aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorcodeworkx <codeworkx@cyanogenmod.com>2012-09-17 17:53:57 +0200
committercodeworkx <codeworkx@cyanogenmod.com>2012-09-18 16:31:59 +0200
commitc28265764ec6ad9995eb0c761a376ffc9f141fcd (patch)
tree3ad899757480d47deb2be6011509a4243e8e0dc2
parent0ddbcb39c0dc0318f68d858f25a96a074142af2f (diff)
downloadkernel_samsung_smdk4412-c28265764ec6ad9995eb0c761a376ffc9f141fcd.zip
kernel_samsung_smdk4412-c28265764ec6ad9995eb0c761a376ffc9f141fcd.tar.gz
kernel_samsung_smdk4412-c28265764ec6ad9995eb0c761a376ffc9f141fcd.tar.bz2
applied patches from i9305 jb sources, updated mali to r3p0
Change-Id: Iec4bc4e2fb59e2cf5b4d25568a644d4e3719565e
-rw-r--r--arch/arm/Kconfig4
-rw-r--r--arch/arm/configs/cyanogenmod_i9300_defconfig1
-rw-r--r--arch/arm/mach-exynos/asv-4x12.c8
-rw-r--r--arch/arm/mach-exynos/asv.c6
-rw-r--r--arch/arm/mach-exynos/include/mach/asv.h13
-rw-r--r--arch/arm/mach-exynos/include/mach/regs-sysmmu.h1
-rw-r--r--arch/arm/plat-s5p/Kconfig2
-rw-r--r--arch/arm/plat-s5p/dev-csis-s5p.c16
-rw-r--r--arch/arm/plat-s5p/dev-csis0.c2
-rw-r--r--arch/arm/plat-s5p/dev-csis1.c2
-rw-r--r--arch/arm/plat-s5p/dev-fimc-s5p.c11
-rw-r--r--arch/arm/plat-s5p/dev-mfc.c10
-rw-r--r--arch/arm/plat-s5p/dev-tvout.c14
-rw-r--r--arch/arm/plat-s5p/dev-usbgadget.c8
-rw-r--r--arch/arm/plat-s5p/reserve_mem.c37
-rw-r--r--arch/arm/plat-s5p/reset.c16
-rw-r--r--arch/arm/plat-s5p/s5p-sysmmu.c42
-rw-r--r--arch/arm/plat-s5p/s5p_iommu.c138
-rw-r--r--arch/arm/plat-s5p/s5p_iovmm.c282
-rw-r--r--arch/arm/plat-s5p/sysmmu.c312
-rw-r--r--arch/arm/plat-samsung/include/plat/cpu.h1
-rw-r--r--drivers/base/Kconfig115
-rw-r--r--drivers/base/Makefile4
-rw-r--r--drivers/base/core.c8
-rw-r--r--drivers/base/dma-contiguous.c504
-rw-r--r--drivers/base/firmware_class.c14
-rw-r--r--drivers/base/iommu.c124
-rw-r--r--drivers/base/sw_sync.c256
-rw-r--r--drivers/base/sync.c801
-rw-r--r--drivers/interceptor/Kconfig3
-rw-r--r--drivers/interceptor/Makefile26
-rw-r--r--drivers/interceptor/engine.h114
-rw-r--r--drivers/interceptor/engine_alloc.h32
-rw-r--r--drivers/interceptor/interceptor.h720
-rw-r--r--drivers/interceptor/kernel_alloc.c124
-rw-r--r--drivers/interceptor/kernel_alloc.h44
-rw-r--r--drivers/interceptor/kernel_encode.c580
-rw-r--r--drivers/interceptor/kernel_includes.h152
-rw-r--r--drivers/interceptor/kernel_mutex.h67
-rw-r--r--drivers/interceptor/linux_hook_magic.c842
-rw-r--r--drivers/interceptor/linux_iface.c863
-rw-r--r--drivers/interceptor/linux_internal.h819
-rw-r--r--drivers/interceptor/linux_ip_glue.c1841
-rw-r--r--drivers/interceptor/linux_ipm.c364
-rw-r--r--drivers/interceptor/linux_kernel_alloc.c182
-rw-r--r--drivers/interceptor/linux_main.c533
-rw-r--r--drivers/interceptor/linux_mutex.c115
-rw-r--r--drivers/interceptor/linux_mutex_internal.h49
-rw-r--r--drivers/interceptor/linux_packet.c846
-rw-r--r--drivers/interceptor/linux_packet_internal.h84
-rw-r--r--drivers/interceptor/linux_params.h84
-rw-r--r--drivers/interceptor/linux_procfs.c800
-rw-r--r--drivers/interceptor/linux_route.c1136
-rw-r--r--drivers/interceptor/linux_usermode.c384
-rw-r--r--drivers/interceptor/linux_versions.h190
-rw-r--r--drivers/interceptor/linux_virtual_adapter.c1073
-rw-r--r--drivers/interceptor/linux_virtual_adapter_internal.h73
-rw-r--r--drivers/interceptor/platform_interceptor.h34
-rw-r--r--drivers/interceptor/platform_kernel_mutex.h54
-rw-r--r--drivers/interceptor/sshconf.h88
-rw-r--r--drivers/interceptor/sshdebug.h175
-rw-r--r--drivers/interceptor/sshencode.h202
-rw-r--r--drivers/interceptor/sshgetput.h108
-rw-r--r--drivers/interceptor/sshincludes.h53
-rw-r--r--drivers/interceptor/sshinet.h233
-rw-r--r--drivers/interceptor/sshinetbits.c45
-rw-r--r--drivers/interceptor/sshinetencode.c130
-rw-r--r--drivers/interceptor/sshinetencode.h43
-rw-r--r--drivers/interceptor/sshinetprint.c136
-rw-r--r--drivers/interceptor/usermodeforwarder.c1363
-rw-r--r--drivers/interceptor/usermodeforwarder.h90
-rw-r--r--drivers/interceptor/virtual_adapter.h296
-rw-r--r--drivers/media/Makefile2
-rw-r--r--drivers/media/video/Kconfig10
-rw-r--r--drivers/media/video/Makefile4
-rw-r--r--drivers/media/video/isx012.c1021
-rw-r--r--drivers/media/video/isx012.h108
-rw-r--r--drivers/media/video/isx012_regs.h1862
-rw-r--r--drivers/media/video/m5mo.c41
-rw-r--r--drivers/media/video/m5mo.h1
-rw-r--r--drivers/media/video/m9mo.c8513
-rw-r--r--drivers/media/video/m9mo.h230
-rw-r--r--drivers/media/video/s5c73m3.c208
-rw-r--r--drivers/media/video/s5c73m3.h26
-rw-r--r--drivers/media/video/s5k5bbgx.c1738
-rw-r--r--drivers/media/video/s5k5bbgx.h117
-rw-r--r--drivers/media/video/s5k5bbgx_setfile.h12066
-rw-r--r--drivers/media/video/s5k5ccgx.c143
-rw-r--r--drivers/media/video/s5k5ccgx.h38
-rw-r--r--drivers/media/video/samsung/Makefile19
-rw-r--r--drivers/media/video/samsung/fimc/Kconfig9
-rw-r--r--drivers/media/video/samsung/fimc/fimc.h42
-rw-r--r--drivers/media/video/samsung/fimc/fimc_capture.c376
-rw-r--r--drivers/media/video/samsung/fimc/fimc_capture_u1.c45
-rw-r--r--drivers/media/video/samsung/fimc/fimc_dev.c334
-rw-r--r--drivers/media/video/samsung/fimc/fimc_dev_u1.c26
-rw-r--r--drivers/media/video/samsung/fimc/fimc_output.c92
-rw-r--r--drivers/media/video/samsung/fimc/fimc_regs.c7
-rw-r--r--drivers/media/video/samsung/fimc/fimc_v4l2.c130
-rw-r--r--drivers/media/video/samsung/fimg2d3x-exynos4/fimg2d_dev.c35
-rw-r--r--drivers/media/video/samsung/fimg2d4x-exynos4/fimg2d.h12
-rw-r--r--drivers/media/video/samsung/fimg2d4x-exynos4/fimg2d4x_blt.c9
-rw-r--r--drivers/media/video/samsung/fimg2d4x-exynos4/fimg2d4x_hw.c17
-rw-r--r--drivers/media/video/samsung/fimg2d4x-exynos4/fimg2d_cache.c87
-rw-r--r--drivers/media/video/samsung/fimg2d4x-exynos4/fimg2d_cache.h10
-rw-r--r--drivers/media/video/samsung/fimg2d4x-exynos4/fimg2d_ctx.c64
-rw-r--r--drivers/media/video/samsung/fimg2d4x-exynos4/fimg2d_drv.c64
-rw-r--r--drivers/media/video/samsung/jpeg_v2x/jpeg_conf.h44
-rw-r--r--drivers/media/video/samsung/jpeg_v2x/jpeg_dev.c29
-rw-r--r--drivers/media/video/samsung/jpeg_v2x/jpeg_mem.h5
-rw-r--r--drivers/media/video/samsung/jpeg_v2x/jpeg_regs.c103
-rw-r--r--drivers/media/video/samsung/jpeg_v2x/jpeg_regs.h2
-rw-r--r--drivers/media/video/samsung/mali/Kconfig10
-rw-r--r--drivers/media/video/samsung/mali/Makefile207
-rw-r--r--drivers/media/video/samsung/mali/Makefile.common59
-rw-r--r--drivers/media/video/samsung/mali/Makefile_module89
l---------drivers/media/video/samsung/mali/arch1
-rw-r--r--drivers/media/video/samsung/mali/arch-debug/config.h (renamed from drivers/media/video/samsung/mali/arch-orion-m400/config.h)2
-rw-r--r--drivers/media/video/samsung/mali/arch-pb-virtex5-m300/config.h85
-rw-r--r--drivers/media/video/samsung/mali/arch-pb-virtex5-m400-1-direct/config.h92
-rw-r--r--drivers/media/video/samsung/mali/arch-pb-virtex5-m400-1-pmu/config.h85
-rw-r--r--drivers/media/video/samsung/mali/arch-pb-virtex5-m400-1/config.h77
-rw-r--r--drivers/media/video/samsung/mali/arch-pb-virtex5-m400-2/config.h91
-rw-r--r--drivers/media/video/samsung/mali/arch-pb-virtex5-m400-3/config.h105
-rw-r--r--drivers/media/video/samsung/mali/arch-pb-virtex5-m400-4/config.h119
-rw-r--r--drivers/media/video/samsung/mali/arch-pegasus-m400/config.h154
-rw-r--r--drivers/media/video/samsung/mali/arch-release/config.h154
-rw-r--r--drivers/media/video/samsung/mali/arch-ve-virtex6-m450-8/config.h168
-rw-r--r--drivers/media/video/samsung/mali/arch/config.h154
-rw-r--r--drivers/media/video/samsung/mali/common/mali_block_allocator.c6
-rw-r--r--drivers/media/video/samsung/mali/common/mali_cluster.c218
-rw-r--r--drivers/media/video/samsung/mali/common/mali_cluster.h44
-rw-r--r--drivers/media/video/samsung/mali/common/mali_device_pause_resume.c46
-rw-r--r--drivers/media/video/samsung/mali/common/mali_device_pause_resume.h31
-rw-r--r--drivers/media/video/samsung/mali/common/mali_dlbu.c285
-rw-r--r--drivers/media/video/samsung/mali/common/mali_dlbu.h45
-rw-r--r--drivers/media/video/samsung/mali/common/mali_gp.c693
-rw-r--r--drivers/media/video/samsung/mali/common/mali_gp.h46
-rw-r--r--drivers/media/video/samsung/mali/common/mali_gp_job.c49
-rw-r--r--drivers/media/video/samsung/mali/common/mali_gp_job.h131
-rw-r--r--drivers/media/video/samsung/mali/common/mali_gp_scheduler.c438
-rw-r--r--drivers/media/video/samsung/mali/common/mali_gp_scheduler.h30
-rw-r--r--drivers/media/video/samsung/mali/common/mali_group.c841
-rw-r--r--drivers/media/video/samsung/mali/common/mali_group.h146
-rw-r--r--drivers/media/video/samsung/mali/common/mali_hw_core.c46
-rw-r--r--drivers/media/video/samsung/mali/common/mali_hw_core.h71
-rw-r--r--drivers/media/video/samsung/mali/common/mali_kernel_GP2.c1493
-rw-r--r--drivers/media/video/samsung/mali/common/mali_kernel_MALI200.c1304
-rw-r--r--drivers/media/video/samsung/mali/common/mali_kernel_common.h5
-rw-r--r--drivers/media/video/samsung/mali/common/mali_kernel_core.c1359
-rw-r--r--drivers/media/video/samsung/mali/common/mali_kernel_core.h127
-rw-r--r--drivers/media/video/samsung/mali/common/mali_kernel_descriptor_mapping.c15
-rw-r--r--drivers/media/video/samsung/mali/common/mali_kernel_descriptor_mapping.h6
-rw-r--r--drivers/media/video/samsung/mali/common/mali_kernel_l2_cache.c517
-rw-r--r--drivers/media/video/samsung/mali/common/mali_kernel_l2_cache.h25
-rw-r--r--drivers/media/video/samsung/mali/common/mali_kernel_mem_buddy.c1427
-rw-r--r--drivers/media/video/samsung/mali/common/mali_kernel_mem_mmu.c3157
-rw-r--r--drivers/media/video/samsung/mali/common/mali_kernel_mem_mmu.h75
-rw-r--r--drivers/media/video/samsung/mali/common/mali_kernel_mem_os.c26
-rw-r--r--drivers/media/video/samsung/mali/common/mali_kernel_memory_engine.c26
-rw-r--r--drivers/media/video/samsung/mali/common/mali_kernel_memory_engine.h5
-rw-r--r--drivers/media/video/samsung/mali/common/mali_kernel_rendercore.c2031
-rw-r--r--drivers/media/video/samsung/mali/common/mali_kernel_rendercore.h565
-rw-r--r--drivers/media/video/samsung/mali/common/mali_kernel_subsystem.h107
-rw-r--r--drivers/media/video/samsung/mali/common/mali_kernel_utilization.c56
-rw-r--r--drivers/media/video/samsung/mali/common/mali_kernel_utilization.h2
-rw-r--r--drivers/media/video/samsung/mali/common/mali_kernel_vsync.c32
-rw-r--r--drivers/media/video/samsung/mali/common/mali_l2_cache.c398
-rw-r--r--drivers/media/video/samsung/mali/common/mali_l2_cache.h43
-rw-r--r--drivers/media/video/samsung/mali/common/mali_mem_validation.c71
-rw-r--r--drivers/media/video/samsung/mali/common/mali_mem_validation.h (renamed from drivers/media/video/samsung/mali/common/mali_kernel_session_manager.h)14
-rw-r--r--drivers/media/video/samsung/mali/common/mali_memory.c1321
-rw-r--r--drivers/media/video/samsung/mali/common/mali_memory.h80
-rw-r--r--drivers/media/video/samsung/mali/common/mali_mmu.c619
-rw-r--r--drivers/media/video/samsung/mali/common/mali_mmu.h55
-rw-r--r--drivers/media/video/samsung/mali/common/mali_mmu_page_directory.c459
-rw-r--r--drivers/media/video/samsung/mali/common/mali_mmu_page_directory.h83
-rw-r--r--drivers/media/video/samsung/mali/common/mali_osk.h158
-rw-r--r--drivers/media/video/samsung/mali/common/mali_osk_list.h2
-rw-r--r--drivers/media/video/samsung/mali/common/mali_osk_mali.h32
-rw-r--r--drivers/media/video/samsung/mali/common/mali_osk_profiling.h (renamed from drivers/media/video/samsung/mali/common/mali_kernel_profiling.h)88
-rw-r--r--drivers/media/video/samsung/mali/common/mali_pm.c547
-rw-r--r--drivers/media/video/samsung/mali/common/mali_pm.h56
-rw-r--r--drivers/media/video/samsung/mali/common/mali_pmu.c199
-rw-r--r--drivers/media/video/samsung/mali/common/mali_pmu.h70
-rw-r--r--drivers/media/video/samsung/mali/common/mali_pp.c710
-rw-r--r--drivers/media/video/samsung/mali/common/mali_pp.h47
-rw-r--r--drivers/media/video/samsung/mali/common/mali_pp_job.c92
-rw-r--r--drivers/media/video/samsung/mali/common/mali_pp_job.h255
-rw-r--r--drivers/media/video/samsung/mali/common/mali_pp_scheduler.c542
-rw-r--r--drivers/media/video/samsung/mali/common/mali_pp_scheduler.h38
-rw-r--r--drivers/media/video/samsung/mali/common/mali_scheduler.c36
-rw-r--r--drivers/media/video/samsung/mali/common/mali_scheduler.h (renamed from drivers/media/video/samsung/mali/common/mali_kernel_mem.h)16
-rw-r--r--drivers/media/video/samsung/mali/common/mali_session.c47
-rw-r--r--drivers/media/video/samsung/mali/common/mali_session.h65
-rw-r--r--drivers/media/video/samsung/mali/common/mali_ukk.h184
-rw-r--r--drivers/media/video/samsung/mali/common/mali_user_settings_db.c88
-rw-r--r--drivers/media/video/samsung/mali/common/mali_user_settings_db.h40
-rw-r--r--drivers/media/video/samsung/mali/common/pmm/mali_pmm.c1024
-rw-r--r--drivers/media/video/samsung/mali/common/pmm/mali_pmm.h348
-rw-r--r--drivers/media/video/samsung/mali/common/pmm/mali_pmm_pmu.c350
-rw-r--r--drivers/media/video/samsung/mali/common/pmm/mali_pmm_pmu.h86
-rw-r--r--drivers/media/video/samsung/mali/common/pmm/mali_pmm_policy.c243
-rw-r--r--drivers/media/video/samsung/mali/common/pmm/mali_pmm_policy.h155
-rw-r--r--drivers/media/video/samsung/mali/common/pmm/mali_pmm_policy_alwayson.c80
-rw-r--r--drivers/media/video/samsung/mali/common/pmm/mali_pmm_policy_alwayson.h62
-rw-r--r--drivers/media/video/samsung/mali/common/pmm/mali_pmm_policy_jobcontrol.c470
-rw-r--r--drivers/media/video/samsung/mali/common/pmm/mali_pmm_policy_jobcontrol.h80
-rw-r--r--drivers/media/video/samsung/mali/common/pmm/mali_pmm_state.c716
-rw-r--r--drivers/media/video/samsung/mali/common/pmm/mali_pmm_state.h290
-rw-r--r--drivers/media/video/samsung/mali/common/pmm/mali_pmm_system.h61
-rw-r--r--drivers/media/video/samsung/mali/include/linux/mali/mali_utgard.h (renamed from drivers/media/video/samsung/mali/common/mali_kernel_gp.h)25
-rw-r--r--drivers/media/video/samsung/mali/include/linux/mali/mali_utgard_counters.h264
-rw-r--r--drivers/media/video/samsung/mali/include/linux/mali/mali_utgard_ioctl.h80
-rw-r--r--drivers/media/video/samsung/mali/include/linux/mali/mali_utgard_profiling_events.h121
-rw-r--r--drivers/media/video/samsung/mali/include/linux/mali/mali_utgard_uk_types.h (renamed from drivers/media/video/samsung/mali/common/mali_uk_types.h)341
-rw-r--r--drivers/media/video/samsung/mali/linux/mali_device_pause_resume.c72
-rw-r--r--drivers/media/video/samsung/mali/linux/mali_kernel_ioctl.h13
-rw-r--r--drivers/media/video/samsung/mali/linux/mali_kernel_linux.c227
-rw-r--r--drivers/media/video/samsung/mali/linux/mali_kernel_linux.h8
-rw-r--r--drivers/media/video/samsung/mali/linux/mali_kernel_pm.c681
-rw-r--r--drivers/media/video/samsung/mali/linux/mali_kernel_pm.h5
-rw-r--r--drivers/media/video/samsung/mali/linux/mali_kernel_sysfs.c977
-rw-r--r--drivers/media/video/samsung/mali/linux/mali_kernel_sysfs.h2
-rw-r--r--drivers/media/video/samsung/mali/linux/mali_linux_pm.h7
-rw-r--r--drivers/media/video/samsung/mali/linux/mali_linux_pm_testsuite.h13
-rw-r--r--drivers/media/video/samsung/mali/linux/mali_linux_trace.h132
-rw-r--r--drivers/media/video/samsung/mali/linux/mali_osk_indir_mmap.h2
-rw-r--r--drivers/media/video/samsung/mali/linux/mali_osk_irq.c84
-rw-r--r--drivers/media/video/samsung/mali/linux/mali_osk_locks.c109
-rw-r--r--drivers/media/video/samsung/mali/linux/mali_osk_low_level_mem.c31
-rw-r--r--drivers/media/video/samsung/mali/linux/mali_osk_mali.c21
-rw-r--r--drivers/media/video/samsung/mali/linux/mali_osk_memory.c2
-rw-r--r--drivers/media/video/samsung/mali/linux/mali_osk_misc.c5
-rw-r--r--drivers/media/video/samsung/mali/linux/mali_osk_notification.c25
-rw-r--r--drivers/media/video/samsung/mali/linux/mali_osk_pm.c204
-rw-r--r--drivers/media/video/samsung/mali/linux/mali_osk_profiling.c47
-rw-r--r--drivers/media/video/samsung/mali/linux/mali_osk_profiling_gator.c262
-rw-r--r--drivers/media/video/samsung/mali/linux/mali_osk_profiling_internal.c (renamed from drivers/media/video/samsung/mali/common/mali_kernel_profiling.c)122
-rw-r--r--drivers/media/video/samsung/mali/linux/mali_osk_specific.h102
-rw-r--r--drivers/media/video/samsung/mali/linux/mali_osk_timers.c4
-rw-r--r--drivers/media/video/samsung/mali/linux/mali_osk_wait_queue.c73
-rw-r--r--drivers/media/video/samsung/mali/linux/mali_pmu_power_up_down.c65
-rw-r--r--drivers/media/video/samsung/mali/linux/mali_profiling_events.h (renamed from drivers/media/video/samsung/ump/arch-marcopolo-vega1-m400/config.h)13
-rw-r--r--drivers/media/video/samsung/mali/linux/mali_uk_types.h (renamed from drivers/media/video/samsung/mali/linux/mali_device_pause_resume.h)16
-rw-r--r--drivers/media/video/samsung/mali/linux/mali_ukk_core.c24
-rw-r--r--drivers/media/video/samsung/mali/linux/mali_ukk_gp.c21
-rw-r--r--drivers/media/video/samsung/mali/linux/mali_ukk_mem.c81
-rw-r--r--drivers/media/video/samsung/mali/linux/mali_ukk_pp.c49
-rw-r--r--drivers/media/video/samsung/mali/linux/mali_ukk_profiling.c63
-rw-r--r--drivers/media/video/samsung/mali/linux/mali_ukk_vsync.c4
-rw-r--r--drivers/media/video/samsung/mali/linux/mali_ukk_wrappers.h14
-rw-r--r--drivers/media/video/samsung/mali/platform/default/mali_platform.c4
-rw-r--r--drivers/media/video/samsung/mali/platform/mali_platform.h36
-rw-r--r--drivers/media/video/samsung/mali/platform/mali_platform_pmu_testing/mali_platform.c66
-rw-r--r--drivers/media/video/samsung/mali/platform/orion-m400/mali_platform.c2
-rw-r--r--drivers/media/video/samsung/mali/platform/orion-m400/mali_platform_dvfs.c415
-rw-r--r--drivers/media/video/samsung/mali/platform/pegasus-m400/mali_platform.c118
-rw-r--r--drivers/media/video/samsung/mali/platform/pegasus-m400/mali_platform_dvfs.c175
-rw-r--r--drivers/media/video/samsung/mali/readme.txt28
-rw-r--r--drivers/media/video/samsung/mali/regs/mali_200_regs.h32
-rw-r--r--drivers/media/video/samsung/mali/regs/mali_gp_regs.h27
-rw-r--r--drivers/media/video/samsung/mali/timestamp-arm11-cc/mali_timestamp.c2
-rw-r--r--drivers/media/video/samsung/mali/timestamp-arm11-cc/mali_timestamp.h2
-rw-r--r--drivers/media/video/samsung/mali/timestamp-default/mali_timestamp.c2
-rw-r--r--drivers/media/video/samsung/mali/timestamp-default/mali_timestamp.h2
-rw-r--r--drivers/media/video/samsung/tvout/Kconfig10
-rw-r--r--drivers/media/video/samsung/tvout/hw_if/hdcp.c20
-rw-r--r--drivers/media/video/samsung/tvout/hw_if/hdmi.c56
-rw-r--r--drivers/media/video/samsung/tvout/hw_if/hw_if.h26
-rw-r--r--drivers/media/video/samsung/tvout/s5p_mixer_ctrl.c76
-rw-r--r--drivers/media/video/samsung/tvout/s5p_tvif_ctrl.c89
-rw-r--r--drivers/media/video/samsung/tvout/s5p_tvout.c38
-rw-r--r--drivers/media/video/samsung/tvout/s5p_tvout_common_lib.h10
-rw-r--r--drivers/media/video/samsung/tvout/s5p_tvout_ctrl.h4
-rw-r--r--drivers/media/video/samsung/tvout/s5p_tvout_fb.c16
-rw-r--r--drivers/media/video/samsung/tvout/s5p_tvout_hpd.c80
-rw-r--r--drivers/media/video/samsung/tvout/s5p_tvout_v4l2.c115
-rw-r--r--drivers/media/video/samsung/tvout/s5p_vp_ctrl.c20
-rw-r--r--drivers/media/video/samsung/ump/Kconfig5
-rw-r--r--drivers/media/video/samsung/ump/Makefile18
-rw-r--r--drivers/media/video/samsung/ump/Makefile.common19
-rw-r--r--drivers/media/video/samsung/ump/Makefile_backup80
-rw-r--r--drivers/media/video/samsung/ump/Makefile_module119
l---------drivers/media/video/samsung/ump/arch1
-rw-r--r--drivers/media/video/samsung/ump/arch-debug/config.h (renamed from drivers/media/video/samsung/mali/common/mali_kernel_pp.h)23
-rwxr-xr-xdrivers/media/video/samsung/ump/arch-marcopolo-vega1-m400/config.h.org87
-rw-r--r--drivers/media/video/samsung/ump/arch-orion-m400/config.h14
-rw-r--r--drivers/media/video/samsung/ump/arch-pb-virtex5/config.h4
-rw-r--r--drivers/media/video/samsung/ump/arch-pegasus-m400/config.h22
-rw-r--r--drivers/media/video/samsung/ump/arch-release/config.h22
-rw-r--r--drivers/media/video/samsung/ump/arch/config.h22
-rw-r--r--drivers/media/video/samsung/ump/common/ump_kernel_api.c229
-rw-r--r--drivers/media/video/samsung/ump/common/ump_kernel_common.c15
-rw-r--r--drivers/media/video/samsung/ump/common/ump_kernel_common.h14
-rw-r--r--drivers/media/video/samsung/ump/common/ump_kernel_descriptor_mapping.c35
-rw-r--r--drivers/media/video/samsung/ump/common/ump_kernel_descriptor_mapping.h6
-rw-r--r--drivers/media/video/samsung/ump/common/ump_kernel_memory_backend.h7
-rw-r--r--drivers/media/video/samsung/ump/common/ump_kernel_ref_drv.c13
-rw-r--r--drivers/media/video/samsung/ump/common/ump_kernel_types.h24
-rw-r--r--drivers/media/video/samsung/ump/common/ump_osk.h11
-rw-r--r--drivers/media/video/samsung/ump/common/ump_uk_types.h75
-rw-r--r--drivers/media/video/samsung/ump/common/ump_ukk.h14
-rw-r--r--drivers/media/video/samsung/ump/include/ump_kernel_interface.h6
-rw-r--r--drivers/media/video/samsung/ump/include/ump_kernel_interface_ref_drv.h6
-rw-r--r--drivers/media/video/samsung/ump/include/ump_kernel_interface_vcm.h6
-rw-r--r--drivers/media/video/samsung/ump/include/ump_kernel_platform.h6
-rw-r--r--drivers/media/video/samsung/ump/linux/license/gpl/ump_kernel_license.h6
-rw-r--r--drivers/media/video/samsung/ump/linux/ump_ioctl.h16
-rw-r--r--drivers/media/video/samsung/ump/linux/ump_kernel_linux.c36
-rw-r--r--drivers/media/video/samsung/ump/linux/ump_kernel_linux.h12
-rw-r--r--drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_dedicated.c19
-rw-r--r--drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_dedicated.h7
-rw-r--r--drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_os.c16
-rw-r--r--drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_os.h7
-rw-r--r--drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_vcm.c24
-rw-r--r--drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_vcm.h6
-rw-r--r--drivers/media/video/samsung/ump/linux/ump_memory_backend.c7
-rw-r--r--drivers/media/video/samsung/ump/linux/ump_osk_atomics.c6
-rw-r--r--drivers/media/video/samsung/ump/linux/ump_osk_low_level_mem.c213
-rw-r--r--drivers/media/video/samsung/ump/linux/ump_osk_misc.c6
-rw-r--r--drivers/media/video/samsung/ump/linux/ump_ukk_ref_wrappers.c6
-rw-r--r--drivers/media/video/samsung/ump/linux/ump_ukk_ref_wrappers.h6
-rw-r--r--drivers/media/video/samsung/ump/linux/ump_ukk_wrappers.c143
-rw-r--r--drivers/media/video/samsung/ump/linux/ump_ukk_wrappers.h10
-rw-r--r--drivers/media/video/slp_db8131m.c796
-rw-r--r--drivers/media/video/slp_db8131m.h100
-rw-r--r--drivers/media/video/slp_db8131m_setfile.h2264
-rw-r--r--drivers/media/video/slp_s5c73m3.c3415
-rw-r--r--drivers/media/video/slp_s5c73m3.h516
-rw-r--r--drivers/media/video/slp_s5k4ecgx.c2335
-rw-r--r--drivers/media/video/slp_s5k4ecgx.h195
-rw-r--r--drivers/media/video/slp_s5k4ecgx_setfile.h7308
-rw-r--r--drivers/media/video/sr200pc20m.h8
-rw-r--r--drivers/media/video/sr200pc20m_regs-s2plus.h4168
-rw-r--r--drivers/media/video/v4l2-ioctl.c4
-rw-r--r--drivers/video/samsung/Kconfig47
-rw-r--r--drivers/video/samsung/Makefile4
-rw-r--r--drivers/video/samsung/aid_ea8061.h337
-rw-r--r--drivers/video/samsung/aid_s6e8aa0.h36
-rw-r--r--drivers/video/samsung/aid_s6evr02.h248
-rw-r--r--drivers/video/samsung/ea8061_param.h391
-rw-r--r--drivers/video/samsung/ea8061_volt_tbl.h667
-rw-r--r--drivers/video/samsung/lcdfreq.c105
-rw-r--r--drivers/video/samsung/ld9040.c87
-rw-r--r--drivers/video/samsung/lms501xx.h156
-rw-r--r--drivers/video/samsung/mdnie_table_baffin.h803
-rw-r--r--drivers/video/samsung/mdnie_table_t0.h763
-rw-r--r--drivers/video/samsung/s3cfb.h122
-rw-r--r--drivers/video/samsung/s3cfb_ea8061.c1289
-rw-r--r--drivers/video/samsung/s3cfb_fimd6x.c66
-rw-r--r--drivers/video/samsung/s3cfb_ielcd.c2
-rw-r--r--drivers/video/samsung/s3cfb_lms501xx.c737
-rw-r--r--drivers/video/samsung/s3cfb_main.c293
-rw-r--r--drivers/video/samsung/s3cfb_mdnie.c2
-rw-r--r--drivers/video/samsung/s3cfb_ops.c694
-rw-r--r--drivers/video/samsung/s3cfb_s6c1372.c21
-rw-r--r--drivers/video/samsung/s3cfb_s6e39a0.c223
-rw-r--r--drivers/video/samsung/s3cfb_s6e63m0.c1718
-rw-r--r--drivers/video/samsung/s3cfb_s6e8aa0.c390
-rw-r--r--drivers/video/samsung/s3cfb_s6e8ab0.c177
-rw-r--r--drivers/video/samsung/s3cfb_s6evr02.c1352
-rw-r--r--drivers/video/samsung/s5p-dsim.c176
-rw-r--r--drivers/video/samsung/s5p-dsim.h3
-rw-r--r--drivers/video/samsung/s6d6aa1.c393
-rw-r--r--drivers/video/samsung/s6dr171.c146
-rw-r--r--drivers/video/samsung/s6e63m0_gamma_grande.h229
-rw-r--r--drivers/video/samsung/s6e63m0_gamma_l.h311
-rw-r--r--drivers/video/samsung/s6e63m0_param.h375
-rw-r--r--drivers/video/samsung/s6e8aa0_gamma_q1.h6
-rw-r--r--drivers/video/samsung/s6e8aa0_param.h6
-rw-r--r--drivers/video/samsung/s6e8aa1.c568
-rw-r--r--drivers/video/samsung/s6e8aa1_param.h74
-rw-r--r--drivers/video/samsung/s6evr02_param.h351
-rw-r--r--drivers/video/samsung/s6evr02_volt_tbl.h665
-rw-r--r--drivers/video/samsung/smart_dimming_ea8061.c918
-rw-r--r--drivers/video/samsung/smart_dimming_ea8061.h133
-rw-r--r--drivers/video/samsung/smart_dimming_s6evr02.c948
-rw-r--r--drivers/video/samsung/smart_dimming_s6evr02.h133
-rw-r--r--include/linux/fb.h1
-rw-r--r--include/linux/sw_sync.h58
-rw-r--r--include/linux/sync.h390
-rw-r--r--include/linux/videodev2_exynos_camera.h718
383 files changed, 92951 insertions, 26050 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 1e3390d..b9e66ff 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -4,6 +4,7 @@ config ARM
select HAVE_AOUT
select HAVE_DMA_API_DEBUG
select HAVE_IDE
+ select HAVE_DMA_CONTIGUOUS if (CPU_V6 || CPU_V6K || CPU_V7)
select HAVE_MEMBLOCK
select RTC_LIB
select SYS_SUPPORTS_APM_EMULATION
@@ -37,6 +38,9 @@ config ARM
Europe. There is an ARM Linux project with a web page at
<http://www.arm.linux.org.uk/>.
+config ARM_HAS_SG_CHAIN
+ bool
+
config HAVE_PWM
bool
diff --git a/arch/arm/configs/cyanogenmod_i9300_defconfig b/arch/arm/configs/cyanogenmod_i9300_defconfig
index f1918cc..7c79791 100644
--- a/arch/arm/configs/cyanogenmod_i9300_defconfig
+++ b/arch/arm/configs/cyanogenmod_i9300_defconfig
@@ -2131,6 +2131,7 @@ CONFIG_FB_S5P=y
CONFIG_FB_S5P_SPLASH_SCREEN=y
# CONFIG_FB_S5P_LCD_INIT is not set
# CONFIG_FB_S5P_DEBUG is not set
+CONFIG_FB_S5P_VSYNC_THREAD=y
# CONFIG_FB_S5P_TRACE_UNDERRUN is not set
CONFIG_FB_S5P_DEFAULT_WINDOW=2
CONFIG_FB_S5P_NR_BUFFERS=2
diff --git a/arch/arm/mach-exynos/asv-4x12.c b/arch/arm/mach-exynos/asv-4x12.c
index 5eeaf20..4953af7 100644
--- a/arch/arm/mach-exynos/asv-4x12.c
+++ b/arch/arm/mach-exynos/asv-4x12.c
@@ -33,10 +33,18 @@
#define MOD_SG_OFFSET 21
#define MOD_SG_MASK 0x7
+#define LOCKING_OFFSET 7
+#define LOCKING_MASK 0x1F
+
+#define EMA_OFFSET 6
+#define EMA_MASK 0x1
+
#define DEFAULT_ASV_GROUP 1
#define CHIP_ID_REG (S5P_VA_CHIPID + 0x4)
+unsigned int exynos_armclk_max;
+
struct asv_judge_table exynos4x12_limit[] = {
/* HPM, IDS */
{ 0, 0}, /* Reserved Group */
diff --git a/arch/arm/mach-exynos/asv.c b/arch/arm/mach-exynos/asv.c
index 4a58ad0..7812009 100644
--- a/arch/arm/mach-exynos/asv.c
+++ b/arch/arm/mach-exynos/asv.c
@@ -25,14 +25,18 @@
static struct samsung_asv *exynos_asv;
unsigned int exynos_result_of_asv;
+unsigned int exynos_special_flag;
+bool exynos_dynamic_ema;
static int __init exynos4_asv_init(void)
{
int ret = -EINVAL;
exynos_asv = kzalloc(sizeof(struct samsung_asv), GFP_KERNEL);
- if (!exynos_asv)
+ if (!exynos_asv) {
+ ret = -ENOMEM;
goto out1;
+ }
if (soc_is_exynos4210())
ret = exynos4210_asv_init(exynos_asv);
diff --git a/arch/arm/mach-exynos/include/mach/asv.h b/arch/arm/mach-exynos/include/mach/asv.h
index 6fda670..ded531b 100644
--- a/arch/arm/mach-exynos/include/mach/asv.h
+++ b/arch/arm/mach-exynos/include/mach/asv.h
@@ -24,7 +24,20 @@
#define LOOP_CNT 10
+#define MIF_LOCK_FLAG 0
+#define INT_LOCK_FLAG 1
+#define G3D_LOCK_FLAG 2
+#define ARM_LOCK_FLAG 3
+
extern unsigned int exynos_result_of_asv;
+extern unsigned int exynos_armclk_max;
+extern unsigned int exynos_special_flag;
+extern bool exynos_dynamic_ema;
+
+static inline unsigned int is_special_flag(void)
+{
+ return exynos_special_flag;
+}
enum exynos4x12_abb_member {
ABB_INT,
diff --git a/arch/arm/mach-exynos/include/mach/regs-sysmmu.h b/arch/arm/mach-exynos/include/mach/regs-sysmmu.h
index a0626fa..4c2292b 100644
--- a/arch/arm/mach-exynos/include/mach/regs-sysmmu.h
+++ b/arch/arm/mach-exynos/include/mach/regs-sysmmu.h
@@ -17,6 +17,7 @@
#define S5P_MMU_CFG 0x004
#define S5P_MMU_STATUS 0x008
#define S5P_MMU_FLUSH 0x00C
+#define S5P_MMU_FLUSH_ENTRY 0x010
#define S5P_PT_BASE_ADDR 0x014
#define S5P_INT_STATUS 0x018
#define S5P_INT_CLEAR 0x01C
diff --git a/arch/arm/plat-s5p/Kconfig b/arch/arm/plat-s5p/Kconfig
index 3398d3b..f1eb177 100644
--- a/arch/arm/plat-s5p/Kconfig
+++ b/arch/arm/plat-s5p/Kconfig
@@ -147,7 +147,7 @@ config S5P_DEV_DP
Compile in platform device definitions for DP controller
config S5P_DEV_TVOUT
- bool
+ bool "enable S5P_DEV_TVOUT"
depends on VIDEO_TVOUT
default y
help
diff --git a/arch/arm/plat-s5p/dev-csis-s5p.c b/arch/arm/plat-s5p/dev-csis-s5p.c
index f3a12a7..295542d 100644
--- a/arch/arm/plat-s5p/dev-csis-s5p.c
+++ b/arch/arm/plat-s5p/dev-csis-s5p.c
@@ -43,12 +43,22 @@ static struct s3c_platform_csis default_csis0_data __initdata = {
.clk_rate = 166000000,
};
+int fimc_clk_rate(void)
+{
+ if (samsung_rev() >= EXYNOS4412_REV_2_0)
+ return 180000000;
+ else
+ return 166750000;
+}
+
void __init s3c_csis0_set_platdata(struct s3c_platform_csis *pd)
{
struct s3c_platform_csis *npd;
- if (!pd)
+ if (!pd) {
+ default_csis0_data.clk_rate = fimc_clk_rate();
pd = &default_csis0_data;
+ }
npd = kmemdup(pd, sizeof(struct s3c_platform_csis), GFP_KERNEL);
if (!npd) {
@@ -94,8 +104,10 @@ void __init s3c_csis1_set_platdata(struct s3c_platform_csis *pd)
{
struct s3c_platform_csis *npd;
- if (!pd)
+ if (!pd) {
+ default_csis1_data.clk_rate = fimc_clk_rate();
pd = &default_csis1_data;
+ }
npd = kmemdup(pd, sizeof(struct s3c_platform_csis), GFP_KERNEL);
if (!npd) {
diff --git a/arch/arm/plat-s5p/dev-csis0.c b/arch/arm/plat-s5p/dev-csis0.c
index a071c7b..69a7468 100644
--- a/arch/arm/plat-s5p/dev-csis0.c
+++ b/arch/arm/plat-s5p/dev-csis0.c
@@ -35,7 +35,7 @@ struct platform_device s5p_device_mipi_csis0 = {
};
struct s5p_platform_mipi_csis s5p_mipi_csis0_default_data __initdata = {
- .clk_rate = 166000000,
+ .clk_rate = 166000000,
.lanes = 2,
.alignment = 32,
.hs_settle = 12,
diff --git a/arch/arm/plat-s5p/dev-csis1.c b/arch/arm/plat-s5p/dev-csis1.c
index 5cf9efa..41a40c8 100644
--- a/arch/arm/plat-s5p/dev-csis1.c
+++ b/arch/arm/plat-s5p/dev-csis1.c
@@ -35,7 +35,7 @@ struct platform_device s5p_device_mipi_csis1 = {
};
struct s5p_platform_mipi_csis s5p_mipi_csis1_default_data __initdata = {
- .clk_rate = 166000000,
+ .clk_rate = 166000000,
.lanes = 2,
.alignment = 32,
.hs_settle = 12,
diff --git a/arch/arm/plat-s5p/dev-fimc-s5p.c b/arch/arm/plat-s5p/dev-fimc-s5p.c
index 53a256d..617861d 100644
--- a/arch/arm/plat-s5p/dev-fimc-s5p.c
+++ b/arch/arm/plat-s5p/dev-fimc-s5p.c
@@ -18,6 +18,11 @@
#include <plat/devs.h>
#include <plat/cpu.h>
#include <plat/fimc.h>
+#ifdef CONFIG_USE_FIMC_CMA
+#include <linux/dma-mapping.h>
+
+static u64 s3c_fimc_dmamask = DMA_BIT_MASK(32);
+#endif
static struct resource s3c_fimc0_resource[] = {
[0] = {
@@ -86,6 +91,12 @@ static struct resource s3c_fimc1_resource[] = {
struct platform_device s3c_device_fimc1 = {
.name = "s3c-fimc",
.id = 1,
+#ifdef CONFIG_USE_FIMC_CMA
+ .dev = {
+ .dma_mask = &s3c_fimc_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+#endif
.num_resources = ARRAY_SIZE(s3c_fimc1_resource),
.resource = s3c_fimc1_resource,
};
diff --git a/arch/arm/plat-s5p/dev-mfc.c b/arch/arm/plat-s5p/dev-mfc.c
index e6b9483..216ca3c 100644
--- a/arch/arm/plat-s5p/dev-mfc.c
+++ b/arch/arm/plat-s5p/dev-mfc.c
@@ -29,10 +29,20 @@ static struct resource s5p_mfc_resource[] = {
},
};
+#if defined(CONFIG_DMA_CMA) && defined(CONFIG_USE_MFC_CMA)
+static u64 s5p_mfc_dma_mask = DMA_BIT_MASK(32);
+#endif
+
struct platform_device s5p_device_mfc = {
.name = "s3c-mfc",
.id = -1,
.num_resources = ARRAY_SIZE(s5p_mfc_resource),
.resource = s5p_mfc_resource,
+#if defined(CONFIG_DMA_CMA) && defined(CONFIG_USE_MFC_CMA)
+ .dev = {
+ .dma_mask = &s5p_mfc_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+#endif
};
diff --git a/arch/arm/plat-s5p/dev-tvout.c b/arch/arm/plat-s5p/dev-tvout.c
index dd057dd..a2f6d54 100644
--- a/arch/arm/plat-s5p/dev-tvout.c
+++ b/arch/arm/plat-s5p/dev-tvout.c
@@ -93,6 +93,20 @@ struct platform_device s5p_device_hpd = {
};
EXPORT_SYMBOL(s5p_device_hpd);
+#ifdef CONFIG_HDMI_TX_STRENGTH
+void __init s5p_hdmi_tvout_set_platdata(struct s5p_platform_tvout *pd)
+{
+ struct s5p_platform_tvout *npd;
+
+ npd = kmemdup(pd, sizeof(struct s5p_platform_tvout), GFP_KERNEL);
+ if (!npd)
+ printk(KERN_ERR "%s: no memory for platform data\n", __func__);
+ else {
+ s5p_device_tvout.dev.platform_data = npd;
+ }
+}
+#endif
+
void __init s5p_hdmi_hpd_set_platdata(struct s5p_platform_hpd *pd)
{
struct s5p_platform_hpd *npd;
diff --git a/arch/arm/plat-s5p/dev-usbgadget.c b/arch/arm/plat-s5p/dev-usbgadget.c
index 3890ce3..5dd3eb2 100644
--- a/arch/arm/plat-s5p/dev-usbgadget.c
+++ b/arch/arm/plat-s5p/dev-usbgadget.c
@@ -168,6 +168,14 @@ static struct android_usb_product usb_products[] = {
.functions = usb_functions_mtp,
},
#endif
+ {
+/* debug mode : using MS Composite*/
+#ifdef CONFIG_USB_ANDROID_SAMSUNG_DEBUG_MTP
+ .product_id = SAMSUNG_KIES_PRODUCT_ID,
+ .num_functions = ARRAY_SIZE(usb_functions_mtp_acm_adb),
+ .functions = usb_functions_mtp_acm_adb,
+#endif
+ },
#if defined(CONFIG_USB_ANDROID_MASS_STORAGE) && defined(CONFIG_USB_ANDROID_ADB)
{
.product_id = SAMSUNG_UMS_PRODUCT_ID,
diff --git a/arch/arm/plat-s5p/reserve_mem.c b/arch/arm/plat-s5p/reserve_mem.c
index 5b91823..a103ec9 100644
--- a/arch/arm/plat-s5p/reserve_mem.c
+++ b/arch/arm/plat-s5p/reserve_mem.c
@@ -155,14 +155,49 @@ void __init s5p_cma_region_reserve(struct cma_region *regions_normal,
}
if (paddr_last) {
+#ifndef CONFIG_DMA_CMA
while (memblock_reserve(paddr_last, size_secure))
paddr_last -= align_secure;
+#else
+ if (!reg->start) {
+ while (memblock_reserve(paddr_last,
+ size_secure))
+ paddr_last -= align_secure;
+ }
+#endif
do {
+#ifndef CONFIG_DMA_CMA
reg->start = paddr_last;
reg->reserved = 1;
paddr_last += reg->size;
-
+#else
+ if (reg->start) {
+ reg->reserved = 1;
+#if defined(CONFIG_USE_MFC_CMA) && defined(CONFIG_MACH_M0)
+ if (reg->start == 0x5C100000) {
+ if (memblock_reserve(0x5C100000,
+ 0x700000))
+ panic("memblock\n");
+ if (memblock_reserve(0x5F000000,
+ 0x200000))
+ panic("memblock\n");
+ } else {
+ if (memblock_reserve(reg->start,
+ reg->size))
+ panic("memblock\n");
+ }
+#else
+ if (memblock_reserve(reg->start,
+ reg->size))
+ panic("memblock\n");
+#endif
+ } else {
+ reg->start = paddr_last;
+ reg->reserved = 1;
+ paddr_last += reg->size;
+ }
+#endif
pr_info("S5P/CMA: "
"Reserved 0x%08x/0x%08x for '%s'\n",
reg->start, reg->size, reg->name);
diff --git a/arch/arm/plat-s5p/reset.c b/arch/arm/plat-s5p/reset.c
index 96dfdab..691002d 100644
--- a/arch/arm/plat-s5p/reset.c
+++ b/arch/arm/plat-s5p/reset.c
@@ -15,6 +15,18 @@
#include <plat/system-reset.h>
#include <plat/watchdog-reset.h>
+#ifdef CONFIG_MACH_P4NOTE
+#include <mach/regs-pmu.h>
+static void exynos_sw_reset(void)
+{
+ int count = 3;
+
+ while (count--) {
+ __raw_writel(0x1, S5P_SWRESET);
+ mdelay(500);
+ }
+}
+#endif
void (*s5p_reset_hook)(void);
@@ -24,6 +36,10 @@ void arch_reset(char mode, const char *cmd)
if (s5p_reset_hook)
s5p_reset_hook();
+#ifdef CONFIG_MACH_P4NOTE
+ else
+ exynos_sw_reset();
+#endif
/* Perform reset using Watchdog reset
* if there is no s5p_reset_hook()
diff --git a/arch/arm/plat-s5p/s5p-sysmmu.c b/arch/arm/plat-s5p/s5p-sysmmu.c
index dae74e1..70edd49 100644
--- a/arch/arm/plat-s5p/s5p-sysmmu.c
+++ b/arch/arm/plat-s5p/s5p-sysmmu.c
@@ -85,6 +85,11 @@ static struct sysmmu_drvdata *get_sysmmu_data(struct device *owner,
return NULL;
}
+struct list_head *get_sysmmu_list(void)
+{
+ return &sysmmu_list;
+}
+
static struct sysmmu_drvdata *get_sysmmu_data_rollback(struct device *owner,
struct sysmmu_drvdata *start)
{
@@ -148,6 +153,12 @@ static void __sysmmu_tlb_invalidate(void __iomem *sfrbase)
__raw_writel(0x1, sfrbase + S5P_MMU_FLUSH);
}
+static void __sysmmu_tlb_invalidate_entry(void __iomem *sfrbase,
+ unsigned long iova)
+{
+ __raw_writel((iova & PAGE_MASK) | 1, sfrbase + S5P_MMU_FLUSH_ENTRY);
+}
+
static void __sysmmu_set_ptbase(void __iomem *sfrbase,
unsigned long pgd)
{
@@ -322,6 +333,8 @@ void s5p_sysmmu_set_tablebase_pgd(struct device *owner, unsigned long pgd)
{
struct sysmmu_drvdata *mmudata = NULL;
+ s5p_sysmmu_tlb_invalidate(owner);
+
while ((mmudata = get_sysmmu_data(owner, mmudata))) {
unsigned long flags;
@@ -467,6 +480,35 @@ void s5p_sysmmu_tlb_invalidate(struct device *owner)
}
}
+void s5p_sysmmu_tlb_invalidate_entry(struct device *owner, unsigned long iova,
+ unsigned int count,
+ unsigned long page_size)
+{
+ struct sysmmu_drvdata *mmudata = NULL;
+
+ while ((mmudata = get_sysmmu_data(owner, mmudata))) {
+ unsigned long flags;
+
+ read_lock_irqsave(&mmudata->lock, flags);
+
+ if (is_sysmmu_active(mmudata)) {
+ while (count > 0) {
+ sysmmu_block(mmudata->sfrbase);
+ __sysmmu_tlb_invalidate_entry(mmudata->sfrbase,
+ iova);
+ sysmmu_unblock(mmudata->sfrbase);
+ count--;
+ iova += page_size;
+ }
+ } else {
+ dev_dbg(mmudata->dev,
+ "Disabled: Skipping invalidating TLB.\n");
+ }
+
+ read_unlock_irqrestore(&mmudata->lock, flags);
+ }
+}
+
static int s5p_sysmmu_probe(struct platform_device *pdev)
{
struct resource *res, *ioarea;
diff --git a/arch/arm/plat-s5p/s5p_iommu.c b/arch/arm/plat-s5p/s5p_iommu.c
index a900c84..32a0de5 100644
--- a/arch/arm/plat-s5p/s5p_iommu.c
+++ b/arch/arm/plat-s5p/s5p_iommu.c
@@ -124,6 +124,56 @@ static void s5p_iommu_domain_destroy(struct iommu_domain *domain)
domain->priv = NULL;
}
+#ifdef CONFIG_DRM_EXYNOS_IOMMU
+static int s5p_iommu_attach_device(struct iommu_domain *domain,
+ struct device *dev)
+{
+ int ret;
+ struct s5p_iommu_domain *s5p_domain = domain->priv;
+ struct sysmmu_drvdata *data = NULL;
+
+ mutex_lock(&s5p_domain->lock);
+
+ /*
+ * get sysmmu_drvdata to dev.
+ * owner device was set to sysmmu->platform_data at machine code.
+ */
+ data = get_sysmmu_data(dev, data);
+ if (!data)
+ return -EFAULT;
+
+ mutex_unlock(&s5p_domain->lock);
+
+ ret = s5p_sysmmu_enable(dev, virt_to_phys(s5p_domain->pgtable));
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static void s5p_iommu_detach_device(struct iommu_domain *domain,
+ struct device *dev)
+{
+ struct sysmmu_drvdata *data = NULL;
+ struct s5p_iommu_domain *s5p_domain = domain->priv;
+
+ mutex_lock(&s5p_domain->lock);
+
+ /*
+ * get sysmmu_drvdata to dev.
+ * owner device was set to sysmmu->platform_data at machine code.
+ */
+ data = get_sysmmu_data(dev, data);
+ if (!data) {
+ dev_err(dev, "failed to detach device.\n");
+ return;
+ }
+
+ s5p_sysmmu_disable(dev);
+
+ mutex_unlock(&s5p_domain->lock);
+}
+#else
static int s5p_iommu_attach_device(struct iommu_domain *domain,
struct device *dev)
{
@@ -168,6 +218,7 @@ static void s5p_iommu_detach_device(struct iommu_domain *domain,
}
}
+#endif
static bool section_available(struct iommu_domain *domain,
unsigned long *lv1entry)
@@ -349,6 +400,92 @@ mapping_done:
return ret;
}
+#ifdef CONFIG_DRM_EXYNOS_IOMMU
+static int s5p_iommu_unmap(struct iommu_domain *domain, unsigned long iova,
+ int gfp_order)
+{
+ struct s5p_iommu_domain *s5p_domain = domain->priv;
+ struct sysmmu_drvdata *data;
+ struct list_head *sysmmu_list, *pos;
+ unsigned long *entry;
+ int num_entry;
+
+ BUG_ON(s5p_domain->pgtable == NULL);
+
+ mutex_lock(&s5p_domain->lock);
+
+ entry = s5p_domain->pgtable + (iova >> S5P_SECTION_SHIFT);
+
+ if (gfp_order >= S5P_SECTION_ORDER) {
+ num_entry = 1 << (gfp_order - S5P_SECTION_ORDER);
+ while (num_entry--) {
+ if (S5P_SECTION_LV1_ENTRY(*entry)) {
+ MAKE_FAULT_ENTRY(*entry);
+ } else if (S5P_PAGE_LV1_ENTRY(*entry)) {
+ unsigned long *lv2beg, *lv2end;
+ lv2beg = phys_to_virt(
+ *entry & S5P_LV2TABLE_MASK);
+ lv2end = lv2beg + S5P_LV2TABLE_ENTRIES;
+ while (lv2beg != lv2end) {
+ MAKE_FAULT_ENTRY(*lv2beg);
+ lv2beg++;
+ }
+ }
+ entry++;
+ }
+ } else {
+ entry = GET_LV2ENTRY(*entry, iova);
+
+ BUG_ON(S5P_LPAGE_LV2_ENTRY(*entry) &&
+ (gfp_order < S5P_LPAGE_ORDER));
+
+ num_entry = 1 << gfp_order;
+
+ while (num_entry--) {
+ MAKE_FAULT_ENTRY(*entry);
+ entry++;
+ }
+ }
+
+ sysmmu_list = get_sysmmu_list();
+
+ /*
+ * invalidate tlb entries to iova(device address) to each iommu
+ * registered in sysmmu_list.
+ *
+ * P.S. a device using iommu was set to data->owner at machine code
+ * and enabled iommu was added in sysmmu_list at sysmmu probe
+ */
+ list_for_each(pos, sysmmu_list) {
+ unsigned int page_size, count;
+
+ /*
+ * get entry count and page size to device address space
+ * mapped with iommu page table and invalidate each entry.
+ */
+ if (gfp_order >= S5P_SECTION_ORDER) {
+ count = 1 << (gfp_order - S5P_SECTION_ORDER);
+ page_size = S5P_SECTION_SIZE;
+ } else if (gfp_order >= S5P_LPAGE_ORDER) {
+ count = 1 << (gfp_order - S5P_LPAGE_ORDER);
+ page_size = S5P_LPAGE_SIZE;
+ } else {
+ count = 1 << (gfp_order - S5P_SPAGE_ORDER);
+ page_size = S5P_SPAGE_SIZE;
+ }
+
+ data = list_entry(pos, struct sysmmu_drvdata, node);
+ if (data)
+ s5p_sysmmu_tlb_invalidate_entry(data->owner, iova,
+ count, page_size);
+ }
+
+ mutex_unlock(&s5p_domain->lock);
+
+ return 0;
+}
+#else
+
static int s5p_iommu_unmap(struct iommu_domain *domain, unsigned long iova,
int gfp_order)
{
@@ -400,6 +537,7 @@ static int s5p_iommu_unmap(struct iommu_domain *domain, unsigned long iova,
return 0;
}
+#endif
static phys_addr_t s5p_iommu_iova_to_phys(struct iommu_domain *domain,
unsigned long iova)
diff --git a/arch/arm/plat-s5p/s5p_iovmm.c b/arch/arm/plat-s5p/s5p_iovmm.c
index a56ccef..c5f366f 100644
--- a/arch/arm/plat-s5p/s5p_iovmm.c
+++ b/arch/arm/plat-s5p/s5p_iovmm.c
@@ -67,6 +67,287 @@ static struct s5p_vm_region *find_region(struct s5p_iovmm *vmm, dma_addr_t iova)
return NULL;
}
+#ifdef CONFIG_DRM_EXYNOS_IOMMU
+void *iovmm_setup(unsigned long s_iova, unsigned long size)
+{
+ struct s5p_iovmm *vmm;
+ int ret;
+
+ vmm = kzalloc(sizeof(*vmm), GFP_KERNEL);
+ if (!vmm) {
+ ret = -ENOMEM;
+ goto err_setup_alloc;
+ }
+
+ vmm->vmm_pool = gen_pool_create(PAGE_SHIFT, -1);
+ if (!vmm->vmm_pool) {
+ ret = -ENOMEM;
+ goto err_setup_genalloc;
+ }
+
+ /* device address space starts from s_iova to s_iova + size */
+ ret = gen_pool_add(vmm->vmm_pool, s_iova, size, -1);
+ if (ret)
+ goto err_setup_domain;
+
+ vmm->domain = iommu_domain_alloc();
+ if (!vmm->domain) {
+ ret = -ENOMEM;
+ goto err_setup_domain;
+ }
+
+ mutex_init(&vmm->lock);
+
+ INIT_LIST_HEAD(&vmm->node);
+ INIT_LIST_HEAD(&vmm->regions_list);
+
+ write_lock(&iovmm_list_lock);
+ list_add(&vmm->node, &s5p_iovmm_list);
+ write_unlock(&iovmm_list_lock);
+
+ return vmm;
+err_setup_domain:
+ gen_pool_destroy(vmm->vmm_pool);
+err_setup_genalloc:
+ kfree(vmm);
+err_setup_alloc:
+ return ERR_PTR(ret);
+}
+
+void iovmm_cleanup(void *in_vmm)
+{
+ struct s5p_iovmm *vmm = in_vmm;
+
+ WARN_ON(!vmm);
+
+ if (vmm) {
+ struct list_head *pos, *tmp;
+
+ iommu_domain_free(vmm->domain);
+
+ list_for_each_safe(pos, tmp, &vmm->regions_list) {
+ struct s5p_vm_region *region;
+
+ region = list_entry(pos, struct s5p_vm_region, node);
+
+ /* No need to unmap the region because
+ * iommu_domain_free() frees the page table */
+ gen_pool_free(vmm->vmm_pool, region->start,
+ region->size);
+
+ kfree(list_entry(pos, struct s5p_vm_region, node));
+ }
+
+ gen_pool_destroy(vmm->vmm_pool);
+
+ write_lock(&iovmm_list_lock);
+ list_del(&vmm->node);
+ write_unlock(&iovmm_list_lock);
+
+ kfree(vmm);
+ }
+}
+
+int iovmm_activate(void *in_vmm, struct device *dev)
+{
+ struct s5p_iovmm *vmm = in_vmm;
+ int ret = 0;
+
+ if (WARN_ON(!vmm))
+ return -EINVAL;
+
+ mutex_lock(&vmm->lock);
+
+ ret = iommu_attach_device(vmm->domain, dev);
+ if (!ret)
+ vmm->active = true;
+
+ mutex_unlock(&vmm->lock);
+
+ return ret;
+}
+
+void iovmm_deactivate(void *in_vmm, struct device *dev)
+{
+ struct s5p_iovmm *vmm = in_vmm;
+
+ if (WARN_ON(!vmm))
+ return;
+
+ iommu_detach_device(vmm->domain, dev);
+
+ vmm->active = false;
+}
+
+dma_addr_t iovmm_map(void *in_vmm, struct scatterlist *sg, off_t offset,
+ size_t size)
+{
+ off_t start_off;
+ dma_addr_t addr, start = 0;
+ size_t mapped_size = 0;
+ struct s5p_vm_region *region;
+ struct s5p_iovmm *vmm = in_vmm;
+ int order;
+#ifdef CONFIG_S5P_SYSTEM_MMU_WA5250ERR
+ size_t iova_size = 0;
+#endif
+
+ BUG_ON(!sg);
+
+ if (WARN_ON(!vmm))
+ goto err_map_nomem;
+
+ for (; sg_dma_len(sg) < offset; sg = sg_next(sg))
+ offset -= sg_dma_len(sg);
+
+ mutex_lock(&vmm->lock);
+
+ start_off = offset_in_page(sg_phys(sg) + offset);
+ size = PAGE_ALIGN(size + start_off);
+
+ order = __fls(min(size, (size_t)SZ_1M));
+#ifdef CONFIG_S5P_SYSTEM_MMU_WA5250ERR
+ iova_size = ALIGN(size, SZ_64K);
+ start = (dma_addr_t)gen_pool_alloc_aligned(vmm->vmm_pool, iova_size,
+ order);
+#else
+ start = (dma_addr_t)gen_pool_alloc_aligned(vmm->vmm_pool, size, order);
+#endif
+ if (!start)
+ goto err_map_nomem_lock;
+
+ addr = start;
+ do {
+ phys_addr_t phys;
+ size_t len;
+
+ phys = sg_phys(sg);
+ len = sg_dma_len(sg);
+
+ if (offset > 0) {
+ len -= offset;
+ phys += offset;
+ offset = 0;
+ }
+
+ if (offset_in_page(phys)) {
+ len += offset_in_page(phys);
+ phys = round_down(phys, PAGE_SIZE);
+ }
+
+ len = PAGE_ALIGN(len);
+
+ if (len > (size - mapped_size))
+ len = size - mapped_size;
+
+ while (len > 0) {
+ order = min3(__ffs(phys), __ffs(addr), __fls(len));
+
+ if (iommu_map(vmm->domain, addr, phys,
+ order - PAGE_SHIFT, 0))
+ goto err_map_map;
+
+ addr += (1 << order);
+ phys += (1 << order);
+ len -= (1 << order);
+ mapped_size += (1 << order);
+ }
+ } while ((sg = sg_next(sg)) && (mapped_size < size));
+
+ BUG_ON(mapped_size > size);
+
+ if (mapped_size < size)
+ goto err_map_map;
+
+#ifdef CONFIG_S5P_SYSTEM_MMU_WA5250ERR
+ if (iova_size != size) {
+ /* System MMU v3 support in SMDK5250 EVT0 */
+ addr = start + size;
+ size = iova_size;
+
+ for (; addr < start + size; addr += PAGE_SIZE) {
+ if (iommu_map(vmm->domain, addr,
+ page_to_phys(ZERO_PAGE(0)), 0, 0)) {
+ goto err_map_map;
+ }
+ mapped_size += PAGE_SIZE;
+ }
+ }
+#endif
+ region = kmalloc(sizeof(*region), GFP_KERNEL);
+ if (!region)
+ goto err_map_map;
+
+ region->start = start + start_off;
+ region->size = size;
+ INIT_LIST_HEAD(&region->node);
+
+ list_add(&region->node, &vmm->regions_list);
+
+ mutex_unlock(&vmm->lock);
+
+ return region->start;
+err_map_map:
+ while (addr >= start) {
+ int order;
+ mapped_size = addr - start;
+
+ if (mapped_size == 0) /* Mapping failed at the first page */
+ mapped_size = size;
+
+ BUG_ON(mapped_size < PAGE_SIZE);
+
+ order = min(__fls(mapped_size), __ffs(start));
+
+ iommu_unmap(vmm->domain, start, order - PAGE_SHIFT);
+
+ start += 1 << order;
+ mapped_size -= 1 << order;
+ }
+ gen_pool_free(vmm->vmm_pool, start, size);
+
+err_map_nomem_lock:
+ mutex_unlock(&vmm->lock);
+err_map_nomem:
+ return (dma_addr_t)0;
+}
+
+void iovmm_unmap(void *in_vmm, dma_addr_t iova)
+{
+ struct s5p_vm_region *region;
+ struct s5p_iovmm *vmm = in_vmm;
+
+ if (WARN_ON(!vmm))
+ return;
+
+ mutex_lock(&vmm->lock);
+
+ region = find_region(vmm, iova);
+ if (WARN_ON(!region))
+ goto err_region_not_found;
+
+ region->start = round_down(region->start, PAGE_SIZE);
+
+ gen_pool_free(vmm->vmm_pool, region->start, region->size);
+ list_del(&region->node);
+
+ while (region->size != 0) {
+ int order;
+
+ order = min(__fls(region->size), __ffs(region->start));
+
+ iommu_unmap(vmm->domain, region->start, order - PAGE_SHIFT);
+
+ region->start += 1 << order;
+ region->size -= 1 << order;
+ }
+
+ kfree(region);
+
+err_region_not_found:
+ mutex_unlock(&vmm->lock);
+}
+#else
int iovmm_setup(struct device *dev)
{
struct s5p_iovmm *vmm;
@@ -357,6 +638,7 @@ void iovmm_unmap(struct device *dev, dma_addr_t iova)
err_region_not_found:
mutex_unlock(&vmm->lock);
}
+#endif
static int __init s5p_iovmm_init(void)
{
diff --git a/arch/arm/plat-s5p/sysmmu.c b/arch/arm/plat-s5p/sysmmu.c
new file mode 100644
index 0000000..54f5edd
--- /dev/null
+++ b/arch/arm/plat-s5p/sysmmu.c
@@ -0,0 +1,312 @@
+/* linux/arch/arm/plat-s5p/sysmmu.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.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/io.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+
+#include <asm/pgtable.h>
+
+#include <mach/map.h>
+#include <mach/regs-sysmmu.h>
+#include <plat/sysmmu.h>
+
+#define CTRL_ENABLE 0x5
+#define CTRL_BLOCK 0x7
+#define CTRL_DISABLE 0x0
+
+static struct device *dev;
+
+static unsigned short fault_reg_offset[SYSMMU_FAULTS_NUM] = {
+ S5P_PAGE_FAULT_ADDR,
+ S5P_AR_FAULT_ADDR,
+ S5P_AW_FAULT_ADDR,
+ S5P_DEFAULT_SLAVE_ADDR,
+ S5P_AR_FAULT_ADDR,
+ S5P_AR_FAULT_ADDR,
+ S5P_AW_FAULT_ADDR,
+ S5P_AW_FAULT_ADDR
+};
+
+static char *sysmmu_fault_name[SYSMMU_FAULTS_NUM] = {
+ "PAGE FAULT",
+ "AR MULTI-HIT FAULT",
+ "AW MULTI-HIT FAULT",
+ "BUS ERROR",
+ "AR SECURITY PROTECTION FAULT",
+ "AR ACCESS PROTECTION FAULT",
+ "AW SECURITY PROTECTION FAULT",
+ "AW ACCESS PROTECTION FAULT"
+};
+
+static int (*fault_handlers[S5P_SYSMMU_TOTAL_IPNUM])(
+ enum S5P_SYSMMU_INTERRUPT_TYPE itype,
+ unsigned long pgtable_base,
+ unsigned long fault_addr);
+
+/*
+ * If adjacent 2 bits are true, the system MMU is enabled.
+ * The system MMU is disabled, otherwise.
+ */
+static unsigned long sysmmu_states;
+
+static inline void set_sysmmu_active(sysmmu_ips ips)
+{
+ sysmmu_states |= 3 << (ips * 2);
+}
+
+static inline void set_sysmmu_inactive(sysmmu_ips ips)
+{
+ sysmmu_states &= ~(3 << (ips * 2));
+}
+
+static inline int is_sysmmu_active(sysmmu_ips ips)
+{
+ return sysmmu_states & (3 << (ips * 2));
+}
+
+static void __iomem *sysmmusfrs[S5P_SYSMMU_TOTAL_IPNUM];
+
+static inline void sysmmu_block(sysmmu_ips ips)
+{
+ __raw_writel(CTRL_BLOCK, sysmmusfrs[ips] + S5P_MMU_CTRL);
+ dev_dbg(dev, "%s is blocked.\n", sysmmu_ips_name[ips]);
+}
+
+static inline void sysmmu_unblock(sysmmu_ips ips)
+{
+ __raw_writel(CTRL_ENABLE, sysmmusfrs[ips] + S5P_MMU_CTRL);
+ dev_dbg(dev, "%s is unblocked.\n", sysmmu_ips_name[ips]);
+}
+
+static inline void __sysmmu_tlb_invalidate(sysmmu_ips ips)
+{
+ __raw_writel(0x1, sysmmusfrs[ips] + S5P_MMU_FLUSH);
+ dev_dbg(dev, "TLB of %s is invalidated.\n", sysmmu_ips_name[ips]);
+}
+
+static inline void __sysmmu_set_ptbase(sysmmu_ips ips, unsigned long pgd)
+{
+ if (unlikely(pgd == 0)) {
+ pgd = (unsigned long)ZERO_PAGE(0);
+ __raw_writel(0x20, sysmmusfrs[ips] + S5P_MMU_CFG); /* 4KB LV1 */
+ } else {
+ __raw_writel(0x0, sysmmusfrs[ips] + S5P_MMU_CFG); /* 16KB LV1 */
+ }
+
+ __raw_writel(pgd, sysmmusfrs[ips] + S5P_PT_BASE_ADDR);
+
+ dev_dbg(dev, "Page table base of %s is initialized with 0x%08lX.\n",
+ sysmmu_ips_name[ips], pgd);
+ __sysmmu_tlb_invalidate(ips);
+}
+
+void sysmmu_set_fault_handler(sysmmu_ips ips,
+ int (*handler)(enum S5P_SYSMMU_INTERRUPT_TYPE itype,
+ unsigned long pgtable_base,
+ unsigned long fault_addr))
+{
+ BUG_ON(!((ips >= SYSMMU_MDMA) && (ips < S5P_SYSMMU_TOTAL_IPNUM)));
+ fault_handlers[ips] = handler;
+}
+
+static irqreturn_t s5p_sysmmu_irq(int irq, void *dev_id)
+{
+ /* SYSMMU is in blocked when interrupt occurred. */
+ unsigned long base = 0;
+ sysmmu_ips ips = (sysmmu_ips)dev_id;
+ enum S5P_SYSMMU_INTERRUPT_TYPE itype;
+
+ itype = (enum S5P_SYSMMU_INTERRUPT_TYPE)
+ __ffs(__raw_readl(sysmmusfrs[ips] + S5P_INT_STATUS));
+
+ BUG_ON(!((itype >= 0) && (itype < 8)));
+
+ dev_alert(dev, "%s occurred by %s.\n", sysmmu_fault_name[itype],
+ sysmmu_ips_name[ips]);
+
+ if (fault_handlers[ips]) {
+ unsigned long addr;
+
+ base = __raw_readl(sysmmusfrs[ips] + S5P_PT_BASE_ADDR);
+ addr = __raw_readl(sysmmusfrs[ips] + fault_reg_offset[itype]);
+
+ if (fault_handlers[ips](itype, base, addr)) {
+ __raw_writel(1 << itype,
+ sysmmusfrs[ips] + S5P_INT_CLEAR);
+ dev_notice(dev, "%s from %s is resolved."
+ " Retrying translation.\n",
+ sysmmu_fault_name[itype], sysmmu_ips_name[ips]);
+ } else {
+ base = 0;
+ }
+ }
+
+ sysmmu_unblock(ips);
+
+ if (!base)
+ dev_notice(dev, "%s from %s is not handled.\n",
+ sysmmu_fault_name[itype], sysmmu_ips_name[ips]);
+
+ return IRQ_HANDLED;
+}
+
+void s5p_sysmmu_set_tablebase_pgd(sysmmu_ips ips, unsigned long pgd)
+{
+ if (is_sysmmu_active(ips)) {
+ sysmmu_block(ips);
+ __sysmmu_set_ptbase(ips, pgd);
+ sysmmu_unblock(ips);
+ } else {
+ dev_dbg(dev, "%s is disabled. "
+ "Skipping initializing page table base.\n",
+ sysmmu_ips_name[ips]);
+ }
+}
+
+void s5p_sysmmu_enable(sysmmu_ips ips, unsigned long pgd)
+{
+ if (!is_sysmmu_active(ips)) {
+ sysmmu_clk_enable(ips);
+
+ __sysmmu_set_ptbase(ips, pgd);
+
+ __raw_writel(CTRL_ENABLE, sysmmusfrs[ips] + S5P_MMU_CTRL);
+
+ set_sysmmu_active(ips);
+ dev_dbg(dev, "%s is enabled.\n", sysmmu_ips_name[ips]);
+ } else {
+ dev_dbg(dev, "%s is already enabled.\n", sysmmu_ips_name[ips]);
+ }
+}
+
+void s5p_sysmmu_disable(sysmmu_ips ips)
+{
+ if (is_sysmmu_active(ips)) {
+ __raw_writel(CTRL_DISABLE, sysmmusfrs[ips] + S5P_MMU_CTRL);
+ set_sysmmu_inactive(ips);
+ sysmmu_clk_disable(ips);
+ dev_dbg(dev, "%s is disabled.\n", sysmmu_ips_name[ips]);
+ } else {
+ dev_dbg(dev, "%s is already disabled.\n", sysmmu_ips_name[ips]);
+ }
+}
+
+void s5p_sysmmu_tlb_invalidate(sysmmu_ips ips)
+{
+ if (is_sysmmu_active(ips)) {
+ sysmmu_block(ips);
+ __sysmmu_tlb_invalidate(ips);
+ sysmmu_unblock(ips);
+ } else {
+ dev_dbg(dev, "%s is disabled. "
+ "Skipping invalidating TLB.\n", sysmmu_ips_name[ips]);
+ }
+}
+
+static int s5p_sysmmu_probe(struct platform_device *pdev)
+{
+ int i, ret;
+ struct resource *res, *mem;
+
+ dev = &pdev->dev;
+
+ for (i = 0; i < S5P_SYSMMU_TOTAL_IPNUM; i++) {
+ int irq;
+
+ sysmmu_clk_init(dev, i);
+ sysmmu_clk_disable(i);
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, i);
+ if (!res) {
+ dev_err(dev, "Failed to get the resource of %s.\n",
+ sysmmu_ips_name[i]);
+ ret = -ENODEV;
+ goto err_res;
+ }
+
+ mem = request_mem_region(res->start,
+ ((res->end) - (res->start)) + 1, pdev->name);
+ if (!mem) {
+ dev_err(dev, "Failed to request the memory region of %s.\n",
+ sysmmu_ips_name[i]);
+ ret = -EBUSY;
+ goto err_res;
+ }
+
+ sysmmusfrs[i] = ioremap(res->start, res->end - res->start + 1);
+ if (!sysmmusfrs[i]) {
+ dev_err(dev, "Failed to ioremap() for %s.\n",
+ sysmmu_ips_name[i]);
+ ret = -ENXIO;
+ goto err_reg;
+ }
+
+ irq = platform_get_irq(pdev, i);
+ if (irq <= 0) {
+ dev_err(dev, "Failed to get the IRQ resource of %s.\n",
+ sysmmu_ips_name[i]);
+ ret = -ENOENT;
+ goto err_map;
+ }
+
+ if (request_irq(irq, s5p_sysmmu_irq, IRQF_DISABLED,
+ pdev->name, (void *)i)) {
+ dev_err(dev, "Failed to request IRQ for %s.\n",
+ sysmmu_ips_name[i]);
+ ret = -ENOENT;
+ goto err_map;
+ }
+ }
+
+ return 0;
+
+err_map:
+ iounmap(sysmmusfrs[i]);
+err_reg:
+ release_mem_region(mem->start, resource_size(mem));
+err_res:
+ return ret;
+}
+
+static int s5p_sysmmu_remove(struct platform_device *pdev)
+{
+ return 0;
+}
+int s5p_sysmmu_runtime_suspend(struct device *dev)
+{
+ return 0;
+}
+
+int s5p_sysmmu_runtime_resume(struct device *dev)
+{
+ return 0;
+}
+
+const struct dev_pm_ops s5p_sysmmu_pm_ops = {
+ .runtime_suspend = s5p_sysmmu_runtime_suspend,
+ .runtime_resume = s5p_sysmmu_runtime_resume,
+};
+
+static struct platform_driver s5p_sysmmu_driver = {
+ .probe = s5p_sysmmu_probe,
+ .remove = s5p_sysmmu_remove,
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "s5p-sysmmu",
+ .pm = &s5p_sysmmu_pm_ops,
+ }
+};
+
+static int __init s5p_sysmmu_init(void)
+{
+ return platform_driver_register(&s5p_sysmmu_driver);
+}
+arch_initcall(s5p_sysmmu_init);
diff --git a/arch/arm/plat-samsung/include/plat/cpu.h b/arch/arm/plat-samsung/include/plat/cpu.h
index f68c5a6..8699823 100644
--- a/arch/arm/plat-samsung/include/plat/cpu.h
+++ b/arch/arm/plat-samsung/include/plat/cpu.h
@@ -132,6 +132,7 @@ IS_SAMSUNG_CPU(exynos5250, EXYNOS5250_CPU_ID, EXYNOS_CPU_MASK)
#define EXYNOS4412_REV_0_1 (0x01)
#define EXYNOS4412_REV_1_0 (0x10)
#define EXYNOS4412_REV_1_1 (0x11)
+#define EXYNOS4412_REV_2_0 (0x20)
#if defined(CONFIG_CPU_EXYNOS5210)
# define soc_is_exynos5210() is_samsung_exynos5210()
diff --git a/drivers/base/Kconfig b/drivers/base/Kconfig
index 5398ce8..e960312 100644
--- a/drivers/base/Kconfig
+++ b/drivers/base/Kconfig
@@ -178,4 +178,119 @@ config DMA_SHARED_BUFFER
APIs extension; the file's descriptor can then be passed on to other
driver.
+config SYNC
+ bool "Synchronization framework"
+ default n
+ select ANON_INODES
+ help
+ This option enables the framework for synchronization between multiple
+ drivers. Sync implementations can take advantage of hardware
+ synchronization built into devices like GPUs.
+
+config SW_SYNC
+ bool "Software synchronization objects"
+ default n
+ depends on SYNC
+ help
+ A sync object driver that uses a 32bit counter to coordinate
+ syncrhronization. Useful when there is no hardware primitive backing
+ the synchronization.
+
+config SW_SYNC_USER
+ bool "Userspace API for SW_SYNC"
+ default n
+ depends on SW_SYNC
+ help
+ Provides a user space API to the sw sync object.
+ *WARNING* improper use of this can result in deadlocking kernel
+ drivers from userspace.
+
+config DMA_CMA
+ bool "Contiguous Memory Allocator (EXPERIMENTAL)"
+ default n
+ select MIGRATION
+ help
+ This enables the Contiguous Memory Allocator which allows drivers
+ to allocate big physically-contiguous blocks of memory for use with
+ hardware components that do not support I/O map nor scatter-gather.
+
+ For more information see <include/linux/dma-contiguous.h>.
+ If unsure, say "n".
+
+if DMA_CMA
+
+config DMA_CMA_DEBUG
+ bool "NEW CMA debug messages (DEVELOPMENT)"
+ depends on DEBUG_KERNEL
+ help
+ Turns on debug messages in CMA. This produces KERN_DEBUG
+ messages for every CMA call as well as various messages while
+ processing calls such as dma_alloc_from_contiguous().
+ This option does not affect warning and error messages.
+
+comment "Default contiguous memory area size:"
+
+config CMA_SIZE_MBYTES
+ int "Size in Mega Bytes"
+ depends on !CMA_SIZE_SEL_PERCENTAGE
+ default 16
+ help
+ Defines the size (in MiB) of the default memory area for CMA.
+
+config CMA_SIZE_PERCENTAGE
+ int "Percentage of total memory"
+ depends on !CMA_SIZE_SEL_MBYTES
+ default 10
+ help
+ Defines the size of the default memory area for Contiguous Memory
+ Allocator as a percentage of the total memory in the system.
+
+choice
+ prompt "Selected region size"
+ default CMA_SIZE_SEL_ABSOLUTE
+
+config CMA_SIZE_SEL_MBYTES
+ bool "Use mega bytes value only"
+
+config CMA_SIZE_SEL_PERCENTAGE
+ bool "Use percentage value only"
+
+config CMA_SIZE_SEL_MIN
+ bool "Use lower value (minimum)"
+
+config CMA_SIZE_SEL_MAX
+ bool "Use higher value (maximum)"
+
+endchoice
+
+config CMA_ALIGNMENT
+ int "Maximum PAGE_SIZE order of alignment for contiguous buffers"
+ range 4 9
+ default 8
+ help
+ DMA mapping framework by default aligns all buffers to the smallest
+ PAGE_SIZE order which is greater than or equal to the requested buffer
+ size. This works well for buffers up to a few hundreds kilobytes, but
+ for larger buffers it just a memory waste. With this parameter you can
+ specify the maximum PAGE_SIZE order for contiguous buffers. Larger
+ buffers will be aligned only to this specified order. The order is
+ expressed as a power of two multiplied by the PAGE_SIZE.
+
+ For example, if your system defaults to 4KiB pages, the order value
+ of 8 means that the buffers will be aligned up to 1MiB only.
+
+ If unsure, leave the default value "8".
+
+config CMA_AREAS
+ int "Maximum count of the CMA device-private areas"
+ default 7
+ help
+ CMA allows to create CMA areas for particular devices. This parameter
+ sets the maximum number of such device private CMA areas in the
+ system.
+
+ If unsure, leave the default value "7".
+
+endif
+
endmenu
diff --git a/drivers/base/Makefile b/drivers/base/Makefile
index a749d9b..a60d7e2 100644
--- a/drivers/base/Makefile
+++ b/drivers/base/Makefile
@@ -5,6 +5,7 @@ obj-y := core.o sys.o bus.o dd.o syscore.o \
cpu.o firmware.o init.o map.o devres.o \
attribute_container.o transport_class.o
obj-$(CONFIG_DEVTMPFS) += devtmpfs.o
+obj-$(CONFIG_DMA_CMA) += dma-contiguous.o
obj-y += power/
obj-$(CONFIG_HAS_DMA) += dma-mapping.o
obj-$(CONFIG_HAVE_GENERIC_DMA_COHERENT) += dma-coherent.o
@@ -20,5 +21,8 @@ obj-$(CONFIG_MODULES) += module.o
endif
obj-$(CONFIG_SYS_HYPERVISOR) += hypervisor.o
+obj-$(CONFIG_SYNC) += sync.o
+obj-$(CONFIG_SW_SYNC) += sw_sync.o
+
ccflags-$(CONFIG_DEBUG_DRIVER) := -DDEBUG
diff --git a/drivers/base/core.c b/drivers/base/core.c
index 835ed32..68bd89e 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -1743,10 +1743,12 @@ void device_shutdown(void)
*/
list_del_init(&dev->kobj.entry);
spin_unlock(&devices_kset->list_lock);
- /* Disable all device's runtime power management */
- pm_runtime_disable(dev);
-#if defined(CONFIG_MACH_Q1_BD) || defined(CONFIG_MACH_PX)
+ /* Don't allow any more runtime suspends */
+ pm_runtime_get_noresume(dev);
+ pm_runtime_barrier(dev);
+
+#if defined(CONFIG_MACH_Q1_BD) || defined(CONFIG_MACH_PX) || defined(CONFIG_MACH_MIDAS)
/* Temporary log to analyze a problem during shutdown */
if (dev->bus && dev->bus->shutdown) {
dev_info(dev, "shutdown +: %pF\n", dev->bus->shutdown);
diff --git a/drivers/base/dma-contiguous.c b/drivers/base/dma-contiguous.c
new file mode 100644
index 0000000..c3a6e3b
--- /dev/null
+++ b/drivers/base/dma-contiguous.c
@@ -0,0 +1,504 @@
+/*
+ * Contiguous Memory Allocator for DMA mapping framework
+ * Copyright (c) 2010-2011 by Samsung Electronics.
+ * Written by:
+ * Marek Szyprowski <m.szyprowski@samsung.com>
+ * Michal Nazarewicz <mina86@mina86.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 optional) any later version of the license.
+ */
+
+#define pr_fmt(fmt) "cma: " fmt
+
+#ifdef CONFIG_DMA_CMA_DEBUG
+#ifndef DEBUG
+# define DEBUG
+#endif
+#endif
+
+#include <asm/page.h>
+#include <asm/dma-contiguous.h>
+
+#include <linux/memblock.h>
+#include <linux/err.h>
+#include <linux/mm.h>
+#include <linux/mutex.h>
+#include <linux/page-isolation.h>
+#include <linux/slab.h>
+#include <linux/swap.h>
+#include <linux/mm_types.h>
+#include <linux/dma-contiguous.h>
+
+#ifndef SZ_1M
+#define SZ_1M (1 << 20)
+#endif
+
+struct cma {
+ unsigned long base_pfn;
+ unsigned long count;
+ unsigned long *bitmap;
+};
+
+struct cma *dma_contiguous_default_area;
+
+#ifdef CONFIG_CMA_SIZE_MBYTES
+#define CMA_SIZE_MBYTES CONFIG_CMA_SIZE_MBYTES
+#else
+#define CMA_SIZE_MBYTES 0
+#endif
+
+/*
+ * Default global CMA area size can be defined in kernel's .config.
+ * This is usefull mainly for distro maintainers to create a kernel
+ * that works correctly for most supported systems.
+ * The size can be set in bytes or as a percentage of the total memory
+ * in the system.
+ *
+ * Users, who want to set the size of global CMA area for their system
+ * should use cma= kernel parameter.
+ */
+static const unsigned long size_bytes = CMA_SIZE_MBYTES * SZ_1M;
+static long size_cmdline = -1;
+
+static int __init early_cma(char *p)
+{
+ pr_debug("%s(%s)\n", __func__, p);
+ size_cmdline = memparse(p, &p);
+ return 0;
+}
+early_param("cma", early_cma);
+
+#ifdef CONFIG_CMA_SIZE_PERCENTAGE
+
+static unsigned long __init __maybe_unused cma_early_percent_memory(void)
+{
+ struct memblock_region *reg;
+ unsigned long total_pages = 0;
+
+ /*
+ * We cannot use memblock_phys_mem_size() here, because
+ * memblock_analyze() has not been called yet.
+ */
+ for_each_memblock(memory, reg)
+ total_pages += memblock_region_memory_end_pfn(reg) -
+ memblock_region_memory_base_pfn(reg);
+
+ return (total_pages * CONFIG_CMA_SIZE_PERCENTAGE / 100) << PAGE_SHIFT;
+}
+
+#else
+
+static inline __maybe_unused unsigned long cma_early_percent_memory(void)
+{
+ return 0;
+}
+
+#endif
+
+/**
+ * dma_contiguous_reserve() - reserve area for contiguous memory handling
+ * @limit: End address of the reserved memory (optional, 0 for any).
+ *
+ * This function reserves memory from early allocator. It should be
+ * called by arch specific code once the early allocator (memblock or bootmem)
+ * has been activated and all other subsystems have already allocated/reserved
+ * memory.
+ */
+void __init dma_contiguous_reserve(phys_addr_t limit)
+{
+ unsigned long selected_size = 0;
+
+ pr_debug("%s(limit %08lx)\n", __func__, (unsigned long)limit);
+
+ if (size_cmdline != -1) {
+ selected_size = size_cmdline;
+ } else {
+#ifdef CONFIG_CMA_SIZE_SEL_MBYTES
+ selected_size = size_bytes;
+#elif defined(CONFIG_CMA_SIZE_SEL_PERCENTAGE)
+ selected_size = cma_early_percent_memory();
+#elif defined(CONFIG_CMA_SIZE_SEL_MIN)
+ selected_size = min(size_bytes, cma_early_percent_memory());
+#elif defined(CONFIG_CMA_SIZE_SEL_MAX)
+ selected_size = max(size_bytes, cma_early_percent_memory());
+#endif
+ }
+
+ if (selected_size) {
+ pr_debug("%s: reserving %ld MiB for global area\n", __func__,
+ selected_size / SZ_1M);
+
+ dma_declare_contiguous(NULL, selected_size, 0, limit);
+ }
+};
+
+static DEFINE_MUTEX(cma_mutex);
+
+static __init int cma_activate_area(unsigned long base_pfn, unsigned long count)
+{
+ unsigned long pfn = base_pfn;
+ unsigned i = count >> pageblock_order;
+ struct zone *zone;
+
+ WARN_ON_ONCE(!pfn_valid(pfn));
+ zone = page_zone(pfn_to_page(pfn));
+
+ do {
+ unsigned j;
+ base_pfn = pfn;
+ for (j = pageblock_nr_pages; j; --j, pfn++) {
+ WARN_ON_ONCE(!pfn_valid(pfn));
+ if (page_zone(pfn_to_page(pfn)) != zone)
+ return -EINVAL;
+ }
+ init_cma_reserved_pageblock(pfn_to_page(base_pfn));
+ } while (--i);
+ return 0;
+}
+
+static __init struct cma *cma_create_area(unsigned long base_pfn,
+ unsigned long count)
+{
+ int bitmap_size = BITS_TO_LONGS(count) * sizeof(long);
+ struct cma *cma;
+ int ret = -ENOMEM;
+
+ pr_debug("%s(base %08lx, count %lx)\n", __func__, base_pfn, count);
+
+ cma = kmalloc(sizeof *cma, GFP_KERNEL);
+ if (!cma)
+ return ERR_PTR(-ENOMEM);
+
+ cma->base_pfn = base_pfn;
+ cma->count = count;
+ cma->bitmap = kzalloc(bitmap_size, GFP_KERNEL);
+
+ if (!cma->bitmap)
+ goto no_mem;
+
+ ret = cma_activate_area(base_pfn, count);
+ if (ret)
+ goto error;
+
+ pr_debug("%s: returned %p\n", __func__, (void *)cma);
+ return cma;
+
+error:
+ kfree(cma->bitmap);
+no_mem:
+ kfree(cma);
+ return ERR_PTR(ret);
+}
+
+static struct cma_reserved {
+ phys_addr_t start;
+ unsigned long size;
+ struct device *dev;
+} cma_reserved[MAX_CMA_AREAS] __initdata;
+static unsigned cma_reserved_count __initdata;
+
+static int __init cma_init_reserved_areas(void)
+{
+ struct cma_reserved *r = cma_reserved;
+ unsigned i = cma_reserved_count;
+
+ pr_debug("%s()\n", __func__);
+
+ for (; i; --i, ++r) {
+ struct cma *cma;
+ cma = cma_create_area(PFN_DOWN(r->start),
+ r->size >> PAGE_SHIFT);
+ if (!IS_ERR(cma))
+ dev_set_cma_area(r->dev, cma);
+ else
+ printk(KERN_ERR "%s() cma_create_area error for %ud\n",
+ __func__, i);
+ }
+ return 0;
+}
+core_initcall(cma_init_reserved_areas);
+
+/**
+ * dma_declare_contiguous() - reserve area for contiguous memory handling
+ * for particular device
+ * @dev: Pointer to device structure.
+ * @size: Size of the reserved memory.
+ * @base: Start address of the reserved memory (optional, 0 for any).
+ * @limit: End address of the reserved memory (optional, 0 for any).
+ *
+ * This function reserves memory for specified device. It should be
+ * called by board specific code when early allocator (memblock or bootmem)
+ * is still activate.
+ */
+int __init dma_declare_contiguous(struct device *dev, unsigned long size,
+ phys_addr_t base, phys_addr_t limit)
+{
+ struct cma_reserved *r = &cma_reserved[cma_reserved_count];
+ unsigned long alignment;
+
+ pr_debug("%s(size %lx, base %08lx, limit %08lx)\n", __func__,
+ (unsigned long)size, (unsigned long)base,
+ (unsigned long)limit);
+
+ /* Sanity checks */
+ if (cma_reserved_count == ARRAY_SIZE(cma_reserved)) {
+ pr_err("Not enough slots for CMA reserved regions!\n");
+ return -ENOSPC;
+ }
+
+ if (!size)
+ return -EINVAL;
+
+ /* Sanitise input arguments */
+ alignment = PAGE_SIZE << max(MAX_ORDER-1, pageblock_order);
+ base = ALIGN(base, alignment);
+ size = ALIGN(size, alignment);
+ limit &= ~(alignment - 1);
+
+ /* Reserve memory */
+ if (base) {
+ if (memblock_is_region_reserved(base, size) ||
+ memblock_reserve(base, size) < 0) {
+ base = -EBUSY;
+ goto err;
+ }
+ } else {
+ /*
+ * Use __memblock_alloc_base() since
+ * memblock_alloc_base() panic()s.
+ */
+ phys_addr_t addr = __memblock_alloc_base(size, alignment,
+ limit);
+ if (!addr) {
+ base = -ENOMEM;
+ goto err;
+ } else if (addr + size > ~(unsigned long)0) {
+ memblock_free(addr, size);
+ base = -EINVAL;
+ goto err;
+ } else {
+ base = addr;
+ }
+ }
+
+ /*
+ * Each reserved area must be initialised later, when more kernel
+ * subsystems (like slab allocator) are available.
+ */
+ r->start = base;
+ r->size = size;
+ r->dev = dev;
+ cma_reserved_count++;
+ pr_info("CMA: reserved %ld MiB at %08lx\n", size / SZ_1M,
+ (unsigned long)base);
+
+ /* Architecture specific contiguous memory fixup. */
+ dma_contiguous_early_fixup(base, size);
+ return 0;
+err:
+ pr_err("CMA: failed to reserve %ld MiB\n", size / SZ_1M);
+ return base;
+}
+
+static struct page *__dma_alloc_from_contiguous(struct device *dev, int count,
+ unsigned int align)
+{
+ unsigned long mask, pfn, pageno, start = 0;
+ struct cma *cma = dev_get_cma_area(dev);
+ int ret;
+
+ if (!cma || !cma->count)
+ return NULL;
+
+ if (align > CONFIG_CMA_ALIGNMENT)
+ align = CONFIG_CMA_ALIGNMENT;
+
+ pr_debug("%s(cma %p, count %d, align %d)\n", __func__, (void *)cma,
+ count, align);
+
+ if (!count)
+ return NULL;
+
+ mask = (1 << align) - 1;
+
+ mutex_lock(&cma_mutex);
+
+ for (;;) {
+ pageno = bitmap_find_next_zero_area(cma->bitmap, cma->count,
+ start, count, mask);
+ if (pageno >= cma->count) {
+ printk(KERN_ERR "%s : cma->count is %lu, "
+ "pageno is %lu\n", __func__,
+ cma->count, pageno);
+ ret = -ENOMEM;
+ goto error;
+ }
+
+ pfn = cma->base_pfn + pageno;
+ ret = alloc_contig_range(pfn, pfn + count, MIGRATE_CMA);
+ if (ret == 0) {
+ bitmap_set(cma->bitmap, pageno, count);
+ break;
+ } else if (ret != -EBUSY && ret != -EAGAIN) {
+ goto error;
+ }
+ pr_debug("%s(): memory range at %p is busy, retrying\n",
+ __func__, pfn_to_page(pfn));
+ /* try again with a bit different memory target */
+ start = pageno + mask + 1;
+ }
+
+ mutex_unlock(&cma_mutex);
+
+ pr_debug("%s(): returned %p\n", __func__, pfn_to_page(pfn));
+ return pfn_to_page(pfn);
+error:
+ pr_err("%s(): returned error (%d)\n", __func__, ret);
+ mutex_unlock(&cma_mutex);
+ return NULL;
+}
+
+struct dma_prepare_alloc_ctx {
+ struct device *dev;
+ int count;
+ unsigned int align;
+ struct work_struct work;
+ struct list_head node;
+ struct page *result;
+};
+
+/* list of asynchronous allocations */
+static LIST_HEAD(dma_prepare_alloc_head);
+/* protects dma_prepare_alloc_head */
+static DEFINE_SPINLOCK(dma_prepare_alloc_lock);
+
+static void do_dma_prepare_alloc(struct work_struct *work)
+{
+ struct dma_prepare_alloc_ctx *ctx = container_of(
+ work, struct dma_prepare_alloc_ctx, work);
+
+ ctx->result = __dma_alloc_from_contiguous(ctx->dev, ctx->count,
+ ctx->align);
+ printk(KERN_INFO "%s[%d]: alloc %d pages for dev %s %s\n",
+ __func__, __LINE__, ctx->count, dev_name(ctx->dev),
+ ctx->result ? "succeeded" : "failed");
+}
+
+/**
+ * dma_prepare_alloc_from_contiguous() - prepare allocation of pages in
+ * an asynchronous thread
+ * @dev: Pointer to device for which the allocation is performed.
+ * @count: Requested number of pages.
+ * @align: Requested alignment of pages (in PAGE_SIZE order).
+ *
+ * This function prepares an allocation by scheduling it in a separate work
+ * thread. Once dma_alloc_from_contiguous is called then it searches
+ * the dma_prepare_alloc_head list in the first place.
+ */
+int dma_prepare_alloc_from_contiguous(struct device *dev, int count,
+ unsigned int align)
+{
+ struct dma_prepare_alloc_ctx *ctx;
+ unsigned long flags;
+
+ ctx = kzalloc(sizeof *ctx, GFP_KERNEL);
+ if (!ctx)
+ return -ENOMEM;
+
+ ctx->dev = dev;
+ ctx->count = count;
+ ctx->align = align;
+ INIT_WORK(&ctx->work, do_dma_prepare_alloc);
+
+ spin_lock_irqsave(&dma_prepare_alloc_lock, flags);
+ list_add_tail(&ctx->node, &dma_prepare_alloc_head);
+ spin_unlock_irqrestore(&dma_prepare_alloc_lock, flags);
+
+ queue_work(system_long_wq, &ctx->work);
+ return 0;
+}
+
+/**
+ * dma_alloc_from_contiguous() - allocate pages from contiguous area
+ * @dev: Pointer to device for which the allocation is performed.
+ * @count: Requested number of pages.
+ * @align: Requested alignment of pages (in PAGE_SIZE order).
+ *
+ * This function allocates memory buffer for specified device. It uses
+ * device specific contiguous memory area if available or the default
+ * global one. Requires architecture specific get_dev_cma_area() helper
+ * function.
+ */
+struct page *dma_alloc_from_contiguous(struct device *dev, int count,
+ unsigned int align)
+{
+ unsigned long flags;
+ struct list_head *i, *n;
+ struct dma_prepare_alloc_ctx *ctx = NULL;
+ struct page *result = NULL;
+
+ /* search for a cached allocation */
+ spin_lock_irqsave(&dma_prepare_alloc_lock, flags);
+ list_for_each_safe(i, n, &dma_prepare_alloc_head) {
+ ctx = list_entry(i, struct dma_prepare_alloc_ctx, node);
+ if (ctx->dev == dev && ctx->count == count &&
+ ctx->align == align) {
+ list_del(i);
+ break;
+ }
+ ctx = NULL;
+ }
+ spin_unlock_irqrestore(&dma_prepare_alloc_lock, flags);
+
+ /* If a cached allocation is found then use its result */
+ if (ctx) {
+ flush_work(&ctx->work);
+ result = ctx->result;
+ kfree(ctx);
+ }
+ /* fallback to sync allocation */
+ if (!result)
+ result = __dma_alloc_from_contiguous(dev, count, align);
+ return result;
+}
+
+/**
+ * dma_release_from_contiguous() - release allocated pages
+ * @dev: Pointer to device for which the pages were allocated.
+ * @pages: Allocated pages.
+ * @count: Number of allocated pages.
+ *
+ * This function releases memory allocated by dma_alloc_from_contiguous().
+ * It returns false when provided pages do not belong to contiguous area and
+ * true otherwise.
+ */
+bool dma_release_from_contiguous(struct device *dev, struct page *pages,
+ int count)
+{
+ struct cma *cma = dev_get_cma_area(dev);
+ unsigned long pfn;
+
+ if (!cma || !pages)
+ return false;
+
+ pr_debug("%s(page %p)\n", __func__, (void *)pages);
+
+ pfn = page_to_pfn(pages);
+
+ if (pfn < cma->base_pfn || pfn >= cma->base_pfn + cma->count) {
+ pr_info("%s : return false\n", __func__);
+ return false;
+ }
+
+ VM_BUG_ON(pfn + count > cma->base_pfn + cma->count);
+
+ mutex_lock(&cma_mutex);
+ bitmap_clear(cma->bitmap, pfn - cma->base_pfn, count);
+ free_contig_range(pfn, count);
+ mutex_unlock(&cma_mutex);
+
+ return true;
+}
diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c
index 06ed6b4..3719c94 100644
--- a/drivers/base/firmware_class.c
+++ b/drivers/base/firmware_class.c
@@ -226,13 +226,13 @@ static ssize_t firmware_loading_store(struct device *dev,
int loading = simple_strtol(buf, NULL, 10);
int i;
+ mutex_lock(&fw_lock);
+
+ if (!fw_priv->fw)
+ goto out;
+
switch (loading) {
case 1:
- mutex_lock(&fw_lock);
- if (!fw_priv->fw) {
- mutex_unlock(&fw_lock);
- break;
- }
firmware_free_data(fw_priv->fw);
memset(fw_priv->fw, 0, sizeof(struct firmware));
/* If the pages are not owned by 'struct firmware' */
@@ -243,7 +243,6 @@ static ssize_t firmware_loading_store(struct device *dev,
fw_priv->page_array_size = 0;
fw_priv->nr_pages = 0;
set_bit(FW_STATUS_LOADING, &fw_priv->status);
- mutex_unlock(&fw_lock);
break;
case 0:
if (test_bit(FW_STATUS_LOADING, &fw_priv->status)) {
@@ -274,7 +273,8 @@ static ssize_t firmware_loading_store(struct device *dev,
fw_load_abort(fw_priv);
break;
}
-
+out:
+ mutex_unlock(&fw_lock);
return count;
}
diff --git a/drivers/base/iommu.c b/drivers/base/iommu.c
new file mode 100644
index 0000000..6e6b6a1
--- /dev/null
+++ b/drivers/base/iommu.c
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 2007-2008 Advanced Micro Devices, Inc.
+ * Author: Joerg Roedel <joerg.roedel@amd.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.
+ *
+ * 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
+ */
+
+#include <linux/bug.h>
+#include <linux/types.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/errno.h>
+#include <linux/iommu.h>
+
+static struct iommu_ops *iommu_ops;
+
+void register_iommu(struct iommu_ops *ops)
+{
+ if (iommu_ops)
+ BUG();
+
+ iommu_ops = ops;
+}
+
+bool iommu_found(void)
+{
+ return iommu_ops != NULL;
+}
+EXPORT_SYMBOL_GPL(iommu_found);
+
+struct iommu_domain *iommu_domain_alloc(void)
+{
+ struct iommu_domain *domain;
+ int ret;
+
+ domain = kmalloc(sizeof(*domain), GFP_KERNEL);
+ if (!domain)
+ return NULL;
+
+ ret = iommu_ops->domain_init(domain);
+ if (ret)
+ goto out_free;
+
+ return domain;
+
+out_free:
+ kfree(domain);
+
+ return NULL;
+}
+EXPORT_SYMBOL_GPL(iommu_domain_alloc);
+
+void iommu_domain_free(struct iommu_domain *domain)
+{
+ iommu_ops->domain_destroy(domain);
+ kfree(domain);
+}
+EXPORT_SYMBOL_GPL(iommu_domain_free);
+
+int iommu_attach_device(struct iommu_domain *domain, struct device *dev)
+{
+ return iommu_ops->attach_dev(domain, dev);
+}
+EXPORT_SYMBOL_GPL(iommu_attach_device);
+
+void iommu_detach_device(struct iommu_domain *domain, struct device *dev)
+{
+ iommu_ops->detach_dev(domain, dev);
+}
+EXPORT_SYMBOL_GPL(iommu_detach_device);
+
+phys_addr_t iommu_iova_to_phys(struct iommu_domain *domain,
+ unsigned long iova)
+{
+ return iommu_ops->iova_to_phys(domain, iova);
+}
+EXPORT_SYMBOL_GPL(iommu_iova_to_phys);
+
+int iommu_domain_has_cap(struct iommu_domain *domain,
+ unsigned long cap)
+{
+ return iommu_ops->domain_has_cap(domain, cap);
+}
+EXPORT_SYMBOL_GPL(iommu_domain_has_cap);
+
+int iommu_map(struct iommu_domain *domain, unsigned long iova,
+ phys_addr_t paddr, int gfp_order, int prot)
+{
+ unsigned long invalid_mask;
+ size_t size;
+
+ size = 0x1000UL << gfp_order;
+ invalid_mask = size - 1;
+
+ BUG_ON((iova | paddr) & invalid_mask);
+
+ return iommu_ops->map(domain, iova, paddr, gfp_order, prot);
+}
+EXPORT_SYMBOL_GPL(iommu_map);
+
+int iommu_unmap(struct iommu_domain *domain, unsigned long iova, int gfp_order)
+{
+ unsigned long invalid_mask;
+ size_t size;
+
+ size = 0x1000UL << gfp_order;
+ invalid_mask = size - 1;
+
+ BUG_ON(iova & invalid_mask);
+
+ return iommu_ops->unmap(domain, iova, gfp_order);
+}
+EXPORT_SYMBOL_GPL(iommu_unmap);
diff --git a/drivers/base/sw_sync.c b/drivers/base/sw_sync.c
new file mode 100644
index 0000000..21ddf4f
--- /dev/null
+++ b/drivers/base/sw_sync.c
@@ -0,0 +1,256 @@
+/*
+ * drivers/base/sw_sync.c
+ *
+ * Copyright (C) 2012 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/file.h>
+#include <linux/fs.h>
+#include <linux/miscdevice.h>
+#include <linux/module.h>
+#include <linux/sw_sync.h>
+#include <linux/syscalls.h>
+#include <linux/uaccess.h>
+
+static int sw_sync_cmp(u32 a, u32 b)
+{
+ if (a == b)
+ return 0;
+
+ return ((s32)a - (s32)b) < 0 ? -1 : 1;
+}
+
+struct sync_pt *sw_sync_pt_create(struct sw_sync_timeline *obj, u32 value)
+{
+ struct sw_sync_pt *pt;
+
+ pt = (struct sw_sync_pt *)
+ sync_pt_create(&obj->obj, sizeof(struct sw_sync_pt));
+
+ pt->value = value;
+
+ return (struct sync_pt *)pt;
+}
+
+static struct sync_pt *sw_sync_pt_dup(struct sync_pt *sync_pt)
+{
+ struct sw_sync_pt *pt = (struct sw_sync_pt *) sync_pt;
+ struct sw_sync_timeline *obj =
+ (struct sw_sync_timeline *)sync_pt->parent;
+
+ return (struct sync_pt *) sw_sync_pt_create(obj, pt->value);
+}
+
+static int sw_sync_pt_has_signaled(struct sync_pt *sync_pt)
+{
+ struct sw_sync_pt *pt = (struct sw_sync_pt *)sync_pt;
+ struct sw_sync_timeline *obj =
+ (struct sw_sync_timeline *)sync_pt->parent;
+
+ return sw_sync_cmp(obj->value, pt->value) >= 0;
+}
+
+static int sw_sync_pt_compare(struct sync_pt *a, struct sync_pt *b)
+{
+ struct sw_sync_pt *pt_a = (struct sw_sync_pt *)a;
+ struct sw_sync_pt *pt_b = (struct sw_sync_pt *)b;
+
+ return sw_sync_cmp(pt_a->value, pt_b->value);
+}
+
+static void sw_sync_print_obj(struct seq_file *s,
+ struct sync_timeline *sync_timeline)
+{
+ struct sw_sync_timeline *obj = (struct sw_sync_timeline *)sync_timeline;
+
+ seq_printf(s, "%d", obj->value);
+}
+
+static void sw_sync_print_pt(struct seq_file *s, struct sync_pt *sync_pt)
+{
+ struct sw_sync_pt *pt = (struct sw_sync_pt *)sync_pt;
+ struct sw_sync_timeline *obj =
+ (struct sw_sync_timeline *)sync_pt->parent;
+
+ seq_printf(s, "%d / %d", pt->value, obj->value);
+}
+
+static int sw_sync_fill_driver_data(struct sync_pt *sync_pt,
+ void *data, int size)
+{
+ struct sw_sync_pt *pt = (struct sw_sync_pt *)sync_pt;
+
+ if (size < sizeof(pt->value))
+ return -ENOMEM;
+
+ memcpy(data, &pt->value, sizeof(pt->value));
+
+ return sizeof(pt->value);
+}
+
+struct sync_timeline_ops sw_sync_timeline_ops = {
+ .driver_name = "sw_sync",
+ .dup = sw_sync_pt_dup,
+ .has_signaled = sw_sync_pt_has_signaled,
+ .compare = sw_sync_pt_compare,
+ .print_obj = sw_sync_print_obj,
+ .print_pt = sw_sync_print_pt,
+ .fill_driver_data = sw_sync_fill_driver_data,
+};
+
+
+struct sw_sync_timeline *sw_sync_timeline_create(const char *name)
+{
+ struct sw_sync_timeline *obj = (struct sw_sync_timeline *)
+ sync_timeline_create(&sw_sync_timeline_ops,
+ sizeof(struct sw_sync_timeline),
+ name);
+
+ return obj;
+}
+
+void sw_sync_timeline_inc(struct sw_sync_timeline *obj, u32 inc)
+{
+ obj->value += inc;
+
+ sync_timeline_signal(&obj->obj);
+}
+
+
+#ifdef CONFIG_SW_SYNC_USER
+/* *WARNING*
+ *
+ * improper use of this can result in deadlocking kernel drivers from userspace.
+ */
+
+/* opening sw_sync create a new sync obj */
+int sw_sync_open(struct inode *inode, struct file *file)
+{
+ struct sw_sync_timeline *obj;
+ char task_comm[TASK_COMM_LEN];
+
+ get_task_comm(task_comm, current);
+
+ obj = sw_sync_timeline_create(task_comm);
+ if (obj == NULL)
+ return -ENOMEM;
+
+ file->private_data = obj;
+
+ return 0;
+}
+
+int sw_sync_release(struct inode *inode, struct file *file)
+{
+ struct sw_sync_timeline *obj = file->private_data;
+ sync_timeline_destroy(&obj->obj);
+ return 0;
+}
+
+long sw_sync_ioctl_create_fence(struct sw_sync_timeline *obj, unsigned long arg)
+{
+ int fd = get_unused_fd();
+ int err;
+ struct sync_pt *pt;
+ struct sync_fence *fence;
+ struct sw_sync_create_fence_data data;
+
+ if (copy_from_user(&data, (void __user *)arg, sizeof(data)))
+ return -EFAULT;
+
+ pt = sw_sync_pt_create(obj, data.value);
+ if (pt == NULL) {
+ err = -ENOMEM;
+ goto err;
+ }
+
+ data.name[sizeof(data.name) - 1] = '\0';
+ fence = sync_fence_create(data.name, pt);
+ if (fence == NULL) {
+ sync_pt_free(pt);
+ err = -ENOMEM;
+ goto err;
+ }
+
+ data.fence = fd;
+ if (copy_to_user((void __user *)arg, &data, sizeof(data))) {
+ sync_fence_put(fence);
+ err = -EFAULT;
+ goto err;
+ }
+
+ sync_fence_install(fence, fd);
+
+ return 0;
+
+err:
+ put_unused_fd(fd);
+ return err;
+}
+
+long sw_sync_ioctl_inc(struct sw_sync_timeline *obj, unsigned long arg)
+{
+ u32 value;
+
+ if (copy_from_user(&value, (void __user *)arg, sizeof(value)))
+ return -EFAULT;
+
+ sw_sync_timeline_inc(obj, value);
+
+ return 0;
+}
+
+long sw_sync_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+ struct sw_sync_timeline *obj = file->private_data;
+
+ switch (cmd) {
+ case SW_SYNC_IOC_CREATE_FENCE:
+ return sw_sync_ioctl_create_fence(obj, arg);
+
+ case SW_SYNC_IOC_INC:
+ return sw_sync_ioctl_inc(obj, arg);
+
+ default:
+ return -ENOTTY;
+ }
+}
+
+static const struct file_operations sw_sync_fops = {
+ .owner = THIS_MODULE,
+ .open = sw_sync_open,
+ .release = sw_sync_release,
+ .unlocked_ioctl = sw_sync_ioctl,
+};
+
+static struct miscdevice sw_sync_dev = {
+ .minor = MISC_DYNAMIC_MINOR,
+ .name = "sw_sync",
+ .fops = &sw_sync_fops,
+};
+
+int __init sw_sync_device_init(void)
+{
+ return misc_register(&sw_sync_dev);
+}
+
+void __exit sw_sync_device_remove(void)
+{
+ misc_deregister(&sw_sync_dev);
+}
+
+module_init(sw_sync_device_init);
+module_exit(sw_sync_device_remove);
+
+#endif /* CONFIG_SW_SYNC_USER */
diff --git a/drivers/base/sync.c b/drivers/base/sync.c
new file mode 100644
index 0000000..d6913f8
--- /dev/null
+++ b/drivers/base/sync.c
@@ -0,0 +1,801 @@
+/*
+ * drivers/base/sync.c
+ *
+ * Copyright (C) 2012 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/debugfs.h>
+#include <linux/file.h>
+#include <linux/fs.h>
+#include <linux/kernel.h>
+#include <linux/poll.h>
+#include <linux/sched.h>
+#include <linux/seq_file.h>
+#include <linux/slab.h>
+#include <linux/sync.h>
+#include <linux/uaccess.h>
+
+#include <linux/anon_inodes.h>
+
+static void sync_fence_signal_pt(struct sync_pt *pt);
+static int _sync_pt_has_signaled(struct sync_pt *pt);
+
+static LIST_HEAD(sync_timeline_list_head);
+static DEFINE_SPINLOCK(sync_timeline_list_lock);
+
+static LIST_HEAD(sync_fence_list_head);
+static DEFINE_SPINLOCK(sync_fence_list_lock);
+
+struct sync_timeline *sync_timeline_create(const struct sync_timeline_ops *ops,
+ int size, const char *name)
+{
+ struct sync_timeline *obj;
+ unsigned long flags;
+
+ if (size < sizeof(struct sync_timeline))
+ return NULL;
+
+ obj = kzalloc(size, GFP_KERNEL);
+ if (obj == NULL)
+ return NULL;
+
+ obj->ops = ops;
+ strlcpy(obj->name, name, sizeof(obj->name));
+
+ INIT_LIST_HEAD(&obj->child_list_head);
+ spin_lock_init(&obj->child_list_lock);
+
+ INIT_LIST_HEAD(&obj->active_list_head);
+ spin_lock_init(&obj->active_list_lock);
+
+ spin_lock_irqsave(&sync_timeline_list_lock, flags);
+ list_add_tail(&obj->sync_timeline_list, &sync_timeline_list_head);
+ spin_unlock_irqrestore(&sync_timeline_list_lock, flags);
+
+ return obj;
+}
+
+static void sync_timeline_free(struct sync_timeline *obj)
+{
+ unsigned long flags;
+
+ if (obj->ops->release_obj)
+ obj->ops->release_obj(obj);
+
+ spin_lock_irqsave(&sync_timeline_list_lock, flags);
+ list_del(&obj->sync_timeline_list);
+ spin_unlock_irqrestore(&sync_timeline_list_lock, flags);
+
+ kfree(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
+ sync_timeline_signal(obj);
+}
+
+static void sync_timeline_add_pt(struct sync_timeline *obj, struct sync_pt *pt)
+{
+ unsigned long flags;
+
+ pt->parent = obj;
+
+ spin_lock_irqsave(&obj->child_list_lock, flags);
+ list_add_tail(&pt->child_list, &obj->child_list_head);
+ spin_unlock_irqrestore(&obj->child_list_lock, flags);
+}
+
+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))
+ list_del_init(&pt->active_list);
+ 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);
+ spin_unlock_irqrestore(&obj->child_list_lock, flags);
+
+ if (needs_freeing)
+ sync_timeline_free(obj);
+}
+
+void sync_timeline_signal(struct sync_timeline *obj)
+{
+ unsigned long flags;
+ LIST_HEAD(signaled_pts);
+ struct list_head *pos, *n;
+
+ 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);
+ }
+
+ 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);
+
+ list_del_init(pos);
+ sync_fence_signal_pt(pt);
+ }
+}
+
+struct sync_pt *sync_pt_create(struct sync_timeline *parent, int size)
+{
+ struct sync_pt *pt;
+
+ if (size < sizeof(struct sync_pt))
+ return NULL;
+
+ pt = kzalloc(size, GFP_KERNEL);
+ if (pt == NULL)
+ return NULL;
+
+ INIT_LIST_HEAD(&pt->active_list);
+ sync_timeline_add_pt(parent, pt);
+
+ return pt;
+}
+
+void sync_pt_free(struct sync_pt *pt)
+{
+ if (pt->parent->ops->free_pt)
+ pt->parent->ops->free_pt(pt);
+
+ sync_timeline_remove_pt(pt);
+
+ kfree(pt);
+}
+
+/* call with pt->parent->active_list_lock held */
+static int _sync_pt_has_signaled(struct sync_pt *pt)
+{
+ int old_status = pt->status;
+
+ if (!pt->status)
+ pt->status = pt->parent->ops->has_signaled(pt);
+
+ if (!pt->status && pt->parent->destroyed)
+ pt->status = -ENOENT;
+
+ if (pt->status != old_status)
+ pt->timestamp = ktime_get();
+
+ return pt->status;
+}
+
+static struct sync_pt *sync_pt_dup(struct sync_pt *pt)
+{
+ return pt->parent->ops->dup(pt);
+}
+
+/* Adds a sync pt to the active queue. Called when added to a fence */
+static void sync_pt_activate(struct sync_pt *pt)
+{
+ struct sync_timeline *obj = pt->parent;
+ unsigned long flags;
+ int err;
+
+ spin_lock_irqsave(&obj->active_list_lock, flags);
+
+ err = _sync_pt_has_signaled(pt);
+ if (err != 0)
+ goto out;
+
+ list_add_tail(&pt->active_list, &obj->active_list_head);
+
+out:
+ spin_unlock_irqrestore(&obj->active_list_lock, flags);
+}
+
+static int sync_fence_release(struct inode *inode, struct file *file);
+static unsigned int sync_fence_poll(struct file *file, poll_table *wait);
+static long sync_fence_ioctl(struct file *file, unsigned int cmd,
+ unsigned long arg);
+
+
+static const struct file_operations sync_fence_fops = {
+ .release = sync_fence_release,
+ .poll = sync_fence_poll,
+ .unlocked_ioctl = sync_fence_ioctl,
+};
+
+static struct sync_fence *sync_fence_alloc(const char *name)
+{
+ struct sync_fence *fence;
+ unsigned long flags;
+
+ fence = kzalloc(sizeof(struct sync_fence), GFP_KERNEL);
+ if (fence == NULL)
+ return NULL;
+
+ fence->file = anon_inode_getfile("sync_fence", &sync_fence_fops,
+ fence, 0);
+ if (fence->file == NULL)
+ goto err;
+
+ strlcpy(fence->name, name, sizeof(fence->name));
+
+ INIT_LIST_HEAD(&fence->pt_list_head);
+ INIT_LIST_HEAD(&fence->waiter_list_head);
+ spin_lock_init(&fence->waiter_list_lock);
+
+ init_waitqueue_head(&fence->wq);
+
+ spin_lock_irqsave(&sync_fence_list_lock, flags);
+ list_add_tail(&fence->sync_fence_list, &sync_fence_list_head);
+ spin_unlock_irqrestore(&sync_fence_list_lock, flags);
+
+ return fence;
+
+err:
+ kfree(fence);
+ return NULL;
+}
+
+/* TODO: implement a create which takes more that one sync_pt */
+struct sync_fence *sync_fence_create(const char *name, struct sync_pt *pt)
+{
+ struct sync_fence *fence;
+
+ if (pt->fence)
+ return NULL;
+
+ fence = sync_fence_alloc(name);
+ if (fence == NULL)
+ return NULL;
+
+ pt->fence = fence;
+ list_add(&pt->pt_list, &fence->pt_list_head);
+ sync_pt_activate(pt);
+
+ return fence;
+}
+
+static int sync_fence_copy_pts(struct sync_fence *dst, struct sync_fence *src)
+{
+ struct list_head *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);
+
+ 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_free_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_pt_free(pt);
+ }
+}
+
+struct sync_fence *sync_fence_fdget(int fd)
+{
+ struct file *file = fget(fd);
+
+ if (file == NULL)
+ return NULL;
+
+ if (file->f_op != &sync_fence_fops)
+ goto err;
+
+ return file->private_data;
+
+err:
+ fput(file);
+ return NULL;
+}
+
+void sync_fence_put(struct sync_fence *fence)
+{
+ fput(fence->file);
+}
+
+void sync_fence_install(struct sync_fence *fence, int fd)
+{
+ fd_install(fd, fence->file);
+}
+
+static int sync_fence_get_status(struct sync_fence *fence)
+{
+ struct list_head *pos;
+ int status = 1;
+
+ 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;
+
+ if (pt_status < 0) {
+ status = pt_status;
+ break;
+ } else if (status == 1) {
+ status = pt_status;
+ }
+ }
+
+ return status;
+}
+
+struct sync_fence *sync_fence_merge(const char *name,
+ struct sync_fence *a, struct sync_fence *b)
+{
+ struct sync_fence *fence;
+ int err;
+
+ fence = sync_fence_alloc(name);
+ if (fence == NULL)
+ return NULL;
+
+ err = sync_fence_copy_pts(fence, a);
+ if (err < 0)
+ goto err;
+
+ err = sync_fence_copy_pts(fence, b);
+ if (err < 0)
+ goto err;
+
+ fence->status = sync_fence_get_status(fence);
+
+ return fence;
+err:
+ sync_fence_free_pts(fence);
+ kfree(fence);
+ return NULL;
+}
+
+static void sync_fence_signal_pt(struct sync_pt *pt)
+{
+ LIST_HEAD(signaled_waiters);
+ struct sync_fence *fence = pt->fence;
+ struct list_head *pos;
+ struct list_head *n;
+ unsigned long flags;
+ int status;
+
+ status = sync_fence_get_status(fence);
+
+ spin_lock_irqsave(&fence->waiter_list_lock, flags);
+ /*
+ * this should protect against two threads racing on the signaled
+ * false -> true transition
+ */
+ if (status && !fence->status) {
+ list_for_each_safe(pos, n, &fence->waiter_list_head)
+ list_move(pos, &signaled_waiters);
+
+ fence->status = status;
+ } else {
+ status = 0;
+ }
+ spin_unlock_irqrestore(&fence->waiter_list_lock, flags);
+
+ if (status) {
+ list_for_each_safe(pos, n, &signaled_waiters) {
+ struct sync_fence_waiter *waiter =
+ container_of(pos, struct sync_fence_waiter,
+ waiter_list);
+
+ waiter->callback(fence, waiter->callback_data);
+ list_del(pos);
+ kfree(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;
+ 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;
+ }
+
+ list_add_tail(&waiter->waiter_list, &fence->waiter_list_head);
+out:
+ spin_unlock_irqrestore(&fence->waiter_list_lock, flags);
+
+ return err;
+}
+
+int sync_fence_wait(struct sync_fence *fence, long timeout)
+{
+ int err;
+
+ if (timeout) {
+ timeout = msecs_to_jiffies(timeout);
+ err = wait_event_interruptible_timeout(fence->wq,
+ fence->status != 0,
+ timeout);
+ } else {
+ err = wait_event_interruptible(fence->wq, fence->status != 0);
+ }
+
+ if (err < 0)
+ return err;
+
+ if (fence->status < 0)
+ return fence->status;
+
+ if (fence->status == 0)
+ return -ETIME;
+
+ return 0;
+}
+
+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);
+
+ spin_lock_irqsave(&sync_fence_list_lock, flags);
+ list_del(&fence->sync_fence_list);
+ spin_unlock_irqrestore(&sync_fence_list_lock, flags);
+
+ kfree(fence);
+
+ return 0;
+}
+
+static unsigned int sync_fence_poll(struct file *file, poll_table *wait)
+{
+ struct sync_fence *fence = file->private_data;
+
+ poll_wait(file, &fence->wq, wait);
+
+ if (fence->status == 1)
+ return POLLIN;
+ else if (fence->status < 0)
+ return POLLERR;
+ else
+ return 0;
+}
+
+static long sync_fence_ioctl_wait(struct sync_fence *fence, unsigned long arg)
+{
+ __u32 value;
+
+ if (copy_from_user(&value, (void __user *)arg, sizeof(value)))
+ return -EFAULT;
+
+ return sync_fence_wait(fence, value);
+}
+
+static long sync_fence_ioctl_merge(struct sync_fence *fence, unsigned long arg)
+{
+ int fd = get_unused_fd();
+ int err;
+ struct sync_fence *fence2, *fence3;
+ struct sync_merge_data data;
+
+ if (copy_from_user(&data, (void __user *)arg, sizeof(data)))
+ return -EFAULT;
+
+ fence2 = sync_fence_fdget(data.fd2);
+ if (fence2 == NULL) {
+ err = -ENOENT;
+ goto err_put_fd;
+ }
+
+ data.name[sizeof(data.name) - 1] = '\0';
+ fence3 = sync_fence_merge(data.name, fence, fence2);
+ if (fence3 == NULL) {
+ err = -ENOMEM;
+ goto err_put_fence2;
+ }
+
+ data.fence = fd;
+ if (copy_to_user((void __user *)arg, &data, sizeof(data))) {
+ err = -EFAULT;
+ goto err_put_fence3;
+ }
+
+ sync_fence_install(fence3, fd);
+ sync_fence_put(fence2);
+ return 0;
+
+err_put_fence3:
+ sync_fence_put(fence3);
+
+err_put_fence2:
+ sync_fence_put(fence2);
+
+err_put_fd:
+ put_unused_fd(fd);
+ return err;
+}
+
+int sync_fill_pt_info(struct sync_pt *pt, void *data, int size)
+{
+ struct sync_pt_info *info = data;
+ int ret;
+
+ if (size < sizeof(struct sync_pt_info))
+ return -ENOMEM;
+
+ info->len = sizeof(struct sync_pt_info);
+
+ if (pt->parent->ops->fill_driver_data) {
+ ret = pt->parent->ops->fill_driver_data(pt, info->driver_data,
+ size - sizeof(*info));
+ if (ret < 0)
+ return ret;
+
+ info->len += ret;
+ }
+
+ strlcpy(info->obj_name, pt->parent->name, sizeof(info->obj_name));
+ strlcpy(info->driver_name, pt->parent->ops->driver_name,
+ sizeof(info->driver_name));
+ info->status = pt->status;
+ info->timestamp_ns = ktime_to_ns(pt->timestamp);
+
+ return info->len;
+}
+
+
+static long sync_fence_ioctl_fence_info(struct sync_fence *fence,
+ unsigned long arg)
+{
+ struct sync_fence_info_data *data;
+ struct list_head *pos;
+ __u32 size;
+ __u32 len = 0;
+ int ret;
+
+ if (copy_from_user(&size, (void __user *)arg, sizeof(size)))
+ return -EFAULT;
+
+ if (size < sizeof(struct sync_fence_info_data))
+ return -EINVAL;
+
+ if (size > 4096)
+ size = 4096;
+
+ data = kzalloc(size, GFP_KERNEL);
+ if (data == NULL)
+ return -ENOMEM;
+
+ strlcpy(data->name, fence->name, sizeof(data->name));
+ data->status = fence->status;
+ len = sizeof(struct sync_fence_info_data);
+
+ list_for_each(pos, &fence->pt_list_head) {
+ struct sync_pt *pt =
+ container_of(pos, struct sync_pt, pt_list);
+
+ ret = sync_fill_pt_info(pt, (u8 *)data + len, size - len);
+
+ if (ret < 0)
+ goto out;
+
+ len += ret;
+ }
+
+ data->len = len;
+
+ if (copy_to_user((void __user *)arg, data, len))
+ ret = -EFAULT;
+ else
+ ret = 0;
+
+out:
+ kfree(data);
+
+ return ret;
+}
+
+static long sync_fence_ioctl(struct file *file, unsigned int cmd,
+ unsigned long arg)
+{
+ struct sync_fence *fence = file->private_data;
+ switch (cmd) {
+ case SYNC_IOC_WAIT:
+ return sync_fence_ioctl_wait(fence, arg);
+
+ case SYNC_IOC_MERGE:
+ return sync_fence_ioctl_merge(fence, arg);
+
+ case SYNC_IOC_FENCE_INFO:
+ return sync_fence_ioctl_fence_info(fence, arg);
+
+ default:
+ return -ENOTTY;
+ }
+}
+
+#ifdef CONFIG_DEBUG_FS
+static const char *sync_status_str(int status)
+{
+ if (status > 0)
+ return "signaled";
+ else if (status == 0)
+ return "active";
+ else
+ return "error";
+}
+
+static void sync_print_pt(struct seq_file *s, struct sync_pt *pt, bool fence)
+{
+ int status = pt->status;
+ seq_printf(s, " %s%spt %s",
+ fence ? pt->parent->name : "",
+ fence ? "_" : "",
+ sync_status_str(status));
+ if (pt->status) {
+ struct timeval tv = ktime_to_timeval(pt->timestamp);
+ seq_printf(s, "@%ld.%06ld", tv.tv_sec, tv.tv_usec);
+ }
+
+ if (pt->parent->ops->print_pt) {
+ seq_printf(s, ": ");
+ pt->parent->ops->print_pt(s, pt);
+ }
+
+ seq_printf(s, "\n");
+}
+
+static void sync_print_obj(struct seq_file *s, struct sync_timeline *obj)
+{
+ struct list_head *pos;
+ unsigned long flags;
+
+ seq_printf(s, "%s %s", obj->name, obj->ops->driver_name);
+
+ if (obj->ops->print_obj) {
+ seq_printf(s, ": ");
+ obj->ops->print_obj(s, obj);
+ }
+
+ seq_printf(s, "\n");
+
+ spin_lock_irqsave(&obj->child_list_lock, flags);
+ list_for_each(pos, &obj->child_list_head) {
+ struct sync_pt *pt =
+ container_of(pos, struct sync_pt, child_list);
+ sync_print_pt(s, pt, false);
+ }
+ spin_unlock_irqrestore(&obj->child_list_lock, flags);
+}
+
+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));
+
+ list_for_each(pos, &fence->pt_list_head) {
+ struct sync_pt *pt =
+ container_of(pos, struct sync_pt, pt_list);
+ sync_print_pt(s, pt, true);
+ }
+
+ spin_lock_irqsave(&fence->waiter_list_lock, flags);
+ list_for_each(pos, &fence->waiter_list_head) {
+ struct sync_fence_waiter *waiter =
+ container_of(pos, struct sync_fence_waiter,
+ waiter_list);
+
+ seq_printf(s, "waiter %pF %p\n", waiter->callback,
+ waiter->callback_data);
+ }
+ spin_unlock_irqrestore(&fence->waiter_list_lock, flags);
+}
+
+static int sync_debugfs_show(struct seq_file *s, void *unused)
+{
+ unsigned long flags;
+ struct list_head *pos;
+
+ seq_printf(s, "objs:\n--------------\n");
+
+ spin_lock_irqsave(&sync_timeline_list_lock, flags);
+ list_for_each(pos, &sync_timeline_list_head) {
+ struct sync_timeline *obj =
+ container_of(pos, struct sync_timeline,
+ sync_timeline_list);
+
+ sync_print_obj(s, obj);
+ seq_printf(s, "\n");
+ }
+ spin_unlock_irqrestore(&sync_timeline_list_lock, flags);
+
+ seq_printf(s, "fences:\n--------------\n");
+
+ spin_lock_irqsave(&sync_fence_list_lock, flags);
+ list_for_each(pos, &sync_fence_list_head) {
+ struct sync_fence *fence =
+ container_of(pos, struct sync_fence, sync_fence_list);
+
+ sync_print_fence(s, fence);
+ seq_printf(s, "\n");
+ }
+ spin_unlock_irqrestore(&sync_fence_list_lock, flags);
+ return 0;
+}
+
+static int sync_debugfs_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, sync_debugfs_show, inode->i_private);
+}
+
+static const struct file_operations sync_debugfs_fops = {
+ .open = sync_debugfs_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
+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);
+
+#endif
diff --git a/drivers/interceptor/Kconfig b/drivers/interceptor/Kconfig
new file mode 100644
index 0000000..8d8a30a
--- /dev/null
+++ b/drivers/interceptor/Kconfig
@@ -0,0 +1,3 @@
+config AUTHENTEC_VPNCLIENT_INTERCEPTOR
+ tristate "AuthenTec VPNClient Interceptor"
+ default n
diff --git a/drivers/interceptor/Makefile b/drivers/interceptor/Makefile
new file mode 100644
index 0000000..28c4223
--- /dev/null
+++ b/drivers/interceptor/Makefile
@@ -0,0 +1,26 @@
+obj-$(CONFIG_AUTHENTEC_VPNCLIENT_INTERCEPTOR) := vpnclient.o
+
+vpnclient-y := \
+ kernel_alloc.o \
+ kernel_encode.o \
+ linux_hook_magic.o \
+ linux_iface.o \
+ linux_ip_glue.o \
+ linux_ipm.o \
+ linux_kernel_alloc.o \
+ linux_main.o \
+ linux_usermode.o \
+ linux_virtual_adapter.o \
+ linux_mutex.o \
+ linux_packet.o \
+ linux_procfs.o \
+ linux_route.o \
+ sshinetbits.o \
+ sshinetencode.o \
+ sshinetprint.o \
+ usermodeforwarder.o
+
+override EXTRA_CFLAGS += \
+ -DKERNEL \
+ -D_KERNEL \
+ -DWITH_IPV6
diff --git a/drivers/interceptor/engine.h b/drivers/interceptor/engine.h
new file mode 100644
index 0000000..e1bf35b
--- /dev/null
+++ b/drivers/interceptor/engine.h
@@ -0,0 +1,114 @@
+/* Netfilter Driver for IPSec VPN Client
+ *
+ * Copyright(c) 2012 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.
+ */
+
+/*
+ * engine.h
+ *
+ * Engine API specifies the Engine side interface between the Interceptor
+ * and the Engine components.
+ *
+ */
+
+#ifndef ENGINE_H
+#define ENGINE_H
+
+/******************************** Data types ********************************/
+
+/* Definition of the type for the engine object. */
+typedef struct SshEngineRec *SshEngine;
+
+/* A function of this type is used to send messages from the engine to
+ the policy manager. The function should return TRUE if the message
+ was actually sent, and FALSE otherwise. This should always
+ eventually free `data' with ssh_free. The packet in the buffer
+ starts with a 32-bit length MSB first. If the connection to the
+ policy manager is not open, this should return FALSE and free
+ `data' using ssh_free. Warning: this function is called from
+ ssh_debug and ssh_warning; thus, this is not allowed to emit
+ debugging or warning messages. This function can be called
+ concurrently, and must perform appropriate locking. */
+typedef Boolean (*SshEngineSendProc)(unsigned char *data, size_t len,
+ Boolean reliable,
+ void *machine_context);
+
+/***************************************************************************
+ * Functions called by the machine-dependent main program
+ ***************************************************************************/
+
+/* Flags for the ssh_engine_start function. */
+#define SSH_ENGINE_DROP_IF_NO_IPM 0x00000001
+#define SSH_ENGINE_NO_FORWARDING 0x00000002
+
+/* Creates the engine object. Among other things, this opens the
+ interceptor, initializes filters to default values, and arranges to send
+ messages to the policy manager using the send procedure. The send
+ procedure will not be called until from the bottom of the event loop.
+ The `machine_context' argument is passed to the interceptor and the
+ `send' callback, but is not used otherwise. This function can be
+ called concurrently for different machine contexts, but not otherwise.
+ The first packet and interface callbacks may arrive before this has
+ returned. */
+SshEngine ssh_engine_start(SshEngineSendProc send,
+ void *machine_context,
+ SshUInt32 flags);
+
+/* Stops the engine, closes the interceptor, and destroys the
+ engine object. This does not notify IPM interface of the close;
+ that must be done by the caller before calling this. This returns
+ TRUE if the engine was successfully stopped (and the object freed),
+ and FALSE if the engine cannot yet be freed because there are
+ threads inside the engine or uncancellable callbacks expected to
+ arrive. When this returns FALSE, the engine has started stopping,
+ and this should be called again after a while. This function can
+ be called concurrently with packet/interface callbacks or timeouts
+ for this engine, or any functions for other engines.*/
+Boolean ssh_engine_stop(SshEngine engine);
+
+/* The machine-specific main program should call this when the policy
+ manager has opened the connection to the engine. This also
+ sends the version packet to the policy manager. This function can
+ be called concurrently with packet/interface callbacks or timeouts. */
+void ssh_engine_notify_ipm_open(SshEngine engine);
+
+/* This function is called whenever the policy manager closes the
+ connection to the engine. This is also called when the engine is
+ stopped. This function can be called concurrently with
+ packet/interface callbacks or timeouts. */
+void ssh_engine_notify_ipm_close(SshEngine engine);
+
+/* This function should be called by the machine-dependent main
+ program whenever a packet for this engine is received from
+ the policy manager. The data should not contain the 32-bit length
+ or the type (they have already been processed at this stage, to
+ check for possible machine-specific packets). The `data' argument
+ remains valid until this function returns; it should not be freed
+ by this function. This function can be called concurrently. */
+void ssh_engine_packet_from_ipm(SshEngine engine,
+ SshUInt32 type,
+ const unsigned char *data, size_t len);
+
+/******************************** Version global ****************************/
+
+/* This is statically (compile-time) initialized to SSH_ENGINE_VERSION */
+extern const char ssh_engine_version[];
+
+/* This is statically (compile-time) initialized to a value containing
+ information about the SSH_ENGINE_VERSION, compilation time,
+ compiler etc. etc. etc. It can be used by interceptors, usermode
+ engine etc. for startup output or somesuch. Debug information,
+ basically, and can vary quite much depending on the compilation
+ environment. */
+extern const char ssh_engine_compile_version[];
+
+/* Suffix to append to the device name. This is defined by the
+ engine. */
+extern const char ssh_device_suffix[];
+
+#endif /* ENGINE_H */
diff --git a/drivers/interceptor/engine_alloc.h b/drivers/interceptor/engine_alloc.h
new file mode 100644
index 0000000..f4a11c7
--- /dev/null
+++ b/drivers/interceptor/engine_alloc.h
@@ -0,0 +1,32 @@
+/* Netfilter Driver for IPSec VPN Client
+ *
+ * Copyright(c) 2012 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.
+ */
+
+/*
+ * engine_alloc.h
+ *
+ * Engine memory allocation API.
+ *
+ */
+
+#ifndef ENGINE_ALLOC_H
+#define ENGINE_ALLOC_H
+
+void *ssh_malloc(size_t size);
+void *ssh_malloc_flags(size_t size, SshUInt32 flags);
+void *ssh_realloc(void *ptr, size_t old_size, size_t new_size);
+void *ssh_realloc_flags(void *ptr, size_t old_size, size_t new_size,
+ SshUInt32 flags);
+void *ssh_calloc(size_t nitems, size_t size);
+void *ssh_calloc_flags(size_t nitems, size_t size, SshUInt32 flags);
+void *ssh_strdup(const void *p);
+void *ssh_memdup(const void *p, size_t len);
+void ssh_free(void *ptr);
+
+#endif /* ENGINE_ALLOC_H */
diff --git a/drivers/interceptor/interceptor.h b/drivers/interceptor/interceptor.h
new file mode 100644
index 0000000..054daf1
--- /dev/null
+++ b/drivers/interceptor/interceptor.h
@@ -0,0 +1,720 @@
+/* Netfilter Driver for IPSec VPN Client
+ *
+ * Copyright(c) 2012 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.
+ */
+
+/*
+ * interceptor.h
+ *
+ * Interceptor API specifies the Interceptor side interface between
+ * the Interceptor and Engine components. This API contains functions
+ * for Interceptor initialization, packet allocation, packet data access,
+ * routing and packet sending.
+ *
+ */
+
+#ifndef INTERCEPTOR_H
+#define INTERCEPTOR_H
+
+#include "sshinet.h"
+
+/** The amount of space to reserve in packet header for the IPsec engine. */
+#define SSH_INTERCEPTOR_UPPER_DATA_SIZE 192
+
+/** The number of available extension selectors for platform-specific
+ extensions. */
+#define SSH_INTERCEPTOR_NUM_EXTENSION_SELECTORS 1
+
+/** Size of interface system name. */
+#define SSH_INTERCEPTOR_IFNAME_SIZE 64
+
+/** Data type for the interceptor context. */
+typedef struct SshInterceptorRec *SshInterceptor;
+
+/** This type defines the type of a network interface interface. The
+ type is supposed to be sufficient to determine how to process the
+ packets. It is not expected to provide maximal detail to the
+ user. Regardless of the interface type, the higher-level code
+ should not assume that incoming packets have been defragmented,
+ nor will it assume that the interceptor will perform fragmentation
+ for outgoing packets. Thus, it will perform these functions
+ itself. It will not assume the underlying interceptor will do it.
+ Routing will also be done by the higher level to determine which
+ interface a packet should go out from. */
+typedef enum {
+ SSH_INTERCEPTOR_MEDIA_NONEXISTENT, /** The interface is not available */
+ SSH_INTERCEPTOR_MEDIA_PLAIN, /** Any interceptor w/o media headers*/
+ SSH_INTERCEPTOR_MEDIA_ETHERNET, /** Ethernet (rfc894) framing */
+ SSH_INTERCEPTOR_MEDIA_FDDI, /** FDDI (rfc1042/rfc1103) framing */
+ SSH_INTERCEPTOR_MEDIA_TOKENRING, /** Tokenring (rfc1042/rfc1469) framing */
+ /** New types may be added here. Look for one of the existing types
+ to find all places in code that should be updated. */
+ SSH_INTERCEPTOR_NUM_MEDIAS /** Must be the last entry! */
+} SshInterceptorMedia;
+
+/** Protocol identifiers. These identify recognized protocols (packet
+ formats) in a portable manner. This enumeration includes media
+ types, but also all recognized higher-level protocols. */
+typedef enum
+{
+ SSH_PROTOCOL_IP4, /** IPv4 frame */
+ SSH_PROTOCOL_IP6, /** IPv6 frame */
+ SSH_PROTOCOL_IPX, /** IPX frame */
+ SSH_PROTOCOL_ETHERNET, /** Ethernet frame */
+ SSH_PROTOCOL_FDDI, /** FDDI frame */
+ SSH_PROTOCOL_TOKENRING, /** Token Ring frame */
+ SSH_PROTOCOL_ARP, /** ARP frame */
+ SSH_PROTOCOL_OTHER, /** some other type frame */
+ SSH_PROTOCOL_NUM_PROTOCOLS /** must be the last entry! */
+} SshInterceptorProtocol;
+
+/** Data type for an interface number. This type must be atleast as big as
+ the system interface index. */
+typedef SshUInt32 SshInterceptorIfnum;
+
+/** Maximum value of interface number.
+ All valid interface numbers must be smaller than this value. */
+#define SSH_INTERCEPTOR_MAX_IFNUM ((SshInterceptorIfnum) 0xffffffff)
+
+/** Reserved value for invalid interface number. */
+#define SSH_INTERCEPTOR_INVALID_IFNUM SSH_INTERCEPTOR_MAX_IFNUM
+
+/** Data structure for representing an address for a network interface. */
+typedef struct SshInterfaceAddressRec
+{
+ /** Protocol for which the address is. */
+ SshInterceptorProtocol protocol;
+
+ /** The address itself. */
+ union
+ {
+ /** IPv4 and IPv6. */
+ struct
+ {
+ SshIpAddrStruct ip;
+ SshIpAddrStruct mask;
+ SshIpAddrStruct broadcast;
+ } ip;
+
+ /** IPX */
+ struct
+ {
+ SshUInt32 net;
+ unsigned char host[6];
+ } ns;
+ } addr;
+} *SshInterfaceAddress, SshInterfaceAddressStruct;
+
+/** Flags for the media direction information. */
+
+/** Do not fragment before sending from engine. */
+#define SSH_INTERCEPTOR_MEDIA_INFO_NO_FRAGMENT 0x0001
+
+/** Accessor for mtu member in SshInterceptorMediaDirectionInfo. */
+#ifdef WITH_IPV6
+#define SSH_INTERCEPTOR_MEDIA_INFO_MTU(info, is_ipv6) \
+ ((is_ipv6) ? (info)->mtu_ipv6 : (info)->mtu_ipv4)
+#else /* WITH_IPV6 */
+#define SSH_INTERCEPTOR_MEDIA_INFO_MTU(info, is_ipv6) \
+ ((info)->mtu_ipv4)
+#endif /* WITH_IPV6 */
+
+/** Media direction information. This information is used when engine
+ is sending packets to the interceptor. */
+typedef struct SshInterceptorMediaDirectionInfoRec
+{
+ SshInterceptorMedia media; /* media type */
+ SshUInt32 flags; /* flags */
+ size_t mtu_ipv4; /* mtu for the direction (ipv4) */
+#ifdef WITH_IPV6
+ size_t mtu_ipv6; /* mtu for the direction (ipv6) */
+#endif /* WITH_IPV6 */
+} *SshInterceptorMediaDirectionInfo, SshInterceptorMediaDirectionInfoStruct;
+
+/** Flag values for flags in SshInterceptorInterface */
+/* Interface type */
+#define SSH_INTERFACE_FLAG_VIP 0x0001
+#define SSH_INTERFACE_FLAG_POINTOPOINT 0x0002
+#define SSH_INTERFACE_FLAG_BROADCAST 0x0004
+/* Interface link status */
+#define SSH_INTERFACE_FLAG_LINK_DOWN 0x0100
+
+/** Data structure for providing information about a network
+ interface. */
+typedef struct
+{
+ SshInterceptorMediaDirectionInfoStruct to_protocol;
+ SshInterceptorMediaDirectionInfoStruct to_adapter;
+ char name[SSH_INTERCEPTOR_IFNAME_SIZE]; /** system name for the interface */
+ SshInterceptorIfnum ifnum; /** Interface number */
+ SshUInt32 num_addrs; /** Number of addresses for the interface. */
+ SshInterfaceAddress addrs; /** mallocated array of address structures. */
+ unsigned char media_addr[16]; /** MAC address, medium size and format */
+ size_t media_addr_len; /** Length of the MAC address. */
+
+ SshUInt32 flags; /** Flags for the interface. */
+
+ /** Context pointer for owner/user for this SshInterceptorInterface.
+ Can be used for e.g. storing interface-specific
+ NAT-configuration. */
+ void *ctx_user;
+} SshInterceptorInterface;
+
+/* Packet flag bits. */
+#define SSH_PACKET_FROMPROTOCOL 0x00000001U /** Packet from the protocol. */
+#define SSH_PACKET_FROMADAPTER 0x00000002U /** Packet from the adapter. */
+#define SSH_PACKET_IP4HDRCKSUMOK 0x00000004U /** IPv4 header cksum checked. */
+#define SSH_PACKET_FORWARDED 0x00000008U /** Packet was forwarded. */
+#define SSH_PACKET_HWCKSUM 0x00000010U /** TCP/UDP cksum done by NIC. */
+#define SSH_PACKET_MEDIABCAST 0x00000020U /** Packet was media broadcast. */
+#define SSH_PACKET_UNMODIFIED 0x00000200U /** Unmodified packet. */
+
+/* This flag specifies that the engine is allowed to fragment the packet if
+ the packet is too large to fit into interafce MTU. Some operating
+ system handle the fragmentation after us and therefore this flag
+ may be set for some outbound data packets. The packet is guaranteed
+ to have been originated from local stack and stack has indicated
+ that this packet can be fragmented. */
+#define SSH_PACKET_FRAGMENTATION_ALLOWED 0x00000400U
+
+/* Flag bits with mask 0x00000fff are reserved for interceptor. */
+/* Flag bits with mask 0xfffff000 are reserved for IPSEC engine. */
+
+/** Macro to access upper-level data in the packet header. */
+#define SSH_INTERCEPTOR_PACKET_DATA(packet, type) \
+ ((type)(&(packet)->upper_data))
+
+/** Data structure for a packet. These data structures can only be
+ allocated by the interceptor; higher-level code must never
+ directly allocate these (the interceptor implementation may
+ actually use a larger structure containing this public
+ structure). */
+typedef struct SshInterceptorPacketRec
+{
+ /** Flags for the packet. The SSH_PACKET_* bitmasks are used. Code
+ above the interceptor is not allowed to modify flags 0x001-0x800;
+ they may be used internally by the interceptor to pass
+ information from packet_cb/ssh_interceptor_packet_alloc to
+ ssh_interceptor_send/ssh_interceptor_packet_free. During
+ certain times, such when applying asynchronous IPSEC
+ transformations, this field may be changed concurrently by
+ another thread (or interrupt) even when another thread is
+ processing the packet. Care should be taken with locking in
+ those situations. */
+ SshUInt32 flags;
+
+ /** Number of the interface that this packet arrived from */
+ SshInterceptorIfnum ifnum_in;
+
+ /** Number of the interface that this packet going out */
+ SshInterceptorIfnum ifnum_out;
+
+ /** Format of the packet (protocol identifier). */
+ SshInterceptorProtocol protocol;
+
+ /** Path MTU stored for this packet, which must be respected at
+ media send (if interface MTU is smaller than this value, then
+ the media send routine must send ICMP PMTU message and discard
+ the packet). If 0, means use the interface MTU only. */
+ SshUInt32 pmtu;
+
+#if (SSH_INTERCEPTOR_NUM_EXTENSION_SELECTORS > 0)
+ /** Platform-dependent extension selectors for things like user id,
+ virtual network identifier, etc. */
+ SshUInt32 extension[SSH_INTERCEPTOR_NUM_EXTENSION_SELECTORS];
+#endif /* (SSH_INTERCEPTOR_NUM_EXTENSION_SELECTORS > 0) */
+
+#ifdef SSH_IPSEC_IP_ONLY_INTERCEPTOR
+ /** Route key selector that was used in the route lookup */
+ SshUInt16 route_selector;
+#endif /* SSH_IPSEC_IP_ONLY_INTERCEPTOR */
+
+ /** Buffer that can be used by higher level software to store its
+ data (such as cached media addresses). This field can only be
+ accessed using the SSH_INTERCEPTOR_PACKET_DATA macro. */
+ union {
+ /** Contents of this union are private (they are there to
+ guarantee proper alignment for any data structure stored
+ here). */
+ long force_alignment_l; int force_alignment_i; short force_alignment_s;
+ void *force_alignment_v;
+ SshUInt16 force_alignment_i16; SshUInt32 force_alignment_i32;
+ SshUInt64 force_alignment_i64;
+ char force_size_dont_use_this_directly[SSH_INTERCEPTOR_UPPER_DATA_SIZE];
+ /* Should have double here if floating point was allowed. */
+ } upper_data;
+
+ /** Next pointer on freelist. This can also be used by higher-level
+ code to put the packet on a list. */
+ struct SshInterceptorPacketRec *next;
+} *SshInterceptorPacket, SshInterceptorPacketStruct;
+
+/** Error codes for route add / remove functions. */
+typedef enum {
+ SSH_INTERCEPTOR_ROUTE_ERROR_OK = 0,
+ SSH_INTERCEPTOR_ROUTE_ERROR_NONEXISTENT = 1,
+ SSH_INTERCEPTOR_ROUTE_ERROR_OUT_OF_MEMORY = 2,
+ SSH_INTERCEPTOR_ROUTE_ERROR_ALREADY_EXISTS = 3,
+ SSH_INTERCEPTOR_ROUTE_ERROR_UNDEFINED = 255
+} SshInterceptorRouteError;
+
+/** Flag values for the route add / remove functions. */
+
+/** Ignore non-existent routes when attempting to remove the route. */
+#define SSH_INTERCEPTOR_ROUTE_FLAG_IGNORE_NONEXISTENT 0x0001
+
+/** Data structure for routing key, used in route lookups and routing table
+ manipulation.
+
+ The route lookup is performed for the destination address, using other
+ fields in the routing key to enforce routing policies. It is a fatal
+ error to call ssh_interceptor_route using a SshInterceptorRouteKey
+ which does not have the destination address set.
+
+ Use the provided macros for setting fields in SshInterceptorRouteKey.
+
+ Note that on platforms that do not support policy routing, the route lookup
+ uses only the destination address. On other platforms other fields of the
+ SshInterceptorRouteKey may be used in the route lookup. */
+typedef struct SshInterceptorRouteKeyRec
+{
+ /** Destination address, mandatory */
+ SshIpAddrStruct dst;
+ /** Source address, optional */
+ SshIpAddrStruct src;
+ /** IP protocol identifier, optional */
+ SshUInt32 ipproto;
+ /** Interface number, optional.
+ Note that this field specifies either the inbound interface number
+ or the outbound interface number, depending on the value of the
+ 'selector' field. */
+ SshUInt32 ifnum;
+ /** Network layer fields */
+ union
+ {
+ /** IPv4 TOS, optional */
+ struct
+ {
+ SshUInt8 tos;
+ } ip4;
+ /** IPv6 priority and flow label, optional */
+ struct
+ {
+ SshUInt8 priority;
+ SshUInt32 flow;
+ } ip6;
+ /** For encoding / decoding */
+ unsigned char raw[5];
+ } nh;
+ /** Transport layer fields */
+ union
+ {
+ /** TCP / UDP ports, optional */
+ struct
+ {
+ SshUInt16 dst_port;
+ SshUInt16 src_port;
+ } tcp;
+ /** ICMP type and code, optional */
+ struct
+ {
+ SshUInt8 type;
+ SshUInt8 code;
+ } icmp;
+ /** ESP / AH spi, optional */
+ struct
+ {
+ SshUInt32 spi;
+ } ipsec;
+ /** For encoding / decoding */
+ unsigned char raw[4];
+ } th;
+#if (SSH_INTERCEPTOR_NUM_EXTENSION_SELECTORS > 0)
+ /** Platform-dependent extension selectors, optional */
+ SshUInt32 extension[SSH_INTERCEPTOR_NUM_EXTENSION_SELECTORS];
+#endif /* (SSH_INTERCEPTOR_NUM_EXTENSION_SELECTORS > 0) */
+ /** Bitmap of selectors that are to be used in the route lookup.
+ Use the provided macros to add selectors to the routing key,
+ do not access this field directly. The highest 3 bits of
+ 'selector' are reserved for flags defined below. */
+ SshUInt16 selector;
+} *SshInterceptorRouteKey, SshInterceptorRouteKeyStruct;
+
+/* Selector values for 'selector' bitmap */
+
+/** Source address */
+#define SSH_INTERCEPTOR_ROUTE_KEY_SRC 0x0001
+/** IP protocol identifier */
+#define SSH_INTERCEPTOR_ROUTE_KEY_IPPROTO 0x0002
+/** Inbound interface number */
+#define SSH_INTERCEPTOR_ROUTE_KEY_IN_IFNUM 0x0004
+/** Outbound interface number */
+#define SSH_INTERCEPTOR_ROUTE_KEY_OUT_IFNUM 0x0008
+/** IPv4 type of service */
+#define SSH_INTERCEPTOR_ROUTE_KEY_IP4_TOS 0x0010
+/** Platform-dependent Extension selectors */
+#define SSH_INTERCEPTOR_ROUTE_KEY_EXTENSION 0x1000
+
+/* Flag values for 'selector' bitmap */
+
+/** Packets going to this destination are transformed by the engine and the
+ resulting packet may be larger than the path MTU reported to the IP stack
+ by the engine. */
+#define SSH_INTERCEPTOR_ROUTE_KEY_FLAG_TRANSFORM_APPLIED 0x2000
+/** Source address belongs to one of the local interfaces. */
+#define SSH_INTERCEPTOR_ROUTE_KEY_FLAG_LOCAL_SRC 0x4000
+
+/** A callback function of this type will be called when the
+ interceptor is first opened, and from then on whenever there is a
+ change in the interface list (e.g., a new interface goes up or
+ down or the address of an interface changes). This function will
+ be given a list of the interfaces. The supplied array will only
+ be valid for the duration of this call; the implementation of this
+ function is supposed to copy the information if it is going to
+ need it later. Note that this function may be called
+ asynchronously, concurrently with any other functions. */
+typedef void (*SshInterceptorInterfacesCB)(SshUInt32 num_interfaces,
+ SshInterceptorInterface *ifs,
+ void *context);
+
+/** Callback functions of this type are called whenever a packet is
+ received from the network or from a protocol. This function must
+ eventually free the packet, either by calling
+ ssh_interceptor_packet_free on the packet or by passing it to the
+ ssh_interceptor_send function. Note that this function may be
+ called asynchronously, concurrently with any other functions.
+
+ When a packet is passed to this callback, the `pp->flags' field
+ may contain arbitrary flags in the bits reserved for the
+ interceptor (mask 0x00000fff). This callback is not allowed to
+ modify any of those bits; they must be passed intact to
+ ssh_interceptor_send or ssh_interceptor_packet_free. Any other
+ bits (mask 0xfffff000) will be zero when the packet is sent to
+ this callback; those bits may be used freely by this callback.
+ They are not used by the interceptor. */
+typedef void (*SshInterceptorPacketCB)(SshInterceptorPacket pp, void *context);
+
+/** A callback function of this type is used to notify code above the
+ interceptor that routing information has changed, and any cached
+ routing data should be thrown away and refreshed by a new route
+ lookup. */
+typedef void (*SshInterceptorRouteChangeCB)(void *context);
+
+/** Opens the packet interceptor. This must be called before using
+ any other interceptor functions. This registers the callbacks
+ that the interceptor will use to notify the higher levels of
+ received packets or changes in the interface list. The interface
+ callback will be called once either during this call or soon after
+ this has returned.
+
+ The `machine_context' argument is intended to be meaningful only
+ to machine-specific code. It is passed through from the
+ machine-specific main program. One example of its possible uses
+ is to identify a virtual router in systems that implement multiple
+ virtual routers in a single software environment. Most
+ implementations will ignore this argument.
+
+ The `packet_cb' callback will be called whenever a packet is
+ received from either a network adapter or a protocol stack. The
+ first calls may arrive already before this function has returned.
+
+ The `interfaces_cb' callback will be called once soon after
+ opening the interceptor (possibly before this call returns). From
+ then on, it will be called whenever there is a change in the
+ interface list (e.g., the IP address of an interface is changed,
+ or a PPP interface goes up or down).
+
+ The `route_change_cb' callback should be called whenever there is
+ a change in routing information. Implementing this callback is
+ optional but beneficial in e.g. router environments (the
+ information is not easily available on all systems).
+
+ The `context' argument is passed to the callbacks.
+
+ This function returns TRUE if opening the interceptor was
+ successful. The interceptor object is returned in the
+ `interceptor_return' argument. Most systems will only allow a
+ single interceptor to be opened; however, some systems may support
+ multiple interceptors identified by the `machine_context'
+ argument. This returns FALSE if an error occurs (e.g., no
+ interceptor kernel module is loaded on this system, or the
+ interceptor is already open).
+
+ Care must be taken regarding concurrency control in systems that have
+ multithreaded IP stacks. In particular:
+ - packet_cb and interfaces_cb may get called before this function
+ returns. It is, however, guaranteed that `*interceptor_return'
+ has been set before the first call to either of them.
+ - the interceptor cannot be closed while there are calls or packets
+ out. The ssh_interceptor_stop function must be used.
+ In such systems, additional concurrency may be introduced by timeouts
+ and actions from the policy manager connection. */
+Boolean ssh_interceptor_open(void *machine_context,
+ SshInterceptorPacketCB packet_cb,
+ SshInterceptorInterfacesCB interfaces_cb,
+ SshInterceptorRouteChangeCB route_change_cb,
+ void *context,
+ SshInterceptor *interceptor_return);
+
+/** Sends a packet to the network or to the protocol stacks. This
+ will eventually free the packet by calling
+ ssh_interceptor_packet_free. The `media_header_len' argument
+ specifies how many bytes from the start of the packet are media
+ (link-level) headers. It will be 0 if the interceptor operates
+ directly at protocol level. If the configure define
+ INTERCEPTOR_IP_ALIGNS_PACKETS is set, this function must ensure
+ that the IP header of the packet is aligned to a word boundary.
+
+ This function relies on 'pp->ifnum_out' being an 'ifnum' which has
+ previously been reported via a SshInterceptorInterfacesCB. It does
+ not have to be valid at that precise point in time. If 'pp->ifnum_out'
+ is an ifnum which may have been previously reported to the
+ SshInterceptorInterfacesCB, then ssh_interceptor_send() MUST check
+ that it is valid, or otherwise discard the packet. Also,
+ pp->protocol (and the corresponding encapsulation) may be
+ incorrect for the interface denoted by 'pp->ifnum_out'. The packet
+ should be dropped also in this case.
+
+ This function can be called concurrently from multiple threads,
+ but only for one packet at a time. It is ok to call this even
+ before ssh_interceptor_open has actually returned (from a
+ `packet_cb' or `interface_cb' callback). */
+
+void ssh_interceptor_send(SshInterceptor interceptor,
+ SshInterceptorPacket pp,
+ size_t media_header_len);
+
+/** Enables or disables packet interception. */
+void ssh_interceptor_enable_interception(SshInterceptor interceptor,
+ Boolean enable);
+
+/** Stops the packet interceptor. After this call has returned, no
+ new calls to the packet and interfaces callbacks will be made.
+ The interceptor keeps track of how many threads are processing
+ packet, interface, or have pending route callbacks, and this
+ function returns TRUE if there are no callbacks/pending calls to
+ those functions. This returns FALSE if threads are still
+ executing in those callbacks or routing callbacks are pending.
+
+ After calling this function, the higher-level code should wait for
+ packet processing to continue, free all packet structures received
+ from that interceptor, and then call ssh_interceptor_close. It is
+ not an error to call this multiple times (the latter calls are
+ ignored).
+
+ It is forbidden to hold ANY locks when calling
+ ssh_interceptor_stop(). */
+
+Boolean ssh_interceptor_stop(SshInterceptor interceptor);
+
+/** Closes the packet interceptor. This function can only be called when
+ - ssh_interceptor_stop has been called
+ - all packet and interface callbacks from this interceptor have
+ returned.
+ - all ssh_interceptor_route completions have been called
+ - all packets received from the packet callbacks from this interceptor
+ have been freed.
+
+ It is illegal to call any packet interceptor functions (other than
+ ssh_interceptor_open) after this call. This function cannot be
+ called from an interceptor callback.
+
+ This function can be called from one thread only for any particular
+ interceptor. If multiple interceptors are supported, then this may be
+ called for different interceptors asynchronously. */
+void ssh_interceptor_close(SshInterceptor interceptor);
+
+/** Completion function for route lookup. This function is called when the
+ route lookup is complete.
+ reachable FALSE if the destination cannot be reached, TRUE otherwise
+ next_hop_gw IP address of next hop gw or destination
+ ifnum network interface to which to send the packet
+ mtu path mtu, or 0 if not known (= should use link mtu)
+ context context argument supplied to route request.
+
+ This function may get called concurrently from multiple threads. */
+typedef void (*SshInterceptorRouteCompletion)(Boolean reachable,
+ SshIpAddr next_hop_gw,
+ SshInterceptorIfnum ifnum,
+ size_t mtu,
+ void *context);
+
+/** Looks up routing information for the routing key specified
+ by `key'. Calls the callback function either during this
+ call or some time later. The purpose of the callback function is
+ to allow this function to perform asynchronous operations, such as
+ forwarding the routing request to a user-level process. This
+ function will not be very efficient on some systems, and calling
+ this on a per-packet basis should be avoided if possible.
+ This function expects that 'key' is valid only for the duration
+ of the call, and will take a local copy of it, if necessary.
+
+ Note that if this function is implemented by forwarding the
+ request to a user-level process, care must be taken to never lose
+ replies. The completion function must *always* be called. For
+ example, if the policy manager interface is used to pass the
+ requests to the policy manager process, and the interface is
+ closed, the completion function must still be called for all
+ requests. Code may be needed to keep track of which requests are
+ waiting for replies from the user-level process.
+
+ This function can be called concurrently from multiple threads.
+ While legal, new calls to this function after calling
+ ssh_interceptor_stop should be avoided, because it is not possible
+ to call ssh_interceptor_close until all route lookup completions
+ have been called. */
+void ssh_interceptor_route(SshInterceptor interceptor,
+ SshInterceptorRouteKey key,
+ SshInterceptorRouteCompletion completion,
+ void *context);
+
+/** Allocates a packet of at least the given size. Packets can only
+ be allocated using this function (either internally by the
+ interceptor or by other code by calling this function).
+ Typically, this takes a packet header from a free list, stores a
+ pointer to a platform-specific packet object, and returns the
+ packet header. This should be re-entrant and support concurrent
+ operations if the IPSEC engine is re-entrant on the target
+ platform. Other functions in this interface should be re-entrant
+ for different packet objects, but only one operation will be in
+ progress at any given time for a single packet object. This
+ returns NULL if no more packets can be allocated. On systems that
+ support concurrency, this can be called from multiple threads
+ concurrently.
+
+ This sets initial values for the mandatory fields of the packet
+ that always need to be initialized. However, any of these fields
+ can be modified later. */
+SshInterceptorPacket ssh_interceptor_packet_alloc(SshInterceptor interceptor,
+ SshUInt32 flags,
+ SshInterceptorProtocol proto,
+ SshInterceptorIfnum ifnum_in,
+ SshInterceptorIfnum ifnum_out,
+ size_t total_len);
+
+
+/** Frees the packet.
+
+ All packets allocated by ssh_interceptor_packet_alloc must
+ eventually be freed using this function by either calling this
+ explicitly or by passing the packet to the ssh_interceptor_send
+ function. Typically, this calls a suitable function to
+ free/release the platform-specific packet object, and puts the
+ packet header on a free list. This function should be re-entrant,
+ so if a free list is used, it should be protected by a lock in
+ systems that implement concurrency in the IPSEC Engine. Multiple
+ threads may call this function concurrently for different packets,
+ but not for the same packet. */
+void ssh_interceptor_packet_free(SshInterceptorPacket pp);
+
+/** Returns the total length of the packet in bytes. Multiple threads may
+ call this function concurrently, but not for the same packet. */
+size_t ssh_interceptor_packet_len(SshInterceptorPacket pp);
+
+
+/** Copies data into the packet. Space for the new data must already
+ have been allocated. It is a fatal error to attempt to copy beyond
+ the allocated packet. Multiple threads may call this function
+ concurrently, but not for the same packet. Returns TRUE if
+ successfull and FALSE otherwise. If error occurs then the pp is
+ already freed by this function, and the caller must not refer to
+ it anymore.
+
+ There is a generic version of this function inside the engine, in
+ case interceptor does not want to implement this. If interceptor
+ implements this function it must define the
+ INTERCEPTOR_HAS_PACKET_COPYIN pre-processor symbol. */
+Boolean ssh_interceptor_packet_copyin(SshInterceptorPacket pp, size_t offset,
+ const unsigned char *buf, size_t len);
+
+/** Copies data out from the packet. Space for the new data must
+ already have been allocated. It is a fatal error to attempt to
+ copy beyond the allocated packet. Multiple threads may call this
+ function concurrently, but not for the same packet.
+
+ There is a generic version of this function inside the engine, in
+ case interceptor does not want to implement this. If interceptor
+ implements this function it must define the
+ INTERCEPTOR_HAS_PACKET_COPYOUT pre-processor symbol. */
+void ssh_interceptor_packet_copyout(SshInterceptorPacket pp, size_t offset,
+ unsigned char *buf, size_t len);
+
+
+/** These two routines provide way to export and import
+ interceptor-specific internal packet data as an opaque binary data
+ block.
+
+ If the export routine returns FALSE, the packet `pp' is
+ invalidated. If it returnes TRUE, but *data_ret is NULL, then no
+ internal data was exported. If *data_ret is non-NULL, then
+ *len_return contains the length of *data_ret in bytes. The caller
+ must free the *data_ret value using ssh_free.
+
+ The import routine returns TRUE if the data was imported
+ successfully, otherwise it returns FALSE and the packet `pp' is
+ invalidated. It is a fatal error to call import routine on the
+ same packet more than once.
+
+ Notice: If the interceptor does not define these routines, then
+ the engine provides dummy versions.
+
+ Notice: This routine overlaps a bit with
+ ssh_interceptor_packet_alloc_and_copy_ext_data, as it could be
+ implemented as:
+
+ new_pp = ssh_interceptor_packet_alloc(...);
+ ssh_interceptor_packet_copy(pp, 0, ..., new_pp, 0);
+ ssh_interceptor_packet_export_internal_data(pp, &data, &len);
+ ssh_interceptor_packet_import_internal_data(new_pp, data, len);
+ ssh_free(data);
+
+ The main purpose of these routines is to allow some per-packet
+ interceptor-specific data to be transported to the usermode
+ engine. Under the kernel IPSec Engine, these routines are not
+ actually used at all. */
+Boolean ssh_interceptor_packet_export_internal_data(SshInterceptorPacket pp,
+ unsigned char **data_ret,
+ size_t *len_return);
+
+Boolean ssh_interceptor_packet_import_internal_data(SshInterceptorPacket pp,
+ const unsigned char *data,
+ size_t len);
+
+void ssh_interceptor_packet_discard_internal_data(unsigned char *data,
+ size_t data_len);
+
+
+/** Copy data from one packet to another. Start from the
+ `source_offset' and copy `bytes_to_copy' bytes to
+ `destination_offset' in the destination packet. If the destination
+ packet cannot be written then return FALSE, and the destination
+ packet has been freed by this function. The source packet is not
+ freed even in case of error. If data copying was successfull then
+ return TRUE.
+
+ This function can also be implemented so that it will simply
+ increment the reference counts in the source packet and share the
+ actual data without copying it at all. There is a generic version
+ of this function inside the engine, in case interceptor does not
+ want to implement this. If interceptor implements this function it
+ must define INTERCEPTOR_HAS_PACKET_COPY pre-processor symbol. */
+Boolean ssh_interceptor_packet_copy(SshInterceptorPacket source_pp,
+ size_t source_offset,
+ size_t bytes_to_copy,
+ SshInterceptorPacket destination_pp,
+ size_t destination_offset);
+
+#ifdef DEBUG_LIGHT
+#define KERNEL_INTERCEPTOR_USE_FUNCTIONS
+#endif /* DEBUG_LIGHT */
+
+#ifdef INTERCEPTOR_HAS_PLATFORM_INCLUDE
+#include "platform_interceptor.h"
+#endif /* INTERCEPTOR_HAS_PLATFORM_INCLUDE */
+
+#endif /* INTERCEPTOR_H */
diff --git a/drivers/interceptor/kernel_alloc.c b/drivers/interceptor/kernel_alloc.c
new file mode 100644
index 0000000..21af9ba
--- /dev/null
+++ b/drivers/interceptor/kernel_alloc.c
@@ -0,0 +1,124 @@
+/* Netfilter Driver for IPSec VPN Client
+ *
+ * Copyright(c) 2012 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.
+ */
+
+/*
+ * kernel_alloc.
+ *
+ * Engine memory allocation API implementation for kernel space.
+ *
+ */
+
+#include "sshincludes.h"
+#include "kernel_alloc.h"
+#include "kernel_mutex.h"
+
+void *
+ssh_malloc_flags(size_t size, SshUInt32 flags)
+{
+ return ssh_kernel_alloc(size, flags);
+}
+
+void *
+ssh_malloc(size_t size)
+{
+ return ssh_malloc_flags(size, SSH_KERNEL_ALLOC_NOWAIT);
+}
+
+void *
+ssh_realloc_flags(void *oldptr, size_t oldsize, size_t newsize,
+ SshUInt32 flags)
+{
+ void * newptr;
+
+ if (oldptr == NULL)
+ return ssh_kernel_alloc(newsize, flags);
+
+ if (newsize <= oldsize)
+ return oldptr;
+
+ if ((newptr = ssh_kernel_alloc(newsize, flags)) == NULL)
+ return NULL;
+
+ /* newsize > oldsize, see above */
+ if (oldsize > 0)
+ memcpy(newptr, oldptr, oldsize);
+
+ /* Success, thus we can release the old memory */
+ ssh_kernel_free(oldptr);
+
+ return newptr;
+}
+
+void *
+ssh_realloc(void * oldptr, size_t oldsize, size_t newsize)
+{
+ return ssh_realloc_flags(oldptr, oldsize, newsize, SSH_KERNEL_ALLOC_NOWAIT);
+}
+
+/* coverity[ -tainted_data_sink : arg-0 ] */
+void ssh_free (void * ptr)
+{
+ if (ptr != NULL)
+ ssh_kernel_free(ptr);
+}
+
+void*
+ssh_calloc_flags (size_t nitems, size_t isize, SshUInt32 flags)
+{
+ void * ptr;
+ unsigned long size;
+
+ size = isize * nitems;
+
+ if ((ptr = ssh_malloc_flags(size ? size : 1, flags)) == NULL)
+ return NULL;
+
+ if (size > 0)
+ memset(ptr, 0, size);
+
+ return ptr;
+}
+
+void *
+ssh_calloc(size_t nitems, size_t isize)
+{
+ return ssh_calloc_flags(nitems, isize, SSH_KERNEL_ALLOC_NOWAIT);
+}
+
+void *ssh_strdup (const void * p)
+{
+ const char * str;
+ char * cp;
+
+ SSH_PRECOND(p != NULL);
+
+ str = (const char *) p;
+
+ if ((cp = (char *) ssh_malloc(strlen(str) + 1)) == NULL)
+ return NULL;
+
+ strcpy(cp, str);
+
+ return (void *) cp;
+}
+
+void *ssh_memdup(const void * p, size_t len)
+{
+ void * cp;
+
+ if ((cp = ssh_malloc(len + 1)) == NULL)
+ return NULL;
+
+ memcpy(cp, p, (size_t)len);
+
+ ((unsigned char *) cp)[len] = '\0';
+
+ return cp;
+}
diff --git a/drivers/interceptor/kernel_alloc.h b/drivers/interceptor/kernel_alloc.h
new file mode 100644
index 0000000..c722bf8
--- /dev/null
+++ b/drivers/interceptor/kernel_alloc.h
@@ -0,0 +1,44 @@
+/* Netfilter Driver for IPSec VPN Client
+ *
+ * Copyright(c) 2012 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.
+ */
+
+/*
+ * kernel_alloc.h
+ *
+ * Kernel memory allocation API.
+ *
+ */
+
+#ifndef KERNEL_ALLOC_H
+#define KERNEL_ALLOC_H
+
+/* Allocate 'size' amount of memory, with the 'flag'
+ parameters. Returns a NULL value if the allocation request cannot
+ be satisfied for some reason.
+
+ Notice: 'flag' is nothing more than a hint to the allocator. The
+ allocator is free to ignore 'flag'. The allocatee is free to
+ specify flag as ssh_rand() number, and the returned memory must still
+ have the same semantics as any other memory block allocated. */
+void *ssh_kernel_alloc(size_t size, SshUInt32 flag);
+
+/* Flag is or-ed together of the following flags. */
+#define SSH_KERNEL_ALLOC_NOWAIT 0x0000 /* allocation/use atomic. */
+#define SSH_KERNEL_ALLOC_WAIT 0x0001 /* allow sleeping alloc/use. */
+#define SSH_KERNEL_ALLOC_DMA 0x0002 /* allow DMA use. */
+/* Other bits are usable for other purposes? */
+
+/* Frees a previously allocated block of memory. */
+void ssh_kernel_free(void *ptr);
+
+#ifdef DEBUG_LIGHT
+#define KERNEL_ALLOC_USE_FUNCTIONS
+#endif /* DEBUG_LIGHT */
+
+#endif /* KERNEL_ALLOC_H */
diff --git a/drivers/interceptor/kernel_encode.c b/drivers/interceptor/kernel_encode.c
new file mode 100644
index 0000000..f13694d
--- /dev/null
+++ b/drivers/interceptor/kernel_encode.c
@@ -0,0 +1,580 @@
+/* Netfilter Driver for IPSec VPN Client
+ *
+ * Copyright(c) 2012 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.
+ */
+
+/*
+ * kernel_encode.c
+ *
+ * Encode/decode API implementation for kernel space.
+ *
+ */
+
+#include "sshincludes.h"
+#include "sshgetput.h"
+#include "sshencode.h"
+
+/* Encodes data into the buffer. Returns the number of bytes added, or
+ 0 if the buffer is too small. The data to be encoded is specified by the
+ variable-length argument list. Each element must start with a
+ SshEncodingFormat type, be followed by arguments of the appropriate
+ type, and the list must end with SSH_FORMAT_END. */
+size_t ssh_encode_array_va(unsigned char *buf, size_t bufsize, va_list ap)
+{
+ SshEncodingFormat format;
+ unsigned int intvalue;
+ SshUInt16 u16;
+ SshUInt32 u32;
+ SshUInt64 u64;
+ size_t len, offset;
+ Boolean b;
+ const unsigned char *p;
+
+ offset = 0;
+ for (;;)
+ {
+ format = va_arg(ap, SshEncodingFormat);
+ switch (format)
+ {
+ case SSH_FORMAT_UINT32_STR:
+ p = va_arg(ap, unsigned char *);
+ len = va_arg(ap, size_t);
+ if (bufsize - offset < 4 + len)
+ return 0;
+ SSH_PUT_32BIT(buf + offset, len);
+ memcpy(buf + offset + 4, p, len);
+ offset += 4 + len;
+ break;
+
+ case SSH_FORMAT_BOOLEAN:
+ b = va_arg(ap, Boolean);
+ if (bufsize - offset < 1)
+ return 0;
+ buf[offset++] = (unsigned char)b;
+ break;
+
+ case SSH_FORMAT_UINT32:
+ u32 = va_arg(ap, SshUInt32);
+ if (bufsize - offset < 4)
+ return 0;
+ SSH_PUT_32BIT(buf + offset, u32);
+ offset += 4;
+ break;
+
+ case SSH_FORMAT_UINT16:
+ intvalue = va_arg(ap, unsigned int);
+ u16 = (SshUInt16) intvalue;
+ if (bufsize - offset < 2)
+ return 0;
+ SSH_PUT_16BIT(buf + offset, u16);
+ offset += 2;
+ break;
+
+ case SSH_FORMAT_CHAR:
+ intvalue = va_arg(ap, unsigned int);
+ if (bufsize - offset < 1)
+ return 0;
+ buf[offset++] = (unsigned char)intvalue;
+ break;
+
+ case SSH_FORMAT_DATA:
+ p = va_arg(ap, unsigned char *);
+ len = va_arg(ap, size_t);
+ if (bufsize - offset < len)
+ return 0;
+ memcpy(buf + offset, p, len);
+ offset += len;
+ break;
+
+ case SSH_FORMAT_UINT64:
+ u64 = va_arg(ap, SshUInt64);
+ if (bufsize - offset < 8)
+ return 0;
+ SSH_PUT_64BIT(buf + offset, u64);
+ offset += 8;
+ break;
+
+ case SSH_FORMAT_SPECIAL:
+ {
+ SshEncodeDatum fn;
+ void *datum;
+ size_t space, size;
+
+ fn = va_arg(ap, SshEncodeDatum);
+ datum = va_arg(ap, void *);
+
+ space = bufsize - offset;
+ size = (*fn)(buf, space, datum);
+ if (size > space)
+ return 0;
+
+ offset += size;
+ }
+ break;
+
+ case SSH_FORMAT_END:
+ /* Return the number of bytes added. */
+ return offset;
+
+ default:
+ SSH_FATAL("ssh_encode_array_va: invalid format code %d "
+ "(check arguments and SSH_FORMAT_END)",
+ (int)format);
+ }
+ }
+}
+
+/* Appends data at the end of the buffer as specified by the variable-length
+ argument list. Each element must start with a SshEncodingFormat type,
+ be followed by arguments of the appropriate type, and the list must end
+ with SSH_FORMAT_END. This returns the number of bytes added to the
+ buffer, or 0 if the buffer is too small. */
+size_t ssh_encode_array(unsigned char *buf, size_t bufsize, ...)
+{
+ size_t bytes;
+ va_list ap;
+
+ va_start(ap, bufsize);
+ bytes = ssh_encode_array_va(buf, bufsize, ap);
+ va_end(ap);
+ return bytes;
+}
+
+/* Doubles the size of a buffer. Copies the contents from the old one
+ to the new one and frees the old one. Returns new buffer size.
+ If realloc fails, frees the old buffer and returns 0. */
+size_t ssh_encode_array_enlarge_buffer(unsigned char **buf, size_t bufsize)
+{
+ unsigned int newsize;
+ unsigned char *newbuf;
+
+ SSH_ASSERT(buf != NULL);
+
+ newsize = bufsize * 2;
+ SSH_ASSERT(newsize < 10000000);
+
+ if (newsize == 0)
+ newsize = 100;
+
+ newbuf = ssh_realloc(*buf, bufsize, newsize);
+ if (newbuf == NULL)
+ {
+ ssh_free(*buf);
+ return 0;
+ }
+ *buf = newbuf;
+
+ return newsize;
+}
+
+/* Encodes the given data. Returns the length of encoded data in bytes, and
+ if `buf_return' is non-NULL, it is set to a memory area allocated by
+ ssh_malloc that contains the data. The caller should free the data when
+ no longer needed.
+
+ Duplicates functionality in ssh_encode_array_va, could combine
+ some. Note that cycling va_list with va_arg is not supported in all
+ environments, so repeatedly trying ssh_encode_array_va with bigger
+ buffers is not possible. */
+size_t ssh_encode_array_alloc_va(unsigned char **buf_return, va_list ap)
+{
+ size_t bufsize;
+ unsigned char *buf = NULL;
+ SshEncodingFormat format;
+ unsigned int intvalue;
+ SshUInt16 u16;
+ SshUInt32 u32;
+ SshUInt64 u64;
+ size_t len, offset;
+ Boolean b;
+ const unsigned char *p;
+
+ /* Prepare return value in case of later failure. */
+ if (buf_return != NULL)
+ *buf_return = NULL;
+
+ /* Allocate new buffer. */
+ bufsize = ssh_encode_array_enlarge_buffer(&buf, 0);
+
+ offset = 0;
+ for (;;)
+ {
+ format = va_arg(ap, SshEncodingFormat);
+ switch (format)
+ {
+ case SSH_FORMAT_UINT32_STR:
+ p = va_arg(ap, unsigned char *);
+ len = va_arg(ap, size_t);
+ while (bufsize - offset < 4 + len)
+ {
+ if (!(bufsize = ssh_encode_array_enlarge_buffer(&buf, bufsize)))
+ return 0;
+ }
+ SSH_PUT_32BIT(buf + offset, len);
+ memcpy(buf + offset + 4, p, len);
+ offset += 4 + len;
+ break;
+
+ case SSH_FORMAT_BOOLEAN:
+ b = va_arg(ap, Boolean);
+ while (bufsize - offset < 1)
+ {
+ if (!(bufsize = ssh_encode_array_enlarge_buffer(&buf, bufsize)))
+ return 0;
+ }
+ buf[offset++] = (unsigned char)b;
+ break;
+
+ case SSH_FORMAT_UINT32:
+ u32 = va_arg(ap, SshUInt32);
+ while (bufsize - offset < 4)
+ {
+ if (!(bufsize = ssh_encode_array_enlarge_buffer(&buf, bufsize)))
+ return 0;
+ }
+ SSH_PUT_32BIT(buf + offset, u32);
+ offset += 4;
+ break;
+
+ case SSH_FORMAT_UINT16:
+ intvalue = va_arg(ap, unsigned int);
+ u16 = (SshUInt16) intvalue;
+ while (bufsize - offset < 2)
+ {
+ if (!(bufsize = ssh_encode_array_enlarge_buffer(&buf, bufsize)))
+ return 0;
+ }
+ SSH_PUT_16BIT(buf + offset, u16);
+ offset += 2;
+ break;
+
+ case SSH_FORMAT_CHAR:
+ intvalue = va_arg(ap, unsigned int);
+ while (bufsize - offset < 1)
+ {
+ if (!(bufsize = ssh_encode_array_enlarge_buffer(&buf, bufsize)))
+ return 0;
+ }
+ buf[offset++] = (unsigned char)intvalue;
+ break;
+
+ case SSH_FORMAT_DATA:
+ p = va_arg(ap, unsigned char *);
+ len = va_arg(ap, size_t);
+ while (bufsize - offset < len)
+ {
+ if (!(bufsize = ssh_encode_array_enlarge_buffer(&buf, bufsize)))
+ return 0;
+ }
+ memcpy(buf + offset, p, len);
+ offset += len;
+ break;
+
+ case SSH_FORMAT_UINT64:
+ u64 = va_arg(ap, SshUInt64);
+ while (bufsize - offset < 8)
+ {
+ if (!(bufsize = ssh_encode_array_enlarge_buffer(&buf, bufsize)))
+ return 0;
+ }
+ SSH_PUT_64BIT(buf + offset, u64);
+ offset += 8;
+ break;
+
+ case SSH_FORMAT_END:
+ if (buf_return != NULL)
+ *buf_return = buf;
+ else
+ /* They only want to know the size of the buffer */
+ ssh_free(buf);
+
+ /* Return the number of bytes added. */
+ return offset;
+
+ default:
+ SSH_FATAL("ssh_encode_array_alloc_va: invalid format code %d "
+ "(check arguments and SSH_FORMAT_END)",
+ (int)format);
+ }
+ }
+}
+
+/* Encodes the given data. Returns the length of encoded data in bytes, and
+ if `buf_return' is non-NULL, it is set to a memory area allocated by
+ ssh_malloc that contains the data. The caller should free the data when
+ no longer needed. It is an error to call this with an argument list that
+ would result in zero bytes being encoded. */
+size_t ssh_encode_array_alloc(unsigned char **buf_return, ...)
+{
+ size_t bytes;
+ va_list ap;
+
+ va_start(ap, buf_return);
+ bytes = ssh_encode_array_alloc_va(buf_return, ap);
+ va_end(ap);
+
+ return bytes;
+}
+
+/* Allocates a buffer of the given size with ssh_malloc. However,
+ the buffer is also recorded in *num_allocs_p and *allocs_p, so that
+ they can all be easily freed later if necessary. */
+static unsigned char *ssh_decode_array_alloc(unsigned int *num_allocs_p,
+ unsigned char ***allocsp,
+ size_t size)
+{
+ unsigned char *p;
+
+ /* Check if we need to enlarge the pointer array. We enlarge it in chunks
+ of 16 pointers. */
+ if (*num_allocs_p == 0)
+ *allocsp = NULL;
+
+ /* This will also match *num_allocs_p == 0, and it is valid to pass
+ NULL to krealloc, so this works. */
+ if (*num_allocs_p % 16 == 0)
+ {
+ unsigned char ** nallocsp;
+
+ nallocsp = ssh_realloc(*allocsp,
+ *num_allocs_p
+ * sizeof(unsigned char *),
+ (*num_allocs_p + 16)
+ * sizeof(unsigned char *));
+
+ /* If we fail in allocation, return NULL but leave *allocsp intact. */
+ if (!nallocsp)
+ return NULL;
+
+ *allocsp = nallocsp;
+ }
+
+ /* Allocate the memory block. */
+ if (!(p = ssh_malloc(size)))
+ return NULL;
+
+ /* Store it in the array. */
+ (*allocsp)[*num_allocs_p] = p;
+ (*num_allocs_p)++;
+
+ return p;
+}
+
+/* Decodes data from the given byte array as specified by the
+ variable-length argument list. If all specified arguments could be
+ successfully parsed, returns the number of bytes parsed (any
+ remaining data can be parsed by first skipping this many bytes).
+ If parsing any element results in an error, this returns 0 (and
+ frees any already allocated data). Zero is also returned if the
+ specified length would be exceeded. */
+size_t ssh_decode_array_va(const unsigned char *buf, size_t len,
+ va_list ap)
+{
+ SshEncodingFormat format;
+ unsigned long longvalue;
+ SshUInt16 *u16p;
+ SshUInt32 *u32p;
+ SshUInt64 *u64p;
+ Boolean *bp;
+ size_t size, *sizep;
+ unsigned int *uip;
+ unsigned char *p, **pp;
+ const unsigned char **cpp;
+ size_t offset;
+ unsigned int i, num_allocs;
+ unsigned char **allocs = NULL;
+
+ offset = 0;
+ num_allocs = 0;
+
+ for (;;)
+ {
+ /* Get the next format code. */
+ format = va_arg(ap, SshEncodingFormat);
+ switch (format)
+ {
+
+ case SSH_FORMAT_UINT32_STR:
+ /* Get length and data pointers. */
+ pp = va_arg(ap, unsigned char **);
+ sizep = va_arg(ap, size_t *);
+
+ /* Check if the length of the string is there. */
+ if (len - offset < 4)
+ goto fail;
+
+ /* Get the length of the string. */
+ longvalue = SSH_GET_32BIT(buf + offset);
+ offset += 4;
+
+ /* Check that the string is all in the buffer. */
+ if (longvalue > len - offset)
+ goto fail;
+
+ /* Store length if requested. */
+ if (sizep != NULL)
+ *sizep = longvalue;
+
+ /* Retrieve the data if requested. */
+ if (pp != NULL)
+ {
+ *pp = ssh_decode_array_alloc(&num_allocs, &allocs,
+ (size_t)longvalue + 1);
+
+ if (!*pp)
+ goto fail;
+
+ memcpy(*pp, buf + offset, (size_t)longvalue);
+ (*pp)[longvalue] = '\0';
+ }
+
+ /* Consume the data. */
+ offset += longvalue;
+ break;
+
+ case SSH_FORMAT_UINT32_STR_NOCOPY:
+
+ /* Get length and data pointers. */
+ cpp = va_arg(ap, const unsigned char **);
+ sizep = va_arg(ap, size_t *);
+
+ /* Decode string length and skip the length. */
+
+ if (len - offset < 4)
+ goto fail;
+
+ longvalue = SSH_GET_32BIT(buf + offset);
+ offset += 4;
+
+ /* Check that the string is all in the buffer. */
+ if (longvalue > len - offset)
+ goto fail;
+
+ /* Store length if requested. */
+ if (sizep != NULL)
+ *sizep = longvalue;
+
+ /* Retrieve the data if requested. */
+ if (cpp != NULL)
+ *cpp = buf + offset;
+
+ /* Consume the data. */
+ offset += longvalue;
+ break;
+
+
+ case SSH_FORMAT_BOOLEAN:
+ bp = va_arg(ap, Boolean *);
+ if (len - offset < 1)
+ goto fail;
+ if (bp != NULL)
+ *bp = buf[offset] != 0;
+ offset++;
+ break;
+
+ case SSH_FORMAT_UINT32:
+ u32p = va_arg(ap, SshUInt32 *);
+ if (len - offset < 4)
+ goto fail;
+ if (u32p)
+ *u32p = SSH_GET_32BIT(buf + offset);
+ offset += 4;
+ break;
+
+ case SSH_FORMAT_UINT16:
+ u16p = va_arg(ap, SshUInt16 *);
+ if (len - offset < 2)
+ goto fail;
+ if (u16p)
+ *u16p = SSH_GET_16BIT(buf + offset);
+ offset += 2;
+ break;
+
+ case SSH_FORMAT_CHAR:
+ uip = va_arg(ap, unsigned int *);
+ if (len - offset < 1)
+ goto fail;
+ if (uip)
+ *uip = buf[offset];
+ offset++;
+ break;
+
+ case SSH_FORMAT_DATA:
+ p = va_arg(ap, unsigned char *);
+ size = va_arg(ap, size_t);
+ if (len - offset < size)
+ goto fail;
+ if (p)
+ memcpy(p, buf + offset, size);
+ offset += size;
+ break;
+
+ case SSH_FORMAT_UINT64:
+ u64p = va_arg(ap, SshUInt64 *);
+ if (len - offset < 8)
+ goto fail;
+ if (u64p)
+ *u64p = SSH_GET_64BIT(buf + offset);
+ offset += 8;
+ break;
+
+ case SSH_FORMAT_SPECIAL:
+ {
+ SshDecodeDatum fn;
+ void **datump;
+
+ fn = va_arg(ap, SshDecodeDatum);
+ datump = va_arg(ap, void **);
+ size = (*fn)(buf + offset, len - offset, datump);
+ if (size > len - offset)
+ goto fail;
+ offset += size;
+ }
+ break;
+
+ case SSH_FORMAT_END:
+ /* Free the allocs array. */
+ if (num_allocs > 0)
+ ssh_free(allocs);
+ /* Return the number of bytes consumed. */
+ return offset;
+
+ default:
+ SSH_FATAL("ssh_decode_array_va: invalid format code %d "
+ "(check arguments and SSH_FORMAT_END)",
+ (int)format);
+ }
+ }
+
+fail:
+ /* An error was encountered. Free all allocated memory and return zero. */
+ for (i = 0; i < num_allocs; i++)
+ ssh_free(allocs[i]);
+ if (i > 0)
+ ssh_free(allocs);
+ return 0;
+}
+
+/* Decodes data from the given byte array as specified by the
+ variable-length argument list. If all specified arguments could be
+ successfully parsed, returns the number of bytes parsed (any
+ remaining data can be parsed by first skipping this many bytes).
+ If parsing any element results in an error, this returns 0 (and
+ frees any already allocates data). Zero is also returned if the
+ specified length would be exceeded. */
+size_t ssh_decode_array(const unsigned char *buf, size_t len, ...)
+{
+ va_list ap;
+ size_t bytes;
+
+ va_start(ap, len);
+ bytes = ssh_decode_array_va(buf, len, ap);
+ va_end(ap);
+
+ return bytes;
+}
diff --git a/drivers/interceptor/kernel_includes.h b/drivers/interceptor/kernel_includes.h
new file mode 100644
index 0000000..93eeea8
--- /dev/null
+++ b/drivers/interceptor/kernel_includes.h
@@ -0,0 +1,152 @@
+/* Netfilter Driver for IPSec VPN Client
+ *
+ * Copyright(c) 2012 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.
+ */
+
+/*
+ * kernel_includes.h
+ *
+ * Common include file for kernel space components.
+ *
+ */
+
+#ifndef KERNEL_INCLUDES_H
+#define KERNEL_INCLUDES_H
+
+#ifdef KERNEL
+# undef _KERNEL
+# define _KERNEL
+#endif /* KERNEL */
+
+#include "sshconf.h"
+
+/* Set SIZEOF_* defines to point to kernel definitions of those. */
+#ifndef SIZEOF_INT
+# define SIZEOF_INT KERNEL_SIZEOF_INT
+#endif /* SIZEOF_INT */
+
+#ifndef SIZEOF_LONG
+# define SIZEOF_LONG KERNEL_SIZEOF_LONG
+#endif /* SIZEOF_LONG */
+
+#ifndef SIZEOF_LONG_LONG
+# define SIZEOF_LONG_LONG KERNEL_SIZEOF_LONG_LONG
+#endif /* SIZEOF_LONG_LONG */
+
+#ifndef SIZEOF_SHORT
+# define SIZEOF_SHORT KERNEL_SIZEOF_SHORT
+#endif /* SIZEOF_SHORT */
+
+#ifndef SIZEOF_VOID_P
+# define SIZEOF_VOID_P KERNEL_SIZEOF_VOID_P
+#endif /* SIZEOF_VOID_P */
+
+/* Set HAVE_ */
+#ifdef HAVE_KERNEL_SHORT
+# define HAVE_SHORT
+#endif
+#ifdef HAVE_KERNEL_INT
+# define HAVE_INT
+#endif
+#ifdef HAVE_KERNEL_LONG
+# define HAVE_LONG
+#endif
+#ifdef HAVE_KERNEL_LONG_LONG
+# define HAVE_LONG_LONG
+#endif
+#ifdef HAVE_KERNEL_VOID_P
+# define HAVE_VOID_P
+#endif
+
+typedef unsigned char SshUInt8; /* At least 8 bits. */
+typedef signed char SshInt8; /* At least 8 bits. */
+
+typedef unsigned short SshUInt16; /* At least 16 bits. */
+typedef short SshInt16; /* At least 16 bits. */
+
+#if SIZEOF_LONG == 4
+typedef unsigned long SshUInt32; /* At least 32 bits. */
+typedef long SshInt32; /* At least 32 bits. */
+#else /* SIZEOF_LONG != 4 */
+#if SIZEOF_INT == 4
+typedef unsigned int SshUInt32; /* At least 32 bits. */
+typedef int SshInt32; /* At least 32 bits. */
+#else /* SIZEOF_INT != 4 */
+#if SIZEOF_SHORT >= 4
+typedef unsigned short SshUInt32; /* At least 32 bits. */
+typedef short SshInt32; /* At least 32 bits. */
+#else /* SIZEOF_SHORT < 4 */
+# error "Autoconfig error, your compiler doesn't support any 32 bit type"
+#endif /* SIZEOF_SHORT < 4 */
+#endif /* SIZEOF_INT != 4 */
+#endif /* SIZEOF_LONG != 4 */
+
+#if SIZEOF_LONG >= 8
+typedef unsigned long SshUInt64;
+typedef long SshInt64;
+# define SSHUINT64_IS_64BITS
+# define SSH_C64(x) (x##lu)
+# define SSH_S64(x) (x##l)
+#else /* SIZEOF_LONG < 8 */
+#if SIZEOF_LONG_LONG >= 8
+typedef unsigned long long SshUInt64;
+typedef long long SshInt64;
+# define SSHUINT64_IS_64BITS
+# define SSH_C64(x) (x##llu)
+# define SSH_S64(x) (x##ll)
+#else /* SIZEOF_LONG_LONG < 8 */
+/* No 64 bit type; SshUInt64 and SshInt64 will be 32 bits. */
+typedef unsigned long SshUInt64;
+typedef long SshInt64;
+# define SSH_C64(x) SSH_FATAL(ERROR_NO_64_BIT_ON_THIS_SYSTEM)
+#endif /* SIZEOF_LONG_LONG < 8 */
+#endif /* SIZEOF_LONG < 8 */
+
+typedef SshInt64 SshTime;
+
+#include <linux/types.h>
+
+#ifdef HAVE_MACHINE_ENDIAN_H
+# include <sys/param.h>
+# include <machine/endian.h>
+#endif
+
+#include <stddef.h>
+
+#include <stdarg.h>
+
+#ifndef TRUE
+# define TRUE 1
+#endif
+
+#ifndef FALSE
+# define FALSE 0
+#endif
+
+typedef unsigned int Boolean;
+
+/* Platform-specific kernel-mode definitions follow. */
+
+/****************************** LINUX *****************************/
+/* Sanity checks about module support and that we are supporting it really */
+#ifndef MODULE
+# error "MODULE must be defined when compiling for Linux"
+#endif
+
+#include <linux/string.h>
+
+/* Including linux/skbuff.h here allows us to cleanly make
+ ssh_interceptor_packet*() macros for it. It really ought to
+ be in the the "platform_interceptor.h" header file, but unfortunately
+ this would require generic engine code to set SSH_ALLOW_SYSTEM_SPRINTFS,
+ which is why it is here. */
+#include "linux/skbuff.h"
+
+/****************************** LINUX (END) *****************************/
+
+#endif /* KERNEL_INCLUDES_H */
diff --git a/drivers/interceptor/kernel_mutex.h b/drivers/interceptor/kernel_mutex.h
new file mode 100644
index 0000000..e966d8d
--- /dev/null
+++ b/drivers/interceptor/kernel_mutex.h
@@ -0,0 +1,67 @@
+/* Netfilter Driver for IPSec VPN Client
+ *
+ * Copyright(c) 2012 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.
+ */
+
+/*
+ * kernel_mutex.h
+ *
+ * Kernel mutex API.
+ *
+ */
+
+#ifndef KERNEL_MUTEX_H
+#define KERNEL_MUTEX_H
+
+typedef struct SshKernelMutexRec *SshKernelMutex;
+
+/* Allocates and initializes a simple mutex. This should be as fast as
+ possible, but work between different processors in a multiprocessor
+ machine. Also, it is a fatal error for a thread to attempt to lock
+ this twice (i.e., this need not check whether it is actually held
+ by the same thread). The recommended implementation is a spinlock. */
+SshKernelMutex ssh_kernel_mutex_alloc(void);
+
+/* Initializes a mutex allocated from the stack. Returns TRUE on success
+ and FALSE on failure. */
+Boolean ssh_kernel_mutex_init(SshKernelMutex mutex);
+
+/* Frees the given mutex. The mutex must not be locked when it is freed. */
+void ssh_kernel_mutex_free(SshKernelMutex mutex);
+
+/* Uninitializes the given mutex. The mutex must not be locked when it is
+ uninitialized. */
+void ssh_kernel_mutex_uninit(SshKernelMutex mutex);
+
+/* Locks the mutex. Only one thread of execution can have a mutex locked
+ at a time. This will block until execution can continue. One should
+ not keep mutexes locked for extended periods of time. */
+void ssh_kernel_mutex_lock(SshKernelMutex mutex);
+
+/* Unlocks the mutex. The mutex must be unlocked from the same thread
+ from which it was locked. If other threads are waiting to lock the mutex,
+ one of them will get the lock and continue execution. */
+void ssh_kernel_mutex_unlock(SshKernelMutex mutex);
+
+#ifdef DEBUG_LIGHT
+/* Check that the mutex is locked. It is a fatal error if it is not. */
+void ssh_kernel_mutex_assert_is_locked(SshKernelMutex mutex);
+#else /* DEBUG_LIGHT */
+#define ssh_kernel_mutex_assert_is_locked(mutex)
+#endif /* DEBUG_LIGHT */
+
+#ifdef DEBUG_LIGHT
+#define KERNEL_MUTEX_USE_FUNCTIONS
+#endif /* DEBUG_LIGHT */
+
+/* This must be in the -I path of the machine-dependent interceptor
+ dir. It defines any platform-dependent things (such as the inline
+ functions, if KERNEL_MUTEX_USE_FUNCTIONS is not defined). */
+#include "platform_kernel_mutex.h"
+
+#endif /* KERNEL_MUTEX_H */
diff --git a/drivers/interceptor/linux_hook_magic.c b/drivers/interceptor/linux_hook_magic.c
new file mode 100644
index 0000000..20a6edb
--- /dev/null
+++ b/drivers/interceptor/linux_hook_magic.c
@@ -0,0 +1,842 @@
+/* Netfilter Driver for IPSec VPN Client
+ *
+ * Copyright(c) 2012 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.
+ */
+
+/*
+ * linux_hook_magic.c
+ *
+ * Linux netfilter hook probing.
+ *
+ */
+
+#include "linux_internal.h"
+
+#include <net/checksum.h>
+#include <linux/udp.h>
+
+extern SshInterceptor ssh_interceptor_context;
+
+/***************************** Probe hooks ***********************************/
+
+#define SSH_LINUX_HOOK_MAGIC_NUM_PROBES 10
+
+typedef struct SshInterceptorHookMagicOpsRec
+{
+ struct nf_hook_ops ops;
+ struct sk_buff *skbp[SSH_LINUX_HOOK_MAGIC_NUM_PROBES];
+ int probe_count;
+} SshInterceptorHookMagicOpsStruct;
+
+static SshInterceptorHookMagicOpsStruct hook_magic_in4;
+static SshInterceptorHookMagicOpsStruct hook_magic_out4;
+
+#ifdef SSH_LINUX_INTERCEPTOR_IPV6
+static SshInterceptorHookMagicOpsStruct hook_magic_in6;
+static SshInterceptorHookMagicOpsStruct hook_magic_out6;
+#endif /* SSH_LINUX_INTERCEPTOR_IPV6 */
+
+#ifndef SSH_IPSEC_IP_ONLY_INTERCEPTOR
+static SshInterceptorHookMagicOpsStruct hook_magic_arp_in;
+#endif /* !SSH_IPSEC_IP_ONLY_INTERCEPTOR */
+
+
+static unsigned int
+ssh_interceptor_hook_magic_hookfn(int pf,
+ unsigned int hooknum,
+ SshHookSkb *skb,
+ const struct net_device *in,
+ const struct net_device *out,
+ int (*okfn) (struct sk_buff *))
+{
+ struct sk_buff *skbp = SSH_HOOK_SKB_PTR(skb);
+ int i;
+
+ /* Grab lock */
+ local_bh_disable();
+ ssh_kernel_mutex_lock(ssh_interceptor_context->interceptor_lock);
+
+ switch (pf)
+ {
+ case PF_INET:
+ switch (hooknum)
+ {
+ case SSH_NF_IP_PRE_ROUTING:
+ /* Check if this is our hook_magic probe */
+ for (i = 0; i < hook_magic_in4.probe_count; i++)
+ {
+ if (hook_magic_in4.skbp[i] == skbp)
+ {
+ SSH_ASSERT(okfn != NULL);
+
+ /* Check if we have probed this hook */
+ if (ssh_interceptor_context->linux_fn.ip_rcv_finish == NULL)
+ {
+ /* Make sure the assignments do not get reordered */
+ barrier();
+
+ ssh_interceptor_context->linux_fn.ip_rcv_finish = okfn;
+ SSH_DEBUG(SSH_D_LOWOK, ("ip_rcv_finish 0x%p", okfn));
+ }
+ else
+ {
+ SSH_DEBUG(SSH_D_LOWOK,
+ ("Double probe received for "
+ "NF_IP_PRE_ROUTING"));
+ SSH_ASSERT(ssh_interceptor_context->
+ linux_fn.ip_rcv_finish == okfn);
+ }
+
+ /* Mark packet as being handled */
+ hook_magic_in4.skbp[i] = NULL;
+ goto drop;
+ }
+ }
+
+ /* Not our probe packet, let through */
+ SSH_DEBUG(10, ("Not our skbp 0x%p", skbp));
+ goto accept;
+
+ case SSH_NF_IP_POST_ROUTING:
+ /* Check if this is our hook_magic probe */
+ for (i = 0; i < hook_magic_out4.probe_count; i++)
+ {
+ if (hook_magic_out4.skbp[i] == skbp)
+ {
+ SSH_ASSERT(okfn != NULL);
+
+ /* Check if we have probed this hook */
+ if (ssh_interceptor_context->linux_fn.ip_finish_output
+ == NULL)
+ {
+ /* Make sure the assignments do not get reordered */
+ barrier();
+
+ ssh_interceptor_context->linux_fn.ip_finish_output = okfn;
+ SSH_DEBUG(SSH_D_LOWOK, ("ip_finish_output 0x%p", okfn));
+ }
+ else
+ {
+ SSH_DEBUG(SSH_D_LOWOK,
+ ("Double probe received for "
+ "NF_IP_POST_ROUTING"));
+ SSH_ASSERT(ssh_interceptor_context->
+ linux_fn.ip_finish_output == okfn);
+ }
+
+ /* Mark packet as being handled */
+ hook_magic_out4.skbp[i] = NULL;
+ goto drop;
+ }
+ }
+
+ /* Not our probe packet, let through */
+ SSH_DEBUG(10, ("Not our skbp 0x%p", skbp));
+ goto accept;
+
+ default:
+ SSH_NOTREACHED;
+ break;
+ }
+ break;
+
+#ifdef SSH_LINUX_INTERCEPTOR_IPV6
+ case PF_INET6:
+ switch (hooknum)
+ {
+ case SSH_NF_IP6_PRE_ROUTING:
+ /* Check if this is our hook_magic probe */
+ for (i = 0; i < hook_magic_in6.probe_count; i++)
+ {
+ if (hook_magic_in6.skbp[i] == skbp)
+ {
+ SSH_ASSERT(okfn != NULL);
+
+ /* Check if we have probed this hook */
+ if (ssh_interceptor_context->linux_fn.ip6_rcv_finish == NULL)
+ {
+ /* Make sure the assignments do not get reordered */
+ barrier();
+
+ ssh_interceptor_context->linux_fn.ip6_rcv_finish = okfn;
+ SSH_DEBUG(SSH_D_LOWOK, ("ip6_rcv_finish 0x%p", okfn));
+ }
+ else
+ {
+ SSH_DEBUG(SSH_D_LOWOK,
+ ("Double probe received for "
+ "NF_IP6_PRE_ROUTING"));
+ SSH_ASSERT(ssh_interceptor_context->
+ linux_fn.ip6_rcv_finish == okfn);
+ }
+
+ /* Mark packet as being handled */
+ hook_magic_in6.skbp[i] = NULL;
+ goto drop;
+ }
+ }
+
+ /* Not our probe packet, let through */
+ SSH_DEBUG(10, ("Not our skbp 0x%p", skbp));
+ goto accept;
+
+ case SSH_NF_IP6_POST_ROUTING:
+ /* Check if this is our hook_magic probe */
+ for (i = 0; i < hook_magic_out6.probe_count; i++)
+ {
+ if (hook_magic_out6.skbp[i] == skbp)
+ {
+ SSH_ASSERT(okfn != NULL);
+
+ /* Check if we have not yet probed this hook */
+ if (ssh_interceptor_context->linux_fn.ip6_output_finish
+ == NULL)
+ {
+ /* Make sure the assignments do not get reordered */
+ barrier();
+
+ ssh_interceptor_context->linux_fn.ip6_output_finish =
+ okfn;
+ SSH_DEBUG(SSH_D_LOWOK, ("ip6_output_finish 0x%p", okfn));
+ }
+ else
+ {
+ SSH_DEBUG(SSH_D_LOWOK,
+ ("Double probe received for "
+ "NF_IP6_POST_ROUTING"));
+ SSH_ASSERT(ssh_interceptor_context->
+ linux_fn.ip6_output_finish == okfn);
+ }
+
+ /* Mark packet as being handled */
+ hook_magic_out6.skbp[i] = NULL;
+ goto drop;
+ }
+ }
+
+ /* Not our probe packet, let through */
+ SSH_DEBUG(10, ("Not our skbp 0x%p", skbp));
+ goto accept;
+
+ default:
+ SSH_NOTREACHED;
+ break;
+ }
+ break;
+#endif /* SSH_LINUX_INTERCEPTOR_IPV6 */
+
+#ifndef SSH_IPSEC_IP_ONLY_INTERCEPTOR
+ case SSH_NFPROTO_ARP:
+ /* Check if this is our hook_magic probe */
+ for (i = 0; i < hook_magic_arp_in.probe_count; i++)
+ {
+ if (hook_magic_arp_in.skbp[i] == skbp)
+ {
+ SSH_ASSERT(hooknum == NF_ARP_IN);
+ SSH_ASSERT(okfn != NULL);
+
+ /* Check if we have probed this hook */
+ if (ssh_interceptor_context->linux_fn.arp_process == NULL)
+ {
+ /* Make sure the assignments do not get reordered */
+ barrier();
+
+ ssh_interceptor_context->linux_fn.arp_process = okfn;
+ SSH_DEBUG(SSH_D_LOWOK, ("arp_process 0x%p", okfn));
+ }
+ else
+ {
+ SSH_DEBUG(SSH_D_LOWOK,
+ ("Double probe received for NF_ARP_IN"));
+ SSH_ASSERT(ssh_interceptor_context->linux_fn.arp_process
+ == okfn);
+ }
+
+ /* Mark packet as being handled */
+ hook_magic_arp_in.skbp[i] = NULL;
+ goto drop;
+ }
+ }
+
+ /* Not our probe packet, let through */
+ SSH_DEBUG(10, ("Not our skbp 0x%p", skbp));
+ goto accept;
+#endif /* !SSH_IPSEC_IP_ONLY_INTERCEPTOR */
+
+ default:
+ SSH_NOTREACHED;
+ break;
+ }
+
+ /* Unlock and drop the packet */
+ drop:
+ ssh_kernel_mutex_unlock(ssh_interceptor_context->interceptor_lock);
+ local_bh_enable();
+ return NF_DROP;
+
+ accept:
+ /* Unlock and let packet continue */
+ ssh_kernel_mutex_unlock(ssh_interceptor_context->interceptor_lock);
+ local_bh_enable();
+ return NF_ACCEPT;
+}
+
+static unsigned int
+ssh_interceptor_hook_magic_hookfn_ipv4(unsigned int hooknum,
+ SshHookSkb *skb,
+ const struct net_device *in,
+ const struct net_device *out,
+ int (*okfn) (struct sk_buff *))
+{
+ return ssh_interceptor_hook_magic_hookfn(PF_INET, hooknum, skb,
+ in, out, okfn);
+}
+
+#ifdef SSH_LINUX_INTERCEPTOR_IPV6
+static unsigned int
+ssh_interceptor_hook_magic_hookfn_ipv6(unsigned int hooknum,
+ SshHookSkb *skb,
+ const struct net_device *in,
+ const struct net_device *out,
+ int (*okfn) (struct sk_buff *))
+{
+ return ssh_interceptor_hook_magic_hookfn(PF_INET6, hooknum, skb,
+ in, out, okfn);
+}
+#endif /* SSH_LINUX_INTERCEPTOR_IPV6 */
+
+#ifndef SSH_IPSEC_IP_ONLY_INTERCEPTOR
+static unsigned int
+ssh_interceptor_hook_magic_hookfn_arp(unsigned int hooknum,
+ SshHookSkb *skb,
+ const struct net_device *in,
+ const struct net_device *out,
+ int (*okfn) (struct sk_buff *))
+{
+ return ssh_interceptor_hook_magic_hookfn(SSH_NFPROTO_ARP, hooknum, skb,
+ in, out, okfn);
+}
+#endif /* !SSH_IPSEC_IP_ONLY_INTERCEPTOR */
+
+
+/***************************** Probe packet sending **************************/
+
+/* Caller holds 'interceptor_lock'.
+ This function will release it when calling the network stack functions,
+ and will grab it back after the function has returned. */
+
+static int
+ssh_interceptor_hook_magic_send(SshInterceptorHookMagicOpsStruct *hook_magic)
+{
+ struct sk_buff *skbp;
+ struct net_device *dev;
+ struct in_device *inet_dev = NULL;
+ struct iphdr *iph;
+#ifdef SSH_LINUX_INTERCEPTOR_IPV6
+ struct inet6_dev *inet6_dev = NULL;
+ struct ipv6hdr *ip6h;
+ struct in6_addr addr6;
+#endif /* SSH_LINUX_INTERCEPTOR_IPV6 */
+#ifndef SSH_IPSEC_IP_ONLY_INTERCEPTOR
+ unsigned char *ptr;
+ struct arphdr *arph;
+#endif /* !SSH_IPSEC_IP_ONLY_INTERCEPTOR */
+ struct udphdr *udph;
+
+ /* Assert that we have the lock */
+ ssh_kernel_mutex_assert_is_locked(ssh_interceptor_context->interceptor_lock);
+
+ /* Find a suitable device to put on the probe skb */
+ read_lock(&dev_base_lock);
+
+ for (dev = SSH_FIRST_NET_DEVICE();
+ dev != NULL;
+ dev = SSH_NEXT_NET_DEVICE(dev))
+ {
+ if (!(dev->flags & IFF_UP))
+ continue;
+
+ inet_dev = in_dev_get(dev);
+ if (inet_dev == NULL || inet_dev->ifa_list == NULL)
+ goto next_dev;
+
+#ifdef SSH_LINUX_INTERCEPTOR_IPV6
+ /* The device must have an IPv6 address. */
+ inet6_dev = in6_dev_get(dev);
+ memset(&addr6, 0, sizeof(addr6));
+
+ if (inet6_dev != NULL)
+ {
+ struct inet6_ifaddr *ifaddr6, *next_ifaddr6;
+ SSH_INET6_IFADDR_LIST_FOR_EACH(ifaddr6,
+ next_ifaddr6,
+ inet6_dev->addr_list)
+ {
+ addr6 = ifaddr6->addr;
+ break;
+ }
+ }
+
+ if (inet6_dev == NULL ||
+ memcmp(addr6.s6_addr, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 16) == 0)
+ goto next_dev;
+#endif /* SSH_LINUX_INTERCEPTOR_IPV6 */
+
+#ifndef SSH_IPSEC_IP_ONLY_INTERCEPTOR
+ /* The device must must support ARP. */
+ if ((dev->flags & IFF_NOARP) || dev->addr_len != 6)
+ goto next_dev;
+#endif /* !SSH_IPSEC_IP_ONLY_INTERCEPTOR */
+
+ /* This device is suitable for probing. */
+ break;
+
+ next_dev:
+ if (inet_dev)
+ in_dev_put(inet_dev);
+ inet_dev = NULL;
+#ifdef SSH_LINUX_INTERCEPTOR_IPV6
+ if (inet6_dev)
+ in6_dev_put(inet6_dev);
+ inet6_dev = NULL;
+#endif /* SSH_LINUX_INTERCEPTOR_IPV6 */
+ }
+ read_unlock(&dev_base_lock);
+ if (dev == NULL)
+ {
+ SSH_DEBUG(SSH_D_ERROR,
+ ("Hook magic failed, could not find a suitable device"));
+ goto out;
+ }
+
+ /* Allocate probe skb */
+ /* Maximum size: IPv6 + UDP = 48 bytes
+ ( + headroom for ethernet header + 2 bytes for proper alignment) */
+ skbp = alloc_skb(48 + ETH_HLEN + 2, GFP_ATOMIC);
+ if (skbp == NULL)
+ {
+ SSH_DEBUG(SSH_D_ERROR,
+ ("Hook magic failed, could not allocate skbuff"));
+ goto out;
+ }
+
+ /* Reserve headroom for ethernet header.
+ Make sure IP header will be properly aligned. */
+ skb_reserve(skbp, ETH_HLEN + 2);
+
+ SSH_SKB_SET_MACHDR(skbp, skbp->data);
+
+#ifdef LINUX_HAS_SKB_MAC_LEN
+ skbp->mac_len = 0;
+#endif /* LINUX_HAS_SKB_MAC_LEN */
+ skbp->pkt_type = PACKET_HOST;
+
+ skbp->dev = dev;
+ SSH_SKB_DST_SET(skbp, NULL);
+
+ /* Store skb pointer to a free slot. */
+ SSH_ASSERT(hook_magic->probe_count < SSH_LINUX_HOOK_MAGIC_NUM_PROBES);
+ hook_magic->skbp[hook_magic->probe_count] = skbp;
+ hook_magic->probe_count++;
+
+ switch (hook_magic->ops.pf)
+ {
+ case PF_INET:
+
+ /* Build an IP + UDP packet for probing */
+ skbp->protocol = __constant_htons(ETH_P_IP);
+
+ iph = (struct iphdr *) skb_put(skbp, sizeof(struct iphdr));
+ if (iph == NULL)
+ {
+ SSH_DEBUG(SSH_D_ERROR,
+ ("Hook magic failed, no space for IPv4 header"));
+ goto out;
+ }
+ SSH_SKB_SET_NETHDR(skbp, (unsigned char *) iph);
+
+ memset(iph, 0, sizeof(struct iphdr));
+ iph->version = 4;
+ iph->ihl = 5;
+ iph->ttl = 1;
+ iph->protocol = IPPROTO_UDP;
+ iph->tot_len = htons(28);
+
+ /* Use the device addresses */
+ SSH_ASSERT(inet_dev != NULL && inet_dev->ifa_list != NULL);
+ iph->saddr = inet_dev->ifa_list->ifa_local;
+ iph->daddr = inet_dev->ifa_list->ifa_local;
+
+ /* Add UDP header */
+ udph = (struct udphdr *) skb_put(skbp, sizeof(struct udphdr));
+ if (udph == NULL)
+ {
+ SSH_DEBUG(SSH_D_ERROR,
+ ("Hook magic failed, no space for UDP header"));
+ goto out;
+ }
+ SSH_SKB_SET_TRHDR(skbp, (unsigned char *) udph);
+
+ udph->source = htons(9);
+ udph->dest = htons(9);
+ udph->len = 0;
+ udph->check = 0;
+
+ /* Checksum */
+ iph->check = 0;
+ iph->check = ip_fast_csum((unsigned char *) iph, iph->ihl);
+
+ switch (hook_magic->ops.hooknum)
+ {
+ case SSH_NF_IP_PRE_ROUTING:
+ SSH_ASSERT(ssh_interceptor_context->
+ linux_fn.ip_rcv_finish == NULL);
+ SSH_DEBUG(SSH_D_HIGHOK,
+ ("Probing SSH_NF_IP_PRE_ROUTING with skbp 0x%p", skbp));
+ /* Release lock for duration of netif_rx() */
+ ssh_kernel_mutex_unlock(ssh_interceptor_context->interceptor_lock);
+ local_bh_enable();
+ netif_rx(skbp);
+ local_bh_disable();
+ ssh_kernel_mutex_lock(ssh_interceptor_context->interceptor_lock);
+ break;
+
+ case SSH_NF_IP_POST_ROUTING:
+ SSH_ASSERT(ssh_interceptor_context->
+ linux_fn.ip_finish_output == NULL);
+ SSH_DEBUG(SSH_D_HIGHOK,
+ ("Probing SSH_NF_IP_POST_ROUTING with skbp 0x%p", skbp));
+ if (ssh_interceptor_reroute_skb_ipv4(ssh_interceptor_context,
+ skbp, 0, 0))
+ {
+ /* Release lock for the duration of dst->output() */
+ ssh_kernel_mutex_unlock(ssh_interceptor_context->
+ interceptor_lock);
+ dst_output(skbp);
+ ssh_kernel_mutex_lock(ssh_interceptor_context->interceptor_lock);
+ }
+ break;
+
+ default:
+ SSH_NOTREACHED;
+ break;
+ }
+ break;
+
+#ifdef SSH_LINUX_INTERCEPTOR_IPV6
+ case PF_INET6:
+
+ /* Build an IPv6 + UDP packet for probing */
+ skbp->protocol = __constant_htons(ETH_P_IPV6);
+ ip6h = (struct ipv6hdr *) skb_put(skbp, sizeof(struct ipv6hdr));
+ if (ip6h == NULL)
+ {
+ SSH_DEBUG(SSH_D_ERROR,
+ ("Hook magic failed, no space for IPv6 header"));
+ goto out;
+ }
+ SSH_SKB_SET_NETHDR(skbp, (unsigned char *) ip6h);
+
+ memset(ip6h, 0, sizeof(struct ipv6hdr));
+ ip6h->version = 6;
+ ip6h->hop_limit = 1;
+ ip6h->nexthdr = NEXTHDR_UDP;
+
+ /* Use the device addresses */
+ SSH_ASSERT(memcmp(addr6.s6_addr, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 16)
+ != 0);
+
+ ip6h->saddr = addr6;
+ ip6h->daddr = addr6;
+
+ /* Add UDP header */
+ udph = (struct udphdr *) skb_put(skbp, sizeof(struct udphdr));
+ if (udph == NULL)
+ {
+ SSH_DEBUG(SSH_D_ERROR,
+ ("Hook magic failed, no space for UDP header"));
+ goto out;
+ }
+ SSH_SKB_SET_TRHDR(skbp, (unsigned char *) udph);
+
+ udph->source = htons(9);
+ udph->dest = htons(9);
+ udph->len = 0;
+ udph->check = 0;
+
+ switch (hook_magic->ops.hooknum)
+ {
+ case SSH_NF_IP6_PRE_ROUTING:
+ SSH_ASSERT(ssh_interceptor_context->
+ linux_fn.ip6_rcv_finish == NULL);
+ SSH_DEBUG(SSH_D_HIGHOK,
+ ("Probing SSH_NF_IP6_PRE_ROUTING with skbp 0x%p", skbp));
+ /* Release lock for the duration of netif_rx() */
+ ssh_kernel_mutex_unlock(ssh_interceptor_context->interceptor_lock);
+ local_bh_enable();
+ netif_rx(skbp);
+ local_bh_disable();
+ ssh_kernel_mutex_lock(ssh_interceptor_context->interceptor_lock);
+ break;
+
+ case SSH_NF_IP6_POST_ROUTING:
+ SSH_ASSERT(ssh_interceptor_context->
+ linux_fn.ip6_output_finish == NULL);
+ SSH_DEBUG(SSH_D_HIGHOK,
+ ("Probing SSH_NF_IP6_POST_ROUTING with skbp 0x%p", skbp));
+ if (ssh_interceptor_reroute_skb_ipv6(ssh_interceptor_context,
+ skbp, 0, 0))
+ {
+ /* Release lock for the duration of dst->output() */
+ ssh_kernel_mutex_unlock(ssh_interceptor_context->
+ interceptor_lock);
+ dst_output(skbp);
+ ssh_kernel_mutex_lock(ssh_interceptor_context->interceptor_lock);
+ }
+ break;
+
+ default:
+ SSH_NOTREACHED;
+ break;
+ }
+ break;
+#endif /* SSH_LINUX_INTERCEPTOR_IPV6 */
+
+#ifndef SSH_IPSEC_IP_ONLY_INTERCEPTOR
+ case SSH_NFPROTO_ARP:
+ SSH_ASSERT(hook_magic->ops.hooknum == NF_ARP_IN);
+ SSH_ASSERT(ssh_interceptor_context->linux_fn.arp_process == NULL);
+
+ /* Build an ARP REQ packet for probing */
+ skbp->protocol = __constant_htons(ETH_P_ARP);
+
+ SSH_ASSERT(dev->addr_len == 6);
+ SSH_ASSERT((sizeof(struct arphdr) + (2 * dev->addr_len) + 8) <= 48);
+
+ arph = (struct arphdr *) skb_put(skbp, sizeof(struct arphdr) +
+ (2 * dev->addr_len) + 8);
+ if (arph == NULL)
+ {
+ SSH_DEBUG(SSH_D_ERROR,
+ ("Hook magic failed, no space for ARP header"));
+ goto out;
+ }
+ SSH_SKB_SET_NETHDR(skbp, (unsigned char *) arph);
+
+ arph->ar_hrd = htons(ARPHRD_ETHER);
+ arph->ar_pro = htons(ETH_P_IP);
+ arph->ar_hln = dev->addr_len;
+ arph->ar_pln = 4;
+ arph->ar_op = htons(ARPOP_REQUEST);
+
+ ptr = skbp->data + sizeof(*arph);
+
+ /* Zero sender HA */
+ memset(ptr, 0, dev->addr_len);
+ ptr += dev->addr_len;
+
+ /* Take sender IP from device */
+ memcpy(ptr, &inet_dev->ifa_list->ifa_local, 4);
+ ptr += 4;
+
+ /* All f's target HA */
+ memset(ptr, 0xff, dev->addr_len);
+ ptr += dev->addr_len;
+
+ /* Take target IP from device */
+ memcpy(ptr, &inet_dev->ifa_list->ifa_local, 4);
+
+ SSH_DEBUG(SSH_D_HIGHOK,
+ ("Probing NF_ARP_IN with skbp 0x%p", skbp));
+ /* Release the lock for the duration of dst->output() */
+ ssh_kernel_mutex_unlock(ssh_interceptor_context->interceptor_lock);
+ local_bh_enable();
+ netif_rx(skbp);
+ local_bh_disable();
+ ssh_kernel_mutex_lock(ssh_interceptor_context->interceptor_lock);
+ break;
+#endif /* !SSH_IPSEC_IP_ONLY_INTERCEPTOR */
+
+ default:
+ SSH_NOTREACHED;
+ break;
+ }
+
+ out:
+ if (inet_dev)
+ in_dev_put(inet_dev);
+#ifdef SSH_LINUX_INTERCEPTOR_IPV6
+ if (inet6_dev)
+ in6_dev_put(inet6_dev);
+#endif /* SSH_LINUX_INTERCEPTOR_IPV6 */
+
+ return 1;
+}
+
+static void
+ssh_interceptor_hook_magic_uninit(void)
+{
+ /* Unregister probe hooks */
+
+ if (hook_magic_in4.ops.pf == PF_INET)
+ {
+ nf_unregister_hook(&hook_magic_in4.ops);
+ hook_magic_in4.ops.pf = 0;
+ }
+ if (hook_magic_out4.ops.pf == PF_INET)
+ {
+ nf_unregister_hook(&hook_magic_out4.ops);
+ hook_magic_out4.ops.pf = 0;
+ }
+
+#ifdef SSH_LINUX_INTERCEPTOR_IPV6
+ if (hook_magic_in6.ops.pf == PF_INET6)
+ {
+ nf_unregister_hook(&hook_magic_in6.ops);
+ hook_magic_in6.ops.pf = 0;
+ }
+ if (hook_magic_out6.ops.pf == PF_INET6)
+ {
+ nf_unregister_hook(&hook_magic_out6.ops);
+ hook_magic_out6.ops.pf = 0;
+ }
+#endif /* SSH_LINUX_INTERCEPTOR_IPV6 */
+
+#ifndef SSH_IPSEC_IP_ONLY_INTERCEPTOR
+ if (hook_magic_arp_in.ops.pf == SSH_NFPROTO_ARP)
+ {
+ nf_unregister_hook(&hook_magic_arp_in.ops);
+ hook_magic_arp_in.ops.pf = 0;
+ }
+#endif /* !SSH_IPSEC_IP_ONLY_INTERCEPTOR */
+}
+
+int
+ssh_interceptor_hook_magic_init()
+{
+ int ret;
+ int i;
+
+ /* Intialize and register probe hooks */
+
+ /* SSH_NF_IP_PRE_ROUTING */
+ ssh_interceptor_context->linux_fn.ip_rcv_finish = NULL;
+ memset(&hook_magic_in4, 0, sizeof(hook_magic_in4));
+ hook_magic_in4.ops.hook = ssh_interceptor_hook_magic_hookfn_ipv4;
+ hook_magic_in4.ops.pf = PF_INET;
+ hook_magic_in4.ops.hooknum = SSH_NF_IP_PRE_ROUTING;
+ hook_magic_in4.ops.priority = SSH_NF_IP_PRI_FIRST;
+ nf_register_hook(&hook_magic_in4.ops);
+
+ /* SSH_NF_IP_POST_ROUTING */
+ ssh_interceptor_context->linux_fn.ip_finish_output = NULL;
+ memset(&hook_magic_out4, 0, sizeof(hook_magic_out4));
+ hook_magic_out4.ops.hook = ssh_interceptor_hook_magic_hookfn_ipv4;
+ hook_magic_out4.ops.pf = PF_INET;
+ hook_magic_out4.ops.hooknum = SSH_NF_IP_POST_ROUTING;
+ hook_magic_out4.ops.priority = SSH_NF_IP_PRI_FIRST;
+ nf_register_hook(&hook_magic_out4.ops);
+
+#ifdef SSH_LINUX_INTERCEPTOR_IPV6
+ /* SSH_NF_IP6_PRE_ROUTING */
+ ssh_interceptor_context->linux_fn.ip6_rcv_finish = NULL;
+ memset(&hook_magic_in6, 0, sizeof(hook_magic_in6));
+ hook_magic_in6.ops.hook = ssh_interceptor_hook_magic_hookfn_ipv6;
+ hook_magic_in6.ops.pf = PF_INET6;
+ hook_magic_in6.ops.hooknum = SSH_NF_IP6_PRE_ROUTING;
+ hook_magic_in6.ops.priority = SSH_NF_IP6_PRI_FIRST;
+ nf_register_hook(&hook_magic_in6.ops);
+
+ /* SSH_NF_IP6_POST_ROUTING */
+ ssh_interceptor_context->linux_fn.ip6_output_finish = NULL;
+ memset(&hook_magic_out6, 0, sizeof(hook_magic_out6));
+ hook_magic_out6.ops.hook = ssh_interceptor_hook_magic_hookfn_ipv6;
+ hook_magic_out6.ops.pf = PF_INET6;
+ hook_magic_out6.ops.hooknum = SSH_NF_IP6_POST_ROUTING;
+ hook_magic_out6.ops.priority = SSH_NF_IP6_PRI_FIRST;
+ nf_register_hook(&hook_magic_out6.ops);
+#endif /* SSH_LINUX_INTERCEPTOR_IPV6 */
+
+#ifndef SSH_IPSEC_IP_ONLY_INTERCEPTOR
+ /* NF_ARP_IN */
+ ssh_interceptor_context->linux_fn.arp_process = NULL;
+ memset(&hook_magic_arp_in, 0, sizeof(hook_magic_arp_in));
+ hook_magic_arp_in.ops.hook = ssh_interceptor_hook_magic_hookfn_arp;
+ hook_magic_arp_in.ops.pf = SSH_NFPROTO_ARP;
+ hook_magic_arp_in.ops.hooknum = NF_ARP_IN;
+ hook_magic_arp_in.ops.priority = 1;
+ nf_register_hook(&hook_magic_arp_in.ops);
+#endif /* !SSH_IPSEC_IP_ONLY_INTERCEPTOR */
+
+ /* Send probe packets */
+
+ /* Try maximum SSH_LINUX_HOOK_MAGIC_NUM_PROBES times, and give up */
+ for (i = 0; i < SSH_LINUX_HOOK_MAGIC_NUM_PROBES; i++)
+ {
+ ret = 0;
+
+ local_bh_disable();
+ ssh_kernel_mutex_lock(ssh_interceptor_context->interceptor_lock);
+
+ if (ssh_interceptor_context->linux_fn.ip_rcv_finish == NULL)
+ ret += ssh_interceptor_hook_magic_send(&hook_magic_in4);
+ if (ssh_interceptor_context->linux_fn.ip_finish_output == NULL)
+ ret += ssh_interceptor_hook_magic_send(&hook_magic_out4);
+
+#ifdef SSH_LINUX_INTERCEPTOR_IPV6
+ if (ssh_interceptor_context->linux_fn.ip6_rcv_finish == NULL)
+ ret += ssh_interceptor_hook_magic_send(&hook_magic_in6);
+ if (ssh_interceptor_context->linux_fn.ip6_output_finish == NULL)
+ ret += ssh_interceptor_hook_magic_send(&hook_magic_out6);
+#endif /* SSH_LINUX_INTERCEPTOR_IPV6 */
+
+#ifndef SSH_IPSEC_IP_ONLY_INTERCEPTOR
+ if (ssh_interceptor_context->linux_fn.arp_process == NULL)
+ ret += ssh_interceptor_hook_magic_send(&hook_magic_arp_in);
+#endif /* !SSH_IPSEC_IP_ONLY_INTERCEPTOR */
+
+ ssh_kernel_mutex_unlock(ssh_interceptor_context->interceptor_lock);
+ local_bh_enable();
+
+ if (ret == 0)
+ break;
+
+ set_current_state(TASK_UNINTERRUPTIBLE);
+ if (i < 5)
+ schedule_timeout((i + 5) * HZ / 10);
+ else
+ schedule_timeout(HZ);
+ }
+
+ /* Remove probe hooks */
+ ssh_interceptor_hook_magic_uninit();
+
+#ifdef DEBUG_LIGHT
+ if (ret)
+ {
+ SSH_DEBUG(SSH_D_ERROR,
+ ("ssh_hook_magic_init exits with return value %d", -ret));
+ }
+ else
+ {
+ /* Assert that all function pointers have been resolved. */
+ SSH_ASSERT(ssh_interceptor_context->linux_fn.ip_rcv_finish != NULL);
+ SSH_ASSERT(ssh_interceptor_context->linux_fn.ip_finish_output != NULL);
+#ifdef SSH_LINUX_INTERCEPTOR_IPV6
+ SSH_ASSERT(ssh_interceptor_context->linux_fn.ip6_rcv_finish != NULL);
+ SSH_ASSERT(ssh_interceptor_context->linux_fn.ip6_output_finish != NULL);
+#endif /* SSH_LINUX_INTERCEPTOR_IPV6 */
+#ifndef SSH_IPSEC_IP_ONLY_INTERCEPTOR
+ SSH_ASSERT(ssh_interceptor_context->linux_fn.arp_process != NULL);
+#endif /* !SSH_IPSEC_IP_ONLY_INTERCEPTOR */
+ }
+
+#endif /* DEBUG_LIGHT */
+
+ return -ret;
+}
diff --git a/drivers/interceptor/linux_iface.c b/drivers/interceptor/linux_iface.c
new file mode 100644
index 0000000..cc0c499
--- /dev/null
+++ b/drivers/interceptor/linux_iface.c
@@ -0,0 +1,863 @@
+/* Netfilter Driver for IPSec VPN Client
+ *
+ * Copyright(c) 2012 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.
+ */
+
+/*
+ * linux_iface.c
+ *
+ * Linux interceptor network interface handling.
+ *
+ */
+
+#include "linux_internal.h"
+
+extern SshInterceptor ssh_interceptor_context;
+
+/* Protect access to net_device list in kernel. */
+#define SSH_LOCK_LINUX_DEV_LIST() read_lock(&dev_base_lock)
+#define SSH_UNLOCK_LINUX_DEV_LIST() read_unlock(&dev_base_lock);
+
+/**************************** Notification handlers *************************/
+
+/* Interface notifier callback. This will notify when there has been a
+ change in the interface list; device is added or removed, or an
+ IPv4/IPv6 address has been added or removed from an device. */
+
+int
+ssh_interceptor_notifier_callback(struct notifier_block *block,
+ unsigned long type, void *arg)
+{
+ if (ssh_interceptor_context != NULL)
+ ssh_interceptor_receive_ifaces(ssh_interceptor_context);
+
+ return NOTIFY_OK;
+}
+
+/* Internal mapping from ifnum to net_device.
+ This function will assert that 'ifnum' is a valid
+ SshInterceptorIfnum and that the corresponding net_device
+ exists in the interface hashtable. This function will dev_hold()
+ the net_device. The caller of this function must release it by
+ calling ssh_interceptor_release_netdev(). If `context_return' is
+ not NULL then this sets it to point to the interface context. */
+inline struct net_device *
+ssh_interceptor_ifnum_to_netdev_ctx(SshInterceptor interceptor,
+ SshUInt32 ifnum,
+ void **context_return)
+{
+ SshInterceptorInternalInterface iface;
+ struct net_device *dev = NULL;
+
+ SSH_LINUX_ASSERT_VALID_IFNUM(ifnum);
+
+ read_lock(&interceptor->if_table_lock);
+ for (iface = interceptor->if_hash[ifnum % SSH_LINUX_IFACE_HASH_SIZE];
+ iface && iface->ifindex != ifnum;
+ iface = iface->next)
+ ;
+ if (iface)
+ {
+ SSH_ASSERT(iface->generation == interceptor->if_generation);
+ dev = iface->dev;
+ SSH_ASSERT(dev != NULL);
+ dev_hold(dev);
+ if (context_return != NULL)
+ *context_return = iface->context;
+ }
+ read_unlock(&interceptor->if_table_lock);
+
+ return dev;
+}
+
+inline struct net_device *
+ssh_interceptor_ifnum_to_netdev(SshInterceptor interceptor,
+ SshUInt32 ifnum)
+{
+ return ssh_interceptor_ifnum_to_netdev_ctx(interceptor, ifnum, NULL);
+}
+
+/* Decrement the reference count of net_device 'dev'. */
+inline void
+ssh_interceptor_release_netdev(struct net_device *dev)
+{
+ SSH_ASSERT(dev != NULL);
+ dev_put(dev);
+}
+
+#ifndef SSH_IPSEC_IP_ONLY_INTERCEPTOR
+/* Map Linux media types (actually extensions of ARP hardware
+ address types) to platform independent denominations. */
+static SshInterceptorMedia
+ssh_interceptor_media_type(unsigned short type)
+{
+ switch (type)
+ {
+ case ARPHRD_ETHER:
+ return SSH_INTERCEPTOR_MEDIA_ETHERNET;
+ case ARPHRD_IEEE802:
+ return SSH_INTERCEPTOR_MEDIA_FDDI;
+ default:
+ return SSH_INTERCEPTOR_MEDIA_PLAIN;
+ }
+ SSH_NOTREACHED;
+ return SSH_INTERCEPTOR_MEDIA_PLAIN;
+}
+#endif /* !SSH_IPSEC_IP_ONLY_INTERCEPTOR */
+
+
+/* Sends the updated interface information to the engine. This is called
+ at the initialization of the interceptor and whenever the status of any
+ interface changes.
+
+ This function grabs 'if_table_lock' (for reading) and 'interceptor_lock'.
+*/
+static void
+ssh_interceptor_send_interfaces(SshInterceptor interceptor)
+{
+ SshInterceptorInternalInterface iface;
+ SshInterceptorInterface *ifarray;
+ SshInterceptorInterfacesCB interfaces_callback;
+ struct net_device *dev;
+ struct in_device *inet_dev = NULL;
+ struct in_ifaddr *addr;
+ int num, n, count, i, hashvalue;
+#ifdef SSH_LINUX_INTERCEPTOR_IPV6
+ struct inet6_dev *inet6_dev = NULL;
+ struct inet6_ifaddr *addr6, *next_addr6;
+#endif /* SSH_LINUX_INTERCEPTOR_IPV6 */
+
+ /* Grab 'if_table_lock' for reading the interface table. */
+ read_lock(&interceptor->if_table_lock);
+
+ num = interceptor->if_table_size;
+ if (!num)
+ {
+ read_unlock(&interceptor->if_table_lock);
+ SSH_DEBUG(4, ("No interfaces to report."));
+ return;
+ }
+
+ /* Allocate temporary memory for the table that is
+ passed to the engine. This is mallocated, since
+ we want to minimise stack usage. */
+ ifarray = ssh_malloc(sizeof(*ifarray) * num);
+ if (ifarray == NULL)
+ {
+ read_unlock(&interceptor->if_table_lock);
+ return;
+ }
+ memset(ifarray, 0, sizeof(*ifarray) * num);
+
+ /* Iterate over the slots of the iface hashtable. */
+ n = 0;
+ for (hashvalue = 0; hashvalue < SSH_LINUX_IFACE_HASH_SIZE; hashvalue++)
+ {
+
+ /* Iterate over the chain of iface entries in a hashtable slot. */
+ for (iface = interceptor->if_hash[hashvalue];
+ iface != NULL;
+ iface = iface->next)
+ {
+ /* Ignore devices that are not up. */
+ dev = iface->dev;
+ if (dev == NULL || !(dev->flags & IFF_UP))
+ continue;
+
+ /* Disable net_device features that vpnclient does not support */
+ if (dev->features & NETIF_F_TSO)
+ dev->features &= ~NETIF_F_TSO;
+
+#ifdef LINUX_HAS_NETIF_F_GSO
+ /* Disable net_device features that vpnclient does not support */
+ if (dev->features & NETIF_F_GSO)
+ {
+ SSH_DEBUG(2, ("Warning: Interface %lu [%s], dropping unsupported "
+ "feature NETIF_F_GSO",
+ (unsigned long) iface->ifindex,
+ (dev->name ? dev->name : "<none>")));
+ dev->features &= ~NETIF_F_GSO;
+ }
+#endif /* LINUX_HAS_NETIF_F_GSO */
+
+#ifdef LINUX_HAS_NETIF_F_TSO6
+ /* Disable net_device features that vpnclient does not support */
+ if (dev->features & NETIF_F_TSO6)
+ {
+ SSH_DEBUG(2, ("Warning: Interface %lu [%s], dropping unsupported "
+ "feature NETIF_F_TSO6",
+ (unsigned long) iface->ifindex,
+ (dev->name ? dev->name : "<none>")));
+ dev->features &= ~NETIF_F_TSO6;
+ }
+#endif /* LINUX_HAS_NETIF_F_TSO6 */
+
+#ifdef LINUX_HAS_NETIF_F_TSO_ECN
+ /* Disable net_device features that vpnclient does not support */
+ if (dev->features & NETIF_F_TSO_ECN)
+ {
+ SSH_DEBUG(2, ("Warning: Interface %lu [%s], dropping unsupported "
+ "feature NETIF_F_TSO_ECN",
+ (unsigned long) iface->ifindex,
+ (dev->name ? dev->name : "<none>")));
+ dev->features &= ~NETIF_F_TSO_ECN;
+ }
+#endif /* LINUX_HAS_NETIF_F_TSO_ECN */
+
+#ifdef LINUX_HAS_NETIF_F_GSO_ROBUST
+ /* Disable net_device features that vpnclient does not support */
+ if (dev->features & NETIF_F_GSO_ROBUST)
+ {
+ SSH_DEBUG(2, ("Warning: Interface %lu [%s], dropping unsupported "
+ "feature NETIF_F_GSO_ROBUST",
+ (unsigned long) iface->ifindex,
+ (dev->name ? dev->name : "<none>")));
+ dev->features &= ~NETIF_F_GSO_ROBUST;
+ }
+#endif /* LINUX_HAS_NETIF_F_GSO_ROBUST */
+
+#ifdef LINUX_HAS_NETIF_F_UFO
+ if (dev->features & NETIF_F_UFO)
+ {
+ SSH_DEBUG(2, ("Warning: Interface %lu [%s], dropping unsupported "
+ "feature NETIF_F_UFO",
+ (unsigned long) iface->ifindex,
+ (dev->name ? dev->name : "<none>")));
+ dev->features &= ~NETIF_F_UFO;
+ }
+#endif /* LINUX_HAS_NETIF_F_UFO */
+
+ /* Count addresses */
+ count = 0;
+
+ /* Increment refcount to make sure the device does not disappear. */
+ inet_dev = in_dev_get(dev);
+ if (inet_dev)
+ {
+ /* Count the device's IPv4 addresses */
+ for (addr = inet_dev->ifa_list; addr != NULL;
+ addr = addr->ifa_next)
+ {
+ count++;
+ }
+ }
+
+#ifdef SSH_LINUX_INTERCEPTOR_IPV6
+ /* Increment refcount to make sure the device does not disappear. */
+ inet6_dev = in6_dev_get(dev);
+ if (inet6_dev)
+ {
+ /* Count the device's IPv6 addresses */
+ SSH_INET6_IFADDR_LIST_FOR_EACH(addr6,
+ next_addr6,
+ inet6_dev->addr_list)
+ {
+ count++;
+ }
+ }
+#endif /* SSH_LINUX_INTERCEPTOR_IPV6 */
+
+ /* Fill interface entry. */
+ ifarray[n].ifnum = iface->ifindex;
+ ifarray[n].to_protocol.flags =
+ SSH_INTERCEPTOR_MEDIA_INFO_NO_FRAGMENT;
+ ifarray[n].to_protocol.mtu_ipv4 = dev->mtu;
+ ifarray[n].to_adapter.flags = 0;
+ ifarray[n].to_adapter.mtu_ipv4 = dev->mtu;
+
+#ifdef WITH_IPV6
+ ifarray[n].to_adapter.mtu_ipv6 = dev->mtu;
+ ifarray[n].to_protocol.mtu_ipv6 = dev->mtu;
+#endif /* WITH_IPV6 */
+
+#ifndef SSH_IPSEC_IP_ONLY_INTERCEPTOR
+ ifarray[n].to_adapter.media = ssh_interceptor_media_type(dev->type);
+ ifarray[n].to_protocol.media = ssh_interceptor_media_type(dev->type);
+#else /* !SSH_IPSEC_IP_ONLY_INTERCEPTOR */
+ ifarray[n].to_adapter.media = SSH_INTERCEPTOR_MEDIA_PLAIN;
+ ifarray[n].to_protocol.media = SSH_INTERCEPTOR_MEDIA_PLAIN;
+#endif /* !SSH_IPSEC_IP_ONLY_INTERCEPTOR */
+
+ strncpy(ifarray[n].name, dev->name, 15);
+
+ /* Set interface type and link status. */
+ if (dev->flags & IFF_POINTOPOINT)
+ ifarray[n].flags |= SSH_INTERFACE_FLAG_POINTOPOINT;
+ if (dev->flags & IFF_BROADCAST)
+ ifarray[n].flags |= SSH_INTERFACE_FLAG_BROADCAST;
+ if (!netif_carrier_ok(dev))
+ ifarray[n].flags |= SSH_INTERFACE_FLAG_LINK_DOWN;
+
+ ifarray[n].num_addrs = count;
+ ifarray[n].addrs = NULL;
+
+ /* Add addresses to interface entry. */
+ if (count > 0)
+ {
+ ifarray[n].addrs = ssh_malloc(sizeof(*ifarray[n].addrs) * count);
+
+ if (ifarray[n].addrs == NULL)
+ {
+ /* Release INET/INET6 devices */
+ if (inet_dev)
+ in_dev_put(inet_dev);
+#ifdef SSH_LINUX_INTERCEPTOR_IPV6
+ if (inet6_dev)
+ in6_dev_put(inet6_dev);
+#endif /* SSH_LINUX_INTERCEPTOR_IPV6 */
+ read_unlock(&interceptor->if_table_lock);
+ goto out;
+ }
+ count = 0;
+ if (inet_dev)
+ {
+ /* Put the IPv4 addresses */
+ for (addr = inet_dev->ifa_list;
+ addr != NULL;
+ addr = addr->ifa_next)
+ {
+ ifarray[n].addrs[count].protocol = SSH_PROTOCOL_IP4;
+ SSH_IP4_DECODE(&ifarray[n].addrs[count].addr.ip.ip,
+ &addr->ifa_local);
+ SSH_IP4_DECODE(&ifarray[n].addrs[count].addr.ip.mask,
+ &addr->ifa_mask);
+
+#if 0
+
+
+
+ if (dev->flags & IFF_POINTOPOINT)
+ SSH_IP4_DECODE(&ifarray[n].addrs[count].
+ addr.ip.broadcast,
+ &addr->ifa_address);
+ else
+#endif /* 0 */
+ if (dev->flags & IFF_BROADCAST)
+ SSH_IP4_DECODE(&ifarray[n].addrs[count].
+ addr.ip.broadcast,
+ &addr->ifa_broadcast);
+ else
+ SSH_IP_UNDEFINE(&ifarray[n].addrs[count].
+ addr.ip.broadcast);
+ count++;
+ }
+ }
+
+#ifdef SSH_LINUX_INTERCEPTOR_IPV6
+ if (inet6_dev)
+ {
+ /* Put the IPv6 addresses */
+ SSH_INET6_IFADDR_LIST_FOR_EACH(addr6,
+ next_addr6,
+ inet6_dev->addr_list)
+ {
+ ifarray[n].addrs[count].protocol = SSH_PROTOCOL_IP6;
+
+ SSH_IP6_DECODE(&ifarray[n].addrs[count].addr.ip.ip,
+ &addr6->addr);
+
+ /* Generate mask from prefix length and IPv6 addr */
+ SSH_IP6_DECODE(&ifarray[n].addrs[count].addr.ip.mask,
+ "\xff\xff\xff\xff\xff\xff\xff\xff"
+ "\xff\xff\xff\xff\xff\xff\xff\xff");
+ ssh_ipaddr_set_bits(&ifarray[n].addrs[count].
+ addr.ip.mask,
+ &ifarray[n].addrs[count].
+ addr.ip.mask,
+ addr6->prefix_len, 0);
+
+ /* Set the broadcast address to the IPv6
+ undefined address */
+ SSH_IP6_DECODE(&ifarray[n].addrs[count].
+ addr.ip.broadcast,
+ "\x00\x00\x00\x00\x00\x00\x00\x00"
+ "\x00\x00\x00\x00\x00\x00\x00\x00");
+
+ /* Copy the ifnum in case of ipv6 to scope_id, since
+ in linux scope_id == ifnum. */
+ ifarray[n].addrs[count].addr.ip.ip.
+ scope_id.scope_id_union.ui32 = ifarray[n].ifnum;
+ count++;
+ }
+ }
+#endif /* SSH_LINUX_INTERCEPTOR_IPV6 */
+ }
+#ifndef SSH_IPSEC_IP_ONLY_INTERCEPTOR
+ /* Grab the MAC address */
+ ifarray[n].media_addr_len = dev->addr_len;
+ SSH_ASSERT(dev->addr_len <= sizeof(ifarray[n].media_addr));
+ memcpy(&ifarray[n].media_addr[0], dev->dev_addr, dev->addr_len);
+#else /* !SSH_IPSEC_IP_ONLY_INTERCEPTOR */
+ ifarray[n].media_addr[0] = 0;
+ ifarray[n].media_addr_len = 0;
+#endif /* !SSH_IPSEC_IP_ONLY_INTERCEPTOR */
+
+ /* Release INET/INET6 devices */
+ if (inet_dev)
+ in_dev_put(inet_dev);
+ inet_dev = NULL;
+#ifdef SSH_LINUX_INTERCEPTOR_IPV6
+ if (inet6_dev)
+ in6_dev_put(inet6_dev);
+ inet6_dev = NULL;
+#endif /* SSH_LINUX_INTERCEPTOR_IPV6 */
+
+ ssh_kernel_mutex_lock(interceptor->interceptor_lock);
+ for (i = 0; i < SSH_LINUX_MAX_VIRTUAL_ADAPTERS; i++)
+ {
+ SshVirtualAdapter adapter = interceptor->virtual_adapters[i];
+ if (adapter && adapter->dev->ifindex == ifarray[n].ifnum)
+ {
+ ifarray[n].flags |= SSH_INTERFACE_FLAG_VIP;
+ break;
+ }
+ }
+ ssh_kernel_mutex_unlock(interceptor->interceptor_lock);
+
+ /* Done with the interface entry,
+ increase ifarray index and continue with next iface. */
+ n++;
+
+ } /* for (iface entry chain iteration) */
+ } /* for (hashtable iteration) */
+
+ /* Release if_table lock. */
+ read_unlock(&interceptor->if_table_lock);
+
+ SSH_ASSERT(n <= num);
+
+ /* 'interceptor_lock' protects 'num_interface_callbacks' and
+ 'interfaces_callback'. */
+ ssh_kernel_mutex_lock(interceptor->interceptor_lock);
+ interceptor->num_interface_callbacks++;
+ interfaces_callback = interceptor->interfaces_callback;
+ ssh_kernel_mutex_unlock(interceptor->interceptor_lock);
+
+ /* Call the interface callback. */
+ (interfaces_callback)(n, ifarray, interceptor->callback_context);
+
+ ssh_kernel_mutex_lock(interceptor->interceptor_lock);
+ interceptor->num_interface_callbacks--;
+ ssh_kernel_mutex_unlock(interceptor->interceptor_lock);
+
+out:
+ /* Free the array. */
+ for (i = 0; i < n; i++)
+ {
+ if (ifarray[i].addrs != NULL)
+ ssh_free(ifarray[i].addrs);
+ }
+ ssh_free(ifarray);
+
+ return;
+}
+
+/* Caller must hold 'if_table_lock' for writing */
+static SshInterceptorInternalInterface
+ssh_interceptor_alloc_iface(SshInterceptor interceptor)
+{
+ SshInterceptorInternalInterface iface, new_table;
+ SshUInt32 i, n, new_table_size, hashvalue;
+
+ iface = NULL;
+
+ relookup:
+ /* Find empty slot in the if_table */
+ for (i = 0; i < interceptor->if_table_size; i++)
+ {
+ iface = &interceptor->if_table[i];
+ if (iface->generation == 0)
+ {
+#ifdef DEBUG_LIGHT
+ iface->dev = NULL;
+ iface->ifindex = SSH_INTERCEPTOR_INVALID_IFNUM;
+ iface->next = NULL;
+#endif /* DEBUG_LIGHT */
+ iface->context = NULL;
+ return iface;
+ }
+ }
+
+ /* No free slots, reallocate if_table */
+ if (interceptor->if_table_size >= SSH_LINUX_IFACE_TABLE_SIZE)
+ return NULL; /* Maximum table size reached. */
+
+ new_table_size = interceptor->if_table_size + 10;
+ if (new_table_size > SSH_LINUX_IFACE_TABLE_SIZE)
+ new_table_size = SSH_LINUX_IFACE_TABLE_SIZE;
+
+ new_table = ssh_malloc(sizeof(*new_table) * new_table_size);
+ if (new_table == NULL)
+ return NULL;
+
+ /* Copy existing entries from if_hash */
+ n = 0;
+ for (i = 0; i < SSH_LINUX_IFACE_HASH_SIZE; i++)
+ {
+ for (iface = interceptor->if_hash[i]; iface; iface = iface->next)
+ {
+ new_table[n].next = NULL;
+ new_table[n].ifindex = iface->ifindex;
+ new_table[n].dev = iface->dev;
+ new_table[n].generation = iface->generation;
+ n++;
+ }
+ }
+
+ /* Initialize the rest of the new interface table */
+ for (; n < new_table_size; n++)
+ {
+ new_table[n].generation = 0;
+#ifdef DEBUG_LIGHT
+ new_table[n].dev = NULL;
+ new_table[n].ifindex = SSH_INTERCEPTOR_INVALID_IFNUM;
+ new_table[n].next = NULL;
+#endif /* DEBUG_LIGHT */
+ new_table[n].context = NULL;
+ }
+
+ /* Rebuild hashtable */
+ memset(interceptor->if_hash, 0, sizeof(interceptor->if_hash));
+ for (i = 0; i < new_table_size; i++)
+ {
+ if (new_table[i].generation == 0)
+ continue;
+
+ hashvalue = new_table[i].ifindex % SSH_LINUX_IFACE_HASH_SIZE;
+ new_table[i].next = interceptor->if_hash[hashvalue];
+ interceptor->if_hash[hashvalue] = &new_table[i];
+ }
+
+ /* Free old if_table */
+ ssh_free(interceptor->if_table);
+ wmb();
+ interceptor->if_table = new_table;
+ interceptor->if_table_size = new_table_size;
+
+ goto relookup;
+}
+
+/* The interceptor_update_interfaces() function traverses the kernels
+ list of interfaces, grabs a refcnt for each one, and updates the
+ interceptors 'ifnum->net_device' cache (optimizing away the need to
+ grab a lock, traverse dev_base linked list, unlock, for each
+ packet).
+
+ This function grabs 'if_table_lock' (for writing) and dev_base lock. */
+static void
+ssh_interceptor_update_interfaces(SshInterceptor interceptor)
+{
+ SshInterceptorInternalInterface iface, iface_prev, iface_next;
+ struct net_device *dev;
+ SshUInt32 i, hashvalue, ifindex;
+
+ /* WARNING: TWO LOCKS HELD AT THE SAME TIME. BE CAREFUL!
+ dev_base_lock MUST be held to ensure integrity during traversal
+ of list of interfaces in kernel. */
+ SSH_LOCK_LINUX_DEV_LIST();
+
+ /* Grab 'if_table_lock' for modifying the interface table. */
+ write_lock(&interceptor->if_table_lock);
+
+ /* Increment 'if_generation' */
+ interceptor->if_generation++;
+ if (interceptor->if_generation == 0)
+ interceptor->if_generation++; /* Handle wrapping */
+
+ /* Traverse net_device list, add new interfaces to hashtable,
+ and mark existing entries up-to-date. */
+ for (dev = SSH_FIRST_NET_DEVICE();
+ dev != NULL;
+ dev = SSH_NEXT_NET_DEVICE(dev))
+ {
+ ifindex = (SshUInt32) dev->ifindex;
+
+ /* Ignore the loopback device. */
+ if (dev->flags & IFF_LOOPBACK)
+ continue;
+
+ /* Ignore interfaces that collide with SSH_INTERCEPTOR_INVALID_IFNUM */
+ if (ifindex == SSH_INTERCEPTOR_INVALID_IFNUM)
+ {
+ SSH_DEBUG(2, ("Interface index collides with "
+ "SSH_INTERCEPTOR_INVALID_IFNUM, "
+ "ignoring interface %lu[%s]",
+ (unsigned long) ifindex,
+ (dev->name ? dev->name : "<none>")));
+ continue;
+ }
+
+ /* Assert that 'dev->ifindex' is otherwise valid. */
+ SSH_LINUX_ASSERT_VALID_IFNUM(ifindex);
+
+ /* Lookup interface from the hashtable. */
+ for (iface =
+ interceptor->if_hash[ifindex % SSH_LINUX_IFACE_HASH_SIZE];
+ iface != NULL && iface->ifindex != ifindex;
+ iface = iface->next)
+ ;
+
+ /* Interface found */
+ if (iface)
+ {
+ if (iface->dev == dev)
+ {
+ SSH_DEBUG(SSH_D_NICETOKNOW,
+ ("Old interface %lu[%s]",
+ (unsigned long) ifindex,
+ (dev->name ? dev->name : "<none>")));
+
+ /* Mark up-to-date. */
+ iface->generation = interceptor->if_generation;
+ }
+
+ /* Interface index matches, but net_device has changed. */
+ else
+ {
+ SSH_DEBUG(SSH_D_NICETOKNOW,
+ ("Changed interface %lu[%s] (from %lu[%s])",
+ (unsigned long) ifindex,
+ (dev->name ? dev->name : "<none>"),
+ (unsigned long) iface->ifindex,
+ (iface->dev->name ? iface->dev->name : "<none>")));
+
+ /* Release old net_device. */
+ SSH_ASSERT(iface->dev != NULL);
+ dev_put(iface->dev);
+ /* Hold new net_device. */
+ dev_hold(dev);
+ wmb(); /* Make sure assignments are not reordered. */
+ iface->dev = dev;
+ iface->ifindex = ifindex;
+ iface->context = NULL;
+ /* Mark up-to-date. */
+ iface->generation = interceptor->if_generation;
+ }
+ }
+
+ /* Interface not found */
+ else
+ {
+ SSH_DEBUG(SSH_D_NICETOKNOW,
+ ("New interface %lu[%s]",
+ (unsigned long) ifindex,
+ (dev->name ? dev->name : "<none>")));
+
+ /* Allocate new interface entry */
+ iface = ssh_interceptor_alloc_iface(interceptor);
+ if (iface)
+ {
+ /* Hold new net_device. */
+ dev_hold(dev);
+ /* Fill interface entry. */
+ iface->ifindex = ifindex;
+ iface->dev = dev;
+ iface->context = NULL;
+ /* Mark up-to-date */
+ iface->generation = interceptor->if_generation;
+ /* Add entry to hashtable. */
+ hashvalue = iface->ifindex % SSH_LINUX_IFACE_HASH_SIZE;
+ iface->next = interceptor->if_hash[hashvalue];
+ wmb();
+ interceptor->if_hash[hashvalue] = iface;
+ }
+ else
+ {
+ SSH_DEBUG(SSH_D_FAIL,
+ ("Could not allocate memory for new interface %lu[%s]",
+ (unsigned long) ifindex,
+ (dev->name ? dev->name : "<none>")));
+ }
+ }
+ }
+
+ /* Remove old interfaces from the table */
+ for (i = 0; i < SSH_LINUX_IFACE_HASH_SIZE; i++)
+ {
+ iface_prev = NULL;
+ for (iface = interceptor->if_hash[i];
+ iface != NULL;
+ iface = iface_next)
+ {
+ if (iface->generation != 0 &&
+ iface->generation != interceptor->if_generation)
+ {
+ SSH_DEBUG(SSH_D_NICETOKNOW,
+ ("Disappeared interface %lu[%s]",
+ (unsigned long) iface->ifindex,
+ (iface->dev->name ? iface->dev->name : "<none>")));
+
+ /* Release old netdevice */
+ SSH_ASSERT(iface->dev != NULL);
+ dev_put(iface->dev);
+
+#ifdef DEBUG_LIGHT
+ wmb();
+ iface->dev = NULL;
+ iface->ifindex = SSH_INTERCEPTOR_INVALID_IFNUM;
+#endif /* DEBUG_LIGHT */
+
+ /* Mark entry freed. */
+ iface->generation = 0;
+
+ /* Remove entry from hashtable. */
+ if (iface_prev)
+ iface_prev->next = iface->next;
+ else
+ interceptor->if_hash[i] = iface->next;
+ iface_next = iface->next;
+ iface->next = NULL;
+ }
+ else
+ {
+ iface_prev = iface;
+ iface_next = iface->next;
+ }
+ }
+ }
+ /* Unlock if_table_lock */
+ write_unlock(&interceptor->if_table_lock);
+
+ /* Release dev_base_lock. */
+ SSH_UNLOCK_LINUX_DEV_LIST();
+
+ /* Notify changes to engine */
+ if (interceptor->engine != NULL && interceptor->engine_open == TRUE)
+ {
+ local_bh_disable();
+ ssh_interceptor_send_interfaces(interceptor);
+ local_bh_enable();
+ }
+
+ return;
+}
+
+
+/* Callback for interface and address notifier. */
+void
+ssh_interceptor_receive_ifaces(SshInterceptor interceptor)
+{
+ local_bh_disable();
+ ssh_interceptor_update_interfaces(interceptor);
+ local_bh_enable();
+
+ return;
+}
+
+
+/* Release all refcounts and free the 'ifnum->net_device' map cache. */
+void
+ssh_interceptor_clear_ifaces(SshInterceptor interceptor)
+{
+ int i;
+ SshInterceptorInternalInterface iface;
+
+ /* At this point. All hooks must have completed running! */
+
+ SSH_LOCK_LINUX_DEV_LIST();
+ write_lock(&interceptor->if_table_lock);
+
+ /* Release net_devices and free if_table. */
+ if (interceptor->if_table != NULL)
+ {
+ for (i = 0; i < interceptor->if_table_size; i++)
+ {
+ iface = &interceptor->if_table[i];
+ if (iface->generation != 0)
+ {
+ SSH_ASSERT(iface->dev != NULL);
+ dev_put(iface->dev);
+#ifdef DEBUG_LIGHT
+ wmb();
+ iface->dev = NULL;
+#endif /* DEBUG_LIGHT */
+ iface->generation = 0;
+ }
+ }
+
+ ssh_free(interceptor->if_table);
+ interceptor->if_table = NULL;
+ }
+
+ /* Clear interface hashtable. */
+ memset(interceptor->if_hash, 0, sizeof(interceptor->if_hash));
+
+ write_unlock(&interceptor->if_table_lock);
+ SSH_UNLOCK_LINUX_DEV_LIST();
+}
+
+
+/*************************** Module init / uninit **************************/
+
+Boolean ssh_interceptor_iface_init(SshInterceptor interceptor)
+{
+ /* This will register notifier that notifies about bringing the
+ interface up and down. */
+ interceptor->notifier_netdev.notifier_call =
+ ssh_interceptor_notifier_callback;
+ interceptor->notifier_netdev.priority = 1;
+ interceptor->notifier_netdev.next = NULL;
+ register_netdevice_notifier(&interceptor->notifier_netdev);
+
+ /* This will register notifier that notifies when address of the
+ interface changes without bringing the interface down. */
+ interceptor->notifier_inetaddr.notifier_call =
+ ssh_interceptor_notifier_callback;
+ interceptor->notifier_inetaddr.priority = 1;
+ interceptor->notifier_inetaddr.next = NULL;
+ register_inetaddr_notifier(&interceptor->notifier_inetaddr);
+
+#ifdef SSH_LINUX_INTERCEPTOR_IPV6
+ interceptor->notifier_inet6addr.notifier_call =
+ ssh_interceptor_notifier_callback;
+ interceptor->notifier_inet6addr.priority = 1;
+ interceptor->notifier_inet6addr.next = NULL;
+ register_inet6addr_notifier(&interceptor->notifier_inet6addr);
+#endif /* SSH_LINUX_INTERCEPTOR_IPV6 */
+
+ interceptor->iface_notifiers_installed = TRUE;
+
+ /* Send interface information to engine. This causes the interceptor
+ to grab reference to each net_device. On error cases
+ ssh_interceptor_clear_ifaces() or ssh_interceptor_iface_uninit()
+ must be called to release the references. */
+ ssh_interceptor_receive_ifaces(interceptor);
+
+ return TRUE;
+}
+
+void ssh_interceptor_iface_uninit(SshInterceptor interceptor)
+{
+ if (interceptor->iface_notifiers_installed)
+ {
+ local_bh_enable();
+
+ /* Unregister notifier callback */
+ unregister_netdevice_notifier(&interceptor->notifier_netdev);
+ unregister_inetaddr_notifier(&interceptor->notifier_inetaddr);
+#ifdef SSH_LINUX_INTERCEPTOR_IPV6
+ unregister_inet6addr_notifier(&interceptor->notifier_inet6addr);
+#endif /* SSH_LINUX_INTERCEPTOR_IPV6 */
+
+ local_bh_disable();
+ }
+
+ /* Clear interface table and release net_device references. */
+ ssh_interceptor_clear_ifaces(interceptor);
+
+ /* Due to lack of proper locking in linux kernel notifier code,
+ the unregister_*_notifier functions might leave the notifier
+ blocks out of sync, resulting in that the kernel may call an
+ unregistered notifier function.
+
+ Sleep for a while to decrease the possibility of the bug causing
+ trouble (crash during module unloading). */
+ mdelay(500);
+
+ interceptor->iface_notifiers_installed = FALSE;
+}
diff --git a/drivers/interceptor/linux_internal.h b/drivers/interceptor/linux_internal.h
new file mode 100644
index 0000000..ebd0c9f
--- /dev/null
+++ b/drivers/interceptor/linux_internal.h
@@ -0,0 +1,819 @@
+/* Netfilter Driver for IPSec VPN Client
+ *
+ * Copyright(c) 2012 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.
+ */
+
+/*
+ * linux_internal.h
+ *
+ * Internal header file for the linux interceptor.
+ *
+ */
+
+#ifndef LINUX_INTERNAL_H
+#define LINUX_INTERNAL_H
+
+#include "sshincludes.h"
+
+/* Parameters used to tune the interceptor. */
+#include "linux_versions.h"
+#include "linux_params.h"
+
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/skbuff.h>
+#include <linux/string.h>
+#include <linux/delay.h>
+#include <linux/poll.h>
+#include <linux/proc_fs.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <net/pkt_sched.h>
+
+#include <linux/interrupt.h>
+#include <linux/inetdevice.h>
+
+#include <net/ip.h>
+#include <net/inet_common.h>
+
+#ifdef SSH_LINUX_INTERCEPTOR_IPV6
+#include <net/ipv6.h>
+#include <net/addrconf.h>
+#endif /* SSH_LINUX_INTERCEPTOR_IPV6 */
+
+#ifndef SSH_IPSEC_IP_ONLY_INTERCEPTOR
+#include <linux/if_arp.h>
+#endif /* SSH_IPSEC_IP_ONLY_INTERCEPTOR */
+
+#include <linux/netfilter.h>
+#include <linux/netfilter_ipv4.h>
+#include <linux/netfilter_ipv6.h>
+#include <linux/netfilter_bridge.h>
+#include <linux/netfilter_arp.h>
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+
+#include <linux/cpumask.h>
+#include <linux/rcupdate.h>
+
+#ifdef LINUX_NEED_IF_ADDR_H
+#include <linux/if_addr.h>
+#endif /* LINUX_NEED_IF_ADDR_H */
+
+#include <net/ip.h>
+#include <net/route.h>
+#include <net/inet_common.h>
+
+#ifdef SSH_LINUX_INTERCEPTOR_IPV6
+#include <net/ipv6.h>
+#include <net/addrconf.h>
+#include <net/ip6_fib.h>
+#include <net/ip6_route.h>
+#include <net/flow.h>
+#endif /* SSH_LINUX_INTERCEPTOR_IPV6 */
+
+#include <linux/threads.h>
+
+#include "engine.h"
+#include "kernel_includes.h"
+#include "kernel_mutex.h"
+#include "interceptor.h"
+#include "sshinet.h"
+#include "sshdebug.h"
+
+#include "linux_packet_internal.h"
+#include "linux_mutex_internal.h"
+#include "linux_virtual_adapter_internal.h"
+
+/****************************** Sanity checks ********************************/
+
+#ifndef MODULE
+#error "VPNClient can only be compiled as a MODULE"
+#endif /* MODULE */
+
+#ifndef CONFIG_NETFILTER
+#error "Kernel is not compiled with CONFIG_NETFILTER"
+#endif /* CONFIG_NETFILTER */
+
+/* Check that SSH_LINUX_FWMARK_EXTENSION_SELECTOR is in range. */
+#ifdef SSH_LINUX_FWMARK_EXTENSION_SELECTOR
+#if (SSH_INTERCEPTOR_NUM_EXTENSION_SELECTORS > 0)
+#if (SSH_LINUX_FWMARK_EXTENSION_SELECTOR >= \
+ SSH_INTERCEPTOR_NUM_EXTENSION_SELECTORS)
+#error "Invalid value specified for SSH_LINUX_FWMARK_EXTENSION_SELECTOR"
+#endif
+#endif /* (SSH_INTERCEPTOR_NUM_EXTENSION_SELECTORS > 0) */
+#endif /* SSH_LINUX_FWMARK_EXTENSION_SELECTOR */
+
+
+/****************************** Internal defines *****************************/
+
+#define SSH_LINUX_INTERCEPTOR_NR_CPUS NR_CPUS
+
+/* Flags for ssh_engine_start */
+#define SSH_LINUX_ENGINE_FLAGS 0
+
+#define SSH_LINUX_INTERCEPTOR_MODULE_DESCRIPTION "VPNClient"
+
+/********************** Kernel version specific wrapper macros ***************/
+
+#ifdef LINUX_HAS_DEV_GET_FLAGS
+#define SSH_LINUX_DEV_GET_FLAGS(dev) dev_get_flags(dev)
+#else /* LINUX_HAS_DEV_GET_FLAGS */
+#define SSH_LINUX_DEV_GET_FLAGS(dev) ((dev)->flags)
+#endif /* LINUX_HAS_DEV_GET_FLAGS */
+
+#ifdef LINUX_NF_HOOK_SKB_IS_POINTER
+typedef struct sk_buff SshHookSkb;
+#define SSH_HOOK_SKB_PTR(_skb) _skb
+#else /* LINUX_NF_HOOK_SKB_IS_POINTER */
+typedef struct sk_buff *SshHookSkb;
+#define SSH_HOOK_SKB_PTR(_skb) *_skb
+#endif /* LINUX_NF_HOOK_SKB_IS_POINTER */
+
+#ifdef LINUX_HAS_SKB_MARK
+#define SSH_SKB_MARK(__skb) ((__skb)->mark)
+#else /* LINUX_HAS_SKB_MARK */
+#define SSH_SKB_MARK(__skb) ((__skb)->nfmark)
+#endif /* LINUX_HAS_SKB_MARK */
+
+#ifdef LINUX_HAS_DST_MTU
+#define SSH_DST_MTU(__dst) (dst_mtu((__dst)))
+#else /* LINUX_HAS_DST_MTU */
+#define SSH_DST_MTU(__dst) (dst_pmtu((__dst)))
+#endif /* LINUX_HAS_DST_MTU */
+
+/* Before 2.6.22 kernels, the net devices were accessed
+ using directly global variables.
+ 2.6.22 -> 2.6.23 introduced new functions accessing
+ the net device list.
+ 2.6.24 -> these new functions started taking new
+ arguments. */
+#ifndef LINUX_HAS_NETDEVICE_ACCESSORS
+/* For 2.4.x -> 2.6.21 kernels */
+#define SSH_FIRST_NET_DEVICE() dev_base
+#define SSH_NEXT_NET_DEVICE(_dev) _dev->next
+
+#else /* LINUX_HAS_NETDEVICE_ACCESSORS */
+#ifndef LINUX_NET_DEVICE_HAS_ARGUMENT
+/* For 2.6.22 -> 2.6.23 kernels */
+#define SSH_FIRST_NET_DEVICE() first_net_device()
+#define SSH_NEXT_NET_DEVICE(_dev) next_net_device(_dev)
+
+#else /* LINUX_NET_DEVICE_HAS_ARGUMENT */
+/* For 2.6.24 -> kernels */
+#define SSH_FIRST_NET_DEVICE() first_net_device(&init_net)
+#define SSH_NEXT_NET_DEVICE(_dev) next_net_device(_dev)
+
+#endif /* LINUX_NET_DEVICE_HAS_ARGUMENT */
+#endif /* LINUX_HAS_NETDEVICE_ACCESSORS */
+
+/* This HAVE_NET_DEVICE_OPS was removed in 3.1.x */
+#ifdef LINUX_HAS_NET_DEVICE_OPS
+#ifndef HAVE_NET_DEVICE_OPS
+#define HAVE_NET_DEVICE_OPS 1
+#endif /* HAVE_NET_DEVICE_OPS */
+#endif /* LINUX_HAS_NET_DEVICE_OPS */
+
+#ifdef LINUX_NET_DEVICE_HAS_ARGUMENT
+#define SSH_DEV_GET_BY_INDEX(_i) dev_get_by_index(&init_net, (_i))
+#else /* LINUX_NET_DEVICE_HAS_ARGUMENT */
+#define SSH_DEV_GET_BY_INDEX(_i) dev_get_by_index((_i))
+#endif /* LINUX_NET_DEVICE_HAS_ARGUMENT */
+
+#ifdef LINUX_HAS_SKB_DATA_ACCESSORS
+/* On new kernel versions the skb->end, skb->tail, skb->network_header,
+ skb->mac_header, and skb->transport_header are either pointers to
+ skb->data (on 32bit platforms) or offsets from skb->data
+ (on 64bit platforms). */
+
+#define SSH_SKB_GET_END(__skb) (skb_end_pointer((__skb)))
+
+#define SSH_SKB_GET_TAIL(__skb) (skb_tail_pointer((__skb)))
+#define SSH_SKB_SET_TAIL(__skb, __ptr) \
+ (skb_set_tail_pointer((__skb), (__ptr) - (__skb)->data))
+#define SSH_SKB_RESET_TAIL(__skb) (skb_reset_tail_pointer((__skb)))
+
+#define SSH_SKB_GET_NETHDR(__skb) (skb_network_header((__skb)))
+#define SSH_SKB_SET_NETHDR(__skb, __ptr) \
+ (skb_set_network_header((__skb), (__ptr) - (__skb)->data))
+#define SSH_SKB_RESET_NETHDR(__skb) (skb_reset_network_header((__skb)))
+
+#define SSH_SKB_GET_MACHDR(__skb) (skb_mac_header((__skb)))
+#define SSH_SKB_SET_MACHDR(__skb, __ptr) \
+ (skb_set_mac_header((__skb), (__ptr) - (__skb)->data))
+#define SSH_SKB_RESET_MACHDR(__skb) (skb_reset_mac_header((__skb)))
+
+#define SSH_SKB_GET_TRHDR(__skb) (skb_transport_header((__skb)))
+#define SSH_SKB_SET_TRHDR(__skb, __ptr) \
+ (skb_set_transport_header((__skb), (__ptr) - (__skb)->data))
+#define SSH_SKB_RESET_TRHDR(__skb) (skb_reset_transport_header((__skb)))
+
+#else /* LINUX_HAS_SKB_DATA_ACCESSORS */
+
+#define SSH_SKB_GET_END(__skb) ((__skb)->end)
+
+#define SSH_SKB_GET_TAIL(__skb) ((__skb)->tail)
+#define SSH_SKB_SET_TAIL(__skb, __ptr) ((__skb)->tail = (__ptr))
+#define SSH_SKB_RESET_TAIL(__skb) ((__skb)->tail = NULL)
+
+#define SSH_SKB_GET_NETHDR(__skb) ((__skb)->nh.raw)
+#define SSH_SKB_SET_NETHDR(__skb, __ptr) ((__skb)->nh.raw = (__ptr))
+#define SSH_SKB_RESET_NETHDR(__skb) ((__skb)->nh.raw = NULL)
+
+#define SSH_SKB_GET_MACHDR(__skb) ((__skb)->mac.raw)
+#define SSH_SKB_SET_MACHDR(__skb, __ptr) ((__skb)->mac.raw = (__ptr))
+#define SSH_SKB_RESET_MACHDR(__skb) ((__skb)->mac.raw = NULL)
+
+#define SSH_SKB_GET_TRHDR(__skb) ((__skb)->h.raw)
+#define SSH_SKB_SET_TRHDR(__skb, __ptr) ((__skb)->h.raw = (__ptr))
+#define SSH_SKB_RESET_TRHDR(__skb) ((__skb)->h.raw = NULL)
+
+#endif /* LINUX_HAS_SKB_DATA_ACCESSORS */
+
+#ifdef LINUX_HAS_SKB_CSUM_OFFSET
+/* On linux-2.6.20 and later skb->csum is split into
+ a union of csum and csum_offset. */
+#define SSH_SKB_CSUM_OFFSET(__skb) ((__skb)->csum_offset)
+#define SSH_SKB_CSUM(__skb) ((__skb)->csum)
+#else /* LINUX_HAS_SKB_CSUM_OFFSET */
+#define SSH_SKB_CSUM_OFFSET(__skb) ((__skb)->csum)
+#define SSH_SKB_CSUM(__skb) ((__skb)->csum)
+#endif /* LINUX_HAS_SKB_CSUM_OFFSET */
+
+#ifdef LINUX_NF_INET_HOOKNUMS
+
+#define SSH_NF_IP_PRE_ROUTING NF_INET_PRE_ROUTING
+#define SSH_NF_IP_LOCAL_IN NF_INET_LOCAL_IN
+#define SSH_NF_IP_FORWARD NF_INET_FORWARD
+#define SSH_NF_IP_LOCAL_OUT NF_INET_LOCAL_OUT
+#define SSH_NF_IP_POST_ROUTING NF_INET_POST_ROUTING
+#define SSH_NF_IP_PRI_FIRST INT_MIN
+
+#define SSH_NF_IP6_PRE_ROUTING NF_INET_PRE_ROUTING
+#define SSH_NF_IP6_LOCAL_IN NF_INET_LOCAL_IN
+#define SSH_NF_IP6_FORWARD NF_INET_FORWARD
+#define SSH_NF_IP6_LOCAL_OUT NF_INET_LOCAL_OUT
+#define SSH_NF_IP6_POST_ROUTING NF_INET_POST_ROUTING
+#define SSH_NF_IP6_PRI_FIRST INT_MIN
+
+#else /* LINUX_UNIFIED_NETFILTER_IP_HOOKNUMS */
+
+#define SSH_NF_IP_PRE_ROUTING NF_IP_PRE_ROUTING
+#define SSH_NF_IP_LOCAL_IN NF_IP_LOCAL_IN
+#define SSH_NF_IP_FORWARD NF_IP_FORWARD
+#define SSH_NF_IP_LOCAL_OUT NF_IP_LOCAL_OUT
+#define SSH_NF_IP_POST_ROUTING NF_IP_POST_ROUTING
+#define SSH_NF_IP_PRI_FIRST NF_IP_PRI_FIRST
+
+#define SSH_NF_IP6_PRE_ROUTING NF_IP6_PRE_ROUTING
+#define SSH_NF_IP6_LOCAL_IN NF_IP6_LOCAL_IN
+#define SSH_NF_IP6_FORWARD NF_IP6_FORWARD
+#define SSH_NF_IP6_LOCAL_OUT NF_IP6_LOCAL_OUT
+#define SSH_NF_IP6_POST_ROUTING NF_IP6_POST_ROUTING
+#define SSH_NF_IP6_PRI_FIRST NF_IP6_PRI_FIRST
+
+#endif /* LINUX_NF_INET_HOOKNUMS */
+
+#ifdef LINUX_HAS_NFPROTO_ARP
+#define SSH_NFPROTO_ARP NFPROTO_ARP
+#else /* LINUX_HAS_NFPROTO_ARP */
+#define SSH_NFPROTO_ARP NF_ARP
+#endif /* LINUX_HAS_NFPROTO_ARP */
+
+/*
+ Since 2.6.31 there is now skb->dst pointer and
+ functions skb_dst() and skb_dst_set() should be used.
+
+ The code is modified to use the functions. For older
+ version corresponding macros are defined.
+ */
+#ifdef LINUX_HAS_SKB_DST_FUNCTIONS
+#define SSH_SKB_DST(__skb) skb_dst((__skb))
+#define SSH_SKB_DST_SET(__skb, __dst) skb_dst_set((__skb), (__dst))
+#else /* LINUX_HAS_SKB_DST_FUNCTIONS */
+#define SSH_SKB_DST(__skb) ((__skb)->dst)
+#define SSH_SKB_DST_SET(__skb, __dst) ((void)((__skb)->dst = (__dst)))
+#endif /* LINUX_HAS_SKB_DST_FUNCTIONS */
+
+#ifdef IP6CB
+#define SSH_LINUX_IP6CB(skbp) IP6CB(skbp)
+#else /* IP6CB */
+#define SSH_LINUX_IP6CB(skbp) ((struct inet6_skb_parm *) ((skbp)->cb))
+#endif /* IP6CB */
+
+/* Stating from linux 2.6.35 the IPv6 address list needs to be iterated
+ using the list_for_each_* macros. */
+#ifdef LINUX_RT_DST_IS_NOT_IN_UNION
+#define SSH_RT_DST(_rt) ((_rt)->dst)
+#else /* LINUX_RT_DST_IS_NOT_IN_UNION */
+#define SSH_RT_DST(_rt) ((_rt)->u.dst)
+#endif /* LINUX_RT_DST_IS_NOT_IN_UNION */
+
+/* Starting from linux 2.6.35 the IPv6 address list needs to be iterated
+ using the list_for_each_* macros. */
+#ifdef LINUX_HAS_INET6_IFADDR_LIST_HEAD
+#define SSH_INET6_IFADDR_LIST_FOR_EACH(item, next, list) \
+ list_for_each_entry_safe((item), (next), &(list), if_list)
+#else /* LINUX_HAS_INET6_IFADDR_LIST_HEAD */
+#define SSH_INET6_IFADDR_LIST_FOR_EACH(item, next, list) \
+ for ((item) = (list), (next) = NULL; \
+ (item) != NULL; \
+ (item) = (item)->if_next)
+#endif /* LINUX_HAS_INET6_IFADDR_LIST_HEAD */
+
+#if defined(LINUX_DST_ALLOC_HAS_MANY_ARGS)
+#define SSH_DST_ALLOC(_dst) dst_alloc((_dst)->ops, NULL, 0, 0, 0)
+#elif defined(LINUX_DST_ALLOC_HAS_REFCOUNT)
+#define SSH_DST_ALLOC(_dst) dst_alloc((_dst)->ops, 0)
+#else /* defined(LINUX_DST_ALLOC_HAS_REFCOUNT) */
+#define SSH_DST_ALLOC(_dst) dst_alloc((_dst)->ops)
+#endif /* defined(LINUX_DST_ALLOC_HAS_REFCOUNT) */
+
+#if defined(LINUX_SSH_RTABLE_FIRST_ELEMENT_NEEDED)
+#if LINUX_VERSION_CODE == KERNEL_VERSION(2,6,38)
+#define SSH_RTABLE_FIRST_MEMBER(_rt) ((_rt)->fl)
+#elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,39)
+#define SSH_RTABLE_FIRST_MEMBER(_rt) ((_rt)->rt_key_dst)
+#endif /* LINUX_VERSION_CODE */
+#endif /* defined(LINUX_SSH_RTABLE_FIRST_ELEMENT_NEEDED) */
+
+/* Linux 2.6.39 removed fl4_dst and fl6_dst defines. We like to use
+ those so redefinig those for our purposes. */
+#ifdef LINUX_FLOWI_NO_FL4_ACCESSORS
+#define fl4_dst u.ip4.daddr
+#define fl4_src u.ip4.saddr
+#define fl4_tos u.ip4.__fl_common.flowic_tos
+#define oif u.ip4.__fl_common.flowic_oif
+#define proto u.ip4.__fl_common.flowic_proto
+#define fl4_scope u.ip4.__fl_common.flowic_scope
+#endif /* LINUX_FLOWI_NO_FL4_ACCESSORS */
+
+#ifdef LINUX_FLOWI_NO_FL6_ACCESSORS
+#define fl6_dst u.ip6.daddr
+#define fl6_src u.ip6.saddr
+#endif /* LINUX_FLOWI_NO_FL6_ACCESSORS */
+
+/****************************** Statistics helper macros *********************/
+
+#ifdef DEBUG_LIGHT
+
+#define SSH_LINUX_STATISTICS(interceptor, block) \
+do \
+ { \
+ if ((interceptor)) \
+ { \
+ spin_lock_bh(&(interceptor)->statistics_lock); \
+ block; \
+ spin_unlock_bh(&(interceptor)->statistics_lock); \
+ } \
+ } \
+while (0)
+
+#else /* DEBUG_LIGHT */
+
+#define SSH_LINUX_STATISTICS(interceptor, block)
+
+#endif /* DEBUG_LIGHT */
+
+/****************************** Interface handling ***************************/
+
+/* Sanity check that the interface index 'ifnum' fits into
+ the SshInterceptorIfnum data type. 'ifnum' may be equal to
+ SSH_INTERCEPTOR_INVALID_IFNUM. */
+#define SSH_LINUX_ASSERT_IFNUM(ifnum) \
+SSH_ASSERT(((SshUInt32) (ifnum)) < ((SshUInt32) SSH_INTERCEPTOR_MAX_IFNUM) \
+|| ((SshUInt32) (ifnum)) == ((SshUInt32) SSH_INTERCEPTOR_INVALID_IFNUM))
+
+/* Sanity check that the interface index 'ifnum' is a valid
+ SshInterceptorIfnum. */
+#define SSH_LINUX_ASSERT_VALID_IFNUM(ifnum) \
+SSH_ASSERT(((SshUInt32) (ifnum)) < ((SshUInt32) SSH_INTERCEPTOR_MAX_IFNUM) \
+&& ((SshUInt32) (ifnum)) != ((SshUInt32) SSH_INTERCEPTOR_INVALID_IFNUM))
+
+/* Interface structure for caching "ifindex->dev" mapping. */
+typedef struct SshInterceptorInternalInterfaceRec
+*SshInterceptorInternalInterface;
+
+struct SshInterceptorInternalInterfaceRec
+{
+ /* Next entry in the hashtable chain */
+ SshInterceptorInternalInterface next;
+ /* Interface index */
+ SshUInt32 ifindex;
+ /* Linux net_device structure */
+ struct net_device *dev;
+
+ /* This field is used to mark existing interfaces,
+ and to remove disappeared interfaces from the hashtable. */
+ SshUInt8 generation;
+
+ /* Pointer to private data. This is currently used only by Octeon. */
+ void *context;
+};
+
+/* Number of hashtable slots in the interface hashtable. */
+#define SSH_LINUX_IFACE_HASH_SIZE 256
+
+/* Maximum number of entries in the interface hashtable.
+ Currently equal to maximum interface number. */
+#define SSH_LINUX_IFACE_TABLE_SIZE SSH_INTERCEPTOR_MAX_IFNUM
+
+/****************************** Proc entries *********************************/
+
+#define SSH_PROC_ROOT "vpnclient"
+#define SSH_PROC_ENGINE "engine"
+#define SSH_PROC_VERSION "version"
+
+/* Ipm receive buffer size. This must be big enough to fit a maximum sized
+ IP packet + internal packet data + ipm message header. There is only
+ one receive buffer. */
+#define SSH_LINUX_IPM_RECV_BUFFER_SIZE 66000
+
+/* Ipm channel message structure. These structures are used for queueing
+ messages from kernel to userspace. The maximum number of allocated messages
+ is limited by SSH_LINUX_MAX_IPM_MESSAGES (in linux_params.h). */
+typedef struct SshInterceptorIpmMsgRec
+SshInterceptorIpmMsgStruct, *SshInterceptorIpmMsg;
+
+struct SshInterceptorIpmMsgRec
+{
+ /* Send queue is doubly linked, freelist uses only `next'. */
+ SshInterceptorIpmMsg next;
+ SshInterceptorIpmMsg prev;
+
+ SshUInt8 reliable : 1; /* message is reliable. */
+ SshUInt8 emergency_mallocated : 1; /* message is allocated from heap */
+
+ /* Offset for partially sent message */
+ size_t offset;
+
+ /* Message length and data. */
+ size_t len;
+ unsigned char *buf;
+};
+
+/* Ipm structure */
+typedef struct SshInterceptorIpmRec
+{
+ /* RW lock for protecting the send message queue and the message freelist. */
+ rwlock_t lock;
+
+ /* Is ipm channel open */
+ atomic_t open;
+
+ /* Message freelist and number of allocated messages. */
+ SshInterceptorIpmMsg msg_freelist;
+ SshUInt32 msg_allocated;
+
+ /* Output message queue */
+ SshInterceptorIpmMsg send_queue;
+ SshInterceptorIpmMsg send_queue_tail;
+
+ /* Number of unreliable messages in the sed queue. */
+ SshUInt32 send_queue_num_unreliable;
+
+} SshInterceptorIpmStruct, *SshInterceptorIpm;
+
+
+/* Structure for ipm channel /proc entry. */
+typedef struct SshInterceptorIpmProcEntryRec
+{
+ /* /proc filesystem inode */
+ struct proc_dir_entry *entry;
+
+ /* RW lock for protecting the proc entry */
+ rwlock_t lock;
+
+ /* Is an userspace application using this entry */
+ Boolean open;
+
+ /* Is another read ongoing? When this is TRUE
+ then `send_msg' is owned by the reader. */
+ Boolean read_active;
+
+ /* Is another write ongoing? When this is TRUE
+ then `recv_buf' is owned by the writer. */
+ Boolean write_active;
+
+ /* Wait queue for blocking mode reads and writes. */
+ wait_queue_head_t wait_queue;
+
+ /* Output message under processing. */
+ SshInterceptorIpmMsg send_msg;
+
+ /* Input message length */
+ size_t recv_len;
+
+ /* Input message buffer */
+ size_t recv_buf_size;
+ unsigned char *recv_buf;
+
+} SshInterceptorIpmProcEntryStruct, *SshInterceptorIpmProcEntry;
+
+
+/* Structure for other /proc entries. */
+typedef struct SshInterceptorProcEntryRec
+{
+ /* /proc filesystem entry */
+ struct proc_dir_entry *entry;
+
+ /* RW lock for protecting the proc entry */
+ rwlock_t lock;
+
+ /* Is an userspace application using this entry */
+ Boolean open;
+
+ /* Is another read or write ongoing? When this is TRUE
+ then `buf' is owned by the reader/writer. */
+ Boolean active;
+
+ /* Number of bytes returned to the userpace application */
+ size_t buf_len;
+
+ /* Preallocated buffer for read and write operations. */
+ char buf[1024];
+
+} SshInterceptorProcEntryStruct, *SshInterceptorProcEntry;
+
+/****************************** Dst entry cache ******************************/
+#define SSH_DST_ENTRY_TBL_SIZE 128
+typedef struct SshDstEntryRec
+{
+ struct dst_entry *dst_entry;
+
+ unsigned long allocation_time;
+ SshUInt32 dst_entry_id;
+
+ struct SshDstEntryRec *next;
+} *SshDstEntry, SshDstEntryStruct;
+
+
+/****************************** Interceptor Object ***************************/
+
+struct SshInterceptorRec
+{
+ /* Function pointers to netfilter infrastructure */
+ struct
+ {
+ int (*ip_rcv_finish) (struct sk_buff *);
+ int (*ip_finish_output) (struct sk_buff *);
+#ifdef SSH_LINUX_INTERCEPTOR_IPV6
+ int (*ip6_rcv_finish) (struct sk_buff *);
+ int (*ip6_output_finish) (struct sk_buff *);
+#endif /* SSH_LINUX_INTERCEPTOR_IPV6 */
+#ifndef SSH_IPSEC_IP_ONLY_INTERCEPTOR
+ int (*arp_process) (struct sk_buff *);
+#endif /* !SSH_IPSEC_IP_ONLY_INTERCEPTOR */
+ } linux_fn;
+
+ SshVirtualAdapter virtual_adapters[SSH_LINUX_MAX_VIRTUAL_ADAPTERS];
+
+ Boolean hooks_installed;
+
+ /* Interface information used in ssh_interceptor_send()
+ (and elsewhere obviously, but the aforementioned
+ is the reason it is here). 'if_hash', 'if_table_size',
+ and 'if_generation' are protected by 'if_table_lock' rwlock. */
+ SshInterceptorInternalInterface if_hash[SSH_LINUX_IFACE_HASH_SIZE];
+
+ SshInterceptorInternalInterface if_table;
+ SshUInt32 if_table_size;
+ SshUInt8 if_generation;
+
+ /* Protected by interceptor_lock */
+ int num_interface_callbacks;
+
+ /* Notifiers, notifies when interfaces change. */
+ Boolean iface_notifiers_installed;
+
+ struct notifier_block notifier_netdev;
+ struct notifier_block notifier_inetaddr;
+#ifdef SSH_LINUX_INTERCEPTOR_IPV6
+ struct notifier_block notifier_inet6addr;
+#endif /* SSH_LINUX_INTERCEPTOR_IPV6 */
+
+ /* Reader Writer lock for interface table manipulation */
+ rwlock_t if_table_lock;
+
+ /* Registered callbacks */
+
+ /* Interface callback. Protected by 'interceptor_lock' */
+ SshInterceptorInterfacesCB interfaces_callback;
+
+ /* Unused and unprotected */
+ SshInterceptorRouteChangeCB route_callback;
+
+ /* Callback for packet. Protected by rcu. */
+ SshInterceptorPacketCB packet_callback;
+
+ /* Context for interface, route and packet callbacks. */
+ void *callback_context;
+
+ /* Engine context */
+ SshEngine engine;
+ Boolean engine_open;
+
+ /* Intercept packets. */
+ Boolean enable_interception;
+
+ /* Name of related engine-instance */
+ char *name;
+
+ /* Ipm channel */
+ SshInterceptorIpmStruct ipm;
+
+ /* /proc filesystem entries */
+ struct proc_dir_entry *proc_dir;
+
+ SshInterceptorIpmProcEntryStruct ipm_proc_entry;
+
+ SshInterceptorProcEntryStruct version_proc_entry;
+
+ /* Main mutex for interceptor use */
+ SshKernelMutex interceptor_lock;
+
+ /* Mutex for memory map manipulation */
+ SshKernelMutex memory_lock;
+
+ /* Mutex for packet handling */
+ SshKernelMutex packet_lock;
+
+ SshKernelMutex dst_entry_cache_lock;
+ Boolean dst_entry_cache_timeout_registered;
+ SshUInt32 dst_entry_id;
+ struct timer_list dst_cache_timer;
+ SshUInt32 dst_entry_cached_items;
+ SshDstEntry dst_entry_table[SSH_DST_ENTRY_TBL_SIZE];
+
+#ifdef DEBUG_LIGHT
+ /* Statistics spin lock */
+ spinlock_t statistics_lock;
+
+ struct {
+ /* Statistics */
+ SshUInt64 num_packets_out;
+ SshUInt64 num_packets_in;
+ SshUInt64 num_bytes_out;
+ SshUInt64 num_bytes_in;
+ SshUInt64 num_passthrough;
+ SshUInt64 num_fastpath_packets_in;
+ SshUInt64 num_fastpath_packets_out;
+ SshUInt64 num_fastpath_bytes_in;
+ SshUInt64 num_fastpath_bytes_out;
+ SshUInt64 num_errors;
+ SshUInt64 num_packets_sent;
+ SshUInt64 num_bytes_sent;
+ SshUInt64 allocated_memory;
+ SshUInt64 allocated_memory_max;
+ SshUInt64 num_allocations;
+ SshUInt64 num_allocations_large;
+ SshUInt64 num_allocations_total;
+ SshUInt64 num_allocated_packets;
+ SshUInt64 num_allocated_packets_total;
+ SshUInt64 num_copied_packets;
+ SshUInt64 num_failed_allocs;
+ SshUInt64 num_light_locks;
+ SshUInt64 num_light_interceptor_locks;
+ SshUInt64 num_heavy_locks;
+ SshUInt64 ipm_send_queue_len;
+ SshUInt64 ipm_send_queue_bytes;
+ } stats;
+#endif /* DEBUG_LIGHT */
+};
+
+typedef struct SshInterceptorRec SshInterceptorStruct;
+
+/****************************** Function prototypes **************************/
+
+/* Call packet_callback */
+#define SSH_LINUX_INTERCEPTOR_PACKET_CALLBACK(interceptor, pkt) \
+ do { \
+ rcu_read_lock(); \
+ (interceptor)->packet_callback((pkt), (interceptor)->callback_context); \
+ rcu_read_unlock(); \
+ } while (0)
+
+/* Proc entries */
+Boolean ssh_interceptor_proc_init(SshInterceptor interceptor);
+void ssh_interceptor_proc_uninit(SshInterceptor interceptor);
+
+/* Ipm channel */
+
+/* init / uninit */
+Boolean ssh_interceptor_ipm_init(SshInterceptor interceptor);
+void ssh_interceptor_ipm_uninit(SshInterceptor interceptor);
+
+/* open / close. These functions handle ipm message queue flushing. */
+void interceptor_ipm_open(SshInterceptor interceptor);
+void interceptor_ipm_close(SshInterceptor interceptor);
+
+/* open / close notifiers. These functions notify engine. */
+void ssh_interceptor_notify_ipm_open(SshInterceptor interceptor);
+void ssh_interceptor_notify_ipm_close(SshInterceptor interceptor);
+
+Boolean ssh_interceptor_send_to_ipm(unsigned char *data, size_t len,
+ Boolean reliable, void *machine_context);
+ssize_t ssh_interceptor_receive_from_ipm(unsigned char *data, size_t len);
+
+void interceptor_ipm_message_free(SshInterceptor interceptor,
+ SshInterceptorIpmMsg msg);
+
+/* Packet access and manipulation. */
+
+/* Header-only allocation.
+ This function will assert that the interface numbers will
+ fit into the data type SshInterceptorIfnum. */
+SshInterceptorInternalPacket
+ssh_interceptor_packet_alloc_header(SshInterceptor interceptor,
+ SshUInt32 flags,
+ SshInterceptorProtocol protocol,
+ SshUInt32 ifnum_in,
+ SshUInt32 ifnum_out,
+ struct sk_buff *skb,
+ Boolean force_copy_skbuff,
+ Boolean free_original_on_copy,
+ Boolean packet_from_system);
+
+
+
+/* Allocates new packet skb with copied data from original
+ + the extra free space reserved for extensions. */
+struct sk_buff *
+ssh_interceptor_packet_skb_dup(SshInterceptor interceptor,
+ struct sk_buff *skb,
+ size_t addbytes_active_ofs,
+ size_t addbytes_active);
+
+/* Align the interceptor packet at the data offset 'offset' to a word
+ boundary. On failure, 'pp' is freed and returns FALSE. */
+Boolean
+ssh_interceptor_packet_align(SshInterceptorPacket packet, size_t offset);
+
+/* Verify that `skbp' has enough headroom to be sent out through `skbp->dev'.
+ On failure this frees `skbp' and returns NULL. */
+struct sk_buff *
+ssh_interceptor_packet_verify_headroom(struct sk_buff *skbp,
+ size_t media_header_len);
+
+void
+ssh_interceptor_packet_return_dst_entry(SshInterceptor interceptor,
+ SshUInt32 dst_entry_id,
+ SshInterceptorPacket pp,
+ Boolean remove_only);
+SshUInt32
+ssh_interceptor_packet_cache_dst_entry(SshInterceptor interceptor,
+ SshInterceptorPacket pp);
+
+Boolean
+ssh_interceptor_dst_entry_cache_init(SshInterceptor interceptor);
+
+void
+ssh_interceptor_dst_entry_cache_flush(SshInterceptor interceptor);
+
+void
+ssh_interceptor_dst_entry_cache_uninit(SshInterceptor interceptor);
+
+/* Packet freelist init / uninit. */
+Boolean ssh_interceptor_packet_freelist_init(SshInterceptor interceptor);
+void ssh_interceptor_packet_freelist_uninit(SshInterceptor interceptor);
+
+int ssh_linux_module_inc_use_count(void);
+void ssh_linux_module_dec_use_count(void);
+
+
+Boolean ssh_interceptor_ip_glue_init(SshInterceptor interceptor);
+Boolean ssh_interceptor_ip_glue_uninit(SshInterceptor interceptor);
+
+int ssh_interceptor_hook_magic_init(void);
+
+struct net_device *
+ssh_interceptor_ifnum_to_netdev(SshInterceptor interceptor, SshUInt32 ifnum);
+struct net_device *
+ssh_interceptor_ifnum_to_netdev_ctx(SshInterceptor interceptor,
+ SshUInt32 ifnum, void **context_return);
+void ssh_interceptor_release_netdev(struct net_device *dev);
+void ssh_interceptor_receive_ifaces(SshInterceptor interceptor);
+void ssh_interceptor_clear_ifaces(SshInterceptor interceptor);
+Boolean ssh_interceptor_iface_init(SshInterceptor interceptor);
+void ssh_interceptor_iface_uninit(SshInterceptor interceptor);
+
+/* skb rerouting */
+Boolean ssh_interceptor_reroute_skb_ipv4(SshInterceptor interceptor,
+ struct sk_buff *skb,
+ SshUInt16 route_selector,
+ SshUInt32 ifnum_in);
+#ifdef SSH_LINUX_INTERCEPTOR_IPV6
+Boolean ssh_interceptor_reroute_skb_ipv6(SshInterceptor interceptor,
+ struct sk_buff *skb,
+ SshUInt16 route_selector,
+ SshUInt32 ifnum_in);
+#endif /* SSH_LINUX_INTERCEPTOR_IPV6 */
+
+#endif /* LINUX_INTERNAL_H */
diff --git a/drivers/interceptor/linux_ip_glue.c b/drivers/interceptor/linux_ip_glue.c
new file mode 100644
index 0000000..7638c08
--- /dev/null
+++ b/drivers/interceptor/linux_ip_glue.c
@@ -0,0 +1,1841 @@
+/* Netfilter Driver for IPSec VPN Client
+ *
+ * Copyright(c) 2012 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.
+ */
+
+/*
+ * linux_ip_glue.c
+ *
+ * Linux interceptor packet interception using Netfilter hooks.
+ *
+ */
+
+#include "linux_internal.h"
+
+extern SshInterceptor ssh_interceptor_context;
+
+/********************* Prototypes for packet handling hooks *****************/
+
+static unsigned int
+ssh_interceptor_packet_in_ipv4(unsigned int hooknum,
+ SshHookSkb *skb,
+ const struct net_device *in,
+ const struct net_device *out,
+ int (*okfn) (struct sk_buff *));
+
+#ifdef SSH_LINUX_INTERCEPTOR_IPV6
+static unsigned int
+ssh_interceptor_packet_in_ipv6(unsigned int hooknum,
+ SshHookSkb *skb,
+ const struct net_device *in,
+ const struct net_device *out,
+ int (*okfn) (struct sk_buff *));
+#endif /* SSH_LINUX_INTERCEPTOR_IPV6 */
+
+#ifndef SSH_IPSEC_IP_ONLY_INTERCEPTOR
+static unsigned int
+ssh_interceptor_packet_in_arp(unsigned int hooknum,
+ SshHookSkb *skb,
+ const struct net_device *in,
+ const struct net_device *out,
+ int (*okfn) (struct sk_buff *));
+#endif /* !SSH_IPSEC_IP_ONLY_INTERCEPTOR */
+
+static unsigned int
+ssh_interceptor_packet_out(int pf,
+ unsigned int hooknum,
+ SshHookSkb *skb,
+ const struct net_device *in,
+ const struct net_device *out,
+ int (*okfn) (struct sk_buff *));
+
+static unsigned int
+ssh_interceptor_packet_out_ipv4(unsigned int hooknum,
+ SshHookSkb *skb,
+ const struct net_device *in,
+ const struct net_device *out,
+ int (*okfn) (struct sk_buff *));
+
+#ifdef SSH_LINUX_INTERCEPTOR_IPV6
+static unsigned int
+ssh_interceptor_packet_out_ipv6(unsigned int hooknum,
+ SshHookSkb *skb,
+ const struct net_device *in,
+ const struct net_device *out,
+ int (*okfn) (struct sk_buff *));
+#endif /* SSH_LINUX_INTERCEPTOR_IPV6 */
+
+
+/********** Definition of netfilter hooks to register **********************/
+
+struct SshLinuxHooksRec
+{
+ const char *name; /* Name of hook */
+ Boolean is_registered; /* Has this hook been registered? */
+ Boolean is_mandatory; /* If the registration fails,
+ abort initialization? */
+ int pf; /* Protocol family */
+ int hooknum; /* Hook id */
+ int priority; /* Netfilter priority of hook */
+
+ /* Actual hook function */
+ unsigned int (*hookfn)(unsigned int hooknum,
+ SshHookSkb *skb,
+ const struct net_device *in,
+ const struct net_device *out,
+ int (*okfn)(struct sk_buff *));
+
+ struct nf_hook_ops *ops; /* Pointer to storage for nf_hook_ops
+ to store the netfilter hook configuration
+ and state */
+};
+
+struct nf_hook_ops ssh_nf_in4, ssh_nf_out4;
+
+#ifndef SSH_IPSEC_IP_ONLY_INTERCEPTOR
+struct nf_hook_ops ssh_nf_in_arp;
+#endif /* !SSH_IPSEC_IP_ONLY_INTERCEPTOR */
+
+#ifdef SSH_LINUX_INTERCEPTOR_IPV6
+struct nf_hook_ops ssh_nf_in6, ssh_nf_out6;
+#endif /* SSH_LINUX_INTERCEPTOR_IPV6 */
+
+static struct SshLinuxHooksRec ssh_nf_hooks[] =
+{
+ { "ipv4 in",
+ FALSE, TRUE, PF_INET, SSH_NF_IP_PRE_ROUTING, SSH_NF_IP_PRI_FIRST,
+ ssh_interceptor_packet_in_ipv4, &ssh_nf_in4 },
+ { "ipv4 out",
+ FALSE, TRUE, PF_INET, SSH_NF_IP_POST_ROUTING, SSH_NF_IP_PRI_FIRST,
+ ssh_interceptor_packet_out_ipv4, &ssh_nf_out4 },
+
+#ifndef SSH_IPSEC_IP_ONLY_INTERCEPTOR
+ { "arp in",
+ FALSE, TRUE, SSH_NFPROTO_ARP, NF_ARP_IN, 1,
+ ssh_interceptor_packet_in_arp, &ssh_nf_in_arp },
+#endif /* !SSH_IPSEC_IP_ONLY_INTERCEPTOR */
+
+#ifdef SSH_LINUX_INTERCEPTOR_IPV6
+ { "ipv6 in",
+ FALSE, TRUE, PF_INET6, SSH_NF_IP6_PRE_ROUTING, SSH_NF_IP6_PRI_FIRST,
+ ssh_interceptor_packet_in_ipv6, &ssh_nf_in6 },
+ { "ipv6 out",
+ FALSE, TRUE, PF_INET6, SSH_NF_IP6_POST_ROUTING, SSH_NF_IP6_PRI_FIRST,
+ ssh_interceptor_packet_out_ipv6, &ssh_nf_out6 },
+#endif /* SSH_LINUX_INTERCEPTOR_IPV6 */
+
+ { NULL,
+ 0, 0, 0, 0, 0,
+ NULL_FNPTR, NULL },
+};
+
+
+/******************************** Module parameters *************************/
+
+/* Module parameters. Default values. These can be overrided at the
+ loading of the module from the command line. These set the priority
+ for netfilter hooks. */
+
+static int in_priority = SSH_NF_IP_PRI_FIRST;
+static int out_priority = SSH_NF_IP_PRI_FIRST;
+#ifdef SSH_LINUX_INTERCEPTOR_IPV6
+static int in6_priority = SSH_NF_IP6_PRI_FIRST;
+static int out6_priority = SSH_NF_IP6_PRI_FIRST;
+#endif /* SSH_LINUX_INTERCEPTOR_IPV6 */
+
+MODULE_PARM_DESC(in_priority, "Netfilter hook priority at IPv4 PREROUTING");
+MODULE_PARM_DESC(out_priority, "Netfilter hook priority at IPv4 POSTROUTING");
+#ifdef SSH_LINUX_INTERCEPTOR_IPV6
+MODULE_PARM_DESC(in6_priority, "Netfilter hook priority at IPv6 PREROUTING");
+MODULE_PARM_DESC(out6_priority, "Netfilter hook priority at IPv6 POSTROUTING");
+#endif /* SSH_LINUX_INTERCEPTOR_IPV6 */
+
+module_param(in_priority, int, 0444);
+module_param(out_priority, int, 0444);
+#ifdef SSH_LINUX_INTERCEPTOR_IPV6
+module_param(in6_priority, int, 0444);
+module_param(out6_priority, int, 0444);
+#endif /* SSH_LINUX_INTERCEPTOR_IPV6 */
+
+
+/************* Utility functions ********************************************/
+
+/* Map a SshInterceptorProtocol to a skbuff protocol id */
+static unsigned short
+ssh_proto_to_skb_proto(SshInterceptorProtocol protocol)
+{
+ /* If support for other than IPv6, IPv4 and ARP
+ inside the engine on Linux are to be supported, their
+ protocol types must be added here. */
+ switch (protocol)
+ {
+#ifdef SSH_LINUX_INTERCEPTOR_IPV6
+ case SSH_PROTOCOL_IP6:
+ return __constant_htons(ETH_P_IPV6);
+#endif /* SSH_LINUX_INTERCEPTOR_IPV6 */
+
+ case SSH_PROTOCOL_ARP:
+ return __constant_htons(ETH_P_ARP);
+
+ case SSH_PROTOCOL_IP4:
+ return __constant_htons(ETH_P_IP);
+
+ default:
+ SSH_DEBUG(SSH_D_ERROR, ("Unknown protocol %d", protocol));
+ return 0;
+ }
+}
+
+#ifndef SSH_IPSEC_IP_ONLY_INTERCEPTOR
+
+/* Map ethernet type to a skbuff protocol id */
+static unsigned short
+ssh_ethertype_to_skb_proto(SshInterceptorProtocol protocol,
+ size_t media_header_len,
+ unsigned char *media_header)
+{
+ SshUInt16 ethertype;
+
+ if (protocol != SSH_PROTOCOL_ETHERNET)
+ return ssh_proto_to_skb_proto(protocol);
+
+ SSH_ASSERT(media_header_len >= SSH_ETHERH_HDRLEN);
+ ethertype = SSH_GET_16BIT(media_header + SSH_ETHERH_OFS_TYPE);
+
+ /* If support for other than IPv6, IPv4 and ARP
+ inside the engine on Linux are to be supported, their
+ ethernet types must be added here. */
+ switch (ethertype)
+ {
+ case SSH_ETHERTYPE_IPv6:
+ return __constant_htons(ETH_P_IPV6);
+
+ case SSH_ETHERTYPE_ARP:
+ return __constant_htons(ETH_P_ARP);
+
+ case SSH_ETHERTYPE_IP:
+ return __constant_htons(ETH_P_IP);
+
+ default:
+ SSH_DEBUG(SSH_D_ERROR, ("Unknown ethertype 0x%x", ethertype));
+ return 0;
+ }
+}
+
+/* Return the pointer to start of ethernet header */
+static struct ethhdr *ssh_get_eth_hdr(const struct sk_buff *skb)
+{
+#ifdef LINUX_HAS_ETH_HDR
+ return eth_hdr(skb);
+#else /* LINUX_HAS_ETH_HDR */
+ return skb->mac.ethernet;
+#endif /* LINUX_HAS_ETH_HDR */
+}
+
+#endif /* !SSH_IPSEC_IP_ONLY_INTERCEPTOR */
+
+
+/**************** Packet reception and sending *****************************/
+
+/**************** Inbound packet interception ******************************/
+
+
+/* Common code for ssh_interceptor_packet_in_finish_ipv4()
+ and ssh_interceptor_packet_in_finish_ipv6().
+
+ If SSH_LINUX_NF_PRE_ROUTING_BEFORE_ENGINE is set, then
+ this function is called as the okfn() from the netfilter
+ infrastructure after inbound netfilter hook iteration.
+ Otherwise this function is called directly from the inbound
+ netfilter hookfn().
+*/
+
+static inline int
+ssh_interceptor_packet_in_finish(struct sk_buff *skbp,
+ SshInterceptorProtocol protocol)
+{
+ SshInterceptorInternalPacket packet;
+ SshInterceptor interceptor;
+ int ifnum_in;
+
+ interceptor = ssh_interceptor_context;
+
+ SSH_ASSERT(skbp->dev != NULL);
+ ifnum_in = skbp->dev->ifindex;
+
+ SSH_DEBUG(SSH_D_HIGHSTART,
+ ("incoming packet 0x%p, len %d proto 0x%x [%s] iface %d [%s]",
+ skbp, skbp->len, ntohs(skbp->protocol),
+ (protocol == SSH_PROTOCOL_IP4 ? "ipv4" :
+ (protocol == SSH_PROTOCOL_IP6 ? "ipv6" :
+ (protocol == SSH_PROTOCOL_ETHERNET ? "ethernet" : "unknown"))),
+ ifnum_in, skbp->dev->name));
+
+#ifndef SSH_IPSEC_IP_ONLY_INTERCEPTOR
+ if (unlikely(protocol == SSH_PROTOCOL_ETHERNET))
+ {
+ /* Unwrap ethernet header. This is needed by the engine currently
+ due to some sillyness in the ARP handling. */
+ if (SSH_SKB_GET_MACHDR(skbp))
+ {
+ size_t media_header_len = skbp->data - SSH_SKB_GET_MACHDR(skbp);
+ if (media_header_len)
+ skb_push(skbp, media_header_len);
+ }
+ }
+#endif /* !SSH_IPSEC_IP_ONLY_INTERCEPTOR */
+
+ /* Encapsulate the skb into a new packet. Note that ip_rcv()
+ performs IP header checksum computation, so we do not
+ need to. */
+ packet = ssh_interceptor_packet_alloc_header(interceptor,
+ SSH_PACKET_FROMADAPTER
+ |SSH_PACKET_IP4HDRCKSUMOK,
+ protocol,
+ ifnum_in,
+ SSH_INTERCEPTOR_INVALID_IFNUM,
+ skbp,
+ FALSE, TRUE, TRUE);
+
+ if (unlikely(packet == NULL))
+ {
+ SSH_DEBUG(SSH_D_FAIL, ("encapsulation failed, packet dropped"));
+ /* Free sk_buff and return error */
+ dev_kfree_skb_any(skbp);
+ SSH_LINUX_STATISTICS(interceptor, { interceptor->stats.num_errors++; });
+ return -EPERM;
+ }
+
+#ifdef DEBUG_LIGHT
+ packet->skb->dev = NULL;
+#endif /* DEBUG_LIGHT */
+
+ SSH_DEBUG_HEXDUMP(SSH_D_PCKDMP,
+ ("incoming packet, len=%d flags=0x%08lx%s",
+ packet->skb->len,
+ (unsigned long) packet->packet.flags,
+ ((packet->packet.flags & SSH_PACKET_HWCKSUM) ?
+ " [hwcsum]" : "")),
+ packet->skb->data, packet->skb->len);
+
+ SSH_LINUX_STATISTICS(interceptor,
+ {
+ interceptor->stats.num_fastpath_bytes_in += (SshUInt64) packet->skb->len;
+ interceptor->stats.num_fastpath_packets_in++;
+ });
+
+ /* Pass the packet to then engine. Which eventually will call
+ ssh_interceptor_send. */
+ SSH_LINUX_INTERCEPTOR_PACKET_CALLBACK(interceptor,
+ (SshInterceptorPacket) packet);
+
+ /* Return ok */
+ return 0;
+}
+
+
+#ifdef SSH_LINUX_NF_PRE_ROUTING_BEFORE_ENGINE
+
+static inline int
+ssh_interceptor_packet_in_finish_ipv4(struct sk_buff *skbp)
+{
+ return ssh_interceptor_packet_in_finish(skbp, SSH_PROTOCOL_IP4);
+}
+
+#ifdef SSH_LINUX_INTERCEPTOR_IPV6
+static inline int
+ssh_interceptor_packet_in_finish_ipv6(struct sk_buff *skbp)
+{
+ return ssh_interceptor_packet_in_finish(skbp, SSH_PROTOCOL_IP6);
+}
+#endif /* SSH_LINUX_INTERCEPTOR_IPV6 */
+
+#endif /* SSH_LINUX_NF_PRE_ROUTING_BEFORE_ENGINE */
+
+
+/* ssh_interceptor_packet_in() is the common code for
+ inbound netfilter hooks ssh_interceptor_packet_in_ipv4(),
+ ssh_interceptor_packet_in_ipv6(), and ssh_interceptor_packet_in_arp().
+
+ This function must only be called from softirq context, or
+ with softirqs disabled. This function MUST NOT be called
+ from a hardirq (as then it could pre-empt itself on the same CPU). */
+
+static inline unsigned int
+ssh_interceptor_packet_in(int pf,
+ unsigned int hooknum,
+ SshHookSkb *skb,
+ const struct net_device *in,
+ const struct net_device *out,
+ int (*okfn) (struct sk_buff *))
+{
+ SshInterceptor interceptor;
+ struct sk_buff *skbp = SSH_HOOK_SKB_PTR(skb);
+#ifdef DEBUG_LIGHT
+ struct iphdr *iph = (struct iphdr *) SSH_SKB_GET_NETHDR(skbp);
+#endif /* DEBUG_LIGHT */
+
+ SSH_DEBUG(SSH_D_PCKDMP,
+ ("IN 0x%04x/0x%x (%s[%d]->%s[%d]) len %d "
+ "type=0x%08x %08x -> %08x dst 0x%p dev (%s[%d])",
+ htons(skbp->protocol),
+ pf,
+ (in ? in->name : "<none>"),
+ (in ? in->ifindex : -1),
+ (out ? out->name : "<none>"),
+ (out ? out->ifindex : -1),
+ skbp->len,
+ skbp->pkt_type,
+ iph->saddr, iph->daddr,
+ SSH_SKB_DST(skbp),
+ (skbp->dev ? skbp->dev->name : "<none>"),
+ (skbp->dev ? skbp->dev->ifindex : -1)
+ ));
+
+ interceptor = ssh_interceptor_context;
+
+ if (interceptor->enable_interception == FALSE)
+ {
+ SSH_LINUX_STATISTICS(interceptor,
+ { interceptor->stats.num_passthrough++; });
+ SSH_DEBUG(11, ("packet passed through"));
+ return NF_ACCEPT;
+ }
+
+ SSH_LINUX_STATISTICS(interceptor,
+ {
+ interceptor->stats.num_bytes_in += (SshUInt64) skbp->len;
+ interceptor->stats.num_packets_in++;
+ });
+
+ /* If the device is to loopback, pass the packet through. */
+ if (in->flags & IFF_LOOPBACK)
+ {
+ SSH_LINUX_STATISTICS(interceptor,
+ { interceptor->stats.num_passthrough++; });
+ return NF_ACCEPT;
+ }
+
+ /* The linux stack makes a copy of each locally generated
+ broadcast / multicast packet. The original packet will
+ be sent to network as any packet. The copy will be marked
+ as PACKET_LOOPBACK and looped back to local stack.
+ So we let the copy continue back to local stack. */
+ if (skbp->pkt_type == PACKET_LOOPBACK)
+ {
+ SSH_LINUX_STATISTICS(interceptor,
+ { interceptor->stats.num_passthrough++; });
+ return NF_ACCEPT;
+ }
+
+ /* VPNClient code relies on skb->dev to be set.
+ If packet has been processed by AF_PACKET (what tcpdump uses),
+ then skb->dev has been cleared, and we must reset it here. */
+ SSH_ASSERT(skbp->dev == NULL || skbp->dev == in);
+ if (skbp->dev == NULL)
+ {
+ skbp->dev = (struct net_device *) in;
+ /* Increment refcount of skbp->dev. */
+ dev_hold(skbp->dev);
+ }
+
+#ifdef SSH_LINUX_NF_PRE_ROUTING_BEFORE_ENGINE
+
+ /* Traverse lower priority netfilter hooks. */
+ switch (pf)
+ {
+ case PF_INET:
+ SSH_ASSERT(hooknum == SSH_NF_IP_PRE_ROUTING);
+ NF_HOOK_THRESH(PF_INET, SSH_NF_IP_PRE_ROUTING, skbp,
+ (struct net_device *) in, (struct net_device *) out,
+ ssh_interceptor_packet_in_finish_ipv4,
+ ssh_nf_in4.priority + 1);
+ return NF_STOLEN;
+
+#ifdef SSH_LINUX_INTERCEPTOR_IPV6
+ case PF_INET6:
+ SSH_ASSERT(hooknum == SSH_NF_IP6_PRE_ROUTING);
+ NF_HOOK_THRESH(PF_INET6, SSH_NF_IP6_PRE_ROUTING, skbp,
+ (struct net_device *) in, (struct net_device *) out,
+ ssh_interceptor_packet_in_finish_ipv6,
+ ssh_nf_in6.priority + 1);
+ return NF_STOLEN;
+#endif /* SSH_LINUX_INTERCEPTOR_IPV6 */
+
+#ifndef SSH_IPSEC_IP_ONLY_INTERCEPTOR
+ case SSH_NFPROTO_ARP:
+ /* There is no point in looping ARP packets,
+ just continue packet processing, and return NF_STOLEN. */
+ ssh_interceptor_packet_in_finish(skbp, SSH_PROTOCOL_ETHERNET);
+ return NF_STOLEN;
+#endif /* !SSH_IPSEC_IP_ONLY_INTERCEPTOR */
+
+ default:
+ SSH_NOTREACHED;
+ return NF_DROP;
+ }
+
+#else /* SSH_LINUX_NF_PRE_ROUTING_BEFORE_ENGINE */
+
+ /* Continue packet processing ssh_interceptor_packet_in_finish() */
+ switch (pf)
+ {
+ case PF_INET:
+ ssh_interceptor_packet_in_finish(skbp, SSH_PROTOCOL_IP4);
+ return NF_STOLEN;
+
+#ifdef SSH_LINUX_INTERCEPTOR_IPV6
+ case PF_INET6:
+ ssh_interceptor_packet_in_finish(skbp, SSH_PROTOCOL_IP6);
+ return NF_STOLEN;
+#endif /* SSH_LINUX_INTERCEPTOR_IPV6 */
+
+#ifndef SSH_IPSEC_IP_ONLY_INTERCEPTOR
+ case SSH_NFPROTO_ARP:
+ ssh_interceptor_packet_in_finish(skbp, SSH_PROTOCOL_ETHERNET);
+ return NF_STOLEN;
+#endif /* !SSH_IPSEC_IP_ONLY_INTERCEPTOR */
+
+ default:
+ break;
+ }
+
+#endif /* SSH_LINUX_NF_PRE_ROUTING_BEFORE_ENGINE */
+
+ SSH_NOTREACHED;
+ return NF_DROP;
+}
+
+/* Netfilter hookfn() wrapper function for IPv4 packets. */
+static unsigned int
+ssh_interceptor_packet_in_ipv4(unsigned int hooknum,
+ SshHookSkb *skb,
+ const struct net_device *in,
+ const struct net_device *out,
+ int (*okfn) (struct sk_buff *))
+{
+ return ssh_interceptor_packet_in(PF_INET, hooknum, skb, in, out, okfn);
+}
+
+#ifdef SSH_LINUX_INTERCEPTOR_IPV6
+/* Netfilter nf_hookfn() wrapper function for IPv6 packets. */
+static unsigned int
+ssh_interceptor_packet_in_ipv6(unsigned int hooknum,
+ SshHookSkb *skb,
+ const struct net_device *in,
+ const struct net_device *out,
+ int (*okfn) (struct sk_buff *))
+{
+ return ssh_interceptor_packet_in(PF_INET6, hooknum, skb, in, out, okfn);
+}
+#endif /* SSH_LINUX_INTERCEPTOR_IPV6 */
+
+#ifndef SSH_IPSEC_IP_ONLY_INTERCEPTOR
+/* Netfilter nf_hookfn() wrapper function for ARP packets. */
+static unsigned int
+ssh_interceptor_packet_in_arp(unsigned int hooknum,
+ SshHookSkb *skb,
+ const struct net_device *in,
+ const struct net_device *out,
+ int (*okfn) (struct sk_buff *))
+{
+ return ssh_interceptor_packet_in(SSH_NFPROTO_ARP, hooknum, skb,
+ in, out, okfn);
+}
+#endif /* !SSH_IPSEC_IP_ONLY_INTERCEPTOR */
+
+
+/**************** Outbound packet interception *****************************/
+
+
+/* Common code for ssh_interceptor_packet_out_finish_ipv4()
+ and ssh_interceptor_packet_out_finish_ipv6().
+
+ If SSH_LINUX_NF_POST_ROUTING_BEFORE_ENGINE is set, then
+ this function is called as the okfn() function from the
+ netfilter infrastructure after the outbound hook iteration.
+ Otherwise, this function is called directly from the outbound
+ netfilter hookfn().
+
+ This function must only be called from softirq context or
+ from an exception. It will disable softirqs for the engine
+ processing. This function MUST NOT be called
+ from a hardirq (as then it could pre-empt itself
+ on the same CPU). */
+static inline int
+ssh_interceptor_packet_out_finish(struct sk_buff *skbp,
+ SshInterceptorProtocol protocol)
+{
+ SshInterceptorInternalPacket packet;
+ SshInterceptor interceptor;
+ int ifnum_in;
+ SshUInt32 flags;
+
+ SSH_ASSERT(skbp->dev != NULL);
+ ifnum_in = skbp->dev->ifindex;
+
+ interceptor = ssh_interceptor_context;
+
+ SSH_DEBUG(SSH_D_HIGHSTART,
+ ("outgoing packet 0x%p, len %d proto 0x%x [%s] iface %d [%s]",
+ skbp, skbp->len, ntohs(skbp->protocol),
+ (protocol == SSH_PROTOCOL_IP4 ? "ipv4" :
+ (protocol == SSH_PROTOCOL_IP6 ? "ipv6" :
+ (protocol == SSH_PROTOCOL_ETHERNET ? "ethernet" : "unknown"))),
+ ifnum_in, skbp->dev->name));
+
+ local_bh_disable();
+
+ flags = SSH_PACKET_FROMPROTOCOL;
+
+#ifdef LINUX_FRAGMENTATION_AFTER_NF6_POST_ROUTING
+ /* Is this a local packet which is allowed to be fragmented? */
+ if (protocol == SSH_PROTOCOL_IP6 && skbp->local_df == 1)
+ {
+ SSH_DEBUG(SSH_D_NICETOKNOW, ("Local packet, fragmentation allowed."));
+ flags |= SSH_PACKET_FRAGMENTATION_ALLOWED;
+ }
+#endif /* LINUX_FRAGMENTATION_AFTER_NF6_POST_ROUTING */
+
+#ifdef LINUX_FRAGMENTATION_AFTER_NF_POST_ROUTING
+ /* Is this a local packet which is allowed to be fragmented? */
+ if (protocol == SSH_PROTOCOL_IP4 && skbp->local_df == 1)
+ {
+ SSH_DEBUG(SSH_D_NICETOKNOW, ("Local packet, fragmentation allowed."));
+ flags |= SSH_PACKET_FRAGMENTATION_ALLOWED;
+ }
+#endif /* LINUX_FRAGMENTATION_AFTER_NF_POST_ROUTING */
+
+ /* Encapsulate the skb into a new packet. This function
+ holds packet_lock during freelist manipulation. */
+ packet = ssh_interceptor_packet_alloc_header(interceptor,
+ flags,
+ protocol,
+ ifnum_in,
+ SSH_INTERCEPTOR_INVALID_IFNUM,
+ skbp,
+ FALSE, TRUE, TRUE);
+ if (unlikely(packet == NULL))
+ {
+ SSH_DEBUG(SSH_D_FAIL, ("encapsulation failed, packet dropped"));
+ local_bh_enable();
+ /* Free sk_buff and return error */
+ dev_kfree_skb_any(skbp);
+ SSH_LINUX_STATISTICS(interceptor, { interceptor->stats.num_errors++; });
+ return -EPERM;
+ }
+
+#ifdef DEBUG_LIGHT
+ packet->skb->dev = NULL;
+#endif /* DEBUG_LIGHT */
+
+ SSH_DEBUG_HEXDUMP(SSH_D_PCKDMP,
+ ("outgoing packet, len=%d flags=0x%08lx%s",
+ packet->skb->len,
+ (unsigned long) packet->packet.flags,
+ ((packet->packet.flags & SSH_PACKET_HWCKSUM) ?
+ " [hwcsum]" : "")),
+ packet->skb->data, packet->skb->len);
+
+ SSH_LINUX_STATISTICS(interceptor,
+ {
+ interceptor->stats.num_fastpath_bytes_out += (SshUInt64) packet->skb->len;
+ interceptor->stats.num_fastpath_packets_out++;
+ });
+
+ /* Pass the packet to engine. */
+ SSH_LINUX_INTERCEPTOR_PACKET_CALLBACK(interceptor,
+ (SshInterceptorPacket) packet);
+
+ local_bh_enable();
+
+ /* Return ok */
+ return 0;
+}
+
+#ifdef SSH_LINUX_NF_POST_ROUTING_BEFORE_ENGINE
+
+static inline int
+ssh_interceptor_packet_out_finish_ipv4(struct sk_buff *skbp)
+{
+ return ssh_interceptor_packet_out_finish(skbp, SSH_PROTOCOL_IP4);
+}
+
+#ifdef SSH_LINUX_INTERCEPTOR_IPV6
+static inline int
+ssh_interceptor_packet_out_finish_ipv6(struct sk_buff *skbp)
+{
+ return ssh_interceptor_packet_out_finish(skbp, SSH_PROTOCOL_IP6);
+}
+#endif /* SSH_LINUX_INTERCEPTOR_IPV6 */
+#endif /* SSH_LINUX_NF_POST_ROUTING_BEFORE_ENGINE */
+
+/* ssh_interceptor_packet_out() is the common code for
+ outbound netfilter hook ssh_interceptor_packet_out_ipv4()
+ and ssh_interceptor_packet_out_ipv6().
+
+ Netfilter does not provide a clean way of intercepting ALL packets
+ being sent via an output chain after all other filters are processed.
+ Therefore this hook is registered first, and then if
+ SSH_LINUX_NF_POST_ROUTING_BEFORE_ENGINE is set the packet is
+ sent back to SSH_NF_IP_POST_ROUTING hook with (*okfn)()
+ pointing to the actual interception function. If
+ SSH_LINUX_NF_POST_ROUTING_BEFORE_ENGINE is not set, then
+ all following netfilter hook functions in SSH_NF_IP_POST_ROUTING hook
+ are skipped.
+
+ This function must only be called from softirq context or
+ from an exception. It will disable softirqs for the engine
+ processing. This function MUST NOT be called
+ from a hardirq (as then it could pre-empt itself
+ on the same CPU). */
+
+static inline unsigned int
+ssh_interceptor_packet_out(int pf,
+ unsigned int hooknum,
+ SshHookSkb *skb,
+ const struct net_device *in,
+ const struct net_device *out,
+ int (*okfn) (struct sk_buff *))
+{
+ SshInterceptor interceptor;
+ struct sk_buff *skbp = SSH_HOOK_SKB_PTR(skb);
+#ifdef DEBUG_LIGHT
+ struct iphdr *iph = (struct iphdr *) SSH_SKB_GET_NETHDR(skbp);
+#endif /* DEBUG_LIGHT */
+
+ SSH_DEBUG(SSH_D_PCKDMP,
+ ("OUT 0x%04x/0x%x (%s[%d]->%s[%d]) len %d "
+ "type=0x%08x %08x -> %08x dst 0x%p dev (%s[%d])",
+ htons(skbp->protocol),
+ pf,
+ (in ? in->name : "<none>"),
+ (in ? in->ifindex : -1),
+ (out ? out->name : "<none>"),
+ (out ? out->ifindex : -1),
+ skbp->len,
+ skbp->pkt_type,
+ iph->saddr, iph->daddr,
+ SSH_SKB_DST(skbp),
+ (skbp->dev ? skbp->dev->name : "<none>"),
+ (skbp->dev ? skbp->dev->ifindex : -1)
+ ));
+
+ interceptor = ssh_interceptor_context;
+
+ if (interceptor->enable_interception == FALSE)
+ {
+ SSH_LINUX_STATISTICS(interceptor,
+ { interceptor->stats.num_passthrough++; });
+ SSH_DEBUG(11, ("packet passed through"));
+ return NF_ACCEPT;
+ }
+
+ SSH_LINUX_STATISTICS(interceptor,
+ {
+ interceptor->stats.num_packets_out++;
+ interceptor->stats.num_bytes_out += (SshUInt64) skbp->len;
+ });
+
+ /* If the device is to loopback, pass the packet through. */
+ if (out->flags & IFF_LOOPBACK)
+ {
+ SSH_DEBUG(SSH_D_NICETOKNOW, ("loopback packet passed through"));
+ SSH_DEBUG_HEXDUMP(SSH_D_PCKDMP, ("len=%d", skbp->len),
+ skbp->data, skbp->len);
+ SSH_LINUX_STATISTICS(interceptor,
+ { interceptor->stats.num_passthrough++; });
+ return NF_ACCEPT;
+ }
+
+ /* Linux network stack creates a copy of locally generated broadcast
+ and multicast packets, and sends the copies to local stack using
+ 'ip_dev_loopback_xmit' or 'ip6_dev_loopback_xmit' as the NFHOOK
+ okfn. Intercept the original packets and let the local copies go
+ through. */
+ if (pf == PF_INET &&
+ okfn != interceptor->linux_fn.ip_finish_output)
+ {
+ SSH_DEBUG(SSH_D_NICETOKNOW,
+ ("local IPv4 broadcast loopback packet passed through"));
+ SSH_DEBUG_HEXDUMP(SSH_D_PCKDMP, ("len=%d", skbp->len),
+ skbp->data, skbp->len);
+ SSH_LINUX_STATISTICS(interceptor,
+ { interceptor->stats.num_passthrough++; });
+ return NF_ACCEPT;
+ }
+#ifdef SSH_LINUX_INTERCEPTOR_IPV6
+ if (pf == PF_INET6 &&
+ okfn != interceptor->linux_fn.ip6_output_finish)
+ {
+ SSH_DEBUG(SSH_D_NICETOKNOW,
+ ("local IPv6 broadcast loopback packet passed through"));
+ SSH_DEBUG_HEXDUMP(SSH_D_PCKDMP, ("len=%d", skbp->len),
+ skbp->data, skbp->len);
+ SSH_LINUX_STATISTICS(interceptor,
+ { interceptor->stats.num_passthrough++; });
+ return NF_ACCEPT;
+ }
+
+#ifdef SSH_IPSEC_IP_ONLY_INTERCEPTOR
+#ifdef LINUX_IP_ONLY_PASSTHROUGH_NDISC
+ if (pf == PF_INET6 &&
+ skbp->sk == dev_net(skbp->dev)->ipv6.ndisc_sk)
+ {
+ SSH_DEBUG(SSH_D_NICETOKNOW,
+ ("Neighbour discovery packet passed through"));
+ SSH_DEBUG_HEXDUMP(SSH_D_PCKDMP,
+ ("length %d dumping %d bytes",
+ (int) skbp->len, (int) skb_headlen(skbp)),
+ skbp->data, skb_headlen(skbp));
+ SSH_LINUX_STATISTICS(interceptor,
+ { interceptor->stats.num_passthrough++; });
+ return NF_ACCEPT;
+ }
+#endif /* LINUX_IP_ONLY_PASSTHROUGH_NDISC */
+#endif /* SSH_IPSEC_IP_ONLY_INTERCEPTOR */
+
+#endif /* SSH_LINUX_INTERCEPTOR_IPV6 */
+
+ /* Assert that we are about to intercept the packet from
+ the correct netfilter hook on the correct path. */
+#ifdef SSH_LINUX_INTERCEPTOR_IPV6
+ SSH_ASSERT(okfn == interceptor->linux_fn.ip_finish_output ||
+ okfn == interceptor->linux_fn.ip6_output_finish);
+#else /* SSH_LINUX_INTERCEPTOR_IPV6 */
+ SSH_ASSERT(okfn == interceptor->linux_fn.ip_finish_output);
+#endif /* SSH_LINUX_INTERCEPTOR_IPV6 */
+
+#ifdef SSH_LINUX_NF_POST_ROUTING_BEFORE_ENGINE
+
+ /* Traverse lower priority netfilter hooks. */
+ switch (pf)
+ {
+ case PF_INET:
+ SSH_ASSERT(hooknum == SSH_NF_IP_POST_ROUTING);
+ NF_HOOK_THRESH(PF_INET, SSH_NF_IP_POST_ROUTING, skbp,
+ (struct net_device *) in, (struct net_device *) out,
+ ssh_interceptor_packet_out_finish_ipv4,
+ ssh_nf_out4.priority + 1);
+ return NF_STOLEN;
+
+#ifdef SSH_LINUX_INTERCEPTOR_IPV6
+ case PF_INET6:
+ SSH_ASSERT(hooknum == SSH_NF_IP6_POST_ROUTING);
+ NF_HOOK_THRESH(PF_INET6, SSH_NF_IP6_POST_ROUTING, skbp,
+ (struct net_device *) in, (struct net_device *) out,
+ ssh_interceptor_packet_out_finish_ipv6,
+ ssh_nf_out6.priority + 1);
+ return NF_STOLEN;
+#endif /* SSH_LINUX_INTERCEPTOR_IPV6 */
+
+ default:
+ SSH_NOTREACHED;
+ return NF_DROP;
+ }
+
+#else /* SSH_LINUX_NF_POST_ROUTING_BEFORE_ENGINE */
+
+ /* Continue packet processing in ssh_interceptor_packet_out_finish() */
+ switch (pf)
+ {
+ case PF_INET:
+ SSH_ASSERT(hooknum == SSH_NF_IP_POST_ROUTING);
+ ssh_interceptor_packet_out_finish(skbp, SSH_PROTOCOL_IP4);
+ return NF_STOLEN;
+
+#ifdef SSH_LINUX_INTERCEPTOR_IPV6
+ case PF_INET6:
+ SSH_ASSERT(hooknum == SSH_NF_IP6_POST_ROUTING);
+ ssh_interceptor_packet_out_finish(skbp, SSH_PROTOCOL_IP6);
+ return NF_STOLEN;
+#endif /* SSH_LINUX_INTERCEPTOR_IPV6 */
+
+ default:
+ break;
+ }
+#endif /* SSH_LINUX_NF_POST_ROUTING_BEFORE_ENGINE */
+
+ SSH_NOTREACHED;
+ return NF_DROP;
+}
+
+/* Netfilter nf_hookfn() wrapper function for IPv4 packets. */
+static unsigned int
+ssh_interceptor_packet_out_ipv4(unsigned int hooknum,
+ SshHookSkb *skb,
+ const struct net_device *in,
+ const struct net_device *out,
+ int (*okfn) (struct sk_buff *))
+{
+ return ssh_interceptor_packet_out(PF_INET, hooknum, skb, in, out, okfn);
+}
+
+#ifdef SSH_LINUX_INTERCEPTOR_IPV6
+/* Netfilter nf_hookfn() wrapper function for IPv6 packets. */
+static unsigned int
+ssh_interceptor_packet_out_ipv6(unsigned int hooknum,
+ SshHookSkb *skb,
+ const struct net_device *in,
+ const struct net_device *out,
+ int (*okfn) (struct sk_buff *))
+{
+ struct sk_buff *skbp = SSH_HOOK_SKB_PTR(skb);
+ if (skbp->dev == NULL)
+ skbp->dev = SSH_SKB_DST(skbp)->dev;
+
+ return ssh_interceptor_packet_out(PF_INET6, hooknum, skb, in, out, okfn);
+}
+#endif /* SSH_LINUX_INTERCEPTOR_IPV6 */
+
+
+/**************** Sending packets ******************************************/
+
+/* Netfilter okfn() for sending packets to network after
+ SSH_NF_IP_FORWARD hook traversal. */
+
+static inline int
+ssh_interceptor_send_to_network(int pf, struct sk_buff *skbp)
+{
+ skbp->pkt_type = PACKET_OUTGOING;
+
+#ifdef CONFIG_NETFILTER_DEBUG
+#ifdef LINUX_HAS_SKB_NFDEBUG
+ if (pf == PF_INET)
+ {
+ /* Mark SSH_NF_IP_LOCAL_OUT chains visited */
+ if (skbp->sk)
+ skbp->nf_debug = ((1 << SSH_NF_IP_LOCAL_OUT)
+ | (1 << SSH_NF_IP_POST_ROUTING));
+
+ /* skbp is unowned, netfilter thinks this is a forwarded skb.
+ Mark SSH_NF_IP_PRE_ROUTING, SSH_NF_IP_FORWARD,
+ and SSH_NF_IP_POST_ROUTING
+ chains visited */
+ else
+ skbp->nf_debug = ((1 << SSH_NF_IP_PRE_ROUTING)
+ | (1 << SSH_NF_IP_FORWARD)
+ | (1 << SSH_NF_IP_POST_ROUTING));
+ }
+#endif /* LINUX_HAS_SKB_NFDEBUG */
+#endif /* CONFIG_NETFILTER_DEBUG */
+
+ SSH_LINUX_STATISTICS(ssh_interceptor_context,
+ {
+ ssh_interceptor_context->stats.num_packets_sent++;
+ ssh_interceptor_context->stats.num_bytes_sent += (SshUInt64) skbp->len;
+ });
+
+#ifdef SSH_LINUX_NF_POST_ROUTING_AFTER_ENGINE
+ /* Traverse lower priority netfilter hooks. */
+ switch (pf)
+ {
+ case PF_INET:
+ return NF_HOOK_THRESH(PF_INET, SSH_NF_IP_POST_ROUTING, skbp,
+ NULL, skbp->dev,
+ ssh_interceptor_context->
+ linux_fn.ip_finish_output,
+ ssh_nf_out4.priority + 1);
+
+#ifdef SSH_LINUX_INTERCEPTOR_IPV6
+ case PF_INET6:
+ return NF_HOOK_THRESH(PF_INET6, SSH_NF_IP6_POST_ROUTING, skbp,
+ NULL, skbp->dev,
+ ssh_interceptor_context->
+ linux_fn.ip6_output_finish,
+ ssh_nf_out6.priority + 1);
+#endif /* SSH_LINUX_INTERCEPTOR_IPV6 */
+
+ default:
+ break;
+ }
+
+#else /* SSH_LINUX_NF_POST_ROUTING_AFTER_ENGINE */
+ /* Pass packet to output path. */
+ switch (pf)
+ {
+ case PF_INET:
+ return (*ssh_interceptor_context->linux_fn.ip_finish_output)(skbp);
+
+#ifdef SSH_LINUX_INTERCEPTOR_IPV6
+ case PF_INET6:
+ return (*ssh_interceptor_context->linux_fn.ip6_output_finish)(skbp);
+#endif /* SSH_LINUX_INTERCEPTOR_IPV6 */
+
+ default:
+ break;
+ }
+#endif /* SSH_LINUX_NF_POST_ROUTING_AFTER_ENGINE */
+
+ SSH_NOTREACHED;
+ dev_kfree_skb_any(skbp);
+ return -EPERM;
+}
+
+static inline int
+ssh_interceptor_send_to_network_ipv4(struct sk_buff *skbp)
+{
+ return ssh_interceptor_send_to_network(PF_INET, skbp);
+}
+
+#ifdef SSH_LINUX_INTERCEPTOR_IPV6
+static inline int
+ssh_interceptor_send_to_network_ipv6(struct sk_buff *skbp)
+{
+ return ssh_interceptor_send_to_network(PF_INET6, skbp);
+}
+#endif /* SSH_LINUX_INTERCEPTOR_IPV6 */
+
+/* ssh_interceptor_send() sends a packet to the network or to the
+ protocol stacks. This will eventually free the packet by calling
+ ssh_interceptor_packet_free. The packet header should not be
+ touched once this function has been called.
+
+ ssh_interceptor_send() function for both media level and IP level
+ interceptor. This grabs a packet with media layer headers attached
+ and sends it to the interface defined by 'pp->ifnum_out'. */
+void
+ssh_interceptor_send(SshInterceptor interceptor,
+ SshInterceptorPacket pp,
+ size_t media_header_len)
+{
+ SshInterceptorInternalPacket ipp = (SshInterceptorInternalPacket) pp;
+ struct net_device *dev;
+#ifdef SSH_IPSEC_IP_ONLY_INTERCEPTOR
+#ifdef SSH_LINUX_NF_FORWARD_AFTER_ENGINE
+ struct net_device *in_dev = NULL;
+#endif /* SSH_LINUX_NF_FORWARD_AFTER_ENGINE */
+#endif /*SSH_IPSEC_IP_ONLY_INTERCEPTOR */
+ unsigned char *neth;
+#ifdef SSH_LINUX_INTERCEPTOR_IPV6
+ size_t offset;
+ SshUInt8 ipproto;
+#endif /* SSH_LINUX_INTERCEPTOR_IPV6 */
+
+ SSH_DEBUG(SSH_D_HIGHSTART,
+ ("sending packet to %s, "
+ "len=%d flags=0x%08lx ifnum_out=%lu protocol=%s[0x%x]",
+ ((pp->flags & SSH_PACKET_FROMPROTOCOL) ? "network" :
+ ((pp->flags & SSH_PACKET_FROMADAPTER) ? "stack" :
+ "nowhere")),
+ ipp->skb->len, (unsigned long) pp->flags,
+ (unsigned long) pp->ifnum_out,
+ (pp->protocol == SSH_PROTOCOL_IP4 ? "ipv4" :
+ (pp->protocol == SSH_PROTOCOL_IP6 ? "ipv6" :
+ (pp->protocol == SSH_PROTOCOL_ARP ? "arp" :
+ (pp->protocol == SSH_PROTOCOL_ETHERNET ? "ethernet" :
+ "unknown")))),
+ pp->protocol));
+
+ SSH_DEBUG_HEXDUMP(SSH_D_PCKDMP, ("packet, len %d", ipp->skb->len),
+ ipp->skb->data, ipp->skb->len);
+
+ /* Require that any references to previous devices
+ were released by the entrypoint hooks. */
+ SSH_ASSERT(ipp->skb->dev == NULL);
+
+ /* Map 'pp->ifnum_out' to a net_device.
+ This will dev_hold() the net_device. */
+ dev = ssh_interceptor_ifnum_to_netdev(interceptor, pp->ifnum_out);
+ if (dev == NULL)
+ {
+ SSH_DEBUG(SSH_D_UNCOMMON,
+ ("Interface %lu has disappeared, dropping packet 0x%p",
+ (unsigned long) pp->ifnum_out, ipp->skb));
+ goto error;
+ }
+ ipp->skb->dev = dev;
+
+ /* Verify that packet has enough headroom to be sent out via `skb->dev'. */
+ ipp->skb =
+ ssh_interceptor_packet_verify_headroom(ipp->skb, media_header_len);
+ if (ipp->skb == NULL)
+ {
+ SSH_DEBUG(SSH_D_UNCOMMON,
+ ("Could not add headroom to skbp, dropping packet 0x%p",
+ ipp->skb));
+ goto error;
+ }
+
+#ifdef INTERCEPTOR_IP_ALIGNS_PACKETS
+ /* Align IP header to word boundary. */
+ if (!ssh_interceptor_packet_align(pp, media_header_len))
+ {
+ pp = NULL;
+ goto error;
+ }
+#endif /* INTERCEPTOR_IP_ALIGNS_PACKETS */
+
+#if (SSH_INTERCEPTOR_NUM_EXTENSION_SELECTORS > 0)
+#ifdef SSH_LINUX_FWMARK_EXTENSION_SELECTOR
+ /* Copy the linux nfmark from the extension slot indexed by
+ SSH_LINUX_FWMARK_EXTENSION_SELECTOR. */
+ SSH_SKB_MARK(ipp->skb) = pp->extension[SSH_LINUX_FWMARK_EXTENSION_SELECTOR];
+#endif /* SSH_LINUX_FWMARK_EXTENSION_SELECTOR */
+#endif /* (SSH_INTERCEPTOR_NUM_EXTENSION_SELECTORS > 0) */
+
+ /* Check if the engine has cleared the SSH_PACKET_HWCKSUM flag. */
+ if ((pp->flags & SSH_PACKET_HWCKSUM) == 0)
+ ipp->skb->ip_summed = CHECKSUM_NONE;
+
+ /* Clear control buffer, as packet contents might have changed. */
+ if ((pp->flags & SSH_PACKET_UNMODIFIED) == 0)
+ memset(ipp->skb->cb, 0, sizeof(ipp->skb->cb));
+
+ /* Send to network */
+ if (pp->flags & SSH_PACKET_FROMPROTOCOL)
+ {
+ /* Network header pointer is required by tcpdump. */
+ SSH_SKB_SET_NETHDR(ipp->skb, ipp->skb->data + media_header_len);
+
+ /* Let unmodified packets pass on as if they were never intercepted.
+ Note that this expects that skb->dst has not been cleared or modified
+ during Engine processing. */
+ if (pp->flags & SSH_PACKET_UNMODIFIED)
+ {
+ SSH_DEBUG(SSH_D_HIGHOK, ("Passing unmodified packet to network"));
+
+#ifndef SSH_IPSEC_IP_ONLY_INTERCEPTOR
+ /* Remove the media header that was prepended to the packet
+ in the inbound netfilter hook. Update skb->protocol and
+ pp->protocol. */
+ if (media_header_len > 0)
+ {
+ SSH_ASSERT(ipp->skb->len >= media_header_len);
+ SSH_SKB_SET_MACHDR(ipp->skb, ipp->skb->data);
+ ipp->skb->protocol = ssh_ethertype_to_skb_proto(pp->protocol,
+ media_header_len,
+ ipp->skb->data);
+ skb_pull(ipp->skb, media_header_len);
+ if (ntohs(ipp->skb->protocol) == ETH_P_IP)
+ pp->protocol = SSH_PROTOCOL_IP4;
+#ifdef SSH_LINUX_INTERCEPTOR_IPV6
+ else if (ntohs(ipp->skb->protocol) == ETH_P_IPV6)
+ pp->protocol = SSH_PROTOCOL_IP6;
+#endif /* SSH_LINUX_INTERCEPTOR_IPV6 */
+ else
+ {
+ SSH_DEBUG(SSH_D_FAIL,
+ ("Invalid skb protocol %d, dropping packet",
+ ntohs(ipp->skb->protocol)));
+ goto error;
+ }
+ }
+#endif /* SSH_IPSEC_IP_ONLY_INTERCEPTOR */
+
+ if (SSH_SKB_DST(ipp->skb) == NULL)
+ {
+ SSH_DEBUG(SSH_D_FAIL, ("Invalid skb->dst, dropping packet"));
+ goto error;
+ }
+
+ switch (pp->protocol)
+ {
+ case SSH_PROTOCOL_IP4:
+ SSH_LINUX_STATISTICS(interceptor,
+ { interceptor->stats.num_passthrough++; });
+ ssh_interceptor_send_to_network_ipv4(ipp->skb);
+ break;
+
+#ifdef SSH_LINUX_INTERCEPTOR_IPV6
+ case SSH_PROTOCOL_IP6:
+ SSH_LINUX_STATISTICS(interceptor,
+ { interceptor->stats.num_passthrough++; });
+ ssh_interceptor_send_to_network_ipv6(ipp->skb);
+ break;
+#endif /* SSH_LINUX_INTERCEPTOR_IPV6 */
+
+ default:
+ SSH_DEBUG(SSH_D_ERROR,
+ ("pp->protocol 0x%x ipp->skb->protocol 0x%x",
+ pp->protocol, ipp->skb->protocol));
+ SSH_NOTREACHED;
+ goto error;
+ }
+
+ /* All done. */
+ goto sent;
+ }
+
+#ifdef DEBUG_LIGHT
+ if (
+#ifdef LINUX_HAS_NEW_CHECKSUM_FLAGS
+ ipp->skb->ip_summed == CHECKSUM_PARTIAL
+#else /* LINUX_HAS_NEW_CHECKSUM_FLAGS */
+ ipp->skb->ip_summed == CHECKSUM_HW
+#endif /* LINUX_HAS_NEW_CHECKSUM_FLAGS */
+ )
+ SSH_DEBUG(SSH_D_LOWOK, ("Hardware performs checksumming."));
+ else if (ipp->skb->ip_summed == CHECKSUM_NONE)
+ SSH_DEBUG(SSH_D_LOWOK, ("Checksum calculated in software."));
+ else
+ SSH_DEBUG(SSH_D_LOWOK, ("No checksumming required."));
+#endif /* DEBUG_LIGHT */
+
+#ifndef SSH_IPSEC_IP_ONLY_INTERCEPTOR
+
+ /* Media level */
+ SSH_ASSERT(media_header_len <= ipp->skb->len);
+ SSH_SKB_SET_MACHDR(ipp->skb, ipp->skb->data);
+
+ /* Set ipp->skb->protocol */
+ SSH_ASSERT(skb_headlen(ipp->skb) >= media_header_len);
+ ipp->skb->protocol = ssh_ethertype_to_skb_proto(pp->protocol,
+ media_header_len,
+ ipp->skb->data);
+
+ SSH_LINUX_STATISTICS(interceptor,
+ {
+ interceptor->stats.num_packets_sent++;
+ interceptor->stats.num_bytes_sent += (SshUInt64) ipp->skb->len;
+ });
+
+ /* Pass packet to network device driver. */
+ dev_queue_xmit(ipp->skb);
+
+ /* All done. */
+ goto sent;
+
+#else /* !SSH_IPSEC_IP_ONLY_INTERCEPTOR */
+
+ /* IP level */
+
+ /* Set ipp->skb->protocol */
+ ipp->skb->protocol = ssh_proto_to_skb_proto(pp->protocol);
+
+#ifdef SSH_LINUX_NF_FORWARD_AFTER_ENGINE
+
+ /* Prepare to pass forwarded packets through
+ SSH_NF_IP_FORWARD netfilter hook. */
+ if (pp->flags & SSH_PACKET_FORWARDED)
+ {
+ /* Map 'pp->ifnum_in' to a net_device. */
+ in_dev = ssh_interceptor_ifnum_to_netdev(interceptor, pp->ifnum_in);
+
+ SSH_DEBUG(SSH_D_PCKDMP,
+ ("FWD 0x%04x/%d (%s[%d]->%s[%d]) len %d "
+ "type=0x%08x dst 0x%08x",
+ ntohs(ipp->skb->protocol), pp->protocol,
+ (in_dev ? in_dev->name : "<none>"),
+ (in_dev ? in_dev->ifindex : -1),
+ (ipp->skb->dev ? ipp->skb->dev->name : "<none>"),
+ (ipp->skb->dev ? ipp->skb->dev->ifindex : -1),
+ ipp->skb->len, ipp->skb->pkt_type, SSH_SKB_DST(ipp->skb)));
+
+ SSH_DEBUG(SSH_D_HIGHSTART,
+ ("forwarding packet 0x%08x, len %d proto 0x%x [%s]",
+ ipp->skb, ipp->skb->len, ntohs(ipp->skb->protocol),
+ (pp->protocol == SSH_PROTOCOL_IP4 ? "ipv4" :
+ (pp->protocol == SSH_PROTOCOL_IP6 ? "ipv6" :
+ (pp->protocol == SSH_PROTOCOL_ARP ? "arp" :
+ "unknown")))));
+
+ /* Change pkt_type to PACKET_HOST, which is expected
+ in the SSH_NF_IP_FORWARD hook. It is set to PACKET_OUTGOING
+ in ssh_interceptor_send_to_network_*() */
+ ipp->skb->pkt_type = PACKET_HOST;
+ }
+#endif /* SSH_LINUX_NF_FORWARD_AFTER_ENGINE */
+
+ SSH_ASSERT(media_header_len == 0);
+
+ switch (pp->protocol)
+ {
+ case SSH_PROTOCOL_IP4:
+ /* Set ipp->skb->dst */
+ if (!ssh_interceptor_reroute_skb_ipv4(interceptor,
+ ipp->skb,
+ pp->route_selector,
+ pp->ifnum_in))
+ {
+ SSH_DEBUG(SSH_D_UNCOMMON,
+ ("Unable to reroute skb 0x%p", ipp->skb));
+ goto error;
+ }
+ SSH_ASSERT(SSH_SKB_DST(ipp->skb) != NULL);
+#ifdef SSH_LINUX_NF_FORWARD_AFTER_ENGINE
+ /* Pass forwarded packets to SSH_NF_IP_FORWARD netfilter hook */
+ if (pp->flags & SSH_PACKET_FORWARDED)
+ {
+ NF_HOOK(PF_INET, SSH_NF_IP_FORWARD, ipp->skb,
+ in_dev, ipp->skb->dev,
+ ssh_interceptor_send_to_network_ipv4);
+ }
+ /* Send local packets directly to network. */
+ else
+#endif /* SSH_LINUX_NF_FORWARD_AFTER_ENGINE */
+ ssh_interceptor_send_to_network_ipv4(ipp->skb);
+ break;
+
+#ifdef SSH_LINUX_INTERCEPTOR_IPV6
+ case SSH_PROTOCOL_IP6:
+ /* Set ipp->skb->dst */
+ if (!ssh_interceptor_reroute_skb_ipv6(interceptor,
+ ipp->skb,
+ pp->route_selector,
+ pp->ifnum_in))
+ {
+ SSH_DEBUG(SSH_D_UNCOMMON,
+ ("Unable to reroute skb 0x%p", ipp->skb));
+ goto error;
+ }
+ SSH_ASSERT(SSH_SKB_DST(ipp->skb) != NULL);
+#ifdef SSH_LINUX_NF_FORWARD_AFTER_ENGINE
+ /* Pass forwarded packets to SSH_NF_IP6_FORWARD netfilter hook */
+ if (pp->flags & SSH_PACKET_FORWARDED)
+ {
+ NF_HOOK(PF_INET6, SSH_NF_IP6_FORWARD, ipp->skb,
+ in_dev, ipp->skb->dev,
+ ssh_interceptor_send_to_network_ipv6);
+ }
+ /* Send local packets directly to network. */
+ else
+#endif /* SSH_LINUX_NF_FORWARD_AFTER_ENGINE */
+ ssh_interceptor_send_to_network_ipv6(ipp->skb);
+ break;
+#endif /* SSH_LINUX_INTERCEPTOR_IPV6 */
+
+ default:
+ SSH_DEBUG(SSH_D_ERROR,
+ ("pp->protocol 0x%x ipp->skb->protocol 0x%x",
+ pp->protocol, ipp->skb->protocol));
+ SSH_NOTREACHED;
+ goto error;
+ }
+
+ /* All done. */
+ goto sent;
+
+#endif /* SSH_IPSEC_IP_ONLY_INTERCEPTOR */
+ }
+
+ /* Send to stack */
+ else if (pp->flags & SSH_PACKET_FROMADAPTER)
+ {
+#ifndef SSH_IPSEC_IP_ONLY_INTERCEPTOR
+ SshUInt32 pkt_len4;
+#endif /* SSH_IPSEC_IP_ONLY_INTERCEPTOR */
+#ifdef SSH_LINUX_INTERCEPTOR_IPV6
+ SshUInt32 pkt_len6;
+#endif /* SSH_LINUX_INTERCEPTOR_IPV6 */
+
+ /* Network header pointer is required by tcpdump. */
+ SSH_SKB_SET_NETHDR(ipp->skb, ipp->skb->data + media_header_len);
+
+ /* Let unmodified packets pass on as if they were never intercepted.
+ Note that this expects that SSH_PACKET_UNMODIFIED packets are either
+ IPv4 or IPv6. Currently there is no handling for ARP, as the Engine
+ never sets SSH_PACKET_UNMODIFIED for ARP packets. */
+ if (pp->flags & SSH_PACKET_UNMODIFIED)
+ {
+ SSH_DEBUG(SSH_D_HIGHOK, ("Passing unmodified packet to stack"));
+
+#ifndef SSH_IPSEC_IP_ONLY_INTERCEPTOR
+ /* Remove the media header that was prepended to the packet
+ in the inbound netfilter hook. Update skb->protocol and
+ pp->protocol. */
+ if (media_header_len > 0)
+ {
+ SSH_ASSERT(ipp->skb->len >= media_header_len);
+ SSH_SKB_SET_MACHDR(ipp->skb, ipp->skb->data);
+ ipp->skb->protocol = ssh_ethertype_to_skb_proto(pp->protocol,
+ media_header_len,
+ ipp->skb->data);
+ skb_pull(ipp->skb, media_header_len);
+ if (ntohs(ipp->skb->protocol) == ETH_P_IP)
+ pp->protocol = SSH_PROTOCOL_IP4;
+#ifdef SSH_LINUX_INTERCEPTOR_IPV6
+ else if (ntohs(ipp->skb->protocol) == ETH_P_IPV6)
+ pp->protocol = SSH_PROTOCOL_IP6;
+#endif /* SSH_LINUX_INTERCEPTOR_IPV6 */
+ else
+ {
+ SSH_DEBUG(SSH_D_FAIL,
+ ("Invalid skb protocol %d, dropping packet",
+ ntohs(ipp->skb->protocol)));
+ goto error;
+ }
+ }
+#endif /* SSH_IPSEC_IP_ONLY_INTERCEPTOR */
+
+ switch (pp->protocol)
+ {
+ case SSH_PROTOCOL_IP4:
+ SSH_LINUX_STATISTICS(interceptor,
+ { interceptor->stats.num_passthrough++; });
+#ifdef SSH_LINUX_NF_PRE_ROUTING_AFTER_ENGINE
+ SSH_DEBUG(SSH_D_LOWOK, ("Passing skb 0x%p to NF_IP_PRE_ROUTING",
+ ipp->skb));
+ NF_HOOK_THRESH(PF_INET, SSH_NF_IP_PRE_ROUTING,
+ ipp->skb, ipp->skb->dev, NULL,
+ interceptor->nf->linux_fn.ip_rcv_finish,
+ ssh_nf_in4.priority + 1);
+#else /* SSH_LINUX_NF_PRE_ROUTING_AFTER_ENGINE */
+ /* Call SSH_NF_IP_PREROUTING okfn() directly */
+ SSH_DEBUG(SSH_D_LOWOK, ("Passing skb 0x%p to ip_rcv_finish",
+ ipp->skb));
+ (*interceptor->linux_fn.ip_rcv_finish)(ipp->skb);
+#endif /* SSH_LINUX_NF_PRE_ROUTING_AFTER_ENGINE */
+ break;
+
+#ifdef SSH_LINUX_INTERCEPTOR_IPV6
+ case SSH_PROTOCOL_IP6:
+ SSH_LINUX_STATISTICS(interceptor,
+ { interceptor->stats.num_passthrough++; });
+#ifdef SSH_LINUX_NF_PRE_ROUTING_AFTER_ENGINE
+ SSH_DEBUG(SSH_D_LOWOK, ("Passing skb 0x%p to NF_IP6_PRE_ROUTING",
+ ipp->skb));
+ NF_HOOK_THRESH(PF_INET6, SSH_NF_IP6_PRE_ROUTING, ipp->skb,
+ ipp->skb->dev, NULL,
+ interceptor->nf->linux_fn.ip6_rcv_finish,
+ ssh_nf_out6.priority + 1);
+#else /* SSH_LINUX_NF_PRE_ROUTING_AFTER_ENGINE */
+ /* Call SSH_NF_IP6_PREROUTING okfn() directly */
+ SSH_DEBUG(SSH_D_LOWOK, ("Passing skb 0x%p to ip6_rcv_finish",
+ ipp->skb));
+ (*interceptor->linux_fn.ip6_rcv_finish)(ipp->skb);
+#endif /* SSH_LINUX_NF_PRE_ROUTING_AFTER_ENGINE */
+ break;
+#endif /* SSH_LINUX_INTERCEPTOR_IPV6 */
+
+ default:
+ SSH_DEBUG(SSH_D_ERROR,
+ ("pp->protocol 0x%x ipp->skb->protocol 0x%x",
+ pp->protocol, ipp->skb->protocol));
+ SSH_NOTREACHED;
+ goto error;
+ }
+
+ /* All done. */
+ goto sent;
+ }
+
+ /* If we do not wish to keep the broadcast state of
+ the packet, then reset the pkt_type to PACKET_HOST. */
+ if (!((ipp->skb->pkt_type == PACKET_MULTICAST
+ || ipp->skb->pkt_type == PACKET_BROADCAST)
+ && (pp->flags & SSH_PACKET_MEDIABCAST) != 0))
+ ipp->skb->pkt_type = PACKET_HOST;
+
+ /* Clear old routing decision */
+ if (SSH_SKB_DST(ipp->skb))
+ {
+ dst_release(SSH_SKB_DST(ipp->skb));
+ SSH_SKB_DST_SET(ipp->skb, NULL);
+ }
+
+ /* If the packet has an associated SKB and that SKB is associated
+ with a socket, orphan the skb from it's owner. These situations
+ may arise when sending packets towards the protocol when
+ the packet has been turned around by the engine. */
+ skb_orphan(ipp->skb);
+
+#ifndef SSH_IPSEC_IP_ONLY_INTERCEPTOR
+
+ /* Media level */
+
+ /* If the packet does not include a media level header (for
+ example in case of pppoe), calling eth_type_trans() will
+ corrupt the beginning of packet. Instead skb->protocol must
+ be set from pp->protocol. */
+ if (media_header_len == 0)
+ {
+ SSH_SKB_SET_MACHDR(ipp->skb, ipp->skb->data);
+ ipp->skb->protocol = ssh_proto_to_skb_proto(pp->protocol);
+ }
+ else
+ {
+ /* Workaround for 802.2Q VLAN interfaces.
+ Calling eth_type_trans() would corrupt these packets,
+ as dev->hard_header_len includes the VLAN tag, but the
+ packet does not. */
+ if (ipp->skb->dev->priv_flags & IFF_802_1Q_VLAN)
+ {
+ struct ethhdr *ethernet;
+
+ SSH_SKB_SET_MACHDR(ipp->skb, ipp->skb->data);
+ ethernet = ssh_get_eth_hdr(ipp->skb);
+ ipp->skb->protocol = ethernet->h_proto;
+ skb_pull(ipp->skb, media_header_len);
+ }
+
+ /* For all other packets, call eth_type_trans() to
+ set the protocol and the skb pointers. */
+ else
+ ipp->skb->protocol = eth_type_trans(ipp->skb, ipp->skb->dev);
+ }
+#else /* !SSH_IPSEC_IP_ONLY_INTERCEPTOR */
+
+ /* IP level */
+
+ /* Assert that the media_header_len is always zero. */
+ SSH_ASSERT(media_header_len == 0);
+ SSH_SKB_SET_MACHDR(ipp->skb, ipp->skb->data);
+ ipp->skb->protocol = ssh_proto_to_skb_proto(pp->protocol);
+
+#endif /* !SSH_IPSEC_IP_ONLY_INTERCEPTOR */
+
+#ifdef DEBUG_LIGHT
+ if (ipp->skb->ip_summed == CHECKSUM_NONE)
+ SSH_DEBUG(SSH_D_LOWOK, ("Checksum is verified in software"));
+ else if (ipp->skb->ip_summed == CHECKSUM_UNNECESSARY)
+ SSH_DEBUG(SSH_D_LOWOK, ("Hardware claims to have verified checksum"));
+ else if (
+#ifdef LINUX_HAS_NEW_CHECKSUM_FLAGS
+ ipp->skb->ip_summed == CHECKSUM_COMPLETE
+#else /* LINUX_HAS_NEW_CHECKSUM_FLAGS */
+ ipp->skb->ip_summed == CHECKSUM_HW
+#endif /* LINUX_HAS_NEW_CHECKSUM_FLAGS */
+ )
+ SSH_DEBUG(SSH_D_LOWOK, ("Hardware has verified checksum, csum 0x%x",
+ SSH_SKB_CSUM(ipp->skb)));
+ /* ip_summed is CHECKSUM_PARTIAL, this should never happen. */
+ else
+ SSH_DEBUG(SSH_D_ERROR, ("Invalid HW checksum flag %d",
+ ipp->skb->ip_summed));
+#endif /* DEBUG_LIGHT */
+
+ /* Set nh pointer */
+ SSH_SKB_SET_NETHDR(ipp->skb, ipp->skb->data);
+ switch(ntohs(ipp->skb->protocol))
+ {
+ case ETH_P_IP:
+ neth = SSH_SKB_GET_NETHDR(ipp->skb);
+ if (neth == NULL)
+ {
+ SSH_DEBUG(SSH_D_ERROR, ("Could not access IP header"));
+ goto error;
+ }
+ SSH_SKB_SET_TRHDR(ipp->skb, neth + SSH_IPH4_HLEN(neth) * 4);
+
+#ifdef CONFIG_NETFILTER_DEBUG
+#ifdef LINUX_HAS_SKB_NFDEBUG
+ /* Mark SSH_NF_IP_PRE_ROUTING visited */
+ ipp->skb->nf_debug = (1 << SSH_NF_IP_PRE_ROUTING);
+#endif /* LINUX_HAS_SKB_NFDEBUG */
+#endif /* CONFIG_NETFILTER_DEBUG */
+
+#ifndef SSH_IPSEC_IP_ONLY_INTERCEPTOR
+ /* Remove padding from packet. */
+ pkt_len4 = SSH_IPH4_LEN(neth);
+ SSH_ASSERT(pkt_len4 >= SSH_IPH4_HDRLEN && pkt_len4 <= 0xffff);
+ if (pkt_len4 != ipp->skb->len)
+ {
+ SSH_DEBUG(SSH_D_NICETOKNOW, ("Trimming skb down from %d to %lu",
+ ipp->skb->len,
+ (unsigned long) pkt_len4));
+ skb_trim(ipp->skb, pkt_len4);
+ }
+#endif /* !SSH_IPSEC_IP_ONLY_INTERCEPTOR */
+
+ SSH_LINUX_STATISTICS(interceptor,
+ {
+ interceptor->stats.num_packets_sent++;
+ interceptor->stats.num_bytes_sent += (SshUInt64) ipp->skb->len;
+ });
+
+#ifdef SSH_LINUX_NF_PRE_ROUTING_AFTER_ENGINE
+ NF_HOOK_THRESH(PF_INET, SSH_NF_IP_PRE_ROUTING,
+ ipp->skb, ipp->skb->dev, NULL,
+ interceptor->linux_fn.ip_rcv_finish,
+ ssh_nf_in4.priority + 1);
+#else /* SSH_LINUX_NF_PRE_ROUTING_AFTER_ENGINE */
+ /* Call SSH_NF_IP_PREROUTING okfn() directly */
+ (*interceptor->linux_fn.ip_rcv_finish)(ipp->skb);
+#endif /* SSH_LINUX_NF_PRE_ROUTING_AFTER_ENGINE */
+ break;
+
+#ifdef SSH_LINUX_INTERCEPTOR_IPV6
+ case ETH_P_IPV6:
+ neth = SSH_SKB_GET_NETHDR(ipp->skb);
+ if (neth == NULL)
+ {
+ SSH_DEBUG(SSH_D_ERROR, ("Could not access IPv6 header"));
+ goto error;
+ }
+
+ ipproto = SSH_IPH6_NH(neth);
+ pkt_len6 = SSH_IPH6_LEN(neth) + SSH_IPH6_HDRLEN;
+
+ /* Parse hop-by-hop options and update IPv6 control buffer. */
+ SSH_LINUX_IP6CB(ipp->skb)->iif = ipp->skb->dev->ifindex;
+ SSH_LINUX_IP6CB(ipp->skb)->hop = 0;
+ SSH_LINUX_IP6CB(ipp->skb)->ra = 0;
+#ifdef LINUX_HAS_IP6CB_NHOFF
+ SSH_LINUX_IP6CB(ipp->skb)->nhoff = SSH_IPH6_OFS_NH;
+#endif /* LINUX_HAS_IP6CB_NHOFF */
+
+ offset = SSH_IPH6_HDRLEN;
+ /* Ipproto == HOPOPT */
+ if (ipproto == 0)
+ {
+ unsigned char *opt_ptr = neth + offset + 2;
+ int opt_len;
+
+ ipproto = SSH_IP6_EXT_COMMON_NH(neth + offset);
+ offset += SSH_IP6_EXT_COMMON_LENB(neth + offset);
+
+ while (opt_ptr < neth + offset)
+ {
+ opt_len = opt_ptr[1] + 2;
+ switch (opt_ptr[0])
+ {
+ /* PAD0 */
+ case 0:
+ opt_len = 1;
+ break;
+
+ /* PADN */
+ case 1:
+ break;
+
+ /* Jumbogram */
+ case 194:
+ /* Take packet len from option (skb->len is zero). */
+ pkt_len6 = SSH_GET_32BIT(&opt_ptr[2])
+ + sizeof(struct ipv6hdr);
+ break;
+
+ /* Router alert */
+ case 5:
+ SSH_LINUX_IP6CB(ipp->skb)->ra = opt_ptr - neth;
+ break;
+
+ /* Unknown / unsupported */
+ default:
+ /* Just skip unknown options. */
+ break;
+ }
+ opt_ptr += opt_len;
+ }
+ SSH_LINUX_IP6CB(ipp->skb)->hop = sizeof(struct ipv6hdr);
+
+#ifdef LINUX_HAS_IP6CB_NHOFF
+ SSH_LINUX_IP6CB(ipp->skb)->nhoff = sizeof(struct ipv6hdr);
+#endif /* LINUX_HAS_IP6CB_NHOFF */
+ }
+ SSH_SKB_SET_TRHDR(ipp->skb, neth + offset);
+
+ /* Remove padding from packet. */
+ SSH_ASSERT(pkt_len6 >= sizeof(struct ipv6hdr));
+ if (pkt_len6 != ipp->skb->len)
+ {
+ SSH_DEBUG(SSH_D_NICETOKNOW, ("Trimming skb down from %d to %lu",
+ ipp->skb->len,
+ (unsigned long) pkt_len6));
+ skb_trim(ipp->skb, pkt_len6);
+ }
+
+ SSH_LINUX_STATISTICS(interceptor,
+ {
+ interceptor->stats.num_packets_sent++;
+ interceptor->stats.num_bytes_sent += (SshUInt64) ipp->skb->len;
+ });
+
+#ifdef SSH_LINUX_NF_PRE_ROUTING_AFTER_ENGINE
+ NF_HOOK_THRESH(PF_INET6, SSH_NF_IP6_PRE_ROUTING, ipp->skb,
+ ipp->skb->dev, NULL,
+ interceptor->linux_fn.ip6_rcv_finish,
+ ssh_nf_out6.priority + 1);
+#else /* SSH_LINUX_NF_PRE_ROUTING_AFTER_ENGINE */
+ /* Call SSH_NF_IP6_PREROUTING okfn() directly */
+ (*interceptor->linux_fn.ip6_rcv_finish)(ipp->skb);
+#endif /* SSH_LINUX_NF_PRE_ROUTING_AFTER_ENGINE */
+ break;
+#endif /* SSH_LINUX_INTERCEPTOR_IPV6 */
+
+#ifndef SSH_IPSEC_IP_ONLY_INTERCEPTOR
+ case ETH_P_ARP:
+ SSH_LINUX_STATISTICS(interceptor,
+ {
+ interceptor->stats.num_packets_sent++;
+ interceptor->stats.num_bytes_sent += (SshUInt64) ipp->skb->len;
+ });
+#ifdef SSH_LINUX_NF_PRE_ROUTING_AFTER_ENGINE
+ NF_HOOK_THRESH(SSH_NFPROTO_ARP, NF_ARP_IN,
+ ipp->skb, ipp->skb->dev, NULL,
+ interceptor->linux_fn.arp_process,
+ ssh_nf_in_arp.priority + 1);
+#else /* SSH_LINUX_NF_PRE_ROUTING_AFTER_ENGINE */
+ /* Call NF_ARP_IN okfn() directly */
+ (*interceptor->linux_fn.arp_process)(ipp->skb);
+#endif /* SSH_LINUX_NF_PRE_ROUTING_AFTER_ENGINE */
+ break;
+#endif /* !SSH_IPSEC_IP_ONLY_INTERCEPTOR */
+
+ default:
+ SSH_DEBUG(SSH_D_ERROR,
+ ("skb->protocol 0x%x", htons(ipp->skb->protocol)));
+ SSH_NOTREACHED;
+ goto error;
+ }
+
+ /* All done. */
+ goto sent;
+ } /* SSH_PACKET_FROMADAPTER */
+
+ else
+ {
+ /* Not SSH_PACKET_FROMPROTOCOL or SSH_PACKET_FROMADAPTER. */
+ SSH_DEBUG(SSH_D_ERROR, ("Invalid packet direction flags"));
+ SSH_NOTREACHED;
+ goto error;
+ }
+
+ sent:
+ ipp->skb = NULL;
+
+ out:
+#ifdef INTERCEPTOR_IP_ALIGNS_PACKETS
+ /* pp can go NULL only with packet aligning. */
+
+ if (pp)
+#endif /* INTERCEPTOR_IP_ALIGNS_PACKETS */
+ ssh_interceptor_packet_free(pp);
+
+ /* Release net_device */
+ if (dev)
+ ssh_interceptor_release_netdev(dev);
+
+#ifdef SSH_IPSEC_IP_ONLY_INTERCEPTOR
+#ifdef SSH_LINUX_NF_FORWARD_AFTER_ENGINE
+ /* Release inbound net_device that was used for
+ FORWARD NF_HOOK traversal. */
+ if (in_dev)
+ ssh_interceptor_release_netdev(in_dev);
+#endif /* SSH_LINUX_NF_FORWARD_AFTER_ENGINE */
+#endif /* SSH_IPSEC_IP_ONLY_INTERCEPTOR */
+
+ return;
+
+ error:
+ SSH_LINUX_STATISTICS(interceptor, { interceptor->stats.num_errors++; });
+ goto out;
+}
+
+
+/******************************************************* General init/uninit */
+
+void ssh_interceptor_enable_interception(SshInterceptor interceptor,
+ Boolean enable)
+{
+
+ SSH_DEBUG(SSH_D_LOWOK, ("%s packet interception",
+ (enable ? "Enabling" : "Disabling")));
+ interceptor->enable_interception = enable;
+}
+
+/* Interceptor hook init. Utility function to initialize
+ individual hooks. */
+static Boolean
+ssh_interceptor_hook_init(struct SshLinuxHooksRec *hook)
+{
+ int rval;
+
+ SSH_ASSERT(hook->is_registered == FALSE);
+
+ if (hook->pf == PF_INET && hook->hooknum == SSH_NF_IP_PRE_ROUTING)
+ hook->priority = in_priority;
+
+ if (hook->pf == PF_INET && hook->hooknum == SSH_NF_IP_POST_ROUTING)
+ hook->priority = out_priority;
+
+#ifdef SSH_LINUX_INTERCEPTOR_IPV6
+ if (hook->pf == PF_INET6 && hook->hooknum == SSH_NF_IP6_PRE_ROUTING)
+ hook->priority = in6_priority;
+
+ if (hook->pf == PF_INET6 && hook->hooknum == SSH_NF_IP6_POST_ROUTING)
+ hook->priority = out6_priority;
+#endif /* SSH_LINUX_INTERCEPTOR_IPV6 */
+
+ hook->ops->hook = hook->hookfn;
+ hook->ops->pf = hook->pf;
+ hook->ops->hooknum = hook->hooknum;
+ hook->ops->priority = hook->priority;
+
+ rval = nf_register_hook(hook->ops);
+ if (rval < 0)
+ {
+ if (hook->is_mandatory)
+ {
+ printk(KERN_ERR
+ "VPNClient netfilter %s hook failed to install.\n",
+ hook->name);
+ return FALSE;
+ }
+ return TRUE;
+ }
+
+ hook->is_registered=TRUE;
+ return TRUE;
+}
+
+/* Utility function for uninstalling a single netfilter hook. */
+static void
+ssh_interceptor_hook_uninit(struct SshLinuxHooksRec *hook)
+{
+ if (hook->is_registered == FALSE)
+ return;
+
+ nf_unregister_hook(hook->ops);
+
+ hook->is_registered = FALSE;
+}
+
+/* IP/Network glue initialization. This must be called only
+ after the engine has "opened" the interceptor, and packet_callback()
+ has been set to a valid value. */
+Boolean
+ssh_interceptor_ip_glue_init(SshInterceptor interceptor)
+{
+ int i;
+
+ /* Verify that the hooks haven't been initialized yet. */
+ if (interceptor->hooks_installed)
+ {
+ SSH_DEBUG(2, ("init called when hooks are initialized already.\n"));
+ return TRUE;
+ }
+
+ /* Register all hooks */
+ for (i = 0; ssh_nf_hooks[i].name != NULL; i++)
+ {
+ if (ssh_interceptor_hook_init(&ssh_nf_hooks[i]) == FALSE)
+ goto fail;
+ }
+
+ interceptor->hooks_installed = TRUE;
+ return TRUE;
+
+ fail:
+ for (i = 0; ssh_nf_hooks[i].name != NULL; i++)
+ ssh_interceptor_hook_uninit(&ssh_nf_hooks[i]);
+ return FALSE;
+}
+
+/* Uninitialization of netfilter glue. */
+Boolean
+ssh_interceptor_ip_glue_uninit(SshInterceptor interceptor)
+{
+ int i;
+
+ /* Note that we do not perform concurrency control here!
+ We expect that we are essentially running single-threaded
+ in init/shutdown! */
+
+ if (interceptor->hooks_installed == FALSE)
+ return TRUE;
+
+ /* Unregister netfilter hooks */
+ for (i = 0; ssh_nf_hooks[i].name != NULL; i++)
+ ssh_interceptor_hook_uninit(&ssh_nf_hooks[i]);
+
+ interceptor->hooks_installed = FALSE;
+
+ return TRUE;
+}
diff --git a/drivers/interceptor/linux_ipm.c b/drivers/interceptor/linux_ipm.c
new file mode 100644
index 0000000..a9cb079
--- /dev/null
+++ b/drivers/interceptor/linux_ipm.c
@@ -0,0 +1,364 @@
+/* Netfilter Driver for IPSec VPN Client
+ *
+ * Copyright(c) 2012 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.
+ */
+
+/*
+ * linux_ipm.c
+ *
+ * Linux interceptor kernel to user space messaging.
+ *
+ */
+
+#include "linux_internal.h"
+
+extern SshInterceptor ssh_interceptor_context;
+
+/************************ Internal utility functions ************************/
+
+/* Use printk instead of SSH_DEBUG macros. */
+#ifdef DEBUG_LIGHT
+#define SSH_LINUX_IPM_DEBUG(x...) if (net_ratelimit()) printk(KERN_INFO x)
+#define SSH_LINUX_IPM_WARN(x...) panic(x)
+#endif /* DEBUG_LIGHT */
+
+#ifndef SSH_LINUX_IPM_DEBUG
+#define SSH_LINUX_IPM_DEBUG(x...)
+#define SSH_LINUX_IPM_WARN(x...) printk(KERN_CRIT x)
+#endif /* SSH_LINUX_IPM_DEBUG */
+
+/************************* Ipm message alloc / free *************************/
+
+static void interceptor_ipm_message_free_internal(SshInterceptor interceptor,
+ SshInterceptorIpmMsg msg)
+{
+ SSH_ASSERT(interceptor != NULL);
+ SSH_ASSERT(msg != NULL);
+
+ if (msg->buf)
+ ssh_free(msg->buf);
+ msg->buf = NULL;
+
+ SSH_LINUX_STATISTICS(interceptor,
+ {
+ interceptor->stats.ipm_send_queue_len--;
+ interceptor->stats.ipm_send_queue_bytes -= (SshUInt64) msg->len;
+ });
+
+ if (msg->emergency_mallocated)
+ {
+ ssh_free(msg);
+ }
+ else
+ {
+ msg->next = interceptor->ipm.msg_freelist;
+ interceptor->ipm.msg_freelist = msg;
+ msg->prev = NULL;
+ }
+}
+
+void interceptor_ipm_message_free(SshInterceptor interceptor,
+ SshInterceptorIpmMsg msg)
+{
+ local_bh_disable();
+ write_lock(&interceptor->ipm.lock);
+ interceptor_ipm_message_free_internal(interceptor, msg);
+ write_unlock(&interceptor->ipm.lock);
+ local_bh_enable();
+}
+
+static SshInterceptorIpmMsg
+interceptor_ipm_message_alloc(SshInterceptor interceptor,
+ Boolean reliable,
+ size_t len)
+{
+ SshInterceptorIpmMsg msg = NULL;
+
+ SSH_ASSERT(interceptor != NULL);
+
+ /* Try to take a message from freelist. */
+ if (interceptor->ipm.msg_freelist)
+ {
+ msg = interceptor->ipm.msg_freelist;
+ interceptor->ipm.msg_freelist = msg->next;
+ }
+
+#if SSH_LINUX_MAX_IPM_MESSAGES < 2000
+#error "SSH_LINUX_MAX_IPM_MESSAGES is too low"
+#endif /* SSH_LINUX_MAX_IPM_MESSAGES */
+
+ /* Try to allocate a new message. */
+ else if (interceptor->ipm.msg_allocated < SSH_LINUX_MAX_IPM_MESSAGES)
+ {
+ msg = ssh_calloc(1, sizeof(*msg));
+ if (msg != NULL)
+ {
+ interceptor->ipm.msg_allocated++;
+ }
+ }
+
+ /* Try to reuse last unreliable message in send queue. */
+ if (msg == NULL && reliable == TRUE)
+ {
+ /* This is a reliable message, reuse last unreliable message. */
+ if (interceptor->ipm.send_queue_num_unreliable > 0)
+ {
+ for (msg = interceptor->ipm.send_queue_tail;
+ msg != NULL;
+ msg = msg->prev)
+ {
+ if (msg->reliable == 0)
+ {
+ if (msg->next != NULL)
+ msg->next->prev = msg->prev;
+
+ if (msg->prev != NULL)
+ msg->prev->next = msg->next;
+
+ if (msg == interceptor->ipm.send_queue)
+ interceptor->ipm.send_queue = msg->next;
+
+ if (msg == interceptor->ipm.send_queue_tail)
+ interceptor->ipm.send_queue_tail = msg->prev;
+
+ SSH_ASSERT(interceptor->ipm.send_queue_num_unreliable > 0);
+ interceptor->ipm.send_queue_num_unreliable--;
+
+ SSH_LINUX_STATISTICS(interceptor,
+ {
+ interceptor->stats.ipm_send_queue_len--;
+ interceptor->stats.ipm_send_queue_bytes
+ -= (SshUInt64) msg->len;
+ });
+
+ ssh_free(msg->buf);
+ break;
+ }
+ }
+ }
+
+ /* Last resort, malloc message. */
+ if (msg == NULL)
+ {
+ msg = ssh_calloc(1, sizeof(*msg));
+ if (msg != NULL)
+ msg->emergency_mallocated = 1;
+ }
+ }
+
+ if (msg)
+ SSH_LINUX_STATISTICS(interceptor,
+ {
+ interceptor->stats.ipm_send_queue_len++;
+ interceptor->stats.ipm_send_queue_bytes += (SshUInt64) len;
+ });
+
+ return msg;
+}
+
+void interceptor_ipm_message_freelist_uninit(SshInterceptor interceptor)
+{
+ SshInterceptorIpmMsg msg;
+ int freelist_len;
+
+ local_bh_disable();
+ write_lock(&interceptor->ipm.lock);
+
+ SSH_ASSERT(atomic_read(&interceptor->ipm.open) == 0);
+
+ while (interceptor->ipm.msg_freelist != NULL)
+ {
+ msg = interceptor->ipm.msg_freelist;
+ interceptor->ipm.msg_freelist = msg->next;
+ SSH_ASSERT(msg->buf == NULL);
+ ssh_free(msg);
+ interceptor->ipm.msg_allocated--;
+ }
+
+ freelist_len = interceptor->ipm.msg_allocated;
+
+ write_unlock(&interceptor->ipm.lock);
+ local_bh_enable();
+
+ if (freelist_len)
+ SSH_LINUX_IPM_WARN("Memory leak detected: %d ipm messages leaked!\n",
+ freelist_len);
+}
+
+
+/***************************** Process message from ipm ********************/
+
+ssize_t ssh_interceptor_receive_from_ipm(unsigned char *data, size_t len)
+{
+ SshUInt32 msg_len;
+ SshUInt8 msg_type;
+
+ /* Need a complete header. */
+ if (len < 5)
+ return 0;
+
+ /* Parse message header. */
+ msg_len = SSH_GET_32BIT(data) - 1;
+ msg_type = SSH_GET_8BIT(data + 4);
+
+ /* Need a complete message. */
+ if (msg_len > (len - 5))
+ return 0;
+
+ /* Pass message to engine. */
+ local_bh_disable();
+
+ ssh_engine_packet_from_ipm(ssh_interceptor_context->engine,
+ msg_type, data + 5, msg_len);
+
+ local_bh_enable();
+
+ return msg_len + 5;
+}
+
+
+/***************************** Send to ipm *********************************/
+
+Boolean ssh_interceptor_send_to_ipm(unsigned char *data, size_t len,
+ Boolean reliable, void *machine_context)
+{
+ SshInterceptorIpmMsg msg = NULL;
+
+ local_bh_disable();
+ write_lock(&ssh_interceptor_context->ipm.lock);
+
+ /* Check ipm channel status */
+ if (atomic_read(&ssh_interceptor_context->ipm.open) == 0)
+ {
+ write_unlock(&ssh_interceptor_context->ipm.lock);
+ local_bh_enable();
+ ssh_free(data);
+ SSH_LINUX_IPM_DEBUG("ipm channel closed, dropping ipm message len %d\n",
+ (int) len);
+ return FALSE;
+ }
+
+ /* Allocate a message. */
+ msg = interceptor_ipm_message_alloc(ssh_interceptor_context, reliable, len);
+ if (msg == NULL)
+ {
+ write_unlock(&ssh_interceptor_context->ipm.lock);
+ local_bh_enable();
+
+ if (reliable)
+ SSH_LINUX_IPM_WARN("Dropping reliable ipm message type %d len %d\n",
+ (int) (len < 5 ? -1 : data[4]), (int) len);
+ else
+ SSH_LINUX_IPM_DEBUG("Dropping unreliable ipm message type %d "
+ "len %d\n",
+ (int) (len < 5 ? -1 : data[4]), (int) len);
+ ssh_free(data);
+ return FALSE;
+ }
+
+ /* Fill message structure. */
+ msg->buf = data;
+ msg->len = len;
+ msg->offset = 0;
+ if (reliable)
+ msg->reliable = 1;
+
+ /* Append message to send queue tail. */
+ msg->prev = ssh_interceptor_context->ipm.send_queue_tail;
+ ssh_interceptor_context->ipm.send_queue_tail = msg;
+ msg->next = NULL;
+ if (msg->prev)
+ msg->prev->next = msg;
+
+ if (ssh_interceptor_context->ipm.send_queue == NULL)
+ ssh_interceptor_context->ipm.send_queue = msg;
+
+ if (msg->reliable == 0)
+ {
+ ssh_interceptor_context->ipm.send_queue_num_unreliable++;
+ SSH_ASSERT(ssh_interceptor_context->ipm.send_queue_num_unreliable != 0);
+ }
+
+ write_unlock(&ssh_interceptor_context->ipm.lock);
+ local_bh_enable();
+
+ /* Wake up reader. */
+ wake_up_interruptible(&ssh_interceptor_context->ipm_proc_entry.wait_queue);
+
+ return TRUE;
+}
+
+
+/**************************** Ipm channel open / close **********************/
+
+void interceptor_ipm_open(SshInterceptor interceptor)
+{
+
+ local_bh_disable();
+ write_lock(&interceptor->ipm.lock);
+
+ /* Assert that send queue is empty */
+ SSH_ASSERT(interceptor->ipm.send_queue == NULL);
+
+ /* Mark ipm channel open */
+ atomic_set(&interceptor->ipm.open, 1);
+
+ write_unlock(&interceptor->ipm.lock);
+ local_bh_enable();
+}
+
+void interceptor_ipm_close(SshInterceptor interceptor)
+{
+ SshInterceptorIpmMsg msg, list;
+
+ local_bh_disable();
+ write_lock(&interceptor->ipm.lock);
+
+ /* Mark ipm channel closed */
+ atomic_set(&interceptor->ipm.open, 0);
+
+ /* Clear send queue */
+ list = interceptor->ipm.send_queue;
+ interceptor->ipm.send_queue = NULL;
+ interceptor->ipm.send_queue_tail = NULL;
+
+ write_unlock(&interceptor->ipm.lock);
+ local_bh_enable();
+
+ /* Free all ipm messages from send queue. */
+ while (list != NULL)
+ {
+ msg = list;
+ list = msg->next;
+ interceptor_ipm_message_free(interceptor, msg);
+ }
+}
+
+
+/***************************** Init / uninit ********************************/
+
+Boolean ssh_interceptor_ipm_init(SshInterceptor interceptor)
+{
+ /* Initialize ipm structure */
+ atomic_set(&interceptor->ipm.open, 0);
+ rwlock_init(&interceptor->ipm.lock);
+
+ /* Initialize /proc interface */
+ return ssh_interceptor_proc_init(interceptor);
+}
+
+void ssh_interceptor_ipm_uninit(SshInterceptor interceptor)
+{
+ /* Uninit /proc interface */
+ ssh_interceptor_proc_uninit(interceptor);
+
+ interceptor_ipm_close(interceptor);
+
+ /* Free ipm messages.*/
+ interceptor_ipm_message_freelist_uninit(interceptor);
+}
diff --git a/drivers/interceptor/linux_kernel_alloc.c b/drivers/interceptor/linux_kernel_alloc.c
new file mode 100644
index 0000000..5f4c57f
--- /dev/null
+++ b/drivers/interceptor/linux_kernel_alloc.c
@@ -0,0 +1,182 @@
+/* Netfilter Driver for IPSec VPN Client
+ *
+ * Copyright(c) 2012 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.
+ */
+
+/*
+ * linux_kernel_alloc.c
+ *
+ * Linux interceptor implementation of kernel memory allocation API.
+ *
+ */
+#include "linux_internal.h"
+#include "kernel_alloc.h"
+
+/* Malloc overhead:
+ <uint32> size (highest bit used for vmalloc indication)
+ <uint32> magic
+*/
+#define SSH_MALLOC_OVERHEAD (sizeof(SshUInt32) * 2)
+
+#define SSH_MALLOC_FLAG_LARGE (1 << 31)
+#define SSH_MALLOC_MAGIC 0x32085242
+#define SSH_MALLOC_MAGIC_FREED 0x00420042
+
+/* The maximum allocation size of kmalloc is 128K, however because of
+ memory fragmentation it's still insecure to allocate areas of many
+ pages with kmalloc. So for areas bigger than one page (usually 4K)
+ vmalloc() should be used. */
+#define SSH_NORMAL_MALLOC_MAX (128 << 10)
+
+/* The maximum allocation size of __get_free_pages is 2M, that is the
+ maximum order of alloc_pages() is 9 (2^9 of 4K pages), sometimes
+ erroneous code can cause arbitarily long allocations so this is
+ good sanity check. In general, allocations should be fairly
+ small. */
+#define SSH_VMALLOC_MAX (2 << 20)
+
+/* When do we shift to using vmalloc? In truth this should be ~equal
+ to normal-alloc-max. */
+#define SSH_VMALLOC_THRESHOLD (SSH_NORMAL_MALLOC_MAX)
+
+#ifdef DEBUG_LIGHT
+extern SshInterceptor ssh_interceptor_context;
+#endif /* DEBUG_LIGHT */
+
+
+void *
+ssh_kernel_alloc(size_t size, SshUInt32 flag)
+{
+ void *ptr;
+ int malloc_flag;
+ int total_size = size + SSH_MALLOC_OVERHEAD;
+ Boolean is_vmalloc = FALSE;
+
+ if (flag & SSH_KERNEL_ALLOC_WAIT)
+ malloc_flag = GFP_KERNEL;
+ else
+ {
+ SSH_ASSERT((flag & SSH_KERNEL_ALLOC_NOWAIT) ==
+ SSH_KERNEL_ALLOC_NOWAIT);
+ malloc_flag = GFP_ATOMIC;
+ }
+ if (flag & SSH_KERNEL_ALLOC_DMA)
+ {
+ SSH_ASSERT(malloc_flag == GFP_ATOMIC);
+ malloc_flag |= GFP_DMA;
+
+ if (total_size > SSH_NORMAL_MALLOC_MAX)
+ return NULL;
+ }
+ else
+ if (total_size > SSH_VMALLOC_THRESHOLD)
+ {
+ if (total_size > SSH_VMALLOC_MAX)
+ return NULL;
+
+ is_vmalloc = TRUE;
+ }
+ if (is_vmalloc)
+ {
+ unsigned long order;
+
+ /* Round up to nearest page size. The pages allocated with
+ __get_free_pages() are guaranteed to be contiguous in memory,
+ but you get one only if the requested amount of contiguous
+ pages are available. Linux doesn't currently have any
+ mechanisms for smart defragmentation of physical memory and
+ even if we had them they couldn't be fully reliable. So be
+ careful what you ask for, if you ask for too large a chunk of
+ memory you might end up not getting any at all. */
+ total_size = ((total_size + PAGE_SIZE - 1) / PAGE_SIZE) * PAGE_SIZE;
+ for (order = 0; ((1 << order) * PAGE_SIZE) < total_size; order++);
+
+ if (order >= MAX_ORDER)
+ return NULL;
+
+ ptr = (char *)__get_free_pages(malloc_flag, order);
+ }
+ else
+ ptr = kmalloc(total_size, malloc_flag);
+
+ if (ptr == NULL)
+ return NULL;
+
+ /* Log all allocs to first entry */
+ SSH_LINUX_STATISTICS(ssh_interceptor_context,
+ {
+ ssh_interceptor_context->stats.allocated_memory += (SshUInt64) total_size;
+
+ if (ssh_interceptor_context->stats.allocated_memory >
+ ssh_interceptor_context->stats.allocated_memory_max)
+ ssh_interceptor_context->stats.allocated_memory_max =
+ (SshUInt64) ssh_interceptor_context->stats.allocated_memory;
+
+ if (is_vmalloc)
+ ssh_interceptor_context->stats.num_allocations_large++;
+ else
+ ssh_interceptor_context->stats.num_allocations++;
+
+ ssh_interceptor_context->stats.num_allocations_total++;
+ });
+
+ /* Fill in the size and magic */
+ ((SshUInt32 *) ptr)[0] = total_size
+ | (is_vmalloc ? SSH_MALLOC_FLAG_LARGE : 0);
+
+#ifdef DEBUG_LIGHT
+ ((SshUInt32 *) ptr)[1] = SSH_MALLOC_MAGIC;
+#endif /* DEBUG_LIGHT */
+
+ return ((char *) ptr) + SSH_MALLOC_OVERHEAD;
+}
+
+void
+ssh_kernel_free(void *ptr)
+{
+ Boolean is_vmalloc;
+ SshUInt32 size;
+
+#ifdef DEBUG_LIGHT
+ /* Sanity check */
+ if (((SshUInt32 *) ptr)[-1] != SSH_MALLOC_MAGIC)
+ SSH_FATAL("ssh_kernel_free: Malloc object corrupted (invalid magic %x)",
+ ((unsigned int *) ptr)[-1]);
+
+ /* Set this to distinctive value to make sure we detect double free. */
+ ((SshUInt32 *) ptr)[-1] = SSH_MALLOC_MAGIC_FREED;
+#endif /* DEBUG_LIGHT */
+
+ size = ((SshUInt32 *) ptr)[-2];
+ is_vmalloc = (size & SSH_MALLOC_FLAG_LARGE) != 0;
+
+ if (is_vmalloc)
+ size &= ~SSH_MALLOC_FLAG_LARGE;
+
+ /* Statistics */
+ SSH_LINUX_STATISTICS(ssh_interceptor_context,
+ {
+ ssh_interceptor_context->stats.allocated_memory -= (SshUInt64) size;
+ if (is_vmalloc)
+ ssh_interceptor_context->stats.num_allocations_large--;
+ else
+ ssh_interceptor_context->stats.num_allocations--;
+
+ ssh_interceptor_context->stats.num_allocations_total--;
+ });
+
+ /* Free the real block */
+ if (is_vmalloc)
+ {
+ SshUInt32 order;
+ for (order = 0; ((1 << order) * PAGE_SIZE) < size; order++);
+ free_pages((unsigned long)((char *) ptr - SSH_MALLOC_OVERHEAD), order);
+ }
+ else
+ kfree((char *) ptr - SSH_MALLOC_OVERHEAD);
+}
diff --git a/drivers/interceptor/linux_main.c b/drivers/interceptor/linux_main.c
new file mode 100644
index 0000000..ba92502
--- /dev/null
+++ b/drivers/interceptor/linux_main.c
@@ -0,0 +1,533 @@
+/* Netfilter Driver for IPSec VPN Client
+ *
+ * Copyright(c) 2012 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.
+ */
+
+/*
+ * linux_main.c
+ *
+ * Linux interceptor kernel module main.
+ *
+ */
+
+#include "linux_internal.h"
+#include "sshinet.h"
+
+#include <linux/kernel.h>
+
+#ifdef DEBUG_LIGHT
+unsigned int ssh_debug_level = 0;
+MODULE_PARM_DESC(ssh_debug_level, "Debug level");
+module_param(ssh_debug_level, uint, 0444);
+#endif /* DEBUG_LIGHT */
+
+/* Global interceptor object */
+SshInterceptor ssh_interceptor_context = NULL;
+
+/* Preallocated interceptor object */
+static SshInterceptorStruct interceptor_struct;
+
+/******************************** Utility functions *************************/
+
+void
+ssh_interceptor_notify_ipm_open(SshInterceptor interceptor)
+{
+ local_bh_disable();
+
+ /* Tell engine the PM connection is open. */
+ ssh_engine_notify_ipm_open(interceptor->engine);
+
+ local_bh_enable();
+}
+
+void
+ssh_interceptor_notify_ipm_close(SshInterceptor interceptor)
+{
+ local_bh_disable();
+
+ /* Tell engine the PM connection is closed. */
+ ssh_engine_notify_ipm_close(interceptor->engine);
+
+ /* Disable packet interception now that ipm has disconnected. */
+ interceptor->enable_interception = FALSE;
+ ssh_interceptor_dst_entry_cache_flush(interceptor);
+
+ local_bh_enable();
+}
+
+/******************************* Interceptor API ****************************/
+
+/* Opens the packet interceptor. This must be called before using any
+ other interceptor functions. This registers the callbacks that the
+ interceptor will use to notify the higher levels of received packets
+ or changes in the interface list. The interface callback will be called
+ once either during this call or soon after this has returned.
+ The `packet_cb' callback will be called whenever a packet is received
+ from either a network adapter or a protocol stack. It is guaranteed that
+ this will not be called until from the bottom of the event loop after the
+ open call has returned.
+
+ The `interfaces_cb' callback will be called once soon after opening the
+ interceptor, however earliest from the bottom of the event loop after the
+ open call has returned. From then on, it will be called whenever there is
+ a change in the interface list (e.g., the IP address of an interface is
+ changed, or a PPP interface goes up or down).
+
+ The `callback_context' argument is passed to the callbacks. */
+
+Boolean
+ssh_interceptor_open(void *machine_context,
+ SshInterceptorPacketCB packet_cb,
+ SshInterceptorInterfacesCB interfaces_cb,
+ SshInterceptorRouteChangeCB route_cb,
+ void *callback_context,
+ SshInterceptor * interceptor_return)
+{
+ SshInterceptor interceptor;
+
+ interceptor = ssh_interceptor_context;
+ if (interceptor->engine_open)
+ return FALSE;
+
+ local_bh_disable();
+
+ SSH_DEBUG(2, ("interceptor opened"));
+
+ interceptor->engine_open = TRUE;
+ interceptor->packet_callback = packet_cb;
+ interceptor->interfaces_callback = interfaces_cb;
+ interceptor->route_callback = route_cb;
+ interceptor->callback_context = callback_context;
+
+ /* Return the global interceptor object. */
+ *interceptor_return = (void *) interceptor;
+
+ local_bh_enable();
+ return TRUE;
+}
+
+/* Closes the packet interceptor. No more packet or interface callbacks
+ will be received from the interceptor after this returns. Destructors
+ may still get called even after this has returned.
+
+ It is illegal to call any packet interceptor functions (other than
+ ssh_interceptor_open) after this call. It is, however, legal to call
+ destructors for any previously returned packets even after calling this.
+ Destructors for any packets previously supplied to one of the send
+ functions will get called before this function returns. */
+
+void
+ssh_interceptor_close(SshInterceptor interceptor)
+{
+ /* all closing is done in ssh_interceptor_uninit() */
+ interceptor->engine_open = FALSE;
+ return;
+}
+
+/* Dummy function callback after interceptor has been stopped */
+static void
+ssh_interceptor_dummy_interface_cb(SshUInt32 num_interfaces,
+ SshInterceptorInterface *ifs,
+ void *context)
+{
+ /* Do nothing */
+ return;
+}
+
+/* Dummy function which packets get routed to after ssh_interceptor_stop()
+ has been called. */
+static void
+ssh_interceptor_dummy_packet_cb(SshInterceptorPacket pp, void *ctx)
+{
+ ssh_interceptor_packet_free(pp);
+}
+
+/* Stops the packet interceptor. After this call has returned, no new
+ calls to the packet and interfaces callbacks will be made. The
+ interceptor keeps track of how many threads are processing packet,
+ interface, or have pending route callbacks, and this function
+ returns TRUE if there are no callbacks/pending calls to those functions.
+ This returns FALSE if threads are still executing in those callbacks
+ or routing callbacks are pending.
+
+ After calling this function, the higher-level code should wait for
+ packet processing to continue, free all packet structures received
+ from that interceptor, and then close ssh_interceptor_close. It is
+ not an error to call this multiple times (the latter calls are
+ ignored). */
+
+Boolean
+ssh_interceptor_stop(SshInterceptor interceptor)
+{
+ SSH_DEBUG(2, ("interceptor stopping"));
+
+ /* 'interceptor_lock protects the 'interfaces_callback'
+ and 'num_interface_callbacks'. */
+ ssh_kernel_mutex_lock(interceptor->interceptor_lock);
+
+ if (interceptor->num_interface_callbacks)
+ {
+ ssh_kernel_mutex_unlock(interceptor->interceptor_lock);
+ SSH_DEBUG(SSH_D_ERROR,
+ ("%d interface callbacks pending, can't stop",
+ interceptor->num_interface_callbacks));
+ return FALSE;
+ }
+
+ /* No more interfaces are delivered to the engine after this. */
+ interceptor->interfaces_callback = ssh_interceptor_dummy_interface_cb;
+
+ /* Route callback is currently not used. */
+ interceptor->route_callback = NULL_FNPTR;
+
+ ssh_kernel_mutex_unlock(interceptor->interceptor_lock);
+
+ /* After this the engine will receive no more packets from
+ the interceptor, although the netfilter hooks are still
+ installed. */
+
+ /* Set packet_callback to point to our dummy_db */
+ rcu_assign_pointer(interceptor->packet_callback,
+ ssh_interceptor_dummy_packet_cb);
+
+ /* Wait for state synchronization. */
+ local_bh_enable();
+ synchronize_rcu();
+ local_bh_disable();
+
+ /* Callback context can now be safely zeroed, as both
+ the interface_callback and the packet_callback point to
+ our dummy_cb, and all kernel threads have returned from
+ the engine. */
+ interceptor->callback_context = NULL;
+
+ SSH_DEBUG(2, ("interceptor stopped"));
+
+ return TRUE;
+}
+
+/************** Interceptor uninitialization break-down. *******************/
+
+static void
+ssh_interceptor_uninit_external_interfaces(SshInterceptor interceptor)
+{
+ ssh_interceptor_virtual_adapter_uninit(interceptor);
+
+ /* Remove netfilter hooks */
+ ssh_interceptor_ip_glue_uninit(interceptor);
+}
+
+static void
+ssh_interceptor_uninit_engine(SshInterceptor interceptor)
+{
+ /* Stop packet processing engine */
+ if (interceptor->engine != NULL)
+ {
+ while (ssh_engine_stop(interceptor->engine) == FALSE)
+ {
+ local_bh_enable();
+ schedule();
+ mdelay(300);
+ local_bh_disable();
+ }
+ interceptor->engine = NULL;
+ }
+
+ /* Free packet data structure */
+ ssh_interceptor_packet_freelist_uninit(interceptor);
+}
+
+static void
+ssh_interceptor_uninit_kernel_services(void)
+{
+ /* Remove interface event handlers and free interface table. */
+ ssh_interceptor_iface_uninit(ssh_interceptor_context);
+
+ ssh_interceptor_dst_entry_cache_uninit(ssh_interceptor_context);
+
+ /* Uninitialize ipm channel */
+ ssh_interceptor_ipm_uninit(ssh_interceptor_context);
+
+ /* Free locks */
+ ssh_kernel_mutex_free(ssh_interceptor_context->interceptor_lock);
+ ssh_interceptor_context->interceptor_lock = NULL;
+ ssh_kernel_mutex_free(ssh_interceptor_context->packet_lock);
+ ssh_interceptor_context->packet_lock = NULL;
+
+ ssh_interceptor_context = NULL;
+}
+
+/* Interceptor uninitialization. Called by cleanup_module() with
+ softirqs disabled. */
+static int
+ssh_interceptor_uninit(void)
+{
+ /* Uninitialize external interfaces. We leave softirqs enabled for
+ this as we have to make calls into the netfilter API that will
+ execute scheduling in Linux 2.6. */
+ ssh_interceptor_uninit_external_interfaces(ssh_interceptor_context);
+
+ /* Uninitialize engine. Via ssh_interceptor_stop() this
+ function makes sure that no callouts to the interceptor
+ are in progress after it returns. ssh_interceptor_stop()
+ _WILL_ grab the interceptor_lock, so make sure that it
+ is not held.*/
+ local_bh_disable();
+ ssh_interceptor_uninit_engine(ssh_interceptor_context);
+
+ /* Uninitialize basic kernel services to the engine and the
+ interceptor. This frees all remaining memory. Note that all locks
+ are also freed here, so none of them can be held. */
+ ssh_interceptor_uninit_kernel_services();
+ local_bh_enable();
+
+ return 0;
+}
+
+
+/************** Interceptor initialization break-down. *********************/
+
+
+int
+ssh_interceptor_init_kernel_services(void)
+{
+ /* Interceptor object is always preallocated. */
+ SSH_ASSERT(ssh_interceptor_context == NULL);
+ memset(&interceptor_struct, 0, sizeof(interceptor_struct));
+ ssh_interceptor_context = &interceptor_struct;
+
+#ifdef DEBUG_LIGHT
+ spin_lock_init(&ssh_interceptor_context->statistics_lock);
+#endif /* DEBUG_LIGHT */
+
+ /* General init */
+ ssh_interceptor_context->interceptor_lock = ssh_kernel_mutex_alloc();
+ ssh_interceptor_context->packet_lock = ssh_kernel_mutex_alloc();
+
+ if (ssh_interceptor_context->interceptor_lock == NULL
+ || ssh_interceptor_context->packet_lock == NULL)
+ goto error;
+
+ rwlock_init(&ssh_interceptor_context->if_table_lock);
+
+ /* Init packet data structure */
+ if (!ssh_interceptor_packet_freelist_init(ssh_interceptor_context))
+ {
+ printk(KERN_ERR
+ "VPNClient packet processing engine failed to start "
+ "(out of memory).\n");
+ goto error;
+ }
+
+ if (ssh_interceptor_dst_entry_cache_init(ssh_interceptor_context) == FALSE)
+ {
+ printk(KERN_ERR "VPNClient packet processing engine "
+ "failed to start, dst cache initialization failed.");
+ goto error;
+ }
+
+ /* Initialize ipm channel */
+ if (!ssh_interceptor_ipm_init(ssh_interceptor_context))
+ {
+ printk(KERN_ERR
+ "VPNClient packet processing engine failed to start "
+ "(proc filesystem initialization error)\n");
+ goto error1;
+ }
+
+ return 0;
+
+ error1:
+ local_bh_disable();
+ ssh_interceptor_packet_freelist_uninit(ssh_interceptor_context);
+ local_bh_enable();
+
+ error:
+ ssh_interceptor_dst_entry_cache_uninit(ssh_interceptor_context);
+ ssh_kernel_mutex_free(ssh_interceptor_context->interceptor_lock);
+ ssh_interceptor_context->interceptor_lock = NULL;
+
+ ssh_kernel_mutex_free(ssh_interceptor_context->packet_lock);
+ ssh_interceptor_context->packet_lock = NULL;
+
+ ssh_interceptor_context = NULL;
+
+ return -ENOMEM;
+}
+
+int
+ssh_interceptor_init_external_interfaces(SshInterceptor interceptor)
+{
+ /* Register interface notifiers. */
+ if (!ssh_interceptor_iface_init(interceptor))
+ {
+ printk(KERN_ERR
+ "VPNClient packet processing engine failed to start "
+ "(interface notifier installation error).\n");
+ goto error0;
+ }
+
+ /* Register the firewall hooks. */
+ if (!ssh_interceptor_ip_glue_init(interceptor))
+ {
+ printk(KERN_ERR
+ "VPNClient packet processing engine failed to start "
+ "(firewall glue installation error).\n");
+ goto error1;
+ }
+
+ return 0;
+
+ error1:
+
+ local_bh_disable();
+ ssh_interceptor_iface_uninit(interceptor);
+ local_bh_enable();
+ error0:
+
+ return -EBUSY;
+}
+
+int
+ssh_interceptor_init_engine(SshInterceptor interceptor)
+{
+ int start_cnt;
+
+ /* Initialize the IPsec engine */
+
+ interceptor->engine = NULL;
+ for (start_cnt = 0;
+ start_cnt < 3 && interceptor->engine == NULL;
+ start_cnt++)
+ {
+ /* In theory, it would be nice and proper to disable softirqs
+ here and enable them after we exit engine_start(), but then
+ we could not allocate memory without GFP_ATOMIC in the
+ engine initialization, which would not be nice. Therefore
+ we leave softirqs open here, and disable them for the
+ duration of ssh_interceptor_open(). */
+ interceptor->engine = ssh_engine_start(ssh_interceptor_send_to_ipm,
+ interceptor,
+ SSH_LINUX_ENGINE_FLAGS);
+ if (interceptor->engine == NULL)
+ {
+ schedule();
+ mdelay(500);
+ }
+ }
+
+ if (interceptor->engine == NULL)
+ {
+ printk(KERN_ERR
+ "VPNClient packet processing engine failed to start "
+ "(engine start error).\n");
+ goto error;
+ }
+
+ return 0;
+
+ error:
+ if (interceptor->engine != NULL)
+ {
+ local_bh_disable();
+ while (ssh_engine_stop(interceptor->engine) == FALSE)
+ {
+ local_bh_enable();
+ schedule();
+ mdelay(300);
+ local_bh_disable();
+ }
+ local_bh_enable();
+ interceptor->engine = NULL;
+ }
+
+ return -EBUSY;
+}
+
+/* Interceptor initialization. Called by init_module(). */
+int ssh_interceptor_init(void)
+{
+ int ret;
+
+ /* Print version info for log files */
+ printk(KERN_INFO "VPNClient built on " __DATE__ " " __TIME__ "\n");
+
+ ret = ssh_interceptor_init_kernel_services();
+ if (ret != 0)
+ goto error0;
+
+ SSH_ASSERT(ssh_interceptor_context != NULL);
+
+ ret = ssh_interceptor_hook_magic_init();
+ if (ret != 0)
+ goto error1;
+
+ ret = ssh_interceptor_virtual_adapter_init(ssh_interceptor_context);
+ if (ret != 0)
+ goto error1;
+
+ ret = ssh_interceptor_init_engine(ssh_interceptor_context);
+ if (ret != 0)
+ goto error4;
+
+ ret = ssh_interceptor_init_external_interfaces(ssh_interceptor_context);
+ if (ret != 0)
+ goto error5;
+
+ return 0;
+
+ error5:
+ local_bh_disable();
+ ssh_interceptor_uninit_engine(ssh_interceptor_context);
+ local_bh_enable();
+
+ error4:
+ ssh_interceptor_clear_ifaces(ssh_interceptor_context);
+ ssh_interceptor_virtual_adapter_uninit(ssh_interceptor_context);
+
+ error1:
+ local_bh_disable();
+ ssh_interceptor_uninit_kernel_services();
+ local_bh_enable();
+
+ error0:
+ return ret;
+}
+
+MODULE_DESCRIPTION(SSH_LINUX_INTERCEPTOR_MODULE_DESCRIPTION);
+
+int __init ssh_init_module(void)
+{
+ if (ssh_interceptor_init() != 0)
+ return -EIO;
+ return 0;
+}
+
+void __exit ssh_cleanup_module(void)
+{
+ if (ssh_interceptor_uninit() != 0)
+ {
+ printk("ssh_interceptor: module can't be removed.");
+ return;
+ }
+}
+
+void ssh_linux_module_dec_use_count()
+{
+ module_put(THIS_MODULE);
+}
+
+int
+ssh_linux_module_inc_use_count()
+{
+ return try_module_get(THIS_MODULE);
+}
+
+MODULE_LICENSE("GPL");
+module_init(ssh_init_module);
+module_exit(ssh_cleanup_module);
diff --git a/drivers/interceptor/linux_mutex.c b/drivers/interceptor/linux_mutex.c
new file mode 100644
index 0000000..7a9fae7
--- /dev/null
+++ b/drivers/interceptor/linux_mutex.c
@@ -0,0 +1,115 @@
+/* Netfilter Driver for IPSec VPN Client
+ *
+ * Copyright(c) 2012 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.
+ */
+
+/*
+ * linux_mutex.c
+ *
+ * Linux interceptor kernel mutex API implementation.
+ *
+ */
+
+#include "linux_internal.h"
+#include "linux_mutex_internal.h"
+
+extern SshInterceptor ssh_interceptor_context;
+
+Boolean ssh_kernel_mutex_init(SshKernelMutex mutex)
+{
+ spin_lock_init(&mutex->lock);
+
+#ifdef DEBUG_LIGHT
+ mutex->taken = FALSE;
+ mutex->jiffies = 0;
+#endif
+ return TRUE;
+}
+
+/* Allocates a simple mutex. This should be as fast as possible, but work
+ between different processors in a multiprocessor machine. This need
+ not work between different independent processes. */
+
+SshKernelMutex
+ssh_kernel_mutex_alloc(void)
+{
+ SshKernelMutex m;
+
+ m = ssh_calloc(1, sizeof(struct SshKernelMutexRec));
+ if (m == NULL)
+ return NULL;
+
+ if (!ssh_kernel_mutex_init(m))
+ {
+ ssh_free(m);
+ m = NULL;
+ }
+ return m;
+}
+
+/* Frees the given mutex. The mutex must not be locked when it is
+ freed. */
+
+void ssh_kernel_mutex_uninit(SshKernelMutex mutex)
+{
+ SSH_ASSERT(!mutex->taken);
+}
+
+void ssh_kernel_mutex_free(SshKernelMutex mutex)
+{
+ if (mutex)
+ {
+ ssh_kernel_mutex_uninit(mutex);
+ ssh_free(mutex);
+ }
+}
+
+#ifdef KERNEL_MUTEX_USE_FUNCTIONS
+/* Locks the mutex. Only one thread of execution can have a mutex locked
+ at a time. This will block until execution can continue. One should
+ not keep mutexes locked for extended periods of time. */
+void
+ssh_kernel_mutex_lock_i(SshKernelMutex mutex)
+{
+ SSH_LINUX_STATISTICS(ssh_interceptor_context,
+ { ssh_interceptor_context->stats.num_light_locks++; });
+
+ spin_lock(&mutex->lock);
+
+ SSH_ASSERT(!mutex->taken);
+
+#ifdef DEBUG_LIGHT
+ mutex->taken = TRUE;
+ mutex->jiffies = jiffies;
+#endif /* DEBUG_LIGHT */
+}
+
+/* Unlocks the mutex. If other threads are waiting to lock the mutex,
+ one of them will get the lock and continue execution. */
+
+void
+ssh_kernel_mutex_unlock_i(SshKernelMutex mutex)
+{
+ SSH_ASSERT(mutex->taken);
+#ifdef DEBUG_LIGHT
+ mutex->taken = FALSE;
+#endif /* DEBUG_LIGHT */
+
+ spin_unlock(&mutex->lock);
+}
+#endif /* KERNEL_MUTEX_USE_FUNCTIONS */
+
+#ifdef DEBUG_LIGHT
+/* Check that the mutex is locked. It is a fatal error if it is not. */
+
+void
+ssh_kernel_mutex_assert_is_locked(SshKernelMutex mutex)
+{
+ SSH_ASSERT(mutex->taken);
+}
+#endif /* DEBUG_LIGHT */
diff --git a/drivers/interceptor/linux_mutex_internal.h b/drivers/interceptor/linux_mutex_internal.h
new file mode 100644
index 0000000..954fbb6
--- /dev/null
+++ b/drivers/interceptor/linux_mutex_internal.h
@@ -0,0 +1,49 @@
+/* Netfilter Driver for IPSec VPN Client
+ *
+ * Copyright(c) 2012 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.
+ */
+
+/*
+ * linux_mutex_internal.h
+ *
+ * Linux interceptor internal defines for kernel mutex API.
+ *
+ */
+
+#ifndef LINUX_MUTEX_INTERNAL_H
+#define LINUX_MUTEX_INTERNAL_H
+
+#include <linux/spinlock.h>
+#include <asm/current.h>
+
+typedef struct SshKernelMutexRec
+{
+ spinlock_t lock;
+ unsigned long flags;
+
+#ifdef DEBUG_LIGHT
+ Boolean taken;
+ unsigned long jiffies;
+#endif
+} SshKernelMutexStruct;
+
+#ifdef CONFIG_PREEMPT
+
+#include <linux/preempt.h>
+
+#define icept_preempt_enable() preempt_enable()
+#define icept_preempt_disable() preempt_disable()
+
+#else /* CONFIG_PREEMPT */
+
+#define icept_preempt_enable() do {;} while(0)
+#define icept_preempt_disable() do {;} while(0)
+
+#endif /* CONFIG_PREEMPT */
+
+#endif /* LINUX_MUTEX_INTERNAL_H */
diff --git a/drivers/interceptor/linux_packet.c b/drivers/interceptor/linux_packet.c
new file mode 100644
index 0000000..7a9649b
--- /dev/null
+++ b/drivers/interceptor/linux_packet.c
@@ -0,0 +1,846 @@
+/* Netfilter Driver for IPSec VPN Client
+ *
+ * Copyright(c) 2012 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.
+ */
+
+/*
+ * linux_packet.c
+ *
+ * Linux interceptor implementation of interceptor API packet functions.
+ *
+ */
+
+#include "linux_internal.h"
+#include "linux_packet_internal.h"
+
+/* Packet context freelist head pointer array. There is a freelist entry for
+ each CPU and one freelist entry (with index SSH_LINUX_INTERCEPTOR_NR_CPUS)
+ shared among all CPU's. When getting a packet, the current CPU freelist is
+ searched, if that is empty the shared freelist is searched (which requires
+ taking a lock). When returning a packet, if the CPU is the same as when
+ the packet was allocated, the packet is returned to the CPU freelist, if
+ not it is returned to the shared freelist (which again requires taking
+ a lock). */
+struct SshInterceptorInternalPacketRec
+*ssh_packet_freelist_head[SSH_LINUX_INTERCEPTOR_NR_CPUS + 1] = {NULL};
+
+extern SshInterceptor ssh_interceptor_context;
+
+static inline SshInterceptorInternalPacket
+ssh_freelist_packet_get(SshInterceptor interceptor,
+ Boolean may_borrow)
+{
+ SshInterceptorInternalPacket p;
+ unsigned int cpu;
+
+ icept_preempt_disable();
+
+ cpu = smp_processor_id();
+
+ p = ssh_packet_freelist_head[cpu];
+ if (p)
+ {
+ p->cpu = cpu;
+
+ ssh_packet_freelist_head[p->cpu] =
+ (SshInterceptorInternalPacket) p->packet.next;
+ }
+ else
+ {
+ /* Try getting a packet from the shared freelist */
+ ssh_kernel_mutex_lock(interceptor->packet_lock);
+
+ p = ssh_packet_freelist_head[SSH_LINUX_INTERCEPTOR_NR_CPUS];
+ if (p)
+ {
+ p->cpu = cpu;
+
+ ssh_packet_freelist_head[SSH_LINUX_INTERCEPTOR_NR_CPUS] =
+ (SshInterceptorInternalPacket) p->packet.next;
+
+ ssh_kernel_mutex_unlock(interceptor->packet_lock);
+ goto done;
+ }
+ ssh_kernel_mutex_unlock(interceptor->packet_lock);
+
+ p = ssh_malloc(sizeof(*p));
+ if (!p)
+ goto done;
+
+ p->cpu = cpu;
+ }
+
+ done:
+ icept_preempt_enable();
+
+ return p;
+}
+
+static inline void
+ssh_freelist_packet_put(SshInterceptor interceptor,
+ SshInterceptorInternalPacket p)
+{
+ unsigned int cpu;
+
+ icept_preempt_disable();
+
+ cpu = p->cpu;
+
+ SSH_ASSERT(cpu < SSH_LINUX_INTERCEPTOR_NR_CPUS);
+
+#ifdef DEBUG_LIGHT
+ memset(p, 'F', sizeof(*p));
+#endif /* DEBUG_LIGHT */
+
+ if (likely(cpu == smp_processor_id()))
+ {
+ p->packet.next =
+ (SshInterceptorPacket) ssh_packet_freelist_head[cpu];
+ ssh_packet_freelist_head[cpu] = p;
+ }
+ else
+ {
+ cpu = SSH_LINUX_INTERCEPTOR_NR_CPUS;
+
+ /* The executing CPU is not the same as when the packet was
+ allocated. Put the packet back to the shared freelist */
+ ssh_kernel_mutex_lock(interceptor->packet_lock);
+
+ p->packet.next =
+ (SshInterceptorPacket) ssh_packet_freelist_head[cpu];
+ ssh_packet_freelist_head[cpu] = p;
+
+ ssh_kernel_mutex_unlock(interceptor->packet_lock);
+ }
+
+ icept_preempt_enable();
+}
+
+
+Boolean
+ssh_interceptor_packet_freelist_init(SshInterceptor interceptor)
+{
+ unsigned int i;
+
+ for (i = 0; i < SSH_LINUX_INTERCEPTOR_NR_CPUS + 1; i++)
+ ssh_packet_freelist_head[i] = NULL;
+
+ return TRUE;
+}
+
+void
+ssh_interceptor_packet_freelist_uninit(SshInterceptor interceptor)
+{
+ SshInterceptorInternalPacket p;
+ unsigned int i;
+
+ ssh_kernel_mutex_lock(interceptor->packet_lock);
+
+ for (i = 0; i < SSH_LINUX_INTERCEPTOR_NR_CPUS + 1; i++)
+ {
+ /* Traverse freelist and free allocated all packets. */
+ p = ssh_packet_freelist_head[i];
+ while (p != NULL)
+ {
+ ssh_packet_freelist_head[i] =
+ (SshInterceptorInternalPacket) p->packet.next;
+
+ ssh_free(p);
+
+ p = ssh_packet_freelist_head[i];
+ }
+ }
+
+ ssh_kernel_mutex_unlock(interceptor->packet_lock);
+}
+
+/******************************************* General packet allocation stuff */
+
+/* Allocates new packet skb with copied data from original
+ + the extra free space reserved for extensions. */
+struct sk_buff *
+ssh_interceptor_packet_skb_dup(SshInterceptor interceptor,
+ struct sk_buff *skb,
+ size_t addbytes_active_ofs,
+ size_t addbytes_active)
+{
+ struct sk_buff *new_skb;
+ ssize_t offset;
+ size_t addbytes_spare_start = SSH_INTERCEPTOR_PACKET_HEAD_ROOM;
+ size_t addbytes_spare_end = SSH_INTERCEPTOR_PACKET_TAIL_ROOM;
+ unsigned char *ptr;
+
+ SSH_DEBUG(SSH_D_LOWOK,
+ ("skb dup: len %d extra %d offset %d headroom %d tailroom %d",
+ skb->len, (int) addbytes_active, (int) addbytes_active_ofs,
+ (int) addbytes_spare_start, (int) addbytes_spare_end));
+
+ /* Create new skb */
+ new_skb = alloc_skb(skb->len + addbytes_active +
+ addbytes_spare_start +
+ addbytes_spare_end,
+ SSH_LINUX_ALLOC_SKB_GFP_MASK);
+ if (!new_skb)
+ {
+ SSH_LINUX_STATISTICS(interceptor,
+ { interceptor->stats.num_failed_allocs++; });
+ return NULL;
+ }
+
+ /* Set the fields */
+ new_skb->len = skb->len + addbytes_active;
+ new_skb->data = new_skb->head + addbytes_spare_start;
+ SSH_SKB_SET_TAIL(new_skb, new_skb->data + new_skb->len);
+ new_skb->protocol = skb->protocol;
+ new_skb->dev = skb->dev;
+
+ new_skb->pkt_type = skb->pkt_type;
+#ifdef LINUX_HAS_SKB_STAMP
+ new_skb->stamp = skb->stamp;
+#endif /* LINUX_HAS_SKB_STAMP */
+ new_skb->destructor = NULL_FNPTR;
+
+ /* Set transport header offset. TX Checksum offloading relies this to be
+ set in the case that the checksum has to be calculated in software
+ in dev_queue_xmit(). */
+ ptr = SSH_SKB_GET_TRHDR(skb);
+ if (ptr != NULL)
+ {
+ offset = ptr - skb->data;
+ if (offset > addbytes_active_ofs)
+ offset += addbytes_active;
+ SSH_SKB_SET_TRHDR(new_skb, new_skb->data + offset);
+ }
+
+ /* Set mac header offset. This is set for convinience. Note that if
+ mac header has already been removed from the sk_buff then the mac
+ header data is not copied to the duplicate. */
+ ptr = SSH_SKB_GET_MACHDR(skb);
+ if (ptr != NULL)
+ {
+ offset = ptr - skb->data;
+ if (offset > addbytes_active_ofs)
+ offset += addbytes_active;
+ SSH_SKB_SET_MACHDR(new_skb, new_skb->data + offset);
+ }
+
+ /* Set network header offset. This one is maintained out of convenience
+ (so we need not do setting by hand unless we definitely want to,
+ i.e. sending packet out). */
+ ptr = SSH_SKB_GET_NETHDR(skb);
+ if (ptr != NULL)
+ {
+ offset = ptr - skb->data;
+ if (offset > addbytes_active_ofs)
+ offset += addbytes_active;
+ SSH_SKB_SET_NETHDR(new_skb, new_skb->data + offset);
+ }
+
+ /* not used by old interceptor. */
+ new_skb->sk = NULL; /* kernel does this.. copying might make more sense? */
+
+ /* not needed according to kernel (alloc_skb does this) */
+ atomic_set(&new_skb->users, 1);
+
+ /* Set csum fields. */
+ new_skb->ip_summed = skb->ip_summed;
+ if (
+#ifdef LINUX_HAS_NEW_CHECKSUM_FLAGS
+ new_skb->ip_summed == CHECKSUM_COMPLETE
+#else /* LINUX_HAS_NEW_CHECKSUM_FLAGS */
+ new_skb->ip_summed == CHECKSUM_HW
+#endif /* LINUX_HAS_NEW_CHECKSUM_FLAGS */
+ )
+ {
+ SSH_SKB_CSUM(new_skb) = SSH_SKB_CSUM(skb);
+ }
+#ifdef LINUX_HAS_NEW_CHECKSUM_FLAGS
+ else if (new_skb->ip_summed == CHECKSUM_PARTIAL)
+ {
+ SSH_SKB_CSUM_OFFSET(new_skb) = SSH_SKB_CSUM_OFFSET(skb);
+#ifdef LINUX_HAS_SKB_CSUM_START
+ /* Set csum_start. */
+ offset = (skb->head + skb->csum_start) - skb->data;
+ if (offset > addbytes_active_ofs)
+ offset += addbytes_active;
+ new_skb->csum_start = (new_skb->data + offset) - new_skb->head;
+#endif /* LINUX_HAS_SKB_CSUM_START */
+ }
+#endif /* LINUX_HAS_NEW_CHECKSUM_FLAGS */
+ else
+ {
+ SSH_SKB_CSUM(new_skb) = 0;
+ }
+
+ new_skb->priority = skb->priority;
+ SSH_SKB_DST_SET(new_skb, dst_clone(SSH_SKB_DST(skb)));
+ memcpy(new_skb->cb, skb->cb, sizeof(skb->cb));
+
+#ifdef LINUX_HAS_SKB_SECURITY
+ new_skb->security = skb->security;
+#endif /* LINUX_HAS_SKB_SECURITY */
+
+#ifdef CONFIG_NETFILTER
+ SSH_SKB_MARK(new_skb) = SSH_SKB_MARK(skb);
+#ifdef LINUX_HAS_SKB_NFCACHE
+ new_skb->nfcache = NFC_UNKNOWN;
+#endif /* LINUX_HAS_SKB_NFCACHE */
+#ifdef CONFIG_NETFILTER_DEBUG
+#ifdef LINUX_HAS_SKB_NFDEBUG
+ new_skb->nf_debug = skb->nf_debug;
+#endif /* LINUX_HAS_SKB_NFDEBUG */
+#endif /* CONFIG_NETFILTER_DEBUG */
+#endif /* CONFIG_NETFILTER */
+
+ SSH_LINUX_STATISTICS(interceptor,
+ { interceptor->stats.num_copied_packets++; });
+
+ /* Copy data from active_ofs+ => active_ofs+addbytes+ */
+ if ((skb->len - addbytes_active_ofs) > 0)
+ {
+ memcpy(new_skb->data + addbytes_active_ofs + addbytes_active,
+ skb->data + addbytes_active_ofs,
+ skb->len - addbytes_active_ofs);
+ }
+
+ /* Copy the 0+ => 0+ where value < ofs (header part that is left alone). */
+ if (addbytes_active_ofs > 0)
+ {
+ SSH_ASSERT(addbytes_active_ofs <= skb->len);
+ memcpy(new_skb->data,
+ skb->data,
+ addbytes_active_ofs);
+ }
+
+ return new_skb;
+}
+
+/* Allocates a packet header wrapping the given skbuff.
+ Packet headers can be allocated only using this function.
+
+ Note that the actual packet->skb is NULL after packet has been
+ returned.
+
+ This function returns NULL if the packet header cannot be
+ allocated. */
+
+SshInterceptorInternalPacket
+ssh_interceptor_packet_alloc_header(SshInterceptor interceptor,
+ SshUInt32 flags,
+ SshInterceptorProtocol protocol,
+ SshUInt32 ifnum_in,
+ SshUInt32 ifnum_out,
+ struct sk_buff *skb,
+ Boolean force_copy_skbuff,
+ Boolean free_original_on_copy,
+ Boolean packet_from_system)
+{
+ SshInterceptorInternalPacket p;
+
+ /* Linearize the packet in case it isn't already. */
+#ifdef LINUX_SKB_LINEARIZE_NEEDS_FLAGS
+ if (skb && skb_is_nonlinear(skb) && skb_linearize(skb, GFP_ATOMIC) != 0)
+ return NULL;
+#else /* LINUX_SKB_LINEARIZE_NEEDS_FLAGS */
+ if (skb && skb_is_nonlinear(skb) && skb_linearize(skb) != 0)
+ return NULL;
+#endif /* LINUX_SKB_LINEARIZE_NEEDS_FLAGS */
+
+ /* Allocate a wrapper structure */
+ p = ssh_freelist_packet_get(interceptor, !packet_from_system);
+ if (p == NULL)
+ {
+ SSH_LINUX_STATISTICS(interceptor,
+ { interceptor->stats.num_failed_allocs++; });
+ return NULL;
+ }
+
+ /* Initialize all the fields */
+ p->packet.flags = flags;
+
+ /* Assert that the interface number fits into SshInterceptorIfnum.
+ Note that both interface numbers may be equal to
+ SSH_INTERCEPTOR_INVALID_IFNUM. */
+ SSH_LINUX_ASSERT_IFNUM(ifnum_in);
+ SSH_LINUX_ASSERT_IFNUM(ifnum_out);
+
+ p->packet.ifnum_in = ifnum_in;
+ p->packet.ifnum_out = ifnum_out;
+ p->original_ifnum = ifnum_in;
+
+#ifdef SSH_IPSEC_IP_ONLY_INTERCEPTOR
+ p->packet.route_selector = 0;
+#endif /* SSH_IPSEC_IP_ONLY_INTERCEPTOR */
+
+ p->packet.pmtu = 0;
+ p->packet.protocol = protocol;
+#if (SSH_INTERCEPTOR_NUM_EXTENSION_SELECTORS > 0)
+ memset(p->packet.extension, 0, sizeof(p->packet.extension));
+#ifdef SSH_LINUX_FWMARK_EXTENSION_SELECTOR
+ /* Copy the linux fwmark to the extension slot indexed by
+ SSH_LINUX_FWMARK_EXTENSION_SELECTOR. */
+ if (skb)
+ p->packet.extension[SSH_LINUX_FWMARK_EXTENSION_SELECTOR] =
+ SSH_SKB_MARK(skb);
+#endif /* SSH_LINUX_FWMARK_EXTENSION_SELECTOR */
+#endif /* (SSH_INTERCEPTOR_NUM_EXTENSION_SELECTORS > 0) */
+ p->interceptor = interceptor;
+ p->skb = skb;
+
+ SSH_LINUX_STATISTICS(interceptor,
+ {
+ interceptor->stats.num_allocated_packets++;
+ interceptor->stats.num_allocated_packets_total++;
+ });
+
+ if (skb)
+ {
+ /* we have skb */
+ if (force_copy_skbuff || skb_cloned(skb))
+ {
+ /* The skb was already cloned, so make a new copy to be modified by
+ * the engine processing. */
+ p->skb = ssh_interceptor_packet_skb_dup(interceptor, skb, 0, 0);
+ if (p->skb == NULL)
+ {
+ SSH_LINUX_STATISTICS(interceptor,
+ { interceptor->stats.num_allocated_packets--; });
+ ssh_freelist_packet_put(interceptor, p);
+ return NULL;
+ }
+
+ if (free_original_on_copy)
+ {
+ /* Free the original buffer as we will not return it anymore */
+ dev_kfree_skb_any(skb);
+ }
+ }
+ else
+ {
+ /* No one else has cloned the original skb, so use it
+ without copying */
+ p->skb = skb;
+ }
+
+ /* If the packet is of media-broadcast persuasion, add it to the flags. */
+ if (p->skb->pkt_type == PACKET_BROADCAST)
+ p->packet.flags |= SSH_PACKET_MEDIABCAST;
+ if (p->skb->pkt_type == PACKET_MULTICAST)
+ p->packet.flags |= SSH_PACKET_MEDIABCAST;
+
+#ifdef LINUX_HAS_NEW_CHECKSUM_FLAGS
+ if (p->skb->ip_summed == CHECKSUM_COMPLETE /* inbound */
+ || p->skb->ip_summed == CHECKSUM_UNNECESSARY /* inbound */
+ || p->skb->ip_summed == CHECKSUM_PARTIAL) /* outbound */
+ p->packet.flags |= SSH_PACKET_HWCKSUM;
+#else /* LINUX_HAS_NEW_CHECKSUM_FLAGS */
+ if (p->skb->ip_summed == CHECKSUM_HW /* inbound/outbound */
+ || p->skb->ip_summed == CHECKSUM_UNNECESSARY) /* inbound */
+ p->packet.flags |= SSH_PACKET_HWCKSUM;
+#endif /* LINUX_HAS_NEW_CHECKSUM_FLAGS */
+
+ SSH_DEBUG(SSH_D_LOWOK,
+ ("alloc header: skb len %d headroom %d tailroom %d",
+ p->skb->len, skb_headroom(p->skb), skb_tailroom(p->skb)));
+ }
+
+ return p;
+}
+
+/* Allocates a packet of at least the given size. Packets can only be
+ allocated using this function (either internally by the interceptor or
+ by other code by calling this function). This returns NULL if no more
+ packets can be allocated. */
+
+SshInterceptorPacket
+ssh_interceptor_packet_alloc(SshInterceptor interceptor,
+ SshUInt32 flags,
+ SshInterceptorProtocol protocol,
+ SshInterceptorIfnum ifnum_in,
+ SshInterceptorIfnum ifnum_out,
+ size_t total_len)
+{
+ SshInterceptorInternalPacket packet;
+ size_t len;
+ struct sk_buff *skb;
+
+ packet = (SshInterceptorInternalPacket)
+ ssh_interceptor_packet_alloc_header(interceptor,
+ flags,
+ protocol,
+ ifnum_in,
+ ifnum_out,
+ NULL,
+ FALSE,
+ FALSE,
+ FALSE);
+ if (!packet)
+ return NULL; /* header allocation failed */
+
+ /* Allocate actual kernel packet. Note that some overhead is calculated
+ so that media headers etc. fit without additional allocations or
+ copying. */
+ len = total_len + SSH_INTERCEPTOR_PACKET_HEAD_ROOM +
+ SSH_INTERCEPTOR_PACKET_TAIL_ROOM;
+ skb = alloc_skb(len, SSH_LINUX_ALLOC_SKB_GFP_MASK);
+ if (skb == NULL)
+ {
+ SSH_LINUX_STATISTICS(interceptor,
+ { interceptor->stats.num_failed_allocs++; });
+ ssh_freelist_packet_put(interceptor, packet);
+ return NULL;
+ }
+ packet->skb = skb;
+
+ /* Set data area inside the packet */
+ skb->len = total_len;
+ skb->data = skb->head + SSH_INTERCEPTOR_PACKET_HEAD_ROOM;
+ SSH_SKB_SET_TAIL(skb, skb->data + total_len);
+
+ /* Ensure the IP header offset is 16 byte aligned for ethernet frames. */
+ if (protocol == SSH_PROTOCOL_ETHERNET)
+ {
+ /* Assert that SSH_INTERCEPTOR_PACKET_TAIL_ROOM is large enough */
+ SSH_ASSERT(SSH_SKB_GET_END(skb) - SSH_SKB_GET_TAIL(skb) >= 2);
+ skb->data += 2;
+ /* This works on both pointers and offsets. */
+ skb->tail += 2;
+ }
+
+#ifdef LINUX_HAS_NEW_CHECKSUM_FLAGS
+ if (flags & SSH_PACKET_HWCKSUM)
+ {
+ if (flags & SSH_PACKET_FROMADAPTER)
+ skb->ip_summed = CHECKSUM_COMPLETE;
+ else if (flags & SSH_PACKET_FROMPROTOCOL)
+ skb->ip_summed = CHECKSUM_PARTIAL;
+ }
+#else /* LINUX_HAS_NEW_CHECKSUM_FLAGS */
+ if (flags & SSH_PACKET_HWCKSUM)
+ skb->ip_summed = CHECKSUM_HW;
+#endif /* LINUX_HAS_NEW_CHECKSUM_FLAGS */
+
+ /* If support for other than IPv6, IPv4 and ARP
+ inside the engine on Linux are to be supported, their
+ protocol types must be added here. */
+ switch(protocol)
+ {
+#ifdef SSH_LINUX_INTERCEPTOR_IPV6
+ case SSH_PROTOCOL_IP6:
+ skb->protocol = __constant_htons(ETH_P_IPV6);
+ break;
+#endif /* SSH_LINUX_INTERCEPTOR_IPV6 */
+
+ case SSH_PROTOCOL_ARP:
+ skb->protocol = __constant_htons(ETH_P_ARP);
+ break;
+
+ case SSH_PROTOCOL_IP4:
+ default:
+ skb->protocol = __constant_htons(ETH_P_IP);
+ break;
+ }
+
+ SSH_DEBUG(SSH_D_LOWOK,
+ ("alloc packet: skb len %d headroom %d tailroom %d",
+ packet->skb->len, skb_headroom(packet->skb),
+ skb_tailroom(packet->skb)));
+
+ return (SshInterceptorPacket) packet;
+}
+
+/* Frees the given packet. All packets allocated by
+ ssh_interceptor_packet_alloc must eventually be freed using this
+ function by either calling this explicitly or by passing the packet
+ to the interceptor send function. */
+
+void
+ssh_interceptor_packet_free(SshInterceptorPacket pp)
+{
+ SshInterceptorInternalPacket packet = (SshInterceptorInternalPacket) pp;
+
+ /* Free the packet buffer first */
+ if (packet->skb)
+ {
+ dev_kfree_skb_any(packet->skb);
+ packet->skb = NULL;
+ }
+
+ SSH_LINUX_STATISTICS(packet->interceptor,
+ { packet->interceptor->stats.num_allocated_packets--; });
+
+ /* Free the wrapper */
+ ssh_freelist_packet_put(packet->interceptor, packet);
+}
+
+#if defined(KERNEL_INTERCEPTOR_USE_FUNCTIONS) || !defined(KERNEL)
+/* Returns the length of the data packet. */
+size_t
+ssh_interceptor_packet_len(SshInterceptorPacket pp)
+{
+ SshInterceptorInternalPacket packet = (SshInterceptorInternalPacket) pp;
+ return packet->skb->len;
+}
+#endif /* defined(KERNEL_INTERCEPTOR_USE_FUNCTIONS) || !defined(KERNEL) */
+
+
+/* Copies data into the packet. Space for the new data must already have
+ been allocated. It is a fatal error to attempt to copy beyond the
+ allocated packet. Multiple threads may call this function concurrently,
+ but not for the same packet. This does not change the length of the
+ packet. */
+
+Boolean
+ssh_interceptor_packet_copyin(SshInterceptorPacket pp, size_t offset,
+ const unsigned char *buf, size_t len)
+{
+ SshInterceptorInternalPacket packet = (SshInterceptorInternalPacket) pp;
+
+ memmove(packet->skb->data + offset, buf, len);
+
+ return TRUE;
+}
+
+/* Copies data out from the packet. Space for the new data must
+ already have been allocated. It is a fatal error to attempt to
+ copy beyond the allocated packet. Multiple threads may call this
+ function concurrently, but not for the same packet. */
+
+void
+ssh_interceptor_packet_copyout(SshInterceptorPacket pp, size_t offset,
+ unsigned char *buf, size_t len)
+{
+ SshInterceptorInternalPacket packet = (SshInterceptorInternalPacket) pp;
+
+ memmove(buf, packet->skb->data + offset, len);
+}
+
+#define SSH_PACKET_IDATA_IFNUM_OFFSET 0
+#define SSH_PACKET_IDATA_DST_CACHE_ID_OFFSET sizeof(SshUInt32)
+#define SSH_PACKET_IDATA_PKT_TYPE_OFFSET (2 * sizeof(SshUInt32))
+#define SSH_PACKET_IDATA_TRHDR_OFFSET (3 * sizeof(SshUInt32))
+#define SSH_PACKET_IDATA_CP_OFFSET (4 * sizeof(SshUInt32))
+#define SSH_PACKET_IDATA_MINLEN SSH_PACKET_IDATA_CP_OFFSET
+
+Boolean ssh_interceptor_packet_export_internal_data(SshInterceptorPacket pp,
+ unsigned char **data_ret,
+ size_t *len_return)
+{
+ unsigned char *data;
+ SshInterceptorInternalPacket ipp = (SshInterceptorInternalPacket)pp;
+ SshUInt32 dst_cache_id = 0;
+ SshUInt32 transport_offset = 0;
+
+ if (ipp->skb == NULL)
+ {
+ SSH_DEBUG(SSH_D_FAIL,
+ ("Unable to export internal packet data, sk buff"));
+ *data_ret = NULL;
+ *len_return = 0;
+ return FALSE;
+ }
+
+ data = ssh_calloc(1, SSH_PACKET_IDATA_MINLEN + sizeof(ipp->skb->cb));
+ if (data == NULL)
+ {
+ SSH_DEBUG(SSH_D_FAIL, ("Unable to export internal packet data"));
+ *data_ret = NULL;
+ *len_return = 0;
+ return FALSE;
+ }
+
+ SSH_PUT_32BIT(data, SSH_PACKET_IDATA_IFNUM_OFFSET);
+
+ dst_cache_id =
+ ssh_interceptor_packet_cache_dst_entry(ssh_interceptor_context, pp);
+ SSH_PUT_32BIT(data + SSH_PACKET_IDATA_DST_CACHE_ID_OFFSET, dst_cache_id);
+
+ SSH_PUT_8BIT(data + SSH_PACKET_IDATA_PKT_TYPE_OFFSET, ipp->skb->pkt_type);
+
+ transport_offset = (SshUInt32)(SSH_SKB_GET_TRHDR(ipp->skb) - ipp->skb->data);
+
+ SSH_PUT_32BIT(data + SSH_PACKET_IDATA_TRHDR_OFFSET, transport_offset);
+ memcpy(data + SSH_PACKET_IDATA_CP_OFFSET, ipp->skb->cb,
+ sizeof(ipp->skb->cb));
+
+ *data_ret = data;
+ *len_return = SSH_PACKET_IDATA_MINLEN + sizeof(ipp->skb->cb);
+
+ return TRUE;
+}
+
+void
+ssh_interceptor_packet_discard_internal_data(unsigned char *data,
+ size_t data_len)
+{
+ SshUInt32 dst_cache_id;
+
+ if (data_len == 0)
+ return;
+
+ if (data == NULL || data_len < SSH_PACKET_IDATA_MINLEN)
+ {
+ /* Attempt to import corrupted data. */
+ SSH_DEBUG(SSH_D_FAIL, ("Unable to import internal packet data"));
+ return;
+ }
+
+ dst_cache_id = SSH_GET_32BIT(data + SSH_PACKET_IDATA_DST_CACHE_ID_OFFSET);
+
+ ssh_interceptor_packet_return_dst_entry(ssh_interceptor_context,
+ dst_cache_id, NULL, TRUE);
+}
+
+Boolean ssh_interceptor_packet_import_internal_data(SshInterceptorPacket pp,
+ const unsigned char *data,
+ size_t len)
+{
+ SshInterceptorInternalPacket ipp = (SshInterceptorInternalPacket)pp;
+ SshUInt32 orig_ifnum;
+ SshUInt32 dst_cache_id;
+ SshUInt32 transport_offset;
+ Boolean remove_only = FALSE;
+
+ if (ipp->skb == NULL)
+ {
+ SSH_DEBUG(SSH_D_FAIL,
+ ("Unable to import internal packet data, no skb"));
+ return FALSE;
+ }
+
+ if (len == 0)
+ {
+ /* No data to import, i.e. packet created by engine. */
+ ipp->original_ifnum = SSH_INTERCEPTOR_INVALID_IFNUM;
+ ipp->skb->pkt_type = PACKET_HOST;
+ return TRUE;
+ }
+
+ if (data == NULL || len < (SSH_PACKET_IDATA_MINLEN + sizeof(ipp->skb->cb)))
+ {
+ /* Attempt to import corrupted data. */
+ SSH_DEBUG(SSH_D_FAIL, ("Unable to import internal packet data"));
+ return FALSE;
+ }
+
+ orig_ifnum = SSH_GET_32BIT(data + SSH_PACKET_IDATA_IFNUM_OFFSET);
+ ipp->original_ifnum = orig_ifnum;
+
+ dst_cache_id = SSH_GET_32BIT(data + SSH_PACKET_IDATA_DST_CACHE_ID_OFFSET);
+
+ if (pp->flags & SSH_PACKET_UNMODIFIED)
+ remove_only = FALSE;
+ ssh_interceptor_packet_return_dst_entry(ssh_interceptor_context,
+ dst_cache_id, pp, remove_only);
+
+ ipp->skb->pkt_type = SSH_GET_8BIT(data + SSH_PACKET_IDATA_PKT_TYPE_OFFSET);
+ transport_offset = SSH_GET_32BIT(data + SSH_PACKET_IDATA_TRHDR_OFFSET);
+
+ SSH_SKB_SET_TRHDR(ipp->skb, ipp->skb->data + transport_offset);
+
+ memcpy(ipp->skb->cb, data + SSH_PACKET_IDATA_CP_OFFSET,
+ sizeof(ipp->skb->cb));
+
+ return TRUE;
+}
+
+Boolean
+ssh_interceptor_packet_align(SshInterceptorPacket pp, size_t offset)
+{
+ SshInterceptorInternalPacket packet = (SshInterceptorInternalPacket) pp;
+ struct sk_buff *skb, *new_skb;
+ unsigned long addr;
+ size_t word_size, bytes;
+
+ word_size = sizeof(int *);
+ SSH_ASSERT(word_size < SSH_INTERCEPTOR_PACKET_TAIL_ROOM);
+
+ skb = packet->skb;
+
+ addr = (unsigned long) (skb->data + offset);
+
+ bytes = (size_t)((((addr + word_size - 1) / word_size) * word_size) - addr);
+ if (bytes == 0)
+ return TRUE;
+
+ if (SSH_SKB_GET_END(skb) - SSH_SKB_GET_TAIL(skb) >= bytes)
+ {
+ memmove(skb->data + bytes, skb->data, skb->len);
+ skb->data += bytes;
+ /* This works for both pointers and offsets. */
+ skb->tail += bytes;
+
+ SSH_DEBUG(SSH_D_LOWOK,
+ ("Aligning skb->data %p at offset %d to word "
+ "boundary (word_size %d), headroom %d tailroom %d",
+ skb->data, (int) offset, (int) word_size,
+ skb_headroom(skb), skb_tailroom(skb)));
+
+ return TRUE;
+ }
+ else if (skb->data - skb->head >= word_size - bytes)
+ {
+ bytes = word_size - bytes;
+ memmove(skb->data - bytes, skb->data, skb->len);
+ skb->data -= bytes;
+ skb->tail -= bytes;
+ return TRUE;
+ }
+ else
+ {
+ /* Allocate a new packet which has enough head/tail room to allow
+ alignment. */
+ new_skb = ssh_interceptor_packet_skb_dup(packet->interceptor, skb, 0, 0);
+
+ if (!new_skb)
+ {
+ ssh_interceptor_packet_free(pp);
+ return FALSE;
+ }
+ SSH_ASSERT(SSH_SKB_GET_END(new_skb) - SSH_SKB_GET_TAIL(new_skb)
+ >= word_size);
+
+ /* Free the old packet */
+ packet->skb = new_skb;
+ dev_kfree_skb_any(skb);
+ return ssh_interceptor_packet_align(pp, offset);
+ }
+}
+
+struct sk_buff *
+ssh_interceptor_packet_verify_headroom(struct sk_buff *skbp,
+ size_t media_header_len)
+{
+ SshUInt32 required_headroom;
+ struct sk_buff *skbp2;
+
+ SSH_ASSERT(skbp != NULL);
+ SSH_ASSERT(skbp->dev != NULL);
+
+ required_headroom = LL_RESERVED_SPACE(skbp->dev);
+#if (SSH_INTERCEPTOR_PACKET_HARD_HEAD_ROOM > 0)
+ if (required_headroom < SSH_INTERCEPTOR_PACKET_HARD_HEAD_ROOM)
+ required_headroom = SSH_INTERCEPTOR_PACKET_HARD_HEAD_ROOM;
+#endif /* (SSH_INTERCEPTOR_PACKET_HARD_HEAD_ROOM > 0) */
+
+ if (unlikely(required_headroom > media_header_len &&
+ skb_headroom(skbp) < (required_headroom - media_header_len)))
+ {
+ SSH_DEBUG(SSH_D_NICETOKNOW,
+ ("skb does not have enough headroom for device %d, "
+ "reallocating skb headroom",
+ skbp->dev->ifindex));
+ skbp2 = skb_realloc_headroom(skbp,
+ (required_headroom - media_header_len));
+ dev_kfree_skb_any(skbp);
+
+ return skbp2;
+ }
+
+ return skbp;
+}
diff --git a/drivers/interceptor/linux_packet_internal.h b/drivers/interceptor/linux_packet_internal.h
new file mode 100644
index 0000000..dd5c049
--- /dev/null
+++ b/drivers/interceptor/linux_packet_internal.h
@@ -0,0 +1,84 @@
+/* Netfilter Driver for IPSec VPN Client
+ *
+ * Copyright(c) 2012 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.
+ */
+
+/*
+ * linux_packet_internal.h
+ *
+ * Linux interceptor specific defines for the packet portion of the
+ * Interceptor API.
+ *
+ */
+
+#ifndef LINUX_PACKET_INTERNAL_H
+#define LINUX_PACKET_INTERNAL_H
+
+#include "kernel_includes.h"
+
+/* Internal packet structure, used to encapsulate the kernel structure
+ for the generic packet processing engine. */
+
+typedef struct SshInterceptorInternalPacketRec
+{
+ /* Generic packet structure */
+ struct SshInterceptorPacketRec packet;
+
+ /* Backpointer to interceptor */
+ SshInterceptor interceptor;
+
+ /* Kernel skb structure. */
+ struct sk_buff *skb;
+
+ /* The processor from which this packet was allocated from the freelist */
+ unsigned int cpu;
+
+ size_t iteration_offset;
+ size_t iteration_bytes;
+
+ /* These are SshUInt32's for export/import */
+ SshUInt32 original_ifnum;
+
+ SshUInt16 borrowed : 1; /* From spare resource, free after use */
+} *SshInterceptorInternalPacket;
+
+
+/* Typical needed tailroom: ESP trailer (worstcase ~27B).
+ Typical needed headroom: media, IPIP, ESP (~60B for IPv4, ~80B for IPv6)
+ Worstcase headroom: media, UDP(8), NAT-T(12), IPIP(~20), ESP(22) */
+
+/* The amount of headroom reserved for network interface processing. The
+ interceptor ensures that all packets passed to NIC driver will have atleast
+ this much headroom. */
+#ifndef SSH_IPSEC_IP_ONLY_INTERCEPTOR
+/* With media level interceptor the SSH_INTERCEPTOR_PACKET_HARD_HEAD_ROOM
+ includes the media header length. Let us use up the full skb if necessary.
+ This is important for reducing overhead in the forwarding case. */
+#define SSH_INTERCEPTOR_PACKET_HARD_HEAD_ROOM 0
+#else
+/* Ensure that packet has always enough headroom for an aligned
+ ethernet header. */
+#define SSH_INTERCEPTOR_PACKET_HARD_HEAD_ROOM 16
+#endif /* !SSH_IPSEC_IP_ONLY_INTERCEPTOR */
+
+/* Amount of head- and tailroom to reserve when allocating or duplicating
+ a packet. These values are optimised for IPsec processing. */
+#define SSH_INTERCEPTOR_PACKET_HEAD_ROOM (80)
+#define SSH_INTERCEPTOR_PACKET_TAIL_ROOM (30)
+
+#define SSH_LINUX_ALLOC_SKB_GFP_MASK (GFP_ATOMIC)
+
+#ifdef LINUX_HAS_SKB_CLONE_WRITABLE
+#define SSH_SKB_WRITABLE(_skb, _len) \
+ (!skb_cloned((_skb)) || skb_clone_writable((_skb), (_len)))
+#else /* LINUX_HAS_SKB_CLONE_WRITABLE */
+#define SSH_SKB_WRITABLE(_skb, _len) \
+ (!skb_cloned((_skb)))
+#endif /* LINUX_HAS_SKB_CLONE_WRITABLE */
+
+#endif /* LINUX_PACKET_INTERNAL_H */
diff --git a/drivers/interceptor/linux_params.h b/drivers/interceptor/linux_params.h
new file mode 100644
index 0000000..29b264b
--- /dev/null
+++ b/drivers/interceptor/linux_params.h
@@ -0,0 +1,84 @@
+/* Netfilter Driver for IPSec VPN Client
+ *
+ * Copyright(c) 2012 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.
+ */
+
+/*
+ * linux_params.h
+ *
+ * Linux interceptor tunable parameters.
+ *
+ */
+
+#ifndef LINUX_PARAMS_H
+#define LINUX_PARAMS_H
+
+/* Netfilter interoperability flag. This flags specifies the extension
+ selector slot which is used for storing the Linux 'skb->nfmark' firewall
+ mark. Note that in kernel versions before 2.6.20 the linux kernel
+ CONFIG_IP_ROUTE_FWMARK must be enabled if you wish to use `skb->nfmark'
+ in route lookups. This define is not used if
+ SSH_INTERCEPTOR_NUM_EXTENSION_SELECTORS is 0. */
+/* #define SSH_LINUX_FWMARK_EXTENSION_SELECTOR 0 */
+
+/* The upper treshold of queued messages from the engine to the policymanager.
+ If this treshold is passed, then "unreliable" messages (messages not
+ necessary for the correct operation of the engine/policymanager), are
+ discarded. Both existing queued messages or new messages can be
+ discarded. */
+#define SSH_LINUX_MAX_IPM_MESSAGES 2000
+
+/* Disable IPV6 support in the interceptor here, if explicitly desired.
+ Undefining SSH_LINUX_INTERCEPTOR_IPV6 results into excluding IPv6
+ specific code in the interceptor. The define does not affect the
+ size of any common data structures.
+ Currently it is disabled by default if IPv6 is not available in the
+ kernel. */
+#if defined (WITH_IPV6)
+#define SSH_LINUX_INTERCEPTOR_IPV6 1
+#ifndef CONFIG_IPV6
+#ifndef CONFIG_IPV6_MODULE
+#undef SSH_LINUX_INTERCEPTOR_IPV6
+#endif /* !CONFIG_IPV6_MODULE */
+#endif /* !CONFIG_IPV6 */
+#endif /* WITH_IPV6 */
+
+/* Netfilter interoperability flag. If this flag is set, then packets
+ intercepted at the PRE_ROUTING hook are passed to other netfilter modules
+ before the packet is given to the engine for processing. */
+/* #define SSH_LINUX_NF_PRE_ROUTING_BEFORE_ENGINE 1 */
+
+/* Netfilter interoperability flag. If this flag is set, then packets
+ sent to host stack are passed to other netfilter modules in the PRE_ROUTING
+ hook after the packet has been processed in the engine. */
+/* #define SSH_LINUX_NF_PRE_ROUTING_AFTER_ENGINE 1 */
+
+/* Netfilter interoperability flag. If this flag is set, then packets
+ intercepted at the POST_ROUTING hook are passed to other netfilter
+ modules before the packet is given to the engine for processing. */
+/* #define SSH_LINUX_NF_POST_ROUTING_BEFORE_ENGINE 1 */
+
+/* Netfilter interoperability flag. If this flag is set, then packets
+ sent to network are passed to other netfilter modules in the POST_ROUTING
+ hook after the packet has been processed in the engine. This flag is usable
+ only if SSH_IPSEC_IP_ONLY_INTERCEPTOR is defined. */
+#ifdef SSH_IPSEC_IP_ONLY_INTERCEPTOR
+/* #define SSH_LINUX_NF_POST_ROUTING_AFTER_ENGINE 1 */
+#endif /* SSH_IPSEC_IP_ONLY_INTERCEPTOR */
+
+/* Netfilter interoperability flag. If this flags is set, then forwarded
+ packets are passed to netfilter modules in the FORWARD hook after
+ the packet has been processed in the engine. This flag is usable
+ only if SSH_IPSEC_IP_ONLY_INTERCEPTOR defined, and if the engine performs
+ packet forwarding (that is, SSH_ENGINE_FLAGS does not include
+ SSH_ENGINE_NO_FORWARDING). */
+#ifdef SSH_IPSEC_IP_ONLY_INTERCEPTOR
+/* #define SSH_LINUX_NF_FORWARD_AFTER_ENGINE 1 */
+#endif /* SSH_IPSEC_IP_ONLY_INTERCEPTOR */
+
+#endif /* LINUX_PARAMS_H */
diff --git a/drivers/interceptor/linux_procfs.c b/drivers/interceptor/linux_procfs.c
new file mode 100644
index 0000000..6dff18c
--- /dev/null
+++ b/drivers/interceptor/linux_procfs.c
@@ -0,0 +1,800 @@
+/* Netfilter Driver for IPSec VPN Client
+ *
+ * Copyright(c) 2012 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.
+ */
+
+/*
+ * linux_procfs.c
+ *
+ * Linux interceptor proc filesystem interface for kernel to user space
+ * messaging.
+ *
+ */
+
+#include "linux_internal.h"
+
+extern SshInterceptor ssh_interceptor_context;
+
+/************************ Module parameters *********************************/
+
+unsigned int ssh_procfs_uid = 0;
+MODULE_PARM_DESC(ssh_procfs_uid, "Procfs uid");
+module_param(ssh_procfs_uid, uint, 0444);
+
+unsigned int ssh_procfs_gid = 0;
+MODULE_PARM_DESC(ssh_procfs_gid, "Procfs gid");
+module_param(ssh_procfs_gid, uint, 0444);
+
+/************************ Internal utility functions ************************/
+
+/* Use printk instead of SSH_DEBUG macros. */
+#ifdef DEBUG_LIGHT
+#define SSH_LINUX_PROCFS_DEBUG(x...) if (net_ratelimit()) printk(KERN_INFO x)
+#define SSH_LINUX_PROCFS_WARN(x...) printk(KERN_EMERG x)
+#endif /* DEBUG_LIGHT */
+
+#ifndef SSH_LINUX_PROCFS_DEBUG
+#define SSH_LINUX_PROCFS_DEBUG(x...)
+#define SSH_LINUX_PROCFS_WARN(x...)
+#endif /* SSH_LINUX_PROCFS_DEBUG */
+
+/* Maximum number of bytes that can be written to the ipm proc entry
+ in one call. This limits the time spent softirqs disabled by forcing
+ the application to perform another write operation. */
+#define SSH_LINUX_PROCFS_IPM_WRITE_MAX_LENGTH \
+ (4 * SSH_LINUX_IPM_RECV_BUFFER_SIZE)
+
+static int
+interceptor_proc_entry_fop_open(SshInterceptorProcEntry entry,
+ struct file *file)
+{
+ /* Allow only one userspace application at a time. */
+ write_lock(&entry->lock);
+ if (entry->open == TRUE)
+ {
+ write_unlock(&entry->lock);
+ return -EBUSY;
+ }
+
+ /* Check that engine initialization has been completed. */
+ if (ssh_interceptor_context->engine_open == FALSE)
+ {
+ write_unlock(&entry->lock);
+ return -EBUSY;
+ }
+
+ /* Increment module ref to prohibit module unloading. */
+ if (!ssh_linux_module_inc_use_count())
+ {
+ write_unlock(&entry->lock);
+ return -EBUSY;
+ }
+
+ file->private_data = ssh_interceptor_context;
+ entry->buf_len = 0;
+ entry->open = TRUE;
+
+ write_unlock(&entry->lock);
+
+ return 0;
+}
+
+static int
+interceptor_proc_entry_fop_release(SshInterceptorProcEntry entry)
+{
+ write_lock(&entry->lock);
+
+ /* Release the module reference. */
+ ssh_linux_module_dec_use_count();
+
+ /* Mark proc entry closed */
+ entry->open = FALSE;
+
+ write_unlock(&entry->lock);
+
+ return 0;
+}
+
+static int interceptor_proc_entry_iop_permission(struct inode *inode,
+ int op
+#ifdef LINUX_INODE_OPERATION_PERMISSION_HAS_NAMEIDATA
+ , struct nameidata *nd
+#endif /* LINUX_INODE_OPERATION_PERMISSION_HAS_NAMEIDATA */
+#ifdef LINUX_INODE_OPERATION_PERMISSION_HAS_UINT
+ , unsigned int ed
+#endif /* LINUX_INODE_OPERATION_PERMISSION_HAS_UINT */
+ )
+{
+ if (op & MAY_EXEC)
+ return -EACCES;
+
+ if ((op & (MAY_READ | MAY_WRITE)) &&
+#ifdef LINUX_HAS_TASK_CRED_STRUCT
+ current_euid() == (uid_t) ssh_procfs_uid
+#else /* LINUX_HAS_TASK_CRED_STRUCT */
+ current->euid == (uid_t) ssh_procfs_uid
+#endif /* LINUX_HAS_TASK_CRED_STRUCT */
+ )
+ {
+ return 0;
+ }
+
+ return -EACCES;
+}
+
+static struct inode_operations common_proc_entry_iops =
+{
+ .permission = interceptor_proc_entry_iop_permission
+};
+
+
+/************************ Ipm proc entry ************************************/
+
+static ssize_t
+interceptor_ipm_proc_entry_fop_read(struct file *file,
+ char __user *buf,
+ size_t len,
+ loff_t *pos)
+{
+ SshInterceptor interceptor = file->private_data;
+ SshInterceptorIpmMsg msg = NULL;
+ ssize_t msg_len;
+
+ write_lock(&interceptor->ipm_proc_entry.lock);
+
+ /* Allow only one read at a time. */
+ if (interceptor->ipm_proc_entry.read_active)
+ {
+ write_unlock(&interceptor->ipm_proc_entry.lock);
+ SSH_LINUX_PROCFS_DEBUG("interceptor_ipm_proc_entry_fop_read: -EBUSY\n");
+ return -EBUSY;
+ }
+
+ interceptor->ipm_proc_entry.read_active = TRUE;
+ write_unlock(&interceptor->ipm_proc_entry.lock);
+
+ /* Continue from the partial message. */
+ if (interceptor->ipm_proc_entry.send_msg != NULL)
+ msg = interceptor->ipm_proc_entry.send_msg;
+
+
+ retry:
+ if (msg == NULL)
+ {
+ /* Get the next message from send queue. */
+ local_bh_disable();
+ write_lock(&interceptor->ipm.lock);
+
+ /* Take next message from send queue. */
+ if (interceptor->ipm.send_queue != NULL)
+ {
+ msg = interceptor->ipm.send_queue;
+
+ interceptor->ipm.send_queue = msg->next;
+ if (msg->next)
+ msg->next->prev = NULL;
+ msg->next = NULL;
+
+ if (msg == interceptor->ipm.send_queue_tail)
+ interceptor->ipm.send_queue_tail = msg->next;
+
+ if (msg->reliable == 0)
+ {
+ SSH_ASSERT(interceptor->ipm.send_queue_num_unreliable > 0);
+ interceptor->ipm.send_queue_num_unreliable--;
+ }
+ }
+
+ write_unlock(&interceptor->ipm.lock);
+ local_bh_enable();
+ }
+
+ if (msg == NULL)
+ {
+ /* Non-blocking mode, fail read. */
+ if (file->f_flags & O_NONBLOCK)
+ {
+ write_lock(&interceptor->ipm_proc_entry.lock);
+ interceptor->ipm_proc_entry.read_active = FALSE;
+ write_unlock(&interceptor->ipm_proc_entry.lock);
+
+ return -EAGAIN;
+ }
+
+ /* Blocking mode, sleep until a message or a signal arrives. */
+ interruptible_sleep_on(&interceptor->ipm_proc_entry.wait_queue);
+
+ if (signal_pending(current))
+ {
+ SSH_LINUX_PROCFS_DEBUG("interceptor_ipm_proc_entry_fop_read: "
+ "-ERESTARTSYS\n");
+
+ write_lock(&interceptor->ipm_proc_entry.lock);
+ interceptor->ipm_proc_entry.read_active = FALSE;
+ write_unlock(&interceptor->ipm_proc_entry.lock);
+
+ return -ERESTARTSYS;
+ }
+
+ goto retry;
+ }
+
+ interceptor->ipm_proc_entry.send_msg = msg;
+
+ /* Copy message to userspace. */
+ msg_len = msg->len - msg->offset;
+ if (len < msg_len)
+ msg_len = len;
+
+ if (copy_to_user(buf, msg->buf + msg->offset, msg_len))
+ {
+ SSH_LINUX_PROCFS_WARN("interceptor_ipm_proc_entry_fop_read: "
+ "copy_to_user failed, dropping message\n");
+
+ interceptor->ipm_proc_entry.send_msg = NULL;
+ write_lock(&interceptor->ipm_proc_entry.lock);
+ interceptor->ipm_proc_entry.read_active = FALSE;
+ write_unlock(&interceptor->ipm_proc_entry.lock);
+
+ interceptor_ipm_message_free(interceptor, msg);
+ return -EFAULT;
+ }
+
+ msg->offset += msg_len;
+
+ /* Whole message was sent. */
+ if (msg->offset >= msg->len)
+ {
+ interceptor->ipm_proc_entry.send_msg = NULL;
+ write_lock(&interceptor->ipm_proc_entry.lock);
+ interceptor->ipm_proc_entry.read_active = FALSE;
+ write_unlock(&interceptor->ipm_proc_entry.lock);
+
+ interceptor_ipm_message_free(interceptor, msg);
+ }
+ else
+ {
+ write_lock(&interceptor->ipm_proc_entry.lock);
+ interceptor->ipm_proc_entry.read_active = FALSE;
+ write_unlock(&interceptor->ipm_proc_entry.lock);
+ }
+
+ return msg_len;
+}
+
+static ssize_t
+interceptor_ipm_proc_entry_fop_write(struct file *file,
+ const char __user *buf,
+ size_t len,
+ loff_t *pos)
+{
+ SshInterceptor interceptor = file->private_data;
+ size_t total_len, write_len, recv_len, consumed, msg_len;
+ char *user_buf, *recv_buf;
+
+ /* Limit the maximum write length to avoid running in softirq
+ context for long periods of time. */
+ if (len > SSH_LINUX_PROCFS_IPM_WRITE_MAX_LENGTH)
+ write_len = SSH_LINUX_PROCFS_IPM_WRITE_MAX_LENGTH;
+ else
+ write_len = len;
+
+ /* Refuse to receive any data if send queue is getting full.
+ Note this here checks if the IPM message freelist is empty,
+ which indicates that all IPM messages are in the send queue.
+
+ Allowing a new write in such condition could cause a number
+ of reply IPM messages to be queued for sending and this would
+ cause either unreliable IPM messages to be discarded from the
+ send queue or an emergency mallocation of a reliable IPM message.
+
+ A better way to solve this problem is to refuse this write
+ operation and force the application to read messages from the send
+ queue before allowing another write. */
+ local_bh_disable();
+ read_lock(&interceptor->ipm.lock);
+ if (interceptor->ipm.msg_freelist == NULL
+ && interceptor->ipm.msg_allocated >= SSH_LINUX_MAX_IPM_MESSAGES)
+ write_len = 0;
+ read_unlock(&interceptor->ipm.lock);
+ local_bh_enable();
+
+ if (write_len == 0)
+ return -EAGAIN;
+
+ /* Check if there is another write going on. */
+ retry:
+ write_lock(&interceptor->ipm_proc_entry.lock);
+
+ if (interceptor->ipm_proc_entry.write_active)
+ {
+ write_unlock(&interceptor->ipm_proc_entry.lock);
+
+ /* Non-blocking mode, fail write. */
+ if (file->f_flags & O_NONBLOCK)
+ return -EAGAIN;
+
+ /* Blocking mode, wait until other writes are done. */
+ interruptible_sleep_on(&interceptor->ipm_proc_entry.wait_queue);
+
+ if (signal_pending(current))
+ {
+ SSH_LINUX_PROCFS_DEBUG("interceptor_ipm_proc_entry_fop_write: "
+ "-ERESTARTSYS\n");
+ return -ERESTARTSYS;
+ }
+
+ goto retry;
+ }
+
+ interceptor->ipm_proc_entry.write_active = TRUE;
+ write_unlock(&interceptor->ipm_proc_entry.lock);
+
+ /* Receive data. */
+ total_len = 0;
+ user_buf = (char *) buf;
+ while (user_buf < (buf + write_len))
+ {
+ /* Copy data from user to receive buffer up to the maximum
+ allowed write size. */
+ user_buf = (char *) (buf + total_len);
+
+ recv_buf = (interceptor->ipm_proc_entry.recv_buf
+ + interceptor->ipm_proc_entry.recv_len);
+ recv_len = (interceptor->ipm_proc_entry.recv_buf_size
+ - interceptor->ipm_proc_entry.recv_len);
+
+ /* Break out of the loop if receive buffer is full. */
+ if (recv_len == 0)
+ break;
+
+ if (recv_len > (write_len - total_len))
+ recv_len = (write_len - total_len);
+
+ if (copy_from_user(recv_buf, user_buf, recv_len))
+ {
+ SSH_LINUX_PROCFS_WARN("interceptor_ipm_proc_entry_fop_write: "
+ "copy_from_user failed, dropping message\n");
+
+ write_lock(&interceptor->ipm_proc_entry.lock);
+ interceptor->ipm_proc_entry.write_active = FALSE;
+ write_unlock(&interceptor->ipm_proc_entry.lock);
+
+ wake_up_interruptible(&interceptor->ipm_proc_entry.wait_queue);
+ return -EFAULT;
+ }
+
+ total_len += recv_len;
+ interceptor->ipm_proc_entry.recv_len += recv_len;
+
+ /* Parse ipm messages. */
+ consumed = 0;
+ while (consumed < interceptor->ipm_proc_entry.recv_len)
+ {
+ msg_len =
+ ssh_interceptor_receive_from_ipm(interceptor->ipm_proc_entry.
+ recv_buf + consumed,
+ interceptor->ipm_proc_entry.
+ recv_len - consumed);
+
+ /* Need more data. */
+ if (msg_len == 0)
+ break;
+
+ /* Else continue parsing ipm messages. */
+ consumed += msg_len;
+ }
+
+ /* Move unparsed data to beginning of receive buffer. */
+ if (consumed > 0)
+ {
+ SSH_ASSERT(consumed <= interceptor->ipm_proc_entry.recv_len);
+
+ if (consumed < interceptor->ipm_proc_entry.recv_len)
+ memmove(interceptor->ipm_proc_entry.recv_buf,
+ interceptor->ipm_proc_entry.recv_buf + consumed,
+ interceptor->ipm_proc_entry.recv_len - consumed);
+
+ interceptor->ipm_proc_entry.recv_len -= consumed;
+ }
+
+ /* Continue receiving data from user. */
+ }
+
+ write_lock(&interceptor->ipm_proc_entry.lock);
+ interceptor->ipm_proc_entry.write_active = FALSE;
+ write_unlock(&interceptor->ipm_proc_entry.lock);
+
+ if (total_len == 0)
+ {
+ SSH_LINUX_PROCFS_WARN("interceptor_ipm_proc_entry_fop_write: "
+ "Out of receive buffer space\n");
+ return -ENOMEM;
+ }
+
+ SSH_ASSERT(total_len <= write_len);
+ return total_len;
+}
+
+static unsigned int
+interceptor_ipm_proc_entry_fop_poll(struct file *file,
+ struct poll_table_struct *table)
+{
+ unsigned int mask = 0;
+ SshInterceptor interceptor = file->private_data;
+
+ poll_wait(file, &interceptor->ipm_proc_entry.wait_queue, table);
+
+ /* Check if there are messages in the send queue. */
+ if (interceptor->ipm_proc_entry.send_msg != NULL)
+ mask |= (POLLIN | POLLRDNORM);
+
+ local_bh_disable();
+ read_lock(&interceptor->ipm.lock);
+
+ /* Check if there is a message pending for sending. */
+ if (interceptor->ipm.send_queue != NULL)
+ mask |= (POLLIN | POLLRDNORM);
+
+ /* /proc entry is always writable, unless send queue is too long. */
+ if (interceptor->ipm.msg_freelist != NULL
+ || interceptor->ipm.msg_allocated < SSH_LINUX_MAX_IPM_MESSAGES)
+ mask |= (POLLOUT | POLLWRNORM);
+
+ read_unlock(&interceptor->ipm.lock);
+ local_bh_enable();
+
+ return mask;
+}
+
+static int
+interceptor_ipm_proc_entry_fop_open(struct inode *inode,
+ struct file *file)
+{
+ write_lock(&ssh_interceptor_context->ipm_proc_entry.lock);
+
+ /* Allow only one read form userspace at a time. */
+ if (ssh_interceptor_context->ipm_proc_entry.open)
+ {
+ write_unlock(&ssh_interceptor_context->ipm_proc_entry.lock);
+ SSH_LINUX_PROCFS_DEBUG("interceptor_ipm_proc_entry_fop_open: -EBUSY\n");
+ return -EBUSY;
+ }
+
+ /* Check that engine initialization has been completed. */
+ if (ssh_interceptor_context->engine_open == FALSE)
+ {
+ write_unlock(&ssh_interceptor_context->ipm_proc_entry.lock);
+ SSH_LINUX_PROCFS_DEBUG("interceptor_ipm_proc_entry_fop_open: -EBUSY\n");
+ return -EBUSY;
+ }
+
+ /* Increment module ref to prohibit module unloading. */
+ if (!ssh_linux_module_inc_use_count())
+ {
+ write_unlock(&ssh_interceptor_context->ipm_proc_entry.lock);
+ SSH_LINUX_PROCFS_DEBUG("interceptor_ipm_proc_entry_fop_open: -EBUSY\n");
+ return -EBUSY;
+ }
+
+ file->private_data = ssh_interceptor_context;
+
+ ssh_interceptor_context->ipm_proc_entry.open = TRUE;
+
+ /* Clear receive buffer. */
+ ssh_interceptor_context->ipm_proc_entry.recv_len = 0;
+
+ write_unlock(&ssh_interceptor_context->ipm_proc_entry.lock);
+
+ interceptor_ipm_open(ssh_interceptor_context);
+ ssh_interceptor_notify_ipm_open(ssh_interceptor_context);
+
+ return 0;
+}
+
+static int
+interceptor_ipm_proc_entry_fop_release(struct inode *inode,
+ struct file *file)
+{
+ SshInterceptor interceptor = file->private_data;
+ SshInterceptorIpmMsg msg;
+
+ ssh_interceptor_notify_ipm_close(interceptor);
+ interceptor_ipm_close(interceptor);
+
+ write_lock(&interceptor->ipm_proc_entry.lock);
+
+ interceptor->ipm_proc_entry.open = FALSE;
+
+ /* Release the module reference. */
+ ssh_linux_module_dec_use_count();
+
+ /* Clear receive buffer. */
+ interceptor->ipm_proc_entry.recv_len = 0;
+
+ /* Free partial output message */
+ msg = interceptor->ipm_proc_entry.send_msg;
+ interceptor->ipm_proc_entry.send_msg = NULL;
+
+ write_unlock(&interceptor->ipm_proc_entry.lock);
+
+ if (msg)
+ interceptor_ipm_message_free(interceptor, msg);
+
+ return 0;
+}
+
+static struct file_operations ipm_proc_entry_fops =
+{
+ .read = interceptor_ipm_proc_entry_fop_read,
+ .write = interceptor_ipm_proc_entry_fop_write,
+ .poll = interceptor_ipm_proc_entry_fop_poll,
+ .open = interceptor_ipm_proc_entry_fop_open,
+ .release = interceptor_ipm_proc_entry_fop_release
+};
+
+static Boolean
+interceptor_ipm_proc_entry_init(SshInterceptor interceptor)
+{
+ /* Assert that parent dir exists. */
+ SSH_ASSERT(interceptor->proc_dir != NULL);
+
+ /* Initialize proc entry structure. */
+ init_waitqueue_head(&interceptor->ipm_proc_entry.wait_queue);
+ rwlock_init(&interceptor->ipm_proc_entry.lock);
+
+ write_lock(&interceptor->ipm_proc_entry.lock);
+ interceptor->ipm_proc_entry.open = TRUE;
+ interceptor->ipm_proc_entry.write_active = TRUE;
+ interceptor->ipm_proc_entry.read_active = TRUE;
+ write_unlock(&interceptor->ipm_proc_entry.lock);
+
+ interceptor->ipm_proc_entry.recv_buf_size = SSH_LINUX_IPM_RECV_BUFFER_SIZE;
+ interceptor->ipm_proc_entry.recv_buf =
+ ssh_malloc(interceptor->ipm_proc_entry.recv_buf_size);
+ if (interceptor->ipm_proc_entry.recv_buf == NULL)
+ return FALSE;
+
+ /* Create entry to procfs. */
+ interceptor->ipm_proc_entry.entry =
+ create_proc_entry(SSH_PROC_ENGINE, S_IFREG | S_IRUSR | S_IWUSR,
+ interceptor->proc_dir);
+
+ if (interceptor->ipm_proc_entry.entry == NULL)
+ return FALSE;
+
+#ifdef LINUX_HAS_PROC_DIR_ENTRY_OWNER
+ interceptor->ipm_proc_entry.entry->owner = THIS_MODULE;
+#endif
+
+ interceptor->ipm_proc_entry.entry->proc_iops = &common_proc_entry_iops;
+ interceptor->ipm_proc_entry.entry->proc_fops = &ipm_proc_entry_fops;
+ interceptor->ipm_proc_entry.entry->uid = (uid_t) ssh_procfs_uid;
+ interceptor->ipm_proc_entry.entry->gid = (uid_t) ssh_procfs_gid;
+ interceptor->ipm_proc_entry.entry->size = 0;
+
+ /* Mark proc entry ready for use. */
+ write_lock(&interceptor->ipm_proc_entry.lock);
+ interceptor->ipm_proc_entry.open = FALSE;
+ interceptor->ipm_proc_entry.write_active = FALSE;
+ interceptor->ipm_proc_entry.read_active = FALSE;
+ write_unlock(&interceptor->ipm_proc_entry.lock);
+
+ return TRUE;
+}
+
+static void
+interceptor_ipm_proc_entry_uninit(SshInterceptor interceptor)
+{
+ if (interceptor->ipm_proc_entry.recv_buf != NULL)
+ ssh_free(interceptor->ipm_proc_entry.recv_buf);
+ interceptor->ipm_proc_entry.recv_buf = NULL;
+
+ /* This should be safe to do without locking as interceptor code
+ does not refer `interceptor->ipm_proc_entry.entry' except in
+ init/uninit. */
+ if (interceptor->ipm_proc_entry.entry != NULL)
+ remove_proc_entry(interceptor->ipm_proc_entry.entry->name,
+ interceptor->proc_dir);
+ interceptor->ipm_proc_entry.entry = NULL;
+}
+
+/************************ Version proc_entry ********************************/
+
+static ssize_t
+interceptor_version_proc_entry_fop_read(struct file *file,
+ char __user *buf,
+ size_t len,
+ loff_t *pos)
+{
+ SshInterceptor interceptor = file->private_data;
+ ssize_t version_len;
+
+ /* Check if another read / write is ongoing */
+ write_lock(&interceptor->version_proc_entry.lock);
+ if (interceptor->version_proc_entry.active == TRUE)
+ {
+ write_unlock(&interceptor->version_proc_entry.lock);
+ return -EBUSY;
+ }
+ interceptor->version_proc_entry.active = TRUE;
+ write_unlock(&interceptor->version_proc_entry.lock);
+
+ if (*pos == 0)
+ {
+ version_len =
+ snprintf(interceptor->version_proc_entry.buf,
+ sizeof(interceptor->version_proc_entry.buf),
+ "VPNClient built on " __DATE__ " " __TIME__ "\n");
+ interceptor->version_proc_entry.buf_len = version_len;
+ }
+
+ else if (*pos >= interceptor->version_proc_entry.buf_len)
+ {
+ interceptor->version_proc_entry.buf_len = 0;
+ version_len = 0;
+ goto out;
+ }
+
+ else
+ {
+ version_len = interceptor->version_proc_entry.buf_len - *pos;
+ }
+
+ if (len < version_len)
+ version_len = len;
+
+ if (copy_to_user(buf, interceptor->version_proc_entry.buf + *pos,
+ version_len))
+ {
+ interceptor->version_proc_entry.buf_len = 0;
+ version_len = -EFAULT;
+ goto out;
+ }
+
+ *pos += version_len;
+
+ out:
+ write_lock(&interceptor->version_proc_entry.lock);
+ interceptor->version_proc_entry.active = FALSE;
+ write_unlock(&interceptor->version_proc_entry.lock);
+
+ return version_len;
+}
+
+static int
+interceptor_version_proc_entry_fop_open(struct inode *inode,
+ struct file *file)
+{
+ return interceptor_proc_entry_fop_open(&ssh_interceptor_context->
+ version_proc_entry,
+ file);
+}
+
+static int
+interceptor_version_proc_entry_fop_release(struct inode *inode,
+ struct file *file)
+{
+ SshInterceptor interceptor = file->private_data;
+ return interceptor_proc_entry_fop_release(&interceptor->version_proc_entry);
+}
+
+static struct file_operations version_proc_entry_fops =
+{
+ .read = interceptor_version_proc_entry_fop_read,
+ .open = interceptor_version_proc_entry_fop_open,
+ .release = interceptor_version_proc_entry_fop_release
+};
+
+static Boolean
+interceptor_version_proc_entry_init(SshInterceptor interceptor)
+{
+ /* Assert that parent dir exists. */
+ SSH_ASSERT(interceptor->proc_dir != NULL);
+
+ /* Initialize proc entry structure. */
+ rwlock_init(&interceptor->version_proc_entry.lock);
+ interceptor->version_proc_entry.buf_len = 0;
+
+ /* Take lock to use same variables always under lock to not confuse
+ static analysis. */
+ write_lock(&interceptor->version_proc_entry.lock);
+ interceptor->version_proc_entry.active = TRUE;
+ interceptor->version_proc_entry.open = TRUE;
+ write_unlock(&interceptor->version_proc_entry.lock);
+
+ /* Create entry to procfs. */
+ interceptor->version_proc_entry.entry =
+ create_proc_entry(SSH_PROC_VERSION, S_IFREG | S_IRUSR,
+ interceptor->proc_dir);
+
+ if (interceptor->version_proc_entry.entry == NULL)
+ return FALSE;
+
+#ifdef LINUX_HAS_PROC_DIR_ENTRY_OWNER
+ interceptor->version_proc_entry.entry->owner = THIS_MODULE;
+#endif
+
+ interceptor->version_proc_entry.entry->proc_iops = &common_proc_entry_iops;
+ interceptor->version_proc_entry.entry->proc_fops = &version_proc_entry_fops;
+ interceptor->version_proc_entry.entry->uid = (uid_t) ssh_procfs_uid;
+ interceptor->version_proc_entry.entry->gid = (uid_t) ssh_procfs_gid;
+ interceptor->version_proc_entry.entry->size = 0;
+
+ /* Mark proc entry ready for use. */
+ write_lock(&interceptor->version_proc_entry.lock);
+ interceptor->version_proc_entry.active = FALSE;
+ interceptor->version_proc_entry.open = FALSE;
+ write_unlock(&interceptor->version_proc_entry.lock);
+
+ return TRUE;
+}
+
+static void
+interceptor_version_proc_entry_uninit(SshInterceptor interceptor)
+{
+ if (interceptor->version_proc_entry.entry == NULL)
+ return;
+
+ /* This should be safe to do without locking as interceptor code
+ does not refer `interceptor->version_proc_entry.entry' except in
+ init/uninit. */
+ remove_proc_entry(interceptor->version_proc_entry.entry->name,
+ interceptor->proc_dir);
+ interceptor->version_proc_entry.entry = NULL;
+}
+
+
+/************************ Proc init / uninit ********************************/
+
+Boolean ssh_interceptor_proc_init(SshInterceptor interceptor)
+{
+ char name[128];
+
+ /* Create a directory under /proc/ */
+ snprintf(name, sizeof(name), "%s%s", SSH_PROC_ROOT, ssh_device_suffix);
+
+ interceptor->proc_dir = create_proc_entry(name, S_IFDIR, NULL);
+
+ if (interceptor->proc_dir == NULL)
+ goto error;
+
+ if (interceptor_ipm_proc_entry_init(interceptor) == FALSE)
+ goto error;
+
+ if (interceptor_version_proc_entry_init(interceptor) == FALSE)
+ goto error;
+
+ return TRUE;
+
+ error:
+ SSH_DEBUG(SSH_D_ERROR, ("Could not create /proc/%s", name));
+
+ interceptor_ipm_proc_entry_uninit(interceptor);
+ interceptor_version_proc_entry_uninit(interceptor);
+
+ if (interceptor->proc_dir)
+ remove_proc_entry(interceptor->proc_dir->name, NULL);
+ interceptor->proc_dir = NULL;
+
+ return FALSE;
+}
+
+void ssh_interceptor_proc_uninit(SshInterceptor interceptor)
+{
+ local_bh_enable();
+
+ interceptor_ipm_proc_entry_uninit(interceptor);
+ interceptor_version_proc_entry_uninit(interceptor);
+
+ if (interceptor->proc_dir)
+ remove_proc_entry(interceptor->proc_dir->name, NULL);
+ interceptor->proc_dir = NULL;
+
+ local_bh_disable();
+}
diff --git a/drivers/interceptor/linux_route.c b/drivers/interceptor/linux_route.c
new file mode 100644
index 0000000..ab93c6a
--- /dev/null
+++ b/drivers/interceptor/linux_route.c
@@ -0,0 +1,1136 @@
+/* Netfilter Driver for IPSec VPN Client
+ *
+ * Copyright(c) 2012 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.
+ */
+
+/*
+ * linux_route.c
+ *
+ * Linux interceptor implementation of interceptor API routing functions.
+ *
+ */
+
+#include "linux_internal.h"
+
+/****************** Internal data types and declarations ********************/
+
+typedef struct SshInterceptorRouteResultRec
+{
+ SshIpAddrStruct gw[1];
+ SshInterceptorIfnum ifnum;
+ SshUInt16 mtu;
+} SshInterceptorRouteResultStruct, *SshInterceptorRouteResult;
+
+/****************** Internal Utility Functions ******************************/
+
+#ifdef SSH_IPSEC_IP_ONLY_INTERCEPTOR
+#if (defined LINUX_FRAGMENTATION_AFTER_NF_POST_ROUTING) \
+ || (defined LINUX_FRAGMENTATION_AFTER_NF6_POST_ROUTING)
+
+/* Create a child dst_entry with locked interface MTU, and attach it to `dst'.
+ This is needed on newer linux kernels and IP_ONLY_INTERCEPTOR builds,
+ where the IP stack fragments packets to path MTU after ssh_interceptor_send.
+*/
+static struct dst_entry *
+interceptor_route_create_child_dst(struct dst_entry *dst, Boolean ipv6)
+{
+ struct dst_entry *child;
+#ifdef LINUX_HAS_DST_COPY_METRICS
+ SshUInt32 set;
+ struct rt6_info *rt6;
+ struct rtable *rt;
+#endif /* LINUX_HAS_DST_COPY_METRICS */
+
+ /* Allocate a dst_entry and copy relevant fields from dst. */
+ child = SSH_DST_ALLOC(dst);
+ if (child == NULL)
+ return NULL;
+
+ child->input = dst->input;
+ child->output = dst->output;
+
+ /* Child is not added to dst hash, and linux native IPsec is disabled. */
+ child->flags |= (DST_NOHASH | DST_NOPOLICY | DST_NOXFRM);
+
+ /* Copy route metrics and lock MTU to interface MTU. */
+#ifdef LINUX_HAS_DST_COPY_METRICS
+ if (ipv6 == TRUE)
+ {
+ rt6 = (struct rt6_info *)child;
+ memset(&rt6->rt6i_table, 0, sizeof(*rt6) - sizeof(struct dst_entry));
+ }
+ else
+ {
+ rt = (struct rtable *)child;
+ memset(&SSH_RTABLE_FIRST_MEMBER(rt), 0,
+ sizeof(*rt) - sizeof(struct dst_entry));
+ }
+
+ dst_copy_metrics(child, dst);
+ set = dst_metric(child, RTAX_LOCK);
+ set |= 1 << RTAX_MTU;
+ dst_metric_set(child, RTAX_LOCK, set);
+#else /* LINUX_HAS_DST_COPY_METRICS */
+ memcpy(child->metrics, dst->metrics, sizeof(child->metrics));
+ child->metrics[RTAX_LOCK-1] |= 1 << RTAX_MTU;
+#endif /* LINUX_HAS_DST_COPY_METRICS */
+
+#ifdef CONFIG_NET_CLS_ROUTE
+ child->tclassid = dst->tclassid;
+#endif /* CONFIG_NET_CLS_ROUTE */
+
+#ifdef CONFIG_XFRM
+ child->xfrm = NULL;
+#endif /* CONFIG_XFRM */
+
+#ifdef LINUX_HAS_HH_CACHE
+ if (dst->hh)
+ {
+ atomic_inc(&dst->hh->hh_refcnt);
+ child->hh = dst->hh;
+ }
+#endif /* LINUX_HAS_HH_CACHE */
+
+#ifdef LINUX_HAS_DST_NEIGHBOUR_FUNCTIONS
+ if (dst_get_neighbour(dst) != NULL)
+ dst_set_neighbour(child, neigh_clone(dst_get_neighbour(dst)));
+#else /* LINUX_HAS_DST_NEIGHBOUR_FUNCTIONS */
+ if (dst->neighbour != NULL)
+ child->neighbour = neigh_clone(dst->neighbour);
+#endif /* LINUX_HAS_DST_NEIGHBOUR_FUNCTIONS */
+
+ if (dst->dev)
+ {
+ dev_hold(dst->dev);
+ child->dev = dst->dev;
+ }
+
+ SSH_ASSERT(dst->child == NULL);
+ dst->child = dst_clone(child);
+
+ SSH_DEBUG(SSH_D_MIDOK, ("Allocated child %p dst_entry for dst %p mtu %d",
+ child, dst, dst_mtu(dst)));
+
+ return child;
+}
+
+#endif /* LINUX_FRAGMENTATION_AFTER_NF_POST_ROUTING
+ || LINUX_FRAGMENTATION_AFTER_NF6_POST_ROUTING */
+#endif /* SSH_IPSEC_IP_ONLY_INTERCEPTOR */
+
+static inline int interceptor_ip4_route_output(struct rtable **rt,
+ struct flowi *fli)
+{
+ int rval = 0;
+#ifdef LINUX_USE_NF_FOR_ROUTE_OUTPUT
+ struct dst_entry *dst = NULL;
+ const struct nf_afinfo *afinfo = NULL;
+ unsigned short family = AF_INET;
+
+ rcu_read_lock();
+ afinfo = nf_get_afinfo(family);
+ if (!afinfo)
+ {
+ rcu_read_unlock();
+ SSH_DEBUG(SSH_D_FAIL, ("Failed to get nf afinfo"));
+ return -1;
+ }
+
+ rval = afinfo->route(&init_net, &dst, fli, TRUE);
+ rcu_read_unlock();
+
+ *rt = (struct rtable *)dst;
+
+#else /* LINUX_USE_NF_FOR_ROUTE_OUTPUT */
+
+#ifdef LINUX_IP_ROUTE_OUTPUT_KEY_HAS_NET_ARGUMENT
+ rval = ip_route_output_key(&init_net, rt, fli);
+#else /* LINUX_IP_ROUTE_OUTPUT_KEY_HAS_NET_ARGUMENT */
+ rval = ip_route_output_key(rt, fli);
+#endif /* LINUX_IP_ROUTE_OUTPUT_KEY_HAS_NET_ARGUMENT */
+#endif /* LINUX_USE_NF_FOR_ROUTE_OUTPUT */
+
+ if (rval > 0)
+ rval = -rval;
+
+ return rval;
+}
+
+static inline struct dst_entry *interceptor_ip6_route_output(struct flowi *fli)
+{
+ struct dst_entry *dst = NULL;
+
+ /* Perform route lookup */
+ /* we do not need a socket, only fake flow */
+#ifdef LINUX_USE_NF_FOR_ROUTE_OUTPUT
+ const struct nf_afinfo *afinfo = NULL;
+ unsigned short family = AF_INET6;
+ int rval = 0;
+
+ rcu_read_lock();
+ afinfo = nf_get_afinfo(family);
+ if (!afinfo)
+ {
+ rcu_read_unlock();
+ SSH_DEBUG(SSH_D_FAIL, ("Failed to get nf afinfo"));
+ return NULL;
+ }
+
+ rval = afinfo->route(&init_net, &dst, fli, FALSE);
+ rcu_read_unlock();
+ if (rval != 0)
+ {
+ SSH_DEBUG(SSH_D_FAIL, ("Failed to get route from IPv6 NF"));
+ return NULL;
+ }
+#else /* LINUX_USE_NF_FOR_ROUTE_OUTPUT */
+
+#ifdef LINUX_IP6_ROUTE_OUTPUT_KEY_HAS_NET_ARGUMENT
+ dst = ip6_route_output(&init_net, NULL, fli);
+#else /* LINUX_IP6_ROUTE_OUTPUT_KEY_HAS_NET_ARGUMENT */
+ dst = ip6_route_output(NULL, fli);
+#endif /* LINUX_IP6_ROUTE_OUTPUT_KEY_HAS_NET_ARGUMENT */
+#endif /* LINUX_USE_NF_FOR_ROUTE_OUTPUT */
+
+ return dst;
+}
+
+/****************** Implementation of ssh_interceptor_route *****************/
+
+/* Perform route lookup using linux ip_route_output_key.
+
+ The route lookup will use the following selectors:
+ dst, src, outbound ifnum, ip protocol, tos, and fwmark.
+ The source address is expected to be local or undefined.
+
+ The following selectors are ignored:
+ dst port, src port, icmp type, icmp code, ipsec spi. */
+Boolean
+ssh_interceptor_route_output_ipv4(SshInterceptor interceptor,
+ SshInterceptorRouteKey key,
+ SshUInt16 selector,
+ SshInterceptorRouteResult result)
+{
+ u32 daddr;
+ struct rtable *rt;
+ int rval;
+ struct flowi rt_key;
+ u16 rt_type;
+#ifdef DEBUG_LIGHT
+ unsigned char *rt_type_str;
+ u32 fwmark = 0;
+ unsigned char dst_buf[SSH_IP_ADDR_STRING_SIZE];
+ unsigned char src_buf[SSH_IP_ADDR_STRING_SIZE];
+#endif /* DEBUG_LIGHT */
+
+ SSH_IP4_ENCODE(&key->dst, (unsigned char *) &daddr);
+
+ /* Initialize rt_key with zero values */
+ memset(&rt_key, 0, sizeof(rt_key));
+
+ rt_key.fl4_dst = daddr;
+ if (selector & SSH_INTERCEPTOR_ROUTE_KEY_SRC)
+ SSH_IP4_ENCODE(&key->src, (unsigned char *) &rt_key.fl4_src);
+ if (selector & SSH_INTERCEPTOR_ROUTE_KEY_OUT_IFNUM)
+ {
+ SSH_LINUX_ASSERT_VALID_IFNUM(key->ifnum);
+ rt_key.oif = key->ifnum;
+ }
+ if (selector & SSH_INTERCEPTOR_ROUTE_KEY_IPPROTO)
+ rt_key.proto = key->ipproto;
+ if (selector & SSH_INTERCEPTOR_ROUTE_KEY_IP4_TOS)
+ rt_key.fl4_tos = key->nh.ip4.tos;
+ rt_key.fl4_scope = RT_SCOPE_UNIVERSE;
+
+#if (SSH_INTERCEPTOR_NUM_EXTENSION_SELECTORS > 0)
+#ifdef SSH_LINUX_FWMARK_EXTENSION_SELECTOR
+
+ /* Use linux fw_mark in routing */
+ if (selector & SSH_INTERCEPTOR_ROUTE_KEY_EXTENSION)
+ {
+#ifdef LINUX_HAS_SKB_MARK
+ rt_key.mark = key->extension[SSH_LINUX_FWMARK_EXTENSION_SELECTOR];
+#else /* LINUX_HAS_SKB_MARK */
+#ifdef CONFIG_IP_ROUTE_FWMARK
+ rt_key.fl4_fwmark =
+ key->extension[SSH_LINUX_FWMARK_EXTENSION_SELECTOR];
+#endif /* CONFIG_IP_ROUTE_FWMARK */
+#endif /* LINUX_HAS_SKB_MARK */
+#ifdef DEBUG_LIGHT
+ fwmark = key->extension[SSH_LINUX_FWMARK_EXTENSION_SELECTOR];
+#endif /* DEBUG_LIGHT */
+ }
+
+#endif /* SSH_LINUX_FWMARK_EXTENSION_SELECTOR */
+#endif /* (SSH_INTERCEPTOR_NUM_EXTENSION_SELECTORS > 0) */
+
+ SSH_DEBUG(SSH_D_LOWOK,
+ ("Route lookup: "
+ "dst %s src %s ifnum %d ipproto %d tos 0x%02x fwmark 0x%lx",
+ ssh_ipaddr_print(&key->dst, dst_buf, sizeof(dst_buf)),
+ ((selector & SSH_INTERCEPTOR_ROUTE_KEY_SRC) ?
+ ssh_ipaddr_print(&key->src, src_buf, sizeof(src_buf)) : NULL),
+ (int) ((selector & SSH_INTERCEPTOR_ROUTE_KEY_OUT_IFNUM)?
+ key->ifnum : -1),
+ (int) ((selector & SSH_INTERCEPTOR_ROUTE_KEY_IPPROTO) ?
+ key->ipproto : -1),
+ ((selector & SSH_INTERCEPTOR_ROUTE_KEY_IP4_TOS) ?
+ key->nh.ip4.tos : 0),
+ (unsigned long) ((selector & SSH_INTERCEPTOR_ROUTE_KEY_EXTENSION)?
+ fwmark : 0)));
+
+ /* Perform route lookup */
+
+ rval = interceptor_ip4_route_output(&rt, &rt_key);
+ if (rval < 0)
+ {
+ goto fail;
+ }
+
+ /* Get the gateway, mtu and ifnum */
+
+ SSH_IP4_DECODE(result->gw, &rt->rt_gateway);
+ result->mtu = SSH_DST_MTU(&SSH_RT_DST(rt));
+ result->ifnum = SSH_RT_DST(rt).dev->ifindex;
+ rt_type = rt->rt_type;
+
+#ifdef DEBUG_LIGHT
+ switch (rt_type)
+ {
+ case RTN_UNSPEC:
+ rt_type_str = "unspec";
+ break;
+ case RTN_UNICAST:
+ rt_type_str = "unicast";
+ break;
+ case RTN_LOCAL:
+ rt_type_str = "local";
+ break;
+ case RTN_BROADCAST:
+ rt_type_str = "broadcast";
+ break;
+ case RTN_ANYCAST:
+ rt_type_str = "anycast";
+ break;
+ case RTN_MULTICAST:
+ rt_type_str = "multicast";
+ break;
+ case RTN_BLACKHOLE:
+ rt_type_str = "blackhole";
+ break;
+ case RTN_UNREACHABLE:
+ rt_type_str = "unreachable";
+ break;
+ case RTN_PROHIBIT:
+ rt_type_str = "prohibit";
+ break;
+ case RTN_THROW:
+ rt_type_str = "throw";
+ break;
+ case RTN_NAT:
+ rt_type_str = "nat";
+ break;
+ case RTN_XRESOLVE:
+ rt_type_str = "xresolve";
+ break;
+ default:
+ rt_type_str = "unknown";
+ }
+#endif /* DEBUG_LIGHT */
+
+ SSH_DEBUG(SSH_D_LOWOK,
+ ("Route result: dst %s via %s ifnum %d[%s] mtu %d type %s [%d]",
+ dst_buf, ssh_ipaddr_print(result->gw, src_buf, sizeof(src_buf)),
+ (int) result->ifnum,
+ (SSH_RT_DST(rt).dev->name ? SSH_RT_DST(rt).dev->name : "none"),
+ result->mtu, rt_type_str, rt_type));
+
+#ifdef SSH_IPSEC_IP_ONLY_INTERCEPTOR
+#ifdef LINUX_FRAGMENTATION_AFTER_NF_POST_ROUTING
+ /* Check if need to create a child dst_entry with interface MTU. */
+ if ((selector & SSH_INTERCEPTOR_ROUTE_KEY_FLAG_TRANSFORM_APPLIED)
+ && SSH_RT_DST(rt).child == NULL)
+ {
+ if (interceptor_route_create_child_dst(&SSH_RT_DST(rt), FALSE) == NULL)
+ SSH_DEBUG(SSH_D_FAIL, ("Could not create child dst_entry for dst %p",
+ &SSH_RT_DST(rt)));
+ }
+#endif /* LINUX_FRAGMENTATION_AFTER_NF_POST_ROUTING */
+#endif /* SSH_IPSEC_IP_ONLY_INTERCEPTOR */
+
+ /* Release the routing table entry ; otherwise a memory leak occurs
+ in the route entry table. */
+ ip_rt_put(rt);
+
+ /* Assert that ifnum fits into the SshInterceptorIfnum data type. */
+ SSH_LINUX_ASSERT_IFNUM(result->ifnum);
+
+ /* Check that ifnum does not collide with SSH_INTERCEPTOR_INVALID_IFNUM. */
+ if (result->ifnum == SSH_INTERCEPTOR_INVALID_IFNUM)
+ goto fail;
+
+ /* Accept only unicast, broadcast, anycast, multicast and local routes */
+ if (rt_type == RTN_UNICAST
+ || rt_type == RTN_BROADCAST
+ || rt_type == RTN_ANYCAST
+ || rt_type == RTN_MULTICAST
+ || rt_type == RTN_LOCAL)
+ {
+ SSH_LINUX_ASSERT_VALID_IFNUM(result->ifnum);
+ return TRUE;
+ }
+
+ fail:
+ /* Fail route lookup for other route types */
+ SSH_DEBUG(SSH_D_FAIL, ("Route lookup for %s failed with code %d",
+ dst_buf, rval));
+
+ return FALSE;
+}
+
+
+/* Perform route lookup using linux ip_route_input.
+
+ The route lookup will use the following selectors:
+ dst, src, inbound ifnum, ip protocol, tos, and fwmark.
+ The source address is expected to be non-local and it must be defined.
+
+ The following selectors are ignored:
+ dst port, src port, icmp type, icmp code, ipsec spi. */
+Boolean
+ssh_interceptor_route_input_ipv4(SshInterceptor interceptor,
+ SshInterceptorRouteKey key,
+ SshUInt16 selector,
+ SshInterceptorRouteResult result)
+{
+ u32 daddr, saddr;
+ u8 ipproto;
+ u8 tos;
+ u32 fwmark;
+ struct sk_buff *skbp;
+ struct net_device *dev;
+ struct rtable *rt;
+ int rval = 0;
+ u16 rt_type;
+ struct iphdr *iph = NULL;
+#ifdef DEBUG_LIGHT
+ unsigned char *rt_type_str;
+ unsigned char dst_buf[SSH_IP_ADDR_STRING_SIZE];
+ unsigned char src_buf[SSH_IP_ADDR_STRING_SIZE];
+#endif /* DEBUG_LIGHT */
+
+ SSH_IP4_ENCODE(&key->dst, (unsigned char *) &daddr);
+
+ /* Initialize */
+ saddr = 0;
+ ipproto = 0;
+ tos = 0;
+ fwmark = 0;
+ dev = NULL;
+
+ if (selector & SSH_INTERCEPTOR_ROUTE_KEY_SRC)
+ SSH_IP4_ENCODE(&key->src, (unsigned char *) &saddr);
+ if (selector & SSH_INTERCEPTOR_ROUTE_KEY_IN_IFNUM)
+ {
+ SSH_LINUX_ASSERT_VALID_IFNUM(key->ifnum);
+ dev = ssh_interceptor_ifnum_to_netdev(interceptor, key->ifnum);
+ }
+
+ if (dev == NULL)
+ return FALSE;
+
+ if (selector & SSH_INTERCEPTOR_ROUTE_KEY_IPPROTO)
+ ipproto = key->ipproto;
+ if (selector & SSH_INTERCEPTOR_ROUTE_KEY_IP4_TOS)
+ tos = key->nh.ip4.tos;
+
+#if (SSH_INTERCEPTOR_NUM_EXTENSION_SELECTORS > 0)
+#ifdef SSH_LINUX_FWMARK_EXTENSION_SELECTOR
+ /* Use linux fw_mark in routing */
+ if (selector & SSH_INTERCEPTOR_ROUTE_KEY_EXTENSION)
+ fwmark = key->extension[SSH_LINUX_FWMARK_EXTENSION_SELECTOR];
+#endif /* SSH_LINUX_FWMARK_EXTENSION_SELECTOR */
+#endif /* (SSH_INTERCEPTOR_NUM_EXTENSION_SELECTORS > 0) */
+
+ /* Build dummy skb */
+ skbp = alloc_skb(SSH_IPH4_HDRLEN, GFP_ATOMIC);
+ if (skbp == NULL)
+ goto fail;
+
+ SSH_SKB_RESET_MACHDR(skbp);
+ iph = (struct iphdr *) skb_put(skbp, SSH_IPH4_HDRLEN);
+ if (iph == NULL)
+ {
+ dev_kfree_skb(skbp);
+ goto fail;
+ }
+ SSH_SKB_SET_NETHDR(skbp, (unsigned char *) iph);
+
+ SSH_SKB_DST_SET(skbp, NULL);
+ skbp->protocol = __constant_htons(ETH_P_IP);
+ SSH_SKB_MARK(skbp) = fwmark;
+ iph->protocol = ipproto;
+
+ SSH_DEBUG(SSH_D_LOWOK,
+ ("Route lookup: "
+ "dst %s src %s ifnum %d[%s] ipproto %d tos 0x%02x fwmark 0x%x",
+ ssh_ipaddr_print(&key->dst, dst_buf, sizeof(dst_buf)),
+ ((selector & SSH_INTERCEPTOR_ROUTE_KEY_SRC) ?
+ ssh_ipaddr_print(&key->src, src_buf, sizeof(src_buf)) : NULL),
+ dev->ifindex, dev->name,
+ ipproto, tos, fwmark));
+
+ /* Perform route lookup */
+
+ rval = ip_route_input(skbp, daddr, saddr, tos, dev);
+ if (rval < 0 || SSH_SKB_DST(skbp) == NULL)
+ {
+ dev_kfree_skb(skbp);
+ goto fail;
+ }
+
+ /* Get the gateway, mtu and ifnum */
+ rt = (struct rtable *) SSH_SKB_DST(skbp);
+ SSH_IP4_DECODE(result->gw, &rt->rt_gateway);
+ result->mtu = SSH_DST_MTU(SSH_SKB_DST(skbp));
+ result->ifnum = SSH_SKB_DST(skbp)->dev->ifindex;
+ rt_type = rt->rt_type;
+
+#ifdef DEBUG_LIGHT
+ switch (rt_type)
+ {
+ case RTN_UNSPEC:
+ rt_type_str = "unspec";
+ break;
+ case RTN_UNICAST:
+ rt_type_str = "unicast";
+ break;
+ case RTN_LOCAL:
+ rt_type_str = "local";
+ break;
+ case RTN_BROADCAST:
+ rt_type_str = "broadcast";
+ break;
+ case RTN_ANYCAST:
+ rt_type_str = "anycast";
+ break;
+ case RTN_MULTICAST:
+ rt_type_str = "multicast";
+ break;
+ case RTN_BLACKHOLE:
+ rt_type_str = "blackhole";
+ break;
+ case RTN_UNREACHABLE:
+ rt_type_str = "unreachable";
+ break;
+ case RTN_PROHIBIT:
+ rt_type_str = "prohibit";
+ break;
+ case RTN_THROW:
+ rt_type_str = "throw";
+ break;
+ case RTN_NAT:
+ rt_type_str = "nat";
+ break;
+ case RTN_XRESOLVE:
+ rt_type_str = "xresolve";
+ break;
+ default:
+ rt_type_str = "unknown";
+ }
+#endif /* DEBUG_LIGHT */
+
+ SSH_DEBUG(SSH_D_LOWOK,
+ ("Route result: dst %s via %s ifnum %d[%s] mtu %d type %s [%d]",
+ dst_buf, ssh_ipaddr_print(result->gw, src_buf, sizeof(src_buf)),
+ (int) result->ifnum,
+ (SSH_RT_DST(rt).dev->name ? SSH_RT_DST(rt).dev->name : "none"),
+ result->mtu, rt_type_str, rt_type));
+
+#ifdef SSH_IPSEC_IP_ONLY_INTERCEPTOR
+#ifdef LINUX_FRAGMENTATION_AFTER_NF_POST_ROUTING
+ /* Check if need to create a child dst_entry with interface MTU. */
+ if ((selector & SSH_INTERCEPTOR_ROUTE_KEY_FLAG_TRANSFORM_APPLIED)
+ && SSH_SKB_DST(skbp)->child == NULL)
+ {
+ if (interceptor_route_create_child_dst(SSH_SKB_DST(skbp), FALSE) == NULL)
+ SSH_DEBUG(SSH_D_FAIL, ("Could not create child dst_entry for dst %p",
+ SSH_SKB_DST(skbp)));
+ }
+#endif /* LINUX_FRAGMENTATION_AFTER_NF_POST_ROUTING */
+#endif /* SSH_IPSEC_IP_ONLY_INTERCEPTOR */
+
+ /* Release the routing table entry ; otherwise a memory leak occurs
+ in the route entry table. */
+ dst_release(SSH_SKB_DST(skbp));
+ SSH_SKB_DST_SET(skbp, NULL);
+ dev_kfree_skb(skbp);
+
+ /* Assert that ifnum fits into the SshInterceptorIfnum data type. */
+ SSH_LINUX_ASSERT_IFNUM(result->ifnum);
+
+ /* Check that ifnum does not collide with SSH_INTERCEPTOR_INVALID_IFNUM. */
+ if (result->ifnum == SSH_INTERCEPTOR_INVALID_IFNUM)
+ goto fail;
+
+ /* Accept only unicast, broadcast, anycast, multicast and local routes. */
+ if (rt_type == RTN_UNICAST
+ || rt_type == RTN_BROADCAST
+ || rt_type == RTN_ANYCAST
+ || rt_type == RTN_MULTICAST
+ || rt_type == RTN_LOCAL)
+ {
+ ssh_interceptor_release_netdev(dev);
+ SSH_LINUX_ASSERT_VALID_IFNUM(result->ifnum);
+ return TRUE;
+ }
+
+ /* Fail route lookup for other route types. */
+ fail:
+ ssh_interceptor_release_netdev(dev);
+
+ SSH_DEBUG(SSH_D_FAIL,
+ ("Route lookup for %s failed with code %d",
+ ssh_ipaddr_print(&key->dst, dst_buf, sizeof(dst_buf)), rval));
+
+ return FALSE;
+}
+
+#ifdef SSH_LINUX_INTERCEPTOR_IPV6
+
+/* Perform route lookup using linux ip6_route_output.
+
+ The route lookup will use the following selectors:
+ dst, src, outbound ifnum.
+
+ The following selectors are ignored:
+ ipv6 priority, flowlabel, ip protocol, dst port, src port,
+ icmp type, icmp code, ipsec spi, and fwmark. */
+Boolean
+ssh_interceptor_route_output_ipv6(SshInterceptor interceptor,
+ SshInterceptorRouteKey key,
+ SshUInt16 selector,
+ SshInterceptorRouteResult result)
+{
+ struct flowi rt_key;
+ struct dst_entry *dst;
+ struct rt6_info *rt;
+ u32 rt6i_flags;
+ int error = 0;
+ struct neighbour *neigh;
+#ifdef DEBUG_LIGHT
+ unsigned char dst_buf[SSH_IP_ADDR_STRING_SIZE];
+ unsigned char src_buf[SSH_IP_ADDR_STRING_SIZE];
+#endif /* DEBUG_LIGHT */
+
+ memset(&rt_key, 0, sizeof(rt_key));
+
+ SSH_IP6_ENCODE(&key->dst, rt_key.fl6_dst.s6_addr);
+
+ if (selector & SSH_INTERCEPTOR_ROUTE_KEY_SRC)
+ SSH_IP6_ENCODE(&key->src, rt_key.fl6_src.s6_addr);
+
+ if (selector & SSH_INTERCEPTOR_ROUTE_KEY_OUT_IFNUM)
+ {
+ SSH_LINUX_ASSERT_VALID_IFNUM(key->ifnum);
+ rt_key.oif = key->ifnum;
+ }
+
+ SSH_DEBUG(SSH_D_LOWOK,
+ ("Route lookup: dst %s src %s ifnum %d",
+ ssh_ipaddr_print(&key->dst, dst_buf, sizeof(dst_buf)),
+ ((selector & SSH_INTERCEPTOR_ROUTE_KEY_SRC) ?
+ ssh_ipaddr_print(&key->src, src_buf, sizeof(src_buf)) : NULL),
+ (int) ((selector & SSH_INTERCEPTOR_ROUTE_KEY_OUT_IFNUM) ?
+ key->ifnum : -1)));
+
+ dst = interceptor_ip6_route_output(&rt_key);
+ if (dst == NULL)
+ {
+ goto fail;
+ }
+ else if (dst->error != 0)
+ {
+ error = dst->error;
+ /* Release dst_entry */
+ dst_release(dst);
+ goto fail;
+ }
+
+ rt = (struct rt6_info *) dst;
+
+ /* Get the gateway, mtu and ifnum */
+
+ /* For an example of retrieving routing information for IPv6
+ within Linux kernel (2.4.19) see inet6_rtm_getroute()
+ in /usr/src/linux/net/ipv6/route.c */
+#ifdef LINUX_HAS_DST_NEIGHBOUR_FUNCTIONS
+ neigh = dst_get_neighbour(&rt->dst);
+#else /* LINUX_HAS_DST_NEIGHBOUR_FUNCTIONS */
+ neigh = rt->rt6i_nexthop;
+#endif /* LINUX_HAS_DST_NEIGHBOUR_FUNCTIONS */
+
+ if (neigh != NULL)
+ SSH_IP6_DECODE(result->gw, &neigh->primary_key);
+ else
+ SSH_IP6_DECODE(result->gw, &rt_key.fl6_dst.s6_addr);
+
+ result->mtu = SSH_DST_MTU(&SSH_RT_DST(rt));
+
+ /* The interface number might not be ok, but that is a problem
+ for the recipient of the routing information. */
+ result->ifnum = dst->dev->ifindex;
+
+ rt6i_flags = rt->rt6i_flags;
+
+ SSH_DEBUG(SSH_D_LOWOK,
+ ("Route result: %s via %s ifnum %d[%s] mtu %d flags 0x%08x[%s%s]",
+ dst_buf, ssh_ipaddr_print(result->gw, src_buf, sizeof(src_buf)),
+ (int) result->ifnum, (dst->dev ? dst->dev->name : "none"),
+ result->mtu, rt6i_flags, ((rt6i_flags & RTF_UP) ? "up " : ""),
+ ((rt6i_flags & RTF_REJECT) ? "reject" : "")));
+
+
+#ifdef SSH_IPSEC_IP_ONLY_INTERCEPTOR
+#ifdef LINUX_FRAGMENTATION_AFTER_NF6_POST_ROUTING
+ /* Check if need to create a child dst_entry with interface MTU. */
+ if (selector & SSH_INTERCEPTOR_ROUTE_KEY_FLAG_TRANSFORM_APPLIED)
+ {
+ if (dst->child == NULL)
+ if (interceptor_route_create_child_dst(dst, TRUE) == NULL)
+ SSH_DEBUG(SSH_D_FAIL, ("Could not create child dst_entry for dst %p",
+ dst));
+ }
+#endif /* LINUX_FRAGMENTATION_AFTER_NF6_POST_ROUTING */
+#endif /* SSH_IPSEC_IP_ONLY_INTERCEPTOR */
+
+ /* Release dst_entry */
+ dst_release(dst);
+
+ /* Assert that ifnum fits into the SshInterceptorIfnum data type. */
+ SSH_LINUX_ASSERT_IFNUM(result->ifnum);
+
+ /* Check that ifnum does not collide with SSH_INTERCEPTOR_INVALID_IFNUM. */
+ if (result->ifnum == SSH_INTERCEPTOR_INVALID_IFNUM)
+ goto fail;
+
+ /* Accept only valid routes */
+ if ((rt6i_flags & RTF_UP)
+ && (rt6i_flags & RTF_REJECT) == 0)
+ {
+ SSH_LINUX_ASSERT_VALID_IFNUM(result->ifnum);
+ return TRUE;
+ }
+
+ /* Fail route lookup for reject and unknown routes */
+ fail:
+ SSH_DEBUG(SSH_D_FAIL, ("Route lookup for %s failed with code %d",
+ dst_buf, error));
+
+ return FALSE;
+}
+#endif /* SSH_LINUX_INTERCEPTOR_IPV6 */
+
+/* Performs a route lookup for the given destination address.
+ This also always calls a callback function. */
+
+void
+ssh_interceptor_route(SshInterceptor interceptor,
+ SshInterceptorRouteKey key,
+ SshInterceptorRouteCompletion callback,
+ void *cb_context)
+{
+ SshInterceptorRouteResultStruct result;
+
+ /* It is a fatal error to call ssh_interceptor_route with
+ a routing key that does not specify the destination address. */
+ SSH_ASSERT(SSH_IP_DEFINED(&key->dst));
+
+ if (SSH_IP_IS4(&key->dst))
+ {
+ /* Key specifies non-local src address and inbound ifnum
+ -> use ssh_interceptor_route_input_ipv4 */
+ if ((key->selector & SSH_INTERCEPTOR_ROUTE_KEY_SRC)
+ && (key->selector & SSH_INTERCEPTOR_ROUTE_KEY_FLAG_LOCAL_SRC) == 0
+ && (key->selector & SSH_INTERCEPTOR_ROUTE_KEY_IN_IFNUM))
+ {
+ /* Assert that all mandatory selectors are present. */
+ SSH_ASSERT(key->selector & SSH_INTERCEPTOR_ROUTE_KEY_SRC);
+ SSH_ASSERT(SSH_IP_IS4(&key->src));
+ SSH_ASSERT(key->selector & SSH_INTERCEPTOR_ROUTE_KEY_IN_IFNUM);
+
+ if (!ssh_interceptor_route_input_ipv4(interceptor, key,
+ key->selector, &result))
+ goto fail;
+ }
+
+ /* Otherwise use ssh_interceptor_route_output_ipv4 */
+ else
+ {
+ SshUInt16 selector = key->selector;
+
+ /* Assert that all mandatory selectors are present. */
+ SSH_ASSERT((key->selector & SSH_INTERCEPTOR_ROUTE_KEY_SRC) == 0
+ || SSH_IP_IS4(&key->src));
+
+ /* Key specifies non-local src address.
+ Linux ip_route_output_key will fail such route lookups,
+ so we must clear the src address selector and do the
+ route lookup as if src was one of local addresses.
+ For example, locally generated TCP RST packets are
+ such packets. */
+ if ((key->selector & SSH_INTERCEPTOR_ROUTE_KEY_FLAG_LOCAL_SRC) == 0)
+ selector &= ~SSH_INTERCEPTOR_ROUTE_KEY_SRC;
+
+ if (!ssh_interceptor_route_output_ipv4(interceptor, key, selector,
+ &result))
+ goto fail;
+ }
+
+ (*callback)(TRUE, result.gw, result.ifnum, result.mtu, cb_context);
+ return;
+ }
+
+#ifdef SSH_LINUX_INTERCEPTOR_IPV6
+ if (SSH_IP_IS6(&key->dst))
+ {
+ /* Assert that all mandatory selectors are present. */
+ SSH_ASSERT((key->selector & SSH_INTERCEPTOR_ROUTE_KEY_SRC) == 0
+ || SSH_IP_IS6(&key->src));
+
+ /* Always use ip6_route_output for IPv6 */
+ if (!ssh_interceptor_route_output_ipv6(interceptor, key, key->selector,
+ &result))
+ goto fail;
+
+ (*callback)(TRUE, result.gw, result.ifnum, result.mtu, cb_context);
+ return;
+ }
+#endif /* SSH_LINUX_INTERCEPTOR_IPV6 */
+
+ /* Fallback to error */
+ fail:
+ SSH_DEBUG(SSH_D_FAIL, ("Route lookup failed, unknown dst address type"));
+ (*callback) (FALSE, NULL, 0, 0, cb_context);
+}
+
+
+/**************************** Rerouting of Packets **************************/
+
+
+/* Route IPv4 packet 'skbp', using the route key selectors in
+ 'route_selector' and the interface number 'ifnum_in'. */
+Boolean
+ssh_interceptor_reroute_skb_ipv4(SshInterceptor interceptor,
+ struct sk_buff *skbp,
+ SshUInt16 route_selector,
+ SshUInt32 ifnum_in)
+{
+ struct iphdr *iph;
+ int rval = 0;
+
+ /* Recalculate the route info as the engine might have touched the
+ destination address. This can happen for example if we are in
+ tunnel mode. */
+
+ iph = (struct iphdr *) SSH_SKB_GET_NETHDR(skbp);
+ if (iph == NULL)
+ {
+ SSH_DEBUG(SSH_D_ERROR, ("Could not access IP header"));
+ return FALSE;
+ }
+
+ /* Release old dst_entry */
+ if (SSH_SKB_DST(skbp))
+ dst_release(SSH_SKB_DST(skbp));
+
+ SSH_SKB_DST_SET(skbp, NULL);
+
+ if ((route_selector & SSH_INTERCEPTOR_ROUTE_KEY_SRC)
+ && (route_selector & SSH_INTERCEPTOR_ROUTE_KEY_FLAG_LOCAL_SRC) == 0
+ && (route_selector & SSH_INTERCEPTOR_ROUTE_KEY_IN_IFNUM))
+ {
+ u32 saddr = 0;
+ u8 ipproto = 0;
+ u8 tos = 0;
+#if (SSH_INTERCEPTOR_NUM_EXTENSION_SELECTORS > 0)
+#ifdef SSH_LINUX_FWMARK_EXTENSION_SELECTOR
+ u32 fwmark = 0;
+#endif /* SSH_LINUX_FWMARK_EXTENSION_SELECTOR */
+#endif /* (SSH_INTERCEPTOR_NUM_EXTENSION_SELECTORS > 0) */
+ struct net_device *dev;
+
+ SSH_ASSERT(skbp->protocol == __constant_htons(ETH_P_IP));
+
+ if (route_selector & SSH_INTERCEPTOR_ROUTE_KEY_SRC)
+ saddr = iph->saddr;
+
+ /* Map 'ifnum_in' to a net_device. */
+ SSH_LINUX_ASSERT_VALID_IFNUM(ifnum_in);
+ dev = ssh_interceptor_ifnum_to_netdev(interceptor, ifnum_in);
+ if (dev == NULL)
+ return FALSE;
+
+ /* Clear the IP protocol, if selector does not define it. */
+ if ((route_selector & SSH_INTERCEPTOR_ROUTE_KEY_IPPROTO) == 0)
+ {
+ ipproto = iph->protocol;
+ iph->protocol = 0;
+ }
+
+ if (route_selector & SSH_INTERCEPTOR_ROUTE_KEY_IP4_TOS)
+ tos = RT_TOS(iph->tos);
+
+#if (SSH_INTERCEPTOR_NUM_EXTENSION_SELECTORS > 0)
+#ifdef SSH_LINUX_FWMARK_EXTENSION_SELECTOR
+ /* Clear the nfmark, if selector does not define it. */
+ if ((route_selector & SSH_INTERCEPTOR_ROUTE_KEY_EXTENSION) == 0)
+ {
+ fwmark = SSH_SKB_MARK(skbp);
+ SSH_SKB_MARK(skbp) = 0;
+ }
+#endif /* SSH_LINUX_FWMARK_EXTENSION_SELECTOR */
+#endif /* (SSH_INTERCEPTOR_NUM_EXTENSION_SELECTORS > 0) */
+
+ /* Call ip_route_input */
+ if (ip_route_input(skbp, iph->daddr, saddr, tos, dev) < 0)
+ {
+ SSH_DEBUG(SSH_D_FAIL,
+ ("ip_route_input failed. (0x%08x -> 0x%08x)",
+ iph->saddr, iph->daddr));
+
+ SSH_DEBUG(SSH_D_NICETOKNOW,
+ ("dst 0x%08x src 0x%08x iif %d[%s] proto %d tos 0x%02x "
+ "fwmark 0x%x",
+ iph->daddr, saddr, (dev ? dev->ifindex : -1),
+ (dev ? dev->name : "none"), iph->protocol, tos,
+ SSH_SKB_MARK(skbp)));
+
+ /* Release netdev reference */
+ ssh_interceptor_release_netdev(dev);
+
+ return FALSE;
+ }
+
+ /* Write original IP protocol back to skb */
+ if (ipproto)
+ iph->protocol = ipproto;
+
+#if (SSH_INTERCEPTOR_NUM_EXTENSION_SELECTORS > 0)
+#ifdef SSH_LINUX_FWMARK_EXTENSION_SELECTOR
+ /* Write original fwmark back to skb */
+ if (fwmark)
+ SSH_SKB_MARK(skbp) = fwmark;
+#endif /* SSH_LINUX_FWMARK_EXTENSION_SELECTOR */
+#endif /* (SSH_INTERCEPTOR_NUM_EXTENSION_SELECTORS > 0) */
+
+ /* Release netdev reference */
+ ssh_interceptor_release_netdev(dev);
+ }
+
+ else
+ {
+ struct rtable *rt;
+ struct flowi rt_key;
+
+ if ((route_selector & SSH_INTERCEPTOR_ROUTE_KEY_FLAG_LOCAL_SRC) == 0)
+ route_selector &= ~SSH_INTERCEPTOR_ROUTE_KEY_SRC;
+
+ memset(&rt_key, 0, sizeof(rt_key));
+
+ rt_key.fl4_dst = iph->daddr;
+ if (route_selector & SSH_INTERCEPTOR_ROUTE_KEY_SRC)
+ rt_key.fl4_src = iph->saddr;
+ if (route_selector & SSH_INTERCEPTOR_ROUTE_KEY_OUT_IFNUM)
+ rt_key.oif = (skbp->dev ? skbp->dev->ifindex : 0);
+ if (route_selector & SSH_INTERCEPTOR_ROUTE_KEY_IPPROTO)
+ rt_key.proto = iph->protocol;
+ if (route_selector & SSH_INTERCEPTOR_ROUTE_KEY_IP4_TOS)
+ rt_key.fl4_tos = RT_TOS(iph->tos);
+ rt_key.fl4_scope = RT_SCOPE_UNIVERSE;
+
+#if (SSH_INTERCEPTOR_NUM_EXTENSION_SELECTORS > 0)
+#ifdef SSH_LINUX_FWMARK_EXTENSION_SELECTOR
+ if (route_selector & SSH_INTERCEPTOR_ROUTE_KEY_EXTENSION)
+ {
+#ifdef LINUX_HAS_SKB_MARK
+ rt_key.mark = SSH_SKB_MARK(skbp);
+#else /* LINUX_HAS_SKB_MARK */
+#ifdef CONFIG_IP_ROUTE_FWMARK
+ rt_key.fl4_fwmark = SSH_SKB_MARK(skbp);
+#endif /* CONFIG_IP_ROUTE_FWMARK */
+#endif /* LINUX_HAS_SKB_MARK */
+ }
+#endif /* SSH_LINUX_FWMARK_EXTENSION_SELECTOR */
+#endif /* (SSH_INTERCEPTOR_NUM_EXTENSION_SELECTORS > 0) */
+
+ rval = interceptor_ip4_route_output(&rt, &rt_key);
+ if (rval < 0)
+ {
+ SSH_DEBUG(SSH_D_FAIL,
+ ("ip_route_output_key failed (0x%08x -> 0x%08x): %d",
+ iph->saddr, iph->daddr, rval));
+
+ SSH_DEBUG(SSH_D_NICETOKNOW,
+ ("dst 0x%08x src 0x%08x oif %d[%s] proto %d tos 0x%02x"
+ "fwmark 0x%x",
+ iph->daddr,
+ ((route_selector & SSH_INTERCEPTOR_ROUTE_KEY_SRC) ?
+ iph->saddr : 0),
+ ((route_selector & SSH_INTERCEPTOR_ROUTE_KEY_OUT_IFNUM) ?
+ rt_key.oif : -1),
+ ((route_selector & SSH_INTERCEPTOR_ROUTE_KEY_OUT_IFNUM) ?
+ (skbp->dev ? skbp->dev->name : "none") : "none"),
+ ((route_selector & SSH_INTERCEPTOR_ROUTE_KEY_IPPROTO) ?
+ iph->protocol : -1),
+ ((route_selector & SSH_INTERCEPTOR_ROUTE_KEY_IP4_TOS) ?
+ iph->tos : 0),
+ ((route_selector & SSH_INTERCEPTOR_ROUTE_KEY_EXTENSION) ?
+ SSH_SKB_MARK(skbp) : 0)));
+
+ return FALSE;
+ }
+
+ /* Make a new dst because we just rechecked the route. */
+ SSH_SKB_DST_SET(skbp, dst_clone(&SSH_RT_DST(rt)));
+
+ /* Release the routing table entry ; otherwise a memory leak occurs
+ in the route entry table. */
+ ip_rt_put(rt);
+ }
+
+ SSH_ASSERT(SSH_SKB_DST(skbp) != NULL);
+
+#ifdef SSH_IPSEC_IP_ONLY_INTERCEPTOR
+#ifdef LINUX_FRAGMENTATION_AFTER_NF_POST_ROUTING
+ if (route_selector & SSH_INTERCEPTOR_ROUTE_KEY_FLAG_TRANSFORM_APPLIED)
+ {
+ /* Check if need to create a child dst_entry with interface MTU. */
+ if (SSH_SKB_DST(skbp)->child == NULL)
+ {
+ if (interceptor_route_create_child_dst(SSH_SKB_DST(skbp), FALSE)
+ == NULL)
+ {
+ SSH_DEBUG(SSH_D_ERROR,
+ ("Could not create child dst_entry for dst %p",
+ SSH_SKB_DST(skbp)));
+ return FALSE;
+ }
+ }
+
+ /* Pop dst stack and use the child entry with interface MTU
+ for sending the packet. */
+#ifdef LINUX_DST_POP_IS_SKB_DST_POP
+ SSH_SKB_DST_SET(skbp, dst_clone(skb_dst_pop(skbp)));
+#else /* LINUX_DST_POP_IS_SKB_DST_POP */
+ SSH_SKB_DST_SET(skbp, dst_pop(SSH_SKB_DST(skbp)));
+#endif /*LINUX_DST_POP_IS_SKB_DST_POP */
+ }
+#endif /* LINUX_FRAGMENTATION_AFTER_NF_POST_ROUTING */
+#endif /* SSH_IPSEC_IP_ONLY_INTERCEPTOR */
+
+ return TRUE;
+}
+
+
+#ifdef SSH_LINUX_INTERCEPTOR_IPV6
+
+/* Route IPv6 packet 'skbp', using the route key selectors in
+ 'route_selector' and the interface number 'ifnum_in'. */
+Boolean
+ssh_interceptor_reroute_skb_ipv6(SshInterceptor interceptor,
+ struct sk_buff *skbp,
+ SshUInt16 route_selector,
+ SshUInt32 ifnum_in)
+{
+ /* we do not need a socket, only fake flow */
+ struct flowi rt_key;
+ struct dst_entry *dst;
+ struct ipv6hdr *iph6;
+
+ iph6 = (struct ipv6hdr *) SSH_SKB_GET_NETHDR(skbp);
+ if (iph6 == NULL)
+ {
+ SSH_DEBUG(SSH_D_ERROR, ("Could not access IPv6 header"));
+ return FALSE;
+ }
+
+ memset(&rt_key, 0, sizeof(rt_key));
+
+ rt_key.fl6_dst = iph6->daddr;
+
+ if (route_selector & SSH_INTERCEPTOR_ROUTE_KEY_SRC)
+ rt_key.fl6_src = iph6->saddr;
+
+ if (route_selector & SSH_INTERCEPTOR_ROUTE_KEY_OUT_IFNUM)
+ {
+ rt_key.oif = (skbp->dev ? skbp->dev->ifindex : 0);
+ SSH_LINUX_ASSERT_IFNUM(rt_key.oif);
+ }
+
+ dst = interceptor_ip6_route_output(&rt_key);
+ if (dst == NULL || dst->error != 0)
+ {
+ if (dst != NULL)
+ dst_release(dst);
+
+ SSH_DEBUG(SSH_D_FAIL,
+ ("ip6_route_output failed."));
+
+ SSH_DEBUG_HEXDUMP(SSH_D_NICETOKNOW,
+ ("dst "),
+ (unsigned char *) &iph6->daddr, sizeof(iph6->daddr));
+ SSH_DEBUG_HEXDUMP(SSH_D_NICETOKNOW,
+ ("src "),
+ (unsigned char *) &iph6->saddr, sizeof(iph6->saddr));
+ SSH_DEBUG(SSH_D_NICETOKNOW,
+ ("oif %d[%s]",
+ (skbp->dev ? skbp->dev->ifindex : -1),
+ (skbp->dev ? skbp->dev->name : "none")));
+ return FALSE;
+ }
+ if (SSH_SKB_DST(skbp))
+ dst_release(SSH_SKB_DST(skbp));
+
+#ifdef SSH_IPSEC_IP_ONLY_INTERCEPTOR
+#ifdef LINUX_FRAGMENTATION_AFTER_NF6_POST_ROUTING
+ if (route_selector & SSH_INTERCEPTOR_ROUTE_KEY_FLAG_TRANSFORM_APPLIED)
+ {
+ SSH_DEBUG(SSH_D_LOWOK,
+ ("Creating a new child entry for dst %p, child %p %lu",
+ dst, dst->child, skbp->_skb_refdst));
+
+ /* Check if need to create a child dst_entry with interface MTU. */
+ if (dst->child == NULL)
+ {
+ if (interceptor_route_create_child_dst(dst, TRUE) == NULL)
+ {
+ SSH_DEBUG(SSH_D_ERROR,
+ ("Could not create child dst_entry for dst %p",
+ dst));
+
+ dst_release(dst);
+ return FALSE;
+ }
+ }
+
+ SSH_SKB_DST_SET(skbp, dst_clone(dst->child));
+ dst_release(dst);
+ }
+ else
+#endif /* LINUX_FRAGMENTATION_AFTER_NF6_POST_ROUTING */
+#endif /* SSH_IPSEC_IP_ONLY_INTERCEPTOR */
+ {
+ /* No need to clone the dst as ip6_route_output has already taken
+ one for us. */
+ SSH_SKB_DST_SET(skbp, dst);
+ }
+
+ return TRUE;
+}
+#endif /* SSH_LINUX_INTERCEPTOR_IPV6 */
diff --git a/drivers/interceptor/linux_usermode.c b/drivers/interceptor/linux_usermode.c
new file mode 100644
index 0000000..4a6401d
--- /dev/null
+++ b/drivers/interceptor/linux_usermode.c
@@ -0,0 +1,384 @@
+/* Netfilter Driver for IPSec VPN Client
+ *
+ * Copyright(c) 2012 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.
+ */
+
+/*
+ * linux_usermode.c
+ *
+ */
+
+#include "linux_internal.h"
+#include "linux_packet_internal.h"
+
+#define SSH_DEBUG_MODULE "SshInterceptorPacketDstCache"
+
+extern SshInterceptor ssh_interceptor_context;
+
+Boolean
+ssh_interceptor_dst_entry_cache_init(SshInterceptor interceptor)
+{
+ SSH_DEBUG(SSH_D_MIDOK, ("Initialising dst entry cache"));
+
+ /* When the IPM is open, we cache dst entries with usermode engine. */
+ interceptor->dst_entry_cache_lock = ssh_kernel_mutex_alloc();
+ if (interceptor->dst_entry_cache_lock == NULL)
+ return FALSE;
+
+ interceptor->dst_entry_cache_timeout_registered = FALSE;
+ memset(interceptor->dst_entry_table, 0x0,
+ sizeof(SshDstEntry) * SSH_DST_ENTRY_TBL_SIZE);
+
+ interceptor->dst_entry_id = 1;
+ interceptor->dst_entry_cached_items = 0;
+
+ return TRUE;
+}
+
+/* How long the dst entry can live in the cache. */
+#define DST_ENTRY_MAX_CACHE_TIME 15
+static void
+ssh_interceptor_dst_entry_cache_timeout(unsigned long data)
+{
+ SshInterceptor interceptor = ssh_interceptor_context;
+ SshUInt32 slot;
+ SshDstEntry tmp, prev = NULL;
+ struct timeval tv;
+ unsigned long time_now;
+ unsigned long expiry;
+
+ ssh_kernel_mutex_lock(interceptor->dst_entry_cache_lock);
+
+ SSH_DEBUG(SSH_D_MIDOK,
+ ("Dst entry cache timeout %lu items in cache",
+ (unsigned long)interceptor->dst_entry_cached_items));
+ SSH_ASSERT(interceptor->dst_entry_cache_timeout_registered == TRUE);
+
+ if (interceptor->dst_entry_cached_items == 0)
+ {
+ interceptor->dst_entry_cache_timeout_registered = FALSE;
+ ssh_kernel_mutex_unlock(interceptor->dst_entry_cache_lock);
+ return;
+ }
+
+ tv.tv_sec = DST_ENTRY_MAX_CACHE_TIME;
+ tv.tv_usec = 0;
+ time_now = jiffies;
+ expiry = timeval_to_jiffies(&tv);
+
+ for (slot = 0; slot < SSH_DST_ENTRY_TBL_SIZE; slot++)
+ {
+ restart:
+ prev = NULL;
+ for (tmp = interceptor->dst_entry_table[slot];
+ tmp != NULL;
+ tmp = tmp->next)
+ {
+ /* Do we have a match? */
+ if ((tmp->allocation_time + expiry) < time_now ||
+ (time_now - tmp->allocation_time) > expiry)
+ {
+ /* Head of list. */
+ if (tmp == interceptor->dst_entry_table[slot])
+ {
+ SSH_DEBUG(SSH_D_MIDOK,
+ ("Dst entry cache timeout freeing head ID %lu",
+ (unsigned long)tmp->dst_entry_id));
+ interceptor->dst_entry_table[slot] = tmp->next;
+
+ interceptor->dst_entry_cached_items--;
+
+ dst_release(tmp->dst_entry);
+ ssh_free(tmp);
+
+ goto restart;
+ }
+
+ /* Any other place in the list. */
+ else
+ {
+ prev->next = tmp->next;
+
+ interceptor->dst_entry_cached_items--;
+
+ SSH_DEBUG(SSH_D_MIDOK,
+ ("Dst entry cache timeout freeing ID %lu",
+ (unsigned long)tmp->dst_entry_id));
+
+ dst_release(tmp->dst_entry);
+ ssh_free(tmp);
+
+ goto restart;
+ }
+ }
+
+ prev = tmp;
+ }
+ }
+
+ if (interceptor->dst_entry_cached_items > 0)
+ {
+ struct timeval tv;
+
+ tv.tv_sec = DST_ENTRY_MAX_CACHE_TIME;
+ tv.tv_usec = 0;
+
+ interceptor->dst_cache_timer.expires = jiffies + timeval_to_jiffies(&tv);
+ interceptor->dst_cache_timer.data = (unsigned long)interceptor;
+ interceptor->dst_cache_timer.function =
+ ssh_interceptor_dst_entry_cache_timeout;
+
+ mod_timer(&interceptor->dst_cache_timer,
+ interceptor->dst_cache_timer.expires);
+ }
+ else
+ {
+ interceptor->dst_entry_cache_timeout_registered = FALSE;
+ }
+
+ SSH_DEBUG(SSH_D_NICETOKNOW, ("Left %lu items in dst cache",
+ (unsigned long)
+ interceptor->dst_entry_cached_items));
+
+ ssh_kernel_mutex_unlock(interceptor->dst_entry_cache_lock);
+}
+
+void
+ssh_interceptor_dst_entry_cache_flush(SshInterceptor interceptor)
+{
+ SshUInt32 slot;
+ SshDstEntry tmp;
+
+ SSH_DEBUG(SSH_D_MIDOK, ("Dst entry cache flush, %lu items in cache",
+ (unsigned long)interceptor->dst_entry_cached_items));
+
+ ssh_kernel_mutex_lock(interceptor->dst_entry_cache_lock);
+ if (interceptor->dst_entry_cache_timeout_registered == TRUE)
+ {
+ ssh_kernel_mutex_unlock(interceptor->dst_entry_cache_lock);
+ del_timer_sync(&interceptor->dst_cache_timer);
+ ssh_kernel_mutex_lock(interceptor->dst_entry_cache_lock);
+ }
+
+ interceptor->dst_entry_cache_timeout_registered = FALSE;
+
+ /* Free all entries that are left in the table. */
+ for (slot = 0; slot < SSH_DST_ENTRY_TBL_SIZE; slot++)
+ {
+ tmp = interceptor->dst_entry_table[slot];
+ while (tmp != NULL)
+ {
+ SshDstEntry next = tmp->next;
+ interceptor->dst_entry_table[slot] = next;
+
+ interceptor->dst_entry_cached_items--;
+
+ SSH_DEBUG(SSH_D_NICETOKNOW, ("Releasing dst cache entry"));
+
+ dst_release(tmp->dst_entry);
+ ssh_free(tmp);
+
+ tmp = next;
+ }
+ }
+
+ SSH_ASSERT(interceptor->dst_entry_cached_items == 0);
+ ssh_kernel_mutex_unlock(interceptor->dst_entry_cache_lock);
+}
+
+void
+ssh_interceptor_dst_entry_cache_uninit(SshInterceptor interceptor)
+{
+ /* Something failed during initialization. */
+ if (interceptor->dst_entry_cache_lock == NULL)
+ return;
+
+ SSH_DEBUG(SSH_D_MIDOK, ("Dst entry cache uninit, %lu items in cache",
+ (unsigned long)interceptor->dst_entry_cached_items));
+
+ ssh_interceptor_dst_entry_cache_flush(interceptor);
+ ssh_kernel_mutex_uninit(interceptor->dst_entry_cache_lock);
+ ssh_kernel_mutex_free(interceptor->dst_entry_cache_lock);
+}
+
+/* Cache a dst entry for later purposes. This is required by the
+ pass unmodified to work. If we lose the dst entry, we basically
+ cannot return the packet as unmodified to the linux. Return 0
+ if the caching fails. If it succeeds, return a valid cache ID. */
+SshUInt32
+ssh_interceptor_packet_cache_dst_entry(SshInterceptor interceptor,
+ SshInterceptorPacket pp)
+{
+ SshInterceptorInternalPacket ipp = (SshInterceptorInternalPacket)pp;
+ SshDstEntry cache_dst;
+ SshDstEntry tmp;
+ SshUInt32 slot;
+
+ SSH_DEBUG(SSH_D_MIDOK,
+ ("Dst entry cache, caching dst for pp 0x%p, %lu items in cache",
+ pp, (unsigned long)interceptor->dst_entry_cached_items));
+
+ if (ipp->skb == NULL || SSH_SKB_DST(ipp->skb) == NULL)
+ return 0;
+
+ cache_dst = ssh_calloc(1, sizeof(SshDstEntryStruct));
+ if (cache_dst == NULL)
+ return 0;
+
+ cache_dst->allocation_time = jiffies;
+ cache_dst->next = NULL;
+
+ cache_dst->dst_entry = SSH_SKB_DST(ipp->skb);
+ dst_hold(cache_dst->dst_entry);
+
+ ssh_kernel_mutex_lock(interceptor->dst_entry_cache_lock);
+
+ cache_dst->dst_entry_id = interceptor->dst_entry_id++;
+ slot = cache_dst->dst_entry_id % SSH_DST_ENTRY_TBL_SIZE;
+
+ interceptor->dst_entry_cached_items++;
+
+ SSH_ASSERT(slot < SSH_DST_ENTRY_TBL_SIZE);
+
+ /* Head of list. */
+ if (interceptor->dst_entry_table[slot] == NULL)
+ {
+ interceptor->dst_entry_table[slot] = cache_dst;
+ }
+ else
+ {
+ /* We do not care about potential collisions. These are highly unlikely
+ to happen and in the end */
+ for (tmp = interceptor->dst_entry_table[slot];
+ tmp->next != NULL;
+ tmp = tmp->next)
+ SSH_ASSERT(cache_dst->dst_entry_id != tmp->dst_entry_id);
+
+ tmp->next = cache_dst;
+ }
+
+ /* Handle special case, the id is overflowing. 0 is used for special
+ purposes, i.e. for 'real' engine created packets. */
+ if (interceptor->dst_entry_id == 0)
+ interceptor->dst_entry_id = 1;
+
+ if (interceptor->dst_entry_cache_timeout_registered == FALSE)
+ {
+ struct timeval tv;
+
+ SSH_ASSERT(interceptor->dst_entry_cached_items > 0);
+
+ tv.tv_sec = DST_ENTRY_MAX_CACHE_TIME;
+ tv.tv_usec = 0;
+
+ init_timer(&interceptor->dst_cache_timer);
+ interceptor->dst_cache_timer.expires = jiffies + timeval_to_jiffies(&tv);
+ interceptor->dst_cache_timer.data = (unsigned long)interceptor;
+ interceptor->dst_cache_timer.function =
+ ssh_interceptor_dst_entry_cache_timeout;
+ add_timer(&interceptor->dst_cache_timer);
+
+ interceptor->dst_entry_cache_timeout_registered = TRUE;
+ }
+
+ SSH_DEBUG(SSH_D_NICETOKNOW, ("Cache ID %lu, left %lu items in dst cache",
+ (unsigned long)cache_dst->dst_entry_id,
+ (unsigned long)
+ interceptor->dst_entry_cached_items));
+
+ ssh_kernel_mutex_unlock(interceptor->dst_entry_cache_lock);
+
+ return cache_dst->dst_entry_id;
+}
+
+void
+ssh_interceptor_packet_return_dst_entry(SshInterceptor interceptor,
+ SshUInt32 dst_entry_id,
+ SshInterceptorPacket pp,
+ Boolean remove_only)
+{
+ SshInterceptorInternalPacket ipp = (SshInterceptorInternalPacket)pp;
+ SshUInt32 slot = dst_entry_id % SSH_DST_ENTRY_TBL_SIZE;
+ SshDstEntry tmp, prev = NULL;
+
+ SSH_DEBUG(SSH_D_MIDOK,
+ ("Returning dst entry ID %lu, pp 0x%p, %lu items in cache, "
+ "update %s",
+ (unsigned long)dst_entry_id, pp,
+ (unsigned long)interceptor->dst_entry_cached_items,
+ remove_only == TRUE ? "no" : "yes"));
+
+ /* Special case, 'real' engine created packets. */
+ if (dst_entry_id == 0)
+ return;
+
+ SSH_ASSERT(slot < SSH_DST_ENTRY_TBL_SIZE);
+
+ ssh_kernel_mutex_lock(interceptor->dst_entry_cache_lock);
+ for (tmp = interceptor->dst_entry_table[slot]; tmp != NULL; tmp = tmp->next)
+ {
+ /* Do we have a match? */
+ if (tmp->dst_entry_id == dst_entry_id)
+ {
+ /* Head of list. */
+ if (tmp == interceptor->dst_entry_table[slot])
+ {
+ interceptor->dst_entry_table[slot] = tmp->next;
+
+ interceptor->dst_entry_cached_items--;
+ ssh_kernel_mutex_unlock(interceptor->dst_entry_cache_lock);
+
+ if (remove_only == FALSE && pp != NULL)
+ SSH_SKB_DST_SET(ipp->skb, tmp->dst_entry);
+ else
+ dst_release(tmp->dst_entry);
+
+ ssh_free(tmp);
+
+ SSH_DEBUG(SSH_D_NICETOKNOW,
+ ("Removed cache ID %lu, left %lu items in dst cache",
+ (unsigned long)dst_entry_id,
+ (unsigned long)interceptor->dst_entry_cached_items));
+
+ return;
+ }
+
+ /* Any other place in the list. */
+ else
+ {
+ prev->next = tmp->next;
+
+ interceptor->dst_entry_cached_items--;
+ ssh_kernel_mutex_unlock(interceptor->dst_entry_cache_lock);
+
+ if (remove_only == FALSE)
+ SSH_SKB_DST_SET(ipp->skb, tmp->dst_entry);
+ else
+ dst_release(tmp->dst_entry);
+
+ ssh_free(tmp);
+
+ SSH_DEBUG(SSH_D_NICETOKNOW,
+ ("Removed cache ID %lu, left %lu items in dst cache",
+ (unsigned long)dst_entry_id,
+ (unsigned long)interceptor->dst_entry_cached_items));
+
+ return;
+ }
+ }
+
+ prev = tmp;
+ }
+
+ SSH_DEBUG(SSH_D_NICETOKNOW,
+ ("Cache ID %lu was not found, left %lu items in dst cache",
+ (unsigned long)dst_entry_id,
+ (unsigned long)interceptor->dst_entry_cached_items));
+
+ ssh_kernel_mutex_unlock(interceptor->dst_entry_cache_lock);
+}
diff --git a/drivers/interceptor/linux_versions.h b/drivers/interceptor/linux_versions.h
new file mode 100644
index 0000000..426b5b1
--- /dev/null
+++ b/drivers/interceptor/linux_versions.h
@@ -0,0 +1,190 @@
+/* Netfilter Driver for IPSec VPN Client
+ *
+ * Copyright(c) 2012 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.
+ */
+
+/*
+ * linux_versions.h
+ *
+ * Linux interceptor kernel version specific defines. When adding support
+ * for new kernel versions, add the kernel version specific block to the
+ * bottom of the file and undefine any removed feature defines inherited
+ * from earlier kernel version blocks.
+ *
+ */
+
+#ifndef LINUX_VERSION_H
+#define LINUX_VERSION_H
+
+#include <linux/version.h>
+
+#ifndef KERNEL_VERSION
+#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))
+#endif /* KERNEL_VERSION */
+
+/* 3.1.10 is the highest version currently supported */
+#if LINUX_VERSION_CODE > KERNEL_VERSION(3,1,10)
+#error "Kernel versions after 3.1.10 are not supported"
+#endif /* LINUX_VERSION_CODE > KERNEL_VERSION(3,1,10) */
+
+/* 2.4 is not supported */
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
+#error "Kernel versions pre 2.6.0 are not supported"
+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) */
+
+/* 2.6 series specific things */
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
+#define LINUX_HAS_SKB_SECURITY 1
+#define LINUX_HAS_SKB_STAMP 1
+#define LINUX_HAS_SKB_NFCACHE 1
+#define LINUX_HAS_SKB_NFDEBUG 1
+#define LINUX_SKB_LINEARIZE_NEEDS_FLAGS 1
+#define LINUX_INODE_OPERATION_PERMISSION_HAS_NAMEIDATA 1
+#define LINUX_HAS_PROC_DIR_ENTRY_OWNER 1
+#define LINUX_HAS_HH_CACHE 1
+#endif /* >= 2.6.0 */
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,4)
+#define LINUX_HAS_SKB_MAC_LEN 1
+#endif /* >= 2.6.4 */
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,9)
+#define LINUX_HAS_ETH_HDR 1
+#endif /* >= 2.6.9 */
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,12)
+#define LINUX_HAS_DST_MTU 1
+#define LINUX_HAS_DEV_GET_FLAGS 1
+#endif /* >= 2.6.12 */
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,13)
+#undef LINUX_HAS_SKB_SECURITY
+#undef LINUX_HAS_SKB_STAMP
+#undef LINUX_HAS_SKB_NFCACHE
+#undef LINUX_HAS_SKB_NFDEBUG
+#endif /* >= 2.6.13 */
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15)
+#define LINUX_HAS_NETIF_F_UFO 1
+#endif /* >= 2.6.15 */
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16)
+#define LINUX_HAS_IP6CB_NHOFF 1
+#define LINUX_FRAGMENTATION_AFTER_NF_POST_ROUTING 1
+#endif /* >= 2.6.16 */
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,18)
+#undef LINUX_SKB_LINEARIZE_NEEDS_FLAGS
+#define LINUX_HAS_NETIF_F_GSO 1
+#define LINUX_HAS_NETIF_F_TSO6 1
+#define LINUX_HAS_NETIF_F_TSO_ECN 1
+#define LINUX_HAS_NETIF_F_GSO_ROBUST 1
+#endif /* >= 2.6.18 */
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)
+#define LINUX_HAS_NEW_CHECKSUM_FLAGS 1
+#define LINUX_NEED_IF_ADDR_H 1
+#endif /* >= 2.6.19 */
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
+#define LINUX_HAS_SKB_MARK 1
+#define LINUX_HAS_SKB_CSUM_OFFSET 1
+#endif /* >= 2.6.20 */
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22)
+#define LINUX_HAS_NETDEVICE_ACCESSORS 1
+#define LINUX_HAS_SKB_DATA_ACCESSORS 1
+#define LINUX_HAS_SKB_CSUM_START 1
+#endif /* >= 2.6.22 */
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
+#define LINUX_NET_DEVICE_HAS_ARGUMENT 1
+#define LINUX_NF_HOOK_SKB_IS_POINTER 1
+#endif /* >= 2.6.24 */
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,25)
+#define LINUX_NF_INET_HOOKNUMS 1
+#define LINUX_IP_ROUTE_OUTPUT_KEY_HAS_NET_ARGUMENT 1
+#endif /* >= 2.6.25 */
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)
+#define LINUX_IP6_ROUTE_OUTPUT_KEY_HAS_NET_ARGUMENT 1
+#endif /* >= 2.6.26 */
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
+#undef LINUX_INODE_OPERATION_PERMISSION_HAS_NAMEIDATA
+#endif /* >= 2.6.27 */
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,28)
+#define LINUX_HAS_NFPROTO_ARP 1
+#endif /* >= 2.6.28 */
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29)
+#define LINUX_HAS_TASK_CRED_STRUCT 1
+#endif /* >= 2.6.29 */
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,30)
+#undef LINUX_HAS_PROC_DIR_ENTRY_OWNER
+#endif /* >= 2.6.30 */
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,31)
+#define LINUX_HAS_SKB_DST_FUNCTIONS 1
+#endif /* >= 2.6.31 */
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32)
+#endif /* >= 2.6.32 */
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,33)
+#endif /* >= 2.6.33 */
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,34)
+#endif /* >= 2.6.34 */
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,35)
+#define LINUX_HAS_INET6_IFADDR_LIST_HEAD 1
+#define LINUX_DST_POP_IS_SKB_DST_POP 1
+#define LINUX_IP_ONLY_PASSTHROUGH_NDISC 1
+#define LINUX_FRAGMENTATION_AFTER_NF6_POST_ROUTING 1
+#endif /* >= 2.6.35 */
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36)
+#define LINUX_RT_DST_IS_NOT_IN_UNION 1
+#endif /* >= 2.6.36 */
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37)
+#endif /* >= 2.6.37 */
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)
+#define LINUX_INODE_OPERATION_PERMISSION_HAS_UINT 1
+#define LINUX_HAS_DST_COPY_METRICS 1
+#define LINUX_SSH_RTABLE_FIRST_ELEMENT_NEEDED 1
+#endif /* >= 2.6.38 */
+
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,39)
+#define LINUX_USE_NF_FOR_ROUTE_OUTPUT 1
+#define LINUX_FLOWI_NO_FL4_ACCESSORS 1
+#define LINUX_FLOWI_NO_FL6_ACCESSORS 1
+#define LINUX_DST_ALLOC_HAS_REFCOUNT 1
+#endif /* >= 2.6.38 */
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,0)
+#define LINUX_DST_ALLOC_HAS_MANY_ARGS 1
+#endif /* >= 3.0.0 */
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,29)
+#define LINUX_HAS_DST_NEIGHBOUR_FUNCTIONS 1
+#endif /* >= 3.1.0 */
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,1,0)
+#undef LINUX_INODE_OPERATION_PERMISSION_HAS_UINT
+#define LINUX_HAS_NET_DEVICE_OPS 1
+#undef LINUX_HAS_HH_CACHE
+#endif /* >= 3.1.0 */
+
+#endif /* LINUX_VERSION_H */
diff --git a/drivers/interceptor/linux_virtual_adapter.c b/drivers/interceptor/linux_virtual_adapter.c
new file mode 100644
index 0000000..8196d0a
--- /dev/null
+++ b/drivers/interceptor/linux_virtual_adapter.c
@@ -0,0 +1,1073 @@
+/* Netfilter Driver for IPSec VPN Client
+ *
+ * Copyright(c) 2012 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.
+ */
+
+/*
+ * linux_virtual_adapter.c
+ *
+ */
+
+#include "linux_internal.h"
+
+#include "virtual_adapter.h"
+#include "linux_virtual_adapter_internal.h"
+#include "sshencode.h"
+#include "sshinetencode.h"
+
+extern SshInterceptor ssh_interceptor_context;
+
+/* ************************ Types and definitions ***************************/
+
+#define SSH_DEBUG_MODULE "SshInterceptorVirtualAdapter"
+
+static int num_virtual_adapters = 1; /* Default to 1 virtual adapter. */
+MODULE_PARM_DESC(num_virtual_adapters, "Number of virtual adapters to create");
+module_param(num_virtual_adapters, int, 0444);
+
+
+#ifdef LINUX_HAS_NET_DEVICE_PRIV
+#define SSH_LINUX_NET_DEVICE_PRIV(netdev) ((netdev)->priv)
+#else
+#define SSH_LINUX_NET_DEVICE_PRIV(netdev) (*((void **) netdev_priv(netdev)))
+#endif
+
+
+/* *********************** Internal Utility Functions ***********************/
+
+static inline SshVirtualAdapter
+ssh_virtual_adapter_ifnum_to_adapter(SshInterceptor interceptor,
+ SshInterceptorIfnum adapter_ifnum)
+{
+ SshVirtualAdapter adapter = NULL;
+ SshUInt32 i;
+
+ ssh_kernel_mutex_assert_is_locked(interceptor->interceptor_lock);
+
+ for (i = 0; i < SSH_LINUX_MAX_VIRTUAL_ADAPTERS; i++)
+ {
+ adapter = interceptor->virtual_adapters[i];
+ if (adapter && adapter->dev->ifindex == adapter_ifnum)
+ return adapter;
+ }
+ return NULL;
+}
+
+
+/* ******************* Public Virtual Adapter Operations *********************/
+
+void ssh_virtual_adapter_get_status(SshInterceptor interceptor,
+ SshInterceptorIfnum adapter_ifnum,
+ SshVirtualAdapterStatusCB status_cb,
+ void *context)
+{
+ SshVirtualAdapter adapter;
+ unsigned char adapter_name[SSH_INTERCEPTOR_IFNAME_SIZE];
+ SshVirtualAdapterState adapter_state;
+ unsigned int dev_flags;
+ void *adapter_context;
+ SshUInt32 i;
+
+ if (adapter_ifnum == SSH_INTERCEPTOR_INVALID_IFNUM)
+ {
+ i = 0;
+ restart:
+ local_bh_disable();
+ ssh_kernel_mutex_lock(interceptor->interceptor_lock);
+ for (; i < SSH_LINUX_MAX_VIRTUAL_ADAPTERS; i++)
+ {
+ adapter = interceptor->virtual_adapters[i];
+ if (adapter == NULL)
+ continue;
+
+ SSH_ASSERT(adapter->dev != NULL);
+ adapter_ifnum = (SshInterceptorIfnum) adapter->dev->ifindex;
+ snprintf(adapter_name, SSH_INTERCEPTOR_IFNAME_SIZE,
+ "%s", adapter->dev->name);
+ dev_flags = SSH_LINUX_DEV_GET_FLAGS(adapter->dev);
+ adapter_state = SSH_VIRTUAL_ADAPTER_STATE_DOWN;
+ if (dev_flags & IFF_UP)
+ adapter_state = SSH_VIRTUAL_ADAPTER_STATE_UP;
+ adapter_context = adapter->adapter_context;
+ ssh_kernel_mutex_unlock(interceptor->interceptor_lock);
+ local_bh_enable();
+ (*status_cb)(SSH_VIRTUAL_ADAPTER_ERROR_OK_MORE,
+ adapter_ifnum, adapter_name, adapter_state,
+ adapter_context, context);
+ i++;
+ goto restart;
+ }
+ ssh_kernel_mutex_unlock(interceptor->interceptor_lock);
+ local_bh_enable();
+ (*status_cb)(SSH_VIRTUAL_ADAPTER_ERROR_NONEXISTENT,
+ SSH_INTERCEPTOR_INVALID_IFNUM, NULL,
+ SSH_VIRTUAL_ADAPTER_STATE_UNDEFINED,
+ NULL, context);
+ return;
+ }
+ else
+ {
+ local_bh_disable();
+ ssh_kernel_mutex_lock(interceptor->interceptor_lock);
+ adapter = ssh_virtual_adapter_ifnum_to_adapter(interceptor,
+ adapter_ifnum);
+ if (adapter == NULL)
+ {
+ ssh_kernel_mutex_unlock(interceptor->interceptor_lock);
+ local_bh_enable();
+ (*status_cb)(SSH_VIRTUAL_ADAPTER_ERROR_NONEXISTENT,
+ adapter_ifnum, NULL,
+ SSH_VIRTUAL_ADAPTER_STATE_UNDEFINED,
+ NULL, context);
+ return;
+ }
+
+ SSH_ASSERT(adapter->dev != NULL);
+ snprintf(adapter_name, SSH_INTERCEPTOR_IFNAME_SIZE,
+ "%s", adapter->dev->name);
+ dev_flags = SSH_LINUX_DEV_GET_FLAGS(adapter->dev);
+ adapter_state = SSH_VIRTUAL_ADAPTER_STATE_DOWN;
+ if (dev_flags & IFF_UP)
+ adapter_state = SSH_VIRTUAL_ADAPTER_STATE_UP;
+ adapter_context = adapter->adapter_context;
+ ssh_kernel_mutex_unlock(interceptor->interceptor_lock);
+ local_bh_enable();
+ (*status_cb)(SSH_VIRTUAL_ADAPTER_ERROR_OK,
+ adapter_ifnum, adapter_name, adapter_state,
+ adapter_context, context);
+ return;
+ }
+}
+
+void ssh_virtual_adapter_attach(SshInterceptor interceptor,
+ SshInterceptorIfnum adapter_ifnum,
+ SshVirtualAdapterPacketCB packet_cb,
+ SshVirtualAdapterDetachCB detach_cb,
+ void *adapter_context,
+ SshVirtualAdapterStatusCB callback,
+ void *context)
+{
+ SshVirtualAdapter adapter;
+ unsigned char adapter_name[SSH_INTERCEPTOR_IFNAME_SIZE];
+ SshVirtualAdapterState adapter_state = SSH_VIRTUAL_ADAPTER_STATE_DOWN;
+ unsigned int dev_flags;
+ SshVirtualAdapterDetachCB old_detach_cb;
+ void *old_adapter_context;
+
+ restart:
+ local_bh_disable();
+ ssh_kernel_mutex_lock(interceptor->interceptor_lock);
+ adapter = ssh_virtual_adapter_ifnum_to_adapter(interceptor, adapter_ifnum);
+ if (adapter == NULL)
+ {
+ ssh_kernel_mutex_unlock(interceptor->interceptor_lock);
+ local_bh_enable();
+ SSH_DEBUG(SSH_D_ERROR, ("Attach failed for virtual adapter %d",
+ (int) adapter_ifnum));
+ if (callback)
+ (*callback)(SSH_VIRTUAL_ADAPTER_ERROR_NONEXISTENT,
+ adapter_ifnum, NULL, SSH_VIRTUAL_ADAPTER_STATE_UNDEFINED,
+ NULL, context);
+ return;
+ }
+
+ /* Destroy old adapter_context. */
+ if (adapter->detach_cb != NULL)
+ {
+ old_detach_cb = adapter->detach_cb;
+ old_adapter_context = adapter->adapter_context;
+ adapter->detach_cb = NULL;
+ adapter->adapter_context = NULL;
+ ssh_kernel_mutex_unlock(interceptor->interceptor_lock);
+ local_bh_enable();
+ (*old_detach_cb)(old_adapter_context);
+ goto restart;
+ }
+
+ /* Fill in new adapter_context and callbacks. */
+ adapter->adapter_context = adapter_context;
+ adapter->packet_cb = packet_cb;
+ adapter->detach_cb = detach_cb;
+ adapter->attached = 1;
+
+ /* Gather info for callback. */
+ if (callback)
+ {
+ snprintf(adapter_name, SSH_INTERCEPTOR_IFNAME_SIZE,
+ "%s", adapter->dev->name);
+ dev_flags = SSH_LINUX_DEV_GET_FLAGS(adapter->dev);
+ if (dev_flags & IFF_UP)
+ adapter_state = SSH_VIRTUAL_ADAPTER_STATE_UP;
+ }
+
+ ssh_kernel_mutex_unlock(interceptor->interceptor_lock);
+ local_bh_enable();
+
+ if (callback)
+ (*callback)(SSH_VIRTUAL_ADAPTER_ERROR_OK,
+ adapter_ifnum, adapter_name, adapter_state,
+ adapter_context, context);
+}
+
+/* Clear virtual adapter callbacks, context, and configured IPv6 addresses. */
+static void ssh_virtual_adapter_clear(SshVirtualAdapter adapter)
+{
+ /* Clear adapter_context and callbacks. */
+ adapter->detach_cb = NULL;
+ adapter->adapter_context = NULL;
+ adapter->packet_cb = NULL;
+}
+
+void ssh_virtual_adapter_detach(SshInterceptor interceptor,
+ SshInterceptorIfnum adapter_ifnum,
+ SshVirtualAdapterStatusCB callback,
+ void *context)
+{
+ SshVirtualAdapter adapter;
+ unsigned char adapter_name[SSH_INTERCEPTOR_IFNAME_SIZE];
+ SshVirtualAdapterDetachCB detach_cb = NULL;
+ void *adapter_context = NULL;
+
+ local_bh_disable();
+ ssh_kernel_mutex_lock(interceptor->interceptor_lock);
+ adapter = ssh_virtual_adapter_ifnum_to_adapter(interceptor, adapter_ifnum);
+ if (adapter == NULL)
+ {
+ ssh_kernel_mutex_unlock(interceptor->interceptor_lock);
+ local_bh_enable();
+ if (callback)
+ (*callback)(SSH_VIRTUAL_ADAPTER_ERROR_NONEXISTENT,
+ adapter_ifnum, NULL, SSH_VIRTUAL_ADAPTER_STATE_UNDEFINED,
+ NULL, context);
+ return;
+ }
+
+ if (adapter->detach_cb)
+ {
+ detach_cb = adapter->detach_cb;
+ adapter_context = adapter->adapter_context;
+ }
+
+ ssh_virtual_adapter_clear(adapter);
+ adapter->attached = 0;
+
+ /* Gather info for callback. */
+ if (callback)
+ {
+ snprintf(adapter_name, SSH_INTERCEPTOR_IFNAME_SIZE,
+ "%s", adapter->dev->name);
+ }
+
+ ssh_kernel_mutex_unlock(interceptor->interceptor_lock);
+ local_bh_enable();
+
+ /* Destroy adapter_context. */
+ if (detach_cb)
+ (*detach_cb)(adapter_context);
+
+ if (callback)
+ (*callback)(SSH_VIRTUAL_ADAPTER_ERROR_OK,
+ adapter_ifnum, adapter_name,
+ SSH_VIRTUAL_ADAPTER_STATE_UNDEFINED,
+ NULL, context);
+}
+
+void ssh_virtual_adapter_detach_all(SshInterceptor interceptor)
+{
+ SshVirtualAdapter adapter;
+ SshUInt32 i = 0;
+ SshVirtualAdapterDetachCB detach_cb;
+ void *adapter_context;
+
+ restart:
+ local_bh_disable();
+ ssh_kernel_mutex_lock(interceptor->interceptor_lock);
+ for (; i < SSH_LINUX_MAX_VIRTUAL_ADAPTERS; i++)
+ {
+ adapter = interceptor->virtual_adapters[i];
+ if (adapter == NULL)
+ continue;
+
+ detach_cb = NULL;
+ adapter_context = NULL;
+ if (adapter->detach_cb != NULL)
+ {
+ detach_cb = adapter->detach_cb;
+ adapter_context = adapter->adapter_context;
+ }
+
+ ssh_virtual_adapter_clear(adapter);
+ adapter->attached = 0;
+
+ if (detach_cb != NULL)
+ {
+ ssh_kernel_mutex_unlock(interceptor->interceptor_lock);
+ local_bh_enable();
+
+ /* Destroy adapter_context. */
+ (*detach_cb)(adapter_context);
+
+ goto restart;
+ }
+ }
+ ssh_kernel_mutex_unlock(interceptor->interceptor_lock);
+ local_bh_enable();
+}
+
+/* ****************************** Platform stuff *****************************/
+
+/* Netdevice low level statistics callback function. */
+static struct net_device_stats *
+ssh_virtual_adapter_get_stats(struct net_device *dev)
+{
+ SshVirtualAdapter adapter =
+ (SshVirtualAdapter) SSH_LINUX_NET_DEVICE_PRIV(dev);
+
+ if (adapter)
+ return &adapter->low_level_stats;
+
+ return NULL;
+}
+
+/* Netdevice low level transmit callback function. */
+static int
+ssh_virtual_adapter_xmit(struct sk_buff *skbp,
+ struct net_device *dev)
+{
+ struct net_device_stats *stats;
+ SshInterceptorInternalPacket ipp;
+ SshInterceptor interceptor;
+ SshVirtualAdapter adapter;
+ SshInterceptorIfnum ifnum_in;
+ SshVirtualAdapterPacketCB packet_cb;
+ void *adapter_context;
+
+ SSH_ASSERT(skbp != NULL && dev != NULL);
+
+ interceptor = ssh_interceptor_context;
+
+ ssh_kernel_mutex_lock(interceptor->interceptor_lock);
+ adapter = (SshVirtualAdapter) SSH_LINUX_NET_DEVICE_PRIV(dev);
+ if (adapter == NULL)
+ {
+ /* Virtual adapter is not attached. */
+ ssh_kernel_mutex_unlock(interceptor->interceptor_lock);
+ SSH_DEBUG(SSH_D_NICETOKNOW,
+ ("Device %d [%s] is not attached to a SshVirtualAdapter",
+ dev->ifindex, dev->name));
+ discard:
+ /* Silently discard the packet. */
+ dev_kfree_skb_any(skbp);
+ return NET_XMIT_SUCCESS;
+ }
+
+ /* Update statistics */
+ stats = ssh_virtual_adapter_get_stats(dev);
+ SSH_ASSERT(stats != NULL);
+ stats->tx_packets++;
+
+ if (!adapter->initialized || !adapter->packet_cb)
+ {
+ /* This is not very uncommon. Packets end up here if the virtual
+ adapter is set up when policymanager is not running. We discard
+ the packets silently, as otherwise the stack will attempt to
+ transmit IPv6 IGMP messages indefinitely. */
+ ssh_kernel_mutex_unlock(interceptor->interceptor_lock);
+ SSH_DEBUG(SSH_D_LOWOK,
+ ("Virtual adapter %d [%s] not initialized / no cb.",
+ adapter->dev->ifindex, adapter->dev->name));
+ goto discard;
+ }
+
+ ifnum_in = (SshInterceptorIfnum) dev->ifindex;
+ SSH_LINUX_ASSERT_VALID_IFNUM(ifnum_in);
+
+ /* Pass the packet to the packet callback. */
+ ipp = ssh_interceptor_packet_alloc_header(interceptor,
+ SSH_PACKET_FROMPROTOCOL,
+ SSH_PROTOCOL_ETHERNET,
+ ifnum_in,
+ SSH_INTERCEPTOR_INVALID_IFNUM,
+ skbp,
+ FALSE, FALSE, TRUE);
+ if (ipp == NULL)
+ {
+ SSH_DEBUG(SSH_D_NICETOKNOW,
+ ("Could not allocate packet header, virtual adapter %d [%s]",
+ adapter->dev->ifindex, adapter->dev->name));
+ stats->tx_errors++;
+ ssh_kernel_mutex_unlock(interceptor->interceptor_lock);
+ return NET_XMIT_DROP;
+ }
+
+ stats->tx_bytes += ipp->skb->len;
+
+ packet_cb = adapter->packet_cb;
+ adapter_context = adapter->adapter_context;
+
+ ssh_kernel_mutex_unlock(interceptor->interceptor_lock);
+
+ SSH_DEBUG(SSH_D_NICETOKNOW,
+ ("Passing skb %p from virtual adapter %d [%s] to engine",
+ ipp->skb, (int)ifnum_in, dev->name));
+
+ /* Call the callback. This will eventually free `pp'. */
+ (*packet_cb)(interceptor, (SshInterceptorPacket) ipp, adapter_context);
+
+ return NET_XMIT_SUCCESS;
+}
+
+#ifdef HAVE_NET_DEVICE_OPS
+static const struct net_device_ops ssh_virtual_adapter_ops = {
+ .ndo_start_xmit = ssh_virtual_adapter_xmit,
+ .ndo_get_stats = ssh_virtual_adapter_get_stats,
+};
+#endif
+
+/* **************** Netdevice registration / unregistration ******************/
+
+static void
+ssh_virtual_adapter_low_level_setup(struct net_device *dev)
+{
+ /* Empty at the moment, but some netdevice specific settings could be done
+ here. */
+}
+
+static void
+ssh_virtual_adapter_destructor(struct net_device *dev)
+{
+ /* Free netdevice object. */
+ free_netdev(dev);
+}
+
+/* Attach virtual adapter to system. Returns FALSE on error, TRUE otherwise. */
+static Boolean
+ssh_virtual_adapter_attach_low_level(SshVirtualAdapter adapter,
+ unsigned char *adapter_name,
+ unsigned char *adapter_enaddr)
+{
+ int i, result;
+
+ /*
+ After priv member has disappeared from struct net_device, store
+ the "priv" pointer to private data area following the structure.
+ */
+#ifdef LINUX_HAS_NET_DEVICE_PRIV
+ const unsigned int private_data_size = 0;
+#else
+ const unsigned int private_data_size = sizeof(void *);
+#endif
+
+ SSH_ASSERT(adapter->dev == NULL);
+ SSH_ASSERT(adapter_name != NULL);
+ SSH_ASSERT(adapter_enaddr != NULL);
+
+
+ /* Allocate net_device. */
+ adapter->dev = alloc_netdev(private_data_size, adapter_name,
+ ssh_virtual_adapter_low_level_setup);
+ if (adapter->dev == NULL)
+ {
+ SSH_DEBUG(SSH_D_ERROR, ("alloc_netdev failed"));
+ return FALSE;
+ }
+
+ /* Copy ethernet address. */
+ for (i = 0; i < ETH_ALEN; i++)
+ adapter->dev->dev_addr[i] = adapter_enaddr[i];
+
+ /* Initialize the device structure. */
+ /* Set device private data to point to virtual adapter structure. */
+ SSH_LINUX_NET_DEVICE_PRIV(adapter->dev) = (void *) adapter;
+
+#ifdef HAVE_NET_DEVICE_OPS
+ adapter->dev->netdev_ops = &ssh_virtual_adapter_ops;
+#else
+ adapter->dev->hard_start_xmit = ssh_virtual_adapter_xmit;
+ adapter->dev->get_stats = ssh_virtual_adapter_get_stats;
+#endif
+
+ memset(&adapter->low_level_stats, 0, sizeof(struct net_device_stats));
+ adapter->dev->tx_queue_len = 0; /* no transmit queue */
+ adapter->dev->destructor = ssh_virtual_adapter_destructor;
+
+ /* Fill in the fields of the device structure with ethernet-generic
+ values. */
+ ether_setup(adapter->dev);
+
+ adapter->dev->flags |= IFF_POINTOPOINT;
+
+ /* Set default MTU. */
+ adapter->dev->mtu -= 100;
+
+ /* Register the network device. This call assigns a valid ifindex to
+ virtual adapter and it triggers an interface event. */
+ result = register_netdev(adapter->dev);
+
+ if (result != 0)
+ {
+ /* register_netdev() failed. Free net_device. */
+ SSH_LINUX_NET_DEVICE_PRIV(adapter->dev) = NULL;
+ ssh_virtual_adapter_destructor(adapter->dev);
+ adapter->dev = NULL;
+ SSH_DEBUG(SSH_D_ERROR, ("register_netdev failed: %d", result));
+ return FALSE;
+ }
+
+ /* All ok. */
+ SSH_DEBUG(SSH_D_MIDOK, ("Virtual adapter %d [%s] attached successfully",
+ adapter->dev->ifindex, adapter->dev->name));
+ return TRUE;
+}
+
+static void
+ssh_virtual_adapter_detach_low_level(SshVirtualAdapter adapter)
+{
+#ifdef DEBUG_LIGHT
+ unsigned char adapter_name[SSH_INTERCEPTOR_IFNAME_SIZE];
+ SshInterceptorIfnum adapter_ifnum;
+#endif /* DEBUG_LIGHT */
+
+ /* Virtual adapter is not attached to system. */
+ if (adapter->dev == NULL)
+ return;
+
+#ifdef DEBUG_LIGHT
+ memcpy(adapter_name, adapter->dev->name, IFNAMSIZ);
+ adapter_ifnum = (SshInterceptorIfnum) adapter->dev->ifindex;
+#endif /* DEBUG_LIGHT */
+
+ /* Remove the network device. This call triggers an interface event. */
+ unregister_netdev(adapter->dev);
+
+ /* Unlink netdevice structure, it will be freed in the device destructor. */
+ adapter->dev = NULL;
+
+ /* All ok. */
+ SSH_DEBUG(SSH_D_NICETOKNOW, ("Virtual adapter %d [%s] detached",
+ (int)adapter_ifnum, adapter_name));
+}
+
+/* *************** Creating and Destroying Virtual Adapters *****************/
+
+/* Workhorse for destroy_all and error handler for create. `adapter' must
+ not be in the adapter table when this function is called. */
+static Boolean
+ssh_virtual_adapter_destroy(SshInterceptor interceptor,
+ SshVirtualAdapter adapter)
+{
+ SSH_ASSERT(adapter != NULL);
+
+ ssh_kernel_mutex_assert_is_locked(interceptor->interceptor_lock);
+
+ SSH_DEBUG(SSH_D_HIGHOK,
+ ("Destroying virtual adapter %d [%s]",
+ (adapter->dev ? adapter->dev->ifindex : -1),
+ (adapter->dev ? adapter->dev->name : "unknown")));
+
+ if (adapter->dev)
+ {
+ /* Detach and destroy net_device. */
+ ssh_kernel_mutex_unlock(interceptor->interceptor_lock);
+ local_bh_enable();
+
+ /* This call will produce an interface event. */
+ ssh_virtual_adapter_detach_low_level(adapter);
+
+ local_bh_disable();
+ ssh_kernel_mutex_lock(interceptor->interceptor_lock);
+ adapter->dev = NULL;
+ }
+
+ /* Free adapter */
+ ssh_free(adapter);
+
+ /* All ok. */
+ return TRUE;
+}
+
+/* This function is called during module loading. */
+static Boolean
+ssh_virtual_adapter_create(SshInterceptor interceptor,
+ unsigned char *adapter_name)
+{
+ SshVirtualAdapter adapter;
+ SshUInt32 i;
+ Boolean error = FALSE;
+ unsigned char created_adapter_name[SSH_INTERCEPTOR_IFNAME_SIZE];
+ unsigned char adapter_enaddr[SSH_MAX_VIRTUAL_ADAPTER_HWADDR_LEN];
+
+ local_bh_disable();
+ ssh_kernel_mutex_lock(interceptor->interceptor_lock);
+
+ /* Find a slot for this virtual adapter. Slot index will be used in
+ adapter name and ethernet address creation. */
+ for (i = 0; i < SSH_LINUX_MAX_VIRTUAL_ADAPTERS; i++)
+ {
+ if (interceptor->virtual_adapters[i] == NULL)
+ break;
+ }
+ if (i >= SSH_LINUX_MAX_VIRTUAL_ADAPTERS)
+ {
+ ssh_kernel_mutex_unlock(interceptor->interceptor_lock);
+ local_bh_enable();
+ SSH_DEBUG(SSH_D_ERROR, ("Maximum number of virtual adapters reached"));
+ return FALSE;
+ }
+
+ /* Allocate the virtual adapter and store it in to the table. */
+ adapter = ssh_calloc(1, sizeof(*adapter));
+ if (adapter == NULL)
+ {
+ ssh_kernel_mutex_unlock(interceptor->interceptor_lock);
+ local_bh_enable();
+ SSH_DEBUG(SSH_D_ERROR, ("Could not allocate virtual adapter"));
+ return FALSE;
+ }
+ interceptor->virtual_adapters[i] = adapter;
+
+ /* Create a name for the virtual adapter. */
+ if (adapter_name == NULL)
+ {
+ snprintf(created_adapter_name, SSH_INTERCEPTOR_IFNAME_SIZE,
+ "%s%d", SSH_ADAPTER_NAME_PREFIX, (int)i);
+ adapter_name = created_adapter_name;
+ }
+
+ /* Create ethernet hardware address for virtual adapter. */
+ ssh_virtual_adapter_interface_ether_address(i, adapter_enaddr);
+
+ /* We can't have lock when attaching the adapter, as it will create an
+ interface event. It is guaranteed that the adapter will not disappear
+ under us, as it not yet marked initialized. */
+ ssh_kernel_mutex_unlock(interceptor->interceptor_lock);
+ local_bh_enable();
+
+ /* Initialize net_device structure and attach it to the system. */
+ if (!ssh_virtual_adapter_attach_low_level(adapter,
+ adapter_name, adapter_enaddr))
+ {
+ SSH_DEBUG(SSH_D_ERROR,
+ ("Could not attach virtual adapter %s to system.",
+ adapter_name));
+ error = TRUE;
+ }
+ else
+ {
+ /* We are attached to the system. */
+ SSH_DEBUG(SSH_D_MIDOK,
+ ("Virtual adapter %lu [%s] created",
+ (unsigned long)adapter->dev->ifindex, adapter->dev->name));
+ }
+
+ /* Lock for finalizing adapter creation. */
+ local_bh_disable();
+ ssh_kernel_mutex_lock(interceptor->interceptor_lock);
+
+ /* Mark adapter initialized. */
+ adapter->initialized = 1;
+
+ /* Adapter low level attach failed or adapter was destroyed under us.
+ Free it now. */
+ if (error || adapter->destroyed)
+ {
+ interceptor->virtual_adapters[i] = NULL;
+ ssh_virtual_adapter_destroy(interceptor, adapter);
+ ssh_kernel_mutex_unlock(interceptor->interceptor_lock);
+ local_bh_enable();
+ return FALSE;
+ }
+
+ /* All ok. */
+ ssh_kernel_mutex_unlock(interceptor->interceptor_lock);
+ local_bh_enable();
+ return TRUE;
+}
+
+/* This function is called during module unload. */
+static void
+ssh_virtual_adapter_destroy_all(SshInterceptor interceptor)
+{
+ SshVirtualAdapter adapter;
+ Boolean check_again;
+ SshUInt32 i;
+
+ restart:
+ local_bh_disable();
+ ssh_kernel_mutex_lock(interceptor->interceptor_lock);
+
+ check_again = FALSE;
+ for (i = 0; i < SSH_LINUX_MAX_VIRTUAL_ADAPTERS; i++)
+ {
+ adapter = interceptor->virtual_adapters[i];
+ if (adapter == NULL)
+ continue;
+
+ if (!adapter->initialized)
+ {
+ /* Initialization is underway, mark adapter to be destroyed. */
+ adapter->destroyed = 1;
+ check_again = TRUE;
+ continue;
+ }
+
+ /* Remove adapter from table. */
+ interceptor->virtual_adapters[i] = NULL;
+
+ /* Detach and destroy adapter. */
+ ssh_virtual_adapter_destroy(interceptor, adapter);
+
+ /* Unlock and restart. */
+ ssh_kernel_mutex_unlock(interceptor->interceptor_lock);
+ local_bh_enable();
+ goto restart;
+ }
+
+ ssh_kernel_mutex_unlock(interceptor->interceptor_lock);
+ local_bh_enable();
+
+ if (check_again)
+ goto restart;
+}
+
+/* ************ Interceptor Side Virtual Adapter Init / Uninit ***************/
+
+/* Initialize virtual adapters. This function is called from linux_main.c
+ during module loading. */
+int ssh_interceptor_virtual_adapter_init(SshInterceptor interceptor)
+{
+ SshUInt32 i;
+
+ SSH_ASSERT(!in_softirq());
+
+ if (num_virtual_adapters > SSH_LINUX_MAX_VIRTUAL_ADAPTERS)
+ {
+ SSH_DEBUG(SSH_D_NICETOKNOW,
+ ("Maximum value for num_virtual_adapters is %d",
+ SSH_LINUX_MAX_VIRTUAL_ADAPTERS));
+ return -1;
+ }
+
+ for (i = 0; i < num_virtual_adapters; i++)
+ {
+ if (!ssh_virtual_adapter_create(interceptor, NULL))
+ goto error;
+ }
+
+ return 0;
+
+ error:
+ ssh_virtual_adapter_destroy_all(interceptor);
+ return -1;
+}
+
+/* Uninitialize virtual adapters. This function is called from linux_main.c
+ during module unloading. */
+int ssh_interceptor_virtual_adapter_uninit(SshInterceptor interceptor)
+{
+ SSH_ASSERT(!in_softirq());
+
+ /* Detach all virtual adapters from the system. */
+ ssh_virtual_adapter_destroy_all(interceptor);
+
+ return 0;
+}
+
+Boolean
+ssh_virtual_adapter_param_decode(SshVirtualAdapterParams params,
+ const unsigned char *data, size_t len)
+{
+ unsigned char *dns;
+ size_t dns_len;
+ unsigned char *wins;
+ size_t wins_len;
+ unsigned char *win_domain;
+ size_t win_domain_len;
+ SshUInt32 netbios_node_type;
+ SshUInt32 i;
+ size_t decode_len;
+
+ SSH_ASSERT(params != NULL);
+ SSH_ASSERT(data != NULL);
+ SSH_ASSERT(len > 0);
+
+ memset(params, 0, sizeof(*params));
+
+ if (ssh_decode_array(data, len,
+ SSH_DECODE_UINT32(&params->mtu),
+ SSH_DECODE_UINT32(&params->dns_ip_count),
+ SSH_DECODE_UINT32_STR_NOCOPY(&dns, &dns_len),
+ SSH_DECODE_UINT32(&params->wins_ip_count),
+ SSH_DECODE_UINT32_STR_NOCOPY(&wins, &wins_len),
+ SSH_DECODE_UINT32_STR_NOCOPY(
+ &win_domain, &win_domain_len),
+ SSH_DECODE_UINT32(&netbios_node_type),
+ SSH_FORMAT_END) != len)
+ return FALSE;
+
+ /* DNS. */
+ if (params->dns_ip_count)
+ {
+ params->dns_ip = ssh_calloc(params->dns_ip_count,
+ sizeof(*params->dns_ip));
+ if (params->dns_ip == NULL)
+ goto error;
+
+ for (i = 0; i < params->dns_ip_count; i++)
+ {
+ decode_len = ssh_decode_ipaddr_array(dns, dns_len,
+ &params->dns_ip[i]);
+ if (decode_len == 0)
+ goto error;
+ dns += decode_len;
+ dns_len -= decode_len;
+ }
+ }
+
+ /* WINS. */
+ if (params->wins_ip_count)
+ {
+ params->wins_ip = ssh_calloc(params->wins_ip_count,
+ sizeof(*params->wins_ip));
+ if (params->wins_ip == NULL)
+ goto error;
+
+ for (i = 0; i < params->wins_ip_count; i++)
+ {
+ decode_len = ssh_decode_ipaddr_array(wins, wins_len,
+ &params->wins_ip[i]);
+ if (decode_len == 0)
+ goto error;
+ wins += decode_len;
+ wins_len -= decode_len;
+ }
+ }
+
+ if (win_domain_len)
+ {
+ params->win_domain = ssh_memdup(win_domain, win_domain_len);
+ if (params->win_domain == NULL)
+ goto error;
+ }
+
+ params->netbios_node_type = (SshUInt8) netbios_node_type;
+
+ return TRUE;
+
+ error:
+ ssh_free(params->dns_ip);
+ ssh_free(params->wins_ip);
+ ssh_free(params->win_domain);
+ memset(params, 0, sizeof(*params));
+ return FALSE;
+}
+
+void
+ssh_virtual_adapter_interface_ether_address(SshInterceptorIfnum adapter_ifnum,
+ unsigned char *buffer)
+{
+ memset(buffer, 0, SSH_ETHERH_ADDRLEN);
+ buffer[1] = 1;
+ SSH_PUT_32BIT(buffer + 2, (SshUInt32) adapter_ifnum + 1);
+}
+
+void
+ssh_virtual_adapter_ip_ether_address(SshIpAddr ip, unsigned char *buffer)
+{
+ memset(buffer, 0, SSH_ETHERH_ADDRLEN);
+
+ if (SSH_IP_IS4(ip))
+ {
+ buffer[1] = 2;
+ SSH_IP4_ENCODE(ip, buffer + 2);
+ }
+#if defined (WITH_IPV6)
+ else
+ {
+ SshUInt32 value;
+
+ value = SSH_IP6_WORD0_TO_INT(ip);
+ value ^= SSH_IP6_WORD1_TO_INT(ip);
+ value ^= SSH_IP6_WORD2_TO_INT(ip);
+ value ^= SSH_IP6_WORD3_TO_INT(ip);
+
+ buffer[1] = 2;
+ SSH_PUT_32BIT(buffer + 2, value);
+ }
+#endif /* WITH_IPV6 */
+}
+
+
+/* ****************** Sending Packets to Local Stack ************************/
+
+void
+ssh_virtual_adapter_send(SshInterceptor interceptor,
+ SshInterceptorPacket pp)
+{
+ SshVirtualAdapter adapter;
+ SshInterceptorInternalPacket ipp = (SshInterceptorInternalPacket) pp;
+ struct net_device_stats *stats;
+ struct sk_buff *skb;
+
+ local_bh_disable();
+ ssh_kernel_mutex_lock(interceptor->interceptor_lock);
+ adapter = ssh_virtual_adapter_ifnum_to_adapter(interceptor, pp->ifnum_out);
+ if (adapter == NULL)
+ {
+ ssh_kernel_mutex_unlock(interceptor->interceptor_lock);
+ local_bh_enable();
+ SSH_DEBUG(SSH_D_ERROR,
+ ("Virtual adapter %d does not exist", (int)pp->ifnum_out));
+ goto error;
+ }
+
+ /* Check the type of the source packet. */
+ if (pp->protocol == SSH_PROTOCOL_ETHERNET)
+ {
+ /* We can send this directly. */
+ }
+ else if (pp->protocol == SSH_PROTOCOL_IP4
+#ifdef SSH_LINUX_INTERCEPTOR_IPV6
+ || pp->protocol == SSH_PROTOCOL_IP6
+#endif /* SSH_LINUX_INTERCEPTOR_IPV6 */
+ )
+ {
+ unsigned char ether_hdr[SSH_ETHERH_HDRLEN];
+ SshIpAddrStruct src;
+ SshUInt16 ethertype = SSH_ETHERTYPE_IP;
+ unsigned char *cp = NULL;
+ size_t packet_len;
+
+ /* Add ethernet framing. */
+
+ /* Destination is virtual adapter's ethernet address. */
+ memcpy(ether_hdr + SSH_ETHERH_OFS_DST, adapter->dev->dev_addr,
+ SSH_ETHERH_ADDRLEN);
+
+ /* Resolve packet's source and the ethernet type to use. */
+ packet_len = ssh_interceptor_packet_len(pp);
+
+ /* IPv4 */
+ if (pp->protocol == SSH_PROTOCOL_IP4)
+ {
+ if (packet_len < SSH_IPH4_HDRLEN)
+ {
+ ssh_kernel_mutex_unlock(interceptor->interceptor_lock);
+ local_bh_enable();
+ SSH_DEBUG(SSH_D_ERROR,
+ ("Packet is too short to contain IPv4 header"));
+ goto error;
+ }
+
+ /* Pullup requests data from the header of a writable skb. */
+ if (likely(skb_headlen(ipp->skb) >= SSH_IPH4_HDRLEN
+ && !skb_shared(ipp->skb) &&
+ SSH_SKB_WRITABLE(ipp->skb, SSH_IPH4_HDRLEN)))
+ cp = ipp->skb->data;
+
+ if (cp == NULL)
+ {
+ ssh_kernel_mutex_unlock(interceptor->interceptor_lock);
+ local_bh_enable();
+ goto error_already_freed;
+ }
+
+ SSH_IPH4_SRC(&src, cp);
+ }
+
+#ifdef SSH_LINUX_INTERCEPTOR_IPV6
+ /* IPv6 */
+ else
+ {
+ if (packet_len < SSH_IPH6_HDRLEN)
+ {
+ ssh_kernel_mutex_unlock(interceptor->interceptor_lock);
+ local_bh_enable();
+ SSH_DEBUG(SSH_D_ERROR,
+ ("Packet too short to contain IPv6 header"));
+ goto error;
+ }
+
+ if (likely(skb_headlen(ipp->skb) >= SSH_IPH6_HDRLEN
+ && !skb_shared(ipp->skb) &&
+ SSH_SKB_WRITABLE(ipp->skb, SSH_IPH6_HDRLEN)))
+ cp = ipp->skb->data;
+
+ if (cp == NULL)
+ {
+ ssh_kernel_mutex_unlock(interceptor->interceptor_lock);
+ local_bh_enable();
+ goto error_already_freed;
+ }
+
+ SSH_IPH6_SRC(&src, cp);
+ ethertype = SSH_ETHERTYPE_IPv6;
+ }
+#endif /* SSH_LINUX_INTERCEPTOR_IPV6 */
+
+ /* Finalize ethernet header. */
+ ssh_virtual_adapter_ip_ether_address(&src,
+ ether_hdr + SSH_ETHERH_OFS_SRC);
+ SSH_PUT_16BIT(ether_hdr + SSH_ETHERH_OFS_TYPE, ethertype);
+
+ /* Insert header to the packet. */
+ cp = NULL;
+ if (likely((skb_headroom(ipp->skb) >=
+ (SSH_ETHERH_HDRLEN + SSH_INTERCEPTOR_PACKET_HARD_HEAD_ROOM))
+ && !skb_shared(ipp->skb) && SSH_SKB_WRITABLE(ipp->skb, 0)))
+ cp = skb_push(ipp->skb, SSH_ETHERH_HDRLEN);
+
+ if (cp == NULL)
+ {
+ ssh_kernel_mutex_unlock(interceptor->interceptor_lock);
+ goto error_already_freed;
+ }
+ memcpy(cp, ether_hdr, SSH_ETHERH_HDRLEN);
+
+ /* Just to be pedantic. */
+ pp->protocol = SSH_PROTOCOL_ETHERNET;
+ }
+ else
+ {
+ ssh_kernel_mutex_unlock(interceptor->interceptor_lock);
+ local_bh_enable();
+ SSH_DEBUG(SSH_D_ERROR, ("Can not handle protocol %d", pp->protocol));
+ goto error;
+ }
+
+ /* Tear off the internal packet from the generic SshInterceptorPacket. */
+ skb = ipp->skb;
+ ipp->skb = NULL;
+
+ /* (re-)receive the packet via the interface; this should
+ make the packet go back up the stack */
+ skb->protocol = eth_type_trans(skb, adapter->dev);
+ skb->dev = adapter->dev;
+
+ /* Update per virtual adapter statistics. */
+ stats = &adapter->low_level_stats;
+ stats->rx_packets++;
+ stats->rx_bytes += skb->len;
+
+ ssh_kernel_mutex_unlock(interceptor->interceptor_lock);
+ local_bh_enable();
+
+ /* Send the skb up towards stack. If it is IP (or ARP), it will be
+ intercepted by ssh_interceptor_packet_in. */
+ netif_rx(skb);
+
+ /* Put the packet header on freelist. */
+ ssh_interceptor_packet_free((SshInterceptorPacket) ipp);
+ return;
+
+ error:
+ ssh_interceptor_packet_free(pp);
+
+ error_already_freed:
+ return;
+}
diff --git a/drivers/interceptor/linux_virtual_adapter_internal.h b/drivers/interceptor/linux_virtual_adapter_internal.h
new file mode 100644
index 0000000..72f3b01
--- /dev/null
+++ b/drivers/interceptor/linux_virtual_adapter_internal.h
@@ -0,0 +1,73 @@
+/* Netfilter Driver for IPSec VPN Client
+ *
+ * Copyright(c) 2012 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.
+ */
+
+/*
+ *
+ * linux_virtual_adapter_internal.h
+ *
+ * Internal declarations for linux virtual adapters.
+ *
+ */
+
+
+#ifndef LINUX_VIRTUAL_ADAPTER_INTERNAL_H
+#define LINUX_VIRTUAL_ADAPTER_INTERNAL_H
+
+#include "virtual_adapter.h"
+
+/* **************************** Types and Definitions ************************/
+
+/* Maximum number of virtual adapters. */
+#define SSH_LINUX_MAX_VIRTUAL_ADAPTERS 16
+
+/* Prefix for adapter names. */
+#define SSH_ADAPTER_NAME_PREFIX "vip"
+
+/* HW address lenght. */
+#define SSH_MAX_VIRTUAL_ADAPTER_HWADDR_LEN 6
+
+/* Maximum number of configured IPv6 addresses the virtual adapter saves
+ and restores on ifdown / ifup. */
+#define SSH_VIRTUAL_ADAPTER_MAX_IPV6_ADDRS 2
+
+/* Context for a virtual adapter. */
+typedef struct SshVirtualAdapterRec
+{
+ /* Is the adapter initialized. This is 0 until the
+ ssh_virtual_adapter_create() returns. */
+ SshUInt8 initialized : 1;
+
+ /* Is the adapter destroyed. */
+ SshUInt8 destroyed : 1;
+
+ /* Is the adapter attached to engine. */
+ SshUInt8 attached : 1;
+
+ /* Packet callback. */
+ SshVirtualAdapterPacketCB packet_cb;
+
+ /* Destructor for engine-level block */
+ SshVirtualAdapterDetachCB detach_cb;
+ void *adapter_context;
+
+ /* The low-level implementation of a virtual adapter. */
+
+ /* Platform dependant low-level implementation structure. */
+ struct net_device *dev;
+ struct net_device_stats low_level_stats;
+
+} SshVirtualAdapterStruct, *SshVirtualAdapter;
+
+/* ******************************* Functions *********************************/
+
+int ssh_interceptor_virtual_adapter_init(SshInterceptor interceptor);
+int ssh_interceptor_virtual_adapter_uninit(SshInterceptor interceptor);
+
+#endif /* LINUX_VIRTUAL_ADAPTER_INTERNAL_H */
diff --git a/drivers/interceptor/platform_interceptor.h b/drivers/interceptor/platform_interceptor.h
new file mode 100644
index 0000000..2813cca
--- /dev/null
+++ b/drivers/interceptor/platform_interceptor.h
@@ -0,0 +1,34 @@
+/* Netfilter Driver for IPSec VPN Client
+ *
+ * Copyright(c) 2012 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.
+ */
+
+/*
+ * platform_interceptor.h
+ *
+ * Linux interceptor specific defines for the Interceptor API.
+ *
+ */
+
+#ifndef SSH_PLATFORM_INTERCEPTOR_H
+
+#define SSH_PLATFORM_INTERCEPTOR_H 1
+
+#ifdef KERNEL
+#ifndef KERNEL_INTERCEPTOR_USE_FUNCTIONS
+
+#define ssh_interceptor_packet_len(pp) \
+ ((size_t)((SshInterceptorInternalPacket)(pp))->skb->len)
+
+#include "linux_params.h"
+#include "linux_packet_internal.h"
+
+#endif /* KERNEL_INTERCEPTOR_USE_FUNCTIONS */
+#endif /* KERNEL */
+
+#endif /* SSH_PLATFORM_INTERCEPTOR_H */
diff --git a/drivers/interceptor/platform_kernel_mutex.h b/drivers/interceptor/platform_kernel_mutex.h
new file mode 100644
index 0000000..2e9d080
--- /dev/null
+++ b/drivers/interceptor/platform_kernel_mutex.h
@@ -0,0 +1,54 @@
+/* Netfilter Driver for IPSec VPN Client
+ *
+ * Copyright(c) 2012 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.
+ */
+
+/*
+ * platform_kernel_mutex.h
+ *
+ * Linux interceptor specific defines for the kernel mutex API.
+ *
+ */
+
+#ifndef PLATFORM_KERNEL_MUTEX_H
+#define PLATFORM_KERNEL_MUTEX_H 1
+
+/* Sanity check to make sure that optimizations get done correcly
+ on a UP machine. The following block can be safely removed. */
+#ifndef CONFIG_SMP
+#ifdef __ASM_SPINLOCK_H
+#error "asm/spinlock.h" should not be included explicitly.
+#endif /* __ASM_SPINLOCK_H */
+#endif /* !CONFIG_SMP */
+
+#include "linux_params.h"
+#include "linux_mutex_internal.h"
+
+/* Directly map linux mutexes to macros. This causes significantly
+ less overhead in the non-preemptive UP case, where these macros
+ are empty. */
+#ifndef KERNEL_MUTEX_USE_FUNCTIONS
+
+/* This code should not be used unless DEBUG_LIGHT is disabled. */
+
+#define ssh_kernel_mutex_lock(a) spin_lock(&((a)->lock))
+#define ssh_kernel_mutex_unlock(b) spin_unlock(&((b)->lock))
+
+#else /* KERNEL_MUTEX_USE_FUNCTIONS */
+
+void ssh_kernel_mutex_lock_i(SshKernelMutex mutex);
+void ssh_kernel_mutex_unlock_i(SshKernelMutex mutex);
+
+#define ssh_kernel_mutex_lock(a) \
+ ssh_kernel_mutex_lock_i((a))
+#define ssh_kernel_mutex_unlock(a) \
+ ssh_kernel_mutex_unlock_i((a))
+
+#endif /* KERNEL_MUTEX_USE_FUNCTIONS */
+
+#endif /* PLATFORM_KERNEL_MUTEX_H */
diff --git a/drivers/interceptor/sshconf.h b/drivers/interceptor/sshconf.h
new file mode 100644
index 0000000..e198965
--- /dev/null
+++ b/drivers/interceptor/sshconf.h
@@ -0,0 +1,88 @@
+/* Netfilter Driver for IPSec VPN Client
+ *
+ * Copyright(c) 2012 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.
+ */
+
+/*
+ * sshconf.h
+ *
+ * Generic configuration defines.
+ *
+ */
+
+#ifndef SSHCONF_H
+#define SSHCONF_H
+
+/* Light debugging */
+#define DEBUG_LIGHT 1
+
+/* Interceptor has its own version of ssh_interceptor_packet_copy */
+/* #undef INTERCEPTOR_HAS_PACKET_COPY */
+
+/* Interceptor has its own version of ssh_interceptor_packet_copyin */
+#define INTERCEPTOR_HAS_PACKET_COPYIN 1
+
+/* Interceptor has its own version of ssh_interceptor_packet_copyout */
+#define INTERCEPTOR_HAS_PACKET_COPYOUT 1
+
+/* Interceptor has its own versions of
+ ssh_interceptor_export_internal_data and
+ ssh_interceptor_import_internal_data */
+#define INTERCEPTOR_HAS_PACKET_INTERNAL_DATA_ROUTINES 1
+
+/* Interceptor has "platform_interceptor.h" include file
+ to be included by interceptor.h. */
+#define INTERCEPTOR_HAS_PLATFORM_INCLUDE 1
+
+/* Should the interceptor align the IP header of packets to word boundary
+ when sending to the network or stack? */
+/* #undef INTERCEPTOR_IP_ALIGNS_PACKETS */
+
+/* Define this if the interceptor operates at IP level (that is, no
+ interface supplies or requires packets at ethernet level, or
+ generally media level). Generally there is no much difference in
+ performance whether the interceptor operates at ethernet level or
+ at IP level; however, some functionality (particularity the ability
+ to proxy arp so that the same subnet can be shared for both
+ external and DMZ interfaces) is not available without an ethernet
+ level interceptor. */
+#define SSH_IPSEC_IP_ONLY_INTERCEPTOR 1
+
+#define KERNEL_SIZEOF_SHORT 2
+#define KERNEL_SIZEOF_INT 4
+#define KERNEL_SIZEOF_LONG_LONG 8
+
+#ifdef __LP64__
+#define KERNEL_SIZEOF_LONG 8
+#define KERNEL_SIZEOF_SIZE_T 8
+#define KERNEL_SIZEOF_VOID_P 8
+#else
+#define KERNEL_SIZEOF_LONG 4
+#define KERNEL_SIZEOF_SIZE_T 4
+#define KERNEL_SIZEOF_VOID_P 4
+#endif
+
+#include <asm/byteorder.h>
+
+#if defined(__BIG_ENDIAN)
+#define WORDS_BIGENDIAN
+#elif !defined(__LITTLE_ENDIAN)
+#error cannot determine byte order
+#endif
+
+/* "Have" for kernel basic types */
+#define HAVE_KERNEL_INT 1
+#define HAVE_KERNEL_LONG 1
+#define HAVE_KERNEL_LONG_LONG 1
+#define HAVE_KERNEL_SHORT 1
+#define HAVE_KERNEL_VOID_P 1
+
+/* Define this to enable IPv6 support. */
+#define WITH_IPV6 1
+
+#endif /* SSHCONF_H */
diff --git a/drivers/interceptor/sshdebug.h b/drivers/interceptor/sshdebug.h
new file mode 100644
index 0000000..c1c0836
--- /dev/null
+++ b/drivers/interceptor/sshdebug.h
@@ -0,0 +1,175 @@
+/* Netfilter Driver for IPSec VPN Client
+ *
+ * Copyright(c) 2012 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.
+ */
+
+/*
+ * sshdebug.h
+ *
+ * Debug macros and assertions.
+ *
+ */
+
+#ifndef SSHDEBUG_H
+#define SSHDEBUG_H
+
+#ifdef DEBUG_LIGHT
+
+/* Debug level */
+extern unsigned int ssh_debug_level;
+
+#define SSH_FATAL(_fmt...) panic(_fmt)
+
+#define SSH_NOTREACHED \
+ panic("%s:%d: Unreachable code reached!", __FILE__, __LINE__)
+
+#define SSH_DEBUG(level, varcall) \
+ do { \
+ if ((level) <= ssh_debug_level) \
+ { \
+ printk("%s:%d: ", __FILE__, __LINE__); \
+ printk varcall; \
+ printk("\n"); \
+ } \
+ } while (0)
+
+#define SSH_ASSERT(cond) \
+ do { \
+ if (!(cond)) \
+ panic("%s:%d: Assertion failed: %s\n", __FILE__, __LINE__, "#cond"); \
+ } while (0)
+#define SSH_VERIFY(cond) SSH_ASSERT(cond)
+#define SSH_PRECOND(cond) SSH_ASSERT(cond)
+
+static inline void
+ssh_debug_hexdump(const unsigned char *buf, const size_t len)
+{
+ size_t i;
+
+ for (i = 0; (i + 16) < len; i += 16)
+ printk("%08x: %02x%02x %02x%02x %02x%02x %02x%02x "
+ "%02x%02x %02x%02x %02x%02x %02x%02x\n",
+ (unsigned int) i,
+ (unsigned int) buf[i+0], (unsigned int) buf[i+1],
+ (unsigned int) buf[i+2], (unsigned int) buf[i+3],
+ (unsigned int) buf[i+4], (unsigned int) buf[i+5],
+ (unsigned int) buf[i+6], (unsigned int) buf[i+7],
+ (unsigned int) buf[i+8], (unsigned int) buf[i+9],
+ (unsigned int) buf[i+10], (unsigned int) buf[i+11],
+ (unsigned int) buf[i+12], (unsigned int) buf[i+13],
+ (unsigned int) buf[i+14], (unsigned int) buf[i+15]);
+ if (i >= len)
+ return;
+
+ printk("%08x: ", (unsigned int) i);
+ for (; i < len; i++)
+ printk("%02x%s", (unsigned int) buf[i], ((i % 2) == 1 ? " " : ""));
+ printk("\n");
+}
+
+#define SSH_DEBUG_HEXDUMP(level, varcall, buf, len) \
+ do { \
+ if ((level) <= ssh_debug_level) \
+ { \
+ printk("%s:%d: ", __FILE__, __LINE__); \
+ printk varcall; \
+ printk("\n"); \
+ ssh_debug_hexdump((buf), (len)); \
+ } \
+ } while (0)
+
+#else /* !DEBUG_LIGHT */
+
+#define SSH_FATAL(_fmt...) panic(_fmt)
+
+#define SSH_NOTREACHED \
+ panic("%s:%d: Unreachable code reached!", __FILE__, __LINE__)
+
+#define SSH_DEBUG(level, varcall)
+
+#define SSH_VERIFY(cond) \
+ do { \
+ if (!(cond)) \
+ panic("%s:%d: Verify failed: %s\n", __FILE__, __LINE__, "#cond"); \
+ } while (0)
+
+#ifdef __COVERITY__
+#define SSH_ASSERT(cond) \
+ do { \
+ if (!(cond)) \
+ panic("%s:%d: Assertion failed: %s\n", __FILE__, __LINE__, "#cond"); \
+ } while (0)
+#else /* __COVERITY__ */
+#define SSH_ASSERT(cond)
+#endif /* __COVERITY__ */
+
+#define SSH_PRECOND(cond) SSH_ASSERT(cond)
+
+#define SSH_DEBUG_HEXDUMP(level, varcall, buf, len)
+
+#endif /* DEBUG_LIGHT */
+
+
+
+/* *********************************************************************
+ * DEBUG LEVELS
+ * *********************************************************************/
+
+/* *********************************************************************
+ * Debug type definitions for debug level mapping
+ * *********************************************************************/
+
+/* Use debug code definitions below, not the debug level numbers
+ (except 11-15). */
+
+/** Software malfunction. */
+#define SSH_D_ERROR 0
+
+/** Software failure, but caused by a packet coming from network. */
+#define SSH_D_NETFAULT 3
+
+/** Data formatted incorrectly coming from a network or other outside source.*/
+#define SSH_D_NETGARB 3
+
+/** Nonfatal failure in a high or middle-level operation. */
+#define SSH_D_FAIL 3
+
+/** Uncommon situation. */
+#define SSH_D_UNCOMMON 6
+
+/** Success in a high-level operation. */
+#define SSH_D_HIGHOK 4
+
+/** Success in a middle-level operation. */
+#define SSH_D_MIDOK 7
+
+/** Success in a low-level operation. */
+#define SSH_D_LOWOK 9
+
+/** Start of a high-level operation. */
+#define SSH_D_HIGHSTART 5
+
+/** Start of a middle-level operation. */
+#define SSH_D_MIDSTART 8
+
+/** Start of a low-level operation. */
+#define SSH_D_LOWSTART 10
+
+/** Nice-to-know information. */
+#define SSH_D_NICETOKNOW 7
+
+/** Data block dump. */
+#define SSH_D_DATADUMP 8
+
+/** Packet dump. */
+#define SSH_D_PCKDMP 9
+
+/** Middle result of an operation, loop-internal information. */
+#define SSH_D_MIDRESULT 10
+
+#endif /* SSHDEBUG_H */
diff --git a/drivers/interceptor/sshencode.h b/drivers/interceptor/sshencode.h
new file mode 100644
index 0000000..473e212
--- /dev/null
+++ b/drivers/interceptor/sshencode.h
@@ -0,0 +1,202 @@
+/* Netfilter Driver for IPSec VPN Client
+ *
+ * Copyright(c) 2012 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.
+ */
+
+/*
+ * sshencode.h
+ *
+ * Encode/decode API.
+ *
+ */
+
+#ifndef SSHENCODE_H
+#define SSHENCODE_H
+
+/* Encode object in `datum' into buffer `buf' whose size is `len' bytes.
+
+ Return values:
+ [0,len] number of bytes datums prentation took in the buffer.
+ ]len,inf[ amount of space writing datum would require.
+
+ If buf can be extented, this will be done by the driver, and the
+ encoder function will be called again. If buf can not be extented
+ (either it is static, or allocating space fails at the driver,
+ ssh_encode call will return error. */
+typedef int (*SshEncodeDatum)(unsigned char *buf, size_t len,
+ const void *datum);
+
+/* Decode */
+typedef int (*SshDecodeDatum)(const unsigned char *buf, size_t len,
+ void **datum);
+
+/* Decode, which does not alloc new datum to be returned, but assumes that
+ it gets preallocated datum of correct size in, and fills it up */
+typedef int (*SshDecodeDatumNoAlloc)(const unsigned char *buf, size_t len,
+ void *datum);
+
+/* The packet encoding/decoding functions take a variable number of
+ arguments, and decode data from a SshBuffer or a character array as
+ specified by a format. Each element of the format contains a type
+ specifier, and arguments depending on the type specifier. The list
+ must end with a SSH_FORMAT_END specifier. */
+
+typedef enum {
+ /* Specifies a string with uint32-coded length. This has two arguments.
+ For encoding,
+ const unsigned char *data
+ size_t len
+ For decoding,
+ unsigned char **data_return
+ size_t *len_return
+ When decoding, either or both arguments may be NULL, in which case they
+ are not stored. The returned data is allocated by ssh_xmalloc, and an
+ extra nul (\0) character is automatically added at the end to make it
+ easier to retrieve strings. */
+ SSH_FORMAT_UINT32_STR, /* Encode const unsigned char *, size_t */
+ /* Decode unsigned char *, size_t * */
+
+
+ /* This code can only be used while decoding. This specifies string with
+ uint32-coded length. This has two arguments:
+ unsigned char **data_return
+ size_t *len_return
+ Either argument may be NULL. *data_return is set to point to the data
+ in the packet, and *len_return is set to the length of the string.
+ No null character is stored, and the string remains in the original
+ buffer. This can only be used with ssh_decode_array. */
+ SSH_FORMAT_UINT32_STR_NOCOPY, /* unsigned char **, size_t */
+
+ /* An 32-bit MSB first integer value. */
+ SSH_FORMAT_UINT32, /* SshUInt32, note that if you encode constant
+ integer, you still must use (SshUInt32) cast
+ before it. Also enums must be casted to
+ SshUInt32 before encoding. */
+
+ /* A boolean value. For encoding, this has a single "Boolean" argument.
+ For decoding, this has a "Boolean *" argument, where the value will
+ be stored. The argument may be NULL in which case the value is not
+ stored. */
+ SSH_FORMAT_BOOLEAN, /* Boolean */
+
+ /* Application specific value given as `void *' argument is encoded
+ using SshEncodeDatum function, or decoded using SshDecodeDatum.
+ For information about renderers, see their definitions. */
+ SSH_FORMAT_SPECIAL, /* SshEncodeDatum, void * */
+ /* SshDecodeDatum, void ** */
+
+ /* A single one-byte character. The argument is of type "unsigned int"
+ when encoding, and of type "unsigned int *" when decoding. The value
+ may also be NULL when decoding, in which case the value is ignored. */
+ SSH_FORMAT_CHAR, /* unsigned int */
+
+ /* A fixed-length character array, without explicit length. When
+ encoding, the arguments are
+ const unsigned char *buf
+ size_t len
+ and when decoding,
+ unsigned char *buf
+ size_t len
+ The buffer must be preallocated when decoding; data is simply copied
+ there. `buf' may also be NULL, in which the value is ignored. */
+ SSH_FORMAT_DATA, /* char * (fixed length!), size_t */
+
+ /* A 64-bit MSB first integer value. For encoding, this has a single
+ "SshUInt64" argument (the value), and for decoding an
+ "SshUInt64 *" argument, where the value will be stored. The argument
+ may be NULL in which case the value is not stored. */
+ SSH_FORMAT_UINT64, /* SshUInt64 */
+
+ /* A 16-bit MSB first integer value. */
+ SSH_FORMAT_UINT16, /* SshUInt16 */
+
+ /* Marks end of the argument list. */
+ SSH_FORMAT_END = 0x0d0e0a0d
+} SshEncodingFormat;
+
+/* Encodes the given data to a given buffer as specified by the
+ variable-length argument list. If the given buffer cannot hold the
+ encoded data, 0 is returned and the given buffer is left in
+ undefined state. */
+size_t ssh_encode_array(unsigned char *buf, size_t bufsize,...);
+
+/* Encodes the given data to a given buffer as specified by the
+ variable-length argument list. If the given buffer cannot hold the
+ encoded data, 0 is returned and the given buffer is left in
+ undefined state. */
+size_t ssh_encode_array_va(unsigned char *buf, size_t bufsize, va_list ap);
+
+/* Encodes the given data. Returns the length of encoded data in
+ bytes, and if `buf_return' is non-NULL, it is set to a memory area
+ allocated by ssh_xmalloc that contains the data. The caller should
+ free the data when no longer needed. */
+size_t ssh_encode_array_alloc(unsigned char **buf_return, ...);
+
+/* Encodes the given data. Returns the length of encoded data in
+ bytes, and if `buf_return' is non-NULL, it is set to a memory area
+ allocated by ssh_xmalloc that contains the data. The caller should
+ free the data when no longer needed. */
+size_t ssh_encode_array_alloc_va(unsigned char **buf_return, va_list ap);
+
+/* Decodes data from the given byte array as specified by the
+ variable-length argument list. If all specified arguments could be
+ successfully parsed, returns the number of bytes parsed (any
+ remaining data can be parsed by first skipping this many bytes).
+ If parsing any element results in an error, this returns 0 (and
+ frees any already allocated data). Zero is also returned if the
+ specified length would be exceeded. */
+size_t ssh_decode_array(const unsigned char *buf, size_t len, ...);
+
+/* Decodes data from the given byte array as specified by the
+ variable-length argument list. If all specified arguments could be
+ successfully parsed, returns the number of bytes parsed (any
+ remaining data can be parsed by first skipping this many bytes).
+ If parsing any element results in an error, this returns 0 (and
+ frees any already allocated data). Zero is also returned if the
+ specified length would be exceeded. */
+size_t ssh_decode_array_va(const unsigned char *buf, size_t len, va_list ap);
+
+#define ssh_xxcode_unsigned_char_ptr(ptr) ((unsigned char *) (ptr))
+#define ssh_xxcode_const_unsigned_char_ptr(ptr) ((const unsigned char *) (ptr))
+#define ssh_xxcode_size_t(size) ((size_t) (size))
+#define ssh_xxcode_uint32(num) ((SshUInt32) (num))
+#define ssh_xxcode_uint32_ptr(ptr) ((SshUInt32 *) (ptr))
+#define ssh_xxcode_unsigned_int(num) ((unsigned int) num)
+#define ssh_xxcode_unsigned_int_ptr(ptr) ((unsigned int *) ptr)
+#define ssh_xxcode_unsigned_char_ptr_ptr(ptr) ((unsigned char **) (ptr))
+#define ssh_xxcode_size_t_ptr(size) ((size_t *) (size))
+
+#define SSH_ENCODE_UINT32(num) \
+ SSH_FORMAT_UINT32, \
+ ssh_xxcode_uint32(num)
+#define SSH_DECODE_UINT32(ptr) \
+ SSH_FORMAT_UINT32, \
+ ssh_xxcode_uint32_ptr(ptr)
+
+#define SSH_DECODE_UINT32_STR_NOCOPY(ptr,size) \
+ SSH_FORMAT_UINT32_STR_NOCOPY, \
+ ssh_xxcode_unsigned_char_ptr_ptr(ptr), \
+ ssh_xxcode_size_t_ptr(size)
+
+#define SSH_ENCODE_CHAR(num) \
+ SSH_FORMAT_CHAR, \
+ ssh_xxcode_unsigned_int(num)
+#define SSH_DECODE_CHAR(ptr) \
+ SSH_FORMAT_CHAR, \
+ ssh_xxcode_unsigned_int_ptr(ptr)
+
+#define SSH_ENCODE_DATA(ptr,size) \
+ SSH_FORMAT_DATA, \
+ ssh_xxcode_const_unsigned_char_ptr(ptr), \
+ ssh_xxcode_size_t(size)
+#define SSH_DECODE_DATA(ptr,size) \
+ SSH_FORMAT_DATA, \
+ ssh_xxcode_unsigned_char_ptr(ptr), \
+ ssh_xxcode_size_t(size)
+
+#endif /* SSHENCODE_H */
diff --git a/drivers/interceptor/sshgetput.h b/drivers/interceptor/sshgetput.h
new file mode 100644
index 0000000..9e009a4
--- /dev/null
+++ b/drivers/interceptor/sshgetput.h
@@ -0,0 +1,108 @@
+/* Netfilter Driver for IPSec VPN Client
+ *
+ * Copyright(c) 2012 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.
+ */
+
+/*
+ * sshgetput.h
+ *
+ * Macros for enconding/decoding of integers to character data.
+ *
+ */
+
+#ifndef SSHGETPUT_H
+#define SSHGETPUT_H
+
+
+#define SSH_GET_8BIT(cp) (*(unsigned char *)(cp))
+#define SSH_PUT_8BIT(cp, value) (*(unsigned char *)(cp)) = \
+ (unsigned char)(value)
+
+#define SSH_GET_4BIT_LOW(cp) (*(unsigned char *)(cp) & 0x0f)
+#define SSH_GET_4BIT_HIGH(cp) ((*(unsigned char *)(cp) >> 4) & 0x0f)
+#define SSH_PUT_4BIT_LOW(cp, value) (*(unsigned char *)(cp) = \
+ (unsigned char)((*(unsigned char *)(cp) & 0xf0) | ((value) & 0x0f)))
+#define SSH_PUT_4BIT_HIGH(cp, value) (*(unsigned char *)(cp) = \
+ (unsigned char)((*(unsigned char *)(cp) & 0x0f) | (((value) & 0x0f) << 4)))
+
+#ifdef SSHUINT64_IS_64BITS
+
+#define SSH_GET_64BIT(cp) (((SshUInt64)SSH_GET_32BIT((cp)) << 32) | \
+ ((SshUInt64)SSH_GET_32BIT((cp) + 4)))
+#define SSH_PUT_64BIT(cp, value) do { \
+ SSH_PUT_32BIT((cp), (SshUInt32)((SshUInt64)(value) >> 32)); \
+ SSH_PUT_32BIT((cp) + 4, (SshUInt32)(value)); } while (0)
+
+#else /* SSHUINT64_IS_64BITS */
+
+#define SSH_GET_64BIT(cp) ((SshUInt64)SSH_GET_32BIT((cp) + 4))
+#define SSH_PUT_64BIT(cp, value) do { \
+ SSH_PUT_32BIT((cp), 0L); \
+ SSH_PUT_32BIT((cp) + 4, (SshUInt32)(value)); } while (0)
+#define SSH_GET_64BIT_LSB_FIRST(cp) ((SshUInt64)SSH_GET_32BIT((cp)))
+#define SSH_PUT_64BIT_LSB_FIRST(cp, value) do { \
+ SSH_PUT_32BIT_LSB_FIRST((cp), (SshUInt32)(value)); \
+ SSH_PUT_32BIT_LSB_FIRST((cp) + 4, 0L); } while (0)
+
+#define SSH_GET_40BIT(cp) ((SshUInt64)SSH_GET_32BIT((cp) + 1))
+#define SSH_PUT_40BIT(cp, value) do { \
+ SSH_PUT_8BIT((cp), 0); \
+ SSH_PUT_32BIT((cp) + 1, (SshUInt32)(value)); } while (0)
+#define SSH_GET_40BIT_LSB_FIRST(cp) ((SshUInt64)SSH_GET_32BIT_LSB_FIRST((cp)))
+#define SSH_PUT_40BIT_LSB_FIRST(cp, value) do { \
+ SSH_PUT_32BIT_LSB_FIRST((cp), (SshUInt32)(value)); \
+ SSH_PUT_8BIT((cp) + 4, 0); } while (0)
+
+#endif /* SSHUINT64_IS_64BITS */
+
+
+/*------------ macros for storing/extracting msb first words -------------*/
+
+#define SSH_GET_32BIT(cp) \
+ ((((unsigned long)((unsigned char *)(cp))[0]) << 24) | \
+ (((unsigned long)((unsigned char *)(cp))[1]) << 16) | \
+ (((unsigned long)((unsigned char *)(cp))[2]) << 8) | \
+ ((unsigned long)((unsigned char *)(cp))[3]))
+
+#define SSH_GET_16BIT(cp) \
+ ((SshUInt16) ((((unsigned long)((unsigned char *)(cp))[0]) << 8) | \
+ ((unsigned long)((unsigned char *)(cp))[1])))
+
+#define SSH_PUT_32BIT(cp, value) do { \
+ ((unsigned char *)(cp))[0] = (unsigned char)((value) >> 24); \
+ ((unsigned char *)(cp))[1] = (unsigned char)((value) >> 16); \
+ ((unsigned char *)(cp))[2] = (unsigned char)((value) >> 8); \
+ ((unsigned char *)(cp))[3] = (unsigned char)(value); } while (0)
+
+#define SSH_PUT_16BIT(cp, value) do { \
+ ((unsigned char *)(cp))[0] = (unsigned char)((value) >> 8); \
+ ((unsigned char *)(cp))[1] = (unsigned char)(value); } while (0)
+
+/*------------ macros for storing/extracting lsb first words -------------*/
+
+#define SSH_GET_32BIT_LSB_FIRST(cp) \
+ (((unsigned long)((unsigned char *)(cp))[0]) | \
+ (((unsigned long)((unsigned char *)(cp))[1]) << 8) | \
+ (((unsigned long)((unsigned char *)(cp))[2]) << 16) | \
+ (((unsigned long)((unsigned char *)(cp))[3]) << 24))
+
+#define SSH_GET_16BIT_LSB_FIRST(cp) \
+ ((SshUInt16) (((unsigned long)((unsigned char *)(cp))[0]) | \
+ (((unsigned long)((unsigned char *)(cp))[1]) << 8)))
+
+#define SSH_PUT_32BIT_LSB_FIRST(cp, value) do { \
+ ((unsigned char *)(cp))[0] = (unsigned char)(value); \
+ ((unsigned char *)(cp))[1] = (unsigned char)((value) >> 8); \
+ ((unsigned char *)(cp))[2] = (unsigned char)((value) >> 16); \
+ ((unsigned char *)(cp))[3] = (unsigned char)((value) >> 24); } while (0)
+
+#define SSH_PUT_16BIT_LSB_FIRST(cp, value) do { \
+ ((unsigned char *)(cp))[0] = (unsigned char)(value); \
+ ((unsigned char *)(cp))[1] = (unsigned char)((value) >> 8); } while (0)
+
+#endif /* GETPUT_H */
diff --git a/drivers/interceptor/sshincludes.h b/drivers/interceptor/sshincludes.h
new file mode 100644
index 0000000..b0b59d8
--- /dev/null
+++ b/drivers/interceptor/sshincludes.h
@@ -0,0 +1,53 @@
+/* Netfilter Driver for IPSec VPN Client
+ *
+ * Copyright(c) 2012 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.
+ */
+
+/*
+ * sshincludes.h
+ *
+ * Common include file.
+ *
+ */
+
+#ifndef SSHINCLUDES_H
+#define SSHINCLUDES_H
+
+/* Defines related to segmented memory architectures. */
+#ifndef NULL_FNPTR
+#define NULL_FNPTR NULL
+#endif
+
+/* Macros for giving branch prediction hints to the compiler. The
+ result type of the expression must be an integral type. */
+#if __GNUC__ >= 3
+#define SSH_PREDICT_TRUE(expr) __builtin_expect(!!(expr), 1)
+#define SSH_PREDICT_FALSE(expr) __builtin_expect(!!(expr), 0)
+#else /* __GNUC__ >= 3 */
+#define SSH_PREDICT_TRUE(expr) (!!(expr))
+#define SSH_PREDICT_FALSE(expr) (!!(expr))
+#endif /* __GNUC__ >= 3 */
+
+/* Macros for marking functions to be placed in a special section. */
+#if __GNUC__ >= 3
+#define SSH_FASTTEXT __attribute__((__section__ (".text.fast")))
+#else /* __GNUC__ >= 3 */
+#define SSH_FASTTEXT
+#endif /* __GNUC__ >= 3 */
+
+/* Some generic pointer types. */
+typedef char *SshCharPtr;
+typedef void *SshVoidPtr;
+
+#include "kernel_includes.h"
+
+/* Some internal headers used in almost every file. */
+#include "sshdebug.h"
+#include "engine_alloc.h"
+
+#endif /* SSHINCLUDES_H */
diff --git a/drivers/interceptor/sshinet.h b/drivers/interceptor/sshinet.h
new file mode 100644
index 0000000..ac18c53
--- /dev/null
+++ b/drivers/interceptor/sshinet.h
@@ -0,0 +1,233 @@
+/* Netfilter Driver for IPSec VPN Client
+ *
+ * Copyright(c) 2012 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.
+ */
+
+/*
+ * sshinet.h
+ *
+ * Inet API.
+ *
+ */
+
+#ifndef SSHINET_H
+#define SSHINET_H
+
+#include "sshgetput.h"
+
+/*************************** Ethernet definitions ***************************/
+
+/* Etherenet header things we need */
+#define SSH_ETHERH_HDRLEN 14
+#define SSH_ETHERH_OFS_DST 0
+#define SSH_ETHERH_OFS_SRC 6
+#define SSH_ETHERH_OFS_TYPE 12
+#define SSH_ETHERH_ADDRLEN 6
+
+/* Known values for the ethernet type field. The same values are used for
+ both ethernet (rfc894) and IEEE 802 encapsulation (the type will just
+ be in a different position in the header). */
+#define SSH_ETHERTYPE_IP 0x0800 /* IPv4, as per rfc894 */
+#define SSH_ETHERTYPE_ARP 0x0806 /* ARP, as per rfc826 */
+#define SSH_ETHERTYPE_IPv6 0x86dd /* IPv6, as per rfc1972 */
+
+
+/***************************** SshIpAddr stuff ******************************/
+
+typedef enum {
+ SSH_IP_TYPE_NONE = 0,
+ SSH_IP_TYPE_IPV4 = 1,
+ SSH_IP_TYPE_IPV6 = 2
+} SshIpAddrType;
+
+#if defined(WITH_IPV6)
+/* An IPv6 link-local address scope ID. */
+struct SshScopeIdRec
+{
+ union
+ {
+ SshUInt32 ui32;
+ } scope_id_union;
+};
+
+typedef struct SshScopeIdRec SshScopeIdStruct;
+typedef struct SshScopeIdRec *SshScopeId;
+
+#endif /* WITH_IPV6 */
+
+#if !defined(WITH_IPV6)
+#define SSH_IP_ADDR_SIZE 4
+#define SSH_IP_ADDR_STRING_SIZE 32
+#else /* WITH_IPV6 */
+#define SSH_IP_ADDR_SIZE 16
+#define SSH_IP_ADDR_STRING_SIZE 64
+#endif /* !WITH_IPV6 */
+
+typedef struct SshIpAddrRec
+{
+ /* Note: All fields of this data structure are private, and should
+ not be accessed except using the macros and functions defined in
+ this header. They should never be accessed directly; the
+ internal definition of this structure is subject to change
+ without notice. */
+ SshUInt8 type; /* KEEP type first if changing rest of the contents */
+ SshUInt8 mask_len;
+
+ /* There is a hole of 16 bits here */
+
+ /* For optimised mask comparison routine _addr_data has to be 32-bit
+ aligned so it can be read as words on machines requiring
+ alignment */
+ union {
+ unsigned char _addr_data[SSH_IP_ADDR_SIZE];
+ SshUInt32 _addr_align;
+ } addr_union;
+
+#define addr_data addr_union._addr_data
+
+#if defined(WITH_IPV6)
+ SshScopeIdStruct scope_id;
+#endif /* WITH_IPV6 */
+
+} *SshIpAddr, SshIpAddrStruct;
+
+#define SSH_IP_DEFINED(ip_addr) ((ip_addr)->type != SSH_IP_TYPE_NONE)
+#define SSH_IP_IS4(ip_addr) ((ip_addr)->type == SSH_IP_TYPE_IPV4)
+#define SSH_IP_IS6(ip_addr) ((ip_addr)->type == SSH_IP_TYPE_IPV6)
+
+#define SSH_IP_ADDR_LEN(ip_addr) \
+ (SSH_PREDICT_TRUE(SSH_IP_IS4(ip_addr))\
+ ? (4) \
+ : (SSH_IP_IS6(ip_addr) \
+ ? (16) \
+ : 0))
+
+/* Make given IP address undefined. */
+#define SSH_IP_UNDEFINE(IPADDR) \
+do { \
+ (IPADDR)->type = SSH_IP_TYPE_NONE; \
+} while (0)
+
+
+#if defined(WITH_IPV6)
+/* Decode, that is fill given 'ipaddr', with given 'type', 'bytes' and
+ 'masklen' information. */
+#define __SSH_IP_MASK_DECODE(IPADDR,TYPE,BYTES,BYTELEN,MASKLEN) \
+ do { \
+ (IPADDR)->type = (TYPE); \
+ memmove((IPADDR)->addr_data, (BYTES), (BYTELEN)); \
+ memset(&(IPADDR)->scope_id, 0, sizeof((IPADDR)->scope_id)); \
+ (IPADDR)->mask_len = (MASKLEN); \
+ } while (0)
+#else /* WITH_IPV6 */
+#define __SSH_IP_MASK_DECODE(IPADDR,TYPE,BYTES,BYTELEN,MASKLEN) \
+ do { \
+ (IPADDR)->type = (TYPE); \
+ memmove((IPADDR)->addr_data, (BYTES), (BYTELEN)); \
+ (IPADDR)->mask_len = (MASKLEN); \
+ } while (0)
+#endif /* WITH_IPV6 */
+
+/* Encode, that is copy from 'ipaddr' into 'bytes' and 'maskptr'. The
+ input 'ipaddr' needs to be of given 'type'. It is an fatal error
+ to call this for invalid address type. */
+#define __SSH_IP_MASK_ENCODE(IPADDR,TYPE,BYTES,BYTELEN,MASKPTR) \
+ do { \
+ SSH_VERIFY((IPADDR)->type == (TYPE)); \
+ memmove((BYTES), (IPADDR)->addr_data, (BYTELEN)); \
+ if (SSH_PREDICT_FALSE(MASKPTR)) \
+ *((SshUInt32 *) (MASKPTR)) = (IPADDR)->mask_len; \
+ } while (0)
+
+/* IPv4 Address manipulation */
+#define SSH_IP4_ENCODE(ip_addr,bytes) \
+ __SSH_IP_MASK_ENCODE(ip_addr,SSH_IP_TYPE_IPV4,bytes,4,NULL)
+#define SSH_IP4_DECODE(ip_addr,bytes) \
+ __SSH_IP_MASK_DECODE(ip_addr,SSH_IP_TYPE_IPV4,bytes,4,32)
+
+/* IPv6 address manipulation */
+#define SSH_IP6_ENCODE(ip_addr,bytes) \
+ __SSH_IP_MASK_ENCODE(ip_addr,SSH_IP_TYPE_IPV6,bytes,16,NULL)
+
+#if !defined(WITH_IPV6)
+#define SSH_IP6_DECODE(ip_addr,bytes) SSH_IP_UNDEFINE(ip_addr)
+#else /* WITH_IPV6 */
+#define SSH_IP6_DECODE(ip_addr,bytes) \
+ __SSH_IP_MASK_DECODE(ip_addr,SSH_IP_TYPE_IPV6,bytes,16,128)
+#endif /* !WITH_IPV6 */
+
+#define SSH_IP_MASK_LEN(ip_addr) ((ip_addr)->mask_len)
+
+#if defined(WITH_IPV6)
+#define SSH_IP6_SCOPE_ID(ip_addr) ((ip_addr)->scope_id.scope_id_union.ui32)
+#endif /* WITH_IPV6 */
+
+/*********************** Definitions for IPv4 packets ***********************/
+
+
+/* IPv4 header lengths. */
+#define SSH_IPH4_HDRLEN 20
+#define SSH_IPH4_HLEN(ucp) SSH_GET_4BIT_LOW(ucp)
+#define SSH_IPH4_LEN(ucp) SSH_GET_16BIT((ucp) + 2)
+#define SSH_IPH4_SRC(ipaddr, ucp) SSH_IP4_DECODE((ipaddr), (ucp) + 12)
+
+/*********************** Definitions for IPv6 packets ***********************/
+
+/* IPv6 header length. Extension headers are not counted in IPv6
+ header */
+#define SSH_IPH6_HDRLEN 40
+
+#define SSH_IPH6_OFS_LEN 4
+#define SSH_IPH6_OFS_NH 6
+
+#define SSH_IPH6_ADDRLEN 16
+#define SSH_IPH6_OFS_SRC 8
+
+#define SSH_IP6_WORD0_TO_INT(ip_addr) SSH_GET_32BIT((ip_addr)->addr_data)
+#define SSH_IP6_WORD1_TO_INT(ip_addr) SSH_GET_32BIT((ip_addr)->addr_data + 4)
+#define SSH_IP6_WORD2_TO_INT(ip_addr) SSH_GET_32BIT((ip_addr)->addr_data + 8)
+#define SSH_IP6_WORD3_TO_INT(ip_addr) SSH_GET_32BIT((ip_addr)->addr_data + 12)
+
+#define SSH_IPH6_LEN(ucp) SSH_GET_16BIT((ucp) + SSH_IPH6_OFS_LEN)
+#define SSH_IPH6_NH(ucp) SSH_GET_8BIT((ucp) + SSH_IPH6_OFS_NH)
+#define SSH_IPH6_SRC(ipaddr, ucp) SSH_IP6_DECODE((ipaddr), \
+ (ucp) + SSH_IPH6_OFS_SRC)
+
+/****************** Definitions for IPv6 extension headers ******************/
+
+#define SSH_IP6_EXT_COMMON_NH(ucp) SSH_GET_8BIT((ucp))
+#define SSH_IP6_EXT_COMMON_LEN(ucp) SSH_GET_8BIT((ucp) + 1)
+#define SSH_IP6_EXT_COMMON_LENB(ucp) \
+ ((SSH_IP6_EXT_COMMON_LEN((ucp)) + 1) << 3)
+
+/*************************** Link definitions *******************************/
+
+/* Reserved value for invalid interface index. */
+#define SSH_INVALID_IFNUM 0xffffffff
+
+/***************************** Helper functions *****************************/
+
+/* Sets all rightmost bits after keeping `keep_bits' bits on the left
+ to the value specified by `value'. */
+void ssh_ipaddr_set_bits(SshIpAddr result, SshIpAddr ip,
+ unsigned int keep_bits, unsigned int value);
+
+/* Prints the IP address into the buffer in string format. If the buffer
+ is too short, the address is truncated. This returns `buf'. */
+unsigned char *ssh_ipaddr_print(const SshIpAddr ip, unsigned char *buf,
+ size_t buflen);
+
+/* Prints the IP address into the buffer in string format. If the buffer
+ is too short, the address is truncated. This returns `buf'. */
+void ssh_ipaddr_ipv4_print(const unsigned char *data,
+ unsigned char *buf, size_t buflen);
+void ssh_ipaddr_ipv6_print(const unsigned char *data,
+ unsigned char *buf, size_t buflen,
+ SshUInt32 scope);
+
+#endif /* SSHINET_H */
diff --git a/drivers/interceptor/sshinetbits.c b/drivers/interceptor/sshinetbits.c
new file mode 100644
index 0000000..6a77ef8
--- /dev/null
+++ b/drivers/interceptor/sshinetbits.c
@@ -0,0 +1,45 @@
+/* Netfilter Driver for IPSec VPN Client
+ *
+ * Copyright(c) 2012 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.
+ */
+
+/*
+ * sshinetbits.c
+ *
+ * Implementation of inet API IP address bit manipulation functions.
+ *
+ */
+
+#include "sshincludes.h"
+#include "sshinet.h"
+
+/* Sets all rightmost bits after keeping `keep_bits' bits on the left to
+ the value specified by `value'. */
+
+void ssh_ipaddr_set_bits(SshIpAddr result, SshIpAddr ip,
+ unsigned int keep_bits, unsigned int value)
+{
+ size_t len;
+ unsigned int i;
+
+ len = SSH_IP_IS6(ip) ? 16 : 4;
+
+ *result = *ip;
+ for (i = keep_bits / 8; i < len; i++)
+ {
+ if (8 * i >= keep_bits)
+ result->addr_data[i] = value ? 0xff : 0;
+ else
+ {
+ SSH_ASSERT(keep_bits - 8 * i < 8);
+ result->addr_data[i] &= (0xff << (8 - (keep_bits - 8 * i)));
+ if (value)
+ result->addr_data[i] |= (0xff >> (keep_bits - 8 * i));
+ }
+ }
+}
diff --git a/drivers/interceptor/sshinetencode.c b/drivers/interceptor/sshinetencode.c
new file mode 100644
index 0000000..35b406f
--- /dev/null
+++ b/drivers/interceptor/sshinetencode.c
@@ -0,0 +1,130 @@
+/* Netfilter Driver for IPSec VPN Client
+ *
+ * Copyright(c) 2012 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.
+ */
+
+/*
+ * sshinetencode.c
+ *
+ * Implementation of inet API IP address encoding and decoding functions.
+ *
+ */
+
+#include "sshincludes.h"
+#include "sshencode.h"
+#include "sshinetencode.h"
+
+size_t ssh_encode_ipaddr_array(unsigned char *buf, size_t bufsize,
+ const SshIpAddr ip)
+{
+ if (!ip || ip->type == SSH_IP_TYPE_NONE)
+ return ssh_encode_array(buf, bufsize,
+ SSH_ENCODE_CHAR(SSH_IP_TYPE_NONE),
+ SSH_FORMAT_END);
+ return ssh_encode_array(buf, bufsize,
+ SSH_ENCODE_CHAR(ip->type),
+ SSH_ENCODE_UINT32(ip->mask_len),
+ SSH_ENCODE_DATA(ip->addr_data,
+ SSH_IP_ADDR_LEN(ip)),
+#ifdef WITH_IPV6
+ SSH_ENCODE_UINT32(ip->scope_id.scope_id_union.ui32),
+#endif /* WITH_IPV6 */
+ SSH_FORMAT_END);
+}
+
+size_t ssh_encode_ipaddr_array_alloc(unsigned char **buf_return,
+ const SshIpAddr ip)
+{
+ size_t req, got;
+
+ if (ip->type == SSH_IP_TYPE_NONE)
+ req = 1;
+ else
+#ifdef WITH_IPV6
+ req = 1 + 8 + SSH_IP_ADDR_LEN(ip);
+#else /* WITH_IPV6 */
+ req = 1 + 4 + SSH_IP_ADDR_LEN(ip);
+#endif /* WITH_IPV6 */
+
+ if (buf_return == NULL)
+ return req;
+
+ if ((*buf_return = ssh_malloc(req)) == NULL)
+ return 0;
+
+ got = ssh_encode_ipaddr_array(*buf_return, req, ip);
+
+ if (got != req)
+ {
+ ssh_free(*buf_return);
+ *buf_return = NULL;
+ return 0;
+ }
+
+ return got;
+}
+
+int ssh_decode_ipaddr_array(const unsigned char *buf, size_t len,
+ void * ipaddr)
+{
+ size_t point, got;
+ SshUInt32 mask_len;
+#ifdef WITH_IPV6
+ SshUInt32 scope_id;
+#endif /* WITH_IPV6 */
+ unsigned int type;
+ SshIpAddr ip = (SshIpAddr)ipaddr;
+ point = 0;
+
+ if ((got = ssh_decode_array(buf + point, len - point,
+ SSH_DECODE_CHAR(&type),
+ SSH_FORMAT_END)) != 1)
+ return 0;
+
+ /* Make sure scope-id (that is not present at the kernel) is
+ zeroed */
+ memset(ip, 0, sizeof(*ip));
+
+ ip->type = (SshUInt8) type;
+
+ point += got;
+
+ if (ip->type == SSH_IP_TYPE_NONE)
+ return point;
+
+ if ((got = ssh_decode_array(buf + point, len - point,
+ SSH_DECODE_UINT32(&mask_len),
+ SSH_DECODE_DATA(ip->addr_data,
+ SSH_IP_ADDR_LEN(ip)),
+#ifdef WITH_IPV6
+ SSH_DECODE_UINT32(&scope_id),
+ SSH_FORMAT_END)) != ((2 * sizeof(SshUInt32))
+ + SSH_IP_ADDR_LEN(ip)))
+#else /* WITH_IPV6 */
+ SSH_FORMAT_END)) != (4 + SSH_IP_ADDR_LEN(ip)))
+#endif /* WITH_IPV6 */
+ return 0;
+
+ /* Sanity check */
+ if (mask_len > 255)
+ return 0;
+
+ ip->mask_len = (SshUInt8) mask_len;
+
+ point += got;
+
+#ifdef WITH_IPV6
+ ip->scope_id.scope_id_union.ui32 = scope_id;
+#endif /* WITH_IPV6 */
+
+ /* Sanity check */
+ if (!SSH_IP_IS4(ip) && !SSH_IP_IS6(ip))
+ return 0;
+
+ return point;
+}
diff --git a/drivers/interceptor/sshinetencode.h b/drivers/interceptor/sshinetencode.h
new file mode 100644
index 0000000..0c453ed
--- /dev/null
+++ b/drivers/interceptor/sshinetencode.h
@@ -0,0 +1,43 @@
+/* Netfilter Driver for IPSec VPN Client
+ *
+ * Copyright(c) 2012 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.
+ */
+
+/*
+ * sshinetencode.h
+ *
+ * Inet API: IP address encoding and decoding functions.
+ *
+ */
+
+#ifndef SSHINETENCODE_H
+#define SSHINETENCODE_H
+
+#include "sshinet.h"
+
+/* Decode IP-address from array. */
+int ssh_decode_ipaddr_array(const unsigned char *buf, size_t bufsize,
+ void *ip);
+
+/* Encode IP-address to array. Return 0 in case it does not fit to the buffer.
+ NOTE, this is NOT a SshEncodeDatum Encoder, as the return values are
+ different. */
+size_t ssh_encode_ipaddr_array(unsigned char *buf, size_t bufsize,
+ const SshIpAddr ip);
+size_t ssh_encode_ipaddr_array_alloc(unsigned char **buf_return,
+ const SshIpAddr ip);
+
+#ifdef WITH_IPV6
+/* type+mask+scopeid+content */
+#define SSH_MAX_IPADDR_ENCODED_LENGTH (1+4+4+16)
+#else /* WITH_IPV6 */
+/* type+mask+content */
+#define SSH_MAX_IPADDR_ENCODED_LENGTH (1+4+16)
+#endif /* WITH_IPV6 */
+
+#endif /* SSHINETENCODE_H */
diff --git a/drivers/interceptor/sshinetprint.c b/drivers/interceptor/sshinetprint.c
new file mode 100644
index 0000000..76bd877
--- /dev/null
+++ b/drivers/interceptor/sshinetprint.c
@@ -0,0 +1,136 @@
+/* Netfilter Driver for IPSec VPN Client
+ *
+ * Copyright(c) 2012 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.
+ */
+
+/*
+ * sshinetprint.c
+ *
+ * Implementation of inet API IP address printing functions.
+ *
+ */
+
+#include "sshincludes.h"
+#include "sshinet.h"
+
+/* Prints the IP address into the buffer in string format. If the buffer
+ is too short, the address is truncated. This returns `buf'. */
+
+void ssh_ipaddr_ipv4_print(const unsigned char *data,
+ unsigned char *buf, size_t buflen)
+{
+ snprintf(buf, buflen, "%d.%d.%d.%d", data[0], data[1], data[2], data[3]);
+}
+
+void ssh_ipaddr_ipv6_print(const unsigned char *data,
+ unsigned char *buf, size_t buflen,
+ SshUInt32 scope)
+{
+ int i, j;
+ unsigned char *cp;
+ int opt_start = 8;
+ int opt_len = 0, n, l;
+ SshUInt16 val;
+
+ /* Optimize the largest zero-block from the address. */
+ for (i = 0; i < 8; i++)
+ if (SSH_GET_16BIT(data + i * 2) == 0)
+ {
+ for (j = i + 1; j < 8; j++)
+ {
+ val = SSH_GET_16BIT(data + j * 2);
+ if (val != 0)
+ break;
+ }
+ if (j - i > opt_len)
+ {
+ opt_start = i;
+ opt_len = j - i;
+ }
+ i = j;
+ }
+
+ if (opt_len <= 1)
+ /* Disable optimization. */
+ opt_start = 8;
+
+ cp = buf;
+ n = buflen;
+
+ /* Format the result. */
+ for (i = 0; i < 8; i++)
+ {
+ if (i == opt_start)
+ {
+ if (i == 0)
+ {
+ *cp++ = ':';
+ n -= 1;
+ if (n <= 1)
+ break;
+ }
+
+ *cp++ = ':';
+ n -= 1;
+ if (n <= 1)
+ break;
+
+ i += opt_len - 1;
+ }
+ else
+ {
+ l = snprintf(cp, n, "%x",
+ (unsigned int) SSH_GET_16BIT(data + i * 2));
+ if (l == -1)
+ {
+ *cp = '\0';
+ return;
+ }
+
+ cp += l;
+ n -= l;
+ if (n <= 1)
+ break;
+
+ if (i + 1 < 8)
+ {
+ *cp = ':';
+ cp++;
+ n -= 1;
+ if (n <= 1)
+ break;
+ }
+ }
+ }
+
+ /* Put scope id there, if stored. */
+ if (scope != 0)
+ {
+ l = snprintf(cp, n, "%%%u", (unsigned int) scope);
+
+ if (l > 0)
+ cp += l;
+ }
+
+ *cp = '\0';
+}
+
+unsigned char *ssh_ipaddr_print(const SshIpAddr ip, unsigned char *buf,
+ size_t buflen)
+{
+ if (SSH_IP_IS4(ip))
+ ssh_ipaddr_ipv4_print(ip->addr_data, buf, buflen);
+#if defined(WITH_IPV6)
+ else if (SSH_IP_IS6(ip))
+ ssh_ipaddr_ipv6_print(ip->addr_data, buf, buflen, SSH_IP6_SCOPE_ID(ip));
+#endif /* WITH_IPV6 */
+ else if (buflen > 0)
+ buf[0] = '\0';
+
+ return buf;
+}
diff --git a/drivers/interceptor/usermodeforwarder.c b/drivers/interceptor/usermodeforwarder.c
new file mode 100644
index 0000000..0122302
--- /dev/null
+++ b/drivers/interceptor/usermodeforwarder.c
@@ -0,0 +1,1363 @@
+/* Netfilter Driver for IPSec VPN Client
+ *
+ * Copyright(c) 2012 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.
+ */
+
+/*
+ * usermodeforwarder.c
+ *
+ * Stub implementation of Engine API. The usermodeforwarder forwards packets
+ * and requests between the kernel space Interceptor and user space Engine
+ * components.
+ *
+ */
+#include "sshincludes.h"
+#include "interceptor.h"
+#include "engine.h"
+#include "sshencode.h"
+#include "kernel_mutex.h"
+#include "usermodeforwarder.h"
+#include "sshinetencode.h"
+#include "virtual_adapter.h"
+
+#define SSH_ENGINE_VERSION "User-Mode Forwarder 1.0"
+
+const char ssh_engine_version[] = SSH_ENGINE_VERSION;
+
+/* Suffix to add to the name of the device name used for communicating
+ with the kernel module in systems that have such a concept. This
+ is ignored on other systems. */
+const char ssh_device_suffix[] = "-usermode";
+
+/* Data structure for the user mode forwarder engine. */
+struct SshEngineRec
+{
+ /* Lock for the engine. */
+ SshKernelMutex lock;
+
+ /* Function and context for sending packets to the user mode code. */
+ SshEngineSendProc send;
+ void *machine_context;
+
+ /* Flag indicating that packets should be dropped if the user mode
+ code is not connected. Otherwise packets will be passed through in this
+ situation. */
+ Boolean drop_if_no_ipm;
+
+ /* Flag indicating whether the user mode connection is currently open. */
+ Boolean ipm_open;
+
+ /* Packet interceptor. */
+ SshInterceptor interceptor;
+
+ /* Saved interfaces message (to be sent when ipm opens). */
+ unsigned char *queued_interfaces_message;
+ size_t queued_interfaces_len;
+
+ /* List of registered control message handlers */
+ struct SshEngineControlHandlerRec * control_handlers;
+ size_t control_handlers_num;
+};
+
+/* Formats the message, and tries to send it to the policy manager. This
+ returns FALSE if sending the message fails (e.g., the queue is full).
+ Every argument list should start with SSH_FORMAT_UINT32, (SshUInt32) 0,
+ SSH_FORMAT_CHAR, type. The first integer will be set to the length
+ of the resulting packet. This function can be called concurrently. */
+Boolean ssh_engine_send(SshEngine engine, Boolean locked,
+ Boolean reliable, ...)
+{
+ va_list ap;
+ unsigned char *ucp;
+ size_t len;
+
+ if (!locked)
+ ssh_kernel_mutex_lock(engine->lock);
+
+ if (!engine->ipm_open)
+ {
+ if (!locked)
+ ssh_kernel_mutex_unlock(engine->lock);
+ return FALSE;
+ }
+ if (!locked)
+ ssh_kernel_mutex_unlock(engine->lock);
+
+ /* Construct the final packet to send to ipm. */
+ va_start(ap, reliable);
+ len = ssh_encode_array_alloc_va(&ucp, ap);
+ va_end(ap);
+ SSH_ASSERT(len >= 5); /* must have at least len+type */
+
+ /* Update the length of the packet. */
+ SSH_PUT_32BIT(ucp, len - 4);
+
+ /* Send and/or queue the packet to the ipm. This will free the buffer. */
+ return (*engine->send)(ucp, len, reliable, engine->machine_context);
+}
+
+/* Callback function called by the real interceptor whenever a packet
+ is received. This passes the packet to the user mode
+ interceptor. */
+
+void ssh_engine_packet_callback(SshInterceptorPacket pp, void *context)
+{
+ SshEngine engine = (SshEngine) context;
+#if (SSH_INTERCEPTOR_NUM_EXTENSION_SELECTORS > 0)
+ unsigned char extbuf[4 * SSH_INTERCEPTOR_NUM_EXTENSION_SELECTORS];
+ SshUInt32 i;
+#endif /* (SSH_INTERCEPTOR_NUM_EXTENSION_SELECTORS > 0) */
+ unsigned char *packetbuf, *internalbuf;
+ size_t packet_len, internal_len, mediahdr_len;
+
+ /* Check if the user mode connection is open. */
+ ssh_kernel_mutex_lock(engine->lock);
+ if (!engine->ipm_open)
+ {
+ /* The user-mode connection is not open. Either
+ drop the packet or pass it through. */
+ ssh_kernel_mutex_unlock(engine->lock);
+ if (engine->drop_if_no_ipm)
+ ssh_interceptor_packet_free(pp);
+ else
+ {
+ /* Determine media header length. */
+ if (pp->protocol == SSH_PROTOCOL_ETHERNET)
+ mediahdr_len = SSH_ETHERH_HDRLEN;
+ else
+ if (pp->protocol == SSH_PROTOCOL_FDDI ||
+ pp->protocol == SSH_PROTOCOL_TOKENRING)
+ mediahdr_len = 22;
+ else
+ mediahdr_len = 0;
+
+ /* Send it through. */
+ /* Set 'pp->ifnum_out' to the inbound interface 'pp->ifnum_in'. */
+ pp->ifnum_out = pp->ifnum_in;
+
+ ssh_interceptor_send(engine->interceptor, pp, mediahdr_len);
+ }
+ return;
+ }
+ ssh_kernel_mutex_unlock(engine->lock);
+
+ /* Format the extension selectors into a buffer. */
+#if (SSH_INTERCEPTOR_NUM_EXTENSION_SELECTORS > 0)
+ for (i = 0; i < SSH_INTERCEPTOR_NUM_EXTENSION_SELECTORS; i++)
+ {
+ SSH_PUT_32BIT(extbuf + 4 * i, pp->extension[i]);
+ }
+#endif /* (SSH_INTERCEPTOR_NUM_EXTENSION_SELECTORS > 0) */
+
+ /* Copy the packet into a linear buffer. This is not fast, but is easy. */
+ packet_len = ssh_interceptor_packet_len(pp);
+ if (!(packetbuf = ssh_malloc(packet_len)))
+ {
+ ssh_interceptor_packet_free(pp);
+ return;
+ }
+
+ ssh_interceptor_packet_copyout(pp, 0, packetbuf, packet_len);
+
+ if (!ssh_interceptor_packet_export_internal_data(pp, &internalbuf,
+ &internal_len))
+ {
+ ssh_free(packetbuf);
+ return;
+ }
+
+
+ /* Send a packet to the user mode code. */
+ ssh_engine_send(engine, FALSE, FALSE,
+ SSH_FORMAT_UINT32, (SshUInt32) 0,
+ SSH_FORMAT_CHAR,
+ (unsigned int) SSH_ENGINE_IPM_FORWARDER_PACKET,
+ SSH_FORMAT_UINT32, (SshUInt32) pp->flags,
+ SSH_FORMAT_UINT32, (SshUInt32) pp->ifnum_in,
+ SSH_FORMAT_UINT32, (SshUInt32) pp->ifnum_out,
+ SSH_FORMAT_UINT32, (SshUInt32) pp->protocol,
+ SSH_FORMAT_UINT32_STR, packetbuf, packet_len,
+ SSH_FORMAT_UINT32_STR, internalbuf, internal_len,
+#if (SSH_INTERCEPTOR_NUM_EXTENSION_SELECTORS > 0)
+ SSH_FORMAT_DATA, extbuf, sizeof(extbuf),
+#endif /* (SSH_INTERCEPTOR_NUM_EXTENSION_SELECTORS > 0) */
+ SSH_FORMAT_END);
+
+ /* Free the buffers. */
+ ssh_free(packetbuf);
+ ssh_free(internalbuf);
+ ssh_interceptor_packet_free(pp);
+}
+
+/* This function is called whenever the interface list changes. */
+void ssh_engine_interfaces_callback(SshUInt32 num_interfaces,
+ SshInterceptorInterface *ifs,
+ void *context)
+{
+ SshEngine engine = (SshEngine) context;
+ unsigned char * packet, * packet_new;
+ size_t len, packet_len;
+ unsigned char *ucp;
+ SshUInt32 i, k;
+
+ /* Prepare the packet to send. Loop over all interfaces and create data
+ for each. */
+ packet = NULL;
+ packet_len = 0;
+ for (i = 0; i < num_interfaces; i++)
+ {
+ /* Complete the data for the interface. */
+ if (ifs[i].to_adapter.media == SSH_INTERCEPTOR_MEDIA_NONEXISTENT)
+ len = ssh_encode_array_alloc(
+ &ucp,
+
+ SSH_FORMAT_UINT32,
+ (SshUInt32) SSH_INTERCEPTOR_MEDIA_NONEXISTENT,
+
+ SSH_FORMAT_UINT32, (SshUInt32) 0,
+ SSH_FORMAT_UINT32, (SshUInt32) 0,
+#ifdef WITH_IPV6
+ SSH_FORMAT_UINT32, (SshUInt32) 0,
+#endif /* WITH_IPV6 */
+
+ SSH_FORMAT_UINT32,
+ (SshUInt32) SSH_INTERCEPTOR_MEDIA_NONEXISTENT,
+
+ SSH_FORMAT_UINT32, (SshUInt32) 0,
+ SSH_FORMAT_UINT32, (SshUInt32) 0,
+#ifdef WITH_IPV6
+ SSH_FORMAT_UINT32, (SshUInt32) 0,
+#endif /* WITH_IPV6 */
+
+ SSH_FORMAT_UINT32_STR, "", (size_t)0L,
+ SSH_FORMAT_UINT32, (SshUInt32) ifs[i].ifnum,
+ SSH_FORMAT_UINT32, (SshUInt32) ifs[i].flags,
+ SSH_FORMAT_UINT32_STR, "", (size_t)0L,
+ SSH_FORMAT_UINT32, (SshUInt32) 0,
+ SSH_FORMAT_END);
+ else
+ len = ssh_encode_array_alloc(
+ &ucp,
+ SSH_FORMAT_UINT32, (SshUInt32) ifs[i].to_protocol.media,
+ SSH_FORMAT_UINT32, (SshUInt32) ifs[i].to_protocol.flags,
+ SSH_FORMAT_UINT32, (SshUInt32) ifs[i].to_protocol.mtu_ipv4,
+#ifdef WITH_IPV6
+ SSH_FORMAT_UINT32, (SshUInt32) ifs[i].to_protocol.mtu_ipv6,
+#endif /* WITH_IPV6 */
+ SSH_FORMAT_UINT32, (SshUInt32) ifs[i].to_adapter.media,
+ SSH_FORMAT_UINT32, (SshUInt32) ifs[i].to_adapter.flags,
+ SSH_FORMAT_UINT32, (SshUInt32) ifs[i].to_adapter.mtu_ipv4,
+#ifdef WITH_IPV6
+ SSH_FORMAT_UINT32, (SshUInt32) ifs[i].to_adapter.mtu_ipv6,
+#endif /* WITH_IPV6 */
+
+ SSH_FORMAT_UINT32_STR,
+ ifs[i].media_addr, ifs[i].media_addr_len,
+
+ SSH_FORMAT_UINT32, (SshUInt32) ifs[i].ifnum,
+ SSH_FORMAT_UINT32, (SshUInt32) ifs[i].flags,
+ SSH_FORMAT_UINT32_STR, ifs[i].name, strlen(ifs[i].name),
+ SSH_FORMAT_UINT32, (SshUInt32) ifs[i].num_addrs,
+ SSH_FORMAT_END);
+
+ if (!ucp)
+ {
+ ssh_free(packet);
+ return;
+ }
+
+ packet_new = ssh_realloc(packet, packet_len, packet_len + len);
+
+ if (!packet_new)
+ {
+ ssh_free(packet);
+ ssh_free(ucp);
+ return;
+ }
+
+ packet = packet_new;
+
+ memcpy(packet + packet_len, ucp, len);
+ packet_len += len;
+
+ ssh_free(ucp);
+
+ for (k = 0; k < ifs[i].num_addrs; k++)
+ {
+ unsigned char *addr;
+ size_t addr_size;
+
+ if (ifs[i].addrs[k].protocol == SSH_PROTOCOL_IP4 ||
+ ifs[i].addrs[k].protocol == SSH_PROTOCOL_IP6)
+ {
+ unsigned char *ip, *mask, *bcast;
+ size_t ip_size, mask_size, bcast_size;
+
+ ip_size =
+ ssh_encode_ipaddr_array_alloc(&ip,
+ &ifs[i].addrs[k].addr.ip.ip);
+
+ mask_size =
+ ssh_encode_ipaddr_array_alloc(&mask,
+ &ifs[i].addrs[k].addr.ip.mask);
+
+ bcast_size =
+ ssh_encode_ipaddr_array_alloc(&bcast,
+ &ifs[i].addrs[k].addr.ip.broadcast);
+
+ /* Out of memory */
+ if (!ip_size || !mask_size || !bcast_size)
+ {
+ failure:
+ ssh_free(ip);
+ ssh_free(mask);
+ ssh_free(bcast);
+ ssh_free(packet);
+ return;
+ }
+
+ addr_size = ssh_encode_array_alloc(&addr,
+ SSH_FORMAT_UINT32_STR,
+ ip, ip_size,
+ SSH_FORMAT_UINT32_STR,
+ mask, mask_size,
+ SSH_FORMAT_UINT32_STR,
+ bcast, bcast_size,
+ SSH_FORMAT_END);
+
+ if (!addr_size)
+ goto failure;
+
+ ssh_free(ip);
+ ssh_free(mask);
+ ssh_free(bcast);
+ }
+ else
+ {
+ SSH_DEBUG(SSH_D_ERROR,
+ ("ifs[i].addrs[%d].protocol == %d is not supported",
+ (int) k, ifs[i].addrs[k].protocol));
+
+ addr = ssh_strdup("");
+
+ if (!addr)
+ {
+ ssh_free(packet);
+ return;
+ }
+
+ addr_size = 0;
+ }
+
+ len = ssh_encode_array_alloc(&ucp,
+ SSH_FORMAT_UINT32,
+ ifs[i].addrs[k].protocol,
+ SSH_FORMAT_UINT32_STR, addr, addr_size,
+ SSH_FORMAT_END);
+
+ ssh_free(addr);
+
+ if (!ucp)
+ {
+ ssh_free(packet);
+ return;
+ }
+
+ packet_new = ssh_realloc(packet, packet_len, packet_len + len);
+
+ if (!packet_new)
+ {
+ ssh_free(packet);
+ ssh_free(ucp);
+ return;
+ }
+
+ packet = packet_new;
+ memcpy(packet + packet_len, ucp, len);
+ packet_len += len;
+
+ ssh_free(ucp);
+ }
+ }
+
+ /* Send the interfaces packet. */
+ len = ssh_encode_array_alloc(&ucp,
+ SSH_FORMAT_UINT32, (SshUInt32) 0,
+ SSH_FORMAT_CHAR,
+ (unsigned int) SSH_ENGINE_IPM_FORWARDER_INTERFACES,
+ SSH_FORMAT_UINT32, num_interfaces,
+ SSH_FORMAT_DATA, packet, packet_len,
+ SSH_FORMAT_END);
+
+ ssh_free(packet);
+
+ if (!ucp)
+ return;
+
+ /* Save the interfaces message so that we can send it again when the
+ ipm is next opened. */
+ ssh_kernel_mutex_lock(engine->lock);
+ if (engine->queued_interfaces_message)
+ ssh_free(engine->queued_interfaces_message);
+ engine->queued_interfaces_message = ucp;
+ engine->queued_interfaces_len = len;
+ ssh_kernel_mutex_unlock(engine->lock);
+
+ /* Send the message now (assuming the user mode connection is open). */
+ ssh_engine_send(engine, FALSE, TRUE, SSH_FORMAT_DATA, ucp, len,
+ SSH_FORMAT_END);
+
+ /* ucp is not freed here, since it is stored in queued_interfaces_message */
+}
+
+/* Function that is called whenever routing information changes. There
+ is no guarantee that this ever gets called. */
+void ssh_engine_route_change_callback(void *context)
+{
+ SshEngine engine = (SshEngine) context;
+
+ /* Send a simple notification. */
+ ssh_engine_send(engine, FALSE, FALSE,
+ SSH_FORMAT_UINT32, (SshUInt32) 0,
+ SSH_FORMAT_CHAR,
+ (unsigned int) SSH_ENGINE_IPM_FORWARDER_ROUTECHANGE,
+ SSH_FORMAT_END);
+}
+
+/* Creates the engine object. Among other things, this opens the
+ interceptor, initializes filters to default values, and arranges to send
+ messages to the policy manager using the send procedure. The send
+ procedure will not be called until from the bottom of the event loop.
+ The `machine_context' argument is passed to the interceptor and the
+ `send' callback, but is not used otherwise. This function can be
+ called concurrently for different machine contexts, but not otherwise.
+ The first packet and interface callbacks may arrive before this has
+ returned. */
+SshEngine ssh_engine_start(SshEngineSendProc send,
+ void *machine_context,
+ SshUInt32 flags)
+{
+ SshEngine engine;
+
+ engine = ssh_calloc(1, sizeof(*engine));
+ if (engine == NULL)
+ {
+ SSH_DEBUG(SSH_D_FAIL, ("failed to allocate engine object"));
+ goto fail;
+ }
+
+ /* Transform data pointers are already all zero (assumed to equal NULL). */
+ /* Fragment magic data initialized to zero. */
+ engine->lock = ssh_kernel_mutex_alloc();
+ engine->send = send;
+ engine->machine_context = machine_context;
+ engine->drop_if_no_ipm = (flags & SSH_ENGINE_DROP_IF_NO_IPM) != 0;
+ engine->ipm_open = FALSE;
+ engine->interceptor = NULL;
+
+ /* Open the interceptor. */
+ if (!ssh_interceptor_open(machine_context,
+ ssh_engine_packet_callback,
+ ssh_engine_interfaces_callback,
+ ssh_engine_route_change_callback,
+ (void *) engine,
+ &engine->interceptor))
+ {
+ SSH_DEBUG(1, ("opening the real interceptor failed"));
+ goto fail;
+ }
+
+ SSH_DEBUG(1, ("SSH forwarder engine started"));
+ return engine;
+
+ fail:
+ if (engine != NULL)
+ {
+ if (engine->interceptor)
+ ssh_interceptor_close(engine->interceptor);
+ ssh_kernel_mutex_free(engine->lock);
+ ssh_free(engine);
+ }
+ return NULL;
+}
+
+/* Stops the engine, closes the interceptor, and destroys the
+ engine object. This does not notify IPM interface of the close;
+ that must be done by the caller before calling this. This returns
+ TRUE if the engine was successfully stopped (and the object freed),
+ and FALSE if the engine cannot yet be freed because there are
+ threads inside the engine or uncancellable callbacks expected to
+ arrive. When this returns FALSE, the engine has started stopping,
+ and this should be called again after a while. This function can
+ be called concurrently with packet/interface callbacks or timeouts
+ for this engine, or any functions for other engines.*/
+
+Boolean ssh_engine_stop(SshEngine engine)
+{
+ /* Stop the interceptor. This means that no more new callbacks will
+ arrive. */
+ if (!ssh_interceptor_stop(engine->interceptor))
+ return FALSE;
+
+ /* Close the packet interceptor. */
+ ssh_interceptor_close(engine->interceptor);
+
+ /* Free the engine data structures. */
+ ssh_free(engine->control_handlers);
+ ssh_free(engine->queued_interfaces_message);
+ ssh_kernel_mutex_free(engine->lock);
+ memset(engine, 'F', sizeof(*engine));
+ ssh_free(engine);
+ return TRUE;
+}
+
+/* The machine-specific main program should call this when the policy
+ manager has opened the connection to the engine. This also
+ sends the version packet to the policy manager. This function can
+ be called concurrently with packet/interface callbacks or timeouts. */
+
+void ssh_engine_notify_ipm_open(SshEngine engine)
+{
+ SSH_DEBUG(1, ("User level module opened connection."));
+
+ /* Update state information about the policy manager connection. */
+ ssh_kernel_mutex_lock(engine->lock);
+ SSH_ASSERT(!engine->ipm_open);
+ engine->ipm_open = TRUE;
+ ssh_kernel_mutex_unlock(engine->lock);
+
+ /* Send a version packet to the policy manager. */
+ ssh_engine_send(engine, FALSE, TRUE,
+ SSH_FORMAT_UINT32, (SshUInt32) 0,
+ SSH_FORMAT_CHAR,
+ (unsigned int) SSH_ENGINE_IPM_FORWARDER_VERSION,
+ SSH_FORMAT_UINT32_STR,
+ SSH_ENGINE_VERSION, strlen(SSH_ENGINE_VERSION),
+ SSH_FORMAT_END);
+
+ /* If there is a saved interfaces message, send it now. */
+ if (engine->queued_interfaces_message)
+ {
+ ssh_engine_send(engine, FALSE, TRUE,
+ SSH_FORMAT_DATA,
+ engine->queued_interfaces_message,
+ engine->queued_interfaces_len,
+ SSH_FORMAT_END);
+
+ /* queued_interfaces_message is not freed, as it either will be
+ freed on _stop or next interfaces callback */
+ }
+}
+
+/* This function is called whenever the policy manager closes the
+ connection to the engine. This is also called when the engine is
+ stopped. This function can be called concurrently with
+ packet/interface callbacks or timeouts. */
+
+void ssh_engine_notify_ipm_close(SshEngine engine)
+{
+ SSH_DEBUG(1, ("User level module closed connection."));
+
+ /* Lock the engine. */
+ ssh_kernel_mutex_lock(engine->lock);
+
+ /* Mark the policy interface not open. */
+ engine->ipm_open = FALSE;
+
+ /* Unlock the engine. */
+ ssh_kernel_mutex_unlock(engine->lock);
+}
+
+/* Context structure for route lookups in the kernel. */
+
+typedef struct SshEngineFromIpmRouteRec
+{
+ SshEngine engine;
+ SshUInt32 id;
+} *SshEngineFromIpmRoute;
+
+/* Callback function to be called when a route lookup completes. This sends
+ a response to the user-mode interceptor. */
+
+void ssh_engine_route_completion(Boolean reachable,
+ SshIpAddr next_hop_gw,
+ SshInterceptorIfnum ifnum,
+ size_t mtu,
+ void *context)
+{
+ SshEngineFromIpmRoute rr = (SshEngineFromIpmRoute) context;
+ unsigned char *buf;
+ size_t len;
+ SshIpAddrStruct ip;
+#ifdef DEBUG_LIGHT
+ unsigned char next_hop_buf[SSH_IP_ADDR_STRING_SIZE];
+#endif /* DEBUG_LIGHT */
+
+ buf = NULL;
+ len = 0;
+
+ if (next_hop_gw)
+ {
+ len = ssh_encode_ipaddr_array_alloc(&buf, next_hop_gw);
+ }
+ else
+ {
+ SSH_IP_UNDEFINE(&ip);
+ len = ssh_encode_ipaddr_array_alloc(&buf, &ip);
+ }
+
+ if (reachable)
+ SSH_DEBUG(SSH_D_NICETOKNOW,
+ ("sending route reply id=%d reachable=%d ifnum=%d mtu=%d "
+ "next_hop=%s",
+ (int) rr->id, reachable, (int) ifnum, (int) mtu,
+ (next_hop_gw != NULL ?
+ ssh_ipaddr_print(next_hop_gw, next_hop_buf,
+ sizeof(next_hop_buf)) : NULL)));
+ else
+ SSH_DEBUG(SSH_D_NICETOKNOW,
+ ("sending route reply id=%d not reachable", (int) rr->id));
+
+ ssh_engine_send(rr->engine, FALSE, TRUE,
+ SSH_FORMAT_UINT32, (SshUInt32) 0,
+ SSH_FORMAT_CHAR,
+ (unsigned int) SSH_ENGINE_IPM_FORWARDER_ROUTEREPLY,
+ SSH_FORMAT_UINT32, (SshUInt32) rr->id,
+ SSH_FORMAT_UINT32, (SshUInt32) reachable,
+ SSH_FORMAT_UINT32, (SshUInt32) ifnum,
+ SSH_FORMAT_UINT32, (SshUInt32) mtu,
+ SSH_FORMAT_UINT32_STR, buf, len,
+ SSH_FORMAT_END);
+
+ ssh_free(buf);
+ ssh_free(rr);
+}
+
+/* Processes a route lookup message received from the user-mode
+ interceptor. */
+
+void ssh_engine_from_ipm_route(SshEngine engine,
+ const unsigned char *data, size_t len)
+{
+ SshEngineFromIpmRoute rr;
+ SshUInt32 id;
+ SshInterceptorRouteKeyStruct key;
+ unsigned char *dst_ptr, *src_ptr;
+ SshUInt32 ipproto, ifnum, selector;
+ size_t dst_len, src_len;
+#if (SSH_INTERCEPTOR_NUM_EXTENSION_SELECTORS > 0)
+ unsigned char extbuf[4 * SSH_INTERCEPTOR_NUM_EXTENSION_SELECTORS];
+ SshUInt32 i;
+#endif /* (SSH_INTERCEPTOR_NUM_EXTENSION_SELECTORS > 0) */
+#ifdef DEBUG_LIGHT
+ unsigned char dst_buf[SSH_IP_ADDR_STRING_SIZE];
+#endif /* DEBUG_LIGHT */
+
+ /* Decode the packet. */
+ if (ssh_decode_array(data, len,
+ SSH_FORMAT_UINT32, &id,
+ SSH_FORMAT_UINT32_STR_NOCOPY, &dst_ptr, &dst_len,
+ SSH_FORMAT_UINT32_STR_NOCOPY, &src_ptr, &src_len,
+ SSH_FORMAT_UINT32, &ipproto,
+ SSH_FORMAT_UINT32, &ifnum,
+ SSH_FORMAT_DATA, key.nh.raw, sizeof(key.nh.raw),
+ SSH_FORMAT_DATA, key.th.raw, sizeof(key.th.raw),
+#if (SSH_INTERCEPTOR_NUM_EXTENSION_SELECTORS > 0)
+ SSH_FORMAT_DATA, extbuf, sizeof(extbuf),
+#endif /* (SSH_INTERCEPTOR_NUM_EXTENSION_SELECTORS > 0) */
+ SSH_FORMAT_UINT32, &selector,
+ SSH_FORMAT_END) != len || !dst_ptr)
+ {
+ SSH_DEBUG_HEXDUMP(SSH_D_ERROR,
+ ("bad ipm route packet len=%d", (int) len),
+ data, len);
+ return;
+ }
+
+ /* Copy addresses to the structure. */
+ if (!ssh_decode_ipaddr_array(dst_ptr, dst_len, &key.dst))
+ {
+ SSH_DEBUG_HEXDUMP(SSH_D_ERROR,
+ ("bad ipaddr encoding"), dst_ptr, dst_len);
+ return;
+ }
+ if (!ssh_decode_ipaddr_array(src_ptr, src_len, &key.src))
+ {
+ SSH_DEBUG_HEXDUMP(SSH_D_ERROR,
+ ("bad ipaddr encoding"), src_ptr, src_len);
+ return;
+ }
+
+ /* Set ipproto, ifnum, and selector */
+ key.ipproto = ipproto;
+ key.ifnum = (SshInterceptorIfnum) ifnum;
+ key.selector = (SshUInt16) selector;
+
+ /* Copy extension selectors */
+#if (SSH_INTERCEPTOR_NUM_EXTENSION_SELECTORS > 0)
+ for (i = 0; i < SSH_INTERCEPTOR_NUM_EXTENSION_SELECTORS; i++)
+ {
+ key.extension[i] = SSH_GET_32BIT(extbuf + 4 * i);
+ }
+#endif /* (SSH_INTERCEPTOR_NUM_EXTENSION_SELECTORS > 0) */
+
+ SSH_DEBUG(SSH_D_NICETOKNOW,
+ ("route request to %s (id %d)",
+ ssh_ipaddr_print(&key.dst, dst_buf, sizeof(dst_buf)), (int) id));
+
+ /* Allocate and initialize a context structure. */
+ rr = ssh_calloc(1, sizeof(*rr));
+ rr->engine = engine;
+ rr->id = id;
+ ssh_interceptor_route(engine->interceptor, &key,
+ ssh_engine_route_completion, (void *)rr);
+}
+
+/* Processes a packet to send received from the user-mode interceptor. */
+
+void ssh_engine_from_ipm_packet(SshEngine engine,
+ const unsigned char *data, size_t len)
+{
+ SshInterceptorPacket pp;
+ SshUInt32 flags, ifnum_in, ifnum_out, protocol, media_header_len;
+#if (SSH_INTERCEPTOR_NUM_EXTENSION_SELECTORS > 0)
+ SshUInt32 extensions[SSH_INTERCEPTOR_NUM_EXTENSION_SELECTORS];
+ SshUInt32 i;
+#endif /* (SSH_INTERCEPTOR_NUM_EXTENSION_SELECTORS > 0) */
+ unsigned char *packet_ptr, *internal_ptr;
+ size_t packet_len, internal_len, bytes;
+
+ /* Decode the packet. */
+ bytes = ssh_decode_array(data, len,
+ SSH_FORMAT_UINT32, &flags,
+ SSH_FORMAT_UINT32, &ifnum_in,
+ SSH_FORMAT_UINT32, &ifnum_out,
+ SSH_FORMAT_UINT32, &protocol,
+ SSH_FORMAT_UINT32, &media_header_len,
+ SSH_FORMAT_UINT32_STR_NOCOPY,
+ &packet_ptr, &packet_len,
+ SSH_FORMAT_UINT32_STR_NOCOPY,
+ &internal_ptr, &internal_len,
+ SSH_FORMAT_END);
+ if (bytes == 0)
+ {
+ SSH_DEBUG_HEXDUMP(SSH_D_ERROR, ("bad ipm_packet fixed part"), data, len);
+ return;
+ }
+ data += bytes;
+ len -= bytes;
+#if (SSH_INTERCEPTOR_NUM_EXTENSION_SELECTORS > 0)
+ for (i = 0; i < SSH_INTERCEPTOR_NUM_EXTENSION_SELECTORS; i++)
+ {
+ bytes = ssh_decode_array(data, len,
+ SSH_FORMAT_UINT32, &extensions[i],
+ SSH_FORMAT_END);
+ if (bytes == 0)
+ {
+ SSH_DEBUG_HEXDUMP(SSH_D_ERROR,
+ ("bad extension selector in ipm_packet"),
+ data, len);
+ return;
+ }
+ data += bytes;
+ len -= bytes;
+ }
+#endif /* (SSH_INTERCEPTOR_NUM_EXTENSION_SELECTORS > 0) */
+ if (len != 0)
+ {
+ SSH_DEBUG_HEXDUMP(SSH_D_ERROR, ("garbage at end of ipm_packet"),
+ data, len);
+ return;
+ }
+
+ /* Assert that interface numbers fit into SshInterceptorIfnum. */
+ SSH_ASSERT(((SshUInt32)ifnum_in) <= ((SshUInt32)SSH_INTERCEPTOR_MAX_IFNUM));
+ SSH_ASSERT(((SshUInt32)ifnum_out) <= ((SshUInt32)SSH_INTERCEPTOR_MAX_IFNUM));
+
+ /* Allocate a packet object and copy data into it. */
+ flags &= SSH_PACKET_FROMADAPTER | SSH_PACKET_FROMPROTOCOL;
+ pp = ssh_interceptor_packet_alloc(engine->interceptor,
+ flags, protocol,
+ ifnum_in, ifnum_out,
+ packet_len);
+ if (pp == NULL)
+ {
+ SSH_DEBUG(SSH_D_ERROR, ("failed to allocate packet"));
+ return;
+ }
+ if (!ssh_interceptor_packet_copyin(pp, 0, packet_ptr, packet_len))
+ {
+ SSH_DEBUG(SSH_D_ERROR, ("copyin failed, dropping packet"));
+ return;
+ }
+ if (!ssh_interceptor_packet_import_internal_data(pp,
+ internal_ptr, internal_len))
+ {
+ SSH_DEBUG(SSH_D_ERROR, ("internal import failed, dropping packet"));
+ return;
+ }
+
+#if (SSH_INTERCEPTOR_NUM_EXTENSION_SELECTORS > 0)
+ for (i = 0; i < SSH_INTERCEPTOR_NUM_EXTENSION_SELECTORS; i++)
+ {
+ pp->extension[i] = extensions[i];
+ }
+#endif /* (SSH_INTERCEPTOR_NUM_EXTENSION_SELECTORS > 0) */
+
+ /* Send the packet out. */
+ ssh_interceptor_send(engine->interceptor, pp, media_header_len);
+}
+
+/* Process enable interception request */
+void ssh_engine_from_ipm_enable_interception(SshEngine engine,
+ const unsigned char *data,
+ size_t len)
+{
+ size_t bytes;
+ SshUInt32 enable;
+
+ bytes = ssh_decode_array(data, len,
+ SSH_FORMAT_UINT32, &enable,
+ SSH_FORMAT_END);
+ if (bytes == 0)
+ {
+ SSH_DEBUG_HEXDUMP(SSH_D_ERROR, ("bad ipm_enable_interception packet"),
+ data, len);
+ return;
+ }
+
+ SSH_DEBUG(SSH_D_LOWOK, ("%s packet interception",
+ (enable == 0 ? "Disabling" : "Enabling")));
+
+ if (enable == 0)
+ ssh_interceptor_enable_interception(engine->interceptor, FALSE);
+ else
+ ssh_interceptor_enable_interception(engine->interceptor, TRUE);
+}
+
+void ssh_engine_from_ipm_set_debug(SshEngine engine,
+ const unsigned char *data, size_t len)
+{
+ unsigned char *s;
+
+ if (ssh_decode_array(data, len,
+ SSH_FORMAT_UINT32_STR_NOCOPY, &s, NULL,
+ SSH_FORMAT_END) != len)
+ return;
+
+ SSH_DEBUG(SSH_D_NICETOKNOW, ("Setting debug level to \"%s\"", s));
+}
+
+
+void ssh_engine_from_ipm_internal_data_discarded(SshEngine engine,
+ const unsigned char *data,
+ size_t len)
+{
+ unsigned char *data_ptr;
+ size_t data_len, bytes;
+
+ /* Decode the packet. */
+ bytes = ssh_decode_array(data, len,
+ SSH_FORMAT_UINT32_STR_NOCOPY,
+ &data_ptr, &data_len,
+ SSH_FORMAT_END);
+ if (bytes == 0)
+ {
+ SSH_DEBUG_HEXDUMP(0, ("bad ipm_packet fixed part"), data, len);
+ return;
+ }
+ data += bytes;
+ len -= bytes;
+
+ if (len != 0)
+ {
+ SSH_DEBUG_HEXDUMP(0, ("garbage at end of ipm_packet"), data, len);
+ return;
+ }
+
+ ssh_interceptor_packet_discard_internal_data(data_ptr, data_len);
+}
+
+/***************************** Virtual adapter things ************************/
+typedef struct SshEngineIpmVirtualAdapterOpCtxRec
+{
+ SshEngine engine;
+ SshUInt32 operation_id;
+ Boolean dynamic;
+} *SshEngineIpmVirtualAdapterOpCtx, SshEngineIpmVirtualAdapterOpCtxStruct;
+
+void
+ssh_engine_ipm_virtual_adapter_packet_cb(SshInterceptor interceptor,
+ SshInterceptorPacket pp,
+ void *adapter_context)
+{
+ SshEngine engine = adapter_context;
+ unsigned char *packet, *internal;
+ size_t packet_len, internal_len;
+
+ /* Copy the packet into a linear buffer. */
+ packet_len = ssh_interceptor_packet_len(pp);
+ packet = ssh_malloc(packet_len);
+ if (packet == NULL)
+ {
+ ssh_interceptor_packet_free(pp);
+ return;
+ }
+
+#ifdef INTERCEPTOR_HAS_PACKET_INTERNAL_DATA_ROUTINES
+ if (!ssh_interceptor_packet_export_internal_data(pp,
+ &internal, &internal_len))
+ {
+ ssh_free(packet);
+ return;
+ }
+#endif /* INTERCEPTOR_HAS_PACKET_INTERNAL_DATA_ROUTINES */
+
+ ssh_interceptor_packet_copyout(pp, 0, packet, packet_len);
+
+ /* Send the packet to the user-mode engine. */
+ ssh_engine_send(engine, FALSE, FALSE,
+ SSH_FORMAT_UINT32, (SshUInt32) 0, /* reserved for length */
+
+ SSH_FORMAT_CHAR,
+ (unsigned int) SSH_ENGINE_IPM_FORWARDER_VIRTUAL_ADAPTER_PACKET_CB,
+
+ SSH_FORMAT_UINT32, (SshUInt32) pp->flags,
+ SSH_FORMAT_UINT32, (SshUInt32) pp->ifnum_in,
+ SSH_FORMAT_UINT32, (SshUInt32) pp->ifnum_out,
+ SSH_FORMAT_UINT32, (SshUInt32) pp->protocol,
+ SSH_FORMAT_UINT32_STR, packet, packet_len,
+ SSH_FORMAT_UINT32_STR, internal, internal_len,
+
+ SSH_FORMAT_END);
+
+ /* Free the temporary buffer. */
+ ssh_free(packet);
+
+ /* Free internal data representation */
+ ssh_free(internal);
+
+ /* Free the interceptor packet. */
+ ssh_interceptor_packet_free(pp);
+}
+
+void
+ssh_engine_ipm_virtual_adapter_status_cb(SshVirtualAdapterError error,
+ SshInterceptorIfnum adapter_ifnum,
+ const unsigned char *adapter_name,
+ SshVirtualAdapterState adapter_state,
+ void *adapter_context,
+ void *context)
+{
+ SshEngineIpmVirtualAdapterOpCtx ctx =
+ (SshEngineIpmVirtualAdapterOpCtx) context;
+ size_t adapter_name_len = 0;
+
+ if (adapter_name != NULL)
+ adapter_name_len = strlen(adapter_name);
+
+ ssh_engine_send(ctx->engine, FALSE, TRUE,
+ SSH_FORMAT_UINT32, (SshUInt32) 0,
+ SSH_FORMAT_CHAR, (unsigned int)
+ SSH_ENGINE_IPM_FORWARDER_VIRTUAL_ADAPTER_STATUS_CB,
+ SSH_FORMAT_UINT32, ctx->operation_id,
+ SSH_FORMAT_UINT32, error,
+ SSH_FORMAT_UINT32, adapter_ifnum,
+ SSH_FORMAT_UINT32_STR, adapter_name, adapter_name_len,
+ SSH_FORMAT_UINT32, adapter_state,
+ SSH_FORMAT_END);
+
+ /* Free the context if it is dynamically allocated and no more callbacks
+ are expected. */
+ if (error != SSH_VIRTUAL_ADAPTER_ERROR_OK_MORE && ctx->dynamic)
+ ssh_free(ctx);
+}
+
+void
+ssh_engine_from_ipm_virtual_adapter_send(SshEngine engine,
+ const unsigned char *data,
+ size_t len)
+{
+ SshUInt32 ifnum_in, ifnum_out;
+ SshUInt32 protocol;
+ const unsigned char *packet, *internal;
+ size_t packet_len, internal_len;
+ SshInterceptorPacket pp;
+
+ if (ssh_decode_array(data, len,
+ SSH_FORMAT_UINT32, &ifnum_in,
+ SSH_FORMAT_UINT32, &ifnum_out,
+ SSH_FORMAT_UINT32, &protocol,
+ SSH_FORMAT_UINT32_STR_NOCOPY, &packet, &packet_len,
+ SSH_FORMAT_UINT32_STR_NOCOPY, &internal, &internal_len,
+ SSH_FORMAT_END) != len)
+ {
+ SSH_DEBUG_HEXDUMP(SSH_D_ERROR,
+ ("Bad virtual adapter send request from PM"),
+ data, len);
+ return;
+ }
+
+ /* Allocate an interceptor packet. */
+ pp = ssh_interceptor_packet_alloc(engine->interceptor,
+ SSH_PACKET_FROMADAPTER,
+ protocol,
+ ifnum_in,
+ ifnum_out,
+ packet_len);
+ if (pp == NULL)
+ {
+ SSH_DEBUG(SSH_D_ERROR, ("failed to allocate packet"));
+ return;
+ }
+
+ if (!ssh_interceptor_packet_copyin(pp, 0, packet, packet_len))
+ {
+ SSH_DEBUG(SSH_D_ERROR, ("copyin failed, dropping packet"));
+ return;
+ }
+
+ if (!ssh_interceptor_packet_import_internal_data(pp, internal, internal_len))
+ {
+ SSH_DEBUG(SSH_D_ERROR, ("internal import failed, dropping packet"));
+ return;
+ }
+
+ ssh_virtual_adapter_send(engine->interceptor, pp);
+}
+
+void
+ssh_engine_from_ipm_virtual_adapter_attach(SshEngine engine,
+ const unsigned char *data,
+ size_t len)
+{
+ SshUInt32 operation_id;
+ SshUInt32 adapter_ifnum;
+ SshEngineIpmVirtualAdapterOpCtx ctx;
+
+ if (ssh_decode_array(data, len,
+ SSH_FORMAT_UINT32, &operation_id,
+ SSH_FORMAT_UINT32, &adapter_ifnum,
+ SSH_FORMAT_END) != len)
+ {
+ SSH_DEBUG_HEXDUMP(SSH_D_ERROR,
+ ("Bad virtual adapter attach request from PM"),
+ data, len);
+ return;
+ }
+
+ /* Attach virtual adapter. */
+ ctx = ssh_calloc(1, sizeof(*ctx));
+ if (ctx == NULL)
+ {
+ SshEngineIpmVirtualAdapterOpCtxStruct ctx_struct;
+
+ ctx_struct.engine = engine;
+ ctx_struct.operation_id = operation_id;
+ ctx_struct.dynamic = FALSE;
+
+ ssh_engine_ipm_virtual_adapter_status_cb(
+ SSH_VIRTUAL_ADAPTER_ERROR_OUT_OF_MEMORY,
+ (SshInterceptorIfnum) adapter_ifnum,
+ NULL,
+ SSH_VIRTUAL_ADAPTER_STATE_UNDEFINED,
+ NULL, &ctx_struct);
+ return;
+ }
+
+ ctx->engine = engine;
+ ctx->operation_id = operation_id;
+ ctx->dynamic = TRUE;
+
+ ssh_virtual_adapter_attach(engine->interceptor,
+ (SshInterceptorIfnum) adapter_ifnum,
+ ssh_engine_ipm_virtual_adapter_packet_cb,
+ NULL_FNPTR,
+ engine,
+ ssh_engine_ipm_virtual_adapter_status_cb, ctx);
+}
+
+
+void
+ssh_engine_from_ipm_virtual_adapter_detach(SshEngine engine,
+ const unsigned char *data,
+ size_t len)
+{
+ SshUInt32 operation_id;
+ SshUInt32 adapter_ifnum;
+ SshEngineIpmVirtualAdapterOpCtx ctx;
+
+ if (ssh_decode_array(data, len,
+ SSH_FORMAT_UINT32, &operation_id,
+ SSH_FORMAT_UINT32, &adapter_ifnum,
+ SSH_FORMAT_END) != len)
+ {
+ SSH_DEBUG_HEXDUMP(SSH_D_ERROR,
+ ("Bad virtual adapter detach request from PM"),
+ data, len);
+ return;
+ }
+
+ /* Detach virtual adapter. */
+ ctx = ssh_calloc(1, sizeof(*ctx));
+ if (ctx == NULL)
+ {
+ SshEngineIpmVirtualAdapterOpCtxStruct ctx_struct;
+
+ ctx_struct.engine = engine;
+ ctx_struct.operation_id = operation_id;
+ ctx_struct.dynamic = FALSE;
+
+ ssh_engine_ipm_virtual_adapter_status_cb(
+ SSH_VIRTUAL_ADAPTER_ERROR_OUT_OF_MEMORY,
+ (SshInterceptorIfnum) adapter_ifnum,
+ NULL,
+ SSH_VIRTUAL_ADAPTER_STATE_UNDEFINED,
+ NULL, &ctx_struct);
+ return;
+ }
+
+ ctx->engine = engine;
+ ctx->operation_id = operation_id;
+ ctx->dynamic = TRUE;
+
+ ssh_virtual_adapter_detach(engine->interceptor,
+ (SshInterceptorIfnum) adapter_ifnum,
+ ssh_engine_ipm_virtual_adapter_status_cb, ctx);
+}
+
+
+void
+ssh_engine_from_ipm_virtual_adapter_detach_all(SshEngine engine,
+ const unsigned char *data,
+ size_t len)
+{
+ ssh_virtual_adapter_detach_all(engine->interceptor);
+}
+
+
+void
+ssh_engine_from_ipm_virtual_adapter_configure(SshEngine engine,
+ const unsigned char *data,
+ size_t len)
+{
+ SshUInt32 operation_id;
+ SshUInt32 adapter_ifnum, adapter_state;
+ SshUInt32 num_addresses = 0;
+ SshIpAddrStruct addresses[16] = { { 0 } };
+ SshVirtualAdapterParamsStruct p;
+ const unsigned char *ip_ptr, *param_ptr;
+ size_t ip_len, param_len;
+ size_t decode_len;
+ SshUInt32 i;
+ SshEngineIpmVirtualAdapterOpCtxStruct ctx_struct;
+ SshEngineIpmVirtualAdapterOpCtx ctx;
+ SshVirtualAdapterError error = SSH_VIRTUAL_ADAPTER_ERROR_UNKNOWN_ERROR;
+
+ if (ssh_decode_array(data, len,
+ SSH_FORMAT_UINT32, &operation_id,
+ SSH_FORMAT_UINT32, &adapter_ifnum,
+ SSH_FORMAT_UINT32, &adapter_state,
+ SSH_FORMAT_UINT32, &num_addresses,
+ SSH_FORMAT_UINT32_STR_NOCOPY, &ip_ptr, &ip_len,
+ SSH_FORMAT_UINT32_STR_NOCOPY, &param_ptr, &param_len,
+ SSH_FORMAT_END) != len)
+ {
+ SSH_DEBUG_HEXDUMP(SSH_D_ERROR,
+ ("Bad virtual adapter configure request from PM"),
+ data, len);
+ return;
+ }
+
+ /* Decode IP addresses. */
+ if (ip_len)
+ {
+ for (i = 0; i < num_addresses && i < 16; i++)
+ {
+ decode_len = ssh_decode_ipaddr_array(ip_ptr, ip_len, &addresses[i]);
+ if (decode_len == 0)
+ {
+ error = SSH_VIRTUAL_ADAPTER_ERROR_ADDRESS_FAILURE;
+ goto error;
+ }
+ ip_ptr += decode_len;
+ ip_len -= decode_len;
+ }
+ }
+
+ /* A single undefined address "means clear all addresses". */
+ if (num_addresses == 1 && !SSH_IP_DEFINED(&addresses[0]))
+ num_addresses = 0;
+
+ /* Decode params. */
+ memset(&p, 0, sizeof(p));
+ if (param_len)
+ {
+ if (!ssh_virtual_adapter_param_decode(&p, param_ptr, param_len))
+ goto error;
+ }
+
+ /* Create context. */
+ ctx = ssh_calloc(1, sizeof(*ctx));
+ if (ctx == NULL)
+ {
+ error = SSH_VIRTUAL_ADAPTER_ERROR_OUT_OF_MEMORY;
+ goto error;
+ }
+
+ ctx->engine = engine;
+ ctx->operation_id = operation_id;
+ ctx->dynamic = TRUE;
+
+ /* This interceptor does not implement kernel level
+ virtual adapter configure. */
+ ssh_engine_ipm_virtual_adapter_status_cb(
+ SSH_VIRTUAL_ADAPTER_ERROR_NONEXISTENT,
+ (SshInterceptorIfnum) adapter_ifnum,
+ NULL,
+ SSH_VIRTUAL_ADAPTER_STATE_UNDEFINED,
+ NULL, ctx);
+ return;
+
+ /* Error handling. */
+ error:
+ ctx_struct.engine = engine;
+ ctx_struct.operation_id = operation_id;
+ ctx_struct.dynamic = FALSE;
+
+ ssh_engine_ipm_virtual_adapter_status_cb(error,
+ (SshInterceptorIfnum) adapter_ifnum,
+ NULL,
+ SSH_VIRTUAL_ADAPTER_STATE_UNDEFINED,
+ NULL, &ctx_struct);
+}
+
+
+void
+ssh_engine_from_ipm_virtual_adapter_get_status(SshEngine engine,
+ const unsigned char *data,
+ size_t len)
+{
+ SshUInt32 operation_id;
+ SshUInt32 adapter_ifnum;
+ SshEngineIpmVirtualAdapterOpCtx ctx;
+
+ if (ssh_decode_array(data, len,
+ SSH_FORMAT_UINT32, &operation_id,
+ SSH_FORMAT_UINT32, &adapter_ifnum,
+ SSH_FORMAT_END) != len)
+ {
+ SSH_DEBUG_HEXDUMP(SSH_D_ERROR,
+ ("Bad virtual adapter get status request from PM"),
+ data, len);
+ return;
+ }
+
+ /* Get virtual adapter status. */
+ ctx = ssh_calloc(1, sizeof(*ctx));
+ if (ctx == NULL)
+ {
+ SshEngineIpmVirtualAdapterOpCtxStruct ctx_struct;
+
+ ctx_struct.engine = engine;
+ ctx_struct.operation_id = operation_id;
+ ctx_struct.dynamic = FALSE;
+
+ ssh_engine_ipm_virtual_adapter_status_cb(
+ SSH_VIRTUAL_ADAPTER_ERROR_OUT_OF_MEMORY,
+ (SshInterceptorIfnum) adapter_ifnum,
+ NULL,
+ SSH_VIRTUAL_ADAPTER_STATE_UNDEFINED,
+ NULL, &ctx_struct);
+ return;
+ }
+
+ ctx->engine = engine;
+ ctx->operation_id = operation_id;
+ ctx->dynamic = TRUE;
+
+ ssh_virtual_adapter_get_status(engine->interceptor,
+ (SshInterceptorIfnum) adapter_ifnum,
+ ssh_engine_ipm_virtual_adapter_status_cb,
+ ctx);
+}
+
+
+/***************************** Packet Multiplexing ***************************/
+
+/* This function should be called by the machine-dependent main
+ program whenever a packet for this engine is received from
+ the policy manager. The data should not contain the 32-bit length
+ or the type (they have already been processed at this stage, to
+ check for possible machine-specific packets). The `data' argument
+ remains valid until this function returns; it should not be freed
+ by this function. This function can be called concurrently. */
+
+void ssh_engine_packet_from_ipm(SshEngine engine,
+ SshUInt32 type,
+ const unsigned char *data, size_t len)
+{
+ switch (type)
+ {
+ case SSH_ENGINE_IPM_FORWARDER_PACKET:
+ ssh_engine_from_ipm_packet(engine, data, len);
+ break;
+
+ case SSH_ENGINE_IPM_FORWARDER_INTERNAL_DATA_DISCARDED:
+ ssh_engine_from_ipm_internal_data_discarded(engine, data, len);
+ break;
+
+ case SSH_ENGINE_IPM_FORWARDER_ROUTEREQ:
+ ssh_engine_from_ipm_route(engine, data, len);
+ break;
+
+ case SSH_ENGINE_IPM_FORWARDER_ENABLE_INTERCEPTION:
+ ssh_engine_from_ipm_enable_interception(engine, data, len);
+ break;
+
+ case SSH_ENGINE_IPM_FORWARDER_VIRTUAL_ADAPTER_SEND:
+ ssh_engine_from_ipm_virtual_adapter_send(engine, data, len);
+ break;
+
+ case SSH_ENGINE_IPM_FORWARDER_VIRTUAL_ADAPTER_ATTACH:
+ ssh_engine_from_ipm_virtual_adapter_attach(engine, data, len);
+ break;
+
+ case SSH_ENGINE_IPM_FORWARDER_VIRTUAL_ADAPTER_DETACH:
+ ssh_engine_from_ipm_virtual_adapter_detach(engine, data, len);
+ break;
+
+ case SSH_ENGINE_IPM_FORWARDER_VIRTUAL_ADAPTER_DETACH_ALL:
+ ssh_engine_from_ipm_virtual_adapter_detach_all(engine, data, len);
+ break;
+
+ case SSH_ENGINE_IPM_FORWARDER_VIRTUAL_ADAPTER_CONFIGURE:
+ ssh_engine_from_ipm_virtual_adapter_configure(engine, data, len);
+ break;
+
+ case SSH_ENGINE_IPM_FORWARDER_VIRTUAL_ADAPTER_GET_STATUS:
+ ssh_engine_from_ipm_virtual_adapter_get_status(engine, data, len);
+ break;
+
+ case SSH_ENGINE_IPM_FORWARDER_SET_DEBUG:
+ ssh_engine_from_ipm_set_debug(engine, data, len);
+ break;
+
+ default:
+ printk(KERN_EMERG "Unknown packet type %u", (unsigned int)type);
+ SSH_DEBUG(2, ("ssh_engine_packet_from_ipm: unexpected packet %u in "
+ "kernel; probably wrong policy manager",
+ (unsigned int) type));
+
+ SSH_DEBUG_HEXDUMP(SSH_D_ERROR,
+ ("invalid packet from engine, type=%u",
+ (unsigned int) type),
+ data, len);
+ break;
+ }
+}
diff --git a/drivers/interceptor/usermodeforwarder.h b/drivers/interceptor/usermodeforwarder.h
new file mode 100644
index 0000000..5df0a71
--- /dev/null
+++ b/drivers/interceptor/usermodeforwarder.h
@@ -0,0 +1,90 @@
+/* Netfilter Driver for IPSec VPN Client
+ *
+ * Copyright(c) 2012 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.
+ */
+
+/*
+ * usermodeforwarder.h
+ *
+ * Message types for kernel to userspace messaging.
+ *
+ */
+
+#ifndef USERMODEFORWARDER_H
+#define USERMODEFORWARDER_H
+
+/* Allocate message numbers from the platform-specific portion. */
+
+/** Received packet or packet to be sent.
+ - uint32 flags
+ - uint32 ifnum
+ - uint32 protocol
+ - uint32 media_header_len (0 for packets going up)
+ - uint16 route_selector (0 in media level interceptor builds)
+ - string packet data
+ - uint32 extension
+ repeats SSH_INTERCEPTOR_NUM_EXTENSION_SELECTORS times. */
+#define SSH_ENGINE_IPM_FORWARDER_PACKET 201
+
+/** Routing request from user mode.
+ - string destination
+ - uint32 request id */
+#define SSH_ENGINE_IPM_FORWARDER_ROUTEREQ 202
+
+/** Routing reply from kernel.
+ - uint32 id
+ - uint32 reachable
+ - uint32 ifnum
+ - uint32 mtu
+ - string next_hop_gw */
+#define SSH_ENGINE_IPM_FORWARDER_ROUTEREPLY 203
+
+/** Interfaces information from kernel:
+ - uint32 num_interfaces.
+
+ Repeats:
+ - uint32 media
+ - uint32 mtu
+ - string name
+ - string media_addr
+ - uint32 num_addrs
+ - string addrs array as binary data */
+#define SSH_ENGINE_IPM_FORWARDER_INTERFACES 204
+
+/** Route change notification. No data. */
+#define SSH_ENGINE_IPM_FORWARDER_ROUTECHANGE 205
+
+/** Kernel version string. */
+#define SSH_ENGINE_IPM_FORWARDER_VERSION 206
+
+#define SSH_ENGINE_IPM_FORWARDER_SET_DEBUG 208
+
+/** Enable / disable packet interception:
+ - uint32 enable (1 to enable, 0 to disable) */
+#define SSH_ENGINE_IPM_FORWARDER_ENABLE_INTERCEPTION 215
+
+#define SSH_ENGINE_IPM_FORWARDER_INTERNAL_DATA_DISCARDED 216
+
+/** Send a packet to local stack. */
+#define SSH_ENGINE_IPM_FORWARDER_VIRTUAL_ADAPTER_SEND 220
+/** Attach a virtual adapter to Engine. */
+#define SSH_ENGINE_IPM_FORWARDER_VIRTUAL_ADAPTER_ATTACH 221
+/** Detach a virtual adapter from Engine. */
+#define SSH_ENGINE_IPM_FORWARDER_VIRTUAL_ADAPTER_DETACH 222
+/** Detach all virtual adapters from Engine. */
+#define SSH_ENGINE_IPM_FORWARDER_VIRTUAL_ADAPTER_DETACH_ALL 223
+/** Configure virtual adapter. */
+#define SSH_ENGINE_IPM_FORWARDER_VIRTUAL_ADAPTER_CONFIGURE 224
+/** Enumerate virtual adapters. */
+#define SSH_ENGINE_IPM_FORWARDER_VIRTUAL_ADAPTER_GET_STATUS 225
+/** Virtual adapter status callback. */
+#define SSH_ENGINE_IPM_FORWARDER_VIRTUAL_ADAPTER_STATUS_CB 226
+/** Virtual adapter packet callback. */
+#define SSH_ENGINE_IPM_FORWARDER_VIRTUAL_ADAPTER_PACKET_CB 227
+
+#endif /* USERMODEFORWARDER_H */
diff --git a/drivers/interceptor/virtual_adapter.h b/drivers/interceptor/virtual_adapter.h
new file mode 100644
index 0000000..628b04a
--- /dev/null
+++ b/drivers/interceptor/virtual_adapter.h
@@ -0,0 +1,296 @@
+/* Netfilter Driver for IPSec VPN Client
+ *
+ * Copyright(c) 2012 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.
+ */
+
+/*
+ *
+ * Kernel-mode virtual adapter interface.
+ *
+ * File: virtual_adapter.h
+ *
+ */
+
+
+#ifndef VIRTUAL_ADAPTER_H
+#define VIRTUAL_ADAPTER_H
+
+#include "interceptor.h"
+
+/* ***************************** Data Types **********************************/
+
+/** Error codes for virtual adapter operations. */
+typedef enum {
+ /** Success */
+ SSH_VIRTUAL_ADAPTER_ERROR_OK = 0,
+ /** Success, status callback will be called again */
+ SSH_VIRTUAL_ADAPTER_ERROR_OK_MORE = 1,
+ /** Nonexistent adapter */
+ SSH_VIRTUAL_ADAPTER_ERROR_NONEXISTENT = 2,
+ /** Address configuration error */
+ SSH_VIRTUAL_ADAPTER_ERROR_ADDRESS_FAILURE = 3,
+ /** Route configuration error */
+ SSH_VIRTUAL_ADAPTER_ERROR_ROUTE_FAILURE = 4,
+ /** Parameter configuration error */
+ SSH_VIRTUAL_ADAPTER_ERROR_PARAM_FAILURE = 5,
+ /** Memory allocation error */
+ SSH_VIRTUAL_ADAPTER_ERROR_OUT_OF_MEMORY = 6,
+ /** Undefined internal error */
+ SSH_VIRTUAL_ADAPTER_ERROR_UNKNOWN_ERROR = 255
+} SshVirtualAdapterError;
+
+/** Virtual adapter state. */
+typedef enum {
+ /** Invalid value */
+ SSH_VIRTUAL_ADAPTER_STATE_UNDEFINED = 0,
+ /** Up */
+ SSH_VIRTUAL_ADAPTER_STATE_UP = 1,
+ /** Down */
+ SSH_VIRTUAL_ADAPTER_STATE_DOWN = 2,
+ /** Keep existing state */
+ SSH_VIRTUAL_ADAPTER_STATE_KEEP_OLD = 3,
+} SshVirtualAdapterState;
+
+/** Optional parameters for a virtual adapter. */
+struct SshVirtualAdapterParamsRec
+{
+ /** Virtual adapter mtu. */
+ SshUInt32 mtu;
+
+ /** DNS server IP addresses. */
+ SshUInt32 dns_ip_count;
+ SshIpAddr dns_ip;
+
+ /** WINS server IP addresses. */
+ SshUInt32 wins_ip_count;
+ SshIpAddr wins_ip;
+
+ /** Windows domain name. */
+ char *win_domain;
+
+ /** Netbios node type. */
+ SshUInt8 netbios_node_type;
+};
+
+typedef struct SshVirtualAdapterParamsRec SshVirtualAdapterParamsStruct;
+typedef struct SshVirtualAdapterParamsRec *SshVirtualAdapterParams;
+
+/* ******************* Sending and Receiving Packets *************************/
+
+/** Send packet `pp' to the IP stack like it was received by the
+ virtual adapter indexed by `pp->ifnum_in'. The packet `pp' must be a
+ plain IP packet (IPv4 or IPv6) or it must be of the same media type
+ as the virtual adapter (most probably ethernet). This will free the
+ packet `pp'.
+
+ NOTE: LOCKS MUST NOT BE HELD DURING CALLS TO ssh_virtual_adapter_receive()!
+*/
+void ssh_virtual_adapter_send(SshInterceptor interceptor,
+ SshInterceptorPacket pp);
+
+/** Callback function of this type is called whenever a packet is
+ sent out via a virtual adapter. This function must eventually free the
+ packet by calling ssh_interceptor_packet_free.
+
+ This function is used for handling only those ARP, neighbor discovery,
+ and DHCP packets that are not handled by the generic engine packet
+ callback. This function must not be used for passing normal
+ IP packets.
+
+ Note that this function may be called asynchronously. */
+typedef void (*SshVirtualAdapterPacketCB)(SshInterceptor interceptor,
+ SshInterceptorPacket pp,
+ void *adapter_context);
+
+/* **************************** Generic Callbacks ****************************/
+
+/** A callback function of this type is called to notify about the
+ success of a virtual adapter operation.
+
+ - The argument `error' describes whether the operation was successful or
+ not. If `error' indicates success, the arguments `adapter_ifnum',
+ `adapter_name', and `state' contain information about the virtual adapter.
+
+ - The argument `adapter_ifnum' is an unique interface identifier for the
+ virtual adapter. You can use it configuring additional routes for
+ the adapter, and for configuring and destroying the adapter.
+
+ - The argument `adapter_name' contains the name of the created adapter.
+ The returned name is the same that identifies the interface in the
+ interceptor's interface callback.
+
+ - The argument `adapter_context' is the context attached to the virtual
+ adapter in the call to ssh_virtual_adapter_attach.
+
+ Arguments `adapter_ifnum', `adapter_name', `adapter_state', and
+ `adapter_context' are valid only for the duration of the callback. */
+typedef void (*SshVirtualAdapterStatusCB)(SshVirtualAdapterError error,
+ SshInterceptorIfnum adapter_ifnum,
+ const unsigned char *adapter_name,
+ SshVirtualAdapterState adapter_state,
+ void *adapter_context,
+ void *context);
+
+/* **************************** Attach and Detach ****************************/
+
+/** A callback function of this type is called to notify about detachment
+ of a virtual adapter from the engine. The callback is meant only as a
+ destructor of the virtual adapter context, and thus should be called
+ whenever there is no possibility of `packet_cb' being called again.
+ The argument `adapter_context' is the context attached to the virtual
+ adapter in the call to ssh_virtual_adapter_attach. */
+typedef void (*SshVirtualAdapterDetachCB)(void *adapter_context);
+
+/** Attaches the packet callback and context to a virtual adapter.
+
+ - The argument `packet_cb' specifies a callback function that is
+ called when a packet is received from the virtual adapter. The argument
+ `adapter_context' is the context for this callback.
+
+ - The optional argument `detach_cb' specifies an engine-level
+ destructor for `adapter_context'. It must be called when the
+ interceptor is done with virtual adapter, i.e. when the `packet_cb'
+ will not be called for this adapter again. Even in case of instant
+ failure, the `detach_cb' must be called.
+
+ - The operation completion callback `callback' must be called to notify
+ about success or failure of the attachment. In failure cases `callback'
+ must be called after `detach_cb'. The argument `context' is the context
+ data for this callback.
+
+ NOTE: LOCKS MUST NOT BE HELD DURING CALLS TO ssh_virtual_adapter_attach()!
+*/
+void ssh_virtual_adapter_attach(SshInterceptor interceptor,
+ SshInterceptorIfnum adapter_ifnum,
+ SshVirtualAdapterPacketCB packet_cb,
+ SshVirtualAdapterDetachCB detach_cb,
+ void *adapter_context,
+ SshVirtualAdapterStatusCB callback,
+ void *context);
+
+/** Detach the virtual adapter `adapter_ifnum'. The success of the
+ operation is notified by calling the callback function `callback'.
+
+ The detach operation will fail with the error code
+ SSH_VIRTUAL_ADAPTER_NONEXISTENT if the virtual adapter was never
+ attached. Detaching a virtual adapter must generate an interface callback
+ for the interceptor.
+
+ If a detach callback was specified in ssh_virtual_adapter_attach, then
+ this `detach_cb' must be called before calling the operation completion
+ callback `callback'.
+
+ NOTE: LOCKS MUST NOT BE HELD DURING CALLS TO ssh_virtual_adapter_detach()!
+*/
+void ssh_virtual_adapter_detach(SshInterceptor interceptor,
+ SshInterceptorIfnum adapter_ifnum,
+ SshVirtualAdapterStatusCB callback,
+ void *context);
+
+/** Detach all configured virtual adapters. This is called when the engine
+ is stopped during interceptor is unloading. This function must call
+ `detach_cb' for each detached virtual adapter that defines `detach_cb'.
+
+ NOTE: LOCKS MUST NOT BE HELD DURING CALLS TO
+ ssh_virtual_adapter_detach_all()! */
+void ssh_virtual_adapter_detach_all(SshInterceptor interceptor);
+
+/* *************************** Configuration *********************************/
+
+#ifdef INTERCEPTOR_IMPLEMENTS_VIRTUAL_ADAPTER_CONFIGURE
+
+/** Configures the virtual adapter `adapter_ifnum' with `state', `addresses',
+ and `params'. The argument `adapter_ifnum' must be the valid interface
+ index of a virtual adapter that has been attached to the engine during
+ pm connect.
+
+ The argument `adapter_state' specifies the state to configure for the
+ virtual adapter.
+
+ The arguments `num_addresses' and `addresses' specify the IP addresses
+ for the virtual adapter. The addresses must specify the netmask. If
+ `addresses' is NULL, the address configuration will not be changed.
+ Otherwise the existing addresses will be removed from the virtual adapter
+ and specified addresses will be added. To clear all addresses from the
+ virtual adapter, specify `addresses' as non-NULL and `num_addresses' as 0.
+
+ The argument `params' specifies optional parameters for the virtual
+ adapter. If `params' is non-NULL, then the existing params will be cleared
+ and the specified params will be set for the virtual adapter.
+
+ Any configured interface addresses must survive interface state changes.
+
+ If the define INTERCEPTOR_IMPLEMENTS_VIRTUAL_ADAPTER_CONFIGURE is not
+ defined then the interceptor does not support kernel level virtual
+ adapter configure.
+*/
+void ssh_virtual_adapter_configure(SshInterceptor interceptor,
+ SshInterceptorIfnum adapter_ifnum,
+ SshVirtualAdapterState adapter_state,
+ SshUInt32 num_addresses,
+ SshIpAddr addresses,
+ SshVirtualAdapterParams params,
+ SshVirtualAdapterStatusCB callback,
+ void *context);
+
+#endif /* INTERCEPTOR_IMPLEMENTS_VIRTUAL_ADAPTER_CONFIGURE */
+
+/* *************************** Virtual Adapter Status ************************/
+
+/** This function will call `callback' for virtual adapter `adapter_ifnum'.
+ If `adapter_ifnum' equals SSH_INTERCEPTOR_INVALID_IFNUM, then this
+ function calls `callback' once for each existing virtual adapter with
+ error code SSH_VIRTUAL_ADAPTER_ERROR_OK_MORE, and once with error code
+ SSH_VIRTUAL_ADAPTER_ERROR_NONEXISTENT after enumerating all virtual
+ adapters. */
+void ssh_virtual_adapter_get_status(SshInterceptor interceptor,
+ SshInterceptorIfnum adapter_ifnum,
+ SshVirtualAdapterStatusCB callback,
+ void *context);
+
+/* *************************** Utility functions *****************************/
+
+/** These generic utility functions that are implemented in files
+ virtual_adapter_misc.c and virtual_adapter_util.s, and they use the
+ virtual adapter API described above. */
+
+/** Initializes engine side virtual adapter contexts and attaches the existing
+ virtual adapters to engine. */
+SshVirtualAdapterError ssh_virtual_adapter_init(SshInterceptor interceptor);
+
+/** Unitializes engine side virtual adapter contexts and detaches virtual
+ adapters from the engine. */
+SshVirtualAdapterError ssh_virtual_adapter_uninit(SshInterceptor interceptor);
+
+/** Creates a pseudo Ethernet hardware address for the virtual adapter
+ `adapter_ifnum'. The address is formatted in the buffer `buffer' which
+ must have space for SSH_ETHERH_ADDRLEN bytes. */
+void
+ssh_virtual_adapter_interface_ether_address(SshInterceptorIfnum adapter_ifnum,
+ unsigned char *buffer);
+
+/** Create a pseudo Ethernet hardware address for the IP address `ip'.
+ The address `ip' can be an IPv4 or an IPv6 address. The address if
+ formatted in the buffer `buffer' which must have space for
+ SSH_ETHERH_ADDRLEN bytes. */
+void ssh_virtual_adapter_ip_ether_address(SshIpAddr ip, unsigned char *buffer);
+
+/** Encode virtual adapter params `params' to buffer `buffer'. This
+ function returns TRUE on success. The caller must ssh_free the allocated
+ memory in `data'. */
+Boolean
+ssh_virtual_adapter_param_encode(SshVirtualAdapterParams params,
+ unsigned char **data, size_t *len);
+
+/** Decode virtual adapter params from table `data' into `params'. This
+ function returns TRUE on success. */
+Boolean
+ssh_virtual_adapter_param_decode(SshVirtualAdapterParams params,
+ const unsigned char *data, size_t len);
+
+#endif /* not VIRTUAL_ADAPTER_H */
diff --git a/drivers/media/Makefile b/drivers/media/Makefile
index 01d6967..7f8a1cc 100644
--- a/drivers/media/Makefile
+++ b/drivers/media/Makefile
@@ -13,4 +13,4 @@ obj-y += common/ rc/ video/
obj-$(CONFIG_VIDEO_DEV) += radio/
obj-$(CONFIG_DVB_CORE) += dvb/
obj-$(CONFIG_TDMB) += tdmb/
-obj-$(CONFIG_ISDBT_FC8100) += isdbt/
+obj-$(CONFIG_ISDBT) += isdbt/
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
index 8298e84..aeedd90 100644
--- a/drivers/media/video/Kconfig
+++ b/drivers/media/video/Kconfig
@@ -442,7 +442,7 @@ endchoice
config VIDEO_S5K4E5
tristate "S5K4E5 supporting camera driver"
- depends on VIDEO_V4L2 && ((VIDEO_FIMC_MIPI || VIDEO_S5P_MIPI_CSIS) && VIDEO_EXYNOS_FIMC_IS) || VIDEO_EXYNOS5_FIMC_IS
+ depends on VIDEO_V4L2 && ((VIDEO_FIMC_MIPI || VIDEO_S5P_MIPI_CSIS) && VIDEO_EXYNOS_FIMC_IS) || VIDEO_EXYNOS5_FIMC_IS
---help---
This driver supports S5K4E5 sensor.
choice
@@ -478,7 +478,7 @@ endchoice
config VIDEO_S5K6A3
tristate "S5K6A3 supporting camera driver"
- depends on VIDEO_V4L2 && ((VIDEO_FIMC_MIPI || VIDEO_S5P_MIPI_CSIS) && VIDEO_EXYNOS_FIMC_IS) || VIDEO_EXYNOS5_FIMC_IS
+ depends on VIDEO_V4L2 && ((VIDEO_FIMC_MIPI || VIDEO_S5P_MIPI_CSIS) && VIDEO_EXYNOS_FIMC_IS) || VIDEO_EXYNOS5_FIMC_IS
---help---
This driver supports S5K6A3 sensor.
choice
@@ -530,6 +530,12 @@ config VIDEO_S5K5BAFX
---help---
This driver supports S5K5BAFX SoC camera module
+config VIDEO_S5K5BBGX
+ tristate "S5K5BBGX supporting camera driver"
+ depends on I2C && VIDEO_V4L2 && TARGET_LOCALE_NA && VIDEO_FIMC_MIPI
+ ---help---
+ This driver supports S5K5BBGX SoC camera module
+
config VIDEO_S5K5CCGX_COMMON
tristate "S5K5CCGX supporting camera driver"
depends on I2C && VIDEO_V4L2
diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile
index 805f5fd..1ad29ec 100644
--- a/drivers/media/video/Makefile
+++ b/drivers/media/video/Makefile
@@ -81,6 +81,7 @@ ifeq ($(CONFIG_MACH_PX),y)
obj-$(CONFIG_VIDEO_S5K5BAFX) += s5k5bafx-v2.o
else
obj-$(CONFIG_VIDEO_S5K5BAFX) += s5k5bafx.o
+obj-$(CONFIG_VIDEO_S5K5BBGX) += s5k5bbgx.o
endif
obj-$(CONFIG_VIDEO_S5K5CCGX_COMMON) += s5k5ccgx.o
obj-$(CONFIG_VIDEO_SR200PC20) += sr200pc20-p2.o
@@ -91,6 +92,9 @@ 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_SLP_S5C73M3) += slp_s5c73m3.o
+obj-$(CONFIG_VIDEO_SLP_S5K4ECGX) += slp_s5k4ecgx.o
+obj-$(CONFIG_VIDEO_SLP_DB8131M) += slp_db8131m.o
obj-$(CONFIG_SOC_CAMERA_IMX074) += imx074.o
obj-$(CONFIG_SOC_CAMERA_MT9M001) += mt9m001.o
diff --git a/drivers/media/video/isx012.c b/drivers/media/video/isx012.c
index ff2cbb0..8223d58 100644
--- a/drivers/media/video/isx012.c
+++ b/drivers/media/video/isx012.c
@@ -12,7 +12,7 @@
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
- * - change date: 2012.04.25
+ * - change date: 2012.06.28
*/
#include "isx012.h"
#include <linux/gpio.h>
@@ -23,9 +23,15 @@
#define isx012_writeb(sd, addr, data) isx012_i2c_write(sd, addr, data, 1)
#define isx012_writew(sd, addr, data) isx012_i2c_write(sd, addr, data, 2)
#define isx012_writel(sd, addr, data) isx012_i2c_write(sd, addr, data, 4)
+#define isx012_wait_ae_stable_af(sd) isx012_wait_ae_stable(sd, true, false)
+#define isx012_wait_ae_stable_preview(sd) isx012_wait_ae_stable(sd, false, true)
+#define isx012_wait_ae_stable_cap(sd) isx012_wait_ae_stable(sd, false, false)
+
+static int dbg_level;
static const struct isx012_fps isx012_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 },
@@ -48,6 +54,7 @@ static const struct isx012_framesize isx012_preview_frmsizes[] = {
static const struct isx012_framesize isx012_capture_frmsizes[] = {
{ CAPTURE_SZ_VGA, 640, 480 },
+ { CAPTURE_SZ_960_720, 960, 720 },
{ CAPTURE_SZ_W1MP, 1536, 864 },
{ CAPTURE_SZ_2MP, 1600, 1200 },
{ CAPTURE_SZ_W2MP, 2048, 1152 },
@@ -112,6 +119,9 @@ static const struct isx012_regs reg_datas = {
ISX012_REGSET(IMAGE_EFFECT_SEPIA, isx012_Effect_Sepia),
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),
},
.white_balance = {
ISX012_REGSET(WHITE_BALANCE_AUTO, isx012_WB_Auto),
@@ -162,14 +172,13 @@ static const struct isx012_regs reg_datas = {
ISX012_REGSET(SHARPNESS_PLUS_1, isx012_Sharpness_Plus_1),
ISX012_REGSET(SHARPNESS_PLUS_2, isx012_Sharpness_Plus_2),
},
-
.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),
},
-
.preview_size = {
ISX012_REGSET(PREVIEW_SZ_320x240, isx012_320_Preview),
ISX012_REGSET(PREVIEW_SZ_VGA, isx012_640_Preview),
@@ -179,21 +188,10 @@ static const struct isx012_regs reg_datas = {
},
.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),
},
-#if 0 /* DSLIM: Should be implemented */
- .preview_return = ISX012_REGSET_TABLE(s5k5ccgx_preview_return),
-
- .ae_lock_on =
- ISX012_REGSET_TABLE(s5k5ccgx_ae_lock),
- .ae_lock_off =
- ISX012_REGSET_TABLE(s5k5ccgx_ae_unlock),
- .awb_lock_on =
- ISX012_REGSET_TABLE(s5k5ccgx_awb_lock),
- .awb_lock_off =
- ISX012_REGSET_TABLE(s5k5ccgx_awb_unlock),
-#endif
/* AF */
.af_window_reset = ISX012_REGSET_TABLE(ISX012_AF_Window_Reset),
@@ -211,11 +209,11 @@ static const struct isx012_regs reg_datas = {
.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),
.init_reg = ISX012_REGSET_TABLE(ISX012_Init_Reg),
-#if 0 /* DSLIM: Should be implemented */
- .get_esd_status = ISX012_REGSET_TABLE(s5k5ccgx_get_esd_reg),
-#endif
+
/* Camera mode */
.preview_mode = ISX012_REGSET_TABLE(ISX012_Preview_Mode),
.capture_mode = ISX012_REGSET_TABLE(ISX012_Capture_Mode),
@@ -252,13 +250,16 @@ 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 <= 5)
+ if (msecs <= 7)
delta_halfrange = 100;
else
- delta_halfrange = 500;
+ delta_halfrange = 300;
if (msecs <= 20)
usleep_range((msecs * 1000 - delta_halfrange),
@@ -358,7 +359,15 @@ static int isx012_define_table(void)
printk(KERN_DEBUG "isx012_define_table start!\n");
start = strstr(isx012_regs_table, "aeoffset_table");
+ if (!start) {
+ cam_err("%s: can not find %s", __func__, "aeoffset_table");
+ return -ENOENT;
+ }
end = strstr(start, "};");
+ if (!end) {
+ cam_err("%s: can not find %s end", __func__, "aeoffset_table");
+ return -ENOENT;
+ }
/* Find table */
index_2 = 0;
@@ -440,7 +449,15 @@ static int isx012_define_read(char *name, int len_size)
//printk(KERN_DEBUG "isx012_define_read start!\n");
start = strstr(isx012_regs_table, name);
+ if (!start) {
+ cam_err("%s: can not find %s", __func__, name);
+ return -ENOENT;
+ }
end = strstr(start, "tuning");
+ if (!end) {
+ cam_err("%s: can not find %s", __func__, "tuning");
+ return -ENOENT;
+ }
reg = strstr(start," ");
@@ -690,7 +707,7 @@ static int isx012_i2c_read(struct v4l2_subdev *sd,
struct i2c_client *client = v4l2_get_subdevdata(sd);
u8 buf[16] = {0,};
struct i2c_msg msg[2];
- int err, retry = 3;
+ int err, retry = 5;
if (unlikely(!client->adapter)) {
@@ -724,7 +741,7 @@ static int isx012_i2c_read(struct v4l2_subdev *sd,
msleep_debug(POLL_TIME_MS, false);
} while (retry-- > 0);
- CHECK_ERR_COND_MSG(err != 2, -EIO, "I2C does not working\n");
+ CHECK_ERR_COND_MSG(err != 2, -EIO, "I2C does not work\n");
#ifdef CONFIG_CAM_I2C_LITTLE_ENDIAN
if (len == 1)
@@ -819,7 +836,7 @@ static int isx012_i2c_write(struct v4l2_subdev *sd,
msleep_debug(POLL_TIME_MS, false);
} while (retry_count-- > 0);
- CHECK_ERR_COND_MSG(err != 1, -EIO, "I2C does not working\n");
+ CHECK_ERR_COND_MSG(err != 1, -EIO, "I2C does not work\n");
return 0;
}
@@ -975,8 +992,7 @@ static int isx012_is_om_changed(struct v4l2_subdev *sd)
for (cnt1 = 0; cnt1 < ISX012_CNT_OM_CHECK; cnt1++) {
err = isx012_readb(sd, REG_INTSTS, &val);
- if (unlikely(err))
- cam_err("om changed: error, readb cnt=%d\n", cnt1);
+ CHECK_ERR_MSG(err, "om changed: error, readb cnt=%d\n", cnt1);
if ((val & REG_INTBIT_OM) == REG_INTBIT_OM) {
status &= ~0x01;
@@ -988,8 +1004,7 @@ static int isx012_is_om_changed(struct v4l2_subdev *sd)
for (cnt2 = 0; cnt2 < ISX012_CNT_OM_CHECK; cnt2++) {
err = isx012_writeb(sd, REG_INTCLR, REG_INTBIT_OM);
err |= isx012_readb(sd, REG_INTSTS, &val);
- if (unlikely(err))
- cam_err("om changed: error, rw cnt=%d\n", cnt2);
+ CHECK_ERR_MSG(err, "om changed: clear error, rw\n");
if ((val & REG_INTBIT_OM) == 0) {
status &= ~0x02;
@@ -998,13 +1013,13 @@ static int isx012_is_om_changed(struct v4l2_subdev *sd)
msleep_debug(5, false);
}
- cam_dbg("om changed: sucess. int cnt=%d, clr cnt=%d\n", cnt1, cnt2);
-
if (unlikely(status)) {
cam_err("om changed: error, fail 0x%X\n", status);
return -EAGAIN;
}
+ cam_dbg("om changed: int cnt=%d, clr cnt=%d\n", cnt1, cnt2);
+
return 0;
}
@@ -1032,8 +1047,9 @@ static int isx012_is_cm_changed(struct v4l2_subdev *sd)
for (cnt2 = 0; cnt2 < ISX012_CNT_CM_CHECK; cnt2++) {
err = isx012_writeb(sd, REG_INTCLR, REG_INTBIT_CM);
- CHECK_ERR_MSG(err, "cm changed: error, writeb\n");
- isx012_readb(sd, REG_INTSTS, &val);
+ err |= isx012_readb(sd, REG_INTSTS, &val);
+ CHECK_ERR_MSG(err, "cm changed: clear error, rw\n");
+
if ((val & REG_INTBIT_CM) == 0) {
status &= ~0x02;
break;
@@ -1042,24 +1058,27 @@ static int isx012_is_cm_changed(struct v4l2_subdev *sd)
msleep_debug(5, false);
}
- cam_dbg("cm changed: int cnt=%d, clr cnt=%d\n", cnt1, cnt2);
-
if (unlikely(status)) {
cam_err("cm changed: error, fail 0x%X\n", status);
return -EAGAIN;
}
+ cam_dbg("cm changed: int cnt=%d, clr cnt=%d\n", cnt1, cnt2);
+
return 0;
}
static inline int isx012_transit_preview_mode(struct v4l2_subdev *sd)
{
struct isx012_state *state = to_state(sd);
- int err = -EIO;
- err = isx012_set_from_table(sd, "preview_mode",
+ isx012_restore_sensor_flash(sd);
+
+ if (state->exposure.ae_lock || state->wb.awb_lock)
+ cam_info("Restore user ae(awb)-lock...\n");
+
+ return isx012_set_from_table(sd, "preview_mode",
&state->regs->preview_mode, 1, 0);
- return err;
}
/**
@@ -1078,11 +1097,11 @@ static inline int isx012_transit_half_mode(struct v4l2_subdev *sd)
if (state->scene_mode == SCENE_MODE_NIGHTSHOT &&
state->light_level >= LUX_LEVEL_LOW) {
cam_info("half_mode: night lowlux\n");
- state->lowlux_night = 1;
+ state->capture.lowlux_night = 1;
err = isx012_set_from_table(sd, "night_halfrelease_mode",
&state->regs->halfrelease_mode_night, 1, 0);
} else {
- state->lowlux_night = 0;
+ state->capture.lowlux_night = 0;
err = isx012_set_from_table(sd, "halfrelease",
&state->regs->halfrelease_mode, 1, 0);
}
@@ -1096,11 +1115,8 @@ static inline int isx012_transit_capture_mode(struct v4l2_subdev *sd)
struct isx012_state *state = to_state(sd);
int err = -EIO;
- if (state->lowlux_night) {
+ if (state->capture.lowlux_night) {
cam_info("capture_mode: night lowlux\n");
-#if !defined(CONFIG_NEW_STREAM_DELAY)
- state->lowlux_night = 0;
-#endif
err = isx012_set_from_table(sd, "capture_mode_night",
&state->regs->capture_mode_night, 1, 0);
} else
@@ -1260,7 +1276,7 @@ static void isx012_frame_checker(struct work_struct *work)
if (((u8)val & ISX012_INTSRC_VINT) == ISX012_INTSRC_VINT) {
++int_cnt;
- cam_info("frame INT %d (cnt=%d)\n", int_cnt, cnt);
+ cam_info("frame_INT %d (cnt=%d)\n", int_cnt, cnt);
if (int_cnt >= 2) {
state->frame_check = false;
return;
@@ -1279,7 +1295,7 @@ static void isx012_frame_checker(struct work_struct *work)
return;
}
- msleep_debug(10, false);
+ msleep_debug(3, false);
}
cam_err("frame INT Not occured!\n");
@@ -1330,7 +1346,7 @@ static void isx012_stop_frame_checker(struct v4l2_subdev *sd)
/**
* isx012_is_hwflash_on - check whether flash device is on
*
- * Refer to state->flash_on to check whether flash is in use in driver.
+ * Refer to state->flash.on to check whether flash is in use in driver.
*/
static inline int isx012_is_hwflash_on(struct v4l2_subdev *sd)
{
@@ -1352,7 +1368,7 @@ static int isx012_flash_en(struct v4l2_subdev *sd, s32 mode, s32 onoff)
{
struct isx012_state *state = to_state(sd);
- if (unlikely(state->ignore_flash)) {
+ if (unlikely(state->flash.ignore_flash)) {
cam_warn("WARNING, we ignore flash command.\n");
return 0;
}
@@ -1368,7 +1384,7 @@ static int isx012_flash_en(struct v4l2_subdev *sd, s32 mode, s32 onoff)
* isx012_flash_torch - turn flash on/off as torch for preflash, recording
* @onoff: ISX012_FLASH_ON or ISX012_FLASH_OFF
*
- * This func set state->flash_on properly.
+ * This func set state->flash.on properly.
*/
static inline int isx012_flash_torch(struct v4l2_subdev *sd, s32 onoff)
{
@@ -1376,7 +1392,7 @@ static inline int isx012_flash_torch(struct v4l2_subdev *sd, s32 onoff)
int err = 0;
err = isx012_flash_en(sd, ISX012_FLASH_MODE_MOVIE, onoff);
- state->flash_on = (onoff == ISX012_FLASH_ON) ? 1 : 0;
+ state->flash.on = (onoff == ISX012_FLASH_ON) ? 1 : 0;
return err;
}
@@ -1393,9 +1409,7 @@ static inline int isx012_flash_oneshot(struct v4l2_subdev *sd, s32 onoff)
int err = 0;
err = isx012_flash_en(sd, ISX012_FLASH_MODE_NORMAL, onoff);
-
- /* The flash_on here is only used for EXIF */
- state->flash_on = (onoff == ISX012_FLASH_ON) ? 1 : 0;
+ state->flash.on = (onoff == ISX012_FLASH_ON) ? 1 : 0;
return err;
}
@@ -1441,7 +1455,8 @@ static void isx012_set_framesize(struct v4l2_subdev *sd,
cam_dbg("%s: Requested Res %dx%d\n", __func__,
width, height);
- found_frmsize = (preview ? &state->preview : &state->capture);
+ found_frmsize = preview ?
+ &state->preview.frmsize : &state->capture.frmsize;
for (i = 0; i < num_frmsize; i++) {
if ((frmsizes[i].width == width) &&
@@ -1538,9 +1553,19 @@ static int isx012_set_exposure(struct v4l2_subdev *sd, s32 val)
static inline u32 isx012_get_light_level(struct v4l2_subdev *sd,
u32 *light_level)
{
- isx012_readb(sd, REG_USER_GAINLEVEL_NOW, light_level);
+ struct isx012_state *state = to_state(sd);
+ u32 val_lsb = 0, val_msb = 0;
+
+ if (state->iso == ISO_AUTO)
+ isx012_readb(sd, REG_USER_GAINLEVEL_NOW, light_level);
+ else {
+ isx012_readw(sd, REG_SHT_TIME_OUT_L, &val_lsb);
+ isx012_readw(sd, REG_SHT_TIME_OUT_H, &val_msb);
+
+ *light_level = (val_msb << 16) | (val_lsb & 0xFFFF);
+ }
- cam_trace("X, light level = 0x%X", *light_level);
+ cam_trace("X, iso = %d, light level = 0x%X", state->iso, *light_level);
return 0;
}
@@ -1549,19 +1574,23 @@ static inline u32 isx012_get_light_level(struct v4l2_subdev *sd,
static int isx012_set_capture_size(struct v4l2_subdev *sd)
{
struct isx012_state *state = to_state(sd);
+ u32 width, height;
- if (unlikely(!state->capture)) {
+ if (unlikely(!state->capture.frmsize)) {
cam_warn("warning, capture resolution not set\n");
- state->capture = isx012_get_framesize(isx012_capture_frmsizes,
+ state->capture.frmsize = isx012_get_framesize(
+ isx012_capture_frmsizes,
ARRAY_SIZE(isx012_capture_frmsizes),
- CAPTURE_SZ_3MP);
+ CAPTURE_SZ_5MP);
}
- cam_dbg("set capture size(%dx%d)\n",
- state->capture->width, state->capture->height);
+ width = state->capture.frmsize->width;
+ height = state->capture.frmsize->height;
+
+ cam_dbg("set capture size(%dx%d)\n", width, height);
- isx012_writew(sd, REG_HSIZE_CAP, state->capture->width);
- isx012_writew(sd, REG_VSIZE_CAP, state->capture->height);
+ isx012_writew(sd, REG_HSIZE_CAP, width);
+ isx012_writew(sd, REG_VSIZE_CAP, height);
return 0;
}
@@ -1571,7 +1600,7 @@ static int isx012_set_sensor_mode(struct v4l2_subdev *sd, s32 val)
{
struct isx012_state *state = to_state(sd);
- cam_trace("mode=%d\n", val); /*DSLIM*/
+ cam_trace("mode=%d\n", val);
switch (val) {
case SENSOR_MOVIE:
@@ -1640,6 +1669,7 @@ static int isx012_set_ae_lock(struct v4l2_subdev *sd, s32 lock, bool force)
isx012_readb(sd, REG_CPUEXT, &val);
val |= REG_CPUEXT_AE_HOLD;
isx012_writeb(sd, REG_CPUEXT, val);
+
state->exposure.ae_lock = 1;
cam_info("AE lock by user\n");
break;
@@ -1651,8 +1681,9 @@ static int isx012_set_ae_lock(struct v4l2_subdev *sd, s32 lock, bool force)
isx012_readb(sd, REG_CPUEXT, &val);
val &= ~REG_CPUEXT_AE_HOLD;
isx012_writeb(sd, REG_CPUEXT, val);
+
state->exposure.ae_lock = 0;
- cam_info("AE unlock by user\n");
+ cam_info("AE unlock\n");
break;
default:
@@ -1675,6 +1706,7 @@ static int isx012_set_awb_lock(struct v4l2_subdev *sd, s32 lock, bool force)
isx012_readb(sd, REG_CPUEXT, &val);
val |= REG_CPUEXT_AWB_HOLD;
isx012_writeb(sd, REG_CPUEXT, val);
+
state->wb.awb_lock = 1;
cam_info("AWB lock by user\n");
break;
@@ -1686,8 +1718,9 @@ static int isx012_set_awb_lock(struct v4l2_subdev *sd, s32 lock, bool force)
isx012_readb(sd, REG_CPUEXT, &val);
val &= ~REG_CPUEXT_AWB_HOLD;
isx012_writeb(sd, REG_CPUEXT, val);
+
state->wb.awb_lock = 0;
- cam_info("AWB unlock by user\n");
+ cam_info("AWB unlock\n");
break;
default:
@@ -1776,8 +1809,8 @@ static int isx012_pre_sensor_flash(struct v4l2_subdev *sd)
/* read preview AE scale */
isx012_readw(sd, REG_USER_AESCL_AUTO,
- &state->exposure.ae_offset.ae_auto);
- isx012_readw(sd, REG_ERRSCL_AUTO, &state->exposure.ae_offset.ersc_auto);
+ &state->flash.ae_offset.ae_auto);
+ isx012_readw(sd, REG_ERRSCL_AUTO, &state->flash.ae_offset.ersc_auto);
if (state->wb.mode == WHITE_BALANCE_AUTO)
isx012_writeb(sd, REG_AWB_SN1, 0x00);
@@ -1808,28 +1841,45 @@ static int isx012_post_sensor_flash(struct v4l2_subdev *sd)
isx012_writeb(sd, REG_VPARA_TRG, 0x01);
+ state->flash.ae_flash_lock = 0;
+ state->capture.ae_manual_mode = 0;
+
return 0;
}
+static inline int isx012_restore_sensor_flash(struct v4l2_subdev *sd)
+{
+ struct isx012_state *state = to_state(sd);
+
+ if (!state->flash.ae_flash_lock)
+ return 0;
+
+ cam_info("Flash is locked. Unlocking...\n");
+ return isx012_post_sensor_flash(sd);
+}
+
static int isx012_set_ae_gainoffset(struct v4l2_subdev *sd)
{
struct isx012_state *state = to_state(sd);
- s16 ae_diff, ae_offset;
+ s16 ae_diff, ae_offset = 0;
u16 ae_auto, ae_now;
s16 ersc_auto, ersc_now;
+ u16 ae_ofsetval, ae_maxdiff;
- ae_auto = (u16)state->exposure.ae_offset.ae_auto;
- ae_now = (u16)state->exposure.ae_offset.ae_now;
- ersc_auto = (u16)state->exposure.ae_offset.ersc_auto;
- ersc_now = (u16)state->exposure.ae_offset.ersc_now;
+ ae_auto = (u16)state->flash.ae_offset.ae_auto;
+ ae_now = (u16)state->flash.ae_offset.ae_now;
+ ersc_auto = (u16)state->flash.ae_offset.ersc_auto;
+ ersc_now = (u16)state->flash.ae_offset.ersc_now;
+ ae_ofsetval = (u16)state->flash.ae_offset.ae_ofsetval;
+ ae_maxdiff = (u16)state->flash.ae_offset.ae_maxdiff;
ae_diff = (ae_now + ersc_now) - (ae_auto + ersc_auto);
if (ae_diff < 0)
ae_diff = 0;
if (ersc_now < 0) {
- if (ae_diff >= AE_MAXDIFF)
- ae_offset = -AE_OFSETVAL - ersc_now;
+ if (ae_diff >= ae_maxdiff)
+ ae_offset = -ae_ofsetval - ersc_now;
else {
#ifdef CONFIG_LOAD_FILE
ae_offset = -gtable_buf[ae_diff / 10] - ersc_now;
@@ -1838,21 +1888,100 @@ static int isx012_set_ae_gainoffset(struct v4l2_subdev *sd)
#endif
}
} else {
- if (ae_diff >= AE_MAXDIFF)
- ae_offset = -AE_OFSETVAL;
+ if (ae_diff >= ae_maxdiff)
+ ae_offset = -ae_ofsetval;
else {
#ifdef CONFIG_LOAD_FILE
- ae_offset = -gtable_buf[ae_offset / 10];
+ ae_offset = -gtable_buf[ae_diff / 10];
#else
- ae_offset = -aeoffset_table[ae_offset / 10];
+ ae_offset = -aeoffset_table[ae_diff / 10];
#endif
}
}
+ /* cam_info("[ae_gainoffset] ae_offset(%d), ae_diff(%d):"
+ " (ae_now(%d) + ersc_now(%d)) - (ae_auto(%d) + ersc_auto(%d))",
+ ae_offset, ae_diff, ae_now, ersc_now, ae_auto, ersc_auto); */
isx012_writew(sd, REG_CAP_GAINOFFSET, ae_offset);
return 0;
}
+static int isx012_wait_ae_stable(struct v4l2_subdev *sd,
+ bool af_doing, bool long_wait)
+{
+ struct isx012_state *state = to_state(sd);
+ u32 val = 0, mode = 0;
+ int count;
+ int max_1st, max_2nd;
+
+ if (af_doing || long_wait)
+ max_1st = max_2nd = ISX012_CNT_AE_STABLE;
+ else {
+ max_1st = 20; /* 200ms + alpha */
+ max_2nd = 70; /* 700ms + alpha */
+ }
+
+ /* 1st: go to Half mode */
+ for (count = 0; count < max_1st; count++) {
+ if (af_doing && (state->focus.start == AUTO_FOCUS_OFF))
+ goto cancel_out;
+
+ isx012_readb(sd, REG_MODESEL_FIX, &mode);
+ if ((u8)mode == 0x01)
+ break;
+
+ msleep_debug(10, false);
+ }
+
+ if (count >= max_1st)
+ cam_info("check_ae_stable: fail to check modesel_fix\n\n");
+ else
+ cam_dbg("check_ae_stable: 1st check count=%d\n", count);
+
+ /* 2nd: check move_sts */
+ for (count = 0; count < max_2nd; count++) {
+ if (af_doing && (state->focus.start == AUTO_FOCUS_OFF))
+ goto cancel_out;
+
+ isx012_readb(sd, REG_HALF_MOVE_STS, &val);
+ if ((u8)val == 0x00)
+ break;
+
+ msleep_debug(10, false);
+ }
+
+ if (count >= max_2nd)
+ cam_info("check_ae_stable: fail to check half_move_sts\n\n");
+ else
+ cam_dbg("check_ae_stable: 2nd check count=%d\n", count);
+
+ return 0;
+
+cancel_out:
+ cam_info("check_ae_stable: AF is cancelled(%s)\n",
+ mode == 0x01 ? "1st" : "2nd");
+ return 1;
+}
+
+static bool isx012_check_flash_fire(struct v4l2_subdev *sd, u32 light_level)
+{
+ struct isx012_state *state = to_state(sd);
+
+ if (state->iso == ISO_AUTO) {
+ if (light_level < state->lux_level_flash)
+ goto flash_off;
+ } else if (light_level < state->shutter_level_flash)
+ goto flash_off;
+
+ /* Flash on */
+ return true;
+
+flash_off:
+ isx012_restore_sensor_flash(sd);
+
+ return false;
+}
+
static int isx012_cancel_af(struct v4l2_subdev *sd, bool flash)
{
struct isx012_state *state = to_state(sd);
@@ -1867,17 +1996,14 @@ static int isx012_cancel_af(struct v4l2_subdev *sd, bool flash)
if (flash)
isx012_post_sensor_flash(sd);
- isx012_return_focus(sd);
-
return 0;
}
/* PX: Prepare AF Flash */
-static int isx012_af_start_preflash(struct v4l2_subdev *sd, u32 touch)
+static int isx012_af_start_preflash(struct v4l2_subdev *sd,
+ u32 touch, u32 flash_mode)
{
struct isx012_state *state = to_state(sd);
- u32 val = 0;
- int count;
bool flash = false;
cam_trace("E\n");
@@ -1885,16 +2011,18 @@ static int isx012_af_start_preflash(struct v4l2_subdev *sd, u32 touch)
if (state->sensor_mode == SENSOR_MOVIE)
return 0;
- cam_dbg("Start SINGLE AF, flash mode %d\n", state->flash_mode);
+ cam_dbg("Start SINGLE AF, touch %d, flash mode %d\n",
+ touch, flash_mode);
- state->focus.preflash = PREFLASH_OFF;
+ state->flash.preflash = PREFLASH_OFF;
state->light_level = LUX_LEVEL_MAX;
/* We unlock AE, AWB if not going to capture mode after AF
* for market app. */
if (state->focus.lock) {
+ cam_warn("Focus is locked. Unlocking...\n");
isx012_writeb(sd, REG_MODESEL, 0x0);
- msleep_debug(200, true);
+ msleep_debug(200, false);
state->focus.lock = 0;
}
@@ -1904,77 +2032,32 @@ static int isx012_af_start_preflash(struct v4l2_subdev *sd, u32 touch)
isx012_get_light_level(sd, &state->light_level);
- switch (state->flash_mode) {
+ switch (flash_mode) {
case FLASH_MODE_AUTO:
- if (state->light_level < state->lux_level_flash) {
- /* flash not needed */
+ if (!isx012_check_flash_fire(sd, state->light_level))
break;
- }
case FLASH_MODE_ON:
flash = true;
- state->focus.preflash = PREFLASH_ON;
+ state->flash.preflash = PREFLASH_ON;
isx012_pre_sensor_flash(sd);
isx012_flash_torch(sd, ISX012_FLASH_ON);
break;
case FLASH_MODE_OFF:
- break;
-
default:
+ isx012_restore_sensor_flash(sd);
break;
}
- /* Check AE-stable */
- if (flash) {
- for (count = 0; count < ISX012_CNT_AE_STABLE; count++) {
- if (state->focus.start == AUTO_FOCUS_OFF) {
- cam_info("af_start_preflash: "
- "AF is cancelled!\n");
- state->focus.status = AF_RESULT_CANCELLED;
- goto cancel_out;
- }
-
- isx012_readb(sd, REG_MODESEL_FIX, &val);
- if ((u8)val == 0x01)
- break;
-
- msleep_debug(10, false);
- }
- if (count >= ISX012_CNT_AE_STABLE)
- cam_info("start preflash: fail to check modesel_fix\n\n\n");
- else
- cam_dbg("start preflash: 1st check count=%d\n", count);
-
- for (count = 0; count < ISX012_CNT_AE_STABLE; count++) {
- if (state->focus.start == AUTO_FOCUS_OFF) {
- cam_info("af_start_preflash: "
- "AF is cancelled!\n");
- state->focus.status = AF_RESULT_CANCELLED;
- goto cancel_out;
- }
-
- isx012_readb(sd, REG_HALF_MOVE_STS, &val);
- if ((u8)val == 0x00)
- break;
-
- msleep_debug(10, false);
- }
- if (count >= ISX012_CNT_AE_STABLE)
- cam_info("start preflash: fail to check half_move_sts\n\n\n");
- else
- cam_dbg("start preflash: 2nd check count=%d\n", count);
- }
-
-cancel_out:
- /* If AF cancel, finish pre-flash process. */
- if (state->focus.status == AF_RESULT_CANCELLED) {
- if (flash) {
- isx012_flash_torch(sd, ISX012_FLASH_OFF);
- state->focus.preflash = PREFLASH_NONE;
- }
+ if (flash && isx012_wait_ae_stable_af(sd)) {
+ /* Cancel AF */
+ state->focus.status = AF_RESULT_CANCELLED;
+ isx012_flash_torch(sd, ISX012_FLASH_OFF);
+ state->flash.preflash = PREFLASH_NONE;
isx012_cancel_af(sd, flash);
+ isx012_return_focus(sd);
}
cam_trace("X\n");
@@ -1984,22 +2067,22 @@ cancel_out:
static int isx012_do_af(struct v4l2_subdev *sd, u32 touch)
{
struct isx012_state *state = to_state(sd);
- u32 read_value = 0, ae_scl = 0;
+ u32 read_value = 0;
u32 count = 0;
- bool flash = false;
+ bool flash = false, success = false;
cam_trace("E\n");
/* We do not go to half-release mode if setting FLASH_ON.
* And note that flash variable should only be set to true
* in camera mode. */
- if (state->focus.preflash == PREFLASH_ON)
+ if (state->flash.preflash == PREFLASH_ON)
flash = true;
if (state->sensor_mode == SENSOR_MOVIE) {
isx012_set_from_table(sd, "af_camcorder_start",
&state->regs->af_camcorder_start, 1, 0);
- } else
+ } else if (!flash)
isx012_transit_half_mode(sd);
/* Check the result of AF */
@@ -2021,26 +2104,23 @@ static int isx012_do_af(struct v4l2_subdev *sd, u32 touch)
if (unlikely(count >= AF_SEARCH_COUNT)) {
cam_warn("warning, AF check failed. val=0x%X\n\n", read_value);
isx012_writeb(sd, REG_INTCLR, 0x10);
- state->focus.status = AF_RESULT_FAILED;
goto check_fail;
}
isx012_writeb(sd, REG_INTCLR, 0x10);
isx012_readb(sd, REG_AF_RESUNT, &read_value);
if ((u8)read_value == 0x01)
- state->focus.status = AF_RESULT_SUCCESS;
- else {
- state->focus.status = AF_RESULT_FAILED;
+ success = true;
+ else
af_dbg("AF Fail. AF_RESULT reg=0x%X\n", (u8)read_value);
- }
check_fail:
if (flash) {
isx012_readw(sd, REG_ERRSCL_NOW,
- &state->exposure.ae_offset.ersc_now);
+ &state->flash.ae_offset.ersc_now);
isx012_readw(sd, REG_USER_AESCL_NOW,
- &state->exposure.ae_offset.ae_now);
- isx012_readw(sd, REG_AESCL, &ae_scl);
+ &state->flash.ae_offset.ae_now);
+ isx012_readw(sd, REG_AESCL, &state->flash.ae_scl);
}
if (touch)
@@ -2050,38 +2130,46 @@ check_fail:
isx012_set_from_table(sd, "af_saf_off",
&state->regs->af_saf_off, 1, 0);
- msleep_debug(66, true); /* Wait 1V time(66ms) */
+ /* Remove the exising below 66ms delay:
+ * many delays have been added to _saf_off recently*/
+ /* msleep_debug(66, true);*/ /* Wait 1V time(66ms) */
if (state->focus.start == AUTO_FOCUS_OFF) {
- cam_dbg("do_af: AF is cancelled 02\n");
+ cam_dbg("do_af: AF is cancelled\n");
state->focus.status = AF_RESULT_CANCELLED;
goto cancel_out;
}
if (flash) {
isx012_writew(sd, REG_MANOUTGAIN,
- (u16)ae_scl - AE_SCL_SUBRACT_VALUE);
+ (u16)(state->flash.ae_scl - AE_SCL_SUBRACT_VALUE));
isx012_set_ae_gainoffset(sd);
isx012_flash_torch(sd, ISX012_FLASH_OFF);
- state->focus.ae_manual_mode = touch ? 1 : 0;
+ state->capture.ae_manual_mode = touch ? 1 : 0;
}
cancel_out:
if (state->focus.status == AF_RESULT_CANCELLED) {
- cam_dbg("Single AF cancelled.\n");
+ cam_info("Single AF cancelled\n");
if (flash) {
isx012_flash_torch(sd, ISX012_FLASH_OFF);
- state->focus.preflash = PREFLASH_NONE;
+ state->flash.preflash = PREFLASH_NONE;
}
isx012_cancel_af(sd, flash);
+ isx012_return_focus(sd);
} else {
if (state->sensor_mode == SENSOR_MOVIE)
isx012_return_focus(sd);
state->focus.start = AUTO_FOCUS_OFF;
- cam_dbg("Single AF finished(0x%X)\n", state->focus.status);
+ state->focus.status = success ?
+ AF_RESULT_SUCCESS : AF_RESULT_FAILED;
+ cam_info("Single AF finished(0x%X)\n", state->focus.status);
+
if (!touch)
state->focus.lock = 1; /* fix me */
+ if (flash)
+ state->flash.ae_flash_lock = 1;
}
return 0;
@@ -2093,8 +2181,8 @@ static int isx012_set_af(struct v4l2_subdev *sd, s32 val)
struct isx012_state *state = to_state(sd);
int err = 0;
- cam_info("%s: %s, focus mode %d\n", __func__,
- val ? "start" : "stop", state->focus.mode);
+ cam_info("set_af: %s, focus %d, touch %d\n",
+ val ? "start" : "stop", state->focus.mode, state->focus.touch);
if (unlikely((u32)val >= AUTO_FOCUS_MAX)) {
cam_err("%s: error, invalid value(%d)\n", __func__, val);
@@ -2121,11 +2209,41 @@ static int isx012_set_af(struct v4l2_subdev *sd, s32 val)
return 0;
}
+static int isx012_start_af(struct v4l2_subdev *sd)
+{
+ struct isx012_state *state = to_state(sd);
+ int err = 0;
+ u32 touch, flash_mode;
+
+ mutex_lock(&state->af_lock);
+ touch = state->focus.touch;
+ state->focus.touch = 0;
+
+ flash_mode = state->flash.mode;
+
+ if (state->sensor_mode == SENSOR_CAMERA) {
+ err = isx012_af_start_preflash(sd, touch, flash_mode);
+ if (unlikely(err))
+ goto out;
+
+ if (state->focus.status == AF_RESULT_CANCELLED)
+ goto out;
+ }
+
+ isx012_do_af(sd, touch);
+
+out:
+ mutex_unlock(&state->af_lock);
+
+ return 0;
+}
+
/* PX: Stop AF */
static int isx012_stop_af(struct v4l2_subdev *sd, s32 touch)
{
struct isx012_state *state = to_state(sd);
int err = 0;
+ bool flash;
cam_trace("E\n");
/* mutex_lock(&state->af_lock); */
@@ -2133,18 +2251,17 @@ static int isx012_stop_af(struct v4l2_subdev *sd, s32 touch)
switch (state->focus.status) {
case AF_RESULT_FAILED:
case AF_RESULT_SUCCESS:
- cam_dbg("Stop AF, focus mode %d, AF result %d\n",
+ cam_info("Stop AF, focus mode %d, AF result %d\n",
state->focus.mode, state->focus.status);
- if (state->focus.mode == FOCUS_MODE_MACRO)
- isx012_set_from_table(sd, "cancel_af_macro",
- &state->regs->cancel_af_macro, 1, 0);
- else
- isx012_set_from_table(sd, "cancel_af_normal",
- &state->regs->cancel_af_normal, 1, 0);
+ flash = ((state->flash.preflash == PREFLASH_ON) ||
+ state->flash.ae_flash_lock) ? 1 : 0;
+
+ isx012_cancel_af(sd, flash);
state->focus.status = AF_RESULT_CANCELLED;
- state->focus.preflash = PREFLASH_NONE;
+ state->flash.preflash = PREFLASH_NONE;
+ state->focus.lock = 0;
break;
case AF_RESULT_CANCELLED:
@@ -2158,17 +2275,9 @@ static int isx012_stop_af(struct v4l2_subdev *sd, s32 touch)
break;
}
-#if 0
- if (!touch) {
- /* We move lens to default position if af is cancelled.*/
- err = isx012_return_focus(sd);
- if (unlikely(err)) {
- cam_err("%s: error, fail to af_norma_mode (%d)\n",
- __func__, err);
- goto err_out;
- }
- }
-#endif
+ if (state->focus.touch)
+ state->focus.touch = 0;
+
/* mutex_unlock(&state->af_lock); */
cam_trace("X\n");
return 0;
@@ -2182,28 +2291,8 @@ static void isx012_af_worker(struct work_struct *work)
{
struct isx012_state *state = container_of(work, \
struct isx012_state, af_work);
- struct v4l2_subdev *sd = &state->sd;
- int err = -EINVAL;
- u32 touch;
- mutex_lock(&state->af_lock);
- touch = state->focus.touch;
-
- if (state->sensor_mode == SENSOR_CAMERA) {
- err = isx012_af_start_preflash(sd, touch);
- if (unlikely(err))
- goto out;
-
- if (state->focus.status == AF_RESULT_CANCELLED)
- goto out;
- }
-
- isx012_do_af(sd, touch);
-
-out:
- state->focus.touch = 0;
- mutex_unlock(&state->af_lock);
- return;
+ isx012_start_af(&state->sd);
}
/* PX: Set focus mode */
@@ -2214,7 +2303,7 @@ static int isx012_set_focus_mode(struct v4l2_subdev *sd, s32 val)
u32 cancel = 0;
u8 focus_mode = (u8)val;
- cam_dbg("%s val =%d(0x%X)\n", __func__, val, val);
+ cam_info("set_focus_mode %d(0x%X)\n", val, val);
if (state->focus.mode == val)
return 0;
@@ -2274,9 +2363,9 @@ static int isx012_set_af_window(struct v4l2_subdev *sd)
struct isx012_state *state = to_state(sd);
const s32 mapped_x = state->focus.pos_x;
const s32 mapped_y = state->focus.pos_y;
- const u32 preview_width = state->preview->width;
- const u32 preview_height = state->preview->height;
- const u32 preview_ratio = FRM_RATIO(state->preview);
+ const u32 preview_width = state->preview.frmsize->width;
+ const u32 preview_height = state->preview.frmsize->height;
+ const u32 preview_ratio = FRM_RATIO(state->preview.frmsize);
u32 start_x, start_y;
u32 ratio_width, ratio_height;
struct isx012_rect window = {0, 0, 0, 0};
@@ -2318,9 +2407,11 @@ static int isx012_set_af_window(struct v4l2_subdev *sd)
isx012_writew(sd, 0x6A56, window.height);
isx012_set_from_table(sd, "af_winddow_set",
&state->regs->af_winddow_set, 1, 0);
+
+ state->focus.touch = 1;
mutex_unlock(&state->af_lock);
- cam_dbg("AF window position completed.\n");
+ cam_info("AF window position completed.\n");
cam_trace("X\n");
return 0;
@@ -2331,10 +2422,8 @@ static int isx012_set_touch_af(struct v4l2_subdev *sd, s32 val)
struct isx012_state *state = to_state(sd);
int err = -EIO;
- cam_trace("%s, x=%d y=%d\n", val ? "start" : "stop",
- state->focus.pos_x, state->focus.pos_y);
-
- state->focus.touch = val;
+ cam_info("set_touch (%d, %d)\n",
+ state->focus.pos_x, state->focus.pos_y);
if (val) {
if (mutex_is_locked(&state->af_lock)) {
@@ -2345,7 +2434,8 @@ static int isx012_set_touch_af(struct v4l2_subdev *sd, s32 val)
err = queue_work(state->workqueue, &state->af_win_work);
if (likely(!err))
cam_warn("WARNING, AF window is still processing\n");
- }
+ } else
+ cam_err("%s: invalid val(%d)\n", __func__, val);
cam_trace("X\n");
return 0;
@@ -2425,54 +2515,113 @@ static int isx012_init_regs(struct v4l2_subdev *sd)
}
#endif
-static int isx012_wait_steamoff(struct v4l2_subdev *sd)
+static inline int isx012_do_wait_steamoff(struct v4l2_subdev *sd)
{
struct isx012_state *state = to_state(sd);
struct isx012_stream_time *stream_time = &state->stream_time;
s32 elapsed_msec = 0;
+ u32 val = 0;
+ int err = 0, count;
cam_trace("E\n");
- if (unlikely(!(state->pdata->is_mipi & state->need_wait_streamoff)))
- return 0;
-
do_gettimeofday(&stream_time->curr_time);
elapsed_msec = GET_ELAPSED_TIME(stream_time->curr_time, \
stream_time->before_time) / 1000;
- if (state->pdata->streamoff_delay > elapsed_msec) {
- cam_info("stream-off: %dms + %dms\n", elapsed_msec,
- state->pdata->streamoff_delay - elapsed_msec);
- msleep_debug(state->pdata->streamoff_delay - elapsed_msec,
- true);
- } else
- cam_info("stream-off: %dms\n", elapsed_msec);
+ for (count = 0; count < ISX012_CNT_STREAMOFF; count++) {
+ err = isx012_readb(sd, 0x00DC, &val);
+ CHECK_ERR_MSG(err, "wait_steamoff: error, readb\n")
+
+ if ((val & 0x04) == 0) {
+ cam_dbg("wait_steamoff: %dms + cnt(%d)\n",
+ elapsed_msec, count);
+ break;
+ }
+
+ /* cam_info("wait_steamoff: val = 0x%X\n", val);*/
+ msleep_debug(2, false);
+ }
+
+ if (unlikely(count >= ISX012_CNT_STREAMOFF))
+ cam_info("wait_steamoff: time-out!\n\n");
state->need_wait_streamoff = 0;
return 0;
}
-static int isx012_control_stream(struct v4l2_subdev *sd, u32 cmd)
+static inline int isx012_fast_capture_switch(struct v4l2_subdev *sd)
+{
+ u32 val = 0;
+ int err = 0, count;
+
+ cam_trace("EX\n");
+
+ for (count = 0; count < ISX012_CNT_STREAMOFF; count++) {
+ err = isx012_readb(sd, 0x00DC, &val);
+ CHECK_ERR_MSG(err, "fast_capture_switch: error, readb\n")
+
+ if ((val & 0x03) == 0x02) {
+ cam_dbg("fast_capture_switch: cnt(%d)\n", count);
+ break;
+ }
+
+ /* cam_info("wait_steamoff: val = 0x%X\n", val);*/
+ msleep_debug(2, false);
+ }
+
+ if (unlikely(count >= ISX012_CNT_STREAMOFF))
+ cam_info("fast_capture_switch: time-out!\n\n");
+
+ return 0;
+}
+
+static int isx012_wait_steamoff(struct v4l2_subdev *sd)
{
struct isx012_state *state = to_state(sd);
- cam_info("STREAM %s\n", (cmd == STREAM_STOP) ? "STOP" : "START");
+ if (unlikely(!state->pdata->is_mipi))
+ return 0;
+
+ if (state->need_wait_streamoff) {
+ isx012_do_wait_steamoff(sd);
+ state->need_wait_streamoff = 0;
+ } else if (state->format_mode == V4L2_PIX_FMT_MODE_CAPTURE)
+ isx012_fast_capture_switch(sd);
+
+ cam_trace("EX\n");
+
+ return 0;
+}
+
+static int isx012_control_stream(struct v4l2_subdev *sd, u32 cmd)
+{
+ struct isx012_state *state = to_state(sd);
if (cmd == STREAM_STOP) {
- isx012_writeb(sd, 0x00BF, 0x01);
+#if !defined(CONFIG_VIDEO_IMPROVE_STREAMOFF)
+ state->capture.pre_req = 0;
+#endif
+ if (!((state->runmode == RUNMODE_RUNNING)
+ && state->capture.pre_req)) {
+ isx012_writeb(sd, 0x00BF, 0x01);
+ state->need_wait_streamoff = 1;
+ cam_info("STREAM STOP\n");
+ }
+
#ifdef CONFIG_DEBUG_NO_FRAME
isx012_stop_frame_checker(sd);
#endif
-#ifdef CONFIG_VIDEO_IMPROVE_STREAMOFF
do_gettimeofday(&state->stream_time.before_time);
- state->need_wait_streamoff = 1;
-#else
- msleep_debug(150, true);
+
+#if !defined(CONFIG_VIDEO_IMPROVE_STREAMOFF)
+ isx012_wait_steamoff(sd);
#endif
} else {
isx012_writeb(sd, 0x00BF, 0x00);
+ cam_info("STREAM START\n");
return 0;
}
@@ -2480,39 +2629,31 @@ static int isx012_control_stream(struct v4l2_subdev *sd, u32 cmd)
case RUNMODE_CAPTURING:
cam_dbg("Capture Stop!\n");
state->runmode = RUNMODE_CAPTURING_STOP;
+ state->capture.ready = 0;
+ state->capture.lowlux_night = 0;
-#ifdef CONFIG_NEW_STREAM_DELAY
- if (state->lowlux_night) {
- state->pdata->streamoff_delay = 400;
- state->lowlux_night = 0;
- } else
- state->pdata->streamoff_delay = 150;
-#endif
- /* We turn flash off if one shot flash is still on. */
+ /* We turn flash off if one-shot flash is still on. */
if (isx012_is_hwflash_on(sd))
isx012_flash_oneshot(sd, ISX012_FLASH_OFF);
+ else
+ state->flash.on = 0;
- if (state->focus.preflash == PREFLASH_ON)
+ if (state->flash.preflash == PREFLASH_ON)
isx012_post_sensor_flash(sd);
break;
case RUNMODE_RUNNING:
cam_dbg("Preview Stop!\n");
state->runmode = RUNMODE_RUNNING_STOP;
-#ifdef CONFIG_NEW_STREAM_DELAY
- if (state->scene_mode == SCENE_MODE_NIGHTSHOT)
- state->pdata->streamoff_delay = 150;
- else
- state->pdata->streamoff_delay = 66;
-#endif
+ if (state->capture.pre_req) {
+ isx012_prepare_fast_capture(sd);
+ state->capture.pre_req = 0;
+ }
break;
case RUNMODE_RECORDING:
state->runmode = RUNMODE_RECORDING_STOP;
-#ifdef CONFIG_NEW_STREAM_DELAY
- state->pdata->streamoff_delay = 66;
-#endif
break;
default:
@@ -2531,7 +2672,7 @@ static int isx012_set_flash_mode(struct v4l2_subdev *sd, s32 val)
/* if (state->sensor_mode == SENSOR_MOVIE && !state->recording)
return 0;*/
- if (state->flash_mode == val) {
+ if (state->flash.mode == val) {
cam_dbg("the same flash mode=%d\n", val);
return 0;
}
@@ -2539,11 +2680,11 @@ static int isx012_set_flash_mode(struct v4l2_subdev *sd, s32 val)
if (val == FLASH_MODE_TORCH)
isx012_flash_torch(sd, ISX012_FLASH_ON);
- if ((state->flash_mode == FLASH_MODE_TORCH)
+ if ((state->flash.mode == FLASH_MODE_TORCH)
&& (val == FLASH_MODE_OFF))
isx012_flash_torch(sd, ISX012_FLASH_OFF);
- state->flash_mode = val;
+ state->flash.mode = val;
cam_dbg("Flash mode = %d\n", val);
return 0;
}
@@ -2603,21 +2744,32 @@ retry:
switch (val) {
case ISO_AUTO:
case ISO_50:
+ state->shutter_level_flash = 0xB52A;
+ break;
+
case ISO_100:
+ state->shutter_level_flash = 0x9DBA;
+ break;
+
case ISO_200:
+ state->shutter_level_flash = 0x864A;
+ break;
+
case ISO_400:
- isx012_set_from_table(sd, "iso",
- state->regs->iso, ARRAY_SIZE(state->regs->iso),
- val);
+ state->shutter_level_flash = 0x738A;
break;
default:
cam_err("set_iso: error, not supported (%d)\n", val);
val = ISO_AUTO;
goto retry;
- break;
}
+ isx012_set_from_table(sd, "iso", state->regs->iso,
+ ARRAY_SIZE(state->regs->iso), val);
+
+ state->iso = val;
+
cam_trace("X\n");
return 0;
}
@@ -2641,7 +2793,9 @@ static inline void isx012_get_exif_flash(struct v4l2_subdev *sd,
{
struct isx012_state *state = to_state(sd);
- switch (state->flash_mode) {
+ *flash = 0;
+
+ switch (state->flash.mode) {
case FLASH_MODE_OFF:
*flash |= EXIF_FLASH_MODE_SUPPRESSION;
break;
@@ -2659,12 +2813,8 @@ static inline void isx012_get_exif_flash(struct v4l2_subdev *sd,
break;
}
- if (state->flash_on) {
+ if (state->flash.on)
*flash |= EXIF_FLASH_FIRED;
- if (state->sensor_mode == SENSOR_CAMERA)
- state->flash_on = 0;
- }
-
}
/* PX: */
@@ -2672,14 +2822,21 @@ static int isx012_get_exif(struct v4l2_subdev *sd)
{
struct isx012_state *state = to_state(sd);
u32 exposure_time = 0;
+ u32 int_dec, integer;
/* exposure time */
state->exif.exp_time_den = 0;
isx012_get_exif_exptime(sd, &exposure_time);
- /*WARN(!exposure_time, "WARNING: exposure time is 0\n");*/
- if (exposure_time)
+ if (exposure_time) {
state->exif.exp_time_den = 1000 * 1000 / exposure_time;
- else
+
+ int_dec = (1000 * 1000) * 10 / exposure_time;
+ integer = state->exif.exp_time_den * 10;
+
+ /* Round off */
+ if ((int_dec - integer) > 5)
+ state->exif.exp_time_den += 1;
+ } else
state->exif.exp_time_den = 0;
/* iso */
@@ -2695,20 +2852,51 @@ static int isx012_get_exif(struct v4l2_subdev *sd)
return 0;
}
+/* for debugging */
+static int isx012_check_preview_status(struct v4l2_subdev *sd)
+{
+ u32 reg_val1 = 0;
+ u32 reg_val4 = 0;
+ u32 reg_val7 = 0;
+ u32 reg_val11 = 0;
+
+ /* AE SN */
+ isx012_readb(sd, REG_AE_SN1, &reg_val1);
+ isx012_readb(sd, REG_AE_SN4, &reg_val4);
+ isx012_readb(sd, REG_AE_SN7, &reg_val7);
+ isx012_readb(sd, REG_AE_SN11, &reg_val11);
+
+ cam_info("AE_SN[0x%X, 0x%X, 0x%X, 0x%X]"
+ , reg_val1, reg_val4, reg_val7, reg_val11);
+
+ return 0;
+}
+
static int isx012_set_preview_size(struct v4l2_subdev *sd)
{
struct isx012_state *state = to_state(sd);
+ u32 width, height;
- if (!state->update_frmsize)
+ if (!state->preview.update_frmsize)
return 0;
- cam_dbg("set preview size(%dx%d)\n",
- state->preview->width, state->preview->height);
+ if (unlikely(!state->preview.frmsize)) {
+ cam_warn("warning, preview resolution not set\n");
+ state->preview.frmsize = isx012_get_framesize(
+ isx012_preview_frmsizes,
+ ARRAY_SIZE(isx012_preview_frmsizes),
+ PREVIEW_SZ_XGA);
+ }
- isx012_writew(sd, REG_HSIZE_MONI, state->preview->width);
- isx012_writew(sd, REG_VSIZE_MONI, state->preview->height);
+ width = state->preview.frmsize->width;
+ height = state->preview.frmsize->height;
- state->update_frmsize = 0;
+ cam_dbg("set preview size(%dx%d)\n", width, height);
+
+ isx012_writew(sd, REG_HSIZE_MONI, width);
+ isx012_writew(sd, REG_VSIZE_MONI, height);
+
+ state->preview.update_frmsize = 0;
return 0;
}
@@ -2718,7 +2906,7 @@ static int isx012_start_preview(struct v4l2_subdev *sd)
struct isx012_state *state = to_state(sd);
int err = -EINVAL;
- cam_dbg("Camera Preview start, runmode = %d\n", state->runmode);
+ cam_info("Camera Preview start, runmode = %d\n", state->runmode);
if ((state->runmode == RUNMODE_NOTREADY) ||
(state->runmode == RUNMODE_CAPTURING)) {
@@ -2727,9 +2915,18 @@ static int isx012_start_preview(struct v4l2_subdev *sd)
}
state->focus.status = AF_RESULT_NONE;
- state->focus.preflash = PREFLASH_NONE;
+ state->flash.preflash = PREFLASH_NONE;
state->focus.touch = 0;
+ /* Do fast-AE before preview mode if needed */
+ if (state->preview.fast_ae) {
+ cam_info("Fast AE for preview\n");
+ isx012_set_from_table(sd, "flash_fast_ae_awb",
+ &state->regs->flash_fast_ae_awb, 1, 0);
+ isx012_wait_ae_stable_preview(sd);
+ state->preview.fast_ae = 0;
+ }
+
/* Set movie mode if needed. */
isx012_transit_movie_mode(sd);
@@ -2745,8 +2942,11 @@ static int isx012_start_preview(struct v4l2_subdev *sd)
err = isx012_transit_preview_mode(sd);
CHECK_ERR_MSG(err, "preview_mode(%d)\n", err);
+ isx012_check_preview_status(sd);
+
err = isx012_is_cm_changed(sd);
CHECK_ERR(err);
+
isx012_control_stream(sd, STREAM_START);
#ifdef CONFIG_DEBUG_NO_FRAME
@@ -2763,55 +2963,62 @@ static int isx012_start_preview(struct v4l2_subdev *sd)
return 0;
}
-static int isx012_start_video_preview(struct v4l2_subdev *sd)
+static int isx012_set_capture(struct v4l2_subdev *sd)
{
struct isx012_state *state = to_state(sd);
- int err = -EINVAL;
+ int err = 0;
+ u32 lux = 0, ae_scl;
- cam_dbg("Video Preview start, runmode = %d (Not Implemented)\n",
- state->runmode);
- return err;
-}
+ if (unlikely((state->flash.preflash == PREFLASH_ON) &&
+ (state->flash.mode == FLASH_MODE_OFF)))
+ isx012_post_sensor_flash(sd);
-static int isx012_start_capture(struct v4l2_subdev *sd)
-{
- struct isx012_state *state = to_state(sd);
- int err = -ENODEV, count;
- u32 lux = 0, val = 0;
+ if (state->capture.ae_manual_mode) {
+ /* Check whether fast-AE for preview is needed after capture */
+ isx012_readw(sd, REG_AESCL, &ae_scl);
+ cam_dbg("set_capture: pre ae_scl = %d, ae_scl = %d\n",
+ state->flash.ae_scl, ae_scl);
+ if (abs(state->flash.ae_scl - ae_scl) >= AESCL_DIFF_FASTAE)
+ state->preview.fast_ae = 1;
- cam_trace("E\n");
+ isx012_set_from_table(sd, "ae_manual_mode",
+ &state->regs->ae_manual, 1, 0);
+ }
/* Set capture size */
err = isx012_set_capture_size(sd);
CHECK_ERR_MSG(err, "fail to set capture size (%d)\n", err);
- if (state->focus.ae_manual_mode) {
- isx012_writeb(sd, REG_AE_SN1, 0x02);
- isx012_writeb(sd, REG_AE_SN4, 0x02);
- isx012_writeb(sd, REG_AE_SN7, 0x02);
- isx012_writeb(sd, REG_AE_SN11, 0x02);
-
- msleep_debug(66, true); /* Wait 1v time(66ms) */
- }
-
/* Set flash */
- switch (state->flash_mode) {
+ switch (state->flash.mode) {
case FLASH_MODE_AUTO:
- /* 3rd party App could do capturing without AF. So we check
- * whether AF is executed before capture and turn on flash
- * if needed. But we do not consider low-light capture of Market
- * App. */
- if (state->focus.preflash == PREFLASH_NONE) {
+ /* 3rd party App could do capturing without AF.*/
+ if (state->flash.preflash == PREFLASH_NONE) {
isx012_get_light_level(sd, &lux);
- if (lux < state->lux_level_flash)
+ if (!isx012_check_flash_fire(sd, lux))
break;
- } else if (state->focus.preflash == PREFLASH_OFF)
- break;
+ } else if (state->flash.preflash == PREFLASH_OFF) {
+ /* we re-check lux if capture after touch-AF*/
+ if (!state->focus.lock) {
+ isx012_get_light_level(sd, &lux);
+ if (!isx012_check_flash_fire(sd, lux))
+ break;
+ } else
+ break;
+ }
/* We do not break. */
case FLASH_MODE_ON:
isx012_flash_oneshot(sd, ISX012_FLASH_ON);
- /* We here don't need to set state->flash_on to 1 */
+
+ if (unlikely(state->flash.preflash != PREFLASH_ON)) {
+ cam_warn("warning: Flash capture without preflash!!\n\n");
+ isx012_set_from_table(sd, "flash_fast_ae_awb",
+ &state->regs->flash_fast_ae_awb, 1, 0);
+ isx012_wait_ae_stable_cap(sd);
+ state->flash.awb_delay = 0;
+ } else
+ state->flash.awb_delay = 210;
break;
case FLASH_MODE_OFF:
@@ -2819,36 +3026,78 @@ static int isx012_start_capture(struct v4l2_subdev *sd)
break;
}
- /* Set here lowlux_night field for night shot of 3rd party App.
- * Refer to comments of above switch() statements */
-
/* Transit to capture mode */
err = isx012_transit_capture_mode(sd);
CHECK_ERR_MSG(err, "fail to capture_mode (%d)\n", err);
- err = isx012_is_cm_changed(sd);
+ return 0;
+}
+
+static int isx012_prepare_fast_capture(struct v4l2_subdev *sd)
+{
+ struct isx012_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);
+ isx012_set_framesize(sd, isx012_capture_frmsizes,
+ ARRAY_SIZE(isx012_capture_frmsizes), false);
+
+ err = isx012_set_capture(sd);
CHECK_ERR(err);
- isx012_control_stream(sd, STREAM_START);
+ state->capture.ready = 1;
+
+ return 0;
+}
+
+static int isx012_start_capture(struct v4l2_subdev *sd)
+{
+ struct isx012_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 = isx012_set_capture(sd);
+ CHECK_ERR(err);
+
+ err = isx012_is_cm_changed(sd);
+ CHECK_ERR(err);
+
+ isx012_control_stream(sd, STREAM_START);
+ night_delay = 500;
+ } else
+ night_delay = 700; /* for completely skipping 1 frame. */
#ifdef CONFIG_DEBUG_NO_FRAME
isx012_start_frame_checker(sd);
#endif
- if (state->focus.preflash == PREFLASH_ON) {
- msleep_debug(210, true);
+ if (state->flash.on && (state->wb.mode == WHITE_BALANCE_AUTO)) {
+ msleep_debug(state->flash.awb_delay, true);
+
for (count = 0; count < ISX012_CNT_CAPTURE_AWB; count++) {
isx012_readb(sd, REG_AWBSTS, &val);
- if ((val & 0x06) != 0) {
- cam_trace("AWB stable. cnt=%d\n", count);
+ if ((val & 0x06) != 0)
break;
- }
+
msleep_debug(30, false);
}
+
+ if (unlikely(count >= ISX012_CNT_CAPTURE_AWB))
+ cam_warn("start_capture: fail to check awb\n");
}
state->runmode = RUNMODE_CAPTURING;
+ if (state->capture.lowlux_night)
+ msleep_debug(night_delay, true);
+
/* Get EXIF */
isx012_get_exif(sd);
@@ -2872,12 +3121,13 @@ static int isx012_s_mbus_fmt(struct v4l2_subdev *sd,
state->format_mode = V4L2_PIX_FMT_MODE_CAPTURE;
if (state->format_mode != V4L2_PIX_FMT_MODE_CAPTURE) {
- previous_index = state->preview ? state->preview->index : -1;
+ previous_index = state->preview.frmsize ?
+ state->preview.frmsize->index : -1;
isx012_set_framesize(sd, isx012_preview_frmsizes,
ARRAY_SIZE(isx012_preview_frmsizes), true);
- if (previous_index != state->preview->index)
- state->update_frmsize = 1;
+ if (previous_index != state->preview.frmsize->index)
+ state->preview.update_frmsize = 1;
} else {
/*
* In case of image capture mode,
@@ -2888,8 +3138,8 @@ static int isx012_s_mbus_fmt(struct v4l2_subdev *sd,
/* for maket app.
* Samsung camera app does not use unmatched ratio.*/
- if (unlikely(FRM_RATIO(state->preview)
- != FRM_RATIO(state->capture))) {
+ if (unlikely(FRM_RATIO(state->preview.frmsize)
+ != FRM_RATIO(state->capture.frmsize))) {
cam_warn("%s: warning, capture ratio " \
"is different with preview ratio\n",
__func__);
@@ -2926,7 +3176,7 @@ static int isx012_try_mbus_fmt(struct v4l2_subdev *sd,
for (i = 0; i < num_entries; i++) {
if (capture_fmts[i].code == fmt->code &&
capture_fmts[i].colorspace == fmt->colorspace) {
- cam_dbg("%s: match found, returning 0\n", __func__);
+ cam_info("%s: match found, returning 0\n", __func__);
return 0;
}
}
@@ -2948,23 +3198,23 @@ static int isx012_enum_framesizes(struct v4l2_subdev *sd,
* this returns the default camera resolution (VGA)
*/
if (state->format_mode != V4L2_PIX_FMT_MODE_CAPTURE) {
- if (unlikely(state->preview == NULL)) {
+ 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->width;
- fsize->discrete.height = state->preview->height;
+ fsize->discrete.width = state->preview.frmsize->width;
+ fsize->discrete.height = state->preview.frmsize->height;
} else {
- if (unlikely(state->capture == NULL)) {
+ 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->width;
- fsize->discrete.height = state->capture->height;
+ fsize->discrete.width = state->capture.frmsize->width;
+ fsize->discrete.height = state->capture.frmsize->height;
}
return 0;
@@ -3082,7 +3332,7 @@ static int isx012_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
static int isx012_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
{
struct isx012_state *state = to_state(sd);
- int err = -ENOIOCTLCMD;
+ int err = 0;
if (!state->initialized && ctrl->id != V4L2_CID_CAMERA_SENSOR_MODE) {
cam_warn("%s: WARNING, camera not initialized. ID = %d(0x%X)\n",
@@ -3188,11 +3438,20 @@ static int isx012_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
err = isx012_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_ANTI_BANDING:
+ break;
+
case V4L2_CID_CAMERA_FRAME_RATE:
default:
cam_err("%s: WARNING, unknown Ctrl-ID 0x%x\n",
__func__, ctrl->id);
- err = 0; /* we return no error. */
+ /* we return no error. */
break;
}
@@ -3263,14 +3522,14 @@ static int isx012_s_stream(struct v4l2_subdev *sd, int enable)
case STREAM_MODE_MOVIE_ON:
cam_info("movie on");
state->recording = 1;
- if (state->flash_mode != FLASH_MODE_OFF)
+ if (state->flash.mode != FLASH_MODE_OFF)
isx012_flash_torch(sd, ISX012_FLASH_ON);
break;
case STREAM_MODE_MOVIE_OFF:
cam_info("movie off");
state->recording = 0;
- if (state->flash_on)
+ if (state->flash.on)
isx012_flash_torch(sd, ISX012_FLASH_OFF);
break;
@@ -3457,7 +3716,7 @@ static int isx012_post_poweron(struct v4l2_subdev *sd)
isx012_Sensor_Calibration(sd);
cam_dbg("calibration complete!\n");
- cam_dbg("POWER ON END\n\n");
+ cam_info("POWER ON END\n\n");
return 0;
}
@@ -3473,7 +3732,7 @@ static void isx012_init_parameter(struct v4l2_subdev *sd)
state->light_level = LUX_LEVEL_MAX;
/* Set update_frmsize to 1 for case of power reset */
- state->update_frmsize = 1;
+ state->preview.update_frmsize = 1;
/* Initialize focus field for case of init after power reset. */
memset(&state->focus, 0, sizeof(state->focus));
@@ -3482,6 +3741,17 @@ static void isx012_init_parameter(struct v4l2_subdev *sd)
state->frame_check = false;
#endif
state->lux_level_flash = LUX_LEVEL_FLASH_ON;
+ state->shutter_level_flash = 0x0;
+
+#ifdef CONFIG_LOAD_FILE
+ state->flash.ae_offset.ae_ofsetval =
+ isx012_define_read("AE_OFSETVAL", 4);
+ state->flash.ae_offset.ae_maxdiff =
+ isx012_define_read("AE_MAXDIFF", 4);
+#else
+ state->flash.ae_offset.ae_ofsetval = AE_OFSETVAL;
+ state->flash.ae_offset.ae_maxdiff = AE_MAXDIFF;
+#endif
}
static int isx012_init(struct v4l2_subdev *sd, u32 val)
@@ -3489,10 +3759,11 @@ static int isx012_init(struct v4l2_subdev *sd, u32 val)
struct isx012_state *state = to_state(sd);
int err = -EINVAL;
- cam_dbg("%s: start\n", __func__);
+ cam_info("init: start v08(%s)\n", __DATE__);
#ifdef CONFIG_LOAD_FILE
err = isx012_regs_table_init();
+ CHECK_ERR_MSG(err, "loading setfile fail!\n");
#endif
err = isx012_post_poweron(sd);
CHECK_ERR_MSG(err, "power-on fail!\n");
@@ -3558,22 +3829,22 @@ static int isx012_s_config(struct v4l2_subdev *sd,
else
state->freq = state->pdata->freq;
- state->preview = state->capture = NULL;
+ 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;
/* Initialize the independant HW module like flash here */
- state->flash_mode = FLASH_MODE_OFF;
- state->flash_on = 0;
+ state->flash.mode = FLASH_MODE_OFF;
+ state->flash.on = 0;
for (i = 0; i < ARRAY_SIZE(isx012_ctrls); i++)
isx012_ctrls[i].value = isx012_ctrls[i].default_value;
#ifdef ISX012_SUPPORT_FLASH
if (isx012_is_hwflash_on(sd))
- state->ignore_flash = 1;
+ state->flash.ignore_flash = 1;
#endif
state->regs = &reg_datas;
@@ -3672,7 +3943,7 @@ static int isx012_remove(struct i2c_client *client)
* 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->ignore_flash))
+ if (unlikely(state->flash.on && !state->flash.ignore_flash))
isx012_flash_torch(sd, ISX012_FLASH_OFF);
v4l2_device_unregister_subdev(sd);
@@ -3685,6 +3956,83 @@ static int isx012_remove(struct i2c_client *client)
return 0;
}
+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)
+{
+ 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);
+}
+
+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 isx012_create_dbglogfile(struct class *cls)
+{
+ struct device *dev;
+ int err;
+
+ dbg_level |= CAMDBG_LEVEL_DEFAULT;
+
+ dev = class_find_device(cls, NULL, "rear", is_sysdev);
+ if (unlikely(!dev)) {
+ pr_info("[ISX012] can not find rear 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 isx012_id[] = {
{ ISX012_DRIVER_NAME, 0 },
{}
@@ -3703,6 +4051,7 @@ static int __init v4l2_i2c_drv_init(void)
{
pr_info("%s: %s called\n", __func__, ISX012_DRIVER_NAME); /* dslim*/
isx012_create_file(camera_class);
+ isx012_create_dbglogfile(camera_class);
return i2c_add_driver(&v4l2_i2c_driver);
}
diff --git a/drivers/media/video/isx012.h b/drivers/media/video/isx012.h
index 9e34992..5e65195 100644
--- a/drivers/media/video/isx012.h
+++ b/drivers/media/video/isx012.h
@@ -9,7 +9,7 @@
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
- * - change date: 2012.04.17 12
+ * - change date: 2012.06.28
*/
#ifndef __ISX012_H__
@@ -35,12 +35,11 @@
#define CONFIG_CAM_YUV_CAPTURE
#define CONFIG_CAM_I2C_LITTLE_ENDIAN
/* #define CONFIG_LOAD_FILE */ /* for tuning */
-#define CONFIG_DEBUG_NO_FRAME
-#define CONFIG_NEW_STREAM_DELAY
+/* #define CONFIG_DEBUG_NO_FRAME */
/** Debuging Feature **/
-#define CONFIG_CAM_DEBUG
-#define CONFIG_CAM_TRACE /* 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 */
/***********************************/
@@ -63,6 +62,16 @@ module_param_named(debug_mask, isx012_debug_mask, uint, S_IWUSR | S_IRUGO);
#endif
#define TAG_NAME "["ISX012_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, ...) \
@@ -76,7 +85,7 @@ module_param_named(debug_mask, isx012_debug_mask, uint, S_IWUSR | S_IRUGO);
#else
#define cam_dbg(fmt, ...) \
do { \
- if (*to_state(sd)->dbg_level & CAMDBG_LEVEL_DEBUG) \
+ if (dbg_level & CAMDBG_LEVEL_DEBUG) \
printk(KERN_DEBUG TAG_NAME fmt, ##__VA_ARGS__); \
} while (0)
#endif
@@ -86,7 +95,7 @@ module_param_named(debug_mask, isx012_debug_mask, uint, S_IWUSR | S_IRUGO);
#else
#define cam_trace(fmt, ...) \
do { \
- if (*to_state(sd)->dbg_level & CAMDBG_LEVEL_TRACE) \
+ if (dbg_level & CAMDBG_LEVEL_TRACE) \
printk(KERN_DEBUG TAG_NAME "%s: " fmt, \
__func__, ##__VA_ARGS__); \
} while (0)
@@ -214,6 +223,7 @@ enum isx012_preview_frame_size {
enum isx012_capture_frame_size {
CAPTURE_SZ_VGA = 0, /* 640x480 */
+ CAPTURE_SZ_960_720,
CAPTURE_SZ_W1MP, /* 1536x864. Samsung-defined */
CAPTURE_SZ_2MP, /* UXGA - 1600x1200 */
CAPTURE_SZ_W2MP, /* 2048x1152. Samsung-defined */
@@ -350,18 +360,31 @@ struct isx012_gps_info {
s32 gps_timeStamp;
};
+struct isx012_preview {
+ const struct isx012_framesize *frmsize;
+ u32 update_frmsize:1;
+ u32 fast_ae:1;
+};
+
+struct isx012_capture {
+ const struct isx012_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 isx012_focus {
enum v4l2_focusmode mode;
enum af_result_status status;
- enum preflash_status preflash;
u32 pos_x;
u32 pos_y;
u32 start:1; /* enum v4l2_auto_focus*/
u32 touch:1;
- u32 lock:1; /* fix me */
- u32 ae_manual_mode:1;
+ u32 lock:1; /* set if single AF is done */
};
/* struct for sensor specific data */
@@ -370,16 +393,30 @@ struct isx012_ae_gain_offset {
u32 ae_now;
u32 ersc_auto;
u32 ersc_now;
+
+ u32 ae_ofsetval;
+ u32 ae_maxdiff;
};
-/* Exposure */
-struct isx012_exposure {
+/* Flash struct */
+struct isx012_flash {
struct isx012_ae_gain_offset ae_offset;
- s32 val;
+ 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 isx012_exposure {
+ s32 val; /* exposure value */
u32 ae_lock:1;
};
-/* White Balance */
+/* White Balance struct */
struct isx012_whitebalance {
enum v4l2_wb_mode mode; /* wb mode */
u32 awb_lock:1;
@@ -396,8 +433,8 @@ struct isx012_exif {
/* EXIF - flash filed */
#define EXIF_FLASH_FIRED (0x01)
-#define EXIF_FLASH_MODE_FIRING (0x01)
-#define EXIF_FLASH_MODE_SUPPRESSION (0x01 << 1)
+#define EXIF_FLASH_MODE_FIRING (0x01 << 3)
+#define EXIF_FLASH_MODE_SUPPRESSION (0x02 << 3)
#define EXIF_FLASH_MODE_AUTO (0x03 << 3)
struct isx012_stream_time {
@@ -486,17 +523,13 @@ struct isx012_regs {
struct regset_table sharpness[SHARPNESS_MAX];
struct regset_table fps[I_FPS_MAX];
struct regset_table preview_return;
- struct regset_table ae_lock_on;
- struct regset_table ae_lock_off;
- struct regset_table awb_lock_on;
- struct regset_table awb_lock_off;
-#ifdef CONFIG_VIDEO_ISX012_P8
- struct regset_table set_lowlight_cap;
-#endif
+
/* Flash */
struct regset_table flash_ae_line;
struct regset_table flash_on;
struct regset_table flash_off;
+ struct regset_table flash_fast_ae_awb;
+ struct regset_table ae_manual;
/* AF */
struct regset_table af_normal_mode;
@@ -534,9 +567,10 @@ struct isx012_state {
struct isx012_platform_data *pdata;
struct v4l2_subdev sd;
struct v4l2_pix_format req_fmt;
- const struct isx012_framesize *preview;
- const struct isx012_framesize *capture;
+ struct isx012_preview preview;
+ struct isx012_capture capture;
struct isx012_focus focus;
+ struct isx012_flash flash;
struct isx012_exposure exposure;
struct isx012_whitebalance wb;
struct isx012_exif exif;
@@ -556,8 +590,8 @@ struct isx012_state {
enum runmode runmode;
enum v4l2_sensor_mode sensor_mode;
enum v4l2_pix_format_mode format_mode;
- enum v4l2_flash_mode flash_mode;
enum v4l2_scene_mode scene_mode;
+ enum v4l2_iso_mode iso;
s32 vt_mode;
s32 req_fps;
@@ -566,18 +600,15 @@ struct isx012_state {
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 flash_on:1;
- u32 ignore_flash:1;
- u32 update_frmsize:1;
u32 need_wait_streamoff:1;
u32 initialized:1;
- u32 lowlux_night:1;
};
static inline struct isx012_state *to_state(struct v4l2_subdev *sd)
@@ -585,6 +616,10 @@ static inline struct isx012_state *to_state(struct v4l2_subdev *sd)
return container_of(sd, struct isx012_state, sd);
}
+static inline int isx012_restore_sensor_flash(struct v4l2_subdev *sd);
+static int isx012_set_capture(struct v4l2_subdev *sd);
+static int isx012_prepare_fast_capture(struct v4l2_subdev *sd);
+
extern struct class *camera_class;
extern int isx012_create_file(struct class *cls);
@@ -615,14 +650,15 @@ extern int isx012_create_file(struct class *cls);
#define LUX_LEVEL_FLASH_ON 0x2B
/* Count for loop */
-#define ISX012_CNT_CAPTURE_FRM 100
+#define ISX012_CNT_CAPTURE_FRM 330
#define ISX012_CNT_CLEAR_VINT 20
#define ISX012_CNT_AE_STABLE 100 /* for checking MODESEL_FIX */
-#define ISX012_CNT_CAPTURE_AWB 8
+#define ISX012_CNT_CAPTURE_AWB 3 /* 8 -> 3 */
#define ISX012_CNT_OM_CHECK 30
-#define ISX012_CNT_CM_CHECK 180 /* 160 -> 180 */
+#define ISX012_CNT_CM_CHECK 280 /* 160 -> 180 */
+#define ISX012_CNT_STREAMOFF 300
-#define AF_SEARCH_COUNT 80
+#define AF_SEARCH_COUNT 200
#define AE_STABLE_SEARCH_COUNT 7
/* Sensor AF first,second window size.
@@ -631,6 +667,10 @@ extern int isx012_create_file(struct class *cls);
#define DEFAULT_WINDOW_HEIGHT 80
#define AF_PRECISION 100
+/* diff value fior fast AE in preview */
+#define AESCL_DIFF_FASTAE 1000
+
+
/*
* Register Address Definition
*/
diff --git a/drivers/media/video/isx012_regs.h b/drivers/media/video/isx012_regs.h
index 4e05dbf..fa8de0c 100644
--- a/drivers/media/video/isx012_regs.h
+++ b/drivers/media/video/isx012_regs.h
@@ -9,14 +9,14 @@
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
- * Change Date: 2012.04.19
+ * 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 5000 //for tuning // max =< 5000
+#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
@@ -83,7 +83,6 @@ const uint16_t aeoffset_table[] = { // normal 4.6times
static const isx012_regset_t ISX012_Init_Reg[] =
{
-//ISX012_Initial_Setting_sensor_111218_V3.08.ini//
/////////////////////////////////////
//AF driver setting//³»ºÎ AF driver//
/////////////////////////////////////
@@ -254,7 +253,7 @@ static const isx012_regset_t ISX012_Init_Reg[] =
{0x6616,0x01,0x01}, // AF_DIRECTBACK_F :On=1
{0x661B,0x03,0x01}, // AF_OPDDATA_SAVE :
{0x661C,0x00,0x01}, // AF_MONOTONY_POS :
-{0x663E,0x01,0x01}, // AF_SEARCH_SECOND_DIR :
+{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ÀÚµ¿ ĵ½½
@@ -273,9 +272,9 @@ static const isx012_regset_t ISX012_Init_Reg[] =
{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,0x0004,0x02}, // AF_DRV_AMOUNT_TONEAR_S :
+{0x665E,0x0003,0x02}, // AF_DRV_AMOUNT_TONEAR_S :
{0x6660,0x0018,0x02}, // AF_DRV_AMOUNT_TOFAR_F :
-{0x6662,0x0004,0x02}, // AF_DRV_AMOUNT_TOFAR_S :
+{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 :
@@ -290,10 +289,10 @@ static const isx012_regset_t ISX012_Init_Reg[] =
{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,0x0024,0x02}, // AF_SEARCH_OFFSET_FAR :
-{0x6744,0x0024,0x02}, // AF_SEARCH_OFFSET_NEAR :
+{0x6742,0x0012,0x02}, // AF_SEARCH_OFFSET_FAR :
+{0x6744,0x0006,0x02}, // AF_SEARCH_OFFSET_NEAR :
//chooys add
-{0x6677,0x00,0x01}, /* AF_SEND_PARTITION : Use=1 */
+{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
@@ -304,6 +303,9 @@ static const isx012_regset_t ISX012_Init_Reg[] =
{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 :
@@ -321,14 +323,14 @@ static const isx012_regset_t ISX012_Init_Reg[] =
{0x6A4A,0x00C9,0x02}, // AF_OPD3_VDELAY :
{0x6A4C,0x01AE,0x02}, // AF_OPD3_HVALID :
{0x6A4E,0x01AE,0x02}, // AF_OPD3_VVALID :
-{0x6A50,0x048A,0x02}, // AF_OPD4_HDELAY :
-{0x6A52,0x0321,0x02}, // AF_OPD4_VDELAY :
-{0x6A54,0x015F,0x02}, // AF_OPD4_HVALID :
-{0x6A56,0x015F,0x02}, // AF_OPD4_VVALID :
-{0x6A58,0x04BA,0x02}, // AF_OPD5_HDELAY :
-{0x6A5A,0x02E4,0x02}, // AF_OPD5_VDELAY :
-{0x6A5C,0x00F0,0x02}, // AF_OPD5_HVALID :
-{0x6A5E,0x0276,0x02}, // AF_OPD5_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 :
@@ -337,24 +339,24 @@ static const isx012_regset_t ISX012_Init_Reg[] =
{0x6A6A,0x052C,0x02}, // AF_OPD7_VDELAY :
{0x6A6C,0x01AE,0x02}, // AF_OPD7_HVALID :
{0x6A6E,0x01AE,0x02}, // AF_OPD7_VVALID :
-{0x6A70,0x04C6,0x02}, // AF_OPD8_HDELAY :
-{0x6A72,0x0493,0x02}, // AF_OPD8_VDELAY :
-{0x6A74,0x00E6,0x02}, // AF_OPD8_HVALID :
-{0x6A76,0x00E6,0x02}, // AF_OPD8_VVALID :
-{0x6A78,0x048A,0x02}, // AF_OPD9_HDELAY :
-{0x6A7A,0x0457,0x02}, // AF_OPD9_VDELAY :
-{0x6A7C,0x015F,0x02}, // AF_OPD9_HVALID :
-{0x6A7E,0x015F,0x02}, // AF_OPD9_VVALID :
-{0x6A80,0x05,0x01}, // AF_OPD1A_WEIGHT :
-{0x6A81,0x04,0x01}, // AF_OPD1B_WEIGHT :
-{0x6A82,0x03,0x01}, // AF_OPD2A_WEIGHT :
+{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,0x03,0x01}, // AF_OPD4A_WEIGHT :
-{0x6A87,0x02,0x01}, // AF_OPD4B_WEIGHT :
-{0x6A88,0x00,0x01}, // AF_OPD5A_WEIGHT :
-{0x6A89,0x00,0x01}, // AF_OPD5B_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
@@ -384,7 +386,7 @@ static const isx012_regset_t ISX012_Init_Reg[] =
{0x0328,0x52,0x01}, // SHTCTRLTIME2_TYPE1 :
{0x0329,0x23,0x01}, // AGCGAIN2_TYPE1 :
{0x032A,0x3E,0x01}, // SHTCTRLTIME3_TYPE1 :
-{0x032B,0x42,0x01}, // AGCGAIN3_TYPE1 :
+{0x032B,0x3F,0x01}, // AGCGAIN3_TYPE1 :
// normal preview AE line
{0x032C,0x7C,0x01}, // SHTCTRLTIME1_TYPE2
@@ -392,7 +394,7 @@ static const isx012_regset_t ISX012_Init_Reg[] =
{0x032E,0x7C,0x01}, // SHTCTRLTIME2_TYPE2
{0x032F,0x3D,0x01}, // AGCGAIN2_TYPE2
{0x0330,0x3E,0x01}, // SHTCTRLTIME3_TYPE2
-{0x0331,0x42,0x01}, // AGCGAIN3_TYPE2
+{0x0331,0x3F,0x01}, // AGCGAIN3_TYPE2
// flash ae line
{0x0332,0x42,0x01}, // SHTCTRLTIME1_TYPE3 :
@@ -403,7 +405,7 @@ static const isx012_regset_t ISX012_Init_Reg[] =
{0x0337,0x3C,0x01}, // AGCGAIN3_TYPE3 :
//sports ae line
-{0x0338,0x01,0x01}, // SHTCTRLTIME1_TYPE4
+{0x0338,0x00,0x01}, // SHTCTRLTIME1_TYPE4
{0x0339,0x14,0x01}, // AGCGAIN1_TYPE4
{0x033A,0x21,0x01}, // SHTCTRLTIME2_TYPE4
{0x033B,0x19,0x01}, // AGCGAIN2_TYPE4
@@ -424,7 +426,7 @@ static const isx012_regset_t ISX012_Init_Reg[] =
{0x0346,0xFF,0x01}, // SHTCTRLTIME2_TYPE6 :
{0x0347,0x00,0x01}, // AGCGAIN2_TYPE6 :
{0x0348,0xFA,0x01}, // SHTCTRLTIME3_TYPE6 :
-{0x0349,0x3D,0x01}, // AGCGAIN3_TYPE6 :
+{0x0349,0x3B,0x01}, // AGCGAIN3_TYPE6 :
// fire mode line
{0x0356,0x01,0x01}, // SHTCTRLTIME1_TYPE9 :
@@ -1084,9 +1086,9 @@ static const isx012_regset_t ISX012_Init_Reg[] =
{0x6E92,0x0000,0x02}, // IBYHUE4_POS1 :
{0x6E94,0xFFEC,0x02}, // IRYHUE4_POS1 :
{0x6E96,0x0000,0x02}, // IBYHUE1_POS2 :
-{0x6E98,0xFFF8,0x02}, // IRYHUE1_POS2 :
+{0x6E98,0xFFF5,0x02}, // IRYHUE1_POS2 :
{0x6E9A,0xFFFD,0x02}, // IBYHUE2_POS2 :
-{0x6E9C,0xFFF8,0x02}, // IRYHUE2_POS2 :
+{0x6E9C,0xFFF5,0x02}, // IRYHUE2_POS2 :
{0x6E9E,0xFFFD,0x02}, // IBYHUE3_POS2 :
{0x6EA0,0xFFEE,0x02}, // IRYHUE3_POS2 :
{0x6EA2,0x0000,0x02}, // IBYHUE4_POS2 :
@@ -2369,22 +2371,8 @@ static const isx012_regset_t ISX012_Init_Reg[] =
{0x62A4,0x92,0x01}, // IN_LUMST : 146
{0x62A5,0x9C,0x01}, // OUT_LUMST : 156
-//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 :
-{0x005E,0xA6A6,0x02}, /* for ESD check */
+//ISO output setting
+{0x5E3F,0x00,0x01}, // ISOSENS_OUT_SEL :
};
// ISX012-0
@@ -2861,6 +2849,11 @@ static const isx012_regset_t ISX012_Preview_SizeSetting[] =
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
@@ -4068,9 +4061,9 @@ static const isx012_regset_t ISX012_Camcorder_Mode_OFF[] = {
static const isx012_regset_t ISX012_Halfrelease_Mode[] =
{
-{0x00B1,0x01,0x01}, //AF_RESTART_F
+{0x00B2,0x03,0x01}, //AFMODE_MONI : AF OFF
{0x00B3,0x00,0x01}, //AFMODE_HREL :
-{0xFFFF,0x21,0x01},//$wait, 33
+{0xFFFF,0x42,0x01},//$wait, 66
{0x0081,0x01,0x01}, //MODESEL
};
@@ -4083,14 +4076,8 @@ static const isx012_regset_t ISX012_Barcode_SAF[] =
static const isx012_regset_t ISX012_Lowlux_night_Halfrelease_Mode[] =
{
-/*++ Disable mipi high clock */
-#if 0
-/* {0x6A9E,0x0AE0,0x02},*/ /* HMAX_1_1*/
-/* {0x00AC,0x02,0x01},*/ /* */
-#endif
-/*-- Disable mipi high clock */
-{0x660E,0x09,0x01}, // AF_HBPF_PEAK_OPD_TH_MIN
-{0x6610,0x09,0x01}, // AF_HBPF_PEAK_OPD_TH_MAX
+{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
@@ -4147,7 +4134,7 @@ static const isx012_regset_t ISX012_AF_Macro_ON[] =
static const isx012_regset_t ISX012_AF_SAF[] =
{
-{0x00B1,0x01,0x01}, //AF_RESTART_F
+{0x00B2,0x03,0x01}, //AFMODE_MONI : AF OFF
{0x00B3,0x00,0x01}, //AFMODE_HREL :
{0xFFFF,0x21,0x01},//$wait, 33
{0x0081,0x01,0x01}, //MODESEL
@@ -4155,16 +4142,16 @@ static const isx012_regset_t ISX012_AF_SAF[] =
static const isx012_regset_t ISX012_AF_SAF_OFF[] =
{
+{0xFFFF,0x42,0x01},//$wait, 66
{0x00B2,0x03,0x01}, //AFMODE_MONI : AF OFF
{0x00B3,0x03,0x01}, //AFMODE_HREL : AF OFF
-{0xFFFF,0x21,0x01}, //$wait,33
};
static const isx012_regset_t ISX012_AF_TouchSAF_OFF[] =
{
+{0xFFFF,0x42,0x01},//$wait, 66
{0x00B2,0x03,0x01}, //AFMODE_MONI : AF OFF
{0x00B3,0x03,0x01}, //AFMODE_HREL : AF OFF
-{0xFFFF,0x21,0x01}, //$wait,33
{0x0081,0x00,0x01}, //MODESEL
};
@@ -4215,24 +4202,24 @@ static const isx012_regset_t ISX012_AF_Window_Reset[] =
{0x6A6A,0x052C,0x02}, // AF_OPD7_VDELAY :
{0x6A6C,0x01AE,0x02}, // AF_OPD7_HVALID :
{0x6A6E,0x01AE,0x02}, // AF_OPD7_VVALID :
-{0x6A70,0x04C6,0x02}, // AF_OPD8_HDELAY :
-{0x6A72,0x0493,0x02}, // AF_OPD8_VDELAY :
-{0x6A74,0x00E6,0x02}, // AF_OPD8_HVALID :
-{0x6A76,0x00E6,0x02}, // AF_OPD8_VVALID :
-{0x6A78,0x048A,0x02}, // AF_OPD9_HDELAY :
-{0x6A7A,0x0457,0x02}, // AF_OPD9_VDELAY :
-{0x6A7C,0x015F,0x02}, // AF_OPD9_HVALID :
-{0x6A7E,0x015F,0x02}, // AF_OPD9_VVALID :
-{0x6A80,0x05,0x01}, // AF_OPD1A_WEIGHT :
-{0x6A81,0x04,0x01}, // AF_OPD1B_WEIGHT :
-{0x6A82,0x03,0x01}, // AF_OPD2A_WEIGHT :
+{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,0x03,0x01}, // AF_OPD4A_WEIGHT :
-{0x6A87,0x02,0x01}, // AF_OPD4B_WEIGHT :
-{0x6A88,0x00,0x01}, // AF_OPD5A_WEIGHT :
-{0x6A89,0x00,0x01}, // AF_OPD5B_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 :
};
@@ -4277,6 +4264,17 @@ 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
@@ -4287,6 +4285,11 @@ 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
@@ -4429,23 +4432,21 @@ static const isx012_regset_t ISX012_Capture_Mode[] =
{0x0012,0xFF,0x01}, //INTCLR0
{0x0081,0x02,0x01}, //MODESEL
{0x0082,0x01,0x01}, //MONI_REFRESH
-{0xFFFF,0x42,0x01}, //$wait,66
};
static const isx012_regset_t ISX012_Lowlux_Night_Capture_Mode[] =
{
{0x03A0,0xA0,0x01}, //UISATURATION_TYPE3 :
-{0x039D,0xF6,0x01}, //UIHUE_TYPE3 :
+{0x039D,0xF4,0x01}, //UIHUE_TYPE3 :
{0x982A,0xFFD8,0x02}, // CS_CBLLEV_A :
{0x9830,0xFFD8,0x02}, // CS_CRLLEV_A :
-{0x9805,0x08,0x01}, // CS_SLP_C_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
-{0xFFFF,0x03E8,0x01}, //$wait,1s
};
static const isx012_regset_t isx012_Saturation_Default[] =
@@ -4478,8 +4479,8 @@ static const isx012_regset_t isx012_Scene_Default[] =
{0x02A8,0x00,0x01}, //ISO_TYPE1 : Auto
{0x5E06,0x02,0x01}, //SHTCTRLMAG3
{0x038F,0x00,0x01}, //PICT1_SN1 :
-{0x6742,0x0024,0x02}, // AF_SEARCH_OFFSET_FAR :
-{0x6744,0x0024,0x02}, // AF_SEARCH_OFFSET_NEAR :
+{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
};
@@ -4492,8 +4493,8 @@ static const isx012_regset_t isx012_Scene_Landscape[] =
{0x03A6,0x2C,0x01}, //UISHARPNESS_NEG_TYPE3 : +1
{0x5E06,0x02,0x01}, //SHTCTRLMAG3
{0x038F,0x00,0x01}, //PICT1_SN1 :
-{0x6742,0x0024,0x02}, // AF_SEARCH_OFFSET_FAR :
-{0x6744,0x0024,0x02}, // AF_SEARCH_OFFSET_NEAR :
+{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
};
@@ -4503,8 +4504,8 @@ static const isx012_regset_t isx012_Scene_Sports[] =
{0x02A8,0x00,0x01}, //ISO_TYPE1 : Auto
{0x5E06,0x02,0x01}, //SHTCTRLMAG3
{0x038F,0x00,0x01}, //PICT1_SN1 :
-{0x6742,0x0024,0x02}, // AF_SEARCH_OFFSET_FAR :
-{0x6744,0x0024,0x02}, // AF_SEARCH_OFFSET_NEAR :
+{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
};
@@ -4515,8 +4516,8 @@ static const isx012_regset_t isx012_Scene_Party_Indoor[] =
{0x039F,0x9E,0x01}, //UISATURATION_TYPE2 :
{0x5E06,0x02,0x01}, //SHTCTRLMAG3
{0x038F,0x04,0x01}, //PICT1_SN1 :
-{0x6742,0x0024,0x02}, // AF_SEARCH_OFFSET_FAR :
-{0x6744,0x0024,0x02}, // AF_SEARCH_OFFSET_NEAR :
+{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
};
@@ -4527,8 +4528,8 @@ static const isx012_regset_t isx012_Scene_Beach_Snow[] =
{0x039F,0x9E,0x01}, //UISATURATION_TYPE2 :
{0x5E06,0x02,0x01}, //SHTCTRLMAG3
{0x038F,0x00,0x01}, //PICT1_SN1 :
-{0x6742,0x0024,0x02}, // AF_SEARCH_OFFSET_FAR :
-{0x6744,0x0024,0x02}, // AF_SEARCH_OFFSET_NEAR :
+{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
};
@@ -4540,8 +4541,8 @@ static const isx012_regset_t isx012_Scene_Sunset[] =
{0x0394,0x00,0x01}, //PICT1_SN6 :
{0x5E06,0x02,0x01}, //SHTCTRLMAG3
{0x038F,0x00,0x01}, //PICT1_SN1 :
-{0x6742,0x0024,0x02}, // AF_SEARCH_OFFSET_FAR :
-{0x6744,0x0024,0x02}, // AF_SEARCH_OFFSET_NEAR :
+{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
};
@@ -4553,8 +4554,8 @@ static const isx012_regset_t isx012_Scene_Duskdawn[] =
{0x0394,0x00,0x01}, //PICT1_SN6 :
{0x5E06,0x02,0x01}, //SHTCTRLMAG3
{0x038F,0x00,0x01}, //PICT1_SN1 :
-{0x6742,0x0024,0x02}, // AF_SEARCH_OFFSET_FAR :
-{0x6744,0x0024,0x02}, // AF_SEARCH_OFFSET_NEAR :
+{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
};
@@ -4566,8 +4567,8 @@ static const isx012_regset_t isx012_Scene_Candle_Light[] =
{0x0394,0x00,0x01}, //PICT1_SN6 :
{0x5E06,0x02,0x01}, //SHTCTRLMAG3
{0x038F,0x00,0x01}, //PICT1_SN1 :
-{0x6742,0x0024,0x02}, // AF_SEARCH_OFFSET_FAR :
-{0x6744,0x0024,0x02}, // AF_SEARCH_OFFSET_NEAR :
+{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
};
@@ -4580,8 +4581,8 @@ static const isx012_regset_t isx012_Scene_Fall_Color[] =
{0x0394,0x04,0x01}, //PICT1_SN6 :
{0x5E06,0x02,0x01}, //SHTCTRLMAG3
{0x038F,0x00,0x01}, //PICT1_SN1 :
-{0x6742,0x0024,0x02}, // AF_SEARCH_OFFSET_FAR :
-{0x6744,0x0024,0x02}, // AF_SEARCH_OFFSET_NEAR :
+{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
};
@@ -4591,8 +4592,8 @@ static const isx012_regset_t isx012_Scene_Portrait[] =
{0x02A8,0x00,0x01}, //ISO_TYPE1 : Auto
{0x5E06,0x02,0x01}, //SHTCTRLMAG3
{0x038F,0x50,0x01}, //PICT1_SN1 :
-{0x6742,0x0024,0x02}, // AF_SEARCH_OFFSET_FAR :
-{0x6744,0x0024,0x02}, // AF_SEARCH_OFFSET_NEAR :
+{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
};
@@ -4602,8 +4603,8 @@ static const isx012_regset_t isx012_Scene_Nightshot[] =
{0x02A8,0x00,0x01}, //ISO_TYPE1 : Auto
{0x5E06,0x02,0x01}, //SHTCTRLMAG3
{0x038F,0x00,0x01}, //PICT1_SN1 :
-{0x6742,0x000C,0x02}, // AF_SEARCH_OFFSET_FAR :
-{0x6744,0x000C,0x02}, // AF_SEARCH_OFFSET_NEAR :
+{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
};
@@ -4613,8 +4614,8 @@ static const isx012_regset_t isx012_Scene_Fireworks[] =
{0x02A8,0x00,0x01}, //ISO_TYPE1 : AUTO
{0x5E06,0x04,0x01}, //SHTCTRLMAG3
{0x038F,0x00,0x01}, //PICT1_SN1 :
-{0x6742,0x000C,0x02}, // AF_SEARCH_OFFSET_FAR :
-{0x6744,0x000C,0x02}, // AF_SEARCH_OFFSET_NEAR :
+{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
};
@@ -4626,8 +4627,8 @@ static const isx012_regset_t isx012_Scene_Text[] =
{0x03A6,0x38,0x01}, //UISHARPNESS_NEG_TYPE3 : +2
{0x5E06,0x02,0x01}, //SHTCTRLMAG3
{0x038F,0xA0,0x01}, //PICT1_SN1 :
-{0x6742,0x0024,0x02}, // AF_SEARCH_OFFSET_FAR :
-{0x6744,0x0024,0x02}, // AF_SEARCH_OFFSET_NEAR :
+{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
};
@@ -4637,8 +4638,8 @@ static const isx012_regset_t isx012_Scene_Backlight[] =
{0x02A8,0x00,0x01}, //ISO_TYPE1 : Auto
{0x5E06,0x02,0x01}, //SHTCTRLMAG3
{0x038F,0x00,0x01}, //PICT1_SN1 :
-{0x6742,0x0024,0x02}, // AF_SEARCH_OFFSET_FAR :
-{0x6744,0x0024,0x02}, // AF_SEARCH_OFFSET_NEAR :
+{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
};
@@ -4725,14 +4726,17 @@ static const isx012_regset_t ISX012_Image_Quality_Table[] =
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},
-{0x6666,0x0000,0x02},
-{0x6648,0x0020,0x02}, /* AF_MANUAL_POS : MANUA AF search start position */
-{0xFFFF,0x01,0x01}, //$wait, 1
+{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,0x96,0x01}, //$wait, 150
+{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[] =
@@ -4750,7 +4754,6 @@ 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[] =
@@ -4804,6 +4807,11 @@ 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
@@ -5027,6 +5035,12 @@ static const isx012_regset_t isx012_fps_auto[] =
{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 */
@@ -6048,81 +6062,81 @@ static const isx012_regset_t ISX012_Shading_Nocal[] =
//SHD2 CW+TL84 33:66
{0xED00,0x9191,0x02},//
-{0xEF54,0x21,0x01},
-{0xEF55,0x92,0x01},
-{0xEF56,0xD1,0x01},
-{0xEF57,0x8A,0x01},
-{0xEF58,0x3E,0x01},
-{0xEF59,0xF4,0x01},
-{0xEF5A,0xA1,0x01},
-{0xEF5B,0x10,0x01},
-{0xEF5C,0xB9,0x01},
-{0xEF5D,0x48,0x01},
-{0xEF5E,0x46,0x01},
-{0xEF5F,0x1F,0x01},
-{0xEF60,0x82,0x01},
+{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,0x7E,0x01},
-{0xEF63,0xBC,0x01},
-{0xEF64,0xC3,0x01},
+{0xEF62,0x7F,0x01},
+{0xEF63,0xC2,0x01},
+{0xEF64,0xF3,0x01},
{0xEF65,0x1C,0x01},
-{0xEF66,0xE3,0x01},
-{0xEF67,0x38,0x01},
-{0xEF68,0xC7,0x01},
-{0xEF69,0x3B,0x01},
-{0xEF6A,0xF7,0x01},
-{0xEF6B,0x71,0x01},
+{0xEF66,0xE4,0x01},
+{0xEF67,0x40,0x01},
+{0xEF68,0x27,0x01},
+{0xEF69,0x3C,0x01},
+{0xEF6A,0xFB,0x01},
+{0xEF6B,0xA1,0x01},
{0xEF6C,0x90,0x01},
-{0xEF6D,0x7B,0x01},
-{0xEF6E,0x8E,0x01},
-{0xEF6F,0x53,0x01},
-{0xEF70,0x1A,0x01},
+{0xEF6D,0x7C,0x01},
+{0xEF6E,0x92,0x01},
+{0xEF6F,0x63,0x01},
+{0xEF70,0x9A,0x01},
{0xEF71,0xC5,0x01},
-{0xEF72,0x04,0x01},
-{0xEF73,0x46,0x01},
+{0xEF72,0x0C,0x01},
+{0xEF73,0x66,0x01},
{0xEF74,0x31,0x01},
-{0xEF75,0xA2,0x01},
-{0xEF76,0x39,0x01},
+{0xEF75,0xA4,0x01},
+{0xEF76,0x49,0x01},
{0xEF77,0x0E,0x01},
-{0xEF78,0x7E,0x01},
-{0xEF79,0x9A,0x01},
-{0xEF7A,0xA3,0x01},
-{0xEF7B,0x99,0x01},
-{0xEF7C,0xB5,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,0x8B,0x01},
-{0xEF83,0x67,0x01},
-{0xEF84,0xB0,0x01},
-{0xEF85,0x53,0x01},
-{0xEF86,0x1B,0x01},
+{0xEF82,0x0B,0x01},
+{0xEF83,0x68,0x01},
+{0xEF84,0xB6,0x01},
+{0xEF85,0x73,0x01},
+{0xEF86,0x9B,0x01},
{0xEF87,0xBB,0x01},
-{0xEF88,0x08,0x01},
+{0xEF88,0x0C,0x01},
{0xEF89,0x45,0x01},
{0xEF8A,0x24,0x01},
{0xEF8B,0x17,0x01},
{0xEF8C,0x11,0x01},
-{0xEF8D,0x09,0x01},
+{0xEF8D,0x49,0x01},
{0xEF8E,0x51,0x01},
-{0xEF8F,0xF2,0x01},
-{0xEF90,0xA2,0x01},
-{0xEF91,0x9B,0x01},
-{0xEF92,0xD3,0x01},
-{0xEF93,0x90,0x01},
+{0xEF8F,0xF4,0x01},
+{0xEF90,0xC2,0x01},
+{0xEF91,0x1B,0x01},
+{0xEF92,0xD4,0x01},
+{0xEF93,0x94,0x01},
{0xEF94,0xC5,0x01},
{0xEF95,0x25,0x01},
-{0xEF96,0x0A,0x01},
+{0xEF96,0x0B,0x01},
{0xEF97,0x01,0x01},
{0xEF98,0x48,0x01},
{0xEF99,0x43,0x01},
{0xEF9A,0x62,0x01},
-{0xEF9B,0x52,0x01},
-{0xEF9C,0x16,0x01},
+{0xEF9B,0x62,0x01},
+{0xEF9C,0x96,0x01},
{0xEF9D,0xD5,0x01},
-{0xEF9E,0x9C,0x01},
+{0xEF9E,0xA4,0x01},
{0xEF9F,0xC6,0x01},
{0xEFA0,0x2C,0x01},
{0xEFA1,0x2F,0x01},
@@ -6131,71 +6145,71 @@ static const isx012_regset_t ISX012_Shading_Nocal[] =
{0xEFA4,0x40,0x01},
{0xEFA5,0x1C,0x01},
{0xEFA6,0x22,0x01},
-{0xEFA7,0x93,0x01},
-{0xEFA8,0xB3,0x01},
-{0xEFA9,0xB8,0x01},
-{0xEFAA,0x46,0x01},
+{0xEFA7,0x13,0x01},
+{0xEFA8,0xB4,0x01},
+{0xEFA9,0xC0,0x01},
+{0xEFAA,0x86,0x01},
{0xEFAB,0x37,0x01},
-{0xEFAC,0x7A,0x01},
-{0xEFAD,0x21,0x01},
-{0xEFAE,0x4A,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,0xF0,0x01},
-{0xEFB5,0xE5,0x01},
-{0xEFB6,0x37,0x01},
-{0xEFB7,0xD6,0x01},
-{0xEFB8,0xF9,0x01},
-{0xEFB9,0x8C,0x01},
+{0xEFB4,0xF4,0x01},
+{0xEFB5,0x25,0x01},
+{0xEFB6,0x38,0x01},
+{0xEFB7,0xD9,0x01},
+{0xEFB8,0x01,0x01},
+{0xEFB9,0xCD,0x01},
{0xEFBA,0x5B,0x01},
-{0xEFBB,0x9E,0x01},
-{0xEFBC,0x62,0x01},
+{0xEFBB,0xA0,0x01},
+{0xEFBC,0x72,0x01},
{0xEFBD,0x14,0x01},
{0xEFBE,0xA9,0x01},
-{0xEFBF,0xC8,0x01},
-{0xEFC0,0xA5,0x01},
+{0xEFBF,0xCC,0x01},
+{0xEFC0,0xC5,0x01},
{0xEFC1,0x34,0x01},
-{0xEFC2,0xE0,0x01},
-{0xEFC3,0xD1,0x01},
-{0xEFC4,0x8F,0x01},
-{0xEFC5,0x73,0x01},
-{0xEFC6,0x4C,0x01},
-{0xEFC7,0xE3,0x01},
-{0xEFC8,0x18,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,0x3C,0x01},
-{0xEFCB,0x46,0x01},
+{0xEFCA,0x40,0x01},
+{0xEFCB,0x86,0x01},
{0xEFCC,0x35,0x01},
-{0xEFCD,0xD2,0x01},
-{0xEFCE,0x09,0x01},
-{0xEFCF,0x90,0x01},
-{0xEFD0,0x85,0x01},
-{0xEFD1,0xF6,0x01},
-{0xEFD2,0x03,0x01},
-{0xEFD3,0x1E,0x01},
-{0xEFD4,0xE7,0x01},
-{0xEFD5,0x20,0x01},
-{0xEFD6,0x27,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,0xE4,0x01},
-{0xEFD9,0x01,0x01},
-{0xEFDA,0x90,0x01},
-{0xEFDB,0x87,0x01},
-{0xEFDC,0x30,0x01},
-{0xEFDD,0x04,0x01},
-{0xEFDE,0x22,0x01},
-{0xEFDF,0x0B,0x01},
-{0xEFE0,0x2D,0x01},
-{0xEFE1,0x28,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,0x10,0x01},
-{0xEFE4,0xDA,0x01},
-{0xEFE5,0x90,0x01},
-{0xEFE6,0x88,0x01},
-{0xEFE7,0x3C,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},
@@ -6204,7 +6218,6 @@ static const isx012_regset_t ISX012_Shading_Nocal[] =
{0xEFED,0x00,0x01},
-
//SHD3 D65+TL84 C01//
{0xED00,0x9191,0x02},//
{0xEFEE,0x12,0x01},
@@ -7519,81 +7532,81 @@ static const isx012_regset_t ISX012_Shading_0[] =
//SHD2 CW+TL84 33:66
{0xED00,0x9191,0x02},//
-{0xEF54,0x21,0x01},
-{0xEF55,0x92,0x01},
-{0xEF56,0xD1,0x01},
-{0xEF57,0x8A,0x01},
-{0xEF58,0x3E,0x01},
-{0xEF59,0xF4,0x01},
-{0xEF5A,0xA1,0x01},
-{0xEF5B,0x10,0x01},
-{0xEF5C,0xB9,0x01},
-{0xEF5D,0x48,0x01},
-{0xEF5E,0x46,0x01},
-{0xEF5F,0x1F,0x01},
-{0xEF60,0x82,0x01},
+{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,0x7E,0x01},
-{0xEF63,0xBC,0x01},
-{0xEF64,0xC3,0x01},
+{0xEF62,0x7F,0x01},
+{0xEF63,0xC2,0x01},
+{0xEF64,0xF3,0x01},
{0xEF65,0x1C,0x01},
-{0xEF66,0xE3,0x01},
-{0xEF67,0x38,0x01},
-{0xEF68,0xC7,0x01},
-{0xEF69,0x3B,0x01},
-{0xEF6A,0xF7,0x01},
-{0xEF6B,0x71,0x01},
+{0xEF66,0xE4,0x01},
+{0xEF67,0x40,0x01},
+{0xEF68,0x27,0x01},
+{0xEF69,0x3C,0x01},
+{0xEF6A,0xFB,0x01},
+{0xEF6B,0xA1,0x01},
{0xEF6C,0x90,0x01},
-{0xEF6D,0x7B,0x01},
-{0xEF6E,0x8E,0x01},
-{0xEF6F,0x53,0x01},
-{0xEF70,0x1A,0x01},
+{0xEF6D,0x7C,0x01},
+{0xEF6E,0x92,0x01},
+{0xEF6F,0x63,0x01},
+{0xEF70,0x9A,0x01},
{0xEF71,0xC5,0x01},
-{0xEF72,0x04,0x01},
-{0xEF73,0x46,0x01},
+{0xEF72,0x0C,0x01},
+{0xEF73,0x66,0x01},
{0xEF74,0x31,0x01},
-{0xEF75,0xA2,0x01},
-{0xEF76,0x39,0x01},
+{0xEF75,0xA4,0x01},
+{0xEF76,0x49,0x01},
{0xEF77,0x0E,0x01},
-{0xEF78,0x7E,0x01},
-{0xEF79,0x9A,0x01},
-{0xEF7A,0xA3,0x01},
-{0xEF7B,0x99,0x01},
-{0xEF7C,0xB5,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,0x8B,0x01},
-{0xEF83,0x67,0x01},
-{0xEF84,0xB0,0x01},
-{0xEF85,0x53,0x01},
-{0xEF86,0x1B,0x01},
+{0xEF82,0x0B,0x01},
+{0xEF83,0x68,0x01},
+{0xEF84,0xB6,0x01},
+{0xEF85,0x73,0x01},
+{0xEF86,0x9B,0x01},
{0xEF87,0xBB,0x01},
-{0xEF88,0x08,0x01},
+{0xEF88,0x0C,0x01},
{0xEF89,0x45,0x01},
{0xEF8A,0x24,0x01},
{0xEF8B,0x17,0x01},
{0xEF8C,0x11,0x01},
-{0xEF8D,0x09,0x01},
+{0xEF8D,0x49,0x01},
{0xEF8E,0x51,0x01},
-{0xEF8F,0xF2,0x01},
-{0xEF90,0xA2,0x01},
-{0xEF91,0x9B,0x01},
-{0xEF92,0xD3,0x01},
-{0xEF93,0x90,0x01},
+{0xEF8F,0xF4,0x01},
+{0xEF90,0xC2,0x01},
+{0xEF91,0x1B,0x01},
+{0xEF92,0xD4,0x01},
+{0xEF93,0x94,0x01},
{0xEF94,0xC5,0x01},
{0xEF95,0x25,0x01},
-{0xEF96,0x0A,0x01},
+{0xEF96,0x0B,0x01},
{0xEF97,0x01,0x01},
{0xEF98,0x48,0x01},
{0xEF99,0x43,0x01},
{0xEF9A,0x62,0x01},
-{0xEF9B,0x52,0x01},
-{0xEF9C,0x16,0x01},
+{0xEF9B,0x62,0x01},
+{0xEF9C,0x96,0x01},
{0xEF9D,0xD5,0x01},
-{0xEF9E,0x9C,0x01},
+{0xEF9E,0xA4,0x01},
{0xEF9F,0xC6,0x01},
{0xEFA0,0x2C,0x01},
{0xEFA1,0x2F,0x01},
@@ -7602,71 +7615,71 @@ static const isx012_regset_t ISX012_Shading_0[] =
{0xEFA4,0x40,0x01},
{0xEFA5,0x1C,0x01},
{0xEFA6,0x22,0x01},
-{0xEFA7,0x93,0x01},
-{0xEFA8,0xB3,0x01},
-{0xEFA9,0xB8,0x01},
-{0xEFAA,0x46,0x01},
+{0xEFA7,0x13,0x01},
+{0xEFA8,0xB4,0x01},
+{0xEFA9,0xC0,0x01},
+{0xEFAA,0x86,0x01},
{0xEFAB,0x37,0x01},
-{0xEFAC,0x7A,0x01},
-{0xEFAD,0x21,0x01},
-{0xEFAE,0x4A,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,0xF0,0x01},
-{0xEFB5,0xE5,0x01},
-{0xEFB6,0x37,0x01},
-{0xEFB7,0xD6,0x01},
-{0xEFB8,0xF9,0x01},
-{0xEFB9,0x8C,0x01},
+{0xEFB4,0xF4,0x01},
+{0xEFB5,0x25,0x01},
+{0xEFB6,0x38,0x01},
+{0xEFB7,0xD9,0x01},
+{0xEFB8,0x01,0x01},
+{0xEFB9,0xCD,0x01},
{0xEFBA,0x5B,0x01},
-{0xEFBB,0x9E,0x01},
-{0xEFBC,0x62,0x01},
+{0xEFBB,0xA0,0x01},
+{0xEFBC,0x72,0x01},
{0xEFBD,0x14,0x01},
{0xEFBE,0xA9,0x01},
-{0xEFBF,0xC8,0x01},
-{0xEFC0,0xA5,0x01},
+{0xEFBF,0xCC,0x01},
+{0xEFC0,0xC5,0x01},
{0xEFC1,0x34,0x01},
-{0xEFC2,0xE0,0x01},
-{0xEFC3,0xD1,0x01},
-{0xEFC4,0x8F,0x01},
-{0xEFC5,0x73,0x01},
-{0xEFC6,0x4C,0x01},
-{0xEFC7,0xE3,0x01},
-{0xEFC8,0x18,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,0x3C,0x01},
-{0xEFCB,0x46,0x01},
+{0xEFCA,0x40,0x01},
+{0xEFCB,0x86,0x01},
{0xEFCC,0x35,0x01},
-{0xEFCD,0xD2,0x01},
-{0xEFCE,0x09,0x01},
-{0xEFCF,0x90,0x01},
-{0xEFD0,0x85,0x01},
-{0xEFD1,0xF6,0x01},
-{0xEFD2,0x03,0x01},
-{0xEFD3,0x1E,0x01},
-{0xEFD4,0xE7,0x01},
-{0xEFD5,0x20,0x01},
-{0xEFD6,0x27,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,0xE4,0x01},
-{0xEFD9,0x01,0x01},
-{0xEFDA,0x90,0x01},
-{0xEFDB,0x87,0x01},
-{0xEFDC,0x30,0x01},
-{0xEFDD,0x04,0x01},
-{0xEFDE,0x22,0x01},
-{0xEFDF,0x0B,0x01},
-{0xEFE0,0x2D,0x01},
-{0xEFE1,0x28,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,0x10,0x01},
-{0xEFE4,0xDA,0x01},
-{0xEFE5,0x90,0x01},
-{0xEFE6,0x88,0x01},
-{0xEFE7,0x3C,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},
@@ -7675,7 +7688,6 @@ static const isx012_regset_t ISX012_Shading_0[] =
{0xEFED,0x00,0x01},
-
//SHD3 D65+TL84 C01//
{0xED00,0x9191,0x02},//
{0xEFEE,0x12,0x01},
@@ -8990,154 +9002,154 @@ static const isx012_regset_t ISX012_Shading_1[] =
//SHD2 CW+TL84 33:66
{0xED00,0x9191,0x02},//
-{0xEF54,0x21,0x01},
-{0xEF55,0x92,0x01},
-{0xEF56,0xD1,0x01},
-{0xEF57,0x8A,0x01},
-{0xEF58,0x3E,0x01},
-{0xEF59,0xF4,0x01},
+{0xEF54,0x0B,0x01},
+{0xEF55,0xFA,0x01},
+{0xEF56,0x10,0x01},
+{0xEF57,0x87,0x01},
+{0xEF58,0x24,0x01},
+{0xEF59,0x24,0x01},
{0xEF5A,0xA1,0x01},
-{0xEF5B,0x10,0x01},
-{0xEF5C,0xB9,0x01},
-{0xEF5D,0x48,0x01},
-{0xEF5E,0x46,0x01},
-{0xEF5F,0x1F,0x01},
-{0xEF60,0x82,0x01},
-{0xEF61,0x10,0x01},
-{0xEF62,0x7E,0x01},
-{0xEF63,0xBC,0x01},
-{0xEF64,0xC3,0x01},
-{0xEF65,0x1C,0x01},
-{0xEF66,0xE3,0x01},
-{0xEF67,0x38,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,0x3B,0x01},
-{0xEF6A,0xF7,0x01},
-{0xEF6B,0x71,0x01},
-{0xEF6C,0x90,0x01},
-{0xEF6D,0x7B,0x01},
-{0xEF6E,0x8E,0x01},
-{0xEF6F,0x53,0x01},
-{0xEF70,0x1A,0x01},
-{0xEF71,0xC5,0x01},
-{0xEF72,0x04,0x01},
-{0xEF73,0x46,0x01},
-{0xEF74,0x31,0x01},
-{0xEF75,0xA2,0x01},
-{0xEF76,0x39,0x01},
-{0xEF77,0x0E,0x01},
-{0xEF78,0x7E,0x01},
-{0xEF79,0x9A,0x01},
-{0xEF7A,0xA3,0x01},
-{0xEF7B,0x99,0x01},
-{0xEF7C,0xB5,0x01},
-{0xEF7D,0x34,0x01},
-{0xEF7E,0x85,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,0x4D,0x01},
-{0xEF81,0x61,0x01},
+{0xEF80,0x4B,0x01},
+{0xEF81,0x49,0x01},
{0xEF82,0x8B,0x01},
-{0xEF83,0x67,0x01},
-{0xEF84,0xB0,0x01},
-{0xEF85,0x53,0x01},
-{0xEF86,0x1B,0x01},
-{0xEF87,0xBB,0x01},
-{0xEF88,0x08,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,0x17,0x01},
-{0xEF8C,0x11,0x01},
-{0xEF8D,0x09,0x01},
-{0xEF8E,0x51,0x01},
-{0xEF8F,0xF2,0x01},
-{0xEF90,0xA2,0x01},
-{0xEF91,0x9B,0x01},
-{0xEF92,0xD3,0x01},
-{0xEF93,0x90,0x01},
-{0xEF94,0xC5,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,0x62,0x01},
-{0xEF9B,0x52,0x01},
-{0xEF9C,0x16,0x01},
-{0xEF9D,0xD5,0x01},
-{0xEF9E,0x9C,0x01},
-{0xEF9F,0xC6,0x01},
+{0xEF9A,0x60,0x01},
+{0xEF9B,0x32,0x01},
+{0xEF9C,0x96,0x01},
+{0xEF9D,0xD2,0x01},
+{0xEF9E,0x88,0x01},
+{0xEF9F,0x66,0x01},
{0xEFA0,0x2C,0x01},
-{0xEFA1,0x2F,0x01},
+{0xEFA1,0x2E,0x01},
{0xEFA2,0x51,0x01},
{0xEFA3,0x48,0x01},
{0xEFA4,0x40,0x01},
{0xEFA5,0x1C,0x01},
-{0xEFA6,0x22,0x01},
+{0xEFA6,0x12,0x01},
{0xEFA7,0x93,0x01},
-{0xEFA8,0xB3,0x01},
-{0xEFA9,0xB8,0x01},
-{0xEFAA,0x46,0x01},
-{0xEFAB,0x37,0x01},
-{0xEFAC,0x7A,0x01},
-{0xEFAD,0x21,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,0xA4,0x01},
-{0xEFB4,0xF0,0x01},
-{0xEFB5,0xE5,0x01},
+{0xEFB3,0xA3,0x01},
+{0xEFB4,0xE4,0x01},
+{0xEFB5,0x25,0x01},
{0xEFB6,0x37,0x01},
-{0xEFB7,0xD6,0x01},
-{0xEFB8,0xF9,0x01},
-{0xEFB9,0x8C,0x01},
-{0xEFBA,0x5B,0x01},
-{0xEFBB,0x9E,0x01},
-{0xEFBC,0x62,0x01},
+{0xEFB7,0xCF,0x01},
+{0xEFB8,0xD1,0x01},
+{0xEFB9,0xCC,0x01},
+{0xEFBA,0x5A,0x01},
+{0xEFBB,0x9A,0x01},
+{0xEFBC,0x52,0x01},
{0xEFBD,0x14,0x01},
-{0xEFBE,0xA9,0x01},
-{0xEFBF,0xC8,0x01},
-{0xEFC0,0xA5,0x01},
+{0xEFBE,0xA8,0x01},
+{0xEFBF,0xC0,0x01},
+{0xEFC0,0x05,0x01},
{0xEFC1,0x34,0x01},
-{0xEFC2,0xE0,0x01},
-{0xEFC3,0xD1,0x01},
-{0xEFC4,0x8F,0x01},
-{0xEFC5,0x73,0x01},
-{0xEFC6,0x4C,0x01},
-{0xEFC7,0xE3,0x01},
-{0xEFC8,0x18,0x01},
-{0xEFC9,0xC2,0x01},
-{0xEFCA,0x3C,0x01},
-{0xEFCB,0x46,0x01},
-{0xEFCC,0x35,0x01},
-{0xEFCD,0xD2,0x01},
-{0xEFCE,0x09,0x01},
-{0xEFCF,0x90,0x01},
-{0xEFD0,0x85,0x01},
-{0xEFD1,0xF6,0x01},
-{0xEFD2,0x03,0x01},
-{0xEFD3,0x1E,0x01},
-{0xEFD4,0xE7,0x01},
-{0xEFD5,0x20,0x01},
-{0xEFD6,0x27,0x01},
-{0xEFD7,0x3A,0x01},
-{0xEFD8,0xE4,0x01},
-{0xEFD9,0x01,0x01},
-{0xEFDA,0x90,0x01},
-{0xEFDB,0x87,0x01},
-{0xEFDC,0x30,0x01},
-{0xEFDD,0x04,0x01},
-{0xEFDE,0x22,0x01},
-{0xEFDF,0x0B,0x01},
-{0xEFE0,0x2D,0x01},
-{0xEFE1,0x28,0x01},
-{0xEFE2,0x41,0x01},
-{0xEFE3,0x10,0x01},
-{0xEFE4,0xDA,0x01},
-{0xEFE5,0x90,0x01},
-{0xEFE6,0x88,0x01},
-{0xEFE7,0x3C,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},
@@ -9149,45 +9161,45 @@ static const isx012_regset_t ISX012_Shading_1[] =
//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},
+{0xEFEE,0x0B,0x01},
+{0xEFEF,0x12,0x01},
+{0xEFF0,0x11,0x01},
+{0xEFF1,0x88,0x01},
+{0xEFF2,0x2E,0x01},
+{0xEFF3,0x94,0x01},
{0xEFF4,0x21,0x01},
-{0xEFF5,0x10,0x01},
-{0xEFF6,0xAD,0x01},
-{0xEFF7,0xA8,0x01},
-{0xEFF8,0x45,0x01},
-{0xEFF9,0x18,0x01},
-{0xEFFA,0x4A,0x01},
+{0xEFF5,0x0E,0x01},
+{0xEFF6,0x99,0x01},
+{0xEFF7,0xE8,0x01},
+{0xEFF8,0x44,0x01},
+{0xEFF9,0x10,0x01},
+{0xEFFA,0x22,0x01},
{0xEFFB,0x50,0x01},
-{0xEFFC,0x7D,0x01},
-{0xEFFD,0xBA,0x01},
-{0xEFFE,0xD3,0x01},
+{0xEFFC,0x7C,0x01},
+{0xEFFD,0xB6,0x01},
+{0xEFFE,0xB3,0x01},
{0xEFFF,0x1C,0x01},
-{0xF000,0xE4,0x01},
-{0xF001,0x40,0x01},
-{0xF002,0x27,0x01},
-{0xF003,0x3C,0x01},
-{0xF004,0xF8,0x01},
-{0xF005,0x69,0x01},
+{0xF000,0xE3,0x01},
+{0xF001,0x38,0x01},
+{0xF002,0xC7,0x01},
+{0xF003,0x3B,0x01},
+{0xF004,0xF4,0x01},
+{0xF005,0x39,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},
+{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,0xA6,0x01},
-{0xF010,0x59,0x01},
-{0xF011,0x8E,0x01},
-{0xF012,0x7E,0x01},
-{0xF013,0x9A,0x01},
-{0xF014,0xB3,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},
@@ -9195,22 +9207,22 @@ static const isx012_regset_t ISX012_Shading_1[] =
{0xF019,0x28,0x01},
{0xF01A,0x4F,0x01},
{0xF01B,0x79,0x01},
-{0xF01C,0xCB,0x01},
+{0xF01C,0x8B,0x01},
{0xF01D,0x68,0x01},
-{0xF01E,0xBA,0x01},
-{0xF01F,0x53,0x01},
-{0xF020,0x9B,0x01},
+{0xF01E,0xB4,0x01},
+{0xF01F,0x43,0x01},
+{0xF020,0x1B,0x01},
{0xF021,0xBB,0x01},
{0xF022,0x0C,0x01},
-{0xF023,0x65,0x01},
+{0xF023,0x45,0x01},
{0xF024,0x24,0x01},
{0xF025,0x17,0x01},
-{0xF026,0x21,0x01},
+{0xF026,0x19,0x01},
{0xF027,0xC9,0x01},
{0xF028,0x51,0x01},
-{0xF029,0xFC,0x01},
-{0xF02A,0xF2,0x01},
-{0xF02B,0x9B,0x01},
+{0xF029,0xFA,0x01},
+{0xF02A,0xD2,0x01},
+{0xF02B,0x1B,0x01},
{0xF02C,0xD3,0x01},
{0xF02D,0x94,0x01},
{0xF02E,0xC5,0x01},
@@ -9220,11 +9232,11 @@ static const isx012_regset_t ISX012_Shading_1[] =
{0xF032,0x48,0x01},
{0xF033,0x43,0x01},
{0xF034,0x66,0x01},
-{0xF035,0x92,0x01},
+{0xF035,0x82,0x01},
{0xF036,0x96,0x01},
-{0xF037,0xD7,0x01},
-{0xF038,0xA0,0x01},
-{0xF039,0xE6,0x01},
+{0xF037,0xD6,0x01},
+{0xF038,0x98,0x01},
+{0xF039,0xC6,0x01},
{0xF03A,0x2C,0x01},
{0xF03B,0x2F,0x01},
{0xF03C,0x51,0x01},
@@ -9232,12 +9244,12 @@ static const isx012_regset_t ISX012_Shading_1[] =
{0xF03E,0x40,0x01},
{0xF03F,0x1E,0x01},
{0xF040,0x42,0x01},
-{0xF041,0x93,0x01},
+{0xF041,0x13,0x01},
{0xF042,0xB5,0x01},
-{0xF043,0xCC,0x01},
-{0xF044,0x46,0x01},
+{0xF043,0xC8,0x01},
+{0xF044,0x06,0x01},
{0xF045,0x37,0x01},
-{0xF046,0x7C,0x01},
+{0xF046,0x7B,0x01},
{0xF047,0x29,0x01},
{0xF048,0x8A,0x01},
{0xF049,0x48,0x01},
@@ -9245,58 +9257,58 @@ static const isx012_regset_t ISX012_Shading_1[] =
{0xF04B,0x72,0x01},
{0xF04C,0x12,0x01},
{0xF04D,0xA5,0x01},
-{0xF04E,0x00,0x01},
-{0xF04F,0xA6,0x01},
+{0xF04E,0xFC,0x01},
+{0xF04F,0x65,0x01},
{0xF050,0x38,0x01},
-{0xF051,0xD7,0x01},
-{0xF052,0x01,0x01},
-{0xF053,0x0D,0x01},
-{0xF054,0x5C,0x01},
-{0xF055,0xA2,0x01},
+{0xF051,0xD4,0x01},
+{0xF052,0xF9,0x01},
+{0xF053,0xCC,0x01},
+{0xF054,0x5B,0x01},
+{0xF055,0xA0,0x01},
{0xF056,0x82,0x01},
-{0xF057,0x94,0x01},
+{0xF057,0x14,0x01},
{0xF058,0xAA,0x01},
-{0xF059,0xD8,0x01},
-{0xF05A,0x45,0x01},
+{0xF059,0xD4,0x01},
+{0xF05A,0x05,0x01},
{0xF05B,0x35,0x01},
-{0xF05C,0xE5,0x01},
-{0xF05D,0xC9,0x01},
-{0xF05E,0xCF,0x01},
+{0xF05C,0xE2,0x01},
+{0xF05D,0xA9,0x01},
+{0xF05E,0x4F,0x01},
{0xF05F,0x73,0x01},
-{0xF060,0x50,0x01},
-{0xF061,0x03,0x01},
-{0xF062,0x99,0x01},
+{0xF060,0x4E,0x01},
+{0xF061,0xF3,0x01},
+{0xF062,0x18,0x01},
{0xF063,0xC3,0x01},
-{0xF064,0x4C,0x01},
-{0xF065,0xE6,0x01},
+{0xF064,0x48,0x01},
+{0xF065,0xC6,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},
+{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,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},
+{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},
@@ -9472,8 +9484,8 @@ static const isx012_regset_t ISX012_Shading_1[] =
//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 :
+{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
@@ -9864,136 +9876,136 @@ static const isx012_regset_t ISX012_Shading_2[] =
//SHD1(from CO1)
{0xED02,0xE6,0x01},
-{0xED03,0x61,0x01},
+{0xED03,0xD9,0x01},
{0xED04,0x92,0x01},
{0xED05,0x7C,0x01},
-{0xED06,0xBE,0x01},
+{0xED06,0xD8,0x01},
{0xED07,0xB4,0x01},
-{0xED08,0x9E,0x01},
-{0xED09,0x2C,0x01},
+{0xED08,0x1E,0x01},
+{0xED09,0x32,0x01},
{0xED0A,0x75,0x01},
-{0xED0B,0x47,0x01},
-{0xED0C,0x49,0x01},
+{0xED0B,0x67,0x01},
+{0xED0C,0x4A,0x01},
{0xED0D,0xD7,0x01},
-{0xED0E,0x61,0x01},
+{0xED0E,0xA9,0x01},
{0xED0F,0x12,0x01},
{0xED10,0x76,0x01},
-{0xED11,0xA8,0x01},
+{0xED11,0xBC,0x01},
{0xED12,0x34,0x01},
{0xED13,0x1E,0x01},
-{0xED14,0x31,0x01},
+{0xED14,0x37,0x01},
{0xED15,0xA1,0x01},
-{0xED16,0xC7,0x01},
-{0xED17,0x4C,0x01},
+{0xED16,0x87,0x01},
+{0xED17,0x4E,0x01},
{0xED18,0xDE,0x01},
-{0xED19,0xC1,0x01},
-{0xED1A,0xD2,0x01},
+{0xED19,0x41,0x01},
+{0xED1A,0xD3,0x01},
{0xED1B,0x77,0x01},
-{0xED1C,0x76,0x01},
+{0xED1C,0x8C,0x01},
{0xED1D,0x94,0x01},
{0xED1E,0x9C,0x01},
-{0xED1F,0x10,0x01},
+{0xED1F,0x14,0x01},
{0xED20,0xC9,0x01},
-{0xED21,0xC6,0x01},
-{0xED22,0x40,0x01},
+{0xED21,0xA6,0x01},
+{0xED22,0x41,0x01},
{0xED23,0xA2,0x01},
-{0xED24,0x99,0x01},
+{0xED24,0xC1,0x01},
{0xED25,0x8F,0x01},
{0xED26,0x66,0x01},
-{0xED27,0xDC,0x01},
+{0xED27,0xE6,0x01},
{0xED28,0xF3,0x01},
{0xED29,0x19,0x01},
-{0xED2A,0xFC,0x01},
+{0xED2A,0xFF,0x01},
{0xED2B,0xB0,0x01},
-{0xED2C,0xA6,0x01},
-{0xED2D,0x41,0x01},
+{0xED2C,0x66,0x01},
+{0xED2D,0x42,0x01},
{0xED2E,0xC1,0x01},
-{0xED2F,0x49,0x01},
+{0xED2F,0x91,0x01},
{0xED30,0x91,0x01},
{0xED31,0x75,0x01},
-{0xED32,0x8C,0x01},
+{0xED32,0xA2,0x01},
{0xED33,0x74,0x01},
{0xED34,0x1C,0x01},
-{0xED35,0x0B,0x01},
+{0xED35,0x0F,0x01},
{0xED36,0x91,0x01},
-{0xED37,0x86,0x01},
-{0xED38,0x3D,0x01},
+{0xED37,0x26,0x01},
+{0xED38,0x3E,0x01},
{0xED39,0x87,0x01},
-{0xED3A,0x39,0x01},
+{0xED3A,0x51,0x01},
{0xED3B,0x4E,0x01},
{0xED3C,0x5C,0x01},
-{0xED3D,0x50,0x01},
+{0xED3D,0x54,0x01},
{0xED3E,0x83,0x01},
-{0xED3F,0x16,0x01},
-{0xED40,0xCF,0x01},
+{0xED3F,0x96,0x01},
+{0xED40,0xD0,0x01},
{0xED41,0xBC,0x01},
-{0xED42,0x45,0x01},
+{0xED42,0xA5,0x01},
{0xED43,0x35,0x01},
{0xED44,0x83,0x01},
-{0xED45,0x41,0x01},
+{0xED45,0x61,0x01},
{0xED46,0xCE,0x01},
{0xED47,0x67,0x01},
-{0xED48,0xE8,0x01},
+{0xED48,0xF2,0x01},
{0xED49,0x33,0x01},
{0xED4A,0x1C,0x01},
-{0xED4B,0x16,0x01},
+{0xED4B,0x1A,0x01},
{0xED4C,0xC1,0x01},
-{0xED4D,0x86,0x01},
-{0xED4E,0x3E,0x01},
+{0xED4D,0x46,0x01},
+{0xED4E,0x3F,0x01},
{0xED4F,0x83,0x01},
-{0xED50,0xC1,0x01},
+{0xED50,0xD9,0x01},
{0xED51,0x0D,0x01},
{0xED52,0x57,0x01},
-{0xED53,0x02,0x01},
+{0xED53,0x06,0x01},
{0xED54,0x23,0x01},
{0xED55,0x14,0x01},
-{0xED56,0xAE,0x01},
+{0xED56,0xAF,0x01},
{0xED57,0xE4,0x01},
-{0xED58,0x44,0x01},
+{0xED58,0x64,0x01},
{0xED59,0x2A,0x01},
{0xED5A,0x43,0x01},
-{0xED5B,0xF9,0x01},
-{0xED5C,0xCA,0x01},
+{0xED5B,0x01,0x01},
+{0xED5C,0xCB,0x01},
{0xED5D,0x56,0x01},
-{0xED5E,0x0C,0x01},
+{0xED5E,0x10,0x01},
{0xED5F,0x03,0x01},
-{0xED60,0x98,0x01},
-{0xED61,0xE2,0x01},
+{0xED60,0x18,0x01},
+{0xED61,0xE4,0x01},
{0xED62,0xA8,0x01},
-{0xED63,0x26,0x01},
+{0xED63,0xE6,0x01},
{0xED64,0x41,0x01},
{0xED65,0x9E,0x01},
-{0xED66,0xC1,0x01},
+{0xED66,0xE1,0x01},
{0xED67,0xCE,0x01},
{0xED68,0x59,0x01},
-{0xED69,0x1C,0x01},
+{0xED69,0x20,0x01},
{0xED6A,0xB3,0x01},
-{0xED6B,0x93,0x01},
-{0xED6C,0xA7,0x01},
+{0xED6B,0x13,0x01},
+{0xED6C,0xA8,0x01},
{0xED6D,0x74,0x01},
{0xED6E,0x04,0x01},
{0xED6F,0x25,0x01},
{0xED70,0x13,0x01},
-{0xED71,0xD9,0x01},
+{0xED71,0xE1,0x01},
{0xED72,0xC8,0x01},
{0xED73,0x47,0x01},
-{0xED74,0x54,0x01},
+{0xED74,0x56,0x01},
{0xED75,0xD2,0x01},
-{0xED76,0x93,0x01},
-{0xED77,0xAA,0x01},
+{0xED76,0x13,0x01},
+{0xED77,0xAB,0x01},
{0xED78,0x98,0x01},
-{0xED79,0xE5,0x01},
-{0xED7A,0x32,0x01},
+{0xED79,0x25,0x01},
+{0xED7A,0x33,0x01},
{0xED7B,0x9A,0x01},
-{0xED7C,0x29,0x01},
+{0xED7C,0x49,0x01},
{0xED7D,0xCF,0x01},
{0xED7E,0x64,0x01},
-{0xED7F,0x8E,0x01},
+{0xED7F,0x96,0x01},
{0xED80,0x73,0x01},
{0xED81,0x95,0x01},
-{0xED82,0xBB,0x01},
+{0xED82,0xBC,0x01},
{0xED83,0xA4,0x01},
-{0xED84,0xA4,0x01},
+{0xED84,0xC4,0x01},
{0xED85,0x26,0x01},
{0xED86,0x0A,0x01},
{0xED87,0x59,0x01},
@@ -10004,21 +10016,21 @@ static const isx012_regset_t ISX012_Shading_2[] =
{0xED8C,0x10,0x01},
{0xED8D,0x88,0x01},
{0xED8E,0xB0,0x01},
-{0xED8F,0x84,0x01},
+{0xED8F,0xA4,0x01},
{0xED90,0x27,0x01},
{0xED91,0x59,0x01},
-{0xED92,0xF1,0x01},
+{0xED92,0xF9,0x01},
{0xED93,0x0B,0x01},
{0xED94,0x64,0x01},
-{0xED95,0xA2,0x01},
+{0xED95,0xA8,0x01},
{0xED96,0x43,0x01},
-{0xED97,0x99,0x01},
-{0xED98,0xE4,0x01},
+{0xED97,0x19,0x01},
+{0xED98,0xE6,0x01},
{0xED99,0x68,0x01},
-{0xED9A,0x25,0x01},
+{0xED9A,0x45,0x01},
{0xED9B,0x2F,0x01},
{0xED9C,0x2B,0x01},
-{0xED9D,0xB1,0x01},
+{0xED9D,0xB9,0x01},
{0xED9E,0xC9,0x01},
{0xED9F,0x42,0x01},
{0xEDA0,0x18,0x01},
@@ -10026,24 +10038,24 @@ static const isx012_regset_t ISX012_Shading_2[] =
{0xEDA2,0x90,0x01},
{0xEDA3,0x80,0x01},
{0xEDA4,0x3C,0x01},
-{0xEDA5,0x24,0x01},
+{0xEDA5,0x44,0x01},
{0xEDA6,0x22,0x01},
{0xEDA7,0x2F,0x01},
{0xEDA8,0xF1,0x01},
{0xEDA9,0x09,0x01},
{0xEDAA,0x57,0x01},
-{0xEDAB,0x00,0x01},
+{0xEDAB,0x04,0x01},
{0xEDAC,0x53,0x01},
{0xEDAD,0x99,0x01},
-{0xEDAE,0xEA,0x01},
+{0xEDAE,0xEC,0x01},
{0xEDAF,0x90,0x01},
-{0xEDB0,0xC6,0x01},
-{0xEDB1,0x3B,0x01},
+{0xEDB0,0x66,0x01},
+{0xEDB1,0x3C,0x01},
{0xEDB2,0x6D,0x01},
-{0xEDB3,0x99,0x01},
+{0xEDB3,0xA9,0x01},
{0xEDB4,0x4C,0x01},
{0xEDB5,0x50,0x01},
-{0xEDB6,0xA4,0x01},
+{0xEDB6,0xA6,0x01},
{0xEDB7,0x32,0x01},
{0xEDB8,0x12,0x01},
{0xEDB9,0x94,0x01},
@@ -10054,112 +10066,112 @@ static const isx012_regset_t ISX012_Shading_2[] =
{0xEDBE,0x71,0x01},
{0xEDBF,0x49,0x01},
{0xEDC0,0x51,0x01},
-{0xEDC1,0xB2,0x01},
+{0xEDC1,0xB4,0x01},
{0xEDC2,0x02,0x01},
{0xEDC3,0x17,0x01},
-{0xEDC4,0xCD,0x01},
+{0xEDC4,0xCE,0x01},
{0xEDC5,0x98,0x01},
-{0xEDC6,0x86,0x01},
-{0xEDC7,0x3D,0x01},
+{0xEDC6,0x06,0x01},
+{0xEDC7,0x3E,0x01},
{0xEDC8,0xBC,0x01},
-{0xEDC9,0x01,0x01},
+{0xEDC9,0x31,0x01},
{0xEDCA,0x50,0x01},
{0xEDCB,0x63,0x01},
-{0xEDCC,0x80,0x01},
+{0xEDCC,0x86,0x01},
{0xEDCD,0x63,0x01},
{0xEDCE,0x16,0x01},
-{0xEDCF,0xC3,0x01},
+{0xEDCF,0xC4,0x01},
{0xEDD0,0x2C,0x01},
-{0xEDD1,0x25,0x01},
+{0xEDD1,0x45,0x01},
{0xEDD2,0x2C,0x01},
{0xEDD3,0x43,0x01},
-{0xEDD4,0xB1,0x01},
+{0xEDD4,0xB9,0x01},
{0xEDD5,0x4A,0x01},
{0xEDD6,0x53,0x01},
-{0xEDD7,0xCC,0x01},
+{0xEDD7,0xCE,0x01},
{0xEDD8,0x82,0x01},
{0xEDD9,0x96,0x01},
-{0xEDDA,0xC7,0x01},
+{0xEDDA,0xC8,0x01},
{0xEDDB,0x40,0x01},
-{0xEDDC,0xA6,0x01},
-{0xEDDD,0x39,0x01},
+{0xEDDC,0x06,0x01},
+{0xEDDD,0x3A,0x01},
{0xEDDE,0xBE,0x01},
-{0xEDDF,0x91,0x01},
+{0xEDDF,0xC1,0x01},
{0xEDE0,0xD0,0x01},
{0xEDE1,0x75,0x01},
-{0xEDE2,0x54,0x01},
+{0xEDE2,0x64,0x01},
{0xEDE3,0x34,0x01},
-{0xEDE4,0x1B,0x01},
-{0xEDE5,0xFC,0x01},
+{0xEDE4,0x9B,0x01},
+{0xEDE5,0xFE,0x01},
{0xEDE6,0x4C,0x01},
-{0xEDE7,0x46,0x01},
+{0xEDE7,0xA6,0x01},
{0xEDE8,0x39,0x01},
{0xEDE9,0x7D,0x01},
-{0xEDEA,0x71,0x01},
+{0xEDEA,0x89,0x01},
{0xEDEB,0x8D,0x01},
{0xEDEC,0x5D,0x01},
-{0xEDED,0x46,0x01},
+{0xEDED,0x4A,0x01},
{0xEDEE,0xE3,0x01},
-{0xEDEF,0x17,0x01},
-{0xEDF0,0xD9,0x01},
+{0xEDEF,0x97,0x01},
+{0xEDF0,0xDA,0x01},
{0xEDF1,0x50,0x01},
-{0xEDF2,0x86,0x01},
+{0xEDF2,0xE6,0x01},
{0xEDF3,0x3A,0x01},
{0xEDF4,0xB3,0x01},
-{0xEDF5,0x09,0x01},
+{0xEDF5,0x39,0x01},
{0xEDF6,0x50,0x01},
{0xEDF7,0x76,0x01},
-{0xEDF8,0x6A,0x01},
+{0xEDF8,0x7A,0x01},
{0xEDF9,0xF4,0x01},
-{0xEDFA,0x1E,0x01},
-{0xEDFB,0x25,0x01},
+{0xEDFA,0x9E,0x01},
+{0xEDFB,0x2A,0x01},
{0xEDFC,0x61,0x01},
-{0xEDFD,0x67,0x01},
-{0xEDFE,0x45,0x01},
+{0xEDFD,0x87,0x01},
+{0xEDFE,0x46,0x01},
{0xEDFF,0xC0,0x01},
-{0xEE00,0x69,0x01},
+{0xEE00,0x99,0x01},
{0xEE01,0xD0,0x01},
{0xEE02,0x6B,0x01},
-{0xEE03,0xF6,0x01},
-{0xEE04,0x93,0x01},
-{0xEE05,0x9A,0x01},
-{0xEE06,0xFA,0x01},
+{0xEE03,0x02,0x01},
+{0xEE04,0x94,0x01},
+{0xEE05,0x1A,0x01},
+{0xEE06,0xFD,0x01},
{0xEE07,0xB8,0x01},
-{0xEE08,0x26,0x01},
+{0xEE08,0xE6,0x01},
{0xEE09,0x40,0x01},
{0xEE0A,0xC0,0x01},
-{0xEE0B,0xB9,0x01},
+{0xEE0B,0xF1,0x01},
{0xEE0C,0xD0,0x01},
{0xEE0D,0x75,0x01},
-{0xEE0E,0x6E,0x01},
+{0xEE0E,0x80,0x01},
{0xEE0F,0xE4,0x01},
{0xEE10,0x9E,0x01},
-{0xEE11,0x2D,0x01},
+{0xEE11,0x33,0x01},
{0xEE12,0xE1,0x01},
{0xEE13,0xA7,0x01},
-{0xEE14,0x49,0x01},
+{0xEE14,0x4B,0x01},
{0xEE15,0xFD,0x01},
-{0xEE16,0xB9,0x01},
-{0xEE17,0x52,0x01},
+{0xEE16,0x21,0x01},
+{0xEE17,0x53,0x01},
{0xEE18,0x7C,0x01},
-{0xEE19,0x98,0x01},
+{0xEE19,0xAE,0x01},
{0xEE1A,0x64,0x01},
-{0xEE1B,0x1E,0x01},
-{0xEE1C,0x22,0x01},
+{0xEE1B,0x9E,0x01},
+{0xEE1C,0x26,0x01},
{0xEE1D,0x89,0x01},
-{0xEE1E,0xA7,0x01},
-{0xEE1F,0x48,0x01},
+{0xEE1E,0xC7,0x01},
+{0xEE1F,0x49,0x01},
{0xEE20,0xE4,0x01},
-{0xEE21,0x49,0x01},
+{0xEE21,0x99,0x01},
{0xEE22,0x12,0x01},
{0xEE23,0x7D,0x01},
-{0xEE24,0xB4,0x01},
+{0xEE24,0xCA,0x01},
{0xEE25,0xB4,0x01},
-{0xEE26,0x1F,0x01},
-{0xEE27,0x31,0x01},
+{0xEE26,0x9F,0x01},
+{0xEE27,0x37,0x01},
{0xEE28,0xC5,0x01},
{0xEE29,0x47,0x01},
-{0xEE2A,0x4B,0x01},
+{0xEE2A,0x4D,0x01},
{0xEE2B,0xC2,0x01},
{0xEE2C,0x19,0x01},
{0xEE2D,0x0F,0x01},
@@ -10461,154 +10473,154 @@ static const isx012_regset_t ISX012_Shading_2[] =
//SHD2 CW+TL84 33:66
{0xED00,0x9191,0x02},//
-{0xEF54,0x21,0x01},
-{0xEF55,0x92,0x01},
-{0xEF56,0xD1,0x01},
-{0xEF57,0x8A,0x01},
-{0xEF58,0x3E,0x01},
-{0xEF59,0xF4,0x01},
-{0xEF5A,0xA1,0x01},
-{0xEF5B,0x10,0x01},
-{0xEF5C,0xB9,0x01},
-{0xEF5D,0x48,0x01},
-{0xEF5E,0x46,0x01},
-{0xEF5F,0x1F,0x01},
-{0xEF60,0x82,0x01},
+{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,0x7E,0x01},
-{0xEF63,0xBC,0x01},
-{0xEF64,0xC3,0x01},
-{0xEF65,0x1C,0x01},
-{0xEF66,0xE3,0x01},
-{0xEF67,0x38,0x01},
-{0xEF68,0xC7,0x01},
-{0xEF69,0x3B,0x01},
-{0xEF6A,0xF7,0x01},
-{0xEF6B,0x71,0x01},
-{0xEF6C,0x90,0x01},
-{0xEF6D,0x7B,0x01},
-{0xEF6E,0x8E,0x01},
-{0xEF6F,0x53,0x01},
-{0xEF70,0x1A,0x01},
-{0xEF71,0xC5,0x01},
-{0xEF72,0x04,0x01},
-{0xEF73,0x46,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,0xA2,0x01},
-{0xEF76,0x39,0x01},
-{0xEF77,0x0E,0x01},
-{0xEF78,0x7E,0x01},
-{0xEF79,0x9A,0x01},
-{0xEF7A,0xA3,0x01},
-{0xEF7B,0x99,0x01},
-{0xEF7C,0xB5,0x01},
-{0xEF7D,0x34,0x01},
-{0xEF7E,0x85,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,0x4D,0x01},
-{0xEF81,0x61,0x01},
-{0xEF82,0x8B,0x01},
-{0xEF83,0x67,0x01},
-{0xEF84,0xB0,0x01},
-{0xEF85,0x53,0x01},
+{0xEF80,0x4E,0x01},
+{0xEF81,0x69,0x01},
+{0xEF82,0x4B,0x01},
+{0xEF83,0x68,0x01},
+{0xEF84,0xBA,0x01},
+{0xEF85,0x93,0x01},
{0xEF86,0x1B,0x01},
-{0xEF87,0xBB,0x01},
-{0xEF88,0x08,0x01},
-{0xEF89,0x45,0x01},
+{0xEF87,0xBC,0x01},
+{0xEF88,0x0C,0x01},
+{0xEF89,0x65,0x01},
{0xEF8A,0x24,0x01},
{0xEF8B,0x17,0x01},
-{0xEF8C,0x11,0x01},
-{0xEF8D,0x09,0x01},
+{0xEF8C,0x19,0x01},
+{0xEF8D,0x49,0x01},
{0xEF8E,0x51,0x01},
-{0xEF8F,0xF2,0x01},
-{0xEF90,0xA2,0x01},
-{0xEF91,0x9B,0x01},
-{0xEF92,0xD3,0x01},
-{0xEF93,0x90,0x01},
+{0xEF8F,0xF6,0x01},
+{0xEF90,0xE2,0x01},
+{0xEF91,0x1B,0x01},
+{0xEF92,0xD5,0x01},
+{0xEF93,0x98,0x01},
{0xEF94,0xC5,0x01},
{0xEF95,0x25,0x01},
-{0xEF96,0x0A,0x01},
+{0xEF96,0x0B,0x01},
{0xEF97,0x01,0x01},
{0xEF98,0x48,0x01},
{0xEF99,0x43,0x01},
-{0xEF9A,0x62,0x01},
-{0xEF9B,0x52,0x01},
-{0xEF9C,0x16,0x01},
-{0xEF9D,0xD5,0x01},
-{0xEF9E,0x9C,0x01},
-{0xEF9F,0xC6,0x01},
+{0xEF9A,0x64,0x01},
+{0xEF9B,0x72,0x01},
+{0xEF9C,0x96,0x01},
+{0xEF9D,0xD6,0x01},
+{0xEF9E,0xA8,0x01},
+{0xEF9F,0xE6,0x01},
{0xEFA0,0x2C,0x01},
-{0xEFA1,0x2F,0x01},
+{0xEFA1,0x30,0x01},
{0xEFA2,0x51,0x01},
{0xEFA3,0x48,0x01},
{0xEFA4,0x40,0x01},
{0xEFA5,0x1C,0x01},
{0xEFA6,0x22,0x01},
{0xEFA7,0x93,0x01},
-{0xEFA8,0xB3,0x01},
-{0xEFA9,0xB8,0x01},
-{0xEFAA,0x46,0x01},
+{0xEFA8,0xB4,0x01},
+{0xEFA9,0xC8,0x01},
+{0xEFAA,0xA6,0x01},
{0xEFAB,0x37,0x01},
-{0xEFAC,0x7A,0x01},
-{0xEFAD,0x21,0x01},
-{0xEFAE,0x4A,0x01},
+{0xEFAC,0x7C,0x01},
+{0xEFAD,0x29,0x01},
+{0xEFAE,0x8A,0x01},
{0xEFAF,0x48,0x01},
{0xEFB0,0x30,0x01},
-{0xEFB1,0x52,0x01},
+{0xEFB1,0x62,0x01},
{0xEFB2,0x12,0x01},
{0xEFB3,0xA4,0x01},
-{0xEFB4,0xF0,0x01},
-{0xEFB5,0xE5,0x01},
-{0xEFB6,0x37,0x01},
-{0xEFB7,0xD6,0x01},
-{0xEFB8,0xF9,0x01},
-{0xEFB9,0x8C,0x01},
-{0xEFBA,0x5B,0x01},
-{0xEFBB,0x9E,0x01},
-{0xEFBC,0x62,0x01},
-{0xEFBD,0x14,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,0xC8,0x01},
-{0xEFC0,0xA5,0x01},
-{0xEFC1,0x34,0x01},
-{0xEFC2,0xE0,0x01},
-{0xEFC3,0xD1,0x01},
-{0xEFC4,0x8F,0x01},
-{0xEFC5,0x73,0x01},
-{0xEFC6,0x4C,0x01},
-{0xEFC7,0xE3,0x01},
-{0xEFC8,0x18,0x01},
-{0xEFC9,0xC2,0x01},
-{0xEFCA,0x3C,0x01},
-{0xEFCB,0x46,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,0xD2,0x01},
-{0xEFCE,0x09,0x01},
-{0xEFCF,0x90,0x01},
-{0xEFD0,0x85,0x01},
-{0xEFD1,0xF6,0x01},
-{0xEFD2,0x03,0x01},
-{0xEFD3,0x1E,0x01},
-{0xEFD4,0xE7,0x01},
-{0xEFD5,0x20,0x01},
-{0xEFD6,0x27,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,0xE4,0x01},
-{0xEFD9,0x01,0x01},
-{0xEFDA,0x90,0x01},
-{0xEFDB,0x87,0x01},
-{0xEFDC,0x30,0x01},
-{0xEFDD,0x04,0x01},
+{0xEFD8,0xEA,0x01},
+{0xEFD9,0x41,0x01},
+{0xEFDA,0x50,0x01},
+{0xEFDB,0x8A,0x01},
+{0xEFDC,0x4E,0x01},
+{0xEFDD,0xB4,0x01},
{0xEFDE,0x22,0x01},
-{0xEFDF,0x0B,0x01},
-{0xEFE0,0x2D,0x01},
-{0xEFE1,0x28,0x01},
-{0xEFE2,0x41,0x01},
-{0xEFE3,0x10,0x01},
-{0xEFE4,0xDA,0x01},
-{0xEFE5,0x90,0x01},
-{0xEFE6,0x88,0x01},
-{0xEFE7,0x3C,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},
@@ -10620,154 +10632,154 @@ static const isx012_regset_t ISX012_Shading_2[] =
//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},
+{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,0x7D,0x01},
-{0xEFFD,0xBA,0x01},
-{0xEFFE,0xD3,0x01},
-{0xEFFF,0x1C,0x01},
-{0xF000,0xE4,0x01},
-{0xF001,0x40,0x01},
-{0xF002,0x27,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,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},
+{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,0x7E,0x01},
-{0xF013,0x9A,0x01},
-{0xF014,0xB3,0x01},
+{0xF012,0x80,0x01},
+{0xF013,0xA4,0x01},
+{0xF014,0xE3,0x01},
{0xF015,0x19,0x01},
-{0xF016,0xB6,0x01},
-{0xF017,0x38,0x01},
-{0xF018,0xA5,0x01},
+{0xF016,0xB7,0x01},
+{0xF017,0x3C,0x01},
+{0xF018,0xC5,0x01},
{0xF019,0x28,0x01},
-{0xF01A,0x4F,0x01},
-{0xF01B,0x79,0x01},
-{0xF01C,0xCB,0x01},
-{0xF01D,0x68,0x01},
-{0xF01E,0xBA,0x01},
-{0xF01F,0x53,0x01},
+{0xF01A,0x51,0x01},
+{0xF01B,0x89,0x01},
+{0xF01C,0x8B,0x01},
+{0xF01D,0x69,0x01},
+{0xF01E,0xC4,0x01},
+{0xF01F,0x93,0x01},
{0xF020,0x9B,0x01},
-{0xF021,0xBB,0x01},
-{0xF022,0x0C,0x01},
+{0xF021,0xBC,0x01},
+{0xF022,0x10,0x01},
{0xF023,0x65,0x01},
{0xF024,0x24,0x01},
-{0xF025,0x17,0x01},
+{0xF025,0x18,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},
+{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,0x48,0x01},
+{0xF032,0x88,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},
+{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,0xB5,0x01},
-{0xF043,0xCC,0x01},
-{0xF044,0x46,0x01},
+{0xF042,0xB6,0x01},
+{0xF043,0xDC,0x01},
+{0xF044,0xC6,0x01},
{0xF045,0x37,0x01},
-{0xF046,0x7C,0x01},
-{0xF047,0x29,0x01},
-{0xF048,0x8A,0x01},
+{0xF046,0x7E,0x01},
+{0xF047,0x31,0x01},
+{0xF048,0xCA,0x01},
{0xF049,0x48,0x01},
{0xF04A,0x32,0x01},
{0xF04B,0x72,0x01},
-{0xF04C,0x12,0x01},
+{0xF04C,0x92,0x01},
{0xF04D,0xA5,0x01},
-{0xF04E,0x00,0x01},
-{0xF04F,0xA6,0x01},
-{0xF050,0x38,0x01},
-{0xF051,0xD7,0x01},
-{0xF052,0x01,0x01},
-{0xF053,0x0D,0x01},
+{0xF04E,0x08,0x01},
+{0xF04F,0x26,0x01},
+{0xF050,0x39,0x01},
+{0xF051,0xDC,0x01},
+{0xF052,0x19,0x01},
+{0xF053,0x8D,0x01},
{0xF054,0x5C,0x01},
-{0xF055,0xA2,0x01},
-{0xF056,0x82,0x01},
-{0xF057,0x94,0x01},
-{0xF058,0xAA,0x01},
-{0xF059,0xD8,0x01},
-{0xF05A,0x45,0x01},
+{0xF055,0xA4,0x01},
+{0xF056,0x92,0x01},
+{0xF057,0x14,0x01},
+{0xF058,0xAB,0x01},
+{0xF059,0xE0,0x01},
+{0xF05A,0xA5,0x01},
{0xF05B,0x35,0x01},
-{0xF05C,0xE5,0x01},
-{0xF05D,0xC9,0x01},
-{0xF05E,0xCF,0x01},
-{0xF05F,0x73,0x01},
-{0xF060,0x50,0x01},
-{0xF061,0x03,0x01},
+{0xF05C,0xEA,0x01},
+{0xF05D,0x09,0x01},
+{0xF05E,0x10,0x01},
+{0xF05F,0x75,0x01},
+{0xF060,0x58,0x01},
+{0xF061,0x33,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},
+{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},
@@ -10943,8 +10955,8 @@ static const isx012_regset_t ISX012_Shading_2[] =
//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 :
+{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
@@ -11199,6 +11211,26 @@ static const isx012_regset_t ISX012_Flash_AELINE[] =
{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},
+
+{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 :
diff --git a/drivers/media/video/m5mo.c b/drivers/media/video/m5mo.c
index 0750ecb..d411269 100644
--- a/drivers/media/video/m5mo.c
+++ b/drivers/media/video/m5mo.c
@@ -36,11 +36,6 @@
#define M5MO_DRIVER_NAME "M5MO"
-#ifdef CONFIG_MACH_S2PLUS
-extern struct class *camera_class;
-struct device *m5mo_dev;
-#endif
-
#define M5MO_FW_PATH "/sdcard/RS_M5LS.bin"
#define M5MO_FW_DUMP_PATH "/data/RS_M5LS_dump.bin"
@@ -117,8 +112,9 @@ static const struct m5mo_frmsizeenum preview_frmsizes[] = {
};
static const struct m5mo_frmsizeenum capture_frmsizes[] = {
- { M5MO_CAPTURE_VGA, 640, 480, 0x09 },
- { M5MO_CAPTURE_WVGA, 800, 480, 0x0A },
+ { M5MO_CAPTURE_VGA, 640, 480, 0x09 },
+ { M5MO_CAPTURE_WVGA, 800, 480, 0x0A },
+ { M5MO_CAPTURE_SXGA, 1280, 960, 0x14 },
{ M5MO_CAPTURE_W2MP, 2048, 1232, 0x2C },
{ M5MO_CAPTURE_3MP, 2048, 1536, 0x1B },
{ M5MO_CAPTURE_W7MP, 3264, 1968, 0x2D },
@@ -178,9 +174,7 @@ static struct m5mo_control m5mo_ctrls[] = {
},
};
-#ifndef CONFIG_MACH_S2PLUS
struct class *camera_class;
-#endif
static inline struct m5mo_state *to_state(struct v4l2_subdev *sd)
{
@@ -1567,9 +1561,7 @@ static int m5mo_set_af(struct v4l2_subdev *sd, int val)
static int m5mo_set_af_mode(struct v4l2_subdev *sd, int val)
{
struct m5mo_state *state = to_state(sd);
-#ifndef CONFIG_MACH_S2PLUS
struct regulator *movie = regulator_get(NULL, "led_movie");
-#endif
u32 cancel, mode, status = 0;
int i, err;
@@ -1632,12 +1624,10 @@ retry:
CHECK_ERR(err);
}
-#ifndef CONFIG_MACH_S2PLUS
if (val == FOCUS_MODE_MACRO)
regulator_set_current_limit(movie, 15000, 17000);
else if (state->focus.mode == FOCUS_MODE_MACRO)
regulator_set_current_limit(movie, 90000, 110000);
-#endif
state->focus.mode = val;
@@ -1656,7 +1646,7 @@ retry:
if ((status & 0x01) != 0x00) {
cam_err("failed\n");
- return -ETIMEDOUT;
+ /*return -ETIMEDOUT;*/ /*This return value cause camera lock-up.*/
}
cam_trace("X\n");
@@ -2944,7 +2934,6 @@ static int __devinit m5mo_probe(struct i2c_client *client,
#ifdef CAM_DEBUG
state->dbg_level = CAM_DEBUG;
#endif
-#ifndef CONFIG_MACH_S2PLUS
if (state->m5mo_dev == NULL) {
state->m5mo_dev =
device_create(camera_class, NULL, 0, NULL, "rear");
@@ -2964,7 +2953,6 @@ static int __devinit m5mo_probe(struct i2c_client *client,
}
}
}
-#endif
/* wait queue initialize */
init_waitqueue_head(&state->isp.wait);
@@ -3026,30 +3014,9 @@ static struct i2c_driver m5mo_i2c_driver = {
static int __init m5mo_mod_init(void)
{
-#ifdef CONFIG_MACH_S2PLUS
- if (!m5mo_dev) {
- m5mo_dev =
- device_create(camera_class, NULL, 0, NULL, "rear");
- if (IS_ERR(m5mo_dev)) {
- cam_err("failed to create device m5mo_dev!\n");
- return 0;
- }
- if (device_create_file
- (m5mo_dev, &dev_attr_rear_camtype) < 0) {
- cam_err("failed to create device file, %s\n",
- dev_attr_rear_camtype.attr.name);
- }
- if (device_create_file
- (m5mo_dev, &dev_attr_rear_camfw) < 0) {
- cam_err("failed to create device file, %s\n",
- dev_attr_rear_camfw.attr.name);
- }
- }
-#else
camera_class = class_create(THIS_MODULE, "camera");
if (IS_ERR(camera_class))
pr_err("Failed to create class(camera)!\n");
-#endif
return i2c_add_driver(&m5mo_i2c_driver);
}
diff --git a/drivers/media/video/m5mo.h b/drivers/media/video/m5mo.h
index 8d41584..6218eba 100644
--- a/drivers/media/video/m5mo.h
+++ b/drivers/media/video/m5mo.h
@@ -80,6 +80,7 @@ enum m5mo_prev_frmsize {
enum m5mo_cap_frmsize {
M5MO_CAPTURE_VGA, /* 640 x 480 */
M5MO_CAPTURE_WVGA, /* 800 x 480 */
+ M5MO_CAPTURE_SXGA, /*1280 x 960*/
M5MO_CAPTURE_W1MP, /* 1600 x 960 */
M5MO_CAPTURE_2MP, /* UXGA - 1600 x 1200 */
M5MO_CAPTURE_W2MP, /* 2048 x 1232 */
diff --git a/drivers/media/video/m9mo.c b/drivers/media/video/m9mo.c
index 8b67610..09c496e 100644
--- a/drivers/media/video/m9mo.c
+++ b/drivers/media/video/m9mo.c
@@ -37,6 +37,7 @@
extern struct class *camera_class;
struct device *m9mo_dev;
+static bool leave_power;
#if 0
#define M9MO_FW_PATH "/data/RS_M9MO.bin"
@@ -44,11 +45,19 @@ struct device *m9mo_dev;
#endif
#define M9MO_FW_PATH "/sdcard/RS_M9MO.bin"
+
#define M9MO_FW_REQ_PATH "RS_M9MO.bin"
+#define M9MO_EVT31_FW_REQ_PATH "RS_M9MO_EVT3.1.bin"
+
#define FW_INFO_PATH "/sdcard/FW_INFO.bin"
-#define M9MO_FW_DUMP_PATH "/data/RS_M9LS_dump.bin"
+#define M9MO_FW_DUMP_PATH "/sdcard/M9MO_dump.bin"
+
+#if 0
+#define M9MO_FACTORY_CSV_PATH "/data/FACTORY_CSV_RAW.bin"
+#endif
+#define M9MO_FACTORY_CSV_PATH "/mnt/sdcard/FACTORY_CSV_RAW.bin"
#define M9MOTB_FW_PATH "RS_M9LS_TB.bin" /* TECHWIN - SONY */
/* #define M9MOON_FW_PATH "RS_M9LS_ON.bin" */ /* FIBEROPTICS - SONY */
@@ -68,9 +77,12 @@ struct device *m9mo_dev;
#if 0
#define M9MO_FW_VER_LEN 22
#define M9MO_FW_VER_FILE_CUR 0x16FF00
+#define M9MO_FW_VER_NUM 0x000018
#else
-#define M9MO_FW_VER_LEN 20
+#define M9MO_FW_VER_LEN 20
+#define M9MO_SEN_FW_VER_LEN 30
#define M9MO_FW_VER_FILE_CUR 0x1FF080
+#define M9MO_FW_VER_NUM 0x1FF080
#endif
#define M9MO_FLASH_BASE_ADDR 0x00000000
@@ -79,33 +91,65 @@ struct device *m9mo_dev;
#define M9MO_FLASH_BASE_ADDR_1 0x001FF000
+u32 M9MO_FLASH_FACTORY_OIS[] = {0x27E031A2, 0x27E031C7};
+u32 M9MO_FLASH_FACTORY_VIB[] = {0x27E031C8, 0x27E031D1};
+u32 M9MO_FLASH_FACTORY_GYRO[] = {0x27E031D2, 0x27E031D7};
+u32 M9MO_FLASH_FACTORY_TELE_RESOL[] = {0x27E03298, 0x27E0329F};
+u32 M9MO_FLASH_FACTORY_WIDE_RESOL[] = {0x27E032A0, 0x27E032A7};
+u32 M9MO_FLASH_FACTORY_AF_FCS[] = {0x27E0323A, 0x27E03275};
+u32 M9MO_FLASH_FACTORY_PUNT[] = {0x27E031D8, 0x27E03239};
+
+u32 M9MO_FLASH_FACTORY_BACKLASH[] = {0x27E03276, 0x27E03279};
+
+u32 M9MO_FLASH_FACTORY_AF_LED[] = {0x27E032A8, 0x27E032AD};
+u32 M9MO_FLASH_FACTORY_IRIS[] = {0x27E030E8, 0x27E03107};
+u32 M9MO_FLASH_FACTORY_LIVEVIEW[] = {0x27E03108, 0x27E0310F};
+u32 M9MO_FLASH_FACTORY_GAIN_CAPTURE[] = {0x27E03110, 0x27E03117};
+u32 M9MO_FLASH_FACTORY_SH_CLOSE[] = {0x27E0327A, 0x27E03297};
+u32 M9MO_FLASH_FACTORY_FLASH_CHECK[] = {0x27E032AE, 0x27E032B0};
+u32 M9MO_FLASH_FACTORY_WB_ADJ[] = {0x27E03000, 0x27E0304F};
+u32 M9MO_FLASH_FACTORY_FLASH_WB[] = {0x27E032B4, 0x27E032C3};
+u32 M9MO_FLASH_FACTORY_ADJ_FLASH_WB[] = {0x27E032D0, 0x27E032EB};
+
+u32 M9MO_FLASH_FACTORY_IR_CHECK[] = {0x27E032C4, 0x27E032CD};
+
+u32 M9MO_FLASH_FACTORY_RESULT = 0x27E03128;
+
#define M9MO_INT_RAM_BASE_ADDR 0x01100000
#define M9MO_I2C_RETRY 5
#define M9MO_I2C_VERIFY 100
-#define M9MO_ISP_TIMEOUT 5000 /* timeout delay for m9mo 3000->5000 */
+/* TODO
+ Timeout delay is changed to 35 sec to support large shutter speed.
+ This value must be set according to shutter speed.
+*/
+#define M9MO_ISP_TIMEOUT 5000
+#define M9MO_ISP_CAPTURE_TIMEOUT 35000
+#define M9MO_SOUND_TIMEOUT 35000
#define M9MO_ISP_AFB_TIMEOUT 15000 /* FIXME */
#define M9MO_ISP_ESD_TIMEOUT 1000
-#if 1
-#define M9MO_JPEG_MAXSIZE 0x3A0000
-#define M9MO_THUMB_MAXSIZE 0xFC00
-#define M9MO_POST_MAXSIZE 0xBB800
-#else
-#define M9MO_JPEG_MAXSIZE 0x43C600
+#define M9MO_JPEG_MAXSIZE 0x17E8000 /* 25M 4K align */
#define M9MO_THUMB_MAXSIZE 0x0
#define M9MO_POST_MAXSIZE 0x0
-#endif
#define M9MO_DEF_APEX_DEN 100
-#define m9mo_readb(sd, g, b, v) m9mo_read(sd, 1, g, b, v)
-#define m9mo_readw(sd, g, b, v) m9mo_read(sd, 2, g, b, v)
-#define m9mo_readl(sd, g, b, v) m9mo_read(sd, 4, g, b, v)
+#define m9mo_readb(sd, g, b, v) m9mo_read(__LINE__, sd, 1, g, b, v, true)
+#define m9mo_readw(sd, g, b, v) m9mo_read(__LINE__, sd, 2, g, b, v, true)
+#define m9mo_readl(sd, g, b, v) m9mo_read(__LINE__, sd, 4, g, b, v, true)
-#define m9mo_writeb(sd, g, b, v) m9mo_write(sd, 1, g, b, v)
-#define m9mo_writew(sd, g, b, v) m9mo_write(sd, 2, g, b, v)
-#define m9mo_writel(sd, g, b, v) m9mo_write(sd, 4, g, b, v)
+#define m9mo_writeb(sd, g, b, v) m9mo_write(__LINE__, sd, 1, g, b, v, true)
+#define m9mo_writew(sd, g, b, v) m9mo_write(__LINE__, sd, 2, g, b, v, true)
+#define m9mo_writel(sd, g, b, v) m9mo_write(__LINE__, sd, 4, g, b, v, true)
+
+#define m9mo_readb2(sd, g, b, v) m9mo_read(__LINE__, sd, 1, g, b, v, false)
+#define m9mo_readw2(sd, g, b, v) m9mo_read(__LINE__, sd, 2, g, b, v, false)
+#define m9mo_readl2(sd, g, b, v) m9mo_read(__LINE__, sd, 4, g, b, v, false)
+
+#define m9mo_writeb2(sd, g, b, v) m9mo_write(__LINE__, sd, 1, g, b, v, false)
+#define m9mo_writew2(sd, g, b, v) m9mo_write(__LINE__, sd, 2, g, b, v, false)
+#define m9mo_writel2(sd, g, b, v) m9mo_write(__LINE__, sd, 4, g, b, v, false)
#define CHECK_ERR(x) if ((x) < 0) { \
cam_err("i2c failed, err %d\n", x); \
@@ -120,51 +164,50 @@ struct device *m9mo_dev;
static const struct m9mo_frmsizeenum preview_frmsizes[] = {
{ M9MO_PREVIEW_QCIF, 176, 144, 0x05 }, /* 176 x 144 */
- { M9MO_PREVIEW_QCIF2, 528, 432, 0x2C }, /* 176 x 144 */
{ M9MO_PREVIEW_QVGA, 320, 240, 0x09 },
{ M9MO_PREVIEW_VGA, 640, 480, 0x17 },
- { M9MO_PREVIEW_D1, 720, 480, 0x33 }, /* High speed */
- { M9MO_PREVIEW_WVGA, 800, 480, 0x1A },
+ { M9MO_PREVIEW_D1, 768, 512, 0x33 }, /* High speed */
+ { M9MO_PREVIEW_960_720, 960, 720, 0x34 },
+ { M9MO_PREVIEW_1080_720, 1056, 704, 0x35 },
{ M9MO_PREVIEW_720P, 1280, 720, 0x21 },
-
-#if defined(CONFIG_MACH_Q1_BD)
- { M9MO_PREVIEW_880_720, 880, 720, 0x2E },
- { M9MO_PREVIEW_1200_800, 1200, 800, 0x2F },
- { M9MO_PREVIEW_1280_800, 1280, 800, 0x35 },
- { M9MO_PREVIEW_1280_768, 1280, 768, 0x22 },
- { M9MO_PREVIEW_1072_800, 1072, 800, 0x36 },
- { M9MO_PREVIEW_980_800, 980, 800, 0x37 },
-#endif
-
{ M9MO_PREVIEW_1080P, 1920, 1080, 0x28 },
{ M9MO_PREVIEW_HDR, 3264, 2448, 0x27 },
{ M9MO_PREVIEW_720P_60FPS, 1280, 720, 0x25 },
{ M9MO_PREVIEW_VGA_60FPS, 640, 480, 0x2F },
-
+ { M9MO_PREVIEW_1080P_DUAL, 1920, 1080, 0x2C },
+ { M9MO_PREVIEW_720P_DUAL, 1280, 720, 0x2D },
+ { M9MO_PREVIEW_VGA_DUAL, 640, 480, 0x2E },
+ { M9MO_PREVIEW_QVGA_DUAL, 320, 240, 0x36 },
};
static const struct m9mo_frmsizeenum capture_frmsizes[] = {
+ { M9MO_CAPTURE_HD, 960, 720, 0x34 },
{ M9MO_CAPTURE_1MP, 1024, 768, 0x0F },
{ M9MO_CAPTURE_2MPW, 1920, 1080, 0x19 },
{ M9MO_CAPTURE_3MP, 1984, 1488, 0x2F },
+ { M9MO_CAPTURE_4MP, 2304, 1728, 0x1E },
{ M9MO_CAPTURE_5MP, 2592, 1944, 0x20 },
{ M9MO_CAPTURE_8MP, 3264, 2448, 0x25 },
{ M9MO_CAPTURE_10MP, 3648, 2736, 0x30 },
{ M9MO_CAPTURE_12MPW, 4608, 2592, 0x31 },
{ M9MO_CAPTURE_14MP, 4608, 3072, 0x32 },
{ M9MO_CAPTURE_16MP, 4608, 3456, 0x33 },
- /* for Postview size */
- { M9MO_CAPTURE_POSTWVGA, 800, 480, 0x09 },
+};
+
+static const struct m9mo_frmsizeenum postview_frmsizes[] = {
+ { M9MO_CAPTURE_POSTQVGA, 320, 240, 0x01 },
{ M9MO_CAPTURE_POSTVGA, 640, 480, 0x08 },
- { M9MO_CAPTURE_POSTWHD, 1280, 720, 0x0F },
+ { M9MO_CAPTURE_POSTWVGA, 800, 480, 0x09 },
{ M9MO_CAPTURE_POSTHD, 960, 720, 0x13 },
+ { M9MO_CAPTURE_POSTP, 1056, 704, 0x14 },
+ { M9MO_CAPTURE_POSTWHD, 1280, 720, 0x0F },
};
static struct m9mo_control m9mo_ctrls[] = {
{
.id = V4L2_CID_CAMERA_ISO,
.minimum = ISO_AUTO,
- .maximum = ISO_800,
+ .maximum = ISO_3200,
.step = 1,
.value = ISO_AUTO,
.default_value = ISO_AUTO,
@@ -190,6 +233,13 @@ static struct m9mo_control m9mo_ctrls[] = {
.value = SHARPNESS_DEFAULT,
.default_value = SHARPNESS_DEFAULT,
}, {
+ .id = V4L2_CID_CAMERA_CONTRAST,
+ .minimum = CONTRAST_MINUS_2,
+ .maximum = CONTRAST_MAX - 1,
+ .step = 1,
+ .value = CONTRAST_DEFAULT,
+ .default_value = CONTRAST_DEFAULT,
+ }, {
.id = V4L2_CID_CAMERA_ZOOM,
.minimum = ZOOM_LEVEL_0,
.maximum = ZOOM_LEVEL_MAX - 1,
@@ -208,18 +258,22 @@ static struct m9mo_control m9mo_ctrls[] = {
.minimum = ANTI_BANDING_AUTO,
.maximum = ANTI_BANDING_OFF,
.step = 1,
- .value = ANTI_BANDING_50HZ,
- .default_value = ANTI_BANDING_50HZ,
+ .value = ANTI_BANDING_AUTO,
+ .default_value = ANTI_BANDING_AUTO,
},
};
+static u8 sysfs_sensor_fw[7] = {0,};
+static u8 sysfs_phone_fw[7] = {0,};
+static u8 sysfs_sensor_type[25] = {0,};
+
static inline struct m9mo_state *to_state(struct v4l2_subdev *sd)
{
return container_of(sd, struct m9mo_state, sd);
}
-static int m9mo_read(struct v4l2_subdev *sd,
- u8 len, u8 category, u8 byte, int *val)
+static int m9mo_read(int _line, struct v4l2_subdev *sd,
+ u8 len, u8 category, u8 byte, int *val, bool log)
{
struct i2c_client *client = v4l2_get_subdevdata(sd);
struct i2c_msg msg;
@@ -253,7 +307,8 @@ static int m9mo_read(struct v4l2_subdev *sd,
}
if (err != 1) {
- cam_err("category %#x, byte %#x\n", category, byte);
+ cam_err("category %#x, byte %#x, err %d\n",
+ category, byte, err);
return err;
}
@@ -268,7 +323,8 @@ static int m9mo_read(struct v4l2_subdev *sd,
}
if (err != 1) {
- cam_err("category %#x, byte %#x\n", category, byte);
+ cam_err("RD category %#x, byte %#x, err %d\n",
+ category, byte, err);
return err;
}
@@ -284,13 +340,16 @@ static int m9mo_read(struct v4l2_subdev *sd,
*val = recv_data[1] << 24 | recv_data[2] << 16 |
recv_data[3] << 8 | recv_data[4];
- cam_i2c_dbg("category %#02x, byte %#x, value %#x\n",
+ if (log)
+ cam_i2c_dbg("[ %4d ] Read %s %#02x, byte %#x, value %#x\n",
+ _line, (len == 4 ? "L" : (len == 2 ? "W" : "B")),
category, byte, *val);
+
return err;
}
-static int m9mo_write(struct v4l2_subdev *sd,
- u8 len, u8 category, u8 byte, int val)
+static int m9mo_write(int _line, struct v4l2_subdev *sd,
+ u8 len, u8 category, u8 byte, int val, bool log)
{
struct i2c_client *client = v4l2_get_subdevdata(sd);
struct i2c_msg msg;
@@ -324,7 +383,10 @@ static int m9mo_write(struct v4l2_subdev *sd,
data[7] = val & 0xFF;
}
- cam_i2c_dbg("category %#x, byte %#x, value %#x\n", category, byte, val);
+ if (log)
+ cam_i2c_dbg("[ %4d ] Write %s %#x, byte %#x, value %#x\n",
+ _line, (len == 4 ? "L" : (len == 2 ? "W" : "B")),
+ category, byte, val);
for (i = M9MO_I2C_RETRY; i; i--) {
err = i2c_transfer(client->adapter, &msg, 1);
@@ -335,7 +397,7 @@ static int m9mo_write(struct v4l2_subdev *sd,
return err;
}
-static int m9mo_mem_read_1(struct v4l2_subdev *sd, u16 len, u32 addr, u8 *val)
+static int m9mo_mem_dump(struct v4l2_subdev *sd, u16 len, u32 addr, u8 *val)
{
struct i2c_client *client = v4l2_get_subdevdata(sd);
struct i2c_msg msg;
@@ -513,6 +575,7 @@ static u32 m9mo_wait_interrupt(struct v4l2_subdev *sd,
unsigned int timeout)
{
struct m9mo_state *state = to_state(sd);
+ int try_cnt = 30;
cam_trace("E\n");
if (wait_event_interruptible_timeout(state->isp.wait,
@@ -524,10 +587,20 @@ static u32 m9mo_wait_interrupt(struct v4l2_subdev *sd,
state->isp.issued = 0;
- m9mo_readw(sd, M9MO_CATEGORY_SYS,
- M9MO_SYS_INT_FACTOR, &state->isp.int_factor);
- cam_err("state->isp.int_factor = %x\n", state->isp.int_factor);
- cam_trace("X\n");
+ do {
+ m9mo_readw(sd, M9MO_CATEGORY_SYS,
+ M9MO_SYS_INT_FACTOR, &state->isp.int_factor);
+ cam_err(": state->isp.int_factor = %x\n",
+ state->isp.int_factor);
+ if (state->isp.int_factor == 0xFFFF) {
+ try_cnt--;
+ msleep(20);
+ } else
+ try_cnt = 0;
+ } while (try_cnt);
+
+ cam_trace("X %s\n",
+ (state->isp.int_factor == 0xFFFF ? "fail(0xFFFF)" : ""));
return state->isp.int_factor;
}
@@ -538,22 +611,20 @@ static int m9mo_wait_framesync(struct v4l2_subdev *sd)
s32 read_val = 0;
struct m9mo_state *state = to_state(sd);
- if (state->running_capture_mode == RUNNING_MODE_CONTINUOUS) {
- cam_dbg("Start Continuous capture");
- frame_sync_count = 9;
- } else if (state->running_capture_mode == RUNNING_MODE_BRACKET
- || state->running_capture_mode == RUNNING_MODE_HDR) {
- cam_dbg("Start AutoBracket(AEB) or HDR capture");
+ if (state->running_capture_mode == RUNNING_MODE_AE_BRACKET
+ || state->running_capture_mode == RUNNING_MODE_LOWLIGHT
+ || state->running_capture_mode == RUNNING_MODE_HDR) {
+ cam_dbg("Start AE Bracket or HDR capture\n");
frame_sync_count = 3;
} else if (state->running_capture_mode == RUNNING_MODE_BLINK) {
- cam_dbg("Start FaceDetect EyeBlink capture");
+ cam_dbg("Start FaceDetect EyeBlink capture\n");
frame_sync_count = 3;
}
/* Clear Interrupt factor */
for (i = frame_sync_count; i; i--) {
int_factor = m9mo_wait_interrupt(sd,
- M9MO_ISP_TIMEOUT);
+ M9MO_SOUND_TIMEOUT);
if (!(int_factor & M9MO_INT_FRAME_SYNC)) {
cam_warn("M9MO_INT_FRAME_SYNC isn't issued, %#x\n",
int_factor);
@@ -563,7 +634,7 @@ static int m9mo_wait_framesync(struct v4l2_subdev *sd)
M9MO_CATEGORY_SYS,
M9MO_SYS_FRAMESYNC_CNT,
&read_val);
- cam_dbg("Frame interrupt M9MO_INT_FRAME_SYNC cnt[%d]\n",
+ cam_dbg("Frame interrupt FRAME_SYNC cnt[%d]\n",
read_val);
}
@@ -574,7 +645,8 @@ static int m9mo_set_mode(struct v4l2_subdev *sd, u32 mode)
{
int i, err;
u32 old_mode, val;
- u32 int_factor;
+ u32 int_factor, int_en;
+ struct m9mo_state *state = to_state(sd);
cam_trace("E\n");
@@ -583,6 +655,15 @@ static int m9mo_set_mode(struct v4l2_subdev *sd, u32 mode)
if (err < 0)
return err;
+ /* don't change mode when cap -> param */
+ if (old_mode == M9MO_STILLCAP_MODE && mode == M9MO_PARMSET_MODE)
+ return 10;
+
+#if 1 /* Dual Capture */
+ if (state->dual_capture_start && mode == M9MO_STILLCAP_MODE)
+ mode = M9MO_PARMSET_MODE;
+#endif
+
if (old_mode == mode) {
cam_dbg("%#x -> %#x\n", old_mode, mode);
return old_mode;
@@ -623,11 +704,31 @@ static int m9mo_set_mode(struct v4l2_subdev *sd, u32 mode)
if (err < 0)
return err;
- if (mode == M9MO_STILLCAP_MODE) {
+ if (mode == M9MO_STILLCAP_MODE
+ && state->running_capture_mode != RUNNING_MODE_AE_BRACKET
+ && state->running_capture_mode != RUNNING_MODE_LOWLIGHT) {
+
m9mo_wait_framesync(sd);
+ if (state->running_capture_mode == RUNNING_MODE_WB_BRACKET
+ || state->running_capture_mode == RUNNING_MODE_RAW) {
+ err = m9mo_readw(sd, M9MO_CATEGORY_SYS,
+ M9MO_SYS_INT_EN, &int_en);
+ CHECK_ERR(err);
+
+ if (int_en & M9MO_INT_SOUND) {
+ /* Clear Interrupt factor */
+ int_factor = m9mo_wait_interrupt(sd,
+ M9MO_SOUND_TIMEOUT);
+ if (!(int_factor & M9MO_INT_SOUND)) {
+ cam_warn("M9MO_INT_SOUND isn't issued, %#x\n",
+ int_factor);
+ return -ETIMEDOUT;
+ }
+ }
+ }
/* Clear Interrupt factor */
- int_factor = m9mo_wait_interrupt(sd, M9MO_ISP_TIMEOUT);
+ int_factor = m9mo_wait_interrupt(sd, M9MO_ISP_CAPTURE_TIMEOUT);
if (!(int_factor & M9MO_INT_CAPTURE)) {
cam_warn("M9MO_INT_CAPTURE isn't issued, %#x\n",
int_factor);
@@ -646,18 +747,153 @@ static int m9mo_set_mode(struct v4l2_subdev *sd, u32 mode)
return old_mode;
}
-static int m9mo_set_capture_mode(struct v4l2_subdev *sd, int val)
+static int m9mo_set_mode_part1(struct v4l2_subdev *sd, u32 mode)
{
- int err, capture_val, shutter_val;
+ int i, err;
+ u32 old_mode, val;
+ u32 int_factor;
+ u32 int_en;
struct m9mo_state *state = to_state(sd);
+ state->stream_on_part2 = false;
cam_trace("E\n");
- state->running_capture_mode = val;
+ err = m9mo_readb(sd, M9MO_CATEGORY_SYS, M9MO_SYS_MODE, &old_mode);
- err = m9mo_readb(sd, M9MO_CATEGORY_ADJST,
- M9MO_ADJST_SHUTTER_MODE, &shutter_val);
- CHECK_ERR(err);
+ if (err < 0)
+ return err;
+
+ /* don't change mode when cap -> param */
+ if (old_mode == M9MO_STILLCAP_MODE && mode == M9MO_PARMSET_MODE)
+ return 10;
+
+#if 1 /* Dual Capture */
+ if (state->dual_capture_start && mode == M9MO_STILLCAP_MODE)
+ mode = M9MO_PARMSET_MODE;
+#endif
+
+ if (old_mode == mode) {
+ cam_dbg("%#x -> %#x\n", old_mode, mode);
+ return old_mode;
+ }
+
+ cam_dbg("%#x -> %#x\n", old_mode, mode);
+
+ switch (old_mode) {
+ case M9MO_SYSINIT_MODE:
+ cam_warn("sensor is initializing\n");
+ err = -EBUSY;
+ break;
+
+ case M9MO_PARMSET_MODE:
+ if (mode == M9MO_STILLCAP_MODE) {
+ err = m9mo_writeb(sd, M9MO_CATEGORY_SYS,
+ M9MO_SYS_MODE, M9MO_MONITOR_MODE);
+ if (err < 0)
+ break;
+ for (i = M9MO_I2C_VERIFY; i; i--) {
+ err = m9mo_readb(sd, M9MO_CATEGORY_SYS,
+ M9MO_SYS_MODE, &val);
+ if (val == M9MO_MONITOR_MODE)
+ break;
+ msleep(20);
+ }
+ }
+ case M9MO_MONITOR_MODE:
+ case M9MO_STILLCAP_MODE:
+ err = m9mo_writeb(sd, M9MO_CATEGORY_SYS, M9MO_SYS_MODE, mode);
+ break;
+
+ default:
+ cam_warn("current mode is unknown, %d\n", old_mode);
+ err = 0;/* -EINVAL; */
+ }
+
+ if (err < 0)
+ return err;
+
+ if (mode == M9MO_STILLCAP_MODE
+ && state->running_capture_mode != RUNNING_MODE_AE_BRACKET
+ && state->running_capture_mode != RUNNING_MODE_LOWLIGHT) {
+
+ err = m9mo_readw(sd, M9MO_CATEGORY_SYS,
+ M9MO_SYS_INT_EN, &int_en);
+ CHECK_ERR(err);
+
+ if (int_en & M9MO_INT_SOUND) {
+ /* Clear Interrupt factor */
+ int_factor = m9mo_wait_interrupt(sd,
+ M9MO_SOUND_TIMEOUT);
+ if (!(int_factor & M9MO_INT_SOUND)) {
+ cam_warn("M9MO_INT_SOUND isn't issued, %#x\n",
+ int_factor);
+ return -ETIMEDOUT;
+ }
+ }
+ }
+
+ state->stream_on_part2 = true;
+
+ cam_trace("X\n");
+ return old_mode;
+}
+
+static int m9mo_set_mode_part2(struct v4l2_subdev *sd, u32 mode)
+{
+ int i, err;
+ u32 val;
+ u32 int_factor;
+ struct m9mo_state *state = to_state(sd);
+
+ if (state->running_capture_mode != RUNNING_MODE_SINGLE)
+ return 0;
+
+ if (state->stream_on_part2 == false)
+ return 0;
+
+ cam_trace("E, %d\n", mode);
+
+#if 1 /* Dual Capture */
+ if (state->dual_capture_start && mode == M9MO_STILLCAP_MODE)
+ mode = M9MO_PARMSET_MODE;
+#endif
+
+ if (mode == M9MO_STILLCAP_MODE
+ && state->running_capture_mode != RUNNING_MODE_AE_BRACKET
+ && state->running_capture_mode != RUNNING_MODE_LOWLIGHT) {
+
+ /* m9mo_wait_framesync(sd); */
+
+ /* Clear Interrupt factor */
+ int_factor = m9mo_wait_interrupt(sd, M9MO_ISP_CAPTURE_TIMEOUT);
+ if (!(int_factor & M9MO_INT_CAPTURE)) {
+ cam_warn("M9MO_INT_CAPTURE isn't issued, %#x\n",
+ int_factor);
+ return -ETIMEDOUT;
+ }
+ }
+
+ for (i = M9MO_I2C_VERIFY; i; i--) {
+ err = m9mo_readb(sd, M9MO_CATEGORY_SYS, M9MO_SYS_MODE, &val);
+ if (val == mode)
+ break;
+ msleep(20);
+ }
+
+ state->stream_on_part2 = false;
+
+ cam_trace("X\n");
+ return 0;
+}
+
+static int m9mo_set_capture_mode(struct v4l2_subdev *sd, int val)
+{
+ int err, capture_val, framecount, raw_enable;
+ struct m9mo_state *state = to_state(sd);
+
+ cam_trace("E capture_mode=%d\n", val);
+
+ state->running_capture_mode = val;
err = m9mo_readb(sd, M9MO_CATEGORY_CAPCTRL,
M9MO_CAPCTRL_CAP_MODE, &capture_val);
@@ -665,116 +901,133 @@ static int m9mo_set_capture_mode(struct v4l2_subdev *sd, int val)
switch (state->running_capture_mode) {
case RUNNING_MODE_CONTINUOUS:
- if (shutter_val != 0x00) {
- err = m9mo_writeb(sd, M9MO_CATEGORY_ADJST,
- M9MO_ADJST_SHUTTER_MODE, 0x00);
- CHECK_ERR(err);
- }
+ case RUNNING_MODE_BEST:
+ cam_dbg("m9mo_set_capture_mode() CONTINUOUS fps=%d\n",
+ state->continueFps);
- if (capture_val != M9MO_CAP_MODE_MULTI_CAPTURE) {
- err = m9mo_writeb(sd, M9MO_CATEGORY_CAPCTRL,
- M9MO_CAPCTRL_CAP_MODE,
- M9MO_CAP_MODE_MULTI_CAPTURE);
- CHECK_ERR(err);
- }
err = m9mo_writeb(sd, M9MO_CATEGORY_CAPCTRL,
- M9MO_CAPCTRL_CAP_FRM_COUNT, 0x09);
+ M9MO_CAPCTRL_CAP_MODE, M9MO_CAP_MODE_MULTI_CAPTURE);
CHECK_ERR(err);
-#if 0
- switch (state->) {
- case _CONTI_3:
- cam_trace("~~~~~~ Continuous 3 ~~~~~~\n");
- err = m9mo_writeb(sd, M9MO_CATEGORY_CAPCTRL,
- M9MO_CAPCTRL_CAP_FRM_INTERVAL, 0x03);
- CHECK_ERR(err);
- break;
+ err = m9mo_writeb(sd, M9MO_CATEGORY_CAPCTRL,
+ M9MO_CAPCTRL_CAP_FRM_INTERVAL,
+ state->continueFps);
+ CHECK_ERR(err); /* 0:7.5, 1:5, 2:3fps */
- case _CONTI_5:
- cam_trace("~~~~~~ Continuous 5 ~~~~~~\n");
- err = m9mo_writeb(sd, M9MO_CATEGORY_CAPCTRL,
- M9MO_CAPCTRL_CAP_FRM_INTERVAL, 0x01);
- CHECK_ERR(err);
- break;
+ framecount = 0x0A;
+ if (state->running_capture_mode == RUNNING_MODE_BEST)
+ framecount = 0x08;
- case _CONTI_10:
- cam_trace("~~~~~~ Continuous 10 ~~~~~~\n");
- err = m9mo_writeb(sd, M9MO_CATEGORY_CAPCTRL,
- M9MO_CAPCTRL_CAP_FRM_INTERVAL, 0x00);
- CHECK_ERR(err);
- break;
- }
+ cam_dbg("m9mo_set_capture_mode() framecount=%d\n",
+ framecount);
+
+ err = m9mo_writeb(sd, M9MO_CATEGORY_CAPCTRL,
+ M9MO_CAPCTRL_CAP_FRM_COUNT, framecount+1);
+ CHECK_ERR(err); /* frame count : A */
+
+ err = m9mo_writeb(sd, M9MO_CATEGORY_CAPCTRL, 0x03, 0x01);
+ CHECK_ERR(err); /* Enable limited framerate*/
+
+ err = m9mo_writeb(sd, M9MO_CATEGORY_NEW, 0x18, 0x03);
+ CHECK_ERR(err); /* OIS */
+
+ /* AF proc */
+#if 0
+ err = m9mo_writeb(sd, M9MO_CATEGORY_SYS, M9MO_SYS_INT_EN, 0x99);
+ CHECK_ERR(err);
#endif
- break;
+ err = m9mo_writeb(sd, M9MO_CATEGORY_SYS,
+ M9MO_SYS_MODE, M9MO_STILLCAP_MODE);
+ CHECK_ERR(err);
- case RUNNING_MODE_BRACKET:
- cam_trace("~~~~~~ AutoBracket ~~~~~~\n");
- if (shutter_val != 0x00) {
- err = m9mo_writeb(sd, M9MO_CATEGORY_ADJST,
- M9MO_ADJST_SHUTTER_MODE, 0x00);
- CHECK_ERR(err);
+ cam_dbg("continue image Start ==========================\n");
+
+ err = m9mo_wait_interrupt(sd, M9MO_ISP_TIMEOUT);
+ if (!(err & M9MO_INT_FRAME_SYNC)) {
+ cam_err("m9mo_set_capture_mode() FRAME_SYNC error\n");
+ return -ETIMEDOUT;
}
+ break;
+ case RUNNING_MODE_AE_BRACKET:
+ case RUNNING_MODE_LOWLIGHT:
+ cam_trace("~~~~~~ AutoBracket AEB ~~~~~~\n");
if (capture_val != M9MO_CAP_MODE_BRACKET_CAPTURE) {
err = m9mo_writeb(sd, M9MO_CATEGORY_CAPCTRL,
M9MO_CAPCTRL_CAP_MODE,
M9MO_CAP_MODE_BRACKET_CAPTURE);
CHECK_ERR(err);
}
- break;
- case RUNNING_MODE_HDR:
- cam_trace("~~~~~~ HDRmode capture ~~~~~~\n");
- if (shutter_val != 0x00) {
- err = m9mo_writeb(sd, M9MO_CATEGORY_ADJST,
- M9MO_ADJST_SHUTTER_MODE, 0x00);
+ if (state->running_capture_mode == RUNNING_MODE_LOWLIGHT) {
+ err = m9mo_writeb(sd, M9MO_CATEGORY_AE,
+ M9MO_AE_AUTO_BRACKET_EV, 0x0); /* EV 0.0 */
+ }
+
+ err = m9mo_writeb(sd, M9MO_CATEGORY_CAPCTRL,
+ M9MO_CAPCTRL_CAP_FRM_INTERVAL, 0x02);
+ CHECK_ERR(err); /* 0:7.5, 1:5, 2:3fps */
+ break;
+
+ case RUNNING_MODE_WB_BRACKET:
+ cam_trace("~~~~~~ AutoBracket WBB ~~~~~~\n");
+ if (capture_val != M9MO_CAP_MODE_SINGLE_CAPTURE) {
+ err = m9mo_writeb(sd, M9MO_CATEGORY_CAPCTRL,
+ M9MO_CAPCTRL_CAP_MODE,
+ M9MO_CAP_MODE_SINGLE_CAPTURE);
CHECK_ERR(err);
}
+ break;
+ case RUNNING_MODE_HDR:
+ cam_trace("~~~~~~ HDRmode capture ~~~~~~\n");
if (capture_val != M9MO_CAP_MODE_BRACKET_CAPTURE) {
err = m9mo_writeb(sd, M9MO_CATEGORY_CAPCTRL,
M9MO_CAPCTRL_CAP_MODE,
M9MO_CAP_MODE_BRACKET_CAPTURE);
CHECK_ERR(err);
}
+
+ err = m9mo_writeb(sd, M9MO_CATEGORY_CAPCTRL,
+ M9MO_CAPCTRL_CAP_FRM_INTERVAL, 0x00);
+ CHECK_ERR(err); /* 0:7.5, 1:5, 2:3fps */
break;
case RUNNING_MODE_BLINK:
cam_trace("~~~~~~ EyeBlink capture ~~~~~~\n");
- if (shutter_val != 0x00) {
- err = m9mo_writeb(sd, M9MO_CATEGORY_ADJST,
- M9MO_ADJST_SHUTTER_MODE, 0x00);
- CHECK_ERR(err);
- }
-
if (capture_val != M9MO_CAP_MODE_BLINK_CAPTURE) {
err = m9mo_writeb(sd, M9MO_CATEGORY_CAPCTRL,
M9MO_CAPCTRL_CAP_MODE,
M9MO_CAP_MODE_BLINK_CAPTURE);
CHECK_ERR(err);
- /* Set frame rate (0x00, 12 fps) */
- /* err = m9mo_writeb(sd, M9MO_CATEGORY_CAPCTRL,
- M9MO_CAPCTRL_CAP_FRM_INTERVAL, 0x00);
- CHECK_ERR(err); */
- /* Set frame count (0x03, 3 frames) */
- /* err = m9mo_writeb(sd, M9MO_CATEGORY_CAPCTRL,
- M9MO_CAPCTRL_CAP_FRM_COUNT, 0x03);
- CHECK_ERR(err); */
}
break;
- case RUNNING_MODE_SINGLE:
- default:
- cam_trace("~~~~~~ Single capture ~~~~~~\n");
- if (shutter_val != 0x01) {
- err = m9mo_writeb(sd, M9MO_CATEGORY_ADJST,
- M9MO_ADJST_SHUTTER_MODE, 0x01);
+ case RUNNING_MODE_RAW:
+ cam_trace("~~~~~~ raw capture ~~~~~~\n");
+ err = m9mo_readb(sd, M9MO_CATEGORY_CAPPARM,
+ 0x78, &raw_enable);
+ CHECK_ERR(err);
+
+ /* if (capture_val != M9MO_CAP_MODE_RAW) always run */
+ if (raw_enable != 0x01) {
+ err = m9mo_writeb(sd, M9MO_CATEGORY_CAPPARM,
+ 0x78, 0x01);
CHECK_ERR(err);
}
+ break;
+
+ case RUNNING_MODE_BURST:
+ cam_trace("~~~~~~ burst capture mode ~~~~~~\n");
+ break;
+ case RUNNING_MODE_SINGLE:
+ default:
+ cam_trace("~~~~~~ Single capture ~~~~~~\n");
if (capture_val != M9MO_CAP_MODE_SINGLE_CAPTURE) {
err = m9mo_writeb(sd, M9MO_CATEGORY_CAPCTRL,
- M9MO_CAPCTRL_CAP_MODE, 0x00);
+ M9MO_CAPCTRL_CAP_MODE,
+ M9MO_CAP_MODE_SINGLE_CAPTURE);
CHECK_ERR(err);
}
break;
@@ -804,24 +1057,609 @@ static int m9mo_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
return -EINVAL;
}
+
+static int m9mo_set_lock(struct v4l2_subdev *sd, int val)
+{
+ struct m9mo_state *state = to_state(sd);
+ int err, status;
+ int cnt = 100;
+
+ cam_trace("%s\n", val ? "on" : "off");
+
+ if (state->running_capture_mode == RUNNING_MODE_BURST)
+ return 0;
+
+ err = m9mo_writeb(sd, M9MO_CATEGORY_AE, M9MO_AF_AE_LOCK, val);
+ CHECK_ERR(err);
+
+ /* check AE stability before AE,AWB lock */
+ if (val == 1) {
+ err = m9mo_readb(sd, M9MO_CATEGORY_AE,
+ M9MO_AE_STABILITY, &status);
+
+ while (!status && cnt) {
+ msleep(10);
+ err = m9mo_readb(sd, M9MO_CATEGORY_AE,
+ M9MO_AE_STABILITY, &status);
+ CHECK_ERR(err);
+ cnt--;
+ }
+ }
+
+ err = m9mo_writeb(sd, M9MO_CATEGORY_AE, M9MO_AE_LOCK, val);
+ CHECK_ERR(err);
+ err = m9mo_writeb(sd, M9MO_CATEGORY_WB, M9MO_AWB_LOCK, val);
+ CHECK_ERR(err);
+
+ state->focus.lock = val;
+
+ cam_trace("X\n");
+ return 0;
+}
+
+static int m9mo_set_CAF(struct v4l2_subdev *sd, int val)
+{
+ int err, range_status, af_range, zoom_status;
+ struct m9mo_state *state = to_state(sd);
+
+ if (state->fps == 120) {
+ cam_info("not supported on 120 fps !!!\n");
+ return 0;
+ }
+
+ err = m9mo_readb2(sd, M9MO_CATEGORY_LENS,
+ M9MO_LENS_ZOOM_STATUS, &zoom_status);
+ CHECK_ERR(err);
+
+ if (zoom_status == 1 && val == 1) {
+ cam_info("zoom moving !!! val : %d\n", val);
+ return 0;
+ }
+
+ state->caf_state = val;
+
+ if (val == 1) {
+ if (state->focus.status != 0x1000) {
+ /* Set LOCK OFF */
+ if (state->focus.lock && state->focus.status != 0x1000)
+ m9mo_set_lock(sd, 0);
+
+ /* Set mode to Continuous */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_LENS,
+ M9MO_LENS_AF_MODE, 0x01);
+ CHECK_ERR(err);
+
+ err = m9mo_readb(sd, M9MO_CATEGORY_LENS,
+ M9MO_LENS_AF_SCAN_RANGE, &range_status);
+
+ /* Set range to macro or auto-macro */
+ if (state->mode == MODE_CLOSE_UP)
+ af_range = 0x01;
+ else
+ af_range = 0x02;
+
+ err = m9mo_writeb(sd, M9MO_CATEGORY_LENS,
+ M9MO_LENS_AF_SCAN_RANGE, af_range);
+ CHECK_ERR(err);
+
+ /* Set Zone REQ */
+ if (range_status != af_range) {
+ err = m9mo_writeb(sd, M9MO_CATEGORY_LENS,
+ M9MO_LENS_AF_INITIAL, 0x04);
+ CHECK_ERR(err);
+ }
+
+ /* Start Continuous AF */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_LENS,
+ M9MO_LENS_AF_START_STOP, 0x01);
+ CHECK_ERR(err);
+ }
+ } else {
+ /* Stop Continuous AF */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_LENS,
+ M9MO_LENS_AF_START_STOP, 0x02);
+ CHECK_ERR(err);
+
+ /* need delay for AF stable time */
+ if (state->focus.mode == FOCUS_MODE_CONTINOUS)
+ msleep(100);
+ }
+
+ cam_trace("X val : %d %d\n", val, state->focus.mode);
+ return 0;
+}
+
static int m9mo_get_af_result(struct v4l2_subdev *sd,
- struct v4l2_control *ctrl);
+ struct v4l2_control *ctrl)
+{
+ struct m9mo_state *state = to_state(sd);
+ int status, err;
+ static int get_cnt;
+
+ cam_trace("E, cnt: %d, status: 0x%x\n", get_cnt, state->focus.status);
+
+ get_cnt++;
+
+ err = m9mo_readw2(sd, M9MO_CATEGORY_LENS,
+ M9MO_LENS_AF_RESULT, &status);
+ CHECK_ERR(err);
+
+ if ((status != 0x1000) && (status != 0x0)) {
+ cam_dbg("~~~ success !!!~~~\n");
+ msleep(33);
+ get_cnt = 0;
+ } else if (status == 0x0) {
+ cam_dbg("~~~ fail !!!~~~\n");
+ msleep(33);
+ get_cnt = 0;
+ } else if (status == 0x1000) {
+ cam_dbg("~~~ focusing !!!~~~\n");
+ }
+
+ if (state->focus.mode == FOCUS_MODE_TOUCH && status != 0x1000)
+ m9mo_set_lock(sd, 0);
+
+ if (state->focus.lock && !(state->focus.start) && status != 0x1000)
+ m9mo_set_lock(sd, 0);
+
+ state->focus.status = status;
+
+ if (state->caf_state && !(state->focus.start) && status != 0x1000)
+ m9mo_set_CAF(sd, 1);
+
+ ctrl->value = state->focus.status;
+
+ cam_dbg("X, value 0x%04x\n", ctrl->value);
+
+ return ctrl->value;
+}
static int m9mo_get_scene_mode(struct v4l2_subdev *sd,
struct v4l2_control *ctrl)
{
int err;
- err = m9mo_readb(sd, M9MO_CATEGORY_NEW,
+ err = m9mo_readb2(sd, M9MO_CATEGORY_NEW,
M9MO_NEW_DETECT_SCENE, &ctrl->value);
+#if 0
+ cam_trace("mode : %d\n", ctrl->value);
+#endif
+
+ return ctrl->value;
+}
+
+static int m9mo_get_scene_sub_mode(struct v4l2_subdev *sd,
+ struct v4l2_control *ctrl)
+{
+ int err;
+
+ err = m9mo_readb2(sd, M9MO_CATEGORY_NEW, 0x0C, &ctrl->value);
+
return ctrl->value;
}
+static int m9mo_get_zoom_level(struct v4l2_subdev *sd,
+ struct v4l2_control *ctrl)
+{
+ struct m9mo_state *state = to_state(sd);
+ int err;
+ int zoom_level, zoom_status, zoom_lens_status;
+
+ err = m9mo_readb2(sd, M9MO_CATEGORY_LENS,
+ M9MO_LENS_ZOOM_LEVEL_INFO, &zoom_level);
+ CHECK_ERR(err);
+
+ err = m9mo_readb2(sd, M9MO_CATEGORY_LENS,
+ M9MO_LENS_ZOOM_STATUS, &zoom_status);
+ CHECK_ERR(err);
+
+ err = m9mo_readb2(sd, M9MO_CATEGORY_LENS,
+ M9MO_LENS_ZOOM_LENS_STATUS, &zoom_lens_status);
+ CHECK_ERR(err);
+
+ if (state->zoom <= 0xF && (zoom_level & 0xF) < 0xF)
+ state->zoom = zoom_level & 0xF;
+ ctrl->value = ((0x1 & zoom_status) << 4)
+ | ((0x1 & zoom_lens_status) << 5)
+ | (0xF & zoom_level);
+
+ return 0;
+}
+
+static int m9mo_get_zoom_status(struct v4l2_subdev *sd,
+ struct v4l2_control *ctrl)
+{
+ struct m9mo_state *state = to_state(sd);
+ int err;
+ int curr_zoom_info;
+
+ err = m9mo_readb2(sd, M9MO_CATEGORY_PRO_MODE,
+ M9MO_PRO_SMART_READ3, &curr_zoom_info);
+ CHECK_ERR(err);
+
+ if (state->zoom <= 0xF && (curr_zoom_info & 0xF) < 0xF)
+ state->zoom = curr_zoom_info & 0xF;
+ ctrl->value = curr_zoom_info & 0x3F;
+
+ return 0;
+}
+
+static int m9mo_get_smart_read1(struct v4l2_subdev *sd,
+ struct v4l2_control *ctrl)
+{
+ int value, err;
+
+ err = m9mo_readl2(sd, M9MO_CATEGORY_PRO_MODE,
+ M9MO_PRO_SMART_READ1, &value);
+ CHECK_ERR(err);
+
+ ctrl->value = value;
+
+ return ctrl->value;
+}
+
+static int m9mo_get_smart_read2(struct v4l2_subdev *sd,
+ struct v4l2_control *ctrl)
+{
+ int value, err;
+
+ err = m9mo_readl2(sd, M9MO_CATEGORY_PRO_MODE,
+ M9MO_PRO_SMART_READ2, &value);
+ CHECK_ERR(err);
+
+ ctrl->value = value;
+
+ return ctrl->value;
+}
+
+static int m9mo_get_lens_status(struct v4l2_subdev *sd,
+ struct v4l2_control *ctrl)
+{
+ int value, err;
+
+ err = m9mo_readb2(sd, M9MO_CATEGORY_LENS,
+ M9MO_LENS_LENS_STATUS, &value);
+ CHECK_ERR(err);
+
+ ctrl->value = value;
+
+ return ctrl->value;
+}
+
+static int m9mo_get_flash_status(struct v4l2_subdev *sd,
+ struct v4l2_control *ctrl)
+{
+ int err;
+ int strobe_charge, strobe_up_down;
+
+ err = m9mo_readb2(sd, M9MO_CATEGORY_CAPPARM,
+ M9MO_CAPPARM_STROBE_CHARGE, &strobe_charge);
+ CHECK_ERR(err);
+
+ err = m9mo_readb2(sd, M9MO_CATEGORY_CAPPARM,
+ M9MO_CAPPARM_STROBE_UP_DOWN, &strobe_up_down);
+ CHECK_ERR(err);
+
+ strobe_charge &= 0xFF;
+ strobe_up_down &= 0xFF;
+
+ ctrl->value = strobe_charge | (strobe_up_down << 8);
+
+#if 0
+ cam_trace(": strobe_charge %d up_down %d\n",
+ strobe_charge, strobe_up_down);
+#endif
+
+ return 0;
+}
+
+static int m9mo_get_object_tracking(struct v4l2_subdev *sd,
+ struct v4l2_control *ctrl)
+{
+ struct m9mo_state *state = to_state(sd);
+ int err;
+#if 0
+ int ot_ready, cnt = 30;
+#endif
+
+ err = m9mo_readb2(sd, M9MO_CATEGORY_OT,
+ M9MO_OT_TRACKING_STATUS, &state->ot_status);
+ CHECK_ERR(err);
+
+#if 0
+ if (state->ot_status != OBJECT_TRACKING_STATUS_SUCCESS)
+ return 0;
+
+ err = m9mo_readb2(sd, M9MO_CATEGORY_OT,
+ M9MO_OT_INFO_READY, &ot_ready);
+ CHECK_ERR(err);
+ while (ot_ready && cnt) {
+ msleep(20);
+ err = m9mo_readb(sd, M9MO_CATEGORY_OT,
+ M9MO_OT_INFO_READY, &ot_ready);
+ CHECK_ERR(err);
+ cnt--;
+ }
+
+ err = m9mo_readw(sd, M9MO_CATEGORY_OT,
+ M9MO_OT_TRACKING_X_LOCATION,
+ &state->ot_x_loc);
+ CHECK_ERR(err);
+ err = m9mo_readw(sd, M9MO_CATEGORY_OT,
+ M9MO_OT_TRACKING_Y_LOCATION,
+ &state->ot_y_loc);
+ CHECK_ERR(err);
+ err = m9mo_readw(sd, M9MO_CATEGORY_OT,
+ M9MO_OT_TRACKING_FRAME_WIDTH,
+ &state->ot_width);
+ CHECK_ERR(err);
+ err = m9mo_readw(sd, M9MO_CATEGORY_OT,
+ M9MO_OT_TRACKING_FRAME_HEIGHT,
+ &state->ot_height);
+ CHECK_ERR(err);
+ cam_dbg("OT pos x: %d, y: %d, w: %d, h: %d\n",
+ state->ot_x_loc, state->ot_y_loc,
+ state->ot_width, state->ot_height);
+
+ cam_trace("X status : %d\n", state->ot_status);
+#endif
+ return 0;
+}
+
+static int m9mo_get_warning_condition(struct v4l2_subdev *sd,
+ struct v4l2_control *ctrl)
+{
+ int value, err;
+
+ err = m9mo_readw2(sd, M9MO_CATEGORY_PRO_MODE,
+ 0x03, &value);
+ CHECK_ERR(err);
+
+ ctrl->value = value;
+
+ return ctrl->value;
+}
+
+static int m9mo_get_av(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+{
+ struct m9mo_state *state = to_state(sd);
+ int value, err;
+
+ err = m9mo_readl2(sd, M9MO_CATEGORY_AE,
+ M9MO_AE_NOW_AV, &value);
+ CHECK_ERR(err);
+
+ ctrl->value = value;
+ state->AV = value;
+
+ return ctrl->value;
+}
+
+static int m9mo_get_tv(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+{
+ struct m9mo_state *state = to_state(sd);
+ int value, err;
+
+ err = m9mo_readl2(sd, M9MO_CATEGORY_AE,
+ M9MO_AE_NOW_TV, &value);
+ CHECK_ERR(err);
+
+ ctrl->value = value;
+ state->TV = value;
+
+ return ctrl->value;
+}
+
+static int m9mo_get_sv(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+{
+ struct m9mo_state *state = to_state(sd);
+ int value, err;
+
+ err = m9mo_readl2(sd, M9MO_CATEGORY_AE,
+ M9MO_AE_NOW_SV, &value);
+ CHECK_ERR(err);
+
+ ctrl->value = value;
+ state->SV = ctrl->value;
+
+ return ctrl->value;
+}
+
+static int m9mo_get_ev(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+{
+ struct m9mo_state *state = to_state(sd);
+
+ state->EV = state->AV + state->TV;
+
+ return state->EV;
+}
+
+static int m9mo_get_lv(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+{
+ struct m9mo_state *state = to_state(sd);
+ int value, err;
+
+ err = m9mo_readb2(sd, M9MO_CATEGORY_AE,
+ M9MO_AE_NOW_LV, &value);
+ CHECK_ERR(err);
+
+ ctrl->value = value;
+ state->LV = ctrl->value;
+
+ return ctrl->value;
+}
+
+
+static int m9mo_get_WBcustomX(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+{
+ struct m9mo_state *state = to_state(sd);
+ int value, value2, err, int_factor, int_en;
+ int changed_capture_mode = false;
+
+ if (state->running_capture_mode != M9MO_CAP_MODE_SINGLE_CAPTURE) {
+ err = m9mo_writeb(sd, M9MO_CATEGORY_CAPCTRL,
+ M9MO_CAPCTRL_CAP_MODE,
+ M9MO_CAP_MODE_SINGLE_CAPTURE);
+ CHECK_ERR(err);
+ changed_capture_mode = true;
+ }
+
+ err = m9mo_writeb(sd, M9MO_CATEGORY_WB,
+ M9MO_WB_AWB_MODE, 0x02);
+ CHECK_ERR(err);
+
+ err = m9mo_writeb(sd, M9MO_CATEGORY_WB,
+ M9MO_WB_AWB_MANUAL, 0x08);
+ CHECK_ERR(err);
+
+ err = m9mo_writeb(sd, M9MO_CATEGORY_WB,
+ M9MO_WB_CWB_MODE, 0x02);
+ CHECK_ERR(err);
+
+ err = m9mo_writeb(sd, M9MO_CATEGORY_SYS,
+ M9MO_SYS_MODE, M9MO_STILLCAP_MODE);
+ CHECK_ERR(err);
+
+ err = m9mo_readw(sd, M9MO_CATEGORY_SYS,
+ M9MO_SYS_INT_EN, &int_en);
+ CHECK_ERR(err);
+
+ if (int_en & M9MO_INT_SOUND) {
+ /* Clear Interrupt factor */
+ int_factor = m9mo_wait_interrupt(sd, M9MO_SOUND_TIMEOUT);
+ if (!(int_factor & M9MO_INT_SOUND)) {
+ cam_warn("M9MO_INT_SOUND isn't issued, %#x\n",
+ int_factor);
+ return -ETIMEDOUT;
+ }
+ }
+
+ int_factor = m9mo_wait_interrupt(sd, M9MO_ISP_TIMEOUT);
+ if (!(int_factor & M9MO_INT_CAPTURE)) {
+ cam_warn("M9MO_INT_CAPTURE isn't issued, %#x\n",
+ int_factor);
+ return -ETIMEDOUT;
+ }
+
+ m9mo_set_mode(sd, M9MO_MONITOR_MODE);
+
+ err = m9mo_wait_interrupt(sd, M9MO_ISP_TIMEOUT);
+ if (!(err & M9MO_INT_MODE)) {
+ cam_err("firmware was erased?\n");
+ return -ETIMEDOUT;
+ }
+
+ err = m9mo_readw(sd, M9MO_CATEGORY_WB,
+ M9MO_WB_GET_CUSTOM_RG, &value);
+ CHECK_ERR(err);
+
+ err = m9mo_readw(sd, M9MO_CATEGORY_WB,
+ M9MO_WB_GET_CUSTOM_BG, &value2);
+ CHECK_ERR(err);
+
+ /* prevent abnormal value, to be fixed by ISP */
+ if (value == 0)
+ value = 424;
+ if (value2 == 0)
+ value2 = 452;
+
+ state->wb_custom_rg = value;
+ state->wb_custom_bg = value2;
+
+ err = m9mo_writeb(sd, M9MO_CATEGORY_WB,
+ M9MO_WB_CWB_MODE, 0x02);
+ CHECK_ERR(err);
+
+ err = m9mo_writew(sd, M9MO_CATEGORY_WB,
+ M9MO_WB_SET_CUSTOM_RG, state->wb_custom_rg);
+ CHECK_ERR(err);
+ err = m9mo_writew(sd, M9MO_CATEGORY_WB,
+ M9MO_WB_SET_CUSTOM_BG, state->wb_custom_bg);
+ CHECK_ERR(err);
+
+ err = m9mo_writeb(sd, M9MO_CATEGORY_WB,
+ M9MO_WB_CWB_MODE, 0x01);
+ CHECK_ERR(err);
+
+ if (changed_capture_mode)
+ m9mo_set_capture_mode(sd, state->running_capture_mode);
+
+ cam_trace("X value : %d value2 : %d\n", value, value2);
+
+ return value;
+}
+
+static int m9mo_get_WBcustomY(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+{
+ struct m9mo_state *state = to_state(sd);
+
+ return state->wb_custom_bg;
+}
+
+static int m9mo_get_face_detect_number(struct v4l2_subdev *sd,
+ struct v4l2_control *ctrl)
+{
+ struct m9mo_state *state = to_state(sd);
+ int value, err;
+
+ err = m9mo_readb2(sd, M9MO_CATEGORY_FD, 0x0A, &value);
+ CHECK_ERR(err);
+
+ state->fd_num = value;
+
+#if 0
+ cam_trace("X %d\n", value);
+#endif
+
+ return value;
+}
+
+static int m9mo_get_factory_FW_info(struct v4l2_subdev *sd,
+ struct v4l2_control *ctrl)
+{
+ int err = 0;
+ u32 read_val1, read_val2;
+ u32 ver = 0;
+
+ m9mo_readb(sd, M9MO_CATEGORY_SYS,
+ 0x02, &read_val1);
+ CHECK_ERR(err);
+
+ m9mo_readb(sd, M9MO_CATEGORY_SYS,
+ 0x03, &read_val2);
+ CHECK_ERR(err);
+
+ ver = 0;
+ ver = (read_val1 << 8) | (read_val2);
+
+ cam_trace("m9mo_get_factory_FW : 0x%x\n", ver);
+ ctrl->value = ver;
+
+ return 0;
+}
+
+static int m9mo_get_factory_OIS_info(struct v4l2_subdev *sd,
+ struct v4l2_control *ctrl)
+{
+ int err;
+ u32 ver = 0;
+
+ err = m9mo_readl(sd, M9MO_CATEGORY_NEW,
+ 0x1B, &ver);
+ CHECK_ERR(err);
+
+ cam_trace("m9mo_get_factory_FW : 0x%x\n", ver);
+ ctrl->value = ver;
+
+ return 0;
+}
+
static int m9mo_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
{
struct m9mo_state *state = to_state(sd);
int err = 0;
+ u32 val = 0;
switch (ctrl->id) {
case V4L2_CID_CAMERA_AUTO_FOCUS_RESULT:
@@ -869,17 +1707,132 @@ static int m9mo_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
ctrl->value = state->exif.bv;
break;
+ case V4L2_CID_CAMERA_EXIF_AV:
+ ctrl->value = state->exif.av;
+ break;
+
case V4L2_CID_CAMERA_EXIF_EBV:
ctrl->value = state->exif.ebv;
break;
+ case V4L2_CID_CAMERA_EXIF_FL:
+ ctrl->value = state->exif.focal_length;
+ break;
+
+ case V4L2_CID_CAMERA_EXIF_FL_35mm:
+ ctrl->value = state->exif.focal_35mm_length;
+ break;
+
case V4L2_CID_CAMERA_FD_EYE_BLINK_RESULT:
ctrl->value = state->fd_eyeblink_cap;
break;
+ case V4L2_CID_CAMERA_RED_EYE_FIX_RESULT:
+ ctrl->value = state->fd_red_eye_status;
+ break;
+
case V4L2_CID_CAMERA_SCENE_MODE:
err = m9mo_get_scene_mode(sd, ctrl);
- cam_info("Smart scene mode = %d\n", ctrl->value);
+ break;
+
+ case V4L2_CID_CAMERA_SCENE_SUB_MODE:
+ err = m9mo_get_scene_sub_mode(sd, ctrl);
+ break;
+
+ case V4L2_CID_CAMERA_FACTORY_DOWN_RESULT:
+ ctrl->value = state->factory_down_check;
+ break;
+
+ case V4L2_CID_CAMERA_FACTORY_AF_INT_RESULT:
+ ctrl->value = state->factory_result_check;
+ break;
+
+ case V4L2_CID_CAMERA_FACTORY_END_RESULT:
+ ctrl->value = state->factory_end_check;
+ cam_trace("leesm test ----- factory_end_check %d\n",
+ ctrl->value);
+ break;
+
+ case V4L2_CID_CAMERA_ZOOM:
+ err = m9mo_get_zoom_status(sd, ctrl);
+ break;
+
+ case V4L2_CID_CAMERA_OPTICAL_ZOOM_CTRL:
+ err = m9mo_get_zoom_level(sd, ctrl);
+ break;
+
+ case V4L2_CID_CAMERA_FLASH_MODE:
+ err = m9mo_get_flash_status(sd, ctrl);
+ break;
+
+ case V4L2_CID_CAMERA_OBJ_TRACKING_STATUS:
+ err = m9mo_get_object_tracking(sd, ctrl);
+ ctrl->value = state->ot_status;
+ break;
+
+ case V4L2_CID_CAMERA_AV:
+ ctrl->value = m9mo_get_av(sd, ctrl);
+ break;
+
+ case V4L2_CID_CAMERA_TV:
+ ctrl->value = m9mo_get_tv(sd, ctrl);
+ break;
+
+ case V4L2_CID_CAMERA_SV:
+ ctrl->value = m9mo_get_sv(sd, ctrl);
+ break;
+
+ case V4L2_CID_CAMERA_EV:
+ ctrl->value = m9mo_get_ev(sd, ctrl);
+ break;
+
+ case V4L2_CID_CAMERA_LV:
+ ctrl->value = m9mo_get_lv(sd, ctrl);
+ break;
+
+ case V4L2_CID_CAMERA_WB_CUSTOM_X:
+ ctrl->value = m9mo_get_WBcustomX(sd, ctrl);
+ break;
+
+ case V4L2_CID_CAMERA_WB_CUSTOM_Y:
+ ctrl->value = m9mo_get_WBcustomY(sd, ctrl);
+ break;
+
+ case V4L2_CID_CAMERA_GET_MODE:
+ err = m9mo_readb(sd, M9MO_CATEGORY_SYS,
+ M9MO_SYS_MODE, &val);
+ if (err < 0)
+ ctrl->value = -1;
+ else
+ ctrl->value = val;
+ break;
+
+ case V4L2_CID_CAMERA_SMART_READ1:
+ m9mo_get_smart_read1(sd, ctrl);
+ break;
+
+ case V4L2_CID_CAMERA_SMART_READ2:
+ m9mo_get_smart_read2(sd, ctrl);
+ break;
+
+ case V4L2_CID_CAMERA_LENS_STATUS:
+ m9mo_get_lens_status(sd, ctrl);
+ break;
+
+ case V4L2_CID_CAMERA_WARNING_CONDITION:
+ ctrl->value = m9mo_get_warning_condition(sd, ctrl);
+ break;
+
+ case V4L2_CID_CAMERA_FACTORY_ISP_FW_CHECK:
+ err = m9mo_get_factory_FW_info(sd, ctrl);
+ break;
+
+ case V4L2_CID_CAMERA_FACTORY_OIS_VER_CHECK:
+ err = m9mo_get_factory_OIS_info(sd, ctrl);
+ break;
+
+ case V4L2_CID_CAMERA_FACE_DETECT_NUMBER:
+ ctrl->value = m9mo_get_face_detect_number(sd, ctrl);
break;
default:
@@ -902,7 +1855,7 @@ static int m9mo_set_antibanding(struct v4l2_subdev *sd,
struct v4l2_queryctrl qc = {0,};
struct m9mo_state *state = to_state(sd);
int val = ctrl->value, err;
- u32 antibanding[] = {0x00, 0x01, 0x02, 0x03};
+ u32 antibanding[] = {0x00, 0x01, 0x02, 0x03, 0x04};
if (state->anti_banding == val)
return 0;
@@ -929,11 +1882,12 @@ static int m9mo_set_antibanding(struct v4l2_subdev *sd,
return 0;
}
-static int m9mo_set_af_softlanding(struct v4l2_subdev *sd)
+static int m9mo_set_lens_off(struct v4l2_subdev *sd)
{
struct m9mo_state *state = to_state(sd);
- u32 status = 0;
- int i, err = 0;
+ u32 int_factor = 0;
+ int err = 0;
+ int int_en;
cam_trace("E\n");
@@ -942,27 +1896,28 @@ static int m9mo_set_af_softlanding(struct v4l2_subdev *sd)
return -ENOSYS;
}
+ err = m9mo_readw(sd, M9MO_CATEGORY_SYS,
+ M9MO_SYS_INT_EN, &int_en);
+ CHECK_ERR(err);
+ int_en &= ~M9MO_INT_MODE;
+ err = m9mo_writew(sd, M9MO_CATEGORY_SYS,
+ M9MO_SYS_INT_EN, int_en);
+ CHECK_ERR(err);
+
err = m9mo_set_mode(sd, M9MO_MONITOR_MODE);
if (err <= 0) {
cam_err("failed to set mode\n");
return err;
}
- err = m9mo_writeb(sd, M9MO_CATEGORY_LENS, M9MO_LENS_AF_MODE, 0x07);
- CHECK_ERR(err);
-
- for (i = M9MO_I2C_VERIFY; i; i--) {
- msleep(20);
- err = m9mo_readb(sd, M9MO_CATEGORY_LENS,
- M9MO_LENS_AF_STATUS, &status);
- CHECK_ERR(err);
+ err = m9mo_writeb(sd, M9MO_CATEGORY_LENS,
+ 0x01, 0x00);
- if ((status & 0x01) == 0x00)
- break;
- }
+ int_factor = m9mo_wait_interrupt(sd, M9MO_ISP_TIMEOUT);
- if ((status & 0x01) != 0x00) {
- cam_err("failed\n");
+ if (!(int_factor & M9MO_INT_LENS_INIT)) {
+ cam_err("M9MO_INT_LENS_INIT isn't issued, %#x\n",
+ int_factor);
return -ETIMEDOUT;
}
@@ -1036,10 +1991,10 @@ static int m9mo_dump_fw(struct v4l2_subdev *sd)
addr = M9MO_FLASH_READ_BASE_ADDR;
unit = SZ_4K;
- count = 512;
+ count = 1024;
for (i = 0; i < count; i++) {
- err = m9mo_mem_read_1(sd,
+ err = m9mo_mem_dump(sd,
unit, addr + (i * unit), buf);
cam_err("dump ~~ %d\n", i);
if (err < 0) {
@@ -1076,37 +2031,97 @@ file_out:
return err;
}
-static int m9mo_get_sensor_fw_version(struct v4l2_subdev *sd,
- char *buf)
+static int m9mo_get_sensor_fw_version(struct v4l2_subdev *sd)
{
-#if 0
- u8 val;
+ struct m9mo_state *state = to_state(sd);
int err;
-#endif
+ int fw_ver = 0x00;
+ int awb_ver = 0x00;
+ int af_ver = 0x00;
+ int ois_ver = 0x00;
+ int parm_ver = 0x00;
+ int user_ver_temp;
+ char user_ver[20];
+ char sensor_ver[7];
+ int i = 0;
cam_err("E\n");
-#if 0
- buf = "SJEL01 Fujitsu M9MOLS";
- return 0;
-#endif
-#if 0
- /* set pin */
- val = 0x7E;
- err = m9mo_mem_write(sd, 0x04, sizeof(val), 0x50000308, &val);
+
+ /* read F/W version */
+ err = m9mo_readw(sd, M9MO_CATEGORY_SYS,
+ M9MO_SYS_VER_FW, &fw_ver);
CHECK_ERR(err);
- err = m9mo_mem_read(sd, M9MO_FW_VER_LEN,
- M9MO_FLASH_BASE_ADDR + M9MO_FW_VER_FILE_CUR, buf);
-#endif
+ err = m9mo_readw(sd, M9MO_CATEGORY_SYS,
+ M9MO_SYS_VER_AWB, &awb_ver);
+ CHECK_ERR(err);
+
+ err = m9mo_readw(sd, M9MO_CATEGORY_SYS,
+ M9MO_SYS_VER_PARAM, &parm_ver);
+ CHECK_ERR(err);
+
+ err = m9mo_readl(sd, M9MO_CATEGORY_LENS,
+ M9MO_LENS_AF_VERSION, &af_ver);
+ CHECK_ERR(err);
+
+ err = m9mo_readl(sd, M9MO_CATEGORY_NEW,
+ M9MO_NEW_OIS_VERSION, &ois_ver);
+ CHECK_ERR(err);
+
+
+ for (i = 0; i < M9MO_FW_VER_LEN; i++) {
+ err = m9mo_readb(sd, M9MO_CATEGORY_SYS,
+ M9MO_SYS_USER_VER, &user_ver_temp);
+ CHECK_ERR(err);
+
+ if ((char)user_ver_temp == '\0')
+ break;
+
+ user_ver[i] = (char)user_ver_temp;
+ /*cam_info("user temp version = %c\n", (char)user_ver_temp);*/
+
+ }
+
+ user_ver[i] = '\0';
+
+ if (user_ver[0] == 'F' && user_ver[1] == 'C') {
+ for (i = 0; i < M9MO_FW_VER_LEN; i++) {
+ if (user_ver[i] == 0x20) {
+ sensor_ver[i] = '\0';
+ break;
+ }
+ sensor_ver[i] = user_ver[i];
+ }
+ } else {
+ sprintf(sensor_ver, "%s", "Invalid version");
+ }
- cam_info("%s\n", buf);
+ cam_info("f/w version = %x\n", fw_ver);
+ cam_info("awb version = %x\n", awb_ver);
+ cam_info("af version = %x\n", af_ver);
+ cam_info("ois version = %x\n", ois_ver);
+ cam_info("parm version = %x\n", parm_ver);
+ cam_info("user version = %s\n", user_ver);
+ cam_info("sensor version = %s\n", sensor_ver);
+
+ sprintf(state->sensor_ver, "%s", sensor_ver);
+ sprintf(state->sensor_type, "%d %d %d %x",
+ awb_ver, af_ver, ois_ver, parm_ver);
+ memcpy(sysfs_sensor_fw, state->sensor_ver,
+ sizeof(state->sensor_ver));
+ memcpy(sysfs_sensor_type, state->sensor_type,
+ sizeof(state->sensor_type));
+ state->isp_fw_ver = fw_ver;
+
+ cam_info("sensor fw : %s\n", sysfs_sensor_fw);
+ cam_info("sensor type : %s\n", sysfs_sensor_type);
return 0;
}
-static int m9mo_get_phone_fw_version(struct v4l2_subdev *sd, char *buf)
+static int m9mo_get_phone_fw_version(struct v4l2_subdev *sd)
{
+ struct m9mo_state *state = to_state(sd);
struct device *dev = sd->v4l2_dev->dev;
- /*u8 sensor_ver[M9MO_FW_VER_LEN] = {0, };*/
const struct firmware *fw;
int err = 0;
@@ -1114,6 +2129,9 @@ static int m9mo_get_phone_fw_version(struct v4l2_subdev *sd, char *buf)
mm_segment_t old_fs;
long nread;
int fw_requested = 1;
+ char ver_tmp[20];
+ char phone_ver[7];
+ int i = 0;
cam_info("E\n");
@@ -1131,13 +2149,15 @@ static int m9mo_get_phone_fw_version(struct v4l2_subdev *sd, char *buf)
fw_requested = 0;
- err = vfs_llseek(fp, M9MO_FW_VER_FILE_CUR, SEEK_SET);
+ err = vfs_llseek(fp, M9MO_FW_VER_NUM, SEEK_SET);
if (err < 0) {
cam_warn("failed to fseek, %d\n", err);
goto out;
}
- nread = vfs_read(fp, (char __user *)buf, M9MO_FW_VER_LEN, &fp->f_pos);
+ /*nread = vfs_read(fp, (char __user *)state->phone_ver,*/
+ nread = vfs_read(fp, (char __user *)ver_tmp,
+ M9MO_FW_VER_LEN, &fp->f_pos);
if (nread != M9MO_FW_VER_LEN) {
cam_err("failed to read firmware file, %ld Bytes\n", nread);
err = -EIO;
@@ -1172,8 +2192,15 @@ request_fw:
#endif
}
#else
- cam_info("Firmware Path = %s\n", M9MO_FW_REQ_PATH);
- err = request_firmware(&fw, M9MO_FW_REQ_PATH, dev);
+ if (system_rev > 1) {
+ cam_info("Firmware Path = %s\n",
+ M9MO_EVT31_FW_REQ_PATH);
+ err = request_firmware(&fw,
+ M9MO_EVT31_FW_REQ_PATH, dev);
+ } else {
+ cam_info("Firmware Path = %s\n", M9MO_FW_REQ_PATH);
+ err = request_firmware(&fw, M9MO_FW_REQ_PATH, dev);
+ }
#endif
if (err != 0) {
@@ -1181,12 +2208,45 @@ request_fw:
err = -EINVAL;
goto out;
}
+#if 0
+ sprintf(state->phone_ver, "%x%x",
+ (u32)&fw->data[M9MO_FW_VER_NUM],
+ (u32)&fw->data[M9MO_FW_VER_NUM + 1]);
+ cam_info("%s: fw->data[0] = %x, fw->data[1] = %x\n", __func__,
+ (int)fw->data[M9MO_FW_VER_NUM],
+ (int)fw->data[M9MO_FW_VER_NUM + 1]);
+ ver_tmp = (int)fw->data[M9MO_FW_VER_NUM] * 16 * 16;
+ ver_tmp += (int)fw->data[M9MO_FW_VER_NUM + 1];
+ cam_info("ver_tmp = %x\n", ver_tmp);
+ sprintf(state->phone_ver, "FU%x", ver_tmp);
+#endif
- memcpy(buf, (u8 *)&fw->data[M9MO_FW_VER_FILE_CUR],
- M9MO_FW_VER_LEN);
- }
+ for (i = 0; i < M9MO_FW_VER_LEN; i++) {
+ if ((int)fw->data[M9MO_FW_VER_NUM+i] == 0x00)
+ break;
+ ver_tmp[i] = (int)fw->data[M9MO_FW_VER_NUM+i];
+ }
+ }
out:
+
+ ver_tmp[M9MO_FW_VER_LEN-1] = '\0';
+
+ for (i = 0; i < M9MO_FW_VER_LEN; i++) {
+ if (ver_tmp[i] == 0x20) {
+ phone_ver[i] = '\0';
+ /*cam_info("phone_ver = %s\n", phone_ver);*/
+ break;
+ }
+ phone_ver[i] = ver_tmp[i];
+ }
+
+ cam_info("ver_tmp = %s\n", ver_tmp);
+ cam_info("phone_ver = %s\n", phone_ver);
+ sprintf(state->phone_ver, "%s", phone_ver);
+ memcpy(sysfs_phone_fw, state->phone_ver,
+ sizeof(state->phone_ver));
+
if (!fw_requested) {
filp_close(fp, current->files);
set_fs(old_fs);
@@ -1194,33 +2254,35 @@ out:
release_firmware(fw);
}
- cam_dbg("%s\n", buf);
+ cam_dbg("phone ver : %s\n", sysfs_phone_fw);
return 0;
}
static int m9mo_check_fw(struct v4l2_subdev *sd)
{
+#if 0
struct m9mo_state *state = to_state(sd);
- u8 sensor_ver[M9MO_FW_VER_LEN] = "FAILED Fujitsu M9MO";
- u8 phone_ver[M9MO_FW_VER_LEN] = "FAILED Fujitsu M9MO";
- int af_cal_h = 0, af_cal_l = 0;
+#endif
+ int /*af_cal_h = 0,*/ af_cal_l = 0;
int rg_cal_h = 0, rg_cal_l = 0;
int bg_cal_h = 0, bg_cal_l = 0;
+#if 0
int update_count = 0;
+#endif
u32 int_factor;
int err;
cam_trace("E\n");
/* F/W version */
- m9mo_get_phone_fw_version(sd, phone_ver);
+ m9mo_get_phone_fw_version(sd);
#if 0
if (state->isp.bad_fw)
goto out;
#endif
- m9mo_get_sensor_fw_version(sd, sensor_ver);
+ m9mo_get_sensor_fw_version(sd);
goto out;
@@ -1251,22 +2313,153 @@ static int m9mo_check_fw(struct v4l2_subdev *sd)
CHECK_ERR(err);
out:
- if (!state->fw_version) {
- state->fw_version = kzalloc(50, GFP_KERNEL);
- if (!state->fw_version) {
+#if 0
+ if (!state->sensor_type) {
+ state->sensor_type = kzalloc(50, GFP_KERNEL);
+ if (!state->sensor_type) {
cam_err("no memory for F/W version\n");
return -ENOMEM;
}
}
+#endif
- sprintf(state->fw_version, "%s %s %d %x %x %x %x %x %x",
+#if 0
+ sprintf(state->sensor_type, "%s %s %d %x %x %x %x %x %x",
sensor_ver, phone_ver, update_count,
af_cal_h, af_cal_l, rg_cal_h, rg_cal_l, bg_cal_h, bg_cal_l);
+#endif
+ cam_info("phone ver = %s, sensor_ver = %s\n",
+ sysfs_phone_fw, sysfs_sensor_fw);
cam_trace("X\n");
return 0;
}
+
+static int m9mo_make_CSV_rawdata(struct v4l2_subdev *sd,
+ u32 *address, bool bAddResult)
+{
+ struct file *fp;
+ mm_segment_t old_fs;
+ u8 *buf;
+ u32 addr, unit, intram_unit = 0x1000;
+ int err;
+
+ old_fs = get_fs();
+ set_fs(KERNEL_DS);
+
+ fp = filp_open(M9MO_FACTORY_CSV_PATH,
+ O_WRONLY|O_CREAT|O_TRUNC, S_IRUGO|S_IWUGO|S_IXUSR);
+ if (IS_ERR(fp)) {
+ cam_err("failed to open %s, err %ld\n",
+ M9MO_FACTORY_CSV_PATH, PTR_ERR(fp));
+ err = -ENOENT;
+ goto file_out;
+ }
+
+ buf = kmalloc(intram_unit, GFP_KERNEL);
+ if (!buf) {
+ cam_err("failed to allocate memory\n");
+ err = -ENOMEM;
+ goto out;
+ }
+
+ cam_dbg("start, file path %s\n", M9MO_FACTORY_CSV_PATH);
+
+ addr = address[0];
+ unit = address[1]-address[0]+1;
+
+ cam_trace("m9mo_make_CSV_rawdata() addr[0x%0x] size=%d\n",
+ addr, unit);
+
+ err = m9mo_mem_read(sd, unit, addr, buf);
+ if (err < 0) {
+ cam_err("i2c falied, err %d\n", err);
+ goto out;
+ }
+
+/*"Result27E03128(0:OK, 1:NG)"Bit 0 : IRIS
+Bit 1 : Liveview Gain
+Bit 2 : ShutterClose
+Bit 3 : CaptureGain
+Bit 5 : DefectPixel*/
+ if (bAddResult) {
+ m9mo_mem_read(sd, 0x2,
+ M9MO_FLASH_FACTORY_RESULT, buf+unit);
+ cam_trace("m9mo_make_CSV_rawdata() size=%d result=%x\n",
+ unit, *(u16 *)(buf+unit));
+ unit += 2;
+ }
+
+ vfs_write(fp, buf, unit, &fp->f_pos);
+ msleep(20);
+
+out:
+ kfree(buf);
+ if (!IS_ERR(fp))
+ filp_close(fp, current->files);
+file_out:
+ set_fs(old_fs);
+
+ return err;
+}
+
+static int m9mo_make_CSV_rawdata_direct(struct v4l2_subdev *sd, int nkind)
+{
+ struct file *fp;
+ mm_segment_t old_fs;
+ u8 *buf;
+ int val;
+ u32 unit, intram_unit = 0x1000;
+ int i, err, start, end;
+
+ old_fs = get_fs();
+ set_fs(KERNEL_DS);
+
+ fp = filp_open(M9MO_FACTORY_CSV_PATH,
+ O_WRONLY|O_CREAT|O_TRUNC, S_IRUGO|S_IWUGO|S_IXUSR);
+ if (IS_ERR(fp)) {
+ cam_err("failed to open %s, err %ld\n",
+ M9MO_FACTORY_CSV_PATH, PTR_ERR(fp));
+ err = -ENOENT;
+ goto file_out;
+ }
+
+ buf = kmalloc(intram_unit, GFP_KERNEL);
+ if (!buf) {
+ cam_err("failed to allocate memory\n");
+ err = -ENOMEM;
+ goto out;
+ }
+
+ if (V4L2_CID_CAMERA_FACTORY_DEFECTPIXEL) {
+ cam_dbg("start, file path %s\n", M9MO_FACTORY_CSV_PATH);
+
+ start = 0x69;
+ end = 0x8C;
+ unit = end-start + 1;
+
+ for (i = start; i <= end; i++) {
+ err = m9mo_readb(sd, M9MO_CATEGORY_MON, i, &val);
+ CHECK_ERR(err);
+
+ buf[i-start] = (u8)val;
+ }
+ }
+ vfs_write(fp, buf, unit, &fp->f_pos);
+
+out:
+ kfree(buf);
+
+ if (!IS_ERR(fp))
+ filp_close(fp, current->files);
+
+file_out:
+ set_fs(old_fs);
+
+ return err;
+}
+
#ifdef FAST_CAPTURE
static int m9mo_set_fast_capture(struct v4l2_subdev *sd)
{
@@ -1289,17 +2482,44 @@ static int m9mo_set_sensor_mode(struct v4l2_subdev *sd, int val)
{
struct m9mo_state *state = to_state(sd);
int err;
+ int set_shutter_mode;
cam_dbg("E, value %d\n", val);
+ /* Do not set CATE_408 0x01,0x02 at mode change */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_NEW, 0x08, 0x00);
+ CHECK_ERR(err);
+
err = m9mo_set_mode(sd, M9MO_PARMSET_MODE);
CHECK_ERR(err);
+ if (val == SENSOR_MOVIE)
+ set_shutter_mode = 0; /* Rolling Shutter */
+ else
+ set_shutter_mode = 1; /* Mechanical Shutter */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_ADJST,
+ M9MO_ADJST_SHUTTER_MODE, set_shutter_mode);
+ CHECK_ERR(err);
+
state->sensor_mode = val;
cam_trace("X\n");
return 0;
}
+static int m9mo_set_flash_evc_step(struct v4l2_subdev *sd, int val)
+{
+ int err;
+
+ cam_trace("E, value %d\n", val);
+
+ err = m9mo_writeb(sd, M9MO_CATEGORY_CAPPARM,
+ M9MO_CAPPARM_STROBE_EVC, val);
+ CHECK_ERR(err);
+
+ cam_trace("X\n");
+ return 0;
+}
+
static int m9mo_set_flash(struct v4l2_subdev *sd, int val, int force)
{
struct m9mo_state *state = to_state(sd);
@@ -1317,31 +2537,31 @@ static int m9mo_set_flash(struct v4l2_subdev *sd, int val, int force)
retry:
switch (val) {
case FLASH_MODE_OFF:
- strobe_en = 0;
+ strobe_en = 0;
break;
case FLASH_MODE_AUTO:
- strobe_en = 2;
+ strobe_en = 0x02;
break;
case FLASH_MODE_ON:
- strobe_en = 1;
+ strobe_en = 0x01;
break;
case FLASH_MODE_RED_EYE:
- strobe_en = 1;
+ strobe_en = 0x12;
break;
case FLASH_MODE_FILL_IN:
- strobe_en = 1;
+ strobe_en = 0x01;
break;
case FLASH_MODE_SLOW_SYNC:
- strobe_en = 1;
+ strobe_en = 0x03;
break;
case FLASH_MODE_RED_EYE_FIX:
- strobe_en = 2;
+ strobe_en = 0x02;
err = m9mo_writeb(sd, M9MO_CATEGORY_FD,
M9MO_FD_RED_EYE, 0x01);
CHECK_ERR(err);
@@ -1367,12 +2587,32 @@ retry:
return 0;
}
+static int m9mo_set_flash_batt_info(struct v4l2_subdev *sd, int val)
+{
+ int err;
+ int set_strobe_batt;
+
+ cam_trace("E, value %d\n", val);
+
+ if (val)
+ set_strobe_batt = 1;
+ else
+ set_strobe_batt = 0;
+
+ err = m9mo_writeb(sd, M9MO_CATEGORY_CAPPARM,
+ M9MO_CAPPARM_STROBE_BATT_INFO, set_strobe_batt);
+ CHECK_ERR(err);
+
+ cam_trace("X\n");
+ return 0;
+}
+
static int m9mo_set_iso(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
{
struct m9mo_state *state = to_state(sd);
struct v4l2_queryctrl qc = {0,};
- int val = ctrl->value, err;
- u32 iso[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07};
+ int val = ctrl->value, err, current_state;
+ u32 iso[] = {0x00, 0x01, 0x64, 0xC8, 0x190, 0x320, 0x640, 0xC80};
if (state->scene_mode != SCENE_MODE_NONE) {
/* sensor will set internally */
@@ -1391,9 +2631,103 @@ static int m9mo_set_iso(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
val -= qc.minimum;
- err = m9mo_writeb(sd, M9MO_CATEGORY_AE, M9MO_AE_ISOSEL, iso[val]);
- CHECK_ERR(err);
+ switch (val) {
+ case 0:
+ state->iso = 0;
+ break;
+
+ case 1:
+ state->iso = 50;
+ break;
+
+ case 2:
+ state->iso = 100;
+ break;
+
+ case 3:
+ state->iso = 200;
+ break;
+
+ case 4:
+ state->iso = 400;
+ break;
+
+ case 5:
+ state->iso = 800;
+ break;
+
+ case 6:
+ state->iso = 1600;
+ break;
+
+ case 7:
+ state->iso = 3200;
+ break;
+
+ default:
+ break;
+ }
+
+ err = m9mo_readb(sd, M9MO_CATEGORY_AE,
+ M9MO_AE_EV_PRG_MODE_CAP, &current_state);
+
+ /* ISO AUTO */
+ if (val == 0) {
+ switch (state->mode) {
+ case MODE_PROGRAM:
+ err = m9mo_writeb(sd, M9MO_CATEGORY_AE,
+ M9MO_AE_EV_PRG_MODE_CAP, 0x00);
+ CHECK_ERR(err);
+ break;
+
+ case MODE_A:
+ err = m9mo_writeb(sd, M9MO_CATEGORY_AE,
+ M9MO_AE_EV_PRG_MODE_CAP, 0x01);
+ CHECK_ERR(err);
+ break;
+
+ case MODE_S:
+ err = m9mo_writeb(sd, M9MO_CATEGORY_AE,
+ M9MO_AE_EV_PRG_MODE_CAP, 0x02);
+ CHECK_ERR(err);
+ break;
+
+ default:
+ break;
+ }
+ } else {
+ switch (state->mode) {
+ case MODE_PROGRAM:
+ if (current_state != 0x04) {
+ err = m9mo_writeb(sd, M9MO_CATEGORY_AE,
+ M9MO_AE_EV_PRG_MODE_CAP, 0x04);
+ CHECK_ERR(err);
+ }
+ break;
+
+ case MODE_A:
+ if (current_state != 0x05) {
+ err = m9mo_writeb(sd, M9MO_CATEGORY_AE,
+ M9MO_AE_EV_PRG_MODE_CAP, 0x05);
+ CHECK_ERR(err);
+ }
+ break;
+
+ case MODE_S:
+ if (current_state != 0x06) {
+ err = m9mo_writeb(sd, M9MO_CATEGORY_AE,
+ M9MO_AE_EV_PRG_MODE_CAP, 0x06);
+ CHECK_ERR(err);
+ }
+ break;
+ default:
+ break;
+ }
+ err = m9mo_writew(sd, M9MO_CATEGORY_AE,
+ M9MO_AE_EV_PRG_ISO_VALUE, iso[val]);
+ CHECK_ERR(err);
+ }
cam_trace("X\n");
return 0;
}
@@ -1433,11 +2767,13 @@ static int m9mo_set_exposure(struct v4l2_subdev *sd,
struct v4l2_queryctrl qc = {0,};
int val = ctrl->value, err;
/*
- -6, -5, -4, +4, +5, +6 is not implemented in ISP
+ -2.0, -1.7, -1.3, -1.0 -0.7 -0.3
+ 0
+ +0.3 +0.7 +1.0 +1.3 +1.7 +2.0
*/
- u32 exposure[] = {0x00, 0x00, 0x00,
- 0x00, 0x0A, 0x14, 0x1E, 0x28,
- 0x32, 0x3C, 0x3C, 0x3C, 0x3C};
+ u32 exposure[] = {0x0A, 0x0D, 0x11, 0x14, 0x17, 0x1B,
+ 0x1E,
+ 0x21, 0x25, 0x28, 0x2B, 0x2F, 0x32};
cam_dbg("E, value %d\n", val);
qc.id = ctrl->id;
@@ -1460,6 +2796,8 @@ static int m9mo_set_exposure(struct v4l2_subdev *sd,
static int m9mo_set_whitebalance(struct v4l2_subdev *sd, int val)
{
+ struct m9mo_state *state = to_state(sd);
+
int err;
cam_dbg("E, value %d\n", val);
@@ -1467,6 +2805,9 @@ retry:
switch (val) {
case WHITE_BALANCE_AUTO:
err = m9mo_writeb(sd, M9MO_CATEGORY_WB,
+ M9MO_WB_CWB_MODE, 0x00);
+ CHECK_ERR(err);
+ err = m9mo_writeb(sd, M9MO_CATEGORY_WB,
M9MO_WB_AWB_MODE, 0x01);
CHECK_ERR(err);
err = m9mo_writeb(sd, M9MO_CATEGORY_WB,
@@ -1476,6 +2817,9 @@ retry:
case WHITE_BALANCE_SUNNY:
err = m9mo_writeb(sd, M9MO_CATEGORY_WB,
+ M9MO_WB_CWB_MODE, 0x00);
+ CHECK_ERR(err);
+ err = m9mo_writeb(sd, M9MO_CATEGORY_WB,
M9MO_WB_AWB_MODE, 0x02);
CHECK_ERR(err);
err = m9mo_writeb(sd, M9MO_CATEGORY_WB,
@@ -1485,6 +2829,9 @@ retry:
case WHITE_BALANCE_CLOUDY:
err = m9mo_writeb(sd, M9MO_CATEGORY_WB,
+ M9MO_WB_CWB_MODE, 0x00);
+ CHECK_ERR(err);
+ err = m9mo_writeb(sd, M9MO_CATEGORY_WB,
M9MO_WB_AWB_MODE, 0x02);
CHECK_ERR(err);
err = m9mo_writeb(sd, M9MO_CATEGORY_WB,
@@ -1494,6 +2841,9 @@ retry:
case WHITE_BALANCE_TUNGSTEN:
err = m9mo_writeb(sd, M9MO_CATEGORY_WB,
+ M9MO_WB_CWB_MODE, 0x00);
+ CHECK_ERR(err);
+ err = m9mo_writeb(sd, M9MO_CATEGORY_WB,
M9MO_WB_AWB_MODE, 0x02);
CHECK_ERR(err);
err = m9mo_writeb(sd, M9MO_CATEGORY_WB,
@@ -1504,6 +2854,9 @@ retry:
case WHITE_BALANCE_FLUORESCENT:
case WHITE_BALANCE_FLUORESCENT_H:
err = m9mo_writeb(sd, M9MO_CATEGORY_WB,
+ M9MO_WB_CWB_MODE, 0x00);
+ CHECK_ERR(err);
+ err = m9mo_writeb(sd, M9MO_CATEGORY_WB,
M9MO_WB_AWB_MODE, 0x02);
CHECK_ERR(err);
err = m9mo_writeb(sd, M9MO_CATEGORY_WB,
@@ -1513,6 +2866,9 @@ retry:
case WHITE_BALANCE_FLUORESCENT_L:
err = m9mo_writeb(sd, M9MO_CATEGORY_WB,
+ M9MO_WB_CWB_MODE, 0x00);
+ CHECK_ERR(err);
+ err = m9mo_writeb(sd, M9MO_CATEGORY_WB,
M9MO_WB_AWB_MODE, 0x02);
CHECK_ERR(err);
err = m9mo_writeb(sd, M9MO_CATEGORY_WB,
@@ -1520,6 +2876,92 @@ retry:
CHECK_ERR(err);
break;
+ case WHITE_BALANCE_K:
+ err = m9mo_writeb(sd, M9MO_CATEGORY_WB,
+ M9MO_WB_CWB_MODE, 0x00);
+ CHECK_ERR(err);
+ err = m9mo_writeb(sd, M9MO_CATEGORY_WB,
+ M9MO_WB_AWB_MODE, 0x02);
+ CHECK_ERR(err);
+ err = m9mo_writeb(sd, M9MO_CATEGORY_WB,
+ M9MO_WB_AWB_MANUAL, 0x0A);
+ CHECK_ERR(err);
+ break;
+
+ case WHITE_BALANCE_INCANDESCENT:
+ err = m9mo_writeb(sd, M9MO_CATEGORY_WB,
+ M9MO_WB_CWB_MODE, 0x00);
+ CHECK_ERR(err);
+ err = m9mo_writeb(sd, M9MO_CATEGORY_WB,
+ M9MO_WB_AWB_MODE, 0x02);
+ CHECK_ERR(err);
+ err = m9mo_writeb(sd, M9MO_CATEGORY_WB,
+ M9MO_WB_AWB_MANUAL, 0x01);
+ CHECK_ERR(err);
+ break;
+
+ case WHITE_BALANCE_PROHIBITION:
+ err = m9mo_writeb(sd, M9MO_CATEGORY_WB,
+ M9MO_WB_CWB_MODE, 0x00);
+ CHECK_ERR(err);
+ err = m9mo_writeb(sd, M9MO_CATEGORY_WB,
+ M9MO_WB_AWB_MODE, 0x02);
+ CHECK_ERR(err);
+ err = m9mo_writeb(sd, M9MO_CATEGORY_WB,
+ M9MO_WB_AWB_MANUAL, 0x00);
+ CHECK_ERR(err);
+ break;
+
+ case WHITE_BALANCE_HORIZON:
+ err = m9mo_writeb(sd, M9MO_CATEGORY_WB,
+ M9MO_WB_CWB_MODE, 0x00);
+ CHECK_ERR(err);
+ err = m9mo_writeb(sd, M9MO_CATEGORY_WB,
+ M9MO_WB_AWB_MODE, 0x02);
+ CHECK_ERR(err);
+ err = m9mo_writeb(sd, M9MO_CATEGORY_WB,
+ M9MO_WB_AWB_MANUAL, 0x07);
+ CHECK_ERR(err);
+ break;
+
+ case WHITE_BALANCE_LEDLIGHT:
+ err = m9mo_writeb(sd, M9MO_CATEGORY_WB,
+ M9MO_WB_CWB_MODE, 0x00);
+ CHECK_ERR(err);
+ err = m9mo_writeb(sd, M9MO_CATEGORY_WB,
+ M9MO_WB_AWB_MODE, 0x02);
+ CHECK_ERR(err);
+ err = m9mo_writeb(sd, M9MO_CATEGORY_WB,
+ M9MO_WB_AWB_MANUAL, 0x09);
+ CHECK_ERR(err);
+ break;
+
+ case WHITE_BALANCE_CUSTOM:
+ err = m9mo_writeb(sd, M9MO_CATEGORY_WB,
+ M9MO_WB_AWB_MODE, 0x02);
+ CHECK_ERR(err);
+
+ err = m9mo_writeb(sd, M9MO_CATEGORY_WB,
+ M9MO_WB_AWB_MANUAL, 0x08);
+ CHECK_ERR(err);
+
+ err = m9mo_writeb(sd, M9MO_CATEGORY_WB,
+ M9MO_WB_CWB_MODE, 0x02);
+ CHECK_ERR(err);
+
+ err = m9mo_writew(sd, M9MO_CATEGORY_WB,
+ M9MO_WB_SET_CUSTOM_RG, state->wb_custom_rg);
+ CHECK_ERR(err);
+
+ err = m9mo_writew(sd, M9MO_CATEGORY_WB,
+ M9MO_WB_SET_CUSTOM_BG, state->wb_custom_bg);
+ CHECK_ERR(err);
+
+ err = m9mo_writeb(sd, M9MO_CATEGORY_WB,
+ M9MO_WB_CWB_MODE, 0x01);
+ CHECK_ERR(err);
+ break;
+
default:
cam_warn("invalid value, %d\n", val);
val = WHITE_BALANCE_AUTO;
@@ -1534,7 +2976,7 @@ static int m9mo_set_sharpness(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
{
struct v4l2_queryctrl qc = {0,};
int val = ctrl->value, err;
- u32 sharpness[] = {0x03, 0x04, 0x05, 0x06, 0x07};
+ u32 sharpness[] = {0x01, 0x02, 0x03, 0x04, 0x05};
cam_dbg("E, value %d\n", val);
qc.id = ctrl->id;
@@ -1545,10 +2987,31 @@ static int m9mo_set_sharpness(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
val = qc.default_value;
}
- val -= qc.minimum;
+ err = m9mo_writeb(sd, M9MO_CATEGORY_MON,
+ M9MO_MON_EDGE_CTRL, sharpness[val]);
+ CHECK_ERR(err);
+
+ cam_trace("X\n");
+ return 0;
+}
+
+static int m9mo_set_contrast(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+{
+ struct v4l2_queryctrl qc = {0,};
+ int val = ctrl->value, err;
+ u32 contrast[] = {0x01, 0x02, 0x03, 0x04, 0x05};
+ cam_dbg("E, value %d\n", val);
+
+ qc.id = ctrl->id;
+ m9mo_queryctrl(sd, &qc);
+
+ if (val < qc.minimum || val > qc.maximum) {
+ cam_warn("invalied value, %d\n", val);
+ val = qc.default_value;
+ }
err = m9mo_writeb(sd, M9MO_CATEGORY_MON,
- M9MO_MON_EDGE_LVL, sharpness[val]);
+ M9MO_MON_TONE_CTRL, contrast[val]);
CHECK_ERR(err);
cam_trace("X\n");
@@ -1571,8 +3034,6 @@ static int m9mo_set_saturation(struct v4l2_subdev *sd,
val = qc.default_value;
}
- val -= qc.minimum;
-
err = m9mo_writeb(sd, M9MO_CATEGORY_MON,
M9MO_MON_CHROMA_LVL, saturation[val]);
CHECK_ERR(err);
@@ -1690,40 +3151,12 @@ retry:
return 0;
}
-
static int m9mo_set_effect_color(struct v4l2_subdev *sd, int val)
{
- u32 int_factor;
- int on, old_mode, cb, cr;
+ int cb = 0, cr = 0;
int err;
- err = m9mo_readb(sd, M9MO_CATEGORY_PARM, M9MO_PARM_EFFECT, &on);
- CHECK_ERR(err);
- if (on) {
- old_mode = m9mo_set_mode(sd, M9MO_PARMSET_MODE);
- CHECK_ERR(old_mode);
-
- err = m9mo_writeb(sd, M9MO_CATEGORY_PARM, M9MO_PARM_EFFECT, 0);
- CHECK_ERR(err);
-
- if (old_mode == M9MO_MONITOR_MODE) {
- err = m9mo_set_mode(sd, old_mode);
- CHECK_ERR(err);
-
- int_factor = m9mo_wait_interrupt(sd, M9MO_ISP_TIMEOUT);
- if (!(int_factor & M9MO_INT_MODE)) {
- cam_err("M9MO_INT_MODE isn't issued, %#x\n",
- int_factor);
- return -ETIMEDOUT;
- }
- CHECK_ERR(err);
- }
- }
-
switch (val) {
- case IMAGE_EFFECT_NONE:
- break;
-
case IMAGE_EFFECT_SEPIA:
cb = 0xD8;
cr = 0x18;
@@ -1733,86 +3166,96 @@ static int m9mo_set_effect_color(struct v4l2_subdev *sd, int val)
cb = 0x00;
cr = 0x00;
break;
- }
- err = m9mo_writeb(sd, M9MO_CATEGORY_MON,
- M9MO_MON_COLOR_EFFECT, val == IMAGE_EFFECT_NONE ? 0x00 : 0x01);
- CHECK_ERR(err);
+ case IMAGE_EFFECT_ANTIQUE:
+ cb = 0xD0;
+ cr = 0x30;
+ break;
- if (val != IMAGE_EFFECT_NONE) {
- err = m9mo_writeb(sd, M9MO_CATEGORY_MON, M9MO_MON_CFIXB, cb);
- CHECK_ERR(err);
- err = m9mo_writeb(sd, M9MO_CATEGORY_MON, M9MO_MON_CFIXR, cr);
- CHECK_ERR(err);
+ default:
+ return 0;
}
+ err = m9mo_writeb(sd, M9MO_CATEGORY_MON, M9MO_MON_CFIXB, cb);
+ CHECK_ERR(err);
+ err = m9mo_writeb(sd, M9MO_CATEGORY_MON, M9MO_MON_CFIXR, cr);
+ CHECK_ERR(err);
+
return 0;
}
-static int m9mo_set_effect_gamma(struct v4l2_subdev *sd, s32 val)
+static int m9mo_set_effect_point(struct v4l2_subdev *sd, int val)
{
- u32 int_factor;
- int on, effect, old_mode;
+ int point = 0;
int err;
- err = m9mo_readb(sd, M9MO_CATEGORY_MON, M9MO_MON_COLOR_EFFECT, &on);
- CHECK_ERR(err);
- if (on) {
- err = m9mo_writeb(sd, M9MO_CATEGORY_MON,
- M9MO_MON_COLOR_EFFECT, 0);
- CHECK_ERR(err);
- }
-
switch (val) {
- case IMAGE_EFFECT_NEGATIVE:
- effect = 0x01;
+ case IMAGE_EFFECT_POINT_BLUE:
+ point = 0;
break;
- case IMAGE_EFFECT_AQUA:
- effect = 0x08;
+ case IMAGE_EFFECT_POINT_RED:
+ point = 1;
break;
- }
-
- old_mode = m9mo_set_mode(sd, M9MO_PARMSET_MODE);
- CHECK_ERR(old_mode);
- err = m9mo_writeb(sd, M9MO_CATEGORY_PARM, M9MO_PARM_EFFECT, effect);
- CHECK_ERR(err);
-
- if (old_mode == M9MO_MONITOR_MODE) {
- err = m9mo_set_mode(sd, old_mode);
- CHECK_ERR(err);
+ case IMAGE_EFFECT_POINT_YELLOW:
+ point = 2;
+ break;
- int_factor = m9mo_wait_interrupt(sd, M9MO_ISP_TIMEOUT);
- if (!(int_factor & M9MO_INT_MODE)) {
- cam_err("M9MO_INT_MODE isn't issued, %#x\n",
- int_factor);
- return -ETIMEDOUT;
- }
- CHECK_ERR(err);
+ default:
+ return 0;
}
- return err;
+ err = m9mo_writeb(sd, M9MO_CATEGORY_MON,
+ M9MO_MON_POINT_COLOR, point);
+ CHECK_ERR(err);
+
+ return 0;
}
static int m9mo_set_effect(struct v4l2_subdev *sd, int val)
{
+ int set_effect = 0;
int err;
+ struct m9mo_state *state = to_state(sd);
cam_dbg("E, value %d\n", val);
retry:
switch (val) {
case IMAGE_EFFECT_NONE:
+ set_effect = 0;
+ break;
+
+ case IMAGE_EFFECT_NEGATIVE:
+ set_effect = 2;
+ break;
+
case IMAGE_EFFECT_BNW:
case IMAGE_EFFECT_SEPIA:
+ case IMAGE_EFFECT_ANTIQUE:
err = m9mo_set_effect_color(sd, val);
CHECK_ERR(err);
+ set_effect = 1;
break;
- case IMAGE_EFFECT_AQUA:
- case IMAGE_EFFECT_NEGATIVE:
- err = m9mo_set_effect_gamma(sd, val);
+ case IMAGE_EFFECT_POINT_BLUE:
+ case IMAGE_EFFECT_POINT_RED:
+ case IMAGE_EFFECT_POINT_YELLOW:
+ err = m9mo_set_effect_point(sd, val);
CHECK_ERR(err);
+ set_effect = 3;
+ break;
+
+ case IMAGE_EFFECT_VINTAGE_WARM:
+ set_effect = 4;
+ break;
+
+ case IMAGE_EFFECT_VINTAGE_COLD:
+ set_effect = 5;
+ break;
+
+ case IMAGE_EFFECT_WASHED:
+ set_effect = 6;
break;
default:
@@ -1821,22 +3264,24 @@ retry:
goto retry;
}
+ err = m9mo_writeb(sd, M9MO_CATEGORY_MON,
+ M9MO_MON_COLOR_EFFECT, set_effect);
+ CHECK_ERR(err);
+
+ state->color_effect = set_effect;
+
cam_trace("X\n");
return 0;
}
static int m9mo_set_wdr(struct v4l2_subdev *sd, int val)
{
- int contrast, wdr, err;
+ int wdr, err;
cam_dbg("%s\n", val ? "on" : "off");
- contrast = (val == 1 ? 0x09 : 0x05);
wdr = (val == 1 ? 0x01 : 0x00);
- err = m9mo_writeb(sd, M9MO_CATEGORY_MON,
- M9MO_MON_TONE_CTRL, contrast);
- CHECK_ERR(err);
err = m9mo_writeb(sd, M9MO_CATEGORY_CAPPARM,
M9MO_CAPPARM_WDR_EN, wdr);
CHECK_ERR(err);
@@ -1885,184 +3330,375 @@ static int m9mo_set_face_beauty(struct v4l2_subdev *sd, int val)
return 0;
}
-static int m9mo_set_lock(struct v4l2_subdev *sd, int val)
+static unsigned int m9mo_set_cal_rect_pos(struct v4l2_subdev *sd,
+ unsigned int pos_val)
{
struct m9mo_state *state = to_state(sd);
- int err;
+ unsigned int set_val;
- cam_trace("%s\n", val ? "on" : "off");
+ if (pos_val <= 40)
+ set_val = 40;
+ else if (pos_val > (state->preview->width - 40))
+ set_val = state->preview->width - 40;
+ else
+ set_val = pos_val;
- err = m9mo_writeb(sd, M9MO_CATEGORY_AE, M9MO_AE_LOCK, val);
- CHECK_ERR(err);
- err = m9mo_writeb(sd, M9MO_CATEGORY_WB, M9MO_AWB_LOCK, val);
+ return set_val;
+}
+
+static int m9mo_set_object_tracking(struct v4l2_subdev *sd, int val)
+{
+ struct m9mo_state *state = to_state(sd);
+ int err = 0;
+ unsigned int set_x, set_y;
+
+ err = m9mo_writeb(sd, M9MO_CATEGORY_OT,
+ M9MO_OT_TRACKING_CTL, 0x10);
CHECK_ERR(err);
- state->focus.lock = val;
+ cam_trace("E val : %d\n", val);
+
+ if (val == OT_START) {
+ set_x = m9mo_set_cal_rect_pos(sd, state->focus.pos_x);
+ set_y = m9mo_set_cal_rect_pos(sd, state->focus.pos_y);
+
+ cam_dbg("idx[%d] w[%d] h[%d]", state->preview->index,
+ state->preview->width, state->preview->height);
+ cam_dbg("pos_x[%d] pos_y[%d] x[%d] y[%d]",
+ state->focus.pos_x, state->focus.pos_y,
+ set_x, set_y);
+
+ err = m9mo_writeb(sd, M9MO_CATEGORY_OT,
+ M9MO_OT_FRAME_WIDTH, 0x02);
+ CHECK_ERR(err);
+ err = m9mo_writew(sd, M9MO_CATEGORY_OT,
+ M9MO_OT_X_START_LOCATION,
+ set_x - 40);
+ CHECK_ERR(err);
+ err = m9mo_writew(sd, M9MO_CATEGORY_OT,
+ M9MO_OT_Y_START_LOCATION,
+ set_y - 40);
+ CHECK_ERR(err);
+ err = m9mo_writew(sd, M9MO_CATEGORY_OT,
+ M9MO_OT_X_END_LOCATION,
+ set_x + 40);
+ CHECK_ERR(err);
+ err = m9mo_writew(sd, M9MO_CATEGORY_OT,
+ M9MO_OT_Y_END_LOCATION,
+ set_y + 40);
+ CHECK_ERR(err);
+ err = m9mo_writeb(sd, M9MO_CATEGORY_OT,
+ M9MO_OT_TRACKING_CTL, 0x11);
+ CHECK_ERR(err);
+ }
- cam_trace("X\n");
return 0;
}
-static int m9mo_get_af_result(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+
+static int m9mo_set_image_stabilizer_OIS(struct v4l2_subdev *sd, int val)
{
- struct m9mo_state *state = to_state(sd);
- int status, err;
+ int err, int_factor, set_ois, int_en;
+ int wait_int_ois = 0;
- err = m9mo_readb(sd, M9MO_CATEGORY_LENS,
- M9MO_LENS_AF_STATUS, &status);
+ cam_trace("E: mode %d\n", val);
- state->focus.status = status;
- ctrl->value = status;
- /*
- Get af result is not supported in ISP now. FIXME
- */
- ctrl->value = 0x02;
- return ctrl->value;
-}
-static int m9mo_set_af(struct v4l2_subdev *sd, int val)
-{
- struct m9mo_state *state = to_state(sd);
- /* int i, status; */
- int err = 0;
+retry:
+ switch (val) {
+ case V4L2_IS_OIS_NONE:
+ cam_warn("OIS_NONE and OIS End");
+ return 0;
- cam_info("%s, mode %#x\n", val ? "start" : "stop", state->focus.mode);
+ case V4L2_IS_OIS_MOVIE:
+ set_ois = 0x01;
+ wait_int_ois = 1;
+ break;
- state->focus.start = val;
+ case V4L2_IS_OIS_STILL:
+ set_ois = 0x02;
+ wait_int_ois = 0;
+ break;
- /*
- Single AF is only supported in ISP now. FIXME
- */
-#if 0
- if (state->focus.mode != FOCUS_MODE_CONTINOUS) {
- err = m9mo_writeb(sd, M9MO_CATEGORY_LENS,
- M9MO_LENS_AF_START, val);
+ case V4L2_IS_OIS_MULTI:
+ set_ois = 0x03;
+ wait_int_ois = 0;
+ break;
+
+ case V4L2_IS_OIS_VSS:
+ set_ois = 0x04;
+ wait_int_ois = 1;
+ break;
+
+ default:
+ cam_warn("invalid value, %d", val);
+ val = V4L2_IS_OIS_STILL;
+ goto retry;
+ }
+
+ if (wait_int_ois) {
+ err = m9mo_readw(sd, M9MO_CATEGORY_SYS,
+ M9MO_SYS_INT_EN, &int_en);
CHECK_ERR(err);
- if (!(state->focus.touch &&
- state->focus.mode == FOCUS_MODE_TOUCH)) {
- if (val && state->focus.lock) {
- m9mo_set_lock(sd, 0);
- msleep(100);
- }
- m9mo_set_lock(sd, val);
- }
+ /* enable OIS_SET interrupt */
+ int_en |= M9MO_INT_OIS_SET;
- } else {
- err = m9mo_writeb(sd, M9MO_CATEGORY_LENS,
- M9MO_LENS_AF_START, val ? 0x02 : 0x00);
+ err = m9mo_writew(sd, M9MO_CATEGORY_SYS,
+ M9MO_SYS_INT_EN, int_en);
CHECK_ERR(err);
- err = -EBUSY;
- for (i = M9MO_I2C_VERIFY; i && err; i--) {
- msleep(20);
- err = m9mo_readb(sd, M9MO_CATEGORY_LENS,
- M9MO_LENS_AF_STATUS, &status);
- CHECK_ERR(err);
+ err = m9mo_writeb(sd, M9MO_CATEGORY_NEW, 0x18, set_ois);
+ CHECK_ERR(err);
- if ((val && status == 0x05) || (!val && status != 0x05))
- err = 0;
+ int_factor = m9mo_wait_interrupt(sd, M9MO_ISP_TIMEOUT);
+ if (!(int_factor & M9MO_INT_OIS_SET)) {
+ cam_err("M9MO_INT_OIS_SET isn't issued, %#x\n",
+ int_factor);
+ return -ETIMEDOUT;
}
- }
-#endif
- if (state->focus.start == 1) {
- err = m9mo_writeb(sd, M9MO_CATEGORY_LENS,
- 0x03, 0x00);
CHECK_ERR(err);
- msleep(100);
+
+ /* enable OIS_SET interrupt */
+ int_en &= ~M9MO_INT_OIS_SET;
+
+ err = m9mo_writew(sd, M9MO_CATEGORY_SYS,
+ M9MO_SYS_INT_EN, int_en);
+ CHECK_ERR(err);
+ } else {
+ err = m9mo_writeb(sd, M9MO_CATEGORY_NEW, 0x18, set_ois);
+ CHECK_ERR(err);
}
- cam_dbg("X\n");
- return err;
+ cam_trace("X\n");
+ return 0;
}
-static int m9mo_set_af_mode(struct v4l2_subdev *sd, int val)
+static int m9mo_set_af_sensor_mode(struct v4l2_subdev *sd, int val)
{
struct m9mo_state *state = to_state(sd);
- u32 cancel, mode, status = 0;
- int i, err;
+ u32 cancel;
+ int err;
+ int af_mode, af_window, af_range;
+ int range_status, mode_status, window_status;
cancel = val & FOCUS_MODE_DEFAULT;
val &= 0xFF;
+ af_range = state->focus_range;
+
+ cam_dbg("E, value %d\n", val);
retry:
switch (val) {
case FOCUS_MODE_AUTO:
- mode = 0x00;
+ af_mode = 0x00;
+ af_window = state->focus_area_mode;
break;
- case FOCUS_MODE_MACRO:
- mode = 0x01;
+ case FOCUS_MODE_MULTI:
+ af_mode = 0x00;
+ af_window = 0x01;
break;
case FOCUS_MODE_CONTINOUS:
- mode = 0x02;
- cancel = 0;
+ af_mode = 0x01;
+ af_range = 0x02;
+ af_window = 0x00;
break;
case FOCUS_MODE_FACEDETECT:
- mode = 0x03;
+ af_mode = 0x00;
+ af_window = 0x02;
+ af_range = 0x02;
break;
case FOCUS_MODE_TOUCH:
- mode = 0x04;
- cancel = 0;
+ af_mode = 0x00;
+ af_window = 0x02;
break;
- case FOCUS_MODE_INFINITY:
- mode = 0x06;
+ case FOCUS_MODE_MACRO:
+ af_mode = 0x00;
+ af_range = 0x01;
+ af_window = state->focus_area_mode;
+ break;
+
+ case FOCUS_MODE_MANUAL:
+ af_mode = 0x02;
+ af_window = state->focus_area_mode;
+ af_range = 0x02;
cancel = 0;
break;
+ case FOCUS_MODE_OBJECT_TRACKING:
+ af_mode = 0x00;
+ af_window = 0x02;
+ af_range = 0x02;
+ break;
+
default:
cam_warn("invalid value, %d", val);
val = FOCUS_MODE_AUTO;
goto retry;
}
- if (cancel) {
- m9mo_set_af(sd, 0);
+ if (cancel && state->focus.lock)
m9mo_set_lock(sd, 0);
- } else {
- if (state->focus.mode == val)
- return 0;
+
+ state->focus.mode = val;
+
+ /* Set AF Mode */
+ err = m9mo_readb(sd, M9MO_CATEGORY_LENS,
+ M9MO_LENS_AF_MODE, &mode_status);
+
+ if (mode_status != af_mode) {
+ if (state->focus.mode != FOCUS_MODE_TOUCH) {
+ err = m9mo_writeb(sd, M9MO_CATEGORY_LENS,
+ M9MO_LENS_AF_MODE, af_mode);
+ CHECK_ERR(err);
+ }
}
- cam_dbg("E, value %d\n", val);
+ /* fix range to auto-macro when FD on */
+ if (state->facedetect_mode == FACE_DETECTION_NORMAL)
+ af_range = 0x02;
+
+ /* fix range to macro when CLOSE_UP mode */
+ if (state->mode == MODE_CLOSE_UP)
+ af_range = 0x01;
+
+ /* fix window to center */
+ if ((state->focus.mode == 0 || state->focus.mode == 1)
+ && state->focus_area_mode == 2)
+ af_window = 0x00;
+
+ /* Set AF Scan Range */
+ err = m9mo_readb(sd, M9MO_CATEGORY_LENS,
+ M9MO_LENS_AF_SCAN_RANGE, &range_status);
- if (val == FOCUS_MODE_FACEDETECT) {
- /* enable face detection */
- err = m9mo_writeb(sd, M9MO_CATEGORY_FD, M9MO_FD_CTL, 0x11);
+ if (range_status != af_range) {
+ err = m9mo_writeb(sd, M9MO_CATEGORY_LENS,
+ M9MO_LENS_AF_SCAN_RANGE, af_range);
CHECK_ERR(err);
- msleep(20);
- } else if (state->focus.mode == FOCUS_MODE_FACEDETECT) {
- /* disable face detection */
- err = m9mo_writeb(sd, M9MO_CATEGORY_FD, M9MO_FD_CTL, 0x00);
+ }
+
+ /* Set Zone REQ */
+ if (range_status != af_range) {
+ err = m9mo_writeb(sd, M9MO_CATEGORY_LENS,
+ M9MO_LENS_AF_INITIAL, 0x04);
CHECK_ERR(err);
}
- state->focus.mode = val;
+ /* Set AF Window Mode */
+ err = m9mo_readb(sd, M9MO_CATEGORY_LENS,
+ M9MO_LENS_AF_WINDOW_MODE, &window_status);
- /* Lens barrel error is occured by this command now. FIXME */
-#if 0
- err = m9mo_writeb(sd, M9MO_CATEGORY_LENS, M9MO_LENS_AF_MODE, mode);
- CHECK_ERR(err);
-#endif
+ if (window_status != af_window) {
+ err = m9mo_writeb(sd, M9MO_CATEGORY_LENS,
+ M9MO_LENS_AF_WINDOW_MODE, af_window);
+ CHECK_ERR(err);
+ }
+ cam_trace("X\n");
+ return 0;
+}
- for (i = M9MO_I2C_VERIFY; i; i--) {
- msleep(20);
- err = m9mo_readb(sd, M9MO_CATEGORY_LENS,
- M9MO_LENS_AF_STATUS, &status);
+static int m9mo_set_af(struct v4l2_subdev *sd, int val)
+{
+ struct m9mo_state *state = to_state(sd);
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ const struct m9mo_platform_data *pdata = client->dev.platform_data;
+ int status, err = 0;
+
+ cam_info("%s, mode %d\n", val ? "start" : "stop", state->focus.mode);
+
+ state->focus.start = val;
+
+ if (val == 1) {
+ /* AF LED regulator on */
+ pdata->af_led_power(1);
+
+ if (state->facedetect_mode == FACE_DETECTION_NORMAL
+ && state->mode == MODE_SMART_AUTO) {
+ err = m9mo_writeb(sd, M9MO_CATEGORY_FD,
+ M9MO_FD_CTL, 0x11);
+ CHECK_ERR(err);
+ }
+
+ m9mo_set_af_sensor_mode(sd, state->focus.mode);
+
+ if (state->focus.mode != FOCUS_MODE_CONTINOUS) {
+ m9mo_set_lock(sd, 1);
+
+ /* Single AF Start */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_LENS,
+ M9MO_LENS_AF_START_STOP, 0x00);
+ CHECK_ERR(err);
+ }
+ } else {
+ err = m9mo_readw(sd, M9MO_CATEGORY_LENS,
+ M9MO_LENS_AF_RESULT, &status);
CHECK_ERR(err);
- if (!(status & 0x01))
- break;
+ if (state->facedetect_mode == FACE_DETECTION_NORMAL
+ && state->mode == MODE_SMART_AUTO) {
+ err = m9mo_writeb(sd, M9MO_CATEGORY_FD,
+ M9MO_FD_CTL, 0x01);
+ CHECK_ERR(err);
+ }
+
+ if (state->focus.lock && status != 0x1000) {
+ if (state->focus.mode != FOCUS_MODE_CONTINOUS)
+ m9mo_set_lock(sd, 0);
+ }
+ /* AF LED regulator off */
+ pdata->af_led_power(0);
}
- if ((status & 0x01) != 0x00) {
- cam_err("failed\n");
- return -ETIMEDOUT;
+ cam_dbg("X\n");
+ return err;
+}
+
+static int m9mo_set_af_mode(struct v4l2_subdev *sd, int val)
+{
+ struct m9mo_state *state = to_state(sd);
+
+ state->focus.mode = val;
+
+ cam_trace("X val : %d\n", val);
+ return 0;
+}
+
+static int m9mo_set_focus_range(struct v4l2_subdev *sd, int val)
+{
+ struct m9mo_state *state = to_state(sd);
+ int err, range_status;
+
+ /* Set AF Scan Range */
+ err = m9mo_readb(sd, M9MO_CATEGORY_LENS,
+ M9MO_LENS_AF_SCAN_RANGE, &range_status);
+
+ if (range_status != val) {
+ err = m9mo_writeb(sd, M9MO_CATEGORY_LENS,
+ M9MO_LENS_AF_SCAN_RANGE, val);
+ CHECK_ERR(err);
+
+ /* Set Zone REQ */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_LENS,
+ M9MO_LENS_AF_INITIAL, 0x04);
+ CHECK_ERR(err);
}
- cam_trace("X\n");
+ state->focus_range = val;
+
+ cam_trace("X val : %d\n", val);
+ return 0;
+}
+
+static int m9mo_set_focus_area_mode(struct v4l2_subdev *sd, int val)
+{
+ struct m9mo_state *state = to_state(sd);
+
+ state->focus_area_mode = val;
+
+ cam_trace("X val : %d\n", val);
return 0;
}
@@ -2075,11 +3711,6 @@ static int m9mo_set_touch_auto_focus(struct v4l2_subdev *sd, int val)
state->focus.touch = val;
if (val) {
- err = m9mo_set_af_mode(sd, FOCUS_MODE_TOUCH);
- if (err < 0) {
- cam_err("m9mo_set_af_mode failed\n");
- return err;
- }
err = m9mo_writew(sd, M9MO_CATEGORY_LENS,
M9MO_LENS_AF_TOUCH_POSX, state->focus.pos_x);
CHECK_ERR(err);
@@ -2092,36 +3723,83 @@ static int m9mo_set_touch_auto_focus(struct v4l2_subdev *sd, int val)
return err;
}
+static int m9mo_set_AF_LED(struct v4l2_subdev *sd, int val)
+{
+ int err;
+ int set_AF_LED_On;
+
+ cam_trace("E, value %d\n", val);
+
+ if (val)
+ set_AF_LED_On = 1;
+ else
+ set_AF_LED_On = 0;
+
+ err = m9mo_writeb(sd, M9MO_CATEGORY_LENS,
+ M9MO_LENS_AF_LED, set_AF_LED_On);
+ CHECK_ERR(err);
+
+ cam_trace("X\n");
+ return 0;
+}
+
static int m9mo_set_zoom(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
{
struct m9mo_state *state = to_state(sd);
struct v4l2_queryctrl qc = {0,};
- int val = ctrl->value, err, i;
- int n_zoom[] = { 75, 150, 225, 300};
- int zoom[] = { 4, 16, 28, 39};
- cam_dbg("E, value %d\n", val);
+ int val = ctrl->value, err;
+ int opti_val, digi_val;
+ int opti_max = 15;
+ int optical_zoom_val[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
+ 11, 12, 13, 14, 15};
+ int zoom_val[] = { 0x01,
+ 0x0E, 0x17, 0x1D, 0x22, 0x26,
+ 0x29, 0x2C, 0x2E, 0x30, 0x32,
+ 0x34, 0x35, 0x36, 0x37, 0x38 };
+ cam_trace("E, value %d\n", val);
qc.id = ctrl->id;
m9mo_queryctrl(sd, &qc);
- if (val < (qc.minimum * 10) || val > (qc.maximum * 10)) {
- cam_warn("invalied value, %d\n", val);
- val = qc.default_value * 10;
+ if (val < qc.minimum) {
+ cam_warn("invalied min value, %d\n", val);
+ val = qc.default_value;
}
- for (i = 0 ; i <= sizeof(n_zoom) ; i++) {
- if (n_zoom[i] >= ctrl->value) {
- val = i;
- break;
- }
+ if (val > qc.maximum) {
+ cam_warn("invalied max value, %d\n", val);
+ val = qc.maximum;
}
- if (val < 0 || val > 4) {
- cam_warn("invalied value, %d\n", val);
- val = 0;
+ if (val <= opti_max) {
+ opti_val = val;
+ digi_val = 0;
+ } else {
+ opti_val = opti_max;
+ digi_val = val - opti_max;
}
- err = m9mo_writeb(sd, M9MO_CATEGORY_MON, M9MO_MON_ZOOM, zoom[val]);
+ if (state->recording) {
+ err = m9mo_writeb(sd, M9MO_CATEGORY_LENS,
+ M9MO_LENS_ZOOM_SPEED, 0x00);
+ CHECK_ERR(err);
+ } else {
+ err = m9mo_writeb(sd, M9MO_CATEGORY_LENS,
+ M9MO_LENS_ZOOM_SPEED, 0x01);
+ CHECK_ERR(err);
+ }
+
+ /* AF CANCEL */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_LENS,
+ M9MO_LENS_AF_START_STOP, 0x05);
+ CHECK_ERR(err);
+
+ err = m9mo_writeb(sd, M9MO_CATEGORY_LENS,
+ M9MO_LENS_AF_ZOOM_LEVEL, optical_zoom_val[opti_val]);
+ CHECK_ERR(err);
+
+ err = m9mo_writeb(sd, M9MO_CATEGORY_MON,
+ M9MO_MON_ZOOM, zoom_val[digi_val]);
CHECK_ERR(err);
state->zoom = val;
@@ -2130,61 +3808,100 @@ static int m9mo_set_zoom(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
return 0;
}
-static int m9mo_set_optical_zoom_step(struct v4l2_subdev *sd,
- struct v4l2_control *ctrl)
+static int m9mo_set_zoom_ctrl(struct v4l2_subdev *sd, int val)
{
struct m9mo_state *state = to_state(sd);
- struct v4l2_queryctrl qc = {0,};
- int val = ctrl->value, err, i;
- int n_zoom[] = { 10, 12, 15, 18, 22, 28, 34, 40, 50, 61, 75,
- 94, 114, 139, 179, 210};
- cam_dbg("E, value %d\n", val);
+ int err;
+ int zoom_ctrl, zoom_speed;
+ int read_ctrl, read_speed;
- qc.id = ctrl->id;
- m9mo_queryctrl(sd, &qc);
+ cam_trace("E, value %d\n", val);
- if (val < (qc.minimum * 10) || val > (qc.maximum * 10)) {
- cam_warn("invalied value, %d\n", val);
- val = qc.default_value * 10;
- }
+ switch (val) {
+ case V4L2_OPTICAL_ZOOM_TELE_START:
+ zoom_ctrl = 0;
+ zoom_speed = 1;
+ break;
- for (i = 0 ; i <= sizeof(n_zoom) ; i++) {
- if (n_zoom[i] >= ctrl->value) {
- val = i;
- break;
- }
- }
+ case V4L2_OPTICAL_ZOOM_WIDE_START:
+ zoom_ctrl = 1;
+ zoom_speed = 1;
+ break;
- if (val < 0 || val > 0x0F) {
- cam_warn("invalied value, %d\n", val);
- val = 0;
+ case V4L2_OPTICAL_ZOOM_SLOW_TELE_START:
+ zoom_ctrl = 0;
+ zoom_speed = 0;
+ break;
+
+ case V4L2_OPTICAL_ZOOM_SLOW_WIDE_START:
+ zoom_ctrl = 1;
+ zoom_speed = 0;
+ break;
+
+ case V4L2_OPTICAL_ZOOM_STOP:
+ zoom_ctrl = 2;
+ zoom_speed = 0x0F;
+ break;
+
+ default:
+ cam_warn("invalid value, %d", val);
+ return 0;
}
- err = m9mo_writeb(sd, M9MO_CATEGORY_LENS,
- M9MO_LENS_AF_ZOOM_LEVEL, val);
+ if (state->recording)
+ zoom_speed = 0;
+
+ err = m9mo_readb(sd, M9MO_CATEGORY_LENS,
+ M9MO_LENS_ZOOM_SPEED, &read_speed);
CHECK_ERR(err);
- state->optical_zoom = val;
+ err = m9mo_readb(sd, M9MO_CATEGORY_LENS,
+ M9MO_LENS_AF_ZOOM_CTRL, &read_ctrl);
+ CHECK_ERR(err);
+
+ if (read_speed != zoom_speed && val != V4L2_OPTICAL_ZOOM_STOP) {
+ err = m9mo_writeb(sd, M9MO_CATEGORY_LENS,
+ M9MO_LENS_ZOOM_SPEED, zoom_speed);
+ CHECK_ERR(err);
+ }
+
+ if (read_ctrl != zoom_ctrl) {
+ if (val != V4L2_OPTICAL_ZOOM_STOP) {
+ /* AF CANCEL */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_LENS,
+ M9MO_LENS_AF_START_STOP, 0x05);
+ CHECK_ERR(err);
+ }
+
+ err = m9mo_writeb(sd, M9MO_CATEGORY_LENS,
+ M9MO_LENS_AF_ZOOM_CTRL, zoom_ctrl);
+ CHECK_ERR(err);
+ }
cam_trace("X\n");
return 0;
}
-static int m9mo_set_optical_zoom_ctrl(struct v4l2_subdev *sd, int val)
+static int m9mo_set_smart_zoom(struct v4l2_subdev *sd, int val)
{
- struct m9mo_state *state = to_state(sd);
int err;
- s32 zoom_step;
+ int smart_zoom;
+ struct m9mo_state *state = to_state(sd);
- err = m9mo_writeb(sd, M9MO_CATEGORY_LENS,
- M9MO_LENS_AF_ZOOM_CTRL, val);
- CHECK_ERR(err);
+ cam_trace("E, value %d\n", val);
- err = m9mo_readb(sd, M9MO_CATEGORY_LENS,
- M9MO_LENS_AF_ZOOM_LEVEL, &zoom_step);
+ if (val)
+ smart_zoom = 0x5C;
+ else
+ smart_zoom = 0;
+
+ /* Off:0x00, On: 0x01 ~ 0x5C */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_MON,
+ M9MO_MON_HR_ZOOM, smart_zoom);
+ CHECK_ERR(err);
- state->optical_zoom = zoom_step;
+ state->smart_zoom_mode = val;
cam_trace("X\n");
return 0;
@@ -2209,14 +3926,13 @@ static int m9mo_set_jpeg_quality(struct v4l2_subdev *sd,
M9MO_CAPPARM_JPEG_RATIO, 0x62);
CHECK_ERR(err);
-#if 0 /* m9mo */
+ /* m9mo */
if (val <= 65) /* Normal */
- ratio = 0x0A;
+ ratio = 0x14;
else if (val <= 75) /* Fine */
- ratio = 0x05;
+ ratio = 0x09;
else /* Superfine */
-#endif
- ratio = 0x00;
+ ratio = 0x02;
err = m9mo_writeb(sd, M9MO_CATEGORY_CAPPARM,
M9MO_CAPPARM_JPEG_RATIO_OFS, ratio);
@@ -2229,6 +3945,7 @@ static int m9mo_set_jpeg_quality(struct v4l2_subdev *sd,
static int m9mo_get_exif(struct v4l2_subdev *sd)
{
struct m9mo_state *state = to_state(sd);
+#if 0 /* legacy */
/* standard values */
u16 iso_std_values[] = { 10, 12, 16, 20, 25, 32, 40, 50, 64, 80,
100, 125, 160, 200, 250, 320, 400, 500, 640, 800,
@@ -2237,8 +3954,46 @@ static int m9mo_get_exif(struct v4l2_subdev *sd)
u16 iso_qtable[] = { 11, 14, 17, 22, 28, 35, 44, 56, 71, 89,
112, 141, 178, 224, 282, 356, 449, 565, 712, 890,
1122, 1414, 1782, 2245, 2828, 3564, 4490, 5657, 7127, 8909};
+#endif
+ /* standard values : M9MO */
+ u16 iso_std_values[] = {
+ 64, 80, 100, 125, 160,
+ 200, 250, 320, 400, 500,
+ 640, 800, 1000, 1250, 1600,
+ 2000, 2500, 3200, 4000, 5000,
+ 6400
+ };
+ /* quantization table */
+ u16 iso_qtable[] = {
+ 72, 89, 112, 141, 179,
+ 224, 283, 358, 447, 566,
+ 716, 894, 1118, 1414, 1789,
+ 2236, 2828, 3578, 4472, 5657,
+ 7155
+ };
+
+ s16 ss_std_values[] = {
+ -400, -358, -300, -258, -200,
+ -158, -100, -58, 0, 51,
+ 100, 158, 200, 258, 300,
+ 332, 391, 432, 491, 549,
+ 591, 649, 697, 749, 797,
+ 845, 897, 955, 997, 1055,
+ };
+
+ s16 ss_qtable[] = {
+ -375, -325, -275, -225, -175,
+ -125, -75, -25, 25, 75,
+ 125, 175, 225, 275, 325,
+ 375, 425, 475, 525, 575,
+ 625, 675, 725, 775, 825,
+ 875, 925, 975, 1025, 1075,
+ };
+
int num, den, i, err;
+ cam_trace("E\n");
+
/* exposure time */
err = m9mo_readl(sd, M9MO_CATEGORY_EXIF,
M9MO_EXIF_EXPTIME_NUM, &num);
@@ -2246,7 +4001,10 @@ static int m9mo_get_exif(struct v4l2_subdev *sd)
err = m9mo_readl(sd, M9MO_CATEGORY_EXIF,
M9MO_EXIF_EXPTIME_DEN, &den);
CHECK_ERR(err);
- state->exif.exptime = (u32)num*1000/den;
+ if (den)
+ state->exif.exptime = (u32)num*1000/den;
+ else
+ state->exif.exptime = 0;
/* flash */
err = m9mo_readw(sd, M9MO_CATEGORY_EXIF, M9MO_EXIF_FLASH, &num);
@@ -2262,27 +4020,82 @@ static int m9mo_get_exif(struct v4l2_subdev *sd)
break;
}
}
+ if (i == NELEMS(iso_qtable))
+ state->exif.iso = 8000;
+
+ cam_info("%s: real iso = %d, qtable_iso = %d, stored iso = %d\n",
+ __func__, num, iso_qtable[i], state->exif.iso);
/* shutter speed */
err = m9mo_readl(sd, M9MO_CATEGORY_EXIF, M9MO_EXIF_TV_NUM, &num);
CHECK_ERR(err);
err = m9mo_readl(sd, M9MO_CATEGORY_EXIF, M9MO_EXIF_TV_DEN, &den);
CHECK_ERR(err);
- state->exif.tv = num*M9MO_DEF_APEX_DEN/den;
+#if 0
+ if (den)
+ state->exif.tv = num*M9MO_DEF_APEX_DEN/den;
+ else
+ state->exif.tv = 0;
+#endif
+
+ if (den) {
+ for (i = 0; i < NELEMS(ss_qtable); i++) {
+ if (num*M9MO_DEF_APEX_DEN/den <= ss_qtable[i]) {
+ state->exif.tv = ss_std_values[i];
+ break;
+ }
+ }
+ if (i == NELEMS(ss_qtable))
+ state->exif.tv = 1097;
+ cam_info("%s: real TV = %d, stored TV = %d\n", __func__,
+ num*M9MO_DEF_APEX_DEN/den, state->exif.tv);
+ } else
+ state->exif.tv = 0;
/* brightness */
err = m9mo_readl(sd, M9MO_CATEGORY_EXIF, M9MO_EXIF_BV_NUM, &num);
CHECK_ERR(err);
err = m9mo_readl(sd, M9MO_CATEGORY_EXIF, M9MO_EXIF_BV_DEN, &den);
CHECK_ERR(err);
- state->exif.bv = num*M9MO_DEF_APEX_DEN/den;
+ if (den)
+ state->exif.bv = num*M9MO_DEF_APEX_DEN/den;
+ else
+ state->exif.bv = 0;
- /* exposure */
+ /* exposure bias value */
err = m9mo_readl(sd, M9MO_CATEGORY_EXIF, M9MO_EXIF_EBV_NUM, &num);
CHECK_ERR(err);
err = m9mo_readl(sd, M9MO_CATEGORY_EXIF, M9MO_EXIF_EBV_DEN, &den);
CHECK_ERR(err);
- state->exif.ebv = num*M9MO_DEF_APEX_DEN/den;
+ if (den)
+ state->exif.ebv = num*M9MO_DEF_APEX_DEN/den;
+ else
+ state->exif.ebv = 0;
+
+ /* Aperture */
+ err = m9mo_readl(sd, M9MO_CATEGORY_EXIF, M9MO_EXIF_AV_NUM, &num);
+ CHECK_ERR(err);
+ err = m9mo_readl(sd, M9MO_CATEGORY_EXIF, M9MO_EXIF_AV_DEN, &den);
+ CHECK_ERR(err);
+ if (den)
+ state->exif.av = num*M9MO_DEF_APEX_DEN/den;
+ else
+ state->exif.av = 0;
+ cam_info("%s: AV num = %d, AV den = %d\n", __func__, num, den);
+
+ /* Focal length */
+ err = m9mo_readw(sd, M9MO_CATEGORY_LENS, M9MO_EXIF_FL, &num);
+ CHECK_ERR(err);
+ state->exif.focal_length = num * M9MO_DEF_APEX_DEN;
+ cam_info("%s: FL = %d\n", __func__, num);
+
+ /* Focal length 35m */
+ err = m9mo_readw(sd, M9MO_CATEGORY_LENS, M9MO_EXIF_FL_35, &num);
+ CHECK_ERR(err);
+ state->exif.focal_35mm_length = num * M9MO_DEF_APEX_DEN;
+ cam_info("%s: FL_35 = %d\n", __func__, num);
+
+ cam_trace("X\n");
return err;
}
@@ -2314,13 +4127,147 @@ static int m9mo_get_fd_eye_blink_result(struct v4l2_subdev *sd)
return err;
}
+static int m9mo_get_red_eye_fix_result(struct v4l2_subdev *sd)
+{
+ struct m9mo_state *state = to_state(sd);
+ int err;
+ s32 red_eye_status;
+
+ if (state->flash_mode != FLASH_MODE_RED_EYE_FIX)
+ return 0;
+
+ err = m9mo_readb(sd, M9MO_CATEGORY_FD,
+ M9MO_FD_RED_DET_STATUS, &red_eye_status);
+ CHECK_ERR(err);
+
+ state->fd_red_eye_status = red_eye_status;
+
+ cam_dbg("red eye status [0x%x]\n", red_eye_status);
+
+ return err;
+}
+
+static int m9mo_start_dual_postview(struct v4l2_subdev *sd, int frame_num)
+{
+#if 0
+ struct m9mo_state *state = to_state(sd);
+#endif
+ int err, int_factor;
+ cam_trace("E : %d frame\n", frame_num);
+
+ /* Select image number of frame Preview image */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_PARM,
+ M9MO_PARM_SEL_FRAME_VIDEO_SNAP, frame_num);
+ CHECK_ERR(err);
+
+ /* Select main image format */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_CAPPARM,
+ M9MO_CAPPARM_YUVOUT_PREVIEW, 0x00);
+ CHECK_ERR(err);
+
+#if 0
+ /* Select preview image size */
+#if 0
+ err = m9mo_writeb(sd, M9MO_CATEGORY_CAPPARM,
+ M9MO_CAPPARM_PREVIEW_IMG_SIZE, 0x08);
+ CHECK_ERR(err);
+#else
+ if (FRM_RATIO(state->preview) == CAM_FRMRATIO_VGA) {
+ err = m9mo_writeb(sd, M9MO_CATEGORY_CAPPARM,
+ M9MO_CAPPARM_PREVIEW_IMG_SIZE, 0x08);
+ CHECK_ERR(err);
+ } else if (FRM_RATIO(state->preview) == CAM_FRMRATIO_HD) {
+ err = m9mo_writeb(sd, M9MO_CATEGORY_CAPPARM,
+ M9MO_CAPPARM_PREVIEW_IMG_SIZE, 0x0F);
+ CHECK_ERR(err);
+ }
+#endif
+#endif
+
+ /* Get Video Snap Shot data */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_PARM,
+ M9MO_PARM_VIDEO_SNAP_IMG_TRANSFER_START, 0x02);
+ CHECK_ERR(err);
+
+ /* Clear Interrupt factor */
+ int_factor = m9mo_wait_interrupt(sd, M9MO_ISP_TIMEOUT);
+ if (!(int_factor & M9MO_INT_FRAME_SYNC)) {
+ cam_err("M9MO_INT_FRAME_SYNC isn't issued, %#x\n", int_factor);
+ return -ETIMEDOUT;
+ }
+
+ cam_trace("X\n");
+ return err;
+}
+
+static int m9mo_start_dual_capture(struct v4l2_subdev *sd, int frame_num)
+{
+ struct m9mo_state *state = to_state(sd);
+ int err, int_factor;
+ cam_trace("E : %d frame\n", frame_num);
+
+ /* Select image number of frame For Video Snap Shot image */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_PARM,
+ M9MO_PARM_SEL_FRAME_VIDEO_SNAP, frame_num);
+ CHECK_ERR(err);
+
+ /* Select main image format */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_CAPPARM,
+ M9MO_CAPPARM_YUVOUT_MAIN, 0x01);
+ CHECK_ERR(err);
+
+ /* Select main image size - 4M */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_CAPPARM,
+ M9MO_CAPPARM_MAIN_IMG_SIZE, 0x1E);
+ CHECK_ERR(err);
+
+ /* Get Video Snap Shot data */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_PARM,
+ M9MO_PARM_VIDEO_SNAP_IMG_TRANSFER_START, 0x01);
+ CHECK_ERR(err);
+
+ /* Clear Interrupt factor */
+ int_factor = m9mo_wait_interrupt(sd, M9MO_ISP_TIMEOUT);
+ if (!(int_factor & M9MO_INT_FRAME_SYNC)) {
+ cam_err("M9MO_INT_FRAME_SYNC isn't issued, %#x\n", int_factor);
+ return -ETIMEDOUT;
+ }
+
+ /* Get main image JPEG size */
+ err = m9mo_readl(sd, M9MO_CATEGORY_CAPCTRL,
+ M9MO_CAPCTRL_IMG_SIZE, &state->jpeg.main_size);
+ CHECK_ERR(err);
+ cam_trace("~~~~~~ main_size : 0x%x ~~~~~~\n", state->jpeg.main_size);
+#if 1
+ state->jpeg.main_offset = 0;
+ state->jpeg.thumb_offset = M9MO_JPEG_MAXSIZE;
+ state->jpeg.postview_offset = M9MO_JPEG_MAXSIZE + M9MO_THUMB_MAXSIZE;
+
+ /* Read Exif information */
+ m9mo_get_exif(sd);
+#endif
+
+ if (frame_num == state->dual_capture_frame)
+ state->dual_capture_start = 0;
+
+ cam_trace("X\n");
+ return err;
+}
+
static int m9mo_start_postview_capture(struct v4l2_subdev *sd, int frame_num)
{
struct m9mo_state *state = to_state(sd);
int err, int_factor;
- cam_trace("E\n");
+ cam_trace("E : %d frame\n", frame_num);
+
+ if (state->dual_capture_start)
+ return m9mo_start_dual_postview(sd, frame_num);
+
+ if (state->running_capture_mode == RUNNING_MODE_CONTINUOUS
+ || state->running_capture_mode == RUNNING_MODE_BEST) {
+
+ cam_dbg("m9mo_start_postview_capture (%d)\n", frame_num);
- if (state->running_capture_mode == RUNNING_MODE_CONTINUOUS) {
/* Select image number of frame */
err = m9mo_writeb(sd, M9MO_CATEGORY_CAPCTRL,
M9MO_CAPCTRL_FRM_PRV_SEL, frame_num);
@@ -2332,7 +4279,8 @@ static int m9mo_start_postview_capture(struct v4l2_subdev *sd, int frame_num)
int_factor);
return -ETIMEDOUT;
}
- } else if (state->running_capture_mode == RUNNING_MODE_BRACKET) {
+ } else if (state->running_capture_mode == RUNNING_MODE_AE_BRACKET
+ || state->running_capture_mode == RUNNING_MODE_LOWLIGHT) {
/* Select image number of frame */
err = m9mo_writeb(sd, M9MO_CATEGORY_CAPCTRL,
M9MO_CAPCTRL_FRM_PRV_SEL, frame_num);
@@ -2344,6 +4292,10 @@ static int m9mo_start_postview_capture(struct v4l2_subdev *sd, int frame_num)
int_factor);
return -ETIMEDOUT;
}
+ } else if (state->running_capture_mode == RUNNING_MODE_WB_BRACKET) {
+ /* Select image number of frame */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_CAPCTRL,
+ M9MO_CAPCTRL_FRM_PRV_SEL, frame_num);
} else if (state->running_capture_mode == RUNNING_MODE_HDR) {
cam_warn("HDR have no PostView\n");
return 0;
@@ -2359,6 +4311,29 @@ static int m9mo_start_postview_capture(struct v4l2_subdev *sd, int frame_num)
int_factor);
return -ETIMEDOUT;
}
+ } else if (state->running_capture_mode == RUNNING_MODE_BURST) {
+ int i;
+
+ /* Get Preview data */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_CAPCTRL,
+ M9MO_CAPCTRL_TRANSFER, 0x02);
+ CHECK_ERR(err);
+
+ for (i = 0; i < 3; i++) { /*wait M9MO_INT_FRAME_SYNC*/
+ /* Clear Interrupt factor */
+ int_factor = m9mo_wait_interrupt(sd, M9MO_ISP_TIMEOUT);
+ if (int_factor & (M9MO_INT_CAPTURE|M9MO_INT_SOUND)) {
+ cam_trace("----skip interrupt=%x", int_factor);
+ continue;
+ }
+
+ if (!(int_factor & M9MO_INT_FRAME_SYNC)) {
+ cam_warn("M9MO_INT_FRAME_SYNC isn't issued on transfer, %#x\n",
+ int_factor);
+ return -ETIMEDOUT;
+ }
+ break;
+ }
} else {
/* Select image number of frame */
err = m9mo_writeb(sd, M9MO_CATEGORY_CAPCTRL,
@@ -2366,33 +4341,41 @@ static int m9mo_start_postview_capture(struct v4l2_subdev *sd, int frame_num)
}
CHECK_ERR(err);
- /* Set YUV out for Preview */
- err = m9mo_writeb(sd, M9MO_CATEGORY_CAPPARM,
- M9MO_CAPPARM_YUVOUT_PREVIEW, 0x00);
- CHECK_ERR(err);
-
- /* Set Preview Image size */
- if (FRM_RATIO(state->capture) == CAM_FRMRATIO_WVGA) {
- err = m9mo_writeb(sd, M9MO_CATEGORY_CAPPARM,
- M9MO_CAPPARM_PREVIEW_IMG_SIZE, 0x0F);
- CHECK_ERR(err);
- } else if (FRM_RATIO(state->capture) == CAM_FRMRATIO_VGA) {
+ if (state->running_capture_mode != RUNNING_MODE_BURST) {
+ /* Set YUV out for Preview */
err = m9mo_writeb(sd, M9MO_CATEGORY_CAPPARM,
- M9MO_CAPPARM_PREVIEW_IMG_SIZE, 0x13);
+ M9MO_CAPPARM_YUVOUT_PREVIEW, 0x00);
CHECK_ERR(err);
- }
- /* Get Preview data */
- err = m9mo_writeb(sd, M9MO_CATEGORY_CAPCTRL,
- M9MO_CAPCTRL_TRANSFER, 0x02);
- CHECK_ERR(err);
+#if 0
+ /* Set Preview(Postview) Image size */
+ if (FRM_RATIO(state->capture) == CAM_FRMRATIO_HD) {
+ err = m9mo_writeb(sd, M9MO_CATEGORY_CAPPARM,
+ M9MO_CAPPARM_PREVIEW_IMG_SIZE, 0x0F);
+ CHECK_ERR(err);
+ } else if (FRM_RATIO(state->capture) == CAM_FRMRATIO_D1) {
+ err = m9mo_writeb(sd, M9MO_CATEGORY_CAPPARM,
+ M9MO_CAPPARM_PREVIEW_IMG_SIZE, 0x14);
+ CHECK_ERR(err);
+ } else {
+ err = m9mo_writeb(sd, M9MO_CATEGORY_CAPPARM,
+ M9MO_CAPPARM_PREVIEW_IMG_SIZE, 0x13);
+ CHECK_ERR(err);
+ }
+#endif
- /* Clear Interrupt factor */
- int_factor = m9mo_wait_interrupt(sd, M9MO_ISP_TIMEOUT);
- if (!(int_factor & M9MO_INT_CAPTURE)) {
- cam_warn("M9MO_INT_CAPTURE isn't issued on transfer, %#x\n",
- int_factor);
- return -ETIMEDOUT;
+ /* Get Preview data */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_CAPCTRL,
+ M9MO_CAPCTRL_TRANSFER, 0x02);
+ CHECK_ERR(err);
+
+ /* Clear Interrupt factor */
+ int_factor = m9mo_wait_interrupt(sd, M9MO_ISP_TIMEOUT);
+ if (!(int_factor & M9MO_INT_CAPTURE)) {
+ cam_warn("M9MO_INT_CAPTURE isn't issued on transfer, %#x\n",
+ int_factor);
+ return -ETIMEDOUT;
+ }
}
/*
@@ -2418,7 +4401,7 @@ static int m9mo_start_YUV_capture(struct v4l2_subdev *sd, int frame_num)
{
struct m9mo_state *state = to_state(sd);
int err, int_factor;
- cam_trace("E\n");
+ cam_trace("E : %d frame\n", frame_num);
/* Select image number of frame */
err = m9mo_writeb(sd, M9MO_CATEGORY_CAPCTRL,
@@ -2440,7 +4423,9 @@ static int m9mo_start_YUV_capture(struct v4l2_subdev *sd, int frame_num)
err = m9mo_writeb(sd, M9MO_CATEGORY_CAPPARM,
M9MO_CAPPARM_MAIN_IMG_SIZE, state->capture->reg_val);
CHECK_ERR(err);
- cam_trace("Select image size [ width %d, height : %d ]\n",
+ if (state->smart_zoom_mode)
+ m9mo_set_smart_zoom(sd, state->smart_zoom_mode);
+ cam_trace("Select image size [ w=%d, h=%d ]\n",
state->capture->width, state->capture->height);
/* Get main YUV data */
@@ -2478,9 +4463,16 @@ static int m9mo_start_capture(struct v4l2_subdev *sd, int frame_num)
{
struct m9mo_state *state = to_state(sd);
int err, int_factor;
- cam_trace("E\n");
+ cam_trace("E : %d frame\n", frame_num);
+
+ if (state->dual_capture_start)
+ return m9mo_start_dual_capture(sd, frame_num);
+
+ if (state->running_capture_mode == RUNNING_MODE_CONTINUOUS
+ || state->running_capture_mode == RUNNING_MODE_BEST) {
+
+ cam_dbg("m9mo_start_capture() num=%d\n", frame_num);
- if (state->running_capture_mode == RUNNING_MODE_CONTINUOUS) {
/* Select image number of frame */
err = m9mo_writeb(sd, M9MO_CATEGORY_CAPCTRL,
M9MO_CAPCTRL_FRM_SEL, frame_num);
@@ -2493,7 +4485,9 @@ static int m9mo_start_capture(struct v4l2_subdev *sd, int frame_num)
int_factor);
return -ETIMEDOUT;
}
- } else if (state->running_capture_mode == RUNNING_MODE_BRACKET) {
+ } else if (state->running_capture_mode == RUNNING_MODE_AE_BRACKET
+ || state->running_capture_mode == RUNNING_MODE_LOWLIGHT) {
+
/* Select image number of frame */
err = m9mo_writeb(sd, M9MO_CATEGORY_CAPCTRL,
M9MO_CAPCTRL_FRM_SEL, frame_num);
@@ -2506,6 +4500,11 @@ static int m9mo_start_capture(struct v4l2_subdev *sd, int frame_num)
int_factor);
return -ETIMEDOUT;
}
+ } else if (state->running_capture_mode == RUNNING_MODE_WB_BRACKET) {
+ /* Select image number of frame */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_CAPCTRL,
+ M9MO_CAPCTRL_FRM_SEL, frame_num);
+ CHECK_ERR(err);
} else if (state->running_capture_mode == RUNNING_MODE_BLINK) {
/* Select image number of frame */
err = m9mo_writeb(sd, M9MO_CATEGORY_CAPCTRL,
@@ -2522,6 +4521,31 @@ static int m9mo_start_capture(struct v4l2_subdev *sd, int frame_num)
err = m9mo_get_fd_eye_blink_result(sd);
CHECK_ERR(err);
+ } else if (state->running_capture_mode == RUNNING_MODE_RAW) {
+ /* Select Main Image Format */
+ if (frame_num == 0) {
+ err = m9mo_writeb(sd, M9MO_CATEGORY_CAPPARM,
+ M9MO_CAPPARM_YUVOUT_MAIN, 0x05);
+ } else {
+ err = m9mo_writeb(sd, M9MO_CATEGORY_CAPPARM,
+ M9MO_CAPPARM_YUVOUT_MAIN, 0x01);
+ }
+ CHECK_ERR(err);
+
+ /* Select image number of frame */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_CAPCTRL,
+ M9MO_CAPCTRL_FRM_SEL, 0x01);
+ CHECK_ERR(err);
+
+ if (frame_num == 1) {
+ /* Set Size */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_CAPPARM,
+ M9MO_CAPPARM_MAIN_IMG_SIZE, 0x33);
+ CHECK_ERR(err);
+ }
+ } else if (state->running_capture_mode == RUNNING_MODE_BURST) {
+ err = 0;
+
} else {
/* Select image number of frame */
err = m9mo_writeb(sd, M9MO_CATEGORY_CAPCTRL,
@@ -2529,54 +4553,92 @@ static int m9mo_start_capture(struct v4l2_subdev *sd, int frame_num)
CHECK_ERR(err);
}
+ m9mo_get_red_eye_fix_result(sd);
+
+#if 0
/* Set main image JPEG fime max size */
err = m9mo_writel(sd, M9MO_CATEGORY_CAPPARM,
- M9MO_CAPPARM_JPEG_SIZE_MAX, 0x00500000);
+ M9MO_CAPPARM_JPEG_SIZE_MAX, 0x01000000);
CHECK_ERR(err);
/* Set main image JPEG fime min size */
err = m9mo_writel(sd, M9MO_CATEGORY_CAPPARM,
M9MO_CAPPARM_JPEG_SIZE_MIN, 0x00100000);
CHECK_ERR(err);
-
- /* Select main image format */
- err = m9mo_writeb(sd, M9MO_CATEGORY_CAPPARM,
- M9MO_CAPPARM_YUVOUT_MAIN, 0x01);
- CHECK_ERR(err);
-
-#if 0
- /* Select main image size */
- err = m9mo_writeb(sd, M9MO_CATEGORY_CAPPARM,
- M9MO_CAPPARM_MAIN_IMG_SIZE, 0x31);
- CHECK_ERR(err);
#endif
+ if (state->running_capture_mode == RUNNING_MODE_LOWLIGHT) {
+ err = m9mo_writeb(sd, M9MO_CATEGORY_CAPPARM,
+ M9MO_CAPPARM_YUVOUT_MAIN, 0x0);
+ CHECK_ERR(err);
+ } else {
+ if (state->running_capture_mode != RUNNING_MODE_RAW
+ && state->running_capture_mode != RUNNING_MODE_BURST) {
+ /* Select main image format */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_CAPPARM,
+ M9MO_CAPPARM_YUVOUT_MAIN, 0x01);
+ CHECK_ERR(err);
+ }
+ }
/* Get main JPEG data */
err = m9mo_writeb(sd, M9MO_CATEGORY_CAPCTRL,
M9MO_CAPCTRL_TRANSFER, 0x01);
- /* Clear Interrupt factor */
- int_factor = m9mo_wait_interrupt(sd, M9MO_ISP_TIMEOUT);
- if (!(int_factor & M9MO_INT_CAPTURE)) {
- cam_warn("M9MO_INT_CAPTURE isn't issued on transfer, %#x\n",
- int_factor);
- return -ETIMEDOUT;
+ if (state->running_capture_mode == RUNNING_MODE_BURST) {
+ int i;
+ for (i = 0; i < 3; i++) { /*wait M9MO_INT_CAPTURE*/
+
+ int_factor = m9mo_wait_interrupt(sd, M9MO_ISP_TIMEOUT);
+ if (int_factor & (M9MO_INT_FRAME_SYNC|M9MO_INT_SOUND)) {
+ cam_trace("----skip interrupt=%x", int_factor);
+ continue;
+ }
+
+ if (!(int_factor & M9MO_INT_CAPTURE)) {
+ cam_warn("M9MO_INT_CAPTURE isn't issued on transfer, %#x\n",
+ int_factor);
+ return -ETIMEDOUT;
+ }
+ break;
+ }
+ } else {
+ /* Clear Interrupt factor */
+ int_factor = m9mo_wait_interrupt(sd, M9MO_ISP_TIMEOUT);
+ if (!(int_factor & M9MO_INT_CAPTURE)) {
+ cam_warn("M9MO_INT_CAPTURE isn't issued on transfer, %#x\n",
+ int_factor);
+ return -ETIMEDOUT;
+ }
}
err = m9mo_readl(sd, M9MO_CATEGORY_CAPCTRL, M9MO_CAPCTRL_IMG_SIZE,
&state->jpeg.main_size);
CHECK_ERR(err);
+ cam_dbg(" ==> jpeg size=%d\n", state->jpeg.main_size);
-/*
- err = m9mo_readl(sd, M9MO_CATEGORY_CAPCTRL, M9MO_CAPCTRL_THUMB_SIZE,
- &state->jpeg.thumb_size);
- CHECK_ERR(err);
-*/
state->jpeg.main_offset = 0;
state->jpeg.thumb_offset = M9MO_JPEG_MAXSIZE;
state->jpeg.postview_offset = M9MO_JPEG_MAXSIZE + M9MO_THUMB_MAXSIZE;
- m9mo_get_exif(sd);
+ if (state->running_capture_mode != RUNNING_MODE_RAW) {
+ if (state->running_capture_mode != RUNNING_MODE_LOWLIGHT)
+ m9mo_get_exif(sd);
+ } else {
+ if (frame_num == 1) {
+ m9mo_get_exif(sd);
+
+ m9mo_set_mode(sd, M9MO_MONITOR_MODE);
+ err = m9mo_wait_interrupt(sd, M9MO_ISP_TIMEOUT);
+ if (!(err & M9MO_INT_MODE)) {
+ cam_err("m9mo_start_capture() MONITOR_MODE error\n");
+ return -ETIMEDOUT;
+ }
+
+ err = m9mo_writeb(sd, M9MO_CATEGORY_CAPPARM,
+ 0x78, 0x00);
+ CHECK_ERR(err);
+ }
+ }
cam_trace("X\n");
return err;
@@ -2589,6 +4651,53 @@ static int m9mo_start_capture(struct v4l2_subdev *sd, int frame_num)
return 0;
}*/
+static int m9mo_start_capture_thumb(struct v4l2_subdev *sd, int frame_num)
+{
+ struct m9mo_state *state = to_state(sd);
+ int err, int_factor;
+ cam_trace("E : %d frame\n", frame_num);
+
+ cam_dbg("m9mo_start_capture_thumb() num=%d\n", frame_num);
+
+ /* Select image number of frame */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_CAPCTRL,
+ M9MO_CAPCTRL_FRM_THUMB_SEL, frame_num);
+ CHECK_ERR(err);
+
+ /* Clear Interrupt factor */
+ int_factor = m9mo_wait_interrupt(sd, M9MO_ISP_TIMEOUT);
+ if (!(int_factor & M9MO_INT_CAPTURE)) {
+ cam_warn("M9MO_INT_CAPTURE isn't issued on frame select, %#x\n",
+ int_factor);
+ return -ETIMEDOUT;
+ }
+
+ err = m9mo_writeb(sd, M9MO_CATEGORY_CAPPARM,
+ M9MO_CAPPARM_YUVOUT_THUMB, 0x01);
+ CHECK_ERR(err);
+
+ err = m9mo_writeb(sd, M9MO_CATEGORY_CAPPARM,
+ M9MO_CAPPARM_THUMB_IMG_SIZE, 0x04); /* 320 x 240 */
+ CHECK_ERR(err);
+
+ /* Get main thumb data */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_CAPCTRL,
+ M9MO_CAPCTRL_TRANSFER, 0x03);
+
+ /* Clear Interrupt factor */
+ int_factor = m9mo_wait_interrupt(sd, M9MO_ISP_TIMEOUT);
+ if (!(int_factor & M9MO_INT_CAPTURE)) {
+ cam_warn("M9MO_INT_CAPTURE isn't issued on transfer, %#x\n",
+ int_factor);
+ return -ETIMEDOUT;
+ }
+
+ err = m9mo_readl(sd, M9MO_CATEGORY_CAPCTRL, M9MO_CAPCTRL_THUMB_SIZE,
+ &state->jpeg.thumb_size);
+ CHECK_ERR(err);
+
+ return err;
+}
static int m9mo_set_facedetect(struct v4l2_subdev *sd, int val)
{
@@ -2606,26 +4715,14 @@ static int m9mo_set_facedetect(struct v4l2_subdev *sd, int val)
CHECK_ERR(err);
err = m9mo_writeb(sd, M9MO_CATEGORY_FD, M9MO_FD_MAX, 0x07);
CHECK_ERR(err);
- err = m9mo_writeb(sd, M9MO_CATEGORY_FD, M9MO_FD_CTL, 0x11);
- CHECK_ERR(err);
-
-#if 0 /* AF */
- err = m9mo_writeb(sd, M9MO_CATEGORY_LENS,
- M9MO_LENS_AF_SCAN_RANGE, 0x00);
- CHECK_ERR(err);
- err = m9mo_writeb(sd, M9MO_CATEGORY_LENS,
- M9MO_LENS_AF_ADJ_TEMP_VALUE, 0x23);
- CHECK_ERR(err);
- err = m9mo_writeb(sd, M9MO_CATEGORY_LENS,
- M9MO_LENS_AF_ALGORITHM, 0x00);
- CHECK_ERR(err);
- err = m9mo_writeb(sd, M9MO_CATEGORY_SYS,
- M9MO_SYS_INT_EN, M9MO_INT_AF);
- CHECK_ERR(err);
- err = m9mo_writeb(sd, M9MO_CATEGORY_LENS,
- M9MO_LENS_AF_START, 0x01);
+ if (state->mode == MODE_SMART_AUTO) {
+ err = m9mo_writeb(sd, M9MO_CATEGORY_FD,
+ M9MO_FD_CTL, 0x01);
+ } else {
+ err = m9mo_writeb(sd, M9MO_CATEGORY_FD,
+ M9MO_FD_CTL, 0x11);
+ }
CHECK_ERR(err);
-#endif
break;
case FACE_DETECTION_SMILE_SHOT:
@@ -2647,32 +4744,6 @@ static int m9mo_set_facedetect(struct v4l2_subdev *sd, int val)
return 0;
}
-
-static int m9mo_set_bracket(struct v4l2_subdev *sd, int val)
-{
- cam_trace("E val : %d\n", val);
-
- switch (val) {
- case BRACKET_MODE_OFF:
- cam_dbg("~~~~~~ bracket off ~~~~~~ val : %d\n", val);
- break;
-
- case BRACKET_MODE_AEB:
- cam_dbg("~~~~~~ bracket aeb on ~~~~~~ val : %d\n", val);
- break;
-
- case BRACKET_MODE_WBB:
- cam_dbg("~~~~~~ bracket wbb on ~~~~~~ val : %d\n", val);
- break;
-
- default:
- cam_err("~~~~ TBD ~~~~ val : %d", val);
- break;
- }
- cam_trace("X\n");
- return 0;
-}
-
static int m9mo_set_bracket_aeb(struct v4l2_subdev *sd, int val)
{
int err;
@@ -2680,45 +4751,52 @@ static int m9mo_set_bracket_aeb(struct v4l2_subdev *sd, int val)
switch (val) {
case BRACKET_AEB_VALUE1:
- cam_trace("~~~~~~ AEB value1 ~~~~~~ val : %d\n", val);
+ cam_dbg("~~~~~~ AEB value1 ~~~~~~ val : %d\n", val);
err = m9mo_writeb(sd, M9MO_CATEGORY_AE,
M9MO_AE_AUTO_BRACKET_EV, 0x1E); /* EV 0.3 */
+ CHECK_ERR(err);
break;
case BRACKET_AEB_VALUE2:
- cam_trace("~~~~~~ AEB value2 ~~~~~~ val : %d\n", val);
+ cam_dbg("~~~~~~ AEB value2 ~~~~~~ val : %d\n", val);
err = m9mo_writeb(sd, M9MO_CATEGORY_AE,
M9MO_AE_AUTO_BRACKET_EV, 0x3C); /* EV 0.6 */
+ CHECK_ERR(err);
break;
case BRACKET_AEB_VALUE3:
- cam_trace("~~~~~~ AEB value3 ~~~~~~ val : %d\n", val);
+ cam_dbg("~~~~~~ AEB value3 ~~~~~~ val : %d\n", val);
err = m9mo_writeb(sd, M9MO_CATEGORY_AE,
M9MO_AE_AUTO_BRACKET_EV, 0x64); /* EV 1.0 */
+ CHECK_ERR(err);
break;
case BRACKET_AEB_VALUE4:
- cam_trace("~~~~~~ AEB value4 ~~~~~~ val : %d\n", val);
+ cam_dbg("~~~~~~ AEB value4 ~~~~~~ val : %d\n", val);
err = m9mo_writeb(sd, M9MO_CATEGORY_AE,
M9MO_AE_AUTO_BRACKET_EV, 0x82); /* EV 1.3 */
+ CHECK_ERR(err);
break;
case BRACKET_AEB_VALUE5:
- cam_trace("~~~~~~ AEB value5 ~~~~~~ val : %d\n", val);
+ cam_dbg("~~~~~~ AEB value5 ~~~~~~ val : %d\n", val);
err = m9mo_writeb(sd, M9MO_CATEGORY_AE,
M9MO_AE_AUTO_BRACKET_EV, 0xA0); /* EV 1.6 */
+ CHECK_ERR(err);
break;
case BRACKET_AEB_VALUE6:
- cam_trace("~~~~~~ AEB value6 ~~~~~~ val : %d\n", val);
+ cam_dbg("~~~~~~ AEB value6 ~~~~~~ val : %d\n", val);
err = m9mo_writeb(sd, M9MO_CATEGORY_AE,
M9MO_AE_AUTO_BRACKET_EV, 0xC8); /* EV 2.0 */
+ CHECK_ERR(err);
break;
default:
cam_err("~~~~ TBD ~~~~ val : %d", val);
err = m9mo_writeb(sd, M9MO_CATEGORY_AE,
M9MO_AE_AUTO_BRACKET_EV, 0x64); /* Ev 1.0 */
+ CHECK_ERR(err);
break;
}
cam_trace("X\n");
@@ -2727,31 +4805,108 @@ static int m9mo_set_bracket_aeb(struct v4l2_subdev *sd, int val)
static int m9mo_set_bracket_wbb(struct v4l2_subdev *sd, int val)
{
+ struct m9mo_state *state = to_state(sd);
+ int err;
cam_trace("E val : %d\n", val);
switch (val) {
case BRACKET_WBB_VALUE1:
- cam_trace("~~~~~~ WBB value1 ~~~~~~ val : %d\n", val);
+ cam_trace("~~~~~~ WBB value1 AB 3~~~~~~ val : %d\n", val);
+ err = m9mo_writeb(sd, M9MO_CATEGORY_WB,
+ M9MO_WB_WBB_MODE, 0x01);
+ CHECK_ERR(err);
+ err = m9mo_writeb(sd, M9MO_CATEGORY_WB,
+ M9MO_WB_WBB_AB, 0x30);
+ CHECK_ERR(err);
break;
case BRACKET_WBB_VALUE2:
- cam_trace("~~~~~~ WBB value2 ~~~~~~ val : %d\n", val);
+ cam_trace("~~~~~~ WBB value2 AB 2~~~~~~ val : %d\n", val);
+ err = m9mo_writeb(sd, M9MO_CATEGORY_WB,
+ M9MO_WB_WBB_MODE, 0x01);
+ CHECK_ERR(err);
+ err = m9mo_writeb(sd, M9MO_CATEGORY_WB,
+ M9MO_WB_WBB_AB, 0x20);
+ CHECK_ERR(err);
break;
case BRACKET_WBB_VALUE3:
- cam_trace("~~~~~~ WBB value3 ~~~~~~ val : %d\n", val);
+ cam_trace("~~~~~~ WBB value3 AB 1~~~~~~ val : %d\n", val);
+ err = m9mo_writeb(sd, M9MO_CATEGORY_WB,
+ M9MO_WB_WBB_MODE, 0x01);
+ CHECK_ERR(err);
+ err = m9mo_writeb(sd, M9MO_CATEGORY_WB,
+ M9MO_WB_WBB_AB, 0x0F);
+ CHECK_ERR(err);
break;
case BRACKET_WBB_VALUE4:
- cam_trace("~~~~~~ WBB value4 ~~~~~~ val : %d\n", val);
+ cam_trace("~~~~~~ WBB value4 GM 3~~~~~~ val : %d\n", val);
+ err = m9mo_writeb(sd, M9MO_CATEGORY_WB,
+ M9MO_WB_WBB_MODE, 0x02);
+ CHECK_ERR(err);
+ err = m9mo_writeb(sd, M9MO_CATEGORY_WB,
+ M9MO_WB_WBB_GM, 0x30);
+ CHECK_ERR(err);
break;
case BRACKET_WBB_VALUE5:
- cam_trace("~~~~~~ WBB value5 ~~~~~~ val : %d\n", val);
+ cam_trace("~~~~~~ WBB value5 GM 2~~~~~~ val : %d\n", val);
+ err = m9mo_writeb(sd, M9MO_CATEGORY_WB,
+ M9MO_WB_WBB_MODE, 0x02);
+ CHECK_ERR(err);
+ err = m9mo_writeb(sd, M9MO_CATEGORY_WB,
+ M9MO_WB_WBB_GM, 0x20);
+ CHECK_ERR(err);
break;
case BRACKET_WBB_VALUE6:
- cam_trace("~~~~~~ WBB value6 ~~~~~~ val : %d\n", val);
+ cam_trace("~~~~~~ WBB value6 GM 1~~~~~~ val : %d\n", val);
+ err = m9mo_writeb(sd, M9MO_CATEGORY_WB,
+ M9MO_WB_WBB_MODE, 0x02);
+ CHECK_ERR(err);
+ err = m9mo_writeb(sd, M9MO_CATEGORY_WB,
+ M9MO_WB_WBB_GM, 0x0F);
+ CHECK_ERR(err);
+ break;
+
+ case BRACKET_WBB_OFF:
+ cam_trace("~~~~~~ WBB Off ~~~~~~\n");
+ err = m9mo_writeb(sd, M9MO_CATEGORY_WB,
+ M9MO_WB_WBB_MODE, 0x00);
+ CHECK_ERR(err);
+ break;
+
+ default:
+ val = 0xFF;
+ cam_err("~~~~ TBD ~~~~ val : %d", val);
+ break;
+ }
+
+ if (val != 0xFF)
+ state->bracket_wbb_val = val;
+
+ cam_trace("X\n");
+ return 0;
+}
+
+static int m9mo_set_bracket(struct v4l2_subdev *sd, int val)
+{
+ struct m9mo_state *state = to_state(sd);
+ cam_trace("E val : %d\n", val);
+
+ switch (val) {
+ case BRACKET_MODE_OFF:
+ case BRACKET_MODE_AEB:
+ cam_dbg("~~~~~~ bracket aeb on ~~~~~~ val : %d\n", val);
+ m9mo_set_bracket_wbb(sd, BRACKET_WBB_OFF);
+ break;
+
+ case BRACKET_MODE_WBB:
+ cam_dbg("~~~~~~ bracket wbb on ~~~~~~ val : %d\n", val);
+ if (state->bracket_wbb_val == BRACKET_WBB_OFF)
+ state->bracket_wbb_val = BRACKET_WBB_VALUE3;
+ m9mo_set_bracket_wbb(sd, state->bracket_wbb_val);
break;
default:
@@ -2762,148 +4917,2140 @@ static int m9mo_set_bracket_wbb(struct v4l2_subdev *sd, int val)
return 0;
}
+static int m9mo_set_factory_cam_sys_mode(struct v4l2_subdev *sd, int val)
+{
+ int old_mode;
+
+ cam_trace("E val : %d\n", val);
+
+ switch (val) {
+ case FACTORY_SYSMODE_CAPTURE:
+ cam_trace("~ FACTORY_SYSMODE_CAPTURE ~\n");
+ old_mode = m9mo_set_mode(sd, M9MO_STILLCAP_MODE);
+ break;
+
+ case FACTORY_SYSMODE_MONITOR:
+ break;
+
+ case FACTORY_SYSMODE_PARAM:
+ cam_trace("~ FACTORY_SYSMODE_PARAM ~\n");
+ old_mode = m9mo_set_mode(sd, M9MO_PARMSET_MODE);
+ break;
+
+ default:
+ cam_trace("~ FACTORY_SYSMODE_DEFAULT ~\n");
+ break;
+ }
+ cam_trace("X\n");
+ return 0;
+
+}
+
static int m9mo_set_fps(struct v4l2_subdev *sd, int val)
{
- int err, old_mode;
- u32 int_factor;
+ int err;
struct m9mo_state *state = to_state(sd);
cam_trace("E val : %d\n", val);
- if (state->preview == NULL) {
- cam_trace("~~~~~~ return ~~~~~~\n");
+ if (val == state->fps) {
+ cam_info("same fps. skip\n");
return 0;
}
+ if (val <= 0 || val > 120) {
+ cam_err("invalid frame rate %d\n", val);
+ val = 0; /* set to auto(default) */
+ }
+
+ cam_info("set AE EP to %d\n", val);
switch (val) {
+ case 120:
+ cam_trace("~~~~~~ 120 fps ~~~~~~\n");
+ err = m9mo_writeb(sd, M9MO_CATEGORY_AE,
+ M9MO_AE_EP_MODE_MON, 0x1C);
+ CHECK_ERR(err);
+ err = m9mo_writeb(sd, M9MO_CATEGORY_AE,
+ M9MO_AE_EP_MODE_CAP, 0x1C);
+ CHECK_ERR(err);
+ break;
+
+ case 60:
+ cam_trace("~~~~~~ 60 fps ~~~~~~\n");
+ err = m9mo_writeb(sd, M9MO_CATEGORY_AE,
+ M9MO_AE_EP_MODE_MON, 0x1A);
+ CHECK_ERR(err);
+ err = m9mo_writeb(sd, M9MO_CATEGORY_AE,
+ M9MO_AE_EP_MODE_CAP, 0x1A);
+ CHECK_ERR(err);
+ break;
+
case 30:
cam_trace("~~~~~~ 30 fps ~~~~~~\n");
+ err = m9mo_writeb(sd, M9MO_CATEGORY_AE,
+ M9MO_AE_EP_MODE_MON, 0x19);
+ CHECK_ERR(err);
+ err = m9mo_writeb(sd, M9MO_CATEGORY_AE,
+ M9MO_AE_EP_MODE_CAP, 0x19);
+ CHECK_ERR(err);
+ break;
- old_mode = m9mo_set_mode(sd, M9MO_PARMSET_MODE);
- CHECK_ERR(old_mode);
+ default:
+ cam_trace("~~~~~~ default : auto fps ~~~~~~\n");
+ err = m9mo_writeb(sd, M9MO_CATEGORY_AE,
+ M9MO_AE_EP_MODE_MON, 0x00);
+ CHECK_ERR(err);
+ err = m9mo_writeb(sd, M9MO_CATEGORY_AE,
+ M9MO_AE_EP_MODE_CAP, 0x00);
+ CHECK_ERR(err);
+ break;
+ }
+
+ state->fps = val;
+
+ cam_trace("X\n");
+ return 0;
+}
+
+static int m9mo_set_time_info(struct v4l2_subdev *sd, int val)
+{
+ int err;
+#if 0
+ int read_hour, read_min;
+#endif
+
+ cam_trace("E val : %x\n", val);
+
+ err = m9mo_writew(sd, M9MO_CATEGORY_NEW,
+ M9MO_NEW_TIME_INFO, val);
+ CHECK_ERR(err);
+
+#if 0 /* for check time */
+ err = m9mo_readb(sd, M9MO_CATEGORY_NEW,
+ M9MO_NEW_TIME_INFO, &read_hour);
+ CHECK_ERR(err);
+
+ err = m9mo_readb(sd, M9MO_CATEGORY_NEW,
+ M9MO_NEW_TIME_INFO+1, &read_min);
+ CHECK_ERR(err);
+
+ cam_dbg("time %02d:%02d\n", read_hour, read_min);
+#endif
+
+ cam_trace("X\n");
+ return 0;
+}
+
+static int m9mo_set_lens_off_timer(struct v4l2_subdev *sd, int val)
+{
+ int err;
+
+ cam_trace("E val : %x\n", val);
+
+ if (val > 0xFF) {
+ cam_warn("Can not set over 0xFF, but set 0x%x", val);
+ val = 0xFF;
+ }
+
+ err = m9mo_writeb2(sd, M9MO_CATEGORY_SYS,
+ M9MO_SYS_LENS_TIMER, val);
+ CHECK_ERR(err);
+
+ cam_trace("X\n");
+ return 0;
+}
+
+static int m9mo_set_widget_mode_level(struct v4l2_subdev *sd, int val)
+{
+ struct m9mo_state *state = to_state(sd);
+ int err;
+
+ /* valid values are 0, 2, 4 */
+ state->widget_mode_level = val * 2 - 2;
+
+ /* LIKE A PRO STEP SET */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_PRO_MODE,
+ 0x02, state->widget_mode_level);
+ CHECK_ERR(err);
+
+ if (state->mode == MODE_SILHOUETTE) {
+ /* GAMMA_TBL_RGB_CAP */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_CAPPARM,
+ 0x42, 0x0D + state->widget_mode_level);
+ CHECK_ERR(err);
+
+ /* change to PARAM mode */
+ err = m9mo_set_mode(sd, M9MO_PARMSET_MODE);
+ CHECK_ERR(err);
+
+ /* GAMMA_TBL_RGB_MON */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_PARM,
+ 0x31, 0x0D + state->widget_mode_level);
+ CHECK_ERR(err);
+
+ /* change to MON mode */
+ m9mo_set_mode(sd, M9MO_MONITOR_MODE);
+ err = m9mo_wait_interrupt(sd, M9MO_ISP_TIMEOUT);
+ if (!(err & M9MO_INT_MODE)) {
+ cam_err("M9MO_INT_MODE isn't issued!!!\n");
+ return -ETIMEDOUT;
+ }
+ } else if (state->mode == MODE_BLUE_SKY) {
+ /* COLOR EFFECT SET */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_MON,
+ M9MO_MON_COLOR_EFFECT, 0x11 + state->widget_mode_level);
+ CHECK_ERR(err);
+ } else if (state->mode == MODE_NATURAL_GREEN) {
+ /* COLOR EFFECT SET */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_MON,
+ M9MO_MON_COLOR_EFFECT, 0x21 + state->widget_mode_level);
+ CHECK_ERR(err);
+ }
+
+ cam_dbg("X %d %d\n", val, state->mode);
+ return 0;
+}
+
+static int m9mo_set_LDC(struct v4l2_subdev *sd, int val)
+{
+ int err;
+
+ cam_dbg("%s\n", val ? "on" : "off");
+
+ if (val == 1) {
+ err = m9mo_writeb(sd, M9MO_CATEGORY_PARM,
+ 0x1B, 0x01);
+ CHECK_ERR(err);
+ } else {
+ err = m9mo_writeb(sd, M9MO_CATEGORY_PARM,
+ 0x1B, 0x00);
+ CHECK_ERR(err);
+ }
+
+ cam_trace("X\n");
+ return 0;
+}
+
+static int m9mo_set_LSC(struct v4l2_subdev *sd, int val)
+{
+ int err;
+
+ cam_dbg("%s\n", val ? "on" : "off");
+
+ if (val == 1) {
+ err = m9mo_writeb(sd, M9MO_CATEGORY_PARM,
+ 0x07, 0x01);
+ CHECK_ERR(err);
+ } else {
+ err = m9mo_writeb(sd, M9MO_CATEGORY_PARM,
+ 0x07, 0x00);
+ CHECK_ERR(err);
+ }
+
+ cam_trace("X\n");
+ return 0;
+}
+
+static int m9mo_set_aperture_preview(struct v4l2_subdev *sd, int val)
+{
+ int err, temp, i;
+ unsigned char convert = 0x00;
+
+ cam_trace("E val : %d\n", val);
+
+ if (val < 28)
+ val = 28;
+
+ temp = val / 10;
+
+ for (i = 0; i < temp; i++)
+ convert += 0x10;
+
+ temp = val % 10;
+ convert += temp;
+
+ cam_trace("check val : %d\n", convert);
+ err = m9mo_writeb(sd, M9MO_CATEGORY_AE, 0x3D, convert);
+
+ CHECK_ERR(err);
+ cam_trace("X\n");
+ return 0;
+}
+
+static int m9mo_set_aperture_capture(struct v4l2_subdev *sd, int val)
+{
+ int err, temp, i;
+ unsigned char convert = 0x00;
+
+ cam_trace("E val : %d\n", val);
+
+ if (val < 28)
+ val = 28;
+
+ temp = val / 10;
+
+ for (i = 0; i < temp; i++)
+ convert += 0x10;
+
+ temp = val % 10;
+ convert += temp;
+
+ cam_trace("check val : %d\n", convert);
+ err = m9mo_writeb(sd, M9MO_CATEGORY_AE,
+ 0x36, convert);
+ CHECK_ERR(err);
+ cam_trace("X\n");
+ return 0;
+}
+
+static int m9mo_set_factory_OIS(struct v4l2_subdev *sd, int val)
+{
+ int err;
+
+ cam_trace("E val : %d\n", val);
+
+ switch (val) {
+ case FACTORY_OIS_RETURN_TO_CENTER:
+ cam_trace("~ FACTORY_OIS_RETURN_TO_CENTER ~\n");
+ err = m9mo_writeb(sd, M9MO_CATEGORY_NEW,
+ 0x15, 0x30);
+ CHECK_ERR(err);
+ err = m9mo_writeb(sd, M9MO_CATEGORY_NEW,
+ 0x16, 0x11);
+ CHECK_ERR(err);
+ break;
+
+ case FACTORY_OIS_RUN:
+ cam_trace("~ FACTORY_OIS_RUN ~\n");
+ err = m9mo_writeb(sd, M9MO_CATEGORY_NEW,
+ 0x11, 0x01);
+ CHECK_ERR(err);
+ break;
+
+ case FACTORY_OIS_START:
+ cam_trace("~ FACTORY_OIS_START ~\n");
+ err = m9mo_writeb(sd, M9MO_CATEGORY_NEW,
+ 0x20, 0x01);
+ CHECK_ERR(err);
+ break;
+
+ case FACTORY_OIS_STOP:
+ cam_trace("~ FACTORY_OIS_STOP ~\n");
+ break;
+
+ case FACTORY_OIS_MODE_ON:
+ err = m9mo_writeb(sd, M9MO_CATEGORY_NEW,
+ 0x11, 0x02);
+ CHECK_ERR(err);
+ cam_trace("~ FACTORY_OIS_MODE_ON ~\n");
+ break;
+
+ case FACTORY_OIS_MODE_OFF:
+ err = m9mo_writeb(sd, M9MO_CATEGORY_NEW,
+ 0x10, 0x00);
+ cam_trace("~ FACTORY_OIS_MODE_OFF ~\n");
+ break;
+ case FACTORY_OIS_LOG:
+ err = m9mo_writeb(sd, M9MO_CATEGORY_NEW,
+ 0x19, 0x01);
+ CHECK_ERR(err);
+ msleep(40);
+ err = m9mo_make_CSV_rawdata(sd, M9MO_FLASH_FACTORY_OIS, false);
+ CHECK_ERR(err);
+ cam_trace("~FACTORY_OIS_LOG ~\n");
+ break;
+
+ case FACTORY_OIS_ON:
+ err = m9mo_writeb(sd, M9MO_CATEGORY_NEW,
+ 0x11, 0x02);
+ CHECK_ERR(err);
+ break;
+
+ default:
+ cam_err("~ m9mo_set_factory_OIS ~ val : %d", val);
+ break;
+ }
+
+ cam_trace("X\n");
+ return 0;
+}
+
+static int m9mo_set_factory_OIS_shift(struct v4l2_subdev *sd, int val)
+{
+ int err;
+ cam_trace("E val : 0x%x\n", val);
+ err = m9mo_writew(sd, M9MO_CATEGORY_AE,
+ 0x15, val);
+ CHECK_ERR(err);
+ err = m9mo_writew(sd, M9MO_CATEGORY_AE,
+ 0x14, 0);
+ CHECK_ERR(err);
+ cam_trace("X\n");
+ return 0;
+}
+
+static int m9mo_set_factory_punt(struct v4l2_subdev *sd, int val)
+{
+ int err;
+ struct m9mo_state *state = to_state(sd);
+
+ cam_trace("E val : %d\n", val);
+
+ switch (val) {
+ case FACTORY_PUNT_RANGE_START:
+ cam_trace("~ FACTORY_PUNT_RANGE_START ~\n");
+ err = m9mo_writeb(sd, M9MO_CATEGORY_LENS,
+ 0x0E, 0x00);
+ CHECK_ERR(err);
+ break;
+
+ case FACTORY_PUNT_RANGE_STOP:
+ cam_trace("~ FACTORY_PUNT_RANGE_STOP ~\n");
+ break;
+
+ case FACTORY_PUNT_SHORT_SCAN_DATA:
+ cam_trace("~ FACTORY_PUNT_SHORT_SCAN_DATA ~\n");
+ err = m9mo_writeb(sd, M9MO_CATEGORY_LENS,
+ 0x1B, 0x00);
+ CHECK_ERR(err);
+ break;
+
+ case FACTORY_PUNT_SHORT_SCAN_START:
+ cam_trace("~ FACTORY_PUNT_SHORT_SCAN_START ~\n");
+ err = m9mo_writeb(sd, M9MO_CATEGORY_LENS,
+ 0x0E, 0x01);
+ CHECK_ERR(err);
+ break;
+
+ case FACTORY_PUNT_SHORT_SCAN_STOP:
+ cam_trace("~ FACTORY_PUNT_SHORT_SCAN_STOP ~\n");
+ break;
+
+ case FACTORY_PUNT_LONG_SCAN_DATA:
+ cam_trace("~ FACTORY_PUNT_LONG_SCAN_DATA ~\n");
+ err = m9mo_writeb(sd, M9MO_CATEGORY_LENS,
+ 0x1B, 0x00);
+ CHECK_ERR(err);
+ break;
+
+ case FACTORY_PUNT_LONG_SCAN_START:
+ cam_trace("~ FACTORY_PUNT_LONG_SCAN_START ~\n");
+ err = m9mo_writeb(sd, M9MO_CATEGORY_LENS,
+ 0x0E, 0x02);
+ CHECK_ERR(err);
+ break;
+
+ case FACTORY_PUNT_LONG_SCAN_STOP:
+ cam_trace("~FACTORY_PUNT_LONG_SCAN_STOP ~\n");
+ break;
+
+ case FACTORY_PUNT_LOG:
+ err = m9mo_writeb(sd, M9MO_CATEGORY_LENS,
+ 0x0E, 0x04);
+ CHECK_ERR(err);
+ msleep(40);
+ err = m9mo_make_CSV_rawdata(sd, M9MO_FLASH_FACTORY_PUNT, false);
+ CHECK_ERR(err);
+ cam_trace("~FACTORY_PUNT_LOG ~\n");
+ break;
+
+ case FACTORY_PUNT_SET_RANGE_DATA:
+ cam_trace("~FACTORY_PUNT_SET_RANGE_DATA ~\n");
+ err = m9mo_writew(sd, M9MO_CATEGORY_LENS,
+ 0x17, (unsigned short)(state->f_punt_data.min));
+ CHECK_ERR(err);
+
+ err = m9mo_writew(sd, M9MO_CATEGORY_LENS,
+ 0x19, (unsigned short)(state->f_punt_data.max));
+ CHECK_ERR(err);
+
+ err = m9mo_writeb(sd, M9MO_CATEGORY_LENS,
+ 0x1B, (unsigned char)(state->f_punt_data.num));
+ CHECK_ERR(err);
+
+ cam_trace("~ FACTORY_PUNT_RANGE_START ~\n");
+ err = m9mo_writeb(sd, M9MO_CATEGORY_LENS,
+ 0x0E, 0x00);
+ CHECK_ERR(err);
+ break;
+
+ case FACTORY_PUNT_EEP_WRITE:
+ err = m9mo_writeb(sd, M9MO_CATEGORY_LENS,
+ 0x0E, 0x05);
+ CHECK_ERR(err);
+ break;
+
+ default:
+ cam_err("~ m9mo_set_factory_punt ~ val : %d", val);
+ break;
+ }
+
+ cam_trace("X\n");
+ return 0;
+}
+
+static int m9mo_set_factory_zoom(struct v4l2_subdev *sd, int val)
+{
+ int err;
+ int end_check = 0;
+ struct m9mo_state *state = to_state(sd);
+
+ cam_trace("E val : %d\n", val);
+
+ switch (val) {
+ case FACTORY_ZOOM_MOVE_STEP:
+ cam_trace("~ FACTORY_ZOOM_MOVE_STEP ~\n");
+ err = m9mo_writeb(sd, M9MO_CATEGORY_LENS,
+ 0x0F, 0x00);
+ CHECK_ERR(err);
+ break;
+
+ case FACTORY_ZOOM_RANGE_CHECK_START:
+ cam_trace("~ FACTORY_ZOOM_RANGE_CHECK_START ~\n");
+ err = m9mo_writeb(sd, M9MO_CATEGORY_LENS,
+ 0x0F, 0x05);
+ CHECK_ERR(err);
+ break;
+
+ case FACTORY_ZOOM_RANGE_CHECK_STOP:
+ cam_trace("~ FACTORY_ZOOM_RANGE_CHECK_STOP ~\n");
+ break;
+
+ case FACTORY_ZOOM_SLOPE_CHECK_START:
+ cam_trace("~ FACTORY_ZOOM_SLOPE_CHECK_START ~\n");
+ err = m9mo_writeb(sd, M9MO_CATEGORY_LENS,
+ 0x0E, 0x03);
+ CHECK_ERR(err);
+ break;
+
+ case FACTORY_ZOOM_SLOPE_CHECK_STOP:
+ cam_trace("~ FACTORY_ZOOM_SLOPE_CHECK_STOP ~\n");
+ break;
+
+ case FACTORY_ZOOM_SET_RANGE_CHECK_DATA:
+ cam_trace("~ FACTORY_ZOOM_SET_RANGE_CHECK_DATA ~\n");
+ err = m9mo_writew(sd, M9MO_CATEGORY_LENS,
+ 0x18, (unsigned short)(state->f_zoom_data.range_min));
+ CHECK_ERR(err);
+
+ err = m9mo_writew(sd, M9MO_CATEGORY_LENS,
+ 0x1A, (unsigned short)(state->f_zoom_data.range_max));
+ CHECK_ERR(err);
+ break;
+
+ case FACTORY_ZOOM_SET_SLOPE_CHECK_DATA:
+ cam_trace("~ FACTORY_ZOOM_SET_SLOPE_CHECK_DATA ~\n");
+ err = m9mo_writew(sd, M9MO_CATEGORY_LENS,
+ 0x18, (unsigned short)(state->f_zoom_data.slope_min));
+ CHECK_ERR(err);
+
+ err = m9mo_writew(sd, M9MO_CATEGORY_LENS,
+ 0x1A, (unsigned short)(state->f_zoom_data.slope_max));
+ CHECK_ERR(err);
+ break;
+
+ case FACTORY_ZOOM_STEP_TELE:
+ cam_trace("~ FACTORY_ZOOM_STEP_TELE ~\n");
+ err = m9mo_writew(sd, M9MO_CATEGORY_LENS,
+ 0x1A, 0x0F);
+ CHECK_ERR(err);
+ break;
+
+ case FACTORY_ZOOM_STEP_WIDE:
+ cam_trace("~ FACTORY_ZOOM_STEP_WIDE ~\n");
+ err = m9mo_writew(sd, M9MO_CATEGORY_LENS,
+ 0x1A, 0x00);
+ CHECK_ERR(err);
+ break;
+
+ case FACTORY_ZOOM_MOVE_END_CHECK:
+ err = m9mo_readb(sd, M9MO_CATEGORY_LENS,
+ 0x26, &end_check);
+ CHECK_ERR(err);
+ state->factory_end_check = end_check;
+ cam_trace("~ FACTORY_ZOOM_MOVE_CHECK ~\n");
+ break;
+
+ default:
+ cam_err("~ m9mo_set_factory_zoom ~ val : %d", val);
+ break;
+ }
+
+ cam_trace("X\n");
+ return 0;
+}
+
+static int m9mo_set_factory_zoom_step(struct v4l2_subdev *sd, int val)
+{
+ int err;
+
+ cam_trace("E val : %d\n", val);
+#if 1
+ if (val >= 0 && val < 16) {
+ err = m9mo_writeb(sd, M9MO_CATEGORY_LENS,
+ 0x1A, val);
+ CHECK_ERR(err);
+ err = m9mo_writeb(sd, M9MO_CATEGORY_LENS,
+ 0x1B, 0x00);
+ CHECK_ERR(err);
+ }
+ cam_trace("~ FACTORY_ZOOM_MOVE_STEP ~\n");
+ err = m9mo_writeb(sd, M9MO_CATEGORY_LENS,
+ 0x0F, 0x00);
+ CHECK_ERR(err);
+#else
+ err = m9mo_writeb(sd, M9MO_CATEGORY_LENS,
+ 0x06, val);
+ CHECK_ERR(err);
+ msleep(500);
+#endif
+ return 0;
+}
+
+static int m9mo_set_factory_fail_stop(struct v4l2_subdev *sd, int val)
+{
+ int err;
+
+ cam_trace("E val : %d\n", val);
+
+ switch (val) {
+ case FACTORY_FAIL_STOP_ON:
+ cam_trace("~ FACTORY_FAIL_STOP_ON ~\n");
+ err = m9mo_writeb(sd, M9MO_CATEGORY_LENS,
+ 0x1B, 0x01);
+ CHECK_ERR(err);
+ break;
+
+ case FACTORY_FAIL_STOP_OFF:
+ cam_trace("~ FACTORY_FAIL_STOP_OFF ~\n");
+ break;
+
+ case FACTORY_FAIL_STOP_RUN:
+ err = m9mo_writeb(sd, M9MO_CATEGORY_LENS,
+ 0x0D, 0x0C);
+ CHECK_ERR(err);
+
+ cam_trace("~ FACTORY_FAIL_STOP_RUN ~\n");
+ break;
+
+ case FACTORY_FAIL_STOP_STOP:
+ cam_trace("~ FACTORY_FAIL_STOP_STOP ~\n");
+ break;
+
+ default:
+ cam_err("~ m9mo_set_factory_fail_stop ~ val : %d", val);
+ break;
+ }
+
+ cam_trace("X\n");
+ return 0;
+}
+
+static int m9mo_set_factory_nodefocus(struct v4l2_subdev *sd, int val)
+{
+ int err;
+
+ cam_trace("E val : %d\n", val);
+
+ switch (val) {
+ case FACTORY_NODEFOCUSYES_ON:
+ cam_trace("~ FACTORY_NODEFOCUSYES_ON ~\n");
+ err = m9mo_writeb(sd, M9MO_CATEGORY_LENS,
+ 0x1B, 0x01);
+ CHECK_ERR(err);
+ break;
+
+ case FACTORY_NODEFOCUSYES_OFF:
+ cam_trace("~ FACTORY_NODEFOCUSYES_OFF ~\n");
+ break;
+
+ case FACTORY_NODEFOCUSYES_RUN:
+ err = m9mo_writeb(sd, M9MO_CATEGORY_LENS,
+ 0x0D, 0x09);
+ CHECK_ERR(err);
+
+ cam_trace("~ FACTORY_NODEFOCUSYES_RUN ~\n");
+ break;
+
+ case FACTORY_NODEFOCUSYES_STOP:
+ cam_trace("~ FACTORY_NODEFOCUSYES_STOP ~\n");
+ break;
+
+ default:
+ cam_err("~ m9mo_set_factory_defocus ~ val : %d", val);
+ break;
+ }
+
+ cam_trace("X\n");
+ return 0;
+}
+
+static int m9mo_set_factory_interpolation(struct v4l2_subdev *sd, int val)
+{
+ int err;
+
+ cam_trace("E val : %d\n", val);
+
+ switch (val) {
+ case FACTORY_INTERPOLATION_USE:
+ cam_trace("~ FACTORY_INTERPOLATION_USE ~\n");
+ err = m9mo_writeb(sd, M9MO_CATEGORY_LENS,
+ 0x0E, 0x0A);
+ CHECK_ERR(err);
+ break;
+
+ case FACTORY_INTERPOLATION_RELEASE:
+ cam_trace("~ FACTORY_INTERPOLATION_RELEASE ~\n");
+ break;
+
+ default:
+ cam_err("~ m9mo_set_factory_interpolation ~ val : %d", val);
+ break;
+ }
+
+ cam_trace("X\n");
+ return 0;
+}
+
+static int m9mo_set_factory_common(struct v4l2_subdev *sd, int val)
+{
+ int err, down_check = 1, end_check = 0;
+ struct m9mo_state *state = to_state(sd);
+
+ cam_trace("E val : %d\n", val);
+
+ switch (val) {
+ case FACTORY_FIRMWARE_DOWNLOAD:
+ cam_trace("~ FACTORY_FIRMWARE_DOWNLOAD ~\n");
+ err = m9mo_writeb(sd, M9MO_CATEGORY_NEW,
+ 0x11, 0x00);
+ CHECK_ERR(err);
+ break;
+
+ case FACTORY_DOWNLOAD_CHECK:
+ cam_trace("~ FACTORY_DOWNLOAD_CHECK ~\n");
+ err = m9mo_readb(sd, M9MO_CATEGORY_NEW,
+ 0x11, &down_check);
+ CHECK_ERR(err);
+ state->factory_down_check = down_check;
+ break;
+
+ case FACTORY_END_CHECK:
+ cam_trace("~ FACTORY_END_CHECK ~\n");
+ err = m9mo_readb(sd, M9MO_CATEGORY_LENS,
+ 0x40, &end_check);
+ CHECK_ERR(err);
+ state->factory_end_check = end_check;
+ break;
+
+ case FACTORY_COMMON_SET_FOCUS_ZONE_MACRO:
+ cam_trace("~ FACTORY_COMMON_SET_FOCUS_ZONE_MACRO ~\n");
+ err = m9mo_writeb(sd, M9MO_CATEGORY_LENS,
+ 0x07, 0x02);
+ CHECK_ERR(err);
+ break;
+
+ case FACTORY_FPS30_ON:
+ cam_trace("~ FACTORY_FPS30_ON ~\n");
+ err = m9mo_writeb(sd, M9MO_CATEGORY_LENS,
+ 0x3F, 0x01);
+ CHECK_ERR(err);
+ break;
+
+ case FACTORY_FPS30_OFF:
+ cam_trace("~ FACTORY_FPS30_OFF ~\n");
+ err = m9mo_writeb(sd, M9MO_CATEGORY_LENS,
+ 0x3F, 0x00);
+ CHECK_ERR(err);
+ break;
+
+ default:
+ cam_err("~ m9mo_set_factory_common ~ val : %d", val);
+ break;
+ }
+
+ cam_trace("X\n");
+ return 0;
+}
+
+static int m9mo_set_factory_vib(struct v4l2_subdev *sd, int val)
+{
+ int err;
+
+ cam_trace("m9mo_set_factory_vib E val : %d\n", val);
+
+ switch (val) {
+ case FACTORY_VIB_START:
+ cam_trace("~ FACTORY_VIB_START ~\n");
+ err = m9mo_writeb(sd, M9MO_CATEGORY_NEW,
+ 0x20, 0x02);
+ CHECK_ERR(err);
+ break;
+
+ case FACTORY_VIB_STOP:
+ cam_trace("~ FACTORY_VIB_STOP ~\n");
+ break;
+
+ case FACTORY_VIB_LOG:
+ err = m9mo_writeb(sd, M9MO_CATEGORY_NEW,
+ 0x19, 0x02);
+ CHECK_ERR(err);
+ msleep(40);
+ err = m9mo_make_CSV_rawdata(sd, M9MO_FLASH_FACTORY_VIB, false);
+ CHECK_ERR(err);
+ cam_trace("~FACTORY_VIB_LOG ~\n");
+ break;
+
+ default:
+ cam_err("~m9mo_set_factory_vib~ val : %d", val);
+ break;
+ }
+
+ cam_trace("X\n");
+ return 0;
+}
+
+static int m9mo_set_factory_gyro(struct v4l2_subdev *sd, int val)
+{
+ int err;
+
+ cam_trace("E val : %d\n", val);
+
+ switch (val) {
+ case FACTORY_GYRO_START:
+ cam_trace("~ FACTORY_GYRO_START ~\n");
+ err = m9mo_writeb(sd, M9MO_CATEGORY_NEW,
+ 0x20, 0x03);
+ CHECK_ERR(err);
+ break;
+
+ case FACTORY_GYRO_STOP:
+ cam_trace("~ FACTORY_GYRO_STOP ~\n");
+ break;
+
+ case FACTORY_GYRO_LOG:
+ err = m9mo_writeb(sd, M9MO_CATEGORY_NEW,
+ 0x19, 0x03);
+ CHECK_ERR(err);
+ msleep(40);
+ err = m9mo_make_CSV_rawdata(sd, M9MO_FLASH_FACTORY_GYRO, false);
+ CHECK_ERR(err);
+ cam_trace("~FACTORY_PUNT_LOG ~\n");
+ break;
+ default:
+ cam_err("~ m9mo_set_factory_gyro ~ val : %d", val);
+ break;
+ }
+
+ cam_trace("X\n");
+ return 0;
+}
+
+static int m9mo_set_factory_backlash(struct v4l2_subdev *sd, int val)
+{
+ int err;
+
+ cam_trace("E val : %d\n", val);
+
+ switch (val) {
+ case FACTORY_BACKLASH_INPUT:
+ cam_trace("~ FACTORY_BACKLASH_INPUT ~\n");
+ err = m9mo_writeb(sd, M9MO_CATEGORY_LENS,
+ 0x0A, 0x01);
+ CHECK_ERR(err);
+ break;
+
+ case FACTORY_BACKLASH_MAX_THR:
+ err = m9mo_writeb(sd, M9MO_CATEGORY_LENS,
+ 0x0A, 0x00);
+ CHECK_ERR(err);
+ cam_trace("~ FACTORY_BACKLASH_MAX_THR ~\n");
+ break;
+
+ case FACTORY_BACKLASH_WIDE_RUN:
+ err = m9mo_writeb(sd, M9MO_CATEGORY_LENS,
+ 0x0A, 0x03);
+ CHECK_ERR(err);
+ cam_trace("~ FACTORY_BACKLASH_WIDE_RUN ~\n");
+ break;
+
+ case FACTORY_BACKLASH_LOG:
+ err = m9mo_writeb(sd, M9MO_CATEGORY_LENS,
+ 0x0A, 0x05);
+ CHECK_ERR(err);
+ msleep(40);
+ err = m9mo_make_CSV_rawdata(sd,
+ M9MO_FLASH_FACTORY_BACKLASH, false);
+ CHECK_ERR(err);
+ cam_trace("~FACTORY_BACKLASH_LOG ~\n");
+ break;
+
+ default:
+ cam_err("~ m9mo_set_factory_backlash ~ val : %d", val);
+ break;
+ }
+
+ cam_trace("X\n");
+ return 0;
+}
+
+static int m9mo_set_factory_backlash_count(struct v4l2_subdev *sd, int val)
+{
+ int err;
+
+ cam_trace("E val : %d\n", val);
+
+ err = m9mo_writeb(sd, M9MO_CATEGORY_LENS,
+ 0x1B, val);
+ CHECK_ERR(err);
+
+ cam_trace("X\n");
+ return 0;
+}
- if (state->preview->height == 480) {
- err = m9mo_writeb(sd, M9MO_CATEGORY_PARM,
- M9MO_PARM_MON_SIZE, 0x17);
+static int m9mo_set_factory_af(struct v4l2_subdev *sd, int val)
+{
+ int err, end_check = 0;
+ int result_check = 0;
+ struct m9mo_state *state = to_state(sd);
+
+ cam_trace("E val : %d\n", val);
+
+ switch (val) {
+ case FACTORY_AF_LOCK_ON_SET:
+ cam_trace("~ FACTORY_AF_LOCK_ON_SET ~\n");
+ err = m9mo_writeb(sd, M9MO_CATEGORY_LENS,
+ 0x1B, 0x01);
+ CHECK_ERR(err);
+ break;
+
+ case FACTORY_AF_LOCK_OFF_SET:
+ err = m9mo_writeb(sd, M9MO_CATEGORY_LENS,
+ 0x1B, 0x00);
+ CHECK_ERR(err);
+ cam_trace("~ FACTORY_AF_LOCK_OFF_SET ~\n");
+ break;
+
+ case FACTORY_AF_MOVE:
+ cam_trace("~ FACTORY_AF_MOVE ~\n");
+ break;
+
+ case FACTORY_AF_STEP_LOG:
+ if (state->factory_test_num == 106) {
+ cam_trace("~ FACTORY_AF_STEP_LOG WIDE ~\n");
+ err = m9mo_writeb(sd, M9MO_CATEGORY_LENS,
+ 0x0D, 0x1A);
+ CHECK_ERR(err);
+ msleep(40);
+ err = m9mo_make_CSV_rawdata(sd,
+ M9MO_FLASH_FACTORY_WIDE_RESOL, false);
CHECK_ERR(err);
- } else if (state->preview->height == 720) {
- err = m9mo_writeb(sd, M9MO_CATEGORY_PARM,
- M9MO_PARM_MON_SIZE, 0x21);
+ } else if (state->factory_test_num == 107) {
+ cam_trace("~ FACTORY_AF_STEP_LOG TELE ~\n");
+ err = m9mo_writeb(sd, M9MO_CATEGORY_LENS,
+ 0x0D, 0x19);
CHECK_ERR(err);
+ msleep(40);
+ err = m9mo_make_CSV_rawdata(sd,
+ M9MO_FLASH_FACTORY_TELE_RESOL, false);
+ CHECK_ERR(err);
+ } else {
+ cam_trace("~ FACTORY NUMBER ERROR ~\n");
}
+ break;
- if (old_mode == M9MO_MONITOR_MODE) {
- err = m9mo_set_mode(sd, old_mode);
- CHECK_ERR(err);
+ case FACTORY_AF_LOCK_START:
+ err = m9mo_writeb(sd, M9MO_CATEGORY_LENS,
+ 0x0D, 0x01);
+ CHECK_ERR(err);
+ cam_trace("~ FACTORY_AF_LOCK_START ~\n");
+ break;
+
+ case FACTORY_AF_LOCK_STOP:
+ cam_trace("~ FACTORY_AF_LOCK_STOP ~\n");
+ break;
+
+ case FACTORY_AF_FOCUS_LOG:
+ err = m9mo_writeb(sd, M9MO_CATEGORY_LENS,
+ 0x0D, 0x0B);
+ CHECK_ERR(err);
+ msleep(40);
+ err = m9mo_make_CSV_rawdata(sd,
+ M9MO_FLASH_FACTORY_AF_FCS, false);
+ CHECK_ERR(err);
+
+ cam_trace("~ FACTORY_AF_FOCUS_LOG ~\n");
+ break;
+
+ case FACTORY_AF_INT_SET:
+ cam_trace("~ FACTORY_AF_INT_SET ~\n");
+ err = m9mo_readw(sd, M9MO_CATEGORY_LENS,
+ 0x23, &result_check);
+ CHECK_ERR(err);
+ state->factory_result_check = result_check;
+ break;
+
+ case FACTORY_AF_STEP_SAVE:
+ err = m9mo_writeb(sd, M9MO_CATEGORY_LENS,
+ 0x0D, 0x0A);
+ CHECK_ERR(err);
+ cam_trace("~ FACTORY_AF_SETP_SAVE ~\n");
+ break;
+
+ case FACTORY_AF_SCAN_LIMIT_START:
+ err = m9mo_writeb(sd, M9MO_CATEGORY_LENS,
+ 0x0D, 0x06);
+ CHECK_ERR(err);
+ cam_trace("~ FACTORY_AF_SCAN_LIMIT_START ~\n");
+ break;
+
+ case FACTORY_AF_SCAN_LIMIT_STOP:
+ cam_trace("~ FACTORY_AF_SCAN_LIMIT_STOP ~\n");
+ break;
+
+ case FACTORY_AF_SCAN_RANGE_START:
+ err = m9mo_writeb(sd, M9MO_CATEGORY_LENS,
+ 0x0D, 0x07);
+ CHECK_ERR(err);
+ cam_trace("~ FACTORY_AF_SCAN_RANGE_START ~\n");
+ break;
+
+ case FACTORY_AF_SCAN_RANGE_STOP:
+ cam_trace("~ FACTORY_AF_SCAN_RANGE_STOP ~\n");
+ break;
+
+ case FACTORY_AF_LED_END_CHECK:
+ cam_trace("~ FACTORY_AF_LED_END_CHECK ~\n");
+ err = m9mo_readb(sd, M9MO_CATEGORY_LENS,
+ 0x40, &end_check);
+ CHECK_ERR(err);
+ state->factory_end_check = end_check;
+ break;
+
+ case FACTORY_AF_LED_LOG:
+ err = m9mo_writeb(sd, M9MO_CATEGORY_LENS,
+ 0x4D, 0x02);
+ CHECK_ERR(err);
+ msleep(40);
+ err = m9mo_make_CSV_rawdata(sd,
+ M9MO_FLASH_FACTORY_AF_LED, false);
+ CHECK_ERR(err);
+
+ cam_trace("~ FACTORY_AF_LED_LOG ~\n");
+ break;
+
+ case FACTORY_AF_MOVE_END_CHECK:
+ cam_trace("~ FACTORY_AF_MOVE_END_CHECK ~\n");
+ err = m9mo_readw(sd, M9MO_CATEGORY_LENS,
+ 0x29, &end_check);
+ CHECK_ERR(err);
+ state->factory_end_check = end_check;
+ break;
+
+ case FACTORY_AF_SCAN_END_CHECK:
+ cam_trace("~ FACTORY_AF_SCAN_END_CHECK ~\n");
+ err = m9mo_readw(sd, M9MO_CATEGORY_LENS,
+ 0x20, &end_check);
+ CHECK_ERR(err);
+ state->factory_end_check = end_check;
+ break;
+
+ default:
+ cam_err("~ m9mo_set_factory_af ~ val : %d", val);
+ break;
+ }
+
+ cam_trace("X\n");
+ return 0;
+}
+
+static int m9mo_set_factory_af_step(struct v4l2_subdev *sd, int val)
+{
+ int err;
+
+ cam_trace("E val : %d\n", val);
+
+ err = m9mo_writew(sd, M9MO_CATEGORY_LENS,
+ 0x1A, val);
+ CHECK_ERR(err);
+
+ cam_trace("X\n");
+ return 0;
+}
+
+static int m9mo_set_factory_af_position(struct v4l2_subdev *sd, int val)
+{
+ int err;
+
+ cam_trace("E val : %d\n", val);
+
+ err = m9mo_writeb(sd, M9MO_CATEGORY_LENS,
+ 0x0B, val);
+ CHECK_ERR(err);
+
+ cam_trace("X\n");
+ return 0;
+}
+
+static int m9mo_set_factory_defocus(struct v4l2_subdev *sd, int val)
+{
+ int err;
+
+ cam_trace("E val : %d\n", val);
+
+ switch (val) {
+ case FACTORY_DEFOCUS_RUN:
+ cam_trace("~ FACTORY_DEFOCUS_RUN ~\n");
+ err = m9mo_writeb(sd, M9MO_CATEGORY_LENS,
+ 0x0D, 0x18);
+ CHECK_ERR(err);
+ break;
+
+ case FACTORY_DEFOCUS_STOP:
+ cam_trace("~ FACTORY_DEFOCUS_STOP ~\n");
+ break;
+
+ default:
+ cam_err("~ m9mo_set_factory_defocus ~ val : %d", val);
+ break;
+ }
+
+ cam_trace("X\n");
+ return 0;
+}
+
+static int m9mo_set_factory_defocus_wide(struct v4l2_subdev *sd, int val)
+{
+ int err;
+
+ cam_trace("E val : %d\n", val);
+
+ err = m9mo_writeb(sd, M9MO_CATEGORY_LENS,
+ 0x1A, val);
+ CHECK_ERR(err);
+
+ cam_trace("X\n");
+ return 0;
+}
+
+static int m9mo_set_factory_defocus_tele(struct v4l2_subdev *sd, int val)
+{
+ int err;
+
+ cam_trace("E val : %d\n", val);
+
+ err = m9mo_writeb(sd, M9MO_CATEGORY_LENS,
+ 0x1B, val);
+ CHECK_ERR(err);
+
+ cam_trace("X\n");
+ return 0;
+}
+
+static int m9mo_set_factory_resol_cap(struct v4l2_subdev *sd, int val)
+{
+ int err;
+
+ cam_trace("E val : %d\n", val);
+
+ switch (val) {
+ case FACTORY_CAP_COMP_ON:
+ err = m9mo_writeb(sd, M9MO_CATEGORY_LENS,
+ 0x1B, 0x01);
+ CHECK_ERR(err);
+ cam_trace("~ FACTORY_CAP_COMP_ON ~\n");
+ break;
+
+ case FACTORY_CAP_COMP_OFF:
+ err = m9mo_writeb(sd, M9MO_CATEGORY_LENS,
+ 0x1B, 0x00);
+ CHECK_ERR(err);
+ cam_trace("~ FACTORY_CAP_COMP_OFF ~\n");
+ break;
+
+ case FACTORY_CAP_COMP_START:
+ err = m9mo_writeb(sd, M9MO_CATEGORY_LENS,
+ 0x0D, 0x04);
+ CHECK_ERR(err);
+ cam_trace("~ FACTORY_CAP_COMP_START ~\n");
+ break;
+
+ case FACTORY_CAP_COMP_STOP:
+ cam_trace("~ FACTORY_CAP_COMP_STOP ~\n");
+ break;
+
+ case FACTORY_CAP_BARREL_ON:
+ err = m9mo_writeb(sd, M9MO_CATEGORY_LENS,
+ 0x1B, 0x01);
+ CHECK_ERR(err);
+ cam_trace("~ FACTORY_CAP_BARREL_ON ~\n");
+ break;
+
+ case FACTORY_CAP_BARREL_OFF:
+ err = m9mo_writeb(sd, M9MO_CATEGORY_LENS,
+ 0x1B, 0x00);
+ CHECK_ERR(err);
+ cam_trace("~ FACTORY_CAP_BARREL_OFF ~\n");
+ break;
+
+ case FACTORY_CAP_BARREL_START:
+ err = m9mo_writeb(sd, M9MO_CATEGORY_LENS,
+ 0x0D, 0x05);
+ CHECK_ERR(err);
+ cam_trace("~ FACTORY_CAP_BARREL_START ~\n");
+ break;
+
+ case FACTORY_CAP_BARREL_STOP:
+ cam_trace("~ FACTORY_CAP_BARREL_STOP ~\n");
+ break;
+
+ default:
+ cam_err("~ m9mo_set_factory_resol_cap ~ val : %d", val);
+ break;
+ }
+
+ cam_trace("X\n");
+ return 0;
+}
+
+static int m9mo_set_factory_af_zone(struct v4l2_subdev *sd, int val)
+{
+ int err;
+
+ cam_trace("E val : %d\n", val);
+
+ switch (val) {
+ case FACTORY_AFZONE_NORMAL:
+ err = m9mo_writeb(sd, M9MO_CATEGORY_LENS,
+ 0x07, 0x00);
+ CHECK_ERR(err);
+ cam_trace("~ FACTORY_AFZONE_NORMAL ~\n");
+ break;
+
+ case FACTORY_AFZONE_MACRO:
+ err = m9mo_writeb(sd, M9MO_CATEGORY_LENS,
+ 0x07, 0x01);
+ CHECK_ERR(err);
+ cam_trace("~ FACTORY_AFZONE_MACRO ~\n");
+ break;
+
+ case FACTORY_AFZONE_AUTO:
+ err = m9mo_writeb(sd, M9MO_CATEGORY_LENS,
+ 0x07, 0x02);
+ CHECK_ERR(err);
+ cam_trace("~ FACTORY_AFZONE_AUTO ~\n");
+ break;
+
+ default:
+ cam_err("~ m9mo_set_factory_resol_cap ~ val : %d", val);
+ break;
+ }
+
+ cam_trace("X\n");
+ return 0;
+}
+
+static int m9mo_set_factory_af_lens(struct v4l2_subdev *sd, int val)
+{
+ int err;
+ u32 int_factor;
+
+ cam_trace("E val : %d\n", val);
+
+ switch (val) {
+ case FACTORY_AFLENS_OPEN:
+ err = m9mo_writeb(sd, M9MO_CATEGORY_LENS,
+ 0x00, 0x00);
+ CHECK_ERR(err);
+
+ int_factor = m9mo_wait_interrupt(sd, M9MO_ISP_TIMEOUT);
+
+ if (!(int_factor & M9MO_INT_LENS_INIT)) {
+ cam_err("M9MO_INT_LENS_INIT isn't issued, %#x\n",
+ int_factor);
+ return -ETIMEDOUT;
+ }
+
+
+ cam_trace("~ FACTORY_AFLENS_OPEN ~\n");
+ break;
+
+ case FACTORY_AFLENS_CLOSE:
+ err = m9mo_writeb(sd, M9MO_CATEGORY_LENS,
+ 0x01, 0x00);
+ CHECK_ERR(err);
+ cam_trace("~ FACTORY_AFLENS_CLOSE ~\n");
+ break;
+
+ default:
+ cam_err("~ m9mo_set_factory_af_lens ~ val : %d", val);
+ break;
+ }
+
+ cam_trace("X\n");
+ return 0;
+}
+
+static int m9mo_set_factory_adj_iris(struct v4l2_subdev *sd, int val)
+{
+ int err, end_check = 0;
+ int int_factor;
+ struct m9mo_state *state = to_state(sd);
+
+ cam_trace("E val : %d\n", val);
+
+ switch (val) {
+ case FACTORY_ADJ_IRIS_RUN:
+ cam_trace("~ FACTORY_ADJ_IRIS_RUN ~\n");
+ err = m9mo_writeb(sd, M9MO_CATEGORY_ADJST,
+ 0x53, 0x01);
+ CHECK_ERR(err);
+ break;
+
+ case FACTORY_ADJ_IRIS_STOP:
+ cam_trace("~ FACTORY_ADJ_IRIS_STOP ~\n");
+ break;
+ case FACTORY_ADJ_IRIS_END_CHECK:
+ err = m9mo_readb(sd, M9MO_CATEGORY_LENS,
+ 0x40, &end_check);
+ CHECK_ERR(err);
+ state->factory_end_check = end_check;
+ cam_trace("FACTORY_ADJ_IRIS_END_CHECK=%d\n",
+ end_check);
+
+ if (end_check == 2) {
+ /* Clear Interrupt factor */
int_factor = m9mo_wait_interrupt(sd, M9MO_ISP_TIMEOUT);
- if (!(int_factor & M9MO_INT_MODE)) {
- cam_err("M9MO_INT_MODE isn't issued, %#x\n",
+ if (!(int_factor & M9MO_INT_CAPTURE)) {
+ cam_warn("M9MO_INT_CAPTURE isn't issued, %#x\n",
int_factor);
return -ETIMEDOUT;
}
- CHECK_ERR(err);
}
break;
- case 60:
- cam_trace("~~~~~~ 60 fps ~~~~~~\n");
+ case FACTORY_ADJ_IRIS_LOG:
+ err = m9mo_make_CSV_rawdata(sd,
+ M9MO_FLASH_FACTORY_IRIS, true);
+ CHECK_ERR(err);
+ break;
- old_mode = m9mo_set_mode(sd, M9MO_PARMSET_MODE);
- CHECK_ERR(old_mode);
+ default:
+ cam_err("~ m9mo_set_factory_adj_iris ~ val : %d", val);
+ break;
+ }
- if (state->preview->height == 480) {
- err = m9mo_writeb(sd, M9MO_CATEGORY_PARM,
- M9MO_PARM_MON_SIZE, 0x2F);
- CHECK_ERR(err);
- } else if (state->preview->height == 720) {
- err = m9mo_writeb(sd, M9MO_CATEGORY_PARM,
- M9MO_PARM_MON_SIZE, 0x25);
- CHECK_ERR(err);
+ cam_trace("X\n");
+ return 0;
+}
+
+static int m9mo_set_factory_sh_close(struct v4l2_subdev *sd, int val)
+{
+ int err, end_check = 0;
+ int int_factor;
+ struct m9mo_state *state = to_state(sd);
+
+ cam_trace("E val : %d\n", val);
+
+ switch (val) {
+ case FACTORY_SH_CLOSE_RUN:
+ cam_trace("~ FACTORY_SH_CLOSE_RUN ~\n");
+ err = m9mo_writeb(sd, M9MO_CATEGORY_ADJST,
+ 0x53, 0x05);
+ CHECK_ERR(err);
+ break;
+
+ case FACTORY_SH_CLOSE_STOP:
+ cam_trace("~ FACTORY_SH_CLOSE_STOP ~\n");
+ break;
+
+ case FACTORY_SH_CLOSE_END_CHECK:
+ cam_trace("~ FACTORY_SH_CLOSE_END_CHECK ~\n");
+ err = m9mo_readb(sd, M9MO_CATEGORY_LENS,
+ 0x40, &end_check);
+ CHECK_ERR(err);
+ state->factory_end_check = end_check;
+ if (end_check == 2) {
+ int_factor = m9mo_wait_interrupt(sd, M9MO_ISP_TIMEOUT);
+ if (!(int_factor)) {
+ cam_warn("M9MO_INT_MODE isn't issued, %#x\n",
+ int_factor);
+ return -ETIMEDOUT;
+ }
}
+ break;
- if (old_mode == M9MO_MONITOR_MODE) {
- err = m9mo_set_mode(sd, old_mode);
- CHECK_ERR(err);
+ case FACTORY_SH_CLOSE_LOG:
+ cam_trace("~ FACTORY_SH_CLOSE_LOG ~\n");
+ err = m9mo_make_CSV_rawdata(sd,
+ M9MO_FLASH_FACTORY_SH_CLOSE, true);
+ CHECK_ERR(err);
+
+ int_factor = m9mo_wait_interrupt(sd, M9MO_ISP_TIMEOUT);
+ if (!(int_factor)) {
+ cam_warn("M9MO_INT_CAPTURE isn't issued, %#x\n",
+ int_factor);
+ return -ETIMEDOUT;
+ }
+
+ break;
+ default:
+ cam_err("~ m9mo_set_factory_adj_iris ~ val : %d", val);
+ break;
+ }
+
+ cam_trace("X\n");
+ return 0;
+}
+
+static int m9mo_set_factory_adj_gain_liveview(struct v4l2_subdev *sd, int val)
+{
+ int err, end_check = 0;
+ int int_factor;
+ struct m9mo_state *state = to_state(sd);
+
+ cam_trace("E val : %d\n", val);
+
+ switch (val) {
+ case FACTORY_ADJ_GAIN_LIVEVIEW_RUN:
+ cam_trace("~ FACTORY_ADJ_GAIN_LIVEVIEW_RUN ~\n");
+ err = m9mo_writeb(sd, M9MO_CATEGORY_ADJST,
+ 0x53, 0x03);
+ CHECK_ERR(err);
+ break;
+
+ case FACTORY_ADJ_GAIN_LIVEVIEW_STOP:
+ cam_trace("~ FACTORY_ADJ_GAIN_LIVEVIEW_STOP ~\n");
+ break;
+
+ case FACTORY_ADJ_GAIN_LIVEVIEW_END_CHECK:
+ cam_trace("~ FACTORY_ADJ_GAIN_LIVEVIEW_END_CHECK ~\n");
+ err = m9mo_readb(sd, M9MO_CATEGORY_LENS,
+ 0x40, &end_check);
+ CHECK_ERR(err);
+ state->factory_end_check = 0;
+
+ if (end_check == 2) {
+ state->factory_end_check = 4;
+ /* Clear Interrupt factor */
int_factor = m9mo_wait_interrupt(sd, M9MO_ISP_TIMEOUT);
- if (!(int_factor & M9MO_INT_MODE)) {
- cam_err("M9MO_INT_MODE isn't issued, %#x\n",
+ if (!(int_factor & M9MO_INT_CAPTURE)) {
+ cam_warn("M9MO_INT_CAPTURE isn't issued, %#x\n",
int_factor);
return -ETIMEDOUT;
}
- CHECK_ERR(err);
}
break;
- case 120:
- cam_trace("~~~~~~ 120 fps ~~~~~~\n");
+ case FACTORY_ADJ_GAIN_LIVEVIEW_LOG:
+ cam_trace("~ FACTORY_ADJ_GAIN_LIVEVIEW_END_CHECK ~\n");
+ err = m9mo_make_CSV_rawdata(sd,
+ M9MO_FLASH_FACTORY_LIVEVIEW, true);
+ CHECK_ERR(err);
break;
default:
- cam_err("~~~~ 30fps ~~~~\n");
+ cam_err("~ m9mo_set_factory_adj_iris ~ val : %d", val);
break;
}
+
cam_trace("X\n");
return 0;
}
-static int m9mo_set_LDC(struct v4l2_subdev *sd, int val)
+static int m9mo_set_factory_flicker(struct v4l2_subdev *sd, int val)
{
int err;
+ cam_trace("E val : %d\n", val);
- cam_dbg("%s\n", val ? "on" : "off");
+ switch (val) {
+ case FACTORY_FLICKER_AUTO:
+ cam_trace("~ FACTORY_FLICKER_AUTO ~\n");
+ err = m9mo_writeb(sd, M9MO_CATEGORY_AE,
+ M9MO_AE_FLICKER, 0x00);
+ CHECK_ERR(err);
+ break;
- if (val == 1) {
- err = m9mo_writeb(sd, M9MO_CATEGORY_MON,
- M9MO_MON_TONE_CTRL, 0x01);
+ case FACTORY_FLICKER_50HZ:
+ cam_trace("~ FACTORY_FLICKER_50HZ ~\n");
+ err = m9mo_writeb(sd, M9MO_CATEGORY_AE,
+ M9MO_AE_FLICKER, 0x01);
CHECK_ERR(err);
- } else {
- err = m9mo_writeb(sd, M9MO_CATEGORY_CAPPARM,
- M9MO_CAPPARM_WDR_EN, 0x00);
+ break;
+
+ case FACTORY_FLICKER_60HZ:
+ cam_trace("~ FACTORY_FLICKER_60HZ ~\n");
+ err = m9mo_writeb(sd, M9MO_CATEGORY_AE,
+ M9MO_AE_FLICKER, 0x02);
+ break;
+
+ case FACTORY_FLICKER_50_60:
+ cam_trace("~ FACTORY_FLICKER_50_60 ~\n");
+ err = m9mo_writeb(sd, M9MO_CATEGORY_AE,
+ M9MO_AE_FLICKER, 0x03);
+ break;
+
+ case FACTORY_FLICKER_OFF:
+ cam_trace("~ FACTORY_FLICKER_OFF ~\n");
+ err = m9mo_writeb(sd, M9MO_CATEGORY_AE,
+ M9MO_AE_FLICKER, 0x04);
CHECK_ERR(err);
+ break;
+
+ default:
+ cam_err("~ m9mo_set_factory_adj_iris ~ val : %d", val);
+ break;
}
cam_trace("X\n");
return 0;
}
-static int m9mo_set_LSC(struct v4l2_subdev *sd, int val)
+static int m9mo_set_factory_capture_gain(struct v4l2_subdev *sd, int val)
+{
+ int err, end_check = 0;
+ int int_factor;
+ struct m9mo_state *state = to_state(sd);
+ cam_trace("E val : %d\n", val);
+
+ switch (val) {
+ case FACTORY_CAPTURE_GAIN_RUN:
+ cam_trace("~ FACTORY_CAPTURE_GAIN_RUN ~\n");
+ err = m9mo_writeb(sd, M9MO_CATEGORY_ADJST,
+ 0x53, 0x07);
+ CHECK_ERR(err);
+ break;
+
+ case FACTORY_CAPTURE_GAIN_STOP:
+ cam_trace("~ FACTORY_CAPTURE_GAIN_STOP ~\n");
+ break;
+
+ case FACTORY_CAPTURE_GAIN_END_CHECK:
+ cam_trace("~ FACTORY_CAPTURE_GAIN_END_CHECK ~\n");
+ err = m9mo_readb(sd, M9MO_CATEGORY_LENS,
+ 0x40, &end_check);
+ CHECK_ERR(err);
+
+ state->factory_end_check = 0;
+ if (end_check == 2) {
+ state->factory_end_check = 8;
+ /* Clear Interrupt factor */
+ int_factor = m9mo_wait_interrupt(sd, M9MO_ISP_TIMEOUT);
+ if (!(int_factor & M9MO_INT_CAPTURE)) {
+ cam_warn("M9MO_INT_CAPTURE isn't issued, %#x\n",
+ int_factor);
+ return -ETIMEDOUT;
+ }
+ }
+
+ break;
+
+ case FACTORY_CAPTURE_GAIN_LOG:
+ err = m9mo_make_CSV_rawdata(sd,
+ M9MO_FLASH_FACTORY_GAIN_CAPTURE, true);
+ CHECK_ERR(err);
+ cam_trace("~FACTORY_CAPTURE_GAIN_LOG ~\n");
+ break;
+
+ default:
+ cam_err("~ m9mo_set_factory_capture_gain ~ val : %d", val);
+ break;
+ }
+
+ cam_trace("X\n");
+ return 0;
+}
+
+static int m9mo_set_image_stabilizer_mode(struct v4l2_subdev *sd, int val)
{
+ struct m9mo_state *state = to_state(sd);
int err;
+#if 0 /* Not use Mode Chagne */
+ int old_mode, int_factor;
+#endif
+ int cnt = 30;
+ s32 ois_stability = 1;
+ cam_trace("E: mode %d\n", val);
- cam_dbg("%s\n", val ? "on" : "off");
+#if 0 /* Not use Mode Chagne */
+ old_mode = m9mo_set_mode(sd, M9MO_PARMSET_MODE);
+ CHECK_ERR(old_mode);
+#endif
+retry:
+ switch (val) {
+ case V4L2_IMAGE_STABILIZER_OFF:
+ err = m9mo_writeb(sd, M9MO_CATEGORY_NEW, 0x11, 0x04);
+ CHECK_ERR(err);
+
+ err = m9mo_writeb(sd, M9MO_CATEGORY_NEW, 0x1A, 0x01);
+ CHECK_ERR(err);
+ err = m9mo_writeb(sd, M9MO_CATEGORY_NEW, 0x11, 0x01);
+ CHECK_ERR(err);
+
+ err = m9mo_readb(sd, M9MO_CATEGORY_NEW,
+ 0x1A, &ois_stability);
+ CHECK_ERR(err);
+ while (ois_stability && cnt) {
+ msleep(20);
+ err = m9mo_readb(sd, M9MO_CATEGORY_NEW,
+ 0x1A, &ois_stability);
+ CHECK_ERR(err);
+ cnt--;
+ }
+ break;
+
+ case V4L2_IMAGE_STABILIZER_OIS:
+ err = m9mo_writeb(sd, M9MO_CATEGORY_NEW, 0x1A, 0x01);
+ CHECK_ERR(err);
+ err = m9mo_writeb(sd, M9MO_CATEGORY_NEW, 0x11, 0x02);
+ CHECK_ERR(err);
+
+ err = m9mo_readb(sd, M9MO_CATEGORY_NEW,
+ 0x1A, &ois_stability);
+ CHECK_ERR(err);
+ while (ois_stability && cnt) {
+ msleep(20);
+ err = m9mo_readb(sd, M9MO_CATEGORY_NEW,
+ 0x1A, &ois_stability);
+ CHECK_ERR(err);
+ cnt--;
+ }
+ break;
+
+ case V4L2_IMAGE_STABILIZER_DUALIS:
+ /*break;*/
+
+ default:
+ val = V4L2_IMAGE_STABILIZER_OFF;
+ goto retry;
+ break;
+ }
+
+#if 0 /* Not use Mode Chagne */
+ if (old_mode == M9MO_MONITOR_MODE) {
+ err = m9mo_set_mode(sd, old_mode);
+ CHECK_ERR(err);
+
+ int_factor = m9mo_wait_interrupt(sd, M9MO_ISP_TIMEOUT);
+ if (!(int_factor & M9MO_INT_MODE)) {
+ cam_err("M9MO_INT_MODE isn't issued, %#x\n",
+ int_factor);
+ return -ETIMEDOUT;
+ }
+ CHECK_ERR(err);
+ }
+#endif
+
+ state->image_stabilizer_mode = val;
+
+ cam_trace("X\n");
+ return 0;
+}
+
+static int m9mo_set_factory_capture_ctrl(struct v4l2_subdev *sd, int val)
+{
+ int err = 0;
+ int int_factor;
+
+ cam_trace("E val : %d\n", val);
+
+ switch (val) {
+ case FACTORY_STILL_CAP_NORMAL:
+ cam_trace("~ FACTORY_STILL_CAP_NORMAL ~\n");
+ err = m9mo_writeb(sd, M9MO_CATEGORY_CAPCTRL,
+ M9MO_CAPCTRL_CAP_MODE, 0x00);
+ CHECK_ERR(err);
+ break;
+
+ case FACTORY_STILL_CAP_DUALCAP:
+ cam_trace("~ FACTORY_STILL_CAP_DUALCAP ~\n");
+ err = m9mo_writeb(sd, M9MO_CATEGORY_CAPCTRL,
+ M9MO_CAPCTRL_CAP_MODE, 0x05);
+ CHECK_ERR(err);
+ break;
+
+ case FACTORY_DUAL_CAP_ON:
+ cam_trace("~ FACTORY_DUAL_CAP_ON ~\n");
#if 0
- if (val == 1) {
- err = m9mo_writeb(sd, M9MO_CATEGORY_MON,
- M9MO_MON_TONE_CTRL, 0x01);
+ err = m9mo_readw(sd, M9MO_CATEGORY_SYS,
+ M9MO_SYS_INT_EN, &int_factor);
CHECK_ERR(err);
- } else {
+ int_factor &= ~M9MO_INT_FRAME_SYNC;
+ err = m9mo_writew(sd, M9MO_CATEGORY_SYS,
+ M9MO_SYS_INT_EN, int_factor);
+ CHECK_ERR(err);
+#endif
+
+ err = m9mo_writeb(sd, M9MO_CATEGORY_CAPCTRL,
+ M9MO_CAPCTRL_START_DUALCAP, 0x01);
+ CHECK_ERR(err);
+ break;
+
+ case FACTORY_DUAL_CAP_OFF:
+ cam_trace("~ FACTORY_DUAL_CAP_OFF ~\n");
+#if 1
+ int_factor = m9mo_wait_interrupt(sd, M9MO_ISP_TIMEOUT);
+ if (!(int_factor/* & M9MO_INT_SCENARIO_FIN*/)) {
+ cam_warn(
+ "M9MO_INT_SCENARIO_FIN isn't issued, %#x\n",
+ int_factor);
+ return -ETIMEDOUT;
+ }
+#endif
+ err = m9mo_writeb(sd, M9MO_CATEGORY_CAPCTRL,
+ M9MO_CAPCTRL_START_DUALCAP, 0x02);
+ CHECK_ERR(err);
+#if 1
+ int_factor = m9mo_wait_interrupt(sd, M9MO_ISP_TIMEOUT);
+ if (!(int_factor/* & M9MO_INT_SCENARIO_FIN*/)) {
+ cam_warn(
+ "M9MO_INT_SCENARIO_FIN isn't issued, %#x\n",
+ int_factor);
+ return -ETIMEDOUT;
+ }
+#endif
+
+ break;
+
+ default:
+ cam_err("~ m9mo_set_factory_capture_ctrl ~ val : %d", val);
+ break;
+ }
+
+ cam_trace("X\n");
+ return 0;
+}
+
+static int m9mo_set_factory_flash(struct v4l2_subdev *sd, int val)
+{
+ int err, end_check = 0;
+ struct m9mo_state *state = to_state(sd);
+
+ cam_trace("E val : %d\n", val);
+
+ switch (val) {
+ case FACTORY_FLASH_STROBE_CHECK_ON:
+ cam_trace("~ FACTORY_FLASH_STROBE_CHECK_ON ~\n");
+ err = m9mo_writeb(sd, M9MO_CATEGORY_ADJST,
+ 0x70, 0x01);
+ CHECK_ERR(err);
+ break;
+
+ case FACTORY_FLASH_STROBE_CHECK_OFF:
+ cam_trace("~ FACTORY_FLASH_STROBE_CHECK_OFF ~\n");
+ err = m9mo_writeb(sd, M9MO_CATEGORY_ADJST,
+ 0x70, 0x00);
+ CHECK_ERR(err);
+ break;
+
+ case FACTORY_FLASH_CHARGE:
+ cam_trace("~ FACTORY_FLASH_CHARGE ~\n");
err = m9mo_writeb(sd, M9MO_CATEGORY_CAPPARM,
- M9MO_CAPPARM_WDR_EN, 0x00);
+ 0x2A, 0x01);
+ CHECK_ERR(err);
+ break;
+
+ case FACTORY_FLASH_LOG:
+ err = m9mo_make_CSV_rawdata(sd,
+ M9MO_FLASH_FACTORY_FLASH_CHECK, false);
+ cam_trace("~ FACTORY_FLASH_LOG ~\n");
+ break;
+
+ case FACTORY_FLASH_CHARGE_END_CHECK:
+ cam_trace("~ FACTORY_FLASH_CHARGE_END_CHECK ~\n");
+ err = m9mo_readb(sd, M9MO_CATEGORY_ADJST,
+ 0x40, &end_check);
+ CHECK_ERR(err);
+ state->factory_end_check = end_check;
+ break;
+
+ case FACTORY_FLASH_STROBE_CHARGE_END_CHECK:
+ cam_trace("~ FLASH_STROBE_CHARGE_END_CHECK ~\n");
+ err = m9mo_readb(sd, M9MO_CATEGORY_CAPPARM,
+ 0x27, &end_check);
+ CHECK_ERR(err);
+ state->factory_end_check = end_check;
+ break;
+
+ case FACTORY_ADJ_FLASH_WB_END_CHECK:
+ cam_trace("~ ADJ_FLASH_WB_END_CHECK ~\n");
+ err = m9mo_readb(sd, M9MO_CATEGORY_ADJST,
+ 0x14, &end_check);
+ CHECK_ERR(err);
+ state->factory_end_check = end_check;
+ break;
+
+ case FACTORY_FLASH_WB_LOG:
+ err = m9mo_writeb(sd, M9MO_CATEGORY_NEW,
+ 0x31, 0x01);
+ msleep(40);
+ err = m9mo_make_CSV_rawdata(sd,
+ M9MO_FLASH_FACTORY_FLASH_WB, false);
+ cam_trace("~ FACTORY_FLASH_WB_LOG ~\n");
+ break;
+
+ case FACTORY_ADJ_FLASH_WB_LOG:
+ err = m9mo_make_CSV_rawdata(sd,
+ M9MO_FLASH_FACTORY_ADJ_FLASH_WB, false);
+ cam_trace("~ FACTORY_ADJ_FLASH_WB_LOG ~\n");
+ break;
+
+ default:
+ break;
+ }
+
+ cam_trace("X\n");
+ return 0;
+}
+
+static int m9mo_set_factory_wb(struct v4l2_subdev *sd, int val)
+{
+ int err, end_check = 0;
+ struct m9mo_state *state = to_state(sd);
+
+ cam_trace("E val : %d\n", val);
+
+ switch (val) {
+ case FACTORY_WB_INDOOR_RUN:
+ cam_trace("~ FACTORY_WB_INDOOR_RUN ~\n");
+ err = m9mo_writeb(sd, M9MO_CATEGORY_ADJST,
+ 0x14, 0x01);
CHECK_ERR(err);
+ break;
+
+ case FACTORY_WB_OUTDOOR_RUN:
+ cam_trace("~ FACTORY_WB_OUTDOOR_RUN ~\n");
+ err = m9mo_writeb(sd, M9MO_CATEGORY_ADJST,
+ 0x14, 0x21);
+ CHECK_ERR(err);
+ break;
+
+ case FACTORY_WB_INDOOR_END_CHECK:
+ case FACTORY_WB_OUTDOOR_END_CHECK:
+ cam_trace("~ FACTORY_WB_END_CHECK ~\n");
+ err = m9mo_readw(sd, M9MO_CATEGORY_ADJST,
+ 0x14, &end_check);
+ CHECK_ERR(err);
+ state->factory_end_check = end_check;
+ break;
+
+ case FACTORY_WB_LOG:
+ err = m9mo_make_CSV_rawdata(sd,
+ M9MO_FLASH_FACTORY_WB_ADJ, false);
+ cam_trace("~ FACTORY_WB_LOG ~\n");
+ break;
+
+ default:
+ break;
}
+
+ cam_trace("X\n");
+ return 0;
+}
+
+static int m9mo_set_factory_defectpixel(struct v4l2_subdev *sd, int val)
+{
+ int err;
+ int int_factor;
+ int end_check = 0;
+#if 0
+ int i;
#endif
+ struct m9mo_state *state = to_state(sd);
+
+ cam_trace("E val : %d\n", val);
+
+ switch (val) {
+ case FACTORY_DEFECTPIXEL_SCENARIO_6:
+ cam_trace("~ FACTORY_DEFECTPIXEL_SCENARIO_6 ~\n");
+
+ /*Interrupt Enable*/
+ err = m9mo_readw(sd, M9MO_CATEGORY_SYS,
+ M9MO_SYS_INT_EN, &int_factor);
+ CHECK_ERR(err);
+ int_factor |= M9MO_INT_SCENARIO_FIN;
+ err = m9mo_writew(sd, M9MO_CATEGORY_SYS,
+ M9MO_SYS_INT_EN, int_factor);
+ CHECK_ERR(err);
+
+ err = m9mo_writeb(sd, M9MO_CATEGORY_LENS,
+ 0x40, 0x00);
+ CHECK_ERR(err);
+
+ err = m9mo_writeb(sd, M9MO_CATEGORY_MON,
+ 0x5C, 0x06);
+ CHECK_ERR(err);
+ break;
+
+ case FACTORY_DEFECTPIXEL_RUN:
+ cam_trace("~ FACTORY_DEFECTPIXEL_RUN ~\n");
+ err = m9mo_writeb(sd, M9MO_CATEGORY_LENS,
+ 0x40, 0x00);
+ CHECK_ERR(err);
+ /*Interrrupt Disable*/
+#if 0
+ err = m9mo_readw(sd, M9MO_CATEGORY_SYS,
+ M9MO_SYS_INT_EN, &int_factor);
+ CHECK_ERR(err);
+ int_factor &= ~M9MO_INT_STNW_DETECT;
+ int_factor &= ~M9MO_INT_SCENARIO_FIN;
+ err = m9mo_writew(sd, M9MO_CATEGORY_SYS,
+ M9MO_SYS_INT_EN, int_factor);
+ CHECK_ERR(err);
+#endif
+
+ err = m9mo_writeb(sd, M9MO_CATEGORY_MON,
+ 0x5C, 0x07);
+ CHECK_ERR(err);
+#if 0
+ for (i = 0; i < 5; i++) {
+ int_factor = m9mo_wait_interrupt(sd, M9MO_ISP_TIMEOUT);
+ if (!(int_factor & M9MO_INT_STNW_DETECT)) {
+ cam_warn(
+ "M9MO_INT_STNW_DETECT isn't issued, %#x\n",
+ int_factor);
+ return -ETIMEDOUT;
+ }
+ }
+
+ int_factor = m9mo_wait_interrupt(sd, M9MO_ISP_TIMEOUT);
+ if (!(int_factor & M9MO_INT_SCENARIO_FIN)) {
+ cam_warn(
+ "M9MO_INT_SCENARIO_FIN isn't issued, %#x\n",
+ int_factor);
+ return -ETIMEDOUT;
+ }
+#endif
+ break;
+
+ case FACTORY_DEFECTPIXEL_END_CHECK:
+ cam_trace("~ FACTORY_DEFECTPIXEL_END_CHECK ~\n");
+ err = m9mo_readb(sd, M9MO_CATEGORY_LENS,
+ 0x40, &end_check);
+ CHECK_ERR(err);
+ state->factory_end_check = end_check;
+#if 0
+ if (0) { /*end_check != 0) {*/
+ msleep(100);
+ int_factor = m9mo_wait_interrupt(sd, M9MO_ISP_TIMEOUT);
+ if (!(int_factor & M9MO_INT_SCENARIO_FIN)) {
+ cam_warn(
+ "M9MO_INT_SCENARIO_FIN isn't issued, %#x\n",
+ int_factor);
+ return -ETIMEDOUT;
+ }
+ }
+#endif
+ m9mo_readw(sd, M9MO_CATEGORY_SYS,
+ M9MO_SYS_INT_FACTOR, &state->isp.int_factor);
+ cam_err("m9mo_wait_interrupt : state->isp.int_factor = %x\n",
+ state->isp.int_factor);
+ cam_trace("X\n");
+ break;
+
+ case FACTORY_DEFECTPIXEL_CID_WRITE:
+ cam_trace("~ FACTORY_DEFECTPIXEL_CID_WRITE ~\n");
+ m9mo_writeb(sd, M9MO_CATEGORY_SYS,
+ 0x29, 0x01);
+ cam_trace("X\n");
+ break;
+
+ case FACTORY_DEFECTPIXEL_CID_1:
+ cam_trace("~ FACTORY_DEFECTPIXEL_CID_1 ~\n");
+ m9mo_readw(sd, M9MO_CATEGORY_SYS,
+ 0x2A, &end_check);
+ cam_err("CID_1 : %x\n", end_check);
+ state->factory_end_check = end_check;
+ cam_trace("X\n");
+ break;
+
+ case FACTORY_DEFECTPIXEL_CID_2:
+ cam_trace("~ FACTORY_DEFECTPIXEL_CID_2 ~\n");
+ m9mo_readw(sd, M9MO_CATEGORY_SYS,
+ 0x2C, &end_check);
+ cam_err("CID_2 : %x\n", end_check);
+ state->factory_end_check = end_check;
+ cam_trace("X\n");
+ break;
+
+ case FACTORY_DEFECTPIXEL_CID_3:
+ cam_trace("~ FACTORY_DEFECTPIXEL_CID_3 ~\n");
+ m9mo_readw(sd, M9MO_CATEGORY_SYS,
+ 0x2E, &end_check);
+ cam_err("CID_3 : %x\n", end_check);
+ state->factory_end_check = end_check;
+ cam_trace("X\n");
+ break;
+
+ case FACTORY_DEFECTPIXEL_LOG:
+ cam_trace("~ FACTORY_DEFECTPIXEL_LOG ~\n");
+
+#if 0
+ msleep(300);
+ int_factor = m9mo_wait_interrupt(sd, M9MO_ISP_TIMEOUT);
+ if (!(int_factor & M9MO_INT_SCENARIO_FIN)) {
+ cam_warn(
+ "M9MO_INT_SCENARIO_FIN isn't issued, %#x\n",
+ int_factor);
+ return -ETIMEDOUT;
+ }
+#endif
+ m9mo_make_CSV_rawdata_direct(sd,
+ V4L2_CID_CAMERA_FACTORY_DEFECTPIXEL);
+
+ err = m9mo_writew(sd, M9MO_CATEGORY_SYS,
+ M9MO_SYS_INT_EN,
+ M9MO_INT_MODE | M9MO_INT_CAPTURE |
+ M9MO_INT_FRAME_SYNC | M9MO_INT_ATSCENE_UPDATE |
+ M9MO_INT_LENS_INIT/* | M9MO_INT_SOUND*/);
+ CHECK_ERR(err);
+
+ int_factor = m9mo_wait_interrupt(sd, M9MO_ISP_TIMEOUT);
+ cam_trace("~ Event clear ~\n");
+ break;
+
+ case FACTORY_DEFECTPIXEL_DOT_WRITE_CHECK:
+ case FACTORY_DEFECTPIXEL_FLASH_MERGE:
+ err = m9mo_readb(sd, M9MO_CATEGORY_ADJST,
+ 0x90, &end_check);
+ CHECK_ERR(err);
+ cam_trace("DOT DATA END CHECK : %d\n", end_check);
+ state->factory_end_check = end_check;
+ break;
+
+ default:
+ break;
+ }
+
+ cam_trace("X\n");
+ return 0;
+}
+
+static int m9mo_set_factory_tilt(struct v4l2_subdev *sd, int val)
+{
+ int err, end_check = 0;
+ struct m9mo_state *state = to_state(sd);
+
+ cam_trace("E val : %d\n", val);
+
+ switch (val) {
+ case FACTORY_TILT_ONE_SCRIPT_RUN:
+ err = m9mo_writeb(sd, M9MO_CATEGORY_LENS,
+ 0x0C, 0x06);
+ CHECK_ERR(err);
+ cam_trace("FACTORY_TILT_ONE_SCRIPT_RUN\n");
+ break;
+
+ case FACTORY_TILT_ONE_SCRIPT_DISP1:
+ err = m9mo_readw(sd, M9MO_CATEGORY_LENS,
+ 0x34, &end_check);
+ CHECK_ERR(err);
+ state->factory_end_check = end_check;
+ cam_trace("FACTORY_TILT_ONE_SCRIPT_DISP1 %d\n", end_check);
+ break;
+
+ case FACTORY_TILT_ONE_SCRIPT_DISP2:
+ err = m9mo_readw(sd, M9MO_CATEGORY_LENS,
+ 0x36, &end_check);
+ CHECK_ERR(err);
+ state->factory_end_check = end_check;
+ cam_trace("FACTORY_TILT_ONE_SCRIPT_DISP2 %d\n", end_check);
+ break;
+
+ case FACTORY_TILT_ONE_SCRIPT_DISP3:
+ err = m9mo_readw(sd, M9MO_CATEGORY_LENS,
+ 0x38, &end_check);
+ CHECK_ERR(err);
+ state->factory_end_check = end_check;
+ cam_trace("FACTORY_TILT_ONE_SCRIPT_DISP3 %d\n", end_check);
+ break;
+
+ case FACTORY_TILT_ONE_SCRIPT_DISP4:
+ err = m9mo_readw(sd, M9MO_CATEGORY_LENS,
+ 0x3A, &end_check);
+ CHECK_ERR(err);
+ state->factory_end_check = end_check;
+ cam_trace("FACTORY_TILT_ONE_SCRIPT_DISP4 %d\n", end_check);
+ break;
+
+ case FACTORY_TILT_ONE_SCRIPT_DISP5:
+ err = m9mo_readw(sd, M9MO_CATEGORY_LENS,
+ 0x3C, &end_check);
+ CHECK_ERR(err);
+ state->factory_end_check = end_check;
+ cam_trace("FACTORY_TILT_ONE_SCRIPT_DISP5 %d\n", end_check);
+ break;
+
+ default:
+ cam_err("~ m9mo_set_factory_common ~ val : %d", val);
+ break;
+ }
cam_trace("X\n");
return 0;
}
-static int m9mo_set_aperture(struct v4l2_subdev *sd, int val)
+static int m9mo_set_factory_IR_Check(struct v4l2_subdev *sd, int val)
{
int err;
cam_trace("E val : %d\n", val);
- err = m9mo_writeb(sd, M9MO_CATEGORY_AE,
- M9MO_AE_EP_MODE_MON, 0x0C);
- CHECK_ERR(err);
+ switch (val) {
+ case FACTORY_IR_CHECK_LOG:
+ cam_trace("~ FACTORY_IR_CHECK_LOG ~\n");
+ msleep(40);
+ err = m9mo_make_CSV_rawdata(sd,
+ M9MO_FLASH_FACTORY_IR_CHECK, false);
+ CHECK_ERR(err);
+ break;
+
+ default:
+ cam_err("~ m9mo_set_factory_common ~ val : %d", val);
+ break;
+ }
cam_trace("X\n");
return 0;
}
+static int m9mo_send_factory_command_value(struct v4l2_subdev *sd)
+{
+ int err;
+ int category = 0, byte = 0, value = 0, size = 0;
+ struct m9mo_state *state = to_state(sd);
+
+ category = state->factory_category;
+ byte = state->factory_byte;
+ value = state->factory_value;
+ size = state->factory_value_size;
+
+ cam_trace("category : 0x%x, byte : 0x%x, value : 0x%x\n",
+ category, byte, value);
+
+ if ((size == 4) || (value > 0xFFFF)) {
+ cam_trace("write long");
+ err = m9mo_writel(sd, category, byte, value);
+ CHECK_ERR(err);
+ return err;
+ }
+
+ if ((size == 2) || (value > 0xFF)) {
+ cam_trace("write word");
+ err = m9mo_writew(sd, category, byte, value);
+ CHECK_ERR(err);
+ return err;
+ }
+
+ cam_trace("write byte");
+ err = m9mo_writeb(sd, category, byte, value);
+ CHECK_ERR(err);
+ return err;
+}
+
static int m9mo_set_aeawblock(struct v4l2_subdev *sd, int val)
{
int err;
@@ -2942,6 +7089,1323 @@ static int m9mo_set_aeawblock(struct v4l2_subdev *sd, int val)
return 0;
}
+static int m9mo_set_GBAM(struct v4l2_subdev *sd, int val)
+{
+ struct m9mo_state *state = to_state(sd);
+ int err = 0;
+
+ if (state->wb_g_value == 0 && state->wb_b_value == 0
+ && state->wb_a_value == 0 && state->wb_m_value == 0)
+ val = 0;
+
+ cam_trace("E, val = %d\n", val);
+
+ if (val) {
+ err = m9mo_writeb(sd, M9MO_CATEGORY_WB,
+ M9MO_WB_GBAM_MODE, 0x01);
+ CHECK_ERR(err);
+
+ err = m9mo_writeb(sd, M9MO_CATEGORY_WB,
+ M9MO_WB_G_VALUE, state->wb_g_value);
+ CHECK_ERR(err);
+
+ err = m9mo_writeb(sd, M9MO_CATEGORY_WB,
+ M9MO_WB_B_VALUE, state->wb_b_value);
+ CHECK_ERR(err);
+
+ err = m9mo_writeb(sd, M9MO_CATEGORY_WB,
+ M9MO_WB_A_VALUE, state->wb_a_value);
+ CHECK_ERR(err);
+
+ err = m9mo_writeb(sd, M9MO_CATEGORY_WB,
+ M9MO_WB_M_VALUE, state->wb_m_value);
+ CHECK_ERR(err);
+ } else {
+ err = m9mo_writeb(sd, M9MO_CATEGORY_WB,
+ M9MO_WB_GBAM_MODE, 0x00);
+ CHECK_ERR(err);
+ }
+
+ cam_trace("X\n");
+ return 0;
+}
+
+static int m9mo_set_K(struct v4l2_subdev *sd, int val)
+{
+ int err = 0;
+
+ cam_trace("E %02X\n", val);
+
+ err = m9mo_writeb(sd, M9MO_CATEGORY_WB,
+ M9MO_WB_K_VALUE, val);
+ CHECK_ERR(err);
+
+ cam_trace("X\n");
+ return 0;
+}
+
+static int m9mo_set_dual_capture_mode(struct v4l2_subdev *sd, int val)
+{
+ int err = 0;
+ int old_mode;
+ struct m9mo_state *state = to_state(sd);
+
+ cam_trace("E, val = %d\n", val);
+
+ if (val == state->vss_mode) {
+ cam_err("same vss_mode: %d\n", state->vss_mode);
+ return err;
+ }
+
+ old_mode = m9mo_set_mode(sd, M9MO_PARMSET_MODE);
+ CHECK_ERR(old_mode);
+
+ switch (val) {
+ case 0:
+ /* Normal Video Snap Shot */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_PARM,
+ M9MO_PARM_VSS_MODE, 0x00);
+ CHECK_ERR(err);
+ break;
+
+ case 1:
+ /* 4M Video Snap Shot */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_PARM,
+ M9MO_PARM_VSS_MODE, 0x01);
+ CHECK_ERR(err);
+ break;
+ default:
+ val = 0;
+ break;
+ }
+
+ state->vss_mode = val;
+
+ cam_trace("X\n");
+ return err;
+}
+
+static int m9mo_start_set_dual_capture(struct v4l2_subdev *sd, int frame_num)
+{
+ struct m9mo_state *state = to_state(sd);
+ int err, int_factor;
+
+ cam_trace("E, vss mode: %d, frm[%d]\n", state->vss_mode, frame_num);
+
+ if (!state->vss_mode)
+ return 0;
+
+ /* Start video snap shot */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_MON,
+ M9MO_MON_START_VIDEO_SNAP_SHOT, 0x01);
+ CHECK_ERR(err);
+
+ /* Clear Interrupt factor */
+ int_factor = m9mo_wait_interrupt(sd, M9MO_ISP_TIMEOUT);
+ if (!(int_factor & M9MO_INT_FRAME_SYNC)) {
+ cam_err("M9MO_INT_FRAME_SYNC isn't issued, %#x\n", int_factor);
+ return -ETIMEDOUT;
+ }
+
+ state->dual_capture_start = 1;
+ state->dual_capture_frame = frame_num;
+
+ cam_trace("X\n");
+ return err;
+}
+
+static int m9mo_continue_proc(struct v4l2_subdev *sd, int val)
+{
+ int err = 1, int_factor;
+
+ cam_trace("E\n");
+
+ switch (val) {
+ case V4L2_INT_STATE_FRAME_SYNC:
+ int_factor = m9mo_wait_interrupt(sd, M9MO_ISP_TIMEOUT);
+ if (!(int_factor & M9MO_INT_FRAME_SYNC)) {
+ cam_dbg("m9mo_continue_proc() INT_FRAME_SYNC error%#x\n",
+ int_factor);
+ return -ETIMEDOUT;
+ }
+ break;
+
+ case V4L2_INT_STATE_CAPTURE_SYNC:
+ /* continue : cancel CAPTURE or postview end CAPTURE*/
+ int_factor = m9mo_wait_interrupt(sd, M9MO_ISP_CAPTURE_TIMEOUT);
+ if (!(int_factor & M9MO_INT_CAPTURE)) {
+ cam_dbg("m9mo_continue_proc() INT_STATE_CAPTURE_SYNC error%#x\n",
+ int_factor);
+ return -ETIMEDOUT;
+ }
+ break;
+
+ case V4L2_INT_STATE_CONTINUE_CANCEL:
+ /* continue cancel */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_CAPCTRL,
+ M9MO_CAPCTRL_START_DUALCAP, 0x02);
+ CHECK_ERR(err);
+ cam_dbg("-------------V4L2_INT_STATE_CONTINUE_CANCEL-------------\n");
+ /* CAPTURE wait interrupt -> V4L2_INT_STATE_CAPTURE_SYNC */
+ break;
+
+ case V4L2_INT_STATE_CONTINUE_END:
+ m9mo_set_mode(sd, M9MO_MONITOR_MODE);
+
+ err = m9mo_wait_interrupt(sd, M9MO_ISP_TIMEOUT);
+ if (!(err & M9MO_INT_MODE)) {
+ cam_err("m9mo_continue_proc() INT_STATE_CONTINUE_END error\n");
+ return -ETIMEDOUT;
+ }
+ break;
+
+ case V4L2_INT_STATE_START_CAPTURE:
+ m9mo_set_mode(sd, M9MO_STILLCAP_MODE);
+ break;
+ }
+
+ cam_dbg("m9mo_continue_proc : 0x%x err=%d\n",
+ val, err);
+
+ cam_trace("X\n");
+ return err;
+}
+
+static int m9mo_burst_set_postview_size(struct v4l2_subdev *sd, int val)
+{
+ int err = 1, i, num_entries;
+ struct m9mo_state *state = to_state(sd);
+ const struct m9mo_frmsizeenum **frmsize;
+
+ int width = val >> 16;
+ int height = val & 0xFFFF;
+
+ cam_trace("E\n");
+ cam_trace("size = (%d x %d)\n", width, height);
+
+ frmsize = &state->postview;
+
+ num_entries = ARRAY_SIZE(postview_frmsizes);
+ *frmsize = &postview_frmsizes[num_entries-1];
+
+ for (i = 0; i < num_entries; i++) {
+ if (width == postview_frmsizes[i].width &&
+ height == postview_frmsizes[i].height) {
+ *frmsize = &postview_frmsizes[i];
+ break;
+ }
+ }
+
+ err = m9mo_writeb(sd, M9MO_CATEGORY_CAPPARM,
+ M9MO_CAPPARM_PREVIEW_IMG_SIZE,
+ state->postview->reg_val);
+
+ cam_trace("X\n");
+
+ return err;
+}
+
+static int m9mo_burst_set_snapshot_size(struct v4l2_subdev *sd, int val)
+{
+ int err = 1, i, num_entries;
+ struct m9mo_state *state = to_state(sd);
+ const struct m9mo_frmsizeenum **frmsize;
+
+ int width = val >> 16;
+ int height = val & 0xFFFF;
+
+ cam_trace("E\n");
+ cam_trace("size = (%d x %d)\n", width, height);
+
+ frmsize = &state->capture;
+
+ num_entries = ARRAY_SIZE(capture_frmsizes);
+ *frmsize = &capture_frmsizes[num_entries-1];
+
+ for (i = 0; i < num_entries; i++) {
+ if (width == capture_frmsizes[i].width &&
+ height == capture_frmsizes[i].height) {
+ *frmsize = &capture_frmsizes[i];
+ break;
+ }
+ }
+
+ err = m9mo_writeb(sd, M9MO_CATEGORY_CAPPARM,
+ M9MO_CAPPARM_MAIN_IMG_SIZE,
+ state->capture->reg_val);
+
+ cam_trace("X\n");
+
+ return err;
+}
+
+static int m9mo_burst_proc(struct v4l2_subdev *sd, int val)
+{
+ int err = 1, int_factor;
+ struct m9mo_state *state = to_state(sd);
+
+ cam_trace("E\n");
+
+ switch (val) {
+ case V4L2_INT_STATE_BURST_START:
+ cam_trace("Burstshot Capture START ~~~~~~\n");
+
+ err = m9mo_writeb(sd, M9MO_CATEGORY_CAPPARM,
+ 0x0F, 0x0);
+ CHECK_ERR(err);
+
+ err = m9mo_writeb(sd, M9MO_CATEGORY_CAPPARM,
+ 0x10, 0x50);
+ CHECK_ERR(err);
+
+ err = m9mo_writeb(sd, M9MO_CATEGORY_CAPPARM,
+ 0x11, 0x0);
+ CHECK_ERR(err);
+
+ err = m9mo_writeb(sd, M9MO_CATEGORY_CAPPARM,
+ M9MO_CAPPARM_YUVOUT_MAIN, 0x01);
+ CHECK_ERR(err);
+
+ err = m9mo_writeb(sd, M9MO_CATEGORY_CAPPARM,
+ 0x12, 0x0);
+ CHECK_ERR(err);
+
+ err = m9mo_writeb(sd, M9MO_CATEGORY_CAPCTRL,
+ M9MO_CAPCTRL_CAP_MODE, 0x0D);
+ CHECK_ERR(err);
+
+ err = m9mo_writeb(sd, M9MO_CATEGORY_CAPCTRL,
+ M9MO_CAPCTRL_START_DUALCAP, M9MO_CAP_MODE_MULTI_CAPTURE);
+ CHECK_ERR(err);
+#if 0
+ int_factor = m9mo_wait_interrupt(sd, M9MO_ISP_TIMEOUT);
+ if (!(int_factor & M9MO_INT_SOUND)) {
+ cam_dbg("m9mo_continue_proc() INT_FRAME_SYNC error%#x\n",
+ int_factor);
+ return -ETIMEDOUT;
+ }
+#endif
+ break;
+
+ case V4L2_INT_STATE_BURST_SYNC:
+ cam_trace("Burstshot Page SYNC~~~\n");
+ int_factor = m9mo_wait_interrupt(sd, M9MO_ISP_TIMEOUT);
+ if (!(int_factor & M9MO_INT_SOUND)) {
+ cam_dbg("m9mo_continue_proc() INT_FRAME_SYNC error%#x\n",
+ int_factor);
+ return -ETIMEDOUT;
+ }
+ break;
+
+ case V4L2_INT_STATE_BURST_STOP:
+ /* continue cancel */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_CAPCTRL,
+ M9MO_CAPCTRL_START_DUALCAP, 0x02);
+ CHECK_ERR(err);
+
+ /* CAPTURE wait interrupt -> V4L2_INT_STATE_CAPTURE_SYNC */
+ err = m9mo_wait_interrupt(sd, M9MO_ISP_TIMEOUT);
+ if (!(err & M9MO_INT_MODE)) {
+ cam_err("m9mo_burst_proc() INT_STATE_CONTINUE_END error\n");
+ return -ETIMEDOUT;
+ }
+
+ state->running_capture_mode = RUNNING_MODE_SINGLE;
+
+ cam_trace("Burstshot Capture STOP ~~~~~~\n");
+ break;
+ }
+
+ cam_trace("X\n");
+ return err;
+}
+
+static int m9mo_set_gamma(struct v4l2_subdev *sd)
+{
+ struct m9mo_state *state = to_state(sd);
+ int err = 0;
+ int gamma_rgb_mon, mon_gamma, cap_gamma, gamma_rgb_cap;
+
+ cam_trace("E, mode %d\n", state->mode);
+
+ /* Set Monitor/Video flag */
+ if (state->mode == MODE_VIDEO) {
+ err = m9mo_writeb(sd, M9MO_CATEGORY_PARM,
+ M9MO_PARM_MON_MOVIE_SELECT, 0x01);
+ CHECK_ERR(err);
+ } else {
+ err = m9mo_writeb(sd, M9MO_CATEGORY_PARM,
+ M9MO_PARM_MON_MOVIE_SELECT, 0x00);
+ CHECK_ERR(err);
+ }
+
+ /* Set Gamma value */
+ err = m9mo_readb(sd, M9MO_CATEGORY_PARM, 0x0A, &gamma_rgb_mon);
+ CHECK_ERR(err);
+ err = m9mo_readb(sd, M9MO_CATEGORY_PARM, 0x31, &mon_gamma);
+ CHECK_ERR(err);
+ err = m9mo_readb(sd, M9MO_CATEGORY_CAPPARM, 0x41, &cap_gamma);
+ CHECK_ERR(err);
+ err = m9mo_readb(sd, M9MO_CATEGORY_CAPPARM, 0x42, &gamma_rgb_cap);
+ CHECK_ERR(err);
+
+ if (mon_gamma < 0xD && gamma_rgb_cap < 0xD) {
+ state->gamma_rgb_mon = gamma_rgb_mon;
+ state->gamma_tbl_rgb_mon = mon_gamma;
+ state->gamma_rgb_cap = cap_gamma;
+ state->gamma_tbl_rgb_cap = gamma_rgb_cap;
+ }
+
+ if (state->mode == MODE_SILHOUETTE) {
+ err = m9mo_writeb(sd, M9MO_CATEGORY_PARM,
+ 0x0A, 0x00);
+ CHECK_ERR(err);
+ err = m9mo_writeb(sd, M9MO_CATEGORY_PARM,
+ 0x31, 0x0D + state->widget_mode_level);
+ CHECK_ERR(err);
+ err = m9mo_writeb(sd, M9MO_CATEGORY_CAPPARM,
+ 0x41, 0x00);
+ CHECK_ERR(err);
+ err = m9mo_writeb(sd, M9MO_CATEGORY_CAPPARM,
+ 0x42, 0x0D + state->widget_mode_level);
+ CHECK_ERR(err);
+ } else {
+ err = m9mo_writeb(sd, M9MO_CATEGORY_PARM,
+ 0x0A, state->gamma_rgb_mon);
+ CHECK_ERR(err);
+ err = m9mo_writeb(sd, M9MO_CATEGORY_PARM,
+ 0x31, state->gamma_tbl_rgb_mon);
+ CHECK_ERR(err);
+ err = m9mo_writeb(sd, M9MO_CATEGORY_CAPPARM,
+ 0x41, state->gamma_rgb_cap);
+ CHECK_ERR(err);
+ err = m9mo_writeb(sd, M9MO_CATEGORY_CAPPARM,
+ 0x42, state->gamma_tbl_rgb_cap);
+ CHECK_ERR(err);
+ }
+
+ cam_trace("X\n");
+ return 0;
+}
+
+static int m9mo_set_PASM_mode(struct v4l2_subdev *sd, int val)
+{
+ struct m9mo_state *state = to_state(sd);
+ int err = 0;
+ int color_effect, current_mode;
+
+ cam_dbg("E, value %d\n", val);
+
+ state->mode = val;
+
+ err = m9mo_readb(sd, M9MO_CATEGORY_SYS, M9MO_SYS_MODE, &current_mode);
+
+ switch (val) {
+ case MODE_SMART_AUTO:
+ err = m9mo_writeb(sd, M9MO_CATEGORY_MON,
+ M9MO_MON_COLOR_EFFECT, state->color_effect);
+ CHECK_ERR(err);
+
+ /* Set LIKE_PRO_EN Disable */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_PRO_MODE, 0x00, 0x00);
+ CHECK_ERR(err);
+
+ /* Set Still Mode */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_NEW, 0x08, 0x01);
+ CHECK_ERR(err);
+
+ /* Set HISTOGRAM ON */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_MON, 0x58, 0x01);
+ CHECK_ERR(err);
+
+ /* SMART AUTO CAP */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_AE,
+ M9MO_AE_EV_PRG_MODE_CAP, 0x10);
+ CHECK_ERR(err);
+
+ if (state->facedetect_mode == FACE_DETECTION_NORMAL) {
+ err = m9mo_writeb(sd, M9MO_CATEGORY_FD,
+ M9MO_FD_CTL, 0x01);
+ CHECK_ERR(err);
+ }
+
+ break;
+
+ case MODE_PROGRAM:
+ err = m9mo_writeb(sd, M9MO_CATEGORY_MON,
+ M9MO_MON_COLOR_EFFECT, state->color_effect);
+ CHECK_ERR(err);
+
+ /* Set LIKE_PRO_EN Disable */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_PRO_MODE, 0x00, 0x00);
+ CHECK_ERR(err);
+
+ /* Set CATE_408 to None */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_NEW, 0x08, 0x00);
+ CHECK_ERR(err);
+
+ /* Set HISTOGRAM OFF */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_MON, 0x58, 0x00);
+ CHECK_ERR(err);
+
+ /* Set Monitor EV program mode */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_AE,
+ M9MO_AE_EP_MODE_MON, 0x00);
+ CHECK_ERR(err);
+
+ /* Set Still Capture EV program mode */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_AE,
+ M9MO_AE_EP_MODE_CAP, 0x00);
+ CHECK_ERR(err);
+
+ /* Still Capture EVP Set Parameter Mode */
+ if (state->iso == 0) {
+ err = m9mo_writeb(sd, M9MO_CATEGORY_AE,
+ M9MO_AE_EV_PRG_MODE_CAP, 0x00);
+ CHECK_ERR(err);
+ } else {
+ err = m9mo_writeb(sd, M9MO_CATEGORY_AE,
+ M9MO_AE_EV_PRG_MODE_CAP, 0x04);
+ CHECK_ERR(err);
+ }
+ break;
+
+ case MODE_A:
+ err = m9mo_writeb(sd, M9MO_CATEGORY_MON,
+ M9MO_MON_COLOR_EFFECT, state->color_effect);
+ CHECK_ERR(err);
+
+ /* Set LIKE_PRO_EN Disable */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_PRO_MODE, 0x00, 0x00);
+ CHECK_ERR(err);
+
+ /* Set CATE_408 to None */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_NEW, 0x08, 0x00);
+ CHECK_ERR(err);
+
+ /* Set HISTOGRAM OFF */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_MON, 0x58, 0x00);
+ CHECK_ERR(err);
+
+ /* Set Monitor EV program mode */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_AE,
+ M9MO_AE_EP_MODE_MON, 0x02);
+ CHECK_ERR(err);
+
+ /* Set Still Capture EV program mode */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_AE,
+ M9MO_AE_EP_MODE_CAP, 0x02);
+ CHECK_ERR(err);
+
+ /* Still Capture EVP Set Parameter Mode */
+ if (state->iso == 0) {
+ err = m9mo_writeb(sd, M9MO_CATEGORY_AE,
+ M9MO_AE_EV_PRG_MODE_CAP, 0x01);
+ CHECK_ERR(err);
+ } else {
+ err = m9mo_writeb(sd, M9MO_CATEGORY_AE,
+ M9MO_AE_EV_PRG_MODE_CAP, 0x05);
+ CHECK_ERR(err);
+ }
+
+ /* Set Still Capture F-Number Value */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_AE,
+ M9MO_AE_EV_PRG_F_NUMBER, state->f_number);
+ CHECK_ERR(err);
+ break;
+
+ case MODE_S:
+ err = m9mo_writeb(sd, M9MO_CATEGORY_MON,
+ M9MO_MON_COLOR_EFFECT, state->color_effect);
+ CHECK_ERR(err);
+
+ /* Set LIKE_PRO_EN Disable */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_PRO_MODE, 0x00, 0x00);
+ CHECK_ERR(err);
+
+ /* Set CATE_408 to None */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_NEW, 0x08, 0x00);
+ CHECK_ERR(err);
+
+ /* Set HISTOGRAM OFF */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_MON, 0x58, 0x00);
+ CHECK_ERR(err);
+
+ /* Set Monitor EV program mode */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_AE,
+ M9MO_AE_EP_MODE_MON, 0x04);
+ CHECK_ERR(err);
+
+ /* Set Still Capture EV program mode */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_AE,
+ M9MO_AE_EP_MODE_CAP, 0x04);
+ CHECK_ERR(err);
+
+ /* Still Capture EVP Set Parameter Mode */
+ if (state->iso == 0) {
+ err = m9mo_writeb(sd, M9MO_CATEGORY_AE,
+ M9MO_AE_EV_PRG_MODE_CAP, 0x02);
+ CHECK_ERR(err);
+ } else {
+ err = m9mo_writeb(sd, M9MO_CATEGORY_AE,
+ M9MO_AE_EV_PRG_MODE_CAP, 0x06);
+ CHECK_ERR(err);
+ }
+
+ /* Set Capture Shutter Speed Time */
+ err = m9mo_writew(sd, M9MO_CATEGORY_AE,
+ M9MO_AE_EV_PRG_SS_NUMERATOR, state->numerator);
+ CHECK_ERR(err);
+ err = m9mo_writew(sd, M9MO_CATEGORY_AE,
+ M9MO_AE_EV_PRG_SS_DENOMINATOR, state->denominator);
+ CHECK_ERR(err);
+ break;
+
+ case MODE_M:
+ err = m9mo_writeb(sd, M9MO_CATEGORY_MON,
+ M9MO_MON_COLOR_EFFECT, state->color_effect);
+ CHECK_ERR(err);
+
+ /* Set LIKE_PRO_EN Disable */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_PRO_MODE, 0x00, 0x00);
+ CHECK_ERR(err);
+
+ /* Set CATE_408 to None */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_NEW, 0x08, 0x00);
+ CHECK_ERR(err);
+
+ /* Set HISTOGRAM OFF */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_MON, 0x58, 0x00);
+ CHECK_ERR(err);
+
+ /* Set Monitor EV program mode */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_AE,
+ M9MO_AE_EP_MODE_MON, 0x00);
+ CHECK_ERR(err);
+
+ /* Set Still Capture EV program mode */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_AE,
+ M9MO_AE_EP_MODE_CAP, 0x00);
+ CHECK_ERR(err);
+
+ /* Still Capture EVP Set Parameter Mode */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_AE,
+ M9MO_AE_EV_PRG_MODE_CAP, 0x07);
+ CHECK_ERR(err);
+
+ /* Set Still Capture F-Number Value */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_AE,
+ M9MO_AE_EV_PRG_F_NUMBER, state->f_number);
+ CHECK_ERR(err);
+
+ /* Set Capture Shutter Speed Time */
+ err = m9mo_writew(sd, M9MO_CATEGORY_AE,
+ M9MO_AE_EV_PRG_SS_NUMERATOR, state->numerator);
+ CHECK_ERR(err);
+ err = m9mo_writew(sd, M9MO_CATEGORY_AE,
+ M9MO_AE_EV_PRG_SS_DENOMINATOR, state->denominator);
+ CHECK_ERR(err);
+
+ /* Set Still Capture ISO Value */
+ err = m9mo_writew(sd, M9MO_CATEGORY_AE,
+ M9MO_AE_EV_PRG_ISO_VALUE, state->iso);
+ CHECK_ERR(err);
+ break;
+
+ case MODE_VIDEO:
+ err = m9mo_writeb(sd, M9MO_CATEGORY_MON,
+ M9MO_MON_COLOR_EFFECT, state->color_effect);
+ CHECK_ERR(err);
+
+ /* Set LIKE_PRO_EN Disable */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_PRO_MODE, 0x00, 0x00);
+ CHECK_ERR(err);
+
+ /* Set HISTOGRAM OFF */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_MON, 0x58, 0x00);
+ CHECK_ERR(err);
+
+ /* Still Capture EVP Set Parameter Mode */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_AE,
+ M9MO_AE_EV_PRG_MODE_CAP, 0x00);
+ CHECK_ERR(err);
+ break;
+
+ case MODE_HIGH_SPEED:
+ /* Set CATE_408 to None */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_NEW, 0x08, 0x00);
+ CHECK_ERR(err);
+
+ /* Set HISTOGRAM ON */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_MON, 0x58, 0x01);
+ CHECK_ERR(err);
+
+ /* LIKE A PRO MODE SET */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_PRO_MODE, 0x01, 0x01);
+ CHECK_ERR(err);
+
+ /* LIKE A PRO STEP SET */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_PRO_MODE,
+ 0x02, state->widget_mode_level);
+ CHECK_ERR(err);
+
+ err = m9mo_writeb(sd, M9MO_CATEGORY_MON,
+ M9MO_MON_COLOR_EFFECT, state->color_effect);
+ CHECK_ERR(err);
+
+ /* Set LIKE_PRO_EN Enable */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_PRO_MODE, 0x00, 0x01);
+ CHECK_ERR(err);
+
+ /* Set CATE_409 to 1(PREVIEW) */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_NEW, 0x09, 0x01);
+ CHECK_ERR(err);
+ break;
+
+ case MODE_LIGHT_TRAIL_SHOT:
+ /* Set CATE_408 to None */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_NEW, 0x08, 0x00);
+ CHECK_ERR(err);
+
+ /* Set HISTOGRAM ON */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_MON, 0x58, 0x01);
+ CHECK_ERR(err);
+
+ /* LIKE A PRO MODE SET */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_PRO_MODE, 0x01, 0x02);
+ CHECK_ERR(err);
+
+ /* LIKE A PRO STEP SET */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_PRO_MODE,
+ 0x02, state->widget_mode_level);
+ CHECK_ERR(err);
+
+ err = m9mo_writeb(sd, M9MO_CATEGORY_MON,
+ M9MO_MON_COLOR_EFFECT, state->color_effect);
+ CHECK_ERR(err);
+
+ /* Set LIKE_PRO_EN Enable */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_PRO_MODE, 0x00, 0x01);
+ CHECK_ERR(err);
+
+ /* Set CATE_409 to 1(PREVIEW) */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_NEW, 0x09, 0x01);
+ CHECK_ERR(err);
+ break;
+
+ case MODE_WATERFALL:
+ /* Set CATE_408 to None */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_NEW, 0x08, 0x00);
+ CHECK_ERR(err);
+
+ /* Set HISTOGRAM ON */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_MON, 0x58, 0x01);
+ CHECK_ERR(err);
+
+ /* LIKE A PRO MODE SET */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_PRO_MODE, 0x01, 0x03);
+ CHECK_ERR(err);
+
+ /* LIKE A PRO STEP SET */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_PRO_MODE,
+ 0x02, state->widget_mode_level);
+ CHECK_ERR(err);
+
+ err = m9mo_writeb(sd, M9MO_CATEGORY_MON,
+ M9MO_MON_COLOR_EFFECT, state->color_effect);
+ CHECK_ERR(err);
+
+ /* Set LIKE_PRO_EN Enable */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_PRO_MODE, 0x00, 0x01);
+ CHECK_ERR(err);
+
+ /* Set CATE_409 to 1(PREVIEW) */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_NEW, 0x09, 0x01);
+ CHECK_ERR(err);
+ break;
+
+ case MODE_SILHOUETTE:
+ /* Set CATE_408 to None */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_NEW, 0x08, 0x00);
+ CHECK_ERR(err);
+
+ /* Set HISTOGRAM ON */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_MON, 0x58, 0x01);
+ CHECK_ERR(err);
+
+ /* LIKE A PRO MODE SET */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_PRO_MODE, 0x01, 0x04);
+ CHECK_ERR(err);
+
+ /* LIKE A PRO STEP SET */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_PRO_MODE,
+ 0x02, state->widget_mode_level);
+ CHECK_ERR(err);
+
+ /* Set Color effect */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_MON,
+ M9MO_MON_COLOR_EFFECT, state->color_effect);
+ CHECK_ERR(err);
+
+ /* Set LIKE_PRO_EN Enable */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_PRO_MODE, 0x00, 0x01);
+ CHECK_ERR(err);
+
+ /* Set CATE_409 to 1(PREVIEW) */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_NEW, 0x09, 0x01);
+ CHECK_ERR(err);
+ break;
+
+ case MODE_SUNSET:
+ /* Set CATE_408 to None */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_NEW, 0x08, 0x00);
+ CHECK_ERR(err);
+
+ /* Set HISTOGRAM ON */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_MON, 0x58, 0x01);
+ CHECK_ERR(err);
+
+ /* LIKE A PRO MODE SET */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_PRO_MODE, 0x01, 0x05);
+ CHECK_ERR(err);
+
+ /* LIKE A PRO STEP SET */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_PRO_MODE,
+ 0x02, state->widget_mode_level);
+ CHECK_ERR(err);
+
+ err = m9mo_writeb(sd, M9MO_CATEGORY_MON,
+ M9MO_MON_COLOR_EFFECT, state->color_effect);
+ CHECK_ERR(err);
+
+ /* Set LIKE_PRO_EN Enable */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_PRO_MODE, 0x00, 0x01);
+ CHECK_ERR(err);
+
+ /* Set CATE_409 to 1(PREVIEW) */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_NEW, 0x09, 0x01);
+ CHECK_ERR(err);
+ break;
+
+ case MODE_CLOSE_UP:
+ /* Set CATE_408 to None */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_NEW, 0x08, 0x00);
+ CHECK_ERR(err);
+
+ /* Set HISTOGRAM ON */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_MON, 0x58, 0x01);
+ CHECK_ERR(err);
+
+ /* LIKE A PRO MODE SET */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_PRO_MODE, 0x01, 0x06);
+ CHECK_ERR(err);
+
+ /* LIKE A PRO STEP SET */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_PRO_MODE,
+ 0x02, state->widget_mode_level);
+ CHECK_ERR(err);
+
+ err = m9mo_writeb(sd, M9MO_CATEGORY_MON,
+ M9MO_MON_COLOR_EFFECT, state->color_effect);
+ CHECK_ERR(err);
+
+ /* Set LIKE_PRO_EN Enable */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_PRO_MODE, 0x00, 0x01);
+ CHECK_ERR(err);
+
+ /* Set CATE_409 to 1(PREVIEW) */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_NEW, 0x09, 0x01);
+ CHECK_ERR(err);
+ break;
+
+ case MODE_FIREWORKS:
+ /* Set CATE_408 to None */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_NEW, 0x08, 0x00);
+ CHECK_ERR(err);
+
+ /* Set HISTOGRAM ON */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_MON, 0x58, 0x01);
+ CHECK_ERR(err);
+
+ /* LIKE A PRO MODE SET */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_PRO_MODE, 0x01, 0x07);
+ CHECK_ERR(err);
+
+ /* LIKE A PRO STEP SET */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_PRO_MODE,
+ 0x02, state->widget_mode_level);
+ CHECK_ERR(err);
+
+ err = m9mo_writeb(sd, M9MO_CATEGORY_MON,
+ M9MO_MON_COLOR_EFFECT, state->color_effect);
+ CHECK_ERR(err);
+
+ /* Set LIKE_PRO_EN Enable */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_PRO_MODE, 0x00, 0x01);
+ CHECK_ERR(err);
+
+ /* Set CATE_409 to 1(PREVIEW) */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_NEW, 0x09, 0x01);
+ CHECK_ERR(err);
+ break;
+
+ case MODE_BACKLIGHT:
+ /* Set CATE_408 to None */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_NEW, 0x08, 0x00);
+ CHECK_ERR(err);
+
+ /* Set HISTOGRAM ON */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_MON, 0x58, 0x01);
+ CHECK_ERR(err);
+
+ /* LIKE A PRO MODE SET */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_PRO_MODE, 0x01, 0x0A);
+ CHECK_ERR(err);
+
+ /* LIKE A PRO STEP SET */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_PRO_MODE,
+ 0x02, state->widget_mode_level);
+ CHECK_ERR(err);
+
+ err = m9mo_writeb(sd, M9MO_CATEGORY_MON,
+ M9MO_MON_COLOR_EFFECT, state->color_effect);
+ CHECK_ERR(err);
+
+ /* Set LIKE_PRO_EN Enable */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_PRO_MODE, 0x00, 0x01);
+ CHECK_ERR(err);
+
+ /* Set CATE_409 to 1(PREVIEW) */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_NEW, 0x09, 0x01);
+ CHECK_ERR(err);
+ break;
+
+ case MODE_BLUE_SKY:
+ /* Set CATE_408 to None */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_NEW, 0x08, 0x00);
+ CHECK_ERR(err);
+
+ /* Set HISTOGRAM ON */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_MON, 0x58, 0x01);
+ CHECK_ERR(err);
+
+ /* LIKE A PRO MODE SET */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_PRO_MODE, 0x01, 0x08);
+ CHECK_ERR(err);
+
+ /* LIKE A PRO STEP SET */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_PRO_MODE,
+ 0x02, state->widget_mode_level);
+ CHECK_ERR(err);
+
+ /* COLOR EFFECT SET */
+ err = m9mo_readb(sd, M9MO_CATEGORY_MON,
+ M9MO_MON_COLOR_EFFECT, &color_effect);
+ CHECK_ERR(err);
+
+ if (color_effect < 0x11)
+ state->color_effect = color_effect;
+
+ err = m9mo_writeb(sd, M9MO_CATEGORY_MON,
+ M9MO_MON_COLOR_EFFECT, 0x11 + state->widget_mode_level);
+ CHECK_ERR(err);
+
+ /* Set LIKE_PRO_EN Enable */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_PRO_MODE, 0x00, 0x01);
+ CHECK_ERR(err);
+
+ /* Set CATE_409 to 1(PREVIEW) */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_NEW, 0x09, 0x01);
+ CHECK_ERR(err);
+ break;
+
+ case MODE_NATURAL_GREEN:
+ /* Set CATE_408 to None */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_NEW, 0x08, 0x00);
+ CHECK_ERR(err);
+
+ /* Set HISTOGRAM ON */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_MON, 0x58, 0x01);
+ CHECK_ERR(err);
+
+ /* LIKE A PRO MODE SET */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_PRO_MODE, 0x01, 0x09);
+ CHECK_ERR(err);
+
+ /* LIKE A PRO STEP SET */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_PRO_MODE,
+ 0x02, state->widget_mode_level);
+ CHECK_ERR(err);
+
+ /* COLOR EFFECT SET */
+ err = m9mo_readb(sd, M9MO_CATEGORY_MON,
+ M9MO_MON_COLOR_EFFECT, &color_effect);
+ CHECK_ERR(err);
+
+ if (color_effect < 0x11)
+ state->color_effect = color_effect;
+
+ err = m9mo_writeb(sd, M9MO_CATEGORY_MON,
+ M9MO_MON_COLOR_EFFECT, 0x21 + state->widget_mode_level);
+ CHECK_ERR(err);
+
+ /* Set LIKE_PRO_EN Enable */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_PRO_MODE, 0x00, 0x01);
+ CHECK_ERR(err);
+
+ /* Set CATE_409 to 1(PREVIEW) */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_NEW, 0x09, 0x01);
+ CHECK_ERR(err);
+ break;
+
+ default:
+ break;
+ }
+
+ cam_trace("X\n");
+
+ return 0;
+}
+
+static int m9mo_set_shutter_speed(struct v4l2_subdev *sd, int val)
+{
+ struct m9mo_state *state = to_state(sd);
+ int err = 0;
+ int numerator = 1, denominator = 30;
+ cam_dbg("E, value %d\n", val);
+
+ if (state->mode > MODE_VIDEO) {
+ cam_trace("Don't set when like a pro !!!\n");
+ return 0;
+ }
+
+ switch (val) {
+ case 1:
+ numerator = 16;
+ denominator = 1;
+ break;
+
+ case 2:
+ numerator = 12;
+ denominator = 1;
+ break;
+
+ case 3:
+ numerator = 8;
+ denominator = 1;
+ break;
+
+ case 4:
+ numerator = 6;
+ denominator = 1;
+ break;
+
+ case 5:
+ numerator = 4;
+ denominator = 1;
+ break;
+
+ case 6:
+ numerator = 3;
+ denominator = 1;
+ break;
+
+ case 7:
+ numerator = 2;
+ denominator = 1;
+ break;
+
+ case 8:
+ numerator = 15;
+ denominator = 10;
+ break;
+
+ case 9:
+ numerator = 1;
+ denominator = 1;
+ break;
+
+ case 10:
+ numerator = 7;
+ denominator = 10;
+ break;
+
+ case 11:
+ numerator = 5;
+ denominator = 10;
+ break;
+
+ case 12:
+ numerator = 1;
+ denominator = 3;
+ break;
+
+ case 13:
+ numerator = 1;
+ denominator = 4;
+ break;
+
+ case 14:
+ numerator = 1;
+ denominator = 6;
+ break;
+
+ case 15:
+ numerator = 1;
+ denominator = 8;
+ break;
+
+ case 16:
+ numerator = 1;
+ denominator = 15;
+ break;
+
+ case 17:
+ numerator = 1;
+ denominator = 20;
+ break;
+
+ case 18:
+ numerator = 1;
+ denominator = 30;
+ break;
+
+ case 19:
+ numerator = 1;
+ denominator = 45;
+ break;
+
+ case 20:
+ numerator = 1;
+ denominator = 60;
+ break;
+
+ case 21:
+ numerator = 1;
+ denominator = 90;
+ break;
+
+ case 22:
+ numerator = 1;
+ denominator = 125;
+ break;
+
+ case 23:
+ numerator = 1;
+ denominator = 180;
+ break;
+
+ case 24:
+ numerator = 1;
+ denominator = 250;
+ break;
+
+ case 25:
+ numerator = 1;
+ denominator = 350;
+ break;
+
+ case 26:
+ numerator = 1;
+ denominator = 500;
+ break;
+
+ case 27:
+ numerator = 1;
+ denominator = 750;
+ break;
+
+ case 28:
+ numerator = 1;
+ denominator = 1000;
+ break;
+
+ case 29:
+ numerator = 1;
+ denominator = 1500;
+ break;
+
+ case 30:
+ numerator = 1;
+ denominator = 2000;
+ break;
+
+ default:
+ break;
+ }
+
+ state->numerator = numerator;
+ state->denominator = denominator;
+
+ /* Set Capture Shutter Speed Time */
+ err = m9mo_writew(sd, M9MO_CATEGORY_AE,
+ M9MO_AE_EV_PRG_SS_NUMERATOR, numerator);
+ CHECK_ERR(err);
+ err = m9mo_writew(sd, M9MO_CATEGORY_AE,
+ M9MO_AE_EV_PRG_SS_DENOMINATOR, denominator);
+ CHECK_ERR(err);
+
+ cam_trace("X\n");
+ return 0;
+}
+
+static int m9mo_set_f_number(struct v4l2_subdev *sd, int val)
+{
+ struct m9mo_state *state = to_state(sd);
+ int err = 0;
+
+ cam_dbg("E, value %d\n", val);
+
+ /* Max value : 15.9 */
+ if (val > 159)
+ val = 159;
+
+ val = (val / 10) * 16 + (val % 10);
+ state->f_number = val;
+
+ /* Set Still Capture F-Number Value */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_AE,
+ M9MO_AE_EV_PRG_F_NUMBER, val);
+ CHECK_ERR(err);
+
+ cam_trace("X\n");
+ return 0;
+}
+
+static int m9mo_set_wb_custom(struct v4l2_subdev *sd, int val)
+{
+ struct m9mo_state *state = to_state(sd);
+ int err = 0;
+
+ cam_dbg("E\n");
+
+ err = m9mo_writeb(sd, M9MO_CATEGORY_WB,
+ M9MO_WB_AWB_MODE, 0x02);
+ CHECK_ERR(err);
+
+ err = m9mo_writeb(sd, M9MO_CATEGORY_WB,
+ M9MO_WB_AWB_MANUAL, 0x08);
+ CHECK_ERR(err);
+
+ err = m9mo_writeb(sd, M9MO_CATEGORY_WB,
+ M9MO_WB_CWB_MODE, 0x02);
+ CHECK_ERR(err);
+
+ err = m9mo_writew(sd, M9MO_CATEGORY_WB,
+ M9MO_WB_SET_CUSTOM_RG, state->wb_custom_rg);
+ CHECK_ERR(err);
+
+ err = m9mo_writew(sd, M9MO_CATEGORY_WB,
+ M9MO_WB_SET_CUSTOM_BG, state->wb_custom_bg);
+ CHECK_ERR(err);
+
+ err = m9mo_writeb(sd, M9MO_CATEGORY_WB,
+ M9MO_WB_CWB_MODE, 0x01);
+ CHECK_ERR(err);
+
+ cam_trace("X\n");
+ return 0;
+}
+
+static int m9mo_set_smart_auto_s1_push(struct v4l2_subdev *sd, int val)
+{
+ struct m9mo_state *state = to_state(sd);
+ int int_factor, err;
+
+ cam_dbg("E val : %d\n", val);
+
+ if (state->mode == MODE_SMART_AUTO ||
+ state->mode >= MODE_BACKGROUND_BLUR) {
+ if (val == 1) {
+ err = m9mo_writeb(sd, M9MO_CATEGORY_NEW, 0x09, 0x02);
+ CHECK_ERR(err);
+ } else if (val == 2) {
+ err = m9mo_writeb(sd, M9MO_CATEGORY_NEW, 0x09, 0x04);
+ CHECK_ERR(err);
+
+ int_factor = m9mo_wait_interrupt(sd, M9MO_ISP_TIMEOUT);
+ if (!(int_factor & M9MO_INT_ATSCENE_UPDATE)) {
+ cam_err("M9MO_INT_ATSCENE_UPDATE isn't issued, %#x\n",
+ int_factor);
+ return -ETIMEDOUT;
+ }
+ CHECK_ERR(err);
+ } else {
+ err = m9mo_writeb(sd, M9MO_CATEGORY_NEW, 0x09, 0x03);
+ CHECK_ERR(err);
+ }
+ }
+ cam_trace("X\n");
+ return 0;
+}
+
+static int m9mo_set_mon_size(struct v4l2_subdev *sd, int val)
+{
+ struct m9mo_state *state = to_state(sd);
+ int err, vss_val;
+ u32 size_val;
+
+ if (state->isp_fw_ver < 0xA02B) {
+ cam_dbg("%x firmware cannot working quick monitor mode\n",
+ state->isp_fw_ver);
+ return 0;
+ }
+
+ cam_dbg("E\n");
+
+ if (state->fps == 60) {
+ if (state->preview_height == 480)
+ size_val = 0x2F;
+ else if (state->preview_height == 720)
+ size_val = 0x25;
+ vss_val = 0;
+ } else if (state->sensor_mode == SENSOR_MOVIE
+ && state->fps == 30) {
+ if (state->preview_height == 1080)
+ size_val = 0x2C;
+ else if (state->preview_height == 720)
+ size_val = 0x2D;
+ else if (state->preview_height == 480)
+ size_val = 0x2E;
+ else if (state->preview_height == 240)
+ size_val = 0x36;
+ vss_val = 1;
+ } else {
+ if (state->preview_width == 640)
+ size_val = 0x17;
+ else if (state->preview_width == 768)
+ size_val = 0x33;
+ else if (state->preview_width == 960)
+ size_val = 0x34;
+ else if (state->preview_width == 1056)
+ size_val = 0x35;
+ else if (state->preview_width == 1280)
+ size_val = 0x21;
+ vss_val = 0;
+ }
+
+ if (val == 1080) {
+ size_val = 0x2C;
+ vss_val = 1;
+ }
+
+ err = m9mo_writeb(sd, M9MO_CATEGORY_PARM,
+ M9MO_PARM_MON_SIZE, size_val);
+ CHECK_ERR(err);
+
+ m9mo_set_dual_capture_mode(sd, vss_val);
+
+ err = m9mo_writeb(sd, M9MO_CATEGORY_CAPCTRL, 0x25, 0x01);
+ CHECK_ERR(err);
+
+ cam_trace("start quick monitor mode !!!\n");
+ err = m9mo_writeb(sd, M9MO_CATEGORY_PARM, 0x7C, 0x01);
+ CHECK_ERR(err);
+
+ cam_trace("X\n");
+ return 0;
+}
+
static int m9mo_check_dataline(struct v4l2_subdev *sd, int val)
{
int err = 0;
@@ -2961,10 +8425,21 @@ static int m9mo_check_esd(struct v4l2_subdev *sd)
s32 val = 0;
int err = 0;
+ struct m9mo_state *state = to_state(sd);
+
+ if (state->factory_test_num != 0) {
+ cam_dbg("factory test mode !!! ignore esd check\n");
+ return 0;
+ }
+
/* check ISP */
+#if 0 /* TO DO */
err = m9mo_readb(sd, M9MO_CATEGORY_TEST, M9MO_TEST_ISP_PROCESS, &val);
CHECK_ERR(err);
cam_dbg("progress %#x\n", val);
+#else
+ val = 0x80;
+#endif
if (val != 0x80) {
goto esd_occur;
@@ -2989,12 +8464,80 @@ esd_occur:
static int m9mo_g_ext_ctrl(struct v4l2_subdev *sd,
struct v4l2_ext_control *ctrl)
{
- struct m9mo_state *state = to_state(sd);
- int err = 0;
+ int err = 0, i = 0;
+
+ char *buf = NULL;
+
+ int size = 0, rtn = 0, cmd_size = 0;
+ u8 category = 0, sub = 0;
+ u32 addr = 0;
+
+ size = ctrl->size;
+
+ cam_dbg("ISPD m9mo_g_ext_ctrl() id=%d, size=%d\n",
+ ctrl->id, ctrl->size);
+
+ if (size > 4096)
+ return -1;
switch (ctrl->id) {
- case V4L2_CID_CAM_SENSOR_FW_VER:
- strcpy(ctrl->string, state->exif.unique_id);
+ case V4L2_CID_ISP_DEBUG_READ:
+
+ cmd_size = 2;
+ if (size < cmd_size+1) /* category:1, sub:1, data:>1 */
+ return -2;
+
+ buf = kmalloc(ctrl->size, GFP_KERNEL);
+ if (copy_from_user(buf, (void __user *)ctrl->string, size)) {
+ err = -1;
+ break;
+ }
+
+ category = buf[0];
+ sub = buf[1];
+
+ memset(buf, 0, size-cmd_size);
+ for (i = 0; i < size-cmd_size; i++) {
+ err = m9mo_readb(sd, category, sub+i, &rtn);
+ buf[i] = rtn;
+ cam_dbg("ISPD m9mo_readb(sd, %x, %x, %x\n",
+ category, sub+i, buf[i]);
+ CHECK_ERR(err);
+ }
+
+ if (copy_to_user((void __user *)ctrl->string,
+ buf, size-cmd_size))
+ err = -1;
+
+ kfree(buf);
+ break;
+
+ case V4L2_CID_ISP_DEBUG_READ_MEM:
+
+ cmd_size = 4;
+ if (size < cmd_size+1) /* cmd size : 4, data : >1 */
+ return -2;
+
+ buf = kmalloc(ctrl->size, GFP_KERNEL);
+ if (copy_from_user(buf, (void __user *)ctrl->string, size)) {
+ err = -1;
+ break;
+ }
+
+ addr = buf[0]<<24|buf[1]<<16|buf[2]<<8|buf[3];
+
+ memset(buf, 0, size-cmd_size);
+ err = m9mo_mem_read(sd, size-cmd_size, addr, buf);
+ cam_dbg("ISPD m9mo_mem_read7(sd, %x, %d)\n",
+ addr, size-cmd_size);
+ if (err < 0)
+ cam_err("i2c falied, err %d\n", err);
+
+ if (copy_to_user((void __user *)ctrl->string,
+ buf, size-cmd_size))
+ err = -1;
+
+ kfree(buf);
break;
default:
@@ -3030,6 +8573,204 @@ static int m9mo_g_ext_ctrls(struct v4l2_subdev *sd,
return err;
}
+static int m9mo_makeLog(struct v4l2_subdev *sd, char *filename)
+{
+ int addr = 0, len = 0xff; /* init */
+ int err = 0;
+ int i = 0, no = 0;
+ char buf[256];
+
+ struct file *fp;
+ mm_segment_t old_fs;
+ char filepath[256];
+
+ old_fs = get_fs();
+ set_fs(KERNEL_DS);
+
+ sprintf(filepath, "/sdcard/ISPD/%s%c", filename, 0);
+
+ fp = filp_open(filepath,
+ O_WRONLY|O_CREAT|O_TRUNC, S_IRUGO|S_IWUGO|S_IXUSR);
+ if (IS_ERR(fp)) {
+ cam_err("failed to open %s, err %ld\n",
+ filepath, PTR_ERR(fp));
+ return -1;
+ }
+
+ err = m9mo_writeb(sd, 0x0d, 0x06, 0x0);
+ CHECK_ERR(err);
+
+ err = m9mo_readl(sd, 0x0d, 0x08, &addr);
+ CHECK_ERR(err);
+
+ err = m9mo_writeb(sd, 0x0d, 0x0e, 0x2);
+ CHECK_ERR(err);
+
+ while (no < 10000) { /* max log count : 10000 */
+ err = m9mo_writew(sd, 0x0d, 0x0c, no);
+ CHECK_ERR(err);
+
+ err = m9mo_writeb(sd, 0x0d, 0x0e, 0x3);
+ CHECK_ERR(err);
+
+ while (len == 0xff) {
+ err = m9mo_readb(sd, 0x0d, 0x07, &len);
+ CHECK_ERR(err);
+
+ if (i++ > 3000) /* only delay code */
+ break;
+ }
+
+ if (len == 0 || len == 0xff) {
+ err = m9mo_writeb(sd, 0x0d, 0x0e, 0x1);
+ CHECK_ERR(err);
+ break;
+ }
+
+ i = 0;
+ len += 1;
+ if (len > sizeof(buf))
+ len = sizeof(buf);
+ err = m9mo_mem_read(sd, len, addr, buf);
+ if (err < 0)
+ cam_err("ISPD i2c falied, err %d\n", err);
+
+ buf[len-1] = '\n';
+
+ vfs_write(fp, buf, len, &fp->f_pos);
+#if 0
+ cam_dbg("ISPD Log : %x[%d], %d, %32s)\n",
+ addr, no, len, buf);
+#endif
+ len = 0xff; /* init */
+ no++;
+ }
+
+ if (!IS_ERR(fp))
+ filp_close(fp, current->files);
+
+ set_fs(old_fs);
+
+ return 0;
+}
+
+static int m9mo_s_ext_ctrl(struct v4l2_subdev *sd,
+ struct v4l2_ext_control *ctrl)
+{
+ int err = 0, i = 0;
+ char *buf = NULL;
+
+ int size = 0, cmd_size = 0;
+ u8 category = 0, sub = 0;
+ u32 addr = 0;
+
+ size = ctrl->size;
+
+ if (size > 1024)
+ return -1;
+
+ switch (ctrl->id) {
+ case V4L2_CID_ISP_DEBUG_WRITE:
+
+ cmd_size = 2;
+ if (size < cmd_size+1)
+ return -2;
+
+ buf = kmalloc(ctrl->size, GFP_KERNEL);
+ if (copy_from_user(buf, (void __user *)ctrl->string, size)) {
+ err = -1;
+ break;
+ }
+
+ category = buf[0];
+ sub = buf[1];
+
+ cam_dbg("ISP_DBG write() %x%x%x\n", buf[0], buf[1], buf[2]);
+
+ for (i = 0; i < size-cmd_size; i++) {
+ err = m9mo_writeb(sd, category, sub+i, buf[i+cmd_size]);
+ cam_dbg("ISPD m9mo_writeb(sd, %x, %x, %x\n",
+ category, sub+i, buf[i+cmd_size]);
+ CHECK_ERR(err);
+ }
+
+ kfree(buf);
+ break;
+
+ case V4L2_CID_ISP_DEBUG_WRITE_MEM:
+
+ cmd_size = 4;
+ if (size < cmd_size+1)
+ return -2;
+
+ buf = kmalloc(ctrl->size, GFP_KERNEL);
+ if (copy_from_user(buf,
+ (void __user *)ctrl->string, size)) {
+ err = -1;
+ break;
+ }
+
+ addr = buf[0]<<24|buf[1]<<16|buf[2]<<8|buf[3];
+
+ cam_dbg("ISP_DBG write_mem() 0x%08x, size=%d\n",
+ addr, size);
+
+ err = m9mo_mem_write(sd, 0x04,
+ size-cmd_size, addr, buf+cmd_size);
+ cam_dbg("ISPD m9mo_mem_write(sd, %x, %d)\n",
+ addr, size-cmd_size);
+ if (err < 0)
+ cam_err("i2c falied, err %d\n", err);
+
+ kfree(buf);
+ break;
+
+ case V4L2_CID_ISP_DEBUG_LOGV:
+
+ if (size > 0) {
+ buf = kmalloc(ctrl->size+1, GFP_KERNEL);
+ if (copy_from_user(buf,
+ (void __user *)ctrl->string, size)) {
+ err = -1;
+ break;
+ }
+ buf[size] = 0;
+
+ m9mo_makeLog(sd, buf);
+
+ kfree(buf);
+ } else {
+ m9mo_makeLog(sd, "default.log");
+ }
+
+ break;
+
+ default:
+ cam_err("no such control id %d\n",
+ ctrl->id - V4L2_CID_CAMERA_CLASS_BASE);
+ break;
+ }
+
+ return err;
+}
+
+
+static int m9mo_s_ext_ctrls(struct v4l2_subdev *sd,
+ struct v4l2_ext_controls *ctrls)
+{
+ struct v4l2_ext_control *ctrl = ctrls->controls;
+ int i, err = 0;
+
+ for (i = 0; i < ctrls->count; i++, ctrl++) {
+ err = m9mo_s_ext_ctrl(sd, ctrl);
+ if (err) {
+ ctrls->error_idx = i;
+ break;
+ }
+ }
+ return err;
+}
+
static int m9mo_check_manufacturer_id(struct v4l2_subdev *sd)
{
int i, err;
@@ -3132,6 +8873,7 @@ static int m9mo_load_fw_main(struct v4l2_subdev *sd)
struct device *dev = sd->v4l2_dev->dev;
const struct firmware *fw = NULL;
u8 *buf_m9mo = NULL;
+ unsigned int count = 0;
/*int offset;*/
int err = 0;
@@ -3152,8 +8894,10 @@ static int m9mo_load_fw_main(struct v4l2_subdev *sd)
fw_requested = 0;
fsize = fp->f_path.dentry->d_inode->i_size;
+ count = fsize / SZ_4K;
- cam_err("start, file path %s, size %ld Bytes\n", M9MO_FW_PATH, fsize);
+ cam_err("start, file path %s, size %ld Bytes, count %d\n",
+ M9MO_FW_PATH, fsize, count);
buf_m9mo = vmalloc(fsize);
if (!buf_m9mo) {
@@ -3174,16 +8918,24 @@ static int m9mo_load_fw_main(struct v4l2_subdev *sd)
request_fw:
if (fw_requested) {
set_fs(old_fs);
+ if (system_rev > 1) {
+ cam_info("Firmware Path = %s\n",
+ M9MO_EVT31_FW_REQ_PATH);
+ err = request_firmware(&fw,
+ M9MO_EVT31_FW_REQ_PATH, dev);
+ } else {
+ cam_info("Firmware Path = %s\n", M9MO_FW_REQ_PATH);
+ err = request_firmware(&fw, M9MO_FW_REQ_PATH, dev);
+ }
- cam_info("Firmware Path = %s\n", M9MO_FW_REQ_PATH);
- err = request_firmware(&fw, M9MO_FW_REQ_PATH, dev);
if (err != 0) {
cam_err("request_firmware failed\n");
err = -EINVAL;
goto out;
}
- cam_dbg("start, size %d Bytes\n", fw->size);
+ count = fw->size / SZ_4K;
+ cam_err("start, size %d Bytes count = %d\n", fw->size, count);
buf_m9mo = (u8 *)fw->data;
}
@@ -3212,7 +8964,7 @@ request_fw:
mdelay(10);
/* program FLASH ROM */
- err = m9mo_program_fw(sd, buf_m9mo, M9MO_FLASH_BASE_ADDR, SZ_4K, 512);
+ err = m9mo_program_fw(sd, buf_m9mo, M9MO_FLASH_BASE_ADDR, SZ_4K, count);
if (err < 0)
goto out;
@@ -3414,7 +9166,7 @@ request_fw:
if (fw_requested) {
set_fs(old_fs);
- m9mo_get_sensor_fw_version(sd, sensor_ver);
+ m9mo_get_sensor_fw_version(sd);
if (sensor_ver[0] == 'T' && sensor_ver[1] == 'B') {
err = request_firmware(&fw, M9MOTB_FW_PATH, dev);
@@ -3506,16 +9258,24 @@ static int m9mo_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
{
struct m9mo_state *state = to_state(sd);
int err = 0;
+ int int_en = 0;
+ s16 temp;
- cam_trace(" id %d, value %d\n",
+ if (ctrl->id != V4L2_CID_CAMERA_LENS_TIMER) {
+ cam_trace(" id %d, value %d\n",
ctrl->id - V4L2_CID_PRIVATE_BASE, ctrl->value);
+ }
if (unlikely(state->isp.bad_fw && ctrl->id != V4L2_CID_CAM_UPDATE_FW)) {
cam_err("\"Unknown\" state, please update F/W");
- return -ENOSYS;
+ return 0;
}
switch (ctrl->id) {
+ case V4L2_CID_CAMERA_HOLD_LENS:
+ leave_power = true;
+ break;
+
case V4L2_CID_CAM_UPDATE_FW:
if (ctrl->value == FW_MODE_DUMP)
err = m9mo_dump_fw(sd);
@@ -3548,6 +9308,18 @@ static int m9mo_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
err = m9mo_set_exposure(sd, ctrl);
break;
+ case V4L2_CID_CAMERA_SHARPNESS:
+ err = m9mo_set_sharpness(sd, ctrl);
+ break;
+
+ case V4L2_CID_CAMERA_CONTRAST:
+ err = m9mo_set_contrast(sd, ctrl);
+ break;
+
+ case V4L2_CID_CAMERA_SATURATION:
+ err = m9mo_set_saturation(sd, ctrl);
+ break;
+
case V4L2_CID_CAMERA_WHITE_BALANCE:
err = m9mo_set_whitebalance(sd, ctrl->value);
break;
@@ -3582,6 +9354,7 @@ static int m9mo_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
case V4L2_CID_CAMERA_OBJECT_POSITION_X:
state->focus.pos_x = ctrl->value;
+ #if 0
/* FIXME - It should be fixed on F/W (touch AF offset) */
if (state->preview != NULL) {
if (state->exif.unique_id[0] == 'T') {
@@ -3592,10 +9365,12 @@ static int m9mo_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
state->focus.pos_x -= 50;
}
}
+ #endif
break;
case V4L2_CID_CAMERA_OBJECT_POSITION_Y:
state->focus.pos_y = ctrl->value;
+ #if 0
/* FIXME - It should be fixed on F/W (touch AF offset) */
if (state->preview != NULL) {
if (state->preview->index == M9MO_PREVIEW_VGA) {
@@ -3608,22 +9383,23 @@ static int m9mo_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
state->focus.pos_y += 60;
}
}
+ #endif
break;
case V4L2_CID_CAMERA_TOUCH_AF_START_STOP:
err = m9mo_set_touch_auto_focus(sd, ctrl->value);
break;
- case V4L2_CID_CAMERA_ZOOM:
- err = m9mo_set_zoom(sd, ctrl);
+ case V4L2_CID_CAMERA_AF_LED:
+ err = m9mo_set_AF_LED(sd, ctrl->value);
break;
- case V4L2_CID_CAMERA_OPTICAL_ZOOM_STEP:
- err = m9mo_set_optical_zoom_step(sd, ctrl);
+ case V4L2_CID_CAMERA_ZOOM:
+ err = m9mo_set_zoom(sd, ctrl);
break;
case V4L2_CID_CAMERA_OPTICAL_ZOOM_CTRL:
- err = m9mo_set_optical_zoom_ctrl(sd, ctrl->value);
+ err = m9mo_set_zoom_ctrl(sd, ctrl->value);
break;
case V4L2_CID_CAM_JPEG_QUALITY:
@@ -3634,6 +9410,10 @@ static int m9mo_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
err = m9mo_start_capture(sd, ctrl->value);
break;
+ case V4L2_CID_CAMERA_CAPTURE_THUMB:
+ err = m9mo_start_capture_thumb(sd, ctrl->value);
+ break;
+
case V4L2_CID_CAMERA_YUV_CAPTURE:
err = m9mo_start_YUV_capture(sd, ctrl->value);
break;
@@ -3686,9 +9466,28 @@ static int m9mo_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
err = m9mo_set_bracket_wbb(sd, ctrl->value);
break;
+ case V4L2_CID_CAMERA_IMAGE_STABILIZER:
+ err = m9mo_set_image_stabilizer_mode(sd, ctrl->value);
+ break;
+
+ case V4L2_CID_CAMERA_IS_OIS_MODE:
+ err = m9mo_set_image_stabilizer_OIS(sd, ctrl->value);
+ break;
+
+ case V4L2_CID_CAMERA_FOCUS_AREA_MODE:
+ err = m9mo_set_focus_area_mode(sd, ctrl->value);
+ break;
+
+ case V4L2_CID_CAMERA_OBJ_TRACKING_START_STOP:
+ err = m9mo_set_object_tracking(sd, ctrl->value);
+ break;
+
case V4L2_CID_CAMERA_FRAME_RATE:
err = m9mo_set_fps(sd, ctrl->value);
- state->fps = ctrl->value;
+ break;
+
+ case V4L2_CID_CAMERA_SMART_ZOOM:
+ err = m9mo_set_smart_zoom(sd, ctrl->value);
break;
case V4L2_CID_CAMERA_LDC:
@@ -3699,8 +9498,953 @@ static int m9mo_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
err = m9mo_set_LSC(sd, ctrl->value);
break;
- case V4L2_CID_CAM_APERTURE:
- err = m9mo_set_aperture(sd, ctrl->value);
+ case V4L2_CID_CAMERA_WIDGET_MODE_LEVEL:
+ err = m9mo_set_widget_mode_level(sd, ctrl->value);
+ break;
+
+ case V4L2_CID_CAMERA_PREVIEW_WIDTH:
+ state->preview_width = ctrl->value;
+ break;
+
+ case V4L2_CID_CAMERA_PREVIEW_HEIGHT:
+ state->preview_height = ctrl->value;
+ break;
+
+ case V4L2_CID_CAMERA_PREVIEW_SIZE:
+ err = m9mo_set_mon_size(sd, ctrl->value);
+ break;
+
+ case V4L2_CID_CAM_APERTURE_PREVIEW:
+ err = m9mo_set_aperture_preview(sd, ctrl->value);
+ break;
+
+ case V4L2_CID_CAM_APERTURE_CAPTURE:
+ err = m9mo_set_aperture_capture(sd, ctrl->value);
+ break;
+
+ case V4L2_CID_CAMERA_FACTORY_OIS:
+ err = m9mo_set_factory_OIS(sd, ctrl->value);
+ break;
+
+ case V4L2_CID_CAMERA_FACTORY_OIS_SHIFT:
+ err = m9mo_set_factory_OIS_shift(sd, ctrl->value);
+ break;
+
+ case V4L2_CID_CAMERA_FACTORY_PUNT:
+ err = m9mo_set_factory_punt(sd, ctrl->value);
+ break;
+
+ case V4L2_CID_CAMERA_FACTORY_PUNT_SHORT_SCAN_DATA:
+ cam_trace("FACTORY_PUNT_SHORT_SCAN_DATA : 0x%x\n", ctrl->value);
+ err = m9mo_writeb(sd, M9MO_CATEGORY_LENS,
+ 0x1B, (unsigned char)(ctrl->value));
+ CHECK_ERR(err);
+
+ cam_trace("~ FACTORY_PUNT_SHORT_SCAN_START ~\n");
+ err = m9mo_writeb(sd, M9MO_CATEGORY_LENS,
+ 0x0E, 0x01);
+ CHECK_ERR(err);
+ break;
+
+ case V4L2_CID_CAMERA_FACTORY_PUNT_LONG_SCAN_DATA:
+ cam_trace("FACTORY_PUNT_LONG_SCAN_DATA : 0x%x\n", ctrl->value);
+ err = m9mo_writeb(sd, M9MO_CATEGORY_LENS,
+ 0x1B, (unsigned char)(ctrl->value));
+ CHECK_ERR(err);
+
+ cam_trace("~ FACTORY_PUNT_LONG_SCAN_START ~\n");
+ err = m9mo_writeb(sd, M9MO_CATEGORY_LENS,
+ 0x0E, 0x02);
+ CHECK_ERR(err);
+ break;
+
+ case V4L2_CID_CAMERA_FACTORY_ZOOM:
+ err = m9mo_set_factory_zoom(sd, ctrl->value);
+ break;
+
+ case V4L2_CID_CAMERA_FACTORY_ZOOM_STEP:
+ err = m9mo_set_factory_zoom_step(sd, ctrl->value);
+ break;
+
+ case V4L2_CID_CAMERA_FACTORY_PUNT_RANGE_DATA_MIN:
+ state->f_punt_data.min = ctrl->value;
+ break;
+
+ case V4L2_CID_CAMERA_FACTORY_PUNT_RANGE_DATA_MAX:
+ state->f_punt_data.max = ctrl->value;
+ break;
+
+ case V4L2_CID_CAMERA_FACTORY_PUNT_RANGE_DATA_NUM:
+ state->f_punt_data.num = ctrl->value;
+ break;
+
+ case V4L2_CID_CAMERA_FACTORY_FAIL_STOP:
+ err = m9mo_set_factory_fail_stop(sd, ctrl->value);
+ break;
+
+ case V4L2_CID_CAMERA_FACTORY_NODEFOCUS:
+ err = m9mo_set_factory_nodefocus(sd, ctrl->value);
+ break;
+
+ case V4L2_CID_CAMERA_FACTORY_INTERPOLATION:
+ err = m9mo_set_factory_interpolation(sd, ctrl->value);
+ break;
+
+ case V4L2_CID_CAMERA_FACTORY_COMMON:
+ err = m9mo_set_factory_common(sd, ctrl->value);
+ break;
+
+ case V4L2_CID_CAMERA_FACTORY_VIB:
+ err = m9mo_set_factory_vib(sd, ctrl->value);
+ break;
+
+ case V4L2_CID_CAMERA_FACTORY_GYRO:
+ err = m9mo_set_factory_gyro(sd, ctrl->value);
+ break;
+
+ case V4L2_CID_CAMERA_FACTORY_BACKLASH:
+ err = m9mo_set_factory_backlash(sd, ctrl->value);
+ break;
+
+ case V4L2_CID_CAMERA_FACTORY_BACKLASH_COUNT:
+ err = m9mo_set_factory_backlash_count(sd, ctrl->value);
+ break;
+
+ case V4L2_CID_CAMERA_FACTORY_BACKLASH_MAXTHRESHOLD:
+ err = m9mo_writew(sd, M9MO_CATEGORY_LENS,
+ 0x1A, ctrl->value);
+ CHECK_ERR(err);
+ break;
+
+ case V4L2_CID_CAMERA_FACTORY_ZOOM_RANGE_CHECK_DATA_MIN:
+ state->f_zoom_data.range_min = ctrl->value;
+ break;
+
+ case V4L2_CID_CAMERA_FACTORY_ZOOM_RANGE_CHECK_DATA_MAX:
+ state->f_zoom_data.range_max = ctrl->value;
+ break;
+
+ case V4L2_CID_CAMERA_FACTORY_ZOOM_SLOPE_CHECK_DATA_MIN:
+ state->f_zoom_data.slope_min = ctrl->value;
+ break;
+
+ case V4L2_CID_CAMERA_FACTORY_ZOOM_SLOPE_CHECK_DATA_MAX:
+ state->f_zoom_data.slope_max = ctrl->value;
+ break;
+
+ case V4L2_CID_CAMERA_FACTORY_AF:
+ err = m9mo_set_factory_af(sd, ctrl->value);
+ break;
+
+ case V4L2_CID_CAMERA_FACTORY_AF_STEP_SET:
+ err = m9mo_set_factory_af_step(sd, ctrl->value);
+ break;
+
+ case V4L2_CID_CAMERA_FACTORY_AF_POSITION:
+ err = m9mo_set_factory_af_position(sd, ctrl->value);
+ break;
+
+ case V4L2_CID_CAMERA_FACTORY_DEFOCUS:
+ err = m9mo_set_factory_defocus(sd, ctrl->value);
+ break;
+
+ case V4L2_CID_CAMERA_FACTORY_DEFOCUS_WIDE:
+ err = m9mo_set_factory_defocus_wide(sd, ctrl->value);
+ break;
+
+ case V4L2_CID_CAMERA_FACTORY_DEFOCUS_TELE:
+ err = m9mo_set_factory_defocus_tele(sd, ctrl->value);
+ break;
+
+ case V4L2_CID_CAMERA_FACTORY_RESOL_CAP:
+ err = m9mo_set_factory_resol_cap(sd, ctrl->value);
+ break;
+ case V4L2_CID_CAMERA_SET_G_VALUE:
+ state->wb_g_value = ctrl->value;
+ break;
+
+ case V4L2_CID_CAMERA_SET_B_VALUE:
+ state->wb_b_value = ctrl->value;
+ break;
+
+ case V4L2_CID_CAMERA_SET_A_VALUE:
+ state->wb_a_value = ctrl->value;
+ break;
+
+ case V4L2_CID_CAMERA_SET_M_VALUE:
+ state->wb_m_value = ctrl->value;
+ break;
+
+ case V4L2_CID_CAMERA_SET_GBAM:
+ err = m9mo_set_GBAM(sd, ctrl->value);
+ break;
+
+ case V4L2_CID_CAMERA_SET_K_VALUE:
+ err = m9mo_set_K(sd, ctrl->value);
+ break;
+
+ case V4L2_CID_CAMERA_SET_FLASH_EVC_STEP:
+ err = m9mo_set_flash_evc_step(sd, ctrl->value);
+ break;
+
+ case V4L2_CID_CAMERA_FLASH_BATT_INFO:
+ err = m9mo_set_flash_batt_info(sd, ctrl->value);
+ break;
+
+ case V4L2_CID_CAMERA_FACTORY_OIS_RANGE_DATA_X_MIN:
+ cam_trace("==========Range X min Data : 0x%x, %d\n",
+ (short)ctrl->value, (short)ctrl->value);
+ err = m9mo_writew(sd, M9MO_CATEGORY_NEW,
+ 0x21, (short)(ctrl->value));
+ CHECK_ERR(err);
+ break;
+
+ case V4L2_CID_CAMERA_FACTORY_VIB_RANGE_DATA_X_MIN:
+ case V4L2_CID_CAMERA_FACTORY_GYRO_RANGE_DATA_X_MIN:
+ cam_trace("==========Range X min Data : 0x%x, %d\n",
+ (u16)ctrl->value, (u16)ctrl->value);
+ err = m9mo_writew(sd, M9MO_CATEGORY_NEW,
+ 0x21, (short)(ctrl->value));
+ CHECK_ERR(err);
+ break;
+
+ case V4L2_CID_CAMERA_FACTORY_OIS_RANGE_DATA_X_MAX:
+ cam_trace("==========Range X max Data : 0x%x, %d\n",
+ (short)ctrl->value, (short)ctrl->value);
+ err = m9mo_writew(sd, M9MO_CATEGORY_NEW,
+ 0x23, (short)(ctrl->value));
+ CHECK_ERR(err);
+ break;
+
+ case V4L2_CID_CAMERA_FACTORY_VIB_RANGE_DATA_X_MAX:
+ case V4L2_CID_CAMERA_FACTORY_GYRO_RANGE_DATA_X_MAX:
+ cam_trace("==========Range X max Data : 0x%x, %d\n",
+ (u16)ctrl->value, (u16)ctrl->value);
+ err = m9mo_writew(sd, M9MO_CATEGORY_NEW,
+ 0x23, (u16)(ctrl->value));
+ CHECK_ERR(err);
+ break;
+
+ case V4L2_CID_CAMERA_FACTORY_OIS_RANGE_DATA_Y_MIN:
+ err = m9mo_writew(sd, M9MO_CATEGORY_NEW,
+ 0x25, (short)(ctrl->value));
+ CHECK_ERR(err);
+ break;
+
+ case V4L2_CID_CAMERA_FACTORY_VIB_RANGE_DATA_Y_MIN:
+ case V4L2_CID_CAMERA_FACTORY_GYRO_RANGE_DATA_Y_MIN:
+ err = m9mo_writew(sd, M9MO_CATEGORY_NEW,
+ 0x25, (u16)(ctrl->value));
+ CHECK_ERR(err);
+ break;
+
+ case V4L2_CID_CAMERA_FACTORY_OIS_RANGE_DATA_Y_MAX:
+ err = m9mo_writew(sd, M9MO_CATEGORY_NEW,
+ 0x27, (short)(ctrl->value));
+ CHECK_ERR(err);
+ break;
+
+ case V4L2_CID_CAMERA_FACTORY_VIB_RANGE_DATA_Y_MAX:
+ case V4L2_CID_CAMERA_FACTORY_GYRO_RANGE_DATA_Y_MAX:
+ err = m9mo_writew(sd, M9MO_CATEGORY_NEW,
+ 0x27, (u16)(ctrl->value));
+ CHECK_ERR(err);
+ break;
+
+ case V4L2_CID_CAMERA_FACTORY_OIS_RANGE_DATA_X_GAIN:
+ err = m9mo_writew(sd, M9MO_CATEGORY_NEW,
+ 0x29, (short)(ctrl->value));
+ CHECK_ERR(err);
+ break;
+
+ case V4L2_CID_CAMERA_FACTORY_VIB_RANGE_DATA_PEAK_X:
+ err = m9mo_writew(sd, M9MO_CATEGORY_NEW,
+ 0x29, (u16)(ctrl->value));
+ CHECK_ERR(err);
+ break;
+
+ case V4L2_CID_CAMERA_FACTORY_OIS_RANGE_DATA_PEAK_X:
+ err = m9mo_writew(sd, M9MO_CATEGORY_NEW,
+ 0x2B, (short)(ctrl->value));
+ CHECK_ERR(err);
+ break;
+
+ case V4L2_CID_CAMERA_FACTORY_VIB_RANGE_DATA_PEAK_Y:
+ err = m9mo_writew(sd, M9MO_CATEGORY_NEW,
+ 0x2B, (u16)(ctrl->value));
+ CHECK_ERR(err);
+ break;
+
+ case V4L2_CID_CAMERA_FACTORY_OIS_RANGE_DATA_PEAK_Y:
+ err = m9mo_writew(sd, M9MO_CATEGORY_NEW,
+ 0x2D, (u16)(ctrl->value));
+ CHECK_ERR(err);
+ break;
+
+ case V4L2_CID_CAMERA_FACTORY_TEST_NUMBER:
+ cam_trace("==========FACTORY_TEST_NUMBER : 0x%x\n",
+ ctrl->value);
+
+ err = m9mo_readw(sd, M9MO_CATEGORY_SYS,
+ M9MO_SYS_INT_EN, &int_en);
+ CHECK_ERR(err);
+ int_en &= ~M9MO_INT_SOUND;
+ err = m9mo_writew(sd, M9MO_CATEGORY_SYS,
+ M9MO_SYS_INT_EN, int_en);
+ CHECK_ERR(err);
+
+ err = m9mo_writeb(sd, M9MO_CATEGORY_LENS,
+ 0x41, ctrl->value);
+ state->factory_test_num = ctrl->value;
+ CHECK_ERR(err);
+ break;
+
+ case V4L2_CID_SET_CONTINUE_FPS:
+ state->continueFps = ctrl->value;
+ break;
+
+ case V4L2_CID_CONTINUESHOT_PROC:
+ err = m9mo_continue_proc(sd, ctrl->value);
+ break;
+
+ case V4L2_CID_BURSTSHOT_PROC:
+ err = m9mo_burst_proc(sd, ctrl->value);
+ break;
+
+ case V4L2_CID_BURSTSHOT_SET_POSTVIEW_SIZE:
+ err = m9mo_burst_set_postview_size(sd, ctrl->value);
+ break;
+
+ case V4L2_CID_BURSTSHOT_SET_SNAPSHOT_SIZE:
+ err = m9mo_burst_set_snapshot_size(sd, ctrl->value);
+ break;
+
+#if 0
+ case V4L2_CID_CAMERA_DUAL_POSTVIEW:
+ err = m9mo_start_dual_postview(sd, ctrl->value);
+ break;
+
+ case V4L2_CID_CAMERA_DUAL_CAPTURE:
+ err = m9mo_start_dual_capture(sd, ctrl->value);
+ break;
+#endif
+
+ case V4L2_CID_CAMERA_SET_DUAL_CAPTURE:
+ err = m9mo_start_set_dual_capture(sd, ctrl->value);
+ break;
+
+ case V4L2_CID_CAMERA_DUAL_CAPTURE_MODE:
+ /*err = m9mo_set_dual_capture_mode(sd, ctrl->value);*/
+ break;
+
+ case V4L2_CID_CAMERA_FACTORY_AF_SCAN_LIMIT_MIN:
+ case V4L2_CID_CAMERA_FACTORY_AF_SCAN_RANGE_MIN:
+ temp = (short)((ctrl->value) & 0x0000FFFF);
+ cam_trace("==========Range min Data : 0x%x, %d\n",
+ temp, temp);
+ err = m9mo_writew(sd, M9MO_CATEGORY_LENS,
+ 0x18, temp);
+ CHECK_ERR(err);
+ break;
+
+ case V4L2_CID_CAMERA_FACTORY_AF_SCAN_LIMIT_MAX:
+ case V4L2_CID_CAMERA_FACTORY_AF_SCAN_RANGE_MAX:
+ err = m9mo_writew(sd, M9MO_CATEGORY_LENS,
+ 0x1A, (u16)(ctrl->value));
+ CHECK_ERR(err);
+ break;
+
+ case V4L2_CID_CAMERA_FACTORY_AF_LENS:
+ err = m9mo_set_factory_af_lens(sd, ctrl->value);
+ break;
+
+ case V4L2_CID_CAMERA_FACTORY_AF_ZONE:
+ err = m9mo_set_factory_af_zone(sd, ctrl->value);
+ break;
+
+ case V4L2_CID_CAMERA_FACTORY_LV_TARGET:
+ cam_trace("FACTORY_LV_TARGET : 0x%x\n", ctrl->value);
+ err = m9mo_writeb(sd, M9MO_CATEGORY_ADJST,
+ 0x52, ctrl->value);
+ CHECK_ERR(err);
+ break;
+
+ case V4L2_CID_CAMERA_FACTORY_ADJ_IRIS:
+ err = m9mo_set_factory_adj_iris(sd, ctrl->value);
+ break;
+
+ case V4L2_CID_CAMERA_FACTORY_ADJ_IRIS_RANGE_MIN:
+ cam_trace("FACTORY_ADJ_IRIS_RANGE_MIN : 0x%x\n", ctrl->value);
+ err = m9mo_writeb(sd, M9MO_CATEGORY_ADJST,
+ 0x54, (unsigned char)(ctrl->value));
+ CHECK_ERR(err);
+ break;
+
+ case V4L2_CID_CAMERA_FACTORY_ADJ_IRIS_RANGE_MAX:
+ cam_trace("FACTORY_ADJ_IRIS_RANGE_MAX : 0x%x\n", ctrl->value);
+ err = m9mo_writeb(sd, M9MO_CATEGORY_ADJST,
+ 0x55, (unsigned char)(ctrl->value));
+ CHECK_ERR(err);
+ break;
+
+ case V4L2_CID_CAMERA_FACTORY_ADJ_GAIN_LIVEVIEW:
+ err = m9mo_set_factory_adj_gain_liveview(sd, ctrl->value);
+ break;
+
+ case V4L2_CID_CAMERA_FACTORY_LIVEVIEW_OFFSET_MARK:
+ cam_trace("FACTORY_LIVEVIEW_OFFSET_MARK : 0x%x\n",
+ ctrl->value);
+ err = m9mo_writel(sd, M9MO_CATEGORY_ADJST,
+ 0x3A, (u32)ctrl->value);
+ CHECK_ERR(err);
+ break;
+
+ case V4L2_CID_CAMERA_FACTORY_LIVEVIEW_OFFSET_VAL:
+ cam_trace("FACTORY_LIVEVIEW_OFFSET_VAL : 0x%x\n",
+ ctrl->value);
+ err = m9mo_writeb(sd, M9MO_CATEGORY_ADJST,
+ 0x3E, (u16)ctrl->value);
+ CHECK_ERR(err);
+ break;
+
+ case V4L2_CID_CAMERA_FACTORY_ADJ_GAIN_LIVEVIEW_RANGE_MIN:
+ cam_trace("FACTORY_ADJ_GAIN_LIVEVIEW_RANGE_MIN : 0x%x\n",
+ ctrl->value);
+ err = m9mo_writew(sd, M9MO_CATEGORY_ADJST,
+ 0x56, (u16)(ctrl->value));
+ CHECK_ERR(err);
+ break;
+
+ case V4L2_CID_CAMERA_FACTORY_ADJ_GAIN_LIVEVIEW_RANGE_MAX:
+ cam_trace("FACTORY_ADJ_GAIN_LIVEVIEW_RANGE_MAX : 0x%x\n",
+ ctrl->value);
+ err = m9mo_writew(sd, M9MO_CATEGORY_ADJST,
+ 0x58, (u16)(ctrl->value));
+ CHECK_ERR(err);
+ break;
+
+ case V4L2_CID_CAMERA_FACTORY_SH_CLOSE:
+ err = m9mo_set_factory_sh_close(sd, ctrl->value);
+ break;
+
+ case V4L2_CID_CAMERA_FACTORY_SH_CLOSE_IRIS_NUM:
+ cam_trace("FACTORY_SH_CLOSE_IRIS_NUM : 0x%x\n", ctrl->value);
+ err = m9mo_writeb(sd, M9MO_CATEGORY_ADJST,
+ 0x51, ctrl->value);
+ CHECK_ERR(err);
+ break;
+
+ case V4L2_CID_CAMERA_FACTORY_SH_CLOSE_SET_IRIS:
+ cam_trace("FACTORY_SH_CLOSE_SET_IRIS : 0x%x\n", ctrl->value);
+ err = m9mo_writeb(sd, M9MO_CATEGORY_ADJST,
+ 0x6E, ctrl->value);
+ CHECK_ERR(err);
+ break;
+
+ case V4L2_CID_CAMERA_FACTORY_SH_CLOSE_RANGE:
+ cam_trace("FACTORY_SH_CLOSE_RANGE : 0x%x\n", ctrl->value);
+ err = m9mo_writew(sd, M9MO_CATEGORY_ADJST,
+ 0x5A, (u16)(ctrl->value));
+ CHECK_ERR(err);
+ break;
+
+ case V4L2_CID_CAMERA_FACTORY_SH_CLOSE_ISO:
+ cam_trace("FACTORY_SH_CLOSE_ISO : 0x%x\n", ctrl->value);
+ err = m9mo_writew(sd, M9MO_CATEGORY_AE,
+ 0x3B, ctrl->value);
+ CHECK_ERR(err);
+ break;
+
+ case V4L2_CID_CAMERA_FACTORY_SH_CLOSE_SPEEDTIME_X:
+ cam_trace("FACTORY_SH_CLOSE_SPEEDTIME_X : 0x%x\n", ctrl->value);
+ err = m9mo_writew(sd, M9MO_CATEGORY_AE,
+ 0x37, (u16)(ctrl->value));
+ CHECK_ERR(err);
+ break;
+
+ case V4L2_CID_CAMERA_FACTORY_SH_CLOSE_SPEEDTIME_Y:
+ cam_trace("FACTORY_SH_CLOSE_SPEEDTIME_Y : 0x%x\n", ctrl->value);
+ err = m9mo_writew(sd, M9MO_CATEGORY_AE,
+ 0x39, (u16)(ctrl->value));
+ CHECK_ERR(err);
+ break;
+
+ case V4L2_CID_CAMERA_FACTORY_FLICKER:
+ err = m9mo_set_factory_flicker(sd, ctrl->value);
+ break;
+
+ case V4L2_CID_CAMERA_FACTORY_CAPTURE_GAIN:
+ err = m9mo_set_factory_capture_gain(sd, ctrl->value);
+ break;
+
+ case V4L2_CID_CAMERA_FACTORY_CAPTURE_GAIN_OFFSET_MARK:
+ cam_trace("FACTORY_CAPTURE_GAIN_OFFSET_MARK : 0x%x\n",
+ ctrl->value);
+ err = m9mo_writel(sd, M9MO_CATEGORY_ADJST,
+ 0x3A, (u32)ctrl->value);
+ CHECK_ERR(err);
+ break;
+
+ case V4L2_CID_CAMERA_FACTORY_CAPTURE_GAIN_OFFSET_VAL:
+ cam_trace("FACTORY_CAPTURE_GAIN_OFFSET_VAL : 0x%x\n",
+ ctrl->value);
+ err = m9mo_writeb(sd, M9MO_CATEGORY_ADJST,
+ 0x3E, (u16)ctrl->value);
+ CHECK_ERR(err);
+ break;
+
+ case V4L2_CID_CAMERA_FACTORY_CAPTURE_GAIN_RANGE_MIN:
+ cam_trace("FACTORY_CAPTURE_GAIN_RANGE_MIN : 0x%x\n",
+ ctrl->value);
+ err = m9mo_writew(sd, M9MO_CATEGORY_ADJST,
+ 0x56, (u16)ctrl->value);
+ CHECK_ERR(err);
+ break;
+
+ case V4L2_CID_CAMERA_FACTORY_CAPTURE_GAIN_RANGE_MAX:
+ cam_trace("FACTORY_CAPTURE_GAIN_RANGE_MAX : 0x%x\n",
+ ctrl->value);
+ err = m9mo_writew(sd, M9MO_CATEGORY_ADJST,
+ 0x58, (u16)ctrl->value);
+ CHECK_ERR(err);
+ break;
+
+ case V4L2_CID_CAMERA_FACTORY_LSC_TABLE:
+ cam_trace("FACTORY_LSC_TABLE : 0x%x\n", ctrl->value);
+ err = m9mo_writeb(sd, M9MO_CATEGORY_ADJST,
+ 0x30, ctrl->value);
+ CHECK_ERR(err);
+ break;
+
+ case V4L2_CID_CAMERA_FACTORY_LSC_REFERENCE:
+ cam_trace("FACTORY_LSC_REFERENCE : 0x%x\n", ctrl->value);
+ err = m9mo_writeb(sd, M9MO_CATEGORY_ADJST,
+ 0x31, ctrl->value);
+ CHECK_ERR(err);
+ break;
+
+ case V4L2_CID_CAMERA_FACTORY_CAPTURE_CTRL:
+ err = m9mo_set_factory_capture_ctrl(sd, ctrl->value);
+ break;
+
+ case V4L2_CID_CAMERA_FACTORY_AE_TARGET:
+ cam_trace("V4L2_CID_CAMERA_FACTORY_AE_TARGET : 0x%x\n",
+ ctrl->value);
+ err = m9mo_writeb(sd, M9MO_CATEGORY_AE,
+ 0x02, (unsigned char)ctrl->value);
+ CHECK_ERR(err);
+ break;
+
+ case V4L2_CID_CAMERA_FACTORY_FLASH:
+ err = m9mo_set_factory_flash(sd, ctrl->value);
+ break;
+
+ case V4L2_CID_CAMERA_FACTORY_FLASH_CHR_CHK_TM:
+ cam_trace("FLASH_CHR_CHK_TM : 0x%x\n", ctrl->value);
+ err = m9mo_writew(sd, M9MO_CATEGORY_CAPPARM,
+ 0x3B, (u16)ctrl->value);
+ CHECK_ERR(err);
+ break;
+
+ case V4L2_CID_CAMERA_FACTORY_FLASH_RANGE_X:
+ cam_trace("FLASH_RANGE_X : 0x%x\n", ctrl->value);
+ err = m9mo_writew(sd, M9MO_CATEGORY_ADJST,
+ 0x71, (u16)ctrl->value);
+ CHECK_ERR(err);
+ break;
+
+ case V4L2_CID_CAMERA_FACTORY_FLASH_RANGE_Y:
+ cam_trace("FLASH_RANGE_Y : 0x%x\n", ctrl->value);
+ err = m9mo_writew(sd, M9MO_CATEGORY_ADJST,
+ 0x73, (u16)ctrl->value);
+ CHECK_ERR(err);
+ break;
+
+ case V4L2_CID_CAMERA_FACTORY_WB:
+ err = m9mo_set_factory_wb(sd, ctrl->value);
+ break;
+
+ case V4L2_CID_CAMERA_FACTORY_WB_IN_RG_VALUE:
+ cam_trace("WB_IN_RG_VALUE : 0x%x\n",
+ ctrl->value);
+ err = m9mo_writew(sd, M9MO_CATEGORY_ADJST,
+ 0x27, (u16)ctrl->value);
+ CHECK_ERR(err);
+ break;
+
+ case V4L2_CID_CAMERA_FACTORY_WB_IN_BG_VALUE:
+ cam_trace("WB_IN_BG_VALUE : 0x%x\n",
+ ctrl->value);
+ err = m9mo_writew(sd, M9MO_CATEGORY_ADJST,
+ 0x29, (u16)ctrl->value);
+ CHECK_ERR(err);
+ break;
+
+ case V4L2_CID_CAMERA_FACTORY_WB_OUT_RG_VALUE:
+ cam_trace("WB_OUT_RG_VALUE : 0x%x\n",
+ ctrl->value);
+ err = m9mo_writew(sd, M9MO_CATEGORY_ADJST,
+ 0x2B, (u16)ctrl->value);
+ CHECK_ERR(err);
+ break;
+
+ case V4L2_CID_CAMERA_FACTORY_WB_OUT_BG_VALUE:
+ cam_trace("WB_OUT_RG_VALUE : 0x%x\n",
+ ctrl->value);
+ err = m9mo_writew(sd, M9MO_CATEGORY_ADJST,
+ 0x2D, (u16)ctrl->value);
+ CHECK_ERR(err);
+ break;
+
+ case V4L2_CID_CAMERA_FACTORY_WB_RANGE:
+ cam_trace("WB_RANGE_PERCENT : 0x%x\n",
+ ctrl->value);
+ err = m9mo_writeb(sd, M9MO_CATEGORY_ADJST,
+ 0x1F, (u8)ctrl->value);
+ CHECK_ERR(err);
+ break;
+
+ case V4L2_CID_CAMERA_FACTORY_WB_RANGE_FLASH_WRITE:
+ err = m9mo_writeb(sd, M9MO_CATEGORY_ADJST,
+ 0x26, 0x01);
+ CHECK_ERR(err);
+ break;
+
+ case V4L2_CID_CAMERA_FACTORY_AFLED_RANGE_DATA_START_X:
+ cam_trace("AFLED_RANGE_DATA_START_X : 0x%x\n",
+ ctrl->value);
+ err = m9mo_writeb(sd, M9MO_CATEGORY_LENS,
+ 0x43, (unsigned char)ctrl->value);
+ CHECK_ERR(err);
+ break;
+
+ case V4L2_CID_CAMERA_FACTORY_AFLED_RANGE_DATA_END_X:
+ cam_trace("AFLED_RANGE_DATA_END_X : 0x%x\n",
+ ctrl->value);
+ err = m9mo_writeb(sd, M9MO_CATEGORY_LENS,
+ 0x44, (unsigned char)ctrl->value);
+ CHECK_ERR(err);
+ break;
+
+ case V4L2_CID_CAMERA_FACTORY_AFLED_RANGE_DATA_START_Y:
+ cam_trace("AFLED_RANGE_DATA_START_Y : 0x%x\n",
+ ctrl->value);
+ err = m9mo_writeb(sd, M9MO_CATEGORY_LENS,
+ 0x45, (unsigned char)ctrl->value);
+ CHECK_ERR(err);
+ break;
+
+ case V4L2_CID_CAMERA_FACTORY_AFLED_RANGE_DATA_END_Y:
+ cam_trace("AFLED_RANGE_DATA_END_Y : 0x%x\n",
+ ctrl->value);
+ err = m9mo_writeb(sd, M9MO_CATEGORY_LENS,
+ 0x46, (unsigned char)ctrl->value);
+ CHECK_ERR(err);
+ break;
+
+ case V4L2_CID_CAMERA_FACTORY_AF_LED_TIME:
+ cam_trace("AF_LED_TIME : 0x%x\n", ctrl->value);
+ err = m9mo_writew(sd, M9MO_CATEGORY_LENS,
+ 0x4B, ctrl->value);
+ CHECK_ERR(err);
+
+ err = m9mo_writeb(sd, M9MO_CATEGORY_LENS,
+ 0x4D, 0x01);
+ CHECK_ERR(err);
+ break;
+
+ case V4L2_CID_CAMERA_FACTORY_AF_DIFF_CHECK_MIN:
+ cam_trace("AF_DIFF_CHECK_MIN : 0x%x\n", ctrl->value);
+ err = m9mo_writew(sd, M9MO_CATEGORY_LENS,
+ 0x18, (u16)ctrl->value);
+ CHECK_ERR(err);
+ break;
+
+ case V4L2_CID_CAMERA_FACTORY_AF_DIFF_CHECK_MAX:
+ cam_trace("AF_DIFF_CHECK_MAX : 0x%x\n", ctrl->value);
+ err = m9mo_writew(sd, M9MO_CATEGORY_LENS,
+ 0x1A, (u16)ctrl->value);
+ CHECK_ERR(err);
+ err = m9mo_writeb(sd, M9MO_CATEGORY_LENS,
+ 0xD, 0x11);
+ CHECK_ERR(err);
+ break;
+
+ case V4L2_CID_CAMERA_FACTORY_DEFECTPIXEL:
+ err = m9mo_set_factory_defectpixel(sd, ctrl->value);
+ break;
+
+ case V4L2_CID_CAMERA_FACTORY_DFPX_NLV_CAP:
+ cam_trace("DFPX_NLV_CAP : 0x%x\n", ctrl->value);
+ err = m9mo_writew(sd, M9MO_CATEGORY_PARM,
+ 0x70, (u16) ctrl->value);
+ CHECK_ERR(err);
+ break;
+
+ case V4L2_CID_CAMERA_FACTORY_DFPX_NLV_DR1_HD:
+ cam_trace("DFPX_NLV_DR1_HD : 0x%x\n", ctrl->value);
+ err = m9mo_writew(sd, M9MO_CATEGORY_PARM,
+ 0x7A, (u16)ctrl->value);
+ CHECK_ERR(err);
+ break;
+
+ case V4L2_CID_CAMERA_FACTORY_DFPX_NLV_DR0:
+ cam_trace("DFPX_NLV_DR0 : 0x%x\n", ctrl->value);
+ err = m9mo_writew(sd, M9MO_CATEGORY_PARM,
+ 0x76, (u16)ctrl->value);
+ CHECK_ERR(err);
+ break;
+
+ case V4L2_CID_CAMERA_FACTORY_DFPX_NLV_DR1:
+ cam_trace("DFPX_NLV_D1 : 0x%x\n", ctrl->value);
+ err = m9mo_writew(sd, M9MO_CATEGORY_PARM,
+ 0x72, (u16)ctrl->value);
+ CHECK_ERR(err);
+ break;
+
+ case V4L2_CID_CAMERA_FACTORY_DFPX_NLV_DR2:
+ cam_trace("DFPX_NLV_DR2 : 0x%x\n", ctrl->value);
+ err = m9mo_writew(sd, M9MO_CATEGORY_PARM,
+ 0x78, (u16)ctrl->value);
+ CHECK_ERR(err);
+ break;
+
+ case V4L2_CID_CAMERA_FACTORY_DFPX_NLV_DR_HS:
+ cam_trace("DFPX_NLV_DR_HS : 0x%x\n", ctrl->value);
+ err = m9mo_writew(sd, M9MO_CATEGORY_PARM,
+ 0x74, (u16)ctrl->value);
+ CHECK_ERR(err);
+ break;
+
+ case V4L2_CID_CAMERA_FACTORY_AF_LED_LV_MIN:
+ cam_trace("AF_LED_LV_MIN : 0x%x\n", ctrl->value);
+ err = m9mo_writew(sd, M9MO_CATEGORY_LENS,
+ 0x47, (u16)ctrl->value);
+ CHECK_ERR(err);
+ break;
+
+ case V4L2_CID_CAMERA_FACTORY_AF_LED_LV_MAX:
+ cam_trace("AF_LED_LV_MIN : 0x%x\n", ctrl->value);
+ err = m9mo_writew(sd, M9MO_CATEGORY_LENS,
+ 0x49, (u16)ctrl->value);
+ CHECK_ERR(err);
+ break;
+
+ case V4L2_CID_CAMERA_FACTORY_CAM_SYS_MODE:
+ err = m9mo_set_factory_cam_sys_mode(sd, ctrl->value);
+ break;
+
+ case V4L2_CID_CAMERA_PASM_MODE:
+ err = m9mo_set_PASM_mode(sd, ctrl->value);
+ break;
+
+ case V4L2_CID_CAMERA_SHUTTER_SPEED:
+ err = m9mo_set_shutter_speed(sd, ctrl->value);
+ break;
+
+ case V4L2_CID_CAMERA_F_NUMBER:
+ err = m9mo_set_f_number(sd, ctrl->value);
+ break;
+
+ case V4L2_CID_CAMERA_WB_CUSTOM_X:
+ state->wb_custom_rg = ctrl->value;
+ break;
+
+ case V4L2_CID_CAMERA_WB_CUSTOM_Y:
+ state->wb_custom_bg = ctrl->value;
+ break;
+
+ case V4L2_CID_CAMERA_WB_CUSTOM_VALUE:
+ err = m9mo_set_wb_custom(sd, ctrl->value);
+ break;
+
+ case V4L2_CID_CAMERA_SMART_SCENE_DETECT:
+ if (ctrl->value == 1) {
+ state->smart_scene_detect_mode = 1;
+ err = m9mo_writeb(sd, M9MO_CATEGORY_NEW, 0x08, 0x02);
+ CHECK_ERR(err);
+ err = m9mo_writeb(sd, M9MO_CATEGORY_NEW, 0x0A, 0x01);
+ CHECK_ERR(err);
+ } else {
+ state->smart_scene_detect_mode = 0;
+ err = m9mo_writeb(sd, M9MO_CATEGORY_NEW, 0x08, 0x00);
+ CHECK_ERR(err);
+ err = m9mo_writeb(sd, M9MO_CATEGORY_NEW, 0x0A, 0x00);
+ CHECK_ERR(err);
+ }
+ break;
+
+ case V4L2_CID_CAMERA_SMART_MOVIE_RECORDING:
+ if (state->smart_scene_detect_mode == 1) {
+ if (ctrl->value == 1) {
+ err = m9mo_writeb(sd, M9MO_CATEGORY_NEW,
+ 0x0A, 0x02);
+ CHECK_ERR(err);
+ } else {
+ err = m9mo_writeb(sd, M9MO_CATEGORY_NEW,
+ 0x0A, 0x01);
+ CHECK_ERR(err);
+ }
+ }
+
+ /* add recording check for zoom move */
+ if (ctrl->value == 1) {
+ state->recording = 1;
+ err = m9mo_writeb(sd, M9MO_CATEGORY_LENS, 0x27, 0x01);
+ CHECK_ERR(err);
+ } else {
+ state->recording = 0;
+ err = m9mo_writeb(sd, M9MO_CATEGORY_LENS, 0x27, 0x00);
+ CHECK_ERR(err);
+ }
+ break;
+
+ case V4L2_CID_CAMERA_SMART_AUTO_S1_PUSH:
+ err = m9mo_set_smart_auto_s1_push(sd, ctrl->value);
+ break;
+
+ case V4L2_CID_CAMERA_CAF:
+ err = m9mo_set_CAF(sd, ctrl->value);
+ break;
+
+ case V4L2_CID_CAMERA_FOCUS_RANGE:
+ err = m9mo_set_focus_range(sd, ctrl->value);
+ break;
+
+ case V4L2_CID_CAMERA_TIME_INFO:
+ err = m9mo_set_time_info(sd, ctrl->value);
+ break;
+
+ case V4L2_CID_CAMERA_LENS_TIMER:
+ err = m9mo_set_lens_off_timer(sd, ctrl->value);
+ break;
+
+ case V4L2_CID_CAMERA_STREAM_PART2: /* for shutter sound */
+ err = m9mo_set_mode_part2(sd, M9MO_STILLCAP_MODE);
+ break;
+
+ case V4L2_CID_CAMERA_FACTORY_SEND_SETTING:
+ state->factory_category = (ctrl->value) / 1000;
+ state->factory_byte = (ctrl->value) % 1000;
+ break;
+
+ case V4L2_CID_CAMERA_FACTORY_SEND_VALUE:
+ state->factory_value_size = 1;
+ state->factory_value = ctrl->value;
+ m9mo_send_factory_command_value(sd);
+ break;
+
+ case V4L2_CID_CAMERA_FACTORY_SEND_WORD_VALUE:
+ state->factory_value_size = 2;
+ state->factory_value = ctrl->value;
+ m9mo_send_factory_command_value(sd);
+ break;
+
+ case V4L2_CID_CAMERA_FACTORY_SEND_LONG_VALUE:
+ state->factory_value_size = 4;
+ state->factory_value = ctrl->value;
+ m9mo_send_factory_command_value(sd);
+ break;
+
+ case V4L2_CID_CAMERA_FACTORY_TILT:
+ cam_trace("TILT_ONE_SCRIPT_RUN : 0x%x\n", ctrl->value);
+ m9mo_set_factory_tilt(sd, ctrl->value);
+ break;
+
+ case V4L2_CID_CAMERA_FACTORY_IR_CHECK:
+ cam_trace("IR_CHECK : 0x%x\n", ctrl->value);
+ m9mo_set_factory_IR_Check(sd, ctrl->value);
+ break;
+
+ case V4L2_CID_CAMERA_FACTORY_TILT_SCAN_MIN:
+ cam_trace("TILT_SCAN_MIN : 0x%x\n", ctrl->value);
+ err = m9mo_writew(sd, M9MO_CATEGORY_LENS,
+ 0x18, (u16)ctrl->value);
+ CHECK_ERR(err);
+ break;
+
+ case V4L2_CID_CAMERA_FACTORY_TILT_SCAN_MAX:
+ cam_trace("TILT_SCAN_MAX : 0x%x\n", ctrl->value);
+ err = m9mo_writew(sd, M9MO_CATEGORY_LENS,
+ 0x1A, (u16)ctrl->value);
+ CHECK_ERR(err);
+ err = m9mo_writeb(sd, M9MO_CATEGORY_LENS,
+ 0x0D, 0x06);
+ CHECK_ERR(err);
+ break;
+
+ case V4L2_CID_CAMERA_FACTORY_TILT_FIELD:
+ cam_trace("TILT_FIELD : 0x%x\n", ctrl->value);
+ err = m9mo_writeb(sd, M9MO_CATEGORY_LENS,
+ 0x1B, (u8)ctrl->value);
+ CHECK_ERR(err);
+ err = m9mo_writeb(sd, M9MO_CATEGORY_LENS,
+ 0x0C, 0x00);
+ CHECK_ERR(err);
+ break;
+
+ case V4L2_CID_CAMERA_FACTORY_TILT_AF_RANGE_MIN:
+ cam_trace("TILT_AF_RANGE_MIN : 0x%x\n", ctrl->value);
+ err = m9mo_writew(sd, M9MO_CATEGORY_LENS,
+ 0x18, (u16)ctrl->value);
+ CHECK_ERR(err);
+ break;
+
+ case V4L2_CID_CAMERA_FACTORY_TILT_AF_RANGE_MAX:
+ cam_trace("TILT_AF_RANGE_MAX : 0x%x\n", ctrl->value);
+ err = m9mo_writew(sd, M9MO_CATEGORY_LENS,
+ 0x1A, (u16)ctrl->value);
+ CHECK_ERR(err);
+ err = m9mo_writeb(sd, M9MO_CATEGORY_LENS,
+ 0x0C, 0x01);
+ CHECK_ERR(err);
+ break;
+
+ case V4L2_CID_CAMERA_FACTORY_TILT_DIFF_RANGE_MIN:
+ cam_trace("TILT_DIFF_MIN : 0x%x\n", ctrl->value);
+ err = m9mo_writeb(sd, M9MO_CATEGORY_LENS,
+ 0x1A, (u8)ctrl->value);
+ CHECK_ERR(err);
+ break;
+
+ case V4L2_CID_CAMERA_FACTORY_TILT_DIFF_RANGE_MAX:
+ cam_trace("TILT_DIFF_MAX : 0x%x\n", ctrl->value);
+ err = m9mo_writeb(sd, M9MO_CATEGORY_LENS,
+ 0x1B, (u8)ctrl->value);
+ CHECK_ERR(err);
+ err = m9mo_writeb(sd, M9MO_CATEGORY_LENS,
+ 0x0C, 0x02);
+ CHECK_ERR(err);
+ break;
+
+ case V4L2_CID_CAMERA_FACTORY_IR_B_GAIN_MIN:
+ cam_trace("IR_B_GAIN_MIN : 0x%x\n", ctrl->value);
+ break;
+
+ case V4L2_CID_CAMERA_FACTORY_IR_B_GAIN_MAX:
+ cam_trace("IR_B_GAIN_MAX : 0x%x\n", ctrl->value);
+ break;
+
+ case V4L2_CID_CAMERA_FACTORY_IR_R_GAIN_MIN:
+ cam_trace("IR_R_GAIN_MIN : 0x%x\n", ctrl->value);
+ break;
+
+ case V4L2_CID_CAMERA_FACTORY_IR_R_GAIN_MAX:
+ cam_trace("IR_R_GAIN_MAX : 0x%x\n", ctrl->value);
+ break;
+
+ case V4L2_CID_CAMERA_FACTORY_FLASH_MAN_CHARGE:
+ cam_trace("FLASH_MAN_CHARGE : 0x%x\n", ctrl->value);
+ err = m9mo_writeb(sd, M9MO_CATEGORY_CAPPARM,
+ 0x2A, (u8)ctrl->value);
+ CHECK_ERR(err);
+ break;
+
+ case V4L2_CID_CAMERA_FACTORY_FLASH_MAN_EN:
+ cam_trace("FLASH_MAN_EN : 0x%x\n", ctrl->value);
+ err = m9mo_writeb(sd, M9MO_CATEGORY_CAPPARM,
+ 0x3D, (u8)ctrl->value);
+ CHECK_ERR(err);
break;
default:
@@ -3737,47 +10481,101 @@ static const struct m9mo_frmsizeenum *m9mo_get_frmsize
static int m9mo_set_frmsize(struct v4l2_subdev *sd)
{
struct m9mo_state *state = to_state(sd);
- struct v4l2_control ctrl;
int err;
+ int read_mon_size;
+ u32 size_val;
cam_trace("E\n");
if (state->format_mode == V4L2_PIX_FMT_MODE_PREVIEW) {
err = m9mo_set_mode(sd, M9MO_PARMSET_MODE);
CHECK_ERR(err);
- err = m9mo_writeb(sd, M9MO_CATEGORY_PARM,
- M9MO_PARM_MON_SIZE, state->preview->reg_val);
+ m9mo_set_gamma(sd);
+
+ err = m9mo_readb(sd, M9MO_CATEGORY_PARM,
+ M9MO_PARM_MON_SIZE, &read_mon_size);
CHECK_ERR(err);
- if (state->zoom) {
- /* Zoom position returns to 1
- when the monitor size is changed. */
- ctrl.id = V4L2_CID_CAMERA_ZOOM;
- ctrl.value = state->zoom;
- m9mo_set_zoom(sd, &ctrl);
+ /* don't set frmsize when returning preivew after capture */
+ if (err == 10)
+ cam_trace("~~~~ return when CAP->PAR ~~~~\n");
+ else {
+ if (state->fps == 60) {
+ if (state->preview->height == 480)
+ size_val = 0x2F;
+ else if (state->preview->height == 720)
+ size_val = 0x25;
+
+ if (read_mon_size != size_val) {
+ err = m9mo_writeb(sd, M9MO_CATEGORY_PARM,
+ M9MO_PARM_MON_SIZE, size_val);
+ CHECK_ERR(err);
+ }
+ } else if (state->sensor_mode == SENSOR_MOVIE
+ && state->fps == 30) {
+ if (state->preview->height == 1080)
+ size_val = 0x2C;
+ else if (state->preview->height == 720)
+ size_val = 0x2D;
+ else if (state->preview->width == 640
+ && state->preview->height == 480)
+ size_val = 0x2E;
+ else if (state->preview->width == 320
+ && state->preview->height == 240)
+ size_val = 0x36;
+
+ if (read_mon_size != size_val) {
+ err = m9mo_writeb(sd, M9MO_CATEGORY_PARM,
+ M9MO_PARM_MON_SIZE, size_val);
+ CHECK_ERR(err);
+ }
+ } else {
+ if (read_mon_size != state->preview->reg_val) {
+ err = m9mo_writeb(sd, M9MO_CATEGORY_PARM,
+ M9MO_PARM_MON_SIZE,
+ state->preview->reg_val);
+ CHECK_ERR(err);
+ }
}
+#if 1 /* Dual Capture */
+ if (size_val == 0x2C
+ || size_val == 0x2D
+ || size_val == 0x2E
+ || size_val == 0x36)
+ m9mo_set_dual_capture_mode(sd, 1);
+ else
+ m9mo_set_dual_capture_mode(sd, 0);
+#endif
+ }
cam_err("preview frame size %dx%d\n",
state->preview->width, state->preview->height);
} else {
- if (state->pixelformat == V4L2_COLORSPACE_JPEG) {
- err = m9mo_writeb(sd, M9MO_CATEGORY_CAPPARM,
- M9MO_CAPPARM_MAIN_IMG_SIZE,
- state->capture->reg_val);
- CHECK_ERR(err);
+ if (state->pixelformat == V4L2_COLORSPACE_JPEG
+ || state->running_capture_mode == RUNNING_MODE_LOWLIGHT
+ || state->running_capture_mode == RUNNING_MODE_HDR) {
+ if (!state->dual_capture_start) {
+ err = m9mo_writeb(sd, M9MO_CATEGORY_CAPPARM,
+ M9MO_CAPPARM_MAIN_IMG_SIZE,
+ state->capture->reg_val);
+ CHECK_ERR(err);
+ if (state->smart_zoom_mode)
+ m9mo_set_smart_zoom(sd,
+ state->smart_zoom_mode);
+ }
cam_info("capture frame size %dx%d\n",
- state->capture->width, state->capture->height);
+ state->capture->width,
+ state->capture->height);
} else {
err = m9mo_writeb(sd, M9MO_CATEGORY_CAPPARM,
M9MO_CAPPARM_PREVIEW_IMG_SIZE,
- state->capture->reg_val);
+ state->postview->reg_val);
CHECK_ERR(err);
- cam_info("capture frame size %dx%d\n",
- state->capture->width,
- state->capture->height);
+ cam_info("postview frame size %dx%d\n",
+ state->postview->width,
+ state->postview->height);
}
}
-
cam_trace("X\n");
return 0;
}
@@ -3801,8 +10599,14 @@ static int m9mo_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *ffmt)
state->format_mode = ffmt->field;
state->pixelformat = ffmt->colorspace;
- frmsize = state->format_mode == V4L2_PIX_FMT_MODE_PREVIEW ?
- &state->preview : &state->capture;
+ if (state->format_mode == V4L2_PIX_FMT_MODE_PREVIEW)
+ frmsize = &state->preview;
+ else if (state->pixelformat == V4L2_COLORSPACE_JPEG
+ || state->running_capture_mode == RUNNING_MODE_LOWLIGHT
+ || state->running_capture_mode == RUNNING_MODE_HDR)
+ frmsize = &state->capture;
+ else
+ frmsize = &state->postview;
old_index = *frmsize ? (*frmsize)->index : -1;
*frmsize = NULL;
@@ -3817,24 +10621,42 @@ static int m9mo_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *ffmt)
}
}
} else {
- num_entries = ARRAY_SIZE(capture_frmsizes);
- for (i = 0; i < num_entries; i++) {
- if (width == capture_frmsizes[i].width &&
- height == capture_frmsizes[i].height) {
- *frmsize = &capture_frmsizes[i];
- break;
+ if (state->pixelformat == V4L2_COLORSPACE_JPEG
+ || state->running_capture_mode == RUNNING_MODE_LOWLIGHT
+ || state->running_capture_mode == RUNNING_MODE_HDR) {
+ num_entries = ARRAY_SIZE(capture_frmsizes);
+ for (i = 0; i < num_entries; i++) {
+ if (width == capture_frmsizes[i].width &&
+ height == capture_frmsizes[i].height) {
+ *frmsize = &capture_frmsizes[i];
+ break;
+ }
+ }
+ } else {
+ num_entries = ARRAY_SIZE(postview_frmsizes);
+ for (i = 0; i < num_entries; i++) {
+ if (width == postview_frmsizes[i].width &&
+ height == postview_frmsizes[i].height) {
+ *frmsize = &postview_frmsizes[i];
+ break;
+ }
}
}
}
if (*frmsize == NULL) {
cam_warn("invalid frame size %dx%d\n", width, height);
- *frmsize = state->format_mode == V4L2_PIX_FMT_MODE_PREVIEW ?
- m9mo_get_frmsize(preview_frmsizes, num_entries,
- M9MO_PREVIEW_VGA) :
-
- m9mo_get_frmsize(capture_frmsizes, num_entries,
- M9MO_CAPTURE_3MP);
+ if (state->format_mode == V4L2_PIX_FMT_MODE_PREVIEW)
+ *frmsize = m9mo_get_frmsize(preview_frmsizes,
+ num_entries, M9MO_PREVIEW_720P);
+ else if (state->pixelformat == V4L2_COLORSPACE_JPEG
+ || state->running_capture_mode == RUNNING_MODE_LOWLIGHT
+ || state->running_capture_mode == RUNNING_MODE_HDR)
+ *frmsize = m9mo_get_frmsize(capture_frmsizes,
+ num_entries, M9MO_CAPTURE_12MPW);
+ else
+ *frmsize = m9mo_get_frmsize(postview_frmsizes,
+ num_entries, M9MO_CAPTURE_POSTWHD);
}
cam_err("%dx%d\n", (*frmsize)->width, (*frmsize)->height);
@@ -3868,25 +10690,13 @@ static int m9mo_s_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *a)
}
if (fps != state->fps) {
- if (fps <= 0 || fps > 30) {
+ if (fps <= 0 || fps > 120) {
cam_err("invalid frame rate %d\n", fps);
- fps = 30;
+ fps = 0; /* set to auto(default) */
}
- state->fps = fps;
}
-#if 0
- err = m9mo_set_mode(sd, M9MO_PARMSET_MODE);
- CHECK_ERR(err);
-#endif
-
- cam_dbg("fixed fps %d\n", state->fps);
-#if 0
- err = m9mo_writeb(sd, M9MO_CATEGORY_PARM,
- M9MO_PARM_FLEX_FPS, state->fps != 30 ? state->fps : 0);
- CHECK_ERR(err);
-#endif
-
+ cam_info("%s: X, fps = %d\n", __func__, fps);
return 0;
}
@@ -3909,7 +10719,9 @@ static int m9mo_enum_framesizes(struct v4l2_subdev *sd,
fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
fsize->discrete.width = state->preview->width;
fsize->discrete.height = state->preview->height;
- } else {
+ } else if (state->pixelformat == V4L2_COLORSPACE_JPEG
+ || state->running_capture_mode == RUNNING_MODE_LOWLIGHT
+ || state->running_capture_mode == RUNNING_MODE_HDR) {
if (state->capture == NULL
/* FIXME || state->capture->index < 0 */)
return -EINVAL;
@@ -3917,6 +10729,14 @@ static int m9mo_enum_framesizes(struct v4l2_subdev *sd,
fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
fsize->discrete.width = state->capture->width;
fsize->discrete.height = state->capture->height;
+ } else {
+ if (state->postview == NULL
+ /* FIXME || state->postview->index < 0 */)
+ return -EINVAL;
+
+ fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
+ fsize->discrete.width = state->postview->width;
+ fsize->discrete.height = state->postview->height;
}
return 0;
@@ -3925,7 +10745,8 @@ static int m9mo_enum_framesizes(struct v4l2_subdev *sd,
static int m9mo_s_stream_preview(struct v4l2_subdev *sd, int enable)
{
struct m9mo_state *state = to_state(sd);
- u32 old_mode, int_factor, value;
+ struct v4l2_control ctrl;
+ u32 old_mode, int_factor;
int err;
if (enable) {
@@ -3935,23 +10756,6 @@ static int m9mo_s_stream_preview(struct v4l2_subdev *sd, int enable)
CHECK_ERR(err);
}
- if (state->preview->width == 720 &&
- state->preview->height == 480) {
- err = m9mo_writeb(sd, M9MO_CATEGORY_AE,
- M9MO_AE_EP_MODE_MON, 0x1C);
- CHECK_ERR(err);
- err = m9mo_writeb(sd, M9MO_CATEGORY_AE,
- M9MO_AE_EP_MODE_CAP, 0x1C);
- CHECK_ERR(err);
- } else {
- err = m9mo_writeb(sd, M9MO_CATEGORY_AE,
- M9MO_AE_EP_MODE_MON, 0x00);
- CHECK_ERR(err);
- err = m9mo_writeb(sd, M9MO_CATEGORY_AE,
- M9MO_AE_EP_MODE_CAP, 0x00);
- CHECK_ERR(err);
- }
-
old_mode = m9mo_set_mode(sd, M9MO_MONITOR_MODE);
if (old_mode <= 0) {
cam_err("failed to set mode\n");
@@ -3966,31 +10770,18 @@ static int m9mo_s_stream_preview(struct v4l2_subdev *sd, int enable)
return -ETIMEDOUT;
}
}
- err = m9mo_writeb(sd, M9MO_CATEGORY_TEST,
- 0x34, 0x00);
- err = m9mo_writeb(sd, M9MO_CATEGORY_TEST,
- 0x35, 0x02);
- err = m9mo_writeb(sd, M9MO_CATEGORY_TEST,
- 0x33, 0x01);
- msleep(20);
- err = m9mo_readb(sd, M9MO_CATEGORY_TEST,
- 0x36, &value);
- cam_err("******** sensor version = %x *********\n", value);
-
- m9mo_set_lock(sd, 0);
-
-#if 0
- cam_err("******** LENS ON *********\n");
- err = m9mo_writeb(sd, M9MO_CATEGORY_LENS,
- 0x04, 0x0a);
-#endif
-#if 0
- if (state->check_dataline) {
- err = m9mo_check_dataline(sd, state->check_dataline);
- CHECK_ERR(err);
+ if (state->zoom >= 0x0F) {
+ /* Zoom position returns to 1
+ when the monitor size is changed. */
+ ctrl.id = V4L2_CID_CAMERA_ZOOM;
+ ctrl.value = state->zoom;
+ m9mo_set_zoom(sd, &ctrl);
}
-#endif
+ if (state->smart_zoom_mode)
+ m9mo_set_smart_zoom(sd, state->smart_zoom_mode);
+
+ m9mo_set_lock(sd, 0);
} else {
}
@@ -4001,13 +10792,18 @@ static int m9mo_s_stream_capture(struct v4l2_subdev *sd, int enable)
{
/*u32 int_factor;*/
int err;
+ struct m9mo_state *state = to_state(sd);
#ifndef FAST_CAPTURE
if (enable) {
- err = m9mo_set_mode(sd, M9MO_STILLCAP_MODE);
- if (err <= 0) {
- cam_err("failed to set mode\n");
- return err;
+ if (state->running_capture_mode == RUNNING_MODE_SINGLE) {
+ m9mo_set_mode_part1(sd, M9MO_STILLCAP_MODE);
+ } else {
+ err = m9mo_set_mode(sd, M9MO_STILLCAP_MODE);
+ if (err <= 0) {
+ cam_err("failed to set mode\n");
+ return err;
+ }
}
/*
int_factor = m9mo_wait_interrupt(sd, M9MO_ISP_TIMEOUT);
@@ -4096,6 +10892,12 @@ static int m9mo_s_stream(struct v4l2_subdev *sd, int enable)
return -ENOSYS;
}
+ cam_info("state->format_mode=%d\n", state->format_mode);
+ if (state->running_capture_mode == RUNNING_MODE_BURST) {
+ cam_trace("X\n");
+ return 0;
+ }
+
switch (enable) {
case STREAM_MODE_CAM_ON:
case STREAM_MODE_CAM_OFF:
@@ -4121,8 +10923,10 @@ static int m9mo_s_stream(struct v4l2_subdev *sd, int enable)
case STREAM_MODE_MOVIE_ON:
state->recording = 1;
+#if 0 /* Not use S project */
if (state->flash_mode != FLASH_MODE_OFF)
err = m9mo_set_flash(sd, state->flash_mode, 1);
+#endif
if (state->preview->index == M9MO_PREVIEW_720P ||
state->preview->index == M9MO_PREVIEW_1080P)
@@ -4134,7 +10938,9 @@ static int m9mo_s_stream(struct v4l2_subdev *sd, int enable)
state->preview->index == M9MO_PREVIEW_1080P)
err = m9mo_set_af(sd, 0);
+#if 0 /* Not use S project */
m9mo_set_flash(sd, FLASH_MODE_OFF, 1);
+#endif
state->recording = 0;
break;
@@ -4169,15 +10975,18 @@ static int m9mo_check_version(struct v4l2_subdev *sd)
static int m9mo_init_param(struct v4l2_subdev *sd)
{
+ struct m9mo_state *state = to_state(sd);
int err;
cam_trace("E\n");
err = m9mo_writew(sd, M9MO_CATEGORY_SYS, M9MO_SYS_INT_EN,
M9MO_INT_MODE | M9MO_INT_CAPTURE | M9MO_INT_FRAME_SYNC
- /* | M9MO_INT_SOUND*/);
+ | M9MO_INT_ATSCENE_UPDATE
+ | M9MO_INT_SOUND);
CHECK_ERR(err);
- err = m9mo_writeb(sd, M9MO_CATEGORY_PARM, M9MO_PARM_OUT_SEL, 0x02);
+ err = m9mo_writeb(sd, M9MO_CATEGORY_PARM,
+ M9MO_PARM_OUT_SEL, 0x02);
CHECK_ERR(err);
/* Capture */
@@ -4185,6 +10994,8 @@ static int m9mo_init_param(struct v4l2_subdev *sd)
M9MO_CAPPARM_YUVOUT_MAIN, 0x01);
CHECK_ERR(err);
+ m9mo_set_sensor_mode(sd, state->sensor_mode);
+
#if 0
err = m9mo_writel(sd, M9MO_CATEGORY_CAPPARM,
M9MO_CAPPARM_THUMB_JPEG_MAX, M9MO_THUMB_MAXSIZE);
@@ -4215,6 +11026,9 @@ static int m9mo_ois_init(struct v4l2_subdev *sd)
const struct m9mo_platform_data *pdata = client->dev.platform_data;
struct m9mo_state *state = to_state(sd);
u32 int_factor, int_en, err, ois_result;
+ int try_cnt = 2;
+
+ cam_dbg("E\n");
err = m9mo_readw(sd, M9MO_CATEGORY_SYS, M9MO_SYS_INT_EN, &int_en);
CHECK_ERR(err);
@@ -4227,33 +11041,48 @@ static int m9mo_ois_init(struct v4l2_subdev *sd)
err = m9mo_writew(sd, M9MO_CATEGORY_SYS, M9MO_SYS_INT_EN, int_en);
CHECK_ERR(err);
- /* SambaZ PLL enable */
- pdata->config_sambaz(1);
+ do {
+ /* OIS on set */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_NEW,
+ 0x10, 0x01);
+ CHECK_ERR(err);
- /* OIS on set */
- err = m9mo_writeb(sd, M9MO_CATEGORY_NEW,
- 0x10, 0x01);
- CHECK_ERR(err);
+ /* OIS F/W download, boot */
+ err = m9mo_writeb(sd, M9MO_CATEGORY_NEW,
+ 0x11, 0x00);
- /* OIS F/W download, boot */
- err = m9mo_writeb(sd, M9MO_CATEGORY_NEW,
- 0x11, 0x00);
-
- int_factor = m9mo_wait_interrupt(sd, M9MO_ISP_TIMEOUT);
- if (!(int_factor & M9MO_INT_OIS_INIT)) {
- cam_err("OIS interrupt not issued\n");
- state->isp.bad_fw = 1;
- return -ENOSYS;
- }
- cam_info("OIS init complete\n");
-
- /* Read OIS result */
- m9mo_readb(sd, M9MO_CATEGORY_NEW, 0x17, &ois_result);
- cam_info("ois result = %d", ois_result);
+ int_factor = m9mo_wait_interrupt(sd, M9MO_ISP_TIMEOUT);
+ if (!(int_factor & M9MO_INT_OIS_INIT)) {
+ cam_err("OIS interrupt not issued\n");
+ if (try_cnt > 1) {
+ try_cnt--;
+ pdata->config_sambaz(0);
+ msleep(20);
+ if (try_cnt == 1)
+ pdata->config_sambaz(1);
+ continue;
+ }
+ state->isp.bad_fw = 1;
+ return -ENOSYS;
+ }
+ cam_info("OIS init complete\n");
+
+ /* Read OIS result */
+ m9mo_readb(sd, M9MO_CATEGORY_NEW, 0x17, &ois_result);
+ cam_info("ois result = %d", ois_result);
+ if (ois_result != 0x02) {
+ try_cnt--;
+ pdata->config_sambaz(0);
+ msleep(20);
+ if (try_cnt == 1)
+ pdata->config_sambaz(1);
+ } else
+ try_cnt = 0;
+ } while (try_cnt);
/* Lens boot */
err = m9mo_writeb(sd, M9MO_CATEGORY_LENS,
- 0x00, 0x00);
+ M9MO_LENS_AF_INITIAL, 0x00);
int_factor = m9mo_wait_interrupt(sd, M9MO_ISP_TIMEOUT);
if (!(int_factor & M9MO_INT_LENS_INIT)) {
cam_err("M9MO_INT_LENS_INIT isn't issued, %#x\n",
@@ -4261,20 +11090,26 @@ static int m9mo_ois_init(struct v4l2_subdev *sd)
return -ETIMEDOUT;
}
+ cam_dbg("X\n");
+
return err;
}
static int m9mo_init(struct v4l2_subdev *sd, u32 val)
{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ const struct m9mo_platform_data *pdata = client->dev.platform_data;
struct m9mo_state *state = to_state(sd);
u32 int_factor;
/*u32 value;*/
int err;
- int fw_ver;
+
+ cam_dbg("E : val = %d\n", val);
/* Default state values */
state->preview = NULL;
state->capture = NULL;
+ state->postview = NULL;
state->format_mode = V4L2_PIX_FMT_MODE_PREVIEW;
state->sensor_mode = SENSOR_CAMERA;
@@ -4288,58 +11123,61 @@ static int m9mo_init(struct v4l2_subdev *sd, u32 val)
state->isp.bad_fw = 0;
state->isp.issued = 0;
- memset(&state->focus, 0, sizeof(state->focus));
+ state->zoom = 0;
+ state->smart_zoom_mode = 0;
- /* Test force update FW */
-#if 0
- err = m9mo_load_fw_main(sd);
- msleep(1000);
-#endif
- if (system_rev > 0) {
- err = m9mo_writel(sd, M9MO_CATEGORY_FLASH,
- 0x0C, 0x27c00020);
- }
+ state->vss_mode = 0;
+ state->dual_capture_start = 0;
+ state->dual_capture_frame = 1;
+ state->focus_area_mode = V4L2_FOCUS_AREA_CENTER;
- /* start camera program(parallel FLASH ROM) */
- cam_info("write 0x0f, 0x12~~~\n");
- err = m9mo_writeb(sd, M9MO_CATEGORY_FLASH,
- M9MO_FLASH_CAM_START, 0x01);
- CHECK_ERR(err);
+ state->bracket_wbb_val = BRACKET_WBB_VALUE3; /* AB -+1 */
+ state->wb_custom_rg = 424; /* 1A8 */
+ state->wb_custom_bg = 452; /* 1C4 */
- int_factor = m9mo_wait_interrupt(sd, M9MO_ISP_TIMEOUT);
- if (!(int_factor & M9MO_INT_MODE)) {
- cam_err("firmware was erased?\n");
- state->isp.bad_fw = 1;
- return -ENOSYS;
- }
- cam_info("ISP boot complete\n");
+ state->color_effect = 0;
+ state->gamma_rgb_mon = 2;
+ state->gamma_rgb_cap = 2;
+ state->gamma_tbl_rgb_cap = 1;
+ state->gamma_tbl_rgb_mon = 1;
-#if 0
- cam_err("read 0x00, 0x1c~~~\n");
+ memset(&state->focus, 0, sizeof(state->focus));
- m9mo_readb(sd, M9MO_CATEGORY_SYS,
- M9MO_SYS_INT_FACTOR, &state->isp.int_factor);
- cam_err("state->isp.int_factor = %x\n", state->isp.int_factor);
+ if (!leave_power) {
+ /* SambaZ PLL enable */
+ cam_dbg("SambaZ On start ~~~\n");
+ pdata->config_sambaz(1);
+ cam_dbg("SambaZ On finish ~~~\n");
- m9mo_readb(sd, 0x01,
- 0x01, &value);
- cam_err("value = %x\n", value);
-#endif
+ if (system_rev > 0) {
+ err = m9mo_writel(sd, M9MO_CATEGORY_FLASH,
+ 0x0C, 0x27c00020);
+ }
+
+ /* start camera program(parallel FLASH ROM) */
+ cam_info("write 0x0f, 0x12~~~\n");
+ err = m9mo_writeb(sd, M9MO_CATEGORY_FLASH,
+ M9MO_FLASH_CAM_START, 0x01);
+ CHECK_ERR(err);
+
+ int_factor = m9mo_wait_interrupt(sd, M9MO_ISP_TIMEOUT);
+ if (!(int_factor & M9MO_INT_MODE)) {
+ cam_err("firmware was erased?\n");
+ state->isp.bad_fw = 1;
+ return -ENOSYS;
+ }
+ cam_info("ISP boot complete\n");
+ }
/* check up F/W version */
-#if 0
- err = m9mo_check_version(sd);
- CHECK_ERR(err);
-#else
- /* read F/W version */
- m9mo_readw(sd, M9MO_CATEGORY_SYS,
- M9MO_SYS_VER_FW, &fw_ver);
- cam_info("f/w version = %x\n", fw_ver);
-#endif
+ err = m9mo_check_fw(sd);
- m9mo_init_param(sd);
- m9mo_ois_init(sd);
+ if (!leave_power) {
+ m9mo_init_param(sd);
+ m9mo_ois_init(sd);
+ }
+ leave_power = false;
cam_info("Lens boot complete - M9MO init complete\n");
return 0;
@@ -4352,6 +11190,7 @@ static const struct v4l2_subdev_core_ops m9mo_core_ops = {
.g_ctrl = m9mo_g_ctrl,
.s_ctrl = m9mo_s_ctrl,
.g_ext_ctrls = m9mo_g_ext_ctrls,
+ .s_ext_ctrls = m9mo_s_ext_ctrls,
};
static const struct v4l2_subdev_video_ops m9mo_video_ops = {
@@ -4370,26 +11209,13 @@ static const struct v4l2_subdev_ops m9mo_ops = {
static ssize_t m9mo_camera_type_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
- struct m9mo_state *state = dev_get_drvdata(dev);
- char type[25];
-
- if (state->exif.unique_id[1] == 'B') {
- strcpy(type, "SONY_IMX105PQ_M9MOLS");
- } else if (state->exif.unique_id[1] == 'C') {
- strcpy(type, "SLSI_S5K3H2YX_M9MOLS");
- } else {
- cam_warn("cannot find the matched camera type\n");
- strcpy(type, "SONY_IMX105PQ_M9MOLS");
- }
-
- return sprintf(buf, "%s\n", type);
+ return sprintf(buf, "%s\n", sysfs_sensor_type);
}
static ssize_t m9mo_camera_fw_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
- struct m9mo_state *state = dev_get_drvdata(dev);
- return sprintf(buf, "%s\n", state->fw_version);
+ return sprintf(buf, "%s %s\n", sysfs_phone_fw, sysfs_sensor_fw);
}
static DEVICE_ATTR(rear_camtype, S_IRUGO, m9mo_camera_type_show, NULL);
@@ -4447,27 +11273,30 @@ static int __devexit m9mo_remove(struct i2c_client *client)
{
struct v4l2_subdev *sd = i2c_get_clientdata(client);
struct m9mo_state *state = to_state(sd);
- int err;
+ int err = 0;
+ /*int err;*/
- cam_err("******** LENS OFF *********\n");
- err = m9mo_writeb(sd, M9MO_CATEGORY_LENS,
- 0x04, 0x0b);
- CHECK_ERR(err);
- msleep(1500);
-/* if (m9mo_set_af_softlanding(sd) < 0)
- cam_err("failed to set soft landing\n");*/
+ if (!leave_power) {
+ if (m9mo_set_lens_off(sd) < 0)
+ cam_err("failed to set m9mo_set_lens_off~~~~~\n");
+ }
- device_remove_file(state->m9mo_dev, &dev_attr_rear_camtype);
- device_remove_file(state->m9mo_dev, &dev_attr_rear_camfw);
- device_destroy(camera_class, 0);
- state->m9mo_dev = NULL;
+ if (leave_power) {
+ err = m9mo_set_lens_off_timer(sd, 0);
+ CHECK_ERR(err);
+
+ err = m9mo_set_mode(sd, M9MO_PARMSET_MODE);
+ CHECK_ERR(err);
+ }
if (state->isp.irq > 0)
free_irq(state->isp.irq, sd);
v4l2_device_unregister_subdev(sd);
- kfree(state->fw_version);
+#if 0
+ kfree(state->sensor_type);
+#endif
kfree(state);
return 0;
@@ -4514,13 +11343,9 @@ static int __init m9mo_mod_init(void)
static void __exit m9mo_mod_exit(void)
{
i2c_del_driver(&m9mo_i2c_driver);
- if (camera_class)
- class_destroy(camera_class);
}
module_init(m9mo_mod_init);
module_exit(m9mo_mod_exit);
-
-MODULE_AUTHOR("Goeun Lee <ge.lee@samsung.com>");
MODULE_DESCRIPTION("driver for Fusitju M9MO LS 16MP camera");
MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/m9mo.h b/drivers/media/video/m9mo.h
index 0c3f24c..4da72a2 100644
--- a/drivers/media/video/m9mo.h
+++ b/drivers/media/video/m9mo.h
@@ -71,12 +71,12 @@ u8 buf_port_seting0[] = {
u8 buf_port_seting1[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07,
- 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0xFF,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
u8 buf_port_seting2[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -96,35 +96,41 @@ enum m9mo_prev_frmsize {
M9MO_PREVIEW_VGA,
M9MO_PREVIEW_D1,
M9MO_PREVIEW_WVGA,
+ M9MO_PREVIEW_960_720,
+ M9MO_PREVIEW_1080_720,
M9MO_PREVIEW_720P,
-#if defined(CONFIG_MACH_Q1_BD)
- M9MO_PREVIEW_880_720,
- M9MO_PREVIEW_1200_800,
- M9MO_PREVIEW_1280_800,
- M9MO_PREVIEW_1280_768,
- M9MO_PREVIEW_1072_800,
- M9MO_PREVIEW_980_800,
-#endif
M9MO_PREVIEW_1080P,
M9MO_PREVIEW_HDR,
M9MO_PREVIEW_720P_60FPS,
M9MO_PREVIEW_VGA_60FPS,
+ M9MO_PREVIEW_1080P_DUAL,
+ M9MO_PREVIEW_720P_DUAL,
+ M9MO_PREVIEW_VGA_DUAL,
+ M9MO_PREVIEW_QVGA_DUAL,
};
enum m9mo_cap_frmsize {
+ M9MO_CAPTURE_HD, /* 960 x 720 */
M9MO_CAPTURE_1MP, /* 1024 x 768 */
M9MO_CAPTURE_2MPW, /* 1920 x 1080 */
M9MO_CAPTURE_3MP, /* 1984 x 1488 */
+ M9MO_CAPTURE_4MP, /* 2304 x 1728 */
M9MO_CAPTURE_5MP, /* 2592 x 1944 */
M9MO_CAPTURE_8MP, /* 3264 x 2448 */
M9MO_CAPTURE_10MP, /* 3648 x 2736 */
- M9MO_CAPTURE_12MPW, /* 4608 x 2768 */
+ M9MO_CAPTURE_12MPW, /* 4608 x 2592 */
M9MO_CAPTURE_14MP, /* 4608 x 3072 */
M9MO_CAPTURE_16MP, /* 4608 x 3456 */
- M9MO_CAPTURE_POSTWVGA, /* 800 x 480 */
+ M9MO_CAPTURE_RAW, /* 4088 x 2500 */
+};
+
+enum m9mo_post_frmsize {
+ M9MO_CAPTURE_POSTQVGA, /* 320 x 240 */
M9MO_CAPTURE_POSTVGA, /* 640 x 480 */
- M9MO_CAPTURE_POSTWHD, /* 1280 x 720 */
M9MO_CAPTURE_POSTHD, /* 960 x 720 */
+ M9MO_CAPTURE_POSTP, /* 1056 x 704 */
+ M9MO_CAPTURE_POSTWVGA, /* 800 x 480 */
+ M9MO_CAPTURE_POSTWHD, /* 1280 x 720 */
};
enum cam_frmratio {
@@ -184,6 +190,24 @@ struct m9mo_focus {
unsigned int pos_y;
};
+struct m9mo_factory_punt_data {
+ unsigned int min;
+ unsigned int max;
+ unsigned int num;
+};
+
+struct m9mo_factory_zoom_data {
+ unsigned int range_min;
+ unsigned int range_max;
+ unsigned int slope_min;
+ unsigned int slope_max;
+};
+
+struct m9mo_factory_zoom_slope_data {
+ unsigned int min;
+ unsigned int max;
+};
+
struct m9mo_exif {
char unique_id[7];
u32 exptime; /* us */
@@ -192,6 +216,9 @@ struct m9mo_exif {
int tv; /* shutter speed */
int bv; /* brightness */
int ebv; /* exposure bias */
+ int av; /* Aperture */
+ int focal_length;
+ int focal_35mm_length;
};
struct m9mo_state {
@@ -205,6 +232,7 @@ struct m9mo_state {
const struct m9mo_frmsizeenum *preview;
const struct m9mo_frmsizeenum *capture;
+ const struct m9mo_frmsizeenum *postview;
enum v4l2_pix_format_mode format_mode;
enum v4l2_sensor_mode sensor_mode;
@@ -212,18 +240,36 @@ struct m9mo_state {
enum v4l2_scene_mode scene_mode;
int vt_mode;
int zoom;
- int optical_zoom;
+ int smart_zoom_mode;
int m9mo_fw_done;
int fw_info_done;
unsigned int fps;
+
+ int factory_down_check;
+ int factory_result_check;
+ int factory_end_check;
+ int factory_category;
+ int factory_byte;
+ int factory_value;
+ int factory_value_size;
+
struct m9mo_focus focus;
+ struct m9mo_factory_punt_data f_punt_data;
+ struct m9mo_factory_zoom_data f_zoom_data;
+
+ unsigned int factory_log_addr;
+ u16 factory_log_size;
+ int factory_test_num;
struct m9mo_jpeg jpeg;
struct m9mo_exif exif;
- char *fw_version;
+ int isp_fw_ver;
+ u8 sensor_ver[10];
+ u8 phone_ver[10];
+ u8 sensor_type[25];
#ifdef CONFIG_CAM_DEBUG
u8 dbg_level;
@@ -232,12 +278,68 @@ struct m9mo_state {
int facedetect_mode;
int running_capture_mode;
int fd_eyeblink_cap;
+ int fd_red_eye_status;
+ int image_stabilizer_mode;
+ int ot_status;
+ int ot_x_loc;
+ int ot_y_loc;
+ int ot_width;
+ int ot_height;
+ int bracket_wbb_val;
unsigned int face_beauty:1;
unsigned int recording:1;
unsigned int check_dataline:1;
int anti_banding;
int pixelformat;
+
+ int wb_g_value;
+ int wb_b_value;
+ int wb_a_value;
+ int wb_m_value;
+ int wb_custom_rg;
+ int wb_custom_bg;
+
+ int vss_mode;
+ int dual_capture_start;
+ int dual_capture_frame;
+
+ int focus_mode;
+ int focus_range;
+ int focus_area_mode;
+
+ int f_number;
+ int iso;
+ int numerator;
+ int denominator;
+
+ int AV;
+ int TV;
+ int SV;
+ int EV;
+ int LV;
+
+ int smart_scene_detect_mode;
+
+ int continueFps;
+
+ int fd_num;
+
+ int caf_state;
+
+ int mode;
+
+ bool stream_on_part2;
+
+ int widget_mode_level;
+ int gamma_rgb_mon;
+ int gamma_rgb_cap;
+ int gamma_tbl_rgb_mon;
+ int gamma_tbl_rgb_cap;
+ int color_effect;
+
+ int preview_width;
+ int preview_height;
};
/* Category */
@@ -246,8 +348,10 @@ struct m9mo_state {
#define M9MO_CATEGORY_MON 0x02
#define M9MO_CATEGORY_AE 0x03
#define M9MO_CATEGORY_NEW 0x04
+#define M9MO_CATEGORY_PRO_MODE 0x05
#define M9MO_CATEGORY_WB 0x06
#define M9MO_CATEGORY_EXIF 0x07
+#define M9MO_CATEGORY_OT 0x08
#define M9MO_CATEGORY_FD 0x09
#define M9MO_CATEGORY_LENS 0x0A
#define M9MO_CATEGORY_CAPPARM 0x0B
@@ -269,6 +373,7 @@ struct m9mo_state {
#define M9MO_SYS_INT_EN 0x10
#define M9MO_SYS_INT_FACTOR 0x1C
#define M9MO_SYS_FRAMESYNC_CNT 0x14
+#define M9MO_SYS_LENS_TIMER 0x28
/* M9MO_CATEGORY_PARAM: 0x01 */
@@ -277,9 +382,14 @@ struct m9mo_state {
#define M9MO_PARM_EFFECT 0x0B
#define M9MO_PARM_FLEX_FPS 0x67
#define M9MO_PARM_HDMOVIE 0x32
+#define M9MO_PARM_VIDEO_SNAP_IMG_TRANSFER_START 0x3A
+#define M9MO_PARM_SEL_FRAME_VIDEO_SNAP 0x3B
+#define M9MO_PARM_MON_MOVIE_SELECT 0x3C
+#define M9MO_PARM_VSS_MODE 0x6E
/* M9MO_CATEGORY_MON: 0x02 */
#define M9MO_MON_ZOOM 0x01
+#define M9MO_MON_HR_ZOOM 0x04
#define M9MO_MON_MON_REVERSE 0x05
#define M9MO_MON_MON_MIRROR 0x06
#define M9MO_MON_SHOT_REVERSE 0x07
@@ -289,7 +399,11 @@ struct m9mo_state {
#define M9MO_MON_COLOR_EFFECT 0x0B
#define M9MO_MON_CHROMA_LVL 0x0F
#define M9MO_MON_EDGE_LVL 0x11
+#define M9MO_MON_EDGE_CTRL 0x20
+#define M9MO_MON_POINT_COLOR 0x22
#define M9MO_MON_TONE_CTRL 0x25
+#define M9MO_MON_START_VIDEO_SNAP_SHOT 0x56
+#define M9MO_MON_VIDEO_SNAP_SHOT_FRAME_COUNT 0x57
/* M9MO_CATEGORY_AE: 0x03 */
#define M9MO_AE_LOCK 0x00
@@ -299,16 +413,52 @@ struct m9mo_state {
#define M9MO_AE_INDEX 0x09
#define M9MO_AE_EP_MODE_MON 0x0A
#define M9MO_AE_EP_MODE_CAP 0x0B
+#define M9MO_AF_AE_LOCK 0x0D
#define M9MO_AE_AUTO_BRACKET_EV 0x20
-#define M9MO_AE_ONESHOT_MAX_EXP 0x36
+#define M9MO_AE_STABILITY 0x21
+#define M9MO_AE_EV_PRG_MODE_CAP 0x34
+#define M9MO_AE_EV_PRG_MODE_MON 0x35
+#define M9MO_AE_EV_PRG_F_NUMBER 0x36
+#define M9MO_AE_EV_PRG_SS_NUMERATOR 0x37
+#define M9MO_AE_EV_PRG_SS_DENOMINATOR 0x39
+#define M9MO_AE_EV_PRG_ISO_VALUE 0x3B
+#define M9MO_AE_EV_PRG_F_NUMBER_MON 0x3D
+#define M9MO_AE_EV_PRG_SS_NUMERATOR_MON 0x3E
+#define M9MO_AE_EV_PRG_SS_DENOMINATOR_MON 0x40
+#define M9MO_AE_EV_PRG_ISO_VALUE_MON 0x42
+#define M9MO_AE_NOW_AV 0x54
+#define M9MO_AE_NOW_TV 0x58
+#define M9MO_AE_NOW_SV 0x5C
+#define M9MO_AE_NOW_LV 0x52
/* M9MO_CATEGORY_NEW: 0x04 */
+#define M9MO_NEW_TIME_INFO 0x02
#define M9MO_NEW_DETECT_SCENE 0x0B
+#define M9MO_NEW_OIS_VERSION 0x1B
+
+/* M9MO_CATEGORY_PRO_MODE: 0x05 */
+#define M9MO_PRO_SMART_READ1 0x20
+#define M9MO_PRO_SMART_READ2 0x24
+#define M9MO_PRO_SMART_READ3 0x28
/* M9MO_CATEGORY_WB: 0x06 */
#define M9MO_AWB_LOCK 0x00
#define M9MO_WB_AWB_MODE 0x02
#define M9MO_WB_AWB_MANUAL 0x03
+#define M9MO_WB_GBAM_MODE 0x8D
+#define M9MO_WB_G_VALUE 0x8E
+#define M9MO_WB_B_VALUE 0x8F
+#define M9MO_WB_A_VALUE 0x90
+#define M9MO_WB_M_VALUE 0x91
+#define M9MO_WB_K_VALUE 0x92
+#define M9MO_WB_CWB_MODE 0x93
+#define M9MO_WB_SET_CUSTOM_RG 0x94
+#define M9MO_WB_SET_CUSTOM_BG 0x96
+#define M9MO_WB_GET_CUSTOM_RG 0x98
+#define M9MO_WB_GET_CUSTOM_BG 0x9A
+#define M9MO_WB_WBB_MODE 0x9C
+#define M9MO_WB_WBB_AB 0x9D
+#define M9MO_WB_WBB_GM 0x9E
/* M9MO_CATEGORY_EXIF: 0x07 */
#define M9MO_EXIF_EXPTIME_NUM 0x00
@@ -321,12 +471,31 @@ struct m9mo_state {
#define M9MO_EXIF_EBV_DEN 0x24
#define M9MO_EXIF_ISO 0x28
#define M9MO_EXIF_FLASH 0x2A
+#define M9MO_EXIF_AV_NUM 0x10
+#define M9MO_EXIF_AV_DEN 0x14
+#define M9MO_EXIF_FL 0x11
+#define M9MO_EXIF_FL_35 0x13
+
+/* M9MO_CATEGORY_OT: 0x08 */
+#define M9MO_OT_TRACKING_CTL 0x00
+#define M9MO_OT_INFO_READY 0x01
+#define M9MO_OT_X_START_LOCATION 0x05
+#define M9MO_OT_Y_START_LOCATION 0x07
+#define M9MO_OT_X_END_LOCATION 0x09
+#define M9MO_OT_Y_END_LOCATION 0x0B
+#define M9MO_OT_TRACKING_X_LOCATION 0x10
+#define M9MO_OT_TRACKING_Y_LOCATION 0x12
+#define M9MO_OT_TRACKING_FRAME_WIDTH 0x14
+#define M9MO_OT_TRACKING_FRAME_HEIGHT 0x16
+#define M9MO_OT_TRACKING_STATUS 0x18
+#define M9MO_OT_FRAME_WIDTH 0x30
/* M9MO_CATEGORY_FD: 0x09 */
#define M9MO_FD_CTL 0x00
#define M9MO_FD_SIZE 0x01
#define M9MO_FD_MAX 0x02
#define M9MO_FD_RED_EYE 0x55
+#define M9MO_FD_RED_DET_STATUS 0x56
#define M9MO_FD_BLINK_FRAMENO 0x59
#define M9MO_FD_BLINK_LEVEL_1 0x5A
#define M9MO_FD_BLINK_LEVEL_2 0x5B
@@ -334,12 +503,14 @@ struct m9mo_state {
/* M9MO_CATEGORY_LENS: 0x0A */
#define M9MO_LENS_AF_INITIAL 0x00
-#define M9MO_LENS_AF_MODE 0x01
+#define M9MO_LENS_AF_LENS_CLOSE 0x01
#define M9MO_LENS_AF_ZOOM_CTRL 0x02
#define M9MO_LENS_AF_START_STOP 0x03
-#define M9MO_LENS_AF_STATUS 0x03
#define M9MO_LENS_AF_IRIS_STEP 0x05
#define M9MO_LENS_AF_ZOOM_LEVEL 0x06
+#define M9MO_LENS_AF_SCAN_RANGE 0x07
+#define M9MO_LENS_AF_MODE 0x08
+#define M9MO_LENS_AF_WINDOW_MODE 0x09
#define M9MO_LENS_AF_BACKLASH_ADJ 0x0A
#define M9MO_LENS_AF_FOCUS_ADJ 0x0B
#define M9MO_LENS_AF_TILT_ADJ 0x0C
@@ -348,9 +519,18 @@ struct m9mo_state {
#define M9MO_LENS_AF_ZOOM_ADJ 0x0F
#define M9MO_LENS_AF_ADJ_TEMP_VALUE 0x0C
#define M9MO_LENS_AF_ALGORITHM 0x0D
+#define M9MO_LENS_ZOOM_LEVEL_INFO 0x10
+#define M9MO_LENS_AF_LED 0x1C
#define M9MO_LENS_AF_CAL 0x1D
+#define M9MO_LENS_AF_RESULT 0x20
+#define M9MO_LENS_ZOOM_SET_INFO 0x22
+#define M9MO_LENS_ZOOM_SPEED 0x25
+#define M9MO_LENS_ZOOM_STATUS 0x26
+#define M9MO_LENS_LENS_STATUS 0x28
+#define M9MO_LENS_ZOOM_LENS_STATUS 0x2A
#define M9MO_LENS_AF_TOUCH_POSX 0x30
#define M9MO_LENS_AF_TOUCH_POSY 0x32
+#define M9MO_LENS_AF_VERSION 0x60
/* M9MO_CATEGORY_CAPPARM: 0x0B */
#define M9MO_CAPPARM_YUVOUT_MAIN 0x00
@@ -364,9 +544,13 @@ struct m9mo_state {
#define M9MO_CAPPARM_JPEG_RATIO 0x17
#define M9MO_CAPPARM_MCC_MODE 0x1D
#define M9MO_CAPPARM_STROBE_EN 0x22
+#define M9MO_CAPPARM_STROBE_CHARGE 0x27
+#define M9MO_CAPPARM_STROBE_EVC 0x28
+#define M9MO_CAPPARM_STROBE_UP_DOWN 0x29
#define M9MO_CAPPARM_WDR_EN 0x2C
-#define M9MO_CAPPARM_JPEG_RATIO_OFS 0x34
+#define M9MO_CAPPARM_JPEG_RATIO_OFS 0x1B
#define M9MO_CAPPARM_THUMB_JPEG_MAX 0x3C
+#define M9MO_CAPPARM_STROBE_BATT_INFO 0x3F
#define M9MO_CAPPARM_AFB_CAP_EN 0x53
/* M9MO_CATEGORY_CAPCTRL: 0x0C */
@@ -376,6 +560,7 @@ struct m9mo_state {
#define M9MO_CAPCTRL_START_DUALCAP 0x05
#define M9MO_CAPCTRL_FRM_SEL 0x06
#define M9MO_CAPCTRL_FRM_PRV_SEL 0x07
+#define M9MO_CAPCTRL_FRM_THUMB_SEL 0x08
#define M9MO_CAPCTRL_TRANSFER 0x09
#define M9MO_CAPCTRL_IMG_SIZE 0x0D
#define M9MO_CAPCTRL_THUMB_SIZE 0x11
@@ -388,6 +573,7 @@ struct m9mo_state {
#define M9MO_CAP_MODE_ADDPIXEL_CAPTURE (0x08)
#define M9MO_CAP_MODE_PANORAMA_CAPTURE (0x0B)
#define M9MO_CAP_MODE_BLINK_CAPTURE (0x0C)
+#define M9MO_CAP_MODE_RAW (0x0D)
/* M9MO_CATEGORY_ADJST: 0x0E */
#define M9MO_ADJST_SHUTTER_MODE 0x33
@@ -426,6 +612,8 @@ struct m9mo_state {
#define M9MO_INT_MODE (1 << 8)
#define M9MO_INT_ATSCENE (1 << 7)
#define M9MO_INT_ATSCENE_UPDATE (1 << 6)
+#define M9MO_INT_AF_STATUS (1 << 5)
+#define M9MO_INT_OIS_SET (1 << 4)
#define M9MO_INT_OIS_INIT (1 << 3)
#define M9MO_INT_STNW_DETECT (1 << 2)
#define M9MO_INT_SCENARIO_FIN (1 << 1)
diff --git a/drivers/media/video/s5c73m3.c b/drivers/media/video/s5c73m3.c
index 47c4297..b8d3574 100644
--- a/drivers/media/video/s5c73m3.c
+++ b/drivers/media/video/s5c73m3.c
@@ -29,6 +29,7 @@
#ifdef S5C73M3_BUSFREQ_OPP
#include <mach/dev.h>
+#include <plat/cpu.h>
#endif
#ifdef CONFIG_VIDEO_SAMSUNG_V4L2
@@ -37,7 +38,10 @@
#endif
#include <linux/regulator/machine.h>
+
+#ifdef CONFIG_LEDS_AAT1290A
#include <linux/leds-aat1290a.h>
+#endif
#include <media/s5c73m3_platform.h>
#include "s5c73m3.h"
@@ -70,12 +74,16 @@ static const struct s5c73m3_frmsizeenum preview_frmsizes[] = {
{ S5C73M3_PREVIEW_QVGA, 320, 240, 0x01 },
{ S5C73M3_PREVIEW_CIF, 352, 288, 0x0E },
{ S5C73M3_PREVIEW_VGA, 640, 480, 0x02 },
- { S5C73M3_PREVIEW_800X600, 800, 600, 0x09 },
{ S5C73M3_PREVIEW_880X720, 880, 720, 0x03 },
{ S5C73M3_PREVIEW_960X720, 960, 720, 0x04 },
{ S5C73M3_PREVIEW_1008X672, 1008, 672, 0x0F },
{ S5C73M3_PREVIEW_1184X666, 1184, 666, 0x05 },
{ S5C73M3_PREVIEW_720P, 1280, 720, 0x06 },
+#ifdef CONFIG_MACH_T0
+ { S5C73M3_PREVIEW_1280X960, 1280, 960, 0x09 },
+#else
+ { S5C73M3_PREVIEW_800X600, 800, 600, 0x09 },
+#endif
{ S5C73M3_VDIS_720P, 1536, 864, 0x07 },
{ S5C73M3_PREVIEW_1080P, 1920, 1080, 0x0A},
{ S5C73M3_VDIS_1080P, 2304, 1296, 0x0C},
@@ -113,6 +121,7 @@ static const struct s5c73m3_effectenum s5c73m3_effects[] = {
{IMAGE_EFFECT_POINT_RED_YELLOW, S5C73M3_IMAGE_EFFECT_POINT_RED_YELLOW},
{IMAGE_EFFECT_POINT_COLOR_3, S5C73M3_IMAGE_EFFECT_POINT_COLOR_3},
{IMAGE_EFFECT_POINT_GREEN, S5C73M3_IMAGE_EFFECT_POINT_GREEN},
+ {IMAGE_EFFECT_CARTOONIZE, S5C73M3_IMAGE_EFFECT_CARTOONIZE},
};
static struct s5c73m3_control s5c73m3_ctrls[] = {
@@ -397,19 +406,19 @@ void s5c73m3_make_CRC_table(u32 *table, u32 id)
{
u32 i, j, k;
- for(i = 0; i < 256; ++i) {
+ for (i = 0; i < 256; ++i) {
k = i;
- for(j = 0; j < 8; ++j) {
- if(k & 1)
+ for (j = 0; j < 8; ++j) {
+ if (k & 1)
k = (k >> 1) ^ id;
- else
+ else
k >>= 1;
}
table[i] = k;
}
}
-static int s5c73m3_reset_module(struct v4l2_subdev *sd, bool powerReset)
+static int s5c73m3_reset_module(struct v4l2_subdev *sd, bool powerReset)
{
struct s5c73m3_state *state = to_state(sd);
int err = 0;
@@ -468,7 +477,7 @@ static int s5c73m3_set_mode(struct v4l2_subdev *sd)
cam_trace("E\n");
if (state->format_mode != V4L2_PIX_FMT_MODE_CAPTURE) {
- if (state->hdr_mode) {
+ if (state->hdr_mode || state->yuv_snapshot) {
err = s5c73m3_writeb(sd, S5C73M3_IMG_OUTPUT,
S5C73M3_HDR_OUTPUT);
CHECK_ERR(err);
@@ -574,13 +583,23 @@ static int s5c73m3_get_sensor_fw_binary(struct v4l2_subdev *sd)
mm_segment_t old_fs;
long ret = 0;
char fw_path[25] = {0,};
- u8 mem0 =0, mem1 = 0;
+ u8 mem0 = 0, mem1 = 0;
u32 CRC = 0;
u32 DataCRC = 0;
u32 IntOriginalCRC = 0;
u32 crc_index = 0;
int retryCnt = 2;
+#ifdef CONFIG_MACH_T0
+ if (state->sensor_fw[1] == 'D') {
+ sprintf(fw_path, "/data/cfw/SlimISP_%cK.bin",
+ state->sensor_fw[0]);
+ } else {
+ sprintf(fw_path, "/data/cfw/SlimISP_%c%c.bin",
+ state->sensor_fw[0],
+ state->sensor_fw[1]);
+ }
+#else
if (state->sensor_fw[0] == 'O') {
sprintf(fw_path, "/data/cfw/SlimISP_G%c.bin",
state->sensor_fw[1]);
@@ -592,6 +611,7 @@ static int s5c73m3_get_sensor_fw_binary(struct v4l2_subdev *sd)
state->sensor_fw[0],
state->sensor_fw[1]);
}
+#endif
/* Make CRC Table */
s5c73m3_make_CRC_table((u32 *)&crc_table, 0xEDB88320);
@@ -664,7 +684,7 @@ static int s5c73m3_get_sensor_fw_binary(struct v4l2_subdev *sd)
retry:
memset(data_memory, 0, sizeof(data_memory));
- mem0 =0, mem1 = 0;
+ mem0 = 0, mem1 = 0;
CRC = 0;
DataCRC = 0;
IntOriginalCRC = 0;
@@ -684,7 +704,7 @@ retry:
CHECK_ERR(err);
CRC = ~CRC;
- for(crc_index = 0;crc_index < (state->sensor_size-4)/2;crc_index++) {
+ for (crc_index = 0; crc_index < (state->sensor_size-4)/2; crc_index++) {
/*low byte*/
mem0 = (unsigned char)(data_memory[crc_index*2] & 0x00ff);
/*high byte*/
@@ -823,7 +843,7 @@ static int s5c73m3_get_sensor_fw_version(struct v4l2_subdev *sd)
err = s5c73m3_write(sd, 0x3010, 0x00A4, 0x0183);
CHECK_ERR(err);
- for (i = 0; i < 6; i++) {
+ for (i = 0; i < 5; i++) {
err = s5c73m3_read(sd, 0x0000, 0x06+i*2, &sensor_type);
CHECK_ERR(err);
state->sensor_type[i*2] = sensor_type&0x00ff;
@@ -950,6 +970,16 @@ static int s5c73m3_get_phone_fw_version(struct v4l2_subdev *sd)
int retVal = 0;
int fw_requested = 1;
+#ifdef CONFIG_MACH_T0
+ if (state->sensor_fw[1] == 'D') {
+ sprintf(fw_path, "SlimISP_%cK.bin",
+ state->sensor_fw[0]);
+ } else {
+ sprintf(fw_path, "SlimISP_%c%c.bin",
+ state->sensor_fw[0],
+ state->sensor_fw[1]);
+ }
+#else
if (state->sensor_fw[0] == 'O') {
sprintf(fw_path, "SlimISP_G%c.bin",
state->sensor_fw[1]);
@@ -961,6 +991,8 @@ static int s5c73m3_get_phone_fw_version(struct v4l2_subdev *sd)
state->sensor_fw[0],
state->sensor_fw[1]);
}
+#endif
+
sprintf(fw_path_in_data, "/data/cfw/%s",
fw_path);
@@ -1184,7 +1216,14 @@ static int s5c73m3_check_fw_date(struct v4l2_subdev *sd)
phone_date,
strcmp((char *)&sensor_date, (char *)&phone_date));
+#ifdef CONFIG_MACH_T0
+ if (state->sensor_fw[1] == 'D')
+ return -1;
+ else
+ return strcmp((char *)&sensor_date, (char *)&phone_date);
+#else
return strcmp((char *)&sensor_date, (char *)&phone_date);
+#endif
}
static int s5c73m3_check_fw(struct v4l2_subdev *sd, int download)
@@ -1210,9 +1249,9 @@ static int s5c73m3_check_fw(struct v4l2_subdev *sd, int download)
/* retVal = 0 : Same Version
retVal < 0 : Phone Version is latest Version than sensorFW.
retVal > 0 : Sensor Version is latest version than phoenFW. */
- if (retVal <= 0||download) {
+ if (retVal <= 0 || download) {
cam_dbg("Loading From PhoneFW......\n");
-
+
/* In case that there is no FW in phone and FW needs to be
downloaded from F-ROM, ISP power reset is required before
loading FW to ISP for F-ROM to work properly.*/
@@ -1276,8 +1315,17 @@ static int s5c73m3_set_flash(struct v4l2_subdev *sd, int val, int recording)
{
struct s5c73m3_state *state = to_state(sd);
int err;
+ u16 pre_flash = false;
cam_dbg("E, value %d\n", val);
+ s5c73m3_read(sd, 0x0009, S5C73M3_STILL_PRE_FLASH | 0x5000, &pre_flash);
+ if (pre_flash) {
+ err = s5c73m3_writeb(sd, S5C73M3_STILL_MAIN_FLASH
+ , S5C73M3_STILL_MAIN_FLASH_CANCEL);
+ CHECK_ERR(err);
+ state->isflash = S5C73M3_ISNEED_FLASH_UNDEFINED;
+ }
+
retry:
switch (val) {
case FLASH_MODE_OFF:
@@ -1452,6 +1500,31 @@ static int s5c73m3_set_contrast(struct v4l2_subdev *sd,
return 0;
}
+static int s5c73m3_set_sharpness(struct v4l2_subdev *sd,
+ struct v4l2_control *ctrl)
+{
+ int err;
+ int sharpness = 0;
+ int temp_sharpness = 0;
+ cam_dbg("E, value %d\n", ctrl->value);
+
+ if (ctrl->value < 0 || ctrl->value > 4) {
+ cam_warn("invalid value, %d\n", ctrl->value);
+ ctrl->value = 2;
+ }
+ temp_sharpness = ctrl->value - 2;
+ if (temp_sharpness < 0)
+ sharpness = (temp_sharpness * (-1)) + 2;
+ else
+ sharpness = temp_sharpness;
+ err = s5c73m3_writeb(sd, S5C73M3_SHARPNESS,
+ sharpness);
+ CHECK_ERR(err);
+
+ cam_trace("X\n");
+ return 0;
+}
+
static int s5c73m3_set_whitebalance(struct v4l2_subdev *sd, int val)
{
struct s5c73m3_state *state = to_state(sd);
@@ -1594,6 +1667,12 @@ retry:
CHECK_ERR(err);
break;
+ case SCENE_MODE_LOW_LIGHT:
+ err = s5c73m3_writeb(sd, S5C73M3_SCENE_MODE,
+ S5C73M3_SCENE_MODE_LOW_LIGHT);
+ CHECK_ERR(err);
+ break;
+
default:
cam_warn("invalid value, %d\n", val);
val = SCENE_MODE_NONE;
@@ -2143,7 +2222,21 @@ static int s5c73m3_set_frame_rate(struct v4l2_subdev *sd, int fps)
return 0;
}
+ cam_dbg("E, value %d\n", fps);
+
switch (fps) {
+ case 120:
+ err = s5c73m3_writeb(sd, S5C73M3_AE_MODE,
+ S5C73M3_FIXED_120FPS); /* 120fps */
+ break;
+ case 90:
+ err = s5c73m3_writeb(sd, S5C73M3_AE_MODE,
+ S5C73M3_FIXED_90FPS); /* 90fps */
+ break;
+ case 60:
+ err = s5c73m3_writeb(sd, S5C73M3_AE_MODE,
+ S5C73M3_FIXED_60FPS); /* 60fps */
+ break;
case 30:
err = s5c73m3_writeb(sd, S5C73M3_AE_MODE,
S5C73M3_FIXED_30FPS); /* 30fps */
@@ -2160,6 +2253,10 @@ static int s5c73m3_set_frame_rate(struct v4l2_subdev *sd, int fps)
err = s5c73m3_writeb(sd, S5C73M3_AE_MODE,
S5C73M3_FIXED_10FPS); /* 10fps */
break;
+ case 7:
+ err = s5c73m3_writeb(sd, S5C73M3_AE_MODE,
+ S5C73M3_FIXED_7FPS); /* 7fps */
+ break;
default:
err = s5c73m3_writeb(sd, S5C73M3_AE_MODE,
S5C73M3_AUTO_MODE_AE_SET); /* auto */
@@ -2292,6 +2389,19 @@ static int s5c73m3_get_lux(struct v4l2_subdev *sd,
return err;
}
+static int s5c73m3_set_low_light_mode(struct v4l2_subdev *sd, int val)
+{
+ int err;
+ cam_dbg("E, value %d\n", val);
+
+ err = s5c73m3_writeb(sd, S5C73M3_AE_LOW_LIGHT_MODE, val);
+
+ CHECK_ERR(err);
+
+ cam_trace("X\n");
+ return 0;
+}
+
static int s5c73m3_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
{
struct s5c73m3_state *state = to_state(sd);
@@ -2356,6 +2466,10 @@ static int s5c73m3_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
err = s5c73m3_set_contrast(sd, ctrl);
break;
+ case V4L2_CID_CAMERA_SHARPNESS:
+ err = s5c73m3_set_sharpness(sd, ctrl);
+ break;
+
case V4L2_CID_CAMERA_WHITE_BALANCE:
err = s5c73m3_set_whitebalance(sd, ctrl->value);
break;
@@ -2429,6 +2543,16 @@ static int s5c73m3_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
err = 0;
break;
+ case V4L2_CID_CAMERA_FAST_MODE:
+ state->fast_mode = ctrl->value;
+ err = 0;
+ break;
+
+ case V4L2_CID_CAMERA_YUV_SNAPSHOT:
+ state->yuv_snapshot = ctrl->value;
+ err = 0;
+ break;
+
case V4L2_CID_CAMERA_HYBRID_CAPTURE:
err = s5c73m3_set_hybrid_capture(sd);
break;
@@ -2450,6 +2574,10 @@ static int s5c73m3_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
err = s5c73m3_stop_af_lens(sd, ctrl->value);
break;
+ case V4L2_CID_CAMERA_LOW_LIGHT_MODE:
+ err = s5c73m3_set_low_light_mode(sd, ctrl->value);
+ break;
+
default:
cam_err("no such control id %d, value %d\n",
ctrl->id - V4L2_CID_PRIVATE_BASE, ctrl->value);
@@ -2557,6 +2685,16 @@ static int s5c73m3_load_fw(struct v4l2_subdev *sd)
mm_segment_t old_fs;
long fsize = 0, nread;
+#ifdef CONFIG_MACH_T0
+ if (state->sensor_fw[1] == 'D') {
+ sprintf(fw_path, "SlimISP_%cK.bin",
+ state->sensor_fw[0]);
+ } else {
+ sprintf(fw_path, "SlimISP_%c%c.bin",
+ state->sensor_fw[0],
+ state->sensor_fw[1]);
+ }
+#else
if (state->sensor_fw[0] == 'O') {
sprintf(fw_path, "SlimISP_G%c.bin",
state->sensor_fw[1]);
@@ -2568,6 +2706,8 @@ static int s5c73m3_load_fw(struct v4l2_subdev *sd)
state->sensor_fw[0],
state->sensor_fw[1]);
}
+#endif
+
sprintf(fw_path_in_data, "/data/cfw/%s",
fw_path);
@@ -2661,14 +2801,22 @@ static int s5c73m3_set_frmsize(struct v4l2_subdev *sd)
int err ;
cam_trace("E\n");
- if (state->format_mode != V4L2_PIX_FMT_MODE_CAPTURE) {
+ if (state->fast_mode == FAST_MODE_SUBSAMPLING_HALF) {
+ cam_dbg("S5C73M3_FAST_MODE_SUBSAMPLING_HALF\n");
+ err = s5c73m3_writeb(sd, S5C73M3_CHG_MODE,
+ S5C73M3_FAST_MODE_SUBSAMPLING_HALF
+ | state->preview->reg_val | (state->sensor_mode<<8));
+ CHECK_ERR(err);
+ } else if (state->fast_mode == FAST_MODE_SUBSAMPLING_QUARTER) {
+ cam_dbg("S5C73M3_FAST_MODE_SUBSAMPLING_QUARTER\n");
err = s5c73m3_writeb(sd, S5C73M3_CHG_MODE,
- S5C73M3_YUV_MODE | state->preview->reg_val |
- (state->sensor_mode<<8));
+ S5C73M3_FAST_MODE_SUBSAMPLING_QUARTER
+ | state->preview->reg_val | (state->sensor_mode<<8));
CHECK_ERR(err);
} else {
+ cam_dbg("S5C73M3_DEFAULT_MODE\n");
err = s5c73m3_writeb(sd, S5C73M3_CHG_MODE,
- S5C73M3_INTERLEAVED_MODE
+ S5C73M3_DEFAULT_MODE
| state->capture->reg_val | state->preview->reg_val
|(state->sensor_mode<<8));
CHECK_ERR(err);
@@ -2825,7 +2973,7 @@ static int s5c73m3_enum_framesizes(struct v4l2_subdev *sd,
return -EINVAL;
fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
- if (state->hdr_mode) {
+ if (state->hdr_mode || state->yuv_snapshot) {
fsize->discrete.width = state->capture->width;
fsize->discrete.height = state->capture->height;
} else {
@@ -3239,24 +3387,29 @@ static int s5c73m3_read_vdd_core(struct v4l2_subdev *sd)
CHECK_ERR(err);
if (read_val & 0x200) {
- state->pdata->set_vdd_core(1150000);
strcpy(sysfs_isp_core, "1.15V");
+ state->pdata->set_vdd_core(1150000);
vdd_core_val = 1150000;
} else if (read_val & 0x800) {
- state->pdata->set_vdd_core(1100000);
strcpy(sysfs_isp_core, "1.10V");
+#ifdef CONFIG_MACH_M3
+ state->pdata->set_vdd_core(1150000);
+ vdd_core_val = 1150000;
+#else
+ state->pdata->set_vdd_core(1100000);
vdd_core_val = 1100000;
+#endif
} else if (read_val & 0x2000) {
- state->pdata->set_vdd_core(1100000);
strcpy(sysfs_isp_core, "1.05V");
+ state->pdata->set_vdd_core(1100000);
vdd_core_val = 1100000;
} else if (read_val & 0x8000) {
- state->pdata->set_vdd_core(1000000);
strcpy(sysfs_isp_core, "1.00V");
+ state->pdata->set_vdd_core(1000000);
vdd_core_val = 1000000;
} else {
- state->pdata->set_vdd_core(1150000);
strcpy(sysfs_isp_core, "1.15V");
+ state->pdata->set_vdd_core(1150000);
vdd_core_val = 1150000;
}
@@ -3423,7 +3576,11 @@ static ssize_t s5c73m3_camera_rear_flash(struct device *dev,
struct device_attribute *attr, const char *buf,
size_t count)
{
+#ifdef CONFIG_LEDS_AAT1290A
return aat1290a_power(dev, attr, buf, count);
+#else
+ return count;
+#endif
}
static ssize_t s5c73m3_camera_isp_core_show(struct device *dev,
@@ -3471,7 +3628,10 @@ static int __devinit s5c73m3_probe(struct i2c_client *client,
#ifdef S5C73M3_BUSFREQ_OPP
/* lock bus frequency */
- dev_lock(bus_dev, s5c73m3_dev, 400200);
+ if (samsung_rev() >= EXYNOS4412_REV_2_0)
+ dev_lock(bus_dev, s5c73m3_dev, 440220);
+ else
+ dev_lock(bus_dev, s5c73m3_dev, 400200);
#endif
if (s5c73m3_dev)
diff --git a/drivers/media/video/s5c73m3.h b/drivers/media/video/s5c73m3.h
index aaf4007..ca12b2d 100644
--- a/drivers/media/video/s5c73m3.h
+++ b/drivers/media/video/s5c73m3.h
@@ -64,43 +64,33 @@ enum s5c73m3_fw_path{
};
enum s5c73m3_prev_frmsize {
- S5C73M3_PREVIEW_QCIF,
- S5C73M3_PREVIEW_QCIF2,
S5C73M3_PREVIEW_QVGA,
S5C73M3_PREVIEW_CIF,
S5C73M3_PREVIEW_VGA,
S5C73M3_PREVIEW_D1,
- S5C73M3_PREVIEW_WVGA,
S5C73M3_PREVIEW_800X600,
S5C73M3_PREVIEW_880X720,
- S5C73M3_PREVIEW_960X640,
S5C73M3_PREVIEW_960X720,
S5C73M3_PREVIEW_1008X672,
- S5C73M3_PREVIEW_1056X704,
S5C73M3_PREVIEW_1184X666,
S5C73M3_PREVIEW_720P,
+ S5C73M3_PREVIEW_1280X960,
S5C73M3_VDIS_720P,
S5C73M3_PREVIEW_1080P,
S5C73M3_VDIS_1080P,
- S5C73M3_PREVIEW_HDR,
};
enum s5c73m3_cap_frmsize {
S5C73M3_CAPTURE_VGA, /* 640 x 480 */
- S5C73M3_CAPTURE_WVGA, /* 800 x 480 */
S5C73M3_CAPTURE_960x540, /* 960 x 540 */
S5C73M3_CAPTURE_960x720, /* 960 x 720 */
S5C73M3_CAPTURE_1024X768, /* 1024 x 768 */
S5C73M3_CAPTURE_HD, /* 1280 x 720 */
- S5C73M3_CAPTURE_W1MP, /* 1600 x 960 */
S5C73M3_CAPTURE_2MP, /* UXGA - 1600 x 1200 */
S5C73M3_CAPTURE_W2MP, /* 2048 x 1232 */
S5C73M3_CAPTURE_3MP, /* QXGA - 2048 x 1536 */
- S5C73M3_CAPTURE_W4MP, /* WQXGA - 2560 x 1536 */
S5C73M3_CAPTURE_5MP, /* 2560 x 1920 */
S5C73M3_CAPTURE_W6MP, /* 3072 x 1856 */
- S5C73M3_CAPTURE_7MP, /* 3072 x 2304 */
- S5C73M3_CAPTURE_W7MP, /* WQXGA - 2560 x 1536 */
S5C73M3_CAPTURE_3264X2176, /* 3264 x 2176 */
S5C73M3_CAPTURE_8MP, /* 3264 x 2448 */
};
@@ -169,6 +159,8 @@ struct s5c73m3_state {
int vt_mode;
int hdr_mode;
int hybrid_mode;
+ int fast_mode;
+ int yuv_snapshot;
int zoom;
int stream_enable;
int ae_lock;
@@ -233,6 +225,7 @@ struct s5c73m3_state {
#define S5C73M3_IMAGE_EFFECT_POINT_RED_YELLOW 0x000D
#define S5C73M3_IMAGE_EFFECT_POINT_COLOR_3 0x000E
#define S5C73M3_IMAGE_EFFECT_POINT_GREEN 0x000F
+#define S5C73M3_IMAGE_EFFECT_CARTOONIZE 0x001A
#define S5C73M3_IMAGE_QUALITY 0x0B0C
#define S5C73M3_IMAGE_QUALITY_SUPERFINE 0x0000
@@ -255,9 +248,9 @@ struct s5c73m3_state {
#define S5C73M3_CHG_MODE 0x0B10
-#define S5C73M3_YUV_MODE 0x8000
-#define S5C73M3_INTERLEAVED_MODE 0x8000
-
+#define S5C73M3_DEFAULT_MODE 0x8000
+#define S5C73M3_FAST_MODE_SUBSAMPLING_HALF 0xA000
+#define S5C73M3_FAST_MODE_SUBSAMPLING_QUARTER 0xC000
#define S5C73M3_AF_CON 0x0E00
#define S5C73M3_AF_CON_STOP 0x0000
@@ -351,9 +344,11 @@ struct s5c73m3_state {
#define S5C73M3_FIXED_30FPS 0x0002
#define S5C73M3_FIXED_20FPS 0x0003
#define S5C73M3_FIXED_15FPS 0x0004
+#define S5C73M3_FIXED_60FPS 0x0007
#define S5C73M3_FIXED_120FPS 0x0008
#define S5C73M3_FIXED_7FPS 0x0009
#define S5C73M3_FIXED_10FPS 0x000A
+#define S5C73M3_FIXED_90FPS 0x000B
#define S5C73M3_ANTI_SHAKE 0x0013
#define S5C73M3_SHARPNESS 0x0C14
@@ -392,10 +387,13 @@ struct s5c73m3_state {
#define S5C73M3_SCENE_MODE_FIRE 0x000B
#define S5C73M3_SCENE_MODE_TEXT 0x000C
#define S5C73M3_SCENE_MODE_CANDLE 0x000D
+#define S5C73M3_SCENE_MODE_LOW_LIGHT 0x0020
#define S5C73M3_FIREWORK_CAPTURE 0x0C20
#define S5C73M3_NIGHTSHOT_CAPTURE 0x0C22
+#define S5C73M3_AE_LOW_LIGHT_MODE 0x0C2C
+
#define S5C73M3_AE_AUTO_BRAKET 0x0B14
#define S5C73M3_AE_AUTO_BRAKET_EV05 0x0080
#define S5C73M3_AE_AUTO_BRAKET_EV10 0x0100
diff --git a/drivers/media/video/s5k5bbgx.c b/drivers/media/video/s5k5bbgx.c
new file mode 100644
index 0000000..329ead4
--- /dev/null
+++ b/drivers/media/video/s5k5bbgx.c
@@ -0,0 +1,1738 @@
+/*
+ * Driver for S5K5BBGX from Samsung Electronics
+ *
+ * 1/6" 2Mp CMOS Image Sensor SoC with an Embedded Image Processor
+ *
+ * Copyright (C) 2010, DongSeong Lim<dongseong.lim@samsung.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.
+ */
+
+#include <linux/i2c.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/version.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-subdev.h>
+#ifdef CONFIG_VIDEO_SAMSUNG_V4L2
+#include <linux/videodev2_exynos_camera.h>
+#endif
+#include <media/s5k5bbgx_platform.h>
+
+#include "s5k5bbgx.h"
+
+
+
+#ifdef S5K5BBGX_USLEEP
+#include <linux/hrtimer.h>
+#endif
+
+#define S5K5BBGX_BURST_MODE
+
+#ifdef CONFIG_LOAD_FILE
+#include <linux/vmalloc.h>
+#include <linux/fs.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <linux/uaccess.h>
+
+struct test {
+ u8 data;
+ struct test *nextBuf;
+};
+static struct test *testBuf;
+static s32 large_file;
+
+#define TEST_INIT \
+{ \
+ .data = 0; \
+ .nextBuf = NULL; \
+}
+#endif
+
+#define CHECK_ERR(x) if (unlikely((x) < 0)) { \
+ cam_err("i2c failed, err %d\n", x); \
+ return x; \
+ }
+#define NELEMS(array) (sizeof(array) / sizeof(array[0]))
+
+#ifdef S5K5BBGX_USLEEP
+/*
+ * Use msleep() if the sleep time is over 1000 us.
+*/
+static void s5k5bbgx_usleep(u32 usecs)
+{
+ ktime_t expires;
+ u64 add_time = (u64)usecs * 1000;
+
+ if (unlikely(!usecs))
+ return;
+
+ expires = ktime_add_ns(ktime_get(), add_time);
+ set_current_state(TASK_UNINTERRUPTIBLE);
+ schedule_hrtimeout(&expires, HRTIMER_MODE_ABS);
+}
+#endif
+
+static inline int s5k5bbgx_read(struct i2c_client *client,
+ u16 subaddr, u16 *data)
+{
+ u8 buf[2];
+ int err = 0;
+ struct i2c_msg msg = {
+ .addr = client->addr,
+ .flags = 0,
+ .len = 2,
+ .buf = buf,
+ };
+
+ *(u16 *)buf = cpu_to_be16(subaddr);
+
+ /* printk("\n\n\n%X %X\n\n\n", buf[0], buf[1]);*/
+
+ err = i2c_transfer(client->adapter, &msg, 1);
+ if (unlikely(err < 0))
+ cam_err("ERR: %d register read fail\n", __LINE__);
+
+ msg.flags = I2C_M_RD;
+
+ err = i2c_transfer(client->adapter, &msg, 1);
+ if (unlikely(err < 0))
+ cam_err("ERR: %d register read fail\n", __LINE__);
+
+ /*printk("\n\n\n%X %X\n\n\n", buf[0], buf[1]);*/
+ *data = ((buf[0] << 8) | buf[1]);
+
+ return err;
+}
+
+/*
+ * s5k6aafx sensor i2c write routine
+ * <start>--<Device address><2Byte Subaddr><2Byte Value>--<stop>
+ */
+#ifdef CONFIG_LOAD_FILE
+static int loadFile(void)
+{
+ struct file *fp = NULL;
+ struct test *nextBuf = NULL;
+
+ u8 *nBuf = NULL;
+ size_t file_size = 0, max_size = 0, testBuf_size = 0;
+ ssize_t nread = 0;
+ s32 check = 0, starCheck = 0;
+ s32 tmp_large_file = 0;
+ s32 i = 0;
+ int ret = 0;
+ loff_t pos;
+
+ mm_segment_t fs = get_fs();
+ set_fs(get_ds());
+
+ BUG_ON(testBuf);
+
+ fp = filp_open("/mnt/sdcard/external_sd/s5k5bbgx_setfile.h",
+ O_RDONLY, 0);
+ if (IS_ERR(fp)) {
+ cam_err("file open error\n");
+ return PTR_ERR(fp);
+ }
+
+ file_size = (size_t) fp->f_path.dentry->d_inode->i_size;
+ max_size = file_size;
+
+ cam_dbg("file_size = %d\n", file_size);
+
+ nBuf = kmalloc(file_size, GFP_ATOMIC);
+ if (nBuf == NULL) {
+ cam_dbg("Fail to 1st get memory\n");
+ nBuf = vmalloc(file_size);
+ if (nBuf == NULL) {
+ cam_err("ERR: nBuf Out of Memory\n");
+ ret = -ENOMEM;
+ goto error_out;
+ }
+ tmp_large_file = 1;
+ }
+
+ testBuf_size = sizeof(struct test) * file_size;
+ if (tmp_large_file) {
+ testBuf = vmalloc(testBuf_size);
+ large_file = 1;
+ } else {
+ testBuf = kmalloc(testBuf_size, GFP_ATOMIC);
+ if (testBuf == NULL) {
+ cam_dbg("Fail to get mem(%d bytes)\n", testBuf_size);
+ testBuf = vmalloc(testBuf_size);
+ large_file = 1;
+ }
+ }
+ if (testBuf == NULL) {
+ cam_err("ERR: Out of Memory\n");
+ ret = -ENOMEM;
+ goto error_out;
+ }
+
+ pos = 0;
+ memset(nBuf, 0, file_size);
+ memset(testBuf, 0, file_size * sizeof(struct test));
+
+ nread = vfs_read(fp, (char __user *)nBuf, file_size, &pos);
+ if (nread != file_size) {
+ cam_err("failed to read file ret = %d\n", nread);
+ ret = -1;
+ goto error_out;
+ }
+
+ set_fs(fs);
+
+ i = max_size;
+
+ printk(KERN_INFO "i = %d\n", i);
+
+ while (i) {
+ testBuf[max_size - i].data = *nBuf;
+ if (i != 1) {
+ testBuf[max_size - i].nextBuf =
+ &testBuf[max_size - i + 1];
+ } else {
+ testBuf[max_size - i].nextBuf = NULL;
+ break;
+ }
+ i--;
+ nBuf++;
+ }
+
+ i = max_size;
+ nextBuf = &testBuf[0];
+
+#if 1
+ while (i - 1) {
+ if (!check && !starCheck) {
+ if (testBuf[max_size - i].data == '/') {
+ if (testBuf[max_size-i].nextBuf != NULL) {
+ if (testBuf[max_size-i].nextBuf->data
+ == '/') {
+ check = 1;/* when find '//' */
+ i--;
+ } else if (
+ testBuf[max_size-i].nextBuf->data == '*') {
+ starCheck = 1;
+ /* when find '/ *' */
+ i--;
+ }
+ } else
+ break;
+ }
+ if (!check && !starCheck) {
+ /* ignore '\t' */
+ if (testBuf[max_size - i].data != '\t') {
+ nextBuf->nextBuf = &testBuf[max_size-i];
+ nextBuf = &testBuf[max_size - i];
+ }
+ }
+ } else if (check && !starCheck) {
+ if (testBuf[max_size - i].data == '/') {
+ if (testBuf[max_size-i].nextBuf != NULL) {
+ if (
+ testBuf[max_size-i].nextBuf->data == '*') {
+ starCheck = 1;
+ /* when find '/ *' */
+ check = 0;
+ i--;
+ }
+ } else
+ break;
+ }
+
+ /* when find '\n' */
+ if (testBuf[max_size - i].data == '\n' && check) {
+ check = 0;
+ nextBuf->nextBuf = &testBuf[max_size - i];
+ nextBuf = &testBuf[max_size - i];
+ }
+
+ } else if (!check && starCheck) {
+ if (testBuf[max_size - i].data == '*') {
+ if (testBuf[max_size-i].nextBuf != NULL) {
+ if (
+ testBuf[max_size-i].nextBuf->data == '/') {
+ starCheck = 0;
+ /* when find '* /' */
+ i--;
+ }
+ } else
+ break;
+ }
+ }
+
+ i--;
+
+ if (i < 2) {
+ nextBuf = NULL;
+ break;
+ }
+
+ if (testBuf[max_size - i].nextBuf == NULL) {
+ nextBuf = NULL;
+ break;
+ }
+ }
+#endif
+
+#if 0 /* for print */
+ printk(KERN_INFO "i = %d\n", i);
+ nextBuf = &testBuf[0];
+ while (1) {
+ /* printk("sdfdsf\n"); */
+ if (nextBuf->nextBuf == NULL)
+ break;
+ printk(KERN_INFO "%c", nextBuf->data);
+ nextBuf = nextBuf->nextBuf;
+ }
+#endif
+
+error_out:
+
+/* if (nBuf)*/
+ tmp_large_file ? vfree(nBuf) : kfree(nBuf);
+ if (fp)
+ filp_close(fp, current->files);
+ return ret;
+}
+#endif
+
+static inline int s5k5bbgx_write(struct i2c_client *client,
+ u32 packet)
+{
+ u8 buf[4];
+ int err = 0, retry_count = 5;
+
+ struct i2c_msg msg = {
+ .addr = client->addr,
+ .flags = 0,
+ .buf = buf,
+ .len = 4,
+ };
+
+ if (!client->adapter) {
+ cam_err("ERR - can't search i2c client adapter\n");
+ return -EIO;
+ }
+
+ while (retry_count--) {
+ *(u32 *)buf = cpu_to_be32(packet);
+ err = i2c_transfer(client->adapter, &msg, 1);
+ if (likely(err == 1))
+ break;
+ mdelay(10);
+ }
+
+ if (unlikely(err < 0)) {
+ cam_err("ERR - 0x%08x write failed err=%d\n",
+ (u32)packet, err);
+ return err;
+ }
+
+ return (err != 1) ? -1 : 0;
+}
+
+#ifdef CONFIG_LOAD_FILE
+static int s5k5bbgx_write_regs_from_sd(struct v4l2_subdev *sd, u8 s_name[])
+{
+
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct test *tempData = NULL;
+
+ int ret = -EAGAIN;
+ u32 temp;
+ u32 delay = 0;
+ u8 data[11];
+ s32 searched = 0;
+ size_t size = strlen(s_name);
+ s32 i;
+
+ cam_dbg("E size = %d, string = %s\n", size, s_name);
+ tempData = &testBuf[0];
+ while (!searched) {
+ searched = 1;
+ for (i = 0; i < size; i++) {
+ if (tempData->data != s_name[i]) {
+ searched = 0;
+ break;
+ }
+ tempData = tempData->nextBuf;
+ }
+ tempData = tempData->nextBuf;
+ }
+ /* structure is get..*/
+
+ while (1) {
+ if (tempData->data == '{')
+ break;
+ else
+ tempData = tempData->nextBuf;
+ }
+
+ while (1) {
+ searched = 0;
+ while (1) {
+ if (tempData->data == 'x') {
+ /* get 10 strings.*/
+ data[0] = '0';
+ for (i = 1; i < 11; i++) {
+ data[i] = tempData->data;
+ tempData = tempData->nextBuf;
+ }
+ /*cam_dbg("%s\n", data);*/
+ temp = kstrtol(data, NULL, 16);
+ /*patch error: kstrtol is
+ * substitute for simple_strtol*/
+ break;
+ } else if (tempData->data == '}') {
+ searched = 1;
+ break;
+ } else
+ tempData = tempData->nextBuf;
+
+ if (tempData->nextBuf == NULL)
+ return -1;
+ }
+
+ if (searched)
+ break;
+
+ if ((temp & S5K5BBGX_DELAY) == S5K5BBGX_DELAY) {
+ delay = temp & 0xFFFF;
+ cam_info("line(%d):delay(0x%x, %d)\n", __LINE__,
+ delay, delay);
+ msleep(delay);
+ continue;
+ }
+
+ ret = s5k5bbgx_write(client, temp);
+
+ /* In error circumstances */
+ /* Give second shot */
+ if (unlikely(ret)) {
+ dev_info(&client->dev,
+ "s5k5bbgx i2c retry one more time\n");
+ ret = s5k5bbgx_write(client, temp);
+
+ /* Give it one more shot */
+ if (unlikely(ret)) {
+ dev_info(&client->dev,
+ "s5k5bbgx i2c retry twice\n");
+ ret = s5k5bbgx_write(client, temp);
+ }
+ }
+ }
+
+ return ret;
+}
+#endif
+
+/*
+* Read a register.
+*/
+static int s5k5bbgx_read_reg(struct v4l2_subdev *sd,
+ u16 page, u16 addr, u16 *val)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ u32 page_cmd = (0x002C << 16) | page;
+ u32 addr_cmd = (0x002E << 16) | addr;
+ int err = 0;
+
+ cam_dbg("page_cmd=0x%X, addr_cmd=0x%X\n", page_cmd, addr_cmd);
+
+ err = s5k5bbgx_write(client, page_cmd);
+ CHECK_ERR(err);
+ err = s5k5bbgx_write(client, addr_cmd);
+ CHECK_ERR(err);
+ err = s5k5bbgx_read(client, 0x0F12, val);
+ CHECK_ERR(err);
+
+ return 0;
+}
+#ifdef S5K5BBGX_BURST_MODE
+ static u16 addr, value;
+
+ static int len;
+ static u8 buf[SZ_2K] = {0,};
+#else
+ static u8 buf[4] = {0,};
+#endif
+/* program multiple registers */
+static int s5k5bbgx_write_regs(struct v4l2_subdev *sd,
+ const u32 *packet, u32 num)
+{
+ struct s5k5bbgx_state *state = to_state(sd);
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ int ret = -EAGAIN;
+ u32 temp = 0;
+ u16 delay = 0;
+ int retry_count = 5;
+
+
+ struct i2c_msg msg = {
+ msg.addr = client->addr,
+ msg.flags = 0,
+ msg.len = 4,
+ msg.buf = buf,
+ };
+
+ while (num--) {
+ temp = *packet++;
+
+ if ((temp & S5K5BBGX_DELAY) == S5K5BBGX_DELAY) {
+ delay = temp & 0xFFFF;
+ cam_dbg("line(%d):delay(0x%x):delay(%d)\n",
+ __LINE__, delay, delay);
+ msleep(delay);
+ continue;
+ }
+
+#ifdef S5K5BBGX_BURST_MODE
+ addr = temp >> 16;
+ value = temp & 0xFFFF;
+
+ switch (addr) {
+ case 0x0F12:
+ if (len == 0) {
+ buf[len++] = addr >> 8;
+ buf[len++] = addr & 0xFF;
+ }
+ buf[len++] = value >> 8;
+ buf[len++] = value & 0xFF;
+
+ if ((*packet >> 16) != addr) {
+ msg.len = len;
+ goto s5k5bbgx_burst_write;
+ }
+ break;
+
+ case 0xFFFF:
+ break;
+
+ default:
+ msg.len = 4;
+ *(u32 *)buf = cpu_to_be32(temp);
+ goto s5k5bbgx_burst_write;
+ }
+
+ continue;
+#else
+ *(u32 *)buf = cpu_to_be32(temp);
+#endif
+
+#ifdef S5K5BBGX_BURST_MODE
+s5k5bbgx_burst_write:
+ len = 0;
+#endif
+ retry_count = 5;
+
+ while (retry_count--) {
+ ret = i2c_transfer(client->adapter, &msg, 1);
+ if (likely(ret == 1))
+ break;
+ mdelay(10);
+ }
+
+ if (unlikely(ret < 0)) {
+ cam_err("ERR - 0x%08x write failed err=%d\n",
+ (u32)packet, ret);
+ break;
+ }
+
+#ifdef S5K5BBGX_USLEEP
+ if (unlikely(state->vt_mode))
+ if (!(num%200))
+ s5k5bbgx_usleep(3);
+#endif
+ }
+
+ if (unlikely(ret < 0)) {
+ cam_err("fail to write registers!!\n");
+ return -EIO;
+ }
+
+ return 0;
+}
+
+static int s5k5bbgx_get_exif(struct v4l2_subdev *sd)
+{
+ struct s5k5bbgx_state *state = to_state(sd);
+ u16 iso_gain_table[] = {10, 18, 23, 28};
+ u16 iso_table[] = {0, 50, 100, 200, 400};
+ u16 gain = 0, val = 0;
+ s32 index = 0;
+
+ state->exif.shutter_speed = 0;
+ state->exif.iso = 0;
+
+ /* Get shutter speed */
+ s5k5bbgx_read_reg(sd, REG_PAGE_SHUTTER, REG_ADDR_SHUTTER, &val);
+ state->exif.shutter_speed = 1000 * 1000 / (val * 1000 / 400);
+ cam_dbg("val = %d\n", val);
+
+ /* Get ISO */
+ val = 0;
+ s5k5bbgx_read_reg(sd, REG_PAGE_ISO, REG_ADDR_ISO, &val);
+ cam_dbg("val = %d\n", val);
+ gain = val * 10 / 256;
+ for (index = 0; index < NELEMS(iso_gain_table); index++) {
+ if (gain < iso_gain_table[index])
+ break;
+ }
+ state->exif.iso = iso_table[index];
+
+ cam_dbg("gain=%d, Shutter speed=%d, ISO=%d\n",
+ gain, state->exif.shutter_speed, state->exif.iso);
+ return 0;
+}
+
+static int s5k5bbgx_check_dataline(struct v4l2_subdev *sd, s32 val)
+{
+ int err = 0;
+
+ cam_info("DTP %s\n", val ? "ON" : "OFF");
+
+#ifdef CONFIG_LOAD_FILE
+ if (val)
+ err = s5k5bbgx_write_regs_from_sd(sd, "s5k5bbgx_pattern_on");
+ else
+ err = s5k5bbgx_write_regs_from_sd(sd, "s5k5bbgx_pattern_off");
+#else
+ if (val) {
+ cam_dbg("load s5k5bbgx_pattern_on\n");
+ err = s5k5bbgx_write_regs(sd, s5k5bbgx_pattern_on,
+ sizeof(s5k5bbgx_pattern_on) / \
+ sizeof(s5k5bbgx_pattern_on[0]));
+ } else {
+ cam_dbg("load s5k5bbgx_pattern_off\n");
+ err = s5k5bbgx_write_regs(sd, s5k5bbgx_pattern_off,
+ sizeof(s5k5bbgx_pattern_off) / \
+ sizeof(s5k5bbgx_pattern_off[0]));
+ }
+#endif
+ if (unlikely(err)) {
+ cam_err("fail to DTP setting\n");
+ return err;
+ }
+
+ return 0;
+}
+
+static int s5k5bbgx_debug_sensor_status(struct v4l2_subdev *sd)
+{
+ u16 val = 0;
+ int err = -EINVAL;
+
+ /* Read Mon_DBG_Counters_2 */
+ /*err = s5k5bbgx_read_reg(sd, 0x7000, 0x0402, &val);
+ CHECK_ERR(err);
+ cam_info("counter = %d\n", val); */
+
+ /* Read REG_TC_GP_EnableCaptureChanged. */
+ err = s5k5bbgx_read_reg(sd, 0x7000, 0x01F6, &val);
+ CHECK_ERR(err);
+
+ switch (val) {
+ case 0:
+ cam_info("In normal mode(0)\n");
+ break;
+ case 1:
+ cam_info("In swiching to capture mode(1).....\n");
+ break;
+ default:
+ cam_err("In Unknown mode(?)\n");
+ break;
+ }
+
+ return 0;
+}
+
+static int s5k5bbgx_check_sensor_status(struct v4l2_subdev *sd)
+{
+ /*struct i2c_client *client = v4l2_get_subdevdata(sd);*/
+ u16 val_1 = 0, val_2 = 0;
+ int err = -EINVAL;
+
+ err = s5k5bbgx_read_reg(sd, 0x7000, 0x00BC, &val_1);
+ CHECK_ERR(err);
+ err = s5k5bbgx_read_reg(sd, 0xD000, 0x1002, &val_2);
+ CHECK_ERR(err);
+
+ cam_dbg("read val1=0x%x, val2=0x%x\n", val_1, val_2);
+
+ if ((val_1 != 0xAAAA) || (val_2 != 0))
+ goto error_occur;
+
+ cam_dbg("Sensor error is not detected\n");
+ return 0;
+
+error_occur:
+ cam_err("ERR: Sensor error occurs\n\n");
+ return -EIO;
+}
+
+static inline int s5k5bbgx_check_esd(struct v4l2_subdev *sd)
+{
+ int err = -EINVAL;
+
+ err = s5k5bbgx_check_sensor_status(sd);
+ if (err < 0) {
+ cam_err("ERR: ESD Shock detected!\n");
+ return err;
+ }
+
+ return 0;
+}
+
+static int s5k5bbgx_set_preview_start(struct v4l2_subdev *sd)
+{
+ struct s5k5bbgx_state *state = to_state(sd);
+ int err = -EINVAL;
+
+ cam_info("reset preview\n");
+
+#ifdef CONFIG_LOAD_FILE
+ err = s5k5bbgx_write_regs_from_sd(sd, "s5k5bbgx_preview");
+#else
+ cam_dbg("load s5k5bbgx_preview\n");
+ err = s5k5bbgx_write_regs(sd, s5k5bbgx_preview,
+ sizeof(s5k5bbgx_preview) / sizeof(s5k5bbgx_preview[0]));
+#endif
+ if (state->check_dataline)
+ err = s5k5bbgx_check_dataline(sd, 1);
+ if (unlikely(err)) {
+ cam_err("fail to make preview\n");
+ return err;
+ }
+
+ return 0;
+}
+
+static int s5k5bbgx_set_preview_stop(struct v4l2_subdev *sd)
+{
+ int err = 0;
+ cam_info("do nothing.\n");
+
+ return err;
+}
+
+static int s5k5bbgx_set_capture_start(struct v4l2_subdev *sd)
+{
+ int err = -EINVAL;
+ u16 val = 1, retry = 0;
+
+ /* set initial regster value */
+#ifdef CONFIG_LOAD_FILE
+ err = s5k5bbgx_write_regs_from_sd(sd, "s5k5bbgx_capture");
+#else
+ cam_dbg("load s5k5bbgx_capture\n");
+ err = s5k5bbgx_write_regs(sd, s5k5bbgx_capture,
+ sizeof(s5k5bbgx_capture) / sizeof(s5k5bbgx_capture[0]));
+#endif
+ if (unlikely(err)) {
+ cam_err("failed to make capture\n");
+ return err;
+ }
+ s5k5bbgx_get_exif(sd);
+ cam_info("Capture ConfigSync\n");
+ do {
+ msleep(20);
+ err = s5k5bbgx_read_reg(sd, REG_PAGE_CAPTURE_STATUS,
+ REG_ADDR_CAPTURE_STATUS, &val);
+ CHECK_ERR(err);
+ cam_dbg("val = %d\n", val);
+ if (val == 0)
+ break;
+ retry++;
+ } while (retry <= S5K5BBGX_READ_STATUS_RETRIES);
+
+
+ return err;
+}
+
+static int s5k5bbgx_set_sensor_mode(struct v4l2_subdev *sd,
+ struct v4l2_control *ctrl)
+{
+ struct s5k5bbgx_state *state = to_state(sd);
+
+ if ((ctrl->value != SENSOR_CAMERA) &&
+ (ctrl->value != SENSOR_MOVIE)) {
+ cam_err("ERR: Not support.(%d)\n", ctrl->value);
+ return -EINVAL;
+ }
+
+ /* We does not support movie mode when in VT. */
+ if ((ctrl->value == SENSOR_MOVIE) && state->vt_mode) {
+ state->sensor_mode = SENSOR_CAMERA;
+ cam_warn("ERR: Not support movie\n");
+ } else
+ state->sensor_mode = ctrl->value;
+
+ return 0;
+}
+
+static int s5k5bbgx_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
+{
+ cam_dbg("E\n");
+ return 0;
+}
+
+static int s5k5bbgx_enum_framesizes(struct v4l2_subdev *sd, \
+ struct v4l2_frmsizeenum *fsize)
+{
+ struct s5k5bbgx_state *state = to_state(sd);
+
+ cam_dbg("E\n");
+
+ /*
+ * Return the actual output settings programmed to the camera
+ */
+ if (state->req_fmt.priv == V4L2_PIX_FMT_MODE_CAPTURE) {
+ fsize->discrete.width = state->capture_frmsizes.width;
+ fsize->discrete.height = state->capture_frmsizes.height;
+ } else {
+ fsize->discrete.width = state->preview_frmsizes.width;
+ fsize->discrete.height = state->preview_frmsizes.height;
+ }
+
+ cam_info("width - %d , height - %d\n",
+ fsize->discrete.width, fsize->discrete.height);
+
+ return 0;
+}
+
+#if (0) /* not used */
+static int s5k5bbgx_enum_fmt(struct v4l2_subdev *sd,
+ struct v4l2_fmtdesc *fmtdesc)
+{
+ int err = 0;
+
+ FUNC_ENTR();
+ return err;
+}
+
+static int s5k5bbgx_enum_frameintervals(struct v4l2_subdev *sd,
+ struct v4l2_frmivalenum *fival)
+{
+ int err = 0;
+
+ FUNC_ENTR();
+ return err;
+}
+#endif
+
+static int s5k5bbgx_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
+{
+ int err = 0;
+
+ cam_dbg("E\n");
+
+ return err;
+}
+
+static int s5k5bbgx_s_fmt(struct v4l2_subdev *sd,
+ struct v4l2_mbus_framefmt *ffmt)
+{
+ struct s5k5bbgx_state *state = to_state(sd);
+ u32 *width = NULL, *height = NULL;
+
+ cam_dbg("E\n");
+ /*
+ * Just copying the requested format as of now.
+ * We need to check here what are the formats the camera support, and
+ * set the most appropriate one according to the request from FIMC
+ */
+ #ifdef CONFIG_VIDEO_CONFERENCE_CALL
+ if (state->vt_mode == 3) {
+ state->req_fmt.width = fmt->fmt.pix.height;
+ state->req_fmt.height = fmt->fmt.pix.width;
+ }
+#endif
+
+ state->req_fmt.width = ffmt->width;
+ state->req_fmt.height = ffmt->height;
+ state->req_fmt.priv = ffmt->field;
+
+ switch (state->req_fmt.priv) {
+ case V4L2_PIX_FMT_MODE_PREVIEW:
+ cam_dbg("V4L2_PIX_FMT_MODE_PREVIEW\n");
+ width = &state->preview_frmsizes.width;
+ height = &state->preview_frmsizes.height;
+ break;
+
+ case V4L2_PIX_FMT_MODE_CAPTURE:
+ cam_dbg("V4L2_PIX_FMT_MODE_CAPTURE\n");
+ width = &state->capture_frmsizes.width;
+ height = &state->capture_frmsizes.height;
+ break;
+
+ default:
+ cam_err("ERR(EINVAL)\n");
+ return -EINVAL;
+ }
+
+ if ((*width != state->req_fmt.width) ||
+ (*height != state->req_fmt.height)) {
+ cam_err("ERR: Invalid size. width= %d, height= %d\n",
+ state->req_fmt.width, state->req_fmt.height);
+ }
+
+ return 0;
+}
+
+static int s5k5bbgx_set_frame_rate(struct v4l2_subdev *sd, u32 fps)
+{
+ int err = 0;
+
+ cam_info("frame rate %d\n\n", fps);
+
+#ifdef CONFIG_LOAD_FILE
+ switch (fps) {
+ case 7:
+ err = s5k5bbgx_write_regs_from_sd(sd, "s5k5bbgx_vt_7fps");
+ break;
+ case 10:
+ err = s5k5bbgx_write_regs_from_sd(sd, "s5k5bbgx_vt_10fps");
+
+ break;
+ case 12:
+ err = s5k5bbgx_write_regs_from_sd(sd, "s5k5bbgx_vt_12fps");
+
+ break;
+ case 15:
+ err = s5k5bbgx_write_regs_from_sd(sd, "s5k5bbgx_vt_15fps");
+ break;
+ case 30:
+ cam_err("frame rate is 30\n");
+ break;
+ default:
+ cam_err("ERR: Invalid framerate\n");
+ break;
+ }
+#else
+ switch (fps) {
+ case 7:
+ cam_dbg("load s5k5bbgx_vt_7fps\n");
+ err = s5k5bbgx_write_regs(sd, s5k5bbgx_vt_7fps,
+ sizeof(s5k5bbgx_vt_7fps) / \
+ sizeof(s5k5bbgx_vt_7fps[0]));
+ break;
+ case 10:
+ cam_dbg("load s5k5bbgx_vt_10fps\n");
+ err = s5k5bbgx_write_regs(sd, s5k5bbgx_vt_10fps,
+ sizeof(s5k5bbgx_vt_10fps) / \
+ sizeof(s5k5bbgx_vt_10fps[0]));
+
+ break;
+ case 12:
+ cam_dbg("load s5k5bbgx_vt_12fps\n");
+ err = s5k5bbgx_write_regs(sd, s5k5bbgx_vt_12fps,
+ sizeof(s5k5bbgx_vt_12fps) / \
+ sizeof(s5k5bbgx_vt_12fps[0]));
+
+ break;
+ case 15:
+ cam_dbg("load s5k5bbgx_vt_15fps\n");
+ err = s5k5bbgx_write_regs(sd, s5k5bbgx_vt_15fps,
+ sizeof(s5k5bbgx_vt_15fps) / \
+ sizeof(s5k5bbgx_vt_15fps[0]));
+ break;
+ case 30:
+ cam_warn("frame rate is 30\n");
+ break;
+ default:
+ cam_err("ERR: Invalid framerate\n");
+ break;
+ }
+#endif
+
+ if (unlikely(err < 0)) {
+ cam_err("i2c_write for set framerate\n");
+ return -EIO;
+ }
+
+ return err;
+}
+
+static int s5k5bbgx_g_parm(struct v4l2_subdev *sd,
+ struct v4l2_streamparm *parms)
+{
+ int err = 0;
+
+ cam_dbg("E\n");
+
+ return err;
+}
+
+static int s5k5bbgx_s_parm(struct v4l2_subdev *sd,
+ struct v4l2_streamparm *parms)
+{
+ int err = 0;
+ u32 fps = 0;
+ struct s5k5bbgx_state *state = to_state(sd);
+
+ if (!state->vt_mode)
+ return 0;
+
+ cam_dbg("E\n");
+
+ fps = parms->parm.capture.timeperframe.denominator /
+ parms->parm.capture.timeperframe.numerator;
+
+ if (fps != state->set_fps) {
+ if (fps < 0 && fps > 15) {
+ cam_err("invalid frame rate %d\n", fps);
+ fps = 15;
+ }
+ state->req_fps = fps;
+
+ if (state->initialized) {
+ err = s5k5bbgx_set_frame_rate(sd, state->req_fps);
+ if (err >= 0)
+ state->set_fps = state->req_fps;
+ }
+
+ }
+
+ return err;
+}
+
+#if (0) /* not used */
+static int s5k5bbgx_set_60hz_antibanding(struct v4l2_subdev *sd)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct s5k5bbgx_state *state = to_state(sd);
+ int err = -EINVAL;
+
+ FUNC_ENTR();
+
+ u32 s5k5bbgx_antibanding60hz[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ /* Anti-Flicker */
+ /* End user init script*/
+ 0x002A0400,
+ 0x0F12005F, /*REG_TC_DBG_AutoAlgEnBits Auto
+ Anti-Flicker is enabled bit[5] = 1.*/
+ 0x002A03DC,
+ 0x0F120002, /*02 REG_SF_USER_FlickerQuant set
+ flicker quantization(0: no AFC, 1: 50Hz, 2: 60 Hz)*/
+ 0x0F120001,
+ };
+
+ err = s5k5bbgx_write_regs(sd, s5k5bbgx_antibanding60hz,
+ sizeof(s5k5bbgx_antibanding60hz) / sizeof(s5k5bbgx_antibanding60hz[0]));
+ printk(KERN_INFO "%s: setting 60hz antibanding\n", __func__);
+ if (unlikely(err)) {
+ printk(KERN_INFO "%s: failed to set 60hz antibanding\n",
+ __func__);
+ return err;
+ }
+
+ return 0;
+}
+#endif
+
+static int s5k5bbgx_control_stream(struct v4l2_subdev *sd,
+ enum stream_cmd_t cmd)
+{
+ int err = 0;
+
+ switch (cmd) {
+ case STREAM_START:
+ cam_warn("WARN: do nothing\n");
+ break;
+
+ case STREAM_STOP:
+ cam_dbg("stream stop!!!\n");
+#if 0
+#ifdef CONFIG_LOAD_FILE
+ err = s5k5bbgx_write_regs_from_sd(sd, "s5k5bbgx_stream_stop");
+#else
+ err = s5k5bbgx_write_regs(sd, s5k5bbgx_stream_stop,
+ sizeof(s5k5bbgx_stream_stop) / \
+ sizeof(s5k5bbgx_stream_stop[0]));
+#endif
+#endif
+ break;
+ default:
+ cam_err("ERR: Invalid cmd\n");
+ break;
+ }
+
+ if (unlikely(err))
+ cam_err("failed to stream start(stop)\n");
+
+ return err;
+}
+
+static int s5k5bbgx_init(struct v4l2_subdev *sd, u32 val)
+{
+ /* struct i2c_client *client = v4l2_get_subdevdata(sd); */
+ struct s5k5bbgx_state *state = to_state(sd);
+ int err = -EINVAL;
+
+ cam_dbg("E\n");
+
+
+ /* set initial regster value */
+#ifdef CONFIG_LOAD_FILE
+ if (state->sensor_mode == SENSOR_CAMERA) {
+ if (!state->vt_mode) {
+ cam_dbg("load camera common setting\n");
+ err = s5k5bbgx_write_regs_from_sd(sd,
+ "s5k5bbgx_common");
+ } else {
+ if (state->vt_mode == 1) {
+ cam_info("load camera VT call setting\n");
+ err = s5k5bbgx_write_regs_from_sd(sd,
+ "s5k5bbgx_vt_common");
+ } else {
+ cam_info("load camera WIFI VT call setting\n");
+ err = s5k5bbgx_write_regs_from_sd(sd,
+ "s5k5bbgx_vt_wifi_common");
+ }
+ }
+ } else {
+ cam_info("load recording setting\n");
+ err = s5k5bbgx_write_regs_from_sd(sd,
+ "s5k5bbgx_recording_common");
+ }
+#else
+ if (state->sensor_mode == SENSOR_CAMERA) {
+ if (!state->vt_mode) {
+ cam_info("load camera common setting\n");
+ err = s5k5bbgx_write_regs(sd, s5k5bbgx_common,
+ sizeof(s5k5bbgx_common) / \
+ sizeof(s5k5bbgx_common[0]));
+ } else {
+#ifdef CONFIG_VIDEO_CONFERENCE_CALL
+ if (state->vt_mode == 1 || state->vt_mode == 3) {
+#else
+ if (state->vt_mode == 1) {
+#endif
+ cam_info("load camera VT call setting\n");
+ err = s5k5bbgx_write_regs(sd,
+ s5k5bbgx_vt_common,
+ sizeof(s5k5bbgx_vt_common) / \
+ sizeof(s5k5bbgx_vt_common[0]));
+ } else {
+ cam_info("load camera WIFI VT call setting\n");
+ err = s5k5bbgx_write_regs(sd,
+ s5k5bbgx_vt_wifi_common,
+ sizeof(s5k5bbgx_vt_wifi_common) / \
+ sizeof(s5k5bbgx_vt_wifi_common[0]));
+ }
+ }
+ } else {
+ cam_info("load recording setting\n");
+ err = s5k5bbgx_write_regs(sd, s5k5bbgx_recording_common,
+ sizeof(s5k5bbgx_recording_common) / \
+ sizeof(s5k5bbgx_recording_common[0]));
+ }
+#endif
+
+ if (unlikely(err)) {
+ cam_err("failed to init\n");
+ return err;
+ }
+
+ /* We stop stream-output from sensor when starting camera. */
+ err = s5k5bbgx_control_stream(sd, STREAM_STOP);
+ if (unlikely(err < 0))
+ return err;
+ msleep(150);
+
+ if (state->vt_mode && (state->req_fps != state->set_fps)) {
+ err = s5k5bbgx_set_frame_rate(sd, state->req_fps);
+ if (unlikely(err < 0))
+ return err;
+ else
+ state->set_fps = state->req_fps;
+ }
+
+ state->initialized = 1;
+
+ return 0;
+}
+
+#if 0
+static int s5k5bbgx_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
+{
+ FUNC_ENTR();
+ return 0;
+}
+
+static int s5k5bbgx_querymenu(struct v4l2_subdev *sd, struct v4l2_querymenu *qm)
+{
+ FUNC_ENTR();
+ return 0;
+}
+#endif
+
+static int s5k5bbgx_s_stream(struct v4l2_subdev *sd, int enable)
+{
+ struct s5k5bbgx_state *state = to_state(sd);
+ /* struct i2c_client *client = v4l2_get_subdevdata(sd); */
+ int err = 0;
+
+ cam_info("stream mode = %d\n", enable);
+
+ switch (enable) {
+ case STREAM_MODE_CAM_OFF:
+ if (state->sensor_mode == SENSOR_CAMERA) {
+ if (state->check_dataline)
+ err = s5k5bbgx_check_dataline(sd, 0);
+ else
+ err = s5k5bbgx_control_stream(sd, STREAM_STOP);
+ }
+ break;
+
+ case STREAM_MODE_CAM_ON:
+ /* The position of this code need to be adjusted later */
+ if (state->sensor_mode == SENSOR_CAMERA) {
+ if (state->req_fmt.priv == V4L2_PIX_FMT_MODE_CAPTURE)
+ err = s5k5bbgx_set_capture_start(sd);
+ else
+ err = s5k5bbgx_set_preview_start(sd);
+ }
+ break;
+
+ case STREAM_MODE_MOVIE_ON:
+ cam_dbg("do nothing(movie on)!!\n");
+ break;
+
+ case STREAM_MODE_MOVIE_OFF:
+ cam_dbg("do nothing(movie off)!!\n");
+ break;
+
+ default:
+ cam_err("ERR: Invalid stream mode\n");
+ break;
+ }
+
+ if (unlikely(err < 0)) {
+ cam_err("ERR: faild\n");
+ return err;
+ }
+
+ return 0;
+}
+
+static int s5k5bbgx_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+{
+ struct s5k5bbgx_state *state = to_state(sd);
+ int err = 0;
+
+ cam_dbg("ctrl->id : %d\n", ctrl->id - V4L2_CID_PRIVATE_BASE);
+
+ switch (ctrl->id) {
+ case V4L2_CID_CAMERA_EXIF_TV:
+ ctrl->value = state->exif.shutter_speed;
+ break;
+ case V4L2_CID_CAMERA_EXIF_ISO:
+ ctrl->value = state->exif.iso;
+ break;
+ default:
+ cam_err("no such control id %d\n",
+ ctrl->id - V4L2_CID_PRIVATE_BASE);
+ break;
+ }
+
+ return err;
+}
+
+static int s5k5bbgx_set_brightness(struct v4l2_subdev *sd,
+ struct v4l2_control *ctrl)
+{
+ struct s5k5bbgx_state *state = to_state(sd);
+ int err = -EINVAL;
+
+ cam_dbg("E\n");
+
+ if (state->check_dataline)
+ return 0;
+
+#ifdef CONFIG_LOAD_FILE
+ switch (ctrl->value) {
+ case EV_MINUS_4:
+ err = s5k5bbgx_write_regs_from_sd(sd, "s5k5bbgx_bright_m4");
+ break;
+ case EV_MINUS_3:
+ err = s5k5bbgx_write_regs_from_sd(sd, "s5k5bbgx_bright_m3");
+ break;
+ case EV_MINUS_2:
+ err = s5k5bbgx_write_regs_from_sd(sd, "s5k5bbgx_bright_m2");
+ break;
+ case EV_MINUS_1:
+ err = s5k5bbgx_write_regs_from_sd(sd, "s5k5bbgx_bright_m1");
+ break;
+ case EV_DEFAULT:
+ err = s5k5bbgx_write_regs_from_sd(sd,
+ "s5k5bbgx_bright_default");
+ break;
+ case EV_PLUS_1:
+ err = s5k5bbgx_write_regs_from_sd(sd, "s5k5bbgx_bright_p1");
+ break;
+ case EV_PLUS_2:
+ err = s5k5bbgx_write_regs_from_sd(sd, "s5k5bbgx_bright_p2");
+ break;
+ case EV_PLUS_3:
+ err = s5k5bbgx_write_regs_from_sd(sd, "s5k5bbgx_bright_p3");
+ break;
+ case EV_PLUS_4:
+ err = s5k5bbgx_write_regs_from_sd(sd, "s5k5bbgx_bright_p4");
+ break;
+ default:
+ cam_err("ERR: Invalid brightness(%d)\n", ctrl->value);
+ return err;
+ break;
+ }
+#else
+ switch (ctrl->value) {
+ case EV_MINUS_4:
+ cam_dbg("load s5k5bbgx_bright_m4\n");
+ err = s5k5bbgx_write_regs(sd, s5k5bbgx_bright_m4, \
+ sizeof(s5k5bbgx_bright_m4) / \
+ sizeof(s5k5bbgx_bright_m4[0]));
+ break;
+ case EV_MINUS_3:
+ cam_dbg("load s5k5bbgx_bright_m3\n");
+ err = s5k5bbgx_write_regs(sd, s5k5bbgx_bright_m3, \
+ sizeof(s5k5bbgx_bright_m3) / \
+ sizeof(s5k5bbgx_bright_m3[0]));
+
+ break;
+ case EV_MINUS_2:
+ cam_dbg("load s5k5bbgx_bright_m2\n");
+ err = s5k5bbgx_write_regs(sd, s5k5bbgx_bright_m2, \
+ sizeof(s5k5bbgx_bright_m2) / \
+ sizeof(s5k5bbgx_bright_m2[0]));
+ break;
+ case EV_MINUS_1:
+ cam_dbg("load s5k5bbgx_bright_m1\n");
+ err = s5k5bbgx_write_regs(sd, s5k5bbgx_bright_m1, \
+ sizeof(s5k5bbgx_bright_m1) / \
+ sizeof(s5k5bbgx_bright_m1[0]));
+ break;
+ case EV_DEFAULT:
+ cam_dbg("load s5k5bbgx_bright_default\n");
+ err = s5k5bbgx_write_regs(sd, s5k5bbgx_bright_default, \
+ sizeof(s5k5bbgx_bright_default) / \
+ sizeof(s5k5bbgx_bright_default[0]));
+ break;
+ case EV_PLUS_1:
+ cam_dbg("load s5k5bbgx_bright_p1\n");
+ err = s5k5bbgx_write_regs(sd, s5k5bbgx_bright_p1, \
+ sizeof(s5k5bbgx_bright_p1) / \
+ sizeof(s5k5bbgx_bright_p1[0]));
+ break;
+ case EV_PLUS_2:
+ cam_dbg("load s5k5bbgx_bright_p2\n");
+ err = s5k5bbgx_write_regs(sd, s5k5bbgx_bright_p2, \
+ sizeof(s5k5bbgx_bright_p2) / \
+ sizeof(s5k5bbgx_bright_p2[0]));
+ break;
+ case EV_PLUS_3:
+ cam_dbg("load s5k5bbgx_bright_p3\n");
+ err = s5k5bbgx_write_regs(sd, s5k5bbgx_bright_p3, \
+ sizeof(s5k5bbgx_bright_p3) / \
+ sizeof(s5k5bbgx_bright_p3[0]));
+ break;
+ case EV_PLUS_4:
+ cam_dbg("load s5k5bbgx_bright_p4\n");
+ err = s5k5bbgx_write_regs(sd, s5k5bbgx_bright_p4, \
+ sizeof(s5k5bbgx_bright_p4) / \
+ sizeof(s5k5bbgx_bright_p4[0]));
+ break;
+ default:
+ cam_err("ERR: invalid brightness(%d)\n", ctrl->value);
+ return err;
+ break;
+ }
+#endif
+
+ if (unlikely(err < 0)) {
+ cam_err("ERR: i2c_write for set brightness\n");
+ return -EIO;
+ }
+
+ return 0;
+}
+
+static int s5k5bbgx_set_blur(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+{
+ struct s5k5bbgx_state *state = to_state(sd);
+ int err = -EINVAL;
+
+ cam_dbg("E\n");
+
+ if (state->check_dataline)
+ return 0;
+
+#ifdef CONFIG_LOAD_FILE
+ switch (ctrl->value) {
+ case BLUR_LEVEL_0:
+ err = s5k5bbgx_write_regs_from_sd(sd,
+ "s5k5bbgx_vt_pretty_default");
+ break;
+ case BLUR_LEVEL_1:
+ err = s5k5bbgx_write_regs_from_sd(sd, "s5k5bbgx_vt_pretty_1");
+ break;
+ case BLUR_LEVEL_2:
+ err = s5k5bbgx_write_regs_from_sd(sd, "s5k5bbgx_vt_pretty_2");
+ break;
+ case BLUR_LEVEL_3:
+ case BLUR_LEVEL_MAX:
+ err = s5k5bbgx_write_regs_from_sd(sd, "s5k5bbgx_vt_pretty_3");
+ break;
+ default:
+ cam_err("ERR: Invalid blur(%d)\n", ctrl->value);
+ return err;
+ break;
+ }
+#else
+ switch (ctrl->value) {
+ case BLUR_LEVEL_0:
+ cam_dbg("load s5k5bbgx_vt_pretty_default\n");
+ err = s5k5bbgx_write_regs(sd, s5k5bbgx_vt_pretty_default, \
+ sizeof(s5k5bbgx_vt_pretty_default) / \
+ sizeof(s5k5bbgx_vt_pretty_default[0]));
+ break;
+ case BLUR_LEVEL_1:
+ cam_dbg("load s5k5bbgx_vt_pretty_1\n");
+ err = s5k5bbgx_write_regs(sd, s5k5bbgx_vt_pretty_1, \
+ sizeof(s5k5bbgx_vt_pretty_1) / \
+ sizeof(s5k5bbgx_vt_pretty_1[0]));
+ break;
+ case BLUR_LEVEL_2:
+ cam_dbg("load s5k5bbgx_vt_pretty_2\n");
+ err = s5k5bbgx_write_regs(sd, s5k5bbgx_vt_pretty_2, \
+ sizeof(s5k5bbgx_vt_pretty_2) / \
+ sizeof(s5k5bbgx_vt_pretty_2[0]));
+ break;
+ case BLUR_LEVEL_3:
+ case BLUR_LEVEL_MAX:
+ cam_dbg("load s5k5bbgx_vt_pretty_3\n");
+ err = s5k5bbgx_write_regs(sd, s5k5bbgx_vt_pretty_3, \
+ sizeof(s5k5bbgx_vt_pretty_3) / \
+ sizeof(s5k5bbgx_vt_pretty_3[0]));
+ break;
+ default:
+ cam_err("ERR: Invalid blur(%d)\n", ctrl->value);
+ return err;
+ break;
+ }
+#endif
+
+ if (unlikely(err < 0)) {
+ cam_err("ERR: i2c_write for set blur\n");
+ return -EIO;
+ }
+
+ return 0;
+}
+
+static int s5k5bbgx_check_dataline_stop(struct v4l2_subdev *sd)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct s5k5bbgx_state *state = to_state(sd);
+ int err = -EINVAL;
+
+ cam_warn("Warning: do nothing!!\n");
+ return err;
+
+
+ /*s5k5bbgx_write(client, 0xFCFCD000); */
+ /*s5k5bbgx_write(client, 0x0028D000); */
+ /*s5k5bbgx_write(client, 0x002A3100); */
+ /*s5k5bbgx_write(client, 0x0F120000); */
+
+ /*err = s5k5bbgx_write_regs(sd, s5k5bbgx_pattern_off,
+ * sizeof(s5k5bbgx_pattern_off) / sizeof(s5k5bbgx_pattern_off[0])); */
+ printk(KERN_INFO "%s: sensor reset\n", __func__);
+#if defined(CONFIG_TARGET_LOCALE_KOR) || \
+ defined(CONFIG_TARGET_LOCALE_EUR) || \
+ defined(CONFIG_TARGET_LOCALE_HKTW) || \
+ defined(CONFIG_TARGET_LOCALE_HKTW_FET) || \
+ defined(CONFIG_TARGET_LOCALE_USAGSM) || \
+ defined(CONFIG_TARGET_LOCALE_CANBMC_TEMP)
+ /* dont't know where this code came from - comment out for
+ * compile error */
+ /* s5k5bbgx_power_reset();*/
+ #endif
+ cam_dbg("load camera init setting\n");
+ err = s5k5bbgx_write_regs(sd, s5k5bbgx_common,
+ sizeof(s5k5bbgx_common) / sizeof(s5k5bbgx_common[0]));
+
+ state->check_dataline = 0;
+ /* mdelay(100); */
+ return err;
+}
+
+static int s5k5bbgx_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+{
+ /* struct i2c_client *client = v4l2_get_subdevdata(sd); */
+ struct s5k5bbgx_state *state = to_state(sd);
+ int err = 0;
+
+ cam_info("ctrl->id : %d, value=%d\n", ctrl->id - V4L2_CID_PRIVATE_BASE,
+ ctrl->value);
+
+ if ((ctrl->id != V4L2_CID_CAMERA_CHECK_DATALINE)
+ && (ctrl->id != V4L2_CID_CAMERA_SENSOR_MODE)
+ && ((ctrl->id != V4L2_CID_CAMERA_VT_MODE))
+ && (!state->initialized)) {
+ cam_warn("camera isn't initialized\n");
+ return 0;
+ }
+
+ switch (ctrl->id) {
+ case V4L2_CID_CAM_PREVIEW_ONOFF:
+ if (ctrl->value)
+ err = s5k5bbgx_set_preview_start(sd);
+ else
+ err = s5k5bbgx_set_preview_stop(sd);
+ cam_dbg("V4L2_CID_CAM_PREVIEW_ONOFF [%d]\n", ctrl->value);
+ break;
+
+ case V4L2_CID_CAM_CAPTURE:
+ err = s5k5bbgx_set_capture_start(sd);
+ cam_dbg("V4L2_CID_CAM_CAPTURE\n");
+ break;
+
+ case V4L2_CID_CAMERA_BRIGHTNESS:
+ err = s5k5bbgx_set_brightness(sd, ctrl);
+ cam_dbg("V4L2_CID_CAMERA_BRIGHTNESS [%d]\n", ctrl->value);
+ break;
+
+ case V4L2_CID_CAMERA_VGA_BLUR:
+ /*err = s5k5bbgx_set_blur(sd, ctrl);*/
+ cam_dbg("V4L2_CID_CAMERA_VGA_BLUR [%d]\n", ctrl->value);
+ break;
+
+ case V4L2_CID_CAMERA_VT_MODE:
+ state->vt_mode = ctrl->value;
+ break;
+
+ case V4L2_CID_CAMERA_CHECK_DATALINE:
+ state->check_dataline = ctrl->value;
+ cam_dbg("check_dataline = %d\n", state->check_dataline);
+ err = 0;
+ break;
+
+ case V4L2_CID_CAMERA_SENSOR_MODE:
+ err = s5k5bbgx_set_sensor_mode(sd, ctrl);
+ cam_dbg("sensor_mode = %d\n", ctrl->value);
+ break;
+
+ case V4L2_CID_CAMERA_CHECK_DATALINE_STOP:
+ err = s5k5bbgx_check_dataline_stop(sd);
+ break;
+
+ case V4L2_CID_CAMERA_CHECK_ESD:
+ err = s5k5bbgx_check_esd(sd);
+ break;
+
+ case V4L2_CID_CAMERA_FRAME_RATE:
+ cam_dbg("do nothing\n");
+ break;
+
+ case V4L2_CID_CAMERA_CHECK_SENSOR_STATUS:
+ s5k5bbgx_debug_sensor_status(sd);
+ err = s5k5bbgx_check_sensor_status(sd);
+ break;
+
+ default:
+ cam_err("ERR(ENOIOCTLCMD)\n");
+ /* no errors return.*/
+ break;
+ }
+
+ cam_dbg("X\n");
+ return err;
+}
+
+static const struct v4l2_subdev_core_ops s5k5bbgx_core_ops = {
+ .init = s5k5bbgx_init, /* initializing API */
+#if 0
+ .queryctrl = s5k5bbgx_queryctrl,
+ .querymenu = s5k5bbgx_querymenu,
+#endif
+ .g_ctrl = s5k5bbgx_g_ctrl,
+ .s_ctrl = s5k5bbgx_s_ctrl,
+};
+
+static const struct v4l2_subdev_video_ops s5k5bbgx_video_ops = {
+ /*.s_crystal_freq = s5k5bbgx_s_crystal_freq,*/
+ .s_mbus_fmt = s5k5bbgx_s_fmt,
+ .s_stream = s5k5bbgx_s_stream,
+ .enum_framesizes = s5k5bbgx_enum_framesizes,
+ /*.enum_frameintervals = s5k5bbgx_enum_frameintervals,*/
+ /*.enum_fmt = s5k5bbgx_enum_fmt,*/
+ .g_parm = s5k5bbgx_g_parm,
+ .s_parm = s5k5bbgx_s_parm,
+};
+
+static const struct v4l2_subdev_ops s5k5bbgx_ops = {
+ .core = &s5k5bbgx_core_ops,
+ .video = &s5k5bbgx_video_ops,
+};
+
+ssize_t s5k5bbgx_camera_type_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ char *cam_type;
+ cam_info("%s\n", __func__);
+
+ cam_type = "SLSI_S5K5BBGX";
+
+ return sprintf(buf, "%s\n", cam_type);
+}
+
+static DEVICE_ATTR(front_camtype, S_IRUGO, s5k5bbgx_camera_type_show, NULL);
+
+/*
+ * s5k5bbgx_probe
+ * Fetching platform data is being done with s_config subdev call.
+ * In probe routine, we just register subdev device
+ */
+static int s5k5bbgx_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct s5k5bbgx_state *state = NULL;
+ struct v4l2_subdev *sd = NULL;
+ struct s5k5bbgx_platform_data *pdata = NULL;
+ cam_dbg("E\n");
+
+ state = kzalloc(sizeof(struct s5k5bbgx_state), GFP_KERNEL);
+ if (state == NULL)
+ return -ENOMEM;
+
+ sd = &state->sd;
+ strcpy(sd->name, S5K5BBGX_DRIVER_NAME);
+ state->initialized = 0;
+ state->req_fps = state->set_fps = 8;
+ state->sensor_mode = SENSOR_CAMERA;
+
+ pdata = client->dev.platform_data;
+
+ if (!pdata) {
+ cam_err("no platform data\n");
+ return -ENODEV;
+ }
+ /* Registering subdev */
+ v4l2_i2c_subdev_init(sd, client, &s5k5bbgx_ops);
+ if (state->s5k5bbgx_dev == NULL) {
+ state->s5k5bbgx_dev =
+ device_create(camera_class, NULL, 0, NULL,
+ "front");
+ if (IS_ERR(state->s5k5bbgx_dev)) {
+ cam_err("failed to create device s5k5bbgx_dev!\n");
+ } else {
+ dev_set_drvdata(state->s5k5bbgx_dev, state);
+ if (device_create_file
+ (state->s5k5bbgx_dev,
+ &dev_attr_front_camtype) < 0) {
+ cam_err("failed to create device file, %s\n",
+ dev_attr_front_camtype.attr.name);
+ }
+ }
+ }
+
+ /*
+ * Assign default format and resolution
+ * Use configured default information in platform data
+ * or without them, use default information in driver
+ */
+ if (!(pdata->default_width && pdata->default_height)) {
+ state->preview_frmsizes.width = DEFAULT_PREVIEW_WIDTH;
+ state->preview_frmsizes.height = DEFAULT_PREVIEW_HEIGHT;
+ } else {
+ state->preview_frmsizes.width = pdata->default_width;
+ state->preview_frmsizes.height = pdata->default_height;
+ }
+ state->capture_frmsizes.width = DEFAULT_CAPTURE_WIDTH;
+ state->capture_frmsizes.height = DEFAULT_CAPTURE_HEIGHT;
+
+ cam_dbg("preview_width: %d , preview_height: %d, "
+ "capture_width: %d, capture_height: %d",
+ state->preview_frmsizes.width, state->preview_frmsizes.height,
+ state->capture_frmsizes.width, state->capture_frmsizes.height);
+
+ state->req_fmt.width = state->preview_frmsizes.width;
+ state->req_fmt.height = state->preview_frmsizes.height;
+
+ if (!pdata->pixelformat)
+ state->req_fmt.pixelformat = DEFAULT_FMT;
+ else
+ state->req_fmt.pixelformat = pdata->pixelformat;
+ cam_dbg("probed!!\n");
+
+ return 0;
+}
+
+static int s5k5bbgx_remove(struct i2c_client *client)
+{
+ struct v4l2_subdev *sd = i2c_get_clientdata(client);
+ struct s5k5bbgx_state *state = to_state(sd);
+
+ cam_dbg("E\n");
+
+ state->initialized = 0;
+
+ device_remove_file(state->s5k5bbgx_dev, &dev_attr_front_camtype);
+ device_destroy(camera_class, 0);
+ state->s5k5bbgx_dev = NULL;
+
+ v4l2_device_unregister_subdev(sd);
+ kfree(to_state(sd));
+
+#ifdef CONFIG_LOAD_FILE
+/* if (testBuf) {*/
+ large_file ? vfree(testBuf) : kfree(testBuf);
+ large_file = 0;
+ testBuf = NULL;
+/* }*/
+#endif
+
+ return 0;
+}
+
+static const struct i2c_device_id s5k5bbgx_id[] = {
+ { S5K5BBGX_DRIVER_NAME, 0 },
+ { },
+};
+MODULE_DEVICE_TABLE(i2c, s5k5bbgx_id);
+
+static struct i2c_driver s5k5bbgx_i2c_driver = {
+ .driver = {
+ .name = S5K5BBGX_DRIVER_NAME,
+ },
+ .probe = s5k5bbgx_probe,
+ .remove = s5k5bbgx_remove,
+ .id_table = s5k5bbgx_id,
+};
+static int __init s5k5bbgx_mod_init(void)
+{
+ cam_dbg("E\n");
+ return i2c_add_driver(&s5k5bbgx_i2c_driver);
+}
+
+static void __exit s5k5bbgx_mod_exit(void)
+{
+ cam_dbg("E\n");
+ i2c_del_driver(&s5k5bbgx_i2c_driver);
+}
+module_init(s5k5bbgx_mod_init);
+module_exit(s5k5bbgx_mod_exit);
+MODULE_DESCRIPTION("S5K5BBGX ISP driver");
+MODULE_AUTHOR("DongSeong Lim<dongseong.lim@samsung.com>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/s5k5bbgx.h b/drivers/media/video/s5k5bbgx.h
new file mode 100644
index 0000000..3549e93
--- /dev/null
+++ b/drivers/media/video/s5k5bbgx.h
@@ -0,0 +1,117 @@
+/*
+ * Driver for S5K5BBGX 2M ISP from Samsung
+ *
+ * Copyright (C) 2011,
+ * DongSeong Lim<dongseong.lim@samsung.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.
+ */
+
+#ifndef __S5K5BBGX_H
+#define __S5K5BBGX_H
+
+#include <linux/types.h>
+
+#define S5K5BBGX_DRIVER_NAME "S5K5BBGX"
+
+extern struct class *camera_class;
+extern int s5k5bbgx_power_reset(void);
+
+enum stream_cmd_t {
+ STREAM_STOP,
+ STREAM_START,
+};
+
+struct s5k5bbgx_framesize {
+ u32 width;
+ u32 height;
+};
+
+struct s5k5bbgx_exif {
+ u32 shutter_speed;
+ u16 iso;
+};
+
+
+/*
+ * Driver information
+ */
+struct s5k5bbgx_state {
+ struct v4l2_subdev sd;
+struct device *s5k5bbgx_dev;
+ /*
+ * req_fmt is the requested format from the application.
+ * set_fmt is the output format of the camera. Finally FIMC
+ * converts the camera output(set_fmt) to the requested format
+ * with hardware scaler.
+ */
+ struct v4l2_pix_format req_fmt;
+ struct s5k5bbgx_framesize preview_frmsizes;
+ struct s5k5bbgx_framesize capture_frmsizes;
+ struct s5k5bbgx_exif exif;
+
+ enum v4l2_sensor_mode sensor_mode;
+ s32 vt_mode;
+ s32 check_dataline;
+ u32 req_fps;
+ u32 set_fps;
+ u32 initialized;
+};
+
+static inline struct s5k5bbgx_state *to_state(struct v4l2_subdev *sd)
+{
+ return container_of(sd, struct s5k5bbgx_state, sd);
+}
+
+/*#define CONFIG_CAM_DEBUG*/
+#define cam_warn(fmt, ...) \
+ do { \
+ printk(KERN_WARNING "%s: " fmt, __func__, ##__VA_ARGS__); \
+ } while (0)
+
+#define cam_err(fmt, ...) \
+ do { \
+ printk(KERN_ERR "%s: " fmt, __func__, ##__VA_ARGS__); \
+ } while (0)
+
+#define cam_info(fmt, ...) \
+ do { \
+ printk(KERN_INFO "%s: " fmt, __func__, ##__VA_ARGS__); \
+ } while (0)
+
+#ifdef CONFIG_CAM_DEBUG
+#define cam_dbg(fmt, ...) \
+ do { \
+ printk(KERN_DEBUG "%s: " fmt, __func__, ##__VA_ARGS__); \
+ } while (0)
+#else
+#define cam_dbg(fmt, ...)
+#endif /* CONFIG_CAM_DEBUG */
+
+
+/************ driver feature ************/
+#define S5K5BBGX_USLEEP
+/* #define CONFIG_LOAD_FILE */
+
+
+/*********** Sensor specific ************/
+/* #define S5K5BBGX_100MS_DELAY 0xAA55AA5F */
+/* #define S5K5BBGX_10MS_DELAY 0xAA55AA5E */
+#define S5K5BBGX_DELAY 0xFFFF0000
+#define S5K5BBGX_DEF_APEX_DEN 100
+
+/* Register address */
+#define REG_PAGE_SHUTTER 0x7000
+#define REG_ADDR_SHUTTER 0x238C
+#define REG_PAGE_ISO 0x7000
+#define REG_ADDR_ISO 0x2390
+#define REG_PAGE_CAPTURE_STATUS 0x7000
+#define REG_ADDR_CAPTURE_STATUS 0x0142
+#define S5K5BBGX_READ_STATUS_RETRIES 20
+
+#include "s5k5bbgx_setfile.h"
+
+#endif /* __S5K5BBGX_H */
diff --git a/drivers/media/video/s5k5bbgx_setfile.h b/drivers/media/video/s5k5bbgx_setfile.h
new file mode 100644
index 0000000..1efe6af
--- /dev/null
+++ b/drivers/media/video/s5k5bbgx_setfile.h
@@ -0,0 +1,12066 @@
+/*
+ * Driver for S5K5BBGX 2M ISP from Samsung
+ *
+ * Copyright (C) 2011,
+ * DongSeong Lim<dongseong.lim@samsung.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.
+ */
+#ifndef __S5K5BBGX_SETFILE_H
+#define __S5K5BBGX_SETFILE_H
+
+#include <linux/types.h>
+
+
+static const u32 s5k5bbgx_common[] = {
+
+ 0xFCFCD000,
+ 0x00100001, /*S/W Reset*/
+ 0x10300000, /*contint_host_int*/
+ 0x00140001, /*sw_load_complete - Release CORE (Arm) from reset
+ state*/
+ 0xFFFF000A,
+
+ /*0x0028D000,*/ /*Driving Current*/
+ /*0x002A1082,*/
+ /*0x0F1203ff,*/ /*cregs_d0_d4_cd10 D4[9:8], D3[7:6], D2[5:4], D1[3:2],
+ D0[1:0]*/
+ /*0x002A1084,*/
+ /*0x0F1203ff,*/ /*cregs_d5_d9_cd10 D9[9:8], D8[7:6], D7[5:4], D6[3:2],
+ D5[1:0]*/
+ /*0x002A1088,*/
+ /*0x0F120fcf,*/ /*cregs_clks_output_cd10 SDA[11:10], SCL[9:8],
+ PCLK[7:6], VSYNC[3:2], HSYNC[1:0]*/
+
+ 0x0028D000,
+ 0x002AF404,
+ 0x0F120038, /*aig_adc_sat[7:0] : 850mV*/
+ 0x0F120001, /*ms[2:0]; 2h@Normal, 2h@PLA, 1h@CNT.AVG*/
+ 0x0F12000C, /*aig_sig_mx[5:0]*/
+ 0x0F120006, /*aig_rst_mx[5:0]*/
+ 0x0F120008, /*rmp_option[7:0]; [3]SL_Low_PWR_SAVE On*/
+ 0x002AF418,
+ 0x0F120003, /*aig_dbr_clk_sel[1:0]*/
+ 0x002AF41C,
+ 0x0F120140, /*aig_bist_sig_width_e[10:0]*/
+ 0x0F120140, /*aig_bist_sig_width_o[10:0]*/
+ 0x0F120066, /*aig_bist_sig_width_o[10:0]*/
+ 0x0F120005, /*aig_pix_bias[3:0]*/
+ 0x002AF426,
+ 0x0F1200D4, /*aig_clp_lvl[7:0]*/
+ 0x002AF42A,
+ 0x0F120001, /*aig_ref_option[0] SL_Low_PWR_SAVE On*/
+ 0x002AF430,
+ 0x0F120001, /*aig_pd_cp_rosc[0]*/
+ 0x0F120001, /*aig_pd_ncp_rosc[0]*/
+ 0x002AF43A,
+ 0x0F120000, /*aig_pd_fblv[0]*/
+ 0x002AF440,
+ 0x0F120044, /*aig_rosc_tune_ncp[7:4] aig_rosc_tune_cp[3:0]*/
+ 0x002AF44A,
+ 0x0F120000, /*aig_fb_lv[1:0]*/
+ 0x002AF45C,
+ 0x0F120000, /*aig_dshut_en[0]*/
+ 0x0F120000, /*aig_srx_en[0]*/
+ 0x002AF462,
+ 0x0F120001, /*aig_pdb_atop[0]*/
+ 0x002AF46E,
+ 0x0F121F02, /*aig_cds_test[15:0]*/
+ 0x002AF474,
+ 0x0F12000E, /*aig_stx_gap[4:0]*/
+ 0x002AE42E,
+ 0x0F120004, /*adlc_qec[2:0]*/
+ 0x00287000,
+ 0x002A13E0,
+ 0x0F120000, /*senHal_bSRX SRX OFF*/
+ 0x002A13C8,
+ 0x0F120001, /*senHal_bSenAAC AAC Enable*/
+ 0x002A12D8,
+ 0x0F120464, /*senHal_ContPtrs_senModesDataArr[78]*/
+ 0x0F120468, /*senHal_ContPtrs_senModesDataArr[79]*/
+ 0x002A12F6,
+ 0x0F120000, /*senHal_ContPtrs_senModesDataArr[93]*/
+ 0x002A13CC,
+ 0x0F121FC0, /*senHal_bSen11ADLC [12:0] : Write tuning value to E404
+ register*/
+ 0x002A13EC,
+ 0x0F120001, /*senHal_DarklevelTuneMode*/
+ 0x002A184C,
+ 0x0F121EE1,
+ 0x00287000,
+ 0x002A040E,
+ 0x0F120003, /*skl_usConfigStbySettings*/
+ 0xFFFF000A,
+ 0x002A1218,
+ 0x0F120002, /*senHal_SenBinFactor*/
+ 0x0F120002, /*senHal_SamplingType*/
+ 0x002A0C9A,
+ 0x0F120001, /*setot_bUseDigitalHbin*/
+ 0x002A1438,
+ 0x0F12F468, /*senHal_TuneStr_AngTuneData1[0]*/
+ 0x0F120000, /*senHal_TuneStr_AngTuneData1[1] not use binninb block
+ 0x0000, use binnin blcok 0x0000*/
+ 0x0F120008, /*senHal_TuneStr_AngTuneData1[2] not use binninb block
+ 0x000A, use binnin blcok 0x0008*/
+ 0x0F120006, /*senHal_TuneStr_AngTuneData1[3] not use binninb block
+ 0x0005, use binnin blcok 0x0006*/
+ 0x0F120000, /*senHal_TuneStr_AngTuneData1[4]*/
+ 0xFFFF000A,
+ 0x002A0416,
+ 0x0F12F400, /*skl_usStbyBackupReg[0][0]*/
+ 0x0F120074, /*skl_usStbyBackupReg[0][1]*/
+ 0x0F12E42E, /*skl_usStbyBackupReg[1][0]*/
+ 0x0F120030, /*skl_usStbyBackupReg[1][1]*/
+ 0x002A378C,
+ 0x0F120000, /* On/off regiSter bUSeOTP*/
+ 0x002A0AD8,
+ 0x0F120F00,
+ 0x0F120000,
+ 0x0F12000F,
+ 0x0F120F0F,
+ 0x0F120F00,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F12000F,
+ 0x0F120F0F,
+ 0x0F120F00,
+ 0x0F120F00,
+ 0x0F12000F,
+ 0x0F120F0F,
+ 0x0F120000,
+ 0x0F120F0F,
+ 0x0F120000,
+ 0x0F12000F,
+ 0x0F120F00,
+ 0x0F120F00,
+ 0x0F120000,
+ 0x0F120F0F,
+ 0x0F120F0F,
+ 0x0F120F00,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F12000F,
+ 0x0F120F0F,
+ 0x0F120000,
+ 0x0F120F00,
+ 0x0F120000,
+ 0x0F120F00,
+ 0x0F120000,
+ 0x0F120F0F,
+ 0x0F12000F,
+ 0x0F12000F,
+ 0x0F120F00,
+ 0x0F120F00,
+ 0x0F120000,
+ 0x0F120F00,
+ 0x0F120F0F,
+ 0x0F120F00,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F12000F,
+ 0x0F120F00,
+ 0x0F120F00,
+ 0x0F120F00,
+ 0x0F12000F,
+ 0x0F120F00,
+ 0x0F120000,
+ 0x0F120F0F,
+ 0x0F12000F,
+ 0x0F12000F,
+ 0x0F120F00,
+ 0x0F120F00,
+ 0x0F120000,
+ 0x0F120F0F,
+ 0x0F120F0F,
+ 0x0F120F00,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F12000F,
+ 0x0F120F0F,
+ 0x0F120F00,
+ 0x0F120F00,
+ 0x0F120000,
+ 0x0F120F0F,
+ 0x0F120000,
+ 0x0F120F0F,
+ 0x0F12000F,
+ 0x0F12000F,
+ 0x0F120F00,
+ 0x0F128608,
+ 0x0F12E960,
+ 0x0F120243,
+ 0x0F12128B,
+ 0x0F12F073,
+ 0x0F120270,
+ 0x0F12DF47,
+ 0x0F12F226,
+ 0x0F121A31,
+ 0x0F12DFDA,
+ 0x0F121200,
+ 0x0F1205A9,
+ 0x0F120F16,
+ 0x0F120F5E,
+ 0x0F12DF10,
+ 0x0F1225BF,
+ 0x0F12FCF0,
+ 0x0F12DE1B,
+ 0x0F12025B,
+ 0x0F12FA8B,
+ 0x0F12163B,
+ 0x0F12DF44,
+ 0x0F12FB2D,
+ 0x0F1230E6,
+ 0x0F12FE07,
+ 0x0F12F47C,
+ 0x0F1209F2,
+ 0x0F120AED,
+ 0x0F12FA09,
+ 0x0F12E70E,
+ 0x0F120158,
+ 0x0F121110,
+ 0x0F12E28C,
+ 0x0F120DFB,
+ 0x0F12074B,
+ 0x0F12FBE5,
+ 0x0F12961C,
+ 0x0F12E21A,
+ 0x0F120ADF,
+ 0x0F120A67,
+ 0x0F12F8A6,
+ 0x0F12FDC3,
+ 0x0F12D590,
+ 0x0F12FA69,
+ 0x0F1208D5,
+ 0x0F12F635,
+ 0x0F12057E,
+ 0x0F12043B,
+ 0x0F12155C,
+ 0x0F1200C6,
+ 0x0F12F042,
+ 0x0F12176A,
+ 0x0F12F818,
+ 0x0F12F1F3,
+ 0x0F12026F,
+ 0x0F1208F6,
+ 0x0F120CCF,
+ 0x0F12E42D,
+ 0x0F120A92,
+ 0x0F1210EC,
+ 0x0F12005F,
+ 0x0F12F02C,
+ 0x0F120672,
+ 0x0F1209BF,
+ 0x0F12F4B5,
+ 0x0F12FC22,
+ 0x0F12FD50,
+ 0x0F120C26,
+ 0x0F12EED3,
+ 0x0F1207C3,
+ 0x0F12080F,
+ 0x0F12F6CF,
+ 0x0F127A3B,
+ 0x0F12E9DC,
+ 0x0F12088E,
+ 0x0F1201C8,
+ 0x0F12043C,
+ 0x0F12F7E2,
+ 0x0F12E391,
+ 0x0F12F3C4,
+ 0x0F121422,
+ 0x0F12E845,
+ 0x0F120D16,
+ 0x0F1206CA,
+ 0x0F120DEB,
+ 0x0F121324,
+ 0x0F12E814,
+ 0x0F1216B7,
+ 0x0F1202AC,
+ 0x0F12DE4D,
+ 0x0F1201EA,
+ 0x0F12F0C2,
+ 0x0F120E06,
+ 0x0F12EC6D,
+ 0x0F12FDF0,
+ 0x0F122B46,
+ 0x0F120710,
+ 0x0F12F84C,
+ 0x0F120E52,
+ 0x0F120675,
+ 0x0F12F0D7,
+ 0x0F12ED40,
+ 0x0F12F3AD,
+ 0x0F12179A,
+ 0x0F12DE9B,
+ 0x0F1210BA,
+ 0x0F120825,
+ 0x0F12FE0A,
+ 0x0F1288E9,
+ 0x0F12E9E0,
+ 0x0F12043D,
+ 0x0F120A17,
+ 0x0F12FC21,
+ 0x0F12FB58,
+ 0x0F12DCE0,
+ 0x0F12F24C,
+ 0x0F121A19,
+ 0x0F12E011,
+ 0x0F1211A3,
+ 0x0F120649,
+ 0x0F120D04,
+ 0x0F120E15,
+ 0x0F12E112,
+ 0x0F1227BD,
+ 0x0F12F7AA,
+ 0x0F12E06A,
+ 0x0F120A16,
+ 0x0F12FD23,
+ 0x0F121226,
+ 0x0F12DA34,
+ 0x0F1207A4,
+ 0x0F122AD3,
+ 0x0F12FE27,
+ 0x0F12EE64,
+ 0x0F120CAD,
+ 0x0F1211C5,
+ 0x0F12EC55,
+ 0x0F12ED98,
+ 0x0F12F88A,
+ 0x0F121842,
+ 0x0F12E1D5,
+ 0x0F1208FD,
+ 0x0F120FB6,
+ 0x0F12F801,
+ 0x002A0378,
+ 0x0F120001, /*REG_TC_DBG_RelnitCmd*/
+ 0x002A05E8,
+ 0x0F1200E4, /*TVAR_ash_AwbAshCord_0_ Horizon*/
+ 0x0F1200F0, /*TVAR_ash_AwbAshCord_1_ IncandA*/
+ 0x0F120100, /*TVAR_ash_AwbAshCord_2_ WW*/
+ 0x0F120120, /*TVAR_ash_AwbAshCord_3_ CW*/
+ 0x0F120150, /*TVAR_ash_AwbAshCord_4_ D50*/
+ 0x0F120180, /*TVAR_ash_AwbAshCord_5_ D65*/
+ 0x0F1201A0, /*TVAR_ash_AwbAshCord_6_ D75*/
+ 0x002A05FE,
+ 0x0F123800, /*TVAR_ash_GASAlpha_0__0_ Horizon*/
+ 0x0F124000, /*TVAR_ash_GASAlpha_0__1_*/
+ 0x0F124000, /*TVAR_ash_GASAlpha_0__2_*/
+ 0x0F124000, /*TVAR_ash_GASAlpha_0__3_*/
+ 0x0F123800, /*TVAR_ash_GASAlpha_1__0_ IncandA*/
+ 0x0F124000, /*TVAR_ash_GASAlpha_1__1_*/
+ 0x0F124000, /*TVAR_ash_GASAlpha_1__2_*/
+ 0x0F124000, /*TVAR_ash_GASAlpha_1__3_*/
+ 0x0F123800, /*TVAR_ash_GASAlpha_2__0_ WW*/
+ 0x0F124000, /*TVAR_ash_GASAlpha_2__1_*/
+ 0x0F124000, /*TVAR_ash_GASAlpha_2__2_*/
+ 0x0F124000, /*TVAR_ash_GASAlpha_2__3_*/
+ 0x0F123800, /*TVAR_ash_GASAlpha_3__0_ CW*/
+ 0x0F124000, /*TVAR_ash_GASAlpha_3__1_*/
+ 0x0F124000, /*TVAR_ash_GASAlpha_3__2_*/
+ 0x0F124000, /*TVAR_ash_GASAlpha_3__3_*/
+ 0x0F123800, /*TVAR_ash_GASAlpha_4__0_ D50*/
+ 0x0F124000, /*TVAR_ash_GASAlpha_4__1_*/
+ 0x0F124000, /*TVAR_ash_GASAlpha_4__2_*/
+ 0x0F124000, /*TVAR_ash_GASAlpha_4__3_*/
+ 0x0F124000, /*TVAR_ash_GASAlpha_5__0_ D65*/
+ 0x0F124000, /*TVAR_ash_GASAlpha_5__1_*/
+ 0x0F124000, /*TVAR_ash_GASAlpha_5__2_*/
+ 0x0F124000, /*TVAR_ash_GASAlpha_5__3_*/
+ 0x0F124000, /*TVAR_ash_GASAlpha_6__0_ D75*/
+ 0x0F124000, /*TVAR_ash_GASAlpha_6__1_*/
+ 0x0F124000, /*TVAR_ash_GASAlpha_6__2_*/
+ 0x0F124000, /*TVAR_ash_GASAlpha_6__3_*/
+ 0x0F124000, /*TVAR_ash_GASOutdoorAlpha_0_*/
+ 0x0F124000, /*TVAR_ash_GASOutdoorAlpha_1_*/
+ 0x0F124000, /*TVAR_ash_GASOutdoorAlpha_2_*/
+ 0x0F124000, /*TVAR_ash_GASOutdoorAlpha_3_*/
+ 0x00287000,
+ 0x002A2744,
+ 0x0F12B510, /* 70002744*/
+ 0x0F124A1C, /* 70002746*/
+ 0x0F1221FB, /* 70002748*/
+ 0x0F12481C, /* 7000274A*/
+ 0x0F12C004, /* 7000274C*/
+ 0x0F126001, /* 7000274E*/
+ 0x0F12491B, /* 70002750*/
+ 0x0F12481C, /* 70002752*/
+ 0x0F12F000, /* 70002754*/
+ 0x0F12FA0E, /* 70002756*/
+ 0x0F12491B, /* 70002758*/
+ 0x0F12481C, /* 7000275A*/
+ 0x0F12F000, /* 7000275C*/
+ 0x0F12FA0A, /* 7000275E*/
+ 0x0F12491B, /* 70002760*/
+ 0x0F12481C, /* 70002762*/
+ 0x0F12F000, /* 70002764*/
+ 0x0F12FA06, /* 70002766*/
+ 0x0F12491B, /* 70002768*/
+ 0x0F12481C, /* 7000276A*/
+ 0x0F12F000, /* 7000276C*/
+ 0x0F12FA02, /* 7000276E*/
+ 0x0F12491B, /* 70002770*/
+ 0x0F12481C, /* 70002772*/
+ 0x0F12F000, /* 70002774*/
+ 0x0F12F9FE, /* 70002776*/
+ 0x0F12491B, /* 70002778*/
+ 0x0F12481C, /* 7000277A*/
+ 0x0F12F000, /* 7000277C*/
+ 0x0F12F9FA, /* 7000277E*/
+ 0x0F12491B, /* 70002780*/
+ 0x0F12481C, /* 70002782*/
+ 0x0F12F000, /* 70002784*/
+ 0x0F12F9F6, /* 70002786*/
+ 0x0F12481B, /* 70002788*/
+ 0x0F122130, /* 7000278A*/
+ 0x0F128001, /* 7000278C*/
+ 0x0F1221C0, /* 7000278E*/
+ 0x0F128041, /* 70002790*/
+ 0x0F122104, /* 70002792*/
+ 0x0F128081, /* 70002794*/
+ 0x0F122100, /* 70002796*/
+ 0x0F1280C1, /* 70002798*/
+ 0x0F128101, /* 7000279A*/
+ 0x0F124917, /* 7000279C*/
+ 0x0F122016, /* 7000279E*/
+ 0x0F1283C8, /* 700027A0*/
+ 0x0F124917, /* 700027A2*/
+ 0x0F124817, /* 700027A4*/
+ 0x0F12F000, /* 700027A6*/
+ 0x0F12F9E5, /* 700027A8*/
+ 0x0F124917, /* 700027AA*/
+ 0x0F124817, /* 700027AC*/
+ 0x0F12F000, /* 700027AE*/
+ 0x0F12F9E1, /* 700027B0*/
+ 0x0F12BC10, /* 700027B2*/
+ 0x0F12BC08, /* 700027B4*/
+ 0x0F124718, /* 700027B6*/
+ 0x0F120000, /* 700027B8*/
+ 0x0F125BB1, /* 700027BA*/
+ 0x0F121770, /* 700027BC*/
+ 0x0F127000, /* 700027BE*/
+ 0x0F122811, /* 700027C0*/
+ 0x0F127000, /* 700027C2*/
+ 0x0F12C0BB, /* 700027C4*/
+ 0x0F120000, /* 700027C6*/
+ 0x0F12284F, /* 700027C8*/
+ 0x0F127000, /* 700027CA*/
+ 0x0F123609, /* 700027CC*/
+ 0x0F120000, /* 700027CE*/
+ 0x0F122867, /* 700027D0*/
+ 0x0F127000, /* 700027D2*/
+ 0x0F1277C7, /* 700027D4*/
+ 0x0F120000, /* 700027D6*/
+ 0x0F1228F3, /* 700027D8*/
+ 0x0F127000, /* 700027DA*/
+ 0x0F12727D, /* 700027DC*/
+ 0x0F120000, /* 700027DE*/
+ 0x0F122949, /* 700027E0*/
+ 0x0F127000, /* 700027E2*/
+ 0x0F129919, /* 700027E4*/
+ 0x0F120000, /* 700027E6*/
+ 0x0F122987, /* 700027E8*/
+ 0x0F127000, /* 700027EA*/
+ 0x0F121C63, /* 700027EC*/
+ 0x0F120000, /* 700027EE*/
+ 0x0F1229E7, /* 700027F0*/
+ 0x0F127000, /* 700027F2*/
+ 0x0F1204CB, /* 700027F4*/
+ 0x0F120000, /* 700027F6*/
+ 0x0F122C7C, /* 700027F8*/
+ 0x0F127000, /* 700027FA*/
+ 0x0F120CA8, /* 700027FC*/
+ 0x0F127000, /* 700027FE*/
+ 0x0F122B1D, /* 70002800*/
+ 0x0F127000, /* 70002802*/
+ 0x0F1250AF, /* 70002804*/
+ 0x0F120000, /* 70002806*/
+ 0x0F122B2D, /* 70002808*/
+ 0x0F127000, /* 7000280A*/
+ 0x0F125623, /* 7000280C*/
+ 0x0F120000, /* 7000280E*/
+ 0x0F12B4F0, /* 70002810*/
+ 0x0F126801, /* 70002812*/
+ 0x0F12468C, /* 70002814*/
+ 0x0F126846, /* 70002816*/
+ 0x0F122200, /* 70002818*/
+ 0x0F1249C7, /* 7000281A*/
+ 0x0F122000, /* 7000281C*/
+ 0x0F122724, /* 7000281E*/
+ 0x0F124357, /* 70002820*/
+ 0x0F12183B, /* 70002822*/
+ 0x0F124664, /* 70002824*/
+ 0x0F125CE5, /* 70002826*/
+ 0x0F12005C, /* 70002828*/
+ 0x0F125B34, /* 7000282A*/
+ 0x0F12072D, /* 7000282C*/
+ 0x0F120F2D, /* 7000282E*/
+ 0x0F12800D, /* 70002830*/
+ 0x0F12804C, /* 70002832*/
+ 0x0F12808B, /* 70002834*/
+ 0x0F122301, /* 70002836*/
+ 0x0F1280CB, /* 70002838*/
+ 0x0F122300, /* 7000283A*/
+ 0x0F1280CB, /* 7000283C*/
+ 0x0F121C40, /* 7000283E*/
+ 0x0F122824, /* 70002840*/
+ 0x0F12D3EE, /* 70002842*/
+ 0x0F121C52, /* 70002844*/
+ 0x0F122A04, /* 70002846*/
+ 0x0F12D3E8, /* 70002848*/
+ 0x0F12BCF0, /* 7000284A*/
+ 0x0F124770, /* 7000284C*/
+ 0x0F12B510, /* 7000284E*/
+ 0x0F12F000, /* 70002850*/
+ 0x0F12F998, /* 70002852*/
+ 0x0F1248B9, /* 70002854*/
+ 0x0F127A81, /* 70002856*/
+ 0x0F1248B9, /* 70002858*/
+ 0x0F126B00, /* 7000285A*/
+ 0x0F12F000, /* 7000285C*/
+ 0x0F12F99A, /* 7000285E*/
+ 0x0F12BC10, /* 70002860*/
+ 0x0F12BC08, /* 70002862*/
+ 0x0F124718, /* 70002864*/
+ 0x0F12B5F8, /* 70002866*/
+ 0x0F126805, /* 70002868*/
+ 0x0F126844, /* 7000286A*/
+ 0x0F124EB5, /* 7000286C*/
+ 0x0F128861, /* 7000286E*/
+ 0x0F128AB0, /* 70002870*/
+ 0x0F128A72, /* 70002872*/
+ 0x0F122301, /* 70002874*/
+ 0x0F124368, /* 70002876*/
+ 0x0F121889, /* 70002878*/
+ 0x0F1217C2, /* 7000287A*/
+ 0x0F120E12, /* 7000287C*/
+ 0x0F121810, /* 7000287E*/
+ 0x0F121202, /* 70002880*/
+ 0x0F128820, /* 70002882*/
+ 0x0F12029B, /* 70002884*/
+ 0x0F1218C0, /* 70002886*/
+ 0x0F12F000, /* 70002888*/
+ 0x0F12F98C, /* 7000288A*/
+ 0x0F129000, /* 7000288C*/
+ 0x0F128AF6, /* 7000288E*/
+ 0x0F124268, /* 70002890*/
+ 0x0F12210A, /* 70002892*/
+ 0x0F124370, /* 70002894*/
+ 0x0F12F000, /* 70002896*/
+ 0x0F12F98D, /* 70002898*/
+ 0x0F12436E, /* 7000289A*/
+ 0x0F120007, /* 7000289C*/
+ 0x0F12210A, /* 7000289E*/
+ 0x0F120030, /* 700028A0*/
+ 0x0F12F000, /* 700028A2*/
+ 0x0F12F987, /* 700028A4*/
+ 0x0F129A00, /* 700028A6*/
+ 0x0F120039, /* 700028A8*/
+ 0x0F12F000, /* 700028AA*/
+ 0x0F12F989, /* 700028AC*/
+ 0x0F120002, /* 700028AE*/
+ 0x0F128820, /* 700028B0*/
+ 0x0F121880, /* 700028B2*/
+ 0x0F128020, /* 700028B4*/
+ 0x0F1248A4, /* 700028B6*/
+ 0x0F1288C1, /* 700028B8*/
+ 0x0F1248A2, /* 700028BA*/
+ 0x0F123820, /* 700028BC*/
+ 0x0F128B40, /* 700028BE*/
+ 0x0F124240, /* 700028C0*/
+ 0x0F124350, /* 700028C2*/
+ 0x0F12F000, /* 700028C4*/
+ 0x0F12F976, /* 700028C6*/
+ 0x0F128861, /* 700028C8*/
+ 0x0F121840, /* 700028CA*/
+ 0x0F128060, /* 700028CC*/
+ 0x0F12BCF8, /* 700028CE*/
+ 0x0F12BC08, /* 700028D0*/
+ 0x0F124718, /* 700028D2*/
+ 0x0F12B570, /* 700028D4*/
+ 0x0F124C9B, /* 700028D6*/
+ 0x0F123C20, /* 700028D8*/
+ 0x0F128B20, /* 700028DA*/
+ 0x0F12F000, /* 700028DC*/
+ 0x0F12F978, /* 700028DE*/
+ 0x0F124D99, /* 700028E0*/
+ 0x0F1280E8, /* 700028E2*/
+ 0x0F128B60, /* 700028E4*/
+ 0x0F12F000, /* 700028E6*/
+ 0x0F12F97B, /* 700028E8*/
+ 0x0F128128, /* 700028EA*/
+ 0x0F12BC70, /* 700028EC*/
+ 0x0F12BC08, /* 700028EE*/
+ 0x0F124718, /* 700028F0*/
+ 0x0F12B508, /* 700028F2*/
+ 0x0F124895, /* 700028F4*/
+ 0x0F124669, /* 700028F6*/
+ 0x0F12F000, /* 700028F8*/
+ 0x0F12F97A, /* 700028FA*/
+ 0x0F124894, /* 700028FC*/
+ 0x0F12214D, /* 700028FE*/
+ 0x0F128201, /* 70002900*/
+ 0x0F122196, /* 70002902*/
+ 0x0F128281, /* 70002904*/
+ 0x0F12211D, /* 70002906*/
+ 0x0F128301, /* 70002908*/
+ 0x0F12F7FF, /* 7000290A*/
+ 0x0F12FFE3, /* 7000290C*/
+ 0x0F12F000, /* 7000290E*/
+ 0x0F12F977, /* 70002910*/
+ 0x0F12466B, /* 70002912*/
+ 0x0F128818, /* 70002914*/
+ 0x0F128859, /* 70002916*/
+ 0x0F121A40, /* 70002918*/
+ 0x0F12498E, /* 7000291A*/
+ 0x0F126348, /* 7000291C*/
+ 0x0F12488A, /* 7000291E*/
+ 0x0F129900, /* 70002920*/
+ 0x0F123876, /* 70002922*/
+ 0x0F12F000, /* 70002924*/
+ 0x0F12F974, /* 70002926*/
+ 0x0F12466B, /* 70002928*/
+ 0x0F12488A, /* 7000292A*/
+ 0x0F128819, /* 7000292C*/
+ 0x0F123080, /* 7000292E*/
+ 0x0F1284C1, /* 70002930*/
+ 0x0F128859, /* 70002932*/
+ 0x0F128501, /* 70002934*/
+ 0x0F124987, /* 70002936*/
+ 0x0F122000, /* 70002938*/
+ 0x0F123920, /* 7000293A*/
+ 0x0F127088, /* 7000293C*/
+ 0x0F123140, /* 7000293E*/
+ 0x0F127388, /* 70002940*/
+ 0x0F12B001, /* 70002942*/
+ 0x0F12BC08, /* 70002944*/
+ 0x0F124718, /* 70002946*/
+ 0x0F12B570, /* 70002948*/
+ 0x0F120004, /* 7000294A*/
+ 0x0F126820, /* 7000294C*/
+ 0x0F126865, /* 7000294E*/
+ 0x0F12F000, /* 70002950*/
+ 0x0F12F966, /* 70002952*/
+ 0x0F120402, /* 70002954*/
+ 0x0F124880, /* 70002956*/
+ 0x0F120C12, /* 70002958*/
+ 0x0F128142, /* 7000295A*/
+ 0x0F12487F, /* 7000295C*/
+ 0x0F128801, /* 7000295E*/
+ 0x0F122900, /* 70002960*/
+ 0x0F12D008, /* 70002962*/
+ 0x0F12497E, /* 70002964*/
+ 0x0F12002B, /* 70002966*/
+ 0x0F126D8A, /* 70002968*/
+ 0x0F122105, /* 7000296A*/
+ 0x0F121C80, /* 7000296C*/
+ 0x0F12F000, /* 7000296E*/
+ 0x0F12F95F, /* 70002970*/
+ 0x0F126020, /* 70002972*/
+ 0x0F12E005, /* 70002974*/
+ 0x0F12487B, /* 70002976*/
+ 0x0F12002B, /* 70002978*/
+ 0x0F122105, /* 7000297A*/
+ 0x0F12F000, /* 7000297C*/
+ 0x0F12F958, /* 7000297E*/
+ 0x0F126020, /* 70002980*/
+ 0x0F126820, /* 70002982*/
+ 0x0F12E7B2, /* 70002984*/
+ 0x0F12B5F8, /* 70002986*/
+ 0x0F124975, /* 70002988*/
+ 0x0F122200, /* 7000298A*/
+ 0x0F123160, /* 7000298C*/
+ 0x0F1283CA, /* 7000298E*/
+ 0x0F126800, /* 70002990*/
+ 0x0F124669, /* 70002992*/
+ 0x0F12F000, /* 70002994*/
+ 0x0F12F92C, /* 70002996*/
+ 0x0F12466B, /* 70002998*/
+ 0x0F128818, /* 7000299A*/
+ 0x0F12F000, /* 7000299C*/
+ 0x0F12F918, /* 7000299E*/
+ 0x0F120005, /* 700029A0*/
+ 0x0F12466B, /* 700029A2*/
+ 0x0F128858, /* 700029A4*/
+ 0x0F12F000, /* 700029A6*/
+ 0x0F12F91B, /* 700029A8*/
+ 0x0F120004, /* 700029AA*/
+ 0x0F122101, /* 700029AC*/
+ 0x0F121928, /* 700029AE*/
+ 0x0F1202C9, /* 700029B0*/
+ 0x0F121A08, /* 700029B2*/
+ 0x0F120286, /* 700029B4*/
+ 0x0F120029, /* 700029B6*/
+ 0x0F120030, /* 700029B8*/
+ 0x0F12F000, /* 700029BA*/
+ 0x0F12F941, /* 700029BC*/
+ 0x0F120005, /* 700029BE*/
+ 0x0F122701, /* 700029C0*/
+ 0x0F1202BF, /* 700029C2*/
+ 0x0F120021, /* 700029C4*/
+ 0x0F120030, /* 700029C6*/
+ 0x0F12F000, /* 700029C8*/
+ 0x0F12F93A, /* 700029CA*/
+ 0x0F124964, /* 700029CC*/
+ 0x0F124A61, /* 700029CE*/
+ 0x0F123140, /* 700029D0*/
+ 0x0F1232A0, /* 700029D2*/
+ 0x0F12800D, /* 700029D4*/
+ 0x0F128395, /* 700029D6*/
+ 0x0F12804F, /* 700029D8*/
+ 0x0F1283D7, /* 700029DA*/
+ 0x0F128088, /* 700029DC*/
+ 0x0F120011, /* 700029DE*/
+ 0x0F123120, /* 700029E0*/
+ 0x0F128008, /* 700029E2*/
+ 0x0F12E773, /* 700029E4*/
+ 0x0F12B510, /* 700029E6*/
+ 0x0F12485C, /* 700029E8*/
+ 0x0F128980, /* 700029EA*/
+ 0x0F122800, /* 700029EC*/
+ 0x0F12D001, /* 700029EE*/
+ 0x0F12F000, /* 700029F0*/
+ 0x0F12F92C, /* 700029F2*/
+ 0x0F12E734, /* 700029F4*/
+ 0x0F12B5FE, /* 700029F6*/
+ 0x0F122600, /* 700029F8*/
+ 0x0F12495B, /* 700029FA*/
+ 0x0F122000, /* 700029FC*/
+ 0x0F126108, /* 700029FE*/
+ 0x0F1260C8, /* 70002A00*/
+ 0x0F12485A, /* 70002A02*/
+ 0x0F128901, /* 70002A04*/
+ 0x0F124852, /* 70002A06*/
+ 0x0F123020, /* 70002A08*/
+ 0x0F1288C0, /* 70002A0A*/
+ 0x0F129000, /* 70002A0C*/
+ 0x0F120840, /* 70002A0E*/
+ 0x0F129002, /* 70002A10*/
+ 0x0F124856, /* 70002A12*/
+ 0x0F128800, /* 70002A14*/
+ 0x0F129001, /* 70002A16*/
+ 0x0F124853, /* 70002A18*/
+ 0x0F123040, /* 70002A1A*/
+ 0x0F128B05, /* 70002A1C*/
+ 0x0F122900, /* 70002A1E*/
+ 0x0F12D01F, /* 70002A20*/
+ 0x0F124E52, /* 70002A22*/
+ 0x0F122700, /* 70002A24*/
+ 0x0F1280F7, /* 70002A26*/
+ 0x0F122400, /* 70002A28*/
+ 0x0F12E016, /* 70002A2A*/
+ 0x0F12494E, /* 70002A2C*/
+ 0x0F120060, /* 70002A2E*/
+ 0x0F1239C0, /* 70002A30*/
+ 0x0F121841, /* 70002A32*/
+ 0x0F122020, /* 70002A34*/
+ 0x0F125E08, /* 70002A36*/
+ 0x0F129902, /* 70002A38*/
+ 0x0F121840, /* 70002A3A*/
+ 0x0F129900, /* 70002A3C*/
+ 0x0F12F000, /* 70002A3E*/
+ 0x0F12F8FF, /* 70002A40*/
+ 0x0F124B4A, /* 70002A42*/
+ 0x0F120202, /* 70002A44*/
+ 0x0F1200A1, /* 70002A46*/
+ 0x0F12330C, /* 70002A48*/
+ 0x0F12505A, /* 70002A4A*/
+ 0x0F120002, /* 70002A4C*/
+ 0x0F124342, /* 70002A4E*/
+ 0x0F120210, /* 70002A50*/
+ 0x0F121DDA, /* 70002A52*/
+ 0x0F1232F9, /* 70002A54*/
+ 0x0F125050, /* 70002A56*/
+ 0x0F121C64, /* 70002A58*/
+ 0x0F1242A5, /* 70002A5A*/
+ 0x0F12DCE6, /* 70002A5C*/
+ 0x0F128137, /* 70002A5E*/
+ 0x0F12E042, /* 70002A60*/
+ 0x0F122400, /* 70002A62*/
+ 0x0F12E031, /* 70002A64*/
+ 0x0F124940, /* 70002A66*/
+ 0x0F120060, /* 70002A68*/
+ 0x0F1239C0, /* 70002A6A*/
+ 0x0F121841, /* 70002A6C*/
+ 0x0F122020, /* 70002A6E*/
+ 0x0F125E08, /* 70002A70*/
+ 0x0F129902, /* 70002A72*/
+ 0x0F121840, /* 70002A74*/
+ 0x0F129900, /* 70002A76*/
+ 0x0F12F000, /* 70002A78*/
+ 0x0F12F8E2, /* 70002A7A*/
+ 0x0F124A3B, /* 70002A7C*/
+ 0x0F1200A1, /* 70002A7E*/
+ 0x0F12320C, /* 70002A80*/
+ 0x0F125853, /* 70002A82*/
+ 0x0F123A0C, /* 70002A84*/
+ 0x0F128852, /* 70002A86*/
+ 0x0F124353, /* 70002A88*/
+ 0x0F123380, /* 70002A8A*/
+ 0x0F120A1F, /* 70002A8C*/
+ 0x0F1223FF, /* 70002A8E*/
+ 0x0F121C5B, /* 70002A90*/
+ 0x0F121A9B, /* 70002A92*/
+ 0x0F12469C, /* 70002A94*/
+ 0x0F124343, /* 70002A96*/
+ 0x0F1218FF, /* 70002A98*/
+ 0x0F124B34, /* 70002A9A*/
+ 0x0F12330C, /* 70002A9C*/
+ 0x0F12505F, /* 70002A9E*/
+ 0x0F120003, /* 70002AA0*/
+ 0x0F124343, /* 70002AA2*/
+ 0x0F124660, /* 70002AA4*/
+ 0x0F124343, /* 70002AA6*/
+ 0x0F124831, /* 70002AA8*/
+ 0x0F125840, /* 70002AAA*/
+ 0x0F124350, /* 70002AAC*/
+ 0x0F123080, /* 70002AAE*/
+ 0x0F124A2F, /* 70002AB0*/
+ 0x0F120A00, /* 70002AB2*/
+ 0x0F121818, /* 70002AB4*/
+ 0x0F125050, /* 70002AB6*/
+ 0x0F120039, /* 70002AB8*/
+ 0x0F124379, /* 70002ABA*/
+ 0x0F123180, /* 70002ABC*/
+ 0x0F120A09, /* 70002ABE*/
+ 0x0F124281, /* 70002AC0*/
+ 0x0F12D201, /* 70002AC2*/
+ 0x0F121A40, /* 70002AC4*/
+ 0x0F121986, /* 70002AC6*/
+ 0x0F121C64, /* 70002AC8*/
+ 0x0F1242A5, /* 70002ACA*/
+ 0x0F12DCCB, /* 70002ACC*/
+ 0x0F120868, /* 70002ACE*/
+ 0x0F121980, /* 70002AD0*/
+ 0x0F120029, /* 70002AD2*/
+ 0x0F12F000, /* 70002AD4*/
+ 0x0F12F8B4, /* 70002AD6*/
+ 0x0F123008, /* 70002AD8*/
+ 0x0F120900, /* 70002ADA*/
+ 0x0F129A01, /* 70002ADC*/
+ 0x0F124923, /* 70002ADE*/
+ 0x0F124290, /* 70002AE0*/
+ 0x0F12D901, /* 70002AE2*/
+ 0x0F128888, /* 70002AE4*/
+ 0x0F1280C8, /* 70002AE6*/
+ 0x0F124920, /* 70002AE8*/
+ 0x0F1288C8, /* 70002AEA*/
+ 0x0F122800, /* 70002AEC*/
+ 0x0F12D001, /* 70002AEE*/
+ 0x0F121E40, /* 70002AF0*/
+ 0x0F1280C8, /* 70002AF2*/
+ 0x0F129801, /* 70002AF4*/
+ 0x0F122800, /* 70002AF6*/
+ 0x0F12D00D, /* 70002AF8*/
+ 0x0F124A1B, /* 70002AFA*/
+ 0x0F123AC0, /* 70002AFC*/
+ 0x0F127B90, /* 70002AFE*/
+ 0x0F122802, /* 70002B00*/
+ 0x0F12D001, /* 70002B02*/
+ 0x0F122803, /* 70002B04*/
+ 0x0F12D106, /* 70002B06*/
+ 0x0F1288C9, /* 70002B08*/
+ 0x0F122900, /* 70002B0A*/
+ 0x0F12D003, /* 70002B0C*/
+ 0x0F122100, /* 70002B0E*/
+ 0x0F120040, /* 70002B10*/
+ 0x0F121880, /* 70002B12*/
+ 0x0F128081, /* 70002B14*/
+ 0x0F12BCFE, /* 70002B16*/
+ 0x0F12BC08, /* 70002B18*/
+ 0x0F124718, /* 70002B1A*/
+ 0x0F12B510, /* 70002B1C*/
+ 0x0F126800, /* 70002B1E*/
+ 0x0F12F000, /* 70002B20*/
+ 0x0F12F89C, /* 70002B22*/
+ 0x0F124911, /* 70002B24*/
+ 0x0F122001, /* 70002B26*/
+ 0x0F128108, /* 70002B28*/
+ 0x0F12E699, /* 70002B2A*/
+ 0x0F12B510, /* 70002B2C*/
+ 0x0F12F000, /* 70002B2E*/
+ 0x0F12F89D, /* 70002B30*/
+ 0x0F12F7FF, /* 70002B32*/
+ 0x0F12FF60, /* 70002B34*/
+ 0x0F12E693, /* 70002B36*/
+ 0x0F124140, /* 70002B38*/
+ 0x0F12D000, /* 70002B3A*/
+ 0x0F1219DC, /* 70002B3C*/
+ 0x0F127000, /* 70002B3E*/
+ 0x0F121B60, /* 70002B40*/
+ 0x0F127000, /* 70002B42*/
+ 0x0F120DD4, /* 70002B44*/
+ 0x0F127000, /* 70002B46*/
+ 0x0F1222AC, /* 70002B48*/
+ 0x0F127000, /* 70002B4A*/
+ 0x0F120F88, /* 70002B4C*/
+ 0x0F127000, /* 70002B4E*/
+ 0x0F121E8C, /* 70002B50*/
+ 0x0F127000, /* 70002B52*/
+ 0x0F12214C, /* 70002B54*/
+ 0x0F127000, /* 70002B56*/
+ 0x0F121A10, /* 70002B58*/
+ 0x0F127000, /* 70002B5A*/
+ 0x0F123780, /* 70002B5C*/
+ 0x0F127000, /* 70002B5E*/
+ 0x0F122384, /* 70002B60*/
+ 0x0F127000, /* 70002B62*/
+ 0x0F12065C, /* 70002B64*/
+ 0x0F127000, /* 70002B66*/
+ 0x0F121C8C, /* 70002B68*/
+ 0x0F127000, /* 70002B6A*/
+ 0x0F122C7C, /* 70002B6C*/
+ 0x0F127000, /* 70002B6E*/
+ 0x0F122D88, /* 70002B70*/
+ 0x0F127000, /* 70002B72*/
+ 0x0F124778, /* 70002B74*/
+ 0x0F1246C0, /* 70002B76*/
+ 0x0F12C000, /* 70002B78*/
+ 0x0F12E59F, /* 70002B7A*/
+ 0x0F12FF1C, /* 70002B7C*/
+ 0x0F12E12F, /* 70002B7E*/
+ 0x0F12CE77, /* 70002B80*/
+ 0x0F120000, /* 70002B82*/
+ 0x0F124778, /* 70002B84*/
+ 0x0F1246C0, /* 70002B86*/
+ 0x0F12C000, /* 70002B88*/
+ 0x0F12E59F, /* 70002B8A*/
+ 0x0F12FF1C, /* 70002B8C*/
+ 0x0F12E12F, /* 70002B8E*/
+ 0x0F123609, /* 70002B90*/
+ 0x0F120000, /* 70002B92*/
+ 0x0F124778, /* 70002B94*/
+ 0x0F1246C0, /* 70002B96*/
+ 0x0F12C000, /* 70002B98*/
+ 0x0F12E59F, /* 70002B9A*/
+ 0x0F12FF1C, /* 70002B9C*/
+ 0x0F12E12F, /* 70002B9E*/
+ 0x0F129F91, /* 70002BA0*/
+ 0x0F120000, /* 70002BA2*/
+ 0x0F124778, /* 70002BA4*/
+ 0x0F1246C0, /* 70002BA6*/
+ 0x0F12C000, /* 70002BA8*/
+ 0x0F12E59F, /* 70002BAA*/
+ 0x0F12FF1C, /* 70002BAC*/
+ 0x0F12E12F, /* 70002BAE*/
+ 0x0F122AE3, /* 70002BB0*/
+ 0x0F120000, /* 70002BB2*/
+ 0x0F124778, /* 70002BB4*/
+ 0x0F1246C0, /* 70002BB6*/
+ 0x0F12F004, /* 70002BB8*/
+ 0x0F12E51F, /* 70002BBA*/
+ 0x0F12D1DC, /* 70002BBC*/
+ 0x0F120000, /* 70002BBE*/
+ 0x0F124778, /* 70002BC0*/
+ 0x0F1246C0, /* 70002BC2*/
+ 0x0F12C000, /* 70002BC4*/
+ 0x0F12E59F, /* 70002BC6*/
+ 0x0F12FF1C, /* 70002BC8*/
+ 0x0F12E12F, /* 70002BCA*/
+ 0x0F126869, /* 70002BCC*/
+ 0x0F120000, /* 70002BCE*/
+ 0x0F124778, /* 70002BD0*/
+ 0x0F1246C0, /* 70002BD2*/
+ 0x0F12C000, /* 70002BD4*/
+ 0x0F12E59F, /* 70002BD6*/
+ 0x0F12FF1C, /* 70002BD8*/
+ 0x0F12E12F, /* 70002BDA*/
+ 0x0F1268BD, /* 70002BDC*/
+ 0x0F120000, /* 70002BDE*/
+ 0x0F124778, /* 70002BE0*/
+ 0x0F1246C0, /* 70002BE2*/
+ 0x0F12C000, /* 70002BE4*/
+ 0x0F12E59F, /* 70002BE6*/
+ 0x0F12FF1C, /* 70002BE8*/
+ 0x0F12E12F, /* 70002BEA*/
+ 0x0F1268DB, /* 70002BEC*/
+ 0x0F120000, /* 70002BEE*/
+ 0x0F124778, /* 70002BF0*/
+ 0x0F1246C0, /* 70002BF2*/
+ 0x0F12C000, /* 70002BF4*/
+ 0x0F12E59F, /* 70002BF6*/
+ 0x0F12FF1C, /* 70002BF8*/
+ 0x0F12E12F, /* 70002BFA*/
+ 0x0F121BC9, /* 70002BFC*/
+ 0x0F120000, /* 70002BFE*/
+ 0x0F124778, /* 70002C00*/
+ 0x0F1246C0, /* 70002C02*/
+ 0x0F12C000, /* 70002C04*/
+ 0x0F12E59F, /* 70002C06*/
+ 0x0F12FF1C, /* 70002C08*/
+ 0x0F12E12F, /* 70002C0A*/
+ 0x0F1271B9, /* 70002C0C*/
+ 0x0F120000, /* 70002C0E*/
+ 0x0F124778, /* 70002C10*/
+ 0x0F1246C0, /* 70002C12*/
+ 0x0F12C000, /* 70002C14*/
+ 0x0F12E59F, /* 70002C16*/
+ 0x0F12FF1C, /* 70002C18*/
+ 0x0F12E12F, /* 70002C1A*/
+ 0x0F127249, /* 70002C1C*/
+ 0x0F120000, /* 70002C1E*/
+ 0x0F124778, /* 70002C20*/
+ 0x0F1246C0, /* 70002C22*/
+ 0x0F12C000, /* 70002C24*/
+ 0x0F12E59F, /* 70002C26*/
+ 0x0F12FF1C, /* 70002C28*/
+ 0x0F12E12F, /* 70002C2A*/
+ 0x0F1298CD, /* 70002C2C*/
+ 0x0F120000, /* 70002C2E*/
+ 0x0F124778, /* 70002C30*/
+ 0x0F1246C0, /* 70002C32*/
+ 0x0F12C000, /* 70002C34*/
+ 0x0F12E59F, /* 70002C36*/
+ 0x0F12FF1C, /* 70002C38*/
+ 0x0F12E12F, /* 70002C3A*/
+ 0x0F12987F, /* 70002C3C*/
+ 0x0F120000, /* 70002C3E*/
+ 0x0F124778, /* 70002C40*/
+ 0x0F1246C0, /* 70002C42*/
+ 0x0F12F004, /* 70002C44*/
+ 0x0F12E51F, /* 70002C46*/
+ 0x0F12D378, /* 70002C48*/
+ 0x0F120000, /* 70002C4A*/
+ 0x0F124778, /* 70002C4C*/
+ 0x0F1246C0, /* 70002C4E*/
+ 0x0F12C000, /* 70002C50*/
+ 0x0F12E59F, /* 70002C52*/
+ 0x0F12FF1C, /* 70002C54*/
+ 0x0F12E12F, /* 70002C56*/
+ 0x0F1204CB, /* 70002C58*/
+ 0x0F120000, /* 70002C5A*/
+ 0x0F124778, /* 70002C5C*/
+ 0x0F1246C0, /* 70002C5E*/
+ 0x0F12C000, /* 70002C60*/
+ 0x0F12E59F, /* 70002C62*/
+ 0x0F12FF1C, /* 70002C64*/
+ 0x0F12E12F, /* 70002C66*/
+ 0x0F1250AF, /* 70002C68*/
+ 0x0F120000, /* 70002C6A*/
+ 0x0F124778, /* 70002C6C*/
+ 0x0F1246C0, /* 70002C6E*/
+ 0x0F12C000, /* 70002C70*/
+ 0x0F12E59F, /* 70002C72*/
+ 0x0F12FF1C, /* 70002C74*/
+ 0x0F12E12F, /* 70002C76*/
+ 0x0F125623, /* 70002C78*/
+ 0x0F120000, /* 70002C7A*/
+ 0x0028D000,
+ 0x002A1000,
+ 0x0F120001,
+ 0x00287000,
+ 0x002A00F4,
+ 0x0F125DC0, /*REG_TC_IPRM_InClockLSBs*/
+ 0x0F120000, /*REG_TC_IPRM_InClockMSBs 5DC0h=24000d=24Mhz*/
+ 0x002A0110,
+ 0x0F120002, /*REG_TC_IPRM_UseNPviClocks*/
+ 0x0F120000, /*REG_TC_IPRM_bBlockInternalPllCalc*/
+ 0x0F12222E, /*REG_TC_IPRM_OpClk4KHz_0 222Eh=8750d*4=35000d=35Mhz*/
+ 0x0F12445C, /*REG_TC_IPRM_MinOutRate4KHz_0
+ 445CEh=8750d*4=35000d=35Mhz*/
+ 0x0F12445C, /*REG_TC_IPRM_MaxOutRate4KHz_0
+ 445Ch=8750d*4=35000d=35Mhz*/
+ 0x0F12222E, /*REG_TC_IPRM_OpClk4KHz_1*/
+ 0x0F12222E, /*REG_TC_IPRM_MinOutRate4KHz_1*/
+ 0x0F12222E, /*REG_TC_IPRM_MaxOutRate4KHz_1*/
+ 0x002A0126,
+ 0x0F120001, /*REG_TC_IPRM_InitParamsUpdated*/
+ /*0x002A0144,*/
+ /*0x0F120640,*/ /*REG_TC_GP_PrevReqInputWidth 640h=1600d*/
+ /*0x0F1204B0,*/ /*REG_TC_GP_PrevReqInputHeight 4b0h=1200d*/
+ /*0x0F120000,*/ /*REG_TC_GP_PrevInputWidthOfs*/
+ /*0x0F120000,*/ /*REG_TC_GP_PrevInputHeightOfs*/
+ /*0x0F120640,*/ /*REG_TC_GP_CapReqInputWidth 640h=1600d*/
+ /*0x0F1204B0,*/ /*REG_TC_GP_CapReqInputHeight 4b0h=1200d*/
+ /*0x0F120000,*/ /*REG_TC_GP_CapInputWidthOfs*/
+ /*0x0F120000,*/ /*REG_TC_GP_CapInputHeightOfs*/
+ /*0x002A0164,*/
+ /*0x0F120001,*/ /*REG_TC_GP_bUseReqInputInPre*/
+ /*0x0F120001,*/ /*REG_TC_GP_bUseReqInputInCap*/
+ /*0x002A0310,*/
+ /*0x0F120640,*/ /*REG_TC_PZOOM_ZoomInputWidth 640h=1600d*/
+ /*0x0F1204b0,*/ /*REG_TC_PZOOM_ZoomInputHeight 4b0h=1200d*/
+ /*0x0F120000,*/ /*REG_TC_PZOOM_ZoomInputWidthOfs*/
+ /*0x0F120000,*/ /*REG_TC_PZOOM_ZoomInputHeightOfs*/
+ 0x002A0170,
+ 0x0F120280, /*0500 0320 REG_0TC_PCFG_usWidth*/
+ 0x0F1201E0, /*03C0 0258 REG_0TC_PCFG_usHeight*/
+ 0x0F120005, /*0005 0005 REG_0TC_PCFG_Format 0 RGB565;
+ 1 RGB888; 5 Full YUV422; 6 Reduced YUV422; 7 Bayer*/
+ 0x0F12222E, /*445C 222E REG_0TC_PCFG_usMaxOut4KHzRate*/
+ 0x0F12222E, /*445C 222E REG_0TC_PCFG_usMinOut4KHzRate*/
+ 0x0F120042, /*0042 0042 REG_0TC_PCFG_PVIMask*/
+ 0x0F120010, /*0010 0010 REG_0TC_PCFG_OIFMask*/
+ 0x0F120001, /*0000 0001 REG_0TC_PCFG_uClockInd*/
+ 0x0F120000, /*0000 0000 REG_0TC_PCFG_usFrTimeType 0: dynamic
+ 1:fix not accurate 2: fixed_Accurate*/
+ 0x0F120001, /*0000 0001 REG_0TC_PCFG_FrRateQualityType 1b: FR
+ (bin) 2b: Quality (no-bin)*/
+ 0x0F120535, /*0535 0535 REG_0TC_PCFG_uSMaxFrTimeMSecMult10 max
+ frame time : 30fpS:014D 15fpS:029a 7.5fpS:0535
+ 3.75fpS:a6a*/
+ 0x0F1202bb, /*029A 029A REG_0TC_PCFG_uSMinFrTimeMSecMult10 max
+ frame time : 30fpS:014D 15fpS:029a 7.5fpS:0535
+ 3.75fpS:a6a*/
+ 0x0F120000, /*0000 0000 REG_0TC_PCFG_bSmearOutput*/
+ 0x0F120000, /*0000 0000 REG_0TC_PCFG_SSaturation*/
+ 0x0F120000, /*0000 0000 REG_0TC_PCFG_SSharpBlur*/
+ 0x0F120000, /*0000 0000 REG_0TC_PCFG_SColorTemp*/
+ 0x0F120000, /*0000 0000 REG_0TC_PCFG_uDeviceGammaIndex 1:Mirror
+ (X) 2:Mirror(Y) 4:STAT Mirror(X) 8:STAT Mirror(Y)*/
+ 0x0F120003, /*0000 0001 REG_0TC_PCFG_uPrevMirror*/
+ 0x0F120003, /*0000 0001 REG_0TC_PCFG_uCaptureMirror*/
+ 0x0F120000, /*0000 0000 REG_0TC_PCFG_uRotation*/
+ 0x002A0198,
+ 0x0F120280, /*0280 REG_1TC_PCFG_uSWidth 2 70000198 640*/
+ 0x0F1201E0, /*01E0 REG_1TC_PCFG_uSHeight 2 7000019A 480*/
+ 0x0F120005, /*0005 REG_1TC_PCFG_Format 2 7000019C 0 RGB565;
+ 1 RGB888; 5 Full YUV422; 6 Reduced YUV422; 7 Bayer*/
+ 0x0F12222E, /*222E REG_1TC_PCFG_uSMaxOut4KHzRate 2 7000019E*/
+ 0x0F12222E, /*222E REG_1TC_PCFG_uSMinOut4KHzRate 2 700001A0*/
+ 0x0F120042, /*0042 REG_1TC_PCFG_PVIMaSk 2 700001A2*/
+ 0x0F120010, /*0010 REG_1TC_PCFG_OIFMaSk 2 700001A4*/
+ 0x0F120001, /*0001 REG_1TC_PCFG_uClockInd 2 700001A6*/
+ 0x0F120002, /*0000 REG_1TC_PCFG_uSFrTimeType 2 700001A8
+ 0: dynamic 1:fix not accurate 2: fixed_Accurate*/
+ 0x0F120001, /*0001 REG_1TC_PCFG_FrRateQualityType 2 700001AA*/
+ 0x0F12014D, /*01A0 REG_1TC_PCFG_uSMaxFrTimeMSecMult10
+ 2 700001AC
+ max frame time : 30fpS:014D 15fpS:029a
+ 7.5fpS:0535 3.75fpS:a6a*/
+ 0x0F12014D, /*014D REG_1TC_PCFG_uSMinFrTimeMSecMult10
+ 2 700001AE
+ max frame time : 30fpS:014D 15fpS:029a
+ 7.5fpS:0535 3.75fpS:a6a*/
+ 0x0F120000, /*0000 REG_1TC_PCFG_bSmearOutput 2 700001B0*/
+ 0x0F120000, /*0000 REG_1TC_PCFG_SSaturation 2 700001B2*/
+ 0x0F120000, /*0000 REG_1TC_PCFG_SSharpBlur 2 700001B4*/
+ 0x0F120000, /*0000 REG_1TC_PCFG_SColorTemp 2 700001B6*/
+ 0x0F120000, /*0000 REG_1TC_PCFG_uDeviceGammaIndex 2 700001B8*/
+ 0x0F120003, /*0000 REG_1TC_PCFG_uPrevMirror 2 700001BA*/
+ 0x0F120003, /*0000 REG_1TC_PCFG_uCaptureMirror 2 700001BC*/
+ 0x0F120000, /*0000 REG_1TC_PCFG_uRotation 2 700001BE*/
+ 0x002A01C0,
+ 0x0F120280, /*0320 REG_2TC_PCFG_uSWidth*/
+ 0x0F1201e0, /*0258 REG_2TC_PCFG_uSHeight*/
+ 0x0F120005, /*REG_2TC_PCFG_Format*/
+ 0x0F12222E, /*REG_2TC_PCFG_uSMaxOut4KHzRate*/
+ 0x0F12222E, /*REG_2TC_PCFG_uSMinOut4KHzRate*/
+ 0x0F120042, /*REG_2TC_PCFG_PVIMaSk*/
+ 0x0F120010, /*REG_2TC_PCFG_OIFMaSk*/
+ 0x0F120001, /*REG_2TC_PCFG_uClockInd*/
+ 0x0F120000, /*REG_2TC_PCFG_uSFrTimeType*/
+ 0x0F120001, /*REG_2TC_PCFG_FrRateQualityType 1b: FR (bin)
+ 2b: Quality (no-bin)*/
+ 0x0F1207D0, /*REG_2TC_PCFG_uSMaxFrTimeMSecMult10max frame time :
+ 30fpS 014D; 15fpS 029a; a6a - 3.75 fpS; 0535 -
+ 7.5FPS*/
+ 0x0F12029A, /*REG_2TC_PCFG_uSMinFrTimeMSecMult10 2 700001D6*/
+ 0x0F120000, /*REG_2TC_PCFG_bSmearOutput 2 700001D8*/
+ 0x0F120000, /*REG_2TC_PCFG_SSaturation 2 700001DA*/
+ 0x0F120000, /*REG_2TC_PCFG_SSharpBlur 2 700001DC*/
+ 0x0F120000, /*REG_2TC_PCFG_SColorTemp 2 700001DE*/
+ 0x0F120000, /*REG_2TC_PCFG_uDeviceGammaIndex 2 700001E0*/
+ 0x0F120003, /*REG_2TC_PCFG_uPrevMirror 2 700001E2
+ [0] : x [1]: Y [2] Stat X [3] Stat Y*/
+ 0x0F120003, /*REG_2TC_PCFG_uCaptureMirror 2 700001E4*/
+ 0x0F120000, /*REG_2TC_PCFG_uRotation 2 700001E6*/
+ 0x002A01E8,
+ 0x0F120280, /*0320 REG_3TC_PCFG_uSWidth 2 700001E8*/
+ 0x0F1201e0, /*0258 REG_3TC_PCFG_uSHeight 2 700001EA*/
+ 0x0F120005, /*REG_3TC_PCFG_Format 2 700001EC*/
+ 0x0F12222E, /*REG_3TC_PCFG_uSMaxOut4KHzRate 2 700001EE*/
+ 0x0F12222E, /*REG_3TC_PCFG_uSMinOut4KHzRate 2 700001F0*/
+ 0x0F120042, /*REG_3TC_PCFG_PVIMaSk 2 700001F2*/
+ 0x0F120010, /*REG_3TC_PCFG_OIFMaSk 2 700001F4*/
+ 0x0F120001, /*REG_3TC_PCFG_uClockInd 2 700001F6*/
+ 0x0F120002, /*REG_3TC_PCFG_uSFrTimeType 2 700001F8
+ 0: dynamic 1:fix not accurate 2: fixed_Accurate*/
+ 0x0F120001, /*REG_3TC_PCFG_FrRateQualityType 2 700001FA*/
+ 0x0F120190, /*REG_3TC_PCFG_uSMaxFrTimeMSecMult10 2 700001FC
+ max frame time : 30fpS:014D 15fpS:029a 7.5fpS:0535
+ 3.75fpS:a6a*/
+ 0x0F120000, /*REG_3TC_PCFG_uSMinFrTimeMSecMult10 2 700001FE
+ max frame time : 30fpS:014D 15fpS:029a 7.5fpS:0535
+ 3.75fpS:a6a*/
+ 0x0F120000, /*REG_3TC_PCFG_bSmearOutput 2 70000200*/
+ 0x0F120000, /*REG_3TC_PCFG_SSaturation 2 70000202*/
+ 0x0F120000, /*REG_3TC_PCFG_SSharpBlur 2 70000204*/
+ 0x0F120000, /*REG_3TC_PCFG_SColorTemp 2 70000206*/
+ 0x0F120000, /*REG_3TC_PCFG_uDeviceGammaIndex 2 70000208*/
+ 0x0F120003, /*REG_3TC_PCFG_uPrevMirror 2 7000020A*/
+ 0x0F120003, /*REG_3TC_PCFG_uCaptureMirror 2 7000020C*/
+ 0x0F120000, /*REG_3TC_PCFG_uRotation 2 7000020E*/
+ 0x002A0238,
+ 0x0F120001, /*REG_0TC_CCFG_uCaptureMode 2 70000238*/
+ 0x0F120640, /*REG_0TC_CCFG_uSWidth 2 7000023A*/
+ 0x0F1204B0, /*REG_0TC_CCFG_uSHeight 2 7000023C*/
+ 0x0F120005, /*REG_0TC_CCFG_Format 2 7000023E*/
+ 0x0F12222E, /*REG_0TC_CCFG_uSMaxOut4KHzRate 2 70000240*/
+ 0x0F12222E, /*REG_0TC_CCFG_uSMinOut4KHzRate 2 70000242*/
+ 0x0F120042, /*REG_0TC_CCFG_PVIMaSk 2 70000244*/
+ 0x0F120000, /*REG_0TC_CCFG_OIFMaSk 2 70000246*/
+ 0x0F120001, /*REG_0TC_CCFG_uClockInd 2 70000248*/
+ 0x0F120002, /*REG_0TC_CCFG_uSFrTimeType 2 7000024A*/
+ 0x0F120002, /*REG_0TC_CCFG_FrRateQualityType 2 7000024C*/
+ 0x0F120514, /*0535 REG_0TC_CCFG_uSMaxFrTimeMSecMult10
+ 2 7000024E*/
+ 0x0F120514, /*0535 REG_0TC_CCFG_uSMinFrTimeMSecMult10
+ 2 70000250*/
+ 0x0F120000, /*REG_0TC_CCFG_bSmearOutput 2 70000252*/
+ 0x0F120000, /*REG_0TC_CCFG_SSaturation 2 70000254*/
+ 0x0F120000, /*REG_0TC_CCFG_SSharpBlur 2 70000256*/
+ 0x0F120000, /*REG_0TC_CCFG_SColorTemp 2 70000258*/
+ 0x0F120000, /*REG_0TC_CCFG_uDeviceGammaIndex 2 7000025A*/
+ 0x0F120001, /*REG_1TC_CCFG_uCaptureMode 2 7000025C*/
+ 0x0F120640, /*REG_1TC_CCFG_uSWidth 2 7000025E*/
+ 0x0F1204B0, /*REG_1TC_CCFG_uSHeight 2 70000260*/
+ 0x0F120005, /*REG_1TC_CCFG_Format 2 70000262*/
+ 0x0F12445C, /*222E REG_1TC_CCFG_uSMaxOut4KHzRate 2 70000264*/
+ 0x0F12445C, /*222E REG_1TC_CCFG_uSMinOut4KHzRate 2 70000266*/
+ 0x0F120042, /*REG_1TC_CCFG_PVIMaSk 2 70000268*/
+ 0x0F120010, /*0000 REG_1TC_CCFG_OIFMaSk 2 7000026A*/
+ 0x0F120000,/*0001 REG_1TC_CCFG_uClockInd 2 7000026C*/
+ 0x0F120000, /*REG_1TC_CCFG_uSFrTimeType 2 7000026E*/
+ 0x0F120002, /*REG_1TC_CCFG_FrRateQualityType 2 70000270*/
+ 0x0F121388, /*REG_1TC_CCFG_uSMaxFrTimeMSecMult10 2 70000272*/
+ 0x0F121388, /*REG_1TC_CCFG_uSMinFrTimeMSecMult10 2 70000274*/
+ 0x0F120000, /*REG_1TC_CCFG_bSmearOutput 2 70000276*/
+ 0x0F120000, /*REG_1TC_CCFG_SSaturation 2 70000278*/
+ 0x0F120000, /*REG_1TC_CCFG_SSharpBlur 2 7000027A*/
+ 0x0F120000, /*REG_1TC_CCFG_SColorTemp 2 7000027C*/
+ 0x0F120000, /*REG_1TC_CCFG_uDeviceGammaIndex 2 7000027E*/
+ 0x002A1218,
+ 0x0F120002, /*SenHal_SenBinFactor*/
+ 0xFFFF0064,
+ 0x00287000,
+ 0x002A0CC0,
+ 0x0F120001, /*AFC_Default BIT[0] 1:60Hz 0:50Hz*/
+ 0x002A0374,
+ 0x0F12067F, /*REG_TC_DBG BIT[5] : Auto Flicker Disable*/
+
+ /*Int Time limit*/
+ 0x00287000,
+ 0x002A1220,
+ 0x0F1201B7, /*senHal_ExpMinPixels*/
+
+
+
+ 0x002A10C0,
+ 0x0F120040, /*TVAR_ae_BrAve*/
+ 0x002A10C6,
+ 0x0F12000F, /*ae_StatMode*/
+ 0x002A03B2,
+ 0x0F12010E, /*lt_uLimitHigh*/
+ 0x0F1200F5, /*lt_uLimitLow*/
+ 0x002A03C4,
+ 0x0F123415, /*lt_uMaxExp1 3415h=13333d/400d=33.3325ms*/
+ 0x002A03C8,
+ 0x0F12681F, /*lt_uMaxExp2 681Fh=26655d/400d=66.6375ms*/
+ 0x002A03CC,
+ 0x0F128227, /*lt_uMaxExp3 8227h=33319d/400d=83.2975ms*/
+ 0x002A03D0,
+ 0x0F120D40, /*lt_uMaxExp4 30D40h=50000d/400d=500ms*/
+ 0x0F120003,
+ 0x002A03D4,
+ 0x0F123415, /*lt_uCapMaxExp1 3415h=13333d/400d=33.3325ms*/
+ 0x002A03D8,
+ 0x0F12681F, /*lt_uCapMaxExp2 681Fh=26655d/400d=66.6375ms*/
+ 0x002A03DC,
+ 0x0F128227, /*lt_uCapMaxExp3 8227h=33319d/400d=83.2975ms*/
+ 0x002A03E0,
+ 0x0F120D40, /*lt_uCapMaxExp4 30D40h=50000d/400d=500ms*/
+ 0x0F120003,
+ 0x002A03E4,
+ 0x0F120230, /*lt_uMaxAnGain1 0230h=0560d/256d=x2.1875*/
+ 0x0F120260, /*lt_uMaxAnGain2 0260h=0608d/256d=x2.375*/
+ 0x0F120370, /*lt_uMaxAnGain3 0370h=0704d/256d=x3.4375*/
+ 0x0F120880, /*lt_uMaxAnGain4 0710h=2176d/256d=x8.5*/
+ 0x0F120100, /*lt_uMaxDigGain*/
+ 0x0F128000, /*lt_uMaxTotGain*/
+ 0x0F120230, /*lt_uCapMaxAnGain1 0230h=0560d/256d=x2.1875*/
+ 0x0F120260, /*lt_uCapMaxAnGain2 0260h=0608d/256d=x2.375*/
+ 0x0F120380, /*lt_uCapMaxAnGain3 0370h=0704d/256d=x3.4375*/
+ 0x0F120880, /*lt_uCapMaxAnGain4 0710h=2176d/256d=x8.5*/
+ 0x0F120100, /*lt_uCapMaxDigGain*/
+ 0x0F128000, /*lt_uCapMaxTotGain*/
+ 0x002A10CE,
+ 0x0F120000, /*ae_WeightTbl_16[0]*/
+ 0x0F120101, /*ae_WeightTbl_16[1]*/
+ 0x0F120101, /*ae_WeightTbl_16[2]*/
+ 0x0F120000, /*ae_WeightTbl_16[3]*/
+ 0x0F120101, /*ae_WeightTbl_16[4]*/
+ 0x0F120101, /*ae_WeightTbl_16[5]*/
+ 0x0F120101, /*ae_WeightTbl_16[6]*/
+ 0x0F120101, /*ae_WeightTbl_16[7]*/
+ 0x0F120201, /*ae_WeightTbl_16[8]*/
+ 0x0F120303, /*ae_WeightTbl_16[9]*/
+ 0x0F120303, /*ae_WeightTbl_16[10]*/
+ 0x0F120102, /*ae_WeightTbl_16[11]*/
+ 0x0F120201, /*ae_WeightTbl_16[12]*/
+ 0x0F120403, /*ae_WeightTbl_16[13]*/
+ 0x0F120304, /*ae_WeightTbl_16[14]*/
+ 0x0F120102, /*ae_WeightTbl_16[15]*/
+ 0x0F120201, /*ae_WeightTbl_16[16]*/
+ 0x0F120403, /*ae_WeightTbl_16[17]*/
+ 0x0F120304, /*ae_WeightTbl_16[18]*/
+ 0x0F120102, /*ae_WeightTbl_16[19]*/
+ 0x0F120201, /*ae_WeightTbl_16[20]*/
+ 0x0F120403, /*ae_WeightTbl_16[21]*/
+ 0x0F120304, /*ae_WeightTbl_16[22]*/
+ 0x0F120102, /*ae_WeightTbl_16[23]*/
+ 0x0F120201, /*ae_WeightTbl_16[24]*/
+ 0x0F120303, /*ae_WeightTbl_16[25]*/
+ 0x0F120303, /*ae_WeightTbl_16[26]*/
+ 0x0F120102, /*ae_WeightTbl_16[27]*/
+ 0x0F120201, /*ae_WeightTbl_16[28]*/
+ 0x0F120202, /*ae_WeightTbl_16[29]*/
+ 0x0F120202, /*ae_WeightTbl_16[30]*/
+ 0x0F120102, /*ae_WeightTbl_16[31]*/
+ 0x002A0DCC, /*AWB Init White Locus*/
+ 0x0F120138, /*awbb_IntcR*/
+ 0x0F12011C, /*awbb_IntcB*/
+ 0x0F1202A7, /*awbb_GLocusR*/
+ 0x0F120343, /*awbb_GLocusB*/
+ 0x002A0DEC,
+ 0x0F1205F0, /*awbb_GamutWidthThr1*/
+ 0x0F1201F4, /*awbb_GamutHeightThr1*/
+ 0x0F12006C, /*awbb_GamutWidthThr2*/
+ 0x0F120038, /*awbb_GamutHeightThr2*/
+ 0x002A0DD8,
+ 0x0F12000C, /*awbb_MinNumOfFinalPatches*/
+ 0x002A0E50,
+ 0x0F12FE82, /*awbb_SCDetectionMap_SEC_StartR_B*/
+ 0x0F12001E, /*awbb_SCDetectionMap_SEC_StepR_B*/
+ 0x0F120640, /*awbb_SCDetectionMap_SEC_SunnyNB*/
+ 0x0F120122, /*awbb_SCDetectionMap_SEC_StepNB*/
+ 0x0F1200E4, /*awbb_SCDetectionMap_SEC_LowTempR_B*/
+ 0x0F120096, /*awbb_SCDetectionMap_SEC_SunnyNBZone*/
+ 0x0F12000E, /*awbb_SCDetectionMap_SEC_LowTempR_BZone*/
+ 0x002A0DB4, /*LowTemp Zone*/
+ 0x0F12036C, /*awbb_CrclLowT_R_c*/
+ 0x002A0DB8,
+ 0x0F12011D, /*awbb_CrclLowT_B_c*/
+ 0x002A0DBC,
+ 0x0F1262C1, /*awbb_CrclLowT_Rad_c*/
+ 0x002A22BA,
+ 0x0F120006, /*Mon_AWB_ByPassMode*/
+ 0x002A0DEA,
+ 0x0F120000, /*awbb_movingscale10*/
+ 0x002A0F7A,
+ 0x0F120000, /*awbb_RGainOff*/
+ 0x0F120000, /*awbb_BGainOff*/
+ 0x0F120000, /*awbb_GGainOff*/
+ 0x0F1200C2, /*awbb_Alpha_Comp_Mode*/
+ 0x0F120002, /*awbb_Rpl_InvalidOutDoor*/
+ 0x0F120001, /*awbb_UseGrThrCorr*/
+ 0x0F1200E4, /*awbb_Use_Filters*/
+
+ 0x0F12053C, /*awbb_GainsInit[0]*/
+ 0x0F120400, /*awbb_GainsInit[1]*/
+ 0x0F1207ac, /*7AC, 55C, awbb_GainsInit[2]*/
+
+ 0x0F12001E, /*awbb_WpFilterMinThr*/
+ 0x0F120190, /*awbb_WpFilterMaxThr*/
+ 0x0F120064, /*awbb_WpFilterCoef*/
+
+ 0x0F120004, /*awbb_WpFilterSize*/
+ 0x0F120001, /*awbb_otp_disable*/
+ 0x0F120002, /*awbb_GridEnable*/
+ 0x002A0CE0,
+ 0x0F1203F8, /*03F8 03B5 awbb_IndoorGrZones_m_BGrid[0]*/
+ 0x0F120422, /*0422 03DF awbb_IndoorGrZones_m_BGrid[1]*/
+ 0x0F120390, /*03B4 032D awbb_IndoorGrZones_m_BGrid[2]*/
+ 0x0F12042A, /*0408 03D5 awbb_IndoorGrZones_m_BGrid[3]*/
+ 0x0F120352, /*0370 0303 awbb_IndoorGrZones_m_BGrid[4]*/
+ 0x0F12041E, /*03EE 03BB awbb_IndoorGrZones_m_BGrid[5]*/
+ 0x0F120318, /*032C 02DB awbb_IndoorGrZones_m_BGrid[6]*/
+ 0x0F1203DC, /*03FC, 03D4 0397 awbb_IndoorGrZones_m_BGrid[7]*/
+ 0x0F1202E4, /*02E4, 0302 02B1 awbb_IndoorGrZones_m_BGrid[8]*/
+ 0x0F12039C, /*03BA, 03BA 036B awbb_IndoorGrZones_m_BGrid[9]*/
+ 0x0F1202B8, /*02B8, 02DA 0289 awbb_IndoorGrZones_m_BGrid[10]*/
+ 0x0F120368, /*037E, 0374 0349 awbb_IndoorGrZones_m_BGrid[11]*/
+ 0x0F120290, /*0290, 02B0 026F awbb_IndoorGrZones_m_BGrid[12]*/
+ 0x0F12033E, /*034A, 0328 0329 awbb_IndoorGrZones_m_BGrid[13]*/
+ 0x0F120274, /*0274, 0288 0257 awbb_IndoorGrZones_m_BGrid[14]*/
+ 0x0F120316, /*031A, 0300 0309 awbb_IndoorGrZones_m_BGrid[15]*/
+ 0x0F120252, /*0270 0241 awbb_IndoorGrZones_m_BGrid[16]*/
+ 0x0F1202F8, /*02DE 02DD awbb_IndoorGrZones_m_BGrid[17]*/
+ 0x0F120232, /*0258 0227 awbb_IndoorGrZones_m_BGrid[18]*/
+ 0x0F1202E0, /*02BE 02C3 awbb_IndoorGrZones_m_BGrid[19]*/
+ 0x0F12021E, /*0240 0213 awbb_IndoorGrZones_m_BGrid[20]*/
+ 0x0F1202C8, /*02A0 02AF awbb_IndoorGrZones_m_BGrid[21]*/
+ 0x0F120206, /*0228 0209 awbb_IndoorGrZones_m_BGrid[22]*/
+ 0x0F1202B2, /*0296 0295 awbb_IndoorGrZones_m_BGrid[23]*/
+ 0x0F1201FA, /*0212 020D awbb_IndoorGrZones_m_BGrid[24]*/
+ 0x0F1202A2, /*0284 0285 awbb_IndoorGrZones_m_BGrid[25]*/
+ 0x0F1201F4, /*0208 0223 awbb_IndoorGrZones_m_BGrid[26]*/
+ 0x0F120294, /*0274 0261 awbb_IndoorGrZones_m_BGrid[27]*/
+ 0x0F120200, /*020C 0000 awbb_IndoorGrZones_m_BGrid[28]*/
+ 0x0F120288, /*026E 0000 awbb_IndoorGrZones_m_BGrid[29]*/
+ 0x0F120214, /*0222 0000 awbb_IndoorGrZones_m_BGrid[30]*/
+ 0x0F120250, /*0260 0000 awbb_IndoorGrZones_m_BGrid[31]*/
+ 0x0F120000, /*0000 0000 awbb_IndoorGrZones_m_BGrid[32]*/
+ 0x0F120000, /*0000 0000 awbb_IndoorGrZones_m_BGrid[33]*/
+ 0x0F120000, /*0000 0000 awbb_IndoorGrZones_m_BGrid[34]*/
+ 0x0F120000, /*0000 0000 awbb_IndoorGrZones_m_BGrid[35]*/
+ 0x0F120000, /*0000 0000 awbb_IndoorGrZones_m_BGrid[36]*/
+ 0x0F120000, /*0000 0000 awbb_IndoorGrZones_m_BGrid[37]*/
+ 0x0F120000, /*0000 0000 awbb_IndoorGrZones_m_BGrid[38]*/
+ 0x0F120000, /*0000 0000 awbb_IndoorGrZones_m_BGrid[39]*/
+ 0x0F120005, /*awbb_IndoorGrZones_m_GridStep*/
+ 0x002A0D34,
+ 0x0F120010, /*awbb_IndoorGrZones_ZInfo_m_GridSz*/
+ 0x002A0D38,
+ 0x0F1200FE, /*awbb_IndoorGrZones_m_Boff*/
+ 0x002A0D3C,
+ 0x0F120294, /*0294 02A4 02B0 02B6 02B8 02A2 02B8
+ 029F awbb_OutdoorGrZones_m_BGrid[0]*/
+ 0x0F1202F2, /*02F2 02F2 02F0 02F2 02F2 02D4 02F2
+ 02CE awbb_OutdoorGrZones_m_BGrid[1]*/
+ 0x0F120276, /*0276 0276 028A 0276 028E 0282 028E
+ 0282 awbb_OutdoorGrZones_m_BGrid[2]*/
+ 0x0F12030A, /*030A 030A 02FC 030A 030A 02EE 030A
+ 02DA awbb_OutdoorGrZones_m_BGrid[3]*/
+ 0x0F120258, /*0258 0258 026C 0258 026E 027A 027A
+ 026D awbb_OutdoorGrZones_m_BGrid[4]*/
+ 0x0F12030A, /*0302 0302 030A 0302 030A 030A 030A
+ 02C2 awbb_OutdoorGrZones_m_BGrid[5]*/
+ 0x0F120246, /*0246 0246 0258 0246 025E 027A 0274
+ 0256 awbb_OutdoorGrZones_m_BGrid[6]*/
+ 0x0F1202FA, /*02EA 02EA 0302 02EA 02FE 030A 02FE
+ 02A6 awbb_OutdoorGrZones_m_BGrid[7]*/
+ 0x0F120256, /*0256 0256 0246 0256 0264 0274 0282
+ 026E awbb_OutdoorGrZones_m_BGrid[8]*/
+ 0x0F1202DC, /*02B8 02B8 02EA 02B8 02D0 02FE 02DC
+ 028A awbb_OutdoorGrZones_m_BGrid[9]*/
+ 0x0F120000, /*0000 0000 0256 0000 0000 0282 0000
+ 0000 awbb_OutdoorGrZones_m_BGrid[10]*/
+ 0x0F120000, /*0000 0000 02B8 0000 0000 02DC 0000
+ 0000 awbb_OutdoorGrZones_m_BGrid[11]*/
+ 0x0F120000, /*0000 0000 0000 0000 0000 0000 0000
+ 0000 awbb_OutdoorGrZones_m_BGrid[12]*/
+ 0x0F120000, /*0000 0000 0000 0000 0000 0000 0000
+ 0000 awbb_OutdoorGrZones_m_BGrid[13]*/
+ 0x0F120000, /*0000 0000 0000 0000 0000 0000 0000
+ 0000 awbb_OutdoorGrZones_m_BGrid[14]*/
+ 0x0F120000, /*0000 0000 0000 0000 0000 0000 0000
+ 0000 awbb_OutdoorGrZones_m_BGrid[15]*/
+ 0x0F120000, /*0000 0000 0000 0000 0000 0000 0000
+ 0000 awbb_OutdoorGrZones_m_BGrid[16]*/
+ 0x0F120000, /*0000 0000 0000 0000 0000 0000 0000
+ 0000 awbb_OutdoorGrZones_m_BGrid[17]*/
+ 0x0F120000, /*0000 0000 0000 0000 0000 0000 0000
+ 0000 awbb_OutdoorGrZones_m_BGrid[18]*/
+ 0x0F120000, /*0000 0000 0000 0000 0000 0000 0000
+ 0000 awbb_OutdoorGrZones_m_BGrid[19]*/
+ 0x0F120000, /*0000 0000 0000 0000 0000 0000 0000
+ 0000 awbb_OutdoorGrZones_m_BGrid[20]*/
+ 0x0F120000, /*0000 0000 0000 0000 0000 0000 0000
+ 0000 awbb_OutdoorGrZones_m_BGrid[21]*/
+ 0x0F120000, /*0000 0000 0000 0000 0000 0000 0000
+ 0000 awbb_OutdoorGrZones_m_BGrid[22]*/
+ 0x0F120000, /*0000 0000 0000 0000 0000 0000 0000
+ 0000 awbb_OutdoorGrZones_m_BGrid[23]*/
+ 0x0F120005, /*awbb_OutdoorGrZones_m_GridStep*/
+ 0x002A0D70,
+ 0x0F120005, /*awbb_OutdoorGrZones_ZInfo_m_GridSz*/
+ 0x002A0D74,
+ 0x0F1201EB, /*awbb_OutdoorGrZones_m_Boffs*/
+ 0x002A0D78,
+ 0x0F1203CE, /*awbb_LowBrGrZones_m_BGrid[0]*/
+ 0x0F12046E, /*awbb_LowBrGrZones_m_BGrid[1]*/
+ 0x0F12034E, /*awbb_LowBrGrZones_m_BGrid[2]*/
+ 0x0F120474, /*awbb_LowBrGrZones_m_BGrid[3]*/
+ 0x0F1202EA, /*awbb_LowBrGrZones_m_BGrid[4]*/
+ 0x0F120434, /*awbb_LowBrGrZones_m_BGrid[5]*/
+ 0x0F12028C, /*awbb_LowBrGrZones_m_BGrid[6]*/
+ 0x0F1203F0, /*awbb_LowBrGrZones_m_BGrid[7]*/
+ 0x0F120244, /*awbb_LowBrGrZones_m_BGrid[8]*/
+ 0x0F120380, /*awbb_LowBrGrZones_m_BGrid[9]*/
+ 0x0F12020E, /*awbb_LowBrGrZones_m_BGrid[10]*/
+ 0x0F120330, /*awbb_LowBrGrZones_m_BGrid[11]*/
+ 0x0F1201EC, /*awbb_LowBrGrZones_m_BGrid[12]*/
+ 0x0F1202EC, /*awbb_LowBrGrZones_m_BGrid[13]*/
+ 0x0F1201D0, /*awbb_LowBrGrZones_m_BGrid[14]*/
+ 0x0F1202BC, /*awbb_LowBrGrZones_m_BGrid[15]*/
+ 0x0F1201C8, /*awbb_LowBrGrZones_m_BGrid[16]*/
+ 0x0F120296, /*awbb_LowBrGrZones_m_BGrid[17]*/
+ 0x0F1201D2, /*awbb_LowBrGrZones_m_BGrid[18]*/
+ 0x0F120266, /*awbb_LowBrGrZones_m_BGrid[19]*/
+ 0x0F120000, /*awbb_LowBrGrZones_m_BGrid[20]*/
+ 0x0F120000, /*awbb_LowBrGrZones_m_BGrid[21]*/
+ 0x0F120000, /*awbb_LowBrGrZones_m_BGrid[22]*/
+ 0x0F120000, /*awbb_LowBrGrZones_m_BGrid[23]*/
+ 0x0F120006, /*awbb_LowBrGrZones_m_GridStep*/
+ 0x002A0DAC,
+ 0x0F12000A, /*awbb_LowBrGrZones_ZInfo_m_GridSz*/
+ 0x002A0DB0,
+ 0x0F1200E2, /*awbb_LowBrGrZones_m_Boffs*/
+ 0x002A0F60,
+ 0x0F1202E2, /*awbb_GridConst_1[0]*/
+ 0x0F12034B, /*awbb_GridConst_1[1]*/
+ 0x0F120399, /*awbb_GridConst_1[2]*/
+ 0x0F12102D, /*awbb_GridConst_2[0]*/
+ 0x0F1210DE, /*awbb_GridConst_2[1]*/
+ 0x0F12116E, /*awbb_GridConst_2[2]*/
+ 0x0F12117B, /*awbb_GridConst_2[3]*/
+ 0x0F12120A, /*11FF awbb_GridConst_2[4]*/
+ 0x0F121247, /*awbb_GridConst_2[5]*/
+ 0x0F1202C4, /*awbb_GridCoeff_R_1*/
+ 0x0F1202E4, /*awbb_GridCoeff_B_1*/
+ 0x0F1200C3, /*awbb_GridCoeff_R_2*/
+ 0x0F1200A6, /*awbb_GridCoeff_B_2*/
+ 0x002A0ED0,
+
+ 0x0F120046, /*0046, 0046 000A 000A awbb_GridCorr_R[0][0]*/
+ 0x0F120000, /*0000, 0028 0028 0028 awbb_GridCorr_R[0][1]*/
+ 0x0F120000, /*0000, 0028 0028 0028 awbb_GridCorr_R[0][2]*/
+ 0x0F12FFEC, /*FFEC, FFEC FFEC FFEC awbb_GridCorr_R[0][3]*/
+ 0x0F12FFEC, /*FFEC, FFEC FFEC FFEC awbb_GridCorr_R[0][4]*/
+ 0x0F120028, /*0028, 0028 0000 001E awbb_GridCorr_R[0][5]*/
+ 0x0F120046, /*0046, 0046 000A 000A awbb_GridCorr_R[1][0]*/
+ 0x0F120000, /*0000, 0028 0028 0028 awbb_GridCorr_R[1][1]*/
+ 0x0F120000, /*0000, 0028 0028 0028 awbb_GridCorr_R[1][2]*/
+ 0x0F12FFEC, /*FFEC, FFEC FFEC FFEC awbb_GridCorr_R[1][3]*/
+ 0x0F12FFEC, /*FFEC, FFEC FFEC FFEC awbb_GridCorr_R[1][4]*/
+ 0x0F120028, /*0028, 0028 0000 001E awbb_GridCorr_R[1][5]*/
+ 0x0F120046, /*0046, 0046 000A 000A awbb_GridCorr_R[2][0]*/
+ 0x0F120000, /*0000, 0028 0028 0028 awbb_GridCorr_R[2][1]*/
+ 0x0F120000, /*0000, 0028 0028 0028 awbb_GridCorr_R[2][2]*/
+ 0x0F12FFEC, /*FFEC, FFEC FFEC FFEC awbb_GridCorr_R[2][3]*/
+ 0x0F12FFEC, /*FFEC, FFEC FFEC FFEC awbb_GridCorr_R[2][4]*/
+ 0x0F120028, /*0028, 0028 0000 001E awbb_GridCorr_R[2][5]*/
+ 0x0F12FFD8, /*FFD8, FFD8 FFD8 FFD8 awbb_GridCorr_B[0][0]*/
+ 0x0F12FFCE, /*0050, 003C 003C 003C awbb_GridCorr_B[0][1]*/
+ 0x0F12FFCE, /*0050, 003C 003C 003C awbb_GridCorr_B[0][2]*/
+ 0x0F12FFCE, /*FFCE, FFCE FFCE 0000 awbb_GridCorr_B[0][3]*/
+ 0x0F12FFCE, /*FFCE, FFCE FFCE 0000 awbb_GridCorr_B[0][4]*/
+ 0x0F12FF9C, /*FF9C, FF9C FE70 001E awbb_GridCorr_B[0][5]*/
+ 0x0F12FFD8, /*FFD8, FFD8 FFD8 FFD8 awbb_GridCorr_B[1][0]*/
+ 0x0F12FFCE, /*0050, 003C 003C 003C awbb_GridCorr_B[1][1]*/
+ 0x0F12FFCE, /*0050, 003C 003C 003C awbb_GridCorr_B[1][2]*/
+ 0x0F12FFCE, /*FFCE, FFCE FFCE 0000 awbb_GridCorr_B[1][3]*/
+ 0x0F12FFCE, /*FFCE, FFCE FFCE 0000 awbb_GridCorr_B[1][4]*/
+ 0x0F12FF9C, /*FF9C, FF9C FE70 001E awbb_GridCorr_B[1][5]*/
+ 0x0F12FFD8, /*FFD8, FFD8 FFD8 FFD8 awbb_GridCorr_B[2][0]*/
+ 0x0F12FFCE, /*0050, 003C 003C 003C awbb_GridCorr_B[2][1]*/
+ 0x0F12FFCE, /*0050, 003C 003C 003C awbb_GridCorr_B[2][2]*/
+ 0x0F12FFCE, /*FFCE, FFCE FFCE 0000 awbb_GridCorr_B[2][3]*/
+ 0x0F12FFCE, /*FFCE, FFCE FFCE 0000 awbb_GridCorr_B[2][4]*/
+ 0x0F12FF9C, /*FF9C, FF9C FE70 001E awbb_GridCorr_B[2][5]*/
+ 0x0F120000, /*awbb_GridCorr_R_Out[0][0]*/
+ 0x0F12FFE0, /*awbb_GridCorr_R_Out[0][1]*/
+ 0x0F120000, /*awbb_GridCorr_R_Out[0][2]*/
+ 0x0F120000, /*awbb_GridCorr_R_Out[0][3]*/
+ 0x0F120000, /*awbb_GridCorr_R_Out[0][4]*/
+ 0x0F120000, /*awbb_GridCorr_R_Out[0][5]*/
+ 0x0F120000, /*awbb_GridCorr_R_Out[1][0]*/
+ 0x0F12FFE0, /*awbb_GridCorr_R_Out[1][1]*/
+ 0x0F120000, /*awbb_GridCorr_R_Out[1][2]*/
+ 0x0F120000, /*awbb_GridCorr_R_Out[1][3]*/
+ 0x0F120000, /*awbb_GridCorr_R_Out[1][4]*/
+ 0x0F120000, /*awbb_GridCorr_R_Out[1][5]*/
+ 0x0F120000, /*awbb_GridCorr_R_Out[2][0]*/
+ 0x0F12FFE0, /*awbb_GridCorr_R_Out[2][1]*/
+ 0x0F120000, /*awbb_GridCorr_R_Out[2][2]*/
+ 0x0F120000, /*awbb_GridCorr_R_Out[2][3]*/
+ 0x0F120000, /*awbb_GridCorr_R_Out[2][4]*/
+ 0x0F120000, /*awbb_GridCorr_R_Out[2][5]*/
+ 0x0F120000, /*awbb_GridCorr_B_Out[0][0]*/
+ 0x0F12FFDE, /*awbb_GridCorr_B_Out[0][1]*/
+ 0x0F120000, /*awbb_GridCorr_B_Out[0][2]*/
+ 0x0F120000, /*awbb_GridCorr_B_Out[0][3]*/
+ 0x0F120000, /*awbb_GridCorr_B_Out[0][4]*/
+ 0x0F120000, /*awbb_GridCorr_B_Out[0][5]*/
+ 0x0F120000, /*awbb_GridCorr_B_Out[1][0]*/
+ 0x0F12FFDE, /*awbb_GridCorr_B_Out[1][1]*/
+ 0x0F120000, /*awbb_GridCorr_B_Out[1][2]*/
+ 0x0F120000, /*awbb_GridCorr_B_Out[1][3]*/
+ 0x0F120000, /*awbb_GridCorr_B_Out[1][4]*/
+ 0x0F120000, /*awbb_GridCorr_B_Out[1][5]*/
+ 0x0F120000, /*awbb_GridCorr_B_Out[2][0]*/
+ 0x0F12FFDE, /*awbb_GridCorr_B_Out[2][1]*/
+ 0x0F120000, /*awbb_GridCorr_B_Out[2][2]*/
+ 0x0F120000, /*awbb_GridCorr_B_Out[2][3]*/
+ 0x0F120000, /*awbb_GridCorr_B_Out[2][4]*/
+ 0x0F120000, /*awbb_GridCorr_B_Out[2][5]*/
+ 0x002A05D2,
+ 0x0F1200E4, /*SARR_AwbCcmCord[0]*/
+ 0x0F1200F0, /*SARR_AwbCcmCord[1]*/
+ 0x0F120100, /*SARR_AwbCcmCord[2]*/
+ 0x0F120120, /*SARR_AwbCcmCord[3]*/
+ 0x0F120150, /*SARR_AwbCcmCord[4]*/
+ 0x0F120180, /*SARR_AwbCcmCord[5]*/
+ 0x002A05C4,
+ 0x0F123800, /*TVAR_wbt_pBaseCcms*/
+ 0x0F127000,
+ 0x002A05CC,
+ 0x0F1238D8, /*TVAR_wbt_pOutdoorCcm*/
+ 0x0F127000,
+ 0x002A3800,
+ 0x0F1201D0, /*TVAR_wbt_pBaseCcms[0]*/
+ 0x0F12FFA1, /*TVAR_wbt_pBaseCcms[1]*/
+ 0x0F12FFFA, /*TVAR_wbt_pBaseCcms[2]*/
+ 0x0F12FF6F, /*TVAR_wbt_pBaseCcms[3]*/
+ 0x0F120140, /*TVAR_wbt_pBaseCcms[4]*/
+ 0x0F12FF49, /*TVAR_wbt_pBaseCcms[5]*/
+ 0x0F12FFC1, /*TVAR_wbt_pBaseCcms[6]*/
+ 0x0F12001F, /*TVAR_wbt_pBaseCcms[7]*/
+ 0x0F1201BD, /*TVAR_wbt_pBaseCcms[8]*/
+ 0x0F12013F, /*TVAR_wbt_pBaseCcms[9]*/
+ 0x0F1200E1, /*TVAR_wbt_pBaseCcms[10]*/
+ 0x0F12FF43, /*TVAR_wbt_pBaseCcms[11]*/
+ 0x0F120191, /*TVAR_wbt_pBaseCcms[12]*/
+ 0x0F12FFC0, /*TVAR_wbt_pBaseCcms[13]*/
+ 0x0F1201B7, /*TVAR_wbt_pBaseCcms[14]*/
+ 0x0F12FF30, /*TVAR_wbt_pBaseCcms[15]*/
+ 0x0F12015F, /*TVAR_wbt_pBaseCcms[16]*/
+ 0x0F120106, /*TVAR_wbt_pBaseCcms[17]*/
+ 0x0F1201D0, /*TVAR_wbt_pBaseCcms[18]*/
+ 0x0F12FFA1, /*TVAR_wbt_pBaseCcms[19]*/
+ 0x0F12FFFA, /*TVAR_wbt_pBaseCcms[20]*/
+ 0x0F12FF6F, /*TVAR_wbt_pBaseCcms[21]*/
+ 0x0F120140, /*TVAR_wbt_pBaseCcms[22]*/
+ 0x0F12FF49, /*TVAR_wbt_pBaseCcms[23]*/
+ 0x0F12FFC1, /*TVAR_wbt_pBaseCcms[24]*/
+ 0x0F12001F, /*TVAR_wbt_pBaseCcms[25]*/
+ 0x0F1201BD, /*TVAR_wbt_pBaseCcms[26]*/
+ 0x0F12013F, /*TVAR_wbt_pBaseCcms[27]*/
+ 0x0F1200E1, /*TVAR_wbt_pBaseCcms[28]*/
+ 0x0F12FF43, /*TVAR_wbt_pBaseCcms[29]*/
+ 0x0F120191, /*TVAR_wbt_pBaseCcms[30]*/
+ 0x0F12FFC0, /*TVAR_wbt_pBaseCcms[31]*/
+ 0x0F1201B7, /*TVAR_wbt_pBaseCcms[32]*/
+ 0x0F12FF30, /*TVAR_wbt_pBaseCcms[33]*/
+ 0x0F12015F, /*TVAR_wbt_pBaseCcms[34]*/
+ 0x0F120106, /*TVAR_wbt_pBaseCcms[35]*/
+ 0x0F1201C4, /*01D3 01D0 TVAR_wbt_pBaseCcms[36]*/
+ 0x0F12FFAC, /*FFBB FFA1 TVAR_wbt_pBaseCcms[37]*/
+ 0x0F12FFFB, /*FFDD FFFA TVAR_wbt_pBaseCcms[38]*/
+ 0x0F12FF6F, /*FF6F FF6F TVAR_wbt_pBaseCcms[39]*/
+ 0x0F120140, /*0140 0140 TVAR_wbt_pBaseCcms[40]*/
+ 0x0F12FF49, /*FF49 FF49 TVAR_wbt_pBaseCcms[41]*/
+ 0x0F12FFC1, /*FFC1 FFC1 TVAR_wbt_pBaseCcms[42]*/
+ 0x0F12001F, /*001F 001F TVAR_wbt_pBaseCcms[43]*/
+ 0x0F1201BD, /*01BD 01BD TVAR_wbt_pBaseCcms[44]*/
+ 0x0F12013F, /*013F 013F TVAR_wbt_pBaseCcms[45]*/
+ 0x0F1200E1, /*00E1 00E1 TVAR_wbt_pBaseCcms[46]*/
+ 0x0F12FF43, /*FF43 FF43 TVAR_wbt_pBaseCcms[47]*/
+ 0x0F120191, /*0191 0191 TVAR_wbt_pBaseCcms[48]*/
+ 0x0F12FFC0, /*FFC0 FFC0 TVAR_wbt_pBaseCcms[49]*/
+ 0x0F1201B7, /*01B7 01B7 TVAR_wbt_pBaseCcms[50]*/
+ 0x0F12FF30, /*FF30 FF30 TVAR_wbt_pBaseCcms[51]*/
+ 0x0F12015F, /*015F 015F TVAR_wbt_pBaseCcms[52]*/
+ 0x0F120106, /*0106 0106 TVAR_wbt_pBaseCcms[53]*/
+ 0x0F1201B5, /*01C6, 01D0 TVAR_wbt_pBaseCcms[54]*/
+ 0x0F12FFC6, /*FFBE, FFA1 TVAR_wbt_pBaseCcms[55]*/
+ 0x0F12FFEF, /*FFE6, FFFA TVAR_wbt_pBaseCcms[56]*/
+ 0x0F12FF6F, /*FF6F, FF6F TVAR_wbt_pBaseCcms[57]*/
+ 0x0F120140, /*0140, 0140 TVAR_wbt_pBaseCcms[58]*/
+ 0x0F12FF49, /*FF49, FF49 TVAR_wbt_pBaseCcms[59]*/
+ 0x0F12FFC1, /*FFC1, FFC1 TVAR_wbt_pBaseCcms[60]*/
+ 0x0F12001F, /*001F, 001F TVAR_wbt_pBaseCcms[61]*/
+ 0x0F1201BD, /*01BD, 01BD TVAR_wbt_pBaseCcms[62]*/
+ 0x0F12013F, /*013F, 013F TVAR_wbt_pBaseCcms[63]*/
+ 0x0F1200E1, /*00E1, 00E1 TVAR_wbt_pBaseCcms[64]*/
+ 0x0F12FF43, /*FF43, FF43 TVAR_wbt_pBaseCcms[65]*/
+ 0x0F120191, /*0191, 0191 TVAR_wbt_pBaseCcms[66]*/
+ 0x0F12FFC0, /*FFC0, FFC0 TVAR_wbt_pBaseCcms[67]*/
+ 0x0F1201B7, /*01B7, 01B7 TVAR_wbt_pBaseCcms[68]*/
+ 0x0F12FF30, /*FF30, FF30 TVAR_wbt_pBaseCcms[69]*/
+ 0x0F12015F, /*015F, 015F TVAR_wbt_pBaseCcms[70]*/
+ 0x0F120106, /*0106, 0106 TVAR_wbt_pBaseCcms[71]*/
+ 0x0F1201B7, /*C8 01BF TVAR_wbt_pBaseCcms[72]*/
+ 0x0F12FFC4, /*FFBA FFBF TVAR_wbt_pBaseCcms[73]*/
+ 0x0F120001, /*FFE8 FFFE TVAR_wbt_pBaseCcms[74]*/
+ 0x0F12FF6D, /*FF6D FF6F FF6D TVAR_wbt_pBaseCcms[75]*/
+ 0x0F1201B4, /*01B4 0140 01B4 TVAR_wbt_pBaseCcms[76]*/
+ 0x0F12FF66, /*FF66 FF49 FF66 TVAR_wbt_pBaseCcms[77]*/
+ 0x0F12FFCA, /*FFCA FFC1 FFCA TVAR_wbt_pBaseCcms[78]*/
+ 0x0F12FFCE, /*FFCE 001F FFCE TVAR_wbt_pBaseCcms[79]*/
+ 0x0F12017B, /*017B 01BD 017B TVAR_wbt_pBaseCcms[80]*/
+ 0x0F120136, /*0136 013F 0136 TVAR_wbt_pBaseCcms[81]*/
+ 0x0F120132, /*0132 00E1 0132 TVAR_wbt_pBaseCcms[82]*/
+ 0x0F12FF85, /*FF85 FF43 FF85 TVAR_wbt_pBaseCcms[83]*/
+ 0x0F12018B, /*018B 0191 018B TVAR_wbt_pBaseCcms[84]*/
+ 0x0F12FF73, /*FF73 FFC0 FF73 TVAR_wbt_pBaseCcms[85]*/
+ 0x0F120191, /*0191 01B7 0191 TVAR_wbt_pBaseCcms[86]*/
+ 0x0F12FF3F, /*FF3F FF30 FF3F TVAR_wbt_pBaseCcms[87]*/
+ 0x0F12015B, /*015B 015F 015B TVAR_wbt_pBaseCcms[88]*/
+ 0x0F1200D0, /*00D0 0106 00D0 TVAR_wbt_pBaseCcms[89]*/
+ 0x0F1201CA, /*01CA 01C1 TVAR_wbt_pBaseCcms[90]*/
+ 0x0F12FFBE, /*FFBE FFC5 TVAR_wbt_pBaseCcms[91]*/
+ 0x0F12FFF1, /*FFF1 FFF5 TVAR_wbt_pBaseCcms[92]*/
+ 0x0F12FEFB, /*FF15 FF3B TVAR_wbt_pBaseCcms[93]*/
+ 0x0F12021C, /*01F3 0217 TVAR_wbt_pBaseCcms[94]*/
+ 0x0F12FF6B, /*FF7B FF32 TVAR_wbt_pBaseCcms[95]*/
+ 0x0F12FFC1, /*FFC1 FFC1 TVAR_wbt_pBaseCcms[96]*/
+ 0x0F12FFC5, /*FFC5 FFC5 TVAR_wbt_pBaseCcms[97]*/
+ 0x0F12018A, /*018A 018B TVAR_wbt_pBaseCcms[98]*/
+ 0x0F1200FB, /*00FB 0136 TVAR_wbt_pBaseCcms[99]*/
+ 0x0F120167, /*0167 0132 TVAR_wbt_pBaseCcms[100]*/
+ 0x0F12FF8C, /*FF8C FF85 TVAR_wbt_pBaseCcms[101]*/
+ 0x0F12018B, /*018B 018B TVAR_wbt_pBaseCcms[102]*/
+ 0x0F12FF73, /*FF73 FF73 TVAR_wbt_pBaseCcms[103]*/
+ 0x0F120191, /*0191 0191 TVAR_wbt_pBaseCcms[104]*/
+ 0x0F12FF3F, /*FF3F FF3F TVAR_wbt_pBaseCcms[105]*/
+ 0x0F12015B, /*015B 015B TVAR_wbt_pBaseCcms[106]*/
+ 0x0F1200D0, /*00D0 00D0 TVAR_wbt_pBaseCcms[107]*/
+ 0x002A38D8,
+ 0x0F120221, /*022C 0235 TVAR_wbt_pOutdoorCcm[0]*/
+ 0x0F120005, /*FFD8 FFEF TVAR_wbt_pOutdoorCcm[1]*/
+ 0x0F120012, /*0034 0014 TVAR_wbt_pOutdoorCcm[2]*/
+ 0x0F12FF67, /*FF67 FF67 TVAR_wbt_pOutdoorCcm[3]*/
+ 0x0F12027D, /*027D 027D TVAR_wbt_pOutdoorCcm[4]*/
+ 0x0F12FFBA, /*FFBA FFBA TVAR_wbt_pOutdoorCcm[5]*/
+ 0x0F12000D, /*000D 000D TVAR_wbt_pOutdoorCcm[6]*/
+ 0x0F120062, /*0062 0062 TVAR_wbt_pOutdoorCcm[7]*/
+ 0x0F1202A7, /*02A7 02A7 TVAR_wbt_pOutdoorCcm[8]*/
+ 0x0F1200C7, /*00C7 00C9 TVAR_wbt_pOutdoorCcm[9]*/
+ 0x0F12011F, /*011F 0123 TVAR_wbt_pOutdoorCcm[10]*/
+ 0x0F12FF3C, /*FF3C FF36 TVAR_wbt_pOutdoorCcm[11]*/
+ 0x0F1201AD, /*01AD 01AD TVAR_wbt_pOutdoorCcm[12]*/
+ 0x0F12FFC8, /*FFC8 FFC8 TVAR_wbt_pOutdoorCcm[13]*/
+ 0x0F120202, /*0202 0202 TVAR_wbt_pOutdoorCcm[14]*/
+ 0x0F12FFCF, /*FFCF FFCF TVAR_wbt_pOutdoorCcm[15]*/
+ 0x0F120257, /*0257 0257 TVAR_wbt_pOutdoorCcm[16]*/
+ 0x0F12022C, /*022C 022C TVAR_wbt_pOutdoorCcm[17]*/
+ 0x002A23DC,
+ 0x0F1201DD, /*Mon_AAIO_PrevFrmData_NormBr*/
+ 0x002A0460,
+ 0x0F120000, /*0000 0000 saRR_usDualGammaLutRGBIndoor[0][0]*/
+ 0x0F120004, /*0008 0002 saRR_usDualGammaLutRGBIndoor[0][1]*/
+ 0x0F12000C, /*0013 0006 saRR_usDualGammaLutRGBIndoor[0][2]*/
+ 0x0F120024, /*002C 0011 saRR_usDualGammaLutRGBIndoor[0][3]*/
+ 0x0F12006E, /*0061 0036 saRR_usDualGammaLutRGBIndoor[0][4]*/
+ 0x0F1200D1, /*00C8 009A saRR_usDualGammaLutRGBIndoor[0][5]*/
+ 0x0F120119, /*0113 00FD saRR_usDualGammaLutRGBIndoor[0][6]*/
+ 0x0F120139, /*0132 0129 saRR_usDualGammaLutRGBIndoor[0][7]*/
+ 0x0F120157, /*014C 014B saRR_usDualGammaLutRGBIndoor[0][8]*/
+ 0x0F12018E, /*0179 0184 saRR_usDualGammaLutRGBIndoor[0][9]*/
+ 0x0F1201C3, /*01A4 01B8 saRR_usDualGammaLutRGBIndoor[0][10]*/
+ 0x0F1201F3, /*01CD 01EA saRR_usDualGammaLutRGBIndoor[0][11]*/
+ 0x0F12021F, /*01F4 0216 saRR_usDualGammaLutRGBIndoor[0][12]*/
+ 0x0F120269, /*0239 025E saRR_usDualGammaLutRGBIndoor[0][13]*/
+ 0x0F1202A6, /*0278 0299 saRR_usDualGammaLutRGBIndoor[0][14]*/
+ 0x0F1202FF, /*02E0 02F9 saRR_usDualGammaLutRGBIndoor[0][15]*/
+ 0x0F120351, /*0333 0341 saRR_usDualGammaLutRGBIndoor[0][16]*/
+ 0x0F120395, /*037B 037F saRR_usDualGammaLutRGBIndoor[0][17]*/
+ 0x0F1203CE, /*03BF 03BF saRR_usDualGammaLutRGBIndoor[0][18]*/
+ 0x0F1203FF, /*03FF 03FF saRR_usDualGammaLutRGBIndoor[0][19]*/
+ 0x0F120000, /*0000 0000 saRR_usDualGammaLutRGBIndoor[1][0]*/
+ 0x0F120004, /*0008 0002 saRR_usDualGammaLutRGBIndoor[1][1]*/
+ 0x0F12000C, /*0013 0006 saRR_usDualGammaLutRGBIndoor[1][2]*/
+ 0x0F120024, /*002C 0011 saRR_usDualGammaLutRGBIndoor[1][3]*/
+ 0x0F12006E, /*0061 0036 saRR_usDualGammaLutRGBIndoor[1][4]*/
+ 0x0F1200D1, /*00C8 009A saRR_usDualGammaLutRGBIndoor[1][5]*/
+ 0x0F120119, /*0113 00FD saRR_usDualGammaLutRGBIndoor[1][6]*/
+ 0x0F120139, /*0132 0129 saRR_usDualGammaLutRGBIndoor[1][7]*/
+ 0x0F120157, /*014C 014B saRR_usDualGammaLutRGBIndoor[1][8]*/
+ 0x0F12018E, /*0179 0184 saRR_usDualGammaLutRGBIndoor[1][9]*/
+ 0x0F1201C3, /*01A4 01B8 saRR_usDualGammaLutRGBIndoor[1][10]*/
+ 0x0F1201F3, /*01CD 01EA saRR_usDualGammaLutRGBIndoor[1][11]*/
+ 0x0F12021F, /*01F4 0216 saRR_usDualGammaLutRGBIndoor[1][12]*/
+ 0x0F120269, /*0239 025E saRR_usDualGammaLutRGBIndoor[1][13]*/
+ 0x0F1202A6, /*0278 0299 saRR_usDualGammaLutRGBIndoor[1][14]*/
+ 0x0F1202FF, /*02E0 02F9 saRR_usDualGammaLutRGBIndoor[1][15]*/
+ 0x0F120351, /*0333 0341 saRR_usDualGammaLutRGBIndoor[1][16]*/
+ 0x0F120395, /*037B 037F saRR_usDualGammaLutRGBIndoor[1][17]*/
+ 0x0F1203CE, /*03BF 03BF saRR_usDualGammaLutRGBIndoor[1][18]*/
+ 0x0F1203FF, /*03FF 03FF saRR_usDualGammaLutRGBIndoor[1][19]*/
+ 0x0F120000, /*0000 0000 saRR_usDualGammaLutRGBIndoor[2][0]*/
+ 0x0F120004, /*0008 0002 saRR_usDualGammaLutRGBIndoor[2][1]*/
+ 0x0F12000C, /*0013 0006 saRR_usDualGammaLutRGBIndoor[2][2]*/
+ 0x0F120024, /*002C 0011 saRR_usDualGammaLutRGBIndoor[2][3]*/
+ 0x0F12006E, /*0061 0036 saRR_usDualGammaLutRGBIndoor[2][4]*/
+ 0x0F1200D1, /*00C8 009A saRR_usDualGammaLutRGBIndoor[2][5]*/
+ 0x0F120119, /*0113 00FD saRR_usDualGammaLutRGBIndoor[2][6]*/
+ 0x0F120139, /*0132 0129 saRR_usDualGammaLutRGBIndoor[2][7]*/
+ 0x0F120157, /*014C 014B saRR_usDualGammaLutRGBIndoor[2][8]*/
+ 0x0F12018E, /*0179 0184 saRR_usDualGammaLutRGBIndoor[2][9]*/
+ 0x0F1201C3, /*01A4 01B8 saRR_usDualGammaLutRGBIndoor[2][10]*/
+ 0x0F1201F3, /*01CD 01EA saRR_usDualGammaLutRGBIndoor[2][11]*/
+ 0x0F12021F, /*01F4 0216 saRR_usDualGammaLutRGBIndoor[2][12]*/
+ 0x0F120269, /*0239 025E saRR_usDualGammaLutRGBIndoor[2][13]*/
+ 0x0F1202A6, /*0278 0299 saRR_usDualGammaLutRGBIndoor[2][14]*/
+ 0x0F1202FF, /*02E0 02F9 saRR_usDualGammaLutRGBIndoor[2][15]*/
+ 0x0F120351, /*0333 0341 saRR_usDualGammaLutRGBIndoor[2][16]*/
+ 0x0F120395, /*037B 037F saRR_usDualGammaLutRGBIndoor[2][17]*/
+ 0x0F1203CE, /*03BF 03BF saRR_usDualGammaLutRGBIndoor[2][18]*/
+ 0x0F1203FF, /*03FF 03FF saRR_usDualGammaLutRGBIndoor[2][19]*/
+ 0x0F120000, /*0000 0000 saRR_usDualGammaLutRGBOutdoor[0][0]*/
+ 0x0F120004, /*0008 0002 saRR_usDualGammaLutRGBOutdoor[0][1]*/
+ 0x0F12000C, /*0013 0006 saRR_usDualGammaLutRGBOutdoor[0][2]*/
+ 0x0F120024, /*002C 0011 saRR_usDualGammaLutRGBOutdoor[0][3]*/
+ 0x0F12006E, /*0061 0036 saRR_usDualGammaLutRGBOutdoor[0][4]*/
+ 0x0F1200D1, /*00C8 009A saRR_usDualGammaLutRGBOutdoor[0][5]*/
+ 0x0F120119, /*0113 00FD saRR_usDualGammaLutRGBOutdoor[0][6]*/
+ 0x0F120139, /*0132 0129 saRR_usDualGammaLutRGBOutdoor[0][7]*/
+ 0x0F120157, /*014C 014B saRR_usDualGammaLutRGBOutdoor[0][8]*/
+ 0x0F12018E, /*0179 0184 saRR_usDualGammaLutRGBOutdoor[0][9]*/
+ 0x0F1201C3, /*01A4 01B8 saRR_usDualGammaLutRGBOutdoor[0][10]*/
+ 0x0F1201F3, /*01CD 01EA saRR_usDualGammaLutRGBOutdoor[0][11]*/
+ 0x0F12021F, /*01F4 0216 saRR_usDualGammaLutRGBOutdoor[0][12]*/
+ 0x0F120269, /*0239 025E saRR_usDualGammaLutRGBOutdoor[0][13]*/
+ 0x0F1202A6, /*0278 0299 saRR_usDualGammaLutRGBOutdoor[0][14]*/
+ 0x0F1202FF, /*02E0 02F9 saRR_usDualGammaLutRGBOutdoor[0][15]*/
+ 0x0F120351, /*0333 0341 saRR_usDualGammaLutRGBOutdoor[0][16]*/
+ 0x0F120395, /*037B 037F saRR_usDualGammaLutRGBOutdoor[0][17]*/
+ 0x0F1203CE, /*03BF 03BF saRR_usDualGammaLutRGBOutdoor[0][18]*/
+ 0x0F1203FF, /*03FF 03FF saRR_usDualGammaLutRGBOutdoor[0][19]*/
+ 0x0F120000, /*0000 0000 saRR_usDualGammaLutRGBOutdoor[1][0]*/
+ 0x0F120004, /*0008 0002 saRR_usDualGammaLutRGBOutdoor[1][1]*/
+ 0x0F12000C, /*0013 0006 saRR_usDualGammaLutRGBOutdoor[1][2]*/
+ 0x0F120024, /*002C 0011 saRR_usDualGammaLutRGBOutdoor[1][3]*/
+ 0x0F12006E, /*0061 0036 saRR_usDualGammaLutRGBOutdoor[1][4]*/
+ 0x0F1200D1, /*00C8 009A saRR_usDualGammaLutRGBOutdoor[1][5]*/
+ 0x0F120119, /*0113 00FD saRR_usDualGammaLutRGBOutdoor[1][6]*/
+ 0x0F120139, /*0132 0129 saRR_usDualGammaLutRGBOutdoor[1][7]*/
+ 0x0F120157, /*014C 014B saRR_usDualGammaLutRGBOutdoor[1][8]*/
+ 0x0F12018E, /*0179 0184 saRR_usDualGammaLutRGBOutdoor[1][9]*/
+ 0x0F1201C3, /*01A4 01B8 saRR_usDualGammaLutRGBOutdoor[1][10]*/
+ 0x0F1201F3, /*01CD 01EA saRR_usDualGammaLutRGBOutdoor[1][11]*/
+ 0x0F12021F, /*01F4 0216 saRR_usDualGammaLutRGBOutdoor[1][12]*/
+ 0x0F120269, /*0239 025E saRR_usDualGammaLutRGBOutdoor[1][13]*/
+ 0x0F1202A6, /*0278 0299 saRR_usDualGammaLutRGBOutdoor[1][14]*/
+ 0x0F1202FF, /*02E0 02F9 saRR_usDualGammaLutRGBOutdoor[1][15]*/
+ 0x0F120351, /*0333 0341 saRR_usDualGammaLutRGBOutdoor[1][16]*/
+ 0x0F120395, /*037B 037F saRR_usDualGammaLutRGBOutdoor[1][17]*/
+ 0x0F1203CE, /*03BF 03BF saRR_usDualGammaLutRGBOutdoor[1][18]*/
+ 0x0F1203FF, /*03FF 03FF saRR_usDualGammaLutRGBOutdoor[1][19]*/
+ 0x0F120000, /*0000 0000 saRR_usDualGammaLutRGBOutdoor[2][0]*/
+ 0x0F120004, /*0008 0002 saRR_usDualGammaLutRGBOutdoor[2][1]*/
+ 0x0F12000C, /*0013 0006 saRR_usDualGammaLutRGBOutdoor[2][2]*/
+ 0x0F120024, /*002C 0011 saRR_usDualGammaLutRGBOutdoor[2][3]*/
+ 0x0F12006E, /*0061 0036 saRR_usDualGammaLutRGBOutdoor[2][4]*/
+ 0x0F1200D1, /*00C8 009A saRR_usDualGammaLutRGBOutdoor[2][5]*/
+ 0x0F120119, /*0113 00FD saRR_usDualGammaLutRGBOutdoor[2][6]*/
+ 0x0F120139, /*0132 0129 saRR_usDualGammaLutRGBOutdoor[2][7]*/
+ 0x0F120157, /*014C 014B saRR_usDualGammaLutRGBOutdoor[2][8]*/
+ 0x0F12018E, /*0179 0184 saRR_usDualGammaLutRGBOutdoor[2][9]*/
+ 0x0F1201C3, /*01A4 01B8 saRR_usDualGammaLutRGBOutdoor[2][10]*/
+ 0x0F1201F3, /*01CD 01EA saRR_usDualGammaLutRGBOutdoor[2][11]*/
+ 0x0F12021F, /*01F4 0216 saRR_usDualGammaLutRGBOutdoor[2][12]*/
+ 0x0F120269, /*0239 025E saRR_usDualGammaLutRGBOutdoor[2][13]*/
+ 0x0F1202A6, /*0278 0299 saRR_usDualGammaLutRGBOutdoor[2][14]*/
+ 0x0F1202FF, /*02E0 02F9 saRR_usDualGammaLutRGBOutdoor[2][15]*/
+ 0x0F120351, /*0333 0341 saRR_usDualGammaLutRGBOutdoor[2][16]*/
+ 0x0F120395, /*037B 037F saRR_usDualGammaLutRGBOutdoor[2][17]*/
+ 0x0F1203CE, /*03BF 03BF saRR_usDualGammaLutRGBOutdoor[2][18]*/
+ 0x0F1203FF, /*03FF 03FF saRR_usDualGammaLutRGBOutdoor[2][19]*/
+ 0x002A065C,
+ 0x0F12003F, /*afit_uNoiseIndInDoor_0_*/
+ 0x0F120041, /*afit_uNoiseIndInDoor_1_*/
+ 0x0F1200CB, /*afit_uNoiseIndInDoor_2_*/
+ 0x0F1201E0, /*afit_uNoiseIndInDoor_3_*/
+ 0x0F120220, /*afit_uNoiseIndInDoor_4_*/
+ 0x002A3780,
+ 0x0F120000, /*on/off AFIT by NB option*/
+ 0x0F120014, /*SARR_uNormBrInDoor*/
+ 0x0F1200D2, /*SARR_uNormBrInDoor*/
+ 0x0F120384, /*SARR_uNormBrInDoor*/
+ 0x0F1207D0, /*SARR_uNormBrInDoor*/
+ 0x0F121388, /*SARR_uNormBrInDoor*/
+ 0x002A06BC,
+ 0x0F120000, /*AFIT16_BRIGHTNESS*/
+ 0x0F120000, /*AFIT16_CONTRAST*/
+ 0x0F120014, /*AFIT16_SATURATION*/
+ 0x0F120000, /*AFIT16_SHARP_BLUR*/
+ 0x0F120000, /*AFIT16_GLAMOUR*/
+ 0x0F1200C1, /*AFIT16_sddd8a_edge_high*/
+ 0x0F1203FF, /*AFIT16_Demosaicing_isatVal*/
+ 0x0F12009C, /*AFIT16_Sharpening_iReduceEdgeThresh*/
+ 0x0F12017C, /*AFIT16_demsharpmix1_iRGBOffset*/
+ 0x0F1203FF, /*AFIT16_demsharpmix1_iDemClamp*/
+ 0x0F12000C, /*AFIT16_demsharpmix1_iLowThreshold*/
+ 0x0F120010, /*AFIT16_demsharpmix1_iHighThreshold*/
+ 0x0F12012C, /*AFIT16_demsharpmix1_iLowBright*/
+ 0x0F1203E8, /*AFIT16_demsharpmix1_iHighBright*/
+ 0x0F120046, /*AFIT16_demsharpmix1_iLowsat*/
+ 0x0F12005A, /*AFIT16_demsharpmix1_iHighsat*/
+ 0x0F120070, /*AFIT16_demsharpmix1_iTune*/
+ 0x0F12001E, /*AFIT16_demsharpmix1_iHystThLow*/
+ 0x0F12001E, /*AFIT16_demsharpmix1_iHystThHigh*/
+ 0x0F1201F4, /*AFIT16_demsharpmix1_iHystCenter*/
+ 0x0F120046, /*AFIT16_YUV422_DENOIsE_iUVLowThresh*/
+ 0x0F120046, /*AFIT16_YUV422_DENOIsE_iUVHighThresh*/
+ 0x0F120005, /*AFIT16_YUV422_DENOIsE_iYLowThresh*/
+ 0x0F120005, /*AFIT16_YUV422_DENOIsE_iYHighThresh*/
+ 0x0F12003C, /*AFIT16_sharpening_iLowsharpClamp*/
+ 0x0F120014, /*AFIT16_sharpening_iHighsharpClamp*/
+ 0x0F12003C, /*AFIT16_sharpening_iLowsharpClamp_Bin*/
+ 0x0F120014, /*AFIT16_sharpening_iHighsharpClamp_Bin*/
+ 0x0F12003C, /*AFIT16_sharpening_iLowsharpClamp_sBin*/
+ 0x0F12001E, /*AFIT16_sharpening_iHighsharpClamp_sBin*/
+ 0x0F120A24, /*AFIT8_sddd8a_edge_low [7:0],
+ AFIT8_sddd8a_repl_thresh [15:8]*/
+ 0x0F121701, /*AFIT8_sddd8a_repl_force [7:0],
+ AFIT8_sddd8a_sat_level [15:8]*/
+ 0x0F120229, /*AFIT8_sddd8a_sat_thr[7:0],
+ AFIT8_sddd8a_sat_mpl [15:8]*/
+ 0x0F121403, /*AFIT8_sddd8a_sat_noise[7:0],
+ AFIT8_sddd8a_iMaxslopeAllowed [15:8]*/
+ 0x0F120000, /*AFIT8_sddd8a_iHotThreshHigh[7:0],
+ AFIT8_sddd8a_iHotThreshLow [15:8]*/
+ 0x0F120000, /*AFIT8_sddd8a_iColdThreshHigh[7:0],
+ AFIT8_sddd8a_iColdThreshLow [15:8]*/
+ 0x0F120000, /*AFIT8_sddd8a_AddNoisePower1[7:0],
+ AFIT8_sddd8a_AddNoisePower2 [15:8]*/
+ 0x0F1200FF, /*AFIT8_sddd8a_isatsat[7:0],
+ AFIT8_sddd8a_iRadialTune [15:8]*/
+ 0x0F120A3B, /*AFIT8_sddd8a_iRadialLimit [7:0],
+ AFIT8_sddd8a_iRadialPower [15:8]*/
+ 0x0F121414, /*AFIT8_sddd8a_iLowMaxslopeAllowed [7:0],
+ AFIT8_sddd8a_iHighMaxslopeAllowed [15:8]*/
+ 0x0F120301, /*AFIT8_sddd8a_iLowslopeThresh[7:0],
+ AFIT8_sddd8a_iHighslopeThresh [15:8]*/
+ 0x0F12FF07, /*AFIT8_sddd8a_isquaresRounding [7:0],
+ AFIT8_Demosaicing_iCentGrad [15:8]*/
+ 0x0F12081E, /*AFIT8_Demosaicing_iMonochrom [7:0],
+ AFIT8_Demosaicing_iDecisionThresh [15:8]*/
+ 0x0F120A1E, /*AFIT8_Demosaicing_iDesatThresh [7:0],
+ AFIT8_Demosaicing_iEnhThresh [15:8]*/
+ 0x0F120F0F, /*AFIT8_Demosaicing_iGRDenoiseVal [7:0],
+ AFIT8_Demosaicing_iGBDenoiseVal [15:8]*/
+ 0x0F120A00, /*AFIT8_Demosaicing_iNearGrayDesat[7:0],
+ AFIT8_Demosaicing_iDFD_ReduceCoeff [15:8]*/
+ 0x0F120012, /*AFIT8_sharpening_iMsharpen [7:0],
+ AFIT8_sharpening_iMshThresh [15:8]*/
+ 0x0F12001E, /*AFIT8_sharpening_iWsharpen [7:0],
+ AFIT8_sharpening_iWshThresh [15:8]*/
+ 0x0F120002, /*AFIT8_sharpening_nsharpWidth [7:0],
+ AFIT8_sharpening_iReduceNegative [15:8]*/
+ 0x0F1200FF, /*AFIT8_sharpening_ishDespeckle [7:0],
+ AFIT8_demsharpmix1_iRGBMultiplier [15:8]*/
+ 0x0F121102, /*AFIT8_demsharpmix1_iFilterPower [7:0],
+ AFIT8_demsharpmix1_iBCoeff [15:8]*/
+ 0x0F12001B, /*AFIT8_demsharpmix1_iGCoeff [7:0],
+ AFIT8_demsharpmix1_iWideMult [15:8]*/
+ 0x0F120900, /*AFIT8_demsharpmix1_iNarrMult [7:0],
+ AFIT8_demsharpmix1_iHystFalloff [15:8]*/
+ 0x0F120600, /*AFIT8_demsharpmix1_iHystMinMult [7:0],
+ AFIT8_demsharpmix1_iHystWidth [15:8]*/
+ 0x0F120504, /*AFIT8_demsharpmix1_iHystFallLow [7:0],
+ AFIT8_demsharpmix1_iHystFallHigh [15:8]*/
+ 0x0F120306, /*AFIT8_demsharpmix1_iHystTune [7:0],
+ * AFIT8_YUV422_DENOIsE_iUVsupport [15:8]*/
+ 0x0F128003, /*AFIT8_YUV422_DENOIsE_iYsupport [7:0],
+ AFIT8_byr_cgras_ishadingPower [15:8]*/
+ 0x0F121982, /*AFIT8_RGBGamma2_iLinearity [7:0],
+ AFIT8_RGBGamma2_iDarkReduce [15:8]*/
+ 0x0F120B80, /*0A80 AFIT8_ccm_oscar_isaturation[7:0],
+ AFIT8_RGB2YUV_iYOffset [15:8]*/
+ 0x0F120080, /*AFIT8_RGB2YUV_iRGBGain [7:0],
+ AFIT8_RGB2YUV_isaturation [15:8]*/
+ 0x0F121414, /*AFIT8_sddd8a_iClustThresh_H [7:0],
+ AFIT8_sddd8a_iClustThresh_C [15:8]*/
+ 0x0F120101, /*AFIT8_sddd8a_iClustMulT_H [7:0],
+ AFIT8_sddd8a_iClustMulT_C [15:8]*/
+ 0x0F124601, /*AFIT8_sddd8a_nClustLevel_H [7:0],
+ AFIT8_sddd8a_DispTH_Low [15:8]*/
+ 0x0F126444, /*AFIT8_sddd8a_DispTH_High [7:0],
+ AFIT8_sddd8a_iDenThreshLow [15:8]*/
+ 0x0F129650, /*AFIT8_sddd8a_iDenThreshHigh[7:0],
+ AFIT8_Demosaicing_iEdgeDesat [15:8]*/
+ 0x0F120000, /*AFIT8_Demosaicing_iEdgeDesatThrLow [7:0],
+ AFIT8_Demosaicing_iEdgeDesatThrHigh [15:8]*/
+ 0x0F120003, /*AFIT8_Demosaicing_iEdgeDesatLimit[7:0],
+ AFIT8_Demosaicing_iDemsharpenLow [15:8]*/
+ 0x0F121E00, /*AFIT8_Demosaicing_iDemsharpenHigh[7:0],
+ AFIT8_Demosaicing_iDemsharpThresh [15:8]*/
+ 0x0F120714, /*AFIT8_Demosaicing_iDemshLowLimit [7:0],
+ AFIT8_Demosaicing_iDespeckleForDemsharp [15:8]*/
+ 0x0F121464, /*AFIT8_Demosaicing_iDemBlurLow[7:0],
+ AFIT8_Demosaicing_iDemBlurHigh [15:8]*/
+ 0x0F121404, /*AFIT8_Demosaicing_iDemBlurRange[7:0],
+ AFIT8_sharpening_iLowsharpPower [15:8]*/
+ 0x0F120F14, /*AFIT8_sharpening_iHighsharpPower[7:0],
+ AFIT8_sharpening_iLowshDenoise [15:8]*/
+ 0x0F12400F, /*AFIT8_sharpening_iHighshDenoise [7:0],
+ AFIT8_sharpening_iReduceEdgeMinMult [15:8]*/
+ 0x0F120204, /*AFIT8_sharpening_iReduceEdgeslope [7:0],
+ AFIT8_demsharpmix1_iWideFiltReduce [15:8]*/
+ 0x0F121403, /*AFIT8_demsharpmix1_iNarrFiltReduce [7:0],
+ AFIT8_sddd8a_iClustThresh_H_Bin [15:8]*/
+ 0x0F120114, /*AFIT8_sddd8a_iClustThresh_C_Bin [7:0],
+ AFIT8_sddd8a_iClustMulT_H_Bin [15:8]*/
+ 0x0F120101, /*AFIT8_sddd8a_iClustMulT_C_Bin [7:0],
+ AFIT8_sddd8a_nClustLevel_H_Bin [15:8]*/
+ 0x0F124446, /*AFIT8_sddd8a_DispTH_Low_Bin [7:0],
+ AFIT8_sddd8a_DispTH_High_Bin [15:8]*/
+ 0x0F122832, /*5064 AFIT8_sddd8a_iDenThreshLow_Bin [7:0],
+ AFIT8_sddd8a_iDenThreshHigh_Bin [15:8]*/
+ 0x0F120028, /*AFIT8_Demosaicing_iEdgeDesat_Bin[7:0],
+ AFIT8_Demosaicing_iEdgeDesatThrLow_Bin [15:8]*/
+ 0x0F120300, /*AFIT8_Demosaicing_iEdgeDesatThrHigh_Bin [7:0],
+ AFIT8_Demosaicing_iEdgeDesatLimit_Bin [15:8]*/
+ 0x0F120000, /*AFIT8_Demosaicing_iDemsharpenLow_Bin [7:0],
+ AFIT8_Demosaicing_iDemsharpenHigh_Bin [15:8]*/
+ 0x0F12141E, /*AFIT8_Demosaicing_iDemsharpThresh_Bin [7:0],
+ AFIT8_Demosaicing_iDemshLowLimit_Bin [15:8]*/
+ 0x0F126407, /*AFIT8_Demosaicing_iDespeckleForDemsharp_Bin [7:0],
+ AFIT8_Demosaicing_iDemBlurLow_Bin [15:8]*/
+ 0x0F120414, /*AFIT8_Demosaicing_iDemBlurHigh_Bin [7:0],
+ AFIT8_Demosaicing_iDemBlurRange_Bin [15:8]*/
+ 0x0F120A0A, /*1414 AFIT8_sharpening_iLowsharpPower_Bin [7:0],
+ AFIT8_sharpening_iHighsharpPower_Bin [15:8]*/
+ 0x0F120F0F, /*AFIT8_sharpening_iLowshDenoise_Bin [7:0],
+ AFIT8_sharpening_iHighshDenoise_Bin [15:8]*/
+ 0x0F120440, /*AFIT8_sharpening_iReduceEdgeMinMult_Bin [7:0],
+ AFIT8_sharpening_iReduceEdgeslope_Bin [15:8]*/
+ 0x0F120302, /*AFIT8_demsharpmix1_iWideFiltReduce_Bin [7:0],
+ AFIT8_demsharpmix1_iNarrFiltReduce_Bin [15:8]*/
+ 0x0F121414, /*AFIT8_sddd8a_iClustThresh_H_sBin[7:0],
+ AFIT8_sddd8a_iClustThresh_C_sBin [15:8]*/
+ 0x0F120101, /*AFIT8_sddd8a_iClustMulT_H_sBin [7:0],
+ AFIT8_sddd8a_iClustMulT_C_sBin [15:8]*/
+ 0x0F124601, /*AFIT8_sddd8a_nClustLevel_H_sBin [7:0],
+ AFIT8_sddd8a_DispTH_Low_sBin [15:8]*/
+ 0x0F126E44, /*AFIT8_sddd8a_DispTH_High_sBin [7:0],
+ AFIT8_sddd8a_iDenThreshLow_sBin [15:8]*/
+ 0x0F122864, /*AFIT8_sddd8a_iDenThreshHigh_sBin[7:0],
+ AFIT8_Demosaicing_iEdgeDesat_sBin [15:8]*/
+ 0x0F120A00, /*AFIT8_Demosaicing_iEdgeDesatThrLow_sBin [7:0],
+ AFIT8_Demosaicing_iEdgeDesatThrHigh_sBin [15:8]*/
+ 0x0F120003, /*AFIT8_Demosaicing_iEdgeDesatLimit_sBin [7:0],
+ AFIT8_Demosaicing_iDemsharpenLow_sBin [15:8]*/
+ 0x0F121E00, /*AFIT8_Demosaicing_iDemsharpenHigh_sBin [7:0],
+ AFIT8_Demosaicing_iDemsharpThresh_sBin [15:8]*/
+ 0x0F120714, /*AFIT8_Demosaicing_iDemshLowLimit_sBin [7:0],
+ AFIT8_Demosaicing_iDespeckleForDemsharp_sBin [15:8]*/
+ 0x0F1232FF, /*AFIT8_Demosaicing_iDemBlurLow_sBin [7:0],
+ AFIT8_Demosaicing_iDemBlurHigh_sBin [15:8]*/
+ 0x0F120004, /*AFIT8_Demosaicing_iDemBlurRange_sBin [7:0],
+ AFIT8_sharpening_iLowsharpPower_sBin [15:8]*/
+ 0x0F120F00, /*AFIT8_sharpening_iHighsharpPower_sBin [7:0],
+ AFIT8_sharpening_iLowshDenoise_sBin [15:8]*/
+ 0x0F12400F, /*AFIT8_sharpening_iHighshDenoise_sBin [7:0],
+ AFIT8_sharpening_iReduceEdgeMinMult_sBin [15:8]*/
+ 0x0F120204, /*AFIT8_sharpening_iReduceEdgeslope_sBin [7:0],
+ AFIT8_demsharpmix1_iWideFiltReduce_sBin [15:8]*/
+ 0x0F120003, /*AFIT8_demsharpmix1_iNarrFiltReduce_sBin [7:0]*/
+ 0x0F120000, /*AFIT16_BRIGHTNEss*/
+ 0x0F120000, /*AFIT16_CONTRAsT*/
+ 0x0F120014, /*AFIT16_sATURATION*/
+ 0x0F120000, /*AFIT16_sHARP_BLUR*/
+ 0x0F120000, /*AFIT16_GLAMOUR*/
+ 0x0F1200C1, /*AFIT16_sddd8a_edge_high*/
+ 0x0F1203FF, /*AFIT16_Demosaicing_isatVal*/
+ 0x0F12009C, /*AFIT16_sharpening_iReduceEdgeThresh*/
+ 0x0F12017C, /*AFIT16_demsharpmix1_iRGBOffset*/
+ 0x0F1203FF, /*AFIT16_demsharpmix1_iDemClamp*/
+ 0x0F12000C, /*AFIT16_demsharpmix1_iLowThreshold*/
+ 0x0F120010, /*AFIT16_demsharpmix1_iHighThreshold*/
+ 0x0F12012C, /*AFIT16_demsharpmix1_iLowBright*/
+ 0x0F1203E8, /*AFIT16_demsharpmix1_iHighBright*/
+ 0x0F120046, /*AFIT16_demsharpmix1_iLowsat*/
+ 0x0F12005A, /*AFIT16_demsharpmix1_iHighsat*/
+ 0x0F120070, /*AFIT16_demsharpmix1_iTune*/
+ 0x0F120008, /*AFIT16_demsharpmix1_iHystThLow*/
+ 0x0F120000, /*AFIT16_demsharpmix1_iHystThHigh*/
+ 0x0F120320, /*AFIT16_demsharpmix1_iHystCenter*/
+ 0x0F120046, /*AFIT16_YUV422_DENOIsE_iUVLowThresh*/
+ 0x0F120046, /*AFIT16_YUV422_DENOIsE_iUVHighThresh*/
+ 0x0F120000, /*AFIT16_YUV422_DENOIsE_iYLowThresh*/
+ 0x0F120000, /*AFIT16_YUV422_DENOIsE_iYHighThresh*/
+ 0x0F120064, /*AFIT16_sharpening_iLowsharpClamp*/
+ 0x0F120014, /*AFIT16_sharpening_iHighsharpClamp*/
+ 0x0F120064, /*AFIT16_sharpening_iLowsharpClamp_Bin*/
+ 0x0F120014, /*AFIT16_sharpening_iHighsharpClamp_Bin*/
+ 0x0F12003C, /*AFIT16_sharpening_iLowsharpClamp_sBin*/
+ 0x0F12001E, /*AFIT16_sharpening_iHighsharpClamp_sBin*/
+ 0x0F120A24, /*AFIT8_sddd8a_edge_low [7:0],
+ AFIT8_sddd8a_repl_thresh [15:8]*/
+ 0x0F121701, /*AFIT8_sddd8a_repl_force [7:0],
+ AFIT8_sddd8a_sat_level [15:8]*/
+ 0x0F120229, /*AFIT8_sddd8a_sat_thr[7:0],
+ AFIT8_sddd8a_sat_mpl [15:8]*/
+ 0x0F121403, /*AFIT8_sddd8a_sat_noise[7:0],
+ AFIT8_sddd8a_iMaxslopeAllowed [15:8]*/
+ 0x0F120000, /*AFIT8_sddd8a_iHotThreshHigh[7:0],
+ AFIT8_sddd8a_iHotThreshLow [15:8]*/
+ 0x0F120000, /*AFIT8_sddd8a_iColdThreshHigh[7:0],
+ AFIT8_sddd8a_iColdThreshLow [15:8]*/
+ 0x0F120000, /*AFIT8_sddd8a_AddNoisePower1[7:0],
+ AFIT8_sddd8a_AddNoisePower2 [15:8]*/
+ 0x0F1200FF, /*AFIT8_sddd8a_isatsat[7:0],
+ AFIT8_sddd8a_iRadialTune [15:8]*/
+ 0x0F12033B, /*AFIT8_sddd8a_iRadialLimit [7:0],
+ AFIT8_sddd8a_iRadialPower [15:8]*/
+ 0x0F121414, /*AFIT8_sddd8a_iLowMaxslopeAllowed [7:0],
+ AFIT8_sddd8a_iHighMaxslopeAllowed [15:8]*/
+ 0x0F120301, /*AFIT8_sddd8a_iLowslopeThresh[7:0],
+ AFIT8_sddd8a_iHighslopeThresh [15:8]*/
+ 0x0F12FF07, /*AFIT8_sddd8a_isquaresRounding [7:0],
+ AFIT8_Demosaicing_iCentGrad [15:8]*/
+ 0x0F12081E, /*AFIT8_Demosaicing_iMonochrom [7:0],
+ AFIT8_Demosaicing_iDecisionThresh [15:8]*/
+ 0x0F120A1E, /*AFIT8_Demosaicing_iDesatThresh [7:0],
+ AFIT8_Demosaicing_iEnhThresh [15:8]*/
+ 0x0F120F0F, /*AFIT8_Demosaicing_iGRDenoiseVal [7:0],
+ AFIT8_Demosaicing_iGBDenoiseVal [15:8]*/
+ 0x0F120A00, /*AFIT8_Demosaicing_iNearGrayDesat[7:0],
+ AFIT8_Demosaicing_iDFD_ReduceCoeff [15:8]*/
+ 0x0F120012, /*AFIT8_sharpening_iMsharpen [7:0],
+ AFIT8_sharpening_iMshThresh [15:8]*/
+ 0x0F120005, /*AFIT8_sharpening_iWsharpen [7:0],
+ AFIT8_sharpening_iWshThresh [15:8]*/
+ 0x0F120002, /*AFIT8_sharpening_nsharpWidth [7:0],
+ AFIT8_sharpening_iReduceNegative [15:8]*/
+ 0x0F1200FF, /*AFIT8_sharpening_ishDespeckle [7:0],
+ AFIT8_demsharpmix1_iRGBMultiplier [15:8]*/
+ 0x0F121102, /*AFIT8_demsharpmix1_iFilterPower [7:0],
+ AFIT8_demsharpmix1_iBCoeff [15:8]*/
+ 0x0F12001B, /*AFIT8_demsharpmix1_iGCoeff [7:0],
+ AFIT8_demsharpmix1_iWideMult [15:8]*/
+ 0x0F120900, /*AFIT8_demsharpmix1_iNarrMult [7:0],
+ AFIT8_demsharpmix1_iHystFalloff [15:8]*/
+ 0x0F120600, /*AFIT8_demsharpmix1_iHystMinMult [7:0],
+ AFIT8_demsharpmix1_iHystWidth [15:8]*/
+ 0x0F120504, /*AFIT8_demsharpmix1_iHystFallLow [7:0],
+ AFIT8_demsharpmix1_iHystFallHigh [15:8]*/
+ 0x0F120306, /*AFIT8_demsharpmix1_iHystTune [7:0],
+ * AFIT8_YUV422_DENOIsE_iUVsupport [15:8]*/
+ 0x0F128003, /*AFIT8_YUV422_DENOIsE_iYsupport [7:0],
+ AFIT8_byr_cgras_ishadingPower [15:8]*/
+ 0x0F120A6E, /*AFIT8_RGBGamma2_iLinearity [7:0],
+ AFIT8_RGBGamma2_iDarkReduce [15:8]*/
+ 0x0F120080, /*AFIT8_ccm_oscar_isaturation[7:0],
+ AFIT8_RGB2YUV_iYOffset [15:8]*/
+ 0x0F120080, /*AFIT8_RGB2YUV_iRGBGain [7:0],
+ AFIT8_RGB2YUV_isaturation [15:8]*/
+ 0x0F125050, /*AFIT8_sddd8a_iClustThresh_H [7:0],
+ AFIT8_sddd8a_iClustThresh_C [15:8]*/
+ 0x0F120101, /*AFIT8_sddd8a_iClustMulT_H [7:0],
+ AFIT8_sddd8a_iClustMulT_C [15:8]*/
+ 0x0F122801, /*AFIT8_sddd8a_nClustLevel_H [7:0],
+ AFIT8_sddd8a_DispTH_Low [15:8]*/
+ 0x0F12231E, /*AFIT8_sddd8a_DispTH_High [7:0],
+ AFIT8_sddd8a_iDenThreshLow [15:8]*/
+ 0x0F12961E, /*AFIT8_sddd8a_iDenThreshHigh[7:0],
+ AFIT8_Demosaicing_iEdgeDesat [15:8]*/
+ 0x0F120000, /*AFIT8_Demosaicing_iEdgeDesatThrLow [7:0],
+ AFIT8_Demosaicing_iEdgeDesatThrHigh [15:8]*/
+ 0x0F120003, /*AFIT8_Demosaicing_iEdgeDesatLimit[7:0],
+ AFIT8_Demosaicing_iDemsharpenLow [15:8]*/
+ 0x0F120A02, /*AFIT8_Demosaicing_iDemsharpenHigh[7:0],
+ AFIT8_Demosaicing_iDemsharpThresh [15:8]*/
+ 0x0F120764, /*AFIT8_Demosaicing_iDemshLowLimit [7:0],
+ AFIT8_Demosaicing_iDespeckleForDemsharp [15:8]*/
+ 0x0F12143C, /*AFIT8_Demosaicing_iDemBlurLow[7:0],
+ AFIT8_Demosaicing_iDemBlurHigh [15:8]*/
+ 0x0F121401, /*AFIT8_Demosaicing_iDemBlurRange[7:0],
+ AFIT8_sharpening_iLowsharpPower [15:8]*/
+ 0x0F120F14, /*AFIT8_sharpening_iHighsharpPower[7:0],
+ AFIT8_sharpening_iLowshDenoise [15:8]*/
+ 0x0F12400F, /*AFIT8_sharpening_iHighshDenoise [7:0],
+ AFIT8_sharpening_iReduceEdgeMinMult [15:8]*/
+ 0x0F120204, /*AFIT8_sharpening_iReduceEdgeslope [7:0],
+ AFIT8_demsharpmix1_iWideFiltReduce [15:8]*/
+ 0x0F125003, /*AFIT8_demsharpmix1_iNarrFiltReduce [7:0],
+ AFIT8_sddd8a_iClustThresh_H_Bin [15:8]*/
+ 0x0F120150, /*AFIT8_sddd8a_iClustThresh_C_Bin [7:0],
+ AFIT8_sddd8a_iClustMulT_H_Bin [15:8]*/
+ 0x0F120101, /*AFIT8_sddd8a_iClustMulT_C_Bin [7:0],
+ AFIT8_sddd8a_nClustLevel_H_Bin [15:8]*/
+ 0x0F121E28, /*AFIT8_sddd8a_DispTH_Low_Bin [7:0],
+ AFIT8_sddd8a_DispTH_High_Bin [15:8]*/
+ 0x0F120A0C, /*1419 AFIT8_sddd8a_iDenThreshLow_Bin [7:0],
+ AFIT8_sddd8a_iDenThreshHigh_Bin [15:8]*/
+ 0x0F120028, /*AFIT8_Demosaicing_iEdgeDesat_Bin[7:0],
+ AFIT8_Demosaicing_iEdgeDesatThrLow_Bin [15:8]*/
+ 0x0F120300, /*AFIT8_Demosaicing_iEdgeDesatThrHigh_Bin [7:0],
+ AFIT8_Demosaicing_iEdgeDesatLimit_Bin [15:8]*/
+ 0x0F120200, /*AFIT8_Demosaicing_iDemsharpenLow_Bin [7:0],
+ AFIT8_Demosaicing_iDemsharpenHigh_Bin [15:8]*/
+ 0x0F121E0A, /*AFIT8_Demosaicing_iDemsharpThresh_Bin [7:0],
+ AFIT8_Demosaicing_iDemshLowLimit_Bin [15:8]*/
+ 0x0F123C07, /*AFIT8_Demosaicing_iDespeckleForDemsharp_Bin [7:0],
+ AFIT8_Demosaicing_iDemBlurLow_Bin [15:8]*/
+ 0x0F120114, /*AFIT8_Demosaicing_iDemBlurHigh_Bin [7:0],
+ AFIT8_Demosaicing_iDemBlurRange_Bin [15:8]*/
+ 0x0F120A0A, /*1414 AFIT8_sharpening_iLowsharpPower_Bin [7:0],
+ AFIT8_sharpening_iHighsharpPower_Bin [15:8]*/
+ 0x0F120F0F, /*AFIT8_sharpening_iLowshDenoise_Bin [7:0],
+ AFIT8_sharpening_iHighshDenoise_Bin [15:8]*/
+ 0x0F120440, /*AFIT8_sharpening_iReduceEdgeMinMult_Bin [7:0],
+ AFIT8_sharpening_iReduceEdgeslope_Bin [15:8]*/
+ 0x0F120302, /*AFIT8_demsharpmix1_iWideFiltReduce_Bin [7:0],
+ AFIT8_demsharpmix1_iNarrFiltReduce_Bin [15:8]*/
+ 0x0F121E1E, /*AFIT8_sddd8a_iClustThresh_H_sBin[7:0],
+ AFIT8_sddd8a_iClustThresh_C_sBin [15:8]*/
+ 0x0F120101, /*AFIT8_sddd8a_iClustMulT_H_sBin [7:0],
+ AFIT8_sddd8a_iClustMulT_C_sBin [15:8]*/
+ 0x0F123C01, /*AFIT8_sddd8a_nClustLevel_H_sBin [7:0],
+ AFIT8_sddd8a_DispTH_Low_sBin [15:8]*/
+ 0x0F125A3A, /*AFIT8_sddd8a_DispTH_High_sBin [7:0],
+ AFIT8_sddd8a_iDenThreshLow_sBin [15:8]*/
+ 0x0F122858, /*AFIT8_sddd8a_iDenThreshHigh_sBin[7:0],
+ AFIT8_Demosaicing_iEdgeDesat_sBin [15:8]*/
+ 0x0F120A00, /*AFIT8_Demosaicing_iEdgeDesatThrLow_sBin [7:0],
+ AFIT8_Demosaicing_iEdgeDesatThrHigh_sBin [15:8]*/
+ 0x0F120003, /*AFIT8_Demosaicing_iEdgeDesatLimit_sBin [7:0],
+ AFIT8_Demosaicing_iDemsharpenLow_sBin [15:8]*/
+ 0x0F121E00, /*AFIT8_Demosaicing_iDemsharpenHigh_sBin [7:0],
+ AFIT8_Demosaicing_iDemsharpThresh_sBin [15:8]*/
+ 0x0F120714, /*AFIT8_Demosaicing_iDemshLowLimit_sBin [7:0],
+ AFIT8_Demosaicing_iDespeckleForDemsharp_sBin [15:8]*/
+ 0x0F1232FF, /*AFIT8_Demosaicing_iDemBlurLow_sBin [7:0],
+ AFIT8_Demosaicing_iDemBlurHigh_sBin [15:8]*/
+ 0x0F120004, /*AFIT8_Demosaicing_iDemBlurRange_sBin [7:0],
+ AFIT8_sharpening_iLowsharpPower_sBin [15:8]*/
+ 0x0F120F00, /*AFIT8_sharpening_iHighsharpPower_sBin [7:0],
+ AFIT8_sharpening_iLowshDenoise_sBin [15:8]*/
+ 0x0F12400F, /*AFIT8_sharpening_iHighshDenoise_sBin [7:0],
+ AFIT8_sharpening_iReduceEdgeMinMult_sBin [15:8]*/
+ 0x0F120204, /*AFIT8_sharpening_iReduceEdgeslope_sBin [7:0],
+ AFIT8_demsharpmix1_iWideFiltReduce_sBin [15:8]*/
+ 0x0F120003, /*AFIT8_demsharpmix1_iNarrFiltReduce_sBin [7:0]*/
+ 0x0F120000, /*AFIT16_BRIGHTNEss*/
+ 0x0F120000, /*AFIT16_CONTRAsT*/
+ 0x0F120000, /*AFIT16_sATURATION*/
+ 0x0F120000, /*AFIT16_sHARP_BLUR*/
+ 0x0F120000, /*AFIT16_GLAMOUR*/
+ 0x0F1200C1, /*AFIT16_sddd8a_edge_high*/
+ 0x0F1203FF, /*AFIT16_Demosaicing_isatVal*/
+ 0x0F12009C, /*AFIT16_sharpening_iReduceEdgeThresh*/
+ 0x0F12017C, /*AFIT16_demsharpmix1_iRGBOffset*/
+ 0x0F1203FF, /*AFIT16_demsharpmix1_iDemClamp*/
+ 0x0F12000C, /*AFIT16_demsharpmix1_iLowThreshold*/
+ 0x0F120010, /*AFIT16_demsharpmix1_iHighThreshold*/
+ 0x0F12012C, /*AFIT16_demsharpmix1_iLowBright*/
+ 0x0F1203E8, /*AFIT16_demsharpmix1_iHighBright*/
+ 0x0F120046, /*AFIT16_demsharpmix1_iLowsat*/
+ 0x0F12005A, /*AFIT16_demsharpmix1_iHighsat*/
+ 0x0F120070, /*AFIT16_demsharpmix1_iTune*/
+ 0x0F120008, /*AFIT16_demsharpmix1_iHystThLow*/
+ 0x0F120000, /*AFIT16_demsharpmix1_iHystThHigh*/
+ 0x0F120320, /*AFIT16_demsharpmix1_iHystCenter*/
+ 0x0F120032, /*AFIT16_YUV422_DENOIsE_iUVLowThresh*/
+ 0x0F120032, /*AFIT16_YUV422_DENOIsE_iUVHighThresh*/
+ 0x0F120000, /*AFIT16_YUV422_DENOIsE_iYLowThresh*/
+ 0x0F120000, /*AFIT16_YUV422_DENOIsE_iYHighThresh*/
+ 0x0F1200B4, /*AFIT16_sharpening_iLowsharpClamp*/
+ 0x0F120014, /*AFIT16_sharpening_iHighsharpClamp*/
+ 0x0F1200B4, /*AFIT16_sharpening_iLowsharpClamp_Bin*/
+ 0x0F120014, /*AFIT16_sharpening_iHighsharpClamp_Bin*/
+ 0x0F12003C, /*AFIT16_sharpening_iLowsharpClamp_sBin*/
+ 0x0F12001E, /*AFIT16_sharpening_iHighsharpClamp_sBin*/
+ 0x0F120A24, /*AFIT8_sddd8a_edge_low [7:0],
+ AFIT8_sddd8a_repl_thresh [15:8]*/
+ 0x0F121701, /*AFIT8_sddd8a_repl_force [7:0],
+ AFIT8_sddd8a_sat_level [15:8]*/
+ 0x0F120229, /*AFIT8_sddd8a_sat_thr[7:0],
+ AFIT8_sddd8a_sat_mpl [15:8]*/
+ 0x0F121403, /*AFIT8_sddd8a_sat_noise[7:0],
+ AFIT8_sddd8a_iMaxslopeAllowed [15:8]*/
+ 0x0F120000, /*AFIT8_sddd8a_iHotThreshHigh[7:0],
+ AFIT8_sddd8a_iHotThreshLow [15:8]*/
+ 0x0F120000, /*AFIT8_sddd8a_iColdThreshHigh[7:0],
+ AFIT8_sddd8a_iColdThreshLow [15:8]*/
+ 0x0F120000, /*AFIT8_sddd8a_AddNoisePower1[7:0],
+ AFIT8_sddd8a_AddNoisePower2 [15:8]*/
+ 0x0F1200FF, /*AFIT8_sddd8a_isatsat[7:0],
+ AFIT8_sddd8a_iRadialTune [15:8]*/
+ 0x0F12033B, /*AFIT8_sddd8a_iRadialLimit [7:0],
+ AFIT8_sddd8a_iRadialPower [15:8]*/
+ 0x0F121414, /*AFIT8_sddd8a_iLowMaxslopeAllowed [7:0],
+ AFIT8_sddd8a_iHighMaxslopeAllowed [15:8]*/
+ 0x0F120301, /*AFIT8_sddd8a_iLowslopeThresh[7:0],
+ AFIT8_sddd8a_iHighslopeThresh [15:8]*/
+ 0x0F12FF07, /*AFIT8_sddd8a_isquaresRounding [7:0],
+ AFIT8_Demosaicing_iCentGrad [15:8]*/
+ 0x0F12081E, /*AFIT8_Demosaicing_iMonochrom [7:0],
+ AFIT8_Demosaicing_iDecisionThresh [15:8]*/
+ 0x0F120A1E, /*AFIT8_Demosaicing_iDesatThresh [7:0],
+ AFIT8_Demosaicing_iEnhThresh [15:8]*/
+ 0x0F120F0F, /*AFIT8_Demosaicing_iGRDenoiseVal [7:0],
+ AFIT8_Demosaicing_iGBDenoiseVal [15:8]*/
+ 0x0F120A00, /*AFIT8_Demosaicing_iNearGrayDesat[7:0],
+ AFIT8_Demosaicing_iDFD_ReduceCoeff [15:8]*/
+ 0x0F120012, /*AFIT8_sharpening_iMsharpen [7:0],
+ AFIT8_sharpening_iMshThresh [15:8]*/
+ 0x0F120005, /*AFIT8_sharpening_iWsharpen [7:0],
+ AFIT8_sharpening_iWshThresh [15:8]*/
+ 0x0F120001, /*AFIT8_sharpening_nsharpWidth [7:0],
+ AFIT8_sharpening_iReduceNegative [15:8]*/
+ 0x0F1200FF, /*AFIT8_sharpening_ishDespeckle [7:0],
+ AFIT8_demsharpmix1_iRGBMultiplier [15:8]*/
+ 0x0F121102, /*AFIT8_demsharpmix1_iFilterPower [7:0],
+ AFIT8_demsharpmix1_iBCoeff [15:8]*/
+ 0x0F12001B, /*AFIT8_demsharpmix1_iGCoeff [7:0],
+ AFIT8_demsharpmix1_iWideMult [15:8]*/
+ 0x0F120900, /*AFIT8_demsharpmix1_iNarrMult [7:0],
+ AFIT8_demsharpmix1_iHystFalloff [15:8]*/
+ 0x0F120600, /*AFIT8_demsharpmix1_iHystMinMult [7:0],
+ AFIT8_demsharpmix1_iHystWidth [15:8]*/
+ 0x0F120504, /*AFIT8_demsharpmix1_iHystFallLow [7:0],
+ AFIT8_demsharpmix1_iHystFallHigh [15:8]*/
+ 0x0F120306, /*AFIT8_demsharpmix1_iHystTune [7:0],
+ * AFIT8_YUV422_DENOIsE_iUVsupport [15:8]*/
+ 0x0F128002, /*AFIT8_YUV422_DENOIsE_iYsupport [7:0],
+ AFIT8_byr_cgras_ishadingPower [15:8]*/
+ 0x0F120080, /*AFIT8_RGBGamma2_iLinearity [7:0],
+ AFIT8_RGBGamma2_iDarkReduce [15:8]*/
+ 0x0F120080, /*AFIT8_ccm_oscar_isaturation[7:0],
+ AFIT8_RGB2YUV_iYOffset [15:8]*/
+ 0x0F120080, /*AFIT8_RGB2YUV_iRGBGain [7:0],
+ AFIT8_RGB2YUV_isaturation [15:8]*/
+ 0x0F125050, /*AFIT8_sddd8a_iClustThresh_H [7:0],
+ AFIT8_sddd8a_iClustThresh_C [15:8]*/
+ 0x0F120101, /*AFIT8_sddd8a_iClustMulT_H [7:0],
+ AFIT8_sddd8a_iClustMulT_C [15:8]*/
+ 0x0F121B01, /*AFIT8_sddd8a_nClustLevel_H [7:0],
+ AFIT8_sddd8a_DispTH_Low [15:8]*/
+ 0x0F122319, /*AFIT8_sddd8a_DispTH_High [7:0],
+ AFIT8_sddd8a_iDenThreshLow [15:8]*/
+ 0x0F12960F, /*AFIT8_sddd8a_iDenThreshHigh[7:0],
+ AFIT8_Demosaicing_iEdgeDesat [15:8]*/
+ 0x0F120000, /*AFIT8_Demosaicing_iEdgeDesatThrLow [7:0],
+ AFIT8_Demosaicing_iEdgeDesatThrHigh [15:8]*/
+ 0x0F122A03, /*AFIT8_Demosaicing_iEdgeDesatLimit[7:0],
+ AFIT8_Demosaicing_iDemsharpenLow [15:8]*/
+ 0x0F120A02, /*AFIT8_Demosaicing_iDemsharpenHigh[7:0],
+ AFIT8_Demosaicing_iDemsharpThresh [15:8]*/
+ 0x0F120864, /*AFIT8_Demosaicing_iDemshLowLimit [7:0],
+ AFIT8_Demosaicing_iDespeckleForDemsharp [15:8]*/
+ 0x0F121432, /*AFIT8_Demosaicing_iDemBlurLow[7:0],
+ AFIT8_Demosaicing_iDemBlurHigh [15:8]*/
+ 0x0F129601, /*AFIT8_Demosaicing_iDemBlurRange[7:0],
+ AFIT8_sharpening_iLowsharpPower [15:8]*/
+ 0x0F122814, /*AFIT8_sharpening_iHighsharpPower[7:0],
+ AFIT8_sharpening_iLowshDenoise [15:8]*/
+ 0x0F12400A, /*AFIT8_sharpening_iHighshDenoise [7:0],
+ AFIT8_sharpening_iReduceEdgeMinMult [15:8]*/
+ 0x0F120204, /*AFIT8_sharpening_iReduceEdgeslope [7:0],
+ AFIT8_demsharpmix1_iWideFiltReduce [15:8]*/
+ 0x0F125003, /*AFIT8_demsharpmix1_iNarrFiltReduce [7:0],
+ AFIT8_sddd8a_iClustThresh_H_Bin [15:8]*/
+ 0x0F120150, /*AFIT8_sddd8a_iClustThresh_C_Bin [7:0],
+ AFIT8_sddd8a_iClustMulT_H_Bin [15:8]*/
+ 0x0F120101, /*AFIT8_sddd8a_iClustMulT_C_Bin [7:0],
+ AFIT8_sddd8a_nClustLevel_H_Bin [15:8]*/
+ 0x0F12191B, /*AFIT8_sddd8a_DispTH_Low_Bin [7:0],
+ AFIT8_sddd8a_DispTH_High_Bin [15:8]*/
+ 0x0F12070C, /*0F19 AFIT8_sddd8a_iDenThreshLow_Bin [7:0],
+ AFIT8_sddd8a_iDenThreshHigh_Bin [15:8]*/
+ 0x0F120028, /*AFIT8_Demosaicing_iEdgeDesat_Bin[7:0],
+ AFIT8_Demosaicing_iEdgeDesatThrLow_Bin [15:8]*/
+ 0x0F120300, /*AFIT8_Demosaicing_iEdgeDesatThrHigh_Bin [7:0],
+ AFIT8_Demosaicing_iEdgeDesatLimit_Bin [15:8]*/
+ 0x0F12021E, /*AFIT8_Demosaicing_iDemsharpenLow_Bin [7:0],
+ AFIT8_Demosaicing_iDemsharpenHigh_Bin [15:8]*/
+ 0x0F121E0A, /*AFIT8_Demosaicing_iDemsharpThresh_Bin [7:0],
+ AFIT8_Demosaicing_iDemshLowLimit_Bin [15:8]*/
+ 0x0F123208, /*AFIT8_Demosaicing_iDespeckleForDemsharp_Bin [7:0],
+ AFIT8_Demosaicing_iDemBlurLow_Bin [15:8]*/
+ 0x0F120114, /*AFIT8_Demosaicing_iDemBlurHigh_Bin [7:0],
+ AFIT8_Demosaicing_iDemBlurRange_Bin [15:8]*/
+ 0x0F120A28, /*1450 AFIT8_sharpening_iLowsharpPower_Bin [7:0],
+ AFIT8_sharpening_iHighsharpPower_Bin [15:8]*/
+ 0x0F120A28, /*AFIT8_sharpening_iLowshDenoise_Bin [7:0],
+ AFIT8_sharpening_iHighshDenoise_Bin [15:8]*/
+ 0x0F120440, /*AFIT8_sharpening_iReduceEdgeMinMult_Bin [7:0],
+ AFIT8_sharpening_iReduceEdgeslope_Bin [15:8]*/
+ 0x0F120302, /*AFIT8_demsharpmix1_iWideFiltReduce_Bin [7:0],
+ AFIT8_demsharpmix1_iNarrFiltReduce_Bin [15:8]*/
+ 0x0F122828, /*AFIT8_sddd8a_iClustThresh_H_sBin[7:0],
+ AFIT8_sddd8a_iClustThresh_C_sBin [15:8]*/
+ 0x0F120101, /*AFIT8_sddd8a_iClustMulT_H_sBin [7:0],
+ AFIT8_sddd8a_iClustMulT_C_sBin [15:8]*/
+ 0x0F122401, /*AFIT8_sddd8a_nClustLevel_H_sBin [7:0],
+ AFIT8_sddd8a_DispTH_Low_sBin [15:8]*/
+ 0x0F123622, /*AFIT8_sddd8a_DispTH_High_sBin [7:0],
+ AFIT8_sddd8a_iDenThreshLow_sBin [15:8]*/
+ 0x0F122832, /*AFIT8_sddd8a_iDenThreshHigh_sBin[7:0],
+ AFIT8_Demosaicing_iEdgeDesat_sBin [15:8]*/
+ 0x0F120A00, /*AFIT8_Demosaicing_iEdgeDesatThrLow_sBin [7:0],
+ AFIT8_Demosaicing_iEdgeDesatThrHigh_sBin [15:8]*/
+ 0x0F121003, /*AFIT8_Demosaicing_iEdgeDesatLimit_sBin [7:0],
+ AFIT8_Demosaicing_iDemsharpenLow_sBin [15:8]*/
+ 0x0F121E04, /*AFIT8_Demosaicing_iDemsharpenHigh_sBin [7:0],
+ AFIT8_Demosaicing_iDemsharpThresh_sBin [15:8]*/
+ 0x0F120714, /*AFIT8_Demosaicing_iDemshLowLimit_sBin [7:0],
+ AFIT8_Demosaicing_iDespeckleForDemsharp_sBin [15:8]*/
+ 0x0F1232FF, /*AFIT8_Demosaicing_iDemBlurLow_sBin [7:0],
+ AFIT8_Demosaicing_iDemBlurHigh_sBin [15:8]*/
+ 0x0F125004, /*AFIT8_Demosaicing_iDemBlurRange_sBin [7:0],
+ AFIT8_sharpening_iLowsharpPower_sBin [15:8]*/
+ 0x0F120F40, /*AFIT8_sharpening_iHighsharpPower_sBin [7:0],
+ AFIT8_sharpening_iLowshDenoise_sBin [15:8]*/
+ 0x0F12400F, /*AFIT8_sharpening_iHighshDenoise_sBin [7:0],
+ AFIT8_sharpening_iReduceEdgeMinMult_sBin [15:8]*/
+ 0x0F120204, /*AFIT8_sharpening_iReduceEdgeslope_sBin [7:0],
+ AFIT8_demsharpmix1_iWideFiltReduce_sBin [15:8]*/
+ 0x0F120003, /*AFIT8_demsharpmix1_iNarrFiltReduce_sBin [7:0]*/
+ 0x0F120000, /*AFIT16_BRIGHTNEss*/
+ 0x0F120000, /*AFIT16_CONTRAsT*/
+ 0x0F120000, /*AFIT16_sATURATION*/
+ 0x0F120000, /*AFIT16_sHARP_BLUR*/
+ 0x0F120000, /*AFIT16_GLAMOUR*/
+ 0x0F1200C1, /*AFIT16_sddd8a_edge_high*/
+ 0x0F1203FF, /*AFIT16_Demosaicing_isatVal*/
+ 0x0F12009C, /*AFIT16_sharpening_iReduceEdgeThresh*/
+ 0x0F12017C, /*AFIT16_demsharpmix1_iRGBOffset*/
+ 0x0F1203FF, /*AFIT16_demsharpmix1_iDemClamp*/
+ 0x0F12000C, /*AFIT16_demsharpmix1_iLowThreshold*/
+ 0x0F120010, /*AFIT16_demsharpmix1_iHighThreshold*/
+ 0x0F1200C8, /*AFIT16_demsharpmix1_iLowBright*/
+ 0x0F1203E8, /*AFIT16_demsharpmix1_iHighBright*/
+ 0x0F120046, /*AFIT16_demsharpmix1_iLowsat*/
+ 0x0F120050, /*AFIT16_demsharpmix1_iHighsat*/
+ 0x0F120070, /*AFIT16_demsharpmix1_iTune*/
+ 0x0F120008, /*AFIT16_demsharpmix1_iHystThLow*/
+ 0x0F120000, /*AFIT16_demsharpmix1_iHystThHigh*/
+ 0x0F120320, /*AFIT16_demsharpmix1_iHystCenter*/
+ 0x0F120032, /*AFIT16_YUV422_DENOIsE_iUVLowThresh*/
+ 0x0F120032, /*AFIT16_YUV422_DENOIsE_iUVHighThresh*/
+ 0x0F120000, /*AFIT16_YUV422_DENOIsE_iYLowThresh*/
+ 0x0F120000, /*AFIT16_YUV422_DENOIsE_iYHighThresh*/
+ 0x0F1200B4, /*AFIT16_sharpening_iLowsharpClamp*/
+ 0x0F120014, /*AFIT16_sharpening_iHighsharpClamp*/
+ 0x0F1200B4, /*AFIT16_sharpening_iLowsharpClamp_Bin*/
+ 0x0F120014, /*AFIT16_sharpening_iHighsharpClamp_Bin*/
+ 0x0F12002D, /*AFIT16_sharpening_iLowsharpClamp_sBin*/
+ 0x0F120019, /*AFIT16_sharpening_iHighsharpClamp_sBin*/
+ 0x0F120A24, /*AFIT8_sddd8a_edge_low [7:0],AFIT8_sddd8a_repl_thresh
+ [15:8]*/
+ 0x0F121701, /*AFIT8_sddd8a_repl_force [7:0],AFIT8_sddd8a_sat_level
+ [15:8]*/
+ 0x0F120229, /*AFIT8_sddd8a_sat_thr[7:0],AFIT8_sddd8a_sat_mpl
+ [15:8]*/
+ 0x0F121403, /*AFIT8_sddd8a_sat_noise[7:0],
+ AFIT8_sddd8a_iMaxslopeAllowed [15:8]*/
+ 0x0F120000, /*AFIT8_sddd8a_iHotThreshHigh[7:0],
+ AFIT8_sddd8a_iHotThreshLow [15:8]*/
+ 0x0F120000, /*AFIT8_sddd8a_iColdThreshHigh[7:0],
+ AFIT8_sddd8a_iColdThreshLow [15:8]*/
+ 0x0F120000, /*AFIT8_sddd8a_AddNoisePower1[7:0],
+ AFIT8_sddd8a_AddNoisePower2 [15:8]*/
+ 0x0F1200FF, /*AFIT8_sddd8a_isatsat[7:0],
+ AFIT8_sddd8a_iRadialTune [15:8]*/
+ 0x0F12033B, /*AFIT8_sddd8a_iRadialLimit [7:0],
+ AFIT8_sddd8a_iRadialPower [15:8]*/
+ 0x0F121414, /*AFIT8_sddd8a_iLowMaxslopeAllowed [7:0],
+ AFIT8_sddd8a_iHighMaxslopeAllowed [15:8]*/
+ 0x0F120301, /*AFIT8_sddd8a_iLowslopeThresh[7:0],
+ AFIT8_sddd8a_iHighslopeThresh [15:8]*/
+ 0x0F12FF07, /*AFIT8_sddd8a_isquaresRounding [7:0],
+ AFIT8_Demosaicing_iCentGrad [15:8]*/
+ 0x0F12081E, /*AFIT8_Demosaicing_iMonochrom [7:0],
+ AFIT8_Demosaicing_iDecisionThresh [15:8]*/
+ 0x0F120A1E, /*AFIT8_Demosaicing_iDesatThresh [7:0],
+ AFIT8_Demosaicing_iEnhThresh [15:8]*/
+ 0x0F120F0F, /*AFIT8_Demosaicing_iGRDenoiseVal [7:0],
+ AFIT8_Demosaicing_iGBDenoiseVal [15:8]*/
+ 0x0F120A00, /*AFIT8_Demosaicing_iNearGrayDesat[7:0],
+ AFIT8_Demosaicing_iDFD_ReduceCoeff [15:8]*/
+ 0x0F120012, /*AFIT8_sharpening_iMsharpen [7:0],
+ AFIT8_sharpening_iMshThresh [15:8]*/
+ 0x0F120005, /*AFIT8_sharpening_iWsharpen [7:0],
+ AFIT8_sharpening_iWshThresh [15:8]*/
+ 0x0F120001, /*AFIT8_sharpening_nsharpWidth [7:0],
+ AFIT8_sharpening_iReduceNegative [15:8]*/
+ 0x0F1200FF, /*AFIT8_sharpening_ishDespeckle [7:0],
+ AFIT8_demsharpmix1_iRGBMultiplier [15:8]*/
+ 0x0F121002, /*AFIT8_demsharpmix1_iFilterPower [7:0],
+ AFIT8_demsharpmix1_iBCoeff [15:8]*/
+ 0x0F12001E, /*AFIT8_demsharpmix1_iGCoeff [7:0],
+ AFIT8_demsharpmix1_iWideMult [15:8]*/
+ 0x0F120900, /*AFIT8_demsharpmix1_iNarrMult [7:0],
+ AFIT8_demsharpmix1_iHystFalloff [15:8]*/
+ 0x0F120600, /*AFIT8_demsharpmix1_iHystMinMult [7:0],
+ AFIT8_demsharpmix1_iHystWidth [15:8]*/
+ 0x0F120504, /*AFIT8_demsharpmix1_iHystFallLow [7:0],
+ AFIT8_demsharpmix1_iHystFallHigh [15:8]*/
+ 0x0F120307, /*AFIT8_demsharpmix1_iHystTune [7:0],
+ * AFIT8_YUV422_DENOIsE_iUVsupport [15:8]*/
+ 0x0F128002, /*AFIT8_YUV422_DENOIsE_iYsupport [7:0],
+ AFIT8_byr_cgras_ishadingPower [15:8]*/
+ 0x0F120080, /*AFIT8_RGBGamma2_iLinearity [7:0],
+ AFIT8_RGBGamma2_iDarkReduce [15:8]*/
+ 0x0F120080, /*AFIT8_ccm_oscar_isaturation[7:0],
+ AFIT8_RGB2YUV_iYOffset [15:8]*/
+ 0x0F120080, /*AFIT8_RGB2YUV_iRGBGain [7:0],
+ AFIT8_RGB2YUV_isaturation [15:8]*/
+ 0x0F125050, /*AFIT8_sddd8a_iClustThresh_H [7:0],
+ AFIT8_sddd8a_iClustThresh_C [15:8]*/
+ 0x0F120101, /*AFIT8_sddd8a_iClustMulT_H [7:0],
+ AFIT8_sddd8a_iClustMulT_C [15:8]*/
+ 0x0F121B01, /*AFIT8_sddd8a_nClustLevel_H [7:0],
+ AFIT8_sddd8a_DispTH_Low [15:8]*/
+ 0x0F122319, /*AFIT8_sddd8a_DispTH_High [7:0],
+ AFIT8_sddd8a_iDenThreshLow [15:8]*/
+ 0x0F12960F, /*AFIT8_sddd8a_iDenThreshHigh[7:0],
+ AFIT8_Demosaicing_iEdgeDesat [15:8]*/
+ 0x0F120000, /*AFIT8_Demosaicing_iEdgeDesatThrLow [7:0],
+ AFIT8_Demosaicing_iEdgeDesatThrHigh [15:8]*/
+ 0x0F122003, /*AFIT8_Demosaicing_iEdgeDesatLimit[7:0],
+ AFIT8_Demosaicing_iDemsharpenLow [15:8]*/
+ 0x0F120A02, /*AFIT8_Demosaicing_iDemsharpenHigh[7:0],
+ AFIT8_Demosaicing_iDemsharpThresh [15:8]*/
+ 0x0F120864, /*AFIT8_Demosaicing_iDemshLowLimit [7:0],
+ AFIT8_Demosaicing_iDespeckleForDemsharp [15:8]*/
+ 0x0F121432, /*AFIT8_Demosaicing_iDemBlurLow[7:0],
+ AFIT8_Demosaicing_iDemBlurHigh [15:8]*/
+ 0x0F12A001, /*AFIT8_Demosaicing_iDemBlurRange[7:0],
+ AFIT8_sharpening_iLowsharpPower [15:8]*/
+ 0x0F122814, /*AFIT8_sharpening_iHighsharpPower[7:0],
+ AFIT8_sharpening_iLowshDenoise [15:8]*/
+ 0x0F12400A, /*AFIT8_sharpening_iHighshDenoise [7:0],
+ AFIT8_sharpening_iReduceEdgeMinMult [15:8]*/
+ 0x0F120204, /*AFIT8_sharpening_iReduceEdgeslope [7:0],
+ AFIT8_demsharpmix1_iWideFiltReduce [15:8]*/
+ 0x0F125003, /*AFIT8_demsharpmix1_iNarrFiltReduce [7:0],
+ AFIT8_sddd8a_iClustThresh_H_Bin [15:8]*/
+ 0x0F120150, /*AFIT8_sddd8a_iClustThresh_C_Bin [7:0],
+ AFIT8_sddd8a_iClustMulT_H_Bin [15:8]*/
+ 0x0F120101, /*AFIT8_sddd8a_iClustMulT_C_Bin [7:0],
+ AFIT8_sddd8a_nClustLevel_H_Bin [15:8]*/
+ 0x0F12191B, /*AFIT8_sddd8a_DispTH_Low_Bin [7:0],
+ AFIT8_sddd8a_DispTH_High_Bin [15:8]*/
+ 0x0F12070C, /*0F19 AFIT8_sddd8a_iDenThreshLow_Bin [7:0],
+ AFIT8_sddd8a_iDenThreshHigh_Bin [15:8]*/
+ 0x0F120028, /*AFIT8_Demosaicing_iEdgeDesat_Bin[7:0],
+ AFIT8_Demosaicing_iEdgeDesatThrLow_Bin [15:8]*/
+ 0x0F120300, /*AFIT8_Demosaicing_iEdgeDesatThrHigh_Bin [7:0],
+ AFIT8_Demosaicing_iEdgeDesatLimit_Bin [15:8]*/
+ 0x0F12021E, /*AFIT8_Demosaicing_iDemsharpenLow_Bin [7:0],
+ AFIT8_Demosaicing_iDemsharpenHigh_Bin [15:8]*/
+ 0x0F121E0A, /*AFIT8_Demosaicing_iDemsharpThresh_Bin [7:0],
+ AFIT8_Demosaicing_iDemshLowLimit_Bin [15:8]*/
+ 0x0F123208, /*AFIT8_Demosaicing_iDespeckleForDemsharp_Bin [7:0],
+ AFIT8_Demosaicing_iDemBlurLow_Bin [15:8]*/
+ 0x0F120114, /*AFIT8_Demosaicing_iDemBlurHigh_Bin [7:0],
+ AFIT8_Demosaicing_iDemBlurRange_Bin [15:8]*/
+ 0x0F120A28, /*1450 AFIT8_sharpening_iLowsharpPower_Bin [7:0],
+ AFIT8_sharpening_iHighsharpPower_Bin [15:8]*/
+ 0x0F120A28, /*AFIT8_sharpening_iLowshDenoise_Bin [7:0],
+ AFIT8_sharpening_iHighshDenoise_Bin [15:8]*/
+ 0x0F120440, /*AFIT8_sharpening_iReduceEdgeMinMult_Bin [7:0],
+ AFIT8_sharpening_iReduceEdgeslope_Bin [15:8]*/
+ 0x0F120302, /*AFIT8_demsharpmix1_iWideFiltReduce_Bin [7:0],
+ AFIT8_demsharpmix1_iNarrFiltReduce_Bin [15:8]*/
+ 0x0F123C3C, /*AFIT8_sddd8a_iClustThresh_H_sBin[7:0],
+ AFIT8_sddd8a_iClustThresh_C_sBin [15:8]*/
+ 0x0F120101, /*AFIT8_sddd8a_iClustMulT_H_sBin [7:0],
+ AFIT8_sddd8a_iClustMulT_C_sBin [15:8]*/
+ 0x0F121E01, /*AFIT8_sddd8a_nClustLevel_H_sBin [7:0],
+ AFIT8_sddd8a_DispTH_Low_sBin [15:8]*/
+ 0x0F12221C, /*AFIT8_sddd8a_DispTH_High_sBin [7:0],
+ AFIT8_sddd8a_iDenThreshLow_sBin [15:8]*/
+ 0x0F12281E, /*AFIT8_sddd8a_iDenThreshHigh_sBin[7:0],
+ AFIT8_Demosaicing_iEdgeDesat_sBin [15:8]*/
+ 0x0F120A00, /*AFIT8_Demosaicing_iEdgeDesatThrLow_sBin [7:0],
+ AFIT8_Demosaicing_iEdgeDesatThrHigh_sBin [15:8]*/
+ 0x0F121403, /*AFIT8_Demosaicing_iEdgeDesatLimit_sBin [7:0],
+ AFIT8_Demosaicing_iDemsharpenLow_sBin [15:8]*/
+ 0x0F121402, /*AFIT8_Demosaicing_iDemsharpenHigh_sBin [7:0],
+ AFIT8_Demosaicing_iDemsharpThresh_sBin [15:8]*/
+ 0x0F12060E, /*AFIT8_Demosaicing_iDemshLowLimit_sBin [7:0],
+ AFIT8_Demosaicing_iDespeckleForDemsharp_sBin [15:8]*/
+ 0x0F1232FF, /*AFIT8_Demosaicing_iDemBlurLow_sBin [7:0],
+ AFIT8_Demosaicing_iDemBlurHigh_sBin [15:8]*/
+ 0x0F125204, /*AFIT8_Demosaicing_iDemBlurRange_sBin [7:0],
+ AFIT8_sharpening_iLowsharpPower_sBin [15:8]*/
+ 0x0F120C40, /*AFIT8_sharpening_iHighsharpPower_sBin [7:0],
+ AFIT8_sharpening_iLowshDenoise_sBin [15:8]*/
+ 0x0F124015, /*AFIT8_sharpening_iHighshDenoise_sBin [7:0],
+ AFIT8_sharpening_iReduceEdgeMinMult_sBin [15:8]*/
+ 0x0F120204, /*AFIT8_sharpening_iReduceEdgeslope_sBin [7:0],
+ AFIT8_demsharpmix1_iWideFiltReduce_sBin [15:8]*/
+ 0x0F120003, /*AFIT8_demsharpmix1_iNarrFiltReduce_sBin [7:0]*/
+ 0x0F120000, /*AFIT16_BRIGHTNEss*/
+ 0x0F120000, /*AFIT16_CONTRAsT*/
+ 0x0F120000, /*AFIT16_sATURATION*/
+ 0x0F120000, /*AFIT16_sHARP_BLUR*/
+ 0x0F120000, /*AFIT16_GLAMOUR*/
+ 0x0F1200C1, /*AFIT16_sddd8a_edge_high*/
+ 0x0F1203FF, /*AFIT16_Demosaicing_isatVal*/
+ 0x0F12009C, /*AFIT16_sharpening_iReduceEdgeThresh*/
+ 0x0F12017C, /*AFIT16_demsharpmix1_iRGBOffset*/
+ 0x0F1203FF, /*AFIT16_demsharpmix1_iDemClamp*/
+ 0x0F12000C, /*AFIT16_demsharpmix1_iLowThreshold*/
+ 0x0F120010, /*AFIT16_demsharpmix1_iHighThreshold*/
+ 0x0F120032, /*AFIT16_demsharpmix1_iLowBright*/
+ 0x0F12028A, /*AFIT16_demsharpmix1_iHighBright*/
+ 0x0F120032, /*AFIT16_demsharpmix1_iLowsat*/
+ 0x0F1201F4, /*AFIT16_demsharpmix1_iHighsat*/
+ 0x0F120070, /*AFIT16_demsharpmix1_iTune*/
+ 0x0F120002, /*AFIT16_demsharpmix1_iHystThLow*/
+ 0x0F120000, /*AFIT16_demsharpmix1_iHystThHigh*/
+ 0x0F1201AA, /*AFIT16_demsharpmix1_iHystCenter*/
+ 0x0F12003C, /*AFIT16_YUV422_DENOIsE_iUVLowThresh*/
+ 0x0F120050, /*AFIT16_YUV422_DENOIsE_iUVHighThresh*/
+ 0x0F120000, /*AFIT16_YUV422_DENOIsE_iYLowThresh*/
+ 0x0F120000, /*AFIT16_YUV422_DENOIsE_iYHighThresh*/
+ 0x0F1200B4, /*AFIT16_sharpening_iLowsharpClamp*/
+ 0x0F120014, /*AFIT16_sharpening_iHighsharpClamp*/
+ 0x0F1200B4, /*AFIT16_sharpening_iLowsharpClamp_Bin*/
+ 0x0F120014, /*AFIT16_sharpening_iHighsharpClamp_Bin*/
+ 0x0F120046, /*AFIT16_sharpening_iLowsharpClamp_sBin*/
+ 0x0F120019, /*AFIT16_sharpening_iHighsharpClamp_sBin*/
+ 0x0F120A24, /*AFIT8_sddd8a_edge_low [7:0],
+ AFIT8_sddd8a_repl_thresh [15:8]*/
+ 0x0F121701, /*AFIT8_sddd8a_repl_force [7:0],
+ AFIT8_sddd8a_sat_level [15:8]*/
+ 0x0F120229, /*AFIT8_sddd8a_sat_thr[7:0],
+ AFIT8_sddd8a_sat_mpl [15:8]*/
+ 0x0F120503, /*AFIT8_sddd8a_sat_noise[7:0],
+ AFIT8_sddd8a_iMaxslopeAllowed [15:8]*/
+ 0x0F12080F, /*AFIT8_sddd8a_iHotThreshHigh[7:0],
+ AFIT8_sddd8a_iHotThreshLow [15:8]*/
+ 0x0F120808, /*AFIT8_sddd8a_iColdThreshHigh[7:0],
+ AFIT8_sddd8a_iColdThreshLow [15:8]*/
+ 0x0F120000, /*AFIT8_sddd8a_AddNoisePower1[7:0],
+ AFIT8_sddd8a_AddNoisePower2 [15:8]*/
+ 0x0F1200FF, /*AFIT8_sddd8a_isatsat[7:0],
+ AFIT8_sddd8a_iRadialTune [15:8]*/
+ 0x0F12022D, /*AFIT8_sddd8a_iRadialLimit [7:0],
+ AFIT8_sddd8a_iRadialPower [15:8]*/
+ 0x0F121414, /*AFIT8_sddd8a_iLowMaxslopeAllowed [7:0],
+ AFIT8_sddd8a_iHighMaxslopeAllowed [15:8]*/
+ 0x0F120301, /*AFIT8_sddd8a_iLowslopeThresh[7:0],
+ AFIT8_sddd8a_iHighslopeThresh [15:8]*/
+ 0x0F12FF07, /*AFIT8_sddd8a_isquaresRounding [7:0],
+ AFIT8_Demosaicing_iCentGrad [15:8]*/
+ 0x0F12061E, /*AFIT8_Demosaicing_iMonochrom [7:0],
+ AFIT8_Demosaicing_iDecisionThresh [15:8]*/
+ 0x0F120A1E, /*AFIT8_Demosaicing_iDesatThresh [7:0],
+ AFIT8_Demosaicing_iEnhThresh [15:8]*/
+ 0x0F120606, /*AFIT8_Demosaicing_iGRDenoiseVal [7:0],
+ AFIT8_Demosaicing_iGBDenoiseVal [15:8]*/
+ 0x0F120A03, /*AFIT8_Demosaicing_iNearGrayDesat[7:0],
+ AFIT8_Demosaicing_iDFD_ReduceCoeff [15:8]*/
+ 0x0F120028, /*AFIT8_sharpening_iMsharpen [7:0],
+ AFIT8_sharpening_iMshThresh [15:8]*/
+ 0x0F120002, /*AFIT8_sharpening_iWsharpen [7:0],
+ AFIT8_sharpening_iWshThresh [15:8]*/
+ 0x0F120001, /*AFIT8_sharpening_nsharpWidth [7:0],
+ AFIT8_sharpening_iReduceNegative [15:8]*/
+ 0x0F1200FF, /*AFIT8_sharpening_ishDespeckle [7:0],
+ AFIT8_demsharpmix1_iRGBMultiplier [15:8]*/
+ 0x0F121002, /*AFIT8_demsharpmix1_iFilterPower [7:0],
+ AFIT8_demsharpmix1_iBCoeff [15:8]*/
+ 0x0F12001E, /*AFIT8_demsharpmix1_iGCoeff [7:0],
+ AFIT8_demsharpmix1_iWideMult [15:8]*/
+ 0x0F120900, /*AFIT8_demsharpmix1_iNarrMult [7:0],
+ AFIT8_demsharpmix1_iHystFalloff [15:8]*/
+ 0x0F120600, /*AFIT8_demsharpmix1_iHystMinMult [7:0],
+ AFIT8_demsharpmix1_iHystWidth [15:8]*/
+ 0x0F120504, /*AFIT8_demsharpmix1_iHystFallLow [7:0],
+ AFIT8_demsharpmix1_iHystFallHigh [15:8]*/
+ 0x0F120307, /*AFIT8_demsharpmix1_iHystTune [7:0],
+ * AFIT8_YUV422_DENOIsE_iUVsupport [15:8]*/
+ 0x0F128001, /*AFIT8_YUV422_DENOIsE_iYsupport [7:0],
+ AFIT8_byr_cgras_ishadingPower [15:8]*/
+ 0x0F120080, /*AFIT8_RGBGamma2_iLinearity [7:0],
+ AFIT8_RGBGamma2_iDarkReduce [15:8]*/
+ 0x0F120080, /*AFIT8_ccm_oscar_isaturation[7:0],
+ AFIT8_RGB2YUV_iYOffset [15:8]*/
+ 0x0F120080, /*AFIT8_RGB2YUV_iRGBGain [7:0],
+ AFIT8_RGB2YUV_isaturation [15:8]*/
+ 0x0F125050, /*AFIT8_sddd8a_iClustThresh_H [7:0],
+ AFIT8_sddd8a_iClustThresh_C [15:8]*/
+ 0x0F120101, /*AFIT8_sddd8a_iClustMulT_H [7:0],
+ AFIT8_sddd8a_iClustMulT_C [15:8]*/
+ 0x0F121B01, /*AFIT8_sddd8a_nClustLevel_H [7:0],
+ AFIT8_sddd8a_DispTH_Low [15:8]*/
+ 0x0F121219, /*AFIT8_sddd8a_DispTH_High [7:0],
+ AFIT8_sddd8a_iDenThreshLow [15:8]*/
+ 0x0F12320D, /*AFIT8_sddd8a_iDenThreshHigh[7:0],
+ AFIT8_Demosaicing_iEdgeDesat [15:8]*/
+ 0x0F120A0A, /*AFIT8_Demosaicing_iEdgeDesatThrLow [7:0],
+ AFIT8_Demosaicing_iEdgeDesatThrHigh [15:8]*/
+ 0x0F122304, /*AFIT8_Demosaicing_iEdgeDesatLimit[7:0],
+ AFIT8_Demosaicing_iDemsharpenLow [15:8]*/
+ 0x0F120A08, /*AFIT8_Demosaicing_iDemsharpenHigh[7:0],
+ AFIT8_Demosaicing_iDemsharpThresh [15:8]*/
+ 0x0F120832, /*AFIT8_Demosaicing_iDemshLowLimit [7:0],
+ AFIT8_Demosaicing_iDespeckleForDemsharp [15:8]*/
+ 0x0F121432, /*AFIT8_Demosaicing_iDemBlurLow[7:0],
+ AFIT8_Demosaicing_iDemBlurHigh [15:8]*/
+ 0x0F12A001, /*AFIT8_Demosaicing_iDemBlurRange[7:0],
+ AFIT8_sharpening_iLowsharpPower [15:8]*/
+ 0x0F122A0A, /*AFIT8_sharpening_iHighsharpPower[7:0],
+ AFIT8_sharpening_iLowshDenoise [15:8]*/
+ 0x0F124006, /*AFIT8_sharpening_iHighshDenoise [7:0],
+ AFIT8_sharpening_iReduceEdgeMinMult [15:8]*/
+ 0x0F120604, /*AFIT8_sharpening_iReduceEdgeslope [7:0],
+ AFIT8_demsharpmix1_iWideFiltReduce [15:8]*/
+ 0x0F125006, /*AFIT8_demsharpmix1_iNarrFiltReduce [7:0],
+ AFIT8_sddd8a_iClustThresh_H_Bin [15:8]*/
+ 0x0F120150, /*AFIT8_sddd8a_iClustThresh_C_Bin [7:0],
+ AFIT8_sddd8a_iClustMulT_H_Bin [15:8]*/
+ 0x0F120101, /*AFIT8_sddd8a_iClustMulT_C_Bin [7:0],
+ AFIT8_sddd8a_nClustLevel_H_Bin [15:8]*/
+ 0x0F12191B, /*AFIT8_sddd8a_DispTH_Low_Bin [7:0],
+ AFIT8_sddd8a_DispTH_High_Bin [15:8]*/
+ 0x0F12070C, /*0F19 AFIT8_sddd8a_iDenThreshLow_Bin [7:0],
+ AFIT8_sddd8a_iDenThreshHigh_Bin [15:8]*/
+ 0x0F120A28, /*AFIT8_Demosaicing_iEdgeDesat_Bin[7:0],
+ AFIT8_Demosaicing_iEdgeDesatThrLow_Bin [15:8]*/
+ 0x0F12040A, /*AFIT8_Demosaicing_iEdgeDesatThrHigh_Bin [7:0],
+ AFIT8_Demosaicing_iEdgeDesatLimit_Bin [15:8]*/
+ 0x0F120820, /*AFIT8_Demosaicing_iDemsharpenLow_Bin [7:0],
+ AFIT8_Demosaicing_iDemsharpenHigh_Bin [15:8]*/
+ 0x0F12280A, /*AFIT8_Demosaicing_iDemsharpThresh_Bin [7:0],
+ AFIT8_Demosaicing_iDemshLowLimit_Bin [15:8]*/
+ 0x0F123208, /*AFIT8_Demosaicing_iDespeckleForDemsharp_Bin [7:0],
+ AFIT8_Demosaicing_iDemBlurLow_Bin [15:8]*/
+ 0x0F120114, /*AFIT8_Demosaicing_iDemBlurHigh_Bin [7:0],
+ AFIT8_Demosaicing_iDemBlurRange_Bin [15:8]*/
+ 0x0F120532, /*0A64 AFIT8_Sharpening_iLowsharpPower_Bin [7:0],
+ AFIT8_sharpening_iHighsharpPower_Bin [15:8]*/
+ 0x0F12062A, /*AFIT8_Sharpening_iLowShDenoise_Bin [7:0],
+ AFIT8_sharpening_iHighshDenoise_Bin [15:8]*/
+ 0x0F120440, /*AFIT8_Sharpening_iReduceEdgeMinMult_Bin [7:0],
+ AFIT8_sharpening_iReduceEdgeslope_Bin [15:8]*/
+ 0x0F120606, /*AFIT8_demsharpmix1_iWideFiltReduce_Bin [7:0],
+ AFIT8_demsharpmix1_iNarrFiltReduce_Bin [15:8]*/
+ 0x0F124646, /*AFIT8_sddd8a_iClustThresh_H_sBin[7:0],
+ AFIT8_sddd8a_iClustThresh_C_sBin [15:8]*/
+ 0x0F120101, /*AFIT8_sddd8a_iClustMulT_H_sBin [7:0],
+ AFIT8_sddd8a_iClustMulT_C_sBin [15:8]*/
+ 0x0F121801, /*AFIT8_sddd8a_nClustLevel_H_sBin [7:0],
+ AFIT8_sddd8a_DispTH_Low_sBin [15:8]*/
+ 0x0F12191C, /*AFIT8_sddd8a_DispTH_High_sBin [7:0],
+ AFIT8_sddd8a_iDenThreshLow_sBin [15:8]*/
+ 0x0F122818, /*AFIT8_sddd8a_iDenThreshHigh_sBin[7:0],
+ AFIT8_Demosaicing_iEdgeDesat_sBin [15:8]*/
+ 0x0F120A00, /*AFIT8_Demosaicing_iEdgeDesatThrLow_sBin [7:0],
+ AFIT8_Demosaicing_iEdgeDesatThrHigh_sBin [15:8]*/
+ 0x0F121403, /*AFIT8_Demosaicing_iEdgeDesatLimit_sBin [7:0],
+ AFIT8_Demosaicing_iDemsharpenLow_sBin [15:8]*/
+ 0x0F121405, /*AFIT8_Demosaicing_iDemsharpenHigh_sBin [7:0],
+ AFIT8_Demosaicing_iDemsharpThresh_sBin [15:8]*/
+ 0x0F12050C, /*AFIT8_Demosaicing_iDemshLowLimit_sBin [7:0],
+ AFIT8_Demosaicing_iDespeckleForDemsharp_sBin [15:8]*/
+ 0x0F1232FF, /*AFIT8_Demosaicing_iDemBlurLow_sBin [7:0],
+ AFIT8_Demosaicing_iDemBlurHigh_sBin [15:8]*/
+ 0x0F125204, /*AFIT8_Demosaicing_iDemBlurRange_sBin [7:0],
+ AFIT8_sharpening_iLowsharpPower_sBin [15:8]*/
+ 0x0F121440, /*AFIT8_sharpening_iHighsharpPower_sBin [7:0],
+ AFIT8_sharpening_iLowshDenoise_sBin [15:8]*/
+ 0x0F124015, /*AFIT8_sharpening_iHighshDenoise_sBin [7:0],
+ AFIT8_sharpening_iReduceEdgeMinMult_sBin [15:8]*/
+ 0x0F120204, /*AFIT8_sharpening_iReduceEdgeslope_sBin [7:0],
+ AFIT8_demsharpmix1_iWideFiltReduce_sBin [15:8]*/
+ 0x0F120003, /*AFIT8_demsharpmix1_iNarrFiltReduce_sBin [7:0]*/
+ 0x0F127DFA, /*ConstAfitBaseVals*/
+ 0x0F12FFBD, /*ConstAfitBaseVals_1_*/
+ 0x0F1226FE, /*ConstAfitBaseVals_2_*/
+ 0x0F12F7BC, /*ConstAfitBaseVals_3_*/
+ 0x0F127E06, /*ConstAfitBaseVals_4_*/
+ 0x0F1200D3, /*ConstAfitBaseVals_5_*/
+ 0x002A0156,
+ 0x0F120000, /*REG_TC_GP_ActivePrevConfig*/
+ 0x002A015E,
+ 0x0F120000, /*REG_TC_GP_ActiveCapConfig*/
+ 0x002A015A,
+ 0x0F120001, /*REG_TC_GP_PrevOpenAfterChange*/
+ 0x002A0142,
+ 0x0F120001, /*REG_TC_GP_NewConfigSync*/
+ 0x002A0158,
+ 0x0F120001, /*REG_TC_GP_PrevConfigChanged*/
+ 0x002A0160,
+ 0x0F120001, /*REG_TC_GP_CapConfigChanged*/
+ 0x002A013A,
+ 0x0F120001, /*REG_TC_GP_EnablePreview*/
+ 0x0F120001, /*REG_TC_GP_EnablePreviewChanged*/
+ 0xFFFF0096,
+
+};
+
+/* Set-data based on SKT VT standard ,when using 3G network
+* 8fps
+*/
+static const u32 s5k5bbgx_vt_common[] = {
+ 0xFCFCD000,
+ 0x00100001, /*sw_reset*/
+ /*For divided ARM CLK 1/2*/
+ /*WRITE D00000A0 0000*/
+ 0x10300000, /*contint_host_int*/
+ 0x00140001, /*sw_load_complete-Release CORE (Arm) from reset state*/
+ 0x01520084, /*make alive voltage low*/
+ 0xFFFF000A,
+ /* Start of Patch data*/
+ 0x00287000,
+ 0x002A2744,
+ 0x0F12B510, /* 70002744*/
+ 0x0F124A12, /* 70002746*/
+ 0x0F12217B, /* 70002748*/
+ 0x0F124812, /* 7000274A*/
+ 0x0F12C004, /* 7000274C*/
+ 0x0F126001, /* 7000274E*/
+ 0x0F124911, /* 70002750*/
+ 0x0F124812, /* 70002752*/
+ 0x0F12F000, /* 70002754*/
+ 0x0F12F926, /* 70002756*/
+ 0x0F124911, /* 70002758*/
+ 0x0F124812, /* 7000275A*/
+ 0x0F12F000, /* 7000275C*/
+ 0x0F12F922, /* 7000275E*/
+ 0x0F124911, /* 70002760*/
+ 0x0F124812, /* 70002762*/
+ 0x0F12F000, /* 70002764*/
+ 0x0F12F91E, /* 70002766*/
+ 0x0F124911, /* 70002768*/
+ 0x0F124812, /* 7000276A*/
+ 0x0F12F000, /* 7000276C*/
+ 0x0F12F91A, /* 7000276E*/
+ 0x0F124911, /* 70002770*/
+ 0x0F124812, /* 70002772*/
+ 0x0F12F000, /* 70002774*/
+ 0x0F12F916, /* 70002776*/
+ 0x0F124911, /* 70002778*/
+ 0x0F124812, /* 7000277A*/
+ 0x0F12F000, /* 7000277C*/
+ 0x0F12F912, /* 7000277E*/
+ 0x0F124911, /* 70002780*/
+ 0x0F124812, /* 70002782*/
+ 0x0F12F000, /* 70002784*/
+ 0x0F12F90E, /* 70002786*/
+ 0x0F12BC10, /* 70002788*/
+ 0x0F12BC08, /* 7000278A*/
+ 0x0F124718, /* 7000278C*/
+ 0x0F120000, /* 7000278E*/
+ 0x0F120000, /* 70002790*/
+ 0x0F125BB1, /* 70002792*/
+ 0x0F121770, /* 70002794*/
+ 0x0F127000, /* 70002796*/
+ 0x0F1227D1, /* 70002798*/
+ 0x0F127000, /* 7000279A*/
+ 0x0F12C0BB, /* 7000279C*/
+ 0x0F120000, /* 7000279E*/
+ 0x0F12280F, /* 700027A0*/
+ 0x0F127000, /* 700027A2*/
+ 0x0F123609, /* 700027A4*/
+ 0x0F120000, /* 700027A6*/
+ 0x0F122827, /* 700027A8*/
+ 0x0F127000, /* 700027AA*/
+ 0x0F1277C7, /* 700027AC*/
+ 0x0F120000, /* 700027AE*/
+ 0x0F1228B3, /* 700027B0*/
+ 0x0F127000, /* 700027B2*/
+ 0x0F12727D, /* 700027B4*/
+ 0x0F120000, /* 700027B6*/
+ 0x0F1228CD, /* 700027B8*/
+ 0x0F127000, /* 700027BA*/
+ 0x0F129919, /* 700027BC*/
+ 0x0F120000, /* 700027BE*/
+ 0x0F12290B, /* 700027C0*/
+ 0x0F127000, /* 700027C2*/
+ 0x0F121C63, /* 700027C4*/
+ 0x0F120000, /* 700027C6*/
+ 0x0F12296B, /* 700027C8*/
+ 0x0F127000, /* 700027CA*/
+ 0x0F1204CB, /* 700027CC*/
+ 0x0F120000, /* 700027CE*/
+ 0x0F12B4F0, /* 700027D0*/
+ 0x0F126801, /* 700027D2*/
+ 0x0F12468C, /* 700027D4*/
+ 0x0F126846, /* 700027D6*/
+ 0x0F122200, /* 700027D8*/
+ 0x0F124968, /* 700027DA*/
+ 0x0F122000, /* 700027DC*/
+ 0x0F122724, /* 700027DE*/
+ 0x0F124357, /* 700027E0*/
+ 0x0F12183B, /* 700027E2*/
+ 0x0F124664, /* 700027E4*/
+ 0x0F125CE5, /* 700027E6*/
+ 0x0F12005C, /* 700027E8*/
+ 0x0F125B34, /* 700027EA*/
+ 0x0F12072D, /* 700027EC*/
+ 0x0F120F2D, /* 700027EE*/
+ 0x0F12800D, /* 700027F0*/
+ 0x0F12804C, /* 700027F2*/
+ 0x0F12808B, /* 700027F4*/
+ 0x0F122301, /* 700027F6*/
+ 0x0F1280CB, /* 700027F8*/
+ 0x0F122300, /* 700027FA*/
+ 0x0F1280CB, /* 700027FC*/
+ 0x0F121C40, /* 700027FE*/
+ 0x0F122824, /* 70002800*/
+ 0x0F12D3EE, /* 70002802*/
+ 0x0F121C52, /* 70002804*/
+ 0x0F122A04, /* 70002806*/
+ 0x0F12D3E8, /* 70002808*/
+ 0x0F12BCF0, /* 7000280A*/
+ 0x0F124770, /* 7000280C*/
+ 0x0F12B510, /* 7000280E*/
+ 0x0F12F000, /* 70002810*/
+ 0x0F12F8D0, /* 70002812*/
+ 0x0F12485A, /* 70002814*/
+ 0x0F127A81, /* 70002816*/
+ 0x0F12485A, /* 70002818*/
+ 0x0F126B00, /* 7000281A*/
+ 0x0F12F000, /* 7000281C*/
+ 0x0F12F8D2, /* 7000281E*/
+ 0x0F12BC10, /* 70002820*/
+ 0x0F12BC08, /* 70002822*/
+ 0x0F124718, /* 70002824*/
+ 0x0F12B5F8, /* 70002826*/
+ 0x0F126805, /* 70002828*/
+ 0x0F126844, /* 7000282A*/
+ 0x0F124E56, /* 7000282C*/
+ 0x0F128861, /* 7000282E*/
+ 0x0F128AB0, /* 70002830*/
+ 0x0F128A72, /* 70002832*/
+ 0x0F122301, /* 70002834*/
+ 0x0F124368, /* 70002836*/
+ 0x0F121889, /* 70002838*/
+ 0x0F1217C2, /* 7000283A*/
+ 0x0F120E12, /* 7000283C*/
+ 0x0F121810, /* 7000283E*/
+ 0x0F121202, /* 70002840*/
+ 0x0F128820, /* 70002842*/
+ 0x0F12029B, /* 70002844*/
+ 0x0F1218C0, /* 70002846*/
+ 0x0F12F000, /* 70002848*/
+ 0x0F12F8C4, /* 7000284A*/
+ 0x0F129000, /* 7000284C*/
+ 0x0F128AF6, /* 7000284E*/
+ 0x0F124268, /* 70002850*/
+ 0x0F12210A, /* 70002852*/
+ 0x0F124370, /* 70002854*/
+ 0x0F12F000, /* 70002856*/
+ 0x0F12F8C5, /* 70002858*/
+ 0x0F12436E, /* 7000285A*/
+ 0x0F120007, /* 7000285C*/
+ 0x0F12210A, /* 7000285E*/
+ 0x0F120030, /* 70002860*/
+ 0x0F12F000, /* 70002862*/
+ 0x0F12F8BF, /* 70002864*/
+ 0x0F129A00, /* 70002866*/
+ 0x0F120039, /* 70002868*/
+ 0x0F12F000, /* 7000286A*/
+ 0x0F12F8C1, /* 7000286C*/
+ 0x0F120002, /* 7000286E*/
+ 0x0F128820, /* 70002870*/
+ 0x0F121880, /* 70002872*/
+ 0x0F128020, /* 70002874*/
+ 0x0F124845, /* 70002876*/
+ 0x0F1288C1, /* 70002878*/
+ 0x0F124843, /* 7000287A*/
+ 0x0F123820, /* 7000287C*/
+ 0x0F128B40, /* 7000287E*/
+ 0x0F124240, /* 70002880*/
+ 0x0F124350, /* 70002882*/
+ 0x0F12F000, /* 70002884*/
+ 0x0F12F8AE, /* 70002886*/
+ 0x0F128861, /* 70002888*/
+ 0x0F121840, /* 7000288A*/
+ 0x0F128060, /* 7000288C*/
+ 0x0F12BCF8, /* 7000288E*/
+ 0x0F12BC08, /* 70002890*/
+ 0x0F124718, /* 70002892*/
+ 0x0F12B570, /* 70002894*/
+ 0x0F124C3C, /* 70002896*/
+ 0x0F123C20, /* 70002898*/
+ 0x0F128B20, /* 7000289A*/
+ 0x0F12F000, /* 7000289C*/
+ 0x0F12F8B0, /* 7000289E*/
+ 0x0F124D3A, /* 700028A0*/
+ 0x0F1280E8, /* 700028A2*/
+ 0x0F128B60, /* 700028A4*/
+ 0x0F12F000, /* 700028A6*/
+ 0x0F12F8B3, /* 700028A8*/
+ 0x0F128128, /* 700028AA*/
+ 0x0F12BC70, /* 700028AC*/
+ 0x0F12BC08, /* 700028AE*/
+ 0x0F124718, /* 700028B0*/
+ 0x0F12B510, /* 700028B2*/
+ 0x0F124836, /* 700028B4*/
+ 0x0F12214D, /* 700028B6*/
+ 0x0F128201, /* 700028B8*/
+ 0x0F122196, /* 700028BA*/
+ 0x0F128281, /* 700028BC*/
+ 0x0F12211D, /* 700028BE*/
+ 0x0F128301, /* 700028C0*/
+ 0x0F12F7FF, /* 700028C2*/
+ 0x0F12FFE7, /* 700028C4*/
+ 0x0F12F000, /* 700028C6*/
+ 0x0F12F8AB, /* 700028C8*/
+ 0x0F12E7A9, /* 700028CA*/
+ 0x0F12B570, /* 700028CC*/
+ 0x0F120004, /* 700028CE*/
+ 0x0F126820, /* 700028D0*/
+ 0x0F126865, /* 700028D2*/
+ 0x0F12F000, /* 700028D4*/
+ 0x0F12F8AC, /* 700028D6*/
+ 0x0F120402, /* 700028D8*/
+ 0x0F12482E, /* 700028DA*/
+ 0x0F120C12, /* 700028DC*/
+ 0x0F128142, /* 700028DE*/
+ 0x0F12482D, /* 700028E0*/
+ 0x0F128801, /* 700028E2*/
+ 0x0F122900, /* 700028E4*/
+ 0x0F12D008, /* 700028E6*/
+ 0x0F12492C, /* 700028E8*/
+ 0x0F12002B, /* 700028EA*/
+ 0x0F126D8A, /* 700028EC*/
+ 0x0F122105, /* 700028EE*/
+ 0x0F121C80, /* 700028F0*/
+ 0x0F12F000, /* 700028F2*/
+ 0x0F12F8A5, /* 700028F4*/
+ 0x0F126020, /* 700028F6*/
+ 0x0F12E005, /* 700028F8*/
+ 0x0F124829, /* 700028FA*/
+ 0x0F12002B, /* 700028FC*/
+ 0x0F122105, /* 700028FE*/
+ 0x0F12F000, /* 70002900*/
+ 0x0F12F89E, /* 70002902*/
+ 0x0F126020, /* 70002904*/
+ 0x0F126820, /* 70002906*/
+ 0x0F12E7D0, /* 70002908*/
+ 0x0F12B5F8, /* 7000290A*/
+ 0x0F124923, /* 7000290C*/
+ 0x0F122200, /* 7000290E*/
+ 0x0F123160, /* 70002910*/
+ 0x0F1283CA, /* 70002912*/
+ 0x0F126800, /* 70002914*/
+ 0x0F124669, /* 70002916*/
+ 0x0F12F000, /* 70002918*/
+ 0x0F12F89A, /* 7000291A*/
+ 0x0F12466B, /* 7000291C*/
+ 0x0F128818, /* 7000291E*/
+ 0x0F12F000, /* 70002920*/
+ 0x0F12F86E, /* 70002922*/
+ 0x0F120005, /* 70002924*/
+ 0x0F12466B, /* 70002926*/
+ 0x0F128858, /* 70002928*/
+ 0x0F12F000, /* 7000292A*/
+ 0x0F12F871, /* 7000292C*/
+ 0x0F120004, /* 7000292E*/
+ 0x0F122101, /* 70002930*/
+ 0x0F121928, /* 70002932*/
+ 0x0F1202C9, /* 70002934*/
+ 0x0F121A08, /* 70002936*/
+ 0x0F120286, /* 70002938*/
+ 0x0F120029, /* 7000293A*/
+ 0x0F120030, /* 7000293C*/
+ 0x0F12F000, /* 7000293E*/
+ 0x0F12F88F, /* 70002940*/
+ 0x0F120005, /* 70002942*/
+ 0x0F122701, /* 70002944*/
+ 0x0F1202BF, /* 70002946*/
+ 0x0F120021, /* 70002948*/
+ 0x0F120030, /* 7000294A*/
+ 0x0F12F000, /* 7000294C*/
+ 0x0F12F888, /* 7000294E*/
+ 0x0F124912, /* 70002950*/
+ 0x0F124A0E, /* 70002952*/
+ 0x0F123140, /* 70002954*/
+ 0x0F123AC0, /* 70002956*/
+ 0x0F12800D, /* 70002958*/
+ 0x0F128395, /* 7000295A*/
+ 0x0F12804F, /* 7000295C*/
+ 0x0F1283D7, /* 7000295E*/
+ 0x0F128088, /* 70002960*/
+ 0x0F120011, /* 70002962*/
+ 0x0F123120, /* 70002964*/
+ 0x0F128008, /* 70002966*/
+ 0x0F12E791, /* 70002968*/
+ 0x0F12B510, /* 7000296A*/
+ 0x0F12480A, /* 7000296C*/
+ 0x0F128980, /* 7000296E*/
+ 0x0F122800, /* 70002970*/
+ 0x0F12D001, /* 70002972*/
+ 0x0F12F000, /* 70002974*/
+ 0x0F12F87A, /* 70002976*/
+ 0x0F12E752, /* 70002978*/
+ 0x0F120000, /* 7000297A*/
+ 0x0F124140, /* 7000297C*/
+ 0x0F12D000, /* 7000297E*/
+ 0x0F1219DC, /* 70002980*/
+ 0x0F127000, /* 70002982*/
+ 0x0F121B60, /* 70002984*/
+ 0x0F127000, /* 70002986*/
+ 0x0F120DD4, /* 70002988*/
+ 0x0F127000, /* 7000298A*/
+ 0x0F1222AC, /* 7000298C*/
+ 0x0F127000, /* 7000298E*/
+ 0x0F121E8C, /* 70002990*/
+ 0x0F127000, /* 70002992*/
+ 0x0F121A10, /* 70002994*/
+ 0x0F127000, /* 70002996*/
+ 0x0F123780, /* 70002998*/
+ 0x0F127000, /* 7000299A*/
+ 0x0F122384, /* 7000299C*/
+ 0x0F127000, /* 7000299E*/
+ 0x0F12065C, /* 700029A0*/
+ 0x0F127000, /* 700029A2*/
+ 0x0F124778, /* 700029A4*/
+ 0x0F1246C0, /* 700029A6*/
+ 0x0F12C000, /* 700029A8*/
+ 0x0F12E59F, /* 700029AA*/
+ 0x0F12FF1C, /* 700029AC*/
+ 0x0F12E12F, /* 700029AE*/
+ 0x0F12CE77, /* 700029B0*/
+ 0x0F120000, /* 700029B2*/
+ 0x0F124778, /* 700029B4*/
+ 0x0F1246C0, /* 700029B6*/
+ 0x0F12C000, /* 700029B8*/
+ 0x0F12E59F, /* 700029BA*/
+ 0x0F12FF1C, /* 700029BC*/
+ 0x0F12E12F, /* 700029BE*/
+ 0x0F123609, /* 700029C0*/
+ 0x0F120000, /* 700029C2*/
+ 0x0F124778, /* 700029C4*/
+ 0x0F1246C0, /* 700029C6*/
+ 0x0F12C000, /* 700029C8*/
+ 0x0F12E59F, /* 700029CA*/
+ 0x0F12FF1C, /* 700029CC*/
+ 0x0F12E12F, /* 700029CE*/
+ 0x0F129F91, /* 700029D0*/
+ 0x0F120000, /* 700029D2*/
+ 0x0F124778, /* 700029D4*/
+ 0x0F1246C0, /* 700029D6*/
+ 0x0F12C000, /* 700029D8*/
+ 0x0F12E59F, /* 700029DA*/
+ 0x0F12FF1C, /* 700029DC*/
+ 0x0F12E12F, /* 700029DE*/
+ 0x0F122AE3, /* 700029E0*/
+ 0x0F120000, /* 700029E2*/
+ 0x0F124778, /* 700029E4*/
+ 0x0F1246C0, /* 700029E6*/
+ 0x0F12F004, /* 700029E8*/
+ 0x0F12E51F, /* 700029EA*/
+ 0x0F12D1DC, /* 700029EC*/
+ 0x0F120000, /* 700029EE*/
+ 0x0F124778, /* 700029F0*/
+ 0x0F1246C0, /* 700029F2*/
+ 0x0F12C000, /* 700029F4*/
+ 0x0F12E59F, /* 700029F6*/
+ 0x0F12FF1C, /* 700029F8*/
+ 0x0F12E12F, /* 700029FA*/
+ 0x0F126869, /* 700029FC*/
+ 0x0F120000, /* 700029FE*/
+ 0x0F124778, /* 70002A00*/
+ 0x0F1246C0, /* 70002A02*/
+ 0x0F12C000, /* 70002A04*/
+ 0x0F12E59F, /* 70002A06*/
+ 0x0F12FF1C, /* 70002A08*/
+ 0x0F12E12F, /* 70002A0A*/
+ 0x0F1268BD, /* 70002A0C*/
+ 0x0F120000, /* 70002A0E*/
+ 0x0F124778, /* 70002A10*/
+ 0x0F1246C0, /* 70002A12*/
+ 0x0F12C000, /* 70002A14*/
+ 0x0F12E59F, /* 70002A16*/
+ 0x0F12FF1C, /* 70002A18*/
+ 0x0F12E12F, /* 70002A1A*/
+ 0x0F1268DB, /* 70002A1C*/
+ 0x0F120000, /* 70002A1E*/
+ 0x0F124778, /* 70002A20*/
+ 0x0F1246C0, /* 70002A22*/
+ 0x0F12C000, /* 70002A24*/
+ 0x0F12E59F, /* 70002A26*/
+ 0x0F12FF1C, /* 70002A28*/
+ 0x0F12E12F, /* 70002A2A*/
+ 0x0F1271B9, /* 70002A2C*/
+ 0x0F120000, /* 70002A2E*/
+ 0x0F124778, /* 70002A30*/
+ 0x0F1246C0, /* 70002A32*/
+ 0x0F12C000, /* 70002A34*/
+ 0x0F12E59F, /* 70002A36*/
+ 0x0F12FF1C, /* 70002A38*/
+ 0x0F12E12F, /* 70002A3A*/
+ 0x0F1298CD, /* 70002A3C*/
+ 0x0F120000, /* 70002A3E*/
+ 0x0F124778, /* 70002A40*/
+ 0x0F1246C0, /* 70002A42*/
+ 0x0F12C000, /* 70002A44*/
+ 0x0F12E59F, /* 70002A46*/
+ 0x0F12FF1C, /* 70002A48*/
+ 0x0F12E12F, /* 70002A4A*/
+ 0x0F12987F, /* 70002A4C*/
+ 0x0F120000, /* 70002A4E*/
+ 0x0F124778, /* 70002A50*/
+ 0x0F1246C0, /* 70002A52*/
+ 0x0F12C000, /* 70002A54*/
+ 0x0F12E59F, /* 70002A56*/
+ 0x0F12FF1C, /* 70002A58*/
+ 0x0F12E12F, /* 70002A5A*/
+ 0x0F121BC9, /* 70002A5C*/
+ 0x0F120000, /* 70002A5E*/
+ 0x0F124778, /* 70002A60*/
+ 0x0F1246C0, /* 70002A62*/
+ 0x0F12F004, /* 70002A64*/
+ 0x0F12E51F, /* 70002A66*/
+ 0x0F12D378, /* 70002A68*/
+ 0x0F120000, /* 70002A6A*/
+ 0x0F124778, /* 70002A6C*/
+ 0x0F1246C0, /* 70002A6E*/
+ 0x0F12C000, /* 70002A70*/
+ 0x0F12E59F, /* 70002A72*/
+ 0x0F12FF1C, /* 70002A74*/
+ 0x0F12E12F, /* 70002A76*/
+ 0x0F1204CB, /* 70002A78*/
+ 0x0F120000, /* 70002A7A*/
+ /* End of Patch Data(Last : 70002A7Ah)*/
+ /* This parameter should be set before HOST command interrupt
+ * (1000 0001)*/
+ 0x002A378C,
+ 0x0F120000, /* On/off register bUseOTP*/
+ 0x002A0DCC,
+ 0x0F120138, /*awbb_IntcR*/
+ 0x0F12011C, /*awbb_IntcB*/
+ /*===================================================================*/
+ /*Analog & APS Control*/
+ /*===================================================================*/
+ 0x0028D000,
+ 0x002AF404,
+ 0x0F120038, /* aig_adc_sat[7:0] : 850mV, revised by Ana 20100524*/
+ 0x0F120001, /* aig_ms[2:0] : revised by Ana 20100202*/
+ 0x0F12000C, /* aig_sig_mx[5:0]*/
+ 0x0F120006, /* aig_rst_mx[5:0]*/
+ 0x0F120008, /* aig_rmp_option[3] SL_Low_PWR_SAVE On :
+ revised by Ana 20100204*/
+ 0x002AF418,
+ 0x0F120003, /* aig_dbr_clk_sel[1:0] : revised by Ana 20100201*/
+ 0x002AF41C,
+ 0x0F120140, /* aig_bist_sig_width_e[10:0]*/
+ 0x0F120140, /* aig_bist_sig_width_o[10:0]*/
+ 0x0F120066, /* aig_bist_sig_width_o[10:0]*/
+ 0x0F120005, /* aig_pix_bias[3:0]*/
+ 0x002AF426,
+ 0x0F1200D4, /* aig_clp_lvl[7:0]*/
+ 0x002AF42A,
+ 0x0F120001, /* aig_ref_option[0] SL_Low_PWR_SAVE On :
+ revised by Ana 20100204*/
+ 0x002AF430,
+ 0x0F120001, /* aig_pd_cp_rosc[0] : revised by Ana 20100201*/
+ 0x0F120001, /* aig_pd_ncp_rosc[0] : revised by Ana 20100201*/
+ 0x002AF43A,
+ 0x0F120000, /* aig_pd_fblv[0] : revised by Ana 20100203*/
+ 0x002AF440,
+ 0x0F120044, /* aig_rosc_tune_ncp[7:4]*/
+ /* aig_rosc_tune_cp[3:0]*/
+ 0x002AF44A,
+ 0x0F120000, /* aig_fb_lv[1:0] : revised by Ana 20100204*/
+ 0x002AF45C,
+ 0x0F120000, /* aig_dshut_en[0] : revised by APS 20100223*/
+ 0x0F120000, /* aig_srx_en[0]*/
+ 0x002AF462,
+ 0x0F120001, /* aig_pdb_atop[0]*/
+ 0x002AF46E,
+ 0x0F121F02, /* aig_cds_test[15:0]*/
+ 0x002AF474,
+ 0x0F12000E, /* aig_stx_gap[4:0]*/
+ /*====================================================================*/
+ 0x002AE42E,
+ 0x0F120004, /* adlc_qec[2:0] : revised by
+ Dithered L-ADLC Designer 20100203*/
+ 0x00287000,
+ 0x002A13E0,
+ 0x0F120000, /*700013E0 SRX OFF*/
+ 0x002A13C8,
+ 0x0F120001, /*700013C8 AAC Enable*/
+ 0x002A12D8,
+ 0x0F120464, /*700012d8*/
+ 0x0F120468, /*700012da*/
+ 0x002A12F6,
+ 0x0F120000, /*700012f6*/
+ 0x002A13CC,
+ 0x0F121FC0, /* [12:0] : Write tuning value to E404 register*/
+ 0x002A13EC,
+ 0x0F120001,
+ 0x002A184C,
+ 0x0F121EE1,
+ 0x0028D000,
+ 0x002A1000,
+ 0x0F120001,
+ 0x00287000,
+ 0x002A040E,
+ 0x0F120003, /*STBY TnP enable setting STBY TnP enable setting [0]
+ bit STBY enable,[1] bit STBY ø TnP ? on/off bit*/
+ 0xFFFF000A,
+ /*H-Digital binning & V-PLA*/
+ 0x002A1218,
+ 0x0F120002, /*subsampling number.*/
+ 0x0F120002, /*subsampling number.*/
+ 0x002A0C9A,
+ 0x0F120001, /* setot_bUseDigitalHbin 0 : do not use bin block*/
+ 0x002A1438,
+ 0x0F12F468, /* senHal_TuneStr_AngTuneData1[0] : tuning register
+ setting.*/
+ 0x0F120000, /* not use binninb block 0x0000 ,use binnin blcok
+ 0x0000*/
+ 0x0F120008, /* not use binninb block 0x000A ,use binnin blcok
+ 0x0008*/
+ 0x0F120006, /* not use binninb block 0x0005 ,use binnin blcok
+ 0x0006*/
+ 0x0F120000, /* 0x0000 , 0x0000*/
+ 0xFFFF000A,
+ 0x002A0416,
+ 0x0F12F400,
+ 0x0F120074,
+ 0x0F12E42E,
+ 0x0F120030,
+ /*clk Settings*/
+ 0x00287000,
+ 0x002A00F4,
+ 0x0F125DC0, /*REG_TC_IPRM_InClockLSBs 2 700000F4*/
+ 0x002A0110,
+ 0x0F120003, /*REG_TC_IPRM_UseNPviClocks 2 70000110*/
+ 0x0F120000, /*REG_TC_IPRM_bBlockInternalPllCalc 2 70000112*/
+ /*SYSTEM CLOCK*/
+ 0x0F12222E, /*REG_TC_IPRM_OpClk4KHz_0 2 70000114
+ 35000Khz/4=HEX()*/
+ 0x0F12445C, /*REG_TC_IPRM_MinOutRate4KHz_0 2 70000116*/
+ 0x0F12445C, /*REG_TC_IPRM_MaxOutRate4KHz_0 2 70000118*/
+ 0x0F121117, /*1770 REG_TC_IPRM_OpClk4KHz_1 2 7000011A
+ 24000Khz/4*/
+ 0x0F12222E, /*REG_TC_IPRM_MinOutRate4KHz_1 2 7000011C
+ 36000khz/4 =2328hex*/
+ 0x0F12222E, /*REG_TC_IPRM_MaxOutRate4KHz_1 2 7000011E*/
+ 0x0F120BB8, /*REG_TC_IPRM_OpClk4KHz_2 2 70000120
+ 12000Khz*/
+ 0x0F1205DC, /*REG_TC_IPRM_MinOutRate4KHz_2 2 70000122*/
+ 0x0F121770, /*REG_TC_IPRM_MaxOutRate4KHz_2 2 70000124*/
+ 0x0F120001, /*REG_TC_IPRM_InitParamsUpdated 2 70000126*/
+ 0xFFFF0064,
+ 0x002A1218,
+ 0x0F120002,
+ /*===================================================================*/
+ /*Preview0 1600x1200 system 32M PCLK 70M From APS*/
+ /*===================================================================*/
+ 0x002A0144,
+ 0x0F120640,
+ 0x0F1204B0,
+ 0x0F120000,
+ 0x0F120000,
+ /*Preview0 for 7.5~15fps*/
+ 0x002A0170,
+ 0x0F120280, /*REG_0TC_PCFG_usWidth 2 70000170*/
+ 0x0F1201e0, /*REG_0TC_PCFG_usHeight 2 70000172*/
+ 0x0F120005, /*REG_0TC_PCFG_Format 2 70000174*/
+ 0x0F12222E, /*REG_0TC_PCFG_usMaxOut4KHzRate 2 70000176*/
+ 0x0F12222E, /*REG_0TC_PCFG_usMinOut4KHzRate 2 70000178*/
+ 0x0F120042, /*REG_0TC_PCFG_PVIMask 2 7000017A*/
+ 0x0F120010, /*REG_0TC_PCFG_OIFMask 2 7000017C*/
+ 0x0F120001, /*REG_0TC_PCFG_uClockInd 2 7000017E*/
+ 0x0F120002, /*REG_0TC_PCFG_usFrTimeType 2 70000180
+ 0b : dynamic 01:fix not accurate 02b: fixed_Accurate*/
+ 0x0F120001, /*REG_0TC_PCFG_FrRateQualityType 2 70000182
+ 1b: FR (bin) 2b: Quality (no-bin)*/
+ 0x0F1204E2, /*REG_0TC_PCFG_usMaxFrTimeMsecMult10 2 70000184
+ max frame time : 30fps 014D 15fps 029a; a6a -
+ 3.75 fps; 0535 - 7.5FPS*/
+ 0x0F1204E2, /*REG_0TC_PCFG_usMinFrTimeMsecMult10 2 70000186*/
+ 0x0F120000, /*REG_0TC_PCFG_bSmearOutput 2 70000188*/
+ 0x0F120000, /*REG_0TC_PCFG_sSaturation 2 7000018A*/
+ 0x0F120000, /*REG_0TC_PCFG_sSharpBlur 2 7000018C*/
+ 0x0F120000, /*REG_0TC_PCFG_sColorTemp 2 7000018E*/
+ 0x0F120000, /*REG_0TC_PCFG_uDeviceGammaIndex 2 70000190*/
+ 0x0F120003, /*REG_0TC_PCFG_uPrevMirror 2 70000192*/
+ 0x0F120003, /*REG_0TC_PCFG_uCaptureMirror 2 70000194*/
+ 0x0F120000, /*REG_0TC_PCFG_uRotation 2 70000196*/
+ /*Preview1 for fixed 15fps*/
+ 0x0F120320, /*REG_1TC_PCFG_usWidth 2 70000198*/
+ 0x0F120258, /*REG_1TC_PCFG_usHeight 2 7000019A*/
+ 0x0F120005, /*REG_1TC_PCFG_Format 2 7000019C*/
+ 0x0F12222E, /*REG_1TC_PCFG_usMaxOut4KHzRate 2 7000019E*/
+ 0x0F12222E, /*REG_1TC_PCFG_usMinOut4KHzRate 2 700001A0*/
+ 0x0F120042, /*REG_1TC_PCFG_PVIMask 2 700001A2*/
+ 0x0F120010, /*REG_1TC_PCFG_OIFMask 2 700001A4*/
+ 0x0F120001, /*REG_1TC_PCFG_uClockInd 2 700001A6*/
+ 0x0F120000, /*REG_1TC_PCFG_usFrTimeType 2 700001A8*/
+ 0x0F120001, /*REG_1TC_PCFG_FrRateQualityType 2 700001AA*/
+ 0x0F12029A, /*REG_1TC_PCFG_usMaxFrTimeMsecMult10 2 700001AC*/
+ 0x0F12029A, /*REG_1TC_PCFG_usMinFrTimeMsecMult10 2 700001AE*/
+ 0x0F120000, /*REG_1TC_PCFG_bSmearOutput 2 700001B0*/
+ 0x0F120000, /*REG_1TC_PCFG_sSaturation 2 700001B2*/
+ 0x0F120000, /*REG_1TC_PCFG_sSharpBlur 2 700001B4*/
+ 0x0F120000, /*REG_1TC_PCFG_sColorTemp 2 700001B6*/
+ 0x0F120000, /*REG_1TC_PCFG_uDeviceGammaIndex 2 700001B8*/
+ 0x0F120003, /*REG_1TC_PCFG_uPrevMirror 2 700001BA*/
+ 0x0F120003, /*REG_1TC_PCFG_uCaptureMirror 2 700001BC*/
+ 0x0F120000, /*REG_1TC_PCFG_uRotation 2 700001BE*/
+ /*Preview2 for nightshot*/
+ 0x0F120320, /*REG_2TC_PCFG_usWidth 2 700001C0*/
+ 0x0F120258, /*REG_2TC_PCFG_usHeight 2 700001C2*/
+ 0x0F120005, /*REG_2TC_PCFG_Format 2 700001C4*/
+ 0x0F12222E, /*REG_2TC_PCFG_usMaxOut4KHzRate 2 700001C6*/
+ 0x0F12222E, /*REG_2TC_PCFG_usMinOut4KHzRate 2 700001C8*/
+ 0x0F120042, /*REG_2TC_PCFG_PVIMask 2 700001CA*/
+ 0x0F120010, /*REG_2TC_PCFG_OIFMask 2 700001CC*/
+ 0x0F120000, /*REG_2TC_PCFG_uClockInd 2 700001CE*/
+ 0x0F120000, /*REG_2TC_PCFG_usFrTimeType 2 700001D0*/
+ 0x0F120001, /*REG_2TC_PCFG_FrRateQualityType 2 700001D2
+ 1b: FR (bin) 2b: Quality (no-bin)*/
+ 0x0F12014D, /*REG_2TC_PCFG_usMaxFrTimeMsecMult10 2 700001D4
+ max frame time : 30fps 014D 15fps 029a; a6a -
+ 3.75 fps; 0535 - 7.5FPS*/
+ 0x0F12014D, /*REG_2TC_PCFG_usMinFrTimeMsecMult10 2 700001D6*/
+ 0x0F120000, /*REG_2TC_PCFG_bSmearOutput 2 700001D8*/
+ 0x0F120000, /*REG_2TC_PCFG_sSaturation 2 700001DA*/
+ 0x0F120000, /*REG_2TC_PCFG_sSharpBlur 2 700001DC*/
+ 0x0F120000, /*REG_2TC_PCFG_sColorTemp 2 700001DE*/
+ 0x0F120000, /*REG_2TC_PCFG_uDeviceGammaIndex 2 700001E0*/
+ 0x0F120003, /*REG_2TC_PCFG_uPrevMirror 2 700001E2
+ [0] : x [1]: Y [2] Stat X [3] Stat Y*/
+ 0x0F120003, /*REG_2TC_PCFG_uCaptureMirror 2 700001E4*/
+ 0x0F120000, /*REG_2TC_PCFG_uRotation 2 700001E6*/
+ 0x002A0238,
+ 0x0F120001, /*REG_0TC_CCFG_uCaptureMode 2 70000238*/
+ 0x0F120640, /*REG_0TC_CCFG_usWidth 2 7000023A*/
+ 0x0F1204B0, /*REG_0TC_CCFG_usHeight 2 7000023C*/
+ 0x0F120005, /*REG_0TC_CCFG_Format 2 7000023E*/
+ 0x0F12222E, /*REG_0TC_CCFG_usMaxOut4KHzRate 2 70000240*/
+ 0x0F12222E, /*REG_0TC_CCFG_usMinOut4KHzRate 2 70000242*/
+ 0x0F120042, /*REG_0TC_CCFG_PVIMask 2 70000244*/
+ 0x0F120000, /*REG_0TC_CCFG_OIFMask 2 70000246*/
+ 0x0F120001, /*REG_0TC_CCFG_uClockInd 2 70000248*/
+ 0x0F120000, /*REG_0TC_CCFG_usFrTimeType 2 7000024A*/
+ 0x0F120002, /*REG_0TC_CCFG_FrRateQualityType 2 7000024C*/
+ 0x0F1205D0, /*REG_0TC_CCFG_usMaxFrTimeMsecMult10 2 7000024E*/
+ 0x0F1204D0, /*REG_0TC_CCFG_usMinFrTimeMsecMult10 2 70000250*/
+ 0x0F120000, /*REG_0TC_CCFG_bSmearOutput 2 70000252*/
+ 0x0F120000, /*REG_0TC_CCFG_sSaturation 2 70000254*/
+ 0x0F120000, /*REG_0TC_CCFG_sSharpBlur 2 70000256*/
+ 0x0F120000, /*REG_0TC_CCFG_sColorTemp 2 70000258*/
+ 0x0F120000, /*REG_0TC_CCFG_uDeviceGammaIndex 2 7000025A*/
+ 0x0F120001, /*REG_1TC_CCFG_uCaptureMode 2 7000025C*/
+ 0x0F120640, /*REG_1TC_CCFG_usWidth 2 7000025E*/
+ 0x0F1204B0, /*REG_1TC_CCFG_usHeight 2 70000260*/
+ 0x0F120005, /*REG_1TC_CCFG_Format 2 70000262*/
+ 0x0F12222E, /*REG_1TC_CCFG_usMaxOut4KHzRate 2 70000264*/
+ 0x0F12222E, /*REG_1TC_CCFG_usMinOut4KHzRate 2 70000266*/
+ 0x0F120042, /*REG_1TC_CCFG_PVIMask 2 70000268*/
+ 0x0F120000, /*REG_1TC_CCFG_OIFMask 2 7000026A*/
+ 0x0F120001, /*REG_1TC_CCFG_uClockInd 2 7000026C*/
+ 0x0F120000, /*REG_1TC_CCFG_usFrTimeType 2 7000026E*/
+ 0x0F120002, /*REG_1TC_CCFG_FrRateQualityType 2 70000270*/
+ 0x0F121388, /*REG_1TC_CCFG_usMaxFrTimeMsecMult10 2 70000272*/
+ 0x0F121388, /*REG_1TC_CCFG_usMinFrTimeMsecMult10 2 70000274*/
+ 0x0F120000, /*REG_1TC_CCFG_bSmearOutput 2 70000276*/
+ 0x0F120000, /*REG_1TC_CCFG_sSaturation 2 70000278*/
+ 0x0F120000, /*REG_1TC_CCFG_sSharpBlur 2 7000027A*/
+ 0x0F120000, /*REG_1TC_CCFG_sColorTemp 2 7000027C*/
+ 0x0F120000, /*REG_1TC_CCFG_uDeviceGammaIndex 2 7000027E*/
+ 0x002A1218,
+ 0x0F120002,
+ /*PREVIEW*/
+ 0x002A0156,
+ 0x0F120000,
+ 0x002A015E,
+ 0x0F120000,
+ 0x002A015A,
+ 0x0F120001,
+ 0x002A0142,
+ 0x0F120001,
+ 0x002A0158,
+ 0x0F120001,
+ 0x002A0160,
+ 0x0F120001,
+ 0x002A013A,
+ 0x0F120001,
+ 0x0F120001,
+ 0xFFFF0064,
+ /*===================================================================*/
+ /*AFC*/
+ /*===================================================================*/
+ /*Auto*/
+ 0x00287000,
+ 0x002A0CC0,
+ 0x0F120001, /*AFC_Default60Hz 01:60hz 00:50Hz*/
+ 0x002A0374,
+ 0x0F12067F, /*REG_TC_DBG_AutoAlgEnBits*/
+ /*===================================================================*/
+ /*Shading*/
+ /*===================================================================*/
+ /* TVAR_ash_pGAS_high*/
+ 0x00287000,
+ 0x002A0AD8,
+ 0x0F120F00,
+ 0x0F120000,
+ 0x0F12000F,
+ 0x0F120F0F,
+ 0x0F120F00,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F12000F,
+ 0x0F120F0F,
+ 0x0F120F00,
+ 0x0F120F00,
+ 0x0F12000F,
+ 0x0F120F0F,
+ 0x0F120000,
+ 0x0F120F0F,
+ 0x0F120000,
+ 0x0F12000F,
+ 0x0F120F00,
+ 0x0F120F00,
+ 0x0F120000,
+ 0x0F120F0F,
+ 0x0F120F0F,
+ 0x0F120F00,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F12000F,
+ 0x0F120F0F,
+ 0x0F120000,
+ 0x0F120F00,
+ 0x0F120000,
+ 0x0F120F00,
+ 0x0F120000,
+ 0x0F120F0F,
+ 0x0F12000F,
+ 0x0F12000F,
+ 0x0F120F00,
+ 0x0F120F00,
+ 0x0F120000,
+ 0x0F120F00,
+ 0x0F120F0F,
+ 0x0F120F00,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F12000F,
+ 0x0F120F00,
+ 0x0F120F00,
+ 0x0F120F00,
+ 0x0F12000F,
+ 0x0F120F00,
+ 0x0F120000,
+ 0x0F120F0F,
+ 0x0F12000F,
+ 0x0F12000F,
+ 0x0F120F00,
+ 0x0F120F00,
+ 0x0F120000,
+ 0x0F120F0F,
+ 0x0F120F0F,
+ 0x0F120F00,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F12000F,
+ 0x0F120F0F,
+ 0x0F120F00,
+ 0x0F120F00,
+ 0x0F120000,
+ 0x0F120F0F,
+ 0x0F120000,
+ 0x0F120F0F,
+ 0x0F12000F,
+ 0x0F12000F,
+ 0x0F120F00,
+ /* TVAR_ash_pGAS_low*/
+ 0x0F128608,
+ 0x0F12E960,
+ 0x0F120243,
+ 0x0F12128B,
+ 0x0F12F073,
+ 0x0F120270,
+ 0x0F12DF47,
+ 0x0F12F226,
+ 0x0F121A31,
+ 0x0F12DFDA,
+ 0x0F121200,
+ 0x0F1205A9,
+ 0x0F120F16,
+ 0x0F120F5E,
+ 0x0F12DF10,
+ 0x0F1225BF,
+ 0x0F12FCF0,
+ 0x0F12DE1B,
+ 0x0F12025B,
+ 0x0F12FA8B,
+ 0x0F12163B,
+ 0x0F12DF44,
+ 0x0F12FB2D,
+ 0x0F1230E6,
+ 0x0F12FE07,
+ 0x0F12F47C,
+ 0x0F1209F2,
+ 0x0F120AED,
+ 0x0F12FA09,
+ 0x0F12E70E,
+ 0x0F120158,
+ 0x0F121110,
+ 0x0F12E28C,
+ 0x0F120DFB,
+ 0x0F12074B,
+ 0x0F12FBE5,
+ 0x0F12961C,
+ 0x0F12E21A,
+ 0x0F120ADF,
+ 0x0F120A67,
+ 0x0F12F8A6,
+ 0x0F12FDC3,
+ 0x0F12D590,
+ 0x0F12FA69,
+ 0x0F1208D5,
+ 0x0F12F635,
+ 0x0F12057E,
+ 0x0F12043B,
+ 0x0F12155C,
+ 0x0F1200C6,
+ 0x0F12F042,
+ 0x0F12176A,
+ 0x0F12F818,
+ 0x0F12F1F3,
+ 0x0F12026F,
+ 0x0F1208F6,
+ 0x0F120CCF,
+ 0x0F12E42D,
+ 0x0F120A92,
+ 0x0F1210EC,
+ 0x0F12005F,
+ 0x0F12F02C,
+ 0x0F120672,
+ 0x0F1209BF,
+ 0x0F12F4B5,
+ 0x0F12FC22,
+ 0x0F12FD50,
+ 0x0F120C26,
+ 0x0F12EED3,
+ 0x0F1207C3,
+ 0x0F12080F,
+ 0x0F12F6CF,
+ 0x0F127A3B,
+ 0x0F12E9DC,
+ 0x0F12088E,
+ 0x0F1201C8,
+ 0x0F12043C,
+ 0x0F12F7E2,
+ 0x0F12E391,
+ 0x0F12F3C4,
+ 0x0F121422,
+ 0x0F12E845,
+ 0x0F120D16,
+ 0x0F1206CA,
+ 0x0F120DEB,
+ 0x0F121324,
+ 0x0F12E814,
+ 0x0F1216B7,
+ 0x0F1202AC,
+ 0x0F12DE4D,
+ 0x0F1201EA,
+ 0x0F12F0C2,
+ 0x0F120E06,
+ 0x0F12EC6D,
+ 0x0F12FDF0,
+ 0x0F122B46,
+ 0x0F120710,
+ 0x0F12F84C,
+ 0x0F120E52,
+ 0x0F120675,
+ 0x0F12F0D7,
+ 0x0F12ED40,
+ 0x0F12F3AD,
+ 0x0F12179A,
+ 0x0F12DE9B,
+ 0x0F1210BA,
+ 0x0F120825,
+ 0x0F12FE0A,
+ 0x0F1288E9,
+ 0x0F12E9E0,
+ 0x0F12043D,
+ 0x0F120A17,
+ 0x0F12FC21,
+ 0x0F12FB58,
+ 0x0F12DCE0,
+ 0x0F12F24C,
+ 0x0F121A19,
+ 0x0F12E011,
+ 0x0F1211A3,
+ 0x0F120649,
+ 0x0F120D04,
+ 0x0F120E15,
+ 0x0F12E112,
+ 0x0F1227BD,
+ 0x0F12F7AA,
+ 0x0F12E06A,
+ 0x0F120A16,
+ 0x0F12FD23,
+ 0x0F121226,
+ 0x0F12DA34,
+ 0x0F1207A4,
+ 0x0F122AD3,
+ 0x0F12FE27,
+ 0x0F12EE64,
+ 0x0F120CAD,
+ 0x0F1211C5,
+ 0x0F12EC55,
+ 0x0F12ED98,
+ 0x0F12F88A,
+ 0x0F121842,
+ 0x0F12E1D5,
+ 0x0F1208FD,
+ 0x0F120FB6,
+ 0x0F12F801,
+ 0x002A0378,
+ 0x0F120001, /*REG_TC_DBG_RelnitCmd*/
+ /*===================================================================*/
+ /*Shading - Alpha*/
+ /*===================================================================*/
+ 0x002A05E8,
+ 0x0F1200E4, /*TVAR_ash_AwbAshCord[0] 2 70000568*/
+ 0x0F1200F0, /*TVAR_ash_AwbAshCord[1] 2 7000056A*/
+ 0x0F120100, /*TVAR_ash_AwbAshCord[2] 2 7000056C*/
+ 0x0F120120, /*TVAR_ash_AwbAshCord[3] 2 7000056E*/
+ 0x0F120150, /*TVAR_ash_AwbAshCord[4] 2 70000570*/
+ 0x0F120180, /*TVAR_ash_AwbAshCord[5] 2 70000572*/
+ 0x0F1201A0, /*TVAR_ash_AwbAshCord[6] 2 70000574*/
+ 0x002A05FE,
+ 0x0F123800, /*TVAR_ash_GASAlpha[0][0] 2 7000057E*/
+ 0x0F124000, /*TVAR_ash_GASAlpha[0][1] 2 70000580*/
+ 0x0F124000, /*TVAR_ash_GASAlpha[0][2] 2 70000582*/
+ 0x0F124000, /*TVAR_ash_GASAlpha[0][3] 2 70000584*/
+ 0x0F123800, /*TVAR_ash_GASAlpha[1][0] 2 70000586*/
+ 0x0F124000, /*TVAR_ash_GASAlpha[1][1] 2 70000588*/
+ 0x0F124000, /*TVAR_ash_GASAlpha[1][2] 2 7000058A*/
+ 0x0F124000, /*TVAR_ash_GASAlpha[1][3] 2 7000058C*/
+ 0x0F123800, /*TVAR_ash_GASAlpha[2][0] 2 7000058E*/
+ 0x0F124000, /*TVAR_ash_GASAlpha[2][1] 2 70000590*/
+ 0x0F124000, /*TVAR_ash_GASAlpha[2][2] 2 70000592*/
+ 0x0F124000, /*TVAR_ash_GASAlpha[2][3] 2 70000594*/
+ 0x0F123800, /*TVAR_ash_GASAlpha[3][0] 2 70000596*/
+ 0x0F124000, /*TVAR_ash_GASAlpha[3][1] 2 70000598*/
+ 0x0F124000, /*TVAR_ash_GASAlpha[3][2] 2 7000059A*/
+ 0x0F124000, /*TVAR_ash_GASAlpha[3][3] 2 7000059C*/
+ 0x0F123800, /*TVAR_ash_GASAlpha[4][0] 2 7000059E*/
+ 0x0F124000, /*TVAR_ash_GASAlpha[4][1] 2 700005A0*/
+ 0x0F124000, /*TVAR_ash_GASAlpha[4][2] 2 700005A2*/
+ 0x0F124000, /*TVAR_ash_GASAlpha[4][3] 2 700005A4*/
+ 0x0F124000, /*TVAR_ash_GASAlpha[5][0] 2 700005A6*/
+ 0x0F124000, /*TVAR_ash_GASAlpha[5][1] 2 700005A8*/
+ 0x0F124000, /*TVAR_ash_GASAlpha[5][2] 2 700005AA*/
+ 0x0F124000, /*TVAR_ash_GASAlpha[5][3] 2 700005AC*/
+ 0x0F124000, /*TVAR_ash_GASAlpha[6][0] 2 700005AE*/
+ 0x0F124000, /*TVAR_ash_GASAlpha[6][1] 2 700005B0*/
+ 0x0F124000, /*TVAR_ash_GASAlpha[6][2] 2 700005B2*/
+ 0x0F124000, /*TVAR_ash_GASAlpha[6][3] 2 700005B4*/
+ 0x0F124000, /*TVAR_ash_GASOutdoorAlpha[0] 2 700005B6*/
+ 0x0F124000, /*TVAR_ash_GASOutdoorAlpha[1] 2 700005B8*/
+ 0x0F124000, /*TVAR_ash_GASOutdoorAlpha[2] 2 700005BA*/
+ 0x0F124000, /*TVAR_ash_GASOutdoorAlpha[3] 2 700005BC*/
+ /*===================================================================*/
+ /*Gamma*/
+ /*===================================================================*/
+ 0x002A0460,
+ 0x0F120000, /*0000 0000 saRR_usDualGammaLutRGBIndoor[0][0]*/
+ 0x0F120004, /*0008 0002 saRR_usDualGammaLutRGBIndoor[0][1]*/
+ 0x0F12000C, /*0013 0006 saRR_usDualGammaLutRGBIndoor[0][2]*/
+ 0x0F120024, /*002C 0011 saRR_usDualGammaLutRGBIndoor[0][3]*/
+ 0x0F12006E, /*0061 0036 saRR_usDualGammaLutRGBIndoor[0][4]*/
+ 0x0F1200D1, /*00C8 009A saRR_usDualGammaLutRGBIndoor[0][5]*/
+ 0x0F120119, /*0113 00FD saRR_usDualGammaLutRGBIndoor[0][6]*/
+ 0x0F120139, /*0132 0129 saRR_usDualGammaLutRGBIndoor[0][7]*/
+ 0x0F120157, /*014C 014B saRR_usDualGammaLutRGBIndoor[0][8]*/
+ 0x0F12018E, /*0179 0184 saRR_usDualGammaLutRGBIndoor[0][9]*/
+ 0x0F1201C3, /*01A4 01B8 saRR_usDualGammaLutRGBIndoor[0][10]*/
+ 0x0F1201F3, /*01CD 01EA saRR_usDualGammaLutRGBIndoor[0][11]*/
+ 0x0F12021F, /*01F4 0216 saRR_usDualGammaLutRGBIndoor[0][12]*/
+ 0x0F120269, /*0239 025E saRR_usDualGammaLutRGBIndoor[0][13]*/
+ 0x0F1202A6, /*0278 0299 saRR_usDualGammaLutRGBIndoor[0][14]*/
+ 0x0F1202FF, /*02E0 02F9 saRR_usDualGammaLutRGBIndoor[0][15]*/
+ 0x0F120351, /*0333 0341 saRR_usDualGammaLutRGBIndoor[0][16]*/
+ 0x0F120395, /*037B 037F saRR_usDualGammaLutRGBIndoor[0][17]*/
+ 0x0F1203CE, /*03BF 03BF saRR_usDualGammaLutRGBIndoor[0][18]*/
+ 0x0F1203FF, /*03FF 03FF saRR_usDualGammaLutRGBIndoor[0][19]*/
+ 0x0F120000, /*0000 0000 saRR_usDualGammaLutRGBIndoor[1][0]*/
+ 0x0F120004, /*0008 0002 saRR_usDualGammaLutRGBIndoor[1][1]*/
+ 0x0F12000C, /*0013 0006 saRR_usDualGammaLutRGBIndoor[1][2]*/
+ 0x0F120024, /*002C 0011 saRR_usDualGammaLutRGBIndoor[1][3]*/
+ 0x0F12006E, /*0061 0036 saRR_usDualGammaLutRGBIndoor[1][4]*/
+ 0x0F1200D1, /*00C8 009A saRR_usDualGammaLutRGBIndoor[1][5]*/
+ 0x0F120119, /*0113 00FD saRR_usDualGammaLutRGBIndoor[1][6]*/
+ 0x0F120139, /*0132 0129 saRR_usDualGammaLutRGBIndoor[1][7]*/
+ 0x0F120157, /*014C 014B saRR_usDualGammaLutRGBIndoor[1][8]*/
+ 0x0F12018E, /*0179 0184 saRR_usDualGammaLutRGBIndoor[1][9]*/
+ 0x0F1201C3, /*01A4 01B8 saRR_usDualGammaLutRGBIndoor[1][10]*/
+ 0x0F1201F3, /*01CD 01EA saRR_usDualGammaLutRGBIndoor[1][11]*/
+ 0x0F12021F, /*01F4 0216 saRR_usDualGammaLutRGBIndoor[1][12]*/
+ 0x0F120269, /*0239 025E saRR_usDualGammaLutRGBIndoor[1][13]*/
+ 0x0F1202A6, /*0278 0299 saRR_usDualGammaLutRGBIndoor[1][14]*/
+ 0x0F1202FF, /*02E0 02F9 saRR_usDualGammaLutRGBIndoor[1][15]*/
+ 0x0F120351, /*0333 0341 saRR_usDualGammaLutRGBIndoor[1][16]*/
+ 0x0F120395, /*037B 037F saRR_usDualGammaLutRGBIndoor[1][17]*/
+ 0x0F1203CE, /*03BF 03BF saRR_usDualGammaLutRGBIndoor[1][18]*/
+ 0x0F1203FF, /*03FF 03FF saRR_usDualGammaLutRGBIndoor[1][19]*/
+ 0x0F120000, /*0000 0000 saRR_usDualGammaLutRGBIndoor[2][0]*/
+ 0x0F120004, /*0008 0002 saRR_usDualGammaLutRGBIndoor[2][1]*/
+ 0x0F12000C, /*0013 0006 saRR_usDualGammaLutRGBIndoor[2][2]*/
+ 0x0F120024, /*002C 0011 saRR_usDualGammaLutRGBIndoor[2][3]*/
+ 0x0F12006E, /*0061 0036 saRR_usDualGammaLutRGBIndoor[2][4]*/
+ 0x0F1200D1, /*00C8 009A saRR_usDualGammaLutRGBIndoor[2][5]*/
+ 0x0F120119, /*0113 00FD saRR_usDualGammaLutRGBIndoor[2][6]*/
+ 0x0F120139, /*0132 0129 saRR_usDualGammaLutRGBIndoor[2][7]*/
+ 0x0F120157, /*014C 014B saRR_usDualGammaLutRGBIndoor[2][8]*/
+ 0x0F12018E, /*0179 0184 saRR_usDualGammaLutRGBIndoor[2][9]*/
+ 0x0F1201C3, /*01A4 01B8 saRR_usDualGammaLutRGBIndoor[2][10]*/
+ 0x0F1201F3, /*01CD 01EA saRR_usDualGammaLutRGBIndoor[2][11]*/
+ 0x0F12021F, /*01F4 0216 saRR_usDualGammaLutRGBIndoor[2][12]*/
+ 0x0F120269, /*0239 025E saRR_usDualGammaLutRGBIndoor[2][13]*/
+ 0x0F1202A6, /*0278 0299 saRR_usDualGammaLutRGBIndoor[2][14]*/
+ 0x0F1202FF, /*02E0 02F9 saRR_usDualGammaLutRGBIndoor[2][15]*/
+ 0x0F120351, /*0333 0341 saRR_usDualGammaLutRGBIndoor[2][16]*/
+ 0x0F120395, /*037B 037F saRR_usDualGammaLutRGBIndoor[2][17]*/
+ 0x0F1203CE, /*03BF 03BF saRR_usDualGammaLutRGBIndoor[2][18]*/
+ 0x0F1203FF, /*03FF 03FF saRR_usDualGammaLutRGBIndoor[2][19]*/
+ 0x0F120000, /*0000 0000 saRR_usDualGammaLutRGBOutdoor[0][0]*/
+ 0x0F120004, /*0008 0002 saRR_usDualGammaLutRGBOutdoor[0][1]*/
+ 0x0F12000C, /*0013 0006 saRR_usDualGammaLutRGBOutdoor[0][2]*/
+ 0x0F120024, /*002C 0011 saRR_usDualGammaLutRGBOutdoor[0][3]*/
+ 0x0F12006E, /*0061 0036 saRR_usDualGammaLutRGBOutdoor[0][4]*/
+ 0x0F1200D1, /*00C8 009A saRR_usDualGammaLutRGBOutdoor[0][5]*/
+ 0x0F120119, /*0113 00FD saRR_usDualGammaLutRGBOutdoor[0][6]*/
+ 0x0F120139, /*0132 0129 saRR_usDualGammaLutRGBOutdoor[0][7]*/
+ 0x0F120157, /*014C 014B saRR_usDualGammaLutRGBOutdoor[0][8]*/
+ 0x0F12018E, /*0179 0184 saRR_usDualGammaLutRGBOutdoor[0][9]*/
+ 0x0F1201C3, /*01A4 01B8 saRR_usDualGammaLutRGBOutdoor[0][10]*/
+ 0x0F1201F3, /*01CD 01EA saRR_usDualGammaLutRGBOutdoor[0][11]*/
+ 0x0F12021F, /*01F4 0216 saRR_usDualGammaLutRGBOutdoor[0][12]*/
+ 0x0F120269, /*0239 025E saRR_usDualGammaLutRGBOutdoor[0][13]*/
+ 0x0F1202A6, /*0278 0299 saRR_usDualGammaLutRGBOutdoor[0][14]*/
+ 0x0F1202FF, /*02E0 02F9 saRR_usDualGammaLutRGBOutdoor[0][15]*/
+ 0x0F120351, /*0333 0341 saRR_usDualGammaLutRGBOutdoor[0][16]*/
+ 0x0F120395, /*037B 037F saRR_usDualGammaLutRGBOutdoor[0][17]*/
+ 0x0F1203CE, /*03BF 03BF saRR_usDualGammaLutRGBOutdoor[0][18]*/
+ 0x0F1203FF, /*03FF 03FF saRR_usDualGammaLutRGBOutdoor[0][19]*/
+ 0x0F120000, /*0000 0000 saRR_usDualGammaLutRGBOutdoor[1][0]*/
+ 0x0F120004, /*0008 0002 saRR_usDualGammaLutRGBOutdoor[1][1]*/
+ 0x0F12000C, /*0013 0006 saRR_usDualGammaLutRGBOutdoor[1][2]*/
+ 0x0F120024, /*002C 0011 saRR_usDualGammaLutRGBOutdoor[1][3]*/
+ 0x0F12006E, /*0061 0036 saRR_usDualGammaLutRGBOutdoor[1][4]*/
+ 0x0F1200D1, /*00C8 009A saRR_usDualGammaLutRGBOutdoor[1][5]*/
+ 0x0F120119, /*0113 00FD saRR_usDualGammaLutRGBOutdoor[1][6]*/
+ 0x0F120139, /*0132 0129 saRR_usDualGammaLutRGBOutdoor[1][7]*/
+ 0x0F120157, /*014C 014B saRR_usDualGammaLutRGBOutdoor[1][8]*/
+ 0x0F12018E, /*0179 0184 saRR_usDualGammaLutRGBOutdoor[1][9]*/
+ 0x0F1201C3, /*01A4 01B8 saRR_usDualGammaLutRGBOutdoor[1][10]*/
+ 0x0F1201F3, /*01CD 01EA saRR_usDualGammaLutRGBOutdoor[1][11]*/
+ 0x0F12021F, /*01F4 0216 saRR_usDualGammaLutRGBOutdoor[1][12]*/
+ 0x0F120269, /*0239 025E saRR_usDualGammaLutRGBOutdoor[1][13]*/
+ 0x0F1202A6, /*0278 0299 saRR_usDualGammaLutRGBOutdoor[1][14]*/
+ 0x0F1202FF, /*02E0 02F9 saRR_usDualGammaLutRGBOutdoor[1][15]*/
+ 0x0F120351, /*0333 0341 saRR_usDualGammaLutRGBOutdoor[1][16]*/
+ 0x0F120395, /*037B 037F saRR_usDualGammaLutRGBOutdoor[1][17]*/
+ 0x0F1203CE, /*03BF 03BF saRR_usDualGammaLutRGBOutdoor[1][18]*/
+ 0x0F1203FF, /*03FF 03FF saRR_usDualGammaLutRGBOutdoor[1][19]*/
+ 0x0F120000, /*0000 0000 saRR_usDualGammaLutRGBOutdoor[2][0]*/
+ 0x0F120004, /*0008 0002 saRR_usDualGammaLutRGBOutdoor[2][1]*/
+ 0x0F12000C, /*0013 0006 saRR_usDualGammaLutRGBOutdoor[2][2]*/
+ 0x0F120024, /*002C 0011 saRR_usDualGammaLutRGBOutdoor[2][3]*/
+ 0x0F12006E, /*0061 0036 saRR_usDualGammaLutRGBOutdoor[2][4]*/
+ 0x0F1200D1, /*00C8 009A saRR_usDualGammaLutRGBOutdoor[2][5]*/
+ 0x0F120119, /*0113 00FD saRR_usDualGammaLutRGBOutdoor[2][6]*/
+ 0x0F120139, /*0132 0129 saRR_usDualGammaLutRGBOutdoor[2][7]*/
+ 0x0F120157, /*014C 014B saRR_usDualGammaLutRGBOutdoor[2][8]*/
+ 0x0F12018E, /*0179 0184 saRR_usDualGammaLutRGBOutdoor[2][9]*/
+ 0x0F1201C3, /*01A4 01B8 saRR_usDualGammaLutRGBOutdoor[2][10]*/
+ 0x0F1201F3, /*01CD 01EA saRR_usDualGammaLutRGBOutdoor[2][11]*/
+ 0x0F12021F, /*01F4 0216 saRR_usDualGammaLutRGBOutdoor[2][12]*/
+ 0x0F120269, /*0239 025E saRR_usDualGammaLutRGBOutdoor[2][13]*/
+ 0x0F1202A6, /*0278 0299 saRR_usDualGammaLutRGBOutdoor[2][14]*/
+ 0x0F1202FF, /*02E0 02F9 saRR_usDualGammaLutRGBOutdoor[2][15]*/
+ 0x0F120351, /*0333 0341 saRR_usDualGammaLutRGBOutdoor[2][16]*/
+ 0x0F120395, /*037B 037F saRR_usDualGammaLutRGBOutdoor[2][17]*/
+ 0x0F1203CE, /*03BF 03BF saRR_usDualGammaLutRGBOutdoor[2][18]*/
+ 0x0F1203FF, /*03FF 03FF saRR_usDualGammaLutRGBOutdoor[2][19]*/
+
+
+ /*===================================================================*/
+ /*AE - shutter*/
+ /*===================================================================*/
+ /*AE_Target*/
+ 0x002A10C0,
+ 0x0F120045, /*TVAR_ae_BrAve*/
+ 0x002A10C6,
+ 0x0F12000F, /*ae_StatMode 2 70001046*/
+ /*AE_state,*/
+ 0x002A03B2,
+ 0x0F12010E, /*#lt_uLimitHigh*/
+ 0x0F1200F5, /*#lt_uLimitLow*/
+ /*For 60Hz,*/
+ 0x002A03C4,
+ 0x0F123415, /*#lt_uMaxExp1*/
+ 0x002A03C8,
+ 0x0F12681F, /*#lt_uMaxExp2*/
+ 0x002A03CC,
+ 0x0F128227, /*#lt_uMaxExp3*/
+ 0x002A03D0,
+ 0x0F120D40, /*C350 #lt_uMaxExp4*/
+ 0x0F120003, /*0000 #lt_uMaxExp4*/
+ 0x002A03D4,
+ 0x0F123415, /*#lt_uCapMaxExp1*/
+ 0x002A03D8,
+ 0x0F12681F, /*#lt_uCapMaxExp2*/
+ 0x002A03DC,
+ 0x0F128227, /*#lt_uCapMaxExp3*/
+ 0x002A03E0,
+ 0x0F120D40, /*C350 #lt_uCapMaxExp4*/
+ 0x0F120003, /*0000 #lt_uCapMaxExp4*/
+ 0x002A03E4,
+ 0x0F1201C0, /*0230 #lt_uMaxAnGain1*/
+ 0x0F1201D0, /*0260 #lt_uMaxAnGain2*/
+ 0x0F1202D0, /*0380 #lt_uMaxAnGain3*/
+ 0x0F120700, /*#lt_uMaxAnGain4*/
+ 0x0F120100, /*#lt_uMaxDigGain*/
+ 0x0F128000, /*#lt_uMaxTotGain Total-gain is limited by
+ #lt_uMaxTotGain*/
+ 0x0F1201C0, /*#lt_uCapMaxAnGain1*/
+ 0x0F1201D0, /*#lt_uCapMaxAnGain2*/
+ 0x0F1202D0, /*#lt_uCapMaxAnGain3*/
+ 0x0F120700, /*#lt_uCapMaxAnGain4*/
+ 0x0F120100, /*#lt_uCapMaxDigGain*/
+ 0x0F128000, /*#lt_uCapMaxTotGain Total-gain is limited by
+ #lt_uMaxTotGain*/
+ /*===================================================================*/
+ /*AE - Weights*/
+ /*===================================================================*/
+ 0x002A10CE,
+ 0x0F120000, /*ae_WeightTbl_16[0] 2 7000104E*/
+ 0x0F120101, /*ae_WeightTbl_16[1] 2 70001050*/
+ 0x0F120101, /*ae_WeightTbl_16[2] 2 70001052*/
+ 0x0F120000, /*ae_WeightTbl_16[3] 2 70001054*/
+ 0x0F120101, /*ae_WeightTbl_16[4] 2 70001056*/
+ 0x0F120101, /*ae_WeightTbl_16[5] 2 70001058*/
+ 0x0F120101, /*ae_WeightTbl_16[6] 2 7000105A*/
+ 0x0F120101, /*ae_WeightTbl_16[7] 2 7000105C*/
+ 0x0F120201, /*ae_WeightTbl_16[8] 2 7000105E*/
+ 0x0F120303, /*ae_WeightTbl_16[9] 2 70001060*/
+ 0x0F120303, /*ae_WeightTbl_16[10] 2 70001062*/
+ 0x0F120102, /*ae_WeightTbl_16[11] 2 70001064*/
+ 0x0F120201, /*ae_WeightTbl_16[12] 2 70001066*/
+ 0x0F120403, /*ae_WeightTbl_16[13] 2 70001068*/
+ 0x0F120304, /*ae_WeightTbl_16[14] 2 7000106A*/
+ 0x0F120102, /*ae_WeightTbl_16[15] 2 7000106C*/
+ 0x0F120201, /*ae_WeightTbl_16[16] 2 7000106E*/
+ 0x0F120403, /*ae_WeightTbl_16[17] 2 70001070*/
+ 0x0F120304, /*ae_WeightTbl_16[18] 2 70001072*/
+ 0x0F120102, /*ae_WeightTbl_16[19] 2 70001074*/
+ 0x0F120201, /*ae_WeightTbl_16[20] 2 70001076*/
+ 0x0F120403, /*ae_WeightTbl_16[21] 2 70001078*/
+ 0x0F120304, /*ae_WeightTbl_16[22] 2 7000107A*/
+ 0x0F120102, /*ae_WeightTbl_16[23] 2 7000107C*/
+ 0x0F120201, /*ae_WeightTbl_16[24] 2 7000107E*/
+ 0x0F120303, /*ae_WeightTbl_16[25] 2 70001080*/
+ 0x0F120303, /*ae_WeightTbl_16[26] 2 70001082*/
+ 0x0F120102, /*ae_WeightTbl_16[27] 2 70001084*/
+ 0x0F120201, /*ae_WeightTbl_16[28] 2 70001086*/
+ 0x0F120202, /*ae_WeightTbl_16[29] 2 70001088*/
+ 0x0F120202, /*ae_WeightTbl_16[30] 2 7000108A*/
+ 0x0F120102, /*ae_WeightTbl_16[31] 2 7000108C*/
+ /*===================================================================*/
+ /*AWB-BASIC setting*/
+ /*===================================================================*/
+ 0x002A0DCC,
+ 0x0F120138, /*awbb_IntcR*/
+ 0x0F12011C, /*awbb_IntcB*/
+ 0x0F1202A7, /*awbb_GLocusR*/
+ 0x0F120343, /*awbb_GLocusB*/
+ 0x002A0DB4,
+ 0x0F12036C, /*awbb_CrclLowT_R_c*/
+ 0x002A0DB8,
+ 0x0F12011D, /*awbb_CrclLowT_B_c*/
+ 0x002A0DBC,
+ 0x0F1262C1, /*awbb_CrclLowT_Rad_c*/
+ 0x002A0DEC,
+ 0x0F1205F0, /*awbb_GamutWidthThr1*/
+ 0x0F1201F4, /*awbb_GamutHeightThr1*/
+ 0x0F12006C, /*awbb_GamutWidthThr2*/
+ 0x0F120038, /*awbb_GamutHeightThr2*/
+ 0x002A0DD8,
+ 0x0F12000C, /*awbb_MinNumOfFinalPatches*/
+ 0x0F12001E, /*awbb_MinNumOfLowBrFinalPatches*/
+ 0x0F120046, /*awbb_MinNumOfLowBr0_FinalPatches*/
+ 0x002A22BA,
+ 0x0F120006, /* #Mon_AWB_ByPassMode [0]Outdoor [1]LowBr [2]LowTemp*/
+ 0x002A0F7A,
+ 0x0F120000, /*awbb_RGainOff 2 70000EFA*/
+ 0x0F120000, /*awbb_BGainOff 2 70000EFC*/
+ 0x0F120000, /*awbb_GGainOff 2 70000EFE*/
+ 0x0F1200C2, /*awbb_Alpha_Comp_Mode 2 70000F00*/
+ 0x0F120002, /*awbb_Rpl_InvalidOutDoor 2 70000F02*/
+ 0x0F120001, /*awbb_UseGrThrCorr 2 70000F04*/
+ 0x0F1200E4, /*awbb_Use_Filters 2 70000F06*/
+ 0x0F12053C, /*awbb_GainsInit[0] 2 70000F08*/
+ 0x0F120400, /*awbb_GainsInit[1] 2 70000F0A*/
+ 0x0F12055C, /*awbb_GainsInit[2] 2 70000F0C*/
+ 0x0F12001E, /*awbb_WpFilterMinThr 2 70000F0E*/
+ 0x0F120190, /*awbb_WpFilterMaxThr 2 70000F10*/
+ 0x0F1200A0, /*awbb_WpFilterCoef 2 70000F12*/
+ 0x0F120004, /*awbb_WpFilterSize 2 70000F14*/
+ 0x0F120001, /*awbb_otp_disable 2 70000F16*/
+ /*===================================================================*/
+ /*AWB-Zone*/
+ /*===================================================================*/
+ /* param_start awbb_IndoorGrZones_m_BGrid*/
+ 0x002A0CE0,
+ 0x0F1203F8, /*03B5 awbb_IndoorGrZones_m_BGrid[0]*/
+ 0x0F120422, /*03DF awbb_IndoorGrZones_m_BGrid[1]*/
+ 0x0F1203B4, /*032D awbb_IndoorGrZones_m_BGrid[2]*/
+ 0x0F120408, /*03D5 awbb_IndoorGrZones_m_BGrid[3]*/
+ 0x0F120370, /*0303 awbb_IndoorGrZones_m_BGrid[4]*/
+ 0x0F1203EE, /*03BB awbb_IndoorGrZones_m_BGrid[5]*/
+ 0x0F12032C, /*02DB awbb_IndoorGrZones_m_BGrid[6]*/
+ 0x0F1203D4, /*0397 awbb_IndoorGrZones_m_BGrid[7]*/
+ 0x0F120302, /*02B1 awbb_IndoorGrZones_m_BGrid[8]*/
+ 0x0F1203BA, /*036B awbb_IndoorGrZones_m_BGrid[9]*/
+ 0x0F1202DA, /*0289 awbb_IndoorGrZones_m_BGrid[10]*/
+ 0x0F120374, /*0349 awbb_IndoorGrZones_m_BGrid[11]*/
+ 0x0F1202B0, /*026F awbb_IndoorGrZones_m_BGrid[12]*/
+ 0x0F120328, /*0329 awbb_IndoorGrZones_m_BGrid[13]*/
+ 0x0F120288, /*0257 awbb_IndoorGrZones_m_BGrid[14]*/
+ 0x0F120300, /*0309 awbb_IndoorGrZones_m_BGrid[15]*/
+ 0x0F120270, /*0241 awbb_IndoorGrZones_m_BGrid[16]*/
+ 0x0F1202DE, /*02DD awbb_IndoorGrZones_m_BGrid[17]*/
+ 0x0F120258, /*0227 awbb_IndoorGrZones_m_BGrid[18]*/
+ 0x0F1202BE, /*02C3 awbb_IndoorGrZones_m_BGrid[19]*/
+ 0x0F120240, /*0213 awbb_IndoorGrZones_m_BGrid[20]*/
+ 0x0F1202A0, /*02AF awbb_IndoorGrZones_m_BGrid[21]*/
+ 0x0F120228, /*0209 awbb_IndoorGrZones_m_BGrid[22]*/
+ 0x0F120296, /*0295 awbb_IndoorGrZones_m_BGrid[23]*/
+ 0x0F120212, /*020D awbb_IndoorGrZones_m_BGrid[24]*/
+ 0x0F120284, /*0285 awbb_IndoorGrZones_m_BGrid[25]*/
+ 0x0F120208, /*0223 awbb_IndoorGrZones_m_BGrid[26]*/
+ 0x0F120274, /*0261 awbb_IndoorGrZones_m_BGrid[27]*/
+ 0x0F12020C, /*0000 awbb_IndoorGrZones_m_BGrid[28]*/
+ 0x0F12026E, /*0000 awbb_IndoorGrZones_m_BGrid[29]*/
+ 0x0F120222, /*0000 awbb_IndoorGrZones_m_BGrid[30]*/
+ 0x0F120260, /*0000 awbb_IndoorGrZones_m_BGrid[31]*/
+ 0x0F120000, /*0000 awbb_IndoorGrZones_m_BGrid[32]*/
+ 0x0F120000, /*0000 awbb_IndoorGrZones_m_BGrid[33]*/
+ 0x0F120000, /*0000 awbb_IndoorGrZones_m_BGrid[34]*/
+ 0x0F120000, /*0000 awbb_IndoorGrZones_m_BGrid[35]*/
+ 0x0F120000, /*0000 awbb_IndoorGrZones_m_BGrid[36]*/
+ 0x0F120000, /*0000 awbb_IndoorGrZones_m_BGrid[37]*/
+ 0x0F120000, /*0000 awbb_IndoorGrZones_m_BGrid[38]*/
+ 0x0F120000, /*0000 awbb_IndoorGrZones_m_BGrid[39]*/
+ /* param_end awbb_IndoorGrZones_m_BGrid*/
+ 0x0F120005, /*awbb_IndoorGrZones_m_Grid*/
+ 0x002A0D38,
+ 0x0F1200FE, /*awbb_IndoorGrZones_m_Boff*/
+ /* param_start awbb_OutdoorGrZones_m_BGrid*/
+ 0x002A0D3C,
+ 0x0F1202B8, /*029F awbb_OutdoorGrZones_m_BGrid[0]*/
+ 0x0F1202F2, /*02CE awbb_OutdoorGrZones_m_BGrid[1]*/
+ 0x0F12028E, /*0282 awbb_OutdoorGrZones_m_BGrid[2]*/
+ 0x0F12030A, /*02DA awbb_OutdoorGrZones_m_BGrid[3]*/
+ 0x0F12027A, /*026D awbb_OutdoorGrZones_m_BGrid[4]*/
+ 0x0F12030A, /*02C2 awbb_OutdoorGrZones_m_BGrid[5]*/
+ 0x0F120274, /*0256 awbb_OutdoorGrZones_m_BGrid[6]*/
+ 0x0F1202FE, /*02A6 awbb_OutdoorGrZones_m_BGrid[7]*/
+ 0x0F120282, /*026E awbb_OutdoorGrZones_m_BGrid[8]*/
+ 0x0F1202DC, /*028A awbb_OutdoorGrZones_m_BGrid[9]*/
+ 0x0F120000, /*0000 awbb_OutdoorGrZones_m_BGrid[10]*/
+ 0x0F120000, /*0000 awbb_OutdoorGrZones_m_BGrid[11]*/
+ 0x0F120000, /*0000 awbb_OutdoorGrZones_m_BGrid[12]*/
+ 0x0F120000, /*0000 awbb_OutdoorGrZones_m_BGrid[13]*/
+ 0x0F120000, /*0000 awbb_OutdoorGrZones_m_BGrid[14]*/
+ 0x0F120000, /*0000 awbb_OutdoorGrZones_m_BGrid[15]*/
+ 0x0F120000, /*0000 awbb_OutdoorGrZones_m_BGrid[16]*/
+ 0x0F120000, /*0000 awbb_OutdoorGrZones_m_BGrid[17]*/
+ 0x0F120000, /*0000 awbb_OutdoorGrZones_m_BGrid[18]*/
+ 0x0F120000, /*0000 awbb_OutdoorGrZones_m_BGrid[19]*/
+ 0x0F120000, /*0000 awbb_OutdoorGrZones_m_BGrid[20]*/
+ 0x0F120000, /*0000 awbb_OutdoorGrZones_m_BGrid[21]*/
+ 0x0F120000, /*0000 awbb_OutdoorGrZones_m_BGrid[22]*/
+ 0x0F120000, /*0000 awbb_OutdoorGrZones_m_BGrid[23]*/
+ /* param_end awbb_OutdoorGrZones_m_BGrid*/
+ 0x0F120005, /*awbb_OutdoorGrZones_m_Gri*/
+ 0x002A0D70,
+ 0x0F120005, /*awbb_OutdoorGrZones_ZInfo_m_GridSz*/
+ 0x002A0D74,
+ 0x0F1201EB, /*awbb_OutdoorGrZones_m_Bof*/
+ /* param_start awbb_LowBrGrZones_m_BGrid*/
+ 0x002A0D78,
+ 0x0F1203CE, /*awbb_LowBrGrZones_m_BGrid[0]*/
+ 0x0F12046E, /*awbb_LowBrGrZones_m_BGrid[1]*/
+ 0x0F12034E, /*awbb_LowBrGrZones_m_BGrid[2]*/
+ 0x0F120474, /*awbb_LowBrGrZones_m_BGrid[3]*/
+ 0x0F1202EA, /*awbb_LowBrGrZones_m_BGrid[4]*/
+ 0x0F120434, /*awbb_LowBrGrZones_m_BGrid[5]*/
+ 0x0F12028C, /*awbb_LowBrGrZones_m_BGrid[6]*/
+ 0x0F1203F0, /*awbb_LowBrGrZones_m_BGrid[7]*/
+ 0x0F120244, /*awbb_LowBrGrZones_m_BGrid[8]*/
+ 0x0F120380, /*awbb_LowBrGrZones_m_BGrid[9]*/
+ 0x0F12020E, /*awbb_LowBrGrZones_m_BGrid[10]*/
+ 0x0F120330, /*awbb_LowBrGrZones_m_BGrid[11]*/
+ 0x0F1201EC, /*awbb_LowBrGrZones_m_BGrid[12]*/
+ 0x0F1202EC, /*awbb_LowBrGrZones_m_BGrid[13]*/
+ 0x0F1201D0, /*awbb_LowBrGrZones_m_BGrid[14]*/
+ 0x0F1202BC, /*awbb_LowBrGrZones_m_BGrid[15]*/
+ 0x0F1201C8, /*awbb_LowBrGrZones_m_BGrid[16]*/
+ 0x0F120296, /*awbb_LowBrGrZones_m_BGrid[17]*/
+ 0x0F1201D2, /*awbb_LowBrGrZones_m_BGrid[18]*/
+ 0x0F120266, /*awbb_LowBrGrZones_m_BGrid[19]*/
+ 0x0F120000, /*awbb_LowBrGrZones_m_BGrid[20]*/
+ 0x0F120000, /*awbb_LowBrGrZones_m_BGrid[21]*/
+ 0x0F120000, /*awbb_LowBrGrZones_m_BGrid[22]*/
+ 0x0F120000, /*awbb_LowBrGrZones_m_BGrid[23]*/
+ /* param_end awbb_LowBrGrZones_m_BGrid*/
+ 0x0F120006, /*awbb_LowBrGrZones_m_GridS*/
+ 0x002A0DB0,
+ 0x0F1200E2, /*awbb_LowBrGrZones_m_Boffs*/
+ /*===================================================================*/
+ /*AWB Scene Detection*/
+ /*===================================================================*/
+ 0x002A0E50,
+ 0x0F12FE82, /*awbb_SCDetectionMap_SEC_StartR_B 2 70000DD0*/
+ 0x0F12001E, /*awbb_SCDetectionMap_SEC_StepR_B 2 70000DD2*/
+ 0x0F120E74, /*awbb_SCDetectionMap_SEC_SunnyNB 2 70000DD4*/
+ 0x0F120122, /*awbb_SCDetectionMap_SEC_StepNB 2 70000DD6*/
+ 0x0F1200E4, /*awbb_SCDetectionMap_SEC_LowTempR_B 2 70000DD8*/
+ 0x0F120096, /*awbb_SCDetectionMap_SEC_SunnyNBZone 2 70000DDA*/
+ 0x0F12000E, /*awbb_SCDetectionMap_SEC_LowTempR_BZone
+ 2 70000DDC*/
+ 0x002A0E14,
+ 0x0F120000, /*#awbb_SCDetectionMap_SEC 0000
+ WRITE 70000D94 0000
+ awbb_SCDetectionMap_SEC_SceneDetectionMap*/
+ 0x0F120000, /*#awbb_SCDetectionMap_SEC_SceneDetectionMap_0__2_
+ WRITE 70000D96 0000*/
+ 0x0F120000, /*#awbb_SCDetectionMap_SEC_SceneDetectionMap_0__4_
+ WRITE 70000D98 0000*/
+ 0x0F120000, /*#awbb_SCDetectionMap_SEC_SceneDetectionMap_1__1_
+ WRITE 70000D9A 0000*/
+ 0x0F120000, /*#awbb_SCDetectionMap_SEC_SceneDetectionMap_1__3_
+ WRITE 70000D9C 0000*/
+ 0x0F120000, /*#awbb_SCDetectionMap_SEC_SceneDetectionMap_2__0_
+ WRITE 70000D9E 0000*/
+ 0x0F120000, /*#awbb_SCDetectionMap_SEC_SceneDetectionMap_2__2_
+ WRITE 70000DA0 0000*/
+ 0x0F120000, /*#awbb_SCDetectionMap_SEC_SceneDetectionMap_2__4_
+ WRITE 70000DA2 0000*/
+ 0x0F120000, /*#awbb_SCDetectionMap_SEC_SceneDetectionMap_3__1_
+ WRITE 70000DA4 0000*/
+ 0x0F120000, /*#awbb_SCDetectionMap_SEC_SceneDetectionMap_3__3_
+ WRITE 70000DA6 0000*/
+ 0x0F120000, /*#awbb_SCDetectionMap_SEC_SceneDetectionMap_4__0_
+ WRITE 70000DA8 0000*/
+ 0x0F120000, /*#awbb_SCDetectionMap_SEC_SceneDetectionMap_4__2_
+ WRITE 70000DAA 0000*/
+ 0x0F120500, /*#awbb_SCDetectionMap_SEC_SceneDetectionMap_4__4_
+ WRITE 70000DAC 0500*/
+ 0x0F125555, /*#awbb_SCDetectionMap_SEC_SceneDetectionMap_5__1_
+ WRITE 70000DAE 5555*/
+ 0x0F125455, /*#awbb_SCDetectionMap_SEC_SceneDetectionMap_5__3_
+ WRITE 70000DB0 5455*/
+ 0x0F12AA55, /*#awbb_SCDetectionMap_SEC_SceneDetectionMap_6__0_
+ WRITE 70000DB2 AA55*/
+ 0x0F12AAAA, /*#awbb_SCDetectionMap_SEC_SceneDetectionMap_6__2_
+ WRITE 70000DB4 AAAA*/
+ 0x0F12BF54, /*#awbb_SCDetectionMap_SEC_SceneDetectionMap_6__4_
+ WRITE 70000DB6 BF54*/
+ 0x0F12FFFF, /*#awbb_SCDetectionMap_SEC_SceneDetectionMap_7__1_
+ WRITE 70000DB8 FFFF*/
+ 0x0F1254FE, /*#awbb_SCDetectionMap_SEC_SceneDetectionMap_7__3_
+ WRITE 70000DBA 54FE*/
+ 0x0F12FF6F, /*#awbb_SCDetectionMap_SEC_SceneDetectionMap_8__0_
+ WRITE 70000DBC FF6F*/
+ 0x0F12FEFF, /*#awbb_SCDetectionMap_SEC_SceneDetectionMap_8__2_
+ WRITE 70000DBE FEFF*/
+ 0x0F121B54, /*#awbb_SCDetectionMap_SEC_SceneDetectionMap_8__4_
+ WRITE 70000DC0 1B54*/
+ 0x0F12FFFF, /*#awbb_SCDetectionMap_SEC_SceneDetectionMap_9__1_
+ WRITE 70000DC2 FFFF*/
+ 0x0F1254FE, /*#awbb_SCDetectionMap_SEC_SceneDetectionMap_9__3_
+ WRITE 70000DC4 54FE*/
+ 0x0F12FF06, /*#awbb_SCDetectionMap_SEC_SceneDetectionMap_10__0_
+ WRITE 70000DC6 FF06*/
+ 0x0F12FEFF, /*#awbb_SCDetectionMap_SEC_SceneDetectionMap_10__2_
+ WRITE 70000DC8 FEFF*/
+ 0x0F120154, /*#awbb_SCDetectionMap_SEC_SceneDetectionMap_10__4_
+ WRITE 70000DCA 0154*/
+ 0x0F12BFBF, /*#awbb_SCDetectionMap_SEC_SceneDetectionMap_11__1_
+ WRITE 70000DCC BFBF*/
+ 0x0F1254BE, /*#awbb_SCDetectionMap_SEC_SceneDetectionMap_11__3_
+ WRITE 70000DCE 54BE*/
+ 0x002A0F86,
+ 0x0F120074, /*E0 awbb_Use_Filters e4*/
+ 0x002A0F8E,
+ 0x0F12001E, /*awbb_WpFilterMinThr 1e*/
+ /*===================================================================*/
+ /*AWB - GridCorrection*/
+ /*===================================================================*/
+ 0x002A0F98,
+ 0x0F120002, /*awbb_GridEnable 2 70000F18*/
+ 0x002A0F60,
+ 0x0F1202E2, /*awbb_GridConst_1[0] 2 70000EE0*/
+ 0x0F12034B, /*awbb_GridConst_1[1] 2 70000EE2*/
+ 0x0F120399, /*awbb_GridConst_1[2] 2 70000EE4*/
+ 0x0F12102D, /*awbb_GridConst_2[0] 2 70000EE6*/
+ 0x0F1210DE, /*awbb_GridConst_2[1] 2 70000EE8*/
+ 0x0F12116E, /*awbb_GridConst_2[2] 2 70000EEA*/
+ 0x0F12117B, /*awbb_GridConst_2[3] 2 70000EEC*/
+ 0x0F121206, /*awbb_GridConst_2[4] 2 70000EEE*/
+ 0x0F12127F, /*awbb_GridConst_2[5] 2 70000EF0*/
+ 0x0F1202C4, /*awbb_GridCoeff_R_1 2 70000EF2*/
+ 0x0F1202E4, /*awbb_GridCoeff_B_1 2 70000EF4*/
+ 0x0F1200C3, /*awbb_GridCoeff_R_2 2 70000EF6*/
+ 0x0F1200A6, /*awbb_GridCoeff_B_2 2 70000EF8*/
+ 0x002A0ED0,
+ 0x0F12000A, /*awbb_GridCorr_R[0][0] 2 70000ED0*/
+ 0x0F120028, /*awbb_GridCorr_R[0][1] 2 70000ED2*/
+ 0x0F120028, /*awbb_GridCorr_R[0][2] 2 70000ED4*/
+ 0x0F12FFEC, /*awbb_GridCorr_R[0][3] 2 70000ED6*/
+ 0x0F12FFEC, /*awbb_GridCorr_R[0][4] 2 70000ED8*/
+ 0x0F12001E, /*awbb_GridCorr_R[0][5] 2 70000EDA*/
+ 0x0F12000A, /*awbb_GridCorr_R[1][0] 2 70000EDC*/
+ 0x0F120028, /*awbb_GridCorr_R[1][1] 2 70000EDE*/
+ 0x0F120028, /*awbb_GridCorr_R[1][2] 2 70000EE0*/
+ 0x0F12FFEC, /*awbb_GridCorr_R[1][3] 2 70000EE2*/
+ 0x0F12FFEC, /*awbb_GridCorr_R[1][4] 2 70000EE4*/
+ 0x0F12001E, /*awbb_GridCorr_R[1][5] 2 70000EE6*/
+ 0x0F12000A, /*awbb_GridCorr_R[2][0] 2 70000EE8*/
+ 0x0F120028, /*awbb_GridCorr_R[2][1] 2 70000EEA*/
+ 0x0F120028, /*awbb_GridCorr_R[2][2] 2 70000EEC*/
+ 0x0F12FFEC, /*awbb_GridCorr_R[2][3] 2 70000EEE*/
+ 0x0F12FFEC, /*awbb_GridCorr_R[2][4] 2 70000EF0*/
+ 0x0F12001E, /*awbb_GridCorr_R[2][5] 2 70000EF2*/
+ 0x0F12FFD8, /*awbb_GridCorr_B[0][0] 2 70000EF4*/
+ 0x0F12003C, /*awbb_GridCorr_B[0][1] 2 70000EF6*/
+ 0x0F12003C, /*awbb_GridCorr_B[0][2] 2 70000EF8*/
+ 0x0F120000, /*awbb_GridCorr_B[0][3] 2 70000EFA*/
+ 0x0F120000, /*awbb_GridCorr_B[0][4] 2 70000EFC*/
+ 0x0F12001E, /*awbb_GridCorr_B[0][5] 2 70000EFE*/
+ 0x0F12FFD8, /*awbb_GridCorr_B[1][0] 2 70000F00*/
+ 0x0F12003C, /*awbb_GridCorr_B[1][1] 2 70000F02*/
+ 0x0F12003C, /*awbb_GridCorr_B[1][2] 2 70000F04*/
+ 0x0F120000, /*awbb_GridCorr_B[1][3] 2 70000F06*/
+ 0x0F120000, /*awbb_GridCorr_B[1][4] 2 70000F08*/
+ 0x0F12001E, /*awbb_GridCorr_B[1][5] 2 70000F0A*/
+ 0x0F12FFD8, /*awbb_GridCorr_B[2][0] 2 70000F0C*/
+ 0x0F12003C, /*awbb_GridCorr_B[2][1] 2 70000F0E*/
+ 0x0F12003C, /*awbb_GridCorr_B[2][2] 2 70000F10*/
+ 0x0F120000, /*awbb_GridCorr_B[2][3] 2 70000F12*/
+ 0x0F120000, /*awbb_GridCorr_B[2][4] 2 70000F14*/
+ 0x0F12001E, /*awbb_GridCorr_B[2][5] 2 70000F16*/
+ 0x0F120000, /*awbb_GridCorr_R_Out[0][0] 2 70000F18*/
+ 0x0F12FFE0, /*awbb_GridCorr_R_Out[0][1] 2 70000F1A*/
+ 0x0F120000, /*awbb_GridCorr_R_Out[0][2] 2 70000F1C*/
+ 0x0F120000, /*awbb_GridCorr_R_Out[0][3] 2 70000F1E*/
+ 0x0F120000, /*awbb_GridCorr_R_Out[0][4] 2 70000F20*/
+ 0x0F120000, /*awbb_GridCorr_R_Out[0][5] 2 70000F22*/
+ 0x0F120000, /*awbb_GridCorr_R_Out[1][0] 2 70000F24*/
+ 0x0F12FFE0, /*awbb_GridCorr_R_Out[1][1] 2 70000F26*/
+ 0x0F120000, /*awbb_GridCorr_R_Out[1][2] 2 70000F28*/
+ 0x0F120000, /*awbb_GridCorr_R_Out[1][3] 2 70000F2A*/
+ 0x0F120000, /*awbb_GridCorr_R_Out[1][4] 2 70000F2C*/
+ 0x0F120000, /*awbb_GridCorr_R_Out[1][5] 2 70000F2E*/
+ 0x0F120000, /*awbb_GridCorr_R_Out[2][0] 2 70000F30*/
+ 0x0F12FFE0, /*awbb_GridCorr_R_Out[2][1] 2 70000F32*/
+ 0x0F120000, /*awbb_GridCorr_R_Out[2][2] 2 70000F34*/
+ 0x0F120000, /*awbb_GridCorr_R_Out[2][3] 2 70000F36*/
+ 0x0F120000, /*awbb_GridCorr_R_Out[2][4] 2 70000F38*/
+ 0x0F120000, /*awbb_GridCorr_R_Out[2][5] 2 70000F3A*/
+ 0x0F120000, /*awbb_GridCorr_B_Out[0][0] 2 70000F3C*/
+ 0x0F12FFDE, /*awbb_GridCorr_B_Out[0][1] 2 70000F3E*/
+ 0x0F120000, /*awbb_GridCorr_B_Out[0][2] 2 70000F40*/
+ 0x0F120000, /*awbb_GridCorr_B_Out[0][3] 2 70000F42*/
+ 0x0F120000, /*awbb_GridCorr_B_Out[0][4] 2 70000F44*/
+ 0x0F120000, /*awbb_GridCorr_B_Out[0][5] 2 70000F46*/
+ 0x0F120000, /*awbb_GridCorr_B_Out[1][0] 2 70000F48*/
+ 0x0F12FFDE, /*awbb_GridCorr_B_Out[1][1] 2 70000F4A*/
+ 0x0F120000, /*awbb_GridCorr_B_Out[1][2] 2 70000F4C*/
+ 0x0F120000, /*awbb_GridCorr_B_Out[1][3] 2 70000F4E*/
+ 0x0F120000, /*awbb_GridCorr_B_Out[1][4] 2 70000F50*/
+ 0x0F120000, /*awbb_GridCorr_B_Out[1][5] 2 70000F52*/
+ 0x0F120000, /*awbb_GridCorr_B_Out[2][0] 2 70000F54*/
+ 0x0F12FFDE, /*awbb_GridCorr_B_Out[2][1] 2 70000F56*/
+ 0x0F120000, /*awbb_GridCorr_B_Out[2][2] 2 70000F58*/
+ 0x0F120000, /*awbb_GridCorr_B_Out[2][3] 2 70000F5A*/
+ 0x0F120000, /*awbb_GridCorr_B_Out[2][4] 2 70000F5C*/
+ 0x0F120000, /*awbb_GridCorr_B_Out[2][5] 2 70000F5E*/
+ /*===================================================================*/
+ /*CCM*/
+ /*===================================================================*/
+ 0x002A05D2,
+ 0x0F1200E4, /*#SARR_AwbCcmCord 2 70000552*/
+ 0x0F1200F0, /*#SARR_AwbCcmCord_1_ 2 70000554*/
+ 0x0F120100, /*#SARR_AwbCcmCord_2_ 2 70000556*/
+ 0x0F120120, /*#SARR_AwbCcmCord_3_ 2 70000558*/
+ 0x0F120150, /*#SARR_AwbCcmCord_4_ 2 7000055A*/
+ 0x0F120180, /*#SARR_AwbCcmCord_5_ 2 7000055C*/
+ /* param_start TVAR_wbt_pBaseCcms*/
+ 0x002A05C4,
+ 0x0F123800,
+ 0x0F127000,
+ 0x002A3800,
+ 0x0F1201D0, /*TVAR_wbt_pBaseCcms[0]*/
+ 0x0F12FFA1, /*TVAR_wbt_pBaseCcms[1]*/
+ 0x0F12FFFA, /*TVAR_wbt_pBaseCcms[2]*/
+ 0x0F12FF6F, /*TVAR_wbt_pBaseCcms[3]*/
+ 0x0F120140, /*TVAR_wbt_pBaseCcms[4]*/
+ 0x0F12FF49, /*TVAR_wbt_pBaseCcms[5]*/
+ 0x0F12FFC1, /*TVAR_wbt_pBaseCcms[6]*/
+ 0x0F12001F, /*TVAR_wbt_pBaseCcms[7]*/
+ 0x0F1201BD, /*TVAR_wbt_pBaseCcms[8]*/
+ 0x0F12013F, /*TVAR_wbt_pBaseCcms[9]*/
+ 0x0F1200E1, /*TVAR_wbt_pBaseCcms[10]*/
+ 0x0F12FF43, /*TVAR_wbt_pBaseCcms[11]*/
+ 0x0F120191, /*TVAR_wbt_pBaseCcms[12]*/
+ 0x0F12FFC0, /*TVAR_wbt_pBaseCcms[13]*/
+ 0x0F1201B7, /*TVAR_wbt_pBaseCcms[14]*/
+ 0x0F12FF30, /*TVAR_wbt_pBaseCcms[15]*/
+ 0x0F12015F, /*TVAR_wbt_pBaseCcms[16]*/
+ 0x0F120106, /*TVAR_wbt_pBaseCcms[17]*/
+ 0x0F1201D0, /*TVAR_wbt_pBaseCcms[18]*/
+ 0x0F12FFA1, /*TVAR_wbt_pBaseCcms[19]*/
+ 0x0F12FFFA, /*TVAR_wbt_pBaseCcms[20]*/
+ 0x0F12FF6F, /*TVAR_wbt_pBaseCcms[21]*/
+ 0x0F120140, /*TVAR_wbt_pBaseCcms[22]*/
+ 0x0F12FF49, /*TVAR_wbt_pBaseCcms[23]*/
+ 0x0F12FFC1, /*TVAR_wbt_pBaseCcms[24]*/
+ 0x0F12001F, /*TVAR_wbt_pBaseCcms[25]*/
+ 0x0F1201BD, /*TVAR_wbt_pBaseCcms[26]*/
+ 0x0F12013F, /*TVAR_wbt_pBaseCcms[27]*/
+ 0x0F1200E1, /*TVAR_wbt_pBaseCcms[28]*/
+ 0x0F12FF43, /*TVAR_wbt_pBaseCcms[29]*/
+ 0x0F120191, /*TVAR_wbt_pBaseCcms[30]*/
+ 0x0F12FFC0, /*TVAR_wbt_pBaseCcms[31]*/
+ 0x0F1201B7, /*TVAR_wbt_pBaseCcms[32]*/
+ 0x0F12FF30, /*TVAR_wbt_pBaseCcms[33]*/
+ 0x0F12015F, /*TVAR_wbt_pBaseCcms[34]*/
+ 0x0F120106, /*TVAR_wbt_pBaseCcms[35]*/
+ 0x0F1201D0, /*TVAR_wbt_pBaseCcms[36]*/
+ 0x0F12FFA1, /*TVAR_wbt_pBaseCcms[37]*/
+ 0x0F12FFFA, /*TVAR_wbt_pBaseCcms[38]*/
+ 0x0F12FF6F, /*TVAR_wbt_pBaseCcms[39]*/
+ 0x0F120140, /*TVAR_wbt_pBaseCcms[40]*/
+ 0x0F12FF49, /*TVAR_wbt_pBaseCcms[41]*/
+ 0x0F12FFC1, /*TVAR_wbt_pBaseCcms[42]*/
+ 0x0F12001F, /*TVAR_wbt_pBaseCcms[43]*/
+ 0x0F1201BD, /*TVAR_wbt_pBaseCcms[44]*/
+ 0x0F12013F, /*TVAR_wbt_pBaseCcms[45]*/
+ 0x0F1200E1, /*TVAR_wbt_pBaseCcms[46]*/
+ 0x0F12FF43, /*TVAR_wbt_pBaseCcms[47]*/
+ 0x0F120191, /*TVAR_wbt_pBaseCcms[48]*/
+ 0x0F12FFC0, /*TVAR_wbt_pBaseCcms[49]*/
+ 0x0F1201B7, /*TVAR_wbt_pBaseCcms[50]*/
+ 0x0F12FF30, /*TVAR_wbt_pBaseCcms[51]*/
+ 0x0F12015F, /*TVAR_wbt_pBaseCcms[52]*/
+ 0x0F120106, /*TVAR_wbt_pBaseCcms[53]*/
+ 0x0F1201D0, /*TVAR_wbt_pBaseCcms[54]*/
+ 0x0F12FFA1, /*TVAR_wbt_pBaseCcms[55]*/
+ 0x0F12FFFA, /*TVAR_wbt_pBaseCcms[56]*/
+ 0x0F12FF6F, /*TVAR_wbt_pBaseCcms[57]*/
+ 0x0F120140, /*TVAR_wbt_pBaseCcms[58]*/
+ 0x0F12FF49, /*TVAR_wbt_pBaseCcms[59]*/
+ 0x0F12FFC1, /*TVAR_wbt_pBaseCcms[60]*/
+ 0x0F12001F, /*TVAR_wbt_pBaseCcms[61]*/
+ 0x0F1201BD, /*TVAR_wbt_pBaseCcms[62]*/
+ 0x0F12013F, /*TVAR_wbt_pBaseCcms[63]*/
+ 0x0F1200E1, /*TVAR_wbt_pBaseCcms[64]*/
+ 0x0F12FF43, /*TVAR_wbt_pBaseCcms[65]*/
+ 0x0F120191, /*TVAR_wbt_pBaseCcms[66]*/
+ 0x0F12FFC0, /*TVAR_wbt_pBaseCcms[67]*/
+ 0x0F1201B7, /*TVAR_wbt_pBaseCcms[68]*/
+ 0x0F12FF30, /*TVAR_wbt_pBaseCcms[69]*/
+ 0x0F12015F, /*TVAR_wbt_pBaseCcms[70]*/
+ 0x0F120106, /*TVAR_wbt_pBaseCcms[71]*/
+ 0x0F1201BF, /*TVAR_wbt_pBaseCcms[72]*/
+ 0x0F12FFBF, /*TVAR_wbt_pBaseCcms[73]*/
+ 0x0F12FFFE, /*TVAR_wbt_pBaseCcms[74]*/
+ 0x0F12FF6D, /*TVAR_wbt_pBaseCcms[75]*/
+ 0x0F1201B4, /*TVAR_wbt_pBaseCcms[76]*/
+ 0x0F12FF66, /*TVAR_wbt_pBaseCcms[77]*/
+ 0x0F12FFCA, /*TVAR_wbt_pBaseCcms[78]*/
+ 0x0F12FFCE, /*TVAR_wbt_pBaseCcms[79]*/
+ 0x0F12017B, /*TVAR_wbt_pBaseCcms[80]*/
+ 0x0F120136, /*TVAR_wbt_pBaseCcms[81]*/
+ 0x0F120132, /*TVAR_wbt_pBaseCcms[82]*/
+ 0x0F12FF85, /*TVAR_wbt_pBaseCcms[83]*/
+ 0x0F12018B, /*TVAR_wbt_pBaseCcms[84]*/
+ 0x0F12FF73, /*TVAR_wbt_pBaseCcms[85]*/
+ 0x0F120191, /*TVAR_wbt_pBaseCcms[86]*/
+ 0x0F12FF3F, /*TVAR_wbt_pBaseCcms[87]*/
+ 0x0F12015B, /*TVAR_wbt_pBaseCcms[88]*/
+ 0x0F1200D0, /*TVAR_wbt_pBaseCcms[89]*/
+ 0x0F1201BF, /*TVAR_wbt_pBaseCcms[90]*/
+ 0x0F12FFBF, /*TVAR_wbt_pBaseCcms[91]*/
+ 0x0F12FFFE, /*TVAR_wbt_pBaseCcms[92]*/
+ 0x0F12FF6D, /*TVAR_wbt_pBaseCcms[93]*/
+ 0x0F1201B4, /*TVAR_wbt_pBaseCcms[94]*/
+ 0x0F12FF66, /*TVAR_wbt_pBaseCcms[95]*/
+ 0x0F12FFCA, /*TVAR_wbt_pBaseCcms[96]*/
+ 0x0F12FFCE, /*TVAR_wbt_pBaseCcms[97]*/
+ 0x0F12017B, /*TVAR_wbt_pBaseCcms[98]*/
+ 0x0F120136, /*TVAR_wbt_pBaseCcms[99]*/
+ 0x0F120132, /*TVAR_wbt_pBaseCcms[100]*/
+ 0x0F12FF85, /*TVAR_wbt_pBaseCcms[101]*/
+ 0x0F12018B, /*TVAR_wbt_pBaseCcms[102]*/
+ 0x0F12FF73, /*TVAR_wbt_pBaseCcms[103]*/
+ 0x0F120191, /*TVAR_wbt_pBaseCcms[104]*/
+ 0x0F12FF3F, /*TVAR_wbt_pBaseCcms[105]*/
+ 0x0F12015B, /*TVAR_wbt_pBaseCcms[106]*/
+ 0x0F1200D0, /*TVAR_wbt_pBaseCcms[107]*/
+ /* param_end TVAR_wbt_pBaseCcms*/
+ /* param_start TVAR_wbt_pOutdoorCcm*/
+ 0x002A05CC,
+ 0x0F1238D8, /*#TVAR_wbt_pOutdoorCcm*/
+ 0x0F127000,
+ 0x002A38D8,
+ 0x0F120235, /*TVAR_wbt_pOutdoorCcm[0]*/
+ 0x0F12FFEF, /*TVAR_wbt_pOutdoorCcm[1]*/
+ 0x0F120014, /*TVAR_wbt_pOutdoorCcm[2]*/
+ 0x0F12FF67, /*TVAR_wbt_pOutdoorCcm[3]*/
+ 0x0F12027D, /*TVAR_wbt_pOutdoorCcm[4]*/
+ 0x0F12FFBA, /*TVAR_wbt_pOutdoorCcm[5]*/
+ 0x0F12000D, /*TVAR_wbt_pOutdoorCcm[6]*/
+ 0x0F120062, /*TVAR_wbt_pOutdoorCcm[7]*/
+ 0x0F1202A7, /*TVAR_wbt_pOutdoorCcm[8]*/
+ 0x0F1200C9, /*TVAR_wbt_pOutdoorCcm[9]*/
+ 0x0F120123, /*TVAR_wbt_pOutdoorCcm[10]*/
+ 0x0F12FF36, /*TVAR_wbt_pOutdoorCcm[11]*/
+ 0x0F1201AD, /*TVAR_wbt_pOutdoorCcm[12]*/
+ 0x0F12FFC8, /*TVAR_wbt_pOutdoorCcm[13]*/
+ 0x0F120202, /*TVAR_wbt_pOutdoorCcm[14]*/
+ 0x0F12FFCF, /*TVAR_wbt_pOutdoorCcm[15]*/
+ 0x0F120257, /*TVAR_wbt_pOutdoorCcm[16]*/
+ 0x0F12022C, /*TVAR_wbt_pOutdoorCcm[17]*/
+ /* param_end TVAR_wbt_pOutdoorCcm*/
+ 0x002A2404,
+ 0x0F120001, /*#MVAR_AAIO_bFIT*/
+ 0x002A2408,
+ 0x0F120001, /*#MVAR_AAIO_bAutoCCMandASH*/
+ 0x002A23DC,
+ 0x0F1201DD, /*#Mon_AAIO_PrevFrmData_NormBr*/
+ /*===================================================================*/
+ /*AFIT*/
+ /*===================================================================*/
+ /* param_start afit_uNoiseIndInDoor*/
+ 0x002A065C,
+ 0x0F12004A, /*#afit_uNoiseIndInDoor_0_*/
+ 0x0F12005F, /*#afit_uNoiseIndInDoor_1_*/
+ 0x0F1200CB, /*#afit_uNoiseIndInDoor_2_*/
+ 0x0F1201E0, /*#afit_uNoiseIndInDoor_3_*/
+ 0x0F120220, /*#afit_uNoiseIndInDoor_4_*/
+ /* param_end afit_uNoiseIndInDoor*/
+ /* param_start TVAR_afit_pBaseVals*/
+ 0x002A06BC,
+ 0x0F120000, /*#AfitBaseVals AFIT16_BRIGHTNESS*/
+ 0x0F120000, /*#AfitBaseVals_0__1_ AFIT16_CONTRAST*/
+ 0x0F120014, /*#AfitBaseVals_0__2_ AFIT16_SATURATION*/
+ 0x0F120000, /*#AfitBaseVals_0__3_ AFIT16_SHARP_BLUR*/
+ 0x0F120000, /*#AfitBaseVals_0__4_ AFIT16_GLAMOUR*/
+ 0x0F1200C1, /*#AfitBaseVals_0__5_ AFIT16_sddd8a_edge_high*/
+ 0x0F1203FF, /*#AfitBaseVals_0__6_ AFIT16_Demosaicing_iSatVal*/
+ 0x0F12009C, /*#AfitBaseVals_0__7_
+ AFIT16_Sharpening_iReduceEdgeThresh*/
+ 0x0F12017C, /*#AfitBaseVals_0__8_ AFIT16_demsharpmix1_iRGBOffset*/
+ 0x0F1203FF, /*#AfitBaseVals_0__9_ AFIT16_demsharpmix1_iDemClamp*/
+ 0x0F12000C, /*#AfitBaseVals_0__10_
+ AFIT16_demsharpmix1_iLowThreshold*/
+ 0x0F120010, /*#AfitBaseVals_0__11_
+ AFIT16_demsharpmix1_iHighThreshold*/
+ 0x0F12012C, /*#AfitBaseVals_0__12_ AFIT16_demsharpmix1_iLowBright*/
+ 0x0F1203E8, /*#AfitBaseVals_0__13_ AFIT16_demsharpmix1_iHighBright*/
+ 0x0F120046, /*#AfitBaseVals_0__14_ AFIT16_demsharpmix1_iLowSat*/
+ 0x0F12005A, /*#AfitBaseVals_0__15_ AFIT16_demsharpmix1_iHighSat*/
+ 0x0F120070, /*#AfitBaseVals_0__16_ AFIT16_demsharpmix1_iTune*/
+ 0x0F12001E, /*#AfitBaseVals_0__17_ AFIT16_demsharpmix1_iHystThLow*/
+ 0x0F12001E, /*#AfitBaseVals_0__18_ AFIT16_demsharpmix1_iHystThHigh*/
+ 0x0F1201F4, /*#AfitBaseVals_0__19_ AFIT16_demsharpmix1_iHystCenter*/
+ 0x0F120046, /*#AfitBaseVals_0__20_
+ AFIT16_YUV422_DENOISE_iUVLowThresh*/
+ 0x0F120046, /*#AfitBaseVals_0__21_
+ AFIT16_YUV422_DENOISE_iUVHighThresh*/
+ 0x0F120005, /*#AfitBaseVals_0__22_
+ AFIT16_YUV422_DENOISE_iYLowThresh*/
+ 0x0F120005, /*#AfitBaseVals_0__23_
+ AFIT16_YUV422_DENOISE_iYHighThresh*/
+ 0x0F12003C, /*#AfitBaseVals_0__24_AFIT16_Sharpening_iLowSharpClamp*/
+ 0x0F120014, /*#AfitBaseVals_0__25_
+ AFIT16_Sharpening_iHighSharpClamp*/
+ 0x0F12003C, /*#AfitBaseVals_0__26_
+ AFIT16_Sharpening_iLowSharpClamp_Bin*/
+ 0x0F120014, /*#AfitBaseVals_0__27_
+ AFIT16_Sharpening_iHighSharpClamp_Bin*/
+ 0x0F12003C, /*#AfitBaseVals_0__28_
+ AFIT16_Sharpening_iLowSharpClamp_sBin*/
+ 0x0F12001E, /*#AfitBaseVals_0__29_
+ AFIT16_Sharpening_iHighSharpClamp_sBin*/
+ 0x0F120A24, /*#AfitBaseVals_0__30_
+ AFIT8_sddd8a_edge_low [7:0],
+ AFIT8_sddd8a_repl_thresh [15:8]*/
+ 0x0F121701, /*#AfitBaseVals_0__31_
+ AFIT8_sddd8a_repl_force [7:0],
+ AFIT8_sddd8a_sat_level [15:8]*/
+ 0x0F120229, /*#AfitBaseVals_0__32_AFIT8_sddd8a_sat_thr[7:0],
+ AFIT8_sddd8a_sat_mpl [15:8]*/
+ 0x0F121403, /*#AfitBaseVals_0__33_AFIT8_sddd8a_sat_noise[7:0],
+ AFIT8_sddd8a_iMaxSlopeAllowed [15:8]*/
+ 0x0F120000, /*#AfitBaseVals_0__34_AFIT8_sddd8a_iHotThreshHigh[7:0],
+ AFIT8_sddd8a_iHotThreshLow [15:8]*/
+ 0x0F120000, /*#AfitBaseVals_0__35_AFIT8_sddd8a_iColdThreshHigh[7:0],
+ AFIT8_sddd8a_iColdThreshLow [15:8]*/
+ 0x0F120000, /*#AfitBaseVals_0__36_AFIT8_sddd8a_AddNoisePower1[7:0],
+ AFIT8_sddd8a_AddNoisePower2 [15:8]*/
+ 0x0F1200FF, /*#AfitBaseVals_0__37_AFIT8_sddd8a_iSatSat[7:0],
+ AFIT8_sddd8a_iRadialTune [15:8]*/
+ 0x0F120A3B, /*#AfitBaseVals_0__38_AFIT8_sddd8a_iRadialLimit [7:0],
+ AFIT8_sddd8a_iRadialPower [15:8]*/
+ 0x0F121414, /*#AfitBaseVals_0__39_
+ AFIT8_sddd8a_iLowMaxSlopeAllowed [7:0],
+ AFIT8_sddd8a_iHighMaxSlopeAllowed [15:8]*/
+ 0x0F120301, /*#AfitBaseVals_0__40_AFIT8_sddd8a_iLowSlopeThresh[7:0],
+ AFIT8_sddd8a_iHighSlopeThresh [15:8]*/
+ 0x0F12FF07, /*#AfitBaseVals_0__41_
+ AFIT8_sddd8a_iSquaresRounding [7:0],
+ AFIT8_Demosaicing_iCentGrad [15:8]*/
+ 0x0F12081E, /*#AfitBaseVals_0__42_
+ AFIT8_Demosaicing_iMonochrom [7:0],
+ AFIT8_Demosaicing_iDecisionThresh [15:8]*/
+ 0x0F120A1E, /*#AfitBaseVals_0__43_
+ AFIT8_Demosaicing_iDesatThresh[7:0],
+ AFIT8_Demosaicing_iEnhThresh [15:8]*/
+ 0x0F120F0F, /*#AfitBaseVals_0__44_
+ AFIT8_Demosaicing_iGRDenoiseVal [7:0],
+ AFIT8_Demosaicing_iGBDenoiseVal [15:8]*/
+ 0x0F120A00, /*#AfitBaseVals_0__45_
+ AFIT8_Demosaicing_iNearGrayDesat[7:0],
+ AFIT8_Demosaicing_iDFD_ReduceCoeff [15:8]*/
+ 0x0F120012, /*#AfitBaseVals_0__46_
+ AFIT8_Sharpening_iMSharpen [7:0],
+ AFIT8_Sharpening_iMShThresh [15:8]*/
+ 0x0F12001E, /*#AfitBaseVals_0__47_AFIT8_Sharpening_iWSharpen [7:0],
+ AFIT8_Sharpening_iWShThresh [15:8]*/
+ 0x0F120002, /*#AfitBaseVals_0__48_
+ AFIT8_Sharpening_nSharpWidth [7:0],
+ AFIT8_Sharpening_iReduceNegative [15:8]*/
+ 0x0F1200FF, /*#AfitBaseVals_0__49_
+ AFIT8_Sharpening_iShDespeckle [7:0],
+ AFIT8_demsharpmix1_iRGBMultiplier [15:8]*/
+ 0x0F121102, /*#AfitBaseVals_0__50_
+ AFIT8_demsharpmix1_iFilterPower [7:0],
+ AFIT8_demsharpmix1_iBCoeff [15:8]*/
+ 0x0F12001B, /*#AfitBaseVals_0__51_AFIT8_demsharpmix1_iGCoeff [7:0],
+ AFIT8_demsharpmix1_iWideMult [15:8]*/
+ 0x0F120900, /*#AfitBaseVals_0__52_
+ AFIT8_demsharpmix1_iNarrMult [7:0],
+ AFIT8_demsharpmix1_iHystFalloff [15:8]*/
+ 0x0F120600, /*#AfitBaseVals_0__53_
+ AFIT8_demsharpmix1_iHystMinMult [7:0],
+ AFIT8_demsharpmix1_iHystWidth [15:8]*/
+ 0x0F120504, /*#AfitBaseVals_0__54_
+ AFIT8_demsharpmix1_iHystFallLow [7:0],
+ AFIT8_demsharpmix1_iHystFallHigh [15:8]*/
+ 0x0F120306, /*#AfitBaseVals_0__55_
+ AFIT8_demsharpmix1_iHystTune [7:0],
+ * AFIT8_YUV422_DENOISE_iUVSupport [15:8]*/
+ 0x0F128003, /*#AfitBaseVals_0__56_
+ AFIT8_YUV422_DENOISE_iYSupport [7:0],
+ AFIT8_byr_cgras_iShadingPower [15:8]*/
+ 0x0F121982, /*#AfitBaseVals_0__57_
+ AFIT8_RGBGamma2_iLinearity [7:0],
+ AFIT8_RGBGamma2_iDarkReduce [15:8]*/
+ 0x0F120A80, /*#AfitBaseVals_0__58_
+ AFIT8_ccm_oscar_iSaturation[7:0],
+ AFIT8_RGB2YUV_iYOffset [15:8]*/
+ 0x0F120080, /*#AfitBaseVals_0__59_
+ AFIT8_RGB2YUV_iRGBGain [7:0],
+ AFIT8_RGB2YUV_iSaturation [15:8]*/
+ 0x0F121414, /*#AfitBaseVals_0__60_
+ AFIT8_sddd8a_iClustThresh_H [7:0],
+ AFIT8_sddd8a_iClustThresh_C [15:8]*/
+ 0x0F120101, /*#AfitBaseVals_0__61_
+ AFIT8_sddd8a_iClustMulT_H [7:0],
+ AFIT8_sddd8a_iClustMulT_C [15:8]*/
+ 0x0F124601, /*#AfitBaseVals_0__62_AFIT8_sddd8a_nClustLevel_H [7:0],
+ AFIT8_sddd8a_DispTH_Low [15:8]*/
+ 0x0F126444, /*#AfitBaseVals_0__63_AFIT8_sddd8a_DispTH_High [7:0],
+ AFIT8_sddd8a_iDenThreshLow [15:8]*/
+ 0x0F129650, /*#AfitBaseVals_0__64_AFIT8_sddd8a_iDenThreshHigh[7:0],
+ AFIT8_Demosaicing_iEdgeDesat [15:8]*/
+ 0x0F120000, /*#AfitBaseVals_0__65_
+ AFIT8_Demosaicing_iEdgeDesatThrLow [7:0],
+ AFIT8_Demosaicing_iEdgeDesatThrHigh [15:8]*/
+ 0x0F120003, /*#AfitBaseVals_0__66_
+ AFIT8_Demosaicing_iEdgeDesatLimit[7:0],
+ AFIT8_Demosaicing_iDemSharpenLow [15:8]*/
+ 0x0F121E00, /*#AfitBaseVals_0__67_
+ AFIT8_Demosaicing_iDemSharpenHigh[7:0],
+ AFIT8_Demosaicing_iDemSharpThresh [15:8]*/
+ 0x0F120714, /*#AfitBaseVals_0__68_
+ AFIT8_Demosaicing_iDemShLowLimit [7:0],
+ AFIT8_Demosaicing_iDespeckleForDemsharp [15:8]*/
+ 0x0F121464, /*#AfitBaseVals_0__69_
+ AFIT8_Demosaicing_iDemBlurLow[7:0],
+ AFIT8_Demosaicing_iDemBlurHigh [15:8]*/
+ 0x0F121404, /*#AfitBaseVals_0__70_
+ AFIT8_Demosaicing_iDemBlurRange[7:0],
+ AFIT8_Sharpening_iLowSharpPower [15:8]*/
+ 0x0F120F14, /*#AfitBaseVals_0__71_
+ AFIT8_Sharpening_iHighSharpPower[7:0],
+ AFIT8_Sharpening_iLowShDenoise [15:8]*/
+ 0x0F12400F, /*#AfitBaseVals_0__72_
+ AFIT8_Sharpening_iHighShDenoise [7:0],
+ AFIT8_Sharpening_iReduceEdgeMinMult [15:8]*/
+ 0x0F120204, /*#AfitBaseVals_0__73_
+ AFIT8_Sharpening_iReduceEdgeSlope [7:0],
+ AFIT8_demsharpmix1_iWideFiltReduce [15:8]*/
+ 0x0F121403, /*#AfitBaseVals_0__74_
+ AFIT8_demsharpmix1_iNarrFiltReduce [7:0],
+ AFIT8_sddd8a_iClustThresh_H_Bin [15:8]*/
+ 0x0F120114, /*#AfitBaseVals_0__75_
+ AFIT8_sddd8a_iClustThresh_C_Bin [7:0],
+ AFIT8_sddd8a_iClustMulT_H_Bin [15:8]*/
+ 0x0F120101, /*#AfitBaseVals_0__76_
+ AFIT8_sddd8a_iClustMulT_C_Bin [7:0],
+ AFIT8_sddd8a_nClustLevel_H_Bin [15:8]*/
+ 0x0F124446, /*#AfitBaseVals_0__77_
+ AFIT8_sddd8a_DispTH_Low_Bin [7:0],
+ AFIT8_sddd8a_DispTH_High_Bin [15:8]*/
+ 0x0F125064, /*#AfitBaseVals_0__78_
+ AFIT8_sddd8a_iDenThreshLow_Bin [7:0],
+ AFIT8_sddd8a_iDenThreshHigh_Bin [15:8]*/
+ 0x0F120028, /*#AfitBaseVals_0__79_
+ AFIT8_Demosaicing_iEdgeDesat_Bin[7:0],
+ AFIT8_Demosaicing_iEdgeDesatThrLow_Bin [15:8]*/
+ 0x0F120300, /*#AfitBaseVals_0__80_
+ AFIT8_Demosaicing_iEdgeDesatThrHigh_Bin [7:0],
+ AFIT8_Demosaicing_iEdgeDesatLimit_Bin [15:8]*/
+ 0x0F120000, /*#AfitBaseVals_0__81_
+ AFIT8_Demosaicing_iDemSharpenLow_Bin [7:0],
+ AFIT8_Demosaicing_iDemSharpenHigh_Bin [15:8]*/
+ 0x0F12141E, /*#AfitBaseVals_0__82_
+ AFIT8_Demosaicing_iDemSharpThresh_Bin [7:0],
+ AFIT8_Demosaicing_iDemShLowLimit_Bin [15:8]*/
+ 0x0F126407, /*#AfitBaseVals_0__83_
+ AFIT8_Demosaicing_iDespeckleForDemsharp_Bin [7:0],
+ AFIT8_Demosaicing_iDemBlurLow_Bin [15:8]*/
+ 0x0F120414, /*#AfitBaseVals_0__84_
+ AFIT8_Demosaicing_iDemBlurHigh_Bin [7:0],
+ AFIT8_Demosaicing_iDemBlurRange_Bin [15:8]*/
+ 0x0F121414, /*#AfitBaseVals_0__85_
+ AFIT8_Sharpening_iLowSharpPower_Bin [7:0],
+ AFIT8_Sharpening_iHighSharpPower_Bin [15:8]*/
+ 0x0F120F0F, /*#AfitBaseVals_0__86_
+ AFIT8_Sharpening_iLowShDenoise_Bin [7:0],
+ AFIT8_Sharpening_iHighShDenoise_Bin [15:8]*/
+ 0x0F120440, /*#AfitBaseVals_0__87_
+ AFIT8_Sharpening_iReduceEdgeMinMult_Bin [7:0],
+ AFIT8_Sharpening_iReduceEdgeSlope_Bin [15:8]*/
+ 0x0F120302, /*#AfitBaseVals_0__88_
+ AFIT8_demsharpmix1_iWideFiltReduce_Bin [7:0],
+ AFIT8_demsharpmix1_iNarrFiltReduce_Bin [15:8]*/
+ 0x0F121414, /*#AfitBaseVals_0__89_
+ AFIT8_sddd8a_iClustThresh_H_sBin[7:0],
+ AFIT8_sddd8a_iClustThresh_C_sBin [15:8]*/
+ 0x0F120101, /*#AfitBaseVals_0__90_
+ AFIT8_sddd8a_iClustMulT_H_sBin [7:0],
+ AFIT8_sddd8a_iClustMulT_C_sBin [15:8]*/
+ 0x0F124601, /*#AfitBaseVals_0__91_
+ AFIT8_sddd8a_nClustLevel_H_sBin [7:0],
+ AFIT8_sddd8a_DispTH_Low_sBin [15:8]*/
+ 0x0F126E44, /*#AfitBaseVals_0__92_
+ AFIT8_sddd8a_DispTH_High_sBin [7:0],
+ AFIT8_sddd8a_iDenThreshLow_sBin [15:8]*/
+ 0x0F122864, /*#AfitBaseVals_0__93_
+ AFIT8_sddd8a_iDenThreshHigh_sBin[7:0],
+ AFIT8_Demosaicing_iEdgeDesat_sBin [15:8]*/
+ 0x0F120A00, /*#AfitBaseVals_0__94_
+ AFIT8_Demosaicing_iEdgeDesatThrLow_sBin [7:0],
+ AFIT8_Demosaicing_iEdgeDesatThrHigh_sBin [15:8]*/
+ 0x0F120003, /*#AfitBaseVals_0__95_
+ AFIT8_Demosaicing_iEdgeDesatLimit_sBin [7:0],
+ AFIT8_Demosaicing_iDemSharpenLow_sBin [15:8]*/
+ 0x0F121E00, /*#AfitBaseVals_0__96_
+ AFIT8_Demosaicing_iDemSharpenHigh_sBin [7:0],
+ AFIT8_Demosaicing_iDemSharpThresh_sBin [15:8]*/
+ 0x0F120714, /*#AfitBaseVals_0__97_
+ AFIT8_Demosaicing_iDemShLowLimit_sBin [7:0],
+ AFIT8_Demosaicing_iDespeckleForDemsharp_sBin [15:8]*/
+ 0x0F1232FF, /*#AfitBaseVals_0__98_
+ AFIT8_Demosaicing_iDemBlurLow_sBin [7:0],
+ AFIT8_Demosaicing_iDemBlurHigh_sBin [15:8]*/
+ 0x0F120004, /*#AfitBaseVals_0__99_
+ AFIT8_Demosaicing_iDemBlurRange_sBin [7:0],
+ AFIT8_Sharpening_iLowSharpPower_sBin [15:8]*/
+ 0x0F120F00, /*#AfitBaseVals_0__100_
+ AFIT8_Sharpening_iHighSharpPower_sBin [7:0],
+ AFIT8_Sharpening_iLowShDenoise_sBin [15:8]*/
+ 0x0F12400F, /*#AfitBaseVals_0__101_
+ AFIT8_Sharpening_iHighShDenoise_sBin [7:0],
+ AFIT8_Sharpening_iReduceEdgeMinMult_sBin [15:8]*/
+ 0x0F120204, /*#AfitBaseVals_0__102_
+ AFIT8_Sharpening_iReduceEdgeSlope_sBin [7:0],
+ AFIT8_demsharpmix1_iWideFiltReduce_sBin [15:8]*/
+ 0x0F120003, /*#AfitBaseVals_0__103_
+ AFIT8_demsharpmix1_iNarrFiltReduce_sBin [7:0]*/
+ 0x0F120000, /*#AfitBaseVals_1__0_ AFIT16_BRIGHTNESS*/
+ 0x0F120000, /*#AfitBaseVals_1__1_ AFIT16_CONTRAST*/
+ 0x0F120014, /*#AfitBaseVals_1__2_ AFIT16_SATURATION*/
+ 0x0F120000, /*#AfitBaseVals_1__3_ AFIT16_SHARP_BLUR*/
+ 0x0F120000, /*#AfitBaseVals_1__4_ AFIT16_GLAMOUR*/
+ 0x0F1200C1, /*#AfitBaseVals_1__5_ AFIT16_sddd8a_edge_high*/
+ 0x0F1203FF, /*#AfitBaseVals_1__6_ AFIT16_Demosaicing_iSatVal*/
+ 0x0F12009C, /*#AfitBaseVals_1__7_
+ AFIT16_Sharpening_iReduceEdgeThresh*/
+ 0x0F12017C, /*#AfitBaseVals_1__8_ AFIT16_demsharpmix1_iRGBOffset*/
+ 0x0F1203FF, /*#AfitBaseVals_1__9_ AFIT16_demsharpmix1_iDemClamp*/
+ 0x0F12000C, /*#AfitBaseVals_1__10_
+ AFIT16_demsharpmix1_iLowThreshold*/
+ 0x0F120010, /*#AfitBaseVals_1__11_
+ AFIT16_demsharpmix1_iHighThreshold*/
+ 0x0F12012C, /*#AfitBaseVals_1__12_AFIT16_demsharpmix1_iLowBright*/
+ 0x0F1203E8, /*#AfitBaseVals_1__13_AFIT16_demsharpmix1_iHighBright*/
+ 0x0F120046, /*#AfitBaseVals_1__14_AFIT16_demsharpmix1_iLowSat*/
+ 0x0F12005A, /*#AfitBaseVals_1__15_AFIT16_demsharpmix1_iHighSat*/
+ 0x0F120070, /*#AfitBaseVals_1__16_AFIT16_demsharpmix1_iTune*/
+ 0x0F120008, /*#AfitBaseVals_1__17_AFIT16_demsharpmix1_iHystThLow*/
+ 0x0F120000, /*#AfitBaseVals_1__18_AFIT16_demsharpmix1_iHystThHigh*/
+ 0x0F120320, /*#AfitBaseVals_1__19_AFIT16_demsharpmix1_iHystCenter*/
+ 0x0F120046, /*#AfitBaseVals_1__20_
+ AFIT16_YUV422_DENOISE_iUVLowThresh*/
+ 0x0F120046, /*#AfitBaseVals_1__21_
+ AFIT16_YUV422_DENOISE_iUVHighThresh*/
+ 0x0F120000, /*#AfitBaseVals_1__22_
+ AFIT16_YUV422_DENOISE_iYLowThresh*/
+ 0x0F120000, /*#AfitBaseVals_1__23_
+ AFIT16_YUV422_DENOISE_iYHighThresh*/
+ 0x0F120064, /*#AfitBaseVals_1__24_AFIT16_Sharpening_iLowSharpClamp*/
+ 0x0F120014, /*#AfitBaseVals_1__25_
+ AFIT16_Sharpening_iHighSharpClamp*/
+ 0x0F120064, /*#AfitBaseVals_1__26_
+ AFIT16_Sharpening_iLowSharpClamp_Bin*/
+ 0x0F120014, /*#AfitBaseVals_1__27_
+ AFIT16_Sharpening_iHighSharpClamp_Bin*/
+ 0x0F12003C, /*#AfitBaseVals_1__28_
+ AFIT16_Sharpening_iLowSharpClamp_sBin*/
+ 0x0F12001E, /*#AfitBaseVals_1__29_
+ AFIT16_Sharpening_iHighSharpClamp_sBin*/
+ 0x0F120A24, /*#AfitBaseVals_1__30_
+ AFIT8_sddd8a_edge_low [7:0],
+ AFIT8_sddd8a_repl_thresh [15:8]*/
+ 0x0F121701, /*#AfitBaseVals_1__31_AFIT8_sddd8a_repl_force [7:0],
+ AFIT8_sddd8a_sat_level [15:8]*/
+ 0x0F120229, /*#AfitBaseVals_1__32_AFIT8_sddd8a_sat_thr[7:0],
+ AFIT8_sddd8a_sat_mpl [15:8]*/
+ 0x0F121403, /*#AfitBaseVals_1__33_AFIT8_sddd8a_sat_noise[7:0],
+ AFIT8_sddd8a_iMaxSlopeAllowed [15:8]*/
+ 0x0F120000, /*#AfitBaseVals_1__34_
+ AFIT8_sddd8a_iHotThreshHigh[7:0],
+ AFIT8_sddd8a_iHotThreshLow [15:8]*/
+ 0x0F120000, /*#AfitBaseVals_1__35_
+ AFIT8_sddd8a_iColdThreshHigh[7:0],
+ AFIT8_sddd8a_iColdThreshLow [15:8]*/
+ 0x0F120000, /*#AfitBaseVals_1__36_
+ AFIT8_sddd8a_AddNoisePower1[7:0],
+ AFIT8_sddd8a_AddNoisePower2 [15:8]*/
+ 0x0F1200FF, /*#AfitBaseVals_1__37_
+ AFIT8_sddd8a_iSatSat[7:0],
+ AFIT8_sddd8a_iRadialTune [15:8]*/
+ 0x0F12033B, /*#AfitBaseVals_1__38_
+ AFIT8_sddd8a_iRadialLimit [7:0],
+ AFIT8_sddd8a_iRadialPower [15:8]*/
+ 0x0F121414, /*#AfitBaseVals_1__39_
+ AFIT8_sddd8a_iLowMaxSlopeAllowed [7:0],
+ AFIT8_sddd8a_iHighMaxSlopeAllowed [15:8]*/
+ 0x0F120301, /*#AfitBaseVals_1__40_
+ AFIT8_sddd8a_iLowSlopeThresh[7:0],
+ AFIT8_sddd8a_iHighSlopeThresh [15:8]*/
+ 0x0F12FF07, /*#AfitBaseVals_1__41_
+ AFIT8_sddd8a_iSquaresRounding [7:0],
+ AFIT8_Demosaicing_iCentGrad [15:8]*/
+ 0x0F12081E, /*#AfitBaseVals_1__42_
+ AFIT8_Demosaicing_iMonochrom [7:0],
+ AFIT8_Demosaicing_iDecisionThresh [15:8]*/
+ 0x0F120A1E, /*#AfitBaseVals_1__43_
+ AFIT8_Demosaicing_iDesatThresh [7:0],
+ AFIT8_Demosaicing_iEnhThresh [15:8]*/
+ 0x0F120F0F, /*#AfitBaseVals_1__44_
+ AFIT8_Demosaicing_iGRDenoiseVal [7:0],
+ AFIT8_Demosaicing_iGBDenoiseVal [15:8]*/
+ 0x0F120A00, /*#AfitBaseVals_1__45_
+ AFIT8_Demosaicing_iNearGrayDesat[7:0],
+ AFIT8_Demosaicing_iDFD_ReduceCoeff [15:8]*/
+ 0x0F120012, /*#AfitBaseVals_1__46_
+ AFIT8_Sharpening_iMSharpen [7:0],
+ AFIT8_Sharpening_iMShThresh [15:8]*/
+ 0x0F120005, /*#AfitBaseVals_1__47_AFIT8_Sharpening_iWSharpen [7:0],
+ AFIT8_Sharpening_iWShThresh [15:8]*/
+ 0x0F120002, /*#AfitBaseVals_1__48_
+ AFIT8_Sharpening_nSharpWidth [7:0],
+ AFIT8_Sharpening_iReduceNegative [15:8]*/
+ 0x0F1200FF, /*#AfitBaseVals_1__49_
+ AFIT8_Sharpening_iShDespeckle [7:0],
+ AFIT8_demsharpmix1_iRGBMultiplier [15:8]*/
+ 0x0F121102, /*#AfitBaseVals_1__50_
+ AFIT8_demsharpmix1_iFilterPower [7:0],
+ AFIT8_demsharpmix1_iBCoeff [15:8]*/
+ 0x0F12001B, /*#AfitBaseVals_1__51_
+ AFIT8_demsharpmix1_iGCoeff [7:0],
+ AFIT8_demsharpmix1_iWideMult [15:8]*/
+ 0x0F120900, /*#AfitBaseVals_1__52_
+ AFIT8_demsharpmix1_iNarrMult [7:0],
+ AFIT8_demsharpmix1_iHystFalloff [15:8]*/
+ 0x0F120600, /*#AfitBaseVals_1__53_
+ AFIT8_demsharpmix1_iHystMinMult [7:0],
+ AFIT8_demsharpmix1_iHystWidth [15:8]*/
+ 0x0F120504, /*#AfitBaseVals_1__54_
+ AFIT8_demsharpmix1_iHystFallLow [7:0],
+ AFIT8_demsharpmix1_iHystFallHigh [15:8]*/
+ 0x0F120306, /*#AfitBaseVals_1__55_
+ AFIT8_demsharpmix1_iHystTune [7:0],
+ * AFIT8_YUV422_DENOISE_iUVSupport [15:8]*/
+ 0x0F128003, /*#AfitBaseVals_1__56_
+ AFIT8_YUV422_DENOISE_iYSupport [7:0],
+ AFIT8_byr_cgras_iShadingPower [15:8]*/
+ 0x0F120A6E, /*#AfitBaseVals_1__57_
+ AFIT8_RGBGamma2_iLinearity [7:0],
+ AFIT8_RGBGamma2_iDarkReduce [15:8]*/
+ 0x0F120080, /*#AfitBaseVals_1__58_
+ AFIT8_ccm_oscar_iSaturation[7:0],
+ AFIT8_RGB2YUV_iYOffset [15:8]*/
+ 0x0F120080, /*#AfitBaseVals_1__59_
+ AFIT8_RGB2YUV_iRGBGain [7:0],
+ AFIT8_RGB2YUV_iSaturation [15:8]*/
+ 0x0F125050, /*#AfitBaseVals_1__60_
+ AFIT8_sddd8a_iClustThresh_H [7:0],
+ AFIT8_sddd8a_iClustThresh_C [15:8]*/
+ 0x0F120101, /*#AfitBaseVals_1__61_
+ AFIT8_sddd8a_iClustMulT_H [7:0],
+ AFIT8_sddd8a_iClustMulT_C [15:8]*/
+ 0x0F122801, /*#AfitBaseVals_1__62_
+ AFIT8_sddd8a_nClustLevel_H [7:0],
+ AFIT8_sddd8a_DispTH_Low [15:8]*/
+ 0x0F12231E, /*#AfitBaseVals_1__63_
+ AFIT8_sddd8a_DispTH_High [7:0],
+ AFIT8_sddd8a_iDenThreshLow [15:8]*/
+ 0x0F12961E, /*#AfitBaseVals_1__64_
+ AFIT8_sddd8a_iDenThreshHigh[7:0],
+ AFIT8_Demosaicing_iEdgeDesat [15:8]*/
+ 0x0F120000, /*#AfitBaseVals_1__65_
+ AFIT8_Demosaicing_iEdgeDesatThrLow [7:0],
+ AFIT8_Demosaicing_iEdgeDesatThrHigh [15:8]*/
+ 0x0F120003, /*#AfitBaseVals_1__66_
+ AFIT8_Demosaicing_iEdgeDesatLimit[7:0],
+ AFIT8_Demosaicing_iDemSharpenLow [15:8]*/
+ 0x0F120A02, /*#AfitBaseVals_1__67_
+ AFIT8_Demosaicing_iDemSharpenHigh[7:0],
+ AFIT8_Demosaicing_iDemSharpThresh [15:8]*/
+ 0x0F120764, /*#AfitBaseVals_1__68_
+ AFIT8_Demosaicing_iDemShLowLimit [7:0],
+ AFIT8_Demosaicing_iDespeckleForDemsharp [15:8]*/
+ 0x0F12143C, /*#AfitBaseVals_1__69_
+ AFIT8_Demosaicing_iDemBlurLow[7:0],
+ AFIT8_Demosaicing_iDemBlurHigh [15:8]*/
+ 0x0F121401, /*#AfitBaseVals_1__70_
+ AFIT8_Demosaicing_iDemBlurRange[7:0],
+ AFIT8_Sharpening_iLowSharpPower [15:8]*/
+ 0x0F120F14, /*#AfitBaseVals_1__71_
+ AFIT8_Sharpening_iHighSharpPower[7:0],
+ AFIT8_Sharpening_iLowShDenoise [15:8]*/
+ 0x0F12400F, /*#AfitBaseVals_1__72_
+ AFIT8_Sharpening_iHighShDenoise [7:0],
+ AFIT8_Sharpening_iReduceEdgeMinMult [15:8]*/
+ 0x0F120204, /*#AfitBaseVals_1__73_
+ AFIT8_Sharpening_iReduceEdgeSlope [7:0],
+ AFIT8_demsharpmix1_iWideFiltReduce [15:8]*/
+ 0x0F125003, /*#AfitBaseVals_1__74_
+ AFIT8_demsharpmix1_iNarrFiltReduce [7:0],
+ AFIT8_sddd8a_iClustThresh_H_Bin [15:8]*/
+ 0x0F120150, /*#AfitBaseVals_1__75_
+ AFIT8_sddd8a_iClustThresh_C_Bin [7:0],
+ AFIT8_sddd8a_iClustMulT_H_Bin [15:8]*/
+ 0x0F120101, /*#AfitBaseVals_1__76_
+ AFIT8_sddd8a_iClustMulT_C_Bin [7:0],
+ AFIT8_sddd8a_nClustLevel_H_Bin [15:8]*/
+ 0x0F121E28, /*#AfitBaseVals_1__77_
+ AFIT8_sddd8a_DispTH_Low_Bin [7:0],
+ AFIT8_sddd8a_DispTH_High_Bin [15:8]*/
+ 0x0F12140F, /*#AfitBaseVals_1__78_
+ AFIT8_sddd8a_iDenThreshLow_Bin [7:0],
+ AFIT8_sddd8a_iDenThreshHigh_Bin [15:8]*/
+ 0x0F120028, /*#AfitBaseVals_1__79_
+ AFIT8_Demosaicing_iEdgeDesat_Bin[7:0],
+ AFIT8_Demosaicing_iEdgeDesatThrLow_Bin [15:8]*/
+ 0x0F120300, /*#AfitBaseVals_1__80_
+ AFIT8_Demosaicing_iEdgeDesatThrHigh_Bin [7:0],
+ AFIT8_Demosaicing_iEdgeDesatLimit_Bin [15:8]*/
+ 0x0F120200, /*#AfitBaseVals_1__81_
+ AFIT8_Demosaicing_iDemSharpenLow_Bin [7:0],
+ AFIT8_Demosaicing_iDemSharpenHigh_Bin [15:8]*/
+ 0x0F121E0A, /*#AfitBaseVals_1__82_
+ AFIT8_Demosaicing_iDemSharpThresh_Bin [7:0],
+ AFIT8_Demosaicing_iDemShLowLimit_Bin [15:8]*/
+ 0x0F123C07, /*#AfitBaseVals_1__83_
+ AFIT8_Demosaicing_iDespeckleForDemsharp_Bin [7:0],
+ AFIT8_Demosaicing_iDemBlurLow_Bin [15:8]*/
+ 0x0F120114, /*#AfitBaseVals_1__84_
+ AFIT8_Demosaicing_iDemBlurHigh_Bin [7:0],
+ AFIT8_Demosaicing_iDemBlurRange_Bin [15:8]*/
+ 0x0F121414, /*#AfitBaseVals_1__85_
+ AFIT8_Sharpening_iLowSharpPower_Bin [7:0],
+ AFIT8_Sharpening_iHighSharpPower_Bin [15:8]*/
+ 0x0F120F0F, /*#AfitBaseVals_1__86_
+ AFIT8_Sharpening_iLowShDenoise_Bin [7:0],
+ AFIT8_Sharpening_iHighShDenoise_Bin [15:8]*/
+ 0x0F120440, /*#AfitBaseVals_1__87_
+ AFIT8_Sharpening_iReduceEdgeMinMult_Bin [7:0],
+ AFIT8_Sharpening_iReduceEdgeSlope_Bin [15:8]*/
+ 0x0F120302, /*#AfitBaseVals_1__88_
+ AFIT8_demsharpmix1_iWideFiltReduce_Bin [7:0],
+ AFIT8_demsharpmix1_iNarrFiltReduce_Bin [15:8]*/
+ 0x0F121E1E, /*#AfitBaseVals_1__89_
+ AFIT8_sddd8a_iClustThresh_H_sBin[7:0],
+ AFIT8_sddd8a_iClustThresh_C_sBin [15:8]*/
+ 0x0F120101, /*#AfitBaseVals_1__90_
+ AFIT8_sddd8a_iClustMulT_H_sBin [7:0],
+ AFIT8_sddd8a_iClustMulT_C_sBin [15:8]*/
+ 0x0F123C01, /*#AfitBaseVals_1__91_
+ AFIT8_sddd8a_nClustLevel_H_sBin [7:0],
+ AFIT8_sddd8a_DispTH_Low_sBin [15:8]*/
+ 0x0F125A3A, /*#AfitBaseVals_1__92_
+ AFIT8_sddd8a_DispTH_High_sBin [7:0],
+ AFIT8_sddd8a_iDenThreshLow_sBin [15:8]*/
+ 0x0F122858, /*#AfitBaseVals_1__93_
+ AFIT8_sddd8a_iDenThreshHigh_sBin[7:0],
+ AFIT8_Demosaicing_iEdgeDesat_sBin [15:8]*/
+ 0x0F120A00, /*#AfitBaseVals_1__94_
+ AFIT8_Demosaicing_iEdgeDesatThrLow_sBin [7:0],
+ AFIT8_Demosaicing_iEdgeDesatThrHigh_sBin [15:8]*/
+ 0x0F120003, /*#AfitBaseVals_1__95_
+ AFIT8_Demosaicing_iEdgeDesatLimit_sBin [7:0],
+ AFIT8_Demosaicing_iDemSharpenLow_sBin [15:8]*/
+ 0x0F121E00, /*#AfitBaseVals_1__96_
+ AFIT8_Demosaicing_iDemSharpenHigh_sBin [7:0],
+ AFIT8_Demosaicing_iDemSharpThresh_sBin [15:8]*/
+ 0x0F120714, /*#AfitBaseVals_1__97_
+ AFIT8_Demosaicing_iDemShLowLimit_sBin [7:0],
+ AFIT8_Demosaicing_iDespeckleForDemsharp_sBin [15:8]*/
+ 0x0F1232FF, /*#AfitBaseVals_1__98_
+ AFIT8_Demosaicing_iDemBlurLow_sBin [7:0],
+ AFIT8_Demosaicing_iDemBlurHigh_sBin [15:8]*/
+ 0x0F120004, /*#AfitBaseVals_1__99_
+ AFIT8_Demosaicing_iDemBlurRange_sBin [7:0],
+ AFIT8_Sharpening_iLowSharpPower_sBin [15:8]*/
+ 0x0F120F00, /*#AfitBaseVals_1__100_
+ AFIT8_Sharpening_iHighSharpPower_sBin [7:0],
+ AFIT8_Sharpening_iLowShDenoise_sBin [15:8]*/
+ 0x0F12400F, /*#AfitBaseVals_1__101_
+ AFIT8_Sharpening_iHighShDenoise_sBin [7:0],
+ AFIT8_Sharpening_iReduceEdgeMinMult_sBin [15:8]*/
+ 0x0F120204, /*#AfitBaseVals_1__102_
+ AFIT8_Sharpening_iReduceEdgeSlope_sBin [7:0],
+ AFIT8_demsharpmix1_iWideFiltReduce_sBin [15:8]*/
+ 0x0F120003, /*#AfitBaseVals_1__103_
+ AFIT8_demsharpmix1_iNarrFiltReduce_sBin [7:0]*/
+ 0x0F120000, /*#AfitBaseVals_2__0_AFIT16_BRIGHTNESS*/
+ 0x0F120000, /*#AfitBaseVals_2__1_AFIT16_CONTRAST*/
+ 0x0F120000, /*#AfitBaseVals_2__2_AFIT16_SATURATION*/
+ 0x0F120000, /*#AfitBaseVals_2__3_AFIT16_SHARP_BLUR*/
+ 0x0F120000, /*#AfitBaseVals_2__4_AFIT16_GLAMOUR*/
+ 0x0F1200C1, /*#AfitBaseVals_2__5_AFIT16_sddd8a_edge_high*/
+ 0x0F1203FF, /*#AfitBaseVals_2__6_AFIT16_Demosaicing_iSatVal*/
+ 0x0F12009C, /*#AfitBaseVals_2__7_
+ AFIT16_Sharpening_iReduceEdgeThresh*/
+ 0x0F12017C, /*#AfitBaseVals_2__8_AFIT16_demsharpmix1_iRGBOffset*/
+ 0x0F1203FF, /*#AfitBaseVals_2__9_AFIT16_demsharpmix1_iDemClamp*/
+ 0x0F12000C, /*#AfitBaseVals_2__10_
+ AFIT16_demsharpmix1_iLowThreshold*/
+ 0x0F120010, /*#AfitBaseVals_2__11_
+ AFIT16_demsharpmix1_iHighThreshold*/
+ 0x0F12012C, /*#AfitBaseVals_2__12_AFIT16_demsharpmix1_iLowBright*/
+ 0x0F1203E8, /*#AfitBaseVals_2__13_AFIT16_demsharpmix1_iHighBright*/
+ 0x0F120046, /*#AfitBaseVals_2__14_AFIT16_demsharpmix1_iLowSat*/
+ 0x0F12005A, /*#AfitBaseVals_2__15_AFIT16_demsharpmix1_iHighSat*/
+ 0x0F120070, /*#AfitBaseVals_2__16_AFIT16_demsharpmix1_iTune*/
+ 0x0F120008, /*#AfitBaseVals_2__17_AFIT16_demsharpmix1_iHystThLow*/
+ 0x0F120000, /*#AfitBaseVals_2__18_AFIT16_demsharpmix1_iHystThHigh*/
+ 0x0F120320, /*#AfitBaseVals_2__19_AFIT16_demsharpmix1_iHystCenter*/
+ 0x0F120032, /*#AfitBaseVals_2__20_
+ AFIT16_YUV422_DENOISE_iUVLowThresh*/
+ 0x0F120032, /*#AfitBaseVals_2__21_
+ AFIT16_YUV422_DENOISE_iUVHighThresh*/
+ 0x0F120000, /*#AfitBaseVals_2__22_
+ AFIT16_YUV422_DENOISE_iYLowThresh*/
+ 0x0F120000, /*#AfitBaseVals_2__23_
+ AFIT16_YUV422_DENOISE_iYHighThresh*/
+ 0x0F1200B4, /*#AfitBaseVals_2__24_AFIT16_Sharpening_iLowSharpClamp*/
+ 0x0F120014, /*#AfitBaseVals_2__25_
+ AFIT16_Sharpening_iHighSharpClamp*/
+ 0x0F1200B4, /*#AfitBaseVals_2__26_
+ AFIT16_Sharpening_iLowSharpClamp_Bin*/
+ 0x0F120014, /*#AfitBaseVals_2__27_
+ AFIT16_Sharpening_iHighSharpClamp_Bin*/
+ 0x0F12003C, /*#AfitBaseVals_2__28_
+ AFIT16_Sharpening_iLowSharpClamp_sBin*/
+ 0x0F12001E, /*#AfitBaseVals_2__29_
+ AFIT16_Sharpening_iHighSharpClamp_sBin*/
+ 0x0F120A24, /*#AfitBaseVals_2__30_
+ AFIT8_sddd8a_edge_low [7:0],
+ AFIT8_sddd8a_repl_thresh [15:8]*/
+ 0x0F121701, /*#AfitBaseVals_2__31_
+ AFIT8_sddd8a_repl_force [7:0],
+ AFIT8_sddd8a_sat_level [15:8]*/
+ 0x0F120229, /*#AfitBaseVals_2__32_
+ AFIT8_sddd8a_sat_thr[7:0],
+ AFIT8_sddd8a_sat_mpl [15:8]*/
+ 0x0F121403, /*#AfitBaseVals_2__33_
+ AFIT8_sddd8a_sat_noise[7:0],
+ AFIT8_sddd8a_iMaxSlopeAllowed [15:8]*/
+ 0x0F120000, /*#AfitBaseVals_2__34_
+ AFIT8_sddd8a_iHotThreshHigh[7:0],
+ AFIT8_sddd8a_iHotThreshLow [15:8]*/
+ 0x0F120000, /*#AfitBaseVals_2__35_AFIT8_sddd8a_iColdThreshHigh[7:0],
+ AFIT8_sddd8a_iColdThreshLow [15:8]*/
+ 0x0F120000, /*#AfitBaseVals_2__36_AFIT8_sddd8a_AddNoisePower1[7:0],
+ AFIT8_sddd8a_AddNoisePower2 [15:8]*/
+ 0x0F1200FF, /*#AfitBaseVals_2__37_AFIT8_sddd8a_iSatSat[7:0],
+ AFIT8_sddd8a_iRadialTune [15:8]*/
+ 0x0F12033B, /*#AfitBaseVals_2__38_AFIT8_sddd8a_iRadialLimit [7:0],
+ AFIT8_sddd8a_iRadialPower [15:8]*/
+ 0x0F121414, /*#AfitBaseVals_2__39_
+ AFIT8_sddd8a_iLowMaxSlopeAllowed [7:0],
+ AFIT8_sddd8a_iHighMaxSlopeAllowed [15:8]*/
+ 0x0F120301, /*#AfitBaseVals_2__40_
+ AFIT8_sddd8a_iLowSlopeThresh[7:0],
+ AFIT8_sddd8a_iHighSlopeThresh [15:8]*/
+ 0x0F12FF07, /*#AfitBaseVals_2__41_
+ AFIT8_sddd8a_iSquaresRounding [7:0],
+ AFIT8_Demosaicing_iCentGrad [15:8]*/
+ 0x0F12081E, /*#AfitBaseVals_2__42_
+ AFIT8_Demosaicing_iMonochrom [7:0],
+ AFIT8_Demosaicing_iDecisionThresh [15:8]*/
+ 0x0F120A1E, /*#AfitBaseVals_2__43_
+ AFIT8_Demosaicing_iDesatThresh [7:0],
+ AFIT8_Demosaicing_iEnhThresh [15:8]*/
+ 0x0F120F0F, /*#AfitBaseVals_2__44_
+ AFIT8_Demosaicing_iGRDenoiseVal [7:0],
+ AFIT8_Demosaicing_iGBDenoiseVal [15:8]*/
+ 0x0F120A00, /*#AfitBaseVals_2__45_
+ AFIT8_Demosaicing_iNearGrayDesat[7:0],
+ AFIT8_Demosaicing_iDFD_ReduceCoeff [15:8]*/
+ 0x0F120012, /*#AfitBaseVals_2__46_
+ AFIT8_Sharpening_iMSharpen [7:0],
+ AFIT8_Sharpening_iMShThresh [15:8]*/
+ 0x0F120005, /*#AfitBaseVals_2__47_
+ AFIT8_Sharpening_iWSharpen [7:0],
+ AFIT8_Sharpening_iWShThresh [15:8]*/
+ 0x0F120001, /*#AfitBaseVals_2__48_
+ AFIT8_Sharpening_nSharpWidth [7:0],
+ AFIT8_Sharpening_iReduceNegative [15:8]*/
+ 0x0F1200FF, /*#AfitBaseVals_2__49_
+ AFIT8_Sharpening_iShDespeckle [7:0],
+ AFIT8_demsharpmix1_iRGBMultiplier [15:8]*/
+ 0x0F121102, /*#AfitBaseVals_2__50_
+ AFIT8_demsharpmix1_iFilterPower [7:0],
+ AFIT8_demsharpmix1_iBCoeff [15:8]*/
+ 0x0F12001B, /*#AfitBaseVals_2__51_
+ AFIT8_demsharpmix1_iGCoeff [7:0],
+ AFIT8_demsharpmix1_iWideMult [15:8]*/
+ 0x0F120900, /*#AfitBaseVals_2__52_
+ AFIT8_demsharpmix1_iNarrMult [7:0],
+ AFIT8_demsharpmix1_iHystFalloff [15:8]*/
+ 0x0F120600, /*#AfitBaseVals_2__53_
+ AFIT8_demsharpmix1_iHystMinMult [7:0],
+ AFIT8_demsharpmix1_iHystWidth [15:8]*/
+ 0x0F120504, /*#AfitBaseVals_2__54_
+ AFIT8_demsharpmix1_iHystFallLow [7:0],
+ AFIT8_demsharpmix1_iHystFallHigh [15:8]*/
+ 0x0F120306, /*#AfitBaseVals_2__55_
+ AFIT8_demsharpmix1_iHystTune [7:0],
+ * AFIT8_YUV422_DENOISE_iUVSupport [15:8]*/
+ 0x0F128002, /*#AfitBaseVals_2__56_
+ AFIT8_YUV422_DENOISE_iYSupport [7:0],
+ AFIT8_byr_cgras_iShadingPower [15:8]*/
+ 0x0F120080, /*#AfitBaseVals_2__57_
+ AFIT8_RGBGamma2_iLinearity [7:0],
+ AFIT8_RGBGamma2_iDarkReduce [15:8]*/
+ 0x0F120080, /*#AfitBaseVals_2__58_
+ AFIT8_ccm_oscar_iSaturation[7:0],
+ AFIT8_RGB2YUV_iYOffset [15:8]*/
+ 0x0F120080, /*#AfitBaseVals_2__59_
+ AFIT8_RGB2YUV_iRGBGain [7:0],
+ AFIT8_RGB2YUV_iSaturation [15:8]*/
+ 0x0F125050, /*#AfitBaseVals_2__60_
+ AFIT8_sddd8a_iClustThresh_H [7:0],
+ AFIT8_sddd8a_iClustThresh_C [15:8]*/
+ 0x0F120101, /*#AfitBaseVals_2__61_
+ AFIT8_sddd8a_iClustMulT_H [7:0],
+ AFIT8_sddd8a_iClustMulT_C [15:8]*/
+ 0x0F121B01, /*#AfitBaseVals_2__62_
+ AFIT8_sddd8a_nClustLevel_H [7:0],
+ AFIT8_sddd8a_DispTH_Low [15:8]*/
+ 0x0F122319, /*#AfitBaseVals_2__63_
+ AFIT8_sddd8a_DispTH_High [7:0],
+ AFIT8_sddd8a_iDenThreshLow [15:8]*/
+ 0x0F12960F, /*#AfitBaseVals_2__64_
+ AFIT8_sddd8a_iDenThreshHigh[7:0],
+ AFIT8_Demosaicing_iEdgeDesat [15:8]*/
+ 0x0F120000, /*#AfitBaseVals_2__65_
+ AFIT8_Demosaicing_iEdgeDesatThrLow [7:0],
+ AFIT8_Demosaicing_iEdgeDesatThrHigh [15:8]*/
+ 0x0F122A03, /*#AfitBaseVals_2__66_
+ AFIT8_Demosaicing_iEdgeDesatLimit[7:0],
+ AFIT8_Demosaicing_iDemSharpenLow [15:8]*/
+ 0x0F120A02, /*#AfitBaseVals_2__67_
+ AFIT8_Demosaicing_iDemSharpenHigh[7:0],
+ AFIT8_Demosaicing_iDemSharpThresh [15:8]*/
+ 0x0F120864, /*#AfitBaseVals_2__68_
+ AFIT8_Demosaicing_iDemShLowLimit [7:0],
+ AFIT8_Demosaicing_iDespeckleForDemsharp [15:8]*/
+ 0x0F121432, /*#AfitBaseVals_2__69_
+ AFIT8_Demosaicing_iDemBlurLow[7:0],
+ AFIT8_Demosaicing_iDemBlurHigh [15:8]*/
+ 0x0F129601, /*#AfitBaseVals_2__70_
+ AFIT8_Demosaicing_iDemBlurRange[7:0],
+ AFIT8_Sharpening_iLowSharpPower [15:8]*/
+ 0x0F122814, /*#AfitBaseVals_2__71_
+ AFIT8_Sharpening_iHighSharpPower[7:0],
+ AFIT8_Sharpening_iLowShDenoise [15:8]*/
+ 0x0F12400A, /*#AfitBaseVals_2__72_
+ AFIT8_Sharpening_iHighShDenoise [7:0],
+ AFIT8_Sharpening_iReduceEdgeMinMult [15:8]*/
+ 0x0F120204, /*#AfitBaseVals_2__73_
+ AFIT8_Sharpening_iReduceEdgeSlope [7:0],
+ AFIT8_demsharpmix1_iWideFiltReduce [15:8]*/
+ 0x0F125003, /*#AfitBaseVals_2__74_
+ AFIT8_demsharpmix1_iNarrFiltReduce [7:0],
+ AFIT8_sddd8a_iClustThresh_H_Bin [15:8]*/
+ 0x0F120150, /*#AfitBaseVals_2__75_
+ AFIT8_sddd8a_iClustThresh_C_Bin [7:0],
+ AFIT8_sddd8a_iClustMulT_H_Bin [15:8]*/
+ 0x0F120101, /*#AfitBaseVals_2__76_
+ AFIT8_sddd8a_iClustMulT_C_Bin [7:0],
+ AFIT8_sddd8a_nClustLevel_H_Bin [15:8]*/
+ 0x0F12191B, /*#AfitBaseVals_2__77_
+ AFIT8_sddd8a_DispTH_Low_Bin [7:0],
+ AFIT8_sddd8a_DispTH_High_Bin [15:8]*/
+ 0x0F120D0F, /*#AfitBaseVals_2__78_
+ AFIT8_sddd8a_iDenThreshLow_Bin [7:0],
+ AFIT8_sddd8a_iDenThreshHigh_Bin [15:8]*/
+ 0x0F120028, /*#AfitBaseVals_2__79_
+ AFIT8_Demosaicing_iEdgeDesat_Bin[7:0],
+ AFIT8_Demosaicing_iEdgeDesatThrLow_Bin [15:8]*/
+ 0x0F120300, /*#AfitBaseVals_2__80_
+ AFIT8_Demosaicing_iEdgeDesatThrHigh_Bin [7:0],
+ AFIT8_Demosaicing_iEdgeDesatLimit_Bin [15:8]*/
+ 0x0F12021E, /*#AfitBaseVals_2__81_
+ AFIT8_Demosaicing_iDemSharpenLow_Bin [7:0],
+ AFIT8_Demosaicing_iDemSharpenHigh_Bin [15:8]*/
+ 0x0F121E0A, /*#AfitBaseVals_2__82_
+ AFIT8_Demosaicing_iDemSharpThresh_Bin [7:0],
+ AFIT8_Demosaicing_iDemShLowLimit_Bin [15:8]*/
+ 0x0F123208, /*#AfitBaseVals_2__83_
+ AFIT8_Demosaicing_iDespeckleForDemsharp_Bin [7:0],
+ AFIT8_Demosaicing_iDemBlurLow_Bin [15:8]*/
+ 0x0F120114, /*#AfitBaseVals_2__84_
+ AFIT8_Demosaicing_iDemBlurHigh_Bin [7:0],
+ AFIT8_Demosaicing_iDemBlurRange_Bin [15:8]*/
+ 0x0F121450, /*#AfitBaseVals_2__85_
+ AFIT8_Sharpening_iLowSharpPower_Bin [7:0],
+ AFIT8_Sharpening_iHighSharpPower_Bin [15:8]*/
+ 0x0F120A28, /*#AfitBaseVals_2__86_
+ AFIT8_Sharpening_iLowShDenoise_Bin [7:0],
+ AFIT8_Sharpening_iHighShDenoise_Bin [15:8]*/
+ 0x0F120440, /*#AfitBaseVals_2__87_
+ AFIT8_Sharpening_iReduceEdgeMinMult_Bin [7:0],
+ AFIT8_Sharpening_iReduceEdgeSlope_Bin [15:8]*/
+ 0x0F120302, /*#AfitBaseVals_2__88_
+ AFIT8_demsharpmix1_iWideFiltReduce_Bin [7:0],
+ AFIT8_demsharpmix1_iNarrFiltReduce_Bin [15:8]*/
+ 0x0F122828, /*#AfitBaseVals_2__89_
+ AFIT8_sddd8a_iClustThresh_H_sBin[7:0],
+ AFIT8_sddd8a_iClustThresh_C_sBin [15:8]*/
+ 0x0F120101, /*#AfitBaseVals_2__90_
+ AFIT8_sddd8a_iClustMulT_H_sBin [7:0],
+ AFIT8_sddd8a_iClustMulT_C_sBin [15:8]*/
+ 0x0F122401, /*#AfitBaseVals_2__91_
+ AFIT8_sddd8a_nClustLevel_H_sBin [7:0],
+ AFIT8_sddd8a_DispTH_Low_sBin [15:8]*/
+ 0x0F123622, /*#AfitBaseVals_2__92_
+ AFIT8_sddd8a_DispTH_High_sBin [7:0],
+ AFIT8_sddd8a_iDenThreshLow_sBin [15:8]*/
+ 0x0F122832, /*#AfitBaseVals_2__93_
+ AFIT8_sddd8a_iDenThreshHigh_sBin[7:0],
+ AFIT8_Demosaicing_iEdgeDesat_sBin [15:8]*/
+ 0x0F120A00, /*#AfitBaseVals_2__94_
+ AFIT8_Demosaicing_iEdgeDesatThrLow_sBin [7:0],
+ AFIT8_Demosaicing_iEdgeDesatThrHigh_sBin [15:8]*/
+ 0x0F121003, /*#AfitBaseVals_2__95_
+ AFIT8_Demosaicing_iEdgeDesatLimit_sBin [7:0],
+ AFIT8_Demosaicing_iDemSharpenLow_sBin [15:8]*/
+ 0x0F121E04, /*#AfitBaseVals_2__96_
+ AFIT8_Demosaicing_iDemSharpenHigh_sBin [7:0],
+ AFIT8_Demosaicing_iDemSharpThresh_sBin [15:8]*/
+ 0x0F120714, /*#AfitBaseVals_2__97_
+ AFIT8_Demosaicing_iDemShLowLimit_sBin [7:0],
+ AFIT8_Demosaicing_iDespeckleForDemsharp_sBin [15:8]*/
+ 0x0F1232FF, /*#AfitBaseVals_2__98_
+ AFIT8_Demosaicing_iDemBlurLow_sBin [7:0],
+ AFIT8_Demosaicing_iDemBlurHigh_sBin [15:8]*/
+ 0x0F125004, /*#AfitBaseVals_2__99_
+ AFIT8_Demosaicing_iDemBlurRange_sBin [7:0],
+ AFIT8_Sharpening_iLowSharpPower_sBin [15:8]*/
+ 0x0F120F40, /*#AfitBaseVals_2__100_
+ AFIT8_Sharpening_iHighSharpPower_sBin [7:0],
+ AFIT8_Sharpening_iLowShDenoise_sBin [15:8]*/
+ 0x0F12400F, /*#AfitBaseVals_2__101_
+ AFIT8_Sharpening_iHighShDenoise_sBin [7:0],
+ AFIT8_Sharpening_iReduceEdgeMinMult_sBin [15:8]*/
+ 0x0F120204, /*#AfitBaseVals_2__102_
+ AFIT8_Sharpening_iReduceEdgeSlope_sBin [7:0],
+ AFIT8_demsharpmix1_iWideFiltReduce_sBin [15:8]*/
+ 0x0F120003, /*#AfitBaseVals_2__103_
+ AFIT8_demsharpmix1_iNarrFiltReduce_sBin [7:0]*/
+ 0x0F120000, /*#AfitBaseVals_3__0_AFIT16_BRIGHTNESS*/
+ 0x0F120000, /*#AfitBaseVals_3__1_AFIT16_CONTRAST*/
+ 0x0F120000, /*#AfitBaseVals_3__2_AFIT16_SATURATION*/
+ 0x0F120000, /*#AfitBaseVals_3__3_AFIT16_SHARP_BLUR*/
+ 0x0F120000, /*#AfitBaseVals_3__4_AFIT16_GLAMOUR*/
+ 0x0F1200C1, /*#AfitBaseVals_3__5_AFIT16_sddd8a_edge_high*/
+ 0x0F1203FF, /*#AfitBaseVals_3__6_AFIT16_Demosaicing_iSatVal*/
+ 0x0F12009C, /*#AfitBaseVals_3__7_
+ AFIT16_Sharpening_iReduceEdgeThresh*/
+ 0x0F12017C, /*#AfitBaseVals_3__8_AFIT16_demsharpmix1_iRGBOffset*/
+ 0x0F1203FF, /*#AfitBaseVals_3__9_AFIT16_demsharpmix1_iDemClamp*/
+ 0x0F12000C, /*#AfitBaseVals_3__10_
+ AFIT16_demsharpmix1_iLowThreshold*/
+ 0x0F120010, /*#AfitBaseVals_3__11_
+ AFIT16_demsharpmix1_iHighThreshold*/
+ 0x0F1200C8, /*#AfitBaseVals_3__12_AFIT16_demsharpmix1_iLowBright*/
+ 0x0F1203E8, /*#AfitBaseVals_3__13_AFIT16_demsharpmix1_iHighBright*/
+ 0x0F120046, /*#AfitBaseVals_3__14_AFIT16_demsharpmix1_iLowSat*/
+ 0x0F120050, /*#AfitBaseVals_3__15_AFIT16_demsharpmix1_iHighSat*/
+ 0x0F120070, /*#AfitBaseVals_3__16_AFIT16_demsharpmix1_iTune*/
+ 0x0F120008, /*#AfitBaseVals_3__17_AFIT16_demsharpmix1_iHystThLow*/
+ 0x0F120000, /*#AfitBaseVals_3__18_AFIT16_demsharpmix1_iHystThHigh*/
+ 0x0F120320, /*#AfitBaseVals_3__19_AFIT16_demsharpmix1_iHystCenter*/
+ 0x0F120032, /*#AfitBaseVals_3__20_
+ AFIT16_YUV422_DENOISE_iUVLowThresh*/
+ 0x0F120032, /*#AfitBaseVals_3__21_
+ AFIT16_YUV422_DENOISE_iUVHighThresh*/
+ 0x0F120000, /*#AfitBaseVals_3__22_
+ AFIT16_YUV422_DENOISE_iYLowThresh*/
+ 0x0F120000, /*#AfitBaseVals_3__23_
+ AFIT16_YUV422_DENOISE_iYHighThresh*/
+ 0x0F1200B4, /*#AfitBaseVals_3__24_
+ AFIT16_Sharpening_iLowSharpClamp*/
+ 0x0F120014, /*#AfitBaseVals_3__25_
+ AFIT16_Sharpening_iHighSharpClamp*/
+ 0x0F1200B4, /*#AfitBaseVals_3__26_
+ AFIT16_Sharpening_iLowSharpClamp_Bin*/
+ 0x0F120014, /*#AfitBaseVals_3__27_
+ AFIT16_Sharpening_iHighSharpClamp_Bin*/
+ 0x0F12002D, /*#AfitBaseVals_3__28_
+ AFIT16_Sharpening_iLowSharpClamp_sBin*/
+ 0x0F120019, /*#AfitBaseVals_3__29_
+ AFIT16_Sharpening_iHighSharpClamp_sBin*/
+ 0x0F120A24, /*#AfitBaseVals_3__30_
+ AFIT8_sddd8a_edge_low [7:0],
+ AFIT8_sddd8a_repl_thresh [15:8]*/
+ 0x0F121701, /*#AfitBaseVals_3__31_
+ AFIT8_sddd8a_repl_force [7:0],
+ AFIT8_sddd8a_sat_level [15:8]*/
+ 0x0F120229, /*#AfitBaseVals_3__32_
+ AFIT8_sddd8a_sat_thr[7:0],
+ AFIT8_sddd8a_sat_mpl [15:8]*/
+ 0x0F121403, /*#AfitBaseVals_3__33_
+ AFIT8_sddd8a_sat_noise[7:0],
+ AFIT8_sddd8a_iMaxSlopeAllowed [15:8]*/
+ 0x0F120000, /*#AfitBaseVals_3__34_
+ AFIT8_sddd8a_iHotThreshHigh[7:0],
+ AFIT8_sddd8a_iHotThreshLow [15:8]*/
+ 0x0F120000, /*#AfitBaseVals_3__35_
+ AFIT8_sddd8a_iColdThreshHigh[7:0],
+ AFIT8_sddd8a_iColdThreshLow [15:8]*/
+ 0x0F120000, /*#AfitBaseVals_3__36_
+ AFIT8_sddd8a_AddNoisePower1[7:0],
+ AFIT8_sddd8a_AddNoisePower2 [15:8]*/
+ 0x0F1200FF, /*#AfitBaseVals_3__37_
+ AFIT8_sddd8a_iSatSat[7:0],
+ AFIT8_sddd8a_iRadialTune [15:8]*/
+ 0x0F12033B, /*#AfitBaseVals_3__38_
+ AFIT8_sddd8a_iRadialLimit [7:0],
+ AFIT8_sddd8a_iRadialPower [15:8]*/
+ 0x0F121414, /*#AfitBaseVals_3__39_
+ AFIT8_sddd8a_iLowMaxSlopeAllowed [7:0],
+ AFIT8_sddd8a_iHighMaxSlopeAllowed [15:8]*/
+ 0x0F120301, /*#AfitBaseVals_3__40_
+ AFIT8_sddd8a_iLowSlopeThresh[7:0],
+ AFIT8_sddd8a_iHighSlopeThresh [15:8]*/
+ 0x0F12FF07, /*#AfitBaseVals_3__41_
+ AFIT8_sddd8a_iSquaresRounding [7:0],
+ AFIT8_Demosaicing_iCentGrad [15:8]*/
+ 0x0F12081E, /*#AfitBaseVals_3__42_
+ AFIT8_Demosaicing_iMonochrom [7:0],
+ AFIT8_Demosaicing_iDecisionThresh [15:8]*/
+ 0x0F120A1E, /*#AfitBaseVals_3__43_
+ AFIT8_Demosaicing_iDesatThresh [7:0],
+ AFIT8_Demosaicing_iEnhThresh [15:8]*/
+ 0x0F120F0F, /*#AfitBaseVals_3__44_
+ AFIT8_Demosaicing_iGRDenoiseVal [7:0],
+ AFIT8_Demosaicing_iGBDenoiseVal [15:8]*/
+ 0x0F120A00, /*#AfitBaseVals_3__45_
+ AFIT8_Demosaicing_iNearGrayDesat[7:0],
+ AFIT8_Demosaicing_iDFD_ReduceCoeff [15:8]*/
+ 0x0F120012, /*#AfitBaseVals_3__46_
+ AFIT8_Sharpening_iMSharpen [7:0],
+ AFIT8_Sharpening_iMShThresh [15:8]*/
+ 0x0F120005, /*#AfitBaseVals_3__47_
+ AFIT8_Sharpening_iWSharpen [7:0],
+ AFIT8_Sharpening_iWShThresh [15:8]*/
+ 0x0F120001, /*#AfitBaseVals_3__48_
+ AFIT8_Sharpening_nSharpWidth [7:0],
+ AFIT8_Sharpening_iReduceNegative [15:8]*/
+ 0x0F1200FF, /*#AfitBaseVals_3__49_
+ AFIT8_Sharpening_iShDespeckle [7:0],
+ AFIT8_demsharpmix1_iRGBMultiplier [15:8]*/
+ 0x0F121002, /*#AfitBaseVals_3__50_
+ AFIT8_demsharpmix1_iFilterPower [7:0],
+ AFIT8_demsharpmix1_iBCoeff [15:8]*/
+ 0x0F12001E, /*#AfitBaseVals_3__51_
+ AFIT8_demsharpmix1_iGCoeff [7:0],
+ AFIT8_demsharpmix1_iWideMult [15:8]*/
+ 0x0F120900, /*#AfitBaseVals_3__52_
+ AFIT8_demsharpmix1_iNarrMult [7:0],
+ AFIT8_demsharpmix1_iHystFalloff [15:8]*/
+ 0x0F120600, /*#AfitBaseVals_3__53_
+ AFIT8_demsharpmix1_iHystMinMult [7:0],
+ AFIT8_demsharpmix1_iHystWidth [15:8]*/
+ 0x0F120504, /*#AfitBaseVals_3__
+ 54_AFIT8_demsharpmix1_iHystFallLow [7:0],
+ AFIT8_demsharpmix1_iHystFallHigh [15:8]*/
+ 0x0F120307, /*#AfitBaseVals_3__55_
+ AFIT8_demsharpmix1_iHystTune [7:0],
+ * AFIT8_YUV422_DENOISE_iUVSupport [15:8]*/
+ 0x0F128002, /*#AfitBaseVals_3__56_
+ AFIT8_YUV422_DENOISE_iYSupport [7:0],
+ AFIT8_byr_cgras_iShadingPower [15:8]*/
+ 0x0F120080, /*#AfitBaseVals_3__57_
+ AFIT8_RGBGamma2_iLinearity [7:0],
+ AFIT8_RGBGamma2_iDarkReduce [15:8]*/
+ 0x0F120080, /*#AfitBaseVals_3__58_
+ AFIT8_ccm_oscar_iSaturation[7:0],
+ AFIT8_RGB2YUV_iYOffset [15:8]*/
+ 0x0F120080, /*#AfitBaseVals_3__59_
+ AFIT8_RGB2YUV_iRGBGain [7:0],
+ AFIT8_RGB2YUV_iSaturation [15:8]*/
+ 0x0F125050, /*#AfitBaseVals_3__60_
+ AFIT8_sddd8a_iClustThresh_H [7:0],
+ AFIT8_sddd8a_iClustThresh_C [15:8]*/
+ 0x0F120101, /*#AfitBaseVals_3__61_
+ AFIT8_sddd8a_iClustMulT_H [7:0],
+ AFIT8_sddd8a_iClustMulT_C [15:8]*/
+ 0x0F121B01, /*#AfitBaseVals_3__62_
+ AFIT8_sddd8a_nClustLevel_H [7:0],
+ AFIT8_sddd8a_DispTH_Low [15:8]*/
+ 0x0F122319, /*#AfitBaseVals_3__63_
+ AFIT8_sddd8a_DispTH_High [7:0],
+ AFIT8_sddd8a_iDenThreshLow [15:8]*/
+ 0x0F12960F, /*#AfitBaseVals_3__64_
+ AFIT8_sddd8a_iDenThreshHigh[7:0],
+ AFIT8_Demosaicing_iEdgeDesat [15:8]*/
+ 0x0F120000, /*#AfitBaseVals_3__65_
+ AFIT8_Demosaicing_iEdgeDesatThrLow [7:0],
+ AFIT8_Demosaicing_iEdgeDesatThrHigh [15:8]*/
+ 0x0F122003, /*#AfitBaseVals_3__66_
+ AFIT8_Demosaicing_iEdgeDesatLimit[7:0],
+ AFIT8_Demosaicing_iDemSharpenLow [15:8]*/
+ 0x0F120A02, /*#AfitBaseVals_3__67_
+ AFIT8_Demosaicing_iDemSharpenHigh[7:0],
+ AFIT8_Demosaicing_iDemSharpThresh [15:8]*/
+ 0x0F120864, /*#AfitBaseVals_3__68_
+ AFIT8_Demosaicing_iDemShLowLimit [7:0],
+ AFIT8_Demosaicing_iDespeckleForDemsharp [15:8]*/
+ 0x0F121432, /*#AfitBaseVals_3__69_
+ AFIT8_Demosaicing_iDemBlurLow[7:0],
+ AFIT8_Demosaicing_iDemBlurHigh [15:8]*/
+ 0x0F12A001, /*#AfitBaseVals_3__70_
+ AFIT8_Demosaicing_iDemBlurRange[7:0],
+ AFIT8_Sharpening_iLowSharpPower [15:8]*/
+ 0x0F122814, /*#AfitBaseVals_3__71_
+ AFIT8_Sharpening_iHighSharpPower[7:0],
+ AFIT8_Sharpening_iLowShDenoise [15:8]*/
+ 0x0F12400A, /*#AfitBaseVals_3__72_
+ AFIT8_Sharpening_iHighShDenoise [7:0],
+ AFIT8_Sharpening_iReduceEdgeMinMult [15:8]*/
+ 0x0F120204, /*#AfitBaseVals_3__73_
+ AFIT8_Sharpening_iReduceEdgeSlope [7:0],
+ AFIT8_demsharpmix1_iWideFiltReduce [15:8]*/
+ 0x0F125003, /*#AfitBaseVals_3__74_
+ AFIT8_demsharpmix1_iNarrFiltReduce [7:0],
+ AFIT8_sddd8a_iClustThresh_H_Bin [15:8]*/
+ 0x0F120150, /*#AfitBaseVals_3__75_
+ AFIT8_sddd8a_iClustThresh_C_Bin [7:0],
+ AFIT8_sddd8a_iClustMulT_H_Bin [15:8]*/
+ 0x0F120101, /*#AfitBaseVals_3__76_
+ AFIT8_sddd8a_iClustMulT_C_Bin [7:0],
+ AFIT8_sddd8a_nClustLevel_H_Bin [15:8]*/
+ 0x0F12191B, /*#AfitBaseVals_3__77_
+ AFIT8_sddd8a_DispTH_Low_Bin [7:0],
+ AFIT8_sddd8a_DispTH_High_Bin [15:8]*/
+ 0x0F120D0F, /*#AfitBaseVals_3__78_
+ AFIT8_sddd8a_iDenThreshLow_Bin [7:0],
+ AFIT8_sddd8a_iDenThreshHigh_Bin [15:8]*/
+ 0x0F120028, /*#AfitBaseVals_3__79_
+ AFIT8_Demosaicing_iEdgeDesat_Bin[7:0],
+ AFIT8_Demosaicing_iEdgeDesatThrLow_Bin [15:8]*/
+ 0x0F120300, /*#AfitBaseVals_3__80_
+ AFIT8_Demosaicing_iEdgeDesatThrHigh_Bin [7:0],
+ AFIT8_Demosaicing_iEdgeDesatLimit_Bin [15:8]*/
+ 0x0F12021E, /*#AfitBaseVals_3__81_
+ AFIT8_Demosaicing_iDemSharpenLow_Bin [7:0],
+ AFIT8_Demosaicing_iDemSharpenHigh_Bin [15:8]*/
+ 0x0F121E0A, /*#AfitBaseVals_3__82_
+ AFIT8_Demosaicing_iDemSharpThresh_Bin [7:0],
+ AFIT8_Demosaicing_iDemShLowLimit_Bin [15:8]*/
+ 0x0F123208, /*#AfitBaseVals_3__83_
+ AFIT8_Demosaicing_iDespeckleForDemsharp_Bin [7:0],
+ AFIT8_Demosaicing_iDemBlurLow_Bin [15:8]*/
+ 0x0F120114, /*#AfitBaseVals_3__84_
+ AFIT8_Demosaicing_iDemBlurHigh_Bin [7:0],
+ AFIT8_Demosaicing_iDemBlurRange_Bin [15:8]*/
+ 0x0F121450, /*#AfitBaseVals_3__85_
+ AFIT8_Sharpening_iLowSharpPower_Bin [7:0],
+ AFIT8_Sharpening_iHighSharpPower_Bin [15:8]*/
+ 0x0F120A28, /*#AfitBaseVals_3__86_
+ AFIT8_Sharpening_iLowShDenoise_Bin [7:0],
+ AFIT8_Sharpening_iHighShDenoise_Bin [15:8]*/
+ 0x0F120440, /*#AfitBaseVals_3__87_
+ AFIT8_Sharpening_iReduceEdgeMinMult_Bin [7:0],
+ AFIT8_Sharpening_iReduceEdgeSlope_Bin [15:8]*/
+ 0x0F120302, /*#AfitBaseVals_3__88_
+ AFIT8_demsharpmix1_iWideFiltReduce_Bin [7:0],
+ AFIT8_demsharpmix1_iNarrFiltReduce_Bin [15:8]*/
+ 0x0F123C3C, /*#AfitBaseVals_3__89_
+ AFIT8_sddd8a_iClustThresh_H_sBin[7:0],
+ AFIT8_sddd8a_iClustThresh_C_sBin [15:8]*/
+ 0x0F120101, /*#AfitBaseVals_3__90_
+ AFIT8_sddd8a_iClustMulT_H_sBin [7:0],
+ AFIT8_sddd8a_iClustMulT_C_sBin [15:8]*/
+ 0x0F121E01, /*#AfitBaseVals_3__91_
+ AFIT8_sddd8a_nClustLevel_H_sBin [7:0],
+ AFIT8_sddd8a_DispTH_Low_sBin [15:8]*/
+ 0x0F12221C, /*#AfitBaseVals_3__92_
+ AFIT8_sddd8a_DispTH_High_sBin [7:0],
+ AFIT8_sddd8a_iDenThreshLow_sBin [15:8]*/
+ 0x0F12281E, /*#AfitBaseVals_3__93_
+ AFIT8_sddd8a_iDenThreshHigh_sBin[7:0],
+ AFIT8_Demosaicing_iEdgeDesat_sBin [15:8]*/
+ 0x0F120A00, /*#AfitBaseVals_3__94_
+ AFIT8_Demosaicing_iEdgeDesatThrLow_sBin [7:0],
+ AFIT8_Demosaicing_iEdgeDesatThrHigh_sBin [15:8]*/
+ 0x0F121403, /*#AfitBaseVals_3__95_
+ AFIT8_Demosaicing_iEdgeDesatLimit_sBin [7:0],
+ AFIT8_Demosaicing_iDemSharpenLow_sBin [15:8]*/
+ 0x0F121402, /*#AfitBaseVals_3__96_
+ AFIT8_Demosaicing_iDemSharpenHigh_sBin [7:0],
+ AFIT8_Demosaicing_iDemSharpThresh_sBin [15:8]*/
+ 0x0F12060E, /*#AfitBaseVals_3__97_
+ AFIT8_Demosaicing_iDemShLowLimit_sBin [7:0],
+ AFIT8_Demosaicing_iDespeckleForDemsharp_sBin [15:8]*/
+ 0x0F1232FF, /*#AfitBaseVals_3__98_
+ AFIT8_Demosaicing_iDemBlurLow_sBin [7:0],
+ AFIT8_Demosaicing_iDemBlurHigh_sBin [15:8]*/
+ 0x0F125204, /*#AfitBaseVals_3__99_
+ AFIT8_Demosaicing_iDemBlurRange_sBin [7:0],
+ AFIT8_Sharpening_iLowSharpPower_sBin [15:8]*/
+ 0x0F120C40, /*#AfitBaseVals_3__100_
+ AFIT8_Sharpening_iHighSharpPower_sBin [7:0],
+ AFIT8_Sharpening_iLowShDenoise_sBin [15:8]*/
+ 0x0F124015, /*#AfitBaseVals_3__101_
+ AFIT8_Sharpening_iHighShDenoise_sBin [7:0],
+ AFIT8_Sharpening_iReduceEdgeMinMult_sBin [15:8]*/
+ 0x0F120204, /*#AfitBaseVals_3__102_
+ AFIT8_Sharpening_iReduceEdgeSlope_sBin [7:0],
+ AFIT8_demsharpmix1_iWideFiltReduce_sBin [15:8]*/
+ 0x0F120003, /*#AfitBaseVals_3__103_
+ AFIT8_demsharpmix1_iNarrFiltReduce_sBin [7:0]*/
+ 0x0F120000, /*#AfitBaseVals_4__0_AFIT16_BRIGHTNESS*/
+ 0x0F120000, /*#AfitBaseVals_4__1_AFIT16_CONTRAST*/
+ 0x0F120000, /*#AfitBaseVals_4__2_AFIT16_SATURATION*/
+ 0x0F120000, /*#AfitBaseVals_4__3_AFIT16_SHARP_BLUR*/
+ 0x0F120000, /*#AfitBaseVals_4__4_AFIT16_GLAMOUR*/
+ 0x0F1200C1, /*#AfitBaseVals_4__5_AFIT16_sddd8a_edge_high*/
+ 0x0F1203FF, /*#AfitBaseVals_4__6_AFIT16_Demosaicing_iSatVal*/
+ 0x0F12009C, /*#AfitBaseVals_4__7_
+ AFIT16_Sharpening_iReduceEdgeThresh*/
+ 0x0F12017C, /*#AfitBaseVals_4__8_AFIT16_demsharpmix1_iRGBOffset*/
+ 0x0F1203FF, /*#AfitBaseVals_4__9_AFIT16_demsharpmix1_iDemClamp*/
+ 0x0F12000C, /*#AfitBaseVals_4__10_
+ AFIT16_demsharpmix1_iLowThreshold*/
+ 0x0F120010, /*#AfitBaseVals_4__11_
+ AFIT16_demsharpmix1_iHighThreshold*/
+ 0x0F120032, /*#AfitBaseVals_4__12_AFIT16_demsharpmix1_iLowBright*/
+ 0x0F12028A, /*#AfitBaseVals_4__13_AFIT16_demsharpmix1_iHighBright*/
+ 0x0F120032, /*#AfitBaseVals_4__14_AFIT16_demsharpmix1_iLowSat*/
+ 0x0F1201F4, /*#AfitBaseVals_4__15_AFIT16_demsharpmix1_iHighSat*/
+ 0x0F120070, /*#AfitBaseVals_4__16_AFIT16_demsharpmix1_iTune*/
+ 0x0F120002, /*#AfitBaseVals_4__17_AFIT16_demsharpmix1_iHystThLow*/
+ 0x0F120000, /*#AfitBaseVals_4__18_AFIT16_demsharpmix1_iHystThHigh*/
+ 0x0F1201AA, /*#AfitBaseVals_4__19_AFIT16_demsharpmix1_iHystCenter*/
+ 0x0F12003C, /*#AfitBaseVals_4__20_
+ AFIT16_YUV422_DENOISE_iUVLowThresh*/
+ 0x0F120050, /*#AfitBaseVals_4__21_
+ AFIT16_YUV422_DENOISE_iUVHighThresh*/
+ 0x0F120000, /*#AfitBaseVals_4__22_
+ AFIT16_YUV422_DENOISE_iYLowThresh*/
+ 0x0F120000, /*#AfitBaseVals_4__23_
+ AFIT16_YUV422_DENOISE_iYHighThresh*/
+ 0x0F1200B4, /*#AfitBaseVals_4__24_
+ AFIT16_Sharpening_iLowSharpClamp*/
+ 0x0F120014, /*#AfitBaseVals_4__25_
+ AFIT16_Sharpening_iHighSharpClamp*/
+ 0x0F1200B4, /*#AfitBaseVals_4__26_
+ AFIT16_Sharpening_iLowSharpClamp_Bin*/
+ 0x0F120014, /*#AfitBaseVals_4__27_
+ AFIT16_Sharpening_iHighSharpClamp_Bin*/
+ 0x0F120046, /*#AfitBaseVals_4__28_
+ AFIT16_Sharpening_iLowSharpClamp_sBin*/
+ 0x0F120019, /*#AfitBaseVals_4__29_
+ AFIT16_Sharpening_iHighSharpClamp_sBin*/
+ 0x0F120A24, /*#AfitBaseVals_4__30_
+ AFIT8_sddd8a_edge_low [7:0],
+ AFIT8_sddd8a_repl_thresh [15:8]*/
+ 0x0F121701, /*#AfitBaseVals_4__31_
+ AFIT8_sddd8a_repl_force [7:0],
+ AFIT8_sddd8a_sat_level [15:8]*/
+ 0x0F120229, /*#AfitBaseVals_4__32_
+ AFIT8_sddd8a_sat_thr[7:0], AFIT8_sddd8a_sat_mpl [15:8]*/
+ 0x0F120503, /*#AfitBaseVals_4__33_
+ AFIT8_sddd8a_sat_noise[7:0],
+ AFIT8_sddd8a_iMaxSlopeAllowed [15:8]*/
+ 0x0F12080F, /*#AfitBaseVals_4__34_
+ AFIT8_sddd8a_iHotThreshHigh[7:0],
+ AFIT8_sddd8a_iHotThreshLow [15:8]*/
+ 0x0F120808, /*#AfitBaseVals_4__35_
+ AFIT8_sddd8a_iColdThreshHigh[7:0],
+ AFIT8_sddd8a_iColdThreshLow [15:8]*/
+ 0x0F120000, /*#AfitBaseVals_4__36_
+ AFIT8_sddd8a_AddNoisePower1[7:0],
+ AFIT8_sddd8a_AddNoisePower2 [15:8]*/
+ 0x0F1200FF, /*#AfitBaseVals_4__37_
+ AFIT8_sddd8a_iSatSat[7:0],
+ AFIT8_sddd8a_iRadialTune [15:8]*/
+ 0x0F12022D, /*#AfitBaseVals_4__38_
+ AFIT8_sddd8a_iRadialLimit [7:0],
+ AFIT8_sddd8a_iRadialPower [15:8]*/
+ 0x0F121414, /*#AfitBaseVals_4__39_
+ AFIT8_sddd8a_iLowMaxSlopeAllowed [7:0],
+ AFIT8_sddd8a_iHighMaxSlopeAllowed [15:8]*/
+ 0x0F120301, /*#AfitBaseVals_4__40_
+ AFIT8_sddd8a_iLowSlopeThresh[7:0],
+ AFIT8_sddd8a_iHighSlopeThresh [15:8]*/
+ 0x0F12FF07, /*#AfitBaseVals_4__41_
+ AFIT8_sddd8a_iSquaresRounding [7:0],
+ AFIT8_Demosaicing_iCentGrad [15:8]*/
+ 0x0F12061E, /*#AfitBaseVals_4__42_
+ AFIT8_Demosaicing_iMonochrom [7:0],
+ AFIT8_Demosaicing_iDecisionThresh [15:8]*/
+ 0x0F120A1E, /*#AfitBaseVals_4__43_
+ AFIT8_Demosaicing_iDesatThresh [7:0],
+ AFIT8_Demosaicing_iEnhThresh [15:8]*/
+ 0x0F120606, /*#AfitBaseVals_4__44_
+ AFIT8_Demosaicing_iGRDenoiseVal [7:0],
+ AFIT8_Demosaicing_iGBDenoiseVal [15:8]*/
+ 0x0F120A03, /*#AfitBaseVals_4__45_
+ AFIT8_Demosaicing_iNearGrayDesat[7:0],
+ AFIT8_Demosaicing_iDFD_ReduceCoeff [15:8]*/
+ 0x0F120028, /*#AfitBaseVals_4__46_
+ AFIT8_Sharpening_iMSharpen [7:0],
+ AFIT8_Sharpening_iMShThresh [15:8]*/
+ 0x0F120002, /*#AfitBaseVals_4__47_
+ AFIT8_Sharpening_iWSharpen [7:0],
+ AFIT8_Sharpening_iWShThresh [15:8]*/
+ 0x0F120001, /*#AfitBaseVals_4__48_
+ AFIT8_Sharpening_nSharpWidth [7:0],
+ AFIT8_Sharpening_iReduceNegative [15:8]*/
+ 0x0F1200FF, /*#AfitBaseVals_4__49_
+ AFIT8_Sharpening_iShDespeckle [7:0],
+ AFIT8_demsharpmix1_iRGBMultiplier [15:8]*/
+ 0x0F121002, /*#AfitBaseVals_4__50_
+ AFIT8_demsharpmix1_iFilterPower [7:0],
+ AFIT8_demsharpmix1_iBCoeff [15:8]*/
+ 0x0F12001E, /*#AfitBaseVals_4__51_
+ AFIT8_demsharpmix1_iGCoeff [7:0],
+ AFIT8_demsharpmix1_iWideMult [15:8]*/
+ 0x0F120900, /*#AfitBaseVals_4__52_
+ AFIT8_demsharpmix1_iNarrMult [7:0],
+ AFIT8_demsharpmix1_iHystFalloff [15:8]*/
+ 0x0F120600, /*#AfitBaseVals_4__53_
+ AFIT8_demsharpmix1_iHystMinMult [7:0],
+ AFIT8_demsharpmix1_iHystWidth [15:8]*/
+ 0x0F120504, /*#AfitBaseVals_4__54_
+ AFIT8_demsharpmix1_iHystFallLow [7:0],
+ AFIT8_demsharpmix1_iHystFallHigh [15:8]*/
+ 0x0F120307, /*#AfitBaseVals_4__55_
+ AFIT8_demsharpmix1_iHystTune [7:0],
+ * AFIT8_YUV422_DENOISE_iUVSupport [15:8]*/
+ 0x0F128001, /*#AfitBaseVals_4__56_
+ AFIT8_YUV422_DENOISE_iYSupport [7:0],
+ AFIT8_byr_cgras_iShadingPower [15:8]*/
+ 0x0F120080, /*#AfitBaseVals_4__57_
+ AFIT8_RGBGamma2_iLinearity [7:0],
+ AFIT8_RGBGamma2_iDarkReduce [15:8]*/
+ 0x0F120080, /*#AfitBaseVals_4__58_
+ AFIT8_ccm_oscar_iSaturation[7:0],
+ AFIT8_RGB2YUV_iYOffset [15:8]*/
+ 0x0F120080, /*#AfitBaseVals_4__59_
+ AFIT8_RGB2YUV_iRGBGain [7:0],
+ AFIT8_RGB2YUV_iSaturation [15:8]*/
+ 0x0F125050, /*#AfitBaseVals_4__60_
+ AFIT8_sddd8a_iClustThresh_H [7:0],
+ AFIT8_sddd8a_iClustThresh_C [15:8]*/
+ 0x0F120101, /*#AfitBaseVals_4__61_
+ AFIT8_sddd8a_iClustMulT_H [7:0],
+ AFIT8_sddd8a_iClustMulT_C [15:8]*/
+ 0x0F121B01, /*#AfitBaseVals_4__62_
+ AFIT8_sddd8a_nClustLevel_H [7:0],
+ AFIT8_sddd8a_DispTH_Low [15:8]*/
+ 0x0F121219, /*#AfitBaseVals_4__63_
+ AFIT8_sddd8a_DispTH_High [7:0],
+ AFIT8_sddd8a_iDenThreshLow [15:8]*/
+ 0x0F12320D, /*#AfitBaseVals_4__64_
+ AFIT8_sddd8a_iDenThreshHigh[7:0],
+ AFIT8_Demosaicing_iEdgeDesat [15:8]*/
+ 0x0F120A0A, /*#AfitBaseVals_4__65_
+ AFIT8_Demosaicing_iEdgeDesatThrLow [7:0],
+ AFIT8_Demosaicing_iEdgeDesatThrHigh [15:8]*/
+ 0x0F122304, /*#AfitBaseVals_4__66_
+ AFIT8_Demosaicing_iEdgeDesatLimit[7:0],
+ AFIT8_Demosaicing_iDemSharpenLow [15:8]*/
+ 0x0F120A08, /*#AfitBaseVals_4__67_
+ AFIT8_Demosaicing_iDemSharpenHigh[7:0],
+ AFIT8_Demosaicing_iDemSharpThresh [15:8]*/
+ 0x0F120832, /*#AfitBaseVals_4__68_
+ AFIT8_Demosaicing_iDemShLowLimit [7:0],
+ AFIT8_Demosaicing_iDespeckleForDemsharp [15:8]*/
+ 0x0F121432, /*#AfitBaseVals_4__69_
+ AFIT8_Demosaicing_iDemBlurLow[7:0],
+ AFIT8_Demosaicing_iDemBlurHigh [15:8]*/
+ 0x0F12A001, /*#AfitBaseVals_4__70_
+ AFIT8_Demosaicing_iDemBlurRange[7:0],
+ AFIT8_Sharpening_iLowSharpPower [15:8]*/
+ 0x0F122A0A, /*#AfitBaseVals_4__71_
+ AFIT8_Sharpening_iHighSharpPower[7:0],
+ AFIT8_Sharpening_iLowShDenoise [15:8]*/
+ 0x0F124006, /*#AfitBaseVals_4__72_
+ AFIT8_Sharpening_iHighShDenoise [7:0],
+ AFIT8_Sharpening_iReduceEdgeMinMult [15:8]*/
+ 0x0F120604, /*#AfitBaseVals_4__73_
+ AFIT8_Sharpening_iReduceEdgeSlope [7:0],
+ AFIT8_demsharpmix1_iWideFiltReduce [15:8]*/
+ 0x0F125006, /*#AfitBaseVals_4__74_
+ AFIT8_demsharpmix1_iNarrFiltReduce [7:0],
+ AFIT8_sddd8a_iClustThresh_H_Bin [15:8]*/
+ 0x0F120150, /*#AfitBaseVals_4__75_
+ AFIT8_sddd8a_iClustThresh_C_Bin [7:0],
+ AFIT8_sddd8a_iClustMulT_H_Bin [15:8]*/
+ 0x0F120101, /*#AfitBaseVals_4__76_
+ AFIT8_sddd8a_iClustMulT_C_Bin [7:0],
+ AFIT8_sddd8a_nClustLevel_H_Bin [15:8]*/
+ 0x0F12191B, /*#AfitBaseVals_4__77_
+ AFIT8_sddd8a_DispTH_Low_Bin [7:0],
+ AFIT8_sddd8a_DispTH_High_Bin [15:8]*/
+ 0x0F120D0F, /*#AfitBaseVals_4__78_
+ AFIT8_sddd8a_iDenThreshLow_Bin [7:0],
+ AFIT8_sddd8a_iDenThreshHigh_Bin [15:8]*/
+ 0x0F120A28, /*#AfitBaseVals_4__79_
+ AFIT8_Demosaicing_iEdgeDesat_Bin[7:0],
+ AFIT8_Demosaicing_iEdgeDesatThrLow_Bin [15:8]*/
+ 0x0F12040A, /*#AfitBaseVals_4__80_
+ AFIT8_Demosaicing_iEdgeDesatThrHigh_Bin [7:0],
+ AFIT8_Demosaicing_iEdgeDesatLimit_Bin [15:8]*/
+ 0x0F120820, /*#AfitBaseVals_4__81_
+ AFIT8_Demosaicing_iDemSharpenLow_Bin [7:0],
+ AFIT8_Demosaicing_iDemSharpenHigh_Bin [15:8]*/
+ 0x0F12280A, /*#AfitBaseVals_4__82_
+ AFIT8_Demosaicing_iDemSharpThresh_Bin [7:0],
+ AFIT8_Demosaicing_iDemShLowLimit_Bin [15:8]*/
+ 0x0F123208, /*#AfitBaseVals_4__83_
+ AFIT8_Demosaicing_iDespeckleForDemsharp_Bin [7:0],
+ AFIT8_Demosaicing_iDemBlurLow_Bin [15:8]*/
+ 0x0F120114, /*#AfitBaseVals_4__84_
+ AFIT8_Demosaicing_iDemBlurHigh_Bin [7:0],
+ AFIT8_Demosaicing_iDemBlurRange_Bin [15:8]*/
+ 0x0F120A64, /*#AfitBaseVals_4__85_
+ AFIT8_Sharpening_iLowSharpPower_Bin [7:0],
+ AFIT8_Sharpening_iHighSharpPower_Bin [15:8]*/
+ 0x0F12062A, /*#AfitBaseVals_4__86_
+ AFIT8_Sharpening_iLowShDenoise_Bin [7:0],
+ AFIT8_Sharpening_iHighShDenoise_Bin [15:8]*/
+ 0x0F120440, /*#AfitBaseVals_4__87_
+ AFIT8_Sharpening_iReduceEdgeMinMult_Bin [7:0],
+ AFIT8_Sharpening_iReduceEdgeSlope_Bin [15:8]*/
+ 0x0F120606, /*#AfitBaseVals_4__88_
+ AFIT8_demsharpmix1_iWideFiltReduce_Bin [7:0],
+ AFIT8_demsharpmix1_iNarrFiltReduce_Bin [15:8]*/
+ 0x0F124646, /*#AfitBaseVals_4__89_
+ AFIT8_sddd8a_iClustThresh_H_sBin[7:0],
+ AFIT8_sddd8a_iClustThresh_C_sBin [15:8]*/
+ 0x0F120101, /*#AfitBaseVals_4__90_
+ AFIT8_sddd8a_iClustMulT_H_sBin [7:0],
+ AFIT8_sddd8a_iClustMulT_C_sBin [15:8]*/
+ 0x0F121801, /*#AfitBaseVals_4__91_
+ AFIT8_sddd8a_nClustLevel_H_sBin [7:0],
+ AFIT8_sddd8a_DispTH_Low_sBin [15:8]*/
+ 0x0F12191C, /*#AfitBaseVals_4__92_
+ AFIT8_sddd8a_DispTH_High_sBin [7:0],
+ AFIT8_sddd8a_iDenThreshLow_sBin [15:8]*/
+ 0x0F122818, /*#AfitBaseVals_4__93_
+ AFIT8_sddd8a_iDenThreshHigh_sBin[7:0],
+ AFIT8_Demosaicing_iEdgeDesat_sBin [15:8]*/
+ 0x0F120A00, /*#AfitBaseVals_4__94_
+ AFIT8_Demosaicing_iEdgeDesatThrLow_sBin [7:0],
+ AFIT8_Demosaicing_iEdgeDesatThrHigh_sBin [15:8]*/
+ 0x0F121403, /*#AfitBaseVals_4__95_
+ AFIT8_Demosaicing_iEdgeDesatLimit_sBin [7:0],
+ AFIT8_Demosaicing_iDemSharpenLow_sBin [15:8]*/
+ 0x0F121405, /*#AfitBaseVals_4__96_
+ AFIT8_Demosaicing_iDemSharpenHigh_sBin [7:0],
+ AFIT8_Demosaicing_iDemSharpThresh_sBin [15:8]*/
+ 0x0F12050C, /*#AfitBaseVals_4__97_
+ AFIT8_Demosaicing_iDemShLowLimit_sBin [7:0],
+ AFIT8_Demosaicing_iDespeckleForDemsharp_sBin [15:8]*/
+ 0x0F1232FF, /*#AfitBaseVals_4__98_
+ AFIT8_Demosaicing_iDemBlurLow_sBin [7:0],
+ AFIT8_Demosaicing_iDemBlurHigh_sBin [15:8]*/
+ 0x0F125204, /*#AfitBaseVals_4__99_
+ AFIT8_Demosaicing_iDemBlurRange_sBin [7:0],
+ AFIT8_Sharpening_iLowSharpPower_sBin [15:8]*/
+ 0x0F121440, /*#AfitBaseVals_4__100_
+ AFIT8_Sharpening_iHighSharpPower_sBin [7:0],
+ AFIT8_Sharpening_iLowShDenoise_sBin [15:8]*/
+ 0x0F124015, /*#AfitBaseVals_4__101_
+ AFIT8_Sharpening_iHighShDenoise_sBin [7:0],
+ AFIT8_Sharpening_iReduceEdgeMinMult_sBin [15:8]*/
+ 0x0F120204, /*#AfitBaseVals_4__102_
+ AFIT8_Sharpening_iReduceEdgeSlope_sBin [7:0],
+ AFIT8_demsharpmix1_iWideFiltReduce_sBin [15:8]*/
+ 0x0F120003, /*#AfitBaseVals_4__103_
+ AFIT8_demsharpmix1_iNarrFiltReduce_sBin [7:0]*/
+ /* param_end TVAR_afit_pBaseVals*/
+ /* param_start afit_pConstBaseVals*/
+ 0x0F127DFA, /*#ConstAfitBaseVals Because of Edge,
+ disable the iGradientWide*/
+ 0x0F12FFBD, /*#ConstAfitBaseVals_1_*/
+ 0x0F1226FE, /*#ConstAfitBaseVals_2_*/
+ 0x0F12F7BC, /*#ConstAfitBaseVals_3_*/
+ 0x0F127E06, /*#ConstAfitBaseVals_4_*/
+ 0x0F1200D3, /*#ConstAfitBaseVals_5_*/
+ /* param_end afit_pConstBaseVals*/
+ /* AFIT by Normalized Brightness Tuning parameter*/
+ 0x002A3780,
+ 0x0F120000, /* on/off AFIT by NB option 0000 : Ni 0001:Nb*/
+ 0x0F120014, /* NormBR[0]*/
+ 0x002A3782,
+ 0x0F1200D2, /* NormBR[1]*/
+ 0x002A3782,
+ 0x0F120384, /* NormBR[2]*/
+ 0x002A3782,
+ 0x0F1207D0, /* NormBR[3]*/
+ 0x002A3782,
+ 0x0F121388, /* NormBR[4]*/
+};
+
+
+/* Set-data based on Samsung Reliabilty Group standard
+* ,when using WIFI. 15fps
+*/
+static const u32 s5k5bbgx_vt_wifi_common[] = {
+ 0xFCFCD000,
+ /*===================================================================*/
+ /* Reset*/
+ /*===================================================================*/
+ 0x00100001, /*sw_reset*/
+ 0x10300000, /*contint_host_int*/
+ 0x00140001, /*sw_load_complete-Release CORE (Arm) from reset state*/
+ 0x01520084, /*make alive voltage low*/
+ 0xFFFF000A,
+ /* Start of Patch data*/
+ 0x00287000,
+ 0x002A2744,
+ 0x0F12B510, /* 70002744*/
+ 0x0F124A12, /* 70002746*/
+ 0x0F12217B, /* 70002748*/
+ 0x0F124812, /* 7000274A*/
+ 0x0F12C004, /* 7000274C*/
+ 0x0F126001, /* 7000274E*/
+ 0x0F124911, /* 70002750*/
+ 0x0F124812, /* 70002752*/
+ 0x0F12F000, /* 70002754*/
+ 0x0F12F926, /* 70002756*/
+ 0x0F124911, /* 70002758*/
+ 0x0F124812, /* 7000275A*/
+ 0x0F12F000, /* 7000275C*/
+ 0x0F12F922, /* 7000275E*/
+ 0x0F124911, /* 70002760*/
+ 0x0F124812, /* 70002762*/
+ 0x0F12F000, /* 70002764*/
+ 0x0F12F91E, /* 70002766*/
+ 0x0F124911, /* 70002768*/
+ 0x0F124812, /* 7000276A*/
+ 0x0F12F000, /* 7000276C*/
+ 0x0F12F91A, /* 7000276E*/
+ 0x0F124911, /* 70002770*/
+ 0x0F124812, /* 70002772*/
+ 0x0F12F000, /* 70002774*/
+ 0x0F12F916, /* 70002776*/
+ 0x0F124911, /* 70002778*/
+ 0x0F124812, /* 7000277A*/
+ 0x0F12F000, /* 7000277C*/
+ 0x0F12F912, /* 7000277E*/
+ 0x0F124911, /* 70002780*/
+ 0x0F124812, /* 70002782*/
+ 0x0F12F000, /* 70002784*/
+ 0x0F12F90E, /* 70002786*/
+ 0x0F12BC10, /* 70002788*/
+ 0x0F12BC08, /* 7000278A*/
+ 0x0F124718, /* 7000278C*/
+ 0x0F120000, /* 7000278E*/
+ 0x0F120000, /* 70002790*/
+ 0x0F125BB1, /* 70002792*/
+ 0x0F121770, /* 70002794*/
+ 0x0F127000, /* 70002796*/
+ 0x0F1227D1, /* 70002798*/
+ 0x0F127000, /* 7000279A*/
+ 0x0F12C0BB, /* 7000279C*/
+ 0x0F120000, /* 7000279E*/
+ 0x0F12280F, /* 700027A0*/
+ 0x0F127000, /* 700027A2*/
+ 0x0F123609, /* 700027A4*/
+ 0x0F120000, /* 700027A6*/
+ 0x0F122827, /* 700027A8*/
+ 0x0F127000, /* 700027AA*/
+ 0x0F1277C7, /* 700027AC*/
+ 0x0F120000, /* 700027AE*/
+ 0x0F1228B3, /* 700027B0*/
+ 0x0F127000, /* 700027B2*/
+ 0x0F12727D, /* 700027B4*/
+ 0x0F120000, /* 700027B6*/
+ 0x0F1228CD, /* 700027B8*/
+ 0x0F127000, /* 700027BA*/
+ 0x0F129919, /* 700027BC*/
+ 0x0F120000, /* 700027BE*/
+ 0x0F12290B, /* 700027C0*/
+ 0x0F127000, /* 700027C2*/
+ 0x0F121C63, /* 700027C4*/
+ 0x0F120000, /* 700027C6*/
+ 0x0F12296B, /* 700027C8*/
+ 0x0F127000, /* 700027CA*/
+ 0x0F1204CB, /* 700027CC*/
+ 0x0F120000, /* 700027CE*/
+ 0x0F12B4F0, /* 700027D0*/
+ 0x0F126801, /* 700027D2*/
+ 0x0F12468C, /* 700027D4*/
+ 0x0F126846, /* 700027D6*/
+ 0x0F122200, /* 700027D8*/
+ 0x0F124968, /* 700027DA*/
+ 0x0F122000, /* 700027DC*/
+ 0x0F122724, /* 700027DE*/
+ 0x0F124357, /* 700027E0*/
+ 0x0F12183B, /* 700027E2*/
+ 0x0F124664, /* 700027E4*/
+ 0x0F125CE5, /* 700027E6*/
+ 0x0F12005C, /* 700027E8*/
+ 0x0F125B34, /* 700027EA*/
+ 0x0F12072D, /* 700027EC*/
+ 0x0F120F2D, /* 700027EE*/
+ 0x0F12800D, /* 700027F0*/
+ 0x0F12804C, /* 700027F2*/
+ 0x0F12808B, /* 700027F4*/
+ 0x0F122301, /* 700027F6*/
+ 0x0F1280CB, /* 700027F8*/
+ 0x0F122300, /* 700027FA*/
+ 0x0F1280CB, /* 700027FC*/
+ 0x0F121C40, /* 700027FE*/
+ 0x0F122824, /* 70002800*/
+ 0x0F12D3EE, /* 70002802*/
+ 0x0F121C52, /* 70002804*/
+ 0x0F122A04, /* 70002806*/
+ 0x0F12D3E8, /* 70002808*/
+ 0x0F12BCF0, /* 7000280A*/
+ 0x0F124770, /* 7000280C*/
+ 0x0F12B510, /* 7000280E*/
+ 0x0F12F000, /* 70002810*/
+ 0x0F12F8D0, /* 70002812*/
+ 0x0F12485A, /* 70002814*/
+ 0x0F127A81, /* 70002816*/
+ 0x0F12485A, /* 70002818*/
+ 0x0F126B00, /* 7000281A*/
+ 0x0F12F000, /* 7000281C*/
+ 0x0F12F8D2, /* 7000281E*/
+ 0x0F12BC10, /* 70002820*/
+ 0x0F12BC08, /* 70002822*/
+ 0x0F124718, /* 70002824*/
+ 0x0F12B5F8, /* 70002826*/
+ 0x0F126805, /* 70002828*/
+ 0x0F126844, /* 7000282A*/
+ 0x0F124E56, /* 7000282C*/
+ 0x0F128861, /* 7000282E*/
+ 0x0F128AB0, /* 70002830*/
+ 0x0F128A72, /* 70002832*/
+ 0x0F122301, /* 70002834*/
+ 0x0F124368, /* 70002836*/
+ 0x0F121889, /* 70002838*/
+ 0x0F1217C2, /* 7000283A*/
+ 0x0F120E12, /* 7000283C*/
+ 0x0F121810, /* 7000283E*/
+ 0x0F121202, /* 70002840*/
+ 0x0F128820, /* 70002842*/
+ 0x0F12029B, /* 70002844*/
+ 0x0F1218C0, /* 70002846*/
+ 0x0F12F000, /* 70002848*/
+ 0x0F12F8C4, /* 7000284A*/
+ 0x0F129000, /* 7000284C*/
+ 0x0F128AF6, /* 7000284E*/
+ 0x0F124268, /* 70002850*/
+ 0x0F12210A, /* 70002852*/
+ 0x0F124370, /* 70002854*/
+ 0x0F12F000, /* 70002856*/
+ 0x0F12F8C5, /* 70002858*/
+ 0x0F12436E, /* 7000285A*/
+ 0x0F120007, /* 7000285C*/
+ 0x0F12210A, /* 7000285E*/
+ 0x0F120030, /* 70002860*/
+ 0x0F12F000, /* 70002862*/
+ 0x0F12F8BF, /* 70002864*/
+ 0x0F129A00, /* 70002866*/
+ 0x0F120039, /* 70002868*/
+ 0x0F12F000, /* 7000286A*/
+ 0x0F12F8C1, /* 7000286C*/
+ 0x0F120002, /* 7000286E*/
+ 0x0F128820, /* 70002870*/
+ 0x0F121880, /* 70002872*/
+ 0x0F128020, /* 70002874*/
+ 0x0F124845, /* 70002876*/
+ 0x0F1288C1, /* 70002878*/
+ 0x0F124843, /* 7000287A*/
+ 0x0F123820, /* 7000287C*/
+ 0x0F128B40, /* 7000287E*/
+ 0x0F124240, /* 70002880*/
+ 0x0F124350, /* 70002882*/
+ 0x0F12F000, /* 70002884*/
+ 0x0F12F8AE, /* 70002886*/
+ 0x0F128861, /* 70002888*/
+ 0x0F121840, /* 7000288A*/
+ 0x0F128060, /* 7000288C*/
+ 0x0F12BCF8, /* 7000288E*/
+ 0x0F12BC08, /* 70002890*/
+ 0x0F124718, /* 70002892*/
+ 0x0F12B570, /* 70002894*/
+ 0x0F124C3C, /* 70002896*/
+ 0x0F123C20, /* 70002898*/
+ 0x0F128B20, /* 7000289A*/
+ 0x0F12F000, /* 7000289C*/
+ 0x0F12F8B0, /* 7000289E*/
+ 0x0F124D3A, /* 700028A0*/
+ 0x0F1280E8, /* 700028A2*/
+ 0x0F128B60, /* 700028A4*/
+ 0x0F12F000, /* 700028A6*/
+ 0x0F12F8B3, /* 700028A8*/
+ 0x0F128128, /* 700028AA*/
+ 0x0F12BC70, /* 700028AC*/
+ 0x0F12BC08, /* 700028AE*/
+ 0x0F124718, /* 700028B0*/
+ 0x0F12B510, /* 700028B2*/
+ 0x0F124836, /* 700028B4*/
+ 0x0F12214D, /* 700028B6*/
+ 0x0F128201, /* 700028B8*/
+ 0x0F122196, /* 700028BA*/
+ 0x0F128281, /* 700028BC*/
+ 0x0F12211D, /* 700028BE*/
+ 0x0F128301, /* 700028C0*/
+ 0x0F12F7FF, /* 700028C2*/
+ 0x0F12FFE7, /* 700028C4*/
+ 0x0F12F000, /* 700028C6*/
+ 0x0F12F8AB, /* 700028C8*/
+ 0x0F12E7A9, /* 700028CA*/
+ 0x0F12B570, /* 700028CC*/
+ 0x0F120004, /* 700028CE*/
+ 0x0F126820, /* 700028D0*/
+ 0x0F126865, /* 700028D2*/
+ 0x0F12F000, /* 700028D4*/
+ 0x0F12F8AC, /* 700028D6*/
+ 0x0F120402, /* 700028D8*/
+ 0x0F12482E, /* 700028DA*/
+ 0x0F120C12, /* 700028DC*/
+ 0x0F128142, /* 700028DE*/
+ 0x0F12482D, /* 700028E0*/
+ 0x0F128801, /* 700028E2*/
+ 0x0F122900, /* 700028E4*/
+ 0x0F12D008, /* 700028E6*/
+ 0x0F12492C, /* 700028E8*/
+ 0x0F12002B, /* 700028EA*/
+ 0x0F126D8A, /* 700028EC*/
+ 0x0F122105, /* 700028EE*/
+ 0x0F121C80, /* 700028F0*/
+ 0x0F12F000, /* 700028F2*/
+ 0x0F12F8A5, /* 700028F4*/
+ 0x0F126020, /* 700028F6*/
+ 0x0F12E005, /* 700028F8*/
+ 0x0F124829, /* 700028FA*/
+ 0x0F12002B, /* 700028FC*/
+ 0x0F122105, /* 700028FE*/
+ 0x0F12F000, /* 70002900*/
+ 0x0F12F89E, /* 70002902*/
+ 0x0F126020, /* 70002904*/
+ 0x0F126820, /* 70002906*/
+ 0x0F12E7D0, /* 70002908*/
+ 0x0F12B5F8, /* 7000290A*/
+ 0x0F124923, /* 7000290C*/
+ 0x0F122200, /* 7000290E*/
+ 0x0F123160, /* 70002910*/
+ 0x0F1283CA, /* 70002912*/
+ 0x0F126800, /* 70002914*/
+ 0x0F124669, /* 70002916*/
+ 0x0F12F000, /* 70002918*/
+ 0x0F12F89A, /* 7000291A*/
+ 0x0F12466B, /* 7000291C*/
+ 0x0F128818, /* 7000291E*/
+ 0x0F12F000, /* 70002920*/
+ 0x0F12F86E, /* 70002922*/
+ 0x0F120005, /* 70002924*/
+ 0x0F12466B, /* 70002926*/
+ 0x0F128858, /* 70002928*/
+ 0x0F12F000, /* 7000292A*/
+ 0x0F12F871, /* 7000292C*/
+ 0x0F120004, /* 7000292E*/
+ 0x0F122101, /* 70002930*/
+ 0x0F121928, /* 70002932*/
+ 0x0F1202C9, /* 70002934*/
+ 0x0F121A08, /* 70002936*/
+ 0x0F120286, /* 70002938*/
+ 0x0F120029, /* 7000293A*/
+ 0x0F120030, /* 7000293C*/
+ 0x0F12F000, /* 7000293E*/
+ 0x0F12F88F, /* 70002940*/
+ 0x0F120005, /* 70002942*/
+ 0x0F122701, /* 70002944*/
+ 0x0F1202BF, /* 70002946*/
+ 0x0F120021, /* 70002948*/
+ 0x0F120030, /* 7000294A*/
+ 0x0F12F000, /* 7000294C*/
+ 0x0F12F888, /* 7000294E*/
+ 0x0F124912, /* 70002950*/
+ 0x0F124A0E, /* 70002952*/
+ 0x0F123140, /* 70002954*/
+ 0x0F123AC0, /* 70002956*/
+ 0x0F12800D, /* 70002958*/
+ 0x0F128395, /* 7000295A*/
+ 0x0F12804F, /* 7000295C*/
+ 0x0F1283D7, /* 7000295E*/
+ 0x0F128088, /* 70002960*/
+ 0x0F120011, /* 70002962*/
+ 0x0F123120, /* 70002964*/
+ 0x0F128008, /* 70002966*/
+ 0x0F12E791, /* 70002968*/
+ 0x0F12B510, /* 7000296A*/
+ 0x0F12480A, /* 7000296C*/
+ 0x0F128980, /* 7000296E*/
+ 0x0F122800, /* 70002970*/
+ 0x0F12D001, /* 70002972*/
+ 0x0F12F000, /* 70002974*/
+ 0x0F12F87A, /* 70002976*/
+ 0x0F12E752, /* 70002978*/
+ 0x0F120000, /* 7000297A*/
+ 0x0F124140, /* 7000297C*/
+ 0x0F12D000, /* 7000297E*/
+ 0x0F1219DC, /* 70002980*/
+ 0x0F127000, /* 70002982*/
+ 0x0F121B60, /* 70002984*/
+ 0x0F127000, /* 70002986*/
+ 0x0F120DD4, /* 70002988*/
+ 0x0F127000, /* 7000298A*/
+ 0x0F1222AC, /* 7000298C*/
+ 0x0F127000, /* 7000298E*/
+ 0x0F121E8C, /* 70002990*/
+ 0x0F127000, /* 70002992*/
+ 0x0F121A10, /* 70002994*/
+ 0x0F127000, /* 70002996*/
+ 0x0F123780, /* 70002998*/
+ 0x0F127000, /* 7000299A*/
+ 0x0F122384, /* 7000299C*/
+ 0x0F127000, /* 7000299E*/
+ 0x0F12065C, /* 700029A0*/
+ 0x0F127000, /* 700029A2*/
+ 0x0F124778, /* 700029A4*/
+ 0x0F1246C0, /* 700029A6*/
+ 0x0F12C000, /* 700029A8*/
+ 0x0F12E59F, /* 700029AA*/
+ 0x0F12FF1C, /* 700029AC*/
+ 0x0F12E12F, /* 700029AE*/
+ 0x0F12CE77, /* 700029B0*/
+ 0x0F120000, /* 700029B2*/
+ 0x0F124778, /* 700029B4*/
+ 0x0F1246C0, /* 700029B6*/
+ 0x0F12C000, /* 700029B8*/
+ 0x0F12E59F, /* 700029BA*/
+ 0x0F12FF1C, /* 700029BC*/
+ 0x0F12E12F, /* 700029BE*/
+ 0x0F123609, /* 700029C0*/
+ 0x0F120000, /* 700029C2*/
+ 0x0F124778, /* 700029C4*/
+ 0x0F1246C0, /* 700029C6*/
+ 0x0F12C000, /* 700029C8*/
+ 0x0F12E59F, /* 700029CA*/
+ 0x0F12FF1C, /* 700029CC*/
+ 0x0F12E12F, /* 700029CE*/
+ 0x0F129F91, /* 700029D0*/
+ 0x0F120000, /* 700029D2*/
+ 0x0F124778, /* 700029D4*/
+ 0x0F1246C0, /* 700029D6*/
+ 0x0F12C000, /* 700029D8*/
+ 0x0F12E59F, /* 700029DA*/
+ 0x0F12FF1C, /* 700029DC*/
+ 0x0F12E12F, /* 700029DE*/
+ 0x0F122AE3, /* 700029E0*/
+ 0x0F120000, /* 700029E2*/
+ 0x0F124778, /* 700029E4*/
+ 0x0F1246C0, /* 700029E6*/
+ 0x0F12F004, /* 700029E8*/
+ 0x0F12E51F, /* 700029EA*/
+ 0x0F12D1DC, /* 700029EC*/
+ 0x0F120000, /* 700029EE*/
+ 0x0F124778, /* 700029F0*/
+ 0x0F1246C0, /* 700029F2*/
+ 0x0F12C000, /* 700029F4*/
+ 0x0F12E59F, /* 700029F6*/
+ 0x0F12FF1C, /* 700029F8*/
+ 0x0F12E12F, /* 700029FA*/
+ 0x0F126869, /* 700029FC*/
+ 0x0F120000, /* 700029FE*/
+ 0x0F124778, /* 70002A00*/
+ 0x0F1246C0, /* 70002A02*/
+ 0x0F12C000, /* 70002A04*/
+ 0x0F12E59F, /* 70002A06*/
+ 0x0F12FF1C, /* 70002A08*/
+ 0x0F12E12F, /* 70002A0A*/
+ 0x0F1268BD, /* 70002A0C*/
+ 0x0F120000, /* 70002A0E*/
+ 0x0F124778, /* 70002A10*/
+ 0x0F1246C0, /* 70002A12*/
+ 0x0F12C000, /* 70002A14*/
+ 0x0F12E59F, /* 70002A16*/
+ 0x0F12FF1C, /* 70002A18*/
+ 0x0F12E12F, /* 70002A1A*/
+ 0x0F1268DB, /* 70002A1C*/
+ 0x0F120000, /* 70002A1E*/
+ 0x0F124778, /* 70002A20*/
+ 0x0F1246C0, /* 70002A22*/
+ 0x0F12C000, /* 70002A24*/
+ 0x0F12E59F, /* 70002A26*/
+ 0x0F12FF1C, /* 70002A28*/
+ 0x0F12E12F, /* 70002A2A*/
+ 0x0F1271B9, /* 70002A2C*/
+ 0x0F120000, /* 70002A2E*/
+ 0x0F124778, /* 70002A30*/
+ 0x0F1246C0, /* 70002A32*/
+ 0x0F12C000, /* 70002A34*/
+ 0x0F12E59F, /* 70002A36*/
+ 0x0F12FF1C, /* 70002A38*/
+ 0x0F12E12F, /* 70002A3A*/
+ 0x0F1298CD, /* 70002A3C*/
+ 0x0F120000, /* 70002A3E*/
+ 0x0F124778, /* 70002A40*/
+ 0x0F1246C0, /* 70002A42*/
+ 0x0F12C000, /* 70002A44*/
+ 0x0F12E59F, /* 70002A46*/
+ 0x0F12FF1C, /* 70002A48*/
+ 0x0F12E12F, /* 70002A4A*/
+ 0x0F12987F, /* 70002A4C*/
+ 0x0F120000, /* 70002A4E*/
+ 0x0F124778, /* 70002A50*/
+ 0x0F1246C0, /* 70002A52*/
+ 0x0F12C000, /* 70002A54*/
+ 0x0F12E59F, /* 70002A56*/
+ 0x0F12FF1C, /* 70002A58*/
+ 0x0F12E12F, /* 70002A5A*/
+ 0x0F121BC9, /* 70002A5C*/
+ 0x0F120000, /* 70002A5E*/
+ 0x0F124778, /* 70002A60*/
+ 0x0F1246C0, /* 70002A62*/
+ 0x0F12F004, /* 70002A64*/
+ 0x0F12E51F, /* 70002A66*/
+ 0x0F12D378, /* 70002A68*/
+ 0x0F120000, /* 70002A6A*/
+ 0x0F124778, /* 70002A6C*/
+ 0x0F1246C0, /* 70002A6E*/
+ 0x0F12C000, /* 70002A70*/
+ 0x0F12E59F, /* 70002A72*/
+ 0x0F12FF1C, /* 70002A74*/
+ 0x0F12E12F, /* 70002A76*/
+ 0x0F1204CB, /* 70002A78*/
+ 0x0F120000, /* 70002A7A*/
+ 0x002A378C,
+ 0x0F120000, /* On/off register bUseOTP*/
+ 0x002A0DCC,
+ 0x0F120138, /*awbb_IntcR*/
+ 0x0F12011C, /*awbb_IntcB*/
+ /*===================================================================*/
+ /*Analog & APS Control*/
+ /*===================================================================*/
+ 0x0028D000,
+ 0x002AF404,
+ 0x0F120038, /* aig_adc_sat[7:0] : 850mV, revised by Ana 20100524*/
+ 0x0F120001, /* aig_ms[2:0] : revised by Ana 20100202*/
+ 0x0F12000C, /* aig_sig_mx[5:0]*/
+ 0x0F120006, /* aig_rst_mx[5:0]*/
+ 0x0F120008, /* aig_rmp_option[3] SL_Low_PWR_SAVE On :
+ revised by Ana 20100204*/
+ 0x002AF418,
+ 0x0F120003, /* aig_dbr_clk_sel[1:0] : revised by Ana 20100201*/
+ 0x002AF41C,
+ 0x0F120140, /* aig_bist_sig_width_e[10:0]*/
+ 0x0F120140, /* aig_bist_sig_width_o[10:0]*/
+ 0x0F120066, /* aig_bist_sig_width_o[10:0]*/
+ 0x0F120005, /* aig_pix_bias[3:0]*/
+ 0x002AF426,
+ 0x0F1200D4, /* aig_clp_lvl[7:0]*/
+ 0x002AF42A,
+ 0x0F120001, /* aig_ref_option[0] SL_Low_PWR_SAVE On :
+ revised by Ana 20100204*/
+ 0x002AF430,
+ 0x0F120001, /* aig_pd_cp_rosc[0] : revised by Ana 20100201*/
+ 0x0F120001, /* aig_pd_ncp_rosc[0] : revised by Ana 20100201*/
+ 0x002AF43A,
+ 0x0F120000, /* aig_pd_fblv[0] : revised by Ana 20100203*/
+ 0x002AF440,
+ 0x0F120044, /* aig_rosc_tune_ncp[7:4]*/
+ /* aig_rosc_tune_cp[3:0]*/
+ 0x002AF44A,
+ 0x0F120000, /* aig_fb_lv[1:0] : revised by Ana 20100204*/
+ 0x002AF45C,
+ 0x0F120000, /* aig_dshut_en[0] : revised by APS 20100223*/
+ 0x0F120000, /* aig_srx_en[0]*/
+ 0x002AF462,
+ 0x0F120001, /* aig_pdb_atop[0]*/
+ 0x002AF46E,
+ 0x0F121F02, /* aig_cds_test[15:0]*/
+ 0x002AF474,
+ 0x0F12000E, /* aig_stx_gap[4:0]*/
+ 0x002AE42E,
+ 0x0F120004, /* adlc_qec[2:0] : revised by Dithered L-ADLC Designer
+ 20100203*/
+ 0x00287000,
+ 0x002A13E0,
+ 0x0F120000, /*700013E0 SRX OFF*/
+ 0x002A13C8,
+ 0x0F120001, /*700013C8 AAC Enable*/
+ 0x002A12D8,
+ 0x0F120464, /*700012d8*/
+ 0x0F120468, /*700012da*/
+ 0x002A12F6,
+ 0x0F120000, /*700012f6*/
+ 0x002A13CC,
+ 0x0F121FC0, /* [12:0] : Write tuning value to E404 register*/
+ 0x002A13EC,
+ 0x0F120001,
+ 0x002A184C,
+ 0x0F121EE1,
+ 0x0028D000,
+ 0x002A1000,
+ 0x0F120001,
+ 0x00287000,
+ 0x002A040E,
+ 0x0F120003, /*STBY TnP enable setting STBY TnP enable setting [0]
+ bit STBY enable,[1] bit STBY ø TnP ? on/off bit*/
+ 0xFFFF000A,
+ /*H-Digital binning & V-PLA*/
+ 0x002A1218,
+ 0x0F120002, /*subsampling number.*/
+ 0x0F120002, /*subsampling number.*/
+ 0x002A0C9A,
+ 0x0F120001, /* setot_bUseDigitalHbin 0 : do not use bin block*/
+ /* 1 : use binning block*/
+ 0x002A1438,
+ 0x0F12F468, /* senHal_TuneStr_AngTuneData1[0] : tuning register
+ setting.*/
+ 0x0F120000, /* not use binninb block 0x0000 ,use binnin blcok
+ 0x0000*/
+ 0x0F120008, /* not use binninb block 0x000A ,use binnin blcok
+ 0x0008*/
+ 0x0F120006, /* not use binninb block 0x0005 , use binnin blcok
+ 0x0006*/
+ 0x0F120000, /* 0x0000 , 0x0000*/
+ 0xFFFF000A,
+ /* Backup Register*/
+ 0x002A0416,
+ 0x0F12F400,
+ 0x0F120074,
+ 0x0F12E42E,
+ 0x0F120030,
+ /*clk Settings*/
+ 0x00287000,
+ 0x002A00F4,
+ 0x0F125DC0, /*REG_TC_IPRM_InClockLSBs 2 700000F4*/
+ /*0x0F120000*/ /*REG_TC_IPRM_InClockMSBs 2 700000F6*/
+ 0x002A0110,
+ 0x0F120003, /*REG_TC_IPRM_UseNPviClocks 2 70000110*/
+ 0x0F120000, /*REG_TC_IPRM_bBlockInternalPllCalc 2 70000112*/
+ /*SYSTEM CLOCK*/
+ 0x0F12222E, /*REG_TC_IPRM_OpClk4KHz_0 2 70000114
+ 35000Khz/4=HEX()*/
+ 0x0F12445C, /*REG_TC_IPRM_MinOutRate4KHz_0 2 70000116*/
+ 0x0F12445C, /*REG_TC_IPRM_MaxOutRate4KHz_0 2 70000118*/
+ 0x0F121117, /*1770 REG_TC_IPRM_OpClk4KHz_1 2 7000011A
+ 24000Khz/4*/
+ 0x0F12222E, /*REG_TC_IPRM_MinOutRate4KHz_1 2 7000011C
+ 36000khz/4 =2328hex*/
+ 0x0F12222E, /*REG_TC_IPRM_MaxOutRate4KHz_1 2 7000011E*/
+ 0x0F120BB8, /*REG_TC_IPRM_OpClk4KHz_2 2 70000120
+ 12000Khz*/
+ 0x0F1205DC, /*REG_TC_IPRM_MinOutRate4KHz_2 2 70000122*/
+ 0x0F121770, /*REG_TC_IPRM_MaxOutRate4KHz_2 2 70000124*/
+ 0x0F120001, /*REG_TC_IPRM_InitParamsUpdated 2 70000126*/
+ 0xFFFF0064,
+ 0x002A1218,
+ 0x0F120002,
+ /*===================================================================*/
+ /*Preview0 1600x1200 system 32M PCLK 70M From APS*/
+ /*===================================================================*/
+ 0x002A0144,
+ 0x0F120640,
+ 0x0F1204B0,
+ 0x0F120000,
+ 0x0F120000,
+ /*Preview0 for 7.5~15fps*/
+ 0x002A0170,
+ 0x0F120280, /*REG_0TC_PCFG_usWidth 2 70000170*/
+ 0x0F1201e0, /*REG_0TC_PCFG_usHeight 2 70000172*/
+ 0x0F120005, /*REG_0TC_PCFG_Format 2 70000174*/
+ 0x0F12222E, /*REG_0TC_PCFG_usMaxOut4KHzRate 2 70000176*/
+ 0x0F12222E, /*REG_0TC_PCFG_usMinOut4KHzRate 2 70000178*/
+ 0x0F120042, /*REG_0TC_PCFG_PVIMask 2 7000017A*/
+ 0x0F120010, /*REG_0TC_PCFG_OIFMask 2 7000017C*/
+ 0x0F120001, /*REG_0TC_PCFG_uClockInd 2 7000017E*/
+ 0x0F120002, /*REG_0TC_PCFG_usFrTimeType 2 70000180
+ 0b : dynamic 01:fix not accurate 02b: fixed_Accurate*/
+ 0x0F120001, /*REG_0TC_PCFG_FrRateQualityType 2 70000182
+ 1b: FR (bin) 2b: Quality (no-bin)*/
+ 0x0F12029a, /*REG_0TC_PCFG_usMaxFrTimeMsecMult10 2 70000184
+ max frame time : 30fps 014D 15fps 029a; a6a -
+ 3.75 fps; 0535 - 7.5FPS*/
+ 0x0F12029A, /*REG_0TC_PCFG_usMinFrTimeMsecMult10 2 70000186*/
+ 0x0F120000, /*REG_0TC_PCFG_bSmearOutput 2 70000188*/
+ 0x0F120000, /*REG_0TC_PCFG_sSaturation 2 7000018A*/
+ 0x0F120000, /*REG_0TC_PCFG_sSharpBlur 2 7000018C*/
+ 0x0F120000, /*REG_0TC_PCFG_sColorTemp 2 7000018E*/
+ 0x0F120000, /*REG_0TC_PCFG_uDeviceGammaIndex 2 70000190*/
+ 0x0F120000, /*REG_0TC_PCFG_uPrevMirror 2 70000192*/
+ 0x0F120000, /*REG_0TC_PCFG_uCaptureMirror 2 70000194*/
+ 0x0F120000, /*REG_0TC_PCFG_uRotation 2 70000196*/
+ /*Preview1 for fixed 15fps*/
+ 0x0F120280, /*REG_1TC_PCFG_usWidth 2 70000198*/
+ 0x0F1201e0, /*REG_1TC_PCFG_usHeight 2 7000019A*/
+ 0x0F120005, /*REG_1TC_PCFG_Format 2 7000019C*/
+ 0x0F12222E, /*REG_1TC_PCFG_usMaxOut4KHzRate 2 7000019E*/
+ 0x0F12222E, /*REG_1TC_PCFG_usMinOut4KHzRate 2 700001A0*/
+ 0x0F120042, /*REG_1TC_PCFG_PVIMask 2 700001A2*/
+ 0x0F120010, /*REG_1TC_PCFG_OIFMask 2 700001A4*/
+ 0x0F120001, /*REG_1TC_PCFG_uClockInd 2 700001A6*/
+ 0x0F120000, /*REG_1TC_PCFG_usFrTimeType 2 700001A8*/
+ 0x0F120001, /*REG_1TC_PCFG_FrRateQualityType 2 700001AA*/
+ 0x0F12029A, /*REG_1TC_PCFG_usMaxFrTimeMsecMult10 2 700001AC*/
+ 0x0F12029A, /*REG_1TC_PCFG_usMinFrTimeMsecMult10 2 700001AE*/
+ 0x0F120000, /*REG_1TC_PCFG_bSmearOutput 2 700001B0*/
+ 0x0F120000, /*REG_1TC_PCFG_sSaturation 2 700001B2*/
+ 0x0F120000, /*REG_1TC_PCFG_sSharpBlur 2 700001B4*/
+ 0x0F120000, /*REG_1TC_PCFG_sColorTemp 2 700001B6*/
+ 0x0F120000, /*REG_1TC_PCFG_uDeviceGammaIndex 2 700001B8*/
+ 0x0F120000, /*REG_1TC_PCFG_uPrevMirror 2 700001BA*/
+ 0x0F120000, /*REG_1TC_PCFG_uCaptureMirror 2 700001BC*/
+ 0x0F120000, /*REG_1TC_PCFG_uRotation 2 700001BE*/
+ /*Preview2 for nightshot*/
+ 0x0F120320, /*REG_2TC_PCFG_usWidth 2 700001C0*/
+ 0x0F120258, /*REG_2TC_PCFG_usHeight 2 700001C2*/
+ 0x0F120005, /*REG_2TC_PCFG_Format 2 700001C4*/
+ 0x0F12222E, /*REG_2TC_PCFG_usMaxOut4KHzRate 2 700001C6*/
+ 0x0F12222E, /*REG_2TC_PCFG_usMinOut4KHzRate 2 700001C8*/
+ 0x0F120042, /*REG_2TC_PCFG_PVIMask 2 700001CA*/
+ 0x0F120010, /*REG_2TC_PCFG_OIFMask 2 700001CC*/
+ 0x0F120000, /*REG_2TC_PCFG_uClockInd 2 700001CE*/
+ 0x0F120000, /*REG_2TC_PCFG_usFrTimeType 2 700001D0*/
+ 0x0F120001, /*REG_2TC_PCFG_FrRateQualityType 2 700001D2
+ 1b: FR (bin) 2b: Quality (no-bin)*/
+ 0x0F12014D, /*REG_2TC_PCFG_usMaxFrTimeMsecMult10 2 700001D4
+ max frame time : 30fps 014D 15fps 029a; a6a -
+ 3.75 fps; 0535 - 7.5FPS*/
+ 0x0F12014D, /*REG_2TC_PCFG_usMinFrTimeMsecMult10 2 700001D6*/
+ 0x0F120000, /*REG_2TC_PCFG_bSmearOutput 2 700001D8*/
+ 0x0F120000, /*REG_2TC_PCFG_sSaturation 2 700001DA*/
+ 0x0F120000, /*REG_2TC_PCFG_sSharpBlur 2 700001DC*/
+ 0x0F120000, /*REG_2TC_PCFG_sColorTemp 2 700001DE*/
+ 0x0F120000, /*REG_2TC_PCFG_uDeviceGammaIndex 2 700001E0*/
+ 0x0F120000, /*REG_2TC_PCFG_uPrevMirror 2 700001E2
+ [0] : x [1]: Y [2] Stat X [3] Stat Y*/
+ 0x0F120000, /*REG_2TC_PCFG_uCaptureMirror 2 700001E4*/
+ 0x0F120000, /*REG_2TC_PCFG_uRotation 2 700001E6*/
+ 0x002A0238,
+ 0x0F120001, /*REG_0TC_CCFG_uCaptureMode 2 70000238*/
+ 0x0F120640, /*REG_0TC_CCFG_usWidth 2 7000023A*/
+ 0x0F1204B0, /*REG_0TC_CCFG_usHeight 2 7000023C*/
+ 0x0F120005, /*REG_0TC_CCFG_Format 2 7000023E*/
+ 0x0F12222E, /*REG_0TC_CCFG_usMaxOut4KHzRate 2 70000240*/
+ 0x0F12222E, /*REG_0TC_CCFG_usMinOut4KHzRate 2 70000242*/
+ 0x0F120042, /*REG_0TC_CCFG_PVIMask 2 70000244*/
+ 0x0F120000, /*REG_0TC_CCFG_OIFMask 2 70000246*/
+ 0x0F120001, /*REG_0TC_CCFG_uClockInd 2 70000248*/
+ 0x0F120000, /*REG_0TC_CCFG_usFrTimeType 2 7000024A*/
+ 0x0F120002, /*REG_0TC_CCFG_FrRateQualityType 2 7000024C*/
+ 0x0F1205D0, /*REG_0TC_CCFG_usMaxFrTimeMsecMult10 2 7000024E*/
+ 0x0F1204D0, /*REG_0TC_CCFG_usMinFrTimeMsecMult10 2 70000250*/
+ 0x0F120000, /*REG_0TC_CCFG_bSmearOutput 2 70000252*/
+ 0x0F120000, /*REG_0TC_CCFG_sSaturation 2 70000254*/
+ 0x0F120000, /*REG_0TC_CCFG_sSharpBlur 2 70000256*/
+ 0x0F120000, /*REG_0TC_CCFG_sColorTemp 2 70000258*/
+ 0x0F120000, /*REG_0TC_CCFG_uDeviceGammaIndex 2 7000025A*/
+ 0x0F120001, /*REG_1TC_CCFG_uCaptureMode 2 7000025C*/
+ 0x0F120640, /*REG_1TC_CCFG_usWidth 2 7000025E*/
+ 0x0F1204B0, /*REG_1TC_CCFG_usHeight 2 70000260*/
+ 0x0F120005, /*REG_1TC_CCFG_Format 2 70000262*/
+ 0x0F12222E, /*REG_1TC_CCFG_usMaxOut4KHzRate 2 70000264*/
+ 0x0F12222E, /*REG_1TC_CCFG_usMinOut4KHzRate 2 70000266*/
+ 0x0F120042, /*REG_1TC_CCFG_PVIMask 2 70000268*/
+ 0x0F120000, /*REG_1TC_CCFG_OIFMask 2 7000026A*/
+ 0x0F120001, /*REG_1TC_CCFG_uClockInd 2 7000026C*/
+ 0x0F120000, /*REG_1TC_CCFG_usFrTimeType 2 7000026E*/
+ 0x0F120002, /*REG_1TC_CCFG_FrRateQualityType 2 70000270*/
+ 0x0F121388, /*REG_1TC_CCFG_usMaxFrTimeMsecMult10 2 70000272*/
+ 0x0F121388, /*REG_1TC_CCFG_usMinFrTimeMsecMult10 2 70000274*/
+ 0x0F120000, /*REG_1TC_CCFG_bSmearOutput 2 70000276*/
+ 0x0F120000, /*REG_1TC_CCFG_sSaturation 2 70000278*/
+ 0x0F120000, /*REG_1TC_CCFG_sSharpBlur 2 7000027A*/
+ 0x0F120000, /*REG_1TC_CCFG_sColorTemp 2 7000027C*/
+ 0x0F120000, /*REG_1TC_CCFG_uDeviceGammaIndex 2 7000027E*/
+ 0x002A1218,
+ 0x0F120002,
+ /*PREVIEW*/
+ 0x002A0156,
+ 0x0F120001,
+ 0x002A015E,
+ 0x0F120000,
+ 0x002A015A,
+ 0x0F120001,
+ 0x002A0142,
+ 0x0F120001,
+ 0x002A0158,
+ 0x0F120001,
+ 0x002A0160,
+ 0x0F120001,
+ 0x002A013A,
+ 0x0F120001,
+ 0x0F120001,
+ 0xFFFF0064,
+ /*===================================================================*/
+ /*AFC*/
+ /*===================================================================*/
+ /*Auto*/
+ 0x00287000,
+ 0x002A0CC0,
+ 0x0F120001, /*AFC_Default60Hz 01:60hz 00:50Hz*/
+ 0x002A0374,
+ 0x0F12067F, /*REG_TC_DBG_AutoAlgEnBits*/
+ /*===================================================================*/
+ /*Shading*/
+ /*===================================================================*/
+ /* TVAR_ash_pGAS_high*/
+ 0x00287000,
+ 0x002A0AD8,
+ 0x0F120F00,
+ 0x0F120000,
+ 0x0F12000F,
+ 0x0F120F0F,
+ 0x0F120F00,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F12000F,
+ 0x0F120F0F,
+ 0x0F120F00,
+ 0x0F120F00,
+ 0x0F12000F,
+ 0x0F120F0F,
+ 0x0F120000,
+ 0x0F120F0F,
+ 0x0F120000,
+ 0x0F12000F,
+ 0x0F120F00,
+ 0x0F120F00,
+ 0x0F120000,
+ 0x0F120F0F,
+ 0x0F120F0F,
+ 0x0F120F00,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F12000F,
+ 0x0F120F0F,
+ 0x0F120000,
+ 0x0F120F00,
+ 0x0F120000,
+ 0x0F120F00,
+ 0x0F120000,
+ 0x0F120F0F,
+ 0x0F12000F,
+ 0x0F12000F,
+ 0x0F120F00,
+ 0x0F120F00,
+ 0x0F120000,
+ 0x0F120F00,
+ 0x0F120F0F,
+ 0x0F120F00,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F12000F,
+ 0x0F120F00,
+ 0x0F120F00,
+ 0x0F120F00,
+ 0x0F12000F,
+ 0x0F120F00,
+ 0x0F120000,
+ 0x0F120F0F,
+ 0x0F12000F,
+ 0x0F12000F,
+ 0x0F120F00,
+ 0x0F120F00,
+ 0x0F120000,
+ 0x0F120F0F,
+ 0x0F120F0F,
+ 0x0F120F00,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F12000F,
+ 0x0F120F0F,
+ 0x0F120F00,
+ 0x0F120F00,
+ 0x0F120000,
+ 0x0F120F0F,
+ 0x0F120000,
+ 0x0F120F0F,
+ 0x0F12000F,
+ 0x0F12000F,
+ 0x0F120F00,
+ /* TVAR_ash_pGAS_low*/
+ 0x0F128608,
+ 0x0F12E960,
+ 0x0F120243,
+ 0x0F12128B,
+ 0x0F12F073,
+ 0x0F120270,
+ 0x0F12DF47,
+ 0x0F12F226,
+ 0x0F121A31,
+ 0x0F12DFDA,
+ 0x0F121200,
+ 0x0F1205A9,
+ 0x0F120F16,
+ 0x0F120F5E,
+ 0x0F12DF10,
+ 0x0F1225BF,
+ 0x0F12FCF0,
+ 0x0F12DE1B,
+ 0x0F12025B,
+ 0x0F12FA8B,
+ 0x0F12163B,
+ 0x0F12DF44,
+ 0x0F12FB2D,
+ 0x0F1230E6,
+ 0x0F12FE07,
+ 0x0F12F47C,
+ 0x0F1209F2,
+ 0x0F120AED,
+ 0x0F12FA09,
+ 0x0F12E70E,
+ 0x0F120158,
+ 0x0F121110,
+ 0x0F12E28C,
+ 0x0F120DFB,
+ 0x0F12074B,
+ 0x0F12FBE5,
+ 0x0F12961C,
+ 0x0F12E21A,
+ 0x0F120ADF,
+ 0x0F120A67,
+ 0x0F12F8A6,
+ 0x0F12FDC3,
+ 0x0F12D590,
+ 0x0F12FA69,
+ 0x0F1208D5,
+ 0x0F12F635,
+ 0x0F12057E,
+ 0x0F12043B,
+ 0x0F12155C,
+ 0x0F1200C6,
+ 0x0F12F042,
+ 0x0F12176A,
+ 0x0F12F818,
+ 0x0F12F1F3,
+ 0x0F12026F,
+ 0x0F1208F6,
+ 0x0F120CCF,
+ 0x0F12E42D,
+ 0x0F120A92,
+ 0x0F1210EC,
+ 0x0F12005F,
+ 0x0F12F02C,
+ 0x0F120672,
+ 0x0F1209BF,
+ 0x0F12F4B5,
+ 0x0F12FC22,
+ 0x0F12FD50,
+ 0x0F120C26,
+ 0x0F12EED3,
+ 0x0F1207C3,
+ 0x0F12080F,
+ 0x0F12F6CF,
+ 0x0F127A3B,
+ 0x0F12E9DC,
+ 0x0F12088E,
+ 0x0F1201C8,
+ 0x0F12043C,
+ 0x0F12F7E2,
+ 0x0F12E391,
+ 0x0F12F3C4,
+ 0x0F121422,
+ 0x0F12E845,
+ 0x0F120D16,
+ 0x0F1206CA,
+ 0x0F120DEB,
+ 0x0F121324,
+ 0x0F12E814,
+ 0x0F1216B7,
+ 0x0F1202AC,
+ 0x0F12DE4D,
+ 0x0F1201EA,
+ 0x0F12F0C2,
+ 0x0F120E06,
+ 0x0F12EC6D,
+ 0x0F12FDF0,
+ 0x0F122B46,
+ 0x0F120710,
+ 0x0F12F84C,
+ 0x0F120E52,
+ 0x0F120675,
+ 0x0F12F0D7,
+ 0x0F12ED40,
+ 0x0F12F3AD,
+ 0x0F12179A,
+ 0x0F12DE9B,
+ 0x0F1210BA,
+ 0x0F120825,
+ 0x0F12FE0A,
+ 0x0F1288E9,
+ 0x0F12E9E0,
+ 0x0F12043D,
+ 0x0F120A17,
+ 0x0F12FC21,
+ 0x0F12FB58,
+ 0x0F12DCE0,
+ 0x0F12F24C,
+ 0x0F121A19,
+ 0x0F12E011,
+ 0x0F1211A3,
+ 0x0F120649,
+ 0x0F120D04,
+ 0x0F120E15,
+ 0x0F12E112,
+ 0x0F1227BD,
+ 0x0F12F7AA,
+ 0x0F12E06A,
+ 0x0F120A16,
+ 0x0F12FD23,
+ 0x0F121226,
+ 0x0F12DA34,
+ 0x0F1207A4,
+ 0x0F122AD3,
+ 0x0F12FE27,
+ 0x0F12EE64,
+ 0x0F120CAD,
+ 0x0F1211C5,
+ 0x0F12EC55,
+ 0x0F12ED98,
+ 0x0F12F88A,
+ 0x0F121842,
+ 0x0F12E1D5,
+ 0x0F1208FD,
+ 0x0F120FB6,
+ 0x0F12F801,
+ 0x002A0378,
+ 0x0F120001, /*REG_TC_DBG_RelnitCmd*/
+ /*===================================================================*/
+ /*Shading - Alpha*/
+ /*===================================================================*/
+ 0x002A05E8,
+ 0x0F1200E4, /*TVAR_ash_AwbAshCord[0] 2 70000568*/
+ 0x0F1200F0, /*TVAR_ash_AwbAshCord[1] 2 7000056A*/
+ 0x0F120100, /*TVAR_ash_AwbAshCord[2] 2 7000056C*/
+ 0x0F120120, /*TVAR_ash_AwbAshCord[3] 2 7000056E*/
+ 0x0F120150, /*TVAR_ash_AwbAshCord[4] 2 70000570*/
+ 0x0F120180, /*TVAR_ash_AwbAshCord[5] 2 70000572*/
+ 0x0F1201A0, /*TVAR_ash_AwbAshCord[6] 2 70000574*/
+ 0x0F124000, /*TVAR_ash_GASAlpha[0][1] 2 70000580*/
+ 0x0F124000, /*TVAR_ash_GASAlpha[0][2] 2 70000582*/
+ 0x0F124000, /*TVAR_ash_GASAlpha[0][3] 2 70000584*/
+ 0x0F123800, /*TVAR_ash_GASAlpha[1][0] 2 70000586*/
+ 0x0F124000, /*TVAR_ash_GASAlpha[1][1] 2 70000588*/
+ 0x0F124000, /*TVAR_ash_GASAlpha[1][2] 2 7000058A*/
+ 0x0F124000, /*TVAR_ash_GASAlpha[1][3] 2 7000058C*/
+ 0x0F123800, /*TVAR_ash_GASAlpha[2][0] 2 7000058E*/
+ 0x0F124000, /*TVAR_ash_GASAlpha[2][1] 2 70000590*/
+ 0x0F124000, /*TVAR_ash_GASAlpha[2][2] 2 70000592*/
+ 0x0F124000, /*TVAR_ash_GASAlpha[2][3] 2 70000594*/
+ 0x0F123800, /*TVAR_ash_GASAlpha[3][0] 2 70000596*/
+ 0x0F124000, /*TVAR_ash_GASAlpha[3][1] 2 70000598*/
+ 0x0F124000, /*TVAR_ash_GASAlpha[3][2] 2 7000059A*/
+ 0x0F124000, /*TVAR_ash_GASAlpha[3][3] 2 7000059C*/
+ 0x0F123800, /*TVAR_ash_GASAlpha[4][0] 2 7000059E*/
+ 0x0F124000, /*TVAR_ash_GASAlpha[4][1] 2 700005A0*/
+ 0x0F124000, /*TVAR_ash_GASAlpha[4][2] 2 700005A2*/
+ 0x0F124000, /*TVAR_ash_GASAlpha[4][3] 2 700005A4*/
+ 0x0F124000, /*TVAR_ash_GASAlpha[5][0] 2 700005A6*/
+ 0x0F124000, /*TVAR_ash_GASAlpha[5][1] 2 700005A8*/
+ 0x0F124000, /*TVAR_ash_GASAlpha[5][2] 2 700005AA*/
+ 0x0F124000, /*TVAR_ash_GASAlpha[5][3] 2 700005AC*/
+ 0x0F124000, /*TVAR_ash_GASAlpha[6][0] 2 700005AE*/
+ 0x0F124000, /*TVAR_ash_GASAlpha[6][1] 2 700005B0*/
+ 0x0F124000, /*TVAR_ash_GASAlpha[6][2] 2 700005B2*/
+ 0x0F124000, /*TVAR_ash_GASAlpha[6][3] 2 700005B4*/
+ 0x0F124000, /*TVAR_ash_GASOutdoorAlpha[0] 2 700005B6*/
+ 0x0F124000, /*TVAR_ash_GASOutdoorAlpha[1] 2 700005B8*/
+ 0x0F124000, /*TVAR_ash_GASOutdoorAlpha[2] 2 700005BA*/
+ 0x0F124000, /*TVAR_ash_GASOutdoorAlpha[3] 2 700005BC*/
+ /*===================================================================*/
+ /*Gamma*/
+ /*===================================================================*/
+ /* param_start SARR_usGammaLutRGBIndoor*/
+ 0x002A0460,
+ 0x0F120000, /*0000 0000 saRR_usDualGammaLutRGBIndoor[0][0]*/
+ 0x0F120004, /*0008 0002 saRR_usDualGammaLutRGBIndoor[0][1]*/
+ 0x0F12000C, /*0013 0006 saRR_usDualGammaLutRGBIndoor[0][2]*/
+ 0x0F120024, /*002C 0011 saRR_usDualGammaLutRGBIndoor[0][3]*/
+ 0x0F12006E, /*0061 0036 saRR_usDualGammaLutRGBIndoor[0][4]*/
+ 0x0F1200D1, /*00C8 009A saRR_usDualGammaLutRGBIndoor[0][5]*/
+ 0x0F120119, /*0113 00FD saRR_usDualGammaLutRGBIndoor[0][6]*/
+ 0x0F120139, /*0132 0129 saRR_usDualGammaLutRGBIndoor[0][7]*/
+ 0x0F120157, /*014C 014B saRR_usDualGammaLutRGBIndoor[0][8]*/
+ 0x0F12018E, /*0179 0184 saRR_usDualGammaLutRGBIndoor[0][9]*/
+ 0x0F1201C3, /*01A4 01B8 saRR_usDualGammaLutRGBIndoor[0][10]*/
+ 0x0F1201F3, /*01CD 01EA saRR_usDualGammaLutRGBIndoor[0][11]*/
+ 0x0F12021F, /*01F4 0216 saRR_usDualGammaLutRGBIndoor[0][12]*/
+ 0x0F120269, /*0239 025E saRR_usDualGammaLutRGBIndoor[0][13]*/
+ 0x0F1202A6, /*0278 0299 saRR_usDualGammaLutRGBIndoor[0][14]*/
+ 0x0F1202FF, /*02E0 02F9 saRR_usDualGammaLutRGBIndoor[0][15]*/
+ 0x0F120351, /*0333 0341 saRR_usDualGammaLutRGBIndoor[0][16]*/
+ 0x0F120395, /*037B 037F saRR_usDualGammaLutRGBIndoor[0][17]*/
+ 0x0F1203CE, /*03BF 03BF saRR_usDualGammaLutRGBIndoor[0][18]*/
+ 0x0F1203FF, /*03FF 03FF saRR_usDualGammaLutRGBIndoor[0][19]*/
+ 0x0F120000, /*0000 0000 saRR_usDualGammaLutRGBIndoor[1][0]*/
+ 0x0F120004, /*0008 0002 saRR_usDualGammaLutRGBIndoor[1][1]*/
+ 0x0F12000C, /*0013 0006 saRR_usDualGammaLutRGBIndoor[1][2]*/
+ 0x0F120024, /*002C 0011 saRR_usDualGammaLutRGBIndoor[1][3]*/
+ 0x0F12006E, /*0061 0036 saRR_usDualGammaLutRGBIndoor[1][4]*/
+ 0x0F1200D1, /*00C8 009A saRR_usDualGammaLutRGBIndoor[1][5]*/
+ 0x0F120119, /*0113 00FD saRR_usDualGammaLutRGBIndoor[1][6]*/
+ 0x0F120139, /*0132 0129 saRR_usDualGammaLutRGBIndoor[1][7]*/
+ 0x0F120157, /*014C 014B saRR_usDualGammaLutRGBIndoor[1][8]*/
+ 0x0F12018E, /*0179 0184 saRR_usDualGammaLutRGBIndoor[1][9]*/
+ 0x0F1201C3, /*01A4 01B8 saRR_usDualGammaLutRGBIndoor[1][10]*/
+ 0x0F1201F3, /*01CD 01EA saRR_usDualGammaLutRGBIndoor[1][11]*/
+ 0x0F12021F, /*01F4 0216 saRR_usDualGammaLutRGBIndoor[1][12]*/
+ 0x0F120269, /*0239 025E saRR_usDualGammaLutRGBIndoor[1][13]*/
+ 0x0F1202A6, /*0278 0299 saRR_usDualGammaLutRGBIndoor[1][14]*/
+ 0x0F1202FF, /*02E0 02F9 saRR_usDualGammaLutRGBIndoor[1][15]*/
+ 0x0F120351, /*0333 0341 saRR_usDualGammaLutRGBIndoor[1][16]*/
+ 0x0F120395, /*037B 037F saRR_usDualGammaLutRGBIndoor[1][17]*/
+ 0x0F1203CE, /*03BF 03BF saRR_usDualGammaLutRGBIndoor[1][18]*/
+ 0x0F1203FF, /*03FF 03FF saRR_usDualGammaLutRGBIndoor[1][19]*/
+ 0x0F120000, /*0000 0000 saRR_usDualGammaLutRGBIndoor[2][0]*/
+ 0x0F120004, /*0008 0002 saRR_usDualGammaLutRGBIndoor[2][1]*/
+ 0x0F12000C, /*0013 0006 saRR_usDualGammaLutRGBIndoor[2][2]*/
+ 0x0F120024, /*002C 0011 saRR_usDualGammaLutRGBIndoor[2][3]*/
+ 0x0F12006E, /*0061 0036 saRR_usDualGammaLutRGBIndoor[2][4]*/
+ 0x0F1200D1, /*00C8 009A saRR_usDualGammaLutRGBIndoor[2][5]*/
+ 0x0F120119, /*0113 00FD saRR_usDualGammaLutRGBIndoor[2][6]*/
+ 0x0F120139, /*0132 0129 saRR_usDualGammaLutRGBIndoor[2][7]*/
+ 0x0F120157, /*014C 014B saRR_usDualGammaLutRGBIndoor[2][8]*/
+ 0x0F12018E, /*0179 0184 saRR_usDualGammaLutRGBIndoor[2][9]*/
+ 0x0F1201C3, /*01A4 01B8 saRR_usDualGammaLutRGBIndoor[2][10]*/
+ 0x0F1201F3, /*01CD 01EA saRR_usDualGammaLutRGBIndoor[2][11]*/
+ 0x0F12021F, /*01F4 0216 saRR_usDualGammaLutRGBIndoor[2][12]*/
+ 0x0F120269, /*0239 025E saRR_usDualGammaLutRGBIndoor[2][13]*/
+ 0x0F1202A6, /*0278 0299 saRR_usDualGammaLutRGBIndoor[2][14]*/
+ 0x0F1202FF, /*02E0 02F9 saRR_usDualGammaLutRGBIndoor[2][15]*/
+ 0x0F120351, /*0333 0341 saRR_usDualGammaLutRGBIndoor[2][16]*/
+ 0x0F120395, /*037B 037F saRR_usDualGammaLutRGBIndoor[2][17]*/
+ 0x0F1203CE, /*03BF 03BF saRR_usDualGammaLutRGBIndoor[2][18]*/
+ 0x0F1203FF, /*03FF 03FF saRR_usDualGammaLutRGBIndoor[2][19]*/
+ 0x0F120000, /*0000 0000 saRR_usDualGammaLutRGBOutdoor[0][0]*/
+ 0x0F120004, /*0008 0002 saRR_usDualGammaLutRGBOutdoor[0][1]*/
+ 0x0F12000C, /*0013 0006 saRR_usDualGammaLutRGBOutdoor[0][2]*/
+ 0x0F120024, /*002C 0011 saRR_usDualGammaLutRGBOutdoor[0][3]*/
+ 0x0F12006E, /*0061 0036 saRR_usDualGammaLutRGBOutdoor[0][4]*/
+ 0x0F1200D1, /*00C8 009A saRR_usDualGammaLutRGBOutdoor[0][5]*/
+ 0x0F120119, /*0113 00FD saRR_usDualGammaLutRGBOutdoor[0][6]*/
+ 0x0F120139, /*0132 0129 saRR_usDualGammaLutRGBOutdoor[0][7]*/
+ 0x0F120157, /*014C 014B saRR_usDualGammaLutRGBOutdoor[0][8]*/
+ 0x0F12018E, /*0179 0184 saRR_usDualGammaLutRGBOutdoor[0][9]*/
+ 0x0F1201C3, /*01A4 01B8 saRR_usDualGammaLutRGBOutdoor[0][10]*/
+ 0x0F1201F3, /*01CD 01EA saRR_usDualGammaLutRGBOutdoor[0][11]*/
+ 0x0F12021F, /*01F4 0216 saRR_usDualGammaLutRGBOutdoor[0][12]*/
+ 0x0F120269, /*0239 025E saRR_usDualGammaLutRGBOutdoor[0][13]*/
+ 0x0F1202A6, /*0278 0299 saRR_usDualGammaLutRGBOutdoor[0][14]*/
+ 0x0F1202FF, /*02E0 02F9 saRR_usDualGammaLutRGBOutdoor[0][15]*/
+ 0x0F120351, /*0333 0341 saRR_usDualGammaLutRGBOutdoor[0][16]*/
+ 0x0F120395, /*037B 037F saRR_usDualGammaLutRGBOutdoor[0][17]*/
+ 0x0F1203CE, /*03BF 03BF saRR_usDualGammaLutRGBOutdoor[0][18]*/
+ 0x0F1203FF, /*03FF 03FF saRR_usDualGammaLutRGBOutdoor[0][19]*/
+ 0x0F120000, /*0000 0000 saRR_usDualGammaLutRGBOutdoor[1][0]*/
+ 0x0F120004, /*0008 0002 saRR_usDualGammaLutRGBOutdoor[1][1]*/
+ 0x0F12000C, /*0013 0006 saRR_usDualGammaLutRGBOutdoor[1][2]*/
+ 0x0F120024, /*002C 0011 saRR_usDualGammaLutRGBOutdoor[1][3]*/
+ 0x0F12006E, /*0061 0036 saRR_usDualGammaLutRGBOutdoor[1][4]*/
+ 0x0F1200D1, /*00C8 009A saRR_usDualGammaLutRGBOutdoor[1][5]*/
+ 0x0F120119, /*0113 00FD saRR_usDualGammaLutRGBOutdoor[1][6]*/
+ 0x0F120139, /*0132 0129 saRR_usDualGammaLutRGBOutdoor[1][7]*/
+ 0x0F120157, /*014C 014B saRR_usDualGammaLutRGBOutdoor[1][8]*/
+ 0x0F12018E, /*0179 0184 saRR_usDualGammaLutRGBOutdoor[1][9]*/
+ 0x0F1201C3, /*01A4 01B8 saRR_usDualGammaLutRGBOutdoor[1][10]*/
+ 0x0F1201F3, /*01CD 01EA saRR_usDualGammaLutRGBOutdoor[1][11]*/
+ 0x0F12021F, /*01F4 0216 saRR_usDualGammaLutRGBOutdoor[1][12]*/
+ 0x0F120269, /*0239 025E saRR_usDualGammaLutRGBOutdoor[1][13]*/
+ 0x0F1202A6, /*0278 0299 saRR_usDualGammaLutRGBOutdoor[1][14]*/
+ 0x0F1202FF, /*02E0 02F9 saRR_usDualGammaLutRGBOutdoor[1][15]*/
+ 0x0F120351, /*0333 0341 saRR_usDualGammaLutRGBOutdoor[1][16]*/
+ 0x0F120395, /*037B 037F saRR_usDualGammaLutRGBOutdoor[1][17]*/
+ 0x0F1203CE, /*03BF 03BF saRR_usDualGammaLutRGBOutdoor[1][18]*/
+ 0x0F1203FF, /*03FF 03FF saRR_usDualGammaLutRGBOutdoor[1][19]*/
+ 0x0F120000, /*0000 0000 saRR_usDualGammaLutRGBOutdoor[2][0]*/
+ 0x0F120004, /*0008 0002 saRR_usDualGammaLutRGBOutdoor[2][1]*/
+ 0x0F12000C, /*0013 0006 saRR_usDualGammaLutRGBOutdoor[2][2]*/
+ 0x0F120024, /*002C 0011 saRR_usDualGammaLutRGBOutdoor[2][3]*/
+ 0x0F12006E, /*0061 0036 saRR_usDualGammaLutRGBOutdoor[2][4]*/
+ 0x0F1200D1, /*00C8 009A saRR_usDualGammaLutRGBOutdoor[2][5]*/
+ 0x0F120119, /*0113 00FD saRR_usDualGammaLutRGBOutdoor[2][6]*/
+ 0x0F120139, /*0132 0129 saRR_usDualGammaLutRGBOutdoor[2][7]*/
+ 0x0F120157, /*014C 014B saRR_usDualGammaLutRGBOutdoor[2][8]*/
+ 0x0F12018E, /*0179 0184 saRR_usDualGammaLutRGBOutdoor[2][9]*/
+ 0x0F1201C3, /*01A4 01B8 saRR_usDualGammaLutRGBOutdoor[2][10]*/
+ 0x0F1201F3, /*01CD 01EA saRR_usDualGammaLutRGBOutdoor[2][11]*/
+ 0x0F12021F, /*01F4 0216 saRR_usDualGammaLutRGBOutdoor[2][12]*/
+ 0x0F120269, /*0239 025E saRR_usDualGammaLutRGBOutdoor[2][13]*/
+ 0x0F1202A6, /*0278 0299 saRR_usDualGammaLutRGBOutdoor[2][14]*/
+ 0x0F1202FF, /*02E0 02F9 saRR_usDualGammaLutRGBOutdoor[2][15]*/
+ 0x0F120351, /*0333 0341 saRR_usDualGammaLutRGBOutdoor[2][16]*/
+ 0x0F120395, /*037B 037F saRR_usDualGammaLutRGBOutdoor[2][17]*/
+ 0x0F1203CE, /*03BF 03BF saRR_usDualGammaLutRGBOutdoor[2][18]*/
+ 0x0F1203FF, /*03FF 03FF saRR_usDualGammaLutRGBOutdoor[2][19]*/
+ /*===================================================================*/
+ /*AE - shutter*/
+ /*===================================================================*/
+ /*AE_Target*/
+ 0x002A10C0,
+ 0x0F120045, /*TVAR_ae_BrAve*/
+ 0x002A10C6,
+ 0x0F12000F, /*ae_StatMode 2 70001046*/
+ /*AE_state*/
+ 0x002A03B2,
+ 0x0F12010E, /*#lt_uLimitHigh*/
+ 0x0F1200F5, /*#lt_uLimitLow*/
+ /*For 60Hz*/
+ 0x002A03C4,
+ 0x0F123415, /*#lt_uMaxExp1*/
+ 0x002A03C8,
+ 0x0F12681F, /*#lt_uMaxExp2*/
+ 0x002A03CC,
+ 0x0F128227, /*#lt_uMaxExp3*/
+ 0x002A03D0,
+ 0x0F120D40, /*C350 #lt_uMaxExp4*/
+ 0x0F120003, /*0000 #lt_uMaxExp4*/
+ 0x002A03D4,
+ 0x0F123415, /*#lt_uCapMaxExp1*/
+ 0x002A03D8,
+ 0x0F12681F, /*#lt_uCapMaxExp2*/
+ 0x002A03DC,
+ 0x0F128227, /*#lt_uCapMaxExp3*/
+ 0x002A03E0,
+ 0x0F120D40, /*C350 #lt_uCapMaxExp4*/
+ 0x0F120003, /*0000 #lt_uCapMaxExp4*/
+ 0x002A03E4,
+ 0x0F1201C0, /*0230 #lt_uMaxAnGain1*/
+ 0x0F1201D0, /*0260 #lt_uMaxAnGain2*/
+ 0x0F1202D0, /*0380 #lt_uMaxAnGain3*/
+ 0x0F120700, /*#lt_uMaxAnGain4*/
+ 0x0F120100, /*#lt_uMaxDigGain*/
+ 0x0F128000, /*#lt_uMaxTotGain Total-gain is limited by
+ #lt_uMaxTotGain*/
+ 0x0F1201C0, /*#lt_uCapMaxAnGain1*/
+ 0x0F1201D0, /*#lt_uCapMaxAnGain2*/
+ 0x0F1202D0, /*#lt_uCapMaxAnGain3*/
+ 0x0F120700, /*#lt_uCapMaxAnGain4*/
+ 0x0F120100, /*#lt_uCapMaxDigGain*/
+ 0x0F128000, /*#lt_uCapMaxTotGain Total-gain is limited by
+ #lt_uMaxTotGain*/
+ /*===================================================================*/
+ /*AE - Weights*/
+ /*===================================================================*/
+ 0x002A10CE,
+ 0x0F120000, /*ae_WeightTbl_16[0] 2 7000104E*/
+ 0x0F120101, /*ae_WeightTbl_16[1] 2 70001050*/
+ 0x0F120101, /*ae_WeightTbl_16[2] 2 70001052*/
+ 0x0F120000, /*ae_WeightTbl_16[3] 2 70001054*/
+ 0x0F120101, /*ae_WeightTbl_16[4] 2 70001056*/
+ 0x0F120101, /*ae_WeightTbl_16[5] 2 70001058*/
+ 0x0F120101, /*ae_WeightTbl_16[6] 2 7000105A*/
+ 0x0F120101, /*ae_WeightTbl_16[7] 2 7000105C*/
+ 0x0F120201, /*ae_WeightTbl_16[8] 2 7000105E*/
+ 0x0F120303, /*ae_WeightTbl_16[9] 2 70001060*/
+ 0x0F120303, /*ae_WeightTbl_16[10] 2 70001062*/
+ 0x0F120102, /*ae_WeightTbl_16[11] 2 70001064*/
+ 0x0F120201, /*ae_WeightTbl_16[12] 2 70001066*/
+ 0x0F120403, /*ae_WeightTbl_16[13] 2 70001068*/
+ 0x0F120304, /*ae_WeightTbl_16[14] 2 7000106A*/
+ 0x0F120102, /*ae_WeightTbl_16[15] 2 7000106C*/
+ 0x0F120201, /*ae_WeightTbl_16[16] 2 7000106E*/
+ 0x0F120403, /*ae_WeightTbl_16[17] 2 70001070*/
+ 0x0F120304, /*ae_WeightTbl_16[18] 2 70001072*/
+ 0x0F120102, /*ae_WeightTbl_16[19] 2 70001074*/
+ 0x0F120201, /*ae_WeightTbl_16[20] 2 70001076*/
+ 0x0F120403, /*ae_WeightTbl_16[21] 2 70001078*/
+ 0x0F120304, /*ae_WeightTbl_16[22] 2 7000107A*/
+ 0x0F120102, /*ae_WeightTbl_16[23] 2 7000107C*/
+ 0x0F120201, /*ae_WeightTbl_16[24] 2 7000107E*/
+ 0x0F120303, /*ae_WeightTbl_16[25] 2 70001080*/
+ 0x0F120303, /*ae_WeightTbl_16[26] 2 70001082*/
+ 0x0F120102, /*ae_WeightTbl_16[27] 2 70001084*/
+ 0x0F120201, /*ae_WeightTbl_16[28] 2 70001086*/
+ 0x0F120202, /*ae_WeightTbl_16[29] 2 70001088*/
+ 0x0F120202, /*ae_WeightTbl_16[30] 2 7000108A*/
+ 0x0F120102, /*ae_WeightTbl_16[31] 2 7000108C*/
+ /*===================================================================*/
+ /*AWB-BASIC setting*/
+ /*===================================================================*/
+ 0x002A0DCC,
+ 0x0F120138, /*awbb_IntcR*/
+ 0x0F12011C, /*awbb_IntcB*/
+ 0x0F1202A7, /*awbb_GLocusR*/
+ 0x0F120343, /*awbb_GLocusB*/
+ 0x002A0DB4,
+ 0x0F12036C, /*awbb_CrclLowT_R_c*/
+ 0x002A0DB8,
+ 0x0F12011D, /*awbb_CrclLowT_B_c*/
+ 0x002A0DBC,
+ 0x0F1262C1, /*awbb_CrclLowT_Rad_c*/
+ 0x002A0DEC,
+ 0x0F1205F0, /*awbb_GamutWidthThr1*/
+ 0x0F1201F4, /*awbb_GamutHeightThr1*/
+ 0x0F12006C, /*awbb_GamutWidthThr2*/
+ 0x0F120038, /*awbb_GamutHeightThr2*/
+ 0x002A0DD8,
+ 0x0F12000C, /*awbb_MinNumOfFinalPatches*/
+ 0x0F12001E, /*awbb_MinNumOfLowBrFinalPatches*/
+ 0x0F120046, /*awbb_MinNumOfLowBr0_FinalPatches*/
+ 0x002A22BA,
+ 0x0F120006, /* #Mon_AWB_ByPassMode [0]Outdoor [1]LowBr [2]LowTemp*/
+ 0x002A0F7A,
+ 0x0F120000, /*awbb_RGainOff 2 70000EFA*/
+ 0x0F120000, /*awbb_BGainOff 2 70000EFC*/
+ 0x0F120000, /*awbb_GGainOff 2 70000EFE*/
+ 0x0F1200C2, /*awbb_Alpha_Comp_Mode 2 70000F00*/
+ 0x0F120002, /*awbb_Rpl_InvalidOutDoor 2 70000F02*/
+ 0x0F120001, /*awbb_UseGrThrCorr 2 70000F04*/
+ 0x0F1200E4, /*awbb_Use_Filters 2 70000F06*/
+ 0x0F12053C, /*awbb_GainsInit[0] 2 70000F08*/
+ 0x0F120400, /*awbb_GainsInit[1] 2 70000F0A*/
+ 0x0F12055C, /*awbb_GainsInit[2] 2 70000F0C*/
+ 0x0F12001E, /*awbb_WpFilterMinThr 2 70000F0E*/
+ 0x0F120190, /*awbb_WpFilterMaxThr 2 70000F10*/
+ 0x0F1200A0, /*awbb_WpFilterCoef 2 70000F12*/
+ 0x0F120004, /*awbb_WpFilterSize 2 70000F14*/
+ 0x0F120001, /*awbb_otp_disable 2 70000F16*/
+ /*===================================================================*/
+ /*AWB-Zone*/
+ /*===================================================================*/
+ /* param_start awbb_IndoorGrZones_m_BGrid*/
+ 0x002A0CE0,
+ 0x0F1203F8, /*03B5 awbb_IndoorGrZones_m_BGrid[0]*/
+ 0x0F120422, /*03DF awbb_IndoorGrZones_m_BGrid[1]*/
+ 0x0F1203B4, /*032D awbb_IndoorGrZones_m_BGrid[2]*/
+ 0x0F120408, /*03D5 awbb_IndoorGrZones_m_BGrid[3]*/
+ 0x0F120370, /*0303 awbb_IndoorGrZones_m_BGrid[4]*/
+ 0x0F1203EE, /*03BB awbb_IndoorGrZones_m_BGrid[5]*/
+ 0x0F12032C, /*02DB awbb_IndoorGrZones_m_BGrid[6]*/
+ 0x0F1203D4, /*0397 awbb_IndoorGrZones_m_BGrid[7]*/
+ 0x0F120302, /*02B1 awbb_IndoorGrZones_m_BGrid[8]*/
+ 0x0F1203BA, /*036B awbb_IndoorGrZones_m_BGrid[9]*/
+ 0x0F1202DA, /*0289 awbb_IndoorGrZones_m_BGrid[10]*/
+ 0x0F120374, /*0349 awbb_IndoorGrZones_m_BGrid[11]*/
+ 0x0F1202B0, /*026F awbb_IndoorGrZones_m_BGrid[12]*/
+ 0x0F120328, /*0329 awbb_IndoorGrZones_m_BGrid[13]*/
+ 0x0F120288, /*0257 awbb_IndoorGrZones_m_BGrid[14]*/
+ 0x0F120300, /*0309 awbb_IndoorGrZones_m_BGrid[15]*/
+ 0x0F120270, /*0241 awbb_IndoorGrZones_m_BGrid[16]*/
+ 0x0F1202DE, /*02DD awbb_IndoorGrZones_m_BGrid[17]*/
+ 0x0F120258, /*0227 awbb_IndoorGrZones_m_BGrid[18]*/
+ 0x0F1202BE, /*02C3 awbb_IndoorGrZones_m_BGrid[19]*/
+ 0x0F120240, /*0213 awbb_IndoorGrZones_m_BGrid[20]*/
+ 0x0F1202A0, /*02AF awbb_IndoorGrZones_m_BGrid[21]*/
+ 0x0F120228, /*0209 awbb_IndoorGrZones_m_BGrid[22]*/
+ 0x0F120296, /*0295 awbb_IndoorGrZones_m_BGrid[23]*/
+ 0x0F120212, /*020D awbb_IndoorGrZones_m_BGrid[24]*/
+ 0x0F120284, /*0285 awbb_IndoorGrZones_m_BGrid[25]*/
+ 0x0F120208, /*0223 awbb_IndoorGrZones_m_BGrid[26]*/
+ 0x0F120274, /*0261 awbb_IndoorGrZones_m_BGrid[27]*/
+ 0x0F12020C, /*0000 awbb_IndoorGrZones_m_BGrid[28]*/
+ 0x0F12026E, /*0000 awbb_IndoorGrZones_m_BGrid[29]*/
+ 0x0F120222, /*0000 awbb_IndoorGrZones_m_BGrid[30]*/
+ 0x0F120260, /*0000 awbb_IndoorGrZones_m_BGrid[31]*/
+ 0x0F120000, /*0000 awbb_IndoorGrZones_m_BGrid[32]*/
+ 0x0F120000, /*0000 awbb_IndoorGrZones_m_BGrid[33]*/
+ 0x0F120000, /*0000 awbb_IndoorGrZones_m_BGrid[34]*/
+ 0x0F120000, /*0000 awbb_IndoorGrZones_m_BGrid[35]*/
+ 0x0F120000, /*0000 awbb_IndoorGrZones_m_BGrid[36]*/
+ 0x0F120000, /*0000 awbb_IndoorGrZones_m_BGrid[37]*/
+ 0x0F120000, /*0000 awbb_IndoorGrZones_m_BGrid[38]*/
+ 0x0F120000, /*0000 awbb_IndoorGrZones_m_BGrid[39]*/
+ /* param_end awbb_IndoorGrZones_m_BGrid*/
+ 0x0F120005, /*awbb_IndoorGrZones_m_Grid*/
+ 0x002A0D38,
+ 0x0F1200FE, /*awbb_IndoorGrZones_m_Boff*/
+ /* param_start awbb_OutdoorGrZones_m_BGrid*/
+ 0x002A0D3C,
+ 0x0F1202B8, /*029F awbb_OutdoorGrZones_m_BGrid[0]*/
+ 0x0F1202F2, /*02CE awbb_OutdoorGrZones_m_BGrid[1]*/
+ 0x0F12028E, /*0282 awbb_OutdoorGrZones_m_BGrid[2]*/
+ 0x0F12030A, /*02DA awbb_OutdoorGrZones_m_BGrid[3]*/
+ 0x0F12027A, /*026D awbb_OutdoorGrZones_m_BGrid[4]*/
+ 0x0F12030A, /*02C2 awbb_OutdoorGrZones_m_BGrid[5]*/
+ 0x0F120274, /*0256 awbb_OutdoorGrZones_m_BGrid[6]*/
+ 0x0F1202FE, /*02A6 awbb_OutdoorGrZones_m_BGrid[7]*/
+ 0x0F120282, /*026E awbb_OutdoorGrZones_m_BGrid[8]*/
+ 0x0F1202DC, /*028A awbb_OutdoorGrZones_m_BGrid[9]*/
+ 0x0F120000, /*0000 awbb_OutdoorGrZones_m_BGrid[10]*/
+ 0x0F120000, /*0000 awbb_OutdoorGrZones_m_BGrid[11]*/
+ 0x0F120000, /*0000 awbb_OutdoorGrZones_m_BGrid[12]*/
+ 0x0F120000, /*0000 awbb_OutdoorGrZones_m_BGrid[13]*/
+ 0x0F120000, /*0000 awbb_OutdoorGrZones_m_BGrid[14]*/
+ 0x0F120000, /*0000 awbb_OutdoorGrZones_m_BGrid[15]*/
+ 0x0F120000, /*0000 awbb_OutdoorGrZones_m_BGrid[16]*/
+ 0x0F120000, /*0000 awbb_OutdoorGrZones_m_BGrid[17]*/
+ 0x0F120000, /*0000 awbb_OutdoorGrZones_m_BGrid[18]*/
+ 0x0F120000, /*0000 awbb_OutdoorGrZones_m_BGrid[19]*/
+ 0x0F120000, /*0000 awbb_OutdoorGrZones_m_BGrid[20]*/
+ 0x0F120000, /*0000 awbb_OutdoorGrZones_m_BGrid[21]*/
+ 0x0F120000, /*0000 awbb_OutdoorGrZones_m_BGrid[22]*/
+ 0x0F120000, /*0000 awbb_OutdoorGrZones_m_BGrid[23]*/
+ /* param_end awbb_OutdoorGrZones_m_BGrid*/
+ 0x0F120005, /*awbb_OutdoorGrZones_m_Gri*/
+ 0x002A0D70,
+ 0x0F120005, /*awbb_OutdoorGrZones_ZInfo_m_GridSz*/
+ 0x002A0D74,
+ 0x0F1201EB, /*awbb_OutdoorGrZones_m_Bof*/
+ /* param_start awbb_LowBrGrZones_m_BGrid*/
+ 0x002A0D78,
+ 0x0F1203CE, /*awbb_LowBrGrZones_m_BGrid[0]*/
+ 0x0F12046E, /*awbb_LowBrGrZones_m_BGrid[1]*/
+ 0x0F12034E, /*awbb_LowBrGrZones_m_BGrid[2]*/
+ 0x0F120474, /*awbb_LowBrGrZones_m_BGrid[3]*/
+ 0x0F1202EA, /*awbb_LowBrGrZones_m_BGrid[4]*/
+ 0x0F120434, /*awbb_LowBrGrZones_m_BGrid[5]*/
+ 0x0F12028C, /*awbb_LowBrGrZones_m_BGrid[6]*/
+ 0x0F1203F0, /*awbb_LowBrGrZones_m_BGrid[7]*/
+ 0x0F120244, /*awbb_LowBrGrZones_m_BGrid[8]*/
+ 0x0F120380, /*awbb_LowBrGrZones_m_BGrid[9]*/
+ 0x0F12020E, /*awbb_LowBrGrZones_m_BGrid[10]*/
+ 0x0F120330, /*awbb_LowBrGrZones_m_BGrid[11]*/
+ 0x0F1201EC, /*awbb_LowBrGrZones_m_BGrid[12]*/
+ 0x0F1202EC, /*awbb_LowBrGrZones_m_BGrid[13]*/
+ 0x0F1201D0, /*awbb_LowBrGrZones_m_BGrid[14]*/
+ 0x0F1202BC, /*awbb_LowBrGrZones_m_BGrid[15]*/
+ 0x0F1201C8, /*awbb_LowBrGrZones_m_BGrid[16]*/
+ 0x0F120296, /*awbb_LowBrGrZones_m_BGrid[17]*/
+ 0x0F1201D2, /*awbb_LowBrGrZones_m_BGrid[18]*/
+ 0x0F120266, /*awbb_LowBrGrZones_m_BGrid[19]*/
+ 0x0F120000, /*awbb_LowBrGrZones_m_BGrid[20]*/
+ 0x0F120000, /*awbb_LowBrGrZones_m_BGrid[21]*/
+ 0x0F120000, /*awbb_LowBrGrZones_m_BGrid[22]*/
+ 0x0F120000, /*awbb_LowBrGrZones_m_BGrid[23]*/
+ /* param_end awbb_LowBrGrZones_m_BGrid*/
+ 0x0F120006, /*awbb_LowBrGrZones_m_GridS*/
+ 0x002A0DB0,
+ 0x0F1200E2, /*awbb_LowBrGrZones_m_Boffs*/
+ /*===================================================================*/
+ /*AWB Scene Detection*/
+ /*===================================================================*/
+ 0x002A0E50,
+ 0x0F12FE82, /*awbb_SCDetectionMap_SEC_StartR_B 2 70000DD0*/
+ 0x0F12001E, /*awbb_SCDetectionMap_SEC_StepR_B 2 70000DD2*/
+ 0x0F120E74, /*awbb_SCDetectionMap_SEC_SunnyNB 2 70000DD4*/
+ 0x0F120122, /*awbb_SCDetectionMap_SEC_StepNB 2 70000DD6*/
+ 0x0F1200E4, /*awbb_SCDetectionMap_SEC_LowTempR_B 2 70000DD8*/
+ 0x0F120096, /*awbb_SCDetectionMap_SEC_SunnyNBZone 2 70000DDA*/
+ 0x0F12000E, /*awbb_SCDetectionMap_SEC_LowTempR_BZone 2 70000DDC*/
+ 0x002A0E14,
+ 0x0F120000, /*#awbb_SCDetectionMap_SEC 0000
+ WRITE 70000D94
+ 0000 awbb_SCDetectionMap_SEC_SceneDetectionMap*/
+ 0x0F120000, /*#awbb_SCDetectionMap_SEC_SceneDetectionMap_0__2_
+ WRITE 70000D96 0000*/
+ 0x0F120000, /*#awbb_SCDetectionMap_SEC_SceneDetectionMap_0__4_
+ WRITE 70000D98 0000*/
+ 0x0F120000, /*#awbb_SCDetectionMap_SEC_SceneDetectionMap_1__1_
+ WRITE 70000D9A 0000*/
+ 0x0F120000, /*#awbb_SCDetectionMap_SEC_SceneDetectionMap_1__3_
+ WRITE 70000D9C 0000*/
+ 0x0F120000, /*#awbb_SCDetectionMap_SEC_SceneDetectionMap_2__0_
+ WRITE 70000D9E 0000*/
+ 0x0F120000, /*#awbb_SCDetectionMap_SEC_SceneDetectionMap_2__2_
+ WRITE 70000DA0 0000*/
+ 0x0F120000, /*#awbb_SCDetectionMap_SEC_SceneDetectionMap_2__4_
+ WRITE 70000DA2 0000*/
+ 0x0F120000, /*#awbb_SCDetectionMap_SEC_SceneDetectionMap_3__1_
+ WRITE 70000DA4 0000*/
+ 0x0F120000, /*#awbb_SCDetectionMap_SEC_SceneDetectionMap_3__3_
+ WRITE 70000DA6 0000*/
+ 0x0F120000, /*#awbb_SCDetectionMap_SEC_SceneDetectionMap_4__0_
+ WRITE 70000DA8 0000*/
+ 0x0F120000, /*#awbb_SCDetectionMap_SEC_SceneDetectionMap_4__2_
+ WRITE 70000DAA 0000*/
+ 0x0F120500, /*#awbb_SCDetectionMap_SEC_SceneDetectionMap_4__4_
+ WRITE 70000DAC 0500*/
+ 0x0F125555, /*#awbb_SCDetectionMap_SEC_SceneDetectionMap_5__1_
+ WRITE 70000DAE 5555*/
+ 0x0F125455, /*#awbb_SCDetectionMap_SEC_SceneDetectionMap_5__3_
+ WRITE 70000DB0 5455*/
+ 0x0F12AA55, /*#awbb_SCDetectionMap_SEC_SceneDetectionMap_6__0_
+ WRITE 70000DB2 AA55*/
+ 0x0F12AAAA, /*#awbb_SCDetectionMap_SEC_SceneDetectionMap_6__2_
+ WRITE 70000DB4 AAAA*/
+ 0x0F12BF54, /*#awbb_SCDetectionMap_SEC_SceneDetectionMap_6__4_
+ WRITE 70000DB6 BF54*/
+ 0x0F12FFFF, /*#awbb_SCDetectionMap_SEC_SceneDetectionMap_7__1_
+ WRITE 70000DB8 FFFF*/
+ 0x0F1254FE, /*#awbb_SCDetectionMap_SEC_SceneDetectionMap_7__3_
+ WRITE 70000DBA 54FE*/
+ 0x0F12FF6F, /*#awbb_SCDetectionMap_SEC_SceneDetectionMap_8__0_
+ WRITE 70000DBC FF6F*/
+ 0x0F12FEFF, /*#awbb_SCDetectionMap_SEC_SceneDetectionMap_8__2_
+ WRITE 70000DBE FEFF*/
+ 0x0F121B54, /*#awbb_SCDetectionMap_SEC_SceneDetectionMap_8__4_
+ WRITE 70000DC0 1B54*/
+ 0x0F12FFFF, /*#awbb_SCDetectionMap_SEC_SceneDetectionMap_9__1_
+ WRITE 70000DC2 FFFF*/
+ 0x0F1254FE, /*#awbb_SCDetectionMap_SEC_SceneDetectionMap_9__3_
+ WRITE 70000DC4 54FE*/
+ 0x0F12FF06, /*#awbb_SCDetectionMap_SEC_SceneDetectionMap_10__0_
+ WRITE 70000DC6 FF06*/
+ 0x0F12FEFF, /*#awbb_SCDetectionMap_SEC_SceneDetectionMap_10__2_
+ WRITE 70000DC8 FEFF*/
+ 0x0F120154, /*#awbb_SCDetectionMap_SEC_SceneDetectionMap_10__4_
+ WRITE 70000DCA 0154*/
+ 0x0F12BFBF, /*#awbb_SCDetectionMap_SEC_SceneDetectionMap_11__1_
+ WRITE 70000DCC BFBF*/
+ 0x0F1254BE, /*#awbb_SCDetectionMap_SEC_SceneDetectionMap_11__3_
+ WRITE 70000DCE 54BE*/
+ 0x002A0F86,
+ 0x0F120074, /*E0 awbb_Use_Filters e4*/
+ 0x002A0F8E,
+ 0x0F12001E, /*awbb_WpFilterMinThr 1e*/
+ /*===================================================================*/
+ /*AWB - GridCorrection*/
+ /*===================================================================*/
+ 0x002A0F98,
+ 0x0F120002, /*awbb_GridEnable 2 70000F18*/
+ 0x002A0F60,
+ 0x0F1202E2, /*awbb_GridConst_1[0] 2 70000EE0*/
+ 0x0F12034B, /*awbb_GridConst_1[1] 2 70000EE2*/
+ 0x0F120399, /*awbb_GridConst_1[2] 2 70000EE4*/
+ 0x0F12102D, /*awbb_GridConst_2[0] 2 70000EE6*/
+ 0x0F1210DE, /*awbb_GridConst_2[1] 2 70000EE8*/
+ 0x0F12116E, /*awbb_GridConst_2[2] 2 70000EEA*/
+ 0x0F12117B, /*awbb_GridConst_2[3] 2 70000EEC*/
+ 0x0F121206, /*awbb_GridConst_2[4] 2 70000EEE*/
+ 0x0F12127F, /*awbb_GridConst_2[5] 2 70000EF0*/
+ 0x0F1202C4, /*awbb_GridCoeff_R_1 2 70000EF2*/
+ 0x0F1202E4, /*awbb_GridCoeff_B_1 2 70000EF4*/
+ 0x0F1200C3, /*awbb_GridCoeff_R_2 2 70000EF6*/
+ 0x0F1200A6, /*awbb_GridCoeff_B_2 2 70000EF8*/
+ 0x002A0ED0,
+ 0x0F12000A, /*awbb_GridCorr_R[0][0] 2 70000ED0*/
+ 0x0F120028, /*awbb_GridCorr_R[0][1] 2 70000ED2*/
+ 0x0F120028, /*awbb_GridCorr_R[0][2] 2 70000ED4*/
+ 0x0F12FFEC, /*awbb_GridCorr_R[0][3] 2 70000ED6*/
+ 0x0F12FFEC, /*awbb_GridCorr_R[0][4] 2 70000ED8*/
+ 0x0F12001E, /*awbb_GridCorr_R[0][5] 2 70000EDA*/
+ 0x0F12000A, /*awbb_GridCorr_R[1][0] 2 70000EDC*/
+ 0x0F120028, /*awbb_GridCorr_R[1][1] 2 70000EDE*/
+ 0x0F120028, /*awbb_GridCorr_R[1][2] 2 70000EE0*/
+ 0x0F12FFEC, /*awbb_GridCorr_R[1][3] 2 70000EE2*/
+ 0x0F12FFEC, /*awbb_GridCorr_R[1][4] 2 70000EE4*/
+ 0x0F12001E, /*awbb_GridCorr_R[1][5] 2 70000EE6*/
+ 0x0F12000A, /*awbb_GridCorr_R[2][0] 2 70000EE8*/
+ 0x0F120028, /*awbb_GridCorr_R[2][1] 2 70000EEA*/
+ 0x0F120028, /*awbb_GridCorr_R[2][2] 2 70000EEC*/
+ 0x0F12FFEC, /*awbb_GridCorr_R[2][3] 2 70000EEE*/
+ 0x0F12FFEC, /*awbb_GridCorr_R[2][4] 2 70000EF0*/
+ 0x0F12001E, /*awbb_GridCorr_R[2][5] 2 70000EF2*/
+ 0x0F12FFD8, /*awbb_GridCorr_B[0][0] 2 70000EF4*/
+ 0x0F12003C, /*awbb_GridCorr_B[0][1] 2 70000EF6*/
+ 0x0F12003C, /*awbb_GridCorr_B[0][2] 2 70000EF8*/
+ 0x0F120000, /*awbb_GridCorr_B[0][3] 2 70000EFA*/
+ 0x0F120000, /*awbb_GridCorr_B[0][4] 2 70000EFC*/
+ 0x0F12001E, /*awbb_GridCorr_B[0][5] 2 70000EFE*/
+ 0x0F12FFD8, /*awbb_GridCorr_B[1][0] 2 70000F00*/
+ 0x0F12003C, /*awbb_GridCorr_B[1][1] 2 70000F02*/
+ 0x0F12003C, /*awbb_GridCorr_B[1][2] 2 70000F04*/
+ 0x0F120000, /*awbb_GridCorr_B[1][3] 2 70000F06*/
+ 0x0F120000, /*awbb_GridCorr_B[1][4] 2 70000F08*/
+ 0x0F12001E, /*awbb_GridCorr_B[1][5] 2 70000F0A*/
+ 0x0F12FFD8, /*awbb_GridCorr_B[2][0] 2 70000F0C*/
+ 0x0F12003C, /*awbb_GridCorr_B[2][1] 2 70000F0E*/
+ 0x0F12003C, /*awbb_GridCorr_B[2][2] 2 70000F10*/
+ 0x0F120000, /*awbb_GridCorr_B[2][3] 2 70000F12*/
+ 0x0F120000, /*awbb_GridCorr_B[2][4] 2 70000F14*/
+ 0x0F12001E, /*awbb_GridCorr_B[2][5] 2 70000F16*/
+ 0x0F120000, /*awbb_GridCorr_R_Out[0][0] 2 70000F18*/
+ 0x0F12FFE0, /*awbb_GridCorr_R_Out[0][1] 2 70000F1A*/
+ 0x0F120000, /*awbb_GridCorr_R_Out[0][2] 2 70000F1C*/
+ 0x0F120000, /*awbb_GridCorr_R_Out[0][3] 2 70000F1E*/
+ 0x0F120000, /*awbb_GridCorr_R_Out[0][4] 2 70000F20*/
+ 0x0F120000, /*awbb_GridCorr_R_Out[0][5] 2 70000F22*/
+ 0x0F120000, /*awbb_GridCorr_R_Out[1][0] 2 70000F24*/
+ 0x0F12FFE0, /*awbb_GridCorr_R_Out[1][1] 2 70000F26*/
+ 0x0F120000, /*awbb_GridCorr_R_Out[1][2] 2 70000F28*/
+ 0x0F120000, /*awbb_GridCorr_R_Out[1][3] 2 70000F2A*/
+ 0x0F120000, /*awbb_GridCorr_R_Out[1][4] 2 70000F2C*/
+ 0x0F120000, /*awbb_GridCorr_R_Out[1][5] 2 70000F2E*/
+ 0x0F120000, /*awbb_GridCorr_R_Out[2][0] 2 70000F30*/
+ 0x0F12FFE0, /*awbb_GridCorr_R_Out[2][1] 2 70000F32*/
+ 0x0F120000, /*awbb_GridCorr_R_Out[2][2] 2 70000F34*/
+ 0x0F120000, /*awbb_GridCorr_R_Out[2][3] 2 70000F36*/
+ 0x0F120000, /*awbb_GridCorr_R_Out[2][4] 2 70000F38*/
+ 0x0F120000, /*awbb_GridCorr_R_Out[2][5] 2 70000F3A*/
+ 0x0F120000, /*awbb_GridCorr_B_Out[0][0] 2 70000F3C*/
+ 0x0F12FFDE, /*awbb_GridCorr_B_Out[0][1] 2 70000F3E*/
+ 0x0F120000, /*awbb_GridCorr_B_Out[0][2] 2 70000F40*/
+ 0x0F120000, /*awbb_GridCorr_B_Out[0][3] 2 70000F42*/
+ 0x0F120000, /*awbb_GridCorr_B_Out[0][4] 2 70000F44*/
+ 0x0F120000, /*awbb_GridCorr_B_Out[0][5] 2 70000F46*/
+ 0x0F120000, /*awbb_GridCorr_B_Out[1][0] 2 70000F48*/
+ 0x0F12FFDE, /*awbb_GridCorr_B_Out[1][1] 2 70000F4A*/
+ 0x0F120000, /*awbb_GridCorr_B_Out[1][2] 2 70000F4C*/
+ 0x0F120000, /*awbb_GridCorr_B_Out[1][3] 2 70000F4E*/
+ 0x0F120000, /*awbb_GridCorr_B_Out[1][4] 2 70000F50*/
+ 0x0F120000, /*awbb_GridCorr_B_Out[1][5] 2 70000F52*/
+ 0x0F120000, /*awbb_GridCorr_B_Out[2][0] 2 70000F54*/
+ 0x0F12FFDE, /*awbb_GridCorr_B_Out[2][1] 2 70000F56*/
+ 0x0F120000, /*awbb_GridCorr_B_Out[2][2] 2 70000F58*/
+ 0x0F120000, /*awbb_GridCorr_B_Out[2][3] 2 70000F5A*/
+ 0x0F120000, /*awbb_GridCorr_B_Out[2][4] 2 70000F5C*/
+ 0x0F120000, /*awbb_GridCorr_B_Out[2][5] 2 70000F5E*/
+ /*===================================================================*/
+ /*CCM*/
+ /*===================================================================*/
+ 0x002A05D2,
+ 0x0F1200E4, /*#SARR_AwbCcmCord 2 70000552*/
+ 0x0F1200F0, /*#SARR_AwbCcmCord_1_ 2 70000554*/
+ 0x0F120100, /*#SARR_AwbCcmCord_2_ 2 70000556*/
+ 0x0F120120, /*#SARR_AwbCcmCord_3_ 2 70000558*/
+ 0x0F120150, /*#SARR_AwbCcmCord_4_ 2 7000055A*/
+ 0x0F120180, /*#SARR_AwbCcmCord_5_ 2 7000055C*/
+ /* param_start TVAR_wbt_pBaseCcms*/
+ 0x002A05C4,
+ 0x0F123800,
+ 0x0F127000,
+ 0x002A3800,
+ 0x0F1201D0, /*TVAR_wbt_pBaseCcms[0]*/
+ 0x0F12FFA1, /*TVAR_wbt_pBaseCcms[1]*/
+ 0x0F12FFFA, /*TVAR_wbt_pBaseCcms[2]*/
+ 0x0F12FF6F, /*TVAR_wbt_pBaseCcms[3]*/
+ 0x0F120140, /*TVAR_wbt_pBaseCcms[4]*/
+ 0x0F12FF49, /*TVAR_wbt_pBaseCcms[5]*/
+ 0x0F12FFC1, /*TVAR_wbt_pBaseCcms[6]*/
+ 0x0F12001F, /*TVAR_wbt_pBaseCcms[7]*/
+ 0x0F1201BD, /*TVAR_wbt_pBaseCcms[8]*/
+ 0x0F12013F, /*TVAR_wbt_pBaseCcms[9]*/
+ 0x0F1200E1, /*TVAR_wbt_pBaseCcms[10]*/
+ 0x0F12FF43, /*TVAR_wbt_pBaseCcms[11]*/
+ 0x0F120191, /*TVAR_wbt_pBaseCcms[12]*/
+ 0x0F12FFC0, /*TVAR_wbt_pBaseCcms[13]*/
+ 0x0F1201B7, /*TVAR_wbt_pBaseCcms[14]*/
+ 0x0F12FF30, /*TVAR_wbt_pBaseCcms[15]*/
+ 0x0F12015F, /*TVAR_wbt_pBaseCcms[16]*/
+ 0x0F120106, /*TVAR_wbt_pBaseCcms[17]*/
+ 0x0F1201D0, /*TVAR_wbt_pBaseCcms[18]*/
+ 0x0F12FFA1, /*TVAR_wbt_pBaseCcms[19]*/
+ 0x0F12FFFA, /*TVAR_wbt_pBaseCcms[20]*/
+ 0x0F12FF6F, /*TVAR_wbt_pBaseCcms[21]*/
+ 0x0F120140, /*TVAR_wbt_pBaseCcms[22]*/
+ 0x0F12FF49, /*TVAR_wbt_pBaseCcms[23]*/
+ 0x0F12FFC1, /*TVAR_wbt_pBaseCcms[24]*/
+ 0x0F12001F, /*TVAR_wbt_pBaseCcms[25]*/
+ 0x0F1201BD, /*TVAR_wbt_pBaseCcms[26]*/
+ 0x0F12013F, /*TVAR_wbt_pBaseCcms[27]*/
+ 0x0F1200E1, /*TVAR_wbt_pBaseCcms[28]*/
+ 0x0F12FF43, /*TVAR_wbt_pBaseCcms[29]*/
+ 0x0F120191, /*TVAR_wbt_pBaseCcms[30]*/
+ 0x0F12FFC0, /*TVAR_wbt_pBaseCcms[31]*/
+ 0x0F1201B7, /*TVAR_wbt_pBaseCcms[32]*/
+ 0x0F12FF30, /*TVAR_wbt_pBaseCcms[33]*/
+ 0x0F12015F, /*TVAR_wbt_pBaseCcms[34]*/
+ 0x0F120106, /*TVAR_wbt_pBaseCcms[35]*/
+ 0x0F1201D0, /*TVAR_wbt_pBaseCcms[36]*/
+ 0x0F12FFA1, /*TVAR_wbt_pBaseCcms[37]*/
+ 0x0F12FFFA, /*TVAR_wbt_pBaseCcms[38]*/
+ 0x0F12FF6F, /*TVAR_wbt_pBaseCcms[39]*/
+ 0x0F120140, /*TVAR_wbt_pBaseCcms[40]*/
+ 0x0F12FF49, /*TVAR_wbt_pBaseCcms[41]*/
+ 0x0F12FFC1, /*TVAR_wbt_pBaseCcms[42]*/
+ 0x0F12001F, /*TVAR_wbt_pBaseCcms[43]*/
+ 0x0F1201BD, /*TVAR_wbt_pBaseCcms[44]*/
+ 0x0F12013F, /*TVAR_wbt_pBaseCcms[45]*/
+ 0x0F1200E1, /*TVAR_wbt_pBaseCcms[46]*/
+ 0x0F12FF43, /*TVAR_wbt_pBaseCcms[47]*/
+ 0x0F120191, /*TVAR_wbt_pBaseCcms[48]*/
+ 0x0F12FFC0, /*TVAR_wbt_pBaseCcms[49]*/
+ 0x0F1201B7, /*TVAR_wbt_pBaseCcms[50]*/
+ 0x0F12FF30, /*TVAR_wbt_pBaseCcms[51]*/
+ 0x0F12015F, /*TVAR_wbt_pBaseCcms[52]*/
+ 0x0F120106, /*TVAR_wbt_pBaseCcms[53]*/
+ 0x0F1201D0, /*TVAR_wbt_pBaseCcms[54]*/
+ 0x0F12FFA1, /*TVAR_wbt_pBaseCcms[55]*/
+ 0x0F12FFFA, /*TVAR_wbt_pBaseCcms[56]*/
+ 0x0F12FF6F, /*TVAR_wbt_pBaseCcms[57]*/
+ 0x0F120140, /*TVAR_wbt_pBaseCcms[58]*/
+ 0x0F12FF49, /*TVAR_wbt_pBaseCcms[59]*/
+ 0x0F12FFC1, /*TVAR_wbt_pBaseCcms[60]*/
+ 0x0F12001F, /*TVAR_wbt_pBaseCcms[61]*/
+ 0x0F1201BD, /*TVAR_wbt_pBaseCcms[62]*/
+ 0x0F12013F, /*TVAR_wbt_pBaseCcms[63]*/
+ 0x0F1200E1, /*TVAR_wbt_pBaseCcms[64]*/
+ 0x0F12FF43, /*TVAR_wbt_pBaseCcms[65]*/
+ 0x0F120191, /*TVAR_wbt_pBaseCcms[66]*/
+ 0x0F12FFC0, /*TVAR_wbt_pBaseCcms[67]*/
+ 0x0F1201B7, /*TVAR_wbt_pBaseCcms[68]*/
+ 0x0F12FF30, /*TVAR_wbt_pBaseCcms[69]*/
+ 0x0F12015F, /*TVAR_wbt_pBaseCcms[70]*/
+ 0x0F120106, /*TVAR_wbt_pBaseCcms[71]*/
+ 0x0F1201BF, /*TVAR_wbt_pBaseCcms[72]*/
+ 0x0F12FFBF, /*TVAR_wbt_pBaseCcms[73]*/
+ 0x0F12FFFE, /*TVAR_wbt_pBaseCcms[74]*/
+ 0x0F12FF6D, /*TVAR_wbt_pBaseCcms[75]*/
+ 0x0F1201B4, /*TVAR_wbt_pBaseCcms[76]*/
+ 0x0F12FF66, /*TVAR_wbt_pBaseCcms[77]*/
+ 0x0F12FFCA, /*TVAR_wbt_pBaseCcms[78]*/
+ 0x0F12FFCE, /*TVAR_wbt_pBaseCcms[79]*/
+ 0x0F12017B, /*TVAR_wbt_pBaseCcms[80]*/
+ 0x0F120136, /*TVAR_wbt_pBaseCcms[81]*/
+ 0x0F120132, /*TVAR_wbt_pBaseCcms[82]*/
+ 0x0F12FF85, /*TVAR_wbt_pBaseCcms[83]*/
+ 0x0F12018B, /*TVAR_wbt_pBaseCcms[84]*/
+ 0x0F12FF73, /*TVAR_wbt_pBaseCcms[85]*/
+ 0x0F120191, /*TVAR_wbt_pBaseCcms[86]*/
+ 0x0F12FF3F, /*TVAR_wbt_pBaseCcms[87]*/
+ 0x0F12015B, /*TVAR_wbt_pBaseCcms[88]*/
+ 0x0F1200D0, /*TVAR_wbt_pBaseCcms[89]*/
+ 0x0F1201BF, /*TVAR_wbt_pBaseCcms[90]*/
+ 0x0F12FFBF, /*TVAR_wbt_pBaseCcms[91]*/
+ 0x0F12FFFE, /*TVAR_wbt_pBaseCcms[92]*/
+ 0x0F12FF6D, /*TVAR_wbt_pBaseCcms[93]*/
+ 0x0F1201B4, /*TVAR_wbt_pBaseCcms[94]*/
+ 0x0F12FF66, /*TVAR_wbt_pBaseCcms[95]*/
+ 0x0F12FFCA, /*TVAR_wbt_pBaseCcms[96]*/
+ 0x0F12FFCE, /*TVAR_wbt_pBaseCcms[97]*/
+ 0x0F12017B, /*TVAR_wbt_pBaseCcms[98]*/
+ 0x0F120136, /*TVAR_wbt_pBaseCcms[99]*/
+ 0x0F120132, /*TVAR_wbt_pBaseCcms[100]*/
+ 0x0F12FF85, /*TVAR_wbt_pBaseCcms[101]*/
+ 0x0F12018B, /*TVAR_wbt_pBaseCcms[102]*/
+ 0x0F12FF73, /*TVAR_wbt_pBaseCcms[103]*/
+ 0x0F120191, /*TVAR_wbt_pBaseCcms[104]*/
+ 0x0F12FF3F, /*TVAR_wbt_pBaseCcms[105]*/
+ 0x0F12015B, /*TVAR_wbt_pBaseCcms[106]*/
+ 0x0F1200D0, /*TVAR_wbt_pBaseCcms[107]*/
+ /* param_end TVAR_wbt_pBaseCcms*/
+ /* param_start TVAR_wbt_pOutdoorCcm*/
+ 0x002A05CC,
+ 0x0F1238D8, /*#TVAR_wbt_pOutdoorCcm*/
+ 0x0F127000,
+ 0x002A38D8,
+ 0x0F120235, /*TVAR_wbt_pOutdoorCcm[0]*/
+ 0x0F12FFEF, /*TVAR_wbt_pOutdoorCcm[1]*/
+ 0x0F120014, /*TVAR_wbt_pOutdoorCcm[2]*/
+ 0x0F12FF67, /*TVAR_wbt_pOutdoorCcm[3]*/
+ 0x0F12027D, /*TVAR_wbt_pOutdoorCcm[4]*/
+ 0x0F12FFBA, /*TVAR_wbt_pOutdoorCcm[5]*/
+ 0x0F12000D, /*TVAR_wbt_pOutdoorCcm[6]*/
+ 0x0F120062, /*TVAR_wbt_pOutdoorCcm[7]*/
+ 0x0F1202A7, /*TVAR_wbt_pOutdoorCcm[8]*/
+ 0x0F1200C9, /*TVAR_wbt_pOutdoorCcm[9]*/
+ 0x0F120123, /*TVAR_wbt_pOutdoorCcm[10]*/
+ 0x0F12FF36, /*TVAR_wbt_pOutdoorCcm[11]*/
+ 0x0F1201AD, /*TVAR_wbt_pOutdoorCcm[12]*/
+ 0x0F12FFC8, /*TVAR_wbt_pOutdoorCcm[13]*/
+ 0x0F120202, /*TVAR_wbt_pOutdoorCcm[14]*/
+ 0x0F12FFCF, /*TVAR_wbt_pOutdoorCcm[15]*/
+ 0x0F120257, /*TVAR_wbt_pOutdoorCcm[16]*/
+ 0x0F12022C, /*TVAR_wbt_pOutdoorCcm[17]*/
+ /* param_end TVAR_wbt_pOutdoorCcm*/
+ 0x002A2404,
+ 0x0F120001, /*#MVAR_AAIO_bFIT*/
+ 0x002A2408,
+ 0x0F120001, /*#MVAR_AAIO_bAutoCCMandASH*/
+ 0x002A23DC,
+ 0x0F1201DD, /*#Mon_AAIO_PrevFrmData_NormBr*/
+ /*===================================================================*/
+ /*AFIT*/
+ /*===================================================================*/
+ /* param_start afit_uNoiseIndInDoor*/
+ 0x002A065C,
+ 0x0F12004A, /*#afit_uNoiseIndInDoor_0_*/
+ 0x0F12005F, /*#afit_uNoiseIndInDoor_1_*/
+ 0x0F1200CB, /*#afit_uNoiseIndInDoor_2_*/
+ 0x0F1201E0, /*#afit_uNoiseIndInDoor_3_*/
+ 0x0F120220, /*#afit_uNoiseIndInDoor_4_*/
+ /* param_end afit_uNoiseIndInDoor*/
+ /* param_start TVAR_afit_pBaseVals*/
+ 0x002A06BC,
+ 0x0F120000, /*#AfitBaseVals AFIT16_BRIGHTNESS*/
+ 0x0F120000, /*#AfitBaseVals_0__1_ AFIT16_CONTRAST*/
+ 0x0F120014, /*#AfitBaseVals_0__2_ AFIT16_SATURATION*/
+ 0x0F120000, /*#AfitBaseVals_0__3_ AFIT16_SHARP_BLUR*/
+ 0x0F120000, /*#AfitBaseVals_0__4_ AFIT16_GLAMOUR*/
+ 0x0F1200C1, /*#AfitBaseVals_0__5_ AFIT16_sddd8a_edge_high*/
+ 0x0F1203FF, /*#AfitBaseVals_0__6_ AFIT16_Demosaicing_iSatVal*/
+ 0x0F12009C, /*#AfitBaseVals_0__7_
+ AFIT16_Sharpening_iReduceEdgeThresh*/
+ 0x0F12017C, /*#AfitBaseVals_0__8_ AFIT16_demsharpmix1_iRGBOffset*/
+ 0x0F1203FF, /*#AfitBaseVals_0__9_ AFIT16_demsharpmix1_iDemClamp*/
+ 0x0F12000C, /*#AfitBaseVals_0__10_
+ AFIT16_demsharpmix1_iLowThreshold*/
+ 0x0F120010, /*#AfitBaseVals_0__11_
+ AFIT16_demsharpmix1_iHighThreshold*/
+ 0x0F12012C, /*#AfitBaseVals_0__12_AFIT16_demsharpmix1_iLowBright*/
+ 0x0F1203E8, /*#AfitBaseVals_0__13_AFIT16_demsharpmix1_iHighBright*/
+ 0x0F120046, /*#AfitBaseVals_0__14_AFIT16_demsharpmix1_iLowSat*/
+ 0x0F12005A, /*#AfitBaseVals_0__15_AFIT16_demsharpmix1_iHighSat*/
+ 0x0F120070, /*#AfitBaseVals_0__16_AFIT16_demsharpmix1_iTune*/
+ 0x0F12001E, /*#AfitBaseVals_0__17_AFIT16_demsharpmix1_iHystThLow*/
+ 0x0F12001E, /*#AfitBaseVals_0__18_AFIT16_demsharpmix1_iHystThHigh*/
+ 0x0F1201F4, /*#AfitBaseVals_0__19_AFIT16_demsharpmix1_iHystCenter*/
+ 0x0F120046, /*#AfitBaseVals_0__20_
+ AFIT16_YUV422_DENOISE_iUVLowThresh*/
+ 0x0F120046, /*#AfitBaseVals_0__21_
+ AFIT16_YUV422_DENOISE_iUVHighThresh*/
+ 0x0F120005, /*#AfitBaseVals_0__22_
+ AFIT16_YUV422_DENOISE_iYLowThresh*/
+ 0x0F120005, /*#AfitBaseVals_0__23_
+ AFIT16_YUV422_DENOISE_iYHighThresh*/
+ 0x0F12003C, /*#AfitBaseVals_0__24_AFIT16_Sharpening_iLowSharpClamp*/
+ 0x0F120014, /*#AfitBaseVals_0__25_
+ AFIT16_Sharpening_iHighSharpClamp*/
+ 0x0F12003C, /*#AfitBaseVals_0__26_
+ AFIT16_Sharpening_iLowSharpClamp_Bin*/
+ 0x0F120014, /*#AfitBaseVals_0__27_
+ AFIT16_Sharpening_iHighSharpClamp_Bin*/
+ 0x0F12003C, /*#AfitBaseVals_0__28_
+ AFIT16_Sharpening_iLowSharpClamp_sBin*/
+ 0x0F12001E, /*#AfitBaseVals_0__29_
+ AFIT16_Sharpening_iHighSharpClamp_sBin*/
+ 0x0F120A24, /*#AfitBaseVals_0__30_AFIT8_sddd8a_edge_low [7:0],
+ AFIT8_sddd8a_repl_thresh [15:8]*/
+ 0x0F121701, /*#AfitBaseVals_0__31_
+ AFIT8_sddd8a_repl_force [7:0],
+ AFIT8_sddd8a_sat_level [15:8]*/
+ 0x0F120229, /*#AfitBaseVals_0__32_
+ AFIT8_sddd8a_sat_thr[7:0],
+ AFIT8_sddd8a_sat_mpl [15:8]*/
+ 0x0F121403, /*#AfitBaseVals_0__33_
+ AFIT8_sddd8a_sat_noise[7:0],
+ AFIT8_sddd8a_iMaxSlopeAllowed [15:8]*/
+ 0x0F120000, /*#AfitBaseVals_0__34_
+ AFIT8_sddd8a_iHotThreshHigh[7:0],
+ AFIT8_sddd8a_iHotThreshLow [15:8]*/
+ 0x0F120000, /*#AfitBaseVals_0__35_
+ AFIT8_sddd8a_iColdThreshHigh[7:0],
+ AFIT8_sddd8a_iColdThreshLow [15:8]*/
+ 0x0F120000, /*#AfitBaseVals_0__36_
+ AFIT8_sddd8a_AddNoisePower1[7:0],
+ AFIT8_sddd8a_AddNoisePower2 [15:8]*/
+ 0x0F1200FF, /*#AfitBaseVals_0__37_
+ AFIT8_sddd8a_iSatSat[7:0],
+ AFIT8_sddd8a_iRadialTune [15:8]*/
+ 0x0F120A3B, /*#AfitBaseVals_0__38_
+ AFIT8_sddd8a_iRadialLimit [7:0],
+ AFIT8_sddd8a_iRadialPower [15:8]*/
+ 0x0F121414, /*#AfitBaseVals_0__39_
+ AFIT8_sddd8a_iLowMaxSlopeAllowed [7:0],
+ AFIT8_sddd8a_iHighMaxSlopeAllowed [15:8]*/
+ 0x0F120301, /*#AfitBaseVals_0__40_
+ AFIT8_sddd8a_iLowSlopeThresh[7:0],
+ AFIT8_sddd8a_iHighSlopeThresh [15:8]*/
+ 0x0F12FF07, /*#AfitBaseVals_0__41_
+ AFIT8_sddd8a_iSquaresRounding [7:0],
+ AFIT8_Demosaicing_iCentGrad [15:8]*/
+ 0x0F12081E, /*#AfitBaseVals_0__42_
+ AFIT8_Demosaicing_iMonochrom [7:0],
+ AFIT8_Demosaicing_iDecisionThresh [15:8]*/
+ 0x0F120A1E, /*#AfitBaseVals_0__43_
+ AFIT8_Demosaicing_iDesatThresh [7:0],
+ AFIT8_Demosaicing_iEnhThresh [15:8]*/
+ 0x0F120F0F, /*#AfitBaseVals_0__44_
+ AFIT8_Demosaicing_iGRDenoiseVal [7:0],
+ AFIT8_Demosaicing_iGBDenoiseVal [15:8]*/
+ 0x0F120A00, /*#AfitBaseVals_0__45_
+ AFIT8_Demosaicing_iNearGrayDesat[7:0],
+ AFIT8_Demosaicing_iDFD_ReduceCoeff [15:8]*/
+ 0x0F120012, /*#AfitBaseVals_0__46_
+ AFIT8_Sharpening_iMSharpen [7:0],
+ AFIT8_Sharpening_iMShThresh [15:8]*/
+ 0x0F12001E, /*#AfitBaseVals_0__47_
+ AFIT8_Sharpening_iWSharpen [7:0],
+ AFIT8_Sharpening_iWShThresh [15:8]*/
+ 0x0F120002, /*#AfitBaseVals_0__48_
+ AFIT8_Sharpening_nSharpWidth [7:0],
+ AFIT8_Sharpening_iReduceNegative [15:8]*/
+ 0x0F1200FF, /*#AfitBaseVals_0__49_
+ AFIT8_Sharpening_iShDespeckle [7:0],
+ AFIT8_demsharpmix1_iRGBMultiplier [15:8]*/
+ 0x0F121102, /*#AfitBaseVals_0__50_
+ AFIT8_demsharpmix1_iFilterPower [7:0],
+ AFIT8_demsharpmix1_iBCoeff [15:8]*/
+ 0x0F12001B, /*#AfitBaseVals_0__51_
+ AFIT8_demsharpmix1_iGCoeff [7:0],
+ AFIT8_demsharpmix1_iWideMult [15:8]*/
+ 0x0F120900, /*#AfitBaseVals_0__52_
+ AFIT8_demsharpmix1_iNarrMult [7:0],
+ AFIT8_demsharpmix1_iHystFalloff [15:8]*/
+ 0x0F120600, /*#AfitBaseVals_0__53_
+ AFIT8_demsharpmix1_iHystMinMult [7:0],
+ AFIT8_demsharpmix1_iHystWidth [15:8]*/
+ 0x0F120504, /*#AfitBaseVals_0__54_
+ AFIT8_demsharpmix1_iHystFallLow [7:0],
+ AFIT8_demsharpmix1_iHystFallHigh [15:8]*/
+ 0x0F120306, /*#AfitBaseVals_0__55_
+ AFIT8_demsharpmix1_iHystTune [7:0],
+ * AFIT8_YUV422_DENOISE_iUVSupport [15:8]*/
+ 0x0F128003, /*#AfitBaseVals_0__56_
+ AFIT8_YUV422_DENOISE_iYSupport [7:0],
+ AFIT8_byr_cgras_iShadingPower [15:8]*/
+ 0x0F121982, /*#AfitBaseVals_0__57_AFIT8_RGBGamma2_iLinearity [7:0],
+ AFIT8_RGBGamma2_iDarkReduce [15:8]*/
+ 0x0F120A80, /*#AfitBaseVals_0__58_AFIT8_ccm_oscar_iSaturation[7:0],
+ AFIT8_RGB2YUV_iYOffset [15:8]*/
+ 0x0F120080, /*#AfitBaseVals_0__59_AFIT8_RGB2YUV_iRGBGain [7:0],
+ AFIT8_RGB2YUV_iSaturation [15:8]*/
+ 0x0F121414, /*#AfitBaseVals_0__60_AFIT8_sddd8a_iClustThresh_H [7:0],
+ AFIT8_sddd8a_iClustThresh_C [15:8]*/
+ 0x0F120101, /*#AfitBaseVals_0__61_AFIT8_sddd8a_iClustMulT_H [7:0],
+ AFIT8_sddd8a_iClustMulT_C [15:8]*/
+ 0x0F124601, /*#AfitBaseVals_0__62_AFIT8_sddd8a_nClustLevel_H [7:0],
+ AFIT8_sddd8a_DispTH_Low [15:8]*/
+ 0x0F126444, /*#AfitBaseVals_0__63_AFIT8_sddd8a_DispTH_High [7:0],
+ AFIT8_sddd8a_iDenThreshLow [15:8]*/
+ 0x0F129650, /*#AfitBaseVals_0__64_AFIT8_sddd8a_iDenThreshHigh[7:0],
+ AFIT8_Demosaicing_iEdgeDesat [15:8]*/
+ 0x0F120000, /*#AfitBaseVals_0__65_
+ AFIT8_Demosaicing_iEdgeDesatThrLow [7:0],
+ AFIT8_Demosaicing_iEdgeDesatThrHigh [15:8]*/
+ 0x0F120003, /*#AfitBaseVals_0__66_
+ AFIT8_Demosaicing_iEdgeDesatLimit[7:0],
+ AFIT8_Demosaicing_iDemSharpenLow [15:8]*/
+ 0x0F121E00, /*#AfitBaseVals_0__67_
+ AFIT8_Demosaicing_iDemSharpenHigh[7:0],
+ AFIT8_Demosaicing_iDemSharpThresh [15:8]*/
+ 0x0F120714, /*#AfitBaseVals_0__68_
+ AFIT8_Demosaicing_iDemShLowLimit [7:0],
+ AFIT8_Demosaicing_iDespeckleForDemsharp [15:8]*/
+ 0x0F121464, /*#AfitBaseVals_0__69_
+ AFIT8_Demosaicing_iDemBlurLow[7:0],
+ AFIT8_Demosaicing_iDemBlurHigh [15:8]*/
+ 0x0F121404, /*#AfitBaseVals_0__70_
+ AFIT8_Demosaicing_iDemBlurRange[7:0],
+ AFIT8_Sharpening_iLowSharpPower [15:8]*/
+ 0x0F120F14, /*#AfitBaseVals_0__71_
+ AFIT8_Sharpening_iHighSharpPower[7:0],
+ AFIT8_Sharpening_iLowShDenoise [15:8]*/
+ 0x0F12400F, /*#AfitBaseVals_0__72_
+ AFIT8_Sharpening_iHighShDenoise [7:0],
+ AFIT8_Sharpening_iReduceEdgeMinMult [15:8]*/
+ 0x0F120204, /*#AfitBaseVals_0__73_
+ AFIT8_Sharpening_iReduceEdgeSlope [7:0],
+ AFIT8_demsharpmix1_iWideFiltReduce [15:8]*/
+ 0x0F121403, /*#AfitBaseVals_0__74_
+ AFIT8_demsharpmix1_iNarrFiltReduce [7:0],
+ AFIT8_sddd8a_iClustThresh_H_Bin [15:8]*/
+ 0x0F120114, /*#AfitBaseVals_0__75_
+ AFIT8_sddd8a_iClustThresh_C_Bin [7:0],
+ AFIT8_sddd8a_iClustMulT_H_Bin [15:8]*/
+ 0x0F120101, /*#AfitBaseVals_0__76_
+ AFIT8_sddd8a_iClustMulT_C_Bin [7:0],
+ AFIT8_sddd8a_nClustLevel_H_Bin [15:8]*/
+ 0x0F124446, /*#AfitBaseVals_0__77_
+ AFIT8_sddd8a_DispTH_Low_Bin [7:0],
+ AFIT8_sddd8a_DispTH_High_Bin [15:8]*/
+ 0x0F125064, /*#AfitBaseVals_0__78_
+ AFIT8_sddd8a_iDenThreshLow_Bin [7:0],
+ AFIT8_sddd8a_iDenThreshHigh_Bin [15:8]*/
+ 0x0F120028, /*#AfitBaseVals_0__79_
+ AFIT8_Demosaicing_iEdgeDesat_Bin[7:0],
+ AFIT8_Demosaicing_iEdgeDesatThrLow_Bin [15:8]*/
+ 0x0F120300, /*#AfitBaseVals_0__80_
+ AFIT8_Demosaicing_iEdgeDesatThrHigh_Bin [7:0],
+ AFIT8_Demosaicing_iEdgeDesatLimit_Bin [15:8]*/
+ 0x0F120000, /*#AfitBaseVals_0__81_
+ AFIT8_Demosaicing_iDemSharpenLow_Bin [7:0],
+ AFIT8_Demosaicing_iDemSharpenHigh_Bin [15:8]*/
+ 0x0F12141E, /*#AfitBaseVals_0__82_
+ AFIT8_Demosaicing_iDemSharpThresh_Bin [7:0],
+ AFIT8_Demosaicing_iDemShLowLimit_Bin [15:8]*/
+ 0x0F126407, /*#AfitBaseVals_0__83_
+ AFIT8_Demosaicing_iDespeckleForDemsharp_Bin [7:0],
+ AFIT8_Demosaicing_iDemBlurLow_Bin [15:8]*/
+ 0x0F120414, /*#AfitBaseVals_0__84_
+ AFIT8_Demosaicing_iDemBlurHigh_Bin [7:0],
+ AFIT8_Demosaicing_iDemBlurRange_Bin [15:8]*/
+ 0x0F121414, /*#AfitBaseVals_0__85_
+ AFIT8_Sharpening_iLowSharpPower_Bin [7:0],
+ AFIT8_Sharpening_iHighSharpPower_Bin [15:8]*/
+ 0x0F120F0F, /*#AfitBaseVals_0__86_
+ AFIT8_Sharpening_iLowShDenoise_Bin [7:0],
+ AFIT8_Sharpening_iHighShDenoise_Bin [15:8]*/
+ 0x0F120440, /*#AfitBaseVals_0__87_
+ AFIT8_Sharpening_iReduceEdgeMinMult_Bin [7:0],
+ AFIT8_Sharpening_iReduceEdgeSlope_Bin [15:8]*/
+ 0x0F120302, /*#AfitBaseVals_0__88_
+ AFIT8_demsharpmix1_iWideFiltReduce_Bin [7:0],
+ AFIT8_demsharpmix1_iNarrFiltReduce_Bin [15:8]*/
+ 0x0F121414, /*#AfitBaseVals_0__89_
+ AFIT8_sddd8a_iClustThresh_H_sBin[7:0],
+ AFIT8_sddd8a_iClustThresh_C_sBin [15:8]*/
+ 0x0F120101, /*#AfitBaseVals_0__90_
+ AFIT8_sddd8a_iClustMulT_H_sBin [7:0],
+ AFIT8_sddd8a_iClustMulT_C_sBin [15:8]*/
+ 0x0F124601, /*#AfitBaseVals_0__91_
+ AFIT8_sddd8a_nClustLevel_H_sBin [7:0],
+ AFIT8_sddd8a_DispTH_Low_sBin [15:8]*/
+ 0x0F126E44, /*#AfitBaseVals_0__92_
+ AFIT8_sddd8a_DispTH_High_sBin [7:0],
+ AFIT8_sddd8a_iDenThreshLow_sBin [15:8]*/
+ 0x0F122864, /*#AfitBaseVals_0__93_
+ AFIT8_sddd8a_iDenThreshHigh_sBin[7:0],
+ AFIT8_Demosaicing_iEdgeDesat_sBin [15:8]*/
+ 0x0F120A00, /*#AfitBaseVals_0__94_
+ AFIT8_Demosaicing_iEdgeDesatThrLow_sBin [7:0],
+ AFIT8_Demosaicing_iEdgeDesatThrHigh_sBin [15:8]*/
+ 0x0F120003, /*#AfitBaseVals_0__95_
+ AFIT8_Demosaicing_iEdgeDesatLimit_sBin [7:0],
+ AFIT8_Demosaicing_iDemSharpenLow_sBin [15:8]*/
+ 0x0F121E00, /*#AfitBaseVals_0__96_
+ AFIT8_Demosaicing_iDemSharpenHigh_sBin [7:0],
+ AFIT8_Demosaicing_iDemSharpThresh_sBin [15:8]*/
+ 0x0F120714, /*#AfitBaseVals_0__97_
+ AFIT8_Demosaicing_iDemShLowLimit_sBin [7:0],
+ AFIT8_Demosaicing_iDespeckleForDemsharp_sBin [15:8]*/
+ 0x0F1232FF, /*#AfitBaseVals_0__98_
+ AFIT8_Demosaicing_iDemBlurLow_sBin [7:0],
+ AFIT8_Demosaicing_iDemBlurHigh_sBin [15:8]*/
+ 0x0F120004, /*#AfitBaseVals_0__99_
+ AFIT8_Demosaicing_iDemBlurRange_sBin [7:0],
+ AFIT8_Sharpening_iLowSharpPower_sBin [15:8]*/
+ 0x0F120F00, /*#AfitBaseVals_0__100_
+ AFIT8_Sharpening_iHighSharpPower_sBin [7:0],
+ AFIT8_Sharpening_iLowShDenoise_sBin [15:8]*/
+ 0x0F12400F, /*#AfitBaseVals_0__101_
+ AFIT8_Sharpening_iHighShDenoise_sBin [7:0],
+ AFIT8_Sharpening_iReduceEdgeMinMult_sBin [15:8]*/
+ 0x0F120204, /*#AfitBaseVals_0__102_
+ AFIT8_Sharpening_iReduceEdgeSlope_sBin [7:0],
+ AFIT8_demsharpmix1_iWideFiltReduce_sBin [15:8]*/
+ 0x0F120003, /*#AfitBaseVals_0__103_
+ AFIT8_demsharpmix1_iNarrFiltReduce_sBin [7:0]*/
+ 0x0F120000, /*#AfitBaseVals_1__0_ AFIT16_BRIGHTNESS*/
+ 0x0F120000, /*#AfitBaseVals_1__1_ AFIT16_CONTRAST*/
+ 0x0F120014, /*#AfitBaseVals_1__2_ AFIT16_SATURATION*/
+ 0x0F120000, /*#AfitBaseVals_1__3_ AFIT16_SHARP_BLUR*/
+ 0x0F120000, /*#AfitBaseVals_1__4_ AFIT16_GLAMOUR*/
+ 0x0F1200C1, /*#AfitBaseVals_1__5_ AFIT16_sddd8a_edge_high*/
+ 0x0F1203FF, /*#AfitBaseVals_1__6_ AFIT16_Demosaicing_iSatVal*/
+ 0x0F12009C, /*#AfitBaseVals_1__7_
+ AFIT16_Sharpening_iReduceEdgeThresh*/
+ 0x0F12017C, /*#AfitBaseVals_1__8_ AFIT16_demsharpmix1_iRGBOffset*/
+ 0x0F1203FF, /*#AfitBaseVals_1__9_ AFIT16_demsharpmix1_iDemClamp*/
+ 0x0F12000C, /*#AfitBaseVals_1__10_
+ AFIT16_demsharpmix1_iLowThreshold*/
+ 0x0F120010, /*#AfitBaseVals_1__11_
+ AFIT16_demsharpmix1_iHighThreshold*/
+ 0x0F12012C, /*#AfitBaseVals_1__12_AFIT16_demsharpmix1_iLowBright*/
+ 0x0F1203E8, /*#AfitBaseVals_1__13_AFIT16_demsharpmix1_iHighBright*/
+ 0x0F120046, /*#AfitBaseVals_1__14_AFIT16_demsharpmix1_iLowSat*/
+ 0x0F12005A, /*#AfitBaseVals_1__15_AFIT16_demsharpmix1_iHighSat*/
+ 0x0F120070, /*#AfitBaseVals_1__16_AFIT16_demsharpmix1_iTune*/
+ 0x0F120008, /*#AfitBaseVals_1__17_AFIT16_demsharpmix1_iHystThLow*/
+ 0x0F120000, /*#AfitBaseVals_1__18_AFIT16_demsharpmix1_iHystThHigh*/
+ 0x0F120320, /*#AfitBaseVals_1__19_AFIT16_demsharpmix1_iHystCenter*/
+ 0x0F120046, /*#AfitBaseVals_1__20_
+ AFIT16_YUV422_DENOISE_iUVLowThresh*/
+ 0x0F120046, /*#AfitBaseVals_1__21_
+ AFIT16_YUV422_DENOISE_iUVHighThresh*/
+ 0x0F120000, /*#AfitBaseVals_1__22_
+ AFIT16_YUV422_DENOISE_iYLowThresh*/
+ 0x0F120000, /*#AfitBaseVals_1__23_
+ AFIT16_YUV422_DENOISE_iYHighThresh*/
+ 0x0F120064, /*#AfitBaseVals_1__24_
+ AFIT16_Sharpening_iLowSharpClamp*/
+ 0x0F120014, /*#AfitBaseVals_1__25_
+ AFIT16_Sharpening_iHighSharpClamp*/
+ 0x0F120064, /*#AfitBaseVals_1__26_
+ AFIT16_Sharpening_iLowSharpClamp_Bin*/
+ 0x0F120014, /*#AfitBaseVals_1__27_
+ AFIT16_Sharpening_iHighSharpClamp_Bin*/
+ 0x0F12003C, /*#AfitBaseVals_1__28_
+ AFIT16_Sharpening_iLowSharpClamp_sBin*/
+ 0x0F12001E, /*#AfitBaseVals_1__29_
+ AFIT16_Sharpening_iHighSharpClamp_sBin*/
+ 0x0F120A24, /*#AfitBaseVals_1__30_
+ AFIT8_sddd8a_edge_low [7:0],
+ AFIT8_sddd8a_repl_thresh [15:8]*/
+ 0x0F121701, /*#AfitBaseVals_1__31_
+ AFIT8_sddd8a_repl_force [7:0],
+ AFIT8_sddd8a_sat_level [15:8]*/
+ 0x0F120229, /*#AfitBaseVals_1__32_
+ AFIT8_sddd8a_sat_thr[7:0],
+ AFIT8_sddd8a_sat_mpl [15:8]*/
+ 0x0F121403, /*#AfitBaseVals_1__33_
+ AFIT8_sddd8a_sat_noise[7:0],
+ AFIT8_sddd8a_iMaxSlopeAllowed [15:8]*/
+ 0x0F120000, /*#AfitBaseVals_1__34_
+ AFIT8_sddd8a_iHotThreshHigh[7:0],
+ AFIT8_sddd8a_iHotThreshLow [15:8]*/
+ 0x0F120000, /*#AfitBaseVals_1__35_
+ AFIT8_sddd8a_iColdThreshHigh[7:0],
+ AFIT8_sddd8a_iColdThreshLow [15:8]*/
+ 0x0F120000, /*#AfitBaseVals_1__36_
+ AFIT8_sddd8a_AddNoisePower1[7:0],
+ AFIT8_sddd8a_AddNoisePower2 [15:8]*/
+ 0x0F1200FF, /*#AfitBaseVals_1__37_
+ AFIT8_sddd8a_iSatSat[7:0],
+ AFIT8_sddd8a_iRadialTune [15:8]*/
+ 0x0F12033B, /*#AfitBaseVals_1__38_
+ AFIT8_sddd8a_iRadialLimit [7:0],
+ AFIT8_sddd8a_iRadialPower [15:8]*/
+ 0x0F121414, /*#AfitBaseVals_1__39_
+ AFIT8_sddd8a_iLowMaxSlopeAllowed [7:0],
+ AFIT8_sddd8a_iHighMaxSlopeAllowed [15:8]*/
+ 0x0F120301, /*#AfitBaseVals_1__40_
+ AFIT8_sddd8a_iLowSlopeThresh[7:0],
+ AFIT8_sddd8a_iHighSlopeThresh [15:8]*/
+ 0x0F12FF07, /*#AfitBaseVals_1__41_
+ AFIT8_sddd8a_iSquaresRounding [7:0],
+ AFIT8_Demosaicing_iCentGrad [15:8]*/
+ 0x0F12081E, /*#AfitBaseVals_1__42_
+ AFIT8_Demosaicing_iMonochrom [7:0],
+ AFIT8_Demosaicing_iDecisionThresh [15:8]*/
+ 0x0F120A1E, /*#AfitBaseVals_1__43_
+ AFIT8_Demosaicing_iDesatThresh [7:0],
+ AFIT8_Demosaicing_iEnhThresh [15:8]*/
+ 0x0F120F0F, /*#AfitBaseVals_1__44_
+ AFIT8_Demosaicing_iGRDenoiseVal [7:0],
+ AFIT8_Demosaicing_iGBDenoiseVal [15:8]*/
+ 0x0F120A00, /*#AfitBaseVals_1__45_
+ AFIT8_Demosaicing_iNearGrayDesat[7:0],
+ AFIT8_Demosaicing_iDFD_ReduceCoeff [15:8]*/
+ 0x0F120012, /*#AfitBaseVals_1__46_
+ AFIT8_Sharpening_iMSharpen [7:0],
+ AFIT8_Sharpening_iMShThresh [15:8]*/
+ 0x0F120005, /*#AfitBaseVals_1__47_
+ AFIT8_Sharpening_iWSharpen [7:0],
+ AFIT8_Sharpening_iWShThresh [15:8]*/
+ 0x0F120002, /*#AfitBaseVals_1__48_
+ AFIT8_Sharpening_nSharpWidth [7:0],
+ AFIT8_Sharpening_iReduceNegative [15:8]*/
+ 0x0F1200FF, /*#AfitBaseVals_1__49_
+ AFIT8_Sharpening_iShDespeckle [7:0],
+ AFIT8_demsharpmix1_iRGBMultiplier [15:8]*/
+ 0x0F121102, /*#AfitBaseVals_1__50_
+ AFIT8_demsharpmix1_iFilterPower [7:0],
+ AFIT8_demsharpmix1_iBCoeff [15:8]*/
+ 0x0F12001B, /*#AfitBaseVals_1__51_
+ AFIT8_demsharpmix1_iGCoeff [7:0],
+ AFIT8_demsharpmix1_iWideMult [15:8]*/
+ 0x0F120900, /*#AfitBaseVals_1__52_
+ AFIT8_demsharpmix1_iNarrMult [7:0],
+ AFIT8_demsharpmix1_iHystFalloff [15:8]*/
+ 0x0F120600, /*#AfitBaseVals_1__53_
+ AFIT8_demsharpmix1_iHystMinMult [7:0],
+ AFIT8_demsharpmix1_iHystWidth [15:8]*/
+ 0x0F120504, /*#AfitBaseVals_1__54_
+ AFIT8_demsharpmix1_iHystFallLow [7:0],
+ AFIT8_demsharpmix1_iHystFallHigh [15:8]*/
+ 0x0F120306, /*#AfitBaseVals_1__55_
+ AFIT8_demsharpmix1_iHystTune [7:0],
+ * AFIT8_YUV422_DENOISE_iUVSupport [15:8]*/
+ 0x0F128003, /*#AfitBaseVals_1__56_
+ AFIT8_YUV422_DENOISE_iYSupport [7:0],
+ AFIT8_byr_cgras_iShadingPower [15:8]*/
+ 0x0F120A6E, /*#AfitBaseVals_1__57_
+ AFIT8_RGBGamma2_iLinearity [7:0],
+ AFIT8_RGBGamma2_iDarkReduce [15:8]*/
+ 0x0F120080, /*#AfitBaseVals_1__58_
+ AFIT8_ccm_oscar_iSaturation[7:0],
+ AFIT8_RGB2YUV_iYOffset [15:8]*/
+ 0x0F120080, /*#AfitBaseVals_1__59_
+ AFIT8_RGB2YUV_iRGBGain [7:0],
+ AFIT8_RGB2YUV_iSaturation [15:8]*/
+ 0x0F125050, /*#AfitBaseVals_1__60_
+ AFIT8_sddd8a_iClustThresh_H [7:0],
+ AFIT8_sddd8a_iClustThresh_C [15:8]*/
+ 0x0F120101, /*#AfitBaseVals_1__61_
+ AFIT8_sddd8a_iClustMulT_H [7:0],
+ AFIT8_sddd8a_iClustMulT_C [15:8]*/
+ 0x0F122801, /*#AfitBaseVals_1__62_
+ AFIT8_sddd8a_nClustLevel_H [7:0],
+ AFIT8_sddd8a_DispTH_Low [15:8]*/
+ 0x0F12231E, /*#AfitBaseVals_1__63_
+ AFIT8_sddd8a_DispTH_High [7:0],
+ AFIT8_sddd8a_iDenThreshLow [15:8]*/
+ 0x0F12961E, /*#AfitBaseVals_1__64_
+ AFIT8_sddd8a_iDenThreshHigh[7:0],
+ AFIT8_Demosaicing_iEdgeDesat [15:8]*/
+ 0x0F120000, /*#AfitBaseVals_1__65_
+ AFIT8_Demosaicing_iEdgeDesatThrLow [7:0],
+ AFIT8_Demosaicing_iEdgeDesatThrHigh [15:8]*/
+ 0x0F120003, /*#AfitBaseVals_1__66_
+ AFIT8_Demosaicing_iEdgeDesatLimit[7:0],
+ AFIT8_Demosaicing_iDemSharpenLow [15:8]*/
+ 0x0F120A02, /*#AfitBaseVals_1__67_
+ AFIT8_Demosaicing_iDemSharpenHigh[7:0],
+ AFIT8_Demosaicing_iDemSharpThresh [15:8]*/
+ 0x0F120764, /*#AfitBaseVals_1__68_
+ AFIT8_Demosaicing_iDemShLowLimit [7:0],
+ AFIT8_Demosaicing_iDespeckleForDemsharp [15:8]*/
+ 0x0F12143C, /*#AfitBaseVals_1__69_
+ AFIT8_Demosaicing_iDemBlurLow[7:0],
+ AFIT8_Demosaicing_iDemBlurHigh [15:8]*/
+ 0x0F121401, /*#AfitBaseVals_1__70_
+ AFIT8_Demosaicing_iDemBlurRange[7:0],
+ AFIT8_Sharpening_iLowSharpPower [15:8]*/
+ 0x0F120F14, /*#AfitBaseVals_1__71_
+ AFIT8_Sharpening_iHighSharpPower[7:0],
+ AFIT8_Sharpening_iLowShDenoise [15:8]*/
+ 0x0F12400F, /*#AfitBaseVals_1__72_
+ AFIT8_Sharpening_iHighShDenoise [7:0],
+ AFIT8_Sharpening_iReduceEdgeMinMult [15:8]*/
+ 0x0F120204, /*#AfitBaseVals_1__73_
+ AFIT8_Sharpening_iReduceEdgeSlope [7:0],
+ AFIT8_demsharpmix1_iWideFiltReduce [15:8]*/
+ 0x0F125003, /*#AfitBaseVals_1__74_
+ AFIT8_demsharpmix1_iNarrFiltReduce [7:0],
+ AFIT8_sddd8a_iClustThresh_H_Bin [15:8]*/
+ 0x0F120150, /*#AfitBaseVals_1__75_
+ AFIT8_sddd8a_iClustThresh_C_Bin [7:0],
+ AFIT8_sddd8a_iClustMulT_H_Bin [15:8]*/
+ 0x0F120101, /*#AfitBaseVals_1__76_
+ AFIT8_sddd8a_iClustMulT_C_Bin [7:0],
+ AFIT8_sddd8a_nClustLevel_H_Bin [15:8]*/
+ 0x0F121E28, /*#AfitBaseVals_1__77_
+ AFIT8_sddd8a_DispTH_Low_Bin [7:0],
+ AFIT8_sddd8a_DispTH_High_Bin [15:8]*/
+ 0x0F12140F, /*#AfitBaseVals_1__78_
+ AFIT8_sddd8a_iDenThreshLow_Bin [7:0],
+ AFIT8_sddd8a_iDenThreshHigh_Bin [15:8]*/
+ 0x0F120028, /*#AfitBaseVals_1__79_
+ AFIT8_Demosaicing_iEdgeDesat_Bin[7:0],
+ AFIT8_Demosaicing_iEdgeDesatThrLow_Bin [15:8]*/
+ 0x0F120300, /*#AfitBaseVals_1__80_
+ AFIT8_Demosaicing_iEdgeDesatThrHigh_Bin [7:0],
+ AFIT8_Demosaicing_iEdgeDesatLimit_Bin [15:8]*/
+ 0x0F120200, /*#AfitBaseVals_1__81_
+ AFIT8_Demosaicing_iDemSharpenLow_Bin [7:0],
+ AFIT8_Demosaicing_iDemSharpenHigh_Bin [15:8]*/
+ 0x0F121E0A, /*#AfitBaseVals_1__82_
+ AFIT8_Demosaicing_iDemSharpThresh_Bin [7:0],
+ AFIT8_Demosaicing_iDemShLowLimit_Bin [15:8]*/
+ 0x0F123C07, /*#AfitBaseVals_1__83_
+ AFIT8_Demosaicing_iDespeckleForDemsharp_Bin [7:0],
+ AFIT8_Demosaicing_iDemBlurLow_Bin [15:8]*/
+ 0x0F120114, /*#AfitBaseVals_1__84_
+ AFIT8_Demosaicing_iDemBlurHigh_Bin [7:0],
+ AFIT8_Demosaicing_iDemBlurRange_Bin [15:8]*/
+ 0x0F121414, /*#AfitBaseVals_1__85_
+ AFIT8_Sharpening_iLowSharpPower_Bin [7:0],
+ AFIT8_Sharpening_iHighSharpPower_Bin [15:8]*/
+ 0x0F120F0F, /*#AfitBaseVals_1__86_
+ AFIT8_Sharpening_iLowShDenoise_Bin [7:0],
+ AFIT8_Sharpening_iHighShDenoise_Bin [15:8]*/
+ 0x0F120440, /*#AfitBaseVals_1__87_
+ AFIT8_Sharpening_iReduceEdgeMinMult_Bin [7:0],
+ AFIT8_Sharpening_iReduceEdgeSlope_Bin [15:8]*/
+ 0x0F120302, /*#AfitBaseVals_1__88_
+ AFIT8_demsharpmix1_iWideFiltReduce_Bin [7:0],
+ AFIT8_demsharpmix1_iNarrFiltReduce_Bin [15:8]*/
+ 0x0F121E1E, /*#AfitBaseVals_1__89_
+ AFIT8_sddd8a_iClustThresh_H_sBin[7:0],
+ AFIT8_sddd8a_iClustThresh_C_sBin [15:8]*/
+ 0x0F120101, /*#AfitBaseVals_1__90_
+ AFIT8_sddd8a_iClustMulT_H_sBin [7:0],
+ AFIT8_sddd8a_iClustMulT_C_sBin [15:8]*/
+ 0x0F123C01, /*#AfitBaseVals_1__91_
+ AFIT8_sddd8a_nClustLevel_H_sBin [7:0],
+ AFIT8_sddd8a_DispTH_Low_sBin [15:8]*/
+ 0x0F125A3A, /*#AfitBaseVals_1__92_
+ AFIT8_sddd8a_DispTH_High_sBin [7:0],
+ AFIT8_sddd8a_iDenThreshLow_sBin [15:8]*/
+ 0x0F122858, /*#AfitBaseVals_1__93_
+ AFIT8_sddd8a_iDenThreshHigh_sBin[7:0],
+ AFIT8_Demosaicing_iEdgeDesat_sBin [15:8]*/
+ 0x0F120A00, /*#AfitBaseVals_1__94_
+ AFIT8_Demosaicing_iEdgeDesatThrLow_sBin [7:0],
+ AFIT8_Demosaicing_iEdgeDesatThrHigh_sBin [15:8]*/
+ 0x0F120003, /*#AfitBaseVals_1__95_
+ AFIT8_Demosaicing_iEdgeDesatLimit_sBin [7:0],
+ AFIT8_Demosaicing_iDemSharpenLow_sBin [15:8]*/
+ 0x0F121E00, /*#AfitBaseVals_1__96_
+ AFIT8_Demosaicing_iDemSharpenHigh_sBin [7:0],
+ AFIT8_Demosaicing_iDemSharpThresh_sBin [15:8]*/
+ 0x0F120714, /*#AfitBaseVals_1__97_
+ AFIT8_Demosaicing_iDemShLowLimit_sBin [7:0],
+ AFIT8_Demosaicing_iDespeckleForDemsharp_sBin [15:8]*/
+ 0x0F1232FF, /*#AfitBaseVals_1__98_
+ AFIT8_Demosaicing_iDemBlurLow_sBin [7:0],
+ AFIT8_Demosaicing_iDemBlurHigh_sBin [15:8]*/
+ 0x0F120004, /*#AfitBaseVals_1__99_
+ AFIT8_Demosaicing_iDemBlurRange_sBin [7:0],
+ AFIT8_Sharpening_iLowSharpPower_sBin [15:8]*/
+ 0x0F120F00, /*#AfitBaseVals_1__100_
+ AFIT8_Sharpening_iHighSharpPower_sBin [7:0],
+ AFIT8_Sharpening_iLowShDenoise_sBin [15:8]*/
+ 0x0F12400F, /*#AfitBaseVals_1__101_
+ AFIT8_Sharpening_iHighShDenoise_sBin [7:0],
+ AFIT8_Sharpening_iReduceEdgeMinMult_sBin [15:8]*/
+ 0x0F120204, /*#AfitBaseVals_1__102_
+ AFIT8_Sharpening_iReduceEdgeSlope_sBin [7:0],
+ AFIT8_demsharpmix1_iWideFiltReduce_sBin [15:8]*/
+ 0x0F120003, /*#AfitBaseVals_1__103_
+ AFIT8_demsharpmix1_iNarrFiltReduce_sBin [7:0]*/
+ 0x0F120000, /*#AfitBaseVals_2__0_ AFIT16_BRIGHTNESS*/
+ 0x0F120000, /*#AfitBaseVals_2__1_ AFIT16_CONTRAST*/
+ 0x0F120000, /*#AfitBaseVals_2__2_ AFIT16_SATURATION*/
+ 0x0F120000, /*#AfitBaseVals_2__3_ AFIT16_SHARP_BLUR*/
+ 0x0F120000, /*#AfitBaseVals_2__4_ AFIT16_GLAMOUR*/
+ 0x0F1200C1, /*#AfitBaseVals_2__5_ AFIT16_sddd8a_edge_high*/
+ 0x0F1203FF, /*#AfitBaseVals_2__6_ AFIT16_Demosaicing_iSatVal*/
+ 0x0F12009C, /*#AfitBaseVals_2__7_
+ AFIT16_Sharpening_iReduceEdgeThresh*/
+ 0x0F12017C, /*#AfitBaseVals_2__8_ AFIT16_demsharpmix1_iRGBOffset*/
+ 0x0F1203FF, /*#AfitBaseVals_2__9_ AFIT16_demsharpmix1_iDemClamp*/
+ 0x0F12000C, /*#AfitBaseVals_2__10_
+ AFIT16_demsharpmix1_iLowThreshold*/
+ 0x0F120010, /*#AfitBaseVals_2__11_
+ AFIT16_demsharpmix1_iHighThreshold*/
+ 0x0F12012C, /*#AfitBaseVals_2__12_AFIT16_demsharpmix1_iLowBright*/
+ 0x0F1203E8, /*#AfitBaseVals_2__13_AFIT16_demsharpmix1_iHighBright*/
+ 0x0F120046, /*#AfitBaseVals_2__14_AFIT16_demsharpmix1_iLowSat*/
+ 0x0F12005A, /*#AfitBaseVals_2__15_AFIT16_demsharpmix1_iHighSat*/
+ 0x0F120070, /*#AfitBaseVals_2__16_AFIT16_demsharpmix1_iTune*/
+ 0x0F120008, /*#AfitBaseVals_2__17_AFIT16_demsharpmix1_iHystThLow*/
+ 0x0F120000, /*#AfitBaseVals_2__18_AFIT16_demsharpmix1_iHystThHigh*/
+ 0x0F120320, /*#AfitBaseVals_2__19_AFIT16_demsharpmix1_iHystCenter*/
+ 0x0F120032, /*#AfitBaseVals_2__20_
+ AFIT16_YUV422_DENOISE_iUVLowThresh*/
+ 0x0F120032, /*#AfitBaseVals_2__21_
+ AFIT16_YUV422_DENOISE_iUVHighThresh*/
+ 0x0F120000, /*#AfitBaseVals_2__22_
+ AFIT16_YUV422_DENOISE_iYLowThresh*/
+ 0x0F120000, /*#AfitBaseVals_2__23_
+ AFIT16_YUV422_DENOISE_iYHighThresh*/
+ 0x0F1200B4, /*#AfitBaseVals_2__24_
+ AFIT16_Sharpening_iLowSharpClamp*/
+ 0x0F120014, /*#AfitBaseVals_2__25_
+ AFIT16_Sharpening_iHighSharpClamp*/
+ 0x0F1200B4, /*#AfitBaseVals_2__26_
+ AFIT16_Sharpening_iLowSharpClamp_Bin*/
+ 0x0F120014, /*#AfitBaseVals_2__27_
+ AFIT16_Sharpening_iHighSharpClamp_Bin*/
+ 0x0F12003C, /*#AfitBaseVals_2__28_
+ AFIT16_Sharpening_iLowSharpClamp_sBin*/
+ 0x0F12001E, /*#AfitBaseVals_2__29_
+ AFIT16_Sharpening_iHighSharpClamp_sBin*/
+ 0x0F120A24, /*#AfitBaseVals_2__30_
+ AFIT8_sddd8a_edge_low [7:0],
+ AFIT8_sddd8a_repl_thresh [15:8]*/
+ 0x0F121701, /*#AfitBaseVals_2__31_
+ AFIT8_sddd8a_repl_force [7:0],
+ AFIT8_sddd8a_sat_level [15:8]*/
+ 0x0F120229, /*#AfitBaseVals_2__32_
+ AFIT8_sddd8a_sat_thr[7:0],
+ AFIT8_sddd8a_sat_mpl [15:8]*/
+ 0x0F121403, /*#AfitBaseVals_2__33_
+ AFIT8_sddd8a_sat_noise[7:0],
+ AFIT8_sddd8a_iMaxSlopeAllowed [15:8]*/
+ 0x0F120000, /*#AfitBaseVals_2__34_
+ AFIT8_sddd8a_iHotThreshHigh[7:0],
+ AFIT8_sddd8a_iHotThreshLow [15:8]*/
+ 0x0F120000, /*#AfitBaseVals_2__35_
+ AFIT8_sddd8a_iColdThreshHigh[7:0],
+ AFIT8_sddd8a_iColdThreshLow [15:8]*/
+ 0x0F120000, /*#AfitBaseVals_2__36_
+ AFIT8_sddd8a_AddNoisePower1[7:0],
+ AFIT8_sddd8a_AddNoisePower2 [15:8]*/
+ 0x0F1200FF, /*#AfitBaseVals_2__37_
+ AFIT8_sddd8a_iSatSat[7:0],
+ AFIT8_sddd8a_iRadialTune [15:8]*/
+ 0x0F12033B, /*#AfitBaseVals_2__38_
+ AFIT8_sddd8a_iRadialLimit [7:0],
+ AFIT8_sddd8a_iRadialPower [15:8]*/
+ 0x0F121414, /*#AfitBaseVals_2__39_
+ AFIT8_sddd8a_iLowMaxSlopeAllowed [7:0],
+ AFIT8_sddd8a_iHighMaxSlopeAllowed [15:8]*/
+ 0x0F120301, /*#AfitBaseVals_2__40_
+ AFIT8_sddd8a_iLowSlopeThresh[7:0],
+ AFIT8_sddd8a_iHighSlopeThresh [15:8]*/
+ 0x0F12FF07, /*#AfitBaseVals_2__41_
+ AFIT8_sddd8a_iSquaresRounding [7:0],
+ AFIT8_Demosaicing_iCentGrad [15:8]*/
+ 0x0F12081E, /*#AfitBaseVals_2__42_
+ AFIT8_Demosaicing_iMonochrom [7:0],
+ AFIT8_Demosaicing_iDecisionThresh [15:8]*/
+ 0x0F120A1E, /*#AfitBaseVals_2__43_
+ AFIT8_Demosaicing_iDesatThresh [7:0],
+ AFIT8_Demosaicing_iEnhThresh [15:8]*/
+ 0x0F120F0F, /*#AfitBaseVals_2__44_
+ AFIT8_Demosaicing_iGRDenoiseVal [7:0],
+ AFIT8_Demosaicing_iGBDenoiseVal [15:8]*/
+ 0x0F120A00, /*#AfitBaseVals_2__45_
+ AFIT8_Demosaicing_iNearGrayDesat[7:0],
+ AFIT8_Demosaicing_iDFD_ReduceCoeff [15:8]*/
+ 0x0F120012, /*#AfitBaseVals_2__46_
+ AFIT8_Sharpening_iMSharpen [7:0],
+ AFIT8_Sharpening_iMShThresh [15:8]*/
+ 0x0F120005, /*#AfitBaseVals_2__47_
+ AFIT8_Sharpening_iWSharpen [7:0],
+ AFIT8_Sharpening_iWShThresh [15:8]*/
+ 0x0F120001, /*#AfitBaseVals_2__48_
+ AFIT8_Sharpening_nSharpWidth [7:0],
+ AFIT8_Sharpening_iReduceNegative [15:8]*/
+ 0x0F1200FF, /*#AfitBaseVals_2__49_
+ AFIT8_Sharpening_iShDespeckle [7:0],
+ AFIT8_demsharpmix1_iRGBMultiplier [15:8]*/
+ 0x0F121102, /*#AfitBaseVals_2__50_
+ AFIT8_demsharpmix1_iFilterPower [7:0],
+ AFIT8_demsharpmix1_iBCoeff [15:8]*/
+ 0x0F12001B, /*#AfitBaseVals_2__51_
+ AFIT8_demsharpmix1_iGCoeff [7:0],
+ AFIT8_demsharpmix1_iWideMult [15:8]*/
+ 0x0F120900, /*#AfitBaseVals_2__52_
+ AFIT8_demsharpmix1_iNarrMult [7:0],
+ AFIT8_demsharpmix1_iHystFalloff [15:8]*/
+ 0x0F120600, /*#AfitBaseVals_2__53_
+ AFIT8_demsharpmix1_iHystMinMult [7:0],
+ AFIT8_demsharpmix1_iHystWidth [15:8]*/
+ 0x0F120504, /*#AfitBaseVals_2__54_
+ AFIT8_demsharpmix1_iHystFallLow [7:0],
+ AFIT8_demsharpmix1_iHystFallHigh [15:8]*/
+ 0x0F120306, /*#AfitBaseVals_2__55_
+ AFIT8_demsharpmix1_iHystTune [7:0],
+ * AFIT8_YUV422_DENOISE_iUVSupport [15:8]*/
+ 0x0F128002, /*#AfitBaseVals_2__56_
+ AFIT8_YUV422_DENOISE_iYSupport [7:0],
+ AFIT8_byr_cgras_iShadingPower [15:8]*/
+ 0x0F120080, /*#AfitBaseVals_2__57_
+ AFIT8_RGBGamma2_iLinearity [7:0],
+ AFIT8_RGBGamma2_iDarkReduce [15:8]*/
+ 0x0F120080, /*#AfitBaseVals_2__58_
+ AFIT8_ccm_oscar_iSaturation[7:0],
+ AFIT8_RGB2YUV_iYOffset [15:8]*/
+ 0x0F120080, /*#AfitBaseVals_2__59_
+ AFIT8_RGB2YUV_iRGBGain [7:0],
+ AFIT8_RGB2YUV_iSaturation [15:8]*/
+ 0x0F125050, /*#AfitBaseVals_2__60_
+ AFIT8_sddd8a_iClustThresh_H [7:0],
+ AFIT8_sddd8a_iClustThresh_C [15:8]*/
+ 0x0F120101, /*#AfitBaseVals_2__61_
+ AFIT8_sddd8a_iClustMulT_H [7:0],
+ AFIT8_sddd8a_iClustMulT_C [15:8]*/
+ 0x0F121B01, /*#AfitBaseVals_2__62_
+ AFIT8_sddd8a_nClustLevel_H [7:0],
+ AFIT8_sddd8a_DispTH_Low [15:8]*/
+ 0x0F122319, /*#AfitBaseVals_2__63_
+ AFIT8_sddd8a_DispTH_High [7:0],
+ AFIT8_sddd8a_iDenThreshLow [15:8]*/
+ 0x0F12960F, /*#AfitBaseVals_2__64_
+ AFIT8_sddd8a_iDenThreshHigh[7:0],
+ AFIT8_Demosaicing_iEdgeDesat [15:8]*/
+ 0x0F120000, /*#AfitBaseVals_2__65_
+ AFIT8_Demosaicing_iEdgeDesatThrLow [7:0],
+ AFIT8_Demosaicing_iEdgeDesatThrHigh [15:8]*/
+ 0x0F122A03, /*#AfitBaseVals_2__66_
+ AFIT8_Demosaicing_iEdgeDesatLimit[7:0],
+ AFIT8_Demosaicing_iDemSharpenLow [15:8]*/
+ 0x0F120A02, /*#AfitBaseVals_2__67_
+ AFIT8_Demosaicing_iDemSharpenHigh[7:0],
+ AFIT8_Demosaicing_iDemSharpThresh [15:8]*/
+ 0x0F120864, /*#AfitBaseVals_2__68_
+ AFIT8_Demosaicing_iDemShLowLimit [7:0],
+ AFIT8_Demosaicing_iDespeckleForDemsharp [15:8]*/
+ 0x0F121432, /*#AfitBaseVals_2__69_
+ AFIT8_Demosaicing_iDemBlurLow[7:0],
+ AFIT8_Demosaicing_iDemBlurHigh [15:8]*/
+ 0x0F129601, /*#AfitBaseVals_2__70_
+ AFIT8_Demosaicing_iDemBlurRange[7:0],
+ AFIT8_Sharpening_iLowSharpPower [15:8]*/
+ 0x0F122814, /*#AfitBaseVals_2__71_
+ AFIT8_Sharpening_iHighSharpPower[7:0],
+ AFIT8_Sharpening_iLowShDenoise [15:8]*/
+ 0x0F12400A, /*#AfitBaseVals_2__72_
+ AFIT8_Sharpening_iHighShDenoise [7:0],
+ AFIT8_Sharpening_iReduceEdgeMinMult [15:8]*/
+ 0x0F120204, /*#AfitBaseVals_2__73_
+ AFIT8_Sharpening_iReduceEdgeSlope [7:0],
+ AFIT8_demsharpmix1_iWideFiltReduce [15:8]*/
+ 0x0F125003, /*#AfitBaseVals_2__74_
+ AFIT8_demsharpmix1_iNarrFiltReduce [7:0],
+ AFIT8_sddd8a_iClustThresh_H_Bin [15:8]*/
+ 0x0F120150, /*#AfitBaseVals_2__75_
+ AFIT8_sddd8a_iClustThresh_C_Bin [7:0],
+ AFIT8_sddd8a_iClustMulT_H_Bin [15:8]*/
+ 0x0F120101, /*#AfitBaseVals_2__76_
+ AFIT8_sddd8a_iClustMulT_C_Bin [7:0],
+ AFIT8_sddd8a_nClustLevel_H_Bin [15:8]*/
+ 0x0F12191B, /*#AfitBaseVals_2__77_
+ AFIT8_sddd8a_DispTH_Low_Bin [7:0],
+ AFIT8_sddd8a_DispTH_High_Bin [15:8]*/
+ 0x0F120D0F, /*#AfitBaseVals_2__78_
+ AFIT8_sddd8a_iDenThreshLow_Bin [7:0],
+ AFIT8_sddd8a_iDenThreshHigh_Bin [15:8]*/
+ 0x0F120028, /*#AfitBaseVals_2__79_
+ AFIT8_Demosaicing_iEdgeDesat_Bin[7:0],
+ AFIT8_Demosaicing_iEdgeDesatThrLow_Bin [15:8]*/
+ 0x0F120300, /*#AfitBaseVals_2__80_
+ AFIT8_Demosaicing_iEdgeDesatThrHigh_Bin [7:0],
+ AFIT8_Demosaicing_iEdgeDesatLimit_Bin [15:8]*/
+ 0x0F12021E, /*#AfitBaseVals_2__81_
+ AFIT8_Demosaicing_iDemSharpenLow_Bin [7:0],
+ AFIT8_Demosaicing_iDemSharpenHigh_Bin [15:8]*/
+ 0x0F121E0A, /*#AfitBaseVals_2__82_
+ AFIT8_Demosaicing_iDemSharpThresh_Bin [7:0],
+ AFIT8_Demosaicing_iDemShLowLimit_Bin [15:8]*/
+ 0x0F123208, /*#AfitBaseVals_2__83_
+ AFIT8_Demosaicing_iDespeckleForDemsharp_Bin [7:0],
+ AFIT8_Demosaicing_iDemBlurLow_Bin [15:8]*/
+ 0x0F120114, /*#AfitBaseVals_2__84_
+ AFIT8_Demosaicing_iDemBlurHigh_Bin [7:0],
+ AFIT8_Demosaicing_iDemBlurRange_Bin [15:8]*/
+ 0x0F121450, /*#AfitBaseVals_2__85_
+ AFIT8_Sharpening_iLowSharpPower_Bin [7:0],
+ AFIT8_Sharpening_iHighSharpPower_Bin [15:8]*/
+ 0x0F120A28, /*#AfitBaseVals_2__86_
+ AFIT8_Sharpening_iLowShDenoise_Bin [7:0],
+ AFIT8_Sharpening_iHighShDenoise_Bin [15:8]*/
+ 0x0F120440, /*#AfitBaseVals_2__87_
+ AFIT8_Sharpening_iReduceEdgeMinMult_Bin [7:0],
+ AFIT8_Sharpening_iReduceEdgeSlope_Bin [15:8]*/
+ 0x0F120302, /*#AfitBaseVals_2__88_
+ AFIT8_demsharpmix1_iWideFiltReduce_Bin [7:0],
+ AFIT8_demsharpmix1_iNarrFiltReduce_Bin [15:8]*/
+ 0x0F122828, /*#AfitBaseVals_2__89_
+ AFIT8_sddd8a_iClustThresh_H_sBin[7:0],
+ AFIT8_sddd8a_iClustThresh_C_sBin [15:8]*/
+ 0x0F120101, /*#AfitBaseVals_2__90_
+ AFIT8_sddd8a_iClustMulT_H_sBin [7:0],
+ AFIT8_sddd8a_iClustMulT_C_sBin [15:8]*/
+ 0x0F122401, /*#AfitBaseVals_2__91_
+ AFIT8_sddd8a_nClustLevel_H_sBin [7:0],
+ AFIT8_sddd8a_DispTH_Low_sBin [15:8]*/
+ 0x0F123622, /*#AfitBaseVals_2__92_
+ AFIT8_sddd8a_DispTH_High_sBin [7:0],
+ AFIT8_sddd8a_iDenThreshLow_sBin [15:8]*/
+ 0x0F122832, /*#AfitBaseVals_2__93_
+ AFIT8_sddd8a_iDenThreshHigh_sBin[7:0],
+ AFIT8_Demosaicing_iEdgeDesat_sBin [15:8]*/
+ 0x0F120A00, /*#AfitBaseVals_2__94_
+ AFIT8_Demosaicing_iEdgeDesatThrLow_sBin [7:0],
+ AFIT8_Demosaicing_iEdgeDesatThrHigh_sBin [15:8]*/
+ 0x0F121003, /*#AfitBaseVals_2__95_
+ AFIT8_Demosaicing_iEdgeDesatLimit_sBin [7:0],
+ AFIT8_Demosaicing_iDemSharpenLow_sBin [15:8]*/
+ 0x0F121E04, /*#AfitBaseVals_2__96_
+ AFIT8_Demosaicing_iDemSharpenHigh_sBin [7:0],
+ AFIT8_Demosaicing_iDemSharpThresh_sBin [15:8]*/
+ 0x0F120714, /*#AfitBaseVals_2__97_
+ AFIT8_Demosaicing_iDemShLowLimit_sBin [7:0],
+ AFIT8_Demosaicing_iDespeckleForDemsharp_sBin [15:8]*/
+ 0x0F1232FF, /*#AfitBaseVals_2__98_
+ AFIT8_Demosaicing_iDemBlurLow_sBin [7:0],
+ AFIT8_Demosaicing_iDemBlurHigh_sBin [15:8]*/
+ 0x0F125004, /*#AfitBaseVals_2__99_
+ AFIT8_Demosaicing_iDemBlurRange_sBin [7:0],
+ AFIT8_Sharpening_iLowSharpPower_sBin [15:8]*/
+ 0x0F120F40, /*#AfitBaseVals_2__100_
+ AFIT8_Sharpening_iHighSharpPower_sBin [7:0],
+ AFIT8_Sharpening_iLowShDenoise_sBin [15:8]*/
+ 0x0F12400F, /*#AfitBaseVals_2__101_
+ AFIT8_Sharpening_iHighShDenoise_sBin [7:0],
+ AFIT8_Sharpening_iReduceEdgeMinMult_sBin [15:8]*/
+ 0x0F120204, /*#AfitBaseVals_2__102_
+ AFIT8_Sharpening_iReduceEdgeSlope_sBin [7:0],
+ AFIT8_demsharpmix1_iWideFiltReduce_sBin [15:8]*/
+ 0x0F120003, /*#AfitBaseVals_2__103_
+ AFIT8_demsharpmix1_iNarrFiltReduce_sBin [7:0]*/
+ 0x0F120000, /*#AfitBaseVals_3__0_ AFIT16_BRIGHTNESS*/
+ 0x0F120000, /*#AfitBaseVals_3__1_ AFIT16_CONTRAST*/
+ 0x0F120000, /*#AfitBaseVals_3__2_ AFIT16_SATURATION*/
+ 0x0F120000, /*#AfitBaseVals_3__3_ AFIT16_SHARP_BLUR*/
+ 0x0F120000, /*#AfitBaseVals_3__4_ AFIT16_GLAMOUR*/
+ 0x0F1200C1, /*#AfitBaseVals_3__5_ AFIT16_sddd8a_edge_high*/
+ 0x0F1203FF, /*#AfitBaseVals_3__6_ AFIT16_Demosaicing_iSatVal*/
+ 0x0F12009C, /*#AfitBaseVals_3__7_
+ AFIT16_Sharpening_iReduceEdgeThresh*/
+ 0x0F12017C, /*#AfitBaseVals_3__8_ AFIT16_demsharpmix1_iRGBOffset*/
+ 0x0F1203FF, /*#AfitBaseVals_3__9_ AFIT16_demsharpmix1_iDemClamp*/
+ 0x0F12000C, /*#AfitBaseVals_3__10_
+ AFIT16_demsharpmix1_iLowThreshold*/
+ 0x0F120010, /*#AfitBaseVals_3__11_
+ AFIT16_demsharpmix1_iHighThreshold*/
+ 0x0F1200C8, /*#AfitBaseVals_3__12_AFIT16_demsharpmix1_iLowBright*/
+ 0x0F1203E8, /*#AfitBaseVals_3__13_AFIT16_demsharpmix1_iHighBright*/
+ 0x0F120046, /*#AfitBaseVals_3__14_AFIT16_demsharpmix1_iLowSat*/
+ 0x0F120050, /*#AfitBaseVals_3__15_AFIT16_demsharpmix1_iHighSat*/
+ 0x0F120070, /*#AfitBaseVals_3__16_AFIT16_demsharpmix1_iTune*/
+ 0x0F120008, /*#AfitBaseVals_3__17_AFIT16_demsharpmix1_iHystThLow*/
+ 0x0F120000, /*#AfitBaseVals_3__18_AFIT16_demsharpmix1_iHystThHigh*/
+ 0x0F120320, /*#AfitBaseVals_3__19_AFIT16_demsharpmix1_iHystCenter*/
+ 0x0F120032, /*#AfitBaseVals_3__20_
+ AFIT16_YUV422_DENOISE_iUVLowThresh*/
+ 0x0F120032, /*#AfitBaseVals_3__21_
+ AFIT16_YUV422_DENOISE_iUVHighThresh*/
+ 0x0F120000, /*#AfitBaseVals_3__22_
+ AFIT16_YUV422_DENOISE_iYLowThresh*/
+ 0x0F120000, /*#AfitBaseVals_3__23_
+ AFIT16_YUV422_DENOISE_iYHighThresh*/
+ 0x0F1200B4, /*#AfitBaseVals_3__24_
+ AFIT16_Sharpening_iLowSharpClamp*/
+ 0x0F120014, /*#AfitBaseVals_3__25_
+ AFIT16_Sharpening_iHighSharpClamp*/
+ 0x0F1200B4, /*#AfitBaseVals_3__26_
+ AFIT16_Sharpening_iLowSharpClamp_Bin*/
+ 0x0F120014, /*#AfitBaseVals_3__27_
+ AFIT16_Sharpening_iHighSharpClamp_Bin*/
+ 0x0F12002D, /*#AfitBaseVals_3__28_
+ AFIT16_Sharpening_iLowSharpClamp_sBin*/
+ 0x0F120019, /*#AfitBaseVals_3__29_
+ AFIT16_Sharpening_iHighSharpClamp_sBin*/
+ 0x0F120A24, /*#AfitBaseVals_3__30_
+ AFIT8_sddd8a_edge_low [7:0],
+ AFIT8_sddd8a_repl_thresh [15:8]*/
+ 0x0F121701, /*#AfitBaseVals_3__31_
+ AFIT8_sddd8a_repl_force [7:0],
+ AFIT8_sddd8a_sat_level [15:8]*/
+ 0x0F120229, /*#AfitBaseVals_3__32_
+ AFIT8_sddd8a_sat_thr[7:0],AFIT8_sddd8a_sat_mpl [15:8]*/
+ 0x0F121403, /*#AfitBaseVals_3__33_
+ AFIT8_sddd8a_sat_noise[7:0],
+ AFIT8_sddd8a_iMaxSlopeAllowed [15:8]*/
+ 0x0F120000, /*#AfitBaseVals_3__34_
+ AFIT8_sddd8a_iHotThreshHigh[7:0],
+ AFIT8_sddd8a_iHotThreshLow [15:8]*/
+ 0x0F120000, /*#AfitBaseVals_3__35_
+ AFIT8_sddd8a_iColdThreshHigh[7:0],
+ AFIT8_sddd8a_iColdThreshLow [15:8]*/
+ 0x0F120000, /*#AfitBaseVals_3__36_
+ AFIT8_sddd8a_AddNoisePower1[7:0],
+ AFIT8_sddd8a_AddNoisePower2 [15:8]*/
+ 0x0F1200FF, /*#AfitBaseVals_3__37_
+ AFIT8_sddd8a_iSatSat[7:0],
+ AFIT8_sddd8a_iRadialTune [15:8]*/
+ 0x0F12033B, /*#AfitBaseVals_3__38_
+ AFIT8_sddd8a_iRadialLimit [7:0],
+ AFIT8_sddd8a_iRadialPower [15:8]*/
+ 0x0F121414, /*#AfitBaseVals_3__39_
+ AFIT8_sddd8a_iLowMaxSlopeAllowed [7:0],
+ AFIT8_sddd8a_iHighMaxSlopeAllowed [15:8]*/
+ 0x0F120301, /*#AfitBaseVals_3__40_
+ AFIT8_sddd8a_iLowSlopeThresh[7:0],
+ AFIT8_sddd8a_iHighSlopeThresh [15:8]*/
+ 0x0F12FF07, /*#AfitBaseVals_3__41_
+ AFIT8_sddd8a_iSquaresRounding [7:0],
+ AFIT8_Demosaicing_iCentGrad [15:8]*/
+ 0x0F12081E, /*#AfitBaseVals_3__42_
+ AFIT8_Demosaicing_iMonochrom [7:0],
+ AFIT8_Demosaicing_iDecisionThresh [15:8]*/
+ 0x0F120A1E, /*#AfitBaseVals_3__43_
+ AFIT8_Demosaicing_iDesatThresh [7:0],
+ AFIT8_Demosaicing_iEnhThresh [15:8]*/
+ 0x0F120F0F, /*#AfitBaseVals_3__44_
+ AFIT8_Demosaicing_iGRDenoiseVal [7:0],
+ AFIT8_Demosaicing_iGBDenoiseVal [15:8]*/
+ 0x0F120A00, /*#AfitBaseVals_3__45_
+ AFIT8_Demosaicing_iNearGrayDesat[7:0],
+ AFIT8_Demosaicing_iDFD_ReduceCoeff [15:8]*/
+ 0x0F120012, /*#AfitBaseVals_3__46_
+ AFIT8_Sharpening_iMSharpen [7:0],
+ AFIT8_Sharpening_iMShThresh [15:8]*/
+ 0x0F120005, /*#AfitBaseVals_3__47_
+ AFIT8_Sharpening_iWSharpen [7:0],
+ AFIT8_Sharpening_iWShThresh [15:8]*/
+ 0x0F120001, /*#AfitBaseVals_3__48_
+ AFIT8_Sharpening_nSharpWidth [7:0],
+ AFIT8_Sharpening_iReduceNegative [15:8]*/
+ 0x0F1200FF, /*#AfitBaseVals_3__49_
+ AFIT8_Sharpening_iShDespeckle [7:0],
+ AFIT8_demsharpmix1_iRGBMultiplier [15:8]*/
+ 0x0F121002, /*#AfitBaseVals_3__50_
+ AFIT8_demsharpmix1_iFilterPower [7:0],
+ AFIT8_demsharpmix1_iBCoeff [15:8]*/
+ 0x0F12001E, /*#AfitBaseVals_3__51_
+ AFIT8_demsharpmix1_iGCoeff [7:0],
+ AFIT8_demsharpmix1_iWideMult [15:8]*/
+ 0x0F120900, /*#AfitBaseVals_3__52_
+ AFIT8_demsharpmix1_iNarrMult [7:0],
+ AFIT8_demsharpmix1_iHystFalloff [15:8]*/
+ 0x0F120600, /*#AfitBaseVals_3__53_
+ AFIT8_demsharpmix1_iHystMinMult [7:0],
+ AFIT8_demsharpmix1_iHystWidth [15:8]*/
+ 0x0F120504, /*#AfitBaseVals_3__54_
+ AFIT8_demsharpmix1_iHystFallLow [7:0],
+ AFIT8_demsharpmix1_iHystFallHigh [15:8]*/
+ 0x0F120307, /*#AfitBaseVals_3__55_
+ AFIT8_demsharpmix1_iHystTune [7:0],
+ * AFIT8_YUV422_DENOISE_iUVSupport [15:8]*/
+ 0x0F128002, /*#AfitBaseVals_3__56_
+ AFIT8_YUV422_DENOISE_iYSupport [7:0],
+ AFIT8_byr_cgras_iShadingPower [15:8]*/
+ 0x0F120080, /*#AfitBaseVals_3__57_
+ AFIT8_RGBGamma2_iLinearity [7:0],
+ AFIT8_RGBGamma2_iDarkReduce [15:8]*/
+ 0x0F120080, /*#AfitBaseVals_3__58_
+ AFIT8_ccm_oscar_iSaturation[7:0],
+ AFIT8_RGB2YUV_iYOffset [15:8]*/
+ 0x0F120080, /*#AfitBaseVals_3__59_
+ AFIT8_RGB2YUV_iRGBGain [7:0],
+ AFIT8_RGB2YUV_iSaturation [15:8]*/
+ 0x0F125050, /*#AfitBaseVals_3__60_
+ AFIT8_sddd8a_iClustThresh_H [7:0],
+ AFIT8_sddd8a_iClustThresh_C [15:8]*/
+ 0x0F120101, /*#AfitBaseVals_3__61_
+ AFIT8_sddd8a_iClustMulT_H [7:0],
+ AFIT8_sddd8a_iClustMulT_C [15:8]*/
+ 0x0F121B01, /*#AfitBaseVals_3__62_
+ AFIT8_sddd8a_nClustLevel_H [7:0],
+ AFIT8_sddd8a_DispTH_Low [15:8]*/
+ 0x0F122319, /*#AfitBaseVals_3__63_
+ AFIT8_sddd8a_DispTH_High [7:0],
+ AFIT8_sddd8a_iDenThreshLow [15:8]*/
+ 0x0F12960F, /*#AfitBaseVals_3__64_
+ AFIT8_sddd8a_iDenThreshHigh[7:0],
+ AFIT8_Demosaicing_iEdgeDesat [15:8]*/
+ 0x0F120000, /*#AfitBaseVals_3__65_
+ AFIT8_Demosaicing_iEdgeDesatThrLow [7:0],
+ AFIT8_Demosaicing_iEdgeDesatThrHigh [15:8]*/
+ 0x0F122003, /*#AfitBaseVals_3__66_
+ AFIT8_Demosaicing_iEdgeDesatLimit[7:0],
+ AFIT8_Demosaicing_iDemSharpenLow [15:8]*/
+ 0x0F120A02, /*#AfitBaseVals_3__67_
+ AFIT8_Demosaicing_iDemSharpenHigh[7:0],
+ AFIT8_Demosaicing_iDemSharpThresh [15:8]*/
+ 0x0F120864, /*#AfitBaseVals_3__68_
+ AFIT8_Demosaicing_iDemShLowLimit [7:0],
+ AFIT8_Demosaicing_iDespeckleForDemsharp [15:8]*/
+ 0x0F121432, /*#AfitBaseVals_3__69_
+ AFIT8_Demosaicing_iDemBlurLow[7:0],
+ AFIT8_Demosaicing_iDemBlurHigh [15:8]*/
+ 0x0F12A001, /*#AfitBaseVals_3__70_
+ AFIT8_Demosaicing_iDemBlurRange[7:0],
+ AFIT8_Sharpening_iLowSharpPower [15:8]*/
+ 0x0F122814, /*#AfitBaseVals_3__71_
+ AFIT8_Sharpening_iHighSharpPower[7:0],
+ AFIT8_Sharpening_iLowShDenoise [15:8]*/
+ 0x0F12400A, /*#AfitBaseVals_3__72_
+ AFIT8_Sharpening_iHighShDenoise [7:0],
+ AFIT8_Sharpening_iReduceEdgeMinMult [15:8]*/
+ 0x0F120204, /*#AfitBaseVals_3__73_
+ AFIT8_Sharpening_iReduceEdgeSlope [7:0],
+ AFIT8_demsharpmix1_iWideFiltReduce [15:8]*/
+ 0x0F125003, /*#AfitBaseVals_3__74_
+ AFIT8_demsharpmix1_iNarrFiltReduce [7:0],
+ AFIT8_sddd8a_iClustThresh_H_Bin [15:8]*/
+ 0x0F120150, /*#AfitBaseVals_3__75_
+ AFIT8_sddd8a_iClustThresh_C_Bin [7:0],
+ AFIT8_sddd8a_iClustMulT_H_Bin [15:8]*/
+ 0x0F120101, /*#AfitBaseVals_3__76_
+ AFIT8_sddd8a_iClustMulT_C_Bin [7:0],
+ AFIT8_sddd8a_nClustLevel_H_Bin [15:8]*/
+ 0x0F12191B, /*#AfitBaseVals_3__77_
+ AFIT8_sddd8a_DispTH_Low_Bin [7:0],
+ AFIT8_sddd8a_DispTH_High_Bin [15:8]*/
+ 0x0F120D0F, /*#AfitBaseVals_3__78_
+ AFIT8_sddd8a_iDenThreshLow_Bin [7:0],
+ AFIT8_sddd8a_iDenThreshHigh_Bin [15:8]*/
+ 0x0F120028, /*#AfitBaseVals_3__79_
+ AFIT8_Demosaicing_iEdgeDesat_Bin[7:0],
+ AFIT8_Demosaicing_iEdgeDesatThrLow_Bin [15:8]*/
+ 0x0F120300, /*#AfitBaseVals_3__80_
+ AFIT8_Demosaicing_iEdgeDesatThrHigh_Bin [7:0],
+ AFIT8_Demosaicing_iEdgeDesatLimit_Bin [15:8]*/
+ 0x0F12021E, /*#AfitBaseVals_3__81_
+ AFIT8_Demosaicing_iDemSharpenLow_Bin [7:0],
+ AFIT8_Demosaicing_iDemSharpenHigh_Bin [15:8]*/
+ 0x0F121E0A, /*#AfitBaseVals_3__82_
+ AFIT8_Demosaicing_iDemSharpThresh_Bin [7:0],
+ AFIT8_Demosaicing_iDemShLowLimit_Bin [15:8]*/
+ 0x0F123208, /*#AfitBaseVals_3__83_
+ AFIT8_Demosaicing_iDespeckleForDemsharp_Bin [7:0],
+ AFIT8_Demosaicing_iDemBlurLow_Bin [15:8]*/
+ 0x0F120114, /*#AfitBaseVals_3__84_
+ AFIT8_Demosaicing_iDemBlurHigh_Bin [7:0],
+ AFIT8_Demosaicing_iDemBlurRange_Bin [15:8]*/
+ 0x0F121450, /*#AfitBaseVals_3__85_
+ AFIT8_Sharpening_iLowSharpPower_Bin [7:0],
+ AFIT8_Sharpening_iHighSharpPower_Bin [15:8]*/
+ 0x0F120A28, /*#AfitBaseVals_3__86_
+ AFIT8_Sharpening_iLowShDenoise_Bin [7:0],
+ AFIT8_Sharpening_iHighShDenoise_Bin [15:8]*/
+ 0x0F120440, /*#AfitBaseVals_3__87_
+ AFIT8_Sharpening_iReduceEdgeMinMult_Bin [7:0],
+ AFIT8_Sharpening_iReduceEdgeSlope_Bin [15:8]*/
+ 0x0F120302, /*#AfitBaseVals_3__88_
+ AFIT8_demsharpmix1_iWideFiltReduce_Bin [7:0],
+ AFIT8_demsharpmix1_iNarrFiltReduce_Bin [15:8]*/
+ 0x0F123C3C, /*#AfitBaseVals_3__89_
+ AFIT8_sddd8a_iClustThresh_H_sBin[7:0],
+ AFIT8_sddd8a_iClustThresh_C_sBin [15:8]*/
+ 0x0F120101, /*#AfitBaseVals_3__90_
+ AFIT8_sddd8a_iClustMulT_H_sBin [7:0],
+ AFIT8_sddd8a_iClustMulT_C_sBin [15:8]*/
+ 0x0F121E01, /*#AfitBaseVals_3__91_
+ AFIT8_sddd8a_nClustLevel_H_sBin [7:0],
+ AFIT8_sddd8a_DispTH_Low_sBin [15:8]*/
+ 0x0F12221C, /*#AfitBaseVals_3__92_
+ AFIT8_sddd8a_DispTH_High_sBin [7:0],
+ AFIT8_sddd8a_iDenThreshLow_sBin [15:8]*/
+ 0x0F12281E, /*#AfitBaseVals_3__93_
+ AFIT8_sddd8a_iDenThreshHigh_sBin[7:0],
+ AFIT8_Demosaicing_iEdgeDesat_sBin [15:8]*/
+ 0x0F120A00, /*#AfitBaseVals_3__94_
+ AFIT8_Demosaicing_iEdgeDesatThrLow_sBin [7:0],
+ AFIT8_Demosaicing_iEdgeDesatThrHigh_sBin [15:8]*/
+ 0x0F121403, /*#AfitBaseVals_3__95_
+ AFIT8_Demosaicing_iEdgeDesatLimit_sBin [7:0],
+ AFIT8_Demosaicing_iDemSharpenLow_sBin [15:8]*/
+ 0x0F121402, /*#AfitBaseVals_3__96_
+ AFIT8_Demosaicing_iDemSharpenHigh_sBin [7:0],
+ AFIT8_Demosaicing_iDemSharpThresh_sBin [15:8]*/
+ 0x0F12060E, /*#AfitBaseVals_3__97_
+ AFIT8_Demosaicing_iDemShLowLimit_sBin [7:0],
+ AFIT8_Demosaicing_iDespeckleForDemsharp_sBin [15:8]*/
+ 0x0F1232FF, /*#AfitBaseVals_3__98_
+ AFIT8_Demosaicing_iDemBlurLow_sBin [7:0],
+ AFIT8_Demosaicing_iDemBlurHigh_sBin [15:8]*/
+ 0x0F125204, /*#AfitBaseVals_3__99_
+ AFIT8_Demosaicing_iDemBlurRange_sBin [7:0],
+ AFIT8_Sharpening_iLowSharpPower_sBin [15:8]*/
+ 0x0F120C40, /*#AfitBaseVals_3__100_
+ AFIT8_Sharpening_iHighSharpPower_sBin [7:0],
+ AFIT8_Sharpening_iLowShDenoise_sBin [15:8]*/
+ 0x0F124015, /*#AfitBaseVals_3__101_
+ AFIT8_Sharpening_iHighShDenoise_sBin [7:0],
+ AFIT8_Sharpening_iReduceEdgeMinMult_sBin [15:8]*/
+ 0x0F120204, /*#AfitBaseVals_3__102_
+ AFIT8_Sharpening_iReduceEdgeSlope_sBin [7:0],
+ AFIT8_demsharpmix1_iWideFiltReduce_sBin [15:8]*/
+ 0x0F120003, /*#AfitBaseVals_3__103_
+ AFIT8_demsharpmix1_iNarrFiltReduce_sBin [7:0]*/
+ 0x0F120000, /*#AfitBaseVals_4__0_ AFIT16_BRIGHTNESS*/
+ 0x0F120000, /*#AfitBaseVals_4__1_ AFIT16_CONTRAST*/
+ 0x0F120000, /*#AfitBaseVals_4__2_ AFIT16_SATURATION*/
+ 0x0F120000, /*#AfitBaseVals_4__3_ AFIT16_SHARP_BLUR*/
+ 0x0F120000, /*#AfitBaseVals_4__4_ AFIT16_GLAMOUR*/
+ 0x0F1200C1, /*#AfitBaseVals_4__5_ AFIT16_sddd8a_edge_high*/
+ 0x0F1203FF, /*#AfitBaseVals_4__6_ AFIT16_Demosaicing_iSatVal*/
+ 0x0F12009C, /*#AfitBaseVals_4__7_
+ AFIT16_Sharpening_iReduceEdgeThresh*/
+ 0x0F12017C, /*#AfitBaseVals_4__8_ AFIT16_demsharpmix1_iRGBOffset*/
+ 0x0F1203FF, /*#AfitBaseVals_4__9_ AFIT16_demsharpmix1_iDemClamp*/
+ 0x0F12000C, /*#AfitBaseVals_4__10_
+ AFIT16_demsharpmix1_iLowThreshold*/
+ 0x0F120010, /*#AfitBaseVals_4__11_
+ AFIT16_demsharpmix1_iHighThreshold*/
+ 0x0F120032, /*#AfitBaseVals_4__12_AFIT16_demsharpmix1_iLowBright*/
+ 0x0F12028A, /*#AfitBaseVals_4__13_AFIT16_demsharpmix1_iHighBright*/
+ 0x0F120032, /*#AfitBaseVals_4__14_AFIT16_demsharpmix1_iLowSat*/
+ 0x0F1201F4, /*#AfitBaseVals_4__15_AFIT16_demsharpmix1_iHighSat*/
+ 0x0F120070, /*#AfitBaseVals_4__16_AFIT16_demsharpmix1_iTune*/
+ 0x0F120002, /*#AfitBaseVals_4__17_AFIT16_demsharpmix1_iHystThLow*/
+ 0x0F120000, /*#AfitBaseVals_4__18_AFIT16_demsharpmix1_iHystThHigh*/
+ 0x0F1201AA, /*#AfitBaseVals_4__19_AFIT16_demsharpmix1_iHystCenter*/
+ 0x0F12003C, /*#AfitBaseVals_4__20_
+ AFIT16_YUV422_DENOISE_iUVLowThresh*/
+ 0x0F120050, /*#AfitBaseVals_4__21_
+ AFIT16_YUV422_DENOISE_iUVHighThresh*/
+ 0x0F120000, /*#AfitBaseVals_4__22_
+ AFIT16_YUV422_DENOISE_iYLowThresh*/
+ 0x0F120000, /*#AfitBaseVals_4__23_
+ AFIT16_YUV422_DENOISE_iYHighThresh*/
+ 0x0F1200B4, /*#AfitBaseVals_4__24_
+ AFIT16_Sharpening_iLowSharpClamp*/
+ 0x0F120014, /*#AfitBaseVals_4__25_
+ AFIT16_Sharpening_iHighSharpClamp*/
+ 0x0F1200B4, /*#AfitBaseVals_4__26_
+ AFIT16_Sharpening_iLowSharpClamp_Bin*/
+ 0x0F120014, /*#AfitBaseVals_4__27_
+ AFIT16_Sharpening_iHighSharpClamp_Bin*/
+ 0x0F120046, /*#AfitBaseVals_4__28_
+ AFIT16_Sharpening_iLowSharpClamp_sBin*/
+ 0x0F120019, /*#AfitBaseVals_4__29_
+ AFIT16_Sharpening_iHighSharpClamp_sBin*/
+ 0x0F120A24, /*#AfitBaseVals_4__30_
+ AFIT8_sddd8a_edge_low [7:0],
+ AFIT8_sddd8a_repl_thresh [15:8]*/
+ 0x0F121701, /*#AfitBaseVals_4__31_
+ AFIT8_sddd8a_repl_force [7:0],
+ AFIT8_sddd8a_sat_level [15:8]*/
+ 0x0F120229, /*#AfitBaseVals_4__32_
+ AFIT8_sddd8a_sat_thr[7:0],
+ AFIT8_sddd8a_sat_mpl [15:8]*/
+ 0x0F120503, /*#AfitBaseVals_4__33_
+ AFIT8_sddd8a_sat_noise[7:0],
+ AFIT8_sddd8a_iMaxSlopeAllowed [15:8]*/
+ 0x0F12080F, /*#AfitBaseVals_4__34_
+ AFIT8_sddd8a_iHotThreshHigh[7:0],
+ AFIT8_sddd8a_iHotThreshLow [15:8]*/
+ 0x0F120808, /*#AfitBaseVals_4__35_
+ AFIT8_sddd8a_iColdThreshHigh[7:0],
+ AFIT8_sddd8a_iColdThreshLow [15:8]*/
+ 0x0F120000, /*#AfitBaseVals_4__36_
+ AFIT8_sddd8a_AddNoisePower1[7:0],
+ AFIT8_sddd8a_AddNoisePower2 [15:8]*/
+ 0x0F1200FF, /*#AfitBaseVals_4__37_
+ AFIT8_sddd8a_iSatSat[7:0],
+ AFIT8_sddd8a_iRadialTune [15:8]*/
+ 0x0F12022D, /*#AfitBaseVals_4__38_
+ AFIT8_sddd8a_iRadialLimit [7:0],
+ AFIT8_sddd8a_iRadialPower [15:8]*/
+ 0x0F121414, /*#AfitBaseVals_4__39_
+ AFIT8_sddd8a_iLowMaxSlopeAllowed [7:0],
+ AFIT8_sddd8a_iHighMaxSlopeAllowed [15:8]*/
+ 0x0F120301, /*#AfitBaseVals_4__40_
+ AFIT8_sddd8a_iLowSlopeThresh[7:0],
+ AFIT8_sddd8a_iHighSlopeThresh [15:8]*/
+ 0x0F12FF07, /*#AfitBaseVals_4__41_
+ AFIT8_sddd8a_iSquaresRounding [7:0],
+ AFIT8_Demosaicing_iCentGrad [15:8]*/
+ 0x0F12061E, /*#AfitBaseVals_4__42_
+ AFIT8_Demosaicing_iMonochrom [7:0],
+ AFIT8_Demosaicing_iDecisionThresh [15:8]*/
+ 0x0F120A1E, /*#AfitBaseVals_4__43_
+ AFIT8_Demosaicing_iDesatThresh [7:0],
+ AFIT8_Demosaicing_iEnhThresh [15:8]*/
+ 0x0F120606, /*#AfitBaseVals_4__44_
+ AFIT8_Demosaicing_iGRDenoiseVal [7:0],
+ AFIT8_Demosaicing_iGBDenoiseVal [15:8]*/
+ 0x0F120A03, /*#AfitBaseVals_4__45_
+ AFIT8_Demosaicing_iNearGrayDesat[7:0],
+ AFIT8_Demosaicing_iDFD_ReduceCoeff [15:8]*/
+ 0x0F120028, /*#AfitBaseVals_4__46_
+ AFIT8_Sharpening_iMSharpen [7:0],
+ AFIT8_Sharpening_iMShThresh [15:8]*/
+ 0x0F120002, /*#AfitBaseVals_4__47_
+ AFIT8_Sharpening_iWSharpen [7:0],
+ AFIT8_Sharpening_iWShThresh [15:8]*/
+ 0x0F120001, /*#AfitBaseVals_4__48_
+ AFIT8_Sharpening_nSharpWidth [7:0],
+ AFIT8_Sharpening_iReduceNegative [15:8]*/
+ 0x0F1200FF, /*#AfitBaseVals_4__49_
+ AFIT8_Sharpening_iShDespeckle [7:0],
+ AFIT8_demsharpmix1_iRGBMultiplier [15:8]*/
+ 0x0F121002, /*#AfitBaseVals_4__50_
+ AFIT8_demsharpmix1_iFilterPower [7:0],
+ AFIT8_demsharpmix1_iBCoeff [15:8]*/
+ 0x0F12001E, /*#AfitBaseVals_4__51_
+ AFIT8_demsharpmix1_iGCoeff [7:0],
+ AFIT8_demsharpmix1_iWideMult [15:8]*/
+ 0x0F120900, /*#AfitBaseVals_4__52_
+ AFIT8_demsharpmix1_iNarrMult [7:0],
+ AFIT8_demsharpmix1_iHystFalloff [15:8]*/
+ 0x0F120600, /*#AfitBaseVals_4__53_
+ AFIT8_demsharpmix1_iHystMinMult [7:0],
+ AFIT8_demsharpmix1_iHystWidth [15:8]*/
+ 0x0F120504, /*#AfitBaseVals_4__54_
+ AFIT8_demsharpmix1_iHystFallLow [7:0],
+ AFIT8_demsharpmix1_iHystFallHigh [15:8]*/
+ 0x0F120307, /*#AfitBaseVals_4__55_
+ AFIT8_demsharpmix1_iHystTune [7:0],
+ * AFIT8_YUV422_DENOISE_iUVSupport [15:8]*/
+ 0x0F128001, /*#AfitBaseVals_4__56_
+ AFIT8_YUV422_DENOISE_iYSupport [7:0],
+ AFIT8_byr_cgras_iShadingPower [15:8]*/
+ 0x0F120080, /*#AfitBaseVals_4__57_
+ AFIT8_RGBGamma2_iLinearity [7:0],
+ AFIT8_RGBGamma2_iDarkReduce [15:8]*/
+ 0x0F120080, /*#AfitBaseVals_4__58_
+ AFIT8_ccm_oscar_iSaturation[7:0],
+ AFIT8_RGB2YUV_iYOffset [15:8]*/
+ 0x0F120080, /*#AfitBaseVals_4__59_
+ AFIT8_RGB2YUV_iRGBGain [7:0],
+ AFIT8_RGB2YUV_iSaturation [15:8]*/
+ 0x0F125050, /*#AfitBaseVals_4__60_
+ AFIT8_sddd8a_iClustThresh_H [7:0],
+ AFIT8_sddd8a_iClustThresh_C [15:8]*/
+ 0x0F120101, /*#AfitBaseVals_4__61_
+ AFIT8_sddd8a_iClustMulT_H [7:0],
+ AFIT8_sddd8a_iClustMulT_C [15:8]*/
+ 0x0F121B01, /*#AfitBaseVals_4__62_
+ AFIT8_sddd8a_nClustLevel_H [7:0],
+ AFIT8_sddd8a_DispTH_Low [15:8]*/
+ 0x0F121219, /*#AfitBaseVals_4__63_
+ AFIT8_sddd8a_DispTH_High [7:0],
+ AFIT8_sddd8a_iDenThreshLow [15:8]*/
+ 0x0F12320D, /*#AfitBaseVals_4__64_
+ AFIT8_sddd8a_iDenThreshHigh[7:0],
+ AFIT8_Demosaicing_iEdgeDesat [15:8]*/
+ 0x0F120A0A, /*#AfitBaseVals_4__65_
+ AFIT8_Demosaicing_iEdgeDesatThrLow [7:0],
+ AFIT8_Demosaicing_iEdgeDesatThrHigh [15:8]*/
+ 0x0F122304, /*#AfitBaseVals_4__66_
+ AFIT8_Demosaicing_iEdgeDesatLimit[7:0],
+ AFIT8_Demosaicing_iDemSharpenLow [15:8]*/
+ 0x0F120A08, /*#AfitBaseVals_4__67_
+ AFIT8_Demosaicing_iDemSharpenHigh[7:0],
+ AFIT8_Demosaicing_iDemSharpThresh [15:8]*/
+ 0x0F120832, /*#AfitBaseVals_4__68_
+ AFIT8_Demosaicing_iDemShLowLimit [7:0],
+ AFIT8_Demosaicing_iDespeckleForDemsharp [15:8]*/
+ 0x0F121432, /*#AfitBaseVals_4__69_
+ AFIT8_Demosaicing_iDemBlurLow[7:0],
+ AFIT8_Demosaicing_iDemBlurHigh [15:8]*/
+ 0x0F12A001, /*#AfitBaseVals_4__70_
+ AFIT8_Demosaicing_iDemBlurRange[7:0],
+ AFIT8_Sharpening_iLowSharpPower [15:8]*/
+ 0x0F122A0A, /*#AfitBaseVals_4__71_
+ AFIT8_Sharpening_iHighSharpPower[7:0],
+ AFIT8_Sharpening_iLowShDenoise [15:8]*/
+ 0x0F124006, /*#AfitBaseVals_4__72_
+ AFIT8_Sharpening_iHighShDenoise [7:0],
+ AFIT8_Sharpening_iReduceEdgeMinMult [15:8]*/
+ 0x0F120604, /*#AfitBaseVals_4__73_
+ AFIT8_Sharpening_iReduceEdgeSlope [7:0],
+ AFIT8_demsharpmix1_iWideFiltReduce [15:8]*/
+ 0x0F125006, /*#AfitBaseVals_4__74_
+ AFIT8_demsharpmix1_iNarrFiltReduce [7:0],
+ AFIT8_sddd8a_iClustThresh_H_Bin [15:8]*/
+ 0x0F120150, /*#AfitBaseVals_4__75_
+ AFIT8_sddd8a_iClustThresh_C_Bin [7:0],
+ AFIT8_sddd8a_iClustMulT_H_Bin [15:8]*/
+ 0x0F120101, /*#AfitBaseVals_4__76_
+ AFIT8_sddd8a_iClustMulT_C_Bin [7:0],
+ AFIT8_sddd8a_nClustLevel_H_Bin [15:8]*/
+ 0x0F12191B, /*#AfitBaseVals_4__77_
+ AFIT8_sddd8a_DispTH_Low_Bin [7:0],
+ AFIT8_sddd8a_DispTH_High_Bin [15:8]*/
+ 0x0F120D0F, /*#AfitBaseVals_4__78_
+ AFIT8_sddd8a_iDenThreshLow_Bin [7:0],
+ AFIT8_sddd8a_iDenThreshHigh_Bin [15:8]*/
+ 0x0F120A28, /*#AfitBaseVals_4__79_
+ AFIT8_Demosaicing_iEdgeDesat_Bin[7:0],
+ AFIT8_Demosaicing_iEdgeDesatThrLow_Bin [15:8]*/
+ 0x0F12040A, /*#AfitBaseVals_4__80_
+ AFIT8_Demosaicing_iEdgeDesatThrHigh_Bin [7:0],
+ AFIT8_Demosaicing_iEdgeDesatLimit_Bin [15:8]*/
+ 0x0F120820, /*#AfitBaseVals_4__81_
+ AFIT8_Demosaicing_iDemSharpenLow_Bin [7:0],
+ AFIT8_Demosaicing_iDemSharpenHigh_Bin [15:8]*/
+ 0x0F12280A, /*#AfitBaseVals_4__82_
+ AFIT8_Demosaicing_iDemSharpThresh_Bin [7:0],
+ AFIT8_Demosaicing_iDemShLowLimit_Bin [15:8]*/
+ 0x0F123208, /*#AfitBaseVals_4__83_
+ AFIT8_Demosaicing_iDespeckleForDemsharp_Bin [7:0],
+ AFIT8_Demosaicing_iDemBlurLow_Bin [15:8]*/
+ 0x0F120114, /*#AfitBaseVals_4__84_
+ AFIT8_Demosaicing_iDemBlurHigh_Bin [7:0],
+ AFIT8_Demosaicing_iDemBlurRange_Bin [15:8]*/
+ 0x0F120A64, /*#AfitBaseVals_4__85_
+ AFIT8_Sharpening_iLowSharpPower_Bin [7:0],
+ AFIT8_Sharpening_iHighSharpPower_Bin [15:8]*/
+ 0x0F12062A, /*#AfitBaseVals_4__86_
+ AFIT8_Sharpening_iLowShDenoise_Bin [7:0],
+ AFIT8_Sharpening_iHighShDenoise_Bin [15:8]*/
+ 0x0F120440, /*#AfitBaseVals_4__87_
+ AFIT8_Sharpening_iReduceEdgeMinMult_Bin [7:0],
+ AFIT8_Sharpening_iReduceEdgeSlope_Bin [15:8]*/
+ 0x0F120606, /*#AfitBaseVals_4__88_
+ AFIT8_demsharpmix1_iWideFiltReduce_Bin [7:0],
+ AFIT8_demsharpmix1_iNarrFiltReduce_Bin [15:8]*/
+ 0x0F124646, /*#AfitBaseVals_4__89_
+ AFIT8_sddd8a_iClustThresh_H_sBin[7:0],
+ AFIT8_sddd8a_iClustThresh_C_sBin [15:8]*/
+ 0x0F120101, /*#AfitBaseVals_4__90_
+ AFIT8_sddd8a_iClustMulT_H_sBin [7:0],
+ AFIT8_sddd8a_iClustMulT_C_sBin [15:8]*/
+ 0x0F121801, /*#AfitBaseVals_4__91_
+ AFIT8_sddd8a_nClustLevel_H_sBin [7:0],
+ AFIT8_sddd8a_DispTH_Low_sBin [15:8]*/
+ 0x0F12191C, /*#AfitBaseVals_4__92_
+ AFIT8_sddd8a_DispTH_High_sBin [7:0],
+ AFIT8_sddd8a_iDenThreshLow_sBin [15:8]*/
+ 0x0F122818, /*#AfitBaseVals_4__93_
+ AFIT8_sddd8a_iDenThreshHigh_sBin[7:0],
+ AFIT8_Demosaicing_iEdgeDesat_sBin [15:8]*/
+ 0x0F120A00, /*#AfitBaseVals_4__94_
+ AFIT8_Demosaicing_iEdgeDesatThrLow_sBin [7:0],
+ AFIT8_Demosaicing_iEdgeDesatThrHigh_sBin [15:8]*/
+ 0x0F121403, /*#AfitBaseVals_4__95_
+ AFIT8_Demosaicing_iEdgeDesatLimit_sBin [7:0],
+ AFIT8_Demosaicing_iDemSharpenLow_sBin [15:8]*/
+ 0x0F121405, /*#AfitBaseVals_4__96_
+ AFIT8_Demosaicing_iDemSharpenHigh_sBin [7:0],
+ AFIT8_Demosaicing_iDemSharpThresh_sBin [15:8]*/
+ 0x0F12050C, /*#AfitBaseVals_4__97_
+ AFIT8_Demosaicing_iDemShLowLimit_sBin [7:0],
+ AFIT8_Demosaicing_iDespeckleForDemsharp_sBin [15:8]*/
+ 0x0F1232FF, /*#AfitBaseVals_4__98_
+ AFIT8_Demosaicing_iDemBlurLow_sBin [7:0],
+ AFIT8_Demosaicing_iDemBlurHigh_sBin [15:8]*/
+ 0x0F125204, /*#AfitBaseVals_4__99_
+ AFIT8_Demosaicing_iDemBlurRange_sBin [7:0],
+ AFIT8_Sharpening_iLowSharpPower_sBin [15:8]*/
+ 0x0F121440, /*#AfitBaseVals_4__100_
+ AFIT8_Sharpening_iHighSharpPower_sBin [7:0],
+ AFIT8_Sharpening_iLowShDenoise_sBin [15:8]*/
+ 0x0F124015, /*#AfitBaseVals_4__101_
+ AFIT8_Sharpening_iHighShDenoise_sBin [7:0],
+ AFIT8_Sharpening_iReduceEdgeMinMult_sBin [15:8]*/
+ 0x0F120204, /*#AfitBaseVals_4__102_
+ AFIT8_Sharpening_iReduceEdgeSlope_sBin [7:0],
+ AFIT8_demsharpmix1_iWideFiltReduce_sBin [15:8]*/
+ 0x0F120003, /*#AfitBaseVals_4__103_
+ AFIT8_demsharpmix1_iNarrFiltReduce_sBin [7:0]*/
+ /* param_end TVAR_afit_pBaseVals*/
+ /* param_start afit_pConstBaseVals*/
+ 0x0F127DFA, /*#ConstAfitBaseVals Because of Edge,
+ disable the iGradientWide*/
+ 0x0F12FFBD, /*#ConstAfitBaseVals_1_*/
+ 0x0F1226FE, /*#ConstAfitBaseVals_2_*/
+ 0x0F12F7BC, /*#ConstAfitBaseVals_3_*/
+ 0x0F127E06, /*#ConstAfitBaseVals_4_*/
+ 0x0F1200D3, /*#ConstAfitBaseVals_5_*/
+ /* param_end afit_pConstBaseVals*/
+ /* AFIT by Normalized Brightness Tuning parameter*/
+ 0x002A3780,
+ 0x0F120000, /* on/off AFIT by NB option 0000 : Ni 0001:Nb*/
+ 0x0F120014, /* NormBR[0]*/
+ 0x002A3782,
+ 0x0F1200D2, /* NormBR[1]*/
+ 0x002A3782,
+ 0x0F120384, /* NormBR[2]*/
+ 0x002A3782,
+ 0x0F1207D0, /* NormBR[3]*/
+ 0x002A3782,
+ 0x0F121388, /* NormBR[4]*/
+
+};
+
+/*===========================================
+* CAMERA_PREVIEW - ? ? *
+============================================*/
+
+static const u32 s5k5bbgx_preview[] = {
+ /*PREVIEW*/
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A0156, /*#REG_TC_GP_ActivePrevConfig*/
+ 0x0F120000,
+ 0x002A015E, /*#REG_TC_GP_ActiveCapConfig*/
+ 0x0F120000,
+ 0x002A015A, /*#REG_TC_GP_PrevOpenAfterChange*/
+ 0x0F120001,
+ 0x002A0142, /*#REG_TC_GP_NewConfigSync*/
+ 0x0F120001,
+ 0x002A0158, /*#REG_TC_GP_PrevConfigChanged*/
+ 0x0F120001,
+ 0x002A0160, /*#REG_TC_GP_CapConfigChanged*/
+ 0x0F120001,
+ 0x002A013A, /*#REG_TC_GP_EnablePreview*/
+ 0x0F120001,
+ 0x002A013C, /*#REG_TC_GP_EnablePreviewChanged*/
+ 0x0F120001,
+ 0xffff0096, /* 150ms */
+};
+
+/*===========================================
+* CAMERA_SNAPSHOT - ? *
+============================================*/
+
+static const u32 s5k5bbgx_capture[] = {
+ /*Capture*/
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A015E, /*#REG_TC_GP_ActiveCapConfig*/
+ 0x0F120000,
+ 0x002A0142, /*#REG_TC_GP_NewConfigSync*/
+ 0x0F120001,
+ 0x002A0160, /*#REG_TC_GP_CapConfigChanged*/
+ 0x0F120001,
+ 0x002A013E, /*#REG_TC_GP_EnableCapture*/
+ 0x0F120001,
+ 0x002A0140, /*#REG_TC_GP_EnableCaptureChanged*/
+ 0x0F120001,
+ 0xffff0096, /* 150ms */
+};
+
+static const u32 s5k5bbgx_mode_check_capture_staus[] = {
+ 0x002C7000,
+ 0x002E0142,
+};
+
+static const u32 s5k5bbgx_recording_common[] = {
+ 0xFCFCD000,
+ 0x00100001, /*S/W Reset*/
+ 0x10300000, /*contint_host_int*/
+ 0x00140001, /*sw_load_complete - Release CORE (Arm) from reset state*/
+ 0xFFFF000A,
+
+ /*0x0028D000,*/ /*Driving Current*/
+ /*0x002A1082,*/
+ /*0x0F1203ff,*/ /*cregs_d0_d4_cd10 D4[9:8], D3[7:6], D2[5:4],
+ D1[3:2], D0[1:0]*/
+ /*0x002A1084,*/
+ /*0x0F1203ff,*/ /*cregs_d5_d9_cd10 D9[9:8], D8[7:6], D7[5:4],
+ D6[3:2], D5[1:0]*/
+ /*0x002A1088,*/
+ /*0x0F120fcf,*/ /*cregs_clks_output_cd10 SDA[11:10], SCL[9:8],
+ PCLK[7:6], VSYNC[3:2], HSYNC[1:0]*/
+
+ 0x0028D000,
+ 0x002AF404,
+ 0x0F120038, /*aig_adc_sat[7:0] : 850mV*/
+ 0x0F120001, /*ms[2:0]; 2h@Normal, 2h@PLA, 1h@CNT.AVG*/
+ 0x0F12000C, /*aig_sig_mx[5:0]*/
+ 0x0F120006, /*aig_rst_mx[5:0]*/
+ 0x0F120008, /*rmp_option[7:0]; [3]SL_Low_PWR_SAVE On*/
+ 0x002AF418,
+ 0x0F120003, /*aig_dbr_clk_sel[1:0]*/
+ 0x002AF41C,
+ 0x0F120140, /*aig_bist_sig_width_e[10:0]*/
+ 0x0F120140, /*aig_bist_sig_width_o[10:0]*/
+ 0x0F120066, /*aig_bist_sig_width_o[10:0]*/
+ 0x0F120005, /*aig_pix_bias[3:0]*/
+ 0x002AF426,
+ 0x0F1200D4, /*aig_clp_lvl[7:0]*/
+ 0x002AF42A,
+ 0x0F120001, /*aig_ref_option[0] SL_Low_PWR_SAVE On*/
+ 0x002AF430,
+ 0x0F120001, /*aig_pd_cp_rosc[0]*/
+ 0x0F120001, /*aig_pd_ncp_rosc[0]*/
+ 0x002AF43A,
+ 0x0F120000, /*aig_pd_fblv[0]*/
+ 0x002AF440,
+ 0x0F120044, /*aig_rosc_tune_ncp[7:4] aig_rosc_tune_cp[3:0]*/
+ 0x002AF44A,
+ 0x0F120000, /*aig_fb_lv[1:0]*/
+ 0x002AF45C,
+ 0x0F120000, /*aig_dshut_en[0]*/
+ 0x0F120000, /*aig_srx_en[0]*/
+ 0x002AF462,
+ 0x0F120001, /*aig_pdb_atop[0]*/
+ 0x002AF46E,
+ 0x0F121F02, /*aig_cds_test[15:0]*/
+ 0x002AF474,
+ 0x0F12000E, /*aig_stx_gap[4:0]*/
+ 0x002AE42E,
+ 0x0F120004, /*adlc_qec[2:0]*/
+ 0x00287000,
+ 0x002A13E0,
+ 0x0F120000, /*senHal_bSRX SRX OFF*/
+ 0x002A13C8,
+ 0x0F120001, /*senHal_bSenAAC AAC Enable*/
+ 0x002A12D8,
+ 0x0F120464, /*senHal_ContPtrs_senModesDataArr[78]*/
+ 0x0F120468, /*senHal_ContPtrs_senModesDataArr[79]*/
+ 0x002A12F6,
+ 0x0F120000, /*senHal_ContPtrs_senModesDataArr[93]*/
+ 0x002A13CC,
+ 0x0F121FC0, /*senHal_bSen11ADLC [12:0] : Write tuning value to E404
+ register*/
+ 0x002A13EC,
+ 0x0F120001, /*senHal_DarklevelTuneMode*/
+ 0x002A184C,
+ 0x0F121EE1,
+ 0x00287000,
+ 0x002A040E,
+ 0x0F120003, /*skl_usConfigStbySettings*/
+ 0xFFFF000A,
+ 0x002A1218,
+ 0x0F120002, /*senHal_SenBinFactor*/
+ 0x0F120002, /*senHal_SamplingType*/
+ 0x002A0C9A,
+ 0x0F120001, /*setot_bUseDigitalHbin*/
+ 0x002A1438,
+ 0x0F12F468, /*senHal_TuneStr_AngTuneData1[0]*/
+ 0x0F120000, /*senHal_TuneStr_AngTuneData1[1] not use binninb block
+ 0x0000 ,use binnin blcok 0x0000*/
+ 0x0F120008, /*senHal_TuneStr_AngTuneData1[2] not use binninb block
+ 0x000A ,use binnin blcok 0x0008*/
+ 0x0F120006, /*senHal_TuneStr_AngTuneData1[3] not use binninb block
+ 0x0005 ,use binnin blcok 0x0006*/
+ 0x0F120000, /*senHal_TuneStr_AngTuneData1[4]*/
+ 0xFFFF000A,
+ 0x002A0416,
+ 0x0F12F400, /*skl_usStbyBackupReg[0][0]*/
+ 0x0F120074, /*skl_usStbyBackupReg[0][1]*/
+ 0x0F12E42E, /*skl_usStbyBackupReg[1][0]*/
+ 0x0F120030, /*skl_usStbyBackupReg[1][1]*/
+ 0x002A378C,
+ 0x0F120000, /* On/off regiSter bUSeOTP*/
+ 0x002A0AD8,
+ 0x0F120F00,
+ 0x0F120000,
+ 0x0F12000F,
+ 0x0F120F0F,
+ 0x0F120F00,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F12000F,
+ 0x0F120F0F,
+ 0x0F120F00,
+ 0x0F120F00,
+ 0x0F12000F,
+ 0x0F120F0F,
+ 0x0F120000,
+ 0x0F120F0F,
+ 0x0F120000,
+ 0x0F12000F,
+ 0x0F120F00,
+ 0x0F120F00,
+ 0x0F120000,
+ 0x0F120F0F,
+ 0x0F120F0F,
+ 0x0F120F00,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F12000F,
+ 0x0F120F0F,
+ 0x0F120000,
+ 0x0F120F00,
+ 0x0F120000,
+ 0x0F120F00,
+ 0x0F120000,
+ 0x0F120F0F,
+ 0x0F12000F,
+ 0x0F12000F,
+ 0x0F120F00,
+ 0x0F120F00,
+ 0x0F120000,
+ 0x0F120F00,
+ 0x0F120F0F,
+ 0x0F120F00,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F12000F,
+ 0x0F120F00,
+ 0x0F120F00,
+ 0x0F120F00,
+ 0x0F12000F,
+ 0x0F120F00,
+ 0x0F120000,
+ 0x0F120F0F,
+ 0x0F12000F,
+ 0x0F12000F,
+ 0x0F120F00,
+ 0x0F120F00,
+ 0x0F120000,
+ 0x0F120F0F,
+ 0x0F120F0F,
+ 0x0F120F00,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F12000F,
+ 0x0F120F0F,
+ 0x0F120F00,
+ 0x0F120F00,
+ 0x0F120000,
+ 0x0F120F0F,
+ 0x0F120000,
+ 0x0F120F0F,
+ 0x0F12000F,
+ 0x0F12000F,
+ 0x0F120F00,
+ 0x0F128608,
+ 0x0F12E960,
+ 0x0F120243,
+ 0x0F12128B,
+ 0x0F12F073,
+ 0x0F120270,
+ 0x0F12DF47,
+ 0x0F12F226,
+ 0x0F121A31,
+ 0x0F12DFDA,
+ 0x0F121200,
+ 0x0F1205A9,
+ 0x0F120F16,
+ 0x0F120F5E,
+ 0x0F12DF10,
+ 0x0F1225BF,
+ 0x0F12FCF0,
+ 0x0F12DE1B,
+ 0x0F12025B,
+ 0x0F12FA8B,
+ 0x0F12163B,
+ 0x0F12DF44,
+ 0x0F12FB2D,
+ 0x0F1230E6,
+ 0x0F12FE07,
+ 0x0F12F47C,
+ 0x0F1209F2,
+ 0x0F120AED,
+ 0x0F12FA09,
+ 0x0F12E70E,
+ 0x0F120158,
+ 0x0F121110,
+ 0x0F12E28C,
+ 0x0F120DFB,
+ 0x0F12074B,
+ 0x0F12FBE5,
+ 0x0F12961C,
+ 0x0F12E21A,
+ 0x0F120ADF,
+ 0x0F120A67,
+ 0x0F12F8A6,
+ 0x0F12FDC3,
+ 0x0F12D590,
+ 0x0F12FA69,
+ 0x0F1208D5,
+ 0x0F12F635,
+ 0x0F12057E,
+ 0x0F12043B,
+ 0x0F12155C,
+ 0x0F1200C6,
+ 0x0F12F042,
+ 0x0F12176A,
+ 0x0F12F818,
+ 0x0F12F1F3,
+ 0x0F12026F,
+ 0x0F1208F6,
+ 0x0F120CCF,
+ 0x0F12E42D,
+ 0x0F120A92,
+ 0x0F1210EC,
+ 0x0F12005F,
+ 0x0F12F02C,
+ 0x0F120672,
+ 0x0F1209BF,
+ 0x0F12F4B5,
+ 0x0F12FC22,
+ 0x0F12FD50,
+ 0x0F120C26,
+ 0x0F12EED3,
+ 0x0F1207C3,
+ 0x0F12080F,
+ 0x0F12F6CF,
+ 0x0F127A3B,
+ 0x0F12E9DC,
+ 0x0F12088E,
+ 0x0F1201C8,
+ 0x0F12043C,
+ 0x0F12F7E2,
+ 0x0F12E391,
+ 0x0F12F3C4,
+ 0x0F121422,
+ 0x0F12E845,
+ 0x0F120D16,
+ 0x0F1206CA,
+ 0x0F120DEB,
+ 0x0F121324,
+ 0x0F12E814,
+ 0x0F1216B7,
+ 0x0F1202AC,
+ 0x0F12DE4D,
+ 0x0F1201EA,
+ 0x0F12F0C2,
+ 0x0F120E06,
+ 0x0F12EC6D,
+ 0x0F12FDF0,
+ 0x0F122B46,
+ 0x0F120710,
+ 0x0F12F84C,
+ 0x0F120E52,
+ 0x0F120675,
+ 0x0F12F0D7,
+ 0x0F12ED40,
+ 0x0F12F3AD,
+ 0x0F12179A,
+ 0x0F12DE9B,
+ 0x0F1210BA,
+ 0x0F120825,
+ 0x0F12FE0A,
+ 0x0F1288E9,
+ 0x0F12E9E0,
+ 0x0F12043D,
+ 0x0F120A17,
+ 0x0F12FC21,
+ 0x0F12FB58,
+ 0x0F12DCE0,
+ 0x0F12F24C,
+ 0x0F121A19,
+ 0x0F12E011,
+ 0x0F1211A3,
+ 0x0F120649,
+ 0x0F120D04,
+ 0x0F120E15,
+ 0x0F12E112,
+ 0x0F1227BD,
+ 0x0F12F7AA,
+ 0x0F12E06A,
+ 0x0F120A16,
+ 0x0F12FD23,
+ 0x0F121226,
+ 0x0F12DA34,
+ 0x0F1207A4,
+ 0x0F122AD3,
+ 0x0F12FE27,
+ 0x0F12EE64,
+ 0x0F120CAD,
+ 0x0F1211C5,
+ 0x0F12EC55,
+ 0x0F12ED98,
+ 0x0F12F88A,
+ 0x0F121842,
+ 0x0F12E1D5,
+ 0x0F1208FD,
+ 0x0F120FB6,
+ 0x0F12F801,
+ 0x002A0378,
+ 0x0F120001, /*REG_TC_DBG_RelnitCmd*/
+ 0x002A05E8,
+ 0x0F1200E4, /*TVAR_ash_AwbAshCord_0_ Horizon*/
+ 0x0F1200F0, /*TVAR_ash_AwbAshCord_1_ IncandA*/
+ 0x0F120100, /*TVAR_ash_AwbAshCord_2_ WW*/
+ 0x0F120120, /*TVAR_ash_AwbAshCord_3_ CW*/
+ 0x0F120150, /*TVAR_ash_AwbAshCord_4_ D50*/
+ 0x0F120180, /*TVAR_ash_AwbAshCord_5_ D65*/
+ 0x0F1201A0, /*TVAR_ash_AwbAshCord_6_ D75*/
+ 0x002A05FE,
+ 0x0F123800, /*TVAR_ash_GASAlpha_0__0_ Horizon*/
+ 0x0F124000, /*TVAR_ash_GASAlpha_0__1_*/
+ 0x0F124000, /*TVAR_ash_GASAlpha_0__2_*/
+ 0x0F124000, /*TVAR_ash_GASAlpha_0__3_*/
+ 0x0F123800, /*TVAR_ash_GASAlpha_1__0_ IncandA*/
+ 0x0F124000, /*TVAR_ash_GASAlpha_1__1_*/
+ 0x0F124000, /*TVAR_ash_GASAlpha_1__2_*/
+ 0x0F124000, /*TVAR_ash_GASAlpha_1__3_*/
+ 0x0F123800, /*TVAR_ash_GASAlpha_2__0_ WW*/
+ 0x0F124000, /*TVAR_ash_GASAlpha_2__1_*/
+ 0x0F124000, /*TVAR_ash_GASAlpha_2__2_*/
+ 0x0F124000, /*TVAR_ash_GASAlpha_2__3_*/
+ 0x0F123800, /*TVAR_ash_GASAlpha_3__0_ CW*/
+ 0x0F124000, /*TVAR_ash_GASAlpha_3__1_*/
+ 0x0F124000, /*TVAR_ash_GASAlpha_3__2_*/
+ 0x0F124000, /*TVAR_ash_GASAlpha_3__3_*/
+ 0x0F123800, /*TVAR_ash_GASAlpha_4__0_ D50*/
+ 0x0F124000, /*TVAR_ash_GASAlpha_4__1_*/
+ 0x0F124000, /*TVAR_ash_GASAlpha_4__2_*/
+ 0x0F124000, /*TVAR_ash_GASAlpha_4__3_*/
+ 0x0F124000, /*TVAR_ash_GASAlpha_5__0_ D65*/
+ 0x0F124000, /*TVAR_ash_GASAlpha_5__1_*/
+ 0x0F124000, /*TVAR_ash_GASAlpha_5__2_*/
+ 0x0F124000, /*TVAR_ash_GASAlpha_5__3_*/
+ 0x0F124000, /*TVAR_ash_GASAlpha_6__0_ D75*/
+ 0x0F124000, /*TVAR_ash_GASAlpha_6__1_*/
+ 0x0F124000, /*TVAR_ash_GASAlpha_6__2_*/
+ 0x0F124000, /*TVAR_ash_GASAlpha_6__3_*/
+ 0x0F124000, /*TVAR_ash_GASOutdoorAlpha_0_*/
+ 0x0F124000, /*TVAR_ash_GASOutdoorAlpha_1_*/
+ 0x0F124000, /*TVAR_ash_GASOutdoorAlpha_2_*/
+ 0x0F124000, /*TVAR_ash_GASOutdoorAlpha_3_*/
+ 0x00287000,
+ 0x002A2744,
+ 0x0F12B510, /* 70002744*/
+ 0x0F124A1C, /* 70002746*/
+ 0x0F1221FB, /* 70002748*/
+ 0x0F12481C, /* 7000274A*/
+ 0x0F12C004, /* 7000274C*/
+ 0x0F126001, /* 7000274E*/
+ 0x0F12491B, /* 70002750*/
+ 0x0F12481C, /* 70002752*/
+ 0x0F12F000, /* 70002754*/
+ 0x0F12FA0E, /* 70002756*/
+ 0x0F12491B, /* 70002758*/
+ 0x0F12481C, /* 7000275A*/
+ 0x0F12F000, /* 7000275C*/
+ 0x0F12FA0A, /* 7000275E*/
+ 0x0F12491B, /* 70002760*/
+ 0x0F12481C, /* 70002762*/
+ 0x0F12F000, /* 70002764*/
+ 0x0F12FA06, /* 70002766*/
+ 0x0F12491B, /* 70002768*/
+ 0x0F12481C, /* 7000276A*/
+ 0x0F12F000, /* 7000276C*/
+ 0x0F12FA02, /* 7000276E*/
+ 0x0F12491B, /* 70002770*/
+ 0x0F12481C, /* 70002772*/
+ 0x0F12F000, /* 70002774*/
+ 0x0F12F9FE, /* 70002776*/
+ 0x0F12491B, /* 70002778*/
+ 0x0F12481C, /* 7000277A*/
+ 0x0F12F000, /* 7000277C*/
+ 0x0F12F9FA, /* 7000277E*/
+ 0x0F12491B, /* 70002780*/
+ 0x0F12481C, /* 70002782*/
+ 0x0F12F000, /* 70002784*/
+ 0x0F12F9F6, /* 70002786*/
+ 0x0F12481B, /* 70002788*/
+ 0x0F122130, /* 7000278A*/
+ 0x0F128001, /* 7000278C*/
+ 0x0F1221C0, /* 7000278E*/
+ 0x0F128041, /* 70002790*/
+ 0x0F122104, /* 70002792*/
+ 0x0F128081, /* 70002794*/
+ 0x0F122100, /* 70002796*/
+ 0x0F1280C1, /* 70002798*/
+ 0x0F128101, /* 7000279A*/
+ 0x0F124917, /* 7000279C*/
+ 0x0F122016, /* 7000279E*/
+ 0x0F1283C8, /* 700027A0*/
+ 0x0F124917, /* 700027A2*/
+ 0x0F124817, /* 700027A4*/
+ 0x0F12F000, /* 700027A6*/
+ 0x0F12F9E5, /* 700027A8*/
+ 0x0F124917, /* 700027AA*/
+ 0x0F124817, /* 700027AC*/
+ 0x0F12F000, /* 700027AE*/
+ 0x0F12F9E1, /* 700027B0*/
+ 0x0F12BC10, /* 700027B2*/
+ 0x0F12BC08, /* 700027B4*/
+ 0x0F124718, /* 700027B6*/
+ 0x0F120000, /* 700027B8*/
+ 0x0F125BB1, /* 700027BA*/
+ 0x0F121770, /* 700027BC*/
+ 0x0F127000, /* 700027BE*/
+ 0x0F122811, /* 700027C0*/
+ 0x0F127000, /* 700027C2*/
+ 0x0F12C0BB, /* 700027C4*/
+ 0x0F120000, /* 700027C6*/
+ 0x0F12284F, /* 700027C8*/
+ 0x0F127000, /* 700027CA*/
+ 0x0F123609, /* 700027CC*/
+ 0x0F120000, /* 700027CE*/
+ 0x0F122867, /* 700027D0*/
+ 0x0F127000, /* 700027D2*/
+ 0x0F1277C7, /* 700027D4*/
+ 0x0F120000, /* 700027D6*/
+ 0x0F1228F3, /* 700027D8*/
+ 0x0F127000, /* 700027DA*/
+ 0x0F12727D, /* 700027DC*/
+ 0x0F120000, /* 700027DE*/
+ 0x0F122949, /* 700027E0*/
+ 0x0F127000, /* 700027E2*/
+ 0x0F129919, /* 700027E4*/
+ 0x0F120000, /* 700027E6*/
+ 0x0F122987, /* 700027E8*/
+ 0x0F127000, /* 700027EA*/
+ 0x0F121C63, /* 700027EC*/
+ 0x0F120000, /* 700027EE*/
+ 0x0F1229E7, /* 700027F0*/
+ 0x0F127000, /* 700027F2*/
+ 0x0F1204CB, /* 700027F4*/
+ 0x0F120000, /* 700027F6*/
+ 0x0F122C7C, /* 700027F8*/
+ 0x0F127000, /* 700027FA*/
+ 0x0F120CA8, /* 700027FC*/
+ 0x0F127000, /* 700027FE*/
+ 0x0F122B1D, /* 70002800*/
+ 0x0F127000, /* 70002802*/
+ 0x0F1250AF, /* 70002804*/
+ 0x0F120000, /* 70002806*/
+ 0x0F122B2D, /* 70002808*/
+ 0x0F127000, /* 7000280A*/
+ 0x0F125623, /* 7000280C*/
+ 0x0F120000, /* 7000280E*/
+ 0x0F12B4F0, /* 70002810*/
+ 0x0F126801, /* 70002812*/
+ 0x0F12468C, /* 70002814*/
+ 0x0F126846, /* 70002816*/
+ 0x0F122200, /* 70002818*/
+ 0x0F1249C7, /* 7000281A*/
+ 0x0F122000, /* 7000281C*/
+ 0x0F122724, /* 7000281E*/
+ 0x0F124357, /* 70002820*/
+ 0x0F12183B, /* 70002822*/
+ 0x0F124664, /* 70002824*/
+ 0x0F125CE5, /* 70002826*/
+ 0x0F12005C, /* 70002828*/
+ 0x0F125B34, /* 7000282A*/
+ 0x0F12072D, /* 7000282C*/
+ 0x0F120F2D, /* 7000282E*/
+ 0x0F12800D, /* 70002830*/
+ 0x0F12804C, /* 70002832*/
+ 0x0F12808B, /* 70002834*/
+ 0x0F122301, /* 70002836*/
+ 0x0F1280CB, /* 70002838*/
+ 0x0F122300, /* 7000283A*/
+ 0x0F1280CB, /* 7000283C*/
+ 0x0F121C40, /* 7000283E*/
+ 0x0F122824, /* 70002840*/
+ 0x0F12D3EE, /* 70002842*/
+ 0x0F121C52, /* 70002844*/
+ 0x0F122A04, /* 70002846*/
+ 0x0F12D3E8, /* 70002848*/
+ 0x0F12BCF0, /* 7000284A*/
+ 0x0F124770, /* 7000284C*/
+ 0x0F12B510, /* 7000284E*/
+ 0x0F12F000, /* 70002850*/
+ 0x0F12F998, /* 70002852*/
+ 0x0F1248B9, /* 70002854*/
+ 0x0F127A81, /* 70002856*/
+ 0x0F1248B9, /* 70002858*/
+ 0x0F126B00, /* 7000285A*/
+ 0x0F12F000, /* 7000285C*/
+ 0x0F12F99A, /* 7000285E*/
+ 0x0F12BC10, /* 70002860*/
+ 0x0F12BC08, /* 70002862*/
+ 0x0F124718, /* 70002864*/
+ 0x0F12B5F8, /* 70002866*/
+ 0x0F126805, /* 70002868*/
+ 0x0F126844, /* 7000286A*/
+ 0x0F124EB5, /* 7000286C*/
+ 0x0F128861, /* 7000286E*/
+ 0x0F128AB0, /* 70002870*/
+ 0x0F128A72, /* 70002872*/
+ 0x0F122301, /* 70002874*/
+ 0x0F124368, /* 70002876*/
+ 0x0F121889, /* 70002878*/
+ 0x0F1217C2, /* 7000287A*/
+ 0x0F120E12, /* 7000287C*/
+ 0x0F121810, /* 7000287E*/
+ 0x0F121202, /* 70002880*/
+ 0x0F128820, /* 70002882*/
+ 0x0F12029B, /* 70002884*/
+ 0x0F1218C0, /* 70002886*/
+ 0x0F12F000, /* 70002888*/
+ 0x0F12F98C, /* 7000288A*/
+ 0x0F129000, /* 7000288C*/
+ 0x0F128AF6, /* 7000288E*/
+ 0x0F124268, /* 70002890*/
+ 0x0F12210A, /* 70002892*/
+ 0x0F124370, /* 70002894*/
+ 0x0F12F000, /* 70002896*/
+ 0x0F12F98D, /* 70002898*/
+ 0x0F12436E, /* 7000289A*/
+ 0x0F120007, /* 7000289C*/
+ 0x0F12210A, /* 7000289E*/
+ 0x0F120030, /* 700028A0*/
+ 0x0F12F000, /* 700028A2*/
+ 0x0F12F987, /* 700028A4*/
+ 0x0F129A00, /* 700028A6*/
+ 0x0F120039, /* 700028A8*/
+ 0x0F12F000, /* 700028AA*/
+ 0x0F12F989, /* 700028AC*/
+ 0x0F120002, /* 700028AE*/
+ 0x0F128820, /* 700028B0*/
+ 0x0F121880, /* 700028B2*/
+ 0x0F128020, /* 700028B4*/
+ 0x0F1248A4, /* 700028B6*/
+ 0x0F1288C1, /* 700028B8*/
+ 0x0F1248A2, /* 700028BA*/
+ 0x0F123820, /* 700028BC*/
+ 0x0F128B40, /* 700028BE*/
+ 0x0F124240, /* 700028C0*/
+ 0x0F124350, /* 700028C2*/
+ 0x0F12F000, /* 700028C4*/
+ 0x0F12F976, /* 700028C6*/
+ 0x0F128861, /* 700028C8*/
+ 0x0F121840, /* 700028CA*/
+ 0x0F128060, /* 700028CC*/
+ 0x0F12BCF8, /* 700028CE*/
+ 0x0F12BC08, /* 700028D0*/
+ 0x0F124718, /* 700028D2*/
+ 0x0F12B570, /* 700028D4*/
+ 0x0F124C9B, /* 700028D6*/
+ 0x0F123C20, /* 700028D8*/
+ 0x0F128B20, /* 700028DA*/
+ 0x0F12F000, /* 700028DC*/
+ 0x0F12F978, /* 700028DE*/
+ 0x0F124D99, /* 700028E0*/
+ 0x0F1280E8, /* 700028E2*/
+ 0x0F128B60, /* 700028E4*/
+ 0x0F12F000, /* 700028E6*/
+ 0x0F12F97B, /* 700028E8*/
+ 0x0F128128, /* 700028EA*/
+ 0x0F12BC70, /* 700028EC*/
+ 0x0F12BC08, /* 700028EE*/
+ 0x0F124718, /* 700028F0*/
+ 0x0F12B508, /* 700028F2*/
+ 0x0F124895, /* 700028F4*/
+ 0x0F124669, /* 700028F6*/
+ 0x0F12F000, /* 700028F8*/
+ 0x0F12F97A, /* 700028FA*/
+ 0x0F124894, /* 700028FC*/
+ 0x0F12214D, /* 700028FE*/
+ 0x0F128201, /* 70002900*/
+ 0x0F122196, /* 70002902*/
+ 0x0F128281, /* 70002904*/
+ 0x0F12211D, /* 70002906*/
+ 0x0F128301, /* 70002908*/
+ 0x0F12F7FF, /* 7000290A*/
+ 0x0F12FFE3, /* 7000290C*/
+ 0x0F12F000, /* 7000290E*/
+ 0x0F12F977, /* 70002910*/
+ 0x0F12466B, /* 70002912*/
+ 0x0F128818, /* 70002914*/
+ 0x0F128859, /* 70002916*/
+ 0x0F121A40, /* 70002918*/
+ 0x0F12498E, /* 7000291A*/
+ 0x0F126348, /* 7000291C*/
+ 0x0F12488A, /* 7000291E*/
+ 0x0F129900, /* 70002920*/
+ 0x0F123876, /* 70002922*/
+ 0x0F12F000, /* 70002924*/
+ 0x0F12F974, /* 70002926*/
+ 0x0F12466B, /* 70002928*/
+ 0x0F12488A, /* 7000292A*/
+ 0x0F128819, /* 7000292C*/
+ 0x0F123080, /* 7000292E*/
+ 0x0F1284C1, /* 70002930*/
+ 0x0F128859, /* 70002932*/
+ 0x0F128501, /* 70002934*/
+ 0x0F124987, /* 70002936*/
+ 0x0F122000, /* 70002938*/
+ 0x0F123920, /* 7000293A*/
+ 0x0F127088, /* 7000293C*/
+ 0x0F123140, /* 7000293E*/
+ 0x0F127388, /* 70002940*/
+ 0x0F12B001, /* 70002942*/
+ 0x0F12BC08, /* 70002944*/
+ 0x0F124718, /* 70002946*/
+ 0x0F12B570, /* 70002948*/
+ 0x0F120004, /* 7000294A*/
+ 0x0F126820, /* 7000294C*/
+ 0x0F126865, /* 7000294E*/
+ 0x0F12F000, /* 70002950*/
+ 0x0F12F966, /* 70002952*/
+ 0x0F120402, /* 70002954*/
+ 0x0F124880, /* 70002956*/
+ 0x0F120C12, /* 70002958*/
+ 0x0F128142, /* 7000295A*/
+ 0x0F12487F, /* 7000295C*/
+ 0x0F128801, /* 7000295E*/
+ 0x0F122900, /* 70002960*/
+ 0x0F12D008, /* 70002962*/
+ 0x0F12497E, /* 70002964*/
+ 0x0F12002B, /* 70002966*/
+ 0x0F126D8A, /* 70002968*/
+ 0x0F122105, /* 7000296A*/
+ 0x0F121C80, /* 7000296C*/
+ 0x0F12F000, /* 7000296E*/
+ 0x0F12F95F, /* 70002970*/
+ 0x0F126020, /* 70002972*/
+ 0x0F12E005, /* 70002974*/
+ 0x0F12487B, /* 70002976*/
+ 0x0F12002B, /* 70002978*/
+ 0x0F122105, /* 7000297A*/
+ 0x0F12F000, /* 7000297C*/
+ 0x0F12F958, /* 7000297E*/
+ 0x0F126020, /* 70002980*/
+ 0x0F126820, /* 70002982*/
+ 0x0F12E7B2, /* 70002984*/
+ 0x0F12B5F8, /* 70002986*/
+ 0x0F124975, /* 70002988*/
+ 0x0F122200, /* 7000298A*/
+ 0x0F123160, /* 7000298C*/
+ 0x0F1283CA, /* 7000298E*/
+ 0x0F126800, /* 70002990*/
+ 0x0F124669, /* 70002992*/
+ 0x0F12F000, /* 70002994*/
+ 0x0F12F92C, /* 70002996*/
+ 0x0F12466B, /* 70002998*/
+ 0x0F128818, /* 7000299A*/
+ 0x0F12F000, /* 7000299C*/
+ 0x0F12F918, /* 7000299E*/
+ 0x0F120005, /* 700029A0*/
+ 0x0F12466B, /* 700029A2*/
+ 0x0F128858, /* 700029A4*/
+ 0x0F12F000, /* 700029A6*/
+ 0x0F12F91B, /* 700029A8*/
+ 0x0F120004, /* 700029AA*/
+ 0x0F122101, /* 700029AC*/
+ 0x0F121928, /* 700029AE*/
+ 0x0F1202C9, /* 700029B0*/
+ 0x0F121A08, /* 700029B2*/
+ 0x0F120286, /* 700029B4*/
+ 0x0F120029, /* 700029B6*/
+ 0x0F120030, /* 700029B8*/
+ 0x0F12F000, /* 700029BA*/
+ 0x0F12F941, /* 700029BC*/
+ 0x0F120005, /* 700029BE*/
+ 0x0F122701, /* 700029C0*/
+ 0x0F1202BF, /* 700029C2*/
+ 0x0F120021, /* 700029C4*/
+ 0x0F120030, /* 700029C6*/
+ 0x0F12F000, /* 700029C8*/
+ 0x0F12F93A, /* 700029CA*/
+ 0x0F124964, /* 700029CC*/
+ 0x0F124A61, /* 700029CE*/
+ 0x0F123140, /* 700029D0*/
+ 0x0F1232A0, /* 700029D2*/
+ 0x0F12800D, /* 700029D4*/
+ 0x0F128395, /* 700029D6*/
+ 0x0F12804F, /* 700029D8*/
+ 0x0F1283D7, /* 700029DA*/
+ 0x0F128088, /* 700029DC*/
+ 0x0F120011, /* 700029DE*/
+ 0x0F123120, /* 700029E0*/
+ 0x0F128008, /* 700029E2*/
+ 0x0F12E773, /* 700029E4*/
+ 0x0F12B510, /* 700029E6*/
+ 0x0F12485C, /* 700029E8*/
+ 0x0F128980, /* 700029EA*/
+ 0x0F122800, /* 700029EC*/
+ 0x0F12D001, /* 700029EE*/
+ 0x0F12F000, /* 700029F0*/
+ 0x0F12F92C, /* 700029F2*/
+ 0x0F12E734, /* 700029F4*/
+ 0x0F12B5FE, /* 700029F6*/
+ 0x0F122600, /* 700029F8*/
+ 0x0F12495B, /* 700029FA*/
+ 0x0F122000, /* 700029FC*/
+ 0x0F126108, /* 700029FE*/
+ 0x0F1260C8, /* 70002A00*/
+ 0x0F12485A, /* 70002A02*/
+ 0x0F128901, /* 70002A04*/
+ 0x0F124852, /* 70002A06*/
+ 0x0F123020, /* 70002A08*/
+ 0x0F1288C0, /* 70002A0A*/
+ 0x0F129000, /* 70002A0C*/
+ 0x0F120840, /* 70002A0E*/
+ 0x0F129002, /* 70002A10*/
+ 0x0F124856, /* 70002A12*/
+ 0x0F128800, /* 70002A14*/
+ 0x0F129001, /* 70002A16*/
+ 0x0F124853, /* 70002A18*/
+ 0x0F123040, /* 70002A1A*/
+ 0x0F128B05, /* 70002A1C*/
+ 0x0F122900, /* 70002A1E*/
+ 0x0F12D01F, /* 70002A20*/
+ 0x0F124E52, /* 70002A22*/
+ 0x0F122700, /* 70002A24*/
+ 0x0F1280F7, /* 70002A26*/
+ 0x0F122400, /* 70002A28*/
+ 0x0F12E016, /* 70002A2A*/
+ 0x0F12494E, /* 70002A2C*/
+ 0x0F120060, /* 70002A2E*/
+ 0x0F1239C0, /* 70002A30*/
+ 0x0F121841, /* 70002A32*/
+ 0x0F122020, /* 70002A34*/
+ 0x0F125E08, /* 70002A36*/
+ 0x0F129902, /* 70002A38*/
+ 0x0F121840, /* 70002A3A*/
+ 0x0F129900, /* 70002A3C*/
+ 0x0F12F000, /* 70002A3E*/
+ 0x0F12F8FF, /* 70002A40*/
+ 0x0F124B4A, /* 70002A42*/
+ 0x0F120202, /* 70002A44*/
+ 0x0F1200A1, /* 70002A46*/
+ 0x0F12330C, /* 70002A48*/
+ 0x0F12505A, /* 70002A4A*/
+ 0x0F120002, /* 70002A4C*/
+ 0x0F124342, /* 70002A4E*/
+ 0x0F120210, /* 70002A50*/
+ 0x0F121DDA, /* 70002A52*/
+ 0x0F1232F9, /* 70002A54*/
+ 0x0F125050, /* 70002A56*/
+ 0x0F121C64, /* 70002A58*/
+ 0x0F1242A5, /* 70002A5A*/
+ 0x0F12DCE6, /* 70002A5C*/
+ 0x0F128137, /* 70002A5E*/
+ 0x0F12E042, /* 70002A60*/
+ 0x0F122400, /* 70002A62*/
+ 0x0F12E031, /* 70002A64*/
+ 0x0F124940, /* 70002A66*/
+ 0x0F120060, /* 70002A68*/
+ 0x0F1239C0, /* 70002A6A*/
+ 0x0F121841, /* 70002A6C*/
+ 0x0F122020, /* 70002A6E*/
+ 0x0F125E08, /* 70002A70*/
+ 0x0F129902, /* 70002A72*/
+ 0x0F121840, /* 70002A74*/
+ 0x0F129900, /* 70002A76*/
+ 0x0F12F000, /* 70002A78*/
+ 0x0F12F8E2, /* 70002A7A*/
+ 0x0F124A3B, /* 70002A7C*/
+ 0x0F1200A1, /* 70002A7E*/
+ 0x0F12320C, /* 70002A80*/
+ 0x0F125853, /* 70002A82*/
+ 0x0F123A0C, /* 70002A84*/
+ 0x0F128852, /* 70002A86*/
+ 0x0F124353, /* 70002A88*/
+ 0x0F123380, /* 70002A8A*/
+ 0x0F120A1F, /* 70002A8C*/
+ 0x0F1223FF, /* 70002A8E*/
+ 0x0F121C5B, /* 70002A90*/
+ 0x0F121A9B, /* 70002A92*/
+ 0x0F12469C, /* 70002A94*/
+ 0x0F124343, /* 70002A96*/
+ 0x0F1218FF, /* 70002A98*/
+ 0x0F124B34, /* 70002A9A*/
+ 0x0F12330C, /* 70002A9C*/
+ 0x0F12505F, /* 70002A9E*/
+ 0x0F120003, /* 70002AA0*/
+ 0x0F124343, /* 70002AA2*/
+ 0x0F124660, /* 70002AA4*/
+ 0x0F124343, /* 70002AA6*/
+ 0x0F124831, /* 70002AA8*/
+ 0x0F125840, /* 70002AAA*/
+ 0x0F124350, /* 70002AAC*/
+ 0x0F123080, /* 70002AAE*/
+ 0x0F124A2F, /* 70002AB0*/
+ 0x0F120A00, /* 70002AB2*/
+ 0x0F121818, /* 70002AB4*/
+ 0x0F125050, /* 70002AB6*/
+ 0x0F120039, /* 70002AB8*/
+ 0x0F124379, /* 70002ABA*/
+ 0x0F123180, /* 70002ABC*/
+ 0x0F120A09, /* 70002ABE*/
+ 0x0F124281, /* 70002AC0*/
+ 0x0F12D201, /* 70002AC2*/
+ 0x0F121A40, /* 70002AC4*/
+ 0x0F121986, /* 70002AC6*/
+ 0x0F121C64, /* 70002AC8*/
+ 0x0F1242A5, /* 70002ACA*/
+ 0x0F12DCCB, /* 70002ACC*/
+ 0x0F120868, /* 70002ACE*/
+ 0x0F121980, /* 70002AD0*/
+ 0x0F120029, /* 70002AD2*/
+ 0x0F12F000, /* 70002AD4*/
+ 0x0F12F8B4, /* 70002AD6*/
+ 0x0F123008, /* 70002AD8*/
+ 0x0F120900, /* 70002ADA*/
+ 0x0F129A01, /* 70002ADC*/
+ 0x0F124923, /* 70002ADE*/
+ 0x0F124290, /* 70002AE0*/
+ 0x0F12D901, /* 70002AE2*/
+ 0x0F128888, /* 70002AE4*/
+ 0x0F1280C8, /* 70002AE6*/
+ 0x0F124920, /* 70002AE8*/
+ 0x0F1288C8, /* 70002AEA*/
+ 0x0F122800, /* 70002AEC*/
+ 0x0F12D001, /* 70002AEE*/
+ 0x0F121E40, /* 70002AF0*/
+ 0x0F1280C8, /* 70002AF2*/
+ 0x0F129801, /* 70002AF4*/
+ 0x0F122800, /* 70002AF6*/
+ 0x0F12D00D, /* 70002AF8*/
+ 0x0F124A1B, /* 70002AFA*/
+ 0x0F123AC0, /* 70002AFC*/
+ 0x0F127B90, /* 70002AFE*/
+ 0x0F122802, /* 70002B00*/
+ 0x0F12D001, /* 70002B02*/
+ 0x0F122803, /* 70002B04*/
+ 0x0F12D106, /* 70002B06*/
+ 0x0F1288C9, /* 70002B08*/
+ 0x0F122900, /* 70002B0A*/
+ 0x0F12D003, /* 70002B0C*/
+ 0x0F122100, /* 70002B0E*/
+ 0x0F120040, /* 70002B10*/
+ 0x0F121880, /* 70002B12*/
+ 0x0F128081, /* 70002B14*/
+ 0x0F12BCFE, /* 70002B16*/
+ 0x0F12BC08, /* 70002B18*/
+ 0x0F124718, /* 70002B1A*/
+ 0x0F12B510, /* 70002B1C*/
+ 0x0F126800, /* 70002B1E*/
+ 0x0F12F000, /* 70002B20*/
+ 0x0F12F89C, /* 70002B22*/
+ 0x0F124911, /* 70002B24*/
+ 0x0F122001, /* 70002B26*/
+ 0x0F128108, /* 70002B28*/
+ 0x0F12E699, /* 70002B2A*/
+ 0x0F12B510, /* 70002B2C*/
+ 0x0F12F000, /* 70002B2E*/
+ 0x0F12F89D, /* 70002B30*/
+ 0x0F12F7FF, /* 70002B32*/
+ 0x0F12FF60, /* 70002B34*/
+ 0x0F12E693, /* 70002B36*/
+ 0x0F124140, /* 70002B38*/
+ 0x0F12D000, /* 70002B3A*/
+ 0x0F1219DC, /* 70002B3C*/
+ 0x0F127000, /* 70002B3E*/
+ 0x0F121B60, /* 70002B40*/
+ 0x0F127000, /* 70002B42*/
+ 0x0F120DD4, /* 70002B44*/
+ 0x0F127000, /* 70002B46*/
+ 0x0F1222AC, /* 70002B48*/
+ 0x0F127000, /* 70002B4A*/
+ 0x0F120F88, /* 70002B4C*/
+ 0x0F127000, /* 70002B4E*/
+ 0x0F121E8C, /* 70002B50*/
+ 0x0F127000, /* 70002B52*/
+ 0x0F12214C, /* 70002B54*/
+ 0x0F127000, /* 70002B56*/
+ 0x0F121A10, /* 70002B58*/
+ 0x0F127000, /* 70002B5A*/
+ 0x0F123780, /* 70002B5C*/
+ 0x0F127000, /* 70002B5E*/
+ 0x0F122384, /* 70002B60*/
+ 0x0F127000, /* 70002B62*/
+ 0x0F12065C, /* 70002B64*/
+ 0x0F127000, /* 70002B66*/
+ 0x0F121C8C, /* 70002B68*/
+ 0x0F127000, /* 70002B6A*/
+ 0x0F122C7C, /* 70002B6C*/
+ 0x0F127000, /* 70002B6E*/
+ 0x0F122D88, /* 70002B70*/
+ 0x0F127000, /* 70002B72*/
+ 0x0F124778, /* 70002B74*/
+ 0x0F1246C0, /* 70002B76*/
+ 0x0F12C000, /* 70002B78*/
+ 0x0F12E59F, /* 70002B7A*/
+ 0x0F12FF1C, /* 70002B7C*/
+ 0x0F12E12F, /* 70002B7E*/
+ 0x0F12CE77, /* 70002B80*/
+ 0x0F120000, /* 70002B82*/
+ 0x0F124778, /* 70002B84*/
+ 0x0F1246C0, /* 70002B86*/
+ 0x0F12C000, /* 70002B88*/
+ 0x0F12E59F, /* 70002B8A*/
+ 0x0F12FF1C, /* 70002B8C*/
+ 0x0F12E12F, /* 70002B8E*/
+ 0x0F123609, /* 70002B90*/
+ 0x0F120000, /* 70002B92*/
+ 0x0F124778, /* 70002B94*/
+ 0x0F1246C0, /* 70002B96*/
+ 0x0F12C000, /* 70002B98*/
+ 0x0F12E59F, /* 70002B9A*/
+ 0x0F12FF1C, /* 70002B9C*/
+ 0x0F12E12F, /* 70002B9E*/
+ 0x0F129F91, /* 70002BA0*/
+ 0x0F120000, /* 70002BA2*/
+ 0x0F124778, /* 70002BA4*/
+ 0x0F1246C0, /* 70002BA6*/
+ 0x0F12C000, /* 70002BA8*/
+ 0x0F12E59F, /* 70002BAA*/
+ 0x0F12FF1C, /* 70002BAC*/
+ 0x0F12E12F, /* 70002BAE*/
+ 0x0F122AE3, /* 70002BB0*/
+ 0x0F120000, /* 70002BB2*/
+ 0x0F124778, /* 70002BB4*/
+ 0x0F1246C0, /* 70002BB6*/
+ 0x0F12F004, /* 70002BB8*/
+ 0x0F12E51F, /* 70002BBA*/
+ 0x0F12D1DC, /* 70002BBC*/
+ 0x0F120000, /* 70002BBE*/
+ 0x0F124778, /* 70002BC0*/
+ 0x0F1246C0, /* 70002BC2*/
+ 0x0F12C000, /* 70002BC4*/
+ 0x0F12E59F, /* 70002BC6*/
+ 0x0F12FF1C, /* 70002BC8*/
+ 0x0F12E12F, /* 70002BCA*/
+ 0x0F126869, /* 70002BCC*/
+ 0x0F120000, /* 70002BCE*/
+ 0x0F124778, /* 70002BD0*/
+ 0x0F1246C0, /* 70002BD2*/
+ 0x0F12C000, /* 70002BD4*/
+ 0x0F12E59F, /* 70002BD6*/
+ 0x0F12FF1C, /* 70002BD8*/
+ 0x0F12E12F, /* 70002BDA*/
+ 0x0F1268BD, /* 70002BDC*/
+ 0x0F120000, /* 70002BDE*/
+ 0x0F124778, /* 70002BE0*/
+ 0x0F1246C0, /* 70002BE2*/
+ 0x0F12C000, /* 70002BE4*/
+ 0x0F12E59F, /* 70002BE6*/
+ 0x0F12FF1C, /* 70002BE8*/
+ 0x0F12E12F, /* 70002BEA*/
+ 0x0F1268DB, /* 70002BEC*/
+ 0x0F120000, /* 70002BEE*/
+ 0x0F124778, /* 70002BF0*/
+ 0x0F1246C0, /* 70002BF2*/
+ 0x0F12C000, /* 70002BF4*/
+ 0x0F12E59F, /* 70002BF6*/
+ 0x0F12FF1C, /* 70002BF8*/
+ 0x0F12E12F, /* 70002BFA*/
+ 0x0F121BC9, /* 70002BFC*/
+ 0x0F120000, /* 70002BFE*/
+ 0x0F124778, /* 70002C00*/
+ 0x0F1246C0, /* 70002C02*/
+ 0x0F12C000, /* 70002C04*/
+ 0x0F12E59F, /* 70002C06*/
+ 0x0F12FF1C, /* 70002C08*/
+ 0x0F12E12F, /* 70002C0A*/
+ 0x0F1271B9, /* 70002C0C*/
+ 0x0F120000, /* 70002C0E*/
+ 0x0F124778, /* 70002C10*/
+ 0x0F1246C0, /* 70002C12*/
+ 0x0F12C000, /* 70002C14*/
+ 0x0F12E59F, /* 70002C16*/
+ 0x0F12FF1C, /* 70002C18*/
+ 0x0F12E12F, /* 70002C1A*/
+ 0x0F127249, /* 70002C1C*/
+ 0x0F120000, /* 70002C1E*/
+ 0x0F124778, /* 70002C20*/
+ 0x0F1246C0, /* 70002C22*/
+ 0x0F12C000, /* 70002C24*/
+ 0x0F12E59F, /* 70002C26*/
+ 0x0F12FF1C, /* 70002C28*/
+ 0x0F12E12F, /* 70002C2A*/
+ 0x0F1298CD, /* 70002C2C*/
+ 0x0F120000, /* 70002C2E*/
+ 0x0F124778, /* 70002C30*/
+ 0x0F1246C0, /* 70002C32*/
+ 0x0F12C000, /* 70002C34*/
+ 0x0F12E59F, /* 70002C36*/
+ 0x0F12FF1C, /* 70002C38*/
+ 0x0F12E12F, /* 70002C3A*/
+ 0x0F12987F, /* 70002C3C*/
+ 0x0F120000, /* 70002C3E*/
+ 0x0F124778, /* 70002C40*/
+ 0x0F1246C0, /* 70002C42*/
+ 0x0F12F004, /* 70002C44*/
+ 0x0F12E51F, /* 70002C46*/
+ 0x0F12D378, /* 70002C48*/
+ 0x0F120000, /* 70002C4A*/
+ 0x0F124778, /* 70002C4C*/
+ 0x0F1246C0, /* 70002C4E*/
+ 0x0F12C000, /* 70002C50*/
+ 0x0F12E59F, /* 70002C52*/
+ 0x0F12FF1C, /* 70002C54*/
+ 0x0F12E12F, /* 70002C56*/
+ 0x0F1204CB, /* 70002C58*/
+ 0x0F120000, /* 70002C5A*/
+ 0x0F124778, /* 70002C5C*/
+ 0x0F1246C0, /* 70002C5E*/
+ 0x0F12C000, /* 70002C60*/
+ 0x0F12E59F, /* 70002C62*/
+ 0x0F12FF1C, /* 70002C64*/
+ 0x0F12E12F, /* 70002C66*/
+ 0x0F1250AF, /* 70002C68*/
+ 0x0F120000, /* 70002C6A*/
+ 0x0F124778, /* 70002C6C*/
+ 0x0F1246C0, /* 70002C6E*/
+ 0x0F12C000, /* 70002C70*/
+ 0x0F12E59F, /* 70002C72*/
+ 0x0F12FF1C, /* 70002C74*/
+ 0x0F12E12F, /* 70002C76*/
+ 0x0F125623, /* 70002C78*/
+ 0x0F120000, /* 70002C7A*/
+ 0x0028D000,
+ 0x002A1000,
+ 0x0F120001,
+ 0x00287000,
+ 0x002A00F4,
+ 0x0F125DC0, /*REG_TC_IPRM_InClockLSBs*/
+ 0x0F120000, /*REG_TC_IPRM_InClockMSBs 5DC0h=24000d=24Mhz*/
+ 0x002A0110,
+ 0x0F120002, /*REG_TC_IPRM_UseNPviClocks*/
+ 0x0F120000, /*REG_TC_IPRM_bBlockInternalPllCalc*/
+ 0x0F12222E, /*REG_TC_IPRM_OpClk4KHz_0 222Eh=8750d*4=35000d=35Mhz*/
+ 0x0F12445C, /*REG_TC_IPRM_MinOutRate4KHz_0
+ 445CEh=8750d*4=35000d=35Mhz*/
+ 0x0F12445C, /*REG_TC_IPRM_MaxOutRate4KHz_0
+ 445Ch=8750d*4=35000d=35Mhz*/
+ 0x0F12222E, /*REG_TC_IPRM_OpClk4KHz_1*/
+ 0x0F12222E, /*REG_TC_IPRM_MinOutRate4KHz_1*/
+ 0x0F12222E, /*REG_TC_IPRM_MaxOutRate4KHz_1*/
+ 0x002A0126,
+ 0x0F120001, /*REG_TC_IPRM_InitParamsUpdated*/
+ /*0x002A0144,*/
+ /*0x0F120640,*/ /*REG_TC_GP_PrevReqInputWidth 640h=1600d*/
+ /*0x0F1204B0,*/ /*REG_TC_GP_PrevReqInputHeight 4b0h=1200d*/
+ /*0x0F120000,*/ /*REG_TC_GP_PrevInputWidthOfs*/
+ /*0x0F120000,*/ /*REG_TC_GP_PrevInputHeightOfs*/
+ /*0x0F120640,*/ /*REG_TC_GP_CapReqInputWidth 640h=1600d*/
+ /*0x0F1204B0,*/ /*REG_TC_GP_CapReqInputHeight 4b0h=1200d*/
+ /*0x0F120000,*/ /*REG_TC_GP_CapInputWidthOfs*/
+ /*0x0F120000,*/ /*REG_TC_GP_CapInputHeightOfs*/
+ /*0x002A0164,*/
+ /*0x0F120001,*/ /*REG_TC_GP_bUseReqInputInPre*/
+ /*0x0F120001,*/ /*REG_TC_GP_bUseReqInputInCap*/
+ /*0x002A0310,*/
+ /*0x0F120640,*/ /*REG_TC_PZOOM_ZoomInputWidth 640h=1600d*/
+ /*0x0F1204b0,*/ /*REG_TC_PZOOM_ZoomInputHeight 4b0h=1200d*/
+ /*0x0F120000,*/ /*REG_TC_PZOOM_ZoomInputWidthOfs*/
+ /*0x0F120000,*/ /*REG_TC_PZOOM_ZoomInputHeightOfs*/
+ 0x002A0170,
+ 0x0F120280, /*0500 0320 REG_0TC_PCFG_usWidth*/
+ 0x0F1201E0, /*03C0 0258 REG_0TC_PCFG_usHeight*/
+ 0x0F120005, /*0005 0005 REG_0TC_PCFG_Format 0 RGB565;
+ 1 RGB888; 5 Full YUV422; 6 Reduced YUV422; 7 Bayer*/
+ 0x0F12222E, /*445C 222E REG_0TC_PCFG_usMaxOut4KHzRate*/
+ 0x0F12222E, /*445C 222E REG_0TC_PCFG_usMinOut4KHzRate*/
+ 0x0F120042, /*0042 0042 REG_0TC_PCFG_PVIMask*/
+ 0x0F120010, /*0010 0010 REG_0TC_PCFG_OIFMask*/
+ 0x0F120001, /*0000 0001 REG_0TC_PCFG_uClockInd*/
+ 0x0F120000, /*0000 0000 REG_0TC_PCFG_usFrTimeType 0: dynamic 1:
+ fix not accurate 2: fixed_Accurate*/
+ 0x0F120001, /*0000 0001 REG_0TC_PCFG_FrRateQualityType 1b: FR
+ (bin) 2b: Quality (no-bin)*/
+ 0x0F120535, /*0535 0535 REG_0TC_PCFG_uSMaxFrTimeMSecMult10 max
+ frame time : 30fpS:014D 15fpS:029a 7.5fpS:0535
+ 3.75fpS:a6a*/
+ 0x0F1202bb, /*029A 029A REG_0TC_PCFG_uSMinFrTimeMSecMult10
+ max frame time : 30fpS:014D 15fpS:029a 7.5fpS:0535
+ 3.75fpS:a6a*/
+ 0x0F120000, /*0000 0000 REG_0TC_PCFG_bSmearOutput*/
+ 0x0F120000, /*0000 0000 REG_0TC_PCFG_SSaturation*/
+ 0x0F120000, /*0000 0000 REG_0TC_PCFG_SSharpBlur*/
+ 0x0F120000, /*0000 0000 REG_0TC_PCFG_SColorTemp*/
+ 0x0F120000, /*0000 0000 REG_0TC_PCFG_uDeviceGammaIndex 1:Mirror
+ (X) 2:Mirror(Y) 4:STAT Mirror(X) 8:STAT Mirror(Y)*/
+ 0x0F120003, /*0000 0001 REG_0TC_PCFG_uPrevMirror*/
+ 0x0F120003, /*0000 0001 REG_0TC_PCFG_uCaptureMirror*/
+ 0x0F120000, /*0000 0000 REG_0TC_PCFG_uRotation*/
+ 0x002A0198,
+ 0x0F120280, /*0280 REG_1TC_PCFG_uSWidth 2 70000198
+ 640*/
+ 0x0F1201E0, /*01E0 REG_1TC_PCFG_uSHeight 2 7000019A
+ 480*/
+ 0x0F120005, /*0005 REG_1TC_PCFG_Format 2 7000019C
+ 0 RGB565; 1 RGB888; 5 Full YUV422; 6 Reduced YUV422;
+ 7 Bayer*/
+ 0x0F12222E, /*222E REG_1TC_PCFG_uSMaxOut4KHzRate 2 7000019E*/
+ 0x0F12222E, /*222E REG_1TC_PCFG_uSMinOut4KHzRate 2 700001A0*/
+ 0x0F120042, /*0042 REG_1TC_PCFG_PVIMaSk 2 700001A2*/
+ 0x0F120010, /*0010 REG_1TC_PCFG_OIFMaSk 2 700001A4*/
+ 0x0F120001, /*0001 REG_1TC_PCFG_uClockInd 2 700001A6*/
+ 0x0F120002, /*0000 REG_1TC_PCFG_uSFrTimeType 2 700001A8
+ 0: dynamic 1:fix not accurate 2: fixed_Accurate*/
+ 0x0F120001, /*0001 REG_1TC_PCFG_FrRateQualityType 2 700001AA*/
+ 0x0F12014D, /*01A0 REG_1TC_PCFG_uSMaxFrTimeMSecMult10 2 700001AC
+ max frame time : 30fpS:014D 15fpS:029a 7.5fpS:0535
+ 3.75fpS:a6a*/
+ 0x0F12014D, /*014D REG_1TC_PCFG_uSMinFrTimeMSecMult10 2 700001AE
+ max frame time : 30fpS:014D 15fpS:029a 7.5fpS:0535
+ 3.75fpS:a6a*/
+ 0x0F120000, /*0000 REG_1TC_PCFG_bSmearOutput 2 700001B0*/
+ 0x0F120000, /*0000 REG_1TC_PCFG_SSaturation 2 700001B2*/
+ 0x0F120000, /*0000 REG_1TC_PCFG_SSharpBlur 2 700001B4*/
+ 0x0F120000, /*0000 REG_1TC_PCFG_SColorTemp 2 700001B6*/
+ 0x0F120000, /*0000 REG_1TC_PCFG_uDeviceGammaIndex 2 700001B8*/
+ 0x0F120003, /*0000 REG_1TC_PCFG_uPrevMirror 2 700001BA*/
+ 0x0F120003, /*0000 REG_1TC_PCFG_uCaptureMirror 2 700001BC*/
+ 0x0F120000, /*0000 REG_1TC_PCFG_uRotation 2 700001BE*/
+ 0x002A01C0,
+ 0x0F120280, /*0320 REG_2TC_PCFG_uSWidth*/
+ 0x0F1201e0, /*0258 REG_2TC_PCFG_uSHeight*/
+ 0x0F120005, /*REG_2TC_PCFG_Format*/
+ 0x0F12222E, /*REG_2TC_PCFG_uSMaxOut4KHzRate*/
+ 0x0F12222E, /*REG_2TC_PCFG_uSMinOut4KHzRate*/
+ 0x0F120042, /*REG_2TC_PCFG_PVIMaSk*/
+ 0x0F120010, /*REG_2TC_PCFG_OIFMaSk*/
+ 0x0F120001, /*REG_2TC_PCFG_uClockInd*/
+ 0x0F120000, /*REG_2TC_PCFG_uSFrTimeType*/
+ 0x0F120001, /*REG_2TC_PCFG_FrRateQualityType 1b: FR (bin) 2b:
+ Quality (no-bin)*/
+ 0x0F1207D0, /*REG_2TC_PCFG_uSMaxFrTimeMSecMult10max frame time :
+ 30fpS 014D; 15fpS 029a; a6a - 3.75 fpS; 0535 - 7.5FPS*/
+ 0x0F12029A, /*REG_2TC_PCFG_uSMinFrTimeMSecMult10 2 700001D6*/
+ 0x0F120000, /*REG_2TC_PCFG_bSmearOutput 2 700001D8*/
+ 0x0F120000, /*REG_2TC_PCFG_SSaturation 2 700001DA*/
+ 0x0F120000, /*REG_2TC_PCFG_SSharpBlur 2 700001DC*/
+ 0x0F120000, /*REG_2TC_PCFG_SColorTemp 2 700001DE*/
+ 0x0F120000, /*REG_2TC_PCFG_uDeviceGammaIndex 2 700001E0*/
+ 0x0F120003, /*REG_2TC_PCFG_uPrevMirror 2 700001E2
+ [0] : x [1]: Y [2] Stat X [3] Stat Y*/
+ 0x0F120003, /*REG_2TC_PCFG_uCaptureMirror 2 700001E4*/
+ 0x0F120000, /*REG_2TC_PCFG_uRotation 2 700001E6*/
+ 0x002A01E8,
+ 0x0F120280, /*0320 REG_3TC_PCFG_uSWidth 2 700001E8*/
+ 0x0F1201e0, /*0258 REG_3TC_PCFG_uSHeight 2 700001EA*/
+ 0x0F120005, /*REG_3TC_PCFG_Format 2 700001EC*/
+ 0x0F12222E, /*REG_3TC_PCFG_uSMaxOut4KHzRate 2 700001EE*/
+ 0x0F12222E, /*REG_3TC_PCFG_uSMinOut4KHzRate 2 700001F0*/
+ 0x0F120042, /*REG_3TC_PCFG_PVIMaSk 2 700001F2*/
+ 0x0F120010, /*REG_3TC_PCFG_OIFMaSk 2 700001F4*/
+ 0x0F120001, /*REG_3TC_PCFG_uClockInd 2 700001F6*/
+ 0x0F120002, /*REG_3TC_PCFG_uSFrTimeType 2 700001F8
+ 0: dynamic 1:fix not accurate 2: fixed_Accurate*/
+ 0x0F120001, /*REG_3TC_PCFG_FrRateQualityType 2 700001FA*/
+ 0x0F120190, /*REG_3TC_PCFG_uSMaxFrTimeMSecMult10 2 700001FC
+ max frame time : 30fpS:014D 15fpS:029a 7.5fpS:0535
+ 3.75fpS:a6a*/
+ 0x0F120000, /*REG_3TC_PCFG_uSMinFrTimeMSecMult10 2 700001FE
+ max frame time : 30fpS:014D 15fpS:029a 7.5fpS:0535
+ 3.75fpS:a6a*/
+ 0x0F120000, /*REG_3TC_PCFG_bSmearOutput 2 70000200*/
+ 0x0F120000, /*REG_3TC_PCFG_SSaturation 2 70000202*/
+ 0x0F120000, /*REG_3TC_PCFG_SSharpBlur 2 70000204*/
+ 0x0F120000, /*REG_3TC_PCFG_SColorTemp 2 70000206*/
+ 0x0F120000, /*REG_3TC_PCFG_uDeviceGammaIndex 2 70000208*/
+ 0x0F120003, /*REG_3TC_PCFG_uPrevMirror 2 7000020A*/
+ 0x0F120003, /*REG_3TC_PCFG_uCaptureMirror 2 7000020C*/
+ 0x0F120000, /*REG_3TC_PCFG_uRotation 2 7000020E*/
+ 0x002A0238,
+ 0x0F120001, /*REG_0TC_CCFG_uCaptureMode 2 70000238*/
+ 0x0F120640, /*REG_0TC_CCFG_uSWidth 2 7000023A*/
+ 0x0F1204B0, /*REG_0TC_CCFG_uSHeight 2 7000023C*/
+ 0x0F120005, /*REG_0TC_CCFG_Format 2 7000023E*/
+ 0x0F12222E, /*REG_0TC_CCFG_uSMaxOut4KHzRate 2 70000240*/
+ 0x0F12222E, /*REG_0TC_CCFG_uSMinOut4KHzRate 2 70000242*/
+ 0x0F120042, /*REG_0TC_CCFG_PVIMaSk 2 70000244*/
+ 0x0F120000, /*REG_0TC_CCFG_OIFMaSk 2 70000246*/
+ 0x0F120001, /*REG_0TC_CCFG_uClockInd 2 70000248*/
+ 0x0F120002, /*REG_0TC_CCFG_uSFrTimeType 2 7000024A*/
+ 0x0F120002, /*REG_0TC_CCFG_FrRateQualityType 2 7000024C*/
+ 0x0F120514, /*0535 REG_0TC_CCFG_uSMaxFrTimeMSecMult10 2 7000024E*/
+ 0x0F120514, /*0535 REG_0TC_CCFG_uSMinFrTimeMSecMult10 2 70000250*/
+ 0x0F120000, /*REG_0TC_CCFG_bSmearOutput 2 70000252*/
+ 0x0F120000, /*REG_0TC_CCFG_SSaturation 2 70000254*/
+ 0x0F120000, /*REG_0TC_CCFG_SSharpBlur 2 70000256*/
+ 0x0F120000, /*REG_0TC_CCFG_SColorTemp 2 70000258*/
+ 0x0F120000, /*REG_0TC_CCFG_uDeviceGammaIndex 2 7000025A*/
+ 0x0F120001, /*REG_1TC_CCFG_uCaptureMode 2 7000025C*/
+ 0x0F120640, /*REG_1TC_CCFG_uSWidth 2 7000025E*/
+ 0x0F1204B0, /*REG_1TC_CCFG_uSHeight 2 70000260*/
+ 0x0F120005, /*REG_1TC_CCFG_Format 2 70000262*/
+ 0x0F12445C, /*222E REG_1TC_CCFG_uSMaxOut4KHzRate 2 70000264*/
+ 0x0F12445C, /*222E REG_1TC_CCFG_uSMinOut4KHzRate 2 70000266*/
+ 0x0F120042, /*REG_1TC_CCFG_PVIMaSk 2 70000268*/
+ 0x0F120010, /*0000 REG_1TC_CCFG_OIFMaSk 2 7000026A*/
+ 0x0F120000,/*0001 REG_1TC_CCFG_uClockInd 2 7000026C*/
+ 0x0F120000, /*REG_1TC_CCFG_uSFrTimeType 2 7000026E*/
+ 0x0F120002, /*REG_1TC_CCFG_FrRateQualityType 2 70000270*/
+ 0x0F121388, /*REG_1TC_CCFG_uSMaxFrTimeMSecMult10 2 70000272*/
+ 0x0F121388, /*REG_1TC_CCFG_uSMinFrTimeMSecMult10 2 70000274*/
+ 0x0F120000, /*REG_1TC_CCFG_bSmearOutput 2 70000276*/
+ 0x0F120000, /*REG_1TC_CCFG_SSaturation 2 70000278*/
+ 0x0F120000, /*REG_1TC_CCFG_SSharpBlur 2 7000027A*/
+ 0x0F120000, /*REG_1TC_CCFG_SColorTemp 2 7000027C*/
+ 0x0F120000, /*REG_1TC_CCFG_uDeviceGammaIndex 2 7000027E*/
+ 0x002A1218,
+ 0x0F120002, /*SenHal_SenBinFactor*/
+ 0xFFFF0064,
+ 0x00287000,
+ 0x002A0CC0,
+ 0x0F120001, /*AFC_Default BIT[0] 1:60Hz 0:50Hz*/
+ 0x002A0374,
+ 0x0F12067F, /*REG_TC_DBG BIT[5] : Auto Flicker Disable*/
+
+ /*Int Time limit*/
+ 0x00287000,
+ 0x002A1220,
+ 0x0F1201B7, /*senHal_ExpMinPixels*/
+
+ 0x002A10C0,
+ 0x0F120040, /*TVAR_ae_BrAve*/
+ 0x002A10C6,
+ 0x0F12000F, /*ae_StatMode*/
+ 0x002A03B2,
+ 0x0F12010E, /*lt_uLimitHigh*/
+ 0x0F1200F5, /*lt_uLimitLow*/
+ 0x002A03C4,
+ 0x0F123415, /*lt_uMaxExp1 3415h=13333d/400d=33.3325ms*/
+ 0x002A03C8,
+ 0x0F12681F, /*lt_uMaxExp2 681Fh=26655d/400d=66.6375ms*/
+ 0x002A03CC,
+ 0x0F128227, /*lt_uMaxExp3 8227h=33319d/400d=83.2975ms*/
+ 0x002A03D0,
+ 0x0F120D40, /*lt_uMaxExp4 30D40h=50000d/400d=500ms*/
+ 0x0F120003,
+ 0x002A03D4,
+ 0x0F123415, /*lt_uCapMaxExp1 3415h=13333d/400d=33.3325ms*/
+ 0x002A03D8,
+ 0x0F12681F, /*lt_uCapMaxExp2 681Fh=26655d/400d=66.6375ms*/
+ 0x002A03DC,
+ 0x0F128227, /*lt_uCapMaxExp3 8227h=33319d/400d=83.2975ms*/
+ 0x002A03E0,
+ 0x0F120D40, /*lt_uCapMaxExp4 30D40h=50000d/400d=500ms*/
+ 0x0F120003,
+ 0x002A03E4,
+ 0x0F120230, /*lt_uMaxAnGain1 0230h=0560d/256d=x2.1875*/
+ 0x0F120260, /*lt_uMaxAnGain2 0260h=0608d/256d=x2.375*/
+ 0x0F120370, /*lt_uMaxAnGain3 0370h=0704d/256d=x3.4375*/
+ 0x0F120880, /*lt_uMaxAnGain4 0710h=2176d/256d=x8.5*/
+ 0x0F120100, /*lt_uMaxDigGain*/
+ 0x0F128000, /*lt_uMaxTotGain*/
+ 0x0F120230, /*lt_uCapMaxAnGain1 0230h=0560d/256d=x2.1875*/
+ 0x0F120260, /*lt_uCapMaxAnGain2 0260h=0608d/256d=x2.375*/
+ 0x0F120380, /*lt_uCapMaxAnGain3 0370h=0704d/256d=x3.4375*/
+ 0x0F120880, /*lt_uCapMaxAnGain4 0710h=2176d/256d=x8.5*/
+ 0x0F120100, /*lt_uCapMaxDigGain*/
+ 0x0F128000, /*lt_uCapMaxTotGain*/
+ 0x002A10CE,
+ 0x0F120000, /*ae_WeightTbl_16[0]*/
+ 0x0F120101, /*ae_WeightTbl_16[1]*/
+ 0x0F120101, /*ae_WeightTbl_16[2]*/
+ 0x0F120000, /*ae_WeightTbl_16[3]*/
+ 0x0F120101, /*ae_WeightTbl_16[4]*/
+ 0x0F120101, /*ae_WeightTbl_16[5]*/
+ 0x0F120101, /*ae_WeightTbl_16[6]*/
+ 0x0F120101, /*ae_WeightTbl_16[7]*/
+ 0x0F120201, /*ae_WeightTbl_16[8]*/
+ 0x0F120303, /*ae_WeightTbl_16[9]*/
+ 0x0F120303, /*ae_WeightTbl_16[10]*/
+ 0x0F120102, /*ae_WeightTbl_16[11]*/
+ 0x0F120201, /*ae_WeightTbl_16[12]*/
+ 0x0F120403, /*ae_WeightTbl_16[13]*/
+ 0x0F120304, /*ae_WeightTbl_16[14]*/
+ 0x0F120102, /*ae_WeightTbl_16[15]*/
+ 0x0F120201, /*ae_WeightTbl_16[16]*/
+ 0x0F120403, /*ae_WeightTbl_16[17]*/
+ 0x0F120304, /*ae_WeightTbl_16[18]*/
+ 0x0F120102, /*ae_WeightTbl_16[19]*/
+ 0x0F120201, /*ae_WeightTbl_16[20]*/
+ 0x0F120403, /*ae_WeightTbl_16[21]*/
+ 0x0F120304, /*ae_WeightTbl_16[22]*/
+ 0x0F120102, /*ae_WeightTbl_16[23]*/
+ 0x0F120201, /*ae_WeightTbl_16[24]*/
+ 0x0F120303, /*ae_WeightTbl_16[25]*/
+ 0x0F120303, /*ae_WeightTbl_16[26]*/
+ 0x0F120102, /*ae_WeightTbl_16[27]*/
+ 0x0F120201, /*ae_WeightTbl_16[28]*/
+ 0x0F120202, /*ae_WeightTbl_16[29]*/
+ 0x0F120202, /*ae_WeightTbl_16[30]*/
+ 0x0F120102, /*ae_WeightTbl_16[31]*/
+ 0x002A0DCC, /*AWB Init White Locus*/
+ 0x0F120138, /*awbb_IntcR*/
+ 0x0F12011C, /*awbb_IntcB*/
+ 0x0F1202A7, /*awbb_GLocusR*/
+ 0x0F120343, /*awbb_GLocusB*/
+ 0x002A0DEC,
+ 0x0F1205F0, /*awbb_GamutWidthThr1*/
+ 0x0F1201F4, /*awbb_GamutHeightThr1*/
+ 0x0F12006C, /*awbb_GamutWidthThr2*/
+ 0x0F120038, /*awbb_GamutHeightThr2*/
+ 0x002A0DD8,
+ 0x0F12000C, /*awbb_MinNumOfFinalPatches*/
+ 0x002A0E50,
+ 0x0F12FE82, /*awbb_SCDetectionMap_SEC_StartR_B*/
+ 0x0F12001E, /*awbb_SCDetectionMap_SEC_StepR_B*/
+ 0x0F120640, /*awbb_SCDetectionMap_SEC_SunnyNB*/
+ 0x0F120122, /*awbb_SCDetectionMap_SEC_StepNB*/
+ 0x0F1200E4, /*awbb_SCDetectionMap_SEC_LowTempR_B*/
+ 0x0F120096, /*awbb_SCDetectionMap_SEC_SunnyNBZone*/
+ 0x0F12000E, /*awbb_SCDetectionMap_SEC_LowTempR_BZone*/
+ 0x002A0DB4, /*LowTemp Zone*/
+ 0x0F12036C, /*awbb_CrclLowT_R_c*/
+ 0x002A0DB8,
+ 0x0F12011D, /*awbb_CrclLowT_B_c*/
+ 0x002A0DBC,
+ 0x0F1262C1, /*awbb_CrclLowT_Rad_c*/
+ 0x002A22BA,
+ 0x0F120006, /*Mon_AWB_ByPassMode*/
+ 0x002A0DEA,
+ 0x0F120000, /*awbb_movingscale10*/
+ 0x002A0F7A,
+ 0x0F120000, /*awbb_RGainOff*/
+ 0x0F120000, /*awbb_BGainOff*/
+ 0x0F120000, /*awbb_GGainOff*/
+ 0x0F1200C2, /*awbb_Alpha_Comp_Mode*/
+ 0x0F120002, /*awbb_Rpl_InvalidOutDoor*/
+ 0x0F120001, /*awbb_UseGrThrCorr*/
+ 0x0F1200E4, /*awbb_Use_Filters*/
+
+ 0x0F12053C, /*awbb_GainsInit[0]*/
+ 0x0F120400, /*awbb_GainsInit[1]*/
+ 0x0F1207ac, /*7AC, 55C, *awbb_GainsInit[2]*/
+
+ 0x0F12001E, /*awbb_WpFilterMinThr*/
+ 0x0F120190, /*awbb_WpFilterMaxThr*/
+ 0x0F120010, /*awbb_WpFilterCoef*/
+ 0x0F120004, /*awbb_WpFilterSize*/
+ 0x0F120001, /*awbb_otp_disable*/
+ 0x0F120002, /*awbb_GridEnable*/
+ 0x002A0CE0,
+ 0x0F1203F8, /*03F8 03B5 awbb_IndoorGrZones_m_BGrid[0]*/
+ 0x0F120422, /*0422 03DF awbb_IndoorGrZones_m_BGrid[1]*/
+ 0x0F120390, /*03B4 032D awbb_IndoorGrZones_m_BGrid[2]*/
+ 0x0F12042A, /*0408 03D5 awbb_IndoorGrZones_m_BGrid[3]*/
+ 0x0F120352, /*0370 0303 awbb_IndoorGrZones_m_BGrid[4]*/
+ 0x0F12041E, /*03EE 03BB awbb_IndoorGrZones_m_BGrid[5]*/
+ 0x0F120318, /*032C 02DB awbb_IndoorGrZones_m_BGrid[6]*/
+ 0x0F1203DC, /*03FC, 03D4 0397 awbb_IndoorGrZones_m_BGrid[7]*/
+ 0x0F1202E4, /*02E4, 0302 02B1 awbb_IndoorGrZones_m_BGrid[8]*/
+ 0x0F12039C, /*03BA, 03BA 036B awbb_IndoorGrZones_m_BGrid[9]*/
+ 0x0F1202B8, /*02B8, 02DA 0289 awbb_IndoorGrZones_m_BGrid[10]*/
+ 0x0F120368, /*037E, 0374 0349 awbb_IndoorGrZones_m_BGrid[11]*/
+ 0x0F120290, /*0290, 02B0 026F awbb_IndoorGrZones_m_BGrid[12]*/
+ 0x0F12033E, /*034A, 0328 0329 awbb_IndoorGrZones_m_BGrid[13]*/
+ 0x0F120274, /*0274, 0288 0257 awbb_IndoorGrZones_m_BGrid[14]*/
+ 0x0F120316, /*031A, 0300 0309 awbb_IndoorGrZones_m_BGrid[15]*/
+ 0x0F120252, /*0270 0241 awbb_IndoorGrZones_m_BGrid[16]*/
+ 0x0F1202F8, /*02DE 02DD awbb_IndoorGrZones_m_BGrid[17]*/
+ 0x0F120232, /*0258 0227 awbb_IndoorGrZones_m_BGrid[18]*/
+ 0x0F1202E0, /*02BE 02C3 awbb_IndoorGrZones_m_BGrid[19]*/
+ 0x0F12021E, /*0240 0213 awbb_IndoorGrZones_m_BGrid[20]*/
+ 0x0F1202C8, /*02A0 02AF awbb_IndoorGrZones_m_BGrid[21]*/
+ 0x0F120206, /*0228 0209 awbb_IndoorGrZones_m_BGrid[22]*/
+ 0x0F1202B2, /*0296 0295 awbb_IndoorGrZones_m_BGrid[23]*/
+ 0x0F1201FA, /*0212 020D awbb_IndoorGrZones_m_BGrid[24]*/
+ 0x0F1202A2, /*0284 0285 awbb_IndoorGrZones_m_BGrid[25]*/
+ 0x0F1201F4, /*0208 0223 awbb_IndoorGrZones_m_BGrid[26]*/
+ 0x0F120294, /*0274 0261 awbb_IndoorGrZones_m_BGrid[27]*/
+ 0x0F120200, /*020C 0000 awbb_IndoorGrZones_m_BGrid[28]*/
+ 0x0F120288, /*026E 0000 awbb_IndoorGrZones_m_BGrid[29]*/
+ 0x0F120214, /*0222 0000 awbb_IndoorGrZones_m_BGrid[30]*/
+ 0x0F120250, /*0260 0000 awbb_IndoorGrZones_m_BGrid[31]*/
+ 0x0F120000, /*0000 0000 awbb_IndoorGrZones_m_BGrid[32]*/
+ 0x0F120000, /*0000 0000 awbb_IndoorGrZones_m_BGrid[33]*/
+ 0x0F120000, /*0000 0000 awbb_IndoorGrZones_m_BGrid[34]*/
+ 0x0F120000, /*0000 0000 awbb_IndoorGrZones_m_BGrid[35]*/
+ 0x0F120000, /*0000 0000 awbb_IndoorGrZones_m_BGrid[36]*/
+ 0x0F120000, /*0000 0000 awbb_IndoorGrZones_m_BGrid[37]*/
+ 0x0F120000, /*0000 0000 awbb_IndoorGrZones_m_BGrid[38]*/
+ 0x0F120000, /*0000 0000 awbb_IndoorGrZones_m_BGrid[39]*/
+ 0x0F120005, /*awbb_IndoorGrZones_m_GridStep*/
+ 0x002A0D34,
+ 0x0F120010, /*awbb_IndoorGrZones_ZInfo_m_GridSz*/
+ 0x002A0D38,
+ 0x0F1200FE, /*awbb_IndoorGrZones_m_Boff*/
+ 0x002A0D3C,
+ 0x0F120294, /*0294 02A4 02B0 02B6 02B8 02A2 02B8
+ 029F awbb_OutdoorGrZones_m_BGrid[0]*/
+ 0x0F1202F2, /*02F2 02F2 02F0 02F2 02F2 02D4 02F2
+ 02CE awbb_OutdoorGrZones_m_BGrid[1]*/
+ 0x0F120276, /*0276 0276 028A 0276 028E 0282 028E
+ 0282 awbb_OutdoorGrZones_m_BGrid[2]*/
+ 0x0F12030A, /*030A 030A 02FC 030A 030A 02EE 030A
+ 02DA awbb_OutdoorGrZones_m_BGrid[3]*/
+ 0x0F120258, /*0258 0258 026C 0258 026E 027A 027A
+ 026D awbb_OutdoorGrZones_m_BGrid[4]*/
+ 0x0F12030A, /*0302 0302 030A 0302 030A 030A 030A
+ 02C2 awbb_OutdoorGrZones_m_BGrid[5]*/
+ 0x0F120246, /*0246 0246 0258 0246 025E 027A 0274
+ 0256 awbb_OutdoorGrZones_m_BGrid[6]*/
+ 0x0F1202FA, /*02EA 02EA 0302 02EA 02FE 030A 02FE
+ 02A6 awbb_OutdoorGrZones_m_BGrid[7]*/
+ 0x0F120256, /*0256 0256 0246 0256 0264 0274 0282
+ 026E awbb_OutdoorGrZones_m_BGrid[8]*/
+ 0x0F1202DC, /*02B8 02B8 02EA 02B8 02D0 02FE 02DC
+ 028A awbb_OutdoorGrZones_m_BGrid[9]*/
+ 0x0F120000, /*0000 0000 0256 0000 0000 0282 0000
+ 0000 awbb_OutdoorGrZones_m_BGrid[10]*/
+ 0x0F120000, /*0000 0000 02B8 0000 0000 02DC 0000
+ 0000 awbb_OutdoorGrZones_m_BGrid[11]*/
+ 0x0F120000, /*0000 0000 0000 0000 0000 0000 0000
+ 0000 awbb_OutdoorGrZones_m_BGrid[12]*/
+ 0x0F120000, /*0000 0000 0000 0000 0000 0000 0000
+ 0000 awbb_OutdoorGrZones_m_BGrid[13]*/
+ 0x0F120000, /*0000 0000 0000 0000 0000 0000 0000
+ 0000 awbb_OutdoorGrZones_m_BGrid[14]*/
+ 0x0F120000, /*0000 0000 0000 0000 0000 0000 0000
+ 0000 awbb_OutdoorGrZones_m_BGrid[15]*/
+ 0x0F120000, /*0000 0000 0000 0000 0000 0000 0000
+ 0000 awbb_OutdoorGrZones_m_BGrid[16]*/
+ 0x0F120000, /*0000 0000 0000 0000 0000 0000 0000
+ 0000 awbb_OutdoorGrZones_m_BGrid[17]*/
+ 0x0F120000, /*0000 0000 0000 0000 0000 0000 0000
+ 0000 awbb_OutdoorGrZones_m_BGrid[18]*/
+ 0x0F120000, /*0000 0000 0000 0000 0000 0000 0000
+ 0000 awbb_OutdoorGrZones_m_BGrid[19]*/
+ 0x0F120000, /*0000 0000 0000 0000 0000 0000 0000
+ 0000 awbb_OutdoorGrZones_m_BGrid[20]*/
+ 0x0F120000, /*0000 0000 0000 0000 0000 0000 0000
+ 0000 awbb_OutdoorGrZones_m_BGrid[21]*/
+ 0x0F120000, /*0000 0000 0000 0000 0000 0000 0000
+ 0000 awbb_OutdoorGrZones_m_BGrid[22]*/
+ 0x0F120000, /*0000 0000 0000 0000 0000 0000 0000
+ 0000 awbb_OutdoorGrZones_m_BGrid[23]*/
+ 0x0F120005, /*awbb_OutdoorGrZones_m_GridStep*/
+ 0x002A0D70,
+ 0x0F120005, /*awbb_OutdoorGrZones_ZInfo_m_GridSz*/
+ 0x002A0D74,
+ 0x0F1201EB, /*awbb_OutdoorGrZones_m_Boffs*/
+ 0x002A0D78,
+ 0x0F1203CE, /*awbb_LowBrGrZones_m_BGrid[0]*/
+ 0x0F12046E, /*awbb_LowBrGrZones_m_BGrid[1]*/
+ 0x0F12034E, /*awbb_LowBrGrZones_m_BGrid[2]*/
+ 0x0F120474, /*awbb_LowBrGrZones_m_BGrid[3]*/
+ 0x0F1202EA, /*awbb_LowBrGrZones_m_BGrid[4]*/
+ 0x0F120434, /*awbb_LowBrGrZones_m_BGrid[5]*/
+ 0x0F12028C, /*awbb_LowBrGrZones_m_BGrid[6]*/
+ 0x0F1203F0, /*awbb_LowBrGrZones_m_BGrid[7]*/
+ 0x0F120244, /*awbb_LowBrGrZones_m_BGrid[8]*/
+ 0x0F120380, /*awbb_LowBrGrZones_m_BGrid[9]*/
+ 0x0F12020E, /*awbb_LowBrGrZones_m_BGrid[10]*/
+ 0x0F120330, /*awbb_LowBrGrZones_m_BGrid[11]*/
+ 0x0F1201EC, /*awbb_LowBrGrZones_m_BGrid[12]*/
+ 0x0F1202EC, /*awbb_LowBrGrZones_m_BGrid[13]*/
+ 0x0F1201D0, /*awbb_LowBrGrZones_m_BGrid[14]*/
+ 0x0F1202BC, /*awbb_LowBrGrZones_m_BGrid[15]*/
+ 0x0F1201C8, /*awbb_LowBrGrZones_m_BGrid[16]*/
+ 0x0F120296, /*awbb_LowBrGrZones_m_BGrid[17]*/
+ 0x0F1201D2, /*awbb_LowBrGrZones_m_BGrid[18]*/
+ 0x0F120266, /*awbb_LowBrGrZones_m_BGrid[19]*/
+ 0x0F120000, /*awbb_LowBrGrZones_m_BGrid[20]*/
+ 0x0F120000, /*awbb_LowBrGrZones_m_BGrid[21]*/
+ 0x0F120000, /*awbb_LowBrGrZones_m_BGrid[22]*/
+ 0x0F120000, /*awbb_LowBrGrZones_m_BGrid[23]*/
+ 0x0F120006, /*awbb_LowBrGrZones_m_GridStep*/
+ 0x002A0DAC,
+ 0x0F12000A, /*awbb_LowBrGrZones_ZInfo_m_GridSz*/
+ 0x002A0DB0,
+ 0x0F1200E2, /*awbb_LowBrGrZones_m_Boffs*/
+ 0x002A0F60,
+ 0x0F1202E2, /*awbb_GridConst_1[0]*/
+ 0x0F12034B, /*awbb_GridConst_1[1]*/
+ 0x0F120399, /*awbb_GridConst_1[2]*/
+ 0x0F12102D, /*awbb_GridConst_2[0]*/
+ 0x0F1210DE, /*awbb_GridConst_2[1]*/
+ 0x0F12116E, /*awbb_GridConst_2[2]*/
+ 0x0F12117B, /*awbb_GridConst_2[3]*/
+ 0x0F12120A, /*11FF awbb_GridConst_2[4]*/
+ 0x0F121247, /*awbb_GridConst_2[5]*/
+ 0x0F1202C4, /*awbb_GridCoeff_R_1*/
+ 0x0F1202E4, /*awbb_GridCoeff_B_1*/
+ 0x0F1200C3, /*awbb_GridCoeff_R_2*/
+ 0x0F1200A6, /*awbb_GridCoeff_B_2*/
+ 0x002A0ED0,
+ 0x0F120046, /*0046, 0046 000A 000A awbb_GridCorr_R[0][0]*/
+ 0x0F120000, /*0000, 0028 0028 0028 awbb_GridCorr_R[0][1]*/
+ 0x0F120000, /*0000, 0028 0028 0028 awbb_GridCorr_R[0][2]*/
+ 0x0F12FFEC, /*FFEC, FFEC FFEC FFEC awbb_GridCorr_R[0][3]*/
+ 0x0F12FFEC, /*FFEC, FFEC FFEC FFEC awbb_GridCorr_R[0][4]*/
+ 0x0F120028, /*0028, 0028 0000 001E awbb_GridCorr_R[0][5]*/
+ 0x0F120046, /*0046, 0046 000A 000A awbb_GridCorr_R[1][0]*/
+ 0x0F120000, /*0000, 0028 0028 0028 awbb_GridCorr_R[1][1]*/
+ 0x0F120000, /*0000, 0028 0028 0028 awbb_GridCorr_R[1][2]*/
+ 0x0F12FFEC, /*FFEC, FFEC FFEC FFEC awbb_GridCorr_R[1][3]*/
+ 0x0F12FFEC, /*FFEC, FFEC FFEC FFEC awbb_GridCorr_R[1][4]*/
+ 0x0F120028, /*0028, 0028 0000 001E awbb_GridCorr_R[1][5]*/
+ 0x0F120046, /*0046, 0046 000A 000A awbb_GridCorr_R[2][0]*/
+ 0x0F120000, /*0000, 0028 0028 0028 awbb_GridCorr_R[2][1]*/
+ 0x0F120000, /*0000, 0028 0028 0028 awbb_GridCorr_R[2][2]*/
+ 0x0F12FFEC, /*FFEC, FFEC FFEC FFEC awbb_GridCorr_R[2][3]*/
+ 0x0F12FFEC, /*FFEC, FFEC FFEC FFEC awbb_GridCorr_R[2][4]*/
+ 0x0F120028, /*0028, 0028 0000 001E awbb_GridCorr_R[2][5]*/
+ 0x0F12FFD8, /*FFD8, FFD8 FFD8 FFD8 awbb_GridCorr_B[0][0]*/
+ 0x0F12FFCE, /*0050, 003C 003C 003C awbb_GridCorr_B[0][1]*/
+ 0x0F12FFCE, /*0050, 003C 003C 003C awbb_GridCorr_B[0][2]*/
+ 0x0F12FFCE, /*FFCE, FFCE FFCE 0000 awbb_GridCorr_B[0][3]*/
+ 0x0F12FFCE, /*FFCE, FFCE FFCE 0000 awbb_GridCorr_B[0][4]*/
+ 0x0F12FF9C, /*FF9C, FF9C FE70 001E awbb_GridCorr_B[0][5]*/
+ 0x0F12FFD8, /*FFD8, FFD8 FFD8 FFD8 awbb_GridCorr_B[1][0]*/
+ 0x0F12FFCE, /*0050, 003C 003C 003C awbb_GridCorr_B[1][1]*/
+ 0x0F12FFCE, /*0050, 003C 003C 003C awbb_GridCorr_B[1][2]*/
+ 0x0F12FFCE, /*FFCE, FFCE FFCE 0000 awbb_GridCorr_B[1][3]*/
+ 0x0F12FFCE, /*FFCE, FFCE FFCE 0000 awbb_GridCorr_B[1][4]*/
+ 0x0F12FF9C, /*FF9C, FF9C FE70 001E awbb_GridCorr_B[1][5]*/
+ 0x0F12FFD8, /*FFD8, FFD8 FFD8 FFD8 awbb_GridCorr_B[2][0]*/
+ 0x0F12FFCE, /*0050, 003C 003C 003C awbb_GridCorr_B[2][1]*/
+ 0x0F12FFCE, /*0050, 003C 003C 003C awbb_GridCorr_B[2][2]*/
+ 0x0F12FFCE, /*FFCE, FFCE FFCE 0000 awbb_GridCorr_B[2][3]*/
+ 0x0F12FFCE, /*FFCE, FFCE FFCE 0000 awbb_GridCorr_B[2][4]*/
+ 0x0F12FF9C, /*FF9C, FF9C FE70 001E awbb_GridCorr_B[2][5]*/
+ 0x0F120000, /*awbb_GridCorr_R_Out[0][0]*/
+ 0x0F12FFE0, /*awbb_GridCorr_R_Out[0][1]*/
+ 0x0F120000, /*awbb_GridCorr_R_Out[0][2]*/
+ 0x0F120000, /*awbb_GridCorr_R_Out[0][3]*/
+ 0x0F120000, /*awbb_GridCorr_R_Out[0][4]*/
+ 0x0F120000, /*awbb_GridCorr_R_Out[0][5]*/
+ 0x0F120000, /*awbb_GridCorr_R_Out[1][0]*/
+ 0x0F12FFE0, /*awbb_GridCorr_R_Out[1][1]*/
+ 0x0F120000, /*awbb_GridCorr_R_Out[1][2]*/
+ 0x0F120000, /*awbb_GridCorr_R_Out[1][3]*/
+ 0x0F120000, /*awbb_GridCorr_R_Out[1][4]*/
+ 0x0F120000, /*awbb_GridCorr_R_Out[1][5]*/
+ 0x0F120000, /*awbb_GridCorr_R_Out[2][0]*/
+ 0x0F12FFE0, /*awbb_GridCorr_R_Out[2][1]*/
+ 0x0F120000, /*awbb_GridCorr_R_Out[2][2]*/
+ 0x0F120000, /*awbb_GridCorr_R_Out[2][3]*/
+ 0x0F120000, /*awbb_GridCorr_R_Out[2][4]*/
+ 0x0F120000, /*awbb_GridCorr_R_Out[2][5]*/
+ 0x0F120000, /*awbb_GridCorr_B_Out[0][0]*/
+ 0x0F12FFDE, /*awbb_GridCorr_B_Out[0][1]*/
+ 0x0F120000, /*awbb_GridCorr_B_Out[0][2]*/
+ 0x0F120000, /*awbb_GridCorr_B_Out[0][3]*/
+ 0x0F120000, /*awbb_GridCorr_B_Out[0][4]*/
+ 0x0F120000, /*awbb_GridCorr_B_Out[0][5]*/
+ 0x0F120000, /*awbb_GridCorr_B_Out[1][0]*/
+ 0x0F12FFDE, /*awbb_GridCorr_B_Out[1][1]*/
+ 0x0F120000, /*awbb_GridCorr_B_Out[1][2]*/
+ 0x0F120000, /*awbb_GridCorr_B_Out[1][3]*/
+ 0x0F120000, /*awbb_GridCorr_B_Out[1][4]*/
+ 0x0F120000, /*awbb_GridCorr_B_Out[1][5]*/
+ 0x0F120000, /*awbb_GridCorr_B_Out[2][0]*/
+ 0x0F12FFDE, /*awbb_GridCorr_B_Out[2][1]*/
+ 0x0F120000, /*awbb_GridCorr_B_Out[2][2]*/
+ 0x0F120000, /*awbb_GridCorr_B_Out[2][3]*/
+ 0x0F120000, /*awbb_GridCorr_B_Out[2][4]*/
+ 0x0F120000, /*awbb_GridCorr_B_Out[2][5]*/
+ 0x002A05D2,
+ 0x0F1200E4, /*SARR_AwbCcmCord[0]*/
+ 0x0F1200F0, /*SARR_AwbCcmCord[1]*/
+ 0x0F120100, /*SARR_AwbCcmCord[2]*/
+ 0x0F120120, /*SARR_AwbCcmCord[3]*/
+ 0x0F120150, /*SARR_AwbCcmCord[4]*/
+ 0x0F120180, /*SARR_AwbCcmCord[5]*/
+ 0x002A05C4,
+ 0x0F123800, /*TVAR_wbt_pBaseCcms*/
+ 0x0F127000,
+ 0x002A05CC,
+ 0x0F1238D8, /*TVAR_wbt_pOutdoorCcm*/
+ 0x0F127000,
+ 0x002A3800,
+ 0x0F1201D0, /*TVAR_wbt_pBaseCcms[0]*/
+ 0x0F12FFA1, /*TVAR_wbt_pBaseCcms[1]*/
+ 0x0F12FFFA, /*TVAR_wbt_pBaseCcms[2]*/
+ 0x0F12FF6F, /*TVAR_wbt_pBaseCcms[3]*/
+ 0x0F120140, /*TVAR_wbt_pBaseCcms[4]*/
+ 0x0F12FF49, /*TVAR_wbt_pBaseCcms[5]*/
+ 0x0F12FFC1, /*TVAR_wbt_pBaseCcms[6]*/
+ 0x0F12001F, /*TVAR_wbt_pBaseCcms[7]*/
+ 0x0F1201BD, /*TVAR_wbt_pBaseCcms[8]*/
+ 0x0F12013F, /*TVAR_wbt_pBaseCcms[9]*/
+ 0x0F1200E1, /*TVAR_wbt_pBaseCcms[10]*/
+ 0x0F12FF43, /*TVAR_wbt_pBaseCcms[11]*/
+ 0x0F120191, /*TVAR_wbt_pBaseCcms[12]*/
+ 0x0F12FFC0, /*TVAR_wbt_pBaseCcms[13]*/
+ 0x0F1201B7, /*TVAR_wbt_pBaseCcms[14]*/
+ 0x0F12FF30, /*TVAR_wbt_pBaseCcms[15]*/
+ 0x0F12015F, /*TVAR_wbt_pBaseCcms[16]*/
+ 0x0F120106, /*TVAR_wbt_pBaseCcms[17]*/
+ 0x0F1201D0, /*TVAR_wbt_pBaseCcms[18]*/
+ 0x0F12FFA1, /*TVAR_wbt_pBaseCcms[19]*/
+ 0x0F12FFFA, /*TVAR_wbt_pBaseCcms[20]*/
+ 0x0F12FF6F, /*TVAR_wbt_pBaseCcms[21]*/
+ 0x0F120140, /*TVAR_wbt_pBaseCcms[22]*/
+ 0x0F12FF49, /*TVAR_wbt_pBaseCcms[23]*/
+ 0x0F12FFC1, /*TVAR_wbt_pBaseCcms[24]*/
+ 0x0F12001F, /*TVAR_wbt_pBaseCcms[25]*/
+ 0x0F1201BD, /*TVAR_wbt_pBaseCcms[26]*/
+ 0x0F12013F, /*TVAR_wbt_pBaseCcms[27]*/
+ 0x0F1200E1, /*TVAR_wbt_pBaseCcms[28]*/
+ 0x0F12FF43, /*TVAR_wbt_pBaseCcms[29]*/
+ 0x0F120191, /*TVAR_wbt_pBaseCcms[30]*/
+ 0x0F12FFC0, /*TVAR_wbt_pBaseCcms[31]*/
+ 0x0F1201B7, /*TVAR_wbt_pBaseCcms[32]*/
+ 0x0F12FF30, /*TVAR_wbt_pBaseCcms[33]*/
+ 0x0F12015F, /*TVAR_wbt_pBaseCcms[34]*/
+ 0x0F120106, /*TVAR_wbt_pBaseCcms[35]*/
+ 0x0F1201C4, /*01D3 01D0 TVAR_wbt_pBaseCcms[36]*/
+ 0x0F12FFAC, /*FFBB FFA1 TVAR_wbt_pBaseCcms[37]*/
+ 0x0F12FFFB, /*FFDD FFFA TVAR_wbt_pBaseCcms[38]*/
+ 0x0F12FF6F, /*FF6F FF6F TVAR_wbt_pBaseCcms[39]*/
+ 0x0F120140, /*0140 0140 TVAR_wbt_pBaseCcms[40]*/
+ 0x0F12FF49, /*FF49 FF49 TVAR_wbt_pBaseCcms[41]*/
+ 0x0F12FFC1, /*FFC1 FFC1 TVAR_wbt_pBaseCcms[42]*/
+ 0x0F12001F, /*001F 001F TVAR_wbt_pBaseCcms[43]*/
+ 0x0F1201BD, /*01BD 01BD TVAR_wbt_pBaseCcms[44]*/
+ 0x0F12013F, /*013F 013F TVAR_wbt_pBaseCcms[45]*/
+ 0x0F1200E1, /*00E1 00E1 TVAR_wbt_pBaseCcms[46]*/
+ 0x0F12FF43, /*FF43 FF43 TVAR_wbt_pBaseCcms[47]*/
+ 0x0F120191, /*0191 0191 TVAR_wbt_pBaseCcms[48]*/
+ 0x0F12FFC0, /*FFC0 FFC0 TVAR_wbt_pBaseCcms[49]*/
+ 0x0F1201B7, /*01B7 01B7 TVAR_wbt_pBaseCcms[50]*/
+ 0x0F12FF30, /*FF30 FF30 TVAR_wbt_pBaseCcms[51]*/
+ 0x0F12015F, /*015F 015F TVAR_wbt_pBaseCcms[52]*/
+ 0x0F120106, /*0106 0106 TVAR_wbt_pBaseCcms[53]*/
+ 0x0F1201B5, /*01C6, 01D0 TVAR_wbt_pBaseCcms[54]*/
+ 0x0F12FFC6, /*FFBE, FFA1 TVAR_wbt_pBaseCcms[55]*/
+ 0x0F12FFEF, /*FFE6, FFFA TVAR_wbt_pBaseCcms[56]*/
+ 0x0F12FF6F, /*FF6F, FF6F TVAR_wbt_pBaseCcms[57]*/
+ 0x0F120140, /*0140, 0140 TVAR_wbt_pBaseCcms[58]*/
+ 0x0F12FF49, /*FF49, FF49 TVAR_wbt_pBaseCcms[59]*/
+ 0x0F12FFC1, /*FFC1, FFC1 TVAR_wbt_pBaseCcms[60]*/
+ 0x0F12001F, /*001F, 001F TVAR_wbt_pBaseCcms[61]*/
+ 0x0F1201BD, /*01BD, 01BD TVAR_wbt_pBaseCcms[62]*/
+ 0x0F12013F, /*013F, 013F TVAR_wbt_pBaseCcms[63]*/
+ 0x0F1200E1, /*00E1, 00E1 TVAR_wbt_pBaseCcms[64]*/
+ 0x0F12FF43, /*FF43, FF43 TVAR_wbt_pBaseCcms[65]*/
+ 0x0F120191, /*0191, 0191 TVAR_wbt_pBaseCcms[66]*/
+ 0x0F12FFC0, /*FFC0, FFC0 TVAR_wbt_pBaseCcms[67]*/
+ 0x0F1201B7, /*01B7, 01B7 TVAR_wbt_pBaseCcms[68]*/
+ 0x0F12FF30, /*FF30, FF30 TVAR_wbt_pBaseCcms[69]*/
+ 0x0F12015F, /*015F, 015F TVAR_wbt_pBaseCcms[70]*/
+ 0x0F120106, /*0106, 0106 TVAR_wbt_pBaseCcms[71]*/
+ 0x0F1201B7, /*C8 01BF TVAR_wbt_pBaseCcms[72]*/
+ 0x0F12FFC4, /*FFBA FFBF TVAR_wbt_pBaseCcms[73]*/
+ 0x0F120001, /*FFE8 FFFE TVAR_wbt_pBaseCcms[74]*/
+ 0x0F12FF6D, /*FF6D FF6F FF6D TVAR_wbt_pBaseCcms[75]*/
+ 0x0F1201B4, /*01B4 0140 01B4 TVAR_wbt_pBaseCcms[76]*/
+ 0x0F12FF66, /*FF66 FF49 FF66 TVAR_wbt_pBaseCcms[77]*/
+ 0x0F12FFCA, /*FFCA FFC1 FFCA TVAR_wbt_pBaseCcms[78]*/
+ 0x0F12FFCE, /*FFCE 001F FFCE TVAR_wbt_pBaseCcms[79]*/
+ 0x0F12017B, /*017B 01BD 017B TVAR_wbt_pBaseCcms[80]*/
+ 0x0F120136, /*0136 013F 0136 TVAR_wbt_pBaseCcms[81]*/
+ 0x0F120132, /*0132 00E1 0132 TVAR_wbt_pBaseCcms[82]*/
+ 0x0F12FF85, /*FF85 FF43 FF85 TVAR_wbt_pBaseCcms[83]*/
+ 0x0F12018B, /*018B 0191 018B TVAR_wbt_pBaseCcms[84]*/
+ 0x0F12FF73, /*FF73 FFC0 FF73 TVAR_wbt_pBaseCcms[85]*/
+ 0x0F120191, /*0191 01B7 0191 TVAR_wbt_pBaseCcms[86]*/
+ 0x0F12FF3F, /*FF3F FF30 FF3F TVAR_wbt_pBaseCcms[87]*/
+ 0x0F12015B, /*015B 015F 015B TVAR_wbt_pBaseCcms[88]*/
+ 0x0F1200D0, /*00D0 0106 00D0 TVAR_wbt_pBaseCcms[89]*/
+ 0x0F1201CA, /*01CA 01C1 TVAR_wbt_pBaseCcms[90]*/
+ 0x0F12FFBE, /*FFBE FFC5 TVAR_wbt_pBaseCcms[91]*/
+ 0x0F12FFF1, /*FFF1 FFF5 TVAR_wbt_pBaseCcms[92]*/
+ 0x0F12FEFB, /*FF15 FF3B TVAR_wbt_pBaseCcms[93]*/
+ 0x0F12021C, /*01F3 0217 TVAR_wbt_pBaseCcms[94]*/
+ 0x0F12FF6B, /*FF7B FF32 TVAR_wbt_pBaseCcms[95]*/
+ 0x0F12FFC1, /*FFC1 FFC1 TVAR_wbt_pBaseCcms[96]*/
+ 0x0F12FFC5, /*FFC5 FFC5 TVAR_wbt_pBaseCcms[97]*/
+ 0x0F12018A, /*018A 018B TVAR_wbt_pBaseCcms[98]*/
+ 0x0F1200FB, /*00FB 0136 TVAR_wbt_pBaseCcms[99]*/
+ 0x0F120167, /*0167 0132 TVAR_wbt_pBaseCcms[100]*/
+ 0x0F12FF8C, /*FF8C FF85 TVAR_wbt_pBaseCcms[101]*/
+ 0x0F12018B, /*018B 018B TVAR_wbt_pBaseCcms[102]*/
+ 0x0F12FF73, /*FF73 FF73 TVAR_wbt_pBaseCcms[103]*/
+ 0x0F120191, /*0191 0191 TVAR_wbt_pBaseCcms[104]*/
+ 0x0F12FF3F, /*FF3F FF3F TVAR_wbt_pBaseCcms[105]*/
+ 0x0F12015B, /*015B 015B TVAR_wbt_pBaseCcms[106]*/
+ 0x0F1200D0, /*00D0 00D0 TVAR_wbt_pBaseCcms[107]*/
+ 0x002A38D8,
+ 0x0F120221, /*022C 0235 TVAR_wbt_pOutdoorCcm[0]*/
+ 0x0F120005, /*FFD8 FFEF TVAR_wbt_pOutdoorCcm[1]*/
+ 0x0F120012, /*0034 0014 TVAR_wbt_pOutdoorCcm[2]*/
+ 0x0F12FF67, /*FF67 FF67 TVAR_wbt_pOutdoorCcm[3]*/
+ 0x0F12027D, /*027D 027D TVAR_wbt_pOutdoorCcm[4]*/
+ 0x0F12FFBA, /*FFBA FFBA TVAR_wbt_pOutdoorCcm[5]*/
+ 0x0F12000D, /*000D 000D TVAR_wbt_pOutdoorCcm[6]*/
+ 0x0F120062, /*0062 0062 TVAR_wbt_pOutdoorCcm[7]*/
+ 0x0F1202A7, /*02A7 02A7 TVAR_wbt_pOutdoorCcm[8]*/
+ 0x0F1200C7, /*00C7 00C9 TVAR_wbt_pOutdoorCcm[9]*/
+ 0x0F12011F, /*011F 0123 TVAR_wbt_pOutdoorCcm[10]*/
+ 0x0F12FF3C, /*FF3C FF36 TVAR_wbt_pOutdoorCcm[11]*/
+ 0x0F1201AD, /*01AD 01AD TVAR_wbt_pOutdoorCcm[12]*/
+ 0x0F12FFC8, /*FFC8 FFC8 TVAR_wbt_pOutdoorCcm[13]*/
+ 0x0F120202, /*0202 0202 TVAR_wbt_pOutdoorCcm[14]*/
+ 0x0F12FFCF, /*FFCF FFCF TVAR_wbt_pOutdoorCcm[15]*/
+ 0x0F120257, /*0257 0257 TVAR_wbt_pOutdoorCcm[16]*/
+ 0x0F12022C, /*022C 022C TVAR_wbt_pOutdoorCcm[17]*/
+ 0x002A23DC,
+ 0x0F1201DD, /*Mon_AAIO_PrevFrmData_NormBr*/
+ 0x002A0460,
+ 0x0F120000, /*0000 0000 saRR_usDualGammaLutRGBIndoor[0][0]*/
+ 0x0F120004, /*0008 0002 saRR_usDualGammaLutRGBIndoor[0][1]*/
+ 0x0F12000C, /*0013 0006 saRR_usDualGammaLutRGBIndoor[0][2]*/
+ 0x0F120024, /*002C 0011 saRR_usDualGammaLutRGBIndoor[0][3]*/
+ 0x0F12006E, /*0061 0036 saRR_usDualGammaLutRGBIndoor[0][4]*/
+ 0x0F1200D1, /*00C8 009A saRR_usDualGammaLutRGBIndoor[0][5]*/
+ 0x0F120119, /*0113 00FD saRR_usDualGammaLutRGBIndoor[0][6]*/
+ 0x0F120139, /*0132 0129 saRR_usDualGammaLutRGBIndoor[0][7]*/
+ 0x0F120157, /*014C 014B saRR_usDualGammaLutRGBIndoor[0][8]*/
+ 0x0F12018E, /*0179 0184 saRR_usDualGammaLutRGBIndoor[0][9]*/
+ 0x0F1201C3, /*01A4 01B8 saRR_usDualGammaLutRGBIndoor[0][10]*/
+ 0x0F1201F3, /*01CD 01EA saRR_usDualGammaLutRGBIndoor[0][11]*/
+ 0x0F12021F, /*01F4 0216 saRR_usDualGammaLutRGBIndoor[0][12]*/
+ 0x0F120269, /*0239 025E saRR_usDualGammaLutRGBIndoor[0][13]*/
+ 0x0F1202A6, /*0278 0299 saRR_usDualGammaLutRGBIndoor[0][14]*/
+ 0x0F1202FF, /*02E0 02F9 saRR_usDualGammaLutRGBIndoor[0][15]*/
+ 0x0F120351, /*0333 0341 saRR_usDualGammaLutRGBIndoor[0][16]*/
+ 0x0F120395, /*037B 037F saRR_usDualGammaLutRGBIndoor[0][17]*/
+ 0x0F1203CE, /*03BF 03BF saRR_usDualGammaLutRGBIndoor[0][18]*/
+ 0x0F1203FF, /*03FF 03FF saRR_usDualGammaLutRGBIndoor[0][19]*/
+ 0x0F120000, /*0000 0000 saRR_usDualGammaLutRGBIndoor[1][0]*/
+ 0x0F120004, /*0008 0002 saRR_usDualGammaLutRGBIndoor[1][1]*/
+ 0x0F12000C, /*0013 0006 saRR_usDualGammaLutRGBIndoor[1][2]*/
+ 0x0F120024, /*002C 0011 saRR_usDualGammaLutRGBIndoor[1][3]*/
+ 0x0F12006E, /*0061 0036 saRR_usDualGammaLutRGBIndoor[1][4]*/
+ 0x0F1200D1, /*00C8 009A saRR_usDualGammaLutRGBIndoor[1][5]*/
+ 0x0F120119, /*0113 00FD saRR_usDualGammaLutRGBIndoor[1][6]*/
+ 0x0F120139, /*0132 0129 saRR_usDualGammaLutRGBIndoor[1][7]*/
+ 0x0F120157, /*014C 014B saRR_usDualGammaLutRGBIndoor[1][8]*/
+ 0x0F12018E, /*0179 0184 saRR_usDualGammaLutRGBIndoor[1][9]*/
+ 0x0F1201C3, /*01A4 01B8 saRR_usDualGammaLutRGBIndoor[1][10]*/
+ 0x0F1201F3, /*01CD 01EA saRR_usDualGammaLutRGBIndoor[1][11]*/
+ 0x0F12021F, /*01F4 0216 saRR_usDualGammaLutRGBIndoor[1][12]*/
+ 0x0F120269, /*0239 025E saRR_usDualGammaLutRGBIndoor[1][13]*/
+ 0x0F1202A6, /*0278 0299 saRR_usDualGammaLutRGBIndoor[1][14]*/
+ 0x0F1202FF, /*02E0 02F9 saRR_usDualGammaLutRGBIndoor[1][15]*/
+ 0x0F120351, /*0333 0341 saRR_usDualGammaLutRGBIndoor[1][16]*/
+ 0x0F120395, /*037B 037F saRR_usDualGammaLutRGBIndoor[1][17]*/
+ 0x0F1203CE, /*03BF 03BF saRR_usDualGammaLutRGBIndoor[1][18]*/
+ 0x0F1203FF, /*03FF 03FF saRR_usDualGammaLutRGBIndoor[1][19]*/
+ 0x0F120000, /*0000 0000 saRR_usDualGammaLutRGBIndoor[2][0]*/
+ 0x0F120004, /*0008 0002 saRR_usDualGammaLutRGBIndoor[2][1]*/
+ 0x0F12000C, /*0013 0006 saRR_usDualGammaLutRGBIndoor[2][2]*/
+ 0x0F120024, /*002C 0011 saRR_usDualGammaLutRGBIndoor[2][3]*/
+ 0x0F12006E, /*0061 0036 saRR_usDualGammaLutRGBIndoor[2][4]*/
+ 0x0F1200D1, /*00C8 009A saRR_usDualGammaLutRGBIndoor[2][5]*/
+ 0x0F120119, /*0113 00FD saRR_usDualGammaLutRGBIndoor[2][6]*/
+ 0x0F120139, /*0132 0129 saRR_usDualGammaLutRGBIndoor[2][7]*/
+ 0x0F120157, /*014C 014B saRR_usDualGammaLutRGBIndoor[2][8]*/
+ 0x0F12018E, /*0179 0184 saRR_usDualGammaLutRGBIndoor[2][9]*/
+ 0x0F1201C3, /*01A4 01B8 saRR_usDualGammaLutRGBIndoor[2][10]*/
+ 0x0F1201F3, /*01CD 01EA saRR_usDualGammaLutRGBIndoor[2][11]*/
+ 0x0F12021F, /*01F4 0216 saRR_usDualGammaLutRGBIndoor[2][12]*/
+ 0x0F120269, /*0239 025E saRR_usDualGammaLutRGBIndoor[2][13]*/
+ 0x0F1202A6, /*0278 0299 saRR_usDualGammaLutRGBIndoor[2][14]*/
+ 0x0F1202FF, /*02E0 02F9 saRR_usDualGammaLutRGBIndoor[2][15]*/
+ 0x0F120351, /*0333 0341 saRR_usDualGammaLutRGBIndoor[2][16]*/
+ 0x0F120395, /*037B 037F saRR_usDualGammaLutRGBIndoor[2][17]*/
+ 0x0F1203CE, /*03BF 03BF saRR_usDualGammaLutRGBIndoor[2][18]*/
+ 0x0F1203FF, /*03FF 03FF saRR_usDualGammaLutRGBIndoor[2][19]*/
+ 0x0F120000, /*0000 0000 saRR_usDualGammaLutRGBOutdoor[0][0]*/
+ 0x0F120004, /*0008 0002 saRR_usDualGammaLutRGBOutdoor[0][1]*/
+ 0x0F12000C, /*0013 0006 saRR_usDualGammaLutRGBOutdoor[0][2]*/
+ 0x0F120024, /*002C 0011 saRR_usDualGammaLutRGBOutdoor[0][3]*/
+ 0x0F12006E, /*0061 0036 saRR_usDualGammaLutRGBOutdoor[0][4]*/
+ 0x0F1200D1, /*00C8 009A saRR_usDualGammaLutRGBOutdoor[0][5]*/
+ 0x0F120119, /*0113 00FD saRR_usDualGammaLutRGBOutdoor[0][6]*/
+ 0x0F120139, /*0132 0129 saRR_usDualGammaLutRGBOutdoor[0][7]*/
+ 0x0F120157, /*014C 014B saRR_usDualGammaLutRGBOutdoor[0][8]*/
+ 0x0F12018E, /*0179 0184 saRR_usDualGammaLutRGBOutdoor[0][9]*/
+ 0x0F1201C3, /*01A4 01B8 saRR_usDualGammaLutRGBOutdoor[0][10]*/
+ 0x0F1201F3, /*01CD 01EA saRR_usDualGammaLutRGBOutdoor[0][11]*/
+ 0x0F12021F, /*01F4 0216 saRR_usDualGammaLutRGBOutdoor[0][12]*/
+ 0x0F120269, /*0239 025E saRR_usDualGammaLutRGBOutdoor[0][13]*/
+ 0x0F1202A6, /*0278 0299 saRR_usDualGammaLutRGBOutdoor[0][14]*/
+ 0x0F1202FF, /*02E0 02F9 saRR_usDualGammaLutRGBOutdoor[0][15]*/
+ 0x0F120351, /*0333 0341 saRR_usDualGammaLutRGBOutdoor[0][16]*/
+ 0x0F120395, /*037B 037F saRR_usDualGammaLutRGBOutdoor[0][17]*/
+ 0x0F1203CE, /*03BF 03BF saRR_usDualGammaLutRGBOutdoor[0][18]*/
+ 0x0F1203FF, /*03FF 03FF saRR_usDualGammaLutRGBOutdoor[0][19]*/
+ 0x0F120000, /*0000 0000 saRR_usDualGammaLutRGBOutdoor[1][0]*/
+ 0x0F120004, /*0008 0002 saRR_usDualGammaLutRGBOutdoor[1][1]*/
+ 0x0F12000C, /*0013 0006 saRR_usDualGammaLutRGBOutdoor[1][2]*/
+ 0x0F120024, /*002C 0011 saRR_usDualGammaLutRGBOutdoor[1][3]*/
+ 0x0F12006E, /*0061 0036 saRR_usDualGammaLutRGBOutdoor[1][4]*/
+ 0x0F1200D1, /*00C8 009A saRR_usDualGammaLutRGBOutdoor[1][5]*/
+ 0x0F120119, /*0113 00FD saRR_usDualGammaLutRGBOutdoor[1][6]*/
+ 0x0F120139, /*0132 0129 saRR_usDualGammaLutRGBOutdoor[1][7]*/
+ 0x0F120157, /*014C 014B saRR_usDualGammaLutRGBOutdoor[1][8]*/
+ 0x0F12018E, /*0179 0184 saRR_usDualGammaLutRGBOutdoor[1][9]*/
+ 0x0F1201C3, /*01A4 01B8 saRR_usDualGammaLutRGBOutdoor[1][10]*/
+ 0x0F1201F3, /*01CD 01EA saRR_usDualGammaLutRGBOutdoor[1][11]*/
+ 0x0F12021F, /*01F4 0216 saRR_usDualGammaLutRGBOutdoor[1][12]*/
+ 0x0F120269, /*0239 025E saRR_usDualGammaLutRGBOutdoor[1][13]*/
+ 0x0F1202A6, /*0278 0299 saRR_usDualGammaLutRGBOutdoor[1][14]*/
+ 0x0F1202FF, /*02E0 02F9 saRR_usDualGammaLutRGBOutdoor[1][15]*/
+ 0x0F120351, /*0333 0341 saRR_usDualGammaLutRGBOutdoor[1][16]*/
+ 0x0F120395, /*037B 037F saRR_usDualGammaLutRGBOutdoor[1][17]*/
+ 0x0F1203CE, /*03BF 03BF saRR_usDualGammaLutRGBOutdoor[1][18]*/
+ 0x0F1203FF, /*03FF 03FF saRR_usDualGammaLutRGBOutdoor[1][19]*/
+ 0x0F120000, /*0000 0000 saRR_usDualGammaLutRGBOutdoor[2][0]*/
+ 0x0F120004, /*0008 0002 saRR_usDualGammaLutRGBOutdoor[2][1]*/
+ 0x0F12000C, /*0013 0006 saRR_usDualGammaLutRGBOutdoor[2][2]*/
+ 0x0F120024, /*002C 0011 saRR_usDualGammaLutRGBOutdoor[2][3]*/
+ 0x0F12006E, /*0061 0036 saRR_usDualGammaLutRGBOutdoor[2][4]*/
+ 0x0F1200D1, /*00C8 009A saRR_usDualGammaLutRGBOutdoor[2][5]*/
+ 0x0F120119, /*0113 00FD saRR_usDualGammaLutRGBOutdoor[2][6]*/
+ 0x0F120139, /*0132 0129 saRR_usDualGammaLutRGBOutdoor[2][7]*/
+ 0x0F120157, /*014C 014B saRR_usDualGammaLutRGBOutdoor[2][8]*/
+ 0x0F12018E, /*0179 0184 saRR_usDualGammaLutRGBOutdoor[2][9]*/
+ 0x0F1201C3, /*01A4 01B8 saRR_usDualGammaLutRGBOutdoor[2][10]*/
+ 0x0F1201F3, /*01CD 01EA saRR_usDualGammaLutRGBOutdoor[2][11]*/
+ 0x0F12021F, /*01F4 0216 saRR_usDualGammaLutRGBOutdoor[2][12]*/
+ 0x0F120269, /*0239 025E saRR_usDualGammaLutRGBOutdoor[2][13]*/
+ 0x0F1202A6, /*0278 0299 saRR_usDualGammaLutRGBOutdoor[2][14]*/
+ 0x0F1202FF, /*02E0 02F9 saRR_usDualGammaLutRGBOutdoor[2][15]*/
+ 0x0F120351, /*0333 0341 saRR_usDualGammaLutRGBOutdoor[2][16]*/
+ 0x0F120395, /*037B 037F saRR_usDualGammaLutRGBOutdoor[2][17]*/
+ 0x0F1203CE, /*03BF 03BF saRR_usDualGammaLutRGBOutdoor[2][18]*/
+ 0x0F1203FF, /*03FF 03FF saRR_usDualGammaLutRGBOutdoor[2][19]*/
+ 0x002A065C,
+ 0x0F12003F, /*afit_uNoiseIndInDoor_0_*/
+ 0x0F120041, /*afit_uNoiseIndInDoor_1_*/
+ 0x0F1200CB, /*afit_uNoiseIndInDoor_2_*/
+ 0x0F1201E0, /*afit_uNoiseIndInDoor_3_*/
+ 0x0F120220, /*afit_uNoiseIndInDoor_4_*/
+ 0x002A3780,
+ 0x0F120000, /*on/off AFIT by NB option*/
+ 0x0F120014, /*SARR_uNormBrInDoor*/
+ 0x0F1200D2, /*SARR_uNormBrInDoor*/
+ 0x0F120384, /*SARR_uNormBrInDoor*/
+ 0x0F1207D0, /*SARR_uNormBrInDoor*/
+ 0x0F121388, /*SARR_uNormBrInDoor*/
+ 0x002A06BC,
+ 0x0F120000, /*AFIT16_BRIGHTNESS*/
+ 0x0F120000, /*AFIT16_CONTRAST*/
+ 0x0F120014, /*AFIT16_SATURATION*/
+ 0x0F120000, /*AFIT16_SHARP_BLUR*/
+ 0x0F120000, /*AFIT16_GLAMOUR*/
+ 0x0F1200C1, /*AFIT16_sddd8a_edge_high*/
+ 0x0F1203FF, /*AFIT16_Demosaicing_isatVal*/
+ 0x0F12009C, /*AFIT16_Sharpening_iReduceEdgeThresh*/
+ 0x0F12017C, /*AFIT16_demsharpmix1_iRGBOffset*/
+ 0x0F1203FF, /*AFIT16_demsharpmix1_iDemClamp*/
+ 0x0F12000C, /*AFIT16_demsharpmix1_iLowThreshold*/
+ 0x0F120010, /*AFIT16_demsharpmix1_iHighThreshold*/
+ 0x0F12012C, /*AFIT16_demsharpmix1_iLowBright*/
+ 0x0F1203E8, /*AFIT16_demsharpmix1_iHighBright*/
+ 0x0F120046, /*AFIT16_demsharpmix1_iLowsat*/
+ 0x0F12005A, /*AFIT16_demsharpmix1_iHighsat*/
+ 0x0F120070, /*AFIT16_demsharpmix1_iTune*/
+ 0x0F12001E, /*AFIT16_demsharpmix1_iHystThLow*/
+ 0x0F12001E, /*AFIT16_demsharpmix1_iHystThHigh*/
+ 0x0F1201F4, /*AFIT16_demsharpmix1_iHystCenter*/
+ 0x0F120046, /*AFIT16_YUV422_DENOIsE_iUVLowThresh*/
+ 0x0F120046, /*AFIT16_YUV422_DENOIsE_iUVHighThresh*/
+ 0x0F120005, /*AFIT16_YUV422_DENOIsE_iYLowThresh*/
+ 0x0F120005, /*AFIT16_YUV422_DENOIsE_iYHighThresh*/
+ 0x0F12003C, /*AFIT16_sharpening_iLowsharpClamp*/
+ 0x0F120014, /*AFIT16_sharpening_iHighsharpClamp*/
+ 0x0F12003C, /*AFIT16_sharpening_iLowsharpClamp_Bin*/
+ 0x0F120014, /*AFIT16_sharpening_iHighsharpClamp_Bin*/
+ 0x0F12003C, /*AFIT16_sharpening_iLowsharpClamp_sBin*/
+ 0x0F12001E, /*AFIT16_sharpening_iHighsharpClamp_sBin*/
+ 0x0F120A24, /*AFIT8_sddd8a_edge_low [7:0],
+ AFIT8_sddd8a_repl_thresh [15:8]*/
+ 0x0F121701, /*AFIT8_sddd8a_repl_force [7:0],
+ AFIT8_sddd8a_sat_level [15:8]*/
+ 0x0F120229, /*AFIT8_sddd8a_sat_thr[7:0],
+ AFIT8_sddd8a_sat_mpl [15:8]*/
+ 0x0F121403, /*AFIT8_sddd8a_sat_noise[7:0],
+ AFIT8_sddd8a_iMaxslopeAllowed [15:8]*/
+ 0x0F120000, /*AFIT8_sddd8a_iHotThreshHigh[7:0],
+ AFIT8_sddd8a_iHotThreshLow [15:8]*/
+ 0x0F120000, /*AFIT8_sddd8a_iColdThreshHigh[7:0],
+ AFIT8_sddd8a_iColdThreshLow [15:8]*/
+ 0x0F120000, /*AFIT8_sddd8a_AddNoisePower1[7:0],
+ AFIT8_sddd8a_AddNoisePower2 [15:8]*/
+ 0x0F1200FF, /*AFIT8_sddd8a_isatsat[7:0],
+ AFIT8_sddd8a_iRadialTune [15:8]*/
+ 0x0F120A3B, /*AFIT8_sddd8a_iRadialLimit [7:0],
+ AFIT8_sddd8a_iRadialPower [15:8]*/
+ 0x0F121414, /*AFIT8_sddd8a_iLowMaxslopeAllowed [7:0],
+ AFIT8_sddd8a_iHighMaxslopeAllowed [15:8]*/
+ 0x0F120301, /*AFIT8_sddd8a_iLowslopeThresh[7:0],
+ AFIT8_sddd8a_iHighslopeThresh [15:8]*/
+ 0x0F12FF07, /*AFIT8_sddd8a_isquaresRounding [7:0],
+ AFIT8_Demosaicing_iCentGrad [15:8]*/
+ 0x0F12081E, /*AFIT8_Demosaicing_iMonochrom [7:0],
+ AFIT8_Demosaicing_iDecisionThresh [15:8]*/
+ 0x0F120A1E, /*AFIT8_Demosaicing_iDesatThresh [7:0],
+ AFIT8_Demosaicing_iEnhThresh [15:8]*/
+ 0x0F120F0F, /*AFIT8_Demosaicing_iGRDenoiseVal [7:0],
+ AFIT8_Demosaicing_iGBDenoiseVal [15:8]*/
+ 0x0F120A00, /*AFIT8_Demosaicing_iNearGrayDesat[7:0],
+ AFIT8_Demosaicing_iDFD_ReduceCoeff [15:8]*/
+ 0x0F120012, /*AFIT8_sharpening_iMsharpen [7:0],
+ AFIT8_sharpening_iMshThresh [15:8]*/
+ 0x0F12001E, /*AFIT8_sharpening_iWsharpen [7:0],
+ AFIT8_sharpening_iWshThresh [15:8]*/
+ 0x0F120002, /*AFIT8_sharpening_nsharpWidth [7:0],
+ AFIT8_sharpening_iReduceNegative [15:8]*/
+ 0x0F1200FF, /*AFIT8_sharpening_ishDespeckle [7:0],
+ AFIT8_demsharpmix1_iRGBMultiplier [15:8]*/
+ 0x0F121102, /*AFIT8_demsharpmix1_iFilterPower [7:0],
+ AFIT8_demsharpmix1_iBCoeff [15:8]*/
+ 0x0F12001B, /*AFIT8_demsharpmix1_iGCoeff [7:0],
+ AFIT8_demsharpmix1_iWideMult [15:8]*/
+ 0x0F120900, /*AFIT8_demsharpmix1_iNarrMult [7:0],
+ AFIT8_demsharpmix1_iHystFalloff [15:8]*/
+ 0x0F120600, /*AFIT8_demsharpmix1_iHystMinMult [7:0],
+ AFIT8_demsharpmix1_iHystWidth [15:8]*/
+ 0x0F120504, /*AFIT8_demsharpmix1_iHystFallLow [7:0],
+ AFIT8_demsharpmix1_iHystFallHigh [15:8]*/
+ 0x0F120306, /*AFIT8_demsharpmix1_iHystTune [7:0],
+ * AFIT8_YUV422_DENOIsE_iUVsupport [15:8]*/
+ 0x0F128003, /*AFIT8_YUV422_DENOIsE_iYsupport [7:0],
+ AFIT8_byr_cgras_ishadingPower [15:8]*/
+ 0x0F121982, /*AFIT8_RGBGamma2_iLinearity [7:0],
+ AFIT8_RGBGamma2_iDarkReduce [15:8]*/
+ 0x0F120B80, /*0A80 AFIT8_ccm_oscar_isaturation[7:0],
+ AFIT8_RGB2YUV_iYOffset [15:8]*/
+ 0x0F120080, /*AFIT8_RGB2YUV_iRGBGain [7:0],
+ AFIT8_RGB2YUV_isaturation [15:8]*/
+ 0x0F121414, /*AFIT8_sddd8a_iClustThresh_H [7:0],
+ AFIT8_sddd8a_iClustThresh_C [15:8]*/
+ 0x0F120101, /*AFIT8_sddd8a_iClustMulT_H [7:0],
+ AFIT8_sddd8a_iClustMulT_C [15:8]*/
+ 0x0F124601, /*AFIT8_sddd8a_nClustLevel_H [7:0],
+ AFIT8_sddd8a_DispTH_Low [15:8]*/
+ 0x0F126444, /*AFIT8_sddd8a_DispTH_High [7:0],
+ AFIT8_sddd8a_iDenThreshLow [15:8]*/
+ 0x0F129650, /*AFIT8_sddd8a_iDenThreshHigh[7:0],
+ AFIT8_Demosaicing_iEdgeDesat [15:8]*/
+ 0x0F120000, /*AFIT8_Demosaicing_iEdgeDesatThrLow [7:0],
+ AFIT8_Demosaicing_iEdgeDesatThrHigh [15:8]*/
+ 0x0F120003, /*AFIT8_Demosaicing_iEdgeDesatLimit[7:0],
+ AFIT8_Demosaicing_iDemsharpenLow [15:8]*/
+ 0x0F121E00, /*AFIT8_Demosaicing_iDemsharpenHigh[7:0],
+ AFIT8_Demosaicing_iDemsharpThresh [15:8]*/
+ 0x0F120714, /*AFIT8_Demosaicing_iDemshLowLimit [7:0],
+ AFIT8_Demosaicing_iDespeckleForDemsharp [15:8]*/
+ 0x0F121464, /*AFIT8_Demosaicing_iDemBlurLow[7:0],
+ AFIT8_Demosaicing_iDemBlurHigh [15:8]*/
+ 0x0F121404, /*AFIT8_Demosaicing_iDemBlurRange[7:0],
+ AFIT8_sharpening_iLowsharpPower [15:8]*/
+ 0x0F120F14, /*AFIT8_sharpening_iHighsharpPower[7:0],
+ AFIT8_sharpening_iLowshDenoise [15:8]*/
+ 0x0F12400F, /*AFIT8_sharpening_iHighshDenoise [7:0],
+ AFIT8_sharpening_iReduceEdgeMinMult [15:8]*/
+ 0x0F120204, /*AFIT8_sharpening_iReduceEdgeslope [7:0],
+ AFIT8_demsharpmix1_iWideFiltReduce [15:8]*/
+ 0x0F121403, /*AFIT8_demsharpmix1_iNarrFiltReduce [7:0],
+ AFIT8_sddd8a_iClustThresh_H_Bin [15:8]*/
+ 0x0F120114, /*AFIT8_sddd8a_iClustThresh_C_Bin [7:0],
+ AFIT8_sddd8a_iClustMulT_H_Bin [15:8]*/
+ 0x0F120101, /*AFIT8_sddd8a_iClustMulT_C_Bin [7:0],
+ AFIT8_sddd8a_nClustLevel_H_Bin [15:8]*/
+ 0x0F124446, /*AFIT8_sddd8a_DispTH_Low_Bin [7:0],
+ AFIT8_sddd8a_DispTH_High_Bin [15:8]*/
+ 0x0F122832, /*5064 AFIT8_sddd8a_iDenThreshLow_Bin [7:0],
+ AFIT8_sddd8a_iDenThreshHigh_Bin [15:8]*/
+ 0x0F120028, /*AFIT8_Demosaicing_iEdgeDesat_Bin[7:0],
+ AFIT8_Demosaicing_iEdgeDesatThrLow_Bin [15:8]*/
+ 0x0F120300, /*AFIT8_Demosaicing_iEdgeDesatThrHigh_Bin [7:0],
+ AFIT8_Demosaicing_iEdgeDesatLimit_Bin [15:8]*/
+ 0x0F120000, /*AFIT8_Demosaicing_iDemsharpenLow_Bin [7:0],
+ AFIT8_Demosaicing_iDemsharpenHigh_Bin [15:8]*/
+ 0x0F12141E, /*AFIT8_Demosaicing_iDemsharpThresh_Bin [7:0],
+ AFIT8_Demosaicing_iDemshLowLimit_Bin [15:8]*/
+ 0x0F126407, /*AFIT8_Demosaicing_iDespeckleForDemsharp_Bin [7:0],
+ AFIT8_Demosaicing_iDemBlurLow_Bin [15:8]*/
+ 0x0F120414, /*AFIT8_Demosaicing_iDemBlurHigh_Bin [7:0],
+ AFIT8_Demosaicing_iDemBlurRange_Bin [15:8]*/
+ 0x0F120A0A, /*1414 AFIT8_sharpening_iLowsharpPower_Bin [7:0],
+ AFIT8_sharpening_iHighsharpPower_Bin [15:8]*/
+ 0x0F120F0F, /*AFIT8_sharpening_iLowshDenoise_Bin [7:0],
+ AFIT8_sharpening_iHighshDenoise_Bin [15:8]*/
+ 0x0F120440, /*AFIT8_sharpening_iReduceEdgeMinMult_Bin [7:0],
+ AFIT8_sharpening_iReduceEdgeslope_Bin [15:8]*/
+ 0x0F120302, /*AFIT8_demsharpmix1_iWideFiltReduce_Bin [7:0],
+ AFIT8_demsharpmix1_iNarrFiltReduce_Bin [15:8]*/
+ 0x0F121414, /*AFIT8_sddd8a_iClustThresh_H_sBin[7:0],
+ AFIT8_sddd8a_iClustThresh_C_sBin [15:8]*/
+ 0x0F120101, /*AFIT8_sddd8a_iClustMulT_H_sBin [7:0],
+ AFIT8_sddd8a_iClustMulT_C_sBin [15:8]*/
+ 0x0F124601, /*AFIT8_sddd8a_nClustLevel_H_sBin [7:0],
+ AFIT8_sddd8a_DispTH_Low_sBin [15:8]*/
+ 0x0F126E44, /*AFIT8_sddd8a_DispTH_High_sBin [7:0],
+ AFIT8_sddd8a_iDenThreshLow_sBin [15:8]*/
+ 0x0F122864, /*AFIT8_sddd8a_iDenThreshHigh_sBin[7:0],
+ AFIT8_Demosaicing_iEdgeDesat_sBin [15:8]*/
+ 0x0F120A00, /*AFIT8_Demosaicing_iEdgeDesatThrLow_sBin [7:0],
+ AFIT8_Demosaicing_iEdgeDesatThrHigh_sBin [15:8]*/
+ 0x0F120003, /*AFIT8_Demosaicing_iEdgeDesatLimit_sBin [7:0],
+ AFIT8_Demosaicing_iDemsharpenLow_sBin [15:8]*/
+ 0x0F121E00, /*AFIT8_Demosaicing_iDemsharpenHigh_sBin [7:0],
+ AFIT8_Demosaicing_iDemsharpThresh_sBin [15:8]*/
+ 0x0F120714, /*AFIT8_Demosaicing_iDemshLowLimit_sBin [7:0],
+ AFIT8_Demosaicing_iDespeckleForDemsharp_sBin [15:8]*/
+ 0x0F1232FF, /*AFIT8_Demosaicing_iDemBlurLow_sBin [7:0],
+ AFIT8_Demosaicing_iDemBlurHigh_sBin [15:8]*/
+ 0x0F120004, /*AFIT8_Demosaicing_iDemBlurRange_sBin [7:0],
+ AFIT8_sharpening_iLowsharpPower_sBin [15:8]*/
+ 0x0F120F00, /*AFIT8_sharpening_iHighsharpPower_sBin [7:0],
+ AFIT8_sharpening_iLowshDenoise_sBin [15:8]*/
+ 0x0F12400F, /*AFIT8_sharpening_iHighshDenoise_sBin [7:0],
+ AFIT8_sharpening_iReduceEdgeMinMult_sBin [15:8]*/
+ 0x0F120204, /*AFIT8_sharpening_iReduceEdgeslope_sBin [7:0],
+ AFIT8_demsharpmix1_iWideFiltReduce_sBin [15:8]*/
+ 0x0F120003, /*AFIT8_demsharpmix1_iNarrFiltReduce_sBin [7:0]*/
+ 0x0F120000, /*AFIT16_BRIGHTNEss*/
+ 0x0F120000, /*AFIT16_CONTRAsT*/
+ 0x0F120014, /*AFIT16_sATURATION*/
+ 0x0F120000, /*AFIT16_sHARP_BLUR*/
+ 0x0F120000, /*AFIT16_GLAMOUR*/
+ 0x0F1200C1, /*AFIT16_sddd8a_edge_high*/
+ 0x0F1203FF, /*AFIT16_Demosaicing_isatVal*/
+ 0x0F12009C, /*AFIT16_sharpening_iReduceEdgeThresh*/
+ 0x0F12017C, /*AFIT16_demsharpmix1_iRGBOffset*/
+ 0x0F1203FF, /*AFIT16_demsharpmix1_iDemClamp*/
+ 0x0F12000C, /*AFIT16_demsharpmix1_iLowThreshold*/
+ 0x0F120010, /*AFIT16_demsharpmix1_iHighThreshold*/
+ 0x0F12012C, /*AFIT16_demsharpmix1_iLowBright*/
+ 0x0F1203E8, /*AFIT16_demsharpmix1_iHighBright*/
+ 0x0F120046, /*AFIT16_demsharpmix1_iLowsat*/
+ 0x0F12005A, /*AFIT16_demsharpmix1_iHighsat*/
+ 0x0F120070, /*AFIT16_demsharpmix1_iTune*/
+ 0x0F120008, /*AFIT16_demsharpmix1_iHystThLow*/
+ 0x0F120000, /*AFIT16_demsharpmix1_iHystThHigh*/
+ 0x0F120320, /*AFIT16_demsharpmix1_iHystCenter*/
+ 0x0F120046, /*AFIT16_YUV422_DENOIsE_iUVLowThresh*/
+ 0x0F120046, /*AFIT16_YUV422_DENOIsE_iUVHighThresh*/
+ 0x0F120000, /*AFIT16_YUV422_DENOIsE_iYLowThresh*/
+ 0x0F120000, /*AFIT16_YUV422_DENOIsE_iYHighThresh*/
+ 0x0F120064, /*AFIT16_sharpening_iLowsharpClamp*/
+ 0x0F120014, /*AFIT16_sharpening_iHighsharpClamp*/
+ 0x0F120064, /*AFIT16_sharpening_iLowsharpClamp_Bin*/
+ 0x0F120014, /*AFIT16_sharpening_iHighsharpClamp_Bin*/
+ 0x0F12003C, /*AFIT16_sharpening_iLowsharpClamp_sBin*/
+ 0x0F12001E, /*AFIT16_sharpening_iHighsharpClamp_sBin*/
+ 0x0F120A24, /*AFIT8_sddd8a_edge_low [7:0],
+ AFIT8_sddd8a_repl_thresh [15:8]*/
+ 0x0F121701, /*AFIT8_sddd8a_repl_force [7:0],
+ AFIT8_sddd8a_sat_level [15:8]*/
+ 0x0F120229, /*AFIT8_sddd8a_sat_thr[7:0],
+ AFIT8_sddd8a_sat_mpl [15:8]*/
+ 0x0F121403, /*AFIT8_sddd8a_sat_noise[7:0],
+ AFIT8_sddd8a_iMaxslopeAllowed [15:8]*/
+ 0x0F120000, /*AFIT8_sddd8a_iHotThreshHigh[7:0],
+ AFIT8_sddd8a_iHotThreshLow [15:8]*/
+ 0x0F120000, /*AFIT8_sddd8a_iColdThreshHigh[7:0],
+ AFIT8_sddd8a_iColdThreshLow [15:8]*/
+ 0x0F120000, /*AFIT8_sddd8a_AddNoisePower1[7:0],
+ AFIT8_sddd8a_AddNoisePower2 [15:8]*/
+ 0x0F1200FF, /*AFIT8_sddd8a_isatsat[7:0],
+ AFIT8_sddd8a_iRadialTune [15:8]*/
+ 0x0F12033B, /*AFIT8_sddd8a_iRadialLimit [7:0],
+ AFIT8_sddd8a_iRadialPower [15:8]*/
+ 0x0F121414, /*AFIT8_sddd8a_iLowMaxslopeAllowed [7:0],
+ AFIT8_sddd8a_iHighMaxslopeAllowed [15:8]*/
+ 0x0F120301, /*AFIT8_sddd8a_iLowslopeThresh[7:0],
+ AFIT8_sddd8a_iHighslopeThresh [15:8]*/
+ 0x0F12FF07, /*AFIT8_sddd8a_isquaresRounding [7:0],
+ AFIT8_Demosaicing_iCentGrad [15:8]*/
+ 0x0F12081E, /*AFIT8_Demosaicing_iMonochrom [7:0],
+ AFIT8_Demosaicing_iDecisionThresh [15:8]*/
+ 0x0F120A1E, /*AFIT8_Demosaicing_iDesatThresh [7:0],
+ AFIT8_Demosaicing_iEnhThresh [15:8]*/
+ 0x0F120F0F, /*AFIT8_Demosaicing_iGRDenoiseVal [7:0],
+ AFIT8_Demosaicing_iGBDenoiseVal [15:8]*/
+ 0x0F120A00, /*AFIT8_Demosaicing_iNearGrayDesat[7:0],
+ AFIT8_Demosaicing_iDFD_ReduceCoeff [15:8]*/
+ 0x0F120012, /*AFIT8_sharpening_iMsharpen [7:0],
+ AFIT8_sharpening_iMshThresh [15:8]*/
+ 0x0F120005, /*AFIT8_sharpening_iWsharpen [7:0],
+ AFIT8_sharpening_iWshThresh [15:8]*/
+ 0x0F120002, /*AFIT8_sharpening_nsharpWidth [7:0],
+ AFIT8_sharpening_iReduceNegative [15:8]*/
+ 0x0F1200FF, /*AFIT8_sharpening_ishDespeckle [7:0],
+ AFIT8_demsharpmix1_iRGBMultiplier [15:8]*/
+ 0x0F121102, /*AFIT8_demsharpmix1_iFilterPower [7:0],
+ AFIT8_demsharpmix1_iBCoeff [15:8]*/
+ 0x0F12001B, /*AFIT8_demsharpmix1_iGCoeff [7:0],
+ AFIT8_demsharpmix1_iWideMult [15:8]*/
+ 0x0F120900, /*AFIT8_demsharpmix1_iNarrMult [7:0],
+ AFIT8_demsharpmix1_iHystFalloff [15:8]*/
+ 0x0F120600, /*AFIT8_demsharpmix1_iHystMinMult [7:0],
+ AFIT8_demsharpmix1_iHystWidth [15:8]*/
+ 0x0F120504, /*AFIT8_demsharpmix1_iHystFallLow [7:0],
+ AFIT8_demsharpmix1_iHystFallHigh [15:8]*/
+ 0x0F120306, /*AFIT8_demsharpmix1_iHystTune [7:0],
+ * AFIT8_YUV422_DENOIsE_iUVsupport [15:8]*/
+ 0x0F128003, /*AFIT8_YUV422_DENOIsE_iYsupport [7:0],
+ AFIT8_byr_cgras_ishadingPower [15:8]*/
+ 0x0F120A6E, /*AFIT8_RGBGamma2_iLinearity [7:0],
+ AFIT8_RGBGamma2_iDarkReduce [15:8]*/
+ 0x0F120080, /*AFIT8_ccm_oscar_isaturation[7:0],
+ AFIT8_RGB2YUV_iYOffset [15:8]*/
+ 0x0F120080, /*AFIT8_RGB2YUV_iRGBGain [7:0],
+ AFIT8_RGB2YUV_isaturation [15:8]*/
+ 0x0F125050, /*AFIT8_sddd8a_iClustThresh_H [7:0],
+ AFIT8_sddd8a_iClustThresh_C [15:8]*/
+ 0x0F120101, /*AFIT8_sddd8a_iClustMulT_H [7:0],
+ AFIT8_sddd8a_iClustMulT_C [15:8]*/
+ 0x0F122801, /*AFIT8_sddd8a_nClustLevel_H [7:0],
+ AFIT8_sddd8a_DispTH_Low [15:8]*/
+ 0x0F12231E, /*AFIT8_sddd8a_DispTH_High [7:0],
+ AFIT8_sddd8a_iDenThreshLow [15:8]*/
+ 0x0F12961E, /*AFIT8_sddd8a_iDenThreshHigh[7:0],
+ AFIT8_Demosaicing_iEdgeDesat [15:8]*/
+ 0x0F120000, /*AFIT8_Demosaicing_iEdgeDesatThrLow [7:0],
+ AFIT8_Demosaicing_iEdgeDesatThrHigh [15:8]*/
+ 0x0F120003, /*AFIT8_Demosaicing_iEdgeDesatLimit[7:0],
+ AFIT8_Demosaicing_iDemsharpenLow [15:8]*/
+ 0x0F120A02, /*AFIT8_Demosaicing_iDemsharpenHigh[7:0],
+ AFIT8_Demosaicing_iDemsharpThresh [15:8]*/
+ 0x0F120764, /*AFIT8_Demosaicing_iDemshLowLimit [7:0],
+ AFIT8_Demosaicing_iDespeckleForDemsharp [15:8]*/
+ 0x0F12143C, /*AFIT8_Demosaicing_iDemBlurLow[7:0],
+ AFIT8_Demosaicing_iDemBlurHigh [15:8]*/
+ 0x0F121401, /*AFIT8_Demosaicing_iDemBlurRange[7:0],
+ AFIT8_sharpening_iLowsharpPower [15:8]*/
+ 0x0F120F14, /*AFIT8_sharpening_iHighsharpPower[7:0],
+ AFIT8_sharpening_iLowshDenoise [15:8]*/
+ 0x0F12400F, /*AFIT8_sharpening_iHighshDenoise [7:0],
+ AFIT8_sharpening_iReduceEdgeMinMult [15:8]*/
+ 0x0F120204, /*AFIT8_sharpening_iReduceEdgeslope [7:0],
+ AFIT8_demsharpmix1_iWideFiltReduce [15:8]*/
+ 0x0F125003, /*AFIT8_demsharpmix1_iNarrFiltReduce [7:0],
+ AFIT8_sddd8a_iClustThresh_H_Bin [15:8]*/
+ 0x0F120150, /*AFIT8_sddd8a_iClustThresh_C_Bin [7:0],
+ AFIT8_sddd8a_iClustMulT_H_Bin [15:8]*/
+ 0x0F120101, /*AFIT8_sddd8a_iClustMulT_C_Bin [7:0],
+ AFIT8_sddd8a_nClustLevel_H_Bin [15:8]*/
+ 0x0F121E28, /*AFIT8_sddd8a_DispTH_Low_Bin [7:0],
+ AFIT8_sddd8a_DispTH_High_Bin [15:8]*/
+ 0x0F120A0C, /*1419 AFIT8_sddd8a_iDenThreshLow_Bin [7:0],
+ AFIT8_sddd8a_iDenThreshHigh_Bin [15:8]*/
+ 0x0F120028, /*AFIT8_Demosaicing_iEdgeDesat_Bin[7:0],
+ AFIT8_Demosaicing_iEdgeDesatThrLow_Bin [15:8]*/
+ 0x0F120300, /*AFIT8_Demosaicing_iEdgeDesatThrHigh_Bin [7:0],
+ AFIT8_Demosaicing_iEdgeDesatLimit_Bin [15:8]*/
+ 0x0F120200, /*AFIT8_Demosaicing_iDemsharpenLow_Bin [7:0],
+ AFIT8_Demosaicing_iDemsharpenHigh_Bin [15:8]*/
+ 0x0F121E0A, /*AFIT8_Demosaicing_iDemsharpThresh_Bin [7:0],
+ AFIT8_Demosaicing_iDemshLowLimit_Bin [15:8]*/
+ 0x0F123C07, /*AFIT8_Demosaicing_iDespeckleForDemsharp_Bin [7:0],
+ AFIT8_Demosaicing_iDemBlurLow_Bin [15:8]*/
+ 0x0F120114, /*AFIT8_Demosaicing_iDemBlurHigh_Bin [7:0],
+ AFIT8_Demosaicing_iDemBlurRange_Bin [15:8]*/
+ 0x0F120A0A, /*1414 AFIT8_sharpening_iLowsharpPower_Bin [7:0],
+ AFIT8_sharpening_iHighsharpPower_Bin [15:8]*/
+ 0x0F120F0F, /*AFIT8_sharpening_iLowshDenoise_Bin [7:0],
+ AFIT8_sharpening_iHighshDenoise_Bin [15:8]*/
+ 0x0F120440, /*AFIT8_sharpening_iReduceEdgeMinMult_Bin [7:0],
+ AFIT8_sharpening_iReduceEdgeslope_Bin [15:8]*/
+ 0x0F120302, /*AFIT8_demsharpmix1_iWideFiltReduce_Bin [7:0],
+ AFIT8_demsharpmix1_iNarrFiltReduce_Bin [15:8]*/
+ 0x0F121E1E, /*AFIT8_sddd8a_iClustThresh_H_sBin[7:0],
+ AFIT8_sddd8a_iClustThresh_C_sBin [15:8]*/
+ 0x0F120101, /*AFIT8_sddd8a_iClustMulT_H_sBin [7:0],
+ AFIT8_sddd8a_iClustMulT_C_sBin [15:8]*/
+ 0x0F123C01, /*AFIT8_sddd8a_nClustLevel_H_sBin [7:0],
+ AFIT8_sddd8a_DispTH_Low_sBin [15:8]*/
+ 0x0F125A3A, /*AFIT8_sddd8a_DispTH_High_sBin [7:0],
+ AFIT8_sddd8a_iDenThreshLow_sBin [15:8]*/
+ 0x0F122858, /*AFIT8_sddd8a_iDenThreshHigh_sBin[7:0],
+ AFIT8_Demosaicing_iEdgeDesat_sBin [15:8]*/
+ 0x0F120A00, /*AFIT8_Demosaicing_iEdgeDesatThrLow_sBin [7:0],
+ AFIT8_Demosaicing_iEdgeDesatThrHigh_sBin [15:8]*/
+ 0x0F120003, /*AFIT8_Demosaicing_iEdgeDesatLimit_sBin [7:0],
+ AFIT8_Demosaicing_iDemsharpenLow_sBin [15:8]*/
+ 0x0F121E00, /*AFIT8_Demosaicing_iDemsharpenHigh_sBin [7:0],
+ AFIT8_Demosaicing_iDemsharpThresh_sBin [15:8]*/
+ 0x0F120714, /*AFIT8_Demosaicing_iDemshLowLimit_sBin [7:0],
+ AFIT8_Demosaicing_iDespeckleForDemsharp_sBin [15:8]*/
+ 0x0F1232FF, /*AFIT8_Demosaicing_iDemBlurLow_sBin [7:0],
+ AFIT8_Demosaicing_iDemBlurHigh_sBin [15:8]*/
+ 0x0F120004, /*AFIT8_Demosaicing_iDemBlurRange_sBin [7:0],
+ AFIT8_sharpening_iLowsharpPower_sBin [15:8]*/
+ 0x0F120F00, /*AFIT8_sharpening_iHighsharpPower_sBin [7:0],
+ AFIT8_sharpening_iLowshDenoise_sBin [15:8]*/
+ 0x0F12400F, /*AFIT8_sharpening_iHighshDenoise_sBin [7:0],
+ AFIT8_sharpening_iReduceEdgeMinMult_sBin [15:8]*/
+ 0x0F120204, /*AFIT8_sharpening_iReduceEdgeslope_sBin [7:0],
+ AFIT8_demsharpmix1_iWideFiltReduce_sBin [15:8]*/
+ 0x0F120003, /*AFIT8_demsharpmix1_iNarrFiltReduce_sBin [7:0]*/
+ 0x0F120000, /*AFIT16_BRIGHTNEss*/
+ 0x0F120000, /*AFIT16_CONTRAsT*/
+ 0x0F120000, /*AFIT16_sATURATION*/
+ 0x0F120000, /*AFIT16_sHARP_BLUR*/
+ 0x0F120000, /*AFIT16_GLAMOUR*/
+ 0x0F1200C1, /*AFIT16_sddd8a_edge_high*/
+ 0x0F1203FF, /*AFIT16_Demosaicing_isatVal*/
+ 0x0F12009C, /*AFIT16_sharpening_iReduceEdgeThresh*/
+ 0x0F12017C, /*AFIT16_demsharpmix1_iRGBOffset*/
+ 0x0F1203FF, /*AFIT16_demsharpmix1_iDemClamp*/
+ 0x0F12000C, /*AFIT16_demsharpmix1_iLowThreshold*/
+ 0x0F120010, /*AFIT16_demsharpmix1_iHighThreshold*/
+ 0x0F12012C, /*AFIT16_demsharpmix1_iLowBright*/
+ 0x0F1203E8, /*AFIT16_demsharpmix1_iHighBright*/
+ 0x0F120046, /*AFIT16_demsharpmix1_iLowsat*/
+ 0x0F12005A, /*AFIT16_demsharpmix1_iHighsat*/
+ 0x0F120070, /*AFIT16_demsharpmix1_iTune*/
+ 0x0F120008, /*AFIT16_demsharpmix1_iHystThLow*/
+ 0x0F120000, /*AFIT16_demsharpmix1_iHystThHigh*/
+ 0x0F120320, /*AFIT16_demsharpmix1_iHystCenter*/
+ 0x0F120032, /*AFIT16_YUV422_DENOIsE_iUVLowThresh*/
+ 0x0F120032, /*AFIT16_YUV422_DENOIsE_iUVHighThresh*/
+ 0x0F120000, /*AFIT16_YUV422_DENOIsE_iYLowThresh*/
+ 0x0F120000, /*AFIT16_YUV422_DENOIsE_iYHighThresh*/
+ 0x0F1200B4, /*AFIT16_sharpening_iLowsharpClamp*/
+ 0x0F120014, /*AFIT16_sharpening_iHighsharpClamp*/
+ 0x0F1200B4, /*AFIT16_sharpening_iLowsharpClamp_Bin*/
+ 0x0F120014, /*AFIT16_sharpening_iHighsharpClamp_Bin*/
+ 0x0F12003C, /*AFIT16_sharpening_iLowsharpClamp_sBin*/
+ 0x0F12001E, /*AFIT16_sharpening_iHighsharpClamp_sBin*/
+ 0x0F120A24, /*AFIT8_sddd8a_edge_low [7:0],
+ AFIT8_sddd8a_repl_thresh [15:8]*/
+ 0x0F121701, /*AFIT8_sddd8a_repl_force [7:0],
+ AFIT8_sddd8a_sat_level [15:8]*/
+ 0x0F120229, /*AFIT8_sddd8a_sat_thr[7:0],
+ AFIT8_sddd8a_sat_mpl [15:8]*/
+ 0x0F121403, /*AFIT8_sddd8a_sat_noise[7:0],
+ AFIT8_sddd8a_iMaxslopeAllowed [15:8]*/
+ 0x0F120000, /*AFIT8_sddd8a_iHotThreshHigh[7:0],
+ AFIT8_sddd8a_iHotThreshLow [15:8]*/
+ 0x0F120000, /*AFIT8_sddd8a_iColdThreshHigh[7:0],
+ AFIT8_sddd8a_iColdThreshLow [15:8]*/
+ 0x0F120000, /*AFIT8_sddd8a_AddNoisePower1[7:0],
+ AFIT8_sddd8a_AddNoisePower2 [15:8]*/
+ 0x0F1200FF, /*AFIT8_sddd8a_isatsat[7:0],
+ AFIT8_sddd8a_iRadialTune [15:8]*/
+ 0x0F12033B, /*AFIT8_sddd8a_iRadialLimit [7:0],
+ AFIT8_sddd8a_iRadialPower [15:8]*/
+ 0x0F121414, /*AFIT8_sddd8a_iLowMaxslopeAllowed [7:0],
+ AFIT8_sddd8a_iHighMaxslopeAllowed [15:8]*/
+ 0x0F120301, /*AFIT8_sddd8a_iLowslopeThresh[7:0],
+ AFIT8_sddd8a_iHighslopeThresh [15:8]*/
+ 0x0F12FF07, /*AFIT8_sddd8a_isquaresRounding [7:0],
+ AFIT8_Demosaicing_iCentGrad [15:8]*/
+ 0x0F12081E, /*AFIT8_Demosaicing_iMonochrom [7:0],
+ AFIT8_Demosaicing_iDecisionThresh [15:8]*/
+ 0x0F120A1E, /*AFIT8_Demosaicing_iDesatThresh [7:0],
+ AFIT8_Demosaicing_iEnhThresh [15:8]*/
+ 0x0F120F0F, /*AFIT8_Demosaicing_iGRDenoiseVal [7:0],
+ AFIT8_Demosaicing_iGBDenoiseVal [15:8]*/
+ 0x0F120A00, /*AFIT8_Demosaicing_iNearGrayDesat[7:0],
+ AFIT8_Demosaicing_iDFD_ReduceCoeff [15:8]*/
+ 0x0F120012, /*AFIT8_sharpening_iMsharpen [7:0],
+ AFIT8_sharpening_iMshThresh [15:8]*/
+ 0x0F120005, /*AFIT8_sharpening_iWsharpen [7:0],
+ AFIT8_sharpening_iWshThresh [15:8]*/
+ 0x0F120001, /*AFIT8_sharpening_nsharpWidth [7:0],
+ AFIT8_sharpening_iReduceNegative [15:8]*/
+ 0x0F1200FF, /*AFIT8_sharpening_ishDespeckle [7:0],
+ AFIT8_demsharpmix1_iRGBMultiplier [15:8]*/
+ 0x0F121102, /*AFIT8_demsharpmix1_iFilterPower [7:0],
+ AFIT8_demsharpmix1_iBCoeff [15:8]*/
+ 0x0F12001B, /*AFIT8_demsharpmix1_iGCoeff [7:0],
+ AFIT8_demsharpmix1_iWideMult [15:8]*/
+ 0x0F120900, /*AFIT8_demsharpmix1_iNarrMult [7:0],
+ AFIT8_demsharpmix1_iHystFalloff [15:8]*/
+ 0x0F120600, /*AFIT8_demsharpmix1_iHystMinMult [7:0],
+ AFIT8_demsharpmix1_iHystWidth [15:8]*/
+ 0x0F120504, /*AFIT8_demsharpmix1_iHystFallLow [7:0],
+ AFIT8_demsharpmix1_iHystFallHigh [15:8]*/
+ 0x0F120306, /*AFIT8_demsharpmix1_iHystTune [7:0],
+ * AFIT8_YUV422_DENOIsE_iUVsupport [15:8]*/
+ 0x0F128002, /*AFIT8_YUV422_DENOIsE_iYsupport [7:0],
+ AFIT8_byr_cgras_ishadingPower [15:8]*/
+ 0x0F120080, /*AFIT8_RGBGamma2_iLinearity [7:0],
+ AFIT8_RGBGamma2_iDarkReduce [15:8]*/
+ 0x0F120080, /*AFIT8_ccm_oscar_isaturation[7:0],
+ AFIT8_RGB2YUV_iYOffset [15:8]*/
+ 0x0F120080, /*AFIT8_RGB2YUV_iRGBGain [7:0],
+ AFIT8_RGB2YUV_isaturation [15:8]*/
+ 0x0F125050, /*AFIT8_sddd8a_iClustThresh_H [7:0],
+ AFIT8_sddd8a_iClustThresh_C [15:8]*/
+ 0x0F120101, /*AFIT8_sddd8a_iClustMulT_H [7:0],
+ AFIT8_sddd8a_iClustMulT_C [15:8]*/
+ 0x0F121B01, /*AFIT8_sddd8a_nClustLevel_H [7:0],
+ AFIT8_sddd8a_DispTH_Low [15:8]*/
+ 0x0F122319, /*AFIT8_sddd8a_DispTH_High [7:0],
+ AFIT8_sddd8a_iDenThreshLow [15:8]*/
+ 0x0F12960F, /*AFIT8_sddd8a_iDenThreshHigh[7:0],
+ AFIT8_Demosaicing_iEdgeDesat [15:8]*/
+ 0x0F120000, /*AFIT8_Demosaicing_iEdgeDesatThrLow [7:0],
+ AFIT8_Demosaicing_iEdgeDesatThrHigh [15:8]*/
+ 0x0F122A03, /*AFIT8_Demosaicing_iEdgeDesatLimit[7:0],
+ AFIT8_Demosaicing_iDemsharpenLow [15:8]*/
+ 0x0F120A02, /*AFIT8_Demosaicing_iDemsharpenHigh[7:0],
+ AFIT8_Demosaicing_iDemsharpThresh [15:8]*/
+ 0x0F120864, /*AFIT8_Demosaicing_iDemshLowLimit [7:0],
+ AFIT8_Demosaicing_iDespeckleForDemsharp [15:8]*/
+ 0x0F121432, /*AFIT8_Demosaicing_iDemBlurLow[7:0],
+ AFIT8_Demosaicing_iDemBlurHigh [15:8]*/
+ 0x0F129601, /*AFIT8_Demosaicing_iDemBlurRange[7:0],
+ AFIT8_sharpening_iLowsharpPower [15:8]*/
+ 0x0F122814, /*AFIT8_sharpening_iHighsharpPower[7:0],
+ AFIT8_sharpening_iLowshDenoise [15:8]*/
+ 0x0F12400A, /*AFIT8_sharpening_iHighshDenoise [7:0],
+ AFIT8_sharpening_iReduceEdgeMinMult [15:8]*/
+ 0x0F120204, /*AFIT8_sharpening_iReduceEdgeslope [7:0],
+ AFIT8_demsharpmix1_iWideFiltReduce [15:8]*/
+ 0x0F125003, /*AFIT8_demsharpmix1_iNarrFiltReduce [7:0],
+ AFIT8_sddd8a_iClustThresh_H_Bin [15:8]*/
+ 0x0F120150, /*AFIT8_sddd8a_iClustThresh_C_Bin [7:0],
+ AFIT8_sddd8a_iClustMulT_H_Bin [15:8]*/
+ 0x0F120101, /*AFIT8_sddd8a_iClustMulT_C_Bin [7:0],
+ AFIT8_sddd8a_nClustLevel_H_Bin [15:8]*/
+ 0x0F12191B, /*AFIT8_sddd8a_DispTH_Low_Bin [7:0],
+ AFIT8_sddd8a_DispTH_High_Bin [15:8]*/
+ 0x0F12070C, /*0F19 AFIT8_sddd8a_iDenThreshLow_Bin [7:0],
+ AFIT8_sddd8a_iDenThreshHigh_Bin [15:8]*/
+ 0x0F120028, /*AFIT8_Demosaicing_iEdgeDesat_Bin[7:0],
+ AFIT8_Demosaicing_iEdgeDesatThrLow_Bin [15:8]*/
+ 0x0F120300, /*AFIT8_Demosaicing_iEdgeDesatThrHigh_Bin [7:0],
+ AFIT8_Demosaicing_iEdgeDesatLimit_Bin [15:8]*/
+ 0x0F12021E, /*AFIT8_Demosaicing_iDemsharpenLow_Bin [7:0],
+ AFIT8_Demosaicing_iDemsharpenHigh_Bin [15:8]*/
+ 0x0F121E0A, /*AFIT8_Demosaicing_iDemsharpThresh_Bin [7:0],
+ AFIT8_Demosaicing_iDemshLowLimit_Bin [15:8]*/
+ 0x0F123208, /*AFIT8_Demosaicing_iDespeckleForDemsharp_Bin [7:0],
+ AFIT8_Demosaicing_iDemBlurLow_Bin [15:8]*/
+ 0x0F120114, /*AFIT8_Demosaicing_iDemBlurHigh_Bin [7:0],
+ AFIT8_Demosaicing_iDemBlurRange_Bin [15:8]*/
+ 0x0F120A28, /*1450 AFIT8_sharpening_iLowsharpPower_Bin [7:0],
+ AFIT8_sharpening_iHighsharpPower_Bin [15:8]*/
+ 0x0F120A28, /*AFIT8_sharpening_iLowshDenoise_Bin [7:0],
+ AFIT8_sharpening_iHighshDenoise_Bin [15:8]*/
+ 0x0F120440, /*AFIT8_sharpening_iReduceEdgeMinMult_Bin [7:0],
+ AFIT8_sharpening_iReduceEdgeslope_Bin [15:8]*/
+ 0x0F120302, /*AFIT8_demsharpmix1_iWideFiltReduce_Bin [7:0],
+ AFIT8_demsharpmix1_iNarrFiltReduce_Bin [15:8]*/
+ 0x0F122828, /*AFIT8_sddd8a_iClustThresh_H_sBin[7:0],
+ AFIT8_sddd8a_iClustThresh_C_sBin [15:8]*/
+ 0x0F120101, /*AFIT8_sddd8a_iClustMulT_H_sBin [7:0],
+ AFIT8_sddd8a_iClustMulT_C_sBin [15:8]*/
+ 0x0F122401, /*AFIT8_sddd8a_nClustLevel_H_sBin [7:0],
+ AFIT8_sddd8a_DispTH_Low_sBin [15:8]*/
+ 0x0F123622, /*AFIT8_sddd8a_DispTH_High_sBin [7:0],
+ AFIT8_sddd8a_iDenThreshLow_sBin [15:8]*/
+ 0x0F122832, /*AFIT8_sddd8a_iDenThreshHigh_sBin[7:0],
+ AFIT8_Demosaicing_iEdgeDesat_sBin [15:8]*/
+ 0x0F120A00, /*AFIT8_Demosaicing_iEdgeDesatThrLow_sBin [7:0],
+ AFIT8_Demosaicing_iEdgeDesatThrHigh_sBin [15:8]*/
+ 0x0F121003, /*AFIT8_Demosaicing_iEdgeDesatLimit_sBin [7:0],
+ AFIT8_Demosaicing_iDemsharpenLow_sBin [15:8]*/
+ 0x0F121E04, /*AFIT8_Demosaicing_iDemsharpenHigh_sBin [7:0],
+ AFIT8_Demosaicing_iDemsharpThresh_sBin [15:8]*/
+ 0x0F120714, /*AFIT8_Demosaicing_iDemshLowLimit_sBin [7:0],
+ AFIT8_Demosaicing_iDespeckleForDemsharp_sBin [15:8]*/
+ 0x0F1232FF, /*AFIT8_Demosaicing_iDemBlurLow_sBin [7:0],
+ AFIT8_Demosaicing_iDemBlurHigh_sBin [15:8]*/
+ 0x0F125004, /*AFIT8_Demosaicing_iDemBlurRange_sBin [7:0],
+ AFIT8_sharpening_iLowsharpPower_sBin [15:8]*/
+ 0x0F120F40, /*AFIT8_sharpening_iHighsharpPower_sBin [7:0],
+ AFIT8_sharpening_iLowshDenoise_sBin [15:8]*/
+ 0x0F12400F, /*AFIT8_sharpening_iHighshDenoise_sBin [7:0],
+ AFIT8_sharpening_iReduceEdgeMinMult_sBin [15:8]*/
+ 0x0F120204, /*AFIT8_sharpening_iReduceEdgeslope_sBin [7:0],
+ AFIT8_demsharpmix1_iWideFiltReduce_sBin [15:8]*/
+ 0x0F120003, /*AFIT8_demsharpmix1_iNarrFiltReduce_sBin [7:0]*/
+ 0x0F120000, /*AFIT16_BRIGHTNEss*/
+ 0x0F120000, /*AFIT16_CONTRAsT*/
+ 0x0F120000, /*AFIT16_sATURATION*/
+ 0x0F120000, /*AFIT16_sHARP_BLUR*/
+ 0x0F120000, /*AFIT16_GLAMOUR*/
+ 0x0F1200C1, /*AFIT16_sddd8a_edge_high*/
+ 0x0F1203FF, /*AFIT16_Demosaicing_isatVal*/
+ 0x0F12009C, /*AFIT16_sharpening_iReduceEdgeThresh*/
+ 0x0F12017C, /*AFIT16_demsharpmix1_iRGBOffset*/
+ 0x0F1203FF, /*AFIT16_demsharpmix1_iDemClamp*/
+ 0x0F12000C, /*AFIT16_demsharpmix1_iLowThreshold*/
+ 0x0F120010, /*AFIT16_demsharpmix1_iHighThreshold*/
+ 0x0F1200C8, /*AFIT16_demsharpmix1_iLowBright*/
+ 0x0F1203E8, /*AFIT16_demsharpmix1_iHighBright*/
+ 0x0F120046, /*AFIT16_demsharpmix1_iLowsat*/
+ 0x0F120050, /*AFIT16_demsharpmix1_iHighsat*/
+ 0x0F120070, /*AFIT16_demsharpmix1_iTune*/
+ 0x0F120008, /*AFIT16_demsharpmix1_iHystThLow*/
+ 0x0F120000, /*AFIT16_demsharpmix1_iHystThHigh*/
+ 0x0F120320, /*AFIT16_demsharpmix1_iHystCenter*/
+ 0x0F120032, /*AFIT16_YUV422_DENOIsE_iUVLowThresh*/
+ 0x0F120032, /*AFIT16_YUV422_DENOIsE_iUVHighThresh*/
+ 0x0F120000, /*AFIT16_YUV422_DENOIsE_iYLowThresh*/
+ 0x0F120000, /*AFIT16_YUV422_DENOIsE_iYHighThresh*/
+ 0x0F1200B4, /*AFIT16_sharpening_iLowsharpClamp*/
+ 0x0F120014, /*AFIT16_sharpening_iHighsharpClamp*/
+ 0x0F1200B4, /*AFIT16_sharpening_iLowsharpClamp_Bin*/
+ 0x0F120014, /*AFIT16_sharpening_iHighsharpClamp_Bin*/
+ 0x0F12002D, /*AFIT16_sharpening_iLowsharpClamp_sBin*/
+ 0x0F120019, /*AFIT16_sharpening_iHighsharpClamp_sBin*/
+ 0x0F120A24, /*AFIT8_sddd8a_edge_low [7:0],
+ AFIT8_sddd8a_repl_thresh [15:8]*/
+ 0x0F121701, /*AFIT8_sddd8a_repl_force [7:0],
+ AFIT8_sddd8a_sat_level [15:8]*/
+ 0x0F120229, /*AFIT8_sddd8a_sat_thr[7:0],
+ AFIT8_sddd8a_sat_mpl [15:8]*/
+ 0x0F121403, /*AFIT8_sddd8a_sat_noise[7:0],
+ AFIT8_sddd8a_iMaxslopeAllowed [15:8]*/
+ 0x0F120000, /*AFIT8_sddd8a_iHotThreshHigh[7:0],
+ AFIT8_sddd8a_iHotThreshLow [15:8]*/
+ 0x0F120000, /*AFIT8_sddd8a_iColdThreshHigh[7:0],
+ AFIT8_sddd8a_iColdThreshLow [15:8]*/
+ 0x0F120000, /*AFIT8_sddd8a_AddNoisePower1[7:0],
+ AFIT8_sddd8a_AddNoisePower2 [15:8]*/
+ 0x0F1200FF, /*AFIT8_sddd8a_isatsat[7:0],
+ AFIT8_sddd8a_iRadialTune [15:8]*/
+ 0x0F12033B, /*AFIT8_sddd8a_iRadialLimit [7:0],
+ AFIT8_sddd8a_iRadialPower [15:8]*/
+ 0x0F121414, /*AFIT8_sddd8a_iLowMaxslopeAllowed [7:0],
+ AFIT8_sddd8a_iHighMaxslopeAllowed [15:8]*/
+ 0x0F120301, /*AFIT8_sddd8a_iLowslopeThresh[7:0],
+ AFIT8_sddd8a_iHighslopeThresh [15:8]*/
+ 0x0F12FF07, /*AFIT8_sddd8a_isquaresRounding [7:0],
+ AFIT8_Demosaicing_iCentGrad [15:8]*/
+ 0x0F12081E, /*AFIT8_Demosaicing_iMonochrom [7:0],
+ AFIT8_Demosaicing_iDecisionThresh [15:8]*/
+ 0x0F120A1E, /*AFIT8_Demosaicing_iDesatThresh [7:0],
+ AFIT8_Demosaicing_iEnhThresh [15:8]*/
+ 0x0F120F0F, /*AFIT8_Demosaicing_iGRDenoiseVal [7:0],
+ AFIT8_Demosaicing_iGBDenoiseVal [15:8]*/
+ 0x0F120A00, /*AFIT8_Demosaicing_iNearGrayDesat[7:0],
+ AFIT8_Demosaicing_iDFD_ReduceCoeff [15:8]*/
+ 0x0F120012, /*AFIT8_sharpening_iMsharpen [7:0],
+ AFIT8_sharpening_iMshThresh [15:8]*/
+ 0x0F120005, /*AFIT8_sharpening_iWsharpen [7:0],
+ AFIT8_sharpening_iWshThresh [15:8]*/
+ 0x0F120001, /*AFIT8_sharpening_nsharpWidth [7:0],
+ AFIT8_sharpening_iReduceNegative [15:8]*/
+ 0x0F1200FF, /*AFIT8_sharpening_ishDespeckle [7:0],
+ AFIT8_demsharpmix1_iRGBMultiplier [15:8]*/
+ 0x0F121002, /*AFIT8_demsharpmix1_iFilterPower [7:0],
+ AFIT8_demsharpmix1_iBCoeff [15:8]*/
+ 0x0F12001E, /*AFIT8_demsharpmix1_iGCoeff [7:0],
+ AFIT8_demsharpmix1_iWideMult [15:8]*/
+ 0x0F120900, /*AFIT8_demsharpmix1_iNarrMult [7:0],
+ AFIT8_demsharpmix1_iHystFalloff [15:8]*/
+ 0x0F120600, /*AFIT8_demsharpmix1_iHystMinMult [7:0],
+ AFIT8_demsharpmix1_iHystWidth [15:8]*/
+ 0x0F120504, /*AFIT8_demsharpmix1_iHystFallLow [7:0],
+ AFIT8_demsharpmix1_iHystFallHigh [15:8]*/
+ 0x0F120307, /*AFIT8_demsharpmix1_iHystTune [7:0],
+ * AFIT8_YUV422_DENOIsE_iUVsupport [15:8]*/
+ 0x0F128002, /*AFIT8_YUV422_DENOIsE_iYsupport [7:0],
+ AFIT8_byr_cgras_ishadingPower [15:8]*/
+ 0x0F120080, /*AFIT8_RGBGamma2_iLinearity [7:0],
+ AFIT8_RGBGamma2_iDarkReduce [15:8]*/
+ 0x0F120080, /*AFIT8_ccm_oscar_isaturation[7:0],
+ AFIT8_RGB2YUV_iYOffset [15:8]*/
+ 0x0F120080, /*AFIT8_RGB2YUV_iRGBGain [7:0],
+ AFIT8_RGB2YUV_isaturation [15:8]*/
+ 0x0F125050, /*AFIT8_sddd8a_iClustThresh_H [7:0],
+ AFIT8_sddd8a_iClustThresh_C [15:8]*/
+ 0x0F120101, /*AFIT8_sddd8a_iClustMulT_H [7:0],
+ AFIT8_sddd8a_iClustMulT_C [15:8]*/
+ 0x0F121B01, /*AFIT8_sddd8a_nClustLevel_H [7:0],
+ AFIT8_sddd8a_DispTH_Low [15:8]*/
+ 0x0F122319, /*AFIT8_sddd8a_DispTH_High [7:0],
+ AFIT8_sddd8a_iDenThreshLow [15:8]*/
+ 0x0F12960F, /*AFIT8_sddd8a_iDenThreshHigh[7:0],
+ AFIT8_Demosaicing_iEdgeDesat [15:8]*/
+ 0x0F120000, /*AFIT8_Demosaicing_iEdgeDesatThrLow [7:0],
+ AFIT8_Demosaicing_iEdgeDesatThrHigh [15:8]*/
+ 0x0F122003, /*AFIT8_Demosaicing_iEdgeDesatLimit[7:0],
+ AFIT8_Demosaicing_iDemsharpenLow [15:8]*/
+ 0x0F120A02, /*AFIT8_Demosaicing_iDemsharpenHigh[7:0],
+ AFIT8_Demosaicing_iDemsharpThresh [15:8]*/
+ 0x0F120864, /*AFIT8_Demosaicing_iDemshLowLimit [7:0],
+ AFIT8_Demosaicing_iDespeckleForDemsharp [15:8]*/
+ 0x0F121432, /*AFIT8_Demosaicing_iDemBlurLow[7:0],
+ AFIT8_Demosaicing_iDemBlurHigh [15:8]*/
+ 0x0F12A001, /*AFIT8_Demosaicing_iDemBlurRange[7:0],
+ AFIT8_sharpening_iLowsharpPower [15:8]*/
+ 0x0F122814, /*AFIT8_sharpening_iHighsharpPower[7:0],
+ AFIT8_sharpening_iLowshDenoise [15:8]*/
+ 0x0F12400A, /*AFIT8_sharpening_iHighshDenoise [7:0],
+ AFIT8_sharpening_iReduceEdgeMinMult [15:8]*/
+ 0x0F120204, /*AFIT8_sharpening_iReduceEdgeslope [7:0],
+ AFIT8_demsharpmix1_iWideFiltReduce [15:8]*/
+ 0x0F125003, /*AFIT8_demsharpmix1_iNarrFiltReduce [7:0],
+ AFIT8_sddd8a_iClustThresh_H_Bin [15:8]*/
+ 0x0F120150, /*AFIT8_sddd8a_iClustThresh_C_Bin [7:0],
+ AFIT8_sddd8a_iClustMulT_H_Bin [15:8]*/
+ 0x0F120101, /*AFIT8_sddd8a_iClustMulT_C_Bin [7:0],
+ AFIT8_sddd8a_nClustLevel_H_Bin [15:8]*/
+ 0x0F12191B, /*AFIT8_sddd8a_DispTH_Low_Bin [7:0],
+ AFIT8_sddd8a_DispTH_High_Bin [15:8]*/
+ 0x0F12070C, /*0F19 AFIT8_sddd8a_iDenThreshLow_Bin [7:0],
+ AFIT8_sddd8a_iDenThreshHigh_Bin [15:8]*/
+ 0x0F120028, /*AFIT8_Demosaicing_iEdgeDesat_Bin[7:0],
+ AFIT8_Demosaicing_iEdgeDesatThrLow_Bin [15:8]*/
+ 0x0F120300, /*AFIT8_Demosaicing_iEdgeDesatThrHigh_Bin [7:0],
+ AFIT8_Demosaicing_iEdgeDesatLimit_Bin [15:8]*/
+ 0x0F12021E, /*AFIT8_Demosaicing_iDemsharpenLow_Bin [7:0],
+ AFIT8_Demosaicing_iDemsharpenHigh_Bin [15:8]*/
+ 0x0F121E0A, /*AFIT8_Demosaicing_iDemsharpThresh_Bin [7:0],
+ AFIT8_Demosaicing_iDemshLowLimit_Bin [15:8]*/
+ 0x0F123208, /*AFIT8_Demosaicing_iDespeckleForDemsharp_Bin [7:0],
+ AFIT8_Demosaicing_iDemBlurLow_Bin [15:8]*/
+ 0x0F120114, /*AFIT8_Demosaicing_iDemBlurHigh_Bin [7:0],
+ AFIT8_Demosaicing_iDemBlurRange_Bin [15:8]*/
+ 0x0F120A28, /*1450 AFIT8_sharpening_iLowsharpPower_Bin [7:0],
+ AFIT8_sharpening_iHighsharpPower_Bin [15:8]*/
+ 0x0F120A28, /*AFIT8_sharpening_iLowshDenoise_Bin [7:0],
+ AFIT8_sharpening_iHighshDenoise_Bin [15:8]*/
+ 0x0F120440, /*AFIT8_sharpening_iReduceEdgeMinMult_Bin [7:0],
+ AFIT8_sharpening_iReduceEdgeslope_Bin [15:8]*/
+ 0x0F120302, /*AFIT8_demsharpmix1_iWideFiltReduce_Bin [7:0],
+ AFIT8_demsharpmix1_iNarrFiltReduce_Bin [15:8]*/
+ 0x0F123C3C, /*AFIT8_sddd8a_iClustThresh_H_sBin[7:0],
+ AFIT8_sddd8a_iClustThresh_C_sBin [15:8]*/
+ 0x0F120101, /*AFIT8_sddd8a_iClustMulT_H_sBin [7:0],
+ AFIT8_sddd8a_iClustMulT_C_sBin [15:8]*/
+ 0x0F121E01, /*AFIT8_sddd8a_nClustLevel_H_sBin [7:0],
+ AFIT8_sddd8a_DispTH_Low_sBin [15:8]*/
+ 0x0F12221C, /*AFIT8_sddd8a_DispTH_High_sBin [7:0],
+ AFIT8_sddd8a_iDenThreshLow_sBin [15:8]*/
+ 0x0F12281E, /*AFIT8_sddd8a_iDenThreshHigh_sBin[7:0],
+ AFIT8_Demosaicing_iEdgeDesat_sBin [15:8]*/
+ 0x0F120A00, /*AFIT8_Demosaicing_iEdgeDesatThrLow_sBin [7:0],
+ AFIT8_Demosaicing_iEdgeDesatThrHigh_sBin [15:8]*/
+ 0x0F121403, /*AFIT8_Demosaicing_iEdgeDesatLimit_sBin [7:0],
+ AFIT8_Demosaicing_iDemsharpenLow_sBin [15:8]*/
+ 0x0F121402, /*AFIT8_Demosaicing_iDemsharpenHigh_sBin [7:0],
+ AFIT8_Demosaicing_iDemsharpThresh_sBin [15:8]*/
+ 0x0F12060E, /*AFIT8_Demosaicing_iDemshLowLimit_sBin [7:0],
+ AFIT8_Demosaicing_iDespeckleForDemsharp_sBin [15:8]*/
+ 0x0F1232FF, /*AFIT8_Demosaicing_iDemBlurLow_sBin [7:0],
+ AFIT8_Demosaicing_iDemBlurHigh_sBin [15:8]*/
+ 0x0F125204, /*AFIT8_Demosaicing_iDemBlurRange_sBin [7:0],
+ AFIT8_sharpening_iLowsharpPower_sBin [15:8]*/
+ 0x0F120C40, /*AFIT8_sharpening_iHighsharpPower_sBin [7:0],
+ AFIT8_sharpening_iLowshDenoise_sBin [15:8]*/
+ 0x0F124015, /*AFIT8_sharpening_iHighshDenoise_sBin [7:0],
+ AFIT8_sharpening_iReduceEdgeMinMult_sBin [15:8]*/
+ 0x0F120204, /*AFIT8_sharpening_iReduceEdgeslope_sBin [7:0],
+ AFIT8_demsharpmix1_iWideFiltReduce_sBin [15:8]*/
+ 0x0F120003, /*AFIT8_demsharpmix1_iNarrFiltReduce_sBin [7:0]*/
+ 0x0F120000, /*AFIT16_BRIGHTNEss*/
+ 0x0F120000, /*AFIT16_CONTRAsT*/
+ 0x0F120000, /*AFIT16_sATURATION*/
+ 0x0F120000, /*AFIT16_sHARP_BLUR*/
+ 0x0F120000, /*AFIT16_GLAMOUR*/
+ 0x0F1200C1, /*AFIT16_sddd8a_edge_high*/
+ 0x0F1203FF, /*AFIT16_Demosaicing_isatVal*/
+ 0x0F12009C, /*AFIT16_sharpening_iReduceEdgeThresh*/
+ 0x0F12017C, /*AFIT16_demsharpmix1_iRGBOffset*/
+ 0x0F1203FF, /*AFIT16_demsharpmix1_iDemClamp*/
+ 0x0F12000C, /*AFIT16_demsharpmix1_iLowThreshold*/
+ 0x0F120010, /*AFIT16_demsharpmix1_iHighThreshold*/
+ 0x0F120032, /*AFIT16_demsharpmix1_iLowBright*/
+ 0x0F12028A, /*AFIT16_demsharpmix1_iHighBright*/
+ 0x0F120032, /*AFIT16_demsharpmix1_iLowsat*/
+ 0x0F1201F4, /*AFIT16_demsharpmix1_iHighsat*/
+ 0x0F120070, /*AFIT16_demsharpmix1_iTune*/
+ 0x0F120002, /*AFIT16_demsharpmix1_iHystThLow*/
+ 0x0F120000, /*AFIT16_demsharpmix1_iHystThHigh*/
+ 0x0F1201AA, /*AFIT16_demsharpmix1_iHystCenter*/
+ 0x0F12003C, /*AFIT16_YUV422_DENOIsE_iUVLowThresh*/
+ 0x0F120050, /*AFIT16_YUV422_DENOIsE_iUVHighThresh*/
+ 0x0F120000, /*AFIT16_YUV422_DENOIsE_iYLowThresh*/
+ 0x0F120000, /*AFIT16_YUV422_DENOIsE_iYHighThresh*/
+ 0x0F1200B4, /*AFIT16_sharpening_iLowsharpClamp*/
+ 0x0F120014, /*AFIT16_sharpening_iHighsharpClamp*/
+ 0x0F1200B4, /*AFIT16_sharpening_iLowsharpClamp_Bin*/
+ 0x0F120014, /*AFIT16_sharpening_iHighsharpClamp_Bin*/
+ 0x0F120046, /*AFIT16_sharpening_iLowsharpClamp_sBin*/
+ 0x0F120019, /*AFIT16_sharpening_iHighsharpClamp_sBin*/
+ 0x0F120A24, /*AFIT8_sddd8a_edge_low [7:0],
+ AFIT8_sddd8a_repl_thresh [15:8]*/
+ 0x0F121701, /*AFIT8_sddd8a_repl_force [7:0],
+ AFIT8_sddd8a_sat_level [15:8]*/
+ 0x0F120229, /*AFIT8_sddd8a_sat_thr[7:0],
+ AFIT8_sddd8a_sat_mpl [15:8]*/
+ 0x0F120503, /*AFIT8_sddd8a_sat_noise[7:0],
+ AFIT8_sddd8a_iMaxslopeAllowed [15:8]*/
+ 0x0F12080F, /*AFIT8_sddd8a_iHotThreshHigh[7:0],
+ AFIT8_sddd8a_iHotThreshLow [15:8]*/
+ 0x0F120808, /*AFIT8_sddd8a_iColdThreshHigh[7:0],
+ AFIT8_sddd8a_iColdThreshLow [15:8]*/
+ 0x0F120000, /*AFIT8_sddd8a_AddNoisePower1[7:0],
+ AFIT8_sddd8a_AddNoisePower2 [15:8]*/
+ 0x0F1200FF, /*AFIT8_sddd8a_isatsat[7:0],
+ AFIT8_sddd8a_iRadialTune [15:8]*/
+ 0x0F12022D, /*AFIT8_sddd8a_iRadialLimit [7:0],
+ AFIT8_sddd8a_iRadialPower [15:8]*/
+ 0x0F121414, /*AFIT8_sddd8a_iLowMaxslopeAllowed [7:0],
+ AFIT8_sddd8a_iHighMaxslopeAllowed [15:8]*/
+ 0x0F120301, /*AFIT8_sddd8a_iLowslopeThresh[7:0],
+ AFIT8_sddd8a_iHighslopeThresh [15:8]*/
+ 0x0F12FF07, /*AFIT8_sddd8a_isquaresRounding [7:0],
+ AFIT8_Demosaicing_iCentGrad [15:8]*/
+ 0x0F12061E, /*AFIT8_Demosaicing_iMonochrom [7:0],
+ AFIT8_Demosaicing_iDecisionThresh [15:8]*/
+ 0x0F120A1E, /*AFIT8_Demosaicing_iDesatThresh [7:0],
+ AFIT8_Demosaicing_iEnhThresh [15:8]*/
+ 0x0F120606, /*AFIT8_Demosaicing_iGRDenoiseVal [7:0],
+ AFIT8_Demosaicing_iGBDenoiseVal [15:8]*/
+ 0x0F120A03, /*AFIT8_Demosaicing_iNearGrayDesat[7:0],
+ AFIT8_Demosaicing_iDFD_ReduceCoeff [15:8]*/
+ 0x0F120028, /*AFIT8_sharpening_iMsharpen [7:0],
+ AFIT8_sharpening_iMshThresh [15:8]*/
+ 0x0F120002, /*AFIT8_sharpening_iWsharpen [7:0],
+ AFIT8_sharpening_iWshThresh [15:8]*/
+ 0x0F120001, /*AFIT8_sharpening_nsharpWidth [7:0],
+ AFIT8_sharpening_iReduceNegative [15:8]*/
+ 0x0F1200FF, /*AFIT8_sharpening_ishDespeckle [7:0],
+ AFIT8_demsharpmix1_iRGBMultiplier [15:8]*/
+ 0x0F121002, /*AFIT8_demsharpmix1_iFilterPower [7:0],
+ AFIT8_demsharpmix1_iBCoeff [15:8]*/
+ 0x0F12001E, /*AFIT8_demsharpmix1_iGCoeff [7:0],
+ AFIT8_demsharpmix1_iWideMult [15:8]*/
+ 0x0F120900, /*AFIT8_demsharpmix1_iNarrMult [7:0],
+ AFIT8_demsharpmix1_iHystFalloff [15:8]*/
+ 0x0F120600, /*AFIT8_demsharpmix1_iHystMinMult [7:0],
+ AFIT8_demsharpmix1_iHystWidth [15:8]*/
+ 0x0F120504, /*AFIT8_demsharpmix1_iHystFallLow [7:0],
+ AFIT8_demsharpmix1_iHystFallHigh [15:8]*/
+ 0x0F120307, /*AFIT8_demsharpmix1_iHystTune [7:0],
+ * AFIT8_YUV422_DENOIsE_iUVsupport [15:8]*/
+ 0x0F128001, /*AFIT8_YUV422_DENOIsE_iYsupport [7:0],
+ AFIT8_byr_cgras_ishadingPower [15:8]*/
+ 0x0F120080, /*AFIT8_RGBGamma2_iLinearity [7:0],
+ AFIT8_RGBGamma2_iDarkReduce [15:8]*/
+ 0x0F120080, /*AFIT8_ccm_oscar_isaturation[7:0],
+ AFIT8_RGB2YUV_iYOffset [15:8]*/
+ 0x0F120080, /*AFIT8_RGB2YUV_iRGBGain [7:0],
+ AFIT8_RGB2YUV_isaturation [15:8]*/
+ 0x0F125050, /*AFIT8_sddd8a_iClustThresh_H [7:0],
+ AFIT8_sddd8a_iClustThresh_C [15:8]*/
+ 0x0F120101, /*AFIT8_sddd8a_iClustMulT_H [7:0],
+ AFIT8_sddd8a_iClustMulT_C [15:8]*/
+ 0x0F121B01, /*AFIT8_sddd8a_nClustLevel_H [7:0],
+ AFIT8_sddd8a_DispTH_Low [15:8]*/
+ 0x0F121219, /*AFIT8_sddd8a_DispTH_High [7:0],
+ AFIT8_sddd8a_iDenThreshLow [15:8]*/
+ 0x0F12320D, /*AFIT8_sddd8a_iDenThreshHigh[7:0],
+ AFIT8_Demosaicing_iEdgeDesat [15:8]*/
+ 0x0F120A0A, /*AFIT8_Demosaicing_iEdgeDesatThrLow [7:0],
+ AFIT8_Demosaicing_iEdgeDesatThrHigh [15:8]*/
+ 0x0F122304, /*AFIT8_Demosaicing_iEdgeDesatLimit[7:0],
+ AFIT8_Demosaicing_iDemsharpenLow [15:8]*/
+ 0x0F120A08, /*AFIT8_Demosaicing_iDemsharpenHigh[7:0],
+ AFIT8_Demosaicing_iDemsharpThresh [15:8]*/
+ 0x0F120832, /*AFIT8_Demosaicing_iDemshLowLimit [7:0],
+ AFIT8_Demosaicing_iDespeckleForDemsharp [15:8]*/
+ 0x0F121432, /*AFIT8_Demosaicing_iDemBlurLow[7:0],
+ AFIT8_Demosaicing_iDemBlurHigh [15:8]*/
+ 0x0F12A001, /*AFIT8_Demosaicing_iDemBlurRange[7:0],
+ AFIT8_sharpening_iLowsharpPower [15:8]*/
+ 0x0F122A0A, /*AFIT8_sharpening_iHighsharpPower[7:0],
+ AFIT8_sharpening_iLowshDenoise [15:8]*/
+ 0x0F124006, /*AFIT8_sharpening_iHighshDenoise [7:0],
+ AFIT8_sharpening_iReduceEdgeMinMult [15:8]*/
+ 0x0F120604, /*AFIT8_sharpening_iReduceEdgeslope [7:0],
+ AFIT8_demsharpmix1_iWideFiltReduce [15:8]*/
+ 0x0F125006, /*AFIT8_demsharpmix1_iNarrFiltReduce [7:0],
+ AFIT8_sddd8a_iClustThresh_H_Bin [15:8]*/
+ 0x0F120150, /*AFIT8_sddd8a_iClustThresh_C_Bin [7:0],
+ AFIT8_sddd8a_iClustMulT_H_Bin [15:8]*/
+ 0x0F120101, /*AFIT8_sddd8a_iClustMulT_C_Bin [7:0],
+ AFIT8_sddd8a_nClustLevel_H_Bin [15:8]*/
+ 0x0F12191B, /*AFIT8_sddd8a_DispTH_Low_Bin [7:0],
+ AFIT8_sddd8a_DispTH_High_Bin [15:8]*/
+ 0x0F12070C, /*0F19 AFIT8_sddd8a_iDenThreshLow_Bin [7:0],
+ AFIT8_sddd8a_iDenThreshHigh_Bin [15:8]*/
+ 0x0F120A28, /*AFIT8_Demosaicing_iEdgeDesat_Bin[7:0],
+ AFIT8_Demosaicing_iEdgeDesatThrLow_Bin [15:8]*/
+ 0x0F12040A, /*AFIT8_Demosaicing_iEdgeDesatThrHigh_Bin [7:0],
+ AFIT8_Demosaicing_iEdgeDesatLimit_Bin [15:8]*/
+ 0x0F120820, /*AFIT8_Demosaicing_iDemsharpenLow_Bin [7:0],
+ AFIT8_Demosaicing_iDemsharpenHigh_Bin [15:8]*/
+ 0x0F12280A, /*AFIT8_Demosaicing_iDemsharpThresh_Bin [7:0],
+ AFIT8_Demosaicing_iDemshLowLimit_Bin [15:8]*/
+ 0x0F123208, /*AFIT8_Demosaicing_iDespeckleForDemsharp_Bin [7:0],
+ AFIT8_Demosaicing_iDemBlurLow_Bin [15:8]*/
+ 0x0F120114, /*AFIT8_Demosaicing_iDemBlurHigh_Bin [7:0],
+ AFIT8_Demosaicing_iDemBlurRange_Bin [15:8]*/
+ 0x0F120532, /*0A64 AFIT8_Sharpening_iLowsharpPower_Bin [7:0],
+ AFIT8_sharpening_iHighsharpPower_Bin [15:8]*/
+ 0x0F12062A, /*AFIT8_Sharpening_iLowShDenoise_Bin [7:0],
+ AFIT8_sharpening_iHighshDenoise_Bin [15:8]*/
+ 0x0F120440, /*AFIT8_Sharpening_iReduceEdgeMinMult_Bin [7:0],
+ AFIT8_sharpening_iReduceEdgeslope_Bin [15:8]*/
+ 0x0F120606, /*AFIT8_demsharpmix1_iWideFiltReduce_Bin [7:0],
+ AFIT8_demsharpmix1_iNarrFiltReduce_Bin [15:8]*/
+ 0x0F124646, /*AFIT8_sddd8a_iClustThresh_H_sBin[7:0],
+ AFIT8_sddd8a_iClustThresh_C_sBin [15:8]*/
+ 0x0F120101, /*AFIT8_sddd8a_iClustMulT_H_sBin [7:0],
+ AFIT8_sddd8a_iClustMulT_C_sBin [15:8]*/
+ 0x0F121801, /*AFIT8_sddd8a_nClustLevel_H_sBin [7:0],
+ AFIT8_sddd8a_DispTH_Low_sBin [15:8]*/
+ 0x0F12191C, /*AFIT8_sddd8a_DispTH_High_sBin [7:0],
+ AFIT8_sddd8a_iDenThreshLow_sBin [15:8]*/
+ 0x0F122818, /*AFIT8_sddd8a_iDenThreshHigh_sBin[7:0],
+ AFIT8_Demosaicing_iEdgeDesat_sBin [15:8]*/
+ 0x0F120A00, /*AFIT8_Demosaicing_iEdgeDesatThrLow_sBin [7:0],
+ AFIT8_Demosaicing_iEdgeDesatThrHigh_sBin [15:8]*/
+ 0x0F121403, /*AFIT8_Demosaicing_iEdgeDesatLimit_sBin [7:0],
+ AFIT8_Demosaicing_iDemsharpenLow_sBin [15:8]*/
+ 0x0F121405, /*AFIT8_Demosaicing_iDemsharpenHigh_sBin [7:0],
+ AFIT8_Demosaicing_iDemsharpThresh_sBin [15:8]*/
+ 0x0F12050C, /*AFIT8_Demosaicing_iDemshLowLimit_sBin [7:0],
+ AFIT8_Demosaicing_iDespeckleForDemsharp_sBin [15:8]*/
+ 0x0F1232FF, /*AFIT8_Demosaicing_iDemBlurLow_sBin [7:0],
+ AFIT8_Demosaicing_iDemBlurHigh_sBin [15:8]*/
+ 0x0F125204, /*AFIT8_Demosaicing_iDemBlurRange_sBin [7:0],
+ AFIT8_sharpening_iLowsharpPower_sBin [15:8]*/
+ 0x0F121440, /*AFIT8_sharpening_iHighsharpPower_sBin [7:0],
+ AFIT8_sharpening_iLowshDenoise_sBin [15:8]*/
+ 0x0F124015, /*AFIT8_sharpening_iHighshDenoise_sBin [7:0],
+ AFIT8_sharpening_iReduceEdgeMinMult_sBin [15:8]*/
+ 0x0F120204, /*AFIT8_sharpening_iReduceEdgeslope_sBin [7:0],
+ AFIT8_demsharpmix1_iWideFiltReduce_sBin [15:8]*/
+ 0x0F120003, /*AFIT8_demsharpmix1_iNarrFiltReduce_sBin [7:0]*/
+ 0x0F127DFA, /*ConstAfitBaseVals*/
+ 0x0F12FFBD, /*ConstAfitBaseVals_1_*/
+ 0x0F1226FE, /*ConstAfitBaseVals_2_*/
+ 0x0F12F7BC, /*ConstAfitBaseVals_3_*/
+ 0x0F127E06, /*ConstAfitBaseVals_4_*/
+ 0x0F1200D3, /*ConstAfitBaseVals_5_*/
+
+ 0x002A0156,
+ 0x0F120003, /*REG_TC_GP_ActivePrevConfig*/
+ 0x002A015E,
+ 0x0F120000, /*REG_TC_GP_ActiveCapConfig*/
+ 0x002A015A,
+ 0x0F120001, /*REG_TC_GP_PrevOpenAfterChange*/
+ 0x002A0142,
+ 0x0F120001, /*REG_TC_GP_NewConfigSync*/
+ 0x002A0158,
+ 0x0F120001, /*REG_TC_GP_PrevConfigChanged*/
+ 0x002A0160,
+ 0x0F120001, /*REG_TC_GP_CapConfigChanged*/
+ 0x002A013A,
+ 0x0F120001, /*REG_TC_GP_EnablePreview*/
+ 0x0F120001, /*REG_TC_GP_EnablePreviewChanged*/
+ 0xFFFF0096,
+};
+
+static const u32 s5k5bbgx_stream_stop[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A01F0,
+ 0x0F120000, /* REG_TC_GP_EnablePreview */
+ 0x0F120001, /* REG_TC_GP_EnablePreviewChanged*/
+ /*0xffff0096, 150ms*/
+};
+
+#if (0)
+static const u32 s5k5bbgx_stream_start[] = {
+ 0xFCFCD000,
+ 0x002AB00C,
+ 0x0F120001,
+};
+#endif
+
+/*=================================
+* CAMERA_BRIGHTNESS_1 (1/9) M4 *
+==================================*/
+static const u32 s5k5bbgx_bright_m4[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A012A,
+ 0x0F12FF00,
+};
+
+/*=================================
+* CAMERA_BRIGHTNESS_2 (2/9) M3 *
+==================================*/
+
+static const u32 s5k5bbgx_bright_m3[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A012A,
+ 0x0F12FF00,
+};
+
+/*=================================
+ CAMERA_BRIGHTNESS_3 (3/9) M2
+==================================*/
+static const u32 s5k5bbgx_bright_m2[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A012A,
+ 0x0F12FF9B,
+};
+
+/*=================================
+ CAMERA_BRIGHTNESS_4 (4/9) M1
+==================================*/
+
+static const u32 s5k5bbgx_bright_m1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A012A,
+ 0x0F12FF9D,
+};
+
+/*=================================
+ CAMERA_BRIGHTNESS_5 (5/9) Default
+==================================*/
+static const u32 s5k5bbgx_bright_default[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A012A,
+ 0x0F120000,
+};
+
+/*=================================
+ CAMERA_BRIGHTNESS_6 (6/9) P1
+==================================*/
+static const u32 s5k5bbgx_bright_p1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A012A,
+ 0x0F120020,
+};
+
+/*=================================
+ CAMERA_BRIGHTNESS_7 (7/9) P2
+==================================*/
+static const u32 s5k5bbgx_bright_p2[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A012A,
+ 0x0F120040,
+};
+
+/*=================================
+ CAMERA_BRIGHTNESS_8 (8/9) P3
+==================================*/
+static const u32 s5k5bbgx_bright_p3[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A012A,
+ 0x0F120060,
+};
+
+/*=================================
+ CAMERA_BRIGHTNESS_9 (9/9) P4
+==================================*/
+static const u32 s5k5bbgx_bright_p4[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A012A,
+ 0x0F120080,
+};
+
+/*******************************************************
+* CAMERA_VT_PRETTY_0 Default
+* 200s self cam pretty
+*******************************************************/
+static const u32 s5k5bbgx_vt_pretty_default[] = {
+ /* 0xffff000A, */
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A04CC,
+
+ 0x0F120000,
+ 0x0F120002,
+ 0x0F120008,
+ 0x0F120018,
+ 0x0F12005A,
+ 0x0F1200DF,
+ 0x0F12013F,
+ 0x0F120186,
+ 0x0F1201E6,
+ 0x0F120236,
+ 0x0F1202BA,
+ 0x0F12032A,
+ 0x0F120385,
+ 0x0F1203C2,
+ 0x0F1203EA,
+ 0x0F1203FF,
+
+ 0x0F120000,
+ 0x0F120002,
+ 0x0F120008,
+ 0x0F120018,
+ 0x0F12005A,
+ 0x0F1200DF,
+ 0x0F12013F,
+ 0x0F120186,
+ 0x0F1201E6,
+ 0x0F120236,
+ 0x0F1202BA,
+ 0x0F12032A,
+ 0x0F120385,
+ 0x0F1203C2,
+ 0x0F1203EA,
+ 0x0F1203FF,
+
+ 0x0F120000,
+ 0x0F120002,
+ 0x0F120008,
+ 0x0F120018,
+ 0x0F12005A,
+ 0x0F1200DF,
+ 0x0F12013F,
+ 0x0F120186,
+ 0x0F1201E6,
+ 0x0F120236,
+ 0x0F1202BA,
+ 0x0F12032A,
+ 0x0F120385,
+ 0x0F1203C2,
+ 0x0F1203EA,
+ 0x0F1203FF,
+};
+
+
+/*******************************************************
+* CAMERA_VT_PRETTY_1
+*******************************************************/
+static const u32 s5k5bbgx_vt_pretty_1[] = {
+ /*0xffff000A,*/
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A04CC,
+
+ 0x0F120000,
+ 0x0F12000D,
+ 0x0F12001B,
+ 0x0F120046,
+ 0x0F1200AA,
+ 0x0F120120,
+ 0x0F120190,
+ 0x0F1201E0,
+ 0x0F120250,
+ 0x0F1202A5,
+ 0x0F120320,
+ 0x0F120370,
+ 0x0F1203B0,
+ 0x0F1203D8,
+ 0x0F1203F2,
+ 0x0F120400,
+
+ 0x0F120000,
+ 0x0F12000D,
+ 0x0F12001B,
+ 0x0F120046,
+ 0x0F1200AA,
+ 0x0F120120,
+ 0x0F120190,
+ 0x0F1201E0,
+ 0x0F120250,
+ 0x0F1202A5,
+ 0x0F120320,
+ 0x0F120370,
+ 0x0F1203B0,
+ 0x0F1203D8,
+ 0x0F1203F2,
+ 0x0F120400,
+
+ 0x0F120000,
+ 0x0F12000D,
+ 0x0F12001B,
+ 0x0F120046,
+ 0x0F1200AA,
+ 0x0F120120,
+ 0x0F120190,
+ 0x0F1201E0,
+ 0x0F120250,
+ 0x0F1202A5,
+ 0x0F120320,
+ 0x0F120370,
+ 0x0F1203B0,
+ 0x0F1203D8,
+ 0x0F1203F2,
+ 0x0F120400,
+};
+
+
+/*******************************************************
+* CAMERA_VT_PRETTY_2 *
+*******************************************************/
+static const u32 s5k5bbgx_vt_pretty_2[] = {
+ /* 0xffff000A, */
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A04CC,
+
+ 0x0F120000, /* 0000 */
+ 0x0F12000D, /* 000D */
+ 0x0F12001B, /* 001B */
+ 0x0F120055, /* 0050 */
+ 0x0F1200C0, /* 00B4 */
+ 0x0F120164, /* 0154 */
+ 0x0F1201C0, /* 01B8 */
+ 0x0F120220, /* 0212 */
+ 0x0F1202A0, /* 0294 */
+ 0x0F1202F0, /* 02E4 */
+ 0x0F120365, /* 0352 */
+ 0x0F1203A0, /* 0398 */
+ 0x0F1203D4, /* 03D4 */
+ 0x0F1203E8, /* 03E8 */
+ 0x0F1203F7, /* 03F7 */
+ 0x0F120400, /* 0400 */
+
+ 0x0F120000, /* 0000 */
+ 0x0F12000D, /* 000D */
+ 0x0F12001B, /* 001B */
+ 0x0F120055, /* 0050 */
+ 0x0F1200C0, /* 00B4 */
+ 0x0F120164, /* 0154 */
+ 0x0F1201C0, /* 01B8 */
+ 0x0F120220, /* 0212 */
+ 0x0F1202A0, /* 0294 */
+ 0x0F1202F0, /* 02E4 */
+ 0x0F120365, /* 0352 */
+ 0x0F1203A0, /* 0398 */
+ 0x0F1203D4, /* 03D4 */
+ 0x0F1203E8, /* 03E8 */
+ 0x0F1203F7, /* 03F7 */
+ 0x0F120400, /* 0400 */
+
+ 0x0F120000, /* 0000 */
+ 0x0F12000D, /* 000D */
+ 0x0F12001B, /* 001B */
+ 0x0F120055, /* 0050 */
+ 0x0F1200C0, /* 00B4 */
+ 0x0F120164, /* 0154 */
+ 0x0F1201C0, /* 01B8 */
+ 0x0F120220, /* 0212 */
+ 0x0F1202A0, /* 0294 */
+ 0x0F1202F0, /* 02E4 */
+ 0x0F120365, /* 0352 */
+ 0x0F1203A0, /* 0398 */
+ 0x0F1203D4, /* 03D4 */
+ 0x0F1203E8, /* 03E8 */
+ 0x0F1203F7, /* 03F7 */
+ 0x0F120400, /* 0400 */
+};
+
+
+/*******************************************************
+* CAMERA_VT_PRETTY_3
+*******************************************************/
+static const u32 s5k5bbgx_vt_pretty_3[] = {
+ /* 0xffff000A, */
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A04CC,
+
+ 0x0F120000, /* 0000, 0000, */
+ 0x0F12000D, /* 000D, 000D, */
+ 0x0F12001B, /* 001B, 001B, */
+ 0x0F120064, /* 0064, 0064, */
+ 0x0F1200E5, /* 00E5, 00DC, */
+ 0x0F120190, /* 95, 0195, 0186, */
+ 0x0F1201F5, /* 01F5, 01EA, */
+ 0x0F120260, /* 0265, 024E, */
+ 0x0F1202E5, /* 02F0, 02DA, */
+ 0x0F12032A, /* 30, 0335, 0320, */
+ 0x0F12038A, /* 90, 0395, 038E, */
+ 0x0F1203C5, /* CA, 03D0, 03CA, / */
+ 0x0F1203E0, /* E5, 03E8, 03E8, */
+ 0x0F1203EC, /* F0, 03F2, 03F2, */
+ 0x0F1203F7, /* 03F7, 03F7, */
+ 0x0F120400, /* 0400, 0400, */
+
+ 0x0F120000, /* 0000, 0000, 0000, */
+ 0x0F12000D, /* 000D, 000D, 000D, */
+ 0x0F12001B, /* 001B, 001B, 001B, */
+ 0x0F120064, /* 0064, 0064, 0064, */
+ 0x0F1200E5, /* 00E5, 00E5, 00DC, */
+ 0x0F120190, /* 0195, 0195, 0186, */
+ 0x0F1201F5, /* 01F5, 01F5, 01EA, */
+ 0x0F120260, /* 0260, 0265, 024E, */
+ 0x0F1202E5, /* 02E5, 02F0, 02DA, */
+ 0x0F12032A, /* 0330, 0335, 0320, */
+ 0x0F12038A, /* 0390, 0395, 038E, */
+ 0x0F1203C5, /* 03CA, 03D0, 03CA, */
+ 0x0F1203E0, /* 03E5, 03E8, 03E8, */
+ 0x0F1203EC, /* 03F0, 03F2, 03F2, */
+ 0x0F1203F7, /* 03F7, 03F7, 03F7, */
+ 0x0F120400, /* 0400, 0400, 0400, */
+
+ 0x0F120000, /* 0000, 0000, 0000, */
+ 0x0F12000D, /* 000D, 000D, 000D, */
+ 0x0F12001B, /* 001B, 001B, 001B, */
+ 0x0F120064, /* 0064, 0064, 0064, */
+ 0x0F1200E5, /* 00E5, 00E5, 00DC, */
+ 0x0F120190, /* 0195, 0195, 0186, */
+ 0x0F1201F5, /* 01F5, 01F5, 01EA, */
+ 0x0F120260, /* 0260, 0265, 024E, */
+ 0x0F1202E5, /* 02E5, 02F0, 02DA, */
+ 0x0F12032A, /* 0330, 0335, 0320, */
+ 0x0F12038A, /* 0390, 0395, 038E, */
+ 0x0F1203C5, /* 03CA, 03D0, 03CA, */
+ 0x0F1203E0, /* 03E5, 03E8, 03E8, */
+ 0x0F1203EC, /* 03F0, 03F2, 03F2, */
+ 0x0F1203F7, /* 03F7, 03F7, 03F7, */
+ 0x0F120400, /* 0400, 0400, 0400, */
+};
+
+static const u32 s5k5bbgx_vt_7fps[] = {
+ /* Fixed 7fps Mode */
+ 0xFCFCD000,
+ 0x00287000,
+
+ 0x002A0252,
+ 0x0F120000, /* FrRateQualityType */
+ 0x002A0250,
+ 0x0F120002, /* usFrTimeType */
+ 0x002A0254,
+ 0x0F120535, /* 7fps */
+ 0x0F120000,
+
+ 0x002A021C,
+ 0x0F120000, /* REG_TC_GP_ActivePrevConfig */
+ 0x002A0220,
+ 0x0F120001, /* REG_TC_GP_PrevOpenAfterChange */
+ 0x002A01F8,
+ 0x0F120001, /* REG_TC_GP_NewConfigSync */
+ 0x002A021E,
+ 0x0F120001, /* REG_TC_GP_PrevConfigChanged */
+ 0x002A01F0,
+ 0x0F120001, /* REG_TC_GP_EnablePreview */
+ 0x0F120001, /* REG_TC_GP_EnablePreviewChanged */
+
+ 0xffff0096, /* delay 150ms */
+
+ 0x0028D000, /* mipi */
+ 0x002AB0CC,
+ 0x0F12000B,
+};
+
+static const u32 s5k5bbgx_vt_10fps[] = {
+ /* Fixed 10fps Mode */
+ 0xFCFCD000,
+ 0x00287000,
+
+ 0x002A0252,
+ 0x0F120000, /* FrRateQualityType */
+ 0x002A0250,
+ 0x0F120002, /* usFrTimeType */
+ 0x002A0254,
+ 0x0F1203E8, /* 10fps */
+ 0x0F120000,
+
+ 0x002A021C,
+ 0x0F120000, /* REG_TC_GP_ActivePrevConfig */
+ 0x002A0220,
+ 0x0F120001, /* REG_TC_GP_PrevOpenAfterChange */
+ 0x002A01F8,
+ 0x0F120001, /* REG_TC_GP_NewConfigSync */
+ 0x002A021E,
+ 0x0F120001, /* REG_TC_GP_PrevConfigChanged */
+ 0x002A01F0,
+ 0x0F120001, /* REG_TC_GP_EnablePreview */
+ 0x0F120001, /* REG_TC_GP_EnablePreviewChanged */
+
+ 0xffff0096, /* delay 150ms */
+
+ 0x0028D000, /* mipi */
+ 0x002AB0CC,
+ 0x0F12000B,
+};
+
+static const u32 s5k5bbgx_vt_12fps[] = {
+ /* Fixed 12fps Mode */
+ 0xFCFCD000,
+ 0x00287000,
+
+ 0x002A0252,
+ 0x0F120000, /* FrRateQualityType */
+ 0x002A0250,
+ 0x0F120002, /* usFrTimeType */
+ 0x002A0254,
+ 0x0F120341, /* 12fps */
+ 0x0F120000,
+
+ 0x002A021C,
+ 0x0F120000, /* REG_TC_GP_ActivePrevConfig */
+ 0x002A0220,
+ 0x0F120001, /* REG_TC_GP_PrevOpenAfterChange */
+ 0x002A01F8,
+ 0x0F120001, /* REG_TC_GP_NewConfigSync */
+ 0x002A021E,
+ 0x0F120001, /* REG_TC_GP_PrevConfigChanged */
+ 0x002A01F0,
+ 0x0F120001, /* REG_TC_GP_EnablePreview */
+ 0x0F120001, /* REG_TC_GP_EnablePreviewChanged */
+
+ 0xffff0096, /* delay 150ms */
+
+ 0x0028D000, /* mipi */
+ 0x002AB0CC,
+ 0x0F12000B,
+};
+
+static const u32 s5k5bbgx_vt_15fps[] = {
+ /* Fixed 15fps Mode */
+ 0xFCFCD000,
+ 0x00287000,
+
+ 0x002A0252,
+ 0x0F120000, /* FrRateQualityType */
+ 0x002A0250,
+ 0x0F120002, /* usFrTimeType */
+ 0x002A0254,
+ 0x0F12029A, /* 15fps*/
+ 0x0F120000,
+
+ 0x002A021C,
+ 0x0F120000, /* REG_TC_GP_ActivePrevConfig */
+ 0x002A0220,
+ 0x0F120001, /* REG_TC_GP_PrevOpenAfterChange */
+ 0x002A01F8,
+ 0x0F120001, /* REG_TC_GP_NewConfigSync */
+ 0x002A021E,
+ 0x0F120001, /* REG_TC_GP_PrevConfigChanged */
+ 0x002A01F0,
+ 0x0F120001, /* REG_TC_GP_EnablePreview */
+ 0x0F120001, /* REG_TC_GP_EnablePreviewChanged */
+
+ 0xffff0096, /* delay 150ms */
+
+ 0x0028D000, /*mipi */
+ 0x002AB0CC,
+ 0x0F12000B,
+};
+
+/*******************************************************
+* CAMERA_DTP_ON
+*******************************************************/
+static const u32 s5k5bbgx_pattern_on[] = {
+ 0xffff01f4, /* Delay 500ms*/
+
+ 0xFCFCD000,
+ 0x0028D000,
+ 0x002AB054,
+ 0x0F120005, /*5:8bit Mode, 1:10Bit Mode*/
+
+ 0xffff0032, /* Delay 50msec */
+};
+
+/*******************************************************
+* CAMERA_DTP_OFF
+*******************************************************/
+static const u32 s5k5bbgx_pattern_off[] = {
+ 0xFCFCD000,
+ 0x0028D000,
+ 0x002AB054,
+ 0x0F120000,
+};
+
+#endif /* __S5K5BBGX_SETFILE_H */
diff --git a/drivers/media/video/s5k5ccgx.c b/drivers/media/video/s5k5ccgx.c
index 2123304..51ffd6f 100644
--- a/drivers/media/video/s5k5ccgx.c
+++ b/drivers/media/video/s5k5ccgx.c
@@ -1309,15 +1309,15 @@ static int s5k5ccgx_af_start_preflash(struct v4l2_subdev *sd)
break;
}
- /* We wait for 200ms after pre flash on.
- * check whether AE is stable.*/
- msleep(200);
-
/* Check AE-stable */
if (state->focus.preflash == PREFLASH_ON) {
+ /* We wait for 200ms after pre flash on.
+ * check whether AE is stable.*/
+ msleep(200);
+
/* Do checking AE-stable */
for (count = 0; count < AE_STABLE_SEARCH_COUNT; count++) {
- if (state->focus.start == AUTO_FOCUS_OFF) {
+ if (state->focus.cancel) {
cam_info("af_start_preflash: \
AF is cancelled!\n");
state->focus.status = AF_RESULT_CANCELLED;
@@ -1332,11 +1332,11 @@ static int s5k5ccgx_af_start_preflash(struct v4l2_subdev *sd)
if (read_value == 0x0001) {
af_dbg("AE-stable success,"
" count=%d, delay=%dms\n", count,
- state->one_frame_delay_ms);
+ AE_STABLE_SEARCH_DELAY);
break;
}
- msleep(state->one_frame_delay_ms);
+ msleep(AE_STABLE_SEARCH_DELAY);
}
/* restore write mode */
@@ -1345,10 +1345,10 @@ static int s5k5ccgx_af_start_preflash(struct v4l2_subdev *sd)
if (unlikely(count >= AE_STABLE_SEARCH_COUNT)) {
cam_err("%s: ERROR, AE unstable."
" count=%d, delay=%dms\n",
- __func__, count, state->one_frame_delay_ms);
+ __func__, count, AE_STABLE_SEARCH_DELAY);
/* return -ENODEV; */
}
- } else if (state->focus.start == AUTO_FOCUS_OFF) {
+ } else if (state->focus.cancel) {
cam_info("af_start_preflash: AF is cancelled!\n");
state->focus.status = AF_RESULT_CANCELLED;
}
@@ -1364,6 +1364,7 @@ static int s5k5ccgx_af_start_preflash(struct v4l2_subdev *sd)
state->focus.preflash = PREFLASH_NONE;
}
+ state->focus.cancel = 0;
if (state->focus.touch)
state->focus.touch = 0;
}
@@ -1408,7 +1409,7 @@ static int s5k5ccgx_do_af(struct v4l2_subdev *sd)
/*1st search*/
for (count = 0; count < FIRST_AF_SEARCH_COUNT; count++) {
- if (state->focus.start == AUTO_FOCUS_OFF) {
+ if (state->focus.cancel) {
cam_dbg("do_af: AF is cancelled while doing(1st)\n");
state->focus.status = AF_RESULT_CANCELLED;
goto check_done;
@@ -1423,7 +1424,7 @@ static int s5k5ccgx_do_af(struct v4l2_subdev *sd)
if (read_value != 0x01)
break;
- msleep(state->one_frame_delay_ms);
+ msleep(AF_SEARCH_DELAY);
}
if (read_value != 0x02) {
@@ -1436,14 +1437,14 @@ static int s5k5ccgx_do_af(struct v4l2_subdev *sd)
/*2nd search*/
cam_dbg("AF 2nd search\n");
for (count = 0; count < SECOND_AF_SEARCH_COUNT; count++) {
- msleep(state->one_frame_delay_ms);
-
- if (state->focus.start == AUTO_FOCUS_OFF) {
+ if (state->focus.cancel) {
cam_dbg("do_af: AF is cancelled while doing(2nd)\n");
state->focus.status = AF_RESULT_CANCELLED;
goto check_done;
}
+ msleep(AF_SEARCH_DELAY);
+
read_value = 0x0FFFF;
s5k5ccgx_i2c_write_twobyte(client, 0x002C, 0x7000);
s5k5ccgx_i2c_write_twobyte(client, 0x002E, 0x1F2F);
@@ -1472,11 +1473,12 @@ check_done:
* But we now unlock it unconditionally if AF is started,
*/
if (state->focus.status == AF_RESULT_CANCELLED) {
- cam_dbg("%s: Single AF cancelled.\n", __func__);
+ cam_dbg("do_af: Single AF cancelled\n");
s5k5ccgx_set_lock(sd, AEAWB_UNLOCK, false);
+ state->focus.cancel = 0;
} else {
state->focus.start = AUTO_FOCUS_OFF;
- cam_dbg("%s: Single AF finished\n", __func__);
+ cam_dbg("do_af: Single AF finished\n");
}
if ((state->focus.preflash == PREFLASH_ON) &&
@@ -1519,14 +1521,18 @@ static int s5k5ccgx_set_af(struct v4l2_subdev *sd, s32 val)
state->focus.start = val;
if (val == AUTO_FOCUS_ON) {
+ state->focus.cancel = 0;
err = queue_work(state->workqueue, &state->af_work);
- if (likely(err))
- state->focus.status = AF_RESULT_DOING;
- else
- cam_warn("WARNING, AF is still processing. So new AF cannot start\n");
+ if (unlikely(!err)) {
+ cam_warn("AF is still operating!\n");
+ return 0;
+ }
+
+ state->focus.status = AF_RESULT_DOING;
} else {
/* Cancel AF */
cam_info("set_af: AF cancel requested!\n");
+ state->focus.cancel = 1;
}
cam_trace("X\n");
@@ -1540,7 +1546,7 @@ static int s5k5ccgx_stop_af(struct v4l2_subdev *sd)
int err = 0;
cam_trace("E\n");
- mutex_lock(&state->af_lock);
+ /* mutex_lock(&state->af_lock); */
switch (state->focus.status) {
case AF_RESULT_FAILED:
@@ -1568,23 +1574,15 @@ static int s5k5ccgx_stop_af(struct v4l2_subdev *sd)
break;
}
- if (!state->focus.touch) {
- /* We move lens to default position if af is cancelled.*/
- err = s5k5ccgx_return_focus(sd);
- if (unlikely(err)) {
- cam_err("%s: ERROR, fail to af_norma_mode (%d)\n",
- __func__, err);
- goto err_out;
- }
- } else
+ if (state->focus.touch)
state->focus.touch = 0;
- mutex_unlock(&state->af_lock);
+ /* mutex_unlock(&state->af_lock); */
cam_trace("X\n");
return 0;
err_out:
- mutex_unlock(&state->af_lock);
+ /* mutex_unlock(&state->af_lock); */
return err;
}
@@ -1593,22 +1591,39 @@ static void s5k5ccgx_af_worker(struct work_struct *work)
struct s5k5ccgx_state *state = container_of(work, \
struct s5k5ccgx_state, af_work);
struct v4l2_subdev *sd = &state->sd;
+ struct s5k5ccgx_interval *win_stable = &state->focus.win_stable;
+ u32 touch_win_delay = 0;
+ s32 interval = 0;
int err = -EINVAL;
cam_trace("E\n");
mutex_lock(&state->af_lock);
+ state->focus.reset_done = 0;
if (state->sensor_mode == SENSOR_CAMERA) {
state->one_frame_delay_ms = ONE_FRAME_DELAY_MS_NORMAL;
+ touch_win_delay = ONE_FRAME_DELAY_MS_LOW;
err = s5k5ccgx_af_start_preflash(sd);
if (unlikely(err))
goto out;
if (state->focus.status == AF_RESULT_CANCELLED)
goto out;
- } else {
- state->one_frame_delay_ms = 50;
+ } else
+ state->one_frame_delay_ms = touch_win_delay = 50;
+
+ /* sleep here for the time needed for af window before do_af. */
+ if (state->focus.touch) {
+ do_gettimeofday(&win_stable->curr_time);
+ interval = GET_ELAPSED_TIME(win_stable->curr_time, \
+ win_stable->before_time) / 1000;
+ if (interval < touch_win_delay) {
+ cam_dbg("window stable: %dms + %dms\n", interval,
+ touch_win_delay - interval);
+ debug_msleep(sd, touch_win_delay - interval);
+ } else
+ cam_dbg("window stable: %dms\n", interval);
}
s5k5ccgx_do_af(sd);
@@ -1623,19 +1638,36 @@ out:
static int s5k5ccgx_set_focus_mode(struct v4l2_subdev *sd, s32 val)
{
struct s5k5ccgx_state *state = to_state(sd);
- u32 af_cancel = 0;
+ u32 cancel = 0;
+ u8 focus_mode = (u8)val;
int err = -EINVAL;
/* cam_trace("E\n");*/
- cam_dbg("%s val =%d(0x%X)\n", __func__, val, val);
if (state->focus.mode == val)
return 0;
- af_cancel = (u32)val & FOCUS_MODE_DEFAULT;
+ cancel = (u32)val & FOCUS_MODE_DEFAULT;
+
+ /* Do nothing if cancel request occurs when af is being finished*/
+ if (cancel && (state->focus.status == AF_RESULT_DOING)) {
+ state->focus.cancel = 1;
+ return 0;
+ }
+
+ cam_dbg("%s val =%d(0x%X)\n", __func__, val, val);
+
mutex_lock(&state->af_lock);
+ if (cancel) {
+ s5k5ccgx_stop_af(sd);
+ if (state->focus.reset_done) {
+ cam_dbg("AF is already cancelled fully\n");
+ goto out;
+ }
+ state->focus.reset_done = 1;
+ }
- switch (val) {
+ switch (focus_mode) {
case FOCUS_MODE_MACRO:
err = s5k5ccgx_set_from_table(sd, "af_macro_mode",
&state->regs->af_macro_mode, 1, 0);
@@ -1645,7 +1677,7 @@ static int s5k5ccgx_set_focus_mode(struct v4l2_subdev *sd, s32 val)
goto err_out;
}
- state->focus.mode = FOCUS_MODE_MACRO;
+ state->focus.mode = focus_mode;
break;
case FOCUS_MODE_INFINITY:
@@ -1659,7 +1691,7 @@ static int s5k5ccgx_set_focus_mode(struct v4l2_subdev *sd, s32 val)
goto err_out;
}
- state->focus.mode = val;
+ state->focus.mode = focus_mode;
break;
case FOCUS_MODE_FACEDETECT:
@@ -1668,18 +1700,14 @@ static int s5k5ccgx_set_focus_mode(struct v4l2_subdev *sd, s32 val)
break;
default:
- if (!af_cancel) {
- cam_err("%s: ERROR, invalid val(0x%X)\n:",
- __func__, val);
- goto err_out;
- }
+ cam_err("%s: ERROR, invalid val(0x%X)\n:",
+ __func__, val);
+ goto err_out;
break;
}
- mutex_unlock(&state->af_lock);
-
- if (af_cancel)
- s5k5ccgx_stop_af(sd);
+out:
+ mutex_unlock(&state->af_lock);
return 0;
err_out:
@@ -1820,11 +1848,11 @@ static int s5k5ccgx_set_af_window(struct v4l2_subdev *sd)
err |= s5k5ccgx_i2c_write_twobyte(client, 0x002A, 0x023C);
err |= s5k5ccgx_i2c_write_twobyte(client, 0x0F12, 0x0001);
- debug_msleep(sd, 60);
+ do_gettimeofday(&state->focus.win_stable.before_time);
mutex_unlock(&state->af_lock);
CHECK_ERR(err);
- cam_dbg("%s: AF window position completed.\n", __func__);
+ cam_info("AF window position completed.\n");
cam_trace("X\n");
return 0;
@@ -1842,17 +1870,15 @@ static int s5k5ccgx_set_touch_af(struct v4l2_subdev *sd, s32 val)
if (val) {
if (mutex_is_locked(&state->af_lock)) {
- cam_warn("%s: WARNING, AF is busy\n", __func__);
+ cam_warn("%s: AF is still operating!\n", __func__);
return 0;
}
err = queue_work(state->workqueue, &state->af_win_work);
if (likely(!err))
cam_warn("WARNING, AF window is still processing\n");
- } else {
- err = s5k5ccgx_stop_af(sd);
- CHECK_ERR_MSG(err, "val=%d\n", 0)
- }
+ } else
+ cam_info("set_touch_af: invalid value %d\n", val);
cam_trace("X\n");
return 0;
@@ -2005,7 +2031,7 @@ static void s5k5ccgx_set_framesize(struct v4l2_subdev *sd,
static int s5k5ccgx_wait_steamoff(struct v4l2_subdev *sd)
{
struct s5k5ccgx_state *state = to_state(sd);
- struct s5k5ccgx_stream_time *stream_time = &state->stream_time;
+ struct s5k5ccgx_interval *stream_time = &state->stream_time;
s32 elapsed_msec = 0;
cam_trace("E\n");
@@ -2204,6 +2230,8 @@ static inline void s5k5ccgx_get_exif_flash(struct v4l2_subdev *sd,
{
struct s5k5ccgx_state *state = to_state(sd);
+ *flash = 0;
+
switch (state->flash_mode) {
case FLASH_MODE_OFF:
*flash |= EXIF_FLASH_MODE_SUPPRESSION;
@@ -2247,7 +2275,6 @@ static int s5k5ccgx_get_exif(struct v4l2_subdev *sd)
s5k5ccgx_get_exif_iso(sd, &state->exif.iso);
/* flash */
- state->exif.flash = 0;
s5k5ccgx_get_exif_flash(sd, &state->exif.flash);
cam_dbg("EXIF: ex_time_den=%d, iso=%d, flash=0x%02X\n",
diff --git a/drivers/media/video/s5k5ccgx.h b/drivers/media/video/s5k5ccgx.h
index 09657b7..a8ac24c 100644
--- a/drivers/media/video/s5k5ccgx.h
+++ b/drivers/media/video/s5k5ccgx.h
@@ -245,6 +245,15 @@ struct s5k5ccgx_framesize {
#define FRM_RATIO(framesize) \
(((framesize)->width) * 10 / ((framesize)->height))
+struct s5k5ccgx_interval {
+ 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))
+
struct s5k5ccgx_fps {
u32 index;
u32 fps;
@@ -312,6 +321,8 @@ struct s5k5ccgx_gps_info {
};
struct s5k5ccgx_focus {
+ struct s5k5ccgx_interval win_stable;
+
enum v4l2_focusmode mode;
enum af_result_status status;
enum preflash_status preflash;
@@ -323,7 +334,8 @@ struct s5k5ccgx_focus {
u32 ae_lock:1;
u32 awb_lock:1;
u32 touch:1;
- u32 af_cancel:1;
+ u32 reset_done:1;
+ u32 cancel:1;
};
struct s5k5ccgx_exif {
@@ -337,8 +349,8 @@ struct s5k5ccgx_exif {
/* EXIF - flash filed */
#define EXIF_FLASH_FIRED (0x01)
-#define EXIF_FLASH_MODE_FIRING (0x01)
-#define EXIF_FLASH_MODE_SUPPRESSION (0x01 << 1)
+#define EXIF_FLASH_MODE_FIRING (0x01 << 3)
+#define EXIF_FLASH_MODE_SUPPRESSION (0x02 << 3)
#define EXIF_FLASH_MODE_AUTO (0x03 << 3)
struct s5k5ccgx_regset {
@@ -346,15 +358,6 @@ struct s5k5ccgx_regset {
u8 *data;
};
-struct s5k5ccgx_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))
-
#ifdef CONFIG_LOAD_FILE
#define DEBUG_WRITE_REGS
struct s5k5ccgx_regset_table {
@@ -476,7 +479,7 @@ struct s5k5ccgx_state {
#if !defined(FEATURE_YUV_CAPTURE)
struct s5k5ccgx_jpeg_param jpeg;
#endif
- struct s5k5ccgx_stream_time stream_time;
+ struct s5k5ccgx_interval stream_time;
const struct s5k5ccgx_regs *regs;
struct mutex ctrl_lock;
struct mutex af_lock;
@@ -555,9 +558,12 @@ static inline void debug_msleep(struct v4l2_subdev *sd, u32 msecs)
#define FLASH_LOW_LIGHT_LEVEL 0x4A
#endif /* CONFIG_VIDEO_S5K5CCGX_P2 */
-#define FIRST_AF_SEARCH_COUNT 80
-#define SECOND_AF_SEARCH_COUNT 80
-#define AE_STABLE_SEARCH_COUNT 7 /* 4->7. but ae-unstable still occurs. */
+#define FIRST_AF_SEARCH_COUNT 220
+#define SECOND_AF_SEARCH_COUNT 220
+#define AE_STABLE_SEARCH_COUNT 22
+
+#define AF_SEARCH_DELAY 33
+#define AE_STABLE_SEARCH_DELAY 33
/* Sensor AF first,second window size.
* we use constant values intead of reading sensor register */
diff --git a/drivers/media/video/samsung/Makefile b/drivers/media/video/samsung/Makefile
index 301cd9a..639d3bc 100644
--- a/drivers/media/video/samsung/Makefile
+++ b/drivers/media/video/samsung/Makefile
@@ -11,8 +11,27 @@ else
obj-$(CONFIG_VIDEO_FIMG2D3X) += fimg2d3x/
obj-$(CONFIG_VIDEO_FIMG2D4X) += fimg2d4x/
endif
+
+ifeq ($(CONFIG_MACH_U1), y)
+obj-$(CONFIG_VIDEO_UMP) += ump/
+else ifeq ($(CONFIG_MACH_SMDKC210), y)
obj-$(CONFIG_VIDEO_UMP) += ump/
+else ifeq ($(CONFIG_MACH_SMDKV310), y)
+obj-$(CONFIG_VIDEO_UMP) += ump/
+else
+obj-$(CONFIG_VIDEO_UMP) += ump/
+endif
+
obj-$(CONFIG_VIDEO_TSI) += tsi/
+
+ifeq ($(CONFIG_MACH_U1), y)
+obj-$(CONFIG_VIDEO_MALI400MP) += mali/
+else ifeq ($(CONFIG_MACH_SMDKC210), y)
+obj-$(CONFIG_VIDEO_MALI400MP) += mali/
+else ifeq ($(CONFIG_MACH_SMDKV310), y)
obj-$(CONFIG_VIDEO_MALI400MP) += mali/
+else
+obj-$(CONFIG_VIDEO_MALI400MP) += mali/
+endif
EXTRA_CFLAGS += -Idrivers/media/video
diff --git a/drivers/media/video/samsung/fimc/Kconfig b/drivers/media/video/samsung/fimc/Kconfig
index 68f0b14..2fc4c86 100644
--- a/drivers/media/video/samsung/fimc/Kconfig
+++ b/drivers/media/video/samsung/fimc/Kconfig
@@ -6,6 +6,15 @@ config VIDEO_FIMC
help
This is a video4linux driver for Samsung FIMC device.
+config USE_FIMC_CMA
+ bool "Use CMA for FIMC0/1 region (EXPERIMENTAL)"
+ depends on DMA_CMA
+ default n
+ help
+ This enables the Contiguous Memory Allocator for MFC SECURE region.
+
+ If unsure, say "n".
+
choice
depends on VIDEO_FIMC
prompt "Select CSC Range config"
diff --git a/drivers/media/video/samsung/fimc/fimc.h b/drivers/media/video/samsung/fimc/fimc.h
index 9527f52..b648965 100644
--- a/drivers/media/video/samsung/fimc/fimc.h
+++ b/drivers/media/video/samsung/fimc/fimc.h
@@ -25,6 +25,9 @@
#include <media/v4l2-device.h>
#include <media/v4l2-ioctl.h>
#include <media/videobuf-core.h>
+#ifdef CONFIG_SLP_DMABUF
+#include <media/videobuf2-core.h>
+#endif
#include <media/v4l2-mediabus.h>
#if defined(CONFIG_BUSFREQ_OPP) || defined(CONFIG_BUSFREQ_LOCK_WRAPPER)
#include <mach/dev.h>
@@ -42,7 +45,9 @@
#define FIMC_CMA_NAME "fimc"
#define FIMC_CORE_CLK "sclk_fimc"
-#define FIMC_CLK_RATE 166750000
+
+extern int fimc_clk_rate(void);
+
#define EXYNOS_BUSFREQ_NAME "exynos-busfreq"
#if defined(CONFIG_ARCH_EXYNOS4)
@@ -58,7 +63,11 @@
#define FIMC_SUBDEVS 3
#define FIMC_OUTBUFS 3
#define FIMC_INQUEUES 10
+#if defined(CONFIG_SLP)
+#define FIMC_MAX_CTXS 8
+#else
#define FIMC_MAX_CTXS 4
+#endif
#define FIMC_TPID 3
#define FIMC_CAPBUFS 32
#define FIMC_ONESHOT_TIMEOUT 200
@@ -205,12 +214,22 @@ enum cam_mclk_status {
CAM_MCLK_ON,
};
+enum fimc_plane_num {
+ PLANE_1 = 0x1,
+ PLANE_2 = 0x2,
+ PLANE_3 = 0x3,
+ PLANE_4 = 0x4,
+};
+
/*
* STRUCTURES
*/
/* for reserved memory */
struct fimc_meminfo {
+#ifdef CONFIG_USE_FIMC_CMA
+ void *cpu_addr;
+#endif
dma_addr_t base; /* buffer base */
size_t size; /* total length */
dma_addr_t curr; /* current addr */
@@ -263,6 +282,9 @@ struct fimc_capinfo {
/* using c210 */
struct list_head outgoing_q;
int nr_bufs;
+#ifdef CONFIG_SLP_DMABUF
+ int nr_plane;
+#endif
int irq;
int lastirq;
@@ -326,6 +348,9 @@ struct fimc_ctx {
struct fimc_overlay overlay;
u32 buf_num;
+#ifdef CONFIG_SLP_DMABUF
+ int nr_plane;
+#endif
u32 is_requested;
struct fimc_buf_set src[FIMC_OUTBUFS];
struct fimc_buf_set dst[FIMC_OUTBUFS];
@@ -477,6 +502,10 @@ struct fimc_control {
struct timeval before_time;
char cma_name[16];
bool restart;
+#ifdef CONFIG_SLP_DMABUF
+ struct vb2_buffer *out_bufs[VIDEO_MAX_FRAME];
+ struct vb2_buffer *cap_bufs[VIDEO_MAX_FRAME];
+#endif
};
/* global */
@@ -766,5 +795,16 @@ static inline struct fimc_control *get_fimc_ctrl(int id)
{
return &fimc_dev->ctrl[id];
}
+#ifdef CONFIG_SLP_DMABUF
+extern void _fimc_queue_free(struct fimc_control *ctrl,
+ enum v4l2_buf_type type);
+extern int fimc_queue_alloc(struct fimc_control *ctrl, enum v4l2_buf_type type,
+ enum v4l2_memory memory, unsigned int num_buffers,
+ unsigned int num_planes);
+extern int _qbuf_dmabuf(struct fimc_control *ctrl, struct vb2_buffer *vb,
+ struct v4l2_buffer *b);
+extern int _dqbuf_dmabuf(struct fimc_control *ctrl, struct vb2_buffer *vb,
+ struct v4l2_buffer *b);
+#endif
#endif /* __FIMC_H */
diff --git a/drivers/media/video/samsung/fimc/fimc_capture.c b/drivers/media/video/samsung/fimc/fimc_capture.c
index fe0878a..7d00c8b 100644
--- a/drivers/media/video/samsung/fimc/fimc_capture.c
+++ b/drivers/media/video/samsung/fimc/fimc_capture.c
@@ -203,6 +203,9 @@ static const struct v4l2_queryctrl fimc_controls[] = {
.default_value = 0,
},
};
+#ifdef CONFIG_MACH_GC1
+static bool leave_power;
+#endif
#ifndef CONFIG_VIDEO_FIMC_MIPI
void s3c_csis_start(int csis_id, int lanes, int settle, \
@@ -268,7 +271,12 @@ static int fimc_init_camera(struct fimc_control *ctrl)
retry:
/* set rate for mclk */
+#ifndef CONFIG_MACH_GC1
if ((clk_get_rate(cam->clk)) && (fimc->mclk_status == CAM_MCLK_OFF)) {
+#else
+ if ((clk_get_rate(cam->clk)) && (fimc->mclk_status == CAM_MCLK_OFF)
+ && !leave_power) {
+#endif
clk_set_rate(cam->clk, cam->clk_rate);
clk_enable(cam->clk);
fimc->mclk_status = CAM_MCLK_ON;
@@ -277,7 +285,14 @@ retry:
/* enable camera power if needed */
if (cam->cam_power) {
+#ifndef CONFIG_MACH_GC1
ret = cam->cam_power(1);
+#else
+ if (!leave_power)
+ ret = cam->cam_power(1);
+
+ leave_power = false;
+#endif
if (unlikely(ret < 0)) {
fimc_err("\nfail to power on\n");
if (fimc->mclk_status == CAM_MCLK_ON) {
@@ -720,11 +735,19 @@ int fimc_release_subdev(struct fimc_control *ctrl)
client = v4l2_get_subdevdata(ctrl->cam->sd);
i2c_unregister_device(client);
ctrl->cam->sd = NULL;
+#ifndef CONFIG_MACH_GC1
if (ctrl->cam->cam_power)
+#else
+ if (ctrl->cam->cam_power && !leave_power)
+#endif
ctrl->cam->cam_power(0);
/* shutdown the MCLK */
+#ifndef CONFIG_MACH_GC1
if (fimc->mclk_status == CAM_MCLK_ON) {
+#else
+ if (fimc->mclk_status == CAM_MCLK_ON && !leave_power) {
+#endif
clk_disable(ctrl->cam->clk);
fimc->mclk_status = CAM_MCLK_OFF;
}
@@ -801,9 +824,13 @@ static int fimc_configure_subdev(struct fimc_control *ctrl)
ret = fimc_init_camera(ctrl);
if (ret < 0) {
fimc_err("%s: fail to initialize subdev\n", __func__);
+
+#ifndef CONFIG_MACH_GC1
client = v4l2_get_subdevdata(sd);
i2c_unregister_device(client);
ctrl->cam->sd = NULL;
+#endif
+
return ret;
}
}
@@ -1052,9 +1079,6 @@ int fimc_s_input(struct file *file, void *fh, unsigned int i)
}
#else
ctrl->cam = NULL;
-#ifdef CONFIG_MACH_P4NOTE
- fimc_release_subdev(ctrl);
-#endif /* CONFIG_MACH_P4NOTE */
mutex_unlock(&ctrl->v4l2_lock);
fimc_err("%s: Could not register camera" \
" sensor with V4L2.\n", __func__);
@@ -1117,20 +1141,43 @@ int fimc_s_input(struct file *file, void *fh, unsigned int i)
}
ret = v4l2_subdev_call(ctrl->is.sd, core, s_power, 1);
if (ret < 0) {
- fimc_dbg("FIMC-IS init failed");
+ fimc_err("FIMC-IS init s_power failed");
mutex_unlock(&ctrl->v4l2_lock);
return -ENODEV;
}
ret = v4l2_subdev_call(ctrl->is.sd, core, load_fw);
if (ret < 0) {
- fimc_dbg("FIMC-IS init failed");
+ fimc_err("FIMC-IS init load_fw failed");
mutex_unlock(&ctrl->v4l2_lock);
+ if (!cap) {
+ cap = kzalloc(sizeof(*cap), GFP_KERNEL);
+ if (!cap) {
+ fimc_err("%s: no memory for "
+ "capture device info\n", __func__);
+ return -ENOMEM;
+ }
+
+ /* assign to ctrl */
+ ctrl->cap = cap;
+ }
return -ENODEV;
}
ret = v4l2_subdev_call(ctrl->is.sd, core, init, ctrl->cam->sensor_index);
if (ret < 0) {
- fimc_dbg("FIMC-IS init failed");
+ fimc_err("FIMC-IS init failed");
mutex_unlock(&ctrl->v4l2_lock);
+ if (!cap) {
+ cap = kzalloc(sizeof(*cap), GFP_KERNEL);
+ if (!cap) {
+ fimc_err("%s: no memory for "
+ "capture device info\n", __func__);
+ return -ENOMEM;
+ }
+
+ /* assign to ctrl */
+ ctrl->cap = cap;
+ }
+
return -ENODEV;
}
}
@@ -1188,6 +1235,81 @@ int fimc_enum_fmt_vid_capture(struct file *file, void *fh,
return 0;
}
+#ifdef CONFIG_SLP_DMABUF
+/*
+ * figures out the depth of requested format
+ */
+static int fimc_fmt_depth_mplane(struct fimc_control *ctrl,
+ struct v4l2_format *f, int depth[])
+{
+ int ret = 0;
+
+ /* handles only supported pixelformats */
+ switch (f->fmt.pix_mp.pixelformat) {
+ case V4L2_PIX_FMT_NV12:
+ case V4L2_PIX_FMT_NV12T:
+ case V4L2_PIX_FMT_NV21:
+ f->fmt.pix_mp.num_planes = 2;
+ depth[0] = 8;
+ depth[1] = 4;
+ break;
+ case V4L2_PIX_FMT_YUV420:
+ case V4L2_PIX_FMT_YVU420:
+ f->fmt.pix_mp.num_planes = 3;
+ depth[0] = 8;
+ depth[1] = 2;
+ depth[2] = 2;
+ break;
+ case V4L2_PIX_FMT_JPEG:
+ case V4L2_PIX_FMT_INTERLEAVED:
+ f->fmt.pix_mp.num_planes = 1;
+ depth[0] = -1;
+ fimc_dbg("Compressed format.\n");
+ break;
+ default:
+ fimc_dbg("why am I here?\n");
+ ret = -EINVAL;
+ break;
+ }
+
+ return ret;
+}
+static int fimc_g_fmt_vid_capture_mplane(struct fimc_control *ctrl,
+ struct v4l2_format *f)
+{
+ int depth[VIDEO_MAX_PLANES];
+ int ret;
+ int i;
+
+ /*
+ * Note that expecting format only can be with
+ * available output format from FIMC
+ * Following items should be handled in driver
+ * bytesperline = width * depth / 8
+ * sizeimage = bytesperline * height
+ */
+
+ f->fmt.pix_mp.pixelformat = ctrl->cap->fmt.pixelformat;
+ f->fmt.pix_mp.width = ctrl->cap->fmt.width;
+ f->fmt.pix_mp.height = ctrl->cap->fmt.height;
+
+ ret = fimc_fmt_depth_mplane(ctrl, f, depth);
+ if (ret < 0) {
+ fimc_err("Invaild format\n");
+ return ret;
+ }
+ for (i = 0; i < f->fmt.pix_mp.num_planes; ++i) {
+ f->fmt.pix_mp.plane_fmt[i].bytesperline = (f->fmt.pix_mp.width *
+ depth[i]) >> 3;
+ f->fmt.pix_mp.plane_fmt[i].sizeimage =
+ (f->fmt.pix_mp.plane_fmt[i].bytesperline *
+ f->fmt.pix_mp.width);
+ }
+
+ return 0;
+}
+#endif
+
int fimc_g_fmt_vid_capture(struct file *file, void *fh, struct v4l2_format *f)
{
struct fimc_control *ctrl = ((struct fimc_prv_data *)fh)->ctrl;
@@ -1201,8 +1323,20 @@ int fimc_g_fmt_vid_capture(struct file *file, void *fh, struct v4l2_format *f)
mutex_lock(&ctrl->v4l2_lock);
+#ifdef CONFIG_SLP_DMABUF
+ if (V4L2_TYPE_IS_MULTIPLANAR(f->type))
+ if (fimc_g_fmt_vid_capture_mplane(ctrl, f) < 0) {
+ mutex_unlock(&ctrl->v4l2_lock);
+ return -EINVAL;
+ }
+ else {
+ memset(&f->fmt.pix, 0, sizeof(f->fmt.pix));
+ memcpy(&f->fmt.pix, &ctrl->cap->fmt, sizeof(f->fmt.pix));
+ }
+#else
memset(&f->fmt.pix, 0, sizeof(f->fmt.pix));
memcpy(&f->fmt.pix, &ctrl->cap->fmt, sizeof(f->fmt.pix));
+#endif
mutex_unlock(&ctrl->v4l2_lock);
@@ -1308,7 +1442,7 @@ int fimc_s_fmt_vid_private(struct file *file, void *fh, struct v4l2_format *f)
*/
mbus_fmt->field = pix->field;
#endif
-#if (defined(CONFIG_MACH_S2PLUS) || defined(CONFIG_MACH_GC1))
+#if defined(CONFIG_MACH_GC1)
mbus_fmt->field = pix->priv;
#endif
printk(KERN_INFO "%s mbus_fmt->width = %d, height = %d,\n",
@@ -1392,7 +1526,17 @@ int fimc_s_fmt_vid_capture(struct file *file, void *fh, struct v4l2_format *f)
mutex_lock(&ctrl->v4l2_lock);
memset(&cap->fmt, 0, sizeof(cap->fmt));
+#ifdef CONFIG_SLP_DMABUF
+ if (V4L2_TYPE_IS_MULTIPLANAR(f->type)) {
+ cap->fmt.pixelformat = f->fmt.pix_mp.pixelformat;
+ cap->fmt.width = f->fmt.pix_mp.width;
+ cap->fmt.height = f->fmt.pix_mp.height;
+ cap->fmt.pixelformat = f->fmt.pix_mp.pixelformat;
+ } else
+ memcpy(&cap->fmt, &f->fmt.pix, sizeof(cap->fmt));
+#else
memcpy(&cap->fmt, &f->fmt.pix, sizeof(cap->fmt));
+#endif
/*
* Note that expecting format only can be with
@@ -1434,7 +1578,11 @@ int fimc_s_fmt_vid_capture(struct file *file, void *fh, struct v4l2_format *f)
Fimc scaler input Hsize is restricted to 4224 pixels.
So, GC1 has to bypass fimc scaler to use more than 12M YUV.
*/
- ctrl->sc.bypass = 1;
+ if (cap->fmt.width > ctrl->limit->pre_dst_w)
+ ctrl->sc.bypass = 1;
+ else
+ ctrl->sc.bypass = 0;
+
#else
ctrl->sc.bypass = 0;
#endif
@@ -1636,6 +1784,43 @@ static void fimc_free_buffers(struct fimc_control *ctrl)
ctrl->mem.curr = ctrl->mem.base;
}
+#ifdef CONFIG_SLP_DMABUF
+static int fimc_set_cap_num_plane(struct fimc_control *ctrl)
+{
+ struct fimc_capinfo *cap = ctrl->cap;
+
+ switch (cap->fmt.pixelformat) {
+ case V4L2_PIX_FMT_RGB32: /* fall through */
+ case V4L2_PIX_FMT_RGB565: /* fall through */
+ case V4L2_PIX_FMT_YUYV: /* fall through */
+ case V4L2_PIX_FMT_UYVY: /* fall through */
+ case V4L2_PIX_FMT_VYUY: /* fall through */
+ case V4L2_PIX_FMT_YVYU: /* fall through */
+ case V4L2_PIX_FMT_NV16: /* fall through */
+ case V4L2_PIX_FMT_NV61: /* fall through */
+ case V4L2_PIX_FMT_JPEG:
+ case V4L2_PIX_FMT_INTERLEAVED:
+ return PLANE_1;
+
+ case V4L2_PIX_FMT_NV21:
+ case V4L2_PIX_FMT_NV12:
+ case V4L2_PIX_FMT_NV12T:
+ return PLANE_2;
+
+ case V4L2_PIX_FMT_YUV422P: /* fall through */
+ case V4L2_PIX_FMT_YUV420:
+ case V4L2_PIX_FMT_YVU420:
+ return PLANE_3;
+
+ default:
+ fimc_err("%s: Undefined format\n", __func__);
+ break;
+ }
+
+ return 0;
+}
+#endif
+
int fimc_reqbufs_capture_mmap(void *fh, struct v4l2_requestbuffers *b)
{
struct fimc_control *ctrl = fh;
@@ -1825,7 +2010,10 @@ int fimc_reqbufs_capture_userptr(void *fh, struct v4l2_requestbuffers *b)
fimc_streamoff_capture(fh);
fimc_free_buffers(ctrl);
-
+#ifdef CONFIG_SLP_DMABUF
+ if (b->memory == V4L2_MEMORY_DMABUF)
+ _fimc_queue_free(ctrl, V4L2_BUF_TYPE_VIDEO_CAPTURE);
+#endif
mutex_unlock(&ctrl->v4l2_lock);
return 0;
}
@@ -1837,6 +2025,19 @@ int fimc_reqbufs_capture_userptr(void *fh, struct v4l2_requestbuffers *b)
}
cap->nr_bufs = b->count;
+#ifdef CONFIG_SLP_DMABUF
+ if (b->memory == V4L2_MEMORY_DMABUF) {
+ int num_planes;
+
+ num_planes = fimc_set_cap_num_plane(ctrl);
+ if (!num_planes) {
+ mutex_unlock(&ctrl->v4l2_lock);
+ return 0;
+ }
+ fimc_queue_alloc(ctrl, b->type, b->memory,
+ cap->nr_bufs, num_planes);
+ }
+#endif
#if (defined(CONFIG_EXYNOS_DEV_PD) && defined(CONFIG_PM_RUNTIME))
if (ctrl->power_status == FIMC_POWER_OFF) {
@@ -1996,33 +2197,45 @@ int fimc_s_ctrl_capture(void *fh, struct v4l2_control *c)
switch (c->id) {
#ifdef CONFIG_MACH_GC1
- case V4L2_CID_CAM_UPDATE_FW:
- if (fimc->mclk_status == CAM_MCLK_ON) {
- if (ctrl->cam->cam_power)
- ctrl->cam->cam_power(0);
+ case V4L2_CID_CAMERA_HOLD_LENS:
+ leave_power = true;
+ ret = v4l2_subdev_call(ctrl->cam->sd, core, s_ctrl, c);
+ break;
- /* shutdown the MCLK */
- clk_disable(ctrl->cam->clk);
- fimc->mclk_status = CAM_MCLK_OFF;
+ case V4L2_CID_CAM_UPDATE_FW:
+ if (c->value == FW_MODE_UPDATE || c->value == FW_MODE_DUMP) {
+ if (fimc->mclk_status == CAM_MCLK_ON) {
+ if (ctrl->cam->cam_power)
+ ctrl->cam->cam_power(0);
- mdelay(5);
- }
+ /* shutdown the MCLK */
+ clk_disable(ctrl->cam->clk);
+ fimc->mclk_status = CAM_MCLK_OFF;
- if ((clk_get_rate(ctrl->cam->clk)) && (fimc->mclk_status == CAM_MCLK_OFF)) {
- clk_set_rate(ctrl->cam->clk, ctrl->cam->clk_rate);
- clk_enable(ctrl->cam->clk);
- fimc->mclk_status = CAM_MCLK_ON;
- fimc_info1("clock for camera: %d\n", ctrl->cam->clk_rate);
+ mdelay(5);
+ }
- if (ctrl->cam->cam_power)
- ctrl->cam->cam_power(1);
- }
+ if ((clk_get_rate(ctrl->cam->clk)) &&
+ (fimc->mclk_status == CAM_MCLK_OFF)) {
+ clk_set_rate(ctrl->cam->clk,
+ ctrl->cam->clk_rate);
+ clk_enable(ctrl->cam->clk);
+ fimc->mclk_status = CAM_MCLK_ON;
+ fimc_info1("clock for camera: %d\n",
+ ctrl->cam->clk_rate);
+
+ if (ctrl->cam->cam_power)
+ ctrl->cam->cam_power(1);
+ }
- if (c->value == FW_MODE_UPDATE)
- ret = v4l2_subdev_call(ctrl->cam->sd, core, load_fw);
+ if (c->value == FW_MODE_UPDATE)
+ ret = v4l2_subdev_call(ctrl->cam->sd, core, load_fw);
+ else
+ ret = v4l2_subdev_call(ctrl->cam->sd, core, s_ctrl, c);
- else
+ } else {
ret = v4l2_subdev_call(ctrl->cam->sd, core, s_ctrl, c);
+ }
break;
#endif
case V4L2_CID_CAMERA_RESET:
@@ -2206,6 +2419,12 @@ int fimc_s_ctrl_capture(void *fh, struct v4l2_control *c)
break;
#endif
+ case V4L2_CID_CAMERA_SET_DUAL_CAPTURE:
+ case V4L2_CID_CAMERA_DUAL_CAPTURE:
+ case V4L2_CID_CAMERA_DUAL_POSTVIEW:
+ ret = v4l2_subdev_call(ctrl->cam->sd, core, s_ctrl, c);
+ break;
+
case V4L2_CID_IS_CAMERA_FLASH_MODE:
case V4L2_CID_CAMERA_SCENE_MODE:
default:
@@ -2445,6 +2664,9 @@ int fimc_streamon_capture(void *fh)
struct s3c_platform_fimc *pdata = to_fimc_plat(ctrl->dev);
printk(KERN_INFO "%s++ fimc%d\n", __func__, ctrl->id);
+#ifdef CONFIG_SLP
+ cam_frmsize.index = -1;
+#endif
cam_frmsize.discrete.width = 0;
cam_frmsize.discrete.height = 0;
is_ctrl.id = 0;
@@ -2617,7 +2839,7 @@ int fimc_streamon_capture(void *fh)
if (!ctrl->is.sd && cap->movie_mode &&
!((cam->width == 880 && cam->height == 720))) {
printk(KERN_INFO "\n\n\n%s pm_qos_req is called..\n", __func__ );
- dev_lock(ctrl->bus_dev, ctrl->dev, (unsigned long)400200);
+ /*dev_lock(ctrl->bus_dev, ctrl->dev, (unsigned long)400200);*/
pm_qos_add_request(&bus_qos_pm_qos_req, PM_QOS_BUS_QOS, 1);
/* ioremap for register block */
@@ -2746,6 +2968,15 @@ int fimc_streamoff_capture(void *fh)
v4l2_subdev_call(ctrl->cam->sd, video, s_stream, 0);
#endif
+ /* Set FIMD to write back */
+ if ((ctrl->cam->id == CAMERA_WB) || (ctrl->cam->id == CAMERA_WB_B)) {
+ ret = s3cfb_direct_ioctl(0, S3CFB_SET_WRITEBACK, 0);
+ if (ret) {
+ fimc_err("failed set writeback\n");
+ return ret;
+ }
+ }
+
/* wait for stop hardware */
fimc_wait_disable_capture(ctrl);
@@ -2783,7 +3014,7 @@ int fimc_streamoff_capture(void *fh)
!(ctrl->cam->width == 880 && ctrl->cam->height == 720)) {
printk(KERN_INFO "\n\n\n%s pm_qos_req is removed..\n", __func__ );
pm_qos_remove_request(&bus_qos_pm_qos_req);
- dev_unlock(ctrl->bus_dev, ctrl->dev);
+ /*dev_unlock(ctrl->bus_dev, ctrl->dev);*/
/* ioremap for register block */
qos_regs = ioremap(0x11a00400, 0x10);
@@ -2798,14 +3029,6 @@ int fimc_streamoff_capture(void *fh)
iounmap(qos_regs);
}
- /* Set FIMD to write back */
- if ((ctrl->cam->id == CAMERA_WB) || (ctrl->cam->id == CAMERA_WB_B)) {
- ret = s3cfb_direct_ioctl(0, S3CFB_SET_WRITEBACK, 0);
- if (ret) {
- fimc_err("failed set writeback\n");
- return ret;
- }
- }
/* disable camera power */
/* cam power off should call in the subdev release function */
if (fimc_cam_use) {
@@ -2904,7 +3127,7 @@ static void fimc_buf2bs(struct fimc_buf_set *bs, struct fimc_buf *buf)
int fimc_qbuf_capture(void *fh, struct v4l2_buffer *b)
{
struct fimc_control *ctrl = fh;
- struct fimc_buf *buf = (struct fimc_buf *)b->m.userptr;
+ struct fimc_buf *buf;
struct s3c_platform_fimc *pdata = to_fimc_plat(ctrl->dev);
struct fimc_capinfo *cap = ctrl->cap;
int idx = b->index;
@@ -2926,8 +3149,58 @@ int fimc_qbuf_capture(void *fh, struct v4l2_buffer *b)
return -EINVAL;
} else {
if (b->memory == V4L2_MEMORY_USERPTR) {
+ buf = (struct fimc_buf *)b->m.userptr;
fimc_buf2bs(&cap->bufs[idx], buf);
fimc_hwset_output_address(ctrl, &cap->bufs[idx], idx);
+#ifdef CONFIG_SLP_DMABUF
+ } else if (b->memory == V4L2_MEMORY_DMABUF) {
+ struct vb2_buffer *vb;
+ struct sg_table *sg;
+ struct dma_buf_attachment *dba;
+ struct fimc_buf fimc_buf;
+ int ret;
+ unsigned int size;
+
+ vb = ctrl->cap_bufs[b->index];
+
+ ret = _qbuf_dmabuf(ctrl, vb, 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++) {
+ dba = vb->planes[i].mem_priv;
+ sg = dba->priv;
+ if (sg) {
+ fimc_buf.base[i] =
+ sg_dma_address(sg->sgl);
+ fimc_buf.length[i] =
+ sg_dma_len(sg->sgl);
+ } else {
+ fimc_err("%s: Wrong sg value.\n",
+ __func__);
+ mutex_unlock(&ctrl->v4l2_lock);
+ return -ENODEV;
+ }
+ }
+ fimc_buf2bs(&cap->bufs[idx], &fimc_buf);
+ fimc_hwset_output_address(ctrl, &cap->bufs[idx],
+ idx);
+ if (cap->pktdata_enable) {
+ size =
+ fimc_buf.length[vb->num_planes-1];
+ cap->bufs[b->index].vaddr_pktdata =
+ phys_to_virt(
+ cap->bufs[b->index].base
+ [vb->num_planes-1] + size);
+ cap->pktdata_plane = vb->num_planes;
+
+ /* Size of packet data is fixed */
+ cap->pktdata_size = 0x1000;
+ }
+#endif
}
fimc_hwset_output_buf_sequence(ctrl, idx, FIMC_FRAMECNT_SEQ_ENABLE);
@@ -3040,8 +3313,23 @@ int fimc_dqbuf_capture(void *fh, struct v4l2_buffer *b)
b->index = bs->id;
bs->state = VIDEOBUF_IDLE;
- if (b->memory == V4L2_MEMORY_USERPTR)
+ if (b->memory == V4L2_MEMORY_USERPTR) {
fimc_bs2buf(buf, bs);
+#ifdef CONFIG_SLP_DMABUF
+ } else if (b->memory == V4L2_MEMORY_DMABUF) {
+ struct vb2_buffer *vb;
+
+ vb = ctrl->cap_bufs[b->index];
+ ret = _dqbuf_dmabuf(ctrl, vb, b);
+ if (ret < 0) {
+ fimc_err("%s: _qbuf_dmabuf error.\n",
+ __func__);
+ spin_unlock_irqrestore(&ctrl->outq_lock,
+ spin_flags);
+ return -ENODEV;
+ }
+#endif
+ }
list_del(&bs->list);
}
@@ -3123,6 +3411,12 @@ int fimc_enum_framesizes(struct file *filp, void *fh, struct v4l2_frmsizeenum *f
struct fimc_control *ctrl = ((struct fimc_prv_data *)fh)->ctrl;
int i;
u32 index = 0;
+
+#ifdef CONFIG_SLP
+ if (ctrl->cam && ctrl->cam->sd)
+ return v4l2_subdev_call(ctrl->cam->sd, video,
+ enum_framesizes, fsize);
+#endif
for (i = 0; i < ARRAY_SIZE(capture_fmts); i++) {
if (fsize->pixel_format != capture_fmts[i].pixelformat)
continue;
diff --git a/drivers/media/video/samsung/fimc/fimc_capture_u1.c b/drivers/media/video/samsung/fimc/fimc_capture_u1.c
index d21d877..1855abf 100644
--- a/drivers/media/video/samsung/fimc/fimc_capture_u1.c
+++ b/drivers/media/video/samsung/fimc/fimc_capture_u1.c
@@ -454,11 +454,7 @@ int fimc_s_parm(struct file *file, void *fh, struct v4l2_streamparm *a)
return 0;
mutex_lock(&ctrl->v4l2_lock);
-#ifdef CONFIG_MACH_S2PLUS
- if (ctrl->id == FIMC0)
-#else
if (ctrl->id != FIMC2)
-#endif
ret = subdev_call(ctrl, video, s_parm, a);
mutex_unlock(&ctrl->v4l2_lock);
@@ -654,11 +650,7 @@ int fimc_s_input(struct file *file, void *fh, unsigned int i)
if (!fimc->camera_isvalid[i])
return -EINVAL;
-#ifdef CONFIG_MACH_S2PLUS
- if (fimc->camera[i]->sd && ctrl->id == FIMC0) {
-#else
if (fimc->camera[i]->sd && ctrl->id != FIMC2) {
-#endif
fimc_err("%s: Camera already in use.\n", __func__);
return -EBUSY;
}
@@ -685,18 +677,6 @@ int fimc_s_input(struct file *file, void *fh, unsigned int i)
printk(KERN_INFO "fimc_s_input activated subdev = %d\n", i);
}
-#ifdef CONFIG_MACH_S2PLUS
- if (ctrl->id == FIMC1) {
- if (i == fimc->active_camera) {
- ctrl->cam = fimc->camera[i];
- fimc_info2("fimc_s_input activating subdev FIMC1 %d\n",
- ctrl->cam->initialized);
- } else {
- mutex_unlock(&ctrl->v4l2_lock);
- return -EINVAL;
- }
- }
-#else
if (ctrl->id == FIMC2) {
if (i == fimc->active_camera) {
ctrl->cam = fimc->camera[i];
@@ -707,7 +687,6 @@ int fimc_s_input(struct file *file, void *fh, unsigned int i)
return -EINVAL;
}
}
-#endif
/*
* The first time alloc for struct cap_info, and will be
@@ -973,11 +952,7 @@ int fimc_s_fmt_vid_capture(struct file *file, void *fh, struct v4l2_format *f)
memcpy(&cap->fmt, &f->fmt.pix, sizeof(cap->fmt));
mbus_fmt = &cap->mbus_fmt;
-#ifdef CONFIG_MACH_S2PLUS
- if (ctrl->id == FIMC0) {
-#else
if (ctrl->id != FIMC2) {
-#endif
if (cap->movie_mode || cap->vt_mode ||
cap->fmt.priv == V4L2_PIX_FMT_MODE_HDR) {
#if defined(CONFIG_MACH_PX) && defined(CONFIG_VIDEO_HD_SUPPORT)
@@ -1053,11 +1028,7 @@ int fimc_s_fmt_vid_capture(struct file *file, void *fh, struct v4l2_format *f)
return 0;
}
-#ifdef CONFIG_MACH_S2PLUS
- if (ctrl->id == FIMC0)
-#else
if (ctrl->id != FIMC2)
-#endif
ret = subdev_call(ctrl, video, s_mbus_fmt, mbus_fmt);
mutex_unlock(&ctrl->v4l2_lock);
@@ -1637,11 +1608,7 @@ int fimc_s_ctrl_capture(void *fh, struct v4l2_control *c)
if ((ctrl->cam->id == CAMERA_WB) || \
(ctrl->cam->id == CAMERA_WB_B))
break;
-#ifdef CONFIG_MACH_S2PLUS
- if (FIMC0 == ctrl->id)
-#else
if (FIMC2 != ctrl->id)
-#endif
ret = subdev_call(ctrl, core, s_ctrl, c);
else
ret = 0;
@@ -1844,11 +1811,7 @@ int fimc_streamon_capture(void *fh)
cam = ctrl->cam;
if ((ctrl->cam->id != CAMERA_WB) && (ctrl->cam->id != CAMERA_WB_B)) {
-#ifdef CONFIG_MACH_S2PLUS
- if (ctrl->id == FIMC0) {
-#else
if (ctrl->id != FIMC2) {
-#endif
ret = subdev_call(ctrl, video, enum_framesizes, &cam_frmsize);
if (ret < 0) {
dev_err(ctrl->dev, "%s: enum_framesizes failed\n", __func__);
@@ -2067,11 +2030,7 @@ int fimc_streamoff_capture(void *fh)
#if defined(CONFIG_MACH_PX)
#ifdef CONFIG_VIDEO_IMPROVE_STREAMOFF
-#ifdef CONFIG_MACH_S2PLUS
- if ((ctrl->id == FIMC0) && (ctrl->cam->type == CAM_TYPE_MIPI))
-#else
if ((ctrl->id != FIMC2) && (ctrl->cam->type == CAM_TYPE_MIPI))
-#endif
v4l2_subdev_call(ctrl->cam->sd, video, s_stream,
STREAM_MODE_CAM_OFF);
#endif /* CONFIG_VIDEO_IMPROVE_STREAMOFF */
@@ -2090,11 +2049,7 @@ int fimc_streamoff_capture(void *fh)
INIT_LIST_HEAD(&cap->inq);
ctrl->status = FIMC_STREAMOFF;
-#ifdef CONFIG_MACH_S2PLUS
- if (ctrl->id == FIMC0) {
-#else
if (ctrl->id != FIMC2) {
-#endif
if (ctrl->cam->type == CAM_TYPE_MIPI) {
if (ctrl->cam->id == CAMERA_CSI_C)
s3c_csis_stop(CSI_CH_0);
diff --git a/drivers/media/video/samsung/fimc/fimc_dev.c b/drivers/media/video/samsung/fimc/fimc_dev.c
index a0a91cd..1ed79dd 100644
--- a/drivers/media/video/samsung/fimc/fimc_dev.c
+++ b/drivers/media/video/samsung/fimc/fimc_dev.c
@@ -32,9 +32,12 @@
#include <linux/videodev2_exynos_camera.h>
#include <linux/delay.h>
#include <linux/cma.h>
+#include <linux/dma-mapping.h>
#include <plat/fimc.h>
#include <plat/clock.h>
#include <mach/regs-pmu.h>
+#include <linux/cpufreq.h>
+#include <mach/cpufreq.h>
#include "fimc.h"
@@ -711,20 +714,32 @@ static struct fimc_control *fimc_register_controller(struct platform_device *pde
/* In Midas project, FIMC2 reserve memory is used by ION driver. */
if (id != 2) {
#endif
- sprintf(ctrl->cma_name, "%s%d", FIMC_CMA_NAME, ctrl->id);
- err = cma_info(&mem_info, ctrl->dev, 0);
- fimc_info1("%s : [cma_info] start_addr : 0x%x, end_addr : 0x%x, "
- "total_size : 0x%x, free_size : 0x%x\n",
- __func__, mem_info.lower_bound, mem_info.upper_bound,
- mem_info.total_size, mem_info.free_size);
- if (err) {
- fimc_err("%s: get cma info failed\n", __func__);
- ctrl->mem.size = 0;
+#ifdef CONFIG_USE_FIMC_CMA
+ if (id == 1) {
+ ctrl->mem.size =
+ CONFIG_VIDEO_SAMSUNG_MEMSIZE_FIMC1 * SZ_1K;
ctrl->mem.base = 0;
- } else {
- ctrl->mem.size = mem_info.total_size;
- ctrl->mem.base = (dma_addr_t)cma_alloc
- (ctrl->dev, ctrl->cma_name, (size_t)ctrl->mem.size, 0);
+ } else
+#endif
+ {
+ sprintf(ctrl->cma_name, "%s%d",
+ FIMC_CMA_NAME, ctrl->id);
+ err = cma_info(&mem_info, ctrl->dev, 0);
+ fimc_info1("%s : [cma_info] start_addr : 0x%x, "
+ " end_addr : 0x%x, total_size : 0x%x, "
+ "free_size : 0x%x\n", __func__,
+ mem_info.lower_bound, mem_info.upper_bound,
+ mem_info.total_size, mem_info.free_size);
+ if (err) {
+ fimc_err("%s: get cma info failed\n", __func__);
+ ctrl->mem.size = 0;
+ ctrl->mem.base = 0;
+ } else {
+ ctrl->mem.size = mem_info.total_size;
+ ctrl->mem.base = (dma_addr_t)cma_alloc
+ (ctrl->dev, ctrl->cma_name,
+ (size_t)ctrl->mem.size, 0);
+ }
}
#ifdef CONFIG_ION_EXYNOS
}
@@ -813,7 +828,7 @@ static struct fimc_control *fimc_register_controller(struct platform_device *pde
clk_put(fimc_src_clk);
return NULL;
}
- clk_set_rate(sclk_fimc_lclk, FIMC_CLK_RATE);
+ clk_set_rate(sclk_fimc_lclk, fimc_clk_rate());
clk_put(sclk_fimc_lclk);
clk_put(fimc_src_clk);
@@ -1021,6 +1036,255 @@ static int fimc_mmap(struct file *filp, struct vm_area_struct *vma)
return ret;
}
+#ifdef CONFIG_SLP_DMABUF
+/**
+ * _fimc_dmabuf_put() - release memory associated with
+ * a DMABUF shared buffer
+ */
+static void _fimc_dmabuf_put(struct vb2_buffer *vb)
+{
+ unsigned int plane;
+
+ for (plane = 0; plane < vb->num_planes; ++plane) {
+ void *mem_priv = vb->planes[plane].mem_priv;
+
+ if (mem_priv) {
+ dma_buf_detach(vb->planes[plane].dbuf,
+ vb->planes[plane].mem_priv);
+ dma_buf_put(vb->planes[plane].dbuf);
+ vb->planes[plane].dbuf = NULL;
+ vb->planes[plane].mem_priv = NULL;
+ }
+ }
+}
+
+void _fimc_queue_free(struct fimc_control *ctrl, enum v4l2_buf_type type)
+{
+ unsigned int buffer;
+ struct vb2_buffer *vb;
+
+ for (buffer = 0; buffer < VIDEO_MAX_FRAME; ++buffer) {
+ if (V4L2_TYPE_IS_OUTPUT(type))
+ vb = ctrl->out_bufs[buffer];
+ else
+ vb = ctrl->cap_bufs[buffer];
+
+ if (!vb)
+ continue;
+ _fimc_dmabuf_put(vb);
+ kfree(vb);
+ vb = NULL;
+ }
+}
+
+int fimc_queue_alloc(struct fimc_control *ctrl, enum v4l2_buf_type type,
+ enum v4l2_memory memory, unsigned int num_buffers,
+ unsigned int num_planes)
+{
+ unsigned int buffer;
+ struct vb2_buffer *vb;
+
+ for (buffer = 0; buffer < num_buffers; ++buffer) {
+ vb = kzalloc(sizeof(struct vb2_buffer), GFP_KERNEL);
+ if (!vb) {
+ fimc_err("%s: Memory alloc for buffer struct failed\n",
+ __func__);
+ break;
+ }
+
+ if (V4L2_TYPE_IS_MULTIPLANAR(type))
+ vb->v4l2_buf.length = num_planes;
+
+ vb->num_planes = num_planes;
+ vb->v4l2_buf.index = buffer;
+ vb->v4l2_buf.type = type;
+ vb->v4l2_buf.memory = memory;
+
+ if (V4L2_TYPE_IS_OUTPUT(type))
+ ctrl->out_bufs[buffer] = vb;
+ else
+ ctrl->cap_bufs[buffer] = vb;
+ }
+
+ for (buffer = num_buffers; buffer < VIDEO_MAX_FRAME; ++buffer) {
+ ctrl->out_bufs[buffer] = NULL;
+ ctrl->cap_bufs[buffer] = NULL;
+ }
+
+ return buffer;
+}
+
+static inline int _verify_planes_array(struct vb2_buffer *vb,
+ const struct v4l2_buffer *b)
+{
+ if (NULL == b->m.planes) {
+ printk(KERN_ERR "%s: Multi-planar buffer passwd but planes"
+ " array not provided\n", __func__);
+ return -EINVAL;
+ }
+ if (b->length < vb->num_planes || b->length > VIDEO_MAX_PLANES) {
+ printk(KERN_ERR "%s: Incorrect planes array length, "
+ "expected %d, got %d\n", __func__,
+ vb->num_planes, b->length);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int _fill_v4l2_buffer(struct vb2_buffer *vb, struct v4l2_buffer *b,
+ struct v4l2_plane *v4l2_planes)
+{
+ int plane;
+ int ret;
+
+ memcpy(b, &vb->v4l2_buf, offsetof(struct v4l2_buffer, m));
+ b->input = vb->v4l2_buf.input;
+ b->reserved = vb->v4l2_buf.reserved;
+
+ if (V4L2_TYPE_IS_MULTIPLANAR(b->type)) {
+ ret = _verify_planes_array(vb, b);
+ if (ret)
+ return ret;
+
+ memcpy(b->m.planes, vb->v4l2_planes,
+ b->length * sizeof(struct v4l2_plane));
+
+ for (plane = 0; plane < vb->num_planes; ++plane)
+ b->m.planes[plane].m.fd =
+ vb->v4l2_planes[plane].m.fd;
+ } else {
+ b->length = vb->v4l2_planes[0].length;
+ b->bytesused = vb->v4l2_planes[0].bytesused;
+ b->m.fd = vb->v4l2_planes[0].m.fd;
+ }
+
+ return ret;
+}
+
+static int _fill_vb2_buffer(struct vb2_buffer *vb, struct v4l2_buffer *b,
+ struct v4l2_plane *v4l2_planes)
+{
+ unsigned int plane;
+ int ret;
+
+ if (V4L2_TYPE_IS_MULTIPLANAR(b->type)) {
+ ret = _verify_planes_array(vb, b);
+ if (ret)
+ return ret;
+
+ if (V4L2_TYPE_IS_OUTPUT(b->type)) {
+ for (plane = 0; plane < vb->num_planes; ++plane) {
+ v4l2_planes[plane].bytesused =
+ b->m.planes[plane].bytesused;
+ v4l2_planes[plane].data_offset =
+ b->m.planes[plane].data_offset;
+ }
+ }
+ for (plane = 0; plane < vb->num_planes; ++plane)
+ v4l2_planes[plane].m.fd =
+ b->m.planes[plane].m.fd;
+
+ } else {
+ if (V4L2_TYPE_IS_OUTPUT(b->type))
+ v4l2_planes[0].bytesused =
+ b->bytesused;
+ v4l2_planes[0].m.fd = b->m.fd;
+ }
+
+ vb->v4l2_buf.field = b->field;
+ vb->v4l2_buf.timestamp = b->timestamp;
+ vb->v4l2_buf.input = b->input;
+
+ return 0;
+}
+
+int _qbuf_dmabuf(struct fimc_control *ctrl, struct vb2_buffer *vb,
+ struct v4l2_buffer *b)
+{
+ struct v4l2_plane planes[VIDEO_MAX_PLANES];
+ unsigned int plane;
+ struct sg_table *sg;
+ struct dma_buf_attachment *dba;
+ int ret;
+
+ ret = _fill_vb2_buffer(vb, b, planes);
+ if (ret)
+ return ret;
+
+ for (plane = 0; plane < vb->num_planes; ++plane) {
+ struct dma_buf *dbuf = dma_buf_get(planes[plane].m.fd);
+
+ if (IS_ERR_OR_NULL(dbuf)) {
+ fimc_err("dmabuf get error!!! %x\n", plane);
+ ret = PTR_ERR(dbuf);
+ goto err;
+ }
+ planes[plane].length = dbuf->size;
+
+ /* Skip the plane if already verified */
+ if (dbuf == vb->planes[plane].dbuf) {
+ dma_buf_put(dbuf);
+ continue;
+ }
+
+ vb->planes[plane].mem_priv = NULL;
+
+ dba = dma_buf_attach(dbuf, ctrl->dev);
+ if (IS_ERR(dba)) {
+ fimc_err("failed to attach dmabuf\n");
+ dma_buf_put(dbuf);
+ ret = PTR_ERR(dba);
+ goto err;
+ }
+
+ sg = dma_buf_map_attachment(dba, DMA_BIDIRECTIONAL);
+ if (IS_ERR(sg)) {
+ fimc_err("qbuf: failed acquiring dmabuf "
+ "memory for plane\n");
+ ret = PTR_ERR(sg);
+ goto err;
+ }
+ dba->priv = sg;
+
+ vb->planes[plane].dbuf = dbuf;
+ vb->planes[plane].mem_priv = dba;
+
+ vb->v4l2_planes[plane] = planes[plane];
+ }
+
+ return 0;
+
+err:
+ _fimc_dmabuf_put(vb);
+
+ return ret;
+}
+
+int _dqbuf_dmabuf(struct fimc_control *ctrl, struct vb2_buffer *vb,
+ struct v4l2_buffer *b)
+{
+ struct v4l2_plane planes[VIDEO_MAX_PLANES];
+ struct sg_table *sg[VIDEO_MAX_PLANES];
+ struct dma_buf_attachment *dba[VIDEO_MAX_PLANES];
+ unsigned int plane;
+ int ret;
+
+ ret = _fill_v4l2_buffer(vb, b, planes);
+ if (ret)
+ return ret;
+
+ for (plane = 0; plane < vb->num_planes; ++plane) {
+ dba[plane] = vb->planes[plane].mem_priv;
+ sg[plane] = dba[plane]->priv;
+ dma_buf_unmap_attachment(dba[plane],
+ sg[plane], DMA_FROM_DEVICE);
+ }
+
+ return 0;
+}
+#endif
+
static u32 fimc_poll(struct file *filp, poll_table *wait)
{
struct fimc_prv_data *prv_data =
@@ -1226,6 +1490,19 @@ static int fimc_open(struct file *filp)
goto kzalloc_err;
}
+#ifdef CONFIG_USE_FIMC_CMA
+ if (ctrl->id == 1) {
+ ctrl->mem.cpu_addr = dma_alloc_coherent(ctrl->dev,
+ ctrl->mem.size, &(ctrl->mem.base), 0);
+ if (!ctrl->mem.cpu_addr) {
+ printk(KERN_INFO "FIMC%d: dma_alloc_coherent failed\n",
+ ctrl->id);
+ ret = -ENOMEM;
+ goto dma_alloc_err;
+ }
+ }
+#endif
+
if (in_use == 1) {
#if (!defined(CONFIG_EXYNOS_DEV_PD) || !defined(CONFIG_PM_RUNTIME))
if (pdata->clk_on)
@@ -1276,6 +1553,11 @@ static int fimc_open(struct file *filp)
return 0;
+#ifdef CONFIG_USE_FIMC_CMA
+dma_alloc_err:
+ kfree(prv_data);
+#endif
+
kzalloc_err:
atomic_dec(&ctrl->in_use);
@@ -1425,6 +1707,9 @@ static int fimc_release(struct file *filp)
} else {
ctrl->out->ctx_used[ctx_id] = false;
}
+#ifdef CONFIG_SLP_DMABUF
+ _fimc_queue_free(ctrl, V4L2_BUF_TYPE_VIDEO_OUTPUT);
+#endif
}
if (ctrl->cap) {
@@ -1445,6 +1730,9 @@ static int fimc_release(struct file *filp)
}
kfree(ctrl->cap);
ctrl->cap = NULL;
+#ifdef CONFIG_SLP_DMABUF
+ _fimc_queue_free(ctrl, V4L2_BUF_TYPE_VIDEO_CAPTURE);
+#endif
}
/*
@@ -1462,6 +1750,14 @@ static int fimc_release(struct file *filp)
ctrl->fb.is_enable = 0;
}
+#ifdef CONFIG_USE_FIMC_CMA
+ if (ctrl->id == 1) {
+ dma_free_coherent(ctrl->dev, ctrl->mem.size, ctrl->mem.cpu_addr,
+ ctrl->mem.base);
+ ctrl->mem.base = 0;
+ ctrl->mem.cpu_addr = NULL;
+ }
+#endif
fimc_warn("FIMC%d %d released.\n",
ctrl->id, atomic_read(&ctrl->in_use));
@@ -1840,7 +2136,7 @@ static int __devinit fimc_probe(struct platform_device *pdev)
ret = device_create_file(&(pdev->dev), &dev_attr_range_mode);
if (ret < 0) {
fimc_err("failed to add sysfs entries for range mode\n");
- goto err_global;
+ goto err_create_file;
}
printk(KERN_INFO "FIMC%d registered successfully\n", ctrl->id);
#if (defined(CONFIG_EXYNOS_DEV_PD) && defined(CONFIG_PM_RUNTIME))
@@ -1848,7 +2144,7 @@ static int __devinit fimc_probe(struct platform_device *pdev)
ctrl->fimc_irq_wq = create_workqueue(buf);
if (ctrl->fimc_irq_wq == NULL) {
fimc_err("failed to create_workqueue\n");
- goto err_global;
+ goto err_wq;
}
INIT_WORK(&ctrl->work_struct, s3c_fimc_irq_work);
@@ -1869,6 +2165,12 @@ static int __devinit fimc_probe(struct platform_device *pdev)
return 0;
+err_wq:
+ device_remove_file(&(pdev->dev), &dev_attr_range_mode);
+
+err_create_file:
+ device_remove_file(&(pdev->dev), &dev_attr_log_level);
+
err_global:
video_unregister_device(ctrl->vd);
diff --git a/drivers/media/video/samsung/fimc/fimc_dev_u1.c b/drivers/media/video/samsung/fimc/fimc_dev_u1.c
index f36db5d..762256b 100644
--- a/drivers/media/video/samsung/fimc/fimc_dev_u1.c
+++ b/drivers/media/video/samsung/fimc/fimc_dev_u1.c
@@ -682,7 +682,7 @@ struct fimc_control *fimc_register_controller(struct platform_device *pdev)
clk_put(fimc_src_clk);
return NULL;
}
- clk_set_rate(sclk_fimc_lclk, FIMC_CLK_RATE);
+ clk_set_rate(sclk_fimc_lclk, fimc_clk_rate());
clk_put(sclk_fimc_lclk);
clk_put(fimc_src_clk);
@@ -1419,6 +1419,30 @@ static int fimc_init_global(struct platform_device *pdev)
return 0;
}
+#ifdef CONFIG_DRM_EXYNOS_FIMD_WB
+static BLOCKING_NOTIFIER_HEAD(fimc_notifier_client_list);
+
+int fimc_register_client(struct notifier_block *nb)
+{
+ return blocking_notifier_chain_register(
+ &fimc_notifier_client_list, nb);
+}
+EXPORT_SYMBOL(fimc_register_client);
+
+int fimc_unregister_client(struct notifier_block *nb)
+{
+ return blocking_notifier_chain_unregister(
+ &fimc_notifier_client_list, nb);
+}
+EXPORT_SYMBOL(fimc_unregister_client);
+
+int fimc_send_event(unsigned long val, void *v)
+{
+ return blocking_notifier_call_chain(
+ &fimc_notifier_client_list, val, v);
+}
+#endif
+
static int fimc_show_log_level(struct device *dev,
struct device_attribute *attr, char *buf)
{
diff --git a/drivers/media/video/samsung/fimc/fimc_output.c b/drivers/media/video/samsung/fimc/fimc_output.c
index 895cb7f..57611e5 100644
--- a/drivers/media/video/samsung/fimc/fimc_output.c
+++ b/drivers/media/video/samsung/fimc/fimc_output.c
@@ -25,6 +25,9 @@
#include <plat/media.h>
#include <linux/clk.h>
#include <linux/delay.h>
+#ifdef CONFIG_SLP_DMABUF
+#include <linux/dma-buf.h>
+#endif
#include "fimc.h"
#include "fimc-ipc.h"
@@ -287,6 +290,33 @@ static void fimc_init_out_buf(struct fimc_ctx *ctx)
}
}
+#ifdef CONFIG_SLP_DMABUF
+static int fimc_set_out_num_plane(struct fimc_control *ctrl,
+ struct fimc_ctx *ctx)
+{
+ u32 format = ctx->pix.pixelformat;
+
+ switch (format) {
+ case V4L2_PIX_FMT_RGB32:
+ case V4L2_PIX_FMT_RGB565: /* fall through */
+ case V4L2_PIX_FMT_UYVY: /* fall through */
+ case V4L2_PIX_FMT_YUYV:
+ return PLANE_1;
+ case V4L2_PIX_FMT_NV12: /* fall through */
+ case V4L2_PIX_FMT_NV21: /* fall through */
+ case V4L2_PIX_FMT_NV12T:
+ return PLANE_2;
+ case V4L2_PIX_FMT_YUV420: /* fall through */
+ return PLANE_3;
+ default:
+ fimc_err("%s: Invalid pixelformt : %d\n", __func__, format);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+#endif
+
static int fimc_outdev_set_src_buf(struct fimc_control *ctrl,
struct fimc_ctx *ctx)
{
@@ -1690,6 +1720,10 @@ int fimc_reqbufs_output(void *fh, struct v4l2_requestbuffers *b)
default:
break;
}
+#ifdef CONFIG_SLP_DMABUF
+ if (b->memory == V4L2_MEMORY_DMABUF)
+ _fimc_queue_free(ctrl, V4L2_BUF_TYPE_VIDEO_OUTPUT);
+#endif
} else {
/* initialize source buffers */
if (b->memory == V4L2_MEMORY_MMAP) {
@@ -1701,6 +1735,14 @@ int fimc_reqbufs_output(void *fh, struct v4l2_requestbuffers *b)
if (mode == FIMC_OVLY_DMA_AUTO ||
mode == FIMC_OVLY_NOT_FIXED)
ctx->overlay.req_idx = FIMC_USERPTR_IDX;
+#ifdef CONFIG_SLP_DMABUF
+ } else if (b->memory == V4L2_MEMORY_DMABUF) {
+ int num_planes;
+
+ num_planes = fimc_set_out_num_plane(ctrl, ctx);
+ fimc_queue_alloc(ctrl, b->type, b->memory, b->count,
+ num_planes);
+#endif
}
ctx->is_requested = 1;
@@ -2365,6 +2407,7 @@ static int fimc_outdev_start_operation(struct fimc_control *ctrl,
ret = fimc_outdev_start_camif(ctrl);
if (ret < 0) {
fimc_err("Fail: fimc_start_camif\n");
+ spin_unlock_irqrestore(&ctrl->out->slock, spin_flags);
return -EINVAL;
}
@@ -2399,6 +2442,7 @@ static int fimc_qbuf_output_single_buf(struct fimc_control *ctrl,
case V4L2_PIX_FMT_RGB32:
case V4L2_PIX_FMT_RGB565:
case V4L2_PIX_FMT_YUYV:
+ case V4L2_PIX_FMT_UYVY:
buf_set.base[FIMC_ADDR_Y] = (dma_addr_t)ctx->fbuf.base;
break;
case V4L2_PIX_FMT_YUV420:
@@ -2465,9 +2509,11 @@ static int fimc_qbuf_output_multi_buf(struct fimc_control *ctrl,
case V4L2_PIX_FMT_RGB32:
case V4L2_PIX_FMT_RGB565:
case V4L2_PIX_FMT_YUYV:
+ case V4L2_PIX_FMT_UYVY:
buf_set.base[FIMC_ADDR_Y] = ctx->dst[idx].base[FIMC_ADDR_Y];
break;
case V4L2_PIX_FMT_YUV420:
+ case V4L2_PIX_FMT_YVU420: /* fall through */
buf_set.base[FIMC_ADDR_Y] = ctx->dst[idx].base[FIMC_ADDR_Y];
buf_set.base[FIMC_ADDR_CB] = ctx->dst[idx].base[FIMC_ADDR_CB];
buf_set.base[FIMC_ADDR_CR] = ctx->dst[idx].base[FIMC_ADDR_CR];
@@ -2680,7 +2726,7 @@ static int fimc_update_in_queue_addr(struct fimc_control *ctrl,
int fimc_qbuf_output(void *fh, struct v4l2_buffer *b)
{
- struct fimc_buf *buf = (struct fimc_buf *)b->m.userptr;
+ struct fimc_buf *buf;
struct fimc_ctx *ctx;
struct fimc_control *ctrl = ((struct fimc_prv_data *)fh)->ctrl;
int ctx_id = ((struct fimc_prv_data *)fh)->ctx_id;
@@ -2716,9 +2762,40 @@ int fimc_qbuf_output(void *fh, struct v4l2_buffer *b)
(ctrl->status == FIMC_STREAMON) ||
(ctrl->status == FIMC_STREAMON_IDLE)) {
if (b->memory == V4L2_MEMORY_USERPTR) {
+ buf = (struct fimc_buf *)b->m.userptr;
ret = fimc_update_in_queue_addr(ctrl, ctx, b->index, buf->base);
if (ret < 0)
return ret;
+#ifdef CONFIG_SLP_DMABUF
+ } else if (b->memory == V4L2_MEMORY_DMABUF) {
+ struct vb2_buffer *vb;
+ dma_addr_t addr[3];
+ struct sg_table *sg;
+ struct dma_buf_attachment *dba;
+ int i;
+
+ vb = ctrl->out_bufs[b->index];
+ ret = _qbuf_dmabuf(ctrl, vb, b);
+ if (ret < 0) {
+ fimc_err("_qbuf_dmabuf failed ret = %d\n", ret);
+ return ret;
+ }
+ for (i = 0; i < vb->num_planes; i++) {
+ dba = vb->planes[i].mem_priv;
+ sg = dba->priv;
+ if (sg)
+ addr[i] = sg_dma_address(sg->sgl);
+ else {
+ fimc_err("%s: Wrong sg value.\n",
+ __func__);
+ return -ENODEV;
+ }
+ }
+ ret = fimc_update_in_queue_addr(ctrl, ctx, b->index,
+ addr);
+ if (ret < 0)
+ return ret;
+#endif
}
#if defined(CONFIG_EXYNOS_DEV_PD) && defined(CONFIG_PM_RUNTIME)
@@ -2831,6 +2908,7 @@ int fimc_dqbuf_output(void *fh, struct v4l2_buffer *b)
int idx = -1, ret = -1;
ctx = &ctrl->out->ctx[ctx_id];
+
ret = fimc_pop_outq(ctrl, ctx, &idx);
if (ret < 0) {
ret = wait_event_timeout(ctrl->wq, (ctx->outq[0] != -1),
@@ -2838,7 +2916,6 @@ int fimc_dqbuf_output(void *fh, struct v4l2_buffer *b)
if (ret == 0) {
fimc_dump_context(ctrl, ctx);
fimc_recover_output(ctrl, ctx);
- pm_runtime_put_sync(ctrl->dev);
fimc_err("[0] out_queue is empty\n");
return -EAGAIN;
} else if (ret == -ERESTARTSYS) {
@@ -2854,7 +2931,18 @@ int fimc_dqbuf_output(void *fh, struct v4l2_buffer *b)
}
}
}
+#ifdef CONFIG_SLP_DMABUF
+ if (b->memory == V4L2_MEMORY_DMABUF) {
+ struct vb2_buffer *vb;
+ vb = ctrl->out_bufs[idx];
+ ret = _dqbuf_dmabuf(ctrl, vb, b);
+ if (ret < 0) {
+ fimc_err("%s: _qbuf_dmabuf error.\n", __func__);
+ return -ENODEV;
+ }
+ }
+#endif
b->index = idx;
fimc_info2("ctx(%d) dqueued idx = %d\n", ctx->ctx_num, b->index);
diff --git a/drivers/media/video/samsung/fimc/fimc_regs.c b/drivers/media/video/samsung/fimc/fimc_regs.c
index 332e5db..20888c7 100644
--- a/drivers/media/video/samsung/fimc/fimc_regs.c
+++ b/drivers/media/video/samsung/fimc/fimc_regs.c
@@ -258,6 +258,9 @@ static void fimc_reset_cfg(struct fimc_control *ctrl)
{
int i;
u32 cfg[][2] = {
+#ifdef CONFIG_SLP
+ { 0x008, 0x20010480 },
+#endif
{ 0x018, 0x00000000 }, { 0x01c, 0x00000000 },
{ 0x020, 0x00000000 }, { 0x024, 0x00000000 },
{ 0x028, 0x00000000 }, { 0x02c, 0x00000000 },
@@ -1253,7 +1256,11 @@ int fimc_hwset_disable_capture(struct fimc_control *ctrl)
void fimc_wait_disable_capture(struct fimc_control *ctrl)
{
+#ifdef CONFIG_VIDEO_S5K5BBGX
+ unsigned long timeo = jiffies + 60; /* more 40 ms */
+#else
unsigned long timeo = jiffies + 40; /* timeout of 200 ms */
+#endif
u32 cfg;
if (!ctrl || !ctrl->cap)
return;
diff --git a/drivers/media/video/samsung/fimc/fimc_v4l2.c b/drivers/media/video/samsung/fimc/fimc_v4l2.c
index 510e2f1..becd16c 100644
--- a/drivers/media/video/samsung/fimc/fimc_v4l2.c
+++ b/drivers/media/video/samsung/fimc/fimc_v4l2.c
@@ -35,8 +35,15 @@ static int fimc_querycap(struct file *filp, void *fh,
sprintf(cap->bus_info, "FIMC AHB-bus");
cap->version = 0;
+#ifdef CONFIG_SLP_DMABUF
+ cap->capabilities = (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_OUTPUT |
+ V4L2_CAP_VIDEO_OVERLAY | V4L2_CAP_STREAMING |
+ V4L2_CAP_VIDEO_OUTPUT_MPLANE |
+ V4L2_CAP_VIDEO_CAPTURE_MPLANE);
+#else
cap->capabilities = (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_OUTPUT |
V4L2_CAP_VIDEO_OVERLAY | V4L2_CAP_STREAMING);
+#endif
return 0;
}
@@ -47,6 +54,18 @@ static int fimc_reqbufs(struct file *filp, void *fh,
struct fimc_control *ctrl = ((struct fimc_prv_data *)fh)->ctrl;
int ret = -1;
+#ifdef CONFIG_SLP_DMABUF
+ if (V4L2_TYPE_IS_OUTPUT(b->type)) {
+ ret = fimc_reqbufs_output(fh, b);
+ } else if (b->type == V4L2_BUF_TYPE_VIDEO_CAPTURE
+ || b->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
+ ret = fimc_reqbufs_capture(ctrl, b);
+ } else {
+ fimc_err("V4L2_BUF_TYPE_VIDEO_CAPTURE and "
+ "V4L2_BUF_TYPE_VIDEO_OUTPUT are only supported\n");
+ ret = -EINVAL;
+ }
+#else
if (b->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
ret = fimc_reqbufs_capture(ctrl, b);
} else if (b->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
@@ -56,6 +75,7 @@ static int fimc_reqbufs(struct file *filp, void *fh,
"V4L2_BUF_TYPE_VIDEO_OUTPUT are only supported\n");
ret = -EINVAL;
}
+#endif
return ret;
}
@@ -65,6 +85,18 @@ static int fimc_querybuf(struct file *filp, void *fh, struct v4l2_buffer *b)
struct fimc_control *ctrl = ((struct fimc_prv_data *)fh)->ctrl;
int ret = -1;
+#ifdef CONFIG_SLP_DMABUF
+ if (V4L2_TYPE_IS_OUTPUT(b->type)) {
+ ret = fimc_querybuf_output(fh, b);
+ } else if (b->type == V4L2_BUF_TYPE_VIDEO_CAPTURE
+ || b->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
+ ret = fimc_querybuf_capture(ctrl, b);
+ } else {
+ fimc_err("V4L2_BUF_TYPE_VIDEO_CAPTURE and "
+ "V4L2_BUF_TYPE_VIDEO_OUTPUT are only supported\n");
+ ret = -EINVAL;
+ }
+#else
if (b->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
ret = fimc_querybuf_capture(ctrl, b);
} else if (b->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
@@ -74,6 +106,7 @@ static int fimc_querybuf(struct file *filp, void *fh, struct v4l2_buffer *b)
"V4L2_BUF_TYPE_VIDEO_OUTPUT are only supported\n");
ret = -EINVAL;
}
+#endif
return ret;
}
@@ -148,6 +181,18 @@ static int fimc_cropcap(struct file *filp, void *fh, struct v4l2_cropcap *a)
struct fimc_control *ctrl = ((struct fimc_prv_data *)fh)->ctrl;
int ret = -1;
+#ifdef CONFIG_SLP_DMABUF
+ if (V4L2_TYPE_IS_OUTPUT(a->type)) {
+ ret = fimc_cropcap_output(fh, a);
+ } else if (a->type == V4L2_BUF_TYPE_VIDEO_CAPTURE
+ || a->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
+ ret = fimc_cropcap_capture(ctrl, a);
+ } else {
+ fimc_err("V4L2_BUF_TYPE_VIDEO_CAPTURE and "
+ "V4L2_BUF_TYPE_VIDEO_OUTPUT are only supported\n");
+ ret = -EINVAL;
+ }
+#else
if (a->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
ret = fimc_cropcap_capture(ctrl, a);
} else if (a->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
@@ -157,6 +202,7 @@ static int fimc_cropcap(struct file *filp, void *fh, struct v4l2_cropcap *a)
"V4L2_BUF_TYPE_VIDEO_OUTPUT are only supported\n");
ret = -EINVAL;
}
+#endif
return ret;
}
@@ -166,6 +212,18 @@ static int fimc_g_crop(struct file *filp, void *fh, struct v4l2_crop *a)
struct fimc_control *ctrl = ((struct fimc_prv_data *)fh)->ctrl;
int ret = -1;
+#ifdef CONFIG_SLP_DMABUF
+ if (V4L2_TYPE_IS_OUTPUT(a->type)) {
+ ret = fimc_g_crop_output(fh, a);
+ } else if (a->type == V4L2_BUF_TYPE_VIDEO_CAPTURE
+ || a->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
+ ret = fimc_g_crop_capture(ctrl, a);
+ } else {
+ fimc_err("V4L2_BUF_TYPE_VIDEO_CAPTURE and "
+ "V4L2_BUF_TYPE_VIDEO_OUTPUT are only supported\n");
+ ret = -EINVAL;
+ }
+#else
if (a->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
ret = fimc_g_crop_capture(ctrl, a);
} else if (a->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
@@ -175,6 +233,7 @@ static int fimc_g_crop(struct file *filp, void *fh, struct v4l2_crop *a)
"V4L2_BUF_TYPE_VIDEO_OUTPUT are only supported\n");
ret = -EINVAL;
}
+#endif
return ret;
}
@@ -184,6 +243,18 @@ static int fimc_s_crop(struct file *filp, void *fh, struct v4l2_crop *a)
struct fimc_control *ctrl = ((struct fimc_prv_data *)fh)->ctrl;
int ret = -1;
+#ifdef CONFIG_SLP_DMABUF
+ if (V4L2_TYPE_IS_OUTPUT(a->type)) {
+ ret = fimc_s_crop_output(fh, a);
+ } else if (a->type == V4L2_BUF_TYPE_VIDEO_CAPTURE
+ || a->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
+ ret = fimc_s_crop_capture(ctrl, a);
+ } else {
+ fimc_err("V4L2_BUF_TYPE_VIDEO_CAPTURE and "
+ "V4L2_BUF_TYPE_VIDEO_OUTPUT are only supported\n");
+ ret = -EINVAL;
+ }
+#else
if (a->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
ret = fimc_s_crop_capture(ctrl, a);
} else if (a->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
@@ -193,6 +264,7 @@ static int fimc_s_crop(struct file *filp, void *fh, struct v4l2_crop *a)
"V4L2_BUF_TYPE_VIDEO_OUTPUT are only supported\n");
ret = -EINVAL;
}
+#endif
return ret;
}
@@ -202,6 +274,18 @@ static int fimc_streamon(struct file *filp, void *fh, enum v4l2_buf_type i)
struct fimc_control *ctrl = ((struct fimc_prv_data *)fh)->ctrl;
int ret = -1;
+#ifdef CONFIG_SLP_DMABUF
+ if (V4L2_TYPE_IS_OUTPUT(i)) {
+ ret = fimc_streamon_output(fh);
+ } else if (i == V4L2_BUF_TYPE_VIDEO_CAPTURE
+ || i == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
+ ret = fimc_streamon_capture(ctrl);
+ } else {
+ fimc_err("V4L2_BUF_TYPE_VIDEO_CAPTURE and "
+ "V4L2_BUF_TYPE_VIDEO_OUTPUT are only supported\n");
+ ret = -EINVAL;
+ }
+#else
if (i == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
ret = fimc_streamon_capture(ctrl);
} else if (i == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
@@ -211,6 +295,7 @@ static int fimc_streamon(struct file *filp, void *fh, enum v4l2_buf_type i)
"V4L2_BUF_TYPE_VIDEO_OUTPUT are only supported\n");
ret = -EINVAL;
}
+#endif
return ret;
}
@@ -220,6 +305,18 @@ static int fimc_streamoff(struct file *filp, void *fh, enum v4l2_buf_type i)
struct fimc_control *ctrl = ((struct fimc_prv_data *)fh)->ctrl;
int ret = -1;
+#ifdef CONFIG_SLP_DMABUF
+ if (V4L2_TYPE_IS_OUTPUT(i)) {
+ ret = fimc_streamoff_output(fh);
+ } else if (i == V4L2_BUF_TYPE_VIDEO_CAPTURE
+ || i == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
+ ret = fimc_streamoff_capture(ctrl);
+ } else {
+ fimc_err("V4L2_BUF_TYPE_VIDEO_CAPTURE and "
+ "V4L2_BUF_TYPE_VIDEO_OUTPUT are only supported\n");
+ ret = -EINVAL;
+ }
+#else
if (i == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
ret = fimc_streamoff_capture(ctrl);
} else if (i == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
@@ -229,6 +326,7 @@ static int fimc_streamoff(struct file *filp, void *fh, enum v4l2_buf_type i)
"V4L2_BUF_TYPE_VIDEO_OUTPUT are only supported\n");
ret = -EINVAL;
}
+#endif
return ret;
}
@@ -238,6 +336,18 @@ static int fimc_qbuf(struct file *filp, void *fh, struct v4l2_buffer *b)
struct fimc_control *ctrl = ((struct fimc_prv_data *)fh)->ctrl;
int ret = -1;
+#ifdef CONFIG_SLP_DMABUF
+ if (V4L2_TYPE_IS_OUTPUT(b->type)) {
+ ret = fimc_qbuf_output(fh, b);
+ } else if (b->type == V4L2_BUF_TYPE_VIDEO_CAPTURE
+ || b->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
+ ret = fimc_qbuf_capture(ctrl, b);
+ } else {
+ fimc_err("V4L2_BUF_TYPE_VIDEO_CAPTURE and "
+ "V4L2_BUF_TYPE_VIDEO_OUTPUT are only supported\n");
+ ret = -EINVAL;
+ }
+#else
if (b->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
ret = fimc_qbuf_capture(ctrl, b);
} else if (b->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
@@ -247,6 +357,7 @@ static int fimc_qbuf(struct file *filp, void *fh, struct v4l2_buffer *b)
"V4L2_BUF_TYPE_VIDEO_OUTPUT are only supported\n");
ret = -EINVAL;
}
+#endif
return ret;
}
@@ -256,6 +367,18 @@ static int fimc_dqbuf(struct file *filp, void *fh, struct v4l2_buffer *b)
struct fimc_control *ctrl = ((struct fimc_prv_data *)fh)->ctrl;
int ret = -1;
+#ifdef CONFIG_SLP_DMABUF
+ if (V4L2_TYPE_IS_OUTPUT(b->type)) {
+ ret = fimc_dqbuf_output(fh, b);
+ } else if (b->type == V4L2_BUF_TYPE_VIDEO_CAPTURE
+ || b->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
+ ret = fimc_dqbuf_capture(ctrl, b);
+ } else {
+ fimc_err("V4L2_BUF_TYPE_VIDEO_CAPTURE and "
+ "V4L2_BUF_TYPE_VIDEO_OUTPUT are only supported\n");
+ ret = -EINVAL;
+ }
+#else
if (b->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
ret = fimc_dqbuf_capture(ctrl, b);
} else if (b->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
@@ -265,6 +388,7 @@ static int fimc_dqbuf(struct file *filp, void *fh, struct v4l2_buffer *b)
"V4L2_BUF_TYPE_VIDEO_OUTPUT are only supported\n");
ret = -EINVAL;
}
+#endif
return ret;
}
@@ -315,6 +439,12 @@ const struct v4l2_ioctl_ops fimc_v4l2_ops = {
.vidioc_querymenu = fimc_querymenu,
.vidioc_g_fmt_vid_out = fimc_g_fmt_vid_out,
.vidioc_s_fmt_vid_out = fimc_s_fmt_vid_out,
+#ifdef CONFIG_SLP_DMABUF
+ .vidioc_g_fmt_vid_cap_mplane = fimc_g_fmt_vid_capture,
+ .vidioc_s_fmt_vid_cap_mplane = fimc_s_fmt_vid_capture,
+ .vidioc_g_fmt_vid_out_mplane = fimc_g_fmt_vid_out,
+ .vidioc_s_fmt_vid_out_mplane = fimc_s_fmt_vid_out,
+#endif
.vidioc_try_fmt_vid_out = fimc_try_fmt_vid_out,
.vidioc_g_fbuf = fimc_g_fbuf,
.vidioc_s_fbuf = fimc_s_fbuf,
diff --git a/drivers/media/video/samsung/fimg2d3x-exynos4/fimg2d_dev.c b/drivers/media/video/samsung/fimg2d3x-exynos4/fimg2d_dev.c
index 5ccde4a..e0d7d4e 100644
--- a/drivers/media/video/samsung/fimg2d3x-exynos4/fimg2d_dev.c
+++ b/drivers/media/video/samsung/fimg2d3x-exynos4/fimg2d_dev.c
@@ -477,16 +477,27 @@ static int g2d_remove(struct platform_device *dev)
#if defined(CONFIG_HAS_EARLYSUSPEND)
void g2d_early_suspend(struct early_suspend *h)
{
+ int i = 0;
+
atomic_set(&g2d_dev->ready_to_run, 0);
/* wait until G2D running is finished */
while(1) {
if (!atomic_read(&g2d_dev->in_use))
break;
-
+
msleep_interruptible(2);
+
+ i++;
+ /* Timeout 1sec */
+ if (i > 500) {
+ g2d_clk_enable(g2d_dev);
+ g2d_reset(g2d_dev);
+ g2d_clk_disable(g2d_dev);
+ break;
+ }
}
-
+
g2d_sysmmu_off(g2d_dev);
#if defined(CONFIG_EXYNOS_DEV_PD)
@@ -513,25 +524,37 @@ void g2d_late_resume(struct early_suspend *h)
#if !defined(CONFIG_HAS_EARLYSUSPEND)
static int g2d_suspend(struct platform_device *dev, pm_message_t state)
{
+ int i = 0;
+
atomic_set(&g2d_dev->ready_to_run, 0);
/* wait until G2D running is finished */
while(1) {
if (!atomic_read(&g2d_dev->in_use))
break;
-
+
msleep_interruptible(2);
+
+ i++;
+ /* Timeout 1sec */
+ if (i > 500) {
+ g2d_clk_enable(g2d_dev);
+ g2d_reset(g2d_dev);
+ g2d_clk_disable(g2d_dev);
+ break;
+ }
}
-
+
g2d_sysmmu_off(g2d_dev);
-
+
#if defined(CONFIG_EXYNOS_DEV_PD)
/* disable the power domain */
pm_runtime_put(g2d_dev->dev);
-#endif
+#endif
return 0;
}
+
static int g2d_resume(struct platform_device *pdev)
{
diff --git a/drivers/media/video/samsung/fimg2d4x-exynos4/fimg2d.h b/drivers/media/video/samsung/fimg2d4x-exynos4/fimg2d.h
index 2d8f3b7..3bbb194 100644
--- a/drivers/media/video/samsung/fimg2d4x-exynos4/fimg2d.h
+++ b/drivers/media/video/samsung/fimg2d4x-exynos4/fimg2d.h
@@ -41,6 +41,15 @@
#define FIMG2D_BITBLT_SYNC _IOW(FIMG2D_IOCTL_MAGIC, 1, int)
#define FIMG2D_BITBLT_VERSION _IOR(FIMG2D_IOCTL_MAGIC, 2, struct fimg2d_version)
#define FIMG2D_BITBLT_SECURE _IOW(FIMG2D_IOCTL_MAGIC, 3, unsigned int)
+#define FIMG2D_BITBLT_DBUFFER _IOW(FIMG2D_IOCTL_MAGIC, 4, unsigned long)
+
+#define SEQ_NO_BLT_SKIA 0x00000001
+#define SEQ_NO_BLT_HWC_SEC 0x00000012
+#define SEQ_NO_BLT_HWC_NOSEC 0x00000002
+#define SEQ_NO_BLT_HDMI 0x00000003
+#define SEQ_NO_CMD_SECURE_ON 0x10000001
+#define SEQ_NO_CMD_SECURE_OFF 0x10000002
+#define SEQ_NO_CMD_SET_DBUFFER 0x10000003
struct fimg2d_version {
unsigned int hw;
@@ -429,6 +438,7 @@ struct fimg2d_context {
atomic_t ncmd;
wait_queue_head_t wait_q;
struct fimg2d_perf perf[MAX_PERF_DESCS];
+ unsigned long *pgd_clone;
};
/**
@@ -486,6 +496,8 @@ struct fimg2d_control {
int irq;
unsigned int secure;
+ unsigned int dbuffer_addr;
+ unsigned long fault_addr;
atomic_t nctx;
atomic_t busy;
atomic_t active;
diff --git a/drivers/media/video/samsung/fimg2d4x-exynos4/fimg2d4x_blt.c b/drivers/media/video/samsung/fimg2d4x-exynos4/fimg2d4x_blt.c
index fc6016c..1eb8d63 100644
--- a/drivers/media/video/samsung/fimg2d4x-exynos4/fimg2d4x_blt.c
+++ b/drivers/media/video/samsung/fimg2d4x-exynos4/fimg2d4x_blt.c
@@ -83,7 +83,12 @@ void fimg2d4x_bitblt(struct fimg2d_control *info)
goto blitend;
if (cmd->image[IDST].addr.type != ADDR_PHYS) {
- pgd = (unsigned long *)ctx->mm->pgd;
+ if ((cmd->image[IDST].addr.type == ADDR_USER_CONTIG) ||
+ (cmd->image[ISRC].addr.type == ADDR_USER_CONTIG))
+ pgd = (unsigned long *)ctx->pgd_clone;
+ else
+ pgd = (unsigned long *)ctx->mm->pgd;
+
s5p_sysmmu_enable(info->dev, (unsigned long)virt_to_phys(pgd));
fimg2d_debug("sysmmu enable: pgd %p ctx %p seq_no(%u)\n",
pgd, ctx, cmd->seq_no);
@@ -98,6 +103,8 @@ void fimg2d4x_bitblt(struct fimg2d_control *info)
info->run(info);
fimg2d4x_blit_wait(info, cmd);
+ if (info->fault_addr)
+ fimg2d_mmutable_value_replace(cmd, info->fault_addr, 0);
#ifdef PERF_PROFILE
perf_end(cmd->ctx, PERF_BLIT);
#endif
diff --git a/drivers/media/video/samsung/fimg2d4x-exynos4/fimg2d4x_hw.c b/drivers/media/video/samsung/fimg2d4x-exynos4/fimg2d4x_hw.c
index 4eb4d04..7835dee 100644
--- a/drivers/media/video/samsung/fimg2d4x-exynos4/fimg2d4x_hw.c
+++ b/drivers/media/video/samsung/fimg2d4x-exynos4/fimg2d4x_hw.c
@@ -16,6 +16,7 @@
#include "fimg2d.h"
#include "fimg2d4x.h"
#include "fimg2d_clk.h"
+#include "fimg2d_cache.h"
#define wr(d, a) writel((d), info->regs + (a))
#define rd(a) readl(info->regs + (a))
@@ -124,7 +125,13 @@ void fimg2d4x_set_src_image(struct fimg2d_control *info, struct fimg2d_image *s)
{
unsigned long cfg;
- wr(FIMG2D_ADDR(s->addr.start), FIMG2D_SRC_BASE_ADDR_REG);
+ if ((s->addr.type == ADDR_USER_CONTIG) && (s->order < ARGB_ORDER_END)) {
+ wr(FIMG2D_ADDR(GET_MVA(s->addr.start, s->plane2.start)),
+ FIMG2D_SRC_BASE_ADDR_REG);
+ } else {
+ wr(FIMG2D_ADDR(s->addr.start), FIMG2D_SRC_BASE_ADDR_REG);
+ }
+
wr(FIMG2D_STRIDE(s->stride), FIMG2D_SRC_STRIDE_REG);
if (s->order < ARGB_ORDER_END) { /* argb */
@@ -173,7 +180,13 @@ void fimg2d4x_set_dst_image(struct fimg2d_control *info, struct fimg2d_image *d)
{
unsigned long cfg;
- wr(FIMG2D_ADDR(d->addr.start), FIMG2D_DST_BASE_ADDR_REG);
+ if ((d->addr.type == ADDR_USER_CONTIG) && (d->order < ARGB_ORDER_END)) {
+ wr(FIMG2D_ADDR(GET_MVA(d->addr.start, d->plane2.start)),
+ FIMG2D_DST_BASE_ADDR_REG);
+ } else {
+ wr(FIMG2D_ADDR(d->addr.start), FIMG2D_DST_BASE_ADDR_REG);
+ }
+
wr(FIMG2D_STRIDE(d->stride), FIMG2D_DST_STRIDE_REG);
if (d->order < ARGB_ORDER_END) {
diff --git a/drivers/media/video/samsung/fimg2d4x-exynos4/fimg2d_cache.c b/drivers/media/video/samsung/fimg2d4x-exynos4/fimg2d_cache.c
index 43489e4..f5486b1 100644
--- a/drivers/media/video/samsung/fimg2d4x-exynos4/fimg2d_cache.c
+++ b/drivers/media/video/samsung/fimg2d4x-exynos4/fimg2d_cache.c
@@ -114,8 +114,48 @@ void fimg2d_clean_outer_pagetable(struct mm_struct *mm, unsigned long vaddr,
lv1++;
} while (lv1 != lv1end);
}
+
+void fimg2d_clean_outer_pagetable_clone(unsigned long *pgd_clone,
+ unsigned long vaddr, size_t size)
+{
+ unsigned long *pgd;
+ unsigned long *lv1, *lv1end;
+ unsigned long lv2pa;
+
+ pgd = (unsigned long *)pgd_clone;
+
+ lv1 = pgd + (vaddr >> LV1_SHIFT);
+ lv1end = pgd + ((vaddr + size + LV1_PT_SIZE-1) >> LV1_SHIFT);
+
+ /* clean level1 page table */
+ outer_clean_range(virt_to_phys(lv1), virt_to_phys(lv1end));
+
+ do {
+ /* if page size is 4KB, clean level2 page table entry */
+ if ((*lv1 & 0x3) == 0x1) {
+ lv2pa = *lv1 & ~LV2_BASE_MASK; /* lv2 pt base */
+ /* clean level2 page table */
+ outer_clean_range(lv2pa, lv2pa + LV2_PT_SIZE);
+ }
+ lv1++;
+ } while (lv1 != lv1end);
+}
#endif /* CONFIG_OUTER_CACHE */
+void fimg2d_clean_inner_pagetable_clone(unsigned long *pgd_clone,
+ unsigned long vaddr, size_t size)
+{
+ unsigned long *pgd;
+ unsigned long *lv1, *lv1end;
+
+ pgd = (unsigned long *)pgd_clone;
+
+ lv1 = pgd + (vaddr >> LV1_SHIFT);
+ lv1end = pgd + ((vaddr + size + LV1_PT_SIZE-1) >> LV1_SHIFT);
+ fimg2d_dma_sync_inner((unsigned long)lv1,
+ (unsigned int)lv1end - (unsigned int)lv1, DMA_TO_DEVICE);
+}
+
enum pt_status fimg2d_check_pagetable(struct mm_struct *mm, unsigned long vaddr,
size_t size)
{
@@ -166,3 +206,50 @@ enum pt_status fimg2d_check_pagetable(struct mm_struct *mm, unsigned long vaddr,
return PT_NORMAL;
}
+
+#define PT_NS 0x0 // Non Secure
+#define PT_AP 0x8c00 // Access permission
+#define PT_ENTRY 0x2 // 1MB Page
+
+enum pt_status fimg2d_migrate_pagetable(unsigned long *pgd_clone,
+ unsigned long vaddr, unsigned long paddr, size_t size)
+{
+ unsigned long *pgd;
+ unsigned long *lv1d;
+
+ pgd = (unsigned long *)pgd_clone;
+
+ size += vaddr & (SZ_1M - 1);
+ size = ALIGN(size, SZ_1M);
+
+ while ((long)size > 0) {
+ lv1d = pgd + (vaddr >> LV1_SHIFT);
+
+ *lv1d = (paddr & 0xfff00000) | PT_NS | PT_AP | PT_ENTRY;
+
+ vaddr += SZ_1M;
+ paddr += SZ_1M;
+ size -= SZ_1M;
+ }
+ return PT_NORMAL;
+}
+
+void fimg2d_mmutable_value_replace(struct fimg2d_bltcmd *cmd,
+ unsigned long fault_addr, unsigned long l2d_value)
+{
+ unsigned long *pgd;
+ unsigned long *lv1d, *lv2d;
+
+ pgd = (unsigned long *)cmd->ctx->mm->pgd;
+ lv1d = pgd + (fault_addr >> LV1_SHIFT);
+
+ lv2d = (unsigned long *)phys_to_virt(*lv1d & ~LV2_BASE_MASK) +
+ ((fault_addr & LV2_PT_MASK) >> LV2_SHIFT);
+
+ *lv2d = l2d_value;
+
+ flush_all_cpu_caches();
+ fimg2d_clean_outer_pagetable(cmd->ctx->mm, fault_addr, 4);
+
+ printk(KERN_INFO "MMU Level2 value replaced [0x%lx]", l2d_value);
+}
diff --git a/drivers/media/video/samsung/fimg2d4x-exynos4/fimg2d_cache.h b/drivers/media/video/samsung/fimg2d4x-exynos4/fimg2d_cache.h
index f337ea5..7699a37 100644
--- a/drivers/media/video/samsung/fimg2d4x-exynos4/fimg2d_cache.h
+++ b/drivers/media/video/samsung/fimg2d4x-exynos4/fimg2d_cache.h
@@ -18,6 +18,10 @@
#define L1_CACHE_SIZE SZ_64K
#define L2_CACHE_SIZE SZ_1M
#define LINE_FLUSH_THRESHOLD SZ_1K
+#define L1_DESCRIPTOR_SIZE SZ_16K
+
+/* Get Modified virtual address to use 1MB page */
+#define GET_MVA(V, P) ((V & 0xfff00000) | (P & 0x000fffff))
/**
* cache_opr - [kernel] cache operation mode
@@ -92,5 +96,11 @@ static inline void fimg2d_dma_unsync_inner(unsigned long addr, size_t size, int
}
void fimg2d_clean_outer_pagetable(struct mm_struct *mm, unsigned long addr, size_t size);
+void fimg2d_clean_outer_pagetable_clone(unsigned long *pgd_clone, unsigned long addr, size_t size);
+void fimg2d_clean_inner_pagetable_clone(unsigned long *pgd_clone, unsigned long addr, size_t size);
void fimg2d_dma_sync_outer(struct mm_struct *mm, unsigned long addr, size_t size, enum cache_opr opr);
enum pt_status fimg2d_check_pagetable(struct mm_struct *mm, unsigned long addr, size_t size);
+enum pt_status fimg2d_migrate_pagetable(unsigned long *pgd_clone,
+ unsigned long vaddr, unsigned long paddr, size_t size);
+void fimg2d_mmutable_value_replace(struct fimg2d_bltcmd *cmd,
+ unsigned long fault_addr, unsigned long l2d_value);
diff --git a/drivers/media/video/samsung/fimg2d4x-exynos4/fimg2d_ctx.c b/drivers/media/video/samsung/fimg2d4x-exynos4/fimg2d_ctx.c
index eaa722c..0c6c590 100644
--- a/drivers/media/video/samsung/fimg2d4x-exynos4/fimg2d_ctx.c
+++ b/drivers/media/video/samsung/fimg2d4x-exynos4/fimg2d_ctx.c
@@ -130,6 +130,7 @@ static int fimg2d_check_dma_sync(struct fimg2d_bltcmd *cmd)
enum pt_status pt;
int clip_x, clip_w, clip_h, y, dir, i;
unsigned long clip_start;
+ unsigned long modified_addr;
clp = &p->clipping;
@@ -155,6 +156,13 @@ static int fimg2d_check_dma_sync(struct fimg2d_bltcmd *cmd)
pt = fimg2d_check_pagetable(mm, c->addr, c->size);
if (pt == PT_FAULT)
return -1;
+ } else if (img->addr.type == ADDR_USER_CONTIG) {
+ modified_addr = GET_MVA(img->addr.start, img->plane2.start);
+ pt = fimg2d_migrate_pagetable(cmd->ctx->pgd_clone,
+ modified_addr, img->plane2.start, img->height * img->stride);
+ if (pt != PT_NORMAL) {
+ return -1;
+ }
}
if (img->need_cacheopr && i != IMAGE_TMP) {
@@ -175,7 +183,25 @@ static int fimg2d_check_dma_sync(struct fimg2d_bltcmd *cmd)
c = &cmd->dma[i];
r = &img->rect;
- if (!img->addr.type || !c->cached)
+ if (!img->addr.type)
+ continue;
+
+ if ((cmd->image[IMAGE_SRC].addr.type == ADDR_USER_CONTIG) ||
+ (cmd->image[IMAGE_DST].addr.type == ADDR_USER_CONTIG)) {
+ if (img->addr.type == ADDR_USER_CONTIG) {
+ if (i == IMAGE_DST && clp->enable)
+ modified_addr = GET_MVA(img->addr.start, img->plane2.start) +
+ (img->stride * clp->y1);
+ else
+ modified_addr = GET_MVA(img->addr.start, img->plane2.start) +
+ (img->stride * r->y1);
+ } else {
+ modified_addr = c->addr;
+ }
+ fimg2d_clean_inner_pagetable_clone(cmd->ctx->pgd_clone, modified_addr, c->size);
+ }
+
+ if ( !c->cached)
continue;
if (i == IMAGE_DST)
@@ -226,8 +252,22 @@ static int fimg2d_check_dma_sync(struct fimg2d_bltcmd *cmd)
continue;
/* clean pagetable */
- if (img->addr.type == ADDR_USER)
+ if ((cmd->image[IMAGE_SRC].addr.type == ADDR_USER_CONTIG) ||
+ (cmd->image[IMAGE_DST].addr.type == ADDR_USER_CONTIG)) {
+ if (img->addr.type == ADDR_USER_CONTIG) {
+ if (i == IMAGE_DST && clp->enable)
+ modified_addr = GET_MVA(img->addr.start, img->plane2.start) +
+ (img->stride * clp->y1);
+ else
+ modified_addr = GET_MVA(img->addr.start, img->plane2.start) +
+ (img->stride * r->y1);
+ } else {
+ modified_addr = c->addr;
+ }
+ fimg2d_clean_outer_pagetable_clone(cmd->ctx->pgd_clone, modified_addr, c->size);
+ } else {
fimg2d_clean_outer_pagetable(mm, c->addr, c->size);
+ }
if (!c->cached)
continue;
@@ -275,14 +315,17 @@ int fimg2d_add_command(struct fimg2d_control *info, struct fimg2d_context *ctx,
int i, ret;
struct fimg2d_image *buf[MAX_IMAGES] = image_table(blit);
struct fimg2d_bltcmd *cmd;
+ struct fimg2d_image *img;
- if ((blit->dst) && (type == ADDR_USER))
+ if ((blit->dst) && (type == ADDR_USER)
+ && (blit->seq_no == SEQ_NO_BLT_SKIA))
up_write(&page_alloc_slow_rwsem);
cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
if (!cmd) {
- if ((blit->dst) && (type == ADDR_USER))
+ if ((blit->dst) && (type == ADDR_USER)
+ && (blit->seq_no == SEQ_NO_BLT_SKIA))
if (!down_write_trylock(&page_alloc_slow_rwsem))
return -EAGAIN;
return -ENOMEM;
@@ -294,7 +337,8 @@ int fimg2d_add_command(struct fimg2d_control *info, struct fimg2d_context *ctx,
if (copy_from_user(&cmd->image[i], buf[i],
sizeof(struct fimg2d_image))) {
- if ((blit->dst) && (type == ADDR_USER))
+ if ((blit->dst) && (type == ADDR_USER)
+ && (blit->seq_no == SEQ_NO_BLT_SKIA))
if (!down_write_trylock(&page_alloc_slow_rwsem)) {
ret = -EAGAIN;
goto err_user;
@@ -304,7 +348,8 @@ int fimg2d_add_command(struct fimg2d_control *info, struct fimg2d_context *ctx,
}
}
- if ((blit->dst) && (type == ADDR_USER))
+ if ((blit->dst) && (type == ADDR_USER)
+ && (blit->seq_no == SEQ_NO_BLT_SKIA))
if (!down_write_trylock(&page_alloc_slow_rwsem)) {
ret = -EAGAIN;
goto err_user;
@@ -329,6 +374,13 @@ int fimg2d_add_command(struct fimg2d_control *info, struct fimg2d_context *ctx,
fimg2d_fixup_params(cmd);
+ for (i = 0; i < MAX_IMAGES; i++) {
+ img = &cmd->image[i];
+ if (img->addr.type == ADDR_USER_CONTIG) {
+ memcpy(cmd->ctx->pgd_clone, cmd->ctx->mm->pgd, L1_DESCRIPTOR_SIZE);
+ }
+ }
+
if (fimg2d_check_dma_sync(cmd)) {
ret = -EFAULT;
goto err_user;
diff --git a/drivers/media/video/samsung/fimg2d4x-exynos4/fimg2d_drv.c b/drivers/media/video/samsung/fimg2d4x-exynos4/fimg2d_drv.c
index ed14901..84c7db5 100644
--- a/drivers/media/video/samsung/fimg2d4x-exynos4/fimg2d_drv.c
+++ b/drivers/media/video/samsung/fimg2d4x-exynos4/fimg2d_drv.c
@@ -46,6 +46,8 @@
#define LV2_PT_MASK 0xff000
#define LV2_SHIFT 12
#define LV1_DESC_MASK 0x3
+#define LV2_VALUE_META 0xc7f
+#define LV2_VALUE_BASE_MASK 0xfff
static struct fimg2d_control *info;
@@ -116,7 +118,12 @@ static int fimg2d_sysmmu_fault_handler(enum S5P_SYSMMU_INTERRUPT_TYPE itype,
lv2d = (unsigned long *)phys_to_virt(*lv1d & ~LV2_BASE_MASK) +
((fault_addr & LV2_PT_MASK) >> LV2_SHIFT);
printk(KERN_ERR " Level 2 descriptor(0x%lx)\n", *lv2d);
- fimg2d_clean_outer_pagetable(cmd->ctx->mm, fault_addr, 4);
+ if (*lv2d == 0) {
+ fimg2d_mmutable_value_replace(cmd, fault_addr,
+ (info->dbuffer_addr & ~LV2_VALUE_BASE_MASK) | LV2_VALUE_META);
+ info->fault_addr = fault_addr;
+ } else
+ fimg2d_clean_outer_pagetable(cmd->ctx->mm, fault_addr, 4);
next:
return 0;
@@ -161,6 +168,8 @@ static int fimg2d_open(struct inode *inode, struct file *file)
ctx, (unsigned long *)ctx->mm->pgd,
(unsigned long *)init_mm.pgd);
+ ctx->pgd_clone = kzalloc(L1_DESCRIPTOR_SIZE, GFP_KERNEL);
+
fimg2d_add_context(info, ctx);
return 0;
}
@@ -178,6 +187,7 @@ static int fimg2d_release(struct inode *inode, struct file *file)
}
fimg2d_del_context(info, ctx);
+ kfree(ctx->pgd_clone);
kfree(ctx);
return 0;
}
@@ -223,7 +233,8 @@ static long fimg2d_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
dev_lock(info->bus_dev, info->dev, 160160);
#endif
#endif
- if ((blit.dst) && (dst.addr.type == ADDR_USER))
+ if ((blit.dst) && (dst.addr.type == ADDR_USER)
+ && (blit.seq_no == SEQ_NO_BLT_SKIA))
if (!down_write_trylock(&page_alloc_slow_rwsem))
ret = -EAGAIN;
@@ -238,7 +249,9 @@ static long fimg2d_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
perf_print(ctx, blit.seq_no);
perf_clear(ctx);
#endif
- if ((blit.dst) && (dst.addr.type == ADDR_USER) && ret != -EAGAIN)
+ if ((blit.dst) && (dst.addr.type == ADDR_USER)
+ && (blit.seq_no == SEQ_NO_BLT_SKIA)
+ && ret != -EAGAIN)
up_write(&page_alloc_slow_rwsem);
#ifdef CONFIG_BUSFREQ_OPP
@@ -246,6 +259,13 @@ static long fimg2d_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
dev_unlock(info->bus_dev, info->dev);
#endif
#endif
+
+ if (info->fault_addr) {
+ printk(KERN_INFO "Return by G2D fault handler");
+ info->fault_addr = 0;
+ ret = -EFAULT;
+ }
+
break;
case FIMG2D_BITBLT_SYNC:
@@ -281,6 +301,17 @@ static long fimg2d_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
break;
+ case FIMG2D_BITBLT_DBUFFER:
+ if (copy_from_user(&info->dbuffer_addr,
+ (unsigned long *)arg,
+ sizeof(unsigned long))) {
+ printk(KERN_ERR
+ "[%s] failed to FIMG2D_BITBLT_DBUFFER: copy_from_user error\n\n",
+ __func__);
+ return -EFAULT;
+ }
+ break;
+
default:
printk(KERN_ERR "[%s] unknown ioctl\n", __func__);
ret = -EFAULT;
@@ -315,6 +346,7 @@ static int fimg2d_setup_controller(struct fimg2d_control *info)
atomic_set(&info->nctx, 0);
atomic_set(&info->active, 0);
info->secure = 0;
+ info->fault_addr = 0;
spin_lock_init(&info->bltlock);
@@ -384,12 +416,20 @@ static int fimg2d_probe(struct platform_device *pdev)
fimg2d_debug("device name: %s base address: 0x%lx\n",
pdev->name, (unsigned long)res->start);
+ /* Clock setup */
+ ret = fimg2d_clk_setup(info);
+ if (ret) {
+ printk(KERN_ERR "FIMG2D failed to setup clk\n");
+ ret = -ENOENT;
+ goto err_clk;
+ }
+
/* irq */
info->irq = platform_get_irq(pdev, 0);
if (!info->irq) {
printk(KERN_ERR "FIMG2D failed to get irq resource\n");
ret = -ENOENT;
- goto err_map;
+ goto err_irq;
}
fimg2d_debug("irq: %d\n", info->irq);
@@ -400,13 +440,6 @@ static int fimg2d_probe(struct platform_device *pdev)
goto err_irq;
}
- ret = fimg2d_clk_setup(info);
- if (ret) {
- printk(KERN_ERR "FIMG2D failed to setup clk\n");
- ret = -ENOENT;
- goto err_clk;
- }
-
#ifdef CONFIG_PM_RUNTIME
pm_runtime_enable(info->dev);
fimg2d_debug("enable runtime pm\n");
@@ -432,19 +465,20 @@ static int fimg2d_probe(struct platform_device *pdev)
return 0;
err_reg:
- fimg2d_clk_release(info);
-
-err_clk:
free_irq(info->irq, NULL);
err_irq:
+ fimg2d_clk_release(info);
+
+err_clk:
iounmap(info->regs);
err_map:
+ release_mem_region(res->start, resource_size(res));
kfree(info->mem);
err_region:
- release_resource(info->mem);
+ release_resource(res);
err_res:
destroy_workqueue(info->work_q);
diff --git a/drivers/media/video/samsung/jpeg_v2x/jpeg_conf.h b/drivers/media/video/samsung/jpeg_v2x/jpeg_conf.h
index 6fcc276..086c20a 100644
--- a/drivers/media/video/samsung/jpeg_v2x/jpeg_conf.h
+++ b/drivers/media/video/samsung/jpeg_v2x/jpeg_conf.h
@@ -15,27 +15,37 @@
/* Q-table for JPEG */
/* ITU standard Q-table */
-const unsigned int ITU_Q_tbl[4][16] = {
+const unsigned int ITU_Q_tbl[6][16] = {
{
- 0x01010101, 0x01020303, 0x01010101, 0x01030303, /* Y */
- 0x01010101, 0x02030303, 0x01010101, 0x03040403,
- 0x01010203, 0x03050504, 0x01020303, 0x04050605,
- 0x02030404, 0x05060605, 0x04050505, 0x06050505
+ 0x06030303, 0x07070706, 0x03030303, 0x08080804, /* Y QF:97 */
+ 0x01010101, 0x03040303, 0x03010101, 0x04050503,
+ 0x03030101, 0x05060704, 0x04030301, 0x06070605,
+ 0x05050403, 0x06070706, 0x06060604, 0x06070707
} , {
- 0x01010102, 0x05050505, 0x01010103, 0x05050505, /* CbCr */
- 0x01010503, 0x05050505, 0x02030505, 0x05050505,
- 0x05050505, 0x05050505, 0x05050505, 0x05050505,
- 0x05050505, 0x05050505, 0x05050505, 0x05050505
+ 0x06030303, 0x07070706, 0x04030303, 0x08080806, /* CbCr QF:97 */
+ 0x06030301, 0x06060606, 0x06060403, 0x06060606,
+ 0x06060606, 0x06060606, 0x06060606, 0x06060606,
+ 0x06060606, 0x06060606, 0x06060606, 0x06060606
} , {
- 0x05020205, 0x0a161e25, 0x02020307, 0x0c232521, /* Y */
- 0x0302050a, 0x16222b22, 0x0305090e, 0x1e393326,
- 0x06091422, 0x2a384431, 0x0a122118, 0x34454b3c,
- 0x1d283238, 0x44525142, 0x2d3c3e40, 0x4a424441
+ 0x06030303, 0x0a080706, 0x03030303, 0x090a0904, /* Y QF:92 */
+ 0x04030303, 0x090b0906, 0x05040303, 0x0a0d0e08,
+ 0x09060403, 0x0c10110d, 0x0a090604, 0x0f12110d,
+ 0x0e0c0a08, 0x10131310, 0x100f0f0c, 0x10101012
} , {
- 0x05020205, 0x251e160a, 0x07030202, 0x2125230c, /* CbCr */
- 0x0a050203, 0x222b2216, 0x0e090503, 0x2633391e,
- 0x22140906, 0x3144382a, 0x1821120a, 0x3c4b4534,
- 0x3832281d, 0x42515244, 0x403e3c2d, 0x4144424a
+ 0x08040303, 0x10101010, 0x0b040303, 0x10101010, /* CbCr QF:92 */
+ 0x10090404, 0x10101010, 0x10100b08, 0x10101010,
+ 0x10101010, 0x10101010, 0x10101010, 0x10101010,
+ 0x10101010, 0x10101010, 0x10101010, 0x10101010
+ } , {
+ 0x06030304, 0x0e0c0a06, 0x05030303, 0x0d0e0e06, /* Y QF:88 */
+ 0x06040303, 0x0d110e0a, 0x07050403, 0x0f13150c,
+ 0x0d090504, 0x12191a10, 0x0f0d0806, 0x161b1913,
+ 0x15130f0c, 0x181d1d19, 0x18171611, 0x1819181b
+ } , {
+ 0x0b060404, 0x18181818, 0x10060504, 0x18181818, /* CbCr QF:88 */
+ 0x180d0606, 0x18181818, 0x1818100b, 0x18181818,
+ 0x18181818, 0x18181818, 0x18181818, 0x18181818,
+ 0x18181818, 0x18181818, 0x18181818, 0x18181818
}
};
diff --git a/drivers/media/video/samsung/jpeg_v2x/jpeg_dev.c b/drivers/media/video/samsung/jpeg_v2x/jpeg_dev.c
index 1e6b085..eb026ab 100644
--- a/drivers/media/video/samsung/jpeg_v2x/jpeg_dev.c
+++ b/drivers/media/video/samsung/jpeg_v2x/jpeg_dev.c
@@ -504,7 +504,7 @@ static void jpeg_device_enc_run(void *priv)
jpeg_sw_reset(dev->reg_base);
jpeg_set_interrupt(dev->reg_base);
jpeg_set_huf_table_enable(dev->reg_base, 1);
- jpeg_set_enc_tbl(dev->reg_base);
+ jpeg_set_enc_tbl(dev->reg_base, enc_param.quality);
jpeg_set_encode_tbl_select(dev->reg_base, enc_param.quality);
jpeg_set_stream_size(dev->reg_base,
enc_param.in_width, enc_param.in_height);
@@ -893,12 +893,16 @@ static int jpeg_probe(struct platform_device *pdev)
#endif
#ifdef CONFIG_JPEG_V2_1
- dev->watchdog_workqueue = create_singlethread_workqueue(JPEG_NAME);
- INIT_WORK(&dev->watchdog_work, jpeg_watchdog_worker);
- atomic_set(&dev->watchdog_cnt, 0);
- init_timer(&dev->watchdog_timer);
- dev->watchdog_timer.data = (unsigned long)dev;
- dev->watchdog_timer.function = jpeg_watchdog;
+ dev->watchdog_workqueue = create_singlethread_workqueue(JPEG_NAME);
+ if (!dev->watchdog_workqueue) {
+ ret = -ENOMEM;
+ goto err_video_reg;
+ }
+ INIT_WORK(&dev->watchdog_work, jpeg_watchdog_worker);
+ atomic_set(&dev->watchdog_cnt, 0);
+ init_timer(&dev->watchdog_timer);
+ dev->watchdog_timer.data = (unsigned long)dev;
+ dev->watchdog_timer.function = jpeg_watchdog;
#endif
/* clock disable */
clk_disable(dev->clk);
@@ -1043,7 +1047,8 @@ static int jpeg_runtime_suspend(struct device *dev)
struct jpeg_dev *jpeg_drv = platform_get_drvdata(pdev);
#if defined(CONFIG_BUSFREQ_OPP) || defined(CONFIG_BUSFREQ_LOCK_WRAPPER)
/* lock bus frequency */
- dev_unlock(jpeg_drv->bus_dev, dev);
+ if (samsung_rev() < EXYNOS4412_REV_2_0)
+ dev_unlock(jpeg_drv->bus_dev, dev);
#endif
jpeg_drv->vb2->suspend(jpeg_drv->alloc_ctx);
/* clock disable */
@@ -1057,7 +1062,9 @@ static int jpeg_runtime_resume(struct device *dev)
struct jpeg_dev *jpeg_drv = platform_get_drvdata(pdev);
#if defined(CONFIG_BUSFREQ_OPP) || defined(CONFIG_BUSFREQ_LOCK_WRAPPER)
/* lock bus frequency */
- dev_lock(jpeg_drv->bus_dev, &jpeg_drv->plat_dev->dev, BUSFREQ_400MHZ);
+ if (samsung_rev() < EXYNOS4412_REV_2_0)
+ dev_lock(jpeg_drv->bus_dev,
+ &jpeg_drv->plat_dev->dev, BUSFREQ_400MHZ);
#endif
clk_enable(jpeg_drv->clk);
jpeg_drv->vb2->resume(jpeg_drv->alloc_ctx);
@@ -1104,9 +1111,7 @@ static int __init jpeg_init(void)
{
printk(KERN_CRIT "Initialize JPEG driver\n");
- platform_driver_register(&jpeg_driver);
-
- return 0;
+ return platform_driver_register(&jpeg_driver);
}
static void __exit jpeg_exit(void)
diff --git a/drivers/media/video/samsung/jpeg_v2x/jpeg_mem.h b/drivers/media/video/samsung/jpeg_v2x/jpeg_mem.h
index d912628..9336bb8 100644
--- a/drivers/media/video/samsung/jpeg_v2x/jpeg_mem.h
+++ b/drivers/media/video/samsung/jpeg_v2x/jpeg_mem.h
@@ -33,7 +33,12 @@ extern const struct jpeg_vb2 jpeg_vb2_cma;
extern const struct jpeg_vb2 jpeg_vb2_ion;
#endif
+#if defined(CONFIG_MACH_GC1)
+#define MAX_JPEG_WIDTH 4608
+#define MAX_JPEG_HEIGHT 3456
+#else
#define MAX_JPEG_WIDTH 3264
#define MAX_JPEG_HEIGHT 2448
+#endif
#endif /* __JPEG_MEM_H__ */
diff --git a/drivers/media/video/samsung/jpeg_v2x/jpeg_regs.c b/drivers/media/video/samsung/jpeg_v2x/jpeg_regs.c
index e3300cc..0c9bc4b 100644
--- a/drivers/media/video/samsung/jpeg_v2x/jpeg_regs.c
+++ b/drivers/media/video/samsung/jpeg_v2x/jpeg_regs.c
@@ -341,28 +341,99 @@ void jpeg_set_enc_out_fmt(void __iomem *base,
writel(reg, base + S5P_JPEG_IMG_FMT_REG);
}
-void jpeg_set_enc_tbl(void __iomem *base)
+void jpeg_set_enc_tbl(void __iomem *base,
+ enum jpeg_img_quality_level level)
{
int i;
- for (i = 0; i < 16; i++) {
- writel((unsigned int)ITU_Q_tbl[0][i],
- base + S5P_JPEG_QUAN_TBL_ENTRY_REG + (i*0x04));
- }
+ switch (level) {
+ case QUALITY_LEVEL_1:
+ for (i = 0; i < 16; i++) {
+ writel((unsigned int)ITU_Q_tbl[0][i],
+ base + S5P_JPEG_QUAN_TBL_ENTRY_REG + (i*0x04));
+ }
- for (i = 0; i < 16; i++) {
- writel((unsigned int)ITU_Q_tbl[1][i],
- base + S5P_JPEG_QUAN_TBL_ENTRY_REG + 0x40 + (i*0x04));
- }
+ for (i = 0; i < 16; i++) {
+ writel((unsigned int)ITU_Q_tbl[1][i],
+ base + S5P_JPEG_QUAN_TBL_ENTRY_REG + 0x40 + (i*0x04));
+ }
- for (i = 0; i < 16; i++) {
- writel((unsigned int)ITU_Q_tbl[2][i],
- base + S5P_JPEG_QUAN_TBL_ENTRY_REG + 0x80 + (i*0x04));
- }
+ for (i = 0; i < 16; i++) {
+ writel((unsigned int)ITU_Q_tbl[0][i],
+ base + S5P_JPEG_QUAN_TBL_ENTRY_REG + 0x80 + (i*0x04));
+ }
+
+ for (i = 0; i < 16; i++) {
+ writel((unsigned int)ITU_Q_tbl[1][i],
+ base + S5P_JPEG_QUAN_TBL_ENTRY_REG + 0xc0 + (i*0x04));
+ }
+ break;
+
+ case QUALITY_LEVEL_2:
+ for (i = 0; i < 16; i++) {
+ writel((unsigned int)ITU_Q_tbl[2][i],
+ base + S5P_JPEG_QUAN_TBL_ENTRY_REG + (i*0x04));
+ }
+
+ for (i = 0; i < 16; i++) {
+ writel((unsigned int)ITU_Q_tbl[3][i],
+ base + S5P_JPEG_QUAN_TBL_ENTRY_REG + 0x40 + (i*0x04));
+ }
- for (i = 0; i < 16; i++) {
- writel((unsigned int)ITU_Q_tbl[3][i],
- base + S5P_JPEG_QUAN_TBL_ENTRY_REG + 0xc0 + (i*0x04));
+ for (i = 0; i < 16; i++) {
+ writel((unsigned int)ITU_Q_tbl[2][i],
+ base + S5P_JPEG_QUAN_TBL_ENTRY_REG + 0x80 + (i*0x04));
+ }
+
+ for (i = 0; i < 16; i++) {
+ writel((unsigned int)ITU_Q_tbl[3][i],
+ base + S5P_JPEG_QUAN_TBL_ENTRY_REG + 0xc0 + (i*0x04));
+ }
+ break;
+
+ case QUALITY_LEVEL_3:
+ for (i = 0; i < 16; i++) {
+ writel((unsigned int)ITU_Q_tbl[4][i],
+ base + S5P_JPEG_QUAN_TBL_ENTRY_REG + (i*0x04));
+ }
+
+ for (i = 0; i < 16; i++) {
+ writel((unsigned int)ITU_Q_tbl[5][i],
+ base + S5P_JPEG_QUAN_TBL_ENTRY_REG + 0x40 + (i*0x04));
+ }
+
+ for (i = 0; i < 16; i++) {
+ writel((unsigned int)ITU_Q_tbl[4][i],
+ base + S5P_JPEG_QUAN_TBL_ENTRY_REG + 0x80 + (i*0x04));
+ }
+
+ for (i = 0; i < 16; i++) {
+ writel((unsigned int)ITU_Q_tbl[5][i],
+ base + S5P_JPEG_QUAN_TBL_ENTRY_REG + 0xc0 + (i*0x04));
+ }
+ break;
+
+ default:
+ for (i = 0; i < 16; i++) {
+ writel((unsigned int)ITU_Q_tbl[0][i],
+ base + S5P_JPEG_QUAN_TBL_ENTRY_REG + (i*0x04));
+ }
+
+ for (i = 0; i < 16; i++) {
+ writel((unsigned int)ITU_Q_tbl[1][i],
+ base + S5P_JPEG_QUAN_TBL_ENTRY_REG + 0x40 + (i*0x04));
+ }
+
+ for (i = 0; i < 16; i++) {
+ writel((unsigned int)ITU_Q_tbl[0][i],
+ base + S5P_JPEG_QUAN_TBL_ENTRY_REG + 0x80 + (i*0x04));
+ }
+
+ for (i = 0; i < 16; i++) {
+ writel((unsigned int)ITU_Q_tbl[1][i],
+ base + S5P_JPEG_QUAN_TBL_ENTRY_REG + 0xc0 + (i*0x04));
+ }
+ break;
}
for (i = 0; i < 4; i++) {
diff --git a/drivers/media/video/samsung/jpeg_v2x/jpeg_regs.h b/drivers/media/video/samsung/jpeg_v2x/jpeg_regs.h
index 535a3f9..1dee4b2 100644
--- a/drivers/media/video/samsung/jpeg_v2x/jpeg_regs.h
+++ b/drivers/media/video/samsung/jpeg_v2x/jpeg_regs.h
@@ -23,7 +23,7 @@ void jpeg_set_enc_in_fmt(void __iomem *base,
enum jpeg_frame_format in_fmt);
void jpeg_set_enc_out_fmt(void __iomem *base,
enum jpeg_stream_format out_fmt);
-void jpeg_set_enc_tbl(void __iomem *base);
+void jpeg_set_enc_tbl(void __iomem *base, enum jpeg_img_quality_level level);
void jpeg_set_interrupt(void __iomem *base);
void jpeg_clean_interrupt(void __iomem *base);
unsigned int jpeg_get_int_status(void __iomem *base);
diff --git a/drivers/media/video/samsung/mali/Kconfig b/drivers/media/video/samsung/mali/Kconfig
index b93bccf..ae9bd7d 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 n
+ default y
---help---
This enables MALI integration in the multimedia device driver
@@ -39,7 +39,6 @@ int "Dedicated Memory Size"
---help---
This value is dedicated memory size of Mali GPU(unit is MByte).
-
# For DEBUG
config VIDEO_MALI400MP_DEBUG
bool "Enables debug messages"
@@ -48,13 +47,6 @@ config VIDEO_MALI400MP_DEBUG
help
This enables Mali driver debug messages.
-config VIDEO_MALI400MP_STREAMLINE_PROFILING
- bool "Enables mali streamline profiling"
- depends on VIDEO_MALI400MP
- default n
- help
- This enables Mali streamline profiling.
-
config VIDEO_MALI400MP_DVFS
bool "Enables DVFS"
depends on VIDEO_MALI400MP && PM
diff --git a/drivers/media/video/samsung/mali/Makefile b/drivers/media/video/samsung/mali/Makefile
index 0ce60a3..db5ce6a 100644
--- a/drivers/media/video/samsung/mali/Makefile
+++ b/drivers/media/video/samsung/mali/Makefile
@@ -10,7 +10,7 @@
OSKOS :=linux
FILES_PREFIX=
-MALI_FILE_PREFIX := drivers/media/video/samsung/mali
+MALI_INCLUDE_PREFIX := drivers/media/video/samsung/mali/
KBUILDROOT =
ifeq ($(CONFIG_MALI_DED_ONLY),y)
@@ -54,12 +54,8 @@ ifeq ($(CONFIG_VIDEO_MALI400MP_DEBUG),y)
BUILD=debug
endif
-ifeq ($(CONFIG_VIDEO_MALI400MP_STREAMLINE_PROFILING),y)
-USING_PROFILING=1
-USING_TRACEPOINTS=1
-endif
-
# set up defaults if not defined by the user
+USE_UMPV2 ?= 0
PANIC_ON_WATCHDOG_TIMEOUT ?= 1
USING_MALI400 ?= 1
USING_MMU ?= 1
@@ -75,21 +71,47 @@ USING_MALI_PMU ?= 0
USING_GPU_UTILIZATION ?= 0
OS_MEMORY_KERNEL_BUFFER_SIZE_IN_MB ?= 6
USING_PROFILING ?= 0
+USING_INTERNAL_PROFILING ?= 0
USING_TRACEPOINTS ?= 0
USING_MALI_MAJOR_PREDEFINE = 1
-USING_MALI_DVFS_ENABLED ?= 0
+USING_MALI_DVFS_ENABLED ?= 1
TIMESTAMP ?= default
BUILD ?= release
USING_MALI_PMM_EARLYSUSPEND ?= 0
#USING_KERNEL_WITH_DMA_ALLOC_PHYS_PAGE ?= 0
-CONFIG_MALI_MEM_SIZE ?= 64
+CONFIG_MALI_MEM_SIZE ?= 512
+DISABLE_PP0 ?= 0
+DISABLE_PP1 ?= 0
+DISABLE_PP2 ?= 0
+DISABLE_PP3 ?= 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
+
+# Get path to driver source from Linux build system
+ifeq ($(USING_PROFILING),1)
+ifeq ($(USING_INTERNAL_PROFILING),0)
+ifndef CONFIG_TRACEPOINTS
+# Should default to gator profiling, but we dont have the kernel feature required, so disable profiling
+USING_PROFILING = 0
+endif
+endif
+endif
+
+ifeq ($(USING_PROFILING),0)
+# make sure user hasnt selected incompatible flags
+USING_INTERNAL_PROFILING = 0
+endif
+
+USING_MALI_SLP_GLOBAL_LOCK ?= 0
#config validtion check
ifeq ($(USING_OS_MEMORY),1)
USING_MMU = 1
endif
+
# Check if a Mali Core sub module should be enabled, true or false returned
-#submodule_enabled = $(shell gcc $(DEFINES) -E $(MALI_FILE_PREFIX)/arch/config.h | grep type | grep -c $(2))
+#submodule_enabled = $(shell gcc $(DEFINES) -E $(FILES_PREFIX)/arch/config.h | grep type | grep -c $(2))
# Inside the kernel build system
@@ -111,14 +133,21 @@ DEFINES += -DMALI_GPU_UTILIZATION=$(USING_GPU_UTILIZATION)
DEFINES += -DCONFIG_MALI_MEM_SIZE=$(CONFIG_MALI_MEM_SIZE)
DEFINES += -D_MALI_OSK_SPECIFIC_INDIRECT_MMAP
DEFINES += -DMALI_TIMELINE_PROFILING_ENABLED=$(USING_PROFILING)
+DEFINES += -DMALI_INTERNAL_TIMELINE_PROFILING_ENABLED=$(USING_INTERNAL_PROFILING)
DEFINES += -DMALI_POWER_MGMT_TEST_SUITE=$(USING_MALI_PMM_TESTSUITE)
DEFINES += -DMALI_MAJOR_PREDEFINE=$(USING_MALI_MAJOR_PREDEFINE)
DEFINES += -DMALI_DVFS_ENABLED=$(USING_MALI_DVFS_ENABLED)
DEFINES += -DUSING_MALI_PMM_EARLYSUSPEND=$(USING_MALI_PMM_EARLYSUSPEND)
-DEFINES += -DMALI_STATE_TRACKING=1
+DEFINES += -DMALI_STATE_TRACKING=0
DEFINES += -DMALI_OS_MEMORY_KERNEL_BUFFER_SIZE_IN_MB=$(OS_MEMORY_KERNEL_BUFFER_SIZE_IN_MB)
DEFINES += -DMALI_TRACEPOINTS_ENABLED=$(USING_TRACEPOINTS)
-DEFINES += -DMALI_REBOOTNOTIFIER
+DEFINES += -DDISABLE_PP0=$(DISABLE_PP0)
+DEFINES += -DDISABLE_PP1=$(DISABLE_PP1)
+DEFINES += -DDISABLE_PP2=$(DISABLE_PP2)
+DEFINES += -DDISABLE_PP3=$(DISABLE_PP3)
+DEFINES += -DMALI_PP_SCHEDULER_FORCE_NO_JOB_OVERLAP=$(MALI_PP_SCHEDULER_FORCE_NO_JOB_OVERLAP)
+DEFINES += -DMALI_PP_SCHEDULER_KEEP_SUB_JOB_STARTS_ALIGNED=$(MALI_PP_SCHEDULER_KEEP_SUB_JOB_STARTS_ALIGNED)
+DEFINES += -DMALI_PP_SCHEDULER_FORCE_NO_JOB_OVERLAP_BETWEEN_APPS=$(MALI_PP_SCHEDULER_FORCE_NO_JOB_OVERLAP_BETWEEN_APPS)
ifeq ($(BUILD),debug)
DEFINES += -DDEBUG
@@ -130,7 +159,7 @@ DEFINES += -DMALI_UKK_HAS_IMPLICIT_MMAP_CLEANUP
# UMP
ifeq ($(CONFIG_VIDEO_UMP),y)
DEFINES += -DMALI_USE_UNIFIED_MEMORY_PROVIDER=1 -DHAVE_UNLOCKED_IOCTL
- EXTRA_CFLAGS += -I$(MALI_FILE_PREFIX)/../ump/include
+ EXTRA_CFLAGS += -I$(MALI_INCLUDE_PREFIX)../ump/include
else
DEFINES += -DMALI_USE_UNIFIED_MEMORY_PROVIDER=0
endif
@@ -141,17 +170,23 @@ obj-$(CONFIG_VIDEO_MALI400MP) += mali.o
# Use our defines when compiling
# MALI
INCLUDES = \
- -I$(MALI_FILE_PREFIX)\
- -I$(MALI_FILE_PREFIX)/platform\
- -I$(MALI_FILE_PREFIX)/common \
- -I$(MALI_FILE_PREFIX)/linux
+ -I$(MALI_INCLUDE_PREFIX)\
+ -I$(MALI_INCLUDE_PREFIX)include \
+ -I$(MALI_INCLUDE_PREFIX)platform\
+ -I$(MALI_INCLUDE_PREFIX)common \
+ -I$(MALI_INCLUDE_PREFIX)linux \
+ -I$(MALI_INCLUDE_PREFIX)regs
+
+ifeq ($(USING_PROFILING),1)
+INCLUDES += \
+ -I$(MALI_INCLUDE_PREFIX)include
+endif
EXTRA_CFLAGS += $(INCLUDES)\
$(DEFINES)
-
-EXTRA_CFLAGS += -I$(MALI_FILE_PREFIX)/linux/license/gpl
-EXTRA_CFLAGS += -I$(MALI_FILE_PREFIX)/common/pmm
+EXTRA_CFLAGS += -I$(MALI_INCLUDE_PREFIX)linux/license/gpl
+EXTRA_CFLAGS += -I$(MALI_INCLUDE_PREFIX)common/pmm
# Source files which always are included in a build
ifeq ($(CONFIG_VIDEO_UMP),y)
@@ -178,11 +213,12 @@ OSKFILES=\
endif #($(CONFIG_VIDEO_UMP),y)
ifeq ($(CONFIG_CPU_EXYNOS4210),y)
- MALI_PLATFORM_FILE = platform/orion-m400/mali_platform.o
+ MALI_PLATFORM_DIR = platform/orion-m400
else
- MALI_PLATFORM_FILE = platform/pegasus-m400/mali_platform.o
+ MALI_PLATFORM_DIR = platform/pegasus-m400
endif #($(CONFIG_CPU_EXYNOS4210),y)
+MALI_PLATFORM_FILE=$(MALI_PLATFORM_DIR)/mali_platform.o
UKKFILES=\
$(FILES_PREFIX)$(OSKOS)/mali_ukk_mem.o \
$(FILES_PREFIX)$(OSKOS)/mali_ukk_gp.o \
@@ -190,85 +226,94 @@ UKKFILES=\
$(FILES_PREFIX)$(OSKOS)/mali_ukk_core.o \
$(FILES_PREFIX)$(OSKOS)/mali_ukk_vsync.o
-mali-y := \
- $(KBUILDROOT)common/mali_kernel_core.o \
- $(KBUILDROOT)linux/mali_kernel_linux.o \
- $(KBUILDROOT)linux/mali_osk_indir_mmap.o \
- $(KBUILDROOT)common/mali_kernel_rendercore.o \
- $(KBUILDROOT)common/mali_kernel_descriptor_mapping.o \
- $(KBUILDROOT)common/mali_kernel_vsync.o \
- $(KBUILDROOT)linux/mali_kernel_sysfs.o \
- $(KBUILDROOT)$(MALI_PLATFORM_FILE) \
- $(KBUILDROOT)$(OSKFILES) \
- $(KBUILDROOT)$(UKKFILES)
- #__malidrv_build_info.o
-
ifeq ($(USING_PROFILING),1)
-EXTRA_CFLAGS += -I$(MALI_FILE_PREFIX)/timestamp-default
-EXTRA_CFLAGS += -I$(MALI_FILE_PREFIX)/profiling/include
-mali-y += \
- common/mali_kernel_profiling.o \
- timestamp-$(TIMESTAMP)/mali_timestamp.o \
- linux/mali_ukk_profiling.o
-
-EXTRA_CFLAGS += -I$(KBUILD_EXTMOD)/timestamp-$(TIMESTAMP)
+UKKFILES += \
+ $(FILES_PREFIX)$(OSKOS)/mali_ukk_profiling.o
endif
-ifeq ($(USING_TRACEPOINTS),1)
-mali-y += \
- linux/mali_osk_profiling.o
-endif
+mali-y := \
+ common/mali_kernel_core.o \
+ linux/mali_kernel_linux.o \
+ $(OSKOS)/mali_osk_indir_mmap.o \
+ common/mali_kernel_descriptor_mapping.o \
+ common/mali_session.o \
+ common/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_cluster.o \
+ common/mali_group.o \
+ common/mali_dlbu.o \
+ common/mali_pm.o \
+ common/mali_pmu.o \
+ common/mali_user_settings_db.o \
+ $(OSKOS)/mali_osk_pm.o \
+ linux/mali_kernel_pm.o \
+ $(OSKOS)/mali_osk_wait_queue.o \
+ $(MALI_PLATFORM_FILE) \
+ $(OSKFILES) \
+ $(UKKFILES)
+# __malidrv_build_info.c
# Selecting files to compile by parsing the config file
-ifeq ($(USING_PMM),1)
-mali-y += \
- common/pmm/mali_pmm.o \
- common/pmm/mali_pmm_policy.o \
- common/pmm/mali_pmm_policy_alwayson.o \
- common/pmm/mali_pmm_policy_jobcontrol.o \
- common/pmm/mali_pmm_state.o \
- linux/mali_kernel_pm.o \
- linux/mali_osk_pm.o \
- linux/mali_device_pause_resume.o
+ifeq ($(USING_INTERNAL_PROFILING),1)
+PROFILING_BACKEND_SOURCES = \
+ linux/mali_osk_profiling_internal.o \
+ timestamp-$(TIMESTAMP)/mali_timestamp.o
+EXTRA_CFLAGS += -I$(MALI_INCLUDE_PREFIX)timestamp-$(TIMESTAMP)
+else
+ifeq ($(USING_PROFILING),1)
+PROFILING_BACKEND_SOURCES = \
+ linux/mali_osk_profiling_gator.o
endif
-ifeq ($(USING_MALI_PMU),1)
-mali-y += \
- common/pmm/mali_pmm_pmu.o
+endif
+
+# Add the profiling sources
+mali-y += $(PROFILING_BACKEND_SOURCES)
+
+# Mali-400 PP in use
+ifeq ($(USING_MALI_PMM_TESTSUITE),1)
+EXTRA_CFLAGS += -I$(MALI_INCLUDE_PREFIX)platform/mali_pmu_testing
endif
ifeq ($(USING_GPU_UTILIZATION),1)
+EXTRA_CFLAGS += -DCONFIG_MALI400_GPU_UTILIZATION=1
+
mali-y += \
common/mali_kernel_utilization.o
endif
-# Mali-400 PP in use
-EXTRA_CFLAGS += -DUSING_MALI400
-mali-y += common/mali_kernel_MALI200.o
-
-# Mali-400 GP in use
-mali-y += common/mali_kernel_GP2.o
+ifeq ($(USING_MALI_DVFS_ENABLED),1)
+mali-y += $(MALI_PLATFORM_DIR)/mali_platform_dvfs.o
+endif #($(USING_MALI_DVFS_ENABLED),1)
-# Mali MMU in use
-mali-y += \
- common/mali_kernel_mem_mmu.o \
- common/mali_kernel_memory_engine.o \
- common/mali_block_allocator.o \
- common/mali_kernel_mem_os.o
+EXTRA_CFLAGS += -DUSING_MALI400
# Mali Level2 cache in use
EXTRA_CFLAGS += -DUSING_MALI400_L2_CACHE
-mali-y += common/mali_kernel_l2_cache.o
-
-ifeq ($(USING_MALI_DVFS_ENABLED),1)
-ifeq ($(CONFIG_CPU_EXYNOS4210),y)
+mali-y += common/mali_l2_cache.o
+# Mali SLP Global lock feature
+ifeq ($(USING_MALI_SLP_GLOBAL_LOCK),1)
mali-y += \
- platform/orion-m400/mali_platform_dvfs.o
-else
-mali-y += \
- platform/pegasus-m400/mali_platform_dvfs.o
-endif #($(CONFIG_CPU_EXYNOS4210),y)
-endif #($(USING_MALI_DVFS_ENABLED),1)
+ linux/mali_slp_global_lock.o
+endif
+
ifeq ($(PANIC_ON_WATCHDOG_TIMEOUT),1)
EXTRA_CFLAGS += -DUSING_KERNEL_PANIC
diff --git a/drivers/media/video/samsung/mali/Makefile.common b/drivers/media/video/samsung/mali/Makefile.common
deleted file mode 100644
index 53d4e5b..0000000
--- a/drivers/media/video/samsung/mali/Makefile.common
+++ /dev/null
@@ -1,59 +0,0 @@
-#
-# 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.
-#
-
-# Check if a Mali Core sub module should be enabled, true or false returned
-submodule_enabled = $(shell gcc $(DEFINES) -E $1/arch/config.h | grep type | grep -c $(2))
-
-OSKFILES=\
- $(FILES_PREFIX)$(OSKOS)/mali_osk_atomics.c \
- $(FILES_PREFIX)$(OSKOS)/mali_osk_irq.c \
- $(FILES_PREFIX)$(OSKOS)/mali_osk_locks.c \
- $(FILES_PREFIX)$(OSKOS)/mali_osk_low_level_mem.c \
- $(FILES_PREFIX)$(OSKOS)/mali_osk_math.c \
- $(FILES_PREFIX)$(OSKOS)/mali_osk_memory.c \
- $(FILES_PREFIX)$(OSKOS)/mali_osk_misc.c \
- $(FILES_PREFIX)$(OSKOS)/mali_osk_mali.c \
- $(FILES_PREFIX)$(OSKOS)/mali_osk_notification.c \
- $(FILES_PREFIX)$(OSKOS)/mali_osk_time.c \
- $(FILES_PREFIX)$(OSKOS)/mali_osk_timers.c
-
-UKKFILES=\
- $(FILES_PREFIX)$(OSKOS)/mali_ukk_mem.c \
- $(FILES_PREFIX)$(OSKOS)/mali_ukk_gp.c \
- $(FILES_PREFIX)$(OSKOS)/mali_ukk_pp.c \
- $(FILES_PREFIX)$(OSKOS)/mali_ukk_core.c
-
-ifeq ($(USING_PROFILING),1)
-UKKFILES+=\
- $(FILES_PREFIX)$(OSKOS)/mali_ukk_profiling.c
-endif
-
-ifeq ($(MALI_PLATFORM_FILE),)
-MALI_PLATFORM_FILE=platform/default/mali_platform.c
-endif
-
-# Get subversion revision number, fall back to only ${MALI_RELEASE_NAME} if no svn info is available
-SVN_REV := $(shell (cd $(DRIVER_DIR); (svnversion | grep -qv exported && svnversion) || git svn info | grep '^Revision: '| sed -e 's/^Revision: //' ) 2>/dev/null )
-ifeq ($(SVN_REV),)
-SVN_REV := $(MALI_RELEASE_NAME)
-else
-SVN_REV := $(MALI_RELEASE_NAME)-r$(SVN_REV)
-endif
-
-# Common version-string, will be extended by OS-specifc sections
-VERSION_STRINGS :=
-VERSION_STRINGS += CONFIG=$(CONFIG)
-VERSION_STRINGS += USING_OS_MEMORY=$(USING_OS_MEMORY)
-VERSION_STRINGS += API_VERSION=$(shell cd $(DRIVER_DIR); grep "\#define _MALI_API_VERSION" $(FILES_PREFIX)common\/mali_uk_types.h | cut -d' ' -f 3 )
-VERSION_STRINGS += REPO_URL=$(shell cd $(DRIVER_DIR); (svn info || git svn info || echo 'URL: $(MALI_RELEASE_NAME)') 2>/dev/null | grep '^URL: ' | cut -d: -f2- | cut -b2-)
-VERSION_STRINGS += REVISION=$(SVN_REV)
-VERSION_STRINGS += CHANGED_REVISION=$(shell cd $(DRIVER_DIR); (svn info || git svn info || echo 'Last Changed Rev: $(MALI_RELEASE_NAME)') 2>/dev/null | grep '^Last Changed Rev: ' | cut -d: -f2- | cut -b2-)
-VERSION_STRINGS += CHANGE_DATE=$(shell cd $(DRIVER_DIR); (svn info || git svn info || echo 'Last Changed Date: $(MALI_RELEASE_NAME)') 2>/dev/null | grep '^Last Changed Date: ' | cut -d: -f2- | cut -b2-)
-VERSION_STRINGS += BUILD_DATE=$(shell date)
diff --git a/drivers/media/video/samsung/mali/Makefile_module b/drivers/media/video/samsung/mali/Makefile_module
new file mode 100644
index 0000000..4fb0226
--- /dev/null
+++ b/drivers/media/video/samsung/mali/Makefile_module
@@ -0,0 +1,89 @@
+#
+# 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
+
+# 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=
+
+# This conditional makefile exports the global definition ARM_INTERNAL_BUILD. Customer releases will not include arm_internal.mak
+-include ../../../arm_internal.mak
+
+# 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
+
+ifeq ($(USING_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
+
+# 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 ?= arm-none-linux-gnueabi-
+endif
+
+# look up KDIR based om CPU selection
+KDIR ?= $(KDIR-$(CPU))
+
+# validate lookup result
+ifeq ($(KDIR),)
+$(error No KDIR found for platform $(CPU))
+endif
+
+# report detected/selected settings
+ifdef ARM_INTERNAL_BUILD
+$(warning Config $(CONFIG))
+$(warning Host CPU $(CPU))
+$(warning OS_MEMORY $(USING_OS_MEMORY))
+endif
+
+# Set up build config
+export CONFIG_MALI400=m
+
+ifeq ($(USING_GPU_UTILIZATION),1)
+export EXTRA_DEFINES += -DCONFIG_MALI400_GPU_UTILIZATION=1
+export CONFIG_MALI400_GPU_UTILIZATION := 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/media/video/samsung/mali/arch b/drivers/media/video/samsung/mali/arch
deleted file mode 120000
index 6154ca4..0000000
--- a/drivers/media/video/samsung/mali/arch
+++ /dev/null
@@ -1 +0,0 @@
-arch-orion-m400 \ No newline at end of file
diff --git a/drivers/media/video/samsung/mali/arch-orion-m400/config.h b/drivers/media/video/samsung/mali/arch-debug/config.h
index 5c4d79d..d5196c3 100644
--- a/drivers/media/video/samsung/mali/arch-orion-m400/config.h
+++ b/drivers/media/video/samsung/mali/arch-debug/config.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 ARM Limited. All rights reserved.
+ * 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.
diff --git a/drivers/media/video/samsung/mali/arch-pb-virtex5-m300/config.h b/drivers/media/video/samsung/mali/arch-pb-virtex5-m300/config.h
new file mode 100644
index 0000000..e579526
--- /dev/null
+++ b/drivers/media/video/samsung/mali/arch-pb-virtex5-m300/config.h
@@ -0,0 +1,85 @@
+/*
+ * 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_H__
+#define __ARCH_CONFIG_H__
+
+/* Configuration for the PB platform with ZBT memory enabled */
+
+static _mali_osk_resource_t arch_configuration [] =
+{
+ {
+ .type = PMU,
+ .description = "Mali-300 PMU",
+ .base = 0xC0002000,
+ .irq = -1,
+ .mmu_id = 0
+
+ },
+ {
+ .type = MALI300GP,
+ .description = "Mali-300 GP",
+ .base = 0xC0000000,
+ .irq = -1,
+ .mmu_id = 1
+ },
+ {
+ .type = MALI300PP,
+ .base = 0xc0008000,
+ .irq = -1,
+ .description = "Mali-300 PP",
+ .mmu_id = 2
+ },
+ {
+ .type = MMU,
+ .base = 0xC0003000,
+ .irq = -1,
+ .description = "Mali-300 MMU for GP",
+ .mmu_id = 1
+ },
+ {
+ .type = MMU,
+ .base = 0xC0004000,
+ .irq = -1,
+ .description = "Mali-300 MMU for PP",
+ .mmu_id = 2
+ },
+ {
+ .type = MEMORY,
+ .description = "Mali SDRAM remapped to baseboard",
+ .cpu_usage_adjust = -0x50000000,
+ .alloc_order = 0, /* Highest preference for this memory */
+ .base = 0xD0000000,
+ .size = 0x10000000,
+ .flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_READABLE | _MALI_PP_WRITEABLE |_MALI_GP_READABLE | _MALI_GP_WRITEABLE
+ },
+ {
+ .type = MEMORY,
+ .description = "Mali ZBT",
+ .alloc_order = 5, /* Medium preference for this memory */
+ .base = 0xe1000000,
+ .size = 0x01000000,
+ .flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_READABLE | _MALI_PP_WRITEABLE |_MALI_GP_READABLE | _MALI_GP_WRITEABLE
+ },
+ {
+ .type = MEM_VALIDATION,
+ .description = "Framebuffer",
+ .base = 0xe0000000,
+ .size = 0x01000000,
+ .flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_WRITEABLE | _MALI_PP_READABLE
+ },
+ {
+ .type = MALI300L2,
+ .base = 0xC0001000,
+ .description = "Mali-300 L2 cache"
+ },
+};
+
+#endif /* __ARCH_CONFIG_H__ */
diff --git a/drivers/media/video/samsung/mali/arch-pb-virtex5-m400-1-direct/config.h b/drivers/media/video/samsung/mali/arch-pb-virtex5-m400-1-direct/config.h
new file mode 100644
index 0000000..3893d72
--- /dev/null
+++ b/drivers/media/video/samsung/mali/arch-pb-virtex5-m400-1-direct/config.h
@@ -0,0 +1,92 @@
+/*
+ * 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_H__
+#define __ARCH_CONFIG_H__
+
+/* Configuration for the PB platform with ZBT memory enabled */
+
+static _mali_osk_resource_t arch_configuration [] =
+{
+
+ {
+ .type = PMU,
+ .description = "Mali-400 PMU",
+ .base = 0xC0002000,
+ .irq = -1,
+ .mmu_id = 0
+ },
+ {
+ .type = MALI400GP,
+ .description = "Mali-400 GP",
+ .base = 0xC0000000,
+ .irq = -1,
+ .mmu_id = 1
+ },
+ {
+ .type = MALI400PP,
+ .base = 0xc0008000,
+ .irq = -1,
+ .description = "Mali-400 PP",
+ .mmu_id = 2
+ },
+ {
+ .type = MMU,
+ .base = 0xC0003000,
+ .irq = -1,
+ .description = "Mali-400 MMU for GP",
+ .mmu_id = 1
+ },
+ {
+ .type = MMU,
+ .base = 0xC0004000,
+ .irq = -1,
+ .description = "Mali-400 MMU for PP",
+ .mmu_id = 2
+ },
+ {
+ .type = OS_MEMORY,
+ .description = "OS Memory",
+ .alloc_order = 10, /* Lowest preference for this memory */
+ .size = 96 * 1024 * 1024, /* 96 MB */
+ .flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_READABLE | _MALI_PP_WRITEABLE |_MALI_GP_READABLE | _MALI_GP_WRITEABLE
+ },
+ {
+ .type = MEMORY,
+ .description = "Mali SDRAM remapped to baseboard",
+ .cpu_usage_adjust = 0,
+ .alloc_order = 5, /* Medium preference for this memory */
+ .base = 0x80000000,
+ .size = 0x10000000,
+ .flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_READABLE | _MALI_PP_WRITEABLE |_MALI_GP_READABLE | _MALI_GP_WRITEABLE
+ },
+ {
+ .type = MEMORY,
+ .description = "Mali ZBT",
+ .alloc_order = 0, /* Highest preference for this memory */
+ .base = 0xe1000000,
+ .size = 0x01000000,
+ .flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_READABLE | _MALI_PP_WRITEABLE |_MALI_GP_READABLE | _MALI_GP_WRITEABLE
+ },
+ {
+ .type = MEM_VALIDATION,
+ .description = "Framebuffer",
+ .base = 0xe0000000,
+ .size = 0x01000000,
+ .flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_WRITEABLE | _MALI_PP_READABLE
+ },
+ {
+ .type = MALI400L2,
+ .base = 0xC0001000,
+ .description = "Mali-400 L2 cache"
+ },
+};
+
+#endif /* __ARCH_CONFIG_H__ */
diff --git a/drivers/media/video/samsung/mali/arch-pb-virtex5-m400-1-pmu/config.h b/drivers/media/video/samsung/mali/arch-pb-virtex5-m400-1-pmu/config.h
new file mode 100644
index 0000000..d85c090
--- /dev/null
+++ b/drivers/media/video/samsung/mali/arch-pb-virtex5-m400-1-pmu/config.h
@@ -0,0 +1,85 @@
+/*
+ * 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 __ARCH_CONFIG_H__
+#define __ARCH_CONFIG_H__
+
+/* Configuration for the PB platform with ZBT memory enabled */
+
+static _mali_osk_resource_t arch_configuration [] =
+{
+ {
+ .type = PMU,
+ .description = "Mali-400 PMU",
+ .base = 0xC0002000,
+ .irq = -1,
+ .mmu_id = 0
+
+ },
+ {
+ .type = MALI400GP,
+ .description = "Mali-400 GP",
+ .base = 0xC0000000,
+ .irq = -1,
+ .mmu_id = 1
+ },
+ {
+ .type = MALI400PP,
+ .base = 0xc0008000,
+ .irq = -1,
+ .description = "Mali-400 PP",
+ .mmu_id = 2
+ },
+ {
+ .type = MMU,
+ .base = 0xC0003000,
+ .irq = -1,
+ .description = "Mali-400 MMU for GP",
+ .mmu_id = 1
+ },
+ {
+ .type = MMU,
+ .base = 0xC0004000,
+ .irq = -1,
+ .description = "Mali-400 MMU for PP",
+ .mmu_id = 2
+ },
+ {
+ .type = MEMORY,
+ .description = "Mali SDRAM remapped to baseboard",
+ .cpu_usage_adjust = -0x50000000,
+ .alloc_order = 0, /* Highest preference for this memory */
+ .base = 0xD0000000,
+ .size = 0x10000000,
+ .flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_READABLE | _MALI_PP_WRITEABLE |_MALI_GP_READABLE | _MALI_GP_WRITEABLE
+ },
+ {
+ .type = MEMORY,
+ .description = "Mali ZBT",
+ .alloc_order = 5, /* Medium preference for this memory */
+ .base = 0xe1000000,
+ .size = 0x01000000,
+ .flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_READABLE | _MALI_PP_WRITEABLE |_MALI_GP_READABLE | _MALI_GP_WRITEABLE
+ },
+ {
+ .type = MEM_VALIDATION,
+ .description = "Framebuffer",
+ .base = 0xe0000000,
+ .size = 0x01000000,
+ .flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_WRITEABLE | _MALI_PP_READABLE
+ },
+ {
+ .type = MALI400L2,
+ .base = 0xC0001000,
+ .description = "Mali-400 L2 cache"
+ },
+};
+
+#endif /* __ARCH_CONFIG_H__ */
diff --git a/drivers/media/video/samsung/mali/arch-pb-virtex5-m400-1/config.h b/drivers/media/video/samsung/mali/arch-pb-virtex5-m400-1/config.h
new file mode 100644
index 0000000..568ac0a
--- /dev/null
+++ b/drivers/media/video/samsung/mali/arch-pb-virtex5-m400-1/config.h
@@ -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.
+ */
+
+#ifndef __ARCH_CONFIG_H__
+#define __ARCH_CONFIG_H__
+
+/* Configuration for the PB platform with ZBT memory enabled */
+
+static _mali_osk_resource_t arch_configuration [] =
+{
+ {
+ .type = MALI400GP,
+ .description = "Mali-400 GP",
+ .base = 0xC0000000,
+ .irq = -1,
+ .mmu_id = 1
+ },
+ {
+ .type = MALI400PP,
+ .base = 0xc0008000,
+ .irq = -1,
+ .description = "Mali-400 PP",
+ .mmu_id = 2
+ },
+ {
+ .type = MMU,
+ .base = 0xC0003000,
+ .irq = -1,
+ .description = "Mali-400 MMU for GP",
+ .mmu_id = 1
+ },
+ {
+ .type = MMU,
+ .base = 0xC0004000,
+ .irq = -1,
+ .description = "Mali-400 MMU for PP",
+ .mmu_id = 2
+ },
+ {
+ .type = MEMORY,
+ .description = "Mali SDRAM remapped to baseboard",
+ .cpu_usage_adjust = -0x50000000,
+ .alloc_order = 0, /* Highest preference for this memory */
+ .base = 0xD0000000,
+ .size = 0x10000000,
+ .flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_READABLE | _MALI_PP_WRITEABLE |_MALI_GP_READABLE | _MALI_GP_WRITEABLE
+ },
+ {
+ .type = MEMORY,
+ .description = "Mali ZBT",
+ .alloc_order = 5, /* Medium preference for this memory */
+ .base = 0xe1000000,
+ .size = 0x01000000,
+ .flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_READABLE | _MALI_PP_WRITEABLE |_MALI_GP_READABLE | _MALI_GP_WRITEABLE
+ },
+ {
+ .type = MEM_VALIDATION,
+ .description = "Framebuffer",
+ .base = 0xe0000000,
+ .size = 0x01000000,
+ .flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_WRITEABLE | _MALI_PP_READABLE
+ },
+ {
+ .type = MALI400L2,
+ .base = 0xC0001000,
+ .description = "Mali-400 L2 cache"
+ },
+};
+
+#endif /* __ARCH_CONFIG_H__ */
diff --git a/drivers/media/video/samsung/mali/arch-pb-virtex5-m400-2/config.h b/drivers/media/video/samsung/mali/arch-pb-virtex5-m400-2/config.h
new file mode 100644
index 0000000..98b8059
--- /dev/null
+++ b/drivers/media/video/samsung/mali/arch-pb-virtex5-m400-2/config.h
@@ -0,0 +1,91 @@
+/*
+ * 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_H__
+#define __ARCH_CONFIG_H__
+
+/* Configuration for the PB platform with ZBT memory enabled */
+
+static _mali_osk_resource_t arch_configuration [] =
+{
+ {
+ .type = MALI400GP,
+ .description = "Mali-400 GP",
+ .base = 0xC0000000,
+ .irq = -1,
+ .mmu_id = 1
+ },
+ {
+ .type = MALI400PP,
+ .base = 0xc0008000,
+ .irq = -1,
+ .description = "Mali-400 PP 0",
+ .mmu_id = 2
+ },
+ {
+ .type = MALI400PP,
+ .base = 0xc000A000,
+ .irq = -1,
+ .description = "Mali-400 PP 1",
+ .mmu_id = 3
+ },
+ {
+ .type = MMU,
+ .base = 0xC0003000,
+ .irq = -1,
+ .description = "Mali-400 MMU for GP",
+ .mmu_id = 1
+ },
+ {
+ .type = MMU,
+ .base = 0xC0004000,
+ .irq = -1,
+ .description = "Mali-400 MMU for PP 0",
+ .mmu_id = 2
+ },
+ {
+ .type = MMU,
+ .base = 0xC0005000,
+ .irq = -1,
+ .description = "Mali-400 MMU for PP 1",
+ .mmu_id = 3
+ },
+ {
+ .type = MEMORY,
+ .description = "Mali SDRAM remapped to baseboard",
+ .cpu_usage_adjust = -0x50000000,
+ .alloc_order = 0, /* Highest preference for this memory */
+ .base = 0xD0000000,
+ .size = 0x10000000,
+ .flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_READABLE | _MALI_PP_WRITEABLE |_MALI_GP_READABLE | _MALI_GP_WRITEABLE
+ },
+ {
+ .type = MEMORY,
+ .description = "Mali ZBT",
+ .alloc_order = 5, /* Medium preference for this memory */
+ .base = 0xe1000000,
+ .size = 0x01000000,
+ .flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_READABLE | _MALI_PP_WRITEABLE |_MALI_GP_READABLE | _MALI_GP_WRITEABLE
+ },
+ {
+ .type = MEM_VALIDATION,
+ .description = "Framebuffer",
+ .base = 0xe0000000,
+ .size = 0x01000000,
+ .flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_WRITEABLE | _MALI_PP_READABLE
+ },
+ {
+ .type = MALI400L2,
+ .base = 0xC0001000,
+ .description = "Mali-400 L2 cache"
+ },
+};
+
+#endif /* __ARCH_CONFIG_H__ */
diff --git a/drivers/media/video/samsung/mali/arch-pb-virtex5-m400-3/config.h b/drivers/media/video/samsung/mali/arch-pb-virtex5-m400-3/config.h
new file mode 100644
index 0000000..7b10925
--- /dev/null
+++ b/drivers/media/video/samsung/mali/arch-pb-virtex5-m400-3/config.h
@@ -0,0 +1,105 @@
+/*
+ * 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_H__
+#define __ARCH_CONFIG_H__
+
+/* Configuration for the PB platform with ZBT memory enabled */
+
+static _mali_osk_resource_t arch_configuration [] =
+{
+ {
+ .type = MALI400GP,
+ .description = "Mali-400 GP",
+ .base = 0xC0000000,
+ .irq = -1,
+ .mmu_id = 1
+ },
+ {
+ .type = MALI400PP,
+ .base = 0xc0008000,
+ .irq = -1,
+ .description = "Mali-400 PP 0",
+ .mmu_id = 2
+ },
+ {
+ .type = MALI400PP,
+ .base = 0xc000A000,
+ .irq = -1,
+ .description = "Mali-400 PP 1",
+ .mmu_id = 3
+ },
+ {
+ .type = MALI400PP,
+ .base = 0xc000C000,
+ .irq = -1,
+ .description = "Mali-400 PP 2",
+ .mmu_id = 4
+ },
+ {
+ .type = MMU,
+ .base = 0xC0003000,
+ .irq = 102,
+ .description = "Mali-400 MMU for GP",
+ .mmu_id = 1
+ },
+ {
+ .type = MMU,
+ .base = 0xC0004000,
+ .irq = 102,
+ .description = "Mali-400 MMU for PP 0",
+ .mmu_id = 2
+ },
+ {
+ .type = MMU,
+ .base = 0xC0005000,
+ .irq = 102,
+ .description = "Mali-400 MMU for PP 1",
+ .mmu_id = 3
+ },
+ {
+ .type = MMU,
+ .base = 0xC0006000,
+ .irq = 102,
+ .description = "Mali-400 MMU for PP 2",
+ .mmu_id = 4
+ },
+ {
+ .type = MEMORY,
+ .description = "Mali SDRAM remapped to baseboard",
+ .cpu_usage_adjust = -0x50000000,
+ .alloc_order = 0, /* Highest preference for this memory */
+ .base = 0xD0000000,
+ .size = 0x10000000,
+ .flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_READABLE | _MALI_PP_WRITEABLE |_MALI_GP_READABLE | _MALI_GP_WRITEABLE
+ },
+ {
+ .type = MEMORY,
+ .description = "Mali ZBT",
+ .alloc_order = 5, /* Medium preference for this memory */
+ .base = 0xe1000000,
+ .size = 0x01000000,
+ .flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_READABLE | _MALI_PP_WRITEABLE |_MALI_GP_READABLE | _MALI_GP_WRITEABLE
+ },
+ {
+ .type = MEM_VALIDATION,
+ .description = "Framebuffer",
+ .base = 0xe0000000,
+ .size = 0x01000000,
+ .flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_WRITEABLE | _MALI_PP_READABLE
+ },
+ {
+ .type = MALI400L2,
+ .base = 0xC0001000,
+ .description = "Mali-400 L2 cache"
+ },
+};
+
+#endif /* __ARCH_CONFIG_H__ */
diff --git a/drivers/media/video/samsung/mali/arch-pb-virtex5-m400-4/config.h b/drivers/media/video/samsung/mali/arch-pb-virtex5-m400-4/config.h
new file mode 100644
index 0000000..a15a6bd
--- /dev/null
+++ b/drivers/media/video/samsung/mali/arch-pb-virtex5-m400-4/config.h
@@ -0,0 +1,119 @@
+/*
+ * 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_H__
+#define __ARCH_CONFIG_H__
+
+/* Configuration for the EB platform with ZBT memory enabled */
+
+static _mali_osk_resource_t arch_configuration [] =
+{
+ {
+ .type = MALI400GP,
+ .description = "Mali-400 GP",
+ .base = 0xC0000000,
+ .irq = -1,
+ .mmu_id = 1
+ },
+ {
+ .type = MALI400PP,
+ .base = 0xc0008000,
+ .irq = -1,
+ .description = "Mali-400 PP 0",
+ .mmu_id = 2
+ },
+ {
+ .type = MALI400PP,
+ .base = 0xc000A000,
+ .irq = -1,
+ .description = "Mali-400 PP 1",
+ .mmu_id = 3
+ },
+ {
+ .type = MALI400PP,
+ .base = 0xc000C000,
+ .irq = -1,
+ .description = "Mali-400 PP 2",
+ .mmu_id = 4
+ },
+ {
+ .type = MALI400PP,
+ .base = 0xc000E000,
+ .irq = -1,
+ .description = "Mali-400 PP 3",
+ .mmu_id = 5
+ },
+ {
+ .type = MMU,
+ .base = 0xC0003000,
+ .irq = 102,
+ .description = "Mali-400 MMU for GP",
+ .mmu_id = 1
+ },
+ {
+ .type = MMU,
+ .base = 0xC0004000,
+ .irq = 102,
+ .description = "Mali-400 MMU for PP 0",
+ .mmu_id = 2
+ },
+ {
+ .type = MMU,
+ .base = 0xC0005000,
+ .irq = 102,
+ .description = "Mali-400 MMU for PP 1",
+ .mmu_id = 3
+ },
+ {
+ .type = MMU,
+ .base = 0xC0006000,
+ .irq = 102,
+ .description = "Mali-400 MMU for PP 2",
+ .mmu_id = 4
+ },
+ {
+ .type = MMU,
+ .base = 0xC0007000,
+ .irq = 102,
+ .description = "Mali-400 MMU for PP 3",
+ .mmu_id = 5
+ },
+ {
+ .type = MEMORY,
+ .description = "Mali SDRAM remapped to baseboard",
+ .cpu_usage_adjust = -0x50000000,
+ .alloc_order = 0, /* Highest preference for this memory */
+ .base = 0xD0000000,
+ .size = 0x10000000,
+ .flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_READABLE | _MALI_PP_WRITEABLE |_MALI_GP_READABLE | _MALI_GP_WRITEABLE
+ },
+ {
+ .type = MEMORY,
+ .description = "Mali ZBT",
+ .alloc_order = 5, /* Medium preference for this memory */
+ .base = 0xe1000000,
+ .size = 0x01000000,
+ .flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_READABLE | _MALI_PP_WRITEABLE |_MALI_GP_READABLE | _MALI_GP_WRITEABLE
+ },
+ {
+ .type = MEM_VALIDATION,
+ .description = "Framebuffer",
+ .base = 0xe0000000,
+ .size = 0x01000000,
+ .flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_WRITEABLE | _MALI_PP_READABLE
+ },
+ {
+ .type = MALI400L2,
+ .base = 0xC0001000,
+ .description = "Mali-400 L2 cache"
+ },
+};
+
+#endif /* __ARCH_CONFIG_H__ */
diff --git a/drivers/media/video/samsung/mali/arch-pegasus-m400/config.h b/drivers/media/video/samsung/mali/arch-pegasus-m400/config.h
new file mode 100644
index 0000000..d5196c3
--- /dev/null
+++ b/drivers/media/video/samsung/mali/arch-pegasus-m400/config.h
@@ -0,0 +1,154 @@
+/*
+ * 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_H__
+#define __ARCH_CONFIG_H__
+
+/* Configuration for the EB platform with ZBT memory enabled */
+/*zepplin added 2010.08.17 for orion configuration*/
+#define MALI_BASE_ADDR 0x13000000
+#define GP_ADDR MALI_BASE_ADDR
+#define L2_ADDR MALI_BASE_ADDR+0x1000
+#define PMU_ADDR MALI_BASE_ADDR+0x2000
+#define GP_MMU_ADDR MALI_BASE_ADDR+0x3000
+#define PP0_MMU_ADDR MALI_BASE_ADDR+0x4000
+#define PP1_MMU_ADDR MALI_BASE_ADDR+0x5000
+#define PP2_MMU_ADDR MALI_BASE_ADDR+0x6000
+#define PP3_MMU_ADDR MALI_BASE_ADDR+0x7000
+#define PP0_ADDR MALI_BASE_ADDR+0x8000
+#define PP1_ADDR MALI_BASE_ADDR+0xA000
+#define PP2_ADDR MALI_BASE_ADDR+0xC000
+#define PP3_ADDR MALI_BASE_ADDR+0xE000
+
+/*for mmu and os memory*/
+#define MEM_BASE_ADDR 0x40000000
+#define MEM_TOTAL_SIZE 0x40000000
+#define MEM_MALI_OS_SIZE 0x40000000
+
+/*for dedicated memory*/
+//#define MEM_MALI_BASE 0x58000000
+//#define MEM_MALI_SIZE 0x08000000
+#define MEM_MALI_SIZE CONFIG_MALI_MEM_SIZE*1024*1024
+#define MEM_MALI_BASE 0x80000000 - MEM_MALI_SIZE
+
+static _mali_osk_resource_t arch_configuration [] =
+{
+ {
+ .type = MALI400GP,
+ .description = "Mali-400 GP",
+ .base = GP_ADDR,
+ .irq = IRQ_GP_3D,
+ .mmu_id = 1
+ },
+ {
+ .type = MALI400PP,
+ .base = PP0_ADDR,
+ .irq = IRQ_PP0_3D,
+ .description = "Mali-400 PP 0",
+ .mmu_id = 2
+ },
+ {
+ .type = MALI400PP,
+ .base = PP1_ADDR,
+ .irq = IRQ_PP1_3D,
+ .description = "Mali-400 PP 1",
+ .mmu_id = 3
+ },
+ {
+ .type = MALI400PP,
+ .base = PP2_ADDR,
+ .irq = IRQ_PP2_3D,
+ .description = "Mali-400 PP 2",
+ .mmu_id = 4
+ },
+ {
+ .type = MALI400PP,
+ .base = PP3_ADDR,
+ .irq = IRQ_PP3_3D,
+ .description = "Mali-400 PP 3",
+ .mmu_id = 5
+ },
+#if USING_MMU
+ {
+ .type = MMU,
+ .base = GP_MMU_ADDR,
+ .irq = IRQ_GPMMU_3D,
+ .description = "Mali-400 MMU for GP",
+ .mmu_id = 1
+ },
+ {
+ .type = MMU,
+ .base = PP0_MMU_ADDR,
+ .irq = IRQ_PPMMU0_3D,
+ .description = "Mali-400 MMU for PP 0",
+ .mmu_id = 2
+ },
+ {
+ .type = MMU,
+ .base = PP1_MMU_ADDR,
+ .irq = IRQ_PPMMU1_3D,
+ .description = "Mali-400 MMU for PP 1",
+ .mmu_id = 3
+ },
+ {
+ .type = MMU,
+ .base = PP2_MMU_ADDR,
+ .irq = IRQ_PPMMU2_3D,
+ .description = "Mali-400 MMU for PP 2",
+ .mmu_id = 4
+ },
+ {
+ .type = MMU,
+ .base = PP3_MMU_ADDR,
+ .irq = IRQ_PPMMU3_3D,
+ .description = "Mali-400 MMU for PP 3",
+ .mmu_id = 5
+ },
+#if USING_OS_MEMORY
+ {
+ .type = OS_MEMORY,
+ .description = "System Memory",
+ .size = MEM_MALI_OS_SIZE,
+ .flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_READABLE | _MALI_PP_WRITEABLE | _MALI_GP_READABLE | _MALI_GP_WRITEABLE
+ },
+#endif
+#if USING_DED /* Dedicated Memory */
+ {
+ .type = MEMORY,
+ .description = "Dedicated Memory",
+ .base = MEM_MALI_BASE,
+ .size = MEM_MALI_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
+ },
+#endif/* if USING_OS_MEMORY*/
+ {
+ .type = MEM_VALIDATION,
+ .description = "memory validation",
+ .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
+ },
+#else /* Not using MMU */
+ {
+ .type = MEMORY,
+ .description = "Dedicated Memory",
+ .base = MEM_MALI_BASE,
+ .size = MEM_MALI_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
+ },
+#endif
+ {
+ .type = MALI400L2,
+ .base = L2_ADDR,
+ .description = "Mali-400 L2 cache"
+ },
+};
+
+#endif /* __ARCH_CONFIG_H__ */
diff --git a/drivers/media/video/samsung/mali/arch-release/config.h b/drivers/media/video/samsung/mali/arch-release/config.h
new file mode 100644
index 0000000..d5196c3
--- /dev/null
+++ b/drivers/media/video/samsung/mali/arch-release/config.h
@@ -0,0 +1,154 @@
+/*
+ * 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_H__
+#define __ARCH_CONFIG_H__
+
+/* Configuration for the EB platform with ZBT memory enabled */
+/*zepplin added 2010.08.17 for orion configuration*/
+#define MALI_BASE_ADDR 0x13000000
+#define GP_ADDR MALI_BASE_ADDR
+#define L2_ADDR MALI_BASE_ADDR+0x1000
+#define PMU_ADDR MALI_BASE_ADDR+0x2000
+#define GP_MMU_ADDR MALI_BASE_ADDR+0x3000
+#define PP0_MMU_ADDR MALI_BASE_ADDR+0x4000
+#define PP1_MMU_ADDR MALI_BASE_ADDR+0x5000
+#define PP2_MMU_ADDR MALI_BASE_ADDR+0x6000
+#define PP3_MMU_ADDR MALI_BASE_ADDR+0x7000
+#define PP0_ADDR MALI_BASE_ADDR+0x8000
+#define PP1_ADDR MALI_BASE_ADDR+0xA000
+#define PP2_ADDR MALI_BASE_ADDR+0xC000
+#define PP3_ADDR MALI_BASE_ADDR+0xE000
+
+/*for mmu and os memory*/
+#define MEM_BASE_ADDR 0x40000000
+#define MEM_TOTAL_SIZE 0x40000000
+#define MEM_MALI_OS_SIZE 0x40000000
+
+/*for dedicated memory*/
+//#define MEM_MALI_BASE 0x58000000
+//#define MEM_MALI_SIZE 0x08000000
+#define MEM_MALI_SIZE CONFIG_MALI_MEM_SIZE*1024*1024
+#define MEM_MALI_BASE 0x80000000 - MEM_MALI_SIZE
+
+static _mali_osk_resource_t arch_configuration [] =
+{
+ {
+ .type = MALI400GP,
+ .description = "Mali-400 GP",
+ .base = GP_ADDR,
+ .irq = IRQ_GP_3D,
+ .mmu_id = 1
+ },
+ {
+ .type = MALI400PP,
+ .base = PP0_ADDR,
+ .irq = IRQ_PP0_3D,
+ .description = "Mali-400 PP 0",
+ .mmu_id = 2
+ },
+ {
+ .type = MALI400PP,
+ .base = PP1_ADDR,
+ .irq = IRQ_PP1_3D,
+ .description = "Mali-400 PP 1",
+ .mmu_id = 3
+ },
+ {
+ .type = MALI400PP,
+ .base = PP2_ADDR,
+ .irq = IRQ_PP2_3D,
+ .description = "Mali-400 PP 2",
+ .mmu_id = 4
+ },
+ {
+ .type = MALI400PP,
+ .base = PP3_ADDR,
+ .irq = IRQ_PP3_3D,
+ .description = "Mali-400 PP 3",
+ .mmu_id = 5
+ },
+#if USING_MMU
+ {
+ .type = MMU,
+ .base = GP_MMU_ADDR,
+ .irq = IRQ_GPMMU_3D,
+ .description = "Mali-400 MMU for GP",
+ .mmu_id = 1
+ },
+ {
+ .type = MMU,
+ .base = PP0_MMU_ADDR,
+ .irq = IRQ_PPMMU0_3D,
+ .description = "Mali-400 MMU for PP 0",
+ .mmu_id = 2
+ },
+ {
+ .type = MMU,
+ .base = PP1_MMU_ADDR,
+ .irq = IRQ_PPMMU1_3D,
+ .description = "Mali-400 MMU for PP 1",
+ .mmu_id = 3
+ },
+ {
+ .type = MMU,
+ .base = PP2_MMU_ADDR,
+ .irq = IRQ_PPMMU2_3D,
+ .description = "Mali-400 MMU for PP 2",
+ .mmu_id = 4
+ },
+ {
+ .type = MMU,
+ .base = PP3_MMU_ADDR,
+ .irq = IRQ_PPMMU3_3D,
+ .description = "Mali-400 MMU for PP 3",
+ .mmu_id = 5
+ },
+#if USING_OS_MEMORY
+ {
+ .type = OS_MEMORY,
+ .description = "System Memory",
+ .size = MEM_MALI_OS_SIZE,
+ .flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_READABLE | _MALI_PP_WRITEABLE | _MALI_GP_READABLE | _MALI_GP_WRITEABLE
+ },
+#endif
+#if USING_DED /* Dedicated Memory */
+ {
+ .type = MEMORY,
+ .description = "Dedicated Memory",
+ .base = MEM_MALI_BASE,
+ .size = MEM_MALI_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
+ },
+#endif/* if USING_OS_MEMORY*/
+ {
+ .type = MEM_VALIDATION,
+ .description = "memory validation",
+ .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
+ },
+#else /* Not using MMU */
+ {
+ .type = MEMORY,
+ .description = "Dedicated Memory",
+ .base = MEM_MALI_BASE,
+ .size = MEM_MALI_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
+ },
+#endif
+ {
+ .type = MALI400L2,
+ .base = L2_ADDR,
+ .description = "Mali-400 L2 cache"
+ },
+};
+
+#endif /* __ARCH_CONFIG_H__ */
diff --git a/drivers/media/video/samsung/mali/arch-ve-virtex6-m450-8/config.h b/drivers/media/video/samsung/mali/arch-ve-virtex6-m450-8/config.h
new file mode 100644
index 0000000..9b38f35
--- /dev/null
+++ b/drivers/media/video/samsung/mali/arch-ve-virtex6-m450-8/config.h
@@ -0,0 +1,168 @@
+/*
+ * 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_H__
+#define __ARCH_CONFIG_H__
+
+/* Configuration for the Versatile Express platform */
+
+#define MALI_BASE_ADDRESS 0xFC040000
+
+static _mali_osk_resource_t arch_configuration [] =
+{
+ /* GP cluster */
+ {
+ .type = MALI400L2,
+ .base = MALI_BASE_ADDRESS + 0x10000,
+ .description = "Mali-450 L2 cache for GP"
+ },
+ {
+ .type = MALI400GP,
+ .description = "Mali-450 GP",
+ .base = MALI_BASE_ADDRESS,
+ .irq = -1,
+ },
+ {
+ .type = MMU,
+ .base = MALI_BASE_ADDRESS + 0x3000,
+ .irq = 70,
+ .description = "Mali-450 MMU for GP",
+ },
+
+ /* PP0-3 cluster */
+ {
+ .type = MALI400L2,
+ .base = MALI_BASE_ADDRESS + 0x1000,
+ .description = "Mali-450 L2 cache for PP0-3"
+ },
+ {
+ .type = MALI400PP,
+ .base = MALI_BASE_ADDRESS + 0x8000,
+ .irq = 70,
+ .description = "Mali-450 PP0",
+ },
+ {
+ .type = MMU,
+ .base = MALI_BASE_ADDRESS + 0x4000,
+ .irq = 70,
+ .description = "Mali-450 MMU for PP0",
+ },
+ {
+ .type = MALI400PP,
+ .base = MALI_BASE_ADDRESS + 0xA000,
+ .irq = 70,
+ .description = "Mali-450 PP1",
+ },
+ {
+ .type = MMU,
+ .base = MALI_BASE_ADDRESS + 0x5000,
+ .irq = 70,
+ .description = "Mali-450 MMU for PP1",
+ },
+ {
+ .type = MALI400PP,
+ .base = MALI_BASE_ADDRESS + 0xC000,
+ .irq = 70,
+ .description = "Mali-450 PP2",
+ },
+ {
+ .type = MMU,
+ .base = MALI_BASE_ADDRESS + 0x6000,
+ .irq = 70,
+ .description = "Mali-450 MMU for PP2",
+ },
+ {
+ .type = MALI400PP,
+ .base = MALI_BASE_ADDRESS + 0xE000,
+ .irq = 70,
+ .description = "Mali-450 PP3",
+ },
+ {
+ .type = MMU,
+ .base = MALI_BASE_ADDRESS + 0x7000,
+ .irq = 70,
+ .description = "Mali-450 MMU for PP3",
+ },
+
+ /* PP4-7 cluster */
+ {
+ .type = MALI400L2,
+ .base = MALI_BASE_ADDRESS + 0x11000,
+ .description = "Mali-450 L2 cache for PP4-7"
+ },
+ {
+ .type = MALI400PP,
+ .base = MALI_BASE_ADDRESS + 0x28000,
+ .irq = 70,
+ .description = "Mali-450 PP4",
+ },
+ {
+ .type = MMU,
+ .base = MALI_BASE_ADDRESS + 0x1C000,
+ .irq = 70,
+ .description = "Mali-450 MMU for PP4",
+ },
+ {
+ .type = MALI400PP,
+ .base = MALI_BASE_ADDRESS + 0x2A000,
+ .irq = 70,
+ .description = "Mali-450 PP5",
+ },
+ {
+ .type = MMU,
+ .base = MALI_BASE_ADDRESS + 0x1D000,
+ .irq = 70,
+ .description = "Mali-450 MMU for PP5",
+ },
+ {
+ .type = MALI400PP,
+ .base = MALI_BASE_ADDRESS + 0x2C000,
+ .irq = 70,
+ .description = "Mali-450 PP6",
+ },
+ {
+ .type = MMU,
+ .base = MALI_BASE_ADDRESS + 0x1E000,
+ .irq = 70,
+ .description = "Mali-450 MMU for PP6",
+ },
+ {
+ .type = MALI400PP,
+ .base = MALI_BASE_ADDRESS + 0x2E000,
+ .irq = 70,
+ .description = "Mali-450 PP7",
+ },
+ {
+ .type = MMU,
+ .base = MALI_BASE_ADDRESS + 0x1F000,
+ .irq = 70,
+ .description = "Mali-450 MMU for PP7",
+ },
+
+ /* Memory */
+ {
+ .type = OS_MEMORY,
+ .description = "Mali OS memory",
+ .cpu_usage_adjust = 0,
+ .alloc_order = 0, /* Highest preference for this memory */
+ .base = 0x0,
+ .size = 256 * 1024 * 1024,
+ .flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_READABLE | _MALI_PP_WRITEABLE |_MALI_GP_READABLE | _MALI_GP_WRITEABLE
+ },
+ {
+ .type = MEM_VALIDATION,
+ .description = "Framebuffer",
+ .base = 0xe0000000,
+ .size = 0x01000000,
+ .flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_WRITEABLE | _MALI_PP_READABLE
+ },
+};
+
+#endif /* __ARCH_CONFIG_H__ */
diff --git a/drivers/media/video/samsung/mali/arch/config.h b/drivers/media/video/samsung/mali/arch/config.h
new file mode 100644
index 0000000..d5196c3
--- /dev/null
+++ b/drivers/media/video/samsung/mali/arch/config.h
@@ -0,0 +1,154 @@
+/*
+ * 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_H__
+#define __ARCH_CONFIG_H__
+
+/* Configuration for the EB platform with ZBT memory enabled */
+/*zepplin added 2010.08.17 for orion configuration*/
+#define MALI_BASE_ADDR 0x13000000
+#define GP_ADDR MALI_BASE_ADDR
+#define L2_ADDR MALI_BASE_ADDR+0x1000
+#define PMU_ADDR MALI_BASE_ADDR+0x2000
+#define GP_MMU_ADDR MALI_BASE_ADDR+0x3000
+#define PP0_MMU_ADDR MALI_BASE_ADDR+0x4000
+#define PP1_MMU_ADDR MALI_BASE_ADDR+0x5000
+#define PP2_MMU_ADDR MALI_BASE_ADDR+0x6000
+#define PP3_MMU_ADDR MALI_BASE_ADDR+0x7000
+#define PP0_ADDR MALI_BASE_ADDR+0x8000
+#define PP1_ADDR MALI_BASE_ADDR+0xA000
+#define PP2_ADDR MALI_BASE_ADDR+0xC000
+#define PP3_ADDR MALI_BASE_ADDR+0xE000
+
+/*for mmu and os memory*/
+#define MEM_BASE_ADDR 0x40000000
+#define MEM_TOTAL_SIZE 0x40000000
+#define MEM_MALI_OS_SIZE 0x40000000
+
+/*for dedicated memory*/
+//#define MEM_MALI_BASE 0x58000000
+//#define MEM_MALI_SIZE 0x08000000
+#define MEM_MALI_SIZE CONFIG_MALI_MEM_SIZE*1024*1024
+#define MEM_MALI_BASE 0x80000000 - MEM_MALI_SIZE
+
+static _mali_osk_resource_t arch_configuration [] =
+{
+ {
+ .type = MALI400GP,
+ .description = "Mali-400 GP",
+ .base = GP_ADDR,
+ .irq = IRQ_GP_3D,
+ .mmu_id = 1
+ },
+ {
+ .type = MALI400PP,
+ .base = PP0_ADDR,
+ .irq = IRQ_PP0_3D,
+ .description = "Mali-400 PP 0",
+ .mmu_id = 2
+ },
+ {
+ .type = MALI400PP,
+ .base = PP1_ADDR,
+ .irq = IRQ_PP1_3D,
+ .description = "Mali-400 PP 1",
+ .mmu_id = 3
+ },
+ {
+ .type = MALI400PP,
+ .base = PP2_ADDR,
+ .irq = IRQ_PP2_3D,
+ .description = "Mali-400 PP 2",
+ .mmu_id = 4
+ },
+ {
+ .type = MALI400PP,
+ .base = PP3_ADDR,
+ .irq = IRQ_PP3_3D,
+ .description = "Mali-400 PP 3",
+ .mmu_id = 5
+ },
+#if USING_MMU
+ {
+ .type = MMU,
+ .base = GP_MMU_ADDR,
+ .irq = IRQ_GPMMU_3D,
+ .description = "Mali-400 MMU for GP",
+ .mmu_id = 1
+ },
+ {
+ .type = MMU,
+ .base = PP0_MMU_ADDR,
+ .irq = IRQ_PPMMU0_3D,
+ .description = "Mali-400 MMU for PP 0",
+ .mmu_id = 2
+ },
+ {
+ .type = MMU,
+ .base = PP1_MMU_ADDR,
+ .irq = IRQ_PPMMU1_3D,
+ .description = "Mali-400 MMU for PP 1",
+ .mmu_id = 3
+ },
+ {
+ .type = MMU,
+ .base = PP2_MMU_ADDR,
+ .irq = IRQ_PPMMU2_3D,
+ .description = "Mali-400 MMU for PP 2",
+ .mmu_id = 4
+ },
+ {
+ .type = MMU,
+ .base = PP3_MMU_ADDR,
+ .irq = IRQ_PPMMU3_3D,
+ .description = "Mali-400 MMU for PP 3",
+ .mmu_id = 5
+ },
+#if USING_OS_MEMORY
+ {
+ .type = OS_MEMORY,
+ .description = "System Memory",
+ .size = MEM_MALI_OS_SIZE,
+ .flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_READABLE | _MALI_PP_WRITEABLE | _MALI_GP_READABLE | _MALI_GP_WRITEABLE
+ },
+#endif
+#if USING_DED /* Dedicated Memory */
+ {
+ .type = MEMORY,
+ .description = "Dedicated Memory",
+ .base = MEM_MALI_BASE,
+ .size = MEM_MALI_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
+ },
+#endif/* if USING_OS_MEMORY*/
+ {
+ .type = MEM_VALIDATION,
+ .description = "memory validation",
+ .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
+ },
+#else /* Not using MMU */
+ {
+ .type = MEMORY,
+ .description = "Dedicated Memory",
+ .base = MEM_MALI_BASE,
+ .size = MEM_MALI_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
+ },
+#endif
+ {
+ .type = MALI400L2,
+ .base = L2_ADDR,
+ .description = "Mali-400 L2 cache"
+ },
+};
+
+#endif /* __ARCH_CONFIG_H__ */
diff --git a/drivers/media/video/samsung/mali/common/mali_block_allocator.c b/drivers/media/video/samsung/mali/common/mali_block_allocator.c
index 5f421f0..269e662 100644
--- a/drivers/media/video/samsung/mali/common/mali_block_allocator.c
+++ b/drivers/media/video/samsung/mali/common/mali_block_allocator.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 ARM Limited. All rights reserved.
+ * 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.
@@ -76,7 +76,7 @@ mali_physical_memory_allocator * mali_block_allocator_create(u32 base_address, u
info = _mali_osk_malloc(sizeof(block_allocator));
if (NULL != info)
{
- info->mutex = _mali_osk_lock_init( _MALI_OSK_LOCKFLAG_ORDERED, 0, 105);
+ 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);
@@ -355,7 +355,7 @@ static void block_allocator_release_page_table_block( mali_page_table_block *pag
_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 unnecssary for page table block releasing. */
+ * Probably unnecessary for page table block releasing. */
while (block)
{
next = block->next;
diff --git a/drivers/media/video/samsung/mali/common/mali_cluster.c b/drivers/media/video/samsung/mali/common/mali_cluster.c
new file mode 100644
index 0000000..f0fb2b6
--- /dev/null
+++ b/drivers/media/video/samsung/mali/common/mali_cluster.c
@@ -0,0 +1,218 @@
+/*
+ * 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_cluster.h"
+#include "mali_osk.h"
+#include "mali_group.h"
+#include "mali_l2_cache.h"
+#include "mali_scheduler.h"
+
+static struct mali_cluster *mali_global_clusters[MALI_MAX_NUMBER_OF_CLUSTERS] = { NULL, NULL, NULL };
+static u32 mali_global_num_clusters = 0;
+
+/**
+ * The structure represents a render cluster
+ * A render cluster is defined by all the cores that share the same Mali L2 cache
+ */
+struct mali_cluster
+{
+ struct mali_l2_cache_core *l2;
+ u32 number_of_groups;
+ struct mali_group* groups[MALI_MAX_NUMBER_OF_GROUPS_PER_CLUSTER];
+ u32 last_invalidated_id;
+ mali_bool power_is_enabled;
+};
+
+struct mali_cluster *mali_cluster_create(struct mali_l2_cache_core *l2_cache)
+{
+ struct mali_cluster *cluster = NULL;
+
+ if (mali_global_num_clusters >= MALI_MAX_NUMBER_OF_CLUSTERS)
+ {
+ MALI_PRINT_ERROR(("Mali cluster: Too many cluster objects created\n"));
+ return NULL;
+ }
+
+ cluster = _mali_osk_malloc(sizeof(struct mali_cluster));
+ if (NULL != cluster)
+ {
+ _mali_osk_memset(cluster, 0, sizeof(struct mali_cluster));
+ cluster->l2 = l2_cache; /* This cluster now owns this L2 cache object */
+ cluster->last_invalidated_id = 0;
+ cluster->power_is_enabled = MALI_TRUE;
+
+ mali_global_clusters[mali_global_num_clusters] = cluster;
+ mali_global_num_clusters++;
+
+ return cluster;
+ }
+
+ return NULL;
+}
+
+void mali_cluster_power_is_enabled_set(struct mali_cluster * cluster, mali_bool power_is_enabled)
+{
+ cluster->power_is_enabled = power_is_enabled;
+}
+
+mali_bool mali_cluster_power_is_enabled_get(struct mali_cluster * cluster)
+{
+ return cluster->power_is_enabled;
+}
+
+
+void mali_cluster_add_group(struct mali_cluster *cluster, struct mali_group *group)
+{
+ MALI_DEBUG_ASSERT_POINTER(cluster);
+
+ if (cluster->number_of_groups < MALI_MAX_NUMBER_OF_GROUPS_PER_CLUSTER)
+ {
+ /* This cluster now owns the group object */
+ cluster->groups[cluster->number_of_groups] = group;
+ cluster->number_of_groups++;
+ }
+}
+
+void mali_cluster_delete(struct mali_cluster *cluster)
+{
+ u32 i;
+
+ MALI_DEBUG_ASSERT_POINTER(cluster);
+
+ /* Free all the resources we own */
+ for (i = 0; i < cluster->number_of_groups; i++)
+ {
+ mali_group_delete(cluster->groups[i]);
+ }
+
+ if (NULL != cluster->l2)
+ {
+ mali_l2_cache_delete(cluster->l2);
+ }
+
+ for (i = 0; i < mali_global_num_clusters; i++)
+ {
+ if (mali_global_clusters[i] == cluster)
+ {
+ mali_global_clusters[i] = NULL;
+ mali_global_num_clusters--;
+ break;
+ }
+ }
+
+ _mali_osk_free(cluster);
+}
+
+void mali_cluster_reset(struct mali_cluster *cluster)
+{
+ u32 i;
+
+ MALI_DEBUG_ASSERT_POINTER(cluster);
+
+ /* Free all the resources we own */
+ for (i = 0; i < cluster->number_of_groups; i++)
+ {
+ struct mali_group *group = cluster->groups[i];
+
+ mali_group_reset(group);
+ }
+
+ if (NULL != cluster->l2)
+ {
+ mali_l2_cache_reset(cluster->l2);
+ }
+}
+
+struct mali_l2_cache_core* mali_cluster_get_l2_cache_core(struct mali_cluster *cluster)
+{
+ MALI_DEBUG_ASSERT_POINTER(cluster);
+ return cluster->l2;
+}
+
+struct mali_group *mali_cluster_get_group(struct mali_cluster *cluster, u32 index)
+{
+ MALI_DEBUG_ASSERT_POINTER(cluster);
+
+ if (index < cluster->number_of_groups)
+ {
+ return cluster->groups[index];
+ }
+
+ return NULL;
+}
+
+struct mali_cluster *mali_cluster_get_global_cluster(u32 index)
+{
+ if (MALI_MAX_NUMBER_OF_CLUSTERS > index)
+ {
+ return mali_global_clusters[index];
+ }
+
+ return NULL;
+}
+
+u32 mali_cluster_get_glob_num_clusters(void)
+{
+ return mali_global_num_clusters;
+}
+
+mali_bool mali_cluster_l2_cache_invalidate_all(struct mali_cluster *cluster, u32 id)
+{
+ MALI_DEBUG_ASSERT_POINTER(cluster);
+
+ if (NULL != cluster->l2)
+ {
+ /* 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)cluster->last_invalidated_id))
+ {
+ return MALI_FALSE;
+ }
+ else
+ {
+ cluster->last_invalidated_id = mali_scheduler_get_new_id();
+ }
+
+ mali_l2_cache_invalidate_all(cluster->l2);
+ }
+ return MALI_TRUE;
+}
+
+void mali_cluster_l2_cache_invalidate_all_force(struct mali_cluster *cluster)
+{
+ MALI_DEBUG_ASSERT_POINTER(cluster);
+
+ if (NULL != cluster->l2)
+ {
+ cluster->last_invalidated_id = mali_scheduler_get_new_id();
+ mali_l2_cache_invalidate_all(cluster->l2);
+ }
+}
+
+void mali_cluster_invalidate_pages(u32 *pages, u32 num_pages)
+{
+ u32 i;
+
+ for (i = 0; i < mali_global_num_clusters; i++)
+ {
+ /*additional check for cluster*/
+ if (MALI_TRUE == mali_l2_cache_lock_power_state(mali_global_clusters[i]->l2))
+ {
+ mali_l2_cache_invalidate_pages(mali_global_clusters[i]->l2, pages, num_pages);
+ }
+ mali_l2_cache_unlock_power_state(mali_global_clusters[i]->l2);
+ /*check for failed power locking???*/
+ }
+}
diff --git a/drivers/media/video/samsung/mali/common/mali_cluster.h b/drivers/media/video/samsung/mali/common/mali_cluster.h
new file mode 100644
index 0000000..33debdb
--- /dev/null
+++ b/drivers/media/video/samsung/mali/common/mali_cluster.h
@@ -0,0 +1,44 @@
+/*
+ * 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_CLUSTER_H__
+#define __MALI_CLUSTER_H__
+
+#include "mali_osk.h"
+#include "mali_l2_cache.h"
+
+/* Maximum 1 GP and 4 PP for a cluster (Mali-400 Quad-core) */
+#define MALI_MAX_NUMBER_OF_GROUPS_PER_CLUSTER 5
+#define MALI_MAX_NUMBER_OF_CLUSTERS 3
+
+struct mali_cluster;
+struct mali_group;
+
+struct mali_cluster *mali_cluster_create(struct mali_l2_cache_core *l2_cache);
+void mali_cluster_add_group(struct mali_cluster *cluster, struct mali_group *group);
+void mali_cluster_delete(struct mali_cluster *cluster);
+
+void mali_cluster_power_is_enabled_set(struct mali_cluster * cluster, mali_bool power_is_enabled);
+mali_bool mali_cluster_power_is_enabled_get(struct mali_cluster * cluster);
+
+void mali_cluster_reset(struct mali_cluster *cluster);
+
+struct mali_l2_cache_core* mali_cluster_get_l2_cache_core(struct mali_cluster *cluster);
+struct mali_group *mali_cluster_get_group(struct mali_cluster *cluster, u32 index);
+
+struct mali_cluster *mali_cluster_get_global_cluster(u32 index);
+u32 mali_cluster_get_glob_num_clusters(void);
+
+/* Returns MALI_TRUE if it did the flush */
+mali_bool mali_cluster_l2_cache_invalidate_all(struct mali_cluster *cluster, u32 id);
+void mali_cluster_l2_cache_invalidate_all_force(struct mali_cluster *cluster);
+void mali_cluster_invalidate_pages(u32 *pages, u32 num_pages);
+
+#endif /* __MALI_CLUSTER_H__ */
diff --git a/drivers/media/video/samsung/mali/common/mali_device_pause_resume.c b/drivers/media/video/samsung/mali/common/mali_device_pause_resume.c
new file mode 100644
index 0000000..6af1279
--- /dev/null
+++ b/drivers/media/video/samsung/mali/common/mali_device_pause_resume.c
@@ -0,0 +1,46 @@
+/**
+ * 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 "mali_gp_scheduler.h"
+#include "mali_pp_scheduler.h"
+#include "mali_pm.h"
+
+void mali_dev_pause(mali_bool *power_is_on)
+{
+ mali_gp_scheduler_suspend();
+ mali_pp_scheduler_suspend();
+
+ /*
+ * Take and hold the PM lock to be sure we don't change power state as well.
+ * (it might be unsafe to for instance change frequency if Mali GPU is powered off)
+ */
+ mali_pm_execute_state_change_lock();
+ if (NULL != power_is_on)
+ {
+ *power_is_on = mali_pm_is_powered_on();
+ }
+}
+
+void mali_dev_resume(void)
+{
+ mali_pm_execute_state_change_unlock();
+ mali_gp_scheduler_resume();
+ mali_pp_scheduler_resume();
+}
+
+/*
+EXPORT_SYMBOL(mali_dev_pause);
+EXPORT_SYMBOL(mali_dev_resume);
+*/
diff --git a/drivers/media/video/samsung/mali/common/mali_device_pause_resume.h b/drivers/media/video/samsung/mali/common/mali_device_pause_resume.h
new file mode 100644
index 0000000..6be75b0
--- /dev/null
+++ b/drivers/media/video/samsung/mali/common/mali_device_pause_resume.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.
+ */
+
+#ifndef __MALI_DEVICE_PAUSE_RESUME_H__
+#define __MALI_DEVICE_PAUSE_RESUME_H__
+
+#include "mali_osk.h"
+
+/**
+ * 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.
+ *
+ * @param power_is_on Receives the power current status of Mali GPU. MALI_TRUE if GPU is powered on
+ */
+void mali_dev_pause(mali_bool *power_is_on);
+
+/**
+ * Resume scheduling and allow power changes in Mali device driver.
+ * This must always be called after mali_dev_pause().
+ */
+void mali_dev_resume(void);
+
+#endif /* __MALI_DEVICE_PAUSE_RESUME_H__ */
diff --git a/drivers/media/video/samsung/mali/common/mali_dlbu.c b/drivers/media/video/samsung/mali/common/mali_dlbu.c
new file mode 100644
index 0000000..fcc51fa
--- /dev/null
+++ b/drivers/media/video/samsung/mali/common/mali_dlbu.c
@@ -0,0 +1,285 @@
+/*
+ * 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;
+
+static u32 mali_dlbu_tile_position;
+
+/**
+ * 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, ("Dynamic Load Balancing Unit 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))
+ {
+ if (_MALI_OSK_ERR_OK == mali_dlbu_reset(core))
+ {
+ mali_hw_core_register_write(&core->hw_core, MALI_DLBU_REGISTER_MASTER_TLLIST_VADDR, MALI_DLB_VIRT_ADDR);
+
+ 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_dlbu_reset(dlbu);
+ mali_hw_core_delete(&dlbu->hw_core);
+ _mali_osk_free(dlbu);
+}
+
+void mali_dlbu_enable(struct mali_dlbu_core *dlbu)
+{
+ u32 wval = mali_hw_core_register_read(&dlbu->hw_core, MALI_DLBU_REGISTER_MASTER_TLLIST_PHYS_ADDR);
+
+ wval |= 0x1;
+ mali_hw_core_register_write(&dlbu->hw_core, MALI_DLBU_REGISTER_MASTER_TLLIST_PHYS_ADDR, wval);
+}
+
+void mali_dlbu_disable(struct mali_dlbu_core *dlbu)
+{
+ u32 wval = mali_hw_core_register_read(&dlbu->hw_core, MALI_DLBU_REGISTER_MASTER_TLLIST_PHYS_ADDR);
+
+ wval |= (wval & 0xFFFFFFFE);
+ mali_hw_core_register_write(&dlbu->hw_core, MALI_DLBU_REGISTER_MASTER_TLLIST_PHYS_ADDR, wval);
+}
+
+_mali_osk_errcode_t mali_dlbu_enable_pp_core(struct mali_dlbu_core *dlbu, u32 pp_core_enable, u32 val)
+{
+ u32 wval = mali_hw_core_register_read(&dlbu->hw_core, MALI_DLBU_REGISTER_PP_ENABLE_MASK);
+
+ if((pp_core_enable < mali_pp_get_glob_num_pp_cores()) && ((0 == val) || (1 == val))) /* check for valid input parameters */
+ {
+ if (val == 1)
+ {
+ val = (wval | (pp_core_enable <<= 0x1));
+ }
+ if (val == 0)
+ {
+ val = (wval & ~(pp_core_enable << 0x1));
+ }
+ wval |= val;
+ mali_hw_core_register_write(&dlbu->hw_core, MALI_DLBU_REGISTER_PP_ENABLE_MASK, wval);
+ dlbu->pp_cores_mask = wval;
+
+ return _MALI_OSK_ERR_OK;
+ }
+
+ return _MALI_OSK_ERR_FAULT;
+}
+
+void mali_dlbu_enable_all_pp_cores(struct mali_dlbu_core *dlbu)
+{
+ mali_hw_core_register_write(&dlbu->hw_core, MALI_DLBU_REGISTER_PP_ENABLE_MASK, dlbu->pp_cores_mask);
+}
+
+void mali_dlbu_disable_all_pp_cores(struct mali_dlbu_core *dlbu)
+{
+ mali_hw_core_register_write(&dlbu->hw_core, MALI_DLBU_REGISTER_PP_ENABLE_MASK, 0x0);
+}
+
+void mali_dlbu_setup(struct mali_dlbu_core *dlbu, u8 fb_xdim, u8 fb_ydim, u8 xtilesize, u8 ytilesize, u8 blocksize, u8 xgr0, u8 ygr0, u8 xgr1, u8 ygr1)
+{
+ u32 wval = 0x0;
+
+ /* write the framebuffer dimensions */
+ wval = (16 << (u32)fb_ydim) | (u32)fb_xdim;
+ mali_hw_core_register_write(&dlbu->hw_core, MALI_DLBU_REGISTER_FB_DIM, wval);
+
+ /* write the tile list configuration */
+ wval = 0x0;
+ wval = (28 << (u32)blocksize) | (16 << (u32)ytilesize) | ((u32)xtilesize);
+ mali_hw_core_register_write(&dlbu->hw_core, MALI_DLBU_REGISTER_TLLIST_CONF, wval);
+
+ /* write the start tile position */
+ wval = 0x0;
+ wval = (24 << (u32)ygr1 | (16 << (u32)xgr1) | 8 << (u32)ygr0) | (u32)xgr0;
+ mali_hw_core_register_write(&dlbu->hw_core, MALI_DLBU_REGISTER_START_TILE_POS, wval);
+}
+
+_mali_osk_errcode_t mali_dlbu_reset(struct mali_dlbu_core *dlbu)
+{
+ _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));
+
+ mali_hw_core_register_write(&dlbu->hw_core, MALI_DLBU_REGISTER_MASTER_TLLIST_PHYS_ADDR, mali_dlbu_phys_addr);
+ mali_hw_core_register_write(&dlbu->hw_core, MALI_DLBU_REGISTER_TLLIST_VBASEADDR, 0x00);
+ mali_hw_core_register_write(&dlbu->hw_core, MALI_DLBU_REGISTER_FB_DIM, 0x00);
+ mali_hw_core_register_write(&dlbu->hw_core, MALI_DLBU_REGISTER_TLLIST_CONF, 0x00);
+ mali_hw_core_register_write(&dlbu->hw_core, MALI_DLBU_REGISTER_START_TILE_POS, 0x00);
+
+ mali_hw_core_register_write(&dlbu->hw_core, MALI_DLBU_REGISTER_PP_ENABLE_MASK, dlbu->pp_cores_mask);
+
+ err = _MALI_OSK_ERR_OK;
+
+ return err;
+}
+
+_mali_osk_errcode_t mali_dlbu_add_group(struct mali_dlbu_core *dlbu, struct mali_group *group)
+{
+ _mali_osk_errcode_t err = _MALI_OSK_ERR_FAULT;
+ u32 wval, rval;
+ struct mali_pp_core *pp_core = mali_group_get_pp_core(group);
+
+ /* find the core id and set the mask */
+
+ if (NULL != pp_core)
+ {
+ wval = mali_pp_core_get_id(pp_core);
+ rval = mali_hw_core_register_read(&dlbu->hw_core, MALI_DLBU_REGISTER_PP_ENABLE_MASK);
+ mali_hw_core_register_write(&dlbu->hw_core, MALI_DLBU_REGISTER_PP_ENABLE_MASK, (wval << 0x1) | rval);
+ err = _MALI_OSK_ERR_OK;
+ }
+
+ return err;
+}
+
+void mali_dlbu_set_tllist_base_address(struct mali_dlbu_core *dlbu, u32 val)
+{
+ mali_hw_core_register_write(&dlbu->hw_core, MALI_DLBU_REGISTER_TLLIST_VBASEADDR, val);
+}
+
+void mali_dlbu_pp_jobs_stop(struct mali_dlbu_core *dlbu)
+{
+ /* this function to implement (see documentation):
+ * 1) clear all bits in the enable register
+ * 2) wait until all PPs have finished - mali_pp_scheduler.c code - this done in interrupts call?
+ * 3) read the current tile position registers to get current tile positions -
+ * note that current tile position register is the same as start tile position - perhaps the name should be changed!!! */
+
+ /* 1) */
+ mali_dlbu_disable_all_pp_cores(dlbu);
+
+ /* 3) */
+ mali_dlbu_tile_position = mali_hw_core_register_read(&dlbu->hw_core, MALI_DLBU_REGISTER_START_TILE_POS);
+}
+
+void mali_dlbu_pp_jobs_restart(struct mali_dlbu_core *dlbu)
+{
+ /* this function to implement (see the document):
+ * 1) configure the dynamic load balancing unit as normal
+ * 2) set the current tile position registers as read when stopping the job
+ * 3) configure the PPs to start the job as normal - done by another part of the system - scheduler */
+
+ /* 1) */
+ mali_dlbu_reset(dlbu);
+ /* ++ setup the needed values - see this */
+
+ /* 2) */
+ mali_hw_core_register_write(&dlbu->hw_core, MALI_DLBU_REGISTER_START_TILE_POS, mali_dlbu_tile_position);
+}
diff --git a/drivers/media/video/samsung/mali/common/mali_dlbu.h b/drivers/media/video/samsung/mali/common/mali_dlbu.h
new file mode 100644
index 0000000..e3c3b9d
--- /dev/null
+++ b/drivers/media/video/samsung/mali/common/mali_dlbu.h
@@ -0,0 +1,45 @@
+/*
+ * 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__
+
+#include "mali_osk.h"
+#include "mali_group.h"
+
+#define MALI_DLB_VIRT_ADDR 0xFFF00000 /* master tile virtual address fixed at this value and mapped into every session */
+
+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);
+
+void mali_dlbu_enable(struct mali_dlbu_core *dlbu);
+void mali_dlbu_disable(struct mali_dlbu_core *dlbu);
+
+_mali_osk_errcode_t mali_dlbu_enable_pp_core(struct mali_dlbu_core *dlbu, u32 pp_core_enable, u32 val);
+void mali_dlbu_enable_all_pp_cores(struct mali_dlbu_core *dlbu);
+void mali_dlbu_disable_all_pp_cores(struct mali_dlbu_core *dlbu);
+
+_mali_osk_errcode_t mali_dlbu_reset(struct mali_dlbu_core *dlbu);
+void mali_dlbu_setup(struct mali_dlbu_core *dlbu, u8 fb_xdim, u8 fb_ydim, u8 xtilesize, u8 ytilesize, u8 blocksize, u8 xgr0, u8 ygr0, u8 xgr1, u8 ygr1);
+
+_mali_osk_errcode_t mali_dlbu_add_group(struct mali_dlbu_core *dlbu, struct mali_group *group);
+void mali_dlbu_set_tllist_base_address(struct mali_dlbu_core *dlbu, u32 val);
+
+void mali_dlbu_pp_jobs_stop(struct mali_dlbu_core *dlbu);
+void mali_dlbu_pp_jobs_restart(struct mali_dlbu_core *dlbu);
+
+#endif /* __MALI_DLBU_H__ */
diff --git a/drivers/media/video/samsung/mali/common/mali_gp.c b/drivers/media/video/samsung/mali/common/mali_gp.c
new file mode 100644
index 0000000..d03721c
--- /dev/null
+++ b/drivers/media/video/samsung/mali/common/mali_gp.c
@@ -0,0 +1,693 @@
+/*
+ * 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 MALI_TIMELINE_PROFILING_ENABLED
+#include "mali_osk_profiling.h"
+#endif
+
+/**
+ * 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 */
+ struct mali_group *group; /**< Parent group for this core */
+ _mali_osk_irq_t *irq; /**< IRQ handler */
+ struct mali_gp_job *running_job; /**< Current running job */
+ _mali_osk_timer_t *timeout_timer; /**< timeout timer for this core */
+ u32 timeout_job_id; /**< job id for the timed out job - relevant only if gp_core_timed_out == MALI_TRUE */
+ mali_bool core_timed_out; /**< if MALI_TRUE, this gp core has timed out; if MALI_FALSE, no timeout on this gp core */
+ 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 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 */
+};
+
+static struct mali_gp_core *mali_global_gp_core = NULL;
+
+/* Interrupt handlers */
+static _mali_osk_errcode_t mali_gp_upper_half(void *data);
+static void mali_gp_bottom_half(void *data);
+static void mali_gp_irq_probe_trigger(void *data);
+static _mali_osk_errcode_t mali_gp_irq_probe_ack(void *data);
+static void mali_gp_post_process_job(struct mali_gp_core *core, mali_bool suspend);
+static void mali_gp_timeout(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->group = group;
+ core->running_job = NULL;
+ core->counter_src0 = MALI_HW_CORE_NO_COUNTER;
+ core->counter_src1 = MALI_HW_CORE_NO_COUNTER;
+ 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;
+
+ mali_group_lock(group);
+ ret = mali_gp_reset(core);
+ mali_group_unlock(group);
+
+ 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_gp_upper_half,
+ mali_gp_bottom_half,
+ mali_gp_irq_probe_trigger,
+ mali_gp_irq_probe_ack,
+ core,
+ "mali_gp_irq_handlers");
+ if (NULL != core->irq)
+ {
+ /* Initialise the timeout timer */
+ core->timeout_timer = _mali_osk_timer_init();
+ if(NULL != core->timeout_timer)
+ {
+ _mali_osk_timer_setcallback(core->timeout_timer, mali_gp_timeout, (void *)core);
+ 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(("Failed to setup timeout timer for GP core %s\n", core->hw_core.description));
+ /* Release IRQ handlers */
+ _mali_osk_irq_term(core->irq);
+ }
+ }
+ else
+ {
+ MALI_PRINT_ERROR(("Failed to setup interrupt handlers for GP core %s\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_timer_term(core->timeout_timer);
+ _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;
+ const int request_loop_count = 20;
+
+ 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 < request_loop_count; i++)
+ {
+ if (mali_hw_core_register_read(&core->hw_core, MALIGP2_REG_ADDR_MGMT_STATUS) & MALIGP2_REG_VAL_STATUS_BUS_STOPPED)
+ {
+ break;
+ }
+ _mali_osk_time_ubusydelay(10);
+ }
+
+ if (request_loop_count == 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 int reset_finished_loop_count = 15;
+ 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_ASSERT_GROUP_LOCKED(core->group);
+
+ mali_gp_post_process_job(core, MALI_FALSE);
+
+ 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 < reset_finished_loop_count; 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 (i == reset_finished_loop_count)
+ {
+ 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);
+
+}
+
+_mali_osk_errcode_t mali_gp_reset(struct mali_gp_core *core)
+{
+ int i;
+ const int request_loop_count = 20;
+
+ MALI_DEBUG_ASSERT_POINTER(core);
+ MALI_DEBUG_PRINT(4, ("Mali GP: Reset of core %s\n", core->hw_core.description));
+ MALI_ASSERT_GROUP_LOCKED(core->group);
+
+ mali_gp_post_process_job(core, MALI_FALSE);
+
+ mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_MASK, 0); /* disable the IRQs */
+
+#if defined(USING_MALI200)
+
+ /* On Mali-200, stop the bus, then do a hard reset of the core */
+
+ mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_CMD, MALIGP2_REG_VAL_CMD_STOP_BUS);
+
+ for (i = 0; i < request_loop_count; i++)
+ {
+ if (mali_hw_core_register_read(&core->hw_core, MALIGP2_REG_ADDR_MGMT_STATUS) & MALIGP2_REG_VAL_STATUS_BUS_STOPPED)
+ {
+ break;
+ }
+ _mali_osk_time_ubusydelay(10);
+ }
+
+ if (request_loop_count == i)
+ {
+ MALI_PRINT_ERROR(("Mali GP: Failed to stop bus for core %s, unable to recover\n", core->hw_core.description));
+ return _MALI_OSK_ERR_FAULT;
+ }
+
+ /* the bus was stopped OK, do the hard reset */
+ mali_gp_hard_reset(core);
+
+#elif defined(USING_MALI400)
+
+ /* Mali-300 and Mali-400 have a safe reset command which we use */
+
+ 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);
+
+ for (i = 0; i < request_loop_count; i++)
+ {
+ if (mali_hw_core_register_read(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_RAWSTAT) & MALI400GP_REG_VAL_IRQ_RESET_COMPLETED)
+ {
+ break;
+ }
+ _mali_osk_time_ubusydelay(10);
+ }
+
+ if (request_loop_count == i)
+ {
+ MALI_PRINT_ERROR(("Mali GP: Failed to reset core %s, unable to recover\n", core->hw_core.description));
+ return _MALI_OSK_ERR_FAULT;
+ }
+#else
+#error "no supported mali core defined"
+#endif
+
+ /* 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;
+}
+
+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 = core->counter_src0;
+ core->counter_src1_used = core->counter_src1;
+
+ MALI_DEBUG_ASSERT_POINTER(core);
+ MALI_ASSERT_GROUP_LOCKED(core->group);
+
+ 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);
+
+ /* This selects which performance counters we are reading */
+ if (MALI_HW_CORE_NO_COUNTER != core->counter_src0_used || MALI_HW_CORE_NO_COUNTER != core->counter_src0_used)
+ {
+ /* global_config has enabled HW counters, this will override anything specified by user space */
+ 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);
+ }
+ }
+ else
+ {
+ /* Use HW counters from job object, if any */
+ u32 perf_counter_flag = mali_gp_job_get_perf_counter_flag(job);
+ if (0 != perf_counter_flag)
+ {
+ if (perf_counter_flag & _MALI_PERFORMANCE_COUNTER_FLAG_SRC0_ENABLE)
+ {
+ core->counter_src0_used = mali_gp_job_get_perf_counter_src0(job);
+ 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 (perf_counter_flag & _MALI_PERFORMANCE_COUNTER_FLAG_SRC1_ENABLE)
+ {
+ core->counter_src1_used = mali_gp_job_get_perf_counter_src1(job);
+ 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();
+
+ /* Setup the timeout timer value and save the job id for the job running on the gp core */
+
+ _mali_osk_timer_add(core->timeout_timer, _mali_osk_time_mstoticks(mali_max_job_runtime));
+ core->timeout_job_id = mali_gp_job_get_id(job);
+
+#if MALI_TIMELINE_PROFILING_ENABLED
+ _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE | MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(0) | MALI_PROFILING_EVENT_REASON_SINGLE_HW_FLUSH,
+ job->frame_builder_id, job->flush_id, 0, 0, 0);
+ _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_START|MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(0), job->pid, job->tid, 0, 0, 0);
+#endif
+
+ core->running_job = job;
+}
+
+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);
+ MALI_ASSERT_GROUP_LOCKED(core->group);
+
+ 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();
+
+#if MALI_TIMELINE_PROFILING_ENABLED
+ _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_RESUME|MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(0), 0, 0, 0, 0, 0);
+#endif
+ }
+ /*
+ * 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.
+ */
+}
+
+void mali_gp_abort_job(struct mali_gp_core *core)
+{
+ MALI_DEBUG_ASSERT_POINTER(core);
+ MALI_ASSERT_GROUP_LOCKED(core->group);
+
+ if (_MALI_OSK_ERR_FAULT != mali_gp_reset(core))
+ {
+ _mali_osk_timer_del(core->timeout_timer);
+ }
+}
+
+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);
+}
+
+mali_bool mali_gp_core_set_counter_src0(struct mali_gp_core *core, u32 counter)
+{
+ MALI_DEBUG_ASSERT_POINTER(core);
+
+ core->counter_src0 = counter;
+ return MALI_TRUE;
+}
+
+mali_bool mali_gp_core_set_counter_src1(struct mali_gp_core *core, u32 counter)
+{
+ MALI_DEBUG_ASSERT_POINTER(core);
+
+ core->counter_src1 = counter;
+ return MALI_TRUE;
+}
+
+u32 mali_gp_core_get_counter_src0(struct mali_gp_core *core)
+{
+ MALI_DEBUG_ASSERT_POINTER(core);
+ return core->counter_src0;
+}
+
+u32 mali_gp_core_get_counter_src1(struct mali_gp_core *core)
+{
+ MALI_DEBUG_ASSERT_POINTER(core);
+ return core->counter_src1;
+}
+
+struct mali_gp_core *mali_gp_get_global_gp_core(void)
+{
+ return mali_global_gp_core;
+}
+
+/* ------------- interrupt handling below ------------------ */
+static _mali_osk_errcode_t mali_gp_upper_half(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_MASK_NONE != irq_readout)
+ {
+ /* Mask out all IRQs from this core until IRQ is handled */
+ mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_MASK, MALIGP2_REG_VAL_IRQ_MASK_NONE);
+
+#if MALI_TIMELINE_PROFILING_ENABLED
+ _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);
+#endif
+
+ /* We do need to handle this in a bottom half */
+ _mali_osk_irq_schedulework(core->irq);
+ return _MALI_OSK_ERR_OK;
+ }
+
+ return _MALI_OSK_ERR_FAULT;
+}
+
+static void mali_gp_bottom_half(void *data)
+{
+ struct mali_gp_core *core = (struct mali_gp_core *)data;
+ u32 irq_readout;
+ u32 irq_errors;
+
+#if MALI_TIMELINE_PROFILING_ENABLED
+#if 0 /* Bottom half TLP logging is currently not supported */
+ _mali_osk_profiling_add_event( MALI_PROFILING_EVENT_TYPE_START| MALI_PROFILING_EVENT_CHANNEL_SOFTWARE , _mali_osk_get_pid(), _mali_osk_get_tid()+11000, 0, 0, 0);
+#endif
+#endif
+
+ mali_group_lock(core->group); /* Group lock grabbed in core handlers, but released in common group handler */
+
+ if ( MALI_FALSE == mali_group_power_is_on(core->group) )
+ {
+ MALI_PRINT_ERROR(("Interrupt bottom half of %s when core is OFF.", core->hw_core.description));
+ mali_group_unlock(core->group);
+ return;
+ }
+
+ irq_readout = mali_hw_core_register_read(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_RAWSTAT) & MALIGP2_REG_VAL_IRQ_MASK_USED;
+ MALI_DEBUG_PRINT(4, ("Mali GP: Bottom half IRQ 0x%08X from core %s\n", irq_readout, core->hw_core.description));
+
+ if (irq_readout & (MALIGP2_REG_VAL_IRQ_VS_END_CMD_LST|MALIGP2_REG_VAL_IRQ_PLBU_END_CMD_LST))
+ {
+ u32 core_status = mali_hw_core_register_read(&core->hw_core, MALIGP2_REG_ADDR_MGMT_STATUS);
+ if (0 == (core_status & MALIGP2_REG_VAL_STATUS_MASK_ACTIVE))
+ {
+ mali_gp_post_process_job(core, MALI_FALSE);
+ MALI_DEBUG_PRINT(4, ("Mali GP: Job completed, calling group handler\n"));
+ mali_group_bottom_half(core->group, GROUP_EVENT_GP_JOB_COMPLETED); /* Will release group lock */
+ 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_gp_post_process_job(core, MALI_FALSE);
+ MALI_PRINT_ERROR(("Mali GP: Unknown interrupt 0x%08X from core %s, aborting job\n", irq_readout, core->hw_core.description));
+ mali_group_bottom_half(core->group, GROUP_EVENT_GP_JOB_FAILED); /* Will release group lock */
+ return;
+ }
+ else if (MALI_TRUE == core->core_timed_out) /* SW timeout */
+ {
+ if (core->timeout_job_id == mali_gp_job_get_id(core->running_job))
+ {
+ mali_gp_post_process_job(core, MALI_FALSE);
+ MALI_DEBUG_PRINT(2, ("Mali GP: Job %d timed out\n", mali_gp_job_get_id(core->running_job)));
+ mali_group_bottom_half(core->group, GROUP_EVENT_GP_JOB_TIMED_OUT);
+ }
+ core->core_timed_out = MALI_FALSE;
+ return;
+ }
+ else if (irq_readout & MALIGP2_REG_VAL_IRQ_PLBU_OUT_OF_MEM)
+ {
+ /* GP wants more memory in order to continue.
+ *
+ * This must be handled prior to HANG because this actually can
+ * generate a HANG while waiting for more memory.
+ * And it must be handled before the completion interrupts,
+ * since the PLBU can run out of memory after VS is complete;
+ * in which case the OOM must be handled before to complete the
+ * PLBU work.
+ */
+ mali_gp_post_process_job(core, MALI_TRUE);
+ MALI_DEBUG_PRINT(3, ("Mali GP: PLBU needs more heap memory\n"));
+ mali_group_bottom_half(core->group, GROUP_EVENT_GP_OOM); /* Will release group lock */
+ return;
+ }
+ else if (irq_readout & MALIGP2_REG_VAL_IRQ_HANG)
+ {
+ /* Just ignore hang interrupts, the job timer will detect hanging jobs anyways */
+ mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_CLEAR, MALIGP2_REG_VAL_IRQ_HANG);
+ }
+
+ /*
+ * The only way to get here is if we got a HANG interrupt, which we ignore, or only one of two needed END_CMD_LST interrupts.
+ * Re-enable interrupts and let core continue to run.
+ */
+ mali_hw_core_register_write(&core->hw_core, MALIGP2_REG_ADDR_MGMT_INT_MASK, MALIGP2_REG_VAL_IRQ_MASK_USED);
+ mali_group_unlock(core->group);
+
+#if MALI_TIMELINE_PROFILING_ENABLED
+#if 0 /* Bottom half TLP logging is currently not supported */
+ _mali_osk_profiling_add_event( MALI_PROFILING_EVENT_TYPE_STOP| MALI_PROFILING_EVENT_CHANNEL_SOFTWARE , _mali_osk_get_pid(), _mali_osk_get_tid()+11000, 0, 0, 0);
+#endif
+#endif
+}
+
+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); /* @@@@ This should not be needed */
+ 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 --------- */
+
+static void mali_gp_post_process_job(struct mali_gp_core *core, mali_bool suspend)
+{
+ MALI_ASSERT_GROUP_LOCKED(core->group);
+
+ if (NULL != core->running_job)
+ {
+ u32 val0 = 0;
+ u32 val1 = 0;
+#if MALI_TIMELINE_PROFILING_ENABLED
+ u32 event_id;
+#endif
+
+ 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);
+ if (mali_gp_job_get_perf_counter_flag(core->running_job) &&
+ _MALI_PERFORMANCE_COUNTER_FLAG_SRC0_ENABLE && mali_gp_job_get_perf_counter_src0(core->running_job) == core->counter_src0_used)
+ {
+ /* We retrieved the counter that user space asked for, so return the value through the job object */
+ mali_gp_job_set_perf_counter_value0(core->running_job, val0);
+ }
+ else
+ {
+ /* User space asked for a counter, but this is not what we retrived (overridden by counter src set on core) */
+ mali_gp_job_set_perf_counter_value0(core->running_job, MALI_HW_CORE_INVALID_VALUE);
+ }
+
+#if MALI_TIMELINE_PROFILING_ENABLED
+ _mali_osk_profiling_report_hw_counter(COUNTER_VP_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);
+ if (mali_gp_job_get_perf_counter_flag(core->running_job) &&
+ _MALI_PERFORMANCE_COUNTER_FLAG_SRC1_ENABLE && mali_gp_job_get_perf_counter_src1(core->running_job) == core->counter_src1_used)
+ {
+ /* We retrieved the counter that user space asked for, so return the value through the job object */
+ mali_gp_job_set_perf_counter_value1(core->running_job, val1);
+ }
+ else
+ {
+ /* User space asked for a counter, but this is not what we retrieved (overridden by counter src set on core) */
+ mali_gp_job_set_perf_counter_value1(core->running_job, MALI_HW_CORE_INVALID_VALUE);
+ }
+
+#if MALI_TIMELINE_PROFILING_ENABLED
+ _mali_osk_profiling_report_hw_counter(COUNTER_VP_C1, val1);
+#endif
+ }
+
+#if MALI_TIMELINE_PROFILING_ENABLED
+ if (MALI_TRUE == suspend)
+ {
+ event_id = MALI_PROFILING_EVENT_TYPE_SUSPEND|MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(0);
+ }
+ else
+ {
+ event_id = MALI_PROFILING_EVENT_TYPE_STOP|MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(0);
+ }
+ _mali_osk_profiling_add_event(event_id, val0, val1, core->counter_src0_used | (core->counter_src1_used << 8), 0, 0);
+#endif
+
+ mali_gp_job_set_current_heap_addr(core->running_job,
+ mali_hw_core_register_read(&core->hw_core, MALIGP2_REG_ADDR_MGMT_PLBU_ALLOC_START_ADDR));
+
+ if (MALI_TRUE != suspend)
+ {
+ /* We are no longer running a job... */
+ core->running_job = NULL;
+ _mali_osk_timer_del(core->timeout_timer);
+ }
+ }
+}
+
+/* callback function for gp core timeout */
+static void mali_gp_timeout(void *data)
+{
+ struct mali_gp_core * core = ((struct mali_gp_core *)data);
+
+ MALI_DEBUG_PRINT(3, ("Mali GP: TIMEOUT callback \n"));
+ core->core_timed_out = MALI_TRUE;
+ _mali_osk_irq_schedulework(core->irq);
+}
+
+#if 0
+void mali_gp_print_state(struct mali_gp_core *core)
+{
+ MALI_DEBUG_PRINT(2, ("Mali GP: State: 0x%08x\n", mali_hw_core_register_read(&core->hw_core, MALIGP2_REG_ADDR_MGMT_STATUS) ));
+}
+#endif
+
+#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
diff --git a/drivers/media/video/samsung/mali/common/mali_gp.h b/drivers/media/video/samsung/mali/common/mali_gp.h
new file mode 100644
index 0000000..3175b75
--- /dev/null
+++ b/drivers/media/video/samsung/mali/common/mali_gp.h
@@ -0,0 +1,46 @@
+/*
+ * 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"
+
+struct mali_gp_core;
+struct mali_group;
+
+_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_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);
+
+void mali_gp_abort_job(struct mali_gp_core *core);
+
+u32 mali_gp_core_get_version(struct mali_gp_core *core);
+
+mali_bool mali_gp_core_set_counter_src0(struct mali_gp_core *core, u32 counter);
+mali_bool mali_gp_core_set_counter_src1(struct mali_gp_core *core, u32 counter);
+u32 mali_gp_core_get_counter_src0(struct mali_gp_core *core);
+u32 mali_gp_core_get_counter_src1(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);
+
+#endif /* __MALI_GP_H__ */
diff --git a/drivers/media/video/samsung/mali/common/mali_gp_job.c b/drivers/media/video/samsung/mali/common/mali_gp_job.c
new file mode 100644
index 0000000..abe1d93
--- /dev/null
+++ b/drivers/media/video/samsung/mali/common/mali_gp_job.c
@@ -0,0 +1,49 @@
+/*
+ * 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"
+
+struct mali_gp_job *mali_gp_job_create(struct mali_session_data *session, _mali_uk_gp_start_job_s *args, u32 id)
+{
+ struct mali_gp_job *job;
+
+ job = _mali_osk_malloc(sizeof(struct mali_gp_job));
+ if (NULL != job)
+ {
+ _mali_osk_list_init(&job->list);
+ job->session = session;
+ job->id = id;
+ job->user_id = args->user_job_ptr;
+ _mali_osk_memcpy(job->frame_registers, args->frame_registers, sizeof(job->frame_registers));
+ job->heap_current_addr = args->frame_registers[4];
+ job->perf_counter_flag = args->perf_counter_flag;
+ job->perf_counter_src0 = args->perf_counter_src0;
+ job->perf_counter_src1 = args->perf_counter_src1;
+ job->perf_counter_value0 = 0;
+ job->perf_counter_value1 = 0;
+
+ job->pid = _mali_osk_get_pid();
+ job->tid = _mali_osk_get_tid();
+ job->frame_builder_id = args->frame_builder_id;
+ job->flush_id = args->flush_id;
+
+ return job;
+ }
+
+ return NULL;
+}
+
+void mali_gp_job_delete(struct mali_gp_job *job)
+{
+ _mali_osk_free(job);
+}
diff --git a/drivers/media/video/samsung/mali/common/mali_gp_job.h b/drivers/media/video/samsung/mali/common/mali_gp_job.h
new file mode 100644
index 0000000..9c29f1c
--- /dev/null
+++ b/drivers/media/video/samsung/mali/common/mali_gp_job.h
@@ -0,0 +1,131 @@
+/*
+ * 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 represends a GP job, including all sub-jobs
+ * (This struct unfortunatly 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 */
+ u32 id; /**< identifier for this job in kernel space (sequential numbering) */
+ u32 user_id; /**< identifier for the job in user space */
+ u32 frame_registers[MALIGP2_NUM_REGS_FRAME]; /**< core specific registers associated with this job, see ARM DDI0415A */
+ u32 heap_current_addr; /**< Holds the current HEAP address when the job has completed */
+ u32 perf_counter_flag; /**< bitmask indicating which performance counters to enable, see \ref _MALI_PERFORMANCE_COUNTER_FLAG_SRC0_ENABLE and related macro definitions */
+ u32 perf_counter_src0; /**< source id for performance counter 0 (see ARM DDI0415A, Table 3-60) */
+ u32 perf_counter_src1; /**< source id for performance counter 1 (see ARM DDI0415A, Table 3-60) */
+ 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 */
+ u32 frame_builder_id; /**< id of the originating frame builder */
+ u32 flush_id; /**< flush id within the originating frame builder */
+};
+
+struct mali_gp_job *mali_gp_job_create(struct mali_session_data *session, _mali_uk_gp_start_job_s *args, u32 id);
+void mali_gp_job_delete(struct mali_gp_job *job);
+
+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->user_id;
+}
+
+MALI_STATIC_INLINE u32 mali_gp_job_get_frame_builder_id(struct mali_gp_job *job)
+{
+ return job->frame_builder_id;
+}
+
+MALI_STATIC_INLINE u32 mali_gp_job_get_flush_id(struct mali_gp_job *job)
+{
+ return job->flush_id;
+}
+
+MALI_STATIC_INLINE u32* mali_gp_job_get_frame_registers(struct mali_gp_job *job)
+{
+ return job->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->frame_registers[0] != job->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->frame_registers[2] != job->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->perf_counter_flag;
+}
+
+MALI_STATIC_INLINE u32 mali_gp_job_get_perf_counter_src0(struct mali_gp_job *job)
+{
+ return job->perf_counter_src0;
+}
+
+MALI_STATIC_INLINE u32 mali_gp_job_get_perf_counter_src1(struct mali_gp_job *job)
+{
+ return job->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_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/media/video/samsung/mali/common/mali_gp_scheduler.c b/drivers/media/video/samsung/mali/common/mali_gp_scheduler.c
new file mode 100644
index 0000000..05f00fc
--- /dev/null
+++ b/drivers/media/video/samsung/mali/common/mali_gp_scheduler.c
@@ -0,0 +1,438 @@
+/*
+ * 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_cluster.h"
+
+enum mali_gp_slot_state
+{
+ MALI_GP_SLOT_STATE_IDLE,
+ MALI_GP_SLOT_STATE_WORKING,
+};
+
+/* 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 _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 i;
+
+ _MALI_OSK_INIT_LIST_HEAD(&job_queue);
+
+ gp_scheduler_lock = _mali_osk_lock_init(_MALI_OSK_LOCKFLAG_ORDERED | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE, 0, _MALI_OSK_LOCK_ORDER_SCHEDULER);
+ gp_scheduler_working_wait_queue = _mali_osk_wait_queue_init();
+
+ if (NULL == gp_scheduler_lock)
+ {
+ return _MALI_OSK_ERR_NOMEM;
+ }
+
+ 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 */
+ for (i = 0; i < mali_cluster_get_glob_num_clusters(); i++)
+ {
+ u32 group_id = 0;
+ struct mali_cluster *curr_cluster = mali_cluster_get_global_cluster(i);
+ struct mali_group *group = mali_cluster_get_group(curr_cluster, group_id);
+ while (NULL != group)
+ {
+ 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 are only one GP, no point in looking for more */
+ }
+ group_id++;
+ group = mali_cluster_get_group(curr_cluster, group_id);
+ }
+ }
+
+ return _MALI_OSK_ERR_OK;
+}
+
+void mali_gp_scheduler_terminate(void)
+{
+ _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_ASSERT_GP_SCHEDULER_LOCKED();
+
+ 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));
+ return; /* Nothing to do, so early out */
+ }
+
+ job = _MALI_OSK_LIST_ENTRY(job_queue.next, struct mali_gp_job, list);
+
+ MALI_DEBUG_PRINT(3, ("Mali GP scheduler: Starting job %u (0x%08X)\n", mali_gp_job_get_id(job), job));
+ if (_MALI_OSK_ERR_OK == mali_group_start_gp_job(slot.group, job))
+ {
+ /* Mark slot as busy */
+ slot.state = MALI_GP_SLOT_STATE_WORKING;
+
+ /* Remove from queue of unscheduled jobs */
+ _mali_osk_list_del(&job->list);
+ }
+ else
+ {
+ MALI_DEBUG_PRINT(3, ("Mali GP scheduler: Failed to start GP job\n"));
+ }
+}
+
+static void mali_gp_scheduler_return_job_to_user(struct mali_gp_job *job, mali_bool success)
+{
+ _mali_osk_notification_t *notobj = _mali_osk_notification_create(_MALI_NOTIFICATION_GP_FINISHED, sizeof(_mali_uk_gp_job_finished_s));
+ if (NULL != notobj)
+ {
+ _mali_uk_gp_job_finished_s *jobres = notobj->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), notobj);
+ }
+ else
+ {
+ MALI_PRINT_ERROR(("Mali GP scheduler: Unable to allocate notification object\n"));
+ }
+
+ mali_gp_job_delete(job);
+}
+
+
+void mali_gp_scheduler_do_schedule(void)
+{
+ mali_gp_scheduler_lock();
+
+ mali_gp_scheduler_schedule();
+
+ mali_gp_scheduler_unlock();
+}
+
+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_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);
+ }
+ else
+ {
+ mali_gp_scheduler_schedule();
+ }
+
+ mali_gp_scheduler_unlock();
+
+ mali_gp_scheduler_return_job_to_user(job, success);
+}
+
+void mali_gp_scheduler_oom(struct mali_group *group, struct mali_gp_job *job)
+{
+ _mali_osk_notification_t *notobj;
+
+ notobj = _mali_osk_notification_create(_MALI_NOTIFICATION_GP_STALLED, sizeof(_mali_uk_gp_job_suspended_s));
+
+ if (NULL != notobj)
+ {
+ _mali_uk_gp_job_suspended_s * jobres;
+
+ mali_gp_scheduler_lock();
+
+ jobres = (_mali_uk_gp_job_suspended_s *)notobj->result_buffer;
+
+ jobres->user_job_ptr = mali_gp_job_get_user_id(job);
+ jobres->reason = _MALIGP_JOB_SUSPENDED_OUT_OF_MEMORY;
+ jobres->cookie = mali_gp_job_get_id(job);
+ slot.returned_cookie = jobres->cookie;
+
+ mali_session_send_notification(mali_gp_job_get_session(job), notobj);
+
+ mali_gp_scheduler_unlock();
+ }
+
+ /*
+ * 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) */
+ if (0 == pause_count)
+ {
+ mali_gp_scheduler_schedule();
+ }
+ mali_gp_scheduler_unlock();
+}
+
+_mali_osk_errcode_t _mali_ukk_gp_start_job(_mali_uk_gp_start_job_s *args)
+{
+ struct mali_session_data *session;
+ struct mali_gp_job *job;
+
+ 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;
+ }
+
+ job = mali_gp_job_create(session, args, mali_scheduler_get_new_id());
+ if (NULL == job)
+ {
+ return _MALI_OSK_ERR_NOMEM;
+ }
+
+ mali_gp_scheduler_lock();
+
+ _mali_osk_list_addtail(&job->list, &job_queue);
+
+ MALI_DEBUG_PRINT(3, ("Mali GP scheduler: Job %u (0x%08X) queued\n", mali_gp_job_get_id(job), job));
+
+ mali_gp_scheduler_schedule();
+
+ mali_gp_scheduler_unlock();
+
+ 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;
+ _mali_osk_errcode_t ret = _MALI_OSK_ERR_FAULT;
+
+ 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;
+ }
+
+ mali_gp_scheduler_lock();
+
+ /* Make sure that the cookie returned by user space is the same as we provided in the first place */
+ if (args->cookie != slot.returned_cookie)
+ {
+ MALI_DEBUG_PRINT(2, ("Mali GP scheduler: Got an illegal cookie from user space, expected %u but got %u (job id)\n", slot.returned_cookie, args->cookie)) ;
+ mali_gp_scheduler_unlock();
+ return _MALI_OSK_ERR_FAULT;
+ }
+
+ mali_gp_scheduler_unlock();
+
+ switch (args->code)
+ {
+ case _MALIGP_JOB_RESUME_WITH_NEW_HEAP:
+ 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]));
+ mali_group_resume_gp_with_new_heap(slot.group, args->cookie, args->arguments[0], args->arguments[1]);
+ ret = _MALI_OSK_ERR_OK;
+ break;
+
+ case _MALIGP_JOB_ABORT:
+ 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);
+ ret = _MALI_OSK_ERR_OK;
+ break;
+
+ default:
+ MALI_PRINT_ERROR(("Mali GP scheduler: Wrong suspend response from user space\n"));
+ ret = _MALI_OSK_ERR_FAULT;
+ break;
+ }
+
+ return ret;
+
+}
+
+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_unlock();
+
+ /* Abort running jobs from this session. It is safe to do this outside
+ * the scheduler lock as there is only one GP core, and the queue has
+ * already been emptied, as long as there are no new jobs coming in
+ * from user space. */
+ 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, "\t\tState: %d\n", mali_group_gp_state(slot.group));
+ n += _mali_osk_snprintf(buf + n, size - n, "\n");
+
+ return n;
+}
+#endif
diff --git a/drivers/media/video/samsung/mali/common/mali_gp_scheduler.h b/drivers/media/video/samsung/mali/common/mali_gp_scheduler.h
new file mode 100644
index 0000000..ef58509
--- /dev/null
+++ b/drivers/media/video/samsung/mali/common/mali_gp_scheduler.h
@@ -0,0 +1,30 @@
+/*
+ * 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_cluster.h"
+#include "mali_gp_job.h"
+
+_mali_osk_errcode_t mali_gp_scheduler_initialize(void);
+void mali_gp_scheduler_terminate(void);
+
+void mali_gp_scheduler_do_schedule(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);
+
+#endif /* __MALI_GP_SCHEDULER_H__ */
diff --git a/drivers/media/video/samsung/mali/common/mali_group.c b/drivers/media/video/samsung/mali/common/mali_group.c
new file mode 100644
index 0000000..9202bc1
--- /dev/null
+++ b/drivers/media/video/samsung/mali/common/mali_group.c
@@ -0,0 +1,841 @@
+/*
+ * 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_cluster.h"
+#include "mali_gp.h"
+#include "mali_pp.h"
+#include "mali_mmu.h"
+#include "mali_gp_scheduler.h"
+#include "mali_pp_scheduler.h"
+#include "mali_pm.h"
+
+/*
+ * 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).
+ */
+
+/**
+ * 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_cluster *cluster;
+
+ struct mali_mmu_core *mmu;
+ struct mali_session_data *session;
+ int page_dir_ref_count;
+ mali_bool power_is_on;
+#if defined(USING_MALI200)
+ mali_bool pagedir_activation_failed;
+#endif
+
+ struct mali_gp_core *gp_core;
+ enum mali_group_core_state gp_state;
+ struct mali_gp_job *gp_running_job;
+
+ struct mali_pp_core *pp_core;
+ enum mali_group_core_state pp_state;
+ struct mali_pp_job *pp_running_job;
+ u32 pp_running_sub_job;
+
+ _mali_osk_lock_t *lock;
+};
+
+static struct mali_group *mali_global_groups[MALI_MAX_NUMBER_OF_GROUPS];
+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_recovery_reset(struct mali_group *group);
+static void mali_group_complete_jobs(struct mali_group *group, mali_bool complete_gp, mali_bool complete_pp, bool success);
+
+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_cluster *cluster, struct mali_mmu_core *mmu)
+{
+ struct mali_group *group = NULL;
+
+ 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_malloc(sizeof(struct mali_group));
+ if (NULL != group)
+ {
+ _mali_osk_memset(group, 0, sizeof(struct mali_group));
+ group->lock = _mali_osk_lock_init(_MALI_OSK_LOCKFLAG_ORDERED | _MALI_OSK_LOCKFLAG_SPINLOCK_IRQ |_MALI_OSK_LOCKFLAG_NONINTERRUPTABLE, 0, _MALI_OSK_LOCK_ORDER_GROUP);
+ if (NULL != group->lock)
+ {
+ group->cluster = cluster;
+ group->mmu = mmu; /* This group object now owns the MMU object */
+ group->session = NULL;
+ group->page_dir_ref_count = 0;
+ group->power_is_on = MALI_TRUE;
+
+ group->gp_state = MALI_GROUP_CORE_STATE_IDLE;
+ group->pp_state = MALI_GROUP_CORE_STATE_IDLE;
+#if defined(USING_MALI200)
+ group->pagedir_activation_failed = MALI_FALSE;
+#endif
+ mali_global_groups[mali_global_num_groups] = group;
+ mali_global_num_groups++;
+
+ return group;
+ }
+ _mali_osk_free(group);
+ }
+
+ return NULL;
+}
+
+void 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;
+}
+
+void 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;
+}
+
+void mali_group_delete(struct mali_group *group)
+{
+ u32 i;
+
+ /* 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);
+ }
+
+ for (i = 0; i < mali_global_num_groups; i++)
+ {
+ if (mali_global_groups[i] == group)
+ {
+ mali_global_groups[i] = NULL;
+ mali_global_num_groups--;
+ break;
+ }
+ }
+
+ _mali_osk_lock_term(group->lock);
+
+ _mali_osk_free(group);
+}
+
+/* Called from mali_cluster_reset() when the system is re-turned on */
+void mali_group_reset(struct mali_group *group)
+{
+ mali_group_lock(group);
+
+ group->session = NULL;
+
+ if (NULL != group->mmu)
+ {
+ mali_mmu_reset(group->mmu);
+ }
+
+ if (NULL != group->gp_core)
+ {
+ mali_gp_reset(group->gp_core);
+ }
+
+ if (NULL != group->pp_core)
+ {
+ mali_pp_reset(group->pp_core);
+ }
+
+ mali_group_unlock(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;
+}
+
+_mali_osk_errcode_t 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_DEBUG_ASSERT(MALI_GROUP_CORE_STATE_IDLE == group->gp_state);
+
+ mali_pm_core_event(MALI_CORE_EVENT_GP_START);
+
+ session = mali_gp_job_get_session(job);
+
+ mali_group_lock(group);
+
+ mali_cluster_l2_cache_invalidate_all(group->cluster, 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);
+ group->gp_running_job = job;
+ group->gp_state = MALI_GROUP_CORE_STATE_WORKING;
+
+ mali_group_unlock(group);
+
+ return _MALI_OSK_ERR_OK;
+ }
+
+#if defined(USING_MALI200)
+ group->pagedir_activation_failed = MALI_TRUE;
+#endif
+
+ mali_group_unlock(group);
+
+ mali_pm_core_event(MALI_CORE_EVENT_GP_STOP); /* Failed to start, so "cancel" the MALI_CORE_EVENT_GP_START */
+ return _MALI_OSK_ERR_FAULT;
+}
+
+_mali_osk_errcode_t 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_DEBUG_ASSERT(MALI_GROUP_CORE_STATE_IDLE == group->pp_state);
+
+ mali_pm_core_event(MALI_CORE_EVENT_PP_START);
+
+ session = mali_pp_job_get_session(job);
+
+ mali_group_lock(group);
+
+ mali_cluster_l2_cache_invalidate_all(group->cluster, 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);
+ }
+ mali_pp_job_start(group->pp_core, job, sub_job);
+ group->pp_running_job = job;
+ group->pp_running_sub_job = sub_job;
+ group->pp_state = MALI_GROUP_CORE_STATE_WORKING;
+
+ mali_group_unlock(group);
+
+ return _MALI_OSK_ERR_OK;
+ }
+
+#if defined(USING_MALI200)
+ group->pagedir_activation_failed = MALI_TRUE;
+#endif
+
+ mali_group_unlock(group);
+
+ mali_pm_core_event(MALI_CORE_EVENT_PP_STOP); /* Failed to start, so "cancel" the MALI_CORE_EVENT_PP_START */
+ return _MALI_OSK_ERR_FAULT;
+}
+
+void mali_group_resume_gp_with_new_heap(struct mali_group *group, u32 job_id, u32 start_addr, u32 end_addr)
+{
+ mali_group_lock(group);
+
+ if (group->gp_state != MALI_GROUP_CORE_STATE_OOM ||
+ mali_gp_job_get_id(group->gp_running_job) != job_id)
+ {
+ mali_group_unlock(group);
+ return; /* Illegal request or job has already been aborted */
+ }
+
+ mali_cluster_l2_cache_invalidate_all_force(group->cluster);
+ mali_mmu_zap_tlb_without_stall(group->mmu);
+
+ mali_gp_resume_with_new_heap(group->gp_core, start_addr, end_addr);
+ group->gp_state = MALI_GROUP_CORE_STATE_WORKING;
+
+ mali_group_unlock(group);
+}
+
+void mali_group_abort_gp_job(struct mali_group *group, u32 job_id)
+{
+ mali_group_lock(group);
+
+ if (group->gp_state == MALI_GROUP_CORE_STATE_IDLE ||
+ mali_gp_job_get_id(group->gp_running_job) != job_id)
+ {
+ mali_group_unlock(group);
+ return; /* No need to cancel or job has already been aborted or completed */
+ }
+
+ mali_group_complete_jobs(group, MALI_TRUE, MALI_FALSE, MALI_FALSE); /* Will release group lock */
+}
+
+void mali_group_abort_pp_job(struct mali_group *group, u32 job_id)
+{
+ mali_group_lock(group);
+
+ if (group->pp_state == MALI_GROUP_CORE_STATE_IDLE ||
+ mali_pp_job_get_id(group->pp_running_job) != job_id)
+ {
+ mali_group_unlock(group);
+ return; /* No need to cancel or job has already been aborted or completed */
+ }
+
+ mali_group_complete_jobs(group, MALI_FALSE, MALI_TRUE, MALI_FALSE); /* Will release group lock */
+}
+
+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);
+
+ gp_job = group->gp_running_job;
+ pp_job = group->pp_running_job;
+
+ if (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 (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;
+ }
+
+ mali_group_unlock(group);
+
+ /* These functions takes and releases the group lock */
+ if (0 != abort_gp)
+ {
+ mali_group_abort_gp_job(group, gp_job_id);
+ }
+ if (0 != abort_pp)
+ {
+ mali_group_abort_pp_job(group, pp_job_id);
+ }
+
+ mali_group_lock(group);
+ mali_group_remove_session_if_unused(group, session);
+ mali_group_unlock(group);
+}
+
+enum mali_group_core_state mali_group_gp_state(struct mali_group *group)
+{
+ return group->gp_state;
+}
+
+enum mali_group_core_state mali_group_pp_state(struct mali_group *group)
+{
+ return group->pp_state;
+}
+
+/* group lock need to be taken before calling mali_group_bottom_half */
+void mali_group_bottom_half(struct mali_group *group, enum mali_group_event_t event)
+{
+ MALI_ASSERT_GROUP_LOCKED(group);
+
+ switch (event)
+ {
+ case GROUP_EVENT_PP_JOB_COMPLETED:
+ mali_group_complete_jobs(group, MALI_FALSE, MALI_TRUE, MALI_TRUE); /* PP job SUCCESS */
+ /* group lock is released by mali_group_complete_jobs() call above */
+ break;
+ case GROUP_EVENT_PP_JOB_FAILED:
+ mali_group_complete_jobs(group, MALI_FALSE, MALI_TRUE, MALI_FALSE); /* PP job FAIL */
+ /* group lock is released by mali_group_complete_jobs() call above */
+ break;
+ case GROUP_EVENT_PP_JOB_TIMED_OUT:
+ mali_group_complete_jobs(group, MALI_FALSE, MALI_TRUE, MALI_FALSE); /* PP job TIMEOUT */
+ /* group lock is released by mali_group_complete_jobs() call above */
+ break;
+ case GROUP_EVENT_GP_JOB_COMPLETED:
+ mali_group_complete_jobs(group, MALI_TRUE, MALI_FALSE, MALI_TRUE); /* GP job SUCCESS */
+ /* group lock is released by mali_group_complete_jobs() call above */
+ break;
+ case GROUP_EVENT_GP_JOB_FAILED:
+ mali_group_complete_jobs(group, MALI_TRUE, MALI_FALSE, MALI_FALSE); /* GP job FAIL */
+ /* group lock is released by mali_group_complete_jobs() call above */
+ break;
+ case GROUP_EVENT_GP_JOB_TIMED_OUT:
+ mali_group_complete_jobs(group, MALI_TRUE, MALI_FALSE, MALI_FALSE); /* GP job TIMEOUT */
+ /* group lock is released by mali_group_complete_jobs() call above */
+ break;
+ case GROUP_EVENT_GP_OOM:
+ group->gp_state = MALI_GROUP_CORE_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);
+ break;
+ case GROUP_EVENT_MMU_PAGE_FAULT:
+ mali_group_complete_jobs(group, MALI_TRUE, MALI_TRUE, MALI_FALSE); /* GP and PP job FAIL */
+ /* group lock is released by mali_group_complete_jobs() call above */
+ break;
+ default:
+ break;
+ }
+}
+
+struct mali_mmu_core *mali_group_get_mmu(struct mali_group *group)
+{
+ return group->mmu;
+}
+
+struct mali_session_data *mali_group_get_session(struct mali_group *group)
+{
+ return group->session;
+}
+
+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;
+}
+
+/* Used to check if scheduler for the other core type needs to be called on job completion.
+ *
+ * Used only for Mali-200, where job start may fail if the only MMU is busy
+ * with another session's address space.
+ */
+static inline mali_bool mali_group_other_reschedule_needed(struct mali_group *group)
+{
+ MALI_ASSERT_GROUP_LOCKED(group);
+
+#if defined(USING_MALI200)
+ if (group->pagedir_activation_failed)
+ {
+ group->pagedir_activation_failed = MALI_FALSE;
+ return MALI_TRUE;
+ }
+ else
+#endif
+ {
+ return MALI_FALSE;
+ }
+}
+
+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_FALSE;
+ 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);
+}
+
+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_CORE_STATE_IDLE == group->gp_state);
+ MALI_DEBUG_ASSERT(MALI_GROUP_CORE_STATE_IDLE == group->pp_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;
+ }
+ }
+}
+
+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);
+ MALI_DEBUG_ASSERT(MALI_GROUP_CORE_STATE_IDLE == group->gp_state);
+ MALI_DEBUG_ASSERT(MALI_GROUP_CORE_STATE_IDLE == group->pp_state);
+ MALI_DEBUG_ASSERT_POINTER(group->cluster);
+ group->power_is_on = MALI_TRUE;
+ mali_cluster_power_is_enabled_set(group->cluster, MALI_TRUE);
+ mali_group_unlock(group);
+ }
+ MALI_DEBUG_PRINT(3,("group: POWER ON\n"));
+}
+
+mali_bool mali_group_power_is_on(struct mali_group *group)
+{
+ MALI_ASSERT_GROUP_LOCKED(group);
+ return group->power_is_on;
+}
+
+void mali_group_power_off(void)
+{
+ int i;
+ /* It is necessary to set group->session = NULL; so that the powered off MMU is not written to on map /unmap */
+ /* It is necessary to set group->power_is_on=MALI_FALSE so that pending bottom_halves does not access powered off cores. */
+ for (i = 0; i < mali_global_num_groups; i++)
+ {
+ struct mali_group *group = mali_global_groups[i];
+ mali_group_lock(group);
+ MALI_DEBUG_ASSERT(MALI_GROUP_CORE_STATE_IDLE == group->gp_state);
+ MALI_DEBUG_ASSERT(MALI_GROUP_CORE_STATE_IDLE == group->pp_state);
+ MALI_DEBUG_ASSERT_POINTER(group->cluster);
+ group->session = NULL;
+ MALI_DEBUG_ASSERT(MALI_TRUE == group->power_is_on);
+ group->power_is_on = MALI_FALSE;
+ mali_cluster_power_is_enabled_set(group->cluster, MALI_FALSE);
+ mali_group_unlock(group);
+ }
+ MALI_DEBUG_PRINT(3,("group: POWER OFF\n"));
+}
+
+
+static void mali_group_recovery_reset(struct mali_group *group)
+{
+ MALI_ASSERT_GROUP_LOCKED(group);
+
+ /* Stop cores, bus stop */
+ if (NULL != group->pp_core)
+ {
+ mali_pp_stop_bus(group->pp_core);
+ }
+ if (NULL != group->gp_core)
+ {
+ mali_gp_stop_bus(group->gp_core);
+ }
+
+ /* Flush MMU */
+ mali_mmu_activate_fault_flush_page_directory(group->mmu);
+ mali_mmu_page_fault_done(group->mmu);
+
+ /* Wait for cores to stop bus */
+ if (NULL != group->pp_core)
+ {
+ mali_pp_stop_bus_wait(group->pp_core);
+ }
+ if (NULL != group->gp_core)
+ {
+ mali_gp_stop_bus_wait(group->gp_core);
+ }
+
+ /* Reset cores */
+ if (NULL != group->pp_core)
+ {
+ mali_pp_hard_reset(group->pp_core);
+ }
+ if (NULL != group->gp_core)
+ {
+ mali_gp_hard_reset(group->gp_core);
+ }
+
+ /* Reset MMU */
+ mali_mmu_reset(group->mmu);
+ group->session = NULL;
+}
+
+/* Group lock need to be taken before calling mali_group_complete_jobs. Will release the lock here. */
+static void mali_group_complete_jobs(struct mali_group *group, mali_bool complete_gp, mali_bool complete_pp, bool success)
+{
+ mali_bool need_group_reset = MALI_FALSE;
+ mali_bool gp_success = success;
+ mali_bool pp_success = success;
+
+ MALI_ASSERT_GROUP_LOCKED(group);
+
+ if (complete_gp && !complete_pp)
+ {
+ MALI_DEBUG_ASSERT_POINTER(group->gp_core);
+ if (_MALI_OSK_ERR_OK == mali_gp_reset(group->gp_core))
+ {
+ struct mali_gp_job *gp_job_to_return = group->gp_running_job;
+ group->gp_state = MALI_GROUP_CORE_STATE_IDLE;
+ group->gp_running_job = NULL;
+
+ MALI_DEBUG_ASSERT_POINTER(gp_job_to_return);
+
+ mali_group_deactivate_page_directory(group, mali_gp_job_get_session(gp_job_to_return));
+
+ if(mali_group_other_reschedule_needed(group))
+ {
+ mali_group_unlock(group);
+ mali_pp_scheduler_do_schedule();
+ }
+ else
+ {
+ mali_group_unlock(group);
+ }
+
+ mali_gp_scheduler_job_done(group, gp_job_to_return, gp_success);
+ mali_pm_core_event(MALI_CORE_EVENT_GP_STOP); /* It is ok to do this after schedule, since START/STOP is simply ++ and -- anyways */
+
+ return;
+ }
+ else
+ {
+ need_group_reset = MALI_TRUE;
+ MALI_DEBUG_PRINT(3, ("Mali group: Failed to reset GP, need to reset entire group\n"));
+ pp_success = MALI_FALSE; /* This might kill PP as well, so this should fail */
+ }
+ }
+ if (complete_pp && !complete_gp)
+ {
+ MALI_DEBUG_ASSERT_POINTER(group->pp_core);
+ if (_MALI_OSK_ERR_OK == mali_pp_reset(group->pp_core))
+ {
+ struct mali_pp_job *pp_job_to_return = group->pp_running_job;
+ u32 pp_sub_job_to_return = group->pp_running_sub_job;
+ group->pp_state = MALI_GROUP_CORE_STATE_IDLE;
+ group->pp_running_job = NULL;
+
+ MALI_DEBUG_ASSERT_POINTER(pp_job_to_return);
+
+ mali_group_deactivate_page_directory(group, mali_pp_job_get_session(pp_job_to_return));
+
+ if(mali_group_other_reschedule_needed(group))
+ {
+ mali_group_unlock(group);
+ mali_gp_scheduler_do_schedule();
+ }
+ else
+ {
+ mali_group_unlock(group);
+ }
+
+ mali_pp_scheduler_job_done(group, pp_job_to_return, pp_sub_job_to_return, pp_success);
+ mali_pm_core_event(MALI_CORE_EVENT_PP_STOP); /* It is ok to do this after schedule, since START/STOP is simply ++ and -- anyways */
+
+ return;
+ }
+ else
+ {
+ need_group_reset = MALI_TRUE;
+ MALI_DEBUG_PRINT(3, ("Mali group: Failed to reset PP, need to reset entire group\n"));
+ gp_success = MALI_FALSE; /* This might kill GP as well, so this should fail */
+ }
+ }
+ else if (complete_gp && complete_pp)
+ {
+ need_group_reset = MALI_TRUE;
+ }
+
+ if (MALI_TRUE == need_group_reset)
+ {
+ struct mali_gp_job *gp_job_to_return = group->gp_running_job;
+ struct mali_pp_job *pp_job_to_return = group->pp_running_job;
+ u32 pp_sub_job_to_return = group->pp_running_sub_job;
+ mali_bool schedule_other = MALI_FALSE;
+
+ MALI_DEBUG_PRINT(3, ("Mali group: Resetting entire group\n"));
+
+ group->gp_state = MALI_GROUP_CORE_STATE_IDLE;
+ group->gp_running_job = NULL;
+ if (NULL != gp_job_to_return)
+ {
+ mali_group_deactivate_page_directory(group, mali_gp_job_get_session(gp_job_to_return));
+ }
+
+ group->pp_state = MALI_GROUP_CORE_STATE_IDLE;
+ group->pp_running_job = NULL;
+ if (NULL != pp_job_to_return)
+ {
+ mali_group_deactivate_page_directory(group, mali_pp_job_get_session(pp_job_to_return));
+ }
+
+ /* The reset has to be done after mali_group_deactivate_page_directory() */
+ mali_group_recovery_reset(group);
+
+ if (mali_group_other_reschedule_needed(group) && (NULL == gp_job_to_return || NULL == pp_job_to_return))
+ {
+ schedule_other = MALI_TRUE;
+ }
+
+ mali_group_unlock(group);
+
+ if (NULL != gp_job_to_return)
+ {
+ mali_gp_scheduler_job_done(group, gp_job_to_return, gp_success);
+ mali_pm_core_event(MALI_CORE_EVENT_GP_STOP); /* It is ok to do this after schedule, since START/STOP is simply ++ and -- anyways */
+ }
+ else if (schedule_other)
+ {
+ mali_pp_scheduler_do_schedule();
+ }
+
+ if (NULL != pp_job_to_return)
+ {
+ mali_pp_scheduler_job_done(group, pp_job_to_return, pp_sub_job_to_return, pp_success);
+ mali_pm_core_event(MALI_CORE_EVENT_PP_STOP); /* It is ok to do this after schedule, since START/STOP is simply ++ and -- anyways */
+ }
+ else if (schedule_other)
+ {
+ mali_gp_scheduler_do_schedule();
+ }
+
+ return;
+ }
+
+ mali_group_unlock(group);
+}
+
+#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);
+ 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 state: %d\n", group->gp_state);
+ 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 state: %d\n", group->pp_state);
+ 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
diff --git a/drivers/media/video/samsung/mali/common/mali_group.h b/drivers/media/video/samsung/mali/common/mali_group.h
new file mode 100644
index 0000000..3533d13
--- /dev/null
+++ b/drivers/media/video/samsung/mali/common/mali_group.h
@@ -0,0 +1,146 @@
+/*
+ * 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_cluster.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 9
+
+struct mali_group;
+
+enum mali_group_event_t
+{
+ GROUP_EVENT_PP_JOB_COMPLETED, /**< PP job completed successfully */
+ GROUP_EVENT_PP_JOB_FAILED, /**< PP job completed with failure */
+ GROUP_EVENT_PP_JOB_TIMED_OUT, /**< PP job reached max runtime */
+ GROUP_EVENT_GP_JOB_COMPLETED, /**< GP job completed successfully */
+ GROUP_EVENT_GP_JOB_FAILED, /**< GP job completed with failure */
+ GROUP_EVENT_GP_JOB_TIMED_OUT, /**< GP job reached max runtime */
+ GROUP_EVENT_GP_OOM, /**< GP job ran out of heap memory */
+ GROUP_EVENT_MMU_PAGE_FAULT, /**< MMU page fault */
+};
+
+enum mali_group_core_state
+{
+ MALI_GROUP_CORE_STATE_IDLE,
+ MALI_GROUP_CORE_STATE_WORKING,
+ MALI_GROUP_CORE_STATE_OOM
+};
+
+/** @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_cluster *cluster, struct mali_mmu_core *mmu);
+void mali_group_add_gp_core(struct mali_group *group, struct mali_gp_core* gp_core);
+void mali_group_add_pp_core(struct mali_group *group, struct mali_pp_core* pp_core);
+void mali_group_delete(struct mali_group *group);
+
+/** @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 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
+ */
+_mali_osk_errcode_t mali_group_start_gp_job(struct mali_group *group, struct mali_gp_job *job);
+/** @brief Start fragment of PP job
+ */
+_mali_osk_errcode_t 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
+ */
+void 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);
+
+enum mali_group_core_state mali_group_gp_state(struct mali_group *group);
+enum mali_group_core_state mali_group_pp_state(struct mali_group *group);
+
+/** @brief The common group bottom half interrupt handler
+ *
+ * This is only called from the GP and PP bottom halves.
+ *
+ * The action taken is dictated by the \a event.
+ *
+ * @param event The event code
+ */
+void mali_group_bottom_half(struct mali_group *group, enum mali_group_event_t event);
+
+struct mali_mmu_core *mali_group_get_mmu(struct mali_group *group);
+struct mali_session_data *mali_group_get_session(struct mali_group *group);
+
+void mali_group_remove_session_if_unused(struct mali_group *group, struct mali_session_data *session_data);
+
+void mali_group_power_on(void);
+void mali_group_power_off(void);
+mali_bool mali_group_power_is_on(struct mali_group *group);
+
+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);
+
+#endif /* __MALI_GROUP_H__ */
diff --git a/drivers/media/video/samsung/mali/common/mali_hw_core.c b/drivers/media/video/samsung/mali/common/mali_hw_core.c
new file mode 100644
index 0000000..0b08622
--- /dev/null
+++ b/drivers/media/video/samsung/mali/common/mali_hw_core.c
@@ -0,0 +1,46 @@
+/*
+ * 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/media/video/samsung/mali/common/mali_hw_core.h b/drivers/media/video/samsung/mali/common/mali_hw_core.h
new file mode 100644
index 0000000..c797804
--- /dev/null
+++ b/drivers/media/video/samsung/mali/common/mali_hw_core.h
@@ -0,0 +1,71 @@
+/*
+ * 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_HW_CORE_NO_COUNTER ((u32)-1)
+#define MALI_HW_CORE_INVALID_VALUE ((u32)-1)
+
+_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);
+}
+
+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]);
+ }
+}
+
+#endif /* __MALI_HW_CORE_H__ */
diff --git a/drivers/media/video/samsung/mali/common/mali_kernel_GP2.c b/drivers/media/video/samsung/mali/common/mali_kernel_GP2.c
deleted file mode 100644
index cfd70f4..0000000
--- a/drivers/media/video/samsung/mali/common/mali_kernel_GP2.c
+++ /dev/null
@@ -1,1493 +0,0 @@
-/*
- * 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.
- */
-//added for SPI
-#include <linux/kernel.h>
-
-#include "mali_kernel_common.h"
-#include "mali_kernel_core.h"
-#include "mali_kernel_subsystem.h"
-#include "regs/mali_gp_regs.h"
-#include "mali_kernel_rendercore.h"
-#include "mali_osk.h"
-#include "mali_osk_list.h"
-#if MALI_TIMELINE_PROFILING_ENABLED
-#include "mali_kernel_profiling.h"
-#endif
-#if defined(USING_MALI400_L2_CACHE)
-#include "mali_kernel_l2_cache.h"
-#endif
-#if USING_MMU
-#include "mali_kernel_mem_mmu.h" /* Needed for mali_kernel_mmu_force_bus_reset() */
-#endif
-
-#if defined(USING_MALI200)
-#define MALI_GP_SUBSYSTEM_NAME "MaliGP2"
-#define MALI_GP_CORE_TYPE _MALI_GP2
-#elif defined(USING_MALI400)
-#define MALI_GP_SUBSYSTEM_NAME "Mali-400 GP"
-#define MALI_GP_CORE_TYPE _MALI_400_GP
-#else
-#error "No supported mali core defined"
-#endif
-
-#define GET_JOB_EMBEDDED_PTR(job) (&((job)->embedded_core_job))
-#define GET_JOBGP2_PTR(job_extern) _MALI_OSK_CONTAINER_OF(job_extern, maligp_job, embedded_core_job)
-
-/* Initialized when this subsystem is initialized. This is determined by the
- * position in subsystems[], and so the value used to initialize this is
- * determined at compile time */
-static mali_kernel_subsystem_identifier mali_subsystem_gp_id = -1;
-
-static mali_core_renderunit * last_gp_core_cookie = NULL;
-
-/* Describing a maligp job settings */
-typedef struct maligp_job
-{
- /* The general job struct common for all mali cores */
- mali_core_job embedded_core_job;
- _mali_uk_gp_start_job_s user_input;
-
- u32 irq_status;
- u32 status_reg_on_stop;
- u32 perf_counter0;
- u32 perf_counter1;
- u32 vscl_stop_addr;
- u32 plbcl_stop_addr;
- u32 heap_current_addr;
-
- /* The data we will return back to the user */
- _mali_osk_notification_t *notification_obj;
-
- int is_stalled_waiting_for_more_memory;
-
- u32 active_mask;
- /* progress checking */
- u32 last_vscl;
- u32 last_plbcl;
- /* extended progress checking, only enabled when we can use one of the performance counters */
- u32 have_extended_progress_checking;
- u32 vertices;
-
-#if defined(USING_MALI400_L2_CACHE)
- u32 perf_counter_l2_src0;
- u32 perf_counter_l2_src1;
- u32 perf_counter_l2_val0;
- u32 perf_counter_l2_val1;
-#endif
-
-#if MALI_TIMELINE_PROFILING_ENABLED
- u32 pid;
- u32 tid;
-#endif
-} maligp_job;
-
-/*Functions Exposed to the General External System through
- function pointers.*/
-
-static _mali_osk_errcode_t maligp_subsystem_startup(mali_kernel_subsystem_identifier id);
-#if USING_MMU
-static _mali_osk_errcode_t maligp_subsystem_mmu_connect(mali_kernel_subsystem_identifier id);
-#endif
-static void maligp_subsystem_terminate(mali_kernel_subsystem_identifier id);
-static _mali_osk_errcode_t maligp_subsystem_session_begin(struct mali_session_data * mali_session_data, mali_kernel_subsystem_session_slot * slot, _mali_osk_notification_queue_t * queue);
-static void maligp_subsystem_session_end(struct mali_session_data * mali_session_data, mali_kernel_subsystem_session_slot * slot);
-static _mali_osk_errcode_t maligp_subsystem_core_system_info_fill(_mali_system_info* info);
-static _mali_osk_errcode_t maligp_renderunit_create(_mali_osk_resource_t * resource);
-#if USING_MMU
-static void maligp_subsystem_broadcast_notification(mali_core_notification_message message, u32 data);
-#endif
-#if MALI_STATE_TRACKING
-u32 maligp_subsystem_dump_state(char *buf, u32 size);
-#endif
-
-/* Internal support functions */
-static _mali_osk_errcode_t maligp_core_version_legal( mali_core_renderunit *core );
-static void maligp_raw_reset( mali_core_renderunit *core);
-static void maligp_reset_hard(struct mali_core_renderunit * core);
-static void maligp_reset(mali_core_renderunit *core);
-static void maligp_initialize_registers_mgmt(mali_core_renderunit *core );
-
-#ifdef DEBUG
-static void maligp_print_regs(int debug_level, mali_core_renderunit *core);
-#endif
-
-/* Functions exposed to mali_core system through functionpointers
- in the subsystem struct. */
-static _mali_osk_errcode_t subsystem_maligp_start_job(mali_core_job * job, mali_core_renderunit * core);
-static u32 subsystem_maligp_irq_handler_upper_half(mali_core_renderunit * core);
-static int subsystem_maligp_irq_handler_bottom_half(mali_core_renderunit* core);
-static _mali_osk_errcode_t subsystem_maligp_get_new_job_from_user(struct mali_core_session * session, void * argument);
-static _mali_osk_errcode_t subsystem_maligp_suspend_response(struct mali_core_session * session, void * argument);
-static void subsystem_maligp_return_job_to_user(mali_core_job * job, mali_subsystem_job_end_code end_status);
-static void subsystem_maligp_renderunit_delete(mali_core_renderunit * core);
-static void subsystem_maligp_renderunit_reset_core(struct mali_core_renderunit * core, mali_core_reset_style style );
-static void subsystem_maligp_renderunit_probe_core_irq_trigger(struct mali_core_renderunit* core);
-static _mali_osk_errcode_t subsystem_maligp_renderunit_probe_core_irq_finished(struct mali_core_renderunit* core);
-static void subsystem_maligp_renderunit_stop_bus(struct mali_core_renderunit* core);
-
-/* Variables */
-static register_address_and_value default_mgmt_regs[] =
-{
- { MALIGP2_REG_ADDR_MGMT_INT_MASK, MALIGP2_REG_VAL_IRQ_MASK_USED }
-};
-
-
-/* This will be one of the subsystems in the array of subsystems:
- static struct mali_kernel_subsystem * subsystems[];
- found in file: mali_kernel_core.c
-*/
-
-struct mali_kernel_subsystem mali_subsystem_gp2=
-{
- maligp_subsystem_startup, /* startup */
- NULL, /*maligp_subsystem_terminate,*/ /* shutdown */
-#if USING_MMU
- maligp_subsystem_mmu_connect, /* load_complete */
-#else
- NULL,
-#endif
- maligp_subsystem_core_system_info_fill, /* system_info_fill */
- maligp_subsystem_session_begin, /* session_begin */
- maligp_subsystem_session_end, /* session_end */
-#if USING_MMU
- maligp_subsystem_broadcast_notification, /* broadcast_notification */
-#else
- NULL,
-#endif
-#if MALI_STATE_TRACKING
- maligp_subsystem_dump_state, /* dump_state */
-#endif
-} ;
-
-static mali_core_subsystem subsystem_maligp ;
-
-static _mali_osk_errcode_t maligp_subsystem_startup(mali_kernel_subsystem_identifier id)
-{
- mali_core_subsystem * subsystem;
-
- MALI_DEBUG_PRINT(3, ("Mali GP: maligp_subsystem_startup\n") ) ;
-
- mali_subsystem_gp_id = id;
-
- /* All values get 0 as default */
- _mali_osk_memset(&subsystem_maligp, 0, sizeof(*subsystem));
-
- subsystem = &subsystem_maligp;
- subsystem->start_job = &subsystem_maligp_start_job;
- subsystem->irq_handler_upper_half = &subsystem_maligp_irq_handler_upper_half;
- subsystem->irq_handler_bottom_half = &subsystem_maligp_irq_handler_bottom_half;
- subsystem->get_new_job_from_user = &subsystem_maligp_get_new_job_from_user;
- subsystem->suspend_response = &subsystem_maligp_suspend_response;
- subsystem->return_job_to_user = &subsystem_maligp_return_job_to_user;
- subsystem->renderunit_delete = &subsystem_maligp_renderunit_delete;
- subsystem->reset_core = &subsystem_maligp_renderunit_reset_core;
- subsystem->stop_bus = &subsystem_maligp_renderunit_stop_bus;
- subsystem->probe_core_irq_trigger = &subsystem_maligp_renderunit_probe_core_irq_trigger;
- subsystem->probe_core_irq_acknowledge = &subsystem_maligp_renderunit_probe_core_irq_finished;
-
- /* Setting variables in the general core part of the subsystem.*/
- subsystem->name = MALI_GP_SUBSYSTEM_NAME;
- subsystem->core_type = MALI_GP_CORE_TYPE;
- subsystem->id = id;
-
- /* Initiates the rest of the general core part of the subsystem */
- MALI_CHECK_NO_ERROR(mali_core_subsystem_init( subsystem ));
-
- /* This will register the function for adding MALIGP2 cores to the subsystem */
-#if defined(USING_MALI200)
- MALI_CHECK_NO_ERROR(_mali_kernel_core_register_resource_handler(MALIGP2, maligp_renderunit_create));
-#endif
-#if defined(USING_MALI400)
- MALI_CHECK_NO_ERROR(_mali_kernel_core_register_resource_handler(MALI400GP, maligp_renderunit_create));
-#endif
-
- MALI_DEBUG_PRINT(6, ("Mali GP: maligp_subsystem_startup\n") ) ;
-
- MALI_SUCCESS;
-}
-
-#if USING_MMU
-static _mali_osk_errcode_t maligp_subsystem_mmu_connect(mali_kernel_subsystem_identifier id)
-{
- mali_core_subsystem_attach_mmu(&subsystem_maligp);
- MALI_SUCCESS; /* OK */
-}
-#endif
-
-static void maligp_subsystem_terminate(mali_kernel_subsystem_identifier id)
-{
- MALI_DEBUG_PRINT(3, ("Mali GP: maligp_subsystem_terminate\n") ) ;
- mali_core_subsystem_cleanup(&subsystem_maligp);
-}
-
-static _mali_osk_errcode_t maligp_subsystem_session_begin(struct mali_session_data * mali_session_data, mali_kernel_subsystem_session_slot * slot, _mali_osk_notification_queue_t * queue)
-{
- mali_core_session * session;
-
- MALI_DEBUG_PRINT(3, ("Mali GP: maligp_subsystem_session_begin\n") ) ;
- MALI_CHECK_NON_NULL(session = _mali_osk_malloc( sizeof(*session) ), _MALI_OSK_ERR_FAULT);
-
- _mali_osk_memset(session, 0, sizeof(*session) );
- *slot = (mali_kernel_subsystem_session_slot)session;
-
- session->subsystem = &subsystem_maligp;
-
- session->notification_queue = queue;
-
-#if USING_MMU
- session->mmu_session = mali_session_data;
-#endif
-
- mali_core_session_begin(session);
-
- MALI_DEBUG_PRINT(6, ("Mali GP: maligp_subsystem_session_begin\n") ) ;
-
- MALI_SUCCESS;
-}
-
-static void maligp_subsystem_session_end(struct mali_session_data * mali_session_data, mali_kernel_subsystem_session_slot * slot)
-{
- mali_core_session * session;
- /** @note mali_session_data not needed here */
-
- MALI_DEBUG_PRINT(3, ("Mali GP: maligp_subsystem_session_end\n") ) ;
- if ( NULL==slot || NULL==*slot)
- {
- MALI_PRINT_ERROR(("Input slot==NULL"));
- return;
- }
- session = (mali_core_session *)*slot;
- mali_core_session_close(session);
-
- _mali_osk_free(session);
- *slot = NULL;
-
- MALI_DEBUG_PRINT(6, ("Mali GP: maligp_subsystem_session_end\n") ) ;
-}
-
-/**
- * We fill in info about all the cores we have
- * @param info Pointer to system info struct to update
- * @return _MALI_OSK_ERR_OK on success, or another _mali_osk_errcode_t for errors.
- */
-static _mali_osk_errcode_t maligp_subsystem_core_system_info_fill(_mali_system_info* info)
-{
- return mali_core_subsystem_system_info_fill(&subsystem_maligp, info);
-}
-
-static _mali_osk_errcode_t maligp_renderunit_create(_mali_osk_resource_t * resource)
-{
- mali_core_renderunit *core;
- int err;
-
- MALI_DEBUG_PRINT(3, ("Mali GP: maligp_renderunit_create\n") ) ;
- /* Checking that the resource settings are correct */
-#if defined(USING_MALI200)
- if(MALIGP2 != resource->type)
- {
- MALI_PRINT_ERROR(("Can not register this resource as a " MALI_GP_SUBSYSTEM_NAME " core."));
- MALI_ERROR(_MALI_OSK_ERR_FAULT);
- }
-#elif defined(USING_MALI400)
- if(MALI400GP != resource->type)
- {
- MALI_PRINT_ERROR(("Can not register this resource as a " MALI_GP_SUBSYSTEM_NAME " core."));
- MALI_ERROR(_MALI_OSK_ERR_FAULT);
- }
-#endif
- if ( 0 != resource->size )
- {
- MALI_PRINT_ERROR(("Memory size set to " MALI_GP_SUBSYSTEM_NAME " core should be zero."));
- MALI_ERROR(_MALI_OSK_ERR_FAULT);
- }
-
- if ( NULL == resource->description )
- {
- MALI_PRINT_ERROR(("A " MALI_GP_SUBSYSTEM_NAME " core needs a unique description field"));
- MALI_ERROR(_MALI_OSK_ERR_FAULT);
- }
-
- /* Create a new core object */
- core = (mali_core_renderunit*) _mali_osk_malloc(sizeof(*core));
- if ( NULL == core )
- {
- MALI_ERROR(_MALI_OSK_ERR_FAULT);
- }
-
- /* Variables set to be able to open and register the core */
- core->subsystem = &subsystem_maligp ;
- core->registers_base_addr = resource->base ;
- core->size = MALIGP2_REGISTER_ADDRESS_SPACE_SIZE ;
- core->description = resource->description;
- core->irq_nr = resource->irq ;
-#if USING_MMU
- core->mmu_id = resource->mmu_id;
- core->mmu = NULL;
-#endif
-#if USING_MALI_PMM
- /* Set up core's PMM id */
- core->pmm_id = MALI_PMM_CORE_GP;
-#endif
-
- err = mali_core_renderunit_init( core );
- if (_MALI_OSK_ERR_OK != err)
- {
- MALI_DEBUG_PRINT(1, ("Failed to initialize renderunit\n"));
- goto exit_on_error0;
- }
-
- /* Map the new core object, setting: core->registers_mapped */
- err = mali_core_renderunit_map_registers(core);
- if (_MALI_OSK_ERR_OK != err) goto exit_on_error1;
-
- /* Check that the register mapping of the core works.
- Return 0 if maligp core is present and accessible. */
- if (mali_benchmark) {
- core->core_version = MALI_GP_PRODUCT_ID << 16;
- } else {
- core->core_version = mali_core_renderunit_register_read(core, MALIGP2_REG_ADDR_MGMT_VERSION);
- }
-
- err = maligp_core_version_legal(core);
- if (_MALI_OSK_ERR_OK != err) goto exit_on_error2;
-
- /* Reset the core. Put the core into a state where it can start to render. */
- maligp_reset(core);
-
- /* Registering IRQ, init the work_queue_irq_handle */
- /* Adding this core as an available renderunit in the subsystem. */
- err = mali_core_subsystem_register_renderunit(&subsystem_maligp, core);
- if (_MALI_OSK_ERR_OK != err) goto exit_on_error2;
-
-#ifdef DEBUG
- MALI_DEBUG_PRINT(4, ("Mali GP: Initial Register settings:\n"));
- maligp_print_regs(4, core);
-#endif
-
- MALI_DEBUG_PRINT(6, ("Mali GP: maligp_renderunit_create\n") ) ;
-
- MALI_SUCCESS;
-
-exit_on_error2:
- mali_core_renderunit_unmap_registers(core);
-exit_on_error1:
- mali_core_renderunit_term(core);
-exit_on_error0:
- _mali_osk_free( core ) ;
- MALI_PRINT_ERROR(("Renderunit NOT created."));
- MALI_ERROR((_mali_osk_errcode_t)err);
-}
-
-#if USING_MMU
-/* Used currently only for signalling when MMU has a pagefault */
-static void maligp_subsystem_broadcast_notification(mali_core_notification_message message, u32 data)
-{
- mali_core_subsystem_broadcast_notification(&subsystem_maligp, message, data);
-}
-#endif
-
-#ifdef DEBUG
-static void maligp_print_regs(int debug_level, mali_core_renderunit *core)
-{
- if (debug_level <= mali_debug_level)
- {
- MALI_DEBUG_PRINT(1, (" VS 0x%08X 0x%08X, PLBU 0x%08X 0x%08X ALLOC 0x%08X 0x%08X\n",
- mali_core_renderunit_register_read(core, MALIGP2_REG_ADDR_MGMT_VSCL_START_ADDR),
- mali_core_renderunit_register_read(core, MALIGP2_REG_ADDR_MGMT_VSCL_END_ADDR),
- mali_core_renderunit_register_read(core, MALIGP2_REG_ADDR_MGMT_PLBUCL_START_ADDR),
- mali_core_renderunit_register_read(core, MALIGP2_REG_ADDR_MGMT_PLBUCL_END_ADDR),
- mali_core_renderunit_register_read(core, MALIGP2_REG_ADDR_MGMT_PLBU_ALLOC_START_ADDR),
- mali_core_renderunit_register_read(core, MALIGP2_REG_ADDR_MGMT_PLBU_ALLOC_END_ADDR))
- );
- MALI_DEBUG_PRINT(1, (" IntRaw 0x%08X IntMask 0x%08X, Status 0x%02X Ver: 0x%08X \n",
- mali_core_renderunit_register_read(core, MALIGP2_REG_ADDR_MGMT_INT_RAWSTAT),
- mali_core_renderunit_register_read(core, MALIGP2_REG_ADDR_MGMT_INT_MASK),
- mali_core_renderunit_register_read(core, MALIGP2_REG_ADDR_MGMT_STATUS),
- mali_core_renderunit_register_read(core, MALIGP2_REG_ADDR_MGMT_VERSION)));
-
- MALI_DEBUG_PRINT(1, (" PERF_CNT Enbl:%d %d Src: %02d %02d VAL: 0x%08X 0x%08X\n",
- mali_core_renderunit_register_read(core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_0_ENABLE),
- mali_core_renderunit_register_read(core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_1_ENABLE),
- mali_core_renderunit_register_read(core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_0_SRC),
- mali_core_renderunit_register_read(core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_1_SRC),
- mali_core_renderunit_register_read(core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_0_VALUE),
- mali_core_renderunit_register_read(core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_1_VALUE)));
-
- MALI_DEBUG_PRINT(1, (" VS_START 0x%08X PLBU_START 0x%08X AXI_ERR 0x%08X\n",
- mali_core_renderunit_register_read(core, MALIGP2_REG_ADDR_MGMT_VSCL_START_ADDR_READ),
- mali_core_renderunit_register_read(core, MALIGP2_REG_ADDR_MGMT_PLBCL_START_ADDR_READ),
- mali_core_renderunit_register_read(core, MALIGP2_CONTR_AXI_BUS_ERROR_STAT)));
- }
-}
-#endif
-
-static _mali_osk_errcode_t maligp_core_version_legal( mali_core_renderunit *core )
-{
- u32 mali_type;
-
- mali_type = core->core_version >> 16;
-
-#if defined(USING_MALI400)
- if ( MALI400_GP_PRODUCT_ID != mali_type && MALI300_GP_PRODUCT_ID != mali_type )
-#else
- if ( MALI_GP_PRODUCT_ID != mali_type )
-#endif
- {
- MALI_PRINT_ERROR(("Error: reading this from maligp version register: 0x%x\n", core->core_version));
- MALI_ERROR(_MALI_OSK_ERR_FAULT);
- }
- MALI_DEBUG_PRINT(3, ("Mali GP: core_version_legal: Reads correct mali version: %d\n", core->core_version )) ;
- MALI_SUCCESS;
-}
-
-static void subsystem_maligp_renderunit_stop_bus(struct mali_core_renderunit* core)
-{
- mali_core_renderunit_register_write(core, MALIGP2_REG_ADDR_MGMT_CMD, MALIGP2_REG_VAL_CMD_STOP_BUS);
-}
-
-static void maligp_reset( mali_core_renderunit *core )
-{
- if (!mali_benchmark) {
- maligp_raw_reset(core);
- maligp_initialize_registers_mgmt(core);
- }
-}
-
-
-static void maligp_reset_hard( mali_core_renderunit *core )
-{
- const int reset_finished_loop_count = 15;
- 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_core_renderunit_register_write(core, reset_wait_target_register, reset_invalid_value);
-
- mali_core_renderunit_register_write(core, MALIGP2_REG_ADDR_MGMT_CMD, MALIGP2_REG_VAL_CMD_RESET);
-
- for (i = 0; i < reset_finished_loop_count; i++)
- {
- mali_core_renderunit_register_write(core, reset_wait_target_register, reset_check_value);
- if (reset_check_value == mali_core_renderunit_register_read(core, reset_wait_target_register))
- {
- MALI_DEBUG_PRINT(5, ("Reset loop exiting after %d iterations\n", i));
- break;
- }
- }
-
- if (i == reset_finished_loop_count)
- {
- MALI_DEBUG_PRINT(1, ("The reset loop didn't work\n"));
- }
-
- mali_core_renderunit_register_write(core, reset_wait_target_register, reset_default_value); /* set it back to the default */
- mali_core_renderunit_register_write(core, MALIGP2_REG_ADDR_MGMT_INT_CLEAR, MALIGP2_REG_VAL_IRQ_MASK_ALL);
-
-
-}
-
-static void maligp_raw_reset( mali_core_renderunit *core )
-{
- int i;
- const int request_loop_count = 20;
-
- MALI_DEBUG_PRINT(4, ("Mali GP: maligp_raw_reset: %s\n", core->description)) ;
- if (mali_benchmark) return;
-
- mali_core_renderunit_register_write(core, MALIGP2_REG_ADDR_MGMT_INT_MASK, 0); /* disable the IRQs */
-
-#if defined(USING_MALI200)
-
- mali_core_renderunit_register_write(core, MALIGP2_REG_ADDR_MGMT_CMD, MALIGP2_REG_VAL_CMD_STOP_BUS);
-
- for (i = 0; i < request_loop_count; i++)
- {
- if (mali_core_renderunit_register_read(core, MALIGP2_REG_ADDR_MGMT_STATUS) & MALIGP2_REG_VAL_STATUS_BUS_STOPPED) break;
- _mali_osk_time_ubusydelay(10);
- }
-
- MALI_DEBUG_PRINT_IF(1, request_loop_count == i, ("Mali GP: Bus was never stopped during core reset\n"));
-
- if (request_loop_count==i)
- {
- /* Could not stop bus connections from core, probably because some of the already pending
- bus request has had a page fault, and therefore can not complete before the MMU does PageFault
- handling. This can be treated as a heavier reset function - which unfortunately reset all
- the cores on this MMU in addition to the MMU itself */
-#if USING_MMU
- if ((NULL!=core->mmu) && (MALI_FALSE == core->error_recovery))
- {
- MALI_DEBUG_PRINT(1, ("Mali GP: Forcing MMU bus reset\n"));
- mali_kernel_mmu_force_bus_reset(core->mmu);
- return;
- }
-#endif
- MALI_PRINT(("A MMU reset did not allow GP to stop its bus, system failure, unable to recover\n"));
- return;
- }
-
- /* the bus was stopped OK, complete the reset */
- /* use the hard reset routine to do the actual reset */
- maligp_reset_hard(core);
-
-#elif defined(USING_MALI400)
-
- mali_core_renderunit_register_write(core, MALIGP2_REG_ADDR_MGMT_INT_CLEAR, MALI400GP_REG_VAL_IRQ_RESET_COMPLETED);
- mali_core_renderunit_register_write(core, MALIGP2_REG_ADDR_MGMT_CMD, MALI400GP_REG_VAL_CMD_SOFT_RESET);
-
- for (i = 0; i < request_loop_count; i++)
- {
- if (mali_core_renderunit_register_read(core, MALIGP2_REG_ADDR_MGMT_INT_RAWSTAT) & /*Bitwise OR*/
- MALI400GP_REG_VAL_IRQ_RESET_COMPLETED) break;
- _mali_osk_time_ubusydelay(10);
- }
-
- if ( request_loop_count==i )
- {
-#if USING_MMU
- /* Could not stop bus connections from core, probably because some of the already pending
- bus request has had a page fault, and therefore can not complete before the MMU does PageFault
- handling. This can be treated as a heavier reset function - which unfortunately reset all
- the cores on this MMU in addition to the MMU itself */
- if ((NULL!=core->mmu) && (MALI_FALSE == core->error_recovery))
- {
- MALI_DEBUG_PRINT(1, ("Mali GP: Forcing Bus reset\n"));
- mali_kernel_mmu_force_bus_reset(core->mmu);
- return;
- }
-#endif
- MALI_PRINT(("A MMU reset did not allow GP to stop its bus, system failure, unable to recover\n"));
- }
- else
- {
- mali_core_renderunit_register_write(core, MALIGP2_REG_ADDR_MGMT_INT_CLEAR, MALIGP2_REG_VAL_IRQ_MASK_ALL);
- }
-
-#else
-#error "no supported mali core defined"
-#endif
-}
-
-/* Sets the registers on maligp according to the const default_mgmt_regs array. */
-static void maligp_initialize_registers_mgmt(mali_core_renderunit *core )
-{
- int i;
-
- MALI_DEBUG_PRINT(6, ("Mali GP: maligp_initialize_registers_mgmt: %s\n", core->description)) ;
- for(i=0 ; i< (sizeof(default_mgmt_regs)/sizeof(*default_mgmt_regs)) ; ++i)
- {
- mali_core_renderunit_register_write_relaxed(core, default_mgmt_regs[i].address, default_mgmt_regs[i].value);
- }
- _mali_osk_write_mem_barrier();
-}
-
-
-/* Start this job on this core. Return MALI_TRUE if the job was started. */
-static _mali_osk_errcode_t subsystem_maligp_start_job(mali_core_job * job, mali_core_renderunit * core)
-{
- maligp_job *jobgp;
- u32 startcmd;
- /* The local extended version of the general structs */
- jobgp = _MALI_OSK_CONTAINER_OF(job, maligp_job, embedded_core_job);
-
- startcmd = 0;
- if ( jobgp->user_input.frame_registers[0] != jobgp->user_input.frame_registers[1] )
- {
- startcmd |= (u32) MALIGP2_REG_VAL_CMD_START_VS;
- }
-
- if ( jobgp->user_input.frame_registers[2] != jobgp->user_input.frame_registers[3] )
- {
- startcmd |= (u32) MALIGP2_REG_VAL_CMD_START_PLBU;
- }
-
- if(0 == startcmd)
- {
- MALI_DEBUG_PRINT(4, ("Mali GP: Job: 0x%08x WILL NOT START SINCE JOB HAS ILLEGAL ADDRESSES\n",
- (u32)jobgp->user_input.user_job_ptr));
- MALI_ERROR(_MALI_OSK_ERR_FAULT);
- }
-
-
-#ifdef DEBUG
- MALI_DEBUG_PRINT(4, ("Mali GP: Registers Start\n"));
- maligp_print_regs(4, core);
-#endif
-
-
- mali_core_renderunit_register_write_array(
- core,
- MALIGP2_REG_ADDR_MGMT_VSCL_START_ADDR,
- &(jobgp->user_input.frame_registers[0]),
- sizeof(jobgp->user_input.frame_registers)/sizeof(jobgp->user_input.frame_registers[0]));
-
-#if MALI_TRACEPOINTS_ENABLED
- jobgp->user_input.perf_counter_flag = 0;
-
- if( counter_table[7] != 0xFFFFFFFF ) {
- jobgp->user_input.perf_counter_flag |= _MALI_PERFORMANCE_COUNTER_FLAG_SRC0_ENABLE;
- jobgp->user_input.perf_counter_src0 = counter_table[7];
- }
- if( counter_table[8] != 0xFFFFFFFF ) {
- jobgp->user_input.perf_counter_flag |= _MALI_PERFORMANCE_COUNTER_FLAG_SRC1_ENABLE;
- jobgp->user_input.perf_counter_src1 = counter_table[8];
- }
-#endif
-
- /* This selects which performance counters we are reading */
- if ( 0 != jobgp->user_input.perf_counter_flag )
- {
- if ( jobgp->user_input.perf_counter_flag & _MALI_PERFORMANCE_COUNTER_FLAG_SRC0_ENABLE)
- {
- mali_core_renderunit_register_write_relaxed(
- core,
- MALIGP2_REG_ADDR_MGMT_PERF_CNT_0_SRC,
- jobgp->user_input.perf_counter_src0);
-
- mali_core_renderunit_register_write_relaxed(
- core,
- MALIGP2_REG_ADDR_MGMT_PERF_CNT_0_ENABLE,
- MALIGP2_REG_VAL_PERF_CNT_ENABLE);
- }
-
- if ( jobgp->user_input.perf_counter_flag & _MALI_PERFORMANCE_COUNTER_FLAG_SRC1_ENABLE)
- {
- mali_core_renderunit_register_write_relaxed(
- core,
- MALIGP2_REG_ADDR_MGMT_PERF_CNT_1_SRC,
- jobgp->user_input.perf_counter_src1);
-
- mali_core_renderunit_register_write_relaxed(
- core,
- MALIGP2_REG_ADDR_MGMT_PERF_CNT_1_ENABLE,
- MALIGP2_REG_VAL_PERF_CNT_ENABLE);
- }
-
-#if defined(USING_MALI400_L2_CACHE)
- if ( jobgp->user_input.perf_counter_flag & (_MALI_PERFORMANCE_COUNTER_FLAG_L2_SRC0_ENABLE|_MALI_PERFORMANCE_COUNTER_FLAG_L2_SRC1_ENABLE) )
- {
- int force_reset = ( jobgp->user_input.perf_counter_flag & _MALI_PERFORMANCE_COUNTER_FLAG_L2_RESET ) ? 1 : 0;
- u32 src0 = 0;
- u32 src1 = 0;
-
- if ( jobgp->user_input.perf_counter_flag & _MALI_PERFORMANCE_COUNTER_FLAG_L2_SRC0_ENABLE )
- {
- src0 = jobgp->user_input.perf_counter_l2_src0;
- }
- if ( jobgp->user_input.perf_counter_flag & _MALI_PERFORMANCE_COUNTER_FLAG_L2_SRC1_ENABLE )
- {
- src1 = jobgp->user_input.perf_counter_l2_src1;
- }
-
- mali_kernel_l2_cache_set_perf_counters(src0, src1, force_reset); /* will activate and possibly reset counters */
-
- /* Now, retrieve the current values, so we can substract them when the job has completed */
- mali_kernel_l2_cache_get_perf_counters(&jobgp->perf_counter_l2_src0,
- &jobgp->perf_counter_l2_val0,
- &jobgp->perf_counter_l2_src1,
- &jobgp->perf_counter_l2_val1);
- }
-#endif
- }
-
- if ( 0 == (jobgp->user_input.perf_counter_flag & _MALI_PERFORMANCE_COUNTER_FLAG_SRC1_ENABLE))
- {
- /* extended progress checking can be enabled */
-
- jobgp->have_extended_progress_checking = 1;
-
- mali_core_renderunit_register_write_relaxed(
- core,
- MALIGP2_REG_ADDR_MGMT_PERF_CNT_1_SRC,
- MALIGP2_REG_VAL_PERF_CNT1_SRC_NUMBER_OF_VERTICES_PROCESSED
- );
-
- mali_core_renderunit_register_write_relaxed(
- core,
- MALIGP2_REG_ADDR_MGMT_PERF_CNT_1_ENABLE,
- MALIGP2_REG_VAL_PERF_CNT_ENABLE);
- }
-
- subsystem_flush_mapped_mem_cache();
-
- MALI_DEBUG_PRINT(4, ("Mali GP: STARTING GP WITH CMD: 0x%x\n", startcmd));
-#if MALI_STATE_TRACKING
- _mali_osk_atomic_inc(&job->session->jobs_started);
-#endif
-
- /* This is the command that starts the Core */
- mali_core_renderunit_register_write(core,
- MALIGP2_REG_ADDR_MGMT_CMD,
- startcmd);
- _mali_osk_write_mem_barrier();
-
- pr_debug("SPI_GPU_GP Start\n");
-#if MALI_TIMELINE_PROFILING_ENABLED
- _mali_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE | MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(core->core_number) | MALI_PROFILING_EVENT_REASON_SINGLE_HW_FLUSH,
- jobgp->user_input.frame_builder_id, jobgp->user_input.flush_id, 0, 0, 0);
- _mali_profiling_add_event(MALI_PROFILING_EVENT_TYPE_START|MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(core->core_number), jobgp->pid, jobgp->tid, 0, 0, 0);
-#endif
-
- MALI_SUCCESS;
-}
-
-/* Check if given core has an interrupt pending. Return MALI_TRUE and set mask to 0 if pending */
-
-static u32 subsystem_maligp_irq_handler_upper_half(mali_core_renderunit * core)
-{
- u32 irq_readout;
-
- if (mali_benchmark) {
- return (core->current_job ? 1 : 0); /* simulate irq is pending when a job is pending */
- }
-
- irq_readout = mali_core_renderunit_register_read(core, MALIGP2_REG_ADDR_MGMT_INT_STAT);
-
- MALI_DEBUG_PRINT(5, ("Mali GP: IRQ: %04x\n", irq_readout)) ;
-
- if ( MALIGP2_REG_VAL_IRQ_MASK_NONE != irq_readout )
- {
- /* Mask out all IRQs from this core until IRQ is handled */
- mali_core_renderunit_register_write(core, MALIGP2_REG_ADDR_MGMT_INT_MASK, MALIGP2_REG_VAL_IRQ_MASK_NONE);
-
-#if MALI_TIMELINE_PROFILING_ENABLED
- _mali_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE|MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(core->core_number)|MALI_PROFILING_EVENT_REASON_SINGLE_HW_INTERRUPT, irq_readout, 0, 0, 0, 0);
-#endif
-
- /* We do need to handle this in a bottom half, return 1 */
- return 1;
- }
- return 0;
-}
-
-/* This function should check if the interrupt indicates that job was finished.
-If so it should update the job-struct, reset the core registers, and return MALI_TRUE, .
-If the job is still working after this function it should return MALI_FALSE.
-The function must also enable the bits in the interrupt mask for the core.
-Called by the bottom half interrupt function. */
-static int subsystem_maligp_irq_handler_bottom_half(mali_core_renderunit* core)
-{
- mali_core_job * job;
- maligp_job * jobgp;
- u32 irq_readout;
- u32 core_status;
- u32 vscl;
- u32 plbcl;
-
- job = core->current_job;
-
- if (mali_benchmark) {
- MALI_DEBUG_PRINT(3, ("MaliGP: Job: Benchmark\n") );
- irq_readout = MALIGP2_REG_VAL_IRQ_VS_END_CMD_LST | MALIGP2_REG_VAL_IRQ_PLBU_END_CMD_LST;
- core_status = 0;
- } else {
- irq_readout = mali_core_renderunit_register_read(core, MALIGP2_REG_ADDR_MGMT_INT_RAWSTAT) & MALIGP2_REG_VAL_IRQ_MASK_USED;
- core_status = mali_core_renderunit_register_read(core, MALIGP2_REG_ADDR_MGMT_STATUS);
- }
-
- if (NULL == job)
- {
- MALI_DEBUG_ASSERT(CORE_IDLE==core->state);
- if ( 0 != irq_readout )
- {
- MALI_PRINT_ERROR(("Interrupt from a core not running a job. IRQ: 0x%04x Status: 0x%04x", irq_readout, core_status));
- }
- return JOB_STATUS_END_UNKNOWN_ERR;
- }
- MALI_DEBUG_ASSERT(CORE_IDLE!=core->state);
-
- jobgp = GET_JOBGP2_PTR(job);
-
- jobgp->heap_current_addr = mali_core_renderunit_register_read(core, MALIGP2_REG_ADDR_MGMT_PLBU_ALLOC_START_ADDR);
-
- vscl = mali_core_renderunit_register_read(core, MALIGP2_REG_ADDR_MGMT_VSCL_START_ADDR);
- plbcl = mali_core_renderunit_register_read(core, MALIGP2_REG_ADDR_MGMT_PLBUCL_START_ADDR);
-
- MALI_DEBUG_PRINT(3, ("Mali GP: Job: 0x%08x IRQ RECEIVED Rawstat: 0x%x Status: 0x%x\n",
- (u32)jobgp->user_input.user_job_ptr, irq_readout , core_status )) ;
-
- jobgp->irq_status |= irq_readout;
- jobgp->status_reg_on_stop = core_status;
-
- if ( 0 != jobgp->is_stalled_waiting_for_more_memory )
- {
- /* Readback the performance counters */
- if (jobgp->user_input.perf_counter_flag & (_MALI_PERFORMANCE_COUNTER_FLAG_SRC0_ENABLE|_MALI_PERFORMANCE_COUNTER_FLAG_SRC1_ENABLE) )
- {
- jobgp->perf_counter0 = mali_core_renderunit_register_read(core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_0_VALUE);
- jobgp->perf_counter1 = mali_core_renderunit_register_read(core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_1_VALUE);
-
-#if MALI_TRACEPOINTS_ENABLED
- //TODO magic numbers should come from mali_linux_trace.h instead
- _mali_profiling_add_counter(7, jobgp->perf_counter0);
- _mali_profiling_add_counter(8, jobgp->perf_counter1);
-#endif
- }
-
-#if defined(USING_MALI400_L2_CACHE)
- if (jobgp->user_input.perf_counter_flag & (_MALI_PERFORMANCE_COUNTER_FLAG_L2_SRC0_ENABLE|_MALI_PERFORMANCE_COUNTER_FLAG_L2_SRC1_ENABLE) )
- {
- u32 src0;
- u32 val0;
- u32 src1;
- u32 val1;
- mali_kernel_l2_cache_get_perf_counters(&src0, &val0, &src1, &val1);
-
- if (jobgp->perf_counter_l2_src0 == src0)
- {
- jobgp->perf_counter_l2_val0 = val0 - jobgp->perf_counter_l2_val0;
- }
- else
- {
- jobgp->perf_counter_l2_val0 = 0;
- }
-
- if (jobgp->perf_counter_l2_src1 == src1)
- {
- jobgp->perf_counter_l2_val1 = val1 - jobgp->perf_counter_l2_val1;
- }
- else
- {
- jobgp->perf_counter_l2_val1 = 0;
- }
- }
-#endif
-
-#if MALI_TIMELINE_PROFILING_ENABLED
- _mali_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP|MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(core->core_number), 0, 0, 0, 0, 0); /* add GP and L2 counters and return status? */
-#endif
-
- MALI_DEBUG_PRINT(2, ("Mali GP: Job aborted - userspace would not provide more heap memory.\n"));
-#if MALI_STATE_TRACKING
- _mali_osk_atomic_inc(&job->session->jobs_ended);
-#endif
- return JOB_STATUS_END_OOM; /* Core is ready for more jobs.*/
- }
- /* finished ? */
- else if (0 == (core_status & MALIGP2_REG_VAL_STATUS_MASK_ACTIVE))
- {
-#ifdef DEBUG
- MALI_DEBUG_PRINT(4, ("Mali GP: Registers On job end:\n"));
- maligp_print_regs(4, core);
-#endif
- MALI_DEBUG_PRINT_IF(5, irq_readout & 0x04, ("OOM when done, ignoring (reg.current = 0x%x, reg.end = 0x%x)\n",
- (void*)mali_core_renderunit_register_read(core, MALIGP2_REG_ADDR_MGMT_PLBU_ALLOC_START_ADDR),
- (void*)mali_core_renderunit_register_read(core, MALIGP2_REG_ADDR_MGMT_PLBU_ALLOC_END_ADDR))
- );
-
-
- if (0 != jobgp->user_input.perf_counter_flag )
- {
- /* Readback the performance counters */
- if (jobgp->user_input.perf_counter_flag & (_MALI_PERFORMANCE_COUNTER_FLAG_SRC0_ENABLE|_MALI_PERFORMANCE_COUNTER_FLAG_SRC1_ENABLE) )
- {
- jobgp->perf_counter0 = mali_core_renderunit_register_read(core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_0_VALUE);
- jobgp->perf_counter1 = mali_core_renderunit_register_read(core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_1_VALUE);
-
-#if MALI_TRACEPOINTS_ENABLED
- //TODO magic numbers should come from mali_linux_trace.h instead
- _mali_profiling_add_counter(7, jobgp->perf_counter0);
- _mali_profiling_add_counter(8, jobgp->perf_counter1);
-#endif
- }
-
-#if defined(USING_MALI400_L2_CACHE)
- if (jobgp->user_input.perf_counter_flag & (_MALI_PERFORMANCE_COUNTER_FLAG_L2_SRC0_ENABLE|_MALI_PERFORMANCE_COUNTER_FLAG_L2_SRC1_ENABLE) )
- {
- u32 src0;
- u32 val0;
- u32 src1;
- u32 val1;
- mali_kernel_l2_cache_get_perf_counters(&src0, &val0, &src1, &val1);
-
- if (jobgp->perf_counter_l2_src0 == src0)
- {
- jobgp->perf_counter_l2_val0 = val0 - jobgp->perf_counter_l2_val0;
- }
- else
- {
- jobgp->perf_counter_l2_val0 = 0;
- }
-
- if (jobgp->perf_counter_l2_src1 == src1)
- {
- jobgp->perf_counter_l2_val1 = val1 - jobgp->perf_counter_l2_val1;
- }
- else
- {
- jobgp->perf_counter_l2_val1 = 0;
- }
- }
-#endif
- }
-
-#if MALI_TIMELINE_PROFILING_ENABLED
- _mali_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP|MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(core->core_number),
- jobgp->perf_counter0, jobgp->perf_counter1,
- jobgp->user_input.perf_counter_src0 | (jobgp->user_input.perf_counter_src1 << 8)
-#if defined(USING_MALI400_L2_CACHE)
- | (jobgp->user_input.perf_counter_l2_src0 << 16) | (jobgp->user_input.perf_counter_l2_src1 << 24),
- jobgp->perf_counter_l2_val0,
- jobgp->perf_counter_l2_val1
-#else
- ,0, 0
-#endif
- );
-#endif
-
- mali_core_renderunit_register_write(core, MALIGP2_REG_ADDR_MGMT_INT_CLEAR, MALIGP2_REG_VAL_IRQ_MASK_ALL);
-
-#if MALI_STATE_TRACKING
- _mali_osk_atomic_inc(&job->session->jobs_ended);
-#endif
- pr_debug("SPI_GPU_GP Idle\n");
- return JOB_STATUS_END_SUCCESS; /* core idle */
- }
- /* sw watchdog timeout handling or time to do hang checking ? */
- else if (
- (CORE_WATCHDOG_TIMEOUT == core->state) ||
- (
- (CORE_HANG_CHECK_TIMEOUT == core->state) &&
- (
- (jobgp->have_extended_progress_checking ? (mali_core_renderunit_register_read(core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_1_VALUE) == jobgp->vertices) : 1/*TRUE*/) &&
- ((core_status & MALIGP2_REG_VAL_STATUS_VS_ACTIVE) ? (vscl == jobgp->last_vscl) : 1/*TRUE*/) &&
- ((core_status & MALIGP2_REG_VAL_STATUS_PLBU_ACTIVE) ? (plbcl == jobgp->last_plbcl) : 1/*TRUE*/)
- )
- )
- )
- {
- /* no progress detected, killed by the watchdog */
-
-#if MALI_TIMELINE_PROFILING_ENABLED
- _mali_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP|MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(core->core_number), 0, 0, 0, 0, 0); /* add GP and L2 counters and return status? */
-#endif
-
- MALI_PRINT( ("Mali GP: SW-Timeout.\n"));
- if (core_status & MALIGP2_REG_VAL_STATUS_VS_ACTIVE) MALI_DEBUG_PRINT(1, ("vscl current = 0x%x last = 0x%x\n", (void*)vscl, (void*)jobgp->last_vscl));
- if (core_status & MALIGP2_REG_VAL_STATUS_PLBU_ACTIVE) MALI_DEBUG_PRINT(1, ("plbcl current = 0x%x last = 0x%x\n", (void*)plbcl, (void*)jobgp->last_plbcl));
- if (jobgp->have_extended_progress_checking) MALI_DEBUG_PRINT(1, ("vertices processed = %d, last = %d\n", mali_core_renderunit_register_read(core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_1_VALUE),
- jobgp->vertices));
-#ifdef DEBUG
- maligp_print_regs(2, core);
-#endif
-
-#if MALI_STATE_TRACKING
- _mali_osk_atomic_inc(&job->session->jobs_ended);
-#endif
- MALI_PANIC("%s Watchdog timeout\n", MALI_GP_SUBSYSTEM_NAME);
- return JOB_STATUS_END_HANG;
- }
- /* if hang timeout checking was enabled and we detected progress, will be fall down to this check */
- /* check for PLBU OOM before the hang check to avoid the race condition of the hw wd trigging while waiting for us to handle the OOM interrupt */
- else if ( 0 != (irq_readout & MALIGP2_REG_VAL_IRQ_PLBU_OUT_OF_MEM))
- {
- mali_core_session *session;
- _mali_osk_notification_t *notific;
- _mali_uk_gp_job_suspended_s * suspended_job;
-
-#if MALI_TIMELINE_PROFILING_ENABLED
- _mali_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SUSPEND|MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(core->core_number), 0, 0, 0, 0, 0); /* add GP and L2 counters and return status? */
-#endif
-
- session = job->session;
-
- MALI_DEBUG_PRINT(4, ("OOM, new heap requested by GP\n"));
- MALI_DEBUG_PRINT(4, ("Status when OOM: current = 0x%x, end = 0x%x\n",
- (void*)mali_core_renderunit_register_read(core, MALIGP2_REG_ADDR_MGMT_PLBU_ALLOC_START_ADDR),
- (void*)mali_core_renderunit_register_read(core, MALIGP2_REG_ADDR_MGMT_PLBU_ALLOC_END_ADDR))
- );
-
- notific = _mali_osk_notification_create(
-
- _MALI_NOTIFICATION_GP_STALLED,
- sizeof( _mali_uk_gp_job_suspended_s )
- );
- if ( NULL == notific)
- {
- MALI_PRINT_ERROR( ("Mali GP: Could not get notification object\n")) ;
- return JOB_STATUS_END_OOM; /* Core is ready for more jobs.*/
- }
-
- core->state = CORE_WORKING;
- jobgp->is_stalled_waiting_for_more_memory = 1;
- suspended_job = (_mali_uk_gp_job_suspended_s *)notific->result_buffer; /* this is ok - result_buffer was malloc'd */
-
- suspended_job->user_job_ptr = jobgp->user_input.user_job_ptr;
- suspended_job->reason = _MALIGP_JOB_SUSPENDED_OUT_OF_MEMORY ;
- suspended_job->cookie = (u32) core;
- last_gp_core_cookie = core;
-
- _mali_osk_notification_queue_send( session->notification_queue, notific);
-
-#ifdef DEBUG
- maligp_print_regs(4, core);
-#endif
-
- /* stop all active timers */
- _mali_osk_timer_del( core->timer);
- _mali_osk_timer_del( core->timer_hang_detection);
- MALI_DEBUG_PRINT(4, ("Mali GP: PLBU heap empty, sending memory request to userspace\n"));
- /* save to watchdog_jiffies what was remaining WD timeout value when OOM was triggered */
- job->watchdog_jiffies = (long)job->watchdog_jiffies - (long)_mali_osk_time_tickcount();
- /* reuse core->timer as the userspace response timeout handler */
- _mali_osk_timer_add( core->timer, _mali_osk_time_mstoticks(1000) ); /* wait max 1 sec for userspace to respond */
- return JOB_STATUS_CONTINUE_RUN; /* The core is NOT available for new jobs. */
- }
- /* hw watchdog is reporting a new hang or an existing progress-during-hang check passed? */
- else if ((CORE_HANG_CHECK_TIMEOUT == core->state) || (irq_readout & jobgp->active_mask & MALIGP2_REG_VAL_IRQ_HANG))
- {
- /* check interval in ms */
- u32 timeout = mali_core_hang_check_timeout_get();
- MALI_DEBUG_PRINT(3, ("Mali GP: HW/SW Watchdog triggered, checking for progress in %d ms\n", timeout));
- core->state = CORE_WORKING;
-
- /* save state for the progress checking */
- jobgp->last_vscl = vscl;
- jobgp->last_plbcl = plbcl;
- if (jobgp->have_extended_progress_checking)
- {
- jobgp->vertices = mali_core_renderunit_register_read(core, MALIGP2_REG_ADDR_MGMT_PERF_CNT_1_VALUE);
- }
- /* hw watchdog triggered, set up a progress checker every HANGCHECK ms */
- _mali_osk_timer_add( core->timer_hang_detection, _mali_osk_time_mstoticks(timeout));
- jobgp->active_mask &= ~MALIGP2_REG_VAL_IRQ_HANG; /* ignore the hw watchdog from now on */
- mali_core_renderunit_register_write(core, MALIGP2_REG_ADDR_MGMT_INT_CLEAR, irq_readout);
- mali_core_renderunit_register_write(core, MALIGP2_REG_ADDR_MGMT_INT_MASK, jobgp->active_mask);
- return JOB_STATUS_CONTINUE_RUN; /* not finihsed */ }
- /* no errors, but still working */
- else if ( ( 0 == (core_status & MALIGP2_REG_VAL_STATUS_MASK_ERROR)) &&
- ( 0 != (core_status & MALIGP2_REG_VAL_STATUS_MASK_ACTIVE ))
- )
- {
- mali_core_renderunit_register_write(core, MALIGP2_REG_ADDR_MGMT_INT_CLEAR, irq_readout);
- mali_core_renderunit_register_write(core, MALIGP2_REG_ADDR_MGMT_INT_MASK, jobgp->active_mask);
- return JOB_STATUS_CONTINUE_RUN;
- }
- /* Else there must be some error */
- else
- {
-#if MALI_TIMELINE_PROFILING_ENABLED
- _mali_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP|MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(core->core_number), 0, 0, 0, 0, 0); /* add GP and L2 counters and return status? */
-#endif
-
- MALI_PRINT( ("Mali GP: Core crashed? *IRQ: 0x%x Status: 0x%x\n", irq_readout, core_status ));
- #ifdef DEBUG
- MALI_DEBUG_PRINT(1, ("Mali GP: Registers Before reset:\n"));
- maligp_print_regs(1, core);
- #endif
-#if MALI_STATE_TRACKING
- _mali_osk_atomic_inc(&job->session->jobs_ended);
-#endif
- return JOB_STATUS_END_UNKNOWN_ERR;
- }
-}
-
-
-/* This function is called from the ioctl function and should return a mali_core_job pointer
-to a created mali_core_job object with the data given from userspace */
-static _mali_osk_errcode_t subsystem_maligp_get_new_job_from_user(struct mali_core_session * session, void * argument)
-{
- maligp_job *jobgp;
- mali_core_job *job = NULL;
- mali_core_job *previous_replaced_job;
- _mali_osk_errcode_t err = _MALI_OSK_ERR_OK;
- _mali_uk_gp_start_job_s * user_ptr_job_input;
-
- user_ptr_job_input = (_mali_uk_gp_start_job_s *)argument;
-
- MALI_CHECK_NON_NULL(jobgp = (maligp_job *) _mali_osk_calloc(1, sizeof(maligp_job)), _MALI_OSK_ERR_FAULT);
-
- /* Copy the job data from the U/K interface */
- if ( NULL == _mali_osk_memcpy(&jobgp->user_input, user_ptr_job_input, sizeof(_mali_uk_gp_start_job_s) ) )
- {
- MALI_PRINT_ERROR( ("Mali GP: Could not copy data from U/K interface.\n")) ;
- err = _MALI_OSK_ERR_FAULT;
- goto function_exit;
- }
-
- MALI_DEBUG_PRINT(3, ("Mali GP: subsystem_maligp_get_new_job_from_user 0x%x\n", (void*)jobgp->user_input.user_job_ptr));
-
- MALI_DEBUG_PRINT(3, ("Mali GP: Job Regs: 0x%08X 0x%08X, 0x%08X 0x%08X 0x%08X 0x%08X\n",
- jobgp->user_input.frame_registers[0],
- jobgp->user_input.frame_registers[1],
- jobgp->user_input.frame_registers[2],
- jobgp->user_input.frame_registers[3],
- jobgp->user_input.frame_registers[4],
- jobgp->user_input.frame_registers[5]) );
-
-
- job = GET_JOB_EMBEDDED_PTR(jobgp);
-
- job->session = session;
- job->flags = MALI_UK_START_JOB_FLAG_DEFAULT; /* Current flags only make sence for PP jobs */
- job_priority_set(job, jobgp->user_input.priority);
- job_watchdog_set(job, jobgp->user_input.watchdog_msecs );
- jobgp->heap_current_addr = jobgp->user_input.frame_registers[4];
-
- job->abort_id = jobgp->user_input.abort_id;
-
- jobgp->is_stalled_waiting_for_more_memory = 0;
-
-#if MALI_TIMELINE_PROFILING_ENABLED
- jobgp->pid = _mali_osk_get_pid();
- jobgp->tid = _mali_osk_get_tid();
-#endif
-
- if (mali_job_queue_full(session))
- {
- /* Cause jobgp to free: */
- user_ptr_job_input->status = _MALI_UK_START_JOB_NOT_STARTED_DO_REQUEUE;
- goto function_exit;
- }
-
- /* We now know that we have a job, and a slot to put it in */
-
- jobgp->active_mask = MALIGP2_REG_VAL_IRQ_MASK_USED;
-
- /* Allocating User Return Data */
- jobgp->notification_obj = _mali_osk_notification_create(
- _MALI_NOTIFICATION_GP_FINISHED,
- sizeof(_mali_uk_gp_job_finished_s) );
-
- if ( NULL == jobgp->notification_obj )
- {
- MALI_PRINT_ERROR( ("Mali GP: Could not get notification_obj.\n")) ;
- err = _MALI_OSK_ERR_NOMEM;
- goto function_exit;
- }
-
- _MALI_OSK_INIT_LIST_HEAD( &(job->list) ) ;
-
- MALI_DEBUG_PRINT(4, ("Mali GP: Job: 0x%08x INPUT from user.\n", (u32)jobgp->user_input.user_job_ptr)) ;
-
- /* This should not happen since we have the checking of priority above */
- err = mali_core_session_add_job(session, job, &previous_replaced_job);
- if ( _MALI_OSK_ERR_OK != err )
- {
- MALI_PRINT_ERROR( ("Mali GP: Internal error\n")) ;
- /* Cause jobgp to free: */
- user_ptr_job_input->status = _MALI_UK_START_JOB_NOT_STARTED_DO_REQUEUE;
- _mali_osk_notification_delete( jobgp->notification_obj );
- goto function_exit;
- }
-
- /* If MALI_TRUE: This session had a job with lower priority which were removed.
- This replaced job is given back to userspace. */
- if ( NULL != previous_replaced_job )
- {
- maligp_job *previous_replaced_jobgp;
-
- previous_replaced_jobgp = GET_JOBGP2_PTR(previous_replaced_job);
-
- MALI_DEBUG_PRINT(4, ("Mali GP: Replacing job: 0x%08x\n", (u32)previous_replaced_jobgp->user_input.user_job_ptr)) ;
-
- /* Copy to the input data (which also is output data) the
- pointer to the job that were replaced, so that the userspace
- driver can put this job in the front of its job-queue */
- user_ptr_job_input->returned_user_job_ptr = previous_replaced_jobgp->user_input.user_job_ptr;
-
- /** @note failure to 'copy to user' at this point must not free jobgp,
- * and so no transaction rollback required in the U/K interface */
-
- /* This does not cause jobgp to free: */
- user_ptr_job_input->status = _MALI_UK_START_JOB_STARTED_LOW_PRI_JOB_RETURNED;
- MALI_DEBUG_PRINT(5, ("subsystem_maligp_get_new_job_from_user: Job added, prev returned\n")) ;
- }
- else
- {
- /* This does not cause jobgp to free: */
- user_ptr_job_input->status = _MALI_UK_START_JOB_STARTED;
- MALI_DEBUG_PRINT(5, ("subsystem_maligp_get_new_job_from_user: Job added\n")) ;
- }
-
-function_exit:
- if ( _MALI_UK_START_JOB_NOT_STARTED_DO_REQUEUE == user_ptr_job_input->status
- || _MALI_OSK_ERR_OK != err )
- {
- _mali_osk_free(jobgp);
- }
-#if MALI_STATE_TRACKING
- if (_MALI_UK_START_JOB_STARTED==user_ptr_job_input->status)
- {
- if(job)
- {
- job->job_nr=_mali_osk_atomic_inc_return(&session->jobs_received);
- }
- }
-#endif
-
- MALI_ERROR(err);
-}
-
-
-static _mali_osk_errcode_t subsystem_maligp_suspend_response(struct mali_core_session * session, void * argument)
-{
- mali_core_renderunit *core;
- maligp_job *jobgp;
- mali_core_job *job;
-
- _mali_uk_gp_suspend_response_s * suspend_response;
-
- MALI_DEBUG_PRINT(5, ("subsystem_maligp_suspend_response\n"));
-
- suspend_response = (_mali_uk_gp_suspend_response_s *)argument;
-
- /* We read job data from User */
- /* On a single mali_gp system we can only have one Stalled GP,
- and therefore one stalled request with a cookie. This checks
- that we get the correct cookie */
- if ( last_gp_core_cookie != (mali_core_renderunit *)suspend_response->cookie )
- {
- MALI_DEBUG_PRINT(2, ("Mali GP: Got an illegal cookie from Userspace.\n")) ;
- MALI_ERROR(_MALI_OSK_ERR_FAULT);
- }
- core = (mali_core_renderunit *)suspend_response->cookie;
- last_gp_core_cookie = NULL;
- job = core->current_job;
- jobgp = GET_JOBGP2_PTR(job);
-
- switch( suspend_response->code )
- {
- case _MALIGP_JOB_RESUME_WITH_NEW_HEAP :
- MALI_DEBUG_PRINT(5, ("MALIGP_JOB_RESUME_WITH_NEW_HEAP jiffies: %li\n", _mali_osk_time_tickcount()));
- MALI_DEBUG_PRINT(4, ("New Heap addr 0x%08x - 0x%08x\n", suspend_response->arguments[0], suspend_response->arguments[1]));
-
- jobgp->is_stalled_waiting_for_more_memory = 0;
- job->watchdog_jiffies += _mali_osk_time_tickcount(); /* convert to absolute time again */
- _mali_osk_timer_mod( core->timer, job->watchdog_jiffies); /* update the timer */
-
-
- mali_core_renderunit_register_write(core, MALIGP2_REG_ADDR_MGMT_INT_CLEAR, (MALIGP2_REG_VAL_IRQ_PLBU_OUT_OF_MEM | MALIGP2_REG_VAL_IRQ_HANG));
- mali_core_renderunit_register_write(core, MALIGP2_REG_ADDR_MGMT_INT_MASK, jobgp->active_mask);
- mali_core_renderunit_register_write_relaxed(core, MALIGP2_REG_ADDR_MGMT_PLBU_ALLOC_START_ADDR, suspend_response->arguments[0]);
- mali_core_renderunit_register_write_relaxed(core, MALIGP2_REG_ADDR_MGMT_PLBU_ALLOC_END_ADDR, suspend_response->arguments[1]);
- mali_core_renderunit_register_write(core, MALIGP2_REG_ADDR_MGMT_CMD, MALIGP2_REG_VAL_CMD_UPDATE_PLBU_ALLOC);
- _mali_osk_write_mem_barrier();
-
-#if MALI_TIMELINE_PROFILING_ENABLED
- _mali_profiling_add_event(MALI_PROFILING_EVENT_TYPE_RESUME|MALI_PROFILING_MAKE_EVENT_CHANNEL_GP(core->core_number), 0, 0, 0, 0, 0);
-#endif
-
- MALI_DEBUG_PRINT(4, ("GP resumed with new heap\n"));
-
- break;
-
- case _MALIGP_JOB_ABORT:
- MALI_DEBUG_PRINT(3, ("MALIGP_JOB_ABORT on heap extend request\n"));
- _mali_osk_irq_schedulework( core->irq );
- break;
-
- default:
- MALI_PRINT_ERROR(("Wrong Suspend response from userspace\n"));
- }
- MALI_SUCCESS;
-}
-
-/* This function is called from the ioctl function and should write the necessary data
-to userspace telling which job was finished and the status and debuginfo for this job.
-The function must also free and cleanup the input job object. */
-static void subsystem_maligp_return_job_to_user( mali_core_job * job, mali_subsystem_job_end_code end_status )
-{
- maligp_job *jobgp;
- _mali_uk_gp_job_finished_s * job_out;
- _mali_uk_gp_start_job_s* job_input;
- mali_core_session *session;
-
-
- jobgp = _MALI_OSK_CONTAINER_OF(job, maligp_job, embedded_core_job);
- job_out = (_mali_uk_gp_job_finished_s *)jobgp->notification_obj->result_buffer; /* OK - this should've been malloc'd */
- job_input= &(jobgp->user_input);
- session = job->session;
-
- MALI_DEBUG_PRINT(5, ("Mali GP: Job: 0x%08x OUTPUT to user. Runtime: %d us, irq readout %x\n",
- (u32)jobgp->user_input.user_job_ptr,
- job->render_time_usecs,
- jobgp->irq_status)) ;
-
- _mali_osk_memset(job_out, 0 , sizeof(_mali_uk_gp_job_finished_s));
-
- job_out->user_job_ptr = job_input->user_job_ptr;
-
- switch( end_status )
- {
- case JOB_STATUS_CONTINUE_RUN:
- case JOB_STATUS_END_SUCCESS:
- case JOB_STATUS_END_OOM:
- case JOB_STATUS_END_ABORT:
- case JOB_STATUS_END_TIMEOUT_SW:
- case JOB_STATUS_END_HANG:
- case JOB_STATUS_END_SEG_FAULT:
- case JOB_STATUS_END_ILLEGAL_JOB:
- case JOB_STATUS_END_UNKNOWN_ERR:
- case JOB_STATUS_END_SHUTDOWN:
- case JOB_STATUS_END_SYSTEM_UNUSABLE:
- job_out->status = (mali_subsystem_job_end_code) end_status;
- break;
- default:
- job_out->status = JOB_STATUS_END_UNKNOWN_ERR ;
- }
-
- job_out->irq_status = jobgp->irq_status;
- job_out->status_reg_on_stop = jobgp->status_reg_on_stop;
- job_out->vscl_stop_addr = 0;
- job_out->plbcl_stop_addr = 0;
- job_out->heap_current_addr = jobgp->heap_current_addr;
- job_out->perf_counter0 = jobgp->perf_counter0;
- job_out->perf_counter1 = jobgp->perf_counter1;
- job_out->perf_counter_src0 = jobgp->user_input.perf_counter_src0 ;
- job_out->perf_counter_src1 = jobgp->user_input.perf_counter_src1 ;
- job_out->render_time = job->render_time_usecs;
-#if defined(USING_MALI400_L2_CACHE)
- job_out->perf_counter_l2_src0 = jobgp->perf_counter_l2_src0;
- job_out->perf_counter_l2_src1 = jobgp->perf_counter_l2_src1;
- job_out->perf_counter_l2_val0 = jobgp->perf_counter_l2_val0;
- job_out->perf_counter_l2_val1 = jobgp->perf_counter_l2_val1;
-#endif
-
-#if MALI_STATE_TRACKING
- _mali_osk_atomic_inc(&session->jobs_returned);
-#endif
- _mali_osk_notification_queue_send( session->notification_queue, jobgp->notification_obj);
- jobgp->notification_obj = NULL;
-
- _mali_osk_free(jobgp);
-
- last_gp_core_cookie = NULL;
-}
-
-static void subsystem_maligp_renderunit_delete(mali_core_renderunit * core)
-{
- MALI_DEBUG_PRINT(5, ("Mali GP: maligp_renderunit_delete\n"));
- _mali_osk_free(core);
-}
-
-static void subsystem_maligp_renderunit_reset_core(struct mali_core_renderunit * core, mali_core_reset_style style)
-{
- MALI_DEBUG_PRINT(5, ("Mali GP: renderunit_reset_core\n"));
-
- switch (style)
- {
- case MALI_CORE_RESET_STYLE_RUNABLE:
- maligp_reset(core);
- break;
- case MALI_CORE_RESET_STYLE_DISABLE:
- maligp_raw_reset(core); /* do the raw reset */
- mali_core_renderunit_register_write(core, MALIGP2_REG_ADDR_MGMT_INT_MASK, 0); /* then disable the IRQs */
- break;
- case MALI_CORE_RESET_STYLE_HARD:
- maligp_reset_hard(core);
- maligp_initialize_registers_mgmt(core);
- break;
- default:
- MALI_DEBUG_PRINT(1, ("Unknown reset type %d\n", style));
- break;
- }
-}
-
-static void subsystem_maligp_renderunit_probe_core_irq_trigger(struct mali_core_renderunit* core)
-{
- mali_core_renderunit_register_write(core , MALIGP2_REG_ADDR_MGMT_INT_MASK, MALIGP2_REG_VAL_IRQ_MASK_USED);
- mali_core_renderunit_register_write(core , MALIGP2_REG_ADDR_MGMT_INT_RAWSTAT, MALIGP2_REG_VAL_CMD_FORCE_HANG );
- _mali_osk_mem_barrier();
-}
-
-static _mali_osk_errcode_t subsystem_maligp_renderunit_probe_core_irq_finished(struct mali_core_renderunit* core)
-{
- u32 irq_readout;
-
- irq_readout = mali_core_renderunit_register_read(core, MALIGP2_REG_ADDR_MGMT_INT_STAT);
-
- if ( MALIGP2_REG_VAL_IRQ_FORCE_HANG & irq_readout )
- {
- mali_core_renderunit_register_write(core, MALIGP2_REG_ADDR_MGMT_INT_CLEAR, MALIGP2_REG_VAL_IRQ_FORCE_HANG);
- _mali_osk_mem_barrier();
- MALI_SUCCESS;
- }
-
- MALI_ERROR(_MALI_OSK_ERR_FAULT);
-}
-
-_mali_osk_errcode_t _mali_ukk_gp_start_job( _mali_uk_gp_start_job_s *args )
-{
- mali_core_session * session;
- MALI_DEBUG_ASSERT_POINTER(args);
- MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS);
- session = (mali_core_session *)mali_kernel_session_manager_slot_get(args->ctx, mali_subsystem_gp_id);
- MALI_CHECK_NON_NULL(session, _MALI_OSK_ERR_FAULT);
- return mali_core_subsystem_ioctl_start_job(session, args);
-}
-
-_mali_osk_errcode_t _mali_ukk_get_gp_number_of_cores( _mali_uk_get_gp_number_of_cores_s *args )
-{
- mali_core_session * session;
- MALI_DEBUG_ASSERT_POINTER(args);
- MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS);
- session = (mali_core_session *)mali_kernel_session_manager_slot_get(args->ctx, mali_subsystem_gp_id);
- MALI_CHECK_NON_NULL(session, _MALI_OSK_ERR_FAULT);
- return mali_core_subsystem_ioctl_number_of_cores_get(session, &args->number_of_cores);
-}
-
-_mali_osk_errcode_t _mali_ukk_get_gp_core_version( _mali_uk_get_gp_core_version_s *args )
-{
- mali_core_session * session;
- MALI_DEBUG_ASSERT_POINTER(args);
- MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS);
- session = (mali_core_session *)mali_kernel_session_manager_slot_get(args->ctx, mali_subsystem_gp_id);
- MALI_CHECK_NON_NULL(session, _MALI_OSK_ERR_FAULT);
- return mali_core_subsystem_ioctl_core_version_get(session, &args->version);
-}
-
-_mali_osk_errcode_t _mali_ukk_gp_suspend_response( _mali_uk_gp_suspend_response_s *args )
-{
- mali_core_session * session;
- MALI_DEBUG_ASSERT_POINTER(args);
- MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS);
- session = (mali_core_session *)mali_kernel_session_manager_slot_get(args->ctx, mali_subsystem_gp_id);
- MALI_CHECK_NON_NULL(session, _MALI_OSK_ERR_FAULT);
- return mali_core_subsystem_ioctl_suspend_response(session, args);
-}
-
-void _mali_ukk_gp_abort_job( _mali_uk_gp_abort_job_s * args)
-{
- mali_core_session * session;
- MALI_DEBUG_ASSERT_POINTER(args);
- if (NULL == args->ctx) return;
- session = (mali_core_session *)mali_kernel_session_manager_slot_get(args->ctx, mali_subsystem_gp_id);
- if (NULL == session) return;
- mali_core_subsystem_ioctl_abort_job(session, args->abort_id);
-
-}
-
-#if USING_MALI_PMM
-
-_mali_osk_errcode_t maligp_signal_power_up( mali_bool queue_only )
-{
- MALI_DEBUG_PRINT(4, ("Mali GP: signal power up core - queue_only: %d\n", queue_only ));
-
- return( mali_core_subsystem_signal_power_up( &subsystem_maligp, 0, queue_only ) );
-}
-
-_mali_osk_errcode_t maligp_signal_power_down( mali_bool immediate_only )
-{
- MALI_DEBUG_PRINT(4, ("Mali GP: signal power down core - immediate_only: %d\n", immediate_only ));
-
- return( mali_core_subsystem_signal_power_down( &subsystem_maligp, 0, immediate_only ) );
-}
-
-#endif
-
-#if MALI_STATE_TRACKING
-u32 maligp_subsystem_dump_state(char *buf, u32 size)
-{
- return mali_core_renderunit_dump_state(&subsystem_maligp, buf, size);
-}
-#endif
diff --git a/drivers/media/video/samsung/mali/common/mali_kernel_MALI200.c b/drivers/media/video/samsung/mali/common/mali_kernel_MALI200.c
deleted file mode 100644
index 0f5ebd0..0000000
--- a/drivers/media/video/samsung/mali/common/mali_kernel_MALI200.c
+++ /dev/null
@@ -1,1304 +0,0 @@
-/*
- * 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.
- */
-
-//added for SPI
-#include <linux/kernel.h>
-
-#include "mali_kernel_common.h"
-#include "mali_osk.h"
-#include "mali_kernel_pp.h"
-#include "mali_kernel_subsystem.h"
-#include "mali_kernel_core.h"
-#include "regs/mali_200_regs.h"
-#include "mali_kernel_rendercore.h"
-#if MALI_TIMELINE_PROFILING_ENABLED
-#include "mali_kernel_profiling.h"
-#endif
-#ifdef USING_MALI400_L2_CACHE
-#include "mali_kernel_l2_cache.h"
-#endif
-#if USING_MMU
-#include "mali_kernel_mem_mmu.h" /* Needed for mali_kernel_mmu_force_bus_reset() */
-#endif
-
-#include "mali_osk_list.h"
-
-#if defined(USING_MALI200)
-#define MALI_PP_SUBSYSTEM_NAME "Mali200"
-#define MALI_PP_CORE_TYPE _MALI_200
-#elif defined(USING_MALI400)
-#define MALI_PP_SUBSYSTEM_NAME "Mali-400 PP"
-#define MALI_PP_CORE_TYPE _MALI_400_PP
-#else
-#error "No supported mali core defined"
-#endif
-
-#define GET_JOB_EMBEDDED_PTR(job) (&((job)->embedded_core_job))
-#define GET_JOB200_PTR(job_extern) _MALI_OSK_CONTAINER_OF(job_extern, mali200_job, embedded_core_job)
-
-/* Initialized when this subsystem is initialized. This is determined by the
- * position in subsystems[], and so the value used to initialize this is
- * determined at compile time */
-static mali_kernel_subsystem_identifier mali_subsystem_mali200_id = -1;
-
-/* Describing a mali200 job settings */
-typedef struct mali200_job
-{
- /* The general job struct common for all mali cores */
- mali_core_job embedded_core_job;
- _mali_uk_pp_start_job_s user_input;
-
- u32 irq_status;
- u32 perf_counter0;
- u32 perf_counter1;
- u32 last_tile_list_addr; /* Neccessary to continue a stopped job */
-
- u32 active_mask;
-
- /* The data we will return back to the user */
- _mali_osk_notification_t *notification_obj;
-
-#if defined(USING_MALI400_L2_CACHE)
- u32 perf_counter_l2_src0;
- u32 perf_counter_l2_src1;
- u32 perf_counter_l2_val0;
- u32 perf_counter_l2_val1;
- u32 perf_counter_l2_val0_raw;
- u32 perf_counter_l2_val1_raw;
-#endif
-
-#if MALI_TIMELINE_PROFILING_ENABLED
- u32 pid;
- u32 tid;
-#endif
-} mali200_job;
-
-
-/*Functions Exposed to the General External System through
- funciont pointers.*/
-
-static _mali_osk_errcode_t mali200_subsystem_startup(mali_kernel_subsystem_identifier id);
-#if USING_MMU
-static _mali_osk_errcode_t mali200_subsystem_mmu_connect(mali_kernel_subsystem_identifier id);
-#endif
-static void mali200_subsystem_terminate(mali_kernel_subsystem_identifier id);
-static _mali_osk_errcode_t mali200_subsystem_session_begin(struct mali_session_data * mali_session_data, mali_kernel_subsystem_session_slot * slot, _mali_osk_notification_queue_t * queue);
-static void mali200_subsystem_session_end(struct mali_session_data * mali_session_data, mali_kernel_subsystem_session_slot * slot);
-static _mali_osk_errcode_t mali200_subsystem_core_system_info_fill(_mali_system_info* info);
-static _mali_osk_errcode_t mali200_renderunit_create(_mali_osk_resource_t * resource);
-#if USING_MMU
-static void mali200_subsystem_broadcast_notification(mali_core_notification_message message, u32 data);
-#endif
-#if MALI_STATE_TRACKING
-u32 mali200_subsystem_dump_state(char *buf, u32 size);
-#endif
-
-/* Internal support functions */
-static _mali_osk_errcode_t mali200_core_version_legal( mali_core_renderunit *core );
-static void mali200_reset(mali_core_renderunit *core);
-static void mali200_reset_hard(struct mali_core_renderunit * core);
-static void mali200_raw_reset(mali_core_renderunit * core);
-static void mali200_initialize_registers_mgmt(mali_core_renderunit *core );
-
-/* Functions exposed to mali_core system through functionpointers
- in the subsystem struct. */
-static _mali_osk_errcode_t subsystem_mali200_start_job(mali_core_job * job, mali_core_renderunit * core);
-static _mali_osk_errcode_t subsystem_mali200_get_new_job_from_user(struct mali_core_session * session, void * argument);
-static void subsystem_mali200_return_job_to_user( mali_core_job * job, mali_subsystem_job_end_code end_status);
-static void subsystem_mali200_renderunit_delete(mali_core_renderunit * core);
-static void subsystem_mali200_renderunit_reset_core(struct mali_core_renderunit * core, mali_core_reset_style style);
-static void subsystem_mali200_renderunit_probe_core_irq_trigger(struct mali_core_renderunit* core);
-static _mali_osk_errcode_t subsystem_mali200_renderunit_probe_core_irq_finished(struct mali_core_renderunit* core);
-
-static void subsystem_mali200_renderunit_stop_bus(struct mali_core_renderunit* core);
-static u32 subsystem_mali200_irq_handler_upper_half(struct mali_core_renderunit * core);
-static int subsystem_mali200_irq_handler_bottom_half(struct mali_core_renderunit* core);
-
-/* This will be one of the subsystems in the array of subsystems:
- static struct mali_kernel_subsystem * subsystems[];
- found in file: mali_kernel_core.c
-*/
-
-struct mali_kernel_subsystem mali_subsystem_mali200=
-{
- mali200_subsystem_startup, /* startup */
- NULL, /*mali200_subsystem_terminate,*/ /* shutdown */
-#if USING_MMU
- mali200_subsystem_mmu_connect, /* load_complete */
-#else
- NULL,
-#endif
- mali200_subsystem_core_system_info_fill, /* system_info_fill */
- mali200_subsystem_session_begin, /* session_begin */
- mali200_subsystem_session_end, /* session_end */
-#if USING_MMU
- mali200_subsystem_broadcast_notification, /* broadcast_notification */
-#else
- NULL,
-#endif
-#if MALI_STATE_TRACKING
- mali200_subsystem_dump_state, /* dump_state */
-#endif
-} ;
-
-static mali_core_subsystem subsystem_mali200 ;
-
-static _mali_osk_errcode_t mali200_subsystem_startup(mali_kernel_subsystem_identifier id)
-{
- mali_core_subsystem * subsystem;
-
- MALI_DEBUG_PRINT(3, ("Mali PP: mali200_subsystem_startup\n") ) ;
-
- mali_subsystem_mali200_id = id;
-
- /* All values get 0 as default */
- _mali_osk_memset(&subsystem_mali200, 0, sizeof(subsystem_mali200));
-
- subsystem = &subsystem_mali200;
- subsystem->start_job = &subsystem_mali200_start_job;
- subsystem->irq_handler_upper_half = &subsystem_mali200_irq_handler_upper_half;
- subsystem->irq_handler_bottom_half = &subsystem_mali200_irq_handler_bottom_half;
- subsystem->get_new_job_from_user = &subsystem_mali200_get_new_job_from_user;
- subsystem->return_job_to_user = &subsystem_mali200_return_job_to_user;
- subsystem->renderunit_delete = &subsystem_mali200_renderunit_delete;
- subsystem->reset_core = &subsystem_mali200_renderunit_reset_core;
- subsystem->stop_bus = &subsystem_mali200_renderunit_stop_bus;
- subsystem->probe_core_irq_trigger = &subsystem_mali200_renderunit_probe_core_irq_trigger;
- subsystem->probe_core_irq_acknowledge = &subsystem_mali200_renderunit_probe_core_irq_finished;
-
- /* Setting variables in the general core part of the subsystem.*/
- subsystem->name = MALI_PP_SUBSYSTEM_NAME;
- subsystem->core_type = MALI_PP_CORE_TYPE;
- subsystem->id = id;
-
- /* Initiates the rest of the general core part of the subsystem */
- MALI_CHECK_NO_ERROR(mali_core_subsystem_init( subsystem ));
-
- /* This will register the function for adding MALI200 cores to the subsystem */
-#if defined(USING_MALI200)
- MALI_CHECK_NO_ERROR(_mali_kernel_core_register_resource_handler(MALI200, mali200_renderunit_create));
-#endif
-#if defined(USING_MALI400)
- MALI_CHECK_NO_ERROR(_mali_kernel_core_register_resource_handler(MALI400PP, mali200_renderunit_create));
-#endif
-
- MALI_DEBUG_PRINT(6, ("Mali PP: mali200_subsystem_startup\n") ) ;
-
- MALI_SUCCESS;
-}
-
-#if USING_MMU
-static _mali_osk_errcode_t mali200_subsystem_mmu_connect(mali_kernel_subsystem_identifier id)
-{
- mali_core_subsystem_attach_mmu(&subsystem_mali200);
- MALI_SUCCESS; /* OK */
-}
-#endif
-
-static void mali200_subsystem_terminate(mali_kernel_subsystem_identifier id)
-{
- MALI_DEBUG_PRINT(3, ("Mali PP: mali200_subsystem_terminate\n") ) ;
- mali_core_subsystem_cleanup(&subsystem_mali200);
-}
-
-static _mali_osk_errcode_t mali200_subsystem_session_begin(struct mali_session_data * mali_session_data, mali_kernel_subsystem_session_slot * slot, _mali_osk_notification_queue_t * queue)
-{
- mali_core_session * session;
-
- MALI_DEBUG_PRINT(3, ("Mali PP: mali200_subsystem_session_begin\n") ) ;
- MALI_CHECK_NON_NULL(session = _mali_osk_malloc( sizeof(mali_core_session) ), _MALI_OSK_ERR_NOMEM);
-
- _mali_osk_memset(session, 0, sizeof(*session) );
- *slot = (mali_kernel_subsystem_session_slot)session;
-
- session->subsystem = &subsystem_mali200;
-
- session->notification_queue = queue;
-
-#if USING_MMU
- session->mmu_session = mali_session_data;
-#endif
-
- mali_core_session_begin(session);
-
- MALI_DEBUG_PRINT(6, ("Mali PP: mali200_subsystem_session_begin\n") ) ;
-
- MALI_SUCCESS;
-}
-
-static void mali200_subsystem_session_end(struct mali_session_data * mali_session_data, mali_kernel_subsystem_session_slot * slot)
-{
- mali_core_session * session;
-
- MALI_DEBUG_PRINT(3, ("Mali PP: mali200_subsystem_session_end\n") ) ;
- if ( NULL==slot || NULL==*slot)
- {
- MALI_PRINT_ERROR(("Input slot==NULL"));
- return;
- }
- session = (mali_core_session*) *slot;
- mali_core_session_close(session);
-
- _mali_osk_free(session);
- *slot = NULL;
-
- MALI_DEBUG_PRINT(6, ("Mali PP: mali200_subsystem_session_end\n") ) ;
-}
-
-/**
- * We fill in info about all the cores we have
- * @param info Pointer to system info struct to update
- * @return 0 on success, negative on error
- */
-static _mali_osk_errcode_t mali200_subsystem_core_system_info_fill(_mali_system_info* info)
-{
- return mali_core_subsystem_system_info_fill(&subsystem_mali200, info);
-}
-
-
-static _mali_osk_errcode_t mali200_renderunit_create(_mali_osk_resource_t * resource)
-{
- mali_core_renderunit *core;
- _mali_osk_errcode_t err;
-
- MALI_DEBUG_PRINT(3, ("Mali PP: mali200_renderunit_create\n") ) ;
- /* Checking that the resource settings are correct */
-#if defined(USING_MALI200)
- if(MALI200 != resource->type)
- {
- MALI_PRINT_ERROR(("Can not register this resource as a " MALI_PP_SUBSYSTEM_NAME " core."));
- MALI_ERROR(_MALI_OSK_ERR_FAULT);
- }
-#elif defined(USING_MALI400)
- if(MALI400PP != resource->type)
- {
- MALI_PRINT_ERROR(("Can not register this resource as a " MALI_PP_SUBSYSTEM_NAME " core."));
- MALI_ERROR(_MALI_OSK_ERR_FAULT);
- }
-#endif
- if ( 0 != resource->size )
- {
- MALI_PRINT_ERROR(("Memory size set to " MALI_PP_SUBSYSTEM_NAME " core should be zero."));
- MALI_ERROR(_MALI_OSK_ERR_FAULT);
- }
-
- if ( NULL == resource->description )
- {
- MALI_PRINT_ERROR(("A " MALI_PP_SUBSYSTEM_NAME " core needs a unique description field"));
- MALI_ERROR(_MALI_OSK_ERR_FAULT);
- }
-
- /* Create a new core object */
- core = (mali_core_renderunit*) _mali_osk_malloc(sizeof(*core));
- if ( NULL == core )
- {
- MALI_ERROR(_MALI_OSK_ERR_NOMEM);
- }
-
- /* Variables set to be able to open and register the core */
- core->subsystem = &subsystem_mali200 ;
- core->registers_base_addr = resource->base ;
- core->size = MALI200_REG_SIZEOF_REGISTER_BANK ;
- core->irq_nr = resource->irq ;
- core->description = resource->description;
-#if USING_MMU
- core->mmu_id = resource->mmu_id;
- core->mmu = NULL;
-#endif
-#if USING_MALI_PMM
- /* Set up core's PMM id */
- switch( subsystem_mali200.number_of_cores )
- {
- case 0:
- core->pmm_id = MALI_PMM_CORE_PP0;
- break;
- case 1:
- core->pmm_id = MALI_PMM_CORE_PP1;
- break;
- case 2:
- core->pmm_id = MALI_PMM_CORE_PP2;
- break;
- case 3:
- core->pmm_id = MALI_PMM_CORE_PP3;
- break;
- default:
- MALI_DEBUG_PRINT(1, ("Unknown supported core for PMM\n"));
- err = _MALI_OSK_ERR_FAULT;
- goto exit_on_error0;
- }
-#endif
-
- err = mali_core_renderunit_init( core );
- if (_MALI_OSK_ERR_OK != err)
- {
- MALI_DEBUG_PRINT(1, ("Failed to initialize renderunit\n"));
- goto exit_on_error0;
- }
-
- /* Map the new core object, setting: core->registers_mapped */
- err = mali_core_renderunit_map_registers(core);
- if (_MALI_OSK_ERR_OK != err)
- {
- MALI_DEBUG_PRINT(1, ("Failed to map register\n"));
- goto exit_on_error1;
- }
-
- /* Check that the register mapping of the core works.
- Return 0 if Mali PP core is present and accessible. */
- if (mali_benchmark) {
-#if defined(USING_MALI200)
- core->core_version = (((u32)MALI_PP_PRODUCT_ID) << 16) | 5 /* Fake Mali200-r0p5 */;
-#elif defined(USING_MALI400)
- core->core_version = (((u32)MALI_PP_PRODUCT_ID) << 16) | 0x0101 /* Fake Mali400-r1p1 */;
-#else
-#error "No supported mali core defined"
-#endif
- } else {
- core->core_version = mali_core_renderunit_register_read(
- core,
- MALI200_REG_ADDR_MGMT_VERSION);
- }
-
- err = mali200_core_version_legal(core);
- if (_MALI_OSK_ERR_OK != err)
- {
- MALI_DEBUG_PRINT(1, ("Invalid core\n"));
- goto exit_on_error2;
- }
-
- /* Reset the core. Put the core into a state where it can start to render. */
- mali200_reset(core);
-
- /* Registering IRQ, init the work_queue_irq_handle */
- /* Adding this core as an available renderunit in the subsystem. */
- err = mali_core_subsystem_register_renderunit(&subsystem_mali200, core);
- if (_MALI_OSK_ERR_OK != err)
- {
- MALI_DEBUG_PRINT(1, ("Failed to register with core\n"));
- goto exit_on_error2;
- }
- MALI_DEBUG_PRINT(6, ("Mali PP: mali200_renderunit_create\n") ) ;
-
- MALI_SUCCESS;
-
-exit_on_error2:
- mali_core_renderunit_unmap_registers(core);
-exit_on_error1:
- mali_core_renderunit_term(core);
-exit_on_error0:
- _mali_osk_free( core ) ;
- MALI_PRINT_ERROR(("Renderunit NOT created."));
- MALI_ERROR(err);
-}
-
-#if USING_MMU
-/* Used currently only for signalling when MMU has a pagefault */
-static void mali200_subsystem_broadcast_notification(mali_core_notification_message message, u32 data)
-{
- mali_core_subsystem_broadcast_notification(&subsystem_mali200, message, data);
-}
-#endif
-
-static _mali_osk_errcode_t mali200_core_version_legal( mali_core_renderunit *core )
-{
- u32 mali_type;
-
- mali_type = core->core_version >> 16;
-#if defined(USING_MALI400)
- /* Mali300 and Mali400 is compatible, accept either core. */
- if (MALI400_PP_PRODUCT_ID != mali_type && MALI300_PP_PRODUCT_ID != mali_type)
-#else
- if (MALI_PP_PRODUCT_ID != mali_type)
-#endif
- {
- MALI_PRINT_ERROR(("Error: reading this from " MALI_PP_SUBSYSTEM_NAME " version register: 0x%x\n", core->core_version));
- MALI_ERROR(_MALI_OSK_ERR_FAULT);
- }
- MALI_DEBUG_PRINT(3, ("Mali PP: core_version_legal: Reads correct mali version: %d\n", mali_type) ) ;
- MALI_SUCCESS;
-}
-
-static void subsystem_mali200_renderunit_stop_bus(struct mali_core_renderunit* core)
-{
- mali_core_renderunit_register_write(core, MALI200_REG_ADDR_MGMT_CTRL_MGMT, MALI200_REG_VAL_CTRL_MGMT_STOP_BUS);
-}
-
-static void mali200_raw_reset( mali_core_renderunit *core )
-{
- int i;
- const int request_loop_count = 20;
-
- MALI_DEBUG_PRINT(4, ("Mali PP: mali200_raw_reset: %s\n", core->description));
- if (mali_benchmark) return;
-
- mali_core_renderunit_register_write(core, MALI200_REG_ADDR_MGMT_INT_MASK, 0); /* disable IRQs */
-
-#if defined(USING_MALI200)
-
- mali_core_renderunit_register_write(core, MALI200_REG_ADDR_MGMT_CTRL_MGMT, MALI200_REG_VAL_CTRL_MGMT_STOP_BUS);
-
- for (i = 0; i < request_loop_count; i++)
- {
- if (mali_core_renderunit_register_read(core, MALI200_REG_ADDR_MGMT_STATUS) & MALI200_REG_VAL_STATUS_BUS_STOPPED) break;
- _mali_osk_time_ubusydelay(10);
- }
-
- MALI_DEBUG_PRINT_IF(1, request_loop_count == i, ("Mali PP: Bus was never stopped during core reset\n"));
-
-
- if (request_loop_count==i)
- {
-#if USING_MMU
- if ((NULL!=core->mmu) && (MALI_FALSE == core->error_recovery))
- {
- /* Could not stop bus connections from core, probably because some of the already pending
- bus request has had a page fault, and therefore can not complete before the MMU does PageFault
- handling. This can be treated as a heavier reset function - which unfortunately reset all
- the cores on this MMU in addition to the MMU itself */
- MALI_DEBUG_PRINT(1, ("Mali PP: Forcing Bus reset\n"));
- mali_kernel_mmu_force_bus_reset(core->mmu);
- return;
- }
-#endif
- MALI_PRINT(("A MMU reset did not allow PP to stop its bus, system failure, unable to recover\n"));
- return;
- }
-
- /* use the hard reset routine to do the actual reset */
- mali200_reset_hard(core);
-
-#elif defined(USING_MALI400)
-
- mali_core_renderunit_register_write(core, MALI200_REG_ADDR_MGMT_INT_CLEAR, MALI400PP_REG_VAL_IRQ_RESET_COMPLETED);
- mali_core_renderunit_register_write(core, MALI200_REG_ADDR_MGMT_CTRL_MGMT, MALI400PP_REG_VAL_CTRL_MGMT_SOFT_RESET);
-
- for (i = 0; i < request_loop_count; i++)
- {
- if (mali_core_renderunit_register_read(core, MALI200_REG_ADDR_MGMT_INT_RAWSTAT) & MALI400PP_REG_VAL_IRQ_RESET_COMPLETED) break;
- _mali_osk_time_ubusydelay(10);
- }
-
- if (request_loop_count==i)
- {
-#if USING_MMU
- if ((NULL!=core->mmu) && (MALI_FALSE == core->error_recovery))
- {
- /* Could not stop bus connections from core, probably because some of the already pending
- bus request has had a page fault, and therefore can not complete before the MMU does PageFault
- handling. This can be treated as a heavier reset function - which unfortunately reset all
- the cores on this MMU in addition to the MMU itself */
- MALI_DEBUG_PRINT(1, ("Mali PP: Forcing Bus reset\n"));
- mali_kernel_mmu_force_bus_reset(core->mmu);
- return;
- }
-#endif
- MALI_PRINT(("A MMU reset did not allow PP to stop its bus, system failure, unable to recover\n"));
- return;
- }
- else
- mali_core_renderunit_register_write(core, MALI200_REG_ADDR_MGMT_INT_CLEAR, MALI200_REG_VAL_IRQ_MASK_ALL);
-
-#else
-#error "no supported mali core defined"
-#endif
-}
-
-static void mali200_reset( mali_core_renderunit *core )
-{
- if (!mali_benchmark) {
- mali200_raw_reset(core);
- mali200_initialize_registers_mgmt(core);
- }
-}
-
-/* Sets the registers on mali200 according to the const default_mgmt_regs array. */
-static void mali200_initialize_registers_mgmt(mali_core_renderunit *core )
-{
- MALI_DEBUG_PRINT(6, ("Mali PP: mali200_initialize_registers_mgmt: %s\n", core->description)) ;
- mali_core_renderunit_register_write(core, MALI200_REG_ADDR_MGMT_INT_MASK, MALI200_REG_VAL_IRQ_MASK_USED);
-}
-
-/* Start this job on this core. Return MALI_TRUE if the job was started. */
-static _mali_osk_errcode_t subsystem_mali200_start_job(mali_core_job * job, mali_core_renderunit * core)
-{
- mali200_job *job200;
-
- /* The local extended version of the general structs */
- job200 = _MALI_OSK_CONTAINER_OF(job, mali200_job, embedded_core_job);
-
- if ( (0 == job200->user_input.frame_registers[0]) ||
- (0 == job200->user_input.frame_registers[1]) )
- {
- MALI_DEBUG_PRINT(4, ("Mali PP: Job: 0x%08x WILL NOT START SINCE JOB HAS ILLEGAL ADDRESSES\n",
- (u32)job200->user_input.user_job_ptr));
- MALI_ERROR(_MALI_OSK_ERR_FAULT);
- }
-
- MALI_DEBUG_PRINT(4, ("Mali PP: Job: 0x%08x START_RENDER Tile_list: 0x%08x\n",
- (u32)job200->user_input.user_job_ptr,
- job200->user_input.frame_registers[0]));
- MALI_DEBUG_PRINT(6, ("Mali PP: RSW base addr: 0x%08x Vertex base addr: 0x%08x\n",
- job200->user_input.frame_registers[1], job200->user_input.frame_registers[2]));
-
- /* Frame registers. Copy from mem to physical registers */
- mali_core_renderunit_register_write_array(
- core,
- MALI200_REG_ADDR_FRAME,
- &(job200->user_input.frame_registers[0]),
- MALI200_NUM_REGS_FRAME);
-
- /* Write Back unit 0. Copy from mem to physical registers only if the WB unit will be used. */
- if (job200->user_input.wb0_registers[0])
- {
- mali_core_renderunit_register_write_array(
- core,
- MALI200_REG_ADDR_WB0,
- &(job200->user_input.wb0_registers[0]),
- MALI200_NUM_REGS_WBx);
- }
-
- /* Write Back unit 1. Copy from mem to physical registers only if the WB unit will be used. */
- if (job200->user_input.wb1_registers[0])
- {
- mali_core_renderunit_register_write_array(
- core,
- MALI200_REG_ADDR_WB1,
- &(job200->user_input.wb1_registers[0]),
- MALI200_NUM_REGS_WBx);
- }
-
- /* Write Back unit 2. Copy from mem to physical registers only if the WB unit will be used. */
- if (job200->user_input.wb2_registers[0])
- {
- mali_core_renderunit_register_write_array(
- core,
- MALI200_REG_ADDR_WB2,
- &(job200->user_input.wb2_registers[0]),
- MALI200_NUM_REGS_WBx);
- }
-
-#if MALI_TRACEPOINTS_ENABLED
- {
- int counter = ((core->core_number)*2)+9; /* magic numbers for FP0 are 9 & 10 */
-
- //printk("FP core->number = %d\n", core->core_number);
- //TODO we are using magic numbers again... these are from gator_events_mali.c
- job200->user_input.perf_counter_flag = 0;
-
- if( counter>=9 && counter<=16) {
-
- if( counter_table[counter] != 0xFFFFFFFF ) {
- job200->user_input.perf_counter_flag |= _MALI_PERFORMANCE_COUNTER_FLAG_SRC0_ENABLE;
- job200->user_input.perf_counter_src0 = counter_table[counter];
- }
- if( counter_table[counter+1] != 0xFFFFFFFF ) {
- job200->user_input.perf_counter_flag |= _MALI_PERFORMANCE_COUNTER_FLAG_SRC1_ENABLE;
- job200->user_input.perf_counter_src1 = counter_table[counter+1];
- }
-
- } else {
- MALI_DEBUG_PRINT(2, ("core->core_number out of the range (0-3) (%d)\n", core->core_number));
- }
- }
-#if defined(USING_MALI400_L2_CACHE)
- if( counter_table[5] != 0xFFFFFFFF ) {
- job200->user_input.perf_counter_flag |= _MALI_PERFORMANCE_COUNTER_FLAG_L2_SRC0_ENABLE | _MALI_PERFORMANCE_COUNTER_FLAG_L2_RESET;
- job200->user_input.perf_counter_l2_src0 = counter_table[5];
- }
- if( counter_table[6] != 0xFFFFFFFF ) {
- job200->user_input.perf_counter_flag |= _MALI_PERFORMANCE_COUNTER_FLAG_L2_SRC1_ENABLE | _MALI_PERFORMANCE_COUNTER_FLAG_L2_RESET;
- job200->user_input.perf_counter_l2_src1 = counter_table[6];
- }
-#endif
-#endif
-
- /* This selects which performance counters we are reading */
- if ( 0 != job200->user_input.perf_counter_flag )
- {
- if ( job200->user_input.perf_counter_flag & _MALI_PERFORMANCE_COUNTER_FLAG_SRC0_ENABLE)
- {
- mali_core_renderunit_register_write_relaxed(
- core,
- MALI200_REG_ADDR_MGMT_PERF_CNT_0_ENABLE,
- MALI200_REG_VAL_PERF_CNT_ENABLE);
- mali_core_renderunit_register_write_relaxed(
- core,
- MALI200_REG_ADDR_MGMT_PERF_CNT_0_SRC,
- job200->user_input.perf_counter_src0);
-
- }
-
- if ( job200->user_input.perf_counter_flag & _MALI_PERFORMANCE_COUNTER_FLAG_SRC1_ENABLE)
- {
- mali_core_renderunit_register_write_relaxed(
- core,
- MALI200_REG_ADDR_MGMT_PERF_CNT_1_ENABLE,
- MALI200_REG_VAL_PERF_CNT_ENABLE);
- mali_core_renderunit_register_write_relaxed(
- core,
- MALI200_REG_ADDR_MGMT_PERF_CNT_1_SRC,
- job200->user_input.perf_counter_src1);
-
- }
-
-#if defined(USING_MALI400_L2_CACHE)
- if ( job200->user_input.perf_counter_flag & (_MALI_PERFORMANCE_COUNTER_FLAG_L2_SRC0_ENABLE|_MALI_PERFORMANCE_COUNTER_FLAG_L2_SRC1_ENABLE) )
- {
- int force_reset = ( job200->user_input.perf_counter_flag & _MALI_PERFORMANCE_COUNTER_FLAG_L2_RESET ) ? 1 : 0;
- u32 src0 = 0;
- u32 src1 = 0;
-
- if ( job200->user_input.perf_counter_flag & _MALI_PERFORMANCE_COUNTER_FLAG_L2_SRC0_ENABLE )
- {
- src0 = job200->user_input.perf_counter_l2_src0;
- }
- if ( job200->user_input.perf_counter_flag & _MALI_PERFORMANCE_COUNTER_FLAG_L2_SRC1_ENABLE )
- {
- src1 = job200->user_input.perf_counter_l2_src1;
- }
-
- mali_kernel_l2_cache_set_perf_counters(src0, src1, force_reset); /* will activate and possibly reset counters */
-
- /* Now, retrieve the current values, so we can substract them when the job has completed */
- mali_kernel_l2_cache_get_perf_counters(&job200->perf_counter_l2_src0,
- &job200->perf_counter_l2_val0,
- &job200->perf_counter_l2_src1,
- &job200->perf_counter_l2_val1);
- }
-#endif
- }
-
- subsystem_flush_mapped_mem_cache();
-
-#if MALI_STATE_TRACKING
- _mali_osk_atomic_inc(&job->session->jobs_started);
-#endif
-
- /* This is the command that starts the Core */
- mali_core_renderunit_register_write(
- core,
- MALI200_REG_ADDR_MGMT_CTRL_MGMT,
- MALI200_REG_VAL_CTRL_MGMT_START_RENDERING);
- _mali_osk_write_mem_barrier();
-
-
- pr_debug("SPI_GPU_PP%u Start\n", core->core_number);
-#if MALI_TIMELINE_PROFILING_ENABLED
- _mali_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE | MALI_PROFILING_MAKE_EVENT_CHANNEL_PP(core->core_number) | MALI_PROFILING_EVENT_REASON_SINGLE_HW_FLUSH, job200->user_input.frame_builder_id, job200->user_input.flush_id, 0, 0, 0);
- _mali_profiling_add_event(MALI_PROFILING_EVENT_TYPE_START|MALI_PROFILING_MAKE_EVENT_CHANNEL_PP(core->core_number), job200->pid, job200->tid,
-#if defined(USING_MALI400_L2_CACHE)
- (job200->user_input.perf_counter_l2_src0 << 16) | (job200->user_input.perf_counter_l2_src1 << 24),
- job200->perf_counter_l2_val0, job200->perf_counter_l2_val1
-#else
- 0, 0, 0
-#endif
- );
-#endif
-
- MALI_SUCCESS;
-}
-
-static u32 subsystem_mali200_irq_handler_upper_half(mali_core_renderunit * core)
-{
- u32 irq_readout;
-
- if (mali_benchmark) {
- return (core->current_job ? 1 : 0); /* simulate irq is pending when a job is pending */
- }
-
- MALI_DEBUG_PRINT(5, ("Mali PP: subsystem_mali200_irq_handler_upper_half: %s\n", core->description)) ;
- irq_readout = mali_core_renderunit_register_read(core, MALI200_REG_ADDR_MGMT_INT_STATUS);
-
- if ( MALI200_REG_VAL_IRQ_MASK_NONE != irq_readout )
- {
- /* Mask out all IRQs from this core until IRQ is handled */
- mali_core_renderunit_register_write(core, MALI200_REG_ADDR_MGMT_INT_MASK, MALI200_REG_VAL_IRQ_MASK_NONE);
-
-#if MALI_TIMELINE_PROFILING_ENABLED
- _mali_profiling_add_event(MALI_PROFILING_EVENT_TYPE_SINGLE|MALI_PROFILING_MAKE_EVENT_CHANNEL_PP(core->core_number)|MALI_PROFILING_EVENT_REASON_SINGLE_HW_INTERRUPT, irq_readout, 0, 0, 0, 0);
-#endif
-
- return 1;
- }
- return 0;
-}
-
-static int subsystem_mali200_irq_handler_bottom_half(struct mali_core_renderunit* core)
-{
- u32 irq_readout;
- u32 current_tile_addr;
- u32 core_status;
- mali_core_job * job;
- mali200_job * job200;
-
- job = core->current_job;
- job200 = GET_JOB200_PTR(job);
-
-
- if (mali_benchmark) {
- irq_readout = MALI200_REG_VAL_IRQ_END_OF_FRAME;
- current_tile_addr = 0;
- core_status = 0;
- } else {
- irq_readout = mali_core_renderunit_register_read(core, MALI200_REG_ADDR_MGMT_INT_RAWSTAT) & MALI200_REG_VAL_IRQ_MASK_USED;
- current_tile_addr = mali_core_renderunit_register_read(core, MALI200_REG_ADDR_MGMT_CURRENT_REND_LIST_ADDR);
- core_status = mali_core_renderunit_register_read(core, MALI200_REG_ADDR_MGMT_STATUS);
- }
-
- if (NULL == job)
- {
- MALI_DEBUG_ASSERT(CORE_IDLE==core->state);
- if ( 0 != irq_readout )
- {
- MALI_PRINT_ERROR(("Interrupt from a core not running a job. IRQ: 0x%04x Status: 0x%04x", irq_readout, core_status));
- }
- return JOB_STATUS_END_UNKNOWN_ERR;
- }
- MALI_DEBUG_ASSERT(CORE_IDLE!=core->state);
-
- job200->irq_status |= irq_readout;
-
- MALI_DEBUG_PRINT_IF( 3, ( 0 != irq_readout ),
- ("Mali PP: Job: 0x%08x IRQ RECEIVED Rawstat: 0x%x Tile_addr: 0x%x Status: 0x%x\n",
- (u32)job200->user_input.user_job_ptr, irq_readout ,current_tile_addr ,core_status));
-
- if ( MALI200_REG_VAL_IRQ_END_OF_FRAME & irq_readout)
- {
-#if defined(USING_MALI200)
- mali_core_renderunit_register_write(core, MALI200_REG_ADDR_MGMT_CTRL_MGMT, MALI200_REG_VAL_CTRL_MGMT_FLUSH_CACHES);
-#endif
-
- if (0 != job200->user_input.perf_counter_flag )
- {
- if (job200->user_input.perf_counter_flag & (_MALI_PERFORMANCE_COUNTER_FLAG_SRC0_ENABLE|_MALI_PERFORMANCE_COUNTER_FLAG_SRC1_ENABLE) )
- {
-#if MALI_TRACEPOINTS_ENABLED
- //TODO magic numbers should come from mali_linux_trace.h instead
- unsigned int counter = (core->core_number * 2) + 9;
-#endif
-
- job200->perf_counter0 = mali_core_renderunit_register_read(core, MALI200_REG_ADDR_MGMT_PERF_CNT_0_VALUE);
- job200->perf_counter1 = mali_core_renderunit_register_read(core, MALI200_REG_ADDR_MGMT_PERF_CNT_1_VALUE);
-
-#if MALI_TRACEPOINTS_ENABLED
- _mali_profiling_add_counter(counter, job200->perf_counter0);
- _mali_profiling_add_counter(counter + 1, job200->perf_counter1);
-#endif
-
- }
-
-#if defined(USING_MALI400_L2_CACHE)
- if (job200->user_input.perf_counter_flag & (_MALI_PERFORMANCE_COUNTER_FLAG_L2_SRC0_ENABLE|_MALI_PERFORMANCE_COUNTER_FLAG_L2_SRC1_ENABLE) )
- {
- u32 src0;
- u32 val0;
- u32 src1;
- u32 val1;
- mali_kernel_l2_cache_get_perf_counters(&src0, &val0, &src1, &val1);
-
- if (job200->perf_counter_l2_src0 == src0)
- {
- job200->perf_counter_l2_val0_raw = val0;
- job200->perf_counter_l2_val0 = val0 - job200->perf_counter_l2_val0;
- }
- else
- {
- job200->perf_counter_l2_val0_raw = 0;
- job200->perf_counter_l2_val0 = 0;
- }
-
- if (job200->perf_counter_l2_src1 == src1)
- {
- job200->perf_counter_l2_val1_raw = val1;
- job200->perf_counter_l2_val1 = val1 - job200->perf_counter_l2_val1;
- }
- else
- {
- job200->perf_counter_l2_val1_raw = 0;
- job200->perf_counter_l2_val1 = 0;
- }
-
-#if MALI_TRACEPOINTS_ENABLED
- //TODO magic numbers should come from mali_linux_trace.h instead
- _mali_profiling_add_counter(5, val0);
- _mali_profiling_add_counter(6, val1);
-#endif
- }
-#endif
-
- }
-
-#if MALI_TIMELINE_PROFILING_ENABLED
- _mali_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP|MALI_PROFILING_MAKE_EVENT_CHANNEL_PP(core->core_number),
- job200->perf_counter0, job200->perf_counter1,
- job200->user_input.perf_counter_src0 | (job200->user_input.perf_counter_src1 << 8)
-#if defined(USING_MALI400_L2_CACHE)
- | (job200->user_input.perf_counter_l2_src0 << 16) | (job200->user_input.perf_counter_l2_src1 << 24),
- job200->perf_counter_l2_val0, job200->perf_counter_l2_val1
-#else
- , 0, 0
-#endif
- );
-#endif
-
-
-#if MALI_STATE_TRACKING
- _mali_osk_atomic_inc(&job->session->jobs_ended);
-#endif
-
- pr_debug("SPI_GPU_PP%u Idle\n", core->core_number);
-
- return JOB_STATUS_END_SUCCESS; /* reschedule */
- }
- /* Overall SW watchdog timeout or (time to do hang checking and progress detected)? */
- else if (
- (CORE_WATCHDOG_TIMEOUT == core->state) ||
- ((CORE_HANG_CHECK_TIMEOUT == core->state) && (current_tile_addr == job200->last_tile_list_addr))
- )
- {
-#if MALI_TIMELINE_PROFILING_ENABLED
- _mali_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP|MALI_PROFILING_MAKE_EVENT_CHANNEL_PP(core->core_number), 0, 0, 0, 0, 0); /* add GP and L2 counters and return status */
-#endif
- /* no progress detected, killed by the watchdog */
- MALI_PRINT( ("M200: SW-Timeout Rawstat: 0x%x Tile_addr: 0x%x Status: 0x%x.\n", irq_readout ,current_tile_addr ,core_status) );
- /* In this case will the system outside cleanup and reset the core */
-
- MALI_PANIC("%s Watchdog timeout (rawstat: 0x%x tile_addr: 0x%x status: 0x%x)\n", MALI_PP_SUBSYSTEM_NAME, irq_readout, current_tile_addr, core_status);
-
-#if MALI_STATE_TRACKING
- _mali_osk_atomic_inc(&job->session->jobs_ended);
-#endif
-
- return JOB_STATUS_END_HANG;
- }
- /* HW watchdog triggered or an existing hang check passed? */
- else if ((CORE_HANG_CHECK_TIMEOUT == core->state) || (irq_readout & job200->active_mask & MALI200_REG_VAL_IRQ_HANG))
- {
- /* check interval in ms */
- u32 timeout = mali_core_hang_check_timeout_get();
- MALI_PRINT( ("M200: HW/SW Watchdog triggered, checking for progress in %d ms\n", timeout));
- job200->last_tile_list_addr = current_tile_addr;
- /* hw watchdog triggered, set up a progress checker every HANGCHECK ms */
- _mali_osk_timer_add(core->timer_hang_detection, _mali_osk_time_mstoticks(timeout));
- job200->active_mask &= ~MALI200_REG_VAL_IRQ_HANG; /* ignore the hw watchdoig from now on */
- mali_core_renderunit_register_write(core, MALI200_REG_ADDR_MGMT_INT_CLEAR, irq_readout & ~MALI200_REG_VAL_IRQ_HANG);
- mali_core_renderunit_register_write(core, MALI200_REG_ADDR_MGMT_INT_MASK, job200->active_mask);
- return JOB_STATUS_CONTINUE_RUN; /* not finished */
- }
- /* No irq pending, core still busy */
- else if ((0 == (irq_readout & MALI200_REG_VAL_IRQ_MASK_USED)) && ( 0 != (core_status & MALI200_REG_VAL_STATUS_RENDERING_ACTIVE)))
- {
- mali_core_renderunit_register_write(core, MALI200_REG_ADDR_MGMT_INT_CLEAR, irq_readout);
- mali_core_renderunit_register_write(core, MALI200_REG_ADDR_MGMT_INT_MASK, job200->active_mask);
- return JOB_STATUS_CONTINUE_RUN; /* Not finished */
- }
- else
- {
-#if MALI_TIMELINE_PROFILING_ENABLED
- _mali_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP|MALI_PROFILING_MAKE_EVENT_CHANNEL_PP(core->core_number), 0, 0, 0, 0, 0); /* add GP and L2 counters and return status */
-#endif
-
- MALI_PRINT( ("Mali PP: Job: 0x%08x CRASH? Rawstat: 0x%x Tile_addr: 0x%x Status: 0x%x\n",
- (u32)job200->user_input.user_job_ptr, irq_readout ,current_tile_addr ,core_status) ) ;
-
- if (irq_readout & MALI200_REG_VAL_IRQ_BUS_ERROR)
- {
- u32 bus_error = mali_core_renderunit_register_read(core, MALI200_REG_ADDR_MGMT_BUS_ERROR_STATUS);
-
- MALI_PRINT(("Bus error status: 0x%08X\n", bus_error));
- MALI_DEBUG_PRINT_IF(1, (bus_error & 0x01), ("Bus write error from id 0x%02x\n", (bus_error>>2) & 0x0F));
- MALI_DEBUG_PRINT_IF(1, (bus_error & 0x02), ("Bus read error from id 0x%02x\n", (bus_error>>6) & 0x0F));
- MALI_DEBUG_PRINT_IF(1, (0 == (bus_error & 0x03)), ("Bus error but neither read or write was set as the error reason\n"));
- (void)bus_error;
- }
-
-#if MALI_STATE_TRACKING
- _mali_osk_atomic_inc(&job->session->jobs_ended);
-#endif
- return JOB_STATUS_END_UNKNOWN_ERR; /* reschedule */
- }
-}
-
-
-/* This function is called from the ioctl function and should return a mali_core_job pointer
-to a created mali_core_job object with the data given from userspace */
-static _mali_osk_errcode_t subsystem_mali200_get_new_job_from_user(struct mali_core_session * session, void * argument)
-{
- mali200_job *job200;
- mali_core_job *job = NULL;
- mali_core_job *previous_replaced_job;
- _mali_osk_errcode_t err = _MALI_OSK_ERR_OK;
- _mali_uk_pp_start_job_s * user_ptr_job_input;
-
- user_ptr_job_input = (_mali_uk_pp_start_job_s *)argument;
-
- MALI_CHECK_NON_NULL(job200 = (mali200_job *) _mali_osk_malloc(sizeof(mali200_job)), _MALI_OSK_ERR_NOMEM);
- _mali_osk_memset(job200, 0 , sizeof(mali200_job) );
-
- /* We read job data from Userspace pointer */
- if ( NULL == _mali_osk_memcpy((void*)&job200->user_input, user_ptr_job_input, sizeof(job200->user_input)) )
- {
- MALI_PRINT_ERROR( ("Mali PP: Could not copy data from U/K interface.\n")) ;
- err = _MALI_OSK_ERR_FAULT;
- goto function_exit;
- }
-
- MALI_DEBUG_PRINT(5, ("Mali PP: subsystem_mali200_get_new_job_from_user 0x%x\n", (void*)job200->user_input.user_job_ptr));
-
- MALI_DEBUG_PRINT(5, ("Mali PP: Frameregs: 0x%x 0x%x 0x%x Writeback[1] 0x%x, Pri:%d; Watchd:%d\n",
- job200->user_input.frame_registers[0], job200->user_input.frame_registers[1], job200->user_input.frame_registers[2],
- job200->user_input.wb0_registers[1], job200->user_input.priority,
- job200->user_input.watchdog_msecs));
-
- if ( job200->user_input.perf_counter_flag)
- {
-#if defined(USING_MALI400_L2_CACHE)
- MALI_DEBUG_PRINT(5, ("Mali PP: Performance counters: flag:0x%x src0:0x%x src1:0x%x l2_src0:0x%x l2_src1:0x%x\n",
- job200->user_input.perf_counter_flag,
- job200->user_input.perf_counter_src0,
- job200->user_input.perf_counter_src1,
- job200->user_input.perf_counter_l2_src0,
- job200->user_input.perf_counter_l2_src1));
-#else
- MALI_DEBUG_PRINT(5, ("Mali PP: Performance counters: flag:0x%x src0:0x%x src1:0x%x\n",
- job200->user_input.perf_counter_flag,
- job200->user_input.perf_counter_src0,
- job200->user_input.perf_counter_src1));
-#endif
- }
-
- job = GET_JOB_EMBEDDED_PTR(job200);
-
- job->session = session;
- job->flags = user_ptr_job_input->flags;
- job_priority_set(job, job200->user_input.priority);
- job_watchdog_set(job, job200->user_input.watchdog_msecs );
-
-#if MALI_TIMELINE_PROFILING_ENABLED
- job200->pid = _mali_osk_get_pid();
- job200->tid = _mali_osk_get_tid();
-#endif
-
- job->abort_id = job200->user_input.abort_id;
- if (mali_job_queue_full(session))
- {
- user_ptr_job_input->status = _MALI_UK_START_JOB_NOT_STARTED_DO_REQUEUE;
- goto function_exit;
- }
-
- /* We now know that we has a job, and a empty session slot to put it in */
-
- job200->active_mask = MALI200_REG_VAL_IRQ_MASK_USED;
-
- /* Allocating User Return Data */
- job200->notification_obj = _mali_osk_notification_create(
- _MALI_NOTIFICATION_PP_FINISHED,
- sizeof(_mali_uk_pp_job_finished_s) );
-
- if ( NULL == job200->notification_obj )
- {
- MALI_PRINT_ERROR( ("Mali PP: Could not get notification_obj.\n")) ;
- err = _MALI_OSK_ERR_NOMEM;
- goto function_exit;
- }
-
- _MALI_OSK_INIT_LIST_HEAD( &(job->list) ) ;
-
- MALI_DEBUG_PRINT(4, ("Mali PP: Job: 0x%08x INPUT from user.\n", (u32)job200->user_input.user_job_ptr)) ;
-
- /* This should not happen since we have the checking of priority above */
- if ( _MALI_OSK_ERR_OK != mali_core_session_add_job(session, job, &previous_replaced_job))
- {
- MALI_PRINT_ERROR( ("Mali PP: Internal error\n")) ;
- user_ptr_job_input->status = _MALI_UK_START_JOB_NOT_STARTED_DO_REQUEUE;
- _mali_osk_notification_delete( job200->notification_obj );
- goto function_exit;
- }
-
- /* If MALI_TRUE: This session had a job with lower priority which were removed.
- This replaced job is given back to userspace. */
- if ( NULL != previous_replaced_job )
- {
- mali200_job *previous_replaced_job200;
-
- previous_replaced_job200 = GET_JOB200_PTR(previous_replaced_job);
-
- MALI_DEBUG_PRINT(4, ("Mali PP: Replacing job: 0x%08x\n", (u32)previous_replaced_job200->user_input.user_job_ptr)) ;
-
- /* Copy to the input data (which also is output data) the
- pointer to the job that were replaced, so that the userspace
- driver can put this job in the front of its job-queue */
-
- user_ptr_job_input->returned_user_job_ptr = previous_replaced_job200->user_input.user_job_ptr;
-
- /** @note failure to 'copy to user' at this point must not free job200,
- * and so no transaction rollback required in the U/K interface */
-
- /* This does not cause job200 to free: */
- user_ptr_job_input->status = _MALI_UK_START_JOB_STARTED_LOW_PRI_JOB_RETURNED;
- MALI_DEBUG_PRINT(5, ("subsystem_mali200_get_new_job_from_user: Job added, prev returned\n")) ;
- }
- else
- {
- /* This does not cause job200 to free: */
- user_ptr_job_input->status = _MALI_UK_START_JOB_STARTED;
- MALI_DEBUG_PRINT(5, ("subsystem_mali200_get_new_job_from_user: Job added\n")) ;
- }
-
-function_exit:
- if (_MALI_UK_START_JOB_NOT_STARTED_DO_REQUEUE == user_ptr_job_input->status
- || _MALI_OSK_ERR_OK != err )
- {
- _mali_osk_free(job200);
- }
-#if MALI_STATE_TRACKING
- if (_MALI_UK_START_JOB_STARTED==user_ptr_job_input->status)
- {
- if(job)
- {
- job->job_nr=_mali_osk_atomic_inc_return(&session->jobs_received);
- }
- }
-#endif
-
- MALI_ERROR(err);
-}
-
-/* This function is called from the ioctl function and should write the necessary data
-to userspace telling which job was finished and the status and debuginfo for this job.
-The function must also free and cleanup the input job object. */
-static void subsystem_mali200_return_job_to_user( mali_core_job * job, mali_subsystem_job_end_code end_status)
-{
- mali200_job *job200;
- _mali_uk_pp_job_finished_s * job_out;
- _mali_uk_pp_start_job_s * job_input;
- mali_core_session *session;
-
- if (NULL == job)
- {
- MALI_DEBUG_PRINT(1, ("subsystem_mali200_return_job_to_user received a NULL ptr\n"));
- return;
- }
-
- job200 = _MALI_OSK_CONTAINER_OF(job, mali200_job, embedded_core_job);
-
- if (NULL == job200->notification_obj)
- {
- MALI_DEBUG_PRINT(1, ("Found job200 with NULL notification object, abandoning userspace sending\n"));
- return;
- }
-
- job_out = job200->notification_obj->result_buffer;
- job_input= &(job200->user_input);
- session = job->session;
-
- MALI_DEBUG_PRINT(4, ("Mali PP: Job: 0x%08x OUTPUT to user. Runtime: %dus\n",
- (u32)job200->user_input.user_job_ptr,
- job->render_time_usecs)) ;
-
- _mali_osk_memset(job_out, 0 , sizeof(_mali_uk_pp_job_finished_s));
-
- job_out->user_job_ptr = job_input->user_job_ptr;
-
- switch( end_status )
- {
- case JOB_STATUS_CONTINUE_RUN:
- case JOB_STATUS_END_SUCCESS:
- case JOB_STATUS_END_OOM:
- case JOB_STATUS_END_ABORT:
- case JOB_STATUS_END_TIMEOUT_SW:
- case JOB_STATUS_END_HANG:
- case JOB_STATUS_END_SEG_FAULT:
- case JOB_STATUS_END_ILLEGAL_JOB:
- case JOB_STATUS_END_UNKNOWN_ERR:
- case JOB_STATUS_END_SHUTDOWN:
- case JOB_STATUS_END_SYSTEM_UNUSABLE:
- job_out->status = (mali_subsystem_job_end_code) end_status;
- break;
-
- default:
- job_out->status = JOB_STATUS_END_UNKNOWN_ERR ;
- }
- job_out->irq_status = job200->irq_status;
- job_out->perf_counter0 = job200->perf_counter0;
- job_out->perf_counter1 = job200->perf_counter1;
- job_out->render_time = job->render_time_usecs;
-
-#if defined(USING_MALI400_L2_CACHE)
- job_out->perf_counter_l2_src0 = job200->perf_counter_l2_src0;
- job_out->perf_counter_l2_src1 = job200->perf_counter_l2_src1;
- job_out->perf_counter_l2_val0 = job200->perf_counter_l2_val0;
- job_out->perf_counter_l2_val1 = job200->perf_counter_l2_val1;
- job_out->perf_counter_l2_val0_raw = job200->perf_counter_l2_val0_raw;
- job_out->perf_counter_l2_val1_raw = job200->perf_counter_l2_val1_raw;
-#endif
-
-#if MALI_STATE_TRACKING
- _mali_osk_atomic_inc(&session->jobs_returned);
-#endif
- _mali_osk_notification_queue_send( session->notification_queue, job200->notification_obj);
- job200->notification_obj = NULL;
-
- _mali_osk_free(job200);
-}
-
-static void subsystem_mali200_renderunit_delete(mali_core_renderunit * core)
-{
- MALI_DEBUG_PRINT(5, ("Mali PP: mali200_renderunit_delete\n"));
- _mali_osk_free(core);
-}
-
-static void mali200_reset_hard(struct mali_core_renderunit * core)
-{
- const int reset_finished_loop_count = 15;
- const u32 reset_wait_target_register = MALI200_REG_ADDR_MGMT_WRITE_BOUNDARY_LOW;
- const u32 reset_invalid_value = 0xC0FFE000;
- const u32 reset_check_value = 0xC01A0000;
- const u32 reset_default_value = 0;
- int i;
-
- MALI_DEBUG_PRINT(5, ("subsystem_mali200_renderunit_reset_core_hard called for core %s\n", core->description));
-
- mali_core_renderunit_register_write(core, reset_wait_target_register, reset_invalid_value);
-
- mali_core_renderunit_register_write(
- core,
- MALI200_REG_ADDR_MGMT_CTRL_MGMT,
- MALI200_REG_VAL_CTRL_MGMT_FORCE_RESET);
-
- for (i = 0; i < reset_finished_loop_count; i++)
- {
- mali_core_renderunit_register_write(core, reset_wait_target_register, reset_check_value);
- if (reset_check_value == mali_core_renderunit_register_read(core, reset_wait_target_register))
- {
- MALI_DEBUG_PRINT(5, ("Reset loop exiting after %d iterations\n", i));
- break;
- }
- _mali_osk_time_ubusydelay(10);
- }
-
- if (i == reset_finished_loop_count)
- {
- MALI_DEBUG_PRINT(1, ("The reset loop didn't work\n"));
- }
-
- mali_core_renderunit_register_write(core, reset_wait_target_register, reset_default_value); /* set it back to the default */
- mali_core_renderunit_register_write(core, MALI200_REG_ADDR_MGMT_INT_CLEAR, MALI200_REG_VAL_IRQ_MASK_ALL);
-}
-
-static void subsystem_mali200_renderunit_reset_core(struct mali_core_renderunit * core, mali_core_reset_style style)
-{
- MALI_DEBUG_PRINT(5, ("Mali PP: renderunit_reset_core\n"));
-
- switch (style)
- {
- case MALI_CORE_RESET_STYLE_RUNABLE:
- mali200_reset(core);
- break;
- case MALI_CORE_RESET_STYLE_DISABLE:
- mali200_raw_reset(core); /* do the raw reset */
- mali_core_renderunit_register_write(core, MALI200_REG_ADDR_MGMT_INT_MASK, 0); /* then disable the IRQs */
- break;
- case MALI_CORE_RESET_STYLE_HARD:
- mali200_reset_hard(core);
- break;
- default:
- MALI_DEBUG_PRINT(1, ("Unknown reset type %d\n", style));
- }
-}
-
-static void subsystem_mali200_renderunit_probe_core_irq_trigger(struct mali_core_renderunit* core)
-{
- mali_core_renderunit_register_write(core, MALI200_REG_ADDR_MGMT_INT_MASK, MALI200_REG_VAL_IRQ_MASK_USED);
- mali_core_renderunit_register_write(core, MALI200_REG_ADDR_MGMT_INT_RAWSTAT, MALI200_REG_VAL_IRQ_FORCE_HANG);
- _mali_osk_mem_barrier();
-}
-
-static _mali_osk_errcode_t subsystem_mali200_renderunit_probe_core_irq_finished(struct mali_core_renderunit* core)
-{
- u32 irq_readout;
-
- irq_readout = mali_core_renderunit_register_read(core, MALI200_REG_ADDR_MGMT_INT_STATUS);
-
- if ( MALI200_REG_VAL_IRQ_FORCE_HANG & irq_readout )
- {
- mali_core_renderunit_register_write(core, MALI200_REG_ADDR_MGMT_INT_CLEAR, MALI200_REG_VAL_IRQ_FORCE_HANG);
- _mali_osk_mem_barrier();
- MALI_SUCCESS;
- }
-
- MALI_ERROR(_MALI_OSK_ERR_FAULT);
-}
-
-_mali_osk_errcode_t _mali_ukk_pp_start_job( _mali_uk_pp_start_job_s *args )
-{
- mali_core_session * session;
- MALI_DEBUG_ASSERT_POINTER(args);
- MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS);
- session = (mali_core_session *)mali_kernel_session_manager_slot_get(args->ctx, mali_subsystem_mali200_id);
- MALI_CHECK_NON_NULL(session, _MALI_OSK_ERR_FAULT);
- return mali_core_subsystem_ioctl_start_job(session, args);
-}
-
-_mali_osk_errcode_t _mali_ukk_get_pp_number_of_cores( _mali_uk_get_pp_number_of_cores_s *args )
-{
- mali_core_session * session;
- MALI_DEBUG_ASSERT_POINTER(args);
- MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS);
- session = (mali_core_session *)mali_kernel_session_manager_slot_get(args->ctx, mali_subsystem_mali200_id);
- MALI_CHECK_NON_NULL(session, _MALI_OSK_ERR_FAULT);
- return mali_core_subsystem_ioctl_number_of_cores_get(session, &args->number_of_cores);
-}
-
-_mali_osk_errcode_t _mali_ukk_get_pp_core_version( _mali_uk_get_pp_core_version_s *args )
-{
- mali_core_session * session;
- MALI_DEBUG_ASSERT_POINTER(args);
- MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS);
- session = (mali_core_session *)mali_kernel_session_manager_slot_get(args->ctx, mali_subsystem_mali200_id);
- MALI_CHECK_NON_NULL(session, _MALI_OSK_ERR_FAULT);
- return mali_core_subsystem_ioctl_core_version_get(session, &args->version);
-}
-
-void _mali_ukk_pp_abort_job( _mali_uk_pp_abort_job_s * args)
-{
- mali_core_session * session;
- MALI_DEBUG_ASSERT_POINTER(args);
- if (NULL == args->ctx) return;
- session = (mali_core_session *)mali_kernel_session_manager_slot_get(args->ctx, mali_subsystem_mali200_id);
- if (NULL == session) return;
- mali_core_subsystem_ioctl_abort_job(session, args->abort_id);
-
-}
-
-#if USING_MALI_PMM
-
-_mali_osk_errcode_t malipp_signal_power_up( u32 core_num, mali_bool queue_only )
-{
- MALI_DEBUG_PRINT(4, ("Mali PP: signal power up core: %d - queue_only: %d\n", core_num, queue_only ));
-
- return( mali_core_subsystem_signal_power_up( &subsystem_mali200, core_num, queue_only ) );
-}
-
-_mali_osk_errcode_t malipp_signal_power_down( u32 core_num, mali_bool immediate_only )
-{
- MALI_DEBUG_PRINT(4, ("Mali PP: signal power down core: %d - immediate_only: %d\n", core_num, immediate_only ));
-
- return( mali_core_subsystem_signal_power_down( &subsystem_mali200, core_num, immediate_only ) );
-}
-
-#endif
-
-#if MALI_STATE_TRACKING
-u32 mali200_subsystem_dump_state(char *buf, u32 size)
-{
- return mali_core_renderunit_dump_state(&subsystem_mali200, buf, size);
-}
-#endif
diff --git a/drivers/media/video/samsung/mali/common/mali_kernel_common.h b/drivers/media/video/samsung/mali/common/mali_kernel_common.h
index ab6f143..b354f92 100644
--- a/drivers/media/video/samsung/mali/common/mali_kernel_common.h
+++ b/drivers/media/video/samsung/mali/common/mali_kernel_common.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 ARM Limited. All rights reserved.
+ * 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.
@@ -28,7 +28,6 @@
#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.
@@ -129,7 +128,9 @@
} 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 { \
diff --git a/drivers/media/video/samsung/mali/common/mali_kernel_core.c b/drivers/media/video/samsung/mali/common/mali_kernel_core.c
index be1889d..0155dfc 100644
--- a/drivers/media/video/samsung/mali/common/mali_kernel_core.c
+++ b/drivers/media/video/samsung/mali/common/mali_kernel_core.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 ARM Limited. All rights reserved.
+ * 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.
@@ -8,344 +8,805 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#include "mali_kernel_subsystem.h"
-#include "mali_kernel_mem.h"
-#include "mali_kernel_session_manager.h"
-#include "mali_kernel_pp.h"
-#include "mali_kernel_gp.h"
+#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_kernel_rendercore.h"
-#if defined USING_MALI400_L2_CACHE
-#include "mali_kernel_l2_cache.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_gp.h"
+#include "mali_pp.h"
+#include "mali_gp_scheduler.h"
+#include "mali_pp_scheduler.h"
+#include "mali_cluster.h"
+#include "mali_group.h"
+#include "mali_pm.h"
+#include "mali_pmu.h"
+#include "mali_scheduler.h"
+#ifdef CONFIG_MALI400_GPU_UTILIZATION
+#include "mali_kernel_utilization.h"
+#endif
+#include "mali_l2_cache.h"
+#if MALI_TIMELINE_PROFILING_ENABLED
+#include "mali_osk_profiling.h"
#endif
-#if USING_MALI_PMM
-#include "mali_pmm.h"
-#endif /* USING_MALI_PMM */
-
-/* platform specific set up */
-#include "mali_platform.h"
-
-/* Initialized when this subsystem is initialized. This is determined by the
- * position in subsystems[], and so the value used to initialize this is
- * determined at compile time */
-static mali_kernel_subsystem_identifier mali_subsystem_core_id = -1;
/** Pointer to table of resource definitions available to the Mali driver.
* _mali_osk_resources_init() sets up the pointer to this table.
*/
static _mali_osk_resource_t *arch_configuration = NULL;
+/** Start profiling from module load? */
+int mali_boot_profiling = 0;
+
/** Number of resources initialized by _mali_osk_resources_init() */
static u32 num_resources;
-static _mali_osk_errcode_t register_resources( _mali_osk_resource_t **arch_configuration, u32 num_resources );
-
-static _mali_osk_errcode_t initialize_subsystems(void);
-static void terminate_subsystems(void);
-
-static _mali_osk_errcode_t mali_kernel_subsystem_core_setup(mali_kernel_subsystem_identifier id);
-static void mali_kernel_subsystem_core_cleanup(mali_kernel_subsystem_identifier id);
-static _mali_osk_errcode_t mali_kernel_subsystem_core_system_info_fill(_mali_system_info* info);
-static _mali_osk_errcode_t mali_kernel_subsystem_core_session_begin(struct mali_session_data * mali_session_data, mali_kernel_subsystem_session_slot * slot, _mali_osk_notification_queue_t * queue);
+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;
static _mali_osk_errcode_t build_system_info(void);
static void cleanup_system_info(_mali_system_info *cleanup);
-/**
- * @brief handler for MEM_VALIDATION resources
- *
- * This resource handler is common to all memory systems. It provides a default
- * means for validating requests to map in external memory via
- * _mali_ukk_map_external_mem. In addition, if _mali_ukk_va_to_pa is
- * implemented, then _mali_ukk_va_to_pa can make use of this MEM_VALIDATION
- * resource.
- *
- * MEM_VALIDATION also provide a CPU physical to Mali physical address
- * translation, for use by _mali_ukk_map_external_mem.
- *
- * @note MEM_VALIDATION resources are only to handle simple cases where a
- * certain physical address range is allowed to be mapped in by any process,
- * e.g. a framebuffer at a fixed location. If the implementor has more complex
- * mapping requirements, then they must either:
- * - implement their own memory validation function
- * - or, integrate with UMP.
- *
- * @param resource The resource to handle (type MEM_VALIDATION)
- * @return _MALI_OSK_ERR_OK on success, otherwise a suitable _mali_osk_errcode_t on failure.
- */
-static _mali_osk_errcode_t mali_kernel_core_resource_mem_validation(_mali_osk_resource_t * resource);
-
-/* MEM_VALIDATION handler state */
-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 */
- s32 cpu_usage_adjust; /**< Offset to add to Mali Physical address to obtain CPU physical address */
-} _mali_mem_validation_t;
+/* system info variables */
+static _mali_osk_lock_t *system_info_lock = NULL;
+static _mali_system_info *system_info = NULL;
+static u32 system_info_size = 0;
+static u32 first_pp_offset = 0;
-#define INVALID_MEM 0xffffffff
+#define HANG_CHECK_MSECS_DEFAULT 500 /* 500 ms */
+#define WATCHDOG_MSECS_DEFAULT 4000 /* 4 s */
-static _mali_mem_validation_t mem_validator = { INVALID_MEM, INVALID_MEM, -1 };
+/* timer related */
+int mali_max_job_runtime = WATCHDOG_MSECS_DEFAULT;
+int mali_hang_check_interval = HANG_CHECK_MSECS_DEFAULT;
-static struct mali_kernel_subsystem mali_subsystem_core =
+static _mali_osk_resource_t *mali_find_resource(_mali_osk_resource_type_t type, u32 offset)
{
- mali_kernel_subsystem_core_setup, /* startup */
- mali_kernel_subsystem_core_cleanup, /* shutdown */
- NULL, /* load_complete */
- mali_kernel_subsystem_core_system_info_fill, /* system_info_fill */
- mali_kernel_subsystem_core_session_begin, /* session_begin */
- NULL, /* session_end */
- NULL, /* broadcast_notification */
-#if MALI_STATE_TRACKING
- NULL, /* dump_state */
-#endif
-};
+ int i;
+ u32 addr = global_gpu_base_address + offset;
-static struct mali_kernel_subsystem * subsystems[] =
-{
+ for (i = 0; i < num_resources; i++)
+ {
+ if (type == arch_configuration[i].type && arch_configuration[i].base == addr)
+ {
+ return &(arch_configuration[i]);
+ }
+ }
-#if USING_MALI_PMM
- /* The PMM must be initialized before any cores - including L2 cache */
- &mali_subsystem_pmm,
-#endif
+ return NULL;
+}
- /* always included */
- &mali_subsystem_memory,
+static u32 mali_count_resources(_mali_osk_resource_type_t type)
+{
+ int i;
+ u32 retval = 0;
- /* The rendercore subsystem must be initialized before any subsystem based on the
- * rendercores is started e.g. mali_subsystem_mali200 and mali_subsystem_gp2 */
- &mali_subsystem_rendercore,
+ for (i = 0; i < num_resources; i++)
+ {
+ if (type == arch_configuration[i].type)
+ {
+ retval++;
+ }
+ }
- /* add reference to the subsystem */
- &mali_subsystem_mali200,
+ return retval;
+}
- /* add reference to the subsystem */
- &mali_subsystem_gp2,
-#if defined USING_MALI400_L2_CACHE
- &mali_subsystem_l2_cache,
-#endif
+static _mali_osk_errcode_t mali_parse_gpu_base_and_first_pp_offset_address(void)
+{
+ int i;
+ _mali_osk_resource_t *first_gp_resource = NULL;
+ _mali_osk_resource_t *first_pp_resource = NULL;
+
+ for (i = 0; i < num_resources; i++)
+ {
+ if (MALI_GP == arch_configuration[i].type)
+ {
+ if (NULL == first_gp_resource || first_gp_resource->base > arch_configuration[i].base)
+ {
+ first_gp_resource = &(arch_configuration[i]);
+ }
+ }
+ if (MALI_PP == arch_configuration[i].type)
+ {
+ if (NULL == first_pp_resource || first_pp_resource->base > arch_configuration[i].base)
+ {
+ first_pp_resource = &(arch_configuration[i]);
+ }
+ }
+ }
- /* always included */
- /* NOTE Keep the core entry at the tail of the list */
- &mali_subsystem_core
-};
+ if (NULL == first_gp_resource || NULL == first_pp_resource)
+ {
+ MALI_PRINT_ERROR(("No GP+PP core specified in config file\n"));
+ return _MALI_OSK_ERR_FAULT;
+ }
-#define SUBSYSTEMS_COUNT ( sizeof(subsystems) / sizeof(subsystems[0]) )
+ if (first_gp_resource->base < first_pp_resource->base)
+ {
+ /* GP is first, so we are dealing with Mali-300, Mali-400 or Mali-450 */
+ global_gpu_base_address = first_gp_resource->base;
+ first_pp_offset = 0x8000;
+ }
+ else
+ {
+ /* PP is first, so we are dealing with Mali-200 */
+ global_gpu_base_address = first_pp_resource->base;
+ first_pp_offset = 0x0;
+ }
+ MALI_SUCCESS;
+}
-/* Pointers to this type available as incomplete struct in mali_kernel_session_manager.h */
-struct mali_session_data
+static _mali_osk_errcode_t mali_parse_product_info(void)
{
- void * subsystem_data[SUBSYSTEMS_COUNT];
- _mali_osk_notification_queue_t * ioctl_queue;
-};
+ _mali_osk_resource_t *first_pp_resource = NULL;
-static mali_kernel_resource_registrator resource_handler[RESOURCE_TYPE_COUNT] = { NULL, };
+ /* Find the first PP core */
+ first_pp_resource = mali_find_resource(MALI_PP, first_pp_offset);
+ if (NULL != 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);
+ if (NULL != group)
+ {
+ /*struct mali_pp_core *pp_core = mali_pp_create(first_pp_resource, group, 0);*/
+ struct mali_pp_core *pp_core = mali_pp_create(first_pp_resource, group);
+ if (NULL != pp_core)
+ {
+ u32 pp_version = mali_pp_core_get_version(pp_core);
+ mali_pp_delete(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));
+ 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 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"));
+ }
-/* system info variables */
-static _mali_osk_lock_t *system_info_lock = NULL;
-static _mali_system_info * system_info = NULL;
-static u32 system_info_size = 0;
+ return _MALI_OSK_ERR_FAULT;
+}
-/* is called from OS specific driver entry point */
-_mali_osk_errcode_t mali_kernel_constructor( void )
+static void mali_delete_clusters(void)
{
- _mali_osk_errcode_t err;
-
- err = mali_platform_init();
- if (_MALI_OSK_ERR_OK != err) goto error1;
+ u32 i;
+ u32 number_of_clusters = mali_cluster_get_glob_num_clusters();
- err = _mali_osk_init();
- if (_MALI_OSK_ERR_OK != err) goto error2;
+ for (i = 0; i < number_of_clusters; i++)
+ {
+ mali_cluster_delete(mali_cluster_get_global_cluster(i));
+ }
+}
- MALI_DEBUG_PRINT(2, ("\n"));
- 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, ("Svn revision: %s\n", SVN_REV_STRING));
+static _mali_osk_errcode_t mali_create_cluster(_mali_osk_resource_t *resource)
+{
+ if (NULL != resource)
+ {
+ struct mali_l2_cache_core *l2_cache;
- err = initialize_subsystems();
- if (_MALI_OSK_ERR_OK != err) goto error3;
+ if (mali_l2_cache_core_get_glob_num_l2_cores() >= mali_l2_cache_core_get_max_num_l2_cores())
+ {
+ MALI_PRINT_ERROR(("Found too many L2 cache core objects, max %u is supported\n", mali_l2_cache_core_get_max_num_l2_cores()));
+ return _MALI_OSK_ERR_FAULT;
+ }
- MALI_PRINT(("Mali device driver %s loaded\n", SVN_REV_STRING));
+ MALI_DEBUG_PRINT(3, ("Found L2 cache %s, starting new cluster\n", resource->description));
- MALI_SUCCESS;
+ /*l2_cache = mali_l2_cache_create(resource, global_num_l2_cache_cores);*/
+ l2_cache = mali_l2_cache_create(resource);
+ if (NULL == l2_cache)
+ {
+ MALI_PRINT_ERROR(("Failed to create L2 cache object\n"));
+ return _MALI_OSK_ERR_FAULT;
+ }
-error3:
- MALI_PRINT(("Mali subsystems failed\n"));
- _mali_osk_term();
-error2:
- MALI_PRINT(("Mali device driver init failed\n"));
- if (_MALI_OSK_ERR_OK != mali_platform_deinit())
+ if (NULL == mali_cluster_create(l2_cache))
+ {
+ MALI_PRINT_ERROR(("Failed to create cluster object\n"));
+ mali_l2_cache_delete(l2_cache);
+ return _MALI_OSK_ERR_FAULT;
+ }
+ }
+ else
{
- MALI_PRINT(("Failed to deinit platform\n"));
+ mali_cluster_create(NULL);
+ if (NULL == mali_cluster_get_global_cluster(0))
+ {
+ MALI_PRINT_ERROR(("Failed to create cluster object\n"));
+ return _MALI_OSK_ERR_FAULT;
+ }
}
-error1:
- MALI_PRINT(("Failed to init platform\n"));
- MALI_ERROR(err);
+
+ MALI_DEBUG_PRINT(3, ("Created cluster object\n"));
+ return _MALI_OSK_ERR_OK;
}
-/* is called from OS specific driver exit point */
-void mali_kernel_destructor( void )
+static _mali_osk_errcode_t mali_parse_config_cluster(void)
{
- MALI_DEBUG_PRINT(2, ("\n"));
- MALI_DEBUG_PRINT(2, ("Unloading Mali v%d device driver.\n",_MALI_API_VERSION));
-#if USING_MALI_PMM
- malipmm_force_powerup();
-#endif
- terminate_subsystems(); /* subsystems are responsible for their registered resources */
- _mali_osk_term();
-
- if (_MALI_OSK_ERR_OK != mali_platform_deinit())
+ if (_MALI_PRODUCT_ID_MALI200 == global_product_id)
{
- MALI_PRINT(("Failed to deinit platform\n"));
+ /* Create dummy cluster without L2 cache */
+ return mali_create_cluster(NULL);
}
- MALI_DEBUG_PRINT(2, ("Module unloaded.\n"));
-}
+ else if (_MALI_PRODUCT_ID_MALI300 == global_product_id || _MALI_PRODUCT_ID_MALI400 == global_product_id)
+ {
+ _mali_osk_resource_t *l2_resource = mali_find_resource(MALI_L2, 0x1000);
+ if (NULL == l2_resource)
+ {
+ MALI_DEBUG_PRINT(3, ("Did not find required Mali L2 cache in config file\n"));
+ return _MALI_OSK_ERR_FAULT;
+ }
-_mali_osk_errcode_t register_resources( _mali_osk_resource_t **arch_configuration, u32 num_resources )
-{
- _mali_osk_resource_t *arch_resource = *arch_configuration;
- u32 i;
-#if USING_MALI_PMM
- u32 is_pmu_first_resource = 1;
-#endif /* USING_MALI_PMM */
-
- /* loop over arch configuration */
- for (i = 0; i < num_resources; ++i, arch_resource++)
- {
- if ( (arch_resource->type >= RESOURCE_TYPE_FIRST) &&
- (arch_resource->type < RESOURCE_TYPE_COUNT) &&
- (NULL != resource_handler[arch_resource->type])
- )
- {
-#if USING_MALI_PMM
- if((arch_resource->type != PMU) && (is_pmu_first_resource == 1))
+ return mali_create_cluster(l2_resource);
+ }
+ else if (_MALI_PRODUCT_ID_MALI450 == global_product_id)
+ {
+ /*
+ * 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 */
+ l2_gp_resource = mali_find_resource(MALI_L2, 0x10000);
+ if (NULL != l2_gp_resource)
+ {
+ _mali_osk_errcode_t ret;
+ MALI_DEBUG_PRINT(3, ("Creating Mali-450 cluster for GP\n"));
+ ret = mali_create_cluster(l2_gp_resource);
+ if (_MALI_OSK_ERR_OK != ret)
{
- _mali_osk_resource_t mali_pmu_virtual_resource;
- mali_pmu_virtual_resource.type = PMU;
- mali_pmu_virtual_resource.description = "Virtual PMU";
- mali_pmu_virtual_resource.base = 0x00000000;
- mali_pmu_virtual_resource.cpu_usage_adjust = 0;
- mali_pmu_virtual_resource.size = 0;
- mali_pmu_virtual_resource.irq = 0;
- mali_pmu_virtual_resource.flags = 0;
- mali_pmu_virtual_resource.mmu_id = 0;
- mali_pmu_virtual_resource.alloc_order = 0;
- MALI_CHECK_NO_ERROR(resource_handler[mali_pmu_virtual_resource.type](&mali_pmu_virtual_resource));
+ return ret;
}
- is_pmu_first_resource = 0;
-#endif /* USING_MALI_PMM */
+ }
+ else
+ {
+ MALI_DEBUG_PRINT(3, ("Did not find required Mali L2 cache for GP in config file\n"));
+ return _MALI_OSK_ERR_FAULT;
+ }
- MALI_CHECK_NO_ERROR(resource_handler[arch_resource->type](arch_resource));
- /* the subsystem shutdown process will release all the resources already registered */
+ /* Make cluster for first PP core group */
+ l2_pp_grp0_resource = mali_find_resource(MALI_L2, 0x1000);
+ if (NULL != l2_pp_grp0_resource)
+ {
+ _mali_osk_errcode_t ret;
+ MALI_DEBUG_PRINT(3, ("Creating Mali-450 cluster for PP group 0\n"));
+ ret = mali_create_cluster(l2_pp_grp0_resource);
+ if (_MALI_OSK_ERR_OK != ret)
+ {
+ return ret;
+ }
}
else
{
- MALI_DEBUG_PRINT(1, ("No handler installed for resource %s, type %d\n", arch_resource->description, arch_resource->type));
- MALI_ERROR(_MALI_OSK_ERR_INVALID_ARGS);
+ 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 */
+ l2_pp_grp1_resource = mali_find_resource(MALI_L2, 0x11000);
+ if (NULL != l2_pp_grp1_resource)
+ {
+ _mali_osk_errcode_t ret;
+ MALI_DEBUG_PRINT(3, ("Creating Mali-450 cluster for PP group 0\n"));
+ ret = mali_create_cluster(l2_pp_grp1_resource);
+ if (_MALI_OSK_ERR_OK != ret)
+ {
+ return ret;
+ }
}
}
- MALI_SUCCESS;
+ return _MALI_OSK_ERR_OK;
}
-static _mali_osk_errcode_t initialize_subsystems(void)
+static _mali_osk_errcode_t mali_create_group(struct mali_cluster *cluster,
+ _mali_osk_resource_t *resource_mmu,
+ _mali_osk_resource_t *resource_gp,
+ _mali_osk_resource_t *resource_pp)
{
- int i, j;
- _mali_osk_errcode_t err = _MALI_OSK_ERR_FAULT; /* default error code */
+ struct mali_mmu_core *mmu;
+ struct mali_group *group;
+ struct mali_pp_core *pp;
- MALI_CHECK_NON_NULL(system_info_lock = _mali_osk_lock_init( (_mali_osk_lock_flags_t)(_MALI_OSK_LOCKFLAG_SPINLOCK | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE), 0, 0 ), _MALI_OSK_ERR_FAULT);
+ MALI_DEBUG_PRINT(3, ("Starting new group for MMU %s\n", resource_mmu->description));
- for (i = 0; i < (int)SUBSYSTEMS_COUNT; ++i)
+ /* Create the MMU object */
+ mmu = mali_mmu_create(resource_mmu);
+ if (NULL == mmu)
{
- if (NULL != subsystems[i]->startup)
+ MALI_PRINT_ERROR(("Failed to create MMU object\n"));
+ return _MALI_OSK_ERR_FAULT;
+ }
+
+ /* Create the group object */
+ group = mali_group_create(cluster, mmu);
+ if (NULL == group)
+ {
+ MALI_PRINT_ERROR(("Failed to create group object for MMU %s\n", resource_mmu->description));
+ mali_mmu_delete(mmu);
+ return _MALI_OSK_ERR_FAULT;
+ }
+
+ /* Set pointer back to group in mmu.*/
+ mali_mmu_set_group(mmu, group);
+
+ /* Add this group to current cluster */
+ mali_cluster_add_group(cluster, group);
+
+ if (NULL != resource_gp)
+ {
+ /* Create the GP core object inside this group */
+ /* global_gp_core = mali_gp_create(resource_gp, group); */
+ if (NULL == mali_gp_create(resource_gp, group))
{
- /* the subsystem has a startup function defined */
- err = subsystems[i]->startup(i); /* the subsystem identifier is the offset in our subsystems array */
- if (_MALI_OSK_ERR_OK != err) goto cleanup;
+ /* 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"));
+ return _MALI_OSK_ERR_FAULT;
}
+
+ /* Add GP object to this group */
+ MALI_DEBUG_PRINT(3, ("Adding GP %s to group\n", resource_gp->description));
+ mali_group_add_gp_core(group, mali_gp_get_global_gp_core());
}
- for (j = 0; j < (int)SUBSYSTEMS_COUNT; ++j)
+ if (NULL != resource_pp)
{
- if (NULL != subsystems[j]->load_complete)
+ /* Create the PP core object inside this group */
+ pp = mali_pp_create(resource_pp, group);
+
+ if (NULL == pp)
{
- /* the subsystem has a load_complete function defined */
- err = subsystems[j]->load_complete(j);
- if (_MALI_OSK_ERR_OK != err) goto cleanup;
+ /* 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"));
+ return _MALI_OSK_ERR_FAULT;
}
+
+ /* Add PP object to this group */
+ MALI_DEBUG_PRINT(3, ("Adding PP %s to group\n", resource_pp->description));
+ mali_group_add_pp_core(group, pp);
}
- /* All systems loaded and resources registered */
- /* Build system info */
- if (_MALI_OSK_ERR_OK != build_system_info()) goto cleanup;
+ return _MALI_OSK_ERR_OK;
+}
+
+static _mali_osk_errcode_t mali_parse_config_groups(void)
+{
+ if (_MALI_PRODUCT_ID_MALI200 == global_product_id)
+ {
+ _mali_osk_resource_t *resource_gp;
+ _mali_osk_resource_t *resource_pp;
+ _mali_osk_resource_t *resource_mmu;
+
+ MALI_DEBUG_ASSERT(1 == mali_cluster_get_glob_num_clusters());
- MALI_SUCCESS; /* all ok */
+ resource_gp = mali_find_resource(MALI_GP, 0x02000);
+ resource_pp = mali_find_resource(MALI_PP, 0x00000);
+ resource_mmu = mali_find_resource(MMU, 0x03000);
-cleanup:
- /* i is index of subsystem which failed to start, all indices before that has to be shut down */
- for (i = i - 1; i >= 0; --i)
+ if (NULL == resource_mmu || NULL == resource_gp || NULL == resource_pp)
+ {
+ /* Missing mandatory core(s) */
+ return _MALI_OSK_ERR_FAULT;
+ }
+
+ /*return mali_create_group(global_clusters[0], resource_mmu, resource_gp, resource_pp);*/
+ return mali_create_group(mali_cluster_get_global_cluster(0), resource_mmu, resource_gp, resource_pp);
+ }
+ else if (_MALI_PRODUCT_ID_MALI300 == global_product_id ||
+ _MALI_PRODUCT_ID_MALI400 == global_product_id ||
+ _MALI_PRODUCT_ID_MALI450 == global_product_id)
{
- /* the subsystem identifier is the offset in our subsystems array */
- /* Call possible shutdown notficiation functions */
- if (NULL != subsystems[i]->shutdown) subsystems[i]->shutdown(i);
+ _mali_osk_errcode_t err;
+ 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[mali_pp_get_max_num_pp_cores()];
+ _mali_osk_resource_t *resource_pp_mmu[mali_pp_get_max_num_pp_cores()];
+ u32 max_num_pp_cores = mali_pp_get_max_num_pp_cores();
+
+ if (_MALI_PRODUCT_ID_MALI450 == global_product_id)
+ {
+ /* Mali-450 has separate L2s for GP, and PP core group(s) */
+ cluster_id_pp_grp0 = 1;
+ cluster_id_pp_grp1 = 2;
+ }
+
+ resource_gp = mali_find_resource(MALI_GP, 0x00000);
+ resource_gp_mmu = mali_find_resource(MMU, 0x03000);
+ resource_pp[0] = mali_find_resource(MALI_PP, 0x08000);
+ resource_pp[1] = mali_find_resource(MALI_PP, 0x0A000);
+ resource_pp[2] = mali_find_resource(MALI_PP, 0x0C000);
+ resource_pp[3] = mali_find_resource(MALI_PP, 0x0E000);
+ resource_pp[4] = mali_find_resource(MALI_PP, 0x28000);
+ resource_pp[5] = mali_find_resource(MALI_PP, 0x2A000);
+ resource_pp[6] = mali_find_resource(MALI_PP, 0x2C000);
+ resource_pp[7] = mali_find_resource(MALI_PP, 0x2E000);
+ resource_pp_mmu[0] = mali_find_resource(MMU, 0x04000);
+ resource_pp_mmu[1] = mali_find_resource(MMU, 0x05000);
+ resource_pp_mmu[2] = mali_find_resource(MMU, 0x06000);
+ resource_pp_mmu[3] = mali_find_resource(MMU, 0x07000);
+ resource_pp_mmu[4] = mali_find_resource(MMU, 0x1C000);
+ resource_pp_mmu[5] = mali_find_resource(MMU, 0x1D000);
+ resource_pp_mmu[6] = mali_find_resource(MMU, 0x1E000);
+ resource_pp_mmu[7] = mali_find_resource(MMU, 0x1F000);
+
+ if (NULL == resource_gp || NULL == resource_gp_mmu || NULL == resource_pp[0] || NULL == resource_pp_mmu[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 (0x%08X, 0x%08X, 0x%08X, 0x%08X)\n",
+ resource_gp, resource_gp_mmu, resource_pp[0], resource_pp_mmu[0]));
+ return _MALI_OSK_ERR_FAULT;
+ }
+
+ MALI_DEBUG_ASSERT(1 <= mali_cluster_get_glob_num_clusters());
+ err = mali_create_group(mali_cluster_get_global_cluster(cluster_id_gp), resource_gp_mmu, resource_gp, NULL);
+ if (err != _MALI_OSK_ERR_OK)
+ {
+ return err;
+ }
+
+ /* Create group for first (and mandatory) PP core */
+ MALI_DEBUG_ASSERT(mali_cluster_get_glob_num_clusters() >= (cluster_id_pp_grp0 + 1)); /* >= 1 on Mali-300 and Mali-400, >= 2 on Mali-450 */
+ err = mali_create_group(mali_cluster_get_global_cluster(cluster_id_pp_grp0), resource_pp_mmu[0], NULL, resource_pp[0]);
+ if (err != _MALI_OSK_ERR_OK)
+ {
+ return err;
+ }
+
+ /* 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 (NULL != resource_pp[i])
+ {
+ err = mali_create_group(mali_cluster_get_global_cluster(cluster_id_pp_grp0), resource_pp_mmu[i], NULL, resource_pp[i]);
+ if (err != _MALI_OSK_ERR_OK)
+ {
+ return err;
+ }
+ }
+ }
+
+ /* Create groups for cores in the second PP core group */
+ for (i = 4; i < max_num_pp_cores; i++) /* Second half of the PP cores belong to second core group */
+ {
+ if (NULL != resource_pp[i])
+ {
+ MALI_DEBUG_ASSERT(mali_cluster_get_glob_num_clusters() >= 2); /* Only Mali-450 have more than 4 PPs, and these cores belong to second core group */
+ err = mali_create_group(mali_cluster_get_global_cluster(cluster_id_pp_grp1), resource_pp_mmu[i], NULL, resource_pp[i]);
+ if (err != _MALI_OSK_ERR_OK)
+ {
+ return err;
+ }
+ }
+ }
}
- _mali_osk_lock_term( system_info_lock );
- MALI_ERROR(err); /* err is what the module which failed its startup returned, or the default */
+ return _MALI_OSK_ERR_OK;
}
-static void terminate_subsystems(void)
+static _mali_osk_errcode_t mali_parse_config_pmu(void)
{
- int i;
- /* shut down subsystems in reverse order from startup */
- for (i = SUBSYSTEMS_COUNT - 1; i >= 0; --i)
+ _mali_osk_errcode_t err = _MALI_OSK_ERR_OK;
+ _mali_osk_resource_t *resource_pmu;
+ u32 number_of_pp_cores;
+ u32 number_of_l2_caches;
+
+ resource_pmu = mali_find_resource(PMU, 0x02000);
+ number_of_pp_cores = mali_count_resources(MALI_PP);
+ number_of_l2_caches = mali_count_resources(MALI_L2);
+
+ if (NULL != resource_pmu)
{
- /* the subsystem identifier is the offset in our subsystems array */
- if (NULL != subsystems[i]->shutdown) subsystems[i]->shutdown(i);
+ if (NULL == mali_pmu_create(resource_pmu, number_of_pp_cores, number_of_l2_caches))
+ {
+ err = _MALI_OSK_ERR_FAULT;
+ }
}
- if (system_info_lock) _mali_osk_lock_term( system_info_lock );
-
- /* Free _mali_system_info struct */
- cleanup_system_info(system_info);
+ return err;
}
-void _mali_kernel_core_broadcast_subsystem_message(mali_core_notification_message message, u32 data)
+static _mali_osk_errcode_t mali_parse_config_memory(void)
{
int i;
+ _mali_osk_errcode_t ret;
- for (i = 0; i < (int)SUBSYSTEMS_COUNT; ++i)
+ for(i = 0; i < num_resources; i++)
{
- if (NULL != subsystems[i]->broadcast_notification)
+ switch(arch_configuration[i].type)
{
- subsystems[i]->broadcast_notification(message, data);
+ case OS_MEMORY:
+ ret = mali_memory_core_resource_os_memory(&arch_configuration[i]);
+ if (_MALI_OSK_ERR_OK != ret)
+ {
+ MALI_PRINT_ERROR(("Failed to register OS_MEMORY\n"));
+ mali_memory_terminate();
+ return ret;
+ }
+ break;
+ case MEMORY:
+ ret = mali_memory_core_resource_dedicated_memory(&arch_configuration[i]);
+ if (_MALI_OSK_ERR_OK != ret)
+ {
+ MALI_PRINT_ERROR(("Failed to register MEMORY\n"));
+ mali_memory_terminate();
+ return ret;
+ }
+ break;
+ case MEM_VALIDATION:
+ ret = mali_mem_validation_add_range(&arch_configuration[i]);
+ if (_MALI_OSK_ERR_OK != ret)
+ {
+ MALI_PRINT_ERROR(("Failed to register MEM_VALIDATION\n"));
+ mali_memory_terminate();
+ return ret;
+ }
+ break;
+ default:
+ break;
}
}
+ return _MALI_OSK_ERR_OK;
}
-static _mali_osk_errcode_t mali_kernel_subsystem_core_setup(mali_kernel_subsystem_identifier id)
+_mali_osk_errcode_t mali_initialize_subsystems(void)
{
- mali_subsystem_core_id = id;
+ _mali_osk_errcode_t err;
+ mali_bool is_pmu_enabled;
- /* Register our own resources */
- MALI_CHECK_NO_ERROR(_mali_kernel_core_register_resource_handler(MEM_VALIDATION, mali_kernel_core_resource_mem_validation));
+ MALI_CHECK_NON_NULL(system_info_lock = _mali_osk_lock_init( (_mali_osk_lock_flags_t)(_MALI_OSK_LOCKFLAG_SPINLOCK
+ | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE), 0, 0 ), _MALI_OSK_ERR_FAULT);
- /* parse the arch resource definition and tell all the subsystems */
- /* this is why the core subsystem has to be specified last in the subsystem array */
- MALI_CHECK_NO_ERROR(_mali_osk_resources_init(&arch_configuration, &num_resources));
+ err = mali_session_initialize();
+ if (_MALI_OSK_ERR_OK != err) goto session_init_failed;
- MALI_CHECK_NO_ERROR(register_resources(&arch_configuration, num_resources));
+#if MALI_TIMELINE_PROFILING_ENABLED
+ err = _mali_osk_profiling_init(mali_boot_profiling ? MALI_TRUE : MALI_FALSE);
+ if (_MALI_OSK_ERR_OK != 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
- /* resource parsing succeeded and the subsystem have corretly accepted their resources */
- MALI_SUCCESS;
+ /* Build dummy system info. Will be removed in the future. */
+ err = build_system_info();
+ if (_MALI_OSK_ERR_OK != err) goto build_system_info_failed;
+
+ /* Get data from config.h */
+ err = _mali_osk_resources_init(&arch_configuration, &num_resources);
+ if (_MALI_OSK_ERR_OK != err) goto osk_resources_init_failed;
+
+ /* Initialize driver subsystems */
+ 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;
+
+ /* Parsing the GPU base address and first pp offset */
+ err = mali_parse_gpu_base_and_first_pp_offset_address();
+ if (_MALI_OSK_ERR_OK != err) goto parse_gpu_base_address_failed;
+
+ /* Initialize the MALI PMU */
+ err = mali_parse_config_pmu();
+ if (_MALI_OSK_ERR_OK != err) goto parse_pmu_config_failed;
+
+ is_pmu_enabled = mali_pmu_get_global_pmu_core() != NULL ? MALI_TRUE : MALI_FALSE;
+
+ /* Initialize the power management module */
+ err = mali_pm_initialize();
+ if (_MALI_OSK_ERR_OK != err) goto pm_init_failed;
+
+ /* Make sure the power stays on for the rest of this function */
+ mali_pm_always_on(MALI_TRUE);
+
+ /* 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 */
+
+ /* Initialize MMU module */
+ err = mali_mmu_initialize();
+ if (_MALI_OSK_ERR_OK != err) goto mmu_init_failed;
+
+ /* Initialize the DLBU module for Mali-450 */
+ if (_MALI_PRODUCT_ID_MALI450 == global_product_id)
+ {
+ err = mali_dlbu_initialize();
+ if (_MALI_OSK_ERR_OK != err) goto dlbu_init_failed;
+ }
+
+ /* Start configuring the actual Mali hardware. */
+ err = mali_parse_config_cluster();
+ 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;
+ err = mali_pp_scheduler_initialize();
+ if (_MALI_OSK_ERR_OK != err) goto pp_scheduler_init_failed;
+
+#ifdef CONFIG_MALI400_GPU_UTILIZATION
+ /* Initialize the GPU utilization tracking */
+ err = mali_utilization_init();
+ if (_MALI_OSK_ERR_OK != err) goto utilization_init_failed;
+#endif
+
+ /* We no longer need to stay */
+ mali_pm_always_on(MALI_FALSE);
+ MALI_SUCCESS; /* all ok */
+
+ /* Error handling */
+#ifdef CONFIG_MALI400_GPU_UTILIZATION
+utilization_init_failed:
+ mali_pp_scheduler_terminate();
+#endif
+pp_scheduler_init_failed:
+ mali_gp_scheduler_terminate();
+gp_scheduler_init_failed:
+ mali_scheduler_terminate();
+scheduler_init_failed:
+config_parsing_failed:
+ mali_delete_clusters(); /* Delete clusters even if config parsing failed. */
+ if (_MALI_PRODUCT_ID_MALI450 == global_product_id)
+ {
+ mali_dlbu_terminate();
+ }
+dlbu_init_failed:
+ mali_mmu_terminate();
+mmu_init_failed:
+ /* Nothing to roll back */
+product_info_parsing_failed:
+ mali_pm_terminate();
+pm_init_failed:
+ if (is_pmu_enabled)
+ {
+ mali_pmu_delete(mali_pmu_get_global_pmu_core());
+ }
+parse_pmu_config_failed:
+parse_gpu_base_address_failed:
+parse_memory_config_failed:
+ mali_memory_terminate();
+memory_init_failed:
+ _mali_osk_resources_term(&arch_configuration, num_resources);
+osk_resources_init_failed:
+ cleanup_system_info(system_info);
+build_system_info_failed:
+#if MALI_TIMELINE_PROFILING_ENABLED
+ _mali_osk_profiling_term();
+#endif
+ mali_session_terminate();
+session_init_failed:
+ return err;
+}
+
+void mali_terminate_subsystems(void)
+{
+ struct mali_pmu_core *pmu;
+ MALI_DEBUG_PRINT(2, ("terminate_subsystems() called\n"));
+
+ /* shut down subsystems in reverse order from startup */
+
+ mali_pm_always_on(MALI_TRUE); /* Mali will be powered off once PM subsystem terminates */
+
+#ifdef CONFIG_MALI400_GPU_UTILIZATION
+ mali_utilization_term();
+#endif
+
+ mali_pp_scheduler_terminate();
+ mali_gp_scheduler_terminate();
+ mali_scheduler_terminate();
+
+ mali_delete_clusters(); /* Delete clusters even if config parsing failed. */
+
+ if (_MALI_PRODUCT_ID_MALI450 == global_product_id)
+ {
+ mali_dlbu_terminate();
+ }
+
+ mali_mmu_terminate();
+
+ pmu = mali_pmu_get_global_pmu_core();
+ if (NULL != pmu)
+ {
+ mali_pmu_delete(pmu);
+ }
+
+ mali_pm_terminate();
+
+ mali_memory_terminate();
+
+ _mali_osk_resources_term(&arch_configuration, num_resources);
+
+ cleanup_system_info(system_info);
+
+#if MALI_TIMELINE_PROFILING_ENABLED
+ _mali_osk_profiling_term();
+#endif
+
+ mali_session_terminate();
+
+ if (NULL != system_info_lock)
+ {
+ _mali_osk_lock_term( system_info_lock );
+ }
+}
+
+_mali_product_id_t mali_kernel_core_get_product_id(void)
+{
+ return global_product_id;
}
-static void mali_kernel_subsystem_core_cleanup(mali_kernel_subsystem_identifier id)
+void mali_kernel_core_wakeup(void)
{
- _mali_osk_resources_term(&arch_configuration, num_resources);
+ u32 i;
+ u32 glob_num_clusters = mali_cluster_get_glob_num_clusters();
+ struct mali_cluster *cluster;
+
+ for (i = 0; i < glob_num_clusters; i++)
+ {
+ cluster = mali_cluster_get_global_cluster(i);
+ mali_cluster_reset(cluster);
+ }
}
static void cleanup_system_info(_mali_system_info *cleanup)
@@ -373,11 +834,10 @@ static void cleanup_system_info(_mali_system_info *cleanup)
_mali_osk_free(cleanup);
}
+/* Build a dummy system info struct. User space still need this. */
static _mali_osk_errcode_t build_system_info(void)
{
- unsigned int i;
- int err = _MALI_OSK_ERR_FAULT;
- _mali_system_info * new_info, * cleanup;
+ _mali_system_info * new_info;
_mali_core_info * current_core;
_mali_mem_info * current_mem;
u32 new_size = 0;
@@ -387,19 +847,25 @@ static _mali_osk_errcode_t build_system_info(void)
_mali_osk_memset(new_info, 0, sizeof(_mali_system_info));
- /* if an error happens during any of the system_info_fill calls cleanup the new info structs */
- cleanup = new_info;
+ /* fill in the info */
+ new_info->has_mmu = 1;
+ new_info->drivermode = _MALI_DRIVER_MODE_NORMAL;
- /* ask each subsystems to fill in their info */
- for (i = 0; i < SUBSYSTEMS_COUNT; ++i)
+ new_info->core_info = NULL; /* Not used by user space */
+
+ new_info->mem_info = _mali_osk_calloc(1, sizeof(_mali_mem_info));
+ if(NULL == new_info->mem_info)
{
- if (NULL != subsystems[i]->system_info_fill)
- {
- err = subsystems[i]->system_info_fill(new_info);
- if (_MALI_OSK_ERR_OK != err) goto error_exit;
- }
+ _mali_osk_free(new_info);
+ return _MALI_OSK_ERR_NOMEM;
}
+ new_info->mem_info->size = 1024 * 1024 * 1024; /* 1GiB */
+ new_info->mem_info->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;
+ new_info->mem_info->maximum_order_supported = 30;
+ new_info->mem_info->identifier = 0;
+ new_info->mem_info->next = NULL;
+
/* building succeeded, calculate the size */
/* size needed of the system info struct itself */
@@ -420,8 +886,6 @@ static _mali_osk_errcode_t build_system_info(void)
/* lock system info access so a user wont't get a corrupted version */
_mali_osk_lock_wait( system_info_lock, _MALI_OSK_LOCKMODE_RW );
- /* cleanup the old one */
- cleanup = system_info;
/* set new info */
system_info = new_info;
system_info_size = new_size;
@@ -430,25 +894,15 @@ static _mali_osk_errcode_t build_system_info(void)
_mali_osk_lock_signal( system_info_lock, _MALI_OSK_LOCKMODE_RW );
/* ok result */
- err = _MALI_OSK_ERR_OK;
-
- /* we share the cleanup routine with the error case */
-error_exit:
- if (NULL == cleanup) MALI_ERROR((_mali_osk_errcode_t)err); /* no cleanup needed, return what err contains */
-
- /* cleanup */
- cleanup_system_info(cleanup);
-
- /* return whatever err is, we could end up here in both the error and success cases */
- MALI_ERROR((_mali_osk_errcode_t)err);
+ return _MALI_OSK_ERR_OK;
}
_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);
+ MALI_DEBUG_ASSERT_POINTER(args);
+ MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS);
- /* check compatability */
+ /* check compatability */
if ( args->version == _MALI_UK_API_VERSION )
{
args->compatible = 1;
@@ -461,14 +915,14 @@ _mali_osk_errcode_t _mali_ukk_get_api_version( _mali_uk_get_api_version_s *args
args->version = _MALI_UK_API_VERSION; /* report our version */
/* success regardless of being compatible or not */
- MALI_SUCCESS;
+ MALI_SUCCESS;
}
_mali_osk_errcode_t _mali_ukk_get_system_info_size(_mali_uk_get_system_info_size_s *args)
{
- MALI_DEBUG_ASSERT_POINTER(args);
- args->size = system_info_size;
- MALI_SUCCESS;
+ MALI_DEBUG_ASSERT_POINTER(args);
+ args->size = system_info_size;
+ MALI_SUCCESS;
}
_mali_osk_errcode_t _mali_ukk_get_system_info( _mali_uk_get_system_info_s *args )
@@ -477,12 +931,12 @@ _mali_osk_errcode_t _mali_ukk_get_system_info( _mali_uk_get_system_info_s *args
_mali_mem_info * current_mem;
_mali_osk_errcode_t err = _MALI_OSK_ERR_FAULT;
void * current_write_pos, ** current_patch_pos;
- u32 adjust_ptr_base;
+ u32 adjust_ptr_base;
/* check input */
MALI_DEBUG_ASSERT_POINTER(args);
- MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS);
- MALI_CHECK_NON_NULL(args->system_info, _MALI_OSK_ERR_INVALID_ARGS);
+ MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS);
+ MALI_CHECK_NON_NULL(args->system_info, _MALI_OSK_ERR_INVALID_ARGS);
/* lock the system info */
_mali_osk_lock_wait( system_info_lock, _MALI_OSK_LOCKMODE_RW );
@@ -491,20 +945,20 @@ _mali_osk_errcode_t _mali_ukk_get_system_info( _mali_uk_get_system_info_s *args
if (args->size < system_info_size) goto exit_when_locked;
/* we build a copy of system_info in the user space buffer specified by the user and
- * patch up the pointers. The ukk_private members of _mali_uk_get_system_info_s may
- * indicate a different base address for patching the pointers (normally the
- * address of the provided system_info buffer would be used). This is helpful when
- * the system_info buffer needs to get copied to user space and the pointers need
- * to be in user space.
- */
- if (0 == args->ukk_private)
- {
- adjust_ptr_base = (u32)args->system_info;
- }
- else
- {
- adjust_ptr_base = args->ukk_private;
- }
+ * patch up the pointers. The ukk_private members of _mali_uk_get_system_info_s may
+ * indicate a different base address for patching the pointers (normally the
+ * address of the provided system_info buffer would be used). This is helpful when
+ * the system_info buffer needs to get copied to user space and the pointers need
+ * to be in user space.
+ */
+ if (0 == args->ukk_private)
+ {
+ adjust_ptr_base = (u32)args->system_info;
+ }
+ else
+ {
+ adjust_ptr_base = args->ukk_private;
+ }
/* copy each struct into the buffer, and update its pointers */
current_write_pos = (void *)args->system_info;
@@ -557,56 +1011,56 @@ _mali_osk_errcode_t _mali_ukk_get_system_info( _mali_uk_get_system_info_s *args
err = _MALI_OSK_ERR_OK;
exit_when_locked:
_mali_osk_lock_signal( system_info_lock, _MALI_OSK_LOCKMODE_RW );
- MALI_ERROR(err);
+ MALI_ERROR(err);
}
_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;
+ _mali_osk_notification_t *notification;
+ _mali_osk_notification_queue_t *queue;
- /* check input */
+ /* check input */
MALI_DEBUG_ASSERT_POINTER(args);
- MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS);
+ MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS);
- queue = (_mali_osk_notification_queue_t *)mali_kernel_session_manager_slot_get(args->ctx, mali_subsystem_core_id);
+ 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;
+ args->type = _MALI_NOTIFICATION_CORE_SHUTDOWN_IN_PROGRESS;
MALI_SUCCESS;
}
- /* receive a notification, might sleep */
+ /* 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 */
- }
+ 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);
+ 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_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;
+ _mali_osk_notification_queue_t *queue;
- /* check input */
+ /* check input */
MALI_DEBUG_ASSERT_POINTER(args);
- MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS);
+ MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS);
- queue = (_mali_osk_notification_queue_t *)mali_kernel_session_manager_slot_get(args->ctx, mali_subsystem_core_id);
+ queue = ((struct mali_session_data *)args->ctx)->ioctl_queue;
/* if the queue does not exist we're currently shutting down */
if (NULL == queue)
@@ -618,294 +1072,115 @@ _mali_osk_errcode_t _mali_ukk_post_notification( _mali_uk_post_notification_s *a
notification = _mali_osk_notification_create(args->type, 0);
if ( NULL == notification)
{
- MALI_PRINT_ERROR( ("Failed to create notification object\n")) ;
+ 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 */
-}
-
-static _mali_osk_errcode_t mali_kernel_subsystem_core_system_info_fill(_mali_system_info* info)
-{
- MALI_CHECK_NON_NULL(info, _MALI_OSK_ERR_INVALID_ARGS);
-
- info->drivermode = _MALI_DRIVER_MODE_NORMAL;
-
- MALI_SUCCESS;
-}
-
-static _mali_osk_errcode_t mali_kernel_subsystem_core_session_begin(struct mali_session_data * mali_session_data, mali_kernel_subsystem_session_slot * slot, _mali_osk_notification_queue_t * queue)
-{
- MALI_CHECK_NON_NULL(slot, _MALI_OSK_ERR_INVALID_ARGS);
- *slot = queue;
- MALI_SUCCESS;
-}
-
-/* MEM_VALIDATION resource handler */
-static _mali_osk_errcode_t mali_kernel_core_resource_mem_validation(_mali_osk_resource_t * resource)
-{
- /* Check that no other MEM_VALIDATION resources exist */
- MALI_CHECK( ((u32)-1) == mem_validator.phys_base, _MALI_OSK_ERR_FAULT );
-
- /* Check restrictions on page alignment */
- MALI_CHECK( 0 == (resource->base & (~_MALI_OSK_CPU_PAGE_MASK)), _MALI_OSK_ERR_FAULT );
- MALI_CHECK( 0 == (resource->size & (~_MALI_OSK_CPU_PAGE_MASK)), _MALI_OSK_ERR_FAULT );
- MALI_CHECK( 0 == (resource->cpu_usage_adjust & (~_MALI_OSK_CPU_PAGE_MASK)), _MALI_OSK_ERR_FAULT );
-
- mem_validator.phys_base = resource->base;
- mem_validator.size = resource->size;
- mem_validator.cpu_usage_adjust = resource->cpu_usage_adjust;
- MALI_DEBUG_PRINT( 2, ("Memory Validator '%s' installed for Mali physical address base==0x%08X, size==0x%08X, cpu_adjust==0x%08X\n",
- resource->description, mem_validator.phys_base, mem_validator.size, mem_validator.cpu_usage_adjust ));
- MALI_SUCCESS;
-}
-
-_mali_osk_errcode_t mali_kernel_core_translate_cpu_to_mali_phys_range( u32 *phys_base, u32 size )
-{
- u32 mali_phys_base;
-
- mali_phys_base = *phys_base - mem_validator.cpu_usage_adjust;
-
- MALI_CHECK( 0 == ( mali_phys_base & (~_MALI_OSK_CPU_PAGE_MASK)), _MALI_OSK_ERR_FAULT );
- MALI_CHECK( 0 == ( size & (~_MALI_OSK_CPU_PAGE_MASK)), _MALI_OSK_ERR_FAULT );
-
- MALI_CHECK_NO_ERROR( mali_kernel_core_validate_mali_phys_range( mali_phys_base, size ) );
-
- *phys_base = mali_phys_base;
- MALI_SUCCESS;
-}
-
-_mali_osk_errcode_t mali_kernel_core_validate_mali_phys_range( u32 phys_base, u32 size )
-{
- MALI_CHECK_GOTO( 0 == ( phys_base & (~_MALI_OSK_CPU_PAGE_MASK)), failure );
- MALI_CHECK_GOTO( 0 == ( size & (~_MALI_OSK_CPU_PAGE_MASK)), failure );
-
- if ( phys_base >= mem_validator.phys_base
- && (phys_base + size) >= mem_validator.phys_base
- && phys_base <= (mem_validator.phys_base + mem_validator.size)
- && (phys_base + size) <= (mem_validator.phys_base + mem_validator.size) )
- {
- MALI_SUCCESS;
- }
-
- failure:
- MALI_PRINTF( ("*******************************************************************************\n") );
- MALI_PRINTF( ("MALI PHYSICAL RANGE VALIDATION ERROR!\n") );
- MALI_PRINTF( ("\n") );
- MALI_PRINTF( ("We failed to validate a Mali-Physical range that the user-side wished to map in\n") );
- MALI_PRINTF( ("\n") );
- MALI_PRINTF( ("It is likely that the user-side wished to do Direct Rendering, but a suitable\n") );
- MALI_PRINTF( ("address range validation mechanism has not been correctly setup\n") );
- MALI_PRINTF( ("\n") );
- MALI_PRINTF( ("The range supplied was: phys_base=0x%08X, size=0x%08X\n", phys_base, size) );
- MALI_PRINTF( ("\n") );
- MALI_PRINTF( ("Please refer to the ARM Mali Software Integration Guide for more information.\n") );
- MALI_PRINTF( ("\n") );
- MALI_PRINTF( ("*******************************************************************************\n") );
-
- MALI_ERROR( _MALI_OSK_ERR_FAULT );
-}
-
-
-_mali_osk_errcode_t _mali_kernel_core_register_resource_handler(_mali_osk_resource_type_t type, mali_kernel_resource_registrator handler)
-{
- MALI_CHECK(type < RESOURCE_TYPE_COUNT, _MALI_OSK_ERR_INVALID_ARGS);
- MALI_DEBUG_ASSERT(NULL == resource_handler[type]); /* A handler for resource already exists */
- resource_handler[type] = handler;
- MALI_SUCCESS;
-}
-
-void * mali_kernel_session_manager_slot_get(struct mali_session_data * session_data, int id)
-{
- MALI_DEBUG_ASSERT_POINTER(session_data);
- if(id >= SUBSYSTEMS_COUNT) { MALI_DEBUG_PRINT(3, ("mali_kernel_session_manager_slot_get: id %d out of range\n", id)); return NULL; }
-
- if (NULL == session_data) { MALI_DEBUG_PRINT(3, ("mali_kernel_session_manager_slot_get: got NULL session data\n")); return NULL; }
- return session_data->subsystem_data[id];
+ MALI_SUCCESS; /* all ok */
}
_mali_osk_errcode_t _mali_ukk_open(void **context)
{
- int i;
- _mali_osk_errcode_t err;
- struct mali_session_data * session_data;
+ struct mali_session_data *session_data;
/* allocated struct to track this session */
- session_data = (struct mali_session_data *)_mali_osk_malloc(sizeof(struct mali_session_data));
- MALI_CHECK_NON_NULL(session_data, _MALI_OSK_ERR_NOMEM);
+ session_data = (struct mali_session_data *)_mali_osk_calloc(1, sizeof(struct mali_session_data));
+ MALI_CHECK_NON_NULL(session_data, _MALI_OSK_ERR_NOMEM);
- _mali_osk_memset(session_data->subsystem_data, 0, sizeof(session_data->subsystem_data));
+ MALI_DEBUG_PRINT(2, ("Session starting\n"));
/* create a response queue for this session */
session_data->ioctl_queue = _mali_osk_notification_queue_init();
if (NULL == session_data->ioctl_queue)
{
_mali_osk_free(session_data);
- MALI_ERROR(_MALI_OSK_ERR_NOMEM);
+ MALI_ERROR(_MALI_OSK_ERR_NOMEM);
}
- MALI_DEBUG_PRINT(3, ("Session starting\n"));
-
- /* call session_begin on all subsystems */
- for (i = 0; i < (int)SUBSYSTEMS_COUNT; ++i)
+ session_data->page_directory = mali_mmu_pagedir_alloc();
+ if (NULL == session_data->page_directory)
{
- if (NULL != subsystems[i]->session_begin)
- {
- /* subsystem has a session_begin */
- err = subsystems[i]->session_begin(session_data, &session_data->subsystem_data[i], session_data->ioctl_queue);
- MALI_CHECK_GOTO(err == _MALI_OSK_ERR_OK, cleanup);
- }
+ _mali_osk_notification_queue_term(session_data->ioctl_queue);
+ _mali_osk_free(session_data);
+ MALI_ERROR(_MALI_OSK_ERR_NOMEM);
}
- *context = (void*)session_data;
+ if (_MALI_OSK_ERR_OK != mali_mmu_pagedir_map(session_data->page_directory, MALI_DLB_VIRT_ADDR, _MALI_OSK_MALI_PAGE_SIZE))
+ {
+ MALI_PRINT_ERROR(("Failed to map DLB page into session\n"));
+ _mali_osk_notification_queue_term(session_data->ioctl_queue);
+ _mali_osk_free(session_data);
+ MALI_ERROR(_MALI_OSK_ERR_NOMEM);
+ }
- MALI_DEBUG_PRINT(3, ("Session started\n"));
- MALI_SUCCESS;
+ if (0 != mali_dlbu_phys_addr)
+ {
+ mali_mmu_pagedir_update(session_data->page_directory, MALI_DLB_VIRT_ADDR, mali_dlbu_phys_addr, _MALI_OSK_MALI_PAGE_SIZE);
+ }
-cleanup:
- MALI_DEBUG_PRINT(2, ("Session startup failed\n"));
- /* i is index of subsystem which failed session begin, all indices before that has to be ended */
- /* end subsystem sessions in the reverse order they where started in */
- for (i = i - 1; i >= 0; --i)
+ if (_MALI_OSK_ERR_OK != mali_memory_session_begin(session_data))
{
- if (NULL != subsystems[i]->session_end) subsystems[i]->session_end(session_data, &session_data->subsystem_data[i]);
+ mali_mmu_pagedir_free(session_data->page_directory);
+ _mali_osk_notification_queue_term(session_data->ioctl_queue);
+ _mali_osk_free(session_data);
+ MALI_ERROR(_MALI_OSK_ERR_NOMEM);
}
- _mali_osk_notification_queue_term(session_data->ioctl_queue);
- _mali_osk_free(session_data);
+ *context = (void*)session_data;
- /* return what the subsystem which failed session start returned */
- MALI_ERROR(err);
+ /* Add session to the list of all sessions. */
+ mali_session_add(session_data);
+
+ MALI_DEBUG_PRINT(3, ("Session started\n"));
+ MALI_SUCCESS;
}
_mali_osk_errcode_t _mali_ukk_close(void **context)
{
- int i;
- struct mali_session_data * session_data;
+ struct mali_session_data *session;
+ MALI_CHECK_NON_NULL(context, _MALI_OSK_ERR_INVALID_ARGS);
+ session = (struct mali_session_data *)*context;
- MALI_CHECK_NON_NULL(context, _MALI_OSK_ERR_INVALID_ARGS);
+ MALI_DEBUG_PRINT(3, ("Session ending\n"));
- session_data = (struct mali_session_data *)*context;
+ /* Remove session from list of all sessions. */
+ mali_session_remove(session);
- MALI_DEBUG_PRINT(2, ("Session ending\n"));
+ /* Abort queued and running jobs */
+ mali_gp_scheduler_abort_session(session);
+ mali_pp_scheduler_abort_session(session);
- /* end subsystem sessions in the reverse order they where started in */
- for (i = SUBSYSTEMS_COUNT - 1; i >= 0; --i)
- {
- if (NULL != subsystems[i]->session_end) subsystems[i]->session_end(session_data, &session_data->subsystem_data[i]);
- }
+ /* 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_flush_workqueue(NULL);
- _mali_osk_notification_queue_term(session_data->ioctl_queue);
- _mali_osk_free(session_data);
+ /* Free remaining memory allocated to this session */
+ mali_memory_session_end(session);
- *context = NULL;
+ /* Free session data structures */
+ mali_mmu_pagedir_free(session->page_directory);
+ _mali_osk_notification_queue_term(session->ioctl_queue);
+ _mali_osk_free(session);
- MALI_DEBUG_PRINT(2, ("Session has ended\n"));
-
- MALI_SUCCESS;
-}
+ *context = NULL;
-#if USING_MALI_PMM
-
-_mali_osk_errcode_t mali_core_signal_power_up( mali_pmm_core_id core, mali_bool queue_only )
-{
- switch( core )
- {
- case MALI_PMM_CORE_GP:
- MALI_CHECK_NO_ERROR(maligp_signal_power_up(queue_only));
- break;
-#if defined USING_MALI400_L2_CACHE
- case MALI_PMM_CORE_L2:
- if( !queue_only )
- {
- /* Enable L2 cache due to power up */
- mali_kernel_l2_cache_do_enable();
+ MALI_DEBUG_PRINT(2, ("Session has ended\n"));
- /* Invalidate the cache on power up */
- MALI_DEBUG_PRINT(5, ("L2 Cache: Invalidate all\n"));
- MALI_CHECK_NO_ERROR(mali_kernel_l2_cache_invalidate_all());
- }
- break;
-#endif
- case MALI_PMM_CORE_PP0:
- MALI_CHECK_NO_ERROR(malipp_signal_power_up(0, queue_only));
- break;
- case MALI_PMM_CORE_PP1:
- MALI_CHECK_NO_ERROR(malipp_signal_power_up(1, queue_only));
- break;
- case MALI_PMM_CORE_PP2:
- MALI_CHECK_NO_ERROR(malipp_signal_power_up(2, queue_only));
- break;
- case MALI_PMM_CORE_PP3:
- MALI_CHECK_NO_ERROR(malipp_signal_power_up(3, queue_only));
- break;
- default:
- /* Unknown core */
- MALI_DEBUG_PRINT_ERROR( ("Unknown core signalled with power up: %d\n", core) );
- MALI_ERROR( _MALI_OSK_ERR_INVALID_ARGS );
- }
-
- MALI_SUCCESS;
-}
-
-_mali_osk_errcode_t mali_core_signal_power_down( mali_pmm_core_id core, mali_bool immediate_only )
-{
- switch( core )
- {
- case MALI_PMM_CORE_GP:
- MALI_CHECK_NO_ERROR(maligp_signal_power_down(immediate_only));
- break;
-#if defined USING_MALI400_L2_CACHE
- case MALI_PMM_CORE_L2:
- /* Nothing to do */
- break;
-#endif
- case MALI_PMM_CORE_PP0:
- MALI_CHECK_NO_ERROR(malipp_signal_power_down(0, immediate_only));
- break;
- case MALI_PMM_CORE_PP1:
- MALI_CHECK_NO_ERROR(malipp_signal_power_down(1, immediate_only));
- break;
- case MALI_PMM_CORE_PP2:
- MALI_CHECK_NO_ERROR(malipp_signal_power_down(2, immediate_only));
- break;
- case MALI_PMM_CORE_PP3:
- MALI_CHECK_NO_ERROR(malipp_signal_power_down(3, immediate_only));
- break;
- default:
- /* Unknown core */
- MALI_DEBUG_PRINT_ERROR( ("Unknown core signalled with power down: %d\n", core) );
- MALI_ERROR( _MALI_OSK_ERR_INVALID_ARGS );
- }
-
MALI_SUCCESS;
}
-#endif
-
-
#if MALI_STATE_TRACKING
u32 _mali_kernel_core_dump_state(char* buf, u32 size)
{
- int i, n;
- char *original_buf = buf;
- for (i = 0; i < SUBSYSTEMS_COUNT; ++i)
- {
- if (NULL != subsystems[i]->dump_state)
- {
- n = subsystems[i]->dump_state(buf, size);
- size -= n;
- buf += n;
- }
- }
-#if USING_MALI_PMM
- n = mali_pmm_dump_os_thread_state(buf, size);
- size -= n;
- buf += n;
-#endif
- /* Return number of bytes written to buf */
- return (u32)(buf - original_buf);
+ 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/media/video/samsung/mali/common/mali_kernel_core.h b/drivers/media/video/samsung/mali/common/mali_kernel_core.h
index 715c1cd..d424c48 100644
--- a/drivers/media/video/samsung/mali/common/mali_kernel_core.h
+++ b/drivers/media/video/samsung/mali/common/mali_kernel_core.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 ARM Limited. All rights reserved.
+ * 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.
@@ -13,122 +13,27 @@
#include "mali_osk.h"
-#if USING_MALI_PMM
-#include "mali_ukk.h"
-#include "mali_pmm.h"
-#include "mali_pmm_system.h"
-#endif
+extern int mali_hang_check_interval;
+extern int mali_max_job_runtime;
-_mali_osk_errcode_t mali_kernel_constructor( void );
-void mali_kernel_destructor( void );
+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;
-/**
- * @brief Tranlate CPU physical to Mali physical addresses.
- *
- * This function is used to convert CPU physical addresses to Mali Physical
- * addresses, such that _mali_ukk_map_external_mem may be used to map them
- * into Mali. This will be used by _mali_ukk_va_to_mali_pa.
- *
- * This function only supports physically contiguous regions.
- *
- * A default implementation is provided, which uses a registered MEM_VALIDATION
- * resource to do a static translation. Only an address range which will lie
- * in the range specified by MEM_VALIDATION will be successfully translated.
- *
- * If a more complex, or non-static translation is required, then the
- * implementor has the following options:
- * - Rewrite this function to provide such a translation
- * - Integrate the provider of the memory with UMP.
- *
- * @param[in,out] phys_base pointer to the page-aligned base address of the
- * physical range to be translated
- *
- * @param[in] size size of the address range to be translated, which must be a
- * multiple of the physical page size.
- *
- * @return on success, _MALI_OSK_ERR_OK and *phys_base is translated. If the
- * cpu physical address range is not in the valid range, then a suitable
- * _mali_osk_errcode_t error.
- *
- */
-_mali_osk_errcode_t mali_kernel_core_translate_cpu_to_mali_phys_range( u32 *phys_base, u32 size );
-
-
-/**
- * @brief Validate a Mali physical address range.
- *
- * This function is used to ensure that an address range passed to
- * _mali_ukk_map_external_mem is allowed to be mapped into Mali.
- *
- * This function only supports physically contiguous regions.
- *
- * A default implementation is provided, which uses a registered MEM_VALIDATION
- * resource to do a static translation. Only an address range which will lie
- * in the range specified by MEM_VALIDATION will be successfully validated.
- *
- * If a more complex, or non-static validation is required, then the
- * implementor has the following options:
- * - Rewrite this function to provide such a validation
- * - Integrate the provider of the memory with UMP.
- *
- * @param phys_base page-aligned base address of the Mali physical range to be
- * validated.
- *
- * @param size size of the address range to be validated, which must be a
- * multiple of the physical page size.
- *
- * @return _MALI_OSK_ERR_OK if the Mali physical range is valid. Otherwise, a
- * suitable _mali_osk_errcode_t error.
- *
- */
-_mali_osk_errcode_t mali_kernel_core_validate_mali_phys_range( u32 phys_base, u32 size );
+_mali_osk_errcode_t mali_initialize_subsystems(void);
-#if USING_MALI_PMM
-/**
- * @brief Signal a power up on a Mali core.
- *
- * This function flags a core as powered up.
- * For PP and GP cores it calls functions that move the core from a power off
- * queue into the idle queue ready to run jobs. It also tries to schedule any
- * pending jobs to run on it.
- *
- * This function will fail if the core is not powered off - either running or
- * already idle.
- *
- * @param core The PMM core id to power up.
- * @param queue_only When MALI_TRUE only re-queue the core - do not reset.
- *
- * @return _MALI_OSK_ERR_OK if the core has been powered up. Otherwise a
- * suitable _mali_osk_errcode_t error.
- */
-_mali_osk_errcode_t mali_core_signal_power_up( mali_pmm_core_id core, mali_bool queue_only );
-
-/**
- * @brief Signal a power down on a Mali core.
- *
- * This function flags a core as powered down.
- * For PP and GP cores it calls functions that move the core from an idle
- * queue into the power off queue.
- *
- * This function will fail if the core is not idle - either running or
- * already powered down.
- *
- * @param core The PMM core id to power up.
- * @param immediate_only Do not set the core to pending power down if it can't
- * power down immediately
- *
- * @return _MALI_OSK_ERR_OK if the core has been powered up. Otherwise a
- * suitable _mali_osk_errcode_t error.
- */
-_mali_osk_errcode_t mali_core_signal_power_down( mali_pmm_core_id core, mali_bool immediate_only );
+void mali_terminate_subsystems(void);
-#endif
+void mali_kernel_core_wakeup(void);
-/**
- * Flag to indicate whether or not mali_benchmark is turned on.
- */
-extern int mali_benchmark;
+_mali_product_id_t mali_kernel_core_get_product_id(void);
+u32 _mali_kernel_core_dump_state(char* buf, u32 size);
#endif /* __MALI_KERNEL_CORE_H__ */
diff --git a/drivers/media/video/samsung/mali/common/mali_kernel_descriptor_mapping.c b/drivers/media/video/samsung/mali/common/mali_kernel_descriptor_mapping.c
index 8b2a97d..b9f05ca 100644
--- a/drivers/media/video/samsung/mali/common/mali_kernel_descriptor_mapping.c
+++ b/drivers/media/video/samsung/mali/common/mali_kernel_descriptor_mapping.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 ARM Limited. All rights reserved.
+ * 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.
@@ -40,11 +40,7 @@ mali_descriptor_mapping * mali_descriptor_mapping_create(int init_entries, int m
map->table = descriptor_table_alloc(init_entries);
if (NULL != map->table)
{
-#if !USING_MMU
- map->lock = _mali_osk_lock_init( (_mali_osk_lock_flags_t)(_MALI_OSK_LOCKFLAG_ORDERED | _MALI_OSK_LOCKFLAG_READERWRITER | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE), 0, 20);
-#else
- map->lock = _mali_osk_lock_init( (_mali_osk_lock_flags_t)(_MALI_OSK_LOCKFLAG_ORDERED | _MALI_OSK_LOCKFLAG_READERWRITER | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE), 0, 116);
-#endif
+ 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 */
@@ -151,15 +147,20 @@ _mali_osk_errcode_t mali_descriptor_mapping_set(mali_descriptor_mapping * map, i
MALI_ERROR(result);
}
-void mali_descriptor_mapping_free(mali_descriptor_mapping * map, int descriptor)
+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)
diff --git a/drivers/media/video/samsung/mali/common/mali_kernel_descriptor_mapping.h b/drivers/media/video/samsung/mali/common/mali_kernel_descriptor_mapping.h
index 745be92..82ed94d 100644
--- a/drivers/media/video/samsung/mali/common/mali_kernel_descriptor_mapping.h
+++ b/drivers/media/video/samsung/mali/common/mali_kernel_descriptor_mapping.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 ARM Limited. All rights reserved.
+ * 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.
@@ -93,7 +93,9 @@ void mali_descriptor_mapping_call_for_each(mali_descriptor_mapping * map, void (
* 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);
+void *mali_descriptor_mapping_free(mali_descriptor_mapping * map, int descriptor);
#endif /* __MALI_KERNEL_DESCRIPTOR_MAPPING_H__ */
diff --git a/drivers/media/video/samsung/mali/common/mali_kernel_l2_cache.c b/drivers/media/video/samsung/mali/common/mali_kernel_l2_cache.c
deleted file mode 100644
index e4d4ab1..0000000
--- a/drivers/media/video/samsung/mali/common/mali_kernel_l2_cache.c
+++ /dev/null
@@ -1,517 +0,0 @@
-/*
- * 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 "mali_kernel_common.h"
-#include "mali_osk.h"
-#include "mali_osk_list.h"
-
-#include "mali_kernel_core.h"
-#include "mali_kernel_pp.h"
-#include "mali_kernel_subsystem.h"
-#include "regs/mali_200_regs.h"
-#include "mali_kernel_rendercore.h"
-#include "mali_kernel_l2_cache.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 = 0x0002,
- /*unused = 0x0003 */
- MALI400_L2_CACHE_REGISTER_COMMAND = 0x0004, /**< Misc cache commands, e.g. clear */
- MALI400_L2_CACHE_REGISTER_CLEAR_PAGE = 0x0005,
- MALI400_L2_CACHE_REGISTER_MAX_READS = 0x0006, /**< Limit of outstanding read requests */
- MALI400_L2_CACHE_REGISTER_ENABLE = 0x0007, /**< Enable misc cache features */
- MALI400_L2_CACHE_REGISTER_PERFCNT_SRC0 = 0x0008,
- MALI400_L2_CACHE_REGISTER_PERFCNT_VAL0 = 0x0009,
- MALI400_L2_CACHE_REGISTER_PERFCNT_SRC1 = 0x000A,
- MALI400_L2_CACHE_REGISTER_PERFCNT_VAL1 = 0x000B,
-} 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;
-
-
-/**
- * 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
- */
-typedef struct mali_kernel_l2_cache_core
-{
- unsigned long base; /**< Physical address of the registers */
- mali_io_address mapped_registers; /**< Virtual mapping of the registers */
- u32 mapping_size; /**< Size of registers in bytes */
- _mali_osk_list_t list; /**< Used to link multiple cache cores into a list */
- _mali_osk_lock_t *lock; /**< Serialize all L2 cache commands */
-} mali_kernel_l2_cache_core;
-
-
-#define MALI400_L2_MAX_READS_DEFAULT 0x1C
-
-int mali_l2_max_reads = MALI400_L2_MAX_READS_DEFAULT;
-
-
-/**
- * Mali L2 cache subsystem startup function
- * Called by the driver core when the driver is loaded.
- *
- * @param id Identifier assigned by the core to the L2 cache subsystem
- * @return 0 on success, negative on error
- */
-static _mali_osk_errcode_t mali_l2_cache_initialize(mali_kernel_subsystem_identifier id);
-
-/**
- * Mali L2 cache subsystem shutdown function
- * Called by the driver core when the driver is unloaded.
- * Cleans up
- * @param id Identifier assigned by the core to the L2 cache subsystem
- */
-static void mali_l2_cache_terminate(mali_kernel_subsystem_identifier id);
-
-/**
- * L2 cache subsystem complete notification function.
- * Called by the driver core when all drivers have loaded and all resources has been registered
- * @param id Identifier assigned by the core to the L2 cache subsystem
- * @return 0 on success, negative on error
- */
-static _mali_osk_errcode_t mali_l2_cache_load_complete(mali_kernel_subsystem_identifier id);
-
-/**
- * Mali L2 cache subsystem's notification handler for a Mali L2 cache resource instances.
- * Registered with the core during startup.
- * Called by the core for each Mali L2 cache described in the active architecture's config.h file.
- * @param resource The resource to handle (type MALI400L2)
- * @return 0 if the Mali L2 cache was found and initialized, negative on error
- */
-static _mali_osk_errcode_t mali_l2_cache_core_create(_mali_osk_resource_t * resource);
-
-/**
- * Write to a L2 cache register
- * Writes the given value to the specified register
- * @param unit The L2 cache to write to
- * @param reg The register to write to
- * @param val The value to write to the register
- */
-static void mali_l2_cache_register_write(mali_kernel_l2_cache_core * unit, mali_l2_cache_register reg, u32 val);
-
-
-
-/**
- * Invalidate specified L2 cache
- * @param cache The L2 cache to invalidate
- * @return 0 if Mali L2 cache was successfully invalidated, otherwise error
- */
-static _mali_osk_errcode_t mali_kernel_l2_cache_invalidate_all_cache(mali_kernel_l2_cache_core *cache);
-
-
-/*
- The fixed Mali L2 cache system's mali subsystem interface implementation.
- We currently handle module and session life-time management.
-*/
-struct mali_kernel_subsystem mali_subsystem_l2_cache =
-{
- mali_l2_cache_initialize, /**< startup */
- NULL, /*mali_l2_cache_terminate,*/ /**< shutdown */
- mali_l2_cache_load_complete, /**< load_complete */
- NULL, /**< system_info_fill */
- NULL, /**< session_begin */
- NULL, /**< session_end */
- NULL, /**< broadcast_notification */
-#if MALI_STATE_TRACKING
- NULL, /**< dump_state */
-#endif
-};
-
-
-
-static _MALI_OSK_LIST_HEAD(caches_head);
-
-
-
-
-/* called during module init */
-static _mali_osk_errcode_t mali_l2_cache_initialize(mali_kernel_subsystem_identifier id)
-{
- _mali_osk_errcode_t err;
-
- MALI_IGNORE( id );
-
- MALI_DEBUG_PRINT(2, ( "Mali L2 cache system initializing\n"));
-
- _MALI_OSK_INIT_LIST_HEAD(&caches_head);
-
- /* This will register the function for adding Mali L2 cache cores to the subsystem */
- err = _mali_kernel_core_register_resource_handler(MALI400L2, mali_l2_cache_core_create);
-
- MALI_ERROR(err);
-}
-
-
-
-/* called if/when our module is unloaded */
-static void mali_l2_cache_terminate(mali_kernel_subsystem_identifier id)
-{
- mali_kernel_l2_cache_core * cache, *temp_cache;
-
- MALI_DEBUG_PRINT(2, ( "Mali L2 cache system terminating\n"));
-
- /* loop over all L2 cache units and shut them down */
- _MALI_OSK_LIST_FOREACHENTRY( cache, temp_cache, &caches_head, mali_kernel_l2_cache_core, list )
- {
- /* reset to defaults */
- mali_l2_cache_register_write(cache, MALI400_L2_CACHE_REGISTER_MAX_READS, (u32)MALI400_L2_MAX_READS_DEFAULT);
- mali_l2_cache_register_write(cache, MALI400_L2_CACHE_REGISTER_ENABLE, (u32)MALI400_L2_CACHE_ENABLE_DEFAULT);
-
- /* remove from the list of cacges on the system */
- _mali_osk_list_del( &cache->list );
-
- /* release resources */
- _mali_osk_mem_unmapioregion( cache->base, cache->mapping_size, cache->mapped_registers );
- _mali_osk_mem_unreqregion( cache->base, cache->mapping_size );
- _mali_osk_lock_term( cache->lock );
- _mali_osk_free( cache );
-
- #if USING_MALI_PMM
- /* Unregister the L2 cache with the PMM */
- malipmm_core_unregister( MALI_PMM_CORE_L2 );
- #endif
- }
-}
-
-static _mali_osk_errcode_t mali_l2_cache_core_create(_mali_osk_resource_t * resource)
-{
- _mali_osk_errcode_t err = _MALI_OSK_ERR_FAULT ;
- mali_kernel_l2_cache_core * cache = NULL;
-
- MALI_DEBUG_PRINT(2, ( "Creating Mali L2 cache: %s\n", resource->description));
-
-#if USING_MALI_PMM
- /* Register the L2 cache with the PMM */
- err = malipmm_core_register( MALI_PMM_CORE_L2 );
- if( _MALI_OSK_ERR_OK != err )
- {
- MALI_DEBUG_PRINT(1, ( "Failed to register L2 cache unit with PMM"));
- return err;
- }
-#endif
-
- err = _mali_osk_mem_reqregion( resource->base, MALI400_L2_CACHE_REGISTERS_SIZE, resource->description);
-
- MALI_CHECK_GOTO( _MALI_OSK_ERR_OK == err, err_cleanup_requestmem_failed);
-
- /* Reset error that might be passed out */
- err = _MALI_OSK_ERR_FAULT;
-
- cache = _mali_osk_malloc(sizeof(mali_kernel_l2_cache_core));
-
- MALI_CHECK_GOTO( NULL != cache, err_cleanup);
-
- cache->lock = _mali_osk_lock_init( _MALI_OSK_LOCKFLAG_ORDERED | _MALI_OSK_LOCKFLAG_SPINLOCK | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE, 0, 104 );
-
- MALI_CHECK_GOTO( NULL != cache->lock, err_cleanup);
-
- /* basic setup */
- _MALI_OSK_INIT_LIST_HEAD(&cache->list);
-
- cache->base = resource->base;
- cache->mapping_size = MALI400_L2_CACHE_REGISTERS_SIZE;
-
- /* map the registers */
- cache->mapped_registers = _mali_osk_mem_mapioregion( cache->base, cache->mapping_size, resource->description );
-
- MALI_CHECK_GOTO( NULL != cache->mapped_registers, err_cleanup);
-
- /* Invalidate cache (just to keep it in a known state at startup) */
- err = mali_kernel_l2_cache_invalidate_all_cache(cache);
-
- MALI_CHECK_GOTO( _MALI_OSK_ERR_OK == err, err_cleanup);
-
- /* add to our list of L2 caches */
- _mali_osk_list_add( &cache->list, &caches_head );
-
- MALI_SUCCESS;
-
-err_cleanup:
- /* This cleanup used when resources have been requested successfully */
-
- if ( NULL != cache )
- {
- if (NULL != cache->mapped_registers)
- {
- _mali_osk_mem_unmapioregion( cache->base, cache->mapping_size, cache->mapped_registers);
- }
- else
- {
- MALI_DEBUG_PRINT(1, ( "Failed to map Mali L2 cache registers at 0x%08lX\n", cache->base));
- }
-
- if( NULL != cache->lock )
- {
- _mali_osk_lock_term( cache->lock );
- }
- else
- {
- MALI_DEBUG_PRINT(1, ( "Failed to allocate a lock for handling a L2 cache unit"));
- }
-
- _mali_osk_free( cache );
- }
- else
- {
- MALI_DEBUG_PRINT(1, ( "Failed to allocate memory for handling a L2 cache unit"));
- }
-
- /* A call is to request region, so this must always be reversed */
- _mali_osk_mem_unreqregion( resource->base, MALI400_L2_CACHE_REGISTERS_SIZE);
-#if USING_MALI_PMM
- malipmm_core_unregister( MALI_PMM_CORE_L2 );
-#endif
- return err;
-
-err_cleanup_requestmem_failed:
- MALI_DEBUG_PRINT(1, ("Failed to request Mali L2 cache '%s' register address space at (0x%08X - 0x%08X)\n",
- resource->description, resource->base, resource->base + MALI400_L2_CACHE_REGISTERS_SIZE - 1) );
-#if USING_MALI_PMM
- malipmm_core_unregister( MALI_PMM_CORE_L2 );
-#endif
- return err;
-
-}
-
-
-static void mali_l2_cache_register_write(mali_kernel_l2_cache_core * unit, mali_l2_cache_register reg, u32 val)
-{
- _mali_osk_mem_iowrite32(unit->mapped_registers, (u32)reg * sizeof(u32), val);
-}
-
-
-static u32 mali_l2_cache_register_read(mali_kernel_l2_cache_core * unit, mali_l2_cache_register reg)
-{
- return _mali_osk_mem_ioread32(unit->mapped_registers, (u32)reg * sizeof(u32));
-}
-
-void mali_kernel_l2_cache_do_enable(void)
-{
- mali_kernel_l2_cache_core * cache, *temp_cache;
-
- /* loop over all L2 cache units and enable them*/
- _MALI_OSK_LIST_FOREACHENTRY( cache, temp_cache, &caches_head, mali_kernel_l2_cache_core, list)
- {
- mali_l2_cache_register_write(cache, MALI400_L2_CACHE_REGISTER_ENABLE, (u32)MALI400_L2_CACHE_ENABLE_ACCESS | (u32)MALI400_L2_CACHE_ENABLE_READ_ALLOCATE);
- mali_l2_cache_register_write(cache, MALI400_L2_CACHE_REGISTER_MAX_READS, (u32)mali_l2_max_reads);
- }
-}
-
-
-static _mali_osk_errcode_t mali_l2_cache_load_complete(mali_kernel_subsystem_identifier id)
-{
- mali_kernel_l2_cache_do_enable();
- MALI_DEBUG_PRINT(2, ( "Mali L2 cache system load complete\n"));
-
- MALI_SUCCESS;
-}
-
-static _mali_osk_errcode_t mali_kernel_l2_cache_send_command(mali_kernel_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->lock, _MALI_OSK_LOCKMODE_RW);
-
- /* First, wait for L2 cache command handler to go idle */
-
- for (i = 0; i < loop_count; i++)
- {
- if (!(_mali_osk_mem_ioread32(cache->mapped_registers , (u32)MALI400_L2_CACHE_REGISTER_STATUS * sizeof(u32)) & (u32)MALI400_L2_CACHE_STATUS_COMMAND_BUSY))
- {
- break;
- }
- }
-
- if (i == loop_count)
- {
- _mali_osk_lock_signal(cache->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_l2_cache_register_write(cache, reg, val);
-
- _mali_osk_lock_signal(cache->lock, _MALI_OSK_LOCKMODE_RW);
- MALI_SUCCESS;
-}
-
-
-static _mali_osk_errcode_t mali_kernel_l2_cache_invalidate_all_cache(mali_kernel_l2_cache_core *cache)
-{
- return mali_kernel_l2_cache_send_command(cache, MALI400_L2_CACHE_REGISTER_COMMAND, MALI400_L2_CACHE_COMMAND_CLEAR_ALL);
-}
-
-_mali_osk_errcode_t mali_kernel_l2_cache_invalidate_all(void)
-{
- mali_kernel_l2_cache_core * cache, *temp_cache;
-
- /* loop over all L2 cache units and invalidate them */
-
- _MALI_OSK_LIST_FOREACHENTRY( cache, temp_cache, &caches_head, mali_kernel_l2_cache_core, list)
- {
- MALI_CHECK_NO_ERROR( mali_kernel_l2_cache_invalidate_all_cache(cache) );
- }
-
- MALI_SUCCESS;
-}
-
-
-static _mali_osk_errcode_t mali_kernel_l2_cache_invalidate_page_cache(mali_kernel_l2_cache_core *cache, u32 page)
-{
- return mali_kernel_l2_cache_send_command(cache, MALI400_L2_CACHE_REGISTER_CLEAR_PAGE, page);
-}
-
-_mali_osk_errcode_t mali_kernel_l2_cache_invalidate_page(u32 page)
-{
- mali_kernel_l2_cache_core * cache, *temp_cache;
-
- /* loop over all L2 cache units and invalidate them */
-
- _MALI_OSK_LIST_FOREACHENTRY( cache, temp_cache, &caches_head, mali_kernel_l2_cache_core, list)
- {
- MALI_CHECK_NO_ERROR( mali_kernel_l2_cache_invalidate_page_cache(cache, page) );
- }
-
- MALI_SUCCESS;
-}
-
-
-void mali_kernel_l2_cache_set_perf_counters(u32 src0, u32 src1, int force_reset)
-{
- mali_kernel_l2_cache_core * cache, *temp_cache;
- int reset0 = force_reset;
- int reset1 = force_reset;
- MALI_DEBUG_CODE(
- int changed0 = 0;
- int changed1 = 0;
- )
-
- /* loop over all L2 cache units and activate the counters on them */
- _MALI_OSK_LIST_FOREACHENTRY(cache, temp_cache, &caches_head, mali_kernel_l2_cache_core, list)
- {
- u32 cur_src0 = mali_l2_cache_register_read(cache, MALI400_L2_CACHE_REGISTER_PERFCNT_SRC0);
- u32 cur_src1 = mali_l2_cache_register_read(cache, MALI400_L2_CACHE_REGISTER_PERFCNT_SRC1);
-
- if (src0 != cur_src0)
- {
- mali_l2_cache_register_write(cache, MALI400_L2_CACHE_REGISTER_PERFCNT_SRC0, src0);
- MALI_DEBUG_CODE(changed0 = 1;)
- reset0 = 1;
- }
-
- if (src1 != cur_src1)
- {
- mali_l2_cache_register_write(cache, MALI400_L2_CACHE_REGISTER_PERFCNT_SRC1, src1);
- MALI_DEBUG_CODE(changed1 = 1;)
- reset1 = 1;
- }
-
- if (reset0)
- {
- mali_l2_cache_register_write(cache, MALI400_L2_CACHE_REGISTER_PERFCNT_VAL0, 0);
- }
-
- if (reset1)
- {
- mali_l2_cache_register_write(cache, MALI400_L2_CACHE_REGISTER_PERFCNT_VAL1, 0);
- }
-
- MALI_DEBUG_PRINT(5, ("L2 cache counters set: SRC0=%u, CHANGED0=%d, RESET0=%d, SRC1=%u, CHANGED1=%d, RESET1=%d\n",
- src0, changed0, reset0,
- src1, changed1, reset1));
- }
-}
-
-
-void mali_kernel_l2_cache_get_perf_counters(u32 *src0, u32 *val0, u32 *src1, u32 *val1)
-{
- mali_kernel_l2_cache_core * cache, *temp_cache;
- int first_time = 1;
- *src0 = 0;
- *src1 = 0;
- *val0 = 0;
- *val1 = 0;
-
- /* loop over all L2 cache units and read the counters */
- _MALI_OSK_LIST_FOREACHENTRY(cache, temp_cache, &caches_head, mali_kernel_l2_cache_core, list)
- {
- u32 cur_src0 = mali_l2_cache_register_read(cache, MALI400_L2_CACHE_REGISTER_PERFCNT_SRC0);
- u32 cur_src1 = mali_l2_cache_register_read(cache, MALI400_L2_CACHE_REGISTER_PERFCNT_SRC1);
- u32 cur_val0 = mali_l2_cache_register_read(cache, MALI400_L2_CACHE_REGISTER_PERFCNT_VAL0);
- u32 cur_val1 = mali_l2_cache_register_read(cache, MALI400_L2_CACHE_REGISTER_PERFCNT_VAL1);
-
- MALI_DEBUG_PRINT(5, ("L2 cache counters get: SRC0=%u, VAL0=%u, SRC1=%u, VAL1=%u\n", cur_src0, cur_val0, cur_src1, cur_val1));
-
- /* Only update the counter source once, with the value from the first L2 cache unit. */
- if (first_time)
- {
- *src0 = cur_src0;
- *src1 = cur_src1;
- first_time = 0;
- }
-
- /* Bail out if the L2 cache units have different counters set. */
- if (*src0 == cur_src0 && *src1 == cur_src1)
- {
- *val0 += cur_val0;
- *val1 += cur_val1;
- }
- else
- {
- MALI_DEBUG_PRINT(1, ("Warning: Mali L2 caches has different performance counters set, not retrieving data\n"));
- }
- }
-}
diff --git a/drivers/media/video/samsung/mali/common/mali_kernel_l2_cache.h b/drivers/media/video/samsung/mali/common/mali_kernel_l2_cache.h
deleted file mode 100644
index 8c12b50..0000000
--- a/drivers/media/video/samsung/mali/common/mali_kernel_l2_cache.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * 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_L2_CACHE_H__
-#define __MALI_KERNEL_L2_CACHE_H__
-
-#include "mali_osk.h"
-#include "mali_kernel_subsystem.h"
-extern struct mali_kernel_subsystem mali_subsystem_l2_cache;
-
-_mali_osk_errcode_t mali_kernel_l2_cache_invalidate_all(void);
-_mali_osk_errcode_t mali_kernel_l2_cache_invalidate_page(u32 page);
-
-void mali_kernel_l2_cache_do_enable(void);
-void mali_kernel_l2_cache_set_perf_counters(u32 src0, u32 src1, int force_reset);
-void mali_kernel_l2_cache_get_perf_counters(u32 *src0, u32 *val0, u32 *src1, u32 *val1);
-
-#endif /* __MALI_KERNEL_L2_CACHE_H__ */
diff --git a/drivers/media/video/samsung/mali/common/mali_kernel_mem_buddy.c b/drivers/media/video/samsung/mali/common/mali_kernel_mem_buddy.c
deleted file mode 100644
index e378f03..0000000
--- a/drivers/media/video/samsung/mali/common/mali_kernel_mem_buddy.c
+++ /dev/null
@@ -1,1427 +0,0 @@
-/*
- * 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 "mali_kernel_core.h"
-#include "mali_kernel_subsystem.h"
-#include "mali_kernel_mem.h"
-#include "mali_kernel_descriptor_mapping.h"
-#include "mali_kernel_session_manager.h"
-
-/* kernel side OS functions and user-kernel interface */
-#include "mali_osk.h"
-#include "mali_osk_mali.h"
-#include "mali_osk_list.h"
-#include "mali_ukk.h"
-
-#ifdef _MALI_OSK_SPECIFIC_INDIRECT_MMAP
-#include "mali_osk_indir_mmap.h"
-#endif
-
-#error Support for non-MMU builds is no longer supported and is planned for removal.
-
-/**
- * Minimum memory allocation size
- */
-#define MIN_BLOCK_SIZE (1024*1024UL)
-
-/**
- * Per-session memory descriptor mapping table sizes
- */
-#define MALI_MEM_DESCRIPTORS_INIT 64
-#define MALI_MEM_DESCRIPTORS_MAX 4096
-
-/**
- * Enum uses to store multiple fields in one u32 to keep the memory block struct small
- */
-enum MISC_SHIFT { MISC_SHIFT_FREE = 0, MISC_SHIFT_ORDER = 1, MISC_SHIFT_TOPLEVEL = 6 };
-enum MISC_MASK { MISC_MASK_FREE = 0x01, MISC_MASK_ORDER = 0x1F, MISC_MASK_TOPLEVEL = 0x1F };
-
-/* forward declaration of the block struct */
-struct mali_memory_block;
-
-/**
- * Definition of memory bank type.
- * Represents a memory bank (separate address space)
- * Each bank keeps track of its block usage.
- * A buddy system used to track the usage
-*/
-typedef struct mali_memory_bank
-{
- _mali_osk_list_t list; /* links multiple banks together */
- _mali_osk_lock_t *lock;
- u32 base_addr; /* Mali seen address of bank */
- u32 cpu_usage_adjust; /* Adjustment factor for what the CPU sees */
- u32 size; /* the effective size */
- u32 real_size; /* the real size of the bank, as given by to the subsystem */
- int min_order;
- int max_order;
- struct mali_memory_block * blocklist;
- _mali_osk_list_t *freelist;
- _mali_osk_atomic_t num_active_allocations;
- u32 used_for_flags;
- u32 alloc_order; /**< Order in which the bank will be used for allocations */
- const char *name; /**< Descriptive name of the bank */
-} mali_memory_bank;
-
-/**
- * Definition of the memory block type
- * Represents a memory block, which is the smallest memory unit operated on.
- * A block keeps info about its mapping, if in use by a user process
- */
-typedef struct mali_memory_block
-{
- _mali_osk_list_t link; /* used for freelist and process usage list*/
- mali_memory_bank * bank; /* the bank it belongs to */
- void __user * mapping; /* possible user space mapping of this block */
- u32 misc; /* used while a block is free to track the number blocks it represents */
- int descriptor;
- u32 mmap_cookie; /**< necessary for interaction with _mali_ukk_mem_mmap/munmap */
-} mali_memory_block;
-
-/**
- * Defintion of the type used to represent memory used by a session.
- * Containts the head of the list of memory currently in use by a session.
- */
-typedef struct memory_session
-{
- _mali_osk_lock_t *lock;
- _mali_osk_list_t memory_head; /* List of the memory blocks used by this session. */
- mali_descriptor_mapping * descriptor_mapping; /**< Mapping between userspace descriptors and our pointers */
-} memory_session;
-
-/*
- Subsystem interface implementation
-*/
-/**
- * Buddy block memory subsystem startup function
- * Called by the driver core when the driver is loaded.
- * Registers the memory systems ioctl handler, resource handlers and memory map function with the core.
- *
- * @param id Identifier assigned by the core to the memory subsystem
- * @return 0 on success, negative on error
- */
-static _mali_osk_errcode_t mali_memory_core_initialize(mali_kernel_subsystem_identifier id);
-
-/**
- * Buddy block memory subsystem shutdown function
- * Called by the driver core when the driver is unloaded.
- * Cleans up
- * @param id Identifier assigned by the core to the memory subsystem
- */
-static void mali_memory_core_terminate(mali_kernel_subsystem_identifier id);
-
-/**
- * Buddy block memory load complete notification function.
- * Called by the driver core when all drivers have loaded and all resources has been registered
- * Reports on the memory resources registered
- * @param id Identifier assigned by the core to the memory subsystem
- * @return 0 on success, negative on error
- */
-static _mali_osk_errcode_t mali_memory_core_load_complete(mali_kernel_subsystem_identifier id);
-
-
-/**
- * Buddy block memory subsystem session begin notification
- * Called by the core when a new session to the driver is started.
- * Creates a memory session object and sets it as the subsystem slot data for this session
- * @param slot Pointer to the slot to use for storing per-session data
- * @param queue The user space event sink
- * @return 0 on success, negative on error
- */
-static _mali_osk_errcode_t mali_memory_core_session_begin(struct mali_session_data * mali_session_data, mali_kernel_subsystem_session_slot * slot, _mali_osk_notification_queue_t * queue);
-
-/**
- * Buddy block memory subsystem session end notification
- * Called by the core when a session to the driver has ended.
- * Cleans up per session data, which includes checking and fixing memory leaks
- *
- * @param slot Pointer to the slot to use for storing per-session data
- */
-static void mali_memory_core_session_end(struct mali_session_data * mali_session_data, mali_kernel_subsystem_session_slot * slot);
-
-/**
- * Buddy block memory subsystem system info filler
- * Called by the core when a system info update is needed
- * We fill in info about all the memory types we have
- * @param info Pointer to system info struct to update
- * @return 0 on success, negative on error
- */
-static _mali_osk_errcode_t mali_memory_core_system_info_fill(_mali_system_info* info);
-
-/* our registered resource handlers */
-/**
- * Buddy block memory subsystem's notification handler for MEMORY resource instances.
- * Registered with the core during startup.
- * Called by the core for each memory bank described in the active architecture's config.h file.
- * Requests memory region ownership and calls backend.
- * @param resource The resource to handle (type MEMORY)
- * @return 0 if the memory was claimed and accepted, negative on error
- */
-static _mali_osk_errcode_t mali_memory_core_resource_memory(_mali_osk_resource_t * resource);
-
-/**
- * Buddy block memory subsystem's notification handler for MMU resource instances.
- * Registered with the core during startup.
- * Called by the core for each mmu described in the active architecture's config.h file.
- * @param resource The resource to handle (type MMU)
- * @return 0 if the MMU was found and initialized, negative on error
- */
-static _mali_osk_errcode_t mali_memory_core_resource_mmu(_mali_osk_resource_t * resource);
-
-/**
- * Buddy block memory subsystem's notification handler for FPGA_FRAMEWORK resource instances.
- * Registered with the core during startup.
- * Called by the core for each fpga framework described in the active architecture's config.h file.
- * @param resource The resource to handle (type FPGA_FRAMEWORK)
- * @return 0 if the FPGA framework was found and initialized, negative on error
- */
-static _mali_osk_errcode_t mali_memory_core_resource_fpga(_mali_osk_resource_t * resource);
-
-/* ioctl command implementations */
-/**
- * Buddy block memory subsystem's handler for MALI_IOC_MEM_GET_BIG_BLOCK ioctl
- * Called by the generic ioctl handler when the MALI_IOC_MEM_GET_BIG_BLOCK command is received.
- * Finds an available memory block and maps into the current process' address space.
- * @param ukk_private private word for use by the User/Kernel interface
- * @param session_data Pointer to the per-session object which will track the memory usage
- * @param argument The argument from the user. A pointer to an struct mali_dd_get_big_block in user space
- * @return Zero if successful, a standard Linux error value value on error (a negative value)
- */
-_mali_osk_errcode_t _mali_ukk_get_big_block( _mali_uk_get_big_block_s *args );
-
-/**
- * Buddy block memory subsystem's handler for MALI_IOC_MEM_FREE_BIG_BLOCK ioctl
- * Called by the generic ioctl handler when the MALI_IOC_MEM_FREE_BIG_BLOCK command is received.
- * Unmaps the memory from the process' address space and marks the block as free.
- * @param session_data Pointer to the per-session object which tracks the memory usage
- * @param argument The argument from the user. A pointer to an struct mali_dd_get_big_block in user space
- * @return Zero if successful, a standard Linux error value value on error (a negative value)
- */
-
-/* this static version allows us to make use of it while holding the memory_session lock.
- * This is required for the session_end code */
-static _mali_osk_errcode_t _mali_ukk_free_big_block_internal( struct mali_session_data * mali_session_data, memory_session * session_data, _mali_uk_free_big_block_s *args);
-
-_mali_osk_errcode_t _mali_ukk_free_big_block( _mali_uk_free_big_block_s *args );
-
-/**
- * Buddy block memory subsystem's memory bank registration routine
- * Called when a MEMORY resource has been found.
- * The memory region has already been reserved for use by this driver.
- * Create a bank object to represent this region and initialize its slots.
- * @note Can only be called in an module atomic scope, i.e. during module init since no locking is performed
- * @param phys_base Physical base address of this bank
- * @param cpu_usage_adjust Adjustment factor for CPU seen address
- * @param size Size of the bank in bytes
- * @param flags Memory type bits
- * @param alloc_order Order in which the bank will be used for allocations
- * @param name descriptive name of the bank
- * @return Zero on success, negative on error
- */
-static int mali_memory_bank_register(u32 phys_base, u32 cpu_usage_adjust, u32 size, u32 flags, u32 alloc_order, const char *name);
-
-/**
- * Get a block of mali memory of at least the given size and of the given type
- * This is the backend for get_big_block.
- * @param type_id The type id of memory requested.
- * @param minimum_size The size requested
- * @return Pointer to a block on success, NULL on failure
- */
-static mali_memory_block * mali_memory_block_get(u32 type_id, u32 minimum_size);
-
-/**
- * Get the mali seen address of the memory described by the block
- * @param block The memory block to return the address of
- * @return The mali seen address of the memory block
- */
-MALI_STATIC_INLINE u32 block_mali_addr_get(mali_memory_block * block);
-
-/**
- * Get the cpu seen address of the memory described by the block
- * The cpu_usage_adjust will be used to change the mali seen phys address
- * @param block The memory block to return the address of
- * @return The mali seen address of the memory block
- */
-MALI_STATIC_INLINE u32 block_cpu_addr_get(mali_memory_block * block);
-
-/**
- * Get the size of the memory described by the given block
- * @param block The memory block to return the size of
- * @return The size of the memory block described by the object
- */
-MALI_STATIC_INLINE u32 block_size_get(mali_memory_block * block);
-
-/**
- * Get the user space accessible mapping the memory described by the given memory block
- * Returns a pointer in user space to the memory, if one has been created.
- * @param block The memory block to return the mapping of
- * @return User space pointer to cpu accessible memory or NULL if not mapped
- */
-MALI_STATIC_INLINE void __user * block_mapping_get(mali_memory_block * block);
-
-/**
- * Set the user space accessible mapping the memory described by the given memory block.
- * Sets the stored pointer to user space for the memory described by this block.
- * @param block The memory block to set mapping info for
- * @param ptr User space pointer to cpu accessible memory or NULL if not mapped
- */
-MALI_STATIC_INLINE void block_mapping_set(mali_memory_block * block, void __user * ptr);
-
-/**
- * Get the cookie for use with _mali_ukk_mem_munmap().
- * @param block The memory block to get the cookie from
- * @return the cookie. A return of 0 is still a valid cookie.
- */
-MALI_STATIC_INLINE u32 block_mmap_cookie_get(mali_memory_block * block);
-
-/**
- * Set the cookie returned via _mali_ukk_mem_mmap().
- * @param block The memory block to set the cookie for
- * @param cookie the cookie
- */
-MALI_STATIC_INLINE void block_mmap_cookie_set(mali_memory_block * block, u32 cookie);
-
-
-/**
- * Get a memory block's free status
- * @param block The block to get the state of
- */
-MALI_STATIC_INLINE u32 get_block_free(mali_memory_block * block);
-
-/**
- * Set a memory block's free status
- * @param block The block to set the state for
- * @param state The state to set
- */
-MALI_STATIC_INLINE void set_block_free(mali_memory_block * block, int state);
-
-/**
- * Set a memory block's order
- * @param block The block to set the order for
- * @param order The order to set
- */
-MALI_STATIC_INLINE void set_block_order(mali_memory_block * block, u32 order);
-
-/**
- * Get a memory block's order
- * @param block The block to get the order for
- * @return The order this block exists on
- */
-MALI_STATIC_INLINE u32 get_block_order(mali_memory_block * block);
-
-/**
- * Tag a block as being a toplevel block.
- * A toplevel block has no buddy and no parent
- * @param block The block to tag as being toplevel
- */
-MALI_STATIC_INLINE void set_block_toplevel(mali_memory_block * block, u32 level);
-
-/**
- * Check if a block is a toplevel block
- * @param block The block to check
- * @return 1 if toplevel, 0 else
- */
-MALI_STATIC_INLINE u32 get_block_toplevel(mali_memory_block * block);
-
-/**
- * Checks if the given block is a buddy at the given order and that it's free
- * @param block The block to check
- * @param order The order to check against
- * @return 0 if not valid, else 1
- */
-MALI_STATIC_INLINE int block_is_valid_buddy(mali_memory_block * block, int order);
-
-/*
- The buddy system uses the following rules to quickly find a blocks buddy
- and parent (block representing this block at a higher order level):
- - Given a block with index i the blocks buddy is at index i ^ ( 1 << order)
- - Given a block with index i the blocks parent is at i & ~(1 << order)
-*/
-
-/**
- * Get a blocks buddy
- * @param block The block to find the buddy for
- * @param order The order to operate on
- * @return Pointer to the buddy block
- */
-MALI_STATIC_INLINE mali_memory_block * block_get_buddy(mali_memory_block * block, u32 order);
-
-/**
- * Get a blocks parent
- * @param block The block to find the parent for
- * @param order The order to operate on
- * @return Pointer to the parent block
- */
-MALI_STATIC_INLINE mali_memory_block * block_get_parent(mali_memory_block * block, u32 order);
-
-/**
- * Release mali memory
- * Backend for free_big_block.
- * Will release the mali memory described by the given block struct.
- * @param block Memory block to free
- */
-static void block_release(mali_memory_block * block);
-
-/* end interface implementation */
-
-/**
- * List of all the memory banks registerd with the subsystem.
- * Access to this list is NOT synchronized since it's only
- * written to during module init and termination.
- */
-static _MALI_OSK_LIST_HEAD(memory_banks_list);
-
-/*
- The buddy memory system's mali subsystem interface implementation.
- We currently handle module and session life-time management.
-*/
-struct mali_kernel_subsystem mali_subsystem_memory =
-{
- mali_memory_core_initialize, /* startup */
- NULL, /*mali_memory_core_terminate,*/ /* shutdown */
- mali_memory_core_load_complete, /* load_complete */
- mali_memory_core_system_info_fill, /* system_info_fill */
- mali_memory_core_session_begin, /* session_begin */
- mali_memory_core_session_end, /* session_end */
- NULL, /* broadcast_notification */
-#if MALI_STATE_TRACKING
- NULL, /* dump_state */
-#endif
-};
-
-/* Initialized when this subsystem is initialized. This is determined by the
- * position in subsystems[], and so the value used to initialize this is
- * determined at compile time */
-static mali_kernel_subsystem_identifier mali_subsystem_memory_id = -1;
-
-/* called during module init */
-static _mali_osk_errcode_t mali_memory_core_initialize(mali_kernel_subsystem_identifier id)
-{
- _MALI_OSK_INIT_LIST_HEAD(&memory_banks_list);
-
- mali_subsystem_memory_id = id;
-
- /* register our handlers */
- MALI_CHECK_NO_ERROR(_mali_kernel_core_register_resource_handler(MEMORY, mali_memory_core_resource_memory));
-
- MALI_CHECK_NO_ERROR(_mali_kernel_core_register_resource_handler(MMU, mali_memory_core_resource_mmu));
-
- MALI_CHECK_NO_ERROR(_mali_kernel_core_register_resource_handler(FPGA_FRAMEWORK, mali_memory_core_resource_fpga));
-
- MALI_SUCCESS;
-}
-
-/* called if/when our module is unloaded */
-static void mali_memory_core_terminate(mali_kernel_subsystem_identifier id)
-{
- mali_memory_bank * bank, *temp;
-
- /* loop over all memory banks to free them */
- /* we use the safe version since we delete the current bank in the body */
- _MALI_OSK_LIST_FOREACHENTRY(bank, temp, &memory_banks_list, mali_memory_bank, list)
- {
- MALI_DEBUG_CODE(int usage_count = _mali_osk_atomic_read(&bank->num_active_allocations));
- /*
- Report leaked memory
- If this happens we have a bug in our session cleanup code.
- */
- MALI_DEBUG_PRINT_IF(1, 0 != usage_count, ("%d allocation(s) from memory bank at 0x%X still in use\n", usage_count, bank->base_addr));
-
- _mali_osk_atomic_term(&bank->num_active_allocations);
-
- _mali_osk_lock_term(bank->lock);
-
- /* unlink from bank list */
- _mali_osk_list_del(&bank->list);
-
- /* release kernel resources used by the bank */
- _mali_osk_mem_unreqregion(bank->base_addr, bank->real_size);
-
- /* remove all resources used to represent this bank*/
- _mali_osk_free(bank->freelist);
- _mali_osk_free(bank->blocklist);
-
- /* destroy the bank object itself */
- _mali_osk_free(bank);
- }
-
- /* No need to de-initialize mali_subsystem_memory_id - it could only be
- * re-initialized to the same value */
-}
-
-/* load_complete handler */
-static _mali_osk_errcode_t mali_memory_core_load_complete(mali_kernel_subsystem_identifier id)
-{
- mali_memory_bank * bank, *temp;
-
- MALI_DEBUG_PRINT( 1, ("Mali memory allocators will be used in this order of preference (lowest number first) :\n"));
-
- _MALI_OSK_LIST_FOREACHENTRY(bank, temp, &memory_banks_list, mali_memory_bank, list)
- {
- if ( NULL != bank->name )
- {
- MALI_DEBUG_PRINT( 1, ("\t%d: %s\n", bank->alloc_order, bank->name) );
- }
- else
- {
- MALI_DEBUG_PRINT( 1, ("\t%d: (UNNAMED ALLOCATOR)\n", bank->alloc_order ) );
- }
- }
- MALI_SUCCESS;
-}
-
-MALI_STATIC_INLINE u32 order_needed_for_size(u32 size, struct mali_memory_bank * bank)
-{
- u32 order = 0;
-
- if (0 < size)
- {
- for ( order = sizeof(u32)*8 - 1; ((1UL<<order) & size) == 0; --order)
- /* nothing */;
-
- /* check if size is pow2, if not we need increment order by one */
- if (0 != (size & ((1UL<<order)-1))) ++order;
- }
-
- if ((NULL != bank) && (order < bank->min_order)) order = bank->min_order;
- /* Not capped to max order, that doesn't make sense */
-
- return order;
-}
-
-MALI_STATIC_INLINE u32 maximum_order_which_fits(u32 size)
-{
- u32 order = 0;
- u32 powsize = 1;
- while (powsize < size)
- {
- powsize <<= 1;
- if (powsize > size) break;
- order++;
- }
-
- return order;
-}
-
-/* called for new MEMORY resources */
-static _mali_osk_errcode_t mali_memory_bank_register(u32 phys_base, u32 cpu_usage_adjust, u32 size, u32 flags, u32 alloc_order, const char *name)
-{
- /* no locking performed due to function contract */
- int i;
- u32 left, offset;
- mali_memory_bank * bank;
- mali_memory_bank * bank_enum, *temp;
-
- _mali_osk_errcode_t err;
-
- /* Only a multiple of MIN_BLOCK_SIZE is usable */
- u32 usable_size = size & ~(MIN_BLOCK_SIZE - 1);
-
- /* handle zero sized banks and bank smaller than the fixed block size */
- if (0 == usable_size)
- {
- MALI_PRINT(("Usable size == 0\n"));
- MALI_ERROR(_MALI_OSK_ERR_INVALID_ARGS);
- }
-
- /* warn for banks not a muliple of the block size */
- MALI_DEBUG_PRINT_IF(1, usable_size != size, ("Memory bank @ 0x%X not a multiple of minimum block size. %d bytes wasted\n", phys_base, size - usable_size));
-
- /* check against previous registrations */
- MALI_DEBUG_CODE(
- {
- _MALI_OSK_LIST_FOREACHENTRY(bank, temp, &memory_banks_list, mali_memory_bank, list)
- {
- /* duplicate ? */
- if (bank->base_addr == phys_base)
- {
- MALI_PRINT(("Duplicate registration of a memory bank at 0x%X detected\n", phys_base));
- MALI_ERROR(_MALI_OSK_ERR_FAULT);
- }
- /* overlapping ? */
- else if (
- ( (phys_base > bank->base_addr) && (phys_base < (bank->base_addr + bank->real_size)) ) ||
- ( (phys_base + size) > bank->base_addr && ((phys_base + size) < (bank->base_addr + bank->real_size)) )
- )
- {
- MALI_PRINT(("Overlapping memory blocks found. Memory at 0x%X overlaps with memory at 0x%X size 0x%X\n", bank->base_addr, phys_base, size));
- MALI_ERROR(_MALI_OSK_ERR_FAULT);
- }
- }
- }
- );
-
- /* create an object to represent this memory bank */
- MALI_CHECK_NON_NULL(bank = (mali_memory_bank*)_mali_osk_malloc(sizeof(mali_memory_bank)), _MALI_OSK_ERR_NOMEM);
-
- /* init the fields */
- _MALI_OSK_INIT_LIST_HEAD(&bank->list);
- bank->base_addr = phys_base;
- bank->cpu_usage_adjust = cpu_usage_adjust;
- bank->size = usable_size;
- bank->real_size = size;
- bank->alloc_order = alloc_order;
- bank->name = name;
-
- err = _mali_osk_atomic_init(&bank->num_active_allocations, 0);
- if (err != _MALI_OSK_ERR_OK)
- {
- _mali_osk_free(bank);
- MALI_ERROR(err);
- }
-
- bank->used_for_flags = flags;
- bank->min_order = order_needed_for_size(MIN_BLOCK_SIZE, NULL);
- bank->max_order = maximum_order_which_fits(usable_size);
- bank->lock = _mali_osk_lock_init((_mali_osk_lock_flags_t)(_MALI_OSK_LOCKFLAG_SPINLOCK | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE), 0, 0);
- if (NULL == bank->lock)
- {
- _mali_osk_atomic_term(&bank->num_active_allocations);
- _mali_osk_free(bank);
- MALI_ERROR(_MALI_OSK_ERR_FAULT);
- }
-
- bank->blocklist = _mali_osk_calloc(1, sizeof(struct mali_memory_block) * (usable_size / MIN_BLOCK_SIZE));
- if (NULL == bank->blocklist)
- {
- _mali_osk_lock_term(bank->lock);
- _mali_osk_atomic_term(&bank->num_active_allocations);
- _mali_osk_free(bank);
- MALI_ERROR(_MALI_OSK_ERR_NOMEM);
- }
-
- for (i = 0; i < (usable_size / MIN_BLOCK_SIZE); i++)
- {
- bank->blocklist[i].bank = bank;
- }
-
- bank->freelist = _mali_osk_calloc(1, sizeof(_mali_osk_list_t) * (bank->max_order - bank->min_order + 1));
- if (NULL == bank->freelist)
- {
- _mali_osk_lock_term(bank->lock);
- _mali_osk_free(bank->blocklist);
- _mali_osk_atomic_term(&bank->num_active_allocations);
- _mali_osk_free(bank);
- MALI_ERROR(_MALI_OSK_ERR_NOMEM);
- }
-
- for (i = 0; i < (bank->max_order - bank->min_order + 1); i++) _MALI_OSK_INIT_LIST_HEAD(&bank->freelist[i]);
-
- /* init slot info */
- for (offset = 0, left = usable_size; offset < (usable_size / MIN_BLOCK_SIZE); /* updated inside the body */)
- {
- u32 block_order;
- mali_memory_block * block;
-
- /* the maximum order which fits in the remaining area */
- block_order = maximum_order_which_fits(left);
-
- /* find the block pointer */
- block = &bank->blocklist[offset];
-
- /* tag the block as being toplevel */
- set_block_toplevel(block, block_order);
-
- /* tag it as being free */
- set_block_free(block, 1);
-
- /* set the order */
- set_block_order(block, block_order);
-
- _mali_osk_list_addtail(&block->link, bank->freelist + (block_order - bank->min_order));
-
- left -= (1 << block_order);
- offset += ((1 << block_order) / MIN_BLOCK_SIZE);
- }
-
- /* add bank to list of banks on the system */
- _MALI_OSK_LIST_FOREACHENTRY( bank_enum, temp, &memory_banks_list, mali_memory_bank, list )
- {
- if ( bank_enum->alloc_order >= alloc_order )
- {
- /* Found insertion point - our item must go before this one */
- break;
- }
- }
- _mali_osk_list_addtail(&bank->list, &bank_enum->list);
-
- MALI_SUCCESS;
-}
-
-_mali_osk_errcode_t mali_memory_mmu_register(u32 type, u32 phys_base)
-{
- /* not supported */
- return _MALI_OSK_ERR_INVALID_FUNC;
-}
-
-void mali_memory_mmu_unregister(u32 phys_base)
-{
- /* not supported */
- return;
-}
-
-static mali_memory_block * mali_memory_block_get(u32 type_id, u32 minimum_size)
-{
- mali_memory_bank * bank;
- mali_memory_block * block = NULL;
- u32 requested_order, current_order;
-
- /* input validation */
- if (0 == minimum_size)
- {
- /* bad size */
- MALI_DEBUG_PRINT(2, ("Zero size block requested by mali_memory_block_get\n"));
- return NULL;
- }
-
- bank = (mali_memory_bank*)type_id;
-
- requested_order = order_needed_for_size(minimum_size, bank);
-
- MALI_DEBUG_PRINT(4, ("For size %d we need order %d (%d)\n", minimum_size, requested_order, 1 << requested_order));
-
- _mali_osk_lock_wait(bank->lock, _MALI_OSK_LOCKMODE_RW);
- /* ! critical section begin */
-
- MALI_DEBUG_PRINT(7, ("Bank 0x%x locked\n", bank));
-
- for (current_order = requested_order; current_order <= bank->max_order; ++current_order)
- {
- _mali_osk_list_t * list = bank->freelist + (current_order - bank->min_order);
- MALI_DEBUG_PRINT(7, ("Checking freelist 0x%x for order %d\n", list, current_order));
- if (0 != _mali_osk_list_empty(list)) continue; /* empty list */
-
- MALI_DEBUG_PRINT(7, ("Found an entry on the freelist for order %d\n", current_order));
-
-
- block = _MALI_OSK_LIST_ENTRY(list->next, mali_memory_block, link);
- _mali_osk_list_delinit(&block->link);
-
- while (current_order > requested_order)
- {
- mali_memory_block * buddy_block;
- MALI_DEBUG_PRINT(7, ("Splitting block 0x%x\n", block));
- current_order--;
- list--;
- buddy_block = block_get_buddy(block, current_order - bank->min_order);
- set_block_order(buddy_block, current_order);
- set_block_free(buddy_block, 1);
- _mali_osk_list_add(&buddy_block->link, list);
- }
-
- set_block_order(block, current_order);
- set_block_free(block, 0);
-
- /* update usage count */
- _mali_osk_atomic_inc(&bank->num_active_allocations);
-
- break;
- }
-
- /* ! critical section end */
- _mali_osk_lock_signal(bank->lock, _MALI_OSK_LOCKMODE_RW);
-
- MALI_DEBUG_PRINT(7, ("Lock released for bank 0x%x\n", bank));
-
- MALI_DEBUG_PRINT_IF(7, NULL != block, ("Block 0x%x allocated\n", block));
-
- return block;
-}
-
-
-static void block_release(mali_memory_block * block)
-{
- mali_memory_bank * bank;
- u32 current_order;
-
- if (NULL == block) return;
-
- bank = block->bank;
-
- /* we're manipulating the free list, so we need to lock it */
- _mali_osk_lock_wait(bank->lock, _MALI_OSK_LOCKMODE_RW);
- /* ! critical section begin */
-
- set_block_free(block, 1);
- current_order = get_block_order(block);
-
- while (current_order <= bank->max_order)
- {
- mali_memory_block * buddy_block;
- buddy_block = block_get_buddy(block, current_order - bank->min_order);
- if (!block_is_valid_buddy(buddy_block, current_order)) break;
- _mali_osk_list_delinit(&buddy_block->link); /* remove from free list */
- /* clear tracked data in both blocks */
- set_block_order(block, 0);
- set_block_free(block, 0);
- set_block_order(buddy_block, 0);
- set_block_free(buddy_block, 0);
- /* make the parent control the new state */
- block = block_get_parent(block, current_order - bank->min_order);
- set_block_order(block, current_order + 1); /* merged has a higher order */
- set_block_free(block, 1); /* mark it as free */
- current_order++;
- if (get_block_toplevel(block) == current_order) break; /* stop the merge if we've arrived at a toplevel block */
- }
-
- _mali_osk_list_add(&block->link, &bank->freelist[current_order - bank->min_order]);
-
- /* update bank usage statistics */
- _mali_osk_atomic_dec(&block->bank->num_active_allocations);
-
- /* !critical section end */
- _mali_osk_lock_signal(bank->lock, _MALI_OSK_LOCKMODE_RW);
-
- return;
-}
-
-MALI_STATIC_INLINE u32 block_get_offset(mali_memory_block * block)
-{
- return block - block->bank->blocklist;
-}
-
-MALI_STATIC_INLINE u32 block_mali_addr_get(mali_memory_block * block)
-{
- if (NULL != block) return block->bank->base_addr + MIN_BLOCK_SIZE * block_get_offset(block);
- else return 0;
-}
-
-MALI_STATIC_INLINE u32 block_cpu_addr_get(mali_memory_block * block)
-{
- if (NULL != block) return (block->bank->base_addr + MIN_BLOCK_SIZE * block_get_offset(block)) + block->bank->cpu_usage_adjust;
- else return 0;
-}
-
-MALI_STATIC_INLINE u32 block_size_get(mali_memory_block * block)
-{
- if (NULL != block) return 1 << get_block_order(block);
- else return 0;
-}
-
-MALI_STATIC_INLINE void __user * block_mapping_get(mali_memory_block * block)
-{
- if (NULL != block) return block->mapping;
- else return NULL;
-}
-
-MALI_STATIC_INLINE void block_mapping_set(mali_memory_block * block, void __user * ptr)
-{
- if (NULL != block) block->mapping = ptr;
-}
-
-MALI_STATIC_INLINE u32 block_mmap_cookie_get(mali_memory_block * block)
-{
- if (NULL != block) return block->mmap_cookie;
- else return 0;
-}
-
-/**
- * Set the cookie returned via _mali_ukk_mem_mmap().
- * @param block The memory block to set the cookie for
- * @param cookie the cookie
- */
-MALI_STATIC_INLINE void block_mmap_cookie_set(mali_memory_block * block, u32 cookie)
-{
- if (NULL != block) block->mmap_cookie = cookie;
-}
-
-
-static _mali_osk_errcode_t mali_memory_core_session_begin(struct mali_session_data * mali_session_data, mali_kernel_subsystem_session_slot * slot, _mali_osk_notification_queue_t * queue)
-{
- memory_session * session_data;
-
- /* validate input */
- if (NULL == slot)
- {
- MALI_DEBUG_PRINT(1, ("NULL slot given to memory session begin\n"));
- MALI_ERROR(_MALI_OSK_ERR_INVALID_ARGS);
- }
-
- if (NULL != *slot)
- {
- MALI_DEBUG_PRINT(1, ("The slot given to memory session begin already contains data"));
- MALI_ERROR(_MALI_OSK_ERR_INVALID_ARGS);
- }
-
- /* create the session data object */
- MALI_CHECK_NON_NULL(session_data = _mali_osk_malloc(sizeof(memory_session)), _MALI_OSK_ERR_NOMEM);
-
- /* 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_osk_free(session_data);
- MALI_ERROR(_MALI_OSK_ERR_NOMEM);
- }
-
- _MALI_OSK_INIT_LIST_HEAD(&session_data->memory_head); /* no memory in use */
- session_data->lock = _mali_osk_lock_init((_mali_osk_lock_flags_t)(_MALI_OSK_LOCKFLAG_ONELOCK | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE), 0, 0);
- if (NULL == session_data->lock)
- {
- _mali_osk_free(session_data);
- MALI_ERROR(_MALI_OSK_ERR_FAULT);
- }
-
- *slot = session_data; /* slot will point to our data object */
-
- MALI_SUCCESS;
-}
-
-static void mali_memory_core_session_end(struct mali_session_data * mali_session_data, mali_kernel_subsystem_session_slot * slot)
-{
- memory_session * session_data;
-
- /* validate input */
- if (NULL == slot)
- {
- MALI_DEBUG_PRINT(1, ("NULL slot given to memory session begin\n"));
- return;
- }
-
- if (NULL == *slot)
- {
- MALI_DEBUG_PRINT(1, ("NULL memory_session found in current session object"));
- return;
- }
-
- _mali_osk_lock_wait(((memory_session*)*slot)->lock, _MALI_OSK_LOCKMODE_RW);
- session_data = (memory_session *)*slot;
- /* clear our slot */
- *slot = NULL;
-
- /*
- First free all memory still being used.
- This can happen if the caller has leaked memory or
- the application has crashed forcing an auto-session end.
- */
- if (0 == _mali_osk_list_empty(&session_data->memory_head))
- {
- mali_memory_block * block, * temp;
- MALI_DEBUG_PRINT(1, ("Memory found on session usage list during session termination\n"));
-
- /* use the _safe version since fre_big_block removes the active block from the list we're iterating */
- _MALI_OSK_LIST_FOREACHENTRY(block, temp, &session_data->memory_head, mali_memory_block, link)
- {
- _mali_osk_errcode_t err;
- _mali_uk_free_big_block_s uk_args;
-
- MALI_DEBUG_PRINT(4, ("Freeing block 0x%x with mali address 0x%x size %d mapped in user space at 0x%x\n",
- block,
- (void*)block_mali_addr_get(block),
- block_size_get(block),
- block_mapping_get(block))
- );
-
- /* free the block */
- /** @note manual type safety check-point */
- uk_args.ctx = mali_session_data;
- uk_args.cookie = (u32)block->descriptor;
- err = _mali_ukk_free_big_block_internal( mali_session_data, session_data, &uk_args );
-
- if ( _MALI_OSK_ERR_OK != err )
- {
- MALI_DEBUG_PRINT_ERROR(("_mali_ukk_free_big_block_internal() failed during session termination on block with cookie==0x%X\n",
- uk_args.cookie)
- );
- }
- }
- }
-
- if (NULL != session_data->descriptor_mapping)
- {
- mali_descriptor_mapping_destroy(session_data->descriptor_mapping);
- session_data->descriptor_mapping = NULL;
- }
-
- _mali_osk_lock_signal(session_data->lock, _MALI_OSK_LOCKMODE_RW);
- _mali_osk_lock_term(session_data->lock);
-
- /* free the session data object */
- _mali_osk_free(session_data);
-
- return;
-}
-
-static _mali_osk_errcode_t mali_memory_core_system_info_fill(_mali_system_info* info)
-{
- mali_memory_bank * bank, *temp;
- _mali_mem_info **mem_info_tail;
-
- /* check input */
- MALI_CHECK_NON_NULL(info, _MALI_OSK_ERR_INVALID_ARGS);
-
- /* make sure we won't leak any memory. It could also be that it's an uninitialized variable, but that would be a bug in the caller */
- MALI_DEBUG_ASSERT(NULL == info->mem_info);
-
- mem_info_tail = &info->mem_info;
-
- _MALI_OSK_LIST_FOREACHENTRY(bank, temp, &memory_banks_list, mali_memory_bank, list)
- {
- _mali_mem_info * mem_info;
-
- mem_info = (_mali_mem_info *)_mali_osk_calloc(1, sizeof(_mali_mem_info));
- if (NULL == mem_info) return _MALI_OSK_ERR_NOMEM; /* memory already allocated will be freed by the caller */
-
- /* set info */
- mem_info->size = bank->size;
- mem_info->flags = (_mali_bus_usage)bank->used_for_flags;
- mem_info->maximum_order_supported = bank->max_order;
- mem_info->identifier = (u32)bank;
-
- /* add to system info linked list */
- (*mem_info_tail) = mem_info;
- mem_info_tail = &mem_info->next;
- }
-
- /* all OK */
- MALI_SUCCESS;
-}
-
-static _mali_osk_errcode_t mali_memory_core_resource_memory(_mali_osk_resource_t * resource)
-{
- _mali_osk_errcode_t err;
-
- /* Request ownership of the memory */
- if (_MALI_OSK_ERR_OK != _mali_osk_mem_reqregion(resource->base, resource->size, resource->description))
- {
- MALI_DEBUG_PRINT(1, ("Failed to request memory region %s (0x%08X - 0x%08X)\n", resource->description, resource->base, resource->base + resource->size - 1));
- MALI_ERROR(_MALI_OSK_ERR_NOMEM);
- }
-
- /* call backend */
- err = mali_memory_bank_register(resource->base, resource->cpu_usage_adjust, resource->size, resource->flags, resource->alloc_order, resource->description);
- if (_MALI_OSK_ERR_OK != err)
- {
- /* if backend refused the memory we have to release the region again */
- MALI_DEBUG_PRINT(1, ("Memory bank registration failed\n"));
- _mali_osk_mem_unreqregion(resource->base, resource->size);
- MALI_ERROR(err);
- }
-
- MALI_SUCCESS;
-}
-
-static _mali_osk_errcode_t mali_memory_core_resource_mmu(_mali_osk_resource_t * resource)
-{
- /* Not supported by the fixed block memory system */
- MALI_DEBUG_PRINT(1, ("MMU resource not supported by non-MMU driver!\n"));
- MALI_ERROR(_MALI_OSK_ERR_INVALID_FUNC);
-}
-
-static _mali_osk_errcode_t mali_memory_core_resource_fpga(_mali_osk_resource_t * resource)
-{
- mali_io_address mapping;
-
- MALI_DEBUG_PRINT(5, ("FPGA framework '%s' @ (0x%08X - 0x%08X)\n",
- resource->description, resource->base, resource->base + sizeof(u32) * 2 - 1
- ));
-
- mapping = _mali_osk_mem_mapioregion(resource->base + 0x1000, sizeof(u32) * 2, "fpga framework");
- if (mapping)
- {
- u32 data;
- data = _mali_osk_mem_ioread32(mapping, 0);
- MALI_DEBUG_PRINT(2, ("FPGA framwork '%s' @ 0x%08X:\n", resource->description, resource->base));
- MALI_DEBUG_PRINT(2, ("\tBitfile date: %d%02d%02d_%02d%02d\n",
- (data >> 20),
- (data >> 16) & 0xF,
- (data >> 11) & 0x1F,
- (data >> 6) & 0x1F,
- (data >> 0) & 0x3F));
- data = _mali_osk_mem_ioread32(mapping, sizeof(u32));
- MALI_DEBUG_PRINT(2, ("\tBitfile SCCS rev: %d\n", data));
-
- _mali_osk_mem_unmapioregion(resource->base + 0x1000, sizeof(u32) *2, mapping);
- }
- else MALI_DEBUG_PRINT(1, ("Failed to access FPGA framwork '%s' @ 0x%08X\n", resource->description, resource->base));
-
- MALI_SUCCESS;
-}
-
-/* static _mali_osk_errcode_t get_big_block(void * ukk_private, struct mali_session_data * mali_session_data, void __user * argument) */
-_mali_osk_errcode_t _mali_ukk_get_big_block( _mali_uk_get_big_block_s *args )
-{
- _mali_uk_mem_mmap_s args_mmap = {0, };
- int md;
- mali_memory_block * block;
- _mali_osk_errcode_t err;
- memory_session * session_data;
-
- MALI_DEBUG_ASSERT_POINTER( args );
-
- MALI_DEBUG_ASSERT_POINTER( args->ctx );
-
- /** @note manual type safety check-point */
- session_data = (memory_session *)mali_kernel_session_manager_slot_get(args->ctx, mali_subsystem_memory_id);
-
- MALI_CHECK_NON_NULL(session_data, _MALI_OSK_ERR_INVALID_ARGS);
-
- _mali_osk_lock_wait(session_data->lock, _MALI_OSK_LOCKMODE_RW);
-
- if (!args->type_id)
- {
- _mali_osk_lock_signal(session_data->lock, _MALI_OSK_LOCKMODE_RW);
- MALI_ERROR(_MALI_OSK_ERR_FAULT);
- }
-
- /* at least min block size */
- if (MIN_BLOCK_SIZE > args->minimum_size_requested) args->minimum_size_requested = MIN_BLOCK_SIZE;
-
- /* perform the actual allocation */
- block = mali_memory_block_get(args->type_id, args->minimum_size_requested);
- if ( NULL == block )
- {
- /* no memory available with requested type_id */
- _mali_osk_lock_signal(session_data->lock, _MALI_OSK_LOCKMODE_RW);
- MALI_ERROR(_MALI_OSK_ERR_NOMEM);
- }
-
- if (_MALI_OSK_ERR_OK != mali_descriptor_mapping_allocate_mapping(session_data->descriptor_mapping, block, &md))
- {
- block_release(block);
- _mali_osk_lock_signal(session_data->lock, _MALI_OSK_LOCKMODE_RW);
- MALI_ERROR(_MALI_OSK_ERR_NOMEM);
- }
- block->descriptor = md;
-
-
- /* fill in response */
- args->mali_address = block_mali_addr_get(block);
- args->block_size = block_size_get(block);
- args->cookie = (u32)md;
- args->flags = block->bank->used_for_flags;
-
- /* map the block into the process' address space */
-
- /** @note manual type safety check-point */
- args_mmap.ukk_private = (void *)args->ukk_private;
- args_mmap.ctx = args->ctx;
- args_mmap.size = args->block_size;
- args_mmap.phys_addr = block_cpu_addr_get(block);
-
-#ifndef _MALI_OSK_SPECIFIC_INDIRECT_MMAP
- err = _mali_ukk_mem_mmap( &args_mmap );
-#else
- err = _mali_osk_specific_indirect_mmap( &args_mmap );
-#endif
-
- /* check if the mapping failed */
- if ( _MALI_OSK_ERR_OK != err )
- {
- MALI_DEBUG_PRINT(1, ("Memory mapping failed 0x%x\n", args->cpuptr));
- /* mapping failed */
-
- /* remove descriptor entry */
- mali_descriptor_mapping_free(session_data->descriptor_mapping, md);
-
- /* free the mali memory */
- block_release(block);
-
- _mali_osk_lock_signal(session_data->lock, _MALI_OSK_LOCKMODE_RW);
- return err;
- }
-
- args->cpuptr = args_mmap.mapping;
- block_mmap_cookie_set(block, args_mmap.cookie);
- block_mapping_set(block, args->cpuptr);
-
- MALI_DEBUG_PRINT(2, ("Mali memory 0x%x (size %d) mapped in process memory space at 0x%x\n", (void*)args->mali_address, args->block_size, args->cpuptr));
-
- /* track memory in use for the session */
- _mali_osk_list_addtail(&block->link, &session_data->memory_head);
-
- /* memory assigned to the session, memory mapped into the process' view */
- _mali_osk_lock_signal(session_data->lock, _MALI_OSK_LOCKMODE_RW);
-
- MALI_SUCCESS;
-}
-
-/* Internal code that assumes the memory session lock is held */
-static _mali_osk_errcode_t _mali_ukk_free_big_block_internal( struct mali_session_data * mali_session_data, memory_session * session_data, _mali_uk_free_big_block_s *args)
-{
- mali_memory_block * block = NULL;
- _mali_osk_errcode_t err;
- _mali_uk_mem_munmap_s args_munmap = {0,};
-
- MALI_DEBUG_ASSERT_POINTER( mali_session_data );
- MALI_DEBUG_ASSERT_POINTER( session_data );
- MALI_DEBUG_ASSERT_POINTER( args );
-
- err = mali_descriptor_mapping_get(session_data->descriptor_mapping, (int)args->cookie, (void**)&block);
- if (_MALI_OSK_ERR_OK != err)
- {
- MALI_DEBUG_PRINT(1, ("Invalid memory descriptor %d used to release memory pages\n", (int)args->cookie));
- MALI_ERROR(err);
- }
-
- MALI_DEBUG_ASSERT_POINTER(block);
-
- MALI_DEBUG_PRINT(4, ("Asked to free block 0x%x with mali address 0x%x size %d mapped in user space at 0x%x\n",
- block,
- (void*)block_mali_addr_get(block),
- block_size_get(block),
- block_mapping_get(block))
- );
-
- /** @note manual type safety check-point */
- args_munmap.ctx = (void*)mali_session_data;
- args_munmap.mapping = block_mapping_get( block );
- args_munmap.size = block_size_get( block );
- args_munmap.cookie = block_mmap_cookie_get( block );
-
-#ifndef _MALI_OSK_SPECIFIC_INDIRECT_MMAP
- _mali_ukk_mem_munmap( &args_munmap );
-#else
- _mali_osk_specific_indirect_munmap( &args_munmap );
-#endif
-
- MALI_DEBUG_PRINT(6, ("Session data 0x%x, lock 0x%x\n", session_data, &session_data->lock));
-
- /* unlink from session usage list */
- MALI_DEBUG_PRINT(5, ("unlink from session usage list\n"));
- _mali_osk_list_delinit(&block->link);
-
- /* remove descriptor entry */
- mali_descriptor_mapping_free(session_data->descriptor_mapping, (int)args->cookie);
-
- /* free the mali memory */
- block_release(block);
- MALI_DEBUG_PRINT(5, ("Block freed\n"));
-
- MALI_SUCCESS;
-}
-
-/* static _mali_osk_errcode_t free_big_block( struct mali_session_data * mali_session_data, void __user * argument) */
-_mali_osk_errcode_t _mali_ukk_free_big_block( _mali_uk_free_big_block_s *args )
-{
- _mali_osk_errcode_t err;
- struct mali_session_data * mali_session_data;
- memory_session * session_data;
-
- MALI_DEBUG_ASSERT_POINTER( args );
-
- MALI_DEBUG_ASSERT_POINTER( args->ctx );
-
- /** @note manual type safety check-point */
- mali_session_data = (struct mali_session_data *)args->ctx;
-
- /* Must always verify this, since these are provided by the user */
- MALI_CHECK_NON_NULL(mali_session_data, _MALI_OSK_ERR_INVALID_ARGS);
-
- session_data = mali_kernel_session_manager_slot_get(mali_session_data, mali_subsystem_memory_id);
-
- MALI_CHECK_NON_NULL(session_data, _MALI_OSK_ERR_INVALID_ARGS);
-
- _mali_osk_lock_wait(session_data->lock, _MALI_OSK_LOCKMODE_RW);
-
- /** @note this has been separated out so that the session_end handler can call this while it has the memory_session lock held */
- err = _mali_ukk_free_big_block_internal( mali_session_data, session_data, args );
-
- _mali_osk_lock_signal(session_data->lock, _MALI_OSK_LOCKMODE_RW);
-
- return err;
-}
-
-MALI_STATIC_INLINE u32 get_block_free(mali_memory_block * block)
-{
- return (block->misc >> MISC_SHIFT_FREE) & MISC_MASK_FREE;
-}
-
-MALI_STATIC_INLINE void set_block_free(mali_memory_block * block, int state)
-{
- if (state) block->misc |= (MISC_MASK_FREE << MISC_SHIFT_FREE);
- else block->misc &= ~(MISC_MASK_FREE << MISC_SHIFT_FREE);
-}
-
-MALI_STATIC_INLINE void set_block_order(mali_memory_block * block, u32 order)
-{
- block->misc &= ~(MISC_MASK_ORDER << MISC_SHIFT_ORDER);
- block->misc |= ((order & MISC_MASK_ORDER) << MISC_SHIFT_ORDER);
-}
-
-MALI_STATIC_INLINE u32 get_block_order(mali_memory_block * block)
-{
- return (block->misc >> MISC_SHIFT_ORDER) & MISC_MASK_ORDER;
-}
-
-MALI_STATIC_INLINE void set_block_toplevel(mali_memory_block * block, u32 level)
-{
- block->misc |= ((level & MISC_MASK_TOPLEVEL) << MISC_SHIFT_TOPLEVEL);
-}
-
-MALI_STATIC_INLINE u32 get_block_toplevel(mali_memory_block * block)
-{
- return (block->misc >> MISC_SHIFT_TOPLEVEL) & MISC_MASK_TOPLEVEL;
-}
-
-MALI_STATIC_INLINE int block_is_valid_buddy(mali_memory_block * block, int order)
-{
- if (get_block_free(block) && (get_block_order(block) == order)) return 1;
- else return 0;
-}
-
-MALI_STATIC_INLINE mali_memory_block * block_get_buddy(mali_memory_block * block, u32 order)
-{
- return block + ( (block_get_offset(block) ^ (1 << order)) - block_get_offset(block));
-}
-
-MALI_STATIC_INLINE mali_memory_block * block_get_parent(mali_memory_block * block, u32 order)
-{
- return block + ((block_get_offset(block) & ~(1 << order)) - block_get_offset(block));
-}
-
-/* This handler registered to mali_mmap for non-MMU builds */
-_mali_osk_errcode_t _mali_ukk_mem_mmap( _mali_uk_mem_mmap_s *args )
-{
- _mali_osk_errcode_t ret;
- struct mali_session_data * mali_session_data;
- mali_memory_allocation * descriptor;
- memory_session * session_data;
-
- /* 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 */
- mali_session_data = (struct mali_session_data *)args->ctx;
-
- if (NULL == mali_session_data) { MALI_DEBUG_PRINT(3,("mali_ukk_mem_mmap: mali_session data was NULL\n")); MALI_ERROR(_MALI_OSK_ERR_INVALID_ARGS); }
-
- MALI_DEBUG_ASSERT( mali_subsystem_memory_id >= 0 );
-
- session_data = mali_kernel_session_manager_slot_get(mali_session_data, mali_subsystem_memory_id);
- /* 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;
-
- ret = _mali_osk_mem_mapregion_init( descriptor );
- if ( _MALI_OSK_ERR_OK != ret )
- {
- MALI_DEBUG_PRINT(3, ("_mali_osk_mem_mapregion_init() failed\n"));
- _mali_osk_free(descriptor);
- MALI_ERROR(ret);
- }
-
- ret = _mali_osk_mem_mapregion_map( descriptor, 0, &descriptor->mali_address, descriptor->size );
- if ( _MALI_OSK_ERR_OK != ret )
- {
- MALI_DEBUG_PRINT(3, ("_mali_osk_mem_mapregion_map() failed\n"));
- _mali_osk_mem_mapregion_term( descriptor );
- _mali_osk_free(descriptor);
- MALI_ERROR(ret);
- }
-
- args->mapping = descriptor->mapping;
-
- /**
- * @note we do not require use of mali_descriptor_mapping here:
- * the cookie gets stored in the mali_memory_block struct, which itself is
- * protected by mali_descriptor_mapping, and so this cookie never leaves
- * kernel space (on any OS).
- *
- * In the MMU case, we must use a mali_descriptor_mapping, since on _some_
- * OSs, the cookie leaves kernel space.
- */
- args->cookie = (u32)descriptor;
- MALI_SUCCESS;
-}
-
-/* This handler registered to mali_munmap for non-MMU builds */
-_mali_osk_errcode_t _mali_ukk_mem_munmap( _mali_uk_mem_munmap_s *args )
-{
- mali_memory_allocation * descriptor;
-
- /** see note in _mali_ukk_mem_mmap() - no need to use descriptor mapping */
- descriptor = (mali_memory_allocation *)args->cookie;
- MALI_DEBUG_ASSERT_POINTER(descriptor);
-
- /* 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_osk_mem_mapregion_unmap( descriptor, 0, descriptor->size, (_mali_osk_mem_mapregion_flags_t)0 );
-
- _mali_osk_mem_mapregion_term( descriptor );
-
- _mali_osk_free(descriptor);
-
- return _MALI_OSK_ERR_OK;
-}
-
-/**
- * Stub function to satisfy UDD interface exclusion requirement.
- * This is because the Base code compiles in \b both MMU and non-MMU calls,
- * so both sets must be declared (but the 'unused' set may be stub)
- */
-_mali_osk_errcode_t _mali_ukk_init_mem( _mali_uk_init_mem_s *args )
-{
- MALI_IGNORE( args );
- return _MALI_OSK_ERR_FAULT;
-}
-
-/**
- * Stub function to satisfy UDD interface exclusion requirement.
- * This is because the Base code compiles in \b both MMU and non-MMU calls,
- * so both sets must be declared (but the 'unused' set may be stub)
- */
-_mali_osk_errcode_t _mali_ukk_term_mem( _mali_uk_term_mem_s *args )
-{
- MALI_IGNORE( args );
- return _MALI_OSK_ERR_FAULT;
-}
-
-/**
- * Stub function to satisfy UDD interface exclusion requirement.
- * This is because the Base code compiles in \b both MMU and non-MMU calls,
- * so both sets must be declared (but the 'unused' set may be stub)
- */
-_mali_osk_errcode_t _mali_ukk_map_external_mem( _mali_uk_map_external_mem_s *args )
-{
- MALI_IGNORE( args );
- return _MALI_OSK_ERR_FAULT;
-}
-
-/**
- * Stub function to satisfy UDD interface exclusion requirement.
- * This is because the Base code compiles in \b both MMU and non-MMU calls,
- * so both sets must be declared (but the 'unused' set may be stub)
- */
-_mali_osk_errcode_t _mali_ukk_unmap_external_mem( _mali_uk_unmap_external_mem_s *args )
-{
- MALI_IGNORE( args );
- return _MALI_OSK_ERR_FAULT;
-}
-
-/**
- * Stub function to satisfy UDD interface exclusion requirement.
- * This is because the Base code compiles in \b both MMU and non-MMU calls,
- * so both sets must be declared (but the 'unused' set may be stub)
- */
-_mali_osk_errcode_t _mali_ukk_query_mmu_page_table_dump_size( _mali_uk_query_mmu_page_table_dump_size_s *args )
-{
- MALI_IGNORE( args );
- return _MALI_OSK_ERR_FAULT;
-}
-
-/**
- * Stub function to satisfy UDD interface exclusion requirement.
- * This is because the Base code compiles in \b both MMU and non-MMU calls,
- * so both sets must be declared (but the 'unused' set may be stub)
- */
-_mali_osk_errcode_t _mali_ukk_dump_mmu_page_table( _mali_uk_dump_mmu_page_table_s * args )
-{
- MALI_IGNORE( args );
- return _MALI_OSK_ERR_FAULT;
-}
diff --git a/drivers/media/video/samsung/mali/common/mali_kernel_mem_mmu.c b/drivers/media/video/samsung/mali/common/mali_kernel_mem_mmu.c
deleted file mode 100644
index c993ad5..0000000
--- a/drivers/media/video/samsung/mali/common/mali_kernel_mem_mmu.c
+++ /dev/null
@@ -1,3157 +0,0 @@
-/*
- * 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 "mali_kernel_subsystem.h"
-#include "mali_kernel_mem.h"
-#include "mali_kernel_ioctl.h"
-#include "mali_kernel_descriptor_mapping.h"
-#include "mali_kernel_mem_mmu.h"
-#include "mali_kernel_memory_engine.h"
-#include "mali_block_allocator.h"
-#include "mali_kernel_mem_os.h"
-#include "mali_kernel_session_manager.h"
-#include "mali_kernel_core.h"
-#include "mali_kernel_rendercore.h"
-
-#if defined USING_MALI400_L2_CACHE
-#include "mali_kernel_l2_cache.h"
-#endif
-
-#if MALI_USE_UNIFIED_MEMORY_PROVIDER != 0
-#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_bitops.h"
-#include "mali_osk_list.h"
-
-/**
- * Size of the MMU registers in bytes
- */
-#define MALI_MMU_REGISTERS_SIZE 0x24
-
-/**
- * Size of an MMU page in bytes
- */
-#define MALI_MMU_PAGE_SIZE 0x1000
-
-/**
- * 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)
-
-/**
- * Calculate memory address from PDE and PTE
- */
-#define MALI_MMU_ADDRESS(pde, pte) (((pde)<<22) | ((pte)<<12))
-
-/**
- * Linux kernel version has marked SA_SHIRQ as deprecated, IRQF_SHARED should be used.
- * This is to handle older kernels which haven't done this swap.
- */
-#ifndef IRQF_SHARED
-#define IRQF_SHARED SA_SHIRQ
-#endif /* IRQF_SHARED */
-
-/**
- * Per-session memory descriptor mapping table sizes
- */
-#define MALI_MEM_DESCRIPTORS_INIT 64
-#define MALI_MEM_DESCRIPTORS_MAX 65536
-
-/**
- * Used to disallow more than one core to run a MMU at the same time
- *
- * @note This value is hardwired into some systems' configuration files,
- * which \em might not be a header file (e.g. some external data configuration
- * file). Therefore, if this value is modified, its occurance must be
- * \b manually checked for in the entire driver source tree.
- */
-#define MALI_MMU_DISALLOW_PARALLELL_WORK_OF_MALI_CORES 1
-
-#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_MASK = 0x07
-} mali_mmu_entry_flags;
-
-/**
- * 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 = 0x0001, /**< Status of the MMU */
- MALI_MMU_REGISTER_COMMAND = 0x0002, /**< Command register, used to control the MMU */
- MALI_MMU_REGISTER_PAGE_FAULT_ADDR = 0x0003, /**< Logical address of the last page fault */
- MALI_MMU_REGISTER_ZAP_ONE_LINE = 0x004, /**< Used to invalidate the mapping of a single page from the MMU */
- MALI_MMU_REGISTER_INT_RAWSTAT = 0x0005, /**< Raw interrupt status, all interrupts visible */
- MALI_MMU_REGISTER_INT_CLEAR = 0x0006, /**< Indicate to the MMU that the interrupt has been received */
- MALI_MMU_REGISTER_INT_MASK = 0x0007, /**< Enable/disable types of interrupts */
- MALI_MMU_REGISTER_INT_STATUS = 0x0008 /**< 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;
-
-/**
- * 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_SOFT_RESET = 0x06 /**< Reset the MMU back to power-on settings */
-} mali_mmu_command;
-
-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_bits;
-
-/**
- * Defintion of the type used to represent memory used by a session.
- * Containts the pointer to the huge user space virtual memory area
- * used to access the Mali memory.
- */
-typedef struct memory_session
-{
- _mali_osk_lock_t *lock; /**< Lock protecting the vm manipulation */
-
- u32 mali_base_address; /**< Mali virtual memory area used by this session */
- mali_descriptor_mapping * descriptor_mapping; /**< Mapping between userspace descriptors and our pointers */
-
- 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 */
-
- _mali_osk_list_t active_mmus; /**< The MMUs in this session, in increasing order of ID (so we can lock them in the correct order when necessary) */
- _mali_osk_list_t memory_head; /**< Track all the memory allocated in this session, for freeing on abnormal termination */
-} memory_session;
-
-typedef struct mali_kernel_memory_mmu_idle_callback
-{
- _mali_osk_list_t link;
- void (*callback)(void*);
- void * callback_argument;
-} mali_kernel_memory_mmu_idle_callback;
-
-/**
- * Definition of the MMU struct
- * Used to track a MMU unit in the system.
- * Contains information about the mapping of the registers
- */
-typedef struct mali_kernel_memory_mmu
-{
- int id; /**< ID of the MMU, no duplicate IDs may exist on the system */
- const char * description; /**< Description text received from the resource manager to help identify the resource for people */
- int irq_nr; /**< IRQ number */
- u32 base; /**< Physical address of the registers */
- mali_io_address mapped_registers; /**< Virtual mapping of the registers */
- u32 mapping_size; /**< Size of registers in bytes */
- _mali_osk_list_t list; /**< Used to link multiple MMU's into a list */
- _mali_osk_irq_t *irq;
- u32 flags; /**< Used to store if there is something special with this mmu. */
-
- _mali_osk_lock_t *lock; /**< Lock protecting access to the usage fields */
- /* usage fields */
- memory_session * active_session; /**< Active session, NULL if no session is active */
- u32 usage_count; /**< Number of nested activations of the active session */
- _mali_osk_list_t callbacks; /**< Callback registered for MMU idle notification */
- void *core;
-
- int in_page_fault_handler;
-
- _mali_osk_list_t session_link;
-} mali_kernel_memory_mmu;
-
-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 MALI_USE_UNIFIED_MEMORY_PROVIDER != 0
-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;
-
-/*
- Subsystem interface implementation
-*/
-/**
- * Fixed block memory subsystem startup function.
- * Called by the driver core when the driver is loaded.
- * Registers the memory systems ioctl handler, resource handlers and memory map function with the core.
- *
- * @param id Identifier assigned by the core to the memory subsystem
- * @return 0 on success, negative on error
- */
-static _mali_osk_errcode_t mali_memory_core_initialize(mali_kernel_subsystem_identifier id);
-
-/**
- * Fixed block memory subsystem shutdown function.
- * Called by the driver core when the driver is unloaded.
- * Cleans up
- * @param id Identifier assigned by the core to the memory subsystem
- */
-static void mali_memory_core_terminate(mali_kernel_subsystem_identifier id);
-
-/**
- * MMU Memory load complete notification function.
- * Called by the driver core when all drivers have loaded and all resources has been registered
- * Builds the memory overall memory list
- * @param id Identifier assigned by the core to the memory subsystem
- * @return 0 on success, negative on error
- */
-static _mali_osk_errcode_t mali_memory_core_load_complete(mali_kernel_subsystem_identifier id);
-
-/**
- * Fixed block memory subsystem session begin notification
- * Called by the core when a new session to the driver is started.
- * Creates a memory session object and sets it as the subsystem slot data for this session
- * @param slot Pointer to the slot to use for storing per-session data
- * @return 0 on success, negative on error
- */
-static _mali_osk_errcode_t mali_memory_core_session_begin(struct mali_session_data * mali_session_data, mali_kernel_subsystem_session_slot * slot, _mali_osk_notification_queue_t * queue);
-
-/**
- * Fixed block memory subsystem session end notification
- * Called by the core when a session to the driver has ended.
- * Cleans up per session data, which includes checking and fixing memory leaks
- *
- * @param slot Pointer to the slot to use for storing per-session data
- */
-static void mali_memory_core_session_end(struct mali_session_data * mali_session_data, mali_kernel_subsystem_session_slot * slot);
-
-/**
- * Fixed block memory subsystem system info filler
- * Called by the core when a system info update is needed
- * We fill in info about all the memory types we have
- * @param info Pointer to system info struct to update
- * @return 0 on success, negative on error
- */
-static _mali_osk_errcode_t mali_memory_core_system_info_fill(_mali_system_info* info);
-
-/* our registered resource handlers */
-
-/**
- * Fixed block memory subsystem's notification handler for MMU resource instances.
- * Registered with the core during startup.
- * Called by the core for each mmu described in the active architecture's config.h file.
- * @param resource The resource to handle (type MMU)
- * @return 0 if the MMU was found and initialized, negative on error
- */
-static _mali_osk_errcode_t mali_memory_core_resource_mmu(_mali_osk_resource_t * resource);
-
-/**
- * Fixed block memory subsystem's notification handler for FPGA_FRAMEWORK resource instances.
- * Registered with the core during startup.
- * Called by the core for each fpga framework described in the active architecture's config.h file.
- * @param resource The resource to handle (type FPGA_FRAMEWORK)
- * @return 0 if the FPGA framework was found and initialized, negative on error
- */
-static _mali_osk_errcode_t mali_memory_core_resource_fpga(_mali_osk_resource_t * resource);
-
-
-static _mali_osk_errcode_t mali_memory_core_resource_dedicated_memory(_mali_osk_resource_t * resource);
-static _mali_osk_errcode_t mali_memory_core_resource_os_memory(_mali_osk_resource_t * resource);
-
-/**
- * @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_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 );
-
-/**
- * The MMU interrupt handler
- * Upper half of the MMU interrupt processing.
- * Called by the kernel when the MMU has triggered an interrupt.
- * The interrupt function supports IRQ sharing. So it'll probe the MMU in question
- * @param irq The irq number (not used)
- * @param dev_id Points to the MMU object being handled
- * @param regs Registers of interrupted process (not used)
- * @return Standard Linux interrupt result.
- * Subset used by the driver is IRQ_HANDLED processed
- * IRQ_NONE Not processed
- */
-static _mali_osk_errcode_t mali_kernel_memory_mmu_interrupt_handler_upper_half(void * data);
-
-/**
- * The MMU reset hander
- * Bottom half of the MMU interrupt processing for page faults and bus errors
- * @param work The item to operate on, NULL in our case
- */
-static void mali_kernel_memory_mmu_interrupt_handler_bottom_half ( void *data );
-
-/**
- * Read MMU register value
- * Reads the contents of the specified register.
- * @param unit The MMU to read from
- * @param reg The register to read
- * @return The contents of the register
- */
-static u32 mali_mmu_register_read(mali_kernel_memory_mmu * unit, mali_mmu_register reg);
-
-/**
- * Write to a MMU register
- * Writes the given value to the specified register
- * @param unit The MMU to write to
- * @param reg The register to write to
- * @param val The value to write to the register
- */
-static void mali_mmu_register_write(mali_kernel_memory_mmu * unit, mali_mmu_register reg, u32 val);
-
-/**
- * Issues the reset command to the MMU and waits for HW to be ready again
- * @param mmu The MMU to reset
- */
-static void mali_mmu_raw_reset(mali_kernel_memory_mmu * mmu);
-
-/**
- * Issues the enable paging command to the MMU and waits for HW to complete the request
- * @param mmu The MMU to enable paging for
- */
-static void mali_mmu_enable_paging(mali_kernel_memory_mmu * 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)
- */
-static mali_bool mali_mmu_enable_stall(mali_kernel_memory_mmu * 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
- */
-static void mali_mmu_disable_stall(mali_kernel_memory_mmu * mmu);
-
-#if MALI_USE_UNIFIED_MEMORY_PROVIDER != 0
-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 /* MALI_USE_UNIFIED_MEMORY_PROVIDER != 0*/
-
-
-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);
-
-static void mali_mmu_activate_address_space(mali_kernel_memory_mmu * mmu, u32 page_directory);
-
-_mali_osk_errcode_t mali_mmu_page_table_cache_create(void);
-void mali_mmu_page_table_cache_destroy(void);
-
-_mali_osk_errcode_t mali_mmu_get_table_page(u32 *table_page, mali_io_address *mapping);
-void mali_mmu_release_table_page(u32 pa);
-
-static _mali_osk_errcode_t mali_allocate_empty_page_directory(void);
-
-static void mali_free_empty_page_directory(void);
-
-static _mali_osk_errcode_t fill_page(mali_io_address mapping, u32 data);
-
-static _mali_osk_errcode_t mali_allocate_fault_flush_pages(void);
-
-static void mali_free_fault_flush_pages(void);
-
-static void mali_mmu_probe_irq_trigger(mali_kernel_memory_mmu * mmu);
-static _mali_osk_errcode_t mali_mmu_probe_irq_acknowledge(mali_kernel_memory_mmu * mmu);
-
-/* 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;
-
-/* Head of the list of MMUs */
-static _MALI_OSK_LIST_HEAD(mmu_head);
-
-/* the mmu page table cache */
-static struct mali_mmu_page_table_allocations page_table_cache;
-
-/* 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 mali_io_address mali_page_fault_flush_page_directory_mapping = NULL;
-static u32 mali_page_fault_flush_page_table = MALI_INVALID_PAGE;
-static mali_io_address mali_page_fault_flush_page_table_mapping = NULL;
-static u32 mali_page_fault_flush_data_page = MALI_INVALID_PAGE;
-static mali_io_address mali_page_fault_flush_data_page_mapping = NULL;
-
-/* 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;
-
-/*
- The fixed memory system's mali subsystem interface implementation.
- We currently handle module and session life-time management.
-*/
-struct mali_kernel_subsystem mali_subsystem_memory =
-{
- mali_memory_core_initialize, /* startup */
- NULL, /*mali_memory_core_terminate,*/ /* shutdown */
- mali_memory_core_load_complete, /* load_complete */
- mali_memory_core_system_info_fill, /* system_info_fill */
- mali_memory_core_session_begin, /* session_begin */
- mali_memory_core_session_end, /* session_end */
- NULL, /* broadcast_notification */
-#if MALI_STATE_TRACKING
- NULL, /* dump_state */
-#endif
-};
-
-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*/
-};
-
-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_allocation_engine memory_engine = NULL;
-static mali_physical_memory_allocator * physical_memory_allocators = NULL;
-
-static dedicated_memory_info * mem_region_registrations = NULL;
-
-/* Initialized when this subsystem is initialized. This is determined by the
- * position in subsystems[], and so the value used to initialize this is
- * determined at compile time */
-static mali_kernel_subsystem_identifier mali_subsystem_memory_id = (mali_kernel_subsystem_identifier)-1;
-
-/* called during module init */
-static _mali_osk_errcode_t mali_memory_core_initialize(mali_kernel_subsystem_identifier id)
-{
- MALI_DEBUG_PRINT(2, ("MMU memory system initializing\n"));
-
- /* save our subsystem id for later for use in slot lookup during session activation */
- mali_subsystem_memory_id = id;
-
- _MALI_OSK_INIT_LIST_HEAD(&mmu_head);
-
- MALI_CHECK_NO_ERROR( mali_mmu_page_table_cache_create() );
-
- /* register our handlers */
- MALI_CHECK_NO_ERROR( _mali_kernel_core_register_resource_handler(MMU, mali_memory_core_resource_mmu) );
-
- MALI_CHECK_NO_ERROR( _mali_kernel_core_register_resource_handler(FPGA_FRAMEWORK, mali_memory_core_resource_fpga) );
-
- MALI_CHECK_NO_ERROR( _mali_kernel_core_register_resource_handler(MEMORY, mali_memory_core_resource_dedicated_memory) );
-
- MALI_CHECK_NO_ERROR( _mali_kernel_core_register_resource_handler(OS_MEMORY, mali_memory_core_resource_os_memory) );
-
- 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 */
-static void mali_memory_core_terminate(mali_kernel_subsystem_identifier id)
-{
- mali_kernel_memory_mmu * mmu, *temp_mmu;
-
- MALI_DEBUG_PRINT(2, ("MMU memory system terminating\n"));
-
- /* loop over all MMU units and shut them down */
- _MALI_OSK_LIST_FOREACHENTRY(mmu, temp_mmu, &mmu_head, mali_kernel_memory_mmu, list)
- {
- /* reset to defaults */
- mali_mmu_raw_reset(mmu);
-
- /* unregister the irq */
- _mali_osk_irq_term(mmu->irq);
-
- /* remove from the list of MMU's on the system */
- _mali_osk_list_del(&mmu->list);
-
- /* release resources */
- _mali_osk_mem_unmapioregion(mmu->base, mmu->mapping_size, mmu->mapped_registers);
- _mali_osk_mem_unreqregion(mmu->base, mmu->mapping_size);
- _mali_osk_lock_term(mmu->lock);
- _mali_osk_free(mmu);
- }
-
- /* free global helper pages */
- mali_free_empty_page_directory();
- mali_free_fault_flush_pages();
-
- /* destroy the page table cache before shutting down backends in case we have a page table leak to report */
- 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;
- }
-
-}
-
-static _mali_osk_errcode_t mali_memory_core_session_begin(struct mali_session_data * mali_session_data, mali_kernel_subsystem_session_slot * slot, _mali_osk_notification_queue_t * queue)
-{
- memory_session * session_data;
- _mali_osk_errcode_t err;
- int i;
- mali_io_address pd_mapped;
-
- /* validate input */
- if (NULL == slot)
- {
- MALI_DEBUG_PRINT(1, ("NULL slot given to memory session begin\n"));
- MALI_ERROR(_MALI_OSK_ERR_INVALID_ARGS);
- }
-
- if (NULL != *slot)
- {
- MALI_DEBUG_PRINT(1, ("The slot given to memory session begin already contains data"));
- MALI_ERROR(_MALI_OSK_ERR_INVALID_ARGS);
- }
-
- MALI_DEBUG_PRINT(2, ("MMU session begin\n"));
-
- /* create the session data object */
- session_data = _mali_osk_calloc(1, sizeof(memory_session));
- MALI_CHECK_NON_NULL( session_data, _MALI_OSK_ERR_NOMEM );
-
- /* 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_osk_free(session_data);
- MALI_ERROR(_MALI_OSK_ERR_NOMEM);
- }
-
- err = mali_mmu_get_table_page(&session_data->page_directory, &pd_mapped);
-
- session_data->page_directory_mapped = pd_mapped;
- if (_MALI_OSK_ERR_OK != err)
- {
- mali_descriptor_mapping_destroy(session_data->descriptor_mapping);
- _mali_osk_free(session_data);
- MALI_ERROR(err);
- }
- MALI_DEBUG_ASSERT_POINTER( session_data->page_directory_mapped );
-
- MALI_DEBUG_PRINT(2, ("Page directory for session 0x%x placed at physical address 0x%08X\n", mali_session_data, session_data->page_directory));
-
- for (i = 0; i < MALI_MMU_PAGE_SIZE/4; i++)
- {
- /* mark each page table as not present */
- _mali_osk_mem_iowrite32_relaxed(session_data->page_directory_mapped, sizeof(u32) * i, 0);
- }
- _mali_osk_write_mem_barrier();
-
- /* page_table_mapped[] is already set to NULL by _mali_osk_calloc call */
-
- _MALI_OSK_INIT_LIST_HEAD(&session_data->active_mmus);
- session_data->lock = _mali_osk_lock_init( _MALI_OSK_LOCKFLAG_ORDERED | _MALI_OSK_LOCKFLAG_ONELOCK | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE, 0, 128);
- if (NULL == session_data->lock)
- {
- mali_mmu_release_table_page(session_data->page_directory);
- 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 );
-
- *slot = session_data; /* slot will point to our data object */
- MALI_DEBUG_PRINT(2, ("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(1, ("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);
-}
-
-static void mali_memory_core_session_end(struct mali_session_data * mali_session_data, mali_kernel_subsystem_session_slot * slot)
-{
- memory_session * session_data;
- int i;
- const int num_page_table_entries = sizeof(session_data->page_entries_mapped) / sizeof(session_data->page_entries_mapped[0]);
-
- MALI_DEBUG_PRINT(2, ("MMU session end\n"));
-
- /* validate input */
- if (NULL == slot)
- {
- MALI_DEBUG_PRINT(1, ("NULL slot given to memory session begin\n"));
- return;
- }
-
- session_data = (memory_session *)*slot;
-
- if (NULL == session_data)
- {
- MALI_DEBUG_PRINT(1, ("No session data found during session end\n"));
- return;
- }
- /* Lock the session so we can modify the memory list */
- _mali_osk_lock_wait( session_data->lock, _MALI_OSK_LOCKMODE_RW );
- /* Noninterruptable spinlock type, so must always have locked. Checking should've been done in OSK function. */
-
-#ifndef MALI_UKK_HAS_IMPLICIT_MMAP_CLEANUP
-#if _MALI_OSK_SPECIFIC_INDIRECT_MMAP
-#error Indirect MMAP specified, but UKK does not have implicit MMAP cleanup. Current implementation does not handle this.
-#else
-
- /* Free all memory engine allocations */
- if (0 == _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 = mali_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->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.
- */
- _mali_ukk_mem_munmap_internal( &unmap_args );
- }
- }
-
- /* Assert that we really did free everything */
- MALI_DEBUG_ASSERT( _mali_osk_list_empty(&session_data->memory_head) );
-#endif /* _MALI_OSK_SPECIFIC_INDIRECT_MMAP */
-#endif /* MALI_UKK_HAS_IMPLICIT_MMAP_CLEANUP */
-
- 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;
- }
-
- for (i = 0; i < num_page_table_entries; i++)
- {
- /* free PTE memory */
- if (session_data->page_directory_mapped && (_mali_osk_mem_ioread32(session_data->page_directory_mapped, sizeof(u32)*i) & MALI_MMU_FLAGS_PRESENT))
- {
- mali_mmu_release_table_page( _mali_osk_mem_ioread32(session_data->page_directory_mapped, i*sizeof(u32)) & ~MALI_MMU_FLAGS_MASK);
- _mali_osk_mem_iowrite32(session_data->page_directory_mapped, i * sizeof(u32), 0);
- }
- }
-
- if (MALI_INVALID_PAGE != session_data->page_directory)
- {
- mali_mmu_release_table_page(session_data->page_directory);
- session_data->page_directory = MALI_INVALID_PAGE;
- }
-
- _mali_osk_lock_signal( session_data->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->lock );
- /* free the session data object */
- _mali_osk_free(session_data);
-
- /* clear our slot */
- *slot = NULL;
-
- return;
-}
-
-static _mali_osk_errcode_t mali_allocate_empty_page_directory(void)
-{
- _mali_osk_errcode_t err;
- mali_io_address mapping;
-
- MALI_CHECK_NO_ERROR(mali_mmu_get_table_page(&mali_empty_page_directory, &mapping));
-
- MALI_DEBUG_ASSERT_POINTER( mapping );
-
- err = fill_page(mapping, 0);
- if (_MALI_OSK_ERR_OK != err)
- {
- mali_mmu_release_table_page(mali_empty_page_directory);
- mali_empty_page_directory = MALI_INVALID_PAGE;
- }
- return err;
-}
-
-static void mali_free_empty_page_directory(void)
-{
- if (MALI_INVALID_PAGE != mali_empty_page_directory)
- {
- mali_mmu_release_table_page(mali_empty_page_directory);
- mali_empty_page_directory = 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;
-}
-
-static _mali_osk_errcode_t mali_allocate_fault_flush_pages(void)
-{
- _mali_osk_errcode_t err;
-
- err = mali_mmu_get_table_page(&mali_page_fault_flush_data_page, &mali_page_fault_flush_data_page_mapping);
- if (_MALI_OSK_ERR_OK == err)
- {
- err = mali_mmu_get_table_page(&mali_page_fault_flush_page_table, &mali_page_fault_flush_page_table_mapping);
- if (_MALI_OSK_ERR_OK == err)
- {
- err = mali_mmu_get_table_page(&mali_page_fault_flush_page_directory, &mali_page_fault_flush_page_directory_mapping);
- if (_MALI_OSK_ERR_OK == err)
- {
- fill_page(mali_page_fault_flush_data_page_mapping, 0);
- fill_page(mali_page_fault_flush_page_table_mapping, mali_page_fault_flush_data_page | MALI_MMU_FLAGS_WRITE_PERMISSION | MALI_MMU_FLAGS_READ_PERMISSION | MALI_MMU_FLAGS_PRESENT);
- fill_page(mali_page_fault_flush_page_directory_mapping, mali_page_fault_flush_page_table | MALI_MMU_FLAGS_PRESENT);
- MALI_SUCCESS;
- }
- mali_mmu_release_table_page(mali_page_fault_flush_page_table);
- mali_page_fault_flush_page_table = MALI_INVALID_PAGE;
- mali_page_fault_flush_page_table_mapping = NULL;
- }
- mali_mmu_release_table_page(mali_page_fault_flush_data_page);
- mali_page_fault_flush_data_page = MALI_INVALID_PAGE;
- mali_page_fault_flush_data_page_mapping = NULL;
- }
- MALI_ERROR(err);
-}
-
-static void mali_free_fault_flush_pages(void)
-{
- if (MALI_INVALID_PAGE != mali_page_fault_flush_page_directory)
- {
- mali_mmu_release_table_page(mali_page_fault_flush_page_directory);
- mali_page_fault_flush_page_directory = MALI_INVALID_PAGE;
- }
-
- if (MALI_INVALID_PAGE != mali_page_fault_flush_page_table)
- {
- mali_mmu_release_table_page(mali_page_fault_flush_page_table);
- mali_page_fault_flush_page_table = MALI_INVALID_PAGE;
- }
-
- if (MALI_INVALID_PAGE != mali_page_fault_flush_data_page)
- {
- mali_mmu_release_table_page(mali_page_fault_flush_data_page);
- mali_page_fault_flush_data_page = MALI_INVALID_PAGE;
- }
-}
-
-static _mali_osk_errcode_t mali_memory_core_load_complete(mali_kernel_subsystem_identifier id)
-{
- mali_kernel_memory_mmu * mmu, * temp_mmu;
-
- /* Report the allocators */
- mali_allocation_engine_report_allocators( physical_memory_allocators );
-
- /* allocate the helper pages */
- MALI_CHECK_NO_ERROR( mali_allocate_empty_page_directory() );
- if (_MALI_OSK_ERR_OK != mali_allocate_fault_flush_pages())
- {
- mali_free_empty_page_directory();
- MALI_ERROR(_MALI_OSK_ERR_FAULT);
- }
-
- /* activate the empty page directory on all MMU's */
- _MALI_OSK_LIST_FOREACHENTRY(mmu, temp_mmu, &mmu_head, mali_kernel_memory_mmu, list)
- {
- mali_mmu_register_write(mmu, MALI_MMU_REGISTER_DTE_ADDR, mali_empty_page_directory);
- mali_mmu_enable_paging(mmu);
- }
-
- MALI_DEBUG_PRINT(4, ("MMUs activated\n"));
- /* the MMU system is now active */
-
- MALI_SUCCESS;
-}
-
-static _mali_osk_errcode_t mali_memory_core_system_info_fill(_mali_system_info* info)
-{
- _mali_mem_info * mem_info;
-
- /* Make sure we won't leak any memory. It could also be that it's an
- * uninitialized variable, but the caller should have zeroed the
- * variable. */
- MALI_DEBUG_ASSERT(NULL == info->mem_info);
-
- info->has_mmu = 1;
-
- mem_info = _mali_osk_calloc(1,sizeof(_mali_mem_info));
- MALI_CHECK_NON_NULL( mem_info, _MALI_OSK_ERR_NOMEM );
-
- mem_info->size = 2048UL * 1024UL * 1024UL;
- mem_info->maximum_order_supported = 30;
- mem_info->flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_READABLE | _MALI_PP_WRITEABLE |_MALI_GP_READABLE | _MALI_GP_WRITEABLE;
- mem_info->identifier = 0;
-
- info->mem_info = mem_info;
-
- /* all OK */
- MALI_SUCCESS;
-}
-
-static _mali_osk_errcode_t mali_memory_core_resource_mmu(_mali_osk_resource_t * resource)
-{
- mali_kernel_memory_mmu * mmu;
-
- MALI_DEBUG_PRINT(4, ("MMU '%s' @ (0x%08X - 0x%08X)\n",
- resource->description, resource->base, resource->base + MALI_MMU_REGISTERS_SIZE - 1
- ));
-
- if (NULL != mali_memory_core_mmu_lookup(resource->mmu_id))
- {
- MALI_DEBUG_PRINT(1, ("Duplicate MMU ids found. The id %d is already in use\n", resource->mmu_id));
- MALI_ERROR(_MALI_OSK_ERR_FAULT);
- }
-
- if (_MALI_OSK_ERR_OK != _mali_osk_mem_reqregion(resource->base, MALI_MMU_REGISTERS_SIZE, resource->description))
- {
- /* specified addresses are already in used by another driver / the kernel */
- MALI_DEBUG_PRINT(
- 1, ("Failed to request MMU '%s' register address space at (0x%08X - 0x%08X)\n",
- resource->description, resource->base, resource->base + MALI_MMU_REGISTERS_SIZE - 1
- ));
- MALI_ERROR(_MALI_OSK_ERR_FAULT);
- }
-
- mmu = _mali_osk_calloc(1, sizeof(mali_kernel_memory_mmu));
-
- if (NULL == mmu)
- {
- MALI_DEBUG_PRINT(1, ("Failed to allocate memory for handling a MMU unit"));
- _mali_osk_mem_unreqregion(resource->base, MALI_MMU_REGISTERS_SIZE);
- MALI_ERROR(_MALI_OSK_ERR_NOMEM);
- }
-
- /* basic setup */
- _MALI_OSK_INIT_LIST_HEAD(&mmu->list);
-
- mmu->id = resource->mmu_id;
- mmu->irq_nr = resource->irq;
- mmu->flags = resource->flags;
- mmu->base = resource->base;
- mmu->mapping_size = MALI_MMU_REGISTERS_SIZE;
- mmu->description = resource->description; /* no need to copy */
- _MALI_OSK_INIT_LIST_HEAD(&mmu->callbacks);
- _MALI_OSK_INIT_LIST_HEAD(&mmu->session_link);
- mmu->in_page_fault_handler = 0;
-
- mmu->lock = _mali_osk_lock_init( _MALI_OSK_LOCKFLAG_ORDERED | _MALI_OSK_LOCKFLAG_ONELOCK | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE, 0, 127-mmu->id);
- if (NULL == mmu->lock)
- {
- MALI_DEBUG_PRINT(1, ("Failed to create mmu lock\n"));
- _mali_osk_mem_unreqregion(mmu->base, mmu->mapping_size);
- _mali_osk_free(mmu);
- MALI_ERROR(_MALI_OSK_ERR_FAULT);
- }
-
- /* map the registers */
- mmu->mapped_registers = _mali_osk_mem_mapioregion( mmu->base, mmu->mapping_size, mmu->description );
- if (NULL == mmu->mapped_registers)
- {
- /* failed to map the registers */
- MALI_DEBUG_PRINT(1, ("Failed to map MMU registers at 0x%08X\n", mmu->base));
- _mali_osk_lock_term(mmu->lock);
- _mali_osk_mem_unreqregion(mmu->base, MALI_MMU_REGISTERS_SIZE);
- _mali_osk_free(mmu);
- MALI_ERROR(_MALI_OSK_ERR_FAULT);
- }
-
- MALI_DEBUG_PRINT(4, ("MMU '%s' @ (0x%08X - 0x%08X) mapped to 0x%08X\n",
- resource->description, resource->base, resource->base + MALI_MMU_REGISTERS_SIZE - 1, mmu->mapped_registers
- ));
-
- /* setup MMU interrupt mask */
- /* set all values to known defaults */
- mali_mmu_raw_reset(mmu);
- mali_mmu_register_write(mmu, MALI_MMU_REGISTER_INT_MASK, MALI_MMU_INTERRUPT_PAGE_FAULT | MALI_MMU_INTERRUPT_READ_BUS_ERROR);
- /* setup MMU page directory pointer */
- /* The mali_page_directory pointer is guaranteed to be 4kb aligned because we've used get_zeroed_page to accquire it */
- /* convert the kernel virtual address into a physical address and set */
-
- /* add to our list of MMU's */
- _mali_osk_list_addtail(&mmu->list, &mmu_head);
-
- mmu->irq = _mali_osk_irq_init(
- mmu->irq_nr,
- mali_kernel_memory_mmu_interrupt_handler_upper_half,
- mali_kernel_memory_mmu_interrupt_handler_bottom_half,
- (_mali_osk_irq_trigger_t)mali_mmu_probe_irq_trigger,
- (_mali_osk_irq_ack_t)mali_mmu_probe_irq_acknowledge,
- mmu,
- "mali_mmu_irq_handlers"
- );
- if (NULL == mmu->irq)
- {
- _mali_osk_list_del(&mmu->list);
- _mali_osk_lock_term(mmu->lock);
- _mali_osk_mem_unmapioregion( mmu->base, mmu->mapping_size, mmu->mapped_registers );
- _mali_osk_mem_unreqregion(resource->base, MALI_MMU_REGISTERS_SIZE);
- _mali_osk_free(mmu);
- MALI_ERROR(_MALI_OSK_ERR_FAULT);
- }
-
- /* set to a known state */
- mali_mmu_raw_reset(mmu);
- mali_mmu_register_write(mmu, MALI_MMU_REGISTER_INT_MASK, MALI_MMU_INTERRUPT_PAGE_FAULT | MALI_MMU_INTERRUPT_READ_BUS_ERROR);
-
- MALI_DEBUG_PRINT(2, ("MMU registered\n"));
-
- MALI_SUCCESS;
-}
-
-static _mali_osk_errcode_t mali_memory_core_resource_fpga(_mali_osk_resource_t * resource)
-{
- mali_io_address mapping;
-
- MALI_DEBUG_PRINT(5, ("FPGA framework '%s' @ (0x%08X - 0x%08X)\n",
- resource->description, resource->base, resource->base + sizeof(u32) * 2 - 1
- ));
-
- mapping = _mali_osk_mem_mapioregion(resource->base + 0x1000, sizeof(u32) * 2, "fpga framework");
- if (mapping)
- {
- MALI_DEBUG_CODE(u32 data = )
- _mali_osk_mem_ioread32(mapping, 0);
- MALI_DEBUG_PRINT(2, ("FPGA framwork '%s' @ 0x%08X:\n", resource->description, resource->base));
- MALI_DEBUG_PRINT(2, ("\tBitfile date: %d%02d%02d_%02d%02d\n",
- (data >> 20),
- (data >> 16) & 0xF,
- (data >> 11) & 0x1F,
- (data >> 6) & 0x1F,
- (data >> 0) & 0x3F));
- MALI_DEBUG_CODE(data = )
- _mali_osk_mem_ioread32(mapping, sizeof(u32));
- MALI_DEBUG_PRINT(2, ("\tBitfile SCCS rev: %d\n", data));
-
- _mali_osk_mem_unmapioregion(resource->base + 0x1000, sizeof(u32) *2, mapping);
- }
- else MALI_DEBUG_PRINT(1, ("Failed to access FPGA framwork '%s' @ 0x%08X\n", resource->description, resource->base));
-
- MALI_SUCCESS;
-}
-
-static _mali_osk_errcode_t mali_memory_core_resource_os_memory(_mali_osk_resource_t * resource)
-{
- mali_physical_memory_allocator * allocator;
- mali_physical_memory_allocator ** next_allocator_list;
-
- u32 alloc_order = resource->alloc_order;
-
- allocator = mali_os_allocator_create(resource->size, resource->cpu_usage_adjust, resource->description);
- 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;
-}
-
-static _mali_osk_errcode_t mali_memory_core_resource_dedicated_memory(_mali_osk_resource_t * resource)
-{
- mali_physical_memory_allocator * allocator;
- mali_physical_memory_allocator ** next_allocator_list;
- dedicated_memory_info * cleanup_data;
-
- u32 alloc_order = resource->alloc_order;
-
- /* do the lowlevel linux operation first */
-
- /* Request ownership of the memory */
- if (_MALI_OSK_ERR_OK != _mali_osk_mem_reqregion(resource->base, resource->size, resource->description))
- {
- MALI_DEBUG_PRINT(1, ("Failed to request memory region %s (0x%08X - 0x%08X)\n", resource->description, resource->base, resource->base + resource->size - 1));
- MALI_ERROR(_MALI_OSK_ERR_FAULT);
- }
-
- /* create generic block allocator object to handle it */
- allocator = mali_block_allocator_create(resource->base, resource->cpu_usage_adjust, resource->size, resource->description );
-
- if (NULL == allocator)
- {
- MALI_DEBUG_PRINT(1, ("Memory bank registration failed\n"));
- _mali_osk_mem_unreqregion(resource->base, resource->size);
- MALI_ERROR(_MALI_OSK_ERR_FAULT);
- }
-
- /* save lowlevel cleanup info */
- allocator->alloc_order = alloc_order;
-
- cleanup_data = _mali_osk_malloc(sizeof(dedicated_memory_info));
-
- if (NULL == cleanup_data)
- {
- _mali_osk_mem_unreqregion(resource->base, resource->size);
- allocator->destroy(allocator);
- MALI_ERROR(_MALI_OSK_ERR_FAULT);
- }
-
- cleanup_data->base = resource->base;
- cleanup_data->size = resource->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;
-}
-
-static _mali_osk_errcode_t mali_kernel_memory_mmu_interrupt_handler_upper_half(void * data)
-{
- mali_kernel_memory_mmu * mmu;
- u32 int_stat;
- mali_core_renderunit *core;
-
- if (mali_benchmark) MALI_SUCCESS;
-
- mmu = (mali_kernel_memory_mmu *)data;
-
- MALI_DEBUG_ASSERT_POINTER(mmu);
-
- /* Pointer to core holding this MMU */
- core = (mali_core_renderunit *)mmu->core;
- if(core && (CORE_OFF == core->state))
- {
- MALI_SUCCESS;
- }
-
-
- /* check if it was our device which caused the interrupt (we could be sharing the IRQ line) */
- int_stat = mali_mmu_register_read(mmu, MALI_MMU_REGISTER_INT_STATUS);
- if (0 == int_stat)
- {
- MALI_ERROR(_MALI_OSK_ERR_FAULT); /* no bits set, we are sharing the IRQ line and someone else caused the interrupt */
- }
-
-
- mali_mmu_register_write(mmu, MALI_MMU_REGISTER_INT_MASK, 0);
-
- mali_mmu_register_read(mmu, MALI_MMU_REGISTER_STATUS);
-
- if (int_stat & MALI_MMU_INTERRUPT_PAGE_FAULT)
- {
- _mali_osk_irq_schedulework(mmu->irq);
- }
- if (int_stat & MALI_MMU_INTERRUPT_READ_BUS_ERROR)
- {
- /* clear interrupt flag */
- mali_mmu_register_write(mmu, MALI_MMU_REGISTER_INT_CLEAR, MALI_MMU_INTERRUPT_READ_BUS_ERROR);
- /* reenable it */
- mali_mmu_register_write(mmu, MALI_MMU_REGISTER_INT_MASK, mali_mmu_register_read(mmu, MALI_MMU_REGISTER_INT_MASK) | MALI_MMU_INTERRUPT_READ_BUS_ERROR);
- }
-
- MALI_SUCCESS;
-}
-
-
-static void mali_kernel_mmu_bus_reset(mali_kernel_memory_mmu * mmu)
-{
-
-#if defined(USING_MALI200)
- int i;
- const int replay_buffer_check_interval = 10; /* must be below 1000 */
- const int replay_buffer_max_number_of_checks = 100;
-#endif
-
- _mali_osk_lock_wait(mmu->lock, _MALI_OSK_LOCKMODE_RW);
- /* add an extra reference while handling the page fault */
- mmu->usage_count++;
- _mali_osk_lock_signal(mmu->lock, _MALI_OSK_LOCKMODE_RW);
-
- MALI_DEBUG_PRINT(4, ("Sending stop bus request to cores\n"));
- /* request to stop the bus, but don't wait for it to actually stop */
- _mali_kernel_core_broadcast_subsystem_message(MMU_KILL_STEP1_STOP_BUS_FOR_ALL_CORES, (u32)mmu);
-
-#if defined(USING_MALI200)
- /* no new request will come from any of the connected cores from now
- * we must now flush the playback buffer for any requests queued already
- */
-
- _mali_osk_lock_wait(mmu->lock, _MALI_OSK_LOCKMODE_RW);
-
- MALI_DEBUG_PRINT(4, ("Switching to the special page fault flush page directory\n"));
- /* don't use the mali_mmu_activate_address_space function here as we can't stall the MMU */
- mali_mmu_register_write(mmu, MALI_MMU_REGISTER_DTE_ADDR, mali_page_fault_flush_page_directory);
- mali_mmu_register_write(mmu, MALI_MMU_REGISTER_COMMAND, MALI_MMU_COMMAND_ZAP_CACHE);
- /* resume the MMU */
- mali_mmu_register_write(mmu, MALI_MMU_REGISTER_INT_CLEAR, MALI_MMU_INTERRUPT_PAGE_FAULT);
- mali_mmu_register_write(mmu, MALI_MMU_REGISTER_COMMAND, MALI_MMU_COMMAND_PAGE_FAULT_DONE);
- /* the MMU will now play back all the requests, all going to our special page fault flush data page */
-
- /* just to be safe, check that the playback buffer is empty before continuing */
- if (!mali_benchmark) {
- for (i = 0; i < replay_buffer_max_number_of_checks; i++)
- {
- if (mali_mmu_register_read(mmu, MALI_MMU_REGISTER_STATUS) & MALI_MMU_STATUS_BIT_REPLAY_BUFFER_EMPTY) break;
- _mali_osk_time_ubusydelay(replay_buffer_check_interval);
- }
-
- MALI_DEBUG_PRINT_IF(1, i == replay_buffer_max_number_of_checks, ("MMU: %s: Failed to flush replay buffer on page fault\n", mmu->description));
- MALI_DEBUG_PRINT(1, ("Replay playback took %ld usec\n", i * replay_buffer_check_interval));
- }
-
- _mali_osk_lock_signal(mmu->lock, _MALI_OSK_LOCKMODE_RW);
-
-#endif
- /* notify all subsystems that the core should be reset once the bus is actually stopped */
- MALI_DEBUG_PRINT(4,("Sending job abort command to subsystems\n"));
- _mali_kernel_core_broadcast_subsystem_message(MMU_KILL_STEP2_RESET_ALL_CORES_AND_ABORT_THEIR_JOBS, (u32)mmu);
-
- _mali_osk_lock_wait(mmu->lock, _MALI_OSK_LOCKMODE_RW);
-
- /* reprogram the MMU */
- mali_mmu_raw_reset(mmu);
- mali_mmu_register_write(mmu, MALI_MMU_REGISTER_INT_MASK, MALI_MMU_INTERRUPT_PAGE_FAULT | MALI_MMU_INTERRUPT_READ_BUS_ERROR);
- mali_mmu_register_write(mmu, MALI_MMU_REGISTER_DTE_ADDR, mali_empty_page_directory); /* no session is active, so just activate the empty page directory */
- mali_mmu_enable_paging(mmu);
-
- _mali_osk_lock_signal(mmu->lock, _MALI_OSK_LOCKMODE_RW);
-
- /* release the extra address space reference, will schedule */
- mali_memory_core_mmu_release_address_space_reference(mmu);
-
- /* resume normal operation */
- _mali_kernel_core_broadcast_subsystem_message(MMU_KILL_STEP3_CONTINUE_JOB_HANDLING, (u32)mmu);
- MALI_DEBUG_PRINT(4, ("Page fault handling complete\n"));
-}
-
-static void mali_mmu_raw_reset(mali_kernel_memory_mmu * mmu)
-{
- const int max_loop_count = 100;
- const int delay_in_usecs = 1;
-
- mali_mmu_register_write(mmu, MALI_MMU_REGISTER_DTE_ADDR, 0xCAFEBABE);
- mali_mmu_register_write(mmu, MALI_MMU_REGISTER_COMMAND, MALI_MMU_COMMAND_SOFT_RESET);
-
- if (!mali_benchmark)
- {
- int i;
- for (i = 0; i < max_loop_count; ++i)
- {
- if (mali_mmu_register_read(mmu, MALI_MMU_REGISTER_DTE_ADDR) == 0)
- {
- break;
- }
- _mali_osk_time_ubusydelay(delay_in_usecs);
- }
- MALI_DEBUG_PRINT_IF(1, (max_loop_count == i), ("Reset request failed, MMU status is 0x%08X\n", mali_mmu_register_read(mmu, MALI_MMU_REGISTER_STATUS)));
- }
-}
-
-static void mali_mmu_enable_paging(mali_kernel_memory_mmu * mmu)
-{
- const int max_loop_count = 100;
- const int delay_in_usecs = 1;
-
- mali_mmu_register_write(mmu, MALI_MMU_REGISTER_COMMAND, MALI_MMU_COMMAND_ENABLE_PAGING);
-
- if (!mali_benchmark)
- {
- int i;
- for (i = 0; i < max_loop_count; ++i)
- {
- if (mali_mmu_register_read(mmu, MALI_MMU_REGISTER_STATUS) & MALI_MMU_STATUS_BIT_PAGING_ENABLED)
- {
- break;
- }
- _mali_osk_time_ubusydelay(delay_in_usecs);
- }
- MALI_DEBUG_PRINT_IF(1, (max_loop_count == i), ("Enable paging request failed, MMU status is 0x%08X\n", mali_mmu_register_read(mmu, MALI_MMU_REGISTER_STATUS)));
- }
-}
-
-static mali_bool mali_mmu_enable_stall(mali_kernel_memory_mmu * mmu)
-{
- const int max_loop_count = 100;
- const int delay_in_usecs = 999;
- int i;
-
- mali_mmu_register_write(mmu, MALI_MMU_REGISTER_COMMAND, MALI_MMU_COMMAND_ENABLE_STALL);
-
- if (!mali_benchmark)
- {
- for (i = 0; i < max_loop_count; ++i)
- {
- if (mali_mmu_register_read(mmu, MALI_MMU_REGISTER_STATUS) & MALI_MMU_STATUS_BIT_STALL_ACTIVE)
- {
- break;
- }
- _mali_osk_time_ubusydelay(delay_in_usecs);
- }
- MALI_DEBUG_PRINT_IF(1, (max_loop_count == i), ("Enable stall request failed, MMU status is 0x%08X\n", mali_mmu_register_read(mmu, MALI_MMU_REGISTER_STATUS)));
- if (max_loop_count == i)
- {
- return MALI_FALSE;
- }
- }
-
- return MALI_TRUE;
-}
-
-static void mali_mmu_disable_stall(mali_kernel_memory_mmu * mmu)
-{
- const int max_loop_count = 100;
- const int delay_in_usecs = 1;
- int i;
-
- mali_mmu_register_write(mmu, MALI_MMU_REGISTER_COMMAND, MALI_MMU_COMMAND_DISABLE_STALL);
-
- if (!mali_benchmark)
- {
- for (i = 0; i < max_loop_count; ++i)
- {
- if ((mali_mmu_register_read(mmu, MALI_MMU_REGISTER_STATUS) & MALI_MMU_STATUS_BIT_STALL_ACTIVE) == 0)
- {
- break;
- }
- _mali_osk_time_ubusydelay(delay_in_usecs);
- }
- MALI_DEBUG_PRINT_IF(1, (max_loop_count == i), ("Disable stall request failed, MMU status is 0x%08X\n", mali_mmu_register_read(mmu, MALI_MMU_REGISTER_STATUS)));
- }
-}
-
-void mali_kernel_mmu_reset(void * input_mmu)
-{
- mali_kernel_memory_mmu * mmu;
- MALI_DEBUG_ASSERT_POINTER(input_mmu);
- mmu = (mali_kernel_memory_mmu *)input_mmu;
-
- MALI_DEBUG_PRINT(4, ("Mali MMU: mali_kernel_mmu_reset: %s\n", mmu->description));
-
- if ( 0 != mmu->in_page_fault_handler)
- {
- /* This is possible if the bus can never be stopped for some reason */
- MALI_PRINT_ERROR(("Stopping the Memory bus not possible. Mali reset could not be performed."));
- return;
- }
- _mali_osk_lock_wait(mmu->lock, _MALI_OSK_LOCKMODE_RW);
- mali_mmu_raw_reset(mmu);
- mali_mmu_register_write(mmu, MALI_MMU_REGISTER_INT_MASK, MALI_MMU_INTERRUPT_PAGE_FAULT | MALI_MMU_INTERRUPT_READ_BUS_ERROR);
- mali_mmu_register_write(mmu, MALI_MMU_REGISTER_DTE_ADDR, mali_empty_page_directory); /* no session is active, so just activate the empty page directory */
- mali_mmu_enable_paging(mmu);
- _mali_osk_lock_signal(mmu->lock, _MALI_OSK_LOCKMODE_RW);
-
-}
-
-void mali_kernel_mmu_force_bus_reset(void * input_mmu)
-{
- mali_kernel_memory_mmu * mmu;
- MALI_DEBUG_ASSERT_POINTER(input_mmu);
- mmu = (mali_kernel_memory_mmu *)input_mmu;
- if ( 0 != mmu->in_page_fault_handler)
- {
- /* This is possible if the bus can never be stopped for some reason */
- MALI_PRINT_ERROR(("Stopping the Memory bus not possible. Mali reset could not be performed."));
- return;
- }
- MALI_DEBUG_PRINT(1, ("Mali MMU: Force_bus_reset.\n"));
- mali_mmu_register_write(mmu, MALI_MMU_REGISTER_INT_MASK, 0);
- mali_kernel_mmu_bus_reset(mmu);
-}
-
-
-static void mali_kernel_memory_mmu_interrupt_handler_bottom_half(void * data)
-{
- mali_kernel_memory_mmu * mmu;
- u32 raw, fault_address, status;
- mali_core_renderunit *core;
-
- MALI_DEBUG_PRINT(1, ("mali_kernel_memory_mmu_interrupt_handler_bottom_half\n"));
- if (NULL == data)
- {
- MALI_PRINT_ERROR(("MMU IRQ work queue: NULL argument"));
- return; /* Error */
- }
- mmu = (mali_kernel_memory_mmu*)data;
-
- MALI_DEBUG_PRINT(4, ("Locking subsystems\n"));
- /* lock all subsystems */
- _mali_kernel_core_broadcast_subsystem_message(MMU_KILL_STEP0_LOCK_SUBSYSTEM, (u32)mmu);
-
- /* Pointer to core holding this MMU */
- core = (mali_core_renderunit *)mmu->core;
-
- if(CORE_OFF == core->state)
- {
- _mali_kernel_core_broadcast_subsystem_message(MMU_KILL_STEP4_UNLOCK_SUBSYSTEM, (u32)mmu);
- return;
- }
-
- raw = mali_mmu_register_read(mmu, MALI_MMU_REGISTER_INT_RAWSTAT);
- status = mali_mmu_register_read(mmu, MALI_MMU_REGISTER_STATUS);
-
- if ( (0==(raw & MALI_MMU_INTERRUPT_PAGE_FAULT)) && (0==(status & MALI_MMU_STATUS_BIT_PAGE_FAULT_ACTIVE)) )
- {
- MALI_DEBUG_PRINT(1, ("MMU: Page fault bottom half: No Irq found.\n"));
- MALI_DEBUG_PRINT(4, ("Unlocking subsystems"));
- _mali_kernel_core_broadcast_subsystem_message(MMU_KILL_STEP4_UNLOCK_SUBSYSTEM, (u32)mmu);
- return;
- }
-
- mmu->in_page_fault_handler = 1;
-
- fault_address = mali_mmu_register_read(mmu, MALI_MMU_REGISTER_PAGE_FAULT_ADDR);
- MALI_PRINT(("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->description)
- );
-
- if (NULL == mmu->active_session)
- {
- MALI_PRINT(("Spurious memory access detected from MMU %s\n", mmu->description));
- }
- else
- {
- MALI_PRINT(("Active page directory at 0x%08X\n", mmu->active_session->page_directory));
- MALI_PRINT(("Info from page table for VA 0x%x:\n", (void*)fault_address));
- MALI_PRINT(("DTE entry: PTE at 0x%x marked as %s\n",
- (void*)(_mali_osk_mem_ioread32(mmu->active_session->page_directory_mapped,
- MALI_MMU_PDE_ENTRY(fault_address) * sizeof(u32)) & ~MALI_MMU_FLAGS_MASK),
- _mali_osk_mem_ioread32(mmu->active_session->page_directory_mapped,
- MALI_MMU_PDE_ENTRY(fault_address) * sizeof(u32)) & MALI_MMU_FLAGS_PRESENT ? "present" : "not present"
- ));
-
- if (_mali_osk_mem_ioread32(mmu->active_session->page_directory_mapped, MALI_MMU_PDE_ENTRY(fault_address) * sizeof(u32)) & MALI_MMU_FLAGS_PRESENT)
- {
- mali_io_address pte;
- u32 data;
- pte = mmu->active_session->page_entries_mapped[MALI_MMU_PDE_ENTRY(fault_address)];
- data = _mali_osk_mem_ioread32(pte, MALI_MMU_PTE_ENTRY(fault_address) * sizeof(u32));
- MALI_PRINT(("PTE entry: Page at 0x%x, %s %s %s\n",
- (void*)(data & ~MALI_MMU_FLAGS_MASK),
- data & MALI_MMU_FLAGS_PRESENT ? "present" : "not present",
- data & MALI_MMU_FLAGS_READ_PERMISSION ? "readable" : "",
- data & MALI_MMU_FLAGS_WRITE_PERMISSION ? "writable" : ""
- ));
- }
- else
- {
- MALI_PRINT(("PTE entry: Not present\n"));
- }
- }
-
-
- mali_kernel_mmu_bus_reset(mmu);
-
- mmu->in_page_fault_handler = 0;
-
- /* unlock all subsystems */
- MALI_DEBUG_PRINT(4, ("Unlocking subsystems"));
- _mali_kernel_core_broadcast_subsystem_message(MMU_KILL_STEP4_UNLOCK_SUBSYSTEM, (u32)mmu);
-
-}
-
-
-static u32 mali_mmu_register_read(mali_kernel_memory_mmu * unit, mali_mmu_register reg)
-{
- u32 val;
-
- if (mali_benchmark) return 0;
-
- val = _mali_osk_mem_ioread32(unit->mapped_registers, (u32)reg * sizeof(u32));
-
- MALI_DEBUG_PRINT(6, ("mali_mmu_register_read addr:0x%04X val:0x%08x\n", (u32)reg * sizeof(u32),val));
-
- return val;
-}
-
-static void mali_mmu_register_write(mali_kernel_memory_mmu * unit, mali_mmu_register reg, u32 val)
-{
- if (mali_benchmark) return;
-
- MALI_DEBUG_PRINT(6, ("mali_mmu_register_write addr:0x%04X val:0x%08x\n", (u32)reg * sizeof(u32), val));
-
- _mali_osk_mem_iowrite32(unit->mapped_registers, (u32)reg * sizeof(u32), val);
-}
-
-#if MALI_USE_UNIFIED_MEMORY_PROVIDER != 0
-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;
- memory_session * 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 = (memory_session *)mali_kernel_session_manager_slot_get(args->ctx, mali_subsystem_memory_id);
- 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->lock = session_data->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->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->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->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;
- memory_session * session_data;
-
- MALI_DEBUG_ASSERT_POINTER(args);
- MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS);
-
- session_data = (memory_session *)mali_kernel_session_manager_slot_get(args->ctx, mali_subsystem_memory_id);
- 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);
- }
-
- mali_descriptor_mapping_free(session_data->descriptor_mapping, args->cookie);
-
- _mali_osk_lock_wait( session_data->lock, _MALI_OSK_LOCKMODE_RW );
-
- mali_allocation_engine_release_memory(memory_engine, descriptor);
-
- _mali_osk_lock_signal( session_data->lock, _MALI_OSK_LOCKMODE_RW );
-
- _mali_osk_free(descriptor);
-
- MALI_SUCCESS;
-
-}
-#endif /* MALI_USE_UNIFIED_MEMORY_PROVIDER != 0 */
-
-
-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(3, ("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_map_external_mem( _mali_uk_map_external_mem_s *args )
-{
- mali_physical_memory_allocator external_memory_allocator;
- memory_session * 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 = (memory_session *)mali_kernel_session_manager_slot_get(args->ctx, mali_subsystem_memory_id);
- 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 */
- MALI_CHECK_NO_ERROR( mali_kernel_core_validate_mali_phys_range( args->phys_addr, args->size ) );
-
- 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->lock = session_data->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))
- {
- _mali_osk_free(descriptor);
- MALI_ERROR(_MALI_OSK_ERR_FAULT);
- }
-
- _mali_osk_lock_wait(session_data->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->lock, _MALI_OSK_LOCKMODE_RW);
- mali_descriptor_mapping_free(session_data->descriptor_mapping, md);
- _mali_osk_free(descriptor);
- MALI_ERROR(_MALI_OSK_ERR_NOMEM);
- }
-
- _mali_osk_lock_signal(session_data->lock, _MALI_OSK_LOCKMODE_RW);
-
- 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;
- memory_session * session_data;
-
- MALI_DEBUG_ASSERT_POINTER(args);
- MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS);
-
- session_data = (memory_session *)mali_kernel_session_manager_slot_get(args->ctx, mali_subsystem_memory_id);
- 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);
- }
-
- mali_descriptor_mapping_free(session_data->descriptor_mapping, args->cookie);
-
- _mali_osk_lock_wait( session_data->lock, _MALI_OSK_LOCKMODE_RW );
-
- mali_allocation_engine_release_memory(memory_engine, descriptor);
-
- _mali_osk_lock_signal( session_data->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;
-}
-
-_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, 110);
- 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;
-}
-
-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, 0 == _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);
-}
-
-_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 (0 == _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);
- }
-
- /* clear memory allocation */
- fill_page(alloc->pages.mapping, 0);
-
- _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 for 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);
-}
-
-void* mali_memory_core_mmu_lookup(u32 id)
-{
- mali_kernel_memory_mmu * mmu, * temp_mmu;
-
- /* find an MMU with a matching id */
- _MALI_OSK_LIST_FOREACHENTRY(mmu, temp_mmu, &mmu_head, mali_kernel_memory_mmu, list)
- {
- if (id == mmu->id) return mmu;
- }
-
- /* not found */
- return NULL;
-}
-
-void mali_memory_core_mmu_owner(void *core, void *mmu_ptr)
-{
- mali_kernel_memory_mmu *mmu;
-
- MALI_DEBUG_ASSERT_POINTER(mmu_ptr);
- MALI_DEBUG_ASSERT_POINTER(core);
-
- mmu = (mali_kernel_memory_mmu *)mmu_ptr;
- mmu->core = core;
-}
-
-void mali_mmu_activate_address_space(mali_kernel_memory_mmu * mmu, u32 page_directory)
-{
- mali_mmu_enable_stall(mmu); /* this might fail, but changing the DTE address and ZAP should work anyway... */
- mali_mmu_register_write(mmu, MALI_MMU_REGISTER_DTE_ADDR, page_directory);
- mali_mmu_register_write(mmu, MALI_MMU_REGISTER_COMMAND, MALI_MMU_COMMAND_ZAP_CACHE);
- mali_mmu_disable_stall(mmu);
-}
-
-_mali_osk_errcode_t mali_memory_core_mmu_activate_page_table(void* mmu_ptr, struct mali_session_data * mali_session_data, void(*callback)(void*), void * callback_argument)
-{
- memory_session * requested_memory_session;
- _mali_osk_errcode_t err = _MALI_OSK_ERR_FAULT;
- mali_kernel_memory_mmu * mmu;
-
- MALI_DEBUG_ASSERT_POINTER(mmu_ptr);
- MALI_DEBUG_ASSERT_POINTER(mali_session_data);
-
- mmu = (mali_kernel_memory_mmu *)mmu_ptr;
-
- MALI_DEBUG_PRINT(4, ("Asked to activate page table for session 0x%x on MMU %s\n", mali_session_data, mmu->description));
- requested_memory_session = mali_kernel_session_manager_slot_get(mali_session_data, mali_subsystem_memory_id);
- MALI_DEBUG_PRINT(5, ("Session 0x%x looked up as using memory session 0x%x\n", mali_session_data, requested_memory_session));
-
- MALI_DEBUG_ASSERT_POINTER(requested_memory_session);
-
- MALI_DEBUG_PRINT(7, ("Taking locks\n"));
-
- _mali_osk_lock_wait(requested_memory_session->lock, _MALI_OSK_LOCKMODE_RW);
- _mali_osk_lock_wait(mmu->lock, _MALI_OSK_LOCKMODE_RW);
- if (0 == mmu->usage_count)
- {
- /* no session currently active, activate the requested session */
- MALI_DEBUG_ASSERT(NULL == mmu->active_session);
- mmu->active_session = requested_memory_session;
- mmu->usage_count = 1;
- MALI_DEBUG_PRINT(4, ("MMU idle, activating page directory 0x%08X on MMU %s\n", requested_memory_session->page_directory, mmu->description));
- mali_mmu_activate_address_space(mmu, requested_memory_session->page_directory);
- {
- /* Insert mmu into the right place in the active_mmus list so that
- * it is still sorted. The list must be sorted by ID so we can get
- * the mutexes in the right order in
- * _mali_ukk_mem_munmap_internal().
- */
- _mali_osk_list_t *entry;
- for (entry = requested_memory_session->active_mmus.next;
- entry != &requested_memory_session->active_mmus;
- entry = entry->next)
- {
- mali_kernel_memory_mmu *temp = _MALI_OSK_LIST_ENTRY(entry, mali_kernel_memory_mmu, session_link);
- if (mmu->id < temp->id)
- break;
- }
- /* If we broke out, then 'entry' points to the list node of the
- * first mmu with a greater ID; otherwise, it points to
- * active_mmus. We want to add *before* this node.
- */
- _mali_osk_list_addtail(&mmu->session_link, entry);
- }
- err = _MALI_OSK_ERR_OK;
- }
-
- /* Allow two cores to run in parallel if they come from the same session */
- else if (
- (mmu->in_page_fault_handler == 0) &&
- (requested_memory_session == mmu->active_session ) &&
- (0==(MALI_MMU_DISALLOW_PARALLELL_WORK_OF_MALI_CORES & mmu->flags))
- )
- {
- /* nested activation detected, just update the reference count */
- MALI_DEBUG_PRINT(4, ("Nested activation detected, %d previous activations found\n", mmu->usage_count));
- mmu->usage_count++;
- err = _MALI_OSK_ERR_OK;
- }
-
- else if (NULL != callback)
- {
- /* can't activate right now, notify caller on idle via callback */
- mali_kernel_memory_mmu_idle_callback * callback_object, * temp_callback_object;
- int found = 0;
-
- MALI_DEBUG_PRINT(3, ("The MMU is busy and is using a different address space, callback given\n"));
- /* check for existing registration */
- _MALI_OSK_LIST_FOREACHENTRY(callback_object, temp_callback_object, &mmu->callbacks, mali_kernel_memory_mmu_idle_callback, link)
- {
- if (callback_object->callback == callback)
- {
- found = 1;
- break;
- }
- }
-
- if (found)
- {
- MALI_DEBUG_PRINT(5, ("Duplicate callback registration found, ignoring\n"));
- /* callback already registered */
- err = _MALI_OSK_ERR_BUSY;
- }
- else
- {
- MALI_DEBUG_PRINT(5,("New callback, registering\n"));
- /* register the new callback */
- callback_object = _mali_osk_malloc(sizeof(mali_kernel_memory_mmu_idle_callback));
- if (NULL != callback_object)
- {
- MALI_DEBUG_PRINT(7,("Callback struct setup\n"));
- callback_object->callback = callback;
- callback_object->callback_argument = callback_argument;
- _mali_osk_list_addtail(&callback_object->link, &mmu->callbacks);
- err = _MALI_OSK_ERR_BUSY;
- }
- }
- }
-
- _mali_osk_lock_signal(mmu->lock, _MALI_OSK_LOCKMODE_RW);
- _mali_osk_lock_signal(requested_memory_session->lock, _MALI_OSK_LOCKMODE_RW);
-
- MALI_ERROR(err);
-}
-
-void mali_memory_core_mmu_release_address_space_reference(void* mmu_ptr)
-{
- mali_kernel_memory_mmu_idle_callback * callback_object, * temp;
- mali_kernel_memory_mmu * mmu;
- memory_session * session;
-
- _MALI_OSK_LIST_HEAD(callbacks);
-
- MALI_DEBUG_ASSERT_POINTER(mmu_ptr);
- mmu = (mali_kernel_memory_mmu *)mmu_ptr;
-
- session = mmu->active_session;
-
- /* support that we handle spurious page faults */
- if (NULL != session)
- {
- _mali_osk_lock_wait(session->lock, _MALI_OSK_LOCKMODE_RW);
- }
-
- _mali_osk_lock_wait(mmu->lock, _MALI_OSK_LOCKMODE_RW);
- MALI_DEBUG_PRINT(4, ("Deactivation of address space on MMU %s, %d references exists\n", mmu->description, mmu->usage_count));
- MALI_DEBUG_ASSERT(0 != mmu->usage_count);
- mmu->usage_count--;
- if (0 != mmu->usage_count)
- {
- MALI_DEBUG_PRINT(4, ("MMU still in use by this address space, %d references still exists\n", mmu->usage_count));
- _mali_osk_lock_signal(mmu->lock, _MALI_OSK_LOCKMODE_RW);
- /* support that we handle spurious page faults */
- if (NULL != session)
- {
- _mali_osk_lock_signal(session->lock, _MALI_OSK_LOCKMODE_RW);
- }
- return;
- }
-
- MALI_DEBUG_PRINT(4, ("Activating the empty page directory on %s\n", mmu->description));
-
- /* last reference gone, deactivate current address space */
- mali_mmu_activate_address_space(mmu, mali_empty_page_directory);
-
- /* unlink from session */
- _mali_osk_list_delinit(&mmu->session_link);
- /* remove the active session pointer */
- mmu->active_session = NULL;
-
- /* Notify all registered callbacks.
- * We have to be clever here:
- * We must call the callbacks with the spinlock unlocked and
- * the callback list emptied to allow them to re-register.
- * So we make a copy of the list, clears the list and then later call the callbacks on the local copy
- */
- /* copy list */
- _MALI_OSK_INIT_LIST_HEAD(&callbacks);
- _mali_osk_list_splice(&mmu->callbacks, &callbacks);
- /* clear the original, allowing new registrations during the callback */
- _MALI_OSK_INIT_LIST_HEAD(&mmu->callbacks);
-
- /* end of mmu manipulation, so safe to unlock */
- _mali_osk_lock_signal(mmu->lock, _MALI_OSK_LOCKMODE_RW);
-
- /* then finally remove the (possible) session lock, supporting that no session was active (spurious page fault handling) */
- if (NULL != session)
- {
- _mali_osk_lock_signal(session->lock, _MALI_OSK_LOCKMODE_RW);
- }
-
- _MALI_OSK_LIST_FOREACHENTRY(callback_object, temp, &callbacks, mali_kernel_memory_mmu_idle_callback, link)
- {
- MALI_DEBUG_ASSERT_POINTER(callback_object->callback);
- (callback_object->callback)(callback_object->callback_argument);
- _mali_osk_list_del(&callback_object->link);
- _mali_osk_free(callback_object);
- }
-}
-
-void mali_memory_core_mmu_unregister_callback(void* mmu_ptr, void(*callback)(void*))
-{
- mali_kernel_memory_mmu_idle_callback * callback_object, * temp_callback_object;
- mali_kernel_memory_mmu * mmu;
- MALI_DEBUG_ASSERT_POINTER(mmu_ptr);
-
- MALI_DEBUG_ASSERT_POINTER(callback);
- MALI_DEBUG_ASSERT_POINTER(mmu_ptr);
-
- mmu = (mali_kernel_memory_mmu *)mmu_ptr;
-
- _mali_osk_lock_wait(mmu->lock, _MALI_OSK_LOCKMODE_RW);
- _MALI_OSK_LIST_FOREACHENTRY(callback_object, temp_callback_object, &mmu->callbacks, mali_kernel_memory_mmu_idle_callback, link)
- {
- MALI_DEBUG_ASSERT_POINTER(callback_object->callback);
- if (callback_object->callback == callback)
- {
- _mali_osk_list_del(&callback_object->link);
- _mali_osk_free(callback_object);
- break;
- }
- }
- _mali_osk_lock_signal(mmu->lock, _MALI_OSK_LOCKMODE_RW);
-}
-
-static _mali_osk_errcode_t mali_address_manager_allocate(mali_memory_allocation * descriptor)
-{
- /* allocate page tables, if needed */
- int i;
- const int first_pde_idx = MALI_MMU_PDE_ENTRY(descriptor->mali_address);
- int last_pde_idx;
- memory_session * session_data;
-#if defined USING_MALI400_L2_CACHE
- int has_active_mmus = 0;
- int page_dir_updated = 0;
-#endif
-
-
- if (descriptor->flags & MALI_MEMORY_ALLOCATION_FLAG_MAP_GUARD_PAGE)
- {
- last_pde_idx = MALI_MMU_PDE_ENTRY(descriptor->mali_address + _MALI_OSK_MALI_PAGE_SIZE + descriptor->size - 1);
- }
- else
- {
- last_pde_idx = MALI_MMU_PDE_ENTRY(descriptor->mali_address + descriptor->size - 1);
- }
-
- session_data = (memory_session*)descriptor->mali_addr_mapping_info;
- MALI_DEBUG_ASSERT_POINTER(session_data);
-
- MALI_DEBUG_PRINT(4, ("allocating page tables for Mali virtual address space 0x%08X to 0x%08X\n", descriptor->mali_address, descriptor->mali_address + descriptor->size - 1));
-
-#if defined USING_MALI400_L2_CACHE
- if (0 == _mali_osk_list_empty(&session_data->active_mmus))
- {
- /*
- * We have active MMUs, so we are probably in the process of alocating more memory for a suspended GP job (PLBU heap)
- * From Mali-400 MP r1p0, MMU page directory/tables are also cached by the Mali L2 cache, thus we need to invalidate the page directory
- * from the L2 cache if we add new page directory entries (PDEs) to the page directory.
- * We only need to do this when we have an active MMU, because we otherwise invalidate the entire Mali L2 cache before at job start
- */
- has_active_mmus = 1;
- }
-#endif
-
- for (i = first_pde_idx; i <= last_pde_idx; i++)
- {
- if ( 0 == (_mali_osk_mem_ioread32(session_data->page_directory_mapped, i * sizeof(u32)) & MALI_MMU_FLAGS_PRESENT) )
- {
- u32 pte_phys;
- mali_io_address pte_mapped;
- _mali_osk_errcode_t err;
-
- /* allocate a new page table */
- MALI_DEBUG_ASSERT(0 == session_data->page_entries_usage_count[i]);
- MALI_DEBUG_ASSERT(NULL == session_data->page_entries_mapped[i]);
-
- err = mali_mmu_get_table_page(&pte_phys, &pte_mapped);
- if (_MALI_OSK_ERR_OK == err)
- {
- session_data->page_entries_mapped[i] = pte_mapped;
- MALI_DEBUG_ASSERT_POINTER( session_data->page_entries_mapped[i] );
-
- _mali_osk_mem_iowrite32(session_data->page_directory_mapped, i * sizeof(u32), pte_phys | MALI_MMU_FLAGS_PRESENT); /* mark page table as present */
-
- /* update usage count */
- session_data->page_entries_usage_count[i]++;
-#if defined USING_MALI400_L2_CACHE
- page_dir_updated = 1;
-#endif
- continue; /* continue loop */
- }
-
- MALI_DEBUG_PRINT(1, ("Page table alloc failed\n"));
- break; /* abort loop, failed to allocate one or more page tables */
- }
- else
- {
- session_data->page_entries_usage_count[i]++;
- }
- }
-
- if (i <= last_pde_idx)
- {
- /* one or more pages could not be allocated, release reference count for the ones we added one for */
- /* adjust for the one which caused the for loop to be aborted */
- i--;
-
- while (i >= first_pde_idx)
- {
- MALI_DEBUG_ASSERT(0 != session_data->page_entries_usage_count[i]);
- session_data->page_entries_usage_count[i]--;
- if (0 == session_data->page_entries_usage_count[i])
- {
- /* last reference removed */
- mali_mmu_release_table_page(MALI_MMU_ENTRY_ADDRESS(_mali_osk_mem_ioread32(session_data->page_directory_mapped, i * sizeof(u32))));
- session_data->page_entries_mapped[i] = NULL;
- _mali_osk_mem_iowrite32(session_data->page_directory_mapped, i * sizeof(u32), 0); /* mark as not present in the page directory */
- }
- i--;
- }
-
- MALI_ERROR(_MALI_OSK_ERR_NOMEM);
- }
-
-#if defined USING_MALI400_L2_CACHE
- if (1 == has_active_mmus && 1 == page_dir_updated)
- {
- /*
- * We have updated the page directory and have an active MMU using it, so invalidate it in the Mali L2 cache.
- */
- mali_kernel_l2_cache_invalidate_page(session_data->page_directory);
- }
-#endif
-
- /* all OK */
- MALI_SUCCESS;
-}
-
-static void mali_address_manager_release(mali_memory_allocation * descriptor)
-{
- int first_pde_idx;
- int last_pde_idx;
- memory_session * session_data;
- u32 mali_address;
- u32 mali_address_end;
- u32 left;
- int i;
-#if defined USING_MALI400_L2_CACHE
- int has_active_mmus = 0;
- int page_dir_updated = 0;
-#endif
-
- MALI_DEBUG_ASSERT_POINTER(descriptor);
- session_data = (memory_session*)descriptor->mali_addr_mapping_info;
- MALI_DEBUG_ASSERT_POINTER(session_data);
- MALI_DEBUG_ASSERT_POINTER(session_data->page_directory_mapped);
-
- mali_address = descriptor->mali_address;
- mali_address_end = descriptor->mali_address + descriptor->size;
- left = descriptor->size;
-
- first_pde_idx = MALI_MMU_PDE_ENTRY(mali_address);
- last_pde_idx = MALI_MMU_PDE_ENTRY(mali_address_end - 1);
-
- MALI_DEBUG_PRINT(3, ("Zapping Mali MMU table for address 0x%08X size 0x%08X\n", mali_address, left));
- MALI_DEBUG_PRINT(4, ("Zapping PDE %d through %d\n", first_pde_idx, last_pde_idx));
-
-#if defined USING_MALI400_L2_CACHE
- if (0 == _mali_osk_list_empty(&session_data->active_mmus))
- {
- /*
- * From Mali-400 MP r1p0, MMU page directory/tables are also cached by the Mali L2 cache, thus we need to invalidate the page tables
- * from the L2 cache to ensure that the memory is unmapped.
- * We only need to do this when we have an active MMU, because we otherwise invalidate the entire Mali L2 cache before at job start
- */
- has_active_mmus = 1;
- }
-#endif
-
-
- for (i = first_pde_idx; i <= last_pde_idx; i++)
- {
- int size_inside_pte = left < 0x400000 ? left : 0x400000;
- const int first_pte_idx = MALI_MMU_PTE_ENTRY(mali_address);
- int last_pte_idx = MALI_MMU_PTE_ENTRY(mali_address + size_inside_pte - 1);
-
- if (last_pte_idx < first_pte_idx)
- {
- /* The last_pte_idx is into the next PTE, crop it to fit into this */
- last_pte_idx = 1023; /* 1024 PTE entries, so 1023 is the last one */
- size_inside_pte = MALI_MMU_ADDRESS(i + 1, 0) - mali_address;
- }
-
- MALI_DEBUG_ASSERT_POINTER(session_data->page_entries_mapped[i]);
- MALI_DEBUG_ASSERT(0 != session_data->page_entries_usage_count[i]);
- MALI_DEBUG_PRINT(4, ("PDE %d: zapping entries %d through %d, address 0x%08X, size 0x%08X, left 0x%08X (page table at 0x%08X)\n",
- i, first_pte_idx, last_pte_idx, mali_address, size_inside_pte, left,
- MALI_MMU_ENTRY_ADDRESS(_mali_osk_mem_ioread32(session_data->page_directory_mapped, i * sizeof(u32)))));
-
- session_data->page_entries_usage_count[i]--;
-
- if (0 == session_data->page_entries_usage_count[i])
- {
- MALI_DEBUG_PRINT(4, ("Releasing page table as this is the last reference\n"));
- /* last reference removed, no need to zero out each PTE */
- mali_mmu_release_table_page(MALI_MMU_ENTRY_ADDRESS(_mali_osk_mem_ioread32(session_data->page_directory_mapped, i * sizeof(u32))));
- session_data->page_entries_mapped[i] = NULL;
- _mali_osk_mem_iowrite32(session_data->page_directory_mapped, i * sizeof(u32), 0); /* mark as not present in the page directory */
-#if defined USING_MALI400_L2_CACHE
- page_dir_updated = 1;
-#endif
- }
- else
- {
- int j;
-
- for (j = first_pte_idx; j <= last_pte_idx; j++)
- {
- _mali_osk_mem_iowrite32(session_data->page_entries_mapped[i], j * sizeof(u32), 0);
- }
-
-#if defined USING_MALI400_L2_CACHE
- if (1 == has_active_mmus)
- {
- /* Invalidate the page we've just modified */
- mali_kernel_l2_cache_invalidate_page( _mali_osk_mem_ioread32(session_data->page_directory_mapped, i*sizeof(u32)) & ~MALI_MMU_FLAGS_MASK);
- }
-#endif
- }
- left -= size_inside_pte;
- mali_address += size_inside_pte;
- }
-
-#if defined USING_MALI400_L2_CACHE
- if ((1 == page_dir_updated) && (1== has_active_mmus))
- {
- /* The page directory was also updated */
- mali_kernel_l2_cache_invalidate_page(session_data->page_directory);
- }
-#endif
-}
-
-static _mali_osk_errcode_t mali_address_manager_map(mali_memory_allocation * descriptor, u32 offset, u32 *phys_addr, u32 size)
-{
- memory_session * session_data;
- u32 mali_address;
- u32 mali_address_end;
- u32 current_phys_addr;
-#if defined USING_MALI400_L2_CACHE
- int has_active_mmus = 0;
-#endif
-
- MALI_DEBUG_ASSERT_POINTER(descriptor);
-
- MALI_DEBUG_ASSERT_POINTER( phys_addr );
-
- current_phys_addr = *phys_addr;
-
- session_data = (memory_session*)descriptor->mali_addr_mapping_info;
- MALI_DEBUG_ASSERT_POINTER(session_data);
-
- mali_address = descriptor->mali_address + offset;
- mali_address_end = descriptor->mali_address + offset + size;
-
-#if defined USING_MALI400_L2_CACHE
- if (0 == _mali_osk_list_empty(&session_data->active_mmus))
- {
- /*
- * We have active MMUs, so we are probably in the process of alocating more memory for a suspended GP job (PLBU heap)
- * From Mali-400 MP r1p0, MMU page directory/tables are also cached by the Mali L2 cache, thus we need to invalidate the page tables
- * from the L2 cache when we have allocated more heap memory.
- * We only need to do this when we have an active MMU, because we otherwise invalidate the entire Mali L2 cache before at job start
- */
- has_active_mmus = 1;
- }
-#endif
-
- MALI_DEBUG_PRINT(6, ("Mali map: mapping 0x%08X to Mali address 0x%08X length 0x%08X\n", current_phys_addr, mali_address, size));
-
- MALI_DEBUG_ASSERT_POINTER(session_data->page_entries_mapped);
-
- for ( ; mali_address < mali_address_end; mali_address += MALI_MMU_PAGE_SIZE, current_phys_addr += MALI_MMU_PAGE_SIZE)
- {
- MALI_DEBUG_ASSERT_POINTER(session_data->page_entries_mapped[MALI_MMU_PDE_ENTRY(mali_address)]);
- _mali_osk_mem_iowrite32_relaxed(session_data->page_entries_mapped[MALI_MMU_PDE_ENTRY(mali_address)], MALI_MMU_PTE_ENTRY(mali_address) * sizeof(u32), current_phys_addr | MALI_MMU_FLAGS_WRITE_PERMISSION | MALI_MMU_FLAGS_READ_PERMISSION | MALI_MMU_FLAGS_PRESENT);
- }
- _mali_osk_write_mem_barrier();
-
-#if defined USING_MALI400_L2_CACHE
- if (1 == has_active_mmus)
- {
- int i;
- const int first_pde_idx = MALI_MMU_PDE_ENTRY(mali_address);
- const int last_pde_idx = MALI_MMU_PDE_ENTRY(mali_address_end - 1);
-
- /*
- * Invalidate the updated page table(s), incase they have been used for something
- * else since last job start (invalidation of entire Mali L2 cache)
- */
- for (i = first_pde_idx; i <= last_pde_idx; i++)
- {
- mali_kernel_l2_cache_invalidate_page( _mali_osk_mem_ioread32(session_data->page_directory_mapped, i*sizeof(u32)) & ~MALI_MMU_FLAGS_MASK);
- }
- }
-#endif
-
- 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 * mali_session_data;
- mali_memory_allocation * descriptor;
- memory_session * session_data;
-
- /* 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 */
- mali_session_data = (struct mali_session_data *)args->ctx;
-
- if (NULL == mali_session_data) { MALI_DEBUG_PRINT(3,("mali_ukk_mem_mmap: mali_session data was NULL\n")); MALI_ERROR(_MALI_OSK_ERR_INVALID_ARGS); }
-
- MALI_DEBUG_ASSERT( mali_subsystem_memory_id >= 0 );
-
- session_data = mali_kernel_session_manager_slot_get(mali_session_data, mali_subsystem_memory_id);
- /* 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->lock = session_data->lock;
- _mali_osk_list_init( &descriptor->list );
-
- _mali_osk_lock_wait(session_data->lock, _MALI_OSK_LOCKMODE_RW);
-
- if (0 == mali_allocation_engine_allocate_memory(memory_engine, descriptor, physical_memory_allocators, &session_data->memory_head))
- {
- mali_kernel_memory_mmu * mmu, * temp_mmu;
-
- _MALI_OSK_LIST_FOREACHENTRY(mmu, temp_mmu, &session_data->active_mmus, mali_kernel_memory_mmu, session_link)
- {
- /* no need to lock the MMU as we own it already */
- MALI_DEBUG_PRINT(5, ("Zapping the cache of mmu %s as it's using the page table we have updated\n", mmu->description));
-
- _mali_osk_lock_wait(mmu->lock, _MALI_OSK_LOCKMODE_RW);
-
- mali_mmu_enable_stall(mmu); /* this might fail, but ZAP should work anyway... */
- mali_mmu_register_write(mmu, MALI_MMU_REGISTER_COMMAND, MALI_MMU_COMMAND_ZAP_CACHE);
- mali_mmu_disable_stall(mmu);
-
- _mali_osk_lock_signal(mmu->lock, _MALI_OSK_LOCKMODE_RW);
- }
-
- _mali_osk_lock_signal(session_data->lock, _MALI_OSK_LOCKMODE_RW);
-
- /* All ok, write out any information generated from this call */
- args->mapping = descriptor->mapping;
- args->cookie = (u32)descriptor;
-
- MALI_DEBUG_PRINT(7, ("MMAP OK\n"));
- /* All done */
- MALI_SUCCESS;
- }
- else
- {
- _mali_osk_lock_signal(session_data->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 )
-{
- memory_session * session_data;
- mali_kernel_memory_mmu * mmu, * temp_mmu;
- 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 = (memory_session*)descriptor->mali_addr_mapping_info;
- MALI_DEBUG_ASSERT_POINTER(session_data);
-
- /* Stall the MMU(s) which is using the address space we're operating on.
- * Note that active_mmus must be sorted in order of ID to avoid a mutex
- * ordering violation.
- */
- _MALI_OSK_LIST_FOREACHENTRY(mmu, temp_mmu, &session_data->active_mmus, mali_kernel_memory_mmu, session_link)
- {
- u32 status;
- status = mali_mmu_register_read(mmu, MALI_MMU_REGISTER_STATUS);
- if ( MALI_MMU_STATUS_BIT_PAGE_FAULT_ACTIVE == (status & MALI_MMU_STATUS_BIT_PAGE_FAULT_ACTIVE) ) {
- MALI_DEBUG_PRINT(2, ("Stopped stall attempt for mmu with id %d since it is in page fault mode.\n", mmu->id));
- continue;
- }
- _mali_osk_lock_wait(mmu->lock, _MALI_OSK_LOCKMODE_RW);
-
- /*
- * If we're unable to stall, then make sure we tell our caller that,
- * the caller should then release the session lock for a while,
- * then this function again.
- * This function will fail if we're in page fault mode, and to get
- * out of page fault mode, the page fault handler must be able to
- * take the session lock.
- */
- if (!mali_mmu_enable_stall(mmu))
- {
- _mali_osk_lock_signal(mmu->lock, _MALI_OSK_LOCKMODE_RW);
- return _MALI_OSK_ERR_BUSY;
- }
-
- _mali_osk_lock_signal(mmu->lock, _MALI_OSK_LOCKMODE_RW);
- }
-
- _MALI_OSK_LIST_FOREACHENTRY(mmu, temp_mmu, &session_data->active_mmus, mali_kernel_memory_mmu, session_link)
- {
- _mali_osk_lock_wait(mmu->lock, _MALI_OSK_LOCKMODE_RW);
- }
-
- /* This function also removes the memory from the session's memory list */
- mali_allocation_engine_release_memory(memory_engine, descriptor);
- _mali_osk_free(descriptor);
-
- /* any L2 maintenance was done during mali_allocation_engine_release_memory */
- /* the session is locked, so the active mmu list should be the same */
- /* zap the TLB and resume operation */
- _MALI_OSK_LIST_FOREACHENTRY(mmu, temp_mmu, &session_data->active_mmus, mali_kernel_memory_mmu, session_link)
- {
- mali_mmu_register_write(mmu, MALI_MMU_REGISTER_COMMAND, MALI_MMU_COMMAND_ZAP_CACHE);
- mali_mmu_disable_stall(mmu);
-
- _mali_osk_lock_signal(mmu->lock, _MALI_OSK_LOCKMODE_RW);
- }
-
- 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((memory_session*)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;
-}
-
-/* Is called when the rendercore wants the mmu to give an interrupt */
-static void mali_mmu_probe_irq_trigger(mali_kernel_memory_mmu * mmu)
-{
- MALI_DEBUG_PRINT(2, ("mali_mmu_probe_irq_trigger\n"));
- mali_mmu_register_write(mmu, 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_irq_acknowledge(mali_kernel_memory_mmu * mmu)
-{
- u32 int_stat;
-
- int_stat = mali_mmu_register_read(mmu, 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_mmu_register_write(mmu, 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_mmu_register_write(mmu, 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))
- {
- MALI_SUCCESS;
- }
-
- MALI_ERROR(_MALI_OSK_ERR_FAULT);
-}
-
-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, int dump_to_serial)
-{
- if (dump_to_serial) MALI_DEBUG_PRINT(1, ("writereg %08X %08X # %s\n", where, what, comment));
-
- 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, int dump_to_serial)
-{
- if (dump_to_serial)
- {
- int i;
- for (i = 0; i < 256; i++)
- {
- MALI_DEBUG_PRINT(1, ("%08X: %08X %08X %08X %08X\n", phys_addr + 16*i, _mali_osk_mem_ioread32(page, (i*4 + 0) * sizeof(u32)),
- _mali_osk_mem_ioread32(page, (i*4 + 1) * sizeof(u32)),
- _mali_osk_mem_ioread32(page, (i*4 + 2) * sizeof(u32)),
- _mali_osk_mem_ioread32(page, (i*4 + 3) * sizeof(u32))));
-
- }
- }
-
- 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(memory_session * session_data, struct dump_info * info)
-{
- MALI_DEBUG_ASSERT_POINTER(session_data);
- MALI_DEBUG_ASSERT_POINTER(info);
-
- if (NULL != session_data->page_directory_mapped)
- {
- int i;
-
- MALI_CHECK_NO_ERROR(
- dump_page(session_data->page_directory_mapped, session_data->page_directory, info, 0)
- );
-
- for (i = 0; i < 1024; i++)
- {
- if (NULL != session_data->page_entries_mapped[i])
- {
- MALI_CHECK_NO_ERROR(
- dump_page(session_data->page_entries_mapped[i], _mali_osk_mem_ioread32(session_data->page_directory_mapped, i * sizeof(u32)) & ~MALI_MMU_FLAGS_MASK, info, 0)
- );
- }
- }
- }
-
- MALI_SUCCESS;
-}
-
-static _mali_osk_errcode_t dump_mmu_registers(memory_session * session_data, struct dump_info * info)
-{
- MALI_CHECK_NO_ERROR(writereg(0x00000000, session_data->page_directory, "set the page directory address", info, 0));
- MALI_CHECK_NO_ERROR(writereg(0x00000008, 4, "zap???", info, 0));
- MALI_CHECK_NO_ERROR(writereg(0x00000008, 0, "enable paging", info, 0));
- 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 };
- memory_session * session_data;
-
- MALI_DEBUG_ASSERT_POINTER(args);
- MALI_CHECK_NON_NULL(args->ctx, _MALI_OSK_ERR_INVALID_ARGS);
-
- session_data = (memory_session *)mali_kernel_session_manager_slot_get(args->ctx, mali_subsystem_memory_id);
-
- MALI_CHECK_NO_ERROR(dump_mmu_registers(session_data, &info));
- MALI_CHECK_NO_ERROR(dump_mmu_page_table(session_data, &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 };
- memory_session * 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 = (memory_session *)mali_kernel_session_manager_slot_get(args->ctx, mali_subsystem_memory_id);
-
- info.buffer_left = args->size;
- info.buffer = args->buffer;
-
- args->register_writes = info.buffer;
- MALI_CHECK_NO_ERROR(dump_mmu_registers(session_data, &info));
-
- args->page_table_dump = info.buffer;
- MALI_CHECK_NO_ERROR(dump_mmu_page_table(session_data, &info));
-
- args->register_writes_size = info.register_writes_size;
- args->page_table_dump_size = info.page_table_dump_size;
-
- MALI_SUCCESS;
-}
-
-/**
- * Stub function to satisfy UDD interface exclusion requirement.
- * This is because the Base code compiles in \b both MMU and non-MMU calls,
- * so both sets must be declared (but the 'unused' set may be stub)
- */
-_mali_osk_errcode_t _mali_ukk_get_big_block( _mali_uk_get_big_block_s *args )
-{
- MALI_IGNORE( args );
- return _MALI_OSK_ERR_FAULT;
-}
-
-/**
- * Stub function to satisfy UDD interface exclusion requirement.
- * This is because the Base code compiles in \b both MMU and non-MMU calls,
- * so both sets must be declared (but the 'unused' set may be stub)
- */
-_mali_osk_errcode_t _mali_ukk_free_big_block( _mali_uk_free_big_block_s *args )
-{
- MALI_IGNORE( args );
- return _MALI_OSK_ERR_FAULT;
-}
-
-u32 _mali_ukk_report_memory_usage(void)
-{
- return mali_allocation_engine_memory_usage(physical_memory_allocators);
-}
diff --git a/drivers/media/video/samsung/mali/common/mali_kernel_mem_mmu.h b/drivers/media/video/samsung/mali/common/mali_kernel_mem_mmu.h
deleted file mode 100644
index 6a110d0..0000000
--- a/drivers/media/video/samsung/mali/common/mali_kernel_mem_mmu.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * 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_MMU_H__
-#define __MALI_KERNEL_MEM_MMU_H__
-
-#include "mali_kernel_session_manager.h"
-
-/**
- * Lookup a MMU core by ID.
- * @param id ID of the MMU to find
- * @return NULL if ID not found or valid, non-NULL if a core was found.
- */
-void* mali_memory_core_mmu_lookup(u32 id);
-
-/**
- * Set the core pointer of MMU to core owner of MMU
- *
- * @param core Core holding this MMU
- * @param mmu_ptr The MMU whose core pointer needs set to core holding the MMU
- *
- */
-void mali_memory_core_mmu_owner(void *core, void *mmu_ptr);
-
-/**
- * Activate a user session with its address space on the given MMU.
- * If the session can't be activated due to that the MMU is busy and
- * a callback pointer is given, the callback will be called once the MMU becomes idle.
- * If the same callback pointer is registered multiple time it will only be called once.
- * Nested activations are supported.
- * Each call must be matched by a call to @see mali_memory_core_mmu_release_address_space_reference
- *
- * @param mmu The MMU to activate the address space on
- * @param mali_session_data The user session object which address space to activate
- * @param callback Pointer to the function to call when the MMU becomes idle
- * @param callback_arg Argument given to the callback
- * @return 0 if the address space was activated, -EBUSY if the MMU was busy, -EFAULT in all other cases.
- */
-int mali_memory_core_mmu_activate_page_table(void* mmu_ptr, struct mali_session_data * mali_session_data, void(*callback)(void*), void * callback_argument);
-
-/**
- * Release a reference to the current active address space.
- * Once the last reference is released any callback(s) registered will be called before the function returns
- *
- * @note Caution must be shown calling this function with locks held due to that callback can be called
- * @param mmu The mmu to release a reference to the active address space of
- */
-void mali_memory_core_mmu_release_address_space_reference(void* mmu);
-
-/**
- * Soft reset of MMU - needed after power up
- *
- * @param mmu_ptr The MMU pointer registered with the relevant core
- */
-void mali_kernel_mmu_reset(void * mmu_ptr);
-
-void mali_kernel_mmu_force_bus_reset(void * mmu_ptr);
-
-/**
- * Unregister a previously registered callback.
- * @param mmu The MMU to unregister the callback on
- * @param callback The function to unregister
- */
-void mali_memory_core_mmu_unregister_callback(void* mmu, void(*callback)(void*));
-
-
-
-#endif /* __MALI_KERNEL_MEM_MMU_H__ */
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 324fcab..7462a6d 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
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 ARM Limited. All rights reserved.
+ * 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.
@@ -65,19 +65,19 @@ mali_physical_memory_allocator * mali_os_allocator_create(u32 max_allocation, u3
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, 106);
- 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;
+ 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->ctx = info;
allocator->name = name;
- return allocator;
- }
- _mali_osk_free(info);
+ return allocator;
+ }
+ _mali_osk_free(info);
}
_mali_osk_free(allocator);
}
@@ -132,7 +132,7 @@ static mali_physical_memory_allocation_result os_allocator_allocate(void* ctx, m
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*)));
- while (left > 0 && ((info->num_pages_allocated + pages_allocated) < info->num_pages_max) && _mali_osk_mem_check_allocated(os_mem_max_usage))
+ 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)
@@ -243,7 +243,7 @@ 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 << 6 */
+ int allocation_order = 11; /* _MALI_OSK_CPU_PAGE_SIZE << 11 */
void *virt = NULL;
u32 size = _MALI_OSK_CPU_PAGE_SIZE << allocation_order;
os_allocator * info;
diff --git a/drivers/media/video/samsung/mali/common/mali_kernel_memory_engine.c b/drivers/media/video/samsung/mali/common/mali_kernel_memory_engine.c
index ff105a4..1377560 100644
--- a/drivers/media/video/samsung/mali/common/mali_kernel_memory_engine.c
+++ b/drivers/media/video/samsung/mali/common/mali_kernel_memory_engine.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 ARM Limited. All rights reserved.
+ * 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.
@@ -161,13 +161,28 @@ _mali_osk_errcode_t mali_allocation_engine_allocate_memory(mali_allocation_engin
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_physical_memory_allocation * active_allocation_tracker;
MALI_DEBUG_ASSERT_POINTER(engine);
MALI_DEBUG_ASSERT_POINTER(descriptor);
- /* Determine whether we need to remove this from a tracking list */
+ /* 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 );
@@ -175,8 +190,6 @@ void mali_allocation_engine_release_memory(mali_allocation_engine mem_engine, ma
MALI_DEBUG_CODE( descriptor->list.next = descriptor->list.prev = NULL; )
}
- engine->mali_address->release(descriptor);
-
active_allocation_tracker = &descriptor->physical_allocation;
while (NULL != active_allocation_tracker)
{
@@ -199,7 +212,6 @@ void mali_allocation_engine_release_memory(mali_allocation_engine mem_engine, ma
}
}
-
_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;
@@ -244,7 +256,7 @@ _mali_osk_errcode_t mali_allocation_engine_map_physical(mali_allocation_engine m
}
}
- MALI_DEBUG_PRINT(4, ("Mapping phys 0x%08X length 0x%08X at offset 0x%08X to CPUVA 0x%08X\n", phys, size, offset, (u32)(descriptor->mapping) + offset));
+ 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 */
diff --git a/drivers/media/video/samsung/mali/common/mali_kernel_memory_engine.h b/drivers/media/video/samsung/mali/common/mali_kernel_memory_engine.h
index 0173c78..cda74c3 100644
--- a/drivers/media/video/samsung/mali/common/mali_kernel_memory_engine.h
+++ b/drivers/media/video/samsung/mali/common/mali_kernel_memory_engine.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 ARM Limited. All rights reserved.
+ * 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.
@@ -136,6 +136,9 @@ 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);
diff --git a/drivers/media/video/samsung/mali/common/mali_kernel_rendercore.c b/drivers/media/video/samsung/mali/common/mali_kernel_rendercore.c
deleted file mode 100644
index cfc5ec1..0000000
--- a/drivers/media/video/samsung/mali/common/mali_kernel_rendercore.c
+++ /dev/null
@@ -1,2031 +0,0 @@
-/*
- * 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 "mali_kernel_common.h"
-#include "mali_kernel_core.h"
-#include "mali_osk.h"
-#include "mali_kernel_subsystem.h"
-#include "mali_kernel_rendercore.h"
-#include "mali_osk_list.h"
-#if MALI_GPU_UTILIZATION
-#include "mali_kernel_utilization.h"
-#endif
-#if MALI_TIMELINE_PROFILING_ENABLED
-#include "mali_kernel_profiling.h"
-#endif
-#if USING_MMU
-#include "mali_kernel_mem_mmu.h"
-#endif /* USING_MMU */
-#if defined USING_MALI400_L2_CACHE
-#include "mali_kernel_l2_cache.h"
-#endif /* USING_MALI400_L2_CACHE */
-
-#define HANG_CHECK_MSECS_MIN 100
-#define HANG_CHECK_MSECS_MAX 2000 /* 2 secs */
-#define HANG_CHECK_MSECS_DEFAULT 500 /* 500 ms */
-
-#define WATCHDOG_MSECS_MIN (10*HANG_CHECK_MSECS_MIN)
-#define WATCHDOG_MSECS_MAX 3600000 /* 1 hour */
-#define WATCHDOG_MSECS_DEFAULT 4000 /* 4 secs */
-
-/* max value that will be converted from jiffies to micro seconds and written to job->render_time_usecs */
-#define JOB_MAX_JIFFIES 100000
-
-int mali_hang_check_interval = HANG_CHECK_MSECS_DEFAULT;
-int mali_max_job_runtime = WATCHDOG_MSECS_DEFAULT;
-
-#if MALI_TIMELINE_PROFILING_ENABLED
-int mali_boot_profiling = 0;
-#endif
-
-#ifdef MALI_REBOOTNOTIFIER
-extern _mali_osk_atomic_t mali_shutdown_state;
-#endif
-
-/* Subsystem entrypoints: */
-static _mali_osk_errcode_t rendercore_subsystem_startup(mali_kernel_subsystem_identifier id);
-static void rendercore_subsystem_terminate(mali_kernel_subsystem_identifier id);
-#if USING_MMU
-static void rendercore_subsystem_broadcast_notification(mali_core_notification_message message, u32 data);
-#endif
-
-
-static void mali_core_subsystem_cleanup_all_renderunits(struct mali_core_subsystem* subsys);
-static void mali_core_subsystem_move_core_set_idle(struct mali_core_renderunit *core);
-
-static mali_core_session * mali_core_subsystem_get_waiting_session(mali_core_subsystem *subsystem);
-static mali_core_job * mali_core_subsystem_release_session_get_job(mali_core_subsystem *subsystem, mali_core_session * session);
-
-static void find_and_abort(mali_core_session* session, u32 abort_id);
-
-static void mali_core_job_start_on_core(mali_core_job *job, mali_core_renderunit *core);
-#if USING_MMU
-static void mali_core_subsystem_callback_schedule_wrapper(void* sub);
-#endif
-static void mali_core_subsystem_schedule(mali_core_subsystem*subsystem);
-static void mali_core_renderunit_detach_job_from_core(mali_core_renderunit* core, mali_subsystem_reschedule_option reschedule, mali_subsystem_job_end_code end_status);
-
-static void mali_core_renderunit_irq_handler_remove(struct mali_core_renderunit *core);
-
-static _mali_osk_errcode_t mali_core_irq_handler_upper_half (void * data);
-static void mali_core_irq_handler_bottom_half ( void *data );
-
-#if USING_MMU
-static void lock_subsystem(struct mali_core_subsystem * subsys);
-static void unlock_subsystem(struct mali_core_subsystem * subsys);
-#endif
-
-
-/**
- * This will be one of the subsystems in the array of subsystems:
- * static struct mali_kernel_subsystem * subsystems[];
- * found in file: mali_kernel_core.c
- *
- * This subsystem is necessary for operations common to all rendercore
- * subsystems. For example, mali_subsystem_mali200 and mali_subsystem_gp2 may
- * share a mutex when RENDERCORES_USE_GLOBAL_MUTEX is non-zero.
- */
-struct mali_kernel_subsystem mali_subsystem_rendercore=
-{
- rendercore_subsystem_startup, /* startup */
- NULL, /*rendercore_subsystem_terminate,*/ /* shutdown */
- NULL, /* load_complete */
- NULL, /* system_info_fill */
- NULL, /* session_begin */
- NULL, /* session_end */
-#if USING_MMU
- rendercore_subsystem_broadcast_notification, /* broadcast_notification */
-#else
- NULL,
-#endif
-#if MALI_STATE_TRACKING
- NULL, /* dump_state */
-#endif
-} ;
-
-static _mali_osk_lock_t *rendercores_global_mutex = NULL;
-static u32 rendercores_global_mutex_is_held = 0;
-static u32 rendercores_global_mutex_owner = 0;
-
-/** The 'dummy' rendercore subsystem to allow global subsystem mutex to be
- * locked for all subsystems that extend the ''rendercore'' */
-static mali_core_subsystem rendercore_dummy_subsystem = {0,};
-
-/*
- * Rendercore Subsystem functions.
- *
- * These are exposed by mali_subsystem_rendercore
- */
-
-/**
- * @brief Initialize the Rendercore subsystem.
- *
- * This must be called before any other subsystem that extends the
- * ''rendercore'' may be initialized. For example, this must be called before
- * the following functions:
- * - mali200_subsystem_startup(), from mali_subsystem_mali200
- * - maligp_subsystem_startup(), from mali_subsystem_gp2
- *
- * @note This function is separate from mali_core_subsystem_init(). They
- * are related, in that mali_core_subsystem_init() may use the structures
- * initialized by rendercore_subsystem_startup()
- */
-static _mali_osk_errcode_t rendercore_subsystem_startup(mali_kernel_subsystem_identifier id)
-{
- rendercores_global_mutex_is_held = 0;
- rendercores_global_mutex = _mali_osk_lock_init(
- (_mali_osk_lock_flags_t)(_MALI_OSK_LOCKFLAG_NONINTERRUPTABLE | _MALI_OSK_LOCKFLAG_ORDERED),
- 0, 129);
-
- if (NULL == rendercores_global_mutex)
- {
- MALI_PRINT_ERROR(("Failed: _mali_osk_lock_init\n")) ;
- MALI_ERROR(_MALI_OSK_ERR_FAULT);
- }
-
- rendercore_dummy_subsystem.name = "Rendercore Global Subsystem"; /* On the constant pool, do not free */
- rendercore_dummy_subsystem.magic_nr = SUBSYSTEM_MAGIC_NR; /* To please the Subsystem Mutex code */
-
-#if MALI_GPU_UTILIZATION
- if (mali_utilization_init() != _MALI_OSK_ERR_OK)
- {
- _mali_osk_lock_term(rendercores_global_mutex);
- rendercores_global_mutex = NULL;
- MALI_PRINT_ERROR(("Failed: mali_utilization_init\n")) ;
- MALI_ERROR(_MALI_OSK_ERR_FAULT);
- }
-#endif
-
-#if MALI_TIMELINE_PROFILING_ENABLED
- if (_mali_profiling_init(mali_boot_profiling ? MALI_TRUE : MALI_FALSE) != _MALI_OSK_ERR_OK)
- {
- /* No biggie if we wheren't able to initialize the profiling */
- MALI_PRINT_ERROR(("Rendercore: Failed to initialize profiling, feature will be unavailable\n")) ;
- }
-#endif
-
- MALI_DEBUG_PRINT(2, ("Rendercore: subsystem global mutex initialized\n")) ;
- MALI_SUCCESS;
-}
-
-/**
- * @brief Terminate the Rendercore subsystem.
- *
- * This must only be called \b after any other subsystem that extends the
- * ''rendercore'' has been terminated. For example, this must be called \b after
- * the following functions:
- * - mali200_subsystem_terminate(), from mali_subsystem_mali200
- * - maligp_subsystem_terminate(), from mali_subsystem_gp2
- *
- * @note This function is separate from mali_core_subsystem_cleanup(), though,
- * the subsystems that extend ''rendercore'' must still call
- * mali_core_subsystem_cleanup() when they terminate.
- */
-static void rendercore_subsystem_terminate(mali_kernel_subsystem_identifier id)
-{
- /* Catch double-terminate */
- MALI_DEBUG_ASSERT_POINTER( rendercores_global_mutex );
-
-#if MALI_TIMELINE_PROFILING_ENABLED
- _mali_profiling_term();
-#endif
-
-#if MALI_GPU_UTILIZATION
- mali_utilization_term();
-#endif
-
- rendercore_dummy_subsystem.name = NULL; /* The original string was on the constant pool, do not free */
- rendercore_dummy_subsystem.magic_nr = 0;
-
- /* ASSERT that no-one's holding this */
- MALI_DEBUG_PRINT_ASSERT( 0 == rendercores_global_mutex_is_held,
- ("Rendercores' Global Mutex was held at termination time. Have the subsystems that extend ''rendercore'' been terminated?\n") );
-
- _mali_osk_lock_term( rendercores_global_mutex );
- rendercores_global_mutex = NULL;
-
- MALI_DEBUG_PRINT(2, ("Rendercore: subsystem global mutex terminated\n")) ;
-}
-
-
-#if USING_MMU
-/**
- * @brief Handle certain Rendercore subsystem broadcast notifications
- *
- * When RENDERCORES_USE_GLOBAL_MUTEX is non-zero, this handles the following messages:
- * - MMU_KILL_STEP0_LOCK_SUBSYSTEM
- * - MMU_KILL_STEP4_UNLOCK_SUBSYSTEM
- *
- * The purpose is to manage the Rendercode Global Mutex, which cannot be
- * managed by any system that extends the ''rendercore''.
- *
- * All other messages must be handled by mali_core_subsystem_broadcast_notification()
- *
- *
- * When RENDERCORES_USE_GLOBAL_MUTEX is 0, this function does nothing.
- * Instead, the subsystem that extends the ''rendercore' \b must handle its
- * own mutexes - refer to mali_core_subsystem_broadcast_notification().
- *
- * Used currently only for signalling when MMU has a pagefault
- */
-static void rendercore_subsystem_broadcast_notification(mali_core_notification_message message, u32 data)
-{
- switch(message)
- {
- case MMU_KILL_STEP0_LOCK_SUBSYSTEM:
- lock_subsystem( &rendercore_dummy_subsystem );
- break;
- case MMU_KILL_STEP4_UNLOCK_SUBSYSTEM:
- unlock_subsystem( &rendercore_dummy_subsystem );
- break;
-
- case MMU_KILL_STEP1_STOP_BUS_FOR_ALL_CORES:
- /** FALLTHROUGH */
- case MMU_KILL_STEP2_RESET_ALL_CORES_AND_ABORT_THEIR_JOBS:
- /** FALLTHROUGH */
- case MMU_KILL_STEP3_CONTINUE_JOB_HANDLING:
- break;
-
- default:
- MALI_PRINT_ERROR(("Illegal message: 0x%x, data: 0x%x\n", (u32)message, data));
- break;
- }
-
-}
-#endif
-
-/*
- * Functions inherited by the subsystems that extend the ''rendercore''.
- */
-
-void mali_core_renderunit_timeout_function_hang_detection(void *arg)
-{
- mali_bool action = MALI_FALSE;
- mali_core_renderunit * core;
-
- core = (mali_core_renderunit *) arg;
- if( !core ) return;
-
- /* if NOT idle OR NOT powered off OR has TIMED_OUT */
- if ( !((CORE_WATCHDOG_TIMEOUT == core->state ) || (CORE_IDLE== core->state) || (CORE_OFF == core->state)) )
- {
- core->state = CORE_HANG_CHECK_TIMEOUT;
- action = MALI_TRUE;
- }
-
- if(action) _mali_osk_irq_schedulework(core->irq);
-}
-
-
-void mali_core_renderunit_timeout_function(void *arg)
-{
- mali_core_renderunit * core;
- mali_bool is_watchdog;
-
- core = (mali_core_renderunit *)arg;
- if( !core ) return;
-
- is_watchdog = MALI_TRUE;
- if (mali_benchmark)
- {
- /* poll based core */
- mali_core_job *job;
- job = core->current_job;
- if ( (NULL != job) &&
- (0 != _mali_osk_time_after(job->watchdog_jiffies,_mali_osk_time_tickcount()))
- )
- {
- core->state = CORE_POLL;
- is_watchdog = MALI_FALSE;
- }
- }
-
- if (is_watchdog)
- {
- MALI_DEBUG_PRINT(3, ("SW-Watchdog timeout: Core:%s\n", core->description));
- core->state = CORE_WATCHDOG_TIMEOUT;
- }
-
- _mali_osk_irq_schedulework(core->irq);
-}
-
-/* Used by external renderunit_create<> function */
-_mali_osk_errcode_t mali_core_renderunit_init(mali_core_renderunit * core)
-{
- MALI_DEBUG_PRINT(5, ("Core: renderunit_init: Core:%s\n", core->description));
-
- _MALI_OSK_INIT_LIST_HEAD(&core->list) ;
- core->timer = _mali_osk_timer_init();
- if (NULL == core->timer)
- {
- MALI_PRINT_ERROR(("Core: renderunit_init: Core:%s -- cannot init timer\n", core->description));
- MALI_ERROR(_MALI_OSK_ERR_FAULT);
- }
-
- _mali_osk_timer_setcallback(core->timer, mali_core_renderunit_timeout_function, (void *)core);
-
- core->timer_hang_detection = _mali_osk_timer_init();
- if (NULL == core->timer_hang_detection)
- {
- _mali_osk_timer_term(core->timer);
- MALI_PRINT_ERROR(("Core: renderunit_init: Core:%s -- cannot init hang detection timer\n", core->description));
- MALI_ERROR(_MALI_OSK_ERR_FAULT);
- }
-
- _mali_osk_timer_setcallback(core->timer_hang_detection, mali_core_renderunit_timeout_function_hang_detection, (void *)core);
-
-#if USING_MALI_PMM
- /* Init no pending power downs */
- core->pend_power_down = MALI_FALSE;
-
- /* Register the core with the PMM - which powers it up */
- if (_MALI_OSK_ERR_OK != malipmm_core_register( core->pmm_id ))
- {
- _mali_osk_timer_term(core->timer);
- _mali_osk_timer_term(core->timer_hang_detection);
- MALI_PRINT_ERROR(("Core: renderunit_init: Core:%s -- cannot register with PMM\n", core->description));
- MALI_ERROR(_MALI_OSK_ERR_FAULT);
- }
-#endif /* USING_MALI_PMM */
-
- core->error_recovery = MALI_FALSE;
- core->in_detach_function = MALI_FALSE;
- core->state = CORE_IDLE;
- core->current_job = NULL;
- core->magic_nr = CORE_MAGIC_NR;
-#if USING_MMU
- core->mmu = NULL;
-#endif /* USING_MMU */
-
- MALI_SUCCESS;
-}
-
-void mali_core_renderunit_term(mali_core_renderunit * core)
-{
- MALI_DEBUG_PRINT(5, ("Core: renderunit_term: Core:%s\n", core->description));
-
- if (NULL != core->timer)
- {
- _mali_osk_timer_term(core->timer);
- core->timer = NULL;
- }
- if (NULL != core->timer_hang_detection)
- {
- _mali_osk_timer_term(core->timer_hang_detection);
- core->timer_hang_detection = NULL;
- }
-
-#if USING_MALI_PMM
- /* Unregister the core with the PMM */
- malipmm_core_unregister( core->pmm_id );
-#endif
-}
-
-/* Used by external renderunit_create<> function */
-_mali_osk_errcode_t mali_core_renderunit_map_registers(mali_core_renderunit *core)
-{
- MALI_DEBUG_PRINT(3, ("Core: renderunit_map_registers: Core:%s\n", core->description)) ;
- if( (0 == core->registers_base_addr) ||
- (0 == core->size) ||
- (NULL == core->description)
- )
- {
- MALI_PRINT_ERROR(("Missing fields in the core structure %u %u 0x%x;\n", core->registers_base_addr, core->size, core->description));
- MALI_ERROR(_MALI_OSK_ERR_INVALID_ARGS);
- }
-
- if (_MALI_OSK_ERR_OK != _mali_osk_mem_reqregion(core->registers_base_addr, core->size, core->description))
- {
- MALI_PRINT_ERROR(("Could not request register region (0x%08X - 0x%08X) to core: %s\n",
- core->registers_base_addr, core->registers_base_addr + core->size - 1, core->description));
- MALI_ERROR(_MALI_OSK_ERR_INVALID_ARGS);
- }
- else
- {
- MALI_DEBUG_PRINT(6, ("Success: request_mem_region: (0x%08X - 0x%08X) Core:%s\n",
- core->registers_base_addr, core->registers_base_addr + core->size - 1, core->description));
- }
-
- core->registers_mapped = _mali_osk_mem_mapioregion( core->registers_base_addr, core->size, core->description );
-
- if ( 0 == core->registers_mapped )
- {
- MALI_PRINT_ERROR(("Could not ioremap registers for %s .\n", core->description));
- _mali_osk_mem_unreqregion(core->registers_base_addr, core->size);
- MALI_ERROR(_MALI_OSK_ERR_NOMEM);
- }
- else
- {
- MALI_DEBUG_PRINT(6, ("Success: ioremap_nocache: Internal ptr: (0x%08X - 0x%08X) Core:%s\n",
- (u32) core->registers_mapped,
- ((u32)core->registers_mapped)+ core->size - 1,
- core->description));
- }
-
- MALI_DEBUG_PRINT(4, ("Success: Mapping registers to core: %s\n",core->description));
-
- MALI_SUCCESS;
-}
-
-/* Used by external renderunit_create<> function + other places */
-void mali_core_renderunit_unmap_registers(mali_core_renderunit *core)
-{
- MALI_DEBUG_PRINT(3, ("Core: renderunit_unmap_registers: Core:%s\n", core->description));
- if (0 == core->registers_mapped)
- {
- MALI_PRINT_ERROR(("Trying to unmap register-mapping with NULL from core: %s\n", core->description));
- return;
- }
- _mali_osk_mem_unmapioregion(core->registers_base_addr, core->size, core->registers_mapped);
- core->registers_mapped = 0;
- _mali_osk_mem_unreqregion(core->registers_base_addr, core->size);
-}
-
-static void mali_core_renderunit_irq_handler_remove(mali_core_renderunit *core)
-{
- MALI_DEBUG_PRINT(3, ("Core: renderunit_irq_handler_remove: Core:%s\n", core->description));
- _mali_osk_irq_term(core->irq);
-}
-
-mali_core_renderunit * mali_core_renderunit_get_mali_core_nr(mali_core_subsystem *subsys, u32 mali_core_nr)
-{
- mali_core_renderunit * core;
- MALI_ASSERT_MUTEX_IS_GRABBED(subsys);
- if (subsys->number_of_cores <= mali_core_nr)
- {
- MALI_PRINT_ERROR(("Trying to get illegal mali_core_nr: 0x%x for %s", mali_core_nr, subsys->name));
- return NULL;
- }
- core = (subsys->mali_core_array)[mali_core_nr];
- MALI_DEBUG_PRINT(6, ("Core: renderunit_get_mali_core_nr: Core:%s\n", core->description));
- MALI_CHECK_CORE(core);
- return core;
-}
-
-/* Is used by external function:
- subsystem_startup<> */
-_mali_osk_errcode_t mali_core_subsystem_init(mali_core_subsystem* new_subsys)
-{
- int i;
-
- /* These function pointers must have been set on before calling this function */
- if (
- ( NULL == new_subsys->name ) ||
- ( NULL == new_subsys->start_job ) ||
- ( NULL == new_subsys->irq_handler_upper_half ) ||
- ( NULL == new_subsys->irq_handler_bottom_half ) ||
- ( NULL == new_subsys->get_new_job_from_user ) ||
- ( NULL == new_subsys->return_job_to_user )
- )
- {
- MALI_PRINT_ERROR(("Missing functions in subsystem."));
- MALI_ERROR(_MALI_OSK_ERR_FAULT);
- }
-
- MALI_DEBUG_PRINT(2, ("Core: subsystem_init: %s\n", new_subsys->name)) ;
-
- /* Catch use-before-initialize/use-after-terminate */
- MALI_DEBUG_ASSERT_POINTER( rendercores_global_mutex );
-
- new_subsys->magic_nr = SUBSYSTEM_MAGIC_NR;
-
- _MALI_OSK_INIT_LIST_HEAD(&new_subsys->renderunit_idle_head); /* Idle cores of this type */
- _MALI_OSK_INIT_LIST_HEAD(&new_subsys->renderunit_off_head); /* Powered off cores of this type */
-
- /* Linked list for each priority of sessions with a job ready for scheduleing */
- for(i=0; i<PRIORITY_LEVELS; ++i)
- {
- _MALI_OSK_INIT_LIST_HEAD(&new_subsys->awaiting_sessions_head[i]);
- }
-
- /* Linked list of all sessions connected to this coretype */
- _MALI_OSK_INIT_LIST_HEAD(&new_subsys->all_sessions_head);
-
- MALI_SUCCESS;
-}
-
-#if USING_MMU
-void mali_core_subsystem_attach_mmu(mali_core_subsystem* subsys)
-{
- u32 i;
- mali_core_renderunit * core;
-
- MALI_CORE_SUBSYSTEM_MUTEX_GRAB(subsys);
-
- for(i=0 ; i < subsys->number_of_cores ; ++i)
- {
- core = mali_core_renderunit_get_mali_core_nr(subsys,i);
- if ( NULL==core ) break;
- core->mmu = mali_memory_core_mmu_lookup(core->mmu_id);
- mali_memory_core_mmu_owner(core,core->mmu);
- MALI_DEBUG_PRINT(2, ("Attach mmu: 0x%x to core: %s in subsystem: %s\n", core->mmu, core->description, subsys->name));
- }
-
- MALI_CORE_SUBSYSTEM_MUTEX_RELEASE(subsys);
-}
-#endif
-
-/* This will register an IRQ handler, and add the core to the list of available cores for this subsystem. */
-_mali_osk_errcode_t mali_core_subsystem_register_renderunit(mali_core_subsystem* subsys, mali_core_renderunit * core)
-{
- mali_core_renderunit ** mali_core_array;
- u32 previous_nr;
- u32 previous_size;
- u32 new_nr;
- u32 new_size;
- _mali_osk_errcode_t err = _MALI_OSK_ERR_FAULT;
-
- /* If any of these are 0 there is an error */
- if(0 == core->subsystem ||
- 0 == core->registers_base_addr ||
- 0 == core->size ||
- 0 == core->description)
- {
- MALI_PRINT_ERROR(("Missing fields in the core structure 0x%x 0x%x 0x%x;\n",
- core->registers_base_addr, core->size, core->description));
- MALI_ERROR(_MALI_OSK_ERR_INVALID_ARGS);
- }
-
- MALI_DEBUG_PRINT(3, ("Core: subsystem_register_renderunit: %s\n", core->description));
-
- MALI_CHECK_NON_NULL(
- core->irq = _mali_osk_irq_init(
- core->irq_nr,
- mali_core_irq_handler_upper_half,
- mali_core_irq_handler_bottom_half,
- (_mali_osk_irq_trigger_t)subsys->probe_core_irq_trigger,
- (_mali_osk_irq_ack_t)subsys->probe_core_irq_acknowledge,
- core,
- "mali_core_irq_handlers"
- ),
- _MALI_OSK_ERR_FAULT
- );
-
- MALI_CORE_SUBSYSTEM_MUTEX_GRAB(subsys);
-
- /* Update which core number this is */
- core->core_number = subsys->number_of_cores;
-
- /* Update the array of cores in the subsystem. */
- previous_nr = subsys->number_of_cores;
- previous_size = sizeof(mali_core_renderunit*)*previous_nr;
- new_nr = previous_nr + 1;
- new_size = sizeof(mali_core_renderunit*)*new_nr;
-
- if (0 != previous_nr)
- {
- if (NULL == subsys->mali_core_array)
- {
- MALI_PRINT_ERROR(("Internal error"));
- goto exit_function;
- }
-
- mali_core_array = (mali_core_renderunit **) _mali_osk_malloc( new_size );
- if (NULL == mali_core_array )
- {
- MALI_PRINT_ERROR(("Out of mem"));
- err = _MALI_OSK_ERR_NOMEM;
- goto exit_function;
- }
- _mali_osk_memcpy(mali_core_array, subsys->mali_core_array, previous_size);
- _mali_osk_free( subsys->mali_core_array);
- MALI_DEBUG_PRINT(5, ("Success: adding a new core to subsystem array %s\n", core->description) ) ;
- }
- else
- {
- mali_core_array = (mali_core_renderunit **) _mali_osk_malloc( new_size );
- if (NULL == mali_core_array )
- {
- MALI_PRINT_ERROR(("Out of mem"));
- err = _MALI_OSK_ERR_NOMEM;
- goto exit_function;
- }
- MALI_DEBUG_PRINT(6, ("Success: adding first core to subsystem array %s\n", core->description) ) ;
- }
- subsys->mali_core_array = mali_core_array;
- mali_core_array[previous_nr] = core;
-
- /* Add the core to the list of available cores on the system */
- _mali_osk_list_add(&(core->list), &(subsys->renderunit_idle_head));
-
- /* Update total number of cores */
- subsys->number_of_cores = new_nr;
- MALI_DEBUG_PRINT(6, ("Success: mali_core_subsystem_register_renderunit %s\n", core->description));
- MALI_CORE_SUBSYSTEM_MUTEX_RELEASE(subsys);
- MALI_SUCCESS;
-
-exit_function:
- mali_core_renderunit_irq_handler_remove(core);
- MALI_CORE_SUBSYSTEM_MUTEX_RELEASE(subsys);
- MALI_ERROR(err);
-}
-
-
-/**
- * Called by the core when a system info update is needed
- * We fill in info about all the core types available
- * @param subsys Pointer to the core's @a mali_core_subsystem data structure
- * @param info Pointer to system info struct to update
- * @return _MALI_OSK_ERR_OK on success, or another _mali_osk_errcode_t error code on failure
- */
-_mali_osk_errcode_t mali_core_subsystem_system_info_fill(mali_core_subsystem* subsys, _mali_system_info* info)
-{
- u32 i;
- _mali_osk_errcode_t err = _MALI_OSK_ERR_OK; /* OK if no cores to update info for */
- mali_core_renderunit * core;
- _mali_core_info **core_info_nextp;
- _mali_core_info * cinfo;
-
- MALI_DEBUG_PRINT(4, ("mali_core_subsystem_system_info_fill: %s\n", subsys->name) ) ;
-
- /* check input */
- MALI_CHECK_NON_NULL(info, _MALI_OSK_ERR_INVALID_ARGS);
-
- core_info_nextp = &(info->core_info);
- cinfo = info->core_info;
-
- while(NULL!=cinfo)
- {
- core_info_nextp = &(cinfo->next);
- cinfo = cinfo->next;
- }
-
- MALI_CORE_SUBSYSTEM_MUTEX_GRAB(subsys);
- for(i=0 ; i < subsys->number_of_cores ; ++i)
- {
- core = mali_core_renderunit_get_mali_core_nr(subsys,i);
- if ( NULL==core )
- {
- err = _MALI_OSK_ERR_FAULT;
- goto early_exit;
- }
- cinfo = (_mali_core_info *)_mali_osk_calloc(1, sizeof(_mali_core_info));
- if ( NULL==cinfo )
- {
- err = _MALI_OSK_ERR_NOMEM;
- goto early_exit;
- }
- cinfo->version = core->core_version;
- cinfo->type =subsys->core_type;
- cinfo->reg_address = core->registers_base_addr;
- cinfo->core_nr = i;
- cinfo->next = NULL;
- /* Writing this address to the previous' *(&next) ptr */
- *core_info_nextp = cinfo;
- /* Setting the next_ptr to point to &this->next_ptr */
- core_info_nextp = &(cinfo->next);
- }
-early_exit:
- if ( _MALI_OSK_ERR_OK != err) MALI_PRINT_ERROR(("Error: In mali_core_subsystem_system_info_fill %d\n", err));
- MALI_DEBUG_CODE(
- cinfo = info->core_info;
-
- MALI_DEBUG_PRINT(3, ("Current list of cores\n"));
- while( NULL != cinfo )
- {
- MALI_DEBUG_PRINT(3, ("Type: 0x%x\n", cinfo->type));
- MALI_DEBUG_PRINT(3, ("Version: 0x%x\n", cinfo->version));
- MALI_DEBUG_PRINT(3, ("Reg_addr: 0x%x\n", cinfo->reg_address));
- MALI_DEBUG_PRINT(3, ("Core_nr: 0x%x\n", cinfo->core_nr));
- MALI_DEBUG_PRINT(3, ("Flags: 0x%x\n", cinfo->flags));
- MALI_DEBUG_PRINT(3, ("*****\n"));
- cinfo = cinfo->next;
- }
- );
-
- MALI_CORE_SUBSYSTEM_MUTEX_RELEASE(subsys);
- MALI_ERROR(err);
-}
-
-
-/* Is used by external function:
- subsystem_terminate<> */
-void mali_core_subsystem_cleanup(mali_core_subsystem* subsys)
-{
- u32 i;
- mali_core_renderunit * core;
-
- MALI_CORE_SUBSYSTEM_MUTEX_GRAB(subsys);
- MALI_DEBUG_PRINT(2, ("Core: subsystem_cleanup: %s\n", subsys->name )) ;
-
- for(i=0 ; i < subsys->number_of_cores ; ++i)
- {
- core = mali_core_renderunit_get_mali_core_nr(subsys,i);
-
-#if USING_MMU
- if (NULL != core->mmu)
- {
- /* the MMU is attached in the load_complete callback, which will never be called if the module fails to load, handle that case */
- mali_memory_core_mmu_unregister_callback(core->mmu, mali_core_subsystem_callback_schedule_wrapper);
- }
-#endif
-
- MALI_CORE_SUBSYSTEM_MUTEX_RELEASE(subsys);
-
- mali_core_renderunit_irq_handler_remove(core);
-
- /* When a process terminates, all cores running jobs from that process is reset and put to idle.
- That means that when the module is unloading (this code) we are guaranteed that all cores are idle.
- However: if something (we can't think of) is really wrong, a core may give an interrupt during this
- unloading, and we may now in the code have a bottom-half-processing pending from the interrupts
- we deregistered above. To be sure that the bottom halves do not access the structures after they
- are deallocated we flush the bottom-halves processing here, before the deallocation. */
-
- MALI_CORE_SUBSYSTEM_MUTEX_GRAB(subsys);
-
-#if USING_MALI_PMM
- /* Only reset when we are using PMM and the core is not off */
-#if MALI_PMM_NO_PMU
- /* We need to reset when there is no PMU - but this will
- * cause the register read/write functions to report an
- * error (hence the if to check for CORE_OFF below) we
- * change state to allow the reset to happen.
- */
- core->state = CORE_IDLE;
-#endif
- if( core->state != CORE_OFF )
- {
- subsys->reset_core( core, MALI_CORE_RESET_STYLE_DISABLE );
- }
-#else
- /* Always reset the core */
- subsys->reset_core( core, MALI_CORE_RESET_STYLE_DISABLE );
-#endif
-
- mali_core_renderunit_unmap_registers(core);
-
- _mali_osk_list_delinit(&core->list);
-
- mali_core_renderunit_term(core);
-
- subsys->renderunit_delete(core);
- }
-
- mali_core_subsystem_cleanup_all_renderunits(subsys);
- MALI_CORE_SUBSYSTEM_MUTEX_RELEASE(subsys);
- MALI_DEBUG_PRINT(6, ("SUCCESS: mali_core_subsystem_cleanup: %s\n", subsys->name )) ;
-}
-
-_mali_osk_errcode_t mali_core_subsystem_ioctl_number_of_cores_get(mali_core_session * session, u32 *number_of_cores)
-{
- mali_core_subsystem * subsystem;
-
- subsystem = session->subsystem;
- if ( NULL != number_of_cores )
- {
- *number_of_cores = subsystem->number_of_cores;
-
- MALI_DEBUG_PRINT(4, ("Core: ioctl_number_of_cores_get: %s: %u\n", subsystem->name, *number_of_cores) ) ;
- }
-
- MALI_SUCCESS;
-}
-
-_mali_osk_errcode_t mali_core_subsystem_ioctl_start_job(mali_core_session * session, void *job_data)
-{
- mali_core_subsystem * subsystem;
- _mali_osk_errcode_t err;
-
- /* need the subsystem to run callback function */
- subsystem = session->subsystem;
- MALI_CHECK_NON_NULL(subsystem, _MALI_OSK_ERR_FAULT);
-
- MALI_CORE_SUBSYSTEM_MUTEX_GRAB(subsystem);
- err = subsystem->get_new_job_from_user(session, job_data);
- MALI_CORE_SUBSYSTEM_MUTEX_RELEASE(subsystem);
-
- MALI_ERROR(err);
-}
-
-
-/* We return the version number to the first core in this subsystem */
-_mali_osk_errcode_t mali_core_subsystem_ioctl_core_version_get(mali_core_session * session, _mali_core_version *version)
-{
- mali_core_subsystem * subsystem;
- mali_core_renderunit * core0;
- u32 nr_return;
-
- subsystem = session->subsystem;
- MALI_CORE_SUBSYSTEM_MUTEX_GRAB(subsystem);
-
- core0 = mali_core_renderunit_get_mali_core_nr(subsystem, 0);
-
- if( NULL == core0 )
- {
- MALI_CORE_SUBSYSTEM_MUTEX_RELEASE(subsystem);
- MALI_ERROR(_MALI_OSK_ERR_FAULT);
- }
-
- nr_return = core0->core_version;
- MALI_CORE_SUBSYSTEM_MUTEX_RELEASE(subsystem);
-
- MALI_DEBUG_PRINT(4, ("Core: ioctl_core_version_get: %s: %u\n", subsystem->name, nr_return )) ;
-
- *version = nr_return;
-
- MALI_SUCCESS;
-}
-
-void mali_core_subsystem_ioctl_abort_job(mali_core_session * session, u32 id)
-{
- find_and_abort(session, id);
-}
-
-static mali_bool job_should_be_aborted(mali_core_job *job, u32 abort_id)
-{
- if ( job->abort_id == abort_id ) return MALI_TRUE;
- else return MALI_FALSE;
-}
-
-static void find_and_abort(mali_core_session* session, u32 abort_id)
-{
- mali_core_subsystem * subsystem;
- mali_core_renderunit *core;
- mali_core_renderunit *tmp;
- mali_core_job *job;
-
- subsystem = session->subsystem;
-
- MALI_CORE_SUBSYSTEM_MUTEX_GRAB( subsystem );
-
- job = mali_job_queue_abort_job(session, abort_id);
- if (NULL != job)
- {
- MALI_DEBUG_PRINT(3, ("Core: Aborting %s job, with id nr: %u, from the waiting_to_run slot.\n", subsystem->name, abort_id ));
- if (mali_job_queue_empty(session))
- {
- _mali_osk_list_delinit(&(session->awaiting_sessions_list));
- }
- subsystem->awaiting_sessions_sum_all_priorities--;
- subsystem->return_job_to_user(job , JOB_STATUS_END_ABORT);
- }
-
- _MALI_OSK_LIST_FOREACHENTRY( core, tmp, &session->renderunits_working_head, mali_core_renderunit, list )
- {
- job = core->current_job;
- if ( (job!=NULL) && (job_should_be_aborted (job, abort_id) ) )
- {
- MALI_DEBUG_PRINT(3, ("Core: Aborting %s job, with id nr: %u, which is currently running on mali.\n", subsystem->name, abort_id ));
- if ( core->state==CORE_IDLE )
- {
- MALI_PRINT_ERROR(("Aborting core with running job which is idle. Must be something very wrong."));
- goto end_bug;
- }
- mali_core_renderunit_detach_job_from_core(core, SUBSYSTEM_RESCHEDULE, JOB_STATUS_END_ABORT);
- }
- }
-end_bug:
-
- MALI_CORE_SUBSYSTEM_MUTEX_RELEASE( subsystem );
-}
-
-
-_mali_osk_errcode_t mali_core_subsystem_ioctl_suspend_response(mali_core_session * session, void *argument)
-{
- mali_core_subsystem * subsystem;
- _mali_osk_errcode_t err = _MALI_OSK_ERR_FAULT;
-
- /* need the subsystem to run callback function */
- subsystem = session->subsystem;
- MALI_CHECK_NON_NULL(subsystem, _MALI_OSK_ERR_FAULT);
-
- MALI_CORE_SUBSYSTEM_MUTEX_GRAB(subsystem);
- if ( NULL != subsystem->suspend_response)
- {
- MALI_DEBUG_PRINT(4, ("MALI_IOC_CORE_CMD_SUSPEND_RESPONSE start\n"));
- err = subsystem->suspend_response(session, argument);
- MALI_DEBUG_PRINT(4, ("MALI_IOC_CORE_CMD_SUSPEND_RESPONSE end\n"));
- }
-
- MALI_CORE_SUBSYSTEM_MUTEX_RELEASE(subsystem);
-
- return err;
-}
-
-
-/* Is used by internal function:
- mali_core_subsystem_cleanup<>s */
-/* All cores should be removed before calling this function
-Must hold subsystem_mutex before entering this function */
-static void mali_core_subsystem_cleanup_all_renderunits(mali_core_subsystem* subsys)
-{
- int i;
- _mali_osk_free(subsys->mali_core_array);
- subsys->number_of_cores = 0;
-
- MALI_DEBUG_PRINT(5, ("Core: subsystem_cleanup_all_renderunits: %s\n", subsys->name) ) ;
- MALI_ASSERT_MUTEX_IS_GRABBED(subsys);
-
- if ( ! _mali_osk_list_empty(&(subsys->renderunit_idle_head)))
- {
- MALI_PRINT_ERROR(("List renderunit_list_idle should be empty."));
- _MALI_OSK_INIT_LIST_HEAD(&(subsys->renderunit_idle_head)) ;
- }
-
- if ( ! _mali_osk_list_empty(&(subsys->renderunit_off_head)))
- {
- MALI_PRINT_ERROR(("List renderunit_list_off should be empty."));
- _MALI_OSK_INIT_LIST_HEAD(&(subsys->renderunit_off_head)) ;
- }
-
- for(i=0; i<PRIORITY_LEVELS; ++i)
- {
- if ( ! _mali_osk_list_empty(&(subsys->awaiting_sessions_head[i])))
- {
- MALI_PRINT_ERROR(("List awaiting_sessions_linkedlist should be empty."));
- _MALI_OSK_INIT_LIST_HEAD(&(subsys->awaiting_sessions_head[i])) ;
- subsys->awaiting_sessions_sum_all_priorities = 0;
- }
- }
-
- if ( ! _mali_osk_list_empty(&(subsys->all_sessions_head)))
- {
- MALI_PRINT_ERROR(("List all_sessions_linkedlist should be empty."));
- _MALI_OSK_INIT_LIST_HEAD(&(subsys->all_sessions_head)) ;
- }
-}
-
-/* Is used by internal functions:
- mali_core_irq_handler_bottom_half<>;
- mali_core_subsystem_schedule<>; */
-/* Will release the core.*/
-/* Must hold subsystem_mutex before entering this function */
-static void mali_core_subsystem_move_core_set_idle(mali_core_renderunit *core)
-{
- mali_core_subsystem *subsystem;
-#if USING_MALI_PMM
- mali_core_status oldstatus;
-#endif
- subsystem = core->subsystem;
- MALI_ASSERT_MUTEX_IS_GRABBED(subsystem);
- MALI_CHECK_CORE(core);
- MALI_CHECK_SUBSYSTEM(subsystem);
-
- _mali_osk_timer_del(core->timer);
- _mali_osk_timer_del(core->timer_hang_detection);
-
- MALI_DEBUG_PRINT(5, ("Core: subsystem_move_core_set_idle: %s\n", core->description) ) ;
-
- core->current_job = NULL ;
-
-#if USING_MALI_PMM
-
- oldstatus = core->state;
-
- if ( !core->pend_power_down )
- {
- core->state = CORE_IDLE ;
- _mali_osk_list_move( &core->list, &subsystem->renderunit_idle_head );
- }
-
- if( CORE_OFF != oldstatus )
- {
- /* Message that this core is now idle or in fact off */
- _mali_uk_pmm_message_s event = {
- NULL,
- MALI_PMM_EVENT_JOB_FINISHED,
- 0 };
- event.data = core->pmm_id;
- _mali_ukk_pmm_event_message( &event );
-#if USING_MMU
- /* Only free the reference when entering idle state from
- * anything other than power off
- */
- mali_memory_core_mmu_release_address_space_reference(core->mmu);
-#endif /* USING_MMU */
- }
-
- if( core->pend_power_down )
- {
- core->state = CORE_OFF ;
- _mali_osk_list_move( &core->list, &subsystem->renderunit_off_head );
-
- /* Done the move from the active queues, so the pending power down can be done */
- core->pend_power_down = MALI_FALSE;
- malipmm_core_power_down_okay( core->pmm_id );
- }
-
-#else /* !USING_MALI_PMM */
-
- core->state = CORE_IDLE ;
- _mali_osk_list_move( &core->list, &subsystem->renderunit_idle_head );
-
-#if USING_MMU
- mali_memory_core_mmu_release_address_space_reference(core->mmu);
-#endif
-
-#endif /* USING_MALI_PMM */
-}
-
-/* Must hold subsystem_mutex before entering this function */
-static void mali_core_subsystem_move_set_working(mali_core_renderunit *core, mali_core_job *job)
-{
- mali_core_subsystem *subsystem;
- mali_core_session *session;
- u64 time_now;
-
- session = job->session;
- subsystem = core->subsystem;
-
- MALI_CHECK_CORE(core);
- MALI_CHECK_JOB(job);
- MALI_CHECK_SUBSYSTEM(subsystem);
-
- MALI_ASSERT_MUTEX_IS_GRABBED(subsystem);
-
- MALI_DEBUG_PRINT(5, ("Core: subsystem_move_set_working: %s\n", core->description) ) ;
-
- time_now = _mali_osk_time_get_ns();
- job->start_time = time_now;
-#if MALI_GPU_UTILIZATION
- mali_utilization_core_start(time_now);
-#endif
-
- core->current_job = job ;
- core->state = CORE_WORKING ;
- _mali_osk_list_move( &core->list, &session->renderunits_working_head );
-
-}
-
-#if USING_MALI_PMM
-
-/* Must hold subsystem_mutex before entering this function */
-static void mali_core_subsystem_move_core_set_off(mali_core_renderunit *core)
-{
- mali_core_subsystem *subsystem;
- subsystem = core->subsystem;
- MALI_ASSERT_MUTEX_IS_GRABBED(subsystem);
- MALI_CHECK_CORE(core);
- MALI_CHECK_SUBSYSTEM(subsystem);
-
- /* Cores must be idle before powering off */
- MALI_DEBUG_ASSERT(core->state == CORE_IDLE);
-
- MALI_DEBUG_PRINT(5, ("Core: subsystem_move_core_set_off: %s\n", core->description) ) ;
-
- core->current_job = NULL ;
- core->state = CORE_OFF ;
- _mali_osk_list_move( &core->list, &subsystem->renderunit_off_head );
-}
-
-#endif /* USING_MALI_PMM */
-
-/* Is used by internal function:
- mali_core_subsystem_schedule<>; */
-/* Returns the job with the highest priority for the subsystem. NULL if none*/
-/* Must hold subsystem_mutex before entering this function */
-static mali_core_session * mali_core_subsystem_get_waiting_session(mali_core_subsystem *subsystem)
-{
- int i;
-
- MALI_CHECK_SUBSYSTEM(subsystem);
- MALI_ASSERT_MUTEX_IS_GRABBED(subsystem);
-
- if ( 0 == subsystem->awaiting_sessions_sum_all_priorities )
- {
- MALI_DEBUG_PRINT(5, ("Core: subsystem_get_waiting_job: No awaiting session found\n"));
- return NULL;
- }
-
- for( i=0; i<PRIORITY_LEVELS ; ++i)
- {
- if (!_mali_osk_list_empty(&subsystem->awaiting_sessions_head[i]))
- {
- return _MALI_OSK_LIST_ENTRY(subsystem->awaiting_sessions_head[i].next, mali_core_session, awaiting_sessions_list);
- }
- }
-
- return NULL;
-}
-
-static mali_core_job * mali_core_subsystem_release_session_get_job(mali_core_subsystem *subsystem, mali_core_session * session)
-{
- mali_core_job *job;
- MALI_CHECK_SUBSYSTEM(subsystem);
- MALI_ASSERT_MUTEX_IS_GRABBED(subsystem);
-
- job = mali_job_queue_get_job(session);
- subsystem->awaiting_sessions_sum_all_priorities--;
-
- if(mali_job_queue_empty(session))
- {
- /* This is the last job, so remove it from the list */
- _mali_osk_list_delinit(&session->awaiting_sessions_list);
- }
- else
- {
- if (0 == (job->flags & MALI_UK_START_JOB_FLAG_MORE_JOBS_FOLLOW))
- {
- /* There are more jobs, but the follow flag is not set, so let other sessions run their jobs first */
- _mali_osk_list_del(&(session->awaiting_sessions_list));
- _mali_osk_list_addtail(&(session->awaiting_sessions_list), &(subsystem->awaiting_sessions_head[
- session->queue[session->queue_head]->priority]));
- }
- /* else; keep on list, follow flag is set and there are more jobs in queue for this session */
- }
-
- MALI_CHECK_JOB(job);
- return job;
-}
-
-/* Is used by internal functions:
- mali_core_subsystem_schedule<> */
-/* This will start the job on the core. It will also release the core if it did not start.*/
-/* Must hold subsystem_mutex before entering this function */
-static void mali_core_job_start_on_core(mali_core_job *job, mali_core_renderunit *core)
-{
- mali_core_session *session;
- mali_core_subsystem *subsystem;
- _mali_osk_errcode_t err;
- session = job->session;
- subsystem = core->subsystem;
-
- MALI_CHECK_CORE(core);
- MALI_CHECK_JOB(job);
- MALI_CHECK_SUBSYSTEM(subsystem);
- MALI_CHECK_SESSION(session);
- MALI_ASSERT_MUTEX_IS_GRABBED(subsystem);
-
- MALI_DEBUG_PRINT(4, ("Core: job_start_on_core: job=0x%x, session=0x%x, core=%s\n", job, session, core->description));
-
- MALI_DEBUG_ASSERT(NULL == core->current_job) ;
- MALI_DEBUG_ASSERT(CORE_IDLE == core->state );
-
- mali_core_subsystem_move_set_working(core, job);
-
-#if defined USING_MALI400_L2_CACHE
- if (0 == (job->flags & MALI_UK_START_JOB_FLAG_NO_FLUSH))
- {
- /* Invalidate the L2 cache */
- if (_MALI_OSK_ERR_OK != mali_kernel_l2_cache_invalidate_all() )
- {
- MALI_DEBUG_PRINT(4, ("Core: Clear of L2 failed, return job. System may not be usable for some reason.\n"));
- mali_core_subsystem_move_core_set_idle(core);
- subsystem->return_job_to_user(job,JOB_STATUS_END_SYSTEM_UNUSABLE );
- return;
- }
- }
-#endif
-
- /* Tries to start job on the core. Returns MALI_FALSE if the job could not be started */
- err = subsystem->start_job(job, core);
-
- if ( _MALI_OSK_ERR_OK != err )
- {
- /* This will happen only if there is something in the job object
- which make it inpossible to start. Like if it require illegal memory.*/
- MALI_DEBUG_PRINT(4, ("Core: start_job failed, return job and putting core back into idle list\n"));
- mali_core_subsystem_move_core_set_idle(core);
- subsystem->return_job_to_user(job,JOB_STATUS_END_ILLEGAL_JOB );
- }
- else
- {
- u32 delay = _mali_osk_time_mstoticks(job->watchdog_msecs)+1;
- job->watchdog_jiffies = _mali_osk_time_tickcount() + delay;
- if (mali_benchmark)
- {
- _mali_osk_timer_add(core->timer, 1);
- }
- else
- {
- _mali_osk_timer_add(core->timer, delay);
- }
- }
-}
-
-#if USING_MMU
-static void mali_core_subsystem_callback_schedule_wrapper(void* sub)
-{
- mali_core_subsystem * subsystem;
- subsystem = (mali_core_subsystem *)sub;
- MALI_DEBUG_PRINT(3, ("MMU: Is schedulling subsystem: %s\n", subsystem->name));
- mali_core_subsystem_schedule(subsystem);
-}
-#endif
-
-/* Is used by internal function:
- mali_core_irq_handler_bottom_half
- mali_core_session_add_job
-*/
-/* Must hold subsystem_mutex before entering this function */
-static void mali_core_subsystem_schedule(mali_core_subsystem * subsystem)
-{
- mali_core_renderunit *core, *tmp;
- mali_core_session *session;
- mali_core_job *job;
-#ifdef MALI_REBOOTNOTIFIER
- if (_mali_osk_atomic_read(&mali_shutdown_state) > 0) {
- MALI_DEBUG_PRINT(3, ("Core: mali already under shutdown process!!")) ;
- return;
- }
-#endif
-
- MALI_DEBUG_PRINT(5, ("Core: subsystem_schedule: %s\n", subsystem->name )) ;
-
- MALI_ASSERT_MUTEX_IS_GRABBED(subsystem);
-
- /* First check that there are sessions with jobs waiting to run */
- if ( 0 == subsystem->awaiting_sessions_sum_all_priorities)
- {
- MALI_DEBUG_PRINT(6, ("Core: No jobs available for %s\n", subsystem->name) ) ;
- return;
- }
-
- /* Returns the session with the highest priority job for the subsystem. NULL if none*/
- session = mali_core_subsystem_get_waiting_session(subsystem);
-
- if (NULL == session)
- {
- MALI_DEBUG_PRINT(6, ("Core: Schedule: No runnable job found\n"));
- return;
- }
-
- _MALI_OSK_LIST_FOREACHENTRY(core, tmp, &subsystem->renderunit_idle_head, mali_core_renderunit, list)
- {
-#if USING_MMU
- int err = mali_memory_core_mmu_activate_page_table(core->mmu, session->mmu_session, mali_core_subsystem_callback_schedule_wrapper, subsystem);
- if (0 == err)
- {
- /* core points to a core where the MMU page table activation succeeded */
-#endif
- /* This will remove the job from queue system */
- job = mali_core_subsystem_release_session_get_job(subsystem, session);
- MALI_DEBUG_ASSERT_POINTER(job);
-
- MALI_DEBUG_PRINT(6, ("Core: Schedule: Got a job 0x%x\n", job));
-
-#if USING_MALI_PMM
- {
- /* Message that there is a job scheduled to run
- * NOTE: mali_core_job_start_on_core() can fail to start
- * the job for several reasons, but it will move the core
- * back to idle which will create the FINISHED message
- * so we can still say that the job is SCHEDULED
- */
- _mali_uk_pmm_message_s event = {
- NULL,
- MALI_PMM_EVENT_JOB_SCHEDULED,
- 0 };
- event.data = core->pmm_id;
- _mali_ukk_pmm_event_message( &event );
- }
-#endif
- /* This will {remove core from freelist AND start the job on the core}*/
- mali_core_job_start_on_core(job, core);
-
- MALI_DEBUG_PRINT(6, ("Core: Schedule: Job started, done\n"));
- return;
-#if USING_MMU
- }
-#endif
- }
- MALI_DEBUG_PRINT(6, ("Core: Schedule: Could not activate MMU. Scheduelling postponed to MMU, checking next.\n"));
-
-#if USING_MALI_PMM
- {
- /* Message that there are jobs to run */
- _mali_uk_pmm_message_s event = {
- NULL,
- MALI_PMM_EVENT_JOB_QUEUED,
- 0 };
- if( subsystem->core_type == _MALI_GP2 || subsystem->core_type == _MALI_400_GP )
- {
- event.data = MALI_PMM_CORE_GP;
- }
- else
- {
- /* Check the PP is supported by the PMM */
- MALI_DEBUG_ASSERT( subsystem->core_type == _MALI_200 || subsystem->core_type == _MALI_400_PP );
- /* We state that all PP cores are scheduled to inform the PMM
- * that it may need to power something up!
- */
- event.data = MALI_PMM_CORE_PP_ALL;
- }
- _mali_ukk_pmm_event_message( &event );
- }
-#endif /* USING_MALI_PMM */
-
-}
-
-/* Is used by external function:
- session_begin<> */
-void mali_core_session_begin(mali_core_session * session)
-{
- mali_core_subsystem * subsystem;
- int i;
-
- subsystem = session->subsystem;
- if ( NULL == subsystem )
- {
- MALI_PRINT_ERROR(("Missing data in struct\n"));
- return;
- }
- MALI_DEBUG_PRINT(2, ("Core: session_begin: for %s\n", session->subsystem->name )) ;
-
- session->magic_nr = SESSION_MAGIC_NR;
-
- _MALI_OSK_INIT_LIST_HEAD(&session->renderunits_working_head);
-
- for (i = 0; i < MALI_JOB_QUEUE_SIZE; i++)
- {
- session->queue[i] = NULL;
- }
- session->queue_head = 0;
- session->queue_tail = 0;
- _MALI_OSK_INIT_LIST_HEAD(&session->awaiting_sessions_list);
- _MALI_OSK_INIT_LIST_HEAD(&session->all_sessions_list);
-
- MALI_CORE_SUBSYSTEM_MUTEX_GRAB(subsystem);
- _mali_osk_list_add(&session->all_sessions_list, &session->subsystem->all_sessions_head);
-
-#if MALI_STATE_TRACKING
- _mali_osk_atomic_init(&session->jobs_received, 0);
- _mali_osk_atomic_init(&session->jobs_returned, 0);
- session->pid = _mali_osk_get_pid();
-#endif
-
- MALI_CORE_SUBSYSTEM_MUTEX_RELEASE(subsystem);
-
- MALI_DEBUG_PRINT(5, ("Core: session_begin: for %s DONE\n", session->subsystem->name) ) ;
-}
-
-#if USING_MMU
-static void mali_core_renderunit_stop_bus(mali_core_renderunit* core)
-{
- core->subsystem->stop_bus(core);
-}
-#endif
-
-void mali_core_session_close(mali_core_session * session)
-{
- mali_core_subsystem * subsystem;
- mali_core_renderunit *core;
-
- subsystem = session->subsystem;
- MALI_DEBUG_ASSERT_POINTER(subsystem);
-
- MALI_DEBUG_PRINT(2, ("Core: session_close: for %s\n", session->subsystem->name) ) ;
-
- /* We must grab subsystem mutex since the list this session belongs to
- is owned by the subsystem */
- MALI_CORE_SUBSYSTEM_MUTEX_GRAB( subsystem );
-
- /* Remove this session from the global sessionlist */
- _mali_osk_list_delinit(&session->all_sessions_list);
-
- _mali_osk_list_delinit(&(session->awaiting_sessions_list));
-
- /* Return the potensial waiting job to user */
- while ( !mali_job_queue_empty(session) )
- {
- /* Queue not empty */
- mali_core_job *job = mali_job_queue_get_job(session);
- subsystem->return_job_to_user( job, JOB_STATUS_END_SHUTDOWN );
- subsystem->awaiting_sessions_sum_all_priorities--;
- }
-
- /* Kill active cores working for this session - freeing their jobs
- Since the handling of one core also could stop jobs from another core, there is a while loop */
- while ( ! _mali_osk_list_empty(&session->renderunits_working_head) )
- {
- core = _MALI_OSK_LIST_ENTRY(session->renderunits_working_head.next, mali_core_renderunit, list);
- MALI_DEBUG_PRINT(3, ("Core: session_close: Core was working: %s\n", core->description )) ;
- mali_core_renderunit_detach_job_from_core(core, SUBSYSTEM_RESCHEDULE, JOB_STATUS_END_SHUTDOWN );
- }
- _MALI_OSK_INIT_LIST_HEAD(&session->renderunits_working_head); /* Not necessary - we will _mali_osk_free session*/
-
- MALI_DEBUG_PRINT(5, ("Core: session_close: for %s FINISHED\n", session->subsystem->name )) ;
- MALI_CORE_SUBSYSTEM_MUTEX_RELEASE( subsystem );
-}
-
-/* Must hold subsystem_mutex before entering this function */
-_mali_osk_errcode_t mali_core_session_add_job(mali_core_session * session, mali_core_job *job, mali_core_job **job_return)
-{
- mali_core_subsystem * subsystem;
-
- job->magic_nr = JOB_MAGIC_NR;
- MALI_CHECK_SESSION(session);
-
- subsystem = session->subsystem;
- MALI_CHECK_SUBSYSTEM(subsystem);
- MALI_ASSERT_MUTEX_IS_GRABBED(subsystem);
-
- MALI_DEBUG_PRINT(5, ("Core: session_add_job: for %s\n", subsystem->name )) ;
-
- /* Setting the default value; No job to return */
- MALI_DEBUG_ASSERT_POINTER(job_return);
- *job_return = NULL;
-
- if (mali_job_queue_empty(session))
- {
- /* Add session to the wait list only if it didn't already have a job waiting. */
- _mali_osk_list_addtail( &(session->awaiting_sessions_list), &(subsystem->awaiting_sessions_head[job->priority]));
- }
-
-
- if (_MALI_OSK_ERR_OK != mali_job_queue_add_job(session, job))
- {
- if (mali_job_queue_empty(session))
- {
- _mali_osk_list_delinit(&(session->awaiting_sessions_list));
- }
- MALI_DEBUG_PRINT(4, ("Core: session_add_job: %s queue is full\n", subsystem->name));
- MALI_ERROR(_MALI_OSK_ERR_FAULT);
- }
-
- /* Continue to add the new job as the next job from this session */
- MALI_DEBUG_PRINT(6, ("Core: session_add_job job=0x%x\n", job));
-
- subsystem->awaiting_sessions_sum_all_priorities++;
-
- mali_core_subsystem_schedule(subsystem);
-
- MALI_DEBUG_PRINT(6, ("Core: session_add_job: for %s FINISHED\n", session->subsystem->name )) ;
-
- MALI_SUCCESS;
-}
-
-static void mali_core_job_set_run_time(mali_core_job * job, u64 end_time)
-{
- u32 time_used_nano_seconds;
-
- time_used_nano_seconds = end_time - job->start_time;
- job->render_time_usecs = time_used_nano_seconds / 1000;
-}
-
-static void mali_core_renderunit_detach_job_from_core(mali_core_renderunit* core, mali_subsystem_reschedule_option reschedule, mali_subsystem_job_end_code end_status)
-{
- mali_core_job * job;
- mali_core_subsystem * subsystem;
- mali_bool already_in_detach_function;
- u64 time_now;
-
- MALI_DEBUG_ASSERT(CORE_IDLE != core->state);
- time_now = _mali_osk_time_get_ns();
- job = core->current_job;
- subsystem = core->subsystem;
-
- /* The reset_core() called some lines below might call this detach
- * funtion again. To protect the core object from being modified by
- * recursive calls, the in_detach_function would track if it is an recursive call
- */
- already_in_detach_function = core->in_detach_function;
-
-
- if ( MALI_FALSE == already_in_detach_function )
- {
- core->in_detach_function = MALI_TRUE;
- if ( NULL != job )
- {
- mali_core_job_set_run_time(job, time_now);
- core->current_job = NULL;
- }
- }
-
- if (JOB_STATUS_END_SEG_FAULT == end_status)
- {
- subsystem->reset_core( core, MALI_CORE_RESET_STYLE_HARD );
- }
- else
- {
- subsystem->reset_core( core, MALI_CORE_RESET_STYLE_RUNABLE );
- }
-
- if ( MALI_FALSE == already_in_detach_function )
- {
- if ( CORE_IDLE != core->state )
- {
- #if MALI_GPU_UTILIZATION
- mali_utilization_core_end(time_now);
- #endif
- mali_core_subsystem_move_core_set_idle(core);
- }
-
- core->in_detach_function = MALI_FALSE;
-
- if ( SUBSYSTEM_RESCHEDULE == reschedule )
- {
- mali_core_subsystem_schedule(subsystem);
- }
- if ( NULL != job )
- {
- core->subsystem->return_job_to_user(job, end_status);
- }
- }
-}
-
-#if USING_MMU
-/* This function intentionally does not release the semaphore. You must run
- stop_bus_for_all_cores(), reset_all_cores_on_mmu() and continue_job_handling()
- after calling this function, and then call unlock_subsystem() to release the
- semaphore. */
-
-static void lock_subsystem(struct mali_core_subsystem * subsys)
-{
- MALI_CORE_SUBSYSTEM_MUTEX_GRAB(subsys);
- MALI_ASSERT_MUTEX_IS_GRABBED(subsys);
-}
-
-/* You must run lock_subsystem() before entering this function, to ensure that
- the subsystem mutex is held.
- Later, unlock_subsystem() can be called to release the mutex.
-
- This function only stops cores behind the given MMU, unless "mmu" is NULL, in
- which case all cores are stopped.
-*/
-static void stop_bus_for_all_cores_on_mmu(struct mali_core_subsystem * subsys, void* mmu)
-{
- u32 i;
-
- MALI_ASSERT_MUTEX_IS_GRABBED(subsys);
- MALI_DEBUG_PRINT(2,("Handling: bus stop %s\n", subsys->name ));
- for(i=0 ; i < subsys->number_of_cores ; ++i)
- {
- mali_core_renderunit * core;
- core = mali_core_renderunit_get_mali_core_nr(subsys,i);
-
- /* We stop only cores behind the given MMU, unless MMU is NULL */
- if ( (NULL!=mmu) && (core->mmu != mmu) ) continue;
-
- if ( CORE_IDLE != core->state )
- {
- MALI_DEBUG_PRINT(4, ("Stopping bus on core %s\n", core->description));
- mali_core_renderunit_stop_bus(core);
- core->error_recovery = MALI_TRUE;
- }
- else
- {
- MALI_DEBUG_PRINT(4,("Core: not active %s\n", core->description ));
- }
- }
- /* Mutex is still being held, to prevent things to happen while we do cleanup */
- MALI_ASSERT_MUTEX_IS_GRABBED(subsys);
-}
-
-/* You must run lock_subsystem() before entering this function, to ensure that
- the subsystem mutex is held.
- Later, unlock_subsystem() can be called to release the mutex.
-
- This function only resets cores behind the given MMU, unless "mmu" is NULL, in
- which case all cores are reset.
-*/
-static void reset_all_cores_on_mmu(struct mali_core_subsystem * subsys, void* mmu)
-{
- u32 i;
-
- MALI_ASSERT_MUTEX_IS_GRABBED(subsys);
- MALI_DEBUG_PRINT(3, ("Handling: reset cores from mmu: 0x%x on %s\n", mmu, subsys->name ));
- for(i=0 ; i < subsys->number_of_cores ; ++i)
- {
- mali_core_renderunit * core;
- core = mali_core_renderunit_get_mali_core_nr(subsys,i);
-
- /* We reset only cores behind the given MMU, unless MMU is NULL */
- if ( (NULL!=mmu) && (core->mmu != mmu) ) continue;
-
- if ( CORE_IDLE != core->state )
- {
- MALI_DEBUG_PRINT(4, ("Abort and reset core: %s\n", core->description ));
- mali_core_renderunit_detach_job_from_core(core, SUBSYSTEM_WAIT, JOB_STATUS_END_SEG_FAULT);
- }
- else
- {
- MALI_DEBUG_PRINT(4, ("Core: not active %s\n", core->description ));
- }
- }
- MALI_DEBUG_PRINT(4, ("Handling: done %s\n", subsys->name ));
- MALI_ASSERT_MUTEX_IS_GRABBED(subsys);
-}
-
-/* You must run lock_subsystem() before entering this function, to ensure that
- the subsystem mutex is held.
- Later, unlock_subsystem() can be called to release the mutex. */
-static void continue_job_handling(struct mali_core_subsystem * subsys)
-{
- u32 i, j;
-
- MALI_DEBUG_PRINT(3, ("Handling: Continue: %s\n", subsys->name ));
- MALI_ASSERT_MUTEX_IS_GRABBED(subsys);
-
-
- for(i=0 ; i < subsys->number_of_cores ; ++i)
- {
- mali_core_renderunit * core;
- core = mali_core_renderunit_get_mali_core_nr(subsys,i);
- core->error_recovery = MALI_FALSE;
- }
-
- i = subsys->number_of_cores;
- j = subsys->awaiting_sessions_sum_all_priorities;
-
- /* Schedule MIN(nr_waiting_jobs , number of cores) times */
- while( i-- && j--)
- {
- mali_core_subsystem_schedule(subsys);
- }
- MALI_DEBUG_PRINT(4, ("Handling: done %s\n", subsys->name ));
- MALI_ASSERT_MUTEX_IS_GRABBED(subsys);
-}
-
-/* Unlock the subsystem. */
-static void unlock_subsystem(struct mali_core_subsystem * subsys)
-{
- MALI_ASSERT_MUTEX_IS_GRABBED(subsys);
- MALI_CORE_SUBSYSTEM_MUTEX_RELEASE(subsys);
-}
-
-void mali_core_subsystem_broadcast_notification(struct mali_core_subsystem * subsys, mali_core_notification_message message, u32 data)
-{
- void * mmu;
- mmu = (void*) data;
-
- switch(message)
- {
- case MMU_KILL_STEP0_LOCK_SUBSYSTEM:
- break;
- case MMU_KILL_STEP1_STOP_BUS_FOR_ALL_CORES:
- stop_bus_for_all_cores_on_mmu(subsys, mmu);
- break;
- case MMU_KILL_STEP2_RESET_ALL_CORES_AND_ABORT_THEIR_JOBS:
- reset_all_cores_on_mmu(subsys, mmu );
- break;
- case MMU_KILL_STEP3_CONTINUE_JOB_HANDLING:
- continue_job_handling(subsys);
- break;
- case MMU_KILL_STEP4_UNLOCK_SUBSYSTEM:
- break;
-
- default:
- MALI_PRINT_ERROR(("Illegal message: 0x%x, data: 0x%x\n", (u32)message, data));
- break;
- }
-}
-#endif /* USING_MMU */
-
-void job_watchdog_set(mali_core_job * job, u32 watchdog_msecs)
-{
- if (watchdog_msecs == 0) job->watchdog_msecs = mali_max_job_runtime; /* use the default */
- else if (watchdog_msecs > WATCHDOG_MSECS_MAX) job->watchdog_msecs = WATCHDOG_MSECS_MAX; /* no larger than max */
- else if (watchdog_msecs < WATCHDOG_MSECS_MIN) job->watchdog_msecs = WATCHDOG_MSECS_MIN; /* not below min */
- else job->watchdog_msecs = watchdog_msecs;
-}
-
-u32 mali_core_hang_check_timeout_get(void)
-{
- /* check the value. The user might have set the value outside the allowed range */
- if (mali_hang_check_interval > HANG_CHECK_MSECS_MAX) mali_hang_check_interval = HANG_CHECK_MSECS_MAX; /* cap to max */
- else if (mali_hang_check_interval < HANG_CHECK_MSECS_MIN) mali_hang_check_interval = HANG_CHECK_MSECS_MIN; /* cap to min */
-
- /* return the active value */
- return mali_hang_check_interval;
-}
-
-static _mali_osk_errcode_t mali_core_irq_handler_upper_half (void * data)
-{
- mali_core_renderunit *core;
- u32 has_pending_irq;
-
- core = (mali_core_renderunit * )data;
-
- if(core && (CORE_OFF == core->state))
- {
- MALI_SUCCESS;
- }
-
- if ( (NULL == core) ||
- (NULL == core->subsystem) ||
- (NULL == core->subsystem->irq_handler_upper_half) )
- {
- MALI_ERROR(_MALI_OSK_ERR_INVALID_ARGS);
- }
- MALI_CHECK_CORE(core);
- MALI_CHECK_SUBSYSTEM(core->subsystem);
-
- has_pending_irq = core->subsystem->irq_handler_upper_half(core);
-
- if ( has_pending_irq )
- {
- _mali_osk_irq_schedulework( core->irq ) ;
- MALI_SUCCESS;
- }
-
- if (mali_benchmark) MALI_SUCCESS;
-
- MALI_ERROR(_MALI_OSK_ERR_FAULT);
-}
-
-static void mali_core_irq_handler_bottom_half ( void *data )
-{
- mali_core_renderunit *core;
- mali_core_subsystem* subsystem;
-
- mali_subsystem_job_end_code job_status;
-
- core = (mali_core_renderunit * )data;
-
- MALI_CHECK_CORE(core);
- subsystem = core->subsystem;
- MALI_CHECK_SUBSYSTEM(subsystem);
-
- MALI_CORE_SUBSYSTEM_MUTEX_GRAB( subsystem );
- if ( CORE_IDLE == core->state || CORE_OFF == core->state ) goto end_function;
-
- MALI_DEBUG_PRINT(5, ("IRQ: handling irq from core %s\n", core->description )) ;
-
- _mali_osk_cache_flushall();
-
- /* This function must also update the job status flag */
- job_status = subsystem->irq_handler_bottom_half( core );
-
- /* Retval is nonzero if the job is finished. */
- if ( JOB_STATUS_CONTINUE_RUN != job_status )
- {
- mali_core_renderunit_detach_job_from_core(core, SUBSYSTEM_RESCHEDULE, job_status);
- }
- else
- {
- switch ( core->state )
- {
- case CORE_WATCHDOG_TIMEOUT:
- MALI_DEBUG_PRINT(2, ("Watchdog SW Timeout of job from core: %s\n", core->description ));
- mali_core_renderunit_detach_job_from_core(core, SUBSYSTEM_RESCHEDULE, JOB_STATUS_END_TIMEOUT_SW );
- break;
-
- case CORE_POLL:
- MALI_DEBUG_PRINT(5, ("Poll core: %s\n", core->description )) ;
- core->state = CORE_WORKING;
- _mali_osk_timer_add( core->timer, 1);
- break;
-
- default:
- MALI_DEBUG_PRINT(4, ("IRQ: The job on the core continue to run: %s\n", core->description )) ;
- break;
- }
- }
-end_function:
- MALI_CORE_SUBSYSTEM_MUTEX_RELEASE(subsystem);
-}
-
-void subsystem_flush_mapped_mem_cache(void)
-{
- _mali_osk_cache_flushall();
- _mali_osk_mem_barrier();
-}
-
-#if USING_MALI_PMM
-
-_mali_osk_errcode_t mali_core_subsystem_signal_power_down(mali_core_subsystem *subsys, u32 mali_core_nr, mali_bool immediate_only)
-{
- mali_core_renderunit * core = NULL;
-
- MALI_CHECK_SUBSYSTEM(subsys);
- MALI_CORE_SUBSYSTEM_MUTEX_GRAB(subsys);
-
- /* It is possible that this signal funciton can be called during a driver exit,
- * and so the requested core may now be destroyed. (This is due to us not having
- * the subsys lock before signalling power down).
- * mali_core_renderunit_get_mali_core_nr() will report a Mali ERR because
- * the core number is out of range (which is a valid error in other cases).
- * So instead we check here (now that we have the subsys lock) and let the
- * caller cope with the core get failure and check that the core has
- * been unregistered in the PMM as part of its destruction.
- */
- if ( subsys->number_of_cores > mali_core_nr )
- {
- core = mali_core_renderunit_get_mali_core_nr(subsys, mali_core_nr);
- }
-
- if ( NULL == core )
- {
- /* Couldn't find the core */
- MALI_CORE_SUBSYSTEM_MUTEX_RELEASE(subsys);
- MALI_DEBUG_PRINT( 1, ("Core: Failed to find core to power down\n") );
- MALI_ERROR(_MALI_OSK_ERR_FAULT);
- }
- else if ( core->state != CORE_IDLE )
- {
- /* When powering down we either set a pending power down flag here so we
- * can power down cleanly after the job completes or we don't set the
- * flag if we have been asked to only do a power down right now
- * In either case, return that the core is busy
- */
- if ( !immediate_only ) core->pend_power_down = MALI_TRUE;
- MALI_CORE_SUBSYSTEM_MUTEX_RELEASE(subsys);
- MALI_DEBUG_PRINT( 5, ("Core: No idle core to power down\n") );
- MALI_ERROR(_MALI_OSK_ERR_BUSY);
- }
-
- /* Shouldn't have a pending power down flag set */
- MALI_DEBUG_ASSERT( !core->pend_power_down );
-
- /* Move core to off queue */
- mali_core_subsystem_move_core_set_off(core);
-
- MALI_CORE_SUBSYSTEM_MUTEX_RELEASE(subsys);
-
- MALI_SUCCESS;
-}
-
-_mali_osk_errcode_t mali_core_subsystem_signal_power_up(mali_core_subsystem *subsys, u32 mali_core_nr, mali_bool queue_only)
-{
- mali_core_renderunit * core;
-
- MALI_CHECK_SUBSYSTEM(subsys);
- MALI_CORE_SUBSYSTEM_MUTEX_GRAB(subsys);
-
- core = mali_core_renderunit_get_mali_core_nr(subsys, mali_core_nr);
-
- if( core == NULL )
- {
- /* Couldn't find the core */
- MALI_CORE_SUBSYSTEM_MUTEX_RELEASE(subsys);
- MALI_DEBUG_PRINT( 1, ("Core: Failed to find core to power up\n") );
- MALI_ERROR(_MALI_OSK_ERR_FAULT);
- }
- else if( core->state != CORE_OFF )
- {
- /* This will usually happen because we are trying to cancel a pending power down */
- core->pend_power_down = MALI_FALSE;
- MALI_CORE_SUBSYSTEM_MUTEX_RELEASE(subsys);
- MALI_DEBUG_PRINT( 1, ("Core: No powered off core to power up (cancelled power down?)\n") );
- MALI_ERROR(_MALI_OSK_ERR_BUSY);
- }
-
- /* Shouldn't have a pending power down set */
- MALI_DEBUG_ASSERT( !core->pend_power_down );
-
- /* Move core to idle queue */
- mali_core_subsystem_move_core_set_idle(core);
-
- if( !queue_only )
- {
- /* Reset MMU & core - core must be idle to allow this */
-#if USING_MMU
- if ( NULL!=core->mmu )
- {
-#if defined(USING_MALI200)
- if (core->pmm_id != MALI_PMM_CORE_PP0)
- {
-#endif
- mali_kernel_mmu_reset(core->mmu);
-#if defined(USING_MALI200)
- }
-#endif
-
- }
-#endif /* USING_MMU */
- subsys->reset_core( core, MALI_CORE_RESET_STYLE_RUNABLE );
- }
-
- /* Need to schedule work to start on this core */
- mali_core_subsystem_schedule(subsys);
-
- MALI_CORE_SUBSYSTEM_MUTEX_RELEASE(subsys);
-
- MALI_SUCCESS;
-}
-
-#endif /* USING_MALI_PMM */
-
-#if MALI_STATE_TRACKING
-u32 mali_core_renderunit_dump_state(mali_core_subsystem* subsystem, char *buf, u32 size)
-{
- u32 i, len = 0;
- mali_core_renderunit *core;
- mali_core_renderunit *tmp_core;
-
- mali_core_session* session;
- mali_core_session* tmp_session;
-
- if (0 >= size)
- {
- return 0;
- }
-
- MALI_CORE_SUBSYSTEM_MUTEX_GRAB( subsystem );
-
- len += _mali_osk_snprintf(buf + len, size - len, "Subsystem:\n");
- len += _mali_osk_snprintf(buf + len, size - len, " Name: %s\n", subsystem->name);
-
- for (i = 0; i < subsystem->number_of_cores; i++)
- {
- len += _mali_osk_snprintf(buf + len, size - len, " Core: #%u\n",
- subsystem->mali_core_array[i]->core_number);
- len += _mali_osk_snprintf(buf + len, size - len, " Description: %s\n",
- subsystem->mali_core_array[i]->description);
- switch(subsystem->mali_core_array[i]->state)
- {
- case CORE_IDLE:
- len += _mali_osk_snprintf(buf + len, size - len, " State: CORE_IDLE\n");
- break;
- case CORE_WORKING:
- len += _mali_osk_snprintf(buf + len, size - len, " State: CORE_WORKING\n");
- break;
- case CORE_WATCHDOG_TIMEOUT:
- len += _mali_osk_snprintf(buf + len, size - len, " State: CORE_WATCHDOG_TIMEOUT\n");
- break;
- case CORE_POLL:
- len += _mali_osk_snprintf(buf + len, size - len, " State: CORE_POLL\n");
- break;
- case CORE_HANG_CHECK_TIMEOUT:
- len += _mali_osk_snprintf(buf + len, size - len, " State: CORE_HANG_CHECK_TIMEOUT\n");
- break;
- case CORE_OFF:
- len += _mali_osk_snprintf(buf + len, size - len, " State: CORE_OFF\n");
- break;
- default:
- len += _mali_osk_snprintf(buf + len, size - len, " State: Unknown (0x%X)\n",
- subsystem->mali_core_array[i]->state);
- break;
- }
- len += _mali_osk_snprintf(buf + len, size - len, " Current job: 0x%X\n",
- (u32)(subsystem->mali_core_array[i]->current_job));
- if (subsystem->mali_core_array[i]->current_job)
- {
- u64 time_used_nano_seconds;
- u32 time_used_micro_seconds;
- u64 time_now = _mali_osk_time_get_ns();
-
- time_used_nano_seconds = time_now - subsystem->mali_core_array[i]->current_job->start_time;
- time_used_micro_seconds = ((u32)(time_used_nano_seconds)) / 1000;
-
- len += _mali_osk_snprintf(buf + len, size - len, " Current job session: 0x%X\n",
- subsystem->mali_core_array[i]->current_job->session);
- len += _mali_osk_snprintf(buf + len, size - len, " Current job number: %d\n",
- subsystem->mali_core_array[i]->current_job->job_nr);
- len += _mali_osk_snprintf(buf + len, size - len, " Current job render_time micro seconds: %d\n",
- time_used_micro_seconds );
- len += _mali_osk_snprintf(buf + len, size - len, " Current job start time micro seconds: %d\n",
- (u32) (subsystem->mali_core_array[i]->current_job->start_time >>10) );
- }
- len += _mali_osk_snprintf(buf + len, size - len, " Core version: 0x%X\n",
- subsystem->mali_core_array[i]->core_version);
-#if USING_MALI_PMM
- len += _mali_osk_snprintf(buf + len, size - len, " PMM id: 0x%X\n",
- subsystem->mali_core_array[i]->pmm_id);
- len += _mali_osk_snprintf(buf + len, size - len, " Power down requested: %s\n",
- subsystem->mali_core_array[i]->pend_power_down ? "TRUE" : "FALSE");
-#endif
- }
-
- len += _mali_osk_snprintf(buf + len, size - len, " Cores on idle list:\n");
- _MALI_OSK_LIST_FOREACHENTRY(core, tmp_core, &subsystem->renderunit_idle_head, mali_core_renderunit, list)
- {
- len += _mali_osk_snprintf(buf + len, size - len, " Core #%u\n", core->core_number);
- }
-
- len += _mali_osk_snprintf(buf + len, size - len, " Cores on off list:\n");
- _MALI_OSK_LIST_FOREACHENTRY(core, tmp_core, &subsystem->renderunit_off_head, mali_core_renderunit, list)
- {
- len += _mali_osk_snprintf(buf + len, size - len, " Core #%u\n", core->core_number);
- }
-
- len += _mali_osk_snprintf(buf + len, size - len, " Connected sessions:\n");
- _MALI_OSK_LIST_FOREACHENTRY(session, tmp_session, &subsystem->all_sessions_head, mali_core_session, all_sessions_list)
- {
- len += _mali_osk_snprintf(buf + len, size - len,
- " Session 0x%X:\n", (u32)session);
- len += _mali_osk_snprintf(buf + len, size - len,
- " Queue depth: %u\n", mali_job_queue_size(session));
- len += _mali_osk_snprintf(buf + len, size - len,
- " First waiting job: 0x%p\n", session->queue[session->queue_head]);
- len += _mali_osk_snprintf(buf + len, size - len, " Notification queue: %s\n",
- _mali_osk_notification_queue_is_empty(session->notification_queue) ? "EMPTY" : "NON-EMPTY");
- len += _mali_osk_snprintf(buf + len, size - len,
- " Jobs received:%4d\n", _mali_osk_atomic_read(&session->jobs_received));
- len += _mali_osk_snprintf(buf + len, size - len,
- " Jobs started :%4d\n", _mali_osk_atomic_read(&session->jobs_started));
- len += _mali_osk_snprintf(buf + len, size - len,
- " Jobs ended :%4d\n", _mali_osk_atomic_read(&session->jobs_ended));
- len += _mali_osk_snprintf(buf + len, size - len,
- " Jobs returned:%4d\n", _mali_osk_atomic_read(&session->jobs_returned));
- len += _mali_osk_snprintf(buf + len, size - len, " PID: %d\n", session->pid);
- }
-
- len += _mali_osk_snprintf(buf + len, size - len, " Waiting sessions sum all priorities: %u\n",
- subsystem->awaiting_sessions_sum_all_priorities);
- for (i = 0; i < PRIORITY_LEVELS; i++)
- {
- len += _mali_osk_snprintf(buf + len, size - len, " Waiting sessions with priority %u:\n", i);
- _MALI_OSK_LIST_FOREACHENTRY(session, tmp_session, &subsystem->awaiting_sessions_head[i],
- mali_core_session, awaiting_sessions_list)
- {
- len += _mali_osk_snprintf(buf + len, size - len, " Session 0x%X:\n", (u32)session);
- len += _mali_osk_snprintf(buf + len, size - len, " Waiting job: 0x%X\n",
- (u32)session->queue[session->queue_head]);
- len += _mali_osk_snprintf(buf + len, size - len, " Notification queue: %s\n",
- _mali_osk_notification_queue_is_empty(session->notification_queue) ? "EMPTY" : "NON-EMPTY");
- }
- }
-
- MALI_CORE_SUBSYSTEM_MUTEX_RELEASE( subsystem );
- return len;
-}
-#endif
diff --git a/drivers/media/video/samsung/mali/common/mali_kernel_rendercore.h b/drivers/media/video/samsung/mali/common/mali_kernel_rendercore.h
deleted file mode 100644
index 5fbe686..0000000
--- a/drivers/media/video/samsung/mali/common/mali_kernel_rendercore.h
+++ /dev/null
@@ -1,565 +0,0 @@
-/*
- * 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_RENDERCORE_H__
-#define __MALI_RENDERCORE_H__
-
-#include "mali_osk.h"
-#include "mali_kernel_common.h"
-#include "mali_kernel_subsystem.h"
-
-#define PRIORITY_LEVELS 3
-#define PRIORITY_MAX 0
-#define PRIORITY_MIN (PRIORITY_MAX+PRIORITY_LEVELS-1)
-
-/* This file contains what we need in kernel for all core types. */
-
-typedef enum
-{
- CORE_IDLE, /**< Core is ready for a new job */
- CORE_WORKING, /**< Core is working on a job */
- CORE_WATCHDOG_TIMEOUT, /**< Core is working but it has timed out */
- CORE_POLL, /**< Poll timer triggered, pending handling */
- CORE_HANG_CHECK_TIMEOUT,/**< Timeout for hang detection */
- CORE_OFF /**< Core is powered off */
-} mali_core_status;
-
-typedef enum
-{
- SUBSYSTEM_RESCHEDULE,
- SUBSYSTEM_WAIT
-} mali_subsystem_reschedule_option;
-
-typedef enum
-{
- MALI_CORE_RESET_STYLE_RUNABLE,
- MALI_CORE_RESET_STYLE_DISABLE,
- MALI_CORE_RESET_STYLE_HARD
-} mali_core_reset_style;
-
-typedef enum
-{
- JOB_STATUS_CONTINUE_RUN = 0x01,
- JOB_STATUS_END_SUCCESS = 1<<(16+0),
- JOB_STATUS_END_OOM = 1<<(16+1),
- JOB_STATUS_END_ABORT = 1<<(16+2),
- JOB_STATUS_END_TIMEOUT_SW = 1<<(16+3),
- JOB_STATUS_END_HANG = 1<<(16+4),
- JOB_STATUS_END_SEG_FAULT = 1<<(16+5),
- JOB_STATUS_END_ILLEGAL_JOB = 1<<(16+6),
- JOB_STATUS_END_UNKNOWN_ERR = 1<<(16+7),
- JOB_STATUS_END_SHUTDOWN = 1<<(16+8),
- JOB_STATUS_END_SYSTEM_UNUSABLE = 1<<(16+9)
-} mali_subsystem_job_end_code;
-
-
-struct mali_core_job;
-struct mali_core_subsystem;
-struct mali_core_renderunit;
-struct mali_core_session;
-
-/* We have one of these subsystems for each core type */
-typedef struct mali_core_subsystem
-{
- struct mali_core_renderunit ** mali_core_array; /* An array of all cores of this type */
- u32 number_of_cores; /* Number of cores in this list */
-
- _mali_core_type core_type;
-
- u32 magic_nr;
-
- _mali_osk_list_t renderunit_idle_head; /* Idle cores of this type */
- _mali_osk_list_t renderunit_off_head; /* Powered off cores of this type */
-
- /* Linked list for each priority of sessions with a job ready for scheduelling */
- _mali_osk_list_t awaiting_sessions_head[PRIORITY_LEVELS];
- u32 awaiting_sessions_sum_all_priorities;
-
- /* Linked list of all sessions connected to this coretype */
- _mali_osk_list_t all_sessions_head;
-
- /* Linked list of all sessions connected to this coretype */
- struct _mali_osk_notification_queue_t * notification_queue;
-
- const char * name;
- mali_kernel_subsystem_identifier id;
-
- /**** Functions registered for this core type. Set during mali_core_init ******/
- /* Start this job on this core. Return MALI_TRUE if the job was started. */
- _mali_osk_errcode_t (*start_job)(struct mali_core_job * job, struct mali_core_renderunit * core);
-
- /* Check if given core has an interrupt pending. Return MALI_TRUE and set mask to 0 if pending */
- u32 (*irq_handler_upper_half)(struct mali_core_renderunit * core);
-
- /* This function should check if the interrupt indicates that job was finished.
- If so it should update the job-struct, reset the core registers, and return MALI_TRUE, .
- If the job is still working after this function it should return MALI_FALSE.
- The function must also enable the bits in the interrupt mask for the core.
- Called by the bottom half interrupt function. */
- int (*irq_handler_bottom_half)(struct mali_core_renderunit* core);
-
- /* This function is called from the ioctl function and should return a mali_core_job pointer
- to a created mali_core_job object with the data given from userspace */
- _mali_osk_errcode_t (*get_new_job_from_user)(struct mali_core_session * session, void * argument);
-
- _mali_osk_errcode_t (*suspend_response)(struct mali_core_session * session, void * argument);
-
- /* This function is called from the ioctl function and should write the necessary data
- to userspace telling which job was finished and the status and debuginfo for this job.
- The function must also free and cleanup the input job object. */
- void (*return_job_to_user)(struct mali_core_job * job, mali_subsystem_job_end_code end_status);
-
- /* Is called when a subsystem shuts down. This function needs to
- release internal pointers in the core struct, and free the
- core struct before returning.
- It is not allowed to write to any registers, since this
- unmapping is already done. */
- void (*renderunit_delete)(struct mali_core_renderunit * core);
-
- /* Is called when we want to abort a job that is running on the core.
- This is done if program exits while core is running */
- void (*reset_core)(struct mali_core_renderunit * core, mali_core_reset_style style);
-
- /* Is called when the rendercore wants the core to give an interrupt */
- void (*probe_core_irq_trigger)(struct mali_core_renderunit* core);
-
- /* Is called when the irq probe wants the core to acknowledge an interrupt from the hw */
- _mali_osk_errcode_t (*probe_core_irq_acknowledge)(struct mali_core_renderunit* core);
-
- /* Called when the rendercore want to issue a bus stop request to a core */
- void (*stop_bus)(struct mali_core_renderunit* core);
-} mali_core_subsystem;
-
-
-/* Per core data. This must be embedded into each core type internal core info. */
-typedef struct mali_core_renderunit
-{
- struct mali_core_subsystem * subsystem; /* The core belongs to this subsystem */
- _mali_osk_list_t list; /* Is always in subsystem->idle_list OR session->renderunits_working */
- mali_core_status state;
- mali_bool error_recovery; /* Indicates if the core is waiting for external help to recover (typically the MMU) */
- mali_bool in_detach_function;
- struct mali_core_job * current_job; /* Current job being processed on this core ||NULL */
- u32 magic_nr;
- _mali_osk_timer_t * timer;
- _mali_osk_timer_t * timer_hang_detection;
-
- mali_io_address registers_mapped; /* IO-mapped pointer to registers */
- u32 registers_base_addr; /* Base addres of the registers */
- u32 size; /* The size of registers_mapped */
- const char * description; /* Description of this core. */
- u32 irq_nr; /* The IRQ nr for this core */
- u32 core_version;
-#if USING_MMU
- u32 mmu_id;
- void * mmu; /* The MMU this rendercore is behind.*/
-#endif
-#if USING_MALI_PMM
- mali_pmm_core_id pmm_id; /* The PMM core id */
- mali_bool pend_power_down; /* Power down is requested */
-#endif
-
- u32 core_number; /* 0 for first detected core of this type, 1 for second and so on */
-
- _mali_osk_irq_t *irq;
-} mali_core_renderunit;
-
-
-#define MALI_JOB_QUEUE_SIZE 8
-/* Per open FILE data. */
-/* You must held subsystem->mutex before any transactions to this datatype. */
-typedef struct mali_core_session
-{
- struct mali_core_subsystem * subsystem; /* The session belongs to this subsystem */
- _mali_osk_list_t renderunits_working_head; /* List of renderunits working for this session */
- struct mali_core_job *queue[MALI_JOB_QUEUE_SIZE]; /* The next job from this session to run */
- int queue_head;
- int queue_tail;
- int queue_size;
-
- _mali_osk_list_t awaiting_sessions_list; /* Linked list of sessions with jobs, for each priority */
- _mali_osk_list_t all_sessions_list; /* Linked list of all sessions on the system. */
-
- _mali_osk_notification_queue_t * notification_queue; /* Messages back to Base in userspace*/
-#if USING_MMU
- struct mali_session_data * mmu_session; /* The session associated with the MMU page tables for this core */
-#endif
- u32 magic_nr;
-#if MALI_STATE_TRACKING
- _mali_osk_atomic_t jobs_received;
- _mali_osk_atomic_t jobs_started;
- _mali_osk_atomic_t jobs_ended;
- _mali_osk_atomic_t jobs_returned;
- u32 pid;
-#endif
-} mali_core_session;
-
-/* This must be embedded into a specific mali_core_job struct */
-/* use this macro to get spesific mali_core_job: container_of(ptr, type, member)*/
-typedef struct mali_core_job
-{
- _mali_osk_list_t list; /* Linked list of jobs. Used by struct mali_core_session */
- struct mali_core_session *session;
- u32 magic_nr;
- u32 priority;
- u32 watchdog_msecs;
- u32 render_time_usecs ;
- u64 start_time;
- unsigned long watchdog_jiffies;
- u32 abort_id;
- u32 job_nr;
- _mali_uk_start_job_flags flags;
-} mali_core_job;
-
-MALI_STATIC_INLINE mali_bool mali_job_queue_empty(mali_core_session *session)
-{
- if (0 == session->queue_size)
- {
- return MALI_TRUE;
- }
- return MALI_FALSE;
-}
-
-MALI_STATIC_INLINE mali_bool mali_job_queue_full(mali_core_session *session)
-{
- if (MALI_JOB_QUEUE_SIZE == session->queue_size)
- {
- return MALI_TRUE;
- }
- return MALI_FALSE;
-}
-
-
-MALI_STATIC_INLINE _mali_osk_errcode_t mali_job_queue_add_job(mali_core_session *session, struct mali_core_job *job)
-{
- if (mali_job_queue_full(session))
- {
- MALI_ERROR(_MALI_OSK_ERR_FAULT);
- }
-
- session->queue[session->queue_tail] = job;
- session->queue_tail = (session->queue_tail + 1) % MALI_JOB_QUEUE_SIZE;
- session->queue_size++;
-
- MALI_SUCCESS;
-}
-
-MALI_STATIC_INLINE struct mali_core_job *mali_job_queue_get_job(mali_core_session *session)
-{
- struct mali_core_job *job;
- MALI_DEBUG_ASSERT(!mali_job_queue_empty(session));
-
- job = session->queue[session->queue_head];
-
- MALI_DEBUG_ASSERT_POINTER(job);
-
- session->queue[session->queue_head] = NULL;
- session->queue_head = (session->queue_head + 1) % MALI_JOB_QUEUE_SIZE;
- session->queue_size--;
-
- return job;
-}
-
-MALI_STATIC_INLINE u32 mali_job_queue_size(mali_core_session *session)
-{
- return (u32)(session->queue_size);
-}
-
-MALI_STATIC_INLINE struct mali_core_job *mali_job_queue_abort_job(mali_core_session *session, u32 abort_id)
-{
- int i;
- int n;
- struct mali_core_job *job = NULL;
-
- for (i = session->queue_head, n = session->queue_size; n > 0; n--, i = (i+1)%MALI_JOB_QUEUE_SIZE)
- {
- if (session->queue[i]->abort_id == abort_id)
- {
- /* Remove job from queue */
- job = session->queue[i];
- session->queue[i] = NULL;
-
- session->queue_size -= 1;
- n--;
- break;
- }
- }
- if (NULL == job)
- {
- return NULL;
- }
-
- /* Rearrange queue */
- while (n > 0)
- {
- int next = (i + 1) % MALI_JOB_QUEUE_SIZE;
- session->queue[i] = session->queue[next];
- i = next;
- n--;
- }
- session->queue_tail = i;
-
- return job;
-}
-
-
-/*
- * The rendercode subsystem is included in the subsystems[] array.
- */
-extern struct mali_kernel_subsystem mali_subsystem_rendercore;
-
-void subsystem_flush_mapped_mem_cache(void);
-
-
-#define SUBSYSTEM_MAGIC_NR 0xdeadbeef
-#define CORE_MAGIC_NR 0xcafebabe
-#define SESSION_MAGIC_NR 0xbabe1234
-#define JOB_MAGIC_NR 0x0123abcd
-
-
-#define MALI_CHECK_SUBSYSTEM(subsystem)\
- do { \
- if ( SUBSYSTEM_MAGIC_NR != subsystem->magic_nr) MALI_PRINT_ERROR(("Wrong magic number"));\
- } while (0)
-
-#define MALI_CHECK_CORE(CORE)\
- do { \
- if ( CORE_MAGIC_NR != CORE->magic_nr) MALI_PRINT_ERROR(("Wrong magic number"));\
-} while (0)
-
-#define MALI_CHECK_SESSION(SESSION)\
- do { \
- if ( SESSION_MAGIC_NR != SESSION->magic_nr) MALI_PRINT_ERROR(("Wrong magic number"));\
-} while (0)
-
-#define MALI_CHECK_JOB(JOB)\
- do { \
- if ( JOB_MAGIC_NR != JOB->magic_nr) MALI_PRINT_ERROR(("Wrong magic number"));\
-} while (0)
-
-
-/* Check if job_a has higher priority than job_b */
-MALI_STATIC_INLINE int job_has_higher_priority(mali_core_job * job_a, mali_core_job * job_b)
-{
- /* The lowest number has the highest priority */
- return (int) (job_a->priority < job_b->priority);
-}
-
-MALI_STATIC_INLINE void job_priority_set(mali_core_job * job, u32 priority)
-{
- if (priority > PRIORITY_MIN) job->priority = PRIORITY_MIN;
- else job->priority = priority;
-}
-
-void job_watchdog_set(mali_core_job * job, u32 watchdog_msecs);
-
-/* For use by const default register settings (e.g. set these after reset) */
-typedef struct register_address_and_value
-{
- u32 address;
- u32 value;
-} register_address_and_value ;
-
-
-/* For use by dynamic default register settings (e.g. set these after reset) */
-typedef struct register_address_and_value_list
-{
- _mali_osk_list_t list;
- register_address_and_value item;
-} register_address_and_value_list ;
-
-/* Used if the user wants to set a continious block of registers */
-typedef struct register_array_user
-{
- u32 entries_in_array;
- u32 start_address;
- void __user * reg_array;
-}register_array_user;
-
-
-#define MALI_CORE_SUBSYSTEM_MUTEX_GRAB(subsys) \
- do { \
- MALI_DEBUG_PRINT(5, ("MUTEX: GRAB %s() %d on %s\n",__FUNCTION__, __LINE__, subsys->name)); \
- _mali_osk_lock_wait( rendercores_global_mutex, _MALI_OSK_LOCKMODE_RW); \
- MALI_DEBUG_PRINT(5, ("MUTEX: GRABBED %s() %d on %s\n",__FUNCTION__, __LINE__, subsys->name)); \
- if ( SUBSYSTEM_MAGIC_NR != subsys->magic_nr ) MALI_PRINT_ERROR(("Wrong magic number"));\
- rendercores_global_mutex_is_held = 1; \
- rendercores_global_mutex_owner = _mali_osk_get_tid(); \
- } while (0) ;
-
-#define MALI_CORE_SUBSYSTEM_MUTEX_RELEASE(subsys) \
- do { \
- MALI_DEBUG_PRINT(5, ("MUTEX: RELEASE %s() %d on %s\n",__FUNCTION__, __LINE__, subsys->name)); \
- rendercores_global_mutex_is_held = 0; \
- rendercores_global_mutex_owner = 0; \
- if ( SUBSYSTEM_MAGIC_NR != subsys->magic_nr ) MALI_PRINT_ERROR(("Wrong magic number"));\
- _mali_osk_lock_signal( rendercores_global_mutex, _MALI_OSK_LOCKMODE_RW); \
- MALI_DEBUG_PRINT(5, ("MUTEX: RELEASED %s() %d on %s\n",__FUNCTION__, __LINE__, subsys->name)); \
- if ( SUBSYSTEM_MAGIC_NR != subsys->magic_nr ) MALI_PRINT_ERROR(("Wrong magic number"));\
- } while (0) ;
-
-
-#define MALI_ASSERT_MUTEX_IS_GRABBED(input_pointer)\
- do { \
- if ( 0 == rendercores_global_mutex_is_held ) MALI_PRINT_ERROR(("ASSERT MUTEX SHOULD BE GRABBED"));\
- if ( SUBSYSTEM_MAGIC_NR != input_pointer->magic_nr ) MALI_PRINT_ERROR(("Wrong magic number"));\
- if ( rendercores_global_mutex_owner != _mali_osk_get_tid() ) MALI_PRINT_ERROR(("Owner mismatch"));\
- } while (0)
-
-MALI_STATIC_INLINE _mali_osk_errcode_t mali_core_renderunit_register_rw_check(mali_core_renderunit *core,
- u32 relative_address)
-{
-#if USING_MALI_PMM
- if( core->state == CORE_OFF )
- {
- MALI_PRINT_ERROR(("Core is OFF during access: Core: %s Addr: 0x%04X\n",
- core->description,relative_address));
- MALI_ERROR(_MALI_OSK_ERR_FAULT);
- }
-#endif
-
- MALI_DEBUG_ASSERT((relative_address & 0x03) == 0);
-
- if (mali_benchmark) MALI_ERROR(_MALI_OSK_ERR_FAULT);
-
- MALI_DEBUG_CODE(if (relative_address >= core->size)
- {
- MALI_PRINT_ERROR(("Trying to access illegal register: 0x%04x in core: %s",
- relative_address, core->description));
- MALI_ERROR(_MALI_OSK_ERR_FAULT);
- })
-
- MALI_SUCCESS;
-}
-
-
-MALI_STATIC_INLINE u32 mali_core_renderunit_register_read(struct mali_core_renderunit *core, u32 relative_address)
-{
- u32 read_val;
-
- if(_MALI_OSK_ERR_FAULT == mali_core_renderunit_register_rw_check(core, relative_address))
- return 0xDEADBEEF;
-
- read_val = _mali_osk_mem_ioread32(core->registers_mapped, relative_address);
-
- MALI_DEBUG_PRINT(6, ("Core: renderunit_register_read: Core:%s Addr:0x%04X Val:0x%08x\n",
- core->description,relative_address, read_val));
-
- return read_val;
-}
-
-MALI_STATIC_INLINE void mali_core_renderunit_register_read_array(struct mali_core_renderunit *core,
- u32 relative_address,
- u32 * result_array,
- u32 nr_of_regs)
-{
- /* NOTE Do not use burst reads against the registers */
- u32 i;
-
- MALI_DEBUG_PRINT(6, ("Core: renderunit_register_read_array: Core:%s Addr:0x%04X Nr_regs: %u\n",
- core->description,relative_address, nr_of_regs));
-
- for(i=0; i<nr_of_regs; ++i)
- {
- result_array[i] = mali_core_renderunit_register_read(core, relative_address + i*4);
- }
-}
-
-/*
- * Write to a core register, and bypass implied memory barriers.
- *
- * On some systems, _mali_osk_mem_iowrite32() implies a memory barrier. This
- * can be a performance problem when doing many writes in sequence.
- *
- * When using this function, ensure proper barriers are put in palce. Most
- * likely a _mali_osk_mem_barrier() is needed after all related writes are
- * completed.
- *
- */
-MALI_STATIC_INLINE void mali_core_renderunit_register_write_relaxed(mali_core_renderunit *core,
- u32 relative_address,
- u32 new_val)
-{
- if(_MALI_OSK_ERR_FAULT == mali_core_renderunit_register_rw_check(core, relative_address))
- return;
-
- MALI_DEBUG_PRINT(6, ("mali_core_renderunit_register_write_relaxed: Core:%s Addr:0x%04X Val:0x%08x\n",
- core->description,relative_address, new_val));
-
- _mali_osk_mem_iowrite32_relaxed(core->registers_mapped, relative_address, new_val);
-}
-
-MALI_STATIC_INLINE void mali_core_renderunit_register_write(struct mali_core_renderunit *core,
- u32 relative_address,
- u32 new_val)
-{
- MALI_DEBUG_PRINT(6, ("mali_core_renderunit_register_write: Core:%s Addr:0x%04X Val:0x%08x\n",
- core->description,relative_address, new_val));
-
- if(_MALI_OSK_ERR_FAULT == mali_core_renderunit_register_rw_check(core, relative_address))
- return;
-
- _mali_osk_mem_iowrite32(core->registers_mapped, relative_address, new_val);
-}
-
-MALI_STATIC_INLINE void mali_core_renderunit_register_write_array(struct mali_core_renderunit *core,
- u32 relative_address,
- u32 * write_array,
- u32 nr_of_regs)
-{
- u32 i;
- MALI_DEBUG_PRINT(6, ("Core: renderunit_register_write_array: Core:%s Addr:0x%04X Nr_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_core_renderunit_register_write_relaxed(core, relative_address + i*4, write_array[i]);
- }
-}
-
-_mali_osk_errcode_t mali_core_renderunit_init(struct mali_core_renderunit * core);
-void mali_core_renderunit_term(struct mali_core_renderunit * core);
-int mali_core_renderunit_map_registers(struct mali_core_renderunit *core);
-void mali_core_renderunit_unmap_registers(struct mali_core_renderunit *core);
-int mali_core_renderunit_irq_handler_add(struct mali_core_renderunit *core);
-mali_core_renderunit * mali_core_renderunit_get_mali_core_nr(mali_core_subsystem *subsys, u32 mali_core_nr);
-
-int mali_core_subsystem_init(struct mali_core_subsystem * new_subsys);
-#if USING_MMU
-void mali_core_subsystem_attach_mmu(mali_core_subsystem* subsys);
-#endif
-int mali_core_subsystem_register_renderunit(struct mali_core_subsystem * subsys, struct mali_core_renderunit * core);
-int mali_core_subsystem_system_info_fill(mali_core_subsystem* subsys, _mali_system_info* info);
-void mali_core_subsystem_cleanup(struct mali_core_subsystem * subsys);
-#if USING_MMU
-void mali_core_subsystem_broadcast_notification(struct mali_core_subsystem * subsys, mali_core_notification_message message, u32 data);
-#endif
-void mali_core_session_begin(mali_core_session *session);
-void mali_core_session_close(mali_core_session * session);
-int mali_core_session_add_job(mali_core_session * session, mali_core_job *job, mali_core_job **job_return);
-u32 mali_core_hang_check_timeout_get(void);
-
-_mali_osk_errcode_t mali_core_subsystem_ioctl_start_job(mali_core_session * session, void *job_data);
-_mali_osk_errcode_t mali_core_subsystem_ioctl_number_of_cores_get(mali_core_session * session, u32 *number_of_cores);
-_mali_osk_errcode_t mali_core_subsystem_ioctl_core_version_get(mali_core_session * session, _mali_core_version *version);
-_mali_osk_errcode_t mali_core_subsystem_ioctl_suspend_response(mali_core_session * session, void* argument);
-void mali_core_subsystem_ioctl_abort_job(mali_core_session * session, u32 id);
-
-#if USING_MALI_PMM
-_mali_osk_errcode_t mali_core_subsystem_signal_power_down(mali_core_subsystem *subsys, u32 mali_core_nr, mali_bool immediate_only);
-_mali_osk_errcode_t mali_core_subsystem_signal_power_up(mali_core_subsystem *subsys, u32 mali_core_nr, mali_bool queue_only);
-#endif
-
-#if MALI_STATE_TRACKING
-u32 mali_core_renderunit_dump_state(mali_core_subsystem* subsystem, char *buf, u32 size);
-#endif
-
-#endif /* __MALI_RENDERCORE_H__ */
diff --git a/drivers/media/video/samsung/mali/common/mali_kernel_subsystem.h b/drivers/media/video/samsung/mali/common/mali_kernel_subsystem.h
deleted file mode 100644
index 8f05216..0000000
--- a/drivers/media/video/samsung/mali/common/mali_kernel_subsystem.h
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * 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_subsystem.h
- */
-
-#ifndef __MALI_KERNEL_SUBSYSTEM_H__
-#define __MALI_KERNEL_SUBSYSTEM_H__
-
-#include "mali_osk.h"
-#include "mali_uk_types.h"
-#include "mali_kernel_common.h"
-#include "mali_kernel_session_manager.h"
-
-/* typedefs of the datatypes used in the hook functions */
-typedef void * mali_kernel_subsystem_session_slot;
-typedef int mali_kernel_subsystem_identifier;
-typedef _mali_osk_errcode_t (*mali_kernel_resource_registrator)(_mali_osk_resource_t *);
-
-/**
- * Broadcast notification messages
- */
-typedef enum mali_core_notification_message
-{
- MMU_KILL_STEP0_LOCK_SUBSYSTEM, /**< Request to lock subsystem */
- MMU_KILL_STEP1_STOP_BUS_FOR_ALL_CORES, /**< Request to stop all buses */
- MMU_KILL_STEP2_RESET_ALL_CORES_AND_ABORT_THEIR_JOBS, /**< Request kill all jobs, and not start more jobs */
- MMU_KILL_STEP3_CONTINUE_JOB_HANDLING, /**< Request to continue with new jobs on all cores */
- MMU_KILL_STEP4_UNLOCK_SUBSYSTEM /**< Request to unlock subsystem */
-} mali_core_notification_message;
-
-/**
- * A function pointer can be NULL if the subsystem isn't interested in the event.
- */
-typedef struct mali_kernel_subsystem
-{
- /* subsystem control */
- _mali_osk_errcode_t (*startup)(mali_kernel_subsystem_identifier id); /**< Called during module load or system startup*/
- void (*shutdown)(mali_kernel_subsystem_identifier id); /**< Called during module unload or system shutdown */
-
- /**
- * Called during module load or system startup.
- * Called when all subsystems have reported startup OK and all resources where successfully initialized
- */
- _mali_osk_errcode_t (*load_complete)(mali_kernel_subsystem_identifier id);
-
- /* per subsystem handlers */
- _mali_osk_errcode_t (*system_info_fill)(_mali_system_info* info); /**< Fill info into info struct. MUST allocate memory with kmalloc, since it's kfree'd */
-
- /* per session handlers */
- /**
- * Informs about a new session.
- * slot can be used to track per-session per-subsystem data.
- * queue can be used to send events to user space.
- * _mali_osk_errcode_t error return value.
- */
- _mali_osk_errcode_t (*session_begin)(struct mali_session_data * mali_session_data, mali_kernel_subsystem_session_slot * slot, _mali_osk_notification_queue_t * queue);
- /**
- * Informs that a session is ending
- * slot was the same as given during session_begin
- */
- void (*session_end)(struct mali_session_data * mali_session_data, mali_kernel_subsystem_session_slot * slot);
-
- /* Used by subsystems to send messages to each other. This is the receiving end */
- void (*broadcast_notification)(mali_core_notification_message message, u32 data);
-
-#if MALI_STATE_TRACKING
- /** Dump the current state of the subsystem */
- u32 (*dump_state)(char *buf, u32 size);
-#endif
-} mali_kernel_subsystem;
-
-/* functions used by the subsystems to interact with the core */
-/**
- * Register a resouce handler
- * @param type The resoruce type to register a handler for
- * @param handler Pointer to the function handling this resource
- * @return _MALI_OSK_ERR_OK on success. Otherwise, a suitable _mali_osk_errcode_t error.
- */
-_mali_osk_errcode_t _mali_kernel_core_register_resource_handler(_mali_osk_resource_type_t type, mali_kernel_resource_registrator handler);
-
-/* function used to interact with other subsystems */
-/**
- * Broadcast a message
- * Sends a message to all subsystems which have registered a broadcast notification handler
- * @param message The message to send
- * @param data Message specific extra data
- */
-void _mali_kernel_core_broadcast_subsystem_message(mali_core_notification_message message, u32 data);
-
-#if MALI_STATE_TRACKING
-/**
- * Tell all subsystems to dump their current state
- */
-u32 _mali_kernel_core_dump_state(char *buf, u32 size);
-#endif
-
-
-#endif /* __MALI_KERNEL_SUBSYSTEM_H__ */
diff --git a/drivers/media/video/samsung/mali/common/mali_kernel_utilization.c b/drivers/media/video/samsung/mali/common/mali_kernel_utilization.c
index b43b872..a374dbf 100644
--- a/drivers/media/video/samsung/mali/common/mali_kernel_utilization.c
+++ b/drivers/media/video/samsung/mali/common/mali_kernel_utilization.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 ARM Limited. All rights reserved.
+ * 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.
@@ -27,7 +27,7 @@ static _mali_osk_timer_t *utilization_timer = NULL;
static mali_bool timer_running = MALI_FALSE;
-static void calculate_gpu_utilization(void *arg)
+static void calculate_gpu_utilization(void* arg)
{
u64 time_now;
u64 time_period;
@@ -39,7 +39,8 @@ static void calculate_gpu_utilization(void *arg)
_mali_osk_lock_wait(time_data_lock, _MALI_OSK_LOCKMODE_RW);
- if (accumulated_work_time == 0 && work_start_time == 0) {
+ if (accumulated_work_time == 0 && work_start_time == 0)
+ {
/* Don't reschedule timer, this will be started if new work arrives */
timer_running = MALI_FALSE;
@@ -55,7 +56,8 @@ static void calculate_gpu_utilization(void *arg)
time_period = time_now - period_start_time;
/* If we are currently busy, update working period up to now */
- if (work_start_time != 0) {
+ if (work_start_time != 0)
+ {
accumulated_work_time += (time_now - work_start_time);
work_start_time = time_now;
}
@@ -79,10 +81,13 @@ static void calculate_gpu_utilization(void *arg)
* (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) {
+ if (period_normalized > 0x00FFFFFF)
+ {
/* The divisor is so big that it is safe to shift it down */
period_normalized >>= 8;
- } else {
+ }
+ else
+ {
/*
* The divisor is so small that we can shift up the dividend, without loosing any data.
* (dividend is always smaller than the divisor)
@@ -99,22 +104,25 @@ static void calculate_gpu_utilization(void *arg)
_mali_osk_timer_add(utilization_timer, _mali_osk_time_mstoticks(MALI_GPU_UTILIZATION_TIMEOUT));
+
mali_gpu_utilization_handler(utilization);
}
-
-
_mali_osk_errcode_t mali_utilization_init(void)
{
- time_data_lock = _mali_osk_lock_init( _MALI_OSK_LOCKFLAG_SPINLOCK_IRQ|_MALI_OSK_LOCKFLAG_NONINTERRUPTABLE, 0, 0 );
+ 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;
-
+ }
_mali_osk_atomic_init(&num_running_cores, 0);
utilization_timer = _mali_osk_timer_init();
- if (NULL == utilization_timer) {
+ if (NULL == utilization_timer)
+ {
_mali_osk_lock_term(time_data_lock);
return _MALI_OSK_ERR_FAULT;
}
@@ -125,7 +133,8 @@ _mali_osk_errcode_t mali_utilization_init(void)
void mali_utilization_suspend(void)
{
- if (NULL != utilization_timer) {
+ if (NULL != utilization_timer)
+ {
_mali_osk_timer_del(utilization_timer);
timer_running = MALI_FALSE;
}
@@ -133,7 +142,8 @@ void mali_utilization_suspend(void)
void mali_utilization_term(void)
{
- if (NULL != utilization_timer) {
+ if (NULL != utilization_timer)
+ {
_mali_osk_timer_del(utilization_timer);
timer_running = MALI_FALSE;
_mali_osk_timer_term(utilization_timer);
@@ -145,11 +155,10 @@ void mali_utilization_term(void)
_mali_osk_lock_term(time_data_lock);
}
-
-
void mali_utilization_core_start(u64 time_now)
{
- if (_mali_osk_atomic_inc_return(&num_running_cores) == 1) {
+ if (_mali_osk_atomic_inc_return(&num_running_cores) == 1)
+ {
/*
* We went from zero cores working, to one core working,
* we now consider the entire GPU for being busy
@@ -167,27 +176,26 @@ void mali_utilization_core_start(u64 time_now)
}
work_start_time = time_now;
-
- if (timer_running != MALI_TRUE) {
+ if (timer_running != MALI_TRUE)
+ {
timer_running = MALI_TRUE;
period_start_time = work_start_time; /* starting a new period */
_mali_osk_lock_signal(time_data_lock, _MALI_OSK_LOCKMODE_RW);
- _mali_osk_timer_del(utilization_timer);
-
_mali_osk_timer_add(utilization_timer, _mali_osk_time_mstoticks(MALI_GPU_UTILIZATION_TIMEOUT));
- } else {
+ }
+ else
+ {
_mali_osk_lock_signal(time_data_lock, _MALI_OSK_LOCKMODE_RW);
}
}
}
-
-
void mali_utilization_core_end(u64 time_now)
{
- if (_mali_osk_atomic_dec_return(&num_running_cores) == 0) {
+ if (_mali_osk_atomic_dec_return(&num_running_cores) == 0)
+ {
/*
* No more cores are working, so accumulate the time we was busy.
*/
diff --git a/drivers/media/video/samsung/mali/common/mali_kernel_utilization.h b/drivers/media/video/samsung/mali/common/mali_kernel_utilization.h
index c779978..1f60517 100644
--- a/drivers/media/video/samsung/mali/common/mali_kernel_utilization.h
+++ b/drivers/media/video/samsung/mali/common/mali_kernel_utilization.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 ARM Limited. All rights reserved.
+ * 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.
diff --git a/drivers/media/video/samsung/mali/common/mali_kernel_vsync.c b/drivers/media/video/samsung/mali/common/mali_kernel_vsync.c
index dc39e01..63c9f5b 100644
--- a/drivers/media/video/samsung/mali/common/mali_kernel_vsync.c
+++ b/drivers/media/video/samsung/mali/common/mali_kernel_vsync.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 ARM Limited. All rights reserved.
+ * 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.
@@ -10,39 +10,41 @@
#include "mali_kernel_common.h"
#include "mali_osk.h"
-#include "mali_osk_mali.h"
#include "mali_ukk.h"
-/*#include "mali_timestamp.h"*/
#if MALI_TIMELINE_PROFILING_ENABLED
-#include "mali_kernel_profiling.h"
+#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 */
-/* u64 ts = _mali_timestamp_get();
- */
#if MALI_TIMELINE_PROFILING_ENABLED
+ /*
+ * 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_profiling_add_event( MALI_PROFILING_EVENT_TYPE_SUSPEND |
- MALI_PROFILING_EVENT_CHANNEL_SOFTWARE |
- MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_VSYNC,
- 0, 0, 0, 0, 0);
+ _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)
+ if (event==_MALI_UK_VSYNC_EVENT_END_WAIT)
{
- _mali_profiling_add_event( MALI_PROFILING_EVENT_TYPE_RESUME |
- MALI_PROFILING_EVENT_CHANNEL_SOFTWARE |
- MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_VSYNC,
- 0, 0, 0, 0, 0);
+ _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/media/video/samsung/mali/common/mali_l2_cache.c b/drivers/media/video/samsung/mali/common/mali_l2_cache.c
new file mode 100644
index 0000000..aa5cc54
--- /dev/null
+++ b/drivers/media/video/samsung/mali/common/mali_l2_cache.c
@@ -0,0 +1,398 @@
+/*
+ * 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_pm.h"
+
+/**
+ * Size of the Mali L2 cache registers in bytes
+ */
+#define MALI400_L2_CACHE_REGISTERS_SIZE 0x30
+
+#define MALI_MAX_NUMBER_OF_L2_CACHE_CORES 3
+
+/**
+ * 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;
+
+/**
+ * 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 */
+};
+
+#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];
+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_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;
+ 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(_MALI_OSK_LOCKFLAG_ORDERED | _MALI_OSK_LOCKFLAG_SPINLOCK | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE,
+ 0, _MALI_OSK_LOCK_ORDER_L2_COMMAND);
+ if (NULL != cache->command_lock)
+ {
+ cache->counter_lock = _mali_osk_lock_init(_MALI_OSK_LOCKFLAG_ORDERED | _MALI_OSK_LOCKFLAG_SPINLOCK | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE,
+ 0, _MALI_OSK_LOCK_ORDER_L2_COUNTER);
+ if (NULL != cache->counter_lock)
+ {
+ if (_MALI_OSK_ERR_OK == mali_l2_cache_reset(cache))
+ {
+ 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 reset L2 cache core %s\n", cache->hw_core.description));
+ }
+
+ _mali_osk_lock_term(cache->counter_lock);
+ }
+ 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--;
+ }
+ }
+
+ _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_DEBUG_ASSERT_POINTER(cache);
+ MALI_DEBUG_ASSERT(counter < (1 << 7)); /* the possible values are 0-127 */
+
+ _mali_osk_lock_wait(cache->counter_lock, _MALI_OSK_LOCKMODE_RW);
+
+ cache->counter_src0 = counter;
+
+ if (counter != MALI_HW_CORE_NO_COUNTER)
+ {
+ value = counter;
+ }
+
+ 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);
+ 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_DEBUG_ASSERT_POINTER(cache);
+ MALI_DEBUG_ASSERT(counter < (1 << 7)); /* the possible values are 0-127 */
+
+ _mali_osk_lock_wait(cache->counter_lock, _MALI_OSK_LOCKMODE_RW);
+
+ cache->counter_src1 = counter;
+
+ if (counter != MALI_HW_CORE_NO_COUNTER)
+ {
+ value = counter;
+ }
+
+ 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);
+ 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_src0 != 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_MAX_NUMBER_OF_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;
+}
+
+u32 mali_l2_cache_core_get_max_num_l2_cores(void)
+{
+ return MALI_MAX_NUMBER_OF_L2_CACHE_CORES;
+}
+
+_mali_osk_errcode_t 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_invalidate_all(cache);
+
+ /* 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);
+
+ return _MALI_OSK_ERR_OK;
+}
+
+_mali_osk_errcode_t mali_l2_cache_invalidate_all(struct mali_l2_cache_core *cache)
+{
+ return mali_l2_cache_send_command(cache, MALI400_L2_CACHE_REGISTER_COMMAND, MALI400_L2_CACHE_COMMAND_CLEAR_ALL);
+}
+
+_mali_osk_errcode_t mali_l2_cache_invalidate_pages(struct mali_l2_cache_core *cache, u32 *pages, u32 num_pages)
+{
+ u32 i;
+ _mali_osk_errcode_t ret1, ret = _MALI_OSK_ERR_OK;
+
+ for (i = 0; i < num_pages; i++)
+ {
+ ret1 = mali_l2_cache_send_command(cache, MALI400_L2_CACHE_REGISTER_CLEAR_PAGE, pages[i]);
+ if (_MALI_OSK_ERR_OK != ret1)
+ {
+ ret = ret1;
+ }
+ }
+
+ return ret;
+}
+
+mali_bool mali_l2_cache_lock_power_state(struct mali_l2_cache_core *cache)
+{
+ /*
+ * Take PM lock and check power state.
+ * Returns MALI_TRUE if module is powered on.
+ * Power state will not change until mali_l2_cache_unlock_power_state() is called.
+ */
+ mali_pm_lock();
+ return mali_pm_is_powered_on();
+}
+
+void mali_l2_cache_unlock_power_state(struct mali_l2_cache_core *cache)
+{
+ /* Release PM lock */
+ mali_pm_unlock();
+}
+
+/* -------- 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/media/video/samsung/mali/common/mali_l2_cache.h b/drivers/media/video/samsung/mali/common/mali_l2_cache.h
new file mode 100644
index 0000000..5a8e4da
--- /dev/null
+++ b/drivers/media/video/samsung/mali/common/mali_l2_cache.h
@@ -0,0 +1,43 @@
+/*
+ * 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"
+
+struct mali_l2_cache_core;
+
+_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);
+
+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);
+u32 mali_l2_cache_core_get_max_num_l2_cores(void);
+
+_mali_osk_errcode_t mali_l2_cache_reset(struct mali_l2_cache_core *cache);
+
+_mali_osk_errcode_t mali_l2_cache_invalidate_all(struct mali_l2_cache_core *cache);
+_mali_osk_errcode_t mali_l2_cache_invalidate_pages(struct mali_l2_cache_core *cache, 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/media/video/samsung/mali/common/mali_mem_validation.c b/drivers/media/video/samsung/mali/common/mali_mem_validation.c
new file mode 100644
index 0000000..ea9c428
--- /dev/null
+++ b/drivers/media/video/samsung/mali/common/mali_mem_validation.c
@@ -0,0 +1,71 @@
+/*
+ * 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"
+
+#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;
+
+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(const _mali_osk_resource_t *resource)
+{
+ /* Check that no other MEM_VALIDATION resources exist */
+ if (MALI_INVALID_MEM_ADDR != mali_mem_validator.phys_base)
+ {
+ MALI_PRINT_ERROR(("Failed to add MEM_VALIDATION resource %s; another range is already specified\n", resource->description));
+ return _MALI_OSK_ERR_FAULT;
+ }
+
+ /* Check restrictions on page alignment */
+ if ((0 != (resource->base & (~_MALI_OSK_CPU_PAGE_MASK))) ||
+ (0 != (resource->size & (~_MALI_OSK_CPU_PAGE_MASK))))
+ {
+ MALI_PRINT_ERROR(("Failed to add MEM_VALIDATION resource %s; incorrect alignment\n", resource->description));
+ return _MALI_OSK_ERR_FAULT;
+ }
+
+ mali_mem_validator.phys_base = resource->base;
+ mali_mem_validator.size = resource->size;
+ MALI_DEBUG_PRINT(2, ("Memory Validator '%s' installed for Mali physical address base=0x%08X, size=0x%08X\n",
+ resource->description, 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/media/video/samsung/mali/common/mali_kernel_session_manager.h b/drivers/media/video/samsung/mali/common/mali_mem_validation.h
index 8cc41d7..2043b44 100644
--- a/drivers/media/video/samsung/mali/common/mali_kernel_session_manager.h
+++ b/drivers/media/video/samsung/mali/common/mali_mem_validation.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 ARM Limited. All rights reserved.
+ * 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.
@@ -8,12 +8,12 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __MALI_KERNEL_SESSION_MANAGER_H__
-#define __MALI_KERNEL_SESSION_MANAGER_H__
+#ifndef __MALI_MEM_VALIDATION_H__
+#define __MALI_MEM_VALIDATION_H__
-/* Incomplete struct to pass around pointers to it */
-struct mali_session_data;
+#include "mali_osk.h"
-void * mali_kernel_session_manager_slot_get(struct mali_session_data * session, int id);
+_mali_osk_errcode_t mali_mem_validation_add_range(const _mali_osk_resource_t * resource);
+_mali_osk_errcode_t mali_mem_validation_check(u32 phys_addr, u32 size);
-#endif /* __MALI_KERNEL_SESSION_MANAGER_H__ */
+#endif /* __MALI_MEM_VALIDATION_H__ */
diff --git a/drivers/media/video/samsung/mali/common/mali_memory.c b/drivers/media/video/samsung/mali/common/mali_memory.c
new file mode 100644
index 0000000..7a11d1a
--- /dev/null
+++ b/drivers/media/video/samsung/mali/common/mali_memory.c
@@ -0,0 +1,1321 @@
+/*
+ * 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_cluster.h"
+#include "mali_group.h"
+#if MALI_USE_UNIFIED_MEMORY_PROVIDER != 0
+#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 MALI_USE_UNIFIED_MEMORY_PROVIDER != 0
+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 MALI_USE_UNIFIED_MEMORY_PROVIDER != 0
+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 /* MALI_USE_UNIFIED_MEMORY_PROVIDER != 0*/
+
+
+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;
+
+/* 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_DEBUG_PRINT(3, ("MMU session end\n"));
+
+ if (NULL == session_data)
+ {
+ MALI_DEBUG_PRINT(1, ("No session data found during session end\n"));
+ return;
+ }
+
+#ifndef MALI_UKK_HAS_IMPLICIT_MMAP_CLEANUP
+#if _MALI_OSK_SPECIFIC_INDIRECT_MMAP
+#error Indirect MMAP specified, but UKK does not have implicit MMAP cleanup. Current implementation does not handle this.
+#else
+ {
+ _mali_osk_errcode_t err;
+ err = _MALI_OSK_ERR_BUSY;
+ 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 (0 == _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) );
+ }
+#endif /* _MALI_OSK_SPECIFIC_INDIRECT_MMAP */
+#else
+ /* Lock the session so we can modify the memory list */
+ _mali_osk_lock_wait( session_data->memory_lock, _MALI_OSK_LOCKMODE_RW );
+#endif /* MALI_UKK_HAS_IMPLICIT_MMAP_CLEANUP */
+
+ 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(_mali_osk_resource_t * resource)
+{
+ mali_physical_memory_allocator * allocator;
+ mali_physical_memory_allocator ** next_allocator_list;
+
+ u32 alloc_order = resource->alloc_order;
+
+ allocator = mali_os_allocator_create(resource->size, resource->cpu_usage_adjust, resource->description);
+ 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(_mali_osk_resource_t * resource)
+{
+ mali_physical_memory_allocator * allocator;
+ mali_physical_memory_allocator ** next_allocator_list;
+ dedicated_memory_info * cleanup_data;
+
+ u32 alloc_order = resource->alloc_order;
+
+ /* do the low level linux operation first */
+
+ /* Request ownership of the memory */
+ if (_MALI_OSK_ERR_OK != _mali_osk_mem_reqregion(resource->base, resource->size, resource->description))
+ {
+ MALI_DEBUG_PRINT(1, ("Failed to request memory region %s (0x%08X - 0x%08X)\n", resource->description, resource->base, resource->base + resource->size - 1));
+ MALI_ERROR(_MALI_OSK_ERR_FAULT);
+ }
+
+ /* create generic block allocator object to handle it */
+ allocator = mali_block_allocator_create(resource->base, resource->cpu_usage_adjust, resource->size, resource->description );
+
+ if (NULL == allocator)
+ {
+ MALI_DEBUG_PRINT(1, ("Memory bank registration failed\n"));
+ _mali_osk_mem_unreqregion(resource->base, resource->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(resource->base, resource->size);
+ allocator->destroy(allocator);
+ MALI_ERROR(_MALI_OSK_ERR_FAULT);
+ }
+
+ cleanup_data->base = resource->base;
+ cleanup_data->size = resource->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 MALI_USE_UNIFIED_MEMORY_PROVIDER != 0
+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->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 /* MALI_USE_UNIFIED_MEMORY_PROVIDER != 0 */
+
+
+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_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->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);
+
+ 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->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;
+
+ u32 num_groups = mali_group_get_glob_num_groups();
+ struct mali_group *group;
+ u32 i;
+
+ 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);
+
+#ifdef MALI_UNMAP_FLUSH_ALL_MALI_L2
+ {
+ u32 number_of_clusters = mali_cluster_get_glob_num_clusters();
+ for (i = 0; i < number_of_clusters; i++)
+ {
+ struct mali_cluster *cluster;
+ cluster = mali_cluster_get_global_cluster(i);
+ if( mali_cluster_power_is_enabled_get(cluster) )
+ {
+ mali_cluster_l2_cache_invalidate_all_force(cluster);
+ }
+ }
+ }
+#endif
+
+ for (i = 0; i < num_groups; i++)
+ {
+ group = mali_group_get_glob_group(i);
+ mali_group_lock(group);
+ mali_group_remove_session_if_unused(group, session_data);
+ if (mali_group_get_session(group) == session_data)
+ {
+ /* The Zap also does the stall and disable_stall */
+ mali_bool zap_success = mali_mmu_zap_tlb(mali_group_get_mmu(group));
+ if (MALI_TRUE != zap_success)
+ {
+ MALI_DEBUG_PRINT(2, ("Mali memory unmap failed. Doing pagefault handling.\n"));
+ mali_group_bottom_half(group, GROUP_EVENT_MMU_PAGE_FAULT);
+ /* The bottom half will also do the unlock */
+ continue;
+ }
+ }
+ mali_group_unlock(group);
+ }
+
+ /* 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 (0 == _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, 0 == _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/media/video/samsung/mali/common/mali_memory.h b/drivers/media/video/samsung/mali/common/mali_memory.h
new file mode 100644
index 0000000..53a994c
--- /dev/null
+++ b/drivers/media/video/samsung/mali/common/mali_memory.h
@@ -0,0 +1,80 @@
+/*
+ * 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"
+
+struct mali_cluster;
+struct mali_group;
+
+/** @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
+ */
+_mali_osk_errcode_t mali_memory_core_resource_os_memory(_mali_osk_resource_t * resource);
+
+/** @brief Parse resource and prepare the dedicated memory allocator
+ */
+_mali_osk_errcode_t mali_memory_core_resource_dedicated_memory(_mali_osk_resource_t * resource);
+
+#endif /* __MALI_MEMORY_H__ */
diff --git a/drivers/media/video/samsung/mali/common/mali_mmu.c b/drivers/media/video/samsung/mali/common/mali_mmu.c
new file mode 100644
index 0000000..2f2fa4d
--- /dev/null
+++ b/drivers/media/video/samsung/mali/common/mali_mmu.c
@@ -0,0 +1,619 @@
+/*
+ * 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 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;
+
+/**
+ * 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;
+
+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_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 */
+ struct mali_group *group; /**< Parent core group */
+ _mali_osk_irq_t *irq; /**< IRQ handler */
+};
+
+/**
+ * The MMU interrupt handler
+ * Upper half of the MMU interrupt processing.
+ * Called by the kernel when the MMU has triggered an interrupt.
+ * The interrupt function supports IRQ sharing. So it'll probe the MMU in question
+ * @param irq The irq number (not used)
+ * @param dev_id Points to the MMU object being handled
+ * @param regs Registers of interrupted process (not used)
+ * @return Standard Linux interrupt result.
+ * Subset used by the driver is IRQ_HANDLED processed
+ * IRQ_NONE Not processed
+ */
+static _mali_osk_errcode_t mali_mmu_upper_half(void * data);
+
+/**
+ * The MMU reset hander
+ * Bottom half of the MMU interrupt processing for page faults and bus errors
+ * @param work The item to operate on, NULL in our case
+ */
+static void mali_mmu_bottom_half(void *data);
+
+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_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_mmu_reset(mmu))
+ {
+ /* Setup IRQ handlers (which will do IRQ probing if needed) */
+ mmu->irq = _mali_osk_irq_init(resource->irq,
+ mali_mmu_upper_half,
+ mali_mmu_bottom_half,
+ mali_mmu_probe_trigger,
+ mali_mmu_probe_ack,
+ mmu,
+ "mali_mmu_irq_handlers");
+ if (NULL != mmu->irq)
+ {
+ return mmu;
+ }
+ else
+ {
+ MALI_PRINT_ERROR(("Failed to setup interrupt handlers for MMU %s\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)
+{
+ _mali_osk_irq_term(mmu->irq);
+ mali_hw_core_delete(&mmu->hw_core);
+ _mali_osk_free(mmu);
+}
+
+void mali_mmu_set_group(struct mali_mmu_core *mmu, struct mali_group *group)
+{
+ mmu->group = group;
+}
+
+static void mali_mmu_enable_paging(struct mali_mmu_core *mmu)
+{
+ const int max_loop_count = 100;
+ const int delay_in_usecs = 1;
+ int i;
+
+ mali_hw_core_register_write(&mmu->hw_core, MALI_MMU_REGISTER_COMMAND, MALI_MMU_COMMAND_ENABLE_PAGING);
+
+ for (i = 0; i < max_loop_count; ++i)
+ {
+ if (mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_STATUS) & MALI_MMU_STATUS_BIT_PAGING_ENABLED)
+ {
+ break;
+ }
+ _mali_osk_time_ubusydelay(delay_in_usecs);
+ }
+ if (max_loop_count == 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)
+{
+ const int max_loop_count = 100;
+ const int delay_in_usecs = 999;
+ int i;
+ u32 mmu_status;
+
+ /* There are no group when it is called from mali_mmu_create */
+ if ( mmu->group ) MALI_ASSERT_GROUP_LOCKED(mmu->group);
+
+ 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 enebled.\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 < max_loop_count; ++i)
+ {
+ mmu_status = mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_STATUS);
+ if ( mmu_status & (MALI_MMU_STATUS_BIT_STALL_ACTIVE|MALI_MMU_STATUS_BIT_PAGE_FAULT_ACTIVE))
+ {
+ break;
+ }
+ if ( 0 == (mmu_status & ( MALI_MMU_STATUS_BIT_PAGING_ENABLED )))
+ {
+ break;
+ }
+ _mali_osk_time_ubusydelay(delay_in_usecs);
+ }
+ if (max_loop_count == i)
+ {
+ MALI_PRINT_ERROR(("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(3, ("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)
+{
+ const int max_loop_count = 100;
+ const int delay_in_usecs = 1;
+ int i;
+ u32 mmu_status;
+ /* There are no group when it is called from mali_mmu_create */
+ if ( mmu->group ) MALI_ASSERT_GROUP_LOCKED(mmu->group);
+
+ 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 < max_loop_count; ++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;
+ }
+ _mali_osk_time_ubusydelay(delay_in_usecs);
+ }
+ if (max_loop_count == 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_ASSERT_GROUP_LOCKED(mmu->group);
+ 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)
+{
+ const int max_loop_count = 100;
+ const int delay_in_usecs = 1;
+ int i;
+ /* The _if_ is neccessary when called from mali_mmu_create and NULL==group */
+ if (mmu->group)MALI_ASSERT_GROUP_LOCKED(mmu->group);
+
+ mali_hw_core_register_write(&mmu->hw_core, MALI_MMU_REGISTER_DTE_ADDR, 0xCAFEBABE);
+ mali_hw_core_register_write(&mmu->hw_core, MALI_MMU_REGISTER_COMMAND, MALI_MMU_COMMAND_HARD_RESET);
+
+ for (i = 0; i < max_loop_count; ++i)
+ {
+ if (mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_DTE_ADDR) == 0)
+ {
+ break;
+ }
+ _mali_osk_time_ubusydelay(delay_in_usecs);
+ }
+ if (max_loop_count == 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);
+ /* The _if_ is neccessary when called from mali_mmu_create and NULL==group */
+ if (mmu->group)
+ {
+ MALI_ASSERT_GROUP_LOCKED(mmu->group);
+ }
+
+ stall_success = mali_mmu_enable_stall(mmu);
+
+ /* The stall can not fail in current hw-state */
+ MALI_DEBUG_ASSERT(stall_success);
+
+ 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;
+}
+
+
+/* ------------- interrupt handling below ------------------ */
+
+static _mali_osk_errcode_t mali_mmu_upper_half(void * data)
+{
+ struct mali_mmu_core *mmu = (struct mali_mmu_core *)data;
+ u32 int_stat;
+
+ MALI_DEBUG_ASSERT_POINTER(mmu);
+
+ /* Check if it was our device which caused the interrupt (we could be sharing the IRQ line) */
+ int_stat = mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_INT_STATUS);
+ if (0 != int_stat)
+ {
+ mali_hw_core_register_write(&mmu->hw_core, MALI_MMU_REGISTER_INT_MASK, 0);
+ mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_STATUS);
+
+ if (int_stat & MALI_MMU_INTERRUPT_PAGE_FAULT)
+ {
+ _mali_osk_irq_schedulework(mmu->irq);
+ }
+
+ if (int_stat & MALI_MMU_INTERRUPT_READ_BUS_ERROR)
+ {
+ /* clear interrupt flag */
+ mali_hw_core_register_write(&mmu->hw_core, MALI_MMU_REGISTER_INT_CLEAR, MALI_MMU_INTERRUPT_READ_BUS_ERROR);
+ /* reenable it */
+ mali_hw_core_register_write(&mmu->hw_core, MALI_MMU_REGISTER_INT_MASK,
+ mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_INT_MASK) | MALI_MMU_INTERRUPT_READ_BUS_ERROR);
+ MALI_PRINT_ERROR(("Mali MMU: Read bus error\n"));
+ }
+ return _MALI_OSK_ERR_OK;
+ }
+
+ return _MALI_OSK_ERR_FAULT;
+}
+
+static void mali_mmu_bottom_half(void * data)
+{
+ struct mali_mmu_core *mmu = (struct mali_mmu_core*)data;
+ u32 raw, status, fault_address;
+
+ MALI_DEBUG_ASSERT_POINTER(mmu);
+
+ MALI_DEBUG_PRINT(3, ("Mali MMU: Page fault bottom half: Locking subsystems\n"));
+
+ mali_group_lock(mmu->group); /* Unlocked in mali_group_bottom_half */
+
+ if ( MALI_FALSE == mali_group_power_is_on(mmu->group) )
+ {
+ MALI_PRINT_ERROR(("Interrupt bottom half of %s when core is OFF.",mmu->hw_core.description));
+ mali_group_unlock(mmu->group);
+ return;
+ }
+
+ raw = mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_INT_RAWSTAT);
+ status = mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_STATUS);
+
+ if ( (0==(raw & MALI_MMU_INTERRUPT_PAGE_FAULT)) && (0==(status & MALI_MMU_STATUS_BIT_PAGE_FAULT_ACTIVE)) )
+ {
+ MALI_DEBUG_PRINT(2, ("Mali MMU: Page fault bottom half: No Irq found.\n"));
+ mali_group_unlock(mmu->group);
+ /* MALI_DEBUG_ASSERT(0); */
+ return;
+ }
+
+ /* An actual page fault has occurred. */
+
+ fault_address = mali_hw_core_register_read(&mmu->hw_core, MALI_MMU_REGISTER_PAGE_FAULT_ADDR);
+
+ 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_group_bottom_half(mmu->group, GROUP_EVENT_MMU_PAGE_FAULT); /* Unlocks the group lock */
+}
+
+mali_bool mali_mmu_zap_tlb(struct mali_mmu_core *mmu)
+{
+ mali_bool stall_success;
+ MALI_ASSERT_GROUP_LOCKED(mmu->group);
+
+ 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_ASSERT_GROUP_LOCKED(mmu->group);
+ 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_ASSERT_GROUP_LOCKED(mmu->group);
+ 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)
+{
+ MALI_ASSERT_GROUP_LOCKED(mmu->group);
+ /* 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_ASSERT_GROUP_LOCKED(mmu->group);
+
+ 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_ASSERT_GROUP_LOCKED(mmu->group);
+ 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_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_ASSERT_GROUP_LOCKED(mmu->group);
+
+ 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/media/video/samsung/mali/common/mali_mmu.h b/drivers/media/video/samsung/mali/common/mali_mmu.h
new file mode 100644
index 0000000..c7274b8
--- /dev/null
+++ b/drivers/media/video/samsung/mali/common/mali_mmu.h
@@ -0,0 +1,55 @@
+/*
+ * 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"
+
+/* Forward declaration from mali_group.h */
+struct mali_group;
+
+struct mali_mmu_core;
+
+_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);
+void mali_mmu_set_group(struct mali_mmu_core *mmu, struct mali_group *group);
+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);
+
+
+#endif /* __MALI_MMU_H__ */
diff --git a/drivers/media/video/samsung/mali/common/mali_mmu_page_directory.c b/drivers/media/video/samsung/mali/common/mali_mmu_page_directory.c
new file mode 100644
index 0000000..43a4cf4
--- /dev/null
+++ b/drivers/media/video/samsung/mali/common/mali_mmu_page_directory.c
@@ -0,0 +1,459 @@
+/*
+ * 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_cluster.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;
+#ifndef MALI_UNMAP_FLUSH_ALL_MALI_L2
+ 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;
+#endif
+
+ /* 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);
+#ifndef MALI_UNMAP_FLUSH_ALL_MALI_L2
+ pd_changed = MALI_TRUE;
+#endif
+ }
+ else
+ {
+#ifndef MALI_UNMAP_FLUSH_ALL_MALI_L2
+ pages_to_invalidate[num_pages_inv] = mali_page_directory_get_phys_address(pagedir, i);
+ num_pages_inv++;
+ MALI_DEBUG_ASSERT(num_pages_inv<3);
+#endif
+
+ /* 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();
+
+#ifndef MALI_UNMAP_FLUSH_ALL_MALI_L2
+ /* L2 pages invalidation */
+ if (MALI_TRUE == pd_changed)
+ {
+ pages_to_invalidate[num_pages_inv] = pagedir->page_directory;
+ num_pages_inv++;
+ MALI_DEBUG_ASSERT(num_pages_inv<3);
+ }
+
+ if (_MALI_PRODUCT_ID_MALI200 != mali_kernel_core_get_product_id())
+ {
+ mali_cluster_invalidate_pages(pages_to_invalidate, num_pages_inv);
+ }
+#endif
+
+ 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)
+{
+ u32 end_address = mali_address + size;
+
+ /* 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 | MALI_MMU_FLAGS_WRITE_PERMISSION | MALI_MMU_FLAGS_READ_PERMISSION | MALI_MMU_FLAGS_PRESENT);
+ }
+ _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/media/video/samsung/mali/common/mali_mmu_page_directory.h b/drivers/media/video/samsung/mali/common/mali_mmu_page_directory.h
new file mode 100644
index 0000000..8aababe
--- /dev/null
+++ b/drivers/media/video/samsung/mali/common/mali_mmu_page_directory.h
@@ -0,0 +1,83 @@
+/*
+ * 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_MASK = 0x07
+} mali_mmu_entry_flags;
+
+
+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 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/media/video/samsung/mali/common/mali_osk.h b/drivers/media/video/samsung/mali/common/mali_osk.h
index 72d851d..e32d15d 100644
--- a/drivers/media/video/samsung/mali/common/mali_osk.h
+++ b/drivers/media/video/samsung/mali/common/mali_osk.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 ARM Limited. All rights reserved.
+ * 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.
@@ -165,9 +165,6 @@ typedef void (*_mali_osk_irq_bhandler_t)( void * arg );
* 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.
*
- * Even though the structure has space for a u32, the counters will only
- * represent signed 24-bit integers.
- *
* 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.
@@ -186,6 +183,40 @@ typedef struct
/** @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_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_GROUP,
+ _MALI_OSK_LOCK_ORDER_SCHEDULER,
+
+ _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_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
@@ -271,6 +302,17 @@ typedef enum
/** @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 );
+#endif
+
/** @} */ /* end group _mali_osk_lock */
/** @defgroup _mali_osk_low_level_memory OSK Low-level Memory Operations
@@ -368,7 +410,6 @@ typedef struct _mali_osk_notification_queue_t_struct _mali_osk_notification_queu
/** @brief Public notification data object type */
typedef struct _mali_osk_notification_t_struct
{
- u32 magic_code;
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 */
@@ -527,20 +568,35 @@ typedef struct _mali_osk_list_s
typedef enum _mali_osk_resource_type
{
RESOURCE_TYPE_FIRST =0, /**< Duplicate resource marker for the first resource*/
+
MEMORY =0, /**< Physically contiguous memory block, not managed by the OS */
OS_MEMORY =1, /**< Memory managed by and shared with the OS */
- MALI200 =3, /**< Mali200 Programmable Fragment Shader */
- MALIGP2 =4, /**< MaliGP2 Programmable Vertex Shader */
- MMU =5, /**< Mali MMU (Memory Management Unit) */
- FPGA_FRAMEWORK =6, /**< Mali registers specific to FPGA implementations */
- MALI400L2 =7, /**< Mali400 L2 Cache */
- MALI300L2 =7, /**< Mali300 L2 Cache */
- MALI400GP =8, /**< Mali400 Programmable Vertex Shader Core */
- MALI300GP =8, /**< Mali300 Programmable Vertex Shader Core */
- MALI400PP =9, /**< Mali400 Programmable Fragment Shader Core */
- MALI300PP =9, /**< Mali300 Programmable Fragment Shader Core */
- MEM_VALIDATION =10, /**< External Memory Validator */
- PMU =11, /**< Power Manangement Unit */
+
+ MALI_PP =2, /**< Mali Pixel Processor core */
+ MALI450PP =2, /**< Compatibility option */
+ MALI400PP =2, /**< Compatibility option */
+ MALI300PP =2, /**< Compatibility option */
+ MALI200 =2, /**< Compatibility option */
+
+ MALI_GP =3, /**< Mali Geometry Processor core */
+ MALI450GP =3, /**< Compatibility option */
+ MALI400GP =3, /**< Compatibility option */
+ MALI300GP =3, /**< Compatibility option */
+ MALIGP2 =3, /**< Compatibility option */
+
+ MMU =4, /**< Mali MMU (Memory Management Unit) */
+
+ FPGA_FRAMEWORK =5, /**< Mali registers specific to FPGA implementations */
+
+ MALI_L2 =6, /**< Mali Level 2 cache core */
+ MALI450L2 =6, /**< Compatibility option */
+ MALI400L2 =6, /**< Compatibility option */
+ MALI300L2 =6, /**< Compatibility option */
+
+ MEM_VALIDATION =7, /**< External Memory Validator */
+
+ PMU =8, /**< Power Manangement Unit */
+
RESOURCE_TYPE_COUNT /**< The total number of known resources */
} _mali_osk_resource_type_t;
@@ -726,11 +782,6 @@ void _mali_osk_atomic_dec( _mali_osk_atomic_t *atom );
/** @brief Decrement an atomic counter, return new value
*
- * Although the value returned is a u32, only numbers with signed 24-bit
- * precision (sign extended to u32) are returned.
- *
- * @note It is an error to decrement the counter beyond -(1<<23)
- *
* @param atom pointer to an atomic counter
* @return The new value, after decrement */
u32 _mali_osk_atomic_dec_return( _mali_osk_atomic_t *atom );
@@ -744,19 +795,11 @@ void _mali_osk_atomic_inc( _mali_osk_atomic_t *atom );
/** @brief Increment an atomic counter, return new value
*
- * Although the value returned is a u32, only numbers with signed 24-bit
- * precision (sign extended to u32) are returned.
- *
- * @note It is an error to increment the counter beyond (1<<23)-1
- *
* @param atom pointer to an atomic counter */
u32 _mali_osk_atomic_inc_return( _mali_osk_atomic_t *atom );
/** @brief Initialize an atomic counter
*
- * The counters have storage for signed 24-bit integers. Initializing to signed
- * values requiring more than 24-bits storage will fail.
- *
* @note the parameter required is a u32, and so signed integers should be
* cast to u32.
*
@@ -769,9 +812,6 @@ _mali_osk_errcode_t _mali_osk_atomic_init( _mali_osk_atomic_t *atom, u32 val );
/** @brief Read a value from an atomic counter
*
- * Although the value returned is a u32, only numbers with signed 24-bit
- * precision (sign extended to u32) are returned.
- *
* 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.
@@ -1624,6 +1664,41 @@ u64 _mali_osk_time_get_ns( void );
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
* @{ */
@@ -1647,6 +1722,7 @@ void _mali_osk_dbgmsg( const char *fmt, ... );
* @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, ... );
@@ -1685,13 +1761,19 @@ u32 _mali_osk_get_pid(void);
*/
u32 _mali_osk_get_tid(void);
-void _mali_osk_profiling_add_event(u32 event_id, u32 data0);
-void _mali_osk_profiling_add_counter(u32 event_id, u32 data0);
-int _mali_osk_counter_event(u32 counter, u32 event);
-extern u32 counter_table[];
+/** @brief Enable OS controlled runtime power management
+ */
+void _mali_osk_pm_dev_enable(void);
-/** @} */ /* end group _mali_osk_miscellaneous */
+/** @brief Tells the OS that device is now idle
+ */
+_mali_osk_errcode_t _mali_osk_pm_dev_idle(void);
+/** @brief Tells the OS that the device is about to become active
+ */
+_mali_osk_errcode_t _mali_osk_pm_dev_activate(void);
+
+/** @} */ /* end group _mali_osk_miscellaneous */
/** @} */ /* end group osuapi */
diff --git a/drivers/media/video/samsung/mali/common/mali_osk_list.h b/drivers/media/video/samsung/mali/common/mali_osk_list.h
index 3a562bb..a8d15f2 100644
--- a/drivers/media/video/samsung/mali/common/mali_osk_list.h
+++ b/drivers/media/video/samsung/mali/common/mali_osk_list.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 ARM Limited. All rights reserved.
+ * 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.
diff --git a/drivers/media/video/samsung/mali/common/mali_osk_mali.h b/drivers/media/video/samsung/mali/common/mali_osk_mali.h
index 0b1d13a..427fcc8 100644
--- a/drivers/media/video/samsung/mali/common/mali_osk_mali.h
+++ b/drivers/media/video/samsung/mali/common/mali_osk_mali.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 ARM Limited. All rights reserved.
+ * 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.
@@ -26,36 +26,6 @@ extern "C"
/** @addtogroup _mali_osk_miscellaneous
* @{ */
-/** @brief Initialize the OSK layer
- *
- * This function is used to setup any initialization of OSK functionality, if
- * required.
- *
- * This must be the first function called from the common code, specifically,
- * from the common code entry-point, mali_kernel_constructor.
- *
- * The OS-integration into the OS's kernel must handle calling of
- * mali_kernel_constructor when the device driver is loaded.
- *
- * @return _MALI_OSK_ERR_OK on success, or a suitable _mali_osk_errcode_t on
- * failure.
- */
-_mali_osk_errcode_t _mali_osk_init( void );
-
-/** @brief Terminate the OSK layer
- *
- * This function is used to terminate any resources initialized by
- * _mali_osk_init.
- *
- * This must be the last function called from the common code, specifically,
- * from the common code closedown function, mali_kernel_destructor, and the
- * error path in mali_kernel_constructor.
- *
- * The OS-integration into the OS's kernel must handle calling of
- * mali_kernel_destructor when the device driver is terminated.
- */
-void _mali_osk_term( void );
-
/** @brief Read the Mali Resource configuration
*
* Populates a _mali_arch_resource_t array from configuration settings, which
diff --git a/drivers/media/video/samsung/mali/common/mali_kernel_profiling.h b/drivers/media/video/samsung/mali/common/mali_osk_profiling.h
index eb1e6c2..fd9a8fb 100644
--- a/drivers/media/video/samsung/mali/common/mali_kernel_profiling.h
+++ b/drivers/media/video/samsung/mali/common/mali_osk_profiling.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 ARM Limited. All rights reserved.
+ * 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.
@@ -8,31 +8,34 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __MALI_KERNEL_PROFILING_H__
-#define __MALI_KERNEL_PROFILING_H__
+#ifndef __MALI_OSK_PROFILING_H__
+#define __MALI_OSK_PROFILING_H__
#if MALI_TIMELINE_PROFILING_ENABLED
-#include "cinstr/mali_cinstr_profiling_events_m200.h"
+#if defined (CONFIG_TRACEPOINTS) && !MALI_INTERNAL_TIMELINE_PROFILING_ENABLED
+#include "mali_linux_trace.h"
+#endif /* CONFIG_TRACEPOINTS && !MALI_INTERNAL_TIMELINE_PROFILING_ENABLED */
+
+#include "mali_profiling_events.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_profiling_init(mali_bool auto_start);
+_mali_osk_errcode_t _mali_osk_profiling_init(mali_bool auto_start);
/*
* Terminate the profiling module.
*/
-void _mali_profiling_term(void);
-
-/** Add a counter event
- * @param event_id - Magic counter id
- * @param data0 - Value of counter
- */
-void _mali_profiling_add_counter(u32 event_id, u32 data0);
+void _mali_osk_profiling_term(void);
/**
* Start recording profiling data
@@ -43,7 +46,7 @@ void _mali_profiling_add_counter(u32 event_id, u32 data0);
* @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_profiling_start(u32 * limit);
+_mali_osk_errcode_t _mali_osk_profiling_start(u32 * limit);
/**
* Add an profiling event
@@ -56,7 +59,35 @@ _mali_osk_errcode_t _mali_profiling_start(u32 * limit);
* @param data4 Fifth data parameter, depending on event_id specified.
* @return _MALI_OSK_ERR_OK on success, otherwise failure.
*/
-_mali_osk_errcode_t _mali_profiling_add_event(u32 event_id, u32 data0, u32 data1, u32 data2, u32 data3, u32 data4);
+#if defined (CONFIG_TRACEPOINTS) && !MALI_INTERNAL_TIMELINE_PROFILING_ENABLED
+/* 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))
+#else
+/* Internal profiling is handled like a plain function call */
+void _mali_osk_profiling_add_event(u32 event_id, u32 data0, u32 data1, u32 data2, u32 data3, u32 data4);
+#endif
+
+/**
+ * Report a hardware counter event.
+ *
+ * @param counter_id The ID of the counter.
+ * @param value The value of the counter.
+ */
+
+#if defined (CONFIG_TRACEPOINTS) && !MALI_INTERNAL_TIMELINE_PROFILING_ENABLED
+/* Call Linux tracepoint directly */
+#define _mali_osk_profiling_report_hw_counter(counter_id, value) trace_mali_hw_counter(counter_id, value)
+#else
+/* Internal profiling is handled like a plain function call */
+void _mali_osk_profiling_report_hw_counter(u32 counter_id, u32 value);
+#endif
+
+/**
+ * Report SW counters
+ *
+ * @param counters array of counter values
+ */
+void _mali_osk_profiling_report_sw_counters(u32 *counters);
/**
* Stop recording profiling data
@@ -64,14 +95,14 @@ _mali_osk_errcode_t _mali_profiling_add_event(u32 event_id, u32 data0, u32 data1
* @param count Returns the number of recorded events.
* @return _MALI_OSK_ERR_OK on success, otherwise failure.
*/
-_mali_osk_errcode_t _mali_profiling_stop(u32 * count);
+_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_profiling_get_count(void);
+u32 _mali_osk_profiling_get_count(void);
/**
* Retrieve an event
@@ -81,7 +112,8 @@ u32 _mali_profiling_get_count(void);
* @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_profiling_get_event(u32 index, u64* timestamp, u32* event_id, u32 data[5]);
+ */
+_mali_osk_errcode_t _mali_osk_profiling_get_event(u32 index, u64* timestamp, u32* event_id, u32 data[5]);
/**
* Clear the recorded buffer.
@@ -90,38 +122,26 @@ u32 _mali_profiling_get_count(void);
*
* @return _MALI_OSK_ERR_OK on success, otherwise failure.
*/
-_mali_osk_errcode_t _mali_profiling_clear(void);
+_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_profiling_is_recording(void);
+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_profiling_have_recording(void);
+mali_bool _mali_osk_profiling_have_recording(void);
-/**
- * Enable or disable profiling events as default for new sessions (applications)
- *
- * @param enable MALI_TRUE if profiling events should be turned on, otherwise MALI_FALSE
- */
-void _mali_profiling_set_default_enable_state(mali_bool enable);
-
-/**
- * Get current default enable state for new sessions (applications)
- *
- * @return MALI_TRUE if profiling events should be turned on, otherwise MALI_FALSE
- */
-mali_bool _mali_profiling_get_default_enable_state(void);
+/** @} */ /* end group _mali_osk_profiling */
#endif /* MALI_TIMELINE_PROFILING_ENABLED */
-#endif /* __MALI_KERNEL_PROFILING_H__ */
+#endif /* __MALI_OSK_PROFILING_H__ */
diff --git a/drivers/media/video/samsung/mali/common/mali_pm.c b/drivers/media/video/samsung/mali/common/mali_pm.c
new file mode 100644
index 0000000..1ef3807
--- /dev/null
+++ b/drivers/media/video/samsung/mali/common/mali_pm.c
@@ -0,0 +1,547 @@
+/*
+ * 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_platform.h"
+#include "mali_kernel_utilization.h"
+#include "mali_kernel_core.h"
+#include "mali_group.h"
+
+#define MALI_PM_LIGHT_SLEEP_TIMEOUT 1000
+
+enum mali_pm_scheme
+{
+ MALI_PM_SCHEME_DYNAMIC,
+ MALI_PM_SCHEME_OS_SUSPENDED,
+ MALI_PM_SCHEME_ALWAYS_ON
+};
+
+enum mali_pm_level
+{
+ MALI_PM_LEVEL_1_ON,
+ MALI_PM_LEVEL_2_STANDBY,
+ MALI_PM_LEVEL_3_LIGHT_SLEEP,
+ MALI_PM_LEVEL_4_DEEP_SLEEP
+};
+static _mali_osk_lock_t *mali_pm_lock_set_next_state;
+static _mali_osk_lock_t *mali_pm_lock_set_core_states;
+static _mali_osk_lock_t *mali_pm_lock_execute_state_change;
+static _mali_osk_irq_t *wq_irq;
+
+static _mali_osk_timer_t *idle_timer = NULL;
+static mali_bool idle_timer_running = MALI_FALSE;
+static u32 mali_pm_event_number = 0;
+
+static u32 num_active_gps = 0;
+static u32 num_active_pps = 0;
+
+static enum mali_pm_scheme current_scheme = MALI_PM_SCHEME_DYNAMIC;
+static enum mali_pm_level current_level = MALI_PM_LEVEL_1_ON;
+static enum mali_pm_level next_level_dynamic = MALI_PM_LEVEL_2_STANDBY; /* Should be the state we go to when we go out of MALI_PM_SCHEME_ALWAYS_ON during init */
+
+
+
+static _mali_osk_errcode_t mali_pm_upper_half(void *data);
+static void mali_pm_bottom_half(void *data);
+static void mali_pm_powerup(void);
+static void mali_pm_powerdown(mali_power_mode power_mode);
+
+static void timeout_light_sleep(void* arg);
+#if 0
+/* Deep sleep timout not supported */
+static void timeout_deep_sleep(void* arg);
+#endif
+static u32 mali_pm_event_number_get(void);
+static void mali_pm_event(enum mali_pm_event pm_event, mali_bool schedule_work, u32 timer_time );
+
+_mali_osk_errcode_t mali_pm_initialize(void)
+{
+ mali_pm_lock_execute_state_change = _mali_osk_lock_init(_MALI_OSK_LOCKFLAG_ORDERED | _MALI_OSK_LOCKFLAG_ORDERED |_MALI_OSK_LOCKFLAG_NONINTERRUPTABLE, 0, _MALI_OSK_LOCK_ORDER_PM_EXECUTE);
+
+ if (NULL != mali_pm_lock_execute_state_change )
+ {
+ mali_pm_lock_set_next_state = _mali_osk_lock_init(_MALI_OSK_LOCKFLAG_ONELOCK| _MALI_OSK_LOCKFLAG_SPINLOCK_IRQ |_MALI_OSK_LOCKFLAG_NONINTERRUPTABLE, 0, _MALI_OSK_LOCK_ORDER_LAST);
+
+ if (NULL != mali_pm_lock_set_next_state)
+ {
+ mali_pm_lock_set_core_states = _mali_osk_lock_init(_MALI_OSK_LOCKFLAG_ORDERED | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE, 0, _MALI_OSK_LOCK_ORDER_PM_CORE_STATE);
+
+ if (NULL != mali_pm_lock_set_core_states)
+ {
+ idle_timer = _mali_osk_timer_init();
+ if (NULL != idle_timer)
+ {
+ wq_irq = _mali_osk_irq_init(_MALI_OSK_IRQ_NUMBER_PMM,
+ mali_pm_upper_half,
+ mali_pm_bottom_half,
+ NULL,
+ NULL,
+ (void *)NULL,
+ "Mali PM deferred work");
+ if (NULL != wq_irq)
+ {
+ if (_MALI_OSK_ERR_OK == mali_platform_init())
+ {
+#if MALI_PMM_RUNTIME_JOB_CONTROL_ON
+ _mali_osk_pm_dev_enable();
+ mali_pm_powerup();
+#endif
+ return _MALI_OSK_ERR_OK;
+ }
+
+ _mali_osk_irq_term(wq_irq);
+ }
+
+ _mali_osk_timer_del(idle_timer);
+ _mali_osk_timer_term(idle_timer);
+ }
+ _mali_osk_lock_term(mali_pm_lock_set_core_states);
+ }
+ _mali_osk_lock_term(mali_pm_lock_set_next_state);
+ }
+ _mali_osk_lock_term(mali_pm_lock_execute_state_change);
+ }
+
+ return _MALI_OSK_ERR_FAULT;
+}
+
+void mali_pm_terminate(void)
+{
+ mali_platform_deinit();
+ _mali_osk_irq_term(wq_irq);
+ _mali_osk_timer_del(idle_timer);
+ _mali_osk_timer_term(idle_timer);
+ _mali_osk_lock_term(mali_pm_lock_execute_state_change);
+ _mali_osk_lock_term(mali_pm_lock_set_next_state);
+ _mali_osk_lock_term(mali_pm_lock_set_core_states);
+}
+
+
+inline void mali_pm_lock(void)
+{
+ _mali_osk_lock_wait(mali_pm_lock_set_next_state, _MALI_OSK_LOCKMODE_RW);
+}
+
+inline void mali_pm_unlock(void)
+{
+ _mali_osk_lock_signal(mali_pm_lock_set_next_state, _MALI_OSK_LOCKMODE_RW);
+}
+
+inline void mali_pm_execute_state_change_lock(void)
+{
+ _mali_osk_lock_wait(mali_pm_lock_execute_state_change,_MALI_OSK_LOCKMODE_RW);
+}
+
+inline void mali_pm_execute_state_change_unlock(void)
+{
+ _mali_osk_lock_signal(mali_pm_lock_execute_state_change, _MALI_OSK_LOCKMODE_RW);
+}
+
+static void mali_pm_powerup(void)
+{
+ MALI_DEBUG_PRINT(3, ("Mali PM: Setting GPU power mode to MALI_POWER_MODE_ON\n"));
+ mali_platform_power_mode_change(MALI_POWER_MODE_ON);
+
+#if MALI_PMM_RUNTIME_JOB_CONTROL_ON
+
+ /* Aquire our reference */
+ MALI_DEBUG_PRINT(4, ("Mali PM: Getting device PM reference (=> requesting MALI_POWER_MODE_ON)\n"));
+ _mali_osk_pm_dev_activate();
+#endif
+
+ mali_group_power_on();
+}
+
+static void mali_pm_powerdown(mali_power_mode power_mode)
+{
+ if ( (MALI_PM_LEVEL_1_ON == current_level) || (MALI_PM_LEVEL_2_STANDBY == current_level) )
+ {
+ mali_group_power_off();
+ }
+ mali_platform_power_mode_change(power_mode);
+
+#if MALI_PMM_RUNTIME_JOB_CONTROL_ON
+ _mali_osk_pm_dev_idle();
+#endif
+}
+
+mali_bool mali_pm_is_powered_on(void)
+{
+ mali_bool is_on = MALI_TRUE;
+
+ if( ! (MALI_PM_SCHEME_ALWAYS_ON == current_scheme || MALI_PM_SCHEME_DYNAMIC == current_scheme) )
+ {
+ is_on = MALI_FALSE;
+ }
+ else if ( ! (MALI_PM_LEVEL_1_ON == current_level || MALI_PM_LEVEL_2_STANDBY == current_level))
+ {
+ is_on = MALI_FALSE;
+ }
+ else if ( ! (MALI_PM_LEVEL_1_ON == next_level_dynamic || MALI_PM_LEVEL_2_STANDBY == next_level_dynamic))
+ {
+ is_on = MALI_FALSE;
+ }
+
+ return is_on;
+}
+
+MALI_DEBUG_CODE(
+static const char *state_as_string(enum mali_pm_level level)
+{
+ switch(level)
+ {
+ case MALI_PM_LEVEL_1_ON:
+ return "MALI_PM_LEVEL_1_ON";
+ case MALI_PM_LEVEL_2_STANDBY:
+ return "MALI_PM_LEVEL_2_STANDBY";
+ case MALI_PM_LEVEL_3_LIGHT_SLEEP:
+ return "MALI_PM_LEVEL_3_LIGHT_SLEEP";
+ case MALI_PM_LEVEL_4_DEEP_SLEEP:
+ return "MALI_PM_LEVEL_4_DEEP_SLEEP";
+ default:
+ return "UNKNOWN LEVEL";
+ }
+});
+
+/* This could be used from another thread (work queue), if we need that */
+static void mali_pm_process_next(void)
+{
+ enum mali_pm_level pm_level_to_set;
+
+ _mali_osk_lock_wait(mali_pm_lock_execute_state_change, _MALI_OSK_LOCKMODE_RW);
+
+ pm_level_to_set = current_level;
+
+ if (MALI_PM_SCHEME_DYNAMIC == current_scheme)
+ {
+ pm_level_to_set = next_level_dynamic;
+
+ MALI_DEBUG_PRINT(4, ("Mali PM: Dynamic scheme; Changing Mali GPU power state from %s to: %s\n", state_as_string(current_level), state_as_string(pm_level_to_set)));
+
+ if (current_level == pm_level_to_set)
+ {
+ goto end_function; /* early out, no change in power level */
+ }
+
+ /* Start timers according to new state, so we get STANDBY -> LIGHT_SLEEP -> DEEP_SLEEP */
+
+ if (MALI_TRUE == idle_timer_running)
+ {
+ /* There is an existing timeout, so delete it */
+ _mali_osk_timer_del(idle_timer);
+ idle_timer_running = MALI_FALSE;
+ }
+
+ /* Making sure that we turn on through the platform file
+ Since it was turned OFF directly through the platform file.
+ This might lead to double turn-on, but the plaform file supports that.*/
+ if ( current_level == MALI_PM_LEVEL_4_DEEP_SLEEP)
+ {
+ mali_pm_powerup();
+ mali_kernel_core_wakeup();
+
+ }
+ if (MALI_PM_LEVEL_1_ON == pm_level_to_set)
+ {
+ if (MALI_PM_LEVEL_2_STANDBY != current_level)
+ {
+ /* We only need to do anything if we came from one of the sleeping states */
+ mali_pm_powerup();
+
+ /* Wake up Mali cores since we came from a sleep state */
+ mali_kernel_core_wakeup();
+ }
+ }
+ else if (MALI_PM_LEVEL_2_STANDBY == pm_level_to_set)
+ {
+ /* This is just an internal state, so we don't bother to report it to the platform file */
+ idle_timer_running = MALI_TRUE;
+ _mali_osk_timer_setcallback(idle_timer, timeout_light_sleep, (void*) mali_pm_event_number_get());
+ _mali_osk_timer_add(idle_timer, _mali_osk_time_mstoticks(MALI_PM_LIGHT_SLEEP_TIMEOUT));
+ }
+ else if (MALI_PM_LEVEL_3_LIGHT_SLEEP == pm_level_to_set)
+ {
+ mali_pm_powerdown(MALI_POWER_MODE_LIGHT_SLEEP);
+ }
+ else if (MALI_PM_LEVEL_4_DEEP_SLEEP == pm_level_to_set)
+ {
+ MALI_DEBUG_PRINT(2, ("Mali PM: Setting GPU power mode to MALI_POWER_MODE_DEEP_SLEEP\n"));
+ mali_pm_powerdown(MALI_POWER_MODE_DEEP_SLEEP);
+ }
+ }
+ else if (MALI_PM_SCHEME_OS_SUSPENDED == current_scheme)
+ {
+ MALI_DEBUG_PRINT(4, ("Mali PM: OS scheme; Changing Mali GPU power state from %s to: %s\n", state_as_string(current_level), state_as_string(MALI_PM_LEVEL_4_DEEP_SLEEP)));
+
+ pm_level_to_set = MALI_PM_LEVEL_4_DEEP_SLEEP;
+
+ if (current_level == pm_level_to_set)
+ {
+ goto end_function; /* early out, no change in power level */
+ }
+
+ /* Cancel any timers */
+ if (MALI_TRUE == idle_timer_running)
+ {
+ /* There is an existing timeout, so delete it */
+ _mali_osk_timer_del(idle_timer);
+ idle_timer_running = MALI_FALSE;
+ }
+
+ MALI_DEBUG_PRINT(2, ("Mali PM: Setting GPU power mode to MALI_POWER_MODE_DEEP_SLEEP\n"));
+ mali_pm_powerdown(MALI_POWER_MODE_DEEP_SLEEP);
+ next_level_dynamic = current_level;
+ }
+ else if (MALI_PM_SCHEME_ALWAYS_ON == current_scheme)
+ {
+ MALI_DEBUG_PRINT(4, ("Mali PM: Always on scheme; Changing Mali GPU power state from %s to: %s\n", state_as_string(current_level), state_as_string(MALI_PM_LEVEL_1_ON)));
+
+ pm_level_to_set = MALI_PM_LEVEL_1_ON;
+ if (current_level == pm_level_to_set)
+ {
+ goto end_function; /* early out, no change in power level */
+ }
+
+ MALI_DEBUG_PRINT(2, ("Mali PM: Setting GPU power mode to MALI_POWER_MODE_ON\n"));
+ mali_pm_powerup();
+ if (MALI_PM_LEVEL_2_STANDBY != current_level)
+ {
+ /* Wake up Mali cores since we came from a sleep state */
+ mali_kernel_core_wakeup();
+ }
+ }
+ else
+ {
+ MALI_PRINT_ERROR(("MALI PM: Illegal scheme"));
+ }
+
+ current_level = pm_level_to_set;
+
+end_function:
+ _mali_osk_lock_signal(mali_pm_lock_execute_state_change, _MALI_OSK_LOCKMODE_RW);
+
+}
+
+void mali_pm_always_on(mali_bool enable)
+{
+ if (MALI_TRUE == enable)
+ {
+ /* The event is processed in current thread synchronously */
+ mali_pm_event(MALI_PM_EVENT_SCHEME_ALWAYS_ON, MALI_FALSE, 0 );
+ }
+ else
+ {
+ /* The event is processed in current thread synchronously */
+ mali_pm_event(MALI_PM_EVENT_SCHEME_DYNAMIC_CONTROLL, MALI_FALSE, 0 );
+ }
+}
+
+static _mali_osk_errcode_t mali_pm_upper_half(void *data)
+{
+ /* not used */
+ return _MALI_OSK_ERR_OK;
+}
+
+static void mali_pm_bottom_half(void *data)
+{
+ mali_pm_process_next();
+}
+
+static u32 mali_pm_event_number_get(void)
+{
+ u32 retval;
+
+ mali_pm_lock(); /* spinlock: mali_pm_lock_set_next_state */
+ retval = ++mali_pm_event_number;
+ if (0==retval ) retval = ++mali_pm_event_number;
+ mali_pm_unlock();
+
+ return retval;
+}
+
+static void mali_pm_event(enum mali_pm_event pm_event, mali_bool schedule_work, u32 timer_time )
+{
+ mali_pm_lock(); /* spinlock: mali_pm_lock_set_next_state */
+ /* Only timer events should set this variable, all other events must set it to zero. */
+ if ( 0 != timer_time )
+ {
+ MALI_DEBUG_ASSERT( (pm_event==MALI_PM_EVENT_TIMER_LIGHT_SLEEP) || (pm_event==MALI_PM_EVENT_TIMER_DEEP_SLEEP) );
+ if ( mali_pm_event_number != timer_time )
+ {
+ /* In this case there have been processed newer events since the timer event was set up.
+ If so we always ignore the timing event */
+ mali_pm_unlock();
+ return;
+ }
+ }
+ else
+ {
+ /* Delete possible ongoing timers
+ if ( (MALI_PM_LEVEL_2_STANDBY==current_level) || (MALI_PM_LEVEL_3_LIGHT_SLEEP==current_level) )
+ {
+ _mali_osk_timer_del(idle_timer);
+ }
+ */
+ }
+ mali_pm_event_number++;
+ switch (pm_event)
+ {
+ case MALI_PM_EVENT_CORES_WORKING:
+ next_level_dynamic = MALI_PM_LEVEL_1_ON;
+ MALI_DEBUG_ASSERT( MALI_PM_SCHEME_OS_SUSPENDED != current_scheme );
+ break;
+ case MALI_PM_EVENT_CORES_IDLE:
+ next_level_dynamic = MALI_PM_LEVEL_2_STANDBY;
+ /*MALI_DEBUG_ASSERT( MALI_PM_SCHEME_OS_SUSPENDED != current_scheme );*/
+ break;
+ case MALI_PM_EVENT_TIMER_LIGHT_SLEEP:
+ MALI_DEBUG_ASSERT( MALI_PM_SCHEME_ALWAYS_ON != current_scheme );
+ MALI_DEBUG_ASSERT( MALI_PM_SCHEME_OS_SUSPENDED != current_scheme );
+ next_level_dynamic = MALI_PM_LEVEL_3_LIGHT_SLEEP;
+ break;
+ case MALI_PM_EVENT_TIMER_DEEP_SLEEP:
+ MALI_DEBUG_ASSERT( MALI_PM_SCHEME_ALWAYS_ON != current_scheme );
+ MALI_DEBUG_ASSERT( MALI_PM_SCHEME_OS_SUSPENDED != current_scheme );
+ next_level_dynamic = MALI_PM_LEVEL_4_DEEP_SLEEP;
+ break;
+ case MALI_PM_EVENT_OS_SUSPEND:
+ MALI_DEBUG_ASSERT( MALI_PM_SCHEME_ALWAYS_ON != current_scheme );
+ MALI_DEBUG_ASSERT( MALI_PM_SCHEME_OS_SUSPENDED != current_scheme );
+ current_scheme = MALI_PM_SCHEME_OS_SUSPENDED;
+ next_level_dynamic = MALI_PM_LEVEL_4_DEEP_SLEEP; /* Dynamic scheme will go into level when we are resumed */
+ break;
+ case MALI_PM_EVENT_OS_RESUME:
+ MALI_DEBUG_ASSERT(MALI_PM_SCHEME_OS_SUSPENDED == current_scheme );
+ current_scheme = MALI_PM_SCHEME_DYNAMIC;
+ break;
+ case MALI_PM_EVENT_SCHEME_ALWAYS_ON:
+ MALI_DEBUG_ASSERT( MALI_PM_SCHEME_OS_SUSPENDED != current_scheme );
+ current_scheme = MALI_PM_SCHEME_ALWAYS_ON;
+ break;
+ case MALI_PM_EVENT_SCHEME_DYNAMIC_CONTROLL:
+ MALI_DEBUG_ASSERT( MALI_PM_SCHEME_ALWAYS_ON == current_scheme || MALI_PM_SCHEME_DYNAMIC == current_scheme );
+ current_scheme = MALI_PM_SCHEME_DYNAMIC;
+ break;
+ default:
+ MALI_DEBUG_PRINT_ERROR(("Unknown next state."));
+ mali_pm_unlock();
+ return;
+ }
+ mali_pm_unlock();
+
+ if (MALI_TRUE == schedule_work)
+ {
+ _mali_osk_irq_schedulework(wq_irq);
+ }
+ else
+ {
+ mali_pm_process_next();
+ }
+}
+
+static void timeout_light_sleep(void* arg)
+{
+ /* State change only if no newer power events have happend from the time in arg.
+ Actual work will be scheduled on worker thread. */
+ mali_pm_event(MALI_PM_EVENT_TIMER_LIGHT_SLEEP, MALI_TRUE, (u32) arg);
+}
+
+void mali_pm_core_event(enum mali_core_event core_event)
+{
+ mali_bool transition_working = MALI_FALSE;
+ mali_bool transition_idle = MALI_FALSE;
+
+ _mali_osk_lock_wait(mali_pm_lock_set_core_states, _MALI_OSK_LOCKMODE_RW);
+
+ switch (core_event)
+ {
+ case MALI_CORE_EVENT_GP_START:
+ if (num_active_pps + num_active_gps == 0)
+ {
+ transition_working = MALI_TRUE;
+ }
+ num_active_gps++;
+ break;
+ case MALI_CORE_EVENT_GP_STOP:
+ if (num_active_pps + num_active_gps == 1)
+ {
+ transition_idle = MALI_TRUE;
+ }
+ num_active_gps--;
+ break;
+ case MALI_CORE_EVENT_PP_START:
+ if (num_active_pps + num_active_gps == 0)
+ {
+ transition_working = MALI_TRUE;
+ }
+ num_active_pps++;
+ break;
+ case MALI_CORE_EVENT_PP_STOP:
+ if (num_active_pps + num_active_gps == 1)
+ {
+ transition_idle = MALI_TRUE;
+ }
+ num_active_pps--;
+ break;
+ }
+
+ if (transition_working == MALI_TRUE)
+ {
+#ifdef CONFIG_MALI400_GPU_UTILIZATION
+ mali_utilization_core_start(_mali_osk_time_get_ns());
+#endif
+ mali_pm_event(MALI_PM_EVENT_CORES_WORKING, MALI_FALSE, 0); /* process event in same thread */
+ }
+ else if (transition_idle == MALI_TRUE)
+ {
+#ifdef CONFIG_MALI400_GPU_UTILIZATION
+ mali_utilization_core_end(_mali_osk_time_get_ns());
+#endif
+ mali_pm_event(MALI_PM_EVENT_CORES_IDLE, MALI_FALSE, 0); /* process event in same thread */
+ }
+
+ _mali_osk_lock_signal(mali_pm_lock_set_core_states, _MALI_OSK_LOCKMODE_RW);
+}
+
+void mali_pm_os_suspend(void)
+{
+ MALI_DEBUG_PRINT(2, ("Mali PM: OS suspending...\n"));
+
+ mali_gp_scheduler_suspend();
+ mali_pp_scheduler_suspend();
+ mali_pm_event(MALI_PM_EVENT_OS_SUSPEND, MALI_FALSE, 0); /* process event in same thread */
+
+ MALI_DEBUG_PRINT(2, ("Mali PM: OS suspend completed\n"));
+}
+
+void mali_pm_os_resume(void)
+{
+ MALI_DEBUG_PRINT(2, ("Mali PM: OS resuming...\n"));
+
+ mali_pm_event(MALI_PM_EVENT_OS_RESUME, MALI_FALSE, 0); /* process event in same thread */
+ mali_gp_scheduler_resume();
+ mali_pp_scheduler_resume();
+
+ MALI_DEBUG_PRINT(2, ("Mali PM: OS resume completed\n"));
+}
+
+void mali_pm_runtime_suspend(void)
+{
+ MALI_DEBUG_PRINT(2, ("Mali PM: OS runtime suspended\n"));
+}
+
+void mali_pm_runtime_resume(void)
+{
+ MALI_DEBUG_PRINT(3, ("Mali PM: OS runtime resumed\n"));
+}
diff --git a/drivers/media/video/samsung/mali/common/mali_pm.h b/drivers/media/video/samsung/mali/common/mali_pm.h
new file mode 100644
index 0000000..d4ccfde
--- /dev/null
+++ b/drivers/media/video/samsung/mali/common/mali_pm.h
@@ -0,0 +1,56 @@
+/*
+ * 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"
+
+enum mali_core_event
+{
+ MALI_CORE_EVENT_GP_START,
+ MALI_CORE_EVENT_GP_STOP,
+ MALI_CORE_EVENT_PP_START,
+ MALI_CORE_EVENT_PP_STOP
+};
+
+enum mali_pm_event
+{
+ MALI_PM_EVENT_CORES_WORKING,
+ MALI_PM_EVENT_CORES_IDLE,
+ MALI_PM_EVENT_TIMER_LIGHT_SLEEP,
+ MALI_PM_EVENT_TIMER_DEEP_SLEEP,
+ MALI_PM_EVENT_OS_SUSPEND,
+ MALI_PM_EVENT_OS_RESUME,
+ MALI_PM_EVENT_SCHEME_ALWAYS_ON,
+ MALI_PM_EVENT_SCHEME_DYNAMIC_CONTROLL,
+};
+
+_mali_osk_errcode_t mali_pm_initialize(void);
+void mali_pm_terminate(void);
+void mali_pm_always_on(mali_bool enable);
+
+void mali_pm_lock(void);
+void mali_pm_unlock(void);
+void mali_pm_execute_state_change_lock(void);
+
+void mali_pm_execute_state_change_unlock(void);
+
+mali_bool mali_pm_is_powered_on(void);
+
+void mali_pm_core_event(enum mali_core_event core_event);
+
+void mali_pm_os_suspend(void);
+void mali_pm_os_resume(void);
+void mali_pm_runtime_suspend(void);
+void mali_pm_runtime_resume(void);
+
+
+#endif /* __MALI_PM_H__ */
diff --git a/drivers/media/video/samsung/mali/common/mali_pmu.c b/drivers/media/video/samsung/mali/common/mali_pmu.c
new file mode 100644
index 0000000..348b5dc
--- /dev/null
+++ b/drivers/media/video/samsung/mali/common/mali_pmu.c
@@ -0,0 +1,199 @@
+/*
+ * 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"
+
+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;
+ u32 mali_registered_cores_power_mask;
+};
+
+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_REGISTER_ADDRESS_SPACE_SIZE = 0x10, /*< Size of register space */
+} pmu_reg_addr_mgmt_addr;
+
+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->mali_registered_cores_power_mask = mali_pmu_detect_mask(number_of_pp_cores, number_of_l2_caches);
+ if (_MALI_OSK_ERR_OK == mali_hw_core_create(&pmu->hw_core, resource, PMU_REGISTER_ADDRESS_SPACE_SIZE))
+ {
+ if (_MALI_OSK_ERR_OK == mali_pmu_reset(pmu))
+ {
+ mali_global_pmu_core = pmu;
+ return pmu;
+ }
+ mali_hw_core_delete(&pmu->hw_core);
+ }
+ _mali_osk_free(pmu);
+ }
+
+ return NULL;
+}
+
+void mali_pmu_delete(struct mali_pmu_core *pmu)
+{
+ MALI_DEBUG_ASSERT_POINTER(pmu);
+
+ mali_hw_core_delete(&pmu->hw_core);
+ _mali_osk_free(pmu);
+ pmu = NULL;
+}
+
+_mali_osk_errcode_t mali_pmu_reset(struct mali_pmu_core *pmu)
+{
+ /* Don't use interrupts - just poll status */
+ mali_hw_core_register_write(&pmu->hw_core, PMU_REG_ADDR_MGMT_INT_MASK, 0);
+ return _MALI_OSK_ERR_OK;
+}
+
+_mali_osk_errcode_t mali_pmu_powerdown_all(struct mali_pmu_core *pmu)
+{
+ u32 stat;
+ u32 timeout;
+
+ MALI_DEBUG_ASSERT_POINTER(pmu);
+ MALI_DEBUG_ASSERT( pmu->mali_registered_cores_power_mask != 0 );
+ MALI_DEBUG_PRINT( 4, ("Mali PMU: power down (0x%08X)\n", pmu->mali_registered_cores_power_mask) );
+
+ mali_hw_core_register_write(&pmu->hw_core, PMU_REG_ADDR_MGMT_POWER_DOWN, pmu->mali_registered_cores_power_mask);
+
+ /* Wait for cores to be powered down (100 x 100us = 100ms) */
+ timeout = 100;
+ do
+ {
+ /* Get status of sleeping cores */
+ stat = mali_hw_core_register_read(&pmu->hw_core, PMU_REG_ADDR_MGMT_STATUS);
+ stat &= pmu->mali_registered_cores_power_mask;
+ if( stat == pmu->mali_registered_cores_power_mask ) break; /* All cores we wanted are now asleep */
+ _mali_osk_time_ubusydelay(100);
+ timeout--;
+ } while( timeout > 0 );
+
+ if( timeout == 0 )
+ {
+ return _MALI_OSK_ERR_TIMEOUT;
+ }
+
+ return _MALI_OSK_ERR_OK;
+}
+
+_mali_osk_errcode_t mali_pmu_powerup_all(struct mali_pmu_core *pmu)
+{
+ u32 stat;
+ u32 timeout;
+
+ MALI_DEBUG_ASSERT_POINTER(pmu);
+ MALI_DEBUG_ASSERT( pmu->mali_registered_cores_power_mask != 0 ); /* Shouldn't be zero */
+ MALI_DEBUG_PRINT( 4, ("Mali PMU: power up (0x%08X)\n", pmu->mali_registered_cores_power_mask) );
+
+ mali_hw_core_register_write(&pmu->hw_core, PMU_REG_ADDR_MGMT_POWER_UP, pmu->mali_registered_cores_power_mask);
+
+ /* Wait for cores to be powered up (100 x 100us = 100ms) */
+ timeout = 100;
+ do
+ {
+ /* Get status of sleeping cores */
+ stat = mali_hw_core_register_read(&pmu->hw_core,PMU_REG_ADDR_MGMT_STATUS);
+ stat &= pmu->mali_registered_cores_power_mask;
+ if( stat == 0 ) break; /* All cores we wanted are now awake */
+ _mali_osk_time_ubusydelay(100);
+ timeout--;
+ } while( timeout > 0 );
+
+ if( timeout == 0 )
+ {
+ return _MALI_OSK_ERR_TIMEOUT;
+ }
+
+ return _MALI_OSK_ERR_OK;
+}
+
+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/media/video/samsung/mali/common/mali_pmu.h b/drivers/media/video/samsung/mali/common/mali_pmu.h
new file mode 100644
index 0000000..fd10c08
--- /dev/null
+++ b/drivers/media/video/samsung/mali/common/mali_pmu.h
@@ -0,0 +1,70 @@
+/*
+ * 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
+ */
+
+#include "mali_osk.h"
+
+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 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_powerdown_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_powerup_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);
diff --git a/drivers/media/video/samsung/mali/common/mali_pp.c b/drivers/media/video/samsung/mali/common/mali_pp.c
new file mode 100644
index 0000000..5549f82
--- /dev/null
+++ b/drivers/media/video/samsung/mali/common/mali_pp.c
@@ -0,0 +1,710 @@
+/*
+ * 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.h"
+#include "mali_hw_core.h"
+#include "mali_group.h"
+#include "mali_osk.h"
+#include "regs/mali_200_regs.h"
+#include "mali_kernel_common.h"
+#include "mali_kernel_core.h"
+#if MALI_TIMELINE_PROFILING_ENABLED
+#include "mali_osk_profiling.h"
+#endif
+
+/* See mali_gp.c file for description on how to handle the interrupt mask.
+ * This is how to do it on PP: mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_MASK, MALI200_REG_VAL_IRQ_MASK_USED);
+ */
+
+#define MALI_MAX_NUMBER_OF_PP_CORES 8
+
+/**
+ * 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 */
+ struct mali_group *group; /**< Parent group for this core */
+ _mali_osk_irq_t *irq; /**< IRQ handler */
+ u32 core_id; /**< Unique core ID */
+ struct mali_pp_job *running_job; /**< Current running (super) job */
+ u32 running_sub_job; /**< Current running sub job */
+ _mali_osk_timer_t *timeout_timer; /**< timeout timer for this core */
+ u32 timeout_job_id; /**< job id for the timed out job - relevant only if pp_core_timed_out == MALI_TRUE */
+ mali_bool core_timed_out; /**< if MALI_TRUE, this pp core has timed out; if MALI_FALSE, no timeout on this pp core */
+ 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 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 */
+};
+
+static struct mali_pp_core* mali_global_pp_cores[MALI_MAX_NUMBER_OF_PP_CORES];
+static u32 mali_global_num_pp_cores = 0;
+
+/* Interrupt handlers */
+static _mali_osk_errcode_t mali_pp_upper_half(void *data);
+static void mali_pp_bottom_half(void *data);
+static void mali_pp_irq_probe_trigger(void *data);
+static _mali_osk_errcode_t mali_pp_irq_probe_ack(void *data);
+static void mali_pp_post_process_job(struct mali_pp_core *core);
+static void mali_pp_timeout(void *data);
+
+struct mali_pp_core *mali_pp_create(const _mali_osk_resource_t *resource, struct mali_group *group)
+{
+ 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->group = group;
+ core->core_id = mali_global_num_pp_cores;
+ core->running_job = NULL;
+ core->counter_src0 = MALI_HW_CORE_NO_COUNTER;
+ core->counter_src1 = MALI_HW_CORE_NO_COUNTER;
+ 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;
+
+ mali_group_lock(group);
+ ret = mali_pp_reset(core);
+ mali_group_unlock(group);
+
+ 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_pp_upper_half,
+ mali_pp_bottom_half,
+ mali_pp_irq_probe_trigger,
+ mali_pp_irq_probe_ack,
+ core,
+ "mali_pp_irq_handlers");
+ if (NULL != core->irq)
+ {
+ /* Initialise the timeout timer */
+ core->timeout_timer = _mali_osk_timer_init();
+ if(NULL != core->timeout_timer)
+ {
+ _mali_osk_timer_setcallback(core->timeout_timer, mali_pp_timeout, (void *)core);
+
+ mali_global_pp_cores[mali_global_num_pp_cores] = core;
+ mali_global_num_pp_cores++;
+
+ return core;
+ }
+ else
+ {
+ MALI_PRINT_ERROR(("Failed to setup timeout timer for PP core %s\n", core->hw_core.description));
+ /* Release IRQ handlers */
+ _mali_osk_irq_term(core->irq);
+ }
+ }
+ else
+ {
+ MALI_PRINT_ERROR(("Mali PP: Failed to setup interrupt handlers for PP core %s\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_timer_term(core->timeout_timer);
+ _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--;
+ 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;
+ const int request_loop_count = 20;
+
+ MALI_DEBUG_ASSERT_POINTER(core);
+ MALI_ASSERT_GROUP_LOCKED(core->group);
+
+ /* Send the stop bus command. */
+ mali_pp_stop_bus(core);
+
+ /* Wait for bus to be stopped */
+ for (i = 0; i < request_loop_count; i++)
+ {
+ if (mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_STATUS) & MALI200_REG_VAL_STATUS_BUS_STOPPED)
+ break;
+ _mali_osk_time_ubusydelay(10);
+ }
+
+ if (request_loop_count == 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;
+}
+
+_mali_osk_errcode_t mali_pp_hard_reset(struct mali_pp_core *core)
+{
+ /* Bus must be stopped before calling this function */
+ const int reset_finished_loop_count = 15;
+ 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));
+ MALI_ASSERT_GROUP_LOCKED(core->group);
+
+ mali_pp_post_process_job(core); /* @@@@ is there some cases where it is unsafe to post process the job here? */
+
+ /* Set register to a bogus value. The register will be used to detect when reset is complete */
+ mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_WRITE_BOUNDARY_LOW, reset_invalid_value);
+
+ /* 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 < reset_finished_loop_count; 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;
+ }
+ _mali_osk_time_ubusydelay(10);
+ }
+
+ if (i == reset_finished_loop_count)
+ {
+ 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;
+}
+
+_mali_osk_errcode_t mali_pp_reset(struct mali_pp_core *core)
+{
+ int i;
+ const int request_loop_count = 20;
+
+ MALI_DEBUG_ASSERT_POINTER(core);
+ MALI_DEBUG_PRINT(4, ("Mali PP: Reset of core %s\n", core->hw_core.description));
+ MALI_ASSERT_GROUP_LOCKED(core->group);
+
+ mali_pp_post_process_job(core); /* @@@@ is there some cases where it is unsafe to post process the job here? */
+
+ mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_MASK, 0); /* disable the IRQs */
+
+#if defined(USING_MALI200)
+
+ /* On Mali-200, stop the bus, then do a hard reset of the core */
+
+ mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_CTRL_MGMT, MALI200_REG_VAL_CTRL_MGMT_STOP_BUS);
+
+ for (i = 0; i < request_loop_count; i++)
+ {
+ if (mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_STATUS) & MALI200_REG_VAL_STATUS_BUS_STOPPED)
+ {
+ break;
+ }
+ _mali_osk_time_ubusydelay(10);
+ }
+
+ if (request_loop_count == i)
+ {
+ MALI_PRINT_ERROR(("Mali PP: Failed to stop bus for core %s, unable to recover\n", core->hw_core.description));
+ return _MALI_OSK_ERR_FAULT ;
+ }
+
+ /* the bus was stopped OK, do the hard reset */
+ mali_pp_hard_reset(core);
+
+#elif defined(USING_MALI400)
+
+ /* Mali-300 and Mali-400 have a safe reset command which we use */
+
+ mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_CLEAR, MALI400PP_REG_VAL_IRQ_RESET_COMPLETED);
+ mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_CTRL_MGMT, MALI400PP_REG_VAL_CTRL_MGMT_SOFT_RESET);
+
+ for (i = 0; i < request_loop_count; i++)
+ {
+ if (mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_RAWSTAT) & MALI400PP_REG_VAL_IRQ_RESET_COMPLETED)
+ {
+ break;
+ }
+ _mali_osk_time_ubusydelay(10);
+ }
+
+ if (request_loop_count == i)
+ {
+ MALI_DEBUG_PRINT(2, ("Mali PP: Failed to reset core %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;
+ }
+#else
+#error "no supported mali core defined"
+#endif
+
+ /* 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_job_start(struct mali_pp_core *core, struct mali_pp_job *job, u32 sub_job)
+{
+ 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 = core->counter_src0;
+ core->counter_src1_used = core->counter_src1;
+
+ MALI_DEBUG_ASSERT_POINTER(core);
+ MALI_ASSERT_GROUP_LOCKED(core->group);
+
+ mali_hw_core_register_write_array_relaxed(&core->hw_core, MALI200_REG_ADDR_FRAME, frame_registers, MALI200_NUM_REGS_FRAME);
+ if (0 != sub_job)
+ {
+ /*
+ * There are two frame registers which are different for each sub job.
+ * For the first sub job, these are correctly represented in the frame register array,
+ * but we need to patch these for all other sub jobs
+ */
+ mali_hw_core_register_write_relaxed(&core->hw_core, MALI200_REG_ADDR_FRAME, mali_pp_job_get_addr_frame(job, sub_job));
+ mali_hw_core_register_write_relaxed(&core->hw_core, MALI200_REG_ADDR_STACK, mali_pp_job_get_addr_stack(job, sub_job));
+ }
+
+ if (wb0_registers[0]) /* M200_WB0_REG_SOURCE_SELECT register */
+ {
+ mali_hw_core_register_write_array_relaxed(&core->hw_core, MALI200_REG_ADDR_WB0, wb0_registers, MALI200_NUM_REGS_WBx);
+ }
+
+ if (wb1_registers[0]) /* M200_WB1_REG_SOURCE_SELECT register */
+ {
+ mali_hw_core_register_write_array_relaxed(&core->hw_core, MALI200_REG_ADDR_WB1, wb1_registers, MALI200_NUM_REGS_WBx);
+ }
+
+ if (wb2_registers[0]) /* M200_WB2_REG_SOURCE_SELECT register */
+ {
+ mali_hw_core_register_write_array_relaxed(&core->hw_core, MALI200_REG_ADDR_WB2, wb2_registers, MALI200_NUM_REGS_WBx);
+ }
+
+ /* This selects which performance counters we are reading */
+ if (MALI_HW_CORE_NO_COUNTER != core->counter_src0_used || MALI_HW_CORE_NO_COUNTER != core->counter_src1_used)
+ {
+ /* global_config has enabled HW counters, this will override anything specified by user space */
+ if (MALI_HW_CORE_NO_COUNTER != core->counter_src0_used)
+ {
+ mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_0_SRC, core->counter_src0_used);
+ mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_0_ENABLE, MALI200_REG_VAL_PERF_CNT_ENABLE);
+ }
+ if (MALI_HW_CORE_NO_COUNTER != core->counter_src1_used)
+ {
+ mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_1_SRC, core->counter_src1_used);
+ mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_1_ENABLE, MALI200_REG_VAL_PERF_CNT_ENABLE);
+ }
+ }
+ else
+ {
+ /* Use HW counters from job object, if any */
+ u32 perf_counter_flag = mali_pp_job_get_perf_counter_flag(job);
+ if (0 != perf_counter_flag)
+ {
+ if (perf_counter_flag & _MALI_PERFORMANCE_COUNTER_FLAG_SRC0_ENABLE)
+ {
+ core->counter_src0_used = mali_pp_job_get_perf_counter_src0(job);
+ mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_0_SRC, core->counter_src0_used);
+ mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_0_ENABLE, MALI200_REG_VAL_PERF_CNT_ENABLE);
+ }
+
+ if (perf_counter_flag & _MALI_PERFORMANCE_COUNTER_FLAG_SRC1_ENABLE)
+ {
+ core->counter_src1_used = mali_pp_job_get_perf_counter_src1(job);
+ mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_1_SRC, core->counter_src1_used);
+ mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_1_ENABLE, MALI200_REG_VAL_PERF_CNT_ENABLE);
+ }
+ }
+ }
+
+ 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();
+
+ /* Setup the timeout timer value and save the job id for the job running on the pp core */
+ _mali_osk_timer_add(core->timeout_timer, _mali_osk_time_mstoticks(mali_max_job_runtime));
+ core->timeout_job_id = mali_pp_job_get_id(job);
+
+#if MALI_TIMELINE_PROFILING_ENABLED
+ _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_FLUSH, job->frame_builder_id, job->flush_id, 0, 0, 0);
+ _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_START|MALI_PROFILING_MAKE_EVENT_CHANNEL_PP(core->core_id), job->pid, job->tid, 0, 0, 0);
+#endif
+
+ core->running_job = job;
+ core->running_sub_job = sub_job;
+}
+
+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);
+}
+
+u32 mali_pp_core_get_id(struct mali_pp_core *core)
+{
+ MALI_DEBUG_ASSERT_POINTER(core);
+ return core->core_id;
+}
+
+mali_bool mali_pp_core_set_counter_src0(struct mali_pp_core *core, u32 counter)
+{
+ MALI_DEBUG_ASSERT_POINTER(core);
+
+ core->counter_src0 = counter;
+ return MALI_TRUE;
+}
+
+mali_bool mali_pp_core_set_counter_src1(struct mali_pp_core *core, u32 counter)
+{
+ MALI_DEBUG_ASSERT_POINTER(core);
+
+ core->counter_src1 = counter;
+ return MALI_TRUE;
+}
+
+u32 mali_pp_core_get_counter_src0(struct mali_pp_core *core)
+{
+ MALI_DEBUG_ASSERT_POINTER(core);
+ return core->counter_src0;
+}
+
+u32 mali_pp_core_get_counter_src1(struct mali_pp_core *core)
+{
+ MALI_DEBUG_ASSERT_POINTER(core);
+ return core->counter_src1;
+}
+
+struct mali_pp_core* mali_pp_get_global_pp_core(u32 index)
+{
+ if (MALI_MAX_NUMBER_OF_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;
+}
+
+u32 mali_pp_get_max_num_pp_cores(void)
+{
+ return MALI_MAX_NUMBER_OF_PP_CORES;
+}
+
+/* ------------- interrupt handling below ------------------ */
+static _mali_osk_errcode_t mali_pp_upper_half(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_MASK_NONE != irq_readout)
+ {
+ /* Mask out all IRQs from this core until IRQ is handled */
+ mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_MASK, MALI200_REG_VAL_IRQ_MASK_NONE);
+
+#if MALI_TIMELINE_PROFILING_ENABLED
+ _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
+
+ /* We do need to handle this in a bottom half */
+ _mali_osk_irq_schedulework(core->irq);
+ return _MALI_OSK_ERR_OK;
+ }
+
+ return _MALI_OSK_ERR_FAULT;
+}
+
+static void mali_pp_bottom_half(void *data)
+{
+ struct mali_pp_core *core = (struct mali_pp_core *)data;
+ u32 irq_readout;
+ u32 irq_errors;
+
+#if MALI_TIMELINE_PROFILING_ENABLED
+#if 0 /* Bottom half TLP logging is currently not supported */
+ _mali_osk_profiling_add_event( MALI_PROFILING_EVENT_TYPE_START| MALI_PROFILING_EVENT_CHANNEL_SOFTWARE , _mali_osk_get_pid(), _mali_osk_get_tid(), 0, 0, 0);
+#endif
+#endif
+
+ mali_group_lock(core->group); /* Group lock grabbed in core handlers, but released in common group handler */
+
+ if ( MALI_FALSE == mali_group_power_is_on(core->group) )
+ {
+ MALI_PRINT_ERROR(("Interrupt bottom half of %s when core is OFF.", core->hw_core.description));
+ mali_group_unlock(core->group);
+ return;
+ }
+
+ irq_readout = mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_RAWSTAT) & MALI200_REG_VAL_IRQ_MASK_USED;
+
+ MALI_DEBUG_PRINT(4, ("Mali PP: Bottom half IRQ 0x%08X from core %s\n", irq_readout, core->hw_core.description));
+
+ if (irq_readout & MALI200_REG_VAL_IRQ_END_OF_FRAME)
+ {
+ mali_pp_post_process_job(core);
+ MALI_DEBUG_PRINT(3, ("Mali PP: Job completed, calling group handler\n"));
+ mali_group_bottom_half(core->group, GROUP_EVENT_PP_JOB_COMPLETED); /* Will release group lock */
+ 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_pp_post_process_job(core);
+ MALI_PRINT_ERROR(("Mali PP: Unknown interrupt 0x%08X from core %s, aborting job\n",
+ irq_readout, core->hw_core.description));
+ mali_group_bottom_half(core->group, GROUP_EVENT_PP_JOB_FAILED); /* Will release group lock */
+ return;
+ }
+ else if (MALI_TRUE == core->core_timed_out) /* SW timeout */
+ {
+ if (core->timeout_job_id == mali_pp_job_get_id(core->running_job))
+ {
+ mali_pp_post_process_job(core);
+ MALI_DEBUG_PRINT(2, ("Mali PP: Job %d timed out on core %s\n",
+ mali_pp_job_get_id(core->running_job), core->hw_core.description));
+ mali_group_bottom_half(core->group, GROUP_EVENT_PP_JOB_TIMED_OUT); /* Will release group lock */
+ }
+ else
+ {
+ mali_group_unlock(core->group);
+ }
+ core->core_timed_out = MALI_FALSE;
+ return;
+ }
+ else if (irq_readout & MALI200_REG_VAL_IRQ_HANG)
+ {
+ /* Just ignore hang interrupts, the job timer will detect hanging jobs anyways */
+ mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_CLEAR, MALI200_REG_VAL_IRQ_HANG);
+ }
+
+ /*
+ * The only way to get here is if we got a HANG interrupt, which we ignore.
+ * Re-enable interrupts and let core continue to run
+ */
+ mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_MASK, MALI200_REG_VAL_IRQ_MASK_USED);
+ mali_group_unlock(core->group);
+
+#if MALI_TIMELINE_PROFILING_ENABLED
+#if 0 /* Bottom half TLP logging is currently not supported */
+ _mali_osk_profiling_add_event( MALI_PROFILING_EVENT_TYPE_STOP| MALI_PROFILING_EVENT_CHANNEL_SOFTWARE , _mali_osk_get_pid(), _mali_osk_get_tid(), 0, 0, 0);
+#endif
+#endif
+}
+
+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); /* @@@@ This should not be needed */
+ 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;
+}
+
+
+/* ------ local helper functions below --------- */
+static void mali_pp_post_process_job(struct mali_pp_core *core)
+{
+ MALI_ASSERT_GROUP_LOCKED(core->group);
+
+ if (NULL != core->running_job)
+ {
+ u32 val0 = 0;
+ u32 val1 = 0;
+#if MALI_TIMELINE_PROFILING_ENABLED
+ int counter_index = COUNTER_FP0_C0 + (2 * core->core_id);
+#endif
+
+ if (MALI_HW_CORE_NO_COUNTER != core->counter_src0_used)
+ {
+ val0 = mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_0_VALUE);
+ if (mali_pp_job_get_perf_counter_flag(core->running_job) &&
+ _MALI_PERFORMANCE_COUNTER_FLAG_SRC0_ENABLE && mali_pp_job_get_perf_counter_src0(core->running_job) == core->counter_src0_used)
+ {
+ /* We retrieved the counter that user space asked for, so return the value through the job object */
+ mali_pp_job_set_perf_counter_value0(core->running_job, core->running_sub_job, val0);
+ }
+ else
+ {
+ /* User space asked for a counter, but this is not what we retrived (overridden by counter src set on core) */
+ mali_pp_job_set_perf_counter_value0(core->running_job, core->running_sub_job, MALI_HW_CORE_INVALID_VALUE);
+ }
+
+#if MALI_TIMELINE_PROFILING_ENABLED
+ _mali_osk_profiling_report_hw_counter(counter_index, val0);
+#endif
+ }
+
+ if (MALI_HW_CORE_NO_COUNTER != core->counter_src1_used)
+ {
+ val1 = mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_PERF_CNT_1_VALUE);
+ if (mali_pp_job_get_perf_counter_flag(core->running_job) &&
+ _MALI_PERFORMANCE_COUNTER_FLAG_SRC1_ENABLE && mali_pp_job_get_perf_counter_src1(core->running_job) == core->counter_src1_used)
+ {
+ /* We retrieved the counter that user space asked for, so return the value through the job object */
+ mali_pp_job_set_perf_counter_value1(core->running_job, core->running_sub_job, val1);
+ }
+ else
+ {
+ /* User space asked for a counter, but this is not what we retrived (overridden by counter src set on core) */
+ mali_pp_job_set_perf_counter_value1(core->running_job, core->running_sub_job, MALI_HW_CORE_INVALID_VALUE);
+ }
+
+#if MALI_TIMELINE_PROFILING_ENABLED
+ _mali_osk_profiling_report_hw_counter(counter_index + 1, val1);
+#endif
+ }
+
+#if MALI_TIMELINE_PROFILING_ENABLED
+ _mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP|MALI_PROFILING_MAKE_EVENT_CHANNEL_PP(core->core_id),
+ val0, val1, core->counter_src0_used | (core->counter_src1_used << 8), 0, 0);
+#endif
+
+ /* We are no longer running a job... */
+ core->running_job = NULL;
+ _mali_osk_timer_del(core->timeout_timer);
+ }
+}
+
+/* callback function for pp core timeout */
+static void mali_pp_timeout(void *data)
+{
+ struct mali_pp_core * core = ((struct mali_pp_core *)data);
+
+ MALI_DEBUG_PRINT(3, ("Mali PP: TIMEOUT callback \n"));
+ core->core_timed_out = MALI_TRUE;
+ _mali_osk_irq_schedulework(core->irq);
+}
+
+#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
+
+#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/media/video/samsung/mali/common/mali_pp.h b/drivers/media/video/samsung/mali/common/mali_pp.h
new file mode 100644
index 0000000..9b425a0
--- /dev/null
+++ b/drivers/media/video/samsung/mali/common/mali_pp.h
@@ -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.
+ */
+
+#ifndef __MALI_PP_H__
+#define __MALI_PP_H__
+
+#include "mali_osk.h"
+#include "mali_pp_job.h"
+
+struct mali_pp_core;
+struct mali_group;
+
+_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);
+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);
+_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);
+
+u32 mali_pp_core_get_version(struct mali_pp_core *core);
+
+u32 mali_pp_core_get_id(struct mali_pp_core *core);
+
+mali_bool mali_pp_core_set_counter_src0(struct mali_pp_core *core, u32 counter);
+mali_bool mali_pp_core_set_counter_src1(struct mali_pp_core *core, u32 counter);
+u32 mali_pp_core_get_counter_src0(struct mali_pp_core *core);
+u32 mali_pp_core_get_counter_src1(struct mali_pp_core *core);
+struct mali_pp_core* mali_pp_get_global_pp_core(u32 index);
+u32 mali_pp_get_glob_num_pp_cores(void);
+u32 mali_pp_get_max_num_pp_cores(void);
+/* Debug */
+u32 mali_pp_dump_state(struct mali_pp_core *core, char *buf, u32 size);
+
+#endif /* __MALI_PP_H__ */
diff --git a/drivers/media/video/samsung/mali/common/mali_pp_job.c b/drivers/media/video/samsung/mali/common/mali_pp_job.c
new file mode 100644
index 0000000..1efcfda
--- /dev/null
+++ b/drivers/media/video/samsung/mali/common/mali_pp_job.c
@@ -0,0 +1,92 @@
+/*
+ * 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"
+
+struct mali_pp_job *mali_pp_job_create(struct mali_session_data *session, _mali_uk_pp_start_job_s *args, u32 id)
+{
+ struct mali_pp_job *job;
+
+ if (args->num_cores > _MALI_PP_MAX_SUB_JOBS)
+ {
+ MALI_PRINT_ERROR(("Mali PP job: Too many sub jobs specified in job object\n"));
+ return NULL;
+ }
+
+ job = _mali_osk_malloc(sizeof(struct mali_pp_job));
+ if (NULL != job)
+ {
+ u32 i;
+ _mali_osk_list_init(&job->list);
+ job->session = session;
+ job->id = id;
+ job->user_id = args->user_job_ptr;
+ _mali_osk_memcpy(job->frame_registers, args->frame_registers, sizeof(job->frame_registers));
+ _mali_osk_memcpy(job->frame_registers_addr_frame, args->frame_registers_addr_frame, sizeof(job->frame_registers_addr_frame));
+ _mali_osk_memcpy(job->frame_registers_addr_stack, args->frame_registers_addr_stack, sizeof(job->frame_registers_addr_stack));
+
+ /* Only copy write back registers for the units that are enabled */
+ job->wb0_registers[0] = 0;
+ job->wb1_registers[0] = 0;
+ job->wb2_registers[0] = 0;
+ if (args->wb0_registers[0]) /* M200_WB0_REG_SOURCE_SELECT register */
+ {
+ _mali_osk_memcpy(job->wb0_registers, args->wb0_registers, sizeof(job->wb0_registers));
+ }
+ if (args->wb1_registers[0]) /* M200_WB1_REG_SOURCE_SELECT register */
+ {
+ _mali_osk_memcpy(job->wb1_registers, args->wb1_registers, sizeof(job->wb1_registers));
+ }
+ if (args->wb2_registers[0]) /* M200_WB2_REG_SOURCE_SELECT register */
+ {
+ _mali_osk_memcpy(job->wb2_registers, args->wb2_registers, sizeof(job->wb2_registers));
+ }
+
+ job->perf_counter_flag = args->perf_counter_flag;
+ job->perf_counter_src0 = args->perf_counter_src0;
+ job->perf_counter_src1 = args->perf_counter_src1;
+ for (i = 0; i < args->num_cores; i++)
+ {
+ job->perf_counter_value0[i] = 0;
+ job->perf_counter_value1[i] = 0;
+ }
+ job->sub_job_count = args->num_cores;
+ job->sub_jobs_started = 0;
+ job->sub_jobs_completed = 0;
+ job->sub_job_errors = 0;
+
+ job->pid = _mali_osk_get_pid();
+ job->tid = _mali_osk_get_tid();
+ job->frame_builder_id = args->frame_builder_id;
+ job->flush_id = args->flush_id;
+
+ return job;
+ }
+
+ return NULL;
+}
+
+void mali_pp_job_delete(struct mali_pp_job *job)
+{
+ _mali_osk_free(job);
+}
+
+_mali_osk_errcode_t mali_pp_job_check(struct mali_pp_job *job)
+{
+ if ((0 == job->frame_registers[0]) || (0 == job->frame_registers[1]))
+ {
+ return _MALI_OSK_ERR_FAULT;
+ }
+ return _MALI_OSK_ERR_OK;
+}
diff --git a/drivers/media/video/samsung/mali/common/mali_pp_job.h b/drivers/media/video/samsung/mali/common/mali_pp_job.h
new file mode 100644
index 0000000..7fe87f8
--- /dev/null
+++ b/drivers/media/video/samsung/mali/common/mali_pp_job.h
@@ -0,0 +1,255 @@
+/*
+ * 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"
+
+/**
+ * The structure represends a PP job, including all sub-jobs
+ * (This struct unfortunatly 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 */
+ u32 id; /**< identifier for this job in kernel space (sequencial numbering) */
+ u32 user_id; /**< identifier for the job in user space */
+ u32 frame_registers[_MALI_PP_MAX_FRAME_REGISTERS]; /**< core specific registers associated with this job, see ARM DDI0415A */
+ u32 frame_registers_addr_frame[_MALI_PP_MAX_SUB_JOBS - 1]; /**< ADDR_FRAME registers for sub job 1-7 */
+ u32 frame_registers_addr_stack[_MALI_PP_MAX_SUB_JOBS - 1]; /**< ADDR_STACK registers for sub job 1-7 */
+ u32 wb0_registers[_MALI_PP_MAX_WB_REGISTERS]; /**< Write back unit 0 registers */
+ u32 wb1_registers[_MALI_PP_MAX_WB_REGISTERS]; /**< Write back unit 1 registers */
+ u32 wb2_registers[_MALI_PP_MAX_WB_REGISTERS]; /**< Write back unit 2 registers */
+ u32 perf_counter_flag; /**< bitmask indicating which performance counters to enable, see \ref _MALI_PERFORMANCE_COUNTER_FLAG_SRC0_ENABLE and related macro definitions */
+ u32 perf_counter_src0; /**< Source id for performance counter 0 (see ARM DDI0415A, Table 3-60) */
+ u32 perf_counter_src1; /**< Source id for performance counter 1 (see ARM DDI0415A, Table 3-60) */
+ 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_job_count; /**< Total number of sub-jobs in this superjob */
+ 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 */
+ u32 frame_builder_id; /**< id of the originating frame builder */
+ u32 flush_id; /**< flush id within the originating frame builder */
+};
+
+struct mali_pp_job *mali_pp_job_create(struct mali_session_data *session, _mali_uk_pp_start_job_s *args, u32 id);
+void mali_pp_job_delete(struct mali_pp_job *job);
+
+_mali_osk_errcode_t mali_pp_job_check(struct mali_pp_job *job);
+
+/******************************************************
+ * simple utility functions for dealing with pp jobs:
+ *****************************************************/
+
+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->user_id;
+}
+
+MALI_STATIC_INLINE u32 mali_pp_job_get_frame_builder_id(struct mali_pp_job *job)
+{
+ return job->frame_builder_id;
+}
+
+MALI_STATIC_INLINE u32 mali_pp_job_get_flush_id(struct mali_pp_job *job)
+{
+ return job->flush_id;
+}
+
+MALI_STATIC_INLINE u32* mali_pp_job_get_frame_registers(struct mali_pp_job *job)
+{
+ return job->frame_registers;
+}
+
+MALI_STATIC_INLINE u32 mali_pp_job_get_addr_frame(struct mali_pp_job *job, u32 sub_job)
+{
+ if (sub_job == 0)
+ {
+ return job->frame_registers[MALI200_REG_ADDR_FRAME / sizeof(u32)];
+ }
+ else if (sub_job < _MALI_PP_MAX_SUB_JOBS)
+ {
+ return job->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 (sub_job == 0)
+ {
+ return job->frame_registers[MALI200_REG_ADDR_STACK / sizeof(u32)];
+ }
+ else if (sub_job < _MALI_PP_MAX_SUB_JOBS)
+ {
+ return job->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->wb0_registers;
+}
+
+MALI_STATIC_INLINE u32* mali_pp_job_get_wb1_registers(struct mali_pp_job *job)
+{
+ return job->wb1_registers;
+}
+
+MALI_STATIC_INLINE u32* mali_pp_job_get_wb2_registers(struct mali_pp_job *job)
+{
+ return job->wb2_registers;
+}
+
+MALI_STATIC_INLINE void mali_pp_job_disable_wb0(struct mali_pp_job *job)
+{
+ job->wb0_registers[MALI200_REG_ADDR_WB_SOURCE_SELECT] = 0;
+}
+
+MALI_STATIC_INLINE void mali_pp_job_disable_wb1(struct mali_pp_job *job)
+{
+ job->wb1_registers[MALI200_REG_ADDR_WB_SOURCE_SELECT] = 0;
+}
+
+MALI_STATIC_INLINE void mali_pp_job_disable_wb2(struct mali_pp_job *job)
+{
+ job->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_job_count) ? 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 is started. */
+MALI_STATIC_INLINE mali_bool mali_pp_job_is_currently_rendering_and_if_so_abort_new_starts(struct mali_pp_job *job)
+{
+ /* All can not be started, since then it would not be in the job queue */
+ MALI_DEBUG_ASSERT( job->sub_jobs_started != job->sub_job_count );
+
+ /* If at least one job is started */
+ if ( (job->sub_jobs_started > 0) )
+ {
+ /* If at least one job is currently being rendered, and thus assigned to a group and core */
+ if (job->sub_jobs_started > job->sub_jobs_completed )
+ {
+ u32 jobs_remaining = job->sub_job_count - job->sub_jobs_started;
+ job->sub_jobs_started += jobs_remaining;
+ job->sub_jobs_completed += jobs_remaining;
+ job->sub_job_errors += jobs_remaining;
+ /* Returning TRUE indicating that we can not delete this job which is being redered */
+ return MALI_TRUE;
+ }
+ }
+ /* The job is not being rendered to at the moment and can then safely be deleted */
+ return MALI_FALSE;
+}
+
+MALI_STATIC_INLINE mali_bool mali_pp_job_is_complete(struct mali_pp_job *job)
+{
+ return (job->sub_job_count == 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_job_count;
+}
+
+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 u32 mali_pp_job_get_perf_counter_flag(struct mali_pp_job *job)
+{
+ return job->perf_counter_flag;
+}
+
+MALI_STATIC_INLINE u32 mali_pp_job_get_perf_counter_src0(struct mali_pp_job *job)
+{
+ return job->perf_counter_src0;
+}
+
+MALI_STATIC_INLINE u32 mali_pp_job_get_perf_counter_src1(struct mali_pp_job *job)
+{
+ return job->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_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;
+}
+
+#endif /* __MALI_PP_JOB_H__ */
diff --git a/drivers/media/video/samsung/mali/common/mali_pp_scheduler.c b/drivers/media/video/samsung/mali/common/mali_pp_scheduler.c
new file mode 100644
index 0000000..ce07a76
--- /dev/null
+++ b/drivers/media/video/samsung/mali/common/mali_pp_scheduler.c
@@ -0,0 +1,542 @@
+/*
+ * 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_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_cluster.h"
+
+/* Maximum of 8 PP cores (a group can only have maximum of 1 PP core) */
+#define MALI_MAX_NUMBER_OF_PP_GROUPS 8
+
+static mali_bool mali_pp_scheduler_is_suspended(void);
+
+enum mali_pp_slot_state
+{
+ MALI_PP_SLOT_STATE_IDLE,
+ MALI_PP_SLOT_STATE_WORKING,
+};
+
+/* A render slot is an entity which jobs can be scheduled onto */
+struct mali_pp_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_pp_slot_state state;
+};
+
+static u32 pp_version = 0;
+static _MALI_OSK_LIST_HEAD(job_queue); /* List of jobs with some unscheduled work */
+static struct mali_pp_slot slots[MALI_MAX_NUMBER_OF_PP_GROUPS];
+static u32 num_slots = 0;
+static u32 num_slots_idle = 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);
+
+_mali_osk_errcode_t mali_pp_scheduler_initialize(void)
+{
+ u32 i;
+
+ _MALI_OSK_INIT_LIST_HEAD(&job_queue);
+
+ pp_scheduler_lock = _mali_osk_lock_init(_MALI_OSK_LOCKFLAG_ORDERED |_MALI_OSK_LOCKFLAG_NONINTERRUPTABLE, 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;
+ }
+
+ /* Find all the available PP cores */
+ for (i = 0; i < mali_cluster_get_glob_num_clusters(); i++)
+ {
+ u32 group_id = 0;
+ struct mali_cluster *curr_cluster = mali_cluster_get_global_cluster(i);
+ struct mali_group *group = mali_cluster_get_group(curr_cluster, group_id);
+ while (NULL != group)
+ {
+ struct mali_pp_core *pp_core = mali_group_get_pp_core(group);
+ if (NULL != pp_core)
+ {
+ if (0 == pp_version)
+ {
+ /* Retrieve PP version from first avaiable PP core */
+ pp_version = mali_pp_core_get_version(pp_core);
+ }
+ slots[num_slots].group = group;
+ slots[num_slots].state = MALI_PP_SLOT_STATE_IDLE;
+ num_slots++;
+ num_slots_idle++;
+ }
+ group_id++;
+ group = mali_cluster_get_group(curr_cluster, group_id);
+ }
+ }
+
+ return _MALI_OSK_ERR_OK;
+}
+
+void mali_pp_scheduler_terminate(void)
+{
+ _mali_osk_wait_queue_term(pp_scheduler_working_wait_queue);
+ _mali_osk_lock_term(pp_scheduler_lock);
+}
+
+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);
+}
+
+#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
+
+static void mali_pp_scheduler_schedule(void)
+{
+ u32 i;
+ struct mali_pp_job *job;
+#if MALI_PP_SCHEDULER_FORCE_NO_JOB_OVERLAP_BETWEEN_APPS
+ struct mali_session_data * session;
+#endif
+
+ MALI_ASSERT_PP_SCHEDULER_LOCKED();
+
+ if (0 < pause_count || 0 == num_slots_idle || _mali_osk_list_empty(&job_queue))
+ {
+ MALI_DEBUG_PRINT(4, ("Mali PP scheduler: Nothing to schedule (paused=%u, idle slots=%u)\n",
+ pause_count, num_slots_idle));
+ return; /* Nothing to do, so early out */
+ }
+
+
+#if MALI_PP_SCHEDULER_FORCE_NO_JOB_OVERLAP
+ if ( num_slots_idle < num_slots )
+ {
+ MALI_DEBUG_PRINT(4, ("Mali PP scheduler: Job not started, since only %d/%d cores are available\n", num_slots_idle,num_slots));
+ return;
+ }
+#endif
+
+#if MALI_PP_SCHEDULER_FORCE_NO_JOB_OVERLAP_BETWEEN_APPS
+ /* Finding initial session for the PP cores */
+ job = _MALI_OSK_LIST_ENTRY(job_queue.next, struct mali_pp_job, list);
+ session = job->session;
+ if ( num_slots != num_slots_idle )
+ {
+ for (i = 0; (i < num_slots) ; i++)
+ {
+ if ( slots[i].state == MALI_PP_SLOT_STATE_IDLE )
+ {
+ continue;
+ }
+ session = mali_group_get_session(slots[i].group);
+ break;
+ }
+ }
+#endif
+
+ for (i = 0; (i < num_slots) && (0 < num_slots_idle); i++)
+ {
+ u32 sub_job;
+
+ if (_mali_osk_list_empty(&job_queue)) /* move this check down to where we know we have started all sub jobs for this job??? */
+ {
+ break; /* No more jobs to schedule, so early out */
+ }
+
+ if (MALI_PP_SLOT_STATE_IDLE != slots[i].state)
+ {
+ continue;
+ }
+
+ job = _MALI_OSK_LIST_ENTRY(job_queue.next, struct mali_pp_job, list);
+ MALI_DEBUG_ASSERT(mali_pp_job_has_unstarted_sub_jobs(job)); /* All jobs on the job_queue should have unstarted sub jobs */
+
+ #if MALI_PP_SCHEDULER_KEEP_SUB_JOB_STARTS_ALIGNED
+ if ( (0==job->sub_jobs_started) && (num_slots_idle < num_slots) && (job->sub_job_count > num_slots_idle))
+ {
+ MALI_DEBUG_PRINT(4, ("Mali PP scheduler: Job with %d subjobs not started, since only %d/%d cores are available\n", job->sub_job_count, num_slots_idle,num_slots));
+ return;
+ }
+ #endif
+
+ #if MALI_PP_SCHEDULER_FORCE_NO_JOB_OVERLAP_BETWEEN_APPS
+ if ( job->session != session )
+ {
+ MALI_DEBUG_PRINT(4, ("Mali PP scheduler: Job not started since existing job is from another application\n"));
+ return;
+ }
+ #endif
+
+ sub_job = mali_pp_job_get_first_unstarted_sub_job(job);
+
+ MALI_DEBUG_PRINT(4, ("Mali PP scheduler: Starting job %u (0x%08X) part %u/%u\n", mali_pp_job_get_id(job), job, sub_job + 1, mali_pp_job_get_sub_job_count(job)));
+ if (_MALI_OSK_ERR_OK == mali_group_start_pp_job(slots[i].group, job, sub_job))
+ {
+ MALI_DEBUG_PRINT(4, ("Mali PP scheduler: Job %u (0x%08X) part %u/%u started\n", mali_pp_job_get_id(job), job, sub_job + 1, mali_pp_job_get_sub_job_count(job)));
+
+ /* Mark this sub job as started */
+ mali_pp_job_mark_sub_job_started(job, sub_job);
+
+ /* Mark slot as busy */
+ slots[i].state = MALI_PP_SLOT_STATE_WORKING;
+ num_slots_idle--;
+
+ if (!mali_pp_job_has_unstarted_sub_jobs(job))
+ {
+ /*
+ * All sub jobs have now started for this job, remove this job from the job queue.
+ * The job will now only be referred to by the slots which are running it.
+ * The last slot to complete will make sure it is returned to user space.
+ */
+ _mali_osk_list_del(&job->list);
+#if MALI_PP_SCHEDULER_FORCE_NO_JOB_OVERLAP
+ MALI_DEBUG_PRINT(6, ("Mali PP scheduler: Skip scheduling more jobs when MALI_PP_SCHEDULER_FORCE_NO_JOB_OVERLAP is set.\n"));
+ return;
+#endif
+ }
+ }
+ else
+ {
+ MALI_DEBUG_PRINT(3, ("Mali PP scheduler: Failed to start PP job\n"));
+ return;
+ }
+ }
+}
+
+static void mali_pp_scheduler_return_job_to_user(struct mali_pp_job *job)
+{
+ _mali_osk_notification_t *notobj = _mali_osk_notification_create(_MALI_NOTIFICATION_PP_FINISHED, sizeof(_mali_uk_pp_job_finished_s));
+ if (NULL != notobj)
+ {
+ u32 i;
+ u32 sub_jobs = mali_pp_job_get_sub_job_count(job);
+ mali_bool success = mali_pp_job_was_success(job);
+
+ _mali_uk_pp_job_finished_s *jobres = notobj->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;
+ }
+
+ for (i = 0; i < sub_jobs; 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), notobj);
+ }
+ else
+ {
+ MALI_PRINT_ERROR(("Mali PP scheduler: Unable to allocate notification object\n"));
+ }
+
+ mali_pp_job_delete(job);
+}
+
+void mali_pp_scheduler_do_schedule(void)
+{
+ mali_pp_scheduler_lock();
+
+ mali_pp_scheduler_schedule();
+
+ mali_pp_scheduler_unlock();
+}
+
+void mali_pp_scheduler_job_done(struct mali_group *group, struct mali_pp_job *job, u32 sub_job, mali_bool success)
+{
+ u32 i;
+ mali_bool job_is_done;
+
+ MALI_DEBUG_PRINT(3, ("Mali PP scheduler: Job %u (0x%08X) part %u/%u completed (%s)\n", mali_pp_job_get_id(job), job, sub_job + 1, mali_pp_job_get_sub_job_count(job), success ? "success" : "failure"));
+
+ mali_pp_scheduler_lock();
+
+ /* Find slot which was running this job */
+ for (i = 0; i < num_slots; i++)
+ {
+ if (slots[i].group == group)
+ {
+ MALI_DEBUG_ASSERT(MALI_PP_SLOT_STATE_WORKING == slots[i].state);
+ slots[i].state = MALI_PP_SLOT_STATE_IDLE;
+ num_slots_idle++;
+ mali_pp_job_mark_sub_job_completed(job, success);
+ }
+ }
+
+ /* 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.
+ */
+ _mali_osk_wait_queue_wake_up(pp_scheduler_working_wait_queue);
+ }
+ else
+ {
+ mali_pp_scheduler_schedule();
+ }
+
+ job_is_done = mali_pp_job_is_complete(job);
+
+ mali_pp_scheduler_unlock();
+
+ if (job_is_done)
+ {
+ /* Send notification back to user space */
+ MALI_DEBUG_PRINT(4, ("Mali PP scheduler: All parts completed for job %u (0x%08X)\n", mali_pp_job_get_id(job), job));
+ mali_pp_scheduler_return_job_to_user(job);
+ }
+}
+
+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();
+
+ /*mali_pp_scheduler_working_lock();*/
+ /* We have now aquired the working lock, which means that we have successfully paused the scheduler */
+ /*mali_pp_scheduler_working_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) */
+ if (0 == pause_count)
+ {
+ mali_pp_scheduler_schedule();
+ }
+ mali_pp_scheduler_unlock();
+}
+
+_mali_osk_errcode_t _mali_ukk_pp_start_job(_mali_uk_pp_start_job_s *args)
+{
+ struct mali_session_data *session;
+ struct mali_pp_job *job;
+
+ MALI_DEBUG_ASSERT_POINTER(args);
+ MALI_DEBUG_ASSERT_POINTER(args->ctx);
+
+ session = (struct mali_session_data*)args->ctx;
+
+ job = mali_pp_job_create(session, args, mali_scheduler_get_new_id());
+ if (NULL == job)
+ {
+ 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); /* This will also delete the job object */
+ return _MALI_OSK_ERR_OK; /* User is notified via a notification, so this call is ok */
+ }
+
+ mali_pp_scheduler_lock();
+
+ _mali_osk_list_addtail(&job->list, &job_queue);
+
+ MALI_DEBUG_PRINT(3, ("Mali PP scheduler: Job %u (0x%08X) with %u parts queued\n", mali_pp_job_get_id(job), job, mali_pp_job_get_sub_job_count(job)));
+
+ mali_pp_scheduler_schedule();
+
+ mali_pp_scheduler_unlock();
+
+ 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_cores = num_slots;
+ return _MALI_OSK_ERR_OK;
+}
+
+_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;
+
+ mali_pp_scheduler_lock();
+
+ /* Check queue for jobs that match */
+ _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;
+ int i;
+
+ mali_pp_scheduler_lock();
+ MALI_DEBUG_PRINT(3, ("Mali PP 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_pp_job, list)
+ {
+ if (mali_pp_job_get_session(job) == session)
+ {
+ _mali_osk_list_del(&(job->list));
+
+ if ( mali_pp_job_is_currently_rendering_and_if_so_abort_new_starts(job) )
+ {
+ /* The job is in the render pipeline, we can not delete it yet. */
+ /* It will be deleted in the mali_group_abort_session() call below */
+ MALI_DEBUG_PRINT(4, ("Mali PP scheduler: Keeping partially started PP job 0x%08x in queue\n", job));
+ continue;
+ }
+ MALI_DEBUG_PRINT(4, ("Mali PP scheduler: Removing PP job 0x%08x from queue\n", job));
+ mali_pp_job_delete(job);
+ }
+ }
+
+ mali_pp_scheduler_unlock();
+
+ /* Abort running jobs from this session */
+ for (i = 0; i < num_slots; i++)
+ {
+ struct mali_group *group = slots[i].group;
+
+ MALI_DEBUG_PRINT(5, ("PP sched abort: Looking at group 0x%08x\n", group));
+
+ if (MALI_PP_SLOT_STATE_WORKING == slots[i].state)
+ {
+ MALI_DEBUG_PRINT(4, ("Mali PP scheduler: Aborting session 0x%08x from group 0x%08x\n", session, group));
+
+ mali_group_abort_session(group, session);
+ }
+ }
+}
+
+static mali_bool mali_pp_scheduler_is_suspended(void)
+{
+ mali_bool ret;
+
+ mali_pp_scheduler_lock();
+ ret = pause_count > 0 && num_slots == num_slots_idle;
+ mali_pp_scheduler_unlock();
+
+ return ret;
+}
+
+#if MALI_STATE_TRACKING
+u32 mali_pp_scheduler_dump_state(char *buf, u32 size)
+{
+ int n = 0;
+ int i;
+
+ 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");
+
+ for (i = 0; i < num_slots; i++)
+ {
+ n += mali_group_dump_state(slots[i].group, buf + n, size - n);
+ n += _mali_osk_snprintf(buf + n, size - n, "\t\tState: %d\n", slots[i].state);
+ }
+
+ return n;
+}
+#endif
diff --git a/drivers/media/video/samsung/mali/common/mali_pp_scheduler.h b/drivers/media/video/samsung/mali/common/mali_pp_scheduler.h
new file mode 100644
index 0000000..48eb3bd
--- /dev/null
+++ b/drivers/media/video/samsung/mali/common/mali_pp_scheduler.h
@@ -0,0 +1,38 @@
+/*
+ * 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_cluster.h"
+#include "mali_pp_job.h"
+
+_mali_osk_errcode_t mali_pp_scheduler_initialize(void);
+void mali_pp_scheduler_terminate(void);
+
+void mali_pp_scheduler_do_schedule(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);
+
+u32 mali_pp_scheduler_dump_state(char *buf, u32 size);
+
+#endif /* __MALI_PP_SCHEDULER_H__ */
diff --git a/drivers/media/video/samsung/mali/common/mali_scheduler.c b/drivers/media/video/samsung/mali/common/mali_scheduler.c
new file mode 100644
index 0000000..52159a0
--- /dev/null
+++ b/drivers/media/video/samsung/mali/common/mali_scheduler.c
@@ -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.
+ */
+
+#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/media/video/samsung/mali/common/mali_kernel_mem.h b/drivers/media/video/samsung/mali/common/mali_scheduler.h
index 8caafe3..74f0947 100644
--- a/drivers/media/video/samsung/mali/common/mali_kernel_mem.h
+++ b/drivers/media/video/samsung/mali/common/mali_scheduler.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 ARM Limited. All rights reserved.
+ * 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.
@@ -8,10 +8,14 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __MALI_KERNEL_MEM_H__
-#define __MALI_KERNEL_MEM_H__
+#ifndef __MALI_SCHEDULER_H__
+#define __MALI_SCHEDULER_H__
-#include "mali_kernel_subsystem.h"
-extern struct mali_kernel_subsystem mali_subsystem_memory;
+#include "mali_osk.h"
-#endif /* __MALI_KERNEL_MEM_H__ */
+_mali_osk_errcode_t mali_scheduler_initialize(void);
+void mali_scheduler_terminate(void);
+
+u32 mali_scheduler_get_new_id(void);
+
+#endif /* __MALI_SCHEDULER_H__ */
diff --git a/drivers/media/video/samsung/mali/common/mali_session.c b/drivers/media/video/samsung/mali/common/mali_session.c
new file mode 100644
index 0000000..2394bb9
--- /dev/null
+++ b/drivers/media/video/samsung/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/media/video/samsung/mali/common/mali_session.h b/drivers/media/video/samsung/mali/common/mali_session.h
new file mode 100644
index 0000000..b47c340
--- /dev/null
+++ b/drivers/media/video/samsung/mali/common/mali_session.h
@@ -0,0 +1,65 @@
+/*
+ * 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;
+
+ _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_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/media/video/samsung/mali/common/mali_ukk.h b/drivers/media/video/samsung/mali/common/mali_ukk.h
index 94efdf5..8ff2002 100644
--- a/drivers/media/video/samsung/mali/common/mali_ukk.h
+++ b/drivers/media/video/samsung/mali/common/mali_ukk.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 ARM Limited. All rights reserved.
+ * 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.
@@ -17,7 +17,7 @@
#define __MALI_UKK_H__
#include "mali_osk.h"
-#include "mali_uk_types.h"
+#include "../linux/mali_uk_types.h"
#ifdef __cplusplus
extern "C"
@@ -139,14 +139,6 @@ extern "C"
* (_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
- * - On OS systems (not including direct function call U/K interface
- * implementations), _mali_ukk_get_big_block() may succeed, but the subsequent
- * copying to user space may fail.
- * - A problem scenario exists: some memory has been reserved by
- * _mali_ukk_get_big_block(), but the user-mode will be unaware of it (it will
- * never receive any information about this memory). In this case, the U/K
- * implementation must do everything necessary to 'rollback' the \em atomic
- * _mali_ukk_get_big_block() transaction.
* - 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.
@@ -233,7 +225,7 @@ _mali_osk_errcode_t _mali_ukk_close( void **context );
* allocated, and a pointer to this memory written into the system_info member
* of _mali_uk_get_system_info_s.
*
- * @param args see _mali_uk_get_system_info_size_s in "mali_uk_types.h"
+ * @param args see _mali_uk_get_system_info_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_get_system_info_size( _mali_uk_get_system_info_size_s *args );
@@ -270,7 +262,7 @@ _mali_osk_errcode_t _mali_ukk_get_system_info_size( _mali_uk_get_system_info_siz
* destination address for pointer-patching to occur. When NULL, it is unused, an no pointer-patching occurs in the
* common code.
*
- * @param args see _mali_uk_get_system_info_s in "mali_uk_types.h"
+ * @param args see _mali_uk_get_system_info_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_system_info( _mali_uk_get_system_info_s *args );
@@ -279,24 +271,37 @@ _mali_osk_errcode_t _mali_ukk_get_system_info( _mali_uk_get_system_info_s *args
*
* Sleeps until notified or a timeout occurs. Returns information about the notification.
*
- * @param args see _mali_uk_wait_for_notification_s in "mali_uk_types.h"
+ * @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_uk_types.h"
+ * @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_uk_types.h"
+ * @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 */
@@ -324,7 +329,7 @@ _mali_osk_errcode_t _mali_ukk_get_api_version( _mali_uk_get_api_version_s *args
* @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_uk_types.h
+ * @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.
*/
@@ -340,43 +345,18 @@ _mali_osk_errcode_t _mali_ukk_init_mem( _mali_uk_init_mem_s *args );
* @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_uk_types.h
+ * @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 a block of memory into the current user process
- *
- * Allocates a minimum of minimum_size_requested bytes of MALI memory and maps it into the current
- * process space. The number of bytes allocated is returned in args->block_size.
- *
- * This is only used for Mali-nonMMU mode.
- *
- * @param args see _mali_uk_get_big_block_s in "mali_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_big_block( _mali_uk_get_big_block_s *args );
-
-/** @brief Unmap a block of memory from the current user process
- *
- * Frees allocated MALI memory and unmaps it from the current process space. The previously allocated memory
- * is indicated by the cookie as returned by _mali_ukk_get_big_block().
- *
- * This is only used for Mali-nonMMU mode.
- *
- * @param args see _mali_uk_free_big_block_s in "mali_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_free_big_block( _mali_uk_free_big_block_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. In Mali-nonMMU mode, the function is callable
- * from the kernel side, and is used to implement _mali_ukk_get_big_block() in this case.
+ * 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:
@@ -392,9 +372,6 @@ _mali_osk_errcode_t _mali_ukk_free_big_block( _mali_uk_free_big_block_s *args );
* they are unnecsessary; the \em Mali-virtual address range must be used for
* programming Mali structures.
*
- * This means that in the first (nonMMU) case, the caller must manage the physical address allocations. The caller
- * in this case is _mali_ukk_get_big_block(), which does indeed manage the Mali physical address ranges.
- *
* 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.
@@ -403,7 +380,7 @@ _mali_osk_errcode_t _mali_ukk_free_big_block( _mali_uk_free_big_block_s *args );
* 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_uk_types.h"
+ * @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 );
@@ -413,42 +390,42 @@ _mali_osk_errcode_t _mali_ukk_mem_mmap( _mali_uk_mem_mmap_s *args );
* 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_uk_types.h"
+ * @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_uk_types.h
+ * @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_uk_types.h
+ * @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 Map a physically contiguous range of memory into Mali
- * @param args see _mali_uk_map_external_mem_s in mali_uk_types.h
+ * @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_uk_types.h
+ * @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 MALI_USE_UNIFIED_MEMORY_PROVIDER != 0
/** @brief Map UMP memory into Mali
- * @param args see _mali_uk_attach_ump_mem_s in mali_uk_types.h
+ * @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_uk_types.h
+ * @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 );
@@ -492,7 +469,7 @@ _mali_osk_errcode_t _mali_ukk_release_ump_mem( _mali_uk_release_ump_mem_s *args
* @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_uk_types.h"
+ * @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 );
@@ -519,20 +496,16 @@ _mali_osk_errcode_t _mali_ukk_va_to_mali_pa( _mali_uk_va_to_mali_pa_s * args );
* existing one returned, otherwise the new job is started and the status field args->status is set to
* _MALI_UK_START_JOB_STARTED.
*
- * If an existing lower priority job is returned, args->returned_user_job_ptr contains a
- * pointer to the returned job and the status field args->status is set to
- * _MALI_UK_START_JOB_STARTED_LOW_PRI_JOB_RETURNED.
- *
* Job completion can be awaited with _mali_ukk_wait_for_notification().
*
- * @param args see _mali_uk_pp_start_job_s in "mali_uk_types.h"
+ * @param args see _mali_uk_pp_start_job_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_pp_start_job( _mali_uk_pp_start_job_s *args );
/** @brief Returns the number of Fragment Processors in the system
*
- * @param args see _mali_uk_get_pp_number_of_cores_s in "mali_uk_types.h"
+ * @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 );
@@ -542,22 +515,18 @@ _mali_osk_errcode_t _mali_ukk_get_pp_number_of_cores( _mali_uk_get_pp_number_of_
* 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_uk_types.h"
+ * @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 Abort any PP jobs with the given ID.
+/** @brief Disable Write-back unit(s) on specified job
*
- * Jobs internally queued or currently running on the hardware is to be stopped/aborted.
- * Jobs aborted are reported via the normal job completion system.
- * Any jobs, running or internally queued should be aborted imediately.
- * Normal notifiction procedures to report on the status of these jobs.
- *
- *
- * @param args see _malu_uk_pp_abort_job_s in "mali_uk_types.h"
+ * @param args see _mali_uk_get_pp_core_version_s in "mali_utgard_uk_types.h"
*/
-void _mali_ukk_pp_abort_job( _mali_uk_pp_abort_job_s *args );
+void _mali_ukk_pp_job_disable_wb(_mali_uk_pp_disable_wb_s *args);
+
+
/** @} */ /* end group _mali_uk_pp */
@@ -580,20 +549,16 @@ void _mali_ukk_pp_abort_job( _mali_uk_pp_abort_job_s *args );
* existing one returned, otherwise the new job is started and the status field args->status is set to
* _MALI_UK_START_JOB_STARTED.
*
- * If an existing lower priority job is returned, args->returned_user_job_ptr contains a pointer to
- * the returned job and the status field args->status is set to
- * _MALI_UK_START_JOB_STARTED_LOW_PRI_JOB_RETURNED.
- *
* Job completion can be awaited with _mali_ukk_wait_for_notification().
*
- * @param args see _mali_uk_gp_start_job_s in "mali_uk_types.h"
+ * @param args see _mali_uk_gp_start_job_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_start_job( _mali_uk_gp_start_job_s *args );
/** @brief Returns the number of Vertex Processors in the system.
*
- * @param args see _mali_uk_get_gp_number_of_cores_s in "mali_uk_types.h"
+ * @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 );
@@ -603,7 +568,7 @@ _mali_osk_errcode_t _mali_ukk_get_gp_number_of_cores( _mali_uk_get_gp_number_of_
* 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_uk_types.h"
+ * @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 );
@@ -613,85 +578,47 @@ _mali_osk_errcode_t _mali_ukk_get_gp_core_version( _mali_uk_get_gp_core_version_
* 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_uk_types.h"
+ * @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 );
-/** @brief Abort any GP jobs with the given ID.
- *
- * Jobs internally queued or currently running on the hardware is to be stopped/aborted.
- * Jobs aborted are reported via the normal job completion system.
- *
- * Any jobs, running or internally queued should be aborted imediately.
- * Normal notifiction procedures to report on the status of these jobs.
- *
- * @param args see _mali_uk_gp_abort_job_s in "mali_uk_types.h"
- */
-void _mali_ukk_gp_abort_job( _mali_uk_gp_abort_job_s *args );
/** @} */ /* end group _mali_uk_gp */
-#if USING_MALI_PMM
-/** @addtogroup _mali_uk_pmm U/K Power Management Module
- * @{ */
-
-/* @brief Power Management Module event message
- *
- * @note The event message can fail to be sent due to OOM but this is
- * stored in the PMM state machine to be handled later
- *
- * @param args see _mali_uk_pmm_event_message_s in "mali_uk_types.h"
- */
-void _mali_ukk_pmm_event_message( _mali_uk_pmm_message_s *args );
-/** @} */ /* end group _mali_uk_pmm */
-#endif /* USING_MALI_PMM */
-
#if MALI_TIMELINE_PROFILING_ENABLED
/** @addtogroup _mali_uk_profiling U/K Timeline profiling module
* @{ */
/** @brief Start recording profiling events.
*
- * @param args see _mali_uk_profiling_start_s in "mali_uk_types.h"
+ * @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_uk_types.h"
+ * @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_uk_types.h"
+ * @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_uk_types.h"
+ * @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_uk_types.h"
+ * @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);
-/** @brief Get the profiling config applicable for calling process.
- *
- * @param args see _mali_uk_profiling_get_config_s in "mali_uk_types.h"
- */
-_mali_osk_errcode_t _mali_ukk_profiling_get_config(_mali_uk_profiling_get_config_s *args);
-
-/** @brief Transfer software counters from user to kernel space
- *
- * @param args see _mali_uk_transfer_sw_counters_s in "mali_uk_types.h"
- */
-_mali_osk_errcode_t _mali_ukk_transfer_sw_counters(_mali_uk_sw_counters_s *args);
-
/** @} */ /* end group _mali_uk_profiling */
#endif
@@ -704,12 +631,23 @@ _mali_osk_errcode_t _mali_ukk_transfer_sw_counters(_mali_uk_sw_counters_s *args)
* 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_uk_types.h"
+ * @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 */
diff --git a/drivers/media/video/samsung/mali/common/mali_user_settings_db.c b/drivers/media/video/samsung/mali/common/mali_user_settings_db.c
new file mode 100644
index 0000000..681c2b0
--- /dev/null
+++ b/drivers/media/video/samsung/mali/common/mali_user_settings_db.c
@@ -0,0 +1,88 @@
+/**
+ * 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;
+
+ MALI_DEBUG_ASSERT(setting < _MALI_UK_USER_SETTING_MAX && setting >= 0);
+
+ 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)
+{
+ MALI_DEBUG_ASSERT(setting < _MALI_UK_USER_SETTING_MAX && setting >= 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(u32) * _MALI_UK_USER_SETTING_MAX));
+
+ return _MALI_OSK_ERR_OK;
+}
diff --git a/drivers/media/video/samsung/mali/common/mali_user_settings_db.h b/drivers/media/video/samsung/mali/common/mali_user_settings_db.h
new file mode 100644
index 0000000..fbb9415
--- /dev/null
+++ b/drivers/media/video/samsung/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/media/video/samsung/mali/common/pmm/mali_pmm.c b/drivers/media/video/samsung/mali/common/pmm/mali_pmm.c
deleted file mode 100644
index 7041391..0000000
--- a/drivers/media/video/samsung/mali/common/pmm/mali_pmm.c
+++ /dev/null
@@ -1,1024 +0,0 @@
-/*
- * 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_pmm.c
- * Implementation of the power management module for the kernel device driver
- */
-
-#if USING_MALI_PMM
-
-#include "mali_ukk.h"
-#include "mali_kernel_common.h"
-#include "mali_kernel_subsystem.h"
-
-#include "mali_pmm.h"
-#include "mali_pmm_system.h"
-#include "mali_pmm_state.h"
-#include "mali_pmm_policy.h"
-#include "mali_pmm_pmu.h"
-#include "mali_platform.h"
-#include "mali_kernel_pm.h"
-
-/* Internal PMM subsystem state */
-static _mali_pmm_internal_state_t *pmm_state = NULL;
-/* Mali kernel subsystem id */
-static mali_kernel_subsystem_identifier mali_subsystem_pmm_id = -1;
-
-#define GET_PMM_STATE_PTR (pmm_state)
-
-/* Internal functions */
-static _mali_osk_errcode_t malipmm_create(_mali_osk_resource_t *resource);
-static void pmm_event_process( void );
-_mali_osk_errcode_t malipmm_irq_uhandler(void *data);
-void malipmm_irq_bhandler(void *data);
-
-/** @brief Start the PMM subsystem
- *
- * @param id Subsystem id to uniquely identify this subsystem
- * @return _MALI_OSK_ERR_OK if the system started successfully, or a suitable
- * _mali_osk_errcode_t otherwise.
- */
-_mali_osk_errcode_t malipmm_kernel_subsystem_start( mali_kernel_subsystem_identifier id );
-
-/** @brief Perform post start up of the PMM subsystem
- *
- * Post start up includes initializing the current policy, now that the system is
- * completely started - to stop policies turning off hardware during the start up
- *
- * @param id the unique subsystem id
- * @return _MALI_OSK_ERR_OK if the post startup was successful, or a suitable
- * _mali_osk_errcode_t otherwise.
- */
-_mali_osk_errcode_t malipmm_kernel_load_complete( mali_kernel_subsystem_identifier id );
-
-/** @brief Terminate the PMM subsystem
- *
- * @param id the unique subsystem id
- */
-void malipmm_kernel_subsystem_terminate( mali_kernel_subsystem_identifier id );
-
-#if MALI_STATE_TRACKING
-u32 malipmm_subsystem_dump_state( char *buf, u32 size );
-#endif
-
-
-/* This will be one of the subsystems in the array of subsystems:
- static struct mali_kernel_subsystem * subsystems[];
- found in file: mali_kernel_core.c
-*/
-struct mali_kernel_subsystem mali_subsystem_pmm=
-{
- malipmm_kernel_subsystem_start, /* startup */
- NULL, /*malipmm_kernel_subsystem_terminate,*/ /* shutdown */
- malipmm_kernel_load_complete, /* loaded all subsystems */
- NULL,
- NULL,
- NULL,
- NULL,
-#if MALI_STATE_TRACKING
- malipmm_subsystem_dump_state, /* dump_state */
-#endif
-};
-
-#if PMM_OS_TEST
-
-u32 power_test_event = 0;
-mali_bool power_test_flag = MALI_FALSE;
-_mali_osk_timer_t *power_test_timer = NULL;
-
-void _mali_osk_pmm_power_up_done(mali_pmm_message_data data)
-{
- MALI_PRINT(("POWER TEST OS UP DONE\n"));
-}
-
-void _mali_osk_pmm_power_down_done(mali_pmm_message_data data)
-{
- MALI_PRINT(("POWER TEST OS DOWN DONE\n"));
-}
-
-/**
- * Symbian OS Power Up call to the driver
- */
-void power_test_callback( void *arg )
-{
- _mali_pmm_internal_state_t *pmm = GET_PMM_STATE_PTR;
- MALI_DEBUG_ASSERT_POINTER(pmm);
-
- power_test_flag = MALI_TRUE;
- _mali_osk_irq_schedulework( pmm->irq );
-}
-
-void power_test_start()
-{
- power_test_timer = _mali_osk_timer_init();
- _mali_osk_timer_setcallback( power_test_timer, power_test_callback, NULL );
-
- /* First event is power down */
- power_test_event = MALI_PMM_EVENT_OS_POWER_DOWN;
- _mali_osk_timer_add( power_test_timer, 10000 );
-}
-
-mali_bool power_test_check()
-{
- if( power_test_flag )
- {
- _mali_uk_pmm_message_s event = {
- NULL,
- 0,
- 1 };
- event.id = power_test_event;
-
- power_test_flag = MALI_FALSE;
-
- /* Send event */
- _mali_ukk_pmm_event_message( &event );
-
- /* Switch to next event to test */
- if( power_test_event == MALI_PMM_EVENT_OS_POWER_DOWN )
- {
- power_test_event = MALI_PMM_EVENT_OS_POWER_UP;
- }
- else
- {
- power_test_event = MALI_PMM_EVENT_OS_POWER_DOWN;
- }
- _mali_osk_timer_add( power_test_timer, 5000 );
-
- return MALI_TRUE;
- }
-
- return MALI_FALSE;
-}
-
-void power_test_end()
-{
- _mali_osk_timer_del( power_test_timer );
- _mali_osk_timer_term( power_test_timer );
- power_test_timer = NULL;
-}
-
-#endif
-
-void _mali_ukk_pmm_event_message( _mali_uk_pmm_message_s *args )
-{
- _mali_pmm_internal_state_t *pmm = GET_PMM_STATE_PTR;
- _mali_osk_notification_t *msg;
- mali_pmm_message_t *event;
- MALI_DEBUG_ASSERT_POINTER(pmm);
- MALI_DEBUG_ASSERT_POINTER(args);
-
- MALIPMM_DEBUG_PRINT( ("PMM: sending message\n") );
-
-#if MALI_PMM_TRACE && MALI_PMM_TRACE_SENT_EVENTS
- _mali_pmm_trace_event_message( args, MALI_FALSE );
-#endif
-
- msg = _mali_osk_notification_create( MALI_PMM_NOTIFICATION_TYPE, sizeof( mali_pmm_message_t ) );
-
- if( msg )
- {
- event = (mali_pmm_message_t *)msg->result_buffer;
- event->id = args->id;
- event->ts = _mali_osk_time_tickcount();
- event->data = args->data;
-
- _mali_osk_atomic_inc( &(pmm->messages_queued) );
-
- if( args->id > MALI_PMM_EVENT_INTERNALS )
- {
- /* Internal PMM message */
- _mali_osk_notification_queue_send( pmm->iqueue, msg );
- #if (MALI_PMM_TRACE || MALI_STATE_TRACKING)
- pmm->imessages_sent++;
- #endif
- }
- else
- {
- /* Real event */
- _mali_osk_notification_queue_send( pmm->queue, msg );
- #if (MALI_PMM_TRACE || MALI_STATE_TRACKING)
- pmm->messages_sent++;
- #endif
- }
- }
- else
- {
- MALI_PRINT_ERROR( ("PMM: Could not send message %d", args->id) );
- /* Make note of this OOM - which has caused a missed event */
- pmm->missed++;
- }
-
- /* Schedule time to look at the event or the fact we couldn't create an event */
- _mali_osk_irq_schedulework( pmm->irq );
-}
-
-mali_pmm_state _mali_pmm_state( void )
-{
- _mali_pmm_internal_state_t *pmm = GET_PMM_STATE_PTR;
- MALI_DEBUG_ASSERT_POINTER(pmm);
-
- if( pmm && (mali_subsystem_pmm_id != -1) )
- {
- return pmm->state;
- }
-
- /* No working subsystem yet */
- return MALI_PMM_STATE_UNAVAILABLE;
-}
-
-
-mali_pmm_core_mask _mali_pmm_cores_list( void )
-{
- _mali_pmm_internal_state_t *pmm = GET_PMM_STATE_PTR;
- MALI_DEBUG_ASSERT_POINTER(pmm);
-
- return pmm->cores_registered;
-}
-
-mali_pmm_core_mask _mali_pmm_cores_powered( void )
-{
- _mali_pmm_internal_state_t *pmm = GET_PMM_STATE_PTR;
- MALI_DEBUG_ASSERT_POINTER(pmm);
-
- return pmm->cores_powered;
-}
-
-
-_mali_osk_errcode_t _mali_pmm_list_policies(
- u32 policy_list_size,
- mali_pmm_policy *policy_list,
- u32 *policies_available )
-{
- /* TBD - This is currently a stub function for basic power management */
-
- MALI_ERROR( _MALI_OSK_ERR_UNSUPPORTED );
-}
-
-_mali_osk_errcode_t _mali_pmm_set_policy( mali_pmm_policy policy )
-{
- /* TBD - This is currently a stub function for basic power management */
-
-/* TBD - When this is not a stub... include tracing...
-#if MALI_PMM_TRACE
- _mali_pmm_trace_policy_change( old, newpolicy );
-#endif
-*/
- MALI_ERROR( _MALI_OSK_ERR_UNSUPPORTED );
-}
-
-_mali_osk_errcode_t _mali_pmm_get_policy( mali_pmm_policy *policy )
-{
- if( policy )
- {
- _mali_pmm_internal_state_t *pmm = GET_PMM_STATE_PTR;
- MALI_DEBUG_ASSERT_POINTER(pmm);
-
- if( pmm )
- {
- *policy = pmm->policy;
- MALI_SUCCESS;
- }
- else
- {
- *policy = MALI_PMM_POLICY_NONE;
- MALI_ERROR( _MALI_OSK_ERR_FAULT );
- }
- }
-
- /* No return argument */
- MALI_ERROR( _MALI_OSK_ERR_INVALID_ARGS );
-}
-
-#if ( MALI_PMM_TRACE || MALI_STATE_TRACKING )
-
-/* Event names - order must match mali_pmm_event_id enum */
-static char *pmm_trace_events[] = {
- "OS_POWER_UP",
- "OS_POWER_DOWN",
- "JOB_SCHEDULED",
- "JOB_QUEUED",
- "JOB_FINISHED",
- "TIMEOUT",
-};
-
-/* State names - order must match mali_pmm_state enum */
-static char *pmm_trace_state[] = {
- "UNAVAILABLE",
- "SYSTEM ON",
- "SYSTEM OFF",
- "SYSTEM TRANSITION",
-};
-
-/* Policy names - order must match mali_pmm_policy enum */
-static char *pmm_trace_policy[] = {
- "NONE",
- "ALWAYS ON",
- "JOB CONTROL",
-};
-
-/* Status names - order must match mali_pmm_status enum */
-static char *pmm_trace_status[] = {
- "MALI_PMM_STATUS_IDLE", /**< PMM is waiting next event */
- "MALI_PMM_STATUS_POLICY_POWER_DOWN", /**< Policy initiated power down */
- "MALI_PMM_STATUS_POLICY_POWER_UP", /**< Policy initiated power down */
- "MALI_PMM_STATUS_OS_WAITING", /**< PMM is waiting for OS power up */
- "MALI_PMM_STATUS_OS_POWER_DOWN", /**< OS initiated power down */
- "MALI_PMM_STATUS_RUNTIME_IDLE_IN_PROGRESS",
- "MALI_PMM_STATUS_DVFS_PAUSE", /**< PMM DVFS Status Pause */
- "MALI_PMM_STATUS_OS_POWER_UP", /**< OS initiated power up */
- "MALI_PMM_STATUS_OFF", /**< PMM is not active */
-};
-
-#endif /* MALI_PMM_TRACE || MALI_STATE_TRACKING */
-#if MALI_PMM_TRACE
-
-/* UK event names - order must match mali_pmm_event_id enum */
-static char *pmm_trace_events_uk[] = {
- "UKS",
- "UK_EXAMPLE",
-};
-
-/* Internal event names - order must match mali_pmm_event_id enum */
-static char *pmm_trace_events_internal[] = {
- "INTERNALS",
- "INTERNAL_POWER_UP_ACK",
- "INTERNAL_POWER_DOWN_ACK",
-};
-
-void _mali_pmm_trace_hardware_change( mali_pmm_core_mask old, mali_pmm_core_mask newstate )
-{
- const char *dname;
- const char *cname;
- const char *ename;
-
- if( old != newstate )
- {
- if( newstate == 0 )
- {
- dname = "NO cores";
- }
- else
- {
- dname = pmm_trace_get_core_name( newstate );
- }
-
- /* These state checks only work if the assumption that only cores can be
- * turned on or turned off in seperate actions is true. If core power states can
- * be toggled (some one, some off) at the same time, this check does not work
- */
- if( old > newstate )
- {
- /* Cores have turned off */
- cname = pmm_trace_get_core_name( old - newstate );
- ename = "OFF";
- }
- else
- {
- /* Cores have turned on */
- cname = pmm_trace_get_core_name( newstate - old );
- ename = "ON";
- }
- MALI_PRINT( ("PMM Trace: Hardware %s ON, %s just turned %s. { 0x%08x -> 0x%08x }", dname, cname, ename, old, newstate) );
- }
-}
-
-void _mali_pmm_trace_state_change( mali_pmm_state old, mali_pmm_state newstate )
-{
- if( old != newstate )
- {
- MALI_PRINT( ("PMM Trace: State changed from %s to %s", pmm_trace_state[old], pmm_trace_state[newstate]) );
- }
-}
-
-void _mali_pmm_trace_policy_change( mali_pmm_policy old, mali_pmm_policy newpolicy )
-{
- if( old != newpolicy )
- {
- MALI_PRINT( ("PMM Trace: Policy changed from %s to %s", pmm_trace_policy[old], pmm_trace_policy[newpolicy]) );
- }
-}
-
-void _mali_pmm_trace_event_message( mali_pmm_message_t *event, mali_bool received )
-{
- const char *ename;
- const char *dname;
- const char *tname;
- const char *format = "PMM Trace: Event %s { (%d) %s, %d ticks, (0x%x) %s }";
-
- MALI_DEBUG_ASSERT_POINTER(event);
-
- tname = (received) ? "received" : "sent";
-
- if( event->id >= MALI_PMM_EVENT_INTERNALS )
- {
- ename = pmm_trace_events_internal[((int)event->id) - MALI_PMM_EVENT_INTERNALS];
- }
- else if( event->id >= MALI_PMM_EVENT_UKS )
- {
- ename = pmm_trace_events_uk[((int)event->id) - MALI_PMM_EVENT_UKS];
- }
- else
- {
- ename = pmm_trace_events[event->id];
- }
-
- switch( event->id )
- {
- case MALI_PMM_EVENT_OS_POWER_UP:
- case MALI_PMM_EVENT_OS_POWER_DOWN:
- dname = "os event";
- break;
-
- case MALI_PMM_EVENT_JOB_SCHEDULED:
- case MALI_PMM_EVENT_JOB_QUEUED:
- case MALI_PMM_EVENT_JOB_FINISHED:
- case MALI_PMM_EVENT_INTERNAL_POWER_UP_ACK:
- case MALI_PMM_EVENT_INTERNAL_POWER_DOWN_ACK:
- dname = pmm_trace_get_core_name( (mali_pmm_core_mask)event->data );
- break;
-
- case MALI_PMM_EVENT_TIMEOUT:
- dname = "timeout start";
- /* Print data with a different format */
- format = "PMM Trace: Event %s { (%d) %s, %d ticks, %d ticks %s }";
- break;
- default:
- dname = "unknown data";
- }
-
- MALI_PRINT( (format, tname, (u32)event->id, ename, event->ts, (u32)event->data, dname) );
-}
-
-#endif /* MALI_PMM_TRACE */
-
-
-/****************** Mali Kernel API *****************/
-
-_mali_osk_errcode_t malipmm_kernel_subsystem_start( mali_kernel_subsystem_identifier id )
-{
- mali_subsystem_pmm_id = id;
- MALI_CHECK_NO_ERROR(_mali_kernel_core_register_resource_handler(PMU, malipmm_create));
- MALI_SUCCESS;
-}
-
-_mali_osk_errcode_t malipmm_create(_mali_osk_resource_t *resource)
-{
- /* Create PMM state memory */
- MALI_DEBUG_ASSERT( pmm_state == NULL );
- pmm_state = (_mali_pmm_internal_state_t *) _mali_osk_malloc(sizeof(*pmm_state));
- MALI_CHECK_NON_NULL( pmm_state, _MALI_OSK_ERR_NOMEM );
-
- /* All values get 0 as default */
- _mali_osk_memset(pmm_state, 0, sizeof(*pmm_state));
-
- /* Set up the initial PMM state */
- pmm_state->waiting = 0;
- pmm_state->status = MALI_PMM_STATUS_IDLE;
- pmm_state->state = MALI_PMM_STATE_UNAVAILABLE; /* Until a core registers */
-
- /* Set up policy via compile time option for the moment */
-#if MALI_PMM_ALWAYS_ON
- pmm_state->policy = MALI_PMM_POLICY_ALWAYS_ON;
-#else
- pmm_state->policy = MALI_PMM_POLICY_JOB_CONTROL;
-#endif
-
-#if MALI_PMM_TRACE
- _mali_pmm_trace_policy_change( MALI_PMM_POLICY_NONE, pmm_state->policy );
-#endif
-
- /* Set up assumes all values are initialized to NULL or MALI_FALSE, so
- * we can exit halfway through set up and perform clean up
- */
-
-#if USING_MALI_PMU
- if( mali_pmm_pmu_init(resource) != _MALI_OSK_ERR_OK ) goto pmm_fail_cleanup;
- pmm_state->pmu_initialized = MALI_TRUE;
-#endif
- pmm_state->queue = _mali_osk_notification_queue_init();
- if( !pmm_state->queue ) goto pmm_fail_cleanup;
-
- pmm_state->iqueue = _mali_osk_notification_queue_init();
- if( !pmm_state->iqueue ) goto pmm_fail_cleanup;
-
- /* We are creating an IRQ handler just for the worker thread it gives us */
- pmm_state->irq = _mali_osk_irq_init( _MALI_OSK_IRQ_NUMBER_PMM,
- malipmm_irq_uhandler,
- malipmm_irq_bhandler,
- NULL,
- NULL,
- (void *)pmm_state, /* PMM state is passed to IRQ */
- "PMM handler" );
-
- if( !pmm_state->irq ) goto pmm_fail_cleanup;
-
- pmm_state->lock = _mali_osk_lock_init((_mali_osk_lock_flags_t)(_MALI_OSK_LOCKFLAG_READERWRITER | _MALI_OSK_LOCKFLAG_ORDERED), 0, 75);
- if( !pmm_state->lock ) goto pmm_fail_cleanup;
-
- if( _mali_osk_atomic_init( &(pmm_state->messages_queued), 0 ) != _MALI_OSK_ERR_OK )
- {
- goto pmm_fail_cleanup;
- }
-
- MALIPMM_DEBUG_PRINT( ("PMM: subsystem created, policy=%d\n", pmm_state->policy) );
-
- MALI_SUCCESS;
-
-pmm_fail_cleanup:
- MALI_PRINT_ERROR( ("PMM: subsystem failed to be created\n") );
- if( pmm_state )
- {
- if( pmm_state->lock ) _mali_osk_lock_term( pmm_state->lock );
- if( pmm_state->irq ) _mali_osk_irq_term( pmm_state->irq );
- if( pmm_state->queue ) _mali_osk_notification_queue_term( pmm_state->queue );
- if( pmm_state->iqueue ) _mali_osk_notification_queue_term( pmm_state->iqueue );
-#if USING_MALI_PMU
- if( pmm_state->pmu_initialized )
- {
- _mali_osk_resource_type_t t = PMU;
- mali_pmm_pmu_deinit(&t);
- }
-#endif /* USING_MALI_PMU */
-
- _mali_osk_free(pmm_state);
- pmm_state = NULL;
- }
- MALI_ERROR( _MALI_OSK_ERR_FAULT );
-}
-
-_mali_osk_errcode_t malipmm_kernel_load_complete( mali_kernel_subsystem_identifier id )
-{
- _mali_pmm_internal_state_t *pmm = GET_PMM_STATE_PTR;
- MALI_DEBUG_ASSERT_POINTER(pmm);
-
- MALIPMM_DEBUG_PRINT( ("PMM: subsystem loaded, policy initializing\n") );
-
-#if PMM_OS_TEST
- power_test_start();
-#endif
-
- /* Initialize the profile now the system has loaded - so that cores are
- * not turned off during start up
- */
- return pmm_policy_init( pmm );
-}
-
-void malipmm_force_powerup( void )
-{
- _mali_pmm_internal_state_t *pmm = GET_PMM_STATE_PTR;
- MALI_DEBUG_ASSERT_POINTER(pmm);
- MALI_PMM_LOCK(pmm);
- pmm->status = MALI_PMM_STATUS_OFF;
- MALI_PMM_UNLOCK(pmm);
-
- /* flush PMM workqueue */
- _mali_osk_flush_workqueue( pmm->irq );
-
- if (pmm->cores_powered == 0)
- {
- malipmm_powerup(pmm->cores_registered);
- }
-}
-
-void malipmm_kernel_subsystem_terminate( mali_kernel_subsystem_identifier id )
-{
- /* Check this is the right system */
- MALI_DEBUG_ASSERT( id == mali_subsystem_pmm_id );
- MALI_DEBUG_ASSERT_POINTER(pmm_state);
-
- if( pmm_state )
- {
-#if PMM_OS_TEST
- power_test_end();
-#endif
- /* Get the lock so we can shutdown */
- MALI_PMM_LOCK(pmm_state);
-#if MALI_STATE_TRACKING
- pmm_state->mali_pmm_lock_acquired = 1;
-#endif /* MALI_STATE_TRACKING */
- pmm_state->status = MALI_PMM_STATUS_OFF;
-#if MALI_STATE_TRACKING
- pmm_state->mali_pmm_lock_acquired = 0;
-#endif /* MALI_STATE_TRACKING */
- MALI_PMM_UNLOCK(pmm_state);
- _mali_osk_pmm_ospmm_cleanup();
- pmm_policy_term(pmm_state);
- _mali_osk_irq_term( pmm_state->irq );
- _mali_osk_notification_queue_term( pmm_state->queue );
- _mali_osk_notification_queue_term( pmm_state->iqueue );
- if (pmm_state->cores_registered) malipmm_powerdown(pmm_state->cores_registered,MALI_POWER_MODE_LIGHT_SLEEP);
-#if USING_MALI_PMU
- if( pmm_state->pmu_initialized )
- {
- _mali_osk_resource_type_t t = PMU;
- mali_pmm_pmu_deinit(&t);
- }
-#endif /* USING_MALI_PMU */
-
- _mali_osk_atomic_term( &(pmm_state->messages_queued) );
- MALI_PMM_LOCK_TERM(pmm_state);
- _mali_osk_free(pmm_state);
- pmm_state = NULL;
- }
-
- MALIPMM_DEBUG_PRINT( ("PMM: subsystem terminated\n") );
-}
-
-_mali_osk_errcode_t malipmm_powerup( u32 cores )
-{
- _mali_osk_errcode_t err = _MALI_OSK_ERR_OK;
- _mali_pmm_internal_state_t *pmm = GET_PMM_STATE_PTR;
-
- /* If all the cores are powered down, power up the MALI */
- if (pmm->cores_powered == 0) {
- mali_platform_power_mode_change(MALI_POWER_MODE_ON);
-#if MALI_PMM_RUNTIME_JOB_CONTROL_ON
- /* Initiate the power up */
- if (_mali_osk_pmm_dev_activate() < 0) {
- MALI_PRINT(("PMM: Try again PD_G3D enable\n"));
- if (mali_pd_enable() < 0) {
- MALI_PRINT(("PMM: Mali PMM device activate failed\n"));
- err = _MALI_OSK_ERR_FAULT;
- return err;
- }
- }
-#endif
- }
-
-#if USING_MALI_PMU
- err = mali_pmm_pmu_powerup( cores );
-#endif
-
-#if MALI_PMM_RUNTIME_JOB_CONTROL_ON
- mali_platform_powerup(cores);
-#endif
-
- return err;
-}
-
-_mali_osk_errcode_t malipmm_powerdown( u32 cores, mali_power_mode power_mode )
-{
- _mali_osk_errcode_t err = _MALI_OSK_ERR_OK;
- _mali_pmm_internal_state_t *pmm = GET_PMM_STATE_PTR;
-
-#if MALI_PMM_RUNTIME_JOB_CONTROL_ON
- mali_platform_powerdown(cores);
-#endif
-
-#if USING_MALI_PMU
- err = mali_pmm_pmu_powerdown( cores );
-#endif
-
- /* If all cores are powered down, power off the MALI */
- if (pmm->cores_powered == 0)
- {
-#if MALI_PMM_RUNTIME_JOB_CONTROL_ON
- /* Initiate the power down */
- _mali_osk_pmm_dev_idle();
-#endif
- mali_platform_power_mode_change(power_mode);
- }
- return err;
-}
-
-_mali_osk_errcode_t malipmm_core_register( mali_pmm_core_id core )
-{
- _mali_osk_errcode_t err;
- _mali_pmm_internal_state_t *pmm = GET_PMM_STATE_PTR;
-
- if( pmm == NULL )
- {
- /* PMM state has not been created, this is because the PMU resource has not been
- * created yet.
- * This probably means that the PMU resource has not been specfied as the first
- * resource in the config file
- */
- MALI_PRINT_ERROR( ("PMM: Cannot register core %s because the PMU resource has not been\n initialized. Please make sure the PMU resource is the first resource in the\n resource configuration.\n",
- pmm_trace_get_core_name(core)) );
- MALI_ERROR(_MALI_OSK_ERR_FAULT);
- }
-
- MALI_PMM_LOCK(pmm);
-
-#if MALI_STATE_TRACKING
- pmm->mali_pmm_lock_acquired = 1;
-#endif /* MALI_STATE_TRACKING */
-
-
- /* Check if the core is registered more than once in PMM */
- MALI_DEBUG_ASSERT( (pmm->cores_registered & core) == 0 );
-
- MALIPMM_DEBUG_PRINT( ("PMM: core registered: (0x%x) %s\n", core, pmm_trace_get_core_name(core)) );
-
-#if !MALI_PMM_NO_PMU
- /* Make sure the core is powered up */
- err = malipmm_powerup( core );
-#else
- err = _MALI_OSK_ERR_OK;
-#endif
- if( _MALI_OSK_ERR_OK == err )
- {
-#if MALI_PMM_TRACE
- mali_pmm_core_mask old_power = pmm->cores_powered;
-#endif
- /* Assume a registered core is now powered up and idle */
- pmm->cores_registered |= core;
- pmm->cores_idle |= core;
- pmm->cores_powered |= core;
- pmm_update_system_state( pmm );
-
-#if MALI_PMM_TRACE
- _mali_pmm_trace_hardware_change( old_power, pmm->cores_powered );
-#endif
- }
- else
- {
- MALI_PRINT_ERROR( ("PMM: Error(%d) powering up registered core: (0x%x) %s\n",
- err, core, pmm_trace_get_core_name(core)) );
- }
-
-#if MALI_STATE_TRACKING
- pmm->mali_pmm_lock_acquired = 0;
-#endif /* MALI_STATE_TRACKING */
-
- MALI_PMM_UNLOCK(pmm);
-
- return err;
-}
-
-void malipmm_core_unregister( mali_pmm_core_id core )
-{
- _mali_pmm_internal_state_t *pmm = GET_PMM_STATE_PTR;
- MALI_DEBUG_ASSERT_POINTER(pmm);
-
- MALI_PMM_LOCK(pmm);
-#if MALI_STATE_TRACKING
- pmm->mali_pmm_lock_acquired = 1;
-#endif /* MALI_STATE_TRACKING */
-
-
- /* Check if the core is registered in PMM */
- MALI_PMM_DEBUG_ASSERT_CORES_SUBSET( pmm->cores_registered, core );
-
- MALIPMM_DEBUG_PRINT( ("PMM: core unregistered: (0x%x) %s\n", core, pmm_trace_get_core_name(core)) );
-
- {
-#if MALI_PMM_TRACE
- mali_pmm_core_mask old_power = pmm->cores_powered;
-#endif
-
- /* Remove the core from the system */
- pmm->cores_idle &= (~core);
- pmm->cores_powered &= (~core);
- pmm->cores_pend_down &= (~core);
- pmm->cores_pend_up &= (~core);
- pmm->cores_ack_down &= (~core);
- pmm->cores_ack_up &= (~core);
-
- pmm_update_system_state( pmm );
-
-#if MALI_PMM_TRACE
- _mali_pmm_trace_hardware_change( old_power, pmm->cores_powered );
-#endif
- }
-
-#if MALI_STATE_TRACKING
- pmm->mali_pmm_lock_acquired = 0;
-#endif /* MALI_STATE_TRACKING */
-
- MALI_PMM_UNLOCK(pmm);
-}
-void malipmm_core_power_down_okay( mali_pmm_core_id core )
-{
- _mali_uk_pmm_message_s event = {
- NULL,
- MALI_PMM_EVENT_INTERNAL_POWER_DOWN_ACK,
- 0 };
-
- event.data = core;
-
- _mali_ukk_pmm_event_message( &event );
-}
-
-void malipmm_set_policy_check()
-{
- _mali_pmm_internal_state_t *pmm = GET_PMM_STATE_PTR;
- MALI_DEBUG_ASSERT_POINTER(pmm);
- pmm->check_policy = MALI_TRUE;
-
- /* To check the policy we need to schedule some work */
- _mali_osk_irq_schedulework( pmm->irq );
-}
-
-_mali_osk_errcode_t malipmm_irq_uhandler(void *data)
-{
- MALIPMM_DEBUG_PRINT( ("PMM: uhandler - not expected to be used\n") );
-
- MALI_SUCCESS;
-}
-
-void malipmm_irq_bhandler(void *data)
-{
- _mali_pmm_internal_state_t *pmm;
- pmm = (_mali_pmm_internal_state_t *)data;
- MALI_DEBUG_ASSERT_POINTER(pmm);
-
-#if PMM_OS_TEST
- if( power_test_check() ) return;
-#endif
-
- MALI_PMM_LOCK(pmm);
-#if MALI_STATE_TRACKING
- pmm->mali_pmm_lock_acquired = 1;
-#endif /* MALI_STATE_TRACKING */
-
- /* Quick out when we are shutting down */
- if( pmm->status == MALI_PMM_STATUS_OFF )
- {
-
- #if MALI_STATE_TRACKING
- pmm->mali_pmm_lock_acquired = 0;
- #endif /* MALI_STATE_TRACKING */
-
- MALI_PMM_UNLOCK(pmm);
- return;
- }
-
- MALIPMM_DEBUG_PRINT( ("PMM: bhandler - Processing event\n") );
-
- if( pmm->missed > 0 )
- {
- MALI_PRINT_ERROR( ("PMM: Failed to send %d events", pmm->missed) );
- pmm_fatal_reset( pmm );
- }
-
- if( pmm->check_policy )
- {
- pmm->check_policy = MALI_FALSE;
- pmm_policy_check_policy(pmm);
- }
- else
- {
- /* Perform event processing */
- pmm_event_process();
- if( pmm->fatal_power_err )
- {
- /* Try a reset */
- pmm_fatal_reset( pmm );
- }
- }
-
-#if MALI_STATE_TRACKING
- pmm->mali_pmm_lock_acquired = 0;
-#endif /* MALI_STATE_TRACKING */
-
- MALI_PMM_UNLOCK(pmm);
-}
-
-static void pmm_event_process( void )
-{
- _mali_osk_errcode_t err = _MALI_OSK_ERR_OK;
- _mali_osk_notification_t *msg = NULL;
- _mali_pmm_internal_state_t *pmm = GET_PMM_STATE_PTR;
- mali_pmm_message_t *event;
- u32 process_messages;
-
- MALI_DEBUG_ASSERT_POINTER(pmm);
-
-
- /* Max number of messages to process before exiting - as we shouldn't stay
- * processing the messages for a long time
- */
- process_messages = _mali_osk_atomic_read( &(pmm->messages_queued) );
-
- while( process_messages > 0 )
- {
- /* Check internal message queue first */
- err = _mali_osk_notification_queue_dequeue( pmm->iqueue, &msg );
-
- if( err != _MALI_OSK_ERR_OK )
- {
- if( pmm->status == MALI_PMM_STATUS_IDLE || pmm->status == MALI_PMM_STATUS_OS_WAITING || pmm->status == MALI_PMM_STATUS_DVFS_PAUSE)
- {
- if( pmm->waiting > 0 ) pmm->waiting--;
-
- /* We aren't busy changing state, so look at real events */
- err = _mali_osk_notification_queue_dequeue( pmm->queue, &msg );
-
- if( err != _MALI_OSK_ERR_OK )
- {
- pmm->no_events++;
- MALIPMM_DEBUG_PRINT( ("PMM: event_process - No message to process\n") );
- /* Nothing to do - so return */
- return;
- }
- else
- {
- #if (MALI_PMM_TRACE || MALI_STATE_TRACKING)
- pmm->messages_received++;
- #endif
- }
- }
- else
- {
- /* Waiting for an internal message */
- pmm->waiting++;
- MALIPMM_DEBUG_PRINT( ("PMM: event_process - Waiting for internal message, messages queued=%d\n", pmm->waiting) );
- return;
- }
- }
- else
- {
- #if (MALI_PMM_TRACE || MALI_STATE_TRACKING)
- pmm->imessages_received++;
- #endif
- }
-
- MALI_DEBUG_ASSERT_POINTER( msg );
- /* Check the message type matches */
- MALI_DEBUG_ASSERT( msg->notification_type == MALI_PMM_NOTIFICATION_TYPE );
-
- event = msg->result_buffer;
-
- _mali_osk_atomic_dec( &(pmm->messages_queued) );
- process_messages--;
-
- #if MALI_PMM_TRACE
- /* Trace before we process the event in case we have an error */
- _mali_pmm_trace_event_message( event, MALI_TRUE );
- #endif
- err = pmm_policy_process( pmm, event );
-
-
- if( err != _MALI_OSK_ERR_OK )
- {
- MALI_PRINT_ERROR( ("PMM: Error(%d) in policy %d when processing event message with id: %d",
- err, pmm->policy, event->id) );
- }
-
- /* Delete notification */
- _mali_osk_notification_delete ( msg );
-
- if( pmm->fatal_power_err )
- {
- /* Nothing good has happened - exit */
- return;
- }
-
-
- #if MALI_PMM_TRACE
- MALI_PRINT( ("PMM Trace: Event processed, msgs (sent/read) = %d/%d, int msgs (sent/read) = %d/%d, no events = %d, waiting = %d\n",
- pmm->messages_sent, pmm->messages_received, pmm->imessages_sent, pmm->imessages_received, pmm->no_events, pmm->waiting) );
- #endif
- }
-
- if( pmm->status == MALI_PMM_STATUS_IDLE && pmm->waiting > 0 )
- {
- /* For events we ignored whilst we were busy, add a new
- * scheduled time to look at them */
- _mali_osk_irq_schedulework( pmm->irq );
- }
-}
-
-#if MALI_STATE_TRACKING
-u32 malipmm_subsystem_dump_state(char *buf, u32 size)
-{
- int len = 0;
- _mali_pmm_internal_state_t *pmm = GET_PMM_STATE_PTR;
-
- if( !pmm )
- {
- len += _mali_osk_snprintf(buf + len, size + len, "PMM: Null state\n");
- }
- else
- {
- len += _mali_osk_snprintf(buf+len, size+len, "Locks:\n PMM lock acquired: %s\n",
- pmm->mali_pmm_lock_acquired ? "true" : "false");
- len += _mali_osk_snprintf(buf+len, size+len,
- "PMM state:\n Previous status: %s\n Status: %s\n Current event: %s\n Policy: %s\n Check policy: %s\n State: %s\n",
- pmm_trace_status[pmm->mali_last_pmm_status], pmm_trace_status[pmm->status],
- pmm_trace_events[pmm->mali_new_event_status], pmm_trace_policy[pmm->policy],
- pmm->check_policy ? "true" : "false", pmm_trace_state[pmm->state]);
- len += _mali_osk_snprintf(buf+len, size+len,
- "PMM cores:\n Cores registered: %d\n Cores powered: %d\n Cores idle: %d\n"
- " Cores pending down: %d\n Cores pending up: %d\n Cores ack down: %d\n Cores ack up: %d\n",
- pmm->cores_registered, pmm->cores_powered, pmm->cores_idle, pmm->cores_pend_down,
- pmm->cores_pend_up, pmm->cores_ack_down, pmm->cores_ack_up);
- len += _mali_osk_snprintf(buf+len, size+len, "PMM misc:\n PMU init: %s\n Messages queued: %d\n"
- " Waiting: %d\n No events: %d\n Missed events: %d\n Fatal power error: %s\n",
- pmm->pmu_initialized ? "true" : "false", _mali_osk_atomic_read(&(pmm->messages_queued)),
- pmm->waiting, pmm->no_events, pmm->missed, pmm->fatal_power_err ? "true" : "false");
- }
- return len;
-}
-#endif /* MALI_STATE_TRACKING */
-
-#endif /* USING_MALI_PMM */
diff --git a/drivers/media/video/samsung/mali/common/pmm/mali_pmm.h b/drivers/media/video/samsung/mali/common/pmm/mali_pmm.h
deleted file mode 100644
index 5170650..0000000
--- a/drivers/media/video/samsung/mali/common/pmm/mali_pmm.h
+++ /dev/null
@@ -1,348 +0,0 @@
-/*
- * 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_pmm.h
- * Defines the power management module for the kernel device driver
- */
-
-#ifndef __MALI_PMM_H__
-#define __MALI_PMM_H__
-
-/* For mali_pmm_message_data and MALI_PMM_EVENT_UK_* defines */
-#include "mali_uk_types.h"
-#include "mali_platform.h"
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
-/**
- * @defgroup pmmapi Power Management Module APIs
- *
- * @{
- */
-
-/** OS event tester */
-#define PMM_OS_TEST 0
-
-/** @brief Compile option to turn on/off tracing */
-#define MALI_PMM_TRACE 0
-#define MALI_PMM_TRACE_SENT_EVENTS 0
-
-/** @brief Compile option to switch between always on or job control PMM policy */
-#define MALI_PMM_ALWAYS_ON 0
-
-/** @brief Overrides hardware PMU and uses software simulation instead
- * @note This even stops intialization of PMU and cores being powered on at start up
- */
-#define MALI_PMM_NO_PMU 0
-
-/** @brief PMM debug print to control debug message level */
-#define MALIPMM_DEBUG_PRINT(args) \
- MALI_DEBUG_PRINT(3, args)
-
-
-/** @brief power management event message identifiers.
- */
-/* These must match up with the pmm_trace_events & pmm_trace_events_internal
- * arrays
- */
-typedef enum mali_pmm_event_id
-{
- MALI_PMM_EVENT_OS_POWER_UP = 0, /**< OS power up event */
- MALI_PMM_EVENT_OS_POWER_DOWN = 1, /**< OS power down event */
- MALI_PMM_EVENT_JOB_SCHEDULED = 2, /**< Job scheduled to run event */
- MALI_PMM_EVENT_JOB_QUEUED = 3, /**< Job queued (but not run) event */
- MALI_PMM_EVENT_JOB_FINISHED = 4, /**< Job finished event */
- MALI_PMM_EVENT_TIMEOUT = 5, /**< Time out timer has expired */
- MALI_PMM_EVENT_DVFS_PAUSE = 6, /**< Mali device pause event */
- MALI_PMM_EVENT_DVFS_RESUME = 7, /**< Mali device resume event */
-
- MALI_PMM_EVENT_UKS = 200, /**< Events from the user-side start here */
- MALI_PMM_EVENT_UK_EXAMPLE = _MALI_PMM_EVENT_UK_EXAMPLE,
-
- MALI_PMM_EVENT_INTERNALS = 1000,
- MALI_PMM_EVENT_INTERNAL_POWER_UP_ACK = 1001, /**< Internal power up acknowledgement */
- MALI_PMM_EVENT_INTERNAL_POWER_DOWN_ACK = 1002, /**< Internal power down acknowledgment */
-} mali_pmm_event_id;
-
-
-/** @brief Use this when the power up/down callbacks do not need any OS data. */
-#define MALI_PMM_NO_OS_DATA 1
-
-
-/* @brief Geometry and pixel processor identifiers for the PMM
- *
- * @note these match the ARM Mali 400 PMU hardware definitions, apart from the "SYSTEM"
- */
-typedef enum mali_pmm_core_id_tag
-{
- MALI_PMM_CORE_SYSTEM = 0x00000000, /**< All of the Mali hardware */
- MALI_PMM_CORE_GP = 0x00000001, /**< Mali GP2 */
- MALI_PMM_CORE_L2 = 0x00000002, /**< Level 2 cache */
- MALI_PMM_CORE_PP0 = 0x00000004, /**< Mali 200 pixel processor 0 */
- MALI_PMM_CORE_PP1 = 0x00000008, /**< Mali 200 pixel processor 1 */
- MALI_PMM_CORE_PP2 = 0x00000010, /**< Mali 200 pixel processor 2 */
- MALI_PMM_CORE_PP3 = 0x00000020, /**< Mali 200 pixel processor 3 */
- MALI_PMM_CORE_PP_ALL = 0x0000003C /**< Mali 200 pixel processors 0-3 */
-} mali_pmm_core_id;
-
-
-/* @brief PMM bitmask of mali_pmm_core_ids
- */
-typedef u32 mali_pmm_core_mask;
-
-/* @brief PMM event timestamp type
- */
-typedef u32 mali_pmm_timestamp;
-
-/** @brief power management event message struct
- */
-typedef struct _mali_pmm_message
-{
- mali_pmm_event_id id; /**< event id */
- mali_pmm_message_data data; /**< specific data associated with the event */
- mali_pmm_timestamp ts; /**< timestamp the event was placed in the event queue */
-} mali_pmm_message_t;
-
-
-
-/** @brief the state of the power management module.
- */
-/* These must match up with the pmm_trace_state array */
-typedef enum mali_pmm_state_tag
-{
- MALI_PMM_STATE_UNAVAILABLE = 0, /**< PMM is not available */
- MALI_PMM_STATE_SYSTEM_ON = 1, /**< All of the Mali hardware is on */
- MALI_PMM_STATE_SYSTEM_OFF = 2, /**< All of the Mali hardware is off */
- MALI_PMM_STATE_SYSTEM_TRANSITION = 3 /**< System is changing state */
-} mali_pmm_state;
-
-
-/** @brief a power management policy.
- */
-/* These must match up with the pmm_trace_policy array */
-typedef enum mali_pmm_policy_tag
-{
- MALI_PMM_POLICY_NONE = 0, /**< No policy */
- MALI_PMM_POLICY_ALWAYS_ON = 1, /**< Always on policy */
- MALI_PMM_POLICY_JOB_CONTROL = 2, /**< Job control policy */
- MALI_PMM_POLICY_RUNTIME_JOB_CONTROL = 3 /**< Run time power management control policy */
-} mali_pmm_policy;
-
-/** @brief Function to power up MALI
- *
- * @param cores core mask to power up the cores
- *
- * @return error code if MALI fails to power up
- */
-_mali_osk_errcode_t malipmm_powerup( u32 cores );
-
-/** @brief Function to power down MALI
- *
- * @param cores core mask to power down the cores
- * @param The power mode to which MALI transitions
- *
- * @return error code if MALI fails to power down
- */
-_mali_osk_errcode_t malipmm_powerdown( u32 cores, mali_power_mode power_mode );
-
-/** @brief Function to report to the OS when the power down has finished
- *
- * @param data The event message data that initiated the power down
- */
-void _mali_osk_pmm_power_down_done(mali_pmm_message_data data);
-
-/** @brief Function to report to the OS when the power up has finished
- *
- * @param data The event message data that initiated the power up
- */
-void _mali_osk_pmm_power_up_done(mali_pmm_message_data data);
-
-/** @brief Function to report that DVFS operation done
- *
- * @param data The event message data
- */
-void _mali_osk_pmm_dvfs_operation_done(mali_pmm_message_data data);
-
-#if MALI_POWER_MGMT_TEST_SUITE
-/** @brief Function to notify power management events
- *
- * @param data The event message data
- */
-void _mali_osk_pmm_policy_events_notifications(mali_pmm_event_id event_id);
-
-#endif
-
-/** @brief Function to power up MALI
- *
- * @note powers up the MALI during MALI device driver is unloaded
- */
-void malipmm_force_powerup( void );
-
-/** @brief Function to report the OS that device is idle
- *
- * @note inform the OS that device is idle
- */
-_mali_osk_errcode_t _mali_osk_pmm_dev_idle( void );
-
-/** @brief Function to report the OS to activate device
- *
- * @note inform the os that device needs to be activated
- */
-int _mali_osk_pmm_dev_activate( void );
-
-/** @brief Function to report OS PMM for cleanup
- *
- * @note Function to report OS PMM for cleanup
- */
-void _mali_osk_pmm_ospmm_cleanup( void );
-
-/** @brief Queries the current state of the PMM software
- *
- * @note the state of the PMM can change after this call has returned
- *
- * @return the current PMM state value
- */
-mali_pmm_state _mali_pmm_state( void );
-
-/** @brief List of cores that are registered with the PMM
- *
- * This will return the cores that have been currently registered with the PMM,
- * which is a bitwise OR of the mali_pmm_core_id_tags. A value of 0x0 means that
- * there are no cores registered.
- *
- * @note the list of cores can change after this call has returned
- *
- * @return a bit mask representing all the cores that have been registered with the PMM
- */
-mali_pmm_core_mask _mali_pmm_cores_list( void );
-
-/** @brief List of cores that are powered up in the PMM
- *
- * This will return the subset of the cores that can be listed using mali_pmm_cores_
- * list, that have power. It is a bitwise OR of the mali_pmm_core_id_tags. A value of
- * 0x0 means that none of the cores registered are powered.
- *
- * @note the list of cores can change after this call has returned
- *
- * @return a bit mask representing all the cores that are powered up
- */
-mali_pmm_core_mask _mali_pmm_cores_powered( void );
-
-
-/** @brief List of power management policies that are supported by the PMM
- *
- * Given an empty array of policies - policy_list - which contains the number
- * of entries as specified by - policy_list_size, this function will populate
- * the list with the available policies. If the policy_list is too small for
- * all the policies then only policy_list_size entries will be returned. If the
- * policy_list is bigger than the number of available policies then, the extra
- * entries will be set to MALI_PMM_POLICY_NONE.
- * The function will also update available_policies with the number of policies
- * that are available, even if it exceeds the policy_list_size.
- * The function will succeed if all policies could be returned, else it will
- * fail if none or only a subset of policies could be returned.
- * The function will also fail if no policy_list is supplied, though
- * available_policies is optional.
- *
- * @note this is a STUB function and is not yet implemented
- *
- * @param policy_list_size is the number of policies that can be returned in
- * the policy_list argument
- * @param policy_list is an array of policies that should be populated with
- * the list of policies that are supported by the PMM
- * @param policies_available optional argument, if non-NULL will be set to the
- * number of policies available
- * @return _MALI_OSK_ERR_OK if the policies could be listed, or a suitable
- * _mali_osk_errcode_t otherwise.
- */
-_mali_osk_errcode_t _mali_pmm_list_policies(
- u32 policy_list_size,
- mali_pmm_policy *policy_list,
- u32 *policies_available );
-
-/** @brief Set the power management policy in the PMM
- *
- * Given a valid supported policy, this function will change the PMM to use
- * this new policy
- * The function will fail if the policy given is invalid or unsupported.
- *
- * @note this is a STUB function and is not yet implemented
- *
- * @param policy the new policy to be set
- * @return _MALI_OSK_ERR_OK if the policy could be set, or a suitable
- * _mali_osk_errcode_t otherwise.
- */
-_mali_osk_errcode_t _mali_pmm_set_policy( mali_pmm_policy policy );
-
-/** @brief Get the current power management policy in the PMM
- *
- * Given a pointer to a policy data type, this function will return the current
- * policy that is in effect for the PMM. This maybe out of date if there is a
- * pending set policy call that has not been serviced.
- * The function will fail if the policy given is NULL.
- *
- * @note the policy of the PMM can change after this call has returned
- *
- * @param policy a pointer to a policy that can be updated to the current
- * policy
- * @return _MALI_OSK_ERR_OK if the policy could be returned, or a suitable
- * _mali_osk_errcode_t otherwise.
- */
-_mali_osk_errcode_t _mali_pmm_get_policy( mali_pmm_policy *policy );
-
-#if MALI_PMM_TRACE
-
-/** @brief Indicates when a hardware state change occurs in the PMM
- *
- * @param old a mask of the cores indicating the previous state of the cores
- * @param newstate a mask of the cores indicating the new current state of the cores
- */
-void _mali_pmm_trace_hardware_change( mali_pmm_core_mask old, mali_pmm_core_mask newstate );
-
-/** @brief Indicates when a state change occurs in the PMM
- *
- * @param old the previous state for the PMM
- * @param newstate the new current state of the PMM
- */
-void _mali_pmm_trace_state_change( mali_pmm_state old, mali_pmm_state newstate );
-
-/** @brief Indicates when a policy change occurs in the PMM
- *
- * @param old the previous policy for the PMM
- * @param newpolicy the new current policy of the PMM
- */
-void _mali_pmm_trace_policy_change( mali_pmm_policy old, mali_pmm_policy newpolicy );
-
-/** @brief Records when an event message is read by the event system
- *
- * @param event the message details
- * @param received MALI_TRUE when the message is received by the PMM, else it is being sent
- */
-void _mali_pmm_trace_event_message( mali_pmm_message_t *event, mali_bool received );
-
-#endif /* MALI_PMM_TRACE */
-
-/** @brief Dumps the current state of OS PMM thread
- */
-#if MALI_STATE_TRACKING
-u32 mali_pmm_dump_os_thread_state( char *buf, u32 size );
-#endif /* MALI_STATE_TRACKING */
-
-/** @} */ /* end group pmmapi */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __MALI_PMM_H__ */
diff --git a/drivers/media/video/samsung/mali/common/pmm/mali_pmm_pmu.c b/drivers/media/video/samsung/mali/common/pmm/mali_pmm_pmu.c
deleted file mode 100644
index a8160ac..0000000
--- a/drivers/media/video/samsung/mali/common/pmm/mali_pmm_pmu.c
+++ /dev/null
@@ -1,350 +0,0 @@
-/*
- * 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_pmm_pmu.c
- * Mali driver functions for Mali 400 PMU hardware
- */
-#include "mali_kernel_common.h"
-#include "mali_osk.h"
-#include "mali_platform.h"
-
-#if USING_MALI_PMU
-#if USING_MALI_PMM
-
-#include "mali_pmm.h"
-
-/* Internal test on/off */
-#define PMU_TEST 0
-
-#if MALI_POWER_MGMT_TEST_SUITE
-#include "mali_platform_pmu_internal_testing.h"
-#endif /* MALI_POWER_MGMT_TEST_SUITE */
-
-/** @brief PMU hardware info
- */
-typedef struct platform_pmu
-{
- u32 reg_base_addr; /**< PMU registers base address */
- u32 reg_size; /**< PMU registers size */
- const char *name; /**< PMU name */
- u32 irq_num; /**< PMU irq number */
-
- mali_io_address reg_mapped; /**< IO-mapped pointer to registers */
-} platform_pmu_t;
-
-static platform_pmu_t *pmu_info = 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_STAT = 0x14, /*< Interrupt status register */
- PMU_REG_ADDR_MGMT_INT_CLEAR = 0x18, /*< Interrupt clear register */
- PMU_REG_ADDR_MGMT_SW_DELAY = 0x1C, /*< Software delay register */
- PMU_REG_ADDR_MGMT_MASTER_PWR_UP = 0x24, /*< Master power up register */
- PMU_REGISTER_ADDRESS_SPACE_SIZE = 0x28, /*< Size of register space */
-} pmu_reg_addr_mgmt_addr;
-
-/* Internal functions */
-static u32 pmu_reg_read(platform_pmu_t *pmu, u32 relative_address);
-static void pmu_reg_write(platform_pmu_t *pmu, u32 relative_address, u32 new_val);
-static mali_pmm_core_mask pmu_translate_cores_to_pmu(mali_pmm_core_mask cores);
-#if PMU_TEST
-static void pmm_pmu_dump_regs( platform_pmu_t *pmu );
-static pmm_pmu_test( platform_pmu_t *pmu, u32 cores );
-#endif
-
-_mali_osk_errcode_t mali_pmm_pmu_init(_mali_osk_resource_t *resource)
-{
-
- if( resource->type == PMU )
- {
- if( (resource->base == 0) ||
- (resource->description == NULL) )
- {
- /* NOTE: We currently don't care about any other resource settings */
- MALI_PRINT_ERROR(("PLATFORM mali400-pmu: Missing PMU set up information\n"));
- MALI_ERROR(_MALI_OSK_ERR_INVALID_ARGS);
- }
- pmu_info = (platform_pmu_t *)_mali_osk_malloc(sizeof(*pmu_info));
- MALI_CHECK_NON_NULL( pmu_info, _MALI_OSK_ERR_NOMEM );
-
- /* All values get 0 as default */
- _mali_osk_memset(pmu_info, 0, sizeof(*pmu_info));
-
- pmu_info->reg_base_addr = resource->base;
- pmu_info->reg_size = (u32)PMU_REGISTER_ADDRESS_SPACE_SIZE;
- pmu_info->name = resource->description;
- pmu_info->irq_num = resource->irq;
-
- if( _MALI_OSK_ERR_OK != _mali_osk_mem_reqregion(pmu_info->reg_base_addr, pmu_info->reg_size, pmu_info->name) )
- {
- MALI_PRINT_ERROR(("PLATFORM mali400-pmu: Could not request register region (0x%08X - 0x%08X) for %s\n",
- pmu_info->reg_base_addr, pmu_info->reg_base_addr + pmu_info->reg_size - 1, pmu_info->name));
- goto cleanup;
- }
- else
- {
- MALI_DEBUG_PRINT( 4, ("PLATFORM mali400-pmu: Success: request_mem_region: (0x%08X - 0x%08X) for %s\n",
- pmu_info->reg_base_addr, pmu_info->reg_base_addr + pmu_info->reg_size - 1, pmu_info->name));
- }
-
- pmu_info->reg_mapped = _mali_osk_mem_mapioregion( pmu_info->reg_base_addr, pmu_info->reg_size, pmu_info->name );
-
- if( 0 == pmu_info->reg_mapped )
- {
- MALI_PRINT_ERROR(("PLATFORM mali400-pmu: Could not ioremap registers for %s .\n", pmu_info->name));
- _mali_osk_mem_unreqregion( pmu_info->reg_base_addr, pmu_info->reg_size );
- goto cleanup;
- }
- else
- {
- MALI_DEBUG_PRINT( 4, ("PLATFORM mali400-pmu: Success: ioremap_nocache: Internal ptr: (0x%08X - 0x%08X) for %s\n",
- (u32) pmu_info->reg_mapped,
- ((u32)pmu_info->reg_mapped)+ pmu_info->reg_size - 1,
- pmu_info->name));
- }
-
- MALI_DEBUG_PRINT( 4, ("PLATFORM mali400-pmu: Success: Mapping registers to %s\n", pmu_info->name));
-
-#if PMU_TEST
- pmu_test(pmu_info, (MALI_PMM_CORE_GP));
- pmu_test(pmu_info, (MALI_PMM_CORE_GP|MALI_PMM_CORE_L2|MALI_PMM_CORE_PP0));
-#endif
-
- MALI_DEBUG_PRINT( 4, ("PLATFORM mali400-pmu: Initialized - %s\n", pmu_info->name) );
- }
- else
- {
- /* Didn't expect a different resource */
- MALI_ERROR(_MALI_OSK_ERR_INVALID_ARGS);
- }
-
- MALI_SUCCESS;
-
-cleanup:
- _mali_osk_free(pmu_info);
- pmu_info = NULL;
- MALI_ERROR(_MALI_OSK_ERR_NOMEM);
-}
-
-_mali_osk_errcode_t mali_pmm_pmu_deinit(_mali_osk_resource_type_t *type)
-{
- if (*type == PMU)
- {
- if( pmu_info )
- {
- _mali_osk_mem_unmapioregion(pmu_info->reg_base_addr, pmu_info->reg_size, pmu_info->reg_mapped);
- _mali_osk_mem_unreqregion(pmu_info->reg_base_addr, pmu_info->reg_size);
- _mali_osk_free(pmu_info);
- pmu_info = NULL;
- MALI_DEBUG_PRINT( 4, ("PLATFORM mali400-pmu: Terminated PMU\n") );
- }
- }
- else
- {
- /* Didn't expect a different resource */
- MALI_ERROR(_MALI_OSK_ERR_INVALID_ARGS);
- }
-
- MALI_SUCCESS;
-
-}
-
-_mali_osk_errcode_t mali_pmm_pmu_powerdown(u32 cores)
-{
- u32 stat;
- u32 timeout;
- u32 cores_pmu;
-
- MALI_DEBUG_ASSERT_POINTER(pmu_info);
- MALI_DEBUG_ASSERT( cores != 0 ); /* Shouldn't receive zero from PMM */
- MALI_DEBUG_PRINT( 4, ("PLATFORM mali400-pmu: power down (0x%x)\n", cores) );
-
- cores_pmu = pmu_translate_cores_to_pmu(cores);
- pmu_reg_write( pmu_info, (u32)PMU_REG_ADDR_MGMT_POWER_DOWN, cores_pmu );
-
- /* Wait for cores to be powered down */
- timeout = 10; /* 10ms */
- do
- {
- /* Get status of sleeping cores */
- stat = pmu_reg_read( pmu_info, (u32)PMU_REG_ADDR_MGMT_STATUS );
- stat &= cores_pmu;
- if( stat == cores_pmu ) break; /* All cores we wanted are now asleep */
- _mali_osk_time_ubusydelay(1000); /* 1ms */
- timeout--;
- } while( timeout > 0 );
-
- if( timeout == 0 ) MALI_ERROR(_MALI_OSK_ERR_TIMEOUT);
-
- MALI_SUCCESS;
-}
-
-_mali_osk_errcode_t mali_pmm_pmu_powerup(u32 cores)
-{
- u32 cores_pmu;
- u32 stat;
- u32 timeout;
-
- MALI_DEBUG_ASSERT_POINTER(pmu_info);
- MALI_DEBUG_ASSERT( cores != 0 ); /* Shouldn't receive zero from PMM */
- MALI_DEBUG_PRINT( 4, ("PLATFORM mali400-pmu: power up (0x%x)\n", cores) );
-
- /* Don't use interrupts - just poll status */
- pmu_reg_write( pmu_info, (u32)PMU_REG_ADDR_MGMT_INT_MASK, 0 );
- cores_pmu = pmu_translate_cores_to_pmu(cores);
- pmu_reg_write( pmu_info, (u32)PMU_REG_ADDR_MGMT_POWER_UP, cores_pmu );
-
- timeout = 10; /* 10ms */
- do
- {
- /* Get status of sleeping cores */
- stat = pmu_reg_read( pmu_info, (u32)PMU_REG_ADDR_MGMT_STATUS );
- stat &= cores_pmu;
- if( stat == 0 ) break; /* All cores we wanted are now awake */
- _mali_osk_time_ubusydelay(1000); /* 1ms */
- timeout--;
- } while( timeout > 0 );
-
- if( timeout == 0 ) MALI_ERROR(_MALI_OSK_ERR_TIMEOUT);
-
- MALI_SUCCESS;
-}
-
-
-/***** INTERNAL *****/
-
-/** @brief Internal PMU function to translate the cores bit mask
- * into something the hardware PMU understands
- *
- * @param cores PMM cores bitmask
- * @return PMU hardware cores bitmask
- */
-static u32 pmu_translate_cores_to_pmu(mali_pmm_core_mask cores)
-{
- /* For Mali 400 PMU the cores mask is already the same as what
- * the hardware PMU expects.
- * For other hardware, some translation can be done here, by
- * translating the MALI_PMM_CORE_* bits into specific hardware
- * bits
- */
- return cores;
-}
-
-/** @brief Internal PMU function to read a PMU register
- *
- * @param pmu handle that identifies the PMU hardware
- * @param relative_address relative PMU hardware address to read from
- * @return 32-bit value that was read from the address
- */
-static u32 pmu_reg_read(platform_pmu_t *pmu, u32 relative_address)
-{
- u32 read_val;
-
- MALI_DEBUG_ASSERT_POINTER(pmu);
- MALI_DEBUG_ASSERT((relative_address & 0x03) == 0);
- MALI_DEBUG_ASSERT(relative_address < pmu->reg_size);
-
- read_val = _mali_osk_mem_ioread32(pmu->reg_mapped, relative_address);
-
- MALI_DEBUG_PRINT( 5, ("PMU: reg_read: %s Addr:0x%04X Val:0x%08x\n",
- pmu->name, relative_address, read_val));
-
- return read_val;
-}
-
-/** @brief Internal PMU function to write to a PMU register
- *
- * @param pmu handle that identifies the PMU hardware
- * @param relative_address relative PMU hardware address to write to
- * @param new_val new 32-bit value to write into the address
- */
-static void pmu_reg_write(platform_pmu_t *pmu, u32 relative_address, u32 new_val)
-{
- MALI_DEBUG_ASSERT_POINTER(pmu);
- MALI_DEBUG_ASSERT((relative_address & 0x03) == 0);
- MALI_DEBUG_ASSERT(relative_address < pmu->reg_size);
-
- MALI_DEBUG_PRINT( 5, ("PMU: reg_write: %s Addr:0x%04X Val:0x%08x\n",
- pmu->name, relative_address, new_val));
-
- _mali_osk_mem_iowrite32(pmu->reg_mapped, relative_address, new_val);
-}
-
-#if PMU_TEST
-
-/***** TEST *****/
-
-static void pmu_dump_regs( platform_pmu_t *pmu )
-{
- u32 addr;
- for( addr = 0x0; addr < PMU_REGISTER_ADDRESS_SPACE_SIZE; addr += 0x4 )
- {
- MALI_PRINT( ("PMU_REG: 0x%08x: 0x%04x\n", (addr + pmu->reg_base_addr), pmu_reg_read( pmu, addr ) ) );
- }
-}
-
-/* This function is an internal test for the PMU without any Mali h/w interaction */
-static void pmu_test( platform_pmu_t *pmu, u32 cores )
-{
- u32 stat;
- u32 timeout;
-
- MALI_PRINT( ("PMU_TEST: Start\n") );
-
- pmu_dump_regs( pmu );
-
- MALI_PRINT( ("PMU_TEST: Power down cores: 0x%x\n", cores) );
- _mali_pmm_pmu_power_down( pmu, cores, MALI_TRUE );
-
- stat = pmu_reg_read( pmu, (u32)PMU_REG_ADDR_MGMT_STATUS );
- MALI_PRINT( ("PMU_TEST: %s\n", (stat & cores) == cores ? "SUCCESS" : "FAIL" ) );
-
- pmu_dump_regs( pmu );
-
- MALI_PRINT( ("PMU_TEST: Power up cores: 0x%x\n", cores) );
- _mali_pmm_pmu_power_up( pmu, cores, MALI_FALSE );
-
- MALI_PRINT( ("PMU_TEST: Waiting for power up...\n") );
- timeout = 1000; /* 1 sec */
- while( !_mali_pmm_pmu_irq_power_up(pmu) && timeout > 0 )
- {
- _mali_osk_time_ubusydelay(1000); /* 1ms */
- timeout--;
- }
-
- MALI_PRINT( ("PMU_TEST: Waited %dms for interrupt\n", (1000-timeout)) );
- stat = pmu_reg_read( pmu, (u32)PMU_REG_ADDR_MGMT_STATUS );
- MALI_PRINT( ("PMU_TEST: %s\n", (stat & cores) == 0 ? "SUCCESS" : "FAIL" ) );
-
- _mali_pmm_pmu_irq_power_up_clear(pmu);
-
- pmu_dump_regs( pmu );
-
- MALI_PRINT( ("PMU_TEST: Finish\n") );
-}
-#endif /* PMU_TEST */
-
-#if MALI_POWER_MGMT_TEST_SUITE
-
-u32 pmu_get_power_up_down_info(void)
-{
- return pmu_reg_read(pmu_info, (u32)PMU_REG_ADDR_MGMT_STATUS);
-}
-
-#endif /* MALI_POWER_MGMT_TEST_SUITE */
-#endif /* USING_MALI_PMM */
-#endif /* USING_MALI_PMU */
diff --git a/drivers/media/video/samsung/mali/common/pmm/mali_pmm_pmu.h b/drivers/media/video/samsung/mali/common/pmm/mali_pmm_pmu.h
deleted file mode 100644
index 7525cac..0000000
--- a/drivers/media/video/samsung/mali/common/pmm/mali_pmm_pmu.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * 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_platform.h
- * Platform specific Mali driver functions
- */
-
-#include "mali_osk.h"
-
-#if !USING_MALI_PMM
-/* @brief System power up/down cores that can be passed into mali_platform_powerdown/up() */
-#define MALI_PLATFORM_SYSTEM 0
-#endif
-
-#if USING_MALI_PMM
-#if USING_MALI_PMU
-#include "mali_pmm.h"
-
-/** @brief Platform specific setup and initialisation of MALI
- *
- * This is called from the entrypoint of the driver to initialize the platform
- * When using PMM, it is also called from the PMM start up to initialise the
- * system PMU
- *
- * @param resource This is NULL when called on first driver start up, else it will
- * be a pointer to a PMU resource
- * @return _MALI_OSK_ERR_OK on success otherwise, a suitable _mali_osk_errcode_t error.
- */
-_mali_osk_errcode_t mali_pmm_pmu_init(_mali_osk_resource_t *resource);
-
-/** @brief Platform specific deinitialisation of MALI
- *
- * This is called on the exit of the driver to terminate the platform
- * When using PMM, it is also called from the PMM termination code to clean up the
- * system PMU
- *
- * @param type This is NULL when called on driver exit, else it will
- * be a pointer to a PMU resource type (not the full resource)
- * @return _MALI_OSK_ERR_OK on success otherwise, a suitable _mali_osk_errcode_t error.
- */
-_mali_osk_errcode_t mali_pmm_pmu_deinit(_mali_osk_resource_type_t *type);
-
-/** @brief Platform specific powerdown sequence of MALI
- *
- * Called as part of platform init if there is no PMM support, else the
- * PMM will call it.
- *
- * @param cores This is MALI_PLATFORM_SYSTEM when called without PMM, else it will
- * be a mask of cores to power down based on the mali_pmm_core_id enum
- * @return _MALI_OSK_ERR_OK on success otherwise, a suitable _mali_osk_errcode_t error.
- */
-_mali_osk_errcode_t mali_pmm_pmu_powerdown(u32 cores);
-
-/** @brief Platform specific powerup sequence of MALI
- *
- * Called as part of platform deinit if there is no PMM support, else the
- * PMM will call it.
- *
- * @param cores This is MALI_PLATFORM_SYSTEM when called without PMM, else it will
- * be a mask of cores to power down based on the mali_pmm_core_id enum
- * @return _MALI_OSK_ERR_OK on success otherwise, a suitable _mali_osk_errcode_t error.
- */
-_mali_osk_errcode_t mali_pmm_pmu_powerup(u32 cores);
-
-#if MALI_POWER_MGMT_TEST_SUITE
-#if USING_MALI_PMM
-#if USING_MALI_PMU
-/** @brief function to get status of individual cores
- *
- * This function is used by power management test suite to get the status of powered up/down the number
- * of cores
- * @param utilization The workload utilization of the Mali GPU. 0 = no utilization, 256 = full utilization.
- */
-u32 pmu_get_power_up_down_info(void);
-#endif
-#endif
-#endif
-#endif
-#endif
diff --git a/drivers/media/video/samsung/mali/common/pmm/mali_pmm_policy.c b/drivers/media/video/samsung/mali/common/pmm/mali_pmm_policy.c
deleted file mode 100644
index 87b6ec2..0000000
--- a/drivers/media/video/samsung/mali/common/pmm/mali_pmm_policy.c
+++ /dev/null
@@ -1,243 +0,0 @@
-/*
- * 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_pmm_policy.c
- * Implementation of the common routines for power management module
- * policies
- */
-
-#if USING_MALI_PMM
-
-#include "mali_ukk.h"
-#include "mali_kernel_common.h"
-
-#include "mali_pmm.h"
-#include "mali_pmm_system.h"
-#include "mali_pmm_state.h"
-#include "mali_pmm_policy.h"
-
-#include "mali_pmm_policy_alwayson.h"
-#include "mali_pmm_policy_jobcontrol.h"
-
-/* Call back function for timer expiration */
-static void pmm_policy_timer_callback( void *arg );
-
-_mali_osk_errcode_t pmm_policy_timer_init( _pmm_policy_timer_t *pptimer, u32 timeout, mali_pmm_event_id id )
-{
- MALI_DEBUG_ASSERT_POINTER(pptimer);
-
- /* All values get 0 as default */
- _mali_osk_memset(pptimer, 0, sizeof(*pptimer));
-
- pptimer->timer = _mali_osk_timer_init();
- if( pptimer->timer )
- {
- _mali_osk_timer_setcallback( pptimer->timer, pmm_policy_timer_callback, (void *)pptimer );
- pptimer->timeout = timeout;
- pptimer->event_id = id;
- MALI_SUCCESS;
- }
-
- return _MALI_OSK_ERR_FAULT;
-}
-
-static void pmm_policy_timer_callback( void *arg )
-{
- _pmm_policy_timer_t *pptimer = (_pmm_policy_timer_t *)arg;
-
- MALI_DEBUG_ASSERT_POINTER(pptimer);
- MALI_DEBUG_ASSERT( pptimer->set );
-
- /* Set timer expired and flag there is a policy to check */
- pptimer->expired = MALI_TRUE;
- malipmm_set_policy_check();
-}
-
-
-void pmm_policy_timer_term( _pmm_policy_timer_t *pptimer )
-{
- MALI_DEBUG_ASSERT_POINTER(pptimer);
-
- _mali_osk_timer_del( pptimer->timer );
- _mali_osk_timer_term( pptimer->timer );
- pptimer->timer = NULL;
-}
-
-mali_bool pmm_policy_timer_start( _pmm_policy_timer_t *pptimer )
-{
- MALI_DEBUG_ASSERT_POINTER(pptimer);
- MALI_DEBUG_ASSERT_POINTER(pptimer->timer);
-
- if( !(pptimer->set) )
- {
- pptimer->set = MALI_TRUE;
- pptimer->expired = MALI_FALSE;
- pptimer->start = _mali_osk_time_tickcount();
- _mali_osk_timer_add( pptimer->timer, pptimer->timeout );
- return MALI_TRUE;
- }
-
- return MALI_FALSE;
-}
-
-mali_bool pmm_policy_timer_stop( _pmm_policy_timer_t *pptimer )
-{
- MALI_DEBUG_ASSERT_POINTER(pptimer);
- MALI_DEBUG_ASSERT_POINTER(pptimer->timer);
-
- if( pptimer->set )
- {
- _mali_osk_timer_del( pptimer->timer );
- pptimer->set = MALI_FALSE;
- pptimer->expired = MALI_FALSE;
- return MALI_TRUE;
- }
-
- return MALI_FALSE;
-}
-
-mali_bool pmm_policy_timer_raise_event( _pmm_policy_timer_t *pptimer )
-{
- MALI_DEBUG_ASSERT_POINTER(pptimer);
-
- if( pptimer->expired )
- {
- _mali_uk_pmm_message_s event = {
- NULL,
- MALI_PMM_EVENT_TIMEOUT, /* Assume timeout id, but set it below */
- 0 };
-
- event.id = pptimer->event_id;
- event.data = (mali_pmm_message_data)pptimer->start;
-
- /* Don't need to do any other notification with this timer */
- pptimer->expired = MALI_FALSE;
- /* Unset timer so it is free to be set again */
- pptimer->set = MALI_FALSE;
-
- _mali_ukk_pmm_event_message( &event );
-
- return MALI_TRUE;
- }
-
- return MALI_FALSE;
-}
-
-mali_bool pmm_policy_timer_valid( u32 timer_start, u32 other_start )
-{
- return (_mali_osk_time_after( other_start, timer_start ) == 0);
-}
-
-
-_mali_osk_errcode_t pmm_policy_init(_mali_pmm_internal_state_t *pmm)
-{
- _mali_osk_errcode_t err;
-
- MALI_DEBUG_ASSERT_POINTER(pmm);
-
- switch( pmm->policy )
- {
- case MALI_PMM_POLICY_ALWAYS_ON:
- {
- err = pmm_policy_init_always_on();
- }
- break;
-
- case MALI_PMM_POLICY_JOB_CONTROL:
- {
- err = pmm_policy_init_job_control(pmm);
- }
- break;
-
- case MALI_PMM_POLICY_NONE:
- default:
- err = _MALI_OSK_ERR_FAULT;
- }
-
- return err;
-}
-
-void pmm_policy_term(_mali_pmm_internal_state_t *pmm)
-{
- MALI_DEBUG_ASSERT_POINTER(pmm);
-
- switch( pmm->policy )
- {
- case MALI_PMM_POLICY_ALWAYS_ON:
- {
- pmm_policy_term_always_on();
- }
- break;
-
- case MALI_PMM_POLICY_JOB_CONTROL:
- {
- pmm_policy_term_job_control();
- }
- break;
-
- case MALI_PMM_POLICY_NONE:
- default:
- MALI_PRINT_ERROR( ("PMM: Invalid policy terminated %d\n", pmm->policy) );
- }
-}
-
-
-_mali_osk_errcode_t pmm_policy_process(_mali_pmm_internal_state_t *pmm, mali_pmm_message_t *event)
-{
- _mali_osk_errcode_t err;
-
- MALI_DEBUG_ASSERT_POINTER(pmm);
- MALI_DEBUG_ASSERT_POINTER(event);
-
- switch( pmm->policy )
- {
- case MALI_PMM_POLICY_ALWAYS_ON:
- {
- err = pmm_policy_process_always_on( pmm, event );
- }
- break;
-
- case MALI_PMM_POLICY_JOB_CONTROL:
- {
- err = pmm_policy_process_job_control( pmm, event );
- }
- break;
-
- case MALI_PMM_POLICY_NONE:
- default:
- err = _MALI_OSK_ERR_FAULT;
- }
-
- return err;
-}
-
-
-void pmm_policy_check_policy( _mali_pmm_internal_state_t *pmm )
-{
- MALI_DEBUG_ASSERT_POINTER(pmm);
-
- switch( pmm->policy )
- {
- case MALI_PMM_POLICY_JOB_CONTROL:
- {
- pmm_policy_check_job_control();
- }
- break;
-
- default:
- /* Nothing needs to be done */
- break;
- }
-}
-
-
-#endif /* USING_MALI_PMM */
-
diff --git a/drivers/media/video/samsung/mali/common/pmm/mali_pmm_policy.h b/drivers/media/video/samsung/mali/common/pmm/mali_pmm_policy.h
deleted file mode 100644
index 75ac8c8..0000000
--- a/drivers/media/video/samsung/mali/common/pmm/mali_pmm_policy.h
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- * 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_pmm_policy.h
- * Defines the power management module policies
- */
-
-#ifndef __MALI_PMM_POLICY_H__
-#define __MALI_PMM_POLICY_H__
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
-/**
- * @addtogroup pmmapi Power Management Module APIs
- *
- * @{
- *
- * @defgroup pmmapi_policy Power Management Module Policies
- *
- * @{
- */
-
-/** @brief Generic timer for use with policies
- */
-typedef struct _pmm_policy_timer
-{
- u32 timeout; /**< Timeout for this timer in ticks */
- mali_pmm_event_id event_id; /**< Event id that will be raised when timer expires */
- _mali_osk_timer_t *timer; /**< Timer */
- mali_bool set; /**< Timer set */
- mali_bool expired; /**< Timer expired - event needs to be raised */
- u32 start; /**< Timer start ticks */
-} _pmm_policy_timer_t;
-
-/** @brief Policy timer initialization
- *
- * This will create a timer for use in policies, but won't start it
- *
- * @param pptimer An empty timer structure to be initialized
- * @param timeout Timeout in ticks for the timer
- * @param id Event id that will be raised on timeout
- * @return _MALI_OSK_ERR_OK if the policy could be initialized, or a suitable
- * _mali_osk_errcode_t otherwise.
- */
-_mali_osk_errcode_t pmm_policy_timer_init( _pmm_policy_timer_t *pptimer, u32 timeout, mali_pmm_event_id id );
-
-/** @brief Policy timer termination
- *
- * This will clean up a timer that was previously used in policies, it
- * will also stop it if started
- *
- * @param pptimer An initialized timer structure to be terminated
- */
-void pmm_policy_timer_term( _pmm_policy_timer_t *pptimer );
-
-/** @brief Policy timer start
- *
- * This will start a previously created timer for use in policies
- * When the timer expires after the initialized timeout it will raise
- * a PMM event of the event id given on initialization
- * As data for the event it will pass the start time of the timer
- *
- * @param pptimer A previously initialized policy timer
- * @return MALI_TRUE if the timer was started, MALI_FALSE if it is already started
- */
-mali_bool pmm_policy_timer_start( _pmm_policy_timer_t *pptimer );
-
-/** @brief Policy timer stop
- *
- * This will stop a previously created timer for use in policies
- *
- * @param pptimer A previously started policy timer
- * @return MALI_TRUE if the timer was stopped, MALI_FALSE if it is already stopped
- */
-mali_bool pmm_policy_timer_stop( _pmm_policy_timer_t *pptimer );
-
-/** @brief Policy timer stop
- *
- * This raise an event for an expired timer
- *
- * @param pptimer An expired policy timer
- * @return MALI_TRUE if an event was raised, else MALI_FALSE
- */
-mali_bool pmm_policy_timer_raise_event( _pmm_policy_timer_t *pptimer );
-
-/** @brief Policy timer valid checker
- *
- * This will check that a timer was started after a given time
- *
- * @param timer_start Time the timer was started
- * @param other_start Time when another event or action occurred
- * @return MALI_TRUE if the timer was started after the other time, else MALI_FALSE
- */
-mali_bool pmm_policy_timer_valid( u32 timer_start, u32 other_start );
-
-
-/** @brief Common policy initialization
- *
- * This will initialize the current policy
- *
- * @note Any previously initialized policy should be terminated first
- *
- * @return _MALI_OSK_ERR_OK if the policy could be initialized, or a suitable
- * _mali_osk_errcode_t otherwise.
- */
-_mali_osk_errcode_t pmm_policy_init( _mali_pmm_internal_state_t *pmm );
-
-/** @brief Common policy termination
- *
- * This will terminate the current policy.
- * @note This can be called when a policy has not been initialized
- */
-void pmm_policy_term( _mali_pmm_internal_state_t *pmm );
-
-/** @brief Common policy state changer
- *
- * Given the next available event message, this routine passes it to
- * the current policy for processing
- *
- * @param pmm internal PMM state
- * @param event PMM event to process
- * @return _MALI_OSK_ERR_OK if the policy state completed okay, or a suitable
- * _mali_osk_errcode_t otherwise.
- */
-_mali_osk_errcode_t pmm_policy_process( _mali_pmm_internal_state_t *pmm, mali_pmm_message_t *event );
-
-
-/** @brief Common policy checker
- *
- * If a policy timer fires then this function will be called to
- * allow the policy to take the correct action
- *
- * @param pmm internal PMM state
- */
-void pmm_policy_check_policy( _mali_pmm_internal_state_t *pmm );
-
-/** @} */ /* End group pmmapi_policy */
-/** @} */ /* End group pmmapi */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __MALI_PMM_POLICY_H__ */
diff --git a/drivers/media/video/samsung/mali/common/pmm/mali_pmm_policy_alwayson.c b/drivers/media/video/samsung/mali/common/pmm/mali_pmm_policy_alwayson.c
deleted file mode 100644
index 0a6b471..0000000
--- a/drivers/media/video/samsung/mali/common/pmm/mali_pmm_policy_alwayson.c
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * 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_pmm_policy_alwayson.c
- * Implementation of the power management module policy - always on
- */
-
-#if USING_MALI_PMM
-
-#include "mali_ukk.h"
-#include "mali_kernel_common.h"
-
-#include "mali_pmm.h"
-#include "mali_pmm_system.h"
-#include "mali_pmm_state.h"
-#include "mali_pmm_policy_alwayson.h"
-
-_mali_osk_errcode_t pmm_policy_init_always_on(void)
-{
- /* Nothing to set up */
- MALI_SUCCESS;
-}
-
-void pmm_policy_term_always_on(void)
-{
- /* Nothing to tear down */
-}
-
-_mali_osk_errcode_t pmm_policy_process_always_on( _mali_pmm_internal_state_t *pmm, mali_pmm_message_t *event )
-{
- MALI_DEBUG_ASSERT_POINTER(pmm);
- MALI_DEBUG_ASSERT_POINTER(event);
-
- switch( event->id )
- {
- case MALI_PMM_EVENT_OS_POWER_DOWN:
- /* We aren't going to do anything, but signal so we don't block the OS
- * NOTE: This may adversely affect any jobs Mali is currently running
- */
- _mali_osk_pmm_power_down_done( event->data );
- break;
-
- case MALI_PMM_EVENT_INTERNAL_POWER_UP_ACK:
- case MALI_PMM_EVENT_INTERNAL_POWER_DOWN_ACK:
- /* Not expected in this policy */
- MALI_DEBUG_ASSERT( MALI_FALSE );
- break;
-
- case MALI_PMM_EVENT_OS_POWER_UP:
- /* Nothing to do */
- _mali_osk_pmm_power_up_done( event->data );
- break;
-
- case MALI_PMM_EVENT_JOB_SCHEDULED:
- case MALI_PMM_EVENT_JOB_QUEUED:
- case MALI_PMM_EVENT_JOB_FINISHED:
- /* Nothing to do - we are always on */
- break;
-
- case MALI_PMM_EVENT_TIMEOUT:
- /* Not expected in this policy */
- MALI_DEBUG_ASSERT( MALI_FALSE );
- break;
-
- default:
- MALI_ERROR(_MALI_OSK_ERR_ITEM_NOT_FOUND);
- }
-
- MALI_SUCCESS;
-}
-
-#endif
diff --git a/drivers/media/video/samsung/mali/common/pmm/mali_pmm_policy_alwayson.h b/drivers/media/video/samsung/mali/common/pmm/mali_pmm_policy_alwayson.h
deleted file mode 100644
index da13224..0000000
--- a/drivers/media/video/samsung/mali/common/pmm/mali_pmm_policy_alwayson.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * 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_pmm_policy_alwayson.h
- * Defines the power management module policy for always on
- */
-
-#ifndef __MALI_PMM_POLICY_ALWAYSON_H__
-#define __MALI_PMM_POLICY_ALWAYSON_H__
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
-/**
- * @addtogroup pmmapi_policy Power Management Module Policies
- *
- * @{
- */
-
-/** @brief Always on policy initialization
- *
- * @return _MALI_OSK_ERR_OK if the policy could be initialized, or a suitable
- * _mali_osk_errcode_t otherwise.
- */
-_mali_osk_errcode_t pmm_policy_init_always_on(void);
-
-/** @brief Always on policy termination
- */
-void pmm_policy_term_always_on(void);
-
-/** @brief Always on policy state changer
- *
- * Given the next available event message, this routine processes it
- * for the policy and changes state as needed.
- *
- * Always on policy will ignore all events and keep the Mali cores on
- * all the time
- *
- * @param pmm internal PMM state
- * @param event PMM event to process
- * @return _MALI_OSK_ERR_OK if the policy state completed okay, or a suitable
- * _mali_osk_errcode_t otherwise.
- */
-_mali_osk_errcode_t pmm_policy_process_always_on( _mali_pmm_internal_state_t *pmm, mali_pmm_message_t *event );
-
-/** @} */ /* End group pmmapi_policies */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __MALI_PMM_POLICY_ALWAYSON_H__ */
diff --git a/drivers/media/video/samsung/mali/common/pmm/mali_pmm_policy_jobcontrol.c b/drivers/media/video/samsung/mali/common/pmm/mali_pmm_policy_jobcontrol.c
deleted file mode 100644
index 237d702..0000000
--- a/drivers/media/video/samsung/mali/common/pmm/mali_pmm_policy_jobcontrol.c
+++ /dev/null
@@ -1,470 +0,0 @@
-/*
- * 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_pmm_policy_jobcontrol.c
- * Implementation of the power management module policy - job control
- */
-
-#if USING_MALI_PMM
-
-#include "mali_ukk.h"
-#include "mali_kernel_common.h"
-#include "mali_platform.h"
-
-#include "mali_pmm.h"
-#include "mali_pmm_system.h"
-#include "mali_pmm_state.h"
-#include "mali_pmm_policy.h"
-#include "mali_pmm_policy_jobcontrol.h"
-
-typedef struct _pmm_policy_data_job_control
-{
- _pmm_policy_timer_t latency; /**< Latency timeout timer for all cores */
- u32 core_active_start; /**< Last time a core was set to active */
- u32 timeout; /**< Timeout in ticks for latency timer */
-} _pmm_policy_data_job_control_t;
-
-
-/* @ brief Local data for this policy
- */
-static _pmm_policy_data_job_control_t *data_job_control = NULL;
-
-/* @brief Set up the timeout if it hasn't already been set and if there are active cores */
-static void job_control_timeout_setup( _mali_pmm_internal_state_t *pmm, _pmm_policy_timer_t *pptimer )
-{
- MALI_DEBUG_ASSERT_POINTER(pmm);
- MALI_DEBUG_ASSERT_POINTER(pptimer);
-
- /* Do we have an inactivity time out and some powered cores? */
- if( pptimer->timeout > 0 && pmm->cores_powered != 0 )
- {
- /* Is the system idle and all the powered cores are idle? */
- if( pmm->status == MALI_PMM_STATUS_IDLE && pmm->cores_idle == pmm->cores_powered )
- {
- if( pmm_policy_timer_start(pptimer) )
- {
- MALIPMM_DEBUG_PRINT( ("PMM policy - Job control: Setting in-activity latency timer\n") );
- }
- }
- else
- {
- /* We are not idle so there is no need for an inactivity timer
- */
- if( pmm_policy_timer_stop(pptimer) )
- {
- MALIPMM_DEBUG_PRINT( ("PMM policy - Job control: Removing in-activity latency timer\n") );
- }
- }
- }
-}
-
-/* @brief Check the validity of the timeout - and if there is one set */
-static mali_bool job_control_timeout_valid( _mali_pmm_internal_state_t *pmm, _pmm_policy_timer_t *pptimer, u32 timer_start )
-{
- MALI_DEBUG_ASSERT_POINTER(pmm);
- MALI_DEBUG_ASSERT_POINTER(pptimer);
-
- /* Not a valid timer! */
- if( pptimer->timeout == 0 ) return MALI_FALSE;
-
- /* Are some cores powered and are they all idle? */
- if( (pmm->cores_powered != 0) && (pmm->cores_idle == pmm->cores_powered) )
- {
- /* Has latency timeout started after the last core was active? */
- if( pmm_policy_timer_valid( timer_start, data_job_control->core_active_start ) )
- {
- return MALI_TRUE;
- }
- else
- {
- MALIPMM_DEBUG_PRINT( ("PMM: In-activity latency time out ignored - out of date\n") );
- }
- }
- else
- {
- if( pmm->cores_powered == 0 )
- {
- MALIPMM_DEBUG_PRINT( ("PMM: In-activity latency time out ignored - cores already off\n") );
- }
- else
- {
- MALIPMM_DEBUG_PRINT( ("PMM: In-activity latency time out ignored - cores active\n") );
- }
- }
-
- return MALI_FALSE;
-}
-
-_mali_osk_errcode_t pmm_policy_init_job_control( _mali_pmm_internal_state_t *pmm )
-{
- _mali_osk_errcode_t err;
- MALI_DEBUG_ASSERT_POINTER( pmm );
- MALI_DEBUG_ASSERT( data_job_control == NULL );
-
- data_job_control = (_pmm_policy_data_job_control_t *) _mali_osk_malloc(sizeof(*data_job_control));
- MALI_CHECK_NON_NULL( data_job_control, _MALI_OSK_ERR_NOMEM );
-
- data_job_control->core_active_start = _mali_osk_time_tickcount();
- data_job_control->timeout = MALI_PMM_POLICY_JOBCONTROL_INACTIVITY_TIMEOUT;
-
- err = pmm_policy_timer_init( &data_job_control->latency, data_job_control->timeout, MALI_PMM_EVENT_TIMEOUT );
- if( err != _MALI_OSK_ERR_OK )
- {
- _mali_osk_free( data_job_control );
- data_job_control = NULL;
- return err;
- }
-
- /* Start the latency timeout */
- job_control_timeout_setup( pmm, &data_job_control->latency );
-
- MALI_SUCCESS;
-}
-
-void pmm_policy_term_job_control(void)
-{
- if( data_job_control != NULL )
- {
- pmm_policy_timer_term( &data_job_control->latency );
- _mali_osk_free( data_job_control );
- data_job_control = NULL;
- }
-}
-
-static void pmm_policy_job_control_job_queued( _mali_pmm_internal_state_t *pmm )
-{
- mali_pmm_core_mask cores;
- mali_pmm_core_mask cores_subset;
-
- /* Make sure that all cores are powered in this
- * simple policy
- */
- cores = pmm->cores_registered;
- cores_subset = pmm_cores_to_power_up( pmm, cores );
- if( cores_subset != 0 )
- {
- /* There are some cores that need powering up */
- if( !pmm_invoke_power_up( pmm ) )
- {
- /* Need to wait until finished */
- pmm->status = MALI_PMM_STATUS_POLICY_POWER_UP;
- }
- }
-}
-
-_mali_osk_errcode_t pmm_policy_process_job_control( _mali_pmm_internal_state_t *pmm, mali_pmm_message_t *event )
-{
- mali_pmm_core_mask cores;
- mali_pmm_core_mask cores_subset;
- MALI_DEBUG_ASSERT_POINTER(pmm);
- MALI_DEBUG_ASSERT_POINTER(event);
- MALI_DEBUG_ASSERT_POINTER(data_job_control);
-
- MALIPMM_DEBUG_PRINT( ("PMM: Job control policy process start - status=%d\n", pmm->status) );
-
- /* Mainly the data is the cores */
- cores = pmm_cores_from_event_data( pmm, event );
-
-#if MALI_STATE_TRACKING
- pmm->mali_last_pmm_status = pmm->status;
-#endif /* MALI_STATE_TRACKING */
-
- switch( pmm->status )
- {
- /**************** IDLE ****************/
- case MALI_PMM_STATUS_IDLE:
- switch( event->id )
- {
- case MALI_PMM_EVENT_OS_POWER_UP:
- /* Not expected in this state */
- break;
-
- case MALI_PMM_EVENT_JOB_SCHEDULED:
-
- /* Update idle cores to indicate active - remove these! */
- pmm_cores_set_active( pmm, cores );
- /* Remember when this happened */
- data_job_control->core_active_start = event->ts;
-#if MALI_POWER_MGMT_TEST_SUITE
- _mali_osk_pmm_policy_events_notifications(MALI_PMM_EVENT_JOB_SCHEDULED);
-#endif
-
- /*** FALL THROUGH to QUEUED to check POWER UP ***/
-
- case MALI_PMM_EVENT_JOB_QUEUED:
-
- pmm_policy_job_control_job_queued( pmm );
-#if MALI_POWER_MGMT_TEST_SUITE
- _mali_osk_pmm_policy_events_notifications(MALI_PMM_EVENT_JOB_QUEUED);
-#endif
- break;
-
- case MALI_PMM_EVENT_DVFS_PAUSE:
-
- cores_subset = pmm_cores_to_power_down( pmm, cores, MALI_FALSE );
- if ( cores_subset != 0 )
- {
- if ( !pmm_power_down_okay( pmm ) )
- {
- pmm->is_dvfs_active = 1;
- pmm->status = MALI_PMM_STATUS_OS_POWER_DOWN;
- pmm_save_os_event_data( pmm, event->data );
- break;
- }
- }
- pmm->status = MALI_PMM_STATUS_DVFS_PAUSE;
- _mali_osk_pmm_dvfs_operation_done(0);
- break;
-
- case MALI_PMM_EVENT_OS_POWER_DOWN:
-
- /* Need to power down all cores even if we need to wait for them */
- cores_subset = pmm_cores_to_power_down( pmm, cores, MALI_FALSE );
- if( cores_subset != 0 )
- {
- /* There are some cores that need powering down */
- if( !pmm_invoke_power_down( pmm, MALI_POWER_MODE_DEEP_SLEEP ) )
- {
- /* We need to wait until they are idle */
-
- pmm->status = MALI_PMM_STATUS_OS_POWER_DOWN;
- /* Save the OS data to respond later */
- pmm_save_os_event_data( pmm, event->data );
- /* Exit this case - as we have to wait */
- break;
- }
- }
- else
- {
- mali_platform_power_mode_change(MALI_POWER_MODE_DEEP_SLEEP);
-
- }
- /* Set waiting status */
- pmm->status = MALI_PMM_STATUS_OS_WAITING;
- /* All cores now down - respond to OS power event */
- _mali_osk_pmm_power_down_done( event->data );
- break;
-
- case MALI_PMM_EVENT_JOB_FINISHED:
-
- /* Update idle cores - add these! */
- pmm_cores_set_idle( pmm, cores );
-#if MALI_POWER_MGMT_TEST_SUITE
- _mali_osk_pmm_policy_events_notifications(MALI_PMM_EVENT_JOB_FINISHED);
-#endif
- if( data_job_control->timeout > 0 )
- {
- /* Wait for time out to fire */
- break;
- }
- /* For job control policy - turn off all cores */
- cores = pmm->cores_powered;
-
- /*** FALL THROUGH to TIMEOUT TEST as NO TIMEOUT ***/
-
- case MALI_PMM_EVENT_TIMEOUT:
-
- /* Main job control policy - turn off cores after inactivity */
- if( job_control_timeout_valid( pmm, &data_job_control->latency, (u32)event->data ) )
- {
- /* Valid timeout of inactivity - so find out if we can power down
- * immedately - if we can't then this means the cores are still in fact
- * active
- */
- cores_subset = pmm_cores_to_power_down( pmm, cores, MALI_TRUE );
- if( cores_subset != 0 )
- {
- /* Check if we can really power down, if not then we are not
- * really in-active
- */
- if( !pmm_invoke_power_down( pmm, MALI_POWER_MODE_LIGHT_SLEEP ) )
- {
- pmm_power_down_cancel( pmm );
- }
- }
- /* else there are no cores powered up! */
- }
-#if MALI_POWER_MGMT_TEST_SUITE
- _mali_osk_pmm_policy_events_notifications(MALI_PMM_EVENT_TIMEOUT);
-#endif
- break;
-
- default:
- /* Unexpected event */
- MALI_ERROR(_MALI_OSK_ERR_ITEM_NOT_FOUND);
- }
- break;
-
- /******************DVFS PAUSE**************/
- case MALI_PMM_STATUS_DVFS_PAUSE:
- switch ( event->id )
- {
- case MALI_PMM_EVENT_DVFS_RESUME:
-
- if ( pmm->cores_powered != 0 )
- {
- pmm->cores_ack_down =0;
- pmm_power_down_cancel( pmm );
- pmm->status = MALI_PMM_STATUS_IDLE;
- }
- else
- {
- pmm_policy_job_control_job_queued( pmm );
- }
- _mali_osk_pmm_dvfs_operation_done( 0 );
- break;
-
- case MALI_PMM_EVENT_OS_POWER_DOWN:
- /* Set waiting status */
- pmm->status = MALI_PMM_STATUS_OS_WAITING;
- if ( pmm->cores_powered != 0 )
- {
- if ( pmm_invoke_power_down( pmm, MALI_POWER_MODE_DEEP_SLEEP ) )
- {
- _mali_osk_pmm_power_down_done( 0 );
- break;
- }
- }
- else
- {
- mali_platform_power_mode_change(MALI_POWER_MODE_DEEP_SLEEP);
- }
- _mali_osk_pmm_power_down_done( 0 );
- break;
- default:
- break;
- }
- break;
-
- /**************** POWER UP ****************/
- case MALI_PMM_STATUS_OS_POWER_UP:
- case MALI_PMM_STATUS_POLICY_POWER_UP:
- switch( event->id )
- {
- case MALI_PMM_EVENT_INTERNAL_POWER_UP_ACK:
- /* Make sure cores powered off equal what we expect */
- MALI_DEBUG_ASSERT( cores == pmm->cores_pend_up );
- pmm_cores_set_up_ack( pmm, cores );
-
- if( pmm_invoke_power_up( pmm ) )
- {
- if( pmm->status == MALI_PMM_STATUS_OS_POWER_UP )
- {
- /* Get the OS data and respond to the power up */
- _mali_osk_pmm_power_up_done( pmm_retrieve_os_event_data( pmm ) );
- }
- pmm->status = MALI_PMM_STATUS_IDLE;
- }
- break;
-
- default:
- /* Unexpected event */
- MALI_ERROR(_MALI_OSK_ERR_ITEM_NOT_FOUND);
- }
- break;
-
- /**************** POWER DOWN ****************/
- case MALI_PMM_STATUS_OS_POWER_DOWN:
- case MALI_PMM_STATUS_POLICY_POWER_DOWN:
- switch( event->id )
- {
-
- case MALI_PMM_EVENT_INTERNAL_POWER_DOWN_ACK:
-
- pmm_cores_set_down_ack( pmm, cores );
-
- if ( pmm->is_dvfs_active == 1 )
- {
- if( pmm_power_down_okay( pmm ) )
- {
- pmm->is_dvfs_active = 0;
- pmm->status = MALI_PMM_STATUS_DVFS_PAUSE;
- _mali_osk_pmm_dvfs_operation_done( pmm_retrieve_os_event_data( pmm ) );
- }
- break;
- }
-
- /* Now check if we can power down */
- if( pmm_invoke_power_down( pmm, MALI_POWER_MODE_DEEP_SLEEP ) )
- {
- if( pmm->status == MALI_PMM_STATUS_OS_POWER_DOWN )
- {
- /* Get the OS data and respond to the power down */
- _mali_osk_pmm_power_down_done( pmm_retrieve_os_event_data( pmm ) );
- }
- pmm->status = MALI_PMM_STATUS_OS_WAITING;
- }
- break;
-
- default:
- /* Unexpected event */
- MALI_ERROR(_MALI_OSK_ERR_ITEM_NOT_FOUND);
- }
- break;
-
- case MALI_PMM_STATUS_OS_WAITING:
- switch( event->id )
- {
- case MALI_PMM_EVENT_OS_POWER_UP:
- cores_subset = pmm_cores_to_power_up( pmm, cores );
- if( cores_subset != 0 )
- {
- /* There are some cores that need powering up */
- if( !pmm_invoke_power_up( pmm ) )
- {
- /* Need to wait until power up complete */
- pmm->status = MALI_PMM_STATUS_OS_POWER_UP;
- /* Save the OS data to respond later */
- pmm_save_os_event_data( pmm, event->data );
- /* Exit this case - as we have to wait */
- break;
- }
- }
- pmm->status = MALI_PMM_STATUS_IDLE;
- /* All cores now up - respond to OS power up event */
- _mali_osk_pmm_power_up_done( event->data );
- break;
-
- default:
- /* All other messages are ignored in this state */
- break;
- }
- break;
-
- default:
- /* Unexpected state */
- MALI_ERROR(_MALI_OSK_ERR_FAULT);
- }
-
- /* Set in-activity latency timer - if required */
- job_control_timeout_setup( pmm, &data_job_control->latency );
-
- /* Update the PMM state */
- pmm_update_system_state( pmm );
-#if MALI_STATE_TRACKING
- pmm->mali_new_event_status = event->id;
-#endif /* MALI_STATE_TRACKING */
-
- MALIPMM_DEBUG_PRINT( ("PMM: Job control policy process end - status=%d and event=%d\n", pmm->status,event->id) );
-
- MALI_SUCCESS;
-}
-
-void pmm_policy_check_job_control()
-{
- MALI_DEBUG_ASSERT_POINTER(data_job_control);
-
- /* Latency timer must have expired raise the event */
- pmm_policy_timer_raise_event(&data_job_control->latency);
-}
-
-
-#endif /* USING_MALI_PMM */
diff --git a/drivers/media/video/samsung/mali/common/pmm/mali_pmm_policy_jobcontrol.h b/drivers/media/video/samsung/mali/common/pmm/mali_pmm_policy_jobcontrol.h
deleted file mode 100644
index dcfa438..0000000
--- a/drivers/media/video/samsung/mali/common/pmm/mali_pmm_policy_jobcontrol.h
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * 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_pmm_policy.h
- * Defines the power management module policies
- */
-
-#ifndef __MALI_PMM_POLICY_JOBCONTROL_H__
-#define __MALI_PMM_POLICY_JOBCONTROL_H__
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
-/**
- * @addtogroup pmmapi_policy Power Management Module Policies
- *
- * @{
- */
-
-/** @brief The jobcontrol policy inactivity latency timeout (in ticks)
- * before the hardware is switched off
- *
- * @note Setting this low whilst tracing or producing debug output can
- * cause alot of timeouts to fire which can affect the PMM behaviour
- */
-#define MALI_PMM_POLICY_JOBCONTROL_INACTIVITY_TIMEOUT 50
-
-/** @brief Job control policy initialization
- *
- * @return _MALI_OSK_ERR_OK if the policy could be initialized, or a suitable
- * _mali_osk_errcode_t otherwise.
- */
-_mali_osk_errcode_t pmm_policy_init_job_control(_mali_pmm_internal_state_t *pmm);
-
-/** @brief Job control policy termination
- */
-void pmm_policy_term_job_control(void);
-
-/** @brief Job control policy state changer
- *
- * Given the next available event message, this routine processes it
- * for the policy and changes state as needed.
- *
- * Job control policy depends on events from the Mali cores, and will
- * power down all cores after an inactivity latency timeout. It will
- * power the cores back on again when a job is scheduled to run.
- *
- * @param pmm internal PMM state
- * @param event PMM event to process
- * @return _MALI_OSK_ERR_OK if the policy state completed okay, or a suitable
- * _mali_osk_errcode_t otherwise.
- */
-_mali_osk_errcode_t pmm_policy_process_job_control( _mali_pmm_internal_state_t *pmm, mali_pmm_message_t *event );
-
-/** @brief Job control policy checker
- *
- * The latency timer has fired and we need to raise the correct event to
- * handle it
- *
- * @param pmm internal PMM state
- */
-void pmm_policy_check_job_control(void);
-
-/** @} */ /* End group pmmapi_policy */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __MALI_PMM_POLICY_JOBCONTROL_H__ */
diff --git a/drivers/media/video/samsung/mali/common/pmm/mali_pmm_state.c b/drivers/media/video/samsung/mali/common/pmm/mali_pmm_state.c
deleted file mode 100644
index d529b9a..0000000
--- a/drivers/media/video/samsung/mali/common/pmm/mali_pmm_state.c
+++ /dev/null
@@ -1,716 +0,0 @@
-/*
- * 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.
- */
-
-#if USING_MALI_PMM
-
-#include "mali_ukk.h"
-#include "mali_kernel_common.h"
-#include "mali_kernel_subsystem.h"
-
-#include "mali_pmm.h"
-#include "mali_pmm_state.h"
-#include "mali_pmm_system.h"
-
-#include "mali_kernel_core.h"
-#include "mali_platform.h"
-
-#define SIZEOF_CORES_LIST 6
-
-/* NOTE: L2 *MUST* be first on the list so that it
- * is correctly powered on first and powered off last
- */
-static mali_pmm_core_id cores_list[] = { MALI_PMM_CORE_L2,
- MALI_PMM_CORE_GP,
- MALI_PMM_CORE_PP0,
- MALI_PMM_CORE_PP1,
- MALI_PMM_CORE_PP2,
- MALI_PMM_CORE_PP3 };
-
-
-
-void pmm_update_system_state( _mali_pmm_internal_state_t *pmm )
-{
- mali_pmm_state state;
-
- MALI_DEBUG_ASSERT_POINTER(pmm);
-
- if( pmm->cores_registered == 0 )
- {
- state = MALI_PMM_STATE_UNAVAILABLE;
- }
- else if( pmm->cores_powered == 0 )
- {
- state = MALI_PMM_STATE_SYSTEM_OFF;
- }
- else if( pmm->cores_powered == pmm->cores_registered )
- {
- state = MALI_PMM_STATE_SYSTEM_ON;
- }
- else
- {
- /* Some other state where not everything is on or off */
- state = MALI_PMM_STATE_SYSTEM_TRANSITION;
- }
-
-#if MALI_PMM_TRACE
- _mali_pmm_trace_state_change( pmm->state, state );
-#endif
- pmm->state = state;
-}
-
-mali_pmm_core_mask pmm_cores_from_event_data( _mali_pmm_internal_state_t *pmm, mali_pmm_message_t *event )
-{
- mali_pmm_core_mask cores;
- MALI_DEBUG_ASSERT_POINTER(pmm);
- MALI_DEBUG_ASSERT_POINTER(event);
-
- switch( event->id )
- {
- case MALI_PMM_EVENT_OS_POWER_UP:
- case MALI_PMM_EVENT_OS_POWER_DOWN:
- /* All cores - the system */
- cores = pmm->cores_registered;
- break;
-
- case MALI_PMM_EVENT_JOB_SCHEDULED:
- case MALI_PMM_EVENT_JOB_QUEUED:
- case MALI_PMM_EVENT_JOB_FINISHED:
- case MALI_PMM_EVENT_INTERNAL_POWER_UP_ACK:
- case MALI_PMM_EVENT_INTERNAL_POWER_DOWN_ACK:
- /* Currently the main event data is only the cores
- * for these messages
- */
- cores = (mali_pmm_core_mask)event->data;
- if( cores == MALI_PMM_CORE_SYSTEM )
- {
- cores = pmm->cores_registered;
- }
- else if( cores == MALI_PMM_CORE_PP_ALL )
- {
- /* Get the subset of registered PP cores */
- cores = (pmm->cores_registered & MALI_PMM_CORE_PP_ALL);
- }
- MALI_PMM_DEBUG_ASSERT_CORES_SUBSET( pmm->cores_registered, cores );
- break;
-
- default:
- /* Assume timeout messages - report cores still powered */
- cores = pmm->cores_powered;
- break;
- }
-
- return cores;
-}
-
-mali_pmm_core_mask pmm_cores_to_power_up( _mali_pmm_internal_state_t *pmm, mali_pmm_core_mask cores )
-{
- mali_pmm_core_mask cores_subset;
- MALI_DEBUG_ASSERT_POINTER(pmm);
- MALI_PMM_DEBUG_ASSERT_CORES_SUBSET( pmm->cores_registered, cores );
-
- /* Check that cores aren't pending power down when asked for power up */
- MALI_DEBUG_ASSERT( pmm->cores_pend_down == 0 );
-
- cores_subset = (~(pmm->cores_powered) & cores);
- if( cores_subset != 0 )
- {
- /* There are some cores that need powering up */
- pmm->cores_pend_up = cores_subset;
- }
-
- return cores_subset;
-}
-
-mali_pmm_core_mask pmm_cores_to_power_down( _mali_pmm_internal_state_t *pmm, mali_pmm_core_mask cores, mali_bool immediate_only )
-{
- mali_pmm_core_mask cores_subset;
- _mali_osk_errcode_t err;
- MALI_DEBUG_ASSERT_POINTER(pmm);
- MALI_PMM_DEBUG_ASSERT_CORES_SUBSET( pmm->cores_registered, cores );
-
- /* Check that cores aren't pending power up when asked for power down */
- MALI_DEBUG_ASSERT( pmm->cores_pend_up == 0 );
-
- cores_subset = (pmm->cores_powered & cores);
- if( cores_subset != 0 )
- {
- int n;
- volatile mali_pmm_core_mask *ppowered = &(pmm->cores_powered);
-
- /* There are some cores that need powering up, but we may
- * need to wait until they are idle
- */
- for( n = SIZEOF_CORES_LIST-1; n >= 0; n-- )
- {
- if( (cores_list[n] & cores_subset) != 0 )
- {
- /* Core is to be powered down */
- pmm->cores_pend_down |= cores_list[n];
-
- /* Can't hold the power lock, when acessing subsystem mutex via
- * the core power call.
- * Due to terminatation of driver requiring a subsystem mutex
- * and then power lock held to unregister a core.
- * This does mean that the following function could fail
- * as the core is unregistered before we tell it to power
- * down, but it does not matter as we are terminating
- */
-#if MALI_STATE_TRACKING
- pmm->mali_pmm_lock_acquired = 0;
-#endif /* MALI_STATE_TRACKING */
-
- MALI_PMM_UNLOCK(pmm);
- /* Signal the core to power down
- * If it is busy (not idle) it will set a pending power down flag
- * (as long as we don't want to only immediately power down).
- * If it isn't busy it will move out of the idle queue right
- * away
- */
- err = mali_core_signal_power_down( cores_list[n], immediate_only );
- MALI_PMM_LOCK(pmm);
-
-#if MALI_STATE_TRACKING
- pmm->mali_pmm_lock_acquired = 1;
-#endif /* MALI_STATE_TRACKING */
-
-
- /* Re-read cores_subset in case it has changed */
- cores_subset = (*ppowered & cores);
-
- if( err == _MALI_OSK_ERR_OK )
- {
- /* We moved an idle core to the power down queue
- * which means it is now acknowledged (if it is still
- * registered)
- */
- pmm->cores_ack_down |= (cores_list[n] & cores_subset);
- }
- else
- {
- MALI_DEBUG_PRINT(1,("PMM: In pmm_cores_to_power_down, the error and cores powered are..%x....%x",err,*ppowered));
- MALI_DEBUG_ASSERT( err == _MALI_OSK_ERR_BUSY ||
- (err == _MALI_OSK_ERR_FAULT &&
- (*ppowered & cores_list[n]) == 0) );
- /* If we didn't move a core - it must be active, so
- * leave it pending, so we get an acknowledgement (when
- * not in immediate only mode)
- * Alternatively we are shutting down and the core has
- * been unregistered
- */
- }
- }
- }
- }
-
- return cores_subset;
-}
-
-void pmm_power_down_cancel( _mali_pmm_internal_state_t *pmm )
-{
- int n;
- mali_pmm_core_mask pd, ad;
- _mali_osk_errcode_t err;
- volatile mali_pmm_core_mask *pregistered;
-
- MALI_DEBUG_ASSERT_POINTER(pmm);
-
- MALIPMM_DEBUG_PRINT( ("PMM: Cancelling power down\n") );
-
- pd = pmm->cores_pend_down;
- ad = pmm->cores_ack_down;
- /* Clear the pending cores so that they don't move to the off
- * queue if they haven't already
- */
- pmm->cores_pend_down = 0;
- pmm->cores_ack_down = 0;
- pregistered = &(pmm->cores_registered);
-
- /* Power up all the pending power down cores - just so
- * we make sure the system is in a known state, as a
- * pending core might have sent an acknowledged message
- * which hasn't been read yet.
- */
- for( n = 0; n < SIZEOF_CORES_LIST; n++ )
- {
- if( (cores_list[n] & pd) != 0 )
- {
- /* Can't hold the power lock, when acessing subsystem mutex via
- * the core power call.
- * Due to terminatation of driver requiring a subsystem mutex
- * and then power lock held to unregister a core.
- * This does mean that the following power up function could fail
- * as the core is unregistered before we tell it to power
- * up, but it does not matter as we are terminating
- */
-#if MALI_STATE_TRACKING
- pmm->mali_pmm_lock_acquired = 0;
-#endif /* MALI_STATE_TRACKING */
-
- MALI_PMM_UNLOCK(pmm);
- /* As we are cancelling - only move the cores back to the queue -
- * no reset needed
- */
- err = mali_core_signal_power_up( cores_list[n], MALI_TRUE );
- MALI_PMM_LOCK(pmm);
-#if MALI_STATE_TRACKING
- pmm->mali_pmm_lock_acquired = 1;
-#endif /* MALI_STATE_TRACKING */
-
- /* Update pending list with the current registered cores */
- pd &= (*pregistered);
-
- if( err != _MALI_OSK_ERR_OK )
- {
- MALI_DEBUG_ASSERT( (err == _MALI_OSK_ERR_BUSY &&
- ((cores_list[n] & ad) == 0)) ||
- (err == _MALI_OSK_ERR_FAULT &&
- (*pregistered & cores_list[n]) == 0) );
- /* If we didn't power up a core - it must be active and
- * hasn't actually tried to power down - this is expected
- * for cores that haven't acknowledged
- * Alternatively we are shutting down and the core has
- * been unregistered
- */
- }
- }
- }
- /* Only used in debug builds */
- MALI_IGNORE(ad);
-}
-
-
-mali_bool pmm_power_down_okay( _mali_pmm_internal_state_t *pmm )
-{
- MALI_DEBUG_ASSERT_POINTER(pmm);
-
- return ( pmm->cores_pend_down == pmm->cores_ack_down ? MALI_TRUE : MALI_FALSE );
-}
-
-mali_bool pmm_invoke_power_down( _mali_pmm_internal_state_t *pmm, mali_power_mode power_mode )
-{
- _mali_osk_errcode_t err;
- MALI_DEBUG_ASSERT_POINTER(pmm);
-
- /* Check that cores are pending power down during power down invoke */
- MALI_DEBUG_ASSERT( pmm->cores_pend_down != 0 );
- /* Check that cores are not pending power up during power down invoke */
- MALI_DEBUG_ASSERT( pmm->cores_pend_up == 0 );
-
- if( !pmm_power_down_okay( pmm ) )
- {
- MALIPMM_DEBUG_PRINT( ("PMM: Waiting for cores to go idle for power off - 0x%08x / 0x%08x\n",
- pmm->cores_pend_down, pmm->cores_ack_down) );
- return MALI_FALSE;
- }
- else
- {
- pmm->cores_powered &= ~(pmm->cores_pend_down);
-#if !MALI_PMM_NO_PMU
- err = malipmm_powerdown( pmm->cores_pend_down, power_mode);
-#else
- err = _MALI_OSK_ERR_OK;
-#endif
-
- if( err == _MALI_OSK_ERR_OK )
- {
-#if MALI_PMM_TRACE
- mali_pmm_core_mask old_power = pmm->cores_powered;
-#endif
- /* Remove powered down cores from idle and powered list */
- pmm->cores_idle &= ~(pmm->cores_pend_down);
- /* Reset pending/acknowledged status */
- pmm->cores_pend_down = 0;
- pmm->cores_ack_down = 0;
-#if MALI_PMM_TRACE
- _mali_pmm_trace_hardware_change( old_power, pmm->cores_powered );
-#endif
- }
- else
- {
- pmm->cores_powered |= pmm->cores_pend_down;
- MALI_PRINT_ERROR( ("PMM: Failed to get PMU to power down cores - (0x%x) %s",
- pmm->cores_pend_down, pmm_trace_get_core_name(pmm->cores_pend_down)) );
- pmm->fatal_power_err = MALI_TRUE;
- }
- }
-
- return MALI_TRUE;
-}
-
-
-mali_bool pmm_power_up_okay( _mali_pmm_internal_state_t *pmm )
-{
- MALI_DEBUG_ASSERT_POINTER(pmm);
-
- return ( pmm->cores_pend_up == pmm->cores_ack_up ? MALI_TRUE : MALI_FALSE );
-}
-
-
-mali_bool pmm_invoke_power_up( _mali_pmm_internal_state_t *pmm )
-{
- _mali_osk_errcode_t err;
-
- MALI_DEBUG_ASSERT_POINTER(pmm);
-
- /* Check that cores are pending power up during power up invoke */
- MALI_DEBUG_ASSERT( pmm->cores_pend_up != 0 );
- /* Check that cores are not pending power down during power up invoke */
- MALI_DEBUG_ASSERT( pmm->cores_pend_down == 0 );
-
- if( pmm_power_up_okay( pmm ) )
- {
- /* Power up has completed - sort out subsystem core status */
-
- int n;
- /* Use volatile to access, so that it is updated if any cores are unregistered */
- volatile mali_pmm_core_mask *ppendup = &(pmm->cores_pend_up);
-#if MALI_PMM_TRACE
- mali_pmm_core_mask old_power = pmm->cores_powered;
-#endif
- /* Move cores into idle queues */
- for( n = 0; n < SIZEOF_CORES_LIST; n++ )
- {
- if( (cores_list[n] & (*ppendup)) != 0 )
- {
- /* Can't hold the power lock, when acessing subsystem mutex via
- * the core power call.
- * Due to terminatation of driver requiring a subsystem mutex
- * and then power lock held to unregister a core.
- * This does mean that the following function could fail
- * as the core is unregistered before we tell it to power
- * up, but it does not matter as we are terminating
- */
-#if MALI_STATE_TRACKING
- pmm->mali_pmm_lock_acquired = 0;
-#endif /* MALI_STATE_TRACKING */
-
- MALI_PMM_UNLOCK(pmm);
- err = mali_core_signal_power_up( cores_list[n], MALI_FALSE );
- MALI_PMM_LOCK(pmm);
-
-#if MALI_STATE_TRACKING
- pmm->mali_pmm_lock_acquired = 1;
-#endif /* MALI_STATE_TRACKING */
-
-
- if( err != _MALI_OSK_ERR_OK )
- {
- MALI_DEBUG_PRINT(1,("In pmm_invoke_power_up:: The error and pending cores to be powered up are...%x...%x",err,*ppendup));
- MALI_DEBUG_ASSERT( (err == _MALI_OSK_ERR_FAULT &&
- (*ppendup & cores_list[n]) == 0) );
- /* We only expect this to fail when we are shutting down
- * and the core has been unregistered
- */
- }
- }
- }
- /* Finished power up - add cores to idle and powered list */
- pmm->cores_powered |= (*ppendup);
- pmm->cores_idle |= (*ppendup);
- /* Reset pending/acknowledge status */
- pmm->cores_pend_up = 0;
- pmm->cores_ack_up = 0;
-
-#if MALI_PMM_TRACE
- _mali_pmm_trace_hardware_change( old_power, pmm->cores_powered );
-#endif
- return MALI_TRUE;
- }
- else
- {
-#if !MALI_PMM_NO_PMU
- /* Power up must now be done */
- err = malipmm_powerup( pmm->cores_pend_up );
-#else
- err = _MALI_OSK_ERR_OK;
-#endif
- if( err != _MALI_OSK_ERR_OK )
- {
- MALI_PRINT_ERROR( ("PMM: Failed to get PMU to power up cores - (0x%x) %s",
- pmm->cores_pend_up, pmm_trace_get_core_name(pmm->cores_pend_up)) );
- pmm->fatal_power_err = MALI_TRUE;
- }
- else
- {
- /* TBD - Update core status immediately rather than use event message */
- _mali_uk_pmm_message_s event = {
- NULL,
- MALI_PMM_EVENT_INTERNAL_POWER_UP_ACK,
- 0 };
- /* All the cores that were pending power up, have now completed power up */
- event.data = pmm->cores_pend_up;
- _mali_ukk_pmm_event_message( &event );
- MALIPMM_DEBUG_PRINT( ("PMM: Sending ACK to power up") );
- }
- }
-
- /* Always return false, as we need an interrupt to acknowledge
- * when power up is complete
- */
- return MALI_FALSE;
-}
-
-mali_pmm_core_mask pmm_cores_set_active( _mali_pmm_internal_state_t *pmm, mali_pmm_core_mask cores )
-{
- MALI_DEBUG_ASSERT_POINTER(pmm);
- MALI_PMM_DEBUG_ASSERT_CORES_SUBSET( pmm->cores_registered, cores );
-
- pmm->cores_idle &= (~cores);
- return pmm->cores_idle;
-}
-
-mali_pmm_core_mask pmm_cores_set_idle( _mali_pmm_internal_state_t *pmm, mali_pmm_core_mask cores )
-{
- MALI_DEBUG_ASSERT_POINTER(pmm);
- MALI_PMM_DEBUG_ASSERT_CORES_SUBSET( pmm->cores_registered, cores );
-
- pmm->cores_idle |= (cores);
- return pmm->cores_idle;
-}
-
-mali_pmm_core_mask pmm_cores_set_down_ack( _mali_pmm_internal_state_t *pmm, mali_pmm_core_mask cores )
-{
- MALI_DEBUG_ASSERT_POINTER(pmm);
- MALI_PMM_DEBUG_ASSERT_CORES_SUBSET( pmm->cores_registered, cores );
-
- /* Check core is not pending a power down */
- MALI_DEBUG_ASSERT( (pmm->cores_pend_down & cores) != 0 );
- /* Check core has not acknowledged power down more than once */
- MALI_DEBUG_ASSERT( (pmm->cores_ack_down & cores) == 0 );
-
- pmm->cores_ack_down |= (cores);
-
- return pmm->cores_ack_down;
-}
-
-void pmm_fatal_reset( _mali_pmm_internal_state_t *pmm )
-{
- _mali_osk_errcode_t err = _MALI_OSK_ERR_OK;
- _mali_osk_notification_t *msg = NULL;
- mali_pmm_status status;
- MALI_DEBUG_ASSERT_POINTER(pmm);
- MALIPMM_DEBUG_PRINT( ("PMM: Fatal Reset called") );
-
- MALI_DEBUG_ASSERT( pmm->status != MALI_PMM_STATUS_OFF );
-
- /* Reset the common status */
- pmm->waiting = 0;
- pmm->missed = 0;
- pmm->fatal_power_err = MALI_FALSE;
- pmm->no_events = 0;
- pmm->check_policy = MALI_FALSE;
- pmm->cores_pend_down = 0;
- pmm->cores_pend_up = 0;
- pmm->cores_ack_down = 0;
- pmm->cores_ack_up = 0;
- pmm->is_dvfs_active = 0;
-#if MALI_PMM_TRACE
- pmm->messages_sent = 0;
- pmm->messages_received = 0;
- pmm->imessages_sent = 0;
- pmm->imessages_received = 0;
- MALI_PRINT( ("PMM Trace: *** Fatal reset occurred ***") );
-#endif
-
- /* Set that we are unavailable whilst resetting */
- pmm->state = MALI_PMM_STATE_UNAVAILABLE;
- status = pmm->status;
- pmm->status = MALI_PMM_STATUS_OFF;
-
- /* We want all cores powered */
- pmm->cores_powered = pmm->cores_registered;
- /* The cores may not be idle, but this state will be rectified later */
- pmm->cores_idle = pmm->cores_registered;
-
- /* So power on any cores that are registered */
- if( pmm->cores_registered != 0 )
- {
- int n;
- volatile mali_pmm_core_mask *pregistered = &(pmm->cores_registered);
-#if !MALI_PMM_NO_PMU
- err = malipmm_powerup( pmm->cores_registered );
-#endif
- if( err != _MALI_OSK_ERR_OK )
- {
- /* This is very bad as we can't even be certain the cores are now
- * powered up
- */
- MALI_PRINT_ERROR( ("PMM: Failed to perform PMM reset!\n") );
- /* TBD driver exit? */
- }
-
- for( n = SIZEOF_CORES_LIST-1; n >= 0; n-- )
- {
- if( (cores_list[n] & (*pregistered)) != 0 )
- {
-#if MALI_STATE_TRACKING
- pmm->mali_pmm_lock_acquired = 0;
-#endif /* MALI_STATE_TRACKING */
-
- MALI_PMM_UNLOCK(pmm);
- /* Core is now active - so try putting it in the idle queue */
- err = mali_core_signal_power_up( cores_list[n], MALI_FALSE );
- MALI_PMM_LOCK(pmm);
-#if MALI_STATE_TRACKING
- pmm->mali_pmm_lock_acquired = 1;
-#endif /* MALI_STATE_TRACKING */
-
- /* We either succeeded, or we were not off anyway, or we have
- * just be deregistered
- */
- MALI_DEBUG_ASSERT( (err == _MALI_OSK_ERR_OK) ||
- (err == _MALI_OSK_ERR_BUSY) ||
- (err == _MALI_OSK_ERR_FAULT &&
- (*pregistered & cores_list[n]) == 0) );
- }
- }
- }
-
- /* Unblock any pending OS event */
- if( status == MALI_PMM_STATUS_OS_POWER_UP )
- {
- /* Get the OS data and respond to the power up */
- _mali_osk_pmm_power_up_done( pmm_retrieve_os_event_data( pmm ) );
- }
- if( status == MALI_PMM_STATUS_OS_POWER_DOWN )
- {
- /* Get the OS data and respond to the power down
- * NOTE: We are not powered down at this point due to power problems,
- * so we are lying to the system, but something bad has already
- * happened and we are trying unstick things
- * TBD - Add busy loop to power down cores?
- */
- _mali_osk_pmm_power_down_done( pmm_retrieve_os_event_data( pmm ) );
- }
-
- /* Purge the event queues */
- do
- {
- if( _mali_osk_notification_queue_dequeue( pmm->iqueue, &msg ) == _MALI_OSK_ERR_OK )
- {
- _mali_osk_notification_delete ( msg );
- break;
- }
- } while (MALI_TRUE);
-
- do
- {
- if( _mali_osk_notification_queue_dequeue( pmm->queue, &msg ) == _MALI_OSK_ERR_OK )
- {
- _mali_osk_notification_delete ( msg );
- break;
- }
- } while (MALI_TRUE);
-
- /* Return status/state to normal */
- pmm->status = MALI_PMM_STATUS_IDLE;
- pmm_update_system_state(pmm);
-}
-
-mali_pmm_core_mask pmm_cores_set_up_ack( _mali_pmm_internal_state_t *pmm, mali_pmm_core_mask cores )
-{
- MALI_DEBUG_ASSERT_POINTER(pmm);
- MALI_PMM_DEBUG_ASSERT_CORES_SUBSET( pmm->cores_registered, cores );
-
- /* Check core is not pending a power up */
- MALI_DEBUG_ASSERT( (pmm->cores_pend_up & cores) != 0 );
- /* Check core has not acknowledged power up more than once */
- MALI_DEBUG_ASSERT( (pmm->cores_ack_up & cores) == 0 );
-
- pmm->cores_ack_up |= (cores);
-
- return pmm->cores_ack_up;
-}
-
-void pmm_save_os_event_data(_mali_pmm_internal_state_t *pmm, mali_pmm_message_data data)
-{
- MALI_DEBUG_ASSERT_POINTER(pmm);
- /* Check that there is no saved data */
- MALI_DEBUG_ASSERT( pmm->os_data == 0 );
- /* Can't store zero data - as retrieve check will fail */
- MALI_DEBUG_ASSERT( data != 0 );
-
- pmm->os_data = data;
-}
-
-mali_pmm_message_data pmm_retrieve_os_event_data(_mali_pmm_internal_state_t *pmm)
-{
- mali_pmm_message_data data;
-
- MALI_DEBUG_ASSERT_POINTER(pmm);
- /* Check that there is saved data */
- MALI_DEBUG_ASSERT( pmm->os_data != 0 );
-
- /* Get data, and clear the saved version */
- data = pmm->os_data;
- pmm->os_data = 0;
-
- return data;
-}
-
-/* Create list of core names to look up
- * We are doing it this way to overcome the need for
- * either string allocation, or stack space, so we
- * use constant strings instead
- */
-typedef struct pmm_trace_corelist
-{
- mali_pmm_core_mask id;
- const char *name;
-} pmm_trace_corelist_t;
-
-static pmm_trace_corelist_t pmm_trace_cores[] = {
- { MALI_PMM_CORE_SYSTEM, "SYSTEM" },
- { MALI_PMM_CORE_GP, "GP" },
- { MALI_PMM_CORE_L2, "L2" },
- { MALI_PMM_CORE_PP0, "PP0" },
- { MALI_PMM_CORE_PP1, "PP1" },
- { MALI_PMM_CORE_PP2, "PP2" },
- { MALI_PMM_CORE_PP3, "PP3" },
- { MALI_PMM_CORE_PP_ALL, "PP (all)" },
- { (MALI_PMM_CORE_GP | MALI_PMM_CORE_L2 | MALI_PMM_CORE_PP0),
- "GP+L2+PP0" },
- { (MALI_PMM_CORE_GP | MALI_PMM_CORE_PP0),
- "GP+PP0" },
- { (MALI_PMM_CORE_GP | MALI_PMM_CORE_L2 | MALI_PMM_CORE_PP0 | MALI_PMM_CORE_PP1),
- "GP+L2+PP0+PP1" },
- { (MALI_PMM_CORE_GP | MALI_PMM_CORE_PP0 | MALI_PMM_CORE_PP1),
- "GP+PP0+PP1" },
- { 0, NULL } /* Terminator of list */
-};
-
-const char *pmm_trace_get_core_name( mali_pmm_core_mask cores )
-{
- const char *dname = NULL;
- int cl;
-
- /* Look up name in corelist */
- cl = 0;
- while( pmm_trace_cores[cl].name != NULL )
- {
- if( pmm_trace_cores[cl].id == cores )
- {
- dname = pmm_trace_cores[cl].name;
- break;
- }
- cl++;
- }
-
- if( dname == NULL )
- {
- /* We don't know a good short-hand for the configuration */
- dname = "[multi-core]";
- }
-
- return dname;
-}
-
-#endif /* USING_MALI_PMM */
-
diff --git a/drivers/media/video/samsung/mali/common/pmm/mali_pmm_state.h b/drivers/media/video/samsung/mali/common/pmm/mali_pmm_state.h
deleted file mode 100644
index 4768344..0000000
--- a/drivers/media/video/samsung/mali/common/pmm/mali_pmm_state.h
+++ /dev/null
@@ -1,290 +0,0 @@
-/*
- * 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_PMM_STATE_H__
-#define __MALI_PMM_STATE_H__
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
-/**
- * @addtogroup pmmapi Power Management Module APIs
- *
- * @{
- *
- * @defgroup pmmapi_state Power Management Module State
- *
- * @{
- */
-
-/* Check that the subset is really a subset of cores */
-#define MALI_PMM_DEBUG_ASSERT_CORES_SUBSET( cores, subset ) \
- MALI_DEBUG_ASSERT( ((~(cores)) & (subset)) == 0 )
-
-
-/* Locking macros */
-#define MALI_PMM_LOCK(pmm) \
- _mali_osk_lock_wait( pmm->lock, _MALI_OSK_LOCKMODE_RW )
-#define MALI_PMM_UNLOCK(pmm) \
- _mali_osk_lock_signal( pmm->lock, _MALI_OSK_LOCKMODE_RW )
-#define MALI_PMM_LOCK_TERM(pmm) \
- _mali_osk_lock_term( pmm->lock )
-
-/* Notification type for messages */
-#define MALI_PMM_NOTIFICATION_TYPE 0
-
-/** @brief Status of the PMM state machine
- */
-typedef enum mali_pmm_status_tag
-{
- MALI_PMM_STATUS_IDLE, /**< PMM is waiting next event */
- MALI_PMM_STATUS_POLICY_POWER_DOWN, /**< Policy initiated power down */
- MALI_PMM_STATUS_POLICY_POWER_UP, /**< Policy initiated power down */
- MALI_PMM_STATUS_OS_WAITING, /**< PMM is waiting for OS power up */
- MALI_PMM_STATUS_OS_POWER_DOWN, /**< OS initiated power down */
- MALI_PMM_STATUS_DVFS_PAUSE, /**< PMM DVFS Status Pause */
- MALI_PMM_STATUS_OS_POWER_UP, /**< OS initiated power up */
- MALI_PMM_STATUS_OFF, /**< PMM is not active */
-} mali_pmm_status;
-
-
-/** @brief Internal state of the PMM
- */
-typedef struct _mali_pmm_internal_state
-{
- mali_pmm_status status; /**< PMM state machine */
- mali_pmm_policy policy; /**< PMM policy */
- mali_bool check_policy; /**< PMM policy needs checking */
- mali_pmm_state state; /**< PMM state */
- mali_pmm_core_mask cores_registered; /**< Bitmask of cores registered */
- mali_pmm_core_mask cores_powered; /**< Bitmask of cores powered up */
- mali_pmm_core_mask cores_idle; /**< Bitmask of cores idle */
- mali_pmm_core_mask cores_pend_down; /**< Bitmask of cores pending power down */
- mali_pmm_core_mask cores_pend_up; /**< Bitmask of cores pending power up */
- mali_pmm_core_mask cores_ack_down; /**< Bitmask of cores acknowledged power down */
- mali_pmm_core_mask cores_ack_up; /**< Bitmask of cores acknowledged power up */
-
- _mali_osk_notification_queue_t *queue; /**< PMM event queue */
- _mali_osk_notification_queue_t *iqueue; /**< PMM internal event queue */
- _mali_osk_irq_t *irq; /**< PMM irq handler */
- _mali_osk_lock_t *lock; /**< PMM lock */
-
- mali_pmm_message_data os_data; /**< OS data sent via the OS events */
-
- mali_bool pmu_initialized; /**< PMU initialized */
-
- _mali_osk_atomic_t messages_queued; /**< PMM event messages queued */
- u32 waiting; /**< PMM waiting events - due to busy */
- u32 no_events; /**< PMM called to process when no events */
-
- u32 missed; /**< PMM missed events due to OOM */
- mali_bool fatal_power_err; /**< PMM has had a fatal power error? */
- u32 is_dvfs_active; /**< PMM DVFS activity */
-
-#if MALI_STATE_TRACKING
- mali_pmm_status mali_last_pmm_status; /**< The previous PMM status */
- mali_pmm_event_id mali_new_event_status;/**< The type of the last PMM event */
- mali_bool mali_pmm_lock_acquired; /**< Is the PMM lock held somewhere or not */
-#endif
-
-#if (MALI_PMM_TRACE || MALI_STATE_TRACKING)
- u32 messages_sent; /**< Total event messages sent */
- u32 messages_received; /**< Total event messages received */
- u32 imessages_sent; /**< Total event internal messages sent */
- u32 imessages_received; /**< Total event internal messages received */
-#endif
-} _mali_pmm_internal_state_t;
-
-/** @brief Sets that a policy needs a check before processing events
- *
- * A timer or something has expired that needs dealing with
- */
-void malipmm_set_policy_check(void);
-
-/** @brief Update the PMM externally viewable state depending on the current PMM internal state
- *
- * @param pmm internal PMM state
- * @return MALI_TRUE if the timeout is valid, else MALI_FALSE
- */
-void pmm_update_system_state( _mali_pmm_internal_state_t *pmm );
-
-/** @brief Returns the core mask from the event data - if applicable
- *
- * @param pmm internal PMM state
- * @param event event message to get the core mask from
- * @return mask of cores that is relevant to this event message
- */
-mali_pmm_core_mask pmm_cores_from_event_data( _mali_pmm_internal_state_t *pmm, mali_pmm_message_t *event );
-
-/** @brief Sort out which cores need to be powered up from the given core mask
- *
- * All cores that can be powered up will be put into a pending state
- *
- * @param pmm internal PMM state
- * @param cores mask of cores to check if they need to be powered up
- * @return mask of cores that need to be powered up, this can be 0 if all cores
- * are powered up already
- */
-mali_pmm_core_mask pmm_cores_to_power_up( _mali_pmm_internal_state_t *pmm, mali_pmm_core_mask cores );
-
-/** @brief Sort out which cores need to be powered down from the given core mask
- *
- * All cores that can be powered down will be put into a pending state. If they
- * can be powered down immediately they will also be acknowledged that they can be
- * powered down. If the immediate_only flag is set, then only those cores that
- * can be acknowledged for power down will be put into a pending state.
- *
- * @param pmm internal PMM state
- * @param cores mask of cores to check if they need to be powered down
- * @param immediate_only MALI_TRUE means that only cores that can power down now will
- * be put into a pending state
- * @return mask of cores that need to be powered down, this can be 0 if all cores
- * are powered down already
- */
-mali_pmm_core_mask pmm_cores_to_power_down( _mali_pmm_internal_state_t *pmm, mali_pmm_core_mask cores, mali_bool immediate_only );
-
-/** @brief Cancel an invokation to power down (pmm_invoke_power_down)
- *
- * @param pmm internal PMM state
- */
-void pmm_power_down_cancel( _mali_pmm_internal_state_t *pmm );
-
-/** @brief Check if a call to invoke power down should succeed, or fail
- *
- * This will report MALI_FALSE if some of the cores are still active and need
- * to acknowledge that they are ready to power down
- *
- * @param pmm internal PMM state
- * @return MALI_TRUE if the pending cores to power down have acknowledged they
- * can power down, else MALI_FALSE
- */
-mali_bool pmm_power_down_okay( _mali_pmm_internal_state_t *pmm );
-
-/** @brief Try to make all the pending cores power down
- *
- * If all the pending cores have acknowledged they can power down, this will call the
- * PMU power down function to turn them off
- *
- * @param pmm internal PMM state
- * @return MALI_TRUE if the pending cores have been powered down, else MALI_FALSE
- */
-mali_bool pmm_invoke_power_down( _mali_pmm_internal_state_t *pmm, mali_power_mode power_mode );
-
-/** @brief Check if all the pending cores to power up have done so
- *
- * This will report MALI_FALSE if some of the cores are still powered off
- * and have not acknowledged that they have powered up
- *
- * @param pmm internal PMM state
- * @return MALI_TRUE if the pending cores to power up have acknowledged they
- * are now powered up, else MALI_FALSE
- */
-mali_bool pmm_power_up_okay( _mali_pmm_internal_state_t *pmm );
-
-/** @brief Try to make all the pending cores power up
- *
- * If all the pending cores have acknowledged they have powered up, this will
- * make the cores start processing jobs again, else this will call the PMU
- * power up function to turn them on, and the PMM is then expected to wait for an
- * interrupt to acknowledge the power up
- *
- * @param pmm internal PMM state
- * @return MALI_TRUE if the pending cores have been powered up, else MALI_FALSE
- */
-mali_bool pmm_invoke_power_up( _mali_pmm_internal_state_t *pmm );
-
-/** @brief Set the cores that are now active in the system
- *
- * Updates which cores are active and returns which cores are still idle
- *
- * @param pmm internal PMM state
- * @param cores mask of cores to set to active
- * @return mask of all the cores that are idle
- */
-mali_pmm_core_mask pmm_cores_set_active( _mali_pmm_internal_state_t *pmm, mali_pmm_core_mask cores );
-
-/** @brief Set the cores that are now idle in the system
- *
- * Updates which cores are idle and returns which cores are still idle
- *
- * @param pmm internal PMM state
- * @param cores mask of cores to set to idle
- * @return mask of all the cores that are idle
- */
-mali_pmm_core_mask pmm_cores_set_idle( _mali_pmm_internal_state_t *pmm, mali_pmm_core_mask cores );
-
-/** @brief Set the cores that have acknowledged a pending power down
- *
- * Updates which cores have acknowledged the pending power down and are now ready
- * to be turned off
- *
- * @param pmm internal PMM state
- * @param cores mask of cores that have acknowledged the pending power down
- * @return mask of all the cores that have acknowledged the power down
- */
-mali_pmm_core_mask pmm_cores_set_down_ack( _mali_pmm_internal_state_t *pmm, mali_pmm_core_mask cores );
-
-/** @brief Set the cores that have acknowledged a pending power up
- *
- * Updates which cores have acknowledged the pending power up and are now
- * fully powered and ready to run jobs
- *
- * @param pmm internal PMM state
- * @param cores mask of cores that have acknowledged the pending power up
- * @return mask of all the cores that have acknowledged the power up
- */
-mali_pmm_core_mask pmm_cores_set_up_ack( _mali_pmm_internal_state_t *pmm, mali_pmm_core_mask cores );
-
-
-/** @brief Tries to reset the PMM and PMU hardware to a known state after any fatal issues
- *
- * This will try and make all the cores powered up and reset the PMM state
- * to its initial state after core registration - all cores powered but not
- * pending or active.
- * All events in the event queues will be thrown away.
- *
- * @note: Any pending power down will be cancelled including the OS calling for power down
- */
-void pmm_fatal_reset( _mali_pmm_internal_state_t *pmm );
-
-/** @brief Save the OS specific data for an OS power up/down event
- *
- * @param pmm internal PMM state
- * @param data OS specific event data
- */
-void pmm_save_os_event_data(_mali_pmm_internal_state_t *pmm, mali_pmm_message_data data);
-
-/** @brief Retrieve the OS specific data for an OS power up/down event
- *
- * This will clear the stored OS data, as well as return it.
- *
- * @param pmm internal PMM state
- * @return OS specific event data that was saved previously
- */
-mali_pmm_message_data pmm_retrieve_os_event_data(_mali_pmm_internal_state_t *pmm);
-
-
-/** @brief Get a human readable name for the cores in a core mask
- *
- * @param core the core mask
- * @return string containing a name relating to the given core mask
- */
-const char *pmm_trace_get_core_name( mali_pmm_core_mask core );
-
-/** @} */ /* End group pmmapi_state */
-/** @} */ /* End group pmmapi */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __MALI_PMM_STATE_H__ */
diff --git a/drivers/media/video/samsung/mali/common/pmm/mali_pmm_system.h b/drivers/media/video/samsung/mali/common/pmm/mali_pmm_system.h
deleted file mode 100644
index eccd35b..0000000
--- a/drivers/media/video/samsung/mali/common/pmm/mali_pmm_system.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * 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_PMM_SYSTEM_H__
-#define __MALI_PMM_SYSTEM_H__
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
-/**
- * @addtogroup pmmapi Power Management Module APIs
- *
- * @{
- *
- * @defgroup pmmapi_system Power Management Module System Functions
- *
- * @{
- */
-
-extern struct mali_kernel_subsystem mali_subsystem_pmm;
-
-/** @brief Register a core with the PMM, which will power up
- * the core
- *
- * @param core the core to register with the PMM
- * @return error if the core cannot be powered up
- */
-_mali_osk_errcode_t malipmm_core_register( mali_pmm_core_id core );
-
-/** @brief Unregister a core with the PMM
- *
- * @param core the core to unregister with the PMM
- */
-void malipmm_core_unregister( mali_pmm_core_id core );
-
-/** @brief Acknowledge that a power down is okay to happen
- *
- * A core should not be running a job, or be in the idle queue when this
- * is called.
- *
- * @param core the core that can now be powered down
- */
-void malipmm_core_power_down_okay( mali_pmm_core_id core );
-
-/** @} */ /* End group pmmapi_system */
-/** @} */ /* End group pmmapi */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __MALI_PMM_H__ */
diff --git a/drivers/media/video/samsung/mali/common/mali_kernel_gp.h b/drivers/media/video/samsung/mali/include/linux/mali/mali_utgard.h
index efd3b43..7c78947 100644
--- a/drivers/media/video/samsung/mali/common/mali_kernel_gp.h
+++ b/drivers/media/video/samsung/mali/include/linux/mali/mali_utgard.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 ARM Limited. All rights reserved.
+ * 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.
@@ -8,14 +8,21 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __MALI_KERNEL_GP2_H__
-#define __MALI_KERNEL_GP2_H__
+#ifndef __MALI_UTGARD_H__
+#define __MALI_UTGARD_H__
-extern struct mali_kernel_subsystem mali_subsystem_gp2;
+/** @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);
-#if USING_MALI_PMM
-_mali_osk_errcode_t maligp_signal_power_up( mali_bool queue_only );
-_mali_osk_errcode_t maligp_signal_power_down( mali_bool immediate_only );
-#endif
+#endif /* __MALI_UTGARD_H__ */
-#endif /* __MALI_KERNEL_GP2_H__ */
diff --git a/drivers/media/video/samsung/mali/include/linux/mali/mali_utgard_counters.h b/drivers/media/video/samsung/mali/include/linux/mali/mali_utgard_counters.h
new file mode 100644
index 0000000..40822f7
--- /dev/null
+++ b/drivers/media/video/samsung/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 + 19,
+ 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/media/video/samsung/mali/include/linux/mali/mali_utgard_ioctl.h b/drivers/media/video/samsung/mali/include/linux/mali/mali_utgard_ioctl.h
new file mode 100644
index 0000000..31af4cf
--- /dev/null
+++ b/drivers/media/video/samsung/mali/include/linux/mali/mali_utgard_ioctl.h
@@ -0,0 +1,80 @@
+/*
+ * 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_GET_SYSTEM_INFO_SIZE _IOR (MALI_IOC_CORE_BASE, _MALI_UK_GET_SYSTEM_INFO_SIZE, _mali_uk_get_system_info_s *)
+#define MALI_IOC_GET_SYSTEM_INFO _IOR (MALI_IOC_CORE_BASE, _MALI_UK_GET_SYSTEM_INFO, _mali_uk_get_system_info_s *)
+#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_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_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_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_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/media/video/samsung/mali/include/linux/mali/mali_utgard_profiling_events.h b/drivers/media/video/samsung/mali/include/linux/mali/mali_utgard_profiling_events.h
new file mode 100644
index 0000000..129526f
--- /dev/null
+++ b/drivers/media/video/samsung/mali/include/linux/mali/mali_utgard_profiling_events.h
@@ -0,0 +1,121 @@
+/*
+ * 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_ENTER_API_FUNC = 10,
+ MALI_PROFILING_EVENT_REASON_SINGLE_SW_LEAVE_API_FUNC = 11,
+ 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,
+} 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
+ */
+typedef enum
+{
+ MALI_PROFILING_EVENT_REASON_START_STOP_SW_NONE = 0,
+ MALI_PROFILING_EVENT_REASON_START_STOP_MALI = 1,
+} 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,
+ MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_PIPELINE_FULL = 1,
+ MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_VSYNC = 26,
+ MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_FB_IFRAME_WAIT = 27,
+ MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_FB_IFRAME_SYNC = 28,
+ MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_VG_WAIT_FILTER_CLEANUP = 29,
+ MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_VG_WAIT_TEXTURE = 30,
+ MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_GLES_WAIT_MIPLEVEL = 31,
+ MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_GLES_WAIT_READPIXELS = 32,
+ MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_EGL_WAIT_SWAP_IMMEDIATE= 33,
+ MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_ICS_QUEUE_BUFFER = 34,
+ MALI_PROFILING_EVENT_REASON_SUSPEND_RESUME_SW_ICS_DEQUEUE_BUFFER = 35,
+} 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,
+} cinstr_profiling_event_reason_single_gpu_t;
+
+#endif /*_MALI_UTGARD_PROFILING_EVENTS_H_*/
diff --git a/drivers/media/video/samsung/mali/common/mali_uk_types.h b/drivers/media/video/samsung/mali/include/linux/mali/mali_utgard_uk_types.h
index e114fa8..512b1e2 100644
--- a/drivers/media/video/samsung/mali/common/mali_uk_types.h
+++ b/drivers/media/video/samsung/mali/include/linux/mali/mali_utgard_uk_types.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 ARM Limited. All rights reserved.
+ * 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.
@@ -13,15 +13,8 @@
* Defines the types and constants used in the user-kernel interface
*/
-#ifndef __MALI_UK_TYPES_H__
-#define __MALI_UK_TYPES_H__
-
-/*
- * NOTE: Because this file can be included from user-side and kernel-side,
- * it is up to the includee to ensure certain typedefs (e.g. u32) are already
- * defined when #including this.
- */
-#include "regs/mali_200_regs.h"
+#ifndef __MALI_UTGARD_UK_TYPES_H__
+#define __MALI_UTGARD_UK_TYPES_H__
#ifdef __cplusplus
extern "C"
@@ -75,6 +68,8 @@ typedef enum
_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] */
/** Memory functions */
@@ -95,21 +90,19 @@ typedef enum
/** Common functions for each core */
_MALI_UK_START_JOB = 0, /**< Start a Fragment/Vertex Processor Job on a core */
- _MALI_UK_ABORT_JOB, /**< Abort a job */
_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_PP_ABORT_JOB = _MALI_UK_ABORT_JOB, /**< _mali_ukk_pp_abort_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_GP_ABORT_JOB = _MALI_UK_ABORT_JOB, /**< _mali_ukk_gp_abort_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() */
@@ -122,12 +115,7 @@ typedef enum
_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_TRANSFER_SW_COUNTERS,
-
-#if USING_MALI_PMM
- /** Power Management Module Functions */
- _MALI_UK_PMM_EVENT_MESSAGE = 0, /**< Raise an event message */
-#endif
+ _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() */
@@ -370,18 +358,9 @@ typedef struct
typedef enum
{
_MALI_UK_START_JOB_STARTED, /**< Job started */
- _MALI_UK_START_JOB_STARTED_LOW_PRI_JOB_RETURNED, /**< Job started and bumped a lower priority job that was pending execution */
_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 starting a Vertex or Fragment processor job */
-typedef enum
-{
- MALI_UK_START_JOB_FLAG_DEFAULT = 0, /**< Default behaviour; Flush L2 caches before start, no following jobs */
- MALI_UK_START_JOB_FLAG_NO_FLUSH = 1, /**< No need to flush L2 caches before start */
- MALI_UK_START_JOB_FLAG_MORE_JOBS_FOLLOW = 2, /**< More related jobs follows, try to schedule them as soon as possible after this job */
-} _mali_uk_start_job_flags;
-
/** @brief Status indicating the result of the execution of a Vertex or Fragment processor job */
typedef enum
@@ -421,10 +400,7 @@ typedef enum
* 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. If the job had a higher priority than the one currently pending
- * execution (@c _MALI_UK_START_JOB_STARTED_LOW_PRI_JOB_RETURNED), it will bump
- * the lower priority job and returns the address of the @c mali_gp_job_info
- * for that job in @c returned_user_job_ptr. That job should get requeued.
+ * 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
@@ -461,25 +437,16 @@ 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 watchdog_msecs; /**< [in] maximum allowed runtime in milliseconds. The job gets killed if it runs longer than this. A value of 0 selects the default used by the device driver. */
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 returned_user_job_ptr; /**< [out] identifier for the returned job in user space, a @c mali_gp_job_info* */
- _mali_uk_start_job_status status; /**< [out] indicates job start status (success, previous job returned, requeue) */
- u32 abort_id; /**< [in] abort id of this job, used to identify this job for later abort requests */
- u32 perf_counter_l2_src0; /**< [in] soruce id for Mali-400 MP L2 cache performance counter 0 */
- u32 perf_counter_l2_src1; /**< [in] source id for Mali-400 MP L2 cache performance counter 1 */
- u32 frame_builder_id; /**< [in] id of the originating frame builder */
- u32 flush_id; /**< [in] flush id within the originating frame builder */
+ 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 */
-#define _MALI_PERFORMANCE_COUNTER_FLAG_L2_SRC0_ENABLE (1<<2) /**< Enable performance counter L2_SRC0 for a job */
-#define _MALI_PERFORMANCE_COUNTER_FLAG_L2_SRC1_ENABLE (1<<3) /**< Enable performance counter L2_SRC1 for a job */
-#define _MALI_PERFORMANCE_COUNTER_FLAG_L2_RESET (1<<4) /**< Enable performance counter L2_RESET for a job */
/** @} */ /* end group _mali_uk_gpstartjob_s */
@@ -487,20 +454,9 @@ 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 irq_status; /**< [out] value of the GP interrupt rawstat register (see ARM DDI0415A) */
- u32 status_reg_on_stop; /**< [out] value of the GP control register */
- u32 vscl_stop_addr; /**< [out] value of the GP VLSCL start register */
- u32 plbcl_stop_addr; /**< [out] value of the GP PLBCL start register */
u32 heap_current_addr; /**< [out] value of the GP PLB PL heap start address register */
- u32 perf_counter_src0; /**< [out] source id for performance counter 0 (see ARM DDI0415A, Table 3-60) */
- u32 perf_counter_src1; /**< [out] source id for performance counter 1 (see ARM DDI0415A, Table 3-60) */
u32 perf_counter0; /**< [out] value of perfomance counter 0 (see ARM DDI0415A) */
u32 perf_counter1; /**< [out] value of perfomance counter 1 (see ARM DDI0415A) */
- u32 render_time; /**< [out] number of microseconds it took for the job to render */
- u32 perf_counter_l2_src0; /**< [out] soruce id for Mali-400 MP L2 cache performance counter 0 */
- u32 perf_counter_l2_src1; /**< [out] soruce id for Mali-400 MP L2 cache performance counter 1 */
- u32 perf_counter_l2_val0; /**< [out] Value of the Mali-400 MP L2 cache performance counter 0 */
- u32 perf_counter_l2_val1; /**< [out] Value of the Mali-400 MP L2 cache performance counter 1 */
} _mali_uk_gp_job_finished_s;
typedef enum _maligp_job_suspended_reason
@@ -521,6 +477,12 @@ typedef struct
/** @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)
+
/** @defgroup _mali_uk_ppstartjob_s Fragment Processor Start Job
* @{ */
@@ -546,10 +508,7 @@ typedef struct
* 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. If the job had a higher priority than the one currently pending
- * execution (@c _MALI_UK_START_JOB_STARTED_LOW_PRI_JOB_RETURNED), it will bump
- * the lower priority job and returns the address of the @c mali_pp_job
- * for that job in @c returned_user_job_ptr. That job should get requeued.
+ * tried again.
*
* After the job has started, _mali_wait_for_notification() will be notified
* when the job finished. The notification will contain a
@@ -573,43 +532,48 @@ 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 watchdog_msecs; /**< [in] maximum allowed runtime in milliseconds. The job gets killed if it runs longer than this. A value of 0 selects the default used by the device driver. */
- u32 frame_registers[MALI200_NUM_REGS_FRAME]; /**< [in] core specific registers associated with this job, see ARM DDI0415A */
- u32 wb0_registers[MALI200_NUM_REGS_WBx];
- u32 wb1_registers[MALI200_NUM_REGS_WBx];
- u32 wb2_registers[MALI200_NUM_REGS_WBx];
+ 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 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 returned_user_job_ptr; /**< [out] identifier for the returned job in user space */
- _mali_uk_start_job_status status; /**< [out] indicates job start status (success, previous job returned, requeue) */
- u32 abort_id; /**< [in] abort id of this job, used to identify this job for later abort requests */
- u32 perf_counter_l2_src0; /**< [in] soruce id for Mali-400 MP L2 cache performance counter 0 */
- u32 perf_counter_l2_src1; /**< [in] source id for Mali-400 MP L2 cache performance counter 1 */
- u32 frame_builder_id; /**< [in] id of the originating frame builder */
- u32 flush_id; /**< [in] flush id within the originating frame builder */
- _mali_uk_start_job_flags flags; /**< [in] Flags for job, see _mali_uk_start_job_flags for more information */
+ u32 frame_builder_id; /**< [in] id of the originating frame builder */
+ u32 flush_id; /**< [in] flush id within the originating frame builder */
} _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 irq_status; /**< [out] value of interrupt rawstat register (see ARM DDI0415A) */
- u32 last_tile_list_addr; /**< [out] value of renderer list register (see ARM DDI0415A); necessary to restart a stopped job */
- u32 perf_counter_src0; /**< [out] source id for performance counter 0 (see ARM DDI0415A, Table 3-60) */
- u32 perf_counter_src1; /**< [out] source id for performance counter 1 (see ARM DDI0415A, Table 3-60) */
- u32 perf_counter0; /**< [out] value of perfomance counter 0 (see ARM DDI0415A) */
- u32 perf_counter1; /**< [out] value of perfomance counter 1 (see ARM DDI0415A) */
- u32 render_time; /**< [out] number of microseconds it took for the job to render */
- u32 perf_counter_l2_src0; /**< [out] soruce id for Mali-400 MP L2 cache performance counter 0 */
- u32 perf_counter_l2_src1; /**< [out] soruce id for Mali-400 MP L2 cache performance counter 1 */
- u32 perf_counter_l2_val0; /**< [out] Value of the Mali-400 MP L2 cache performance counter 0 */
- u32 perf_counter_l2_val1; /**< [out] Value of the Mali-400 MP L2 cache performance counter 1 */
- u32 perf_counter_l2_val0_raw; /**< [out] Raw value of the Mali-400 MP L2 cache performance counter 0 */
- u32 perf_counter_l2_val1_raw; /**< [out] Raw value of the Mali-400 MP L2 cache performance counter 1 */
+ 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;
+
+/**
+ * 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 */
@@ -635,6 +599,7 @@ typedef enum
_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 */
@@ -644,6 +609,7 @@ typedef enum
_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 */
@@ -653,6 +619,51 @@ typedef enum
#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
@@ -698,14 +709,15 @@ typedef enum
*/
typedef struct
{
- void *ctx; /**< [in,out] user-kernel context (trashed on output) */
+ 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 */
- } data;
+ 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()
@@ -718,6 +730,7 @@ 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
@@ -748,7 +761,7 @@ typedef struct
* The 16bit integer is stored twice in a 32bit integer
* For example, for version 1 the value would be 0x00010001
*/
-#define _MALI_API_VERSION 10
+#define _MALI_API_VERSION 14
#define _MALI_UK_API_VERSION _MAKE_VERSION_ID(_MALI_API_VERSION)
/**
@@ -780,6 +793,31 @@ typedef struct
} _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 */
@@ -800,47 +838,6 @@ typedef struct
void *ctx; /**< [in,out] user-kernel context (trashed on output) */
} _mali_uk_term_mem_s;
-/** @brief Arguments for _mali_ukk_get_big_block()
- *
- * - type_id should be set to the value of the identifier member of one of the
- * _mali_mem_info structures returned through _mali_ukk_get_system_info()
- * - ukk_private must be zero when calling from user-side. 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. Specifically, ukk_private will be placed
- * into the ukk_private member of the _mali_uk_mem_mmap_s structure. See
- * _mali_ukk_mem_mmap() for more details.
- * - minimum_size_requested will be updated if it is too small
- * - block_size will always be >= minimum_size_requested, because the underlying
- * allocation mechanism may only be able to divide up memory regions in certain
- * ways. To avoid wasting memory, block_size should always be taken into account
- * rather than assuming minimum_size_requested was really allocated.
- * - to free the memory, the returned cookie member must be stored, and used to
- * refer to it.
- */
-typedef struct
-{
- void *ctx; /**< [in,out] user-kernel context (trashed on output) */
- u32 type_id; /**< [in] the type id of the memory bank to allocate memory from */
- u32 minimum_size_requested; /**< [in,out] minimum size of the allocation */
- u32 ukk_private; /**< [in] Kernel-side private word inserted by certain U/K interface implementations. Caller must set to Zero. */
- u32 mali_address; /**< [out] address of the allocation in mali address space */
- void *cpuptr; /**< [out] address of the allocation in the current process address space */
- u32 block_size; /**< [out] size of the block that got allocated */
- u32 flags; /**< [out] flags associated with the allocated block, of type _mali_bus_usage */
- u32 cookie; /**< [out] identifier for the allocated block in kernel space */
-} _mali_uk_get_big_block_s;
-
-/** @brief Arguments for _mali_ukk_free_big_block()
- *
- * All that is required is that the cookie member must be set to the value of
- * the cookie member returned through _mali_ukk_get_big_block()
- */
-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_free_big_block_s;
-
/** @note Mali-MMU only */
typedef struct
{
@@ -959,12 +956,6 @@ typedef struct
_mali_core_version version; /**< [out] version returned from core, see \ref _mali_core_version */
} _mali_uk_get_pp_core_version_s;
-typedef struct
-{
- void *ctx; /**< [in,out] user-kernel context (trashed on output) */
- u32 abort_id; /**< [in] ID of job(s) to abort */
-} _mali_uk_pp_abort_job_s;
-
/** @} */ /* end group _mali_uk_pp */
@@ -997,12 +988,6 @@ typedef struct
typedef struct
{
- void *ctx; /**< [in,out] user-kernel context (trashed on output) */
- u32 abort_id; /**< [in] ID of job(s) to abort */
-} _mali_uk_gp_abort_job_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;
@@ -1031,24 +1016,9 @@ typedef struct
typedef struct
{
- void *ctx;
-
- u32 id;
- s64 value;
-} _mali_uk_sw_counters_s;
-
-typedef struct
-{
void *ctx; /**< [in,out] user-kernel context (trashed on output) */
} _mali_uk_profiling_clear_s;
-typedef struct
-{
- void *ctx; /**< [in,out] user-kernel context (trashed on output) */
- u32 enable_events; /**< [out] 1 if user space process should generate events, 0 if not */
-} _mali_uk_profiling_get_config_s;
-
-
/** @} */ /* end group _mali_uk_gp */
@@ -1111,35 +1081,6 @@ typedef struct
} _mali_uk_mem_munmap_s;
/** @} */ /* end group _mali_uk_memory */
-#if USING_MALI_PMM
-
-/** @defgroup _mali_uk_pmm U/K Power Management Module
- * @{ */
-
-/** @brief Power management event message identifiers.
- *
- * U/K events start after id 200, and can range up to 999
- * Adding new events will require updates to the PMM mali_pmm_event_id type
- */
-#define _MALI_PMM_EVENT_UK_EXAMPLE 201
-
-/** @brief Generic PMM message data type, that will be dependent on the event msg
- */
-typedef u32 mali_pmm_message_data;
-
-
-/** @brief Arguments to _mali_ukk_pmm_event_message()
- */
-typedef struct
-{
- void *ctx; /**< [in,out] user-kernel context (trashed on output) */
- u32 id; /**< [in] event id */
- mali_pmm_message_data data; /**< [in] specific data associated with the event */
-} _mali_uk_pmm_message_s;
-
-/** @} */ /* end group _mali_uk_pmm */
-#endif /* USING_MALI_PMM */
-
/** @defgroup _mali_uk_vsync U/K VSYNC Wait Reporting Module
* @{ */
@@ -1165,6 +1106,22 @@ typedef struct
/** @} */ /* 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 */
+
/** @} */ /* end group u_k_api */
/** @} */ /* end group uddapi */
@@ -1173,4 +1130,4 @@ typedef struct
}
#endif
-#endif /* __MALI_UK_TYPES_H__ */
+#endif /* __MALI_UTGARD_UK_TYPES_H__ */
diff --git a/drivers/media/video/samsung/mali/linux/mali_device_pause_resume.c b/drivers/media/video/samsung/mali/linux/mali_device_pause_resume.c
deleted file mode 100644
index 04f57d9..0000000
--- a/drivers/media/video/samsung/mali/linux/mali_device_pause_resume.c
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * 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_device_pause_resume.c
- * Implementation of the Mali pause/resume functionality
- */
-#if USING_MALI_PMM
-#include <linux/version.h>
-#include <linux/sched.h>
-#include <linux/module.h>
-#include "mali_osk.h"
-#include "mali_kernel_common.h"
-#include "mali_platform.h"
-#include "mali_linux_pm.h"
-#include "mali_device_pause_resume.h"
-#include "mali_pmm.h"
-#include "mali_kernel_license.h"
-#ifdef CONFIG_PM
-#if MALI_LICENSE_IS_GPL
-
-/* Mali Pause Resume APIs */
-int mali_dev_pause()
-{
- int err = 0;
- _mali_osk_lock_wait(lock, _MALI_OSK_LOCKMODE_RW);
- if ((mali_dvfs_device_state == _MALI_DEVICE_SUSPEND)
- || (mali_device_state == _MALI_DEVICE_SUSPEND) )
- {
- err = -EPERM;
- }
- if ((mali_dvfs_device_state == _MALI_DEVICE_RESUME) && (!err))
- {
- mali_device_suspend(MALI_PMM_EVENT_DVFS_PAUSE, &dvfs_pm_thread);
- mali_dvfs_device_state = _MALI_DEVICE_SUSPEND;
- }
- _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW);
- return err;
-}
-
-EXPORT_SYMBOL(mali_dev_pause);
-
-int mali_dev_resume()
-{
- int err = 0;
- _mali_osk_lock_wait(lock, _MALI_OSK_LOCKMODE_RW);
- if ((mali_dvfs_device_state == _MALI_DEVICE_RESUME)
- || (mali_device_state == _MALI_DEVICE_SUSPEND) )
- {
- err = -EPERM;
- }
- if (!err)
- {
- mali_device_resume(MALI_PMM_EVENT_DVFS_RESUME, &dvfs_pm_thread);
- mali_dvfs_device_state = _MALI_DEVICE_RESUME;
- }
- _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW);
- return err;
-}
-
-EXPORT_SYMBOL(mali_dev_resume);
-
-#endif /* MALI_LICENSE_IS_GPL */
-#endif /* CONFIG_PM */
-#endif /* USING_MALI_PMM */
diff --git a/drivers/media/video/samsung/mali/linux/mali_kernel_ioctl.h b/drivers/media/video/samsung/mali/linux/mali_kernel_ioctl.h
index 7e3a216..6fc59a7 100644
--- a/drivers/media/video/samsung/mali/linux/mali_kernel_ioctl.h
+++ b/drivers/media/video/samsung/mali/linux/mali_kernel_ioctl.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 ARM Limited. All rights reserved.
+ * 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.
@@ -44,8 +44,10 @@ extern "C"
#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_MEM_GET_BIG_BLOCK _IOWR(MALI_IOC_MEMORY_BASE, _MALI_UK_GET_BIG_BLOCK, _mali_uk_get_big_block_s *)
-#define MALI_IOC_MEM_FREE_BIG_BLOCK _IOW (MALI_IOC_MEMORY_BASE, _MALI_UK_FREE_BIG_BLOCK, _mali_uk_free_big_block_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_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 *)
@@ -57,9 +59,7 @@ extern "C"
#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_ABORT_JOB _IOW (MALI_IOC_PP_BASE, _MALI_UK_PP_ABORT_JOB, _mali_uk_pp_abort_job_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_ABORT_JOB _IOWR(MALI_IOC_GP_BASE, _MALI_UK_GP_ABORT_JOB, _mali_uk_gp_abort_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 *)
@@ -68,8 +68,7 @@ extern "C"
#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_TRANSFER_SW_COUNTERS _IOW (MALI_IOC_PROFILING_BASE, _MALI_UK_TRANSFER_SW_COUNTERS, _mali_uk_sw_counters_s *)
-#define MALI_IOC_PROFILING_GET_CONFIG _IOWR(MALI_IOC_PROFILING_BASE, _MALI_UK_PROFILING_GET_CONFIG, _mali_uk_profiling_get_config_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_VSYNC_EVENT_REPORT _IOW (MALI_IOC_VSYNC_BASE, _MALI_UK_VSYNC_EVENT_REPORT, _mali_uk_vsync_event_report_s *)
#ifdef __cplusplus
diff --git a/drivers/media/video/samsung/mali/linux/mali_kernel_linux.c b/drivers/media/video/samsung/mali/linux/mali_kernel_linux.c
index 05762ca..3de368e 100644
--- a/drivers/media/video/samsung/mali/linux/mali_kernel_linux.c
+++ b/drivers/media/video/samsung/mali/linux/mali_kernel_linux.c
@@ -1,5 +1,5 @@
-/*
- * Copyright (C) 2010 ARM Limited. All rights reserved.
+/**
+ * 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.
@@ -15,31 +15,31 @@
#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 mananger definitions */
-#include <linux/device.h>
-
-/* the mali kernel subsystem types */
-#include "mali_kernel_subsystem.h"
-
-/* A memory subsystem always exists, so no need to conditionally include it */
+#include <linux/mm.h> /* memory mananger definitions */
+#include <linux/mali/mali_utgard_ioctl.h>
#include "mali_kernel_common.h"
-#include "mali_kernel_session_manager.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_kernel_ioctl.h"
#include "mali_ukk_wrappers.h"
#include "mali_kernel_pm.h"
-#include "mali_linux_pm.h"
-
#include "mali_kernel_sysfs.h"
-
-/* */
+#include "mali_platform.h"
#include "mali_kernel_license.h"
-#include "mali_platform.h"
+/* Streamline support for the Mali driver */
+#if defined(CONFIG_TRACEPOINTS) && MALI_TIMELINE_PROFILING_ENABLED
+/* Ask Linux to create the tracepoints */
+#define CREATE_TRACE_POINTS
+#include "mali_linux_trace.h"
+#endif /* CONFIG_TRACEPOINTS */
+
+static _mali_osk_errcode_t initialize_kernel_device(void);
+static int initialize_sysfs(void);
+static void terminate_kernel_device(void);
+
/* from the __malidrv_build_info.c file that is generated during build */
extern const char *__malidrv_build_info(void);
@@ -58,23 +58,15 @@ int mali_major = 0;
module_param(mali_major, int, S_IRUGO); /* r--r--r-- */
MODULE_PARM_DESC(mali_major, "Device major number");
-int mali_benchmark = 0;
-module_param(mali_benchmark, int, S_IRUSR | S_IWUSR | S_IWGRP | S_IRGRP | S_IROTH); /* rw-rw-r-- */
-MODULE_PARM_DESC(mali_benchmark, "Bypass Mali hardware when non-zero");
-
-extern int mali_hang_check_interval;
module_param(mali_hang_check_interval, int, S_IRUSR | S_IWUSR | S_IWGRP | S_IRGRP | S_IROTH);
MODULE_PARM_DESC(mali_hang_check_interval, "Interval at which to check for progress after the hw watchdog has been triggered");
-extern int mali_max_job_runtime;
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");
-#if defined(USING_MALI400_L2_CACHE)
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");
-#endif
#if MALI_TIMELINE_PROFILING_ENABLED
extern int mali_boot_profiling;
@@ -82,6 +74,10 @@ 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
+/* 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);
#if MALI_DVFS_ENABLED
extern int mali_dvfs_control;
module_param(mali_dvfs_control, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP| S_IROTH); /* rw-rw-r-- */
@@ -154,7 +150,6 @@ MODULE_PARM_DESC(step3_vol, "Mali Current step3_vol");
#endif
#endif
#endif
-#endif
extern int mali_gpu_clk;
module_param(mali_gpu_clk, int, S_IRUSR | S_IRGRP | S_IROTH); /* r--r--r-- */
@@ -167,7 +162,8 @@ MODULE_PARM_DESC(mali_gpu_vol, "Mali Current Voltage");
extern int gpu_power_state;
module_param(gpu_power_state, int, S_IRUSR | S_IRGRP | S_IROTH); /* r--r--r-- */
MODULE_PARM_DESC(gpu_power_state, "Mali Power State");
-extern _mali_device_power_states mali_dvfs_device_state;
+#endif
+
static char mali_dev_name[] = "mali"; /* should be const, but the functions we call requires non-cost */
@@ -202,53 +198,74 @@ struct file_operations mali_fops =
int mali_driver_init(void)
{
- int err;
-#if USING_MALI_PMM
-#if MALI_LICENSE_IS_GPL
-#ifdef CONFIG_PM
- err = _mali_dev_platform_register();
- if (err)
- {
- return err;
- }
-#endif
-#endif
-#endif
- err = mali_kernel_constructor();
- if (_MALI_OSK_ERR_OK != err)
- {
-#if USING_MALI_PMM
-#if MALI_LICENSE_IS_GPL
-#ifdef CONFIG_PM
- _mali_dev_platform_unregister();
-#endif
-#endif
-#endif
- MALI_PRINT(("Failed to initialize driver (error %d)\n", err));
- return -EFAULT;
- }
+ int ret = 0;
- /* print build options */
- MALI_DEBUG_PRINT(2, ("%s\n", __malidrv_build_info()));
+ MALI_DEBUG_PRINT(2, ("\n"));
+ 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));
- return 0;
+ ret = _mali_dev_platform_register();
+ if (0 != ret) goto platform_register_failed;
+ ret = map_errcode(initialize_kernel_device());
+ if (0 != ret) goto initialize_kernel_device_failed;
+
+ ret = map_errcode(mali_platform_init());
+ if (0 != ret) goto platform_init_failed;
+
+ mali_osk_low_level_mem_init();
+
+ ret = map_errcode(mali_initialize_subsystems());
+ if (0 != ret) goto initialize_subsystems_failed;
+
+ ret = initialize_sysfs();
+ if (0 != ret) goto initialize_sysfs_failed;
+
+ MALI_PRINT(("Mali device driver loaded\n"));
+
+ return 0; /* Success */
+
+ /* Error handling */
+initialize_sysfs_failed:
+ mali_terminate_subsystems();
+initialize_subsystems_failed:
+ mali_osk_low_level_mem_term();
+ mali_platform_deinit();
+platform_init_failed:
+ terminate_kernel_device();
+initialize_kernel_device_failed:
+ _mali_dev_platform_unregister();
+platform_register_failed:
+ return ret;
}
void mali_driver_exit(void)
{
- mali_kernel_destructor();
+ MALI_DEBUG_PRINT(2, ("\n"));
+ MALI_DEBUG_PRINT(2, ("Unloading Mali v%d device driver.\n",_MALI_API_VERSION));
-#if USING_MALI_PMM
-#if MALI_LICENSE_IS_GPL
-#ifdef CONFIG_PM
+ /* No need to terminate sysfs, this will be done automatically along with device termination */
+
+ mali_terminate_subsystems();
+
+ mali_osk_low_level_mem_term();
+
+ mali_platform_deinit();
+
+ terminate_kernel_device();
_mali_dev_platform_unregister();
+
+#if MALI_LICENSE_IS_GPL
+ /* @@@@ clean up the work queues! This should not be terminated here, since it isn't inited in the function above! */
+ flush_workqueue(mali_wq);
+ destroy_workqueue(mali_wq);
+ mali_wq = NULL;
#endif
-#endif
-#endif
+
+ MALI_PRINT(("Mali device driver unloaded\n"));
}
-/* called from _mali_osk_init */
-int initialize_kernel_device(void)
+static int initialize_kernel_device(void)
{
int err;
dev_t dev = 0;
@@ -284,28 +301,25 @@ int initialize_kernel_device(void)
goto init_cdev_err;
}
- err = mali_sysfs_register(&device, dev, mali_dev_name);
- if (err)
- {
- goto init_sysfs_err;
- }
-
/* Success! */
return 0;
-init_sysfs_err:
- cdev_del(&device.cdev);
init_cdev_err:
unregister_chrdev_region(dev, 1/*count*/);
init_chrdev_err:
return err;
}
-/* called from _mali_osk_term */
-void terminate_kernel_device(void)
+static int initialize_sysfs(void)
{
dev_t dev = MKDEV(mali_major, 0);
-
+ return mali_sysfs_register(&device, dev, mali_dev_name);
+}
+
+static void terminate_kernel_device(void)
+{
+ dev_t dev = MKDEV(mali_major, 0);
+
mali_sysfs_unregister(&device, dev, mali_dev_name);
/* unregister char device */
@@ -421,12 +435,6 @@ static int mali_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
return -ENOTTY;
}
- if (_MALI_DEVICE_SHUTDOWN == mali_dvfs_device_state)
- {
- MALI_DEBUG_PRINT(7, ("system is shutdown \n"));
- return 0;
- }
-
switch(cmd)
{
case MALI_IOC_GET_SYSTEM_INFO_SIZE:
@@ -449,6 +457,10 @@ static int mali_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
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 MALI_TIMELINE_PROFILING_ENABLED
case MALI_IOC_PROFILING_START:
err = profiling_start_wrapper(session_data, (_mali_uk_profiling_start_s __user *)arg);
@@ -471,8 +483,26 @@ static int mali_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
break;
case MALI_IOC_PROFILING_GET_CONFIG:
- err = profiling_get_config_wrapper(session_data, (_mali_uk_profiling_get_config_s __user *)arg);
+ /* 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:
@@ -499,14 +529,6 @@ static int mali_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
err = mem_dump_mmu_page_table_wrapper(session_data, (_mali_uk_dump_mmu_page_table_s __user *)arg);
break;
- case MALI_IOC_MEM_GET_BIG_BLOCK:
- err = mem_get_big_block_wrapper(filp, (_mali_uk_get_big_block_s __user *)arg);
- break;
-
- case MALI_IOC_MEM_FREE_BIG_BLOCK:
- err = mem_free_big_block_wrapper(session_data, (_mali_uk_free_big_block_s __user *)arg);
- break;
-
#if MALI_USE_UNIFIED_MEMORY_PROVIDER != 0
case MALI_IOC_MEM_ATTACH_UMP:
@@ -530,10 +552,6 @@ static int mali_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
err = pp_start_job_wrapper(session_data, (_mali_uk_pp_start_job_s __user *)arg);
break;
- case MALI_IOC_PP_ABORT_JOB:
- err = pp_abort_job_wrapper(session_data, (_mali_uk_pp_abort_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;
@@ -542,12 +560,12 @@ static int mali_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
err = pp_get_core_version_wrapper(session_data, (_mali_uk_get_pp_core_version_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);
+ 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_ABORT_JOB:
- err = gp_abort_job_wrapper(session_data, (_mali_uk_gp_abort_job_s __user *)arg);
+ 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:
@@ -565,10 +583,11 @@ static int mali_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
case MALI_IOC_VSYNC_EVENT_REPORT:
err = vsync_event_report_wrapper(session_data, (_mali_uk_vsync_event_report_s __user *)arg);
break;
-#if MALI_TRACEPOINTS_ENABLED
- case MALI_IOC_TRANSFER_SW_COUNTERS:
- err = transfer_sw_counters_wrapper(session_data, (_mali_uk_sw_counters_s __user *)arg);
-#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:
@@ -586,9 +605,3 @@ module_exit(mali_driver_exit);
MODULE_LICENSE(MALI_KERNEL_LINUX_LICENSE);
MODULE_AUTHOR("ARM Ltd.");
MODULE_VERSION(SVN_REV_STRING);
-
-#if MALI_TRACEPOINTS_ENABLED
-/* Create the trace points (otherwise we just get code to call a tracepoint) */
-#define CREATE_TRACE_POINTS
-#include "mali_linux_trace.h"
-#endif
diff --git a/drivers/media/video/samsung/mali/linux/mali_kernel_linux.h b/drivers/media/video/samsung/mali/linux/mali_kernel_linux.h
index 9c7668c..22dc9a4 100644
--- a/drivers/media/video/samsung/mali/linux/mali_kernel_linux.h
+++ b/drivers/media/video/samsung/mali/linux/mali_kernel_linux.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 ARM Limited. All rights reserved.
+ * 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.
@@ -28,8 +28,10 @@ struct mali_dev
#endif
};
-_mali_osk_errcode_t initialize_kernel_device(void);
-void terminate_kernel_device(void);
+#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);
diff --git a/drivers/media/video/samsung/mali/linux/mali_kernel_pm.c b/drivers/media/video/samsung/mali/linux/mali_kernel_pm.c
index f06ea4b..1d861f5 100644
--- a/drivers/media/video/samsung/mali/linux/mali_kernel_pm.c
+++ b/drivers/media/video/samsung/mali/linux/mali_kernel_pm.c
@@ -1,5 +1,5 @@
-/*
- * Copyright (C) 2010 ARM Limited. All rights reserved.
+/**
+ * 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.
@@ -10,615 +10,211 @@
/**
* @file mali_kernel_pm.c
- * Implementation of the Linux Power Management for Mali GPU kernel driver
+ * Linux Power Management integration
*/
-#if USING_MALI_PMM
#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 <asm/current.h>
#include <linux/suspend.h>
-
-#include <plat/cpu.h>
-#include <plat/pd.h>
-#include <plat/devs.h>
-
-#include "mali_platform.h"
+#include <linux/module.h>
+#ifdef CONFIG_PM_RUNTIME
+#include <linux/pm_runtime.h>
+#endif
#include "mali_osk.h"
#include "mali_uk_types.h"
-#include "mali_pmm.h"
-#include "mali_ukk.h"
#include "mali_kernel_common.h"
#include "mali_kernel_license.h"
-#include "mali_kernel_pm.h"
-#include "mali_device_pause_resume.h"
#include "mali_linux_pm.h"
+#include "mali_pm.h"
+#include "mali_platform.h"
-#ifdef MALI_REBOOTNOTIFIER
-_mali_osk_atomic_t mali_shutdown_state;
-#include <linux/reboot.h>
+#if ! MALI_LICENSE_IS_GPL
+#undef CONFIG_PM_RUNTIME
#endif
-#if MALI_GPU_UTILIZATION
-#include "mali_kernel_utilization.h"
-#endif /* MALI_GPU_UTILIZATION */
-
-#if MALI_POWER_MGMT_TEST_SUITE
-#ifdef CONFIG_PM
-#include "mali_linux_pm_testsuite.h"
-#include "mali_platform_pmu_internal_testing.h"
-unsigned int pwr_mgmt_status_reg = 0;
-#endif /* CONFIG_PM */
-#endif /* MALI_POWER_MGMT_TEST_SUITE */
-
-static int is_os_pmm_thread_waiting = 0;
-
-/* kernel should be configured with power management support */
-#ifdef CONFIG_PM
-
-/* License should be GPL */
-#if MALI_LICENSE_IS_GPL
-
-/* Linux kernel major version */
-#define LINUX_KERNEL_MAJOR_VERSION 2
-
-/* Linux kernel minor version */
-#define LINUX_KERNEL_MINOR_VERSION 6
-
-/* Linux kernel development version */
-#define LINUX_KERNEL_DEVELOPMENT_VERSION 29
-
-#ifdef CONFIG_PM_DEBUG
-static const char* const mali_states[_MALI_MAX_DEBUG_OPERATIONS] = {
- [_MALI_DEVICE_SUSPEND] = "suspend",
- [_MALI_DEVICE_RESUME] = "resume",
- [_MALI_DVFS_PAUSE_EVENT] = "dvfs_pause",
- [_MALI_DVFS_RESUME_EVENT] = "dvfs_resume",
-};
-
-#endif /* CONFIG_PM_DEBUG */
-
#if MALI_PMM_RUNTIME_JOB_CONTROL_ON
extern void set_mali_parent_power_domain(struct platform_device* dev);
#endif /* MALI_PMM_RUNTIME_JOB_CONTROL_ON */
+static int mali_probe(struct platform_device *pdev);
+static int mali_remove(struct platform_device *pdev);
#ifdef CONFIG_PM_RUNTIME
-#if MALI_PMM_RUNTIME_JOB_CONTROL_ON
-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 /* MALI_PMM_RUNTIME_JOB_CONTROL_ON */
-#endif /* CONFIG_PM_RUNTIME */
-
-/* Power management thread pointer */
-struct task_struct *pm_thread;
-
-/* dvfs power management thread */
-struct task_struct *dvfs_pm_thread;
-
-/* is wake up needed */
-short is_wake_up_needed = 0;
-int timeout_fired = 2;
-unsigned int is_mali_pmm_testsuite_enabled = 0;
-
-_mali_device_power_states mali_device_state = _MALI_DEVICE_RESUME;
-_mali_device_power_states mali_dvfs_device_state = _MALI_DEVICE_RESUME;
-_mali_osk_lock_t *lock;
-
-#if MALI_POWER_MGMT_TEST_SUITE
-
-const char* const mali_pmm_recording_events[_MALI_DEVICE_MAX_PMM_EVENTS] = {
- [_MALI_DEVICE_PMM_TIMEOUT_EVENT] = "timeout",
- [_MALI_DEVICE_PMM_JOB_SCHEDULING_EVENTS] = "job_scheduling",
- [_MALI_DEVICE_PMM_REGISTERED_CORES] = "cores",
-
-};
-
-unsigned int mali_timeout_event_recording_on = 0;
-unsigned int mali_job_scheduling_events_recording_on = 0;
-unsigned int is_mali_pmu_present = 0;
-#endif /* MALI_POWER_MGMT_TEST_SUITE */
-
-/* Function prototypes */
-static int mali_pm_probe(struct platform_device *pdev);
-static int mali_pm_remove(struct platform_device *pdev);
-static void mali_pm_shutdown(struct platform_device *pdev);
-
-/* Mali device suspend function */
-static int mali_pm_suspend(struct device *dev);
-
-/* Mali device resume function */
-static int mali_pm_resume(struct device *dev);
-
-/* Run time suspend and resume functions */
-#ifdef CONFIG_PM_RUNTIME
-#if MALI_PMM_RUNTIME_JOB_CONTROL_ON
-static int mali_device_runtime_suspend(struct device *dev);
-static int mali_device_runtime_resume(struct device *dev);
-#endif /* MALI_PMM_RUNTIME_JOB_CONTROL_ON */
-#endif /* CONFIG_PM_RUNTIME */
-
-/* OS suspend and resume callbacks */
-#if !MALI_PMM_RUNTIME_JOB_CONTROL_ON
-#ifndef CONFIG_PM_RUNTIME
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(LINUX_KERNEL_MAJOR_VERSION,LINUX_KERNEL_MINOR_VERSION,LINUX_KERNEL_DEVELOPMENT_VERSION))
-static int mali_pm_os_suspend(struct platform_device *pdev, pm_message_t state);
-#else
-static int mali_pm_os_suspend(struct device *dev);
+static int mali_runtime_suspend(struct device *dev);
+static int mali_runtime_resume(struct device *dev);
#endif
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(LINUX_KERNEL_MAJOR_VERSION,LINUX_KERNEL_MINOR_VERSION,LINUX_KERNEL_DEVELOPMENT_VERSION))
-static int mali_pm_os_resume(struct platform_device *pdev);
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29))
+static int mali_os_suspend(struct platform_device *pdev, pm_message_t state);
+static int mali_os_resume(struct platform_device *pdev);
#else
-static int mali_pm_os_resume(struct device *dev);
+static int mali_os_suspend(struct device *dev);
+static int mali_os_resume(struct device *dev);
#endif
-#endif /* CONFIG_PM_RUNTIME */
-#endif /* MALI_PMM_RUNTIME_JOB_CONTROL_ON */
-
-/* OS Hibernation suspend callback */
-static int mali_pm_os_suspend_on_hibernation(struct device *dev);
-
-/* OS Hibernation resume callback */
-static int mali_pm_os_resume_on_hibernation(struct device *dev);
-
-static void _mali_release_pm(struct device* device);
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(LINUX_KERNEL_MAJOR_VERSION,LINUX_KERNEL_MINOR_VERSION,LINUX_KERNEL_DEVELOPMENT_VERSION))
-static const struct dev_pm_ops mali_dev_pm_ops = {
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29))
+static const struct dev_pm_ops mali_dev_pm_ops =
+{
#ifdef CONFIG_PM_RUNTIME
-#if MALI_PMM_RUNTIME_JOB_CONTROL_ON
- .runtime_suspend = mali_device_runtime_suspend,
- .runtime_resume = mali_device_runtime_resume,
-#endif /* MALI_PMM_RUNTIME_JOB_CONTROL_ON */
-#endif /* CONFIG_PM_RUNTIME */
-
-#ifndef CONFIG_PM_RUNTIME
-#if !MALI_PMM_RUNTIME_JOB_CONTROL_ON
- .suspend = mali_pm_os_suspend,
- .resume = mali_pm_os_resume,
-#endif /* MALI_PMM_RUNTIME_JOB_CONTROL_ON */
-#endif /* CONFIG_PM_RUNTIME */
- .freeze = mali_pm_os_suspend_on_hibernation,
- .poweroff = mali_pm_os_suspend_on_hibernation,
- .thaw = mali_pm_os_resume_on_hibernation,
- .restore = mali_pm_os_resume_on_hibernation,
-};
+ .runtime_suspend = mali_runtime_suspend,
+ .runtime_resume = mali_runtime_resume,
+ .runtime_idle = NULL,
+#else
+ .suspend = mali_os_suspend,
+ .resume = mali_os_resume,
#endif
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(LINUX_KERNEL_MAJOR_VERSION,LINUX_KERNEL_MINOR_VERSION,LINUX_KERNEL_DEVELOPMENT_VERSION))
-struct pm_ext_ops mali_pm_operations = {
- .base = {
- .freeze = mali_pm_os_suspend_on_hibernation,
- .thaw = mali_pm_os_resume_on_hibernation,
- .poweroff = mali_pm_os_resume_on_hibernation,
- .restore = mali_pm_os_resume_on_hibernation,
+ .freeze = mali_os_suspend,
+ .poweroff = mali_os_suspend,
+ .thaw = mali_os_resume,
+ .restore = mali_os_resume,
+};
+#elif (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29))
+struct pm_ext_ops mali_ext_pm_operations =
+{
+ .base =
+ {
+ .freeze = mali_os_suspend,
+ .thaw = mali_os_resume,
+ .poweroff = mali_os_suspend,
+ .restore = mali_os_resume,
},
};
#endif
-static struct platform_driver mali_plat_driver = {
- .probe = mali_pm_probe,
- .remove = mali_pm_remove,
- .shutdown = mali_pm_shutdown,
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(LINUX_KERNEL_MAJOR_VERSION,LINUX_KERNEL_MINOR_VERSION,LINUX_KERNEL_DEVELOPMENT_VERSION))
-#ifndef CONFIG_PM_RUNTIME
-#if !MALI_PMM_RUNTIME_JOB_CONTROL_ON
- .suspend = mali_pm_os_suspend,
- .resume = mali_pm_os_resume,
-#endif /* CONFIG_PM_RUNTIME */
-#endif /* MALI_PMM_RUNTIME_JOB_CONTROL_ON */
- .pm = &mali_pm_operations,
+
+static struct platform_driver mali_plat_driver =
+{
+ .probe = mali_probe,
+ .remove = mali_remove,
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29))
+ .suspend = mali_os_suspend,
+ .resume = mali_os_resume,
+ .pm = &mali_ext_pm_operations,
#endif
- .driver = {
+ .driver =
+ {
.name = "mali_dev",
.owner = THIS_MODULE,
+#if MALI_LICENSE_IS_GPL
.bus = &platform_bus_type,
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(LINUX_KERNEL_MAJOR_VERSION,LINUX_KERNEL_MINOR_VERSION,LINUX_KERNEL_DEVELOPMENT_VERSION))
+#endif
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29))
.pm = &mali_dev_pm_ops,
#endif
- },
+ },
};
-/* Mali GPU platform device */
-struct platform_device mali_gpu_device = {
- .name = "mali_dev",
- .id = 0,
- .dev.release = _mali_release_pm
+#ifdef CONFIG_PM_RUNTIME
+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
/** This function is called when platform device is unregistered. This function
* is necessary when the platform device is unregistered.
*/
static void _mali_release_pm(struct device *device)
{
- MALI_DEBUG_PRINT(4, ("OSPMM: MALI Platform device removed\n" ));
}
-
-#if MALI_POWER_MGMT_TEST_SUITE
-void mali_is_pmu_present(void)
+struct platform_device mali_gpu_device =
{
- int temp = 0;
- temp = pmu_get_power_up_down_info();
- if (4095 == temp)
- {
- is_mali_pmu_present = 0;
- }
- else
- {
- is_mali_pmu_present = 1;
- }
-}
-#endif /* MALI_POWER_MGMT_TEST_SUITE */
-#endif /* MALI_LICENSE_IS_GPL */
-
-#if MALI_LICENSE_IS_GPL
-
-static int mali_wait_for_power_management_policy_event(void)
-{
- int err = 0;
- for (; ;)
- {
- set_current_state(TASK_INTERRUPTIBLE);
- if (signal_pending(current))
- {
- err = -EINTR;
- break;
- }
- if (is_wake_up_needed == 1)
- {
- break;
- }
- schedule();
- }
- __set_current_state(TASK_RUNNING);
- is_wake_up_needed =0;
- return err;
-}
+ .name = "mali_dev",
+ .id = 0,
+ .dev.release = _mali_release_pm
+};
-/** This function is invoked when mali device is suspended
- */
-int mali_device_suspend(unsigned int event_id, struct task_struct **pwr_mgmt_thread)
+/** This function is called when the device is probed */
+static int mali_probe(struct platform_device *pdev)
{
- int err = 0;
- _mali_uk_pmm_message_s event = {
- NULL,
- event_id,
- timeout_fired};
- *pwr_mgmt_thread = current;
- MALI_DEBUG_PRINT(4, ("OSPMM: MALI device is being suspended\n" ));
- _mali_ukk_pmm_event_message(&event);
- is_os_pmm_thread_waiting = 1;
- err = mali_wait_for_power_management_policy_event();
- is_os_pmm_thread_waiting = 0;
- return err;
+ return 0;
}
-/** This function is called when Operating system wants to power down
- * the mali GPU device.
- */
-static int mali_pm_suspend(struct device *dev)
+static int mali_remove(struct platform_device *pdev)
{
- int err = 0;
- _mali_osk_lock_wait(lock, _MALI_OSK_LOCKMODE_RW);
- if ((mali_device_state == _MALI_DEVICE_SUSPEND))
- {
- _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW);
- return err;
- }
-#if MALI_DVFS_ENABLED
- mali_utilization_suspend();
-#endif
- err = mali_device_suspend(MALI_PMM_EVENT_OS_POWER_DOWN, &pm_thread);
- mali_device_state = _MALI_DEVICE_SUSPEND;
- _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW);
- return err;
-}
-
-#ifndef CONFIG_PM_RUNTIME
-#if !MALI_PMM_RUNTIME_JOB_CONTROL_ON
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(LINUX_KERNEL_MAJOR_VERSION,LINUX_KERNEL_MINOR_VERSION,LINUX_KERNEL_DEVELOPMENT_VERSION))
-static int mali_pm_os_suspend(struct platform_device *pdev, pm_message_t state)
-#else
-static int mali_pm_os_suspend(struct device *dev)
+#ifdef CONFIG_PM_RUNTIME
+ pm_runtime_disable(&pdev->dev);
#endif
-{
- int err = 0;
- err = mali_pm_suspend(NULL);
- return err;
+ return 0;
}
-#endif /* MALI_PMM_RUNTIME_JOB_CONTROL_ON */
-#endif /* CONFIG_PM_RUNTIME */
#ifdef CONFIG_PM_RUNTIME
-#if MALI_PMM_RUNTIME_JOB_CONTROL_ON
static int mali_pwr_suspend_notifier(struct notifier_block *nb,unsigned long event,void* dummy)
{
- int err = 0;
switch (event)
{
case PM_SUSPEND_PREPARE:
- err = mali_pm_suspend(NULL);
- break;
-
+ MALI_DEBUG_PRINT(2, ("mali_pwr_suspend_notifier(PM_SUSPEND_PREPARE) called\n"));
+ mali_pm_os_suspend();
+ break;
case PM_POST_SUSPEND:
- err = mali_pm_resume(NULL);
- break;
+ MALI_DEBUG_PRINT(2, ("mali_pwr_suspend_notifier(PM_SUSPEND_PREPARE) called\n"));
+ mali_pm_os_resume();
+ break;
default:
- break;
+ break;
}
return 0;
}
-#endif /* MALI_PMM_RUNTIME_JOB_CONTROL_ON */
-#endif /* CONFIG_PM_RUNTIME */
-
-/** This function is called when mali GPU device is to be resumed.
- */
-int mali_device_resume(unsigned int event_id, struct task_struct **pwr_mgmt_thread)
-{
- int err = 0;
- _mali_uk_pmm_message_s event = {
- NULL,
- event_id,
- timeout_fired};
- *pwr_mgmt_thread = current;
- MALI_DEBUG_PRINT(4, ("OSPMM: MALI device is being resumed\n" ));
- _mali_ukk_pmm_event_message(&event);
- MALI_DEBUG_PRINT(4, ("OSPMM: MALI Power up event is scheduled\n" ));
- is_os_pmm_thread_waiting = 1;
- err = mali_wait_for_power_management_policy_event();
- is_os_pmm_thread_waiting = 0;
- return err;
-}
-
-/** This function is called when mali GPU device is to be resumed
- */
-static int mali_pm_resume(struct device *dev)
-{
- int err = 0;
-
- _mali_osk_lock_wait(lock, _MALI_OSK_LOCKMODE_RW);
-
-#ifdef CONFIG_REGULATOR
- mali_regulator_enable();
-#endif
-
- if (mali_device_state == _MALI_DEVICE_RESUME)
- {
- _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW);
- return err;
- }
- err = mali_device_resume(MALI_PMM_EVENT_OS_POWER_UP, &pm_thread);
- mali_device_state = _MALI_DEVICE_RESUME;
- mali_dvfs_device_state = _MALI_DEVICE_RESUME;
- _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW);
- return err;
-}
-
-#ifndef CONFIG_PM_RUNTIME
-#if !MALI_PMM_RUNTIME_JOB_CONTROL_ON
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(LINUX_KERNEL_MAJOR_VERSION,LINUX_KERNEL_MINOR_VERSION,LINUX_KERNEL_DEVELOPMENT_VERSION))
-static int mali_pm_os_resume(struct platform_device *pdev)
-#else
-static int mali_pm_os_resume(struct device *dev)
#endif
-{
- int err = 0;
- err = mali_pm_resume(NULL);
- return err;
-}
-#endif /* MALI_PMM_RUNTIME_JOB_CONTROL_ON */
-#endif /* CONFIG_PM_RUNTIME */
-
-static int mali_pm_os_suspend_on_hibernation(struct device *dev)
-{
- int err = 0;
- err = mali_pm_suspend(NULL);
- return err;
-}
-static int mali_pm_os_resume_on_hibernation(struct device *dev)
-{
- int err = 0;
- err = mali_pm_resume(NULL);
- return err;
-}
#ifdef CONFIG_PM_RUNTIME
-#if MALI_PMM_RUNTIME_JOB_CONTROL_ON
-/** This function is called when runtime suspend of mali device is required.
- */
-static int mali_device_runtime_suspend(struct device *dev)
-{
- MALI_DEBUG_PRINT(4, ("PMMDEBUG: Mali device Run time suspended \n" ));
- return 0;
-}
-/** This function is called when runtime resume of mali device is required.
- */
-static int mali_device_runtime_resume(struct device *dev)
+static int mali_runtime_suspend(struct device *dev)
{
- MALI_DEBUG_PRINT(4, ("PMMDEBUG: Mali device Run time Resumed \n" ));
- return 0;
+ MALI_DEBUG_PRINT(3, ("mali_runtime_suspend() called\n"));
+ mali_pm_runtime_suspend();
+ return 0; /* all ok */
}
-#endif /* MALI_PMM_RUNTIME_JOB_CONTROL_ON */
-#endif /* CONFIG_PM_RUNTIME */
-#ifdef CONFIG_PM_DEBUG
-
-/** This function is used for debugging purposes when the user want to see
- * which power management operations are supported for
- * mali device.
- */
-static ssize_t show_file(struct device *dev, struct device_attribute *attr, char *buf)
+static int mali_runtime_resume(struct device *dev)
{
- char *str = buf;
-#if !MALI_POWER_MGMT_TEST_SUITE
- int pm_counter = 0;
- for (pm_counter = 0; pm_counter<_MALI_MAX_DEBUG_OPERATIONS; pm_counter++)
- {
- str += sprintf(str, "%s ", mali_states[pm_counter]);
- }
-#else
- str += sprintf(str, "%d ",pwr_mgmt_status_reg);
-#endif
- if (str != buf)
- {
- *(str-1) = '\n';
- }
- return (str-buf);
+ MALI_DEBUG_PRINT(3, ("mali_runtime_resume() called\n"));
+ mali_pm_runtime_resume();
+ return 0; /* all ok */
}
-/** This function is called when user wants to suspend the mali GPU device in order
- * to simulate the power up and power down events.
- */
-static ssize_t store_file(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
-{
- int err = 0;
-
-#if MALI_POWER_MGMT_TEST_SUITE
- int test_flag_dvfs = 0;
- pwr_mgmt_status_reg = 0;
- mali_is_pmu_present();
-
#endif
- if (!strncmp(buf,mali_states[_MALI_DEVICE_SUSPEND],strlen(mali_states[_MALI_DEVICE_SUSPEND])))
- {
- MALI_DEBUG_PRINT(4, ("PMMDEBUG: MALI suspend Power operation is scheduled\n" ));
- err = mali_pm_suspend(NULL);
- }
-#if MALI_POWER_MGMT_TEST_SUITE
- else if (!strncmp(buf,mali_pmm_recording_events[_MALI_DEVICE_PMM_REGISTERED_CORES],strlen(mali_pmm_recording_events[_MALI_DEVICE_PMM_REGISTERED_CORES])))
- {
- MALI_DEBUG_PRINT(4, ("PMMDEBUG: MALI Device get number of registerd cores\n" ));
- pwr_mgmt_status_reg = _mali_pmm_cores_list();
- return count;
- }
- else if (!strncmp(buf,mali_pmm_recording_events[_MALI_DEVICE_PMM_TIMEOUT_EVENT],strlen(mali_pmm_recording_events[_MALI_DEVICE_PMM_TIMEOUT_EVENT])))
- {
- MALI_DEBUG_PRINT(4, ("PMMDEBUG: MALI timeout event recording is enabled\n" ));
- mali_timeout_event_recording_on = 1;
- }
- else if (!strncmp(buf,mali_pmm_recording_events[_MALI_DEVICE_PMM_JOB_SCHEDULING_EVENTS],strlen(mali_pmm_recording_events[_MALI_DEVICE_PMM_JOB_SCHEDULING_EVENTS])))
- {
- MALI_DEBUG_PRINT(4, ("PMMDEBUG: MALI Job scheduling events recording is enabled\n" ));
- mali_job_scheduling_events_recording_on = 1;
- }
-#endif /* MALI_POWER_MGMT_TEST_SUITE */
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,29))
- else if (!strncmp(buf,mali_states[_MALI_DEVICE_RESUME],strlen(mali_states[_MALI_DEVICE_RESUME])))
- {
- MALI_DEBUG_PRINT(4, ("PMMDEBUG: MALI Resume Power operation is scheduled\n" ));
- err = mali_pm_resume(NULL);
- }
- else if (!strncmp(buf,mali_states[_MALI_DVFS_PAUSE_EVENT],strlen(mali_states[_MALI_DVFS_PAUSE_EVENT])))
- {
- MALI_DEBUG_PRINT(4, ("PMMDEBUG: MALI DVFS Pause Power operation is scheduled\n" ));
- err = mali_dev_pause();
-#if MALI_POWER_MGMT_TEST_SUITE
- test_flag_dvfs = 1;
-#endif /* MALI_POWER_MGMT_TEST_SUITE */
- }
- else if (!strncmp(buf,mali_states[_MALI_DVFS_RESUME_EVENT],strlen(mali_states[_MALI_DVFS_RESUME_EVENT])))
- {
- MALI_DEBUG_PRINT(4, ("PMMDEBUG: MALI DVFS Resume Power operation is scheduled\n" ));
- err = mali_dev_resume();
-#if MALI_POWER_MGMT_TEST_SUITE
- test_flag_dvfs = 1;
-#endif /* MALI_POWER_MGMT_TEST_SUITE */
- }
- else
- {
- MALI_DEBUG_PRINT(4, ("PMMDEBUG: Invalid Power Mode Operation selected\n" ));
- }
-#if MALI_POWER_MGMT_TEST_SUITE
- if (test_flag_dvfs == 1)
- {
- if (err)
- {
- pwr_mgmt_status_reg = 2;
- }
- else
- {
- pwr_mgmt_status_reg = 1;
- }
- }
- else
- {
- if (1 == is_mali_pmu_present)
- {
- pwr_mgmt_status_reg = pmu_get_power_up_down_info();
- }
- }
-#endif /* MALI_POWER_MGMT_TEST_SUITE */
- return count;
-}
-
-/* Device attribute file */
-static DEVICE_ATTR(file, 0644, show_file, store_file);
-#endif /* CONFIG_PM_DEBUG */
-
-static int mali_pm_remove(struct platform_device *pdev)
+static int mali_os_suspend(struct platform_device *pdev, pm_message_t state)
{
-#ifdef CONFIG_PM_DEBUG
- device_remove_file(&mali_gpu_device.dev, &dev_attr_file);
-#endif /* CONFIG_PM_DEBUG */
-#ifdef CONFIG_PM_RUNTIME
-#if MALI_PMM_RUNTIME_JOB_CONTROL_ON
- pm_runtime_disable(&pdev->dev);
-#endif /* MALI_PMM_RUNTIME_JOB_CONTROL_ON */
-#endif /* CONFIG_PM_RUNTIME */
- return 0;
+ MALI_DEBUG_PRINT(3, ("mali_os_suspend(old) called\n"));
+ mali_pm_os_suspend();
+ return 0; /* all ok */
}
-int mali_pd_enable(void)
+static int mali_os_resume(struct platform_device *pdev)
{
- return exynos_pd_enable(&exynos4_device_pd[PD_G3D].dev);
+ MALI_DEBUG_PRINT(3, ("mali_os_resume(old) called\n"));
+ mali_pm_os_resume();
+ return 0; /* all ok */
}
-static void mali_pm_shutdown(struct platform_device *pdev)
-{
- MALI_PRINT(("Mali shutdown!!\n"));
- mali_dvfs_device_state =_MALI_DEVICE_SHUTDOWN;
- exynos_pd_enable(&exynos4_device_pd[PD_G3D].dev);
- return;
-}
+#else
-/** This function is called when the device is probed */
-static int mali_pm_probe(struct platform_device *pdev)
+static int mali_os_suspend(struct device *dev)
{
-#ifdef CONFIG_PM_DEBUG
- int err;
- err = device_create_file(&mali_gpu_device.dev, &dev_attr_file);
- if (err)
- {
- MALI_DEBUG_PRINT(4, ("PMMDEBUG: Error in creating device file\n" ));
- }
-#endif /* CONFIG_PM_DEBUG */
- return 0;
+ MALI_DEBUG_PRINT(3, ("mali_os_suspend(new) called\n"));
+ mali_pm_os_suspend();
+ return 0; /* all ok */
}
-#ifdef MALI_REBOOTNOTIFIER
-static int mali_reboot_notify(struct notifier_block *this,
- unsigned long code, void *unused)
+
+static int mali_os_resume(struct device *dev)
{
- _mali_osk_atomic_inc_return(&mali_shutdown_state);
- mali_dvfs_device_state = _MALI_DEVICE_SHUTDOWN;
- MALI_PRINT(("REBOOT Notifier for mali\n"));
- return NOTIFY_DONE;
+ MALI_DEBUG_PRINT(3, ("mali_os_resume(new) called\n"));
+ mali_pm_os_resume();
+ return 0; /* all ok */
}
-static struct notifier_block mali_reboot_notifier = {
- .notifier_call = mali_reboot_notify,
-};
+
#endif
/** This function is called when Mali GPU device is initialized
@@ -626,50 +222,34 @@ static struct notifier_block mali_reboot_notifier = {
int _mali_dev_platform_register(void)
{
int err;
-#if MALI_PMM_RUNTIME_JOB_CONTROL_ON
+
+#ifdef CONFIG_PM_RUNTIME
set_mali_parent_power_domain((void *)&mali_gpu_device);
#endif
#ifdef CONFIG_PM_RUNTIME
-#if MALI_PMM_RUNTIME_JOB_CONTROL_ON
err = register_pm_notifier(&mali_pwr_notif_block);
if (err)
{
return err;
}
-#endif /* MALI_PMM_RUNTIME_JOB_CONTROL_ON */
-#endif /* CONFIG_PM_RUNTIME */
-
-#ifdef MALI_REBOOTNOTIFIER
- _mali_osk_atomic_init(&mali_shutdown_state, 0);
- err = register_reboot_notifier(&mali_reboot_notifier);
- if (err) {
- MALI_PRINT(("Failed to setup reboot notifier\n"));
- return err;
- }
#endif
+#if MALI_LICENSE_IS_GPL
err = platform_device_register(&mali_gpu_device);
- lock = _mali_osk_lock_init((_mali_osk_lock_flags_t)( _MALI_OSK_LOCKFLAG_READERWRITER | _MALI_OSK_LOCKFLAG_ORDERED), 0, 0);
if (!err)
{
err = platform_driver_register(&mali_plat_driver);
if (err)
{
- _mali_osk_lock_term(lock);
#ifdef CONFIG_PM_RUNTIME
-#if MALI_PMM_RUNTIME_JOB_CONTROL_ON
unregister_pm_notifier(&mali_pwr_notif_block);
-#endif /* MALI_PMM_RUNTIME_JOB_CONTROL_ON */
-#endif /* CONFIG_PM_RUNTIME */
-
-#ifdef MALI_REBOOTNOTIFIER
- unregister_reboot_notifier(&mali_reboot_notifier);
#endif
-
platform_device_unregister(&mali_gpu_device);
}
}
+#endif
+
return err;
}
@@ -677,33 +257,12 @@ int _mali_dev_platform_register(void)
*/
void _mali_dev_platform_unregister(void)
{
- _mali_osk_lock_term(lock);
-
#ifdef CONFIG_PM_RUNTIME
-#if MALI_PMM_RUNTIME_JOB_CONTROL_ON
unregister_pm_notifier(&mali_pwr_notif_block);
-#endif /* MALI_PMM_RUNTIME_JOB_CONTROL_ON */
-#endif /* CONFIG_PM_RUNTIME */
-
-#ifdef MALI_REBOOTNOTIFIER
- unregister_reboot_notifier(&mali_reboot_notifier);
#endif
+
+#if MALI_LICENSE_IS_GPL
platform_driver_unregister(&mali_plat_driver);
platform_device_unregister(&mali_gpu_device);
+#endif
}
-
-int mali_get_ospmm_thread_state(void)
-{
- return is_os_pmm_thread_waiting;
-}
-
-#endif /* MALI_LICENSE_IS_GPL */
-#endif /* CONFIG_PM */
-
-#if MALI_STATE_TRACKING
-u32 mali_pmm_dump_os_thread_state( char *buf, u32 size )
-{
- return snprintf(buf, size, "OSPMM: OS PMM thread is waiting: %s\n", is_os_pmm_thread_waiting ? "true" : "false");
-}
-#endif /* MALI_STATE_TRACKING */
-#endif /* USING_MALI_PMM */
diff --git a/drivers/media/video/samsung/mali/linux/mali_kernel_pm.h b/drivers/media/video/samsung/mali/linux/mali_kernel_pm.h
index 1c44439..6ef7270 100644
--- a/drivers/media/video/samsung/mali/linux/mali_kernel_pm.h
+++ b/drivers/media/video/samsung/mali/linux/mali_kernel_pm.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 ARM Limited. All rights reserved.
+ * 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.
@@ -11,10 +11,7 @@
#ifndef __MALI_KERNEL_PM_H__
#define __MALI_KERNEL_PM_H__
-#ifdef USING_MALI_PMM
int _mali_dev_platform_register(void);
void _mali_dev_platform_unregister(void);
-#endif /* USING_MALI_PMM */
-int mali_pd_enable(void);
#endif /* __MALI_KERNEL_PM_H__ */
diff --git a/drivers/media/video/samsung/mali/linux/mali_kernel_sysfs.c b/drivers/media/video/samsung/mali/linux/mali_kernel_sysfs.c
index 6dcf052..64853d7 100644
--- a/drivers/media/video/samsung/mali/linux/mali_kernel_sysfs.c
+++ b/drivers/media/video/samsung/mali/linux/mali_kernel_sysfs.c
@@ -1,5 +1,5 @@
-/*
- * Copyright (C) 2010 ARM Limited. All rights reserved.
+/**
+ * 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.
@@ -14,9 +14,14 @@
* Implementation of some sysfs data exports
*/
+#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/device.h>
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/slab.h>
#include "mali_kernel_license.h"
+#include "mali_kernel_common.h"
#include "mali_kernel_linux.h"
#include "mali_ukk.h"
@@ -25,13 +30,721 @@
#include <linux/seq_file.h>
#include <linux/debugfs.h>
#include <asm/uaccess.h>
-#include <linux/slab.h>
-#include "mali_kernel_subsystem.h"
+#include <linux/module.h>
#include "mali_kernel_sysfs.h"
-#include "mali_kernel_profiling.h"
+#if MALI_INTERNAL_TIMELINE_PROFILING_ENABLED
+#include <linux/slab.h>
+#include "mali_osk_profiling.h"
+#endif
+#include "mali_pm.h"
+#include "mali_cluster.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_device_pause_resume.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 u32 virtual_power_status_register=0;
+static char pwr_buf[POWER_BUFFER_SIZE];
+
+static int open_copy_private_data(struct inode *inode, struct file *filp)
+{
+ filp->private_data = inode->i_private;
+ return 0;
+}
+
+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;
+ struct mali_gp_core *gp_core = (struct mali_gp_core *)filp->private_data;
+
+ if (0 == src_id)
+ {
+ val = mali_gp_core_get_counter_src0(gp_core);
+ }
+ else
+ {
+ val = mali_gp_core_get_counter_src1(gp_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, 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)
+{
+ struct mali_gp_core *gp_core = (struct mali_gp_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_gp_core_set_counter_src0(gp_core, (u32)val))
+ {
+ return 0;
+ }
+ }
+ else
+ {
+ if (MALI_TRUE != mali_gp_core_set_counter_src1(gp_core, (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 ci;
+ struct mali_cluster *cluster;
+
+ 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;
+ }
+
+ ci = 0;
+ cluster = mali_cluster_get_global_cluster(ci);
+ while (NULL != cluster)
+ {
+ u32 gi = 0;
+ struct mali_group *group = mali_cluster_get_group(cluster, gi);
+ while (NULL != group)
+ {
+ 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_core_set_counter_src0(gp_core, (u32)val))
+ {
+ return 0;
+ }
+ }
+ else
+ {
+ if (MALI_TRUE != mali_gp_core_set_counter_src1(gp_core, (u32)val))
+ {
+ return 0;
+ }
+ }
+ }
+
+ /* try next group */
+ gi++;
+ group = mali_cluster_get_group(cluster, gi);
+ }
+
+ /* try next cluster */
+ ci++;
+ cluster = mali_cluster_get_global_cluster(ci);
+ }
+
+ *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;
+ struct mali_pp_core *pp_core = (struct mali_pp_core *)filp->private_data;
+
+ if (0 == src_id)
+ {
+ val = mali_pp_core_get_counter_src0(pp_core);
+ }
+ else
+ {
+ val = mali_pp_core_get_counter_src1(pp_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 pp_ppx_counter_srcx_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos, u32 src_id)
+{
+ struct mali_pp_core *pp_core = (struct mali_pp_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_pp_core_set_counter_src0(pp_core, (u32)val))
+ {
+ return 0;
+ }
+ }
+ else
+ {
+ if (MALI_TRUE != mali_pp_core_set_counter_src1(pp_core, (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 ci;
+ struct mali_cluster *cluster;
+
+ 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;
+ }
+
+ ci = 0;
+ cluster = mali_cluster_get_global_cluster(ci);
+ while (NULL != cluster)
+ {
+ u32 gi = 0;
+ struct mali_group *group = mali_cluster_get_group(cluster, gi);
+ while (NULL != group)
+ {
+ 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_core_set_counter_src0(pp_core, (u32)val))
+ {
+ return 0;
+ }
+ }
+ else
+ {
+ if (MALI_TRUE != mali_pp_core_set_counter_src1(pp_core, (u32)val))
+ {
+ return 0;
+ }
+ }
+ }
+
+ /* try next group */
+ gi++;
+ group = mali_cluster_get_group(cluster, gi);
+ }
+
+ /* try next cluster */
+ ci++;
+ cluster = mali_cluster_get_global_cluster(ci);
+ }
+
+ *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_events_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos)
+{
+
+ memset(pwr_buf,0,POWER_BUFFER_SIZE);
+ virtual_power_status_register = 0;
+ if (!strncmp(ubuf,mali_power_events[_MALI_DEVICE_SUSPEND],strlen(mali_power_events[_MALI_DEVICE_SUSPEND])))
+ {
+ mali_pm_os_suspend();
+ /* @@@@ assuming currently suspend is successful later on to tune as per previous*/
+ virtual_power_status_register =1;
+
+ }
+ else if (!strncmp(ubuf,mali_power_events[_MALI_DEVICE_RESUME],strlen(mali_power_events[_MALI_DEVICE_RESUME])))
+ {
+ mali_pm_os_resume();
+
+ /* @@@@ assuming currently resume is successful later on to tune as per previous */
+ virtual_power_status_register = 1;
+ }
+ else if (!strncmp(ubuf,mali_power_events[_MALI_DEVICE_DVFS_PAUSE],strlen(mali_power_events[_MALI_DEVICE_DVFS_PAUSE])))
+ {
+ mali_bool power_on;
+ mali_dev_pause(&power_on);
+ if (!power_on)
+ {
+ virtual_power_status_register = 2;
+ mali_dev_resume();
+ }
+ else
+ {
+ /* @@@@ assuming currently resume is successful later on to tune as per previous */
+ virtual_power_status_register =1;
+ }
+ }
+ else if (!strncmp(ubuf,mali_power_events[_MALI_DEVICE_DVFS_RESUME],strlen(mali_power_events[_MALI_DEVICE_DVFS_RESUME])))
+ {
+ mali_dev_resume();
+ /* @@@@ assuming currently resume is successful later on to tune as per previous */
+ virtual_power_status_register = 1;
+
+ }
+ *ppos += cnt;
+ sprintf(pwr_buf, "%d",virtual_power_status_register);
+ return cnt;
+}
+
+static ssize_t power_events_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos)
+{
+ return simple_read_from_buffer(ubuf, cnt, ppos, pwr_buf, POWER_BUFFER_SIZE);
+}
+
+static loff_t power_events_seek(struct file *file, loff_t offset, int orig)
+{
+ file->f_pos = offset;
+ return 0;
+}
+
+static const struct file_operations power_events_fops = {
+ .owner = THIS_MODULE,
+ .read = power_events_read,
+ .write = power_events_write,
+ .llseek = power_events_seek,
+};
+
+
#if MALI_STATE_TRACKING
static int mali_seq_internal_state_show(struct seq_file *seq_file, void *v)
{
@@ -72,13 +785,13 @@ static const struct file_operations mali_seq_internal_state_fops = {
#endif /* MALI_STATE_TRACKING */
-#if MALI_TIMELINE_PROFILING_ENABLED
+#if MALI_INTERNAL_TIMELINE_PROFILING_ENABLED
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_profiling_is_recording() ? 1 : 0);
+ r = sprintf(buf, "%u\n", _mali_osk_profiling_is_recording() ? 1 : 0);
return simple_read_from_buffer(ubuf, cnt, ppos, buf, r);
}
@@ -111,16 +824,16 @@ static ssize_t profiling_record_write(struct file *filp, const char __user *ubuf
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_profiling_is_recording())
+ if (MALI_TRUE == _mali_osk_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_profiling_have_recording())
+ if (MALI_TRUE == _mali_osk_profiling_have_recording())
{
- if (_MALI_OSK_ERR_OK != _mali_profiling_clear())
+ if (_MALI_OSK_ERR_OK != _mali_osk_profiling_clear())
{
MALI_DEBUG_PRINT(3, ("Failed to clear existing recording of profiling events\n"));
return -EFAULT;
@@ -128,7 +841,7 @@ static ssize_t profiling_record_write(struct file *filp, const char __user *ubuf
}
/* start recording profiling data */
- if (_MALI_OSK_ERR_OK != _mali_profiling_start(&limit))
+ if (_MALI_OSK_ERR_OK != _mali_osk_profiling_start(&limit))
{
MALI_DEBUG_PRINT(3, ("Failed to start recording of profiling events\n"));
return -EFAULT;
@@ -140,7 +853,7 @@ static ssize_t profiling_record_write(struct file *filp, const char __user *ubuf
{
/* stop recording profiling data */
u32 count = 0;
- if (_MALI_OSK_ERR_OK != _mali_profiling_stop(&count))
+ if (_MALI_OSK_ERR_OK != _mali_osk_profiling_stop(&count))
{
MALI_DEBUG_PRINT(2, ("Failed to stop recording of profiling events\n"));
return -EFAULT;
@@ -164,7 +877,7 @@ 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_profiling_have_recording())
+ if (MALI_TRUE != _mali_osk_profiling_have_recording())
{
return NULL;
}
@@ -184,13 +897,13 @@ 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_profiling_have_recording())
+ if (MALI_TRUE != _mali_osk_profiling_have_recording())
{
return NULL;
}
/* check if the next entry actually is avaiable */
- if (_mali_profiling_get_count() <= (u32)(*spos + 1))
+ if (_mali_osk_profiling_get_count() <= (u32)(*spos + 1))
{
return NULL;
}
@@ -215,7 +928,7 @@ static int profiling_events_show(struct seq_file *seq_file, void *v)
index = (u32)*spos;
/* Retrieve all events */
- if (_MALI_OSK_ERR_OK == _mali_profiling_get_event(index, &timestamp, &event_id, data))
+ if (_MALI_OSK_ERR_OK == _mali_osk_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;
@@ -243,68 +956,89 @@ static const struct file_operations profiling_events_fops = {
.llseek = seq_lseek,
.release = seq_release,
};
+#endif
-static ssize_t profiling_proc_default_enable_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos)
+static ssize_t memory_used_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos)
{
char buf[64];
- int r;
+ size_t r;
+ u32 mem = _mali_ukk_report_memory_usage();
- r = sprintf(buf, "%u\n", _mali_profiling_get_default_enable_state() ? 1 : 0);
+ r = snprintf(buf, 64, "%u\n", mem);
return simple_read_from_buffer(ubuf, cnt, ppos, buf, r);
}
-static ssize_t profiling_proc_default_enable_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos)
+static const struct file_operations memory_usage_fops = {
+ .owner = THIS_MODULE,
+ .read = memory_used_read,
+};
+
+
+static ssize_t user_settings_write(struct file *filp, const char __user *ubuf, size_t cnt, loff_t *ppos)
{
- char buf[64];
unsigned long val;
int ret;
+ _mali_uk_user_setting_t setting;
+ char buf[32];
- if (cnt >= sizeof(buf))
- {
- return -EINVAL;
- }
-
- if (copy_from_user(&buf, ubuf, cnt))
+ cnt = min(cnt, sizeof(buf) - 1);
+ if (copy_from_user(buf, ubuf, cnt))
{
return -EFAULT;
}
-
- buf[cnt] = 0;
+ buf[cnt] = '\0';
ret = strict_strtoul(buf, 10, &val);
- if (ret < 0)
+ if (0 != ret)
{
return ret;
}
- _mali_profiling_set_default_enable_state(val != 0 ? MALI_TRUE : MALI_FALSE);
+ /* Update setting */
+ setting = (_mali_uk_user_setting_t)(filp->private_data);
+ mali_set_user_setting(setting, val);
*ppos += cnt;
return cnt;
}
-static const struct file_operations profiling_proc_default_enable_fops = {
- .owner = THIS_MODULE,
- .read = profiling_proc_default_enable_read,
- .write = profiling_proc_default_enable_write,
-};
-#endif
-
-static ssize_t memory_used_read(struct file *filp, char __user *ubuf, size_t cnt, loff_t *ppos)
+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 mem = _mali_ukk_report_memory_usage();
+ u32 value;
+ _mali_uk_user_setting_t setting;
- r = snprintf(buf, 64, "%u\n", mem);
+ 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 memory_usage_fops = {
+static const struct file_operations user_settings_fops = {
.owner = THIS_MODULE,
- .read = memory_used_read,
+ .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;
+}
+
int mali_sysfs_register(struct mali_dev *device, dev_t dev, const char *mali_dev_name)
{
int err = 0;
@@ -334,8 +1068,151 @@ int mali_sysfs_register(struct mali_dev *device, dev_t dev, const char *mali_dev
if(NULL != mali_debugfs_dir)
{
/* Debugfs directory created successfully; create files now */
-#if MALI_TIMELINE_PROFILING_ENABLED
- struct dentry *mali_profiling_dir = debugfs_create_dir("profiling", mali_debugfs_dir);
+ struct dentry *mali_power_dir;
+ struct dentry *mali_gp_dir;
+ struct dentry *mali_pp_dir;
+ struct dentry *mali_l2_dir;
+#if MALI_INTERNAL_TIMELINE_PROFILING_ENABLED
+ struct dentry *mali_profiling_dir;
+#endif
+
+ mali_power_dir = debugfs_create_dir("power", mali_debugfs_dir);
+ if (mali_power_dir != NULL)
+ {
+ debugfs_create_file("power_events", 0400, mali_power_dir, NULL, &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 ci;
+ struct mali_cluster *cluster;
+
+ mali_gp_all_dir = debugfs_create_dir("all", mali_gp_dir);
+ if (mali_gp_all_dir != NULL)
+ {
+ debugfs_create_file("counter_src0", 0400, mali_gp_all_dir, NULL, &gp_all_counter_src0_fops);
+ debugfs_create_file("counter_src1", 0400, mali_gp_all_dir, NULL, &gp_all_counter_src1_fops);
+ }
+
+ ci = 0;
+ cluster = mali_cluster_get_global_cluster(ci);
+ while (NULL != cluster)
+ {
+ u32 gi = 0;
+ struct mali_group *group = mali_cluster_get_group(cluster, gi);
+ while (NULL != group)
+ {
+ 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);
+ }
+ break; /* no need to look for any other GP cores */
+ }
+
+ /* try next group */
+ gi++;
+ group = mali_cluster_get_group(cluster, gi);
+ }
+
+ /* try next cluster */
+ ci++;
+ cluster = mali_cluster_get_global_cluster(ci);
+ }
+ }
+
+ mali_pp_dir = debugfs_create_dir("pp", mali_debugfs_dir);
+ if (mali_pp_dir != NULL)
+ {
+ struct dentry *mali_pp_all_dir;
+ u32 ci;
+ struct mali_cluster *cluster;
+
+ mali_pp_all_dir = debugfs_create_dir("all", mali_pp_dir);
+ if (mali_pp_all_dir != NULL)
+ {
+ debugfs_create_file("counter_src0", 0400, mali_pp_all_dir, NULL, &pp_all_counter_src0_fops);
+ debugfs_create_file("counter_src1", 0400, mali_pp_all_dir, NULL, &pp_all_counter_src1_fops);
+ }
+
+ ci = 0;
+ cluster = mali_cluster_get_global_cluster(ci);
+ while (NULL != cluster)
+ {
+ u32 gi = 0;
+ struct mali_group *group = mali_cluster_get_group(cluster, gi);
+ while (NULL != group)
+ {
+ 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);
+ }
+ }
+
+ /* try next group */
+ gi++;
+ group = mali_cluster_get_group(cluster, gi);
+ }
+
+ /* try next cluster */
+ ci++;
+ cluster = mali_cluster_get_global_cluster(ci);
+ }
+ }
+
+ 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", 0400, mali_l2_all_dir, NULL, &l2_all_counter_src0_fops);
+ debugfs_create_file("counter_src1", 0400, 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);
+ }
+
+ /* 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);
+
+#if MALI_INTERNAL_TIMELINE_PROFILING_ENABLED
+ 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);
@@ -344,7 +1221,7 @@ int mali_sysfs_register(struct mali_dev *device, dev_t dev, const char *mali_dev
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, NULL, &profiling_proc_default_enable_fops);
+ 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);
@@ -356,7 +1233,11 @@ int mali_sysfs_register(struct mali_dev *device, dev_t dev, const char *mali_dev
debugfs_create_file("state_dump", 0400, mali_debugfs_dir, NULL, &mali_seq_internal_state_fops);
#endif
- debugfs_create_file("memory_usage", 0400, mali_debugfs_dir, NULL, &memory_usage_fops);
+ 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"));
+ }
}
}
@@ -385,7 +1266,7 @@ int mali_sysfs_unregister(struct mali_dev *device, dev_t dev, const char *mali_d
#else
-/* Dummy implementations for when the sysfs API isn't available. */
+/* Dummy implementations for non-GPL */
int mali_sysfs_register(struct mali_dev *device, dev_t dev, const char *mali_dev_name)
{
diff --git a/drivers/media/video/samsung/mali/linux/mali_kernel_sysfs.h b/drivers/media/video/samsung/mali/linux/mali_kernel_sysfs.h
index f68b4e1..d79a886 100644
--- a/drivers/media/video/samsung/mali/linux/mali_kernel_sysfs.h
+++ b/drivers/media/video/samsung/mali/linux/mali_kernel_sysfs.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 ARM Limited. All rights reserved.
+ * Copyright (C) 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.
diff --git a/drivers/media/video/samsung/mali/linux/mali_linux_pm.h b/drivers/media/video/samsung/mali/linux/mali_linux_pm.h
index a8c0c52..10f633e 100644
--- a/drivers/media/video/samsung/mali/linux/mali_linux_pm.h
+++ b/drivers/media/video/samsung/mali/linux/mali_linux_pm.h
@@ -1,5 +1,6 @@
+
/*
- * Copyright (C) 2010 ARM Limited. All rights reserved.
+ * 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.
@@ -11,8 +12,6 @@
#ifndef __MALI_LINUX_PM_H__
#define __MALI_LINUX_PM_H__
-#if USING_MALI_PMM
-
#ifdef CONFIG_PM
/* Number of power states supported for making power up and down */
typedef enum
@@ -20,7 +19,6 @@ typedef enum
_MALI_DEVICE_SUSPEND, /* Suspend */
_MALI_DEVICE_RESUME, /* Resume */
_MALI_DEVICE_MAX_POWER_STATES, /* Maximum power states */
- _MALI_DEVICE_SHUTDOWN, /* Power off states*/
} _mali_device_power_states;
/* Number of DVFS events */
@@ -49,5 +47,4 @@ int mali_device_resume(u32 event_id, struct task_struct **pwr_mgmt_thread);
int mali_get_ospmm_thread_state(void);
#endif /* CONFIG_PM */
-#endif /* USING_MALI_PMM */
#endif /* __MALI_LINUX_PM_H___ */
diff --git a/drivers/media/video/samsung/mali/linux/mali_linux_pm_testsuite.h b/drivers/media/video/samsung/mali/linux/mali_linux_pm_testsuite.h
index 7b1bff9..7d811bd 100644
--- a/drivers/media/video/samsung/mali/linux/mali_linux_pm_testsuite.h
+++ b/drivers/media/video/samsung/mali/linux/mali_linux_pm_testsuite.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 ARM Limited. All rights reserved.
+ * 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.
@@ -10,9 +10,7 @@
#ifndef __MALI_LINUX_PM_TESTSUITE_H__
#define __MALI_LINUX_PM_TESTSUITE_H__
-#if USING_MALI_PMM
-#if MALI_POWER_MGMT_TEST_SUITE
-#ifdef CONFIG_PM
+#if MALI_POWER_MGMT_TEST_SUITE && defined(CONFIG_PM)
typedef enum
{
@@ -29,9 +27,6 @@ extern unsigned int pwr_mgmt_status_reg;
extern unsigned int is_mali_pmm_testsuite_enabled;
extern unsigned int is_mali_pmu_present;
-#endif /* CONFIG_PM */
-#endif /* MALI_POWER_MGMT_TEST_SUITE */
-#endif /* USING_MALI_PMM */
-#endif /* __MALI_LINUX_PM_TESTSUITE_H__ */
-
+#endif /* MALI_POWER_MGMT_TEST_SUITE && defined(CONFIG_PM) */
+#endif /* __MALI_LINUX_PM_TESTSUITE_H__ */
diff --git a/drivers/media/video/samsung/mali/linux/mali_linux_trace.h b/drivers/media/video/samsung/mali/linux/mali_linux_trace.h
index 3ce1e50..09afcb3 100644
--- a/drivers/media/video/samsung/mali/linux/mali_linux_trace.h
+++ b/drivers/media/video/samsung/mali/linux/mali_linux_trace.h
@@ -1,93 +1,125 @@
-#if !defined(_TRACE_MALI_H) || defined(TRACE_HEADER_MULTI_READ)
-#define _TRACE_MALI_H
+/*
+ * 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
+#undef TRACE_SYSTEM
#define TRACE_SYSTEM mali
-#define TRACE_SYSTEM_STRING __stringify(TRACE_SYSTEM)
+#define TRACE_SYSTEM_STRING __stringfy(TRACE_SYSTEM)
+
+#define TRACE_INCLUDE_PATH .
#define TRACE_INCLUDE_FILE mali_linux_trace
/**
- * mali_timeline_event - called from the central collection point (_mali_profiling_add_event)
- * @event_id: ORed together bitfields representing a type of event
- * In the future we might add
- * @timestamp
- * @data[5] - this currently includes thread and process id's - we should have EGLConfig or similar too
+ * 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.
*
- * Just make a record of the event_id, we'll decode it elsewhere
+ * @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),
+ 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),
+ TP_ARGS(event_id, d0, d1, d2, d3, d4),
- TP_STRUCT__entry(
- __field( int, event_id )
- ),
+ 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;
- ),
+ 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)
+ TP_printk("event=%d", __entry->event_id)
);
/**
- * mali_hw_counter - called from the ????
- * @event_id: event being counted
- * In the future we might add
- * @timestamp ??
+ * 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.
*
- * Just make a record of the event_id and value
+ * @param counter_id The counter ID.
+ * @param value The value of the counter.
*/
-TRACE_EVENT(mali_hw_counter,
+TRACE_EVENT(mali_hw_counter,
- TP_PROTO(unsigned int event_id, unsigned int value),
+ TP_PROTO(unsigned int counter_id, unsigned int value),
- TP_ARGS(event_id, value),
+ TP_ARGS(counter_id, value),
- TP_STRUCT__entry(
- __field( int, event_id )
- __field( int, value )
- ),
+ TP_STRUCT__entry(
+ __field(unsigned int, counter_id)
+ __field(unsigned int, value)
+ ),
- TP_fast_assign(
- __entry->event_id = event_id;
- ),
+ TP_fast_assign(
+ __entry->counter_id = counter_id;
+ ),
- TP_printk("event %d = %d", __entry->event_id, __entry->value)
+ TP_printk("event %d = %d", __entry->counter_id, __entry->value)
);
/**
- * mali_sw_counter
- * @event_id: counter id
+ * Define a tracepoint used to send a bundle of software counters.
+ *
+ * @param counters The bundle of counters.
*/
-TRACE_EVENT(mali_sw_counter,
+TRACE_EVENT(mali_sw_counters,
- TP_PROTO(unsigned int event_id, signed long long value),
+ TP_PROTO(pid_t pid, pid_t tid, void * surface_id, unsigned int * counters),
- TP_ARGS(event_id, value),
+ TP_ARGS(pid, tid, surface_id, counters),
TP_STRUCT__entry(
- __field( int, event_id )
- __field( long long, value )
+ __field(pid_t, pid)
+ __field(pid_t, tid)
+ __field(void *, surface_id)
+ __field(unsigned int *, counters)
),
TP_fast_assign(
- __entry->event_id = event_id;
+ __entry->pid = pid;
+ __entry->tid = tid;
+ __entry->surface_id = surface_id;
+ __entry->counters = counters;
),
- TP_printk("event %d = %lld", __entry->event_id, __entry->value)
+ TP_printk("counters were %s", __entry->counters == NULL? "NULL" : "not NULL")
);
-#endif /* _TRACE_MALI_H */
-
-#undef TRACE_INCLUDE_PATH
-#undef linux
-#define TRACE_INCLUDE_PATH .
+#endif /* MALI_LINUX_TRACE_H */
-/* This part must be outside protection */
+/* This part must exist outside the header guard. */
#include <trace/define_trace.h>
+
diff --git a/drivers/media/video/samsung/mali/linux/mali_osk_indir_mmap.h b/drivers/media/video/samsung/mali/linux/mali_osk_indir_mmap.h
index 41cb462..f87739b 100644
--- a/drivers/media/video/samsung/mali/linux/mali_osk_indir_mmap.h
+++ b/drivers/media/video/samsung/mali/linux/mali_osk_indir_mmap.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 ARM Limited. All rights reserved.
+ * 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.
diff --git a/drivers/media/video/samsung/mali/linux/mali_osk_irq.c b/drivers/media/video/samsung/mali/linux/mali_osk_irq.c
index c597b9e..ddfe564 100644
--- a/drivers/media/video/samsung/mali/linux/mali_osk_irq.c
+++ b/drivers/media/video/samsung/mali/linux/mali_osk_irq.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 ARM Limited. All rights reserved.
+ * 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.
@@ -15,11 +15,12 @@
#include <linux/slab.h> /* For memory allocation */
#include <linux/workqueue.h>
+#include <linux/version.h>
#include "mali_osk.h"
-#include "mali_kernel_core.h"
#include "mali_kernel_common.h"
#include "mali_kernel_license.h"
+#include "mali_kernel_linux.h"
#include "linux/interrupt.h"
typedef struct _mali_osk_irq_t_struct
@@ -31,7 +32,10 @@ typedef struct _mali_osk_irq_t_struct
struct work_struct work_queue_irq_handle; /* Workqueue for the bottom half of the IRQ-handling. This job is activated when this core gets an IRQ.*/
} mali_osk_irq_object_t;
-static struct workqueue_struct *mali_irq_wq=NULL;
+#if MALI_LICENSE_IS_GPL
+static struct workqueue_struct *pmm_wq = NULL;
+struct workqueue_struct *mali_wq = NULL;
+#endif
typedef void (*workqueue_func_t)(void *);
typedef irqreturn_t (*irq_handler_func_t)(int, void *, struct pt_regs *);
@@ -58,6 +62,23 @@ _mali_osk_irq_t *_mali_osk_irq_init( u32 irqnum, _mali_osk_irq_uhandler_t uhandl
irq_object = kmalloc(sizeof(mali_osk_irq_object_t), GFP_KERNEL);
if (NULL == irq_object) return NULL;
+#if MALI_LICENSE_IS_GPL
+ if (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"));
+ kfree(irq_object);
+ return NULL;
+ }
+ }
+#endif
+
/* workqueue API changed in 2.6.20, support both versions: */
#if defined(INIT_DELAYED_WORK)
/* New syntax: INIT_WORK( struct work_struct *work, void (*function)(struct work_struct *)) */
@@ -107,14 +128,14 @@ _mali_osk_irq_t *_mali_osk_irq_init( u32 irqnum, _mali_osk_irq_uhandler_t uhandl
MALI_DEBUG_PRINT(2, ("Probe for irq failed\n"));
}
}
-
+
irq_object->irqnum = irqnum;
irq_object->uhandler = uhandler;
irq_object->bhandler = bhandler;
irq_object->data = data;
/* Is this a real IRQ handler we need? */
- if (!mali_benchmark && irqnum != _MALI_OSK_IRQ_NUMBER_FAKE && irqnum != _MALI_OSK_IRQ_NUMBER_PMM)
+ if (irqnum != _MALI_OSK_IRQ_NUMBER_FAKE && irqnum != _MALI_OSK_IRQ_NUMBER_PMM)
{
if (-1 == irqnum)
{
@@ -131,10 +152,12 @@ _mali_osk_irq_t *_mali_osk_irq_init( u32 irqnum, _mali_osk_irq_uhandler_t uhandl
}
}
- if (mali_irq_wq == NULL)
+#if MALI_LICENSE_IS_GPL
+ if ( _MALI_OSK_IRQ_NUMBER_PMM == irqnum )
{
- mali_irq_wq = create_singlethread_workqueue("mali-pmm-wq");
+ pmm_wq = create_singlethread_workqueue("mali-pmm-wq");
}
+#endif
return irq_object;
}
@@ -142,29 +165,54 @@ _mali_osk_irq_t *_mali_osk_irq_init( u32 irqnum, _mali_osk_irq_uhandler_t uhandl
void _mali_osk_irq_schedulework( _mali_osk_irq_t *irq )
{
mali_osk_irq_object_t *irq_object = (mali_osk_irq_object_t *)irq;
- queue_work_on(0, mali_irq_wq,&irq_object->work_queue_irq_handle);
+#if MALI_LICENSE_IS_GPL
+ if ( irq_object->irqnum == _MALI_OSK_IRQ_NUMBER_PMM )
+ {
+ queue_work( pmm_wq,&irq_object->work_queue_irq_handle );
+ }
+ else
+ {
+ queue_work(mali_wq, &irq_object->work_queue_irq_handle);
+ }
+#else
+ schedule_work(&irq_object->work_queue_irq_handle);
+#endif
}
void _mali_osk_flush_workqueue( _mali_osk_irq_t *irq )
{
- flush_workqueue(mali_irq_wq );
+#if MALI_LICENSE_IS_GPL
+ if (NULL != irq)
+ {
+ mali_osk_irq_object_t *irq_object = (mali_osk_irq_object_t *)irq;
+ if(irq_object->irqnum == _MALI_OSK_IRQ_NUMBER_PMM )
+ {
+ flush_workqueue(pmm_wq);
+ }
+ else
+ {
+ flush_workqueue(mali_wq);
+ }
+ }
+ else
+ {
+ flush_workqueue(mali_wq);
+ }
+#endif
}
void _mali_osk_irq_term( _mali_osk_irq_t *irq )
{
mali_osk_irq_object_t *irq_object = (mali_osk_irq_object_t *)irq;
- if(mali_irq_wq != NULL)
- {
- flush_workqueue(mali_irq_wq);
- destroy_workqueue(mali_irq_wq);
- mali_irq_wq = NULL;
- }
-
- if (!mali_benchmark)
+#if MALI_LICENSE_IS_GPL
+ if(irq_object->irqnum == _MALI_OSK_IRQ_NUMBER_PMM )
{
- free_irq(irq_object->irqnum, irq_object);
+ flush_workqueue(pmm_wq);
+ destroy_workqueue(pmm_wq);
}
+#endif
+ free_irq(irq_object->irqnum, irq_object);
kfree(irq_object);
flush_scheduled_work();
}
diff --git a/drivers/media/video/samsung/mali/linux/mali_osk_locks.c b/drivers/media/video/samsung/mali/linux/mali_osk_locks.c
index aad6fc6..0297c77 100644
--- a/drivers/media/video/samsung/mali/linux/mali_osk_locks.c
+++ b/drivers/media/video/samsung/mali/linux/mali_osk_locks.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 ARM Limited. All rights reserved.
+ * 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.
@@ -51,7 +51,7 @@ typedef enum
struct _mali_osk_lock_t_struct
{
_mali_osk_internal_locktype type;
- unsigned long flags;
+ unsigned long flags;
union
{
spinlock_t spinlock;
@@ -61,6 +61,15 @@ struct _mali_osk_lock_t_struct
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;
+ /* number of owners this lock currently has (can be > 1 if
+ * taken in R/O mode. */
+ u32 nOwners;
+ /* what mode the lock was taken in */
+ _mali_osk_lock_mode_t mode;
); /* MALI_DEBUG_CODE */
};
@@ -71,11 +80,11 @@ _mali_osk_lock_t *_mali_osk_lock_init( _mali_osk_lock_flags_t flags, u32 initial
/* 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 )) );
+ | _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));
@@ -126,14 +135,35 @@ _mali_osk_lock_t *_mali_osk_lock_init( _mali_osk_lock_flags_t flags, u32 initial
sema_init( &lock->obj.sema, 1 );
}
- MALI_DEBUG_CODE(
- /* Debug tracking of flags */
- lock->orig_flags = flags;
- ); /* MALI_DEBUG_CODE */
+#ifdef DEBUG
+ /* Debug tracking of flags */
+ lock->orig_flags = flags;
+
+ /* Debug tracking of lock owner */
+ lock->owner = 0;
+ lock->nOwners = 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_number_owners( _mali_osk_lock_t *lock )
+{
+ return lock->nOwners;
+}
+
+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;
@@ -162,6 +192,7 @@ _mali_osk_errcode_t _mali_osk_lock_wait( _mali_osk_lock_t *lock, _mali_osk_lock_
case _MALI_OSK_INTERNAL_LOCKTYPE_MUTEX:
if ( down_interruptible(&lock->obj.sema) )
{
+ MALI_PRINT_ERROR(("Can not lock mutex\n"));
err = _MALI_OSK_ERR_RESTARTSYSCALL;
}
break;
@@ -188,6 +219,31 @@ _mali_osk_errcode_t _mali_osk_lock_wait( _mali_osk_lock_t *lock, _mali_osk_lock_
break;
}
+#ifdef DEBUG
+ /* This thread is now the owner of this lock */
+ if (_MALI_OSK_ERR_OK == err)
+ {
+ if (mode == _MALI_OSK_LOCKMODE_RW)
+ {
+ /*MALI_DEBUG_ASSERT(0 == lock->owner);*/
+ 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;
+ ++lock->nOwners;
+ }
+ else /* mode == _MALI_OSK_LOCKMODE_RO */
+ {
+ lock->owner |= _mali_osk_get_tid();
+ lock->mode = mode;
+ ++lock->nOwners;
+ }
+ }
+#endif
+
return err;
}
@@ -205,6 +261,37 @@ void _mali_osk_lock_signal( _mali_osk_lock_t *lock, _mali_osk_lock_mode_t mode )
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)
+ {
+ /*MALI_DEBUG_ASSERT(_mali_osk_get_tid() == lock->owner);*/
+ 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;
+ --lock->nOwners;
+ }
+ else /* mode == _MALI_OSK_LOCKMODE_RO */
+ {
+ if ((_mali_osk_get_tid() & lock->owner) != _mali_osk_get_tid())
+ {
+ printk(KERN_ERR "%d: ERROR: Not an owner of %p lock.\n", _mali_osk_get_tid(), lock);
+ dump_stack();
+ }
+
+ /* if this is the last thread holding this lock in R/O mode, set owner
+ * back to 0 */
+ if (0 == --lock->nOwners)
+ {
+ lock->owner = 0;
+ }
+ }
+#endif /* DEBUG */
+
switch ( lock->type )
{
case _MALI_OSK_INTERNAL_LOCKTYPE_SPIN:
diff --git a/drivers/media/video/samsung/mali/linux/mali_osk_low_level_mem.c b/drivers/media/video/samsung/mali/linux/mali_osk_low_level_mem.c
index c0aecb8..5767912 100644
--- a/drivers/media/video/samsung/mali/linux/mali_osk_low_level_mem.c
+++ b/drivers/media/video/samsung/mali/linux/mali_osk_low_level_mem.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 ARM Limited. All rights reserved.
+ * 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.
@@ -76,12 +76,7 @@ static void _allocation_list_item_release(AllocationList * item);
/* Variable declarations */
-#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,36)
-spinlock_t allocation_list_spinlock = SPIN_LOCK_UNLOCKED;
-#else
-DEFINE_SPINLOCK(allocation_list_spinlock);
-#endif
-
+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
@@ -124,9 +119,9 @@ 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 0;
@@ -145,7 +140,7 @@ static void _kernel_page_release(u32 physical_address)
#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 );
@@ -155,19 +150,19 @@ 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)
{
@@ -197,7 +192,7 @@ static void _allocation_list_item_release(AllocationList * item)
return;
}
spin_unlock_irqrestore(&allocation_list_spinlock,flags);
-
+
_kernel_page_release(item->physaddr);
_mali_osk_free( item );
}
@@ -244,7 +239,6 @@ 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;
- MappingInfo *mappingInfo;
MALI_DEBUG_PRINT(3, ("Close called on vma %p\n", vma));
vma_usage_tracker = (mali_vma_usage_tracker*)vma->vm_private_data;
@@ -254,11 +248,6 @@ static void mali_kernel_memory_vma_close(struct vm_area_struct * vma)
vma_usage_tracker->references--;
- descriptor = (mali_memory_allocation *)vma_usage_tracker->cookie;
-
- mappingInfo = (MappingInfo *)descriptor->process_addr_mapping_info;
- mappingInfo->vma = vma;
-
if (0 != vma_usage_tracker->references)
{
MALI_DEBUG_PRINT(3, ("Ignoring this close, %d references still exists\n", vma_usage_tracker->references));
@@ -268,6 +257,8 @@ static void mali_kernel_memory_vma_close(struct vm_area_struct * vma)
/** @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;
diff --git a/drivers/media/video/samsung/mali/linux/mali_osk_mali.c b/drivers/media/video/samsung/mali/linux/mali_osk_mali.c
index ab571c1..3def446 100644
--- a/drivers/media/video/samsung/mali/linux/mali_osk_mali.c
+++ b/drivers/media/video/samsung/mali/linux/mali_osk_mali.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 ARM Limited. All rights reserved.
+ * 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.
@@ -18,27 +18,10 @@
#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" /* exports initialize/terminate_kernel_device() definition of mali_osk_low_level_mem_init() and term */
+#include "mali_kernel_linux.h"
#include <mach/irqs.h>
#include "arch/config.h" /* contains the configuration of the arch we are compiling for */
-/* is called from mali_kernel_constructor in common code */
-_mali_osk_errcode_t _mali_osk_init( void )
-{
- if (0 != initialize_kernel_device()) MALI_ERROR(_MALI_OSK_ERR_FAULT);
-
- mali_osk_low_level_mem_init();
-
- MALI_SUCCESS;
-}
-
-/* is called from mali_kernel_deconstructor in common code */
-void _mali_osk_term( void )
-{
- mali_osk_low_level_mem_term();
- terminate_kernel_device();
-}
-
_mali_osk_errcode_t _mali_osk_resources_init( _mali_osk_resource_t **arch_config, u32 *num_resources )
{
*num_resources = sizeof(arch_configuration) / sizeof(arch_configuration[0]);
diff --git a/drivers/media/video/samsung/mali/linux/mali_osk_memory.c b/drivers/media/video/samsung/mali/linux/mali_osk_memory.c
index 871505a..7bb470f 100644
--- a/drivers/media/video/samsung/mali/linux/mali_osk_memory.c
+++ b/drivers/media/video/samsung/mali/linux/mali_osk_memory.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 ARM Limited. All rights reserved.
+ * 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.
diff --git a/drivers/media/video/samsung/mali/linux/mali_osk_misc.c b/drivers/media/video/samsung/mali/linux/mali_osk_misc.c
index e37e8c0..ad486db 100644
--- a/drivers/media/video/samsung/mali/linux/mali_osk_misc.c
+++ b/drivers/media/video/samsung/mali/linux/mali_osk_misc.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 ARM Limited. All rights reserved.
+ * 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.
@@ -33,7 +33,7 @@ u32 _mali_osk_snprintf( char *buf, u32 size, const char *fmt, ... )
va_list args;
va_start(args, fmt);
- res = vsnprintf(buf, (size_t)size, fmt, args);
+ res = vscnprintf(buf, (size_t)size, fmt, args);
va_end(args);
return res;
@@ -42,6 +42,7 @@ u32 _mali_osk_snprintf( char *buf, u32 size, const char *fmt, ... )
void _mali_osk_abort(void)
{
/* make a simple fault by dereferencing a NULL pointer */
+ dump_stack();
*(int *)0 = 0;
}
diff --git a/drivers/media/video/samsung/mali/linux/mali_osk_notification.c b/drivers/media/video/samsung/mali/linux/mali_osk_notification.c
index eef839f..c14c0d5 100644
--- a/drivers/media/video/samsung/mali/linux/mali_osk_notification.c
+++ b/drivers/media/video/samsung/mali/linux/mali_osk_notification.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 ARM Limited. All rights reserved.
+ * 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.
@@ -15,8 +15,6 @@
#include "mali_osk.h"
#include "mali_kernel_common.h"
-#include "mali_pmm.h"
-#include "mali_pmm_state.h"
/* needed to detect kernel version specific code */
#include <linux/version.h>
@@ -67,12 +65,8 @@ _mali_osk_notification_t *_mali_osk_notification_create( u32 type, u32 size )
/* OPT Recycling of notification objects */
_mali_osk_notification_wrapper_t *notification;
- if (MALI_PMM_NOTIFICATION_TYPE == type) {
- if (size != sizeof(mali_pmm_message_t))
- return NULL;
- }
-
- notification = (_mali_osk_notification_wrapper_t *)kmalloc( sizeof(_mali_osk_notification_wrapper_t) + size, GFP_KERNEL );
+ 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"));
@@ -92,7 +86,6 @@ _mali_osk_notification_t *_mali_osk_notification_create( u32 type, u32 size )
}
/* set up the non-allocating fields */
- notification->data.magic_code = 0x31415926;
notification->data.notification_type = type;
notification->data.result_buffer_size = size;
@@ -107,8 +100,6 @@ void _mali_osk_notification_delete( _mali_osk_notification_t *object )
notification = container_of( object, _mali_osk_notification_wrapper_t, data );
- /* Remove from the list */
- list_del(&notification->list);
/* Free the container */
kfree(notification);
}
@@ -169,15 +160,7 @@ _mali_osk_errcode_t _mali_osk_notification_queue_dequeue( _mali_osk_notification
wrapper_object = list_entry(queue->head.next, _mali_osk_notification_wrapper_t, list);
*result = &(wrapper_object->data);
list_del_init(&wrapper_object->list);
-
- if (wrapper_object->data.magic_code != 0x31415926) {
- MALI_PRINT(("SEC WARNING : list entry magic_code not match : %x\n", wrapper_object->data.magic_code));
- MALI_PRINT(("SEC WARNING : list entry notification type : %x\n", wrapper_object->data.notification_type));
- MALI_PRINT(("SEC WARNING : list entry result buffer size : %x\n", wrapper_object->data.result_buffer_size));
- MALI_PRINT(("SEC WARNING : list entry result buffer : %x\n", wrapper_object->data.result_buffer));
- } else {
- ret = _MALI_OSK_ERR_OK;
- }
+ ret = _MALI_OSK_ERR_OK;
}
up(&queue->mutex);
diff --git a/drivers/media/video/samsung/mali/linux/mali_osk_pm.c b/drivers/media/video/samsung/mali/linux/mali_osk_pm.c
index 2438cbc..20fb7b4 100644
--- a/drivers/media/video/samsung/mali/linux/mali_osk_pm.c
+++ b/drivers/media/video/samsung/mali/linux/mali_osk_pm.c
@@ -1,5 +1,5 @@
-/*
- * Copyright (C) 2010 ARM Limited. All rights reserved.
+/**
+ * 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.
@@ -18,193 +18,67 @@
#ifdef CONFIG_PM_RUNTIME
#include <linux/pm_runtime.h>
#endif /* CONFIG_PM_RUNTIME */
-
#include <linux/platform_device.h>
-
#include "mali_platform.h"
#include "mali_osk.h"
#include "mali_uk_types.h"
-#include "mali_pmm.h"
#include "mali_kernel_common.h"
#include "mali_kernel_license.h"
#include "mali_linux_pm.h"
-#include "mali_linux_pm_testsuite.h"
-
-#if MALI_LICENSE_IS_GPL
-#if MALI_PMM_RUNTIME_JOB_CONTROL_ON
-#ifdef CONFIG_PM_RUNTIME
-static int is_runtime =0;
-#endif /* CONFIG_PM_RUNTIME */
-#endif /* MALI_PMM_RUNTIME_JOB_CONTROL_ON */
-#endif /* MALI_LICENSE_IS_GPL */
-
-#if MALI_POWER_MGMT_TEST_SUITE
-
-#ifdef CONFIG_PM
-unsigned int mali_pmm_events_triggered_mask = 0;
-#endif /* CONFIG_PM */
-
-void _mali_osk_pmm_policy_events_notifications(mali_pmm_event_id mali_pmm_event)
-{
-#if MALI_LICENSE_IS_GPL
-#ifdef CONFIG_PM
-
- switch (mali_pmm_event)
- {
- case MALI_PMM_EVENT_JOB_QUEUED:
- if (mali_job_scheduling_events_recording_on == 1)
- {
- mali_pmm_events_triggered_mask |= (1<<0);
- }
- break;
-
- case MALI_PMM_EVENT_JOB_SCHEDULED:
- if (mali_job_scheduling_events_recording_on == 1)
- {
- mali_pmm_events_triggered_mask |= (1<<1);
- }
- break;
-
- case MALI_PMM_EVENT_JOB_FINISHED:
- if (mali_job_scheduling_events_recording_on == 1)
- {
- mali_pmm_events_triggered_mask |= (1<<2);
- mali_job_scheduling_events_recording_on = 0;
- pwr_mgmt_status_reg = mali_pmm_events_triggered_mask;
- }
- break;
-
- case MALI_PMM_EVENT_TIMEOUT:
- if (mali_timeout_event_recording_on == 1)
- {
- pwr_mgmt_status_reg = (1<<3);
- mali_timeout_event_recording_on = 0;
- }
- break;
-
- default:
+#include "mali_kernel_license.h"
- break;
+#if ! MALI_LICENSE_IS_GPL
+#undef CONFIG_PM_RUNTIME
+#endif
- }
-#endif /* CONFIG_PM */
+extern struct platform_device mali_gpu_device;
-#endif /* MALI_LICENSE_IS_GPL */
-}
-#endif /* MALI_POWER_MGMT_TEST_SUITE */
-
-/** This function is called when the Mali device has completed power up
- * operation.
- */
-void _mali_osk_pmm_power_up_done(mali_pmm_message_data data)
-{
-#if MALI_LICENSE_IS_GPL
-#ifdef CONFIG_PM
- is_wake_up_needed = 1;
- wake_up_process(pm_thread);
- MALI_DEBUG_PRINT(4, ("OSPMM: MALI OSK Power up Done\n" ));
- return;
-#endif /* CONFIG_PM */
-#endif /* MALI_LICENSE_IS_GPL */
-}
+#ifdef CONFIG_PM_RUNTIME
+static mali_bool have_runtime_reference = MALI_FALSE;
+#endif
-/** This function is called when the Mali device has completed power down
- * operation.
- */
-void _mali_osk_pmm_power_down_done(mali_pmm_message_data data)
+void _mali_osk_pm_dev_enable(void)
{
-#if MALI_LICENSE_IS_GPL
-#ifdef CONFIG_PM
- is_wake_up_needed = 1;
-#if MALI_POWER_MGMT_TEST_SUITE
- if (is_mali_pmu_present == 0)
- {
- pwr_mgmt_status_reg = _mali_pmm_cores_list();
- }
-#endif /* MALI_POWER_MGMT_TEST_SUITE */
- wake_up_process(pm_thread);
- MALI_DEBUG_PRINT(4, ("OSPMM: MALI Power down Done\n" ));
- return;
-
-#endif /* CONFIG_PM */
-#endif /* MALI_LICENSE_IS_GPL */
+#ifdef CONFIG_PM_RUNTIME
+ pm_runtime_enable(&(mali_gpu_device.dev));
+#endif
}
-/** This function is invoked when mali device is idle.
-*/
-_mali_osk_errcode_t _mali_osk_pmm_dev_idle(void)
+/* NB: Function is not thread safe */
+_mali_osk_errcode_t _mali_osk_pm_dev_idle(void)
{
- _mali_osk_errcode_t err = 0;
-#if MALI_LICENSE_IS_GPL
#ifdef CONFIG_PM_RUNTIME
-#if MALI_PMM_RUNTIME_JOB_CONTROL_ON
- err = pm_runtime_put_sync(&(mali_gpu_device.dev));
- if(err)
+ if (MALI_TRUE == have_runtime_reference)
{
- MALI_DEBUG_PRINT(4, ("OSPMM: Error in _mali_osk_pmm_dev_idle\n" ));
+ int err;
+ err = pm_runtime_put_sync(&(mali_gpu_device.dev));
+ if (0 > err)
+ {
+ MALI_PRINT_ERROR(("OSK PM: pm_runtime_put_sync() returned error code %d\n", err));
+ return _MALI_OSK_ERR_FAULT;
+ }
+ have_runtime_reference = MALI_FALSE;
}
-#endif /* MALI_PMM_RUNTIME_JOB_CONTROL_ON */
-#endif /* CONFIG_PM_RUNTIME */
-#endif /* MALI_LICENSE_IS_GPL */
- return err;
+#endif
+ return _MALI_OSK_ERR_OK;
}
-/** This funtion is invoked when mali device needs to be activated.
-*/
-int _mali_osk_pmm_dev_activate(void)
+/* NB: Function is not thread safe */
+_mali_osk_errcode_t _mali_osk_pm_dev_activate(void)
{
-
-#if MALI_LICENSE_IS_GPL
#ifdef CONFIG_PM_RUNTIME
-#if MALI_PMM_RUNTIME_JOB_CONTROL_ON
- int err = 0;
- if(is_runtime == 0)
+ if (MALI_TRUE != have_runtime_reference)
{
- pm_suspend_ignore_children(&(mali_gpu_device.dev), true);
- pm_runtime_enable(&(mali_gpu_device.dev));
+ int err;
err = pm_runtime_get_sync(&(mali_gpu_device.dev));
- is_runtime = 1;
- }
- else
- {
- err = pm_runtime_get_sync(&(mali_gpu_device.dev));
- }
- if(err < 0)
- {
- MALI_PRINT(("OSPMM: Error in _mali_osk_pmm_dev_activate, err : %d\n",err ));
- }
-#endif /* MALI_PMM_RUNTIME_JOB_CONTROL_ON */
-#endif /* CONFIG_PM_RUNTIME */
-#endif /* MALI_LICENSE_IS_GPL */
-
- return err;
-}
-
-void _mali_osk_pmm_ospmm_cleanup( void )
-{
-#if MALI_LICENSE_IS_GPL
-#ifdef CONFIG_PM
- int thread_state;
- thread_state = mali_get_ospmm_thread_state();
- if (thread_state)
- {
- _mali_osk_pmm_dvfs_operation_done(0);
+ if (0 > err)
+ {
+ MALI_PRINT_ERROR(("OSK PM: pm_runtime_get_sync() returned error code %d\n", err));
+ return _MALI_OSK_ERR_FAULT;
+ }
+ have_runtime_reference = MALI_TRUE;
}
-#endif /* CONFIG_PM */
-#endif /* MALI_LICENSE_IS_GPL */
+#endif
+ return _MALI_OSK_ERR_OK;
}
-
-void _mali_osk_pmm_dvfs_operation_done(mali_pmm_message_data data)
-{
-#if MALI_LICENSE_IS_GPL
-#ifdef CONFIG_PM
- is_wake_up_needed = 1;
- wake_up_process(dvfs_pm_thread);
- MALI_DEBUG_PRINT(4, ("OSPMM: MALI OSK DVFS Operation done\n" ));
- return;
-#endif /* CONFIG_PM */
-#endif /* MALI_LICENSE_IS_GPL */
-}
-
-
diff --git a/drivers/media/video/samsung/mali/linux/mali_osk_profiling.c b/drivers/media/video/samsung/mali/linux/mali_osk_profiling.c
deleted file mode 100644
index 98d3937..0000000
--- a/drivers/media/video/samsung/mali/linux/mali_osk_profiling.c
+++ /dev/null
@@ -1,47 +0,0 @@
-#include <linux/module.h>
-#include "mali_linux_trace.h"
-#include "mali_osk.h"
-
-/* The Linux trace point for hardware activity (idle vs running) */
-void _mali_osk_profiling_add_event(u32 event_id, u32 data0)
-{
- trace_mali_timeline_event(event_id);
-}
-
-/* The Linux trace point for hardware counters */
-void _mali_osk_profiling_add_counter(u32 event_id, u32 data0)
-{
- trace_mali_hw_counter(event_id, data0);
-}
-
-/* This table stores the event to be counted by each counter
- * 0xFFFFFFFF is a special value which means disable counter
- */
-//TODO at the moment this table is indexed by the magic numbers
-//listed in gator_events_mali.c. In future these numbers should
-//be shared through the mali_linux_trace.h header
-u32 counter_table[17] = {0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
- 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
- 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
- 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
- 0xFFFFFFFF};
-
-/* Called by gator.ko to populate the table above */
-int _mali_osk_counter_event(u32 counter, u32 event)
-{
- /* Remember what has been set, and that a change has occured
- * When a job actually starts the code will program the registers
- */
- //TODO as above these magic numbers need to be moved to a header file
- if( counter >=5 && counter < 17 ) {
- counter_table[counter] = event;
-
- return 1;
- } else {
- printk("mali rjc: counter out of range (%d,%d)\n", counter, event);
- }
-
- return 0;
-}
-EXPORT_SYMBOL(_mali_osk_counter_event);
-
diff --git a/drivers/media/video/samsung/mali/linux/mali_osk_profiling_gator.c b/drivers/media/video/samsung/mali/linux/mali_osk_profiling_gator.c
new file mode 100644
index 0000000..75c888d
--- /dev/null
+++ b/drivers/media/video/samsung/mali/linux/mali_osk_profiling_gator.c
@@ -0,0 +1,262 @@
+/*
+ * 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_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_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_id == COUNTER_VP_C0)
+ {
+ struct mali_gp_core* gp_core = mali_gp_get_global_gp_core();
+ if (NULL != gp_core)
+ {
+ if (MALI_TRUE == mali_gp_core_set_counter_src0(gp_core, event_id))
+ {
+ return 1;
+ }
+ }
+ }
+ else if (counter_id == COUNTER_VP_C1)
+ {
+ struct mali_gp_core* gp_core = mali_gp_get_global_gp_core();
+ if (NULL != gp_core)
+ {
+ if (MALI_TRUE == mali_gp_core_set_counter_src1(gp_core, event_id))
+ {
+ return 1;
+ }
+ }
+ }
+ else if (counter_id >= COUNTER_FP0_C0 && counter_id <= COUNTER_FP3_C1)
+ {
+ u32 core_id = (counter_id - COUNTER_FP0_C0) >> 1;
+ struct mali_pp_core* pp_core = mali_pp_get_global_pp_core(core_id);
+ if (NULL != pp_core)
+ {
+ u32 counter_src = (counter_id - COUNTER_FP0_C0) & 1;
+ if (0 == counter_src)
+ {
+ if (MALI_TRUE == mali_pp_core_set_counter_src0(pp_core, event_id))
+ {
+ return 1;
+ }
+ }
+ else
+ {
+ if (MALI_TRUE == mali_pp_core_set_counter_src1(pp_core, event_id))
+ {
+ return 1;
+ }
+ }
+ }
+ }
+ else if (counter_id >= COUNTER_L2_C0 && counter_id <= COUNTER_L2_C1)
+ {
+ u32 core_id = (counter_id - COUNTER_L2_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_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 the first L2 cache.
+ * The L2 cache counters are unique in that they are polled by gator, rather than being
+ * transmitted via the tracepoint mechanism.
+ *
+ * @param src0 First L2 cache counter ID.
+ * @param val0 First L2 cache counter value.
+ * @param src1 Second L2 cache counter ID.
+ * @param val1 Second L2 cache counter value.
+ */
+void _mali_profiling_get_counters(u32 *src0, u32 *val0, u32 *src1, u32 *val1)
+{
+ struct mali_l2_cache_core *l2_cache = mali_l2_cache_core_get_glob_l2_core(0); /* @@@@ TODO: Fix hardcoded limit of maximum 1 L2 cache */
+ if (NULL != l2_cache)
+ {
+ 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, src0, val0, src1, val1);
+ /* @@@@ TODO: add error checking, if needed; src == MALI_HW_CORE_NO_COUNTER if not able to get value */
+ }
+ mali_l2_cache_unlock_power_state(l2_cache);
+ }
+}
+
+/*
+ * 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)
+
+/**
+ * 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 */
+ }
+}
+
+EXPORT_SYMBOL(_mali_profiling_set_event);
+EXPORT_SYMBOL(_mali_profiling_get_counters);
+EXPORT_SYMBOL(_mali_profiling_control);
diff --git a/drivers/media/video/samsung/mali/common/mali_kernel_profiling.c b/drivers/media/video/samsung/mali/linux/mali_osk_profiling_internal.c
index ca04b5f..9a423d2 100644
--- a/drivers/media/video/samsung/mali/common/mali_kernel_profiling.c
+++ b/drivers/media/video/samsung/mali/linux/mali_osk_profiling_internal.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 ARM Limited. All rights reserved.
+ * 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.
@@ -13,8 +13,8 @@
#include "mali_osk_mali.h"
#include "mali_ukk.h"
#include "mali_timestamp.h"
-#include "mali_kernel_profiling.h"
-#include "mali_linux_trace.h"
+#include "mali_osk_profiling.h"
+#include "mali_user_settings_db.h"
typedef struct mali_profiling_entry
{
@@ -39,16 +39,15 @@ static mali_profiling_entry* profile_entries = NULL;
static u32 profile_entry_count = 0;
static _mali_osk_atomic_t profile_insert_index;
static _mali_osk_atomic_t profile_entries_written;
-static mali_bool mali_profiling_default_enable = MALI_FALSE;
-_mali_osk_errcode_t _mali_profiling_init(mali_bool auto_start)
+_mali_osk_errcode_t _mali_osk_profiling_init(mali_bool auto_start)
{
profile_entries = NULL;
profile_entry_count = 0;
_mali_osk_atomic_init(&profile_insert_index, 0);
_mali_osk_atomic_init(&profile_entries_written, 0);
- lock = _mali_osk_lock_init( _MALI_OSK_LOCKFLAG_SPINLOCK | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE, 0, 0 );
+ lock = _mali_osk_lock_init(_MALI_OSK_LOCKFLAG_ORDERED | _MALI_OSK_LOCKFLAG_SPINLOCK | _MALI_OSK_LOCKFLAG_NONINTERRUPTABLE, 0, _MALI_OSK_LOCK_ORDER_PROFILING);
if (NULL == lock)
{
return _MALI_OSK_ERR_FAULT;
@@ -59,9 +58,9 @@ _mali_osk_errcode_t _mali_profiling_init(mali_bool auto_start)
if (MALI_TRUE == auto_start)
{
u32 limit = MALI_PROFILING_MAX_BUFFER_ENTRIES; /* Use maximum buffer size */
-
- mali_profiling_default_enable = MALI_TRUE; /* save this so user space can query this on their startup */
- if (_MALI_OSK_ERR_OK != _mali_profiling_start(&limit))
+
+ mali_set_user_setting(_MALI_UK_USER_SETTING_SW_EVENTS_ENABLE, MALI_TRUE);
+ if (_MALI_OSK_ERR_OK != _mali_osk_profiling_start(&limit))
{
return _MALI_OSK_ERR_FAULT;
}
@@ -70,7 +69,7 @@ _mali_osk_errcode_t _mali_profiling_init(mali_bool auto_start)
return _MALI_OSK_ERR_OK;
}
-void _mali_profiling_term(void)
+void _mali_osk_profiling_term(void)
{
prof_state = MALI_PROFILING_STATE_UNINITIALIZED;
@@ -93,7 +92,7 @@ void _mali_profiling_term(void)
}
}
-inline _mali_osk_errcode_t _mali_profiling_start(u32 * limit)
+inline _mali_osk_errcode_t _mali_osk_profiling_start(u32 * limit)
{
_mali_osk_errcode_t ret;
@@ -137,21 +136,10 @@ inline _mali_osk_errcode_t _mali_profiling_start(u32 * limit)
return ret;
}
-inline void _mali_profiling_add_counter(u32 event_id, u32 data0)
-{
-#if MALI_TRACEPOINTS_ENABLED
- _mali_osk_profiling_add_counter(event_id, data0);
-#endif
-}
-
-inline _mali_osk_errcode_t _mali_profiling_add_event(u32 event_id, u32 data0, u32 data1, u32 data2, u32 data3, u32 data4)
+inline void _mali_osk_profiling_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;
-#if MALI_TRACEPOINTS_ENABLED
- _mali_osk_profiling_add_event(event_id, data0);
-#endif
-
if (prof_state != MALI_PROFILING_STATE_RUNNING || cur_index >= profile_entry_count)
{
/*
@@ -159,7 +147,7 @@ inline _mali_osk_errcode_t _mali_profiling_add_event(u32 event_id, u32 data0, u3
* Decrement index again, and early out
*/
_mali_osk_atomic_dec(&profile_insert_index);
- return _MALI_OSK_ERR_FAULT;
+ return;
}
profile_entries[cur_index].timestamp = _mali_timestamp_get();
@@ -171,55 +159,19 @@ inline _mali_osk_errcode_t _mali_profiling_add_event(u32 event_id, u32 data0, u3
profile_entries[cur_index].data[4] = data4;
_mali_osk_atomic_inc(&profile_entries_written);
-
- return _MALI_OSK_ERR_OK;
}
-#if MALI_TRACEPOINTS_ENABLED
-/*
- * The following code uses a bunch of magic numbers taken from the userspace
- * side of the DDK; they are re-used here verbatim. They are taken from the
- * file mali_instrumented_counter_types.h.
- */
-#define MALI_GLES_COUNTER_OFFSET 1000
-#define MALI_VG_COUNTER_OFFSET 2000
-#define MALI_EGL_COUNTER_OFFSET 3000
-#define MALI_SHARED_COUNTER_OFFSET 4000
-
-/* These offsets are derived from the gator driver; see gator_events_mali.c. */
-#define GATOR_EGL_COUNTER_OFFSET 17
-#define GATOR_GLES_COUNTER_OFFSET 18
-
-_mali_osk_errcode_t _mali_ukk_transfer_sw_counters(_mali_uk_sw_counters_s *args)
+inline void _mali_osk_profiling_report_hw_counter(u32 counter_id, u32 value)
{
- /* Convert the DDK counter ID to what gator expects */
- unsigned int gator_counter_value = 0;
-
- _mali_osk_lock_wait(lock, _MALI_OSK_LOCKMODE_RW);
-
- if (args->id >= MALI_EGL_COUNTER_OFFSET && args->id <= MALI_SHARED_COUNTER_OFFSET)
- {
- gator_counter_value = (args->id - MALI_EGL_COUNTER_OFFSET) + GATOR_EGL_COUNTER_OFFSET;
- }
- else if (args->id >= MALI_GLES_COUNTER_OFFSET && args->id <= MALI_VG_COUNTER_OFFSET)
- {
- gator_counter_value = (args->id - MALI_GLES_COUNTER_OFFSET) + GATOR_GLES_COUNTER_OFFSET;
- }
- else
- {
- /* Pass it straight through; gator will ignore it anyway. */
- gator_counter_value = args->id;
- }
-
- trace_mali_sw_counter(gator_counter_value, args->value);
-
- _mali_osk_lock_signal(lock, _MALI_OSK_LOCKMODE_RW);
+ /* Not implemented */
+}
- return _MALI_OSK_ERR_OK;
+void _mali_osk_profiling_report_sw_counters(u32 *counters)
+{
+ /* Not implemented */
}
-#endif
-inline _mali_osk_errcode_t _mali_profiling_stop(u32 * count)
+inline _mali_osk_errcode_t _mali_osk_profiling_stop(u32 * count)
{
_mali_osk_lock_wait(lock, _MALI_OSK_LOCKMODE_RW);
@@ -245,7 +197,7 @@ inline _mali_osk_errcode_t _mali_profiling_stop(u32 * count)
return _MALI_OSK_ERR_OK;
}
-inline u32 _mali_profiling_get_count(void)
+inline u32 _mali_osk_profiling_get_count(void)
{
u32 retval = 0;
@@ -259,7 +211,7 @@ inline u32 _mali_profiling_get_count(void)
return retval;
}
-inline _mali_osk_errcode_t _mali_profiling_get_event(u32 index, u64* timestamp, u32* event_id, u32 data[5])
+inline _mali_osk_errcode_t _mali_osk_profiling_get_event(u32 index, u64* timestamp, u32* event_id, u32 data[5])
{
_mali_osk_lock_wait(lock, _MALI_OSK_LOCKMODE_RW);
@@ -287,7 +239,7 @@ inline _mali_osk_errcode_t _mali_profiling_get_event(u32 index, u64* timestamp,
return _MALI_OSK_ERR_OK;
}
-inline _mali_osk_errcode_t _mali_profiling_clear(void)
+inline _mali_osk_errcode_t _mali_osk_profiling_clear(void)
{
_mali_osk_lock_wait(lock, _MALI_OSK_LOCKMODE_RW);
@@ -311,54 +263,46 @@ inline _mali_osk_errcode_t _mali_profiling_clear(void)
return _MALI_OSK_ERR_OK;
}
-mali_bool _mali_profiling_is_recording(void)
+mali_bool _mali_osk_profiling_is_recording(void)
{
return prof_state == MALI_PROFILING_STATE_RUNNING ? MALI_TRUE : MALI_FALSE;
}
-mali_bool _mali_profiling_have_recording(void)
+mali_bool _mali_osk_profiling_have_recording(void)
{
return prof_state == MALI_PROFILING_STATE_RETURN ? MALI_TRUE : MALI_FALSE;
}
-void _mali_profiling_set_default_enable_state(mali_bool enable)
-{
- mali_profiling_default_enable = enable;
-}
-
-mali_bool _mali_profiling_get_default_enable_state(void)
-{
- return mali_profiling_default_enable;
-}
-
_mali_osk_errcode_t _mali_ukk_profiling_start(_mali_uk_profiling_start_s *args)
{
- return _mali_profiling_start(&args->limit);
+ 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 */
- return _mali_profiling_add_event(args->event_id, _mali_osk_get_pid(), _mali_osk_get_tid(), args->data[2], args->data[3], args->data[4]);
+ _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_profiling_stop(&args->count);
+ 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_profiling_get_event(args->index, &args->timestamp, &args->event_id, args->data);
+ 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_profiling_clear();
+ return _mali_osk_profiling_clear();
}
-_mali_osk_errcode_t _mali_ukk_profiling_get_config(_mali_uk_profiling_get_config_s *args)
+_mali_osk_errcode_t _mali_ukk_sw_counters_report(_mali_uk_sw_counters_report_s *args)
{
- args->enable_events = mali_profiling_default_enable;
+ _mali_osk_profiling_report_sw_counters(args->counters);
return _MALI_OSK_ERR_OK;
}
+
diff --git a/drivers/media/video/samsung/mali/linux/mali_osk_specific.h b/drivers/media/video/samsung/mali/linux/mali_osk_specific.h
index 6aacf17..83ee906 100644
--- a/drivers/media/video/samsung/mali/linux/mali_osk_specific.h
+++ b/drivers/media/video/samsung/mali/linux/mali_osk_specific.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 ARM Limited. All rights reserved.
+ * 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.
@@ -22,11 +22,109 @@ extern "C"
{
#endif
-#define MALI_STATIC_INLINE static inline
+#define MALI_STATIC_INLINE static inline
#define MALI_NON_STATIC_INLINE inline
#ifdef __cplusplus
}
#endif
+/** The list of events supported by the Mali DDK. */
+typedef enum
+{
+ /* Vertex processor activity */
+ ACTIVITY_VP = 0,
+
+ /* Fragment processor activity */
+ ACTIVITY_FP0,
+ ACTIVITY_FP1,
+ ACTIVITY_FP2,
+ ACTIVITY_FP3,
+
+ /* L2 cache counters */
+ COUNTER_L2_C0,
+ COUNTER_L2_C1,
+
+ /* Vertex processor counters */
+ COUNTER_VP_C0,
+ COUNTER_VP_C1,
+
+ /* Fragment processor counters */
+ COUNTER_FP0_C0,
+ COUNTER_FP0_C1,
+ COUNTER_FP1_C0,
+ COUNTER_FP1_C1,
+ COUNTER_FP2_C0,
+ COUNTER_FP2_C1,
+ COUNTER_FP3_C0,
+ COUNTER_FP3_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
+#define LAST_ACTIVITY_EVENT ACTIVITY_FP3
+
+#define FIRST_HW_COUNTER COUNTER_L2_C0
+#define LAST_HW_COUNTER COUNTER_FP3_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
+
#endif /* __MALI_OSK_SPECIFIC_H__ */
diff --git a/drivers/media/video/samsung/mali/linux/mali_osk_timers.c b/drivers/media/video/samsung/mali/linux/mali_osk_timers.c
index 0454756..e5829a3 100644
--- a/drivers/media/video/samsung/mali/linux/mali_osk_timers.c
+++ b/drivers/media/video/samsung/mali/linux/mali_osk_timers.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 ARM Limited. All rights reserved.
+ * 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.
@@ -34,7 +34,7 @@ _mali_osk_timer_t *_mali_osk_timer_init(void)
void _mali_osk_timer_add( _mali_osk_timer_t *tim, u32 ticks_to_expire )
{
- MALI_DEBUG_ASSERT_POINTER(tim);
+ MALI_DEBUG_ASSERT_POINTER(tim);
tim->timer.expires = _mali_osk_time_tickcount() + ticks_to_expire;
add_timer(&(tim->timer));
}
diff --git a/drivers/media/video/samsung/mali/linux/mali_osk_wait_queue.c b/drivers/media/video/samsung/mali/linux/mali_osk_wait_queue.c
new file mode 100644
index 0000000..ce0561d
--- /dev/null
+++ b/drivers/media/video/samsung/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/media/video/samsung/mali/linux/mali_pmu_power_up_down.c b/drivers/media/video/samsung/mali/linux/mali_pmu_power_up_down.c
new file mode 100644
index 0000000..f3b0a2c
--- /dev/null
+++ b/drivers/media/video/samsung/mali/linux/mali_pmu_power_up_down.c
@@ -0,0 +1,65 @@
+/**
+ * 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 "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"));
+
+ if (NULL == pmu)
+ {
+ return -ENXIO;
+ }
+
+ if (_MALI_OSK_ERR_OK != mali_pmu_powerup_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"));
+
+ if (NULL == pmu)
+ {
+ return -ENXIO;
+ }
+
+ if (_MALI_OSK_ERR_OK != mali_pmu_powerdown_all(pmu))
+ {
+ return -EFAULT;
+ }
+
+ return 0;
+}
+
+EXPORT_SYMBOL(mali_pmu_powerdown);
diff --git a/drivers/media/video/samsung/ump/arch-marcopolo-vega1-m400/config.h b/drivers/media/video/samsung/mali/linux/mali_profiling_events.h
index 014c4bb..2639a40 100644
--- a/drivers/media/video/samsung/ump/arch-marcopolo-vega1-m400/config.h
+++ b/drivers/media/video/samsung/mali/linux/mali_profiling_events.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 ARM Limited. All rights reserved.
+ * 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.
@@ -8,11 +8,10 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __ARCH_CONFIG_H__
-#define __ARCH_CONFIG_H__
+#ifndef __MALI_PROFILING_EVENTS_H__
+#define __MALI_PROFILING_EVENTS_H__
-#define ARCH_UMP_BACKEND_DEFAULT 0
-#define ARCH_UMP_MEMORY_ADDRESS_DEFAULT 0x2C000000
-#define ARCH_UMP_MEMORY_SIZE_DEFAULT 0x04000000
+/* Simple wrapper in order to find the OS specific location of this file */
+#include <linux/mali/mali_utgard_profiling_events.h>
-#endif /* __ARCH_CONFIG_H__ */
+#endif /* __MALI_PROFILING_EVENTS_H__ */
diff --git a/drivers/media/video/samsung/mali/linux/mali_device_pause_resume.h b/drivers/media/video/samsung/mali/linux/mali_uk_types.h
index 155a3e6..b535e6c 100644
--- a/drivers/media/video/samsung/mali/linux/mali_device_pause_resume.h
+++ b/drivers/media/video/samsung/mali/linux/mali_uk_types.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 ARM Limited. All rights reserved.
+ * 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.
@@ -8,12 +8,12 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#ifndef __MALI_DEVICE_PAUSE_RESUME_H__
-#define __MALI_DEVICE_PAUSE_RESUME_H__
+#ifndef __MALI_UK_TYPES_H__
+#define __MALI_UK_TYPES_H__
-#if USING_MALI_PMM
-int mali_dev_pause(void);
-int mali_dev_resume(void);
-#endif /* USING_MALI_PMM */
+#include "regs/mali_200_regs.h"
-#endif /* __MALI_DEVICE_PAUSE_RESUME_H__ */
+/* Simple wrapper in order to find the OS specific location of this file */
+#include "../include/linux/mali/mali_utgard_uk_types.h"
+
+#endif /* __MALI_UK_TYPES_H__ */
diff --git a/drivers/media/video/samsung/mali/linux/mali_ukk_core.c b/drivers/media/video/samsung/mali/linux/mali_ukk_core.c
index 59eafe2..6eb2df3 100644
--- a/drivers/media/video/samsung/mali/linux/mali_ukk_core.c
+++ b/drivers/media/video/samsung/mali/linux/mali_ukk_core.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 ARM Limited. All rights reserved.
+ * 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.
@@ -14,7 +14,7 @@
#include "mali_ukk.h"
#include "mali_osk.h"
#include "mali_kernel_common.h"
-#include "mali_kernel_session_manager.h"
+#include "mali_session.h"
#include "mali_ukk_wrappers.h"
int get_api_version_wrapper(struct mali_session_data *session_data, _mali_uk_get_api_version_s __user *uargs)
@@ -140,3 +140,23 @@ int post_notification_wrapper(struct mali_session_data *session_data, _mali_uk_p
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;
+}
diff --git a/drivers/media/video/samsung/mali/linux/mali_ukk_gp.c b/drivers/media/video/samsung/mali/linux/mali_ukk_gp.c
index 58ff1de..7070016 100644
--- a/drivers/media/video/samsung/mali/linux/mali_ukk_gp.c
+++ b/drivers/media/video/samsung/mali/linux/mali_ukk_gp.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 ARM Limited. All rights reserved.
+ * 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.
@@ -13,7 +13,7 @@
#include "mali_ukk.h"
#include "mali_osk.h"
#include "mali_kernel_common.h"
-#include "mali_kernel_session_manager.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)
@@ -36,6 +36,7 @@ int gp_start_job_wrapper(struct mali_session_data *session_data, _mali_uk_gp_sta
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_gp_start_job_s)))
{
/*
@@ -53,22 +54,6 @@ int gp_start_job_wrapper(struct mali_session_data *session_data, _mali_uk_gp_sta
return 0;
}
-int gp_abort_job_wrapper(struct mali_session_data *session_data, _mali_uk_gp_abort_job_s __user *uargs)
-{
- _mali_uk_gp_abort_job_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_gp_abort_job_s))) return -EFAULT;
-
- kargs.ctx = session_data;
- _mali_ukk_gp_abort_job(&kargs);
-
- 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;
diff --git a/drivers/media/video/samsung/mali/linux/mali_ukk_mem.c b/drivers/media/video/samsung/mali/linux/mali_ukk_mem.c
index 0b98e41..260f257 100644
--- a/drivers/media/video/samsung/mali/linux/mali_ukk_mem.c
+++ b/drivers/media/video/samsung/mali/linux/mali_ukk_mem.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 ARM Limited. All rights reserved.
+ * 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.
@@ -13,7 +13,7 @@
#include "mali_ukk.h"
#include "mali_osk.h"
#include "mali_kernel_common.h"
-#include "mali_kernel_session_manager.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)
@@ -257,80 +257,3 @@ err_exit:
if (kargs.buffer) _mali_osk_vfree(kargs.buffer);
return rc;
}
-
-
-
-int mem_get_big_block_wrapper( struct file * filp, _mali_uk_get_big_block_s __user * argument )
-{
- _mali_uk_get_big_block_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_get_big_block_s)) )
- {
- return -EFAULT;
- }
-
- /* This interface inserts something into the ukk_private word */
- uk_args.ukk_private = (u32)filp;
- uk_args.ctx = filp->private_data;
- err_code = _mali_ukk_get_big_block( &uk_args );
-
- /* Do not leak the private word back into user space */
- uk_args.ukk_private = 0;
-
- if ( _MALI_OSK_ERR_OK != err_code )
- {
- return map_errcode(err_code);
- }
-
- /* From this point on, we must roll-back any failing action to preserve the
- * meaning of the U/K interface (e.g. when excluded) */
-
- /* transfer response back to user space */
- if ( 0 != copy_to_user(argument, &uk_args, sizeof(_mali_uk_get_big_block_s)) )
- {
- /* Roll-back - the _mali_uk_get_big_block call succeeded, so all
- * values in uk_args will be correct */
- _mali_uk_free_big_block_s uk_args_rollback = {0, };
-
- uk_args_rollback.ctx = uk_args.ctx;
- uk_args_rollback.cookie = uk_args.cookie;
- err_code = _mali_ukk_free_big_block( &uk_args_rollback );
-
- if ( _MALI_OSK_ERR_OK != err_code )
- {
- /* error in DEBUG and RELEASE */
- MALI_PRINT_ERROR( ("Failed to rollback get_big_block: %.8X\n", (u32)err_code) );
- }
- return -EFAULT;
- }
-
- return 0;
-}
-
-int mem_free_big_block_wrapper(struct mali_session_data *session_data, _mali_uk_free_big_block_s __user * argument)
-{
- _mali_uk_free_big_block_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. get_user returns 0 on success */
- if ( 0 != get_user(uk_args.cookie, &argument->cookie) )
- {
- return -EFAULT;
- }
-
- uk_args.ctx = session_data;
- err_code = _mali_ukk_free_big_block( &uk_args );
-
- /* Return the error that _mali_ukk_free_big_block produced */
- return map_errcode(err_code);
-}
diff --git a/drivers/media/video/samsung/mali/linux/mali_ukk_pp.c b/drivers/media/video/samsung/mali/linux/mali_ukk_pp.c
index 31e2a6a..c11c61b 100644
--- a/drivers/media/video/samsung/mali/linux/mali_ukk_pp.c
+++ b/drivers/media/video/samsung/mali/linux/mali_ukk_pp.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 ARM Limited. All rights reserved.
+ * 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.
@@ -13,7 +13,7 @@
#include "mali_ukk.h"
#include "mali_osk.h"
#include "mali_kernel_common.h"
-#include "mali_kernel_session_manager.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)
@@ -35,36 +35,6 @@ int pp_start_job_wrapper(struct mali_session_data *session_data, _mali_uk_pp_sta
err = _mali_ukk_pp_start_job(&kargs);
if (_MALI_OSK_ERR_OK != err) return map_errcode(err);
- if (0 != put_user(kargs.returned_user_job_ptr, &uargs->returned_user_job_ptr) ||
- 0 != put_user(kargs.status, &uargs->status))
- {
- /*
- * If this happens, then user space will not know that the job was actually started,
- * and if we return a queued job, then user space will still think that one is still queued.
- * This will typically lead to a deadlock in user space.
- * This could however only happen if user space deliberately passes a user buffer which
- * passes the access_ok(VERIFY_WRITE) check, but isn't fully writable at the time of copy_to_user().
- * The official Mali driver will never attempt to do that, and kernel space should not be affected.
- * That is why we do not bother to do a complex rollback in this very very very rare case.
- */
- return -EFAULT;
- }
-
- return 0;
-}
-
-int pp_abort_job_wrapper(struct mali_session_data *session_data, _mali_uk_pp_abort_job_s __user *uargs)
-{
- _mali_uk_pp_abort_job_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_abort_job_s))) return -EFAULT;
-
- kargs.ctx = session_data;
- _mali_ukk_pp_abort_job(&kargs);
-
return 0;
}
@@ -101,3 +71,18 @@ int pp_get_core_version_wrapper(struct mali_session_data *session_data, _mali_uk
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/media/video/samsung/mali/linux/mali_ukk_profiling.c b/drivers/media/video/samsung/mali/linux/mali_ukk_profiling.c
index 17366be..7324d9d 100644
--- a/drivers/media/video/samsung/mali/linux/mali_ukk_profiling.c
+++ b/drivers/media/video/samsung/mali/linux/mali_ukk_profiling.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 ARM Limited. All rights reserved.
+ * 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.
@@ -9,11 +9,12 @@
*/
#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_kernel_session_manager.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)
@@ -133,51 +134,49 @@ int profiling_clear_wrapper(struct mali_session_data *session_data, _mali_uk_pro
return 0;
}
-int profiling_get_config_wrapper(struct mali_session_data *session_data, _mali_uk_profiling_get_config_s __user *uargs)
+int profiling_report_sw_counters_wrapper(struct mali_session_data *session_data, _mali_uk_sw_counters_report_s __user *uargs)
{
- _mali_uk_profiling_get_config_s kargs;
+ _mali_uk_sw_counters_report_s kargs;
_mali_osk_errcode_t err;
+ u32 *counter_buffer;
MALI_CHECK_NON_NULL(uargs, -EINVAL);
- kargs.ctx = session_data;
- err = _mali_ukk_profiling_get_config(&kargs);
- if (_MALI_OSK_ERR_OK != err)
+ if (0 != copy_from_user(&kargs, uargs, sizeof(_mali_uk_sw_counters_report_s)))
{
- return map_errcode(err);
+ return -EFAULT;
}
- if (0 != put_user(kargs.enable_events, &uargs->enable_events))
- {
- 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;
}
- return 0;
-}
+ counter_buffer = (u32*)kmalloc(sizeof(u32) * kargs.num_counters, GFP_KERNEL);
+ if (NULL == counter_buffer)
+ {
+ return -ENOMEM;
+ }
-#if MALI_TRACEPOINTS_ENABLED
-int transfer_sw_counters_wrapper(struct mali_session_data *session_data, _mali_uk_sw_counters_s __user *uargs)
-{
- _mali_uk_sw_counters_s kargs;
- _mali_osk_errcode_t err;
+ if (0 != copy_from_user(counter_buffer, kargs.counters, sizeof(u32) * kargs.num_counters))
+ {
+ kfree(counter_buffer);
+ return -EFAULT;
+ }
- MALI_CHECK_NON_NULL(uargs, -EINVAL);
-
- kargs.ctx = session_data;
+ kargs.ctx = session_data;
+ kargs.counters = counter_buffer;
- if (0 != copy_from_user(&kargs, uargs, sizeof(_mali_uk_sw_counters_s)))
- {
- return -EFAULT;
- }
+ err = _mali_ukk_sw_counters_report(&kargs);
- err = _mali_ukk_transfer_sw_counters(&kargs);
+ kfree(counter_buffer);
- if (_MALI_OSK_ERR_OK != err)
- {
- return map_errcode(err);
- }
+ if (_MALI_OSK_ERR_OK != err)
+ {
+ return map_errcode(err);
+ }
- return 0;
+ return 0;
}
-#endif
diff --git a/drivers/media/video/samsung/mali/linux/mali_ukk_vsync.c b/drivers/media/video/samsung/mali/linux/mali_ukk_vsync.c
index 80a6afd..f9b5a3e 100644
--- a/drivers/media/video/samsung/mali/linux/mali_ukk_vsync.c
+++ b/drivers/media/video/samsung/mali/linux/mali_ukk_vsync.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 ARM Limited. All rights reserved.
+ * 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.
@@ -13,7 +13,7 @@
#include "mali_ukk.h"
#include "mali_osk.h"
#include "mali_kernel_common.h"
-#include "mali_kernel_session_manager.h"
+#include "mali_session.h"
#include "mali_ukk_wrappers.h"
diff --git a/drivers/media/video/samsung/mali/linux/mali_ukk_wrappers.h b/drivers/media/video/samsung/mali/linux/mali_ukk_wrappers.h
index 184ce8d..b568ce7 100644
--- a/drivers/media/video/samsung/mali/linux/mali_ukk_wrappers.h
+++ b/drivers/media/video/samsung/mali/linux/mali_ukk_wrappers.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 ARM Limited. All rights reserved.
+ * 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.
@@ -28,6 +28,7 @@ int get_system_info_size_wrapper(struct mali_session_data *session_data, _mali_u
int get_system_info_wrapper(struct mali_session_data *session_data, _mali_uk_get_system_info_s __user *uargs);
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);
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);
@@ -41,14 +42,11 @@ int mem_attach_ump_wrapper(struct mali_session_data *session_data, _mali_uk_atta
int mem_release_ump_wrapper(struct mali_session_data *session_data, _mali_uk_release_ump_mem_s __user * argument);
#endif /* MALI_USE_UNIFIED_MEMORY_PROVIDER */
-int mem_get_big_block_wrapper( struct file * filp, _mali_uk_get_big_block_s __user * argument );
-int mem_free_big_block_wrapper( struct mali_session_data *session_data, _mali_uk_free_big_block_s __user * argument);
int pp_start_job_wrapper(struct mali_session_data *session_data, _mali_uk_pp_start_job_s __user *uargs);
-int pp_abort_job_wrapper(struct mali_session_data *session_data, _mali_uk_pp_abort_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_abort_job_wrapper(struct mali_session_data *session_data, _mali_uk_gp_abort_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);
@@ -58,14 +56,10 @@ int profiling_add_event_wrapper(struct mali_session_data *session_data, _mali_uk
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_get_config_wrapper(struct mali_session_data *session_data, _mali_uk_profiling_get_config_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);
-#if MALI_TRACEPOINTS_ENABLED
-int transfer_sw_counters_wrapper(struct mali_session_data *session_data, _mali_uk_sw_counters_s __user *uargs);
-#endif
-
int map_errcode( _mali_osk_errcode_t err );
#ifdef __cplusplus
diff --git a/drivers/media/video/samsung/mali/platform/default/mali_platform.c b/drivers/media/video/samsung/mali/platform/default/mali_platform.c
index 44f877e..9e64ce7 100644
--- a/drivers/media/video/samsung/mali/platform/default/mali_platform.c
+++ b/drivers/media/video/samsung/mali/platform/default/mali_platform.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 ARM Limited. All rights reserved.
+ * 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.
@@ -39,3 +39,5 @@ void mali_gpu_utilization_handler(u32 utilization)
void set_mali_parent_power_domain(void* dev)
{
}
+
+
diff --git a/drivers/media/video/samsung/mali/platform/mali_platform.h b/drivers/media/video/samsung/mali/platform/mali_platform.h
index 70cfa14..6e55dee 100644
--- a/drivers/media/video/samsung/mali/platform/mali_platform.h
+++ b/drivers/media/video/samsung/mali/platform/mali_platform.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 ARM Limited. All rights reserved.
+ * 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.
@@ -21,12 +21,7 @@
#ifdef CONFIG_CPU_EXYNOS4210
#define MALI_DVFS_STEPS 2
#else
-#define MALI_DVFS_STEPS 4
-#endif
-
-#if !USING_MALI_PMM
-/* @brief System power up/down cores that can be passed into mali_platform_powerdown/up() */
-#define MALI_PLATFORM_SYSTEM 0
+#define MALI_DVFS_STEPS 5
#endif
/* @Enable or Disable Mali GPU Bottom Lock feature */
@@ -34,6 +29,9 @@
#define MALI_VOLTAGE_LOCK 1
+/* @Enable or Disable the CPU frequency lock when the GPU clock is 440 Mhz */
+#define CPUFREQ_LOCK_DURING_440 0
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -42,9 +40,9 @@ extern "C" {
*/
typedef enum mali_power_mode_tag
{
- MALI_POWER_MODE_ON,
- MALI_POWER_MODE_LIGHT_SLEEP,
- MALI_POWER_MODE_DEEP_SLEEP,
+ MALI_POWER_MODE_ON, /**< Power Mali on */
+ MALI_POWER_MODE_LIGHT_SLEEP, /**< Mali has been idle for a short time, or runtime PM suspend */
+ MALI_POWER_MODE_DEEP_SLEEP, /**< Mali has been idle for a long time, or OS suspend */
} mali_power_mode;
/** @brief Platform specific setup and initialisation of MALI
@@ -65,22 +63,8 @@ _mali_osk_errcode_t mali_platform_deinit(void);
/** @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.
+ * Notification from the Mali device driver stating the new desired power mode.
+ * MALI_POWER_MODE_ON must be obeyed, while the other modes are optional.
* @param power_mode defines the power modes
* @return _MALI_OSK_ERR_OK on success otherwise, a suitable _mali_osk_errcode_t error.
*/
diff --git a/drivers/media/video/samsung/mali/platform/mali_platform_pmu_testing/mali_platform.c b/drivers/media/video/samsung/mali/platform/mali_platform_pmu_testing/mali_platform.c
new file mode 100644
index 0000000..cb95dc6
--- /dev/null
+++ b/drivers/media/video/samsung/mali/platform/mali_platform_pmu_testing/mali_platform.c
@@ -0,0 +1,66 @@
+/*
+ * 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.c
+ * Platform specific Mali driver functions for a default platform
+ */
+#include "mali_kernel_common.h"
+#include "mali_osk.h"
+#include "mali_platform.h"
+#include "mali_pmu.h"
+#include "linux/mali/mali_utgard.h"
+
+static u32 bPowerOff = 1;
+
+_mali_osk_errcode_t mali_platform_init(void)
+{
+ MALI_SUCCESS;
+}
+
+_mali_osk_errcode_t mali_platform_deinit(void)
+{
+ MALI_SUCCESS;
+}
+
+_mali_osk_errcode_t mali_platform_power_mode_change(mali_power_mode power_mode)
+{
+ switch (power_mode)
+ {
+ case MALI_POWER_MODE_ON:
+ if (bPowerOff == 1)
+ {
+ mali_pmu_powerup();
+ bPowerOff = 0;
+ }
+ break;
+ case MALI_POWER_MODE_LIGHT_SLEEP:
+ case MALI_POWER_MODE_DEEP_SLEEP:
+
+ if (bPowerOff == 0)
+ {
+ mali_pmu_powerdown();
+ bPowerOff = 1;
+ }
+
+ break;
+ }
+ MALI_SUCCESS;
+}
+
+void mali_gpu_utilization_handler(u32 utilization)
+{
+}
+
+void set_mali_parent_power_domain(void* dev)
+{
+}
+
+
diff --git a/drivers/media/video/samsung/mali/platform/orion-m400/mali_platform.c b/drivers/media/video/samsung/mali/platform/orion-m400/mali_platform.c
index 0fc4503..792b9a9 100644
--- a/drivers/media/video/samsung/mali/platform/orion-m400/mali_platform.c
+++ b/drivers/media/video/samsung/mali/platform/orion-m400/mali_platform.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 ARM Limited. All rights reserved.
+ * 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.
diff --git a/drivers/media/video/samsung/mali/platform/orion-m400/mali_platform_dvfs.c b/drivers/media/video/samsung/mali/platform/orion-m400/mali_platform_dvfs.c
index 9e6edba..f8d76dc 100644
--- a/drivers/media/video/samsung/mali/platform/orion-m400/mali_platform_dvfs.c
+++ b/drivers/media/video/samsung/mali/platform/orion-m400/mali_platform_dvfs.c
@@ -1,414 +1 @@
-/*
- * 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_platform_dvfs.c
- * Platform specific Mali driver dvfs functions
- */
-
-#include "mali_kernel_common.h"
-#include "mali_osk.h"
-#include "mali_platform.h"
-
-#include <linux/clk.h>
-#include <linux/err.h>
-#include <linux/regulator/consumer.h>
-#include <linux/regulator/driver.h>
-
-#include <asm/io.h>
-
-#ifdef CONFIG_CPU_FREQ
-#include <mach/asv.h>
-#include <mach/regs-pmu.h>
-#define EXYNOS4_ASV_ENABLED
-#endif
-
-#include "mali_device_pause_resume.h"
-#include <linux/workqueue.h>
-
-#define MALI_DVFS_WATING 10 // msec
-
-static int bMaliDvfsRun=0;
-
-#if MALI_GPU_BOTTOM_LOCK
-static _mali_osk_atomic_t bottomlock_status;
-#endif
-
-typedef struct mali_dvfs_tableTag{
- unsigned int clock;
- unsigned int freq;
- unsigned int vol;
-}mali_dvfs_table;
-
-typedef struct mali_dvfs_statusTag{
- unsigned int currentStep;
- mali_dvfs_table * pCurrentDvfs;
-
-}mali_dvfs_currentstatus;
-
-typedef struct mali_dvfs_thresholdTag{
- unsigned int downthreshold;
- unsigned int upthreshold;
-}mali_dvfs_threshold_table;
-
-typedef struct mali_dvfs_staycount{
- unsigned int staycount;
-}mali_dvfs_staycount_table;
-
-mali_dvfs_staycount_table mali_dvfs_staycount[MALI_DVFS_STEPS]={
- /*step 0*/{1},
- /*step 1*/{1},};
-
-/*dvfs threshold*/
-mali_dvfs_threshold_table mali_dvfs_threshold[MALI_DVFS_STEPS]={
- /*step 0*/{((int)((255*0)/100)), ((int)((255*85)/100))},
- /*step 1*/{((int)((255*75)/100)), ((int)((255*100)/100))} };
-
-/*dvfs status*/
-mali_dvfs_currentstatus maliDvfsStatus;
-int mali_dvfs_control=0;
-
-/*dvfs table*/
-mali_dvfs_table mali_dvfs[MALI_DVFS_STEPS]={
- /*step 0*/{160 ,1000000 , 950000},
- /*step 1*/{267 ,1000000 ,1000000} };
-
-#ifdef EXYNOS4_ASV_ENABLED
-
-#define ASV_8_LEVEL 8
-#define ASV_5_LEVEL 5
-
-static unsigned int asv_3d_volt_5_table[ASV_5_LEVEL][MALI_DVFS_STEPS] = {
- /* L3(160MHz), L2(266MHz) */
- {1000000, 1100000}, /* S */
- {1000000, 1100000}, /* A */
- { 950000, 1000000}, /* B */
- { 950000, 1000000}, /* C */
- { 950000, 950000}, /* D */
-};
-
-static unsigned int asv_3d_volt_8_table[ASV_8_LEVEL][MALI_DVFS_STEPS] = {
- /* L3(160MHz), L2(266MHz)) */
- {1000000, 1100000}, /* SS */
- {1000000, 1100000}, /* A1 */
- {1000000, 1100000}, /* A2 */
- { 950000, 1000000}, /* B1 */
- { 950000, 1000000}, /* B2 */
- { 950000, 1000000}, /* C1 */
- { 950000, 1000000}, /* C2 */
- { 950000, 950000}, /* D1 */
-};
-#endif
-
-static u32 mali_dvfs_utilization = 255;
-
-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;
-
-#if MALI_GPU_BOTTOM_LOCK
-extern _mali_osk_lock_t *mali_dvfs_lock;
-#endif
-
-static DECLARE_WORK(mali_dvfs_work, mali_dvfs_work_handler);
-
-static unsigned int get_mali_dvfs_status(void)
-{
- return maliDvfsStatus.currentStep;
-}
-
-#if MALI_GPU_BOTTOM_LOCK
-#if MALI_PMM_RUNTIME_JOB_CONTROL_ON
-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_osk_lock_signal(mali_dvfs_lock, _MALI_OSK_LOCKMODE_RW);
- return MALI_TRUE;
-}
-#endif
-#endif
-
-static mali_bool set_mali_dvfs_status(u32 step,mali_bool boostup)
-{
- u32 validatedStep=step;
-
-#ifdef CONFIG_REGULATOR
- if (mali_regulator_get_usecount()==0) {
- MALI_DEBUG_PRINT(1, ("regulator use_count is 0 \n"));
- return MALI_FALSE;
- }
-#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
- }
-
- maliDvfsStatus.currentStep = validatedStep;
- /*for future use*/
- maliDvfsStatus.pCurrentDvfs = &mali_dvfs[validatedStep];
-
- 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
- }
- /* _mali_osk_time_ubusydelay(msec*1000);*/
-}
-
-static mali_bool change_mali_dvfs_status(u32 step, mali_bool boostup )
-{
-
- MALI_DEBUG_PRINT(1, ("> 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;
-}
-
-static unsigned int decideNextStatus(unsigned int utilization)
-{
- unsigned int level=0; // 0:stay, 1:up
-
- if (!mali_dvfs_control) {
-#if MALI_GPU_BOTTOM_LOCK
- if (_mali_osk_atomic_read(&bottomlock_status) > 0)
- level = 1; /* or bigger */
- else if (utilization > mali_dvfs_threshold[maliDvfsStatus.currentStep].upthreshold)
-#else
- if (utilization > mali_dvfs_threshold[maliDvfsStatus.currentStep].upthreshold)
-#endif
- level=1;
- else if (utilization < mali_dvfs_threshold[maliDvfsStatus.currentStep].downthreshold)
- level=0;
- else
- level = maliDvfsStatus.currentStep;
- } else {
- if ((mali_dvfs_control > 0) && (mali_dvfs_control < mali_dvfs[1].clock))
- level=0;
- else
- level=1;
- }
-
- return level;
-}
-
-#ifdef EXYNOS4_ASV_ENABLED
-static mali_bool mali_dvfs_table_update(void)
-{
- unsigned int exynos_result_of_asv_group;
- unsigned int target_asv;
- unsigned int i;
- 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));
-
- if (target_asv == 0x8) { //SUPPORT_1400MHZ
- for (i = 0; i < MALI_DVFS_STEPS; i++) {
- mali_dvfs[i].vol = asv_3d_volt_5_table[exynos_result_of_asv_group][i];
- MALI_PRINT(("mali_dvfs[%d].vol = %d\n", i, mali_dvfs[i].vol));
- }
- } else if (target_asv == 0x4){ //SUPPORT_1200MHZ
- for (i = 0; i < MALI_DVFS_STEPS; i++) {
- mali_dvfs[i].vol = asv_3d_volt_8_table[exynos_result_of_asv_group][i];
- MALI_PRINT(("mali_dvfs[%d].vol = %d\n", i, mali_dvfs[i].vol));
- }
- }
-
- return MALI_TRUE;
-
-}
-#endif
-
-static mali_bool mali_dvfs_status(u32 utilization)
-{
- unsigned int nextStatus = 0;
- unsigned int curStatus = 0;
- mali_bool boostup = MALI_FALSE;
-#ifdef EXYNOS4_ASV_ENABLED
- static mali_bool asv_applied = MALI_FALSE;
-#endif
- static int stay_count = 0; // to prevent frequent switch
-
- MALI_DEBUG_PRINT(1, ("> mali_dvfs_status: %d \n",utilization));
-#ifdef EXYNOS4_ASV_ENABLED
- if (asv_applied == MALI_FALSE) {
- mali_dvfs_table_update();
- change_mali_dvfs_status(0,0);
- asv_applied = MALI_TRUE;
-
- return MALI_TRUE;
- }
-#endif
-
- /*decide next step*/
- curStatus = get_mali_dvfs_status();
- nextStatus = decideNextStatus(utilization);
-
- MALI_DEBUG_PRINT(1, ("= 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 && stay_count==0)) {
- /*check if boost up or not*/
- if (nextStatus > maliDvfsStatus.currentStep)
- boostup = 1;
-
- /*change mali dvfs status*/
- if (!change_mali_dvfs_status(nextStatus,boostup)) {
- MALI_DEBUG_PRINT(1, ("error on change_mali_dvfs_status \n"));
- return MALI_FALSE;
- }
- stay_count = mali_dvfs_staycount[maliDvfsStatus.currentStep].staycount;
- } else {
- if (stay_count>0)
- stay_count--;
- }
-
- return MALI_TRUE;
-}
-
-
-
-int mali_dvfs_is_running(void)
-{
- return bMaliDvfsRun;
-}
-
-
-
-void mali_dvfs_late_resume(void)
-{
- // set the init clock as low when resume
- set_mali_dvfs_status(0,0);
-}
-
-
-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(int step)
-{
- /*default status
- add here with the right function to get initilization value.
- */
- if (!mali_dvfs_wq)
- mali_dvfs_wq = create_singlethread_workqueue("mali_dvfs");
-
-#if MALI_GPU_BOTTOM_LOCK
- _mali_osk_atomic_init(&bottomlock_status, 0);
-#endif
-
- /*add a error handling here*/
- maliDvfsStatus.currentStep = step;
-
- return MALI_TRUE;
-}
-
-void deinit_mali_dvfs_status(void)
-{
-#if MALI_GPU_BOTTOM_LOCK
- _mali_osk_atomic_term(&bottomlock_status);
-#endif
-
- if (mali_dvfs_wq)
- destroy_workqueue(mali_dvfs_wq);
- mali_dvfs_wq = NULL;
-}
-
-mali_bool mali_dvfs_handler(u32 utilization)
-{
- mali_dvfs_utilization = utilization;
- queue_work_on(0, mali_dvfs_wq,&mali_dvfs_work);
-
- /*add error handle here*/
- return MALI_TRUE;
-}
-
-void mali_default_step_set(int step, mali_bool boostup)
-{
- mali_clk_set_rate(mali_dvfs[step].clock, mali_dvfs[step].freq);
-
- if (maliDvfsStatus.currentStep == 1)
- set_mali_dvfs_status(step, boostup);
-}
-
-#if MALI_GPU_BOTTOM_LOCK
-int mali_dvfs_bottom_lock_push(void)
-{
- int prev_status = _mali_osk_atomic_read(&bottomlock_status);
-
- if (prev_status < 0) {
- MALI_PRINT(("gpu bottom lock status is not valid for push"));
- 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);
-}
-
-int mali_dvfs_bottom_lock_pop(void)
-{
- if (_mali_osk_atomic_read(&bottomlock_status) <= 0) {
- MALI_PRINT(("gpu bottom lock status is not valid for pop"));
- return -1;
- }
-
- return _mali_osk_atomic_dec_return(&bottomlock_status);
-}
-#endif
+/* * 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_dvfs.c * Platform specific Mali driver dvfs functions */ #include "mali_kernel_common.h" #include "mali_osk.h" #include "mali_platform.h" #include <linux/clk.h> #include <linux/err.h> #include <linux/regulator/consumer.h> #include <linux/regulator/driver.h> #include <asm/io.h> #ifdef CONFIG_CPU_FREQ #include <mach/asv.h> #include <mach/regs-pmu.h> #define EXYNOS4_ASV_ENABLED #endif #include "mali_device_pause_resume.h" #include <linux/workqueue.h> #define MALI_DVFS_WATING 10 // msec static int bMaliDvfsRun=0; #if MALI_GPU_BOTTOM_LOCK static _mali_osk_atomic_t bottomlock_status; #endif typedef struct mali_dvfs_tableTag{ unsigned int clock; unsigned int freq; unsigned int vol; }mali_dvfs_table; typedef struct mali_dvfs_statusTag{ unsigned int currentStep; mali_dvfs_table * pCurrentDvfs; }mali_dvfs_currentstatus; typedef struct mali_dvfs_thresholdTag{ unsigned int downthreshold; unsigned int upthreshold; }mali_dvfs_threshold_table; typedef struct mali_dvfs_staycount{ unsigned int staycount; }mali_dvfs_staycount_table; mali_dvfs_staycount_table mali_dvfs_staycount[MALI_DVFS_STEPS]={ /*step 0*/{1}, /*step 1*/{1},}; /*dvfs threshold*/ mali_dvfs_threshold_table mali_dvfs_threshold[MALI_DVFS_STEPS]={ /*step 0*/{((int)((255*0)/100)), ((int)((255*85)/100))}, /*step 1*/{((int)((255*75)/100)), ((int)((255*100)/100))} }; /*dvfs status*/ mali_dvfs_currentstatus maliDvfsStatus; int mali_dvfs_control=0; /*dvfs table*/ mali_dvfs_table mali_dvfs[MALI_DVFS_STEPS]={ /*step 0*/{160 ,1000000 , 950000}, /*step 1*/{267 ,1000000 ,1000000} }; #ifdef EXYNOS4_ASV_ENABLED #define ASV_8_LEVEL 8 #define ASV_5_LEVEL 5 #define ASV_LEVEL_SUPPORT 0 static unsigned int asv_3d_volt_5_table[ASV_5_LEVEL][MALI_DVFS_STEPS] = { /* L3(160MHz), L2(266MHz) */ {1000000, 1100000}, /* S */ {1000000, 1100000}, /* A */ { 950000, 1000000}, /* B */ { 950000, 1000000}, /* C */ { 950000, 950000}, /* D */ }; static unsigned int asv_3d_volt_8_table[ASV_8_LEVEL][MALI_DVFS_STEPS] = { /* L3(160MHz), L2(266MHz)) */ {1000000, 1100000}, /* SS */ {1000000, 1100000}, /* A1 */ {1000000, 1100000}, /* A2 */ { 950000, 1000000}, /* B1 */ { 950000, 1000000}, /* B2 */ { 950000, 1000000}, /* C1 */ { 950000, 1000000}, /* C2 */ { 950000, 950000}, /* D1 */ }; #endif static u32 mali_dvfs_utilization = 255; 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; #if MALI_GPU_BOTTOM_LOCK extern _mali_osk_lock_t *mali_dvfs_lock; #endif static DECLARE_WORK(mali_dvfs_work, mali_dvfs_work_handler); static unsigned int get_mali_dvfs_status(void) { return maliDvfsStatus.currentStep; } #if MALI_GPU_BOTTOM_LOCK #if MALI_PMM_RUNTIME_JOB_CONTROL_ON 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_osk_lock_signal(mali_dvfs_lock, _MALI_OSK_LOCKMODE_RW); return MALI_TRUE; } #endif #endif static mali_bool set_mali_dvfs_status(u32 step,mali_bool boostup) { u32 validatedStep=step; #ifdef CONFIG_REGULATOR if (mali_regulator_get_usecount()==0) { MALI_DEBUG_PRINT(1, ("regulator use_count is 0 \n")); return MALI_FALSE; } #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 } maliDvfsStatus.currentStep = validatedStep; /*for future use*/ maliDvfsStatus.pCurrentDvfs = &mali_dvfs[validatedStep]; 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 } /* _mali_osk_time_ubusydelay(msec*1000);*/ } static mali_bool change_mali_dvfs_status(u32 step, mali_bool boostup ) { MALI_DEBUG_PRINT(1, ("> 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; } static unsigned int decideNextStatus(unsigned int utilization) { unsigned int level=0; // 0:stay, 1:up if (!mali_dvfs_control) { #if MALI_GPU_BOTTOM_LOCK if (_mali_osk_atomic_read(&bottomlock_status) > 0) level = 1; /* or bigger */ else if (utilization > mali_dvfs_threshold[maliDvfsStatus.currentStep].upthreshold) #else if (utilization > mali_dvfs_threshold[maliDvfsStatus.currentStep].upthreshold) #endif level=1; else if (utilization < mali_dvfs_threshold[maliDvfsStatus.currentStep].downthreshold) level=0; else level = maliDvfsStatus.currentStep; } else { if ((mali_dvfs_control > 0) && (mali_dvfs_control < mali_dvfs[1].clock)) level=0; else level=1; } return level; } #ifdef EXYNOS4_ASV_ENABLED static mali_bool mali_dvfs_table_update(void) { unsigned int exynos_result_of_asv_group; unsigned int i; exynos_result_of_asv_group = exynos_result_of_asv & 0xf; MALI_PRINT(("exynos_result_of_asv_group = 0x%x\n", exynos_result_of_asv_group)); if (ASV_LEVEL_SUPPORT) { //asv level information will be added. for (i = 0; i < MALI_DVFS_STEPS; i++) { mali_dvfs[i].vol = asv_3d_volt_5_table[exynos_result_of_asv_group][i]; MALI_PRINT(("mali_dvfs[%d].vol = %d\n", i, mali_dvfs[i].vol)); } } else { for (i = 0; i < MALI_DVFS_STEPS; i++) { mali_dvfs[i].vol = asv_3d_volt_8_table[exynos_result_of_asv_group][i]; MALI_PRINT(("mali_dvfs[%d].vol = %d\n", i, mali_dvfs[i].vol)); } } return MALI_TRUE; } #endif static mali_bool mali_dvfs_status(u32 utilization) { unsigned int nextStatus = 0; unsigned int curStatus = 0; mali_bool boostup = MALI_FALSE; #ifdef EXYNOS4_ASV_ENABLED static mali_bool asv_applied = MALI_FALSE; #endif static int stay_count = 0; // to prevent frequent switch MALI_DEBUG_PRINT(1, ("> mali_dvfs_status: %d \n",utilization)); #ifdef EXYNOS4_ASV_ENABLED if (asv_applied == MALI_FALSE) { mali_dvfs_table_update(); change_mali_dvfs_status(0,0); asv_applied = MALI_TRUE; return MALI_TRUE; } #endif /*decide next step*/ curStatus = get_mali_dvfs_status(); nextStatus = decideNextStatus(utilization); MALI_DEBUG_PRINT(1, ("= 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 && stay_count==0)) { /*check if boost up or not*/ if (nextStatus > maliDvfsStatus.currentStep) boostup = 1; /*change mali dvfs status*/ if (!change_mali_dvfs_status(nextStatus,boostup)) { MALI_DEBUG_PRINT(1, ("error on change_mali_dvfs_status \n")); return MALI_FALSE; } stay_count = mali_dvfs_staycount[maliDvfsStatus.currentStep].staycount; } else { if (stay_count>0) stay_count--; } return MALI_TRUE; } int mali_dvfs_is_running(void) { return bMaliDvfsRun; } void mali_dvfs_late_resume(void) { // set the init clock as low when resume set_mali_dvfs_status(0,0); } 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(int step) { /*default status add here with the right function to get initilization value. */ if (!mali_dvfs_wq) mali_dvfs_wq = create_singlethread_workqueue("mali_dvfs"); #if MALI_GPU_BOTTOM_LOCK _mali_osk_atomic_init(&bottomlock_status, 0); #endif /*add a error handling here*/ maliDvfsStatus.currentStep = step; return MALI_TRUE; } void deinit_mali_dvfs_status(void) { #if MALI_GPU_BOTTOM_LOCK _mali_osk_atomic_term(&bottomlock_status); #endif if (mali_dvfs_wq) destroy_workqueue(mali_dvfs_wq); mali_dvfs_wq = NULL; } mali_bool mali_dvfs_handler(u32 utilization) { mali_dvfs_utilization = utilization; queue_work_on(0, mali_dvfs_wq,&mali_dvfs_work); /*add error handle here*/ return MALI_TRUE; } void mali_default_step_set(int step, mali_bool boostup) { mali_clk_set_rate(mali_dvfs[step].clock, mali_dvfs[step].freq); if (maliDvfsStatus.currentStep == 1) set_mali_dvfs_status(step, boostup); } #if MALI_GPU_BOTTOM_LOCK int mali_dvfs_bottom_lock_push(void) { int prev_status = _mali_osk_atomic_read(&bottomlock_status); if (prev_status < 0) { MALI_PRINT(("gpu bottom lock status is not valid for push")); 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); } int mali_dvfs_bottom_lock_pop(void) { if (_mali_osk_atomic_read(&bottomlock_status) <= 0) { MALI_PRINT(("gpu bottom lock status is not valid for pop")); return -1; } return _mali_osk_atomic_dec_return(&bottomlock_status); } #endif \ No newline at end of file
diff --git a/drivers/media/video/samsung/mali/platform/pegasus-m400/mali_platform.c b/drivers/media/video/samsung/mali/platform/pegasus-m400/mali_platform.c
index 397ba942..e8e5129 100644
--- a/drivers/media/video/samsung/mali/platform/pegasus-m400/mali_platform.c
+++ b/drivers/media/video/samsung/mali/platform/pegasus-m400/mali_platform.c
@@ -1,5 +1,4 @@
-/*
- * Copyright (C) 2010 ARM Limited. All rights reserved.
+/* 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.
@@ -19,7 +18,7 @@
#include "mali_linux_pm.h"
#if USING_MALI_PMM
-#include "mali_pmm.h"
+#include "mali_pm.h"
#endif
#include <linux/clk.h>
@@ -32,8 +31,9 @@
#include <plat/pd.h>
#endif
-#if MALI_TIMELINE_PROFILING_ENABLED
-#include "mali_kernel_profiling.h"
+#if MALI_INTERNAL_TIMELINE_PROFILING_ENABLED
+#include "mali_osk_profiling.h"
+#include "cinstr/mali_cinstr_profiling_events_m200.h"
#endif
#include <asm/io.h>
@@ -58,12 +58,20 @@ typedef struct mali_runtime_resumeTag{
int vol;
}mali_runtime_resume_table;
-mali_runtime_resume_table mali_runtime_resume = {266, 900000};
+mali_runtime_resume_table mali_runtime_resume = {350, 950000};
/* lock/unlock CPU freq by Mali */
extern int cpufreq_lock_by_mali(unsigned int freq);
extern void cpufreq_unlock_by_mali(void);
+/* start of modification by skkim */
+extern mali_bool init_mali_dvfs_status(int step);
+extern void deinit_mali_dvfs_status(void);
+extern mali_bool mali_dvfs_handler(u32 utilization);
+extern int get_mali_dvfs_control_status(void);
+extern mali_bool set_mali_dvfs_current_step(unsigned int step);
+/* end of modification by skkim */
+
static struct clk *ext_xtal_clock = 0;
static struct clk *vpll_src_clock = 0;
static struct clk *fout_vpll_clock = 0;
@@ -76,11 +84,11 @@ static struct clk *mali_clock = 0;
static unsigned int GPU_MHZ = 1000000;
-int mali_gpu_clk = 266;
-int mali_gpu_vol = 900000;
+int mali_gpu_clk = 350;
+int mali_gpu_vol = 950000;
#if MALI_DVFS_ENABLED
-#define MALI_DVFS_DEFAULT_STEP 0
+#define MALI_DVFS_DEFAULT_STEP 2
#endif
#if MALI_VOLTAGE_LOCK
int mali_lock_vol = 0;
@@ -134,7 +142,6 @@ int mali_regulator_get_usecount(void)
void mali_regulator_disable(void)
{
- bPoweroff = 1;
if( IS_ERR_OR_NULL(g3d_regulator) )
{
MALI_DEBUG_PRINT(1, ("error on mali_regulator_disable : g3d_regulator is null\n"));
@@ -142,11 +149,11 @@ void mali_regulator_disable(void)
}
regulator_disable(g3d_regulator);
MALI_DEBUG_PRINT(1, ("regulator_disable -> use cnt: %d \n",mali_regulator_get_usecount()));
+ bPoweroff = 1;
}
void mali_regulator_enable(void)
{
- bPoweroff = 0;
if( IS_ERR_OR_NULL(g3d_regulator) )
{
MALI_DEBUG_PRINT(1, ("error on mali_regulator_enable : g3d_regulator is null\n"));
@@ -154,6 +161,7 @@ void mali_regulator_enable(void)
}
regulator_enable(g3d_regulator);
MALI_DEBUG_PRINT(1, ("regulator_enable -> use cnt: %d \n",mali_regulator_get_usecount()));
+ bPoweroff = 0;
}
void mali_regulator_set_voltage(int min_uV, int max_uV)
@@ -196,8 +204,8 @@ void mali_regulator_set_voltage(int min_uV, int max_uV)
MALI_DEBUG_PRINT(2, ("= regulator_set_voltage: %d, %d \n",min_uV, max_uV));
-#if MALI_TIMELINE_PROFILING_ENABLED
- _mali_profiling_add_event( MALI_PROFILING_EVENT_TYPE_SINGLE |
+#if MALI_INTERNAL_TIMELINE_PROFILING_ENABLED
+ _mali_osk_profiling_add_event( MALI_PROFILING_EVENT_TYPE_SINGLE |
MALI_PROFILING_EVENT_CHANNEL_SOFTWARE |
MALI_PROFILING_EVENT_REASON_SINGLE_SW_GPU_VOLTS,
min_uV, max_uV, 1, 0, 0);
@@ -206,8 +214,8 @@ void mali_regulator_set_voltage(int min_uV, int max_uV)
regulator_set_voltage(g3d_regulator,min_uV,max_uV);
voltage = regulator_get_voltage(g3d_regulator);
-#if MALI_TIMELINE_PROFILING_ENABLED
- _mali_profiling_add_event( MALI_PROFILING_EVENT_TYPE_SINGLE |
+#if MALI_INTERNAL_TIMELINE_PROFILING_ENABLED
+ _mali_osk_profiling_add_event( MALI_PROFILING_EVENT_TYPE_SINGLE |
MALI_PROFILING_EVENT_CHANNEL_SOFTWARE |
MALI_PROFILING_EVENT_REASON_SINGLE_SW_GPU_VOLTS,
voltage, 0, 2, 0, 0);
@@ -398,18 +406,20 @@ mali_bool mali_clk_set_rate(unsigned int clk, unsigned int mhz)
if (clk_enable(mali_clock) < 0)
return MALI_FALSE;
-#if MALI_TIMELINE_PROFILING_ENABLED
- _mali_profiling_add_event( MALI_PROFILING_EVENT_TYPE_SINGLE |
+#if MALI_INTERNAL_TIMELINE_PROFILING_ENABLED
+ unsigned long previous_rate = 0;
+ previous_rate = clk_get_rate(mali_clock);
+ _mali_osk_profiling_add_event( MALI_PROFILING_EVENT_TYPE_SINGLE |
MALI_PROFILING_EVENT_CHANNEL_SOFTWARE |
MALI_PROFILING_EVENT_REASON_SINGLE_SW_GPU_FREQ,
- rate, 0, 0, 0, 0);
+ previous_rate, 0, 0, 0, 0);
#endif
clk_set_rate(mali_clock, rate);
rate = clk_get_rate(mali_clock);
-#if MALI_TIMELINE_PROFILING_ENABLED
- _mali_profiling_add_event( MALI_PROFILING_EVENT_TYPE_SINGLE |
+#if MALI_INTERNAL_TIMELINE_PROFILING_ENABLED
+ _mali_osk_profiling_add_event( MALI_PROFILING_EVENT_TYPE_SINGLE |
MALI_PROFILING_EVENT_CHANNEL_SOFTWARE |
MALI_PROFILING_EVENT_REASON_SINGLE_SW_GPU_FREQ,
rate, 1, 0, 0, 0);
@@ -434,8 +444,6 @@ static mali_bool init_mali_clock(void)
{
mali_bool ret = MALI_TRUE;
- gpu_power_state = 0;
-
if (mali_clock != 0)
return ret; // already initialized
@@ -475,15 +483,15 @@ static mali_bool init_mali_clock(void)
MALI_DEBUG_PRINT(2, ("MALI Clock is set at mali driver\n"));
-
MALI_DEBUG_PRINT(3,("::clk_put:: %s mali_parent_clock - normal\n", __FUNCTION__));
MALI_DEBUG_PRINT(3,("::clk_put:: %s mpll_clock - normal\n", __FUNCTION__));
mali_clk_put(MALI_FALSE);
- return MALI_TRUE;
-
+ gpu_power_state=0;
+ bPoweroff=1;
+ return MALI_TRUE;
#ifdef CONFIG_REGULATOR
err_regulator:
regulator_put(g3d_regulator);
@@ -526,12 +534,13 @@ static _mali_osk_errcode_t enable_mali_clocks(void)
else {
mali_regulator_set_voltage(mali_runtime_resume.vol, mali_runtime_resume.vol);
mali_clk_set_rate(mali_runtime_resume.clk, GPU_MHZ);
+ set_mali_dvfs_current_step(MALI_DVFS_DEFAULT_STEP);
}
- if (mali_gpu_clk <= mali_runtime_resume.clk)
- set_mali_dvfs_current_step(5);
+#if CPUFREQ_LOCK_DURING_440
/* lock/unlock CPU freq by Mali */
if (mali_gpu_clk == 440)
err = cpufreq_lock_by_mali(1200);
+#endif
#else
mali_regulator_set_voltage(mali_runtime_resume.vol, mali_runtime_resume.vol);
mali_clk_set_rate(mali_runtime_resume.clk, GPU_MHZ);
@@ -547,8 +556,10 @@ static _mali_osk_errcode_t disable_mali_clocks(void)
clk_disable(mali_clock);
MALI_DEBUG_PRINT(3,("disable_mali_clocks mali_clock %p \n", mali_clock));
+#if MALI_DVFS_ENABLED
/* lock/unlock CPU freq by Mali */
cpufreq_unlock_by_mali();
+#endif
MALI_SUCCESS;
}
@@ -569,7 +580,7 @@ _mali_osk_errcode_t g3d_power_domain_control(int bpower_on)
{
#if MALI_PMM_RUNTIME_JOB_CONTROL_ON
MALI_DEBUG_PRINT(3,("_mali_osk_pmm_dev_activate \n"));
- _mali_osk_pmm_dev_activate();
+ _mali_osk_pm_dev_activate();
#else //MALI_PMM_RUNTIME_JOB_CONTROL_ON
void __iomem *status;
u32 timeout;
@@ -586,14 +597,14 @@ _mali_osk_errcode_t g3d_power_domain_control(int bpower_on)
timeout--;
_mali_osk_time_ubusydelay(100);
}
+ MALI_PRINTF(("MALI Power domain enabled"));
#endif //MALI_PMM_RUNTIME_JOB_CONTROL_ON
}
else
{
#if MALI_PMM_RUNTIME_JOB_CONTROL_ON
MALI_DEBUG_PRINT( 4,("_mali_osk_pmm_dev_idle\n"));
- _mali_osk_pmm_dev_idle();
-
+ _mali_osk_pm_dev_idle();
#else //MALI_PMM_RUNTIME_JOB_CONTROL_ON
void __iomem *status;
u32 timeout;
@@ -611,6 +622,7 @@ _mali_osk_errcode_t g3d_power_domain_control(int bpower_on)
timeout--;
_mali_osk_time_ubusydelay( 100);
}
+ MALI_PRINTF(("MALI Power domain disabled"));
#endif //MALI_PMM_RUNTIME_JOB_CONTROL_ON
}
@@ -714,7 +726,51 @@ u32 pmu_get_power_up_down_info(void)
_mali_osk_errcode_t mali_platform_power_mode_change(mali_power_mode power_mode)
{
- MALI_SUCCESS;
+ switch (power_mode)
+ {
+ case MALI_POWER_MODE_ON:
+ MALI_DEBUG_PRINT(1, ("Mali platform: Got MALI_POWER_MODE_ON event, %s\n", bPoweroff ? "powering on" : "already on"));
+ if (bPoweroff == 1)
+ {
+ /** If run time power management is used, donot call this function */
+#ifndef CONFIG_PM_RUNTIME
+ g3d_power_domain_control(1);
+#endif
+
+ MALI_DEBUG_PRINT(4,("enable clock \n"));
+ enable_mali_clocks();
+#if MALI_INTERNAL_TIMELINE_PROFILING_ENABLED
+ _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_PRINTF(("Mali Platform powered up"));
+ gpu_power_state=1;
+ bPoweroff=0;
+ }
+ break;
+ case MALI_POWER_MODE_LIGHT_SLEEP:
+ case MALI_POWER_MODE_DEEP_SLEEP:
+ MALI_DEBUG_PRINT(1, ("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 MALI_INTERNAL_TIMELINE_PROFILING_ENABLED
+ _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
+
+#ifndef CONFIG_PM_RUNTIME
+ g3d_power_domain_control(0);
+#endif
+
+ //MALI_PRINTF(("Mali Platform powered down"));
+ gpu_power_state=0;
+ bPoweroff=1;
+ }
+
+ break;
+ }
+ MALI_SUCCESS;
}
#if MALI_VOLTAGE_LOCK
diff --git a/drivers/media/video/samsung/mali/platform/pegasus-m400/mali_platform_dvfs.c b/drivers/media/video/samsung/mali/platform/pegasus-m400/mali_platform_dvfs.c
index 8293d6e..2d47dba 100644
--- a/drivers/media/video/samsung/mali/platform/pegasus-m400/mali_platform_dvfs.c
+++ b/drivers/media/video/samsung/mali/platform/pegasus-m400/mali_platform_dvfs.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 ARM Limited. All rights reserved.
+ * 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.
@@ -27,7 +27,7 @@
#include "mali_device_pause_resume.h"
#include <linux/workqueue.h>
-#define MAX_MALI_DVFS_STEPS 4
+#define MAX_MALI_DVFS_STEPS 5
#define MALI_DVFS_WATING 10 // msec
#ifdef CONFIG_CPU_FREQ
@@ -35,10 +35,12 @@
#define EXYNOS4_ASV_ENABLED
#endif
+#include <plat/cpu.h>
+
static int bMaliDvfsRun=0;
static _mali_osk_atomic_t bottomlock_status;
-static int bottom_lock_step;
+int bottom_lock_step = 0;
typedef struct mali_dvfs_tableTag{
unsigned int clock;
@@ -73,7 +75,10 @@ mali_dvfs_step step[MALI_DVFS_STEPS]={
#if (MALI_DVFS_STEPS > 2)
/*step 2 clk*/ {350, 950000},
#if (MALI_DVFS_STEPS > 3)
- /*step 3 clk*/ {440, 1025000}
+ /*step 3 clk*/ {440, 1025000},
+#if (MALI_DVFS_STEPS > 4)
+ /*step 4 clk*/ {533, 1075000}
+#endif
#endif
#endif
#endif
@@ -86,17 +91,21 @@ mali_dvfs_staycount_table mali_dvfs_staycount[MALI_DVFS_STEPS]={
#if (MALI_DVFS_STEPS > 2)
/*step 2*/{0},
#if (MALI_DVFS_STEPS > 3)
- /*step 3*/{0}
+ /*step 3*/{0},
+#if (MALI_DVFS_STEPS > 4)
+ /*step 4*/{0}
+#endif
#endif
#endif
#endif
};
/* dvfs information */
-// L0 = 440Mhz, 1.025V
-// L1 = 350Mhz, 0.95V
-// L2 = 266Mhz, 0.90V
-// L3 = 160Mhz, 0.875V
+// L0 = 533Mhz, 1.075V
+// L1 = 440Mhz, 1.025V
+// L2 = 350Mhz, 0.95V
+// L3 = 266Mhz, 0.90V
+// L4 = 160Mhz, 0.875V
int step0_clk = 160;
int step0_vol = 875000;
@@ -114,7 +123,13 @@ int step2_down = 85;
int step3_clk = 440;
int step3_vol = 1025000;
int step2_up = 90;
-int step3_down = 90;
+int step3_down = 85;
+#if (MALI_DVFS_STEPS > 4)
+int step4_clk = 533;
+int step4_vol = 1075000;
+int step3_up = 90;
+int step4_down = 95;
+#endif
#endif
#endif
#endif
@@ -123,7 +138,8 @@ mali_dvfs_table mali_dvfs_all[MAX_MALI_DVFS_STEPS]={
{160 ,1000000 , 875000},
{266 ,1000000 , 900000},
{350 ,1000000 , 950000},
- {440 ,1000000 , 1025000} };
+ {440 ,1000000 , 1025000},
+ {533 ,1000000 , 1075000} };
mali_dvfs_table mali_dvfs[MALI_DVFS_STEPS]={
{160 ,1000000 , 875000},
@@ -132,7 +148,10 @@ mali_dvfs_table mali_dvfs[MALI_DVFS_STEPS]={
#if (MALI_DVFS_STEPS > 2)
{350 ,1000000 , 950000},
#if (MALI_DVFS_STEPS > 3)
- {440 ,1000000 ,1025000}
+ {440 ,1000000 ,1025000},
+#if (MALI_DVFS_STEPS > 4)
+ {533 ,1000000 ,1075000}
+#endif
#endif
#endif
#endif
@@ -145,7 +164,10 @@ mali_dvfs_threshold_table mali_dvfs_threshold[MALI_DVFS_STEPS]={
#if (MALI_DVFS_STEPS > 2)
{85 , 90},
#if (MALI_DVFS_STEPS > 3)
- {90 ,100}
+ {85 ,90},
+#if (MALI_DVFS_STEPS > 4)
+ {95 ,100}
+#endif
#endif
#endif
#endif
@@ -154,19 +176,48 @@ mali_dvfs_threshold_table mali_dvfs_threshold[MALI_DVFS_STEPS]={
#ifdef EXYNOS4_ASV_ENABLED
#define ASV_LEVEL 12 /* ASV0, 1, 11 is reserved */
-static unsigned int asv_3d_volt_9_table[MALI_DVFS_STEPS][ASV_LEVEL] = {
+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) */
+ { 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) */
+ { 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) */
+ { 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] = {
+ { 950000, 937500, 925000, 912500, 900000, 887500, 875000, 862500, 875000, 862500, 850000, 850000}, /* L4(160Mhz) */
+#if (MALI_DVFS_STEPS > 1)
+ { 975000, 962500, 950000, 937500, 925000, 912500, 900000, 887500, 900000, 887500, 875000, 862500}, /* L3(266Mhz) */
+#if (MALI_DVFS_STEPS > 2)
+ { 1025000, 1012500, 1000000, 987500, 975000, 962500, 950000, 937500, 950000, 937500, 925000, 912500}, /* L2(350Mhz) */
+#if (MALI_DVFS_STEPS > 3)
+ { 1087500, 1075000, 1062500, 1050000, 1037500, 1025000, 1012500, 1000000, 1012500, 1000000, 987500, 975000}, /* L1(440Mhz) */
+#if (MALI_DVFS_STEPS > 4)
+ { 1150000, 1137500, 1125000, 1112500, 1100000, 1087500, 1075000, 1062500, 1087500, 1075000, 1062500, 1050000}, /* L0(533Mhz) */
+#endif
#endif
+#endif
+#endif
+};
+#endif /* ASV_LEVEL */
/*dvfs status*/
mali_dvfs_currentstatus maliDvfsStatus;
@@ -279,10 +330,12 @@ static mali_bool set_mali_dvfs_status(u32 step,mali_bool boostup)
}
#ifdef EXYNOS4_ASV_ENABLED
- 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);
+ 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
@@ -290,11 +343,13 @@ static mali_bool set_mali_dvfs_status(u32 step,mali_bool boostup)
/*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(1200);
else
cpufreq_unlock_by_mali();
+#endif
return MALI_TRUE;
}
@@ -335,11 +390,30 @@ extern unsigned int exynos_result_of_asv;
static mali_bool mali_dvfs_table_update(void)
{
unsigned int i;
-
- for (i = 0; i < MALI_DVFS_STEPS; i++) {
- MALI_PRINT((":::exynos_result_of_asv : %d\n", exynos_result_of_asv));
- 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));
+ unsigned int step_num = MALI_DVFS_STEPS;
+
+ if(soc_is_exynos4412()) {
+ if (exynos_armclk_max == 1000000) {
+ step_num = MALI_DVFS_STEPS - 1;
+ 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_9_table_1ghz_type[i][exynos_result_of_asv];
+ MALI_PRINT(("mali_dvfs[%d].vol = %d 1ghz_type\n", i, mali_dvfs[i].vol));
+ }
+ } else if (samsung_rev() >= EXYNOS4412_REV_2_0) {
+ 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_9_table_for_prime[i][exynos_result_of_asv];
+ MALI_PRINT(("mali_dvfs[%d].vol = %d 1.6ghz_type\n", i, mali_dvfs[i].vol));
+ }
+ } else {
+ step_num = MALI_DVFS_STEPS - 1;
+ 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_9_table[i][exynos_result_of_asv];
+ MALI_PRINT(("mali_dvfs[%d].vol = %d 1.4ghz_type\n", i, mali_dvfs[i].vol));
+ }
+ }
}
return MALI_TRUE;
@@ -354,7 +428,6 @@ static unsigned int decideNextStatus(unsigned int utilization)
if (mali_runtime_resumed >= 0) {
level = mali_runtime_resumed;
mali_runtime_resumed = -1;
- return level;
}
if (mali_dvfs_threshold[maliDvfsStatus.currentStep].upthreshold
@@ -369,6 +442,9 @@ static unsigned int decideNextStatus(unsigned int utilization)
if (utilization > (int)(255 * mali_dvfs_threshold[maliDvfsStatus.currentStep].upthreshold / 100) &&
level < MALI_DVFS_STEPS - 1) {
level++;
+ if ((samsung_rev() < EXYNOS4412_REV_2_0) && (maliDvfsStatus.currentStep == 3)) {
+ level=get_mali_dvfs_status();
+ }
}
if (utilization < (int)(255 * mali_dvfs_threshold[maliDvfsStatus.currentStep].downthreshold / 100) &&
level > 0) {
@@ -400,6 +476,10 @@ static unsigned int decideNextStatus(unsigned int utilization)
#if (MALI_DVFS_STEPS > 3)
step3_clk = step[3].clk;
change_dvfs_tableset(step3_clk, 3);
+#if (MALI_DVFS_STEPS > 4)
+ step4_clk = step[4].clk;
+ change_dvfs_tableset(step4_clk, 4);
+#endif
#endif
#endif
#endif
@@ -422,12 +502,18 @@ static unsigned int decideNextStatus(unsigned int utilization)
step[i].clk = mali_dvfs_all[2].clock;
}
maliDvfsStatus.currentStep = 2;
- } else {
+ } else if (mali_dvfs_control < mali_dvfs_all[4].clock && mali_dvfs_control >= mali_dvfs_all[3].clock) {
int i = 0;
for (i = 0; i < MALI_DVFS_STEPS; i++) {
step[i].clk = mali_dvfs_all[3].clock;
}
maliDvfsStatus.currentStep = 3;
+ } else {
+ int i = 0;
+ for (i = 0; i < MALI_DVFS_STEPS; i++) {
+ step[i].clk = mali_dvfs_all[4].clock;
+ }
+ maliDvfsStatus.currentStep = 4;
}
step0_clk = step[0].clk;
change_dvfs_tableset(step0_clk, 0);
@@ -440,6 +526,10 @@ static unsigned int decideNextStatus(unsigned int utilization)
#if (MALI_DVFS_STEPS > 3)
step3_clk = step[3].clk;
change_dvfs_tableset(step3_clk, 3);
+#if (MALI_DVFS_STEPS > 4)
+ step4_clk = step[4].clk;
+ change_dvfs_tableset(step4_clk, 4);
+#endif
#endif
#endif
#endif
@@ -577,6 +667,22 @@ static void mali_dvfs_work_handler(struct work_struct *w)
MALI_PRINT((":::step3_down change to %d %\n", step3_down));
mali_dvfs_threshold[3].downthreshold = step3_down;
}
+#if (MALI_DVFS_STEPS > 4)
+ if (step4_clk != mali_dvfs[4].clock) {
+ MALI_PRINT(("::: step4_clk change to %d Mhz\n", step4_clk));
+ change_clk = step4_clk;
+ change_step = 4;
+ step4_clk = change_dvfs_tableset(change_clk, change_step);
+ }
+ if (step3_up != mali_dvfs_threshold[3].upthreshold) {
+ MALI_PRINT((":::step3_up change to %d %\n", step3_up));
+ mali_dvfs_threshold[3].upthreshold = step3_up;
+ }
+ if (step4_down != mali_dvfs_threshold[4].downthreshold) {
+ MALI_PRINT((":::step4_down change to %d %\n", step4_down));
+ mali_dvfs_threshold[4].downthreshold = step4_down;
+ }
+#endif
#endif
#endif
#endif
@@ -587,6 +693,7 @@ static void mali_dvfs_work_handler(struct work_struct *w)
mali_dvfs[1].vol = step1_vol;
mali_dvfs[2].vol = step2_vol;
mali_dvfs[3].vol = step3_vol;
+ mali_dvfs[4].vol = step4_vol;
#endif
MALI_DEBUG_PRINT(3, ("=== mali_dvfs_work_handler\n"));
@@ -641,8 +748,10 @@ int change_dvfs_tableset(int change_clk, int change_step)
mali_dvfs[change_step].clock = mali_dvfs_all[1].clock;
} else if (change_clk < mali_dvfs_all[3].clock && change_clk >= mali_dvfs_all[2].clock) {
mali_dvfs[change_step].clock = mali_dvfs_all[2].clock;
- } else {
+ } else if (change_clk < mali_dvfs_all[4].clock && change_clk >= mali_dvfs_all[3].clock) {
mali_dvfs[change_step].clock = mali_dvfs_all[3].clock;
+ } else {
+ mali_dvfs[change_step].clock = mali_dvfs_all[4].clock;
}
MALI_PRINT((":::mali dvfs step %d clock and voltage = %d Mhz, %d V\n",change_step, mali_dvfs[change_step].clock, mali_dvfs[change_step].vol));
@@ -655,11 +764,13 @@ int change_dvfs_tableset(int change_clk, int change_step)
/*change the clock*/
mali_clk_set_rate(mali_dvfs[change_step].clock, mali_dvfs[change_step].freq);
+#if CPUFREQ_LOCK_DURING_440
/* lock/unlock CPU freq by Mali */
if (mali_dvfs[change_step].clock == 440)
err = cpufreq_lock_by_mali(1200);
else
cpufreq_unlock_by_mali();
+#endif
}
return mali_dvfs[change_step].clock;
@@ -684,10 +795,8 @@ int mali_dvfs_bottom_lock_push(int lock_step)
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);
+ 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);
}
}
diff --git a/drivers/media/video/samsung/mali/readme.txt b/drivers/media/video/samsung/mali/readme.txt
new file mode 100644
index 0000000..3acc51c
--- /dev/null
+++ b/drivers/media/video/samsung/mali/readme.txt
@@ -0,0 +1,28 @@
+Building the Mali Device Driver for Linux
+-----------------------------------------
+
+Build the Mali Device Driver for Linux by running the following make command:
+
+KDIR=<kdir_path> USING_UMP=<ump_option> BUILD=<build_option> \
+TARGET_PLATFORM=<target_platform> CONFIG=<your_config> make
+
+where
+ kdir_path: Path to your Linux Kernel directory
+ ump_option: 1 = Enable UMP support(*)
+ 0 = disable UMP support
+ build_option: debug = debug build of driver
+ release = release build of driver
+ target_platform: Name of the sub-folder in platform/ that contains the
+ required mali_platform.c file.
+ your_config: Name of the sub-folder to find the required config.h(**) file
+ ("arch-" will be prepended)
+
+(*) For newer Linux Kernels, the Module.symvers file for the UMP device driver
+ must be available. The UMP_SYMVERS_FILE variable in the Makefile should
+ point to this file. This file is generated when the UMP driver is built.
+
+(**) The config.h file contains the configuration parameters needed, like where the
+ Mali GPU is located, interrupts it uses, memory and so on.
+
+The result will be a mali.ko file, which can be loaded into the Linux kernel
+by using the insmod command.
diff --git a/drivers/media/video/samsung/mali/regs/mali_200_regs.h b/drivers/media/video/samsung/mali/regs/mali_200_regs.h
index e9da7ab..59e92c8 100644
--- a/drivers/media/video/samsung/mali/regs/mali_200_regs.h
+++ b/drivers/media/video/samsung/mali/regs/mali_200_regs.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 ARM Limited. All rights reserved.
+ * 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.
@@ -51,7 +51,7 @@ enum mali200_mgmt_ctrl_mgmt {
#endif
MALI200_REG_VAL_CTRL_MGMT_FORCE_RESET = (1<<5),
MALI200_REG_VAL_CTRL_MGMT_START_RENDERING = (1<<6),
-#if defined(USING_MALI400)
+#if defined(USING_MALI400) || defined(USING_MALI450)
MALI400PP_REG_VAL_CTRL_MGMT_SOFT_RESET = (1<<7),
#endif
};
@@ -72,7 +72,7 @@ enum mali200_mgmt_irq {
MALI400PP_REG_VAL_IRQ_RESET_COMPLETED = (1<<12),
};
-#if defined USING_MALI200
+#if defined(USING_MALI200)
#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 |\
@@ -83,7 +83,7 @@ enum mali200_mgmt_irq {
MALI200_REG_VAL_IRQ_CNT_0_LIMIT |\
MALI200_REG_VAL_IRQ_CNT_1_LIMIT |\
MALI200_REG_VAL_IRQ_WRITE_BOUNDARY_ERROR))
-#elif defined USING_MALI400
+#elif defined(USING_MALI400) || defined(USING_MALI450)
#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 |\
@@ -102,14 +102,14 @@ enum mali200_mgmt_irq {
#error "No supported mali core defined"
#endif
-#if defined USING_MALI200
+#if defined(USING_MALI200)
#define MALI200_REG_VAL_IRQ_MASK_USED ((enum mali200_mgmt_irq) (\
MALI200_REG_VAL_IRQ_END_OF_FRAME |\
MALI200_REG_VAL_IRQ_HANG |\
MALI200_REG_VAL_IRQ_FORCE_HANG |\
MALI200_REG_VAL_IRQ_BUS_ERROR |\
MALI200_REG_VAL_IRQ_WRITE_BOUNDARY_ERROR))
-#elif defined USING_MALI400
+#elif defined(USING_MALI400) || defined(USING_MALI450)
#define MALI200_REG_VAL_IRQ_MASK_USED ((enum mali200_mgmt_irq) (\
MALI200_REG_VAL_IRQ_END_OF_FRAME |\
MALI200_REG_VAL_IRQ_HANG |\
@@ -134,11 +134,14 @@ enum mali200_mgmt_status {
enum mali200_render_unit
{
MALI200_REG_ADDR_FRAME = 0x0000,
+ MALI200_REG_ADDR_STACK = 0x0030
};
-#if defined USING_MALI200
+#if defined(USING_MALI200)
#define MALI200_NUM_REGS_FRAME ((0x04C/4)+1)
-#elif defined USING_MALI400
+#elif defined(USING_MALI400)
+#define MALI200_NUM_REGS_FRAME ((0x058/4)+1)
+#elif defined(USING_MALI450)
#define MALI200_NUM_REGS_FRAME ((0x058/4)+1)
#else
#error "No supported mali core defined"
@@ -150,21 +153,20 @@ enum mali200_wb_unit {
MALI200_REG_ADDR_WB2 = 0x0300
};
+enum mali200_wb_unit_regs {
+ MALI200_REG_ADDR_WB_SOURCE_SELECT = 0x0000,
+};
+
/** The number of registers in one single writeback unit */
#ifndef MALI200_NUM_REGS_WBx
#define MALI200_NUM_REGS_WBx ((0x02C/4)+1)
#endif
/* This should be in the top 16 bit of the version register of Mali PP */
-#if defined USING_MALI200
-#define MALI_PP_PRODUCT_ID 0xC807
-#elif defined USING_MALI400
+#define MALI200_PP_PRODUCT_ID 0xC807
#define MALI300_PP_PRODUCT_ID 0xCE07
#define MALI400_PP_PRODUCT_ID 0xCD07
-#define MALI_PP_PRODUCT_ID MALI400_PP_PRODUCT_ID
-#else
-#error "No supported mali core defined"
-#endif
+#define MALI450_PP_PRODUCT_ID 0xCF07
#endif /* _MALI200_REGS_H_ */
diff --git a/drivers/media/video/samsung/mali/regs/mali_gp_regs.h b/drivers/media/video/samsung/mali/regs/mali_gp_regs.h
index 14719a3..21c83c0 100644
--- a/drivers/media/video/samsung/mali/regs/mali_gp_regs.h
+++ b/drivers/media/video/samsung/mali/regs/mali_gp_regs.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 ARM Limited. All rights reserved.
+ * 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.
@@ -12,9 +12,9 @@
#define _MALIGP2_CONROL_REGS_H_
/**
- * These are the different geometry processor controll registers.
+ * 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 Builer in the geometry processor.
+ * 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
*/
@@ -60,7 +60,7 @@ typedef enum
MALIGP2_REG_VAL_CMD_RESET = (1<< 5),
MALIGP2_REG_VAL_CMD_FORCE_HANG = (1<< 6),
MALIGP2_REG_VAL_CMD_STOP_BUS = (1<< 9),
-#if defined(USING_MALI400)
+#if defined(USING_MALI400) || defined(USING_MALI450)
MALI400GP_REG_VAL_CMD_SOFT_RESET = (1<<10),
#endif
} mgp_contr_reg_val_cmd;
@@ -84,7 +84,7 @@ typedef enum
#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)
-#if defined USING_MALI400
+#if defined(USING_MALI400) || defined(USING_MALI450)
#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)
@@ -97,7 +97,7 @@ typedef enum
#endif
/* Mask defining all IRQs in MaliGP2 */
-#if defined USING_MALI200
+#if defined(USING_MALI200)
#define MALIGP2_REG_VAL_IRQ_MASK_ALL \
(\
MALIGP2_REG_VAL_IRQ_VS_END_CMD_LST | \
@@ -112,7 +112,7 @@ typedef enum
MALIGP2_REG_VAL_IRQ_WRITE_BOUND_ERR | \
MALIGP2_REG_VAL_IRQ_SYNC_ERROR | \
MALIGP2_REG_VAL_IRQ_AXI_BUS_ERROR)
-#elif defined USING_MALI400
+#elif defined(USING_MALI400) || defined(USING_MALI450)
#define MALIGP2_REG_VAL_IRQ_MASK_ALL \
(\
MALIGP2_REG_VAL_IRQ_VS_END_CMD_LST | \
@@ -139,7 +139,7 @@ typedef enum
#endif
/* Mask defining the IRQs in MaliGP2 which we use*/
-#if defined USING_MALI200
+#if defined(USING_MALI200)
#define MALIGP2_REG_VAL_IRQ_MASK_USED \
(\
MALIGP2_REG_VAL_IRQ_VS_END_CMD_LST | \
@@ -150,7 +150,7 @@ typedef enum
MALIGP2_REG_VAL_IRQ_WRITE_BOUND_ERR | \
MALIGP2_REG_VAL_IRQ_SYNC_ERROR | \
MALIGP2_REG_VAL_IRQ_AXI_BUS_ERROR)
-#elif defined USING_MALI400
+#elif defined(USING_MALI400) || defined(USING_MALI450)
#define MALIGP2_REG_VAL_IRQ_MASK_USED \
(\
MALIGP2_REG_VAL_IRQ_VS_END_CMD_LST | \
@@ -197,15 +197,10 @@ typedef enum
MALIGP2_REG_VAL_STATUS_WRITE_BOUND_ERR )
/* This should be in the top 16 bit of the version register of gp.*/
-#if defined(USING_MALI200)
-#define MALI_GP_PRODUCT_ID 0xA07
-#elif defined(USING_MALI400)
+#define MALI200_GP_PRODUCT_ID 0xA07
#define MALI300_GP_PRODUCT_ID 0xC07
#define MALI400_GP_PRODUCT_ID 0xB07
-#define MALI_GP_PRODUCT_ID MALI400_GP_PRODUCT_ID
-#else
-#error "No supported mali core defined"
-#endif
+#define MALI450_GP_PRODUCT_ID 0xD07
/**
* The different sources for instrumented on the geometry processor.
diff --git a/drivers/media/video/samsung/mali/timestamp-arm11-cc/mali_timestamp.c b/drivers/media/video/samsung/mali/timestamp-arm11-cc/mali_timestamp.c
index cddfa58..a6b1d76 100644
--- a/drivers/media/video/samsung/mali/timestamp-arm11-cc/mali_timestamp.c
+++ b/drivers/media/video/samsung/mali/timestamp-arm11-cc/mali_timestamp.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 ARM Limited. All rights reserved.
+ * 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.
diff --git a/drivers/media/video/samsung/mali/timestamp-arm11-cc/mali_timestamp.h b/drivers/media/video/samsung/mali/timestamp-arm11-cc/mali_timestamp.h
index 442c6e0..3279dae 100644
--- a/drivers/media/video/samsung/mali/timestamp-arm11-cc/mali_timestamp.h
+++ b/drivers/media/video/samsung/mali/timestamp-arm11-cc/mali_timestamp.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 ARM Limited. All rights reserved.
+ * 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.
diff --git a/drivers/media/video/samsung/mali/timestamp-default/mali_timestamp.c b/drivers/media/video/samsung/mali/timestamp-default/mali_timestamp.c
index cddfa58..a6b1d76 100644
--- a/drivers/media/video/samsung/mali/timestamp-default/mali_timestamp.c
+++ b/drivers/media/video/samsung/mali/timestamp-default/mali_timestamp.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 ARM Limited. All rights reserved.
+ * 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.
diff --git a/drivers/media/video/samsung/mali/timestamp-default/mali_timestamp.h b/drivers/media/video/samsung/mali/timestamp-default/mali_timestamp.h
index 470eac9..94b842a 100644
--- a/drivers/media/video/samsung/mali/timestamp-default/mali_timestamp.h
+++ b/drivers/media/video/samsung/mali/timestamp-default/mali_timestamp.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 ARM Limited. All rights reserved.
+ * 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.
diff --git a/drivers/media/video/samsung/tvout/Kconfig b/drivers/media/video/samsung/tvout/Kconfig
index 176efeb..da7bda7 100644
--- a/drivers/media/video/samsung/tvout/Kconfig
+++ b/drivers/media/video/samsung/tvout/Kconfig
@@ -62,6 +62,16 @@ config HDMI_CONTROLLED_BY_EXT_IC
For example, the H/W has HDMI level shifter then it should be turned
on when HPD interrupt comes.
+config HDMI_TX_STRENGTH
+ bool "Tuning TX amplitude"
+ depends on VIDEO_TVOUT && ARCH_EXYNOS4
+ default n
+ ---help---
+ Say y here if the H/W needs to be tuned for TX amplitude.
+ HDMI driver will take the values registered at board file
+ and apply them through HDMI phy i2c according to the requested
+ channel number.
+
config HDMI_SWITCH_HPD
bool "HDMI HPD switch uevent driver support"
depends on HDMI_HPD
diff --git a/drivers/media/video/samsung/tvout/hw_if/hdcp.c b/drivers/media/video/samsung/tvout/hw_if/hdcp.c
index 569de28..41caf19 100644
--- a/drivers/media/video/samsung/tvout/hw_if/hdcp.c
+++ b/drivers/media/video/samsung/tvout/hw_if/hdcp.c
@@ -379,7 +379,9 @@ static int s5p_hdcp_read_bcaps(void)
if (s5p_ddc_read(HDCP_Bcaps, BCAPS_SIZE, &bcaps) < 0)
goto bcaps_read_err;
- if (s5p_hdmi_ctrl_status() == false || !s5p_hdmi_reg_get_hpd_status() || on_stop_process)
+ if (s5p_hdmi_ctrl_status() == false ||
+ !s5p_hdmi_reg_get_hpd_status() ||
+ on_stop_process)
goto bcaps_read_err;
writeb(bcaps, hdmi_base + S5P_HDMI_HDCP_BCAPS);
@@ -532,7 +534,8 @@ static void s5p_hdcp_reset_auth(void)
unsigned long spin_flags;
if (s5p_hdmi_ctrl_status() == false ||
- !s5p_hdmi_reg_get_hpd_status() || on_stop_process)
+ !s5p_hdmi_reg_get_hpd_status() ||
+ on_stop_process)
return;
spin_lock_irqsave(&hdcp_info.reset_lock, spin_flags);
@@ -956,9 +959,12 @@ check_ri_err:
static void s5p_hdcp_work(void *arg)
{
+ s5p_tvout_mutex_lock();
if (!hdcp_info.hdcp_enable || s5p_hdmi_ctrl_status() == false ||
- !s5p_hdmi_reg_get_hpd_status() || on_stop_process)
+ !s5p_hdmi_reg_get_hpd_status() || on_stop_process) {
+ s5p_tvout_mutex_unlock();
return;
+ }
if (hdcp_info.event & HDCP_EVENT_READ_BKSV_START) {
if (s5p_hdcp_bksv() < 0)
@@ -987,13 +993,16 @@ static void s5p_hdcp_work(void *arg)
else
hdcp_info.event &= ~HDCP_EVENT_CHECK_RI_START;
}
+ s5p_tvout_mutex_unlock();
return;
work_err:
if (!hdcp_info.hdcp_enable || s5p_hdmi_ctrl_status() == false ||
!s5p_hdmi_reg_get_hpd_status() || on_stop_process) {
+ s5p_tvout_mutex_unlock();
return;
}
s5p_hdcp_reset_auth();
+ s5p_tvout_mutex_unlock();
}
irqreturn_t s5p_hdcp_irq_handler(int irq, void *dev_id)
@@ -1121,3 +1130,8 @@ int s5p_hdcp_encrypt_stop(bool on)
return 0;
}
+
+void s5p_hdcp_flush_work(void)
+{
+ flush_workqueue(hdcp_wq);
+}
diff --git a/drivers/media/video/samsung/tvout/hw_if/hdmi.c b/drivers/media/video/samsung/tvout/hw_if/hdmi.c
index dfb3152..67099af 100644
--- a/drivers/media/video/samsung/tvout/hw_if/hdmi.c
+++ b/drivers/media/video/samsung/tvout/hw_if/hdmi.c
@@ -871,10 +871,10 @@ static void s5p_hdmi_print_phy_config(void)
printk(KERN_WARNING "read buffer :\n");
- for (i = 1; i < size; i++) {
+ for (i = 0; i < size; i++) {
printk("0x%02x", read_buffer[i]);
- if (i % 8)
+ if ((i+1) % 8)
printk(" ");
else
printk("\n");
@@ -1146,6 +1146,58 @@ void s5p_hdmi_reg_sw_reset(void)
s5p_hdmi_ctrl_clock(0);
}
+#ifdef CONFIG_HDMI_TX_STRENGTH
+int s5p_hdmi_phy_set_tx_strength(u8 ch, u8 *value)
+{
+ u8 buff[2];
+
+ if (ch & TX_EMP_LVL) { /* REG10 BIT7:4 */
+ buff[0] = HDMI_PHY_I2C_REG10;
+ buff[1] = (value[TX_EMP_LVL_VAL] & 0x0f) << 4;
+ if (s5p_hdmi_i2c_phy_write(PHY_I2C_ADDRESS, 2, buff) != 0)
+ goto err_exit;
+ }
+
+ if (ch & TX_AMP_LVL) { /* REG10 BIT3:0, REG0F BIT7 */
+ buff[0] = HDMI_PHY_I2C_REG10;
+ buff[1] = (value[TX_AMP_LVL_VAL] & 0x0e) >> 1;
+ if (s5p_hdmi_i2c_phy_write(PHY_I2C_ADDRESS, 2, buff) != 0)
+ goto err_exit;
+ buff[0] = HDMI_PHY_I2C_REG0F;
+ buff[1] = (value[TX_AMP_LVL_VAL] & 0x01) << 7;
+ if (s5p_hdmi_i2c_phy_write(PHY_I2C_ADDRESS, 2, buff) != 0)
+ goto err_exit;
+ }
+
+ if (ch & TX_LVL_CH0) { /* REG04 BIT7:6 */
+ buff[0] = HDMI_PHY_I2C_REG04;
+ buff[1] = (value[TX_LVL_CH0_VAL] & 0x3) << 6;
+ if (s5p_hdmi_i2c_phy_write(PHY_I2C_ADDRESS, 2, buff) != 0)
+ goto err_exit;
+ }
+
+ if (ch & TX_LVL_CH1) { /* REG13 BIT1:0 */
+ buff[0] = HDMI_PHY_I2C_REG13;
+ buff[1] = (value[TX_LVL_CH1_VAL] & 0x3);
+ if (s5p_hdmi_i2c_phy_write(PHY_I2C_ADDRESS, 2, buff) != 0)
+ goto err_exit;
+ }
+
+ if (ch & TX_LVL_CH2) { /* REG17 BIT1:0 */
+ buff[0] = HDMI_PHY_I2C_REG17;
+ buff[1] = (value[TX_LVL_CH2_VAL] & 0x3);
+ if (s5p_hdmi_i2c_phy_write(PHY_I2C_ADDRESS, 2, buff) != 0)
+ goto err_exit;
+ }
+
+ return 0;
+
+err_exit:
+ pr_err("%s: failed to set tx strength\n", __func__);
+ return -1;
+}
+#endif
+
int s5p_hdmi_phy_power(bool on)
{
u32 size;
diff --git a/drivers/media/video/samsung/tvout/hw_if/hw_if.h b/drivers/media/video/samsung/tvout/hw_if/hw_if.h
index 11bda99..e437b0a 100644
--- a/drivers/media/video/samsung/tvout/hw_if/hw_if.h
+++ b/drivers/media/video/samsung/tvout/hw_if/hw_if.h
@@ -364,6 +364,27 @@ struct s5p_hdmi_v_format {
u8 mhl_vsync;
};
+#ifdef CONFIG_HDMI_TX_STRENGTH
+#define HDMI_PHY_I2C_REG10 0x10
+#define HDMI_PHY_I2C_REG0F 0x0F
+#define HDMI_PHY_I2C_REG04 0x04
+#define HDMI_PHY_I2C_REG13 0x13
+#define HDMI_PHY_I2C_REG17 0x17
+
+#define TX_EMP_LVL 0x10
+#define TX_AMP_LVL 0x08
+#define TX_LVL_CH0 0x04
+#define TX_LVL_CH1 0x02
+#define TX_LVL_CH2 0x01
+
+#define TX_EMP_LVL_VAL 0
+#define TX_AMP_LVL_VAL 1
+#define TX_LVL_CH0_VAL 2
+#define TX_LVL_CH1_VAL 3
+#define TX_LVL_CH2_VAL 4
+
+extern int s5p_hdmi_phy_set_tx_strength(u8 ch, u8 *value);
+#endif
extern int s5p_hdmi_phy_power(bool on);
extern s32 s5p_hdmi_phy_config(
enum phy_freq freq, enum s5p_hdmi_color_depth cd);
@@ -750,6 +771,7 @@ extern int s5p_hdcp_encrypt_stop(bool on);
extern int __init s5p_hdcp_init(void);
extern int s5p_hdcp_start(void);
extern int s5p_hdcp_stop(void);
+extern void s5p_hdcp_flush_work(void);
/****************************************
* Definitions for sdo ctrl class
@@ -1000,6 +1022,10 @@ struct s5p_tvif_ctrl_private_data {
struct device *bus_dev; /* for BusFreq with Opp */
#endif
struct device *dev; /* hpd device pointer */
+#ifdef CONFIG_HDMI_TX_STRENGTH
+ u8 tx_ch;
+ u8 *tx_val;
+#endif
};
#endif /* _SAMSUNG_TVOUT_HW_IF_H_ */
diff --git a/drivers/media/video/samsung/tvout/s5p_mixer_ctrl.c b/drivers/media/video/samsung/tvout/s5p_mixer_ctrl.c
index a0169cb..5e78a3c 100644
--- a/drivers/media/video/samsung/tvout/s5p_mixer_ctrl.c
+++ b/drivers/media/video/samsung/tvout/s5p_mixer_ctrl.c
@@ -241,7 +241,7 @@ static void s5p_mixer_ctrl_clock(bool on)
clk_enable(s5p_mixer_ctrl_private.clk[ACLK].ptr);
- // Restore mixer_base address
+ /* Restore mixer_base address */
s5p_mixer_init(s5p_mixer_ctrl_private.reg_mem.base);
} else {
clk_disable(s5p_mixer_ctrl_private.clk[ACLK].ptr);
@@ -252,7 +252,7 @@ static void s5p_mixer_ctrl_clock(bool on)
clk_disable(s5p_mixer_ctrl_private.clk[MUX].ptr);
- // Set mixer_base address to NULL
+ /* Set mixer_base address to NULL */
s5p_mixer_init(NULL);
}
}
@@ -267,7 +267,7 @@ void s5p_mixer_ctrl_init_grp_layer(enum s5p_mixer_layer layer)
{
struct s5ptvfb_user_scaling scaling;
-#ifdef CONFIG_HAS_EARLYSUSPEND
+#ifdef CLOCK_GATING_ON_EARLY_SUSPEND
if (suspend_status) {
tvout_dbg("driver is suspend_status\n");
return;
@@ -278,12 +278,16 @@ void s5p_mixer_ctrl_init_grp_layer(enum s5p_mixer_layer layer)
s5p_mixer_set_priority(layer,
s5p_mixer_ctrl_private.layer[layer].priority);
s5p_mixer_set_pre_mul_mode(layer,
- s5p_mixer_ctrl_private.layer[layer].pre_mul_mode);
+ s5p_mixer_ctrl_private.layer[layer].
+ pre_mul_mode);
s5p_mixer_set_chroma_key(layer,
- s5p_mixer_ctrl_private.layer[layer].chroma_enable,
- s5p_mixer_ctrl_private.layer[layer].chroma_key);
+ s5p_mixer_ctrl_private.layer[layer].
+ chroma_enable,
+ s5p_mixer_ctrl_private.layer[layer].
+ chroma_key);
s5p_mixer_set_layer_blend(layer,
- s5p_mixer_ctrl_private.layer[layer].layer_blend);
+ s5p_mixer_ctrl_private.layer[layer].
+ layer_blend);
s5p_mixer_set_alpha(layer,
s5p_mixer_ctrl_private.layer[layer].alpha);
s5p_mixer_set_grp_layer_dst_pos(layer,
@@ -299,7 +303,8 @@ void s5p_mixer_ctrl_init_grp_layer(enum s5p_mixer_layer layer)
}
}
-int s5p_mixer_ctrl_set_pixel_format(enum s5p_mixer_layer layer, u32 bpp, u32 trans_len)
+int s5p_mixer_ctrl_set_pixel_format(
+ enum s5p_mixer_layer layer, u32 bpp, u32 trans_len)
{
enum s5p_mixer_color_fmt format;
@@ -322,7 +327,7 @@ int s5p_mixer_ctrl_set_pixel_format(enum s5p_mixer_layer layer, u32 bpp, u32 tra
s5p_mixer_ctrl_private.layer[layer].format = format;
-#ifdef CONFIG_HAS_EARLYSUSPEND
+#ifdef CLOCK_GATING_ON_EARLY_SUSPEND
if (suspend_status) {
tvout_dbg("driver is suspend_status\n");
return 0;
@@ -351,7 +356,7 @@ int s5p_mixer_ctrl_enable_layer(enum s5p_mixer_layer layer)
tvout_err("invalid layer\n");
return -1;
}
-#ifdef CONFIG_HAS_EARLYSUSPEND
+#ifdef CLOCK_GATING_ON_EARLY_SUSPEND
if (suspend_status) {
tvout_dbg("driver is suspend_status\n");
return 0;
@@ -384,7 +389,7 @@ int s5p_mixer_ctrl_disable_layer(enum s5p_mixer_layer layer)
return -1;
}
-#ifdef CONFIG_HAS_EARLYSUSPEND
+#ifdef CLOCK_GATING_ON_EARLY_SUSPEND
if (suspend_status) {
tvout_dbg("driver is suspend_status\n");
return 0;
@@ -523,7 +528,7 @@ int s5p_mixer_ctrl_set_dst_win_pos(enum s5p_mixer_layer layer,
s5p_mixer_ctrl_private.layer[layer].dst_x = (u32)dst_x;
s5p_mixer_ctrl_private.layer[layer].dst_y = (u32)dst_y;
-#ifdef CONFIG_HAS_EARLYSUSPEND
+#ifdef CLOCK_GATING_ON_EARLY_SUSPEND
if (suspend_status) {
tvout_dbg("driver is suspend_status\n");
return 0;
@@ -551,7 +556,7 @@ int s5p_mixer_ctrl_set_src_win_pos(enum s5p_mixer_layer layer,
s5p_mixer_ctrl_private.layer[layer].width = w;
s5p_mixer_ctrl_private.layer[layer].height = h;
-#ifdef CONFIG_HAS_EARLYSUSPEND
+#ifdef CLOCK_GATING_ON_EARLY_SUSPEND
if (suspend_status) {
tvout_dbg("driver is suspend_status\n");
return 0;
@@ -559,7 +564,8 @@ int s5p_mixer_ctrl_set_src_win_pos(enum s5p_mixer_layer layer,
#endif
{
if (s5p_mixer_ctrl_private.running)
- s5p_mixer_set_grp_layer_src_pos(layer, src_x, src_y, w, w, h);
+ s5p_mixer_set_grp_layer_src_pos(
+ layer, src_x, src_y, w, w, h);
}
return 0;
@@ -577,7 +583,7 @@ int s5p_mixer_ctrl_set_buffer_address(enum s5p_mixer_layer layer,
s5p_mixer_ctrl_private.layer[layer].fb_addr = start_addr;
-#ifdef CONFIG_HAS_EARLYSUSPEND
+#ifdef CLOCK_GATING_ON_EARLY_SUSPEND
if (suspend_status) {
tvout_dbg("driver is suspend_status\n");
return 0;
@@ -602,7 +608,7 @@ int s5p_mixer_ctrl_set_chroma_key(enum s5p_mixer_layer layer,
s5p_mixer_ctrl_private.layer[layer].chroma_enable = enabled;
s5p_mixer_ctrl_private.layer[layer].chroma_key = chroma.key;
-#ifdef CONFIG_HAS_EARLYSUSPEND
+#ifdef CLOCK_GATING_ON_EARLY_SUSPEND
if (suspend_status) {
tvout_dbg("driver is suspend_status\n");
return 0;
@@ -709,7 +715,7 @@ int s5p_mixer_ctrl_set_alpha_blending(enum s5p_mixer_layer layer,
case PIXEL_BLENDING:
tvout_dbg("pixel blending\n");
s5p_mixer_ctrl_private.layer[layer].pixel_blend = true;
-#ifdef CONFIG_HAS_EARLYSUSPEND
+#ifdef CLOCK_GATING_ON_EARLY_SUSPEND
if (suspend_status) {
tvout_dbg("driver is suspend_status\n");
return 0;
@@ -723,7 +729,7 @@ int s5p_mixer_ctrl_set_alpha_blending(enum s5p_mixer_layer layer,
tvout_dbg("layer blending : alpha value = 0x%x\n", alpha);
s5p_mixer_ctrl_private.layer[layer].layer_blend = true;
s5p_mixer_ctrl_private.layer[layer].alpha = alpha;
-#ifdef CONFIG_HAS_EARLYSUSPEND
+#ifdef CLOCK_GATING_ON_EARLY_SUSPEND
if (suspend_status) {
tvout_dbg("driver is suspend_status\n");
return 0;
@@ -739,7 +745,7 @@ int s5p_mixer_ctrl_set_alpha_blending(enum s5p_mixer_layer layer,
tvout_dbg("alpha blending off\n");
s5p_mixer_ctrl_private.layer[layer].pixel_blend = false;
s5p_mixer_ctrl_private.layer[layer].layer_blend = false;
-#ifdef CONFIG_HAS_EARLYSUSPEND
+#ifdef CLOCK_GATING_ON_EARLY_SUSPEND
if (suspend_status) {
tvout_dbg("driver is suspend_status\n");
return 0;
@@ -780,7 +786,7 @@ int s5p_mixer_ctrl_scaling(enum s5p_mixer_layer layer,
s5p_mixer_ctrl_private.layer[layer].ver = scaling.ver;
s5p_mixer_ctrl_private.layer[layer].hor = scaling.hor;
-#ifdef CONFIG_HAS_EARLYSUSPEND
+#ifdef CLOCK_GATING_ON_EARLY_SUSPEND
if (suspend_status) {
tvout_dbg("driver is suspend_status\n");
return 0;
@@ -796,7 +802,8 @@ int s5p_mixer_ctrl_mux_clk(struct clk *ptr)
{
if (clk_set_parent(s5p_mixer_ctrl_private.clk[MUX].ptr, ptr)) {
tvout_err("unable to set parent %s of clock %s.\n",
- ptr->name, s5p_mixer_ctrl_private.clk[MUX].ptr->name);
+ ptr->name,
+ s5p_mixer_ctrl_private.clk[MUX].ptr->name);
return -1;
}
@@ -828,6 +835,12 @@ bool s5p_mixer_ctrl_get_vsync_interrupt()
return s5p_mixer_ctrl_private.vsync_interrupt_enable;
}
+void s5p_mixer_ctrl_disable_vsync_interrupt()
+{
+ if (s5p_mixer_ctrl_private.running)
+ s5p_mixer_set_vsync_interrupt(false);
+}
+
void s5p_mixer_ctrl_clear_pend_all(void)
{
if (s5p_mixer_ctrl_private.running)
@@ -840,7 +853,7 @@ void s5p_mixer_ctrl_stop(void)
tvout_dbg("running(%d)\n", s5p_mixer_ctrl_private.running);
if (s5p_mixer_ctrl_private.running) {
-#ifdef CONFIG_HAS_EARLYSUSPEND
+#ifdef CLOCK_GATING_ON_EARLY_SUSPEND
if (suspend_status) {
tvout_dbg("driver is suspend_status\n");
} else
@@ -848,11 +861,12 @@ void s5p_mixer_ctrl_stop(void)
{
s5p_mixer_set_vsync_interrupt(false);
- for (i = 0; i < S5PTV_VP_BUFF_CNT -1; i++)
+ for (i = 0; i < S5PTV_VP_BUFF_CNT-1; i++)
s5ptv_vp_buff.copy_buff_idxs[i] = i;
s5ptv_vp_buff.curr_copy_idx = 0;
- s5ptv_vp_buff.vp_access_buff_idx = S5PTV_VP_BUFF_CNT - 1;
+ s5ptv_vp_buff.vp_access_buff_idx =
+ S5PTV_VP_BUFF_CNT - 1;
s5p_mixer_stop();
s5p_mixer_ctrl_clock(0);
@@ -1006,10 +1020,24 @@ int s5p_mixer_ctrl_start(
s5p_mixer_init_csc_coef_default(csc_for_coeff);
s5p_mixer_init_display_mode(disp, out, csc);
+#ifndef __CONFIG_HDMI_SUPPORT_FULL_RANGE__
if (!s5p_tvif_get_q_range() || out == TVOUT_HDMI_RGB)
mixer_video_limiter = true;
else
mixer_video_limiter = false;
+#else
+ /* full range */
+ if ((out == TVOUT_HDMI_RGB && disp == TVOUT_480P_60_4_3) ||
+ (out != TVOUT_HDMI_RGB && s5p_tvif_get_q_range())) {
+ mixer_video_limiter = false;
+ for (i = MIXER_BG_COLOR_0; i <= MIXER_BG_COLOR_2; i++)
+ s5p_mixer_ctrl_private.bg_color[i].color_y = 0;
+ } else { /* limited range */
+ mixer_video_limiter = true;
+ for (i = MIXER_BG_COLOR_0; i <= MIXER_BG_COLOR_2; i++)
+ s5p_mixer_ctrl_private.bg_color[i].color_y = 16;
+ }
+#endif
s5p_mixer_set_video_limiter(s5p_mixer_ctrl_private.v_layer.y_min,
s5p_mixer_ctrl_private.v_layer.y_max,
diff --git a/drivers/media/video/samsung/tvout/s5p_tvif_ctrl.c b/drivers/media/video/samsung/tvout/s5p_tvif_ctrl.c
index 93cb640..43e7a1f 100644
--- a/drivers/media/video/samsung/tvout/s5p_tvif_ctrl.c
+++ b/drivers/media/video/samsung/tvout/s5p_tvif_ctrl.c
@@ -49,6 +49,12 @@
#if defined(CONFIG_BUSFREQ_OPP) || defined(CONFIG_BUSFREQ_LOCK_WRAPPER)
#include <mach/dev.h>
#endif
+#include <mach/regs-hdmi.h>
+
+#ifdef CONFIG_HDMI_TX_STRENGTH
+#include <plat/tvout.h>
+#endif
+
#include "s5p_tvout_common_lib.h"
#include "hw_if/hw_if.h"
@@ -1758,7 +1764,7 @@ static void s5p_sdo_ctrl_clock(bool on)
#ifdef CONFIG_ARCH_EXYNOS4
s5p_tvout_pm_runtime_get();
#endif
- // Restore sdo_base address
+ /* Restore sdo_base address */
s5p_sdo_init(s5p_sdo_ctrl_private.reg_mem.base);
clk_enable(s5p_sdo_ctrl_private.clk[SDO_PCLK].ptr);
@@ -1771,7 +1777,7 @@ static void s5p_sdo_ctrl_clock(bool on)
clk_disable(s5p_sdo_ctrl_private.clk[SDO_MUX].ptr);
- // Set sdo_base address to NULL
+ /* Set sdo_base address to NULL */
s5p_sdo_init(NULL);
}
@@ -2362,8 +2368,10 @@ static void s5p_hdmi_ctrl_internal_stop(void)
#ifdef CONFIG_HDMI_HPD
s5p_hpd_set_eint();
#endif
- if (ctrl->hdcp_en)
+ if (ctrl->hdcp_en) {
s5p_hdcp_stop();
+ s5p_hdcp_flush_work();
+ }
s5p_hdmi_reg_enable(false);
@@ -2376,10 +2384,16 @@ int s5p_hdmi_ctrl_phy_power(bool on)
if (on) {
/* on */
clk_enable(s5ptv_status.i2c_phy_clk);
- // Restore i2c_hdmi_phy_base address
+ /* Restore i2c_hdmi_phy_base address */
s5p_hdmi_phy_init(s5p_hdmi_ctrl_private.reg_mem[HDMI_PHY].base);
s5p_hdmi_phy_power(true);
+#ifdef CONFIG_HDMI_TX_STRENGTH
+ if (s5p_tvif_ctrl_private.tx_val)
+ s5p_hdmi_phy_set_tx_strength(
+ s5p_tvif_ctrl_private.tx_ch,
+ s5p_tvif_ctrl_private.tx_val);
+#endif
} else {
/*
@@ -2398,7 +2412,7 @@ int s5p_hdmi_ctrl_phy_power(bool on)
s5p_hdmi_phy_power(false);
clk_disable(s5ptv_status.i2c_phy_clk);
- // Set i2c_hdmi_phy_base to NULL
+ /* Set i2c_hdmi_phy_base to NULL */
s5p_hdmi_phy_init(NULL);
}
@@ -2419,7 +2433,7 @@ void s5p_hdmi_ctrl_clock(bool on)
#endif
clk_enable(clk[HDMI_PCLK].ptr);
- // Restore hdmi_base address
+ /* Restore hdmi_base address */
s5p_hdmi_init(s5p_hdmi_ctrl_private.reg_mem[HDMI].base);
} else {
clk_disable(clk[HDMI_PCLK].ptr);
@@ -2430,7 +2444,7 @@ void s5p_hdmi_ctrl_clock(bool on)
clk_disable(clk[HDMI_MUX].ptr);
- // Set hdmi_base to NULL
+ /* Set hdmi_base to NULL */
s5p_hdmi_init(NULL);
}
}
@@ -2447,7 +2461,7 @@ void s5p_hdmi_ctrl_stop(void)
tvout_dbg("running(%d)\n", ctrl->running);
if (ctrl->running) {
ctrl->running = false;
-#ifdef CONFIG_HAS_EARLYSUSPEND
+#ifdef CLOCK_GATING_ON_EARLY_SUSPEND
if (suspend_status) {
tvout_dbg("driver is suspend_status\n");
} else
@@ -2681,7 +2695,7 @@ static int s5p_tvif_ctrl_internal_stop(void)
case TVOUT_HDMI:
case TVOUT_HDMI_RGB:
s5p_hdmi_ctrl_stop();
-#ifdef CONFIG_HAS_EARLYSUSPEND
+#ifdef CLOCK_GATING_ON_EARLY_SUSPEND
if (suspend_status) {
tvout_dbg("driver is suspend_status\n");
} else
@@ -2705,6 +2719,10 @@ static void s5p_tvif_ctrl_internal_start(
enum s5p_tvout_o_mode inf)
{
tvout_dbg("\n");
+#ifdef __CONFIG_HDMI_SUPPORT_FULL_RANGE__
+ s5p_hdmi_output[inf].reg.pxl_limit =
+ S5P_HDMI_PX_LMT_CTRL_BYPASS;
+#endif
s5p_mixer_ctrl_set_int_enable(false);
/* Clear All Interrupt Pending */
@@ -2724,6 +2742,47 @@ static void s5p_tvif_ctrl_internal_start(
case TVOUT_HDMI:
case TVOUT_HDMI_RGB:
case TVOUT_DVI:
+#ifdef __CONFIG_HDMI_SUPPORT_FULL_RANGE__
+ switch (std) {
+ case TVOUT_480P_60_4_3:
+ if (inf == TVOUT_HDMI_RGB) /* full range */
+ s5p_hdmi_output[inf].reg.pxl_limit =
+ S5P_HDMI_PX_LMT_CTRL_BYPASS;
+ else if (s5p_tvif_get_q_range()) /* full range */
+ s5p_hdmi_output[inf].reg.pxl_limit =
+ S5P_HDMI_PX_LMT_CTRL_BYPASS;
+ else /* limited range */
+ s5p_hdmi_output[inf].reg.pxl_limit =
+ S5P_HDMI_PX_LMT_CTRL_YPBPR;
+ break;
+ case TVOUT_480P_60_16_9:
+ case TVOUT_480P_59:
+ case TVOUT_576P_50_16_9:
+ case TVOUT_576P_50_4_3:
+ case TVOUT_720P_60:
+ case TVOUT_720P_50:
+ case TVOUT_720P_59:
+ case TVOUT_1080I_60:
+ case TVOUT_1080I_59:
+ case TVOUT_1080I_50:
+ case TVOUT_1080P_60:
+ case TVOUT_1080P_30:
+ case TVOUT_1080P_59:
+ case TVOUT_1080P_50:
+ if (inf == TVOUT_HDMI_RGB) /* limited range */
+ s5p_hdmi_output[inf].reg.pxl_limit =
+ S5P_HDMI_PX_LMT_CTRL_RGB;
+ else if (s5p_tvif_get_q_range()) /* full range */
+ s5p_hdmi_output[inf].reg.pxl_limit =
+ S5P_HDMI_PX_LMT_CTRL_BYPASS;
+ else /* limited range */
+ s5p_hdmi_output[inf].reg.pxl_limit =
+ S5P_HDMI_PX_LMT_CTRL_YPBPR;
+ break;
+ default:
+ break;
+ }
+#endif
s5p_hdmi_ctrl_phy_power(1);
if (s5p_mixer_ctrl_start(std, inf) < 0)
@@ -2854,7 +2913,7 @@ int s5p_tvif_ctrl_start(
goto cannot_change;
}
-#ifdef CONFIG_HAS_EARLYSUSPEND
+#ifdef CLOCK_GATING_ON_EARLY_SUSPEND
if (suspend_status) {
tvout_dbg("driver is suspend_status\n");
} else
@@ -2889,6 +2948,16 @@ void s5p_tvif_ctrl_stop(void)
int s5p_tvif_ctrl_constructor(struct platform_device *pdev)
{
+#ifdef CONFIG_HDMI_TX_STRENGTH
+ struct s5p_platform_tvout *pdata = to_tvout_plat(&pdev->dev);
+ s5p_tvif_ctrl_private.tx_ch = 0x00;
+ s5p_tvif_ctrl_private.tx_val = NULL;
+ if ((pdata) && (pdata->tx_tune)) {
+ s5p_tvif_ctrl_private.tx_ch = pdata->tx_tune->tx_ch;
+ s5p_tvif_ctrl_private.tx_val = pdata->tx_tune->tx_val;
+ }
+#endif
+
#ifdef CONFIG_ANALOG_TVENC
if (s5p_sdo_ctrl_constructor(pdev))
goto err;
diff --git a/drivers/media/video/samsung/tvout/s5p_tvout.c b/drivers/media/video/samsung/tvout/s5p_tvout.c
index 7407670..5f00ebc 100644
--- a/drivers/media/video/samsung/tvout/s5p_tvout.c
+++ b/drivers/media/video/samsung/tvout/s5p_tvout.c
@@ -13,6 +13,7 @@
#include <linux/clk.h>
#include <linux/io.h>
#include <linux/mm.h>
+#include <linux/delay.h>
#if defined(CONFIG_S5P_SYSMMU_TV)
#include <plat/sysmmu.h>
@@ -25,6 +26,10 @@
#include <mach/media.h>
#endif
+#if defined(CONFIG_HDMI_TX_STRENGTH) && !defined(CONFIG_USER_ALLOC_TVOUT)
+#include <plat/tvout.h>
+#endif
+
#include "s5p_tvout_common_lib.h"
#include "s5p_tvout_ctrl.h"
#include "s5p_tvout_fb.h"
@@ -291,6 +296,12 @@ static int __devinit s5p_tvout_probe(struct platform_device *pdev)
struct device *hdmi_audio_dev;
#endif
+#if defined(CONFIG_HDMI_TX_STRENGTH) && !defined(CONFIG_USER_ALLOC_TVOUT)
+ struct s5p_platform_tvout *pdata;
+ u8 tx_ch;
+ u8 *tx_val;
+#endif
+
#ifdef CONFIG_TVOUT_DEBUG
struct class *sec_tvout;
tvout_dbg_flag = 1 << DBG_FLAG_HPD;
@@ -339,6 +350,15 @@ static int __devinit s5p_tvout_probe(struct platform_device *pdev)
s5p_hdmi_phy_power(true);
if (s5p_tvif_ctrl_start(TVOUT_720P_60, TVOUT_HDMI) < 0)
goto err_tvif_start;
+#ifdef CONFIG_HDMI_TX_STRENGTH
+ pdata = to_tvout_plat(&pdev->dev);
+ if (pdata && pdata->tx_tune) {
+ tx_ch = pdata->tx_tune->tx_ch;
+ tx_val = pdata->tx_tune->tx_val;
+ }
+ if (tx_ch && tx_val)
+ s5p_hdmi_phy_set_tx_strength(tx_ch, tx_val);
+#endif
#endif
/* prepare memory */
@@ -495,14 +515,19 @@ static int s5p_tvout_remove(struct platform_device *pdev)
static void s5p_tvout_early_suspend(struct early_suspend *h)
{
tvout_dbg("\n");
+#ifdef CLOCK_GATING_ON_EARLY_SUSPEND
mutex_lock(&s5p_tvout_mutex);
- s5p_mixer_ctrl_set_vsync_interrupt(false);
+ /* disable vsync interrupt during early suspend */
+ s5p_mixer_ctrl_disable_vsync_interrupt();
s5p_vp_ctrl_suspend();
s5p_mixer_ctrl_suspend();
s5p_tvif_ctrl_suspend();
suspend_status = 1;
tvout_dbg("suspend_status is true\n");
mutex_unlock(&s5p_tvout_mutex);
+#else
+ suspend_status = 1;
+#endif
return;
}
@@ -511,6 +536,7 @@ static void s5p_tvout_late_resume(struct early_suspend *h)
{
tvout_dbg("\n");
+#ifdef CLOCK_GATING_ON_EARLY_SUSPEND
mutex_lock(&s5p_tvout_mutex);
#if defined(CONFIG_CPU_EXYNOS4212) || defined(CONFIG_CPU_EXYNOS4412)
@@ -521,11 +547,17 @@ static void s5p_tvout_late_resume(struct early_suspend *h)
#endif
suspend_status = 0;
tvout_dbg("suspend_status is false\n");
+
s5p_tvif_ctrl_resume();
s5p_mixer_ctrl_resume();
s5p_vp_ctrl_resume();
- s5p_mixer_ctrl_set_vsync_interrupt(s5p_mixer_ctrl_get_vsync_interrupt());
+ /* restore vsync interrupt setting */
+ s5p_mixer_ctrl_set_vsync_interrupt(
+ s5p_mixer_ctrl_get_vsync_interrupt());
mutex_unlock(&s5p_tvout_mutex);
+#else
+ suspend_status = 0;
+#endif
return;
}
@@ -562,8 +594,10 @@ static int s5p_tvout_suspend(struct device *dev)
static int s5p_tvout_resume(struct device *dev)
{
tvout_dbg("\n");
+#if defined(CLOCK_GATING_ON_EARLY_SUSPEND)
#if defined(CONFIG_CPU_EXYNOS4212) || defined(CONFIG_CPU_EXYNOS4412)
flag_after_resume = true;
+#endif
#else
queue_work_on(0, tvout_resume_wq, &tvout_resume_work);
#endif
diff --git a/drivers/media/video/samsung/tvout/s5p_tvout_common_lib.h b/drivers/media/video/samsung/tvout/s5p_tvout_common_lib.h
index e43b9c7..467ab1d 100644
--- a/drivers/media/video/samsung/tvout/s5p_tvout_common_lib.h
+++ b/drivers/media/video/samsung/tvout/s5p_tvout_common_lib.h
@@ -45,6 +45,12 @@ do { \
#endif
#endif
+/*
+#if defined(CONFIG_MACH_T0) || defined(CONFIG_MACH_M3)
+#define __CONFIG_HDMI_SUPPORT_FULL_RANGE__
+#endif
+*/
+
#define S5PTV_FB_CNT 2
#define S5PTV_VP_BUFF_CNT 4
#define S5PTV_VP_BUFF_SIZE (4*1024*1024)
@@ -53,6 +59,10 @@ do { \
#define HDMI_START_NUM 0x1000
+#ifdef CONFIG_CPU_EXYNOS4210
+#define CLOCK_GATING_ON_EARLY_SUSPEND
+#endif
+
enum s5p_tvout_disp_mode {
TVOUT_NTSC_M = 0,
TVOUT_PAL_BDGHI,
diff --git a/drivers/media/video/samsung/tvout/s5p_tvout_ctrl.h b/drivers/media/video/samsung/tvout/s5p_tvout_ctrl.h
index 43043b4..b330a95 100644
--- a/drivers/media/video/samsung/tvout/s5p_tvout_ctrl.h
+++ b/drivers/media/video/samsung/tvout/s5p_tvout_ctrl.h
@@ -29,7 +29,8 @@
extern void s5p_mixer_ctrl_init_fb_addr_phy(enum s5p_mixer_layer layer,
dma_addr_t fb_addr);
extern void s5p_mixer_ctrl_init_grp_layer(enum s5p_mixer_layer layer);
-extern int s5p_mixer_ctrl_set_pixel_format(enum s5p_mixer_layer layer, u32 bpp, u32 trans_len);
+extern int s5p_mixer_ctrl_set_pixel_format(
+ enum s5p_mixer_layer layer, u32 bpp, u32 trans_len);
extern int s5p_mixer_ctrl_enable_layer(enum s5p_mixer_layer layer);
extern int s5p_mixer_ctrl_disable_layer(enum s5p_mixer_layer layer);
extern int s5p_mixer_ctrl_set_priority(enum s5p_mixer_layer layer, u32 prio);
@@ -52,6 +53,7 @@ extern int s5p_mixer_ctrl_mux_clk(struct clk *ptr);
extern void s5p_mixer_ctrl_set_int_enable(bool en);
extern void s5p_mixer_ctrl_set_vsync_interrupt(bool en);
extern bool s5p_mixer_ctrl_get_vsync_interrupt(void);
+extern void s5p_mixer_ctrl_disable_vsync_interrupt(void);
extern void s5p_mixer_ctrl_clear_pend_all(void);
extern void s5p_mixer_ctrl_stop(void);
extern void s5p_mixer_ctrl_internal_start(void);
diff --git a/drivers/media/video/samsung/tvout/s5p_tvout_fb.c b/drivers/media/video/samsung/tvout/s5p_tvout_fb.c
index 5a2ce5a..c0a3508 100644
--- a/drivers/media/video/samsung/tvout/s5p_tvout_fb.c
+++ b/drivers/media/video/samsung/tvout/s5p_tvout_fb.c
@@ -303,7 +303,7 @@ static int s5p_tvout_fb_blank(int blank_mode, struct fb_info *fb)
tvout_dbg("change blank mode\n");
-#ifdef CONFIG_HAS_EARLYSUSPEND
+#if defined(CONFIG_HAS_EARLYSUSPEND) && defined(CLOCK_GATING_ON_EARLY_SUSPEND)
s5p_tvout_mutex_lock();
#endif
switch (fb->node) {
@@ -336,12 +336,12 @@ static int s5p_tvout_fb_blank(int blank_mode, struct fb_info *fb)
goto err_fb_blank;
}
-#ifdef CONFIG_HAS_EARLYSUSPEND
+#if defined(CONFIG_HAS_EARLYSUSPEND) && defined(CLOCK_GATING_ON_EARLY_SUSPEND)
s5p_tvout_mutex_unlock();
#endif
return 1;
err_fb_blank:
-#ifdef CONFIG_HAS_EARLYSUSPEND
+#if defined(CONFIG_HAS_EARLYSUSPEND) && defined(CLOCK_GATING_ON_EARLY_SUSPEND)
s5p_tvout_mutex_unlock();
#endif
return -1;
@@ -356,7 +356,7 @@ static int s5p_tvout_fb_set_par(struct fb_info *fb)
tvout_dbg("[fb%d] set_par\n", win->id);
-#ifdef CONFIG_HAS_EARLYSUSPEND
+#if defined(CONFIG_HAS_EARLYSUSPEND) && defined(CLOCK_GATING_ON_EARLY_SUSPEND)
s5p_tvout_mutex_lock();
#endif
if (!fb->fix.smem_start) {
@@ -390,7 +390,7 @@ static int s5p_tvout_fb_set_par(struct fb_info *fb)
s5p_mixer_ctrl_set_src_win_pos(layer, src_x, src_y, w, h);
s5p_mixer_ctrl_set_alpha_blending(layer, win->alpha.mode,
win->alpha.value);
-#ifdef CONFIG_HAS_EARLYSUSPEND
+#if defined(CONFIG_HAS_EARLYSUSPEND) && defined(CLOCK_GATING_ON_EARLY_SUSPEND)
s5p_tvout_mutex_unlock();
#endif
return 0;
@@ -472,7 +472,7 @@ static int s5p_tvout_fb_ioctl(struct fb_info *fb, unsigned int cmd,
} p;
tvout_dbg("\n");
-#ifdef CONFIG_HAS_EARLYSUSPEND
+#if defined(CONFIG_HAS_EARLYSUSPEND) && defined(CLOCK_GATING_ON_EARLY_SUSPEND)
s5p_tvout_mutex_lock();
#endif
switch (fb->node) {
@@ -552,13 +552,13 @@ static int s5p_tvout_fb_ioctl(struct fb_info *fb, unsigned int cmd,
s5p_mixer_ctrl_scaling(layer, p.user_scaling);
break;
}
-#ifdef CONFIG_HAS_EARLYSUSPEND
+#if defined(CONFIG_HAS_EARLYSUSPEND) && defined(CLOCK_GATING_ON_EARLY_SUSPEND)
s5p_tvout_mutex_unlock();
#endif
return 0;
err_fb_ioctl:
-#ifdef CONFIG_HAS_EARLYSUSPEND
+#if defined(CONFIG_HAS_EARLYSUSPEND) && defined(CLOCK_GATING_ON_EARLY_SUSPEND)
s5p_tvout_mutex_unlock();
#endif
return -1;
diff --git a/drivers/media/video/samsung/tvout/s5p_tvout_hpd.c b/drivers/media/video/samsung/tvout/s5p_tvout_hpd.c
index 4f35a91..1c98453 100644
--- a/drivers/media/video/samsung/tvout/s5p_tvout_hpd.c
+++ b/drivers/media/video/samsung/tvout/s5p_tvout_hpd.c
@@ -67,6 +67,12 @@ struct hpd_struct {
#endif
};
+#ifdef CONFIG_HDMI_CONTROLLED_BY_EXT_IC
+static work_func_t ext_ic_control_func(void) ;
+static DECLARE_DELAYED_WORK(ext_ic_control_dwork,
+ (work_func_t)ext_ic_control_func);
+#endif
+
static struct hpd_struct hpd_struct;
static int last_hpd_state;
@@ -81,6 +87,10 @@ static ssize_t s5p_hpd_read(struct file *file, char __user *buffer,
static unsigned int s5p_hpd_poll(struct file *file, poll_table *wait);
static long s5p_hpd_ioctl(struct file *file,
unsigned int cmd, unsigned long arg);
+#ifdef CONFIG_SAMSUNG_WORKAROUND_HPD_GLANCE
+void mhl_hpd_handler(bool onoff);
+bool (*is_mhl_power_state_on)(void);
+#endif
static const struct file_operations hpd_fops = {
.owner = THIS_MODULE,
@@ -139,6 +149,7 @@ static void s5p_hpd_kobject_uevent(void)
if (hpd_state) {
if (last_uevent_state == -1 || last_uevent_state == HPD_LO) {
#ifdef CONFIG_HDMI_CONTROLLED_BY_EXT_IC
+ HPDPRINTK("ext_ic power ON\n");
hpd_struct.ext_ic_control(true);
msleep(20);
#endif
@@ -154,9 +165,13 @@ static void s5p_hpd_kobject_uevent(void)
KOBJ_CHANGE, envp);
#endif
HPDPRINTK("[HDMI] HPD event -connect!!!\n");
- on_start_process = true;
+ if (atomic_read(&hdmi_status) == HDMI_OFF) {
+ on_start_process = true;
+ } else {
+ on_start_process = false;
+ }
HPDIFPRINTK("%s() on_start_process(%d)\n",
- __func__, on_start_process);
+ __func__, on_start_process);
}
last_uevent_state = HPD_HI;
} else {
@@ -176,10 +191,14 @@ static void s5p_hpd_kobject_uevent(void)
KOBJ_CHANGE, envp);
#endif
HPDPRINTK("[HDMI] HPD event -disconnet!!!\n");
- on_stop_process = true;
-#ifdef CONFIG_HDMI_CONTROLLED_BY_EXT_IC
- hpd_struct.ext_ic_control(false);
-#endif
+ if (atomic_read(&hdmi_status) == HDMI_ON) {
+ on_stop_process = true;
+ } else {
+ on_stop_process = false;
+ }
+ HPDIFPRINTK("%s() on_stop_process(%d)\n",
+ __func__, on_stop_process);
+
}
last_uevent_state = HPD_LO;
}
@@ -233,9 +252,16 @@ static unsigned int s5p_hpd_poll(struct file *file, poll_table * wait)
void hdmi_send_audio_ch_num(
int supported_ch_num, struct switch_dev *p_audio_ch_switch)
{
- printk(KERN_INFO "%s() hdmi_send_audio_ch_num :: "
- "HDMI Audio supported ch = %d",
- __func__, supported_ch_num);
+ if (last_uevent_state == HPD_LO) {
+ printk(KERN_INFO "[WARNING] %s() "
+ "HDMI Audio ch = %d but not send\n",
+ __func__, supported_ch_num);
+ return;
+ } else
+ printk(KERN_INFO "%s() "
+ "HDMI Audio ch = %d\n",
+ __func__, supported_ch_num);
+
p_audio_ch_switch->state = 0;
switch_set_state(p_audio_ch_switch, (int)supported_ch_num);
}
@@ -366,7 +392,16 @@ static int s5p_hpd_irq_eint(int irq)
atomic_set(&poll_state, 1);
last_hpd_state = HPD_LO;
+#ifdef CONFIG_SAMSUNG_WORKAROUND_HPD_GLANCE
+ if (is_mhl_power_state_on != NULL)
+ if (!is_mhl_power_state_on())
+ mhl_hpd_handler(false);
+#endif
+#ifdef CONFIG_HDMI_CONTROLLED_BY_EXT_IC
+ schedule_delayed_work(&ext_ic_control_dwork ,
+ msecs_to_jiffies(1000));
+#endif
wake_up_interruptible(&hpd_struct.waitq);
}
schedule_work(&hpd_work);
@@ -438,6 +473,15 @@ static int s5p_hpd_irq_hdmi(int irq)
atomic_set(&poll_state, 1);
last_hpd_state = HPD_LO;
+#ifdef CONFIG_SAMSUNG_WORKAROUND_HPD_GLANCE
+ if (is_mhl_power_state_on != NULL)
+ if (!is_mhl_power_state_on())
+ mhl_hpd_handler(false);
+#endif
+#ifdef CONFIG_HDMI_CONTROLLED_BY_EXT_IC
+ schedule_delayed_work(&ext_ic_control_dwork ,
+ msecs_to_jiffies(1000));
+#endif
wake_up_interruptible(&hpd_struct.waitq);
}
@@ -474,6 +518,20 @@ static irqreturn_t s5p_hpd_irq_handler(int irq, void *dev_id)
return ret;
}
+#ifdef CONFIG_HDMI_CONTROLLED_BY_EXT_IC
+static work_func_t ext_ic_control_func(void)
+{
+ if (!hpd_struct.read_gpio()) {
+ hpd_struct.ext_ic_control(false);
+ HPDPRINTK("HDMI_EXT_IC Power Off\n");
+ } else {
+ HPDPRINTK("HDMI_EXT_IC Delay work do nothing\n");
+ }
+ return 0;
+}
+#endif
+
+
#ifdef CONFIG_SAMSUNG_WORKAROUND_HPD_GLANCE
static irqreturn_t s5p_hpd_irq_default_handler(int irq, void *dev_id)
{
@@ -566,6 +624,9 @@ static int __devinit s5p_hpd_probe(struct platform_device *pdev)
if (hpd_struct.read_gpio()) {
atomic_set(&hpd_struct.state, HPD_HI);
last_hpd_state = HPD_HI;
+#ifdef CONFIG_HDMI_CONTROLLED_BY_EXT_IC
+ hpd_struct.ext_ic_control(true);
+#endif
} else {
atomic_set(&hpd_struct.state, HPD_LO);
last_hpd_state = HPD_LO;
@@ -575,6 +636,7 @@ static int __devinit s5p_hpd_probe(struct platform_device *pdev)
hpd_struct.hpd_switch.name = "hdmi";
switch_dev_register(&hpd_struct.hpd_switch);
#endif
+ switch_set_state(&hpd_struct.hpd_switch, last_hpd_state);
irq_set_irq_type(hpd_struct.irq_n, IRQ_TYPE_EDGE_BOTH);
ret = request_irq(hpd_struct.irq_n, (irq_handler_t) s5p_hpd_irq_handler,
diff --git a/drivers/media/video/samsung/tvout/s5p_tvout_v4l2.c b/drivers/media/video/samsung/tvout/s5p_tvout_v4l2.c
index 68508e7..3fa6e55 100644
--- a/drivers/media/video/samsung/tvout/s5p_tvout_v4l2.c
+++ b/drivers/media/video/samsung/tvout/s5p_tvout_v4l2.c
@@ -369,7 +369,7 @@ static int s5p_tvout_tvif_s_std(
int i;
v4l2_std_id std_id = *norm;
-#ifdef CONFIG_HAS_EARLYSUSPEND
+#if defined(CONFIG_HAS_EARLYSUSPEND) && defined(CLOCK_GATING_ON_EARLY_SUSPEND)
s5p_tvout_mutex_lock();
#endif
for (i = 0; i < S5P_TVOUT_TVIF_NO_OF_STANDARD; i++) {
@@ -379,7 +379,8 @@ static int s5p_tvout_tvif_s_std(
if (i == S5P_TVOUT_TVIF_NO_OF_STANDARD) {
tvout_err("There is no TV standard(0x%08Lx)\n", std_id);
-#ifdef CONFIG_HAS_EARLYSUSPEND
+
+#if defined(CONFIG_HAS_EARLYSUSPEND) && defined(CLOCK_GATING_ON_EARLY_SUSPEND)
s5p_tvout_mutex_unlock();
#endif
return -EINVAL;
@@ -390,7 +391,7 @@ static int s5p_tvout_tvif_s_std(
tvout_dbg("standard id=0x%X, name=\"%s\"\n",
(u32) std_id, s5p_tvout_tvif_standard[i].name);
-#ifdef CONFIG_HAS_EARLYSUSPEND
+#if defined(CONFIG_HAS_EARLYSUSPEND) && defined(CLOCK_GATING_ON_EARLY_SUSPEND)
s5p_tvout_mutex_unlock();
#endif
@@ -437,7 +438,7 @@ static int s5p_tvout_tvif_s_output(
return -EINVAL;
}
-#ifdef CONFIG_HAS_EARLYSUSPEND
+#if defined(CONFIG_HAS_EARLYSUSPEND)
s5p_tvout_mutex_lock();
#endif
on_start_process = true;
@@ -582,12 +583,12 @@ static int s5p_tvout_tvif_s_output(
s5p_tvif_ctrl_start(tv_std, tv_if);
-#ifdef CONFIG_HAS_EARLYSUSPEND
+#if defined(CONFIG_HAS_EARLYSUSPEND)
s5p_tvout_mutex_unlock();
#endif
return 0;
error_on_tvif_s_output:
-#ifdef CONFIG_HAS_EARLYSUSPEND
+#if defined(CONFIG_HAS_EARLYSUSPEND)
s5p_tvout_mutex_unlock();
#endif
return -1;
@@ -749,7 +750,7 @@ long s5p_tvout_tvif_ioctl(
void *argp = (void *) arg;
int i = 0;
-#ifdef CONFIG_HAS_EARLYSUSPEND
+#if defined(CONFIG_HAS_EARLYSUSPEND) && defined(CLOCK_GATING_ON_EARLY_SUSPEND)
s5p_tvout_mutex_lock();
#endif
@@ -916,13 +917,13 @@ long s5p_tvout_tvif_ioctl(
break;
}
-#ifdef CONFIG_HAS_EARLYSUSPEND
+#if defined(CONFIG_HAS_EARLYSUSPEND) && defined(CLOCK_GATING_ON_EARLY_SUSPEND)
s5p_tvout_mutex_unlock();
#endif
return video_ioctl2(file, cmd, arg);
end_tvif_ioctl:
-#ifdef CONFIG_HAS_EARLYSUSPEND
+#if defined(CONFIG_HAS_EARLYSUSPEND) && defined(CLOCK_GATING_ON_EARLY_SUSPEND)
s5p_tvout_mutex_unlock();
#endif
return ret;
@@ -1035,7 +1036,7 @@ static int s5p_tvout_vo_s_fmt_type_private(
(u32) vparam.base_y, (u32) vparam.base_c,
pix_fmt->field);
-#ifdef CONFIG_HAS_EARLYSUSPEND
+#if defined(CONFIG_HAS_EARLYSUSPEND) && defined(CLOCK_GATING_ON_EARLY_SUSPEND)
s5p_tvout_mutex_lock();
#endif
/* check progressive or not */
@@ -1133,52 +1134,72 @@ static int s5p_tvout_vo_s_fmt_type_private(
pix_fmt->height, color, field);
#else
if (pix_fmt->priv) {
- copy_buff_idx = s5ptv_vp_buff.copy_buff_idxs[s5ptv_vp_buff.curr_copy_idx];
-
- if ((void *)s5ptv_vp_buff.vp_buffs[copy_buff_idx].vir_base == NULL) {
- s5p_vp_ctrl_set_src_plane((u32) vparam.base_y, (u32) vparam.base_c,
- pix_fmt->width, pix_fmt->height, color, field);
+ copy_buff_idx =
+ s5ptv_vp_buff.
+ copy_buff_idxs[s5ptv_vp_buff.curr_copy_idx];
+
+ if ((void *)s5ptv_vp_buff.vp_buffs[copy_buff_idx].vir_base
+ == NULL) {
+ s5p_vp_ctrl_set_src_plane(
+ (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);
+ 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);
+ 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((unsigned long)vparam.base_c);
+ src_vir_y_addr = (unsigned int)phys_to_virt(
+ (unsigned long)vparam.base_y);
+ src_vir_cb_addr = (unsigned int)phys_to_virt(
+ (unsigned long)vparam.base_c);
- memcpy((void *)s5ptv_vp_buff.vp_buffs[copy_buff_idx].vir_base,
- (void *)src_vir_y_addr, y_size);
- memcpy((void *)s5ptv_vp_buff.vp_buffs[copy_buff_idx].vir_base + y_size,
- (void *)src_vir_cb_addr, cbcr_size);
+ memcpy(
+ (void *)
+ s5ptv_vp_buff.vp_buffs[copy_buff_idx].vir_base,
+ (void *)src_vir_y_addr, y_size);
+ memcpy(
+ (void *)s5ptv_vp_buff.vp_buffs[copy_buff_idx].
+ vir_base + y_size,
+ (void *)src_vir_cb_addr, cbcr_size);
flush_all_cpu_caches();
outer_flush_all();
- s5p_vp_ctrl_set_src_plane((u32) s5ptv_vp_buff.vp_buffs[copy_buff_idx].phy_base,
- (u32) s5ptv_vp_buff.vp_buffs[copy_buff_idx].phy_base + y_size,
- pix_fmt->width, pix_fmt->height, color, field);
+ s5p_vp_ctrl_set_src_plane(
+ (u32) s5ptv_vp_buff.
+ vp_buffs[copy_buff_idx].phy_base,
+ (u32) s5ptv_vp_buff.
+ vp_buffs[copy_buff_idx].phy_base
+ + y_size,
+ pix_fmt->width, pix_fmt->height, color, field);
s5ptv_vp_buff.curr_copy_idx++;
- if (s5ptv_vp_buff.curr_copy_idx >= S5PTV_VP_BUFF_CNT - 1)
+ if (s5ptv_vp_buff.curr_copy_idx >=
+ S5PTV_VP_BUFF_CNT - 1)
s5ptv_vp_buff.curr_copy_idx = 0;
}
} else {
- s5p_vp_ctrl_set_src_plane((u32) vparam.base_y, (u32) vparam.base_c,
- pix_fmt->width, pix_fmt->height, color, field);
+ s5p_vp_ctrl_set_src_plane(
+ (u32) vparam.base_y, (u32) vparam.base_c,
+ pix_fmt->width, pix_fmt->height, color, field);
}
#endif
-#ifdef CONFIG_HAS_EARLYSUSPEND
+#if defined(CONFIG_HAS_EARLYSUSPEND) && defined(CLOCK_GATING_ON_EARLY_SUSPEND)
s5p_tvout_mutex_unlock();
#endif
return 0;
error_on_s_fmt_type_private:
-#ifdef CONFIG_HAS_EARLYSUSPEND
+#if defined(CONFIG_HAS_EARLYSUSPEND) && defined(CLOCK_GATING_ON_EARLY_SUSPEND)
s5p_tvout_mutex_unlock();
#endif
return -1;
@@ -1201,7 +1222,7 @@ static int s5p_tvout_vo_s_fmt_vid_overlay(
rect->left, rect->top, rect->width, rect->height,
a->fmt.win.global_alpha);
-#ifdef CONFIG_HAS_EARLYSUSPEND
+#if defined(CONFIG_HAS_EARLYSUSPEND) && defined(CLOCK_GATING_ON_EARLY_SUSPEND)
s5p_tvout_mutex_lock();
#endif
s5p_tvout_v4l2_private.vo_dst_fmt = a->fmt.win;
@@ -1211,7 +1232,7 @@ static int s5p_tvout_vo_s_fmt_vid_overlay(
rect->left, rect->top,
rect->width, rect->height);
-#ifdef CONFIG_HAS_EARLYSUSPEND
+#if defined(CONFIG_HAS_EARLYSUSPEND) && defined(CLOCK_GATING_ON_EARLY_SUSPEND)
s5p_tvout_mutex_unlock();
#endif
return 0;
@@ -1237,7 +1258,7 @@ static int s5p_tvout_vo_s_crop(
struct file *file, void *fh, struct v4l2_crop *a)
{
tvout_dbg("\n");
-#ifdef CONFIG_HAS_EARLYSUSPEND
+#if defined(CONFIG_HAS_EARLYSUSPEND) && defined(CLOCK_GATING_ON_EARLY_SUSPEND)
s5p_tvout_mutex_lock();
#endif
switch (a->type) {
@@ -1260,7 +1281,7 @@ static int s5p_tvout_vo_s_crop(
tvout_err("Invalid buf type(0x%08x)\n", a->type);
break;
}
-#ifdef CONFIG_HAS_EARLYSUSPEND
+#if defined(CONFIG_HAS_EARLYSUSPEND) && defined(CLOCK_GATING_ON_EARLY_SUSPEND)
s5p_tvout_mutex_unlock();
#endif
return 0;
@@ -1285,7 +1306,7 @@ static int s5p_tvout_vo_s_fbuf(
(a->flags & V4L2_FBUF_FLAG_GLOBAL_ALPHA) ? 1 : 0,
a->fmt.priv);
-#ifdef CONFIG_HAS_EARLYSUSPEND
+#if defined(CONFIG_HAS_EARLYSUSPEND) && defined(CLOCK_GATING_ON_EARLY_SUSPEND)
s5p_tvout_mutex_lock();
#endif
@@ -1294,7 +1315,7 @@ static int s5p_tvout_vo_s_fbuf(
s5p_vp_ctrl_set_dest_win_priority(a->fmt.priv);
-#ifdef CONFIG_HAS_EARLYSUSPEND
+#if defined(CONFIG_HAS_EARLYSUSPEND) && defined(CLOCK_GATING_ON_EARLY_SUSPEND)
s5p_tvout_mutex_unlock();
#endif
return 0;
@@ -1305,15 +1326,21 @@ static int s5p_tvout_vo_overlay(
{
tvout_dbg("%s\n", (i) ? "start" : "stop");
-#ifdef CONFIG_HAS_EARLYSUSPEND
+#if defined(CONFIG_HAS_EARLYSUSPEND) && defined(CLOCK_GATING_ON_EARLY_SUSPEND)
s5p_tvout_mutex_lock();
#endif
- if (i)
+ if (i) {
s5p_vp_ctrl_start();
- else
+ /* restore vsync interrupt setting */
+ s5p_mixer_set_vsync_interrupt(
+ s5p_mixer_ctrl_get_vsync_interrupt());
+ } else {
+ /* disable vsync interrupt when VP is disabled */
+ s5p_mixer_ctrl_disable_vsync_interrupt();
s5p_vp_ctrl_stop();
+ }
-#ifdef CONFIG_HAS_EARLYSUSPEND
+#if defined(CONFIG_HAS_EARLYSUSPEND) && defined(CLOCK_GATING_ON_EARLY_SUSPEND)
s5p_tvout_mutex_unlock();
#endif
return 0;
diff --git a/drivers/media/video/samsung/tvout/s5p_vp_ctrl.c b/drivers/media/video/samsung/tvout/s5p_vp_ctrl.c
index d074da3..148e3e9 100644
--- a/drivers/media/video/samsung/tvout/s5p_vp_ctrl.c
+++ b/drivers/media/video/samsung/tvout/s5p_vp_ctrl.c
@@ -279,7 +279,7 @@ static int s5p_vp_ctrl_set_reg(void)
struct s5p_vp_ctrl_pp_param *pp_param = &s5p_vp_ctrl_private.pp_param;
struct s5p_vp_ctrl_op_mode *op_mode = &s5p_vp_ctrl_private.op_mode;
-#ifdef CONFIG_HAS_EARLYSUSPEND
+#ifdef CLOCK_GATING_ON_EARLY_SUSPEND
if (suspend_status) {
tvout_dbg("driver is suspend_status\n");
} else
@@ -362,7 +362,7 @@ static int s5p_vp_ctrl_set_reg(void)
static void s5p_vp_ctrl_internal_stop(void)
{
-#ifdef CONFIG_HAS_EARLYSUSPEND
+#ifdef CLOCK_GATING_ON_EARLY_SUSPEND
if (suspend_status) {
tvout_dbg("driver is suspend_status\n");
} else
@@ -409,7 +409,7 @@ void s5p_vp_ctrl_set_src_plane(
src_plane->w = width;
src_plane->h = height;
-#ifdef CONFIG_HAS_EARLYSUSPEND
+#ifdef CLOCK_GATING_ON_EARLY_SUSPEND
if (suspend_status) {
tvout_dbg("driver is suspend_status\n");
return;
@@ -434,7 +434,7 @@ void s5p_vp_ctrl_set_src_win(u32 left, u32 top, u32 width, u32 height)
src_win->w = width;
src_win->h = height;
-#ifdef CONFIG_HAS_EARLYSUSPEND
+#ifdef CLOCK_GATING_ON_EARLY_SUSPEND
if (suspend_status) {
tvout_dbg("driver is suspend_status\n");
return;
@@ -466,7 +466,7 @@ void s5p_vp_ctrl_set_dest_win(u32 left, u32 top, u32 width, u32 height)
dst_win->y = top;
dst_win->w = width;
dst_win->h = height;
-#ifdef CONFIG_HAS_EARLYSUSPEND
+#ifdef CLOCK_GATING_ON_EARLY_SUSPEND
if (suspend_status) {
tvout_dbg("driver is suspend_status\n");
return;
@@ -493,7 +493,7 @@ void s5p_vp_ctrl_set_dest_win(u32 left, u32 top, u32 width, u32 height)
void s5p_vp_ctrl_set_dest_win_alpha_val(u32 alpha)
{
s5p_vp_ctrl_private.mixer_param.alpha = alpha;
-#ifdef CONFIG_HAS_EARLYSUSPEND
+#ifdef CLOCK_GATING_ON_EARLY_SUSPEND
if (suspend_status) {
tvout_dbg("driver is suspend_status\n");
return;
@@ -505,7 +505,7 @@ void s5p_vp_ctrl_set_dest_win_alpha_val(u32 alpha)
void s5p_vp_ctrl_set_dest_win_blend(bool enable)
{
s5p_vp_ctrl_private.mixer_param.blend = enable;
-#ifdef CONFIG_HAS_EARLYSUSPEND
+#ifdef CLOCK_GATING_ON_EARLY_SUSPEND
if (suspend_status) {
tvout_dbg("driver is suspend_status\n");
return;
@@ -518,7 +518,7 @@ void s5p_vp_ctrl_set_dest_win_blend(bool enable)
void s5p_vp_ctrl_set_dest_win_priority(u32 prio)
{
s5p_vp_ctrl_private.mixer_param.prio = prio;
-#ifdef CONFIG_HAS_EARLYSUSPEND
+#ifdef CLOCK_GATING_ON_EARLY_SUSPEND
if (suspend_status) {
tvout_dbg("driver is suspend_status\n");
return;
@@ -531,7 +531,7 @@ void s5p_vp_ctrl_stop(void)
{
if (s5p_vp_ctrl_private.running) {
s5p_vp_ctrl_internal_stop();
-#ifdef CONFIG_HAS_EARLYSUSPEND
+#ifdef CLOCK_GATING_ON_EARLY_SUSPEND
if (suspend_status) {
tvout_dbg("driver is suspend_status\n");
} else
@@ -647,7 +647,7 @@ int s5p_vp_ctrl_start(void)
if (s5p_vp_ctrl_private.running)
s5p_vp_ctrl_internal_stop();
else {
-#ifdef CONFIG_HAS_EARLYSUSPEND
+#ifdef CLOCK_GATING_ON_EARLY_SUSPEND
if (suspend_status) {
tvout_dbg("driver is suspend_status\n");
} else
diff --git a/drivers/media/video/samsung/ump/Kconfig b/drivers/media/video/samsung/ump/Kconfig
index aaae26e..6304825 100644
--- a/drivers/media/video/samsung/ump/Kconfig
+++ b/drivers/media/video/samsung/ump/Kconfig
@@ -20,7 +20,7 @@ config UMP_VCM_ALLOC
choice
depends on VIDEO_UMP
prompt "UMP MEMEMORY OPTION"
-default UMP_OSMEM_ONLY
+default UMP_OSMEM_ONLY
config UMP_DED_ONLY
bool "ump dedicated memory only"
---help---
@@ -37,7 +37,7 @@ config UMP_VCM_ONLY
endchoice
config UMP_MEM_SIZE
int "UMP Memory Size"
- depends on VIDEO_UMP
+ depends on VIDEO_UMP
default "512"
---help---
This value is dedicated memory size of UMP (unit is MByte).
@@ -48,4 +48,3 @@ config VIDEO_UMP_DEBUG
default n
help
This enables UMP driver debug messages.
-
diff --git a/drivers/media/video/samsung/ump/Makefile b/drivers/media/video/samsung/ump/Makefile
index f429c40..b3157a3 100644
--- a/drivers/media/video/samsung/ump/Makefile
+++ b/drivers/media/video/samsung/ump/Makefile
@@ -1,9 +1,9 @@
#
# 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.
#
@@ -30,14 +30,13 @@ DEFINES += -DDEBUG
endif
# Set up our defines, which will be passed to gcc
-DEFINES += -DKERNEL_BUILTIN=1
DEFINES += -DMALI_USE_UNIFIED_MEMORY_PROVIDER
DEFINES += -DUSING_MEMORY=$(USING_MEMORY)
DEFINES += -DUMP_MEM_SIZE=$(UMP_MEM_SIZE)
DEFINES += -DMALI_STATE_TRACKING=1
UDD_FILE_PREFIX := drivers/media/video/samsung/ump/
-KBUILDROOT =
+KBUILDROOT =
# linux build system integration
@@ -61,7 +60,7 @@ OSKFILES+=\
$(KBUILDROOT)../mali/linux/mali_osk_locks.o \
$(KBUILDROOT)../mali/linux/mali_osk_math.o \
$(KBUILDROOT)../mali/linux/mali_osk_memory.o \
- $(KBUILDROOT)../mali/linux/mali_osk_misc.o
+ $(KBUILDROOT)../mali/linux/mali_osk_misc.o
ump-y := \
$(KBUILDROOT)linux/ump_kernel_linux.o \
@@ -83,12 +82,11 @@ ump-$(CONFIG_UMP_VCM_ALLOC) += \
$(KBUILDROOT)linux/ump_kernel_memory_backend_vcm.o \
EXTRA_CFLAGS += $(INCLUDES) \
- $(DEFINES)
-
-
+ $(DEFINES)
+
+
# 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/media/video/samsung/ump/Makefile.common b/drivers/media/video/samsung/ump/Makefile.common
index 4b5db24..35527a2 100644
--- a/drivers/media/video/samsung/ump/Makefile.common
+++ b/drivers/media/video/samsung/ump/Makefile.common
@@ -1,17 +1,20 @@
#
-# Copyright (C) 2010 ARM Limited. All rights reserved.
-#
+# 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.
#
-UMP_FILE_PREFIX = ./drivers/video/samsung/ump
+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
-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/media/video/samsung/ump/Makefile_backup b/drivers/media/video/samsung/ump/Makefile_backup
deleted file mode 100644
index 632cb0c..0000000
--- a/drivers/media/video/samsung/ump/Makefile_backup
+++ /dev/null
@@ -1,80 +0,0 @@
-#
-# 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.
-#
-BUILD ?= debug
-USING_MALI400 ?= 1
-USING_ZBT ?= 0
-USING_MMU ?= 1
-USING_UMP ?= 1
-CPU ?= vega1
-CONFIG ?= marcopolo-vega1-m400
-
-
-# Set up our defines, which will be passed to gcc
-DEFINES += -DUSING_MALI400=$(USING_MALI400)
-DEFINES += -DUSING_ZBT=$(USING_ZBT)
-DEFINES += -DUSING_MMU=$(USING_MMU)
-DEFINES += -DUSING_UMP=$(USING_UMP)
-DEFINES += -DMALI_USE_UNIFIED_MEMORY_PROVIDER
-ifeq ($(BUILD), debug)
-DEFINES += -DDEBUG
-endif
-
-
-UMP_FILE_PREFIX := drivers/video/samsung/ump
-UDD_FILE_PREFIX := drivers/video/samsung/mali
-KBUILDROOT =
-
-# linux build system integration
-
-obj-y += ump.o
-
-# 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
-
-INCLUDES = \
- -I$(UMP_FILE_PREFIX)\
- -I$(UMP_FILE_PREFIX)/common\
- -I$(UMP_FILE_PREFIX)/linux\
- -I$(UMP_FILE_PREFIX)/include\
- -I$(UMP_FILE_PREFIX)/linux/license/proprietary/\
- -I$(UDD_FILE_PREFIX)/common\
- -I$(UDD_FILE_PREFIX)/linux
-
-ump-y := \
- $(KBUILDROOT)linux/ump_kernel_linux.o \
- $(KBUILDROOT)linux/ump_kernel_memory_backend_os.o \
- $(KBUILDROOT)linux/ump_kernel_memory_backend_dedicated.o \
- $(KBUILDROOT)linux/ump_memory_backend.o \
- $(KBUILDROOT)linux/ump_ukk_wrappers.o \
- $(KBUILDROOT)linux/ump_ukk_ref_wrappers.o \
- $(KBUILDROOT)linux/ump_osk_atomics.o \
- $(KBUILDROOT)linux/ump_osk_low_level_mem.o \
- $(KBUILDROOT)linux/ump_osk_misc.o \
- $(KBUILDROOT)../mali/linux/mali_osk_atomics.o \
- $(KBUILDROOT)../mali/linux/mali_osk_locks.o \
- $(KBUILDROOT)../mali/linux/mali_osk_memory.o \
- $(KBUILDROOT)../mali/linux/mali_osk_math.o \
- $(KBUILDROOT)../mali/linux/mali_osk_misc.o \
- $(KBUILDROOT)common/ump_kernel_common.o \
- $(KBUILDROOT)common/ump_kernel_descriptor_mapping.o \
- $(KBUILDROOT)common/ump_kernel_api.o \
- $(KBUILDROOT)common/ump_kernel_ref_drv.o
-
-EXTRA_CFLAGS += $(INCLUDES) \
- $(DEFINES)
-
-
-# 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/media/video/samsung/ump/Makefile_module b/drivers/media/video/samsung/ump/Makefile_module
new file mode 100644
index 0000000..f0c3829
--- /dev/null
+++ b/drivers/media/video/samsung/ump/Makefile_module
@@ -0,0 +1,119 @@
+#
+# 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.
+#
+
+UMP_FILE_PREFIX =
+UDD_FILE_PREFIX = ../mali/
+
+ifneq ($(KBUILD_EXTMOD),)
+include $(KBUILD_EXTMOD)/Makefile.common
+else
+include ./Makefile.common
+endif
+
+# For each arch check: CROSS_COMPILE , KDIR , CFLAGS += -DARCH
+
+ARCH ?= arm
+BUILD ?= debug
+
+EXTRA_CFLAGS += -DDEBUG -DMALI_STATE_TRACKING=0
+ifeq ($(BUILD), debug)
+EXTRA_CFLAGS += -DDEBUG
+endif
+
+# linux build system integration
+
+ifneq ($(KERNELRELEASE),)
+# Inside the kernel build system
+
+EXTRA_CFLAGS += -I$(KBUILD_EXTMOD) -I$(KBUILD_EXTMOD)/common -I$(KBUILD_EXTMOD)/linux -I$(KBUILD_EXTMOD)/../mali/common -I$(KBUILD_EXTMOD)/../mali/linux -I$(KBUILD_EXTMOD)/../../ump/include/ump
+
+# 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 $(KBUILD_EXTMOD)/linux/license/gpl/*),)
+EXTRA_CFLAGS += -I$(KBUILD_EXTMOD)/linux/license/proprietary
+else
+EXTRA_CFLAGS += -I$(KBUILD_EXTMOD)/linux/license/gpl
+endif
+
+SRC += $(UMP_FILE_PREFIX)linux/ump_kernel_linux.c \
+ $(UMP_FILE_PREFIX)linux/ump_kernel_memory_backend_os.c \
+ $(UMP_FILE_PREFIX)linux/ump_kernel_memory_backend_dedicated.c \
+ $(UMP_FILE_PREFIX)linux/ump_memory_backend.c \
+ $(UMP_FILE_PREFIX)linux/ump_ukk_wrappers.c \
+ $(UMP_FILE_PREFIX)linux/ump_ukk_ref_wrappers.c \
+ $(UMP_FILE_PREFIX)linux/ump_osk_atomics.c \
+ $(UMP_FILE_PREFIX)linux/ump_osk_low_level_mem.c \
+ $(UMP_FILE_PREFIX)linux/ump_osk_misc.c \
+ $(UDD_FILE_PREFIX)linux/mali_osk_atomics.c \
+ $(UDD_FILE_PREFIX)linux/mali_osk_locks.c \
+ $(UDD_FILE_PREFIX)linux/mali_osk_memory.c \
+ $(UDD_FILE_PREFIX)linux/mali_osk_math.c \
+ $(UDD_FILE_PREFIX)linux/mali_osk_misc.c
+
+# Selecting files to compile by parsing the config file
+
+MODULE:=ump.ko
+
+obj-m := $(MODULE:.ko=.o)
+$(MODULE:.ko=-y) := $(SRC:.c=.o)
+
+else
+# Outside the kernel build system
+
+# 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 ?= arm-none-linux-gnueabi-
+endif
+
+# look up KDIR based om CPU selection
+KDIR ?= $(KDIR-$(CPU))
+
+ifeq ($(KDIR),)
+$(error No KDIR found for platform $(CPU))
+endif
+
+# Validate selected config
+ifneq ($(shell [ -d arch-$(CONFIG) ] && [ -f arch-$(CONFIG)/config.h ] && echo "OK"), OK)
+$(warning Current directory is $(shell pwd))
+$(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 arch ] && rm arch)
+$(shell ln -sf arch-$(CONFIG) arch)
+$(shell touch arch/config.h)
+endif
+
+all:
+ $(MAKE) ARCH=$(ARCH) -C $(KDIR) M=$(CURDIR) modules
+
+kernelrelease:
+ $(MAKE) ARCH=$(ARCH) -C $(KDIR) kernelrelease
+
+clean:
+ $(MAKE) ARCH=$(ARCH) -C $(KDIR) M=$(CURDIR) clean
+ $(MAKE) ARCH=$(ARCH) -C $(KDIR) M=$(CURDIR)/../mali clean
+
+endif
diff --git a/drivers/media/video/samsung/ump/arch b/drivers/media/video/samsung/ump/arch
deleted file mode 120000
index a65a3fc..0000000
--- a/drivers/media/video/samsung/ump/arch
+++ /dev/null
@@ -1 +0,0 @@
-./arch-orion-m400 \ No newline at end of file
diff --git a/drivers/media/video/samsung/mali/common/mali_kernel_pp.h b/drivers/media/video/samsung/ump/arch-debug/config.h
index 8cf7bf7..688edc9 100644
--- a/drivers/media/video/samsung/mali/common/mali_kernel_pp.h
+++ b/drivers/media/video/samsung/ump/arch-debug/config.h
@@ -1,21 +1,22 @@
/*
- * Copyright (C) 2010 ARM Limited. All rights reserved.
- *
+ * 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_PP_H__
-#define __MALI_KERNEL_PP_H__
+#ifndef __ARCH_CONFIG_UMP_H__
+#define __ARCH_CONFIG_UMP_H__
-extern struct mali_kernel_subsystem mali_subsystem_mali200;
-
-#if USING_MALI_PMM
-_mali_osk_errcode_t malipp_signal_power_up( u32 core_num, mali_bool queue_only );
-_mali_osk_errcode_t malipp_signal_power_down( u32 core_num, mali_bool immediate_only );
+#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
-#endif /* __MALI_KERNEL_PP_H__ */
+#define ARCH_UMP_MEMORY_SIZE_DEFAULT UMP_MEM_SIZE*1024*1024
+#endif /* __ARCH_CONFIG_UMP_H__ */
diff --git a/drivers/media/video/samsung/ump/arch-marcopolo-vega1-m400/config.h.org b/drivers/media/video/samsung/ump/arch-marcopolo-vega1-m400/config.h.org
deleted file mode 100755
index c92a32a..0000000
--- a/drivers/media/video/samsung/ump/arch-marcopolo-vega1-m400/config.h.org
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * 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 __ARCH_CONFIG_H__
-#define __ARCH_CONFIG_H__
-
-/* Configuration for the EB platform with ZBT memory enabled */
-#define MALI_BASE_ADDR 0xf0000000
-#define GP_ADDR MALI_BASE_ADDR
-#define L2_ADDR MALI_BASE_ADDR+0x1000
-#define PMU_ADDR MALI_BASE_ADDR+0x2000
-#define GP_MMU_ADDR MALI_BASE_ADDR+0x3000
-#define PP_MMU_ADDR MALI_BASE_ADDR+0x4000
-#define PP_ADDR MALI_BASE_ADDR+0x8000
-
-// See 3-11 page in trm. It describes control register address map. cglee
-
-static _mali_osk_resource_t arch_configuration [] =
-{
- {
- .type = MALI400GP,
- .description = "Mali-400 GP",
- .base = GP_ADDR,
- .irq = 18+32,
- .mmu_id = 1
- },
- {
- .type = MALI400PP,
- .base = PP_ADDR,
- .irq = 16+32,
- .description = "Mali-400 PP 0",
- .mmu_id = 2
- },
-#if USING_MMU
- {
- .type = MMU,
- .base = GP_MMU_ADDR,
- .irq = 19+32,
- .description = "Mali-400 MMU for GP",
- .mmu_id = 1
- },
- {
- .type = MMU,
- .base = PP_MMU_ADDR,
- .irq = 17+32,
- .description = "Mali-400 MMU for PP 0",
- .mmu_id = 2
- },
- {
- .type = OS_MEMORY,
- .description = "System Memory",
- .size = 0x06000000,
- .flags = _MALI_CPU_WRITEABLE | _MALI_CPU_READABLE | _MALI_PP_READABLE | _MALI_PP_WRITEABLE | _MALI_GP_READABLE | _MALI_GP_WRITEABLE
- },
- {
- .type = MEM_VALIDATION,
- .description = "memory validation",
- .base = 0x204e0000,
- .size = 0x7B20000,
- .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
- },
-#else
- {
- .type = MEMORY,
- .description = "Dedicated Memory",
- .base = 0x2E000000,
- .size = 0x02000000,
- .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
- },
-#endif
- {
- .type = MALI400L2,
- .base = L2_ADDR,
- .description = "Mali-400 L2 cache"
- },
-};
-
-#endif /* __ARCH_CONFIG_H__ */
diff --git a/drivers/media/video/samsung/ump/arch-orion-m400/config.h b/drivers/media/video/samsung/ump/arch-orion-m400/config.h
index 117cc6e..688edc9 100644
--- a/drivers/media/video/samsung/ump/arch-orion-m400/config.h
+++ b/drivers/media/video/samsung/ump/arch-orion-m400/config.h
@@ -1,9 +1,9 @@
/*
- * Copyright (C) 2010 ARM Limited. All rights reserved.
- *
+ * 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.
*/
@@ -11,12 +11,12 @@
#ifndef __ARCH_CONFIG_UMP_H__
#define __ARCH_CONFIG_UMP_H__
-#define ARCH_UMP_BACKEND_DEFAULT USING_MEMORY
+#define ARCH_UMP_BACKEND_DEFAULT USING_MEMORY
#if (USING_MEMORY == 0) /* Dedicated Memory */
-#define ARCH_UMP_MEMORY_ADDRESS_DEFAULT 0x2C000000
+#define ARCH_UMP_MEMORY_ADDRESS_DEFAULT 0x2C000000
#else
-#define ARCH_UMP_MEMORY_ADDRESS_DEFAULT 0
+#define ARCH_UMP_MEMORY_ADDRESS_DEFAULT 0
#endif
-#define ARCH_UMP_MEMORY_SIZE_DEFAULT UMP_MEM_SIZE*1024*1024
+#define ARCH_UMP_MEMORY_SIZE_DEFAULT UMP_MEM_SIZE*1024*1024
#endif /* __ARCH_CONFIG_UMP_H__ */
diff --git a/drivers/media/video/samsung/ump/arch-pb-virtex5/config.h b/drivers/media/video/samsung/ump/arch-pb-virtex5/config.h
index 560eda9..38ae1ee 100644
--- a/drivers/media/video/samsung/ump/arch-pb-virtex5/config.h
+++ b/drivers/media/video/samsung/ump/arch-pb-virtex5/config.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 ARM Limited. All rights reserved.
+ * 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.
@@ -12,7 +12,7 @@
#define __ARCH_CONFIG_H__
#define ARCH_UMP_BACKEND_DEFAULT 0
-#define ARCH_UMP_MEMORY_ADDRESS_DEFAULT 0xC8000000
+#define ARCH_UMP_MEMORY_ADDRESS_DEFAULT 0xCE000000
#define ARCH_UMP_MEMORY_SIZE_DEFAULT 32UL * 1024UL * 1024UL
#endif /* __ARCH_CONFIG_H__ */
diff --git a/drivers/media/video/samsung/ump/arch-pegasus-m400/config.h b/drivers/media/video/samsung/ump/arch-pegasus-m400/config.h
new file mode 100644
index 0000000..688edc9
--- /dev/null
+++ b/drivers/media/video/samsung/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/media/video/samsung/ump/arch-release/config.h b/drivers/media/video/samsung/ump/arch-release/config.h
new file mode 100644
index 0000000..688edc9
--- /dev/null
+++ b/drivers/media/video/samsung/ump/arch-release/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/media/video/samsung/ump/arch/config.h b/drivers/media/video/samsung/ump/arch/config.h
new file mode 100644
index 0000000..688edc9
--- /dev/null
+++ b/drivers/media/video/samsung/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/media/video/samsung/ump/common/ump_kernel_api.c b/drivers/media/video/samsung/ump/common/ump_kernel_api.c
index ddc9ef7..83f0d30 100644
--- a/drivers/media/video/samsung/ump/common/ump_kernel_api.c
+++ b/drivers/media/video/samsung/ump/common/ump_kernel_api.c
@@ -1,9 +1,9 @@
/*
- * Copyright (C) 2010 ARM Limited. All rights reserved.
- *
+ * 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.
*/
@@ -161,7 +161,7 @@ UMP_KERNEL_API_EXPORT void ump_dd_reference_add(ump_dd_handle memh)
new_ref = _ump_osk_atomic_inc_and_read(&mem->ref_count);
- DBG_MSG(4, ("Memory reference incremented. ID: %u, new value: %d\n", mem->secure_id, new_ref));
+ DBG_MSG(5, ("Memory reference incremented. ID: %u, new value: %d\n", mem->secure_id, new_ref));
}
@@ -181,7 +181,7 @@ UMP_KERNEL_API_EXPORT void ump_dd_reference_release(ump_dd_handle memh)
new_ref = _ump_osk_atomic_dec_and_read(&mem->ref_count);
- DBG_MSG(4, ("Memory reference decremented. ID: %u, new value: %d\n", mem->secure_id, new_ref));
+ DBG_MSG(5, ("Memory reference decremented. ID: %u, new value: %d\n", mem->secure_id, new_ref));
if (0 == new_ref)
{
@@ -277,7 +277,7 @@ _mali_osk_errcode_t _ump_ukk_release( _ump_uk_release_s *release_info )
}
_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_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;
@@ -313,15 +313,22 @@ _mali_osk_errcode_t _ump_ukk_size_get( _ump_uk_size_get_s *user_interaction )
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);
- _mali_osk_lock_signal(device.secure_id_map_lock, _MALI_OSK_LOCKMODE_RW);
- if (NULL==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;
@@ -330,17 +337,215 @@ void _ump_ukk_msync( _ump_uk_msync_s *args )
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));
- return;
+ 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));
- return ;
+ 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;
}
- DBG_MSG(3, ("_ump_ukk_msync FLUSHING ID: %u Enabled: %d OP: %d\n", (ump_secure_id)args->secure_id, mem->is_cached, args->op));
/* The actual cache flush - Implemented for each OS*/
- _ump_osk_msync( mem , args->op, (u32)args->mapping, (u32)args->address, args->size);
+ _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;
+
+ /** TODO: TAKE LOCK HERE */
+
+ 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;
+
+ /** TODO: RELEASE LOCK HERE */
+
+ ump_dd_reference_release(mem);
}
diff --git a/drivers/media/video/samsung/ump/common/ump_kernel_common.c b/drivers/media/video/samsung/ump/common/ump_kernel_common.c
index e5ff198..1fa7c8a 100644
--- a/drivers/media/video/samsung/ump/common/ump_kernel_common.c
+++ b/drivers/media/video/samsung/ump/common/ump_kernel_common.c
@@ -1,9 +1,9 @@
/*
- * Copyright (C) 2010 ARM Limited. All rights reserved.
- *
+ * 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.
*/
@@ -147,6 +147,9 @@ _mali_osk_errcode_t _ump_ukk_open( void** context )
*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;
@@ -225,19 +228,17 @@ _mali_osk_errcode_t _ump_ukk_map_mem( _ump_uk_map_mem_s *args )
int map_id;
session_data = (ump_session_data *)args->ctx;
- if (NULL == session_data)
+ if(NULL == session_data)
{
MSG_ERR(("Session data is NULL in _ump_ukk_map_mem()\n"));
return _MALI_OSK_ERR_INVALID_ARGS;
}
-
/* 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)
{
@@ -370,14 +371,12 @@ void _ump_ukk_unmap_mem( _ump_uk_unmap_mem_s *args )
MSG_ERR(("Session data is NULL in _ump_ukk_map_mem()\n"));
return;
}
-
/* 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 ));
diff --git a/drivers/media/video/samsung/ump/common/ump_kernel_common.h b/drivers/media/video/samsung/ump/common/ump_kernel_common.h
index c8b5541..03d213d 100644
--- a/drivers/media/video/samsung/ump/common/ump_kernel_common.h
+++ b/drivers/media/video/samsung/ump/common/ump_kernel_common.h
@@ -1,15 +1,15 @@
/*
- * Copyright (C) 2010 ARM Limited. All rights reserved.
- *
+ * 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_H__
-#define __UMP_KERNEL_H__
+#ifndef __UMP_KERNEL_COMMON_H__
+#define __UMP_KERNEL_COMMON_H__
#include "ump_kernel_types.h"
#include "ump_kernel_interface.h"
@@ -77,6 +77,8 @@ typedef struct ump_session_data
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;
@@ -123,4 +125,4 @@ int map_errcode( _mali_osk_errcode_t err );
#define __user
#endif
-#endif /* __UMP_KERNEL_H__ */
+#endif /* __UMP_KERNEL_COMMON_H__ */
diff --git a/drivers/media/video/samsung/ump/common/ump_kernel_descriptor_mapping.c b/drivers/media/video/samsung/ump/common/ump_kernel_descriptor_mapping.c
index 5174839..cc7b8be 100644
--- a/drivers/media/video/samsung/ump/common/ump_kernel_descriptor_mapping.c
+++ b/drivers/media/video/samsung/ump/common/ump_kernel_descriptor_mapping.c
@@ -1,9 +1,9 @@
/*
- * Copyright (C) 2010 ARM Limited. All rights reserved.
- *
+ * 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.
*/
@@ -65,9 +65,9 @@ void ump_descriptor_mapping_destroy(ump_descriptor_mapping * 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);
+ 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;
@@ -89,8 +89,8 @@ int ump_descriptor_mapping_allocate_mapping(ump_descriptor_mapping * map, void *
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*));
+ _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);
@@ -107,10 +107,10 @@ unlock_and_exit:
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) )
+ 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;
@@ -122,9 +122,9 @@ int ump_descriptor_mapping_get(ump_descriptor_mapping * map, int descriptor, voi
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) )
+ 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;
@@ -135,8 +135,8 @@ int ump_descriptor_mapping_set(ump_descriptor_mapping * map, int descriptor, voi
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) )
+ _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);
@@ -163,4 +163,3 @@ static void descriptor_table_free(ump_descriptor_table * table)
{
_mali_osk_free(table);
}
-
diff --git a/drivers/media/video/samsung/ump/common/ump_kernel_descriptor_mapping.h b/drivers/media/video/samsung/ump/common/ump_kernel_descriptor_mapping.h
index 319cc3b..881d3d8 100644
--- a/drivers/media/video/samsung/ump/common/ump_kernel_descriptor_mapping.h
+++ b/drivers/media/video/samsung/ump/common/ump_kernel_descriptor_mapping.h
@@ -1,9 +1,9 @@
/*
- * Copyright (C) 2010 ARM Limited. All rights reserved.
- *
+ * 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.
*/
diff --git a/drivers/media/video/samsung/ump/common/ump_kernel_memory_backend.h b/drivers/media/video/samsung/ump/common/ump_kernel_memory_backend.h
index d329bb5..73915ee 100644
--- a/drivers/media/video/samsung/ump/common/ump_kernel_memory_backend.h
+++ b/drivers/media/video/samsung/ump/common/ump_kernel_memory_backend.h
@@ -1,9 +1,9 @@
/*
- * Copyright (C) 2010 ARM Limited. All rights reserved.
- *
+ * 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.
*/
@@ -49,4 +49,3 @@ ump_memory_backend * ump_memory_backend_create ( void );
void ump_memory_backend_destroy( void );
#endif /*__UMP_KERNEL_MEMORY_BACKEND_H__ */
-
diff --git a/drivers/media/video/samsung/ump/common/ump_kernel_ref_drv.c b/drivers/media/video/samsung/ump/common/ump_kernel_ref_drv.c
index 4dcbe21..a5ccfeb 100644
--- a/drivers/media/video/samsung/ump/common/ump_kernel_ref_drv.c
+++ b/drivers/media/video/samsung/ump/common/ump_kernel_ref_drv.c
@@ -1,9 +1,9 @@
/*
- * Copyright (C) 2010 ARM Limited. All rights reserved.
- *
+ * 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.
*/
@@ -95,6 +95,8 @@ UMP_KERNEL_API_EXPORT ump_dd_handle ump_dd_handle_create_from_phys_blocks(ump_dd
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));
@@ -165,6 +167,7 @@ _mali_osk_errcode_t _ump_ukk_allocate( _ump_uk_allocate_s *user_interaction )
}
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 ) )
@@ -176,7 +179,7 @@ _mali_osk_errcode_t _ump_ukk_allocate( _ump_uk_allocate_s *user_interaction )
_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;
@@ -195,6 +198,7 @@ _mali_osk_errcode_t _ump_ukk_allocate( _ump_uk_allocate_s *user_interaction )
return _MALI_OSK_ERR_OK;
}
+
UMP_KERNEL_API_EXPORT ump_dd_status_code ump_dd_meminfo_set(ump_dd_handle memh, void* args)
{
ump_dd_mem * mem;
@@ -255,4 +259,3 @@ UMP_KERNEL_API_EXPORT ump_dd_handle ump_dd_handle_get_from_vaddr(unsigned long v
return (ump_dd_handle)mem;
}
-
diff --git a/drivers/media/video/samsung/ump/common/ump_kernel_types.h b/drivers/media/video/samsung/ump/common/ump_kernel_types.h
index ca03dec..fdacd86 100644
--- a/drivers/media/video/samsung/ump/common/ump_kernel_types.h
+++ b/drivers/media/video/samsung/ump/common/ump_kernel_types.h
@@ -1,9 +1,9 @@
/*
- * Copyright (C) 2010 ARM Limited. All rights reserved.
- *
+ * 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.
*/
@@ -14,6 +14,22 @@
#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
*/
@@ -28,6 +44,8 @@ typedef struct ump_dd_mem
void * ctx;
void * backend_info;
int is_cached;
+ ump_hw_usage hw_device;
+ ump_lock_usage lock_usage;
} ump_dd_mem;
diff --git a/drivers/media/video/samsung/ump/common/ump_osk.h b/drivers/media/video/samsung/ump/common/ump_osk.h
index bd9254b..dabdc7f 100644
--- a/drivers/media/video/samsung/ump/common/ump_osk.h
+++ b/drivers/media/video/samsung/ump/common/ump_osk.h
@@ -1,9 +1,9 @@
/*
- * Copyright (C) 2010 ARM Limited. All rights reserved.
- *
+ * 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.
*/
@@ -18,7 +18,8 @@
#include <mali_osk.h>
#include <ump_kernel_memory_backend.h>
-#include <ump_uk_types.h>
+#include "ump_uk_types.h"
+#include "ump_kernel_common.h"
#ifdef __cplusplus
extern "C"
@@ -39,7 +40,7 @@ _mali_osk_errcode_t _ump_osk_mem_mapregion_map( ump_memory_allocation * descript
void _ump_osk_mem_mapregion_term( ump_memory_allocation * descriptor );
-void _ump_osk_msync( ump_dd_mem * mem, ump_uk_msync_op op, u32 start, u32 address, u32 size);
+void _ump_osk_msync( ump_dd_mem * mem, void * virt, u32 offset, u32 size, ump_uk_msync_op op, ump_session_data * session_data );
void _ump_osk_mem_mapregion_get( ump_dd_mem ** mem, unsigned long vaddr);
diff --git a/drivers/media/video/samsung/ump/common/ump_uk_types.h b/drivers/media/video/samsung/ump/common/ump_uk_types.h
index 2bac454..4fd1ef7 100644
--- a/drivers/media/video/samsung/ump/common/ump_uk_types.h
+++ b/drivers/media/video/samsung/ump/common/ump_uk_types.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 ARM Limited. All rights reserved.
+ * 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.
@@ -45,12 +45,11 @@ typedef enum
_UMP_IOC_MAP_MEM, /* not used in Linux */
_UMP_IOC_UNMAP_MEM, /* not used in Linux */
_UMP_IOC_MSYNC,
-#ifdef CONFIG_ION_EXYNOS
+ _UMP_IOC_CACHE_OPERATIONS_CONTROL,
+ _UMP_IOC_SWITCH_HW_USAGE,
+ _UMP_IOC_LOCK,
+ _UMP_IOC_UNLOCK,
_UMP_IOC_ION_IMPORT,
-#endif
-#ifdef CONFIG_DMA_SHARED_BUFFER
- _UMP_IOC_DMABUF_IMPORT,
-#endif
}_ump_uk_functions;
typedef enum
@@ -64,9 +63,30 @@ 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)
*/
@@ -88,25 +108,14 @@ typedef struct _ump_uk_allocate_s
ump_uk_alloc_constraints constraints; /**< Only input to Devicedriver */
} _ump_uk_allocate_s;
-#ifdef CONFIG_ION_EXYNOS
typedef struct _ump_uk_ion_import_s
{
void *ctx; /**< [in,out] user-kernel context (trashed on output) */
- int ion_fd;
+ 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;
-#endif
-
-#ifdef CONFIG_DMA_SHARED_BUFFER
-struct ump_uk_dmabuf {
- void *ctx;
- int fd;
- size_t size;
- uint32_t ump_handle;
-};
-#endif
/**
* SIZE_GET ([in] u32 secure_id, [out]size )
@@ -156,10 +165,38 @@ typedef struct _ump_uk_msync_s
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] 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
diff --git a/drivers/media/video/samsung/ump/common/ump_ukk.h b/drivers/media/video/samsung/ump/common/ump_ukk.h
index db48cd6..4e6bb86 100644
--- a/drivers/media/video/samsung/ump/common/ump_ukk.h
+++ b/drivers/media/video/samsung/ump/common/ump_ukk.h
@@ -1,9 +1,9 @@
/*
- * Copyright (C) 2010 ARM Limited. All rights reserved.
- *
+ * 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.
*/
@@ -44,6 +44,14 @@ 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
diff --git a/drivers/media/video/samsung/ump/include/ump_kernel_interface.h b/drivers/media/video/samsung/ump/include/ump_kernel_interface.h
index ba81a07..f84d237 100644
--- a/drivers/media/video/samsung/ump/include/ump_kernel_interface.h
+++ b/drivers/media/video/samsung/ump/include/ump_kernel_interface.h
@@ -1,9 +1,9 @@
/*
- * Copyright (C) 2010 ARM Limited. All rights reserved.
- *
+ * 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.
*/
diff --git a/drivers/media/video/samsung/ump/include/ump_kernel_interface_ref_drv.h b/drivers/media/video/samsung/ump/include/ump_kernel_interface_ref_drv.h
index 3efe165..36c5c9d 100644
--- a/drivers/media/video/samsung/ump/include/ump_kernel_interface_ref_drv.h
+++ b/drivers/media/video/samsung/ump/include/ump_kernel_interface_ref_drv.h
@@ -1,9 +1,9 @@
/*
- * Copyright (C) 2010 ARM Limited. All rights reserved.
- *
+ * 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.
*/
diff --git a/drivers/media/video/samsung/ump/include/ump_kernel_interface_vcm.h b/drivers/media/video/samsung/ump/include/ump_kernel_interface_vcm.h
index a784241..5ff4155 100644
--- a/drivers/media/video/samsung/ump/include/ump_kernel_interface_vcm.h
+++ b/drivers/media/video/samsung/ump/include/ump_kernel_interface_vcm.h
@@ -1,9 +1,9 @@
/*
- * Copyright (C) 2010 ARM Limited. All rights reserved.
- *
+ * 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.
*/
diff --git a/drivers/media/video/samsung/ump/include/ump_kernel_platform.h b/drivers/media/video/samsung/ump/include/ump_kernel_platform.h
index 1b5af40..339e967 100644
--- a/drivers/media/video/samsung/ump/include/ump_kernel_platform.h
+++ b/drivers/media/video/samsung/ump/include/ump_kernel_platform.h
@@ -1,9 +1,9 @@
/*
- * Copyright (C) 2010 ARM Limited. All rights reserved.
- *
+ * 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.
*/
diff --git a/drivers/media/video/samsung/ump/linux/license/gpl/ump_kernel_license.h b/drivers/media/video/samsung/ump/linux/license/gpl/ump_kernel_license.h
index 17b930d..50a021c 100644
--- a/drivers/media/video/samsung/ump/linux/license/gpl/ump_kernel_license.h
+++ b/drivers/media/video/samsung/ump/linux/license/gpl/ump_kernel_license.h
@@ -1,9 +1,9 @@
/*
- * Copyright (C) 2010 ARM Limited. All rights reserved.
- *
+ * 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.
*/
diff --git a/drivers/media/video/samsung/ump/linux/ump_ioctl.h b/drivers/media/video/samsung/ump/linux/ump_ioctl.h
index 50ef9df..1d49b4d 100644
--- a/drivers/media/video/samsung/ump/linux/ump_ioctl.h
+++ b/drivers/media/video/samsung/ump/linux/ump_ioctl.h
@@ -1,9 +1,9 @@
/*
- * Copyright (C) 2010 ARM Limited. All rights reserved.
- *
+ * 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.
*/
@@ -19,7 +19,7 @@ extern "C"
#include <linux/types.h>
#include <linux/ioctl.h>
-#include "../common/ump_uk_types.h"
+#include <ump_uk_types.h>
#ifndef __user
#define __user
@@ -39,16 +39,20 @@ extern "C"
#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_size_get_s)
+#define UMP_IOC_MSYNC _IOW(UMP_IOCTL_NR, _UMP_IOC_MSYNC, _ump_uk_msync_s)
#ifdef CONFIG_ION_EXYNOS
#define UMP_IOC_ION_IMPORT _IOW(UMP_IOCTL_NR, _UMP_IOC_ION_IMPORT, _ump_uk_ion_import_s)
#endif
-
#ifdef CONFIG_DMA_SHARED_BUFFER
#define UMP_IOC_DMABUF_IMPORT _IOW(UMP_IOCTL_NR, _UMP_IOC_DMABUF_IMPORT,\
struct ump_uk_dmabuf)
#endif
+#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
diff --git a/drivers/media/video/samsung/ump/linux/ump_kernel_linux.c b/drivers/media/video/samsung/ump/linux/ump_kernel_linux.c
index 69f55c5..58cef54 100644
--- a/drivers/media/video/samsung/ump/linux/ump_kernel_linux.c
+++ b/drivers/media/video/samsung/ump/linux/ump_kernel_linux.c
@@ -1,9 +1,9 @@
/*
- * Copyright (C) 2010 ARM Limited. All rights reserved.
- *
+ * 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.
*/
@@ -42,7 +42,7 @@ struct ion_client *ion_client_ump = NULL;
#endif
/* Module parameter to control log level */
-int ump_debug_level = 3;
+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");
@@ -55,7 +55,9 @@ MODULE_PARM_DESC(ump_major, "Device major number");
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.
@@ -90,7 +92,7 @@ static int ump_file_ioctl(struct inode *inode, struct file *filp, unsigned int c
#endif
static int ump_file_mmap(struct file * filp, struct vm_area_struct * vma);
-#ifdef CONFIG_VIDEO_MALI400MP_R2P3
+#if defined(CONFIG_VIDEO_MALI400MP) || defined(CONFIG_VIDEO_MALI400MP_R3P0) || defined(CONFIG_VIDEO_MALI400MP_R2P3)
extern int map_errcode( _mali_osk_errcode_t err );
#endif
@@ -171,6 +173,7 @@ 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)
{
@@ -180,6 +183,7 @@ int ump_kernel_device_initialize(void)
{
debugfs_create_file("memory_usage", 0400, ump_debugfs_dir, NULL, &ump_memory_usage_fops);
}
+#endif
if (0 == ump_major)
{
@@ -257,8 +261,10 @@ void ump_kernel_device_terminate(void)
/* free major */
unregister_chrdev_region(dev, 1);
+#if UMP_LICENSE_IS_GPL
if(ump_debugfs_dir)
debugfs_remove_recursive(ump_debugfs_dir);
+#endif
}
/*
@@ -369,6 +375,22 @@ static int ump_file_ioctl(struct inode *inode, struct file *filp, unsigned int c
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;
@@ -377,7 +399,6 @@ static int ump_file_ioctl(struct inode *inode, struct file *filp, unsigned int c
return err;
}
-
#ifndef CONFIG_VIDEO_MALI400MP_R2P3
#ifndef CONFIG_VIDEO_MALI400MP
#ifndef CONFIG_VIDEO_MALI400MP_R3P0
@@ -399,7 +420,6 @@ int map_errcode( _mali_osk_errcode_t err )
#endif
#endif
#endif
-
/*
* Handle from OS to map specified virtual memory to specified UMP memory.
*/
@@ -431,6 +451,8 @@ static int ump_file_mmap(struct file * filp, struct vm_area_struct * vma)
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 ));
diff --git a/drivers/media/video/samsung/ump/linux/ump_kernel_linux.h b/drivers/media/video/samsung/ump/linux/ump_kernel_linux.h
index b93c814e..ef68040 100644
--- a/drivers/media/video/samsung/ump/linux/ump_kernel_linux.h
+++ b/drivers/media/video/samsung/ump/linux/ump_kernel_linux.h
@@ -1,18 +1,18 @@
/*
- * Copyright (C) 2010 ARM Limited. All rights reserved.
- *
+ * 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_H__
-#define __UMP_KERNEL_H__
+#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__ */
+#endif /* __UMP_KERNEL_LINUX_H__ */
diff --git a/drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_dedicated.c b/drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_dedicated.c
index 4e6c9b5..82c16cc 100644
--- a/drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_dedicated.c
+++ b/drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_dedicated.c
@@ -1,9 +1,9 @@
/*
- * Copyright (C) 2010 ARM Limited. All rights reserved.
- *
+ * 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.
*/
@@ -52,6 +52,7 @@ 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);
@@ -104,6 +105,7 @@ ump_memory_backend * ump_block_allocator_create(u32 base_address, u32 size)
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;
backend->get = NULL;
@@ -220,6 +222,7 @@ static int block_allocator_allocate(void* ctx, ump_dd_mem * mem)
mem->backend_info = last_allocated;
up(&allocator->mutex);
+ mem->is_cached=0;
return 1;
}
@@ -272,3 +275,13 @@ 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/media/video/samsung/ump/linux/ump_kernel_memory_backend_dedicated.h b/drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_dedicated.h
index fa4bdcc..4f7180e 100644
--- a/drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_dedicated.h
+++ b/drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_dedicated.h
@@ -1,9 +1,9 @@
/*
- * Copyright (C) 2010 ARM Limited. All rights reserved.
- *
+ * 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.
*/
@@ -20,4 +20,3 @@
ump_memory_backend * ump_block_allocator_create(u32 base_address, u32 size);
#endif /* __UMP_KERNEL_MEMORY_BACKEND_DEDICATED_H__ */
-
diff --git a/drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_os.c b/drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_os.c
index 07fbd3f..2d81546 100644
--- a/drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_os.c
+++ b/drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_os.c
@@ -1,9 +1,9 @@
/*
- * Copyright (C) 2010 ARM Limited. All rights reserved.
- *
+ * 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.
*/
@@ -136,16 +136,16 @@ static int os_allocate(void* ctx, ump_dd_mem * descriptor)
return 0; /* failure */
}
- while (left > 0 && ((info->num_pages_allocated + pages_allocated) < info->num_pages_max))
+ while (left > 0)
{
struct page * new_page;
if (is_cached)
{
- new_page = alloc_page(GFP_KERNEL | __GFP_ZERO | __GFP_NOWARN );
+ new_page = alloc_page(GFP_HIGHUSER | __GFP_ZERO | __GFP_REPEAT | __GFP_NOWARN);
} else
{
- new_page = alloc_page(GFP_KERNEL | __GFP_ZERO | __GFP_NOWARN | __GFP_COLD);
+ new_page = alloc_page(GFP_HIGHUSER | __GFP_ZERO | __GFP_REPEAT | __GFP_NOWARN | __GFP_COLD);
}
if (NULL == new_page)
{
@@ -182,9 +182,7 @@ static int os_allocate(void* ctx, ump_dd_mem * descriptor)
if (left)
{
- MSG_ERR(("Failed to allocate needed pages\n"));
- MSG_ERR(("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));
+ DBG_MSG(1, ("Failed to allocate needed pages\n"));
while(pages_allocated)
{
diff --git a/drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_os.h b/drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_os.h
index f924705..b638562d 100644
--- a/drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_os.h
+++ b/drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_os.h
@@ -1,9 +1,9 @@
/*
- * Copyright (C) 2010 ARM Limited. All rights reserved.
- *
+ * 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.
*/
@@ -20,4 +20,3 @@
ump_memory_backend * ump_os_memory_backend_create(const int max_allocation);
#endif /* __UMP_KERNEL_MEMORY_BACKEND_OS_H__ */
-
diff --git a/drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_vcm.c b/drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_vcm.c
index de7f212..46797ea 100644
--- a/drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_vcm.c
+++ b/drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_vcm.c
@@ -1,9 +1,9 @@
/*
- * Copyright (C) 2010 ARM Limited. All rights reserved.
- *
+ * 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.
*/
@@ -66,9 +66,9 @@ ump_memory_backend * ump_vcm_memory_backend_create(const int max_allocation)
{
return NULL;
}
-
+
info->num_vcm_blocks = 0;
-
+
sema_init(&info->mutex, 1);
@@ -85,7 +85,7 @@ ump_memory_backend * ump_vcm_memory_backend_create(const int max_allocation)
backend->shutdown = vcm_memory_backend_destroy;
backend->pre_allocate_physical_check = NULL;
backend->adjust_to_mali_phys = NULL;
-
+
backend->get = vcm_res_get;
backend->set = vcm_attr_set;
@@ -128,8 +128,8 @@ static int ump_vcm_allocate(void *ctx, ump_dd_mem * descriptor)
ump_vcm->dev_id = (int)descriptor->backend_info & ~UMP_REF_DRV_UK_CONSTRAINT_USE_CACHE;
- if(ump_vcm->dev_id == UMP_REF_DRV_UK_CONSTRAINT_NONE) { /* None */
- ump_vcm->dev_id = UMP_REF_DRV_UK_VCM_DEV_G2D; /* this ID is G2D */
+ if(ump_vcm->dev_id == UMP_REF_DRV_UK_CONSTRAINT_NONE) { /* None */
+ ump_vcm->dev_id = UMP_REF_DRV_UK_VCM_DEV_G2D; /* this ID is G2D */
}
else if(ump_vcm->dev_id == UMP_REF_DRV_UK_CONSTRAINT_PHYSICALLY_LINEAR) { /* Physical Linear */
return 0;
@@ -137,7 +137,7 @@ static int ump_vcm_allocate(void *ctx, ump_dd_mem * descriptor)
else { /* Other VCM */
ump_vcm->dev_id -= 2;
}
-
+
DBG_MSG(5, ("Device ID for VCM : %d\n", ump_vcm->dev_id));
ump_vcm->vcm = vcm_find_vcm(ump_vcm->dev_id);
@@ -146,7 +146,7 @@ static int ump_vcm_allocate(void *ctx, ump_dd_mem * descriptor)
return 0;
}
descriptor->backend_info = (void*)ump_vcm;
-
+
if (down_interruptible(&info->mutex)) {
DBG_MSG(1, ("Failed to get mutex in ump_vcm_allocate\n"));
return 0; /* failure */
@@ -168,7 +168,7 @@ static int vcm_mem_allocator(vcm_allocator *info, ump_dd_mem *descriptor)
struct ump_vcm *ump_vcm;
ump_vcm = (struct ump_vcm*)descriptor->backend_info;
-
+
ump_vcm->vcm_res =
vcm_make_binding(ump_vcm->vcm, descriptor->size_bytes,
ump_vcm->dev_id, 0);
@@ -288,5 +288,3 @@ static void vcm_attr_set(ump_dd_mem *mem, void *args)
return;
}
-
-
diff --git a/drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_vcm.h b/drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_vcm.h
index 62f6d12..c1ead0d 100644
--- a/drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_vcm.h
+++ b/drivers/media/video/samsung/ump/linux/ump_kernel_memory_backend_vcm.h
@@ -1,9 +1,9 @@
/*
- * Copyright (C) 2010 ARM Limited. All rights reserved.
- *
+ * 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.
*/
diff --git a/drivers/media/video/samsung/ump/linux/ump_memory_backend.c b/drivers/media/video/samsung/ump/linux/ump_memory_backend.c
index f2a6bd6..821ac27 100644
--- a/drivers/media/video/samsung/ump/linux/ump_memory_backend.c
+++ b/drivers/media/video/samsung/ump/linux/ump_memory_backend.c
@@ -1,9 +1,9 @@
/*
- * Copyright (C) 2010 ARM Limited. All rights reserved.
- *
+ * 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.
*/
@@ -17,7 +17,6 @@
#include "ump_kernel_common.h"
#include "ump_kernel_memory_backend_os.h"
#include "ump_kernel_memory_backend_dedicated.h"
-#include "ump_kernel_memory_backend_vcm.h"
/* Configure which dynamic memory allocator to use */
int ump_backend = ARCH_UMP_BACKEND_DEFAULT;
diff --git a/drivers/media/video/samsung/ump/linux/ump_osk_atomics.c b/drivers/media/video/samsung/ump/linux/ump_osk_atomics.c
index ef1902e..77be0c9 100644
--- a/drivers/media/video/samsung/ump/linux/ump_osk_atomics.c
+++ b/drivers/media/video/samsung/ump/linux/ump_osk_atomics.c
@@ -1,9 +1,9 @@
/*
- * Copyright (C) 2010 ARM Limited. All rights reserved.
- *
+ * 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.
*/
diff --git a/drivers/media/video/samsung/ump/linux/ump_osk_low_level_mem.c b/drivers/media/video/samsung/ump/linux/ump_osk_low_level_mem.c
index 17af2bd..b38c714 100644
--- a/drivers/media/video/samsung/ump/linux/ump_osk_low_level_mem.c
+++ b/drivers/media/video/samsung/ump/linux/ump_osk_low_level_mem.c
@@ -1,9 +1,9 @@
/*
- * Copyright (C) 2010 ARM Limited. All rights reserved.
- *
+ * 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.
*/
@@ -27,6 +27,7 @@
#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>
@@ -301,108 +302,140 @@ static void _ump_osk_msync_with_virt(ump_dd_mem * mem, ump_uk_msync_op op, u32 s
return;
}
-void _ump_osk_msync( ump_dd_mem * mem, ump_uk_msync_op op, u32 start, u32 address, u32 size)
+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;
- u32 start_p, end_p;
- ump_dd_physical_block *block;
+ const void *start_v, *end_v;
- DBG_MSG(3,
- ("Flushing nr of blocks: %u. First: paddr: 0x%08x vaddr: 0x%08x size:%dB\n",
- mem->nr_blocks, mem->block_array[0].addr,
- phys_to_virt(mem->block_array[0].addr),
- mem->block_array[0].size));
-
-#ifndef USING_DMA_FLUSH
- if (address) {
- if ((address >= start)
- && ((address + size) <= start + mem->size_bytes)) {
- if (size >= SZ_64K) {
- flush_all_cpu_caches();
- } else if (op == _UMP_UK_MSYNC_CLEAN_AND_INVALIDATE)
- dmac_flush_range((void *)address,
- (void *)(address + size - 1));
- else
- dmac_map_area((void *)address, size,
- DMA_TO_DEVICE);
-#ifdef CONFIG_CACHE_L2X0
- if (size >= SZ_1M)
- outer_clean_all();
+ /* 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)) )
+ {
+ 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. */
+ dmac_flush_range(start_v, end_v);
+ 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
- _ump_osk_msync_with_virt(mem, op, start, address, size);
-#endif
- return;
+ {
+ 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 ((op == _UMP_UK_MSYNC_CLEAN_AND_INVALIDATE)) {
- if ((mem->size_bytes >= SZ_1M)) {
- flush_all_cpu_caches();
-#ifdef CONFIG_CACHE_L2X0
- outer_flush_all();
-#endif
- return;
- } else if ((mem->size_bytes >= SZ_64K)) {
- flush_all_cpu_caches();
-#ifdef CONFIG_CACHE_L2X0
- for (i = 0; i < mem->nr_blocks; i++) {
- block = &mem->block_array[i];
- start_p = (u32) block->addr;
- end_p = start_p + block->size - 1;
- outer_flush_range(start_p, end_p);
- }
-#endif
- return;
+ 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. */
+ 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;
}
- } else {
- if ((mem->size_bytes >= SZ_1M)) {
- flush_all_cpu_caches();
-#ifdef CONFIG_CACHE_L2X0
- outer_clean_all();
-#endif
- return;
- } else if ((mem->size_bytes >= SZ_64K)) {
- flush_all_cpu_caches();
-#ifdef CONFIG_CACHE_L2X0
- for (i = 0; i < mem->nr_blocks; i++) {
- block = &mem->block_array[i];
- start_p = (u32) block->addr;
+
+ 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;
- outer_clean_range(start_p, end_p);
+ size -= block->size;
}
-#endif
- return;
}
- }
-#endif
- for (i = 0; i < mem->nr_blocks; i++) {
- /* TODO: Find out which flush method is best of 1)Dma OR 2)Normal flush functions */
- /*#define USING_DMA_FLUSH */
-#ifdef USING_DMA_FLUSH
- DEBUG_ASSERT((PAGE_SIZE == mem->block_array[i].size));
- dma_map_page(NULL,
- pfn_to_page(mem->block_array[i].
- addr >> PAGE_SHIFT), 0, PAGE_SIZE,
- DMA_BIDIRECTIONAL);
- /*dma_unmap_page(NULL, mem->block_array[i].addr, PAGE_SIZE, DMA_BIDIRECTIONAL); */
-#else
- block = &mem->block_array[i];
- start_p = (u32) block->addr;
- end_p = start_p + block->size - 1;
- if (op == _UMP_UK_MSYNC_CLEAN_AND_INVALIDATE) {
- dmac_flush_range(phys_to_virt(start_p),
- phys_to_virt(end_p));
- outer_flush_range(start_p, end_p);
- } else {
- dmac_map_area(phys_to_virt(start_p), block->size,
- DMA_TO_DEVICE);
- outer_clean_range(start_p, end_p);
+ 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;
}
-#endif
}
-}
+ return;
+}
void _ump_osk_mem_mapregion_get( ump_dd_mem ** mem, unsigned long vaddr)
{
diff --git a/drivers/media/video/samsung/ump/linux/ump_osk_misc.c b/drivers/media/video/samsung/ump/linux/ump_osk_misc.c
index 12066eb..1f1118e 100644
--- a/drivers/media/video/samsung/ump/linux/ump_osk_misc.c
+++ b/drivers/media/video/samsung/ump/linux/ump_osk_misc.c
@@ -1,9 +1,9 @@
/*
- * Copyright (C) 2010 ARM Limited. All rights reserved.
- *
+ * 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.
*/
diff --git a/drivers/media/video/samsung/ump/linux/ump_ukk_ref_wrappers.c b/drivers/media/video/samsung/ump/linux/ump_ukk_ref_wrappers.c
index 3e355c0..405bdca 100644
--- a/drivers/media/video/samsung/ump/linux/ump_ukk_ref_wrappers.c
+++ b/drivers/media/video/samsung/ump/linux/ump_ukk_ref_wrappers.c
@@ -1,9 +1,9 @@
/*
- * Copyright (C) 2010 ARM Limited. All rights reserved.
- *
+ * 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.
*/
diff --git a/drivers/media/video/samsung/ump/linux/ump_ukk_ref_wrappers.h b/drivers/media/video/samsung/ump/linux/ump_ukk_ref_wrappers.h
index 7bd4660..8e3c0fc 100644
--- a/drivers/media/video/samsung/ump/linux/ump_ukk_ref_wrappers.h
+++ b/drivers/media/video/samsung/ump/linux/ump_ukk_ref_wrappers.h
@@ -1,9 +1,9 @@
/*
- * Copyright (C) 2010 ARM Limited. All rights reserved.
- *
+ * 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.
*/
diff --git a/drivers/media/video/samsung/ump/linux/ump_ukk_wrappers.c b/drivers/media/video/samsung/ump/linux/ump_ukk_wrappers.c
index 8b73ca8..e5c5903 100644
--- a/drivers/media/video/samsung/ump/linux/ump_ukk_wrappers.c
+++ b/drivers/media/video/samsung/ump/linux/ump_ukk_wrappers.c
@@ -1,9 +1,9 @@
/*
- * Copyright (C) 2010 ARM Limited. All rights reserved.
- *
+ * 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.
*/
@@ -138,9 +138,9 @@ int ump_size_get_wrapper(u32 __user * argument, struct ump_session_data * sessi
}
/*
- * IOCTL operation; Return size for specified UMP memory.
+ * IOCTL operation; Do cache maintenance on specified UMP memory.
*/
- int ump_msync_wrapper(u32 __user * argument, struct ump_session_data * session_data)
+int ump_msync_wrapper(u32 __user * argument, struct ump_session_data * session_data)
{
_ump_uk_msync_s user_interaction;
@@ -171,3 +171,136 @@ int ump_size_get_wrapper(u32 __user * argument, struct ump_session_data * sessi
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/media/video/samsung/ump/linux/ump_ukk_wrappers.h b/drivers/media/video/samsung/ump/linux/ump_ukk_wrappers.h
index 4892c31..99b790d 100644
--- a/drivers/media/video/samsung/ump/linux/ump_ukk_wrappers.h
+++ b/drivers/media/video/samsung/ump/linux/ump_ukk_wrappers.h
@@ -1,9 +1,9 @@
/*
- * Copyright (C) 2010 ARM Limited. All rights reserved.
- *
+ * 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.
*/
@@ -30,6 +30,10 @@ int ump_get_api_version_wrapper(u32 __user * argument, struct ump_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
diff --git a/drivers/media/video/slp_db8131m.c b/drivers/media/video/slp_db8131m.c
new file mode 100644
index 0000000..a42bfd4c
--- /dev/null
+++ b/drivers/media/video/slp_db8131m.c
@@ -0,0 +1,796 @@
+/*
+ * linux/drivers/media/video/slp_db8131m.c
+ *
+ * Copyright (c) 2012 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 version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/i2c.h>
+#include <linux/init.h>
+#include <media/v4l2-device.h>
+#include <linux/delay.h>
+#include <linux/version.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-subdev.h>
+#ifdef CONFIG_VIDEO_SAMSUNG_V4L2
+#include <linux/videodev2_exynos_camera.h>
+#endif
+#include <media/db8131m_platform.h>
+
+#include "slp_db8131m.h"
+
+#ifdef DB8131M_USLEEP
+#include <linux/hrtimer.h>
+#endif
+
+#define CHECK_ERR(x) if (unlikely((x) < 0)) { \
+ cam_err("i2c failed, err %d\n", x); \
+ return x; \
+ }
+
+#define NELEMS(array) (sizeof(array) / sizeof(array[0]))
+
+static inline int db8131m_read(struct i2c_client *client,
+ u16 subaddr, u16 *data)
+{
+ u8 buf[2];
+ int err = 0;
+ struct i2c_msg msg = {
+ .addr = client->addr,
+ .flags = 0,
+ .len = 2,
+ .buf = buf,
+ };
+
+ *(u16 *)buf = cpu_to_be16(subaddr);
+
+ err = i2c_transfer(client->adapter, &msg, 1);
+ if (unlikely(err < 0))
+ cam_err("ERR: %d register read fail\n", __LINE__);
+
+ msg.flags = I2C_M_RD;
+
+ err = i2c_transfer(client->adapter, &msg, 1);
+ if (unlikely(err < 0))
+ cam_err("ERR: %d register read fail\n", __LINE__);
+
+ *data = ((buf[0] << 8) | buf[1]);
+
+ return err;
+}
+
+/*
+ * s5k6aafx sensor i2c write routine
+ * <start>--<Device address><2Byte Subaddr><2Byte Value>--<stop>
+ */
+static inline int db8131m_write(struct i2c_client *client,
+ u32 packet)
+{
+ u8 buf[4];
+ int err = 0, retry_count = 5;
+
+ struct i2c_msg msg = {
+ .addr = client->addr,
+ .flags = 0,
+ .buf = buf,
+ .len = 4,
+ };
+
+ if (!client->adapter) {
+ cam_err("ERR - can't search i2c client adapter\n");
+ return -EIO;
+ }
+
+ while (retry_count--) {
+ *(u32 *)buf = cpu_to_be32(packet);
+ err = i2c_transfer(client->adapter, &msg, 1);
+ if (likely(err == 1))
+ break;
+ mdelay(10);
+ }
+
+ if (unlikely(err < 0)) {
+ cam_err("ERR - 0x%08x write failed err=%d\n",
+ (u32)packet, err);
+ return err;
+ }
+
+ return (err != 1) ? -1 : 0;
+}
+
+/* program multiple registers */
+static int db8131m_write_regs(struct v4l2_subdev *sd,
+ const u8 *packet, u32 num)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ int ret = -EAGAIN;
+ int retry_count = 5;
+
+ u8 buf[2] = {0,};
+
+ struct i2c_msg msg = {
+ msg.addr = client->addr,
+ msg.flags = 0,
+ msg.len = 2,
+ msg.buf = buf,
+ };
+
+ while (num) {
+ buf[0] = *packet++;
+ buf[1] = *packet++;
+
+ num -= 2;
+
+ retry_count = 5;
+
+ while (retry_count--) {
+ ret = i2c_transfer(client->adapter, &msg, 1);
+ if (likely(ret == 1))
+ break;
+ mdelay(10);
+ }
+
+ if (unlikely(ret < 0)) {
+ cam_err("ERR - 0x%08x write failed err=%d\n",
+ (u32)packet, ret);
+ break;
+ }
+ }
+
+ if (unlikely(ret < 0)) {
+ cam_err("fail to write registers!!\n");
+ return -EIO;
+ }
+
+ return 0;
+}
+
+static int db8131m_check_dataline(struct v4l2_subdev *sd, s32 val)
+{
+ return 0;
+}
+
+static int db8131m_debug_sensor_status(struct v4l2_subdev *sd)
+{
+ return 0;
+}
+
+static int db8131m_check_sensor_status(struct v4l2_subdev *sd)
+{
+ return 0;
+}
+
+static inline int db8131m_check_esd(struct v4l2_subdev *sd)
+{
+ return 0;
+}
+
+static int db8131m_set_preview_start(struct v4l2_subdev *sd)
+{
+ struct db8131m_state *state = to_state(sd);
+ int err = -EINVAL;
+
+ cam_info("reset preview\n");
+
+#ifdef CONFIG_LOAD_FILE
+ err = db8131m_write_regs_from_sd(sd, "db8131m_preview");
+#else
+ err = db8131m_write_regs(sd, db8131m_preview,
+ sizeof(db8131m_preview) / sizeof(db8131m_preview[0]));
+#endif
+ if (state->check_dataline)
+ err = db8131m_check_dataline(sd, 1);
+ if (unlikely(err)) {
+ cam_err("fail to make preview\n");
+ return err;
+ }
+
+ return 0;
+}
+
+static int db8131m_set_preview_stop(struct v4l2_subdev *sd)
+{
+ return 0;
+}
+
+static int db8131m_set_capture_start(struct v4l2_subdev *sd)
+{
+ return 0;
+}
+
+static int db8131m_set_sensor_mode(struct v4l2_subdev *sd,
+ struct v4l2_control *ctrl)
+{
+ struct db8131m_state *state = to_state(sd);
+
+ if ((ctrl->value != SENSOR_CAMERA) &&
+ (ctrl->value != SENSOR_MOVIE)) {
+ cam_err("ERR: Not support.(%d)\n", ctrl->value);
+ return -EINVAL;
+ }
+
+ state->sensor_mode = ctrl->value;
+
+ return 0;
+}
+
+static int db8131m_enum_framesizes(struct v4l2_subdev *sd, \
+ struct v4l2_frmsizeenum *fsize)
+{
+ return 0;
+}
+
+static int db8131m_s_fmt(struct v4l2_subdev *sd,
+ struct v4l2_mbus_framefmt *ffmt)
+{
+ struct db8131m_state *state = to_state(sd);
+ u32 *width = NULL, *height = NULL;
+
+ cam_dbg("E\n");
+ /*
+ * Just copying the requested format as of now.
+ * We need to check here what are the formats the camera support, and
+ * set the most appropriate one according to the request from FIMC
+ */
+
+ state->req_fmt.width = ffmt->width;
+ state->req_fmt.height = ffmt->height;
+ state->req_fmt.priv = ffmt->field;
+
+ switch (state->req_fmt.priv) {
+ case V4L2_PIX_FMT_MODE_PREVIEW:
+ cam_dbg("V4L2_PIX_FMT_MODE_PREVIEW\n");
+ width = &state->preview_frmsizes.width;
+ height = &state->preview_frmsizes.height;
+ break;
+
+ case V4L2_PIX_FMT_MODE_CAPTURE:
+ cam_dbg("V4L2_PIX_FMT_MODE_CAPTURE\n");
+ width = &state->capture_frmsizes.width;
+ height = &state->capture_frmsizes.height;
+ break;
+
+ default:
+ cam_err("ERR(EINVAL)\n");
+ return -EINVAL;
+ }
+
+ if ((*width != state->req_fmt.width) ||
+ (*height != state->req_fmt.height)) {
+ cam_err("ERR: Invalid size. width= %d, height= %d\n",
+ state->req_fmt.width, state->req_fmt.height);
+ }
+
+ return 0;
+}
+
+static int db8131m_set_frame_rate(struct v4l2_subdev *sd, u32 fps)
+{
+ int err = 0;
+
+ cam_info("frame rate %d\n\n", fps);
+
+ switch (fps) {
+ case 7:
+ err = db8131m_write_regs(sd, db8131m_vt_7fps,
+ sizeof(db8131m_vt_7fps) / \
+ sizeof(db8131m_vt_7fps[0]));
+ break;
+ case 10:
+ err = db8131m_write_regs(sd, db8131m_vt_10fps,
+ sizeof(db8131m_vt_10fps) / \
+ sizeof(db8131m_vt_10fps[0]));
+
+ break;
+ case 12:
+ err = db8131m_write_regs(sd, db8131m_vt_12fps,
+ sizeof(db8131m_vt_12fps) / \
+ sizeof(db8131m_vt_12fps[0]));
+
+ break;
+ case 15:
+ err = db8131m_write_regs(sd, db8131m_vt_15fps,
+ sizeof(db8131m_vt_15fps) / \
+ sizeof(db8131m_vt_15fps[0]));
+ break;
+ default:
+ cam_err("ERR: Invalid framerate\n");
+ break;
+ }
+
+ if (unlikely(err < 0)) {
+ cam_err("i2c_write for set framerate\n");
+ return -EIO;
+ }
+
+ return err;
+}
+
+static int db8131m_g_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *parms)
+{
+ int err = 0;
+
+ cam_dbg("E\n");
+
+ return err;
+}
+
+static int db8131m_s_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *parms)
+{
+ int err = 0;
+ u32 fps = 0;
+ struct db8131m_state *state = to_state(sd);
+
+ if (!state->vt_mode)
+ return 0;
+
+ cam_dbg("E\n");
+
+ fps = parms->parm.capture.timeperframe.denominator /
+ parms->parm.capture.timeperframe.numerator;
+
+ if (fps != state->set_fps) {
+ if (fps < 0 && fps > 30) {
+ cam_err("invalid frame rate %d\n", fps);
+ fps = 30;
+ }
+ state->req_fps = fps;
+
+ if (state->initialized) {
+ err = db8131m_set_frame_rate(sd, state->req_fps);
+ if (err >= 0)
+ state->set_fps = state->req_fps;
+ }
+
+ }
+
+ return err;
+}
+
+static int db8131m_control_stream(struct v4l2_subdev *sd, u32 cmd)
+{
+ int err = 0;
+
+ switch (cmd) {
+ case 0: /* STREAM_STOP */
+ cam_dbg("stream stop!!!\n");
+ break;
+
+ case 1: /* STREAM_START */
+ cam_warn("WARN: do nothing\n");
+ break;
+
+ default:
+ cam_err("ERR: Invalid cmd\n");
+ break;
+ }
+
+ if (unlikely(err))
+ cam_err("failed to stream start(stop)\n");
+
+ return err;
+}
+
+static int db8131m_init(struct v4l2_subdev *sd, u32 val)
+{
+ /* struct i2c_client *client = v4l2_get_subdevdata(sd); */
+ struct db8131m_state *state = to_state(sd);
+ int err = -EINVAL;
+
+ cam_dbg("E\n");
+
+ /* set initial regster value */
+ if (state->sensor_mode == SENSOR_CAMERA) {
+ cam_info("load camera common setting\n");
+ err = db8131m_write_regs(sd, db8131m_common_1,
+ sizeof(db8131m_common_1) / \
+ sizeof(db8131m_common_1[0]));
+
+ msleep(150);
+
+ err |= db8131m_write_regs(sd, db8131m_common_2,
+ sizeof(db8131m_common_2) / \
+ sizeof(db8131m_common_2[0]));
+ } else {
+ cam_info("load recording setting\n");
+ err = db8131m_write_regs(sd, db8131m_common_1,
+ sizeof(db8131m_common_1) / \
+ sizeof(db8131m_common_1[0]));
+
+ msleep(150);
+
+ err = db8131m_write_regs(sd, db8131m_common_2,
+ sizeof(db8131m_common_2) / \
+ sizeof(db8131m_common_2[0]));
+ }
+ if (unlikely(err)) {
+ cam_err("failed to init\n");
+ return err;
+ }
+
+ /* We stop stream-output from sensor when starting camera. */
+ err = db8131m_control_stream(sd, 0);
+ if (unlikely(err < 0))
+ return err;
+ msleep(150);
+
+ state->initialized = 1;
+
+ return 0;
+}
+
+static int db8131m_s_stream(struct v4l2_subdev *sd, int enable)
+{
+ struct db8131m_state *state = to_state(sd);
+ /* struct i2c_client *client = v4l2_get_subdevdata(sd); */
+ int err = 0;
+
+ cam_info("stream mode = %d\n", enable);
+
+ switch (enable) {
+ case STREAM_MODE_CAM_OFF:
+ if (state->sensor_mode == SENSOR_CAMERA) {
+ if (state->check_dataline)
+ err = db8131m_check_dataline(sd, 0);
+ else
+ err = db8131m_control_stream(sd, 0);
+ }
+ break;
+
+ case STREAM_MODE_CAM_ON:
+ /* The position of this code need to be adjusted later */
+ if ((state->sensor_mode == SENSOR_CAMERA)
+ && (state->req_fmt.priv == V4L2_PIX_FMT_MODE_CAPTURE))
+ err = db8131m_set_capture_start(sd);
+ else
+ err = db8131m_set_preview_start(sd);
+ break;
+
+ case STREAM_MODE_MOVIE_ON:
+ cam_dbg("do nothing(movie on)!!\n");
+ break;
+
+ case STREAM_MODE_MOVIE_OFF:
+ cam_dbg("do nothing(movie off)!!\n");
+ break;
+
+ default:
+ cam_err("ERR: Invalid stream mode\n");
+ break;
+ }
+
+ if (unlikely(err < 0)) {
+ cam_err("ERR: faild\n");
+ return err;
+ }
+
+ return 0;
+}
+
+static int db8131m_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+{
+ struct db8131m_state *state = to_state(sd);
+ int err = 0;
+
+ cam_dbg("ctrl->id : %d\n", ctrl->id - V4L2_CID_PRIVATE_BASE);
+
+ switch (ctrl->id) {
+ case V4L2_CID_CAMERA_EXIF_TV:
+ ctrl->value = state->exif.shutter_speed;
+ break;
+ case V4L2_CID_CAMERA_EXIF_ISO:
+ ctrl->value = state->exif.iso;
+ break;
+ default:
+ cam_err("no such control id %d\n",
+ ctrl->id - V4L2_CID_PRIVATE_BASE);
+ break;
+ }
+
+ return err;
+}
+
+static int db8131m_set_brightness(struct v4l2_subdev *sd,
+ struct v4l2_control *ctrl)
+{
+ struct db8131m_state *state = to_state(sd);
+ int err = -EINVAL;
+
+ cam_dbg("E\n");
+
+ if (state->check_dataline)
+ return 0;
+
+ switch (ctrl->value) {
+ case EV_MINUS_4:
+ err = db8131m_write_regs(sd, db8131m_bright_m4, \
+ sizeof(db8131m_bright_m4) / \
+ sizeof(db8131m_bright_m4[0]));
+ break;
+ case EV_MINUS_3:
+ err = db8131m_write_regs(sd, db8131m_bright_m3, \
+ sizeof(db8131m_bright_m3) / \
+ sizeof(db8131m_bright_m3[0]));
+
+ break;
+ case EV_MINUS_2:
+ err = db8131m_write_regs(sd, db8131m_bright_m2, \
+ sizeof(db8131m_bright_m2) / \
+ sizeof(db8131m_bright_m2[0]));
+ break;
+ case EV_MINUS_1:
+ err = db8131m_write_regs(sd, db8131m_bright_m1, \
+ sizeof(db8131m_bright_m1) / \
+ sizeof(db8131m_bright_m1[0]));
+ break;
+ case EV_DEFAULT:
+ err = db8131m_write_regs(sd, db8131m_bright_default, \
+ sizeof(db8131m_bright_default) / \
+ sizeof(db8131m_bright_default[0]));
+ break;
+ case EV_PLUS_1:
+ err = db8131m_write_regs(sd, db8131m_bright_p1, \
+ sizeof(db8131m_bright_p1) / \
+ sizeof(db8131m_bright_p1[0]));
+ break;
+ case EV_PLUS_2:
+ err = db8131m_write_regs(sd, db8131m_bright_p2, \
+ sizeof(db8131m_bright_p2) / \
+ sizeof(db8131m_bright_p2[0]));
+ break;
+ case EV_PLUS_3:
+ err = db8131m_write_regs(sd, db8131m_bright_p3, \
+ sizeof(db8131m_bright_p3) / \
+ sizeof(db8131m_bright_p3[0]));
+ break;
+ case EV_PLUS_4:
+ err = db8131m_write_regs(sd, db8131m_bright_p4, \
+ sizeof(db8131m_bright_p4) / \
+ sizeof(db8131m_bright_p4[0]));
+ break;
+ default:
+ cam_err("ERR: invalid brightness(%d)\n", ctrl->value);
+ return err;
+ break;
+ }
+
+ if (unlikely(err < 0)) {
+ cam_err("ERR: i2c_write for set brightness\n");
+ return -EIO;
+ }
+
+ return 0;
+}
+
+static int db8131m_set_blur(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+{
+ return 0;
+}
+
+static int db8131m_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+{
+ /* struct i2c_client *client = v4l2_get_subdevdata(sd); */
+ struct db8131m_state *state = to_state(sd);
+ int err = 0;
+
+ cam_info("ctrl->id : %d, value=%d\n", ctrl->id - V4L2_CID_PRIVATE_BASE,
+ ctrl->value);
+
+ if ((ctrl->id != V4L2_CID_CAMERA_CHECK_DATALINE)
+ && (ctrl->id != V4L2_CID_CAMERA_SENSOR_MODE)
+ && ((ctrl->id != V4L2_CID_CAMERA_VT_MODE))
+ && (!state->initialized)) {
+ cam_warn("camera isn't initialized\n");
+ return 0;
+ }
+
+ switch (ctrl->id) {
+ case V4L2_CID_CAM_PREVIEW_ONOFF:
+ if (ctrl->value)
+ err = db8131m_set_preview_start(sd);
+ else
+ err = db8131m_set_preview_stop(sd);
+ cam_dbg("V4L2_CID_CAM_PREVIEW_ONOFF [%d]\n", ctrl->value);
+ break;
+
+ case V4L2_CID_CAM_CAPTURE:
+ err = db8131m_set_capture_start(sd);
+ cam_dbg("V4L2_CID_CAM_CAPTURE\n");
+ break;
+
+ case V4L2_CID_CAMERA_BRIGHTNESS:
+ err = db8131m_set_brightness(sd, ctrl);
+ cam_dbg("V4L2_CID_CAMERA_BRIGHTNESS [%d]\n", ctrl->value);
+ break;
+
+ case V4L2_CID_CAMERA_VGA_BLUR:
+ err = db8131m_set_blur(sd, ctrl);
+ cam_dbg("V4L2_CID_CAMERA_VGA_BLUR [%d]\n", ctrl->value);
+ break;
+
+ case V4L2_CID_CAMERA_VT_MODE:
+ state->vt_mode = ctrl->value;
+ break;
+
+ case V4L2_CID_CAMERA_CHECK_DATALINE:
+ state->check_dataline = ctrl->value;
+ cam_dbg("check_dataline = %d\n", state->check_dataline);
+ err = 0;
+ break;
+
+ case V4L2_CID_CAMERA_SENSOR_MODE:
+ err = db8131m_set_sensor_mode(sd, ctrl);
+ cam_dbg("sensor_mode = %d\n", ctrl->value);
+ break;
+
+ case V4L2_CID_CAMERA_CHECK_DATALINE_STOP:
+ cam_dbg("do nothing\n");
+ /*err = db8131m_check_dataline_stop(sd);*/
+ break;
+
+ case V4L2_CID_CAMERA_CHECK_ESD:
+ err = db8131m_check_esd(sd);
+ break;
+
+ case V4L2_CID_CAMERA_FRAME_RATE:
+ cam_dbg("do nothing\n");
+ break;
+
+ case V4L2_CID_CAMERA_CHECK_SENSOR_STATUS:
+ db8131m_debug_sensor_status(sd);
+ err = db8131m_check_sensor_status(sd);
+ break;
+
+ default:
+ cam_err("ERR(ENOIOCTLCMD)\n");
+ /* no errors return.*/
+ break;
+ }
+
+ cam_dbg("X\n");
+ return err;
+}
+
+static const struct v4l2_subdev_core_ops db8131m_core_ops = {
+ .init = db8131m_init, /* initializing API */
+#if 0
+ .queryctrl = db8131m_queryctrl,
+ .querymenu = db8131m_querymenu,
+#endif
+ .g_ctrl = db8131m_g_ctrl,
+ .s_ctrl = db8131m_s_ctrl,
+};
+
+static const struct v4l2_subdev_video_ops db8131m_video_ops = {
+ /*.s_crystal_freq = db8131m_s_crystal_freq,*/
+ .s_mbus_fmt = db8131m_s_fmt,
+ .s_stream = db8131m_s_stream,
+ .enum_framesizes = db8131m_enum_framesizes,
+ /*.enum_frameintervals = db8131m_enum_frameintervals,*/
+ /*.enum_fmt = db8131m_enum_fmt,*/
+ .g_parm = db8131m_g_parm,
+ .s_parm = db8131m_s_parm,
+};
+
+static const struct v4l2_subdev_ops db8131m_ops = {
+ .core = &db8131m_core_ops,
+ .video = &db8131m_video_ops,
+};
+
+/*
+ * db8131m_probe
+ * Fetching platform data is being done with s_config subdev call.
+ * In probe routine, we just register subdev device
+ */
+static int db8131m_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct db8131m_state *state = NULL;
+ struct v4l2_subdev *sd = NULL;
+ struct db8131m_platform_data *pdata = NULL;
+ cam_dbg("E\n");
+
+ state = kzalloc(sizeof(struct db8131m_state), GFP_KERNEL);
+ if (state == NULL)
+ return -ENOMEM;
+
+ sd = &state->sd;
+ strcpy(sd->name, DB8131M_DRIVER_NAME);
+
+ state->initialized = 0;
+ state->req_fps = state->set_fps = 8;
+ state->sensor_mode = SENSOR_CAMERA;
+
+ pdata = client->dev.platform_data;
+
+ if (!pdata) {
+ cam_err("no platform data\n");
+ return -ENODEV;
+ }
+
+ /* Registering subdev */
+ v4l2_i2c_subdev_init(sd, client, &db8131m_ops);
+
+ /*
+ * Assign default format and resolution
+ * Use configured default information in platform data
+ * or without them, use default information in driver
+ */
+ if (!(pdata->default_width && pdata->default_height)) {
+ state->preview_frmsizes.width = DEFAULT_PREVIEW_WIDTH;
+ state->preview_frmsizes.height = DEFAULT_PREVIEW_HEIGHT;
+ } else {
+ state->preview_frmsizes.width = pdata->default_width;
+ state->preview_frmsizes.height = pdata->default_height;
+ }
+ state->capture_frmsizes.width = DEFAULT_CAPTURE_WIDTH;
+ state->capture_frmsizes.height = DEFAULT_CAPTURE_HEIGHT;
+
+ cam_dbg("preview_width: %d , preview_height: %d, "
+ "capture_width: %d, capture_height: %d",
+ state->preview_frmsizes.width, state->preview_frmsizes.height,
+ state->capture_frmsizes.width, state->capture_frmsizes.height);
+
+ state->req_fmt.width = state->preview_frmsizes.width;
+ state->req_fmt.height = state->preview_frmsizes.height;
+
+ if (!pdata->pixelformat)
+ state->req_fmt.pixelformat = VT_DEFAULT_FMT;
+ else
+ state->req_fmt.pixelformat = pdata->pixelformat;
+
+ cam_dbg("probed!!\n");
+
+ return 0;
+}
+
+static int db8131m_remove(struct i2c_client *client)
+{
+ struct v4l2_subdev *sd = i2c_get_clientdata(client);
+ struct db8131m_state *state = to_state(sd);
+
+ cam_dbg("E\n");
+
+ state->initialized = 0;
+
+ v4l2_device_unregister_subdev(sd);
+ kfree(to_state(sd));
+
+ return 0;
+}
+
+static const struct i2c_device_id db8131m_id[] = {
+ { DB8131M_DRIVER_NAME, 0 },
+ { },
+};
+MODULE_DEVICE_TABLE(i2c, db8131m_id);
+
+static struct i2c_driver db8131m_i2c_driver = {
+ .driver = {
+ .name = DB8131M_DRIVER_NAME,
+ },
+ .probe = db8131m_probe,
+ .remove = db8131m_remove,
+ .id_table = db8131m_id,
+};
+
+static int __init db8131m_mod_init(void)
+{
+ cam_dbg("E\n");
+ return i2c_add_driver(&db8131m_i2c_driver);
+}
+
+static void __exit db8131m_mod_exit(void)
+{
+ cam_dbg("E\n");
+ i2c_del_driver(&db8131m_i2c_driver);
+}
+module_init(db8131m_mod_init);
+module_exit(db8131m_mod_exit);
+
+MODULE_DESCRIPTION("DB8131M CAM driver");
+MODULE_AUTHOR(" ");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/slp_db8131m.h b/drivers/media/video/slp_db8131m.h
new file mode 100644
index 0000000..3c594a2
--- /dev/null
+++ b/drivers/media/video/slp_db8131m.h
@@ -0,0 +1,100 @@
+/*
+ * linux/drivers/media/video/slp_db8131m.c
+ *
+ * Copyright (c) 2012 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 version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __DB8131M_H
+#define __DB8131M_H
+
+#include <linux/types.h>
+
+extern struct class *camera_class;
+
+#define DB8131M_DRIVER_NAME "DB8131M"
+
+struct db8131m_framesize {
+ u32 width;
+ u32 height;
+};
+
+struct db8131m_exif {
+ u32 shutter_speed;
+ u16 iso;
+};
+
+
+/*
+ * Driver information
+ */
+struct db8131m_state {
+ struct v4l2_subdev sd;
+ struct device *db8131m_dev;
+ /*
+ * req_fmt is the requested format from the application.
+ * set_fmt is the output format of the camera. Finally FIMC
+ * converts the camera output(set_fmt) to the requested format
+ * with hardware scaler.
+ */
+ struct v4l2_pix_format req_fmt;
+ struct db8131m_framesize preview_frmsizes;
+ struct db8131m_framesize capture_frmsizes;
+ struct db8131m_exif exif;
+
+ enum v4l2_sensor_mode sensor_mode;
+ s32 vt_mode;
+ s32 check_dataline;
+ u32 req_fps;
+ u32 set_fps;
+ u32 initialized;
+};
+
+static inline struct db8131m_state *to_state(struct v4l2_subdev *sd)
+{
+ return container_of(sd, struct db8131m_state, sd);
+}
+
+/*#define CONFIG_CAM_DEBUG */
+#define cam_warn(fmt, ...) \
+ do { \
+ printk(KERN_WARNING "%s: " fmt, __func__, ##__VA_ARGS__); \
+ } while (0)
+
+#define cam_err(fmt, ...) \
+ do { \
+ printk(KERN_ERR "%s: " fmt, __func__, ##__VA_ARGS__); \
+ } while (0)
+
+#define cam_info(fmt, ...) \
+ do { \
+ printk(KERN_INFO "%s: " fmt, __func__, ##__VA_ARGS__); \
+ } while (0)
+
+#ifdef CONFIG_CAM_DEBUG
+#define cam_dbg(fmt, ...) \
+ do { \
+ printk(KERN_DEBUG "%s: " fmt, __func__, ##__VA_ARGS__); \
+ } while (0)
+#else
+#define cam_dbg(fmt, ...)
+#endif /* CONFIG_CAM_DEBUG */
+
+
+
+/*********** Sensor specific ************/
+#define DB8131M_DELAY 0xFFFF0000
+#define DB8131M_DEF_APEX_DEN 100
+
+/* Register address */
+#define REG_PAGE_SHUTTER 0x7000
+#define REG_ADDR_SHUTTER 0x14D0
+#define REG_PAGE_ISO 0x7000
+#define REG_ADDR_ISO 0x14C8
+
+#include "slp_db8131m_setfile.h"
+
+#endif /* __DB8131M_H */
diff --git a/drivers/media/video/slp_db8131m_setfile.h b/drivers/media/video/slp_db8131m_setfile.h
new file mode 100644
index 0000000..ebbdbb0
--- /dev/null
+++ b/drivers/media/video/slp_db8131m_setfile.h
@@ -0,0 +1,2264 @@
+/*
+ * linux/drivers/media/video/slp_db8131m_setfile.h
+ *
+ * Copyright (c) 2012 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 version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef __DB8131M_SETFILE_H
+#define __DB8131M_SETFILE_H
+
+#include <linux/types.h>
+
+/* 1.3M mipi setting-common from PARTRON */
+/*******************************************************************/
+/* Name : DB8131M Initial Setfile*/
+/* PLL mode : MCLK=24MHz / PCLK=48MHz*/
+/* FPS : Preview 7.5~15fps / Capture 7.5fps / recording 25fps*/
+/* Date : 2011.12.06*/
+/*******************************************************************/
+
+
+static const u8 db8131m_common_1[] = {
+/***************************************************/
+/* Command Preview 7.5~15fps*/
+/***************************************************/
+0xFF, 0xC0, /*Page mode*/
+0x10, 0x01,
+};
+/*Wait 150*/
+
+static const u8 db8131m_common_2[] = {
+/***************************************************/
+/* Format*/
+/***************************************************/
+0xFF, 0xA1, /*Page mode*/
+0x70, 0x01,
+0x71, 0x0D,
+
+/***************************************************/
+/* SensorCon*/
+/***************************************************/
+0xFF, 0xD0, /*Page mode*/
+0x0F, 0x0B, /*ABLK_Ctrl_1_Addr*/
+0x13, 0x00, /*Gain_Addr*/
+0x15, 0x01, /*IVREFT_REFB_Addr*/
+0x20, 0x0E, /*ABLK_Rsrv_Addr*/
+0x23, 0x01, /*IVREFT2_REFB2_Addr*/
+0x24, 0x01, /*IPPG_IVCM2_Addr*/
+0x39, 0x70, /*RiseSx_CDS_1_L_Addr*/
+0x51, 0x19, /*Fallcreset_1_L_Addr*/
+0x83, 0x2D, /*RiseTran_Sig_Even_L_Addr*/
+0x85, 0x2F, /*FallTran_Sig_Even_L_Addr*/
+0x87, 0x2D, /*RiseTran_Sig_Odd_L_Addr*/
+0x89, 0x2F, /*FallTran_Sig_Odd_L_Addr*/
+0x8B, 0x27, /*RiseCNT_EN_1_L_Addr*/
+0x8D, 0x6c, /*FallCNT_EN_1_L_Addr*/
+0xD7, 0x80, /*ABLK_Ctrl_12_Addr*/
+0xDB, 0xA2, /*FallScanTx15_1_L_Addr*/
+0xED, 0x01, /*PLL_P_Addr*/
+0xEE, 0x0F, /*PLL_M_Addr*/
+0xEF, 0x00, /*PLL_S_Addr*/
+0xF9, 0x00, /*ABLK_Ctrl_8*/
+0xF8, 0x00, /*Vblank Sleep Mode enable*/
+0xFB, 0x90, /*PostADC_Gain_Addr*/
+
+/***************************************************/
+/* Analog ADF*/
+/***************************************************/
+0xFF, 0x85, /*Page mode*/
+0x89, 0x93, /*gAdf_u8APThreshold*/
+0x8A, 0x0C, /*u8APClmpThreshold*/
+0x8C, 0x07, /*gAdf_u8APMinVal_ThrClampH*/
+0x8D, 0x40, /*gAdf_u8APMinVal_ThrClampL*/
+0x8E, 0x03, /*gAdf_u8APMinVal_DOFFSET*/
+0x8F, 0x14, /*gAdf_u8APMinVal_AMP2_1_SDM*/
+0x91, 0x1A, /*gAdf_u8APMinVal_AMP4_3_SDM*/
+0x92, 0x0F, /*gAdf_u8APMinVal_FallIntTx15*/
+0x93, 0x47, /*gAdf_u8APMinVal_CDSxRange_CtrlPre*/
+0x95, 0x18, /*gAdf_u8APMinVal_REFB_IVCM*/
+0x96, 0x38, /*gAdf_u8APMinVal_ref_os_PB*/
+0x97, 0x0D, /*gAdf_u8APMinVal_NTx_Range*/
+0x98, 0x0D, /*gAdf_u8APMaxVal_Clmp_rst*/
+0x99, 0x06, /*gAdf_u8APMaxVal_ThrClampH*/
+0x9A, 0x9F, /*gAdf_u8APMaxVal_ThrClampL*/
+0x9B, 0x02, /*gAdf_u8APMaxVal_DOFFSET*/
+0x9C, 0x1C, /*gAdf_u8APMaxVal_AMP2_1_SDM*/
+0x9E, 0x11, /*gAdf_u8APMaxVal_AMP4_3_SDM*/
+0x9F, 0x5D, /*gAdf_u8APMaxVal_FallIntTx15*/
+0xA0, 0x78, /*gAdf_u8APMaxVal_CDSxRange_CtrlPre*/
+0xA2, 0x18, /*gAdf_u8APMaxVal_REFB_IVCM*/
+0xA3, 0x40, /*gAdf_u8APMaxVal_ref_os_PB*/
+0xA4, 0x0B, /*gAdf_u8APMaxVal_NTx_Range*/
+
+0xFF, 0x86, /*Page mode*/
+0x15, 0x00, /*gPT_u8Adf_APThrHys*/
+0x16, 0xF7, /*gPT_u8Adf_APFallIntTxThrLevel*/
+0x17, 0x13, /*gPT_u8Adf_APMinVal_BP2_1_SDM*/
+0x18, 0x13, /*gPT_u8Adf_APMidVal_BP2_1_SDM*/
+0x19, 0x1C, /*gPT_u8Adf_APMaxVal_BP2_1_SDM*/
+0x1A, 0x06, /*gPT_u8Adf_APMidVal_ThrClampH*/
+0x1B, 0xF0, /*gPT_u8Adf_APMidVal_ThrClampL*/
+0x1C, 0x01, /*gPT_u8Adf_APMidVal_DOFFSET*/
+0x1D, 0x14, /*gPT_u8Adf_APMidVal_AMP2_1_SDM*/
+0x1F, 0x31, /*gPT_u8Adf_APMidVal_AMP4_3_SDM*/
+0x20, 0x68, /*gPT_u8Adf_APMidVal_CDSxRange_CtrlPre*/
+0x22, 0x18, /*gPT_u8Adf_APMidVal_REFB_IVCM*/
+0x23, 0x38, /*gPT_u8Adf_APMidVal_ref_os_PB*/
+0x24, 0x0F, /*gPT_u8Adf_APMidVal_NTx_Range*/
+0x25, 0x77, /*gPT_u8Adf_APVal_EnSiSoSht_EnSm*/
+
+0xFF, 0x87, /*Page mode*/
+0xEA, 0x41,
+
+0xFF, 0xD0, /*Page mode*/
+0x20, 0x0D, /*ABLK_Rsrv_Addr*/
+
+0xFF, 0x83, /*Page mode*/
+0x63, 0x28, /*Again Table*/
+0x64, 0x10, /*Again Table*/
+0x65, 0xA8, /*Again Table*/
+0x66, 0x50, /*Again Table*/
+0x67, 0x28, /*Again Table*/
+0x68, 0x14, /*Again Table*/
+
+
+/***************************************************/
+/* AE*/
+/***************************************************/
+0xFF, 0x82, /*Page mode*/
+0x95, 0x88, /* AE weight*/
+0x96, 0x88,
+0x97, 0xF8,
+0x98, 0x8F,
+0x99, 0xF8,
+0x9A, 0x8F,
+0x9B, 0x88,
+0x9C, 0x88,
+0xA9, 0x40, /* OTarget*/
+0xAA, 0x40, /* ITarget*/
+0x9D, 0x66, /* AE Speed*/
+0x9F, 0x06, /* AE HoldBnd*/
+0xA8, 0x40, /* STarget*/
+0xB9, 0x04, /* RGain*/
+0xBB, 0x04, /* GGain*/
+0xBD, 0x04, /* BGain*/
+0xC5, 0x02, /* PeakMvStep*/
+0xC6, 0x38, /* PeakTgMin*/
+0xC7, 0x24, /* PeakRatioTh1*/
+0xC8, 0x10, /* PeakRatioTh0*/
+0xC9, 0x05, /* PeakLuTh*/
+0xD5, 0x60, /* LuxGainTB_2*/
+0xFF, 0x83, /*Page mode */
+0x2F, 0x04, /* TimeNum0*/
+0x30, 0x05, /* TimeNum1*/
+0x4F, 0x05, /* FrameOffset*/
+0xFF, 0x82, /*Page mode */
+0xA1, 0x0A, /* AnalogGainMax*/
+0xF3, 0x09, /* SCLK*/
+0xF4, 0x60,
+0xF9, 0x00, /* GainMax*/
+0xFA, 0xC8, /* GainMax*/
+0xFB, 0x62, /* Gain3Lut*/
+0xFC, 0x39, /* Gain2Lut*/
+0xFD, 0x28, /* Gain1Lut*/
+0xFE, 0x12, /* GainMin*/
+0xFF, 0x83, /*Page mode */
+0x03, 0x0F, /* TimeMax60Hz : 8fps*/
+0x04, 0x0A, /* Time3Lux60Hz : 12fps*/
+0x05, 0x04, /* Time2Lut60Hz : 24fps*/
+0x06, 0x04, /* Time1Lut60Hz : 24fps*/
+0xFF, 0x82, /*Page mode */
+0xD3, 0x12, /* LuxTBGainStep0 */
+0xD4, 0x36, /* LuxTBGainStep1 */
+0xD5, 0x60, /* LuxTBGainStep2*/
+0xD6, 0x01, /* LuxTBTimeStep0H*/
+0xD7, 0x00, /* LuxTBTimeStep0L*/
+0xD8, 0x01, /* LuxTBTimeStep1H*/
+0xD9, 0xC0, /* LuxTBTimeStep1L*/
+0xDA, 0x06, /* LuxTBTimeStep2H*/
+0xDB, 0x00, /* LuxTBTimeStep2L*/
+0xFF, 0x83, /*Page mode */
+0x0B, 0x04,
+0x0C, 0x4C, /* Frame Rate*/
+0xFF, 0x82, /*Page mode */
+0x92, 0x5D,
+
+/***************************************************/
+/* AWB*/
+/***************************************************/
+0xFF, 0x83, /*Page mode */
+0x79, 0x83, /* AWB SKIN ON*/
+0x86, 0x07, /* gAWB_u16MinGrayCnt_rw_0*/
+0x87, 0x00, /* gAWB_u16MinGrayCnt_rw_1*/
+0x90, 0x05, /* gAWB_u16FinalRGain_ro_0*/
+0x94, 0x05, /* gAWB_u16FinalBGain_ro_0*/
+0x98, 0xD4, /* SkinWinCntTh*/
+0xA2, 0x28, /* SkinYTh*/
+0xA3, 0x00, /* SkinHoldHitCnt*/
+0xA4, 0x0F, /* SkinHoldHitCnt*/
+0xAD, 0x65, /* u8SkinTop2*/
+0xAE, 0x80, /* gAwb_u8SkinTop2LS1Ratio_rw 5zone*/
+0xAF, 0x20, /* gAwb_u8SkinTop2LS2Ratio_rw 6zone */
+0xB4, 0x10, /* u8SkinTop2LSHys_rw*/
+0xB5, 0x54, /* gAwb_u8SkinLTx*/
+0xB6, 0xbd, /* gAwb_u8SkinLTy*/
+0xB7, 0x74, /* gAwb_u8SkinRBx*/
+0xB8, 0x9d, /* gAwb_u8SkinRBy*/
+0xBA, 0x4F, /* UniCThrY_rw*/
+0xBF, 0x0C, /* u16UniCGrayCntThr_rw_0*/
+0xC0, 0x80, /* u16UniCGrayCntThr_rw_1*/
+0xFF, 0x87, /*Page mode */
+0xC9, 0x22, /* gUR_u8AWBTrim_Addr*/
+0xFF, 0x84, /*Page mode */
+0x49, 0x02, /* Threshold_indoor*/
+0x4A, 0x00,
+0x4B, 0x03, /* Threshold_outdoor*/
+0x4C, 0x80,
+0xFF, 0x83, /*Page mode */
+0xCB, 0x03, /* R MinGain [Default 0X20] A Spec Pass */
+0xCC, 0xC0, /* R MinGain [Default 0X20] A Spec Pass */
+0x82, 0x00, /* lockratio*/
+0xFF, 0x84, /*Page mode */
+0x3D, 0x00, /* gAwb_u32LuxConst1_rw_0*/
+0x3E, 0x00, /* gAwb_u32LuxConst1_rw_1*/
+0x3F, 0x06, /* gAwb_u32LuxConst1_rw_2*/
+0x40, 0x20, /* gAwb_u32LuxConst1_rw_3*/
+0x41, 0x07, /* gAwb_u32LuxConst2_rw_0*/
+0x42, 0x53, /* gAwb_u32LuxConst2_rw_1*/
+0x43, 0x00, /* gAwb_u32LuxConst2_rw_2*/
+0x44, 0x00, /* gAwb_u32LuxConst2_rw_3*/
+0x55, 0x03, /* gAwb_u8Weight_Gen_rw_0 */
+0x56, 0x10, /* gAwb_u8Weight_Gen_rw_1 */
+0x57, 0x14, /* gAwb_u8Weight_Gen_rw_2 */
+0x58, 0x07, /* gAwb_u8Weight_Gen_rw_3 */
+0x59, 0x04, /* gAwb_u8Weight_Gen_rw_4 */
+0x5A, 0x03, /* gAwb_u8Weight_Gen_rw_5 */
+0x5B, 0x03, /* gAwb_u8Weight_Gen_rw_6 */
+0x5C, 0x15, /* gAwb_u8Weight_Gen_rw_7 */
+0x5D, 0x01, /* gAwb_u8Weight_Ind_rw_0 */
+0x5E, 0x0F, /* gAwb_u8Weight_Ind_rw_1 */
+0x5F, 0x07, /* gAwb_u8Weight_Ind_rw_2 */
+0x60, 0x14, /* gAwb_u8Weight_Ind_rw_3 */
+0x61, 0x14, /* gAwb_u8Weight_Ind_rw_4 */
+0x62, 0x12, /* gAwb_u8Weight_Ind_rw_5 */
+0x63, 0x11, /* gAwb_u8Weight_Ind_rw_6 */
+0x64, 0x14, /* gAwb_u8Weight_Ind_rw_7 */
+0x65, 0x03, /* gAwb_u8Weight_Outd_rw_0*/
+0x66, 0x05, /* gAwb_u8Weight_Outd_rw_1*/
+0x67, 0x15, /* gAwb_u8Weight_Outd_rw_2*/
+0x68, 0x04, /* gAwb_u8Weight_Outd_rw_3*/
+0x69, 0x01, /* gAwb_u8Weight_Outd_rw_4*/
+0x6A, 0x02, /* gAwb_u8Weight_Outd_rw_5*/
+0x6B, 0x03, /* gAwb_u8Weight_Outd_rw_6*/
+0x6C, 0x15, /* gAwb_u8Weight_Outd_rw_6*/
+0xFF, 0x85, /*Page mode */
+0xE2, 0x0C, /* gPT_u8Awb_UnicolorZone_rw */
+0xFF, 0x83, /*Page mode */
+0xCD, 0x06, /*Max Rgain*/
+0xCE, 0x80,
+0xD1, 0x06, /*Max BGain*/
+0xd2, 0x80,
+
+/***************************************************/
+/* AWB STE*/
+/***************************************************/
+0xFF, 0xA1, /*Page mode */
+/*Flash*/
+0xA0, 0x5c, /*AWBZone0LTx*/
+0xA1, 0x7a, /*AWBZone0LTy*/
+0xA2, 0x69, /*AWBZone0RBx*/
+0xA3, 0x6f, /*AWBZone0RBy*/
+/*cloudy*/
+0xA4, 0x73, /*AWBZone1LTx*/
+0xA5, 0x55, /*AWBZone1LTy*/
+0xA6, 0x8C, /*AWBZone1RBx*/
+0xA7, 0x30, /*AWBZone1RBy */
+/*Daylight */
+0xA8, 0x69, /*AWBZone2LTx*/
+0xA9, 0x69, /*AWBZone2LTy*/
+0xAA, 0x83, /*AWBZone2RBx*/
+0xAB, 0x52, /*AWBZone2RBy */
+/*Fluorescent */
+0xAC, 0x57, /*AWBZone3LTx*/
+0xAD, 0x6e, /*AWBZone3LTy*/
+0xAE, 0x6f, /*AWBZone3RBx*/
+0xAF, 0x59, /*AWBZone3RBy*/
+
+/*CWF */
+0xB0, 0x50, /*AWBZone4LTx*/
+0xB1, 0x74, /*AWBZone4LTy*/
+0xB2, 0x65, /*AWBZone4RBx*/
+0xB3, 0x5d, /*AWBZone4RBy*/
+/*TL84 */
+0xB4, 0x53, /*AWBZone5LTx*/
+0xB5, 0x7f, /*AWBZone5LTy*/
+0xB6, 0x62, /*AWBZone5RBx*/
+0xB7, 0x75, /*AWBZone5RBy */
+/*A */
+0xB8, 0x4a, /*AWBZone6LTx*/
+0xB9, 0x87, /*AWBZone6LTy*/
+0xBA, 0x59, /*AWBZone6RBx*/
+0xBB, 0x78, /*AWBZone6RBy*/
+/*Horizon */
+0xBC, 0x41, /*AWBZone7LTx*/
+0xBD, 0x91, /*AWBZone7LTy*/
+0xBE, 0x4b, /*AWBZone7RBx*/
+0xBF, 0x89, /*AWBZone7RBy*/
+/*Skin */
+0xC0, 0x5b, /*AWBZone8LTx*/
+0xC1, 0x85, /*AWBZone8LTy*/
+0xC2, 0x60, /*AWBZone8RBx*/
+0xC3, 0x7b, /*AWBZone8RBy*/
+
+/***************************************************/
+/* UR*/
+/***************************************************/
+0xFF, 0x85, /*Page mode */
+0x06, 0x05,
+0xFF, 0x86, /*Page mode */
+0x14, 0x1E, /* CCM sum 1*/
+0xFF, 0x85, /*Page mode */
+0x86, 0x42, /* 42 saturation level*/
+0x07, 0x00, /* sup hysteresis*/
+
+/*DAY light */
+0xFF, 0x83, /*Page mode */
+0xEA, 0x00, /*gAwb_s16AdapCCMTbl_0*/
+0xEB, 0x53, /*gAwb_s16AdapCCMTbl_1*/
+0xEC, 0xFF, /*gAwb_s16AdapCCMTbl_2*/
+0xED, 0xE1, /*gAwb_s16AdapCCMTbl_3*/
+0xEE, 0x00, /*gAwb_s16AdapCCMTbl_4*/
+0xEF, 0x05, /*gAwb_s16AdapCCMTbl_5*/
+0xF0, 0xFF, /*gAwb_s16AdapCCMTbl_6*/
+0xF1, 0xF3, /*gAwb_s16AdapCCMTbl_7*/
+0xF2, 0x00, /*gAwb_s16AdapCCMTbl_8*/
+0xF3, 0x4B, /*gAwb_s16AdapCCMTbl_9*/
+0xF4, 0xFF, /*gAwb_s16AdapCCMTbl_10*/
+0xF5, 0xFA, /*gAwb_s16AdapCCMTbl_11*/
+0xF6, 0xFF, /*gAwb_s16AdapCCMTbl_12*/
+0xF7, 0xFa, /*gAwb_s16AdapCCMTbl_13*/
+0xF8, 0xFF, /*gAwb_s16AdapCCMTbl_14*/
+0xF9, 0xC3, /*gAwb_s16AdapCCMTbl_15*/
+0xFA, 0x00, /*gAwb_s16AdapCCMTbl_16*/
+0xFB, 0x80, /*gAwb_s16AdapCCMTbl_17*/
+
+/*CWF lgiht */
+0xFF, 0x83, /*Page mode*/
+0xFC, 0x00, /* gAwb_s16AdapCCMTbl_18 */
+0xFD, 0x68, /* gAwb_s16AdapCCMTbl_19 */
+0xFF, 0x85, /*Page mode */
+0xE0, 0xFF, /* gAwb_s16AdapCCMTbl_20 */
+0xE1, 0xde, /* gAwb_s16AdapCCMTbl_21 */
+0xFF, 0x84, /*Page mode */
+0x00, 0xff, /* gAwb_s16AdapCCMTbl_22 */
+0x01, 0xfa, /* gAwb_s16AdapCCMTbl_23 */
+0x02, 0xFF, /* gAwb_s16AdapCCMTbl_24 */
+0x03, 0xf0, /* gAwb_s16AdapCCMTbl_25 */
+0x04, 0x00, /* gAwb_s16AdapCCMTbl_26 */
+0x05, 0x52, /* gAwb_s16AdapCCMTbl_27 */
+0x06, 0xFF, /* gAwb_s16AdapCCMTbl_28 */
+0x07, 0xFa, /* gAwb_s16AdapCCMTbl_29 */
+0x08, 0x00, /* gAwb_s16AdapCCMTbl_30 */
+0x09, 0x00, /* gAwb_s16AdapCCMTbl_31 */
+0x0A, 0xFF, /* gAwb_s16AdapCCMTbl_32 */
+0x0B, 0xdb, /* gAwb_s16AdapCCMTbl_33 */
+0x0C, 0x00, /* gAwb_s16AdapCCMTbl_34 */
+0x0D, 0x68, /* gAwb_s16AdapCCMTbl_35 */
+
+/*A light */
+
+0x0E, 0x00, /* gAwb_s16AdapCCMTbl_36 */
+0x0F, 0x6d, /* gAwb_s16AdapCCMTbl_37 */
+0x10, 0xFF, /* gAwb_s16AdapCCMTbl_38 */
+0x11, 0xd5, /* gAwb_s16AdapCCMTbl_39 */
+0x12, 0xff, /* gAwb_s16AdapCCMTbl_40 */
+0x13, 0xfe, /* gAwb_s16AdapCCMTbl_41 */
+0x14, 0xFF, /* gAwb_s16AdapCCMTbl_42 */
+0x15, 0xf4, /* gAwb_s16AdapCCMTbl_43 */
+0x16, 0x00, /* gAwb_s16AdapCCMTbl_44 */
+0x17, 0x5a, /* gAwb_s16AdapCCMTbl_45 */
+0x18, 0xff, /* gAwb_s16AdapCCMTbl_46 */
+0x19, 0xef, /* gAwb_s16AdapCCMTbl_47 */
+0x1A, 0xff, /* gAwb_s16AdapCCMTbl_48 */
+0x1B, 0xfa, /* gAwb_s16AdapCCMTbl_49 */
+0x1C, 0xFF, /* gAwb_s16AdapCCMTbl_50 */
+0x1D, 0xbe, /* gAwb_s16AdapCCMTbl_51 */
+0x1E, 0x00, /* gAwb_s16AdapCCMTbl_52 */
+0x1F, 0x86, /* gAwb_s16AdapCCMTbl_53 */
+
+
+/***************************************************/
+/* ADF*/
+/***************************************************/
+
+/* ISP setting*/
+0xFF, 0xA0, /*Page mode */
+0x10, 0x80, /* BLC: ABLC db*/
+0x60, 0x73, /* CDC: Dark CDC ON */
+0x61, 0x1F, /* Six CDC_Edge En, Slash EN*/
+0x69, 0x0C, /* Slash direction Line threshold*/
+0x6A, 0x60, /* Slash direction Pixel threshold*/
+0xC2, 0x04, /* NSF: directional smoothing*/
+0xD0, 0x51, /* DEM: pattern detection*/
+0xFF, 0xA1, /*Page mode */
+0x30, 0x01, /* EDE: Luminane adaptation on*/
+0x32, 0x50, /* EDE: Adaptation slope */
+0x34, 0x00, /* EDE: x1 point */
+0x35, 0x0B, /* EDE: x1 point */
+0x36, 0x01, /* EDE: x2 point */
+0x37, 0x80, /* EDE: x2 point */
+0x3A, 0x00, /* EDE: Adaptation left margin*/
+0x3B, 0x30, /* EDE: Adaptation right margin*/
+0x3C, 0x08, /* EDE: rgb edge threshol*/
+
+/* Adaptive Setting*/
+0xFF, 0x85, /*Page mode */
+/* LSC*/
+0x0F, 0x43, /* LVLSC lux level threshold*/
+0x10, 0x43, /* LSLSC Light source , threshold lux*/
+
+/* BGT*/
+0x17, 0x30, /* BGT lux level threshold*/
+0x26, 0x20, /* MinVal */
+0x3c, 0x00, /* MaxVal */
+
+/* CNT*/
+0x18, 0x43, /* CNT lux level threshold*/
+0x27, 0x00, /* MinVal */
+0x3d, 0x00, /* MaxVal */
+
+/* NSF */
+0x12, 0xA5, /* NSF lux level threshold */
+0x22, 0x38, /* u8MinVal_NSF1*/
+0x23, 0x70, /* u8MinVal_NSF2*/
+0xFF, 0x86, /*Page mode */
+0x12, 0x00, /* u8MinVal_NSF3*/
+0xFF, 0x85, /*Page mode */
+0x38, 0x12, /* u8MaxVal_NSF1*/
+0x39, 0x30, /* u8MaxVal_NSF2*/
+0xFF, 0x86, /*Page mode */
+0x13, 0x08, /* u8MaxVal_NSF3*/
+
+/* GDC*/
+0xFF, 0x85, /*Page mode */
+0x15, 0xF4, /* GDC lux level threshold */
+0x2D, 0x20, /* u8MinVal_GDC1*/
+0x2E, 0x30, /* u8MinVal_GDC2*/
+0x43, 0x40, /* u8MaxVal_GDC1*/
+0x44, 0x80, /* u8MaxVal_GDC2*/
+
+/* ISP Edge*/
+0x04, 0xFB, /* EnEDE*/
+0x14, 0x54, /* u8ThrLevel_EDE*/
+0x28, 0x00, /* u8MinVal_EDE_CP*/
+0x29, 0x03, /* u8MinVal_EDE1*/
+0x2A, 0x20, /* u8MinVal_EDE2*/
+0x2B, 0x00, /* u8MinVal_EDE_OFS*/
+0x2C, 0x22, /* u8MinVal_SG*/
+0x3E, 0x00, /* u8MaxVal_EDE_CP*/
+0x3F, 0x09, /* u8MaxVal_EDE1*/
+0x40, 0x22, /* u8MaxVal_EDE2*/
+0x41, 0x02, /* u8MaxVal_EDE_OFS*/
+0x42, 0x33, /* u8MaxVal_SG*/
+
+/* Gamma Adaptive*/
+
+0x16, 0xA0, /* Gamma Threshold*/
+0x47, 0x00, /* Min_Gamma_0*/
+0x48, 0x03, /* Min_Gamma_1*/
+0x49, 0x10, /* Min_Gamma_2*/
+0x4A, 0x25, /* Min_Gamma_3*/
+0x4B, 0x3B, /* Min_Gamma_4*/
+0x4C, 0x4F, /* Min_Gamma_5*/
+0x4D, 0x6D, /* Min_Gamma_6*/
+0x4E, 0x86, /* Min_Gamma_7*/
+0x4F, 0x9B, /* Min_Gamma_8*/
+0x50, 0xAD, /* Min_Gamma_9*/
+0x51, 0xC2, /* Min_Gamma_10*/
+0x52, 0xD3, /* Min_Gamma_11*/
+0x53, 0xE1, /* Min_Gamma_12*/
+0x54, 0xE9, /* Min_Gamma_13*/
+0x55, 0xF2, /* Min_Gamma_14*/
+0x56, 0xFA, /* Min_Gamma_15*/
+0x57, 0xFF, /* Min_Gamma_16*/
+0x58, 0x00, /* Max_Gamma_0 */
+0x59, 0x06, /* Max_Gamma_1 */
+0x5a, 0x14, /* Max_Gamma_2 */
+0x5b, 0x30, /* Max_Gamma_3 */
+0x5c, 0x4A, /* Max_Gamma_4 */
+0x5d, 0x5D, /* Max_Gamma_5 */
+0x5e, 0x75, /* Max_Gamma_6 */
+0x5f, 0x89, /* Max_Gamma_7 */
+0x60, 0x9A, /* Max_Gamma_8 */
+0x61, 0xA7, /* Max_Gamma_9 */
+0x62, 0xBC, /* Max_Gamma_10 */
+0x63, 0xD0, /* Max_Gamma_11 */
+0x64, 0xE0, /* Max_Gamma_12 */
+0x65, 0xE7, /* Max_Gamma_13 */
+0x66, 0xEE, /* Max_Gamma_14 */
+0x67, 0xF7, /* Max_Gamma_15 */
+0x68, 0xFF, /* Max_Gamma_16 */
+
+/* Initial edge, noise filter setting*/
+0xFF, 0xA0, /*Page mode */
+0xC0, 0x12, /*NSFTh1_Addr*/
+0xC1, 0x30, /*NSFTh2_Addr*/
+0xC2, 0x08, /*NSFTh3_Addr*/
+0xFF, 0xA1, /*Page mode */
+0x30, 0x01, /*EDEOption_Addr*/
+0x31, 0x33, /*EDESlopeGain_Addr*/
+0x32, 0x50, /*EDELuAdpCtrl_Addr*/
+0x33, 0x00, /*EDEPreCoringPt_Addr*/
+0x34, 0x00, /*EDETransFuncXp1_Addr1*/
+0x35, 0x0B, /*EDETransFuncXp1_Addr0*/
+0x36, 0x01, /*EDETransFuncXp2_Addr1*/
+0x37, 0x80, /*EDETransFuncXp2_Addr0*/
+0x38, 0x09, /*EDETransFuncSl1_Addr*/
+0x39, 0x22, /*EDETransFuncSl2_Addr*/
+0x3A, 0x00, /*EDELuAdpLOffset_Addr*/
+0x3B, 0x30, /*EDELuAdpROffset_Addr*/
+0x3C, 0x08, /*EDERBThrd_Addr*/
+0x3D, 0x02, /*EDESmallOffset_Addr*/
+
+
+/* CCM Saturation Level*/
+0xFF, 0x85, /*Page mode */
+0x1A, 0x64, /* SUP Threshold */
+0x30, 0x40, /* MinSUP */
+
+0xFF, 0xA0, /*Page mode */
+/* Lens Shading*/
+0x43, 0x80, /* RH7 rrhrhh*/
+0x44, 0x80, /* RV*/
+0x45, 0x80, /* RH */
+0x46, 0x80, /* RV*/
+0x47, 0x80, /* GH*/
+0x48, 0x80, /* GV*/
+0x49, 0x80, /* GH*/
+0x4A, 0x80, /* GV */
+0x4B, 0x80, /* BH*/
+0x4C, 0x80, /* BV*/
+0x4D, 0x80, /* BH*/
+0x4E, 0x80, /* BV */
+0x52, 0x90, /* GGain*/
+0x53, 0x20, /* GGain*/
+0x54, 0x00, /* GGain*/
+
+/*Max Shading*/
+0xFF, 0x85, /*Page mode */
+0x32, 0xC0,
+0x33, 0x30,
+0x34, 0x00,
+0x35, 0x90,
+0x36, 0x20,
+0x37, 0x00,
+
+/*Min Shading*/
+0x1c, 0xC0,
+0x1d, 0x30,
+0x1e, 0x00,
+0x1f, 0x90,
+0x20, 0x18,
+0x21, 0x00,
+
+/* LineLength */
+0xFF, 0x87, /*Page mode */
+0xDC, 0x05, /* by Yong In Han 091511*/
+0xDD, 0xB0, /* by Yong In Han 091511*/
+0xd5, 0x00, /* Flip*/
+/***************************************************/
+/* SensorCon */
+/***************************************************/
+0xFF, 0xD0, /*Page mode */
+0x20, 0x0E, /* ABLK_Rsrv_Addr*/
+0x20, 0x0D, /* ABLK_Rsrv_Addr*/
+
+/***************************************************/
+/* MIPI */
+/***************************************************/
+0xFF, 0xB0, /*Page mode */
+0x54, 0x02, /* MIPI PHY_HS_TX_CTRL*/
+0x38, 0x05, /* MIPI DPHY_CTRL_SET*/
+
+
+/* SXGA PR*/
+0xFF, 0x85, /*Page mode */
+0xB8, 0x0A, /* gPT_u8PR_Active_SXGA_WORD_COUNT_Addr0*/
+0xB9, 0x00, /* gPT_u8PR_Active_SXGA_WORD_COUNT_Addr1*/
+0xBC, 0x04, /* gPT_u8PR_Active_SXGA_DPHY_CLK_TIME_Addr3*/
+0xFF, 0x87, /*Page mode */
+0x0C, 0x00, /* start Y*/
+0x0D, 0x20, /* start Y */
+0x10, 0x03, /* end Y*/
+0x11, 0xE0, /* end Y */
+
+/* Recoding */
+0xFF, 0x86, /*Page mode */
+0x38, 0x05, /* gPT_u8PR_Active_720P_WORD_COUNT_Addr0*/
+0x39, 0x00, /* gPT_u8PR_Active_720P_WORD_COUNT_Addr1*/
+0x3C, 0x04, /* gPT_u8PR_Active_720P_DPHY_CLK_TIME_Addr3*/
+
+0xFF, 0x87,
+0x23, 0x02, /*gPR_Active_720P_u8SensorCtrl_Addr */
+0x25, 0x01, /*gPR_Active_720P_u8PLL_P_Addr */
+0x26, 0x0F, /*gPR_Active_720P_u8PLL_M_Addr */
+0x27, 0x00, /*gPR_Active_720P_u8PLL_S_Addr */
+0x28, 0x00, /*gPR_Active_720P_u8PLL_Ctrl_Addr */
+0x29, 0x01, /*gPR_Active_720P_u8src_clk_sel_Addr */
+0x2A, 0x00, /*gPR_Active_720P_u8output_pad_status_Addr */
+0x2B, 0x3F, /*gPR_Active_720P_u8ablk_ctrl_10_Addr */
+0x2C, 0xFF, /*gPR_Active_720P_u8BayerFunc_Addr */
+0x2D, 0xFF, /*gPR_Active_720P_u8RgbYcFunc_Addr */
+0x2E, 0x00, /*gPR_Active_720P_u8ISPMode_Addr */
+0x2F, 0x02, /*gPR_Active_720P_u8SCLCtrl_Addr */
+0x30, 0x01, /*gPR_Active_720P_u8SCLHorScale_Addr0 */
+0x31, 0xFF, /*gPR_Active_720P_u8SCLHorScale_Addr1 */
+0x32, 0x03, /*gPR_Active_720P_u8SCLVerScale_Addr0 */
+0x33, 0xFF, /*gPR_Active_720P_u8SCLVerScale_Addr1 */
+0x34, 0x00, /*gPR_Active_720P_u8SCLCropStartX_Addr0 */
+0x35, 0x00, /*gPR_Active_720P_u8SCLCropStartX_Addr1 */
+0x36, 0x00, /*gPR_Active_720P_u8SCLCropStartY_Addr0 */
+0x37, 0x10, /*gPR_Active_720P_u8SCLCropStartY_Addr1 */
+0x38, 0x02, /*gPR_Active_720P_u8SCLCropEndX_Addr0 */
+0x39, 0x80, /*gPR_Active_720P_u8SCLCropEndX_Addr1 */
+0x3A, 0x01, /*gPR_Active_720P_u8SCLCropEndY_Addr0 */
+0x3B, 0xF0, /*gPR_Active_720P_u8SCLCropEndY_Addr1 */
+0x3C, 0x01, /*gPR_Active_720P_u8OutForm_Addr */
+0x3D, 0x0C, /*gPR_Active_720P_u8OutCtrl_Addr */
+0x3E, 0x04, /*gPR_Active_720P_u8AEWinStartX_Addr */
+0x3F, 0x04, /*gPR_Active_720P_u8AEWinStartY_Addr */
+0x40, 0x66, /*gPR_Active_720P_u8MergedWinWidth_Addr */
+0x41, 0x5E, /*gPR_Active_720P_u8MergedWinHeight_Addr */
+0x42, 0x04, /*gPR_Active_720P_u8AEHistWinAx_Addr */
+0x43, 0x04, /*gPR_Active_720P_u8AEHistWinAy_Addr */
+0x44, 0x98, /*gPR_Active_720P_u8AEHistWinBx_Addr */
+0x45, 0x78, /*gPR_Active_720P_u8AEHistWinBy_Addr */
+0x46, 0x22, /*gPR_Active_720P_u8AWBTrim_Addr */
+0x47, 0x28, /*gPR_Active_720P_u8AWBCTWinAx_Addr */
+0x48, 0x20, /*gPR_Active_720P_u8AWBCTWinAy_Addr */
+0x49, 0x78, /*gPR_Active_720P_u8AWBCTWinBx_Addr */
+0x4A, 0x60, /*gPR_Active_720P_u8AWBCTWinBy_Addr */
+0x4B, 0x03, /*gPR_Active_720P_u16AFCFrameLength_0 */
+0x4C, 0x00, /*gPR_Active_720P_u16AFCFrameLength_1 */
+
+/* VGA PR */
+0xFF, 0x86, /*Page mode */
+0x2F, 0x05, /* gPT_u8PR_Active_VGA_WORD_COUNT_Addr0*/
+0x30, 0x00, /* gPT_u8PR_Active_VGA_WORD_COUNT_Addr1*/
+0x33, 0x04, /* gPT_u8PR_Active_VGA_DPHY_CLK_TIME_Addr3*/
+
+0xFF, 0x87, /*Page mode */
+0x4D, 0x00, /*gPR_Active_VGA_u8SensorCtrl_Addr*/
+0x4E, 0x72, /*gPR_Active_VGA_u8SensorMode_Addr*/
+0x4F, 0x01, /*gPR_Active_VGA_u8PLL_P_Addr*/
+0x50, 0x0F, /*gPR_Active_VGA_u8PLL_M_Addr*/
+0x51, 0x00, /*gPR_Active_VGA_u8PLL_S_Addr*/
+0x52, 0x00, /*gPR_Active_VGA_u8PLL_Ctrl_Addr*/
+0x53, 0x01, /*gPR_Active_VGA_u8src_clk_sel_Addr*/
+0x54, 0x00, /*gPR_Active_VGA_u8output_pad_status_Addr*/
+0x55, 0x3F, /*gPR_Active_VGA_u8ablk_ctrl_10_Addr*/
+0x56, 0xFF, /*gPR_Active_VGA_u8BayerFunc_Addr*/
+0x57, 0xFF, /*gPR_Active_VGA_u8RgbYcFunc_Addr*/
+0x58, 0x00, /*gPR_Active_VGA_u8ISPMode_Addr*/
+0x59, 0x02, /*gPR_Active_VGA_u8SCLCtrl_Addr*/
+0x5A, 0x01, /*gPR_Active_VGA_u8SCLHorScale_Addr0*/
+0x5B, 0xFF, /*gPR_Active_VGA_u8SCLHorScale_Addr1*/
+0x5C, 0x01, /*gPR_Active_VGA_u8SCLVerScale_Addr0*/
+0x5D, 0xFF, /*gPR_Active_VGA_u8SCLVerScale_Addr1*/
+0x5E, 0x00, /*gPR_Active_VGA_u8SCLCropStartX_Addr0*/
+0x5F, 0x00, /*gPR_Active_VGA_u8SCLCropStartX_Addr1*/
+0x60, 0x00, /*gPR_Active_VGA_u8SCLCropStartY_Addr0*/
+0x61, 0x20, /*gPR_Active_VGA_u8SCLCropStartY_Addr1*/
+0x62, 0x05, /*gPR_Active_VGA_u8SCLCropEndX_Addr0*/
+0x63, 0x00, /*gPR_Active_VGA_u8SCLCropEndX_Addr1*/
+0x64, 0x03, /*gPR_Active_VGA_u8SCLCropEndY_Addr0*/
+0x65, 0xE0, /*gPR_Active_VGA_u8SCLCropEndY_Addr1*/
+
+0xFF, 0xd1, /*Page mode */
+0x07, 0x00, /* power off mask clear*/
+0x0b, 0x00, /* clock off mask clear*/
+0xFF, 0xC0, /*Page mode */
+0x10, 0x41,
+
+/* Self-Cam END of Initial */
+};
+
+/* Set-data based on SKT VT standard ,when using 3G network*/
+/* VGA 8fps
+*/
+static const u8 db8131m_vt_common_1[] = {
+/***************************************************/
+/* Device : DB8131M fixed 8Fps */
+/* MIPI Interface for Noncontious Clock */
+/***************************************************/
+/***************************************************/
+/* Command */
+/***************************************************/
+0xFF, 0xC0, /*Page mode*/
+0x10, 0x01,
+};
+/*wait 150*/
+
+static const u8 db8131m_vt_common_2[] = {
+/***************************************************/
+/* Format */
+/***************************************************/
+0xFF, 0xA1, /*Page mode */
+0x70, 0x01,
+0x71, 0x0D,
+
+/***************************************************/
+/* SensorCon */
+/***************************************************/
+0xFF, 0xD0, /*Page mode */
+0x0F, 0x0B, /*ABLK_Ctrl_1_Addr*/
+0x13, 0x00, /*Gain_Addr*/
+0x15, 0x01, /*IVREFT_REFB_Addr*/
+0x20, 0x0E, /*ABLK_Rsrv_Addr*/
+0x23, 0x01, /*IVREFT2_REFB2_Addr*/
+0x24, 0x01, /*IPPG_IVCM2_Addr*/
+0x39, 0x70, /*RiseSx_CDS_1_L_Addr*/
+0x51, 0x19, /*Fallcreset_1_L_Addr*/
+0x83, 0x2D, /*RiseTran_Sig_Even_L_Addr*/
+0x85, 0x2F, /*FallTran_Sig_Even_L_Addr*/
+0x87, 0x2D, /*RiseTran_Sig_Odd_L_Addr*/
+0x89, 0x2F, /*FallTran_Sig_Odd_L_Addr*/
+0x8B, 0x27, /*RiseCNT_EN_1_L_Addr*/
+0x8D, 0x6c, /*FallCNT_EN_1_L_Addr*/
+0xD7, 0x80, /*ABLK_Ctrl_12_Addr*/
+0xDB, 0xA2, /*FallScanTx15_1_L_Addr*/
+0xED, 0x01, /*PLL_P_Addr*/
+0xEE, 0x0F, /*PLL_M_Addr*/
+0xEF, 0x00, /*PLL_S_Addr*/
+0xF9, 0x00, /*ABLK_Ctrl_8*/
+0xF8, 0x00, /*Vblank Sleep Mode enable*/
+0xFB, 0x90, /*PostADC_Gain_Addr*/
+
+/***************************************************/
+/* Analog ADF */
+/***************************************************/
+0xFF, 0x85, /*Page mode */
+0x89, 0x93, /*gAdf_u8APThreshold*/
+0x8A, 0x0C, /*u8APClmpThreshold*/
+0x8C, 0x07, /*gAdf_u8APMinVal_ThrClampH*/
+0x8D, 0x40, /*gAdf_u8APMinVal_ThrClampL*/
+0x8E, 0x03, /*gAdf_u8APMinVal_DOFFSET*/
+0x8F, 0x14, /*gAdf_u8APMinVal_AMP2_1_SDM*/
+0x91, 0x1A, /*gAdf_u8APMinVal_AMP4_3_SDM*/
+0x92, 0x0F, /*gAdf_u8APMinVal_FallIntTx15*/
+0x93, 0x47, /*gAdf_u8APMinVal_CDSxRange_CtrlPre*/
+0x95, 0x18, /*gAdf_u8APMinVal_REFB_IVCM*/
+0x96, 0x38, /*gAdf_u8APMinVal_ref_os_PB*/
+0x97, 0x0D, /*gAdf_u8APMinVal_NTx_Range*/
+0x98, 0x0D, /*gAdf_u8APMaxVal_Clmp_rst*/
+0x99, 0x06, /*gAdf_u8APMaxVal_ThrClampH*/
+0x9A, 0x9F, /*gAdf_u8APMaxVal_ThrClampL*/
+0x9B, 0x02, /*gAdf_u8APMaxVal_DOFFSET*/
+0x9C, 0x1C, /*gAdf_u8APMaxVal_AMP2_1_SDM*/
+0x9E, 0x11, /*gAdf_u8APMaxVal_AMP4_3_SDM*/
+0x9F, 0x5D, /*gAdf_u8APMaxVal_FallIntTx15*/
+0xA0, 0x78, /*gAdf_u8APMaxVal_CDSxRange_CtrlPre*/
+0xA2, 0x18, /*gAdf_u8APMaxVal_REFB_IVCM*/
+0xA3, 0x40, /*gAdf_u8APMaxVal_ref_os_PB*/
+0xA4, 0x0B, /*gAdf_u8APMaxVal_NTx_Range*/
+
+0xFF, 0x86, /*Page mode */
+0x15, 0x00, /*gPT_u8Adf_APThrHys*/
+0x16, 0xF7, /*gPT_u8Adf_APFallIntTxThrLevel*/
+0x17, 0x13, /*gPT_u8Adf_APMinVal_BP2_1_SDM*/
+0x18, 0x13, /*gPT_u8Adf_APMidVal_BP2_1_SDM*/
+0x19, 0x1C, /*gPT_u8Adf_APMaxVal_BP2_1_SDM*/
+0x1A, 0x06, /*gPT_u8Adf_APMidVal_ThrClampH*/
+0x1B, 0xF0, /*gPT_u8Adf_APMidVal_ThrClampL*/
+0x1C, 0x01, /*gPT_u8Adf_APMidVal_DOFFSET*/
+0x1D, 0x14, /*gPT_u8Adf_APMidVal_AMP2_1_SDM*/
+0x1F, 0x31, /*gPT_u8Adf_APMidVal_AMP4_3_SDM*/
+0x20, 0x68, /*gPT_u8Adf_APMidVal_CDSxRange_CtrlPre*/
+0x22, 0x18, /*gPT_u8Adf_APMidVal_REFB_IVCM*/
+0x23, 0x38, /*gPT_u8Adf_APMidVal_ref_os_PB*/
+0x24, 0x0F, /*gPT_u8Adf_APMidVal_NTx_Range*/
+0x25, 0x77, /*gPT_u8Adf_APVal_EnSiSoSht_EnSm*/
+
+0xFF, 0x87, /*Page mode */
+0xEA, 0x41,
+
+0xFF, 0xD0, /*Page mode */
+0x20, 0x0D, /*ABLK_Rsrv_Addr*/
+
+0xFF, 0x83, /*Page mode */
+0x63, 0x28, /*Again Table*/
+0x64, 0x10, /*Again Table*/
+0x65, 0xA8, /*Again Table*/
+0x66, 0x50, /*Again Table*/
+0x67, 0x28, /*Again Table*/
+0x68, 0x14, /*Again Table*/
+
+
+/***************************************************/
+/* AE */
+/***************************************************/
+0xFF, 0x82, /*Page mode */
+0x91, 0x02, /* AeMode*/
+0x95, 0x88, /* AE weight*/
+0x96, 0x88,
+0x97, 0xF8,
+0x98, 0x8F,
+0x99, 0xF8,
+0x9A, 0x8F,
+0x9B, 0x88,
+0x9C, 0x88,
+0xA9, 0x40, /* OTarget*/
+0xAA, 0x40, /* ITarget*/
+0x9D, 0x66, /* AE Speed*/
+0x9F, 0x06, /* AE HoldBnd*/
+0xA8, 0x40, /* STarget*/
+0xB9, 0x04, /* RGain*/
+0xBB, 0x04, /* GGain*/
+0xBD, 0x04, /* BGain*/
+0xC5, 0x02, /* PeakMvStep*/
+0xC6, 0x38, /* PeakTgMin*/
+0xC7, 0x24, /* PeakRatioTh1*/
+0xC8, 0x10, /* PeakRatioTh0*/
+0xC9, 0x05, /* PeakLuTh*/
+0xD5, 0x60, /* LuxGainTB_2*/
+0xFF, 0x83, /*Page mode */
+0x2F, 0x04, /* TimeNum0*/
+0x30, 0x05, /* TimeNum1*/
+0x4F, 0x05, /* FrameOffset*/
+0xFF, 0x82, /*Page mode */
+0xA1, 0x0A, /* AnalogGainMax*/
+0xF3, 0x09, /* SCLK*/
+0xF4, 0x60,
+0xF9, 0x00, /* GainMax*/
+0xFA, 0xC8, /* GainMax*/
+0xFB, 0x62, /* Gain3Lut*/
+0xFC, 0x39, /* Gain2Lut*/
+0xFD, 0x28, /* Gain1Lut*/
+0xFE, 0x12, /* GainMin*/
+0xFF, 0x83, /*Page mode */
+0x03, 0x0F, /* TimeMax60Hz : 8fps*/
+0x04, 0x0A, /* Time3Lux60Hz : 12fps*/
+0x05, 0x04, /* Time2Lut60Hz : 24fps*/
+0x06, 0x04, /* Time1Lut60Hz : 24fps*/
+0xFF, 0x82, /*Page mode */
+0xD3, 0x12, /* LuxTBGainStep0 */
+0xD4, 0x36, /* LuxTBGainStep1 */
+0xD5, 0x60, /* LuxTBGainStep2*/
+0xD6, 0x01, /* LuxTBTimeStep0H*/
+0xD7, 0x00, /* LuxTBTimeStep0L*/
+0xD8, 0x01, /* LuxTBTimeStep1H*/
+0xD9, 0xC0, /* LuxTBTimeStep1L*/
+0xDA, 0x06, /* LuxTBTimeStep2H*/
+0xDB, 0x00, /* LuxTBTimeStep2L*/
+0xFF, 0x83, /*Page mode */
+0x0B, 0x08,
+0x0C, 0x0C, /* Frame Rate*/
+0xFF, 0x82, /*Page mode */
+0x92, 0x5D,
+
+/***************************************************/
+/* AWB */
+/***************************************************/
+0xFF, 0x83, /*Page mode */
+0x79, 0x83, /* AWB SKIN ON*/
+0x86, 0x07, /* gAWB_u16MinGrayCnt_rw_0*/
+0x87, 0x00, /* gAWB_u16MinGrayCnt_rw_1*/
+0x90, 0x05, /* gAWB_u16FinalRGain_ro_0*/
+0x94, 0x05, /* gAWB_u16FinalBGain_ro_0*/
+0x98, 0xD4, /* SkinWinCntTh*/
+0xA2, 0x28, /* SkinYTh*/
+0xA3, 0x00, /* SkinHoldHitCnt*/
+0xA4, 0x0F, /* SkinHoldHitCnt*/
+0xAD, 0x65, /* u8SkinTop2*/
+0xAE, 0x80, /* gAwb_u8SkinTop2LS1Ratio_rw 5zone */
+0xAF, 0x20, /* gAwb_u8SkinTop2LS2Ratio_rw 6zone */
+0xB4, 0x10, /* u8SkinTop2LSHys_rw */
+0xB5, 0x54, /* gAwb_u8SkinLTx */
+0xB6, 0xbd, /* gAwb_u8SkinLTy */
+0xB7, 0x74, /* gAwb_u8SkinRBx */
+0xB8, 0x9d, /* gAwb_u8SkinRBy */
+0xBA, 0x4F, /* UniCThrY_rw */
+0xBF, 0x0C, /* u16UniCGrayCntThr_rw_0 */
+0xC0, 0x80, /* u16UniCGrayCntThr_rw_1 */
+0xFF, 0x87, /*Page mode */
+0xC9, 0x22, /* gUR_u8AWBTrim_Addr */
+0xFF, 0x84, /*Page mode */
+0x49, 0x02, /* Threshold_indoor */
+0x4A, 0x00,
+0x4B, 0x03, /* Threshold_outdoor */
+0x4C, 0x80,
+0xFF, 0x83, /*Page mode */
+0xCB, 0x03, /* R MinGain [Default 0X20] A Spec Pass */
+0xCC, 0xC0, /* R MinGain [Default 0X20] A Spec Pass */
+0x82, 0x00, /* lockratio*/
+0xFF, 0x84, /*Page mode */
+0x3D, 0x00, /* gAwb_u32LuxConst1_rw_0*/
+0x3E, 0x00, /* gAwb_u32LuxConst1_rw_1*/
+0x3F, 0x06, /* gAwb_u32LuxConst1_rw_2*/
+0x40, 0x20, /* gAwb_u32LuxConst1_rw_3*/
+0x41, 0x07, /* gAwb_u32LuxConst2_rw_0*/
+0x42, 0x53, /* gAwb_u32LuxConst2_rw_1*/
+0x43, 0x00, /* gAwb_u32LuxConst2_rw_2*/
+0x44, 0x00, /* gAwb_u32LuxConst2_rw_3*/
+0x55, 0x03, /* gAwb_u8Weight_Gen_rw_0 */
+0x56, 0x10, /* gAwb_u8Weight_Gen_rw_1 */
+0x57, 0x14, /* gAwb_u8Weight_Gen_rw_2 */
+0x58, 0x07, /* gAwb_u8Weight_Gen_rw_3 */
+0x59, 0x04, /* gAwb_u8Weight_Gen_rw_4 */
+0x5A, 0x03, /* gAwb_u8Weight_Gen_rw_5 */
+0x5B, 0x03, /* gAwb_u8Weight_Gen_rw_6 */
+0x5C, 0x15, /* gAwb_u8Weight_Gen_rw_7 */
+0x5D, 0x01, /* gAwb_u8Weight_Ind_rw_0 */
+0x5E, 0x0F, /* gAwb_u8Weight_Ind_rw_1 */
+0x5F, 0x07, /* gAwb_u8Weight_Ind_rw_2 */
+0x60, 0x14, /* gAwb_u8Weight_Ind_rw_3 */
+0x61, 0x14, /* gAwb_u8Weight_Ind_rw_4 */
+0x62, 0x12, /* gAwb_u8Weight_Ind_rw_5 */
+0x63, 0x11, /* gAwb_u8Weight_Ind_rw_6 */
+0x64, 0x14, /* gAwb_u8Weight_Ind_rw_7 */
+0x65, 0x03, /* gAwb_u8Weight_Outd_rw_0*/
+0x66, 0x05, /* gAwb_u8Weight_Outd_rw_1*/
+0x67, 0x15, /* gAwb_u8Weight_Outd_rw_2*/
+0x68, 0x04, /* gAwb_u8Weight_Outd_rw_3*/
+0x69, 0x01, /* gAwb_u8Weight_Outd_rw_4*/
+0x6A, 0x02, /* gAwb_u8Weight_Outd_rw_5*/
+0x6B, 0x03, /* gAwb_u8Weight_Outd_rw_6*/
+0x6C, 0x15, /* gAwb_u8Weight_Outd_rw_6*/
+0xFF, 0x85, /*Page mode */
+0xE2, 0x0C, /* gPT_u8Awb_UnicolorZone_rw */
+0xFF, 0x83, /*Page mode */
+0xCD, 0x06, /*Max Rgain*/
+0xCE, 0x80,
+0xD1, 0x06, /*Max BGain*/
+0xd2, 0x80,
+
+/***************************************************/
+/* AWB STE */
+/***************************************************/
+0xFF, 0xA1, /*Page mode */
+/* Flash */
+0xA0, 0x5c, /*AWBZone0LTx*/
+0xA1, 0x7a, /*AWBZone0LTy*/
+0xA2, 0x69, /*AWBZone0RBx*/
+0xA3, 0x6f, /*AWBZone0RBy*/
+/* cloudy */
+0xA4, 0x73, /*AWBZone1LTx*/
+0xA5, 0x55, /*AWBZone1LTy*/
+0xA6, 0x8C, /*AWBZone1RBx*/
+0xA7, 0x30, /*AWBZone1RBy */
+/* Daylight */
+0xA8, 0x69, /*AWBZone2LTx*/
+0xA9, 0x69, /*AWBZone2LTy*/
+0xAA, 0x83, /*AWBZone2RBx*/
+0xAB, 0x52, /*AWBZone2RBy */
+/* Fluorescent */
+0xAC, 0x57, /*AWBZone3LTx*/
+0xAD, 0x6e, /*AWBZone3LTy*/
+0xAE, 0x6f, /*AWBZone3RBx*/
+0xAF, 0x59, /*AWBZone3RBy*/
+
+/*CWF */
+0xB0, 0x50, /*AWBZone4LTx*/
+0xB1, 0x74, /*AWBZone4LTy*/
+0xB2, 0x65, /*AWBZone4RBx*/
+0xB3, 0x5d, /*AWBZone4RBy*/
+/*TL84 */
+0xB4, 0x53, /*AWBZone5LTx*/
+0xB5, 0x7f, /*AWBZone5LTy*/
+0xB6, 0x62, /*AWBZone5RBx*/
+0xB7, 0x75, /*AWBZone5RBy */
+/*A */
+0xB8, 0x4a, /*AWBZone6LTx*/
+0xB9, 0x87, /*AWBZone6LTy*/
+0xBA, 0x59, /*AWBZone6RBx*/
+0xBB, 0x78, /*AWBZone6RBy*/
+/*Horizon */
+0xBC, 0x41, /*AWBZone7LTx*/
+0xBD, 0x91, /*AWBZone7LTy*/
+0xBE, 0x4b, /*AWBZone7RBx*/
+0xBF, 0x89, /*AWBZone7RBy*/
+/*Skin */
+0xC0, 0x5b, /*AWBZone8LTx*/
+0xC1, 0x85, /*AWBZone8LTy*/
+0xC2, 0x60, /*AWBZone8RBx*/
+0xC3, 0x7b, /*AWBZone8RBy*/
+
+/***************************************************/
+/* UR */
+/***************************************************/
+0xFF, 0x85, /*Page mode */
+0x06, 0x05,
+0xFF, 0x86, /*Page mode */
+0x14, 0x1E, /* CCM sum 1*/
+0xFF, 0x85, /*Page mode */
+0x86, 0x42, /* 42 saturation level*/
+0x07, 0x00, /* sup hysteresis*/
+
+/*DAY light */
+0xFF, 0x83, /*Page mode */
+0xEA, 0x00, /*gAwb_s16AdapCCMTbl_0*/
+0xEB, 0x53, /*gAwb_s16AdapCCMTbl_1*/
+0xEC, 0xFF, /*gAwb_s16AdapCCMTbl_2*/
+0xED, 0xE1, /*gAwb_s16AdapCCMTbl_3*/
+0xEE, 0x00, /*gAwb_s16AdapCCMTbl_4*/
+0xEF, 0x05, /*gAwb_s16AdapCCMTbl_5*/
+0xF0, 0xFF, /*gAwb_s16AdapCCMTbl_6*/
+0xF1, 0xF3, /*gAwb_s16AdapCCMTbl_7*/
+0xF2, 0x00, /*gAwb_s16AdapCCMTbl_8*/
+0xF3, 0x4B, /*gAwb_s16AdapCCMTbl_9*/
+0xF4, 0xFF, /*gAwb_s16AdapCCMTbl_10*/
+0xF5, 0xFA, /*gAwb_s16AdapCCMTbl_11*/
+0xF6, 0xFF, /*gAwb_s16AdapCCMTbl_12*/
+0xF7, 0xFa, /*gAwb_s16AdapCCMTbl_13*/
+0xF8, 0xFF, /*gAwb_s16AdapCCMTbl_14*/
+0xF9, 0xC3, /*gAwb_s16AdapCCMTbl_15*/
+0xFA, 0x00, /*gAwb_s16AdapCCMTbl_16*/
+0xFB, 0x80, /*gAwb_s16AdapCCMTbl_17*/
+
+/*CWF lgiht */
+0xFF, 0x83, /*Page mode */
+0xFC, 0x00, /* gAwb_s16AdapCCMTbl_18 */
+0xFD, 0x68, /* gAwb_s16AdapCCMTbl_19 */
+0xFF, 0x85, /*Page mode */
+0xE0, 0xFF, /* gAwb_s16AdapCCMTbl_20 */
+0xE1, 0xde, /* gAwb_s16AdapCCMTbl_21 */
+0xFF, 0x84, /*Page mode */
+0x00, 0xff, /* gAwb_s16AdapCCMTbl_22 */
+0x01, 0xfa, /* gAwb_s16AdapCCMTbl_23 */
+0x02, 0xFF, /* gAwb_s16AdapCCMTbl_24 */
+0x03, 0xf0, /* gAwb_s16AdapCCMTbl_25 */
+0x04, 0x00, /* gAwb_s16AdapCCMTbl_26 */
+0x05, 0x52, /* gAwb_s16AdapCCMTbl_27 */
+0x06, 0xFF, /* gAwb_s16AdapCCMTbl_28 */
+0x07, 0xFa, /* gAwb_s16AdapCCMTbl_29 */
+0x08, 0x00, /* gAwb_s16AdapCCMTbl_30 */
+0x09, 0x00, /* gAwb_s16AdapCCMTbl_31 */
+0x0A, 0xFF, /* gAwb_s16AdapCCMTbl_32 */
+0x0B, 0xdb, /* gAwb_s16AdapCCMTbl_33 */
+0x0C, 0x00, /* gAwb_s16AdapCCMTbl_34 */
+0x0D, 0x68, /* gAwb_s16AdapCCMTbl_35 */
+
+/*A light */
+
+0x0E, 0x00, /* gAwb_s16AdapCCMTbl_36 */
+0x0F, 0x6d, /* gAwb_s16AdapCCMTbl_37 */
+0x10, 0xFF, /* gAwb_s16AdapCCMTbl_38 */
+0x11, 0xd5, /* gAwb_s16AdapCCMTbl_39 */
+0x12, 0xff, /* gAwb_s16AdapCCMTbl_40 */
+0x13, 0xfe, /* gAwb_s16AdapCCMTbl_41 */
+0x14, 0xFF, /* gAwb_s16AdapCCMTbl_42 */
+0x15, 0xf4, /* gAwb_s16AdapCCMTbl_43 */
+0x16, 0x00, /* gAwb_s16AdapCCMTbl_44 */
+0x17, 0x5a, /* gAwb_s16AdapCCMTbl_45 */
+0x18, 0xff, /* gAwb_s16AdapCCMTbl_46 */
+0x19, 0xef, /* gAwb_s16AdapCCMTbl_47 */
+0x1A, 0xff, /* gAwb_s16AdapCCMTbl_48 */
+0x1B, 0xfa, /* gAwb_s16AdapCCMTbl_49 */
+0x1C, 0xFF, /* gAwb_s16AdapCCMTbl_50 */
+0x1D, 0xbe, /* gAwb_s16AdapCCMTbl_51 */
+0x1E, 0x00, /* gAwb_s16AdapCCMTbl_52 */
+0x1F, 0x86, /* gAwb_s16AdapCCMTbl_53 */
+
+
+/***************************************************/
+/* ADF */
+/***************************************************/
+
+/* ISP setting*/
+0xFF, 0xA0, /*Page mode */
+0x10, 0x80, /* BLC: ABLC db*/
+0x60, 0x73, /* CDC: Dark CDC ON */
+0x61, 0x1F, /* Six CDC_Edge En, Slash EN*/
+0x69, 0x0C, /* Slash direction Line threshold*/
+0x6A, 0x60, /* Slash direction Pixel threshold*/
+0xC2, 0x04, /* NSF: directional smoothing*/
+0xD0, 0x51, /* DEM: pattern detection*/
+0xFF, 0xA1, /*Page mode */
+0x30, 0x01, /* EDE: Luminane adaptation on*/
+0x32, 0x50, /* EDE: Adaptation slope */
+0x34, 0x00, /* EDE: x1 point */
+0x35, 0x0B, /* EDE: x1 point */
+0x36, 0x01, /* EDE: x2 point */
+0x37, 0x80, /* EDE: x2 point */
+0x3A, 0x00, /* EDE: Adaptation left margin*/
+0x3B, 0x30, /* EDE: Adaptation right margin*/
+0x3C, 0x08, /* EDE: rgb edge threshol*/
+
+/* Adaptive Setting*/
+0xFF, 0x85, /*Page mode */
+/* LSC*/
+0x0F, 0x43, /* LVLSC lux level threshold*/
+0x10, 0x43, /* LSLSC Light source , threshold lux*/
+
+/* BGT*/
+0x17, 0x30, /* BGT lux level threshold*/
+0x26, 0x20, /* MinVal */
+0x3c, 0x00, /* MaxVal */
+
+/* CNT*/
+0x18, 0x43, /* CNT lux level threshold*/
+0x27, 0x00, /* MinVal */
+0x3d, 0x00, /* MaxVal */
+
+/* NSF */
+0x12, 0xA5, /* NSF lux level threshold */
+0x22, 0x38, /* u8MinVal_NSF1*/
+0x23, 0x70, /* u8MinVal_NSF2*/
+0xFF, 0x86, /*Page mode */
+0x12, 0x00, /* u8MinVal_NSF3*/
+0xFF, 0x85, /*Page mode */
+0x38, 0x12, /* u8MaxVal_NSF1*/
+0x39, 0x30, /* u8MaxVal_NSF2*/
+0xFF, 0x86, /*Page mode */
+0x13, 0x08, /* u8MaxVal_NSF3*/
+
+/* GDC*/
+0xFF, 0x85, /*Page mode */
+0x15, 0xF4, /* GDC lux level threshold */
+0x2D, 0x20, /* u8MinVal_GDC1*/
+0x2E, 0x30, /* u8MinVal_GDC2*/
+0x43, 0x40, /* u8MaxVal_GDC1*/
+0x44, 0x80, /* u8MaxVal_GDC2*/
+
+/* ISP Edge*/
+0x04, 0xFB, /* EnEDE*/
+0x14, 0x54, /* u8ThrLevel_EDE*/
+0x28, 0x00, /* u8MinVal_EDE_CP*/
+0x29, 0x03, /* u8MinVal_EDE1*/
+0x2A, 0x20, /* u8MinVal_EDE2*/
+0x2B, 0x00, /* u8MinVal_EDE_OFS*/
+0x2C, 0x22, /* u8MinVal_SG*/
+0x3E, 0x00, /* u8MaxVal_EDE_CP*/
+0x3F, 0x09, /* u8MaxVal_EDE1*/
+0x40, 0x22, /* u8MaxVal_EDE2*/
+0x41, 0x02, /* u8MaxVal_EDE_OFS*/
+0x42, 0x33, /* u8MaxVal_SG*/
+
+/* Gamma Adaptive*/
+
+0x16, 0xA0, /* Gamma Threshold*/
+0x47, 0x00, /* Min_Gamma_0*/
+0x48, 0x03, /* Min_Gamma_1*/
+0x49, 0x10, /* Min_Gamma_2*/
+0x4A, 0x25, /* Min_Gamma_3*/
+0x4B, 0x3B, /* Min_Gamma_4*/
+0x4C, 0x4F, /* Min_Gamma_5*/
+0x4D, 0x6D, /* Min_Gamma_6*/
+0x4E, 0x86, /* Min_Gamma_7*/
+0x4F, 0x9B, /* Min_Gamma_8*/
+0x50, 0xAD, /* Min_Gamma_9*/
+0x51, 0xC2, /* Min_Gamma_10*/
+0x52, 0xD3, /* Min_Gamma_11*/
+0x53, 0xE1, /* Min_Gamma_12*/
+0x54, 0xE9, /* Min_Gamma_13*/
+0x55, 0xF2, /* Min_Gamma_14*/
+0x56, 0xFA, /* Min_Gamma_15*/
+0x57, 0xFF, /* Min_Gamma_16*/
+0x58, 0x00, /* Max_Gamma_0 */
+0x59, 0x06, /* Max_Gamma_1 */
+0x5a, 0x14, /* Max_Gamma_2 */
+0x5b, 0x30, /* Max_Gamma_3 */
+0x5c, 0x4A, /* Max_Gamma_4 */
+0x5d, 0x5D, /* Max_Gamma_5 */
+0x5e, 0x75, /* Max_Gamma_6 */
+0x5f, 0x89, /* Max_Gamma_7 */
+0x60, 0x9A, /* Max_Gamma_8 */
+0x61, 0xA7, /* Max_Gamma_9 */
+0x62, 0xBC, /* Max_Gamma_10 */
+0x63, 0xD0, /* Max_Gamma_11 */
+0x64, 0xE0, /* Max_Gamma_12 */
+0x65, 0xE7, /* Max_Gamma_13 */
+0x66, 0xEE, /* Max_Gamma_14 */
+0x67, 0xF7, /* Max_Gamma_15 */
+0x68, 0xFF, /* Max_Gamma_16 */
+
+/* Initial edge, noise filter setting*/
+0xFF, 0xA0, /*Page mode */
+0xC0, 0x12, /*NSFTh1_Addr*/
+0xC1, 0x30, /*NSFTh2_Addr*/
+0xC2, 0x08, /*NSFTh3_Addr*/
+0xFF, 0xA1, /*Page mode */
+0x30, 0x01, /*EDEOption_Addr*/
+0x31, 0x33, /*EDESlopeGain_Addr*/
+0x32, 0x50, /*EDELuAdpCtrl_Addr*/
+0x33, 0x00, /*EDEPreCoringPt_Addr*/
+0x34, 0x00, /*EDETransFuncXp1_Addr1*/
+0x35, 0x0B, /*EDETransFuncXp1_Addr0*/
+0x36, 0x01, /*EDETransFuncXp2_Addr1*/
+0x37, 0x80, /*EDETransFuncXp2_Addr0*/
+0x38, 0x09, /*EDETransFuncSl1_Addr*/
+0x39, 0x22, /*EDETransFuncSl2_Addr*/
+0x3A, 0x00, /*EDELuAdpLOffset_Addr*/
+0x3B, 0x30, /*EDELuAdpROffset_Addr*/
+0x3C, 0x08, /*EDERBThrd_Addr*/
+0x3D, 0x02, /*EDESmallOffset_Addr*/
+
+/* CCM Saturation Level*/
+0xFF, 0x85, /*Page mode */
+0x1A, 0x64, /* SUP Threshold */
+0x30, 0x40, /* MinSUP */
+
+0xFF, 0xA0, /*Page mode */
+/* Lens Shading*/
+0x43, 0x80, /* RH7 rrhrhh*/
+0x44, 0x80, /* RV*/
+0x45, 0x80, /* RH */
+0x46, 0x80, /* RV*/
+0x47, 0x80, /* GH*/
+0x48, 0x80, /* GV*/
+0x49, 0x80, /* GH*/
+0x4A, 0x80, /* GV */
+0x4B, 0x80, /* BH*/
+0x4C, 0x80, /* BV*/
+0x4D, 0x80, /* BH*/
+0x4E, 0x80, /* BV */
+0x52, 0x90, /* GGain*/
+0x53, 0x20, /* GGain*/
+0x54, 0x00, /* GGain*/
+
+/*Max Shading*/
+0xFF, 0x85, /*Page mode */
+0x32, 0xC0,
+0x33, 0x30,
+0x34, 0x00,
+0x35, 0x90,
+0x36, 0x20,
+0x37, 0x00,
+
+/*Min Shading*/
+0x1c, 0xC0,
+0x1d, 0x30,
+0x1e, 0x00,
+0x1f, 0x90,
+0x20, 0x18,
+0x21, 0x00,
+
+/* LineLength */
+0xFF, 0x87, /*Page mode */
+0xDC, 0x05, /* by Yong In Han 091511*/
+0xDD, 0xB0, /* by Yong In Han 091511*/
+0xd5, 0x00, /* Flip*/
+/***************************************************/
+/* SensorCon */
+/***************************************************/
+0xFF, 0xD0, /*Page mode */
+0x20, 0x0E, /* ABLK_Rsrv_Addr*/
+0x20, 0x0D, /* ABLK_Rsrv_Addr*/
+
+/***************************************************/
+/* MIPI */
+/***************************************************/
+0xFF, 0xB0, /*Page mode */
+0x54, 0x02, /* MIPI PHY_HS_TX_CTRL*/
+0x38, 0x05, /* MIPI DPHY_CTRL_SET*/
+
+
+/* SXGA PR*/
+0xFF, 0x85, /*Page mode */
+0xB8, 0x0A, /* gPT_u8PR_Active_SXGA_WORD_COUNT_Addr0*/
+0xB9, 0x00, /* gPT_u8PR_Active_SXGA_WORD_COUNT_Addr1*/
+0xBC, 0x04, /* gPT_u8PR_Active_SXGA_DPHY_CLK_TIME_Addr3*/
+0xFF, 0x87, /*Page mode */
+0x0C, 0x00, /* start Y*/
+0x0D, 0x20, /* start Y */
+0x10, 0x03, /* end Y*/
+0x11, 0xE0, /* end Y */
+
+/* Recoding */
+0xFF, 0x86, /*Page mode */
+0x38, 0x05, /* gPT_u8PR_Active_720P_WORD_COUNT_Addr0*/
+0x39, 0x00, /* gPT_u8PR_Active_720P_WORD_COUNT_Addr1*/
+0x3C, 0x04, /* gPT_u8PR_Active_720P_DPHY_CLK_TIME_Addr3*/
+
+0xFF, 0x87,
+0x23, 0x02, /*gPR_Active_720P_u8SensorCtrl_Addr */
+0x25, 0x01, /*gPR_Active_720P_u8PLL_P_Addr */
+0x26, 0x0F, /*gPR_Active_720P_u8PLL_M_Addr */
+0x27, 0x00, /*gPR_Active_720P_u8PLL_S_Addr */
+0x28, 0x00, /*gPR_Active_720P_u8PLL_Ctrl_Addr */
+0x29, 0x01, /*gPR_Active_720P_u8src_clk_sel_Addr */
+0x2A, 0x00, /*gPR_Active_720P_u8output_pad_status_Addr */
+0x2B, 0x3F, /*gPR_Active_720P_u8ablk_ctrl_10_Addr */
+0x2C, 0xFF, /*gPR_Active_720P_u8BayerFunc_Addr */
+0x2D, 0xFF, /*gPR_Active_720P_u8RgbYcFunc_Addr */
+0x2E, 0x00, /*gPR_Active_720P_u8ISPMode_Addr */
+0x2F, 0x02, /*gPR_Active_720P_u8SCLCtrl_Addr */
+0x30, 0x01, /*gPR_Active_720P_u8SCLHorScale_Addr0 */
+0x31, 0xFF, /*gPR_Active_720P_u8SCLHorScale_Addr1 */
+0x32, 0x03, /*gPR_Active_720P_u8SCLVerScale_Addr0 */
+0x33, 0xFF, /*gPR_Active_720P_u8SCLVerScale_Addr1 */
+0x34, 0x00, /*gPR_Active_720P_u8SCLCropStartX_Addr0 */
+0x35, 0x00, /*gPR_Active_720P_u8SCLCropStartX_Addr1 */
+0x36, 0x00, /*gPR_Active_720P_u8SCLCropStartY_Addr0 */
+0x37, 0x10, /*gPR_Active_720P_u8SCLCropStartY_Addr1 */
+0x38, 0x02, /*gPR_Active_720P_u8SCLCropEndX_Addr0 */
+0x39, 0x80, /*gPR_Active_720P_u8SCLCropEndX_Addr1 */
+0x3A, 0x01, /*gPR_Active_720P_u8SCLCropEndY_Addr0 */
+0x3B, 0xF0, /*gPR_Active_720P_u8SCLCropEndY_Addr1 */
+0x3C, 0x01, /*gPR_Active_720P_u8OutForm_Addr */
+0x3D, 0x0C, /*gPR_Active_720P_u8OutCtrl_Addr */
+0x3E, 0x04, /*gPR_Active_720P_u8AEWinStartX_Addr */
+0x3F, 0x04, /*gPR_Active_720P_u8AEWinStartY_Addr */
+0x40, 0x66, /*gPR_Active_720P_u8MergedWinWidth_Addr */
+0x41, 0x5E, /*gPR_Active_720P_u8MergedWinHeight_Addr */
+0x42, 0x04, /*gPR_Active_720P_u8AEHistWinAx_Addr */
+0x43, 0x04, /*gPR_Active_720P_u8AEHistWinAy_Addr */
+0x44, 0x98, /*gPR_Active_720P_u8AEHistWinBx_Addr */
+0x45, 0x78, /*gPR_Active_720P_u8AEHistWinBy_Addr */
+0x46, 0x22, /*gPR_Active_720P_u8AWBTrim_Addr */
+0x47, 0x28, /*gPR_Active_720P_u8AWBCTWinAx_Addr */
+0x48, 0x20, /*gPR_Active_720P_u8AWBCTWinAy_Addr */
+0x49, 0x78, /*gPR_Active_720P_u8AWBCTWinBx_Addr */
+0x4A, 0x60, /*gPR_Active_720P_u8AWBCTWinBy_Addr */
+0x4B, 0x03, /*gPR_Active_720P_u16AFCFrameLength_0 */
+0x4C, 0x00, /*gPR_Active_720P_u16AFCFrameLength_1 */
+
+
+/* VGA PR */
+0xFF, 0x86, /*Page mode */
+0x2F, 0x05, /* gPT_u8PR_Active_VGA_WORD_COUNT_Addr0*/
+0x30, 0x00, /* gPT_u8PR_Active_VGA_WORD_COUNT_Addr1*/
+0x33, 0x04, /* gPT_u8PR_Active_VGA_DPHY_CLK_TIME_Addr3 */
+
+0xFF, 0x87, /*Page mode */
+0x4D, 0x00, /*gPR_Active_VGA_u8SensorCtrl_Addr*/
+0x4E, 0x72, /*gPR_Active_VGA_u8SensorMode_Addr*/
+0x4F, 0x01, /*gPR_Active_VGA_u8PLL_P_Addr*/
+0x50, 0x0F, /*gPR_Active_VGA_u8PLL_M_Addr*/
+0x51, 0x00, /*gPR_Active_VGA_u8PLL_S_Addr*/
+0x52, 0x00, /*gPR_Active_VGA_u8PLL_Ctrl_Addr*/
+0x53, 0x01, /*gPR_Active_VGA_u8src_clk_sel_Addr*/
+0x54, 0x00, /*gPR_Active_VGA_u8output_pad_status_Addr*/
+0x55, 0x3F, /*gPR_Active_VGA_u8ablk_ctrl_10_Addr*/
+0x56, 0xFF, /*gPR_Active_VGA_u8BayerFunc_Addr*/
+0x57, 0xFF, /*gPR_Active_VGA_u8RgbYcFunc_Addr*/
+0x58, 0x00, /*gPR_Active_VGA_u8ISPMode_Addr*/
+0x59, 0x02, /*gPR_Active_VGA_u8SCLCtrl_Addr*/
+0x5A, 0x01, /*gPR_Active_VGA_u8SCLHorScale_Addr0*/
+0x5B, 0xFF, /*gPR_Active_VGA_u8SCLHorScale_Addr1*/
+0x5C, 0x01, /*gPR_Active_VGA_u8SCLVerScale_Addr0*/
+0x5D, 0xFF, /*gPR_Active_VGA_u8SCLVerScale_Addr1*/
+0x5E, 0x00, /*gPR_Active_VGA_u8SCLCropStartX_Addr0*/
+0x5F, 0x00, /*gPR_Active_VGA_u8SCLCropStartX_Addr1*/
+0x60, 0x00, /*gPR_Active_VGA_u8SCLCropStartY_Addr0*/
+0x61, 0x20, /*gPR_Active_VGA_u8SCLCropStartY_Addr1*/
+0x62, 0x05, /*gPR_Active_VGA_u8SCLCropEndX_Addr0*/
+0x63, 0x00, /*gPR_Active_VGA_u8SCLCropEndX_Addr1*/
+0x64, 0x03, /*gPR_Active_VGA_u8SCLCropEndY_Addr0*/
+0x65, 0xE0, /*gPR_Active_VGA_u8SCLCropEndY_Addr1*/
+
+0xFF, 0xd1, /*Page mode */
+0x07, 0x00, /* power off mask clear*/
+0x0b, 0x00, /* clock off mask clear*/
+0xFF, 0xC0, /*Page mode */
+0x10, 0x41,
+
+
+/* VT-Call END of Initial*/
+};
+
+
+/* Set-data based on Samsung Reliabilty Group standard
+* ,when using WIFI. 15fps
+*/
+static const u8 db8131m_vt_wifi_common_1[] = {
+/***************************************************/
+/* Device : DB8131M Fixed 8fps */
+/* MIPI Interface for Noncontious Clock */
+/***************************************************/
+/***************************************************/
+/* Command */
+/***************************************************/
+0xFF, 0xC0, /*Page mode*/
+0x10, 0x01,
+};
+/*wait 150*/
+
+static const u8 db8131m_vt_wifi_common_2[] = {
+/***************************************************/
+/* Format */
+/***************************************************/
+0xFF, 0xA1, /*Page mode */
+0x70, 0x01,
+0x71, 0x0D,
+
+/***************************************************/
+/* SensorCon */
+/***************************************************/
+0xFF, 0xD0, /*Page mode */
+0x0F, 0x0B, /*ABLK_Ctrl_1_Addr*/
+0x13, 0x00, /*Gain_Addr*/
+0x15, 0x01, /*IVREFT_REFB_Addr*/
+0x20, 0x0E, /*ABLK_Rsrv_Addr*/
+0x23, 0x01, /*IVREFT2_REFB2_Addr*/
+0x24, 0x01, /*IPPG_IVCM2_Addr*/
+0x39, 0x70, /*RiseSx_CDS_1_L_Addr*/
+0x51, 0x19, /*Fallcreset_1_L_Addr*/
+0x83, 0x2D, /*RiseTran_Sig_Even_L_Addr*/
+0x85, 0x2F, /*FallTran_Sig_Even_L_Addr*/
+0x87, 0x2D, /*RiseTran_Sig_Odd_L_Addr*/
+0x89, 0x2F, /*FallTran_Sig_Odd_L_Addr*/
+0x8B, 0x27, /*RiseCNT_EN_1_L_Addr*/
+0x8D, 0x6c, /*FallCNT_EN_1_L_Addr*/
+0xD7, 0x80, /*ABLK_Ctrl_12_Addr*/
+0xDB, 0xA2, /*FallScanTx15_1_L_Addr*/
+0xED, 0x01, /*PLL_P_Addr*/
+0xEE, 0x0F, /*PLL_M_Addr*/
+0xEF, 0x00, /*PLL_S_Addr*/
+0xF9, 0x00, /*ABLK_Ctrl_8*/
+0xF8, 0x00, /*Vblank Sleep Mode enable*/
+0xFB, 0x90, /*PostADC_Gain_Addr*/
+
+/***************************************************/
+/* Analog ADF */
+/***************************************************/
+0xFF, 0x85, /*Page mode */
+0x89, 0x93, /*gAdf_u8APThreshold*/
+0x8A, 0x0C, /*u8APClmpThreshold*/
+0x8C, 0x07, /*gAdf_u8APMinVal_ThrClampH*/
+0x8D, 0x40, /*gAdf_u8APMinVal_ThrClampL*/
+0x8E, 0x03, /*gAdf_u8APMinVal_DOFFSET*/
+0x8F, 0x14, /*gAdf_u8APMinVal_AMP2_1_SDM*/
+0x91, 0x1A, /*gAdf_u8APMinVal_AMP4_3_SDM*/
+0x92, 0x0F, /*gAdf_u8APMinVal_FallIntTx15*/
+0x93, 0x47, /*gAdf_u8APMinVal_CDSxRange_CtrlPre*/
+0x95, 0x18, /*gAdf_u8APMinVal_REFB_IVCM*/
+0x96, 0x38, /*gAdf_u8APMinVal_ref_os_PB*/
+0x97, 0x0D, /*gAdf_u8APMinVal_NTx_Range*/
+0x98, 0x0D, /*gAdf_u8APMaxVal_Clmp_rst*/
+0x99, 0x06, /*gAdf_u8APMaxVal_ThrClampH*/
+0x9A, 0x9F, /*gAdf_u8APMaxVal_ThrClampL*/
+0x9B, 0x02, /*gAdf_u8APMaxVal_DOFFSET*/
+0x9C, 0x1C, /*gAdf_u8APMaxVal_AMP2_1_SDM*/
+0x9E, 0x11, /*gAdf_u8APMaxVal_AMP4_3_SDM*/
+0x9F, 0x5D, /*gAdf_u8APMaxVal_FallIntTx15*/
+0xA0, 0x78, /*gAdf_u8APMaxVal_CDSxRange_CtrlPre*/
+0xA2, 0x18, /*gAdf_u8APMaxVal_REFB_IVCM*/
+0xA3, 0x40, /*gAdf_u8APMaxVal_ref_os_PB*/
+0xA4, 0x0B, /*gAdf_u8APMaxVal_NTx_Range*/
+
+0xFF, 0x86, /*Page mode */
+0x15, 0x00, /*gPT_u8Adf_APThrHys*/
+0x16, 0xF7, /*gPT_u8Adf_APFallIntTxThrLevel*/
+0x17, 0x13, /*gPT_u8Adf_APMinVal_BP2_1_SDM*/
+0x18, 0x13, /*gPT_u8Adf_APMidVal_BP2_1_SDM*/
+0x19, 0x1C, /*gPT_u8Adf_APMaxVal_BP2_1_SDM*/
+0x1A, 0x06, /*gPT_u8Adf_APMidVal_ThrClampH*/
+0x1B, 0xF0, /*gPT_u8Adf_APMidVal_ThrClampL*/
+0x1C, 0x01, /*gPT_u8Adf_APMidVal_DOFFSET*/
+0x1D, 0x14, /*gPT_u8Adf_APMidVal_AMP2_1_SDM*/
+0x1F, 0x31, /*gPT_u8Adf_APMidVal_AMP4_3_SDM*/
+0x20, 0x68, /*gPT_u8Adf_APMidVal_CDSxRange_CtrlPre*/
+0x22, 0x18, /*gPT_u8Adf_APMidVal_REFB_IVCM*/
+0x23, 0x38, /*gPT_u8Adf_APMidVal_ref_os_PB*/
+0x24, 0x0F, /*gPT_u8Adf_APMidVal_NTx_Range*/
+0x25, 0x77, /*gPT_u8Adf_APVal_EnSiSoSht_EnSm*/
+
+0xFF, 0x87, /*Page mode */
+0xEA, 0x41,
+
+0xFF, 0xD0, /*Page mode */
+0x20, 0x0D, /*ABLK_Rsrv_Addr*/
+
+0xFF, 0x83, /*Page mode */
+0x63, 0x28, /*Again Table*/
+0x64, 0x10, /*Again Table*/
+0x65, 0xA8, /*Again Table*/
+0x66, 0x50, /*Again Table*/
+0x67, 0x28, /*Again Table*/
+0x68, 0x14, /*Again Table*/
+
+
+/***************************************************/
+/* AE */
+/***************************************************/
+0xFF, 0x82, /*Page mode */
+0x91, 0x02, /* AeMode*/
+0x95, 0x88, /* AE weight*/
+0x96, 0x88,
+0x97, 0xF8,
+0x98, 0x8F,
+0x99, 0xF8,
+0x9A, 0x8F,
+0x9B, 0x88,
+0x9C, 0x88,
+0xA9, 0x40, /* OTarget*/
+0xAA, 0x40, /* ITarget*/
+0x9D, 0x66, /* AE Speed*/
+0x9F, 0x06, /* AE HoldBnd*/
+0xA8, 0x40, /* STarget*/
+0xB9, 0x04, /* RGain*/
+0xBB, 0x04, /* GGain*/
+0xBD, 0x04, /* BGain*/
+0xC5, 0x02, /* PeakMvStep*/
+0xC6, 0x38, /* PeakTgMin*/
+0xC7, 0x24, /* PeakRatioTh1*/
+0xC8, 0x10, /* PeakRatioTh0*/
+0xC9, 0x05, /* PeakLuTh*/
+0xD5, 0x60, /* LuxGainTB_2*/
+0xFF, 0x83, /*Page mode */
+0x2F, 0x04, /* TimeNum0*/
+0x30, 0x05, /* TimeNum1*/
+0x4F, 0x05, /* FrameOffset*/
+0xFF, 0x82, /*Page mode */
+0xA1, 0x0A, /* AnalogGainMax*/
+0xF3, 0x09, /* SCLK*/
+0xF4, 0x60,
+0xF9, 0x00, /* GainMax*/
+0xFA, 0xC8, /* GainMax*/
+0xFB, 0x62, /* Gain3Lut*/
+0xFC, 0x39, /* Gain2Lut*/
+0xFD, 0x28, /* Gain1Lut*/
+0xFE, 0x12, /* GainMin*/
+0xFF, 0x83, /*Page mode */
+0x03, 0x0F, /* TimeMax60Hz : 8fps*/
+0x04, 0x0A, /* Time3Lux60Hz : 12fps*/
+0x05, 0x04, /* Time2Lut60Hz : 24fps*/
+0x06, 0x04, /* Time1Lut60Hz : 24fps*/
+0xFF, 0x82, /*Page mode */
+0xD3, 0x12, /* LuxTBGainStep0 */
+0xD4, 0x36, /* LuxTBGainStep1 */
+0xD5, 0x60, /* LuxTBGainStep2*/
+0xD6, 0x01, /* LuxTBTimeStep0H*/
+0xD7, 0x00, /* LuxTBTimeStep0L*/
+0xD8, 0x01, /* LuxTBTimeStep1H*/
+0xD9, 0xC0, /* LuxTBTimeStep1L*/
+0xDA, 0x06, /* LuxTBTimeStep2H*/
+0xDB, 0x00, /* LuxTBTimeStep2L*/
+0xFF, 0x83, /*Page mode */
+0x0B, 0x08,
+0x0C, 0x0C, /* Frame Rate*/
+0xFF, 0x82, /*Page mode */
+0x92, 0x5D,
+
+/***************************************************/
+/* AWB */
+/***************************************************/
+0xFF, 0x83, /*Page mode */
+0x79, 0x83, /* AWB SKIN ON*/
+0x86, 0x07, /* gAWB_u16MinGrayCnt_rw_0*/
+0x87, 0x00, /* gAWB_u16MinGrayCnt_rw_1*/
+0x90, 0x05, /* gAWB_u16FinalRGain_ro_0*/
+0x94, 0x05, /* gAWB_u16FinalBGain_ro_0*/
+0x98, 0xD4, /* SkinWinCntTh*/
+0xA2, 0x28, /* SkinYTh*/
+0xA3, 0x00, /* SkinHoldHitCnt*/
+0xA4, 0x0F, /* SkinHoldHitCnt*/
+0xAD, 0x65, /* u8SkinTop2*/
+0xAE, 0x80, /* gAwb_u8SkinTop2LS1Ratio_rw 5zone */
+0xAF, 0x20, /* gAwb_u8SkinTop2LS2Ratio_rw 6zone */
+0xB4, 0x10, /* u8SkinTop2LSHys_rw */
+0xB5, 0x54, /* gAwb_u8SkinLTx */
+0xB6, 0xbd, /* gAwb_u8SkinLTy */
+0xB7, 0x74, /* gAwb_u8SkinRBx */
+0xB8, 0x9d, /* gAwb_u8SkinRBy */
+0xBA, 0x4F, /* UniCThrY_rw */
+0xBF, 0x0C, /* u16UniCGrayCntThr_rw_0*/
+0xC0, 0x80, /* u16UniCGrayCntThr_rw_1 */
+0xFF, 0x87, /*Page mode */
+0xC9, 0x22, /* gUR_u8AWBTrim_Addr */
+0xFF, 0x84, /*Page mode */
+0x49, 0x02, /* Threshold_indoor */
+0x4A, 0x00,
+0x4B, 0x03, /* Threshold_outdoor */
+0x4C, 0x80,
+0xFF, 0x83, /*Page mode */
+0xCB, 0x03, /* R MinGain [Default 0X20] A Spec Pass */
+0xCC, 0xC0, /* R MinGain [Default 0X20] A Spec Pass */
+0x82, 0x00, /* lockratio*/
+0xFF, 0x84, /*Page mode */
+0x3D, 0x00, /* gAwb_u32LuxConst1_rw_0*/
+0x3E, 0x00, /* gAwb_u32LuxConst1_rw_1*/
+0x3F, 0x06, /* gAwb_u32LuxConst1_rw_2*/
+0x40, 0x20, /* gAwb_u32LuxConst1_rw_3*/
+0x41, 0x07, /* gAwb_u32LuxConst2_rw_0*/
+0x42, 0x53, /* gAwb_u32LuxConst2_rw_1*/
+0x43, 0x00, /* gAwb_u32LuxConst2_rw_2*/
+0x44, 0x00, /* gAwb_u32LuxConst2_rw_3*/
+0x55, 0x03, /* gAwb_u8Weight_Gen_rw_0 */
+0x56, 0x10, /* gAwb_u8Weight_Gen_rw_1 */
+0x57, 0x14, /* gAwb_u8Weight_Gen_rw_2 */
+0x58, 0x07, /* gAwb_u8Weight_Gen_rw_3 */
+0x59, 0x04, /* gAwb_u8Weight_Gen_rw_4 */
+0x5A, 0x03, /* gAwb_u8Weight_Gen_rw_5 */
+0x5B, 0x03, /* gAwb_u8Weight_Gen_rw_6 */
+0x5C, 0x15, /* gAwb_u8Weight_Gen_rw_7 */
+0x5D, 0x01, /* gAwb_u8Weight_Ind_rw_0 */
+0x5E, 0x0F, /* gAwb_u8Weight_Ind_rw_1 */
+0x5F, 0x07, /* gAwb_u8Weight_Ind_rw_2 */
+0x60, 0x14, /* gAwb_u8Weight_Ind_rw_3 */
+0x61, 0x14, /* gAwb_u8Weight_Ind_rw_4 */
+0x62, 0x12, /* gAwb_u8Weight_Ind_rw_5 */
+0x63, 0x11, /* gAwb_u8Weight_Ind_rw_6 */
+0x64, 0x14, /* gAwb_u8Weight_Ind_rw_7 */
+0x65, 0x03, /* gAwb_u8Weight_Outd_rw_0*/
+0x66, 0x05, /* gAwb_u8Weight_Outd_rw_1*/
+0x67, 0x15, /* gAwb_u8Weight_Outd_rw_2*/
+0x68, 0x04, /* gAwb_u8Weight_Outd_rw_3*/
+0x69, 0x01, /* gAwb_u8Weight_Outd_rw_4*/
+0x6A, 0x02, /* gAwb_u8Weight_Outd_rw_5*/
+0x6B, 0x03, /* gAwb_u8Weight_Outd_rw_6*/
+0x6C, 0x15, /* gAwb_u8Weight_Outd_rw_6*/
+0xFF, 0x85, /*Page mode */
+0xE2, 0x0C, /* gPT_u8Awb_UnicolorZone_rw */
+0xFF, 0x83, /*Page mode */
+0xCD, 0x06, /*Max Rgain*/
+0xCE, 0x80,
+0xD1, 0x06, /*Max BGain*/
+0xd2, 0x80,
+
+/***************************************************/
+/* AWB STE */
+/***************************************************/
+0xFF, 0xA1, /*Page mode */
+/*Flash*/
+0xA0, 0x5c, /*AWBZone0LTx*/
+0xA1, 0x7a, /*AWBZone0LTy*/
+0xA2, 0x69, /*AWBZone0RBx*/
+0xA3, 0x6f, /*AWBZone0RBy*/
+/*cloudy*/
+0xA4, 0x73, /*AWBZone1LTx*/
+0xA5, 0x55, /*AWBZone1LTy*/
+0xA6, 0x8C, /*AWBZone1RBx*/
+0xA7, 0x30, /*AWBZone1RBy */
+/*Daylight */
+0xA8, 0x69, /*AWBZone2LTx*/
+0xA9, 0x69, /*AWBZone2LTy*/
+0xAA, 0x83, /*AWBZone2RBx*/
+0xAB, 0x52, /*AWBZone2RBy */
+/*Fluorescent */
+0xAC, 0x57, /*AWBZone3LTx*/
+0xAD, 0x6e, /*AWBZone3LTy*/
+0xAE, 0x6f, /*AWBZone3RBx*/
+0xAF, 0x59, /*AWBZone3RBy*/
+
+/*CWF */
+0xB0, 0x50, /*AWBZone4LTx*/
+0xB1, 0x74, /*AWBZone4LTy*/
+0xB2, 0x65, /*AWBZone4RBx*/
+0xB3, 0x5d, /*AWBZone4RBy*/
+/*TL84 */
+0xB4, 0x53, /*AWBZone5LTx*/
+0xB5, 0x7f, /*AWBZone5LTy*/
+0xB6, 0x62, /*AWBZone5RBx*/
+0xB7, 0x75, /*AWBZone5RBy */
+/*A */
+0xB8, 0x4a, /*AWBZone6LTx*/
+0xB9, 0x87, /*AWBZone6LTy*/
+0xBA, 0x59, /*AWBZone6RBx*/
+0xBB, 0x78, /*AWBZone6RBy*/
+/*Horizon */
+0xBC, 0x41, /*AWBZone7LTx*/
+0xBD, 0x91, /*AWBZone7LTy*/
+0xBE, 0x4b, /*AWBZone7RBx*/
+0xBF, 0x89, /*AWBZone7RBy*/
+/*Skin */
+0xC0, 0x5b, /*AWBZone8LTx*/
+0xC1, 0x85, /*AWBZone8LTy*/
+0xC2, 0x60, /*AWBZone8RBx*/
+0xC3, 0x7b, /*AWBZone8RBy*/
+
+/***************************************************/
+/* UR */
+/***************************************************/
+0xFF, 0x85, /*Page mode */
+0x06, 0x05,
+0xFF, 0x86, /*Page mode */
+0x14, 0x1E, /* CCM sum 1*/
+0xFF, 0x85, /*Page mode */
+0x86, 0x42, /* 42 saturation level*/
+0x07, 0x00, /* sup hysteresis*/
+
+/*DAY light */
+0xFF, 0x83, /*Page mode */
+0xEA, 0x00, /*gAwb_s16AdapCCMTbl_0*/
+0xEB, 0x53, /*gAwb_s16AdapCCMTbl_1*/
+0xEC, 0xFF, /*gAwb_s16AdapCCMTbl_2*/
+0xED, 0xE1, /*gAwb_s16AdapCCMTbl_3*/
+0xEE, 0x00, /*gAwb_s16AdapCCMTbl_4*/
+0xEF, 0x05, /*gAwb_s16AdapCCMTbl_5*/
+0xF0, 0xFF, /*gAwb_s16AdapCCMTbl_6*/
+0xF1, 0xF3, /*gAwb_s16AdapCCMTbl_7*/
+0xF2, 0x00, /*gAwb_s16AdapCCMTbl_8*/
+0xF3, 0x4B, /*gAwb_s16AdapCCMTbl_9*/
+0xF4, 0xFF, /*gAwb_s16AdapCCMTbl_10*/
+0xF5, 0xFA, /*gAwb_s16AdapCCMTbl_11*/
+0xF6, 0xFF, /*gAwb_s16AdapCCMTbl_12*/
+0xF7, 0xFa, /*gAwb_s16AdapCCMTbl_13*/
+0xF8, 0xFF, /*gAwb_s16AdapCCMTbl_14*/
+0xF9, 0xC3, /*gAwb_s16AdapCCMTbl_15*/
+0xFA, 0x00, /*gAwb_s16AdapCCMTbl_16*/
+0xFB, 0x80, /*gAwb_s16AdapCCMTbl_17*/
+
+/*CWF lgiht */
+0xFF, 0x83, /*Page mode */
+0xFC, 0x00, /* gAwb_s16AdapCCMTbl_18 */
+0xFD, 0x68, /* gAwb_s16AdapCCMTbl_19 */
+0xFF, 0x85, /*Page mode */
+0xE0, 0xFF, /* gAwb_s16AdapCCMTbl_20 */
+0xE1, 0xde, /* gAwb_s16AdapCCMTbl_21 */
+0xFF, 0x84, /*Page mode */
+0x00, 0xff, /* gAwb_s16AdapCCMTbl_22 */
+0x01, 0xfa, /* gAwb_s16AdapCCMTbl_23 */
+0x02, 0xFF, /* gAwb_s16AdapCCMTbl_24 */
+0x03, 0xf0, /* gAwb_s16AdapCCMTbl_25 */
+0x04, 0x00, /* gAwb_s16AdapCCMTbl_26 */
+0x05, 0x52, /* gAwb_s16AdapCCMTbl_27 */
+0x06, 0xFF, /* gAwb_s16AdapCCMTbl_28 */
+0x07, 0xFa, /* gAwb_s16AdapCCMTbl_29 */
+0x08, 0x00, /* gAwb_s16AdapCCMTbl_30 */
+0x09, 0x00, /* gAwb_s16AdapCCMTbl_31 */
+0x0A, 0xFF, /* gAwb_s16AdapCCMTbl_32 */
+0x0B, 0xdb, /* gAwb_s16AdapCCMTbl_33 */
+0x0C, 0x00, /* gAwb_s16AdapCCMTbl_34 */
+0x0D, 0x68, /* gAwb_s16AdapCCMTbl_35 */
+
+/*A light */
+
+0x0E, 0x00, /* gAwb_s16AdapCCMTbl_36 */
+0x0F, 0x6d, /* gAwb_s16AdapCCMTbl_37 */
+0x10, 0xFF, /* gAwb_s16AdapCCMTbl_38 */
+0x11, 0xd5, /* gAwb_s16AdapCCMTbl_39 */
+0x12, 0xff, /* gAwb_s16AdapCCMTbl_40 */
+0x13, 0xfe, /* gAwb_s16AdapCCMTbl_41 */
+0x14, 0xFF, /* gAwb_s16AdapCCMTbl_42 */
+0x15, 0xf4, /* gAwb_s16AdapCCMTbl_43 */
+0x16, 0x00, /* gAwb_s16AdapCCMTbl_44 */
+0x17, 0x5a, /* gAwb_s16AdapCCMTbl_45 */
+0x18, 0xff, /* gAwb_s16AdapCCMTbl_46 */
+0x19, 0xef, /* gAwb_s16AdapCCMTbl_47 */
+0x1A, 0xff, /* gAwb_s16AdapCCMTbl_48 */
+0x1B, 0xfa, /* gAwb_s16AdapCCMTbl_49 */
+0x1C, 0xFF, /* gAwb_s16AdapCCMTbl_50 */
+0x1D, 0xbe, /* gAwb_s16AdapCCMTbl_51 */
+0x1E, 0x00, /* gAwb_s16AdapCCMTbl_52 */
+0x1F, 0x86, /* gAwb_s16AdapCCMTbl_53 */
+
+
+/***************************************************/
+/* ADF */
+/***************************************************/
+
+/* ISP setting*/
+0xFF, 0xA0, /*Page mode */
+0x10, 0x80, /* BLC: ABLC db*/
+0x60, 0x73, /* CDC: Dark CDC ON */
+0x61, 0x1F, /* Six CDC_Edge En, Slash EN*/
+0x69, 0x0C, /* Slash direction Line threshold*/
+0x6A, 0x60, /* Slash direction Pixel threshold*/
+0xC2, 0x04, /* NSF: directional smoothing*/
+0xD0, 0x51, /* DEM: pattern detection*/
+0xFF, 0xA1, /*Page mode */
+0x30, 0x01, /* EDE: Luminane adaptation on*/
+0x32, 0x50, /* EDE: Adaptation slope */
+0x34, 0x00, /* EDE: x1 point */
+0x35, 0x0B, /* EDE: x1 point */
+0x36, 0x01, /* EDE: x2 point */
+0x37, 0x80, /* EDE: x2 point */
+0x3A, 0x00, /* EDE: Adaptation left margin*/
+0x3B, 0x30, /* EDE: Adaptation right margin*/
+0x3C, 0x08, /* EDE: rgb edge threshol*/
+
+/* Adaptive Setting*/
+0xFF, 0x85, /*Page mode */
+/* LSC*/
+0x0F, 0x43, /* LVLSC lux level threshold*/
+0x10, 0x43, /* LSLSC Light source , threshold lux*/
+
+/* BGT*/
+0x17, 0x30, /* BGT lux level threshold*/
+0x26, 0x20, /* MinVal */
+0x3c, 0x00, /* MaxVal */
+
+/* CNT*/
+0x18, 0x43, /* CNT lux level threshold*/
+0x27, 0x00, /* MinVal */
+0x3d, 0x00, /* MaxVal */
+
+/* NSF */
+0x12, 0xA5, /* NSF lux level threshold */
+0x22, 0x38, /* u8MinVal_NSF1*/
+0x23, 0x70, /* u8MinVal_NSF2*/
+0xFF, 0x86, /*Page mode */
+0x12, 0x00, /* u8MinVal_NSF3*/
+0xFF, 0x85, /*Page mode */
+0x38, 0x12, /* u8MaxVal_NSF1*/
+0x39, 0x30, /* u8MaxVal_NSF2*/
+0xFF, 0x86, /*Page mode */
+0x13, 0x08, /* u8MaxVal_NSF3*/
+
+/* GDC*/
+0xFF, 0x85, /*Page mode */
+0x15, 0xF4, /* GDC lux level threshold */
+0x2D, 0x20, /* u8MinVal_GDC1*/
+0x2E, 0x30, /* u8MinVal_GDC2*/
+0x43, 0x40, /* u8MaxVal_GDC1*/
+0x44, 0x80, /* u8MaxVal_GDC2*/
+
+/* ISP Edge*/
+0x04, 0xFB, /* EnEDE*/
+0x14, 0x54, /* u8ThrLevel_EDE*/
+0x28, 0x00, /* u8MinVal_EDE_CP*/
+0x29, 0x03, /* u8MinVal_EDE1*/
+0x2A, 0x20, /* u8MinVal_EDE2*/
+0x2B, 0x00, /* u8MinVal_EDE_OFS*/
+0x2C, 0x22, /* u8MinVal_SG*/
+0x3E, 0x00, /* u8MaxVal_EDE_CP*/
+0x3F, 0x09, /* u8MaxVal_EDE1*/
+0x40, 0x22, /* u8MaxVal_EDE2*/
+0x41, 0x02, /* u8MaxVal_EDE_OFS*/
+0x42, 0x33, /* u8MaxVal_SG*/
+
+/* Gamma Adaptive*/
+
+0x16, 0xA0, /* Gamma Threshold*/
+0x47, 0x00, /* Min_Gamma_0*/
+0x48, 0x03, /* Min_Gamma_1*/
+0x49, 0x10, /* Min_Gamma_2*/
+0x4A, 0x25, /* Min_Gamma_3*/
+0x4B, 0x3B, /* Min_Gamma_4*/
+0x4C, 0x4F, /* Min_Gamma_5*/
+0x4D, 0x6D, /* Min_Gamma_6*/
+0x4E, 0x86, /* Min_Gamma_7*/
+0x4F, 0x9B, /* Min_Gamma_8*/
+0x50, 0xAD, /* Min_Gamma_9*/
+0x51, 0xC2, /* Min_Gamma_10*/
+0x52, 0xD3, /* Min_Gamma_11*/
+0x53, 0xE1, /* Min_Gamma_12*/
+0x54, 0xE9, /* Min_Gamma_13*/
+0x55, 0xF2, /* Min_Gamma_14*/
+0x56, 0xFA, /* Min_Gamma_15*/
+0x57, 0xFF, /* Min_Gamma_16*/
+0x58, 0x00, /* Max_Gamma_0 */
+0x59, 0x06, /* Max_Gamma_1 */
+0x5a, 0x14, /* Max_Gamma_2 */
+0x5b, 0x30, /* Max_Gamma_3 */
+0x5c, 0x4A, /* Max_Gamma_4 */
+0x5d, 0x5D, /* Max_Gamma_5 */
+0x5e, 0x75, /* Max_Gamma_6 */
+0x5f, 0x89, /* Max_Gamma_7 */
+0x60, 0x9A, /* Max_Gamma_8 */
+0x61, 0xA7, /* Max_Gamma_9 */
+0x62, 0xBC, /* Max_Gamma_10 */
+0x63, 0xD0, /* Max_Gamma_11 */
+0x64, 0xE0, /* Max_Gamma_12 */
+0x65, 0xE7, /* Max_Gamma_13 */
+0x66, 0xEE, /* Max_Gamma_14 */
+0x67, 0xF7, /* Max_Gamma_15 */
+0x68, 0xFF, /* Max_Gamma_16 */
+
+/* Initial edge, noise filter setting*/
+0xFF, 0xA0, /*Page mode */
+0xC0, 0x12, /*NSFTh1_Addr*/
+0xC1, 0x30, /*NSFTh2_Addr*/
+0xC2, 0x08, /*NSFTh3_Addr*/
+0xFF, 0xA1, /*Page mode */
+0x30, 0x01, /*EDEOption_Addr*/
+0x31, 0x33, /*EDESlopeGain_Addr*/
+0x32, 0x50, /*EDELuAdpCtrl_Addr*/
+0x33, 0x00, /*EDEPreCoringPt_Addr*/
+0x34, 0x00, /*EDETransFuncXp1_Addr1*/
+0x35, 0x0B, /*EDETransFuncXp1_Addr0*/
+0x36, 0x01, /*EDETransFuncXp2_Addr1*/
+0x37, 0x80, /*EDETransFuncXp2_Addr0*/
+0x38, 0x09, /*EDETransFuncSl1_Addr*/
+0x39, 0x22, /*EDETransFuncSl2_Addr*/
+0x3A, 0x00, /*EDELuAdpLOffset_Addr*/
+0x3B, 0x30, /*EDELuAdpROffset_Addr*/
+0x3C, 0x08, /*EDERBThrd_Addr*/
+0x3D, 0x02, /*EDESmallOffset_Addr*/
+
+
+/* CCM Saturation Level*/
+0xFF, 0x85, /*Page mode */
+0x1A, 0x64, /* SUP Threshold */
+0x30, 0x40, /* MinSUP */
+
+0xFF, 0xA0, /*Page mode */
+/* Lens Shading*/
+0x43, 0x80, /* RH7 rrhrhh*/
+0x44, 0x80, /* RV*/
+0x45, 0x80, /* RH */
+0x46, 0x80, /* RV*/
+0x47, 0x80, /* GH*/
+0x48, 0x80, /* GV*/
+0x49, 0x80, /* GH*/
+0x4A, 0x80, /* GV */
+0x4B, 0x80, /* BH*/
+0x4C, 0x80, /* BV*/
+0x4D, 0x80, /* BH*/
+0x4E, 0x80, /* BV */
+0x52, 0x90, /* GGain*/
+0x53, 0x20, /* GGain*/
+0x54, 0x00, /* GGain*/
+
+/*Max Shading*/
+0xFF, 0x85, /*Page mode */
+0x32, 0xC0,
+0x33, 0x30,
+0x34, 0x00,
+0x35, 0x90,
+0x36, 0x20,
+0x37, 0x00,
+
+/*Min Shading*/
+0x1c, 0xC0,
+0x1d, 0x30,
+0x1e, 0x00,
+0x1f, 0x90,
+0x20, 0x18,
+0x21, 0x00,
+
+/* LineLength */
+0xFF, 0x87, /*Page mode */
+0xDC, 0x05, /* by Yong In Han 091511*/
+0xDD, 0xB0, /* by Yong In Han 091511*/
+0xd5, 0x00, /* Flip*/
+/***************************************************/
+/* SensorCon */
+/***************************************************/
+0xFF, 0xD0, /*Page mode */
+0x20, 0x0E, /* ABLK_Rsrv_Addr*/
+0x20, 0x0D, /* ABLK_Rsrv_Addr*/
+
+/***************************************************/
+/* MIPI */
+/***************************************************/
+0xFF, 0xB0, /*Page mode */
+0x54, 0x02, /* MIPI PHY_HS_TX_CTRL*/
+0x38, 0x05, /* MIPI DPHY_CTRL_SET*/
+
+
+/* SXGA PR*/
+0xFF, 0x85, /*Page mode */
+0xB8, 0x0A, /* gPT_u8PR_Active_SXGA_WORD_COUNT_Addr0*/
+0xB9, 0x00, /* gPT_u8PR_Active_SXGA_WORD_COUNT_Addr1*/
+0xBC, 0x04, /* gPT_u8PR_Active_SXGA_DPHY_CLK_TIME_Addr3*/
+0xFF, 0x87, /*Page mode */
+0x0C, 0x00, /* start Y*/
+0x0D, 0x20, /* start Y */
+0x10, 0x03, /* end Y*/
+0x11, 0xE0, /* end Y */
+
+/* Recoding */
+0xFF, 0x86, /*Page mode */
+0x38, 0x05, /* gPT_u8PR_Active_720P_WORD_COUNT_Addr0*/
+0x39, 0x00, /* gPT_u8PR_Active_720P_WORD_COUNT_Addr1*/
+0x3C, 0x04, /* gPT_u8PR_Active_720P_DPHY_CLK_TIME_Addr3*/
+
+0xFF, 0x87,
+0x23, 0x02, /*gPR_Active_720P_u8SensorCtrl_Addr */
+0x25, 0x01, /*gPR_Active_720P_u8PLL_P_Addr */
+0x26, 0x0F, /*gPR_Active_720P_u8PLL_M_Addr */
+0x27, 0x00, /*gPR_Active_720P_u8PLL_S_Addr */
+0x28, 0x00, /*gPR_Active_720P_u8PLL_Ctrl_Addr */
+0x29, 0x01, /*gPR_Active_720P_u8src_clk_sel_Addr */
+0x2A, 0x00, /*gPR_Active_720P_u8output_pad_status_Addr */
+0x2B, 0x3F, /*gPR_Active_720P_u8ablk_ctrl_10_Addr */
+0x2C, 0xFF, /*gPR_Active_720P_u8BayerFunc_Addr */
+0x2D, 0xFF, /*gPR_Active_720P_u8RgbYcFunc_Addr */
+0x2E, 0x00, /*gPR_Active_720P_u8ISPMode_Addr */
+0x2F, 0x02, /*gPR_Active_720P_u8SCLCtrl_Addr */
+0x30, 0x01, /*gPR_Active_720P_u8SCLHorScale_Addr0 */
+0x31, 0xFF, /*gPR_Active_720P_u8SCLHorScale_Addr1 */
+0x32, 0x03, /*gPR_Active_720P_u8SCLVerScale_Addr0 */
+0x33, 0xFF, /*gPR_Active_720P_u8SCLVerScale_Addr1 */
+0x34, 0x00, /*gPR_Active_720P_u8SCLCropStartX_Addr0 */
+0x35, 0x00, /*gPR_Active_720P_u8SCLCropStartX_Addr1 */
+0x36, 0x00, /*gPR_Active_720P_u8SCLCropStartY_Addr0 */
+0x37, 0x10, /*gPR_Active_720P_u8SCLCropStartY_Addr1 */
+0x38, 0x02, /*gPR_Active_720P_u8SCLCropEndX_Addr0 */
+0x39, 0x80, /*gPR_Active_720P_u8SCLCropEndX_Addr1 */
+0x3A, 0x01, /*gPR_Active_720P_u8SCLCropEndY_Addr0 */
+0x3B, 0xF0, /*gPR_Active_720P_u8SCLCropEndY_Addr1 */
+0x3C, 0x01, /*gPR_Active_720P_u8OutForm_Addr */
+0x3D, 0x0C, /*gPR_Active_720P_u8OutCtrl_Addr */
+0x3E, 0x04, /*gPR_Active_720P_u8AEWinStartX_Addr */
+0x3F, 0x04, /*gPR_Active_720P_u8AEWinStartY_Addr */
+0x40, 0x66, /*gPR_Active_720P_u8MergedWinWidth_Addr */
+0x41, 0x5E, /*gPR_Active_720P_u8MergedWinHeight_Addr */
+0x42, 0x04, /*gPR_Active_720P_u8AEHistWinAx_Addr */
+0x43, 0x04, /*gPR_Active_720P_u8AEHistWinAy_Addr */
+0x44, 0x98, /*gPR_Active_720P_u8AEHistWinBx_Addr */
+0x45, 0x78, /*gPR_Active_720P_u8AEHistWinBy_Addr */
+0x46, 0x22, /*gPR_Active_720P_u8AWBTrim_Addr */
+0x47, 0x28, /*gPR_Active_720P_u8AWBCTWinAx_Addr */
+0x48, 0x20, /*gPR_Active_720P_u8AWBCTWinAy_Addr */
+0x49, 0x78, /*gPR_Active_720P_u8AWBCTWinBx_Addr */
+0x4A, 0x60, /*gPR_Active_720P_u8AWBCTWinBy_Addr */
+0x4B, 0x03, /*gPR_Active_720P_u16AFCFrameLength_0 */
+0x4C, 0x00, /*gPR_Active_720P_u16AFCFrameLength_1 */
+
+
+/* VGA PR */
+0xFF, 0x86, /*Page mode */
+0x2F, 0x05, /* gPT_u8PR_Active_VGA_WORD_COUNT_Addr0*/
+0x30, 0x00, /* gPT_u8PR_Active_VGA_WORD_COUNT_Addr1*/
+0x33, 0x04, /* gPT_u8PR_Active_VGA_DPHY_CLK_TIME_Addr3*/
+
+0xFF, 0x87, /*Page mode */
+0x4D, 0x00, /*gPR_Active_VGA_u8SensorCtrl_Addr*/
+0x4E, 0x72, /*gPR_Active_VGA_u8SensorMode_Addr*/
+0x4F, 0x01, /*gPR_Active_VGA_u8PLL_P_Addr*/
+0x50, 0x0F, /*gPR_Active_VGA_u8PLL_M_Addr*/
+0x51, 0x00, /*gPR_Active_VGA_u8PLL_S_Addr*/
+0x52, 0x00, /*gPR_Active_VGA_u8PLL_Ctrl_Addr*/
+0x53, 0x01, /*gPR_Active_VGA_u8src_clk_sel_Addr*/
+0x54, 0x00, /*gPR_Active_VGA_u8output_pad_status_Addr*/
+0x55, 0x3F, /*gPR_Active_VGA_u8ablk_ctrl_10_Addr*/
+0x56, 0xFF, /*gPR_Active_VGA_u8BayerFunc_Addr*/
+0x57, 0xFF, /*gPR_Active_VGA_u8RgbYcFunc_Addr*/
+0x58, 0x00, /*gPR_Active_VGA_u8ISPMode_Addr*/
+0x59, 0x02, /*gPR_Active_VGA_u8SCLCtrl_Addr*/
+0x5A, 0x01, /*gPR_Active_VGA_u8SCLHorScale_Addr0*/
+0x5B, 0xFF, /*gPR_Active_VGA_u8SCLHorScale_Addr1*/
+0x5C, 0x01, /*gPR_Active_VGA_u8SCLVerScale_Addr0*/
+0x5D, 0xFF, /*gPR_Active_VGA_u8SCLVerScale_Addr1*/
+0x5E, 0x00, /*gPR_Active_VGA_u8SCLCropStartX_Addr0*/
+0x5F, 0x00, /*gPR_Active_VGA_u8SCLCropStartX_Addr1*/
+0x60, 0x00, /*gPR_Active_VGA_u8SCLCropStartY_Addr0*/
+0x61, 0x20, /*gPR_Active_VGA_u8SCLCropStartY_Addr1*/
+0x62, 0x05, /*gPR_Active_VGA_u8SCLCropEndX_Addr0*/
+0x63, 0x00, /*gPR_Active_VGA_u8SCLCropEndX_Addr1*/
+0x64, 0x03, /*gPR_Active_VGA_u8SCLCropEndY_Addr0*/
+0x65, 0xE0, /*gPR_Active_VGA_u8SCLCropEndY_Addr1*/
+
+0xFF, 0xd1, /*Page mode */
+0x07, 0x00, /* power off mask clear*/
+0x0b, 0x00, /* clock off mask clear*/
+0xFF, 0xC0, /*Page mode */
+0x10, 0x41,
+
+/* Wifi VT-Call END of Initial*/
+};
+
+/***************************************************/
+/* CAMERA_PREVIEW - ÃÔ¿µ ÈÄ ÇÁ¸®ºä º¹±Í½Ã ¼ÂÆà */
+/***************************************************/
+
+static const u8 db8131m_preview[] = {
+0xff, 0x82,
+0x7F, 0x35,
+};
+
+/***************************************************/
+/* CAMERA_SNAPSHOT - ÃÔ¿µ */
+/***************************************************/
+static const u8 db8131m_capture[] = {
+0xff, 0x82,
+0x7F, 0x34,
+0xff, 0xC0,
+0x10, 0x03,
+};
+/*Wait 150ms*/
+/* capture ½ÇÇà*/
+
+/***************************************************/
+/* CAMERA_RECORDING WITH 25fps */
+/***************************************************/
+
+static const u8 db8131m_recording_60Hz_common[] = {
+/***************************************************/
+/* Device : DB8131M */
+/* MIPI Interface for Noncontious Clock */
+/***************************************************/
+
+/* Recording Anti-Flicker 60Hz END of Initial */
+0xFF, 0x87,
+0xDE, 0x7A, /*gPR_Active_720P_u8SensorMode_Addr */
+0xFF, 0xC0, /* Page mode*/
+0x10, 0x42, /* Preview Command*/
+
+/* Fixed 25fps Mode*/
+0xFF, 0x82, /* Page mode*/
+0x91, 0x02, /* AeMode*/
+0xFF, 0x83, /* Page mode*/
+0x0B, 0x02, /* Frame Rate*/
+0x0C, 0x94, /* Frame Rate*/
+0x03, 0x04, /* TimeMax60Hz*/
+0x04, 0x03, /* Time3Lux60Hz*/
+0x05, 0x02, /* Time2Lut60Hz*/
+0x06, 0x01, /* Time1Lut60Hz*/
+0xFF, 0x82, /* Page mode*/
+0x92, 0x5D,
+};
+
+
+static const u8 db8131m_stream_stop[] = {
+
+};
+
+
+/***************************************************/
+/* CAMERA_BRIGHTNESS_1 (1/9) M4 */
+/***************************************************/
+static const u8 db8131m_bright_m4[] = {
+/* Brightness -4 */
+0xFF, 0x87, /* Page mode*/
+0xAE, 0xE0, /* Brightness*/
+};
+
+/***************************************************/
+/* CAMERA_BRIGHTNESS_2 (2/9) M3 */
+/***************************************************/
+
+static const u8 db8131m_bright_m3[] = {
+/* Brightness -3 */
+0xFF, 0x87, /* Page mode*/
+0xAE, 0xE8, /* Brightness*/
+};
+
+/***************************************************/
+/* CAMERA_BRIGHTNESS_3 (3/9) M2 */
+/***************************************************/
+static const u8 db8131m_bright_m2[] = {
+/* Brightness -2 */
+0xFF, 0x87, /* Page mode*/
+0xAE, 0xF0, /* Brightness*/
+};
+
+/***************************************************/
+/* CAMERA_BRIGHTNESS_4 (4/9) M1 */
+/***************************************************/
+
+static const u8 db8131m_bright_m1[] = {
+/* Brightness -1 */
+0xFF, 0x87, /* Page mode*/
+0xAE, 0xF8, /* Brightness*/
+};
+
+/***************************************************/
+/* CAMERA_BRIGHTNESS_5 (5/9) Default */
+/***************************************************/
+static const u8 db8131m_bright_default[] = {
+/* Brightness 0 */
+0xFF, 0x87, /* Page mode*/
+0xAE, 0x00, /* Brightness*/
+};
+
+/***************************************************/
+/* CAMERA_BRIGHTNESS_6 (6/9) P1 */
+/***************************************************/
+static const u8 db8131m_bright_p1[] = {
+/* Brightness +1 */
+0xFF, 0x87, /* Page mode*/
+0xAE, 0x08, /* Brightness*/
+};
+
+/***************************************************/
+/* CAMERA_BRIGHTNESS_7 (7/9) P2 */
+/***************************************************/
+static const u8 db8131m_bright_p2[] = {
+/* Brightness +2 */
+0xFF, 0x87, /* Page mode*/
+0xAE, 0x10, /* Brightness*/
+};
+
+/***************************************************/
+/* CAMERA_BRIGHTNESS_8 (8/9) P3 */
+/***************************************************/
+static const u8 db8131m_bright_p3[] = {
+/* Brightness +3 */
+0xFF, 0x87, /* Page mode*/
+0xAE, 0x18, /* Brightness*/
+};
+
+/***************************************************/
+/* CAMERA_BRIGHTNESS_9 (9/9) P4 */
+/***************************************************/
+static const u8 db8131m_bright_p4[] = {
+/* Brightness +4 */
+0xFF, 0x87, /* Page mode*/
+0xAE, 0x20, /* Brightness*/
+};
+
+
+static const u8 db8131m_vt_7fps[] = {
+/* Fixed 7fps Mode*/
+0xFF, 0x82, /* Page mode*/
+0x91, 0x02, /* AeMode*/
+0xFF, 0x83, /* Page mode*/
+0x0B, 0x09, /* Frame Rate*/
+0x0C, 0x33, /* Frame Rate*/
+0x03, 0x0F, /* TimeMax60Hz*/
+0x04, 0x0A, /* Time3Lux60Hz*/
+0x05, 0x06, /* Time2Lut60Hz*/
+0x06, 0x04, /* Time1Lut60Hz*/
+0xFF, 0x82, /* Page mode*/
+0x92, 0x5D,
+};
+
+static const u8 db8131m_vt_10fps[] = {
+/* Fixed 10fps Mode */
+0xFF, 0x82, /* Page mode*/
+0x91, 0x02, /* AeMode*/
+0xFF, 0x83, /* Page mode*/
+0x0B, 0x06, /* Frame Rate*/
+0x0C, 0x70, /* Frame Rate*/
+0x03, 0x0A, /* TimeMax60Hz*/
+0x04, 0x08, /* Time3Lux60Hz*/
+0x05, 0x06, /* Time2Lut60Hz*/
+0x06, 0x04, /* Time1Lut60Hz*/
+0xFF, 0x82, /* Page mode*/
+0x92, 0x5D,
+
+};
+
+static const u8 db8131m_vt_12fps[] = {
+/* Fixed 12fps Mode */
+0xFF, 0x82, /* Page mode*/
+0x91, 0x02, /* AeMode*/
+0xFF, 0x83, /* Page mode*/
+0x0B, 0x05, /* Frame Rate*/
+0x0C, 0x5E, /* Frame Rate*/
+0x03, 0x0C, /* TimeMax60Hz*/
+0x04, 0x0A, /* Time3Lux60Hz*/
+0x05, 0x06, /* Time2Lut60Hz*/
+0x06, 0x04, /* Time1Lut60Hz*/
+0xFF, 0x82, /* Page mode*/
+0x92, 0x5D,
+};
+
+static const u8 db8131m_vt_15fps[] = {
+/* Fixed 15fps Mode */
+0xFF, 0x82, /* Page mode*/
+0x91, 0x02, /* AeMode*/
+0xFF, 0x83, /* Page mode*/
+0x0B, 0x04, /* Frame Rate*/
+0x0C, 0x4C, /* Frame Rate*/
+0x03, 0x08, /* TimeMax60Hz*/
+0x04, 0x06, /* Time3Lux60Hz*/
+0x05, 0x04, /* Time2Lut60Hz*/
+0x06, 0x04, /* Time1Lut60Hz*/
+0xFF, 0x82, /* Page mode*/
+0x92, 0x5D,
+
+};
+
+/***************************************************/
+/* CAMERA_DTP_ON */
+/***************************************************/
+static const u8 db8131m_pattern_on[] = {
+0xFF, 0x87, /* Page mode*/
+0xAB, 0x00, /* BayerFunc*/
+0xAC, 0x28, /* RGBYcFunc*/
+0xFF, 0xA0, /* Page mode*/
+0x02, 0x05, /* TPG ? Gamma*/
+
+};
+
+/***************************************************/
+/* CAMERA_DTP_OFF */
+/***************************************************/
+static const u8 db8131m_pattern_off[] = {
+0xFF, 0x87, /* Page mode*/
+0xAB, 0xFF, /* BayerFunc*/
+0xAC, 0xFF, /* RGBYcFunc*/
+0xFF, 0xA0, /* Page mode*/
+0x02, 0x00, /* TPG Disable*/
+
+};
+#endif /* __DB8131M_SETFILE_H */
diff --git a/drivers/media/video/slp_s5c73m3.c b/drivers/media/video/slp_s5c73m3.c
new file mode 100644
index 0000000..08726d2
--- /dev/null
+++ b/drivers/media/video/slp_s5c73m3.c
@@ -0,0 +1,3415 @@
+/*
+ * driver for LSI S5C73M3 (ISP for 8MP Camera)
+ *
+ * Copyright (c) 2011, Samsung Electronics. All rights reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 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/i2c.h>
+#include <linux/init.h>
+#include <media/v4l2-device.h>
+#include <linux/delay.h>
+#include <linux/vmalloc.h>
+#include <linux/firmware.h>
+#include <linux/videodev2.h>
+
+#include <plat/gpio-cfg.h>
+#include <linux/gpio.h>
+
+#ifdef CONFIG_BUSFREQ_OPP
+#include <mach/dev.h>
+#else
+#include <linux/pm_qos_params.h>
+#endif
+
+#ifdef CONFIG_VIDEO_SAMSUNG_V4L2
+#include <linux/videodev2_exynos_media.h>
+#include <linux/videodev2_exynos_camera.h>
+#endif
+
+#include <linux/regulator/machine.h>
+
+#include <media/s5c73m3_platform.h>
+#ifdef CONFIG_VIDEO_SLP_S5C73M3
+#include "slp_s5c73m3.h"
+#else
+#include "s5c73m3.h"
+#endif
+
+#define S5C73M3_DRIVER_NAME "S5C73M3"
+
+extern struct class *camera_class; /*sys/class/camera*/
+struct device *s5c73m3_dev; /*sys/class/camera/rear*/
+struct v4l2_subdev *sd_internal;
+
+#ifdef CONFIG_BUSFREQ_OPP
+struct device *bus_dev;
+#else
+static struct pm_qos_request_list entry = {};
+#endif
+
+/*#define S5C73M3_FROM_BOOTING*/
+
+#ifdef CONFIG_VIDEO_SLP_S5C73M3
+
+#define S5C73M3_FW_PATH "/lib/firmware/SlimISP.bin"
+#define S5C73M3_FW_GC_PATH "/lib/firmware/SlimISP_GC.bin"
+#define S5C73M3_FW_GD_PATH "/lib/firmware/SlimISP_GD.bin"
+#define S5C73M3_FW_GE_PATH "/lib/firmware/SlimISP_GE.bin"
+#define S5C73M3_FW_GF_PATH "/lib/firmware/SlimISP_GF.bin"
+#define S5C73M3_FW_ZC_PATH "/lib/firmware/SlimISP_ZC.bin"
+#define S5C73M3_FW_ZD_PATH "/lib/firmware/SlimISP_ZD.bin"
+#define S5C73M3_FW_ZE_PATH "/lib/firmware/SlimISP_ZE.bin"
+#define S5C73M3_FW_ZF_PATH "/lib/firmware/SlimISP_ZF.bin"
+#define S5C73M3_FW_ZG_PATH "/lib/firmware/SlimISP_ZG.bin"
+
+#else /* CONFIG_VIDEO_SLP_S5C73M3 */
+
+/* For Android */
+#define S5C73M3_FW_PATH "/sdcard/SlimISP.bin"
+
+#endif /* CONFIG_VIDEO_SLP_S5C73M3 */
+
+#define S5C73M3_FW_VER_LEN 6
+#define S5C73M3_FW_VER_FILE_CUR 0x60
+
+#define S5C73M3_FLASH_BASE_ADDR 0x10000000
+#define S5C73M3_INT_RAM_BASE_ADDR 0x68000000
+
+#define S5C73M3_I2C_RETRY 5
+#define S5C73M3_I2C_VERIFY 100
+#define S5C73M3_ISP_TIMEOUT 3000
+#define S5C73M3_ISP_AFB_TIMEOUT 15000 /* FIXME */
+#define S5C73M3_ISP_ESD_TIMEOUT 1000
+
+#define S5C73M3_JPEG_MAXSIZE 0x800000
+#define S5C73M3_YUV_MAXSIZE 0x3F4800 /*FHD*/
+#define S5C73M3_POINTER_MAXSIZE 0x10E0 /*FHD*/
+
+#define S5C73M3_DEF_APEX_DEN 100
+
+#define CHECK_ERR(x) if ((x) < 0) { \
+ cam_err("i2c failed, err %d\n", x); \
+ return x; \
+ }
+static const struct s5c73m3_frmsizeenum preview_frmsizes[] = {
+ { S5C73M3_PREVIEW_QVGA, 320, 240, 0x01 },
+ { S5C73M3_PREVIEW_CIF, 352, 288, 0x0E },
+ { S5C73M3_PREVIEW_VGA, 640, 480, 0x02 },
+ { S5C73M3_PREVIEW_880X720, 880, 720, 0x03 },
+ { S5C73M3_PREVIEW_960X720, 960, 720, 0x04 },
+ { S5C73M3_PREVIEW_1008X672, 1008, 672, 0x0F },
+ { S5C73M3_PREVIEW_1184X666, 1184, 666, 0x05 },
+ { S5C73M3_PREVIEW_720P, 1280, 720, 0x06 },
+ { S5C73M3_VDIS_720P, 1536, 864, 0x07 },
+ { S5C73M3_PREVIEW_1080P, 1920, 1080, 0x0A},
+ { S5C73M3_VDIS_1080P, 2304, 1296, 0x0C},
+};
+
+static const struct s5c73m3_frmsizeenum capture_frmsizes[] = {
+ { S5C73M3_CAPTURE_VGA, 640, 480, 0x10 },
+ { S5C73M3_CAPTURE_1024X768, 1024, 768, 0xD0 },
+ { S5C73M3_CAPTURE_HD, 1280, 720, 0x40 },
+ { S5C73M3_CAPTURE_2MP, 1600, 1200, 0x70 },
+ { S5C73M3_CAPTURE_W2MP, 2048, 1152, 0x80 },
+ { S5C73M3_CAPTURE_3MP, 2048, 1536, 0x90 },
+ { S5C73M3_CAPTURE_W4MP, 2560, 1440, 0xA0 },
+ { S5C73M3_CAPTURE_5MP, 2560, 1920, 0xB0 },
+ { S5C73M3_CAPTURE_W6MP, 3264, 1836, 0xE0 },
+ { S5C73M3_CAPTURE_3264X2176, 3264, 2176, 0xC0 },
+ { S5C73M3_CAPTURE_8MP, 3264, 2448, 0xF0 },
+};
+
+static struct s5c73m3_control s5c73m3_ctrls[] = {
+ /* Exposure & Scenemode stuff(ISO, Metering, Saturation, etc) */
+ {
+ .id = V4L2_CID_CAMERA_ISO,
+ .minimum = ISO_AUTO,
+ .maximum = ISO_800,
+ .step = 1,
+ .value = ISO_AUTO,
+ .default_value = ISO_AUTO,
+ }, {
+ /* Capture */
+ .id = V4L2_CID_CAM_JPEG_QUALITY,
+ .minimum = 1,
+ .maximum = 100,
+ .step = 1,
+ .value = 100,
+ .default_value = 100,
+ },
+#ifdef CONFIG_VIDEO_SLP_S5C73M3
+ {
+ /* Flash */
+ .id = V4L2_CID_CAMERA_FLASH_MODE,
+ .minimum = FLASH_MODE_OFF,
+ .maximum = FLASH_MODE_MAX - 1,
+ .step = 1,
+ .value = FLASH_MODE_OFF,
+ .default_value = FLASH_MODE_OFF,
+ }, {
+ .id = V4L2_CID_EXPOSURE,
+ .minimum = EV_MINUS_4,
+ .maximum = EV_MAX - 1,
+ .step = 1,
+ .value = EV_DEFAULT,
+ .default_value = EV_DEFAULT,
+ }, {
+ .id = V4L2_CID_SATURATION,
+ .minimum = SATURATION_MINUS_2,
+ .maximum = SATURATION_MAX - 1,
+ .step = 1,
+ .value = SATURATION_DEFAULT,
+ .default_value = SATURATION_DEFAULT,
+ }, {
+ .id = V4L2_CID_SHARPNESS,
+ .minimum = SHARPNESS_MINUS_2,
+ .maximum = SHARPNESS_MAX - 1,
+ .step = 1,
+ .value = SHARPNESS_DEFAULT,
+ .default_value = SHARPNESS_DEFAULT,
+ }, {
+ .id = V4L2_CID_CAMERA_METERING,
+ .minimum = METERING_MATRIX,
+ .maximum = METERING_MAX - 1,
+ .step = 1,
+ .value = METERING_MATRIX,
+ .default_value = METERING_MATRIX,
+ }, {
+ .id = V4L2_CID_WHITE_BALANCE_PRESET,
+ .minimum = WHITE_BALANCE_AUTO,
+ .maximum = WHITE_BALANCE_MAX - 1,
+ .step = 1,
+ .value = WHITE_BALANCE_AUTO,
+ .default_value = WHITE_BALANCE_AUTO,
+ }, {
+ .id = V4L2_CID_COLORFX,
+ .minimum = V4L2_COLORFX_NONE,
+ .maximum = V4L2_COLORFX_VIVID,
+ .step = 1,
+ .value = V4L2_COLORFX_NONE,
+ .default_value = V4L2_COLORFX_NONE,
+ }, {
+ .id = V4L2_CID_CAMERA_SCENE_MODE,
+ .minimum = SCENE_MODE_NONE,
+ .maximum = SCENE_MODE_MAX - 1,
+ .step = 1,
+ .value = SCENE_MODE_NONE,
+ .default_value = SCENE_MODE_MAX,
+ }, {
+ /* Zoom */
+ .id = V4L2_CID_ZOOM_ABSOLUTE,
+ .minimum = ZOOM_LEVEL_0,
+ .maximum = ZOOM_LEVEL_MAX - 1,
+ .step = 1,
+ .value = ZOOM_LEVEL_0,
+ .default_value = ZOOM_LEVEL_0,
+ }, {
+ /* Focus */
+ .id = V4L2_CID_FOCUS_AUTO_RECTANGLE_LEFT,
+ .minimum = 0,
+ .maximum = 4000, /* FIXME */
+ .step = 1,
+ .value = 0,
+ .default_value = 0,
+ }, {
+ .id = V4L2_CID_FOCUS_AUTO_RECTANGLE_TOP,
+ .minimum = 0,
+ .maximum = 3000, /* FIXME */
+ .step = 1,
+ .value = 0,
+ .default_value = 0,
+ }, {
+ .id = V4L2_CID_FOCUS_AUTO_RECTANGLE_WIDTH,
+ .minimum = 0,
+ .maximum = 4000, /* FIXME */
+ .step = 1,
+ .value = 0,
+ .default_value = 0,
+ }, {
+ .id = V4L2_CID_FOCUS_AUTO_RECTANGLE_HEIGHT,
+ .minimum = 0,
+ .maximum = 3000, /* FIXME */
+ .step = 1,
+ .value = 0,
+ .default_value = 0,
+ }, {
+ .id = V4L2_CID_CAMERA_FOCUS_MODE,
+ .minimum = FOCUS_MODE_AUTO,
+ .maximum = FOCUS_MODE_MAX,
+ .step = 1,
+ .value = FOCUS_MODE_AUTO,
+ .default_value = FOCUS_MODE_AUTO,
+ }, {
+ .id = V4L2_CID_CAMERA_SET_AUTO_FOCUS,
+ .minimum = 0,
+ .maximum = 1,
+ .step = 1,
+ .value = 0,
+ .default_value = 0,
+ }, {
+ .id = V4L2_CID_PHYSICAL_ROTATION,
+ .minimum = IS_ROTATION_0,
+ .maximum = IS_ROTATION_MAX - 1,
+ .step = 1,
+ .value = IS_ROTATION_90,
+ .default_value = IS_ROTATION_90,
+ },
+#else
+ {
+ .id = V4L2_CID_CAMERA_BRIGHTNESS,
+ .minimum = EV_MINUS_4,
+ .maximum = EV_MAX - 1,
+ .step = 1,
+ .value = EV_DEFAULT,
+ .default_value = EV_DEFAULT,
+ }, {
+ .id = V4L2_CID_CAMERA_SATURATION,
+ .minimum = SATURATION_MINUS_2,
+ .maximum = SATURATION_MAX - 1,
+ .step = 1,
+ .value = SATURATION_DEFAULT,
+ .default_value = SATURATION_DEFAULT,
+ }, {
+ .id = V4L2_CID_CAMERA_SHARPNESS,
+ .minimum = SHARPNESS_MINUS_2,
+ .maximum = SHARPNESS_MAX - 1,
+ .step = 1,
+ .value = SHARPNESS_DEFAULT,
+ .default_value = SHARPNESS_DEFAULT,
+ }, {
+ /* Zoom */
+ .id = V4L2_CID_CAMERA_ZOOM,
+ .minimum = ZOOM_LEVEL_0,
+ .maximum = ZOOM_LEVEL_MAX - 1,
+ .step = 1,
+ .value = ZOOM_LEVEL_0,
+ .default_value = ZOOM_LEVEL_0,
+ },
+#endif
+
+};
+
+static u8 sysfs_sensor_fw[10] = {0,};
+static u8 sysfs_phone_fw[10] = {0,};
+static u8 sysfs_sensor_type[15] = {0,};
+static u8 sysfs_isp_core[10] = {0,};
+
+static int s5c73m3_s_stream_sensor(struct v4l2_subdev *sd, int onoff);
+static int s5c73m3_set_touch_auto_focus(struct v4l2_subdev *sd);
+static int s5c73m3_SPI_booting(struct v4l2_subdev *sd);
+static int s5c73m3_get_af_cal_version(struct v4l2_subdev *sd);
+
+static inline struct s5c73m3_state *to_state(struct v4l2_subdev *sd)
+{
+ return container_of(sd, struct s5c73m3_state, sd);
+}
+
+static int s5c73m3_i2c_write(struct v4l2_subdev *sd,
+ unsigned short addr, unsigned short data)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct i2c_msg msg;
+ unsigned char buf[4];
+ int i, err;
+
+ if (!client->adapter)
+ return -ENODEV;
+
+ msg.addr = client->addr;
+ msg.flags = 0;
+ msg.len = sizeof(buf);
+ msg.buf = buf;
+
+ buf[0] = addr >> 8;
+ buf[1] = addr & 0xff;
+ buf[2] = data >> 8;
+ buf[3] = data & 0xff;
+
+ cam_i2c_dbg("addr %#x, data %#x\n", addr, data);
+
+ for (i = S5C73M3_I2C_RETRY; i; i--) {
+ err = i2c_transfer(client->adapter, &msg, 1);
+ if (err == 1)
+ break;
+ msleep(20);
+ }
+
+ return err;
+}
+
+static int s5c73m3_i2c_write_block(struct v4l2_subdev *sd,
+ const u32 regs[], int size)
+{
+ int i, err = 0;
+
+ for (i = 0; i < size; i++) {
+ err = s5c73m3_i2c_write(sd, (regs[i]>>16), regs[i]);
+ CHECK_ERR(err);
+ }
+
+ return err;
+}
+
+static int s5c73m3_i2c_read(struct v4l2_subdev *sd,
+ unsigned short addr, unsigned short *data)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct i2c_msg msg;
+ unsigned char buf[2];
+ int i, err;
+
+ if (!client->adapter)
+ return -ENODEV;
+
+ msg.addr = client->addr;
+ msg.flags = 0;
+ msg.len = sizeof(buf);
+ msg.buf = buf;
+
+ buf[0] = addr >> 8;
+ buf[1] = addr & 0xff;
+
+ for (i = S5C73M3_I2C_RETRY; i; i--) {
+ err = i2c_transfer(client->adapter, &msg, 1);
+ if (err == 1)
+ break;
+ msleep(20);
+ }
+
+ if (err != 1) {
+ cam_err("addr %#x\n", addr);
+ return err;
+ }
+
+ msg.flags = I2C_M_RD;
+
+ for (i = S5C73M3_I2C_RETRY; i; i--) {
+ err = i2c_transfer(client->adapter, &msg, 1);
+ if (err == 1)
+ break;
+ msleep(20);
+ }
+
+ if (err != 1) {
+ cam_err("addr %#x\n", addr);
+ return err;
+ }
+
+ *data = ((buf[0] << 8) | buf[1]);
+
+ return err;
+}
+
+static int s5c73m3_write(struct v4l2_subdev *sd,
+ unsigned short addr1, unsigned short addr2, unsigned short data)
+{
+ int err;
+
+ err = s5c73m3_i2c_write(sd, 0x0050, addr1);
+ CHECK_ERR(err);
+
+ err = s5c73m3_i2c_write(sd, 0x0054, addr2);
+ CHECK_ERR(err);
+
+ err = s5c73m3_i2c_write(sd, 0x0F14, data);
+ CHECK_ERR(err);
+
+ return err;
+}
+
+static int s5c73m3_read(struct v4l2_subdev *sd,
+ unsigned short addr1, unsigned short addr2, unsigned short *data)
+{
+ int err;
+
+ err = s5c73m3_i2c_write(sd, 0xfcfc, 0x3310);
+ CHECK_ERR(err);
+
+ err = s5c73m3_i2c_write(sd, 0x0058, addr1);
+ CHECK_ERR(err);
+
+ err = s5c73m3_i2c_write(sd, 0x005C, addr2);
+ CHECK_ERR(err);
+
+ err = s5c73m3_i2c_read(sd, 0x0F14, data);
+ CHECK_ERR(err);
+
+ return err;
+}
+
+static int s5c73m3_i2c_check_status(struct v4l2_subdev *sd)
+{
+ int err = 0;
+ int index = 0;
+ u16 status = 0;
+ u16 i2c_status = 0;
+
+ do {
+ err = s5c73m3_read(sd, 0x0009, 0x5080, &status);
+ if (status == 0xffff)
+ break;
+ err = s5c73m3_read(sd, 0x0009, 0x599E, &i2c_status);
+ if (i2c_status != 0)
+ cam_dbg("i2c_status = %#x\n", i2c_status);
+
+ index++;
+ udelay(500);
+ } while (index < 2000); /* 1 sec */
+
+ cam_dbg("index : %d, status : %#x, i2c_stauts : %#x\n",
+ index, status, i2c_status);
+
+ if (index >= 2000)
+ err = -1;
+
+ return err;
+}
+
+static int s5c73m3_writeb_no_check_status(struct v4l2_subdev *sd,
+ unsigned short addr, unsigned short data)
+{
+ int err;
+
+ err = s5c73m3_i2c_write(sd, 0x0050, 0x0009);
+ CHECK_ERR(err);
+
+ err = s5c73m3_i2c_write(sd, 0x0054, 0x5000);
+ CHECK_ERR(err);
+
+ err = s5c73m3_i2c_write(sd, 0x0F14, addr);
+ CHECK_ERR(err);
+
+ err = s5c73m3_i2c_write(sd, 0x0F14, data);
+ CHECK_ERR(err);
+
+ err = s5c73m3_i2c_write(sd, 0x0054, 0x5080);
+ CHECK_ERR(err);
+
+ err = s5c73m3_i2c_write(sd, 0x0F14, 0x0001);
+ CHECK_ERR(err);
+
+ return err;
+}
+
+static int s5c73m3_writeb(struct v4l2_subdev *sd,
+ unsigned short addr, unsigned short data)
+{
+ int err;
+ err = s5c73m3_i2c_check_status(sd);
+ CHECK_ERR(err);
+
+ err = s5c73m3_i2c_write(sd, 0x0050, 0x0009);
+ CHECK_ERR(err);
+
+ err = s5c73m3_i2c_write(sd, 0x0054, 0x5000);
+ CHECK_ERR(err);
+
+ err = s5c73m3_i2c_write(sd, 0x0F14, addr);
+ CHECK_ERR(err);
+
+ err = s5c73m3_i2c_write(sd, 0x0F14, data);
+ CHECK_ERR(err);
+
+ err = s5c73m3_i2c_write(sd, 0x0054, 0x5080);
+ CHECK_ERR(err);
+
+ err = s5c73m3_i2c_write(sd, 0x0F14, 0x0001);
+ CHECK_ERR(err);
+
+ return err;
+}
+
+static int s5c73m3_set_mode(struct v4l2_subdev *sd)
+{
+ struct s5c73m3_state *state = to_state(sd);
+ int err;
+ cam_trace("E\n");
+
+ if (state->format_mode != V4L2_PIX_FMT_MODE_CAPTURE) {
+ if (state->hdr_mode) {
+ err = s5c73m3_writeb(sd, S5C73M3_IMG_OUTPUT,
+ S5C73M3_HDR_OUTPUT);
+ CHECK_ERR(err);
+ cam_dbg("hdr ouput mode\n");
+ } else {
+ err = s5c73m3_writeb(sd, S5C73M3_IMG_OUTPUT,
+ S5C73M3_YUV_OUTPUT);
+ CHECK_ERR(err);
+ cam_dbg("yuv ouput mode\n");
+ }
+ } else {
+ if (state->hybrid_mode) {
+ err = s5c73m3_writeb(sd, S5C73M3_IMG_OUTPUT,
+ S5C73M3_HYBRID_OUTPUT);
+ CHECK_ERR(err);
+ cam_dbg("hybrid ouput mode\n");
+ } else {
+ err = s5c73m3_writeb(sd, S5C73M3_IMG_OUTPUT,
+ S5C73M3_INTERLEAVED_OUTPUT);
+ CHECK_ERR(err);
+ cam_dbg("interleaved ouput mode\n");
+ }
+ }
+
+ cam_trace("X\n");
+ return 0;
+}
+
+/*
+ * v4l2_subdev_core_ops
+ */
+static int s5c73m3_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(s5c73m3_ctrls); i++) {
+ if (qc->id == s5c73m3_ctrls[i].id) {
+ qc->maximum = s5c73m3_ctrls[i].maximum;
+ qc->minimum = s5c73m3_ctrls[i].minimum;
+ qc->step = s5c73m3_ctrls[i].step;
+ qc->default_value = s5c73m3_ctrls[i].default_value;
+ return 0;
+ }
+ }
+
+ return -EINVAL;
+}
+
+#ifdef CONFIG_TARGET_LOCALE_KOR
+static int s5c73m3_set_antibanding(struct v4l2_subdev *sd, int val)
+{
+ return 0;
+}
+#endif
+
+static int s5c73m3_set_af_softlanding(struct v4l2_subdev *sd)
+{
+ int err = 0;
+
+ cam_trace("E\n");
+
+ err = s5c73m3_writeb(sd, S5C73M3_AF_SOFTLANDING,
+ S5C73M3_AF_SOFTLANDING_ON);
+ CHECK_ERR(err);
+ cam_trace("X\n");
+
+ return 0;
+}
+
+static int s5c73m3_dump_fw(struct v4l2_subdev *sd)
+{
+ return 0;
+}
+
+static int s5c73m3_get_sensor_fw_version(struct v4l2_subdev *sd)
+{
+ struct s5c73m3_state *state = to_state(sd);
+ u16 read_val;
+ u16 sensor_fw;
+ u16 sensor_type;
+ int i;
+ int err = 0;
+
+ /*ARM go*/
+ err = s5c73m3_write(sd, 0x3000, 0x0004, 0xFFFF);
+ CHECK_ERR(err);
+
+ udelay(400);
+
+ /*Check boot done*/
+ for (i = 0; i < 3; i++) {
+ err = s5c73m3_read(sd, 0x3010, 0x0010, &read_val);
+ CHECK_ERR(err);
+
+ if (read_val == 0x0C)
+ break;
+
+ udelay(100);
+ }
+
+ if (read_val != 0x0C) {
+ cam_err("boot fail, read_val %#x\n", read_val);
+ return -1;
+ }
+
+ /*P,M,S and Boot Mode*/
+ err = s5c73m3_write(sd, 0x3010, 0x0014, 0x2146);
+ CHECK_ERR(err);
+ err = s5c73m3_write(sd, 0x3010, 0x0010, 0x230C);
+ CHECK_ERR(err);
+
+ udelay(200);
+
+ /*Check SPI ready*/
+ for (i = 0; i < 300; i++) {
+ err = s5c73m3_read(sd, 0x3010, 0x0010, &read_val);
+ CHECK_ERR(err);
+
+ if (read_val == 0x230E)
+ break;
+
+ udelay(100);
+ }
+
+ if (read_val != 0x230E) {
+ cam_err("SPI not ready, read_val %#x\n", read_val);
+ return -1;
+ }
+
+ /*ARM reset*/
+ err = s5c73m3_write(sd, 0x3000, 0x0004, 0xFFFD);
+ CHECK_ERR(err);
+
+ /*remap*/
+ err = s5c73m3_write(sd, 0x3010, 0x00A4, 0x0183);
+ CHECK_ERR(err);
+
+ /*ARM go again*/
+ err = s5c73m3_write(sd, 0x3000, 0x0004, 0xFFFF);
+ CHECK_ERR(err);
+
+ for (i = 0; i < 3; i++) {
+ err = s5c73m3_read(sd, 0x0000, 0x0060+i*2, &sensor_fw);
+ CHECK_ERR(err);
+ state->sensor_fw[i*2] = sensor_fw&0x00ff;
+ state->sensor_fw[i*2+1] = (sensor_fw&0xff00)>>8;
+ }
+ state->sensor_fw[i*2+2] = ' ';
+
+ for (i = 0; i < 6; i++) {
+ err = s5c73m3_read(sd, 0x0000, 0x0066+i*2, &sensor_type);
+ CHECK_ERR(err);
+ state->sensor_type[i*2] = sensor_type&0x00ff;
+ state->sensor_type[i*2+1] = (sensor_type&0xff00)>>8;
+ }
+ state->sensor_type[i*2+2] = ' ';
+
+ memcpy(sysfs_sensor_fw, state->sensor_fw,
+ sizeof(state->sensor_fw));
+ memcpy(sysfs_sensor_type, state->sensor_type,
+ sizeof(state->sensor_type));
+
+ cam_dbg("Sensor_version = %s, Sensor_Type = %s\n",
+ state->sensor_fw, state->sensor_type);
+
+ if ((state->sensor_fw[0] < 'A') || state->sensor_fw[0] > 'Z') {
+ cam_dbg("Sensor Version is invalid data\n");
+ err = -1;
+ }
+ return err;
+}
+
+
+static int s5c73m3_get_phone_fw_version(struct v4l2_subdev *sd)
+{
+ struct device *dev = sd->v4l2_dev->dev;
+ struct s5c73m3_state *state = to_state(sd);
+ const struct firmware *fw = {0, };
+ char fw_path[20] = {0,};
+ u8 *buf = NULL;
+ int err = 0;
+
+ struct file *fp;
+ mm_segment_t old_fs;
+ long nread;
+ int fw_requested = 1;
+
+ buf = vmalloc(S5C73M3_FW_VER_LEN+1);
+ if (!buf) {
+ cam_err("failed to allocate memory\n");
+ err = -ENOMEM;
+ goto out;
+ }
+
+ old_fs = get_fs();
+ set_fs(KERNEL_DS);
+
+ fp = filp_open(S5C73M3_FW_PATH, O_RDONLY, 0);
+ if (IS_ERR(fp)) {
+ cam_trace("failed to open %s, err %ld\n",
+ S5C73M3_FW_PATH, PTR_ERR(fp));
+ goto request_fw;
+ }
+
+ fw_requested = 0;
+ err = vfs_llseek(fp, S5C73M3_FW_VER_FILE_CUR, SEEK_SET);
+ if (err < 0) {
+ cam_warn("failed to fseek, %d\n", err);
+ goto out;
+ }
+
+ nread = vfs_read(fp, (char __user *)buf,
+ S5C73M3_FW_VER_LEN,
+ &fp->f_pos);
+
+ if (nread != S5C73M3_FW_VER_LEN) {
+ cam_err("failed to read firmware file, %ld Bytes\n", nread);
+ err = -EIO;
+ goto out;
+ }
+
+request_fw:
+ if (fw_requested) {
+ set_fs(old_fs);
+
+ if (state->sensor_fw[0] == 'O') {
+ sprintf(fw_path, "SlimISP_G%c.bin",
+ state->sensor_fw[1]);
+ } else if (state->sensor_fw[0] == 'S') {
+ sprintf(fw_path, "SlimISP_Z%c.bin",
+ state->sensor_fw[1]);
+ } else {
+ sprintf(fw_path, "SlimISP_%c%c.bin",
+ state->sensor_fw[0],
+ state->sensor_fw[1]);
+ }
+ cam_dbg("file_name = %s\n", fw_path);
+
+ err = request_firmware(&fw, fw_path, dev);
+ if (err != 0) {
+ cam_err("request_firmware falied\n");
+ err = -EINVAL;
+ goto out;
+ }
+
+ memcpy(buf, (u8 *)&fw->data[S5C73M3_FW_VER_FILE_CUR],
+ S5C73M3_FW_VER_LEN);
+
+ }
+
+ memcpy(state->phone_fw, buf, S5C73M3_FW_VER_LEN);
+ state->phone_fw[S5C73M3_FW_VER_LEN+1] = ' ';
+
+ memcpy(sysfs_phone_fw, state->phone_fw, sizeof(state->phone_fw));
+ cam_dbg("Phone_version = %s\n", state->phone_fw);
+
+ cam_dbg("end\n");
+
+out:
+ if (!fw_requested) {
+ vfree(buf);
+
+ filp_close(fp, current->files);
+ set_fs(old_fs);
+ } else {
+ release_firmware(fw);
+ }
+
+ return err;
+}
+
+static int s5c73m3_update_camerafw_to_FROM(struct v4l2_subdev *sd)
+{
+ int err;
+ int index = 0;
+ u16 status = 0;
+
+ do {
+ /* stauts 0 : not ready ISP */
+ if (status == 0) {
+ err = s5c73m3_writeb(sd, 0x0906, 0x0000);
+ CHECK_ERR(err);
+ }
+
+ err = s5c73m3_read(sd, 0x0009, 0x5906, &status);
+ /* Success : 0x05, Fail : 0x07 , Progressing : 0xFFFF*/
+ if (status == 0x0005 ||
+ status == 0x0007)
+ break;
+
+ index++;
+ msleep(20);
+ } while (index < 500); /* 10 sec */
+
+
+ if (status == 0x0007)
+ return -1;
+ else
+ return 0;
+}
+
+static int s5c73m3_check_fw(struct v4l2_subdev *sd, int download)
+{
+ struct s5c73m3_state *state = to_state(sd);
+ int err;
+
+ if (download) {
+ err = state->pdata->is_isp_reset();
+ CHECK_ERR(err);
+ }
+
+ err = s5c73m3_get_sensor_fw_version(sd);
+ err = s5c73m3_get_phone_fw_version(sd);
+
+ if (state->phone_fw[0] == 'Z' || state->phone_fw[0] == 'G' ||
+ state->phone_fw[0] == 'S' || state->phone_fw[0] == 'O') {
+ err = state->pdata->is_isp_reset();
+ CHECK_ERR(err);
+
+ err = s5c73m3_SPI_booting(sd);
+ CHECK_ERR(err);
+
+ if (download) {
+ err = s5c73m3_update_camerafw_to_FROM(sd);
+ CHECK_ERR(err);
+ }
+ }
+ s5c73m3_get_af_cal_version(sd);
+ return 0;
+}
+
+static int s5c73m3_set_sensor_mode(struct v4l2_subdev *sd, int val)
+{
+ struct s5c73m3_state *state = to_state(sd);
+ int err;
+ cam_dbg("E, value %d\n", val);
+
+retry:
+ switch (val) {
+ case SENSOR_CAMERA:
+ err = s5c73m3_writeb(sd, S5C73M3_AE_MODE,
+ S5C73M3_AUTO_MODE_AE_SET);
+ CHECK_ERR(err);
+ break;
+
+ case SENSOR_MOVIE:
+ err = s5c73m3_writeb(sd, S5C73M3_AE_MODE,
+ S5C73M3_FIXED_30FPS);
+ CHECK_ERR(err);
+ break;
+
+ default:
+ cam_warn("invalid value, %d\n", val);
+ val = SENSOR_CAMERA;
+ goto retry;
+ }
+ state->sensor_mode = val;
+
+ cam_trace("X\n");
+ return 0;
+}
+
+static int s5c73m3_set_flash(struct v4l2_subdev *sd, int val, int recording)
+{
+ struct s5c73m3_state *state = to_state(sd);
+ int err;
+ cam_dbg("E, value %d\n", val);
+
+retry:
+ switch (val) {
+ case FLASH_MODE_OFF:
+ err = s5c73m3_writeb(sd, S5C73M3_FLASH_MODE,
+ S5C73M3_FLASH_MODE_OFF);
+ CHECK_ERR(err);
+ err = s5c73m3_writeb(sd, S5C73M3_FLASH_TORCH,
+ S5C73M3_FLASH_TORCH_OFF);
+ CHECK_ERR(err);
+ break;
+
+ case FLASH_MODE_AUTO:
+ err = s5c73m3_writeb(sd, S5C73M3_FLASH_TORCH,
+ S5C73M3_FLASH_TORCH_OFF);
+ CHECK_ERR(err);
+ err = s5c73m3_writeb(sd, S5C73M3_FLASH_MODE,
+ S5C73M3_FLASH_MODE_AUTO);
+ CHECK_ERR(err);
+ break;
+
+ case FLASH_MODE_ON:
+ err = s5c73m3_writeb(sd, S5C73M3_FLASH_TORCH,
+ S5C73M3_FLASH_TORCH_OFF);
+ CHECK_ERR(err);
+ err = s5c73m3_writeb(sd, S5C73M3_FLASH_MODE,
+ S5C73M3_FLASH_MODE_ON);
+ CHECK_ERR(err);
+ break;
+
+ case FLASH_MODE_TORCH:
+ err = s5c73m3_writeb(sd, S5C73M3_FLASH_MODE,
+ S5C73M3_FLASH_MODE_OFF);
+ CHECK_ERR(err);
+ err = s5c73m3_writeb(sd, S5C73M3_FLASH_TORCH,
+ S5C73M3_FLASH_TORCH_ON);
+ CHECK_ERR(err);
+ break;
+
+ default:
+ cam_warn("invalid value, %d\n", val);
+ val = FLASH_MODE_OFF;
+ goto retry;
+ }
+ state->flash_mode = val;
+
+ cam_trace("X\n");
+ return 0;
+}
+
+static int s5c73m3_set_iso(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+{
+ int err;
+ struct s5c73m3_state *state = to_state(sd);
+ cam_dbg("E, value %d\n", ctrl->value);
+
+retry:
+ switch (ctrl->value) {
+ case ISO_AUTO:
+ err = s5c73m3_writeb(sd, S5C73M3_ISO,
+ S5C73M3_ISO_AUTO);
+ CHECK_ERR(err);
+ break;
+
+ case ISO_50:
+ case ISO_100:
+ err = s5c73m3_writeb(sd, S5C73M3_ISO,
+ S5C73M3_ISO_100);
+ CHECK_ERR(err);
+ break;
+
+ case ISO_200:
+ err = s5c73m3_writeb(sd, S5C73M3_ISO,
+ S5C73M3_ISO_200);
+ CHECK_ERR(err);
+ break;
+
+ case ISO_400:
+ err = s5c73m3_writeb(sd, S5C73M3_ISO,
+ S5C73M3_ISO_400);
+ CHECK_ERR(err);
+ break;
+
+ case ISO_800:
+ err = s5c73m3_writeb(sd, S5C73M3_ISO,
+ S5C73M3_ISO_800);
+ CHECK_ERR(err);
+ break;
+
+ default:
+ cam_warn("invalid value, %d\n", ctrl->value);
+ ctrl->value = ISO_AUTO;
+ goto retry;
+ }
+
+ state->exif.iso = ctrl->value;
+
+ cam_trace("X\n");
+ return 0;
+}
+
+static int s5c73m3_set_metering(struct v4l2_subdev *sd, int val)
+{
+ int err;
+ struct s5c73m3_state *state = to_state(sd);
+ cam_dbg("E, value %d\n", val);
+
+retry:
+ switch (val) {
+ case METERING_CENTER:
+ err = s5c73m3_writeb(sd, S5C73M3_METER,
+ S5C73M3_METER_CENTER);
+ CHECK_ERR(err);
+ break;
+
+ case METERING_SPOT:
+ err = s5c73m3_writeb(sd, S5C73M3_METER,
+ S5C73M3_METER_SPOT);
+ CHECK_ERR(err);
+ break;
+
+ case METERING_MATRIX:
+ err = s5c73m3_writeb(sd, S5C73M3_METER,
+ S5C73M3_METER_AVERAGE);
+ CHECK_ERR(err);
+ break;
+
+ default:
+ cam_warn("invalid value, %d\n", val);
+ val = METERING_CENTER;
+ goto retry;
+ }
+
+ state->exif.metering = val;
+
+ cam_trace("X\n");
+ return 0;
+}
+
+static int s5c73m3_set_exposure(struct v4l2_subdev *sd,
+ struct v4l2_control *ctrl)
+{
+ int err;
+ struct s5c73m3_state *state = to_state(sd);
+ cam_dbg("E, value %d\n", ctrl->value);
+
+ if (ctrl->value < -4 || ctrl->value > 4) {
+ cam_warn("invalid value, %d\n", ctrl->value);
+ ctrl->value = 0;
+ }
+ err = s5c73m3_writeb(sd, S5C73M3_EV,
+ ctrl->value + 4);
+ CHECK_ERR(err);
+
+ state->exif.bv = ctrl->value;
+
+ cam_trace("X\n");
+ return 0;
+}
+
+static int s5c73m3_set_contrast(struct v4l2_subdev *sd,
+ struct v4l2_control *ctrl)
+{
+ int err;
+ int contrast = 0;
+ cam_dbg("E, value %d\n", ctrl->value);
+
+ if (ctrl->value < -2 || ctrl->value > 2) {
+ cam_warn("invalid value, %d\n", ctrl->value);
+ ctrl->value = 0;
+ }
+ if (ctrl->value < 0)
+ contrast = (ctrl->value * (-1)) + 2;
+ else
+ contrast = ctrl->value;
+ err = s5c73m3_writeb(sd, S5C73M3_CONTRAST,
+ contrast);
+ CHECK_ERR(err);
+
+ cam_trace("X\n");
+ return 0;
+}
+
+static int s5c73m3_set_whitebalance(struct v4l2_subdev *sd, int val)
+{
+ struct s5c73m3_state *state = to_state(sd);
+ int err;
+ cam_dbg("E, value %d\n", val);
+
+retry:
+ switch (val) {
+ case WHITE_BALANCE_AUTO:
+ err = s5c73m3_writeb(sd, S5C73M3_AWB_MODE,
+ S5C73M3_AWB_MODE_AUTO);
+ CHECK_ERR(err);
+ break;
+
+ case WHITE_BALANCE_SUNNY:
+ err = s5c73m3_writeb(sd, S5C73M3_AWB_MODE,
+ S5C73M3_AWB_MODE_DAYLIGHT);
+ CHECK_ERR(err);
+ break;
+
+ case WHITE_BALANCE_CLOUDY:
+ err = s5c73m3_writeb(sd, S5C73M3_AWB_MODE,
+ S5C73M3_AWB_MODE_CLOUDY);
+ CHECK_ERR(err);
+ break;
+
+ case WHITE_BALANCE_TUNGSTEN:
+ err = s5c73m3_writeb(sd, S5C73M3_AWB_MODE,
+ S5C73M3_AWB_MODE_INCANDESCENT);
+ CHECK_ERR(err);
+ break;
+
+ case WHITE_BALANCE_FLUORESCENT:
+ err = s5c73m3_writeb(sd, S5C73M3_AWB_MODE,
+ S5C73M3_AWB_MODE_FLUORESCENT1);
+ CHECK_ERR(err);
+ break;
+
+ default:
+ cam_warn("invalid value, %d\n", val);
+ val = WHITE_BALANCE_AUTO;
+ goto retry;
+ }
+
+ state->wb_mode = val;
+
+ cam_trace("X\n");
+ return 0;
+}
+
+static int s5c73m3_set_sharpness(struct v4l2_subdev *sd,
+ struct v4l2_control *ctrl)
+{
+ struct s5c73m3_state *state = to_state(sd);
+ cam_dbg("E, value %d\n", ctrl->value);
+
+ cam_err("Sharpness control is not supported\n");
+
+ state->exif.sharpness = ctrl->value;
+
+ return 0;
+}
+
+static int s5c73m3_set_saturation(struct v4l2_subdev *sd,
+ struct v4l2_control *ctrl)
+{
+ struct s5c73m3_state *state = to_state(sd);
+ cam_dbg("E, value %d\n", ctrl->value);
+
+ cam_err("Saturation control is not supported\n");
+
+ state->exif.saturation = ctrl->value;
+
+ return 0;
+}
+
+static int s5c73m3_set_scene_mode(struct v4l2_subdev *sd, int val)
+{
+ struct s5c73m3_state *state = to_state(sd);
+ int err;
+ cam_dbg("E, value %d\n", val);
+
+retry:
+ switch (val) {
+ case SCENE_MODE_NONE:
+ err = s5c73m3_writeb(sd, S5C73M3_SCENE_MODE,
+ S5C73M3_SCENE_MODE_NONE);
+ CHECK_ERR(err);
+ break;
+
+ case SCENE_MODE_PORTRAIT:
+ err = s5c73m3_writeb(sd, S5C73M3_SCENE_MODE,
+ S5C73M3_SCENE_MODE_PORTRAIT);
+ CHECK_ERR(err);
+ break;
+
+ case SCENE_MODE_LANDSCAPE:
+ err = s5c73m3_writeb(sd, S5C73M3_SCENE_MODE,
+ S5C73M3_SCENE_MODE_LANDSCAPE);
+ CHECK_ERR(err);
+ break;
+
+ case SCENE_MODE_SPORTS:
+ err = s5c73m3_writeb(sd, S5C73M3_SCENE_MODE,
+ S5C73M3_SCENE_MODE_SPORTS);
+ CHECK_ERR(err);
+ break;
+
+ case SCENE_MODE_PARTY_INDOOR:
+ err = s5c73m3_writeb(sd, S5C73M3_SCENE_MODE,
+ S5C73M3_SCENE_MODE_INDOOR);
+ CHECK_ERR(err);
+ break;
+
+ case SCENE_MODE_BEACH_SNOW:
+ err = s5c73m3_writeb(sd, S5C73M3_SCENE_MODE,
+ S5C73M3_SCENE_MODE_BEACH);
+ CHECK_ERR(err);
+ break;
+
+ case SCENE_MODE_SUNSET:
+ err = s5c73m3_writeb(sd, S5C73M3_SCENE_MODE,
+ S5C73M3_SCENE_MODE_SUNSET);
+ CHECK_ERR(err);
+ break;
+
+ case SCENE_MODE_DUSK_DAWN:
+ err = s5c73m3_writeb(sd, S5C73M3_SCENE_MODE,
+ S5C73M3_SCENE_MODE_DAWN);
+ CHECK_ERR(err);
+ break;
+
+ case SCENE_MODE_FALL_COLOR:
+ err = s5c73m3_writeb(sd, S5C73M3_SCENE_MODE,
+ S5C73M3_SCENE_MODE_FALL);
+ CHECK_ERR(err);
+ break;
+
+ case SCENE_MODE_NIGHTSHOT:
+ err = s5c73m3_writeb(sd, S5C73M3_SCENE_MODE,
+ S5C73M3_SCENE_MODE_NIGHT);
+ CHECK_ERR(err);
+ break;
+
+ case SCENE_MODE_BACK_LIGHT:
+ err = s5c73m3_writeb(sd, S5C73M3_SCENE_MODE,
+ S5C73M3_SCENE_MODE_AGAINSTLIGHT);
+ CHECK_ERR(err);
+ break;
+
+ case SCENE_MODE_FIREWORKS:
+ err = s5c73m3_writeb(sd, S5C73M3_SCENE_MODE,
+ S5C73M3_SCENE_MODE_FIRE);
+ CHECK_ERR(err);
+ break;
+
+ case SCENE_MODE_TEXT:
+ err = s5c73m3_writeb(sd, S5C73M3_SCENE_MODE,
+ S5C73M3_SCENE_MODE_TEXT);
+ CHECK_ERR(err);
+ break;
+
+ case SCENE_MODE_CANDLE_LIGHT:
+ err = s5c73m3_writeb(sd, S5C73M3_SCENE_MODE,
+ S5C73M3_SCENE_MODE_CANDLE);
+ CHECK_ERR(err);
+ break;
+
+ default:
+ cam_warn("invalid value, %d\n", val);
+ val = SCENE_MODE_NONE;
+ goto retry;
+ }
+
+ state->scene_mode = val;
+ cam_trace("X\n");
+ return 0;
+}
+
+static int s5c73m3_capture_firework(struct v4l2_subdev *sd)
+{
+ int err = 0;
+
+ cam_dbg("E, capture_firework\n");
+
+ err = s5c73m3_writeb(sd, S5C73M3_FIREWORK_CAPTURE, 0x0001);
+ CHECK_ERR(err);
+
+ return err;
+}
+
+static int s5c73m3_set_effect(struct v4l2_subdev *sd, int val)
+{
+ int err;
+ struct s5c73m3_state *state = to_state(sd);
+ cam_dbg("E, value %d\n", val);
+
+retry:
+ switch (val) {
+ case IMAGE_EFFECT_NONE:
+ err = s5c73m3_writeb(sd, S5C73M3_IMAGE_EFFECT,
+ S5C73M3_IMAGE_EFFECT_NONE);
+ CHECK_ERR(err);
+ break;
+
+ case IMAGE_EFFECT_SEPIA:
+ err = s5c73m3_writeb(sd, S5C73M3_IMAGE_EFFECT,
+ S5C73M3_IMAGE_EFFECT_SEPIA);
+ CHECK_ERR(err);
+ break;
+
+ case IMAGE_EFFECT_BNW:
+ err = s5c73m3_writeb(sd, S5C73M3_IMAGE_EFFECT,
+ S5C73M3_IMAGE_EFFECT_MONO);
+ CHECK_ERR(err);
+ break;
+
+ case IMAGE_EFFECT_NEGATIVE:
+ err = s5c73m3_writeb(sd, S5C73M3_IMAGE_EFFECT,
+ S5C73M3_IMAGE_EFFECT_NEGATIVE);
+ CHECK_ERR(err);
+ break;
+
+ case IMAGE_EFFECT_AQUA:
+ err = s5c73m3_writeb(sd, S5C73M3_IMAGE_EFFECT,
+ S5C73M3_IMAGE_EFFECT_AQUA);
+ CHECK_ERR(err);
+ break;
+
+ default:
+ cam_warn("invalid value, %d\n", val);
+ val = IMAGE_EFFECT_NONE;
+ goto retry;
+ }
+
+ state->exif.effect = val;
+
+ cam_trace("X\n");
+ return 0;
+}
+
+static int s5c73m3_set_wdr(struct v4l2_subdev *sd, int val)
+{
+ int err;
+ struct s5c73m3_state *state = to_state(sd);
+ cam_dbg("E, value %d\n", val);
+
+retry:
+ switch (val) {
+ case WDR_OFF:
+ err = s5c73m3_writeb(sd, S5C73M3_WDR,
+ S5C73M3_WDR_OFF);
+ CHECK_ERR(err);
+ break;
+
+ case WDR_ON:
+ err = s5c73m3_writeb(sd, S5C73M3_WDR,
+ S5C73M3_WDR_ON);
+ CHECK_ERR(err);
+ break;
+
+ default:
+ cam_warn("invalid value, %d\n", val);
+ val = WDR_OFF;
+ goto retry;
+ }
+ state->exif.wdr = val;
+
+ cam_trace("X\n");
+ return 0;
+}
+
+static int s5c73m3_set_antishake(struct v4l2_subdev *sd, int val)
+{
+ int err = 0;
+ if (val) {
+ err = s5c73m3_writeb(sd, S5C73M3_AE_MODE,
+ S5C73M3_ANTI_SHAKE);
+ CHECK_ERR(err);
+ } else {
+ err = s5c73m3_writeb(sd, S5C73M3_AE_MODE,
+ S5C73M3_AUTO_MODE_AE_SET);
+ CHECK_ERR(err);
+ }
+ return err;
+}
+
+static int s5c73m3_set_face_beauty(struct v4l2_subdev *sd, int val)
+{
+ return 0;
+}
+
+static int s5c73m3_set_ae_lock(struct v4l2_subdev *sd, int val)
+{
+ int err;
+
+ if (val)
+ err = s5c73m3_writeb(sd, S5C73M3_AE_CON, S5C73M3_AE_STOP);
+ else
+ err = s5c73m3_writeb(sd, S5C73M3_AE_CON, S5C73M3_AE_START);
+
+ CHECK_ERR(err);
+
+ return err;
+}
+
+static int s5c73m3_set_awb_lock(struct v4l2_subdev *sd, int val)
+{
+ int err;
+
+ if (val)
+ err = s5c73m3_writeb(sd, S5C73M3_AWB_CON, S5C73M3_AWB_STOP);
+ else
+ err = s5c73m3_writeb(sd, S5C73M3_AWB_CON, S5C73M3_AWB_START);
+
+ CHECK_ERR(err);
+
+ return err;
+}
+
+static int s5c73m3_set_ae_awb_lock(struct v4l2_subdev *sd, int val)
+{
+ return 0;
+}
+
+static int s5c73m3_get_af_cal_version(struct v4l2_subdev *sd)
+{
+ struct s5c73m3_state *state = to_state(sd);
+ u16 status = 0;
+ int err = 0;
+
+ /* Calibration Device */
+ err = s5c73m3_read(sd, 0x0009, 0x300C, &status);
+ CHECK_ERR(err);
+ state->cal_device = status;
+
+ /* Calibration DLL Version */
+ status = 0;
+ err = s5c73m3_read(sd, 0x0009, 0x4FF8, &status);
+ CHECK_ERR(err);
+ state->cal_dll = status;
+
+ cam_dbg("Cal_Device = 0x%x, Cal_DLL = 0x%x\n",
+ state->cal_device, state->cal_dll);
+
+ return 0;
+}
+
+static int s5c73m3_stop_af_lens(struct v4l2_subdev *sd, int val)
+{
+ struct s5c73m3_state *state = to_state(sd);
+ int err;
+ cam_dbg("E, value\n");
+
+ if (val == CAF_START) {
+ if (state->focus.mode == FOCUS_MODE_CONTINOUS_VIDEO) {
+ err = s5c73m3_writeb(sd, S5C73M3_AF_MODE,
+ S5C73M3_AF_MODE_MOVIE_CAF_START);
+
+ } else {
+ err = s5c73m3_writeb(sd, S5C73M3_AF_MODE,
+ S5C73M3_AF_MODE_PREVIEW_CAF_START);
+ }
+ } else {
+ err = s5c73m3_writeb(sd, S5C73M3_AF_CON,
+ S5C73M3_AF_CON_STOP);
+ }
+ CHECK_ERR(err);
+
+ cam_dbg("X\n");
+
+ return err;
+}
+
+static int s5c73m3_set_af(struct v4l2_subdev *sd, int val)
+{
+ struct s5c73m3_state *state = to_state(sd);
+ int err = 0;
+
+ cam_info("%s, mode %#x\n", val ? "start" : "stop", state->focus.mode);
+
+ state->focus.status = 0;
+
+ if (val) {
+ state->isflash = S5C73M3_ISNEED_FLASH_ON;
+
+ if (state->focus.mode == FOCUS_MODE_TOUCH)
+ err = s5c73m3_set_touch_auto_focus(sd);
+ else
+ err = s5c73m3_writeb(sd, S5C73M3_AF_CON,
+ S5C73M3_AF_CON_START);
+ } else {
+ err = s5c73m3_writeb(sd, S5C73M3_STILL_MAIN_FLASH
+ , S5C73M3_STILL_MAIN_FLASH_CANCEL);
+ err = s5c73m3_writeb(sd, S5C73M3_AF_CON,
+ S5C73M3_AF_CON_STOP);
+ state->isflash = S5C73M3_ISNEED_FLASH_UNDEFINED;
+ }
+
+ CHECK_ERR(err);
+
+ cam_info("X\n");
+ return err;
+}
+
+static int s5c73m3_get_pre_flash(struct v4l2_subdev *sd,
+ struct v4l2_control *ctrl)
+{
+ int err = 0;
+ u16 pre_flash = false;
+
+ s5c73m3_read(sd, 0x0009, S5C73M3_STILL_PRE_FLASH | 0x5000, &pre_flash);
+ ctrl->value = pre_flash;
+ return err;
+}
+
+static int s5c73m3_get_af_result(struct v4l2_subdev *sd,
+ struct v4l2_control *ctrl)
+{
+ struct s5c73m3_state *state = to_state(sd);
+ int err = 0;
+ u16 af_status = S5C73M3_AF_STATUS_UNFOCUSED;
+ /*u16 temp_status = 0;*/
+
+ err = s5c73m3_read(sd, 0x0009, S5C73M3_AF_STATUS, &af_status);
+
+ /*err = s5c73m3_read(sd, 0x0009, 0x5840, &temp_status);*/
+
+ switch (af_status) {
+ case S5C73M3_AF_STATUS_FOCUSING:
+ case S5C73M3_CAF_STATUS_FOCUSING:
+ case S5C73M3_CAF_STATUS_FIND_SEARCHING_DIR:
+ case S5C73M3_AF_STATUS_INVALID:
+ ctrl->value = CAMERA_AF_STATUS_IN_PROGRESS;
+ break;
+
+ case S5C73M3_AF_STATUS_FOCUSED:
+ case S5C73M3_CAF_STATUS_FOCUSED:
+ ctrl->value = CAMERA_AF_STATUS_SUCCESS;
+ break;
+
+ case S5C73M3_CAF_STATUS_UNFOCUSED:
+ case S5C73M3_AF_STATUS_UNFOCUSED:
+ default:
+ ctrl->value = CAMERA_AF_STATUS_FAIL;
+ break;
+ }
+ state->focus.status = af_status;
+
+ /*cam_dbg("af_status = %d, frame_cnt = %d\n",
+ state->focus.status, temp_status);*/
+ return err;
+}
+
+static int s5c73m3_set_af_mode(struct v4l2_subdev *sd, int val)
+{
+ struct s5c73m3_state *state = to_state(sd);
+ int err;
+ cam_dbg("E, value %d\n", val);
+
+retry:
+ switch (val) {
+ case FOCUS_MODE_AUTO:
+ case FOCUS_MODE_INFINITY:
+ if (state->focus.mode != FOCUS_MODE_CONTINOUS_PICTURE) {
+ err = s5c73m3_writeb(sd, S5C73M3_AF_MODE,
+ S5C73M3_AF_MODE_NORMAL);
+ CHECK_ERR(err);
+ } else {
+ err = s5c73m3_writeb(sd, S5C73M3_AF_CON,
+ S5C73M3_AF_CON_STOP);
+ CHECK_ERR(err);
+ }
+
+ state->focus.mode = val;
+ state->caf_mode = S5C73M3_AF_MODE_NORMAL;
+ break;
+
+ case FOCUS_MODE_MACRO:
+ if (state->focus.mode != FOCUS_MODE_CONTINOUS_PICTURE_MACRO) {
+ err = s5c73m3_writeb(sd, S5C73M3_AF_MODE,
+ S5C73M3_AF_MODE_MACRO);
+ CHECK_ERR(err);
+ } else {
+ err = s5c73m3_writeb(sd, S5C73M3_AF_CON,
+ S5C73M3_AF_CON_STOP);
+ CHECK_ERR(err);
+ }
+
+ state->focus.mode = val;
+ state->caf_mode = S5C73M3_AF_MODE_MACRO;
+ break;
+
+ case FOCUS_MODE_CONTINOUS_PICTURE:
+ state->isflash = S5C73M3_ISNEED_FLASH_UNDEFINED;
+
+ if (val != state->focus.mode &&
+ state->caf_mode != S5C73M3_AF_MODE_NORMAL) {
+ state->focus.mode = val;
+
+ err = s5c73m3_writeb(sd, S5C73M3_AF_MODE,
+ S5C73M3_AF_MODE_NORMAL);
+ CHECK_ERR(err);
+ state->caf_mode = S5C73M3_AF_MODE_NORMAL;
+ }
+
+ err = s5c73m3_writeb(sd, S5C73M3_AF_MODE,
+ S5C73M3_AF_MODE_PREVIEW_CAF_START);
+ CHECK_ERR(err);
+ break;
+
+ case FOCUS_MODE_CONTINOUS_PICTURE_MACRO:
+ state->isflash = S5C73M3_ISNEED_FLASH_UNDEFINED;
+ if (val != state->focus.mode &&
+ state->caf_mode != S5C73M3_AF_MODE_MACRO) {
+ state->focus.mode = val;
+
+ err = s5c73m3_writeb(sd, S5C73M3_AF_MODE,
+ S5C73M3_AF_MODE_MACRO);
+ state->caf_mode = S5C73M3_AF_MODE_MACRO;
+ CHECK_ERR(err);
+ }
+
+ err = s5c73m3_writeb(sd, S5C73M3_AF_MODE,
+ S5C73M3_AF_MODE_PREVIEW_CAF_START);
+ CHECK_ERR(err);
+ break;
+
+ case FOCUS_MODE_CONTINOUS_VIDEO:
+ state->focus.mode = val;
+
+ err = s5c73m3_writeb(sd, S5C73M3_AF_MODE,
+ S5C73M3_AF_MODE_MOVIE_CAF_START);
+ CHECK_ERR(err);
+ break;
+
+ case FOCUS_MODE_FACEDETECT:
+ state->focus.mode = val;
+ break;
+
+ case FOCUS_MODE_TOUCH:
+ state->focus.mode = val;
+ break;
+
+ default:
+ cam_warn("invalid value, %d\n", val);
+ val = FOCUS_MODE_AUTO;
+ goto retry;
+ }
+
+ state->focus.mode = val;
+
+ cam_trace("X\n");
+ return 0;
+}
+
+static int s5c73m3_set_touch_auto_focus(struct v4l2_subdev *sd)
+{
+ struct s5c73m3_state *state = to_state(sd);
+ int err;
+
+ cam_dbg("s5c73m3_set_touch_auto_focus\n");
+
+#ifdef CONFIG_VIDEO_SLP_S5C73M3
+ cam_dbg("Rectangle Position(%d,%d,%d,%d)\n",
+ state->focus.top, state->focus.left,
+ state->focus.width, state->focus.height);
+ state->focus.pos_x = state->focus.left + state->focus.width / 2;
+ state->focus.pos_y = state->focus.top + state->focus.height / 2;
+#endif
+ cam_dbg("Touch Position(%d,%d)\n",
+ state->focus.pos_x, state->focus.pos_y);
+ cam_dbg("Preview Size(%d,%d)\n",
+ state->preview->width, state->preview->height);
+
+ err = s5c73m3_i2c_write(sd, 0xfcfc, 0x3310);
+ CHECK_ERR(err);
+
+ err = s5c73m3_i2c_write(sd, 0x0050, 0x0009);
+ CHECK_ERR(err);
+
+ err = s5c73m3_i2c_write(sd, 0x0054, S5C73M3_AF_TOUCH_POSITION);
+ CHECK_ERR(err);
+
+ err = s5c73m3_i2c_write(sd, 0x0F14, state->focus.pos_x);
+ CHECK_ERR(err);
+
+ err = s5c73m3_i2c_write(sd, 0x0F14, state->focus.pos_y);
+ CHECK_ERR(err);
+
+ err = s5c73m3_i2c_write(sd, 0x0F14, state->preview->width);
+ CHECK_ERR(err);
+
+ err = s5c73m3_i2c_write(sd, 0x0F14, state->preview->height);
+ CHECK_ERR(err);
+
+ err = s5c73m3_i2c_write(sd, 0x0050, 0x0009);
+ CHECK_ERR(err);
+
+ err = s5c73m3_i2c_write(sd, 0x0054, 0x5000);
+ CHECK_ERR(err);
+
+ err = s5c73m3_i2c_write(sd, 0x0F14, 0x0E0A);
+ CHECK_ERR(err);
+
+ err = s5c73m3_i2c_write(sd, 0x0F14, 0x0000);
+ CHECK_ERR(err);
+
+ err = s5c73m3_i2c_write(sd, 0x0054, 0x5080);
+ CHECK_ERR(err);
+
+ err = s5c73m3_i2c_write(sd, 0x0F14, 0x0001);
+ CHECK_ERR(err);
+
+ return 0;
+}
+
+static int s5c73m3_set_zoom(struct v4l2_subdev *sd, int value)
+{
+ int err;
+ cam_dbg("E, value %d\n", value);
+
+retry:
+ if (value < 0 || value > 30) {
+ cam_warn("invalid value, %d\n", value);
+ value = 0;
+ goto retry;
+ }
+ err = s5c73m3_writeb_no_check_status(sd, S5C73M3_ZOOM_STEP,
+ value);
+ CHECK_ERR(err);
+ mdelay(10);
+
+ cam_trace("X\n");
+ return 0;
+}
+
+static int s5c73m3_set_jpeg_quality(struct v4l2_subdev *sd,
+ struct v4l2_control *ctrl)
+{
+ int val = ctrl->value, err;
+ cam_dbg("E, value %d\n", val);
+
+ if (val <= 65) /* Normal */
+ err = s5c73m3_writeb(sd, S5C73M3_IMAGE_QUALITY,
+ S5C73M3_IMAGE_QUALITY_NORMAL);
+ else if (val <= 75) /* Fine */
+ err = s5c73m3_writeb(sd, S5C73M3_IMAGE_QUALITY,
+ S5C73M3_IMAGE_QUALITY_FINE);
+ else /* Superfine */
+ err = s5c73m3_writeb(sd, S5C73M3_IMAGE_QUALITY,
+ S5C73M3_IMAGE_QUALITY_SUPERFINE);
+
+ CHECK_ERR(err);
+
+ cam_trace("X\n");
+ return 0;
+}
+
+static int s5c73m3_get_exif(struct v4l2_subdev *sd)
+{
+ return 0;
+}
+
+static int s5c73m3_aeawb_lock_unlock(struct v4l2_subdev *sd, int val)
+{
+ struct s5c73m3_state *state = to_state(sd);
+ int err = 0;
+ int ae_lock = val & 0x1;
+ int awb_lock = (val & 0x2) >> 1;
+ int ae_lock_changed =
+ ~(ae_lock & state->ae_lock) & (ae_lock | state->ae_lock);
+ int awb_lock_changed =
+ ~(awb_lock & state->awb_lock) & (awb_lock | state->awb_lock);
+
+ if (ae_lock_changed) {
+ cam_dbg("ae lock - %s\n", ae_lock ? "true" : "false");
+ err = s5c73m3_writeb(sd, S5C73M3_AE_CON,
+ ae_lock ? S5C73M3_AE_STOP : S5C73M3_AE_START);
+ CHECK_ERR(err);
+ state->ae_lock = ae_lock;
+ }
+ if (awb_lock_changed &&
+ state->wb_mode == WHITE_BALANCE_AUTO) {
+ cam_dbg("awb lock - %s\n", awb_lock ? "true" : "false");
+ err = s5c73m3_writeb(sd, S5C73M3_AWB_CON,
+ awb_lock ? S5C73M3_AWB_STOP : S5C73M3_AWB_START);
+ CHECK_ERR(err);
+ state->awb_lock = awb_lock;
+ }
+
+ return 0;
+}
+
+static int s5c73m3_start_capture(struct v4l2_subdev *sd, int val)
+{
+ struct s5c73m3_state *state = to_state(sd);
+ int err = 0;
+ u16 isneed_flash = false;
+ u16 pre_flash = false;
+
+ s5c73m3_read(sd, 0x0009, S5C73M3_STILL_PRE_FLASH | 0x5000, &pre_flash);
+
+ if (state->flash_mode == FLASH_MODE_ON) {
+ if (!pre_flash) {
+ err = s5c73m3_writeb(sd, S5C73M3_STILL_PRE_FLASH
+ , S5C73M3_STILL_PRE_FLASH_FIRE);
+ msleep(100);
+ }
+ err = s5c73m3_writeb(sd, S5C73M3_STILL_MAIN_FLASH
+ , S5C73M3_STILL_MAIN_FLASH_FIRE);
+ } else if (state->flash_mode == FLASH_MODE_AUTO) {
+ if (pre_flash) {
+ err = s5c73m3_writeb(sd, S5C73M3_STILL_MAIN_FLASH
+ , S5C73M3_STILL_MAIN_FLASH_FIRE);
+ } else if (state->isflash != S5C73M3_ISNEED_FLASH_ON) {
+ err = s5c73m3_read(sd, 0x0009,
+ S5C73M3_AE_ISNEEDFLASH | 0x5000, &isneed_flash);
+ if (isneed_flash) {
+ err = s5c73m3_writeb(sd, S5C73M3_STILL_PRE_FLASH
+ , S5C73M3_STILL_PRE_FLASH_FIRE);
+ msleep(100);
+ err = s5c73m3_writeb(sd,
+ S5C73M3_STILL_MAIN_FLASH,
+ S5C73M3_STILL_MAIN_FLASH_FIRE);
+ }
+ }
+ }
+
+ state->isflash = S5C73M3_ISNEED_FLASH_UNDEFINED;
+
+ return 0;
+}
+
+static int s5c73m3_set_auto_bracket_mode(struct v4l2_subdev *sd)
+{
+ int err = 0;
+
+ err = s5c73m3_writeb(sd, S5C73M3_AE_AUTO_BRAKET,
+ S5C73M3_AE_AUTO_BRAKET_EV20);
+ CHECK_ERR(err);
+
+ return err;
+}
+
+static int s5c73m3_check_dataline(struct v4l2_subdev *sd, int val)
+{
+ return 0;
+}
+
+static int s5c73m3_check_esd(struct v4l2_subdev *sd)
+{
+ return 0;
+}
+
+static int s5c73m3_set_frame_rate(struct v4l2_subdev *sd, int fps)
+{
+ int err = 0;
+ struct s5c73m3_state *state = to_state(sd);
+
+ if (!state->stream_enable) {
+ state->fps = fps;
+ return 0;
+ }
+
+ switch (fps) {
+ case 30:
+ err = s5c73m3_writeb(sd, S5C73M3_AE_MODE,
+ S5C73M3_FIXED_30FPS); /* 30fps */
+ break;
+ case 20:
+ err = s5c73m3_writeb(sd, S5C73M3_AE_MODE,
+ S5C73M3_FIXED_20FPS); /* 20fps */
+ break;
+ case 15:
+ err = s5c73m3_writeb(sd, S5C73M3_AE_MODE,
+ S5C73M3_FIXED_15FPS); /* 15fps */
+ break;
+ default:
+ err = s5c73m3_writeb(sd, S5C73M3_AE_MODE,
+ S5C73M3_AUTO_MODE_AE_SET); /* auto */
+ break;
+ }
+ return err;
+}
+
+static int s5c73m3_set_face_zoom(struct v4l2_subdev *sd, int val)
+{
+ struct s5c73m3_state *state = to_state(sd);
+ int err;
+
+ cam_dbg("s5c73m3_set_face_zoom\n");
+#ifdef CONFIG_VIDEO_SLP_S5C73M3
+ cam_dbg("Rectangle Position(%d,%d,%d,%d)\n",
+ state->focus.top, state->focus.left,
+ state->focus.width, state->focus.height);
+ state->focus.pos_x = state->focus.left + state->focus.width / 2;
+ state->focus.pos_y = state->focus.top + state->focus.height / 2;
+#endif
+ cam_dbg("Touch Position(%d,%d)\n",
+ state->focus.pos_x, state->focus.pos_y);
+ cam_dbg("Preview Size(%d,%d)\n",
+ state->preview->width, state->preview->height);
+
+ err = s5c73m3_i2c_write(sd, 0xfcfc, 0x3310);
+ CHECK_ERR(err);
+
+ err = s5c73m3_i2c_write(sd, 0x0050, 0x0009);
+ CHECK_ERR(err);
+
+ err = s5c73m3_i2c_write(sd, 0x0054, S5C73M3_AF_TOUCH_POSITION);
+ CHECK_ERR(err);
+
+ err = s5c73m3_i2c_write(sd, 0x0F14, state->focus.pos_x);
+ CHECK_ERR(err);
+
+ err = s5c73m3_i2c_write(sd, 0x0F14, state->focus.pos_y);
+ CHECK_ERR(err);
+
+ err = s5c73m3_i2c_write(sd, 0x0F14, state->preview->width);
+ CHECK_ERR(err);
+
+ err = s5c73m3_i2c_write(sd, 0x0F14, state->preview->height);
+ CHECK_ERR(err);
+
+ err = s5c73m3_i2c_write(sd, 0x0050, 0x0009);
+ CHECK_ERR(err);
+
+ err = s5c73m3_i2c_write(sd, 0x0054, 0x5000);
+ CHECK_ERR(err);
+
+ err = s5c73m3_i2c_write(sd, 0x0F14, S5C73M3_AF_FACE_ZOOM);
+ CHECK_ERR(err);
+
+ err = s5c73m3_i2c_write(sd, 0x0F14, val); /*0:reset, 1:Start*/
+ CHECK_ERR(err);
+
+ err = s5c73m3_i2c_write(sd, 0x0054, 0x5080);
+ CHECK_ERR(err);
+
+ err = s5c73m3_i2c_write(sd, 0x0F14, 0x0001);
+ CHECK_ERR(err);
+
+ return 0;
+}
+
+
+static int s5c73m3_set_face_detection(struct v4l2_subdev *sd, int val)
+{
+ int err;
+ cam_dbg("E, value %d\n", val);
+
+retry:
+ switch (val) {
+ case FACE_DETECTION_ON:
+ err = s5c73m3_writeb(sd, S5C73M3_FACE_DET,
+ S5C73M3_FACE_DET_ON);
+ CHECK_ERR(err);
+
+ err = s5c73m3_writeb(sd, S5C73M3_AF_MODE,
+ S5C73M3_AF_MODE_PREVIEW_CAF_START);
+ CHECK_ERR(err);
+
+ break;
+
+ case FACE_DETECTION_OFF:
+ err = s5c73m3_writeb(sd, S5C73M3_FACE_DET,
+ S5C73M3_FACE_DET_OFF);
+ CHECK_ERR(err);
+ break;
+
+ default:
+ cam_warn("invalid value, %d\n", val);
+ val = FACE_DETECTION_OFF;
+ goto retry;
+ }
+
+ cam_trace("X\n");
+ return 0;
+
+}
+
+static int s5c73m3_set_hybrid_capture(struct v4l2_subdev *sd)
+{
+ int err;
+ cam_trace("E\n");
+
+ err = s5c73m3_writeb(sd, S5C73M3_HYBRID_CAPTURE, 1);
+
+ CHECK_ERR(err);
+
+ cam_trace("X\n");
+ return 0;
+}
+
+static int s5c73m3_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+{
+ struct s5c73m3_state *state = to_state(sd);
+ int err = 0;
+
+ if (unlikely(state->isp.bad_fw && ctrl->id != V4L2_CID_CAM_UPDATE_FW)) {
+ cam_err("\"Unknown\" state, please update F/W");
+ return -ENOSYS;
+ }
+
+ switch (ctrl->id) {
+ case V4L2_CID_CAMERA_FRAME_RATE:
+ err = s5c73m3_set_frame_rate(sd, ctrl->value);
+ break;
+
+ case V4L2_CID_CAMERA_FACE_DETECTION:
+ err = s5c73m3_set_face_detection(sd, ctrl->value);
+ break;
+
+ case V4L2_CID_CAMERA_FACE_ZOOM:
+ err = s5c73m3_set_face_zoom(sd, ctrl->value);
+ break;
+
+ case V4L2_CID_CAM_UPDATE_FW:
+ if (ctrl->value == FW_MODE_DUMP)
+ err = s5c73m3_dump_fw(sd);
+ else if (ctrl->value == FW_MODE_UPDATE)
+ err = s5c73m3_check_fw(sd, 1);
+ else
+ err = 0;
+ break;
+
+ case V4L2_CID_CAMERA_SENSOR_MODE:
+ err = s5c73m3_set_sensor_mode(sd, ctrl->value);
+ break;
+
+ case V4L2_CID_CAMERA_FLASH_MODE:
+ err = s5c73m3_set_flash(sd, ctrl->value, 0);
+ break;
+
+ case V4L2_CID_CAMERA_ISO:
+ err = s5c73m3_set_iso(sd, ctrl);
+ break;
+
+ case V4L2_CID_CAMERA_METERING:
+ if (state->sensor_mode == SENSOR_CAMERA)
+ err = s5c73m3_set_metering(sd, ctrl->value);
+ break;
+
+ case V4L2_CID_EXPOSURE:
+ ctrl->value -= 4;
+ err = s5c73m3_set_exposure(sd, ctrl);
+ break;
+
+ case V4L2_CID_CAMERA_BRIGHTNESS:
+ err = s5c73m3_set_exposure(sd, ctrl);
+ break;
+
+ case V4L2_CID_CAMERA_CONTRAST:
+ err = s5c73m3_set_contrast(sd, ctrl);
+ break;
+
+ case V4L2_CID_WHITE_BALANCE_PRESET:
+ err = s5c73m3_set_whitebalance(sd, ctrl->value);
+ break;
+
+ case V4L2_CID_CAMERA_WHITE_BALANCE:
+ err = s5c73m3_set_whitebalance(sd, ctrl->value);
+ break;
+
+ case V4L2_CID_CAMERA_SCENE_MODE:
+ err = s5c73m3_set_scene_mode(sd, ctrl->value);
+ break;
+
+ case V4L2_CID_COLORFX:
+ err = s5c73m3_set_effect(sd, ctrl->value);
+ break;
+
+ case V4L2_CID_CAMERA_EFFECT:
+ err = s5c73m3_set_effect(sd, ctrl->value);
+ break;
+
+ case V4L2_CID_CAMERA_WDR:
+ err = s5c73m3_set_wdr(sd, ctrl->value);
+ break;
+
+ case V4L2_CID_CAMERA_ANTI_SHAKE:
+ err = s5c73m3_set_antishake(sd, ctrl->value);
+ break;
+
+ case V4L2_CID_CAMERA_BEAUTY_SHOT:
+ err = s5c73m3_set_face_beauty(sd, ctrl->value);
+ break;
+
+ case V4L2_CID_CAMERA_DEFAULT_FOCUS_POSITION:
+ /*err = s5c73m3_set_af_mode(sd, state->focus.mode);*/
+ err = 0;
+ break;
+
+ case V4L2_CID_FOCUS_AUTO_MODE:
+ err = s5c73m3_set_af_mode(sd, ctrl->value);
+ break;
+
+ case V4L2_CID_CAMERA_FOCUS_MODE:
+ err = s5c73m3_set_af_mode(sd, ctrl->value);
+ break;
+
+ case V4L2_CID_CAMERA_SET_AUTO_FOCUS:
+ err = s5c73m3_set_af(sd, ctrl->value);
+ break;
+
+ case V4L2_CID_FOCUS_AUTO_RECTANGLE_LEFT:
+ state->focus.left = ctrl->value;
+ break;
+
+ case V4L2_CID_FOCUS_AUTO_RECTANGLE_TOP:
+ state->focus.top = ctrl->value;
+ break;
+
+ case V4L2_CID_FOCUS_AUTO_RECTANGLE_WIDTH:
+ state->focus.width = ctrl->value;
+ break;
+
+ case V4L2_CID_FOCUS_AUTO_RECTANGLE_HEIGHT:
+ state->focus.height = ctrl->value;
+ break;
+
+ case V4L2_CID_CAMERA_OBJECT_POSITION_X:
+ state->focus.pos_x = ctrl->value;
+ break;
+
+ case V4L2_CID_CAMERA_OBJECT_POSITION_Y:
+ state->focus.pos_y = ctrl->value;
+ break;
+
+ case V4L2_CID_CAMERA_ZOOM:
+ err = s5c73m3_set_zoom(sd, ctrl->value);
+ break;
+
+ case V4L2_CID_CAM_JPEG_QUALITY:
+ err = s5c73m3_set_jpeg_quality(sd, ctrl);
+ break;
+
+ case V4L2_CID_CAMERA_CAPTURE:
+ err = s5c73m3_start_capture(sd, ctrl->value);
+
+ if (state->scene_mode == SCENE_MODE_FIREWORKS)
+ err = s5c73m3_capture_firework(sd);
+ break;
+
+ case V4L2_CID_CAMERA_HDR:
+ state->hdr_mode = ctrl->value;
+ err = 0;
+ break;
+
+ case V4L2_CID_CAMERA_HYBRID:
+ state->hybrid_mode = ctrl->value;
+ err = 0;
+ break;
+
+ case V4L2_CID_CAMERA_HYBRID_CAPTURE:
+ err = s5c73m3_set_hybrid_capture(sd);
+ break;
+
+ case V4L2_CID_CAMERA_VT_MODE:
+ state->vt_mode = ctrl->value;
+ break;
+
+ case V4L2_CID_CAMERA_CHECK_DATALINE:
+ state->check_dataline = ctrl->value;
+ break;
+
+ case V4L2_CID_CAMERA_CHECK_ESD:
+ err = s5c73m3_check_esd(sd);
+ break;
+
+ case V4L2_CID_CAMERA_JPEG_RESOLUTION:
+ state->jpeg_width = (u32)ctrl->value >> 16;
+ state->jpeg_height = (u32)ctrl->value & 0x0FFFF;
+ break;
+
+ case V4L2_CID_CAMERA_AEAWB_LOCK_UNLOCK:
+ err = s5c73m3_aeawb_lock_unlock(sd, ctrl->value);
+ break;
+
+ case V4L2_CID_CAMERA_CAF_START_STOP:
+ err = s5c73m3_stop_af_lens(sd, ctrl->value);
+ break;
+
+ case V4L2_CID_SATURATION:
+ err = s5c73m3_set_saturation(sd, ctrl);
+ break;
+
+ case V4L2_CID_SHARPNESS:
+ err = s5c73m3_set_sharpness(sd, ctrl);
+ break;
+
+ default:
+ if ((ctrl->id & 0xFFFF) <= 2000) {
+ cam_err("no such control id(PRIVATE_BASE) %d, value %d\n",
+ ctrl->id & 0xFFFF, ctrl->value);
+ /*err = -ENOIOCTLCMD;*/
+ } else if ((ctrl->id - V4L2_CID_BASE) <= 10000) {
+ cam_err("no such control id(BASE_CID) %d\n",
+ ctrl->id - V4L2_CID_BASE);
+ } else {
+ cam_err("no such control id(CAMERA_CLASS_BASE CID) %d\n",
+ ctrl->id - V4L2_CID_CAMERA_CLASS_BASE);
+ }
+ err = 0;
+ break;
+ }
+
+ if (err < 0 && err != -ENOIOCTLCMD)
+ cam_err("failed, id %d, value %d\n",
+ ctrl->id - V4L2_CID_PRIVATE_BASE, ctrl->value);
+ return err;
+}
+
+static int s5c73m3_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+{
+ struct s5c73m3_state *state = to_state(sd);
+ int err = 0;
+
+ switch (ctrl->id) {
+ case V4L2_CID_CAMERA_CAPTURE:
+ err = s5c73m3_get_pre_flash(sd, ctrl);
+ break;
+ case V4L2_CID_CAMERA_AUTO_FOCUS_RESULT:
+ err = s5c73m3_get_af_result(sd, ctrl);
+ break;
+
+ case V4L2_CID_CAM_JPEG_MEMSIZE:
+ ctrl->value = 0xA00000;
+ break;
+
+ 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_POSTVIEW_OFFSET:
+ ctrl->value = state->jpeg.postview_offset;
+ break;
+
+ case V4L2_CID_CAMERA_EXIF_FLASH:
+ ctrl->value = state->exif.flash;
+ break;
+
+ case V4L2_CID_CAMERA_ISO:
+ ctrl->value = state->exif.iso;
+ break;
+
+ case V4L2_CID_CAMERA_EXIF_ISO:
+ ctrl->value = state->exif.iso;
+ break;
+
+ case V4L2_CID_CAMERA_EXIF_TV:
+ ctrl->value = state->exif.tv;
+ break;
+
+ case V4L2_CID_CAMERA_EXIF_BV:
+ ctrl->value = state->exif.bv;
+ break;
+
+ case V4L2_CID_CAMERA_EXIF_EBV:
+ ctrl->value = state->exif.ebv;
+ break;
+
+ case V4L2_CID_WHITE_BALANCE_PRESET:
+ ctrl->value = state->wb_mode;
+ break;
+
+ case V4L2_CID_EXPOSURE:
+ ctrl->value = state->exif.bv;
+ break;
+
+ case V4L2_CID_COLORFX:
+ ctrl->value = state->exif.effect;
+ break;
+
+ case V4L2_CID_SATURATION:
+ ctrl->value = state->exif.saturation;
+ break;
+
+ case V4L2_CID_SHARPNESS:
+ ctrl->value = state->exif.sharpness;
+ break;
+
+ case V4L2_CID_CAMERA_METERING:
+ ctrl->value = state->exif.metering;
+ break;
+
+ case V4L2_CID_CAMERA_WDR:
+ ctrl->value = state->exif.wdr;
+ break;
+
+ case V4L2_CID_CAMERA_FLASH_MODE:
+ ctrl->value = state->flash_mode;
+ break;
+
+ case V4L2_CID_FOCUS_AUTO_RECTANGLE_LEFT:
+ ctrl->value = state->focus.left;
+ break;
+
+ case V4L2_CID_FOCUS_AUTO_RECTANGLE_TOP:
+ ctrl->value = state->focus.top;
+ break;
+
+ case V4L2_CID_FOCUS_AUTO_RECTANGLE_WIDTH:
+ ctrl->value = state->focus.width;
+ break;
+
+ case V4L2_CID_FOCUS_AUTO_RECTANGLE_HEIGHT:
+ ctrl->value = state->focus.height;
+ break;
+
+ case V4L2_CID_CAM_STABILIZE:
+ cam_err("V4L2_CID_CAM_STABILIZE is not supported\n");
+ break;
+
+ case V4L2_CID_PHYSICAL_ROTATION:
+ ctrl->value = IS_ROTATION_90;
+ break;
+
+ default:
+ if ((ctrl->id & 0xFFFF) <= 2000) {
+ cam_err("no such control id(PRIVATE_BASE) %d, value %d\n",
+ ctrl->id & 0xFFFF, ctrl->value);
+ /*err = -ENOIOCTLCMD;*/
+ } else if ((ctrl->id - V4L2_CID_BASE) <= 10000) {
+ cam_err("no such control id(BASE_CID) %d\n",
+ ctrl->id - V4L2_CID_BASE);
+ } else {
+ cam_err("no such control id(CAMERA_CLASS_BASE CID) %d\n",
+ ctrl->id - V4L2_CID_CAMERA_CLASS_BASE);
+ }
+ err = 0;
+ break;
+ }
+
+ if (err < 0 && err != -ENOIOCTLCMD)
+ cam_err("failed, id %d\n", ctrl->id - V4L2_CID_PRIVATE_BASE);
+
+ return err;
+}
+
+
+static int s5c73m3_g_ext_ctrl(struct v4l2_subdev *sd,
+ struct v4l2_ext_control *ctrl)
+{
+ struct s5c73m3_state *state = to_state(sd);
+ int err = 0;
+
+ switch (ctrl->id) {
+ case V4L2_CID_CAM_SENSOR_FW_VER:
+ strcpy(ctrl->string, state->phone_fw);
+ break;
+
+ default:
+ cam_err("no such control id %d\n",
+ ctrl->id - V4L2_CID_CAMERA_CLASS_BASE);
+ /*err = -ENOIOCTLCMD*/
+ err = 0;
+ break;
+ }
+
+ if (err < 0 && err != -ENOIOCTLCMD)
+ cam_err("failed, id %d\n",
+ ctrl->id - V4L2_CID_CAMERA_CLASS_BASE);
+
+ return err;
+}
+
+static int s5c73m3_g_ext_ctrls(struct v4l2_subdev *sd,
+ struct v4l2_ext_controls *ctrls)
+{
+ struct v4l2_ext_control *ctrl = ctrls->controls;
+ int i, err = 0;
+
+ for (i = 0; i < ctrls->count; i++, ctrl++) {
+ err = s5c73m3_g_ext_ctrl(sd, ctrl);
+ if (err) {
+ ctrls->error_idx = i;
+ break;
+ }
+ }
+ return err;
+}
+
+
+static int s5c73m3_program_fw(struct v4l2_subdev *sd,
+ u8 *buf, u32 addr, u32 unit, u32 count, u8 id)
+{
+ return 0;
+}
+
+#ifndef CONFIG_VIDEO_S5C73M3_SPI
+int s5c73m3_spi_write(const u8 *addr, const int len, const int txSize)
+{ return 0; }
+#endif
+
+static int s5c73m3_load_fw(struct v4l2_subdev *sd)
+{
+ struct device *dev = sd->v4l2_dev->dev;
+ struct s5c73m3_state *state = to_state(sd);
+ const struct firmware *fw;
+ char fw_path[20] = {0,};
+ u8 *buf = NULL;
+ int err, txSize;
+
+ struct file *fp;
+ mm_segment_t old_fs;
+ long fsize, nread;
+ int fw_requested = 1;
+
+ old_fs = get_fs();
+ set_fs(KERNEL_DS);
+
+ if ((state->sensor_fw[0] == 'G') && (state->sensor_fw[1] == 'C'))
+ fp = filp_open(S5C73M3_FW_GC_PATH, O_RDONLY, 0);
+ else if ((state->sensor_fw[0] == 'G') && (state->sensor_fw[1] == 'D'))
+ fp = filp_open(S5C73M3_FW_GD_PATH, O_RDONLY, 0);
+ else if ((state->sensor_fw[0] == 'G') && (state->sensor_fw[1] == 'E'))
+ fp = filp_open(S5C73M3_FW_GE_PATH, O_RDONLY, 0);
+ else if ((state->sensor_fw[0] == 'G') && (state->sensor_fw[1] == 'F'))
+ fp = filp_open(S5C73M3_FW_GF_PATH, O_RDONLY, 0);
+ else if ((state->sensor_fw[0] == 'Z') && (state->sensor_fw[1] == 'C'))
+ fp = filp_open(S5C73M3_FW_ZC_PATH, O_RDONLY, 0);
+ else if ((state->sensor_fw[0] == 'Z') && (state->sensor_fw[1] == 'D'))
+ fp = filp_open(S5C73M3_FW_ZD_PATH, O_RDONLY, 0);
+ else if ((state->sensor_fw[0] == 'Z') && (state->sensor_fw[1] == 'E'))
+ fp = filp_open(S5C73M3_FW_ZE_PATH, O_RDONLY, 0);
+ else if ((state->sensor_fw[0] == 'Z') && (state->sensor_fw[1] == 'F'))
+ fp = filp_open(S5C73M3_FW_ZF_PATH, O_RDONLY, 0);
+ else if ((state->sensor_fw[0] == 'Z') && (state->sensor_fw[1] == 'G'))
+ fp = filp_open(S5C73M3_FW_ZG_PATH, O_RDONLY, 0);
+ else
+ fp = filp_open(S5C73M3_FW_PATH, O_RDONLY, 0);
+
+ if (IS_ERR(fp)) {
+ cam_trace("failed to open %s, err %ld\n",
+ S5C73M3_FW_PATH, PTR_ERR(fp));
+ goto request_fw;
+ }
+
+ fw_requested = 0;
+ fsize = fp->f_path.dentry->d_inode->i_size;
+
+ buf = vmalloc(fsize);
+ if (!buf) {
+ cam_err("failed to allocate memory\n");
+ err = -ENOMEM;
+ goto out;
+ }
+
+ nread = vfs_read(fp, (char __user *)buf, fsize, &fp->f_pos);
+ if (nread != fsize) {
+ cam_err("failed to read firmware file, %ld Bytes\n", nread);
+ err = -EIO;
+ goto out;
+ }
+
+request_fw:
+ if (fw_requested) {
+ set_fs(old_fs);
+
+ if (state->sensor_fw[0] == 'O') {
+ sprintf(fw_path, "SlimISP_G%c.bin",
+ state->sensor_fw[1]);
+ } else if (state->sensor_fw[0] == 'S') {
+ sprintf(fw_path, "SlimISP_Z%c.bin",
+ state->sensor_fw[1]);
+ } else {
+ sprintf(fw_path, "SlimISP_%c%c.bin",
+ state->sensor_fw[0],
+ state->sensor_fw[1]);
+ }
+ cam_dbg("file_name = %s\n", fw_path);
+
+ err = request_firmware(&fw, fw_path, dev);
+ if (err != 0) {
+ cam_err("request_firmware falied\n");
+ err = -EINVAL;
+ goto out;
+ }
+
+ cam_dbg("start, size %d Bytes\n", fw->size);
+ buf = (u8 *)fw->data;
+ fsize = fw->size;
+ }
+
+ if (fw_requested)
+ txSize = 60*1024; /*60KB*/
+ else
+ txSize = 64; /*64 byte for non-DMA mode*/
+
+ err = s5c73m3_spi_write(buf, fsize, txSize);
+ if (err < 0) {
+ cam_err("s5c73m3_spi_write falied\n");
+ goto out;
+ }
+
+ cam_dbg("end\n");
+
+out:
+ if (!fw_requested) {
+ vfree(buf);
+
+ filp_close(fp, current->files);
+ set_fs(old_fs);
+ } else {
+ release_firmware(fw);
+ }
+
+ return err;
+}
+
+/*
+ * v4l2_subdev_video_ops
+ */
+static const struct s5c73m3_frmsizeenum *s5c73m3_get_frmsize
+ (const struct s5c73m3_frmsizeenum *frmsizes, int num_entries, int index)
+{
+ int i;
+
+ for (i = 0; i < num_entries; i++) {
+ if (frmsizes[i].index == index)
+ return &frmsizes[i];
+ }
+
+ return NULL;
+}
+
+static int s5c73m3_set_frmsize(struct v4l2_subdev *sd)
+{
+ struct s5c73m3_state *state = to_state(sd);
+ int err ;
+ cam_trace("E\n");
+
+ if (state->format_mode != V4L2_PIX_FMT_MODE_CAPTURE) {
+ err = s5c73m3_writeb(sd, S5C73M3_CHG_MODE,
+ S5C73M3_YUV_MODE | state->preview->reg_val |
+ (state->sensor_mode<<8));
+ CHECK_ERR(err);
+
+ cam_dbg("yuv frame size %dx%d\n",
+ state->preview->width, state->preview->height);
+ } else {
+ err = s5c73m3_writeb(sd, S5C73M3_CHG_MODE,
+ S5C73M3_INTERLEAVED_MODE
+ | state->capture->reg_val | state->preview->reg_val
+ |(state->sensor_mode<<8));
+ CHECK_ERR(err);
+
+ cam_dbg("interleaved yuv size %dx%d\n",
+ state->preview->width, state->preview->height);
+
+ cam_dbg("interleaved jpeg size %dx%d\n",
+ state->capture->width, state->capture->height);
+ }
+ cam_trace("X\n");
+ return 0;
+}
+
+static int s5c73m3_s_fmt(struct v4l2_subdev *sd,
+ struct v4l2_mbus_framefmt *ffmt)
+{
+ struct s5c73m3_state *state = to_state(sd);
+ const struct s5c73m3_frmsizeenum **frmsize;
+ const struct s5c73m3_frmsizeenum **capfrmsize;
+
+ u32 width = ffmt->width;
+ u32 height = ffmt->height;
+ u32 tmp_width;
+ u32 old_index, old_index_cap;
+ int i, num_entries;
+ cam_trace("E\n");
+
+ if (unlikely(state->isp.bad_fw)) {
+ cam_err("\"Unknown\" state, please update F/W");
+ return -ENOSYS;
+ }
+ if (ffmt->width < ffmt->height) {
+ tmp_width = ffmt->height;
+ height = ffmt->width;
+ width = tmp_width;
+ }
+
+ if (ffmt->colorspace == V4L2_COLORSPACE_JPEG)
+ state->format_mode = V4L2_PIX_FMT_MODE_CAPTURE;
+ else
+ state->format_mode = V4L2_PIX_FMT_MODE_PREVIEW;
+
+ s5c73m3_set_mode(sd);
+
+ /*set frame size for preview(yuv)*/
+ frmsize = &state->preview;
+ old_index = *frmsize ? (*frmsize)->index : -1;
+ *frmsize = NULL;
+
+ num_entries = ARRAY_SIZE(preview_frmsizes);
+ for (i = 0; i < num_entries; i++) {
+ if (width == preview_frmsizes[i].width &&
+ height == preview_frmsizes[i].height) {
+ *frmsize = &preview_frmsizes[i];
+ break;
+ }
+ }
+
+ if (*frmsize == NULL) {
+ cam_warn("invalid yuv frame size %dx%d\n", width, height);
+ *frmsize = s5c73m3_get_frmsize(preview_frmsizes,
+ num_entries,
+ S5C73M3_PREVIEW_960X720);
+ }
+
+ /*set frame size for capture(jpeg)*/
+ /*it's meaningful for interleaved mode*/
+ capfrmsize = &state->capture;
+ old_index_cap = *capfrmsize ? (*capfrmsize)->index : -1;
+ *capfrmsize = NULL;
+
+ width = state->jpeg_width;
+ height = state->jpeg_height;
+
+ num_entries = ARRAY_SIZE(capture_frmsizes);
+ for (i = 0; i < num_entries; i++) {
+ if (width == capture_frmsizes[i].width &&
+ height == capture_frmsizes[i].height) {
+ *capfrmsize = &capture_frmsizes[i];
+ break;
+ }
+ }
+
+ if (*capfrmsize == NULL) {
+ cam_warn("invalid jpeg frame size %dx%d\n", width, height);
+ *capfrmsize = s5c73m3_get_frmsize(capture_frmsizes, num_entries,
+ S5C73M3_CAPTURE_VGA);
+ }
+
+ cam_dbg("yuv %dx%d\n", (*frmsize)->width, (*frmsize)->height);
+ cam_dbg("jpeg %dx%d\n", (*capfrmsize)->width, (*capfrmsize)->height);
+ if (state->stream_enable) {
+ if (ffmt->colorspace == V4L2_COLORSPACE_JPEG) {
+ if ((old_index != (*frmsize)->index)
+ || (old_index_cap != (*capfrmsize)->index))
+ s5c73m3_set_frmsize(sd);
+ } else {
+ if (old_index != (*frmsize)->index)
+ s5c73m3_set_frmsize(sd);
+ }
+ } else
+ s5c73m3_set_frmsize(sd);
+
+ cam_trace("X\n");
+ return 0;
+}
+
+static int s5c73m3_g_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *a)
+{
+ struct s5c73m3_state *state = to_state(sd);
+
+ cam_info("g_parm: FPS %d\n", state->fps);
+ if (state->fps == 0) {
+ a->parm.capture.timeperframe.numerator = state->fps;
+ a->parm.capture.timeperframe.denominator = 1;
+ } else {
+ a->parm.capture.timeperframe.numerator = 1;
+ a->parm.capture.timeperframe.denominator = state->fps;
+ }
+
+ return 0;
+}
+
+static int s5c73m3_s_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *a)
+{
+ struct s5c73m3_state *state = to_state(sd);
+ u32 denom = a->parm.capture.timeperframe.denominator;
+ u32 numer = a->parm.capture.timeperframe.numerator;
+ u32 err = 0;
+ u32 fps;
+
+ if (unlikely(state->isp.bad_fw)) {
+ cam_err("\"Unknown\" state, please update F/W");
+ return -ENOSYS;
+ }
+
+ if (numer == 0) {
+ fps = 0;
+ } else {
+ fps = denom / numer;
+ if (fps != state->fps) {
+ if (fps < 0 || fps > 30) {
+ cam_err("invalid frame rate %d\n", fps);
+ fps = 30;
+ }
+ }
+ }
+
+ state->fps = fps;
+
+ cam_err("Frame rate = %d(%d)\n", fps, state->fps);
+
+ err = s5c73m3_set_frame_rate(sd, state->fps);
+ CHECK_ERR(err);
+
+ return 0;
+}
+
+static int s5c73m3_enum_framesizes(struct v4l2_subdev *sd,
+ struct v4l2_frmsizeenum *fsize)
+{
+ struct s5c73m3_state *state = to_state(sd);
+ unsigned int i;
+ int index = fsize->index;
+
+ /*
+ * Compatible with current fimc code, we have added this condition.
+ * Fimc use this subdev call for getting width and height of current
+ * state.
+ */
+ if (index != -1) {
+ if (index < ARRAY_SIZE(preview_frmsizes)) {
+ for (i = 0; i < ARRAY_SIZE(preview_frmsizes); ++i) {
+ /*
+ * If we need to check pixelformat, please add
+ * condition at this line.
+ */
+ if (index == i) {
+ fsize->type =
+ V4L2_FRMSIZE_TYPE_DISCRETE;
+ fsize->discrete.width =
+ preview_frmsizes[i].width;
+ fsize->discrete.height =
+ preview_frmsizes[i].height;
+ return 0;
+ }
+ }
+ }
+ return -EINVAL;
+ }
+
+ /*
+ * 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->preview == NULL)
+ return -EINVAL;
+
+ fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
+ if (state->hdr_mode) {
+ fsize->discrete.width = state->capture->width;
+ fsize->discrete.height = state->capture->height;
+ } else {
+ fsize->discrete.width = state->preview->width;
+ fsize->discrete.height = state->preview->height;
+ }
+ return 0;
+}
+
+static int s5c73m3_s_stream_sensor(struct v4l2_subdev *sd, int onoff)
+{
+ int err = 0;
+ int index = 0;
+ u16 stream_status = 0;
+
+ cam_info("%s::::onoff=%d\n", __func__, onoff);
+ err = s5c73m3_writeb(sd, S5C73M3_SENSOR_STREAMING,
+ onoff ? S5C73M3_SENSOR_STREAMING_ON :
+ S5C73M3_SENSOR_STREAMING_OFF);
+ CHECK_ERR(err);
+
+ do {
+ err = s5c73m3_read(sd, 0x0009, 0x5080, &stream_status);
+ if (stream_status == 0xffff)
+ break;
+
+ index++;
+ msleep(20);
+ } while (index < 30);
+
+ if (index >= 30) {
+ cam_info("%s::::TimeOut!! index = %d, status = 0x%x",
+ __func__, index, stream_status);
+ err = -1;
+ }
+
+ return err;
+}
+
+static int s5c73m3_s_stream_hdr(struct v4l2_subdev *sd, int enable)
+{
+ struct s5c73m3_state *state = to_state(sd);
+ int err = 0;
+ cam_info("s_stream_hdr\n");
+
+ if (enable) {
+ err = s5c73m3_i2c_write(sd, 0x0050, 0x0009);
+ CHECK_ERR(err);
+
+ err = s5c73m3_i2c_write(sd, 0x0054, 0x5000);
+ CHECK_ERR(err);
+
+ err = s5c73m3_i2c_write(sd, 0x0F14, 0x0902);
+ CHECK_ERR(err);
+
+ err = s5c73m3_i2c_write(sd, 0x0F14, 0x0008);
+ CHECK_ERR(err);
+
+ err = s5c73m3_i2c_write(sd, 0x0F14, 0x091A);
+ CHECK_ERR(err);
+
+ err = s5c73m3_i2c_write(sd, 0x0F14, 0x0002);
+ CHECK_ERR(err);
+
+ err = s5c73m3_i2c_write(sd, 0x0F14, 0x0B10);
+ CHECK_ERR(err);
+
+ err = s5c73m3_i2c_write(sd, 0x0F14, 0x8000 |
+ state->capture->reg_val |
+ state->preview->reg_val);
+ CHECK_ERR(err);
+
+ err = s5c73m3_i2c_write(sd, 0x0054, 0x5080);
+ CHECK_ERR(err);
+
+ err = s5c73m3_i2c_write(sd, 0x0F14, 0x0003);
+ CHECK_ERR(err);
+
+ err = s5c73m3_s_stream_sensor(sd, enable);
+ err = s5c73m3_set_auto_bracket_mode(sd);
+ } else {
+ err = s5c73m3_s_stream_sensor(sd, enable);
+ }
+
+ return 0;
+}
+
+static int s5c73m3_s_stream(struct v4l2_subdev *sd, int enable)
+{
+ struct s5c73m3_state *state = to_state(sd);
+ int err;
+
+ cam_trace("E\n");
+
+ if (unlikely(state->isp.bad_fw)) {
+ cam_err("\"Unknown\" state, please update F/W");
+ return -ENOSYS;
+ }
+
+ switch (enable) {
+ case STREAM_MODE_CAM_ON:
+ case STREAM_MODE_CAM_OFF:
+ switch (state->format_mode) {
+ case V4L2_PIX_FMT_MODE_CAPTURE:
+ cam_info("capture %s",
+ enable == STREAM_MODE_CAM_ON ? "on" : "off");
+
+ s5c73m3_s_stream_sensor(sd, enable);
+ if (enable == STREAM_MODE_CAM_ON &&
+ state->focus.mode ==
+ FOCUS_MODE_CONTINOUS_VIDEO) {
+ s5c73m3_set_af_mode(sd,
+ FOCUS_MODE_CONTINOUS_VIDEO);
+ }
+ break;
+
+ default:
+ cam_info("preview %s",
+ enable == STREAM_MODE_CAM_ON ? "on" : "off");
+
+ if (state->hdr_mode) {
+ err = s5c73m3_set_flash(sd, FLASH_MODE_OFF, 0);
+ err = s5c73m3_s_stream_hdr(sd, enable);
+ } else {
+ err = s5c73m3_s_stream_sensor(sd, enable);
+ if (enable == STREAM_MODE_CAM_ON &&
+ state->focus.mode ==
+ FOCUS_MODE_CONTINOUS_VIDEO) {
+ s5c73m3_set_af_mode(sd,
+ FOCUS_MODE_CONTINOUS_VIDEO);
+ }
+ }
+ break;
+ }
+ break;
+
+ case STREAM_MODE_MOVIE_ON:
+ if (state->flash_mode != FLASH_MODE_OFF)
+ err = s5c73m3_set_flash(sd, state->flash_mode, 1);
+
+ if (state->preview->index == S5C73M3_PREVIEW_720P ||
+ state->preview->index == S5C73M3_PREVIEW_1080P)
+ err = s5c73m3_set_af(sd, 1);
+ break;
+
+ case STREAM_MODE_MOVIE_OFF:
+ if (state->preview->index == S5C73M3_PREVIEW_720P ||
+ state->preview->index == S5C73M3_PREVIEW_1080P)
+ err = s5c73m3_set_af(sd, 0);
+
+ s5c73m3_set_flash(sd, FLASH_MODE_OFF, 1);
+ break;
+
+ default:
+ cam_err("invalid stream option, %d\n", enable);
+ break;
+ }
+
+#if 0
+ err = s5c73m3_writeb(sd, S5C73M3_AF_CAL, 0);
+ CHECK_ERR(err);
+#endif
+ state->stream_enable = enable;
+ if (state->stream_enable && state->hdr_mode == 0) {
+ if (state->fps)
+ s5c73m3_set_frame_rate(sd, state->fps);
+ }
+
+ cam_trace("X\n");
+ return 0;
+}
+
+static int s5c73m3_check_version(struct v4l2_subdev *sd)
+{
+ return 0;
+}
+
+static int s5c73m3_init_param(struct v4l2_subdev *sd)
+{
+ s5c73m3_set_flash(sd, FLASH_MODE_OFF, 0);
+ return 0;
+}
+
+static int s5c73m3_FROM_booting(struct v4l2_subdev *sd)
+{
+ u16 read_val;
+ int i, err;
+
+ cam_trace("E\n");
+
+ /*ARM go*/
+ err = s5c73m3_write(sd, 0x3000, 0x0004, 0xFFFF);
+ CHECK_ERR(err);
+
+ udelay(400);
+
+ /*Check boot done*/
+ for (i = 0; i < 4; i++) {
+ err = s5c73m3_read(sd, 0x3010, 0x0010, &read_val);
+ CHECK_ERR(err);
+
+ if (read_val == 0x0C)
+ break;
+
+ udelay(100);
+ }
+
+ if (read_val != 0x0C) {
+ cam_err("boot fail, read_val %#x\n", read_val);
+ return -1;
+ }
+
+ /*P,M,S and Boot Mode*/
+ err = s5c73m3_write(sd, 0x3100, 0x010C, 0x0044);
+ CHECK_ERR(err);
+ err = s5c73m3_write(sd, 0x3100, 0x0108, 0x000D);
+ CHECK_ERR(err);
+ err = s5c73m3_write(sd, 0x3100, 0x0304, 0x0001);
+ CHECK_ERR(err);
+ err = s5c73m3_write(sd, 0x0001, 0x0000, 0x5800);
+ CHECK_ERR(err);
+ err = s5c73m3_write(sd, 0x0001, 0x0002, 0x0002);
+ CHECK_ERR(err);
+ err = s5c73m3_write(sd, 0x3100, 0x0000, 0x0001);
+ CHECK_ERR(err);
+ err = s5c73m3_write(sd, 0x3010, 0x0014, 0x1B85);
+ CHECK_ERR(err);
+ err = s5c73m3_write(sd, 0x3010, 0x0010, 0x230C);
+ CHECK_ERR(err);
+
+ mdelay(300);
+
+ /*Check binary read done*/
+ for (i = 0; i < 3; i++) {
+ err = s5c73m3_read(sd, 0x3010, 0x0010, &read_val);
+ CHECK_ERR(err);
+
+ if (read_val == 0x230E)
+ break;
+
+ udelay(100);
+ }
+
+ if (read_val != 0x230E) {
+ cam_err("binary read fail, read_val %#x\n", read_val);
+ return -1;
+ }
+
+ /*ARM reset*/
+ err = s5c73m3_write(sd, 0x3000, 0x0004, 0xFFFD);
+ CHECK_ERR(err);
+
+ /*remap*/
+ err = s5c73m3_write(sd, 0x3010, 0x00A4, 0x0183);
+ CHECK_ERR(err);
+
+ /*ARM go again*/
+ err = s5c73m3_write(sd, 0x3000, 0x0004, 0xFFFF);
+ CHECK_ERR(err);
+
+ cam_trace("X\n");
+
+ return 0;
+}
+
+static int s5c73m3_SPI_booting(struct v4l2_subdev *sd)
+{
+ u16 read_val;
+ int i, err;
+
+ cam_trace("E\n");
+
+ /*ARM go*/
+ err = s5c73m3_write(sd, 0x3000, 0x0004, 0xFFFF);
+ CHECK_ERR(err);
+
+ udelay(400);
+
+ /*Check boot done*/
+ for (i = 0; i < 3; i++) {
+ err = s5c73m3_read(sd, 0x3010, 0x0010, &read_val);
+ CHECK_ERR(err);
+
+ if (read_val == 0x0C)
+ break;
+
+ udelay(100);
+ }
+
+ if (read_val != 0x0C) {
+ cam_err("boot fail, read_val %#x\n", read_val);
+ return -1;
+ }
+
+ /*P,M,S and Boot Mode*/
+ err = s5c73m3_write(sd, 0x3010, 0x0014, 0x2146);
+ CHECK_ERR(err);
+ err = s5c73m3_write(sd, 0x3010, 0x0010, 0x210C);
+ CHECK_ERR(err);
+
+ udelay(200);
+
+ /*Check SPI ready*/
+ for (i = 0; i < 3; i++) {
+ err = s5c73m3_read(sd, 0x3010, 0x0010, &read_val);
+ CHECK_ERR(err);
+
+ if (read_val == 0x210D)
+ break;
+
+ udelay(100);
+ }
+
+ if (read_val != 0x210D) {
+ cam_err("SPI not ready, read_val %#x\n", read_val);
+ return -1;
+ }
+
+ /*download fw by SPI*/
+ s5c73m3_load_fw(sd);
+
+ /*ARM reset*/
+ err = s5c73m3_write(sd, 0x3000, 0x0004, 0xFFFD);
+ CHECK_ERR(err);
+
+ /*remap*/
+ err = s5c73m3_write(sd, 0x3010, 0x00A4, 0x0183);
+ CHECK_ERR(err);
+
+ /*ARM go again*/
+ err = s5c73m3_write(sd, 0x3000, 0x0004, 0xFFFF);
+ CHECK_ERR(err);
+
+ cam_trace("X\n");
+
+ return 0;
+}
+
+static int s5c73m3_read_vdd_core(struct v4l2_subdev *sd)
+{
+ struct s5c73m3_state *state = to_state(sd);
+ u16 read_val;
+ int err;
+
+ cam_trace("E\n");
+
+ /*Initialize OTP Controller*/
+ err = s5c73m3_write(sd, 0x3800, 0xA004, 0x0000);
+ CHECK_ERR(err);
+ err = s5c73m3_write(sd, 0x3800, 0xA000, 0x0004);
+ CHECK_ERR(err);
+ err = s5c73m3_write(sd, 0x3800, 0xA0D8, 0x0000);
+ CHECK_ERR(err);
+ err = s5c73m3_write(sd, 0x3800, 0xA0DC, 0x0004);
+ CHECK_ERR(err);
+ err = s5c73m3_write(sd, 0x3800, 0xA0C4, 0x4000);
+ CHECK_ERR(err);
+ err = s5c73m3_write(sd, 0x3800, 0xA0D4, 0x0015);
+ CHECK_ERR(err);
+ err = s5c73m3_write(sd, 0x3800, 0xA000, 0x0001);
+ CHECK_ERR(err);
+ err = s5c73m3_write(sd, 0x3800, 0xA0B4, 0x9F90);
+ CHECK_ERR(err);
+ err = s5c73m3_write(sd, 0x3800, 0xA09C, 0x9A95);
+ CHECK_ERR(err);
+
+ /*Page Select*/
+ err = s5c73m3_write(sd, 0x3800, 0xA0C4, 0x4800);
+ CHECK_ERR(err);
+ err = s5c73m3_write(sd, 0x3800, 0xA0C4, 0x4400);
+ CHECK_ERR(err);
+ err = s5c73m3_write(sd, 0x3800, 0xA0C4, 0x4200);
+ CHECK_ERR(err);
+ err = s5c73m3_write(sd, 0x3800, 0xA004, 0x00C0);
+ CHECK_ERR(err);
+ err = s5c73m3_write(sd, 0x3800, 0xA000, 0x0001);
+ CHECK_ERR(err);
+
+#if 0 /*read_val should be 0x7383*/
+ err = s5c73m3_read(sd, 0x0000, 0x131C, &read_val);
+ CHECK_ERR(err);
+
+ cam_dbg("read_val %#x\n", read_val);
+#endif
+
+ /*Read Data*/
+ err = s5c73m3_read(sd, 0x3800, 0xA034, &read_val);
+ CHECK_ERR(err);
+
+ cam_dbg("read_val %#x\n", read_val);
+
+ /*Read Data End*/
+ err = s5c73m3_write(sd, 0x3800, 0xA000, 0x0000);
+ CHECK_ERR(err);
+
+ if (read_val & 0x200) {
+ state->pdata->set_vdd_core(1150000);
+ strcpy(sysfs_isp_core, "1.15V");
+ } else if (read_val & 0x800) {
+ state->pdata->set_vdd_core(1100000);
+ strcpy(sysfs_isp_core, "1.10V");
+ } else if (read_val & 0x2000) {
+ state->pdata->set_vdd_core(1050000);
+ strcpy(sysfs_isp_core, "1.05V");
+ } else if (read_val & 0x8000) {
+ state->pdata->set_vdd_core(1000000);
+ strcpy(sysfs_isp_core, "1.00V");
+ } else {
+ state->pdata->set_vdd_core(1150000);
+ strcpy(sysfs_isp_core, "1.15V");
+ }
+
+ cam_trace("X\n");
+
+ return 0;
+}
+
+
+static int s5c73m3_init(struct v4l2_subdev *sd, u32 val)
+{
+ struct s5c73m3_state *state = to_state(sd);
+ int err;
+
+ sd_internal = sd;
+
+ /* Default state values */
+ state->isp.bad_fw = 0;
+
+ state->preview = NULL;
+ state->capture = NULL;
+
+ state->format_mode = V4L2_PIX_FMT_MODE_PREVIEW;
+ state->sensor_mode = SENSOR_CAMERA;
+ state->flash_mode = FLASH_MODE_OFF;
+ state->beauty_mode = 0;
+ state->focus.mode = FOCUS_MODE_CONTINOUS_PICTURE;
+ state->focus.touch = 0;
+
+ state->fps = 0; /* auto */
+
+ memset(&state->focus, 0, sizeof(state->focus));
+
+ if (!state->pdata->is_vdd_core_set())
+ s5c73m3_read_vdd_core(sd);
+
+#ifdef S5C73M3_FROM_BOOTING
+ err = s5c73m3_FROM_booting(sd);
+#else
+ err = s5c73m3_check_fw(sd, 0);
+ if (err < 0) {
+ cam_dbg("isp.bad_fw is true\n");
+ state->isp.bad_fw = 1;
+ }
+#endif
+ CHECK_ERR(err);
+
+ s5c73m3_init_param(sd);
+
+ return 0;
+}
+
+static const struct v4l2_subdev_core_ops s5c73m3_core_ops = {
+ .init = s5c73m3_init, /* initializing API */
+ .load_fw = s5c73m3_load_fw,
+ .queryctrl = s5c73m3_queryctrl,
+ .g_ctrl = s5c73m3_g_ctrl,
+ .s_ctrl = s5c73m3_s_ctrl,
+ .g_ext_ctrls = s5c73m3_g_ext_ctrls,
+};
+
+static const struct v4l2_subdev_video_ops s5c73m3_video_ops = {
+ .s_mbus_fmt = s5c73m3_s_fmt,
+ .g_parm = s5c73m3_g_parm,
+ .s_parm = s5c73m3_s_parm,
+ .enum_framesizes = s5c73m3_enum_framesizes,
+ .s_stream = s5c73m3_s_stream,
+};
+
+static const struct v4l2_subdev_ops s5c73m3_ops = {
+ .core = &s5c73m3_core_ops,
+ .video = &s5c73m3_video_ops,
+};
+
+static ssize_t s5c73m3_camera_rear_camtype_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ char type[25];
+
+ strcpy(type, sysfs_sensor_type);
+ return sprintf(buf, "%s\n", type);
+}
+
+static ssize_t s5c73m3_camera_rear_camfw_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ return sprintf(buf, "%s %s\n", sysfs_sensor_fw, sysfs_phone_fw);
+}
+
+static ssize_t s5c73m3_camera_rear_flash(struct device *dev,
+ struct device_attribute *attr, const char *buf,
+ size_t count)
+{
+ int err;
+
+ if (buf[0] == '0')
+ err = s5c73m3_writeb(sd_internal, S5C73M3_FLASH_TORCH,
+ S5C73M3_FLASH_TORCH_OFF);
+ else
+ err = s5c73m3_writeb(sd_internal, S5C73M3_FLASH_TORCH,
+ S5C73M3_FLASH_TORCH_ON);
+
+ CHECK_ERR(err);
+
+ return count;
+}
+
+static ssize_t s5c73m3_camera_isp_core_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ char core[10];
+
+ strcpy(core, sysfs_isp_core);
+ return sprintf(buf, "%s\n", core);
+}
+
+static DEVICE_ATTR(rear_camtype, S_IRUGO,
+ s5c73m3_camera_rear_camtype_show, NULL);
+static DEVICE_ATTR(rear_camfw, S_IRUGO, s5c73m3_camera_rear_camfw_show, NULL);
+static DEVICE_ATTR(rear_flash, S_IWUSR | S_IWGRP, NULL,
+ s5c73m3_camera_rear_flash);
+static DEVICE_ATTR(isp_core, S_IRUGO, s5c73m3_camera_isp_core_show, NULL);
+
+/*
+ * s5c73m3_probe
+ * Fetching platform data is being done with s_config subdev call.
+ * In probe routine, we just register subdev device
+ */
+static int __devinit s5c73m3_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct s5c73m3_state *state;
+ struct v4l2_subdev *sd;
+
+ state = kzalloc(sizeof(struct s5c73m3_state), GFP_KERNEL);
+ if (state == NULL)
+ return -ENOMEM;
+
+ sd = &state->sd;
+ strcpy(sd->name, S5C73M3_DRIVER_NAME);
+
+ state->pdata = client->dev.platform_data;
+
+ /* Registering subdev */
+ v4l2_i2c_subdev_init(sd, client, &s5c73m3_ops);
+
+#ifdef CAM_DEBUG
+ state->dbg_level = CAM_DEBUG;
+#endif
+
+#ifdef CONFIG_BUSFREQ_OPP
+ /* lock bus frequency */
+ dev_lock(bus_dev, s5c73m3_dev, 400200);
+#else
+ pm_qos_update_request(&entry, 400200);
+#endif
+
+ if (s5c73m3_dev)
+ dev_set_drvdata(s5c73m3_dev, state);
+
+ printk(KERN_DEBUG "%s\n", __func__);
+
+ return 0;
+}
+
+static int __devexit s5c73m3_remove(struct i2c_client *client)
+{
+ struct v4l2_subdev *sd = i2c_get_clientdata(client);
+ struct s5c73m3_state *state = to_state(sd);
+
+ if (unlikely(state->isp.bad_fw)) {
+ cam_err("camera is not ready!!\n");
+ } else {
+ if (s5c73m3_set_af_softlanding(sd) < 0)
+ cam_err("failed to set soft landing\n");
+ }
+ v4l2_device_unregister_subdev(sd);
+
+#ifdef CONFIG_BUSFREQ_OPP
+ /* Unlock bus frequency */
+ dev_unlock(bus_dev, s5c73m3_dev);
+#else
+ pm_qos_update_request(&entry, 0);
+#endif
+
+ kfree(state->fw_version);
+ kfree(state);
+
+ return 0;
+}
+
+static const struct i2c_device_id s5c73m3_id[] = {
+ { S5C73M3_DRIVER_NAME, 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, s5c73m3_id);
+
+static struct i2c_driver s5c73m3_i2c_driver = {
+ .driver = {
+ .name = S5C73M3_DRIVER_NAME,
+ },
+ .probe = s5c73m3_probe,
+ .remove = __devexit_p(s5c73m3_remove),
+ .id_table = s5c73m3_id,
+};
+
+static int __init s5c73m3_mod_init(void)
+{
+#ifdef CONFIG_BUSFREQ_OPP
+ /* To lock bus frequency in OPP mode */
+ bus_dev = dev_get("exynos-busfreq");
+#else
+ pm_qos_add_request(&entry, PM_QOS_BUS_DMA_THROUGHPUT, 0);
+#endif
+
+ if (!s5c73m3_dev) {
+ s5c73m3_dev = device_create(camera_class,
+ NULL, 0, NULL, "rear");
+ if (IS_ERR(s5c73m3_dev)) {
+ cam_warn("failed to create device!\n");
+ return 0;
+ }
+
+ if (device_create_file(s5c73m3_dev, &dev_attr_rear_camtype)
+ < 0) {
+ cam_warn("failed to create device file, %s\n",
+ dev_attr_rear_camtype.attr.name);
+ }
+
+ if (device_create_file(s5c73m3_dev, &dev_attr_rear_camfw) < 0) {
+ cam_warn("failed to create device file, %s\n",
+ dev_attr_rear_camfw.attr.name);
+ }
+
+ if (device_create_file(s5c73m3_dev, &dev_attr_rear_flash) < 0) {
+ cam_warn("failed to create device file, %s\n",
+ dev_attr_rear_flash.attr.name);
+ }
+
+ if (device_create_file(s5c73m3_dev, &dev_attr_isp_core) < 0) {
+ cam_warn("failed to create device file, %s\n",
+ dev_attr_isp_core.attr.name);
+ }
+ }
+
+ return i2c_add_driver(&s5c73m3_i2c_driver);
+}
+
+static void __exit s5c73m3_mod_exit(void)
+{
+ i2c_del_driver(&s5c73m3_i2c_driver);
+}
+module_init(s5c73m3_mod_init);
+module_exit(s5c73m3_mod_exit);
+
+
+MODULE_DESCRIPTION("driver for LSI S5C73M3");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/slp_s5c73m3.h b/drivers/media/video/slp_s5c73m3.h
new file mode 100644
index 0000000..314c65f
--- /dev/null
+++ b/drivers/media/video/slp_s5c73m3.h
@@ -0,0 +1,516 @@
+/*
+ * Driver for LSI S5C73M3 (ISP for 8MP Camera)
+ *
+ * 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.
+ */
+
+#ifndef __SLP_S5C73M3_H
+#define __SLP_S5C73M3_H
+
+#define CONFIG_CAM_DEBUG 1
+
+#define cam_warn(fmt, ...) \
+ do { \
+ printk(KERN_WARNING "%s: " fmt, __func__, ##__VA_ARGS__); \
+ } while (0)
+
+#define cam_err(fmt, ...) \
+ do { \
+ printk(KERN_ERR "%s: " fmt, __func__, ##__VA_ARGS__); \
+ } while (0)
+
+#define cam_info(fmt, ...) \
+ do { \
+ printk(KERN_INFO "%s: " fmt, __func__, ##__VA_ARGS__); \
+ } while (0)
+
+#ifdef CONFIG_CAM_DEBUG
+#define CAM_DEBUG (1 << 0)
+#define CAM_TRACE (1 << 1)
+#define CAM_I2C (1 << 2)
+
+#define cam_dbg(fmt, ...) \
+ do { \
+ if (to_state(sd)->dbg_level & CAM_DEBUG) \
+ printk(KERN_DEBUG "%s: " fmt, \
+ __func__, ##__VA_ARGS__); \
+ } while (0)
+
+#define cam_trace(fmt, ...) \
+ do { \
+ if (to_state(sd)->dbg_level & CAM_TRACE) \
+ printk(KERN_DEBUG "%s: " fmt, \
+ __func__, ##__VA_ARGS__); \
+ } while (0)
+
+#define cam_i2c_dbg(fmt, ...) \
+ do { \
+ if (to_state(sd)->dbg_level & CAM_I2C) \
+ printk(KERN_DEBUG "%s: " fmt, \
+ __func__, ##__VA_ARGS__); \
+ } while (0)
+#else
+#define cam_dbg(fmt, ...)
+#define cam_trace(fmt, ...)
+#define cam_i2c_dbg(fmt, ...)
+#endif
+
+enum s5c73m3_prev_frmsize {
+ S5C73M3_PREVIEW_QCIF,
+ S5C73M3_PREVIEW_QCIF2,
+ S5C73M3_PREVIEW_QVGA,
+ S5C73M3_PREVIEW_CIF,
+ S5C73M3_PREVIEW_VGA,
+ S5C73M3_PREVIEW_D1,
+ S5C73M3_PREVIEW_WVGA,
+ S5C73M3_PREVIEW_880X720,
+ S5C73M3_PREVIEW_960X720,
+ S5C73M3_PREVIEW_1008X672,
+ S5C73M3_PREVIEW_1056X704,
+ S5C73M3_PREVIEW_1184X666,
+ S5C73M3_PREVIEW_720P,
+ S5C73M3_VDIS_720P,
+ S5C73M3_PREVIEW_1080P,
+ S5C73M3_VDIS_1080P,
+ S5C73M3_PREVIEW_HDR,
+};
+
+enum s5c73m3_cap_frmsize {
+ S5C73M3_CAPTURE_VGA, /* 640 x 480 */
+ S5C73M3_CAPTURE_WVGA, /* 800 x 480 */
+ S5C73M3_CAPTURE_1024X768, /* 1024 x 768 */
+ S5C73M3_CAPTURE_HD, /* 1280 x 720 */
+ S5C73M3_CAPTURE_W1MP, /* 1600 x 960 */
+ S5C73M3_CAPTURE_2MP, /* UXGA - 1600 x 1200 */
+ S5C73M3_CAPTURE_W2MP, /* 2048 x 1232 */
+ S5C73M3_CAPTURE_3MP, /* QXGA - 2048 x 1536 */
+ S5C73M3_CAPTURE_W4MP, /* WQXGA - 2560 x 1440 */
+ S5C73M3_CAPTURE_5MP, /* 2560 x 1920 */
+ S5C73M3_CAPTURE_W6MP, /* 3072 x 1856 */
+ S5C73M3_CAPTURE_7MP, /* 3072 x 2304 */
+ S5C73M3_CAPTURE_W7MP, /* WQXGA - 2560 x 1536 */
+ S5C73M3_CAPTURE_3264X2176, /* 3264 x 2176 */
+ S5C73M3_CAPTURE_8MP, /* 3264 x 2448 */
+};
+
+enum s5c73m3_isneed_flash_tristate {
+ S5C73M3_ISNEED_FLASH_OFF = 0x00,
+ S5C73M3_ISNEED_FLASH_ON = 0x01,
+ S5C73M3_ISNEED_FLASH_UNDEFINED = 0x02,
+};
+
+struct s5c73m3_control {
+ u32 id;
+ s32 value;
+ s32 minimum; /* Note signedness */
+ s32 maximum;
+ s32 step;
+ s32 default_value;
+};
+
+struct s5c73m3_frmsizeenum {
+ unsigned int index;
+ unsigned int width;
+ unsigned int height;
+ u8 reg_val; /* a value for category parameter */
+};
+
+struct s5c73m3_isp {
+ wait_queue_head_t wait;
+ unsigned int irq; /* irq issued by ISP */
+ unsigned int issued;
+ unsigned int int_factor;
+ unsigned int bad_fw:1;
+};
+
+struct s5c73m3_jpeg {
+ int quality;
+ unsigned int main_size; /* Main JPEG file size */
+ unsigned int thumb_size; /* Thumbnail file size */
+ unsigned int main_offset;
+ unsigned int thumb_offset;
+ unsigned int postview_offset;
+};
+
+struct s5c73m3_focus {
+ unsigned int mode;
+ unsigned int lock;
+ unsigned int status;
+ unsigned int touch;
+ unsigned int pos_x;
+ unsigned int pos_y;
+
+ /* rectangle type values */
+ unsigned int left;
+ unsigned int top;
+ unsigned int width;
+ unsigned int height;
+};
+
+struct s5c73m3_exif {
+ char unique_id[7];
+ u32 exptime; /* us */
+ u16 flash;
+ u16 iso;
+ int tv; /* shutter speed */
+ int bv; /* brightness */
+ int ebv; /* exposure bias */
+ int effect; /* effect(colorfx) */
+ int saturation;
+ int sharpness;
+ int metering;
+ int wdr;
+};
+
+struct s5c73m3_state {
+ struct s5c73m3_platform_data *pdata;
+ struct v4l2_subdev sd;
+
+ struct s5c73m3_isp isp;
+
+ const struct s5c73m3_frmsizeenum *preview;
+ const struct s5c73m3_frmsizeenum *capture;
+
+ enum v4l2_pix_format_mode format_mode;
+ enum v4l2_sensor_mode sensor_mode;
+ enum v4l2_flash_mode flash_mode;
+ enum v4l2_wb_mode wb_mode;
+ enum v4l2_scene_mode scene_mode;
+ int vt_mode;
+ int beauty_mode;
+ int hdr_mode;
+ int hybrid_mode;
+ int zoom;
+ int stream_enable;
+ int ae_lock;
+ int awb_lock;
+
+ int cal_device;
+ int cal_dll;
+
+ unsigned int fps;
+ struct s5c73m3_focus focus;
+ int caf_mode;
+ char isflash;
+
+ struct s5c73m3_jpeg jpeg;
+ struct s5c73m3_exif exif;
+
+ int check_dataline;
+ char *fw_version;
+
+ u32 jpeg_width;
+ u32 jpeg_height;
+
+ u8 sensor_fw[10];
+ u8 phone_fw[10];
+
+ u8 sensor_type[15];
+
+#ifdef CONFIG_CAM_DEBUG
+ u8 dbg_level;
+#endif
+};
+
+#define S5C73M3_IMG_OUTPUT 0x0902
+#define S5C73M3_HDR_OUTPUT 0x0008
+#define S5C73M3_YUV_OUTPUT 0x0009
+#define S5C73M3_INTERLEAVED_OUTPUT 0x000D
+#define S5C73M3_HYBRID_OUTPUT 0x0016
+
+#define S5C73M3_STILL_PRE_FLASH 0x0A00
+#define S5C73M3_STILL_PRE_FLASH_FIRE 0x0000
+#define S5C73M3_STILL_PRE_FLASH_NON_FIRED 0x0000
+#define S5C73M3_STILL_PRE_FLASH_FIRED 0x0001
+
+#define S5C73M3_STILL_MAIN_FLASH 0x0A02
+#define S5C73M3_STILL_MAIN_FLASH_CANCEL 0x0001
+#define S5C73M3_STILL_MAIN_FLASH_FIRE 0x0002
+
+
+#define S5C73M3_ZOOM_STEP 0x0B00
+
+
+#define S5C73M3_IMAGE_EFFECT 0x0B0A
+#define S5C73M3_IMAGE_EFFECT_NONE 0x0001
+#define S5C73M3_IMAGE_EFFECT_NEGATIVE 0x0002
+#define S5C73M3_IMAGE_EFFECT_AQUA 0x0003
+#define S5C73M3_IMAGE_EFFECT_SEPIA 0x0004
+#define S5C73M3_IMAGE_EFFECT_MONO 0x0005
+
+#define S5C73M3_IMAGE_QUALITY 0x0B0C
+#define S5C73M3_IMAGE_QUALITY_SUPERFINE 0x0000
+#define S5C73M3_IMAGE_QUALITY_FINE 0x0001
+#define S5C73M3_IMAGE_QUALITY_NORMAL 0x0002
+
+
+#define S5C73M3_FLASH_MODE 0x0B0E
+#define S5C73M3_FLASH_MODE_OFF 0x0000
+#define S5C73M3_FLASH_MODE_ON 0x0001
+#define S5C73M3_FLASH_MODE_AUTO 0x0002
+
+#define S5C73M3_FLASH_TORCH 0x0B12
+#define S5C73M3_FLASH_TORCH_OFF 0x0000
+#define S5C73M3_FLASH_TORCH_ON 0x0001
+
+#define S5C73M3_AE_ISNEEDFLASH 0x0CBA
+#define S5C73M3_AE_ISNEEDFLASH_OFF 0x0000
+#define S5C73M3_AE_ISNEEDFLASH_ON 0x0001
+
+
+#define S5C73M3_CHG_MODE 0x0B10
+#define S5C73M3_YUV_MODE 0x8000
+#define S5C73M3_INTERLEAVED_MODE 0x8000
+#define S5C73M3_CHG_MODE_YUV_320_240 0x8001
+#define S5C73M3_CHG_MODE_YUV_400_300 0x8002
+#define S5C73M3_CHG_MODE_YUV_640_480 0x8003
+#define S5C73M3_CHG_MODE_YUV_800_600 0x8004
+#define S5C73M3_CHG_MODE_YUV_960_720 0x8005
+#define S5C73M3_CHG_MODE_YUV_1280_720 0x8006
+#define S5C73M3_CHG_MODE_YUV_1280_960 0x8007
+#define S5C73M3_CHG_MODE_YUV_1600_1200 0x8008
+#define S5C73M3_CHG_MODE_YUV_1632_1224 0x8009
+#define S5C73M3_CHG_MODE_YUV_1920_1080 0x800A
+#define S5C73M3_CHG_MODE_YUV_1920_1440 0x800B
+#define S5C73M3_CHG_MODE_YUV_2304_1296 0x800C
+#define S5C73M3_CHG_MODE_YUV_2304_1728 0x800D
+#define S5C73M3_CHG_MODE_JPEG_640_480 0x0010
+#define S5C73M3_CHG_MODE_JPEG_800_450 0x0020
+#define S5C73M3_CHG_MODE_JPEG_800_600 0x0030
+#define S5C73M3_CHG_MODE_JPEG_1600_960 0x0040
+#define S5C73M3_CHG_MODE_JPEG_1600_1200 0x0050
+#define S5C73M3_CHG_MODE_JPEG_2048_1152 0x0060
+#define S5C73M3_CHG_MODE_JPEG_2048_1536 0x0070
+#define S5C73M3_CHG_MODE_JPEG_2560_1440 0x0080
+#define S5C73M3_CHG_MODE_JPEG_2560_1920 0x0090
+#define S5C73M3_CHG_MODE_JPEG_3072_1728 0x00A0
+#define S5C73M3_CHG_MODE_JPEG_3264_2304 0x00B0
+#define S5C73M3_CHG_MODE_JPEG_3264_1836 0x00C0
+#define S5C73M3_CHG_MODE_JPEG_3264_2448 0x00D0
+
+
+#define S5C73M3_AF_CON 0x0E00
+#define S5C73M3_AF_CON_STOP 0x0000
+#define S5C73M3_AF_CON_SCAN 0x0001/*AF_SCAN:Full Search*/
+#define S5C73M3_AF_CON_START 0x0002/*AF_START:Fast Search*/
+
+#define S5C73M3_AF_STATUS 0x5E80
+
+#define S5C73M3_AF_TOUCH_AF 0x0E0A
+
+#define S5C73M3_AF_CAL 0x0E06
+
+#define S5C73M3_CAF_STATUS_FIND_SEARCHING_DIR 0x0001
+#define S5C73M3_CAF_STATUS_FOCUSING 0x0002
+#define S5C73M3_CAF_STATUS_FOCUSED 0x0003
+#define S5C73M3_CAF_STATUS_UNFOCUSED 0x0004
+
+#define S5C73M3_AF_STATUS_INVALID 0x0010
+#define S5C73M3_AF_STATUS_FOCUSING 0x0020
+#define S5C73M3_AF_STATUS_FOCUSED 0x0030/*SUCCESS*/
+#define S5C73M3_AF_STATUS_UNFOCUSED 0x0040/*FAIL*/
+
+#define S5C73M3_AF_TOUCH_POSITION 0x5E8E
+
+#define S5C73M3_AF_FACE_ZOOM 0x0E10
+
+#define S5C73M3_AF_MODE 0x0E02
+#define S5C73M3_AF_MODE_NORMAL 0x0000
+#define S5C73M3_AF_MODE_MACRO 0x0001
+#define S5C73M3_AF_MODE_MOVIE_CAF_START 0x0002
+#define S5C73M3_AF_MODE_MOVIE_CAF_STOP 0x0003
+#define S5C73M3_AF_MODE_PREVIEW_CAF_START 0x0004
+#define S5C73M3_AF_MODE_PREVIEW_CAF_STOP 0x0005
+
+#define S5C73M3_AF_SOFTLANDING 0x0E16
+#define S5C73M3_AF_SOFTLANDING_ON 0x0000
+
+#define S5C73M3_FACE_DET 0x0E0C
+#define S5C73M3_FACE_DET_OFF 0x0000
+#define S5C73M3_FACE_DET_ON 0x0001
+
+#define S5C73M3_FACE_DET_OSD 0x0E0E
+#define S5C73M3_FACE_DET_OSD_OFF 0x0000
+#define S5C73M3_FACE_DET_OSD_ON 0x0001
+
+#define S5C73M3_AE_CON 0x0C00
+#define S5C73M3_AE_STOP 0x0000/*LOCK*/
+#define S5C73M3_AE_START 0x0001/*UNLOCK*/
+
+#define S5C73M3_ISO 0x0C02
+#define S5C73M3_ISO_AUTO 0x0000
+#define S5C73M3_ISO_100 0x0001
+#define S5C73M3_ISO_200 0x0002
+#define S5C73M3_ISO_400 0x0003
+#define S5C73M3_ISO_800 0x0004
+#define S5C73M3_ISO_SPORTS 0x0005
+#define S5C73M3_ISO_NIGHT 0x0006
+#define S5C73M3_ISO_INDOOR 0x0007
+
+#define S5C73M3_EV 0x0C04
+#define S5C73M3_EV_M20 0x0000
+#define S5C73M3_EV_M15 0x0001
+#define S5C73M3_EV_M10 0x0002
+#define S5C73M3_EV_M05 0x0003
+#define S5C73M3_EV_ZERO 0x0004
+#define S5C73M3_EV_P05 0x0005
+#define S5C73M3_EV_P10 0x0006
+#define S5C73M3_EV_P15 0x0007
+#define S5C73M3_EV_P20 0x0008
+
+#define S5C73M3_METER 0x0C06
+#define S5C73M3_METER_CENTER 0x0000
+#define S5C73M3_METER_SPOT 0x0001
+#define S5C73M3_METER_AVERAGE 0x0002
+#define S5C73M3_METER_SMART 0x0003
+
+#define S5C73M3_WDR 0x0C08
+#define S5C73M3_WDR_OFF 0x0000
+#define S5C73M3_WDR_ON 0x0001
+
+#define S5C73M3_AE_MODE 0x0C1E
+#define S5C73M3_AUTO_MODE_AE_SET 0x0000
+#define S5C73M3_FIXED_30FPS 0x0002
+#define S5C73M3_FIXED_20FPS 0x0003
+#define S5C73M3_FIXED_15FPS 0x0004
+#define S5C73M3_FIXED_120FPS 0x0008
+#define S5C73M3_FIXED_7FPS 0x0009
+#define S5C73M3_ANTI_SHAKE 0x0013
+
+#define S5C73M3_SHARPNESS 0x0C14
+#define S5C73M3_SHARPNESS_0 0x0000
+#define S5C73M3_SHARPNESS_1 0x0001
+#define S5C73M3_SHARPNESS_2 0x0002
+#define S5C73M3_SHARPNESS_M1 0x0003
+#define S5C73M3_SHARPNESS_M2 0x0004
+
+#define S5C73M3_SATURATION 0x0C16
+#define S5C73M3_SATURATION_0 0x0000
+#define S5C73M3_SATURATION_1 0x0001
+#define S5C73M3_SATURATION_2 0x0002
+#define S5C73M3_SATURATION_M1 0x0003
+#define S5C73M3_SATURATION_M2 0x0004
+
+#define S5C73M3_CONTRAST 0x0C18
+#define S5C73M3_CONTRAST_0 0x0000
+#define S5C73M3_CONTRAST_1 0x0001
+#define S5C73M3_CONTRAST_2 0x0002
+#define S5C73M3_CONTRAST_M1 0x0003
+#define S5C73M3_CONTRAST_M2 0x0004
+
+#define S5C73M3_SCENE_MODE 0x0C1A
+#define S5C73M3_SCENE_MODE_NONE 0x0000
+#define S5C73M3_SCENE_MODE_PORTRAIT 0x0001
+#define S5C73M3_SCENE_MODE_LANDSCAPE 0x0002
+#define S5C73M3_SCENE_MODE_SPORTS 0x0003
+#define S5C73M3_SCENE_MODE_INDOOR 0x0004
+#define S5C73M3_SCENE_MODE_BEACH 0x0005
+#define S5C73M3_SCENE_MODE_SUNSET 0x0006
+#define S5C73M3_SCENE_MODE_DAWN 0x0007
+#define S5C73M3_SCENE_MODE_FALL 0x0008
+#define S5C73M3_SCENE_MODE_NIGHT 0x0009
+#define S5C73M3_SCENE_MODE_AGAINSTLIGHT 0x000A
+#define S5C73M3_SCENE_MODE_FIRE 0x000B
+#define S5C73M3_SCENE_MODE_TEXT 0x000C
+#define S5C73M3_SCENE_MODE_CANDLE 0x000D
+
+#define S5C73M3_FIREWORK_CAPTURE 0x0C20
+
+#define S5C73M3_AE_AUTO_BRAKET 0x0B14
+#define S5C73M3_AE_AUTO_BRAKET_EV05 0x0080
+#define S5C73M3_AE_AUTO_BRAKET_EV10 0x0100
+#define S5C73M3_AE_AUTO_BRAKET_EV15 0x0180
+#define S5C73M3_AE_AUTO_BRAKET_EV20 0x0200
+
+#define S5C73M3_SENSOR_STREAMING 0x090A
+#define S5C73M3_SENSOR_STREAMING_OFF 0x0000
+#define S5C73M3_SENSOR_STREAMING_ON 0x0001
+
+#define S5C73M3_AWB_MODE 0x0D02
+#define S5C73M3_AWB_MODE_INCANDESCENT 0x0000
+#define S5C73M3_AWB_MODE_FLUORESCENT1 0x0001
+#define S5C73M3_AWB_MODE_FLUORESCENT2 0x0002
+#define S5C73M3_AWB_MODE_DAYLIGHT 0x0003
+#define S5C73M3_AWB_MODE_CLOUDY 0x0004
+#define S5C73M3_AWB_MODE_AUTO 0x0005
+
+#define S5C73M3_AWB_CON 0x0D00
+#define S5C73M3_AWB_STOP 0x0000/*LOCK*/
+#define S5C73M3_AWB_START 0x0001/*UNLOCK*/
+
+#define S5C73M3_HYBRID_CAPTURE 0x0996
+
+/* S5C73M3 Sensor Mode */
+#define S5C73M3_SYSINIT_MODE 0x0
+#define S5C73M3_PARMSET_MODE 0x1
+#define S5C73M3_MONITOR_MODE 0x2
+#define S5C73M3_STILLCAP_MODE 0x3
+
+/* Interrupt Factor */
+#define S5C73M3_INT_SOUND (1 << 7)
+#define S5C73M3_INT_LENS_INIT (1 << 6)
+#define S5C73M3_INT_FD (1 << 5)
+#define S5C73M3_INT_FRAME_SYNC (1 << 4)
+#define S5C73M3_INT_CAPTURE (1 << 3)
+#define S5C73M3_INT_ZOOM (1 << 2)
+#define S5C73M3_INT_AF (1 << 1)
+#define S5C73M3_INT_MODE (1 << 0)
+
+/* ESD Interrupt */
+#define S5C73M3_INT_ESD (1 << 0)
+
+static const u32 S5C73M3_INIT[] = {
+0x00500009,
+0x00545000,
+0x0F140B08,
+0x0F140000,
+0x0F140900,
+0x0F140403, /*640MHz*/
+0x00545080,
+0x0F140002
+};
+
+static u32 S5C73M3_OTP_CONTROL[] = {
+0xFCFC3310,
+0x00503800,
+0x0054A004,
+0x0F140000,
+0x0054A000,
+0x0F140004,
+0x0054A0D8,
+0x0F140000,
+0x0054A0DC,
+0x0F140004,
+0x0054A0C4,
+0x0F144000,
+0x0054A0D4,
+0x0F140015,
+0x0054A000,
+0x0F140001,
+0x0054A0B4,
+0x0F149F90,
+0x0054A09C,
+0x0F149A95,
+};
+
+static u32 S5C73M3_OTP_PAGE[] = {
+0x0054A0C4,
+0x0F144800,
+0x0054A0C4,
+0x0F144400,
+0x0054A0C4,
+0x0F144200,
+0x0054A004,
+0x0F1400C0,
+0x0054A000,
+0x0F140001,
+};
+
+#ifdef CONFIG_VIDEO_S5C73M3_SPI
+extern int s5c73m3_spi_write(const u8 *addr, const int len, const int txSize);
+#endif
+
+#endif /* __SLP_S5C73M3_H */
diff --git a/drivers/media/video/slp_s5k4ecgx.c b/drivers/media/video/slp_s5k4ecgx.c
new file mode 100644
index 0000000..c78ca71
--- /dev/null
+++ b/drivers/media/video/slp_s5k4ecgx.c
@@ -0,0 +1,2335 @@
+/*
+ * Driver for S5K4ECGX from Samsung Electronics
+ *
+ * 5Mp CMOS Image Sensor SoC with an Embedded Image Processor
+ *
+ * Copyright (c) 2012 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.
+ */
+
+#include <linux/i2c.h>
+#include <linux/init.h>
+#include <media/v4l2-device.h>
+#include <linux/delay.h>
+#include <linux/version.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-subdev.h>
+#include <linux/workqueue.h>
+#ifdef CONFIG_VIDEO_SAMSUNG_V4L2
+#include <linux/videodev2_exynos_media.h>
+#include <linux/videodev2_exynos_camera.h>
+#endif
+#include <media/s5k4ecgx_platform.h>
+
+#include "slp_s5k4ecgx.h"
+
+#ifdef S5K4ECGX_USLEEP
+#include <linux/hrtimer.h>
+#endif
+
+#define S5K4ECGX_BURST_MODE
+#ifdef S5K4ECGX_BURST_MODE
+ static u16 addr, value;
+
+ static int len;
+ static u8 buf[SZ_4K] = {0,};
+#else
+ static u8 buf[4] = {0,};
+#endif
+
+/* 5M mem size */
+#define S5K4ECGX_INTLV_DATA_MAXSIZE (5 << 20)
+
+static const struct s5k4ecgx_framesize preview_frmsizes[] = {
+ { S5K4ECGX_PREVIEW_640, 640, 480 },
+ { S5K4ECGX_PREVIEW_176, 640, 480 },
+ { S5K4ECGX_PREVIEW_320, 320, 240 },
+ { S5K4ECGX_PREVIEW_720, 720, 480 },
+ { S5K4ECGX_PREVIEW_800, 800, 480 },
+ { S5K4ECGX_PREVIEW_1280, 1280, 720 },
+};
+
+static const struct s5k4ecgx_framesize capture_frmsizes[] = {
+ { S5K4ECGX_CAPTURE_5MP, 2560, 1920 },
+ { S5K4ECGX_CAPTURE_3MP, 2048, 1536 },
+ { S5K4ECGX_CAPTURE_2MP, 1600, 1200 },
+ { S5K4ECGX_CAPTURE_1MP, 1280, 960 },
+ { S5K4ECGX_CAPTURE_XGA, 1024, 768 },
+ { S5K4ECGX_CAPTURE_VGA, 640, 480 },
+};
+
+#define CHECK_ERR(x) if (unlikely((x) < 0)) { \
+ cam_err("i2c failed, err %d\n", x); \
+ return x; \
+ }
+
+#define NELEMS(array) (sizeof(array) / sizeof(array[0]))
+
+#ifdef S5K4ECGX_USLEEP
+/*
+ * Use msleep() if the sleep time is over 1000 us.
+*/
+static void s5k4ecgx_usleep(u32 usecs)
+{
+ ktime_t expires;
+ u64 add_time = (u64)usecs * 1000;
+
+ if (unlikely(!usecs))
+ return;
+
+ expires = ktime_add_ns(ktime_get(), add_time);
+ set_current_state(TASK_UNINTERRUPTIBLE);
+ schedule_hrtimeout(&expires, HRTIMER_MODE_ABS);
+}
+#endif
+
+static void s5k4ecgx_cam_delay(struct v4l2_subdev *sd)
+{
+ struct s5k4ecgx_state *state = to_state(sd);
+
+ if (state->scene_mode == SCENE_MODE_NIGHTSHOT ||
+ state->scene_mode == SCENE_MODE_FIREWORKS)
+ msleep(250);
+ else
+ msleep(200);
+}
+
+static inline int s5k4ecgx_read(struct i2c_client *client,
+ u16 subaddr, u16 *data)
+{
+ u8 buf[2];
+ int err = 0;
+ struct i2c_msg msg = {
+ .addr = client->addr,
+ .flags = 0,
+ .len = 2,
+ .buf = buf,
+ };
+
+ *(u16 *)buf = cpu_to_be16(subaddr);
+
+ err = i2c_transfer(client->adapter, &msg, 1);
+ if (unlikely(err < 0))
+ cam_err("ERR: %d register read fail\n", __LINE__);
+
+ msg.flags = I2C_M_RD;
+
+ err = i2c_transfer(client->adapter, &msg, 1);
+ if (unlikely(err < 0))
+ cam_err("ERR: %d register read fail\n", __LINE__);
+
+ *data = ((buf[0] << 8) | buf[1]);
+
+ return err;
+}
+
+static inline int s5k4ecgx_write(struct i2c_client *client,
+ u32 packet)
+{
+ u8 buf[4];
+ int err = 0, retry_count = 5;
+
+ struct i2c_msg msg = {
+ .addr = client->addr,
+ .flags = 0,
+ .buf = buf,
+ .len = 4,
+ };
+
+ if (!client->adapter) {
+ cam_err("ERR - can't search i2c client adapter\n");
+ return -EIO;
+ }
+
+ while (retry_count--) {
+ *(u32 *)buf = cpu_to_be32(packet);
+ err = i2c_transfer(client->adapter, &msg, 1);
+ if (likely(err == 1))
+ break;
+ mdelay(10);
+ }
+
+ if (unlikely(err < 0)) {
+ cam_err("ERR - 0x%08x write failed err=%d\n",
+ (u32)packet, err);
+ return err;
+ }
+
+ return (err != 1) ? -1 : 0;
+}
+
+/*
+* Read a register.
+*/
+static int s5k4ecgx_read_reg(struct v4l2_subdev *sd,
+ u16 page, u16 addr, u16 *val)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ u32 page_cmd = (0x002C << 16) | page;
+ u32 addr_cmd = (0x002E << 16) | addr;
+ int err = 0;
+
+ cam_dbg("page_cmd=0x%X, addr_cmd=0x%X\n", page_cmd, addr_cmd);
+
+ err = s5k4ecgx_write(client, page_cmd);
+ CHECK_ERR(err);
+ err = s5k4ecgx_write(client, addr_cmd);
+ CHECK_ERR(err);
+ err = s5k4ecgx_read(client, 0x0F12, val);
+ CHECK_ERR(err);
+
+ return 0;
+}
+
+/* program multiple registers */
+static int s5k4ecgx_write_regs(struct v4l2_subdev *sd,
+ const u32 *packet, u32 num)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ int ret = -EAGAIN;
+ u32 temp = 0;
+ u16 delay = 0;
+ int retry_count = 5;
+
+ struct i2c_msg msg = {
+ msg.addr = client->addr,
+ msg.flags = 0,
+ msg.len = 4,
+ msg.buf = buf,
+ };
+
+ while (num--) {
+ temp = *packet++;
+
+ if ((temp & S5K4ECGX_DELAY) == S5K4ECGX_DELAY) {
+ delay = temp & 0xFFFF;
+ cam_dbg("line(%d):delay(0x%x):delay(%d)\n",
+ __LINE__, delay, delay);
+ msleep(delay);
+ continue;
+ }
+
+#ifdef S5K4ECGX_BURST_MODE
+ addr = temp >> 16;
+ value = temp & 0xFFFF;
+
+ switch (addr) {
+ case 0x0F12:
+ if (len == 0) {
+ buf[len++] = addr >> 8;
+ buf[len++] = addr & 0xFF;
+ }
+ buf[len++] = value >> 8;
+ buf[len++] = value & 0xFF;
+
+ if ((*packet >> 16) != addr) {
+ msg.len = len;
+ goto s5k4ecgx_burst_write;
+ }
+ break;
+
+ case 0xFFFF:
+ break;
+
+ default:
+ msg.len = 4;
+ *(u32 *)buf = cpu_to_be32(temp);
+ goto s5k4ecgx_burst_write;
+ }
+
+ continue;
+#else
+ *(u32 *)buf = cpu_to_be32(temp);
+#endif
+
+#ifdef S5K4ECGX_BURST_MODE
+s5k4ecgx_burst_write:
+ len = 0;
+#endif
+ retry_count = 5;
+
+ while (retry_count--) {
+ ret = i2c_transfer(client->adapter, &msg, 1);
+ if (likely(ret == 1))
+ break;
+ mdelay(10);
+ }
+
+ if (unlikely(ret < 0)) {
+ cam_err("ERR - 0x%08x write failed err=%d\n", \
+ (u32)packet, ret);
+ break;
+ }
+ }
+
+ if (unlikely(ret < 0)) {
+ cam_err("fail to write registers!!\n");
+ return -EIO;
+ }
+
+ return 0;
+}
+
+static int camera_flash_manual_ctrl(struct v4l2_subdev *sd, int mode)
+{
+ struct s5k4ecgx_state *state = to_state(sd);
+ int ret = 0;
+ cam_dbg(" E\n");
+ if (mode == CAM_FLASH_ON) {
+ /* FLASH mode */
+ ret = state->pdata->flash_ctrl(CAM_FLASH_ON);
+ state->preflash = PREFLASH_ON;
+ } else if (mode == CAM_FLASH_TORCH) {
+ /* TORCH mode */
+ ret = state->pdata->flash_ctrl(CAM_FLASH_TORCH);
+ state->preflash = PREFLASH_ON;
+ } else {
+ ret = state->pdata->flash_ctrl(CAM_FLASH_OFF);
+ state->preflash = PREFLASH_OFF;
+ }
+ return ret;
+}
+
+static int s5k4ecgx_get_exif(struct v4l2_subdev *sd)
+{
+ return 0;
+}
+
+static int s5k4ecgx_get_lux(struct v4l2_subdev *sd)
+{
+ struct s5k4ecgx_state *state = to_state(sd);
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ int msb = 0;
+ int lsb = 0;
+ int cur_lux = 0;
+ bool lowlight = false;
+ int err = 0;
+ cam_dbg(" E\n");
+ err = s5k4ecgx_write(client, 0x002C7000);
+ CHECK_ERR(err);
+ err = s5k4ecgx_write(client, 0x002E2C18);
+ CHECK_ERR(err);
+ err = s5k4ecgx_read(client, 0x0F12, (unsigned short *)&lsb);
+ CHECK_ERR(err);
+ err = s5k4ecgx_read(client, 0x0F12, (unsigned short *)&msb);
+ CHECK_ERR(err);
+
+ cur_lux = (msb << 16) | lsb;
+
+ if (cur_lux >= 0x32)
+ lowlight = false;
+ else
+ lowlight = true;
+
+ state->lowlight = lowlight;
+
+ cam_info("%s, s5k4ecgx_status.lowlight is %d\n", __func__,
+ state->lowlight);
+ /*this value is under 0x0032 in low light condition */
+ return err;
+}
+
+static int s5k4ecgx_ae_stable(struct v4l2_subdev *sd)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct s5k4ecgx_state *state = to_state(sd);
+ int val = 0;
+ int err = 0;
+ int cnt;
+ do {
+ if (state->focus.start == AUTO_FOCUS_OFF) {
+ cam_info("af_start_preflash: AF is cancelled!\n");
+ state->focus.status = CAMERA_AF_STATUS_MAX;
+ break;
+ }
+
+ err = s5k4ecgx_write(client, 0x002C7000);
+ CHECK_ERR(err);
+ err = s5k4ecgx_write(client, 0x002E2C74);
+ CHECK_ERR(err);
+ err = s5k4ecgx_read(client, 0x0F12, (unsigned short *)&val);
+ CHECK_ERR(err);
+
+ if (val == 0x1)
+ break;
+
+ s5k4ecgx_usleep(10*1000);
+
+ } while (cnt < 40);
+ cam_info("%s, ret value is %d\n", __func__,
+ val);
+
+ return err;
+}
+
+static int s5k4ecgx_set_awb_lock(struct v4l2_subdev *sd, int val)
+{
+ struct s5k4ecgx_state *state = to_state(sd);
+ int err = 0;
+ cam_info(" E\n");
+
+ if (val == state->awb_lock)
+ return 0;
+
+ if (val)
+ err = s5k4ecgx_write_regs(sd, s5k4ecgx_awb_lock_EVT1,\
+ sizeof(s5k4ecgx_awb_lock_EVT1) / \
+ sizeof(s5k4ecgx_awb_lock_EVT1[0]));
+ else
+ err = s5k4ecgx_write_regs(sd, s5k4ecgx_awb_unlock_EVT1,\
+ sizeof(s5k4ecgx_awb_unlock_EVT1) / \
+ sizeof(s5k4ecgx_awb_unlock_EVT1[0]));
+
+ CHECK_ERR(err);
+ state->awb_lock = val;
+ cam_info("awb %s\n", val ? "lock" : "unlock");
+ return err;
+}
+
+static int s5k4ecgx_set_ae_lock(struct v4l2_subdev *sd, int val)
+{
+ struct s5k4ecgx_state *state = to_state(sd);
+ int err = 0;
+ cam_info(" E\n");
+
+ if (val == state->ae_lock)
+ return 0;
+
+ if (val)
+ err = s5k4ecgx_write_regs(sd, s5k4ecgx_ae_lock_EVT1,\
+ sizeof(s5k4ecgx_ae_lock_EVT1) / \
+ sizeof(s5k4ecgx_ae_lock_EVT1[0]));
+ else
+ err = s5k4ecgx_write_regs(sd, s5k4ecgx_ae_unlock_EVT1,\
+ sizeof(s5k4ecgx_ae_unlock_EVT1) / \
+ sizeof(s5k4ecgx_ae_unlock_EVT1[0]));
+
+ CHECK_ERR(err);
+ state->ae_lock = val;
+ cam_info("ae %s\n", val ? "lock" : "unlock");
+ return err;
+}
+
+static int s5k4ecgx_check_dataline(struct v4l2_subdev *sd, s32 val)
+{
+ cam_info("DTP %s\n", val ? "ON" : "OFF");
+ return 0;
+}
+
+static int s5k4ecgx_debug_sensor_status(struct v4l2_subdev *sd)
+{
+ return 0;
+}
+
+static int s5k4ecgx_check_sensor_status(struct v4l2_subdev *sd)
+{
+ return 0;
+}
+
+static inline int s5k4ecgx_check_esd(struct v4l2_subdev *sd)
+{
+ return 0;
+}
+
+static int s5k4ecgx_set_preview_start(struct v4l2_subdev *sd)
+{
+ struct s5k4ecgx_state *state = to_state(sd);
+ int err = -EINVAL;
+
+ cam_info(" E\n");
+
+ if ((state->runmode == RUNMODE_NOTREADY) ||
+ (state->runmode == RUNMODE_CAPTURING)) {
+ cam_err("%s: ERROR - Invalid runmode\n", __func__);
+ return -EPERM;
+ }
+
+ state->focus.status = CAMERA_AF_STATUS_MAX;
+
+ if (state->runmode == RUNMODE_CAPTURE_STOP) {
+ if (state->preflash != PREFLASH_OFF) {
+ err = state->pdata->flash_ctrl(CAM_FLASH_OFF);
+ state->preflash = PREFLASH_OFF;
+ }
+ /* AE/AWB unlock */
+ err = s5k4ecgx_set_ae_lock(sd, false);
+ err = s5k4ecgx_set_awb_lock(sd, false);
+
+ err = s5k4ecgx_write_regs(sd, s5k4ecgx_Preview_Return_EVT1,\
+ sizeof(s5k4ecgx_Preview_Return_EVT1) / \
+ sizeof(s5k4ecgx_Preview_Return_EVT1[0]));
+ } else {
+ switch (state->preview_frmsizes->index) {
+ case S5K4ECGX_PREVIEW_1280:
+ err = s5k4ecgx_write_regs(sd, \
+ s5k4ecgx_1280_Preview_EVT1,\
+ sizeof(s5k4ecgx_1280_Preview_EVT1) / \
+ sizeof(s5k4ecgx_1280_Preview_EVT1[0]));
+ cam_info("S5K4ECGX_PREVIEW_1280\n");
+ break;
+ case S5K4ECGX_PREVIEW_800:
+ err = s5k4ecgx_write_regs(sd, \
+ s5k4ecgx_800_Preview_EVT1,\
+ sizeof(s5k4ecgx_800_Preview_EVT1) / \
+ sizeof(s5k4ecgx_800_Preview_EVT1[0]));
+ cam_info("S5K4ECGX_PREVIEW_800\n");
+ break;
+ case S5K4ECGX_PREVIEW_720:
+ err = s5k4ecgx_write_regs(sd, \
+ s5k4ecgx_720_Preview_EVT1,\
+ sizeof(s5k4ecgx_720_Preview_EVT1) / \
+ sizeof(s5k4ecgx_720_Preview_EVT1[0]));
+ cam_info("S5K4ECGX_PREVIEW_720\n");
+ break;
+ case S5K4ECGX_PREVIEW_320:
+ err = s5k4ecgx_write_regs(sd, \
+ s5k4ecgx_320_Preview_EVT1,\
+ sizeof(s5k4ecgx_320_Preview_EVT1) / \
+ sizeof(s5k4ecgx_320_Preview_EVT1[0]));
+ cam_info("S5K4ECGX_PREVIEW_320\n");
+ break;
+ case S5K4ECGX_PREVIEW_176:
+ err = s5k4ecgx_write_regs(sd, \
+ s5k4ecgx_176_Preview_EVT1,\
+ sizeof(s5k4ecgx_176_Preview_EVT1) / \
+ sizeof(s5k4ecgx_176_Preview_EVT1[0]));
+ cam_info("S5K4ECGX_PREVIEW_640\n");
+ break;
+ case S5K4ECGX_PREVIEW_640:
+ default:
+ err = s5k4ecgx_write_regs(sd, \
+ s5k4ecgx_640_Preview_EVT1,\
+ sizeof(s5k4ecgx_640_Preview_EVT1) / \
+ sizeof(s5k4ecgx_640_Preview_EVT1[0]));
+ cam_info("S5K4ECGX_PREVIEW_640\n");
+ break;
+ }
+
+ if (state->check_dataline)
+ err = s5k4ecgx_check_dataline(sd, 1);
+ }
+
+ if (unlikely(err)) {
+ cam_err("fail to make preview\n");
+ return err;
+ }
+
+ state->runmode = RUNMODE_RUNNING;
+
+ return 0;
+}
+
+static int s5k4ecgx_set_preview_stop(struct v4l2_subdev *sd)
+{
+ int err = 0;
+ cam_info("do nothing.\n");
+
+ return err;
+}
+
+static int s5k4ecgx_check_capture_status(struct v4l2_subdev *sd)
+{
+ int cnt = 0;
+ int status = 0;
+ int err = 0;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+
+ msleep(20);
+ while (cnt < 150) {
+ err = s5k4ecgx_write(client, 0x002C7000);
+ CHECK_ERR(err);
+ err = s5k4ecgx_write(client, 0x002E0244);
+ CHECK_ERR(err);
+ err = s5k4ecgx_read(client, 0x0F12, (unsigned short *)
+ &status);
+ CHECK_ERR(err);
+
+ if (!status)
+ break;
+ msleep(20);
+ cnt++;
+ }
+ if (cnt)
+ pr_info("[s5k4ecgx] wait time for capture frame : %dms\n",
+ cnt * 10);
+ if (status)
+ pr_info("[s5k4ecgx] take picture failed.\n");
+
+ return 0;
+}
+
+static int s5k4ecgx_set_capture_start(struct v4l2_subdev *sd)
+{
+ struct s5k4ecgx_state *state = to_state(sd);
+ int err = -EINVAL;
+ cam_info(" E\n");
+ /* check lowlight */
+ if (state->lowlight) {
+ /* check scene mode */
+ if (state->scene_mode != SCENE_MODE_NIGHTSHOT &&
+ state->scene_mode != SCENE_MODE_FIREWORKS) {
+ /*low light capture start */
+ err = s5k4ecgx_write_regs(sd,
+ s5k4ecgx_Low_Cap_On_EVT1, \
+ sizeof(s5k4ecgx_Low_Cap_On_EVT1) / \
+ sizeof(s5k4ecgx_Low_Cap_On_EVT1[0]));
+ cam_info("s5k4ecgx_set_capture_start : s5k4ecgx_Low_Cap_On_EVT1\n");
+
+ /* check flash on */
+ if (state->flash_mode == FLASH_MODE_AUTO ||
+ state->flash_mode == FLASH_MODE_ON) {
+ /* AE/AWB unlock */
+ err = s5k4ecgx_set_ae_lock(sd, false);
+ CHECK_ERR(err);
+ err = s5k4ecgx_set_awb_lock(sd, false);
+ CHECK_ERR(err);
+ /* Main flash on */
+ state->pdata->flash_ctrl(CAM_FLASH_ON);
+ state->preflash = PREFLASH_ON;
+ /* 200ms AE delay */
+ msleep(200);
+ } else
+ s5k4ecgx_cam_delay(sd);
+ }
+ } else {
+ /* check flash on */
+ if (state->flash_mode == FLASH_MODE_ON) {
+ /* AE/AWB unlock */
+ err = s5k4ecgx_set_ae_lock(sd, false);
+ CHECK_ERR(err);
+ err = s5k4ecgx_set_awb_lock(sd, false);
+ CHECK_ERR(err);
+ /* Main flash on */
+ state->pdata->flash_ctrl(CAM_FLASH_ON);
+ state->preflash = PREFLASH_ON;
+ /* 200ms AE delay */
+ msleep(200);
+ }
+ }
+
+ /*capture start*/
+ err = s5k4ecgx_write_regs(sd, s5k4ecgx_Capture_Start_EVT1, \
+ sizeof(s5k4ecgx_Capture_Start_EVT1) / \
+ sizeof(s5k4ecgx_Capture_Start_EVT1[0]));
+ cam_info("s5k4ecgx_set_capture_start : s5k4ecgx_Capture_Start_EVT1\n");
+
+ state->runmode = RUNMODE_CAPTURING;
+
+ /*capture delay*/
+ err = s5k4ecgx_check_capture_status(sd);
+
+ /* FIX later - temp code*/
+ state->pdata->flash_ctrl(CAM_FLASH_OFF);
+ state->preflash = PREFLASH_OFF;
+
+ if (unlikely(err)) {
+ cam_err("failed to make capture\n");
+ return err;
+ }
+
+ s5k4ecgx_get_exif(sd);
+
+ return err;
+}
+
+static int s5k4ecgx_set_sensor_mode(struct v4l2_subdev *sd,
+ struct v4l2_control *ctrl)
+{
+ struct s5k4ecgx_state *state = to_state(sd);
+
+ if ((ctrl->value != SENSOR_CAMERA) &&
+ (ctrl->value != SENSOR_MOVIE)) {
+ cam_err("ERR: Not support.(%d)\n", ctrl->value);
+ return -EINVAL;
+ }
+
+ state->sensor_mode = ctrl->value;
+
+ return 0;
+}
+
+static int s5k4ecgx_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
+{
+ cam_dbg("E\n");
+ return 0;
+}
+
+static int s5k4ecgx_enum_framesizes(struct v4l2_subdev *sd, \
+ struct v4l2_frmsizeenum *fsize)
+{
+ struct s5k4ecgx_state *state = to_state(sd);
+
+ cam_dbg("s5k4ecgx_enum_framesizes E\n");
+
+ /*
+ * Return the actual output settings programmed to the camera
+ *
+ * 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->req_fmt.priv == V4L2_PIX_FMT_MODE_CAPTURE) {
+ fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
+ fsize->discrete.width = state->capture_frmsizes->width;
+ fsize->discrete.height = state->capture_frmsizes->height;
+ } else {
+ fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
+ fsize->discrete.width = state->preview_frmsizes->width;
+ fsize->discrete.height = state->preview_frmsizes->height;
+ }
+
+ cam_info("width - %d , height - %d\n",
+ fsize->discrete.width, fsize->discrete.height);
+
+ return 0;
+}
+
+static int s5k4ecgx_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
+{
+ int err = 0;
+
+ cam_dbg("E\n");
+
+ return err;
+}
+
+static int s5k4ecgx_set_fmt_size(struct v4l2_subdev *sd)
+{
+ struct s5k4ecgx_state *state = to_state(sd);
+ int err = 0;
+ cam_info("s5k4ecgx_set_fmt_size E\n");
+
+ if (state->req_fmt.priv == V4L2_PIX_FMT_MODE_CAPTURE) {
+ switch (state->capture_frmsizes->index) {
+ case S5K4ECGX_CAPTURE_5MP:
+ err = s5k4ecgx_write_regs(sd,
+ s5k4ecgx_5M_Capture_EVT1,\
+ sizeof(s5k4ecgx_5M_Capture_EVT1) /
+ sizeof(s5k4ecgx_5M_Capture_EVT1[0]));
+ cam_info("s5k4ecgx_set_fmt_size : S5K4ECGX_CAPTURE_5MP\n");
+ break;
+ case S5K4ECGX_CAPTURE_3MP:
+ err = s5k4ecgx_write_regs(sd,
+ s5k4ecgx_3M_Capture_EVT1,
+ sizeof(s5k4ecgx_3M_Capture_EVT1) /
+ sizeof(s5k4ecgx_3M_Capture_EVT1[0]));
+ cam_info("s5k4ecgx_set_fmt_size : S5K4ECGX_CAPTURE_3MP\n");
+ break;
+ case S5K4ECGX_CAPTURE_2MP:
+ err = s5k4ecgx_write_regs(sd,
+ s5k4ecgx_2M_Capture_EVT1,
+ sizeof(s5k4ecgx_2M_Capture_EVT1) /
+ sizeof(s5k4ecgx_2M_Capture_EVT1[0]));
+ cam_info("s5k4ecgx_set_fmt_size : S5K4ECGX_CAPTURE_2MP\n");
+ break;
+ case S5K4ECGX_CAPTURE_1MP:
+ err = s5k4ecgx_write_regs(sd,
+ s5k4ecgx_1M_Capture_EVT1,
+ sizeof(s5k4ecgx_1M_Capture_EVT1) /
+ sizeof(s5k4ecgx_1M_Capture_EVT1[0]));
+ cam_info("s5k4ecgx_set_fmt_size : S5K4ECGX_CAPTURE_1MP\n");
+ break;
+ case S5K4ECGX_CAPTURE_XGA:
+ err = s5k4ecgx_write_regs(sd,
+ s5k4ecgx_XGA_Capture_EVT1,
+ sizeof(s5k4ecgx_XGA_Capture_EVT1) /
+ sizeof(s5k4ecgx_XGA_Capture_EVT1[0]));
+ cam_info("s5k4ecgx_set_fmt_size : S5K4ECGX_CAPTURE_XGA\n");
+ break;
+ case S5K4ECGX_CAPTURE_VGA:
+ err = s5k4ecgx_write_regs(sd,
+ s5k4ecgx_VGA_Capture_EVT1,
+ sizeof(s5k4ecgx_VGA_Capture_EVT1) /
+ sizeof(s5k4ecgx_VGA_Capture_EVT1[0]));
+ cam_info("s5k4ecgx_set_fmt_size : S5K4ECGX_CAPTURE_VGA\n");
+ break;
+ default:
+ cam_err("ERR: Invalid capture size\n");
+ break;
+ }
+ }
+
+ if (unlikely(err < 0)) {
+ cam_err("i2c_write for set framerate\n");
+ return -EIO;
+ }
+
+ return err;
+}
+
+static int s5k4ecgx_s_fmt(struct v4l2_subdev *sd, \
+ struct v4l2_mbus_framefmt *ffmt)
+{
+ struct s5k4ecgx_state *state = to_state(sd);
+ u32 num_entries = 0;
+ u32 i;
+ u32 err = 0;
+ u32 width, height = 0;
+
+ cam_info("s5k4ecgx_s_fmt E\n");
+ /*
+ * Just copying the requested format as of now.
+ * We need to check here what are the formats the camera support, and
+ * set the most appropriate one according to the request from FIMC
+ */
+
+ width = state->req_fmt.width = ffmt->width;
+ height = state->req_fmt.height = ffmt->height;
+
+ if (ffmt->colorspace == V4L2_COLORSPACE_JPEG)
+ state->req_fmt.priv = V4L2_PIX_FMT_MODE_CAPTURE;
+ else
+ state->req_fmt.priv = V4L2_PIX_FMT_MODE_PREVIEW;
+
+ switch (state->req_fmt.priv) {
+ case V4L2_PIX_FMT_MODE_PREVIEW:
+ cam_info("V4L2_PIX_FMT_MODE_PREVIEW\n");
+ num_entries = ARRAY_SIZE(preview_frmsizes);
+ for (i = 0; i < num_entries; i++) {
+ if (width == preview_frmsizes[i].width &&
+ height == preview_frmsizes[i].height) {
+ state->preview_frmsizes = &preview_frmsizes[i];
+ break;
+ }
+ if (i == (num_entries - 1))
+ state->preview_frmsizes = &preview_frmsizes[0];
+ }
+ break;
+
+ case V4L2_PIX_FMT_MODE_CAPTURE:
+ cam_info("V4L2_PIX_FMT_MODE_CAPTURE\n");
+ num_entries = ARRAY_SIZE(capture_frmsizes);
+ for (i = 0; i < num_entries; i++) {
+ if (width == capture_frmsizes[i].width && \
+ height == capture_frmsizes[i].height) {
+ state->capture_frmsizes = &capture_frmsizes[i];
+ break;
+ }
+ }
+ break;
+
+ default:
+ cam_err
+ ("ERR(EINVAL) : Invalid capture size width(%d), height(%d)\n",\
+ ffmt->width, ffmt->height);
+ return -EINVAL;
+ }
+
+ /*set frame size of preview or capture*/
+ err = s5k4ecgx_set_fmt_size(sd);
+
+ return err;
+}
+
+static int s5k4ecgx_set_frame_rate(struct v4l2_subdev *sd, u32 fps)
+{
+ int err = 0;
+
+ cam_info("frame rate %d\n\n", fps);
+
+ switch (fps) {
+ case 7:
+ err = s5k4ecgx_write_regs(sd, s5k4ecgx_FPS_7_EVT1,
+ sizeof(s5k4ecgx_FPS_7_EVT1) / \
+ sizeof(s5k4ecgx_FPS_7_EVT1[0]));
+ break;
+ case 15:
+ err = s5k4ecgx_write_regs(sd, s5k4ecgx_FPS_15_EVT1,
+ sizeof(s5k4ecgx_FPS_15_EVT1) / \
+ sizeof(s5k4ecgx_FPS_15_EVT1[0]));
+
+ break;
+ case 20:
+ err = s5k4ecgx_write_regs(sd, s5k4ecgx_FPS_20_EVT1,
+ sizeof(s5k4ecgx_FPS_20_EVT1) / \
+ sizeof(s5k4ecgx_FPS_20_EVT1[0]));
+
+ break;
+ case 24:
+ err = s5k4ecgx_write_regs(sd, s5k4ecgx_FPS_24_EVT1,
+ sizeof(s5k4ecgx_FPS_24_EVT1) / \
+ sizeof(s5k4ecgx_FPS_24_EVT1[0]));
+ break;
+ case 30:
+ err = s5k4ecgx_write_regs(sd, s5k4ecgx_FPS_30_EVT1,
+ sizeof(s5k4ecgx_FPS_30_EVT1) / \
+ sizeof(s5k4ecgx_FPS_30_EVT1[0]));
+ break;
+ default:
+ cam_err("ERR: Invalid framerate\n");
+ break;
+ }
+
+ if (unlikely(err < 0)) {
+ cam_err("i2c_write for set framerate\n");
+ return -EIO;
+ }
+
+ return err;
+}
+
+static int s5k4ecgx_g_parm(struct v4l2_subdev *sd,\
+ struct v4l2_streamparm *parms)
+{
+ int err = 0;
+
+ cam_dbg("E\n");
+
+ return err;
+}
+
+static int s5k4ecgx_s_parm(struct v4l2_subdev *sd, \
+ struct v4l2_streamparm *parms)
+{
+ int err = 0;
+ u32 fps = 0;
+ u32 denom = parms->parm.capture.timeperframe.denominator;
+ u32 numer = parms->parm.capture.timeperframe.numerator;
+ struct s5k4ecgx_state *state = to_state(sd);
+
+ cam_dbg("E\n");
+
+ if (denom >= 1 && numer == 1)
+ fps = denom / numer;
+ else if (denom == 1 && numer == 0)
+ fps = 0;
+
+ if (fps != state->set_fps) {
+ if (fps < 0 && fps > 30) {
+ cam_err("invalid frame rate %d\n", fps);
+ fps = 30;
+ }
+ state->req_fps = fps;
+
+ if (state->initialized) {
+ err = s5k4ecgx_set_frame_rate(sd, state->req_fps);
+ if (err >= 0)
+ state->set_fps = state->req_fps;
+ }
+
+ }
+
+ return err;
+}
+
+static int s5k4ecgx_control_stream(struct v4l2_subdev *sd, int cmd)
+{
+ struct s5k4ecgx_state *state = to_state(sd);
+ int err = 0;
+
+ switch (cmd) {
+ case STREAM_START:
+ cam_warn("WARN: do nothing\n");
+ break;
+
+ case STREAM_STOP:
+ cam_dbg("stream stop!!!\n");
+ if (state->runmode == RUNMODE_CAPTURING)
+ state->runmode = RUNMODE_CAPTURE_STOP;
+
+ break;
+
+ default:
+ cam_err("ERR: Invalid cmd\n");
+ break;
+ }
+
+ if (unlikely(err))
+ cam_err("failed to stream start(stop)\n");
+
+ return err;
+}
+
+static int s5k4ecgx_init(struct v4l2_subdev *sd, u32 val)
+{
+ struct s5k4ecgx_state *state = to_state(sd);
+ int err = -EINVAL;
+
+ cam_dbg("E\n");
+
+ /* set initial regster value */
+ if (state->sensor_mode == SENSOR_CAMERA) {
+ cam_info("load camera common setting\n");
+ err = s5k4ecgx_write_regs(sd, s5k4ecgx_init_reg1_EVT1,
+ sizeof(s5k4ecgx_init_reg1_EVT1) / \
+ sizeof(s5k4ecgx_init_reg1_EVT1[0]));
+
+ msleep(20);
+
+ err |= s5k4ecgx_write_regs(sd, s5k4ecgx_init_reg2_EVT1,
+ sizeof(s5k4ecgx_init_reg2_EVT1) / \
+ sizeof(s5k4ecgx_init_reg2_EVT1[0]));
+ } else {
+ cam_info("load recording setting\n");
+ err = s5k4ecgx_write_regs(sd, s5k4ecgx_init_reg1_EVT1,
+ sizeof(s5k4ecgx_init_reg1_EVT1) / \
+ sizeof(s5k4ecgx_init_reg1_EVT1[0]));
+
+ msleep(20);
+
+ err = s5k4ecgx_write_regs(sd, s5k4ecgx_init_reg2_EVT1,
+ sizeof(s5k4ecgx_init_reg2_EVT1) / \
+ sizeof(s5k4ecgx_init_reg2_EVT1[0]));
+ }
+
+ if (unlikely(err)) {
+ cam_err("failed to init\n");
+ return err;
+ }
+
+ state->runmode = RUNMODE_INIT;
+
+ /* We stop stream-output from sensor when starting camera. */
+ err = s5k4ecgx_control_stream(sd, STREAM_STOP);
+ if (unlikely(err < 0))
+ return err;
+ msleep(150);
+
+ state->initialized = 1;
+
+ return 0;
+}
+
+static int s5k4ecgx_s_stream(struct v4l2_subdev *sd, int enable)
+{
+ struct s5k4ecgx_state *state = to_state(sd);
+ int err = 0;
+
+ cam_info("stream mode = %d\n", enable);
+
+ switch (enable) {
+ case STREAM_MODE_CAM_OFF:
+ if (state->sensor_mode == SENSOR_CAMERA) {
+ if (state->check_dataline)
+ err = s5k4ecgx_check_dataline(sd, 0);
+ else
+ err = s5k4ecgx_control_stream(sd, STREAM_STOP);
+ }
+ break;
+
+ case STREAM_MODE_CAM_ON:
+ /* The position of this code need to be adjusted later */
+ if ((state->sensor_mode == SENSOR_CAMERA)
+ && (state->req_fmt.priv == V4L2_PIX_FMT_MODE_CAPTURE))
+ err = s5k4ecgx_set_capture_start(sd);
+ else
+ err = s5k4ecgx_set_preview_start(sd);
+ break;
+
+ case STREAM_MODE_MOVIE_ON:
+ cam_dbg("do nothing(movie on)!!\n");
+ break;
+
+ case STREAM_MODE_MOVIE_OFF:
+ cam_dbg("do nothing(movie off)!!\n");
+ break;
+
+ default:
+ cam_err("ERR: Invalid stream mode\n");
+ break;
+ }
+
+ if (unlikely(err < 0)) {
+ cam_err("ERR: faild\n");
+ return err;
+ }
+
+ return 0;
+}
+
+static int s5k4ecgx_get_af_1stsearch(struct v4l2_subdev *sd,
+ struct v4l2_control *ctrl)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ int af_status = -1;
+ int err = 0;
+ int ret = 0;
+ cam_info("- Start\n");
+ err = s5k4ecgx_write(client, 0x002C7000);
+ CHECK_ERR(err);
+ err = s5k4ecgx_write(client, 0x002E2EEE);
+ CHECK_ERR(err);
+ err = s5k4ecgx_read(client, 0x0F12, (unsigned short *)&af_status);
+ CHECK_ERR(err);
+
+ switch (af_status & 0xff) {
+ case AF_PROGRESS_1ST:
+ ret = CAMERA_AF_STATUS_IN_PROGRESS;
+ break;
+
+ case AF_SUCCESS_1ST:
+ ret = CAMERA_AF_STATUS_SUCCESS;
+ break;
+
+ case AF_FAIL_1ST:
+ default:
+ ret = CAMERA_AF_STATUS_FAIL;
+ break;
+ }
+
+ ctrl->value = ret;
+ cam_info("- END%d\n", ret);
+ return ret;
+}
+
+static int s5k4ecgx_get_af_2ndsearch(struct v4l2_subdev *sd,
+ struct v4l2_control *ctrl)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ int af_status = -1;
+ int err = 0;
+ int ret = 0;
+ cam_info(" E\n");
+ err = s5k4ecgx_write(client, 0x002C7000);
+ CHECK_ERR(err);
+ err = s5k4ecgx_write(client, 0x002E2207);
+ CHECK_ERR(err);
+ err = s5k4ecgx_read(client, 0x0F12, (unsigned short *)&af_status);
+ CHECK_ERR(err);
+
+ switch (af_status & 0xff) {
+ case AF_SUCCESS_2ND:
+ ret = CAMERA_AF_STATUS_SUCCESS;
+ break;
+
+ case AF_PROGRESS_2ND:
+ default:
+ ret = CAMERA_AF_STATUS_IN_PROGRESS;
+ break;
+ }
+
+ ctrl->value = ret;
+ cam_info(" - END%d\n", ret);
+ return ret;
+}
+
+static int s5k4ecgx_get_af_result(struct v4l2_subdev *sd,
+ struct v4l2_control *ctrl)
+{
+ struct s5k4ecgx_state *state = to_state(sd);
+ int status = 0;
+ cam_info(" - START\n");
+ if (state->focus.first == true) {
+ state->focus.first = false;
+ s5k4ecgx_cam_delay(sd);
+ }
+
+ /* 1st search af */
+ s5k4ecgx_cam_delay(sd);
+
+ status = s5k4ecgx_get_af_1stsearch(sd, ctrl);
+
+ if (status != CAMERA_AF_STATUS_SUCCESS) {
+ state->focus.status = status;
+ if (status == CAMERA_AF_STATUS_FAIL)
+ state->pdata->flash_ctrl(CAM_FLASH_OFF);
+ state->preflash = PREFLASH_OFF;
+ return status;
+ }
+
+ /* 2nd search af */
+ s5k4ecgx_cam_delay(sd);
+
+ status = s5k4ecgx_get_af_2ndsearch(sd, ctrl);
+
+ state->focus.status = status;
+ state->pdata->flash_ctrl(CAM_FLASH_OFF);
+ state->preflash = PREFLASH_OFF;
+
+ cam_info("af_status = %d\n", status);
+ cam_info(" - END\n");
+ return 0;
+}
+
+
+static int s5k4ecgx_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+{
+ struct s5k4ecgx_state *state = to_state(sd);
+ int err = 0;
+
+ /* V4L2_CID_PRIVATE_BASE==0x08000000 */
+ /* V4L2_CID_CAMERA_CLASS_BASE==0x009a0900 */
+ /* V4L2_CID_BASE==0x00980900 */
+
+ if (ctrl->id > V4L2_CID_PRIVATE_BASE)
+ cam_dbg("ctrl->id:%d, value=%d V4L2_CID_PRIVATE_BASE\n",\
+ ctrl->id - V4L2_CID_PRIVATE_BASE, ctrl->value);
+ else if (ctrl->id > V4L2_CID_CAMERA_CLASS_BASE)
+ cam_dbg("ctrl->id:%d, value=%d V4L2_CID_CAMERA_CLASS_BASE\n",\
+ ctrl->id - V4L2_CID_CAMERA_CLASS_BASE, ctrl->value);
+ else
+ cam_dbg("ctrl->id:%d, value=%d V4L2_CID_BASE\n", \
+ ctrl->id - V4L2_CID_BASE, ctrl->value);
+
+ mutex_lock(&state->ctrl_lock);
+
+ switch (ctrl->id) {
+ case V4L2_CID_CAMERA_AUTO_FOCUS_RESULT:
+ ctrl->value = state->focus.status;
+ break;
+
+ case V4L2_CID_CAM_JPEG_MEMSIZE:
+ ctrl->value = S5K4ECGX_INTLV_DATA_MAXSIZE;
+ break;
+
+ case V4L2_CID_CAM_JPEG_MAIN_SIZE:
+ ctrl->value = S5K4ECGX_INTLV_DATA_MAXSIZE;
+ break;
+
+ case V4L2_CID_CAM_JPEG_MAIN_OFFSET:
+ ctrl->value = 0;
+ break;
+
+ case V4L2_CID_CAM_JPEG_THUMB_SIZE:
+ ctrl->value = 0;
+ break;
+
+ case V4L2_CID_CAM_JPEG_THUMB_OFFSET:
+ ctrl->value = 0;
+ break;
+
+ case V4L2_CID_CAM_JPEG_POSTVIEW_OFFSET:
+ ctrl->value = 0;
+ break;
+
+ case V4L2_CID_CAMERA_EXIF_FLASH:
+ ctrl->value = state->exif.flash;
+ break;
+
+ case V4L2_CID_CAMERA_ISO:
+ ctrl->value = state->exif.iso;
+ break;
+
+ case V4L2_CID_CAMERA_EXIF_ISO:
+ ctrl->value = state->exif.iso;
+ break;
+
+ case V4L2_CID_CAMERA_EXIF_TV:
+ ctrl->value = state->exif.tv;
+ break;
+
+ case V4L2_CID_CAMERA_EXIF_BV:
+ ctrl->value = state->exif.bv;
+ break;
+
+ case V4L2_CID_CAMERA_EXIF_EBV:
+ ctrl->value = state->exif.ebv;
+ break;
+
+ case V4L2_CID_WHITE_BALANCE_PRESET:
+ ctrl->value = state->wb_mode;
+ break;
+
+ default:
+ cam_err("no such control id %d\n",
+ ctrl->id - V4L2_CID_PRIVATE_BASE);
+ break;
+ }
+
+ mutex_unlock(&state->ctrl_lock);
+
+ return err;
+}
+
+static int s5k4ecgx_set_iso(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+{
+ int err;
+ struct s5k4ecgx_state *state = to_state(sd);
+ cam_dbg("E, value %d\n", ctrl->value);
+
+retry:
+ switch (ctrl->value) {
+ case ISO_AUTO:
+ err = s5k4ecgx_write_regs(sd, s5k4ecgx_ISO_Auto_EVT1, \
+ sizeof(s5k4ecgx_ISO_Auto_EVT1) / \
+ sizeof(s5k4ecgx_ISO_Auto_EVT1[0]));
+ break;
+
+ case ISO_50:
+ err = s5k4ecgx_write_regs(sd, s5k4ecgx_ISO_50_EVT1, \
+ sizeof(s5k4ecgx_ISO_50_EVT1) / \
+ sizeof(s5k4ecgx_ISO_50_EVT1[0]));
+ break;
+
+ case ISO_100:
+ err = s5k4ecgx_write_regs(sd, s5k4ecgx_ISO_100_EVT1, \
+ sizeof(s5k4ecgx_ISO_100_EVT1) / \
+ sizeof(s5k4ecgx_ISO_100_EVT1[0]));
+ break;
+
+ case ISO_200:
+ err = s5k4ecgx_write_regs(sd, s5k4ecgx_ISO_200_EVT1, \
+ sizeof(s5k4ecgx_ISO_200_EVT1) / \
+ sizeof(s5k4ecgx_ISO_200_EVT1[0]));
+ break;
+
+ case ISO_400:
+ err = s5k4ecgx_write_regs(sd, s5k4ecgx_ISO_400_EVT1, \
+ sizeof(s5k4ecgx_ISO_400_EVT1) / \
+ sizeof(s5k4ecgx_ISO_400_EVT1[0]));
+ break;
+
+ default:
+ cam_warn("invalid value, %d\n", ctrl->value);
+ ctrl->value = ISO_AUTO;
+ goto retry;
+ }
+
+ state->exif.iso = ctrl->value;
+
+ cam_dbg("X\n");
+ return 0;
+}
+
+static int s5k4ecgx_set_metering(struct v4l2_subdev *sd, int val)
+{
+ int err;
+ cam_dbg("E, value %d\n", val);
+
+retry:
+ switch (val) {
+ case METERING_CENTER:
+ err = s5k4ecgx_write_regs(sd, s5k4ecgx_Metering_Center_EVT1, \
+ sizeof(s5k4ecgx_Metering_Center_EVT1) / \
+ sizeof(s5k4ecgx_Metering_Center_EVT1[0]));
+ break;
+
+ case METERING_SPOT:
+ err = s5k4ecgx_write_regs(sd, s5k4ecgx_Metering_Spot_EVT1, \
+ sizeof(s5k4ecgx_Metering_Spot_EVT1) / \
+ sizeof(s5k4ecgx_Metering_Spot_EVT1[0]));
+ break;
+
+ case METERING_MATRIX:
+ err = s5k4ecgx_write_regs(sd, s5k4ecgx_Metering_Matrix_EVT1, \
+ sizeof(s5k4ecgx_Metering_Matrix_EVT1) / \
+ sizeof(s5k4ecgx_Metering_Matrix_EVT1[0]));
+ break;
+
+ default:
+ cam_warn("invalid value, %d\n", val);
+ val = METERING_CENTER;
+ goto retry;
+ }
+
+ cam_dbg("X\n");
+ return 0;
+}
+
+static int s5k4ecgx_set_exposure(struct v4l2_subdev *sd, \
+ struct v4l2_control *ctrl)
+{
+ struct s5k4ecgx_state *state = to_state(sd);
+ int err = -EINVAL;
+
+ cam_dbg("E\n");
+
+ if (state->check_dataline)
+ return 0;
+
+ switch (ctrl->value) {
+ case 0:
+ err = s5k4ecgx_write_regs(sd, s5k4ecgx_EV_Minus_4_EVT1, \
+ sizeof(s5k4ecgx_EV_Minus_4_EVT1) / \
+ sizeof(s5k4ecgx_EV_Minus_4_EVT1[0]));
+ break;
+ case 1:
+ err = s5k4ecgx_write_regs(sd, s5k4ecgx_EV_Minus_3_EVT1, \
+ sizeof(s5k4ecgx_EV_Minus_3_EVT1) / \
+ sizeof(s5k4ecgx_EV_Minus_3_EVT1[0]));
+
+ break;
+ case 2:
+ err = s5k4ecgx_write_regs(sd, s5k4ecgx_EV_Minus_2_EVT1, \
+ sizeof(s5k4ecgx_EV_Minus_2_EVT1) / \
+ sizeof(s5k4ecgx_EV_Minus_2_EVT1[0]));
+ break;
+ case 3:
+ err = s5k4ecgx_write_regs(sd, s5k4ecgx_EV_Minus_1_EVT1, \
+ sizeof(s5k4ecgx_EV_Minus_1_EVT1) / \
+ sizeof(s5k4ecgx_EV_Minus_1_EVT1[0]));
+ break;
+ case 4:
+ err = s5k4ecgx_write_regs(sd, s5k4ecgx_EV_Default_EVT1, \
+ sizeof(s5k4ecgx_EV_Default_EVT1) / \
+ sizeof(s5k4ecgx_EV_Default_EVT1[0]));
+ break;
+ case 5:
+ err = s5k4ecgx_write_regs(sd, s5k4ecgx_EV_Plus_1_EVT1, \
+ sizeof(s5k4ecgx_EV_Plus_1_EVT1) / \
+ sizeof(s5k4ecgx_EV_Plus_1_EVT1[0]));
+ break;
+ case 6:
+ err = s5k4ecgx_write_regs(sd, s5k4ecgx_EV_Plus_2_EVT1, \
+ sizeof(s5k4ecgx_EV_Plus_2_EVT1) / \
+ sizeof(s5k4ecgx_EV_Plus_2_EVT1[0]));
+ break;
+ case 7:
+ err = s5k4ecgx_write_regs(sd, s5k4ecgx_EV_Plus_3_EVT1, \
+ sizeof(s5k4ecgx_EV_Plus_3_EVT1) / \
+ sizeof(s5k4ecgx_EV_Plus_3_EVT1[0]));
+ break;
+ case 8:
+ err = s5k4ecgx_write_regs(sd, s5k4ecgx_EV_Plus_4_EVT1, \
+ sizeof(s5k4ecgx_EV_Plus_4_EVT1) / \
+ sizeof(s5k4ecgx_EV_Plus_4_EVT1[0]));
+ break;
+ default:
+ cam_err("ERR: invalid brightness(%d)\n", ctrl->value);
+ return err;
+ break;
+ }
+
+ if (unlikely(err < 0)) {
+ cam_err("ERR: i2c_write for set brightness\n");
+ return -EIO;
+ }
+
+ return 0;
+}
+
+static int s5k4ecgx_set_whitebalance(struct v4l2_subdev *sd, int val)
+{
+ int err;
+ struct s5k4ecgx_state *state = to_state(sd);
+ cam_dbg("E, value %d\n", val);
+
+retry:
+ switch (val) {
+ case WHITE_BALANCE_AUTO:
+ err = s5k4ecgx_write_regs(sd, s5k4ecgx_WB_Auto_EVT1, \
+ sizeof(s5k4ecgx_WB_Auto_EVT1) / \
+ sizeof(s5k4ecgx_WB_Auto_EVT1[0]));
+ break;
+
+ case WHITE_BALANCE_SUNNY:
+ err = s5k4ecgx_write_regs(sd, s5k4ecgx_WB_Sunny_EVT1, \
+ sizeof(s5k4ecgx_WB_Sunny_EVT1) / \
+ sizeof(s5k4ecgx_WB_Sunny_EVT1[0]));
+ break;
+
+ case WHITE_BALANCE_CLOUDY:
+ err = s5k4ecgx_write_regs(sd, s5k4ecgx_WB_Cloudy_EVT1, \
+ sizeof(s5k4ecgx_WB_Cloudy_EVT1) / \
+ sizeof(s5k4ecgx_WB_Cloudy_EVT1[0]));
+ break;
+
+ case WHITE_BALANCE_TUNGSTEN:
+ err = s5k4ecgx_write_regs(sd, s5k4ecgx_WB_Tungsten_EVT1, \
+ sizeof(s5k4ecgx_WB_Tungsten_EVT1) / \
+ sizeof(s5k4ecgx_WB_Tungsten_EVT1[0]));
+ break;
+
+ case WHITE_BALANCE_FLUORESCENT:
+ err = s5k4ecgx_write_regs(sd, s5k4ecgx_WB_Fluorescent_EVT1, \
+ sizeof(s5k4ecgx_WB_Fluorescent_EVT1) / \
+ sizeof(s5k4ecgx_WB_Fluorescent_EVT1[0]));
+ break;
+
+ default:
+ cam_warn("invalid value, %d\n", val);
+ val = WHITE_BALANCE_AUTO;
+ goto retry;
+ }
+
+ state->wb_mode = val;
+ cam_dbg("X\n");
+ return 0;
+}
+
+static int s5k4ecgx_set_scene_mode(struct v4l2_subdev *sd, int val)
+{
+ int err;
+ cam_dbg("E, value %d\n", val);
+
+retry:
+ switch (val) {
+ case SCENE_MODE_NONE:
+ err = s5k4ecgx_write_regs(sd, s5k4ecgx_Scene_Default_EVT1, \
+ sizeof(s5k4ecgx_Scene_Default_EVT1) / \
+ sizeof(s5k4ecgx_Scene_Default_EVT1[0]));
+ break;
+
+ case SCENE_MODE_PORTRAIT:
+ err = s5k4ecgx_write_regs(sd, s5k4ecgx_Scene_Portrait_EVT1, \
+ sizeof(s5k4ecgx_Scene_Portrait_EVT1) / \
+ sizeof(s5k4ecgx_Scene_Portrait_EVT1[0]));
+ break;
+
+ case SCENE_MODE_LANDSCAPE:
+ err = s5k4ecgx_write_regs(sd, s5k4ecgx_Scene_Landscape_EVT1, \
+ sizeof(s5k4ecgx_Scene_Landscape_EVT1) / \
+ sizeof(s5k4ecgx_Scene_Landscape_EVT1[0]));
+ break;
+
+ case SCENE_MODE_SPORTS:
+ err = s5k4ecgx_write_regs(sd, s5k4ecgx_Scene_Sports_EVT1, \
+ sizeof(s5k4ecgx_Scene_Sports_EVT1) / \
+ sizeof(s5k4ecgx_Scene_Sports_EVT1[0]));
+ break;
+
+ case SCENE_MODE_PARTY_INDOOR:
+ err = s5k4ecgx_write_regs(sd, s5k4ecgx_Scene_Party_Indoor_EVT1,\
+ sizeof(s5k4ecgx_Scene_Party_Indoor_EVT1) / \
+ sizeof(s5k4ecgx_Scene_Party_Indoor_EVT1[0]));
+ break;
+
+ case SCENE_MODE_BEACH_SNOW:
+ err = s5k4ecgx_write_regs(sd, s5k4ecgx_Scene_Beach_Snow_EVT1, \
+ sizeof(s5k4ecgx_Scene_Beach_Snow_EVT1) / \
+ sizeof(s5k4ecgx_Scene_Beach_Snow_EVT1[0]));
+ break;
+
+ case SCENE_MODE_SUNSET:
+ err = s5k4ecgx_write_regs(sd, s5k4ecgx_Scene_Sunset_EVT1, \
+ sizeof(s5k4ecgx_Scene_Sunset_EVT1) / \
+ sizeof(s5k4ecgx_Scene_Sunset_EVT1[0]));
+ break;
+
+ case SCENE_MODE_DUSK_DAWN:
+ err = s5k4ecgx_write_regs(sd, s5k4ecgx_Scene_Duskdawn_EVT1, \
+ sizeof(s5k4ecgx_Scene_Duskdawn_EVT1) / \
+ sizeof(s5k4ecgx_Scene_Duskdawn_EVT1[0]));
+ break;
+
+ case SCENE_MODE_FALL_COLOR:
+ err = s5k4ecgx_write_regs(sd, s5k4ecgx_Scene_Fall_Color_EVT1, \
+ sizeof(s5k4ecgx_Scene_Fall_Color_EVT1) / \
+ sizeof(s5k4ecgx_Scene_Fall_Color_EVT1[0]));
+ break;
+
+ case SCENE_MODE_NIGHTSHOT:
+ err = s5k4ecgx_write_regs(sd, s5k4ecgx_Scene_Nightshot_EVT1, \
+ sizeof(s5k4ecgx_Scene_Nightshot_EVT1) / \
+ sizeof(s5k4ecgx_Scene_Nightshot_EVT1[0]));
+ break;
+
+ case SCENE_MODE_BACK_LIGHT:
+ err = s5k4ecgx_write_regs(sd, s5k4ecgx_Scene_Backlight_EVT1, \
+ sizeof(s5k4ecgx_Scene_Backlight_EVT1) / \
+ sizeof(s5k4ecgx_Scene_Backlight_EVT1[0]));
+ break;
+
+ case SCENE_MODE_FIREWORKS:
+ err = s5k4ecgx_write_regs(sd, s5k4ecgx_Scene_Fireworks_EVT1, \
+ sizeof(s5k4ecgx_Scene_Fireworks_EVT1) / \
+ sizeof(s5k4ecgx_Scene_Fireworks_EVT1[0]));
+ break;
+
+ case SCENE_MODE_TEXT:
+ err = s5k4ecgx_write_regs(sd, s5k4ecgx_Scene_Text_EVT1, \
+ sizeof(s5k4ecgx_Scene_Text_EVT1) / \
+ sizeof(s5k4ecgx_Scene_Text_EVT1[0]));
+ break;
+
+ case SCENE_MODE_CANDLE_LIGHT:
+ err = s5k4ecgx_write_regs(sd, \
+ s5k4ecgx_Scene_Candle_Light_EVT1, \
+ sizeof(s5k4ecgx_Scene_Candle_Light_EVT1) / \
+ sizeof(s5k4ecgx_Scene_Candle_Light_EVT1[0]));
+ break;
+
+ default:
+ cam_warn("invalid value, %d\n", val);
+ val = SCENE_MODE_NONE;
+ goto retry;
+ }
+
+ cam_dbg("X\n");
+ return 0;
+}
+
+static int s5k4ecgx_set_effect(struct v4l2_subdev *sd, int val)
+{
+ int err;
+ cam_dbg("E, value %d\n", val);
+
+retry:
+ switch (val) {
+ case IMAGE_EFFECT_NONE:
+ err = s5k4ecgx_write_regs(sd, s5k4ecgx_Effect_Normal_EVT1, \
+ sizeof(s5k4ecgx_Effect_Normal_EVT1) / \
+ sizeof(s5k4ecgx_Effect_Normal_EVT1[0]));
+ break;
+
+ case IMAGE_EFFECT_SEPIA:
+ err = s5k4ecgx_write_regs(sd, s5k4ecgx_Effect_Sepia_EVT1, \
+ sizeof(s5k4ecgx_Effect_Sepia_EVT1) / \
+ sizeof(s5k4ecgx_Effect_Sepia_EVT1[0]));
+ break;
+
+ case IMAGE_EFFECT_BNW:
+ err = s5k4ecgx_write_regs(sd, \
+ s5k4ecgx_Effect_Black_White_EVT1, \
+ sizeof(s5k4ecgx_Effect_Black_White_EVT1) / \
+ sizeof(s5k4ecgx_Effect_Black_White_EVT1[0]));
+ break;
+
+ case IMAGE_EFFECT_NEGATIVE:
+ err = s5k4ecgx_write_regs(sd, s5k4ecgx_Effect_Negative_EVT1, \
+ sizeof(s5k4ecgx_Effect_Negative_EVT1) / \
+ sizeof(s5k4ecgx_Effect_Negative_EVT1[0]));
+ break;
+
+ case IMAGE_EFFECT_AQUA:
+ err = s5k4ecgx_write_regs(sd, \
+ s5k4ecgx_Effect_Solarization_EVT1, \
+ sizeof(s5k4ecgx_Effect_Solarization_EVT1) / \
+ sizeof(s5k4ecgx_Effect_Solarization_EVT1[0]));
+ break;
+
+ default:
+ cam_warn("invalid value, %d\n", val);
+ val = IMAGE_EFFECT_NONE;
+ goto retry;
+ }
+
+ cam_dbg("X\n");
+ return 0;
+}
+
+static int s5k4ecgx_set_wdr(struct v4l2_subdev *sd, int val)
+{
+ int err;
+ cam_dbg("E, value %d\n", val);
+
+retry:
+ switch (val) {
+ case WDR_OFF:
+ err = s5k4ecgx_write_regs(sd, s5k4ecgx_WDR_off_EVT1, \
+ sizeof(s5k4ecgx_WDR_off_EVT1) / \
+ sizeof(s5k4ecgx_WDR_off_EVT1[0]));
+ break;
+
+ case WDR_ON:
+ err = s5k4ecgx_write_regs(sd, s5k4ecgx_WDR_on_EVT1, \
+ sizeof(s5k4ecgx_WDR_on_EVT1) / \
+ sizeof(s5k4ecgx_WDR_on_EVT1[0]));
+ break;
+
+ default:
+ cam_warn("invalid value, %d\n", val);
+ val = WDR_OFF;
+ goto retry;
+ }
+
+ cam_dbg("X\n");
+ return 0;
+}
+
+static int s5k4ecgx_set_jpeg_quality(struct v4l2_subdev *sd, int val)
+{
+ int err = -1;
+ cam_dbg("E, value %d\n", val);
+
+ if (val <= 65) /* Normal */
+ err = s5k4ecgx_write_regs(sd, s5k4ecgx_Jpeg_Quality_Low_EVT1,\
+ sizeof(s5k4ecgx_Jpeg_Quality_Low_EVT1) / \
+ sizeof(s5k4ecgx_Jpeg_Quality_Low_EVT1[0]));
+ else if (val <= 75) /* Fine */
+ err = s5k4ecgx_write_regs
+ (sd, s5k4ecgx_Jpeg_Quality_Normal_EVT1,\
+ sizeof(s5k4ecgx_Jpeg_Quality_Normal_EVT1) / \
+ sizeof(s5k4ecgx_Jpeg_Quality_Normal_EVT1[0]));
+ else /* Superfine */
+ err = s5k4ecgx_write_regs(sd, s5k4ecgx_Jpeg_Quality_High_EVT1,\
+ sizeof(s5k4ecgx_Jpeg_Quality_High_EVT1) / \
+ sizeof(s5k4ecgx_Jpeg_Quality_High_EVT1[0]));
+
+ CHECK_ERR(err);
+
+ cam_dbg("X\n");
+ return 0;
+}
+
+static int s5k4ecgx_return_focus(struct v4l2_subdev *sd)
+{
+ struct s5k4ecgx_state *state = to_state(sd);
+ int err = -EINVAL;
+
+ cam_info("E\n");
+
+ switch (state->focus.mode) {
+ case FOCUS_MODE_MACRO:
+ err = s5k4ecgx_write_regs(sd, s5k4ecgx_AF_Macro_mode_1_EVT1,\
+ sizeof(s5k4ecgx_AF_Macro_mode_1_EVT1) / \
+ sizeof(s5k4ecgx_AF_Macro_mode_1_EVT1[0]));
+
+ s5k4ecgx_cam_delay(sd);
+
+ err = s5k4ecgx_write_regs(sd, s5k4ecgx_AF_Macro_mode_2_EVT1,\
+ sizeof(s5k4ecgx_AF_Macro_mode_2_EVT1) / \
+ sizeof(s5k4ecgx_AF_Macro_mode_2_EVT1[0]));
+
+ s5k4ecgx_cam_delay(sd);
+
+ err = s5k4ecgx_write_regs(sd, s5k4ecgx_AF_Macro_mode_3_EVT1,\
+ sizeof(s5k4ecgx_AF_Macro_mode_3_EVT1) / \
+ sizeof(s5k4ecgx_AF_Macro_mode_3_EVT1[0]));
+
+ break;
+
+ default:
+ err = s5k4ecgx_write_regs(sd, s5k4ecgx_AF_Normal_mode_1_EVT1,\
+ sizeof(s5k4ecgx_AF_Normal_mode_1_EVT1) / \
+ sizeof(s5k4ecgx_AF_Normal_mode_1_EVT1[0]));
+
+ s5k4ecgx_cam_delay(sd);
+
+ err = s5k4ecgx_write_regs(sd, s5k4ecgx_AF_Normal_mode_2_EVT1,\
+ sizeof(s5k4ecgx_AF_Normal_mode_2_EVT1) / \
+ sizeof(s5k4ecgx_AF_Normal_mode_2_EVT1[0]));
+
+ s5k4ecgx_cam_delay(sd);
+
+ err = s5k4ecgx_write_regs(sd, s5k4ecgx_AF_Normal_mode_3_EVT1,\
+ sizeof(s5k4ecgx_AF_Normal_mode_3_EVT1) / \
+ sizeof(s5k4ecgx_AF_Normal_mode_3_EVT1[0]));
+
+ break;
+ }
+
+ CHECK_ERR(err);
+ return 0;
+}
+
+/* PX: Stop AF */
+static int s5k4ecgx_stop_af(struct v4l2_subdev *sd, s32 touch)
+{
+ struct s5k4ecgx_state *state = to_state(sd);
+ int err = 0;
+
+ cam_info("E\n");
+ mutex_lock(&state->af_lock);
+
+ switch (state->focus.status) {
+ case CAMERA_AF_STATUS_FAIL:
+ case CAMERA_AF_STATUS_SUCCESS:
+ cam_dbg("Stop AF, focus mode %d, AF result %d\n",
+ state->focus.mode, state->focus.status);
+
+ err = s5k4ecgx_set_ae_lock(sd, false);
+ err = s5k4ecgx_set_awb_lock(sd, false);
+ if (unlikely(err)) {
+ cam_err("%s: ERROR, fail to set lock\n", __func__);
+ goto err_out;
+ }
+ state->focus.status = CAMERA_AF_STATUS_MAX;
+ state->preflash = PREFLASH_NONE;
+ break;
+
+ case CAMERA_AF_STATUS_MAX:
+ break;
+
+ default:
+ cam_err("%s: WARNING, unnecessary calling. AF status=%d\n",
+ __func__, state->focus.status);
+ /* Return 0. */
+ goto err_out;
+ break;
+ }
+
+ if (!touch) {
+ /* We move lens to default position if af is cancelled.*/
+ err = s5k4ecgx_return_focus(sd);
+ if (unlikely(err)) {
+ cam_err("%s: ERROR, fail to af_norma_mode (%d)\n",
+ __func__, err);
+ goto err_out;
+ }
+ }
+
+ mutex_unlock(&state->af_lock);
+ cam_info("X\n");
+ return 0;
+
+err_out:
+ mutex_unlock(&state->af_lock);
+ return err;
+}
+
+static int s5k4ecgx_set_af_mode(struct v4l2_subdev *sd, int val)
+{
+ struct s5k4ecgx_state *state = to_state(sd);
+ int err = -1;
+ u32 af_cancel = 0;
+ cam_info(" - value %d\n", val);
+
+ mutex_lock(&state->af_lock);
+
+retry:
+ af_cancel = (u32)val & FOCUS_MODE_DEFAULT;
+ switch (val) {
+ case FOCUS_MODE_AUTO:
+ case FOCUS_MODE_INFINITY:
+ state->focus.mode = val;
+
+ err = s5k4ecgx_write_regs(sd, s5k4ecgx_AF_Normal_mode_1_EVT1,\
+ sizeof(s5k4ecgx_AF_Normal_mode_1_EVT1) / \
+ sizeof(s5k4ecgx_AF_Normal_mode_1_EVT1[0]));
+
+ s5k4ecgx_cam_delay(sd);
+
+ err = s5k4ecgx_write_regs(sd, s5k4ecgx_AF_Normal_mode_2_EVT1,\
+ sizeof(s5k4ecgx_AF_Normal_mode_2_EVT1) / \
+ sizeof(s5k4ecgx_AF_Normal_mode_2_EVT1[0]));
+
+ s5k4ecgx_cam_delay(sd);
+
+ err = s5k4ecgx_write_regs(sd, s5k4ecgx_AF_Normal_mode_3_EVT1,\
+ sizeof(s5k4ecgx_AF_Normal_mode_3_EVT1) / \
+ sizeof(s5k4ecgx_AF_Normal_mode_3_EVT1[0]));
+
+ break;
+
+ case FOCUS_MODE_MACRO:
+ state->focus.mode = val;
+
+ err = s5k4ecgx_write_regs(sd, s5k4ecgx_AF_Macro_mode_1_EVT1,\
+ sizeof(s5k4ecgx_AF_Macro_mode_1_EVT1) / \
+ sizeof(s5k4ecgx_AF_Macro_mode_1_EVT1[0]));
+
+ s5k4ecgx_cam_delay(sd);
+
+ err = s5k4ecgx_write_regs(sd, s5k4ecgx_AF_Macro_mode_2_EVT1,\
+ sizeof(s5k4ecgx_AF_Macro_mode_2_EVT1) / \
+ sizeof(s5k4ecgx_AF_Macro_mode_2_EVT1[0]));
+
+ s5k4ecgx_cam_delay(sd);
+
+ err = s5k4ecgx_write_regs(sd, s5k4ecgx_AF_Macro_mode_3_EVT1,\
+ sizeof(s5k4ecgx_AF_Macro_mode_3_EVT1) / \
+ sizeof(s5k4ecgx_AF_Macro_mode_3_EVT1[0]));
+
+ break;
+
+ default:
+ cam_warn("invalid value, %d\n", val);
+ val = FOCUS_MODE_AUTO;
+ goto retry;
+ }
+
+ state->focus.mode = val;
+ mutex_unlock(&state->af_lock);
+
+ if (af_cancel)
+ s5k4ecgx_stop_af(sd, 0);
+
+ return 0;
+
+ CHECK_ERR(err);
+ return 0;
+}
+
+/* PX: Do AF */
+static int s5k4ecgx_do_af(struct v4l2_subdev *sd)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct s5k4ecgx_state *state = to_state(sd);
+ u16 read_value = 0;
+ u32 count = 0;
+ int err = 0;
+
+ cam_info("E\n");
+
+ /* AE, AWB Lock */
+ err = s5k4ecgx_set_ae_lock(sd, true);
+ CHECK_ERR(err);
+ err = s5k4ecgx_set_awb_lock(sd, true);
+ CHECK_ERR(err);
+
+ /* AF start */
+ err = s5k4ecgx_write_regs(sd, s5k4ecgx_Single_AF_Start_EVT1,\
+ sizeof(s5k4ecgx_Single_AF_Start_EVT1) / \
+ sizeof(s5k4ecgx_Single_AF_Start_EVT1[0]));
+ CHECK_ERR(err);
+
+ /* 1 frame delay */
+ s5k4ecgx_cam_delay(sd);
+
+ /* AF Searching */
+ cam_dbg("AF 1st search\n");
+
+ /*1st search*/
+ for (count = 0; count < FIRST_AF_SEARCH_COUNT; count++) {
+ if (state->focus.start == AUTO_FOCUS_OFF) {
+ cam_dbg("do_af: AF is cancelled while doing(1st)\n");
+ state->focus.status = CAMERA_AF_STATUS_MAX;
+ goto check_done;
+ }
+
+ /* 1 frame delay */
+ s5k4ecgx_cam_delay(sd);
+
+ read_value = 0x0;
+ err = s5k4ecgx_write(client, 0x002C7000);
+ CHECK_ERR(err);
+ err = s5k4ecgx_write(client, 0x002E2EEE);
+ CHECK_ERR(err);
+ err = s5k4ecgx_read(client, 0x0F12, &read_value);
+ CHECK_ERR(err);
+ cam_info("1st AF status(%02d) = 0x%04X\n",
+ count, read_value);
+
+ if ((read_value & 0xff) != AF_PROGRESS_1ST)
+ break;
+ }
+
+ if ((read_value & 0xff) != AF_SUCCESS_1ST) {
+ cam_err("%s: ERROR, 1st AF failed. count=%d, read_val=0x%X\n\n",
+ __func__, count, read_value);
+ state->focus.status = CAMERA_AF_STATUS_FAIL;
+ goto check_done;
+ }
+
+ /*2nd search*/
+ cam_dbg("AF 2nd search\n");
+ for (count = 0; count < SECOND_AF_SEARCH_COUNT; count++) {
+ if (state->focus.start == AUTO_FOCUS_OFF) {
+ cam_dbg("do_af: AF is cancelled while doing(2nd)\n");
+ state->focus.status = CAMERA_AF_STATUS_MAX;
+ goto check_done;
+ }
+
+ read_value = 0x0;
+ err = s5k4ecgx_write(client, 0x002C7000);
+ CHECK_ERR(err);
+ err = s5k4ecgx_write(client, 0x002E2207);
+ CHECK_ERR(err);
+ err = s5k4ecgx_read(client, 0x0F12, &read_value);
+ CHECK_ERR(err);
+ cam_info("2nd AF status(%02d) = 0x%04X\n",
+ count, read_value);
+ if ((read_value & 0xff) == AF_SUCCESS_2ND)
+ break;
+ }
+
+ if (count >= SECOND_AF_SEARCH_COUNT) {
+ /* 0x01XX means "Not Finish". */
+ cam_err("%s: ERROR, 2nd AF failed. read_val=0x%X\n\n",
+ __func__, read_value & 0xff);
+ state->focus.status = CAMERA_AF_STATUS_FAIL;
+ goto check_done;
+ }
+
+ cam_info("AF Success!\n");
+ state->focus.status = CAMERA_AF_STATUS_SUCCESS;
+
+check_done:
+ /* restore write mode */
+
+ /* We only unlocked AE,AWB in case of being cancelled.
+ * But we now unlock it unconditionally if AF is started,
+ */
+ if (state->focus.status == CAMERA_AF_STATUS_MAX) {
+ cam_dbg("%s: Single AF cancelled.\n", __func__);
+ /* AE, AWB Lock */
+ err = s5k4ecgx_set_ae_lock(sd, false);
+ CHECK_ERR(err);
+ err = s5k4ecgx_set_awb_lock(sd, false);
+ CHECK_ERR(err);
+ } else {
+ state->focus.start = AUTO_FOCUS_OFF;
+ cam_dbg("%s: Single AF finished\n", __func__);
+ }
+
+ if ((state->preflash == PREFLASH_ON) &&
+ (state->sensor_mode == SENSOR_CAMERA)) {
+ state->pdata->flash_ctrl(CAM_FLASH_OFF);
+ state->preflash = PREFLASH_OFF;
+ if (state->focus.status == CAMERA_AF_STATUS_MAX)
+ state->preflash = PREFLASH_NONE;
+ }
+
+ /* Notice: we here turn touch flag off set previously
+ * when doing Touch AF. */
+
+ return 0;
+}
+
+static void s5k4ecgx_af_worker(struct work_struct *work)
+{
+ struct s5k4ecgx_state *state = container_of(work, \
+ struct s5k4ecgx_state, af_work);
+ struct v4l2_subdev *sd = &state->sd;
+ int err = -EINVAL;
+
+ cam_info("E\n");
+
+ mutex_lock(&state->af_lock);
+
+ /* 1. Check Low Light */
+ err = s5k4ecgx_get_lux(sd);
+
+ /* 2. Turn on Pre Flash */
+ switch (state->flash_mode) {
+ case FLASH_MODE_AUTO:
+ if (!state->lowlight) {
+ /* flash not needed */
+ break;
+ }
+
+ case FLASH_MODE_ON:
+ state->pdata->flash_ctrl(CAM_FLASH_TORCH);
+ state->preflash = PREFLASH_ON;
+ break;
+
+ case FLASH_MODE_OFF:
+ default:
+ break;
+ }
+
+ if (state->preflash == PREFLASH_ON) {
+ /* 3. Waiting until AE Stable */
+ err = s5k4ecgx_ae_stable(sd);
+ } else if (state->focus.start == AUTO_FOCUS_OFF) {
+ cam_info("af_start_preflash: AF is cancelled!\n");
+ state->focus.status = CAMERA_AF_STATUS_MAX;
+ }
+
+ if (state->focus.status == CAMERA_AF_STATUS_MAX) {
+ if (state->preflash == PREFLASH_ON) {
+ state->pdata->flash_ctrl(CAM_FLASH_OFF);
+ state->preflash = PREFLASH_OFF;
+ }
+ goto out;
+ }
+
+ s5k4ecgx_do_af(sd);
+
+out:
+ mutex_unlock(&state->af_lock);
+ cam_info("X\n");
+ return;
+}
+
+static int s5k4ecgx_set_af(struct v4l2_subdev *sd, s32 val)
+{
+ struct s5k4ecgx_state *state = to_state(sd);
+ int err = 0;
+
+ cam_info("%s: %s, focus mode %d\n", __func__,
+ val ? "start" : "stop", state->focus.mode);
+
+ if (unlikely((u32)val >= AUTO_FOCUS_MAX)) {
+ cam_err("%s: ERROR, invalid value(%d)\n", __func__, val);
+ return -EINVAL;
+ }
+
+/* need to check the AF scenario with SLP team - temp code */
+/*
+ if (state->focus.start == val)
+ return 0;
+*/
+ state->focus.start = val;
+
+ if (val == AUTO_FOCUS_ON) {
+ err = queue_work(state->workqueue, &state->af_work);
+ if (likely(err))
+ state->focus.status = CAMERA_AF_STATUS_IN_PROGRESS;
+ else
+ cam_warn("WARNING, AF is still processing. So new AF cannot start\n");
+ } else {
+ /* Cancel AF */
+ /* 1. AE/AWB UnLock */
+ err = s5k4ecgx_set_ae_lock(sd, false);
+ CHECK_ERR(err);
+ err = s5k4ecgx_set_awb_lock(sd, false);
+ CHECK_ERR(err);
+ /* 2. Turn off on pre flash */
+ state->pdata->flash_ctrl(CAM_FLASH_OFF);
+ state->preflash = PREFLASH_OFF;
+ /* 3. Cancel AF mode */
+ err = s5k4ecgx_set_af_mode(sd, state->focus.mode);
+ cam_info("set_af: AF cancel requested!\n");
+ }
+
+ cam_info("X\n");
+ return 0;
+}
+
+static int s5k4ecgx_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+{
+ /* struct i2c_client *client = v4l2_get_subdevdata(sd); */
+ struct s5k4ecgx_state *state = to_state(sd);
+ int err = 0;
+
+ /* V4L2_CID_PRIVATE_BASE == 0x08000000 */
+ /* V4L2_CID_CAMERA_CLASS_BASE == 0x009a0900 */
+ /* V4L2_CID_BASE == 0x00980900 */
+
+ if (ctrl->id > V4L2_CID_PRIVATE_BASE)
+ cam_dbg("ctrl->id:%d, value=%d V4L2_CID_PRIVATE_BASE\n", \
+ ctrl->id - V4L2_CID_PRIVATE_BASE, ctrl->value);
+ else if (ctrl->id > V4L2_CID_CAMERA_CLASS_BASE)
+ cam_dbg("ctrl->id:%d, value=%d V4L2_CID_CAMERA_CLASS_BASE\n",\
+ ctrl->id - V4L2_CID_CAMERA_CLASS_BASE, ctrl->value);
+ else
+ cam_dbg("ctrl->id:%d, value=%d V4L2_CID_BASE\n", \
+ ctrl->id - V4L2_CID_BASE, ctrl->value);
+
+ if ((ctrl->id != V4L2_CID_CAMERA_CHECK_DATALINE)
+ && (ctrl->id != V4L2_CID_CAMERA_SENSOR_MODE)
+ && ((ctrl->id != V4L2_CID_CAMERA_VT_MODE))
+ && (!state->initialized)) {
+ cam_warn("camera isn't initialized\n");
+ return 0;
+ }
+
+ if (ctrl->id != V4L2_CID_CAMERA_SET_AUTO_FOCUS)
+ mutex_lock(&state->ctrl_lock);
+
+ switch (ctrl->id) {
+ case V4L2_CID_CAM_JPEG_QUALITY:
+ err = s5k4ecgx_set_jpeg_quality(sd, ctrl->value);
+ break;
+
+ case V4L2_CID_CAMERA_ISO:
+ err = s5k4ecgx_set_iso(sd, ctrl);
+ break;
+
+ case V4L2_CID_CAMERA_METERING:
+ if (state->sensor_mode == SENSOR_CAMERA)
+ err = s5k4ecgx_set_metering(sd, ctrl->value);
+ break;
+
+ case V4L2_CID_EXPOSURE:
+ err = s5k4ecgx_set_exposure(sd, ctrl);
+ cam_dbg("V4L2_CID_EXPOSURE [%d]\n", ctrl->value);
+ break;
+
+ case V4L2_CID_WHITE_BALANCE_PRESET:
+ case V4L2_CID_CAMERA_WHITE_BALANCE:
+ err = s5k4ecgx_set_whitebalance(sd, ctrl->value);
+ break;
+
+ case V4L2_CID_CAMERA_SCENE_MODE:
+ state->scene_mode = ctrl->value;
+ err = s5k4ecgx_set_scene_mode(sd, ctrl->value);
+ break;
+
+ case V4L2_CID_COLORFX:
+ err = s5k4ecgx_set_effect(sd, ctrl->value);
+ break;
+
+ case V4L2_CID_CAMERA_WDR:
+ err = s5k4ecgx_set_wdr(sd, ctrl->value);
+ break;
+
+ case V4L2_CID_CAMERA_FLASH_MODE:
+ state->flash_mode = ctrl->value;
+ break;
+
+ case V4L2_CID_FOCUS_AUTO_MODE:
+ case V4L2_CID_CAMERA_FOCUS_MODE:
+ err = s5k4ecgx_set_af_mode(sd, ctrl->value);
+ break;
+
+ case V4L2_CID_CAMERA_SET_AUTO_FOCUS:
+ err = s5k4ecgx_set_af(sd, ctrl->value);
+ break;
+
+ case V4L2_CID_CAMERA_CHECK_DATALINE:
+ state->check_dataline = ctrl->value;
+ cam_dbg("check_dataline = %d\n", state->check_dataline);
+ err = 0;
+ break;
+
+ case V4L2_CID_CAMERA_SENSOR_MODE:
+ err = s5k4ecgx_set_sensor_mode(sd, ctrl);
+ cam_dbg("sensor_mode = %d\n", ctrl->value);
+ break;
+
+ case V4L2_CID_CAMERA_CHECK_DATALINE_STOP:
+ cam_dbg("do nothing\n");
+ break;
+
+ case V4L2_CID_CAMERA_CHECK_ESD:
+ err = s5k4ecgx_check_esd(sd);
+ break;
+
+ case V4L2_CID_CAMERA_FRAME_RATE:
+ err = s5k4ecgx_set_frame_rate(sd, ctrl->value);
+ break;
+
+ case V4L2_CID_CAMERA_CHECK_SENSOR_STATUS:
+ s5k4ecgx_debug_sensor_status(sd);
+ err = s5k4ecgx_check_sensor_status(sd);
+ break;
+
+ default:
+ cam_err("ERR(ENOIOCTLCMD)\n");
+ /* no errors return.*/
+ break;
+ }
+
+ if (ctrl->id != V4L2_CID_CAMERA_SET_AUTO_FOCUS)
+ mutex_unlock(&state->ctrl_lock);
+
+ cam_dbg("X\n");
+ return err;
+}
+
+static const struct v4l2_subdev_core_ops s5k4ecgx_core_ops = {
+ .init = s5k4ecgx_init, /* initializing API */
+ .g_ctrl = s5k4ecgx_g_ctrl,
+ .s_ctrl = s5k4ecgx_s_ctrl,
+};
+
+static const struct v4l2_subdev_video_ops s5k4ecgx_video_ops = {
+ .s_mbus_fmt = s5k4ecgx_s_fmt,
+ .s_stream = s5k4ecgx_s_stream,
+ .enum_framesizes = s5k4ecgx_enum_framesizes,
+ .g_parm = s5k4ecgx_g_parm,
+ .s_parm = s5k4ecgx_s_parm,
+};
+
+static const struct v4l2_subdev_ops s5k4ecgx_ops = {
+ .core = &s5k4ecgx_core_ops,
+ .video = &s5k4ecgx_video_ops,
+};
+
+/*
+ * s5k4ecgx_probe
+ * Fetching platform data is being done with s_config subdev call.
+ * In probe routine, we just register subdev device
+ */
+static int s5k4ecgx_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct s5k4ecgx_state *state = NULL;
+ struct v4l2_subdev *sd = NULL;
+ struct s5k4ecgx_platform_data *pdata = NULL;
+ cam_dbg("E\n");
+
+ state = kzalloc(sizeof(struct s5k4ecgx_state), GFP_KERNEL);
+ if (state == NULL)
+ return -ENOMEM;
+
+ sd = &state->sd;
+ strcpy(sd->name, S5K4ECGX_DRIVER_NAME);
+
+ state->runmode = RUNMODE_NOTREADY;
+ state->initialized = 0;
+ state->req_fps = state->set_fps = 0;
+ state->sensor_mode = SENSOR_CAMERA;
+ state->zoom = 0;
+ state->flash_mode = FLASH_MODE_BASE;
+ state->lowlight = 0;
+ state->awb_lock = 0;
+ state->ae_lock = 0;
+ state->preflash = PREFLASH_NONE;
+
+ pdata = client->dev.platform_data;
+
+ if (!pdata) {
+ cam_err("no platform data\n");
+ return -ENODEV;
+ }
+
+ /* Registering subdev */
+ v4l2_i2c_subdev_init(sd, client, &s5k4ecgx_ops);
+
+ mutex_init(&state->ctrl_lock);
+ mutex_init(&state->af_lock);
+
+ state->workqueue = create_workqueue("cam_workqueue");
+ if (unlikely(!state->workqueue)) {
+ dev_err(&client->dev, "probe, fail to create workqueue\n");
+ goto err_out;
+ }
+ INIT_WORK(&state->af_work, s5k4ecgx_af_worker);
+
+ /*
+ * Assign default format and resolution
+ * Use configured default information in platform data
+ * or without them, use default information in driver
+ */
+
+ /*S5K4ECGX_PREVIEW_VGA*/
+ state->preview_frmsizes = &preview_frmsizes[0];
+ /*S5K4ECGX_CAPTURE_5MP */
+ state->capture_frmsizes = &capture_frmsizes[0];
+ cam_dbg("preview_width: %d , preview_height: %d, "
+ "capture_width: %d, capture_height: %d",
+ state->preview_frmsizes->width, state->preview_frmsizes->height,
+ state->capture_frmsizes->width, state->capture_frmsizes->height);
+
+ state->req_fmt.width = state->preview_frmsizes->width;
+ state->req_fmt.height = state->preview_frmsizes->height;
+
+ state->pdata = pdata;
+
+ if (!pdata->pixelformat)
+ state->req_fmt.pixelformat = DEFAULT_FMT;
+ else
+ state->req_fmt.pixelformat = pdata->pixelformat;
+
+ cam_dbg("probed!!\n");
+
+ return 0;
+
+err_out:
+ kfree(state);
+ return -ENOMEM;
+}
+
+static int s5k4ecgx_remove(struct i2c_client *client)
+{
+ struct v4l2_subdev *sd = i2c_get_clientdata(client);
+ struct s5k4ecgx_state *state = to_state(sd);
+
+ cam_dbg("E\n");
+
+ destroy_workqueue(state->workqueue);
+
+ state->initialized = 0;
+
+ v4l2_device_unregister_subdev(sd);
+
+ mutex_destroy(&state->ctrl_lock);
+ mutex_destroy(&state->af_lock);
+
+ kfree(to_state(sd));
+
+ return 0;
+}
+
+static const struct i2c_device_id s5k4ecgx_id[] = {
+ { S5K4ECGX_DRIVER_NAME, 0 },
+ { },
+};
+MODULE_DEVICE_TABLE(i2c, s5k4ecgx_id);
+
+static struct i2c_driver s5k4ecgx_i2c_driver = {
+ .driver = {
+ .name = S5K4ECGX_DRIVER_NAME,
+ },
+ .probe = s5k4ecgx_probe,
+ .remove = s5k4ecgx_remove,
+ .id_table = s5k4ecgx_id,
+};
+
+static int __init s5k4ecgx_mod_init(void)
+{
+ cam_dbg("E\n");
+ return i2c_add_driver(&s5k4ecgx_i2c_driver);
+}
+
+static void __exit s5k4ecgx_mod_exit(void)
+{
+ cam_dbg("E\n");
+ i2c_del_driver(&s5k4ecgx_i2c_driver);
+}
+module_init(s5k4ecgx_mod_init);
+module_exit(s5k4ecgx_mod_exit);
+
+MODULE_DESCRIPTION("S5K4ECGX MIPI sensor driver");
+MODULE_AUTHOR("seungwoolee<samuell.lee@samsung.com>");
+MODULE_AUTHOR("jinsookim<js1002.kim@samsung.com>");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/slp_s5k4ecgx.h b/drivers/media/video/slp_s5k4ecgx.h
new file mode 100644
index 0000000..400581f
--- /dev/null
+++ b/drivers/media/video/slp_s5k4ecgx.h
@@ -0,0 +1,195 @@
+/*
+ * Driver for S5K4ECGX 5M ISP from Samsung
+ * Copyright (C) 2012 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.
+ */
+
+#ifndef __S5K4ECGX_H
+#define __S5K4ECGX_H
+
+#include <linux/types.h>
+
+#define S5K4ECGX_DRIVER_NAME "S5K4ECGX"
+#define is_focus(__mode) (state->focus.mode == __mode)
+
+#define FIRST_AF_SEARCH_COUNT 80
+#define SECOND_AF_SEARCH_COUNT 80
+
+extern struct class *camera_class;
+
+enum stream_cmd {
+ STREAM_STOP,
+ STREAM_START,
+};
+
+struct s5k4ecgx_framesize {
+ u32 index;
+ u32 width;
+ u32 height;
+};
+
+struct s5k4ecgx_exif {
+ u32 exptime; /* us */
+ u16 flash;
+ u16 iso;
+ int tv; /* shutter speed */
+ int bv; /* brightness */
+ int ebv; /* exposure bias */
+};
+
+struct s5k4ecgx_focus {
+ unsigned int mode;
+ unsigned int lock;
+ unsigned int status;
+ unsigned int touch;
+ unsigned int pos_x;
+ unsigned int pos_y;
+ unsigned int width;
+ unsigned int height;
+ unsigned int start;
+ bool focusing;
+ bool needed;
+ bool first;
+};
+
+enum preflash_status {
+ PREFLASH_NONE = 0,
+ PREFLASH_OFF,
+ PREFLASH_ON,
+};
+
+enum s5k4ecgx_runmode {
+ RUNMODE_NOTREADY,
+ RUNMODE_INIT,
+ RUNMODE_RUNNING, /* previewing */
+ RUNMODE_RUNNING_STOP,
+ RUNMODE_CAPTURING,
+ RUNMODE_CAPTURE_STOP,
+};
+
+/*
+ * Driver information
+ */
+struct s5k4ecgx_state {
+ struct v4l2_subdev sd;
+ struct device *s5k4ecgx_dev;
+ struct s5k4ecgx_platform_data *pdata;
+ /*
+ * req_fmt is the requested format from the application.
+ * set_fmt is the output format of the camera. Finally FIMC
+ * converts the camera output(set_fmt) to the requested format
+ * with hardware scaler.
+ */
+ struct v4l2_pix_format req_fmt;
+ const struct s5k4ecgx_framesize *preview_frmsizes;
+ const struct s5k4ecgx_framesize *capture_frmsizes;
+ struct s5k4ecgx_exif exif;
+ struct s5k4ecgx_focus focus;
+
+ enum v4l2_flash_mode flash_mode;
+ enum preflash_status preflash;
+ enum v4l2_sensor_mode sensor_mode;
+ enum v4l2_scene_mode scene_mode;
+ enum v4l2_wb_mode wb_mode;
+ enum s5k4ecgx_runmode runmode;
+
+ struct mutex ctrl_lock; /* Mutex */
+ struct mutex af_lock; /* Mutex */
+ struct work_struct af_work; /* workque for AF */
+ struct work_struct af_win_work; /* workque for AF */
+ struct workqueue_struct *workqueue; /* workque for AF */
+
+ s32 vt_mode;
+ s32 check_dataline;
+ u32 req_fps;
+ u32 set_fps;
+ u32 initialized;
+ u32 zoom;
+ bool lowlight;
+ bool ae_lock;
+ bool awb_lock;
+};
+
+enum AF_1ST_STATUS {
+ AF_PROGRESS_1ST = 1,
+ AF_SUCCESS_1ST ,
+ AF_FAIL_1ST,
+};
+
+enum AF_2ND_STATUS {
+ AF_SUCCESS_2ND = 0,
+ AF_PROGRESS_2ND = 1,
+};
+
+enum s5k4ecgx_prev_frmsize {
+ S5K4ECGX_PREVIEW_176, /* 176 x 144 */
+ S5K4ECGX_PREVIEW_320, /* 320 x 240 */
+ S5K4ECGX_PREVIEW_640, /* 640 x 480 */
+ S5K4ECGX_PREVIEW_720, /* 720 x 480 */
+ S5K4ECGX_PREVIEW_800, /* 800 x 480 */
+ S5K4ECGX_PREVIEW_1280, /* 1280 x 720 */
+};
+
+enum s5k4ecgx_cap_frmsize {
+ S5K4ECGX_CAPTURE_VGA, /* 640 x 480 */
+ S5K4ECGX_CAPTURE_XGA, /* 1024 x 768 */
+ S5K4ECGX_CAPTURE_1MP, /* 1280 x 960 */
+ S5K4ECGX_CAPTURE_2MP, /* UXGA - 1600 x 1200 */
+ S5K4ECGX_CAPTURE_3MP, /* QXGA - 2048 x 1536 */
+ S5K4ECGX_CAPTURE_5MP, /* 2560 x 1920 */
+};
+
+static inline struct s5k4ecgx_state *to_state(struct v4l2_subdev *sd)
+{
+ return container_of(sd, struct s5k4ecgx_state, sd);
+}
+
+/*#define CONFIG_CAM_DEBUG */
+#define cam_warn(fmt, ...) \
+ do { \
+ printk(KERN_WARNING "%s: " fmt, __func__, ##__VA_ARGS__); \
+ } while (0)
+
+#define cam_err(fmt, ...) \
+ do { \
+ printk(KERN_ERR "%s: " fmt, __func__, ##__VA_ARGS__); \
+ } while (0)
+
+#define cam_info(fmt, ...) \
+ do { \
+ printk(KERN_INFO "%s: " fmt, __func__, ##__VA_ARGS__); \
+ } while (0)
+
+#ifdef CONFIG_CAM_DEBUG
+#define cam_dbg(fmt, ...) \
+ do { \
+ printk(KERN_DEBUG "%s: " fmt, __func__, ##__VA_ARGS__); \
+ } while (0)
+#else
+#define cam_dbg(fmt, ...)
+#endif /* CONFIG_CAM_DEBUG */
+
+
+/************ driver feature ************/
+#define S5K4ECGX_USLEEP
+/* #define CONFIG_LOAD_FILE */
+
+
+/*********** Sensor specific ************/
+/* #define S5K4ECGX_100MS_DELAY 0xAA55AA5F */
+/* #define S5K4ECGX_10MS_DELAY 0xAA55AA5E */
+#define S5K4ECGX_DELAY 0xFFFF0000
+#define S5K4ECGX_DEF_APEX_DEN 100
+
+/* Register address */
+#define REG_PAGE_SHUTTER 0x7000
+#define REG_ADDR_SHUTTER 0x14D0
+#define REG_PAGE_ISO 0x7000
+#define REG_ADDR_ISO 0x14C8
+
+#include "slp_s5k4ecgx_setfile.h"
+
+#endif /* __S5K4ECGX_H */
diff --git a/drivers/media/video/slp_s5k4ecgx_setfile.h b/drivers/media/video/slp_s5k4ecgx_setfile.h
new file mode 100644
index 0000000..2c84c7b
--- /dev/null
+++ b/drivers/media/video/slp_s5k4ecgx_setfile.h
@@ -0,0 +1,7308 @@
+/*
+ * Driver for S5K4ECGX 5M ISP from Samsung
+ *
+ * Copyright (C) 2011,
+ *
+ *
+ * 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.
+ */
+#ifndef __S5K4ECGX_SETFILE_H
+#define __S5K4ECGX_SETFILE_H
+
+#include <linux/types.h>
+
+/*
+ * s5k4ecgx register configuration for combinations of initialization
+ */
+/* FOR 4EC EVT1.1*/
+
+/*//////////////////////////FOR EVT1.1//////////////////////////*/
+/* 20110706 SEMCO Base setting*/
+/* ARM Initiation */
+static const u32 s5k4ecgx_init_reg1_EVT1[] = {
+/*==================================================================
+// 01.Start Setting
+//==================================================================*/
+ 0xFCFCD000,
+ 0x00100001, /*S/W Reset */
+ 0x10300000, /*contint_host_int */
+ 0x00140001, /*sw_load_complete-Release CORE(Arm)from reset state*/
+};
+
+/* Delay 10ms*/
+
+static const u32 s5k4ecgx_init_reg2_EVT1[] = {
+/*===============================================================
+//02.ETC Setting
+//==============================================================*/
+
+ 0x0028D000,
+ 0x002A1082, /*Driving current Setting */
+ 0x0F1202AA, /*d0_d4_cd10 d0_d4_cd10 9:0 */
+ 0x0F1202AA, /*d5_d9_cd10 d5_d9_cd10 9:0 */
+ 0x0F1200AA, /*gpio_cd10 gpio_cd10 */
+ 0x0F120AAA, /*clks_output_cd10 clks_output_cd10 11:0 */
+ 0x002A100E,
+ 0x0F120000, /*pclk_delay_r */
+
+ 0x002A007A,
+ 0x0F120000,
+
+/*This register is for FACTORY ONLY.
+If you change it without prior notification*/
+/* YOU are RESPONSIBLE for the FAILURE that will happen in the future.*/
+
+ /*ISP FE(ADLC) */
+ 0x002AE406,
+ 0x0F120092,
+ 0x002AE410,
+ 0x0F123804,
+ 0x002AE41A,
+ 0x0F120010, /*101022 ADD adlcptune_total */
+ 0x002AE420,
+ 0x0F120003,
+ 0x0F120060,
+ 0x002AE42E,
+ 0x0F120004,
+ 0x002AF400,
+ 0x0F125A3C,
+ 0x0F120023,
+ 0x0F128080,
+ 0x0F1203AF,
+ 0x0F12000A,
+ 0x0F12AA54,
+ 0x0F120040,
+ 0x0F12464E,
+ 0x0F120240,
+ 0x0F120240,
+ 0x0F120040,
+ 0x0F121000,
+ 0x0F1255FF, /*555C -> 55FF */
+ 0x0F12D000,
+ 0x0F120010,
+ 0x0F120202,
+ 0x0F120401,
+ 0x0F120022,
+ 0x0F120088,
+ 0x0F12009F,
+ 0x0F120000,
+ 0x0F121800,
+ 0x0F120088,
+ 0x0F120000,
+ 0x0F122428,
+ 0x0F120000,
+ 0x0F1203EE,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x002AF552,
+ 0x0F120708,
+ 0x0F12080C,
+
+ 0x00287000, /*For subsampling Size */
+ 0x002A18BC,
+ 0x0F120004,
+ 0x0F1205B6,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120001,
+ 0x0F1205BA,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120007,
+ 0x0F1205BA,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F1201F4,
+ 0x0F12024E,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F1201F4,
+ 0x0F1205B6,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F1201F4,
+ 0x0F1205BA,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F1201F4,
+ 0x0F12024F,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120075,
+ 0x0F1200CF,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120075,
+ 0x0F1200D6,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120004,
+ 0x0F1201F4,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F1200F0,
+ 0x0F1201F4,
+ 0x0F12029E,
+ 0x0F1205B2,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F1201F8,
+ 0x0F120228,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120208,
+ 0x0F120238,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120218,
+ 0x0F120238,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120001,
+ 0x0F120009,
+ 0x0F1200DE,
+ 0x0F1205C0,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F1200DF,
+ 0x0F1200E4,
+ 0x0F1201F8,
+ 0x0F1201FD,
+ 0x0F1205B6,
+ 0x0F1205BB,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F1201F8,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120077,
+ 0x0F12007E,
+ 0x0F12024F,
+ 0x0F12025E,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120004,
+ 0x0F1209D1,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120001,
+ 0x0F1209D5,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120008,
+ 0x0F1209D5,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F1202AA,
+ 0x0F120326,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F1202AA,
+ 0x0F1209D1,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F1202AA,
+ 0x0F1209D5,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F1202AA,
+ 0x0F120327,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120008,
+ 0x0F120084,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120008,
+ 0x0F12008D,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120008,
+ 0x0F1202AA,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F1200AA,
+ 0x0F1202AA,
+ 0x0F1203AD,
+ 0x0F1209CD,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F1202AE,
+ 0x0F1202DE,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F1202BE,
+ 0x0F1202EE,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F1202CE,
+ 0x0F1202EE,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120001,
+ 0x0F120009,
+ 0x0F120095,
+ 0x0F1209DB,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120096,
+ 0x0F12009B,
+ 0x0F1202AE,
+ 0x0F1202B3,
+ 0x0F1209D1,
+ 0x0F1209D6,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F1202AE,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120009,
+ 0x0F120010,
+ 0x0F120327,
+ 0x0F120336,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x002A1AF8,
+ 0x0F125A3C, /*senHal_TuneStr_AngTuneData1_2_D000F400 register */
+ 0x002A1896,
+ 0x0F120002, /*senHal_SamplingType 0002 03EE: PLA*/
+ 0x0F120000, /*senHal_SamplingMode 0 : 2 PLA / 1 : 4PLA*/
+ 0x0F120003, /*senHal_PLAOption [0] VPLA enable [1] H*/
+
+ 0x002A189E,
+ 0x0F120FB0, /*senHal_ExpMinPixels*/
+
+ 0x002A18AC,
+ 0x0F120060, /*senHal_uAddColsBin*/
+ 0x0F120060, /*senHal_uAddColsNoBin*/
+ 0x0F1205C0, /*senHal_uMinColsBin*/
+ 0x0F1205C0, /*senHal_uMinColsNoBin*/
+
+ 0x002A1AEA,
+ 0x0F128080, /*senHal_SubF404Tune*/
+ 0x0F120080, /*senHal_FullF404Tune*/
+ 0x002A1AE0,
+ 0x0F120000, /*senHal_bSenAAC*/
+
+ 0x002A1A72,
+ 0x0F120000, /*senHal_bSRX SRX off*/
+ 0x002A18A2,
+ 0x0F120004, /*senHal_NExpLinesCheckFine extend For*/
+ 0x002A1A6A,
+ 0x0F12009A, /*senHal_usForbiddenRightOfs*/
+ 0x002A385E,
+ 0x0F12024C, /*Mon_Sen_uExpPixelsOfs*/
+
+ 0x002A0EE6,
+ 0x0F120000, /*setot_bUseDigitalHbin*/
+ 0x002A1B2A,
+ 0x0F120300, /*senHal_TuneStr2_usAngTuneGainTh 2 */
+ 0x0F1200D6, /*senHal_TuneStr2_AngTuneF4CA_0_ 2 70001B2*/
+ 0x0F12008D, /*senHal_TuneStr2_AngTuneF4CA_1_ 2 70001B2*/
+ 0x0F1200CF, /*senHal_TuneStr2_AngTuneF4C2_0_ 2 70001B3*/
+ 0x0F120084, /*senHal_TuneStr2_AngTuneF4C2_1_ 2 70001B3*/
+
+ /* OTP setting*/
+ 0x002A0722,
+ 0x0F120100, /*skl_OTP_usWaitTime This register sho*/
+ 0x002A0726,
+ 0x0F120001, /*skl_bUseOTPfunc//OTP on/off function*/
+ 0x002A08D6,
+ 0x0F120001, /*ash_bUseOTPData*/
+ 0x002A146E,
+ 0x0F120000, /*awbb_otp_disable*/
+ 0x002A08DC,
+ 0x0F120000, /*ash_bUseGasAlphaOTP*/
+
+/*====================================================
+// 05.Trap and Patch
+====================================================*/
+/* Start of Patch data*/
+ 0x00287000,
+ 0x002A3AF8,
+ 0x0F12B570, /*70003AF8 */
+ 0x0F124B39, /*70003AFA */
+ 0x0F124939, /*70003AFC */
+ 0x0F12483A, /*70003AFE */
+ 0x0F122200, /*70003B00 */
+ 0x0F12C008, /*70003B02 */
+ 0x0F126001, /*70003B04 */
+ 0x0F124939, /*70003B06 */
+ 0x0F124839, /*70003B08 */
+ 0x0F122401, /*70003B0A */
+ 0x0F12F000, /*70003B0C */
+ 0x0F12FBD4, /*70003B0E */
+ 0x0F124938, /*70003B10 */
+ 0x0F124839, /*70003B12 */
+ 0x0F122502, /*70003B14 */
+ 0x0F120022, /*70003B16 */
+ 0x0F12F000, /*70003B18 */
+ 0x0F12FBCE, /*70003B1A */
+ 0x0F124837, /*70003B1C */
+ 0x0F120261, /*70003B1E */
+ 0x0F128001, /*70003B20 */
+ 0x0F122100, /*70003B22 */
+ 0x0F128041, /*70003B24 */
+ 0x0F124936, /*70003B26 */
+ 0x0F124836, /*70003B28 */
+ 0x0F126041, /*70003B2A */
+ 0x0F124936, /*70003B2C */
+ 0x0F124837, /*70003B2E */
+ 0x0F122403, /*70003B30 */
+ 0x0F12002A, /*70003B32 */
+ 0x0F12F000, /*70003B34 */
+ 0x0F12FBC0, /*70003B36 */
+ 0x0F124832, /*70003B38 */
+ 0x0F124935, /*70003B3A */
+ 0x0F1230C0, /*70003B3C */
+ 0x0F1263C1, /*70003B3E */
+ 0x0F124930, /*70003B40 */
+ 0x0F124834, /*70003B42 */
+ 0x0F123980, /*70003B44 */
+ 0x0F126408, /*70003B46 */
+ 0x0F124833, /*70003B48 */
+ 0x0F124934, /*70003B4A */
+ 0x0F126388, /*70003B4C */
+ 0x0F124934, /*70003B4E */
+ 0x0F124834, /*70003B50 */
+ 0x0F120022, /*70003B52 */
+ 0x0F122504, /*70003B54 */
+ 0x0F12F000, /*70003B56 */
+ 0x0F12FBAF, /*70003B58 */
+ 0x0F124933, /*70003B5A */
+ 0x0F124833, /*70003B5C */
+ 0x0F122405, /*70003B5E */
+ 0x0F12002A, /*70003B60 */
+ 0x0F12F000, /*70003B62 */
+ 0x0F12F881, /*70003B64 */
+ 0x0F12491F, /*70003B66 */
+ 0x0F124830, /*70003B68 */
+ 0x0F120022, /*70003B6A */
+ 0x0F122506, /*70003B6C */
+ 0x0F1239B6, /*70003B6E */
+ 0x0F121D80, /*70003B70 */
+ 0x0F12F000, /*70003B72 */
+ 0x0F12F879, /*70003B74 */
+ 0x0F12482D, /*70003B76 */
+ 0x0F12492D, /*70003B78 */
+ 0x0F122407, /*70003B7A */
+ 0x0F12002A, /*70003B7C */
+ 0x0F12300C, /*70003B7E */
+ 0x0F12F000, /*70003B80 */
+ 0x0F12F872, /*70003B82 */
+ 0x0F124829, /*70003B84 */
+ 0x0F12492B, /*70003B86 */
+ 0x0F120022, /*70003B88 */
+ 0x0F122508, /*70003B8A */
+ 0x0F123010, /*70003B8C */
+ 0x0F12F000, /*70003B8E */
+ 0x0F12F86B, /*70003B90 */
+ 0x0F124929, /*70003B92 */
+ 0x0F124829, /*70003B94 */
+ 0x0F122409, /*70003B96 */
+ 0x0F12002A, /*70003B98 */
+ 0x0F12F000, /*70003B9A */
+ 0x0F12FB8D, /*70003B9C */
+ 0x0F124928, /*70003B9E */
+ 0x0F124828, /*70003BA0 */
+ 0x0F120022, /*70003BA2 */
+ 0x0F12250A, /*70003BA4 */
+ 0x0F12F000, /*70003BA6 */
+ 0x0F12FB87, /*70003BA8 */
+ 0x0F124927, /*70003BAA */
+ 0x0F124827, /*70003BAC */
+ 0x0F12240B, /*70003BAE */
+ 0x0F12002A, /*70003BB0 */
+ 0x0F12F000, /*70003BB2 */
+ 0x0F12FB81, /*70003BB4 */
+ 0x0F124926, /*70003BB6 */
+ 0x0F124826, /*70003BB8 */
+ 0x0F120022, /*70003BBA */
+ 0x0F12250C, /*70003BBC */
+ 0x0F12F000, /*70003BBE */
+ 0x0F12FB7B, /*70003BC0 */
+ 0x0F124925, /*70003BC2 */
+ 0x0F124825, /*70003BC4 */
+ 0x0F12240D, /*70003BC6 */
+ 0x0F12002A, /*70003BC8 */
+ 0x0F12F000, /*70003BCA */
+ 0x0F12FB75, /*70003BCC */
+ 0x0F124924, /*70003BCE */
+ 0x0F124824, /*70003BD0 */
+ 0x0F120022, /*70003BD2 */
+ 0x0F12F000, /*70003BD4 */
+ 0x0F12FB70, /*70003BD6 */
+ 0x0F12BC70, /*70003BD8 */
+ 0x0F12BC08, /*70003BDA */
+ 0x0F124718, /*70003BDC */
+ 0x0F120000, /*70003BDE */
+ 0x0F12018F, /*70003BE0 */
+ 0x0F124EC2, /*70003BE2 */
+ 0x0F12037F, /*70003BE4 */
+ 0x0F120000, /*70003BE6 */
+ 0x0F121F90, /*70003BE8 */
+ 0x0F127000, /*70003BEA */
+ 0x0F123C81, /*70003BEC */
+ 0x0F127000, /*70003BEE */
+ 0x0F12E38B, /*70003BF0 */
+ 0x0F120000, /*70003BF2 */
+ 0x0F123CB9, /*70003BF4 */
+ 0x0F127000, /*70003BF6 */
+ 0x0F12C3B1, /*70003BF8 */
+ 0x0F120000, /*70003BFA */
+ 0x0F124780, /*70003BFC */
+ 0x0F127000, /*70003BFE */
+ 0x0F123D17, /*70003C00 */
+ 0x0F127000, /*70003C02 */
+ 0x0F120080, /*70003C04 */
+ 0x0F127000, /*70003C06 */
+ 0x0F123D53, /*70003C08 */
+ 0x0F127000, /*70003C0A */
+ 0x0F12B49D, /*70003C0C */
+ 0x0F120000, /*70003C0E */
+ 0x0F123DFF, /*70003C10 */
+ 0x0F127000, /*70003C12 */
+ 0x0F123DB3, /*70003C14 */
+ 0x0F127000, /*70003C16 */
+ 0x0F12FFFF, /*70003C18 */
+ 0x0F1200FF, /*70003C1A */
+ 0x0F1217E0, /*70003C1C */
+ 0x0F127000, /*70003C1E */
+ 0x0F123F7B, /*70003C20 */
+ 0x0F127000, /*70003C22 */
+ 0x0F12053D, /*70003C24 */
+ 0x0F120000, /*70003C26 */
+ 0x0F120000, /*70003C28 */
+ 0x0F120A89, /*70003C2A */
+ 0x0F126CD2, /*70003C2C */
+ 0x0F120000, /*70003C2E */
+ 0x0F120000, /*70003C30 */
+ 0x0F120A9A, /*70003C32 */
+ 0x0F120000, /*70003C34 */
+ 0x0F1202D2, /*70003C36 */
+ 0x0F123FC9, /*70003C38 */
+ 0x0F127000, /*70003C3A */
+ 0x0F129E65, /*70003C3C */
+ 0x0F120000, /*70003C3E */
+ 0x0F12403D, /*70003C40 */
+ 0x0F127000, /*70003C42 */
+ 0x0F127C49, /*70003C44 */
+ 0x0F120000, /*70003C46 */
+ 0x0F1240B1, /*70003C48 */
+ 0x0F127000, /*70003C4A */
+ 0x0F127C63, /*70003C4C */
+ 0x0F120000, /*70003C4E */
+ 0x0F1240CD, /*70003C50 */
+ 0x0F127000, /*70003C52 */
+ 0x0F128F01, /*70003C54 */
+ 0x0F120000, /*70003C56 */
+ 0x0F12416F, /*70003C58 */
+ 0x0F127000, /*70003C5A */
+ 0x0F127F3F, /*70003C5C */
+ 0x0F120000, /*70003C5E */
+ 0x0F1241FD, /*70003C60 */
+ 0x0F127000, /*70003C62 */
+ 0x0F1298C5, /*70003C64 */
+ 0x0F120000, /*70003C66 */
+ 0x0F12B570, /*70003C68 */
+ 0x0F12000C, /*70003C6A */
+ 0x0F120015, /*70003C6C */
+ 0x0F120029, /*70003C6E */
+ 0x0F12F000, /*70003C70 */
+ 0x0F12FB2A, /*70003C72 */
+ 0x0F1249F8, /*70003C74 */
+ 0x0F1200A8, /*70003C76 */
+ 0x0F12500C, /*70003C78 */
+ 0x0F12BC70, /*70003C7A */
+ 0x0F12BC08, /*70003C7C */
+ 0x0F124718, /*70003C7E */
+ 0x0F126808, /*70003C80 */
+ 0x0F120400, /*70003C82 */
+ 0x0F120C00, /*70003C84 */
+ 0x0F126849, /*70003C86 */
+ 0x0F120409, /*70003C88 */
+ 0x0F120C09, /*70003C8A */
+ 0x0F124AF3, /*70003C8C */
+ 0x0F128992, /*70003C8E */
+ 0x0F122A00, /*70003C90 */
+ 0x0F12D00D, /*70003C92 */
+ 0x0F122300, /*70003C94 */
+ 0x0F121A89, /*70003C96 */
+ 0x0F12D400, /*70003C98 */
+ 0x0F12000B, /*70003C9A */
+ 0x0F120419, /*70003C9C */
+ 0x0F120C09, /*70003C9E */
+ 0x0F1223FF, /*70003CA0 */
+ 0x0F1233C1, /*70003CA2 */
+ 0x0F121810, /*70003CA4 */
+ 0x0F124298, /*70003CA6 */
+ 0x0F12D800, /*70003CA8 */
+ 0x0F120003, /*70003CAA */
+ 0x0F120418, /*70003CAC */
+ 0x0F120C00, /*70003CAE */
+ 0x0F124AEB, /*70003CB0 */
+ 0x0F128150, /*70003CB2 */
+ 0x0F128191, /*70003CB4 */
+ 0x0F124770, /*70003CB6 */
+ 0x0F12B5F3, /*70003CB8 */
+ 0x0F120004, /*70003CBA */
+ 0x0F12B081, /*70003CBC */
+ 0x0F129802, /*70003CBE */
+ 0x0F126800, /*70003CC0 */
+ 0x0F120600, /*70003CC2 */
+ 0x0F120E00, /*70003CC4 */
+ 0x0F122201, /*70003CC6 */
+ 0x0F120015, /*70003CC8 */
+ 0x0F120021, /*70003CCA */
+ 0x0F123910, /*70003CCC */
+ 0x0F12408A, /*70003CCE */
+ 0x0F1240A5, /*70003CD0 */
+ 0x0F124FE4, /*70003CD2 */
+ 0x0F120016, /*70003CD4 */
+ 0x0F122C10, /*70003CD6 */
+ 0x0F12DA03, /*70003CD8 */
+ 0x0F128839, /*70003CDA */
+ 0x0F1243A9, /*70003CDC */
+ 0x0F128039, /*70003CDE */
+ 0x0F12E002, /*70003CE0 */
+ 0x0F128879, /*70003CE2 */
+ 0x0F1243B1, /*70003CE4 */
+ 0x0F128079, /*70003CE6 */
+ 0x0F12F000, /*70003CE8 */
+ 0x0F12FAF6, /*70003CEA */
+ 0x0F122C10, /*70003CEC */
+ 0x0F12DA03, /*70003CEE */
+ 0x0F128839, /*70003CF0 */
+ 0x0F124329, /*70003CF2 */
+ 0x0F128039, /*70003CF4 */
+ 0x0F12E002, /*70003CF6 */
+ 0x0F128879, /*70003CF8 */
+ 0x0F124331, /*70003CFA */
+ 0x0F128079, /*70003CFC */
+ 0x0F1249DA, /*70003CFE */
+ 0x0F128809, /*70003D00 */
+ 0x0F122900, /*70003D02 */
+ 0x0F12D102, /*70003D04 */
+ 0x0F12F000, /*70003D06 */
+ 0x0F12FAEF, /*70003D08 */
+ 0x0F122000, /*70003D0A */
+ 0x0F129902, /*70003D0C */
+ 0x0F126008, /*70003D0E */
+ 0x0F12BCFE, /*70003D10 */
+ 0x0F12BC08, /*70003D12 */
+ 0x0F124718, /*70003D14 */
+ 0x0F12B538, /*70003D16 */
+ 0x0F129C04, /*70003D18 */
+ 0x0F120015, /*70003D1A */
+ 0x0F12002A, /*70003D1C */
+ 0x0F129400, /*70003D1E */
+ 0x0F12F000, /*70003D20 */
+ 0x0F12FAEA, /*70003D22 */
+ 0x0F124AD1, /*70003D24 */
+ 0x0F128811, /*70003D26 */
+ 0x0F122900, /*70003D28 */
+ 0x0F12D00F, /*70003D2A */
+ 0x0F128820, /*70003D2C */
+ 0x0F124281, /*70003D2E */
+ 0x0F12D20C, /*70003D30 */
+ 0x0F128861, /*70003D32 */
+ 0x0F128853, /*70003D34 */
+ 0x0F124299, /*70003D36 */
+ 0x0F12D200, /*70003D38 */
+ 0x0F121E40, /*70003D3A */
+ 0x0F120400, /*70003D3C */
+ 0x0F120C00, /*70003D3E */
+ 0x0F128020, /*70003D40 */
+ 0x0F128851, /*70003D42 */
+ 0x0F128061, /*70003D44 */
+ 0x0F124368, /*70003D46 */
+ 0x0F121840, /*70003D48 */
+ 0x0F126060, /*70003D4A */
+ 0x0F12BC38, /*70003D4C */
+ 0x0F12BC08, /*70003D4E */
+ 0x0F124718, /*70003D50 */
+ 0x0F12B5F8, /*70003D52 */
+ 0x0F120004, /*70003D54 */
+ 0x0F126808, /*70003D56 */
+ 0x0F120400, /*70003D58 */
+ 0x0F120C00, /*70003D5A */
+ 0x0F122201, /*70003D5C */
+ 0x0F120015, /*70003D5E */
+ 0x0F120021, /*70003D60 */
+ 0x0F123910, /*70003D62 */
+ 0x0F12408A, /*70003D64 */
+ 0x0F1240A5, /*70003D66 */
+ 0x0F124FBE, /*70003D68 */
+ 0x0F120016, /*70003D6A */
+ 0x0F122C10, /*70003D6C */
+ 0x0F12DA03, /*70003D6E */
+ 0x0F128839, /*70003D70 */
+ 0x0F1243A9, /*70003D72 */
+ 0x0F128039, /*70003D74 */
+ 0x0F12E002, /*70003D76 */
+ 0x0F128879, /*70003D78 */
+ 0x0F1243B1, /*70003D7A */
+ 0x0F128079, /*70003D7C */
+ 0x0F12F000, /*70003D7E */
+ 0x0F12FAC3, /*70003D80 */
+ 0x0F122C10, /*70003D82 */
+ 0x0F12DA03, /*70003D84 */
+ 0x0F128838, /*70003D86 */
+ 0x0F124328, /*70003D88 */
+ 0x0F128038, /*70003D8A */
+ 0x0F12E002, /*70003D8C */
+ 0x0F128878, /*70003D8E */
+ 0x0F124330, /*70003D90 */
+ 0x0F128078, /*70003D92 */
+ 0x0F1248B6, /*70003D94 */
+ 0x0F128800, /*70003D96 */
+ 0x0F120400, /*70003D98 */
+ 0x0F12D507, /*70003D9A */
+ 0x0F124BB5, /*70003D9C */
+ 0x0F127819, /*70003D9E */
+ 0x0F124AB5, /*70003DA0 */
+ 0x0F127810, /*70003DA2 */
+ 0x0F127018, /*70003DA4 */
+ 0x0F127011, /*70003DA6 */
+ 0x0F1249B4, /*70003DA8 */
+ 0x0F128188, /*70003DAA */
+ 0x0F12BCF8, /*70003DAC */
+ 0x0F12BC08, /*70003DAE */
+ 0x0F124718, /*70003DB0 */
+ 0x0F12B538, /*70003DB2 */
+ 0x0F1248B2, /*70003DB4 */
+ 0x0F124669, /*70003DB6 */
+ 0x0F12F000, /*70003DB8 */
+ 0x0F12FAAE, /*70003DBA */
+ 0x0F1248B1, /*70003DBC */
+ 0x0F1249B0, /*70003DBE */
+ 0x0F1269C2, /*70003DC0 */
+ 0x0F122400, /*70003DC2 */
+ 0x0F1231A8, /*70003DC4 */
+ 0x0F122A00, /*70003DC6 */
+ 0x0F12D008, /*70003DC8 */
+ 0x0F1261C4, /*70003DCA */
+ 0x0F12684A, /*70003DCC */
+ 0x0F126242, /*70003DCE */
+ 0x0F126282, /*70003DD0 */
+ 0x0F12466B, /*70003DD2 */
+ 0x0F12881A, /*70003DD4 */
+ 0x0F126302, /*70003DD6 */
+ 0x0F12885A, /*70003DD8 */
+ 0x0F126342, /*70003DDA */
+ 0x0F126A02, /*70003DDC */
+ 0x0F122A00, /*70003DDE */
+ 0x0F12D00A, /*70003DE0 */
+ 0x0F126204, /*70003DE2 */
+ 0x0F126849, /*70003DE4 */
+ 0x0F126281, /*70003DE6 */
+ 0x0F12466B, /*70003DE8 */
+ 0x0F128819, /*70003DEA */
+ 0x0F126301, /*70003DEC */
+ 0x0F128859, /*70003DEE */
+ 0x0F126341, /*70003DF0 */
+ 0x0F1249A5, /*70003DF2 */
+ 0x0F1288C9, /*70003DF4 */
+ 0x0F1263C1, /*70003DF6 */
+ 0x0F12F000, /*70003DF8 */
+ 0x0F12FA96, /*70003DFA */
+ 0x0F12E7A6, /*70003DFC */
+ 0x0F12B5F0, /*70003DFE */
+ 0x0F12B08B, /*70003E00 */
+ 0x0F1220FF, /*70003E02 */
+ 0x0F121C40, /*70003E04 */
+ 0x0F1249A1, /*70003E06 */
+ 0x0F1289CC, /*70003E08 */
+ 0x0F124E9E, /*70003E0A */
+ 0x0F126AB1, /*70003E0C */
+ 0x0F124284, /*70003E0E */
+ 0x0F12D101, /*70003E10 */
+ 0x0F12489F, /*70003E12 */
+ 0x0F126081, /*70003E14 */
+ 0x0F126A70, /*70003E16 */
+ 0x0F120200, /*70003E18 */
+ 0x0F12F000, /*70003E1A */
+ 0x0F12FA8D, /*70003E1C */
+ 0x0F120400, /*70003E1E */
+ 0x0F120C00, /*70003E20 */
+ 0x0F124A96, /*70003E22 */
+ 0x0F128A11, /*70003E24 */
+ 0x0F129109, /*70003E26 */
+ 0x0F122101, /*70003E28 */
+ 0x0F120349, /*70003E2A */
+ 0x0F124288, /*70003E2C */
+ 0x0F12D200, /*70003E2E */
+ 0x0F120001, /*70003E30 */
+ 0x0F124A92, /*70003E32 */
+ 0x0F128211, /*70003E34 */
+ 0x0F124D97, /*70003E36 */
+ 0x0F128829, /*70003E38 */
+ 0x0F129108, /*70003E3A */
+ 0x0F124A8B, /*70003E3C */
+ 0x0F122303, /*70003E3E */
+ 0x0F123222, /*70003E40 */
+ 0x0F121F91, /*70003E42 */
+ 0x0F12F000, /*70003E44 */
+ 0x0F12FA7E, /*70003E46 */
+ 0x0F128028, /*70003E48 */
+ 0x0F12488E, /*70003E4A */
+ 0x0F124987, /*70003E4C */
+ 0x0F126BC2, /*70003E4E */
+ 0x0F126AC0, /*70003E50 */
+ 0x0F124282, /*70003E52 */
+ 0x0F12D201, /*70003E54 */
+ 0x0F128CC8, /*70003E56 */
+ 0x0F128028, /*70003E58 */
+ 0x0F1288E8, /*70003E5A */
+ 0x0F129007, /*70003E5C */
+ 0x0F122240, /*70003E5E */
+ 0x0F124310, /*70003E60 */
+ 0x0F1280E8, /*70003E62 */
+ 0x0F122000, /*70003E64 */
+ 0x0F120041, /*70003E66 */
+ 0x0F12194B, /*70003E68 */
+ 0x0F12001E, /*70003E6A */
+ 0x0F123680, /*70003E6C */
+ 0x0F128BB2, /*70003E6E */
+ 0x0F12AF04, /*70003E70 */
+ 0x0F12527A, /*70003E72 */
+ 0x0F124A7D, /*70003E74 */
+ 0x0F12188A, /*70003E76 */
+ 0x0F128897, /*70003E78 */
+ 0x0F1283B7, /*70003E7A */
+ 0x0F1233A0, /*70003E7C */
+ 0x0F12891F, /*70003E7E */
+ 0x0F12AE01, /*70003E80 */
+ 0x0F125277, /*70003E82 */
+ 0x0F128A11, /*70003E84 */
+ 0x0F128119, /*70003E86 */
+ 0x0F121C40, /*70003E88 */
+ 0x0F120400, /*70003E8A */
+ 0x0F120C00, /*70003E8C */
+ 0x0F122806, /*70003E8E */
+ 0x0F12D3E9, /*70003E90 */
+ 0x0F12F000, /*70003E92 */
+ 0x0F12FA5F, /*70003E94 */
+ 0x0F12F000, /*70003E96 */
+ 0x0F12FA65, /*70003E98 */
+ 0x0F124F79, /*70003E9A */
+ 0x0F1237A8, /*70003E9C */
+ 0x0F122800, /*70003E9E */
+ 0x0F12D10A, /*70003EA0 */
+ 0x0F121FE0, /*70003EA2 */
+ 0x0F1238FD, /*70003EA4 */
+ 0x0F12D001, /*70003EA6 */
+ 0x0F121CC0, /*70003EA8 */
+ 0x0F12D105, /*70003EAA */
+ 0x0F124874, /*70003EAC */
+ 0x0F128829, /*70003EAE */
+ 0x0F123818, /*70003EB0 */
+ 0x0F126840, /*70003EB2 */
+ 0x0F124348, /*70003EB4 */
+ 0x0F126078, /*70003EB6 */
+ 0x0F124972, /*70003EB8 */
+ 0x0F126878, /*70003EBA */
+ 0x0F126B89, /*70003EBC */
+ 0x0F124288, /*70003EBE */
+ 0x0F12D300, /*70003EC0 */
+ 0x0F120008, /*70003EC2 */
+ 0x0F126078, /*70003EC4 */
+ 0x0F122000, /*70003EC6 */
+ 0x0F120041, /*70003EC8 */
+ 0x0F12AA04, /*70003ECA */
+ 0x0F125A53, /*70003ECC */
+ 0x0F12194A, /*70003ECE */
+ 0x0F12269C, /*70003ED0 */
+ 0x0F1252B3, /*70003ED2 */
+ 0x0F12AB01, /*70003ED4 */
+ 0x0F125A59, /*70003ED6 */
+ 0x0F1232A0, /*70003ED8 */
+ 0x0F128111, /*70003EDA */
+ 0x0F121C40, /*70003EDC */
+ 0x0F120400, /*70003EDE */
+ 0x0F120C00, /*70003EE0 */
+ 0x0F122806, /*70003EE2 */
+ 0x0F12D3F0, /*70003EE4 */
+ 0x0F124965, /*70003EE6 */
+ 0x0F129809, /*70003EE8 */
+ 0x0F128208, /*70003EEA */
+ 0x0F129808, /*70003EEC */
+ 0x0F128028, /*70003EEE */
+ 0x0F129807, /*70003EF0 */
+ 0x0F1280E8, /*70003EF2 */
+ 0x0F121FE0, /*70003EF4 */
+ 0x0F1238FD, /*70003EF6 */
+ 0x0F12D13B, /*70003EF8 */
+ 0x0F124D64, /*70003EFA */
+ 0x0F1289E8, /*70003EFC */
+ 0x0F121FC1, /*70003EFE */
+ 0x0F1239FF, /*70003F00 */
+ 0x0F12D136, /*70003F02 */
+ 0x0F124C5F, /*70003F04 */
+ 0x0F128AE0, /*70003F06 */
+ 0x0F12F000, /*70003F08 */
+ 0x0F12FA34, /*70003F0A */
+ 0x0F120006, /*70003F0C */
+ 0x0F128B20, /*70003F0E */
+ 0x0F12F000, /*70003F10 */
+ 0x0F12FA38, /*70003F12 */
+ 0x0F129000, /*70003F14 */
+ 0x0F126AA1, /*70003F16 */
+ 0x0F126878, /*70003F18 */
+ 0x0F121809, /*70003F1A */
+ 0x0F120200, /*70003F1C */
+ 0x0F12F000, /*70003F1E */
+ 0x0F12FA0B, /*70003F20 */
+ 0x0F120400, /*70003F22 */
+ 0x0F120C00, /*70003F24 */
+ 0x0F120022, /*70003F26 */
+ 0x0F123246, /*70003F28 */
+ 0x0F120011, /*70003F2A */
+ 0x0F12310A, /*70003F2C */
+ 0x0F122305, /*70003F2E */
+ 0x0F12F000, /*70003F30 */
+ 0x0F12FA08, /*70003F32 */
+ 0x0F1266E8, /*70003F34 */
+ 0x0F126B23, /*70003F36 */
+ 0x0F120002, /*70003F38 */
+ 0x0F120031, /*70003F3A */
+ 0x0F120018, /*70003F3C */
+ 0x0F12F000, /*70003F3E */
+ 0x0F12FA29, /*70003F40 */
+ 0x0F12466B, /*70003F42 */
+ 0x0F128518, /*70003F44 */
+ 0x0F126EEA, /*70003F46 */
+ 0x0F126B60, /*70003F48 */
+ 0x0F129900, /*70003F4A */
+ 0x0F12F000, /*70003F4C */
+ 0x0F12FA22, /*70003F4E */
+ 0x0F12466B, /*70003F50 */
+ 0x0F128558, /*70003F52 */
+ 0x0F120029, /*70003F54 */
+ 0x0F12980A, /*70003F56 */
+ 0x0F123170, /*70003F58 */
+ 0x0F12F000, /*70003F5A */
+ 0x0F12FA23, /*70003F5C */
+ 0x0F120028, /*70003F5E */
+ 0x0F123060, /*70003F60 */
+ 0x0F128A02, /*70003F62 */
+ 0x0F124946, /*70003F64 */
+ 0x0F123128, /*70003F66 */
+ 0x0F12808A, /*70003F68 */
+ 0x0F128A42, /*70003F6A */
+ 0x0F1280CA, /*70003F6C */
+ 0x0F128A80, /*70003F6E */
+ 0x0F128108, /*70003F70 */
+ 0x0F12B00B, /*70003F72 */
+ 0x0F12BCF0, /*70003F74 */
+ 0x0F12BC08, /*70003F76 */
+ 0x0F124718, /*70003F78 */
+ 0x0F12B570, /*70003F7A */
+ 0x0F122400, /*70003F7C */
+ 0x0F124D46, /*70003F7E */
+ 0x0F124846, /*70003F80 */
+ 0x0F128881, /*70003F82 */
+ 0x0F124846, /*70003F84 */
+ 0x0F128041, /*70003F86 */
+ 0x0F122101, /*70003F88 */
+ 0x0F128001, /*70003F8A */
+ 0x0F12F000, /*70003F8C */
+ 0x0F12FA12, /*70003F8E */
+ 0x0F124842, /*70003F90 */
+ 0x0F123820, /*70003F92 */
+ 0x0F128BC0, /*70003F94 */
+ 0x0F12F000, /*70003F96 */
+ 0x0F12FA15, /*70003F98 */
+ 0x0F124B42, /*70003F9A */
+ 0x0F12220D, /*70003F9C */
+ 0x0F120712, /*70003F9E */
+ 0x0F1218A8, /*70003FA0 */
+ 0x0F128806, /*70003FA2 */
+ 0x0F1200E1, /*70003FA4 */
+ 0x0F1218C9, /*70003FA6 */
+ 0x0F1281CE, /*70003FA8 */
+ 0x0F128846, /*70003FAA */
+ 0x0F12818E, /*70003FAC */
+ 0x0F128886, /*70003FAE */
+ 0x0F12824E, /*70003FB0 */
+ 0x0F1288C0, /*70003FB2 */
+ 0x0F128208, /*70003FB4 */
+ 0x0F123508, /*70003FB6 */
+ 0x0F12042D, /*70003FB8 */
+ 0x0F120C2D, /*70003FBA */
+ 0x0F121C64, /*70003FBC */
+ 0x0F120424, /*70003FBE */
+ 0x0F120C24, /*70003FC0 */
+ 0x0F122C07, /*70003FC2 */
+ 0x0F12D3EC, /*70003FC4 */
+ 0x0F12E658, /*70003FC6 */
+ 0x0F12B510, /*70003FC8 */
+ 0x0F124834, /*70003FCA */
+ 0x0F124C34, /*70003FCC */
+ 0x0F1288C0, /*70003FCE */
+ 0x0F128060, /*70003FD0 */
+ 0x0F122001, /*70003FD2 */
+ 0x0F128020, /*70003FD4 */
+ 0x0F124831, /*70003FD6 */
+ 0x0F123820, /*70003FD8 */
+ 0x0F128BC0, /*70003FDA */
+ 0x0F12F000, /*70003FDC */
+ 0x0F12F9F2, /*70003FDE */
+ 0x0F1288E0, /*70003FE0 */
+ 0x0F124A31, /*70003FE2 */
+ 0x0F122800, /*70003FE4 */
+ 0x0F12D003, /*70003FE6 */
+ 0x0F124930, /*70003FE8 */
+ 0x0F128849, /*70003FEA */
+ 0x0F122900, /*70003FEC */
+ 0x0F12D009, /*70003FEE */
+ 0x0F122001, /*70003FF0 */
+ 0x0F1203C0, /*70003FF2 */
+ 0x0F128050, /*70003FF4 */
+ 0x0F1280D0, /*70003FF6 */
+ 0x0F122000, /*70003FF8 */
+ 0x0F128090, /*70003FFA */
+ 0x0F128110, /*70003FFC */
+ 0x0F12BC10, /*70003FFE */
+ 0x0F12BC08, /*70004000 */
+ 0x0F124718, /*70004002 */
+ 0x0F128050, /*70004004 */
+ 0x0F128920, /*70004006 */
+ 0x0F1280D0, /*70004008 */
+ 0x0F128960, /*7000400A */
+ 0x0F120400, /*7000400C */
+ 0x0F121400, /*7000400E */
+ 0x0F128090, /*70004010 */
+ 0x0F1289A1, /*70004012 */
+ 0x0F120409, /*70004014 */
+ 0x0F121409, /*70004016 */
+ 0x0F128111, /*70004018 */
+ 0x0F1289E3, /*7000401A */
+ 0x0F128A24, /*7000401C */
+ 0x0F122B00, /*7000401E */
+ 0x0F12D104, /*70004020 */
+ 0x0F1217C3, /*70004022 */
+ 0x0F120F5B, /*70004024 */
+ 0x0F121818, /*70004026 */
+ 0x0F1210C0, /*70004028 */
+ 0x0F128090, /*7000402A */
+ 0x0F122C00, /*7000402C */
+ 0x0F12D1E6, /*7000402E */
+ 0x0F1217C8, /*70004030 */
+ 0x0F120F40, /*70004032 */
+ 0x0F121840, /*70004034 */
+ 0x0F1210C0, /*70004036 */
+ 0x0F128110, /*70004038 */
+ 0x0F12E7E0, /*7000403A */
+ 0x0F12B510, /*7000403C */
+ 0x0F12000C, /*7000403E */
+ 0x0F124919, /*70004040 */
+ 0x0F122204, /*70004042 */
+ 0x0F126820, /*70004044 */
+ 0x0F125E8A, /*70004046 */
+ 0x0F120140, /*70004048 */
+ 0x0F121A80, /*7000404A */
+ 0x0F120280, /*7000404C */
+ 0x0F128849, /*7000404E */
+ 0x0F12F000, /*70004050 */
+ 0x0F12F9C0, /*70004052 */
+ 0x0F126020, /*70004054 */
+ 0x0F12E7D2, /*70004056 */
+ 0x0F1238D4, /*70004058 */
+ 0x0F127000, /*7000405A */
+ 0x0F1217D0, /*7000405C */
+ 0x0F127000, /*7000405E */
+ 0x0F125000, /*70004060 */
+ 0x0F12D000, /*70004062 */
+ 0x0F121100, /*70004064 */
+ 0x0F12D000, /*70004066 */
+ 0x0F12171A, /*70004068 */
+ 0x0F127000, /*7000406A */
+ 0x0F124780, /*7000406C */
+ 0x0F127000, /*7000406E */
+ 0x0F122FCA, /*70004070 */
+ 0x0F127000, /*70004072 */
+ 0x0F122FC5, /*70004074 */
+ 0x0F127000, /*70004076 */
+ 0x0F122FC6, /*70004078 */
+ 0x0F127000, /*7000407A */
+ 0x0F122ED8, /*7000407C */
+ 0x0F127000, /*7000407E */
+ 0x0F122BD0, /*70004080 */
+ 0x0F127000, /*70004082 */
+ 0x0F1217E0, /*70004084 */
+ 0x0F127000, /*70004086 */
+ 0x0F122DE8, /*70004088 */
+ 0x0F127000, /*7000408A */
+ 0x0F1237E0, /*7000408C */
+ 0x0F127000, /*7000408E */
+ 0x0F12210C, /*70004090 */
+ 0x0F127000, /*70004092 */
+ 0x0F121484, /*70004094 */
+ 0x0F127000, /*70004096 */
+ 0x0F12A006, /*70004098 */
+ 0x0F120000, /*7000409A */
+ 0x0F120724, /*7000409C */
+ 0x0F127000, /*7000409E */
+ 0x0F12A000, /*700040A0 */
+ 0x0F12D000, /*700040A2 */
+ 0x0F122270, /*700040A4 */
+ 0x0F127000, /*700040A6 */
+ 0x0F122558, /*700040A8 */
+ 0x0F127000, /*700040AA */
+ 0x0F12146C, /*700040AC */
+ 0x0F127000, /*700040AE */
+ 0x0F12B510, /*700040B0 */
+ 0x0F12000C, /*700040B2 */
+ 0x0F124979, /*700040B4 */
+ 0x0F122208, /*700040B6 */
+ 0x0F126820, /*700040B8 */
+ 0x0F125E8A, /*700040BA */
+ 0x0F120140, /*700040BC */
+ 0x0F121A80, /*700040BE */
+ 0x0F120280, /*700040C0 */
+ 0x0F1288C9, /*700040C2 */
+ 0x0F12F000, /*700040C4 */
+ 0x0F12F986, /*700040C6 */
+ 0x0F126020, /*700040C8 */
+ 0x0F12E798, /*700040CA */
+ 0x0F12B5FE, /*700040CC */
+ 0x0F12000C, /*700040CE */
+ 0x0F126825, /*700040D0 */
+ 0x0F126866, /*700040D2 */
+ 0x0F1268A0, /*700040D4 */
+ 0x0F129001, /*700040D6 */
+ 0x0F1268E7, /*700040D8 */
+ 0x0F121BA8, /*700040DA */
+ 0x0F1242B5, /*700040DC */
+ 0x0F12DA00, /*700040DE */
+ 0x0F121B70, /*700040E0 */
+ 0x0F129000, /*700040E2 */
+ 0x0F12496D, /*700040E4 */
+ 0x0F12486E, /*700040E6 */
+ 0x0F12884A, /*700040E8 */
+ 0x0F128843, /*700040EA */
+ 0x0F12435A, /*700040EC */
+ 0x0F122304, /*700040EE */
+ 0x0F125ECB, /*700040F0 */
+ 0x0F120A92, /*700040F2 */
+ 0x0F1218D2, /*700040F4 */
+ 0x0F1202D2, /*700040F6 */
+ 0x0F120C12, /*700040F8 */
+ 0x0F1288CB, /*700040FA */
+ 0x0F128880, /*700040FC */
+ 0x0F124343, /*700040FE */
+ 0x0F120A98, /*70004100 */
+ 0x0F122308, /*70004102 */
+ 0x0F125ECB, /*70004104 */
+ 0x0F1218C0, /*70004106 */
+ 0x0F1202C0, /*70004108 */
+ 0x0F120C00, /*7000410A */
+ 0x0F120411, /*7000410C */
+ 0x0F120400, /*7000410E */
+ 0x0F121409, /*70004110 */
+ 0x0F121400, /*70004112 */
+ 0x0F121A08, /*70004114 */
+ 0x0F124962, /*70004116 */
+ 0x0F1239E0, /*70004118 */
+ 0x0F126148, /*7000411A */
+ 0x0F129801, /*7000411C */
+ 0x0F123040, /*7000411E */
+ 0x0F127880, /*70004120 */
+ 0x0F122800, /*70004122 */
+ 0x0F12D103, /*70004124 */
+ 0x0F129801, /*70004126 */
+ 0x0F120029, /*70004128 */
+ 0x0F12F000, /*7000412A */
+ 0x0F12F959, /*7000412C */
+ 0x0F128839, /*7000412E */
+ 0x0F129800, /*70004130 */
+ 0x0F124281, /*70004132 */
+ 0x0F12D814, /*70004134 */
+ 0x0F128879, /*70004136 */
+ 0x0F129800, /*70004138 */
+ 0x0F124281, /*7000413A */
+ 0x0F12D20C, /*7000413C */
+ 0x0F129801, /*7000413E */
+ 0x0F120029, /*70004140 */
+ 0x0F12F000, /*70004142 */
+ 0x0F12F955, /*70004144 */
+ 0x0F129801, /*70004146 */
+ 0x0F120029, /*70004148 */
+ 0x0F12F000, /*7000414A */
+ 0x0F12F951, /*7000414C */
+ 0x0F129801, /*7000414E */
+ 0x0F120029, /*70004150 */
+ 0x0F12F000, /*70004152 */
+ 0x0F12F94D, /*70004154 */
+ 0x0F12E003, /*70004156 */
+ 0x0F129801, /*70004158 */
+ 0x0F120029, /*7000415A */
+ 0x0F12F000, /*7000415C */
+ 0x0F12F948, /*7000415E */
+ 0x0F129801, /*70004160 */
+ 0x0F120032, /*70004162 */
+ 0x0F120039, /*70004164 */
+ 0x0F12F000, /*70004166 */
+ 0x0F12F94B, /*70004168 */
+ 0x0F126020, /*7000416A */
+ 0x0F12E5D0, /*7000416C */
+ 0x0F12B57C, /*7000416E */
+ 0x0F12484C, /*70004170 */
+ 0x0F12A901, /*70004172 */
+ 0x0F120004, /*70004174 */
+ 0x0F12F000, /*70004176 */
+ 0x0F12F8CF, /*70004178 */
+ 0x0F12466B, /*7000417A */
+ 0x0F1288D9, /*7000417C */
+ 0x0F128898, /*7000417E */
+ 0x0F124B47, /*70004180 */
+ 0x0F123346, /*70004182 */
+ 0x0F121E9A, /*70004184 */
+ 0x0F12F000, /*70004186 */
+ 0x0F12F943, /*70004188 */
+ 0x0F124846, /*7000418A */
+ 0x0F124944, /*7000418C */
+ 0x0F123812, /*7000418E */
+ 0x0F123140, /*70004190 */
+ 0x0F128A42, /*70004192 */
+ 0x0F12888B, /*70004194 */
+ 0x0F1218D2, /*70004196 */
+ 0x0F128242, /*70004198 */
+ 0x0F128AC2, /*7000419A */
+ 0x0F1288C9, /*7000419C */
+ 0x0F121851, /*7000419E */
+ 0x0F1282C1, /*700041A0 */
+ 0x0F120020, /*700041A2 */
+ 0x0F124669, /*700041A4 */
+ 0x0F12F000, /*700041A6 */
+ 0x0F12F8B7, /*700041A8 */
+ 0x0F12483F, /*700041AA */
+ 0x0F12214D, /*700041AC */
+ 0x0F128301, /*700041AE */
+ 0x0F122196, /*700041B0 */
+ 0x0F128381, /*700041B2 */
+ 0x0F12211D, /*700041B4 */
+ 0x0F123020, /*700041B6 */
+ 0x0F128001, /*700041B8 */
+ 0x0F12F000, /*700041BA */
+ 0x0F12F931, /*700041BC */
+ 0x0F12F000, /*700041BE */
+ 0x0F12F937, /*700041C0 */
+ 0x0F12483A, /*700041C2 */
+ 0x0F124C3A, /*700041C4 */
+ 0x0F126E00, /*700041C6 */
+ 0x0F1260E0, /*700041C8 */
+ 0x0F12466B, /*700041CA */
+ 0x0F128818, /*700041CC */
+ 0x0F128859, /*700041CE */
+ 0x0F120025, /*700041D0 */
+ 0x0F121A40, /*700041D2 */
+ 0x0F123540, /*700041D4 */
+ 0x0F1261A8, /*700041D6 */
+ 0x0F124831, /*700041D8 */
+ 0x0F129900, /*700041DA */
+ 0x0F123060, /*700041DC */
+ 0x0F12F000, /*700041DE */
+ 0x0F12F92F, /*700041E0 */
+ 0x0F12466B, /*700041E2 */
+ 0x0F128819, /*700041E4 */
+ 0x0F121DE0, /*700041E6 */
+ 0x0F1230F9, /*700041E8 */
+ 0x0F128741, /*700041EA */
+ 0x0F128859, /*700041EC */
+ 0x0F128781, /*700041EE */
+ 0x0F122000, /*700041F0 */
+ 0x0F1271A0, /*700041F2 */
+ 0x0F1274A8, /*700041F4 */
+ 0x0F12BC7C, /*700041F6 */
+ 0x0F12BC08, /*700041F8 */
+ 0x0F124718, /*700041FA */
+ 0x0F12B5F8, /*700041FC */
+ 0x0F120005, /*700041FE */
+ 0x0F126808, /*70004200 */
+ 0x0F120400, /*70004202 */
+ 0x0F120C00, /*70004204 */
+ 0x0F12684A, /*70004206 */
+ 0x0F120412, /*70004208 */
+ 0x0F120C12, /*7000420A */
+ 0x0F12688E, /*7000420C */
+ 0x0F1268CC, /*7000420E */
+ 0x0F124922, /*70004210 */
+ 0x0F12884B, /*70004212 */
+ 0x0F124343, /*70004214 */
+ 0x0F120A98, /*70004216 */
+ 0x0F122304, /*70004218 */
+ 0x0F125ECB, /*7000421A */
+ 0x0F1218C0, /*7000421C */
+ 0x0F1202C0, /*7000421E */
+ 0x0F120C00, /*70004220 */
+ 0x0F1288CB, /*70004222 */
+ 0x0F124353, /*70004224 */
+ 0x0F120A9A, /*70004226 */
+ 0x0F122308, /*70004228 */
+ 0x0F125ECB, /*7000422A */
+ 0x0F1218D1, /*7000422C */
+ 0x0F1202C9, /*7000422E */
+ 0x0F120C09, /*70004230 */
+ 0x0F122701, /*70004232 */
+ 0x0F12003A, /*70004234 */
+ 0x0F1240AA, /*70004236 */
+ 0x0F129200, /*70004238 */
+ 0x0F12002A, /*7000423A */
+ 0x0F123A10, /*7000423C */
+ 0x0F124097, /*7000423E */
+ 0x0F122D10, /*70004240 */
+ 0x0F12DA06, /*70004242 */
+ 0x0F124A1B, /*70004244 */
+ 0x0F129B00, /*70004246 */
+ 0x0F128812, /*70004248 */
+ 0x0F12439A, /*7000424A */
+ 0x0F124B19, /*7000424C */
+ 0x0F12801A, /*7000424E */
+ 0x0F12E003, /*70004250 */
+ 0x0F124B18, /*70004252 */
+ 0x0F12885A, /*70004254 */
+ 0x0F1243BA, /*70004256 */
+ 0x0F12805A, /*70004258 */
+ 0x0F120023, /*7000425A */
+ 0x0F120032, /*7000425C */
+ 0x0F12F000, /*7000425E */
+ 0x0F12F8D7, /*70004260 */
+ 0x0F122D10, /*70004262 */
+ 0x0F12DA05, /*70004264 */
+ 0x0F124913, /*70004266 */
+ 0x0F129A00, /*70004268 */
+ 0x0F128808, /*7000426A */
+ 0x0F124310, /*7000426C */
+ 0x0F128008, /*7000426E */
+ 0x0F12E003, /*70004270 */
+ 0x0F124810, /*70004272 */
+ 0x0F128841, /*70004274 */
+ 0x0F124339, /*70004276 */
+ 0x0F128041, /*70004278 */
+ 0x0F124D0D, /*7000427A */
+ 0x0F122000, /*7000427C */
+ 0x0F123580, /*7000427E */
+ 0x0F1288AA, /*70004280 */
+ 0x0F125E30, /*70004282 */
+ 0x0F122100, /*70004284 */
+ 0x0F12F000, /*70004286 */
+ 0x0F12F8E3, /*70004288 */
+ 0x0F128030, /*7000428A */
+ 0x0F122000, /*7000428C */
+ 0x0F1288AA, /*7000428E */
+ 0x0F125E20, /*70004290 */
+ 0x0F122100, /*70004292 */
+ 0x0F12F000, /*70004294 */
+ 0x0F12F8DC, /*70004296 */
+ 0x0F128020, /*70004298 */
+ 0x0F12E587, /*7000429A */
+ 0x0F122558, /*7000429C */
+ 0x0F127000, /*7000429E */
+ 0x0F122AB8, /*700042A0 */
+ 0x0F127000, /*700042A2 */
+ 0x0F12145E, /*700042A4 */
+ 0x0F127000, /*700042A6 */
+ 0x0F122698, /*700042A8 */
+ 0x0F127000, /*700042AA */
+ 0x0F122BB8, /*700042AC */
+ 0x0F127000, /*700042AE */
+ 0x0F122998, /*700042B0 */
+ 0x0F127000, /*700042B2 */
+ 0x0F121100, /*700042B4 */
+ 0x0F12D000, /*700042B6 */
+ 0x0F124778, /*700042B8 */
+ 0x0F1246C0, /*700042BA */
+ 0x0F12C000, /*700042BC */
+ 0x0F12E59F, /*700042BE */
+ 0x0F12FF1C, /*700042C0 */
+ 0x0F12E12F, /*700042C2 */
+ 0x0F121789, /*700042C4 */
+ 0x0F120001, /*700042C6 */
+ 0x0F124778, /*700042C8 */
+ 0x0F1246C0, /*700042CA */
+ 0x0F12C000, /*700042CC */
+ 0x0F12E59F, /*700042CE */
+ 0x0F12FF1C, /*700042D0 */
+ 0x0F12E12F, /*700042D2 */
+ 0x0F1216F1, /*700042D4 */
+ 0x0F120001, /*700042D6 */
+ 0x0F124778, /*700042D8 */
+ 0x0F1246C0, /*700042DA */
+ 0x0F12C000, /*700042DC */
+ 0x0F12E59F, /*700042DE */
+ 0x0F12FF1C, /*700042E0 */
+ 0x0F12E12F, /*700042E2 */
+ 0x0F12C3B1, /*700042E4 */
+ 0x0F120000, /*700042E6 */
+ 0x0F124778, /*700042E8 */
+ 0x0F1246C0, /*700042EA */
+ 0x0F12C000, /*700042EC */
+ 0x0F12E59F, /*700042EE */
+ 0x0F12FF1C, /*700042F0 */
+ 0x0F12E12F, /*700042F2 */
+ 0x0F12C36D, /*700042F4 */
+ 0x0F120000, /*700042F6 */
+ 0x0F124778, /*700042F8 */
+ 0x0F1246C0, /*700042FA */
+ 0x0F12C000, /*700042FC */
+ 0x0F12E59F, /*700042FE */
+ 0x0F12FF1C, /*70004300 */
+ 0x0F12E12F, /*70004302 */
+ 0x0F12F6D7, /*70004304 */
+ 0x0F120000, /*70004306 */
+ 0x0F124778, /*70004308 */
+ 0x0F1246C0, /*7000430A */
+ 0x0F12C000, /*7000430C */
+ 0x0F12E59F, /*7000430E */
+ 0x0F12FF1C, /*70004310 */
+ 0x0F12E12F, /*70004312 */
+ 0x0F12B49D, /*70004314 */
+ 0x0F120000, /*70004316 */
+ 0x0F124778, /*70004318 */
+ 0x0F1246C0, /*7000431A */
+ 0x0F12C000, /*7000431C */
+ 0x0F12E59F, /*7000431E */
+ 0x0F12FF1C, /*70004320 */
+ 0x0F12E12F, /*70004322 */
+ 0x0F127EDF, /*70004324 */
+ 0x0F120000, /*70004326 */
+ 0x0F124778, /*70004328 */
+ 0x0F1246C0, /*7000432A */
+ 0x0F12C000, /*7000432C */
+ 0x0F12E59F, /*7000432E */
+ 0x0F12FF1C, /*70004330 */
+ 0x0F12E12F, /*70004332 */
+ 0x0F12448D, /*70004334 */
+ 0x0F120000, /*70004336 */
+ 0x0F124778, /*70004338 */
+ 0x0F1246C0, /*7000433A */
+ 0x0F12F004, /*7000433C */
+ 0x0F12E51F, /*7000433E */
+ 0x0F1229EC, /*70004340 */
+ 0x0F120001, /*70004342 */
+ 0x0F124778, /*70004344 */
+ 0x0F1246C0, /*70004346 */
+ 0x0F12C000, /*70004348 */
+ 0x0F12E59F, /*7000434A */
+ 0x0F12FF1C, /*7000434C */
+ 0x0F12E12F, /*7000434E */
+ 0x0F122EF1, /*70004350 */
+ 0x0F120000, /*70004352 */
+ 0x0F124778, /*70004354 */
+ 0x0F1246C0, /*70004356 */
+ 0x0F12C000, /*70004358 */
+ 0x0F12E59F, /*7000435A */
+ 0x0F12FF1C, /*7000435C */
+ 0x0F12E12F, /*7000435E */
+ 0x0F12EE03, /*70004360 */
+ 0x0F120000, /*70004362 */
+ 0x0F124778, /*70004364 */
+ 0x0F1246C0, /*70004366 */
+ 0x0F12C000, /*70004368 */
+ 0x0F12E59F, /*7000436A */
+ 0x0F12FF1C, /*7000436C */
+ 0x0F12E12F, /*7000436E */
+ 0x0F12A58B, /*70004370 */
+ 0x0F120000, /*70004372 */
+ 0x0F124778, /*70004374 */
+ 0x0F1246C0, /*70004376 */
+ 0x0F12C000, /*70004378 */
+ 0x0F12E59F, /*7000437A */
+ 0x0F12FF1C, /*7000437C */
+ 0x0F12E12F, /*7000437E */
+ 0x0F127C49, /*70004380 */
+ 0x0F120000, /*70004382 */
+ 0x0F124778, /*70004384 */
+ 0x0F1246C0, /*70004386 */
+ 0x0F12C000, /*70004388 */
+ 0x0F12E59F, /*7000438A */
+ 0x0F12FF1C, /*7000438C */
+ 0x0F12E12F, /*7000438E */
+ 0x0F127C63, /*70004390 */
+ 0x0F120000, /*70004392 */
+ 0x0F124778, /*70004394 */
+ 0x0F1246C0, /*70004396 */
+ 0x0F12C000, /*70004398 */
+ 0x0F12E59F, /*7000439A */
+ 0x0F12FF1C, /*7000439C */
+ 0x0F12E12F, /*7000439E */
+ 0x0F122DB7, /*700043A0 */
+ 0x0F120000, /*700043A2 */
+ 0x0F124778, /*700043A4 */
+ 0x0F1246C0, /*700043A6 */
+ 0x0F12C000, /*700043A8 */
+ 0x0F12E59F, /*700043AA */
+ 0x0F12FF1C, /*700043AC */
+ 0x0F12E12F, /*700043AE */
+ 0x0F12EB3D, /*700043B0 */
+ 0x0F120000, /*700043B2 */
+ 0x0F124778, /*700043B4 */
+ 0x0F1246C0, /*700043B6 */
+ 0x0F12C000, /*700043B8 */
+ 0x0F12E59F, /*700043BA */
+ 0x0F12FF1C, /*700043BC */
+ 0x0F12E12F, /*700043BE */
+ 0x0F12F061, /*700043C0 */
+ 0x0F120000, /*700043C2 */
+ 0x0F124778, /*700043C4 */
+ 0x0F1246C0, /*700043C6 */
+ 0x0F12C000, /*700043C8 */
+ 0x0F12E59F, /*700043CA */
+ 0x0F12FF1C, /*700043CC */
+ 0x0F12E12F, /*700043CE */
+ 0x0F12F0EF, /*700043D0 */
+ 0x0F120000, /*700043D2 */
+ 0x0F124778, /*700043D4 */
+ 0x0F1246C0, /*700043D6 */
+ 0x0F12F004, /*700043D8 */
+ 0x0F12E51F, /*700043DA */
+ 0x0F122824, /*700043DC */
+ 0x0F120001, /*700043DE */
+ 0x0F124778, /*700043E0 */
+ 0x0F1246C0, /*700043E2 */
+ 0x0F12C000, /*700043E4 */
+ 0x0F12E59F, /*700043E6 */
+ 0x0F12FF1C, /*700043E8 */
+ 0x0F12E12F, /*700043EA */
+ 0x0F128EDD, /*700043EC */
+ 0x0F120000, /*700043EE */
+ 0x0F124778, /*700043F0 */
+ 0x0F1246C0, /*700043F2 */
+ 0x0F12C000, /*700043F4 */
+ 0x0F12E59F, /*700043F6 */
+ 0x0F12FF1C, /*700043F8 */
+ 0x0F12E12F, /*700043FA */
+ 0x0F128DCB, /*700043FC */
+ 0x0F120000, /*700043FE */
+ 0x0F124778, /*70004400 */
+ 0x0F1246C0, /*70004402 */
+ 0x0F12C000, /*70004404 */
+ 0x0F12E59F, /*70004406 */
+ 0x0F12FF1C, /*70004408 */
+ 0x0F12E12F, /*7000440A */
+ 0x0F128E17, /*7000440C */
+ 0x0F120000, /*7000440E */
+ 0x0F124778, /*70004410 */
+ 0x0F1246C0, /*70004412 */
+ 0x0F12C000, /*70004414 */
+ 0x0F12E59F, /*70004416 */
+ 0x0F12FF1C, /*70004418 */
+ 0x0F12E12F, /*7000441A */
+ 0x0F1298C5, /*7000441C */
+ 0x0F120000, /*7000441E */
+ 0x0F124778, /*70004420 */
+ 0x0F1246C0, /*70004422 */
+ 0x0F12C000, /*70004424 */
+ 0x0F12E59F, /*70004426 */
+ 0x0F12FF1C, /*70004428 */
+ 0x0F12E12F, /*7000442A */
+ 0x0F127C7D, /*7000442C */
+ 0x0F120000, /*7000442E */
+ 0x0F124778, /*70004430 */
+ 0x0F1246C0, /*70004432 */
+ 0x0F12C000, /*70004434 */
+ 0x0F12E59F, /*70004436 */
+ 0x0F12FF1C, /*70004438 */
+ 0x0F12E12F, /*7000443A */
+ 0x0F127E31, /*7000443C */
+ 0x0F120000, /*7000443E */
+ 0x0F124778, /*70004440 */
+ 0x0F1246C0, /*70004442 */
+ 0x0F12C000, /*70004444 */
+ 0x0F12E59F, /*70004446 */
+ 0x0F12FF1C, /*70004448 */
+ 0x0F12E12F, /*7000444A */
+ 0x0F127EAB, /*7000444C */
+ 0x0F120000, /*7000444E */
+ 0x0F124778, /*70004450 */
+ 0x0F1246C0, /*70004452 */
+ 0x0F12C000, /*70004454 */
+ 0x0F12E59F, /*70004456 */
+ 0x0F12FF1C, /*70004458 */
+ 0x0F12E12F, /*7000445A */
+ 0x0F127501, /*7000445C */
+ 0x0F120000, /*7000445E */
+/* End of Patch Data(Last : 7000445Eh)
+// Total Size 2408 (0x0968)
+// Addr : 3AF8 , Size : 2406(966h)
+
+//TNP_USER_MBCV_CONTROL
+//TNP_4EC_MBR_TUNE
+//TNP_4EC_FORBIDDEN_TUNE
+//TNP_AF_FINESEARCH_DRIVEBACK
+//TNP_FLASH_ALG
+//TNP_GAS_ALPHA_OTP
+//TNP_AWB_MODUL_COMP
+//TNP_AWB_INIT_QUEUE
+//TNP_AWB_GRID_LOWBR
+//TNP_AWB_GRID_MODULECOMP*/
+
+ 0x0028D000,
+ 0x002A1000,
+ 0x0F120001,
+ /* End of FACTORY ONLY. */
+
+ /*AF setting */
+ 0x00287000,
+ 0x002A01FC,
+ 0x0F120001, /*REG_TC_IPRM_LedGpio */
+ /*70001720 0100 Only STW Use IT */
+ 0x002A01FE,
+ 0x0F120003,
+ 0x0F120000,
+ 0x002A0204,
+ 0x0F120061,
+ 0x002A020C,
+ 0x0F122F0C,
+ 0x0F120190,
+ 0x002A0294,
+ 0x0F120100,
+ 0x0F1200E3,
+ 0x0F120200,
+ 0x0F120238,
+ 0x0F1201C6,
+ 0x0F120166,
+ 0x0F120074,
+ 0x0F120132,
+ 0x0F120001,
+
+ 0x002A070E,
+ 0x0F1200FF,
+ 0x002A071E,
+ 0x0F120001,
+ 0x002A163C,
+ 0x0F120000,
+
+ 0x002A1648,
+ 0x0F129002, /*2nd search on when 2nd search lens opsite direct moving*/
+ 0x002A1652,
+ 0x0F120002,
+ 0x0F120000,
+ 0x002A15E0,
+ 0x0F120801, /* when 2nd search 1code distance 6+1 position move */
+
+ 0x002A164C,
+ 0x0F120003,
+ 0x002A163E,
+ 0x0F1200E5,
+ 0x0F1200CC, /*98(60%) -> CC(80%) */
+ 0x002A15D4,
+ 0x0F120000,
+ 0x0F12D000,
+ 0x002A169A,
+ 0x0F12FF95,
+ 0x002A166A,
+ 0x0F120280,
+ 0x002A1676,
+ 0x0F1203A0,
+ 0x0F120320,
+ 0x002A16BC,
+ 0x0F120030,
+ 0x002A16E0,
+ 0x0F120060,
+ 0x002A16D4,
+ 0x0F120010,
+ 0x002A1656,
+ 0x0F120000,
+ 0x002A15E6,
+ 0x0F12003C,
+
+ 0x0F120017, /*af_pos_usTableLastInd */
+ 0x0F120026,
+ 0x0F12002C,
+ 0x0F120032,
+ 0x0F120038,
+ 0x0F12003E,
+ 0x0F120044,
+ 0x0F12004A,
+ 0x0F120050,
+ 0x0F120056,
+ 0x0F12005C,
+ 0x0F120062,
+ 0x0F120068,
+ 0x0F12006E,
+ 0x0F120074,
+ 0x0F12007A,
+ 0x0F120080,
+ 0x0F120086,
+ 0x0F12008C,
+ 0x0F120092,
+ 0x0F120098,
+ 0x0F12009E,
+ 0x0F1200A4,
+ 0x0F1200AA,
+ 0x0F1200B0,
+
+ 0x002A1722,
+ 0x0F128000,
+ 0x0F120006,
+ 0x0F123FF0,
+ 0x0F1203E8,
+ 0x0F120000,
+ 0x0F120080, /*delay2 when threshold upper lens moving when moving*/
+ 0x0F120009, /*threshold */
+ 0x0F120020, /*delay1 when threshold lower lens moving when moving*/
+ 0x0F120040,
+ 0x0F120080,
+ 0x0F1200C0,
+ 0x0F1200E0,
+
+ 0x002A028C,
+ 0x0F120003, /*REG_TC_AF_AfCmd */
+
+/*===================================================================
+//04.Gas_Anti Shading_Otp
+//==================================================================*/
+ 0x002A08B4,
+ 0x0F120001, /*wbt_bUseOutdoorASH */
+
+/* Refer Mon_AWB_RotGain*/
+ 0x002A08BC,
+ 0x0F1200C0, /*TVAR_ash_AwbAshCord_0_ 2300K*/
+ 0x0F1200DF, /*TVAR_ash_AwbAshCord_1_ 2750K*/
+ 0x0F120100, /*TVAR_ash_AwbAshCord_2_ 3300K*/
+ 0x0F120125, /*TVAR_ash_AwbAshCord_3_ 4150K*/
+ 0x0F12015F, /*TVAR_ash_AwbAshCord_4_ 5250K*/
+ 0x0F12017C, /*TVAR_ash_AwbAshCord_5_ 6400K*/
+ 0x0F120194, /*TVAR_ash_AwbAshCord_6_ 7500K*/
+
+/* GAS Alpha Table*/
+ 0x002A08F6,
+ 0x0F124000, /*TVAR_ash_GASAlpha_0__0_ R // 2300K */
+ 0x0F124000, /*TVAR_ash_GASAlpha_0__1_ GR */
+ 0x0F124000, /*TVAR_ash_GASAlpha_0__2_ GB */
+ 0x0F124000, /*TVAR_ash_GASAlpha_0__3_ B */
+ 0x0F124000, /*TVAR_ash_GASAlpha_1__0_ R // 2750K */
+ 0x0F124000, /*TVAR_ash_GASAlpha_1__1_ GR */
+ 0x0F124000, /*TVAR_ash_GASAlpha_1__2_ GB */
+ 0x0F124000, /*TVAR_ash_GASAlpha_1__3_ B */
+ 0x0F124000, /*TVAR_ash_GASAlpha_2__0_ R // 3300K */
+ 0x0F124000, /*TVAR_ash_GASAlpha_2__1_ GR */
+ 0x0F124000, /*TVAR_ash_GASAlpha_2__2_ GB */
+ 0x0F124000, /*TVAR_ash_GASAlpha_2__3_ B */
+ 0x0F123C00, /*TVAR_ash_GASAlpha_3__0_ R // 4150K */
+ 0x0F124000, /*TVAR_ash_GASAlpha_3__1_ GR */
+ 0x0F124000, /*TVAR_ash_GASAlpha_3__2_ GB */
+ 0x0F124000, /*TVAR_ash_GASAlpha_3__3_ B */
+ 0x0F123E00, /*TVAR_ash_GASAlpha_4__0_ R // 5250K */
+ 0x0F124000, /*TVAR_ash_GASAlpha_4__1_ GR */
+ 0x0F124000, /*TVAR_ash_GASAlpha_4__2_ GB */
+ 0x0F124000, /*TVAR_ash_GASAlpha_4__3_ B */
+ 0x0F124100, /*TVAR_ash_GASAlpha_5__0_ R // 6400K */
+ 0x0F124000, /*TVAR_ash_GASAlpha_5__1_ GR */
+ 0x0F124000, /*TVAR_ash_GASAlpha_5__2_ GB */
+ 0x0F124000, /*TVAR_ash_GASAlpha_5__3_ B */
+ 0x0F124200, /*TVAR_ash_GASAlpha_6__0_ R // 7500K */
+ 0x0F124000, /*TVAR_ash_GASAlpha_6__1_ GR */
+ 0x0F124000, /*TVAR_ash_GASAlpha_6__2_ GB */
+ 0x0F124000, /*TVAR_ash_GASAlpha_6__3_ B */
+
+/* Outdoor GAS Alpha*/
+ 0x0F124500, /*TVAR_ash_GASOutdoorAlpha_0_ R */
+ 0x0F124000, /*TVAR_ash_GASOutdoorAlpha_1_ GR */
+ 0x0F124000, /*TVAR_ash_GASOutdoorAlpha_2_ GB */
+ 0x0F124000, /*TVAR_ash_GASOutdoorAlpha_3_ B */
+
+ 0x002A08F4,
+ 0x0F120001, /*ash_bUseGasAlpha */
+
+/*=================================================================
+// 09.Auto Flicker Detection
+//================================================================*/
+
+ 0x002A0F30,
+ 0x0F120001, /*AFC_D_ConvAccelerPower */
+
+/*Auto Flicker (60Mhz start)*/
+ 0x002A0F2A,
+ 0x0F120000, /*AFC_Default BIT[0] 1:60Hz 0:50Hz */
+ 0x002A04E6,
+ 0x0F12077F, /*REG_TC_DBG 7F: 60Hz 5F:50Hz */
+
+/*===========================================================
+// 10.AE Setting
+//==========================================================*/
+ 0x002A1484,
+ 0x0F12003C, /*TVAR_ae_BrAve */
+ 0x002A148A,
+ 0x0F12000F, /*ae_StatMode */
+ 0x002A058C,
+ 0x0F123520,
+ 0x0F120000, /*lt_uMaxExp1 */
+ 0x0F12C350,
+ 0x0F120000, /*lt_uMaxExp2 */
+ 0x0F123520,
+ 0x0F120000, /*lt_uCapMaxExp1 */
+ 0x0F12C350,
+ 0x0F120000, /*lt_uCapMaxExp2*/
+ 0x002A059C,
+ 0x0F120470, /*lt_uMaxAnGain1 */
+ 0x0F120C00, /*lt_uMaxAnGain2 */
+ 0x0F120100, /*lt_uMaxDigGain */
+ 0x0F121000, /*lt_uMaxTotGain */
+
+ 0x002A0544,
+ 0x0F120111, /*lt_uLimitHigh */
+ 0x0F1200EF, /*lt_uLimitLow */
+
+ 0x002A0F2A,
+ 0x0F120000, /*AFC_Default60Hz 0001:60Hz 0000h:50Hz */
+ 0x002A04E6,
+ 0x0F12077F, /*REG_TC_DBG */
+
+ 0x002A0F30,
+ 0x0F120001, /*AFC_D_ConvAccelerPower */
+
+ 0x002A0608,
+ 0x0F120001, /*lt_ExpGain_uSubsamplingmode */
+ 0x0F120001, /*lt_ExpGain_uNonSubsampling */
+ 0x0F120800, /*lt_ExpGain_ExpCurveGainMaxStr */
+ 0x0F120100,/*0100 //lt_ExpGain_ExpCurveGainMaxStr_0_uMaxDigGain*/
+ 0x0F120001, /*0001 */
+ 0x0F120000,/*0000 //lt_ExpGain_ExpCurveGainMaxStr_0__ulExpIn_0_ */
+ 0x0F120A3C, /*0A3C */
+ 0x0F120000, /*0000 */
+ 0x0F120D05, /*0D05 */
+ 0x0F120000, /*0000 */
+ 0x0F124008, /*4008 */
+ 0x0F120000, /*0000 */
+ 0x0F127000, /*7400 //?? //700Lux */
+ 0x0F120000, /*0000 */
+ 0x0F129C00, /*C000 //?? //9C00->9F->A5 //400Lux */
+ 0x0F120000, /*0000 */
+ 0x0F12AD00, /*AD00 */
+ 0x0F120001, /*0001 */
+ 0x0F12F1D4, /*F1D4 */
+ 0x0F120002, /*0002 */
+ 0x0F12DC00, /*DC00 */
+ 0x0F120005, /*0005 */
+ 0x0F12DC00, /*DC00 */
+ 0x0F120005, /*0005 */
+ /**/
+ 0x002A0638, /*0638 */
+ 0x0F120001, /*0001 */
+ 0x0F120000,/*0000 //lt_ExpGain_ExpCurveGainMaxStr_0__ulExpOut_0_*/
+ 0x0F120A3C, /*0A3C */
+ 0x0F120000, /*0000 */
+ 0x0F120D05, /*0D05 */
+ 0x0F120000, /*0000 */
+ 0x0F123408, /*3408 */
+ 0x0F120000, /*0000 */
+ 0x0F123408, /*3408 */
+ 0x0F120000, /*0000 */
+ 0x0F126810, /*6810 */
+ 0x0F120000, /*0000 */
+ 0x0F128214, /*8214 */
+ 0x0F120000, /*0000 */
+ 0x0F12C350, /*C350 */
+ 0x0F120000, /*0000 */
+ 0x0F12C350, /*C350 */
+ 0x0F120000, /*0000 */
+ 0x0F12C350, /*C350 */
+ 0x0F120000, /*0000 */
+ 0x002A0660,
+ 0x0F120650, /*lt_ExpGain_ExpCurveGainMaxStr_1_ */
+ 0x0F120100, /*lt_ExpGain_ExpCurveGainMaxStr_1__uMaxDigGain */
+ 0x002A06B8,
+ 0x0F12452C,
+ 0x0F120005, /*lt_uMaxLei */
+
+/*===========================================================
+// 11.AE Weight (Normal)
+//==========================================================*/
+ 0x002A1492,
+ 0x0F120100,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120001,
+ 0x0F120101,
+ 0x0F120201,
+ 0x0F120102,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120202,
+ 0x0F120202,
+ 0x0F120101,
+ 0x0F120201,
+ 0x0F120302,
+ 0x0F120203,
+ 0x0F120102,
+ 0x0F120201,
+ 0x0F120302,
+ 0x0F120203,
+ 0x0F120102,
+ 0x0F120201,
+ 0x0F120202,
+ 0x0F120202,
+ 0x0F120102,
+ 0x0F120101,
+ 0x0F120202,
+ 0x0F120202,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+
+/*============================================
+// 14.AWB-BASIC setting
+//============================================*/
+
+/*AWB init Start point*/
+ 0x002A145E,
+ 0x0F120580,
+ 0x0F120428,
+ 0x0F1207B0,
+
+ /*AWB Init */
+/*White Locus*/
+ 0x002A11F0,
+ 0x0F120120, /*awbb_IntcR */
+ 0x0F120121, /*awbb_IntcB */
+
+/*Indoor Zone*/
+ 0x002A101C,
+ 0x0F120386,
+ 0x0F1203A8,
+ 0x0F12033C,
+ 0x0F120394,
+ 0x0F1202FE,
+ 0x0F120372,
+ 0x0F1202A8,
+ 0x0F120352,
+ 0x0F12027C,
+ 0x0F120300,
+ 0x0F120264,
+ 0x0F1202C8,
+ 0x0F120244,
+ 0x0F1202A8,
+ 0x0F12022C,
+ 0x0F1202A0,
+ 0x0F12020C,
+ 0x0F1202A0,
+ 0x0F1201F4,
+ 0x0F120298,
+ 0x0F1201D4,
+ 0x0F120290,
+ 0x0F1201CC,
+ 0x0F120276,
+ 0x0F1201D2,
+ 0x0F120260,
+ 0x0F1201F6,
+ 0x0F12023A,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000, /*awbb_IndoorGrZones_m_GridStep */
+ 0x0F120005,
+ 0x002A1070, /*awbb_IndoorGrZones_ZInfo_m_GridSz */
+ 0x0F12000F,
+ 0x002A1074, /*awbb_IndoorGrZones_m_Boffs */
+ 0x0F120126,
+/* Outdoor Zone*/
+ 0x002A1078,
+ 0x0F120270,
+ 0x0F120296,
+ 0x0F12024A,
+ 0x0F1202AC,
+ 0x0F120240,
+ 0x0F1202B0,
+ 0x0F120234,
+ 0x0F1202B0,
+ 0x0F120228,
+ 0x0F1202AE,
+ 0x0F12021E,
+ 0x0F1202A8,
+ 0x0F120212,
+ 0x0F1202A0,
+ 0x0F120210,
+ 0x0F120294,
+ 0x0F12020E,
+ 0x0F120288,
+ 0x0F120218,
+ 0x0F12027E,
+ 0x0F120234,
+ 0x0F120256,
+ 0x0F120000,
+ 0x0F120000,
+
+ 0x0F120004, /*awbb_OutdoorGrZones_m_GridStep */
+ 0x002A10AC,
+ 0x0F12000B, /*awbb_OutdoorGrZones_ZInfo_m_GridSz */
+ 0x002A10B0,
+ 0x0F1201E8, /*awbb_OutdoorGrZones_m_Boffs */
+
+ /*LowBR Zone */
+ 0x002A10B4,
+ 0x0F120350,
+ 0x0F120422,
+ 0x0F1202C4,
+ 0x0F120452,
+ 0x0F120278,
+ 0x0F12041C,
+ 0x0F120230,
+ 0x0F1203EE,
+ 0x0F1201F0,
+ 0x0F120392,
+ 0x0F1201C0,
+ 0x0F120340,
+ 0x0F120194,
+ 0x0F120302,
+ 0x0F12016E,
+ 0x0F1202C2,
+ 0x0F120148,
+ 0x0F120286,
+ 0x0F12018A,
+ 0x0F120242,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+
+ 0x0F120006, /*awbb_LowBrGrZones_m_GridStep */
+ 0x002A10E8,
+ 0x0F12000A, /*awbb_LowBrGrZones_ZInfo_m_GridSz */
+ 0x002A10EC,
+ 0x0F120106, /*awbb_LowBrGrZones_m_Boffs */
+
+ /*LowTemp Zone */
+ 0x002A10F0,
+ 0x0F120380,
+ 0x0F120000, /*awbb_CrclLowT_R_c */
+ 0x0F120168,
+ 0x0F120000, /*awbb_CrclLowT_B_c */
+ 0x0F122D90,
+ 0x0F120000, /*awbb_CrclLowT_Rad_c */
+
+ /*AWB Convergence Speed */
+ 0x002A1464,
+ 0x0F120008,
+ 0x0F120190,
+ 0x0F1200A0,
+
+ 0x002A1228,
+ 0x0F1200C0,
+ 0x002A122C,
+ 0x0F120010,
+ 0x002A122A,
+ 0x0F120010,
+
+ 0x002A120A,
+ 0x0F1205D5, /*awbb_MvEq_RBthresh */
+ 0x002A120E,
+ 0x0F120000,
+
+ 0x0F120771,
+ 0x0F1203A4,
+ 0x0F120036,
+ 0x0F12002A,
+
+ 0x002A1278,
+ 0x0F12FEF7,
+ 0x0F120021,
+ 0x0F120AF0, /*0E74 */
+ 0x0F120AF0, /*0E74 */
+ 0x0F12018F,
+ 0x0F120096,
+ 0x0F12000E,
+ 0x002A1224,
+ 0x0F120032,
+ 0x0F12001E,
+ 0x0F1200C0,
+ 0x0F120010,
+ 0x0F120002, /*awbb_YThreshLow_Low */
+ 0x002A2BA4,
+ 0x0F120006, /*Mon_AWB_ByPassMode */
+
+ 0x002A146C,
+ 0x0F120002, /*awbb_GridEnable */
+
+ /*Grid */
+ 0x002A1434,
+ 0x0F1202CE, /* awbb_GridConst_1 */
+ 0x0F120347, /* awbb_GridConst_1_1_ */
+ 0x0F1203C2, /* awbb_GridConst_1_2_ */
+ 0x0F1210A0, /* awbb_GridConst_2 */
+ 0x0F1210A1, /* awbb_GridConst_2_1_ */
+ 0x0F121185, /* awbb_GridConst_2_2_ */
+ 0x0F121186, /* awbb_GridConst_2_3_ */
+ 0x0F1211E5, /* awbb_GridConst_2_4_ */
+ 0x0F1211E6, /* awbb_GridConst_2_5_ */
+ 0x0F1200AB, /* awbb_GridCoeff_R_1 */
+ 0x0F1200BF, /* awbb_GridCoeff_B_1 */
+ 0x0F1200D2, /* awbb_GridCoeff_R_2 */
+ 0x0F120093, /* awbb_GridCoeff_B_2 */
+
+ /*Indoor Grid Offset */
+ 0x002A13A4,
+ 0x0F120000, /*0000 */
+ 0x0F12FFE8, /*FFD8 */
+ 0x0F12FFE8, /*FFD8 */
+ 0x0F12FFC0, /*FFD8 */
+ 0x0F12FFC0, /*FFD8 */
+ 0x0F12FFD0, /*FFF6 B */
+ /**/
+ 0x0F120000,/*0000 */
+ 0x0F12FFD8, /*FFD8 */
+ 0x0F12FFD8, /*FFD8 */
+ 0x0F12FFC0, /*FFD8 */
+ 0x0F12FFC0, /*FFD8 */
+ 0x0F12FFD0, /*FFF6 */
+ /**/
+ 0x0F120000,/*0000 */
+ 0x0F12FFD8, /*FFD8 */
+ 0x0F12FFD8, /*FFD8 */
+ 0x0F12FFC0, /*FFD8 */
+ 0x0F12FFC0, /*FFD8 */
+ 0x0F12FFD0, /*FFF6 */
+ /**/
+ 0x0F12FFEC,/*FFEC*/
+ 0x0F120010,/*000A */
+ 0x0F120010, /*000A */
+ 0x0F12FFC0, /*FFC4 */
+ 0x0F12FFC0, /*FFC4 */
+ 0x0F12FFBC, /*FF56 7 */
+ /**/
+ 0x0F12FFEC,/*FFEC*/
+ 0x0F120010,/*000A */
+ 0x0F120010, /*000A */
+ 0x0F12FFC0, /*FFC4 */
+ 0x0F12FFC0, /*FFC4 */
+ 0x0F12FFBC, /*FF56 */
+ /**/
+ 0x0F12FFEC,/*FFEC*/
+ 0x0F120010,/*000A */
+ 0x0F120010, /*000A */
+ 0x0F12FFC0, /*FFC4 */
+ 0x0F12FFC0, /*FFC4 */
+ 0x0F12FFBC, /*FF56 */
+
+/*Outdoor Grid Offset*/
+ 0x0F12FFE0,
+ 0x0F12FFE0,
+ 0x0F12FFE0,
+ 0x0F12FFE0,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F12FFE0,
+ 0x0F12FFE0,
+ 0x0F12FFE0,
+ 0x0F12FFE0,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F12FFE0,
+ 0x0F12FFE0,
+ 0x0F12FFE0,
+ 0x0F12FFE0,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F12FFB0,
+ 0x0F12FFA8,
+ 0x0F12FFA8,
+ 0x0F12FFA8,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F12FFB0,
+ 0x0F12FFA8,
+ 0x0F12FFA8,
+ 0x0F12FFA8,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F12FFB0,
+ 0x0F12FFA8,
+ 0x0F12FFA8,
+ 0x0F12FFA8,
+ 0x0F120000,
+ 0x0F120000,
+ 0x002A1208,
+ 0x0F120020,
+
+ 0x002A144E,
+ 0x0F120000, /*awbb_RGainOff */
+ 0x0F12FFE0, /*awbb_BGainOff */
+ 0x0F120000, /*awbb_GGainOff */
+
+/*======================================================
+// 15.CCM Setting
+//=====================================================*/
+ /*CCM*/
+ 0x002A08A6,
+ 0x0F1200C0,
+ 0x0F120100,
+ 0x0F120125,
+ 0x0F12015F,
+ 0x0F12017C,
+ 0x0F120194,
+
+ 0x0F120001,
+
+ 0x002A0898,
+ 0x0F124800,
+ 0x0F127000,
+ 0x002A08A0,
+ 0x0F1248D8,
+ 0x0F127000,
+ 0x002A4800,/*Horizon */
+ 0x0F120208,
+ 0x0F12FFB5,
+ 0x0F12FFE8,
+ 0x0F12FF20,
+ 0x0F1201BF,
+ 0x0F12FF53,
+ 0x0F120022,
+ 0x0F12FFEA,
+ 0x0F1201C2,
+ 0x0F1200C6,
+ 0x0F120095,
+ 0x0F12FEFD,
+ 0x0F120206,
+ 0x0F12FF7F,
+ 0x0F120191,
+ 0x0F12FF06,
+ 0x0F1201BA,
+ 0x0F120108,
+
+ 0x0F120208, /* inca A */
+ 0x0F12FFB5,
+ 0x0F12FFE8,
+ 0x0F12FF20,
+ 0x0F1201BF,
+ 0x0F12FF53,
+ 0x0F120022,
+ 0x0F12FFEA,
+ 0x0F1201C2,
+ 0x0F1200C6,
+ 0x0F120095,
+ 0x0F12FEFD,
+ 0x0F120206,
+ 0x0F12FF7F,
+ 0x0F120191,
+ 0x0F12FF06,
+ 0x0F1201BA,
+ 0x0F120108,
+ 0x0F120208,/*WW*/
+ 0x0F12FFB5,
+ 0x0F12FFE8,
+ 0x0F12FF20,
+ 0x0F1201BF,
+ 0x0F12FF53,
+ 0x0F120022,
+ 0x0F12FFEA,
+ 0x0F1201C2,
+ 0x0F1200C6,
+ 0x0F120095,
+ 0x0F12FEFD,
+ 0x0F120206,
+ 0x0F12FF7F,
+ 0x0F120191,
+ 0x0F12FF06,
+ 0x0F1201BA,
+ 0x0F120108,
+ 0x0F120204,/*CW*/
+ 0x0F12FFB2,
+ 0x0F12FFF5,
+ 0x0F12FEF1,
+ 0x0F12014E,
+ 0x0F12FF18,
+ 0x0F12FFE6,
+ 0x0F12FFDD,
+ 0x0F1201B2,
+ 0x0F1200F2,
+ 0x0F1200CA,
+ 0x0F12FF48,
+ 0x0F120151,
+ 0x0F12FF50,
+ 0x0F120147,
+ 0x0F12FF75,
+ 0x0F120187,
+ 0x0F1201BF,
+ 0x0F1201F5,/*D50*/
+ 0x0F12FFB4,
+ 0x0F120001,
+ 0x0F12FED7,
+ 0x0F12014B,
+ 0x0F12FF35,
+ 0x0F12FFE6,
+ 0x0F12FFDD,
+ 0x0F1201B2,
+ 0x0F1200F2,
+ 0x0F1200CA,
+ 0x0F12FF48,
+ 0x0F120151,
+ 0x0F12FF50,
+ 0x0F120147,
+ 0x0F12FF75,
+ 0x0F120187,
+ 0x0F1201BF,
+ 0x0F1201F5,/*D65 */
+ 0x0F12FFB4,
+ 0x0F120001,
+ 0x0F12FED7,
+ 0x0F12014B,
+ 0x0F12FF35,
+ 0x0F12FFE6,
+ 0x0F12FFDD,
+ 0x0F1201B2,
+ 0x0F1200F2,
+ 0x0F1200CA,
+ 0x0F12FF48,
+ 0x0F120151,
+ 0x0F12FF50,
+ 0x0F120147,
+ 0x0F12FF75,
+ 0x0F120187,
+ 0x0F1201BF,
+ 0x0F1201E5,/*Y hue-5. TVAR_wbt_pOutdoorCcm[0] */
+ 0x0F12FFA4,
+ 0x0F12FFDC,
+ 0x0F12FE90,
+ 0x0F12013F,
+ 0x0F12FF1B,
+ 0x0F12FFD2,
+ 0x0F12FFDF,
+ 0x0F120236,
+ 0x0F1200F0,
+ 0x0F1200C9,
+ 0x0F12FF59,
+ 0x0F1201CE,
+ 0x0F12FF83,
+ 0x0F120195,
+ 0x0F12FEF3,
+ 0x0F120126,
+ 0x0F120162,
+/*==================================================================
+// 16.GAMMA
+//================================================================*/
+ 0x002A0734,/*R*/
+ 0x0F120000,
+ 0x0F120001,
+ 0x0F120006,
+ 0x0F120017,
+ 0x0F12004A,
+ 0x0F1200C9,
+ 0x0F120138,
+ 0x0F120163,
+ 0x0F120189,
+ 0x0F1201C6,
+ 0x0F1201F8,
+ 0x0F120222,
+ 0x0F120247,
+ 0x0F120282,
+ 0x0F1202B5,
+ 0x0F12030F,
+ 0x0F12035F,
+ 0x0F1203A2,
+ 0x0F1203D8,
+ 0x0F1203FF,
+
+ 0x0F120000,/*G*/
+ 0x0F120001,
+ 0x0F120006,
+ 0x0F120017,
+ 0x0F12004A,
+ 0x0F1200C9,
+ 0x0F120138,
+ 0x0F120163,
+ 0x0F120189,
+ 0x0F1201C6,
+ 0x0F1201F8,
+ 0x0F120222,
+ 0x0F120247,
+ 0x0F120282,
+ 0x0F1202B5,
+ 0x0F12030F,
+ 0x0F12035F,
+ 0x0F1203A2,
+ 0x0F1203D8,
+ 0x0F1203FF,
+
+ 0x0F120000,/*B*/
+ 0x0F120001,
+ 0x0F120006,
+ 0x0F120017,
+ 0x0F12004A,
+ 0x0F1200C9,
+ 0x0F120138,
+ 0x0F120163,
+ 0x0F120189,
+ 0x0F1201C6,
+ 0x0F1201F8,
+ 0x0F120222,
+ 0x0F120247,
+ 0x0F120282,
+ 0x0F1202B5,
+ 0x0F12030F,
+ 0x0F12035F,
+ 0x0F1203A2,
+ 0x0F1203D8,
+ 0x0F1203FF,
+/*RGB OutdoorGamma*/
+ 0x0F120000,
+ 0x0F12000B,
+ 0x0F120019,
+ 0x0F120036,
+ 0x0F12006F,
+ 0x0F1200D8,
+ 0x0F120135,
+ 0x0F12015F,
+ 0x0F120185,
+ 0x0F1201C1,
+ 0x0F1201F3,
+ 0x0F120220,
+ 0x0F12024A,
+ 0x0F120291,
+ 0x0F1202D0,
+ 0x0F12032A,
+ 0x0F12036A,
+ 0x0F12039F,
+ 0x0F1203CC,
+ 0x0F1203F9,
+ 0x0F120000,
+ 0x0F12000B,
+ 0x0F120019,
+ 0x0F120036,
+ 0x0F12006F,
+ 0x0F1200D8,
+ 0x0F120135,
+ 0x0F12015F,
+ 0x0F120185,
+ 0x0F1201C1,
+ 0x0F1201F3,
+ 0x0F120220,
+ 0x0F12024A,
+ 0x0F120291,
+ 0x0F1202D0,
+ 0x0F12032A,
+ 0x0F12036A,
+ 0x0F12039F,
+ 0x0F1203CC,
+ 0x0F1203F9,
+ 0x0F120000,
+ 0x0F12000B,
+ 0x0F120019,
+ 0x0F120036,
+ 0x0F12006F,
+ 0x0F1200D8,
+ 0x0F120135,
+ 0x0F12015F,
+ 0x0F120185,
+ 0x0F1201C1,
+ 0x0F1201F3,
+ 0x0F120220,
+ 0x0F12024A,
+ 0x0F120291,
+ 0x0F1202D0,
+ 0x0F12032A,
+ 0x0F12036A,
+ 0x0F12039F,
+ 0x0F1203CC,
+ 0x0F1203F9,
+/*===========================================================
+// 17.AFIT
+//==========================================================*/
+ 0x002A0944,
+ 0x0F120050,/*afit_uNoiseIndInDoor */
+ 0x0F1200B0, /*afit_uNoiseIndInDoor */
+ 0x0F120196, /*afit_uNoiseIndInDoor */
+ 0x0F120245, /*afit_uNoiseIndInDoor */
+ 0x0F120300, /*afit_uNoiseIndInDoor */
+
+ 0x002A0938,
+ 0x0F120000,/* on/off AFIT by NB option */
+ 0x0F120014, /*SARR_uNormBrInDoor */
+ 0x0F1200D2, /*SARR_uNormBrInDoor */
+ 0x0F120384, /*SARR_uNormBrInDoor */
+ 0x0F1207D0, /*SARR_uNormBrInDoor */
+ 0x0F121388, /*SARR_uNormBrInDoor */
+
+ 0x002A0976,
+ 0x0F120070,/*afit_usGamutTh */
+ 0x0F120005, /*afit_usNeargrayOffset */
+ 0x0F120000, /*afit_bUseSenBpr */
+ 0x0F1201CC, /*afit_usBprThr_0_ */
+ 0x0F1201CC, /*afit_usBprThr_1_ */
+ 0x0F1201CC, /*afit_usBprThr_2_ */
+ 0x0F1201CC, /*afit_usBprThr_3_ */
+ 0x0F1201CC, /*afit_usBprThr_4_ */
+ 0x0F120180, /*afit_NIContrastAFITValue */
+ 0x0F120196, /*afit_NIContrastTh */
+
+ 0x002A098C,
+ 0x0F12FFEC, /*7000098C//_BRIGHTNESS */
+ 0x0F120000, /*7000098E//_CONTRAST */
+ 0x0F120000, /*70000990//_SATURATION */
+ 0x0F120000, /*70000992//_SHARP_BLUR */
+ 0x0F120000, /*70000994//_GLAMOUR */
+ 0x0F1200C0, /*70000996//_bnr_edge_high */
+ 0x0F120064, /*70000998//_postdmsc_iLowBright */
+ 0x0F120384, /*7000099A//_postdmsc_iHighBright */
+ 0x0F12005F, /*7000099C//_postdmsc_iLowSat */
+ 0x0F1201F4, /*7000099E//_postdmsc_iHighSat */
+ 0x0F120070, /*700009A0//_postdmsc_iTune */
+ 0x0F120040, /*700009A2//_yuvemix_mNegRanges_0 */
+ 0x0F1200A0, /*700009A4//_yuvemix_mNegRanges_1 */
+ 0x0F120100, /*700009A6//_yuvemix_mNegRanges_2 */
+ 0x0F120010, /*700009A8//_yuvemix_mPosRanges_0 */
+ 0x0F120040, /*700009AA//_yuvemix_mPosRanges_1 */
+ 0x0F1200A0, /*700009AC//_yuvemix_mPosRanges_2 */
+ 0x0F121430, /*700009AE//_bnr_edge_low */
+ 0x0F120201, /*700009B0//_bnr_repl_force */
+ 0x0F120204, /*700009B2//_bnr_iHotThreshLow */
+ 0x0F123604, /*700009B4//_bnr_iColdThreshLow */
+ 0x0F12032A, /*700009B6//_bnr_DispTH_High */
+ 0x0F120403, /*700009B8//_bnr_DISP_Limit_High */
+ 0x0F121B06, /*700009BA//_bnr_iDistSigmaMax */
+ 0x0F126015, /*700009BC//_bnr_iDiffSigmaHigh */
+ 0x0F1200C0, /*700009BE//_bnr_iNormalizedSTD_Limit */
+ 0x0F126080, /*700009C0//_bnr_iDirMinThres */
+ 0x0F124080, /*700009C2//_bnr_iDirFltDiffThresLow */
+ 0x0F120640, /*700009C4//_bnr_iDirSmoothPowerLow */
+ 0x0F120306, /*700009C6//_bnr_iHighMaxSlopeAllowed */
+ 0x0F122003, /*700009C8//_bnr_iHighSlopeThresh */
+ 0x0F12FF01, /*700009CA//_bnr_iSlopeBlurStrength */
+ 0x0F120000, /*700009CC//_bnr_AddNoisePower1 */
+ 0x0F120400, /*700009CE//_bnr_iRadialTune */
+ 0x0F12365A, /*700009D0//_bnr_iRadialLimit */
+ 0x0F12102A, /*700009D2//_ee_iFSMagThHigh */
+ 0x0F12000B, /*700009D4//_ee_iFSVarThHigh */
+ 0x0F120600, /*700009D6//_ee_iFSThHigh */
+ 0x0F125A0F, /*700009D8//_ee_iFSVarCountTh */
+ 0x0F120505, /*700009DA//_ee_iRadialPower */
+ 0x0F121802, /*700009DC//_ee_iROADThres */
+ 0x0F120000, /*700009DE//_ee_iROADSubMaxNR */
+ 0x0F122006, /*700009E0//_ee_iROADNeiThres */
+ 0x0F123028, /*700009E2//_ee_iSmoothEdgeThres */
+ 0x0F120418, /*700009E4//_ee_iWSharpen */
+ 0x0F120101, /*700009E6//_ee_iWShThresh */
+ 0x0F120800, /*700009E8//_ee_iEmbossCentAdd */
+ 0x0F121804, /*700009EA//_ee_iReduceEdgeThresh */
+ 0x0F124008, /*700009EC//_dmsc_iDesatThresh */
+ 0x0F120540, /*700009EE//_dmsc_iDemBlurLow */
+ 0x0F128006, /*700009F0//_dmsc_iDecisionThresh */
+ 0x0F120020, /*700009F2//_dmsc_iMonochrom */
+ 0x0F120000, /*700009F4//_dmsc_iGRDenoiseVal */
+ 0x0F122000, /*700009F6//_dmsc_iEdgeDesatThrLow */
+ 0x0F120000, /*700009F8//_dmsc_iNearGrayDesat */
+ 0x0F121E10, /*700009FA//_postdmsc_iBCoeff */
+ 0x0F12000B, /*700009FC//_postdmsc_iWideMult */
+ 0x0F120607, /*700009FE//_yuvemix_mNegSlopes_1 */
+ 0x0F120005, /*70000A00//_yuvemix_mNegSlopes_3 */
+ 0x0F120607, /*70000A02//_yuvemix_mPosSlopes_1 */
+ 0x0F120705, /*70000A04//_yuvemix_mPosSlopes_3 */
+ 0x0F120206, /*70000A06//_yuviirnr_iXSupportUV */
+ 0x0F120304, /*70000A08//_yuviirnr_iHighYNorm */
+ 0x0F120309, /*70000A0A//_yuviirnr_iHighUVNorm */
+ 0x0F120305, /*70000A0C//_yuviirnr_iUVNormShift */
+ 0x0F122006, /*70000A0E//_yuviirnr_iVertLength_UV */
+ 0x0F121320, /*70000A10//_yuviirnr_iDiffThreshH_Y */
+ 0x0F121014, /*70000A12//_yuviirnr_iDiffThreshH_UV */
+ 0x0F121010, /*70000A14//_yuviirnr_iMaxThreshH_Y */
+ 0x0F120C10, /*70000A16//_yuviirnr_iMaxThreshH_UV */
+ 0x0F121A0C, /*70000A18//_yuviirnr_iYNRStrengthH */
+ 0x0F124A18, /*70000A1A//_yuviirnr_iUVNRStrengthH */
+ 0x0F120080, /*70000A1C//_RGBGamma2_iLinearity */
+ 0x0F120350, /*70000A1E//_ccm_oscar_iSaturation */
+ 0x0F120180, /*70000A20//_RGB2YUV_iRGBGain */
+ 0x0F120A0A, /*70000A22//_bnr_iClustMulT_H */
+ 0x0F120101, /*70000A24//_bnr_iClustThresh_H */
+ 0x0F122A36, /*70000A26//_bnr_iDenThreshLow */
+ 0x0F126024, /*70000A28//_ee_iLowSharpPower */
+ 0x0F122A36, /*70000A2A//_ee_iLowShDenoise */
+ 0x0F12FFFF, /*70000A2C//_ee_iLowSharpClamp */
+ 0x0F120808, /*70000A2E//_ee_iReduceEdgeMinMult */
+ 0x0F120A01, /*70000A30//_bnr_nClustLevel_H_Bin */
+ 0x0F12010A, /*70000A32//_bnr_iClustMulT_C_Bin */
+ 0x0F122701, /*70000A34//_bnr_iClustThresh_C_Bin */
+ 0x0F12241E, /*70000A36//_bnr_iDenThreshHigh_Bin */
+ 0x0F122E60, /*70000A38//_ee_iHighSharpPower_Bin */
+ 0x0F12FF22, /*70000A3A//_ee_iHighShDenoise_Bin */
+ 0x0F1240FF, /*70000A3C//_ee_iHighSharpClamp_Bin */
+ 0x0F120009, /*70000A3E//_ee_iReduceEdgeSlope_Bin */
+ 0x0F120001, /*70000A40//_bnr_nClustLevel_C */
+ 0x0F120000, /*70000A42//_BRIGHTNESS */
+ 0x0F120000, /*70000A44//_CONTRAST */
+ 0x0F120000, /*70000A46//_SATURATION */
+ 0x0F120000, /*70000A48//_SHARP_BLUR */
+ 0x0F120000, /*70000A4A//_GLAMOUR */
+ 0x0F1200C0, /*70000A4C//_bnr_edge_high */
+ 0x0F120064, /*70000A4E//_postdmsc_iLowBright */
+ 0x0F120384, /*70000A50//_postdmsc_iHighBright */
+ 0x0F120051, /*70000A52//_postdmsc_iLowSat */
+ 0x0F1201F4, /*70000A54//_postdmsc_iHighSat */
+ 0x0F120070, /*70000A56//_postdmsc_iTune */
+ 0x0F120040, /*70000A58//_yuvemix_mNegRanges_0 */
+ 0x0F1200A0, /*70000A5A//_yuvemix_mNegRanges_1 */
+ 0x0F120100, /*70000A5C//_yuvemix_mNegRanges_2 */
+ 0x0F120010, /*70000A5E//_yuvemix_mPosRanges_0 */
+ 0x0F120060, /*70000A60//_yuvemix_mPosRanges_1 */
+ 0x0F120100, /*70000A62//_yuvemix_mPosRanges_2 */
+ 0x0F121430, /*70000A64//_bnr_edge_low */
+ 0x0F120201, /*70000A66//_bnr_repl_force */
+ 0x0F120204, /*70000A68//_bnr_iHotThreshLow */
+ 0x0F122404, /*70000A6A//_bnr_iColdThreshLow */
+ 0x0F12031B, /*70000A6C//_bnr_DispTH_High */
+ 0x0F120103, /*70000A6E//_bnr_DISP_Limit_High */
+ 0x0F121205, /*70000A70//_bnr_iDistSigmaMax */
+ 0x0F12400D, /*70000A72//_bnr_iDiffSigmaHigh */
+ 0x0F120080, /*70000A74//_bnr_iNormalizedSTD_Limit */
+ 0x0F121980, /*70000A76//_bnr_iDirMinThres */
+ 0x0F12272E, /*70000A78//_bnr_iDirFltDiffThresLow */
+ 0x0F120629, /*70000A7A//_bnr_iDirSmoothPowerLow */
+ 0x0F120306, /*70000A7C//_bnr_iHighMaxSlopeAllowed */
+ 0x0F122003, /*70000A7E//_bnr_iHighSlopeThresh */
+ 0x0F12FF01, /*70000A80//_bnr_iSlopeBlurStrength */
+ 0x0F120404, /*70000A82//_bnr_AddNoisePower1 */
+ 0x0F120300, /*70000A84//_bnr_iRadialTune */
+ 0x0F12245A, /*70000A86//_bnr_iRadialLimit */
+ 0x0F121018, /*70000A88//_ee_iFSMagThHigh */
+ 0x0F12000B, /*70000A8A//_ee_iFSVarThHigh */
+ 0x0F120B00, /*70000A8C//_ee_iFSThHigh */
+ 0x0F125A0F, /*70000A8E//_ee_iFSVarCountTh */
+ 0x0F120505, /*70000A90//_ee_iRadialPower */
+ 0x0F121802, /*70000A92//_ee_iROADThres */
+ 0x0F120000, /*70000A94//_ee_iROADSubMaxNR */
+ 0x0F122006, /*70000A96//_ee_iROADNeiThres */
+ 0x0F123828, /*70000A98//_ee_iSmoothEdgeThres */
+ 0x0F120425, /*70000A9A//_ee_iWSharpen */
+ 0x0F120101, /*70000A9C//_ee_iWShThresh */
+ 0x0F120800, /*70000A9E//_ee_iEmbossCentAdd */
+ 0x0F121004, /*70000AA0//_ee_iReduceEdgeThresh */
+ 0x0F124008, /*70000AA2//_dmsc_iDesatThresh */
+ 0x0F120540, /*70000AA4//_dmsc_iDemBlurLow */
+ 0x0F128006, /*70000AA6//_dmsc_iDecisionThresh */
+ 0x0F120020, /*70000AA8//_dmsc_iMonochrom */
+ 0x0F120000, /*70000AAA//_dmsc_iGRDenoiseVal */
+ 0x0F122000, /*70000AAC//_dmsc_iEdgeDesatThrLow */
+ 0x0F120000, /*70000AAE//_dmsc_iNearGrayDesat */
+ 0x0F121E10, /*70000AB0//_postdmsc_iBCoeff */
+ 0x0F12000B, /*70000AB2//_postdmsc_iWideMult */
+ 0x0F120607, /*70000AB4//_yuvemix_mNegSlopes_1 */
+ 0x0F120005, /*70000AB6//_yuvemix_mNegSlopes_3 */
+ 0x0F120607, /*70000AB8//_yuvemix_mPosSlopes_1 */
+ 0x0F120405, /*70000ABA//_yuvemix_mPosSlopes_3 */
+ 0x0F120205, /*70000ABC//_yuviirnr_iXSupportUV */
+ 0x0F120304, /*70000ABE//_yuviirnr_iHighYNorm */
+ 0x0F120409, /*70000AC0//_yuviirnr_iHighUVNorm */
+ 0x0F120306, /*70000AC2//_yuviirnr_iUVNormShift */
+ 0x0F120407, /*70000AC4//_yuviirnr_iVertLength_UV */
+ 0x0F122204, /*70000AC6//_yuviirnr_iDiffThreshH_Y */
+ 0x0F12021C, /*70000AC8//_yuviirnr_iDiffThreshH_UV */
+ 0x0F121102, /*70000ACA//_yuviirnr_iMaxThreshH_Y */
+ 0x0F120611, /*70000ACC//_yuviirnr_iMaxThreshH_UV */
+ 0x0F121A02, /*70000ACE//_yuviirnr_iYNRStrengthH */
+ 0x0F128018, /*70000AD0//_yuviirnr_iUVNRStrengthH */
+ 0x0F120080, /*70000AD2//_RGBGamma2_iLinearity */
+ 0x0F120374, /*70000AD4//_ccm_oscar_iSaturation */
+ 0x0F120180, /*70000AD6//_RGB2YUV_iRGBGain */
+ 0x0F120A0A, /*70000AD8//_bnr_iClustMulT_H */
+ 0x0F120101, /*70000ADA//_bnr_iClustThresh_H */
+ 0x0F12141D, /*70000ADC//_bnr_iDenThreshLow */
+ 0x0F126024, /*70000ADE//_ee_iLowSharpPower */
+ 0x0F121217, /*70000AE0//_ee_iLowShDenoise */
+ 0x0F12FFFF, /*70000AE2//_ee_iLowSharpClamp */
+ 0x0F120808, /*70000AE4//_ee_iReduceEdgeMinMult */
+ 0x0F120A01, /*70000AE6//_bnr_nClustLevel_H_Bin */
+ 0x0F12010A, /*70000AE8//_bnr_iClustMulT_C_Bin */
+ 0x0F120001, /*70000AEA//_bnr_iClustThresh_C_Bin */
+ 0x0F122400, /*70000AEC//_bnr_iDenThreshHigh_Bin */
+ 0x0F121660, /*70000AEE//_ee_iHighSharpPower_Bin */
+ 0x0F12FF10, /*70000AF0//_ee_iHighShDenoise_Bin */
+ 0x0F1240FF, /*70000AF2//_ee_iHighSharpClamp_Bin */
+ 0x0F120009, /*70000AF4//_ee_iReduceEdgeSlope_Bin */
+ 0x0F120001, /*70000AF6//_bnr_nClustLevel_C */
+ 0x0F120000, /*70000AF8//_BRIGHTNESS AFIT 2 */
+ 0x0F120000, /*70000AFA//_CONTRAST */
+ 0x0F120000, /*70000AFC//_SATURATION */
+ 0x0F120000, /*70000AFE//_SHARP_BLUR */
+ 0x0F120000, /*70000B00//_GLAMOUR */
+ 0x0F1200C0, /*70000B02//_bnr_edge_high */
+ 0x0F120064, /*70000B04//_postdmsc_iLowBright */
+ 0x0F120384, /*70000B06//_postdmsc_iHighBright */
+ 0x0F120043, /*70000B08//_postdmsc_iLowSat */
+ 0x0F1201F4, /*70000B0A//_postdmsc_iHighSat */
+ 0x0F120070, /*70000B0C//_postdmsc_iTune */
+ 0x0F120040, /*70000B0E//_yuvemix_mNegRanges_0 */
+ 0x0F1200A0, /*70000B10//_yuvemix_mNegRanges_1 */
+ 0x0F120100, /*70000B12//_yuvemix_mNegRanges_2 */
+ 0x0F120010, /*70000B14//_yuvemix_mPosRanges_0 */
+ 0x0F120060, /*70000B16//_yuvemix_mPosRanges_1 */
+ 0x0F120100, /*70000B18//_yuvemix_mPosRanges_2 */
+ 0x0F121430, /*70000B1A//_bnr_edge_low */
+ 0x0F120201, /*70000B1C//_bnr_repl_force */
+ 0x0F120204, /*70000B1E//_bnr_iHotThreshLow */
+ 0x0F121B04, /*70000B20//_bnr_iColdThreshLow */
+ 0x0F120312, /*70000B22//_bnr_DispTH_High */
+ 0x0F120003, /*70000B24//_bnr_DISP_Limit_High */
+ 0x0F120C03, /*70000B26//_bnr_iDistSigmaMax */
+ 0x0F122806, /*70000B28//_bnr_iDiffSigmaHigh */
+ 0x0F120060, /*70000B2A//_bnr_iNormalizedSTD_Limit */
+ 0x0F121580, /*70000B2C//_bnr_iDirMinThres */
+ 0x0F122020, /*70000B2E//_bnr_iDirFltDiffThresLow */
+ 0x0F120620, /*70000B30//_bnr_iDirSmoothPowerLow */
+ 0x0F120306, /*70000B32//_bnr_iHighMaxSlopeAllowed */
+ 0x0F122003, /*70000B34//_bnr_iHighSlopeThresh */
+ 0x0F12FF01, /*70000B36//_bnr_iSlopeBlurStrength */
+ 0x0F120404, /*70000B38//_bnr_AddNoisePower1 */
+ 0x0F120300, /*70000B3A//_bnr_iRadialTune */
+ 0x0F12145A, /*70000B3C//_bnr_iRadialLimit */
+ 0x0F121010, /*70000B3E//_ee_iFSMagThHigh */
+ 0x0F12000B, /*70000B40//_ee_iFSVarThHigh */
+ 0x0F120E00, /*70000B42//_ee_iFSThHigh */
+ 0x0F125A0F, /*70000B44//_ee_iFSVarCountTh */
+ 0x0F120504, /*70000B46//_ee_iRadialPower */
+ 0x0F121802, /*70000B48//_ee_iROADThres */
+ 0x0F120000, /*70000B4A//_ee_iROADSubMaxNR */
+ 0x0F122006, /*70000B4C//_ee_iROADNeiThres */
+ 0x0F123828, /*70000B4E//_ee_iSmoothEdgeThres */
+ 0x0F120428, /*70000B50//_ee_iWSharpen */
+ 0x0F120101, /*70000B52//_ee_iWShThresh */
+ 0x0F128000, /*70000B54//_ee_iEmbossCentAdd */
+ 0x0F120A04, /*70000B56//_ee_iReduceEdgeThresh */
+ 0x0F124008, /*70000B58//_dmsc_iDesatThresh */
+ 0x0F120540, /*70000B5A//_dmsc_iDemBlurLow */
+ 0x0F128006, /*70000B5C//_dmsc_iDecisionThresh */
+ 0x0F120020, /*70000B5E//_dmsc_iMonochrom */
+ 0x0F120000, /*70000B60//_dmsc_iGRDenoiseVal */
+ 0x0F122000, /*70000B62//_dmsc_iEdgeDesatThrLow */
+ 0x0F120000, /*70000B64//_dmsc_iNearGrayDesat */
+ 0x0F121E10, /*70000B66//_postdmsc_iBCoeff */
+ 0x0F12000B, /*70000B68//_postdmsc_iWideMult */
+ 0x0F120607, /*70000B6A//_yuvemix_mNegSlopes_1 */
+ 0x0F120005, /*70000B6C//_yuvemix_mNegSlopes_3 */
+ 0x0F120607, /*70000B6E//_yuvemix_mPosSlopes_1 */
+ 0x0F120405, /*70000B70//_yuvemix_mPosSlopes_3 */
+ 0x0F120207, /*70000B72//_yuviirnr_iXSupportUV */
+ 0x0F120304, /*70000B74//_yuviirnr_iHighYNorm */
+ 0x0F120409, /*70000B76//_yuviirnr_iHighUVNorm */
+ 0x0F120306, /*70000B78//_yuviirnr_iUVNormShift */
+ 0x0F120407, /*70000B7A//_yuviirnr_iVertLength_UV */
+ 0x0F122404, /*70000B7C//_yuviirnr_iDiffThreshH_Y */
+ 0x0F120221, /*70000B7E//_yuviirnr_iDiffThreshH_UV */
+ 0x0F121202, /*70000B80//_yuviirnr_iMaxThreshH_Y */
+ 0x0F120613, /*70000B82//_yuviirnr_iMaxThreshH_UV */
+ 0x0F121A02, /*70000B84//_yuviirnr_iYNRStrengthH */
+ 0x0F128018, /*70000B86//_yuviirnr_iUVNRStrengthH */
+ 0x0F120080, /*70000B88//_RGBGamma2_iLinearity */
+ 0x0F120080, /*70000B8A//_ccm_oscar_iSaturation */
+ 0x0F120180, /*70000B8C//_RGB2YUV_iRGBGain */
+ 0x0F120A0A, /*70000B8E//_bnr_iClustMulT_H */
+ 0x0F120101, /*70000B90//_bnr_iClustThresh_H */
+ 0x0F12121B, /*70000B92//_bnr_iDenThreshLow */
+ 0x0F126024, /*70000B94//_ee_iLowSharpPower */
+ 0x0F120C0C, /*70000B96//_ee_iLowShDenoise */
+ 0x0F12FFFF, /*70000B98//_ee_iLowSharpClamp */
+ 0x0F120808, /*70000B9A//_ee_iReduceEdgeMinMult */
+ 0x0F120A01, /*70000B9C//_bnr_nClustLevel_H_Bin */
+ 0x0F12010A, /*70000B9E//_bnr_iClustMulT_C_Bin */
+ 0x0F120001, /*70000BA0//_bnr_iClustThresh_C_Bin */
+ 0x0F122400, /*70000BA2//_bnr_iDenThreshHigh_Bin */
+ 0x0F120460, /*70000BA4//_ee_iHighSharpPower_Bin */
+ 0x0F12FF04, /*70000BA6//_ee_iHighShDenoise_Bin */
+ 0x0F1240FF, /*70000BA8//_ee_iHighSharpClamp_Bin */
+ 0x0F120009, /*70000BAA//_ee_iReduceEdgeSlope_Bin */
+ 0x0F120001, /*70000BAC//_bnr_nClustLevel_C */
+ 0x0F120000, /*70000BAE//_BRIGHTNESS AFIT 3 */
+ 0x0F120000, /*70000BB0//_CONTRAST */
+ 0x0F120000, /*70000BB2//_SATURATION */
+ 0x0F120000, /*70000BB4//_SHARP_BLUR */
+ 0x0F120000, /*70000BB6//_GLAMOUR */
+ 0x0F1200C0, /*70000BB8//_bnr_edge_high */
+ 0x0F120064, /*70000BBA//_postdmsc_iLowBright */
+ 0x0F120384, /*70000BBC//_postdmsc_iHighBright */
+ 0x0F120032, /*70000BBE//_postdmsc_iLowSat */
+ 0x0F1201F4, /*70000BC0//_postdmsc_iHighSat */
+ 0x0F120070, /*70000BC2//_postdmsc_iTune */
+ 0x0F120040, /*70000BC4//_yuvemix_mNegRanges_0 */
+ 0x0F1200A0, /*70000BC6//_yuvemix_mNegRanges_1 */
+ 0x0F120100, /*70000BC8//_yuvemix_mNegRanges_2 */
+ 0x0F120010, /*70000BCA//_yuvemix_mPosRanges_0 */
+ 0x0F120060, /*70000BCC//_yuvemix_mPosRanges_1 */
+ 0x0F120100, /*70000BCE//_yuvemix_mPosRanges_2 */
+ 0x0F121430, /*70000BD0//_bnr_edge_low */
+ 0x0F120201, /*70000BD2//_bnr_repl_force */
+ 0x0F120204, /*70000BD4//_bnr_iHotThreshLow */
+ 0x0F121504, /*70000BD6//_bnr_iColdThreshLow */
+ 0x0F12030F, /*70000BD8//_bnr_DispTH_High */
+ 0x0F120003, /*70000BDA//_bnr_DISP_Limit_High */
+ 0x0F120902, /*70000BDC//_bnr_iDistSigmaMax */
+ 0x0F122004, /*70000BDE//_bnr_iDiffSigmaHigh */
+ 0x0F120050, /*70000BE0//_bnr_iNormalizedSTD_Limit */
+ 0x0F121140, /*70000BE2//_bnr_iDirMinThres */
+ 0x0F12201C, /*70000BE4//_bnr_iDirFltDiffThresLow */
+ 0x0F120620, /*70000BE6//_bnr_iDirSmoothPowerLow */
+ 0x0F120306, /*70000BE8//_bnr_iHighMaxSlopeAllowed */
+ 0x0F122003, /*70000BEA//_bnr_iHighSlopeThresh */
+ 0x0F12FF01, /*70000BEC//_bnr_iSlopeBlurStrength */
+ 0x0F120404, /*70000BEE//_bnr_AddNoisePower1 */
+ 0x0F120300, /*70000BF0//_bnr_iRadialTune */
+ 0x0F12145A, /*70000BF2//_bnr_iRadialLimit */
+ 0x0F121010, /*70000BF4//_ee_iFSMagThHigh */
+ 0x0F12000B, /*70000BF6//_ee_iFSVarThHigh */
+ 0x0F121000, /*70000BF8//_ee_iFSThHigh */
+ 0x0F125A0F, /*70000BFA//_ee_iFSVarCountTh */
+ 0x0F120503, /*70000BFC//_ee_iRadialPower */
+ 0x0F121802, /*70000BFE//_ee_iROADThres */
+ 0x0F120000, /*70000C00//_ee_iROADSubMaxNR */
+ 0x0F122006, /*70000C02//_ee_iROADNeiThres */
+ 0x0F123C28, /*70000C04//_ee_iSmoothEdgeThres */
+ 0x0F12042C, /*70000C06//_ee_iWSharpen */
+ 0x0F120101, /*70000C08//_ee_iWShThresh */
+ 0x0F12FF00, /*70000C0A//_ee_iEmbossCentAdd */
+ 0x0F120904, /*70000C0C//_ee_iReduceEdgeThresh */
+ 0x0F124008, /*70000C0E//_dmsc_iDesatThresh */
+ 0x0F120540, /*70000C10//_dmsc_iDemBlurLow */
+ 0x0F128006, /*70000C12//_dmsc_iDecisionThresh */
+ 0x0F120020, /*70000C14//_dmsc_iMonochrom */
+ 0x0F120000, /*70000C16//_dmsc_iGRDenoiseVal */
+ 0x0F122000, /*70000C18//_dmsc_iEdgeDesatThrLow */
+ 0x0F120000, /*70000C1A//_dmsc_iNearGrayDesat */
+ 0x0F121E10, /*70000C1C//_postdmsc_iBCoeff */
+ 0x0F12000B, /*70000C1E//_postdmsc_iWideMult */
+ 0x0F120607, /*70000C20//_yuvemix_mNegSlopes_1 */
+ 0x0F120005, /*70000C22//_yuvemix_mNegSlopes_3 */
+ 0x0F120607, /*70000C24//_yuvemix_mPosSlopes_1 */
+ 0x0F120405, /*70000C26//_yuvemix_mPosSlopes_3 */
+ 0x0F120206, /*70000C28//_yuviirnr_iXSupportUV */
+ 0x0F120304, /*70000C2A//_yuviirnr_iHighYNorm */
+ 0x0F120409, /*70000C2C//_yuviirnr_iHighUVNorm */
+ 0x0F120305, /*70000C2E//_yuviirnr_iUVNormShift */
+ 0x0F120406, /*70000C30//_yuviirnr_iVertLength_UV */
+ 0x0F122804, /*70000C32//_yuviirnr_iDiffThreshH_Y */
+ 0x0F120228, /*70000C34//_yuviirnr_iDiffThreshH_UV */
+ 0x0F121402, /*70000C36//_yuviirnr_iMaxThreshH_Y */
+ 0x0F120618, /*70000C38//_yuviirnr_iMaxThreshH_UV */
+ 0x0F121A02, /*70000C3A//_yuviirnr_iYNRStrengthH */
+ 0x0F128018, /*70000C3C//_yuviirnr_iUVNRStrengthH */
+ 0x0F120080, /*70000C3E//_RGBGamma2_iLinearity */
+ 0x0F120080, /*70000C40//_ccm_oscar_iSaturation */
+ 0x0F120180, /*70000C42//_RGB2YUV_iRGBGain */
+ 0x0F120A0A, /*70000C44//_bnr_iClustMulT_H */
+ 0x0F120101, /*70000C46//_bnr_iClustThresh_H */
+ 0x0F120F15, /*70000C48//_bnr_iDenThreshLow */
+ 0x0F126024, /*70000C4A//_ee_iLowSharpPower */
+ 0x0F120A0A, /*70000C4C//_ee_iLowShDenoise */
+ 0x0F12FFFF, /*70000C4E//_ee_iLowSharpClamp */
+ 0x0F120808, /*70000C50//_ee_iReduceEdgeMinMult */
+ 0x0F120A01, /*70000C52//_bnr_nClustLevel_H_Bin */
+ 0x0F12010A, /*70000C54//_bnr_iClustMulT_C_Bin */
+ 0x0F120001, /*70000C56//_bnr_iClustThresh_C_Bin */
+ 0x0F122400, /*70000C58//_bnr_iDenThreshHigh_Bin */
+ 0x0F120260, /*70000C5A//_ee_iHighSharpPower_Bin */
+ 0x0F12FF02, /*70000C5C//_ee_iHighShDenoise_Bin */
+ 0x0F1240FF, /*70000C5E//_ee_iHighSharpClamp_Bin */
+ 0x0F120009, /*70000C60//_ee_iReduceEdgeSlope_Bin */
+ 0x0F120001, /*70000C62//_bnr_nClustLevel_C */
+ 0x0F120000, /*70000C64//_BRIGHTNESS AFIT 4 */
+ 0x0F120000, /*70000C66//_CONTRAST */
+ 0x0F120000, /*70000C68//_SATURATION */
+ 0x0F120000, /*70000C6A//_SHARP_BLUR */
+ 0x0F120000, /*70000C6C//_GLAMOUR */
+ 0x0F1200C0, /*70000C6E//_bnr_edge_high */
+ 0x0F120064, /*70000C70//_postdmsc_iLowBright */
+ 0x0F120384, /*70000C72//_postdmsc_iHighBright */
+ 0x0F120032, /*70000C74//_postdmsc_iLowSat */
+ 0x0F1201F4, /*70000C76//_postdmsc_iHighSat */
+ 0x0F120070, /*70000C78//_postdmsc_iTune */
+ 0x0F120040, /*70000C7A//_yuvemix_mNegRanges_0 */
+ 0x0F1200A0, /*70000C7C//_yuvemix_mNegRanges_1 */
+ 0x0F120100, /*70000C7E//_yuvemix_mNegRanges_2 */
+ 0x0F120010, /*70000C80//_yuvemix_mPosRanges_0 */
+ 0x0F120060, /*70000C82//_yuvemix_mPosRanges_1 */
+ 0x0F120100, /*70000C84//_yuvemix_mPosRanges_2 */
+ 0x0F121430, /*70000C86//_bnr_edge_low */
+ 0x0F120201, /*70000C88//_bnr_repl_force */
+ 0x0F120204, /*70000C8A//_bnr_iHotThreshLow */
+ 0x0F120F04, /*70000C8C//_bnr_iColdThreshLow */
+ 0x0F12030C, /*70000C8E//_bnr_DispTH_High */
+ 0x0F120003, /*70000C90//_bnr_DISP_Limit_High */
+ 0x0F120602, /*70000C92//_bnr_iDistSigmaMax */
+ 0x0F121803, /*70000C94//_bnr_iDiffSigmaHigh */
+ 0x0F120040, /*70000C96//_bnr_iNormalizedSTD_Limit */
+ 0x0F120E20, /*70000C98//_bnr_iDirMinThres */
+ 0x0F122018, /*70000C9A//_bnr_iDirFltDiffThresLow */
+ 0x0F120620, /*70000C9C//_bnr_iDirSmoothPowerLow */
+ 0x0F120306, /*70000C9E//_bnr_iHighMaxSlopeAllowed */
+ 0x0F122003, /*70000CA0//_bnr_iHighSlopeThresh */
+ 0x0F12FF01, /*70000CA2//_bnr_iSlopeBlurStrength */
+ 0x0F120404, /*70000CA4//_bnr_AddNoisePower1 */
+ 0x0F120200, /*70000CA6//_bnr_iRadialTune */
+ 0x0F12145A, /*70000CA8//_bnr_iRadialLimit */
+ 0x0F121010, /*70000CAA//_ee_iFSMagThHigh */
+ 0x0F12000B, /*70000CAC//_ee_iFSVarThHigh */
+ 0x0F121200, /*70000CAE//_ee_iFSThHigh */
+ 0x0F125A0F, /*70000CB0//_ee_iFSVarCountTh */
+ 0x0F120502, /*70000CB2//_ee_iRadialPower */
+ 0x0F121802, /*70000CB4//_ee_iROADThres */
+ 0x0F120000, /*70000CB6//_ee_iROADSubMaxNR */
+ 0x0F122006, /*70000CB8//_ee_iROADNeiThres */
+ 0x0F124028, /*70000CBA//_ee_iSmoothEdgeThres */
+ 0x0F120430, /*70000CBC//_ee_iWSharpen */
+ 0x0F120101, /*70000CBE//_ee_iWShThresh */
+ 0x0F12FF00, /*70000CC0//_ee_iEmbossCentAdd */
+ 0x0F120804, /*70000CC2//_ee_iReduceEdgeThresh */
+ 0x0F124008, /*70000CC4//_dmsc_iDesatThresh */
+ 0x0F120540, /*70000CC6//_dmsc_iDemBlurLow */
+ 0x0F128006, /*70000CC8//_dmsc_iDecisionThresh */
+ 0x0F120020, /*70000CCA//_dmsc_iMonochrom */
+ 0x0F120000, /*70000CCC//_dmsc_iGRDenoiseVal */
+ 0x0F122000, /*70000CCE//_dmsc_iEdgeDesatThrLow */
+ 0x0F120000, /*70000CD0//_dmsc_iNearGrayDesat */
+ 0x0F121E10, /*70000CD2//_postdmsc_iBCoeff */
+ 0x0F12000B, /*70000CD4//_postdmsc_iWideMult */
+ 0x0F120607, /*70000CD6//_yuvemix_mNegSlopes_1 */
+ 0x0F120005, /*70000CD8//_yuvemix_mNegSlopes_3 */
+ 0x0F120607, /*70000CDA//_yuvemix_mPosSlopes_1 */
+ 0x0F120405, /*70000CDC//_yuvemix_mPosSlopes_3 */
+ 0x0F120205, /*70000CDE//_yuviirnr_iXSupportUV */
+ 0x0F120304, /*70000CE0//_yuviirnr_iHighYNorm */
+ 0x0F120409, /*70000CE2//_yuviirnr_iHighUVNorm */
+ 0x0F120306, /*70000CE4//_yuviirnr_iUVNormShift */
+ 0x0F120407, /*70000CE6//_yuviirnr_iVertLength_UV */
+ 0x0F122C04, /*70000CE8//_yuviirnr_iDiffThreshH_Y */
+ 0x0F12022C, /*70000CEA//_yuviirnr_iDiffThreshH_UV */
+ 0x0F121402, /*70000CEC//_yuviirnr_iMaxThreshH_Y */
+ 0x0F120618, /*70000CEE//_yuviirnr_iMaxThreshH_UV */
+ 0x0F121A02, /*70000CF0//_yuviirnr_iYNRStrengthH */
+ 0x0F128018, /*70000CF2//_yuviirnr_iUVNRStrengthH */
+ 0x0F120080, /*70000CF4//_RGBGamma2_iLinearity */
+ 0x0F120080, /*70000CF6//_ccm_oscar_iSaturation */
+ 0x0F120180, /*70000CF8//_RGB2YUV_iRGBGain */
+ 0x0F120A0A, /*70000CFA//_bnr_iClustMulT_H */
+ 0x0F120101, /*70000CFC//_bnr_iClustThresh_H */
+ 0x0F120C0F, /*70000CFE//_bnr_iDenThreshLow */
+ 0x0F126024, /*70000D00//_ee_iLowSharpPower */
+ 0x0F120808, /*70000D02//_ee_iLowShDenoise */
+ 0x0F12FFFF, /*70000D04//_ee_iLowSharpClamp */
+ 0x0F120808, /*70000D06//_ee_iReduceEdgeMinMult */
+ 0x0F120A01, /*70000D08//_bnr_nClustLevel_H_Bin */
+ 0x0F12010A, /*70000D0A//_bnr_iClustMulT_C_Bin */
+ 0x0F120001, /*70000D0C//_bnr_iClustThresh_C_Bin */
+ 0x0F122400, /*70000D0E//_bnr_iDenThreshHigh_Bin */
+ 0x0F120060, /*70000D10//_ee_iHighSharpPower_Bin */
+ 0x0F12FF00, /*70000D12//_ee_iHighShDenoise_Bin */
+ 0x0F1240FF, /*70000D14//_ee_iHighSharpClamp_Bin */
+ 0x0F120009, /*70000D16//_ee_iReduceEdgeSlope_Bin */
+ 0x0F120001, /*70000D18//_bnr_nClustLevel_C */
+
+ 0x0F1223CE, /*70000D1A//[0]CAFITB_bnr_bypass */
+ 0x0F12FDC8, /*70000D1C//[0]CAFITB_bnr_bSlopenessTune */
+ 0x0F12112E, /*70000D1E//[0]CAFITB_ee_bReduceNegMedSh */
+ 0x0F1293A5, /*70000D20//[0]CAFITB_dmsc_bDoDesat */
+ 0x0F12FE67, /*70000D22//[0]CAFITB_postdmsc_bSat */
+ 0x0F120000, /*70000D24//[0]CAFITB_yuviirnr_bWideY */
+
+/*=======================================================
+// 06.Clock Setting
+//=======================================================*/
+/*Input Clock (Mclk)*/
+ 0x002A01F8,
+ 0x0F125DC0, /*REG_TC_IPRM_InClockLSBs */
+ 0x002A0212,
+ 0x0F120000, /*REG_TC_IPRM_UseNPviClocks */
+ 0x0F120002, /*REG_TC_IPRM_UseNMipiClocks */
+ 0x0F120002, /*REG_TC_IPRM_NumberOfMipiLanes */
+
+/*System Clock & Output clock (Pclk)*/
+
+ 0x002A021A,
+ 0x0F123A98, /*REG_TC_IPRM_OpClk4KHz_0 */
+ 0x0F12278D, /*4F1A //REG_TC_IPRM_MinOutRate4KHz_0 */
+ 0x0F12278D, /*4F1A //REG_TC_IPRM_MaxOutRate4KHz_0 */
+
+ 0x0F124F1A, /*REG_TC_IPRM_OpClk4KHz_11 */
+ 0x0F12278D, /*4F1A //REG_TC_IPRM_MinOutRate4KHz_1 */
+ 0x0F12278D, /*4F1A //REG_TC_IPRM_MaxOutRate4KHz_1 */
+
+ 0x002A022C,
+ 0x0F120001, /*REG_TC_IPRM_InitParamsUpdated */
+
+/*=============================================================
+// 18.JPEG Thumnail Setting
+//=============================================================*/
+
+ 0x002A0478,
+ 0x0F12005F, /*REG_TC_BRC_usPrevQuality */
+ 0x0F12005F, /*REG_TC_BRC_usCaptureQuality */
+
+/*JPEG Thumnail*/
+ 0x0F120001, /*REG_TC_THUMB_Thumb_bActive */
+ 0x0F120280, /*REG_TC_THUMB_Thumb_uWidth */
+ 0x0F1201E0, /*REG_TC_THUMB_Thumb_uHeight */
+ 0x0F120005, /*REG_TC_THUMB_Thumb_Format */
+
+ 0x002A17DC,
+ 0x0F120054, /*jpeg_ManualMBCV */
+ 0x002A1AE4,
+ 0x0F12001C, /*senHal_bExtraAddLine */
+ 0x002A0284,
+ 0x0F120001, /*REG_TC_GP_bBypassScalerJpg */
+ 0x002A028A,
+ 0x0F120000, /*REG_TC_GP_bUse1FrameCaptureMode */
+
+ 0x002A1CC2, /*DRx_uDRxWeight for AutoCont function */
+ 0x0F120100,
+ 0x0F120100,
+ 0x0F120100,
+ 0x0F120100,
+ 0x002A147C, /*bp_uMaxBrightnessFactor*/
+ 0x0F120170,
+ 0x002A1482, /*bp_uMinBrightnessFactor */
+ 0x0F1201E0,
+
+/*=======================================================
+// 07.Input Size Setting
+//======================================================*/
+/*Input Size*/
+ 0x002A0250,
+ 0x0F120A00, /*REG_TC_GP_PrevReqInputWidth */
+ 0x0F120780, /*REG_TC_GP_PrevReqInputHeight */
+ 0x0F120010, /*REG_TC_GP_PrevInputWidthOfs */
+ 0x0F12000C, /*REG_TC_GP_PrevInputHeightOfs */
+ 0x0F120A00, /*REG_TC_GP_CapReqInputWidth */
+ 0x0F120780, /*REG_TC_GP_CapReqInputHeight */
+ 0x0F120010, /*REG_TC_GP_CapInputWidthOfs */
+ 0x0F12000C, /*REG_TC_GP_CapInputHeightOfs */
+
+ 0x002A0262,
+ 0x0F120001, /*REG_TC_GP_bUseReqInputInPre */
+ 0x0F120001, /*REG_TC_GP_bUseReqInputInCap */
+
+ 0x002A0494,
+ 0x0F120A00, /*REG_TC_PZOOM_PrevZoomReqInputWidth */
+ 0x0F120780, /*REG_TC_PZOOM_PrevZoomReqInputHeight */
+ 0x0F120000, /*REG_TC_PZOOM_PrevZoomReqInputWidthOfs */
+ 0x0F120000, /*REG_TC_PZOOM_PrevZoomReqInputHeightOfs */
+ 0x0F120A00, /*REG_TC_PZOOM_CapZoomReqInputWidth */
+ 0x0F120780, /*REG_TC_PZOOM_CapZoomReqInputHeight */
+ 0x0F120000, /*REG_TC_PZOOM_CapZoomReqInputWidthOfs */
+ 0x0F120000, /*REG_TC_PZOOM_CapZoomReqInputHeightOfs */
+
+/*===========================================================
+// 08.Preview & Capture Configration Setting
+//=======================================================*/
+/*Preview config[0] 640 480 10~30fps*/
+ 0x002A02A6,
+ 0x0F120280, /*REG_0TC_PCFG_usWidth */
+ 0x0F1201E0, /*REG_0TC_PCFG_usHeight */
+ 0x0F120005, /*REG_0TC_PCFG_Format */
+ 0x0F12278D, /*4F1A //REG_0TC_PCFG_usMaxOut4KHzRate */
+ 0x0F12278D, /*4F1A //REG_0TC_PCFG_usMinOut4KHzRate */
+ 0x0F120100, /*REG_0TC_PCFG_OutClkPerPix88 */
+ 0x0F120300, /*REG_0TC_PCFG_uBpp88 */
+ 0x0F120012, /*REG_0TC_PCFG_PVIMask */
+ 0x0F120000, /*REG_0TC_PCFG_OIFMask */
+ 0x0F1201E0, /*REG_0TC_PCFG_usJpegPacketSize */
+ 0x0F120000, /*REG_0TC_PCFG_usJpegTotalPackets */
+ 0x0F120000, /*REG_0TC_PCFG_uClockInd */
+ 0x0F120000, /*REG_0TC_PCFG_usFrTimeType */
+ 0x0F120001, /*REG_0TC_PCFG_FrRateQualityType */
+ 0x0F1203E8, /*029A //REG_0TC_PCFG_usMaxFrTimeMsecMult10 */
+ 0x0F12014A, /*REG_0TC_PCFG_usMinFrTimeMsecMult10 */
+ 0x002A02D0,
+ 0x0F120000, /*REG_0TC_PCFG_uPrevMirror 0711 0000->000A */
+ 0x0F120000, /*REG_0TC_PCFG_uCaptureMirror 0711 0000->000A */
+
+/*Capture Config[0] 2560 1920 7.5~15fps*/
+ 0x002A0396,
+ 0x0F120000, /*REG_0TC_CCFG_uCaptureMode */
+ 0x0F120A00, /*REG_0TC_CCFG_usWidth */
+ 0x0F120780, /*REG_0TC_CCFG_usHeight */
+ 0x0F120009, /*REG_0TC_CCFG_Format */
+ 0x0F12278D, /*4F1A //REG_0TC_CCFG_usMaxOut4KHzRate */
+ 0x0F12278D, /*4F1A //REG_0TC_CCFG_usMinOut4KHzRate */
+ 0x0F120100, /*REG_0TC_CCFG_OutClkPerPix88 */
+ 0x0F120300, /*REG_0TC_CCFG_uBpp88 */
+ 0x0F120012, /*REG_0TC_CCFG_PVIMask */
+ 0x0F120040, /*REG_0TC_CCFG_OIFMask */
+ 0x0F120810, /*REG_0TC_CCFG_usJpegPacketSize */
+ 0x0F120000, /*REG_0TC_CCFG_usJpegTotalPackets */
+ 0x0F120001, /*REG_0TC_CCFG_uClockInd */
+ 0x0F120000, /*REG_0TC_CCFG_usFrTimeType */
+ 0x0F120002, /*REG_0TC_CCFG_FrRateQualityType */
+ 0x0F120535, /*REG_0TC_CCFG_usMaxFrTimeMsecMult10 */
+ 0x0F12029A, /*REG_0TC_CCFG_usMinFrTimeMsecMult10 */
+
+/* Delay 100ms*/
+
+/*===========================================================
+// 19.Select Cofigration Display
+//===========================================================*/
+ /*PREVIEW*/
+ 0x002A0266,
+ 0x0F120000, /*REG_TC_GP_ActivePrevConfig */
+ 0x002A026A,
+ 0x0F120001, /*REG_TC_GP_PrevOpenAfterChange */
+ 0x002A024E,
+ 0x0F120001, /*REG_TC_GP_NewConfigSync */
+ 0x002A0268,
+ 0x0F120001, /*REG_TC_GP_PrevConfigChanged */
+ 0x002A0270,
+ 0x0F120001, /*REG_TC_GP_CapConfigChanged */
+ 0x002A023E,
+ 0x0F120001, /*REG_TC_GP_EnablePreview */
+ 0x0F120001, /*REG_TC_GP_EnablePreviewChanged */
+
+ 0x00287000,
+ 0x002A0484,
+ 0x0F120002, /* capture flash on */
+
+ 0x002A183A,
+ 0x0F120001, /* one frame AE */
+
+ 0x002A17F6,
+ 0x0F12023C, /*210, 258 // AWB R point */
+ 0x0F12020C, /*288, 228 ->258 -> 208 // AWB B point */
+
+ 0x002A1840,
+ 0x0F120001, /* Fls AE tune start */
+
+ 0x0F120100, /* fls_afl_FlsAFIn Rin */
+ 0x0F120120,
+ 0x0F120180,
+ 0x0F120200,
+ 0x0F120400,
+ 0x0F120800,
+ 0x0F120A00,
+ 0x0F121000,
+
+ 0x0F120100, /* fls_afl_FlsAFOut Rout */
+ 0x0F1200A0,
+ 0x0F120090,
+ 0x0F120080,
+ 0x0F120070,
+ 0x0F120045,
+ 0x0F120030,
+ 0x0F120010,
+
+ 0x002A1884,
+ 0x0F120100, /* fls_afl_FlsNBOut flash NB default */
+ 0x0F120100,
+ 0x0F120100,
+ 0x0F120100,
+ 0x0F120100,
+ 0x0F120100,
+ 0x0F120100,
+ 0x0F120100,
+
+ 0x002A1826,
+
+ 0x0F120100, /* fls_afl_FlashWP_Weight flash NB default */
+ 0x0F1200C0,
+ 0x0F120080,
+ 0x0F12000A,
+ 0x0F120000,
+
+ 0x0F120030, /* fls_afl_FlashWP_Weight flash NB default */
+ 0x0F120040,
+ 0x0F120048,
+ 0x0F120050,
+ 0x0F120060,
+
+ 0x002A4784,
+ 0x0F1200A0, /*TNP_Regs_FlsWeightRIn weight tune start in */
+ 0x0F1200C0,
+ 0x0F1200D0,
+ 0x0F120100,
+ 0x0F120200,
+ 0x0F120300,
+
+ 0x0F120088, /* TNP_Regs_FlsWeightROut weight tune start out */
+ 0x0F1200B0,
+ 0x0F1200C0,
+ 0x0F120100,
+ 0x0F120200,
+ 0x0F120300,
+
+ 0x002A479C,
+
+ 0x0F120120, /*Fls BRIn */
+ 0x0F120150,
+ 0x0F120200,
+
+ 0x0F12003C, /* Fls BROut */
+ 0x0F12003B,
+ 0x0F120026, /*brightness // 23 //26 //30 */
+};
+
+static const u32 s5k4ecgx_DTP_init_EVT1[] = {
+/*Delay 500ms*/
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A0944,
+ 0x0F12FFF0, /*af_uNoise_0_*/
+ 0x0F12FFF1, /*afit_uNoiseIndInDoor_1_ */
+ 0x0F12FFF2, /*afit_uNoiseIndInDoor_2_ */
+ 0x0F12FFF3, /*afit_uNoiseIndInDoor_3_ */
+ 0x0F12FFF4, /*afit_uNoiseIndInDoor_4_ */
+ 0x002A0938,
+ 0x0F120000, /*afit_bUseNB_Afit */
+ 0x0F12FFF0, /*SARR_uNormBrInDoor_0_ */
+ 0x0F12FFF1, /*SARR_uNormBrInDoor_1_ */
+ 0x0F12FFF2, /*SARR_uNormBrInDoor_2_ */
+ 0x0F12FFF3, /*SARR_uNormBrInDoor_3_ */
+ 0x0F12FFF4, /*SARR_uNormBrInDoor_4_ */
+ 0x00287000,
+ 0x002A04A6,
+ 0x0F120001,
+ 0x002A04AA,
+ 0x0F120001,
+ 0x0028D000,
+ 0x002A4200,
+ 0x0F1208A3, /*GAS bypass */
+ 0x002A6600,
+ 0x0F120001, /*CCM bypass */
+ 0x002A6700,
+ 0x0F120001, /*Gamma bypass */
+ 0x002A4900,
+ 0x0F120001, /*AWB bypass */
+
+/*Delay 50ms*/
+ 0x0028D000,
+ 0x002A3100,
+ 0x0F120002, /*Colorbar pattern */
+
+};
+
+static const u32 s5k4ecgx_DTP_stop_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A0944,
+ 0x0F12004B, /*afit_uNoiser0*/
+ 0x0F120092, /*afit_uNoiseIndInDoor_1_ */
+ 0x0F120196, /*afit_uNoiseIndInDoor_2_ */
+ 0x0F120217, /*afit_uNoiseIndInDoor_3_ */
+ 0x0F1202B0, /*afit_uNoiseIndInDoor_4_ */
+
+ /* Normal Brightness setting */
+ 0x002A0938,
+ 0x0F120000, /*afit_bUseNB_Afit */
+ 0x0F120014, /*SARR_uNormBrInDoor_0_ */
+ 0x0F1200D2, /*SARR_uNormBrInDoor_1_ */
+ 0x0F120384, /*SARR_uNormBrInDoor_2_ */
+ 0x0F1207D0, /*SARR_uNormBrInDoor_3_ */
+ 0x0F121388, /*SARR_uNormBrInDoor_4_ */
+ 0x00287000,
+ 0x002A04A6,
+ 0x0F120000,
+ 0x002A04AA,
+ 0x0F120001,
+ 0x0028D000,
+ 0x002A4200,
+ 0x0F1208A2, /*GAS bypass */
+ 0x002A6600,
+ 0x0F120000, /*CCM bypass */
+ 0x002A6700,
+ 0x0F120000, /*Gamma bypass */
+ 0x002A4900,
+ 0x0F120000, /*AWB bypass */
+ 0xFFFE0032, /*p50 */
+ 0x0028D000,
+ 0x002A3100,
+ 0x0F120000, /*Colorbar pattern */
+
+};
+
+static const u32 s5k4ecgx_FPS_Auto_EVT1[] = {
+/* frame rate 10~30fps*/
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A02BE,
+ 0x0F120000, /*usFrTimeType*/
+ 0x0F120001, /*REG_0TC_PCFG_FrRateQualityType */
+ 0x0F1203E8, /*029A/REG_0TC_PCFG_usMaxFrTimeMsecMult10 029Ah:15fps*/
+ 0x0F12014A, /*REG_0TC_PCFG_usMinFrTimeMsecMult10 //014Ah:30fps*/
+ 0x002A0266,
+ 0x0F120000, /*REG_TC_GP_ActivePrevConfig */
+ 0x002A026A,
+ 0x0F120001, /*REG_TC_GP_PrevOpenAfterChange */
+ 0x002A024E,
+ 0x0F120001, /*REG_TC_GP_NewConfigSync */
+ 0x002A0268,
+ 0x0F120001, /*REG_TC_GP_PrevConfigChanged */
+};
+
+static const u32 s5k4ecgx_FPS_5_EVT1[] = {
+
+};
+
+static const u32 s5k4ecgx_FPS_7_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A02BE,
+ 0x0F120000, /*REG_0TC_PCFG_usFrTimeType */
+ 0x0F120001, /*REG_0TC_PCFG_FrRateQualityType*/
+ 0x0F120535, /*REG_0TC_PCFG_usMaxFrTimeMsecMult10 //0535h:7.5fps */
+ 0x0F120535, /*REG_0TC_PCFG_usMinFrTimeMsecMult10 //0535h:7.5fps */
+
+ 0x002A0266,
+ 0x0F120000, /*REG_TC_GP_ActivePrevConfig */
+ 0x002A026A,
+ 0x0F120001, /*REG_TC_GP_PrevOpenAfterChange */
+ 0x002A024E,
+ 0x0F120001, /*REG_TC_GP_NewConfigSync */
+ 0x002A0268,
+ 0x0F120001, /*REG_TC_GP_PrevConfigChanged */
+
+};
+
+static const u32 s5k4ecgx_FPS_10_EVT1[] = {
+
+};
+
+static const u32 s5k4ecgx_FPS_15_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A02BE,
+ 0x0F120000, /*REG_0TC_PCFG_usFrTimeType */
+ 0x0F120001, /*REG_0TC_PCFG_FrRateQualityType */
+ 0x0F12029A, /*REG_0TC_PCFG_usMaxFrTimeMsecMult10 //029Ah:15fps */
+ 0x0F12029A, /*REG_0TC_PCFG_usMinFrTimeMsecMult10 //029Ah:15fps */
+
+ 0x002A0266,
+ 0x0F120000, /*REG_TC_GP_ActivePrevConfig */
+ 0x002A026A,
+ 0x0F120001, /*REG_TC_GP_PrevOpenAfterChange */
+ 0x002A024E,
+ 0x0F120001, /*REG_TC_GP_NewConfigSync */
+ 0x002A0268,
+ 0x0F120001, /*REG_TC_GP_PrevConfigChanged */
+
+};
+
+static const u32 s5k4ecgx_FPS_20_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A02BE,
+ 0x0F120000, /*REG_0TC_PCFG_usFrTimeType */
+ 0x0F120001, /*REG_0TC_PCFG_FrRateQualityType */
+ 0x0F1201F4, /*REG_0TC_PCFG_usMaxFrTimeMsecMult10 //01F4h:20fps */
+ 0x0F1201F4, /*REG_0TC_PCFG_usMinFrTimeMsecMult10 //01F4h:20fps */
+
+ 0x002A0266,
+ 0x0F120000, /*REG_TC_GP_ActivePrevConfig */
+ 0x002A026A,
+ 0x0F120001, /*REG_TC_GP_PrevOpenAfterChange */
+ 0x002A024E,
+ 0x0F120001, /*REG_TC_GP_NewConfigSync */
+ 0x002A0268,
+ 0x0F120001, /*REG_TC_GP_PrevConfigChanged */
+};
+
+static const u32 s5k4ecgx_FPS_24_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A02B4,
+ 0x0F120052,
+ 0x002A02BE,
+ 0x0F120000,
+ 0x0F120001,
+ 0x0F1201A1,
+ 0x0F1201A1,
+ 0x002A02D0,
+ 0x0F120000,
+ 0x0F120000,
+ 0x002A0266,
+ 0x0F120000,
+ 0x002A026A,
+ 0x0F120001,
+ 0x002A024E,
+ 0x0F120001,
+ 0x002A0268,
+ 0x0F120001,
+};
+
+static const u32 s5k4ecgx_FPS_25_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A02BE,
+ 0x0F120000, /*REG_0TC_PCFG_usFrTimeType */
+ 0x0F120001, /*REG_0TC_PCFG_FrRateQualityType */
+ 0x0F120190, /*REG_0TC_PCFG_usMaxFrTimeMsecMult10 //014Ah:30fps */
+ 0x0F120190, /*REG_0TC_PCFG_usMinFrTimeMsecMult10 //014Ah:30fps */
+
+ 0x002A0266,
+ 0x0F120000, /*REG_TC_GP_ActivePrevConfig */
+ 0x002A026A,
+ 0x0F120001, /*REG_TC_GP_PrevOpenAfterChange */
+ 0x002A024E,
+ 0x0F120001, /*REG_TC_GP_NewConfigSync */
+ 0x002A0268,
+ 0x0F120001, /*REG_TC_GP_PrevConfigChanged */
+};
+
+
+static const u32 s5k4ecgx_FPS_30_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A02BE,
+ 0x0F120000, /*REG_0TC_PCFG_usFrTimeType */
+ 0x0F120001, /*REG_0TC_PCFG_FrRateQualityType */
+ 0x0F12014A, /*REG_0TC_PCFG_usMaxFrTimeMsecMult10 //014Ah:30fps */
+ 0x0F12014A, /*REG_0TC_PCFG_usMinFrTimeMsecMult10 //014Ah:30fps */
+
+ 0x002A0266,
+ 0x0F120000, /*REG_TC_GP_ActivePrevConfig */
+ 0x002A026A,
+ 0x0F120001, /*REG_TC_GP_PrevOpenAfterChange */
+ 0x002A024E,
+ 0x0F120001, /*REG_TC_GP_NewConfigSync */
+ 0x002A0268,
+ 0x0F120001, /*REG_TC_GP_PrevConfigChanged */
+
+};
+
+static const u32 s5k4ecgx_FPS_60_EVT1[] = {
+
+};
+
+static const u32 s5k4ecgx_FPS_120_EVT1[] = {
+
+};
+
+static const u32 s5k4ecgx_Effect_Normal_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A023C,
+ 0x0F120000,
+};
+
+static const u32 s5k4ecgx_Effect_Solarization_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A023C,
+ 0x0F120002,
+};
+
+static const u32 s5k4ecgx_Effect_Negative_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A023C,
+ 0x0F120003,
+};
+
+static const u32 s5k4ecgx_Effect_Sepia_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A023C,
+ 0x0F120004,
+};
+
+static const u32 s5k4ecgx_Effect_Black_White_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A023C,
+ 0x0F120001,
+};
+
+static const u32 s5k4ecgx_WB_Auto_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+};
+
+static const u32 s5k4ecgx_WB_Sunny_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A04BA,
+ 0x0F1205C0,
+
+ 0x002A04BE,
+ 0x0F1203D0,
+
+ 0x002A04C2,
+ 0x0F120550,
+
+ 0x002A04C6,
+ 0x0F120001,
+};
+
+static const u32 s5k4ecgx_WB_Cloudy_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A04BA,
+ 0x0F1206D8,
+
+ 0x002A04BE,
+ 0x0F1203D0,
+
+ 0x002A04C2,
+ 0x0F1204B0,
+
+ 0x002A04C6,
+ 0x0F120001,
+};
+
+static const u32 s5k4ecgx_WB_Tungsten_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A04BA,
+ 0x0F1203B0,
+
+ 0x002A04BE,
+ 0x0F1203D0,
+
+ 0x002A04C2,
+ 0x0F1209B0,
+ 0x002A04C6,
+ 0x0F120001,
+};
+
+static const u32 s5k4ecgx_WB_Fluorescent_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A04BA,
+ 0x0F1205E0,
+
+ 0x002A04BE,
+ 0x0F120440,
+
+ 0x002A04C2,
+ 0x0F120998,
+
+ 0x002A04C6,
+ 0x0F120001,
+};
+
+static const u32 s5k4ecgx_WB_Auto_ISO_on_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002a04E6,
+ 0x0f12075F,
+};
+
+static const u32 s5k4ecgx_WB_Sunny_ISO_on_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A04E6,
+ 0x0f120757,
+ 0x002A04BA,
+ 0x0F1205C0,
+
+ 0x002A04BE,
+ 0x0F1203D0,
+
+ 0x002A04C2,
+ 0x0F120580,
+ 0x002A04C6,
+ 0x0F120001,
+};
+
+static const u32 s5k4ecgx_WB_Cloudy_ISO_on_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A04E6,
+ 0x0f120757,
+ 0x002A04BA,
+ 0x0F1206E0,
+
+ 0x002A04BE,
+ 0x0F1203D0,
+
+ 0x002A04C2,
+ 0x0F1204B0,
+ 0x002A04C6,
+ 0x0F120001,
+};
+
+static const u32 s5k4ecgx_WB_Tungsten_ISO_on_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A04E6,
+ 0x0f120757,
+ 0x002A04BA,
+ 0x0F1203B0,
+
+ 0x002A04BE,
+ 0x0F1203D0,
+
+ 0x002A04C2,
+ 0x0F1209F0,
+ 0x002A04C6,
+ 0x0F120001,
+};
+
+static const u32 s5k4ecgx_WB_Fluorescent_ISO_on_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A04E6,
+ 0x0f120757,
+ 0x002A04BA,
+ 0x0F120600,
+
+ 0x002A04BE,
+ 0x0F120440,
+
+ 0x002A04C2,
+ 0x0F1209E0,
+ 0x002A04C6,
+ 0x0F120001,
+};
+
+static const u32 s5k4ecgx_WDR_on_EVT1[] = {
+
+};
+
+static const u32 s5k4ecgx_WDR_off_EVT1[] = {
+
+};
+
+static const u32 s5k4ecgx_ISO_Auto_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A0938, /*afit_bUseNB_Afit */
+ 0x0F120000,
+ 0x0F120014, /*SARR_uNormBrInDoor_0_*/
+ 0x0F1200D2, /*SARR_uNormBrInDoor_1_ */
+ 0x0F120384, /*SARR_uNormBrInDoor_2_ */
+ 0x0F1207D0, /*SARR_uNormBrInDoor_3_ */
+ 0x0F121388, /*SARR_uNormBrInDoor_4_ */
+ 0x002A1484,
+ 0x0F12003C,
+ 0x002A0F2A, /*AFC_Default60Hz */
+ 0x0F120000, /*00:50Hz 01:60Hz */
+ 0x002A04D0,
+ 0x0F120000, /*REG_SF_USER_IsoType */
+ 0x0F120000, /*REG_SF_USER_IsoVal */
+ 0x0F120001, /*REG_SF_USER_IsoChanged */
+ 0x002A06C2,
+ 0x0F120200, /*lt_bUseSecISODgain */
+};
+
+static const u32 s5k4ecgx_ISO_50_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A0938,
+ 0x0F120001, /*afit_bUseNB_Afit */
+ 0x0F120014, /*SARR_uNormBrInDoor_0_ */
+ 0x0F1200D2, /*SARR_uNormBrInDoor_1_ */
+ 0x0F120384, /*SARR_uNormBrInDoor_2_ */
+ 0x0F1207D0, /*SARR_uNormBrInDoor_3_ */
+ 0x0F121388, /*SARR_uNormBrInDoor_4_ */
+ 0x002A04D6,
+ 0x0F120000, /*REG_SF_USER_FlickerQuant */
+ 0x0F120001, /*REG_SF_USER_FlickerQuantChanged */
+ 0x002A04D0,
+ 0x0F120001, /*REG_SF_USER_IsoType*/
+ 0x0F120100, /*REG_SF_USER_IsoVal */
+ 0x0F120001, /*REG_SF_USER_IsoChanged */
+ 0x002A06C2,
+ 0x0F120100, /*lt_bUseSecISODgain */
+};
+
+static const u32 s5k4ecgx_ISO_100_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A0938,
+ 0x0F120001, /*afit_bUseNB_Afit */
+ 0x0F120014, /*SARR_uNormBrInDoor_0_ */
+ 0x0F1200D2, /*SARR_uNormBrInDoor_1_ */
+ 0x0F120384, /*SARR_uNormBrInDoor_2_ */
+ 0x0F1207D0, /*SARR_uNormBrInDoor_3_ */
+ 0x0F121388, /*SARR_uNormBrInDoor_4_ */
+ 0x002A1484,
+ 0x0F120044,
+ 0x002A04D6,
+ 0x0F120000, /*REG_SF_USER_FlickerQuant */
+ 0x0F120001, /*REG_SF_USER_FlickerQuantChanged */
+ 0x002A04D0,
+ 0x0F120001, /*REG_SF_USER_IsoType */
+ 0x0F12018A, /*REG_SF_USER_IsoVal/1BA/1CA:16.9msec/1AA: 17.8msec */
+ 0x0F120001, /*REG_SF_USER_IsoChanged */
+ 0x002A06C2,
+ 0x0F120100, /*lt_bUseSecISODgain */
+};
+
+static const u32 s5k4ecgx_ISO_200_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A0938,
+ 0x0F120001, /*afit_bUseNB_Afit */
+ 0x0F120114, /*SARR_uNormBrInDoor_0_ */
+ 0x0F1204A2, /*SARR_uNormBrInDoor_1_ */
+ 0x0F120584, /*SARR_uNormBrInDoor_2_ */
+ 0x0F1208D0, /*SARR_uNormBrInDoor_3_ */
+ 0x0F121388, /*SARR_uNormBrInDoor_4_ */
+ 0x002A1484,
+ 0x0F120044,
+ 0x002A04D6,
+ 0x0F120000, /*REG_SF_USER_FlickerQuant */
+ 0x0F120001, /*REG_SF_USER_FlickerQuantChanged */
+ 0x002A04D0,
+ 0x0F120001, /*REG_SF_USER_IsoType */
+ 0x0F120300, /*REG_SF_IsoVal/36A/370:8.9msec/360:8.8msec/400:7.5msec*/
+ 0x0F120001, /*REG_SF_USER_IsoChanged */
+ 0x002A06C2,
+ 0x0F120100, /*lt_bUseSecISODgain */
+
+};
+
+static const u32 s5k4ecgx_ISO_400_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A0938,
+ 0x0F120001, /*afit_bUseNB_Afit */
+ 0x0F120214, /*SARR_uNormBrInDoor_0_ */
+ 0x0F120BD2, /*SARR_uNormBrInDoor_1_ */
+ 0x0F120C84, /*SARR_uNormBrInDoor_2_ */
+ 0x0F1210D0, /*SARR_uNormBrInDoor_3_ */
+ 0x0F121388, /*SARR_uNormBrInDoor_4_ */
+ 0x002A1484,
+ 0x0F120044,
+ 0x002A04D6,
+ 0x0F120000, /*REG_SF_USER_FlickerQuant */
+ 0x0F120001, /*REG_SF_USER_FlickerQuantChanged */
+ 0x002A04D0,
+ 0x0F120001, /*REG_SF_USER_IsoType */
+ 0x0F120764, /*REGSFUSER_IsoVal/6F4*/
+ 0x0F120001, /*REG_SF_USER_IsoChanged */
+ 0x002A06C2,
+ 0x0F120100, /*lt_bUseSecISODgain */
+};
+
+static const u32 s5k4ecgx_ISO_Auto_MWB_on_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A0938, /*afit_bUseNB_Afit */
+ 0x0F120000,
+ 0x0F120014, /*SARR_uNormBrInDoor_0_ */
+ 0x0F1200D2, /*SARR_uNormBrInDoor_1_ */
+ 0x0F120384, /*SARR_uNormBrInDoor_2_ */
+ 0x0F1207D0, /*SARR_uNormBrInDoor_3_ */
+ 0x0F121388, /*SARR_uNormBrInDoor_4_ */
+ 0x002A1484,
+ 0x0F12003C,
+ 0x002A0F2A, /*AFC_Default60Hz */
+ 0x0F120000, /*00:50Hz 01:60Hz */
+ 0x002A04E6, /*REG_TC_DBG_AutoAlgEnBits */
+ 0x0F120777,
+ 0x002A04D0,
+ 0x0F120000, /*REG_SF_USER_IsoType */
+ 0x0F120000, /*REG_SF_USER_IsoVal */
+ 0x0F120001, /*REG_SF_USER_IsoChanged */
+ 0x002A06C2,
+ 0x0F120200, /*lt_bUseSecISODgain */
+
+};
+
+static const u32 s5k4ecgx_ISO_50_MWB_on_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A0938,
+ 0x0F120001, /*afit_bUseNB_Afit*/
+ 0x0F120014, /*SARR_uNormBrInDoor_0_*/
+ 0x0F1200D2, /*SARR_uNormBrInDoor_1_*/
+ 0x0F120384, /*SARR_uNormBrInDoor_2_*/
+ 0x0F1207D0, /*SARR_uNormBrInDoor_3_*/
+ 0x0F121388, /*SARR_uNormBrInDoor_4_*/
+
+ 0x002A04E6,
+ 0x0F120757, /*REG_TC_DBG_AutoAlgEnBits */
+ 0x002A04D6,
+ 0x0F120000, /*REG_SF_USER_FlickerQuant */
+ 0x0F120001, /*REG_SF_USER_FlickerQuantChanged */
+
+ 0x002A04D0,
+ 0x0F120001, /*REG_SF_USER_IsoType */
+ 0x0F120100, /*REG_SF_USER_IsoVal */
+ 0x0F120001, /*REG_SF_USER_IsoChanged */
+ 0x002A06C2,
+ 0x0F120100, /*lt_bUseSecISODgain */
+};
+
+static const u32 s5k4ecgx_ISO_100_MWB_on_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A0938,
+ 0x0F120001, /*afit_bUseNB_Afit */
+ 0x0F120014, /*SARR_uNormBrInDoor_0_ */
+ 0x0F1200D2, /*SARR_uNormBrInDoor_1_ */
+ 0x0F120384, /*SARR_uNormBrInDoor_2_ */
+ 0x0F1207D0, /*SARR_uNormBrInDoor_3_ */
+ 0x0F121388, /*SARR_uNormBrInDoor_4_ */
+ 0x002A1484,
+ 0x0F120044,
+ 0x002A04E6,
+ 0x0F120757, /*REG_TC_DBG_AutoAlgEnBits */
+ 0x002A04D6,
+ 0x0F120000, /*REG_SF_USER_FlickerQuant */
+ 0x0F120001, /*REG_SF_USER_FlickerQuantChanged */
+
+ 0x002A04D0,
+ 0x0F120001, /*REG_SF_USER_IsoType */
+ 0x0F12018A, /*REG_SF_USER_IsoVal */
+ 0x0F120001, /*REG_SF_USER_IsoChanged */
+ 0x002A06C2,
+ 0x0F120100, /*lt_bUseSecISODgain */
+};
+
+static const u32 s5k4ecgx_ISO_200_MWB_on_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A0938,
+ 0x0F120001, /*afit_bUseNB_Afit */
+ 0x0F120014, /*SARR_uNormBrInDoor_0_ */
+ 0x0F1203A2, /*SARR_uNormBrInDoor_1_ */
+ 0x0F120484, /*SARR_uNormBrInDoor_2_ */
+ 0x0F1207D0, /*SARR_uNormBrInDoor_3_ */
+ 0x0F121388, /*SARR_uNormBrInDoor_4_ */
+ 0x002A1484,
+ 0x0F120044,
+ 0x002A04E6,
+ 0x0F120757, /*REG_TC_DBG_AutoAlgEnBits */
+ 0x002A04D6,
+ 0x0F120000, /*REG_SF_USER_FlickerQuant */
+ 0x0F120001, /*REG_SF_USER_FlickerQuantChanged */
+
+ 0x002A04D0,
+ 0x0F120001, /*REG_SF_USER_IsoType */
+ 0x0F120300, /*REG_SF_USER_IsoVal */
+ 0x0F120001, /*REG_SF_USER_IsoChanged */
+ 0x002A06C2,
+ 0x0F120100, /*lt_bUseSecISODgain */
+};
+
+static const u32 s5k4ecgx_ISO_400_MWB_on_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A0938,
+ 0x0F120001, /*afit_bUseNB_Afit */
+ 0x0F120014, /*SARR_uNormBrInDoor_0_ */
+ 0x0F1208D2, /*SARR_uNormBrInDoor_1_ */
+ 0x0F120C84, /*SARR_uNormBrInDoor_2_ */
+ 0x0F1210D0, /*SARR_uNormBrInDoor_3_ */
+ 0x0F121388, /*SARR_uNormBrInDoor_4_ */
+ 0x002A1484,
+ 0x0F120044,
+ 0x002A04E6,
+ 0x0F120757, /*REG_TC_DBG_AutoAlgEnBits */
+ 0x002A04D6,
+ 0x0F120000, /*REG_SF_USER_FlickerQuant */
+ 0x0F120001, /*REG_SF_USER_FlickerQuantChanged */
+
+ 0x002A04D0,
+ 0x0F120001, /*REG_SF_USER_IsoType */
+ 0x0F120764, /*REG_SF_USER_IsoVal */
+ 0x0F120001, /*REG_SF_USER_IsoChanged */
+ 0x002A06C2,
+ 0x0F120100, /*lt_bUseSecISODgain */
+};
+
+static const u32 s5k4ecgx_Metering_Matrix_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A1492,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+
+ 0x002A0268, /*REG_TC_GP_PrevConfigChanged */
+ 0x0F120001,
+};
+
+static const u32 s5k4ecgx_Metering_Center_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A1492,
+ 0x0F120100,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120001,
+ 0x0F120101,
+ 0x0F120201,
+ 0x0F120102,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120202,
+ 0x0F120202,
+ 0x0F120101,
+ 0x0F120201,
+ 0x0F120302,
+ 0x0F120203,
+ 0x0F120102,
+ 0x0F120201,
+ 0x0F120302,
+ 0x0F120203,
+ 0x0F120102,
+ 0x0F120101,
+ 0x0F120202,
+ 0x0F120202,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120201,
+ 0x0F120102,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+
+ 0x002A0268, /*REG_TC_GP_PrevConfigChanged */
+ 0x0F120001,
+};
+
+static const u32 s5k4ecgx_Metering_Spot_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A1492,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F12010F,
+ 0x0F120F01,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F12010F,
+ 0x0F120F01,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+
+ 0x002A0268, /*REG_TC_GP_PrevConfigChanged */
+ 0x0F120001,
+};
+
+static const u32 s5k4ecgx_EV_Minus_4_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A1484,
+ 0x0F120018, /*TVAR_ae_BrAve */
+};
+
+static const u32 s5k4ecgx_EV_Minus_3_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A1484,
+ 0x0F12001E, /*TVAR_ae_BrAve */
+};
+
+static const u32 s5k4ecgx_EV_Minus_2_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A1484,
+ 0x0F120025, /*TVAR_ae_BrAve */
+};
+
+static const u32 s5k4ecgx_EV_Minus_1_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A1484,
+ 0x0F120030, /*TVAR_ae_BrAve */
+};
+
+static const u32 s5k4ecgx_EV_Default_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A1484,
+ 0x0F12003C, /*TVAR_ae_BrAve */
+};
+
+static const u32 s5k4ecgx_EV_Plus_1_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A1484,
+ 0x0F12004E, /*TVAR_ae_BrAve */
+};
+
+static const u32 s5k4ecgx_EV_Plus_2_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A1484,
+ 0x0F120060, /*TVAR_ae_BrAve */
+};
+
+static const u32 s5k4ecgx_EV_Plus_3_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A1484,
+ 0x0F120070, /*TVAR_ae_BrAve */
+};
+
+static const u32 s5k4ecgx_EV_Plus_4_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A1484,
+ 0x0F120080, /*TVAR_ae_BrAve */
+};
+
+static const u32 s5k4ecgx_Contrast_Minus_4_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A0232,
+ 0x0F12FF81,
+};
+
+static const u32 s5k4ecgx_Contrast_Minus_3_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A0232,
+ 0x0F12FFA0,
+};
+
+static const u32 s5k4ecgx_Contrast_Minus_2_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A0232,
+ 0x0F12FFC0,
+};
+
+static const u32 s5k4ecgx_Contrast_Minus_1_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A0232,
+ 0x0F12FFE0,
+};
+
+static const u32 s5k4ecgx_Contrast_Default_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A0232,
+ 0x0F120000,
+};
+
+static const u32 s5k4ecgx_Contrast_Plus_1_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A0232,
+ 0x0F120020,
+};
+
+static const u32 s5k4ecgx_Contrast_Plus_2_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A0232,
+ 0x0F120040,
+};
+
+static const u32 s5k4ecgx_Contrast_Plus_3_EVT1[] = {/*Setting Unavailable*/
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A0232,
+ 0x0F120060,
+};
+
+static const u32 s5k4ecgx_Contrast_Plus_4_EVT1[] = {/*Setting Unavailable*/
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A0232,
+ 0x0F12007F,
+};
+
+static const u32 s5k4ecgx_Auto_Contrast_ON_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A098E,
+ 0x0F12FFB0,
+
+ 0x002A0A44,
+ 0x0F12FFB0,
+
+ 0x002A0AFA,
+ 0x0F12FFB0,
+
+ 0x002A0BB0,
+ 0x0F12FFB0,
+
+ 0x002A0C66,
+ 0x0F12FFB0,
+};
+
+static const u32 s5k4ecgx_Auto_Contrast_OFF_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A098E,
+ 0x0F120000,
+
+ 0x002A0A44,
+ 0x0F120000,
+
+ 0x002A0AFA,
+ 0x0F120000,
+
+ 0x002A0BB0,
+ 0x0F120000,
+
+ 0x002A0C66,
+ 0x0F120000,
+};
+
+static const u32 s5k4ecgx_Sharpness_Minus_3_EVT1[] = {/*Setting Unavailable*/
+ 0x00287000,
+ 0x002A0A28,
+ 0x0F120000,
+ 0x002A0ADE,
+ 0x0F120000,
+ 0x002A0B94,
+ 0x0F120000,
+ 0x002A0C4A,
+ 0x0F120000,
+ 0x002A0D00,
+ 0x0F120000,
+};
+
+static const u32 s5k4ecgx_Sharpness_Minus_2_EVT1[] = {
+ 0x00287000,
+ 0x002A0A28,
+ 0x0F122010,
+ 0x002A0ADE,
+ 0x0F122010,
+ 0x002A0B94,
+ 0x0F122010,
+ 0x002A0C4A,
+ 0x0F122010,
+ 0x002A0D00,
+ 0x0F122010,
+};
+
+static const u32 s5k4ecgx_Sharpness_Minus_1_EVT1[] = {
+ 0x00287000,
+ 0x002A0A28,
+ 0x0F124020,
+ 0x002A0ADE,
+ 0x0F124020,
+ 0x002A0B94,
+ 0x0F124020,
+ 0x002A0C4A,
+ 0x0F124020,
+ 0x002A0D00,
+ 0x0F124020,
+};
+
+static const u32 s5k4ecgx_Sharpness_Default_EVT1[] = {
+ 0x00287000,
+ 0x002A0A28,
+ 0x0F126024,
+ 0x002A0ADE,
+ 0x0F126024,
+ 0x002A0B94,
+ 0x0F126024,
+ 0x002A0C4A,
+ 0x0F126024,
+ 0x002A0D00,
+ 0x0F126024,
+};
+
+static const u32 s5k4ecgx_Sharpness_Plus_1_EVT1[] = {
+ 0x00287000,
+ 0x002A0A28,
+ 0x0F128040,
+ 0x002A0ADE,
+ 0x0F128040,
+ 0x002A0B94,
+ 0x0F128040,
+ 0x002A0C4A,
+ 0x0F128040,
+ 0x002A0D00,
+ 0x0F128040,
+};
+
+static const u32 s5k4ecgx_Sharpness_Plus_2_EVT1[] = {
+ 0x00287000,
+ 0x002A0A28,
+ 0x0F12A060,
+ 0x002A0ADE,
+ 0x0F12A060,
+ 0x002A0B94,
+ 0x0F12A060,
+ 0x002A0C4A,
+ 0x0F12A060,
+ 0x002A0D00,
+ 0x0F12A060,
+};
+
+static const u32 s5k4ecgx_Sharpness_Plus_3_EVT1[] = {
+ 0x00287000,
+ 0x002A0A28,
+ 0x0F12C080,
+ 0x002A0ADE,
+ 0x0F12C080,
+ 0x002A0B94,
+ 0x0F12C080,
+ 0x002A0C4A,
+ 0x0F12C080,
+ 0x002A0D00,
+ 0x0F12C080,
+};
+
+static const u32 s5k4ecgx_Saturation_Minus_2_EVT1[] = {
+ 0x00287000,
+ 0x002A0234,
+ 0x0F12FF81,
+};
+
+static const u32 s5k4ecgx_Saturation_Minus_1_EVT1[] = {
+ 0x00287000,
+ 0x002A0234,
+ 0x0F12FFC0,
+};
+
+static const u32 s5k4ecgx_Saturation_Default_EVT1[] = {
+ 0x00287000,
+ 0x002A0234,
+ 0x0F120000,
+};
+
+static const u32 s5k4ecgx_Saturation_Plus_1_EVT1[] = {
+ 0x00287000,
+ 0x002A0234,
+ 0x0F120040,
+};
+
+static const u32 s5k4ecgx_Saturation_Plus_2_EVT1[] = {
+ 0x00287000,
+ 0x002A0234,
+ 0x0F12007F,
+};
+
+static const u32 s5k4ecgx_Jpeg_Quality_High_EVT1[] = {
+ 0x00287000,
+ 0x002A0478,
+ 0x0F12005F,
+ 0x0F12005F,
+};
+
+static const u32 s5k4ecgx_Jpeg_Quality_Normal_EVT1[] = {
+ 0x00287000,
+ 0x002A0478,
+ 0x0F12005A,
+ 0x0F12005A,
+};
+
+static const u32 s5k4ecgx_Jpeg_Quality_Low_EVT1[] = {
+ 0x00287000,
+ 0x002A0478,
+ 0x0F120054,
+ 0x0F120054,
+};
+
+static const u32 s5k4ecgx_Scene_Default_EVT1[] = {
+/*scene Backlight landscape*/
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A1484,
+ 0x0F12003C,
+ 0x002A1492,
+ 0x0F120100,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120001,
+ 0x0F120101,
+ 0x0F120201,
+ 0x0F120102,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120202,
+ 0x0F120202,
+ 0x0F120101,
+ 0x0F120201,
+ 0x0F120302,
+ 0x0F120203,
+ 0x0F120102,
+ 0x0F120201,
+ 0x0F120302,
+ 0x0F120203,
+ 0x0F120102,
+ 0x0F120101,
+ 0x0F120202,
+ 0x0F120202,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120201,
+ 0x0F120102,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+
+/* Sharpness 0*/
+ 0x002A0A28,
+ 0x0F126024, /*_ee_iLowSharpPower*/
+ 0x002A0ADE,
+ 0x0F126024, /*_ee_iLowSharpPower*/
+ 0x002A0B94,
+ 0x0F126024, /*_ee_iLowSharpPower*/
+ 0x002A0C4A,
+ 0x0F126024, /*_ee_iLowSharpPower*/
+ 0x002A0D00,
+ 0x0F126024, /*_ee_iLowSharpPower*/
+
+/* Saturation 0*/
+ 0x002A0234,
+ 0x0F120000, /*REG_TC_UserSaturation */
+ 0x002A06B8,
+ 0x0F12452C,
+ 0x0F120005, /*lt_uMaxLei */
+
+ 0x002A0A1E,
+ 0x0F120350,/*_ccm_oscar_iSaturation [7:0] AFIT8_RGB2YUV_iYOffset*/
+
+ 0x002A0638,
+ 0x0F120001,
+ 0x0F120000,/*lt_ExpGain_ExpCurveGainMaxStr_0__ulExpOut_0_ */
+ 0x0F120A3C,
+ 0x0F120000,/*lt_ExpGain_ExpCurveGainMaxStr_0__ulExpOut_1_ */
+ 0x0F120D05,
+ 0x0F120000,/*lt_ExpGain_ExpCurveGainMaxStr_0__ulExpOut_2_ */
+ 0x0F123408,
+ 0x0F120000,/*lt_ExpGain_ExpCurveGainMaxStr_0__ulExpOut_3_ */
+ 0x0F123408,
+ 0x0F120000,/*lt_ExpGain_ExpCurveGainMaxStr_0__ulExpOut_4_ */
+ 0x0F126810,
+ 0x0F120000,/*lt_ExpGain_ExpCurveGainMaxStr_0__ulExpOut_5_ */
+ 0x0F128214,
+ 0x0F120000,/*lt_ExpGain_ExpCurveGainMaxStr_0__ulExpOut_6_ */
+ 0x0F12C350,
+ 0x0F120000,/*lt_ExpGain_ExpCurveGainMaxStr_0__ulExpOut_7_ */
+ 0x0F12C350,
+ 0x0F120000,/*lt_ExpGain_ExpCurveGainMaxStr_0__ulExpOut_8_ */
+ 0x0F12C350,
+ 0x0F120000,/*lt_ExpGain_ExpCurveGainMaxStr_0__ulExpOut_9_ */
+
+ 0x002A02C2,
+ 0x0F12029A,/*REG_0TC_PCFG_usMaxFrTimeMsecMult10 //029Ah:15fps */
+ 0x0F12014A,/*REG_0TC_PCFG_usMinFrTimeMsecMult10 //014Ah:30fps */
+ 0x002A03B4,
+ 0x0F120535,/*REG_0TC_CCFG_usMaxFrTimeMsecMult10 //0535h:7.5fps */
+ 0x0F12029A,/*REG_0TC_CCFG_usMinFrTimeMsecMult10 //029Ah:15fps */
+
+ 0x002A0938,
+ 0x0F120000, /*afit_bUseNB_Afit */
+
+ 0x002A04E6,
+ 0x0F12077F, /*REG_TC_DBG_AutoAlgEnBits */
+
+ 0x002A04D0,
+ 0x0F120000, /*REG_SF_USER_IsoType */
+ 0x0F120000, /*REG_SF_USER_IsoVal */
+ 0x0F120001, /*REG_SF_USER_IsoChanged */
+
+ 0x002A06C2,
+ 0x0F120200, /*lt_bUseSecISODgain */
+
+ 0x002A1648,
+ 0x0F129002, /*af_search_usSingleAfFlags */
+
+ 0x002A15E8,
+ 0x0F120015, /*af_pos_usTableLastInd */
+ 0x0F120027, /*af_pos_usTable_0_ */
+ 0x0F120030, /*af_pos_usTable_1_ */
+ 0x0F120036, /*af_pos_usTable_2_ */
+ 0x0F12003C, /*af_pos_usTable_3_ */
+ 0x0F120042, /*af_pos_usTable_4_ */
+ 0x0F120048, /*af_pos_usTable_5_ */
+ 0x0F12004E, /*af_pos_usTable_6_ */
+ 0x0F120054, /*af_pos_usTable_7_ */
+ 0x0F12005A, /*af_pos_usTable_8_ */
+ 0x0F120060, /*af_pos_usTable_9_ */
+ 0x0F120066, /*af_pos_usTable_10 */
+ 0x0F12006C, /*af_pos_usTable_11_ */
+ 0x0F120072, /*af_pos_usTable_12_ */
+ 0x0F120078, /*af_pos_usTable_13_ */
+ 0x0F12007E, /*af_pos_usTable_14_ */
+ 0x0F120084, /*af_pos_usTable_15_ */
+ 0x0F12008A, /*af_pos_usTable_16_ */
+ 0x0F120090, /*af_pos_usTable_17_ */
+ 0x0F120096, /*af_pos_usTable_18_ */
+ 0x0F12009C, /*af_pos_usTable_19_ */
+ 0x0F1200A2, /*af_pos_usTable_20_ */
+ 0x0F1200A8, /*af_pos_usTable_21_ */
+ 0x0F1200AE, /*af_pos_usTable_22_ */
+ 0x0F1200B4, /*af_pos_usTable_23_ */
+ 0x0F1200BA, /*af_pos_usTable_24_ */
+
+ 0x002A0266,
+ 0x0F120000, /*REG_TC_GP_ActivePrevConfig */
+ 0x002A026A,
+ 0x0F120001, /*REG_TC_GP_PrevOpenAfterChange */
+ 0x002A024E,
+ 0x0F120001, /*REG_TC_GP_NewConfigSync */
+ 0x002A0268,
+ 0x0F120001, /*REG_TC_GP_PrevConfigChanged */
+ 0x002A0270,
+ 0x0F120001, /*REG_TC_GP_CapConfigChanged */
+ 0x002A023E,
+ 0x0F120001, /*REG_TC_GP_EnablePreview */
+ 0x0F120001, /*REG_TC_GP_EnablePreviewChanged */
+
+};
+
+static const u32 s5k4ecgx_Scene_Portrait_EVT1[] = {
+ 0x00287000,
+ 0x002A0A28,
+ 0x0F124020,
+ 0x002A0ADE,
+ 0x0F124020,
+ 0x002A0B94,
+ 0x0F124020,
+ 0x002A0C4A,
+ 0x0F124020,
+ 0x002A0D00,
+ 0x0F124020,
+};
+
+static const u32 s5k4ecgx_Scene_Nightshot_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A06B8,
+ 0x0F12FFFF, /*lt_uMaxLei */
+ 0x0F1200FF, /*lt_usMinExp */
+
+ 0x002A0A1E,
+ 0x0F1215C0,/*_ccm_oscar_iSaturation [7:0] AFIT8_RGB2YUV_iYOffset*/
+
+ 0x002A0638,
+ 0x0F120001,
+ 0x0F120000,/*ltExpGainExpCurveGainMaxStr_0_ulExpOut0*/
+ 0x0F121478,
+ 0x0F120000,/*lt_ExpGain_ExpCurveGainMaxStr_0__ulExpOut_1_ */
+ 0x0F121A0A,
+ 0x0F120000,/*lt_ExpGain_ExpCurveGainMaxStr_0__ulExpOut_2_ */
+ 0x0F126810,
+ 0x0F120000,/*lt_ExpGain_ExpCurveGainMaxStr_0__ulExpOut_3_ */
+ 0x0F126810,
+ 0x0F120000,/*lt_ExpGain_ExpCurveGainMaxStr_0__ulExpOut_4_ */
+ 0x0F12D020,
+ 0x0F120000,/*lt_ExpGain_ExpCurveGainMaxStr_0__ulExpOut_5_ */
+ 0x0F120428,
+ 0x0F120001,/*lt_ExpGain_ExpCurveGainMaxStr_0__ulExpOut_6_ */
+ 0x0F121A80,
+ 0x0F120006,/*lt_ExpGain_ExpCurveGainMaxStr_0__ulExpOut_7_ */
+ 0x0F121A80,
+ 0x0F120006,/*lt_ExpGain_ExpCurveGainMaxStr_0__ulExpOut_8_ */
+ 0x0F121A80,
+ 0x0F120006,/*lt_ExpGain_ExpCurveGainMaxStr_0__ulExpOut_9_ */
+
+ 0x002A02C2,
+ 0x0F1209C4,/*REG_0TC_PCFG_usMaxFrTimeMsecMult10 //09C4h:4fps */
+ 0x0F12014A,/*REG_0TC_PCFG_usMinFrTimeMsecMult10 //014Ah:30fps */
+ 0x002A03B4,
+ 0x0F121388,/*REG_0TC_CCFG_usMaxFrTimeMsecMult10 //1388h:2fps */
+ 0x0F121388,/*REG_0TC_CCFG_usMinFrTimeMsecMult10 //1388h:2fps */
+
+ 0x002A1648, /*af_search_usSingleAfFlags */
+ 0x0F129000,
+
+ 0x002A15E8,
+ 0x0F120006, /*af_pos_usTableLastInd */
+ 0x0F120036,
+ 0x0F12003A,
+ 0x0F120040,
+ 0x0F120048,
+ 0x0F120050,
+ 0x0F120058,
+ 0x0F120060,
+
+ 0x002A0266,
+ 0x0F120000, /*REG_TC_GP_ActivePrevConfig */
+ 0x002A026A,
+ 0x0F120001, /*REG_TC_GP_PrevOpenAfterChange */
+ 0x002A024E,
+ 0x0F120001, /*REG_TC_GP_NewConfigSync */
+ 0x002A0268,
+ 0x0F120001, /*REG_TC_GP_PrevConfigChanged */
+ 0x002A0270,
+ 0x0F120001, /*REG_TC_GP_CapConfigChanged */
+ 0x002A023E,
+ 0x0F120001, /*REG_TC_GP_EnablePreview */
+ 0x0F120001, /*REG_TC_GP_EnablePreviewChanged */
+
+};
+
+static const u32 s5k4ecgx_Scene_Backlight_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A1492,
+ 0x0F120000, /*ae_WeightTbl_16 */
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F12010F,
+ 0x0F120F01,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F12010F,
+ 0x0F120F01,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+ 0x0F120000,
+
+};
+
+static const u32 s5k4ecgx_Scene_Landscape_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A1492,
+ 0x0F120101, /*ae_WeightTbl_16 */
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+
+ 0x002A0A28,
+ 0x0F12E082,/*_ee_iLowSharpPower [7:0] AFIT8_ee_iHighSharpPower*/
+ 0x002A0ADE,
+ 0x0F12E082,/*_ee_iLowSharpPower [7:0] AFIT8_ee_iHighSharpPower*/
+ 0x002A0B94,
+ 0x0F12E082,/*_ee_iLowSharpPower [7:0] AFIT8_ee_iHighSharpPower*/
+ 0x002A0C4A,
+ 0x0F12E082,/*_ee_iLowSharpPower [7:0] AFIT8_ee_iHighSharpPower*/
+ 0x002A0D00,
+ 0x0F12E082,/*_ee_iLowSharpPower [7:0] AFIT8_ee_iHighSharpPower*/
+
+ 0x002A0234,
+ 0x0F120030, /*REG_TC_UserSaturation */
+};
+
+static const u32 s5k4ecgx_Scene_Sports_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A0638,
+ 0x0F120001,
+ 0x0F120000,/*lt_ExpGain_ExpCurveGainMaxStr_0__ulExpOut_0_ */
+ 0x0F120A3C,
+ 0x0F120000,/*lt_ExpGain_ExpCurveGainMaxStr_0__ulExpOut_1_ */
+ 0x0F120D05,
+ 0x0F120000,/*lt_ExpGain_ExpCurveGainMaxStr_0__ulExpOut_2_ */
+ 0x0F123408,
+ 0x0F120000,/*lt_ExpGain_ExpCurveGainMaxStr_0__ulExpOut_3_ */
+ 0x0F123408,
+ 0x0F120000,/*lt_ExpGain_ExpCurveGainMaxStr_0__ulExpOut_4_ */
+ 0x0F123408,
+ 0x0F120000,/*lt_ExpGain_ExpCurveGainMaxStr_0__ulExpOut_5_ */
+ 0x0F123408,
+ 0x0F120000,/*lt_ExpGain_ExpCurveGainMaxStr_0__ulExpOut_6_ */
+ 0x0F123408,
+ 0x0F120000,/*lt_ExpGain_ExpCurveGainMaxStr_0__ulExpOut_7_ */
+ 0x0F123408,
+ 0x0F120000,/*lt_ExpGain_ExpCurveGainMaxStr_0__ulExpOut_8_ */
+ 0x0F123408,
+ 0x0F120000,/*lt_ExpGain_ExpCurveGainMaxStr_0__ulExpOut_9_ */
+
+ 0x002A0938,
+ 0x0F120001, /*afit_bUseNB_Afit */
+
+ 0x002A04D0,
+ 0x0F120001, /*REG_SF_USER_IsoType */
+ 0x0F120200, /*REG_SF_USER_IsoVal */
+ 0x0F120001, /*REG_SF_USER_IsoChanged */
+ 0x002A06C2,
+ 0x0F120150, /*lt_bUseSecISODgain */
+
+ 0x002A0266,
+ 0x0F120000, /*REG_TC_GP_ActivePrevConfig */
+ 0x002A026A,
+ 0x0F120001, /*REG_TC_GP_PrevOpenAfterChange */
+ 0x002A024E,
+ 0x0F120001, /*REG_TC_GP_NewConfigSync */
+ 0x002A0268,
+ 0x0F120001, /*REG_TC_GP_PrevConfigChanged */
+ 0x002A0270,
+ 0x0F120001, /*REG_TC_GP_CapConfigChanged */
+ 0x002A023E,
+ 0x0F120001, /*REG_TC_GP_EnablePreview */
+ 0x0F120001, /*REG_TC_GP_EnablePreviewChanged */
+
+};
+
+static const u32 s5k4ecgx_Scene_Party_Indoor_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A0938,
+ 0x0F120001, /*afit_bUseNB_Afit */
+
+ 0x002A04D0,
+ 0x0F120001, /*REG_SF_USER_IsoType */
+ 0x0F120340, /*REG_SF_USER_IsoVal */
+ 0x0F120001, /*REG_SF_USER_IsoChanged */
+ 0x002A06C2,
+ 0x0F120180, /*lt_bUseSecISODgain */
+
+ 0x002A0234,
+ 0x0F120030, /*REG_TC_UserSaturation */
+};
+
+static const u32 s5k4ecgx_Scene_Beach_Snow_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A1484,
+ 0x0F120045, /*TVAR_ae_BrAve */
+
+ 0x002A0938,
+ 0x0F120001, /*afit_bUseNB_Afit */
+
+ 0x002A04D0,
+ 0x0F120001, /*REG_SF_USER_IsoType */
+ 0x0F1200D0, /*REG_SF_USER_IsoVal */
+ 0x0F120001, /*REG_SF_USER_IsoChanged */
+ 0x002A06C2,
+ 0x0F120150, /*lt_bUseSecISODgain */
+
+ 0x002A0234,
+ 0x0F120030, /*REG_TC_UserSaturation */
+};
+
+static const u32 s5k4ecgx_Scene_Sunset_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A04E6,
+ 0x0F120777, /*REG_TC_DBG_AutoAlgEnBits //AWB Off */
+
+ 0x002A04BA,
+ 0x0F1205F0, /*REG_SF_USER_Rgain */
+ 0x002A04BE,
+ 0x0F120400, /*REG_SF_USER_Ggain */
+ 0x002A04C2,
+ 0x0F120588, /*REG_SF_USER_Bgain */
+
+ 0x002A04C6,
+ 0x0F120001, /*REG_SF_USER_RGBGainChanged */
+};
+
+static const u32 s5k4ecgx_Scene_Duskdawn_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A04E6,
+ 0x0F120777, /*REG_TC_DBG_AutoAlgEnBits //AWB Off */
+
+ 0x002A04BA,
+ 0x0F1205A5, /*REG_SF_USER_Rgain */
+ 0x002A04BE,
+ 0x0F120400, /*REG_SF_USER_Ggain */
+ 0x002A04C2,
+ 0x0F1208A8, /*REG_SF_USER_Bgain */
+
+ 0x002A04C6,
+ 0x0F120001, /*REG_SF_USER_RGBGainChanged */
+};
+
+static const u32 s5k4ecgx_Scene_Fall_Color_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A0234,
+ 0x0F120060,
+};
+
+static const u32 s5k4ecgx_Scene_Fireworks_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A0638,
+ 0x0F120001,
+ 0x0F120000,/*lt_ExpGain_ExpCurveGainMaxStr_0__ulExpOut_0_ */
+ 0x0F121478,
+ 0x0F120000,/*lt_ExpGain_ExpCurveGainMaxStr_0__ulExpOut_1_ */
+ 0x0F121A0A,
+ 0x0F120000,/*lt_ExpGain_ExpCurveGainMaxStr_0__ulExpOut_2_ */
+ 0x0F126810,
+ 0x0F120000,/*lt_ExpGain_ExpCurveGainMaxStr_0__ulExpOut_3_ */
+ 0x0F126810,
+ 0x0F120000,/*lt_ExpGain_ExpCurveGainMaxStr_0__ulExpOut_4_ */
+ 0x0F12D020,
+ 0x0F120000,/*lt_ExpGain_ExpCurveGainMaxStr_0__ulExpOut_5_ */
+ 0x0F120428,
+ 0x0F120001,/*lt_ExpGain_ExpCurveGainMaxStr_0__ulExpOut_6_ */
+ 0x0F121A80,
+ 0x0F120006,/*lt_ExpGain_ExpCurveGainMaxStr_0__ulExpOut_7_ */
+ 0x0F121A80,
+ 0x0F120006,/*lt_ExpGain_ExpCurveGainMaxStr_0__ulExpOut_8_ */
+ 0x0F121A80,
+ 0x0F120006,/*lt_ExpGain_ExpCurveGainMaxStr_0__ulExpOut_9_ */
+
+ 0x002A03B4,
+ 0x0F122710,/*REG_0TC_CCFG_usMaxFrTimeMsecMult10 //2710h:1fps */
+ 0x0F122710,/*REG_0TC_CCFG_usMinFrTimeMsecMult10 //2710h:1fps */
+
+ 0x002A0266,
+ 0x0F120000, /*REG_TC_GP_ActivePrevConfig */
+ 0x002A026A,
+ 0x0F120001, /*REG_TC_GP_PrevOpenAfterChange */
+ 0x002A024E,
+ 0x0F120001, /*REG_TC_GP_NewConfigSync */
+ 0x002A0268,
+ 0x0F120001, /*REG_TC_GP_PrevConfigChanged */
+ 0x002A0270,
+ 0x0F120001, /*REG_TC_GP_CapConfigChanged */
+ 0x002A023E,
+ 0x0F120001, /*REG_TC_GP_EnablePreview */
+ 0x0F120001, /*REG_TC_GP_EnablePreviewChanged */
+};
+
+static const u32 s5k4ecgx_Scene_Text_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A0A28,
+ 0x0F12A060,/*_ee_iLowSharpPower [7:0] AFIT8_ee_iHighSharpPower*/
+ 0x002A0ADE,
+ 0x0F12A060,/*_ee_iLowSharpPower [7:0] AFIT8_ee_iHighSharpPower*/
+ 0x002A0B94,
+ 0x0F12A060,/*_ee_iLowSharpPower [7:0] AFIT8_ee_iHighSharpPower*/
+ 0x002A0C4A,
+ 0x0F12A060,/*_ee_iLowSharpPower [7:0] AFIT8_ee_iHighSharpPower*/
+ 0x002A0D00,
+ 0x0F12A060,/*_ee_iLowSharpPower [7:0] AFIT8_ee_iHighSharpPower*/
+};
+
+static const u32 s5k4ecgx_Scene_Candle_Light_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A04E6,
+ 0x0F120777, /*REG_TC_DBG_AutoAlgEnBits //AWB Off */
+
+ 0x002A04BA,
+ 0x0F1205F0, /*REG_SF_USER_Rgain */
+ 0x002A04BE,
+ 0x0F120400, /*REG_SF_USER_Ggain */
+ 0x002A04C2,
+ 0x0F120588, /*REG_SF_USER_Bgain */
+
+ 0x002A04C6,
+ 0x0F120001, /*REG_SF_USER_RGBGainChanged */
+};
+
+ /* AE Lock */
+static const u32 s5k4ecgx_ae_lock_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A2C5E,
+ 0x0F120000,
+};
+
+ /* AE unLock */
+static const u32 s5k4ecgx_ae_unlock_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A2C5E,
+ 0x0F120001,
+};
+
+ /* AWB Lock */
+static const u32 s5k4ecgx_awb_lock_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A2C66,
+ 0x0F120000,
+};
+
+ /* AWB unLock */
+static const u32 s5k4ecgx_awb_unlock_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A2C66,
+ 0x0F120001,
+};
+
+static const u32 s5k4ecgx_Night_Mode_Off_EVT1[] = {
+
+};
+
+static const u32 s5k4ecgx_AF_Return_Inf_pos_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A15D6,
+ 0x0F12D000,
+};
+
+static const u32 s5k4ecgx_AF_Return_Macro_pos_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A15E8,
+ 0x0F120018,
+ 0x0F12002A,
+ 0x0F120030,
+ 0x0F120036,
+ 0x0F12003C,
+ 0x0F120042,
+ 0x0F120048,
+ 0x0F12004E,
+ 0x0F120054,
+ 0x0F12005A,
+ 0x0F120060,
+ 0x0F120066,
+ 0x0F12006C,
+ 0x0F120072,
+ 0x0F120078,
+ 0x0F12007E,
+ 0x0F120084,
+ 0x0F12008A,
+ 0x0F120090,
+ 0x0F120096,
+ 0x0F12009C,
+ 0x0F1200A2,
+ 0x0F1200A8,
+ 0x0F1200AE,
+ 0x0F1200B4,
+ 0x0F1200BA,
+};
+
+static const u32 s5k4ecgx_AF_Normal_mode_4_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A1648,
+ 0x0F129002,
+};
+
+static const u32 s5k4ecgx_AF_Normal_mode_1_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A028E,
+ 0x0F120000,
+};
+
+static const u32 s5k4ecgx_AF_Normal_mode_2_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A028C,
+ 0x0F120004,
+};
+
+static const u32 s5k4ecgx_AF_Normal_mode_3_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A1648,
+ 0x0F129002,
+
+ 0x002A15E8,
+ 0x0F120017, /*af_pos_usTableLastInd */
+ 0x0F120026,
+ 0x0F12002C,
+ 0x0F120032,
+ 0x0F120038,
+ 0x0F12003E,
+ 0x0F120044,
+ 0x0F12004A,
+ 0x0F120050,
+ 0x0F120056,
+ 0x0F12005C,
+ 0x0F120062,
+ 0x0F120068,
+ 0x0F12006E,
+ 0x0F120074,
+ 0x0F12007A,
+ 0x0F120080,
+ 0x0F120086,
+ 0x0F12008C,
+ 0x0F120092,
+ 0x0F120098,
+ 0x0F12009E,
+ 0x0F1200A4,
+ 0x0F1200AA,
+ 0x0F1200B0,
+};
+
+static const u32 s5k4ecgx_AF_Macro_mode_1_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A028E,
+ 0x0F1200D0,
+};
+
+static const u32 s5k4ecgx_AF_Macro_mode_2_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A028C,
+ 0x0F120004,
+};
+
+static const u32 s5k4ecgx_AF_Macro_mode_3_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A1648,
+ 0x0F129042,
+
+ 0x002A15E8,
+ 0x0F120015, /*af_pos_usTableLastInd */
+ 0x0F120032,
+ 0x0F120038,
+ 0x0F12003E,
+ 0x0F120044,
+ 0x0F12004A,
+ 0x0F120050,
+ 0x0F120056,
+ 0x0F12005C,
+ 0x0F120062,
+ 0x0F120068,
+ 0x0F12006E,
+ 0x0F120074,
+ 0x0F12007A,
+ 0x0F120080,
+ 0x0F120086,
+ 0x0F12008C,
+ 0x0F120092,
+ 0x0F120098,
+ 0x0F12009E,
+ 0x0F1200A4,
+ 0x0F1200AA,
+ 0x0F1200B0,
+
+ 0x002A15DA,
+ 0x0F121500,/* 16 start number of table 00 End number of table */
+};
+
+static const u32 s5k4ecgx_AF_Low_Light_normal_mode_1_EVT1[] = {
+
+};
+
+static const u32 s5k4ecgx_AF_Low_Light_normal_mode_2_EVT1[] = {
+
+};
+
+static const u32 s5k4ecgx_AF_Low_Light_normal_mode_3_EVT1[] = {
+
+};
+
+static const u32 s5k4ecgx_AF_Low_Light_Macro_mode_1_EVT1[] = {
+
+};
+
+static const u32 s5k4ecgx_AF_Low_Light_Macro_mode_2_EVT1[] = {
+
+};
+
+static const u32 s5k4ecgx_AF_Low_Light_Macro_mode_3_EVT1[] = {
+
+};
+
+static const u32 s5k4ecgx_Single_AF_Start_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A028C,
+ 0x0F120005,
+};
+
+static const u32 s5k4ecgx_Single_AF_Off_1_EVT1[] = {
+
+};
+
+static const u32 s5k4ecgx_Single_AF_Off_2_EVT1[] = {
+
+};
+
+static const u32 s5k4ecgx_Single_AF_Off_3_EVT1[] = {
+
+};
+
+static const u32 s5k4ecgx_Face_Detection_On_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A0294,
+ 0x0F120100,
+ 0x0F1200E3,
+ 0x0F120200,
+ 0x0F120238,
+ 0x0F1201C6,
+ 0x0F120166,
+ 0x0F120074,
+ 0x0F120132,
+ 0x0F120001,
+};
+
+static const u32 s5k4ecgx_Face_Detection_Off_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A0294,
+ 0x0F120100,
+ 0x0F1200E3,
+ 0x0F120200,
+ 0x0F120238,
+ 0x0F1201C6,
+ 0x0F120166,
+ 0x0F120074,
+ 0x0F120132,
+ 0x0F120001,
+};
+
+static const u32 s5k4ecgx_Low_Cap_On_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A06B8,
+ 0x0F12552C, /*lt_uMaxLei */
+ 0x0F120006, /*lt_usMinExp */
+
+ 0x002A0608,
+ 0x0F120001, /*lt_ExpGain_uSubsamplingmode */
+ 0x0F120001, /*lt_ExpGain_uNonSubsampling */
+ 0x0F120900, /*lt_ExpGain_ExpCurveGainMaxStr_0__uMaxAnGain */
+
+};
+
+static const u32 s5k4ecgx_Low_Cap_Off_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A06B8,
+ 0x0F12452C, /*lt_uMaxLei */
+ 0x0F120005, /*lt_usMinExp // 0725 000C->0005 */
+
+ 0x002A0608,
+ 0x0F120001, /*lt_ExpGain_uSubsamplingmode */
+ 0x0F120001, /*lt_ExpGain_uNonSubsampling */
+ 0x0F120800, /*lt_ExpGain_ExpCurveGainMaxStr_0__uMaxAnGain */
+
+};
+
+static const u32 s5k4ecgx_Night_Mode_On_EVT1[] = {
+
+};
+
+static const u32 s5k4ecgx_Capture_Start_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A0242,
+ 0x0F120001,
+ 0x002A024E,
+ 0x0F120001,
+ 0x002A0244,
+ 0x0F120001,
+};
+
+static const u32 s5k4ecgx_Preview_Return_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A0242,
+ 0x0F120000, /*REG_TC_GP_EnableCapture*/
+ 0x002A024E,
+ 0x0F120001, /*REG_TC_GP_NewConfigSync*/
+ 0x002A0244,
+ 0x0F120001, /*REG_TC_GP_EnableCaptureChanged*/
+
+};
+
+ /* Flash Control */
+static const u32 s5k4ecgx_Flash_init_EVT1[] = {
+/* Include initial setting*/
+};
+
+static const u32 s5k4ecgx_Pre_Flash_On_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A17FC, /* fls_FlashWP_0_Pre_Flash_Start*/
+ 0x0F120001,
+};
+
+static const u32 s5k4ecgx_Pre_Flash_Off_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A1800, /*fls_afl_FlashWP_Weight_0_Pre_Flash_end*/
+ 0x0F120001,
+};
+
+static const u32 s5k4ecgx_Main_Flash_On_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A17E8,/*fls_afl_FlashMode:Flash alg start*/
+ 0x0F120001,
+ 0x002A180C,/*fls_afl_FlashWP_Weight_4:flash br avg*/
+ 0x0F120027,
+};
+
+static const u32 s5k4ecgx_Main_Flash_Off_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A17E8, /*fls_afl_FlashMode Flash alg end*/
+ 0x0F120000,
+};
+
+static const u32 s5k4ecgx_5M_Capture_EVT1[] = { /* 2560 x 1920 */
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A0258,
+ 0x0F120A00, /*REG_TC_GP_CapReqInputWidth //2560 */
+ 0x0F120780, /*REG_TC_GP_CapReqInputHeight //1920 */
+ 0x0F120010, /*REG_TC_GP_CapInputWidthOfs //(2592-2560)/2 */
+ 0x0F12000C, /*REG_TC_GP_CapInputHeightOfs //(1944-1920)/2 */
+
+ 0x002A0264,
+ 0x0F120001, /*REG_TC_GP_bUseReqInputInCap */
+
+ 0x002A049C,
+ 0x0F120A00, /*REG_TC_PZOOM_CapZoomReqInputWidth //2560 */
+ 0x0F120780, /*REG_TC_PZOOM_CapZoomReqInputHeight //1920 */
+ 0x0F120000, /*REG_TC_PZOOM_CapZoomReqInputWidthOfs */
+ 0x0F120000, /*REG_TC_PZOOM_CapZoomReqInputHeightOfs */
+
+ 0x002A047C,
+ 0x0F120001, /*REG_TC_THUMB_Thumb_bActive */
+ 0x0F120280, /*REG_TC_THUMB_Thumb_uWidth //640 */
+ 0x0F1201E0, /*REG_TC_THUMB_Thumb_uHeight //480 */
+
+ 0x002A0398,
+ 0x0F120A00, /*REG_0TC_CCFG_usWidth //2560 */
+ 0x0F120780, /*REG_0TC_CCFG_usHeight //1920 */
+
+ 0x002A024E,
+ 0x0F120001, /*REG_TC_GP_NewConfigSync */
+ 0x002A0270,
+ 0x0F120001, /*REG_TC_GP_CapConfigChanged */
+};
+
+static const u32 s5k4ecgx_3M_Capture_EVT1[] = { /*2048 x 1536 */
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A0258,
+ 0x0F120A00, /*REG_TC_GP_CapReqInputWidth //2560 */
+ 0x0F120780, /*REG_TC_GP_CapReqInputHeight //1920 */
+ 0x0F120010, /*REG_TC_GP_CapInputWidthOfs //(2592-2560)/2 */
+ 0x0F12000C, /*REG_TC_GP_CapInputHeightOfs //(1944-1920)/2 */
+
+ 0x002A0264,
+ 0x0F120001, /*REG_TC_GP_bUseReqInputInCap */
+
+ 0x002A049C,
+ 0x0F120A00, /*REG_TC_PZOOM_CapZoomReqInputWidth //2560 */
+ 0x0F120780, /*REG_TC_PZOOM_CapZoomReqInputHeight //1920 */
+ 0x0F120000, /*REG_TC_PZOOM_CapZoomReqInputWidthOfs */
+ 0x0F120000, /*REG_TC_PZOOM_CapZoomReqInputHeightOfs */
+
+ 0x002A047C,
+ 0x0F120001, /*REG_TC_THUMB_Thumb_bActive */
+ 0x0F120280, /*REG_TC_THUMB_Thumb_uWidth //640 */
+ 0x0F1201E0, /*REG_TC_THUMB_Thumb_uHeight //480 */
+
+ 0x002A0398,
+ 0x0F120800, /*REG_0TC_CCFG_usWidth //2048 */
+ 0x0F120600, /*REG_0TC_CCFG_usHeight //1536 */
+
+ 0x002A024E,
+ 0x0F120001, /*REG_TC_GP_NewConfigSync */
+ 0x002A0270,
+ 0x0F120001, /*REG_TC_GP_CapConfigChanged */
+
+};
+
+static const u32 s5k4ecgx_2M_Capture_EVT1[] = { /*1600 x 1200 */
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A0258,
+ 0x0F120A00, /*REG_TC_GP_CapReqInputWidth //2560 */
+ 0x0F120780, /*REG_TC_GP_CapReqInputHeight //1920 */
+ 0x0F120010, /*REG_TC_GP_CapInputWidthOfs //(2592-2560)/2 */
+ 0x0F12000C, /*REG_TC_GP_CapInputHeightOfs //(1944-1920)/2 */
+
+ 0x002A0264,
+ 0x0F120001, /*REG_TC_GP_bUseReqInputInCap */
+
+ 0x002A049C,
+ 0x0F120A00, /*REG_TC_PZOOM_CapZoomReqInputWidth //2560 */
+ 0x0F120780, /*REG_TC_PZOOM_CapZoomReqInputHeight //1920 */
+ 0x0F120000, /*REG_TC_PZOOM_CapZoomReqInputWidthOfs */
+ 0x0F120000, /*REG_TC_PZOOM_CapZoomReqInputHeightOfs */
+
+ 0x002A047C,
+ 0x0F120001, /*REG_TC_THUMB_Thumb_bActive */
+ 0x0F120280, /*REG_TC_THUMB_Thumb_uWidth //640 */
+ 0x0F1201E0, /*REG_TC_THUMB_Thumb_uHeight //480 */
+
+ 0x002A0398,
+ 0x0F120640, /*REG_0TC_CCFG_usWidth //1600 */
+ 0x0F1204B0, /*REG_0TC_CCFG_usHeight //1200 */
+
+ 0x002A024E,
+ 0x0F120001, /*REG_TC_GP_NewConfigSync */
+ 0x002A0270,
+ 0x0F120001, /*REG_TC_GP_CapConfigChanged */
+};
+
+static const u32 s5k4ecgx_1M_Capture_EVT1[] = { /* 1280 x 960 */
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A0258,
+ 0x0F120A00, /*REG_TC_GP_CapReqInputWidth //2560 */
+ 0x0F120780, /*REG_TC_GP_CapReqInputHeight //1920 */
+ 0x0F120010, /*REG_TC_GP_CapInputWidthOfs //(2592-2560)/2 */
+ 0x0F12000C, /*REG_TC_GP_CapInputHeightOfs //(1944-1920)/2 */
+
+ 0x002A0264,
+ 0x0F120001, /*REG_TC_GP_bUseReqInputInCap */
+
+ 0x002A049C,
+ 0x0F120A00, /*REG_TC_PZOOM_CapZoomReqInputWidth //2560 */
+ 0x0F120780, /*REG_TC_PZOOM_CapZoomReqInputHeight //1920 */
+ 0x0F120000, /*REG_TC_PZOOM_CapZoomReqInputWidthOfs */
+ 0x0F120000, /*REG_TC_PZOOM_CapZoomReqInputHeightOfs */
+
+ 0x002A047C,
+ 0x0F120001, /*REG_TC_THUMB_Thumb_bActive */
+ 0x0F120280, /*REG_TC_THUMB_Thumb_uWidth //640 */
+ 0x0F1201E0, /*REG_TC_THUMB_Thumb_uHeight //480 */
+
+ 0x002A0398,
+ 0x0F120500, /*REG_0TC_CCFG_usWidth //1280 */
+ 0x0F1203C0, /*REG_0TC_CCFG_usHeight //960 */
+
+ 0x002A024E,
+ 0x0F120001, /*REG_TC_GP_NewConfigSync */
+ 0x002A0270,
+ 0x0F120001, /*REG_TC_GP_CapConfigChanged */
+
+};
+
+ /* 1024 x 768 */
+static const u32 s5k4ecgx_XGA_Capture_EVT1[] = {
+/* 0725 add*/
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A0258,
+ 0x0F120A00, /*REG_TC_GP_CapReqInputWidth //2560 */
+ 0x0F120780, /*REG_TC_GP_CapReqInputHeight //1920 */
+ 0x0F120010, /*REG_TC_GP_CapInputWidthOfs //(2592-2560)/2 */
+ 0x0F12000C, /*REG_TC_GP_CapInputHeightOfs //(1944-1920)/2 */
+
+ 0x002A0264,
+ 0x0F120001, /*REG_TC_GP_bUseReqInputInCap */
+
+ 0x002A049C,
+ 0x0F120A00, /*REG_TC_PZOOM_CapZoomReqInputWidth //2560 */
+ 0x0F120780, /*REG_TC_PZOOM_CapZoomReqInputHeight //1920 */
+ 0x0F120000, /*REG_TC_PZOOM_CapZoomReqInputWidthOfs */
+ 0x0F120000, /*REG_TC_PZOOM_CapZoomReqInputHeightOfs */
+
+ 0x002A047C,
+ 0x0F120001, /*REG_TC_THUMB_Thumb_bActive */
+ 0x0F120280, /*REG_TC_THUMB_Thumb_uWidth //640 */
+ 0x0F1201E0, /*REG_TC_THUMB_Thumb_uHeight //480 */
+
+ 0x002A0398,
+ 0x0F120400, /*REG_0TC_CCFG_usWidth //1024 */
+ 0x0F120300, /*REG_0TC_CCFG_usHeight //768 */
+
+ 0x002A024E,
+ 0x0F120001, /*REG_TC_GP_NewConfigSync */
+ 0x002A0270,
+ 0x0F120001, /*REG_TC_GP_CapConfigChanged */
+};
+
+static const u32 s5k4ecgx_VGA_Capture_EVT1[] = { /* 640 x 480 */
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A0258,
+ 0x0F120A00, /*REG_TC_GP_CapReqInputWidth //2560 */
+ 0x0F120780, /*REG_TC_GP_CapReqInputHeight //1920 */
+ 0x0F120010, /*REG_TC_GP_CapInputWidthOfs //(2592-2560)/2 */
+ 0x0F12000C, /*REG_TC_GP_CapInputHeightOfs //(1944-1920)/2 */
+
+ 0x002A0264,
+ 0x0F120001, /*REG_TC_GP_bUseReqInputInCap */
+
+ 0x002A049C,
+ 0x0F120A00, /*REG_TC_PZOOM_CapZoomReqInputWidth //2560 */
+ 0x0F120780, /*REG_TC_PZOOM_CapZoomReqInputHeight //1920 */
+ 0x0F120000, /*REG_TC_PZOOM_CapZoomReqInputWidthOfs */
+ 0x0F120000, /*REG_TC_PZOOM_CapZoomReqInputHeightOfs */
+
+ 0x002A047C,
+ 0x0F120001, /*REG_TC_THUMB_Thumb_bActive */
+ 0x0F120280, /*REG_TC_THUMB_Thumb_uWidth //640 */
+ 0x0F1201E0, /*REG_TC_THUMB_Thumb_uHeight //480 */
+
+ 0x002A0398,
+ 0x0F120280, /*REG_0TC_CCFG_usWidth //640 */
+ 0x0F1201E0, /*REG_0TC_CCFG_usHeight //480 */
+
+ 0x002A024E,
+ 0x0F120001, /*REG_TC_GP_NewConfigSync */
+ 0x002A0270,
+ 0x0F120001, /*REG_TC_GP_CapConfigChanged */
+};
+
+static const u32 s5k4ecgx_QVGA_Capture_EVT1[] = { /* 320 x 240 */
+
+};
+
+static const u32 s5k4ecgx_1280_Preview_EVT1[] = { /* 1280 x 720 */
+ /*720P enable setting */
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A18AC,
+ 0x0F120060, /*senHal_uAddColsBin */
+ 0x0F120060, /*senHal_uAddColsNoBin */
+ 0x0F1207DC, /*senHal_uMinColsBin */
+ 0x0F1205C0, /*senHal_uMinColsNoBin */
+
+ /* Size */
+ 0x002A0250,
+ 0x0F120A00, /*REG_TC_GP_PrevReqInputWidth //2560 */
+ 0x0F1205A0, /*REG_TC_GP_PrevReqInputHeight //1440 */
+ 0x0F120010, /*REG_TC_GP_PrevInputWidthOfs //(2592-2560)/2 */
+ 0x0F1200FC, /*REG_TC_GP_PrevInputHeightOfs //(1944-1440)/2*/
+ 0x002A0262,
+ 0x0F120001, /*REG_TC_GP_bUseReqInputInPre */
+ 0x002A0494,
+ 0x0F120A00, /*REG_TC_PZOOM_PrevZoomReqInputWidth //2560 */
+ 0x0F1205A0, /*REG_TC_PZOOM_PrevZoomReqInputHeight //1440 */
+ 0x0F120000, /*REG_TC_PZOOM_PrevZoomReqInputWidthOfs */
+ 0x0F120000, /*REG_TC_PZOOM_PrevZoomReqInputHeightOfs */
+ 0x002A02A6,
+ 0x0F120500, /*REG_0TC_PCFG_usWidth //1280 */
+ 0x0F1202D0, /*REG_0TC_PCFG_usHeight //720 */
+
+ /* Frame Rate */
+ 0x002A02BE,
+ 0x0F120000, /*REG_0TC_PCFG_usFrTimeType */
+ 0x0F120001, /*REG_0TC_PCFG_FrRateQualityType */
+ 0x0F12014A,/*REG_0TC_PCFG_usMaxFrTimeMsecMult10 //014Ah:30fps */
+ 0x0F12014A,/*REG_0TC_PCFG_usMinFrTimeMsecMult10 //014Ah:30fps */
+
+ /* AE Target */
+ 0x002A1484,
+ 0x0F12002A, /*003C //TVAR_ae_BrAve */
+
+ /* AE Weight Matrix */
+ 0x002A1492,
+ 0x0F120101, /*0100 */
+ 0x0F120101, /*0101 */
+ 0x0F120101, /*0101 */
+ 0x0F120101, /*0001 */
+ 0x0F120101, /*0101 */
+ 0x0F120101, /*0201 */
+ 0x0F120101, /*0102 */
+ 0x0F120101, /*0101 */
+ 0x0F120101, /*0101 */
+ 0x0F120101, /*0202 */
+ 0x0F120101, /*0202 */
+ 0x0F120101, /*0101 */
+ 0x0F120101, /*0201 */
+ 0x0F120101, /*0302 */
+ 0x0F120101, /*0203 */
+ 0x0F120101, /*0102 */
+ 0x0F120101, /*0201 */
+ 0x0F120101, /*0302 */
+ 0x0F120101, /*0203 */
+ 0x0F120101, /*0102 */
+ 0x0F120101, /*0101 */
+ 0x0F120101, /*0202 */
+ 0x0F120101, /*0202 */
+ 0x0F120101, /*0101 */
+ 0x0F120101, /*0101 */
+ 0x0F120101, /*0201 */
+ 0x0F120101, /*0102 */
+ 0x0F120101, /*0101 */
+ 0x0F120101, /*0101 */
+ 0x0F120101, /*0101 */
+ 0x0F120101, /*0101 */
+ 0x0F120101, /*0101 */
+
+ /* Slow AE */
+ 0x002A1568,
+ 0x0F120030, /*0010 //ae_GainIn_0_ */
+ 0x0F120090, /*0020 //ae_GainIn_1_ */
+ 0x0F1200A8, /*0040 //ae_GainIn_2_ */
+ 0x0F1200C0, /*0080 //ae_GainIn_3_ */
+ 0x0F120100, /*0010 //ae_GainIn_4_ FIX */
+ 0x0F120140, /*0200 //ae_GainIn_5_ */
+ 0x0F120180, /*0400 //ae_GainIn_6_ */
+ 0x0F120400, /*0800 //ae_GainIn_7_ */
+ 0x0F122000, /*0800 //ae_GainIn_8_ */
+ 0x0F120080, /*0010 //ae_GainOut_0_ */
+ 0x0F1200D0, /*0020 //ae_GainOut_1_ */
+ 0x0F1200D8, /*0040 //ae_GainOut_2_ */
+ 0x0F1200F8, /*0080 //ae_GainOut_3_ */
+ 0x0F120100, /*0100 //ae_GainOut_4_ FIX */
+ 0x0F120103, /*0200 //ae_GainOut_5_ */
+ 0x0F120110, /*0400 //ae_GainOut_6_ */
+ 0x0F120150, /*0800 //ae_GainOut_7_ */
+ 0x0F120400, /*2000 //ae_GainOut_8_*/
+ 0x002A0544,
+ 0x0F120105, /*0111 //lt_uLimitHigh */
+ 0x0F1200FA, /*00EF //lt_uLimitLow */
+ 0x002A0588,
+ 0x0F120001, /*0000 //lt_uInitPostToleranceCnt */
+ 0x002A0582,
+ 0x0F1200D0, /*0000 //lt_uSlowFilterCoef */
+
+ 0x002A0734, /*R*/
+ 0x0F120000,
+ 0x0F120005,
+ 0x0F12000F,
+ 0x0F120026,
+ 0x0F120066,
+ 0x0F1200D5,
+ 0x0F120138,
+ 0x0F120163,
+ 0x0F120189,
+ 0x0F1201C6,
+ 0x0F1201F8,
+ 0x0F120222,
+ 0x0F120247,
+ 0x0F120282,
+ 0x0F1202B5,
+ 0x0F12030F,
+ 0x0F12035F,
+ 0x0F1203A2,
+ 0x0F1203D8,
+ 0x0F1203FF,
+
+ 0x0F120000, /*G*/
+ 0x0F120005,
+ 0x0F12000F,
+ 0x0F120026,
+ 0x0F120066,
+ 0x0F1200D5,
+ 0x0F120138,
+ 0x0F120163,
+ 0x0F120189,
+ 0x0F1201C6,
+ 0x0F1201F8,
+ 0x0F120222,
+ 0x0F120247,
+ 0x0F120282,
+ 0x0F1202B5,
+ 0x0F12030F,
+ 0x0F12035F,
+ 0x0F1203A2,
+ 0x0F1203D8,
+ 0x0F1203FF,
+
+ 0x0F120000, /*B*/
+ 0x0F120005,
+ 0x0F12000F,
+ 0x0F120026,
+ 0x0F120066,
+ 0x0F1200D5,
+ 0x0F120138,
+ 0x0F120163,
+ 0x0F120189,
+ 0x0F1201C6,
+ 0x0F1201F8,
+ 0x0F120222,
+ 0x0F120247,
+ 0x0F120282,
+ 0x0F1202B5,
+ 0x0F12030F,
+ 0x0F12035F,
+ 0x0F1203A2,
+ 0x0F1203D8,
+ 0x0F1203FF,
+
+ /* Slow AWB */
+ 0x002A139A,
+ 0x0F120158, /*0258 //awbb_GainsMaxMove */
+
+ /* AWB Convergence Speed */
+ 0x002A1464,
+ 0x0F120008, /*awbb_WpFilterMinThr */
+ 0x0F12FFFF, /*0190 //awbb_WpFilterMaxThr */
+ 0x0F120010, /*00A0 //awbb_WpFilterCoef */
+ 0x0F120020, /*0004 //awbb_WpFilterSize */
+ 0x002A0938,
+ 0x0F120001,/*0000 // on/off AFIT by NB option */
+ 0x0F120014, /*0014//SARR_uNormBrInDoor */
+ 0x0F1200D2, /*00D2//SARR_uNormBrInDoor */
+ 0x0F120784, /*0384//SARR_uNormBrInDoor */
+ 0x0F1210D0, /*07D0//SARR_uNormBrInDoor */
+ 0x0F121388, /*1388//SARR_uNormBrInDoor */
+ 0x002A098C,
+ 0x0F120000, /*0000//7000098C//_BRIGHTNESS AFIT 0 */
+ 0x0F120000, /*0000//7000098E//_CONTRAST */
+ 0x0F120000, /*0000//70000990//_SATURATION */
+ 0x0F120000, /*0000//70000992//_SHARP_BLUR */
+ 0x0F120000, /*0000//70000994//_GLAMOUR */
+ 0x0F1200C0, /*00C0//70000996//_bnr_edge_high */
+ 0x0F120064, /*0064//70000998//_postdmsc_iLowBright */
+ 0x0F120384, /*0384//7000099A//_postdmsc_iHighBright */
+ 0x0F120051, /*005F//7000099C//_postdmsc_iLowSat */
+ 0x0F1201F4, /*01F4//7000099E//_postdmsc_iHighSat */
+ 0x0F120070, /*0070//700009A0//_postdmsc_iTune */
+ 0x0F120040, /*0040//700009A2//_yuvemix_mNegRanges_0 */
+ 0x0F1200A0, /*00A0//700009A4//_yuvemix_mNegRanges_1 */
+ 0x0F120100, /*0100//700009A6//_yuvemix_mNegRanges_2 */
+ 0x0F120010, /*0010//700009A8//_yuvemix_mPosRanges_0 */
+ 0x0F120060, /*0040//700009AA//_yuvemix_mPosRanges_1 */
+ 0x0F120100, /*00A0//700009AC//_yuvemix_mPosRanges_2 */
+ 0x0F121430, /*1430//700009AE//_bnr_edge_low */
+ 0x0F120201, /*0201//700009B0//_bnr_repl_force */
+ 0x0F120204, /*0204//700009B2//_bnr_iHotThreshLow */
+ 0x0F122404, /*3604//700009B4//_bnr_iColdThreshLow */
+ 0x0F12031B, /*032A//700009B6//_bnr_DispTH_High */
+ 0x0F120103, /*0403//700009B8//_bnr_DISP_Limit_High */
+ 0x0F121205, /*1B06//700009BA//_bnr_iDistSigmaMax */
+ 0x0F12400D, /*6015//700009BC//_bnr_iDiffSigmaHigh */
+ 0x0F120080, /*00C0//700009BE//_bnr_iNormalizedSTD_Limit */
+ 0x0F122080, /*6080//700009C0//_bnr_iDirMinThres */
+ 0x0F123040, /*4080//700009C2//_bnr_iDirFltDiffThresLow*/
+ 0x0F120630, /*0640//700009C4//_bnr_iDirSmoothPowerLow*/
+ 0x0F120306, /*0306//700009C6//_bnr_iHighMaxSlopeAllowed */
+ 0x0F122003, /*2003//700009C8//_bnr_iHighSlopeThresh*/
+ 0x0F12FF01, /*FF01//700009CA//_bnr_iSlopeBlurStrength */
+ 0x0F120404, /*0000//700009CC//_bnr_AddNoisePower1 */
+ 0x0F120300, /*0400//700009CE//_bnr_iRadialTune */
+ 0x0F12245A, /*365A//700009D0//_bnr_iRadialLimit */
+ 0x0F121018, /*102A//700009D2//_ee_iFSMagThHigh */
+ 0x0F12000B, /*000B//700009D4//_ee_iFSVarThHigh */
+ 0x0F120B00, /*0600//700009D6//_ee_iFSThHigh */
+ 0x0F125A0F, /*5A0F//700009D8//_ee_iFSVarCountTh */
+ 0x0F120505, /*0505//700009DA//_ee_iRadialPower */
+ 0x0F121802, /*1802//700009DC//_ee_iROADThres */
+ 0x0F120000, /*0000//700009DE//_ee_iROADSubMaxNR */
+ 0x0F122006, /*2006//700009E0//_ee_iROADNeiThres */
+ 0x0F123428, /*3028//700009E2//_ee_iSmoothEdgeThres */
+ 0x0F12041C, /*0418//700009E4//_ee_iWSharpen */
+ 0x0F120101, /*0101//700009E6//_ee_iWShThresh */
+ 0x0F120800, /*0800//700009E8//_ee_iEmbossCentAdd */
+ 0x0F121004, /*1804//700009EA//_ee_iReduceEdgeThresh */
+ 0x0F124008, /*4008//700009EC//_dmsc_iDesatThresh */
+ 0x0F120540, /*0540//700009EE//_dmsc_iDemBlurLow */
+ 0x0F128006, /*8006//700009F0//_dmsc_iDecisionThresh */
+ 0x0F120020, /*0020//700009F2//_dmsc_iMonochrom */
+ 0x0F120000, /*0000//700009F4//_dmsc_iGRDenoiseVal */
+ 0x0F121800, /*2000//700009F6//_dmsc_iEdgeDesatThrLow */
+ 0x0F120000, /*0000//700009F8//_dmsc_iNearGrayDesat */
+ 0x0F121E10, /*1E10//700009FA//_postdmsc_iBCoeff */
+ 0x0F12000B, /*000B//700009FC//_postdmsc_iWideMult */
+ 0x0F120607, /*0607//700009FE//_yuvemix_mNegSlopes_1 */
+ 0x0F120005, /*0005//70000A00//_yuvemix_mNegSlopes_3 */
+ 0x0F120607, /*0607//70000A02//_yuvemix_mPosSlopes_1 */
+ 0x0F120405, /*0705//70000A04//_yuvemix_mPosSlopes_3 */
+ 0x0F120205, /*0206//70000A06//_yuviirnr_iXSupportUV */
+ 0x0F120304, /*0304//70000A08//_yuviirnr_iHighYNorm */
+ 0x0F120409, /*0309//70000A0A//_yuviirnr_iHighUVNorm */
+ 0x0F120306, /*0305//70000A0C//_yuviirnr_iUVNormShift */
+ 0x0F120407, /*2006//70000A0E//_yuviirnr_iVertLength_UV */
+ 0x0F121F04, /*1320//70000A10//_yuviirnr_iDiffThreshH_Y */
+ 0x0F120218, /*1014//70000A12//_yuviirnr_iDiffThreshH_UV */
+ 0x0F121102, /*1010//70000A14//_yuviirnr_iMaxThreshH_Y */
+ 0x0F120611, /*0C10//70000A16//_yuviirnr_iMaxThreshH_UV */
+ 0x0F121A02, /*1A0C//70000A18//_yuviirnr_iYNRStrengthH */
+ 0x0F128018, /*4A18//70000A1A//_yuviirnr_iUVNRStrengthH */
+ 0x0F1200B0, /*0080//70000A1C//_RGBGamma2_iLinearity */
+ 0x0F121080, /*0350//70000A1E//_ccm_oscar_iSaturation */
+ 0x0F120180, /*0180//70000A20//_RGB2YUV_iRGBGain */
+ 0x0F120A0A, /*0A0A//70000A22//_bnr_iClustMulT_H */
+ 0x0F120101, /*0101//70000A24//_bnr_iClustThresh_H */
+ 0x0F121B24, /*2A36//70000A26//_bnr_iDenThreshLow */
+ 0x0F126024, /*6024//70000A28//_ee_iLowSharpPower */
+ 0x0F121D22, /*2A36//70000A2A//_ee_iLowShDenoise */
+ 0x0F12FFFF, /*FFFF//70000A2C//_ee_iLowSharpClamp */
+ 0x0F120808, /*0808//70000A2E//_ee_iReduceEdgeMinMult */
+ 0x0F120A01, /*0A01//70000A30//_bnr_nClustLevel_H_Bin */
+ 0x0F12010A, /*010A//70000A32//_bnr_iClustMulT_C_Bin */
+ 0x0F122401, /*2701//70000A34//_bnr_iClustThresh_C_Bin*/
+ 0x0F12241B, /*241E//70000A36//_bnr_iDenThreshHigh_Bin*/
+ 0x0F121E60, /*2E60//70000A38//_ee_iHighSharpPower_Bin*/
+ 0x0F12FF18, /*FF22//70000A3A//_ee_iHighShDenoise_Bin */
+ 0x0F1208FF, /*40FF//70000A3C//_ee_iHighSharpClamp_Bin */
+ 0x0F120008, /*0009//70000A3E//_ee_iReduceEdgeSlope_Bin */
+ 0x0F120001, /*0001//70000A40//_bnr_nClustLevel_C */
+ 0x0F120000, /*0000//70000A42//_BRIGHTNESS AFIT 1 */
+ 0x0F120000, /*0000//70000A44//_CONTRAST */
+ 0x0F120000, /*0000//70000A46//_SATURATION */
+ 0x0F120000, /*0000//70000A48//_SHARP_BLUR */
+ 0x0F120000, /*0000//70000A4A//_GLAMOUR */
+ 0x0F1200C0, /*00C0//70000A4C//_bnr_edge_high */
+ 0x0F120064, /*0064//70000A4E//_postdmsc_iLowBright */
+ 0x0F120384, /*0384//70000A50//_postdmsc_iHighBright */
+ 0x0F120051, /*0051//70000A52//_postdmsc_iLowSat */
+ 0x0F1201F4, /*01F4//70000A54//_postdmsc_iHighSat */
+ 0x0F120070, /*0070//70000A56//_postdmsc_iTune */
+ 0x0F120040, /*0040//70000A58//_yuvemix_mNegRanges_0 */
+ 0x0F1200A0, /*00A0//70000A5A//_yuvemix_mNegRanges_1 */
+ 0x0F120100, /*0100//70000A5C//_yuvemix_mNegRanges_2 */
+ 0x0F120010, /*0010//70000A5E//_yuvemix_mPosRanges_0 */
+ 0x0F120060, /*0060//70000A60//_yuvemix_mPosRanges_1 */
+ 0x0F120100, /*0100//70000A62//_yuvemix_mPosRanges_2 */
+ 0x0F121430, /*1430//70000A64//_bnr_edge_low */
+ 0x0F120201, /*0201//70000A66//_bnr_repl_force */
+ 0x0F120204, /*0204//70000A68//_bnr_iHotThreshLow */
+ 0x0F121B04, /*2404//70000A6A//_bnr_iColdThreshLow */
+ 0x0F120312, /*031B//70000A6C//_bnr_DispTH_High */
+ 0x0F120003, /*0103//70000A6E//_bnr_DISP_Limit_High */
+ 0x0F120C03, /*1205//70000A70//_bnr_iDistSigmaMax */
+ 0x0F122806, /*400D//70000A72//_bnr_iDiffSigmaHigh */
+ 0x0F120060, /*0080//70000A74//_bnr_iNormalizedSTD_Limit */
+ 0x0F121540, /*1980//70000A76//_bnr_iDirMinThres */
+ 0x0F12201C, /*272E//70000A78//_bnr_iDirFltDiffThresLow */
+ 0x0F120620, /*0629//70000A7A//_bnr_iDirSmoothPowerLow */
+ 0x0F120306, /*0306//70000A7C//_bnr_iHighMaxSlopeAllowed */
+ 0x0F122003, /*2003//70000A7E//_bnr_iHighSlopeThresh */
+ 0x0F12FF01, /*FF01//70000A80//_bnr_iSlopeBlurStrength */
+ 0x0F120404, /*0404//70000A82//_bnr_AddNoisePower1 */
+ 0x0F120300, /*0300//70000A84//_bnr_iRadialTune */
+ 0x0F12145A, /*245A//70000A86//_bnr_iRadialLimit */
+ 0x0F121010, /*1018//70000A88//_ee_iFSMagThHigh */
+ 0x0F12000B, /*000B//70000A8A//_ee_iFSVarThHigh */
+ 0x0F120B00, /*0B00//70000A8C//_ee_iFSThHigh */
+ 0x0F125A0F, /*5A0F//70000A8E//_ee_iFSVarCountTh */
+ 0x0F120503, /*0505//70000A90//_ee_iRadialPower */
+ 0x0F121802, /*1802//70000A92//_ee_iROADThres */
+ 0x0F120000, /*0000//70000A94//_ee_iROADSubMaxNR */
+ 0x0F122006, /*2006//70000A96//_ee_iROADNeiThres */
+ 0x0F123C28, /*3828//70000A98//_ee_iSmoothEdgeThres */
+ 0x0F120428, /*0425//70000A9A//_ee_iWSharpen */
+ 0x0F120101, /*0101//70000A9C//_ee_iWShThresh */
+ 0x0F128000, /*0800//70000A9E//_ee_iEmbossCentAdd */
+ 0x0F121004, /*1004//70000AA0//_ee_iReduceEdgeThresh */
+ 0x0F124008, /*4008//70000AA2//_dmsc_iDesatThresh */
+ 0x0F120540, /*0540//70000AA4//_dmsc_iDemBlurLow */
+ 0x0F128006, /*8006//70000AA6//_dmsc_iDecisionThresh */
+ 0x0F120020, /*0020//70000AA8//_dmsc_iMonochrom */
+ 0x0F120000, /*0000//70000AAA//_dmsc_iGRDenoiseVal */
+ 0x0F121800, /*2000//70000AAC//_dmsc_iEdgeDesatThrLow */
+ 0x0F120000, /*0000//70000AAE//_dmsc_iNearGrayDesat */
+ 0x0F121E10, /*1E10//70000AB0//_postdmsc_iBCoeff */
+ 0x0F12000B, /*000B//70000AB2//_postdmsc_iWideMult */
+ 0x0F120607, /*0607//70000AB4//_yuvemix_mNegSlopes_1 */
+ 0x0F120005, /*0005//70000AB6//_yuvemix_mNegSlopes_3 */
+ 0x0F120607, /*0607//70000AB8//_yuvemix_mPosSlopes_1 */
+ 0x0F120405, /*0405//70000ABA//_yuvemix_mPosSlopes_3 */
+ 0x0F120205, /*0205//70000ABC//_yuviirnr_iXSupportUV */
+ 0x0F120304, /*0304//70000ABE//_yuviirnr_iHighYNorm */
+ 0x0F120409, /*0409//70000AC0//_yuviirnr_iHighUVNorm */
+ 0x0F120306, /*0306//70000AC2//_yuviirnr_iUVNormShift */
+ 0x0F120407, /*0407//70000AC4//_yuviirnr_iVertLength_UV*/
+ 0x0F121F04, /*2204//70000AC6//_yuviirnr_iDiffThreshH_Y*/
+ 0x0F120228, /*021C//70000AC8//_yuviirnr_iDiffThreshH_UV */
+ 0x0F121402, /*1102//70000ACA//_yuviirnr_iMaxThreshH_Y */
+ 0x0F120618, /*0611//70000ACC//_yuviirnr_iMaxThreshH_UV */
+ 0x0F121A02, /*1A02//70000ACE//_yuviirnr_iYNRStrengthH */
+ 0x0F128018, /*8018//70000AD0//_yuviirnr_iUVNRStrengthH*/
+ 0x0F1200A0, /*0080//70000AD2//_RGBGamma2_iLinearity */
+ 0x0F121080, /*0374//70000AD4//_ccm_oscar_iSaturation */
+ 0x0F120180, /*0180//70000AD6//_RGB2YUV_iRGBGain */
+ 0x0F120A0A, /*0A0A//70000AD8//_bnr_iClustMulT_H */
+ 0x0F120101, /*0101//70000ADA//_bnr_iClustThresh_H */
+ 0x0F121B24, /*141D//70000ADC//_bnr_iDenThreshLow */
+ 0x0F126024, /*6024//70000ADE//_ee_iLowSharpPower */
+ 0x0F120C0C, /*1217//70000AE0//_ee_iLowShDenoise */
+ 0x0F12FFFF, /*FFFF//70000AE2//_ee_iLowSharpClamp */
+ 0x0F120808, /*0808//70000AE4//_ee_iReduceEdgeMinMult */
+ 0x0F120A01, /*0A01//70000AE6//_bnr_nClustLevel_H_Bin */
+ 0x0F12010A, /*010A//70000AE8//_bnr_iClustMulT_C_Bin */
+ 0x0F121501, /*0001//70000AEA//_bnr_iClustThresh_C_Bin*/
+ 0x0F12240F, /*2400//70000AEC//_bnr_iDenThreshHigh_Bin*/
+ 0x0F120C60, /*1660//70000AEE//_ee_iHighSharpPower_Bin*/
+ 0x0F12FF0C, /*FF10//70000AF0//_ee_iHighShDenoise_Bin */
+ 0x0F1208FF, /*40FF//70000AF2//_ee_iHighSharpClamp_Bin*/
+ 0x0F120008, /*0009//70000AF4//_ee_iReduceEdgeSlope_Bin */
+ 0x0F120001, /*0001//70000AF6//_bnr_nClustLevel_C */
+ 0x0F120000, /*0000//70000AF8//_BRIGHTNESS AFIT 2 */
+ 0x0F120000, /*0000//70000AFA//_CONTRAST */
+ 0x0F120000, /*0000//70000AFC//_SATURATION */
+ 0x0F120000, /*0000//70000AFE//_SHARP_BLUR */
+ 0x0F120000, /*0000//70000B00//_GLAMOUR */
+ 0x0F1200C0, /*00C0//70000B02//_bnr_edge_high */
+ 0x0F120064, /*0064//70000B04//_postdmsc_iLowBright */
+ 0x0F120384, /*0384//70000B06//_postdmsc_iHighBright */
+ 0x0F120043, /*0043//70000B08//_postdmsc_iLowSat */
+ 0x0F1201F4, /*01F4//70000B0A//_postdmsc_iHighSat */
+ 0x0F120070, /*0070//70000B0C//_postdmsc_iTune */
+ 0x0F120040, /*0040//70000B0E//_yuvemix_mNegRanges_0 */
+ 0x0F1200A0, /*00A0//70000B10//_yuvemix_mNegRanges_1 */
+ 0x0F120100, /*0100//70000B12//_yuvemix_mNegRanges_2 */
+ 0x0F120010, /*0010//70000B14//_yuvemix_mPosRanges_0 */
+ 0x0F120060, /*0060//70000B16//_yuvemix_mPosRanges_1 */
+ 0x0F120100, /*0100//70000B18//_yuvemix_mPosRanges_2 */
+ 0x0F121430, /*1430//70000B1A//_bnr_edge_low */
+ 0x0F120201, /*0201//70000B1C//_bnr_repl_force */
+ 0x0F120204, /*0204//70000B1E//_bnr_iHotThreshLow */
+ 0x0F121B04, /*1B04//70000B20//_bnr_iColdThreshLow */
+ 0x0F120312, /*0312//70000B22//_bnr_DispTH_High */
+ 0x0F120003, /*0003//70000B24//_bnr_DISP_Limit_High */
+ 0x0F120C03, /*0C03//70000B26//_bnr_iDistSigmaMax */
+ 0x0F122806, /*2806//70000B28//_bnr_iDiffSigmaHigh */
+ 0x0F120060, /*0060//70000B2A//_bnr_iNormalizedSTD_Limit*/
+ 0x0F121540, /*1580//70000B2C//_bnr_iDirMinThres */
+ 0x0F12201C, /*2020//70000B2E//_bnr_iDirFltDiffThresLow */
+ 0x0F120620, /*0620//70000B30//_bnr_iDirSmoothPowerLow */
+ 0x0F120306, /*0306//70000B32//_bnr_iHighMaxSlopeAllowed*/
+ 0x0F122003, /*2003//70000B34//_bnr_iHighSlopeThresh */
+ 0x0F12FF01, /*FF01//70000B36//_bnr_iSlopeBlurStrength*/
+ 0x0F120404, /*0404//70000B38//_bnr_AddNoisePower1 */
+ 0x0F120300, /*0300//70000B3A//_bnr_iRadialTune */
+ 0x0F12145A, /*145A//70000B3C//_bnr_iRadialLimit */
+ 0x0F121010, /*1010//70000B3E//_ee_iFSMagThHigh*/
+ 0x0F12000B, /*000B//70000B40//_ee_iFSVarThHigh*/
+ 0x0F120E00, /*0E00//70000B42//_ee_iFSThHigh */
+ 0x0F125A0F, /*5A0F//70000B44//_ee_iFSVarCountTh */
+ 0x0F120503, /*0504//70000B46//_ee_iRadialPower*/
+ 0x0F121802, /*1802//70000B48//_ee_iROADThres */
+ 0x0F120000, /*0000//70000B4A//_ee_iROADSubMaxNR */
+ 0x0F122006, /*2006//70000B4C//_ee_iROADNeiThres */
+ 0x0F123C28, /*3828//70000B4E//_ee_iSmoothEdgeThres */
+ 0x0F120428, /*0428//70000B50//_ee_iWSharpen */
+ 0x0F120101, /*0101//70000B52//_ee_iWShThresh */
+ 0x0F128000, /*8000//70000B54//_ee_iEmbossCentAdd */
+ 0x0F120A04, /*0A04//70000B56//_ee_iReduceEdgeThresh */
+ 0x0F124008, /*4008//70000B58//_dmsc_iDesatThresh */
+ 0x0F120540, /*0540//70000B5A//_dmsc_iDemBlurLow */
+ 0x0F128006, /*8006//70000B5C//_dmsc_iDecisionThresh */
+ 0x0F120020, /*0020//70000B5E//_dmsc_iMonochrom */
+ 0x0F120000, /*0000//70000B60//_dmsc_iGRDenoiseVal */
+ 0x0F121800, /*2000//70000B62//_dmsc_iEdgeDesatThrLow */
+ 0x0F120000, /*0000//70000B64//_dmsc_iNearGrayDesat */
+ 0x0F121E10, /*1E10//70000B66//_postdmsc_iBCoeff */
+ 0x0F12000B, /*000B//70000B68//_postdmsc_iWideMult */
+ 0x0F120607, /*0607//70000B6A//_yuvemix_mNegSlopes_1 */
+ 0x0F120005, /*0005//70000B6C//_yuvemix_mNegSlopes_3 */
+ 0x0F120607, /*0607//70000B6E//_yuvemix_mPosSlopes_1 */
+ 0x0F120405, /*0405//70000B70//_yuvemix_mPosSlopes_3 */
+ 0x0F120205, /*0207//70000B72//_yuviirnr_iXSupportUV */
+ 0x0F120304, /*0304//70000B74//_yuviirnr_iHighYNorm */
+ 0x0F120409, /*0409//70000B76//_yuviirnr_iHighUVNorm */
+ 0x0F120306, /*0306//70000B78//_yuviirnr_iUVNormShift */
+ 0x0F120407, /*0407//70000B7A//_yuviirnr_iVertLength_UV*/
+ 0x0F122404, /*2404//70000B7C//_yuviirnr_iDiffThreshH_Y*/
+ 0x0F120228, /*0221//70000B7E//_yuviirnr_iDiffThreshH_UV */
+ 0x0F121402, /*1202//70000B80//_yuviirnr_iMaxThreshH_Y */
+ 0x0F120618, /*0613//70000B82//_yuviirnr_iMaxThreshH_UV */
+ 0x0F121A02, /*1A02//70000B84//_yuviirnr_iYNRStrengthH */
+ 0x0F128018, /*8018//70000B86//_yuviirnr_iUVNRStrengthH */
+ 0x0F120080, /*0080//70000B88//_RGBGamma2_iLinearity */
+ 0x0F121080, /*0080//70000B8A//_ccm_oscar_iSaturation */
+ 0x0F120180, /*0180//70000B8C//_RGB2YUV_iRGBGain */
+ 0x0F120A0A, /*0A0A//70000B8E//_bnr_iClustMulT_H */
+ 0x0F120101, /*0101//70000B90//_bnr_iClustThresh_H */
+ 0x0F12141D, /*121B//70000B92//_bnr_iDenThreshLow */
+ 0x0F126024, /*6024//70000B94//_ee_iLowSharpPower */
+ 0x0F120C0C, /*0C0C//70000B96//_ee_iLowShDenoise */
+ 0x0F12FFFF, /*FFFF//70000B98//_ee_iLowSharpClamp */
+ 0x0F120808, /*0808//70000B9A//_ee_iReduceEdgeMinMult */
+ 0x0F120A01, /*0A01//70000B9C//_bnr_nClustLevel_H_Bin */
+ 0x0F12010A, /*010A//70000B9E//_bnr_iClustMulT_C_Bin */
+ 0x0F121501, /*0001//70000BA0//_bnr_iClustThresh_C_Bin*/
+ 0x0F12240F, /*2400//70000BA2//_bnr_iDenThreshHigh_Bin*/
+ 0x0F120C60, /*0460//70000BA4//_ee_iHighSharpPower_Bin*/
+ 0x0F12FF0C, /*FF04//70000BA6//_ee_iHighShDenoise_Bin*/
+ 0x0F1208FF, /*40FF//70000BA8//_ee_iHighSharpClamp_Bin */
+ 0x0F120008, /*0009//70000BAA//_ee_iReduceEdgeSlope_Bin */
+ 0x0F120001, /*0001//70000BAC//_bnr_nClustLevel_C */
+ 0x0F120000, /*0000//70000BAE//_BRIGHTNESS AFIT 3 */
+ 0x0F120000, /*0000//70000BB0//_CONTRAST */
+ 0x0F120000, /*0000//70000BB2//_SATURATION */
+ 0x0F120000, /*0000//70000BB4//_SHARP_BLUR */
+ 0x0F120000, /*0000//70000BB6//_GLAMOUR */
+ 0x0F1200C0, /*00C0//70000BB8//_bnr_edge_high */
+ 0x0F120064, /*0064//70000BBA//_postdmsc_iLowBright */
+ 0x0F120384, /*0384//70000BBC//_postdmsc_iHighBright */
+ 0x0F120032, /*0032//70000BBE//_postdmsc_iLowSat */
+ 0x0F1201F4, /*01F4//70000BC0//_postdmsc_iHighSat */
+ 0x0F120070, /*0070//70000BC2//_postdmsc_iTune */
+ 0x0F120040, /*0040//70000BC4//_yuvemix_mNegRanges_0 */
+ 0x0F1200A0, /*00A0//70000BC6//_yuvemix_mNegRanges_1 */
+ 0x0F120100, /*0100//70000BC8//_yuvemix_mNegRanges_2 */
+ 0x0F120010, /*0010//70000BCA//_yuvemix_mPosRanges_0 */
+ 0x0F120060, /*0060//70000BCC//_yuvemix_mPosRanges_1 */
+ 0x0F120100, /*0100//70000BCE//_yuvemix_mPosRanges_2 */
+ 0x0F121430, /*1430//70000BD0//_bnr_edge_low */
+ 0x0F120201, /*0201//70000BD2//_bnr_repl_force */
+ 0x0F120204, /*0204//70000BD4//_bnr_iHotThreshLow */
+ 0x0F121504, /*1504//70000BD6//_bnr_iColdThreshLow */
+ 0x0F12030F, /*030F//70000BD8//_bnr_DispTH_High */
+ 0x0F120003, /*0003//70000BDA//_bnr_DISP_Limit_High */
+ 0x0F120902, /*0902//70000BDC//_bnr_iDistSigmaMax */
+ 0x0F122004, /*2004//70000BDE//_bnr_iDiffSigmaHigh */
+ 0x0F120050, /*0050//70000BE0//_bnr_iNormalizedSTD_Limit*/
+ 0x0F121140, /*1140//70000BE2//_bnr_iDirMinThres */
+ 0x0F12201C, /*201C//70000BE4//_bnr_iDirFltDiffThresLow */
+ 0x0F120620, /*0620//70000BE6//_bnr_iDirSmoothPowerLow */
+ 0x0F120306, /*0306//70000BE8//_bnr_iHighMaxSlopeAllowed*/
+ 0x0F122003, /*2003//70000BEA//_bnr_iHighSlopeThresh */
+ 0x0F12FF01, /*FF01//70000BEC//_bnr_iSlopeBlurStrength*/
+ 0x0F120404, /*0404//70000BEE//_bnr_AddNoisePower1 */
+ 0x0F120300, /*0300//70000BF0//_bnr_iRadialTune */
+ 0x0F12145A, /*145A//70000BF2//_bnr_iRadialLimit */
+ 0x0F121010, /*1010//70000BF4//_ee_iFSMagThHigh */
+ 0x0F12000B, /*000B//70000BF6//_ee_iFSVarThHigh */
+ 0x0F121000, /*1000//70000BF8//_ee_iFSThHigh */
+ 0x0F125A0F, /*5A0F//70000BFA//_ee_iFSVarCountTh */
+ 0x0F120503, /*0503//70000BFC//_ee_iRadialPower */
+ 0x0F121802, /*1802//70000BFE//_ee_iROADThres */
+ 0x0F120000, /*0000//70000C00//_ee_iROADSubMaxNR */
+ 0x0F122006, /*2006//70000C02//_ee_iROADNeiThres */
+ 0x0F123C28, /*3C28//70000C04//_ee_iSmoothEdgeThres */
+ 0x0F12042C, /*042C//70000C06//_ee_iWSharpen */
+ 0x0F120101, /*0101//70000C08//_ee_iWShThresh */
+ 0x0F128000, /*FF00//70000C0A//_ee_iEmbossCentAdd */
+ 0x0F120904, /*0904//70000C0C//_ee_iReduceEdgeThresh */
+ 0x0F124008, /*4008//70000C0E//_dmsc_iDesatThresh */
+ 0x0F120540, /*0540//70000C10//_dmsc_iDemBlurLow */
+ 0x0F128006, /*8006//70000C12//_dmsc_iDecisionThresh */
+ 0x0F120020, /*0020//70000C14//_dmsc_iMonochrom */
+ 0x0F120000, /*0000//70000C16//_dmsc_iGRDenoiseVal */
+ 0x0F121800, /*2000//70000C18//_dmsc_iEdgeDesatThrLow */
+ 0x0F120000, /*0000//70000C1A//_dmsc_iNearGrayDesat */
+ 0x0F121E10, /*1E10//70000C1C//_postdmsc_iBCoeff */
+ 0x0F12000B, /*000B//70000C1E//_postdmsc_iWideMult */
+ 0x0F120607, /*0607//70000C20//_yuvemix_mNegSlopes_1 */
+ 0x0F120005, /*0005//70000C22//_yuvemix_mNegSlopes_3 */
+ 0x0F120607, /*0607//70000C24//_yuvemix_mPosSlopes_1 */
+ 0x0F120405, /*0405//70000C26//_yuvemix_mPosSlopes_3 */
+ 0x0F120205, /*0206//70000C28//_yuviirnr_iXSupportUV */
+ 0x0F120304, /*0304//70000C2A//_yuviirnr_iHighYNorm */
+ 0x0F120409, /*0409//70000C2C//_yuviirnr_iHighUVNorm */
+ 0x0F120306, /*0305//70000C2E//_yuviirnr_iUVNormShift */
+ 0x0F120407, /*0406//70000C30//_yuviirnr_iVertLength_UV*/
+ 0x0F122804, /*2804//70000C32//_yuviirnr_iDiffThreshH_Y*/
+ 0x0F120228, /*0228//70000C34//_yuviirnr_iDiffThreshH_UV */
+ 0x0F121402, /*1402//70000C36//_yuviirnr_iMaxThreshH_Y */
+ 0x0F120618, /*0618//70000C38//_yuviirnr_iMaxThreshH_UV */
+ 0x0F121A02, /*1A02//70000C3A//_yuviirnr_iYNRStrengthH */
+ 0x0F128018, /*8018//70000C3C//_yuviirnr_iUVNRStrengthH*/
+ 0x0F120080, /*0080//70000C3E//_RGBGamma2_iLinearity */
+ 0x0F121080, /*0080//70000C40//_ccm_oscar_iSaturation */
+ 0x0F120180, /*0180//70000C42//_RGB2YUV_iRGBGain */
+ 0x0F120A0A, /*0A0A//70000C44//_bnr_iClustMulT_H */
+ 0x0F120101, /*0101//70000C46//_bnr_iClustThresh_H */
+ 0x0F121117, /*0F15//70000C48//_bnr_iDenThreshLow */
+ 0x0F126024, /*6024//70000C4A//_ee_iLowSharpPower */
+ 0x0F120A0A, /*0A0A//70000C4C//_ee_iLowShDenoise */
+ 0x0F12FFFF, /*FFFF//70000C4E//_ee_iLowSharpClamp */
+ 0x0F120808, /*0808//70000C50//_ee_iReduceEdgeMinMult */
+ 0x0F120A01, /*0A01//70000C52//_bnr_nClustLevel_H_Bin */
+ 0x0F12010A, /*010A//70000C54//_bnr_iClustMulT_C_Bin */
+ 0x0F121501, /*0001//70000C56//_bnr_iClustThresh_C_Bin*/
+ 0x0F12240F, /*2400//70000C58//_bnr_iDenThreshHigh_Bin*/
+ 0x0F120A60, /*0260//70000C5A//_ee_iHighSharpPower_Bin*/
+ 0x0F12FF0A, /*FF02//70000C5C//_ee_iHighShDenoise_Bin */
+ 0x0F1208FF, /*40FF//70000C5E//_ee_iHighSharpClamp_Bin*/
+ 0x0F120008, /*0009//70000C60//_ee_iReduceEdgeSlope_Bin */
+ 0x0F120001, /*0001//70000C62//_bnr_nClustLevel_C */
+ 0x0F120000, /*0000//70000C64//_BRIGHTNESS AFIT 4 */
+ 0x0F120000, /*0000//70000C66//_CONTRAST */
+ 0x0F120000, /*0000//70000C68//_SATURATION */
+ 0x0F120000, /*0000//70000C6A//_SHARP_BLUR */
+ 0x0F120000, /*0000//70000C6C//_GLAMOUR */
+ 0x0F1200C0, /*00C0//70000C6E//_bnr_edge_high */
+ 0x0F120064, /*0064//70000C70//_postdmsc_iLowBright */
+ 0x0F120384, /*0384//70000C72//_postdmsc_iHighBright */
+ 0x0F120032, /*0032//70000C74//_postdmsc_iLowSat */
+ 0x0F1201F4, /*01F4//70000C76//_postdmsc_iHighSat */
+ 0x0F120070, /*0070//70000C78//_postdmsc_iTune */
+ 0x0F120040, /*0040//70000C7A//_yuvemix_mNegRanges_0 */
+ 0x0F1200A0, /*00A0//70000C7C//_yuvemix_mNegRanges_1 */
+ 0x0F120100, /*0100//70000C7E//_yuvemix_mNegRanges_2 */
+ 0x0F120010, /*0010//70000C80//_yuvemix_mPosRanges_0 */
+ 0x0F120060, /*0060//70000C82//_yuvemix_mPosRanges_1 */
+ 0x0F120100, /*0100//70000C84//_yuvemix_mPosRanges_2 */
+ 0x0F121430, /*1430//70000C86//_bnr_edge_low */
+ 0x0F120201, /*0201//70000C88//_bnr_repl_force */
+ 0x0F120204, /*0204//70000C8A//_bnr_iHotThreshLow */
+ 0x0F120F04, /*0F04//70000C8C//_bnr_iColdThreshLow */
+ 0x0F12030C, /*030C//70000C8E//_bnr_DispTH_High */
+ 0x0F120003, /*0003//70000C90//_bnr_DISP_Limit_High */
+ 0x0F120602, /*0602//70000C92//_bnr_iDistSigmaMax */
+ 0x0F121803, /*1803//70000C94//_bnr_iDiffSigmaHigh */
+ 0x0F120040, /*0040//70000C96//_bnr_iNormalizedSTD_Limit*/
+ 0x0F120E20, /*0E20//70000C98//_bnr_iDirMinThres */
+ 0x0F122018, /*2018//70000C9A//_bnr_iDirFltDiffThresLow */
+ 0x0F120620, /*0620//70000C9C//_bnr_iDirSmoothPowerLow */
+ 0x0F120306, /*0306//70000C9E//_bnr_iHighMaxSlopeAllowed*/
+ 0x0F122003, /*2003//70000CA0//_bnr_iHighSlopeThresh */
+ 0x0F12FF01, /*FF01//70000CA2//_bnr_iSlopeBlurStrength*/
+ 0x0F120404, /*0404//70000CA4//_bnr_AddNoisePower1 */
+ 0x0F120200, /*0200//70000CA6//_bnr_iRadialTune */
+ 0x0F12145A, /*145A//70000CA8//_bnr_iRadialLimit */
+ 0x0F121010, /*1010//70000CAA//_ee_iFSMagThHigh */
+ 0x0F12000B, /*000B//70000CAC//_ee_iFSVarThHigh */
+ 0x0F121200, /*1200//70000CAE//_ee_iFSThHigh */
+ 0x0F125A0F, /*5A0F//70000CB0//_ee_iFSVarCountTh */
+ 0x0F120502, /*0502//70000CB2//_ee_iRadialPower */
+ 0x0F121802, /*1802//70000CB4//_ee_iROADThres */
+ 0x0F120000, /*0000//70000CB6//_ee_iROADSubMaxNR */
+ 0x0F122006, /*2006//70000CB8//_ee_iROADNeiThres */
+ 0x0F124028, /*4028//70000CBA//_ee_iSmoothEdgeThres */
+ 0x0F120430, /*0430//70000CBC//_ee_iWSharpen */
+ 0x0F120101, /*0101//70000CBE//_ee_iWShThresh */
+ 0x0F12FF00, /*FF00//70000CC0//_ee_iEmbossCentAdd */
+ 0x0F120804, /*0804//70000CC2//_ee_iReduceEdgeThresh */
+ 0x0F124008, /*4008//70000CC4//_dmsc_iDesatThresh */
+ 0x0F120540, /*0540//70000CC6//_dmsc_iDemBlurLow */
+ 0x0F128006, /*8006//70000CC8//_dmsc_iDecisionThresh */
+ 0x0F120020, /*0020//70000CCA//_dmsc_iMonochrom */
+ 0x0F120000, /*0000//70000CCC//_dmsc_iGRDenoiseVal */
+ 0x0F121800, /*2000//70000CCE//_dmsc_iEdgeDesatThrLow */
+ 0x0F120000, /*0000//70000CD0//_dmsc_iNearGrayDesat */
+ 0x0F121E10, /*1E10//70000CD2//_postdmsc_iBCoeff */
+ 0x0F12000B, /*000B//70000CD4//_postdmsc_iWideMult */
+ 0x0F120607, /*0607//70000CD6//_yuvemix_mNegSlopes_1 */
+ 0x0F120005, /*0005//70000CD8//_yuvemix_mNegSlopes_3 */
+ 0x0F120607, /*0607//70000CDA//_yuvemix_mPosSlopes_1 */
+ 0x0F120405, /*0405//70000CDC//_yuvemix_mPosSlopes_3 */
+ 0x0F120205, /*0205//70000CDE//_yuviirnr_iXSupportUV */
+ 0x0F120304, /*0304//70000CE0//_yuviirnr_iHighYNorm */
+ 0x0F120409, /*0409//70000CE2//_yuviirnr_iHighUVNorm */
+ 0x0F120306, /*0306//70000CE4//_yuviirnr_iUVNormShift */
+ 0x0F120407, /*0407//70000CE6//_yuviirnr_iVertLength_UV*/
+ 0x0F122C04, /*2C04//70000CE8//_yuviirnr_iDiffThreshH_Y*/
+ 0x0F12022C, /*022C//70000CEA//_yuviirnr_iDiffThreshH_UV */
+ 0x0F121402, /*1402//70000CEC//_yuviirnr_iMaxThreshH_Y */
+ 0x0F120618, /*0618//70000CEE//_yuviirnr_iMaxThreshH_UV */
+ 0x0F121A02, /*1A02//70000CF0//_yuviirnr_iYNRStrengthH */
+ 0x0F128018, /*8018//70000CF2//_yuviirnr_iUVNRStrengthH */
+ 0x0F120080, /*0080//70000CF4//_RGBGamma2_iLinearity */
+ 0x0F121080, /*0080//70000CF6//_ccm_oscar_iSaturation */
+ 0x0F120180, /*0180//70000CF8//_RGB2YUV_iRGBGain */
+ 0x0F120A0A, /*0A0A//70000CFA//_bnr_iClustMulT_H */
+ 0x0F120101, /*0101//70000CFC//_bnr_iClustThresh_H */
+ 0x0F120C0F, /*0C0F//70000CFE//_bnr_iDenThreshLow */
+ 0x0F126024, /*6024//70000D00//_ee_iLowSharpPower */
+ 0x0F120808, /*0808//70000D02//_ee_iLowShDenoise */
+ 0x0F12FFFF, /*FFFF//70000D04//_ee_iLowSharpClamp */
+ 0x0F120808, /*0808//70000D06//_ee_iReduceEdgeMinMult */
+ 0x0F120A01, /*0A01//70000D08//_bnr_nClustLevel_H_Bin */
+ 0x0F12010A, /*010A//70000D0A//_bnr_iClustMulT_C_Bin */
+ 0x0F120F01, /*0001//70000D0C//_bnr_iClustThresh_C_Bin*/
+ 0x0F12240C, /*2400//70000D0E//_bnr_iDenThreshHigh_Bin*/
+ 0x0F120860, /*0060//70000D10//_ee_iHighSharpPower_Bin*/
+ 0x0F12FF08, /*FF00//70000D12//_ee_iHighShDenoise_Bin */
+ 0x0F1208FF, /*40FF//70000D14//_ee_iHighSharpClamp_Bin*/
+ 0x0F120008, /*0009//70000D16//_ee_iReduceEdgeSlope_Bin */
+ 0x0F120001, /*0001//70000D18//_bnr_nClustLevel_C */
+ 0x002A0266,
+ 0x0F120000, /*REG_TC_GP_ActivePrevConfig */
+ 0x002A026A,
+ 0x0F120001, /*REG_TC_GP_PrevOpenAfterChange */
+ 0x002A024E,
+ 0x0F120001, /*REG_TC_GP_NewConfigSync */
+ 0x002A0268,
+ 0x0F120001, /*REG_TC_GP_PrevConfigChanged */
+
+};
+
+static const u32 s5k4ecgx_1280_Preview_Disable_EVT1[] = {/*1280x720 */
+ /* 720P disable setting */
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A18AC,
+ 0x0F120060, /*senHal_uAddColsBin */
+ 0x0F120060, /*senHal_uAddColsNoBin */
+ 0x0F1205C0, /*senHal_uMinColsBin */
+ 0x0F1205C0, /*senHal_uMinColsNoBin */
+
+ /* Size */
+ 0x002A0250,
+ 0x0F120A00, /*REG_TC_GP_PrevReqInputWidth //2560 */
+ 0x0F120780, /*REG_TC_GP_PrevReqInputHeight //1920 */
+ 0x0F120010, /*REG_TC_GP_PrevInputWidthOfs/(2592-2560)/2*/
+ 0x0F12000C, /*REG_TC_GP_PrevInputHeightOfs/(1944-1920)/2*/
+ 0x002A0262,
+ 0x0F120001, /*REG_TC_GP_bUseReqInputInPre */
+ 0x002A0494,
+ 0x0F120A00, /*REG_TC_PZOOM_PrevZoomReqInputWidth //2560 */
+ 0x0F120780, /*REG_TC_PZOOM_PrevZoomReqInputHeight //1920 */
+ 0x0F120000, /*REG_TC_PZOOM_PrevZoomReqInputWidthOfs */
+ 0x0F120000, /*REG_TC_PZOOM_PrevZoomReqInputHeightOfs */
+ 0x002A02A6,
+ 0x0F120280, /*REG_0TC_PCFG_usWidth //640 */
+ 0x0F1201E0, /*REG_0TC_PCFG_usHeight //480 */
+
+ /* Frame Rate */
+ 0x002A02BE,
+ 0x0F120000, /*REG_0TC_PCFG_usFrTimeType*/
+ 0x0F120001, /*REG_0TC_PCFG_FrRateQualityType */
+ 0x0F1203E8, /*029A/REG_0TC_PCFG_usMaxFrTimeMsecMult10/029Ah:15fps*/
+ 0x0F12014A, /*REG_0TC_PCFG_usMinFrTimeMsecMult10/014Ah:30fps*/
+
+ /* AE Target */
+ 0x002A1484,
+ 0x0F12003C, /*TVAR_ae_BrAve */
+
+ /* AE Weight Matrix */
+ 0x002A1492,
+ 0x0F120100,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120001,
+ 0x0F120101,
+ 0x0F120201,
+ 0x0F120102,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120202,
+ 0x0F120202,
+ 0x0F120101,
+ 0x0F120201,
+ 0x0F120302,
+ 0x0F120203,
+ 0x0F120102,
+ 0x0F120201,
+ 0x0F120302,
+ 0x0F120203,
+ 0x0F120102,
+ 0x0F120101,
+ 0x0F120202,
+ 0x0F120202,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120201,
+ 0x0F120102,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+ 0x0F120101,
+
+ /* Slow AE */
+ 0x002A1568,
+ 0x0F120010, /*ae_GainIn_0_ */
+ 0x0F120020, /*ae_GainIn_1_ */
+ 0x0F120040, /*ae_GainIn_2_ */
+ 0x0F120080, /*ae_GainIn_3_ */
+ 0x0F120100, /*ae_GainIn_4_ FIX */
+ 0x0F120200, /*ae_GainIn_5_ */
+ 0x0F120400, /*ae_GainIn_6_ */
+ 0x0F120800, /*ae_GainIn_7_ */
+ 0x0F120800, /*ae_GainIn_8_ */
+ 0x0F120010, /*ae_GainOut_0_ */
+ 0x0F120020, /*ae_GainOut_1_ */
+ 0x0F120040, /*ae_GainOut_2_ */
+ 0x0F120080, /*ae_GainOut_3_ */
+ 0x0F120100, /*ae_GainOut_4_ FIX */
+ 0x0F120200, /*ae_GainOut_5_ */
+ 0x0F120400, /*ae_GainOut_6_ */
+ 0x0F120800, /*ae_GainOut_7_ */
+ 0x0F122000, /*ae_GainOut_8_ */
+ 0x002A0544,
+ 0x0F120111, /*lt_uLimitHigh */
+ 0x0F1200EF, /*lt_uLimitLow */
+ 0x002A0588,
+ 0x0F120000, /*lt_uInitPostToleranceCnt */
+ 0x002A0582,
+ 0x0F120000, /*lt_uSlowFilterCoef */
+ 0x002A0734, /*R*/
+ 0x0F120000,
+ 0x0F120001,
+ 0x0F120006,
+ 0x0F120017,
+ 0x0F12004A,
+ 0x0F1200C9,
+ 0x0F120138,
+ 0x0F120163,
+ 0x0F120189,
+ 0x0F1201C6,
+ 0x0F1201F8,
+ 0x0F120222,
+ 0x0F120247,
+ 0x0F120282,
+ 0x0F1202B5,
+ 0x0F12030F,
+ 0x0F12035F,
+ 0x0F1203A2,
+ 0x0F1203D8,
+ 0x0F1203FF,
+ 0x0F120000, /*G*/
+ 0x0F120001,
+ 0x0F120006,
+ 0x0F120017,
+ 0x0F12004A,
+ 0x0F1200C9,
+ 0x0F120138,
+ 0x0F120163,
+ 0x0F120189,
+ 0x0F1201C6,
+ 0x0F1201F8,
+ 0x0F120222,
+ 0x0F120247,
+ 0x0F120282,
+ 0x0F1202B5,
+ 0x0F12030F,
+ 0x0F12035F,
+ 0x0F1203A2,
+ 0x0F1203D8,
+ 0x0F1203FF,
+ 0x0F120000, /*B*/
+ 0x0F120001,
+ 0x0F120006,
+ 0x0F120017,
+ 0x0F12004A,
+ 0x0F1200C9,
+ 0x0F120138,
+ 0x0F120163,
+ 0x0F120189,
+ 0x0F1201C6,
+ 0x0F1201F8,
+ 0x0F120222,
+ 0x0F120247,
+ 0x0F120282,
+ 0x0F1202B5,
+ 0x0F12030F,
+ 0x0F12035F,
+ 0x0F1203A2,
+ 0x0F1203D8,
+ 0x0F1203FF,
+
+ /* Slow AWB */
+ 0x002A139A,
+ 0x0F120258, /*awbb_GainsMaxMove */
+
+ /* AWB Convergence Speed */
+ 0x002A1464,
+ 0x0F120008, /*awbb_WpFilterMinThr */
+ 0x0F120190, /*awbb_WpFilterMaxThr */
+ 0x0F1200A0, /*awbb_WpFilterCoef */
+ 0x0F120004, /*awbb_WpFilterSize */
+ 0x002A0938,
+ 0x0F120000, /* on/off AFIT by NB option */
+ 0x0F120014, /*SARR_uNormBrInDoor */
+ 0x0F1200D2, /*SARR_uNormBrInDoor */
+ 0x0F120384, /*SARR_uNormBrInDoor */
+ 0x0F1207D0, /*SARR_uNormBrInDoor */
+ 0x0F121388, /*SARR_uNormBrInDoor */
+ 0x002A098C,
+ 0x0F120000, /*7000098C//_BRIGHTNESS AFIT 0 */
+ 0x0F120000, /*7000098E//_CONTRAST */
+ 0x0F120000, /*70000990//_SATURATION */
+ 0x0F120000, /*70000992//_SHARP_BLUR */
+ 0x0F120000, /*70000994//_GLAMOUR */
+ 0x0F1200C0, /*70000996//_bnr_edge_high */
+ 0x0F120064, /*70000998//_postdmsc_iLowBright */
+ 0x0F120384, /*7000099A//_postdmsc_iHighBright */
+ 0x0F12005F, /*7000099C//_postdmsc_iLowSat */
+ 0x0F1201F4, /*7000099E//_postdmsc_iHighSat */
+ 0x0F120070, /*700009A0//_postdmsc_iTune */
+ 0x0F120040, /*700009A2//_yuvemix_mNegRanges_0 */
+ 0x0F1200A0, /*700009A4//_yuvemix_mNegRanges_1 */
+ 0x0F120100, /*700009A6//_yuvemix_mNegRanges_2 */
+ 0x0F120010, /*700009A8//_yuvemix_mPosRanges_0 */
+ 0x0F120040, /*700009AA//_yuvemix_mPosRanges_1 */
+ 0x0F1200A0, /*700009AC//_yuvemix_mPosRanges_2 */
+ 0x0F121430, /*700009AE//_bnr_edge_low */
+ 0x0F120201, /*700009B0//_bnr_repl_force */
+ 0x0F120204, /*700009B2//_bnr_iHotThreshLow */
+ 0x0F123604, /*700009B4//_bnr_iColdThreshLow */
+ 0x0F12032A, /*700009B6//_bnr_DispTH_High */
+ 0x0F120403, /*700009B8//_bnr_DISP_Limit_High */
+ 0x0F121B06, /*700009BA//_bnr_iDistSigmaMax */
+ 0x0F126015, /*700009BC//_bnr_iDiffSigmaHigh */
+ 0x0F1200C0, /*700009BE//_bnr_iNormalizedSTD_Limit */
+ 0x0F126080, /*700009C0//_bnr_iDirMinThres */
+ 0x0F124080, /*700009C2//_bnr_iDirFltDiffThresLow */
+ 0x0F120640, /*700009C4//_bnr_iDirSmoothPowerLow */
+ 0x0F120306, /*700009C6//_bnr_iHighMaxSlopeAllowed */
+ 0x0F122003, /*700009C8//_bnr_iHighSlopeThresh */
+ 0x0F12FF01, /*700009CA//_bnr_iSlopeBlurStrength */
+ 0x0F120000, /*700009CC//_bnr_AddNoisePower1 */
+ 0x0F120400, /*700009CE//_bnr_iRadialTune */
+ 0x0F12365A, /*700009D0//_bnr_iRadialLimit */
+ 0x0F12102A, /*700009D2//_ee_iFSMagThHigh */
+ 0x0F12000B, /*700009D4//_ee_iFSVarThHigh */
+ 0x0F120600, /*700009D6//_ee_iFSThHigh */
+ 0x0F125A0F, /*700009D8//_ee_iFSVarCountTh */
+ 0x0F120505, /*700009DA//_ee_iRadialPower */
+ 0x0F121802, /*700009DC//_ee_iROADThres */
+ 0x0F120000, /*700009DE//_ee_iROADSubMaxNR */
+ 0x0F122006, /*700009E0//_ee_iROADNeiThres */
+ 0x0F123028, /*700009E2//_ee_iSmoothEdgeThres */
+ 0x0F120418, /*700009E4//_ee_iWSharpen */
+ 0x0F120101, /*700009E6//_ee_iWShThresh */
+ 0x0F120800, /*700009E8//_ee_iEmbossCentAdd */
+ 0x0F121804, /*700009EA//_ee_iReduceEdgeThresh */
+ 0x0F124008, /*700009EC//_dmsc_iDesatThresh */
+ 0x0F120540, /*700009EE//_dmsc_iDemBlurLow */
+ 0x0F128006, /*700009F0//_dmsc_iDecisionThresh */
+ 0x0F120020, /*700009F2//_dmsc_iMonochrom */
+ 0x0F120000, /*700009F4//_dmsc_iGRDenoiseVal */
+ 0x0F122000, /*700009F6//_dmsc_iEdgeDesatThrLow */
+ 0x0F120000, /*700009F8//_dmsc_iNearGrayDesat */
+ 0x0F121E10, /*700009FA//_postdmsc_iBCoeff */
+ 0x0F12000B, /*700009FC//_postdmsc_iWideMult */
+ 0x0F120607, /*700009FE//_yuvemix_mNegSlopes_1 */
+ 0x0F120005, /*70000A00//_yuvemix_mNegSlopes_3 */
+ 0x0F120607, /*70000A02//_yuvemix_mPosSlopes_1 */
+ 0x0F120705, /*70000A04//_yuvemix_mPosSlopes_3 */
+ 0x0F120206, /*70000A06//_yuviirnr_iXSupportUV */
+ 0x0F120304, /*70000A08//_yuviirnr_iHighYNorm */
+ 0x0F120309, /*70000A0A//_yuviirnr_iHighUVNorm */
+ 0x0F120305, /*70000A0C//_yuviirnr_iUVNormShift */
+ 0x0F122006, /*70000A0E//_yuviirnr_iVertLength_UV */
+ 0x0F121320, /*70000A10//_yuviirnr_iDiffThreshH_Y */
+ 0x0F121014, /*70000A12//_yuviirnr_iDiffThreshH_UV */
+ 0x0F121010, /*70000A14//_yuviirnr_iMaxThreshH_Y */
+ 0x0F120C10, /*70000A16//_yuviirnr_iMaxThreshH_UV */
+ 0x0F121A0C, /*70000A18//_yuviirnr_iYNRStrengthH */
+ 0x0F124A18, /*70000A1A//_yuviirnr_iUVNRStrengthH */
+ 0x0F120080, /*70000A1C//_RGBGamma2_iLinearity */
+ 0x0F120350, /*70000A1E//_ccm_oscar_iSaturation */
+ 0x0F120180, /*70000A20//_RGB2YUV_iRGBGain */
+ 0x0F120A0A, /*70000A22//_bnr_iClustMulT_H */
+ 0x0F120101, /*70000A24//_bnr_iClustThresh_H */
+ 0x0F122A36, /*70000A26//_bnr_iDenThreshLow */
+ 0x0F126024, /*70000A28//_ee_iLowSharpPower */
+ 0x0F122A36, /*70000A2A//_ee_iLowShDenoise */
+ 0x0F12FFFF, /*70000A2C//_ee_iLowSharpClamp */
+ 0x0F120808, /*70000A2E//_ee_iReduceEdgeMinMult */
+ 0x0F120A01, /*70000A30//_bnr_nClustLevel_H_Bin */
+ 0x0F12010A, /*70000A32//_bnr_iClustMulT_C_Bin */
+ 0x0F122701, /*70000A34//_bnr_iClustThresh_C_Bin */
+ 0x0F12241E, /*70000A36//_bnr_iDenThreshHigh_Bin */
+ 0x0F122E60, /*70000A38//_ee_iHighSharpPower_Bin */
+ 0x0F12FF22, /*70000A3A//_ee_iHighShDenoise_Bin */
+ 0x0F1240FF, /*70000A3C//_ee_iHighSharpClamp_Bin */
+ 0x0F120009, /*70000A3E//_ee_iReduceEdgeSlope_Bin */
+ 0x0F120001, /*70000A40//_bnr_nClustLevel_C */
+ 0x0F120000, /*70000A42//_BRIGHTNESS AFIT 1 */
+ 0x0F120000, /*70000A44//_CONTRAST */
+ 0x0F120000, /*70000A46//_SATURATION */
+ 0x0F120000, /*70000A48//_SHARP_BLUR */
+ 0x0F120000, /*70000A4A//_GLAMOUR */
+ 0x0F1200C0, /*70000A4C//_bnr_edge_high */
+ 0x0F120064, /*70000A4E//_postdmsc_iLowBright */
+ 0x0F120384, /*70000A50//_postdmsc_iHighBright */
+ 0x0F120051, /*70000A52//_postdmsc_iLowSat */
+ 0x0F1201F4, /*70000A54//_postdmsc_iHighSat */
+ 0x0F120070, /*70000A56//_postdmsc_iTune */
+ 0x0F120040, /*70000A58//_yuvemix_mNegRanges_0 */
+ 0x0F1200A0, /*70000A5A//_yuvemix_mNegRanges_1 */
+ 0x0F120100, /*70000A5C//_yuvemix_mNegRanges_2 */
+ 0x0F120010, /*70000A5E//_yuvemix_mPosRanges_0 */
+ 0x0F120060, /*70000A60//_yuvemix_mPosRanges_1 */
+ 0x0F120100, /*70000A62//_yuvemix_mPosRanges_2 */
+ 0x0F121430, /*70000A64//_bnr_edge_low */
+ 0x0F120201, /*70000A66//_bnr_repl_force */
+ 0x0F120204, /*70000A68//_bnr_iHotThreshLow */
+ 0x0F122404, /*70000A6A//_bnr_iColdThreshLow */
+ 0x0F12031B, /*70000A6C//_bnr_DispTH_High */
+ 0x0F120103, /*70000A6E//_bnr_DISP_Limit_High */
+ 0x0F121205, /*70000A70//_bnr_iDistSigmaMax */
+ 0x0F12400D, /*70000A72//_bnr_iDiffSigmaHigh */
+ 0x0F120080, /*70000A74//_bnr_iNormalizedSTD_Limit */
+ 0x0F121980, /*70000A76//_bnr_iDirMinThres */
+ 0x0F12272E, /*70000A78//_bnr_iDirFltDiffThresLow */
+ 0x0F120629, /*70000A7A//_bnr_iDirSmoothPowerLow */
+ 0x0F120306, /*70000A7C//_bnr_iHighMaxSlopeAllowed */
+ 0x0F122003, /*70000A7E//_bnr_iHighSlopeThresh */
+ 0x0F12FF01, /*70000A80//_bnr_iSlopeBlurStrength */
+ 0x0F120404, /*70000A82//_bnr_AddNoisePower1 */
+ 0x0F120300, /*70000A84//_bnr_iRadialTune */
+ 0x0F12245A, /*70000A86//_bnr_iRadialLimit */
+ 0x0F121018, /*70000A88//_ee_iFSMagThHigh */
+ 0x0F12000B, /*70000A8A//_ee_iFSVarThHigh */
+ 0x0F120B00, /*70000A8C//_ee_iFSThHigh */
+ 0x0F125A0F, /*70000A8E//_ee_iFSVarCountTh */
+ 0x0F120505, /*70000A90//_ee_iRadialPower */
+ 0x0F121802, /*70000A92//_ee_iROADThres */
+ 0x0F120000, /*70000A94//_ee_iROADSubMaxNR */
+ 0x0F122006, /*70000A96//_ee_iROADNeiThres */
+ 0x0F123828, /*70000A98//_ee_iSmoothEdgeThres */
+ 0x0F120425, /*70000A9A//_ee_iWSharpen */
+ 0x0F120101, /*70000A9C//_ee_iWShThresh */
+ 0x0F120800, /*70000A9E//_ee_iEmbossCentAdd */
+ 0x0F121004, /*70000AA0//_ee_iReduceEdgeThresh */
+ 0x0F124008, /*70000AA2//_dmsc_iDesatThresh */
+ 0x0F120540, /*70000AA4//_dmsc_iDemBlurLow */
+ 0x0F128006, /*70000AA6//_dmsc_iDecisionThresh */
+ 0x0F120020, /*70000AA8//_dmsc_iMonochrom */
+ 0x0F120000, /*70000AAA//_dmsc_iGRDenoiseVal */
+ 0x0F122000, /*70000AAC//_dmsc_iEdgeDesatThrLow */
+ 0x0F120000, /*70000AAE//_dmsc_iNearGrayDesat */
+ 0x0F121E10, /*70000AB0//_postdmsc_iBCoeff */
+ 0x0F12000B, /*70000AB2//_postdmsc_iWideMult */
+ 0x0F120607, /*70000AB4//_yuvemix_mNegSlopes_1 */
+ 0x0F120005, /*70000AB6//_yuvemix_mNegSlopes_3 */
+ 0x0F120607, /*70000AB8//_yuvemix_mPosSlopes_1 */
+ 0x0F120405, /*70000ABA//_yuvemix_mPosSlopes_3 */
+ 0x0F120205, /*70000ABC//_yuviirnr_iXSupportUV */
+ 0x0F120304, /*70000ABE//_yuviirnr_iHighYNorm */
+ 0x0F120409, /*70000AC0//_yuviirnr_iHighUVNorm */
+ 0x0F120306, /*70000AC2//_yuviirnr_iUVNormShift */
+ 0x0F120407, /*70000AC4//_yuviirnr_iVertLength_UV */
+ 0x0F122204, /*70000AC6//_yuviirnr_iDiffThreshH_Y */
+ 0x0F12021C, /*70000AC8//_yuviirnr_iDiffThreshH_UV */
+ 0x0F121102, /*70000ACA//_yuviirnr_iMaxThreshH_Y */
+ 0x0F120611, /*70000ACC//_yuviirnr_iMaxThreshH_UV */
+ 0x0F121A02, /*70000ACE//_yuviirnr_iYNRStrengthH */
+ 0x0F128018, /*70000AD0//_yuviirnr_iUVNRStrengthH */
+ 0x0F120080, /*70000AD2//_RGBGamma2_iLinearity */
+ 0x0F120374, /*70000AD4//_ccm_oscar_iSaturation */
+ 0x0F120180, /*70000AD6//_RGB2YUV_iRGBGain */
+ 0x0F120A0A, /*70000AD8//_bnr_iClustMulT_H */
+ 0x0F120101, /*70000ADA//_bnr_iClustThresh_H */
+ 0x0F12141D, /*70000ADC//_bnr_iDenThreshLow */
+ 0x0F126024, /*70000ADE//_ee_iLowSharpPower */
+ 0x0F121217, /*70000AE0//_ee_iLowShDenoise */
+ 0x0F12FFFF, /*70000AE2//_ee_iLowSharpClamp */
+ 0x0F120808, /*70000AE4//_ee_iReduceEdgeMinMult */
+ 0x0F120A01, /*70000AE6//_bnr_nClustLevel_H_Bin */
+ 0x0F12010A, /*70000AE8//_bnr_iClustMulT_C_Bin */
+ 0x0F120001, /*70000AEA//_bnr_iClustThresh_C_Bin */
+ 0x0F122400, /*70000AEC//_bnr_iDenThreshHigh_Bin */
+ 0x0F121660, /*70000AEE//_ee_iHighSharpPower_Bin */
+ 0x0F12FF10, /*70000AF0//_ee_iHighShDenoise_Bin */
+ 0x0F1240FF, /*70000AF2//_ee_iHighSharpClamp_Bin */
+ 0x0F120009, /*70000AF4//_ee_iReduceEdgeSlope_Bin */
+ 0x0F120001, /*70000AF6//_bnr_nClustLevel_C */
+ 0x0F120000, /*70000AF8//_BRIGHTNESS AFIT 2 */
+ 0x0F120000, /*70000AFA//_CONTRAST */
+ 0x0F120000, /*70000AFC//_SATURATION */
+ 0x0F120000, /*70000AFE//_SHARP_BLUR */
+ 0x0F120000, /*70000B00//_GLAMOUR */
+ 0x0F1200C0, /*70000B02//_bnr_edge_high */
+ 0x0F120064, /*70000B04//_postdmsc_iLowBright */
+ 0x0F120384, /*70000B06//_postdmsc_iHighBright */
+ 0x0F120043, /*70000B08//_postdmsc_iLowSat */
+ 0x0F1201F4, /*70000B0A//_postdmsc_iHighSat */
+ 0x0F120070, /*70000B0C//_postdmsc_iTune */
+ 0x0F120040, /*70000B0E//_yuvemix_mNegRanges_0 */
+ 0x0F1200A0, /*70000B10//_yuvemix_mNegRanges_1 */
+ 0x0F120100, /*70000B12//_yuvemix_mNegRanges_2 */
+ 0x0F120010, /*70000B14//_yuvemix_mPosRanges_0 */
+ 0x0F120060, /*70000B16//_yuvemix_mPosRanges_1 */
+ 0x0F120100, /*70000B18//_yuvemix_mPosRanges_2 */
+ 0x0F121430, /*70000B1A//_bnr_edge_low */
+ 0x0F120201, /*70000B1C//_bnr_repl_force */
+ 0x0F120204, /*70000B1E//_bnr_iHotThreshLow */
+ 0x0F121B04, /*70000B20//_bnr_iColdThreshLow */
+ 0x0F120312, /*70000B22//_bnr_DispTH_High */
+ 0x0F120003, /*70000B24//_bnr_DISP_Limit_High */
+ 0x0F120C03, /*70000B26//_bnr_iDistSigmaMax */
+ 0x0F122806, /*70000B28//_bnr_iDiffSigmaHigh */
+ 0x0F120060, /*70000B2A//_bnr_iNormalizedSTD_Limit */
+ 0x0F121580, /*70000B2C//_bnr_iDirMinThres */
+ 0x0F122020, /*70000B2E//_bnr_iDirFltDiffThresLow */
+ 0x0F120620, /*70000B30//_bnr_iDirSmoothPowerLow */
+ 0x0F120306, /*70000B32//_bnr_iHighMaxSlopeAllowed */
+ 0x0F122003, /*70000B34//_bnr_iHighSlopeThresh */
+ 0x0F12FF01, /*70000B36//_bnr_iSlopeBlurStrength */
+ 0x0F120404, /*70000B38//_bnr_AddNoisePower1 */
+ 0x0F120300, /*70000B3A//_bnr_iRadialTune */
+ 0x0F12145A, /*70000B3C//_bnr_iRadialLimit */
+ 0x0F121010, /*70000B3E//_ee_iFSMagThHigh */
+ 0x0F12000B, /*70000B40//_ee_iFSVarThHigh */
+ 0x0F120E00, /*70000B42//_ee_iFSThHigh */
+ 0x0F125A0F, /*70000B44//_ee_iFSVarCountTh */
+ 0x0F120504, /*70000B46//_ee_iRadialPower */
+ 0x0F121802, /*70000B48//_ee_iROADThres */
+ 0x0F120000, /*70000B4A//_ee_iROADSubMaxNR */
+ 0x0F122006, /*70000B4C//_ee_iROADNeiThres */
+ 0x0F123828, /*70000B4E//_ee_iSmoothEdgeThres */
+ 0x0F120428, /*70000B50//_ee_iWSharpen */
+ 0x0F120101, /*70000B52//_ee_iWShThresh */
+ 0x0F128000, /*70000B54//_ee_iEmbossCentAdd */
+ 0x0F120A04, /*70000B56//_ee_iReduceEdgeThresh */
+ 0x0F124008, /*70000B58//_dmsc_iDesatThresh */
+ 0x0F120540, /*70000B5A//_dmsc_iDemBlurLow */
+ 0x0F128006, /*70000B5C//_dmsc_iDecisionThresh */
+ 0x0F120020, /*70000B5E//_dmsc_iMonochrom */
+ 0x0F120000, /*70000B60//_dmsc_iGRDenoiseVal */
+ 0x0F122000, /*70000B62//_dmsc_iEdgeDesatThrLow */
+ 0x0F120000, /*70000B64//_dmsc_iNearGrayDesat */
+ 0x0F121E10, /*70000B66//_postdmsc_iBCoeff */
+ 0x0F12000B, /*70000B68//_postdmsc_iWideMult */
+ 0x0F120607, /*70000B6A//_yuvemix_mNegSlopes_1 */
+ 0x0F120005, /*70000B6C//_yuvemix_mNegSlopes_3 */
+ 0x0F120607, /*70000B6E//_yuvemix_mPosSlopes_1 */
+ 0x0F120405, /*70000B70//_yuvemix_mPosSlopes_3 */
+ 0x0F120207, /*70000B72//_yuviirnr_iXSupportUV */
+ 0x0F120304, /*70000B74//_yuviirnr_iHighYNorm */
+ 0x0F120409, /*70000B76//_yuviirnr_iHighUVNorm */
+ 0x0F120306, /*70000B78//_yuviirnr_iUVNormShift */
+ 0x0F120407, /*70000B7A//_yuviirnr_iVertLength_UV */
+ 0x0F122404, /*70000B7C//_yuviirnr_iDiffThreshH_Y */
+ 0x0F120221, /*70000B7E//_yuviirnr_iDiffThreshH_UV */
+ 0x0F121202, /*70000B80//_yuviirnr_iMaxThreshH_Y*/
+ 0x0F120613, /*70000B82//_yuviirnr_iMaxThreshH_UV */
+ 0x0F121A02, /*70000B84//_yuviirnr_iYNRStrengthH */
+ 0x0F128018, /*70000B86//_yuviirnr_iUVNRStrengthH */
+ 0x0F120080, /*70000B88//_RGBGamma2_iLinearity */
+ 0x0F120080, /*70000B8A//_ccm_oscar_iSaturation */
+ 0x0F120180, /*70000B8C//_RGB2YUV_iRGBGain */
+ 0x0F120A0A, /*70000B8E//_bnr_iClustMulT_H */
+ 0x0F120101, /*70000B90//_bnr_iClustThresh_H */
+ 0x0F12121B, /*70000B92//_bnr_iDenThreshLow */
+ 0x0F126024, /*70000B94//_ee_iLowSharpPower */
+ 0x0F120C0C, /*70000B96//_ee_iLowShDenoise */
+ 0x0F12FFFF, /*70000B98//_ee_iLowSharpClamp */
+ 0x0F120808, /*70000B9A//_ee_iReduceEdgeMinMult */
+ 0x0F120A01, /*70000B9C//_bnr_nClustLevel_H_Bin */
+ 0x0F12010A, /*70000B9E//_bnr_iClustMulT_C_Bin */
+ 0x0F120001, /*70000BA0//_bnr_iClustThresh_C_Bin */
+ 0x0F122400, /*70000BA2//_bnr_iDenThreshHigh_Bin */
+ 0x0F120460, /*70000BA4//_ee_iHighSharpPower_Bin */
+ 0x0F12FF04, /*70000BA6//_ee_iHighShDenoise_Bin */
+ 0x0F1240FF, /*70000BA8//_ee_iHighSharpClamp_Bin */
+ 0x0F120009, /*70000BAA//_ee_iReduceEdgeSlope_Bin */
+ 0x0F120001, /*70000BAC//_bnr_nClustLevel_C */
+ 0x0F120000, /*70000BAE//_BRIGHTNESS AFIT 3 */
+ 0x0F120000, /*70000BB0//_CONTRAST */
+ 0x0F120000, /*70000BB2//_SATURATION */
+ 0x0F120000, /*70000BB4//_SHARP_BLUR */
+ 0x0F120000, /*70000BB6//_GLAMOUR */
+ 0x0F1200C0, /*70000BB8//_bnr_edge_high */
+ 0x0F120064, /*70000BBA//_postdmsc_iLowBright */
+ 0x0F120384, /*70000BBC//_postdmsc_iHighBright */
+ 0x0F120032, /*70000BBE//_postdmsc_iLowSat */
+ 0x0F1201F4, /*70000BC0//_postdmsc_iHighSat */
+ 0x0F120070, /*70000BC2//_postdmsc_iTune */
+ 0x0F120040, /*70000BC4//_yuvemix_mNegRanges_0 */
+ 0x0F1200A0, /*70000BC6//_yuvemix_mNegRanges_1 */
+ 0x0F120100, /*70000BC8//_yuvemix_mNegRanges_2 */
+ 0x0F120010, /*70000BCA//_yuvemix_mPosRanges_0 */
+ 0x0F120060, /*70000BCC//_yuvemix_mPosRanges_1 */
+ 0x0F120100, /*70000BCE//_yuvemix_mPosRanges_2 */
+ 0x0F121430, /*70000BD0//_bnr_edge_low */
+ 0x0F120201, /*70000BD2//_bnr_repl_force */
+ 0x0F120204, /*70000BD4//_bnr_iHotThreshLow */
+ 0x0F121504, /*70000BD6//_bnr_iColdThreshLow */
+ 0x0F12030F, /*70000BD8//_bnr_DispTH_High */
+ 0x0F120003, /*70000BDA//_bnr_DISP_Limit_High */
+ 0x0F120902, /*70000BDC//_bnr_iDistSigmaMax */
+ 0x0F122004, /*70000BDE//_bnr_iDiffSigmaHigh */
+ 0x0F120050, /*70000BE0//_bnr_iNormalizedSTD_Limit */
+ 0x0F121140, /*70000BE2//_bnr_iDirMinThres */
+ 0x0F12201C, /*70000BE4//_bnr_iDirFltDiffThresLow */
+ 0x0F120620, /*70000BE6//_bnr_iDirSmoothPowerLow */
+ 0x0F120306, /*70000BE8//_bnr_iHighMaxSlopeAllowed */
+ 0x0F122003, /*70000BEA//_bnr_iHighSlopeThresh */
+ 0x0F12FF01, /*70000BEC//_bnr_iSlopeBlurStrength */
+ 0x0F120404, /*70000BEE//_bnr_AddNoisePower1 */
+ 0x0F120300, /*70000BF0//_bnr_iRadialTune */
+ 0x0F12145A, /*70000BF2//_bnr_iRadialLimit */
+ 0x0F121010, /*70000BF4//_ee_iFSMagThHigh */
+ 0x0F12000B, /*70000BF6//_ee_iFSVarThHigh */
+ 0x0F121000, /*70000BF8//_ee_iFSThHigh */
+ 0x0F125A0F, /*70000BFA//_ee_iFSVarCountTh */
+ 0x0F120503, /*70000BFC//_ee_iRadialPower */
+ 0x0F121802, /*70000BFE//_ee_iROADThres */
+ 0x0F120000, /*70000C00//_ee_iROADSubMaxNR */
+ 0x0F122006, /*70000C02//_ee_iROADNeiThres */
+ 0x0F123C28, /*70000C04//_ee_iSmoothEdgeThres */
+ 0x0F12042C, /*70000C06//_ee_iWSharpen */
+ 0x0F120101, /*70000C08//_ee_iWShThresh */
+ 0x0F12FF00, /*70000C0A//_ee_iEmbossCentAdd */
+ 0x0F120904, /*70000C0C//_ee_iReduceEdgeThresh */
+ 0x0F124008, /*70000C0E//_dmsc_iDesatThresh */
+ 0x0F120540, /*70000C10//_dmsc_iDemBlurLow */
+ 0x0F128006, /*70000C12//_dmsc_iDecisionThresh */
+ 0x0F120020, /*70000C14//_dmsc_iMonochrom */
+ 0x0F120000, /*70000C16//_dmsc_iGRDenoiseVal */
+ 0x0F122000, /*70000C18//_dmsc_iEdgeDesatThrLow */
+ 0x0F120000, /*70000C1A//_dmsc_iNearGrayDesat */
+ 0x0F121E10, /*70000C1C//_postdmsc_iBCoeff */
+ 0x0F12000B, /*70000C1E//_postdmsc_iWideMult */
+ 0x0F120607, /*70000C20//_yuvemix_mNegSlopes_1 */
+ 0x0F120005, /*70000C22//_yuvemix_mNegSlopes_3 */
+ 0x0F120607, /*70000C24//_yuvemix_mPosSlopes_1 */
+ 0x0F120405, /*70000C26//_yuvemix_mPosSlopes_3 */
+ 0x0F120206, /*70000C28//_yuviirnr_iXSupportUV */
+ 0x0F120304, /*70000C2A//_yuviirnr_iHighYNorm */
+ 0x0F120409, /*70000C2C//_yuviirnr_iHighUVNorm */
+ 0x0F120305, /*70000C2E//_yuviirnr_iUVNormShift */
+ 0x0F120406, /*70000C30//_yuviirnr_iVertLength_UV */
+ 0x0F122804, /*70000C32//_yuviirnr_iDiffThreshH_Y */
+ 0x0F120228, /*70000C34//_yuviirnr_iDiffThreshH_UV */
+ 0x0F121402, /*70000C36//_yuviirnr_iMaxThreshH_Y */
+ 0x0F120618, /*70000C38//_yuviirnr_iMaxThreshH_UV */
+ 0x0F121A02, /*70000C3A//_yuviirnr_iYNRStrengthH */
+ 0x0F128018, /*70000C3C//_yuviirnr_iUVNRStrengthH */
+ 0x0F120080, /*70000C3E//_RGBGamma2_iLinearity */
+ 0x0F120080, /*70000C40//_ccm_oscar_iSaturation */
+ 0x0F120180, /*70000C42//_RGB2YUV_iRGBGain */
+ 0x0F120A0A, /*70000C44//_bnr_iClustMulT_H */
+ 0x0F120101, /*70000C46//_bnr_iClustThresh_H */
+ 0x0F120F15, /*70000C48//_bnr_iDenThreshLow */
+ 0x0F126024, /*70000C4A//_ee_iLowSharpPower */
+ 0x0F120A0A, /*70000C4C//_ee_iLowShDenoise */
+ 0x0F12FFFF, /*70000C4E//_ee_iLowSharpClamp */
+ 0x0F120808, /*70000C50//_ee_iReduceEdgeMinMult */
+ 0x0F120A01, /*70000C52//_bnr_nClustLevel_H_Bin */
+ 0x0F12010A, /*70000C54//_bnr_iClustMulT_C_Bin */
+ 0x0F120001, /*70000C56//_bnr_iClustThresh_C_Bin */
+ 0x0F122400, /*70000C58//_bnr_iDenThreshHigh_Bin */
+ 0x0F120260, /*70000C5A//_ee_iHighSharpPower_Bin */
+ 0x0F12FF02, /*70000C5C//_ee_iHighShDenoise_Bin */
+ 0x0F1240FF, /*70000C5E//_ee_iHighSharpClamp_Bin */
+ 0x0F120009, /*70000C60//_ee_iReduceEdgeSlope_Bin */
+ 0x0F120001, /*70000C62//_bnr_nClustLevel_C */
+ 0x0F120000, /*70000C64//_BRIGHTNESS AFIT 4 */
+ 0x0F120000, /*70000C66//_CONTRAST */
+ 0x0F120000, /*70000C68//_SATURATION */
+ 0x0F120000, /*70000C6A//_SHARP_BLUR */
+ 0x0F120000, /*70000C6C//_GLAMOUR */
+ 0x0F1200C0, /*70000C6E//_bnr_edge_high */
+ 0x0F120064, /*70000C70//_postdmsc_iLowBright */
+ 0x0F120384, /*70000C72//_postdmsc_iHighBright */
+ 0x0F120032, /*70000C74//_postdmsc_iLowSat */
+ 0x0F1201F4, /*70000C76//_postdmsc_iHighSat */
+ 0x0F120070, /*70000C78//_postdmsc_iTune */
+ 0x0F120040, /*70000C7A//_yuvemix_mNegRanges_0 */
+ 0x0F1200A0, /*70000C7C//_yuvemix_mNegRanges_1 */
+ 0x0F120100, /*70000C7E//_yuvemix_mNegRanges_2 */
+ 0x0F120010, /*70000C80//_yuvemix_mPosRanges_0 */
+ 0x0F120060, /*70000C82//_yuvemix_mPosRanges_1 */
+ 0x0F120100, /*70000C84//_yuvemix_mPosRanges_2 */
+ 0x0F121430, /*70000C86//_bnr_edge_low */
+ 0x0F120201, /*70000C88//_bnr_repl_force */
+ 0x0F120204, /*70000C8A//_bnr_iHotThreshLow */
+ 0x0F120F04, /*70000C8C//_bnr_iColdThreshLow */
+ 0x0F12030C, /*70000C8E//_bnr_DispTH_High */
+ 0x0F120003, /*70000C90//_bnr_DISP_Limit_High */
+ 0x0F120602, /*70000C92//_bnr_iDistSigmaMax */
+ 0x0F121803, /*70000C94//_bnr_iDiffSigmaHigh */
+ 0x0F120040, /*70000C96//_bnr_iNormalizedSTD_Limit */
+ 0x0F120E20, /*70000C98//_bnr_iDirMinThres */
+ 0x0F122018, /*70000C9A//_bnr_iDirFltDiffThresLow */
+ 0x0F120620, /*70000C9C//_bnr_iDirSmoothPowerLow */
+ 0x0F120306, /*70000C9E//_bnr_iHighMaxSlopeAllowed */
+ 0x0F122003, /*70000CA0//_bnr_iHighSlopeThresh */
+ 0x0F12FF01, /*70000CA2//_bnr_iSlopeBlurStrength */
+ 0x0F120404, /*70000CA4//_bnr_AddNoisePower1 */
+ 0x0F120200, /*70000CA6//_bnr_iRadialTune */
+ 0x0F12145A, /*70000CA8//_bnr_iRadialLimit */
+ 0x0F121010, /*70000CAA//_ee_iFSMagThHigh */
+ 0x0F12000B, /*70000CAC//_ee_iFSVarThHigh */
+ 0x0F121200, /*70000CAE//_ee_iFSThHigh */
+ 0x0F125A0F, /*70000CB0//_ee_iFSVarCountTh */
+ 0x0F120502, /*70000CB2//_ee_iRadialPower */
+ 0x0F121802, /*70000CB4//_ee_iROADThres */
+ 0x0F120000, /*70000CB6//_ee_iROADSubMaxNR */
+ 0x0F122006, /*70000CB8//_ee_iROADNeiThres */
+ 0x0F124028, /*70000CBA//_ee_iSmoothEdgeThres */
+ 0x0F120430, /*70000CBC//_ee_iWSharpen */
+ 0x0F120101, /*70000CBE//_ee_iWShThresh */
+ 0x0F12FF00, /*70000CC0//_ee_iEmbossCentAdd */
+ 0x0F120804, /*70000CC2//_ee_iReduceEdgeThresh */
+ 0x0F124008, /*70000CC4//_dmsc_iDesatThresh */
+ 0x0F120540, /*70000CC6//_dmsc_iDemBlurLow */
+ 0x0F128006, /*70000CC8//_dmsc_iDecisionThresh */
+ 0x0F120020, /*70000CCA//_dmsc_iMonochrom */
+ 0x0F120000, /*70000CCC//_dmsc_iGRDenoiseVal */
+ 0x0F122000, /*70000CCE//_dmsc_iEdgeDesatThrLow */
+ 0x0F120000, /*70000CD0//_dmsc_iNearGrayDesat */
+ 0x0F121E10, /*70000CD2//_postdmsc_iBCoeff */
+ 0x0F12000B, /*70000CD4//_postdmsc_iWideMult */
+ 0x0F120607, /*70000CD6//_yuvemix_mNegSlopes_1 */
+ 0x0F120005, /*70000CD8//_yuvemix_mNegSlopes_3 */
+ 0x0F120607, /*70000CDA//_yuvemix_mPosSlopes_1 */
+ 0x0F120405, /*70000CDC//_yuvemix_mPosSlopes_3 */
+ 0x0F120205, /*70000CDE//_yuviirnr_iXSupportUV */
+ 0x0F120304, /*70000CE0//_yuviirnr_iHighYNorm */
+ 0x0F120409, /*70000CE2//_yuviirnr_iHighUVNorm */
+ 0x0F120306, /*70000CE4//_yuviirnr_iUVNormShift */
+ 0x0F120407, /*70000CE6//_yuviirnr_iVertLength_UV */
+ 0x0F122C04, /*70000CE8//_yuviirnr_iDiffThreshH_Y */
+ 0x0F12022C, /*70000CEA//_yuviirnr_iDiffThreshH_UV */
+ 0x0F121402, /*70000CEC//_yuviirnr_iMaxThreshH_Y */
+ 0x0F120618, /*70000CEE//_yuviirnr_iMaxThreshH_UV */
+ 0x0F121A02, /*70000CF0//_yuviirnr_iYNRStrengthH */
+ 0x0F128018, /*70000CF2//_yuviirnr_iUVNRStrengthH */
+ 0x0F120080, /*70000CF4//_RGBGamma2_iLinearity */
+ 0x0F120080, /*70000CF6//_ccm_oscar_iSaturation */
+ 0x0F120180, /*70000CF8//_RGB2YUV_iRGBGain */
+ 0x0F120A0A, /*70000CFA//_bnr_iClustMulT_H */
+ 0x0F120101, /*70000CFC//_bnr_iClustThresh_H */
+ 0x0F120C0F, /*70000CFE//_bnr_iDenThreshLow */
+ 0x0F126024, /*70000D00//_ee_iLowSharpPower */
+ 0x0F120808, /*70000D02//_ee_iLowShDenoise */
+ 0x0F12FFFF, /*70000D04//_ee_iLowSharpClamp */
+ 0x0F120808, /*70000D06//_ee_iReduceEdgeMinMult */
+ 0x0F120A01, /*70000D08//_bnr_nClustLevel_H_Bin */
+ 0x0F12010A, /*70000D0A//_bnr_iClustMulT_C_Bin */
+ 0x0F120001, /*70000D0C//_bnr_iClustThresh_C_Bin */
+ 0x0F122400, /*70000D0E//_bnr_iDenThreshHigh_Bin */
+ 0x0F120060, /*70000D10//_ee_iHighSharpPower_Bin */
+ 0x0F12FF00, /*70000D12//_ee_iHighShDenoise_Bin */
+ 0x0F1240FF, /*70000D14//_ee_iHighSharpClamp_Bin */
+ 0x0F120009, /*70000D16//_ee_iReduceEdgeSlope_Bin */
+ 0x0F120001, /*70000D18//_bnr_nClustLevel_C */
+ 0x002A0266,
+ 0x0F120000, /*REG_TC_GP_ActivePrevConfig */
+ 0x002A026A,
+ 0x0F120001, /*REG_TC_GP_PrevOpenAfterChange */
+ 0x002A024E,
+ 0x0F120001, /*REG_TC_GP_NewConfigSync */
+ 0x002A0268,
+ 0x0F120001, /*REG_TC_GP_PrevConfigChanged */
+
+};
+
+static const u32 s5k4ecgx_800_Preview_EVT1[] = { /* 800 x 480 // */
+ 0xFCFCD000,
+ 0x00287000,
+
+ 0x002A18AC,
+ 0x0F120060, /*senHal_uAddColsBin */
+ 0x0F120060, /*senHal_uAddColsNoBin */
+ 0x0F1205C0, /*senHal_uMinColsBin */
+ 0x0F1205C0, /*senHal_uMinColsNoBin */
+
+ 0x002A0250,
+ 0x0F120A00, /*REG_TC_GP_PrevReqInputWidth //2560 */
+ 0x0F120600, /*REG_TC_GP_PrevReqInputHeight //1536 */
+ 0x0F120010, /*REG_TC_GP_PrevInputWidthOfs //(2592-2560)/2*/
+ 0x0F1200CC, /*REG_TC_GP_PrevInputHeightOfs/(1944-1536)/2*/
+
+ 0x002A0262,
+ 0x0F120001, /*REG_TC_GP_bUseReqInputInPre */
+
+ 0x002A0494,
+ 0x0F120A00, /*REG_TC_PZOOM_PrevZoomReqInputWidth //2560 */
+ 0x0F120600, /*REG_TC_PZOOM_PrevZoomReqInputHeight //1536 */
+ 0x0F120000, /*REG_TC_PZOOM_PrevZoomReqInputWidthOfs */
+ 0x0F120000, /*REG_TC_PZOOM_PrevZoomReqInputHeightOfs */
+
+ 0x002A02A6,
+ 0x0F120320, /*REG_0TC_PCFG_usWidth //800 */
+ 0x0F1201E0, /*REG_0TC_PCFG_usHeight //480 */
+
+ 0x002A0266,
+ 0x0F120000, /*REG_TC_GP_ActivePrevConfig */
+ 0x002A026A,
+ 0x0F120001, /*REG_TC_GP_PrevOpenAfterChange */
+ 0x002A024E,
+ 0x0F120001, /*REG_TC_GP_NewConfigSync */
+ 0x002A0268,
+ 0x0F120001, /*REG_TC_GP_PrevConfigChanged */
+
+};
+
+static const u32 s5k4ecgx_720_Preview_EVT1[] = { /* 720 x 480 */
+ 0xFCFCD000,
+ 0x00287000,
+
+ 0x002A18AC,
+ 0x0F120060, /*senHal_uAddColsBin */
+ 0x0F120060, /*senHal_uAddColsNoBin */
+ 0x0F1205C0, /*senHal_uMinColsBin */
+ 0x0F1205C0, /*senHal_uMinColsNoBin */
+
+ 0x002A0250,
+ 0x0F120A00, /*REG_TC_GP_PrevReqInputWidth //2560 */
+ 0x0F1206A8, /*REG_TC_GP_PrevReqInputHeight //1704 */
+ 0x0F120010, /*REG_TC_GP_PrevInputWidthOfs/(2592-2560)/2*/
+ 0x0F120078, /*REG_TC_GP_PrevInputHeightOfs //(1944-1704)/2*/
+
+ 0x002A0262,
+ 0x0F120001, /*REG_TC_GP_bUseReqInputInPre */
+
+ 0x002A0494,
+ 0x0F120A00, /*REG_TC_PZOOM_PrevZoomReqInputWidth //2560 */
+ 0x0F1206A8, /*REG_TC_PZOOM_PrevZoomReqInputHeight //1704 */
+ 0x0F120000, /*REG_TC_PZOOM_PrevZoomReqInputWidthOfs */
+ 0x0F120000, /*REG_TC_PZOOM_PrevZoomReqInputHeightOfs */
+
+ 0x002A02A6,
+ 0x0F1202D0, /*REG_0TC_PCFG_usWidth //720 */
+ 0x0F1201E0, /*REG_0TC_PCFG_usHeight //480 */
+
+ 0x002A0266,
+ 0x0F120000, /*REG_TC_GP_ActivePrevConfig */
+ 0x002A026A,
+ 0x0F120001, /*REG_TC_GP_PrevOpenAfterChange */
+ 0x002A024E,
+ 0x0F120001, /*REG_TC_GP_NewConfigSync */
+ 0x002A0268,
+ 0x0F120001, /*REG_TC_GP_PrevConfigChanged */
+};
+
+static const u32 s5k4ecgx_640_Preview_EVT1[] = { /* 640 x 480 */
+ 0xFCFCD000,
+ 0x00287000,
+
+ 0x002A18AC,
+ 0x0F120060, /*senHal_uAddColsBin */
+ 0x0F120060, /*senHal_uAddColsNoBin */
+ 0x0F1205C0, /*senHal_uMinColsBin */
+ 0x0F1205C0, /*senHal_uMinColsNoBin */
+
+ 0x002A0250,
+ 0x0F120A00, /*REG_TC_GP_PrevReqInputWidth //2560 */
+ 0x0F120780, /*REG_TC_GP_PrevReqInputHeight //1920 */
+ 0x0F120010, /*REG_TC_GP_PrevInputWidthOfs/(2592-2560)/2*/
+ 0x0F12000C, /*REG_TC_GP_PrevInputHeightOfs/(1944-1920)/2*/
+
+ 0x002A0262,
+ 0x0F120001, /*REG_TC_GP_bUseReqInputInPre */
+
+ 0x002A0494,
+ 0x0F120A00, /*REG_TC_PZOOM_PrevZoomReqInputWidth //2560 */
+ 0x0F120780, /*REG_TC_PZOOM_PrevZoomReqInputHeight //1920 */
+ 0x0F120000, /*REG_TC_PZOOM_PrevZoomReqInputWidthOfs */
+ 0x0F120000, /*REG_TC_PZOOM_PrevZoomReqInputHeightOfs */
+
+ 0x002A02A6,
+ 0x0F120280, /*REG_0TC_PCFG_usWidth //640 */
+ 0x0F1201E0, /*REG_0TC_PCFG_usHeight //480 */
+
+ 0x002A0266,
+ 0x0F120000, /*REG_TC_GP_ActivePrevConfig */
+ 0x002A026A,
+ 0x0F120001, /*REG_TC_GP_PrevOpenAfterChange */
+ 0x002A024E,
+ 0x0F120001, /*REG_TC_GP_NewConfigSync */
+ 0x002A0268,
+ 0x0F120001, /*REG_TC_GP_PrevConfigChanged */
+
+};
+
+static const u32 s5k4ecgx_352_Preview_EVT1[] = { /* 352 x 288 */
+ 0xFCFCD000,
+ 0x00287000,
+
+ 0x002A18AC,
+ 0x0F120060, /*senHal_uAddColsBin */
+ 0x0F120060, /*senHal_uAddColsNoBin */
+ 0x0F1205C0, /*senHal_uMinColsBin */
+ 0x0F1205C0, /*senHal_uMinColsNoBin */
+
+ 0x002A0250,
+ 0x0F120928, /*REG_TC_GP_PrevReqInputWidth //2344 */
+ 0x0F120780, /*REG_TC_GP_PrevReqInputHeight //1920 */
+ 0x0F12007C, /*REG_TC_GP_PrevInputWidthOfs //(2592-2344)/2 */
+ 0x0F12000C, /*REG_TC_GP_PrevInputHeightOfs //(1944-1920)/2 */
+
+ 0x002A0262,
+ 0x0F120001, /*REG_TC_GP_bUseReqInputInPre */
+
+ 0x002A0494,
+ 0x0F120928, /*REG_TC_PZOOM_PrevZoomReqInputWidth //2344 */
+ 0x0F120780, /*REG_TC_PZOOM_PrevZoomReqInputHeight //1920 */
+ 0x0F120000, /*REG_TC_PZOOM_PrevZoomReqInputWidthOfs */
+ 0x0F120000, /*REG_TC_PZOOM_PrevZoomReqInputHeightOfs */
+
+ 0x002A02A6,
+ 0x0F120160, /*REG_0TC_PCFG_usWidth //352 */
+ 0x0F120120, /*REG_0TC_PCFG_usHeight //288 */
+
+ 0x002A0266,
+ 0x0F120000, /*REG_TC_GP_ActivePrevConfig */
+ 0x002A026A,
+ 0x0F120001, /*REG_TC_GP_PrevOpenAfterChange */
+ 0x002A024E,
+ 0x0F120001, /*REG_TC_GP_NewConfigSync */
+ 0x002A0268,
+ 0x0F120001, /*REG_TC_GP_PrevConfigChanged */
+
+};
+
+static const u32 s5k4ecgx_320_Preview_EVT1[] = { /* 320 x 240 */
+ 0xFCFCD000,
+ 0x00287000,
+
+ 0x002A18AC,
+ 0x0F120060, /*senHal_uAddColsBin */
+ 0x0F120060, /*senHal_uAddColsNoBin */
+ 0x0F1205C0, /*senHal_uMinColsBin */
+ 0x0F1205C0, /*senHal_uMinColsNoBin */
+
+ 0x002A0250,
+ 0x0F120A00, /*REG_TC_GP_PrevReqInputWidth //2560 */
+ 0x0F120780, /*REG_TC_GP_PrevReqInputHeight //1920 */
+ 0x0F120010, /*REG_TC_GP_PrevInputWidthOfs //(2592-2560)/2 */
+ 0x0F12000C, /*REG_TC_GP_PrevInputHeightOfs //(1944-1920)/2*/
+
+ 0x002A0262,
+ 0x0F120001, /*REG_TC_GP_bUseReqInputInPre */
+
+ 0x002A0494,
+ 0x0F120A00, /*REG_TC_PZOOM_PrevZoomReqInputWidth //2560 */
+ 0x0F120780, /*REG_TC_PZOOM_PrevZoomReqInputHeight //1920 */
+ 0x0F120000, /*REG_TC_PZOOM_PrevZoomReqInputWidthOfs */
+ 0x0F120000, /*REG_TC_PZOOM_PrevZoomReqInputHeightOfs */
+
+ 0x002A02A6,
+ 0x0F120140, /*REG_0TC_PCFG_usWidth //320 */
+ 0x0F1200F0, /*REG_0TC_PCFG_usHeight //240 */
+
+ 0x002A0266,
+ 0x0F120000, /*REG_TC_GP_ActivePrevConfig */
+ 0x002A026A,
+ 0x0F120001, /*REG_TC_GP_PrevOpenAfterChange */
+ 0x002A024E,
+ 0x0F120001, /*REG_TC_GP_NewConfigSync */
+ 0x002A0268,
+ 0x0F120001, /*REG_TC_GP_PrevConfigChanged */
+
+};
+
+static const u32 s5k4ecgx_176_Preview_EVT1[] = { /* 176 x 144 */
+ 0xFCFCD000,
+ 0x00287000,
+
+ 0x002A18AC,
+ 0x0F120060, /*senHal_uAddColsBin */
+ 0x0F120060, /*senHal_uAddColsNoBin */
+ 0x0F1205C0, /*senHal_uMinColsBin */
+ 0x0F1205C0, /*senHal_uMinColsNoBin */
+
+ 0x002A0250,
+ 0x0F120928, /*REG_TC_GP_PrevReqInputWidth //2344 */
+ 0x0F120780, /*REG_TC_GP_PrevReqInputHeight //1920 */
+ 0x0F12007C, /*REG_TC_GP_PrevInputWidthOfs //(2592-2344)/2 */
+ 0x0F12000C,/*REG_TC_GP_PrevInputHeightOfs/(1944-1920)/2*/
+
+ 0x002A0262,
+ 0x0F120001, /*REG_TC_GP_bUseReqInputInPre */
+
+ 0x002A0494,
+ 0x0F120928, /*REG_TC_PZOOM_PrevZoomReqInputWidth //2344 */
+ 0x0F120780, /*REG_TC_PZOOM_PrevZoomReqInputHeight //1920 */
+ 0x0F120000, /*REG_TC_PZOOM_PrevZoomReqInputWidthOfs */
+ 0x0F120000, /*REG_TC_PZOOM_PrevZoomReqInputHeightOfs */
+
+ 0x002A02A6,
+ 0x0F1200B0, /*REG_0TC_PCFG_usWidth //176 */
+ 0x0F120090, /*REG_0TC_PCFG_usHeight //144 */
+
+ 0x002A0266,
+ 0x0F120000, /*REG_TC_GP_ActivePrevConfig */
+ 0x002A026A,
+ 0x0F120001, /*REG_TC_GP_PrevOpenAfterChange */
+ 0x002A024E,
+ 0x0F120001, /*REG_TC_GP_NewConfigSync */
+ 0x002A0268,
+ 0x0F120001, /*REG_TC_GP_PrevConfigChanged */
+};
+
+/* Zoom set for 320,176*/
+static const u32 s5k4ecgx_X4_Zoom_0_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A048E,
+ 0x0F120100,
+ 0x002A04A4,
+ 0x0F120005,
+};
+
+static const u32 s5k4ecgx_X4_Zoom_1_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A048E,
+ 0x0F120120,
+ 0x002A04A4,
+ 0x0F120005,
+};
+
+static const u32 s5k4ecgx_X4_Zoom_2_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A048E,
+ 0x0F120140,
+ 0x002A04A4,
+ 0x0F120005,
+};
+
+static const u32 s5k4ecgx_X4_Zoom_3_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A048E,
+ 0x0F120160,
+ 0x002A04A4,
+ 0x0F120005,
+};
+
+static const u32 s5k4ecgx_X4_Zoom_4_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A048E,
+ 0x0F120180,
+ 0x002A04A4,
+ 0x0F120005,
+};
+
+static const u32 s5k4ecgx_X4_Zoom_5_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A048E,
+ 0x0F1201A0,
+ 0x002A04A4,
+ 0x0F120005,
+};
+
+static const u32 s5k4ecgx_X4_Zoom_6_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A048E,
+ 0x0F1201C0,
+ 0x002A04A4,
+ 0x0F120005,
+};
+
+static const u32 s5k4ecgx_X4_Zoom_7_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A048E,
+ 0x0F1201E0,
+ 0x002A04A4,
+ 0x0F120005,
+};
+
+static const u32 s5k4ecgx_X4_Zoom_8_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A048E,
+ 0x0F120200,
+ 0x002A04A4,
+ 0x0F120005,
+};
+
+/* Zoom set for 1280 x 640*/
+static const u32 s5k4ecgx_X2_Zoom_0_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A048E,
+ 0x0F120100,
+ 0x002A04A4,
+ 0x0F120005,
+};
+
+static const u32 s5k4ecgx_X2_Zoom_1_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A048E,
+ 0x0F120120,
+ 0x002A04A4,
+ 0x0F120005,
+};
+
+static const u32 s5k4ecgx_X2_Zoom_2_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A048E,
+ 0x0F120140,
+ 0x002A04A4,
+ 0x0F120005,
+};
+
+static const u32 s5k4ecgx_X2_Zoom_3_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A048E,
+ 0x0F120160,
+ 0x002A04A4,
+ 0x0F120005,
+};
+
+static const u32 s5k4ecgx_X2_Zoom_4_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A048E,
+ 0x0F120180,
+ 0x002A04A4,
+ 0x0F120005,
+};
+
+static const u32 s5k4ecgx_X2_Zoom_5_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A048E,
+ 0x0F1201A0,
+ 0x002A04A4,
+ 0x0F120005,
+};
+
+static const u32 s5k4ecgx_X2_Zoom_6_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A048E,
+ 0x0F1201C0,
+ 0x002A04A4,
+ 0x0F120005,
+};
+
+static const u32 s5k4ecgx_X2_Zoom_7_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A048E,
+ 0x0F1201E0,
+ 0x002A04A4,
+ 0x0F120005,
+};
+
+static const u32 s5k4ecgx_X2_Zoom_8_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A048E,
+ 0x0F120200,
+ 0x002A04A4,
+ 0x0F120005,
+};
+
+/* Zoom set for 720*/
+static const u32 s5k4ecgx_X1_77_Zoom_0_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A048E,
+ 0x0F120100,
+ 0x002A04A4,
+ 0x0F120005,
+};
+
+static const u32 s5k4ecgx_X1_77_Zoom_1_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A048E,
+ 0x0F120118,
+ 0x002A04A4,
+ 0x0F120005,
+};
+
+static const u32 s5k4ecgx_X1_77_Zoom_2_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A048E,
+ 0x0F120130,
+ 0x002A04A4,
+ 0x0F120005,
+};
+
+static const u32 s5k4ecgx_X1_77_Zoom_3_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A048E,
+ 0x0F120148,
+ 0x002A04A4,
+ 0x0F120005,
+};
+
+static const u32 s5k4ecgx_X1_77_Zoom_4_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A048E,
+ 0x0F120160,
+ 0x002A04A4,
+ 0x0F120005,
+};
+
+static const u32 s5k4ecgx_X1_77_Zoom_5_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A048E,
+ 0x0F120178,
+ 0x002A04A4,
+ 0x0F120005,
+};
+
+static const u32 s5k4ecgx_X1_77_Zoom_6_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A048E,
+ 0x0F120190,
+ 0x002A04A4,
+ 0x0F120005,
+};
+
+static const u32 s5k4ecgx_X1_77_Zoom_7_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A048E,
+ 0x0F1201A8,
+ 0x002A04A4,
+ 0x0F120005,
+};
+
+static const u32 s5k4ecgx_X1_77_Zoom_8_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A048E,
+ 0x0F1201C5,
+ 0x002A04A4,
+ 0x0F120005,
+};
+
+/* Zoom set for 1600 */
+static const u32 s5k4ecgx_X1_6_Zoom_0_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A048E,
+ 0x0F120100,
+ 0x002A04A4,
+ 0x0F120005,
+};
+
+static const u32 s5k4ecgx_X1_6_Zoom_1_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A048E,
+ 0x0F120113,
+ 0x002A04A4,
+ 0x0F120005,
+};
+
+static const u32 s5k4ecgx_X1_6_Zoom_2_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A048E,
+ 0x0F120126,
+ 0x002A04A4,
+ 0x0F120005,
+};
+
+static const u32 s5k4ecgx_X1_6_Zoom_3_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A048E,
+ 0x0F120139,
+ 0x002A04A4,
+ 0x0F120005,
+};
+
+static const u32 s5k4ecgx_X1_6_Zoom_4_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A048E,
+ 0x0F12014C,
+ 0x002A04A4,
+ 0x0F120005,
+};
+
+static const u32 s5k4ecgx_X1_6_Zoom_5_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A048E,
+ 0x0F12015F,
+ 0x002A04A4,
+ 0x0F120005,
+};
+
+static const u32 s5k4ecgx_X1_6_Zoom_6_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A048E,
+ 0x0F120172,
+ 0x002A04A4,
+ 0x0F120005,
+};
+
+static const u32 s5k4ecgx_X1_6_Zoom_7_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A048E,
+ 0x0F120185,
+ 0x002A04A4,
+ 0x0F120005,
+};
+
+static const u32 s5k4ecgx_X1_6_Zoom_8_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A048E,
+ 0x0F12019A,
+ 0x002A04A4,
+ 0x0F120005,
+};
+
+/* Zoom set for 2048 */
+static const u32 s5k4ecgx_X1_25_Zoom_0_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A048E,
+ 0x0F120100,
+ 0x002A04A4,
+ 0x0F120005,
+};
+
+static const u32 s5k4ecgx_X1_25_Zoom_1_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A048E,
+ 0x0F120108,
+ 0x002A04A4,
+ 0x0F120005,
+};
+
+static const u32 s5k4ecgx_X1_25_Zoom_2_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A048E,
+ 0x0F120110,
+ 0x002A04A4,
+ 0x0F120005,
+};
+
+static const u32 s5k4ecgx_X1_25_Zoom_3_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A048E,
+ 0x0F120118,
+ 0x002A04A4,
+ 0x0F120005,
+};
+
+static const u32 s5k4ecgx_X1_25_Zoom_4_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A048E,
+ 0x0F120120,
+ 0x002A04A4,
+ 0x0F120005,
+};
+
+static const u32 s5k4ecgx_X1_25_Zoom_5_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A048E,
+ 0x0F120128,
+ 0x002A04A4,
+ 0x0F120005,
+};
+
+static const u32 s5k4ecgx_X1_25_Zoom_6_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A048E,
+ 0x0F120130,
+ 0x002A04A4,
+ 0x0F120005,
+};
+
+static const u32 s5k4ecgx_X1_25_Zoom_7_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A048E,
+ 0x0F120138,
+ 0x002A04A4,
+ 0x0F120005,
+};
+
+static const u32 s5k4ecgx_X1_25_Zoom_8_EVT1[] = {
+ 0xFCFCD000,
+ 0x00287000,
+ 0x002A048E,
+ 0x0F120140,
+ 0x002A04A4,
+ 0x0F120005,
+};
+
+#endif /* __S5K4ECGX_SETFILE_H */
diff --git a/drivers/media/video/sr200pc20m.h b/drivers/media/video/sr200pc20m.h
index 1a42088..64a3dd9 100644
--- a/drivers/media/video/sr200pc20m.h
+++ b/drivers/media/video/sr200pc20m.h
@@ -252,18 +252,10 @@ static s32 large_file;
#define dbg_setfile(fmt, ...)
#endif /* 0 */
-#ifdef CONFIG_MACH_S2PLUS
-#define TUNING_FILE_PATH "/mnt/sdcard/sr200pc20m_regs-s2plus.h"
-#else
#define TUNING_FILE_PATH "/mnt/sdcard/sr200pc20m_regs.h"
-#endif /* CONFIG_VIDEO_SR200PC20M */
#endif /* CONFIG_LOAD_FILE */
-#ifdef CONFIG_MACH_S2PLUS
-#include "sr200pc20m_regs-s2plus.h"
-#else
#include "sr200pc20m_regs.h"
-#endif
#endif /* __SR200PC20M_H */
diff --git a/drivers/media/video/sr200pc20m_regs-s2plus.h b/drivers/media/video/sr200pc20m_regs-s2plus.h
deleted file mode 100644
index b2b18f3..0000000
--- a/drivers/media/video/sr200pc20m_regs-s2plus.h
+++ /dev/null
@@ -1,4168 +0,0 @@
-/*
- * Driver for SR200PC20M 2M ISP from Samsung
- * Latest version: 11/11/23
- *
- * Copyright (c) 2011, 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 as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- */
-#ifndef __SR200PC20M_REGS_H
-#define __SR200PC20M_REGS_H
-
-#include <linux/types.h>
-
-/*
- * sr200pc20m register configuration for combinations of initialization
- */
-/* 2M mipi setting-common from PARTRON */
-/*******************************************************
-* Name: SR200PC20M Initial Setfile
-* PLL mode: MCLK=24MHz / SYSCLK=28MHz / PCLK=48MHz
-* FPS: VGA 7.5~15fps / UXGA 7.5fps / recording 25fps
-* Made by: ZEROHOY
-* Date: 2011.03.07
-* History:
-*******************************************************/
-regs_short_t front_init_regs[] = {
-/* Self-Cam -continuous*/
-/* CAMERA INITIAL for Self Camera(Variable Frame)*/
-
-{0x01, 0xf9},/* sleep on */
-{0x01, 0xfb},/* sleep on */
-{0x01, 0xf9},/* sleep on */
-{0x08, 0x20},/* sleep on */
-{0x0a, 0x3f},/* sleep on */
-
-/* PAGE 20 */
-{0x03, 0x20},/* page 20 */
-{0x10, 0x0c},/* AE off 60hz */
-
-/* PAGE 22 */
-{0x03, 0x22},/* page 22 */
-{0x10, 0x69},/* AWB off */
-
-{0x03, 0x12},
-{0x20, 0x00},
-{0x21, 0x00},
-
-{0x03, 0x13},
-{0x10, 0xcb},
-
-/* Initial Start */
-/* PAGE 0 START */
-{0x03, 0x00},
-{0x10, 0x11},/* Vsync Active High B:[3] , Sub1/2 + Preview 1mode */
-{0x11, 0x90},
-{0x12, 0x04},/* Pclk Falling Edge B:[2] *//* 1016 0x04->0x00 */
-
-{0x0b, 0xaa},/* ESD Check Register */
-{0x0c, 0xaa},/* ESD Check Register */
-{0x0d, 0xaa},/* ESD Check Register */
-
-{0x20, 0x00},
-{0x21, 0x02},/* modify 20110929 0x04->0x02 */
-{0x22, 0x00},
-{0x23, 0x0a},/* modify 20110929 0x14->0x0a */
-
-{0x24, 0x04},
-{0x25, 0xb0},
-{0x26, 0x06},
-{0x27, 0x40},
-
-{0x28, 0x0c},
-{0x29, 0x04},
-{0x2a, 0x02},
-{0x2b, 0x04},
-{0x2c, 0x06},
-{0x2d, 0x02},
-
-{0x40, 0x01},/* Hblank_360 */
-{0x41, 0x68},
-{0x42, 0x00},
-{0x43, 0x44},/* Flick Stop 60hz */
-{0x44, 0x09},/* VSCLIP */
-
-{0x45, 0x04},
-{0x46, 0x18},
-{0x47, 0xd8},
-
- /*BLC*/ {0x80, 0x2e},
-{0x81, 0x7e},
-{0x82, 0x90},
-{0x83, 0x00},
-{0x84, 0x0c},
-{0x85, 0x00},
-{0x90, 0x0f},/* BLC_TIME_TH_ON */
-{0x91, 0x0f},/* BLC_TIME_TH_OFF */
-{0x92, 0xd8},/* BLC_AG_TH_ON */
-{0x93, 0xd0},/* BLC_AG_TH_OFF */
-{0x94, 0xff},
-{0x95, 0xff},
-{0x96, 0xdc},
-{0x97, 0xfe},
-{0x98, 0x38},
-
-/*Dark BLC*/
-{0xa0, 0x00},
-{0xa2, 0x00},
-{0xa4, 0x00},
-{0xa6, 0x00},
-
-/*Normal BLC*/
-{0xa8, 0x43},
-{0xaa, 0x43},
-{0xac, 0x43},
-{0xae, 0x43},
-
-/*OutDoor BLC*/
-{0x99, 0x43},
-{0x9a, 0x43},
-{0x9b, 0x43},
-{0x9c, 0x43},
-/* PAGE 0 END */
-
-/* PAGE 2 START */
-{0x03, 0x02},
-{0x12, 0x03},
-{0x13, 0x03},
-{0x16, 0x00},
-{0x17, 0x8C},
-{0x18, 0x4c},/* Double_AG */
-{0x19, 0x00},
-{0x1a, 0x39},/* Double_AG 38 ->39 */
-{0x1c, 0x09},
-{0x1d, 0x40},
-{0x1e, 0x30},
-{0x1f, 0x10},
-
-{0x20, 0x77},
-{0x21, 0xde},
-{0x22, 0xa7},
-{0x23, 0x30},/* CLAMP */
-{0x27, 0x3c},
-{0x2b, 0x80},
-{0x2e, 0x00},
-{0x2f, 0x00},
-{0x30, 0x05},/* For Hi-253 never no change 0x05 */
-
-{0x50, 0x20},
-{0x51, 0x03},/* 20110826 Ãß°¡ */
-{0x52, 0x01},/* 0x03 --> 0x01 */
-{0x53, 0xc1},/* 20110818 Ãß°¡ */
-{0x55, 0x1c},
-{0x56, 0x11},
-{0x5d, 0xa2},
-{0x5e, 0x5a},
-
-{0x60, 0x87},
-{0x61, 0x99},
-{0x62, 0x88},
-{0x63, 0x97},
-{0x64, 0x88},
-{0x65, 0x97},
-
-{0x67, 0x0c},
-{0x68, 0x0c},
-{0x69, 0x0c},
-
-{0x72, 0x89},
-{0x73, 0x96},
-{0x74, 0x89},
-{0x75, 0x96},
-{0x76, 0x89},
-{0x77, 0x96},
-
-{0x7c, 0x85},
-{0x7d, 0xaf},
-{0x80, 0x01},
-{0x81, 0x7f},
-{0x82, 0x13},
-{0x83, 0x24},
-{0x84, 0x7d},
-{0x85, 0x81},
-{0x86, 0x7d},
-{0x87, 0x81},
-
-{0x92, 0x48},
-{0x93, 0x54},
-{0x94, 0x7d},
-{0x95, 0x81},
-{0x96, 0x7d},
-{0x97, 0x81},
-
-{0xa0, 0x02},
-{0xa1, 0x7b},
-{0xa2, 0x02},
-{0xa3, 0x7b},
-{0xa4, 0x7b},
-{0xa5, 0x02},
-{0xa6, 0x7b},
-{0xa7, 0x02},
-
-{0xa8, 0x85},
-{0xa9, 0x8c},
-{0xaa, 0x85},
-{0xab, 0x8c},
-{0xac, 0x10},
-{0xad, 0x16},
-{0xae, 0x10},
-{0xaf, 0x16},
-
-{0xb0, 0x99},
-{0xb1, 0xa3},
-{0xb2, 0xa4},
-{0xb3, 0xae},
-{0xb4, 0x9b},
-{0xb5, 0xa2},
-{0xb6, 0xa6},
-{0xb7, 0xac},
-{0xb8, 0x9b},
-{0xb9, 0x9f},
-{0xba, 0xa6},
-{0xbb, 0xaa},
-{0xbc, 0x9b},
-{0xbd, 0x9f},
-{0xbe, 0xa6},
-{0xbf, 0xaa},
-
-{0xc4, 0x2c},
-{0xc5, 0x43},
-{0xc6, 0x63},
-{0xc7, 0x79},
-
-{0xc8, 0x2d},
-{0xc9, 0x42},
-{0xca, 0x2d},
-{0xcb, 0x42},
-{0xcc, 0x64},
-{0xcd, 0x78},
-{0xce, 0x64},
-{0xcf, 0x78},
-{0xd0, 0x0a},
-{0xd1, 0x09},
-{0xd4, 0x0f},/* DCDC_TIME_TH_ON */
-{0xd5, 0x0f},/* DCDC_TIME_TH_OFF */
-{0xd6, 0xd8},/* DCDC_AG_TH_ON */
-{0xd7, 0xd0},/* DCDC_AG_TH_OFF */
-{0xe0, 0xc4},
-{0xe1, 0xc4},
-{0xe2, 0xc4},
-{0xe3, 0xc4},
-{0xe4, 0x00},
-{0xe8, 0x80},
-{0xe9, 0x40},
-{0xea, 0x7f},
-
-{0xf0, 0x01},
-{0xf1, 0x01},
-{0xf2, 0x01},
-{0xf3, 0x01},
-{0xf4, 0x01},
-
-/* PAGE 2 END */
-
-/* PAGE 3 */
-{0x03, 0x03},
-{0x10, 0x10},
-/* PAGE 3 END */
-
-/* PAGE 10 START */
-{0x03, 0x10},
-{0x10, 0x01},/* CrYCbY 03 00 */
-{0x12, 0x30},
-{0x20, 0x00},
-{0x30, 0x00},
-{0x31, 0x00},
-{0x32, 0x00},
-{0x33, 0x00},
-
-{0x34, 0x30},
-{0x35, 0x00},
-{0x36, 0x00},
-{0x38, 0x00},
-{0x3e, 0x58},
-{0x3f, 0x02},/* For Preview */
-
-{0x40, 0x80},
-{0x41, 0x00},
-
-{0x60, 0x6b},
-{0x61, 0x7a},/* 77 */
-{0x62, 0x72},/* 77 */
-{0x63, 0x50},/* Double_AG 50->30 */
-{0x64, 0x80},
-
-{0x66, 0x42},
-{0x67, 0x20},
-
-{0x6a, 0x80},/* 8a */
-{0x6b, 0x84},/* 74 */
-{0x6c, 0x7a},/* 7e */
-{0x6d, 0x80},/* 8e */
-
-/* PAGE 11 START */
-{0x03, 0x11},
-{0x10, 0x7f},
-{0x11, 0x40},
-{0x12, 0x0a},/* Blue Max-Filter Delete */
-{0x13, 0xbb},
-
-{0x26, 0x31},/* Double_AG 31->20 */
-{0x27, 0x34},/* Double_AG 34->22 */
-{0x28, 0x0f},
-{0x29, 0x10},
-{0x2b, 0x30},
-{0x2c, 0x32},
-
-/*Out2 D-LPF th*/
-{0x30, 0x70},
-{0x31, 0x10},
-{0x32, 0x58},
-{0x33, 0x09},
-{0x34, 0x06},
-{0x35, 0x03},
-
-/*Out1 D-LPF th*/
-{0x36, 0x70},
-{0x37, 0x18},
-{0x38, 0x58},
-{0x39, 0x20},
-{0x3a, 0x1f},
-{0x3b, 0x03},
-
-/*Indoor D-LPF th*/
-{0x3c, 0x80},
-{0x3d, 0x18},
-{0x3e, 0x80},
-{0x3f, 0x0c},
-{0x40, 0x09},
-{0x41, 0x06},
-
-/*Dark1 D-LPF th*/
-{0x42, 0x80},
-{0x43, 0x18},
-{0x44, 0x80},
-{0x45, 0x0f},
-{0x46, 0x0c},
-{0x47, 0x0b},
-
-/*Dark2 D-LPF th*/
-{0x48, 0x88},
-{0x49, 0x2c},
-{0x4a, 0x80},
-{0x4b, 0x0f},
-{0x4c, 0x0c},
-{0x4d, 0x0b},
-
-/*Dark3 D-LPF th*/
-{0x4e, 0x80},
-{0x4f, 0x23},
-{0x50, 0x80},
-{0x51, 0x0f},
-{0x52, 0x0c},
-{0x53, 0x0c},
-
-{0x54, 0x11},
-{0x55, 0x17},
-{0x56, 0x20},
-{0x57, 0x01},
-{0x58, 0x00},
-{0x59, 0x00},
-
-{0x5a, 0x18},
-{0x5b, 0x00},
-{0x5c, 0x00},
-
-{0x60, 0x3f},
-{0x62, 0x60},
-{0x70, 0x06},
-/* PAGE 11 END */
-
-/* PAGE 12 START */
-{0x03, 0x12},
-
-{0x25, 0x00},/* 0x30 */
-
-{0x28, 0x00},
-{0x29, 0x00},
-{0x2a, 0x00},
-
-{0x30, 0x50},
-{0x31, 0x18},
-{0x32, 0x32},
-{0x33, 0x40},
-{0x34, 0x50},
-{0x35, 0x70},
-{0x36, 0xa0},
-
-/*Out2 th*/
-{0x40, 0xa0},
-{0x41, 0x40},
-{0x42, 0xa0},
-{0x43, 0x90},
-{0x44, 0x90},
-{0x45, 0x80},
-
-/*Out1 th*/
-{0x46, 0xb0},
-{0x47, 0x55},
-{0x48, 0xb0},
-{0x49, 0xb0},
-{0x4a, 0x90},
-{0x4b, 0x80},
-
-/*Indoor th*/
-{0x4c, 0xb0},
-{0x4d, 0x40},
-{0x4e, 0x90},
-{0x4f, 0x90},
-{0x50, 0xa0},
-{0x51, 0x80},
-
-/*Dark1 th*/
-{0x52, 0xb0},
-{0x53, 0x50},
-{0x54, 0xa8},
-{0x55, 0xa8},
-{0x56, 0xb0},
-{0x57, 0x7b},
-
-/*Dark2 th*/
-{0x58, 0xa0},
-{0x59, 0x40},
-{0x5a, 0xb8},
-{0x5b, 0xb8},
-{0x5c, 0xc8},
-{0x5d, 0x7b},
-
-/*Dark3 th*/
-{0x5e, 0x9c},
-{0x5f, 0x40},
-{0x60, 0xc0},
-{0x61, 0xc0},
-{0x62, 0xc8},
-{0x63, 0x7b},
-
-{0x70, 0x15},
-{0x71, 0x01},/* Don't Touch register */
-
-{0x72, 0x18},
-{0x73, 0x01},/* Don't Touch register */
-
-{0x74, 0x25},
-{0x75, 0x15},
-
-{0x80, 0x20},
-{0x81, 0x40},
-{0x82, 0x65},
-{0x85, 0x1a},
-{0x88, 0x00},
-{0x89, 0x00},
-{0x90, 0x00},/* For Preview */
-
-/*Dont Touch register*/
-{0xD0, 0x0c},
-{0xD1, 0x80},
-
-/*only for Preview DPC*/
-{0xD2, 0x17},
-
-{0xD3, 0x00},
-{0xD4, 0x00},
-
-/*only for Preview DPC*/
-{0xd5, 0x0f},
-
-{0xD6, 0xff},
-
-/*only for Preview DPC*/
-{0xd7, 0xff},
-
-/*End*/
-{0x3b, 0x06},
-{0x3c, 0x06},
-
-/*Dont Touch register*/
-{0xc5, 0x30},/* 55->48 */
-{0xc6, 0x2a},/* 48->40 */
-/* PAGE 12 END */
-
-/* PAGE 13 START */
-
-{0x03, 0x13},
-{0x11, 0x7b},
-{0x12, 0x07},
-{0x14, 0x00},
-
-{0x20, 0x15},
-{0x21, 0x13},
-{0x22, 0x33},
-{0x23, 0x05},
-{0x24, 0x09},
-
-{0x25, 0x0a},
-
-{0x26, 0x18},
-{0x27, 0x30},
-{0x29, 0x12},
-{0x2a, 0x50},
-
-/*Low clip th*/
-{0x2b, 0x02},
-{0x2c, 0x02},
-{0x25, 0x06},
-{0x2d, 0x0c},
-{0x2e, 0x12},
-{0x2f, 0x12},
-
-/*Out2 Edge*/
-{0x50, 0x10},
-{0x51, 0x14},
-{0x52, 0x12},
-{0x53, 0x0c},
-{0x54, 0x0f},
-{0x55, 0x0c},
-
-/*Out1 Edge*/
-{0x56, 0x0f},
-{0x57, 0x12},
-{0x58, 0x12},
-{0x59, 0x09},
-{0x5a, 0x0c},
-{0x5b, 0x0c},
-
-/*Indoor Edge*/
-{0x5c, 0x0a},
-{0x5d, 0x0b},
-{0x5e, 0x0a},
-{0x5f, 0x08},
-{0x60, 0x09},
-{0x61, 0x08},
-
-/*Dark1 Edge*/
-{0x62, 0x09},
-{0x63, 0x09},
-{0x64, 0x09},
-{0x65, 0x07},
-{0x66, 0x07},
-{0x67, 0x07},
-
-/*Dark2 Edge*/
-{0x68, 0x08},
-{0x69, 0x08},
-{0x6a, 0x08},
-{0x6b, 0x06},
-{0x6c, 0x06},
-{0x6d, 0x06},
-
-/*Dark3 Edge*/
-{0x6e, 0x08},
-{0x6f, 0x08},
-{0x70, 0x08},
-{0x71, 0x06},
-{0x72, 0x06},
-{0x73, 0x06},
-
-/*2DY*/
-{0x80, 0x00},
-{0x81, 0x1f},
-{0x82, 0x05},
-{0x83, 0x31},
-
-{0x90, 0x05},
-{0x91, 0x05},
-{0x92, 0x33},
-{0x93, 0x30},
-{0x94, 0x03},
-{0x95, 0x14},
-{0x97, 0x20},
-{0x99, 0x20},
-
-{0xa0, 0x01},
-{0xa1, 0x02},
-{0xa2, 0x01},
-{0xa3, 0x02},
-{0xa4, 0x05},
-{0xa5, 0x05},
-{0xa6, 0x07},
-{0xa7, 0x08},
-{0xa8, 0x07},
-{0xa9, 0x08},
-{0xaa, 0x07},
-{0xab, 0x08},
-
-/*Out2*/
-{0xb0, 0x22},
-{0xb1, 0x2a},
-{0xb2, 0x28},
-{0xb3, 0x22},
-{0xb4, 0x2a},
-{0xb5, 0x28},
-
-/*Out1*/
-{0xb6, 0x22},
-{0xb7, 0x2a},
-{0xb8, 0x28},
-{0xb9, 0x22},
-{0xba, 0x2a},
-{0xbb, 0x28},
-
-/*Indoor*/
-{0xbc, 0x25},
-{0xbd, 0x2a},
-{0xbe, 0x27},
-{0xbf, 0x25},
-{0xc0, 0x2a},
-{0xc1, 0x27},
-
-/*Dark1*/
-{0xc2, 0x1e},
-{0xc3, 0x24},
-{0xc4, 0x20},
-{0xc5, 0x1e},
-{0xc6, 0x24},
-{0xc7, 0x20},
-
-/*Dark2*/
-{0xc8, 0x18},
-{0xc9, 0x20},
-{0xca, 0x1e},
-{0xcb, 0x18},
-{0xcc, 0x20},
-{0xcd, 0x1e},
-
-/*Dark3*/
-{0xce, 0x18},
-{0xcf, 0x20},
-{0xd0, 0x1e},
-{0xd1, 0x18},
-{0xd2, 0x20},
-{0xd3, 0x1e},
-/* PAGE 13 END */
-
-/* PAGE 14 START */
-{0x03, 0x14},
-{0x10, 0x11},
-
-{0x14, 0x80},/* GX */
-{0x15, 0x80},/* GY */
-{0x16, 0x80},/* RX */
-{0x17, 0x80},/* RY */
-{0x18, 0x80},/* BX */
-{0x19, 0x80},/* BY */
-
-{0x20, 0x80},/* X */
-{0x21, 0x80},/* Y */
-
-{0x22, 0x80},
-{0x23, 0x80},
-{0x24, 0x80},
-
-{0x30, 0xc8},
-{0x31, 0x2b},
-{0x32, 0x00},
-{0x33, 0x00},
-{0x34, 0x90},
-
-{0x40, 0x37},
-{0x50, 0x26},/* 2d */
-{0x60, 0x22},/* 26 */
-{0x70, 0x26},/* 2d */
-/* PAGE 14 END */
-
-/* PAGE 15 START */
-{0x03, 0x15},
-{0x10, 0x0f},
-
-/*Rstep H 16*/
-/*Rstep L 14*/
-{0x14, 0x46},/* CMCOFSGH */
-{0x15, 0x36},/* CMCOFSGM */
-{0x16, 0x26},/* CMCOFSGL */
-{0x17, 0x2f},/* CMC SIGN */
-
- /*CMC*/ {0x30, 0x8f},
-{0x31, 0x59},
-{0x32, 0x0a},
-{0x33, 0x15},
-{0x34, 0x5b},
-{0x35, 0x06},
-{0x36, 0x07},
-{0x37, 0x40},
-{0x38, 0x87},
-
-/*CMC OFS*/
-{0x40, 0x94},
-{0x41, 0x20},
-{0x42, 0x89},
-{0x43, 0x84},
-{0x44, 0x03},
-{0x45, 0x01},
-{0x46, 0x88},
-{0x47, 0x9c},
-{0x48, 0x28},
-
-/*CMC POFS*/
-{0x50, 0x02},
-{0x51, 0x82},
-{0x52, 0x00},
-{0x53, 0x07},
-{0x54, 0x11},
-{0x55, 0x98},
-{0x56, 0x00},
-{0x57, 0x0b},
-{0x58, 0x8b},
-
-{0x80, 0x00},
-{0x85, 0x80},
-{0x87, 0x02},
-{0x88, 0x00},
-{0x89, 0x00},
-{0x8a, 0x00},
-/* PAGE 15 END */
-
-/* PAGE 16 START */
-{0x03, 0x16},
-{0x10, 0x31},
-{0x18, 0x5e},/* Double_AG 5e->37 */
-{0x19, 0x5d},/* Double_AG 5e->36 */
-{0x1a, 0x0e},
-{0x1b, 0x01},
-{0x1c, 0xdc},
-{0x1d, 0xfe},
-
-/*GMA Default*/
-{0x30, 0x00},
-{0x31, 0x08},
-{0x32, 0x1c},
-{0x33, 0x32},
-{0x34, 0x54},
-{0x35, 0x70},
-{0x36, 0x87},
-{0x37, 0x9a},
-{0x38, 0xaa},
-{0x39, 0xb9},
-{0x3a, 0xc4},
-{0x3b, 0xcf},
-{0x3c, 0xd8},
-{0x3d, 0xe0},
-{0x3e, 0xe9},
-{0x3f, 0xf0},
-{0x40, 0xf7},
-{0x41, 0xfc},
-{0x42, 0xff},
-
-{0x50, 0x00},
-{0x51, 0x08},
-{0x52, 0x1e},
-{0x53, 0x36},
-{0x54, 0x5a},
-{0x55, 0x75},
-{0x56, 0x8d},
-{0x57, 0xa1},
-{0x58, 0xb2},
-{0x59, 0xbe},
-{0x5a, 0xc9},
-{0x5b, 0xd2},
-{0x5c, 0xdb},
-{0x5d, 0xe3},
-{0x5e, 0xeb},
-{0x5f, 0xf0},
-{0x60, 0xf5},
-{0x61, 0xf7},
-{0x62, 0xf8},
-
-{0x70, 0x00},
-{0x71, 0x0b},
-{0x72, 0x1a},
-{0x73, 0x37},
-{0x74, 0x58},
-{0x75, 0x70},
-{0x76, 0x86},
-{0x77, 0x99},
-{0x78, 0xa9},
-{0x79, 0xb7},
-{0x7a, 0xc3},
-{0x7b, 0xcf},
-{0x7c, 0xd9},
-{0x7d, 0xe1},
-{0x7e, 0xe8},
-{0x7f, 0xef},
-{0x80, 0xf4},
-{0x81, 0xfa},
-{0x82, 0xff},
-/* PAGE 16 END */
-
-/* PAGE 17 START */
-{0x03, 0x17},
-{0x10, 0xf7},
-/* PAGE 17 END */
-
-/* PAGE 18 START */
-{0x03, 0x18},
-{0x10, 0x07},
-{0x11, 0x00},
-{0x12, 0x58},
-{0x20, 0x05},
-{0x21, 0x00},
-{0x22, 0x01},
-{0x23, 0xe0},
-{0x24, 0x00},
-{0x25, 0x04},
-{0x26, 0x00},
-{0x27, 0x04},
-{0x28, 0x05},
-{0x29, 0x04},
-{0x2a, 0x01},
-{0x2b, 0xe4},
-{0x2c, 0x0a},
-{0x2d, 0x00},
-{0x2e, 0x0a},
-{0x2f, 0x00},
-{0x30, 0x46},
-/* PAGE 18 END */
-
-/* PAGE 20 START */
-{0x03, 0x20},
-{0x11, 0x1c},
-{0x18, 0x30},
-{0x1a, 0x08},
-{0x20, 0x05},
-{0x21, 0x30},
-{0x22, 0x10},
-{0x23, 0x00},
-{0x24, 0x00},
-
-{0x28, 0xef},
-{0x29, 0x0d},/* 20100305 ad->0d */
-{0x2a, 0xff},
-{0x2b, 0xf4},
-
-{0x2c, 0xc2},
-{0x2d, 0xff},
-{0x2e, 0x33},
-{0x30, 0xf8},
-{0x32, 0x03},
-{0x33, 0x2e},
-{0x34, 0x30},
-{0x35, 0xd4},
-{0x36, 0xfe},
-{0x37, 0x32},
-{0x38, 0x04},
-{0x39, 0x22},
-{0x3a, 0xde},
-{0x3b, 0x22},
-{0x3c, 0xde},
-
-{0x50, 0x45},
-{0x51, 0x88},
-
-{0x56, 0x03},
-{0x57, 0xf7},
-{0x58, 0x14},
-{0x59, 0x88},
-{0x5a, 0x04},
-
-{0x60, 0xaa},
-{0x61, 0xaa},
-{0x62, 0xaa},
-{0x63, 0xaa},
-{0x64, 0xaa},
-{0x65, 0xaa},
-{0x66, 0xab},
-{0x67, 0xEa},
-{0x68, 0xab},
-{0x69, 0xEa},
-{0x6a, 0xaa},
-{0x6b, 0xaa},
-{0x6c, 0xaa},
-{0x6d, 0xaa},
-{0x6e, 0xaa},
-{0x6f, 0xaa},
-
-{0x70, 0x70},/* 6c */
-{0x71, 0x82},/* 82(+8) */
-
-{0x76, 0x43},
-{0x77, 0x02},
-{0x78, 0x24},/* 24 */
-{0x79, 0x48},/* Y Target 70 => 25, 72 => 26 */
-{0x7a, 0x23},/* 23 */
-{0x7b, 0x22},/* 22 */
-{0x7d, 0x23},
-
-{0x83, 0x01},/* EXP Normal 30.00 fps */
-{0x84, 0x86},
-{0x85, 0xa0},
-
-{0x86, 0x01},/* EXPMin 6000.00 fps */
-{0x87, 0xf4},
-
-{0x88, 0x05},/* EXP Max 8.00 fps */
-{0x89, 0xb8},
-{0x8a, 0xd8},
-
-{0x8B, 0x75},/* EXP100, PLLx2 Mclk24 */
-{0x8C, 0x30},
-
-{0x8D, 0x61},/* EXP120, PLLx2 Mclk24 */
-{0x8E, 0xa8},
-
-{0x98, 0x9d},
-{0x99, 0x45},
-{0x9a, 0x0d},
-{0x9b, 0xde},
-
-{0x9c, 0x17},/* EXP Limit 500.00 fps, PLLx2 Mclk24 */
-{0x9d, 0x70},
-
-{0x9e, 0x01},/* EXP Unit, PLLx2 Mclk24 */
-{0x9f, 0xf4},
-
-{0xb0, 0x18},
-{0xb1, 0x14},
-{0xb2, 0xe0},
-{0xb3, 0x18},
-{0xb4, 0x1a},
-{0xb5, 0x44},
-{0xb6, 0x2f},
-{0xb7, 0x28},
-{0xb8, 0x25},
-{0xb9, 0x22},
-{0xba, 0x21},
-{0xbb, 0x20},
-{0xbc, 0x32},
-{0xbd, 0x32},
-
-{0xc0, 0x10},
-{0xc1, 0x2b},
-{0xc2, 0x2b},
-{0xc3, 0x2b},
-{0xc4, 0x08},
-
-{0xc8, 0x80},
-{0xc9, 0x80},
-/* PAGE 20 END */
-
-/* PAGE 22 START */
-{0x03, 0x22},
-{0x10, 0xfd},
-{0x11, 0x2e},
-{0x19, 0x01},/* Low On */
-{0x20, 0x10},
-{0x21, 0x80},
-{0x24, 0x01},
-/*0x2500, 7f New Lock Cond & New light stable */
-
-{0x30, 0x80},
-{0x31, 0x80},
-{0x38, 0x11},
-{0x39, 0x34},
-{0x40, 0xf3},
-
-{0x41, 0x32},/* 33 */
-{0x42, 0x22},/* 22 */
-{0x43, 0xf0},/* f6 */
-{0x44, 0x44},/* 44 */
-{0x45, 0x44},/* 33 */
-{0x46, 0x00},
-{0x50, 0xb2},
-{0x51, 0x81},
-{0x52, 0x98},
-
-{0x80, 0x38},
-{0x81, 0x20},
-{0x82, 0x36},/* 3a */
-
-{0x83, 0x5e},/* 5e */
-{0x84, 0x22},/* 24 21 22 Spec AWB H modify */
-{0x85, 0x4f},/* 54 51 4f Spec AWB H modify */
-{0x86, 0x20},/* 24 */
-
-{0x87, 0x48},
-{0x88, 0x38},
-{0x89, 0x37},/* 38 */
-{0x8a, 0x29},/* 2a */
-
-{0x8b, 0x40},/* 47 */
-{0x8c, 0x38},
-{0x8d, 0x34},
-{0x8e, 0x29},/* 2c */
-
-{0x8f, 0x5c},
-{0x90, 0x5b},
-{0x91, 0x57},
-{0x92, 0x4f},
-{0x93, 0x43},
-{0x94, 0x3e},
-{0x95, 0x34},
-{0x96, 0x2c},
-{0x97, 0x23},
-{0x98, 0x20},
-{0x99, 0x1f},
-{0x9a, 0x1f},
-
-{0x9b, 0x77},
-{0x9c, 0x66},
-{0x9d, 0x48},
-{0x9e, 0x38},
-{0x9f, 0x30},
-
-{0xa0, 0x60},
-{0xa1, 0x34},
-{0xa2, 0x6f},
-{0xa3, 0xff},
-
-{0xa4, 0x14},/* 1500fps */
-{0xa5, 0x2c},/* 700fps */
-{0xa6, 0xcf},
-
-{0xad, 0x40},
-{0xae, 0x4a},
-
-{0xaf, 0x28},/* low temp Rgain */
-{0xb0, 0x26},/* low temp Rgain */
-
-{0xb1, 0x00},/* 0x20 -> 0x00 0405 modify */
-{0xb4, 0xea},
-{0xb8, 0xa1},/* a2: b-2, R+2 b4 B-3, R+4 lowtemp b0 a1 Spec AWB A modify */
-{0xb9, 0x00},
-/* PAGE 22 END */
-
-/* PAGE 48 START*/
-{0x03, 0x48},
-
-/* PLL Setting */
-{0x70, 0x05},
-{0x71, 0x30},/*MiPi Pllx2 */
-{0x72, 0x85},
-{0x70, 0xa5},/* PLL Enable */
-{0x03, 0x48},
-{0x03, 0x48},
-{0x03, 0x48},
-{0x03, 0x48},
-{0x70, 0x95},/* CLK_GEN_ENABLE */
-
-/* MIPI TX Setting */
-{0x11, 0x00},/* 20111013 0x10 continuous -> 0x00 not Continuous */
-/*0x17cc*/
-{0x10, 0x1c},
-{0x12, 0x00},
-{0x14, 0x30},/*0x1470, *//* 20111013 0x00 -> 0x30 Clock Delay */
-{0x16, 0x04},/* 1016 0x04->0x05 */
-
-{0x19, 0x00},
-{0x1a, 0x32},
-{0x1b, 0x17},
-{0x1c, 0x0e},
-{0x1d, 0x0f},
-{0x1e, 0x04},
-{0x1f, 0x04},
-{0x20, 0x00},
-
-{0x23, 0x01},
-{0x24, 0x1e},
-{0x25, 0x00},
-{0x26, 0x00},
-{0x27, 0x01},
-{0x28, 0x00},
-{0x2a, 0x06},
-{0x2b, 0x40},
-{0x2c, 0x04},
-{0x2d, 0xb0},
-
-{0x30, 0x00},/*640x480 MiPi OutPut */
-{0x31, 0x05},
-
-/*0x3040, 800x600 MiPi OutPut*/
-/*0x3106,*/
-
-{0x32, 0x06},
-{0x33, 0x0a},
-{0x34, 0x02},/*CLK LP -> HS Prepare time 24MHz:0x02, 48MHz:0x03 */
-{0x35, 0x03},
-{0x36, 0x01},
-{0x37, 0x07},
-{0x38, 0x02},
-{0x39, 0x02},/*drivability 24MHZ:0x02, 48MHz:0x03 */
-/*0x17c4,*/ /*MHSHIM*/
-/*0x17c0,*/ /*MHSHIM*/
-/*0x1700,*/ /*MHSHIM*/
-{0x50, 0x00},
-/* PAGE 48 END*/
-
-/* PAGE 20 */
-{0x03, 0x20},
-{0x10, 0x8c},/*AE on 60hz */
-
-/* PAGE 22 */
-{0x03, 0x22},
-{0x10, 0xe9},
-
-/* PAGE 0 */
-{0x03, 0x00},
-{0x03, 0x00},
-{0x03, 0x00},
-{0x03, 0x00},
-{0x03, 0x00},
-{0x03, 0x00},
-{0x03, 0x00},
-{0x03, 0x00},
-{0x03, 0x00},
-{0x03, 0x00},
-{0x03, 0x00},
-
-{0x03, 0x00},
-{0x01, 0xf8},
-
-{0xff, 0x0a},/* NEED Delay 100ms */
-};
-
-/*==================================================*/
-/* CAMERA INITIAL for Self Recording 24 Fixed Frame */
-/*==================================================*/
-regs_short_t front_init_recording_regs[] = {
-/* Recording 25fps Anti-Flicker 60Hz END of Initial */
-/* CAMERA INITIAL for Self Recording 24 Fixed Frame */
-{0x01, 0xf9},/*sleep on */
-{0x01, 0xfb},/* sleep on */
-{0x01, 0xf9},/*sleep on */
-{0x08, 0x20},/* sleep on */
-{0x0a, 0x3f},/* sleep on */
-
-/* PAGE 20 */
-{0x03, 0x20},/*page 20 */
-{0x10, 0x0c},/*AE off 60hz */
-
-/* PAGE 22 */
-{0x03, 0x22},/*page 22 */
-{0x10, 0x69},/* AWB off */
-
-{0x03, 0x12},
-{0x20, 0x00},
-{0x21, 0x00},
-
-{0x03, 0x13},
-{0x10, 0xcb},
-
-/*Initial Start*/
-/* PAGE 0 START */
-{0x03, 0x00},
-{0x10, 0x03},/* Vsync Active High B:[3] , Sub1/2 + Preview 1 */
-{0x11, 0x94},
-{0x12, 0x04},/* Pclk Falling Edge B:[2] 1016 0x04->0x00 */
-
-{0x0b, 0xaa},
-{0x0c, 0xaa},
-{0x0d, 0xaa},
-
-{0x20, 0x00},
-{0x21, 0x04},
-{0x22, 0x00},
-{0x23, 0x06},
-
-{0x24, 0x04},
-{0x25, 0xb0},
-{0x26, 0x06},
-{0x27, 0x40},
-
-{0x28, 0x0c},
-{0x29, 0x04},
-{0x2a, 0x02},
-{0x2b, 0x04},
-{0x2c, 0x06},
-{0x2d, 0x02},
-
-{0x40, 0x01},/*Hblank 352 */
-{0x41, 0x60},
-{0x42, 0x00},/*Vblank 20 */
-{0x43, 0x14},
-
-{0x45, 0x04},
-{0x46, 0x18},
-{0x47, 0xd8},
-
- /*BLC*/ {0x80, 0x2e},
-{0x81, 0x7e},
-{0x82, 0x90},
-{0x83, 0x00},
-{0x84, 0x0c},
-{0x85, 0x00},
-{0x90, 0x05},/*BLC_TIME_TH_ON */
-{0x91, 0x05},/*BLC_TIME_TH_OFF */
-{0x92, 0xb0},/*BLC_AG_TH_ON */
-{0x93, 0xa8},/*BLC_AG_TH_OFF */
-{0x94, 0xff},
-{0x95, 0xff},
-{0x96, 0xdc},
-{0x97, 0xfe},
-{0x98, 0x38},
-
-/*Dark BLC*/
-{0xa0, 0x00},
-{0xa2, 0x00},
-{0xa4, 0x00},
-{0xa6, 0x00},
-
-/*Normal BLC*/
-{0xa8, 0x43},
-{0xaa, 0x43},
-{0xac, 0x43},
-{0xae, 0x43},
-
-/*OutDoor BLC*/
-{0x99, 0x43},
-{0x9a, 0x43},
-{0x9b, 0x43},
-{0x9c, 0x43},
-/* PAGE 0 END */
-
-/* PAGE 2 START */
-{0x03, 0x02},
-{0x12, 0x03},
-{0x13, 0x03},
-{0x16, 0x00},
-{0x17, 0x8C},
-{0x18, 0x4c},/*Double_AG */
-{0x19, 0x00},
-{0x1a, 0x39},/*Double_AG 38 ->39 */
-{0x1c, 0x09},
-{0x1d, 0x40},
-{0x1e, 0x30},
-{0x1f, 0x10},
-
-{0x20, 0x77},
-{0x21, 0xde},
-{0x22, 0xa7},
-{0x23, 0x30}, /*CLAMP*/ {0x27, 0x3c},
-{0x2b, 0x80},
-{0x2e, 0x00},
-{0x2f, 0x00},
-{0x30, 0x05},/*For Hi-253 never no change 0x05 */
-
-{0x50, 0x20},
-{0x51, 0x03},/*20110826 */
-{0x52, 0x01},/*0x03 --> 0x01 */
-{0x53, 0xc1},/*20110818 Ãß°¡ */
-{0x55, 0x1c},
-{0x56, 0x11},
-{0x5d, 0xa2},
-{0x5e, 0x5a},
-
-{0x60, 0x87},
-{0x61, 0x99},
-{0x62, 0x88},
-{0x63, 0x97},
-{0x64, 0x88},
-{0x65, 0x97},
-
-{0x67, 0x0c},
-{0x68, 0x0c},
-{0x69, 0x0c},
-
-{0x72, 0x89},
-{0x73, 0x96},
-{0x74, 0x89},
-{0x75, 0x96},
-{0x76, 0x89},
-{0x77, 0x96},
-
-{0x7c, 0x85},
-{0x7d, 0xaf},
-{0x80, 0x01},
-{0x81, 0x7f},
-{0x82, 0x13},
-{0x83, 0x24},
-{0x84, 0x7d},
-{0x85, 0x81},
-{0x86, 0x7d},
-{0x87, 0x81},
-
-{0x92, 0x48},
-{0x93, 0x54},
-{0x94, 0x7d},
-{0x95, 0x81},
-{0x96, 0x7d},
-{0x97, 0x81},
-
-{0xa0, 0x02},
-{0xa1, 0x7b},
-{0xa2, 0x02},
-{0xa3, 0x7b},
-{0xa4, 0x7b},
-{0xa5, 0x02},
-{0xa6, 0x7b},
-{0xa7, 0x02},
-
-{0xa8, 0x85},
-{0xa9, 0x8c},
-{0xaa, 0x85},
-{0xab, 0x8c},
-{0xac, 0x10},
-{0xad, 0x16},
-{0xae, 0x10},
-{0xaf, 0x16},
-
-{0xb0, 0x99},
-{0xb1, 0xa3},
-{0xb2, 0xa4},
-{0xb3, 0xae},
-{0xb4, 0x9b},
-{0xb5, 0xa2},
-{0xb6, 0xa6},
-{0xb7, 0xac},
-{0xb8, 0x9b},
-{0xb9, 0x9f},
-{0xba, 0xa6},
-{0xbb, 0xaa},
-{0xbc, 0x9b},
-{0xbd, 0x9f},
-{0xbe, 0xa6},
-{0xbf, 0xaa},
-
-{0xc4, 0x2c},
-{0xc5, 0x43},
-{0xc6, 0x63},
-{0xc7, 0x79},
-
-{0xc8, 0x2d},
-{0xc9, 0x42},
-{0xca, 0x2d},
-{0xcb, 0x42},
-{0xcc, 0x64},
-{0xcd, 0x78},
-{0xce, 0x64},
-{0xcf, 0x78},
-{0xd0, 0x0a},
-{0xd1, 0x09},
-{0xd4, 0x05},/*DCDC_TIME_TH_ON */
-{0xd5, 0x05},/*DCDC_TIME_TH_OFF */
-{0xd6, 0xb0},/*DCDC_AG_TH_ON */
-{0xd7, 0xa8},/*DCDC_AG_TH_OFF */
-{0xe0, 0xc4},
-{0xe1, 0xc4},
-{0xe2, 0xc4},
-{0xe3, 0xc4},
-{0xe4, 0x00},
-{0xe8, 0x80},
-{0xe9, 0x40},
-{0xea, 0x7f},
-
-{0xf0, 0x01},
-{0xf1, 0x01},
-{0xf2, 0x01},
-{0xf3, 0x01},
-{0xf4, 0x01},
-
-/* PAGE 2 END */
-
-/* PAGE 3 */
-{0x03, 0x03},
-{0x10, 0x10},
-/* PAGE 3 END */
-
-/* PAGE 10 START */
-{0x03, 0x10},
-{0x10, 0x01},/* CrYCbY */
-{0x12, 0x30},
-{0x20, 0x00},
-{0x30, 0x00},
-{0x31, 0x00},
-{0x32, 0x00},
-{0x33, 0x00},
-
-{0x34, 0x30},
-{0x35, 0x00},
-{0x36, 0x00},
-{0x38, 0x00},
-{0x3e, 0x58},
-{0x3f, 0x00},/*Setting For Camcorder 24 */
-
-{0x40, 0x80},
-{0x41, 0x00},
-
-{0x60, 0x67},/*Setting For Camcorder 24 */
-{0x61, 0x7a},/*77 */
-{0x62, 0x79},/*77 */
-{0x63, 0x50},/* Double_AG 50->30 */
-{0x64, 0x80},
-
-{0x66, 0x42},
-{0x67, 0x20},
-
-{0x6a, 0x80},/*8a */
-{0x6b, 0x84},/*74 */
-{0x6c, 0x7a},/*7e */
-{0x6d, 0x80},/*8e */
-
-/* PAGE 11 START */
-{0x03, 0x11},
-{0x10, 0x7f},
-{0x11, 0x40},
-{0x12, 0x0a},/* Blue Max-Filter Delete */
-{0x13, 0xbb},
-
-{0x26, 0x31},/* Double_AG 31->20 */
-{0x27, 0x34},/* Double_AG 34->22 */
-{0x28, 0x0f},
-{0x29, 0x10},
-{0x2b, 0x30},
-{0x2c, 0x32},
-
-/*Out2 D-LPF th*/
-{0x30, 0x70},
-{0x31, 0x10},
-{0x32, 0x58},
-{0x33, 0x09},
-{0x34, 0x06},
-{0x35, 0x03},
-
-/*Out1 D-LPF th*/
-{0x36, 0x70},
-{0x37, 0x18},
-{0x38, 0x58},
-{0x39, 0x20},
-{0x3a, 0x1f},
-{0x3b, 0x03},
-
-/*Indoor D-LPF th*/
-{0x3c, 0x80},
-{0x3d, 0x18},
-{0x3e, 0x80},
-{0x3f, 0x0c},
-{0x40, 0x09},
-{0x41, 0x06},
-
-/*Dark1 D-LPF th*/
-{0x42, 0x80},
-{0x43, 0x18},
-{0x44, 0x80},
-{0x45, 0x0c},
-{0x46, 0x09},
-{0x47, 0x06},
-
-/*Dark2 D-LPF th*/
-{0x48, 0x80},
-{0x49, 0x18},
-{0x4a, 0x80},
-{0x4b, 0x0c},
-{0x4c, 0x09},
-{0x4d, 0x06},
-
-/*Dark3 D-LPF th*/
-{0x4e, 0x80},
-{0x4f, 0x18},
-{0x50, 0x80},
-{0x51, 0x0c},
-{0x52, 0x09},
-{0x53, 0x06},
-
-{0x54, 0x11},
-{0x55, 0x17},
-{0x56, 0x20},
-{0x57, 0x01},
-{0x58, 0x00},
-{0x59, 0x00},
-
-{0x5a, 0x18},
-{0x5b, 0x00},
-{0x5c, 0x00},
-
-{0x60, 0x3f},
-{0x62, 0x60},
-{0x70, 0x06},
-/* PAGE 11 END */
-
-/* PAGE 12 START */
-{0x03, 0x12},
-{0x20, 0x0f},/*Setting For Camcorder 24 */
-{0x21, 0x0f},/*Setting For Camcorder 24 */
-
-{0x25, 0x00},/*0x30 */
-
-{0x28, 0x00},
-{0x29, 0x00},
-{0x2a, 0x00},
-
-{0x30, 0x50},
-{0x31, 0x18},
-{0x32, 0x32},
-{0x33, 0x40},
-{0x34, 0x50},
-{0x35, 0x70},
-{0x36, 0xa0},
-
-/*Out2 th*/
-{0x40, 0xa0},
-{0x41, 0x40},
-{0x42, 0xa0},
-{0x43, 0x90},
-{0x44, 0x90},
-{0x45, 0x80},
-
-/*Out1 th*/
-{0x46, 0xb0},
-{0x47, 0x55},
-{0x48, 0xb0},
-{0x49, 0xb0},
-{0x4a, 0x90},
-{0x4b, 0x80},
-
-/*Indoor th*/
-{0x4c, 0xb0},
-{0x4d, 0x40},
-{0x4e, 0x90},
-{0x4f, 0x90},
-{0x50, 0xa0},
-{0x51, 0x80},
-
-/*Dark1 th*/
-{0x52, 0xb0},
-{0x53, 0x40},
-{0x54, 0x90},
-{0x55, 0x90},
-{0x56, 0xa0},
-{0x57, 0x78},
-
-/*Dark2 th*/
-{0x58, 0xb0},
-{0x59, 0x40},
-{0x5a, 0x90},
-{0x5b, 0x90},
-{0x5c, 0xa0},
-{0x5d, 0x78},
-
-/*Dark3 th*/
-{0x5e, 0xb0},
-{0x5f, 0x40},
-{0x60, 0x90},
-{0x61, 0x90},
-{0x62, 0xa0},
-{0x63, 0x78},
-
-{0x70, 0x15},
-{0x71, 0x01},/*Don't Touch register */
-
-{0x72, 0x18},
-{0x73, 0x01},/*Don't Touch register */
-
-{0x74, 0x25},
-{0x75, 0x15},
-
-{0x80, 0x20},
-{0x81, 0x40},
-{0x82, 0x65},
-{0x85, 0x1a},
-{0x88, 0x00},
-{0x89, 0x00},
-{0x90, 0x5d},/*Setting For Camcorder 24 */
-
-/*Dont Touch register*/
-{0xD0, 0x0c},
-{0xD1, 0x80},
-{0xD2, 0x67},
-{0xD3, 0x00},
-{0xD4, 0x00},
-{0xD5, 0x02},
-{0xD6, 0xff},
-{0xD7, 0x18},
-/*End*/
-{0x3b, 0x06},
-{0x3c, 0x06},
-
-/*Dont Touch register*/
-{0xc5, 0x30},/*55->48 */
-{0xc6, 0x2a},/*48->40 */
-/* PAGE 12 END */
-
-/* PAGE 13 START */
-{0x03, 0x13},
-/*Edge*/
-{0x10, 0xcb},
-{0x11, 0x7b},
-{0x12, 0x07},
-{0x14, 0x00},
-
-{0x20, 0x15},
-{0x21, 0x13},
-{0x22, 0x33},
-{0x23, 0x05},
-{0x24, 0x09},
-
-{0x25, 0x0a},
-
-{0x26, 0x18},
-{0x27, 0x30},
-{0x29, 0x12},
-{0x2a, 0x50},
-
-/*Low clip th*/
-{0x2b, 0x02},
-{0x2c, 0x02},
-{0x25, 0x06},
-{0x2d, 0x0c},
-{0x2e, 0x12},
-{0x2f, 0x12},
-
-/*Out2 Edge*/
-{0x50, 0x10},
-{0x51, 0x14},
-{0x52, 0x12},
-{0x53, 0x0c},
-{0x54, 0x0f},
-{0x55, 0x0c},
-
-/*Out1 Edge*/
-{0x56, 0x0f},
-{0x57, 0x12},
-{0x58, 0x12},
-{0x59, 0x09},
-{0x5a, 0x0c},
-{0x5b, 0x0c},
-
-/*Indoor Edge*/
-{0x5c, 0x0a},
-{0x5d, 0x0b},
-{0x5e, 0x0a},
-{0x5f, 0x08},
-{0x60, 0x09},
-{0x61, 0x08},
-
-/*Dark1 Edge*/
-{0x62, 0x0a},
-{0x63, 0x0b},
-{0x64, 0x0a},
-{0x65, 0x08},
-{0x66, 0x09},
-{0x67, 0x08},
-
-/*Dark2 Edge*/
-{0x68, 0x0a},
-{0x69, 0x0b},
-{0x6a, 0x0a},
-{0x6b, 0x08},
-{0x6c, 0x09},
-{0x6d, 0x08},
-
-/*Dark3 Edge*/
-{0x6e, 0x0a},
-{0x6f, 0x0b},
-{0x70, 0x0a},
-{0x71, 0x08},
-{0x72, 0x09},
-{0x73, 0x08},
-
-/*2DY*/
-{0x80, 0xfd},/*Setting For Camcorder 24 */
-{0x81, 0x1f},
-{0x82, 0x05},
-{0x83, 0x31},
-
-{0x90, 0x05},
-{0x91, 0x05},
-{0x92, 0x33},
-{0x93, 0x30},
-{0x94, 0x03},
-{0x95, 0x14},
-{0x97, 0x20},
-{0x99, 0x20},
-
-{0xa0, 0x01},
-{0xa1, 0x02},
-{0xa2, 0x01},
-{0xa3, 0x02},
-{0xa4, 0x05},
-{0xa5, 0x05},
-{0xa6, 0x07},
-{0xa7, 0x08},
-{0xa8, 0x07},
-{0xa9, 0x08},
-{0xaa, 0x07},
-{0xab, 0x08},
-
-/*Out2*/
-{0xb0, 0x22},
-{0xb1, 0x2a},
-{0xb2, 0x28},
-{0xb3, 0x22},
-{0xb4, 0x2a},
-{0xb5, 0x28},
-
-/*Out1*/
-{0xb6, 0x22},
-{0xb7, 0x2a},
-{0xb8, 0x28},
-{0xb9, 0x22},
-{0xba, 0x2a},
-{0xbb, 0x28},
-
-/*Indoor*/
-{0xbc, 0x25},
-{0xbd, 0x2a},
-{0xbe, 0x27},
-{0xbf, 0x25},
-{0xc0, 0x2a},
-{0xc1, 0x27},
-
-/*Dark1*/
-{0xc2, 0x1e},
-{0xc3, 0x24},
-{0xc4, 0x20},
-{0xc5, 0x1e},
-{0xc6, 0x24},
-{0xc7, 0x20},
-
-/*Dark2*/
-{0xc8, 0x18},
-{0xc9, 0x20},
-{0xca, 0x1e},
-{0xcb, 0x18},
-{0xcc, 0x20},
-{0xcd, 0x1e},
-
-/*Dark3*/
-{0xce, 0x18},
-{0xcf, 0x20},
-{0xd0, 0x1e},
-{0xd1, 0x18},
-{0xd2, 0x20},
-{0xd3, 0x1e},
-/* PAGE 13 END */
-
-/* PAGE 14 START */
-{0x03, 0x14},
-{0x10, 0x11},
-
-{0x14, 0x80},/* GX */
-{0x15, 0x80},/* GY */
-{0x16, 0x80},/* RX */
-{0x17, 0x80},/* RY */
-{0x18, 0x80},/* BX */
-{0x19, 0x80},/* BY */
-
-{0x20, 0x80}, /*X*/ {0x21, 0x80}, /*Y*/ {0x22, 0x80},
-{0x23, 0x80},
-{0x24, 0x80},
-
-{0x30, 0xc8},
-{0x31, 0x2b},
-{0x32, 0x00},
-{0x33, 0x00},
-{0x34, 0x90},
-
-{0x40, 0x37},
-{0x50, 0x26},/*2d */
-{0x60, 0x22},/*26 */
-{0x70, 0x26},/*2d */
-/* PAGE 14 END */
-
-/* PAGE 15 START */
-{0x03, 0x15},
-{0x10, 0x0f},
-
-/*Rstep H 16*/
-/*Rstep L 14*/
-{0x14, 0x46}, /*CMCOFSGH*/
-{0x15, 0x36}, /*CMCOFSGM*/
-{0x16, 0x26}, /*CMCOFSGL*/
-{0x17, 0x2f}, /*CMC SIGN */
-
-/*CMC*/
-{0x30, 0x8f},
-{0x31, 0x59},
-{0x32, 0x0a},
-{0x33, 0x15},
-{0x34, 0x5b},
-{0x35, 0x06},
-{0x36, 0x07},
-{0x37, 0x40},
-{0x38, 0x87},
-
-/*CMC OFS*/
-{0x40, 0x94},
-{0x41, 0x20},
-{0x42, 0x89},
-{0x43, 0x84},
-{0x44, 0x03},
-{0x45, 0x01},
-{0x46, 0x88},
-{0x47, 0x9c},
-{0x48, 0x28},
-
-/*CMC POFS*/
-{0x50, 0x02},
-{0x51, 0x82},
-{0x52, 0x00},
-{0x53, 0x07},
-{0x54, 0x11},
-{0x55, 0x98},
-{0x56, 0x00},
-{0x57, 0x0b},
-{0x58, 0x8b},
-
-{0x80, 0x00},
-{0x85, 0x80},
-{0x87, 0x02},
-{0x88, 0x00},
-{0x89, 0x00},
-{0x8a, 0x00},
-/* PAGE 15 END */
-
-/* PAGE 16 START */
-{0x03, 0x16},
-{0x10, 0x31},
-{0x18, 0x5e},/* Double_AG 5e->37 */
-{0x19, 0x5d},/* Double_AG 5e->36 */
-{0x1a, 0x0e},
-{0x1b, 0x01},
-{0x1c, 0xdc},
-{0x1d, 0xfe},
-
-/*GMA Default*/
-{0x30, 0x00},
-{0x31, 0x08},
-{0x32, 0x1c},
-{0x33, 0x32},
-{0x34, 0x54},
-{0x35, 0x70},
-{0x36, 0x87},
-{0x37, 0x9a},
-{0x38, 0xaa},
-{0x39, 0xb9},
-{0x3a, 0xc4},
-{0x3b, 0xcf},
-{0x3c, 0xd8},
-{0x3d, 0xe0},
-{0x3e, 0xe9},
-{0x3f, 0xf0},
-{0x40, 0xf7},
-{0x41, 0xfc},
-{0x42, 0xff},
-
-{0x50, 0x00},
-{0x51, 0x08},
-{0x52, 0x1e},
-{0x53, 0x36},
-{0x54, 0x5a},
-{0x55, 0x75},
-{0x56, 0x8d},
-{0x57, 0xa1},
-{0x58, 0xb2},
-{0x59, 0xbe},
-{0x5a, 0xc9},
-{0x5b, 0xd2},
-{0x5c, 0xdb},
-{0x5d, 0xe3},
-{0x5e, 0xeb},
-{0x5f, 0xf0},
-{0x60, 0xf5},
-{0x61, 0xf7},
-{0x62, 0xf8},
-
-{0x70, 0x00},
-{0x71, 0x08},
-{0x72, 0x1c},
-{0x73, 0x32},
-{0x74, 0x54},
-{0x75, 0x70},
-{0x76, 0x87},
-{0x77, 0x9a},
-{0x78, 0xaa},
-{0x79, 0xb9},
-{0x7a, 0xc4},
-{0x7b, 0xcf},
-{0x7c, 0xd8},
-{0x7d, 0xe0},
-{0x7e, 0xe9},
-{0x7f, 0xf0},
-{0x80, 0xf7},
-{0x81, 0xfc},
-{0x82, 0xff},
-/* PAGE 16 END */
-
-/* PAGE 17 START */
-{0x03, 0x17},
-{0x10, 0xf7},
-/* PAGE 17 END */
-
-/* PAGE 18 START */
-{0x03, 0x18},
-{0x10, 0x07},
-{0x11, 0x00},
-{0x12, 0x58},
-{0x20, 0x02},
-{0x21, 0x80},
-{0x22, 0x01},
-{0x23, 0xe0},
-{0x24, 0x00},
-{0x25, 0x03},
-{0x26, 0x00},
-{0x27, 0x04},
-{0x28, 0x02},
-{0x29, 0x83},
-{0x2a, 0x01},
-{0x2b, 0xe4},
-{0x2c, 0x0a},
-{0x2d, 0x00},
-{0x2e, 0x0a},
-{0x2f, 0x00},
-{0x30, 0x25},
-
-/* PAGE 18 END */
-
-/* PAGE 20 START */
-{0x03, 0x20},
-{0x11, 0x1c},
-{0x18, 0x30},
-{0x1a, 0x08},
-{0x20, 0x05},
-{0x21, 0x30},
-{0x22, 0x10},
-{0x23, 0x00},
-{0x24, 0x00},
-
-{0x28, 0xef},
-{0x29, 0x0d},/*20100305 ad->0d */
-{0x2a, 0x03},
-{0x2b, 0xf5},
-
-{0x2c, 0xc2},
-{0x2d, 0xff},
-{0x2e, 0x33},
-{0x30, 0xf8},
-{0x32, 0x03},
-{0x33, 0x2e},
-{0x34, 0x30},
-{0x35, 0xd4},
-{0x36, 0xfe},
-{0x37, 0x32},
-{0x38, 0x04},
-{0x39, 0x22},
-{0x3a, 0xde},
-{0x3b, 0x22},
-{0x3c, 0xde},
-
-{0x50, 0x45},
-{0x51, 0x88},
-
-{0x56, 0x03},
-{0x57, 0xf7},
-{0x58, 0x14},
-{0x59, 0x88},
-{0x5a, 0x04},
-
-{0x60, 0xaa},
-{0x61, 0xaa},
-{0x62, 0xaa},
-{0x63, 0xaa},
-{0x64, 0xaa},
-{0x65, 0xaa},
-{0x66, 0xab},
-{0x67, 0xEa},
-{0x68, 0xab},
-{0x69, 0xEa},
-{0x6a, 0xaa},
-{0x6b, 0xaa},
-{0x6c, 0xaa},
-{0x6d, 0xaa},
-{0x6e, 0xaa},
-{0x6f, 0xaa},
-
-{0x70, 0x7a},
-{0x71, 0x80},
-
-{0x76, 0x43},
-{0x77, 0x02},
-{0x78, 0x24},
-{0x79, 0x49},
-{0x7a, 0x23},
-{0x7b, 0x22},
-{0x7d, 0x23},
-
-{0x83, 0x01},/*EXP Normal 30.00 fps */
-{0x84, 0x86},
-{0x85, 0x78},
-
-{0x86, 0x01},/*EXPMin 10204.08 fps */
-{0x87, 0x26},
-
-{0x88, 0x01},/*EXP Max 24.00 fps */
-{0x89, 0xe8},
-{0x8a, 0x16},
-
-{0x8B, 0x75},/*EXP100 */
-{0x8C, 0x24},
-
-{0x8D, 0x61},/*EXP120 */
-{0x8E, 0x9e},
-
-{0x91, 0x01},/*EXP Fix 23.93 fps */
-{0x92, 0xe9},
-{0x93, 0xcf},
-
-{0x98, 0x9d},/*9d */
-{0x99, 0x45},
-{0x9a, 0x0d},
-{0x9b, 0xde},
-
-{0x9c, 0x0e},/*EXP Limit 784.93 fps */
-{0x9d, 0xee},
-
-{0x9e, 0x01},/*EXP Unit */
-{0x9f, 0x26},
-
-{0xb0, 0x18},
-{0xb1, 0x14},
-{0xb2, 0xb8},
-{0xb3, 0x18},
-{0xb4, 0x1a},
-{0xb5, 0x44},
-{0xb6, 0x2f},
-{0xb7, 0x28},
-{0xb8, 0x25},
-{0xb9, 0x22},
-{0xba, 0x21},
-{0xbb, 0x20},
-{0xbc, 0x32},
-{0xbd, 0x32},
-
-{0xc0, 0x10},
-{0xc1, 0x2b},
-{0xc2, 0x2b},
-{0xc3, 0x2b},
-{0xc4, 0x08},
-
-{0xc8, 0x80},
-{0xc9, 0x80},
-/* PAGE 20 END */
-
-/* PAGE 22 START */
-{0x03, 0x22},
-{0x10, 0xfd},
-{0x11, 0x2e},
-{0x19, 0x01},
-{0x20, 0x30},
-{0x21, 0x80},
-{0x24, 0x01},
-/*0x2500, 7f New Lock Cond & New light stable*/
-
-{0x30, 0x80},
-{0x31, 0x80},
-{0x38, 0x11},
-{0x39, 0x34},
-{0x40, 0xf3},
-
-{0x41, 0x32},/*33 */
-{0x42, 0x22},/*22 */
-{0x43, 0xf0},/*f6 */
-{0x44, 0x44},/*44 */
-{0x45, 0x44},/*33 */
-{0x46, 0x00},
-{0x50, 0xb2},
-{0x51, 0x81},
-{0x52, 0x98},
-
-{0x80, 0x38},
-{0x81, 0x20},
-{0x82, 0x36},/*3a */
-
-{0x83, 0x5e},/*5e */
-{0x84, 0x22},/* 24 21 22 Spec AWB H modify */
-{0x85, 0x4f},/* 54 51 4f Spec AWB H modify */
-{0x86, 0x20},/*24 */
-
-{0x87, 0x48},
-{0x88, 0x38},
-{0x89, 0x37},/*38 */
-{0x8a, 0x29},/*2a */
-
-{0x8b, 0x40},/* 47 */
-{0x8c, 0x38},
-{0x8d, 0x34},
-{0x8e, 0x29},/*2c */
-
-{0x8f, 0x5c},
-{0x90, 0x5b},
-{0x91, 0x57},
-{0x92, 0x4f},
-{0x93, 0x43},
-{0x94, 0x3e},
-{0x95, 0x34},
-{0x96, 0x2c},
-{0x97, 0x23},
-{0x98, 0x20},
-{0x99, 0x1f},
-{0x9a, 0x1f},
-
-{0x9b, 0x77},
-{0x9c, 0x66},
-{0x9d, 0x48},
-{0x9e, 0x38},
-{0x9f, 0x30},
-
-{0xa0, 0x60},
-{0xa1, 0x34},
-{0xa2, 0x6f},
-{0xa3, 0xff},
-
-{0xa4, 0x14},/*1500fps */
-{0xa5, 0x2c},/* 700fps */
-{0xa6, 0xcf},
-
-{0xad, 0x40},
-{0xae, 0x4a},
-
-{0xaf, 0x28},/* low temp Rgain */
-{0xb0, 0x26},/* low temp Rgain */
-
-{0xb1, 0x00},/*0x20 -> 0x00 0405 modify */
-{0xb4, 0xea},
-{0xb8, 0xa1},/* a2: b-2, R+2 b4 B-3, R+4 lowtemp b0 a1 Spec AWB A modify */
-{0xb9, 0x00},
-/* PAGE 22 END */
-
-/* PAGE 48 START*/
-{0x03, 0x48},
-
-/* PLL Setting */
-{0x70, 0x05},
-{0x71, 0x30},/*MiPi Pllx2 */
-{0x72, 0x81},
-{0x70, 0xa5},/* PLL Enable */
-{0x03, 0x48},
-{0x03, 0x48},
-{0x03, 0x48},
-{0x03, 0x48},
-{0x70, 0x95},/* CLK_GEN_ENABLE */
-
-/* MIPI TX Setting */
-{0x11, 0x00},/* 20111013 0x10 continuous -> 0x00 not Continuous */
-{0x10, 0x1c},
-{0x12, 0x00},
-{0x14, 0x30},/*0x1470, *//* 20111013 0x00 -> 0x30 Clock Delay */
-{0x16, 0x04},/* 1016 0x04->0x05 */
-
-{0x19, 0x00},
-{0x1a, 0x32},
-{0x1b, 0x17},
-{0x1c, 0x0c},
-{0x1d, 0x0f},
-{0x1e, 0x05},
-{0x1f, 0x05},
-{0x20, 0x00},
-
-{0x23, 0x01},
-{0x24, 0x1e},
-{0x25, 0x00},
-{0x26, 0x00},
-{0x27, 0x01},
-{0x28, 0x00},
-{0x2a, 0x06},
-{0x2b, 0x40},
-{0x2c, 0x04},
-{0x2d, 0xb0},
-
-{0x30, 0x00},/*640x480 MiPi OutPut */
-{0x31, 0x05},
-
-/*0x3040, 800x600 MiPi OutPut*/
-/*0x3106,*/
-
-{0x32, 0x06},
-{0x33, 0x0a},
-{0x34, 0x03},/*CLK LP -> HS Prepare time 24MHz:0x02, 48MHz:0x03 */
-{0x35, 0x03},
-{0x36, 0x01},
-{0x37, 0x07},
-{0x38, 0x02},
-{0x39, 0x03},/*drivability 24MHZ:02, 48MHz:03 */
-{0x50, 0x00},
-/* PAGE 48 END*/
-
-/* PAGE 20 */
-{0x03, 0x20},
-{0x10, 0x8c},/*AE on 60hz */
-
-/* PAGE 22 */
-{0x03, 0x22},
-{0x10, 0xe9},
-
-/* PAGE 0 */
-{0x03, 0x00},
-{0x11, 0x94},
-{0x03, 0x00},
-{0x03, 0x00},
-{0x03, 0x00},
-{0x03, 0x00},
-{0x03, 0x00},
-{0x03, 0x00},
-{0x03, 0x00},
-{0x03, 0x00},
-{0x03, 0x00},
-{0x03, 0x00},
-
-{0x03, 0x00},
-{0x01, 0xf8},
-{0xff, 0x28},/*NEED Delay 400ms */
-};
-
-/*============================================================*/
-/* CAMERA INITIAL for VT Preview 15 Fixed Frame (VGA SETTING) */
-/*============================================================*/
-regs_short_t front_init_vt_regs[] = {
-/* SKT-VT - continuous */
-{0x01, 0xf9},/* sleep on */
-{0x01, 0xfb},/* sleep on */
-{0x01, 0xf9},/* sleep on */
-{0x08, 0x20},/* sleep on */
-{0x0a, 0x3f},/* sleep on */
-
-/* PAGE 20 */
-{0x03, 0x20},/* page 20 */
-{0x10, 0x0c},/* AE off 60hz */
-
-/* PAGE 22 */
-{0x03, 0x22},/* page 22 */
-{0x10, 0x69},/* AWB off */
-
-{0x03, 0x12},
-{0x20, 0x00},
-{0x21, 0x00},
-
-{0x03, 0x13},
-{0x10, 0xcb},
-
-/* Initial Start */
-/* PAGE 0 START */
-{0x03, 0x00},
-{0x10, 0x10},/* Vsync Active High B:[3] , Sub1/2mode */
-{0x11, 0x94},
-{0x12, 0x04},/* Pclk Falling Edge B:[2] */
-
-{0x0b, 0xaa},/* ESD Check Register */
-{0x0c, 0xaa},/* ESD Check Register */
-{0x0d, 0xaa},/* ESD Check Register */
-
-{0x20, 0x00},
-{0x21, 0x0a},/* modify 20110929 0x04->0x02 */
-{0x22, 0x00},
-{0x23, 0x0a},/* modify 20110929 0x14->0x0a */
-
-{0x24, 0x04},
-{0x25, 0xb0},
-{0x26, 0x06},
-{0x27, 0x40},
-
-{0x28, 0x0c},
-{0x29, 0x04},
-{0x2a, 0x02},
-{0x2b, 0x04},
-{0x2c, 0x06},
-{0x2d, 0x02},
-
-{0x40, 0x01},/* Hblank_360 */
-{0x41, 0x68},
-{0x42, 0x00},
-{0x43, 0x44},/* Flick Stop 60hz */
-{0x44, 0x09},/* VSCLIP */
-
-{0x45, 0x04},
-{0x46, 0x18},
-{0x47, 0xd8},
-
- /*BLC*/ {0x80, 0x2e},
-{0x81, 0x7e},
-{0x82, 0x90},
-{0x83, 0x00},
-{0x84, 0x0c},
-{0x85, 0x00},
-{0x90, 0x0e},/* BLC_TIME_TH_ON */
-{0x91, 0x0e},/* BLC_TIME_TH_OFF */
-{0x92, 0xd8},/* BLC_AG_TH_ON */
-{0x93, 0xd0},/* BLC_AG_TH_OFF */
-{0x94, 0xff},
-{0x95, 0xff},
-{0x96, 0xdc},
-{0x97, 0xfe},
-{0x98, 0x38},
-
-/*Dark BLC*/
-{0xa0, 0x00},
-{0xa2, 0x00},
-{0xa4, 0x00},
-{0xa6, 0x00},
-
-/*Normal BLC*/
-{0xa8, 0x43},
-{0xaa, 0x43},
-{0xac, 0x43},
-{0xae, 0x43},
-
-/*OutDoor BLC*/
-{0x99, 0x43},
-{0x9a, 0x43},
-{0x9b, 0x43},
-{0x9c, 0x43},
-/* PAGE 0 END */
-
-/* PAGE 2 START */
-{0x03, 0x02},
-{0x12, 0x03},
-{0x13, 0x03},
-{0x16, 0x00},
-{0x17, 0x8C},
-{0x18, 0x4c},/* Double_AG */
-{0x19, 0x00},
-{0x1a, 0x39},/* Double_AG 38 ->39 */
-{0x1c, 0x09},
-{0x1d, 0x40},
-{0x1e, 0x30},
-{0x1f, 0x10},
-
-{0x20, 0x77},
-{0x21, 0xde},
-{0x22, 0xa7},
-{0x23, 0x30},/* CLAMP */
-{0x27, 0x3c},
-{0x2b, 0x80},
-{0x2e, 0x00},
-{0x2f, 0x00},
-{0x30, 0x05},/* For Hi-253 never no change 0x05 */
-
-{0x50, 0x20},
-{0x51, 0x03},/* 20110826 Ãß°¡ */
-{0x52, 0x01},/* 0x03 --> 0x01 */
-{0x53, 0xc1},/* 20110818 Ãß°¡ */
-{0x55, 0x1c},
-{0x56, 0x11},
-{0x5d, 0xa2},
-{0x5e, 0x5a},
-
-{0x60, 0x87},
-{0x61, 0x99},
-{0x62, 0x88},
-{0x63, 0x97},
-{0x64, 0x88},
-{0x65, 0x97},
-
-{0x67, 0x0c},
-{0x68, 0x0c},
-{0x69, 0x0c},
-
-{0x72, 0x89},
-{0x73, 0x96},
-{0x74, 0x89},
-{0x75, 0x96},
-{0x76, 0x89},
-{0x77, 0x96},
-
-{0x7c, 0x85},
-{0x7d, 0xaf},
-{0x80, 0x01},
-{0x81, 0x7f},
-{0x82, 0x13},
-{0x83, 0x24},
-{0x84, 0x7d},
-{0x85, 0x81},
-{0x86, 0x7d},
-{0x87, 0x81},
-
-{0x92, 0x48},
-{0x93, 0x54},
-{0x94, 0x7d},
-{0x95, 0x81},
-{0x96, 0x7d},
-{0x97, 0x81},
-
-{0xa0, 0x02},
-{0xa1, 0x7b},
-{0xa2, 0x02},
-{0xa3, 0x7b},
-{0xa4, 0x7b},
-{0xa5, 0x02},
-{0xa6, 0x7b},
-{0xa7, 0x02},
-
-{0xa8, 0x85},
-{0xa9, 0x8c},
-{0xaa, 0x85},
-{0xab, 0x8c},
-{0xac, 0x10},
-{0xad, 0x16},
-{0xae, 0x10},
-{0xaf, 0x16},
-
-{0xb0, 0x99},
-{0xb1, 0xa3},
-{0xb2, 0xa4},
-{0xb3, 0xae},
-{0xb4, 0x9b},
-{0xb5, 0xa2},
-{0xb6, 0xa6},
-{0xb7, 0xac},
-{0xb8, 0x9b},
-{0xb9, 0x9f},
-{0xba, 0xa6},
-{0xbb, 0xaa},
-{0xbc, 0x9b},
-{0xbd, 0x9f},
-{0xbe, 0xa6},
-{0xbf, 0xaa},
-
-{0xc4, 0x2c},
-{0xc5, 0x43},
-{0xc6, 0x63},
-{0xc7, 0x79},
-
-{0xc8, 0x2d},
-{0xc9, 0x42},
-{0xca, 0x2d},
-{0xcb, 0x42},
-{0xcc, 0x64},
-{0xcd, 0x78},
-{0xce, 0x64},
-{0xcf, 0x78},
-{0xd0, 0x0a},
-{0xd1, 0x09},
-{0xd4, 0x0e},/* DCDC_TIME_TH_ON */
-{0xd5, 0x0e},/* DCDC_TIME_TH_OFF */
-{0xd6, 0xd8},/* DCDC_AG_TH_ON */
-{0xd7, 0xd0},/* DCDC_AG_TH_OFF */
-{0xe0, 0xc4},
-{0xe1, 0xc4},
-{0xe2, 0xc4},
-{0xe3, 0xc4},
-{0xe4, 0x00},
-{0xe8, 0x80},
-{0xe9, 0x40},
-{0xea, 0x7f},
-
-{0xf0, 0x01},
-{0xf1, 0x01},
-{0xf2, 0x01},
-{0xf3, 0x01},
-{0xf4, 0x01},
-
-/* PAGE 2 END */
-
-/* PAGE 3 */
-{0x03, 0x03},
-{0x10, 0x10},
-/* PAGE 3 END */
-
-/* PAGE 10 START */
-{0x03, 0x10},
-{0x10, 0x01},/* CrYCbY */
-{0x12, 0x30},
-{0x20, 0x00},
-{0x30, 0x00},
-{0x31, 0x00},
-{0x32, 0x00},
-{0x33, 0x00},
-
-{0x34, 0x30},
-{0x35, 0x00},
-{0x36, 0x00},
-{0x38, 0x00},
-{0x3e, 0x58},
-{0x3f, 0x02},/* For Preview */
-
-{0x40, 0x80},
-{0x41, 0x2c},
-
-{0x60, 0x6b},
-{0x61, 0x7a},/* 77 */
-{0x62, 0x72},/* 77 */
-{0x63, 0x50},/* Double_AG 50->30 */
-{0x64, 0x80},
-
-{0x66, 0x42},
-{0x67, 0x20},
-
-{0x6a, 0x80},/* 8a */
-{0x6b, 0x84},/* 74 */
-{0x6c, 0x7a},/* 7e */
-{0x6d, 0x80},/* 8e */
-
-/* PAGE 11 START */
-{0x03, 0x11},
-{0x10, 0x7f},
-{0x11, 0x40},
-{0x12, 0x0a},/* Blue Max-Filter Delete */
-{0x13, 0xbb},
-
-{0x26, 0x31},/* Double_AG 31->20 */
-{0x27, 0x34},/* Double_AG 34->22 */
-{0x28, 0x0f},
-{0x29, 0x10},
-{0x2b, 0x30},
-{0x2c, 0x32},
-
-/*Out2 D-LPF th*/
-{0x30, 0x70},
-{0x31, 0x10},
-{0x32, 0x58},
-{0x33, 0x09},
-{0x34, 0x06},
-{0x35, 0x03},
-
-/*Out1 D-LPF th*/
-{0x36, 0x70},
-{0x37, 0x18},
-{0x38, 0x58},
-{0x39, 0x20},
-{0x3a, 0x1f},
-{0x3b, 0x03},
-
-/*Indoor D-LPF th*/
-{0x3c, 0x80},
-{0x3d, 0x18},
-{0x3e, 0x80},
-{0x3f, 0x0c},
-{0x40, 0x09},
-{0x41, 0x06},
-
-/*Dark1 D-LPF th*/
-{0x42, 0x80},
-{0x43, 0x18},
-{0x44, 0x80},
-{0x45, 0x0f},
-{0x46, 0x0c},
-{0x47, 0x0b},
-
-/*Dark2 D-LPF th*/
-{0x48, 0x88},
-{0x49, 0x2c},
-{0x4a, 0x80},
-{0x4b, 0x0f},
-{0x4c, 0x0c},
-{0x4d, 0x0b},
-
-/*Dark3 D-LPF th*/
-{0x4e, 0x80},
-{0x4f, 0x23},
-{0x50, 0x80},
-{0x51, 0x0f},
-{0x52, 0x0c},
-{0x53, 0x0c},
-
-{0x54, 0x11},
-{0x55, 0x17},
-{0x56, 0x20},
-{0x57, 0x01},
-{0x58, 0x00},
-{0x59, 0x00},
-
-{0x5a, 0x18},
-{0x5b, 0x00},
-{0x5c, 0x00},
-
-{0x60, 0x3f},
-{0x62, 0x60},
-{0x70, 0x06},
-/* PAGE 11 END */
-
-/* PAGE 12 START */
-{0x03, 0x12},
-{0x20, 0x0f},
-{0x21, 0x0f},
-
-{0x25, 0x00},/* 0x30 */
-
-{0x28, 0x00},
-{0x29, 0x00},
-{0x2a, 0x00},
-
-{0x30, 0x50},
-{0x31, 0x18},
-{0x32, 0x32},
-{0x33, 0x40},
-{0x34, 0x50},
-{0x35, 0x70},
-{0x36, 0xa0},
-
-/*Out2 th*/
-{0x40, 0xa0},
-{0x41, 0x40},
-{0x42, 0xa0},
-{0x43, 0x90},
-{0x44, 0x90},
-{0x45, 0x80},
-
-/*Out1 th*/
-{0x46, 0xb0},
-{0x47, 0x55},
-{0x48, 0xb0},
-{0x49, 0xb0},
-{0x4a, 0x90},
-{0x4b, 0x80},
-
-/*Indoor th*/
-{0x4c, 0xb0},
-{0x4d, 0x40},
-{0x4e, 0x90},
-{0x4f, 0x90},
-{0x50, 0xa0},
-{0x51, 0x80},
-
-/*Dark1 th*/
-{0x52, 0xb0},
-{0x53, 0x50},
-{0x54, 0xa8},
-{0x55, 0xa8},
-{0x56, 0xb0},
-{0x57, 0x7b},
-
-/*Dark2 th*/
-{0x58, 0xa0},
-{0x59, 0x40},
-{0x5a, 0xb8},
-{0x5b, 0xb8},
-{0x5c, 0xc8},
-{0x5d, 0x7b},
-
-/*Dark3 th*/
-{0x5e, 0x9c},
-{0x5f, 0x40},
-{0x60, 0xc0},
-{0x61, 0xc0},
-{0x62, 0xc8},
-{0x63, 0x7b},
-
-{0x70, 0x15},
-{0x71, 0x01},/* Don't Touch register */
-
-{0x72, 0x18},
-{0x73, 0x01},/* Don't Touch register */
-
-{0x74, 0x25},
-{0x75, 0x15},
-
-{0x80, 0x20},
-{0x81, 0x40},
-{0x82, 0x65},
-{0x85, 0x1a},
-{0x88, 0x00},
-{0x89, 0x00},
-{0x90, 0x5d},/* For SK VT */
-
-/*Dont Touch register*/
-{0xD0, 0x0c},
-{0xD1, 0x80},
-
-/*only For SK VT */
-{0xD2, 0x67},
-
-{0xD3, 0x00},
-{0xD4, 0x00},
-
-/*only For SK VT */
-{0xd5, 0x02},
-
-{0xD6, 0xff},
-
-/*only For SK VT */
-{0xd7, 0x18},
-
-/*End*/
-{0x3b, 0x06},
-{0x3c, 0x06},
-
-/*Dont Touch register*/
-{0xc5, 0x30},/* 55->48 */
-{0xc6, 0x2a},/* 48->40 */
-/* PAGE 12 END */
-
-/* PAGE 13 START */
-{0x03, 0x13},
-/*Edge*/
-{0x10, 0xcb},
-{0x11, 0x7b},
-{0x12, 0x07},
-{0x14, 0x00},
-
-{0x20, 0x15},
-{0x21, 0x13},
-{0x22, 0x33},
-{0x23, 0x05},
-{0x24, 0x09},
-
-{0x25, 0x0a},
-
-{0x26, 0x18},
-{0x27, 0x30},
-{0x29, 0x12},
-{0x2a, 0x50},
-
-/*Low clip th*/
-{0x2b, 0x02},
-{0x2c, 0x02},
-{0x25, 0x06},
-{0x2d, 0x0c},
-{0x2e, 0x12},
-{0x2f, 0x12},
-
-/*Out2 Edge*/
-{0x50, 0x10},
-{0x51, 0x14},
-{0x52, 0x12},
-{0x53, 0x0c},
-{0x54, 0x0f},
-{0x55, 0x0c},
-
-/*Out1 Edge*/
-{0x56, 0x0f},
-{0x57, 0x12},
-{0x58, 0x12},
-{0x59, 0x09},
-{0x5a, 0x0c},
-{0x5b, 0x0c},
-
-/*Indoor Edge*/
-{0x5c, 0x0a},
-{0x5d, 0x0b},
-{0x5e, 0x0a},
-{0x5f, 0x08},
-{0x60, 0x09},
-{0x61, 0x08},
-
-/*Dark1 Edge*/
-{0x62, 0x09},
-{0x63, 0x09},
-{0x64, 0x09},
-{0x65, 0x07},
-{0x66, 0x07},
-{0x67, 0x07},
-
-/*Dark2 Edge*/
-{0x68, 0x08},
-{0x69, 0x08},
-{0x6a, 0x08},
-{0x6b, 0x06},
-{0x6c, 0x06},
-{0x6d, 0x06},
-
-/*Dark3 Edge*/
-{0x6e, 0x08},
-{0x6f, 0x08},
-{0x70, 0x08},
-{0x71, 0x06},
-{0x72, 0x06},
-{0x73, 0x06},
-
-/*2DY*/
-{0x80, 0xfd},/*only For SK VT */
-{0x81, 0x1f},
-{0x82, 0x05},
-{0x83, 0x31},
-
-{0x90, 0x05},
-{0x91, 0x05},
-{0x92, 0x33},
-{0x93, 0x30},
-{0x94, 0x03},
-{0x95, 0x14},
-{0x97, 0x20},
-{0x99, 0x20},
-
-{0xa0, 0x01},
-{0xa1, 0x02},
-{0xa2, 0x01},
-{0xa3, 0x02},
-{0xa4, 0x05},
-{0xa5, 0x05},
-{0xa6, 0x07},
-{0xa7, 0x08},
-{0xa8, 0x07},
-{0xa9, 0x08},
-{0xaa, 0x07},
-{0xab, 0x08},
-
-/*Out2*/
-{0xb0, 0x22},
-{0xb1, 0x2a},
-{0xb2, 0x28},
-{0xb3, 0x22},
-{0xb4, 0x2a},
-{0xb5, 0x28},
-
-/*Out1*/
-{0xb6, 0x22},
-{0xb7, 0x2a},
-{0xb8, 0x28},
-{0xb9, 0x22},
-{0xba, 0x2a},
-{0xbb, 0x28},
-
-/*Indoor*/
-{0xbc, 0x25},
-{0xbd, 0x2a},
-{0xbe, 0x27},
-{0xbf, 0x25},
-{0xc0, 0x2a},
-{0xc1, 0x27},
-
-/*Dark1*/
-{0xc2, 0x1e},
-{0xc3, 0x24},
-{0xc4, 0x20},
-{0xc5, 0x1e},
-{0xc6, 0x24},
-{0xc7, 0x20},
-
-/*Dark2*/
-{0xc8, 0x18},
-{0xc9, 0x20},
-{0xca, 0x1e},
-{0xcb, 0x18},
-{0xcc, 0x20},
-{0xcd, 0x1e},
-
-/*Dark3*/
-{0xce, 0x18},
-{0xcf, 0x20},
-{0xd0, 0x1e},
-{0xd1, 0x18},
-{0xd2, 0x20},
-{0xd3, 0x1e},
-/* PAGE 13 END */
-
-/* PAGE 14 START */
-{0x03, 0x14},
-{0x10, 0x11},
-
-{0x14, 0x80},/* GX */
-{0x15, 0x80},/* GY */
-{0x16, 0x80},/* RX */
-{0x17, 0x80},/* RY */
-{0x18, 0x80},/* BX */
-{0x19, 0x80},/* BY */
-
-{0x20, 0x80},/* X */
-{0x21, 0x80},/* Y */
-
-{0x22, 0x80},
-{0x23, 0x80},
-{0x24, 0x80},
-
-{0x30, 0xc8},
-{0x31, 0x2b},
-{0x32, 0x00},
-{0x33, 0x00},
-{0x34, 0x90},
-
-{0x40, 0x37},
-{0x50, 0x26},/* 2d */
-{0x60, 0x22},/* 26 */
-{0x70, 0x26},/* 2d */
-/* PAGE 14 END */
-
-/* PAGE 15 START */
-{0x03, 0x15},
-{0x10, 0x0f},
-
-/*Rstep H 16*/
-/*Rstep L 14*/
-{0x14, 0x46},/* CMCOFSGH */
-{0x15, 0x36},/* CMCOFSGM */
-{0x16, 0x26},/* CMCOFSGL */
-{0x17, 0x2f},/* CMC SIGN */
-
- /*CMC*/ {0x30, 0x8f},
-{0x31, 0x59},
-{0x32, 0x0a},
-{0x33, 0x15},
-{0x34, 0x5b},
-{0x35, 0x06},
-{0x36, 0x07},
-{0x37, 0x40},
-{0x38, 0x87},
-
-/*CMC OFS*/
-{0x40, 0x94},
-{0x41, 0x20},
-{0x42, 0x89},
-{0x43, 0x84},
-{0x44, 0x03},
-{0x45, 0x01},
-{0x46, 0x88},
-{0x47, 0x9c},
-{0x48, 0x28},
-
-/*CMC POFS*/
-{0x50, 0x02},
-{0x51, 0x82},
-{0x52, 0x00},
-{0x53, 0x07},
-{0x54, 0x11},
-{0x55, 0x98},
-{0x56, 0x00},
-{0x57, 0x0b},
-{0x58, 0x8b},
-
-{0x80, 0x00},
-{0x85, 0x80},
-{0x87, 0x02},
-{0x88, 0x00},
-{0x89, 0x00},
-{0x8a, 0x00},
-/* PAGE 15 END */
-
-/* PAGE 16 START */
-{0x03, 0x16},
-{0x10, 0x31},
-{0x18, 0x5e},/* Double_AG 5e->37 */
-{0x19, 0x5d},/* Double_AG 5e->36 */
-{0x1a, 0x0e},
-{0x1b, 0x01},
-{0x1c, 0xdc},
-{0x1d, 0xfe},
-
-/*GMA Default*/
-{0x30, 0x00},
-{0x31, 0x08},
-{0x32, 0x1c},
-{0x33, 0x32},
-{0x34, 0x54},
-{0x35, 0x70},
-{0x36, 0x87},
-{0x37, 0x9a},
-{0x38, 0xaa},
-{0x39, 0xb9},
-{0x3a, 0xc4},
-{0x3b, 0xcf},
-{0x3c, 0xd8},
-{0x3d, 0xe0},
-{0x3e, 0xe9},
-{0x3f, 0xf0},
-{0x40, 0xf7},
-{0x41, 0xfc},
-{0x42, 0xff},
-
-{0x50, 0x00},
-{0x51, 0x08},
-{0x52, 0x1e},
-{0x53, 0x36},
-{0x54, 0x5a},
-{0x55, 0x75},
-{0x56, 0x8d},
-{0x57, 0xa1},
-{0x58, 0xb2},
-{0x59, 0xbe},
-{0x5a, 0xc9},
-{0x5b, 0xd2},
-{0x5c, 0xdb},
-{0x5d, 0xe3},
-{0x5e, 0xeb},
-{0x5f, 0xf0},
-{0x60, 0xf5},
-{0x61, 0xf7},
-{0x62, 0xf8},
-
-{0x70, 0x00},
-{0x71, 0x0b},
-{0x72, 0x1a},
-{0x73, 0x37},
-{0x74, 0x58},
-{0x75, 0x70},
-{0x76, 0x86},
-{0x77, 0x99},
-{0x78, 0xa9},
-{0x79, 0xb7},
-{0x7a, 0xc3},
-{0x7b, 0xcf},
-{0x7c, 0xd9},
-{0x7d, 0xe1},
-{0x7e, 0xe8},
-{0x7f, 0xef},
-{0x80, 0xf4},
-{0x81, 0xfa},
-{0x82, 0xff},
-/* PAGE 16 END */
-
-/* PAGE 17 START */
-{0x03, 0x17},
-{0x10, 0xf7},
-/* PAGE 17 END */
-
-/* PAGE 18 START */
-{0x03, 0x18},
-{0x10, 0x07},
-{0x11, 0x00},
-{0x12, 0x98},
-{0x20, 0x05},
-{0x21, 0x00},
-{0x22, 0x03},
-{0x23, 0xc0},
-{0x24, 0x00},
-{0x25, 0x04},
-{0x26, 0x00},
-{0x27, 0x08},
-{0x28, 0x05},
-{0x29, 0x04},
-{0x2a, 0x03},
-{0x2b, 0xc8},
-{0x2c, 0x0a},
-{0x2d, 0x00},
-{0x2e, 0x0a},
-{0x2f, 0x00},
-{0x30, 0x46},
-/* PAGE 18 END */
-
-/* PAGE 20 START */
-{0x03, 0x20},
-{0x11, 0x1c},
-{0x18, 0x30},
-{0x1a, 0x08},
-{0x20, 0x05},
-{0x21, 0x30},
-{0x22, 0x10},
-{0x23, 0x00},
-{0x24, 0x04},
-
-{0x28, 0xef},
-{0x29, 0x0d},/* 20100305 ad->0d */
-{0x2a, 0x03},
-{0x2b, 0xf5},
-
-{0x2c, 0xc2},
-{0x2d, 0xff},
-{0x2e, 0x33},
-{0x30, 0xf8},
-{0x32, 0x03},
-{0x33, 0x2e},
-{0x34, 0x30},
-{0x35, 0xd4},
-{0x36, 0xfe},
-{0x37, 0x32},
-{0x38, 0x04},
-{0x39, 0x22},
-{0x3a, 0xde},
-{0x3b, 0x22},
-{0x3c, 0xde},
-
-{0x50, 0x45},
-{0x51, 0x88},
-
-{0x56, 0x03},
-{0x57, 0xf7},
-{0x58, 0x14},
-{0x59, 0x88},
-{0x5a, 0x04},
-
-{0x60, 0xaa},
-{0x61, 0xaa},
-{0x62, 0xaa},
-{0x63, 0xaa},
-{0x64, 0xaa},
-{0x65, 0xaa},
-{0x66, 0xab},
-{0x67, 0xEa},
-{0x68, 0xab},
-{0x69, 0xEa},
-{0x6a, 0xaa},
-{0x6b, 0xaa},
-{0x6c, 0xaa},
-{0x6d, 0xaa},
-{0x6e, 0xaa},
-{0x6f, 0xaa},
-
-{0x70, 0x70},/* 6c */
-{0x71, 0x82},/* 82(+8) */
-
-{0x76, 0x43},
-{0x77, 0x02},
-{0x78, 0x24},/* 24 */
-{0x79, 0x48},/* Y Target 70 => 25, 72 => 26 */
-{0x7a, 0x23},/* 23 */
-{0x7b, 0x22},/* 22 */
-{0x7d, 0x23},
-
-{0x83, 0x01},/* EXP Normal 30.00 fps */
-{0x84, 0x86},
-{0x85, 0xa0},
-
-{0x86, 0x01},/* EXPMin 6000.00 fps */
-{0x87, 0xf4},
-
-{0x88, 0x05},/* EXP Max 8.57 fps */
-{0x89, 0x57},
-{0x8a, 0x30},
-
-{0x8B, 0x75},/* EXP100, PLLx2 Mclk24 */
-{0x8C, 0x30},
-
-{0x8D, 0x61},/* EXP120, PLLx2 Mclk24 */
-{0x8E, 0xa8},
-
-{0x91, 0x05},/* EXP Fix 8.00 fps */
-{0x92, 0xb8},
-{0x93, 0xd8},
-
-{0x98, 0x9d},
-{0x99, 0x45},
-{0x9a, 0x0d},
-{0x9b, 0xde},
-
-{0x9c, 0x17},/* EXP Limit 500.00 fps, PLLx2 Mclk24 */
-{0x9d, 0x70},
-
-{0x9e, 0x01},/* EXP Unit, PLLx2 Mclk24 */
-{0x9f, 0xf4},
-
-{0xb0, 0x18},
-{0xb1, 0x14},
-{0xb2, 0xe0},
-{0xb3, 0x18},
-{0xb4, 0x1a},
-{0xb5, 0x44},
-{0xb6, 0x2f},
-{0xb7, 0x28},
-{0xb8, 0x25},
-{0xb9, 0x22},
-{0xba, 0x21},
-{0xbb, 0x20},
-{0xbc, 0x32},
-{0xbd, 0x32},
-
-{0xc0, 0x10},
-{0xc1, 0x2b},
-{0xc2, 0x2b},
-{0xc3, 0x2b},
-{0xc4, 0x08},
-
-{0xc8, 0x80},
-{0xc9, 0x80},
-/* PAGE 20 END */
-
-/* PAGE 22 START */
-{0x03, 0x22},
-{0x10, 0xfd},
-{0x11, 0x2e},
-{0x19, 0x01},/* Low On */
-{0x20, 0x10},
-{0x21, 0x80},
-{0x24, 0x01},
-/*0x2500, 7f New Lock Cond & New light stable */
-
-{0x30, 0x80},
-{0x31, 0x80},
-{0x38, 0x11},
-{0x39, 0x34},
-{0x40, 0xf3},
-
-{0x41, 0x32},/* 33 */
-{0x42, 0x22},/* 22 */
-{0x43, 0xf0},/* f6 */
-{0x44, 0x44},/* 44 */
-{0x45, 0x44},/* 33 */
-{0x46, 0x00},
-{0x50, 0xb2},
-{0x51, 0x81},
-{0x52, 0x98},
-
-{0x80, 0x38},
-{0x81, 0x20},
-{0x82, 0x36},/* 3a */
-
-{0x83, 0x5e},/* 5e */
-{0x84, 0x22},/* 24 21 22 Spec AWB H modify */
-{0x85, 0x4f},/* 54 51 4f Spec AWB H modify */
-{0x86, 0x20},/* 24 */
-
-{0x87, 0x48},
-{0x88, 0x38},
-{0x89, 0x37},/* 38 */
-{0x8a, 0x29},/* 2a */
-
-{0x8b, 0x40},/* 47 */
-{0x8c, 0x38},
-{0x8d, 0x34},
-{0x8e, 0x29},/* 2c */
-
-{0x8f, 0x5c},
-{0x90, 0x5b},
-{0x91, 0x57},
-{0x92, 0x4f},
-{0x93, 0x43},
-{0x94, 0x3e},
-{0x95, 0x34},
-{0x96, 0x2c},
-{0x97, 0x23},
-{0x98, 0x20},
-{0x99, 0x1f},
-{0x9a, 0x1f},
-
-{0x9b, 0x77},
-{0x9c, 0x66},
-{0x9d, 0x48},
-{0x9e, 0x38},
-{0x9f, 0x30},
-
-{0xa0, 0x60},
-{0xa1, 0x34},
-{0xa2, 0x6f},
-{0xa3, 0xff},
-
-{0xa4, 0x14},/* 1500fps */
-{0xa5, 0x2c},/* 700fps */
-{0xa6, 0xcf},
-
-{0xad, 0x40},
-{0xae, 0x4a},
-
-{0xaf, 0x28},/* low temp Rgain */
-{0xb0, 0x26},/* low temp Rgain */
-
-{0xb1, 0x00},/* 0x20 -> 0x00 0405 modify */
-{0xb4, 0xea},
-{0xb8, 0xa1},/* a2: b-2, R+2 b4 B-3, R+4 lowtemp b0 a1 Spec AWB A modify */
-{0xb9, 0x00},
-/* PAGE 22 END */
-
-/* PAGE 48 START*/
-{0x03, 0x48},
-
-/* PLL Setting */
-{0x70, 0x05},
-{0x71, 0x30},/*MiPi Pllx2 */
-{0x72, 0x85},
-{0x70, 0xa5},/* PLL Enable */
-{0x03, 0x48},
-{0x03, 0x48},
-{0x03, 0x48},
-{0x03, 0x48},
-{0x70, 0x95},/* CLK_GEN_ENABLE */
-
-/* MIPI TX Setting */
-{0x11, 0x00},/* 20111013 0x01 -> 0x00 not Continues */
-/*0x17cc*/
-{0x10, 0x1c},
-{0x12, 0x00},
-{0x14, 0x30},/*0x1470, *//* 20111013 0x00 -> 0x30 Clock Delay */
-{0x16, 0x04},
-
-{0x19, 0x00},
-{0x1a, 0x32},
-{0x1b, 0x17},
-{0x1c, 0x0e},
-{0x1d, 0x0f},
-{0x1e, 0x04},
-{0x1f, 0x04},
-{0x20, 0x00},
-
-{0x23, 0x01},
-{0x24, 0x1e},
-{0x25, 0x00},
-{0x26, 0x00},
-{0x27, 0x01},
-{0x28, 0x00},
-{0x2a, 0x06},
-{0x2b, 0x40},
-{0x2c, 0x04},
-{0x2d, 0xb0},
-
-{0x30, 0x00},/*640x480 MiPi OutPut */
-{0x31, 0x05},
-
-/*0x3040, 800x600 MiPi OutPut*/
-/*0x3106,*/
-
-{0x32, 0x06},
-{0x33, 0x0a},
-{0x34, 0x02},/*CLK LP -> HS Prepare time 24MHz:0x02, 48MHz:0x03 */
-{0x35, 0x03},
-{0x36, 0x01},
-{0x37, 0x07},
-{0x38, 0x02},
-{0x39, 0x02},/*drivability 24MHZ:02, 48MHz:03 */
-
-/*0x17c4,*/ /*MHSHIM*/
-/*0x17c0,*/ /*MHSHIM*/
-/*0x1700,*/ /*MHSHIM*/
-{0x50, 0x00},
-/* PAGE 48 END*/
-
-/* PAGE 20 */
-{0x03, 0x20},
-{0x10, 0x8c},/*AE on 60hz */
-
-/* PAGE 22 */
-{0x03, 0x22},
-{0x10, 0xe9},
-
-/* PAGE 0 */
-{0x03, 0x00},
-{0x03, 0x00},
-{0x03, 0x00},
-{0x03, 0x00},
-{0x03, 0x00},
-{0x03, 0x00},
-{0x03, 0x00},
-{0x03, 0x00},
-{0x03, 0x00},
-{0x03, 0x00},
-{0x03, 0x00},
-
-{0x03, 0x00},
-{0x01, 0xf8},
-
-{0xff, 0x28},/* NEED Delay 400ms */
-};
-
-regs_short_t front_preview_camera_regs[] = {
-{0x03, 0x00},/*Sleep On */
-{0x01, 0xf9},
-
-{0x03, 0x20},/*page 20 */
-{0x18, 0x30},/*for Preview */
-{0x10, 0x0c},/*AE off 60hz */
-
-{0x03, 0x22},/*page 22 */
-{0x10, 0x69},/*awb off */
-
-{0x03, 0x00},
-{0x10, 0x11},
-
-{0x11, 0x90},
-
-{0x20, 0x00},
-{0x21, 0x02},/*modify 20110929 0x04->0x02 */
-{0x22, 0x00},
-{0x23, 0x0a},/*modify 20110929 0x14->0x0a */
-
-{0x42, 0x00},/*VBlank */
-{0x43, 0x44},/*68 */
-
-/*Page10*/
-{0x03, 0x10},
-{0x3f, 0x02},
-{0x60, 0x6b},
-
-/*Page12*/
-{0x03, 0x12},
-{0x20, 0x00},
-{0x21, 0x00},
-{0x90, 0x00},
-
-/*only for Preview DPC */
-{0xd2, 0x17},
-{0xd5, 0x0f},
-{0xd7, 0xff},
-
-/*Page13*/
-{0x03, 0x13},
-{0x80, 0x00},
-
-/*Page18*/
-{0x03, 0x18},
-{0x10, 0x07},
-
-/* PAGE 48 START*/
-{0x03, 0x48},
-
-/* PLL Setting */
-{0x70, 0x05},
-{0x71, 0x30},/*MiPi Pllx2 */
-{0x72, 0x85},
-{0x70, 0xa5},/* PLL Enable */
-{0x03, 0x48},
-{0x03, 0x48},
-{0x03, 0x48},
-{0x03, 0x48},
-{0x70, 0x95},/* CLK_GEN_ENABLE */
-
-/* MIPI TX Setting */
-{0x11, 0x00},/* 20111013 0x10 continuous -> 0x00 not Continuous */
-/*0x17cc,*/ /*MHSHIM*/
-{0x10, 0x1c},
-{0x12, 0x00},
-{0x14, 0x30},/*0x1470, *//* 20111013 0x00 -> 0x30 Clock Delay */
-{0x16, 0x04},/* 1016 0x04->0x05 */
-
-{0x19, 0x00},
-{0x1a, 0x32},
-{0x1b, 0x17},
-{0x1c, 0x0e},
-{0x1d, 0x0f},
-{0x1e, 0x04},
-{0x1f, 0x04},
-{0x20, 0x00},
-
-{0x23, 0x01},
-{0x24, 0x1e},
-{0x25, 0x00},
-{0x26, 0x00},
-{0x27, 0x01},
-{0x28, 0x00},
-{0x2a, 0x06},
-{0x2b, 0x40},
-{0x2c, 0x04},
-{0x2d, 0xb0},
-
-{0x30, 0x00},/*640x480 MiPi OutPut */
-{0x31, 0x05},
-
-/*0x3040, 800x600 MiPi OutPut*/
-/*0x3106,*/
-
-{0x32, 0x06},
-{0x33, 0x0a},
-{0x34, 0x02},/*CLK LP -> HS Prepare time 24MHz:0x02, 48MHz:0x03 */
-{0x35, 0x01},
-{0x36, 0x03},
-{0x37, 0x07},
-{0x38, 0x02},
-{0x39, 0x02},/*drivability 24MHZ:02, 48MHz:03 */
-/*0x17c4,*/ /*MHSHIM*/
-/*0x17c0,*/ /*MHSHIM*/
-/*0x1700,*/ /*MHSHIM*/
-{0x50, 0x00},
-/* PAGE 48 END*/
-
-{0x03, 0x20},
-{0x10, 0x8c},/*AE on 60hz */
-
-{0x03, 0x22},
-{0x10, 0xe9},/*AWB ON */
-
-{0x03, 0x00},
-{0x03, 0x00},
-{0x03, 0x00},
-{0x03, 0x00},
-{0x03, 0x00},
-{0x03, 0x00},
-{0x03, 0x00},
-{0x03, 0x00},
-{0x03, 0x00},
-{0x03, 0x00},
-{0x03, 0x00},
-
-{0x03, 0x00},/*Sleep Off */
-{0x01, 0xf8},
-
-{0xff, 0x28},/*400ms */
-};
-
-regs_short_t front_snapshot_normal_regs[] = {
-{0x03, 0x00},
-{0x01, 0xf9},
-
-{0x03, 0x22},/*Page 22 */
-{0x10, 0x69},/*AWB Off */
-
-{0x03, 0x00},
-{0x10, 0x00},
-{0x11, 0x90},
-
-{0x20, 0x00},
-{0x21, 0x0a},/*modify 20110929 0x0c->0x0a */
-{0x22, 0x00},
-{0x23, 0x0a},/*modify 20110929 0x14->0x0a */
-
-/*Page10*/
-{0x03, 0x10},
-{0x3f, 0x00},
-{0x60, 0x67},
-
-/*Page12*/
-{0x03, 0x12},
-{0x20, 0x0f},
-{0x21, 0x0f},
-{0x90, 0x5d},
-
-/*only for Preview DPC Off*/
-{0xd2, 0x67},
-{0xd5, 0x02},
-{0xd7, 0x18},
-
-/*Page13*/
-{0x03, 0x13},
-{0x80, 0xfd},
-
-/* PAGE 18 START */
-{0x03, 0x18},
-{0x10, 0x00},/* Scaling Off */
-
-/* PAGE 48 START*/
-{0x03, 0x48},
-
-/* PLL Setting */
-{0x70, 0x05},
-{0x71, 0x30},/*MiPi Pllx2 */
-{0x72, 0x81},
-{0x70, 0x85},/* PLL Enable */
-{0x03, 0x48},
-{0x03, 0x48},
-{0x03, 0x48},
-{0x03, 0x48},
-{0x70, 0x95},/* CLK_GEN_ENABLE */
-
-/* MIPI TX Setting */
-{0x11, 0x00},/* 20111013 0x10 continuous -> 0x00 not Continuous */
-{0x10, 0x1c},
-{0x12, 0x00},
-{0x14, 0x30},/*0x1470, *//* 20111013 0x00 -> 0x30 Clock Delay */
-{0x16, 0x04},/* 1016 0x04->0x05 */
-
-{0x19, 0x00},
-{0x1a, 0x32},
-{0x1b, 0x17},
-{0x1c, 0x0c},
-{0x1d, 0x0f},
-{0x1e, 0x05},
-{0x1f, 0x05},
-{0x20, 0x00},
-
-{0x23, 0x01},
-{0x24, 0x1e},
-{0x25, 0x00},
-{0x26, 0x00},
-{0x27, 0x01},
-{0x28, 0x00},
-{0x2a, 0x06},
-{0x2b, 0x40},
-{0x2c, 0x04},
-{0x2d, 0xb0},
-
-{0x30, 0x80},/*1600x1200 MiPi OutPut */
-{0x31, 0x0c},
-
-/*0x3040, 800x600 MiPi OutPut*/
-/*0x3106,*/
-
-{0x32, 0x06},
-{0x33, 0x0a},
-{0x34, 0x03},/*CLK LP -> HS Prepare time 24MHz:0x02, 48MHz:0x03 */
-{0x35, 0x03},
-{0x36, 0x01},
-{0x37, 0x07},
-{0x38, 0x02},
-{0x39, 0x03},/*drivability 24MHZ:02, 48MHz:03 */
-/*0x17c4,*/ /*MHSHIM*/
-/*0x17c0,*/ /*MHSHIM*/
-/*0x1700,*/ /*MHSHIM*/
-{0x50, 0x00},
-/* PAGE 48 END*/
-
-/*Page0*/
-{0x03, 0x00},
-{0x03, 0x00},
-{0x03, 0x00},/*Dummy 750us */
-{0x03, 0x00},
-{0x03, 0x00},
-{0x03, 0x00},
-{0x03, 0x00},
-{0x03, 0x00},
-{0x03, 0x00},
-{0x03, 0x00},
-{0x03, 0x00},
-{0x03, 0x00},
-
-{0x03, 0x00},
-{0x01, 0xf8},/*Sleep Off */
-
-{0xff, 0x03},/*Increase from 30ms */
-};
-
-regs_short_t front_ev_minus_4_regs[] = {
-{0x03, 0x10},
-{0x40, 0xd0},
-};
-
-regs_short_t front_ev_minus_3_regs[] = {
-{0x03, 0x10},
-{0x40, 0xc0},
-};
-
-regs_short_t front_ev_minus_2_regs[] = {
-{0x03, 0x10},
-{0x40, 0xb0},
-};
-
-regs_short_t front_ev_minus_1_regs[] = {
-{0x03, 0x10},
-{0x40, 0xa0},
-};
-
-regs_short_t front_ev_default_regs[] = {
-{0x03, 0x10},
-{0x40, 0x00},
-};
-
-regs_short_t front_ev_plus_1_regs[] = {
-{0x03, 0x10},
-{0x40, 0x20},
-};
-
-regs_short_t front_ev_plus_2_regs[] = {
-{0x03, 0x10},
-{0x40, 0x30},
-};
-
-regs_short_t front_ev_plus_3_regs[] = {
-{0x03, 0x10},
-{0x40, 0x40},
-};
-
-regs_short_t front_ev_plus_4_regs[] = {
-{0x03, 0x10},
-{0x40, 0x50},
-};
-
-regs_short_t front_vt_pretty_default[] = {
-{0x03, 0x10},
-{0x40, 0x50},
-};
-
-regs_short_t front_vt_pretty_1[] = {
-{0x03, 0x10},
-{0x40, 0x50},
-};
-
-regs_short_t front_vt_pretty_2[] = {
-{0x03, 0x10},
-{0x40, 0x50},
-};
-
-regs_short_t front_vt_pretty_3[] = {
-{0x03, 0x10},
-{0x40, 0x50},
-};
-
-regs_short_t front_fps_auto_regs[] = {
-};
-
-regs_short_t front_fps_7_regs[] = {
-/* Fixed 7fps Mode */
-{0x03, 0x00},
-{0x01, 0xf9},
-{0x11, 0x90},
-
-{0x40, 0x01},/*Hblank 360 */
-{0x41, 0x68},
-{0x42, 0x00},/*Vsync 20 */
-{0x43, 0x14},
-
-{0x90, 0x11},/*BLC_TIME_TH_ON */
-{0x91, 0x11},/*BLC_TIME_TH_OFF */
-{0x92, 0xd8},/*BLC_AG_TH_ON */
-{0x93, 0xd0},/*BLC_AG_TH_OFF */
-
-{0x03, 0x02},/*PAGE 2 */
-{0xd4, 0x11},/*DCDC_TIME_TH_ON */
-{0xd5, 0x11},/*DCDC_TIME_TH_OFF */
-{0xd6, 0xd8},/*DCDC_AG_TH_ON */
-{0xd7, 0xd0},/*DCDC_AG_TH_OFF */
-
-{0x03, 0x20},
-{0x10, 0x0C},/*AE off 60hz */
-
-{0x03, 0x22},
-{0x10, 0x69},
-
-{0x03, 0x20},
-{0x2a, 0x03},
-{0x2b, 0xf5},
-
-{0x88, 0x06},/*EXP Max 7.06 fps */
-{0x89, 0x7c},
-{0x8a, 0x28},
-
-{0x91, 0x06},/*EXP Fix 07.00 fps */
-{0x92, 0x89},
-{0x93, 0xd4},
-
-{0x9c, 0x17},/*EXP Limit 500.00 fps */
-{0x9d, 0x70},
-{0x9e, 0x01},/*EXP Unit */
-{0x9f, 0xf4},
-
-{0x03, 0x20},
-{0x10, 0x8C},/*AE on 60hz */
-
-{0x03, 0x22},
-{0x10, 0xe9},
-
-{0x03, 0x00},
-{0x11, 0x94},
-
-/* PAGE 48 START*/
-{0x03, 0x48},
-
-/* PLL Setting */
-{0x70, 0x05},
-{0x71, 0x30},/*MiPi Pllx2 */
-{0x72, 0x85},
-{0x70, 0xa5},/* PLL Enable */
-{0x03, 0x48},
-{0x03, 0x48},
-{0x03, 0x48},
-{0x03, 0x48},
-{0x70, 0x95},/* CLK_GEN_ENABLE */
-
-/* MIPI TX Setting */
-{0x11, 0x00},/* 20111013 0x10 continuous -> 0x00 not Continuous */
-{0x10, 0x1c},
-{0x12, 0x00},
-{0x14, 0x30},/*0x1470, *//* 20111013 0x00 -> 0x30 Clock Delay */
-{0x16, 0x04},/* 1016 0x04->0x05 */
-
-{0x19, 0x00},
-{0x1a, 0x32},
-{0x1b, 0x17},
-{0x1c, 0x0e},
-{0x1d, 0x0f},
-{0x1e, 0x04},
-{0x1f, 0x04},
-{0x20, 0x00},
-
-{0x23, 0x01},
-{0x24, 0x1e},
-{0x25, 0x00},
-{0x26, 0x00},
-{0x27, 0x01},
-{0x28, 0x00},
-{0x2a, 0x06},
-{0x2b, 0x40},
-{0x2c, 0x04},
-{0x2d, 0xb0},
-
-{0x30, 0x00},/*640x480 MiPi OutPut */
-{0x31, 0x05},
-
-/*0x3040, 800x600 MiPi OutPut*/
-/*0x3106,*/
-
-{0x32, 0x06},
-{0x33, 0x0a},
-{0x34, 0x02},/*CLK LP -> HS Prepare time 24MHz:0x02, 48MHz:0x03 */
-{0x35, 0x03},
-{0x36, 0x01},
-{0x37, 0x07},
-{0x38, 0x02},
-{0x39, 0x02},/*drivability 24MHZ:02, 48MHz:03 */
-{0x50, 0x00},
-/* PAGE 48 END*/
-
-{0x03, 0x00},
-{0x03, 0x00},/*Dummy 750us */
-{0x03, 0x00},
-{0x03, 0x00},
-{0x03, 0x00},
-{0x03, 0x00},
-{0x03, 0x00},
-{0x03, 0x00},
-{0x03, 0x00},
-{0x03, 0x00},
-{0x03, 0x00},
-
-{0x01, 0xf8},
-
-{0xff, 0x28},/*NEED Delay 400ms */
-};
-
-regs_short_t front_fps_10_regs[] = {
-/* Fixed 10fps Mode */
-{0x03, 0x00},
-{0x01, 0xf9},
-{0x11, 0x90},
-
-{0x40, 0x01},/*Hblank 360 */
-{0x41, 0x68},
-{0x42, 0x00},/*Vsync 20 */
-{0x43, 0x14},
-
-{0x90, 0x0b},/*BLC_TIME_TH_ON */
-{0x91, 0x0b},/*BLC_TIME_TH_OFF */
-{0x92, 0xd8},/*BLC_AG_TH_ON */
-{0x93, 0xd0},/*BLC_AG_TH_OFF */
-
-{0x03, 0x02},/*PAGE 2 */
-{0xd4, 0x0b},/*DCDC_TIME_TH_ON */
-{0xd5, 0x0b},/*DCDC_TIME_TH_OFF */
-{0xd6, 0xd8},/*DCDC_AG_TH_ON */
-{0xd7, 0xd0},/*DCDC_AG_TH_OFF */
-
-{0x03, 0x20},
-{0x10, 0x0C},/*AE off 60hz */
-
-{0x03, 0x22},
-{0x10, 0x69},
-
-{0x03, 0x20},
-{0x2a, 0x03},
-{0x2b, 0xf5},
-
-{0x88, 0x04},/*EXP Max 10.91 fps */
-{0x89, 0x32},
-{0x8a, 0x38},
-
-{0x91, 0x04},/*EXP Fix 10.00 fps */
-{0x92, 0x93},
-{0x93, 0xe0},
-
-{0x9c, 0x17},/*EXP Limit 500.00 fps */
-{0x9d, 0x70},
-{0x9e, 0x01},/*EXP Unit */
-{0x9f, 0xf4},
-
-{0x03, 0x20},
-{0x10, 0x8C},/*AE on 60hz */
-
-{0x03, 0x22},
-{0x10, 0xe9},
-
-{0x03, 0x00},
-{0x11, 0x94},
-
-/* PAGE 48 START*/
-{0x03, 0x48},
-
-/* PLL Setting */
-{0x70, 0x05},
-{0x71, 0x30},/*MiPi Pllx2 */
-{0x72, 0x85},
-{0x70, 0xa5},/* PLL Enable */
-{0x03, 0x48},
-{0x03, 0x48},
-{0x03, 0x48},
-{0x03, 0x48},
-{0x70, 0x95},/* CLK_GEN_ENABLE */
-
-/* MIPI TX Setting */
-{0x11, 0x00},/* 20111013 0x10 continuous -> 0x00 not Continuous */
-{0x10, 0x1c},
-{0x12, 0x00},
-{0x14, 0x30},/*0x1470, *//* 20111013 0x00 -> 0x30 Clock Delay */
-{0x16, 0x04},/* 1016 0x04->0x05 */
-
-{0x19, 0x00},
-{0x1a, 0x32},
-{0x1b, 0x17},
-{0x1c, 0x0e},
-{0x1d, 0x0f},
-{0x1e, 0x04},
-{0x1f, 0x04},
-{0x20, 0x00},
-
-{0x23, 0x01},
-{0x24, 0x1e},
-{0x25, 0x00},
-{0x26, 0x00},
-{0x27, 0x01},
-{0x28, 0x00},
-{0x2a, 0x06},
-{0x2b, 0x40},
-{0x2c, 0x04},
-{0x2d, 0xb0},
-
-{0x30, 0x00},/*640x480 MiPi OutPut */
-{0x31, 0x05},
-
-/*0x3040, 800x600 MiPi OutPut*/
-/*0x3106,*/
-
-{0x32, 0x06},
-{0x33, 0x0a},
-{0x34, 0x02},/*CLK LP -> HS Prepare time 24MHz:0x02, 48MHz:0x03 */
-{0x35, 0x03},
-{0x36, 0x01},
-{0x37, 0x07},
-{0x38, 0x02},
-{0x39, 0x02},/*drivability 24MHZ:02, 48MHz:03 */
-{0x50, 0x00},
-/* PAGE 48 END*/
-
-{0x03, 0x00},
-{0x03, 0x00},/*Dummy 750us */
-{0x03, 0x00},
-{0x03, 0x00},
-{0x03, 0x00},
-{0x03, 0x00},
-{0x03, 0x00},
-{0x03, 0x00},
-{0x03, 0x00},
-{0x03, 0x00},
-{0x03, 0x00},
-
-{0x01, 0xf8},
-
-{0xff, 0x28},/*NEED Delay 400ms */
-};
-
-regs_short_t front_fps_15_regs[] = {
-/* Fixed 15fps Mode */
-{0x03, 0x00},
-{0x01, 0xf9},
-{0x11, 0x90},
-
-{0x40, 0x01},/*Hblank 360 */
-{0x41, 0x68},
-{0x42, 0x00},/*Vsync 20 */
-{0x43, 0x14},
-
-{0x90, 0x08},/*BLC_TIME_TH_ON */
-{0x91, 0x08},/*BLC_TIME_TH_OFF */
-{0x92, 0xd8},/*BLC_AG_TH_ON */
-{0x93, 0xd0},/*BLC_AG_TH_OFF */
-
-{0x03, 0x02},/*PAGE 2 */
-{0xd4, 0x08},/*DCDC_TIME_TH_ON */
-{0xd5, 0x08},/*DCDC_TIME_TH_OFF */
-{0xd6, 0xd8},/*DCDC_AG_TH_ON */
-{0xd7, 0xd0},/*DCDC_AG_TH_OFF */
-
-{0x03, 0x20},
-{0x10, 0x0C},/*AE off 60hz */
-
-{0x03, 0x22},
-{0x10, 0x69},
-
-{0x03, 0x20},
-{0x2a, 0x03},
-{0x2b, 0xf5},
-
-{0x88, 0x03},/*EXP Max 15.00 fps */
-{0x89, 0x0d},
-{0x8a, 0x40},
-
-{0x91, 0x03},/*EXP Fix 14.91 fps */
-{0x92, 0x12},
-{0x93, 0x22},
-
-{0x9c, 0x17},/*EXP Limit 500.00 fps */
-{0x9d, 0x70},
-{0x9e, 0x01},/*EXP Unit */
-{0x9f, 0xf4},
-
-{0x03, 0x20},
-{0x10, 0x8C},/*AE on 60hz */
-
-{0x03, 0x22},
-{0x10, 0xe9},
-
-{0x03, 0x00},
-{0x11, 0x94},
-
-/* PAGE 48 START*/
-{0x03, 0x48},
-
-/* PLL Setting */
-{0x70, 0x05},
-{0x71, 0x30},/*MiPi Pllx2 */
-{0x72, 0x85},
-{0x70, 0xa5},/* PLL Enable */
-{0x03, 0x48},
-{0x03, 0x48},
-{0x03, 0x48},
-{0x03, 0x48},
-{0x70, 0x95},/* CLK_GEN_ENABLE */
-
-/* MIPI TX Setting */
-{0x11, 0x00},/* 20111013 0x10 continuous -> 0x00 not Continuous */
-{0x10, 0x1c},
-{0x12, 0x00},
-{0x14, 0x30},/*0x1470, *//* 20111013 0x00 -> 0x30 Clock Delay */
-{0x16, 0x04},/* 1016 0x04->0x05 */
-
-{0x19, 0x00},
-{0x1a, 0x32},
-{0x1b, 0x17},
-{0x1c, 0x0e},
-{0x1d, 0x0f},
-{0x1e, 0x04},
-{0x1f, 0x04},
-{0x20, 0x00},
-
-{0x23, 0x01},
-{0x24, 0x1e},
-{0x25, 0x00},
-{0x26, 0x00},
-{0x27, 0x01},
-{0x28, 0x00},
-{0x2a, 0x06},
-{0x2b, 0x40},
-{0x2c, 0x04},
-{0x2d, 0xb0},
-
-{0x30, 0x00},/*640x480 MiPi OutPut */
-{0x31, 0x05},
-
-/*0x3040, 800x600 MiPi OutPut*/
-/*0x3106,*/
-
-{0x32, 0x06},
-{0x33, 0x0a},
-{0x34, 0x02},/*CLK LP -> HS Prepare time 24MHz:0x02, 48MHz:0x03 */
-{0x35, 0x03},
-{0x36, 0x01},
-{0x37, 0x07},
-{0x38, 0x02},
-{0x39, 0x02},/*drivability 24MHZ:02, 48MHz:03 */
-{0x50, 0x00},
-/* PAGE 48 END*/
-
-{0x03, 0x00},
-{0x03, 0x00},/*Dummy 750us */
-{0x03, 0x00},
-{0x03, 0x00},
-{0x03, 0x00},
-{0x03, 0x00},
-{0x03, 0x00},
-{0x03, 0x00},
-{0x03, 0x00},
-{0x03, 0x00},
-{0x03, 0x00},
-
-{0x01, 0xf8},
-
-{0xff, 0x28},/*NEED Delay 400ms */
-
-};
-
-regs_short_t front_fps_24_regs[] = {
-/* Need to add Fixed 24fps Mode */
-/* Temporary setting, Fixed 15fps Mode */
-{0x03, 0x00},
-{0x01, 0xf9},
-{0x11, 0x90},
-
-{0x40, 0x01},/*Hblank 360 */
-{0x41, 0x68},
-{0x42, 0x00},/*Vsync 20 */
-{0x43, 0x14},
-
-{0x90, 0x08},/*BLC_TIME_TH_ON */
-{0x91, 0x08},/*BLC_TIME_TH_OFF */
-{0x92, 0xd8},/*BLC_AG_TH_ON */
-{0x93, 0xd0},/*BLC_AG_TH_OFF */
-
-{0x03, 0x02},/*PAGE 2 */
-{0xd4, 0x08},/*DCDC_TIME_TH_ON */
-{0xd5, 0x08},/*DCDC_TIME_TH_OFF */
-{0xd6, 0xd8},/*DCDC_AG_TH_ON */
-{0xd7, 0xd0},/*DCDC_AG_TH_OFF */
-
-{0x03, 0x20},
-{0x10, 0x0C},/*AE off 60hz */
-
-{0x03, 0x22},
-{0x10, 0x69},
-
-{0x03, 0x20},
-{0x2a, 0x03},
-{0x2b, 0xf5},
-
-{0x88, 0x03},/*EXP Max 15.00 fps */
-{0x89, 0x0d},
-{0x8a, 0x40},
-
-{0x91, 0x03},/*EXP Fix 14.91 fps */
-{0x92, 0x12},
-{0x93, 0x22},
-
-{0x9c, 0x17},/*EXP Limit 500.00 fps */
-{0x9d, 0x70},
-{0x9e, 0x01},/*EXP Unit */
-{0x9f, 0xf4},
-
-{0x03, 0x20},
-{0x10, 0x8C},/*AE on 60hz */
-
-{0x03, 0x22},
-{0x10, 0xe9},
-
-{0x03, 0x00},
-{0x11, 0x94},
-
-/* PAGE 48 START*/
-{0x03, 0x48},
-
-/* PLL Setting */
-{0x70, 0x05},
-{0x71, 0x30},/*MiPi Pllx2 */
-{0x72, 0x85},
-{0x70, 0xa5},/* PLL Enable */
-{0x03, 0x48},
-{0x03, 0x48},
-{0x03, 0x48},
-{0x03, 0x48},
-{0x70, 0x95},/* CLK_GEN_ENABLE */
-
-/* MIPI TX Setting */
-{0x11, 0x00},/* 20111013 0x10 continuous -> 0x00 not Continuous */
-{0x10, 0x1c},
-{0x12, 0x00},
-{0x14, 0x30},/*0x1470, *//* 20111013 0x00 -> 0x30 Clock Delay */
-{0x16, 0x04},/* 1016 0x04->0x05 */
-
-{0x19, 0x00},
-{0x1a, 0x32},
-{0x1b, 0x17},
-{0x1c, 0x0e},
-{0x1d, 0x0f},
-{0x1e, 0x04},
-{0x1f, 0x04},
-{0x20, 0x00},
-
-{0x23, 0x01},
-{0x24, 0x1e},
-{0x25, 0x00},
-{0x26, 0x00},
-{0x27, 0x01},
-{0x28, 0x00},
-{0x2a, 0x06},
-{0x2b, 0x40},
-{0x2c, 0x04},
-{0x2d, 0xb0},
-
-{0x30, 0x00},/*640x480 MiPi OutPut */
-{0x31, 0x05},
-
-/*0x3040, 800x600 MiPi OutPut*/
-/*0x3106,*/
-
-{0x32, 0x06},
-{0x33, 0x0a},
-{0x34, 0x02},/*CLK LP->HS Prepare time 24MHz:0x02, 48MHz:0x03 */
-{0x35, 0x03},
-{0x36, 0x01},
-{0x37, 0x07},
-{0x38, 0x02},
-{0x39, 0x02},/*drivability 24MHZ:02, 48MHz:03 */
-{0x50, 0x00},
-/* PAGE 48 END*/
-
-{0x03, 0x00},
-{0x03, 0x00},/*Dummy 750us */
-{0x03, 0x00},
-{0x03, 0x00},
-{0x03, 0x00},
-{0x03, 0x00},
-{0x03, 0x00},
-{0x03, 0x00},
-{0x03, 0x00},
-{0x03, 0x00},
-{0x03, 0x00},
-
-{0x01, 0xf8},
-
-{0xff, 0x28},/*NEED Delay 400ms */
-};
-
-regs_short_t front_pattern_on_regs[] = {
-{0x03, 0x00},
-{0x50, 0x05},
-};
-
-regs_short_t front_pattern_off_regs[] = {
-{0x03, 0x00},
-{0x50, 0x00},
-};
-
-#endif/* __SR200PC20M_REGS_H */
diff --git a/drivers/media/video/v4l2-ioctl.c b/drivers/media/video/v4l2-ioctl.c
index f3e2cc7..348aa61 100644
--- a/drivers/media/video/v4l2-ioctl.c
+++ b/drivers/media/video/v4l2-ioctl.c
@@ -2308,6 +2308,10 @@ static int check_array_args(unsigned int cmd, void *parg, size_t *array_size,
struct v4l2_ext_controls *ctrls = parg;
if (ctrls->count != 0) {
+ if (ctrls->count > V4L2_CID_MAX_CTRLS) {
+ ret = -EINVAL;
+ break;
+ }
*user_ptr = (void __user *)ctrls->controls;
*kernel_ptr = (void **)&ctrls->controls;
*array_size = sizeof(struct v4l2_ext_control)
diff --git a/drivers/video/samsung/Kconfig b/drivers/video/samsung/Kconfig
index 3cb946f..09711d3 100644
--- a/drivers/video/samsung/Kconfig
+++ b/drivers/video/samsung/Kconfig
@@ -7,11 +7,19 @@ config FB_S5P
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
+ select SYNC
+ select SW_SYNC
+ select SW_SYNC_USER
depends on FB && (ARCH_S5PV210 || ARCH_EXYNOS4) && !FB_S3C
default n
help
This enables support for Samsung Display Controller (FIMD)
+config FB_S5P_SYSMMU
+ bool "S5P FIMD SYSMMU enable"
+ depends on FB_S5P
+ default n
+
config FB_S5P_SPLASH_SCREEN
bool "SPLASH_SCREEN on LCD"
depends on FB_S5P
@@ -26,6 +34,10 @@ config FB_S5P_DEBUG
bool "S5P Framebuffer debug messages"
depends on FB_S5P
+config FB_S5P_VSYNC_THREAD
+ bool "S5P Framebuffer vsync thread"
+ depends on FB_S5P
+
config FB_S5P_TRACE_UNDERRUN
bool "S5P Framebuffer FIFO underrun trace"
depends on FB_S5P
@@ -111,6 +123,21 @@ endif # FIMD_EXT_SUPPORT
choice
depends on FB_S5P
+prompt "Select RGB Order"
+default FB_BGRA_ORDER
+config FB_BGRA_ORDER
+ bool "BGRA8888"
+ help
+ This enables use BGRA order.
+
+config FB_RGBA_ORDER
+ bool "RGBA8888"
+ help
+ This enables use RGBA order.
+endchoice
+
+choice
+depends on FB_S5P
prompt "Select LCD Type"
default FB_S5P_AMS369FG06
config FB_S5P_LTE480WV
@@ -180,6 +207,12 @@ config FB_S5P_LMS501KF03
help
This enables support for Samsung LMS501KF03 5.01" WVGA TFT LCD panel
+config FB_S5P_LMS501XX
+ bool "LMS501XX MIPI LCD"
+ depends on FB_S5P_MIPI_DSIM
+ help
+ This enables support for Samsung LMS501XX 5.01" WVGA TFT LCD panel
+
config FB_S5P_DUMMY_MIPI_LCD
bool "DUMMY MIPI LCD"
depends on FB_S5P_MIPI_DSIM
@@ -192,6 +225,18 @@ config FB_S5P_S6E8AA0
---help---
This enables support for Samsung S6E8AA0 MIPI LCD
+config FB_S5P_EA8061
+ bool "EA8061 MIPI LCD"
+ depends on FB_S5P_MIPI_DSIM
+ ---help---
+ This enables support for Samsung EA8061 MIPI LCD
+
+config FB_S5P_S6EVR02
+ bool "S6EVR02 MIPI LCD"
+ depends on FB_S5P_MIPI_DSIM
+ ---help---
+ This enables support for Samsung S6EVR02 MIPI LCD
+
config FB_S5P_S6E8AB0
bool "S6E8AB0 MIPI LCD"
depends on MACH_PX && FB_S5P_MIPI_DSIM
@@ -199,7 +244,7 @@ config FB_S5P_S6E8AB0
This enables support for Samsung S6E8AB0 MIPI LCD
config FB_S5P_S6D6AA1
- bool "S6E8AB0 MIPI LCD"
+ bool "S6D6AA1 MIPI LCD"
depends on FB_S5P_MIPI_DSIM
---help---
This enables support for Samsung S6D6AA1 MIPI LCD
diff --git a/drivers/video/samsung/Makefile b/drivers/video/samsung/Makefile
index 16ed689..75995be 100644
--- a/drivers/video/samsung/Makefile
+++ b/drivers/video/samsung/Makefile
@@ -17,10 +17,14 @@ obj-$(CONFIG_FB_S5P_LD9040) += ld9040.o smart_dimming_ld9042.o
obj-$(CONFIG_FB_S5P_NT35560) += nt35560.o
obj-$(CONFIG_FB_S5P_MDNIE) += s3cfb_mdnie.o s3cfb_ielcd.o mdnie.o mdnie_tunning.o
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_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
obj-$(CONFIG_FB_S5P_S6E39A0) += s3cfb_s6e39a0.o smart_dimming.o
+obj-$(CONFIG_FB_S5P_S6E63M0) += s3cfb_s6e63m0.o smart_dimming.o
obj-$(CONFIG_FB_S5P_S6D6AA1) += s6d6aa1.o
obj-$(CONFIG_FB_S5P_MIPI_DSIM) += s5p_dsim_lowlevel.o
obj-$(CONFIG_FB_S5P_MIPI_DSIM) += s5p-dsim.o
diff --git a/drivers/video/samsung/aid_ea8061.h b/drivers/video/samsung/aid_ea8061.h
new file mode 100644
index 0000000..9b92d80
--- /dev/null
+++ b/drivers/video/samsung/aid_ea8061.h
@@ -0,0 +1,337 @@
+#ifndef __AID_EA8061_H__
+#define __AID_EA8061_H__
+
+#include "smart_dimming_ea8061.h"
+
+#define aid_300nit_260nit_B3_1st 0x00
+#define aid_300nit_260nit_B3_2nd 0x0A
+#define aid_250nit_190nit_B3_1st 0x00
+#define aid_250nit_190nit_B3_2nd 0x0A
+#define aid_188nit_186nit_B3_1st 0x00
+#define aid_184nit_182nit_B3_1st 0x01
+#define aid_188nit_B3_2nd 0x68
+#define aid_186nit_B3_2nd 0xCF
+#define aid_184nit_B3_2nd 0x37
+#define aid_182nit_B3_2nd 0x9F
+#define aid_180nit_110nit_B3_1st 0x02
+#define aid_180nit_110nit_B3_2nd 0x06
+#define aid_102nit_B3_1st 0x00
+#define aid_108nit_104nit_B3_1st 0x01
+#define aid_108nit_B3_2nd 0xC4
+#define aid_106nit_B3_2nd 0x82
+#define aid_104nit_B3_2nd 0x40
+#define aid_102nit_B3_2nd 0xFE
+#define aid_100nit_B3_1st 0x00
+#define aid_90nit_80nit_B3_1st 0x01
+#define aid_70nit_60nit_B3_1st 0x02
+#define aid_50nit_30nit_B3_1st 0x03
+#define aid_20nit_B3_1st 0x04
+#define aid_100nit_B3_2nd 0xBC
+#define aid_90nit_B3_2nd 0x36
+#define aid_80nit_B3_2nd 0xAB
+#define aid_70nit_B3_2nd 0x25
+#define aid_60nit_B3_2nd 0x95
+#define aid_50nit_B3_2nd 0x0A
+#define aid_40nit_B3_2nd 0x74
+#define aid_30nit_B3_2nd 0xDF
+#define aid_20nit_B3_2nd 0x45
+#define AOR40_BASE_188 202
+#define AOR40_BASE_186 215
+#define AOR40_BASE_184 230
+#define AOR40_BASE_182 250
+#define AOR40_BASE_180 275
+#define AOR40_BASE_170 260
+#define AOR40_BASE_160 246
+#define AOR40_BASE_150 230
+#define AOR40_BASE_140 217
+#define AOR40_BASE_130 202
+#define AOR40_BASE_120 184
+#define AOR40_BASE_110 169
+#define AOR40_BASE_108 154
+#define AOR40_BASE_106 141
+#define AOR40_BASE_104 130
+#define AOR40_BASE_102 120
+#define base_20to100 110
+
+static const struct rgb_offset_info aid_rgb_fix_table_SM2[] = {
+ {GAMMA_184CD, IV_11, CI_BLUE, 1},
+ {GAMMA_182CD, IV_11, CI_GREEN, -1}, {GAMMA_182CD, IV_11, CI_BLUE, 2},
+ {GAMMA_180CD, IV_11, CI_RED, -1}, {GAMMA_180CD, IV_11, CI_GREEN, -2}, {GAMMA_180CD, IV_11, CI_BLUE, 3},
+ {GAMMA_170CD, IV_11, CI_RED, -1}, {GAMMA_170CD, IV_11, CI_GREEN, -2}, {GAMMA_170CD, IV_11, CI_BLUE, 3},
+ {GAMMA_160CD, IV_11, CI_RED, -1}, {GAMMA_160CD, IV_11, CI_GREEN, -2}, {GAMMA_160CD, IV_11, CI_BLUE, 3},
+ {GAMMA_150CD, IV_11, CI_RED, -1}, {GAMMA_150CD, IV_11, CI_GREEN, -2}, {GAMMA_150CD, IV_11, CI_BLUE, 3},
+ {GAMMA_140CD, IV_11, CI_RED, -1}, {GAMMA_140CD, IV_11, CI_GREEN, -2}, {GAMMA_140CD, IV_11, CI_BLUE, 3},
+ {GAMMA_130CD, IV_11, CI_RED, -1}, {GAMMA_130CD, IV_11, CI_GREEN, -2}, {GAMMA_130CD, IV_11, CI_BLUE, 3},
+ {GAMMA_120CD, IV_11, CI_RED, -1}, {GAMMA_120CD, IV_11, CI_GREEN, -2}, {GAMMA_120CD, IV_11, CI_BLUE, 3},
+ {GAMMA_110CD, IV_11, CI_RED, -1}, {GAMMA_110CD, IV_11, CI_GREEN, -2}, {GAMMA_110CD, IV_11, CI_BLUE, 3},
+ {GAMMA_108CD, IV_11, CI_RED, -1}, {GAMMA_108CD, IV_11, CI_GREEN, -2}, {GAMMA_108CD, IV_11, CI_BLUE, 3},
+ {GAMMA_106CD, IV_11, CI_RED, -1}, {GAMMA_106CD, IV_11, CI_GREEN, -1}, {GAMMA_106CD, IV_11, CI_BLUE, 3},
+ {GAMMA_104CD, IV_11, CI_RED, -2}, {GAMMA_104CD, IV_11, CI_GREEN, -1}, {GAMMA_104CD, IV_11, CI_BLUE, 4},
+ {GAMMA_102CD, IV_11, CI_RED, -2}, {GAMMA_102CD, IV_11, CI_BLUE, 4},
+ {GAMMA_100CD, IV_11, CI_RED, -2}, {GAMMA_100CD, IV_11, CI_BLUE, 5},
+ {GAMMA_90CD, IV_11, CI_RED, -5}, {GAMMA_90CD, IV_11, CI_BLUE, 6},
+ {GAMMA_80CD, IV_11, CI_RED, -6}, {GAMMA_80CD, IV_11, CI_BLUE, 8},
+ {GAMMA_70CD, IV_11, CI_RED, -7}, {GAMMA_70CD, IV_11, CI_BLUE, 11},
+ {GAMMA_60CD, IV_11, CI_RED, -10}, {GAMMA_60CD, IV_11, CI_BLUE, 14},
+ {GAMMA_50CD, IV_11, CI_RED, -12}, {GAMMA_50CD, IV_11, CI_BLUE, 19},
+ {GAMMA_40CD, IV_11, CI_RED, -18}, {GAMMA_40CD, IV_11, CI_BLUE, 24},
+ {GAMMA_30CD, IV_11, CI_RED, -18}, {GAMMA_30CD, IV_11, CI_BLUE, 31},
+ {GAMMA_20CD, IV_11, CI_RED, -18}, {GAMMA_20CD, IV_11, CI_BLUE, 39},
+ {GAMMA_90CD, IV_23, CI_GREEN, -3},
+ {GAMMA_80CD, IV_23, CI_RED, -1}, {GAMMA_80CD, IV_23, CI_GREEN, -4},
+ {GAMMA_70CD, IV_23, CI_RED, -3}, {GAMMA_70CD, IV_23, CI_GREEN, -6},
+ {GAMMA_60CD, IV_23, CI_RED, -4}, {GAMMA_60CD, IV_23, CI_GREEN, -9},
+ {GAMMA_50CD, IV_23, CI_RED, -7}, {GAMMA_50CD, IV_23, CI_GREEN, -9},
+ {GAMMA_40CD, IV_23, CI_RED, -12}, {GAMMA_40CD, IV_23, CI_GREEN, -16},
+ {GAMMA_30CD, IV_23, CI_RED, -17}, {GAMMA_30CD, IV_23, CI_GREEN, -16}, {GAMMA_30CD, IV_23, CI_BLUE, 2},
+ {GAMMA_20CD, IV_23, CI_RED, -22}, {GAMMA_20CD, IV_23, CI_GREEN, -16}, {GAMMA_20CD, IV_23, CI_BLUE, 9},
+ {GAMMA_30CD, IV_35, CI_RED, -3}, {GAMMA_30CD, IV_35, CI_GREEN, -14},
+ {GAMMA_20CD, IV_35, CI_RED, -11}, {GAMMA_20CD, IV_35, CI_GREEN, -30},
+};
+
+static const struct rgb_offset_info aid_rgb_fix_table_M4[] = {
+ {GAMMA_180CD, IV_11, CI_GREEN, 1},
+ {GAMMA_170CD, IV_11, CI_GREEN, 1},
+ {GAMMA_160CD, IV_11, CI_GREEN, 1},
+ {GAMMA_150CD, IV_11, CI_GREEN, 1},
+ {GAMMA_140CD, IV_11, CI_GREEN, 1},
+ {GAMMA_130CD, IV_11, CI_GREEN, 1},
+ {GAMMA_120CD, IV_11, CI_GREEN, 1},
+ {GAMMA_110CD, IV_11, CI_GREEN, 1},
+ {GAMMA_180CD, IV_23, CI_GREEN, 1},
+ {GAMMA_170CD, IV_23, CI_GREEN, 1},
+ {GAMMA_160CD, IV_23, CI_GREEN, 1},
+ {GAMMA_150CD, IV_23, CI_GREEN, 1},
+ {GAMMA_140CD, IV_23, CI_GREEN, 1},
+ {GAMMA_130CD, IV_23, CI_GREEN, 1},
+ {GAMMA_120CD, IV_23, CI_GREEN, 1},
+ {GAMMA_110CD, IV_23, CI_GREEN, 1},
+ {GAMMA_180CD, IV_35, CI_RED, -10}, {GAMMA_180CD, IV_35, CI_GREEN, 2},
+ {GAMMA_170CD, IV_35, CI_RED, -11}, {GAMMA_170CD, IV_35, CI_GREEN, 2},
+ {GAMMA_160CD, IV_35, CI_RED, -12}, {GAMMA_160CD, IV_35, CI_GREEN, 2},
+ {GAMMA_150CD, IV_35, CI_RED, -13}, {GAMMA_150CD, IV_35, CI_GREEN, 2},
+ {GAMMA_140CD, IV_35, CI_RED, -14}, {GAMMA_140CD, IV_35, CI_GREEN, 2},
+ {GAMMA_130CD, IV_35, CI_RED, -15}, {GAMMA_130CD, IV_35, CI_GREEN, 2},
+ {GAMMA_120CD, IV_35, CI_RED, -16}, {GAMMA_120CD, IV_35, CI_GREEN, 2},
+ {GAMMA_110CD, IV_35, CI_RED, -17}, {GAMMA_110CD, IV_35, CI_GREEN, 2},
+ {GAMMA_90CD, IV_11, CI_GREEN, 12}, {GAMMA_90CD, IV_11, CI_BLUE, -7},
+ {GAMMA_80CD, IV_11, CI_GREEN, 20}, {GAMMA_80CD, IV_11, CI_BLUE, 2},
+ {GAMMA_70CD, IV_11, CI_RED, -17}, {GAMMA_70CD, IV_11, CI_GREEN, 20}, {GAMMA_70CD, IV_11, CI_BLUE, 5},
+ {GAMMA_60CD, IV_11, CI_RED, -17}, {GAMMA_60CD, IV_11, CI_GREEN, 29}, {GAMMA_60CD, IV_11, CI_BLUE, 16},
+ {GAMMA_50CD, IV_11, CI_RED, -17}, {GAMMA_50CD, IV_11, CI_GREEN, 39}, {GAMMA_50CD, IV_11, CI_BLUE, 27},
+ {GAMMA_40CD, IV_11, CI_RED, -17}, {GAMMA_40CD, IV_11, CI_GREEN, 49}, {GAMMA_40CD, IV_11, CI_BLUE, 37},
+ {GAMMA_30CD, IV_11, CI_RED, -52}, {GAMMA_30CD, IV_11, CI_GREEN, 60}, {GAMMA_30CD, IV_11, CI_BLUE, 52},
+ {GAMMA_20CD, IV_11, CI_RED, -56}, {GAMMA_20CD, IV_11, CI_GREEN, 76}, {GAMMA_20CD, IV_11, CI_BLUE, 72},
+ {GAMMA_70CD, IV_23, CI_RED, -6}, {GAMMA_70CD, IV_23, CI_GREEN, 3},
+ {GAMMA_60CD, IV_23, CI_RED, -13}, {GAMMA_60CD, IV_23, CI_GREEN, 4},
+ {GAMMA_50CD, IV_23, CI_RED, -20}, {GAMMA_50CD, IV_23, CI_GREEN, 5},
+ {GAMMA_40CD, IV_23, CI_RED, -30}, {GAMMA_40CD, IV_23, CI_GREEN, 6},
+ {GAMMA_30CD, IV_23, CI_RED, -35}, {GAMMA_30CD, IV_23, CI_GREEN, -2},
+ {GAMMA_20CD, IV_23, CI_RED, -46}, {GAMMA_20CD, IV_23, CI_GREEN, -6}, {GAMMA_20CD, IV_23, CI_BLUE, 11},
+ {GAMMA_30CD, IV_35, CI_RED, -23}, {GAMMA_30CD, IV_35, CI_GREEN, 11},
+ {GAMMA_20CD, IV_35, CI_RED, -39}, {GAMMA_20CD, IV_35, CI_GREEN, 26},
+};
+
+static unsigned char aid_command_20[] = {
+ aid_20nit_B3_1st,
+ aid_20nit_B3_2nd,
+};
+
+static unsigned char aid_command_30[] = {
+ aid_50nit_30nit_B3_1st,
+ aid_30nit_B3_2nd,
+};
+
+static unsigned char aid_command_40[] = {
+ aid_50nit_30nit_B3_1st,
+ aid_40nit_B3_2nd,
+};
+
+static unsigned char aid_command_50[] = {
+ aid_50nit_30nit_B3_1st,
+ aid_50nit_B3_2nd,
+};
+
+static unsigned char aid_command_60[] = {
+ aid_70nit_60nit_B3_1st,
+ aid_60nit_B3_2nd,
+};
+
+static unsigned char aid_command_70[] = {
+ aid_70nit_60nit_B3_1st,
+ aid_70nit_B3_2nd,
+};
+
+static unsigned char aid_command_80[] = {
+ aid_90nit_80nit_B3_1st,
+ aid_80nit_B3_2nd,
+};
+
+static unsigned char aid_command_90[] = {
+ aid_90nit_80nit_B3_1st,
+ aid_90nit_B3_2nd,
+};
+
+static unsigned char aid_command_100[] = {
+ aid_100nit_B3_1st,
+ aid_100nit_B3_2nd,
+};
+
+static unsigned char aid_command_102[] = {
+ aid_102nit_B3_1st,
+ aid_102nit_B3_2nd,
+};
+
+static unsigned char aid_command_104[] = {
+ aid_108nit_104nit_B3_1st,
+ aid_104nit_B3_2nd,
+};
+
+static unsigned char aid_command_106[] = {
+ aid_108nit_104nit_B3_1st,
+ aid_106nit_B3_2nd,
+};
+
+static unsigned char aid_command_108[] = {
+ aid_108nit_104nit_B3_1st,
+ aid_108nit_B3_2nd,
+};
+
+static unsigned char aid_command_110[] = {
+ aid_180nit_110nit_B3_1st,
+ aid_180nit_110nit_B3_2nd,
+};
+
+static unsigned char aid_command_120[] = {
+ aid_180nit_110nit_B3_1st,
+ aid_180nit_110nit_B3_2nd,
+};
+
+static unsigned char aid_command_130[] = {
+ aid_180nit_110nit_B3_1st,
+ aid_180nit_110nit_B3_2nd,
+};
+
+static unsigned char aid_command_140[] = {
+ aid_180nit_110nit_B3_1st,
+ aid_180nit_110nit_B3_2nd,
+};
+
+static unsigned char aid_command_150[] = {
+ aid_180nit_110nit_B3_1st,
+ aid_180nit_110nit_B3_2nd,
+};
+
+static unsigned char aid_command_160[] = {
+ aid_180nit_110nit_B3_1st,
+ aid_180nit_110nit_B3_2nd,
+};
+
+static unsigned char aid_command_170[] = {
+ aid_180nit_110nit_B3_1st,
+ aid_180nit_110nit_B3_2nd,
+};
+
+static unsigned char aid_command_180[] = {
+ aid_180nit_110nit_B3_1st,
+ aid_180nit_110nit_B3_2nd,
+};
+
+static unsigned char aid_command_182[] = {
+ aid_184nit_182nit_B3_1st,
+ aid_182nit_B3_2nd,
+};
+
+static unsigned char aid_command_184[] = {
+ aid_184nit_182nit_B3_1st,
+ aid_184nit_B3_2nd,
+};
+
+static unsigned char aid_command_186[] = {
+ aid_188nit_186nit_B3_1st,
+ aid_186nit_B3_2nd,
+};
+
+static unsigned char aid_command_188[] = {
+ aid_188nit_186nit_B3_1st,
+ aid_188nit_B3_2nd,
+};
+
+static unsigned char aid_command_190[] = {
+ aid_250nit_190nit_B3_1st,
+ aid_250nit_190nit_B3_2nd,
+};
+
+static unsigned char aid_command_200[] = {
+ aid_250nit_190nit_B3_1st,
+ aid_250nit_190nit_B3_2nd,
+};
+
+static unsigned char aid_command_210[] = {
+ aid_250nit_190nit_B3_1st,
+ aid_250nit_190nit_B3_2nd,
+};
+
+static unsigned char aid_command_220[] = {
+ aid_250nit_190nit_B3_1st,
+ aid_250nit_190nit_B3_2nd,
+};
+
+static unsigned char aid_command_230[] = {
+ aid_250nit_190nit_B3_1st,
+ aid_250nit_190nit_B3_2nd,
+};
+
+static unsigned char aid_command_240[] = {
+ aid_250nit_190nit_B3_1st,
+ aid_250nit_190nit_B3_2nd,
+};
+
+static unsigned char aid_command_250[] = {
+ aid_250nit_190nit_B3_1st,
+ aid_250nit_190nit_B3_2nd,
+};
+
+static unsigned char aid_command_300[] = {
+ aid_300nit_260nit_B3_1st,
+ aid_300nit_260nit_B3_2nd,
+
+};
+
+static unsigned char *aid_command_table[GAMMA_MAX] = {
+ aid_command_20,
+ aid_command_30,
+ aid_command_40,
+ aid_command_50,
+ aid_command_60,
+ aid_command_70,
+ aid_command_80,
+ aid_command_90,
+ aid_command_100,
+ aid_command_102,
+ aid_command_104,
+ aid_command_106,
+ aid_command_108,
+ aid_command_110,
+ aid_command_120,
+ aid_command_130,
+ aid_command_140,
+ aid_command_150,
+ aid_command_160,
+ aid_command_170,
+ aid_command_180,
+ aid_command_182,
+ aid_command_184,
+ aid_command_186,
+ aid_command_188,
+ aid_command_190,
+ aid_command_200,
+ aid_command_210,
+ aid_command_220,
+ aid_command_230,
+ aid_command_240,
+ aid_command_250,
+ aid_command_300
+};
+
+#endif
diff --git a/drivers/video/samsung/aid_s6e8aa0.h b/drivers/video/samsung/aid_s6e8aa0.h
index cf8058a..c06eaf8 100644
--- a/drivers/video/samsung/aid_s6e8aa0.h
+++ b/drivers/video/samsung/aid_s6e8aa0.h
@@ -15,6 +15,10 @@
#define aid_180nit_110nit_F8_18th 0x42
#define aid_180nit_110nit_F8_1st 0x59
#define aid_100nit_20nit_F8_1st 0x59
+#define aid_108nit_F8_18th 0x38
+#define aid_106nit_F8_18th 0x2F
+#define aid_104nit_F8_18th 0x25
+#define aid_102nit_F8_18th 0x1C
#define aid_100nit_F8_18th 0x12
#define aid_90nit_F8_18th 0x22
#define aid_80nit_F8_18th 0x32
@@ -36,6 +40,10 @@
#define AOR40_BASE_130 200
#define AOR40_BASE_120 186
#define AOR40_BASE_110 171
+#define AOR40_BASE_108 156
+#define AOR40_BASE_106 143
+#define AOR40_BASE_104 130
+#define AOR40_BASE_102 120
#define base_20to100 110
const struct rgb_offset_info aid_rgb_fix_table[] = {
@@ -47,6 +55,10 @@ const struct rgb_offset_info aid_rgb_fix_table[] = {
{GAMMA_130CD, IV_15, CI_RED, 1}, {GAMMA_130CD, IV_15, CI_GREEN, -1}, {GAMMA_130CD, IV_15, CI_BLUE, 5},
{GAMMA_120CD, IV_15, CI_RED, 1}, {GAMMA_120CD, IV_15, CI_GREEN, -1}, {GAMMA_120CD, IV_15, CI_BLUE, 5},
{GAMMA_110CD, IV_15, CI_RED, 1}, {GAMMA_110CD, IV_15, CI_GREEN, -1}, {GAMMA_110CD, IV_15, CI_BLUE, 5},
+ {GAMMA_108CD, IV_15, CI_RED, 1}, {GAMMA_110CD, IV_15, CI_GREEN, -1}, {GAMMA_110CD, IV_15, CI_BLUE, 5},
+ {GAMMA_106CD, IV_15, CI_RED, 1}, {GAMMA_110CD, IV_15, CI_GREEN, -1}, {GAMMA_110CD, IV_15, CI_BLUE, 5},
+ {GAMMA_104CD, IV_15, CI_RED, 1}, {GAMMA_110CD, IV_15, CI_GREEN, -1}, {GAMMA_110CD, IV_15, CI_BLUE, 5},
+ {GAMMA_102CD, IV_15, CI_RED, 1}, {GAMMA_110CD, IV_15, CI_GREEN, -1}, {GAMMA_110CD, IV_15, CI_BLUE, 5},
{GAMMA_100CD, IV_15, CI_RED, -2}, {GAMMA_100CD, IV_15, CI_GREEN, -3},
{GAMMA_90CD, IV_15, CI_RED, -6}, {GAMMA_90CD, IV_15, CI_GREEN, -7},
{GAMMA_80CD, IV_15, CI_RED, -10}, {GAMMA_80CD, IV_15, CI_GREEN, -12},
@@ -104,6 +116,26 @@ static unsigned char aid_command_100[] = {
aid_100nit_20nit_F8_1st,
};
+static unsigned char aid_command_102[] = {
+ aid_102nit_F8_18th,
+ aid_100nit_20nit_F8_1st,
+};
+
+static unsigned char aid_command_104[] = {
+ aid_104nit_F8_18th,
+ aid_100nit_20nit_F8_1st,
+};
+
+static unsigned char aid_command_106[] = {
+ aid_106nit_F8_18th,
+ aid_100nit_20nit_F8_1st,
+};
+
+static unsigned char aid_command_108[] = {
+ aid_108nit_F8_18th,
+ aid_100nit_20nit_F8_1st,
+};
+
static unsigned char aid_command_110[] = {
aid_180nit_110nit_F8_18th,
aid_180nit_110nit_F8_1st,
@@ -214,6 +246,10 @@ static unsigned char *aid_command_table[GAMMA_MAX] = {
aid_command_80,
aid_command_90,
aid_command_100,
+ aid_command_102,
+ aid_command_104,
+ aid_command_106,
+ aid_command_108,
aid_command_110,
aid_command_120,
aid_command_130,
diff --git a/drivers/video/samsung/aid_s6evr02.h b/drivers/video/samsung/aid_s6evr02.h
new file mode 100644
index 0000000..2adf731
--- /dev/null
+++ b/drivers/video/samsung/aid_s6evr02.h
@@ -0,0 +1,248 @@
+#ifndef __AID_S6EVR02_H__
+#define __AID_S6EVR02_H__
+
+#include "smart_dimming_s6evr02.h"
+
+#define aid_300nit 0xFF
+#define aid_190nit_250nit 0xFF
+#define aid_188nit 0xEA
+#define aid_186nit 0xD6
+#define aid_184nit 0xC2
+#define aid_182nit 0xAD
+#define aid_110nit_180nit 0x99
+#define aid_108nit 0xF6
+#define aid_106nit 0xEF
+#define aid_104nit 0xE8
+#define aid_102nit 0xE1
+#define aid_100nit 0xDA
+#define aid_90nit 0xC2
+#define aid_80nit 0xAB
+#define aid_70nit 0x93
+#define aid_60nit 0x7D
+#define aid_50nit 0x66
+#define aid_40nit 0x51
+#define aid_30nit 0x3C
+#define aid_20nit 0x28
+#define AOR40_BASE_188 202
+#define AOR40_BASE_186 215
+#define AOR40_BASE_184 230
+#define AOR40_BASE_182 250
+#define AOR40_BASE_180 275
+#define AOR40_BASE_170 260
+#define AOR40_BASE_160 246
+#define AOR40_BASE_150 231
+#define AOR40_BASE_140 217
+#define AOR40_BASE_130 202
+#define AOR40_BASE_120 188
+#define AOR40_BASE_110 169
+#define AOR40_BASE_108 110
+#define AOR40_BASE_106 110
+#define AOR40_BASE_104 110
+#define AOR40_BASE_102 110
+#define base_20to100 110
+
+static const struct rgb_offset_info aid_rgb_fix_table[] = {
+ {GAMMA_184CD, IV_11, CI_BLUE, 1},
+ {GAMMA_182CD, IV_11, CI_GREEN, -1}, {GAMMA_182CD, IV_11, CI_BLUE, 2},
+ {GAMMA_180CD, IV_11, CI_RED, -1}, {GAMMA_180CD, IV_11, CI_GREEN, -2}, {GAMMA_180CD, IV_11, CI_BLUE, 3},
+ {GAMMA_170CD, IV_11, CI_RED, -1}, {GAMMA_170CD, IV_11, CI_GREEN, -2}, {GAMMA_170CD, IV_11, CI_BLUE, 3},
+ {GAMMA_160CD, IV_11, CI_RED, -1}, {GAMMA_160CD, IV_11, CI_GREEN, -2}, {GAMMA_160CD, IV_11, CI_BLUE, 3},
+ {GAMMA_150CD, IV_11, CI_RED, -1}, {GAMMA_150CD, IV_11, CI_GREEN, -2}, {GAMMA_150CD, IV_11, CI_BLUE, 3},
+ {GAMMA_140CD, IV_11, CI_RED, -1}, {GAMMA_140CD, IV_11, CI_GREEN, -2}, {GAMMA_140CD, IV_11, CI_BLUE, 3},
+ {GAMMA_130CD, IV_11, CI_RED, -1}, {GAMMA_130CD, IV_11, CI_GREEN, -2}, {GAMMA_130CD, IV_11, CI_BLUE, 3},
+ {GAMMA_120CD, IV_11, CI_RED, -1}, {GAMMA_120CD, IV_11, CI_GREEN, -2}, {GAMMA_120CD, IV_11, CI_BLUE, 3},
+ {GAMMA_110CD, IV_11, CI_RED, -1}, {GAMMA_110CD, IV_11, CI_GREEN, -2}, {GAMMA_110CD, IV_11, CI_BLUE, 3},
+ {GAMMA_108CD, IV_11, CI_RED, -1}, {GAMMA_108CD, IV_11, CI_GREEN, -2}, {GAMMA_104CD, IV_11, CI_BLUE, 3},
+ {GAMMA_106CD, IV_11, CI_RED, -1}, {GAMMA_106CD, IV_11, CI_GREEN, -1}, {GAMMA_104CD, IV_11, CI_BLUE, 3},
+ {GAMMA_104CD, IV_11, CI_RED, -2}, {GAMMA_104CD, IV_11, CI_GREEN, -1}, {GAMMA_104CD, IV_11, CI_BLUE, 4},
+ {GAMMA_102CD, IV_11, CI_RED, -2}, {GAMMA_102CD, IV_11, CI_BLUE, 4},
+ {GAMMA_100CD, IV_11, CI_RED, -2}, {GAMMA_100CD, IV_11, CI_BLUE, 5},
+ {GAMMA_90CD, IV_11, CI_RED, -5}, {GAMMA_90CD, IV_11, CI_BLUE, 6},
+ {GAMMA_80CD, IV_11, CI_RED, -6}, {GAMMA_80CD, IV_11, CI_BLUE, 8},
+ {GAMMA_70CD, IV_11, CI_RED, -7}, {GAMMA_70CD, IV_11, CI_BLUE, 11},
+ {GAMMA_60CD, IV_11, CI_RED, -10}, {GAMMA_60CD, IV_11, CI_BLUE, 14},
+ {GAMMA_50CD, IV_11, CI_RED, -12}, {GAMMA_50CD, IV_11, CI_BLUE, 19},
+ {GAMMA_40CD, IV_11, CI_RED, -18}, {GAMMA_40CD, IV_11, CI_BLUE, 24},
+ {GAMMA_30CD, IV_11, CI_RED, -18}, {GAMMA_30CD, IV_11, CI_BLUE, 31},
+ {GAMMA_20CD, IV_11, CI_RED, -18}, {GAMMA_20CD, IV_11, CI_BLUE, 39},
+ {GAMMA_90CD, IV_23, CI_GREEN, -3},
+ {GAMMA_80CD, IV_23, CI_RED, -1}, {GAMMA_80CD, IV_23, CI_GREEN, -4},
+ {GAMMA_70CD, IV_23, CI_RED, -3}, {GAMMA_70CD, IV_23, CI_GREEN, -6},
+ {GAMMA_60CD, IV_23, CI_RED, -4}, {GAMMA_60CD, IV_23, CI_GREEN, -9},
+ {GAMMA_50CD, IV_23, CI_RED, -7}, {GAMMA_50CD, IV_23, CI_GREEN, -9},
+ {GAMMA_40CD, IV_23, CI_RED, -12}, {GAMMA_40CD, IV_23, CI_GREEN, -16},
+ {GAMMA_30CD, IV_23, CI_RED, -17}, {GAMMA_30CD, IV_23, CI_GREEN, -16}, {GAMMA_30CD, IV_23, CI_BLUE, 2},
+ {GAMMA_20CD, IV_23, CI_RED, -22}, {GAMMA_20CD, IV_23, CI_GREEN, -16}, {GAMMA_20CD, IV_23, CI_BLUE, 9},
+ {GAMMA_30CD, IV_35, CI_RED, -3}, {GAMMA_30CD, IV_35, CI_GREEN, -14},
+ {GAMMA_20CD, IV_35, CI_RED, -11}, {GAMMA_20CD, IV_35, CI_GREEN, -30},
+};
+
+static unsigned char aid_command_20[] = {
+ aid_20nit
+};
+
+static unsigned char aid_command_30[] = {
+ aid_30nit
+};
+
+static unsigned char aid_command_40[] = {
+ aid_40nit
+};
+
+static unsigned char aid_command_50[] = {
+ aid_50nit
+};
+
+static unsigned char aid_command_60[] = {
+ aid_60nit
+};
+
+static unsigned char aid_command_70[] = {
+ aid_70nit
+};
+
+static unsigned char aid_command_80[] = {
+ aid_80nit
+};
+
+static unsigned char aid_command_90[] = {
+ aid_90nit
+};
+
+static unsigned char aid_command_100[] = {
+ aid_100nit
+};
+
+static unsigned char aid_command_102[] = {
+ aid_102nit
+};
+
+static unsigned char aid_command_104[] = {
+ aid_104nit
+};
+
+static unsigned char aid_command_106[] = {
+ aid_106nit
+};
+
+static unsigned char aid_command_108[] = {
+ aid_108nit
+};
+
+static unsigned char aid_command_110[] = {
+ aid_110nit_180nit
+};
+
+static unsigned char aid_command_120[] = {
+ aid_110nit_180nit
+};
+
+static unsigned char aid_command_130[] = {
+ aid_110nit_180nit
+};
+
+static unsigned char aid_command_140[] = {
+ aid_110nit_180nit
+};
+
+static unsigned char aid_command_150[] = {
+ aid_110nit_180nit
+};
+
+static unsigned char aid_command_160[] = {
+ aid_110nit_180nit
+};
+
+static unsigned char aid_command_170[] = {
+ aid_110nit_180nit
+};
+
+static unsigned char aid_command_180[] = {
+ aid_110nit_180nit
+};
+
+static unsigned char aid_command_182[] = {
+ aid_182nit
+};
+
+static unsigned char aid_command_184[] = {
+ aid_184nit
+};
+
+static unsigned char aid_command_186[] = {
+ aid_186nit
+};
+
+static unsigned char aid_command_188[] = {
+ aid_188nit
+};
+
+static unsigned char aid_command_190[] = {
+ aid_190nit_250nit
+};
+
+static unsigned char aid_command_200[] = {
+ aid_190nit_250nit
+};
+
+static unsigned char aid_command_210[] = {
+ aid_190nit_250nit
+};
+
+static unsigned char aid_command_220[] = {
+ aid_190nit_250nit
+};
+
+static unsigned char aid_command_230[] = {
+ aid_190nit_250nit
+};
+
+static unsigned char aid_command_240[] = {
+ aid_190nit_250nit
+};
+
+static unsigned char aid_command_250[] = {
+ aid_190nit_250nit
+};
+
+static unsigned char aid_command_300[] = {
+ aid_300nit
+};
+
+static unsigned char *aid_command_table[GAMMA_MAX] = {
+ aid_command_20,
+ aid_command_30,
+ aid_command_40,
+ aid_command_50,
+ aid_command_60,
+ aid_command_70,
+ aid_command_80,
+ aid_command_90,
+ aid_command_100,
+ aid_command_102,
+ aid_command_104,
+ aid_command_106,
+ aid_command_108,
+ aid_command_110,
+ aid_command_120,
+ aid_command_130,
+ aid_command_140,
+ aid_command_150,
+ aid_command_160,
+ aid_command_170,
+ aid_command_180,
+ aid_command_182,
+ aid_command_184,
+ aid_command_186,
+ aid_command_188,
+ aid_command_190,
+ aid_command_200,
+ aid_command_210,
+ aid_command_220,
+ aid_command_230,
+ aid_command_240,
+ aid_command_250,
+ aid_command_300
+};
+
+#endif
diff --git a/drivers/video/samsung/ea8061_param.h b/drivers/video/samsung/ea8061_param.h
new file mode 100644
index 0000000..e40a3d9
--- /dev/null
+++ b/drivers/video/samsung/ea8061_param.h
@@ -0,0 +1,391 @@
+#ifndef __EA8061_PARAM_H__
+#define __EA8061_PARAM_H__
+
+#define GAMMA_PARAM_SIZE 34
+#define ACL_PARAM_SIZE ARRAY_SIZE(acl_cutoff_33)
+#define ELVSS_PARAM_SIZE ARRAY_SIZE(elvss_control_set_20)
+#define AID_PARAM_SIZE ARRAY_SIZE(SEQ_LTPS_AID)
+
+enum {
+ GAMMA_20CD,
+ GAMMA_30CD,
+ GAMMA_40CD,
+ GAMMA_50CD,
+ GAMMA_60CD,
+ GAMMA_70CD,
+ GAMMA_80CD,
+ GAMMA_90CD,
+ GAMMA_100CD,
+ GAMMA_102CD,
+ GAMMA_104CD,
+ GAMMA_106CD,
+ GAMMA_108CD,
+ GAMMA_110CD,
+ GAMMA_120CD,
+ GAMMA_130CD,
+ GAMMA_140CD,
+ GAMMA_150CD,
+ GAMMA_160CD,
+ GAMMA_170CD,
+ GAMMA_180CD,
+ GAMMA_182CD,
+ GAMMA_184CD,
+ GAMMA_186CD,
+ GAMMA_188CD,
+ GAMMA_190CD,
+ GAMMA_200CD,
+ GAMMA_210CD,
+ GAMMA_220CD,
+ GAMMA_230CD,
+ GAMMA_240CD,
+ GAMMA_250CD,
+ GAMMA_300CD,
+ GAMMA_MAX
+};
+
+static const unsigned char SEQ_APPLY_LEVEL_2_KEY_ENABLE[] = {
+ 0xF0,
+ 0x5A, 0x5A
+};
+
+static const unsigned char SEQ_APPLY_LEVEL_2_KEY_DISABLE[] = {
+ 0xF0,
+ 0xA5, 0xA5
+};
+
+static const unsigned char SEQ_APPLY_LEVEL_3_KEY[] = {
+ 0xFC,
+ 0x5A, 0x5A
+};
+
+static const unsigned char SEQ_FRAME_GAMMA_UPDATE_KEY[] = {
+ 0xF7,
+ 0x5A, 0x5A
+};
+
+static const unsigned char SEQ_FRAME_GAMMA_UPDATE_KEY2[] = {
+ 0xF7,
+ 0xA5, 0xA5
+};
+
+static const unsigned char SEQ_SLEEP_OUT[] = {
+ 0x11,
+ 0x00, 0x00
+};
+
+static const unsigned char SEQ_SLEEP_IN[] = {
+ 0x10,
+ 0x00, 0x00
+};
+
+static const unsigned char SEQ_PANEL_CONDITION_SET[] = {
+ 0xC4,
+ 0x4E, 0xBD, 0x00, 0x00, 0x58, 0xA7, 0x0B, 0x34, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x0B, 0x92, 0x0B, 0x92, 0x08, 0x08, 0x07,
+ 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x04,
+ 0x04,
+};
+
+static const unsigned char SEQ_M4_PANEL_CONDITION_SET[] = {
+ 0xC4,
+ 0x4E, 0xBD, 0x00, 0x00, 0x58, 0xA7, 0x0B, 0x34, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x0B, 0x92, 0x0B, 0x92, 0x08, 0x08, 0x07,
+ 0x30, 0x50, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x04,
+ 0x04,
+};
+
+static const unsigned char SEQ_GAMMA_CONDITION_SET[] = {
+ 0xCA,
+ 0x00, 0xE8, 0x00, 0xF7, 0x01, 0x03, 0xDB, 0xDB, 0xDC, 0xD9,
+ 0xD8, 0xDA, 0xCB, 0xC8, 0xCB, 0xD4, 0xD3, 0xD7, 0xE6, 0xE6,
+ 0xEA, 0xE2, 0xE4, 0xE5, 0xCE, 0xC3, 0xCF, 0xB9, 0x9D, 0xDE,
+ 0x11, 0x00
+};
+
+static const unsigned char SEQ_M4_GAMMA_CONDITION_SET[] = {
+ 0xCA,
+ 0x00, 0xB6, 0x00, 0xB7, 0x00, 0xD5, 0xD7, 0xDA, 0xDC, 0xD3,
+ 0xD6, 0xD8, 0xBC, 0xC0, 0xC3, 0xBF, 0xC5, 0xCC, 0xD0, 0xD5,
+ 0xE0, 0xC8, 0xD1, 0xD8, 0x96, 0xAF, 0xB9, 0x82, 0xB6, 0xC2,
+ 0x11, 0x00,
+};
+
+static const unsigned char SEQ_LTPS_AID[] = {
+ 0xB3,
+ 0x00, 0x0A,
+};
+
+static const unsigned char ELVSS_CONTROL_SET[] = {
+ 0xB2, 0x0E,
+ 0xB4, 0xA0, 0x00, 0x00, 0x00, 0x00
+};
+
+static const unsigned char SEQ_DISPLAY_CONDITION_SET[] = {
+ 0x36,
+ 0x02, 0x00
+};
+
+static const unsigned char SEQ_ETC_WCABC_CONTROL[] = {
+ 0x55,
+ 0x00, 0x00
+};
+
+static const unsigned char SEQ_SLEW_REV00[] = {
+ 0xB4,
+ 0x33, 0x0E, 0x00
+};
+
+static const unsigned char SEQ_SLEW_REV01[] = {
+ 0xB4,
+ 0x33, 0x0E, 0x00
+};
+
+static const unsigned char SEQ_SLEW_REV02[] = {
+ 0xB4,
+ 0x33, 0x09, 0x00
+};
+
+static const unsigned char SEQ_SLEW_REV03[] = {
+ 0xB4,
+ 0x33, 0x0D, 0x00
+};
+
+static const unsigned char SEQ_SLEW_REV04[] = {
+ 0xB4,
+ 0x33, 0x0A, 0x00
+};
+
+static const unsigned char SEQ_M4_SLEW[] = {
+ 0xB4,
+ 0x33, 0x0D, 0x00
+};
+
+static const unsigned char SEQ_DISPLAY_ON[] = {
+ 0x29,
+ 0x00, 0x00
+};
+
+static const unsigned char SEQ_DISPLAY_OFF[] = {
+ 0x28,
+ 0x00, 0x00
+};
+
+enum {
+ ELVSS_STATUS_20,
+ ELVSS_STATUS_30,
+ ELVSS_STATUS_40,
+ ELVSS_STATUS_50,
+ ELVSS_STATUS_60,
+ ELVSS_STATUS_70,
+ ELVSS_STATUS_80,
+ ELVSS_STATUS_90,
+ ELVSS_STATUS_100,
+ ELVSS_STATUS_110,
+ ELVSS_STATUS_120,
+ ELVSS_STATUS_130,
+ ELVSS_STATUS_140,
+ ELVSS_STATUS_150,
+ ELVSS_STATUS_160,
+ ELVSS_STATUS_170,
+ ELVSS_STATUS_180,
+ ELVSS_STATUS_190,
+ ELVSS_STATUS_200,
+ ELVSS_STATUS_210,
+ ELVSS_STATUS_220,
+ ELVSS_STATUS_230,
+ ELVSS_STATUS_240,
+ ELVSS_STATUS_250,
+ ELVSS_STATUS_300,
+ ELVSS_STATUS_MAX
+};
+
+static const unsigned char elvss_control_set_20[] = {
+ 0xB2, 0x20,
+ 0xB4, 0xA0, 0x00, 0x00, 0x00, 0x00
+};
+
+static const unsigned char elvss_control_set_30[] = {
+ 0xB2, 0x20,
+ 0xB4, 0xA0, 0x00, 0x00, 0x00, 0x00
+};
+
+static const unsigned char elvss_control_set_40[] = {
+ 0xB2, 0x20,
+ 0xB4, 0xA0, 0x00, 0x00, 0x00, 0x00
+};
+
+static const unsigned char elvss_control_set_50[] = {
+ 0xB2, 0x1F,
+ 0xB4, 0xA0, 0x00, 0x00, 0x00, 0x00
+};
+
+static const unsigned char elvss_control_set_60[] = {
+ 0xB2, 0x1F,
+ 0xB4, 0xA0, 0x00, 0x00, 0x00, 0x00
+};
+
+static const unsigned char elvss_control_set_70[] = {
+ 0xB2, 0x1F,
+ 0xB4, 0xA0, 0x00, 0x00, 0x00, 0x00
+};
+
+static const unsigned char elvss_control_set_80[] = {
+ 0xB2, 0x1E,
+ 0xB4, 0xA0, 0x00, 0x00, 0x00, 0x00
+};
+
+static const unsigned char elvss_control_set_90[] = {
+ 0xB2, 0x1E,
+ 0xB4, 0xA0, 0x00, 0x00, 0x00, 0x00
+};
+
+static const unsigned char elvss_control_set_100[] = {
+ 0xB2, 0x1C,
+ 0xB4, 0xA0, 0x00, 0x00, 0x00, 0x00
+};
+
+static const unsigned char elvss_control_set_110[] = {
+ 0xB2, 0x1B,
+ 0xB4, 0xA0, 0x00, 0x00, 0x00, 0x00
+};
+
+static const unsigned char elvss_control_set_120[] = {
+ 0xB2, 0x19,
+ 0xB4, 0xA0, 0x00, 0x00, 0x00, 0x00
+};
+
+static const unsigned char elvss_control_set_130[] = {
+ 0xB2, 0x17,
+ 0xB4, 0xA0, 0x00, 0x00, 0x00, 0x00
+};
+
+static const unsigned char elvss_control_set_140[] = {
+ 0xB2, 0x16,
+ 0xB4, 0xA0, 0x00, 0x00, 0x00, 0x00
+};
+
+static const unsigned char elvss_control_set_150[] = {
+ 0xB2, 0x14,
+ 0xB4, 0xA0, 0x00, 0x00, 0x00, 0x00
+};
+
+static const unsigned char elvss_control_set_160[] = {
+ 0xB2, 0x12,
+ 0xB4, 0xA0, 0x00, 0x00, 0x00, 0x00
+};
+
+static const unsigned char elvss_control_set_170[] = {
+ 0xB2, 0x10,
+ 0xB4, 0xA0, 0x00, 0x00, 0x00, 0x00
+};
+
+static const unsigned char elvss_control_set_180[] = {
+ 0xB2, 0x0F,
+ 0xB4, 0xA0, 0x00, 0x00, 0x00, 0x00
+};
+
+static const unsigned char elvss_control_set_190[] = {
+ 0xB2, 0x15,
+ 0xB4, 0xA0, 0x00, 0x00, 0x00, 0x00
+};
+
+static const unsigned char elvss_control_set_200[] = {
+ 0xB2, 0x14,
+ 0xB4, 0xA0, 0x00, 0x00, 0x00, 0x00
+};
+
+static const unsigned char elvss_control_set_210[] = {
+ 0xB2, 0x13,
+ 0xB4, 0xA0, 0x00, 0x00, 0x00, 0x00
+};
+
+static const unsigned char elvss_control_set_220[] = {
+ 0xB2, 0x12,
+ 0xB4, 0xA0, 0x00, 0x00, 0x00, 0x00
+};
+
+static const unsigned char elvss_control_set_230[] = {
+ 0xB2, 0x11,
+ 0xB4, 0xA0, 0x00, 0x00, 0x00, 0x00
+};
+
+static const unsigned char elvss_control_set_240[] = {
+ 0xB2, 0x10,
+ 0xB4, 0xA0, 0x00, 0x00, 0x00, 0x00
+};
+
+static const unsigned char elvss_control_set_250[] = {
+ 0xB2, 0x10,
+ 0xB4, 0xA0, 0x00, 0x00, 0x00, 0x00
+};
+
+static const unsigned char elvss_control_set_300[] = {
+ 0xB2, 0x0B,
+ 0xB4, 0xA0, 0x00, 0x00, 0x00, 0x00
+};
+
+
+const unsigned char *ELVSS_CONTROL_TABLE[ELVSS_STATUS_MAX] = {
+ elvss_control_set_20,
+ elvss_control_set_30,
+ elvss_control_set_40,
+ elvss_control_set_50,
+ elvss_control_set_60,
+ elvss_control_set_70,
+ elvss_control_set_80,
+ elvss_control_set_90,
+ elvss_control_set_100,
+ elvss_control_set_110,
+ elvss_control_set_120,
+ elvss_control_set_130,
+ elvss_control_set_140,
+ elvss_control_set_150,
+ elvss_control_set_160,
+ elvss_control_set_170,
+ elvss_control_set_180,
+ elvss_control_set_190,
+ elvss_control_set_200,
+ elvss_control_set_210,
+ elvss_control_set_220,
+ elvss_control_set_230,
+ elvss_control_set_240,
+ elvss_control_set_250,
+ elvss_control_set_300
+};
+
+
+enum {
+ ACL_STATUS_0P = 0,
+ ACL_STATUS_33P,
+ ACL_STATUS_40P,
+ ACL_STATUS_50P,
+ ACL_STATUS_MAX
+};
+
+static const unsigned char SEQ_ACL_OFF[] = {
+ 0x55, 0x00,
+ 0x00
+};
+
+static const unsigned char acl_cutoff_33[] = {
+ 0x55, 0x01,
+ 0x00
+};
+
+static const unsigned char acl_cutoff_40[] = {
+ 0x55, 0x02,
+ 0x00
+};
+
+static const unsigned char acl_cutoff_50[] = {
+ 0x55, 0x03,
+ 0x00
+};
+
+static const unsigned char *ACL_CUTOFF_TABLE[ACL_STATUS_MAX] = {
+ SEQ_ACL_OFF,
+ acl_cutoff_33,
+ acl_cutoff_40,
+ acl_cutoff_50,
+};
+#endif /* __EA8061_PARAM_H__ */
diff --git a/drivers/video/samsung/ea8061_volt_tbl.h b/drivers/video/samsung/ea8061_volt_tbl.h
new file mode 100644
index 0000000..990e80e
--- /dev/null
+++ b/drivers/video/samsung/ea8061_volt_tbl.h
@@ -0,0 +1,667 @@
+#ifndef __REF_VOLT_TABLE_H__
+#define __REF_VOLT_TABLE_H__
+
+
+static u32 volt_table_vt[16] = {
+ 399769600, 391840286, 383910971, 375981657,
+ 368052342, 360123028, 352193714, 344264399,
+ 336335085, 328405771, 308582485, 301974723,
+ 295366961, 288759199, 282151437, 276865227,
+};
+
+static u32 volt_table_v255[505] = {
+ 369373895, 368713119, 368052342, 367391566, 366730790, 366070014, 365409238, 364748461,
+ 364087685, 363426909, 362766133, 362105357, 361444580, 360783804, 360123028, 359462252,
+ 358801476, 358140700, 357479923, 356819147, 356158371, 355497595, 354836819, 354176042,
+ 353515266, 352854490, 352193714, 351532938, 350872161, 350211385, 349550609, 348889833,
+ 348229057, 347568280, 346907504, 346246728, 345585952, 344925176, 344264399, 343603623,
+ 342942847, 342282071, 341621295, 340960518, 340299742, 339638966, 338978190, 338317414,
+ 337656637, 336995861, 336335085, 335674309, 335013533, 334352756, 333691980, 333031204,
+ 332370428, 331709652, 331048875, 330388099, 329727323, 329066547, 328405771, 327744994,
+ 327084218, 326423442, 325762666, 325101890, 324441113, 323780337, 323119561, 322458785,
+ 321798009, 321137232, 320476456, 319815680, 319154904, 318494128, 317833351, 317172575,
+ 316511799, 315851023, 315190247, 314529470, 313868694, 313207918, 312547142, 311886366,
+ 311225589, 310564813, 309904037, 309243261, 308582485, 307921708, 307260932, 306600156,
+ 305939380, 305278604, 304617827, 303957051, 303296275, 302635499, 301974723, 301313946,
+ 300653170, 299992394, 299331618, 298670842, 298010065, 297349289, 296688513, 296027737,
+ 295366961, 294706184, 294045408, 293384632, 292723856, 292063080, 291402303, 290741527,
+ 290080751, 289419975, 288759199, 288098422, 287437646, 286776870, 286116094, 285455318,
+ 284794541, 284133765, 283472989, 282812213, 282151437, 281490660, 280829884, 280169108,
+ 279508332, 278847556, 278186780, 277526003, 276865227, 276204451, 275543675, 274882899,
+ 274222122, 273561346, 272900570, 272239794, 271579018, 270918241, 270257465, 269596689,
+ 268935913, 268275137, 267614360, 266953584, 266292808, 265632032, 264971256, 264310479,
+ 263649703, 262988927, 262328151, 261667375, 261006598, 260345822, 259685046, 259024270,
+ 258363494, 257702717, 257041941, 256381165, 255720389, 255059613, 254398836, 253738060,
+ 253077284, 252416508, 251755732, 251094955, 250434179, 249773403, 249112627, 248451851,
+ 247791074, 247130298, 246469522, 245808746, 245147970, 244487193, 243826417, 243165641,
+ 242504865, 241844089, 241183312, 240522536, 239861760, 239200984, 238540208, 237879431,
+ 237218655, 236557879, 235897103, 235236327, 234575550, 233914774, 233253998, 232593222,
+ 231932446, 231271669, 230610893, 229950117, 229289341, 228628565, 227967788, 227307012,
+ 226646236, 225985460, 225324684, 224663907, 224003131, 223342355, 222681579, 222020803,
+ 221360026, 220699250, 220038474, 219377698, 218716922, 218056145, 217395369, 216734593,
+ 216073817, 215413041, 214752264, 214091488, 213430712, 212769936, 212109160, 211448383,
+ 210787607, 210126831, 209466055, 208805279, 208144502, 207483726, 206822950, 206162174,
+ 205501398, 204840621, 204179845, 203519069, 202858293, 202197517, 201536740, 200875964,
+ 200215188, 199554412, 198893636, 198232860, 197572083, 196911307, 196250531, 195589755,
+ 194928979, 194268202, 193607426, 192946650, 192285874, 191625098, 190964321, 190303545,
+ 189642769, 188981993, 188321217, 187660440, 186999664, 186338888, 185678112, 185017336,
+ 184356559, 183695783, 183035007, 182374231, 181713455, 181052678, 180391902, 179731126,
+ 179070350, 178409574, 177748797, 177088021, 176427245, 175766469, 175105693, 174444916,
+ 173784140, 173123364, 172462588, 171801812, 171141035, 170480259, 169819483, 169158707,
+ 168497931, 167837154, 167176378, 166515602, 165854826, 165194050, 164533273, 163872497,
+ 163211721, 162550945, 161890169, 161229392, 160568616, 159907840, 159247064, 158586288,
+ 157925511, 157264735, 156603959, 155943183, 155282407, 154621630, 153960854, 153300078,
+ 152639302, 151978526, 151317749, 150656973, 149996197, 149335421, 148674645, 148013868,
+ 147353092, 146692316, 146031540, 145370764, 144709987, 144049211, 143388435, 142727659,
+ 142066883, 141406106, 140745330, 140084554, 139423778, 138763002, 138102225, 137441449,
+ 136780673, 136119897, 135459121, 134798344, 134137568, 133476792, 132816016, 132155240,
+ 131494463, 130833687, 130172911, 129512135, 128851359, 128190582, 127529806, 126869030,
+ 126208254, 125547478, 124886701, 124225925, 123565149, 122904373, 122243597, 121582820,
+ 120922044, 120261268, 119600492, 118939716, 118278940, 117618163, 116957387, 116296611,
+ 115635835, 114975059, 114314282, 113653506, 112992730, 112331954, 111671178, 111010401,
+ 110349625, 109688849, 109028073, 108367297, 107706520, 107045744, 106384968, 105724192,
+ 105063416, 104402639, 103741863, 103081087, 102420311, 101759535, 101098758, 100437982,
+ 99777206, 99116430, 98455654, 97794877, 97134101, 96473325, 95812549, 95151773,
+ 94490996, 93830220, 93169444, 92508668, 91847892, 91187115, 90526339, 89865563,
+ 89204787, 88544011, 87883234, 87222458, 86561682, 85900906, 85240130, 84579353,
+ 83918577, 83257801, 82597025, 81936249, 81275472, 80614696, 79953920, 79293144,
+ 78632368, 77971591, 77310815, 76650039, 75989263, 75328487, 74667710, 74006934,
+ 73346158, 72685382, 72024606, 71363829, 70703053, 70042277, 69381501, 68720725,
+ 68059948, 67399172, 66738396, 66077620, 65416844, 64756067, 64095291, 63434515,
+ 62773739, 62112963, 61452186, 60791410, 60130634, 59469858, 58809082, 58148305,
+ 57487529, 56826753, 56165977, 55505201, 54844424, 54183648, 53522872, 52862096,
+ 52201320, 51540543, 50879767, 50218991, 49558215, 48897439, 48236662, 47575886,
+ 46915110, 46254334, 45593558, 44932781, 44272005, 43611229, 42950453, 42289677,
+ 41628900, 40968124, 40307348, 39646572, 38985796, 38325020, 37664243, 37003467,
+ 36342691
+};
+
+static u32 volt_table_cv_64_dv_320[256] = {
+ 13107, 13312, 13516, 13721, 13926, 14131, 14336, 14540,
+ 14745, 14950, 15155, 15360, 15564, 15769, 15974, 16179,
+ 16384, 16588, 16793, 16998, 17203, 17408, 17612, 17817,
+ 18022, 18227, 18432, 18636, 18841, 19046, 19251, 19456,
+ 19660, 19865, 20070, 20275, 20480, 20684, 20889, 21094,
+ 21299, 21504, 21708, 21913, 22118, 22323, 22528, 22732,
+ 22937, 23142, 23347, 23552, 23756, 23961, 24166, 24371,
+ 24576, 24780, 24985, 25190, 25395, 25600, 25804, 26009,
+ 26214, 26419, 26624, 26828, 27033, 27238, 27443, 27648,
+ 27852, 28057, 28262, 28467, 28672, 28876, 29081, 29286,
+ 29491, 29696, 29900, 30105, 30310, 30515, 30720, 30924,
+ 31129, 31334, 31539, 31744, 31948, 32153, 32358, 32563,
+ 32768, 32972, 33177, 33382, 33587, 33792, 33996, 34201,
+ 34406, 34611, 34816, 35020, 35225, 35430, 35635, 35840,
+ 36044, 36249, 36454, 36659, 36864, 37068, 37273, 37478,
+ 37683, 37888, 38092, 38297, 38502, 38707, 38912, 39116,
+ 39321, 39526, 39731, 39936, 40140, 40345, 40550, 40755,
+ 40960, 41164, 41369, 41574, 41779, 41984, 42188, 42393,
+ 42598, 42803, 43008, 43212, 43417, 43622, 43827, 44032,
+ 44236, 44441, 44646, 44851, 45056, 45260, 45465, 45670,
+ 45875, 46080, 46284, 46489, 46694, 46899, 47104, 47308,
+ 47513, 47718, 47923, 48128, 48332, 48537, 48742, 48947,
+ 49152, 49356, 49561, 49766, 49971, 50176, 50380, 50585,
+ 50790, 50995, 51200, 51404, 51609, 51814, 52019, 52224,
+ 52428, 52633, 52838, 53043, 53248, 53452, 53657, 53862,
+ 54067, 54272, 54476, 54681, 54886, 55091, 55296, 55500,
+ 55705, 55910, 56115, 56320, 56524, 56729, 56934, 57139,
+ 57344, 57548, 57753, 57958, 58163, 58368, 58572, 58777,
+ 58982, 59187, 59392, 59596, 59801, 60006, 60211, 60416,
+ 60620, 60825, 61030, 61235, 61440, 61644, 61849, 62054,
+ 62259, 62464, 62668, 62873, 63078, 63283, 63488, 63692,
+ 63897, 64102, 64307, 64512, 64716, 64921, 65126, 65331,
+};
+
+static const u32 gamma_300_gra_table[256] = {
+ 0, 2, 7, 17, 32, 53, 78, 110,
+ 148, 191, 241, 298, 361, 430, 506, 589,
+ 679, 776, 880, 991, 1109, 1235, 1368, 1508,
+ 1657, 1812, 1975, 2147, 2325, 2512, 2706, 2909,
+ 3119, 3338, 3564, 3799, 4042, 4293, 4553, 4820,
+ 5096, 5381, 5674, 5975, 6285, 6604, 6931, 7267,
+ 7611, 7965, 8327, 8697, 9077, 9465, 9863, 10269,
+ 10684, 11109, 11542, 11984, 12436, 12896, 13366, 13845,
+ 14333, 14830, 15337, 15852, 16378, 16912, 17456, 18009,
+ 18572, 19144, 19726, 20317, 20918, 21528, 22148, 22778,
+ 23417, 24066, 24724, 25392, 26070, 26758, 27456, 28163,
+ 28880, 29607, 30344, 31090, 31847, 32613, 33390, 34176,
+ 34973, 35779, 36596, 37422, 38259, 39106, 39963, 40830,
+ 41707, 42594, 43492, 44399, 45317, 46246, 47184, 48133,
+ 49092, 50062, 51042, 52032, 53032, 54043, 55065, 56097,
+ 57139, 58192, 59255, 60329, 61413, 62508, 63613, 64729,
+ 65856, 66993, 68141, 69299, 70469, 71648, 72839, 74040,
+ 75252, 76475, 77708, 78952, 80207, 81473, 82750, 84037,
+ 85336, 86645, 87965, 89296, 90638, 91990, 93354, 94729,
+ 96114, 97511, 98919, 100337, 101767, 103208, 104659, 106122,
+ 107596, 109081, 110577, 112085, 113603, 115132, 116673, 118225,
+ 119788, 121362, 122948, 124544, 126152, 127772, 129402, 131044,
+ 132697, 134361, 136037, 137724, 139422, 141132, 142853, 144586,
+ 146330, 148085, 149852, 151630, 153419, 155220, 157033, 158857,
+ 160692, 162540, 164398, 166268, 168150, 170043, 171948, 173864,
+ 175792, 177731, 179683, 181645, 183620, 185606, 187603, 189613,
+ 191634, 193667, 195711, 197767, 199835, 201915, 204006, 206109,
+ 208224, 210351, 212489, 214640, 216802, 218976, 221161, 223359,
+ 225569, 227790, 230023, 232268, 234525, 236794, 239075, 241368,
+ 243672, 245989, 248318, 250658, 253011, 255375, 257752, 260141,
+ 262541, 264954, 267379, 269815, 272264, 274725, 277198, 279683,
+ 282180, 284689, 287211, 289744, 292290, 294848, 297418, 300000
+};
+
+static const u32 gamma_control_set_21[] = {
+ 0, 9, 38, 89, 163, 260, 381, 526,
+ 697, 892, 1113, 1359, 1632, 1930, 2255, 2607,
+ 2985, 3391, 3823, 4283, 4770, 5284, 5826, 6396,
+ 6994, 7620, 8274, 8957, 9668, 10407, 11175, 11971,
+ 12797, 13651, 14534, 15446, 16388, 17358, 18358, 19387,
+ 20446, 21534, 22652, 23799, 24976, 26183, 27420, 28687,
+ 29983, 31310, 32667, 34054, 35471, 36919, 38397, 39905,
+ 41444, 43014, 44614, 46244, 47906, 49598, 51321, 53074,
+ 54859, 56674, 58521, 60399, 62307, 64247, 66218, 68220,
+ 70253, 72318, 74414, 76542, 78700, 80891, 83113, 85366,
+ 87651, 89968, 92316, 94696, 97108, 99551, 102027, 104534,
+ 107073, 109644, 112248, 114883, 117550, 120249, 122980, 125744,
+ 128540, 131367, 134228, 137120, 140045, 143002, 145991, 149013,
+ 152068, 155155, 158274, 161426, 164610, 167827, 171077, 174359,
+ 177674, 181022, 184403, 187816, 191262, 194741, 198253, 201797,
+ 205375, 208985, 212629, 216305, 220015, 223758, 227533, 231342,
+ 235184, 239059, 242967, 246909, 250883, 254891, 258932, 263007,
+ 267115, 271256, 275431, 279639, 283880, 288155, 292464, 296806,
+ 301181, 305590, 310033, 314509, 319019, 323562, 328139, 332750,
+ 337394, 342073, 346785, 351530, 356310, 361123, 365971, 370852,
+ 375767, 380715, 385698, 390715, 395766, 400851, 405969, 411122,
+ 416309, 421530, 426785, 432074, 437397, 442754, 448146, 453572,
+ 459032, 464526, 470054, 475617, 481214, 486845, 492511, 498211,
+ 503945, 509714, 515517, 521355, 527227, 533133, 539074, 545050,
+ 551060, 557104, 563183, 569297, 575445, 581628, 587845, 594097,
+ 600384, 606705, 613061, 619452, 625877, 632338, 638833, 645362,
+ 651927, 658526, 665161, 671830, 678533, 685272, 692046, 698854,
+ 705698, 712576, 719490, 726438, 733421, 740440, 747493, 754581,
+ 761705, 768863, 776057, 783286, 790550, 797848, 805183, 812552,
+ 819956, 827396, 834871, 842381, 849926, 857506, 865122, 872773,
+ 880460, 888181, 895938, 903731, 911558, 919421, 927320, 935254,
+ 943223, 951228, 959268, 967343, 975454, 983601, 991783, 1000000
+};
+
+static const u32 gamma_control_set_213[] = {
+ 0, 8, 33, 78, 144, 231, 341, 473,
+ 628, 807, 1010, 1237, 1489, 1766, 2067, 2395,
+ 2747, 3126, 3531, 3962, 4419, 4903, 5413, 5951,
+ 6516, 7107, 7727, 8373, 9048, 9750, 10480, 11238,
+ 12024, 12839, 13682, 14553, 15453, 16381, 17339, 18325,
+ 19341, 20385, 21459, 22561, 23694, 24855, 26047, 27268,
+ 28518, 29798, 31109, 32449, 33819, 35219, 36650, 38111,
+ 39602, 41123, 42675, 44258, 45871, 47515, 49189, 50894,
+ 52630, 54397, 56196, 58025, 59885, 61776, 63699, 65653,
+ 67638, 69655, 71703, 73782, 75894, 78036, 80211, 82417,
+ 84655, 86925, 89227, 91560, 93926, 96324, 98754, 101216,
+ 103710, 106236, 108795, 111386, 114009, 116665, 119353, 122074,
+ 124827, 127613, 130432, 133283, 136167, 139083, 142033, 145015,
+ 148031, 151079, 154160, 157274, 160422, 163602, 166816, 170063,
+ 173343, 176656, 180002, 183382, 186795, 190242, 193722, 197236,
+ 200783, 204363, 207978, 211626, 215307, 219023, 222772, 226554,
+ 230371, 234221, 238106, 242024, 245976, 249962, 253982, 258037,
+ 262125, 266247, 270404, 274594, 278819, 283079, 287372, 291700,
+ 296062, 300458, 304889, 309354, 313854, 318388, 322957, 327560,
+ 332198, 336870, 341577, 346319, 351096, 355907, 360753, 365633,
+ 370549, 375499, 380484, 385505, 390560, 395650, 400775, 405935,
+ 411130, 416360, 421625, 426925, 432260, 437631, 443037, 448478,
+ 453954, 459466, 465012, 470594, 476212, 481865, 487553, 493277,
+ 499036, 504831, 510661, 516526, 522428, 528364, 534337, 540345,
+ 546388, 552468, 558583, 564733, 570920, 577142, 583400, 589694,
+ 596024, 602389, 608791, 615228, 621702, 628211, 634756, 641337,
+ 647955, 654608, 661297, 668023, 674785, 681582, 688416, 695286,
+ 702193, 709135, 716114, 723129, 730180, 737268, 744392, 751552,
+ 758749, 765982, 773251, 780557, 787900, 795279, 802694, 810146,
+ 817634, 825159, 832721, 840319, 847954, 855625, 863333, 871078,
+ 878860, 886678, 894533, 902425, 910353, 918319, 926321, 934360,
+ 942436, 950548, 958698, 966885, 975108, 983369, 991666, 1000000
+};
+
+static const u32 gamma_control_set_215[] = {
+ 0, 7, 30, 72, 132, 214, 316, 440,
+ 586, 755, 947, 1162, 1401, 1664, 1951, 2263,
+ 2599, 2961, 3348, 3761, 4200, 4664, 5155, 5671,
+ 6215, 6785, 7382, 8006, 8657, 9335, 10041, 10774,
+ 11535, 12324, 13141, 13986, 14859, 15761, 16691, 17650,
+ 18637, 19653, 20698, 21772, 22876, 24008, 25170, 26361,
+ 27581, 28832, 30111, 31421, 32761, 34130, 35530, 36959,
+ 38419, 39909, 41430, 42981, 44562, 46175, 47817, 49491,
+ 51195, 52931, 54697, 56494, 58323, 60182, 62073, 63995,
+ 65949, 67934, 69950, 71998, 74078, 76190, 78333, 80508,
+ 82715, 84954, 87225, 89528, 91863, 94231, 96630, 99062,
+ 101526, 104023, 106552, 109114, 111708, 114335, 116994, 119687,
+ 122412, 125170, 127961, 130784, 133641, 136531, 139454, 142410,
+ 145399, 148422, 151477, 154566, 157689, 160845, 164034, 167257,
+ 170513, 173803, 177127, 180485, 183876, 187301, 190759, 194252,
+ 197779, 201339, 204934, 208562, 212225, 215922, 219653, 223418,
+ 227217, 231051, 234919, 238821, 242758, 246729, 250735, 254775,
+ 258850, 262959, 267103, 271282, 275496, 279744, 284027, 288345,
+ 292697, 297085, 301507, 305965, 310457, 314985, 319548, 324145,
+ 328778, 333446, 338150, 342888, 347662, 352471, 357316, 362195,
+ 367111, 372062, 377048, 382070, 387127, 392220, 397348, 402513,
+ 407713, 412948, 418220, 423527, 428870, 434248, 439663, 445114,
+ 450600, 456123, 461681, 467276, 472906, 478573, 484276, 490014,
+ 495790, 501601, 507448, 513332, 519252, 525209, 531201, 537231,
+ 543296, 549398, 555537, 561712, 567923, 574171, 580456, 586777,
+ 593135, 599529, 605961, 612429, 618933, 625475, 632053, 638668,
+ 645320, 652009, 658735, 665497, 672297, 679133, 686007, 692918,
+ 699865, 706850, 713872, 720931, 728027, 735161, 742331, 749539,
+ 756784, 764067, 771387, 778744, 786138, 793570, 801039, 808546,
+ 816090, 823672, 831291, 838947, 846642, 854374, 862143, 869950,
+ 877795, 885677, 893597, 901555, 909551, 917584, 925655, 933764,
+ 941911, 950096, 958318, 966579, 974877, 983214, 991588, 1000000
+};
+
+static const u32 gamma_control_set_218[] = {
+ 0 , 6, 26, 63, 117, 190, 282, 395,
+ 528, 683, 859, 1057, 1278, 1522, 1788, 2078,
+ 2392, 2730, 3092, 3479, 3891, 4327, 4789, 5277,
+ 5789, 6328, 6893, 7484, 8102, 8746, 9417, 10114,
+ 10839, 11591, 12370, 13177, 14012, 14874, 15765, 16683,
+ 17630, 18605, 19608, 20640, 21701, 22791, 23909, 25057,
+ 26234, 27440, 28675, 29940, 31235, 32559, 33913, 35297,
+ 36711, 38155, 39630, 41134, 42669, 44235, 45831, 47458,
+ 49116, 50804, 52523, 54274, 56055, 57868, 59712, 61587,
+ 63494, 65432, 67402, 69403, 71436, 73501, 75598, 77727,
+ 79888, 82081, 84306, 86564, 88853, 91175, 93530, 95917,
+ 98337, 100789, 103275, 105792, 108343, 110927, 113544, 116193,
+ 118876, 121592, 124342, 127124, 129940, 132790, 135673, 138589,
+ 141539, 144523, 147540, 150592, 153677, 156795, 159948, 163135,
+ 166356, 169611, 172900, 176224, 179582, 182974, 186400, 189861,
+ 193356, 196886, 200451, 204050, 207684, 211352, 215056, 218794,
+ 222567, 226375, 230218, 234096, 238010, 241958, 245941, 249960,
+ 254014, 258104, 262228, 266389, 270584, 274815, 279082, 283384,
+ 287722, 292096, 296505, 300950, 305431, 309948, 314501, 319090,
+ 323714, 328375, 333072, 337805, 342574, 347380, 352221, 357099,
+ 362013, 366964, 371951, 376974, 382034, 387131, 392264, 397434,
+ 402640, 407883, 413163, 418480, 423833, 429223, 434651, 440115,
+ 445616, 451154, 456729, 462341, 467990, 473677, 479401, 485161,
+ 490960, 496795, 502668, 508578, 514526, 520511, 526533, 532593,
+ 538691, 544826, 550999, 557209, 563457, 569743, 576067, 582428,
+ 588828, 595265, 601740, 608253, 614804, 621393, 628020, 634685,
+ 641388, 648129, 654909, 661726, 668582, 675477, 682409, 689380,
+ 696389, 703437, 710523, 717647, 724810, 732011, 739251, 746530,
+ 753847, 761203, 768598, 776031, 783503, 791014, 798563, 806152,
+ 813779, 821445, 829150, 836894, 844677, 852499, 860360, 868261,
+ 876200, 884178, 892196, 900252, 908348, 916484, 924658, 932872,
+ 941125, 949417, 957749, 966121, 974531, 982982, 991471, 1000000
+};
+
+static const u32 gamma_control_set_22[] = {
+ 0, 6, 24, 57, 108, 176, 262, 368,
+ 493, 639, 805, 993, 1202, 1434, 1687, 1964,
+ 2263, 2586, 2933, 3303, 3698, 4117, 4560, 5029,
+ 5522, 6041, 6585, 7156, 7752, 8374, 9022, 9697,
+ 10398, 11127, 11882, 12664, 13474, 14311, 15176, 16068,
+ 16989, 17937, 18913, 19918, 20952, 22013, 23104, 24223,
+ 25372, 26549, 27756, 28992, 30257, 31552, 32876, 34231,
+ 35615, 37029, 38473, 39948, 41452, 42988, 44553, 46149,
+ 47776, 49434, 51123, 52842, 54593, 56375, 58188, 60032,
+ 61908, 63815, 65754, 67725, 69728, 71762, 73828, 75927,
+ 78057, 80220, 82415, 84642, 86902, 89194, 91519, 93876,
+ 96267, 98690, 101146, 103635, 106157, 108712, 111300, 113921,
+ 116576, 119265, 121986, 124741, 127530, 130353, 133209, 136099,
+ 139023, 141981, 144973, 147999, 151059, 154153, 157281, 160444,
+ 163641, 166873, 170139, 173440, 176775, 180145, 183549, 186989,
+ 190463, 193973, 197517, 201096, 204711, 208360, 212045, 215765,
+ 219520, 223311, 227137, 230999, 234896, 238828, 242797, 246801,
+ 250841, 254916, 259028, 263175, 267359, 271578, 275833, 280125,
+ 284453, 288816, 293217, 297653, 302126, 306635, 311181, 315763,
+ 320382, 325037, 329730, 334458, 339224, 344026, 348865, 353741,
+ 358654, 363604, 368591, 373616, 378677, 383775, 388911, 394084,
+ 399294, 404541, 409826, 415149, 420508, 425906, 431341, 436813,
+ 442323, 447871, 453457, 459080, 464742, 470441, 476178, 481953,
+ 487766, 493617, 499506, 505433, 511398, 517402, 523444, 529524,
+ 535642, 541799, 547994, 554228, 560500, 566810, 573159, 579547,
+ 585973, 592439, 598942, 605485, 612066, 618686, 625345, 632043,
+ 638780, 645556, 652371, 659224, 666117, 673050, 680021, 687031,
+ 694081, 701170, 708298, 715466, 722673, 729919, 737205, 744531,
+ 751896, 759300, 766744, 774228, 781751, 789314, 796917, 804560,
+ 812242, 819964, 827726, 835528, 843370, 851252, 859174, 867136,
+ 875138, 883180, 891263, 899385, 907548, 915751, 923994, 932277,
+ 940601, 948965, 957370, 965815, 974301, 982827, 991393, 1000000
+};
+
+static const u32 gamma_control_set_221[] = {
+ 0, 5, 23, 55, 103, 169, 252, 355,
+ 476, 618, 780, 962, 1166, 1392, 1639, 1909,
+ 2202, 2517, 2856, 3219, 3605, 4015, 4450, 4909,
+ 5393, 5902, 6437, 6997, 7582, 8194, 8831, 9495,
+ 10185, 10901, 11645, 12415, 13213, 14037, 14890, 15769,
+ 16677, 17612, 18575, 19567, 20587, 21635, 22712, 23817,
+ 24952, 26115, 27307, 28529, 29780, 31060, 32370, 33710,
+ 35079, 36478, 37908, 39367, 40857, 42377, 43928, 45509,
+ 47120, 48763, 50436, 52141, 53876, 55642, 57440, 59269,
+ 61130, 63022, 64946, 66901, 68889, 70908, 72959, 75042,
+ 77157, 79305, 81485, 83697, 85942, 88219, 90530, 92872,
+ 95248, 97656, 100098, 102572, 105080, 107621, 110195, 112802,
+ 115443, 118117, 120825, 123567, 126342, 129151, 131994, 134871,
+ 137782, 140727, 143706, 146719, 149766, 152848, 155964, 159115,
+ 162300, 165520, 168775, 172064, 175388, 178747, 182141, 185569,
+ 189033, 192532, 196066, 199635, 203240, 206880, 210555, 214266,
+ 218012, 221794, 225612, 229465, 233354, 237279, 241240, 245236,
+ 249269, 253338, 257442, 261583, 265760, 269974, 274223, 278509,
+ 282832, 287191, 291586, 296018, 300487, 304992, 309534, 314113,
+ 318729, 323381, 328071, 332797, 337561, 342362, 347199, 352074,
+ 356987, 361936, 366923, 371947, 377009, 382108, 387245, 392419,
+ 397631, 402881, 408168, 413493, 418856, 424257, 429695, 435172,
+ 440686, 446239, 451830, 457459, 463126, 468831, 474575, 480356,
+ 486177, 492035, 497932, 503868, 509842, 515854, 521906, 527996,
+ 534124, 540292, 546498, 552743, 559027, 565349, 571711, 578112,
+ 584552, 591030, 597548, 604106, 610702, 617337, 624012, 630726,
+ 637480, 644273, 651105, 657977, 664888, 671839, 678830, 685860,
+ 692930, 700039, 707189, 714378, 721607, 728876, 736184, 743533,
+ 750922, 758350, 765819, 773328, 780877, 788466, 796095, 803765,
+ 811475, 819225, 827015, 834846, 842717, 850629, 858582, 866574,
+ 874608, 882682, 890796, 898952, 907148, 915384, 923662, 931980,
+ 940339, 948740, 957181, 965662, 974185, 982749, 991354, 1000000
+};
+
+static const u32 gamma_control_set_222[] = {
+ 0, 5, 22, 53, 99, 162, 243, 342,
+ 460, 597, 755, 932, 1131, 1351, 1592, 1856,
+ 2142, 2450, 2781, 3136, 3514, 3916, 4342, 4792,
+ 5267, 5767, 6292, 6841, 7417, 8017, 8644, 9297,
+ 9976, 10681, 11413, 12171, 12957, 13769, 14609, 15476,
+ 16371, 17293, 18243, 19222, 20228, 21263, 22326, 23418,
+ 24538, 25688, 26866, 28073, 29310, 30576, 31871, 33197,
+ 34551, 35936, 37351, 38795, 40270, 41775, 43311, 44877,
+ 46473, 48101, 49759, 51448, 53169, 54920, 56703, 58516,
+ 60362, 62239, 64147, 66088, 68060, 70064, 72100, 74168,
+ 76268, 78401, 80566, 82763, 84993, 87256, 89551, 91879,
+ 94240, 96634, 99061, 101521, 104014, 106541, 109100, 111694,
+ 114321, 116981, 119675, 122403, 125165, 127961, 130790, 133654,
+ 136551, 139483, 142450, 145450, 148485, 151555, 154659, 157797,
+ 160970, 164178, 167421, 170699, 174012, 177360, 180742, 184160,
+ 187614, 191102, 194626, 198185, 201780, 205410, 209076, 212778,
+ 216515, 220288, 224097, 227942, 231823, 235740, 239692, 243682,
+ 247707, 251768, 255866, 260001, 264171, 268379, 272623, 276903,
+ 281220, 285574, 289965, 294392, 298856, 303358, 307896, 312471,
+ 317084, 321734, 326421, 331145, 335906, 340705, 345541, 350415,
+ 355327, 360276, 365262, 370286, 375349, 380448, 385586, 390762,
+ 395975, 401227, 406516, 411844, 417210, 422614, 428056, 433537,
+ 439055, 444613, 450208, 455843, 461515, 467227, 472977, 478765,
+ 484593, 490459, 496364, 502307, 508290, 514312, 520372, 526472,
+ 532611, 538789, 545006, 551262, 557558, 563892, 570267, 576680,
+ 583133, 589626, 596158, 602729, 609341, 615992, 622682, 629412,
+ 636183, 642992, 649842, 656732, 663662, 670631, 677641, 684691,
+ 691781, 698911, 706081, 713291, 720542, 727833, 735165, 742537,
+ 749949, 757402, 764895, 772429, 780003, 787618, 795274, 802971,
+ 810708, 818486, 826305, 834165, 842065, 850007, 857989, 866013,
+ 874078, 882183, 890330, 898518, 906748, 915018, 923330, 931683,
+ 940078, 948514, 956991, 965510, 974070, 982672, 991315, 1000000
+};
+
+static const u32 gamma_control_set_223[] = {
+ 0, 5, 21, 50, 95, 156, 234, 330,
+ 444, 578, 731, 904, 1097, 1311, 1547, 1804,
+ 2083, 2385, 2709, 3056, 3426, 3820, 4237, 4679,
+ 5144, 5635, 6150, 6689, 7255, 7845, 8461, 9103,
+ 9771, 10465, 11185, 11932, 12705, 13506, 14333, 15188,
+ 16070, 16980, 17917, 18883, 19876, 20897, 21947, 23025,
+ 24132, 25267, 26432, 27625, 28848, 30099, 31381, 32691,
+ 34031, 35402, 36802, 38231, 39692, 41182, 42703, 44254,
+ 45835, 47448, 49091, 50765, 52470, 54207, 55974, 57773,
+ 59603, 61465, 63359, 65284, 67241, 69230, 71251, 73304,
+ 75389, 77507, 79657, 81839, 84054, 86302, 88583, 90896,
+ 93243, 95622, 98034, 100480, 102959, 105471, 108017, 110596,
+ 113209, 115856, 118536, 121251, 123999, 126781, 129597, 132448,
+ 135332, 138251, 141205, 144193, 147215, 150272, 153364, 156490,
+ 159651, 162848, 166079, 169345, 172647, 175983, 179355, 182762,
+ 186205, 189683, 193196, 196746, 200330, 203951, 207607, 211300,
+ 215028, 218792, 222592, 226429, 230301, 234210, 238155, 242137,
+ 246155, 250209, 254300, 258428, 262592, 266793, 271031, 275306,
+ 279618, 283966, 288352, 292775, 297235, 301732, 306267, 310838,
+ 315448, 320094, 324779, 329500, 334260, 339057, 343891, 348764,
+ 353674, 358623, 363609, 368633, 373695, 378796, 383934, 389111,
+ 394326, 399580, 404871, 410202, 415570, 420977, 426423, 431908,
+ 437431, 442992, 448593, 454232, 459911, 465628, 471384, 477180,
+ 483014, 488887, 494800, 500752, 506743, 512774, 518843, 524953,
+ 531102, 537290, 543518, 549785, 556092, 562439, 568826, 575252,
+ 581718, 588224, 594770, 601356, 607982, 614649, 621355, 628101,
+ 634888, 641715, 648582, 655489, 662437, 669425, 676454, 683524,
+ 690633, 697784, 704975, 712207, 719479, 726793, 734147, 741542,
+ 748977, 756454, 763972, 771531, 779131, 786772, 794454, 802177,
+ 809942, 817748, 825595, 833483, 841413, 849385, 857398, 865452,
+ 873548, 881685, 889865, 898085, 906348, 914652, 922998, 931386,
+ 939816, 948288, 956801, 965357, 973955, 982595, 991276, 1000000
+};
+
+static const u32 gamma_control_set_224[] = {
+ 0, 5, 20, 48, 91, 150, 226, 318,
+ 429, 559, 707, 876, 1064, 1273, 1503, 1754,
+ 2026, 2321, 2638, 2977, 3340, 3725, 4135, 4567,
+ 5024, 5505, 6011, 6541, 7096, 7676, 8282, 8913,
+ 9570, 10253, 10962, 11697, 12459, 13248, 14063, 14906,
+ 15775, 16672, 17597, 18549, 19530, 20538, 21574, 22639,
+ 23732, 24854, 26005, 27184, 28393, 29630, 30897, 32194,
+ 33520, 34875, 36261, 37676, 39121, 40597, 42103, 43639,
+ 45206, 46804, 48432, 50091, 51781, 53503, 55255, 57039,
+ 58854, 60701, 62580, 64490, 66432, 68406, 70412, 72450,
+ 74520, 76623, 78758, 80926, 83126, 85359, 87625, 89924,
+ 92256, 94621, 97019, 99450, 101915, 104413, 106944, 109510,
+ 112109, 114742, 117408, 120109, 122843, 125612, 128415, 131252,
+ 134124, 137030, 139971, 142946, 145956, 149000, 152080, 155194,
+ 158343, 161528, 164747, 168002, 171292, 174617, 177978, 181375,
+ 184806, 188274, 191777, 195316, 198891, 202502, 206149, 209832,
+ 213551, 217306, 221098, 224925, 228790, 232690, 236628, 240602,
+ 244612, 248659, 252744, 256864, 261022, 265217, 269449, 273718,
+ 278024, 282368, 286748, 291167, 295622, 300115, 304646, 309214,
+ 313820, 318463, 323145, 327864, 332621, 337416, 342249, 347120,
+ 352030, 356977, 361963, 366987, 372050, 377150, 382290, 387468,
+ 392684, 397939, 403233, 408566, 413937, 419347, 424796, 430285,
+ 435812, 441378, 446983, 452628, 458312, 464035, 469797, 475599,
+ 481440, 487321, 493241, 499201, 505201, 511240, 517319, 523438,
+ 529597, 535795, 542034, 548312, 554631, 560989, 567388, 573827,
+ 580307, 586826, 593386, 599987, 606627, 613309, 620030, 626793,
+ 633596, 640439, 647324, 654249, 661215, 668222, 675270, 682358,
+ 689488, 696659, 703871, 711124, 718418, 725753, 733130, 740548,
+ 748007, 755508, 763050, 770634, 778259, 785926, 793635, 801385,
+ 809177, 817010, 824886, 832803, 840762, 848763, 856806, 864891,
+ 873018, 881188, 889399, 897653, 905948, 914286, 922667, 931089,
+ 939555, 948062, 956612, 965205, 973840, 982517, 991238, 1000000
+};
+
+static const u32 gamma_control_set_225[] = {
+ 0, 4, 19, 46, 88, 144, 217, 307,
+ 415, 540, 685, 849, 1032, 1235, 1460, 1705,
+ 1971, 2259, 2569, 2901, 3256, 3634, 4034, 4459,
+ 4907, 5379, 5875, 6396, 6941, 7511, 8107, 8727,
+ 9373, 10045, 10743, 11467, 12218, 12994, 13798, 14628,
+ 15486, 16370, 17283, 18222, 19190, 20185, 21208, 22259,
+ 23339, 24448, 25584, 26750, 27945, 29168, 30421, 31704,
+ 33015, 34357, 35728, 37129, 38559, 40020, 41512, 43033,
+ 44586, 46168, 47782, 49426, 51102, 52808, 54546, 56314,
+ 58115, 59947, 61810, 63705, 65632, 67591, 69583, 71606,
+ 73661, 75749, 77870, 80023, 82208, 84427, 86678, 88962,
+ 91279, 93630, 96014, 98431, 100881, 103365, 105883, 108434,
+ 111019, 113638, 116291, 118978, 121699, 124454, 127244, 130068,
+ 132926, 135819, 138747, 141710, 144707, 147739, 150806, 153909,
+ 157046, 160218, 163426, 166669, 169948, 173262, 176612, 179997,
+ 183419, 186876, 190369, 193898, 197462, 201063, 204701, 208374,
+ 212084, 215830, 219613, 223432, 227288, 231181, 235110, 239076,
+ 243079, 247119, 251196, 255311, 259462, 263650, 267876, 272139,
+ 276440, 280778, 285154, 289567, 294018, 298507, 303034, 307598,
+ 312200, 316841, 321519, 326236, 330991, 335784, 340615, 345485,
+ 350393, 355339, 360325, 365348, 370411, 375512, 380652, 385831,
+ 391049, 396306, 401601, 406936, 412310, 417723, 423176, 428668,
+ 434199, 439769, 445379, 451029, 456718, 462447, 468215, 474024,
+ 479872, 485760, 491687, 497655, 503663, 509711, 515799, 521927,
+ 528096, 534305, 540554, 546843, 553173, 559544, 565955, 572406,
+ 578899, 585432, 592005, 598620, 605275, 611971, 618709, 625487,
+ 632306, 639167, 646068, 653011, 659995, 667020, 674087, 681195,
+ 688345, 695536, 702768, 710042, 717358, 724715, 732115, 739556,
+ 747038, 754563, 762130, 769738, 777389, 785081, 792816, 800593,
+ 808412, 816273, 824177, 832123, 840111, 848142, 856215, 864331,
+ 872489, 880690, 888934, 897220, 905549, 913921, 922335, 930793,
+ 939293, 947836, 956423, 965052, 973724, 982440, 991199, 1000000
+};
+
+static const u32 *GAMMA_CONTROL_TABLE[G_MAX] = {
+ gamma_control_set_21,
+ gamma_control_set_213,
+ gamma_control_set_215,
+ gamma_control_set_218,
+ gamma_control_set_22,
+ gamma_control_set_221,
+ gamma_control_set_222,
+ gamma_control_set_223,
+ gamma_control_set_224,
+ gamma_control_set_225
+};
+
+static const struct str_flookup_table flookup_table[302] = {
+ { 0, 0}, { 1, 20},
+ { 20, 7}, { 27, 5},
+ { 32, 4}, { 36, 4},
+ { 40, 4}, { 44, 3},
+ { 47, 3}, { 50, 2},
+ { 52, 3}, { 55, 2},
+ { 57, 3}, { 60, 2},
+ { 62, 2}, { 64, 2},
+ { 66, 2}, { 68, 2},
+ { 70, 1}, { 71, 2},
+ { 73, 2}, { 75, 2},
+ { 77, 1}, { 78, 2},
+ { 80, 1}, { 81, 2},
+ { 83, 1}, { 84, 2},
+ { 86, 1}, { 87, 2},
+ { 89, 1}, { 90, 1},
+ { 91, 2}, { 93, 1},
+ { 94, 1}, { 95, 2},
+ { 97, 1}, { 98, 1},
+ { 99, 1}, {100, 1},
+ {101, 2}, {103, 1},
+ {104, 1}, {105, 1},
+ {106, 1}, {107, 1},
+ {108, 1}, {109, 1},
+ {110, 1}, {111, 1},
+ {112, 1}, {113, 1},
+ {114, 1}, {115, 1},
+ {116, 1}, {117, 1},
+ {118, 1}, {119, 1},
+ {120, 1}, {121, 1},
+ {122, 1}, {123, 1},
+ {124, 1}, {125, 1},
+ {126, 1}, {127, 1},
+ {128, 1}, {129, 1},
+ { 0, 0}, {130, 1},
+ {131, 1}, {132, 1},
+ {133, 1}, {134, 1},
+ { 0, 0}, {135, 1},
+ {136, 1}, {137, 1},
+ {138, 1}, {139, 1},
+ { 0, 0}, {140, 1},
+ {141, 1}, {142, 1},
+ { 0, 0}, {143, 1},
+ {144, 1}, {145, 1},
+ {146, 1}, { 0, 0},
+ {147, 1}, {148, 1},
+ {149, 1}, { 0, 0},
+ {150, 1}, {151, 1},
+ { 0, 0}, {152, 1},
+ {153, 1}, {154, 1},
+ { 0, 0}, {155, 1},
+ {156, 1}, { 0, 0},
+ {157, 1}, {158, 1},
+ { 0, 0}, {159, 1},
+ {160, 1}, { 0, 0},
+ {161, 1}, {162, 1},
+ { 0, 0}, {163, 1},
+ {164, 1}, { 0, 0},
+ {165, 1}, {166, 1},
+ { 0, 0}, {167, 1},
+ {168, 1}, { 0, 0},
+ {169, 1}, {170, 1},
+ { 0, 0}, {171, 1},
+ { 0, 0}, {172, 1},
+ {173, 1}, { 0, 0},
+ {174, 1}, { 0, 0},
+ {175, 1}, {176, 1},
+ { 0, 0}, {177, 1},
+ { 0, 0}, {178, 1},
+ {179, 1}, { 0, 0},
+ {180, 1}, { 0, 0},
+ {181, 1}, {182, 1},
+ { 0, 0}, {183, 1},
+ { 0, 0}, {184, 1},
+ { 0, 0}, {185, 1},
+ {186, 1}, { 0, 0},
+ {187, 1}, { 0, 0},
+ {188, 1}, { 0, 0},
+ {189, 1}, { 0, 0},
+ {190, 1}, {191, 1},
+ { 0, 0}, {192, 1},
+ { 0, 0}, {193, 1},
+ { 0, 0}, {194, 1},
+ { 0, 0}, {195, 1},
+ { 0, 0}, {196, 1},
+ { 0, 0}, {197, 1},
+ {198, 1}, { 0, 0},
+ {199, 1}, { 0, 0},
+ {200, 1}, { 0, 0},
+ {201, 1}, { 0, 0},
+ {202, 1}, { 0, 0},
+ {203, 1}, { 0, 0},
+ {204, 1}, { 0, 0},
+ {205, 1}, { 0, 0},
+ {206, 1}, { 0, 0},
+ {207, 1}, { 0, 0},
+ {208, 1}, { 0, 0},
+ {209, 1}, { 0, 0},
+ {210, 1}, { 0, 0},
+ {211, 1}, { 0, 0},
+ {212, 1}, { 0, 0},
+ {213, 1}, { 0, 0},
+ { 0, 0}, {214, 1},
+ { 0, 0}, {215, 1},
+ { 0, 0}, {216, 1},
+ { 0, 0}, {217, 1},
+ { 0, 0}, {218, 1},
+ { 0, 0}, {219, 1},
+ { 0, 0}, {220, 1},
+ { 0, 0}, {221, 1},
+ { 0, 0}, { 0, 0},
+ {222, 1}, { 0, 0},
+ {223, 1}, { 0, 0},
+ {224, 1}, { 0, 0},
+ {225, 1}, { 0, 0},
+ { 0, 0}, {226, 1},
+ { 0, 0}, {227, 1},
+ { 0, 0}, {228, 1},
+ { 0, 0}, {229, 1},
+ { 0, 0}, { 0, 0},
+ {230, 1}, { 0, 0},
+ {231, 1}, { 0, 0},
+ {232, 1}, { 0, 0},
+ {233, 1}, { 0, 0},
+ { 0, 0}, {234, 1},
+ { 0, 0}, {235, 1},
+ { 0, 0}, { 0, 0},
+ {236, 1}, { 0, 0},
+ {237, 1}, { 0, 0},
+ {238, 1}, { 0, 0},
+ { 0, 0}, {239, 1},
+ { 0, 0}, {240, 1},
+ { 0, 0}, {241, 1},
+ { 0, 0}, { 0, 0},
+ {242, 1}, { 0, 0},
+ {243, 1}, { 0, 0},
+ { 0, 0}, {244, 1},
+ { 0, 0}, {245, 1},
+ { 0, 0}, { 0, 0},
+ {246, 1}, { 0, 0},
+ {247, 1}, { 0, 0},
+ { 0, 0}, {248, 1},
+ { 0, 0}, {249, 1},
+ { 0, 0}, { 0, 0},
+ {250, 1}, { 0, 0},
+ {251, 1}, { 0, 0},
+ { 0, 0}, {252, 1},
+ { 0, 0}, {253, 1},
+ { 0, 0}, { 0, 0},
+ {254, 1}, { 0, 0},
+ { 0, 0}, {255, 1},
+};
+
+#endif
+
diff --git a/drivers/video/samsung/lcdfreq.c b/drivers/video/samsung/lcdfreq.c
index 8c25c22..7e4af07 100644
--- a/drivers/video/samsung/lcdfreq.c
+++ b/drivers/video/samsung/lcdfreq.c
@@ -21,8 +21,6 @@
#include "s3cfb.h"
-#define LCDFREQ_LIMIT_HZ 40
-
enum lcdfreq_level_idx {
LEVEL_NORMAL,
LEVEL_LIMIT,
@@ -217,30 +215,44 @@ int get_divider(struct fb_info *fb)
fimd_div = gcd(lcdfreq->table[LEVEL_NORMAL].cmu_clkdiv, lcdfreq->table[LEVEL_LIMIT].cmu_clkdiv);
+ if ((!fimd_div) || (fimd_div > 16)) {
+ dev_info(fb->dev, "%s skip, %d\n", __func__, __LINE__);
+ goto err;
+ }
+
lcdfreq->table[LEVEL_NORMAL].cmu_clkdiv /= fimd_div;
lcdfreq->table[LEVEL_LIMIT].cmu_clkdiv /= fimd_div;
dev_info(fb->dev, "%s rate is %d, fimd divider=%d\n", clk->name, rate, fimd_div);
+ fimd_div--;
for (i = 0; i < LCDFREQ_LEVEL_END; i++) {
- lcdfreq->table[i].cmu_clkdiv--;
- dev_info(fb->dev, "%dHZ divider is %d\n",
+ if (lcdfreq->table[i].cmu_clkdiv > 16) {
+ dev_info(fb->dev, "%s skip, %d\n", __func__, __LINE__);
+ goto err;
+ }
+ dev_info(fb->dev, "%dhz div is %d\n",
lcdfreq->table[i].hz, lcdfreq->table[i].cmu_clkdiv);
+ lcdfreq->table[i].cmu_clkdiv--;
}
reg = (readl(fbdev->regs + S3C_VIDCON0) & (S3C_VIDCON0_CLKVAL_F(0xff))) >> 6;
- reg++;
-
- if (fimd_div != reg)
- return -EINVAL;
+ if (fimd_div != reg) {
+ dev_info(fb->dev, "%s skip, %d\n", __func__, __LINE__);
+ goto err;
+ }
reg = (readl(sclk->reg_div.reg)) >> sclk->reg_div.shift;
reg &= 0xf;
-
- if (lcdfreq->table[LEVEL_NORMAL].cmu_clkdiv != reg)
- return -EINVAL;
+ if (lcdfreq->table[LEVEL_NORMAL].cmu_clkdiv != reg) {
+ dev_info(fb->dev, "%s skip, %d\n", __func__, __LINE__);
+ goto err;
+ }
return 0;
+
+err:
+ return -EINVAL;
}
static ssize_t level_show(struct device *dev,
@@ -256,7 +268,7 @@ static ssize_t level_show(struct device *dev,
return -EINVAL;
}
- return sprintf(buf, "%dHZ, div=%d\n", lcdfreq->table[lcdfreq->level].hz, get_div(fbdev));
+ return sprintf(buf, "%dhz, div=%d\n", lcdfreq->table[lcdfreq->level].hz, get_div(fbdev));
}
static ssize_t level_store(struct device *dev,
@@ -296,12 +308,61 @@ static ssize_t usage_show(struct device *dev,
return sprintf(buf, "%d\n", atomic_read(&lcdfreq->usage));
}
+#if 0
+static ssize_t freq_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct fb_info *fb = dev_get_drvdata(dev);
+ struct s3cfb_window *win = fb->par;
+ struct s3cfb_global *fbdev = get_fimd_global(win->id);
+ struct s3cfb_lcd *lcd = fbdev->lcd;
+
+ return sprintf(buf, "%dhz, hfp=%d, hbp=%d, hsw=%d, div=%d\n", lcd->freq,
+ lcd->timing.h_fp, lcd->timing.h_bp, lcd->timing.h_sw, get_div(fbdev)+1);
+}
+
+extern void s5p_dsim_set_lcd_freq_change(struct s3cfb_lcd_timing *timing);
+
+static ssize_t freq_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ struct fb_info *fb = dev_get_drvdata(dev);
+ struct s3cfb_window *win = fb->par;
+ struct s3cfb_global *fbdev = get_fimd_global(win->id);
+ struct s3cfb_lcd *lcd = fbdev->lcd;
+ struct s3cfb_lcd_timing *timing = &lcd->timing;
+ struct fb_var_screeninfo *var = &fb->var;
+
+ lcd->freq_limit = 0;
+ sscanf(buf, "%d %d %d %d", &lcd->freq,
+ &timing->h_fp, &timing->h_bp, &timing->h_sw);
+
+ var->hsync_len = timing->h_sw;
+ var->left_margin = timing->h_bp;
+ var->right_margin = timing->h_fp;
+
+ var->pixclock = (lcd->freq *
+ (var->left_margin + var->right_margin
+ + var->hsync_len + var->xres) *
+ (var->upper_margin + var->lower_margin
+ + var->vsync_len + var->yres));
+ var->pixclock = KHZ2PICOS(var->pixclock/1000);
+
+ s5p_dsim_set_lcd_freq_change(timing);
+
+ return count;
+}
+
+static DEVICE_ATTR(freq, S_IRUGO|S_IWUSR, freq_show, freq_store);
+#endif
+
static DEVICE_ATTR(level, S_IRUGO|S_IWUSR, level_show, level_store);
static DEVICE_ATTR(usage, S_IRUGO, usage_show, NULL);
static struct attribute *lcdfreq_attributes[] = {
&dev_attr_level.attr,
&dev_attr_usage.attr,
+/* &dev_attr_freq.attr, */
NULL,
};
@@ -323,7 +384,7 @@ static void lcdfreq_early_suspend(struct early_suspend *h)
atomic_set(&lcdfreq->usage, 0);
mutex_unlock(&lcdfreq->lock);
- return ;
+ return;
}
static void lcdfreq_late_resume(struct early_suspend *h)
@@ -392,7 +453,7 @@ static void lcdfreq_status_work(struct work_struct *work)
cancel_delayed_work(&lcdfreq->work);
- dev_info(lcdfreq->dev, "\tHZ=%d, usage=%d\n", hz, atomic_read(&lcdfreq->usage));
+ dev_info(lcdfreq->dev, "\thz=%d, usage=%d\n", hz, atomic_read(&lcdfreq->usage));
schedule_delayed_work(&lcdfreq->work, HZ*120);
}
@@ -405,8 +466,8 @@ int lcdfreq_init(struct fb_info *fb)
struct fb_var_screeninfo *var = &fb->var;
struct lcdfreq_info *lcdfreq = NULL;
- u32 vclk = 0;
- int ret;
+ u32 vclk;
+ int ret = 0;
lcdfreq = kzalloc(sizeof(struct lcdfreq_info), GFP_KERNEL);
if (!lcdfreq) {
@@ -415,6 +476,11 @@ int lcdfreq_init(struct fb_info *fb)
goto err_1;
}
+ if (!lcd->freq_limit) {
+ ret = -EINVAL;
+ goto err_2;
+ }
+
fbdev->data = lcdfreq;
lcdfreq->dev = fb->dev;
@@ -430,7 +496,7 @@ int lcdfreq_init(struct fb_info *fb)
lcdfreq->table[LEVEL_NORMAL].pixclock = var->pixclock;
lcdfreq->table[LEVEL_NORMAL].hz = lcd->freq;
- vclk = (LCDFREQ_LIMIT_HZ *
+ vclk = (lcd->freq_limit *
(var->left_margin + var->right_margin
+ var->hsync_len + var->xres) *
(var->upper_margin + var->lower_margin
@@ -438,11 +504,11 @@ int lcdfreq_init(struct fb_info *fb)
lcdfreq->table[LEVEL_LIMIT].level = LEVEL_LIMIT;
lcdfreq->table[LEVEL_LIMIT].vclk = vclk;
lcdfreq->table[LEVEL_LIMIT].pixclock = KHZ2PICOS(vclk/1000);
- lcdfreq->table[LEVEL_LIMIT].hz = LCDFREQ_LIMIT_HZ;
+ lcdfreq->table[LEVEL_LIMIT].hz = lcd->freq_limit;
ret = get_divider(fb);
if (ret < 0) {
- pr_err("fail to init lcd freq switch");
+ pr_err("skip lcd freq switch init");
fbdev->data = NULL;
goto err_1;
}
@@ -489,4 +555,3 @@ err_1:
return ret;
}
-
diff --git a/drivers/video/samsung/ld9040.c b/drivers/video/samsung/ld9040.c
index 2ff3af0..9c75788 100644
--- a/drivers/video/samsung/ld9040.c
+++ b/drivers/video/samsung/ld9040.c
@@ -75,7 +75,7 @@ struct lcd_info {
unsigned int auto_brightness;
unsigned int ldi_enable;
unsigned int acl_enable;
- unsigned int cur_acl;
+ unsigned int current_acl;
struct mutex lock;
struct mutex bl_lock;
struct lcd_device *ld;
@@ -461,56 +461,49 @@ elvss_err:
return ret;
}
-static int ld9040_set_acl(struct lcd_info *lcd)
+static int ld9040_set_acl(struct lcd_info *lcd, u8 force)
{
- int ret = 0;
+ int ret = 0, enable, level;
+ u32 candela = candela_table[lcd->bl];
struct ld9040_panel_data *pdata = lcd->lcd_pd->pdata;
- if (lcd->acl_enable) {
- if (lcd->cur_acl == 0) {
- if (lcd->bl == 0 || lcd->bl == 1) {
- ret = ld9040_panel_send_sequence(lcd, pdata->acl_table[0]);
- dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d, acl_off\n", __func__, lcd->cur_acl);
- } else {
- ret = ld9040_panel_send_sequence(lcd, pdata->acl_on);
- dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d, acl_on\n", __func__, lcd->cur_acl);
- }
- }
- switch (lcd->bl) {
- case GAMMA_30CD ... GAMMA_40CD: /* 30cd ~ 40cd */
- if (lcd->cur_acl != 0) {
- ret = ld9040_panel_send_sequence(lcd, pdata->acl_table[0]);
- lcd->cur_acl = 0;
- dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d\n", __func__, lcd->cur_acl);
- }
- break;
- case GAMMA_70CD ... GAMMA_250CD: /* 70cd ~ 250cd */
- if (lcd->cur_acl != 40) {
- ret = ld9040_panel_send_sequence(lcd, pdata->acl_table[1]);
- lcd->cur_acl = 40;
- dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d\n", __func__, lcd->cur_acl);
- }
- break;
- default:
- if (lcd->cur_acl != 50) {
- ret = ld9040_panel_send_sequence(lcd, pdata->acl_table[2]);
- lcd->cur_acl = 50;
- dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d\n", __func__, lcd->cur_acl);
- }
- break;
- }
- } else {
- ret = ld9040_panel_send_sequence(lcd, pdata->acl_table[0]);
- lcd->cur_acl = 0;
- dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d\n", __func__, lcd->cur_acl);
+ switch (candela) {
+ case 0 ... 69:
+ level = ACL_STATUS_0P;
+ break;
+ case 70 ... 250:
+ level = ACL_STATUS_40P;
+ break;
+ default:
+ level = ACL_STATUS_50P;
+ break;
}
- if (ret) {
+ if (!lcd->acl_enable)
+ level = ACL_STATUS_0P;
+
+ enable = !!level;
+
+ //if (force || lcd->acl_enable != enable) {
+ dev_dbg(&lcd->ld->dev, "acl turn %s\n", enable ? "on" : "off");
+ if (enable)
+ ret = ld9040_panel_send_sequence(lcd, pdata->acl_on);
+ else {
+ ret = ld9040_panel_send_sequence(lcd, pdata->acl_table[ACL_STATUS_0P]);
+ goto exit;
+ }
+ //}
+
+ //if (force || lcd->current_acl != level) {
+ ret = ld9040_panel_send_sequence(lcd, pdata->acl_table[level]);
+ lcd->current_acl = level;
+ dev_dbg(&lcd->ld->dev, "current_acl = %d\n", lcd->current_acl);
+ //}
+
+ if (ret)
ret = -EPERM;
- goto acl_err;
- }
-acl_err:
+exit:
return ret;
}
@@ -578,7 +571,7 @@ static int update_brightness(struct lcd_info *lcd, u8 force)
ret = ld9040_gamma_ctl(lcd);
- ret |= ld9040_set_acl(lcd);
+ ret |= ld9040_set_acl(lcd, force);
ret |= ld9040_set_elvss(lcd);
@@ -836,7 +829,7 @@ device_attribute *attr, const char *buf, size_t size)
mutex_lock(&lcd->bl_lock);
lcd->acl_enable = value;
if (lcd->ldi_enable)
- ld9040_set_acl(lcd);
+ ld9040_set_acl(lcd, 0);
mutex_unlock(&lcd->bl_lock);
}
}
@@ -1076,7 +1069,7 @@ static int ld9040_probe(struct spi_device *spi)
lcd->current_gamma_mode = 0;
lcd->acl_enable = 0;
- lcd->cur_acl = 0;
+ lcd->current_acl = 0;
lcd->auto_brightness = 1;
diff --git a/drivers/video/samsung/lms501xx.h b/drivers/video/samsung/lms501xx.h
new file mode 100644
index 0000000..0d5ca54
--- /dev/null
+++ b/drivers/video/samsung/lms501xx.h
@@ -0,0 +1,156 @@
+#ifndef __LMS501XX_H__
+#define __LMS501XX_H__
+
+const unsigned char SEQ_SET_EXTC[] = {
+ 0xB9,
+ 0xFF, 0x83, 0x69,
+};
+
+const unsigned char SEQ_SET_MIPI_DSI[] = {
+ 0xBA,
+ 0x11, 0x00, 0x16, 0xC6, 0x80, 0x0A, 0x00, 0x10, 0x24, 0x02,
+ 0x21, 0x21, 0x9A, 0x11, 0x14,
+};
+
+const unsigned char SEQ_SET_GIP[] = {
+ 0xD5,
+ 0x00, 0x00, 0x09, 0x03, 0x2D, 0x00, 0x00, 0x12, 0x31, 0x23,
+ 0x00, 0x00, 0x10, 0x70, 0x37, 0x00, 0x00, 0x0D, 0x01, 0x40,
+ 0x37, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x03,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0xEF, 0x00, 0x13, 0x57,
+ 0x71, 0x00, 0x00, 0x00, 0xEF, 0xEF, 0x00, 0x64, 0x20, 0x06,
+ 0x00, 0x00, 0x00, 0xEF, 0xEF, 0x00, 0x02, 0x46, 0x60, 0x00,
+ 0x00, 0x00, 0xEF, 0xEF, 0x00, 0x75, 0x31, 0x17, 0x00, 0x00,
+ 0x00, 0xEF, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0F,
+ 0xFC, 0x0C, 0xFC, 0xFF, 0x0F, 0xFC, 0x0C, 0xFC, 0xFF, 0x00,
+ 0x00, 0x5A,
+};
+
+const unsigned char SEQ_SET_POWER[] = {
+ 0xB1,
+ 0x0A, 0x83, 0x77, 0x00, 0x91, 0x0F, 0x1C, 0x1C, 0x0C, 0x2A,
+ 0x20, 0x4E,
+};
+
+const unsigned char SEQ_SET_RGB[] = {
+ 0xB3,
+ 0x03, 0x00, 0x30, 0x0B,
+};
+
+const unsigned char SEQ_SET_CYC[] = {
+ 0xB4, 0x02,
+};
+
+const unsigned char SEQ_SET_VCOM[] = {
+ 0xB6,
+ 0xB1, 0xa8, 0x00,
+};
+
+const unsigned char SEQ_SET_PTBA[] = {
+ 0xBF,
+ 0x5F, 0x00, 0x00, 0x06,
+};
+
+const unsigned char SEQ_SET_PANEL[] = {
+ 0xCC, 0x0e,
+};
+
+const unsigned char SEQ_SET_DGC[] = {
+ 0xC1, 0x00,
+};
+
+const unsigned char SEQ_SET_STBA[] = {
+ 0xC0,
+ 0x73, 0x50, 0x00, 0x1f, 0x04, 0x04,
+};
+
+const unsigned char SEQ_SET_EQ[] = {
+ 0xE3,
+ 0x03, 0x03, 0x03, 0x03,
+};
+
+const unsigned char SEQ_SET_VCOM_POWER[] = {
+ 0xEA, 0x7A,
+};
+
+const unsigned char SEQ_SET_ECO[] = {
+ 0xC6, 0x40,
+};
+
+const unsigned char SEQ_SET_GAMMA[] = {
+ 0xE0,
+ 0x00, 0x1C, 0x20, 0x35, 0x3A, 0x3F, 0x31, 0x4c, 0x08, 0x0E,
+ 0x0E, 0x12, 0x13, 0x11, 0x13, 0x18, 0x1D, 0x00, 0x1C, 0x20,
+ 0x35, 0x3A, 0x3F, 0x31, 0x4c, 0x08, 0x0E, 0x0E, 0x12, 0x13,
+ 0x11, 0x13, 0x18, 0x1D, 0x01,
+};
+
+const unsigned char SEQ_SET_CABC_PWM[] = {
+ 0xC9,
+ 0x0F, 0x00,
+};
+
+unsigned char SEQ_SET_BL[] = {
+ 0x51, 0xFF,
+};
+
+const unsigned char SEQ_SET_DISP[] = {
+ 0x53, 0x24,
+};
+
+const unsigned char SEQ_SET_CABC_ON[] = {
+ 0x55, 0x02,
+};
+
+const unsigned char SEQ_SET_CABC_OFF[] = {
+ 0x55, 0x00,
+};
+
+const unsigned char SEQ_SLEEP_IN[] = {
+ 0x10,
+};
+
+const unsigned char SEQ_SLEEP_OUT[] = {
+ 0x11,
+};
+
+const unsigned char SEQ_DISPLAY_ON[] = {
+ 0x29,
+};
+
+const unsigned char SEQ_DISPLAY_OFF[] = {
+ 0x28,
+};
+
+enum {
+ GAMMA_30CD = 0,
+ GAMMA_40CD,
+ GAMMA_70CD,
+ GAMMA_90CD,
+ GAMMA_100CD,
+ GAMMA_110CD,
+ GAMMA_120CD,
+ GAMMA_130CD,
+ GAMMA_140CD,
+ GAMMA_150CD,
+ GAMMA_160CD,
+ GAMMA_170CD,
+ GAMMA_180CD,
+ GAMMA_190CD,
+ GAMMA_200CD,
+ GAMMA_210CD,
+ GAMMA_220CD,
+ GAMMA_230CD,
+ GAMMA_240CD,
+ GAMMA_250CD,
+ GAMMA_260CD,
+ GAMMA_270CD,
+ GAMMA_280CD,
+ GAMMA_290CD,
+ GAMMA_300CD = 24,
+ GAMMA_MAX
+};
+
+#define GAMMA_PARAM_SIZE 26
+
+#endif /* __LMS501XX_H__ */
diff --git a/drivers/video/samsung/mdnie_table_baffin.h b/drivers/video/samsung/mdnie_table_baffin.h
new file mode 100644
index 0000000..a3df222
--- /dev/null
+++ b/drivers/video/samsung/mdnie_table_baffin.h
@@ -0,0 +1,803 @@
+#ifndef __MDNIE_TABLE_H__
+#define __MDNIE_TABLE_H__
+
+#include "mdnie.h"
+
+
+static const unsigned short tune_dynamic_gallery[] = {
+ 0x0000, 0x0000, /*BANK 0*/
+ 0x0008, 0x008c,
+ /*Dither8 UC4 ABC2 CP1 | CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/
+ 0x0030, 0x0000, /*FA cs1 de8 hdr2 fa1*/
+ 0x0092, 0x0080, /*DE pe*/
+ 0x0093, 0x0080, /*DE pf*/
+ 0x0094, 0x0080, /*DE pb*/
+ 0x0095, 0x0080, /*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, 0x1404, /*CS weight grayTH*/
+ 0x0000, 0x0001, /*BANK 1*/
+ 0x001f, 0x0080, /*CC chsel strength*/
+ 0x0020, 0x0000, /*CC lut r 0*/
+ 0x0021, 0x0293, /*CC lut r 16 144*/
+ 0x0022, 0x1aa5, /*CC lut r 32 160*/
+ 0x0023, 0x29b7, /*CC lut r 48 176*/
+ 0x0024, 0x39c8, /*CC lut r 64 192*/
+ 0x0025, 0x4bd8, /*CC lut r 80 208*/
+ 0x0026, 0x5de6, /*CC lut r 96 224*/
+ 0x0027, 0x6ff4, /*CC lut r 112 240*/
+ 0x0028, 0x81ff, /*CC lut r 128 255*/
+ 0x00ff, 0x0000, /*Mask Release*/
+ END_SEQ, 0x0000,
+};
+
+static const unsigned short tune_dynamic_ui[] = {
+ 0x0000, 0x0000, /*BANK 0*/
+ 0x0008, 0x008c,
+ /*Dither8 UC4 ABC2 CP1 | CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/
+ 0x0030, 0x0000, /*FA cs1 de8 hdr2 fa1*/
+ 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, 0x1804, /*CS weight grayTH*/
+ 0x0000, 0x0001, /*BANK 1*/
+ 0x001f, 0x0080, /*CC chsel strength*/
+ 0x0020, 0x0000, /*CC lut r 0*/
+ 0x0021, 0x0293, /*CC lut r 16 144*/
+ 0x0022, 0x1aa5, /*CC lut r 32 160*/
+ 0x0023, 0x29b7, /*CC lut r 48 176*/
+ 0x0024, 0x39c8, /*CC lut r 64 192*/
+ 0x0025, 0x4bd8, /*CC lut r 80 208*/
+ 0x0026, 0x5de6, /*CC lut r 96 224*/
+ 0x0027, 0x6ff4, /*CC lut r 112 240*/
+ 0x0028, 0x81ff, /*CC lut r 128 255*/
+ 0x00ff, 0x0000, /*Mask Release*/
+ END_SEQ, 0x0000,
+};
+
+static const unsigned short tune_dynamic_video[] = {
+ 0x0000, 0x0000, /*BANK 0*/
+ 0x0008, 0x008c,
+ /*Dither8 UC4 ABC2 CP1 | CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/
+ 0x0030, 0x0000, /*FA cs1 de8 hdr2 fa1*/
+ 0x0092, 0x0080, /*DE pe*/
+ 0x0093, 0x0080, /*DE pf*/
+ 0x0094, 0x0080, /*DE pb*/
+ 0x0095, 0x0080, /*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, 0x1404, /*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, 0x00ff, /*SCR KgWg*/
+ 0x00ec, 0x00ff, /*SCR KbWb*/
+ 0x0000, 0x0001, /*BANK 1*/
+ 0x001f, 0x0080, /*CC chsel strength*/
+ 0x0020, 0x0000, /*CC lut r 0*/
+ 0x0021, 0x0293, /*CC lut r 16 144*/
+ 0x0022, 0x1aa5, /*CC lut r 32 160*/
+ 0x0023, 0x29b7, /*CC lut r 48 176*/
+ 0x0024, 0x39c8, /*CC lut r 64 192*/
+ 0x0025, 0x4bd8, /*CC lut r 80 208*/
+ 0x0026, 0x5de6, /*CC lut r 96 224*/
+ 0x0027, 0x6ff4, /*CC lut r 112 240*/
+ 0x0028, 0x81ff, /*CC lut r 128 255*/
+ 0x00ff, 0x0000, /*Mask Release*/
+ END_SEQ, 0x0000,
+};
+
+static const unsigned short tune_dynamic_vt[] = {
+ 0x0000, 0x0000, /*BANK 0*/
+ 0x0008, 0x008e,
+ /*Dither8 UC4 ABC2 CP1 | CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/
+ 0x0030, 0x0005, /*FA cs1 | de8 dnr4 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, 0x0010, /*DE min ratio*/
+ 0x00b0, 0x1010, /*CS hg ry*/
+ 0x00b1, 0x1010, /*CS hg gc*/
+ 0x00b2, 0x1010, /*CS hg bm*/
+ 0x00b3, 0x1a04, /*CS weight grayTH*/
+ 0x0000, 0x0001, /*BANK 1*/
+ 0x001f, 0x0080, /*CC chsel strength*/
+ 0x0020, 0x0000, /*CC lut r 0*/
+ 0x0021, 0x0293, /*CC lut r 16 144*/
+ 0x0022, 0x1aa5, /*CC lut r 32 160*/
+ 0x0023, 0x29b7, /*CC lut r 48 176*/
+ 0x0024, 0x39c8, /*CC lut r 64 192*/
+ 0x0025, 0x4bd8, /*CC lut r 80 208*/
+ 0x0026, 0x5de6, /*CC lut r 96 224*/
+ 0x0027, 0x6ff4, /*CC lut r 112 240*/
+ 0x0028, 0x81ff, /*CC lut r 128 255*/
+ 0x00ff, 0x0000, /*Mask Release*/
+ END_SEQ, 0x0000,
+};
+
+static const unsigned short tune_movie_gallery[] = {
+ 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*/
+ 0x00e1, 0xd6ac, /*SCR RrCr*/
+ 0x00e2, 0x32ff, /*SCR RgCg*/
+ 0x00e3, 0x2ef0, /*SCR RbCb*/
+ 0x00e4, 0xa5fa, /*SCR GrMr*/
+ 0x00e5, 0xff4d, /*SCR GgMg*/
+ 0x00e6, 0x59ff, /*SCR GbMb*/
+ 0x00e7, 0x00ff, /*SCR BrYr*/
+ 0x00e8, 0x00fb, /*SCR BgYg*/
+ 0x00e9, 0xff61, /*SCR BbYb*/
+ 0x00ea, 0x00ff, /*SCR KrWr*/
+ 0x00eb, 0x00f8, /*SCR KgWg*/
+ 0x00ec, 0x00f1, /*SCR KbWb*/
+ 0x0000, 0x0001, /*BANK 1*/
+ 0x001f, 0x0080, /*CC chsel strength*/
+ 0x0020, 0x0000, /*CC lut r 0*/
+ 0x0021, 0x0290, /*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 const unsigned short tune_movie_ui[] = {
+ 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*/
+ 0x00e1, 0xd6ac, /*SCR RrCr*/
+ 0x00e2, 0x32ff, /*SCR RgCg*/
+ 0x00e3, 0x2ef0, /*SCR RbCb*/
+ 0x00e4, 0xa5fa, /*SCR GrMr*/
+ 0x00e5, 0xff4d, /*SCR GgMg*/
+ 0x00e6, 0x59ff, /*SCR GbMb*/
+ 0x00e7, 0x00ff, /*SCR BrYr*/
+ 0x00e8, 0x00fb, /*SCR BgYg*/
+ 0x00e9, 0xff61, /*SCR BbYb*/
+ 0x00ea, 0x00ff, /*SCR KrWr*/
+ 0x00eb, 0x00f8, /*SCR KgWg*/
+ 0x00ec, 0x00f1, /*SCR KbWb*/
+ 0x0000, 0x0001, /*BANK 1*/
+ 0x001f, 0x0080, /*CC chsel strength*/
+ 0x0020, 0x0000, /*CC lut r 0*/
+ 0x0021, 0x0290, /*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 const unsigned short tune_movie_video[] = {
+ 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*/
+ 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, 0xd6ac, /*SCR RrCr*/
+ 0x00e2, 0x32ff, /*SCR RgCg*/
+ 0x00e3, 0x2ef0, /*SCR RbCb*/
+ 0x00e4, 0xa5fa, /*SCR GrMr*/
+ 0x00e5, 0xff4d, /*SCR GgMg*/
+ 0x00e6, 0x59ff, /*SCR GbMb*/
+ 0x00e7, 0x00ff, /*SCR BrYr*/
+ 0x00e8, 0x00fb, /*SCR BgYg*/
+ 0x00e9, 0xff61, /*SCR BbYb*/
+ 0x00ea, 0x00ff, /*SCR KrWr*/
+ 0x00eb, 0x00f8, /*SCR KgWg*/
+ 0x00ec, 0x00f1, /*SCR KbWb*/
+ 0x0000, 0x0001, /*BANK 1*/
+ 0x001f, 0x0080, /*CC chsel strength*/
+ 0x0020, 0x0000, /*CC lut r 0*/
+ 0x0021, 0x0290, /*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 const unsigned short tune_movie_vt[] = {
+ 0x0000, 0x0000, /*BANK 0*/
+ 0x0008, 0x00ae,
+ /*Dither8 UC4 ABC2 CP1 | CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/
+ 0x0030, 0x0005, /*FA cs1 | de8 dnr4 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, 0x0010, /*DE min ratio*/
+ 0x00b0, 0x1010, /*CS hg ry*/
+ 0x00b1, 0x1010, /*CS hg gc*/
+ 0x00b2, 0x1010, /*CS hg bm*/
+ 0x00b3, 0x1204, /*CS weight grayTH*/
+ 0x00e1, 0xd6ac, /*SCR RrCr*/
+ 0x00e2, 0x32ff, /*SCR RgCg*/
+ 0x00e3, 0x2ef0, /*SCR RbCb*/
+ 0x00e4, 0xa5fa, /*SCR GrMr*/
+ 0x00e5, 0xff4d, /*SCR GgMg*/
+ 0x00e6, 0x59ff, /*SCR GbMb*/
+ 0x00e7, 0x00ff, /*SCR BrYr*/
+ 0x00e8, 0x00fb, /*SCR BgYg*/
+ 0x00e9, 0xff61, /*SCR BbYb*/
+ 0x00ea, 0x00ff, /*SCR KrWr*/
+ 0x00eb, 0x00f8, /*SCR KgWg*/
+ 0x00ec, 0x00f1, /*SCR KbWb*/
+ 0x0000, 0x0001, /*BANK 1*/
+ 0x001f, 0x0080, /*CC chsel strength*/
+ 0x0020, 0x0000, /*CC lut r 0*/
+ 0x0021, 0x0290, /*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 const unsigned short tune_standard_gallery[] = {
+ 0x0000, 0x0000, /*BANK 0*/
+ 0x0008, 0x008c,
+ /*Dither8 UC4 ABC2 CP1 | CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/
+ 0x0030, 0x0000, /*FA cs1 de8 hdr2 fa1*/
+ 0x0092, 0x0060, /*DE pe*/
+ 0x0093, 0x0060, /*DE pf*/
+ 0x0094, 0x0060, /*DE pb*/
+ 0x0095, 0x0060, /*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, 0x1204, /*CS weight grayTH*/
+ 0x0000, 0x0001, /*BANK 1*/
+ 0x001f, 0x0080, /*CC chsel strength*/
+ 0x0020, 0x0000, /*CC lut r 0*/
+ 0x0021, 0x0290, /*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 const unsigned short tune_standard_ui[] = {
+ 0x0000, 0x0000, /*BANK 0*/
+ 0x0008, 0x008c,
+ /*Dither8 UC4 ABC2 CP1 | CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/
+ 0x0030, 0x0000, /*FA cs1 de8 hdr2 fa1*/
+ 0x0092, 0x0020, /*DE pe*/
+ 0x0093, 0x0020, /*DE pf*/
+ 0x0094, 0x0020, /*DE pb*/
+ 0x0095, 0x0020, /*DE ne*/
+ 0x0096, 0x0020, /*DE nf*/
+ 0x0097, 0x0020, /*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, 0x1604, /*CS weight grayTH*/
+ 0x0000, 0x0001, /*BANK 1*/
+ 0x001f, 0x0080, /*CC chsel strength*/
+ 0x0020, 0x0000, /*CC lut r 0*/
+ 0x0021, 0x0290, /*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 const unsigned short tune_standard_video[] = {
+ 0x0000, 0x0000, /*BANK 0*/
+ 0x0008, 0x008c,
+ /*Dither8 UC4 ABC2 CP1 | CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/
+ 0x0030, 0x0000, /*FA cs1 de8 hdr2 fa1*/
+ 0x0092, 0x0060, /*DE pe*/
+ 0x0093, 0x0060, /*DE pf*/
+ 0x0094, 0x0060, /*DE pb*/
+ 0x0095, 0x0060, /*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, 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, 0x00ff, /*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, 0x0290, /*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 const unsigned short tune_standard_vt[] = {
+ 0x0000, 0x0000, /*BANK 0*/
+ 0x0008, 0x008e,
+ /*Dither8 UC4 ABC2 CP1 | CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/
+ 0x0030, 0x0005, /*FA cs1 | de8 dnr4 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, 0x0010, /*DE min ratio*/
+ 0x00b0, 0x1010, /*CS hg ry*/
+ 0x00b1, 0x1010, /*CS hg gc*/
+ 0x00b2, 0x1010, /*CS hg bm*/
+ 0x00b3, 0x1804, /*CS weight grayTH*/
+ 0x0000, 0x0001, /*BANK 1*/
+ 0x001f, 0x0080, /*CC chsel strength*/
+ 0x0020, 0x0000, /*CC lut r 0*/
+ 0x0021, 0x0290, /*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 const unsigned short tune_natural_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*/
+ 0x0092, 0x0060, /*DE pe*/
+ 0x0093, 0x0060, /*DE pf*/
+ 0x0094, 0x0060, /*DE pb*/
+ 0x0095, 0x0060, /*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, 0xd6ac, /*SCR RrCr*/
+ 0x00e2, 0x32ff, /*SCR RgCg*/
+ 0x00e3, 0x2ef0, /*SCR RbCb*/
+ 0x00e4, 0xa5fa, /*SCR GrMr*/
+ 0x00e5, 0xff4d, /*SCR GgMg*/
+ 0x00e6, 0x59ff, /*SCR GbMb*/
+ 0x00e7, 0x00ff, /*SCR BrYr*/
+ 0x00e8, 0x00fb, /*SCR BgYg*/
+ 0x00e9, 0xff61, /*SCR BbYb*/
+ 0x00ea, 0x00ff, /*SCR KrWr*/
+ 0x00eb, 0x00fa, /*SCR KgWg*/
+ 0x00ec, 0x00f8, /*SCR KbWb*/
+ 0x0000, 0x0001, /*BANK 1*/
+ 0x001f, 0x0080, /*CC chsel strength*/
+ 0x0020, 0x0000, /*CC lut r 0*/
+ 0x0021, 0x0290, /*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 const unsigned short tune_natural_ui[] = {
+ 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*/
+ 0x0092, 0x0020, /*DE pe*/
+ 0x0093, 0x0020, /*DE pf*/
+ 0x0094, 0x0020, /*DE pb*/
+ 0x0095, 0x0020, /*DE ne*/
+ 0x0096, 0x0020, /*DE nf*/
+ 0x0097, 0x0020, /*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, 0xd6ac, /*SCR RrCr*/
+ 0x00e2, 0x32ff, /*SCR RgCg*/
+ 0x00e3, 0x2ef0, /*SCR RbCb*/
+ 0x00e4, 0xa5fa, /*SCR GrMr*/
+ 0x00e5, 0xff4d, /*SCR GgMg*/
+ 0x00e6, 0x59ff, /*SCR GbMb*/
+ 0x00e7, 0x00ff, /*SCR BrYr*/
+ 0x00e8, 0x00fb, /*SCR BgYg*/
+ 0x00e9, 0xff61, /*SCR BbYb*/
+ 0x00ea, 0x00ff, /*SCR KrWr*/
+ 0x00eb, 0x00fa, /*SCR KgWg*/
+ 0x00ec, 0x00f8, /*SCR KbWb*/
+ 0x0000, 0x0001, /*BANK 1*/
+ 0x001f, 0x0080, /*CC chsel strength*/
+ 0x0020, 0x0000, /*CC lut r 0*/
+ 0x0021, 0x0290, /*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 const unsigned short tune_natural_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*/
+ 0x0092, 0x0060, /*DE pe*/
+ 0x0093, 0x0060, /*DE pf*/
+ 0x0094, 0x0060, /*DE pb*/
+ 0x0095, 0x0060, /*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, 0xd6ac, /*SCR RrCr*/
+ 0x00e2, 0x32ff, /*SCR RgCg*/
+ 0x00e3, 0x2ef0, /*SCR RbCb*/
+ 0x00e4, 0xa5fa, /*SCR GrMr*/
+ 0x00e5, 0xff4d, /*SCR GgMg*/
+ 0x00e6, 0x59ff, /*SCR GbMb*/
+ 0x00e7, 0x00ff, /*SCR BrYr*/
+ 0x00e8, 0x00fb, /*SCR BgYg*/
+ 0x00e9, 0xff61, /*SCR BbYb*/
+ 0x00ea, 0x00ff, /*SCR KrWr*/
+ 0x00eb, 0x00fa, /*SCR KgWg*/
+ 0x00ec, 0x00f8, /*SCR KbWb*/
+ 0x0000, 0x0001, /*BANK 1*/
+ 0x001f, 0x0080, /*CC chsel strength*/
+ 0x0020, 0x0000, /*CC lut r 0*/
+ 0x0021, 0x0290, /*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 const unsigned short tune_natural_vt[] = {
+ 0x0000, 0x0000, /*BANK 0*/
+ 0x0008, 0x00ae,
+ /*Dither8 UC4 ABC2 CP1 | CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/
+ 0x0030, 0x0005, /*FA cs1 | de8 dnr4 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, 0x0010, /*DE min ratio*/
+ 0x00b0, 0x1010, /*CS hg ry*/
+ 0x00b1, 0x1010, /*CS hg gc*/
+ 0x00b2, 0x1010, /*CS hg bm*/
+ 0x00b3, 0x1804, /*CS weight grayTH*/
+ 0x00e1, 0xd6ac, /*SCR RrCr*/
+ 0x00e2, 0x32ff, /*SCR RgCg*/
+ 0x00e3, 0x2ef0, /*SCR RbCb*/
+ 0x00e4, 0xa5fa, /*SCR GrMr*/
+ 0x00e5, 0xff4d, /*SCR GgMg*/
+ 0x00e6, 0x59ff, /*SCR GbMb*/
+ 0x00e7, 0x00ff, /*SCR BrYr*/
+ 0x00e8, 0x00fb, /*SCR BgYg*/
+ 0x00e9, 0xff61, /*SCR BbYb*/
+ 0x00ea, 0x00ff, /*SCR KrWr*/
+ 0x00eb, 0x00fa, /*SCR KgWg*/
+ 0x00ec, 0x00f8, /*SCR KbWb*/
+ 0x0000, 0x0001, /*BANK 1*/
+ 0x001f, 0x0080, /*CC chsel strength*/
+ 0x0020, 0x0000, /*CC lut r 0*/
+ 0x0021, 0x0290, /*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 const unsigned short tune_camera[] = {
+ 0x0000, 0x0000, /*BANK 0*/
+ 0x0008, 0x000c,
+ /*Dither8 UC4 ABC2 CP1 | CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/
+ 0x0030, 0x0000, /*FA cs1 de8 hdr2 fa1*/
+ 0x0092, 0x0060, /*DE pe*/
+ 0x0093, 0x0060, /*DE pf*/
+ 0x0094, 0x0060, /*DE pb*/
+ 0x0095, 0x0060, /*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, 0x1204, /*CS weight grayTH*/
+ 0x00ff, 0x0000, /*Mask Release*/
+ END_SEQ, 0x0000,
+};
+
+static const unsigned short tune_camera_outdoor[] = {
+ 0x0000, 0x0000, /*BANK 0*/
+ 0x0008, 0x040c,
+ /*Dither8 UC4 ABC2 CP1 | CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/
+ 0x0030, 0x0000, /*FA cs1 de8 hdr2 fa1*/
+ 0x0092, 0x0060, /*DE pe*/
+ 0x0093, 0x0060, /*DE pf*/
+ 0x0094, 0x0060, /*DE pb*/
+ 0x0095, 0x0060, /*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, 0x1204, /*CS weight grayTH*/
+ 0x0000, 0x0001, /*BANK 1*/
+ 0x00d0, 0x01c0, /*UC y*/
+ 0x00d1, 0x01ff, /*UC cs*/
+ 0x00ff, 0x0000, /*Mask Release*/
+ END_SEQ, 0x0000,
+};
+
+static const 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, 0xa08b, /*MCM 5cb 1cr W*/
+ 0x000b, 0x7a7a, /*MCM 4cr 5cr W*/
+ 0x00ff, 0x0000, /*Mask Release*/
+ END_SEQ, 0x0000,
+};
+
+static const 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, 0xa08b, /*MCM 5cb 1cr W*/
+ 0x000b, 0x7a7a, /*MCM 4cr 5cr W*/
+ 0x00d0, 0x01c0, /*UC y*/
+ 0x00d1, 0x01ff, /*UC cs*/
+ 0x00ff, 0x0000, /*Mask Release*/
+ END_SEQ, 0x0000,
+};
+
+static const 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, 0x01c0, /*UC y*/
+ 0x00d1, 0x01ff, /*UC cs*/
+ 0x00ff, 0x0000, /*Mask Release*/
+ END_SEQ, 0x0000,
+};
+
+static const 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, 0x7878, /*MCM 1cb 2cb W*/
+ 0x0009, 0xa08b, /*MCM 5cb 1cr W*/
+ 0x00ff, 0x0000, /*Mask Release*/
+ END_SEQ, 0x0000,
+};
+
+static const 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, 0x7878, /*MCM 1cb 2cb W*/
+ 0x0009, 0xa08b, /*MCM 5cb 1cr W*/
+ 0x00d0, 0x01c0, /*UC y*/
+ 0x00d1, 0x01ff, /*UC cs*/
+ 0x00ff, 0x0000, /*Mask Release*/
+ END_SEQ, 0x0000,
+};
+
+struct mdnie_tunning_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_tunning_info tunning_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},
+ }, {
+ {"NATURAL_UI", tune_natural_ui},
+ {"NATURAL_VIDEO", tune_natural_video},
+ {"NATURAL_VIDEO_WARM", tune_natural_video},
+ {"NATURAL_VIDEO_COLD", tune_natural_video},
+ {"CAMERA", NULL},
+ {"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},
+ {"MOVIE_UI", tune_movie_ui},
+ {"MOVIE_GALLERY", tune_movie_gallery},
+ {"MOVIE_VT", tune_movie_vt},
+ },
+ }
+};
+
+struct mdnie_tunning_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
new file mode 100644
index 0000000..a3e9325
--- /dev/null
+++ b/drivers/video/samsung/mdnie_table_t0.h
@@ -0,0 +1,763 @@
+#ifndef __MDNIE_TABLE_H__
+#define __MDNIE_TABLE_H__
+
+#include "mdnie.h"
+
+
+static const unsigned short tune_dynamic_gallery[] = {
+ 0x0000, 0x0000, /*BANK 0*/
+ 0x0008, 0x008c, /*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, 0x1404, /*CS weight grayTH*/
+ 0x0000, 0x0001, /*BANK 1*/
+ 0x001f, 0x0080, /*CC chsel strength*/
+ 0x0020, 0x0000, /*CC lut r 0*/
+ 0x0021, 0x0d93, /*CC lut r 16 144*/
+ 0x0022, 0x1aa5, /*CC lut r 32 160*/
+ 0x0023, 0x29b7, /*CC lut r 48 176*/
+ 0x0024, 0x39c8, /*CC lut r 64 192*/
+ 0x0025, 0x4bd8, /*CC lut r 80 208*/
+ 0x0026, 0x5de6, /*CC lut r 96 224*/
+ 0x0027, 0x6ff4, /*CC lut r 112 240*/
+ 0x0028, 0x81ff, /*CC lut r 128 255*/
+ 0x00ff, 0x0000, /*Mask Release*/
+ END_SEQ, 0x0000,
+};
+
+static const unsigned short tune_dynamic_ui[] = {
+ 0x0000, 0x0000, /*BANK 0*/
+ 0x0008, 0x0088, /*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*/
+ 0x0000, 0x0001, /*BANK 1*/
+ 0x001f, 0x0080, /*CC chsel strength*/
+ 0x0020, 0x0000, /*CC lut r 0*/
+ 0x0021, 0x0d93, /*CC lut r 16 144*/
+ 0x0022, 0x1aa5, /*CC lut r 32 160*/
+ 0x0023, 0x29b7, /*CC lut r 48 176*/
+ 0x0024, 0x39c8, /*CC lut r 64 192*/
+ 0x0025, 0x4bd8, /*CC lut r 80 208*/
+ 0x0026, 0x5de6, /*CC lut r 96 224*/
+ 0x0027, 0x6ff4, /*CC lut r 112 240*/
+ 0x0028, 0x81ff, /*CC lut r 128 255*/
+ 0x00ff, 0x0000, /*Mask Release*/
+ END_SEQ, 0x0000,
+};
+
+static const unsigned short tune_dynamic_video[] = {
+ 0x0000, 0x0000, /*BANK 0*/
+ 0x0008, 0x008c, /*Dither8 UC4 ABC2 CP1 | CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/
+ 0x0030, 0x0000, /*FA cs1 de8 hdr2 fa1*/
+ 0x0092, 0x0080, /*DE pe*/
+ 0x0093, 0x0080, /*DE pf*/
+ 0x0094, 0x0080, /*DE pb*/
+ 0x0095, 0x0080, /*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, 0x1404, /*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, 0x00ff, /*SCR KgWg*/
+ 0x00ec, 0x00ff, /*SCR KbWb*/
+ 0x0000, 0x0001, /*BANK 1*/
+ 0x001f, 0x0080, /*CC chsel strength*/
+ 0x0020, 0x0000, /*CC lut r 0*/
+ 0x0021, 0x0d93, /*CC lut r 16 144*/
+ 0x0022, 0x1aa5, /*CC lut r 32 160*/
+ 0x0023, 0x29b7, /*CC lut r 48 176*/
+ 0x0024, 0x39c8, /*CC lut r 64 192*/
+ 0x0025, 0x4bd8, /*CC lut r 80 208*/
+ 0x0026, 0x5de6, /*CC lut r 96 224*/
+ 0x0027, 0x6ff4, /*CC lut r 112 240*/
+ 0x0028, 0x81ff, /*CC lut r 128 255*/
+ 0x00ff, 0x0000, /*Mask Release*/
+ END_SEQ, 0x0000,
+};
+
+static const unsigned short tune_dynamic_vt[] = {
+ 0x0000, 0x0000, /*BANK 0*/
+ 0x0008, 0x008e, /*Dither8 UC4 ABC2 CP1 | CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/
+ 0x0030, 0x0005, /*FA cs1 | de8 dnr4 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, 0x0010, /*DE min ratio*/
+ 0x00b0, 0x1010, /*CS hg ry*/
+ 0x00b1, 0x1010, /*CS hg gc*/
+ 0x00b2, 0x1010, /*CS hg bm*/
+ 0x00b3, 0x1a04, /*CS weight grayTH*/
+ 0x0000, 0x0001, /*BANK 1*/
+ 0x001f, 0x0080, /*CC chsel strength*/
+ 0x0020, 0x0000, /*CC lut r 0*/
+ 0x0021, 0x0d93, /*CC lut r 16 144*/
+ 0x0022, 0x1aa5, /*CC lut r 32 160*/
+ 0x0023, 0x29b7, /*CC lut r 48 176*/
+ 0x0024, 0x39c8, /*CC lut r 64 192*/
+ 0x0025, 0x4bd8, /*CC lut r 80 208*/
+ 0x0026, 0x5de6, /*CC lut r 96 224*/
+ 0x0027, 0x6ff4, /*CC lut r 112 240*/
+ 0x0028, 0x81ff, /*CC lut r 128 255*/
+ 0x00ff, 0x0000, /*Mask Release*/
+ END_SEQ, 0x0000,
+};
+
+static const unsigned short tune_movie_gallery[] = {
+ 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*/
+ 0x00e1, 0xd6ac, /*SCR RrCr*/
+ 0x00e2, 0x32ff, /*SCR RgCg*/
+ 0x00e3, 0x2ef0, /*SCR RbCb*/
+ 0x00e4, 0xa5fa, /*SCR GrMr*/
+ 0x00e5, 0xff4d, /*SCR GgMg*/
+ 0x00e6, 0x59ff, /*SCR GbMb*/
+ 0x00e7, 0x00ff, /*SCR BrYr*/
+ 0x00e8, 0x00fb, /*SCR BgYg*/
+ 0x00e9, 0xff61, /*SCR BbYb*/
+ 0x00ea, 0x00ff, /*SCR KrWr*/
+ 0x00eb, 0x00f8, /*SCR KgWg*/
+ 0x00ec, 0x00f1, /*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 const unsigned short tune_movie_ui[] = {
+ 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*/
+ 0x00e1, 0xd6ac, /*SCR RrCr*/
+ 0x00e2, 0x32ff, /*SCR RgCg*/
+ 0x00e3, 0x2ef0, /*SCR RbCb*/
+ 0x00e4, 0xa5fa, /*SCR GrMr*/
+ 0x00e5, 0xff4d, /*SCR GgMg*/
+ 0x00e6, 0x59ff, /*SCR GbMb*/
+ 0x00e7, 0x00ff, /*SCR BrYr*/
+ 0x00e8, 0x00fb, /*SCR BgYg*/
+ 0x00e9, 0xff61, /*SCR BbYb*/
+ 0x00ea, 0x00ff, /*SCR KrWr*/
+ 0x00eb, 0x00f8, /*SCR KgWg*/
+ 0x00ec, 0x00f1, /*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 const unsigned short tune_movie_video[] = {
+ 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*/
+ 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, 0xd6ac, /*SCR RrCr*/
+ 0x00e2, 0x32ff, /*SCR RgCg*/
+ 0x00e3, 0x2ef0, /*SCR RbCb*/
+ 0x00e4, 0xa5fa, /*SCR GrMr*/
+ 0x00e5, 0xff4d, /*SCR GgMg*/
+ 0x00e6, 0x59ff, /*SCR GbMb*/
+ 0x00e7, 0x00ff, /*SCR BrYr*/
+ 0x00e8, 0x00fb, /*SCR BgYg*/
+ 0x00e9, 0xff61, /*SCR BbYb*/
+ 0x00ea, 0x00ff, /*SCR KrWr*/
+ 0x00eb, 0x00f8, /*SCR KgWg*/
+ 0x00ec, 0x00f1, /*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 const unsigned short tune_movie_vt[] = {
+ 0x0000, 0x0000, /*BANK 0*/
+ 0x0008, 0x00ae, /*Dither8 UC4 ABC2 CP1 | CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/
+ 0x0030, 0x0005, /*FA cs1 | de8 dnr4 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, 0x0042, /*DE pe*/
+ 0x0093, 0x0042, /*DE pf*/
+ 0x0094, 0x0042, /*DE pb*/
+ 0x0095, 0x0042, /*DE ne*/
+ 0x0096, 0x0042, /*DE nf*/
+ 0x0097, 0x0042, /*DE nb*/
+ 0x0098, 0x1000, /*DE max ratio*/
+ 0x0099, 0x0010, /*DE min ratio*/
+ 0x00b0, 0x1010, /*CS hg ry*/
+ 0x00b1, 0x1010, /*CS hg gc*/
+ 0x00b2, 0x1010, /*CS hg bm*/
+ 0x00b3, 0x1204, /*CS weight grayTH*/
+ 0x00e1, 0xd6ac, /*SCR RrCr*/
+ 0x00e2, 0x32ff, /*SCR RgCg*/
+ 0x00e3, 0x2ef0, /*SCR RbCb*/
+ 0x00e4, 0xa5fa, /*SCR GrMr*/
+ 0x00e5, 0xff4d, /*SCR GgMg*/
+ 0x00e6, 0x59ff, /*SCR GbMb*/
+ 0x00e7, 0x00ff, /*SCR BrYr*/
+ 0x00e8, 0x00fb, /*SCR BgYg*/
+ 0x00e9, 0xff61, /*SCR BbYb*/
+ 0x00ea, 0x00ff, /*SCR KrWr*/
+ 0x00eb, 0x00f8, /*SCR KgWg*/
+ 0x00ec, 0x00f1, /*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 const unsigned short tune_standard_gallery[] = {
+ 0x0000, 0x0000, /*BANK 0*/
+ 0x0008, 0x008c, /*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, 0x1204, /*CS weight grayTH*/
+ 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 const unsigned short tune_standard_ui[] = {
+ 0x0000, 0x0000, /*BANK 0*/
+ 0x0008, 0x0088, /*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, 0x1604, /*CS weight grayTH*/
+ 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 const unsigned short tune_standard_video[] = {
+ 0x0000, 0x0000, /*BANK 0*/
+ 0x0008, 0x008c, /*Dither8 UC4 ABC2 CP1 | CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/
+ 0x0030, 0x0000, /*FA cs1 de8 hdr2 fa1*/
+ 0x0092, 0x0060, /*DE pe*/
+ 0x0093, 0x0060, /*DE pf*/
+ 0x0094, 0x0060, /*DE pb*/
+ 0x0095, 0x0060, /*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, 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, 0x00ff, /*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, 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 const unsigned short tune_standard_vt[] = {
+ 0x0000, 0x0000, /*BANK 0*/
+ 0x0008, 0x008e, /*Dither8 UC4 ABC2 CP1 | CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/
+ 0x0030, 0x0005, /*FA cs1 | de8 dnr4 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, 0x0010, /*DE min ratio*/
+ 0x00b0, 0x1010, /*CS hg ry*/
+ 0x00b1, 0x1010, /*CS hg gc*/
+ 0x00b2, 0x1010, /*CS hg bm*/
+ 0x00b3, 0x1804, /*CS weight grayTH*/
+ 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 const unsigned short tune_natural_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, 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, 0xd6ac, /*SCR RrCr*/
+ 0x00e2, 0x32ff, /*SCR RgCg*/
+ 0x00e3, 0x2ef0, /*SCR RbCb*/
+ 0x00e4, 0xa5fa, /*SCR GrMr*/
+ 0x00e5, 0xff4d, /*SCR GgMg*/
+ 0x00e6, 0x59ff, /*SCR GbMb*/
+ 0x00e7, 0x00ff, /*SCR BrYr*/
+ 0x00e8, 0x00fb, /*SCR BgYg*/
+ 0x00e9, 0xff61, /*SCR BbYb*/
+ 0x00ea, 0x00ff, /*SCR KrWr*/
+ 0x00eb, 0x00fa, /*SCR KgWg*/
+ 0x00ec, 0x00f8, /*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 const unsigned short tune_natural_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, 0x1804, /*CS weight grayTH*/
+ 0x00e1, 0xd6ac, /*SCR RrCr*/
+ 0x00e2, 0x32ff, /*SCR RgCg*/
+ 0x00e3, 0x2ef0, /*SCR RbCb*/
+ 0x00e4, 0xa5fa, /*SCR GrMr*/
+ 0x00e5, 0xff4d, /*SCR GgMg*/
+ 0x00e6, 0x59ff, /*SCR GbMb*/
+ 0x00e7, 0x00ff, /*SCR BrYr*/
+ 0x00e8, 0x00fb, /*SCR BgYg*/
+ 0x00e9, 0xff61, /*SCR BbYb*/
+ 0x00ea, 0x00ff, /*SCR KrWr*/
+ 0x00eb, 0x00fa, /*SCR KgWg*/
+ 0x00ec, 0x00f8, /*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 const unsigned short tune_natural_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, 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, 0xd6ac, /*SCR RrCr*/
+ 0x00e2, 0x32ff, /*SCR RgCg*/
+ 0x00e3, 0x2ef0, /*SCR RbCb*/
+ 0x00e4, 0xa5fa, /*SCR GrMr*/
+ 0x00e5, 0xff4d, /*SCR GgMg*/
+ 0x00e6, 0x59ff, /*SCR GbMb*/
+ 0x00e7, 0x00ff, /*SCR BrYr*/
+ 0x00e8, 0x00fb, /*SCR BgYg*/
+ 0x00e9, 0xff61, /*SCR BbYb*/
+ 0x00ea, 0x00ff, /*SCR KrWr*/
+ 0x00eb, 0x00fa, /*SCR KgWg*/
+ 0x00ec, 0x00f8, /*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 const unsigned short tune_natural_vt[] = {
+ 0x0000, 0x0000, /*BANK 0*/
+ 0x0008, 0x00ae, /*Dither8 UC4 ABC2 CP1 | CC8 MCM4 SCR2 SCC1 | CS8 DE4 DNR2 HDR1*/
+ 0x0030, 0x0005, /*FA cs1 | de8 dnr4 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, 0x0010, /*DE min ratio*/
+ 0x00b0, 0x1010, /*CS hg ry*/
+ 0x00b1, 0x1010, /*CS hg gc*/
+ 0x00b2, 0x1010, /*CS hg bm*/
+ 0x00b3, 0x1804, /*CS weight grayTH*/
+ 0x00e1, 0xd6ac, /*SCR RrCr*/
+ 0x00e2, 0x32ff, /*SCR RgCg*/
+ 0x00e3, 0x2ef0, /*SCR RbCb*/
+ 0x00e4, 0xa5fa, /*SCR GrMr*/
+ 0x00e5, 0xff4d, /*SCR GgMg*/
+ 0x00e6, 0x59ff, /*SCR GbMb*/
+ 0x00e7, 0x00ff, /*SCR BrYr*/
+ 0x00e8, 0x00fb, /*SCR BgYg*/
+ 0x00e9, 0xff61, /*SCR BbYb*/
+ 0x00ea, 0x00ff, /*SCR KrWr*/
+ 0x00eb, 0x00fa, /*SCR KgWg*/
+ 0x00ec, 0x00f8, /*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 const unsigned short tune_camera[] = {
+ 0x0000, 0x0000, /*BANK 0*/
+ 0x0008, 0x000c, /*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, 0x1204, /*CS weight grayTH*/
+ 0x00ff, 0x0000, /*Mask Release*/
+ END_SEQ, 0x0000,
+};
+
+static const unsigned short tune_camera_outdoor[] = {
+ 0x0000, 0x0000, /*BANK 0*/
+ 0x0008, 0x040c, /*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, 0x1204, /*CS weight grayTH*/
+ 0x0000, 0x0001, /*BANK 1*/
+ 0x00d0, 0x01c0, /*UC y*/
+ 0x00d1, 0x01ff, /*UC cs*/
+ 0x00ff, 0x0000, /*Mask Release*/
+ END_SEQ, 0x0000,
+};
+
+static const 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, 0xa08b, /*MCM 5cb 1cr W*/
+ 0x000b, 0x7a7a, /*MCM 4cr 5cr W*/
+ 0x00ff, 0x0000, /*Mask Release*/
+ END_SEQ, 0x0000,
+};
+
+static const 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, 0xa08b, /*MCM 5cb 1cr W*/
+ 0x000b, 0x7a7a, /*MCM 4cr 5cr W*/
+ 0x00d0, 0x01c0, /*UC y*/
+ 0x00d1, 0x01ff, /*UC cs*/
+ 0x00ff, 0x0000, /*Mask Release*/
+ END_SEQ, 0x0000,
+};
+
+static const 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, 0x01c0, /*UC y*/
+ 0x00d1, 0x01ff, /*UC cs*/
+ 0x00ff, 0x0000, /*Mask Release*/
+ END_SEQ, 0x0000,
+};
+
+static const 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, 0x7878, /*MCM 1cb 2cb W*/
+ 0x0009, 0xa08b, /*MCM 5cb 1cr W*/
+ 0x00ff, 0x0000, /*Mask Release*/
+ END_SEQ, 0x0000,
+};
+
+static const 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, 0x7878, /*MCM 1cb 2cb W*/
+ 0x0009, 0xa08b, /*MCM 5cb 1cr W*/
+ 0x00d0, 0x01c0, /*UC y*/
+ 0x00d1, 0x01ff, /*UC cs*/
+ 0x00ff, 0x0000, /*Mask Release*/
+ END_SEQ, 0x0000,
+};
+
+struct mdnie_tunning_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_tunning_info tunning_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},
+ }, {
+ {"NATURAL_UI", tune_natural_ui},
+ {"NATURAL_VIDEO", tune_natural_video},
+ {"NATURAL_VIDEO_WARM", tune_natural_video},
+ {"NATURAL_VIDEO_COLD", tune_natural_video},
+ {"CAMERA", NULL},
+ {"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},
+ {"MOVIE_UI", tune_movie_ui},
+ {"MOVIE_GALLERY", tune_movie_gallery},
+ {"MOVIE_VT", tune_movie_vt},
+ },
+ }
+};
+
+struct mdnie_tunning_info camera_table[OUTDOOR_MAX] = {
+ {"CAMERA", tune_camera},
+ {"CAMERA_OUTDOOR", tune_camera_outdoor},
+};
+
+#endif/* __MDNIE_TABLE_H__ */
+
diff --git a/drivers/video/samsung/s3cfb.h b/drivers/video/samsung/s3cfb.h
index b278184..0831ac8 100644
--- a/drivers/video/samsung/s3cfb.h
+++ b/drivers/video/samsung/s3cfb.h
@@ -22,6 +22,7 @@
#endif
#include <plat/fb-s5p.h>
#endif
+#include <linux/kthread.h>
#include <mach/cpufreq.h>
#define S3CFB_NAME "s3cfb"
@@ -42,10 +43,19 @@
#define POWER_ON 1
#define POWER_OFF 0
+#define VSYNC_TIMEOUT_MSEC 50
+
#if defined(CONFIG_MACH_PX) || defined(CONFIG_MACH_Q1_BD)
#define FEATURE_BUSFREQ_LOCK /* Now, this feature only avaliable in 4210 */
#endif
+/* S3C_FB_MAX_WIN
+ * Set to the maximum number of windows that any of the supported hardware
+ * can use. Since the platform data uses this for an array size, having it
+ * set to the maximum of any version of the hardware can do is safe.
+ */
+#define S3C_FB_MAX_WIN (5)
+
enum s3cfb_data_path_t {
DATA_PATH_FIFO = 0,
DATA_PATH_DMA = 1,
@@ -145,6 +155,7 @@ struct s3cfb_lcd {
int p_height;
int bpp;
int freq;
+ int freq_limit;
int vclk;
struct s3cfb_lcd_timing timing;
struct s3cfb_lcd_polarity polarity;
@@ -161,6 +172,32 @@ struct s3cfb_fimd_desc {
struct s3cfb_global *fbdev[FIMD_MAX];
};
+/**
+ * struct s3cfb_vsync - vsync information+
+ * @wait: a queue for processes waiting for vsync
+ * @timestamp: the time of the last vsync interrupt
+ * @active: whether userspace is requesting vsync uevents
+ * @irq_refcount: reference count for the underlying irq
+ * @irq_lock: mutex protecting the irq refcount and register
+ * @thread: uevent-generating thread
+ */
+struct s3cfb_vsync {
+ wait_queue_head_t wait;
+ ktime_t timestamp;
+ bool active;
+ int irq_refcount;
+ struct mutex irq_lock;
+ struct task_struct *thread;
+};
+
+#ifdef CONFIG_FB_S5P_SYSMMU
+struct sysmmu_flag {
+ bool enabled;
+ unsigned long default_fb_addr;
+ unsigned long pgd;
+};
+#endif
+
struct s3cfb_global {
void __iomem *regs;
void __iomem *regs_org;
@@ -172,21 +209,29 @@ struct s3cfb_global {
#ifdef CONFIG_BUSFREQ_OPP
struct device *bus_dev;
#endif
+ spinlock_t vsync_slock;
struct clk *clock;
int irq;
wait_queue_head_t wq;
unsigned int wq_count;
struct fb_info **fb;
-
- ktime_t vsync_timestamp;
- int vsync_state;
- struct task_struct *vsync_thread;
+ struct s3cfb_vsync vsync_info;
atomic_t enabled_win;
enum s3cfb_output_t output;
enum s3cfb_rgb_mode_t rgb_mode;
struct s3cfb_lcd *lcd;
int system_state;
+
+ /* New added */
+ struct list_head update_regs_list;
+ struct mutex update_regs_list_lock;
+ struct kthread_worker update_regs_worker;
+ struct task_struct *update_regs_thread;
+ struct kthread_work update_regs_work;
+
+ struct sw_sync_timeline *timeline;
+ int timeline_max;
#ifdef CONFIG_HAS_WAKELOCK
struct early_suspend early_suspend;
struct wake_lock idle_lock;
@@ -195,6 +240,9 @@ struct s3cfb_global {
atomic_t busfreq_lock_cnt; /* Bus frequency Lock count */
int busfreq_flag; /* context bus frequency flag*/
#endif
+#ifdef CONFIG_FB_S5P_SYSMMU
+ struct sysmmu_flag sysmmu;
+#endif
};
struct s3cfb_window {
@@ -232,6 +280,61 @@ struct s3cfb_user_chroma {
unsigned char blue;
};
+enum s3c_fb_pixel_format {
+ S3C_FB_PIXEL_FORMAT_RGBA_8888 = 0,
+ S3C_FB_PIXEL_FORMAT_RGB_888 = 1,
+ S3C_FB_PIXEL_FORMAT_BGRA_8888 = 2,
+ S3C_FB_PIXEL_FORMAT_RGB_565 = 3,
+ S3C_FB_PIXEL_FORMAT_RGBX_8888 = 4,
+ S3C_FB_PIXEL_FORMAT_RGBA_5551 = 5,
+ S3C_FB_PIXEL_FORMAT_RGBA_4444 = 6,
+ S3C_FB_PIXEL_FORMAT_MAX = 7,
+};
+
+struct s3c_fb_win_config {
+ enum {
+ S3C_FB_WIN_STATE_DISABLED = 0,
+ S3C_FB_WIN_STATE_COLOR,
+ S3C_FB_WIN_STATE_BUFFER,
+ } state;
+
+ union {
+ __u32 color;
+ struct {
+ int fd;
+ __u32 phys_addr;
+ __u32 virt_addr;
+ __u32 offset;
+ __u32 stride;
+ enum s3c_fb_pixel_format format;
+ };
+ };
+
+ int x;
+ int y;
+ __u32 w;
+ __u32 h;
+};
+
+struct s3c_fb_win_config_data {
+ int fence;
+ struct s3c_fb_win_config config[S3C_FB_MAX_WIN];
+};
+
+struct s3c_reg_data {
+ struct list_head list;
+ u32 shadowcon;
+ u32 wincon[S3C_FB_MAX_WIN];
+ u32 winmap[S3C_FB_MAX_WIN];
+ u32 vidosd_a[S3C_FB_MAX_WIN];
+ u32 vidosd_b[S3C_FB_MAX_WIN];
+ u32 vidosd_c[S3C_FB_MAX_WIN];
+ u32 vidosd_d[S3C_FB_MAX_WIN];
+ u32 vidw_buf_start[S3C_FB_MAX_WIN];
+ u32 vidw_buf_end[S3C_FB_MAX_WIN];
+ u32 vidw_buf_size[S3C_FB_MAX_WIN];
+};
+
#define BLENDING_NONE 0x0100
#define BLENDING_PREMULT 0x0105
#define BLENDING_COVERAGE 0x0405
@@ -245,6 +348,8 @@ struct s3cfb_user_chroma {
struct s3cfb_user_chroma)
#define S3CFB_SET_VSYNC_INT _IOW('F', 206, u32)
#define S3CFB_GET_VSYNC_INT_STATUS _IOR('F', 207, u32)
+#define S3CFB_GET_ION_USER_HANDLE _IOWR('F', 208, struct s3c_fb_user_ion_client)
+#define S3CFB_WIN_CONFIG _IOW('F', 209, struct s3c_fb_win_config_data)
#define S3CFB_GET_LCD_WIDTH _IOR('F', 302, int)
#define S3CFB_GET_LCD_HEIGHT _IOR('F', 303, int)
#define S3CFB_SET_WRITEBACK _IOW('F', 304, u32)
@@ -342,8 +447,17 @@ extern int s3cfb_set_buffer_size(struct s3cfb_global *ctrl, int id);
extern int s3cfb_set_chroma_key(struct s3cfb_global *ctrl, int id);
extern int s3cfb_channel_localpath_on(struct s3cfb_global *ctrl, int id);
extern int s3cfb_channel_localpath_off(struct s3cfb_global *ctrl, int id);
+extern int s3cfb_set_vsync_int(struct fb_info *info, bool active);
extern int s3cfb_check_vsync_status(struct s3cfb_global *ctrl);
extern int s3cfb_set_dualrgb(struct s3cfb_global *ctrl, int mode);
+extern int s3cfb_set_window_protect(struct s3cfb_global *ctrl, int id, bool protect);
+extern void s3c_fb_update_regs(struct s3cfb_global *fbdev, struct s3c_reg_data *regs);
+#ifdef CONFIG_FB_S5P_SYSMMU
+extern void s3cfb_clean_outer_pagetable(unsigned long vaddr, size_t size);
+#endif
+#if defined(CONFIG_FB_S5P_VSYNC_THREAD)
+extern int s3cfb_wait_for_vsync(struct s3cfb_global *fbdev, u32 timeout);
+#endif
#ifdef CONFIG_FB_S5P_MIPI_DSIM
extern int s3cfb_vsync_status_check(void);
#endif
diff --git a/drivers/video/samsung/s3cfb_ea8061.c b/drivers/video/samsung/s3cfb_ea8061.c
new file mode 100644
index 0000000..5edeaaf
--- /dev/null
+++ b/drivers/video/samsung/s3cfb_ea8061.c
@@ -0,0 +1,1289 @@
+/* linux/drivers/video/samsung/s3cfb_ea8061.c
+ *
+ * MIPI-DSI based AMS555HBxx AMOLED lcd panel 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/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/mutex.h>
+#include <linux/wait.h>
+#include <linux/ctype.h>
+#include <linux/io.h>
+#include <linux/delay.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/gpio.h>
+#include <linux/workqueue.h>
+#include <linux/backlight.h>
+#include <linux/lcd.h>
+#include <plat/gpio-cfg.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 "s5p-dsim.h"
+#include "s3cfb.h"
+#include "ea8061_param.h"
+
+#define SMART_DIMMING
+#undef SMART_DIMMING_DEBUG
+
+#ifdef SMART_DIMMING
+#include "smart_dimming_ea8061.h"
+#include "aid_ea8061.h"
+#endif
+
+
+#define POWER_IS_ON(pwr) ((pwr) <= FB_BLANK_NORMAL)
+
+#define MIN_BRIGHTNESS 0
+#define MAX_BRIGHTNESS 255
+#define MAX_GAMMA 300
+#define DEFAULT_BRIGHTNESS 130
+#define DEFAULT_GAMMA_LEVEL GAMMA_130CD
+
+#define LDI_ID_REG 0xD1
+#define LDI_ID_LEN 3
+#ifdef SMART_DIMMING
+#define LDI_MTP_LENGTH 32
+#define LDI_MTP_ADDR 0xDA
+#endif
+
+struct lcd_info {
+ unsigned int bl;
+ unsigned int auto_brightness;
+ unsigned int acl_enable;
+ unsigned int current_acl;
+ unsigned int current_bl;
+ unsigned int current_elvss;
+ unsigned int ldi_enable;
+ unsigned int power;
+ struct mutex lock;
+ struct mutex bl_lock;
+ struct device *dev;
+ struct lcd_device *ld;
+ struct backlight_device *bd;
+ struct lcd_platform_data *lcd_pd;
+ struct early_suspend early_suspend;
+ unsigned char id[LDI_ID_LEN];
+ unsigned char **gamma_table;
+ unsigned char **elvss_table;
+#ifdef SMART_DIMMING
+ struct str_smart_dim smart;
+ unsigned char b3[GAMMA_MAX][ARRAY_SIZE(SEQ_LTPS_AID)];
+#endif
+ unsigned int irq;
+ unsigned int connected;
+
+#if defined(GPIO_OLED_DET)
+ struct delayed_work oled_detection;
+ unsigned int oled_detection_count;
+#endif
+
+ struct dsim_global *dsim;
+};
+
+static const unsigned int candela_table[GAMMA_MAX] = {
+ 20, 30, 40, 50, 60, 70, 80, 90, 100,
+ 102, 104, 106, 108,
+ 110, 120, 130, 140, 150, 160, 170, 180,
+ 182, 184, 186, 188,
+ 190, 200, 210, 220, 230, 240, 250, MAX_GAMMA-1
+};
+
+#ifdef SMART_DIMMING
+static unsigned int aid_candela_table[GAMMA_MAX] = {
+ base_20to100, base_20to100, base_20to100, base_20to100, base_20to100, base_20to100, base_20to100, base_20to100, base_20to100,
+ AOR40_BASE_102, AOR40_BASE_104, AOR40_BASE_106, AOR40_BASE_108,
+ AOR40_BASE_110, AOR40_BASE_120, AOR40_BASE_130, AOR40_BASE_140, AOR40_BASE_150,
+ AOR40_BASE_160, AOR40_BASE_170, AOR40_BASE_180, AOR40_BASE_182, AOR40_BASE_184,
+ AOR40_BASE_186, AOR40_BASE_188,
+ 190, 200, 210, 220, 230, 240, 250, MAX_GAMMA-1
+};
+#endif
+
+extern void (*lcd_early_suspend)(void);
+extern void (*lcd_late_resume)(void);
+
+#if defined(GPIO_OLED_DET)
+static void oled_detection_work(struct work_struct *work)
+{
+ struct lcd_info *lcd =
+ container_of(work, struct lcd_info, oled_detection.work);
+
+ int oled_det_level = gpio_get_value(GPIO_OLED_DET);
+
+ dev_info(&lcd->ld->dev, "%s, %d, %d\n", __func__, lcd->oled_detection_count, oled_det_level);
+
+ if (!oled_det_level) {
+ if (lcd->oled_detection_count < 10) {
+ schedule_delayed_work(&lcd->oled_detection, HZ/8);
+ lcd->oled_detection_count++;
+ set_dsim_hs_clk_toggle_count(15);
+ } else
+ set_dsim_hs_clk_toggle_count(0);
+ } else
+ set_dsim_hs_clk_toggle_count(0);
+
+}
+
+static irqreturn_t oled_detection_int(int irq, void *_lcd)
+{
+ struct lcd_info *lcd = _lcd;
+
+ dev_info(&lcd->ld->dev, "%s\n", __func__);
+
+ lcd->oled_detection_count = 0;
+ schedule_delayed_work(&lcd->oled_detection, HZ/16);
+
+ return IRQ_HANDLED;
+}
+#endif
+
+static int _ea8061_write(struct lcd_info *lcd, const unsigned char *seq, int len)
+{
+ int size;
+ const unsigned char *wbuf;
+ int ret = 0;
+
+ if (!lcd->connected)
+ return 0;
+
+ mutex_lock(&lcd->lock);
+
+ size = len;
+ wbuf = seq;
+
+ if (size == 1)
+ ret = lcd->dsim->ops->cmd_write(lcd->dsim, DCS_WR_NO_PARA, wbuf[0], 0);
+ else if (size == 2)
+ ret = lcd->dsim->ops->cmd_write(lcd->dsim, DCS_WR_1_PARA, wbuf[0], wbuf[1]);
+ else
+ ret = lcd->dsim->ops->cmd_write(lcd->dsim, DCS_LONG_WR, (unsigned int)wbuf, size);
+
+ mutex_unlock(&lcd->lock);
+
+ return ret;
+}
+
+static int ea8061_write(struct lcd_info *lcd, const unsigned char *seq, int len)
+{
+ int ret = 0;
+ int retry_cnt = 1;
+
+retry:
+ ret = _ea8061_write(lcd, seq, len);
+ 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[1]);
+ }
+
+ return ret;
+}
+
+static int _ea8061_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_dcs_read)
+ ret = lcd->dsim->ops->cmd_dcs_read(lcd->dsim, addr, count, buf);
+
+ mutex_unlock(&lcd->lock);
+
+ return ret;
+}
+
+static int ea8061_read(struct lcd_info *lcd, const u8 addr, u16 count, u8 *buf, u8 retry_cnt)
+{
+ int ret = 0;
+
+retry:
+ ret = _ea8061_read(lcd, addr, count, buf);
+ 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__, addr);
+ }
+
+ return ret;
+}
+
+static int get_backlight_level_from_brightness(int brightness)
+{
+ int backlightlevel;
+
+ /* brightness setting from platform is from 0 to 255
+ * But in this driver, brightness is only supported from 0 to 24 */
+
+ switch (brightness) {
+ case 0 ... 29:
+ backlightlevel = GAMMA_20CD;
+ break;
+ case 30 ... 39:
+ backlightlevel = GAMMA_30CD;
+ break;
+ case 40 ... 49:
+ backlightlevel = GAMMA_40CD;
+ break;
+ case 50 ... 59:
+ backlightlevel = GAMMA_50CD;
+ break;
+ case 60 ... 69:
+ backlightlevel = GAMMA_60CD;
+ break;
+ case 70 ... 79:
+ backlightlevel = GAMMA_70CD;
+ break;
+ case 80 ... 89:
+ backlightlevel = GAMMA_80CD;
+ break;
+ case 90 ... 99:
+ backlightlevel = GAMMA_90CD;
+ break;
+ case 100 ... 101:
+ backlightlevel = GAMMA_100CD;
+ break;
+ case 102 ... 103:
+ backlightlevel = GAMMA_102CD;
+ break;
+ case 104 ... 105:
+ backlightlevel = GAMMA_104CD;
+ break;
+ case 106 ... 107:
+ backlightlevel = GAMMA_106CD;
+ break;
+ case 108 ... 109:
+ backlightlevel = GAMMA_108CD;
+ break;
+ case 110 ... 119:
+ backlightlevel = GAMMA_110CD;
+ break;
+ case 120 ... 129:
+ backlightlevel = GAMMA_120CD;
+ break;
+ case 130 ... 139:
+ backlightlevel = GAMMA_130CD;
+ break;
+ case 140 ... 149:
+ backlightlevel = GAMMA_140CD;
+ break;
+ case 150 ... 159:
+ backlightlevel = GAMMA_150CD;
+ break;
+ case 160 ... 169:
+ backlightlevel = GAMMA_160CD;
+ break;
+ case 170 ... 179:
+ backlightlevel = GAMMA_170CD;
+ break;
+ case 180 ... 181:
+ backlightlevel = GAMMA_180CD;
+ break;
+ case 182 ... 183:
+ backlightlevel = GAMMA_182CD;
+ break;
+ case 184 ... 185:
+ backlightlevel = GAMMA_184CD;
+ break;
+ case 186 ... 187:
+ backlightlevel = GAMMA_186CD;
+ break;
+ case 188 ... 189:
+ backlightlevel = GAMMA_188CD;
+ break;
+ case 190 ... 199:
+ backlightlevel = GAMMA_190CD;
+ break;
+ case 200 ... 209:
+ backlightlevel = GAMMA_200CD;
+ break;
+ case 210 ... 219:
+ backlightlevel = GAMMA_210CD;
+ break;
+ case 220 ... 229:
+ backlightlevel = GAMMA_220CD;
+ break;
+ case 230 ... 239:
+ backlightlevel = GAMMA_230CD;
+ break;
+ case 240 ... 249:
+ backlightlevel = GAMMA_240CD;
+ break;
+ case 250 ... 254:
+ backlightlevel = GAMMA_250CD;
+ break;
+ case 255:
+ backlightlevel = GAMMA_300CD;
+ break;
+ default:
+ backlightlevel = DEFAULT_GAMMA_LEVEL;
+ break;
+ }
+ return backlightlevel;
+}
+
+#ifdef SMART_DIMMING
+static int ea8061_aid_parameter_ctl(struct lcd_info *lcd, u8 force)
+{
+ if (force)
+ goto aor_update;
+ else if (aid_command_table[lcd->bl][0] != aid_command_table[lcd->current_bl][0])
+ goto aor_update;
+ else if (aid_command_table[lcd->bl][1] != aid_command_table[lcd->current_bl][1])
+ goto aor_update;
+ else
+ goto exit;
+
+aor_update:
+ ea8061_write(lcd, lcd->b3[lcd->bl], AID_PARAM_SIZE);
+
+exit:
+ return 0;
+}
+#endif
+
+static int ea8061_gamma_ctl(struct lcd_info *lcd)
+{
+ /* ea8061_write(lcd, SEQ_APPLY_LEVEL_2_KEY_ENABLE, ARRAY_SIZE(SEQ_APPLY_LEVEL_2_KEY_ENABLE)); */
+ ea8061_write(lcd, SEQ_FRAME_GAMMA_UPDATE_KEY, ARRAY_SIZE(SEQ_FRAME_GAMMA_UPDATE_KEY));
+ ea8061_write(lcd, lcd->gamma_table[lcd->bl], GAMMA_PARAM_SIZE-1);
+ ea8061_write(lcd, SEQ_FRAME_GAMMA_UPDATE_KEY2, ARRAY_SIZE(SEQ_FRAME_GAMMA_UPDATE_KEY2));
+
+ return 0;
+}
+
+static int ea8061_set_acl(struct lcd_info *lcd, u8 force)
+{
+ int ret = 0, level = 0;
+ u32 candela = candela_table[lcd->bl];
+
+ switch (candela) {
+ case 0 ... 29:
+ level = ACL_STATUS_0P;
+ break;
+ case 30 ... 39:
+ level = ACL_STATUS_33P;
+ break;
+ default:
+ level = ACL_STATUS_40P;
+ break;
+ }
+
+ if ((!lcd->acl_enable) || (lcd->auto_brightness >= 5))
+ level = ACL_STATUS_0P;
+
+ if (force || lcd->current_acl != ACL_CUTOFF_TABLE[level][1]) {
+ ret = ea8061_write(lcd, ACL_CUTOFF_TABLE[level], ACL_PARAM_SIZE);
+ lcd->current_acl = ACL_CUTOFF_TABLE[level][1];
+ dev_dbg(&lcd->ld->dev, "current_acl = %d\n", lcd->current_acl);
+ }
+
+ if (ret)
+ ret = -EPERM;
+
+ return ret;
+}
+
+static int ea8061_set_elvss(struct lcd_info *lcd, u8 force)
+{
+ int ret = 0, elvss_level = 0;
+ u32 candela = candela_table[lcd->bl];
+
+ switch (candela) {
+ case 0 ... 49:
+ elvss_level = ELVSS_STATUS_20;
+ break;
+ case 50 ... 79:
+ elvss_level = ELVSS_STATUS_50;
+ break;
+ case 80 ... 99:
+ elvss_level = ELVSS_STATUS_80;
+ break;
+ case 100 ... 109:
+ elvss_level = ELVSS_STATUS_100;
+ break;
+ case 110 ... 119:
+ elvss_level = ELVSS_STATUS_110;
+ break;
+ case 120 ... 129:
+ elvss_level = ELVSS_STATUS_120;
+ break;
+ case 130 ... 139:
+ elvss_level = ELVSS_STATUS_130;
+ break;
+ case 140 ... 149:
+ elvss_level = ELVSS_STATUS_140;
+ break;
+ case 150 ... 159:
+ elvss_level = ELVSS_STATUS_150;
+ break;
+ case 160 ... 169:
+ elvss_level = ELVSS_STATUS_160;
+ break;
+ case 170 ... 179:
+ elvss_level = ELVSS_STATUS_170;
+ break;
+ case 180 ... 189:
+ elvss_level = ELVSS_STATUS_180;
+ break;
+ case 190 ... 199:
+ elvss_level = ELVSS_STATUS_190;
+ break;
+ case 200 ... 209:
+ elvss_level = ELVSS_STATUS_200;
+ break;
+ case 210 ... 219:
+ elvss_level = ELVSS_STATUS_210;
+ break;
+ case 220 ... 229:
+ elvss_level = ELVSS_STATUS_220;
+ break;
+ case 230 ... 239:
+ elvss_level = ELVSS_STATUS_230;
+ break;
+ case 240 ... 250:
+ elvss_level = ELVSS_STATUS_240;
+ break;
+ case 299:
+ elvss_level = ELVSS_STATUS_300;
+ break;
+ }
+
+ if (force || lcd->current_elvss != lcd->elvss_table[elvss_level][1]) {
+ ret = ea8061_write(lcd, lcd->elvss_table[elvss_level], ELVSS_PARAM_SIZE);
+ lcd->current_elvss = lcd->elvss_table[elvss_level][1];
+ }
+
+ dev_dbg(&lcd->ld->dev, "elvss = %x\n", lcd->elvss_table[elvss_level][1]);
+
+ if (ret) {
+ ret = -EPERM;
+ goto elvss_err;
+ }
+
+elvss_err:
+ return ret;
+}
+
+static int init_elvss_table(struct lcd_info *lcd)
+{
+ int i, ret = 0;
+#ifdef SMART_DIMMING_DEBUG
+ int j;
+#endif
+ lcd->elvss_table = (unsigned char **)ELVSS_CONTROL_TABLE;
+
+#ifdef SMART_DIMMING_DEBUG
+ for (i = 0; i < ELVSS_STATUS_MAX; i++) {
+ for (j = 0; j < ELVSS_PARAM_SIZE; j++)
+ printk("0x%02x, ", lcd->elvss_table[i][j]);
+ printk("\n");
+ }
+#endif
+
+ return 0;
+
+err_alloc_elvss:
+ while (i > 0) {
+ kfree(lcd->elvss_table[i-1]);
+ i--;
+ }
+ kfree(lcd->elvss_table);
+err_alloc_elvss_table:
+ return ret;
+}
+
+#ifdef SMART_DIMMING
+static int init_gamma_table(struct lcd_info *lcd , const u8 *mtp_data)
+{
+ int i, ret = 0;
+
+ lcd->gamma_table = kzalloc(GAMMA_MAX * sizeof(u8 *), GFP_KERNEL);
+ if (IS_ERR_OR_NULL(lcd->gamma_table)) {
+ pr_err("failed to allocate gamma table\n");
+ ret = -ENOMEM;
+ goto err_alloc_gamma_table;
+ }
+
+ for (i = 0; i < GAMMA_MAX; i++) {
+ lcd->gamma_table[i] = kzalloc(GAMMA_PARAM_SIZE * sizeof(u8), GFP_KERNEL);
+ if (IS_ERR_OR_NULL(lcd->gamma_table[i])) {
+ pr_err("failed to allocate gamma\n");
+ ret = -ENOMEM;
+ goto err_alloc_gamma;
+ }
+ lcd->gamma_table[i][0] = 0xCA;
+ }
+
+ for (i = 0; i < GAMMA_MAX; i++) {
+
+ if (candela_table[i] == 20)
+ calc_gamma_table_20_100_ea8061(&lcd->smart, aid_candela_table[i], &lcd->gamma_table[i][1], G_21, mtp_data);
+ else if (candela_table[i] == 30)
+ calc_gamma_table_20_100_ea8061(&lcd->smart, aid_candela_table[i], &lcd->gamma_table[i][1], G_213, mtp_data);
+ else if (candela_table[i] == 40)
+ calc_gamma_table_20_100_ea8061(&lcd->smart, aid_candela_table[i], &lcd->gamma_table[i][1], G_215, mtp_data);
+ else if (candela_table[i] == 50)
+ calc_gamma_table_20_100_ea8061(&lcd->smart, aid_candela_table[i], &lcd->gamma_table[i][1], G_218, mtp_data);
+ else if (candela_table[i] == 60)
+ calc_gamma_table_20_100_ea8061(&lcd->smart, aid_candela_table[i], &lcd->gamma_table[i][1], G_22, mtp_data);
+ else if (candela_table[i] == 70)
+ calc_gamma_table_20_100_ea8061(&lcd->smart, aid_candela_table[i], &lcd->gamma_table[i][1], G_222, mtp_data);
+ else if (candela_table[i] == 80)
+ calc_gamma_table_20_100_ea8061(&lcd->smart, aid_candela_table[i], &lcd->gamma_table[i][1], G_223, mtp_data);
+ else if (candela_table[i] == 90)
+ calc_gamma_table_20_100_ea8061(&lcd->smart, aid_candela_table[i], &lcd->gamma_table[i][1], G_224, mtp_data);
+ else if (candela_table[i] == 100)
+ calc_gamma_table_20_100_ea8061(&lcd->smart, aid_candela_table[i], &lcd->gamma_table[i][1], G_225, mtp_data);
+ else if (candela_table[i] == 102)
+ calc_gamma_table_ea8061(&lcd->smart, aid_candela_table[i], &lcd->gamma_table[i][1], G_224, mtp_data);
+ else if (candela_table[i] == 104)
+ calc_gamma_table_ea8061(&lcd->smart, aid_candela_table[i], &lcd->gamma_table[i][1], G_223, mtp_data);
+ else if (candela_table[i] == 106)
+ calc_gamma_table_ea8061(&lcd->smart, aid_candela_table[i], &lcd->gamma_table[i][1], G_222, mtp_data);
+ else if (candela_table[i] == 108)
+ calc_gamma_table_ea8061(&lcd->smart, aid_candela_table[i], &lcd->gamma_table[i][1], G_221, mtp_data);
+ else if (candela_table[i] == 182)
+ calc_gamma_table_ea8061(&lcd->smart, aid_candela_table[i], &lcd->gamma_table[i][1], G_221, mtp_data);
+ else if (candela_table[i] == 184)
+ calc_gamma_table_ea8061(&lcd->smart, aid_candela_table[i], &lcd->gamma_table[i][1], G_222, mtp_data);
+ else if (candela_table[i] == 186)
+ calc_gamma_table_ea8061(&lcd->smart, aid_candela_table[i], &lcd->gamma_table[i][1], G_223, mtp_data);
+ else if (candela_table[i] == 188)
+ calc_gamma_table_ea8061(&lcd->smart, aid_candela_table[i], &lcd->gamma_table[i][1], G_224, mtp_data);
+ else if (candela_table[i] == 190)
+ calc_gamma_table_190_ea8061(&lcd->smart, aid_candela_table[i], &lcd->gamma_table[i][1], G_225, mtp_data);
+ else if ((candela_table[i] > 190) && (candela_table[i] < MAX_GAMMA-1))
+ calc_gamma_table_ea8061(&lcd->smart, aid_candela_table[i], &lcd->gamma_table[i][1], G_225 , mtp_data);
+ else if (candela_table[i] == MAX_GAMMA-1)
+ calc_gamma_table_ea8061(&lcd->smart, aid_candela_table[i], &lcd->gamma_table[i][1], G_22, mtp_data);
+ else
+ calc_gamma_table_ea8061(&lcd->smart, aid_candela_table[i], &lcd->gamma_table[i][1], G_22, mtp_data);
+ }
+
+#ifdef SMART_DIMMING_DEBUG
+ for (i = 0; i < GAMMA_MAX; i++) {
+ for (j = 0; j < GAMMA_PARAM_SIZE; j++)
+ printk("%d,", lcd->gamma_table[i][j]);
+ printk("\n");
+ }
+#endif
+ return 0;
+
+err_alloc_gamma:
+ while (i > 0) {
+ kfree(lcd->gamma_table[i-1]);
+ i--;
+ }
+ kfree(lcd->gamma_table);
+err_alloc_gamma_table:
+ return ret;
+}
+
+static int init_aid_dimming_table(struct lcd_info *lcd)
+{
+ unsigned int i, j, c;
+ u16 reverse_seq[] = {0, 28, 29, 30, 31, 32, 33, 25, 26, 27, 22, 23, 24, 19, 20, 21, 16, 17, 18, 13, 14, 15, 10, 11, 12, 7, 8, 9, 4, 5, 6, 1, 2, 3};
+ u16 temp[GAMMA_PARAM_SIZE];
+
+ if ((lcd->id[1] == 0x12) || (lcd->id[1] == 0x16)) {
+ for (i = 0; i < ARRAY_SIZE(aid_rgb_fix_table_SM2); i++) {
+ j = (aid_rgb_fix_table_SM2[i].gray * 3 + aid_rgb_fix_table_SM2[i].rgb) + 1;
+ c = lcd->gamma_table[aid_rgb_fix_table_SM2[i].candela_idx][j] + aid_rgb_fix_table_SM2[i].offset;
+ if (c > 0xff)
+ lcd->gamma_table[aid_rgb_fix_table_SM2[i].candela_idx][j] = 0xff;
+ else
+ lcd->gamma_table[aid_rgb_fix_table_SM2[i].candela_idx][j] += aid_rgb_fix_table_SM2[i].offset;
+ }
+ }
+
+ if (lcd->id[1] == 0x13) {
+ for (i = 0; i < ARRAY_SIZE(aid_rgb_fix_table_M4); i++) {
+ j = (aid_rgb_fix_table_M4[i].gray * 3 + aid_rgb_fix_table_M4[i].rgb) + 1;
+ c = lcd->gamma_table[aid_rgb_fix_table_M4[i].candela_idx][j] + aid_rgb_fix_table_M4[i].offset;
+ if (c > 0xff)
+ lcd->gamma_table[aid_rgb_fix_table_M4[i].candela_idx][j] = 0xff;
+ else
+ lcd->gamma_table[aid_rgb_fix_table_M4[i].candela_idx][j] += aid_rgb_fix_table_M4[i].offset;
+ }
+ }
+
+ for (i = 0; i < GAMMA_MAX; i++) {
+ memcpy(lcd->b3[i], SEQ_LTPS_AID, AID_PARAM_SIZE);
+ lcd->b3[i][0x02] = aid_command_table[i][1];
+ lcd->b3[i][0x01] = aid_command_table[i][0];
+ }
+#ifdef SMART_DIMMING_DEBUG
+ for (i = 0; i < GAMMA_MAX; i++) {
+ for (j = 0; j < GAMMA_PARAM_SIZE; j++)
+ printk("%d,", lcd->gamma_table[i][j]);
+ printk("\n");
+ }
+ printk("\n");
+#endif
+
+
+ for (i = 0; i < GAMMA_MAX; i++) {
+ for (j = 0; j < GAMMA_PARAM_SIZE; j++)
+ temp[j] = lcd->gamma_table[i][reverse_seq[j]];
+
+ for (j = 0; j < GAMMA_PARAM_SIZE; j++)
+ lcd->gamma_table[i][j] = temp[j];
+
+ lcd->gamma_table[i][31] = lcd->smart.default_gamma[31]<<4|lcd->smart.default_gamma[30];
+ /*default_gamma 30,31th range 0000~1111 */
+ /*31,30th gamma need to reverse order , because of normal order is R,G,B
+ but Magna DDI VT G,R,B so R,G order change to G,R order*/
+ lcd->gamma_table[i][32] = lcd->smart.default_gamma[32];
+ }
+
+#ifdef SMART_DIMMING_DEBUG
+ for (i = 0; i < GAMMA_MAX; i++) {
+ for (j = 0; j < GAMMA_PARAM_SIZE-1; j++)
+ printk("0x%x,", lcd->gamma_table[i][j]);
+ printk("\n");
+ }
+#endif
+
+ return 0;
+}
+#endif
+
+static int update_brightness(struct lcd_info *lcd, u8 force)
+{
+ u32 brightness;
+
+ mutex_lock(&lcd->bl_lock);
+
+ brightness = lcd->bd->props.brightness;
+
+ if (unlikely(!lcd->auto_brightness && brightness > 250))
+ brightness = 250;
+
+ lcd->bl = get_backlight_level_from_brightness(brightness);
+
+ if ((force) || ((lcd->ldi_enable) && (lcd->current_bl != lcd->bl))) {
+
+ ea8061_gamma_ctl(lcd);
+
+ ea8061_aid_parameter_ctl(lcd, force);
+
+ ea8061_set_acl(lcd, force);
+
+ ea8061_set_elvss(lcd, force);
+
+ lcd->current_bl = lcd->bl;
+
+ dev_info(&lcd->ld->dev, "brightness=%d, bl=%d, candela=%d\n", brightness, lcd->bl, candela_table[lcd->bl]);
+ }
+
+ mutex_unlock(&lcd->bl_lock);
+
+ return 0;
+}
+
+static int slew_rev_control_set(struct lcd_info *lcd)
+{
+ if (lcd->id[2] == 0x00)
+ ea8061_write(lcd, SEQ_SLEW_REV00, ARRAY_SIZE(SEQ_SLEW_REV00));
+ else if (lcd->id[2] == 0x01)
+ ea8061_write(lcd, SEQ_SLEW_REV01, ARRAY_SIZE(SEQ_SLEW_REV01));
+ else if (lcd->id[2] == 0x02)
+ ea8061_write(lcd, SEQ_SLEW_REV02, ARRAY_SIZE(SEQ_SLEW_REV02));
+ else if (lcd->id[2] == 0x03)
+ ea8061_write(lcd, SEQ_SLEW_REV03, ARRAY_SIZE(SEQ_SLEW_REV03));
+ else
+ ea8061_write(lcd, SEQ_SLEW_REV04, ARRAY_SIZE(SEQ_SLEW_REV04));
+ return 0;
+}
+
+static int ea8061_ldi_init(struct lcd_info *lcd)
+{
+ int ret = 0;
+ ea8061_write(lcd, SEQ_APPLY_LEVEL_2_KEY_ENABLE, ARRAY_SIZE(SEQ_APPLY_LEVEL_2_KEY_ENABLE));
+ ea8061_write(lcd, SEQ_APPLY_LEVEL_3_KEY, ARRAY_SIZE(SEQ_APPLY_LEVEL_3_KEY));
+ if (lcd->id[1] == 0x13) { /* M4 */
+ ea8061_write(lcd, SEQ_M4_PANEL_CONDITION_SET, ARRAY_SIZE(SEQ_M4_PANEL_CONDITION_SET));
+ ea8061_write(lcd, SEQ_DISPLAY_CONDITION_SET, ARRAY_SIZE(SEQ_DISPLAY_CONDITION_SET));
+/* ea8061_write(lcd, SEQ_FRAME_GAMMA_UPDATE_KEY, ARRAY_SIZE(SEQ_FRAME_GAMMA_UPDATE_KEY));
+ ea8061_write(lcd, SEQ_M4_GAMMA_CONDITION_SET, ARRAY_SIZE(SEQ_M4_GAMMA_CONDITION_SET));
+ ea8061_write(lcd, SEQ_FRAME_GAMMA_UPDATE_KEY2, ARRAY_SIZE(SEQ_FRAME_GAMMA_UPDATE_KEY2)); */
+ ea8061_gamma_ctl(lcd);
+ ea8061_write(lcd, SEQ_LTPS_AID, ARRAY_SIZE(SEQ_LTPS_AID));
+ ea8061_write(lcd, ELVSS_CONTROL_SET, ARRAY_SIZE(ELVSS_CONTROL_SET));
+ ea8061_write(lcd, SEQ_ETC_WCABC_CONTROL, ARRAY_SIZE(SEQ_ETC_WCABC_CONTROL));
+ ea8061_write(lcd, SEQ_M4_SLEW, ARRAY_SIZE(SEQ_M4_SLEW));
+ } else { /* SM2 */
+ ea8061_write(lcd, SEQ_PANEL_CONDITION_SET, ARRAY_SIZE(SEQ_PANEL_CONDITION_SET));
+ ea8061_write(lcd, SEQ_DISPLAY_CONDITION_SET, ARRAY_SIZE(SEQ_DISPLAY_CONDITION_SET));
+/* ea8061_write(lcd, SEQ_FRAME_GAMMA_UPDATE_KEY, ARRAY_SIZE(SEQ_FRAME_GAMMA_UPDATE_KEY));
+ ea8061_write(lcd, SEQ_GAMMA_CONDITION_SET, ARRAY_SIZE(SEQ_GAMMA_CONDITION_SET));
+ ea8061_write(lcd, SEQ_FRAME_GAMMA_UPDATE_KEY2, ARRAY_SIZE(SEQ_FRAME_GAMMA_UPDATE_KEY2)); */
+ ea8061_gamma_ctl(lcd);
+ ea8061_write(lcd, SEQ_LTPS_AID, ARRAY_SIZE(SEQ_LTPS_AID));
+ ea8061_write(lcd, ELVSS_CONTROL_SET, ARRAY_SIZE(ELVSS_CONTROL_SET));
+ ea8061_write(lcd, SEQ_ETC_WCABC_CONTROL, ARRAY_SIZE(SEQ_ETC_WCABC_CONTROL));
+ slew_rev_control_set(lcd);
+ }
+
+ ea8061_write(lcd, SEQ_SLEEP_OUT, ARRAY_SIZE(SEQ_SLEEP_OUT));
+
+ return ret;
+}
+
+static int ea8061_ldi_enable(struct lcd_info *lcd)
+{
+ int ret = 0;
+
+ ea8061_write(lcd, SEQ_DISPLAY_ON, ARRAY_SIZE(SEQ_DISPLAY_ON));
+
+ return ret;
+}
+
+static int ea8061_ldi_disable(struct lcd_info *lcd)
+{
+ int ret = 0;
+
+ ea8061_write(lcd, SEQ_DISPLAY_OFF, ARRAY_SIZE(SEQ_DISPLAY_OFF));
+
+ msleep(35);
+
+ ea8061_write(lcd, SEQ_SLEEP_IN, ARRAY_SIZE(SEQ_SLEEP_IN));
+
+ msleep(100);
+
+ return ret;
+}
+
+static int ea8061_power_on(struct lcd_info *lcd)
+{
+ int ret = 0;
+ struct lcd_platform_data *pd = NULL;
+ pd = lcd->lcd_pd;
+
+ dev_info(&lcd->ld->dev, "%s\n", __func__);
+
+ ret = ea8061_ldi_init(lcd);
+ if (ret) {
+ dev_err(&lcd->ld->dev, "failed to initialize ldi.\n");
+ goto err;
+ }
+
+ msleep(120);
+
+ ret = ea8061_ldi_enable(lcd);
+ if (ret) {
+ dev_err(&lcd->ld->dev, "failed to enable ldi.\n");
+ goto err;
+ }
+
+ lcd->ldi_enable = 1;
+
+ update_brightness(lcd, 1);
+err:
+ return ret;
+}
+
+static int ea8061_power_off(struct lcd_info *lcd)
+{
+ int ret = 0;
+
+ dev_info(&lcd->ld->dev, "%s\n", __func__);
+
+ lcd->ldi_enable = 0;
+
+ ret = ea8061_ldi_disable(lcd);
+
+ msleep(135);
+
+ return ret;
+}
+
+static int ea8061_power(struct lcd_info *lcd, int power)
+{
+ int ret = 0;
+
+ if (POWER_IS_ON(power) && !POWER_IS_ON(lcd->power))
+ ret = ea8061_power_on(lcd);
+ else if (!POWER_IS_ON(power) && POWER_IS_ON(lcd->power))
+ ret = ea8061_power_off(lcd);
+
+ if (!ret)
+ lcd->power = power;
+
+ return ret;
+}
+
+static int ea8061_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 ea8061_power(lcd, power);
+}
+
+static int ea8061_get_power(struct lcd_device *ld)
+{
+ struct lcd_info *lcd = lcd_get_data(ld);
+
+ return lcd->power;
+}
+
+
+static int ea8061_set_brightness(struct backlight_device *bd)
+{
+ int ret = 0;
+ int brightness = bd->props.brightness;
+ struct lcd_info *lcd = bl_get_data(bd);
+
+ /* dev_info(&lcd->ld->dev, "%s: brightness=%d\n", __func__, 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, MAX_BRIGHTNESS, brightness);
+ return -EINVAL;
+ }
+
+ if (lcd->ldi_enable) {
+ ret = update_brightness(lcd, 0);
+ if (ret < 0) {
+ dev_err(lcd->dev, "err in %s\n", __func__);
+ return -EINVAL;
+ }
+ }
+
+ return ret;
+}
+
+static int ea8061_get_brightness(struct backlight_device *bd)
+{
+ struct lcd_info *lcd = bl_get_data(bd);
+
+ return candela_table[lcd->bl];
+}
+
+static int ea8061_check_fb(struct lcd_device *ld, struct fb_info *fb)
+{
+ struct s3cfb_window *win = fb->par;
+ struct lcd_info *lcd = lcd_get_data(ld);
+
+ dev_info(&lcd->ld->dev, "%s, fb%d\n", __func__, win->id);
+
+ return 0;
+}
+
+static struct lcd_ops ea8061_lcd_ops = {
+ .set_power = ea8061_set_power,
+ .get_power = ea8061_get_power,
+ .check_fb = ea8061_check_fb,
+};
+
+static const struct backlight_ops ea8061_backlight_ops = {
+ .get_brightness = ea8061_get_brightness,
+ .update_status = ea8061_set_brightness,
+};
+
+static ssize_t power_reduce_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct lcd_info *lcd = dev_get_drvdata(dev);
+ char temp[3];
+
+ sprintf(temp, "%d\n", lcd->acl_enable);
+ strcpy(buf, temp);
+
+ return strlen(buf);
+}
+
+static ssize_t power_reduce_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t size)
+{
+ struct lcd_info *lcd = 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 (lcd->acl_enable != value) {
+ dev_info(dev, "%s - %d, %d\n", __func__, lcd->acl_enable, value);
+ mutex_lock(&lcd->bl_lock);
+ lcd->acl_enable = value;
+ mutex_unlock(&lcd->bl_lock);
+ if (lcd->ldi_enable)
+ update_brightness(lcd, 1);
+ }
+ }
+ return size;
+}
+
+static DEVICE_ATTR(power_reduce, 0664, power_reduce_show, power_reduce_store);
+
+static ssize_t lcd_type_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ char temp[15];
+ sprintf(temp, "SMD_AMS555HBxx\n");
+
+ strcat(buf, temp);
+ return strlen(buf);
+}
+
+static DEVICE_ATTR(lcd_type, 0444, lcd_type_show, NULL);
+
+static ssize_t window_type_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct lcd_info *lcd = dev_get_drvdata(dev);
+ char temp[15];
+
+ sprintf(temp, "%x %x %x\n", lcd->id[0], lcd->id[1], lcd->id[2]);
+
+ strcat(buf, temp);
+ return strlen(buf);
+}
+
+static DEVICE_ATTR(window_type, 0444, window_type_show, NULL);
+
+static ssize_t gamma_table_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct lcd_info *lcd = dev_get_drvdata(dev);
+ int i, j;
+
+ for (i = 0; i < GAMMA_MAX; i++) {
+ for (j = 0; j < GAMMA_PARAM_SIZE; j++)
+ printk("0x%02x, ", lcd->gamma_table[i][j]);
+ printk("\n");
+ }
+
+ for (i = 0; i < ELVSS_STATUS_MAX; i++) {
+ for (j = 0; j < ELVSS_PARAM_SIZE; j++)
+ printk("0x%02x, ", lcd->elvss_table[i][j]);
+ printk("\n");
+ }
+
+ return strlen(buf);
+}
+static DEVICE_ATTR(gamma_table, 0444, gamma_table_show, NULL);
+
+static ssize_t auto_brightness_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct lcd_info *lcd = dev_get_drvdata(dev);
+ char temp[3];
+
+ sprintf(temp, "%d\n", lcd->auto_brightness);
+ strcpy(buf, temp);
+
+ return strlen(buf);
+}
+
+static ssize_t auto_brightness_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t size)
+{
+ struct lcd_info *lcd = 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 (lcd->auto_brightness != value) {
+ dev_info(dev, "%s - %d, %d\n", __func__, lcd->auto_brightness, value);
+ mutex_lock(&lcd->bl_lock);
+ lcd->auto_brightness = value;
+ mutex_unlock(&lcd->bl_lock);
+ if (lcd->ldi_enable)
+ update_brightness(lcd, 1);
+ }
+ }
+ return size;
+}
+
+static DEVICE_ATTR(auto_brightness, 0644, auto_brightness_show, auto_brightness_store);
+
+#ifdef CONFIG_HAS_EARLYSUSPEND
+static struct lcd_info *g_lcd;
+
+void ea8061_early_suspend(void)
+{
+ struct lcd_info *lcd = g_lcd;
+
+ set_dsim_lcd_enabled(0);
+
+ dev_info(&lcd->ld->dev, "+%s\n", __func__);
+
+#if defined(GPIO_OLED_DET)
+ disable_irq(lcd->irq);
+ gpio_request(GPIO_OLED_DET, "OLED_DET");
+ s3c_gpio_cfgpin(GPIO_OLED_DET, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_OLED_DET, S3C_GPIO_PULL_NONE);
+ gpio_direction_output(GPIO_OLED_DET, GPIO_LEVEL_LOW);
+ gpio_free(GPIO_OLED_DET);
+#endif
+
+ ea8061_power(lcd, FB_BLANK_POWERDOWN);
+ dev_info(&lcd->ld->dev, "-%s\n", __func__);
+
+ return ;
+}
+
+void ea8061_late_resume(void)
+{
+ struct lcd_info *lcd = g_lcd;
+
+ dev_info(&lcd->ld->dev, "+%s\n", __func__);
+ ea8061_power(lcd, FB_BLANK_UNBLANK);
+
+#if defined(GPIO_OLED_DET)
+ s3c_gpio_cfgpin(GPIO_OLED_DET, S3C_GPIO_SFN(0xf));
+ s3c_gpio_setpull(GPIO_OLED_DET, S3C_GPIO_PULL_NONE);
+ enable_irq(lcd->irq);
+#endif
+
+ dev_info(&lcd->ld->dev, "-%s\n", __func__);
+
+ set_dsim_lcd_enabled(1);
+
+ return ;
+}
+#endif
+
+
+static void ea8061_read_id(struct lcd_info *lcd, u8 *buf)
+{
+ int ret = 0;
+ unsigned char wbuf[] = {0xFD, LDI_ID_REG};
+
+ ea8061_write(lcd, wbuf, ARRAY_SIZE(wbuf));
+
+ ret = ea8061_read(lcd, 0xFE, LDI_ID_LEN, buf, 2);
+ if (!ret) {
+ lcd->connected = 0;
+ dev_info(&lcd->ld->dev, "panel is not connected well\n");
+ }
+}
+
+#ifdef SMART_DIMMING
+static int ea8061_read_mtp(struct lcd_info *lcd, u8 *mtp_data)
+{
+ int ret;
+
+ unsigned char wbuf[] = {0xFD, LDI_MTP_ADDR};
+
+ ea8061_write(lcd, wbuf, ARRAY_SIZE(wbuf));
+
+ ret = ea8061_read(lcd, 0xFE, LDI_MTP_LENGTH, mtp_data, 1);
+ return ret;
+}
+#endif
+
+static int ea8061_probe(struct device *dev)
+{
+ int ret = 0, i;
+ struct lcd_info *lcd;
+
+#ifdef SMART_DIMMING
+ u8 mtp_data[LDI_MTP_LENGTH] = {0,};
+#endif
+
+ 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, &ea8061_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->bd = backlight_device_register("panel", dev, lcd, &ea8061_backlight_ops, NULL);
+ if (IS_ERR(lcd->bd)) {
+ pr_err("failed to register backlight device\n");
+ ret = PTR_ERR(lcd->bd);
+ goto out_free_backlight;
+ }
+
+ lcd->dev = dev;
+ lcd->dsim = (struct dsim_global *)dev_get_drvdata(dev->parent);
+ lcd->bd->props.max_brightness = MAX_BRIGHTNESS;
+ lcd->bd->props.brightness = DEFAULT_BRIGHTNESS;
+ lcd->bl = DEFAULT_GAMMA_LEVEL;
+ lcd->current_bl = lcd->bl;
+ lcd->acl_enable = 0;
+ lcd->current_acl = 0;
+ lcd->power = FB_BLANK_UNBLANK;
+ lcd->ldi_enable = 1;
+ lcd->connected = 1;
+ lcd->auto_brightness = 0;
+
+ ret = device_create_file(&lcd->ld->dev, &dev_attr_power_reduce);
+ if (ret < 0)
+ dev_err(&lcd->ld->dev, "failed to add sysfs entries, %d\n", __LINE__);
+
+ ret = device_create_file(&lcd->ld->dev, &dev_attr_lcd_type);
+ if (ret < 0)
+ dev_err(&lcd->ld->dev, "failed to add sysfs entries, %d\n", __LINE__);
+
+ ret = device_create_file(&lcd->ld->dev, &dev_attr_window_type);
+ if (ret < 0)
+ dev_err(&lcd->ld->dev, "failed to add sysfs entries, %d\n", __LINE__);
+
+ ret = device_create_file(&lcd->ld->dev, &dev_attr_gamma_table);
+ if (ret < 0)
+ dev_err(&lcd->ld->dev, "failed to add sysfs entries, %d\n", __LINE__);
+
+ ret = device_create_file(&lcd->bd->dev, &dev_attr_auto_brightness);
+ if (ret < 0)
+ dev_err(&lcd->ld->dev, "failed to add sysfs entries, %d\n", __LINE__);
+
+ dev_set_drvdata(dev, lcd);
+
+ mutex_init(&lcd->lock);
+ mutex_init(&lcd->bl_lock);
+
+ ea8061_read_id(lcd, lcd->id);
+
+ dev_info(&lcd->ld->dev, "ID: %x, %x, %x\n", lcd->id[0], lcd->id[1], lcd->id[2]);
+
+ dev_info(&lcd->ld->dev, "%s lcd panel driver has been probed.\n", dev_name(dev));
+
+#ifdef SMART_DIMMING
+ for (i = 0; i < LDI_ID_LEN; i++)
+ lcd->smart.panelid[i] = lcd->id[i];
+
+ init_table_info_ea8061(&lcd->smart);
+
+ ret = ea8061_read_mtp(lcd, mtp_data);
+/*
+ for (i = 0; i < LDI_MTP_LENGTH ; i++)
+ printk(" %dth mtp value is %x\n", i, mtp_data[i]);
+*/
+ if (!ret)
+ printk(KERN_ERR "[LCD:ERROR] : %s read mtp failed\n", __func__);
+
+ calc_voltage_table_ea8061(&lcd->smart, mtp_data);
+
+ ret = init_elvss_table(lcd);
+ ret += init_gamma_table(lcd, mtp_data);
+ ret += init_aid_dimming_table(lcd);
+
+ if (ret)
+ printk(KERN_ERR "gamma table generation is failed\n");
+
+ update_brightness(lcd, 1);
+#endif
+
+#if defined(GPIO_OLED_DET)
+ if (lcd->connected) {
+ INIT_DELAYED_WORK(&lcd->oled_detection, oled_detection_work);
+
+ lcd->irq = gpio_to_irq(GPIO_OLED_DET);
+
+ s3c_gpio_cfgpin(GPIO_OLED_DET, S3C_GPIO_SFN(0xf));
+ s3c_gpio_setpull(GPIO_OLED_DET, S3C_GPIO_PULL_NONE);
+
+ if (request_irq(lcd->irq, oled_detection_int,
+ IRQF_TRIGGER_FALLING, "oled_detection", lcd))
+ pr_err("failed to reqeust irq. %d\n", lcd->irq);
+ }
+#endif
+
+ lcd_early_suspend = ea8061_early_suspend;
+ lcd_late_resume = ea8061_late_resume;
+
+ return 0;
+
+out_free_backlight:
+ lcd_device_unregister(lcd->ld);
+ kfree(lcd);
+ return ret;
+
+out_free_lcd:
+ kfree(lcd);
+ return ret;
+
+err_alloc:
+ return ret;
+}
+
+static int __devexit ea8061_remove(struct device *dev)
+{
+ struct lcd_info *lcd = dev_get_drvdata(dev);
+
+ ea8061_power(lcd, FB_BLANK_POWERDOWN);
+ lcd_device_unregister(lcd->ld);
+ backlight_device_unregister(lcd->bd);
+ kfree(lcd);
+
+ return 0;
+}
+
+/* Power down all displays on reboot, poweroff or halt. */
+static void ea8061_shutdown(struct device *dev)
+{
+ struct lcd_info *lcd = dev_get_drvdata(dev);
+
+ dev_info(&lcd->ld->dev, "%s\n", __func__);
+
+ ea8061_power(lcd, FB_BLANK_POWERDOWN);
+}
+
+static struct mipi_lcd_driver ea8061_mipi_driver = {
+ .name = "ea8061",
+ .probe = ea8061_probe,
+ .remove = __devexit_p(ea8061_remove),
+ .shutdown = ea8061_shutdown,
+};
+
+static int ea8061_init(void)
+{
+ return s5p_dsim_register_lcd_driver(&ea8061_mipi_driver);
+}
+
+static void ea8061_exit(void)
+{
+ return;
+}
+
+module_init(ea8061_init);
+module_exit(ea8061_exit);
+
+MODULE_DESCRIPTION("MIPI-DSI EA8061:AMS555HBXX (720x1280) Panel Driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/video/samsung/s3cfb_fimd6x.c b/drivers/video/samsung/s3cfb_fimd6x.c
index 71a24ae..02c75e6 100644
--- a/drivers/video/samsung/s3cfb_fimd6x.c
+++ b/drivers/video/samsung/s3cfb_fimd6x.c
@@ -22,6 +22,11 @@
#include "s3cfb.h"
+#ifdef CONFIG_FB_S5P_SYSMMU
+#include <asm/cacheflush.h>
+#include <plat/s5p-sysmmu.h>
+#endif
+
void s3cfb_check_line_count(struct s3cfb_global *ctrl)
{
int timeout = 30 * 5300;
@@ -111,6 +116,12 @@ int s3cfb_set_output(struct s3cfb_global *ctrl)
return -EINVAL;
}
+#if defined(CONFIG_FB_RGBA_ORDER)
+ /* Change format to BGR order */
+ cfg &= ~(0x3F0000);
+ cfg |= 0x240000;
+#endif
+
writel(cfg, ctrl->regs + S3C_VIDCON2);
if (ctrl->output == OUTPUT_I80LDI0) {
@@ -210,7 +221,7 @@ int s3cfb_set_clock(struct s3cfb_global *ctrl)
S3C_VIDCON0_VCLKEN_FREERUN);
src_clk = clk_get_rate(ctrl->clock);
- printk(KERN_DEBUG "FIMD src sclk = %d\n", src_clk);
+ dev_dbg(ctrl->dev, "FIMD src sclk = %d\n", src_clk);
} else {
cfg &= ~(S3C_VIDCON0_CLKSEL_MASK |
S3C_VIDCON0_CLKVALUP_MASK |
@@ -223,12 +234,12 @@ int s3cfb_set_clock(struct s3cfb_global *ctrl)
if (strcmp(pdata->clk_name, "sclk_fimd") == 0) {
cfg |= S3C_VIDCON0_CLKSEL_SCLK;
src_clk = clk_get_rate(ctrl->clock);
- printk(KERN_DEBUG "FIMD src sclk = %d\n", src_clk);
+ dev_dbg(ctrl->dev, "FIMD src sclk = %d\n", src_clk);
} else {
cfg |= S3C_VIDCON0_CLKSEL_HCLK;
src_clk = ctrl->clock->parent->rate;
- printk(KERN_DEBUG "FIMD src hclk = %d\n", src_clk);
+ dev_dbg(ctrl->dev, "FIMD src hclk = %d\n", src_clk);
}
}
@@ -555,6 +566,23 @@ int s3cfb_win_map_off(struct s3cfb_global *ctrl, int id)
return 0;
}
+int s3cfb_set_window_protect(struct s3cfb_global *ctrl, int id, bool protect)
+{
+ struct s3c_platform_fb *pdata = to_fb_plat(ctrl->dev);
+ u32 shw;
+
+ if ((pdata->hw_ver == 0x62) || (pdata->hw_ver == 0x70)) {
+ shw = readl(ctrl->regs + S3C_WINSHMAP);
+ if (protect)
+ shw |= S3C_WINSHMAP_PROTECT(id);
+ else
+ shw &= ~(S3C_WINSHMAP_PROTECT(id));
+ writel(shw, ctrl->regs + S3C_WINSHMAP);
+ }
+
+ return 0;
+}
+
int s3cfb_set_window_control(struct s3cfb_global *ctrl, int id)
{
struct s3c_platform_fb *pdata = to_fb_plat(ctrl->dev);
@@ -677,6 +705,38 @@ int s3cfb_get_win_cur_buf_addr(struct s3cfb_global *ctrl, int id)
return start_addr;
}
+#ifdef CONFIG_FB_S5P_SYSMMU
+#define LV1_SHIFT 20
+#define LV1_PT_SIZE SZ_1M
+#define LV2_PT_SIZE SZ_1K
+#define LV2_BASE_MASK 0x3ff
+
+void s3cfb_clean_outer_pagetable(unsigned long vaddr, size_t size)
+{
+ unsigned long *pgd;
+ unsigned long *lv1, *lv1end;
+ unsigned long lv2pa;
+
+ if (!current->mm)
+ return;
+
+ pgd = (unsigned long *)current->mm->pgd;
+
+ lv1 = pgd + (vaddr >> LV1_SHIFT);
+ lv1end = pgd + ((vaddr + size + LV1_PT_SIZE-1) >> LV1_SHIFT);
+
+ /* clean level1 page table */
+ outer_clean_range(virt_to_phys(lv1), virt_to_phys(lv1end));
+
+ do {
+ lv2pa = *lv1 & ~LV2_BASE_MASK; /* lv2 pt base */
+ /* clean level2 page table */
+ outer_clean_range(lv2pa, lv2pa + LV2_PT_SIZE);
+ lv1++;
+ } while (lv1 != lv1end);
+}
+#endif
+
int s3cfb_set_buffer_address(struct s3cfb_global *ctrl, int id)
{
struct fb_fix_screeninfo *fix = &ctrl->fb[id]->fix;
diff --git a/drivers/video/samsung/s3cfb_ielcd.c b/drivers/video/samsung/s3cfb_ielcd.c
index b86d6f5..f8c90d2 100644
--- a/drivers/video/samsung/s3cfb_ielcd.c
+++ b/drivers/video/samsung/s3cfb_ielcd.c
@@ -59,7 +59,7 @@ int s3c_ielcd_hw_init(void)
return -ENOENT;
}
- printk(KERN_INFO "%s : 0x%p\n", __func__, s3c_ielcd_base);
+ /* printk(KERN_INFO "%s : 0x%p\n", __func__, s3c_ielcd_base); */
ielcd_fbdev = &ielcd_fb;
diff --git a/drivers/video/samsung/s3cfb_lms501xx.c b/drivers/video/samsung/s3cfb_lms501xx.c
new file mode 100644
index 0000000..c57a8be
--- /dev/null
+++ b/drivers/video/samsung/s3cfb_lms501xx.c
@@ -0,0 +1,737 @@
+/* linux/drivers/video/samsung/s3cfb_lms501xx.c
+ *
+ * MIPI-DSI based LMS501XX TFT lcd panel 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/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/mutex.h>
+#include <linux/wait.h>
+#include <linux/ctype.h>
+#include <linux/io.h>
+#include <linux/delay.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/gpio.h>
+#include <linux/workqueue.h>
+#include <linux/backlight.h>
+#include <linux/lcd.h>
+#include <plat/gpio-cfg.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 "s5p-dsim.h"
+#include "s3cfb.h"
+#include "lms501xx.h"
+
+#define POWER_IS_ON(pwr) ((pwr) <= FB_BLANK_NORMAL)
+
+#define MIN_BRIGHTNESS 0
+#define MAX_BRIGHTNESS 255
+#define MAX_GAMMA 255
+#define DEFAULT_BRIGHTNESS 160
+#define DEFAULT_GAMMA_LEVEL GAMMA_160CD
+
+#define LDI_ID_REG 0xD1
+#define LDI_ID_LEN 3
+
+struct lcd_info {
+ unsigned int bl;
+ unsigned int auto_brightness;
+ unsigned int current_cabc;
+ unsigned int current_bl;
+
+ unsigned int ldi_enable;
+ unsigned int power;
+ struct mutex lock;
+ struct mutex bl_lock;
+
+ struct device *dev;
+ struct lcd_device *ld;
+ struct backlight_device *bd;
+ struct lcd_platform_data *lcd_pd;
+ struct early_suspend early_suspend;
+
+ unsigned char id[LDI_ID_LEN];
+
+ unsigned char **gamma_table;
+ unsigned char **elvss_table;
+
+ unsigned int irq;
+ unsigned int connected;
+
+#if defined(GPIO_OLED_DET)
+ struct delayed_work oled_detection;
+ unsigned int oled_detection_count;
+#endif
+ struct dsim_global *dsim;
+};
+
+static const unsigned int candela_table[GAMMA_MAX] = {
+ 30, 40, 50, 60, 70, 80, 90, 100, 110, 120,
+ 130, 140, 150, 160, 170, 180, 190, 200, 210, 220,
+ 230, 240, 250, MAX_GAMMA
+};
+
+extern void (*lcd_early_suspend)(void);
+extern void (*lcd_late_resume)(void);
+
+#if defined(GPIO_OLED_DET)
+static void oled_detection_work(struct work_struct *work)
+{
+ struct lcd_info *lcd =
+ container_of(work, struct lcd_info, oled_detection.work);
+
+ int oled_det_level = gpio_get_value(GPIO_OLED_DET);
+
+ dev_info(&lcd->ld->dev, "%s, %d, %d\n",
+ __func__, lcd->oled_detection_count, oled_det_level);
+
+ if (!oled_det_level) {
+ if (lcd->oled_detection_count < 10) {
+ schedule_delayed_work(&lcd->oled_detection, HZ/8);
+ lcd->oled_detection_count++;
+ set_dsim_hs_clk_toggle_count(15);
+ } else
+ set_dsim_hs_clk_toggle_count(0);
+ } else
+ set_dsim_hs_clk_toggle_count(0);
+
+}
+
+static irqreturn_t oled_detection_int(int irq, void *_lcd)
+{
+ struct lcd_info *lcd = _lcd;
+
+ dev_info(&lcd->ld->dev, "%s\n", __func__);
+
+ lcd->oled_detection_count = 0;
+ schedule_delayed_work(&lcd->oled_detection, HZ/16);
+
+ return IRQ_HANDLED;
+}
+#endif
+
+static int lms501xx_write(struct lcd_info *lcd,
+ const unsigned char *seq, int len)
+{
+ int size;
+ const unsigned char *wbuf;
+
+ if (!lcd->connected)
+ return 0;
+
+ mutex_lock(&lcd->lock);
+
+ size = len;
+ wbuf = seq;
+
+ if (size == 1)
+ lcd->dsim->ops->cmd_write(lcd->dsim,
+ DCS_WR_NO_PARA, wbuf[0], 0);
+ else if (size == 2)
+ lcd->dsim->ops->cmd_write(lcd->dsim,
+ DCS_WR_1_PARA, wbuf[0], wbuf[1]);
+ else
+ lcd->dsim->ops->cmd_write(lcd->dsim,
+ DCS_LONG_WR, (unsigned int)wbuf, size);
+
+ mutex_unlock(&lcd->lock);
+
+ return 0;
+}
+
+static int _lms501xx_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_read(lcd->dsim, addr, count, buf);
+
+ mutex_unlock(&lcd->lock);
+
+ return ret;
+}
+
+static int lms501xx_read(struct lcd_info *lcd,
+ const u8 addr, u16 count, u8 *buf, u8 retry_cnt)
+{
+ int ret = 0;
+
+read_retry:
+ ret = _lms501xx_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;
+}
+
+static int get_backlight_level_from_brightness(int brightness)
+{
+ int backlightlevel;
+
+ /* brightness setting from platform is from 0 to 255
+ * But in this driver, brightness is only supported from 0 to 24 */
+
+ switch (brightness) {
+ case 0 ... 29:
+ backlightlevel = GAMMA_30CD;
+ break;
+ case 30 ... 254:
+ backlightlevel = (brightness - candela_table[0]) / 10;
+ break;
+ case 255:
+ backlightlevel = ARRAY_SIZE(candela_table) - 1;
+ break;
+ default:
+ backlightlevel = DEFAULT_GAMMA_LEVEL;
+ break;
+ }
+ return backlightlevel;
+}
+
+static int lms501xx_gamma_ctl(struct lcd_info *lcd)
+{
+ SEQ_SET_BL[1] = candela_table[lcd->bl];
+ lms501xx_write(lcd, SEQ_SET_BL, ARRAY_SIZE(SEQ_SET_BL));
+ lms501xx_write(lcd, SEQ_SET_DISP, ARRAY_SIZE(SEQ_SET_DISP));
+ return 0;
+}
+
+static int lms501xx_set_cabc(struct lcd_info *lcd)
+{
+ int ret = 0;
+
+ dev_info(&lcd->ld->dev, "%s - %d\n", __func__, lcd->current_cabc);
+ if (lcd->current_cabc)
+ lms501xx_write(lcd,
+ SEQ_SET_CABC_ON, ARRAY_SIZE(SEQ_SET_CABC_ON));
+ else
+ lms501xx_write(lcd,
+ SEQ_SET_CABC_OFF, ARRAY_SIZE(SEQ_SET_CABC_OFF));
+
+ mdelay(5);
+
+ return ret;
+}
+
+static int update_brightness(struct lcd_info *lcd, u8 force)
+{
+ u32 brightness;
+
+ mutex_lock(&lcd->bl_lock);
+
+ brightness = lcd->bd->props.brightness;
+
+ if (unlikely(!lcd->auto_brightness && brightness > 250))
+ brightness = 250;
+
+ lcd->bl = get_backlight_level_from_brightness(brightness);
+
+ if ((force) || ((lcd->ldi_enable) && (lcd->current_bl != lcd->bl))) {
+
+ lms501xx_gamma_ctl(lcd);
+ lms501xx_set_cabc(lcd);
+
+ lcd->current_bl = lcd->bl;
+
+ dev_info(&lcd->ld->dev, "brightness=%d, bl=%d, candela=%d\n",
+ brightness, lcd->bl, candela_table[lcd->bl]);
+ }
+
+ mutex_unlock(&lcd->bl_lock);
+
+ return 0;
+}
+
+static int lms501xx_ldi_init(struct lcd_info *lcd)
+{
+ int ret = 0;
+
+ dev_info(&lcd->ld->dev, "%s\n", __func__);
+
+ lms501xx_write(lcd, SEQ_SET_EXTC, ARRAY_SIZE(SEQ_SET_EXTC));
+ mdelay(5);
+ lms501xx_write(lcd, SEQ_SET_MIPI_DSI, ARRAY_SIZE(SEQ_SET_MIPI_DSI));
+ lms501xx_write(lcd, SEQ_SET_GIP, ARRAY_SIZE(SEQ_SET_GIP));
+ lms501xx_write(lcd, SEQ_SET_POWER, ARRAY_SIZE(SEQ_SET_POWER));
+ mdelay(5);
+ lms501xx_write(lcd, SEQ_SLEEP_OUT, ARRAY_SIZE(SEQ_SLEEP_OUT));
+ msleep(125);
+ lms501xx_write(lcd, SEQ_SET_RGB, ARRAY_SIZE(SEQ_SET_RGB));
+ lms501xx_write(lcd, SEQ_SET_CYC, ARRAY_SIZE(SEQ_SET_CYC));
+ lms501xx_write(lcd, SEQ_SET_VCOM, ARRAY_SIZE(SEQ_SET_VCOM));
+ lms501xx_write(lcd, SEQ_SET_PTBA, ARRAY_SIZE(SEQ_SET_PTBA));
+ lms501xx_write(lcd, SEQ_SET_PANEL, ARRAY_SIZE(SEQ_SET_PANEL));
+ lms501xx_write(lcd, SEQ_SET_DGC, ARRAY_SIZE(SEQ_SET_DGC));
+ lms501xx_write(lcd, SEQ_SET_STBA, ARRAY_SIZE(SEQ_SET_STBA));
+ lms501xx_write(lcd, SEQ_SET_EQ, ARRAY_SIZE(SEQ_SET_EQ));
+ lms501xx_write(lcd, SEQ_SET_VCOM_POWER, ARRAY_SIZE(SEQ_SET_VCOM_POWER));
+ lms501xx_write(lcd, SEQ_SET_ECO, ARRAY_SIZE(SEQ_SET_ECO));
+ lms501xx_write(lcd, SEQ_SET_GAMMA, ARRAY_SIZE(SEQ_SET_GAMMA));
+ lms501xx_write(lcd, SEQ_SET_CABC_PWM, ARRAY_SIZE(SEQ_SET_CABC_PWM));
+
+ return ret;
+}
+
+static int lms501xx_ldi_enable(struct lcd_info *lcd)
+{
+ int ret = 0;
+
+ lms501xx_write(lcd, SEQ_DISPLAY_ON, ARRAY_SIZE(SEQ_DISPLAY_ON));
+ msleep(100);
+
+ return ret;
+}
+
+static int lms501xx_ldi_disable(struct lcd_info *lcd)
+{
+ int ret = 0;
+
+ lms501xx_write(lcd, SEQ_DISPLAY_OFF, ARRAY_SIZE(SEQ_DISPLAY_OFF));
+ lms501xx_write(lcd, SEQ_SLEEP_IN, ARRAY_SIZE(SEQ_SLEEP_IN));
+
+ return ret;
+}
+
+static int lms501xx_power_on(struct lcd_info *lcd)
+{
+ int ret = 0;
+ struct lcd_platform_data *pd = NULL;
+ pd = lcd->lcd_pd;
+
+ dev_info(&lcd->ld->dev, "%s\n", __func__);
+
+ ret = lms501xx_ldi_init(lcd);
+ if (ret) {
+ dev_err(&lcd->ld->dev, "failed to initialize ldi.\n");
+ goto err;
+ }
+
+ msleep(120);
+
+ ret = lms501xx_ldi_enable(lcd);
+ if (ret) {
+ dev_err(&lcd->ld->dev, "failed to enable ldi.\n");
+ goto err;
+ }
+
+ lcd->ldi_enable = 1;
+
+ update_brightness(lcd, 1);
+err:
+ return ret;
+}
+
+static int lms501xx_power_off(struct lcd_info *lcd)
+{
+ int ret = 0;
+
+ dev_info(&lcd->ld->dev, "%s\n", __func__);
+
+ lcd->ldi_enable = 0;
+
+ ret = lms501xx_ldi_disable(lcd);
+
+ msleep(135);
+
+ return ret;
+}
+
+static int lms501xx_power(struct lcd_info *lcd, int power)
+{
+ int ret = 0;
+
+ if (POWER_IS_ON(power) && !POWER_IS_ON(lcd->power))
+ ret = lms501xx_power_on(lcd);
+ else if (!POWER_IS_ON(power) && POWER_IS_ON(lcd->power))
+ ret = lms501xx_power_off(lcd);
+
+ if (!ret)
+ lcd->power = power;
+
+ return ret;
+}
+
+static int lms501xx_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 lms501xx_power(lcd, power);
+}
+
+static int lms501xx_get_power(struct lcd_device *ld)
+{
+ struct lcd_info *lcd = lcd_get_data(ld);
+
+ return lcd->power;
+}
+
+static int lms501xx_check_fb(struct lcd_device *ld, struct fb_info *fb)
+{
+ struct s3cfb_window *win = fb->par;
+ struct lcd_info *lcd = lcd_get_data(ld);
+
+ dev_info(&lcd->ld->dev, "%s, fb%d\n", __func__, win->id);
+
+ return 0;
+}
+
+static int lms501xx_set_brightness(struct backlight_device *bd)
+{
+ int ret = 0;
+ int brightness = bd->props.brightness;
+ struct lcd_info *lcd = bl_get_data(bd);
+
+ 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, MAX_BRIGHTNESS, brightness);
+ return -EINVAL;
+ }
+
+ if (lcd->ldi_enable) {
+ ret = update_brightness(lcd, 0);
+ if (ret < 0) {
+ dev_err(lcd->dev, "err in %s\n", __func__);
+ return -EINVAL;
+ }
+ }
+
+ return ret;
+}
+
+static int lms501xx_get_brightness(struct backlight_device *bd)
+{
+ struct lcd_info *lcd = bl_get_data(bd);
+
+ return candela_table[lcd->bl];
+}
+
+static struct lcd_ops lms501xx_lcd_ops = {
+ .set_power = lms501xx_set_power,
+ .get_power = lms501xx_get_power,
+ .check_fb = lms501xx_check_fb,
+};
+
+static const struct backlight_ops lms501xx_backlight_ops = {
+ .get_brightness = lms501xx_get_brightness,
+ .update_status = lms501xx_set_brightness,
+};
+
+static ssize_t power_reduce_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct lcd_info *lcd = dev_get_drvdata(dev);
+ char temp[3];
+
+ sprintf(temp, "%d\n", lcd->current_cabc);
+ strcpy(buf, temp);
+
+ return strlen(buf);
+}
+
+static ssize_t power_reduce_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t size)
+{
+ struct lcd_info *lcd = 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 (lcd->current_cabc != value) {
+ dev_info(dev, "%s - %d, %d\n",
+ __func__, lcd->current_cabc, value);
+ mutex_lock(&lcd->bl_lock);
+ lcd->current_cabc = value;
+ if (lcd->ldi_enable)
+ lms501xx_set_cabc(lcd);
+ mutex_unlock(&lcd->bl_lock);
+ }
+ }
+ return size;
+}
+
+static DEVICE_ATTR(power_reduce, 0664, power_reduce_show, power_reduce_store);
+
+static ssize_t lcd_type_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ char temp[15];
+ sprintf(temp, "SMD_LMS501KF06\n");
+ strcat(buf, temp);
+ return strlen(buf);
+}
+
+static DEVICE_ATTR(lcd_type, 0444, lcd_type_show, NULL);
+
+static ssize_t auto_brightness_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct lcd_info *lcd = dev_get_drvdata(dev);
+ char temp[3];
+
+ sprintf(temp, "%d\n", lcd->auto_brightness);
+ strcpy(buf, temp);
+
+ return strlen(buf);
+}
+
+static ssize_t auto_brightness_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t size)
+{
+ struct lcd_info *lcd = 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 (lcd->auto_brightness != value) {
+ dev_info(dev, "%s - %d, %d\n",
+ __func__, lcd->auto_brightness, value);
+ mutex_lock(&lcd->bl_lock);
+ lcd->auto_brightness = value;
+ mutex_unlock(&lcd->bl_lock);
+ if (lcd->ldi_enable)
+ update_brightness(lcd, 0);
+ }
+ }
+ return size;
+}
+
+static DEVICE_ATTR(auto_brightness, 0644,
+ auto_brightness_show, auto_brightness_store);
+
+#ifdef CONFIG_HAS_EARLYSUSPEND
+struct lcd_info *g_lcd;
+
+void lms501xx_early_suspend(void)
+{
+ struct lcd_info *lcd = g_lcd;
+
+ set_dsim_lcd_enabled(0);
+
+ dev_info(&lcd->ld->dev, "+%s\n", __func__);
+#if defined(GPIO_OLED_DET)
+ disable_irq(lcd->irq);
+ gpio_request(GPIO_OLED_DET, "OLED_DET");
+ s3c_gpio_cfgpin(GPIO_OLED_DET, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_OLED_DET, S3C_GPIO_PULL_NONE);
+ gpio_direction_output(GPIO_OLED_DET, GPIO_LEVEL_LOW);
+ gpio_free(GPIO_OLED_DET);
+#endif
+ lms501xx_power(lcd, FB_BLANK_POWERDOWN);
+ dev_info(&lcd->ld->dev, "-%s\n", __func__);
+
+ return ;
+}
+
+void lms501xx_late_resume(void)
+{
+ struct lcd_info *lcd = g_lcd;
+
+ dev_info(&lcd->ld->dev, "+%s\n", __func__);
+ lms501xx_power(lcd, FB_BLANK_UNBLANK);
+#if defined(GPIO_OLED_DET)
+ s3c_gpio_cfgpin(GPIO_OLED_DET, S3C_GPIO_SFN(0xf));
+ s3c_gpio_setpull(GPIO_OLED_DET, S3C_GPIO_PULL_NONE);
+ enable_irq(lcd->irq);
+#endif
+ dev_info(&lcd->ld->dev, "-%s\n", __func__);
+
+ set_dsim_lcd_enabled(1);
+
+ return ;
+}
+#endif
+
+static void lms501xx_read_id(struct lcd_info *lcd, u8 *buf)
+{
+ int ret = 0;
+
+ ret = lms501xx_read(lcd, LDI_ID_REG, LDI_ID_LEN, buf, 3);
+ if (!ret) {
+ lcd->connected = 0;
+ dev_info(&lcd->ld->dev, "panel is not connected well\n");
+ }
+}
+
+static int lms501xx_probe(struct device *dev)
+{
+ int ret = 0;
+ struct lcd_info *lcd;
+
+ 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, &lms501xx_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->bd = backlight_device_register("panel",
+ dev, lcd, &lms501xx_backlight_ops, NULL);
+ if (IS_ERR(lcd->bd)) {
+ pr_err("failed to register backlight device\n");
+ ret = PTR_ERR(lcd->bd);
+ goto out_free_backlight;
+ }
+
+ lcd->dev = dev;
+ lcd->dsim = (struct dsim_global *)dev_get_drvdata(dev->parent);
+ lcd->bd->props.max_brightness = MAX_BRIGHTNESS;
+ lcd->bd->props.brightness = DEFAULT_BRIGHTNESS;
+ lcd->bl = DEFAULT_GAMMA_LEVEL;
+ lcd->current_bl = lcd->bl;
+ lcd->current_cabc = 0;
+
+ lcd->power = FB_BLANK_UNBLANK;
+ lcd->ldi_enable = 1;
+ lcd->connected = 1;
+ lcd->auto_brightness = 0;
+
+ ret = device_create_file(&lcd->ld->dev, &dev_attr_power_reduce);
+ if (ret < 0)
+ dev_err(&lcd->ld->dev,
+ "failed to add sysfs entries, %d\n", __LINE__);
+
+ ret = device_create_file(&lcd->ld->dev, &dev_attr_lcd_type);
+ if (ret < 0)
+ dev_err(&lcd->ld->dev,
+ "failed to add sysfs entries, %d\n", __LINE__);
+
+ ret = device_create_file(&lcd->bd->dev, &dev_attr_auto_brightness);
+ if (ret < 0)
+ dev_err(&lcd->ld->dev,
+ "failed to add sysfs entries, %d\n", __LINE__);
+
+ dev_set_drvdata(dev, lcd);
+
+ mutex_init(&lcd->lock);
+ mutex_init(&lcd->bl_lock);
+
+ dev_info(&lcd->ld->dev, "lms501xx lcd panel driver has been probed.\n");
+
+ update_brightness(lcd, 1);
+
+#if defined(GPIO_OLED_DET)
+ if (lcd->connected) {
+ INIT_DELAYED_WORK(&lcd->oled_detection, oled_detection_work);
+
+ lcd->irq = gpio_to_irq(GPIO_OLED_DET);
+
+ s3c_gpio_cfgpin(GPIO_OLED_DET, S3C_GPIO_SFN(0xf));
+ s3c_gpio_setpull(GPIO_OLED_DET, S3C_GPIO_PULL_NONE);
+ if (request_irq(lcd->irq, oled_detection_int,
+ IRQF_TRIGGER_FALLING, "oled_detection", lcd))
+ pr_err("failed to reqeust irq. %d\n", lcd->irq);
+ }
+#endif
+
+ lcd_early_suspend = lms501xx_early_suspend;
+ lcd_late_resume = lms501xx_late_resume;
+
+ return 0;
+
+out_free_backlight:
+ lcd_device_unregister(lcd->ld);
+ kfree(lcd);
+ return ret;
+
+out_free_lcd:
+ kfree(lcd);
+ return ret;
+
+err_alloc:
+ return ret;
+}
+
+static int __devexit lms501xx_remove(struct device *dev)
+{
+ struct lcd_info *lcd = dev_get_drvdata(dev);
+
+ lms501xx_power(lcd, FB_BLANK_POWERDOWN);
+ lcd_device_unregister(lcd->ld);
+ backlight_device_unregister(lcd->bd);
+ kfree(lcd);
+
+ return 0;
+}
+
+/* Power down all displays on reboot, poweroff or halt. */
+static void lms501xx_shutdown(struct device *dev)
+{
+ struct lcd_info *lcd = dev_get_drvdata(dev);
+
+ dev_info(&lcd->ld->dev, "%s\n", __func__);
+
+ lms501xx_power(lcd, FB_BLANK_POWERDOWN);
+}
+
+static struct mipi_lcd_driver lms501xx_mipi_driver = {
+ .name = "lms501xx",
+ .probe = lms501xx_probe,
+ .remove = __devexit_p(lms501xx_remove),
+ .shutdown = lms501xx_shutdown,
+};
+
+static int lms501xx_init(void)
+{
+ return s5p_dsim_register_lcd_driver(&lms501xx_mipi_driver);
+}
+
+static void lms501xx_exit(void)
+{
+ return;
+}
+
+module_init(lms501xx_init);
+module_exit(lms501xx_exit);
+
+MODULE_DESCRIPTION("MIPI-DSI LMS501XX WVGA (480x800) Panel Driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/video/samsung/s3cfb_main.c b/drivers/video/samsung/s3cfb_main.c
index 2cb7c86..a723306 100644
--- a/drivers/video/samsung/s3cfb_main.c
+++ b/drivers/video/samsung/s3cfb_main.c
@@ -29,7 +29,7 @@
#include <linux/memory.h>
#include <linux/pm_runtime.h>
#include <linux/delay.h>
-#include <linux/kthread.h>
+#include <linux/sw_sync.h>
#include <plat/clock.h>
#include <plat/media.h>
#include <mach/media.h>
@@ -58,11 +58,13 @@
#include <mach/regs-pmu.h>
#include <plat/regs-fb-s5p.h>
-extern int s3cfb_vsync_timestamp_changed(struct s3cfb_global *fbdev, ktime_t prev_timestamp);
+#ifdef CONFIG_FB_S5P_SYSMMU
+#include <plat/s5p-sysmmu.h>
+#endif
struct s3cfb_fimd_desc *fbfimd;
-inline struct s3cfb_global *get_fimd_global(int id)
+struct s3cfb_global *get_fimd_global(int id)
{
struct s3cfb_global *fbdev;
@@ -85,17 +87,57 @@ int s3cfb_vsync_status_check(void)
return 0;
}
+#if defined(CONFIG_FB_S5P_VSYNC_THREAD)
+static void s3cfb_activate_vsync(struct s3cfb_global *fbdev)
+{
+ int prev_refcount;
+
+ mutex_lock(&fbdev->vsync_info.irq_lock);
+ prev_refcount = fbdev->vsync_info.irq_refcount++;
+ if (!prev_refcount) {
+ s3cfb_set_global_interrupt(fbdev, 1);
+ s3cfb_set_vsync_interrupt(fbdev, 1);
+ }
+
+ mutex_unlock(&fbdev->vsync_info.irq_lock);
+}
+
+static void s3cfb_deactivate_vsync(struct s3cfb_global *fbdev)
+{
+ int new_refcount;
+
+ mutex_lock(&fbdev->vsync_info.irq_lock);
+
+ new_refcount = --fbdev->vsync_info.irq_refcount;
+ WARN_ON(new_refcount < 0);
+ if (!new_refcount) {
+ s3cfb_set_global_interrupt(fbdev, 0);
+ s3cfb_set_vsync_interrupt(fbdev, 0);
+ }
+
+ mutex_unlock(&fbdev->vsync_info.irq_lock);
+}
+#endif
+
static irqreturn_t s3cfb_irq_frame(int irq, void *dev_id)
{
struct s3cfb_global *fbdev[2];
fbdev[0] = fbfimd->fbdev[0];
+ spin_lock(&fbdev[0]->vsync_slock);
+
if (fbdev[0]->regs != 0)
s3cfb_clear_interrupt(fbdev[0]);
+#if defined(CONFIG_FB_S5P_VSYNC_THREAD)
+ fbdev[0]->vsync_info.timestamp = ktime_get();
+ wake_up_interruptible_all(&fbdev[0]->vsync_info.wait);
+#endif
+
fbdev[0]->wq_count++;
- fbdev[0]->vsync_timestamp = ktime_get();
- wake_up_interruptible(&fbdev[0]->wq);
+ wake_up(&fbdev[0]->wq);
+
+ spin_unlock(&fbdev[0]->vsync_slock);
return IRQ_HANDLED;
}
@@ -113,6 +155,57 @@ static irqreturn_t s3cfb_irq_fifo(int irq, void *dev_id)
}
#endif
+#if defined(CONFIG_FB_S5P_VSYNC_THREAD)
+int s3cfb_set_vsync_int(struct fb_info *info, bool active)
+{
+ struct s3cfb_global *fbdev = fbfimd->fbdev[0];
+ bool prev_active = fbdev->vsync_info.active;
+
+ fbdev->vsync_info.active = active;
+
+ if (active && !prev_active)
+ s3cfb_activate_vsync(fbdev);
+ else if (!active && prev_active)
+ s3cfb_deactivate_vsync(fbdev);
+
+ return 0;
+}
+
+/**
+ * s3cfb_wait_for_vsync() - sleep until next VSYNC interrupt or timeout
+ * @sfb: main hardware state
+ * @timeout: timeout in msecs, or 0 to wait indefinitely.
+ */
+int s3cfb_wait_for_vsync(struct s3cfb_global *fbdev, u32 timeout)
+{
+ ktime_t timestamp;
+ int ret;
+
+ pm_runtime_get_sync(fbdev->dev);
+
+ timestamp = fbdev->vsync_info.timestamp;
+ s3cfb_activate_vsync(fbdev);
+ if (timeout) {
+ ret = wait_event_interruptible_timeout(fbdev->vsync_info.wait,
+ !ktime_equal(timestamp,
+ fbdev->vsync_info.timestamp),
+ msecs_to_jiffies(timeout));
+ } else {
+ ret = wait_event_interruptible(fbdev->vsync_info.wait,
+ !ktime_equal(timestamp,
+ fbdev->vsync_info.timestamp));
+ }
+ s3cfb_deactivate_vsync(fbdev);
+
+ pm_runtime_put_sync(fbdev->dev);
+
+ if (timeout && ret == 0)
+ return -ETIMEDOUT;
+
+ return 0;
+}
+#endif
+
int s3cfb_register_framebuffer(struct s3cfb_global *fbdev)
{
struct s3c_platform_fb *pdata = to_fb_plat(fbdev->dev);
@@ -322,30 +415,53 @@ void s3cfb_trigger(void)
EXPORT_SYMBOL(s3cfb_trigger);
#endif
+#if defined(CONFIG_FB_S5P_VSYNC_THREAD)
static int s3cfb_wait_for_vsync_thread(void *data)
{
- struct s3cfb_global *fbdev = data;
-
- while (!kthread_should_stop()) {
- ktime_t prev_timestamp = fbdev->vsync_timestamp;
-
- int ret = wait_event_interruptible_timeout(fbdev->wq,
- s3cfb_vsync_timestamp_changed(fbdev, prev_timestamp),
- msecs_to_jiffies(100));
-
- if (ret > 0) {
- char *envp[2];
- char buf[64];
+ struct s3cfb_global *fbdev = data;
+
+ while (!kthread_should_stop()) {
+ ktime_t timestamp = fbdev->vsync_info.timestamp;
+ int ret = wait_event_interruptible_timeout(
+ fbdev->vsync_info.wait,
+ !ktime_equal(timestamp,
+ fbdev->vsync_info.timestamp) &&
+ fbdev->vsync_info.active,
+ msecs_to_jiffies(VSYNC_TIMEOUT_MSEC));
+
+ if (ret > 0) {
+ char *envp[2];
+ char buf[64];
+ snprintf(buf, sizeof(buf), "VSYNC=%llu",
+ ktime_to_ns(fbdev->vsync_info.timestamp));
+ envp[0] = buf;
+ envp[1] = NULL;
+ kobject_uevent_env(&fbdev->dev->kobj, KOBJ_CHANGE,
+ envp);
+ }
+ }
- snprintf(buf, sizeof(buf), "VSYNC=%llu",
- ktime_to_ns(fbdev->vsync_timestamp));
- envp[0] = buf;
- envp[1] = NULL;
- kobject_uevent_env(&fbdev->dev->kobj, KOBJ_CHANGE, envp);
- }
- }
+ return 0;
+}
+#endif
- return 0;
+static void s3c_fb_update_regs_handler(struct kthread_work *work)
+{
+ struct s3cfb_global *fbdev =
+ container_of(work, struct s3cfb_global, update_regs_work);
+ struct s3c_reg_data *data, *next;
+ struct list_head saved_list;
+
+ mutex_lock(&fbdev->update_regs_list_lock);
+ saved_list = fbdev->update_regs_list;
+ list_replace_init(&fbdev->update_regs_list, &saved_list);
+ mutex_unlock(&fbdev->update_regs_list_lock);
+
+ list_for_each_entry_safe(data, next, &saved_list, list) {
+ s3c_fb_update_regs(fbdev, data);
+ list_del(&data->list);
+ kfree(data);
+ }
}
static int s3cfb_probe(struct platform_device *pdev)
@@ -362,7 +478,13 @@ static int s3cfb_probe(struct platform_device *pdev)
/* enable the power domain */
pm_runtime_get_sync(&pdev->dev);
#endif
+
fbfimd = kzalloc(sizeof(struct s3cfb_fimd_desc), GFP_KERNEL);
+ if (!fbfimd) {
+ printk(KERN_ERR "failed to allocate for fimd fb descriptor\n");
+ ret = -ENOMEM;
+ goto err_fimd_desc;
+ }
if (FIMD_MAX == 2)
fbfimd->dual = 1;
@@ -418,9 +540,30 @@ static int s3cfb_probe(struct platform_device *pdev)
if (!fbdev[i]->regs) {
dev_err(fbdev[i]->dev, "failed to remap io region\n");
ret = -EINVAL;
- goto err1;
+ goto err_ioremap;
}
+ spin_lock_init(&fbdev[i]->vsync_slock);
+
+#if defined(CONFIG_FB_S5P_VSYNC_THREAD)
+ INIT_LIST_HEAD(&fbdev[i]->update_regs_list);
+ mutex_init(&fbdev[i]->update_regs_list_lock);
+ init_kthread_worker(&fbdev[i]->update_regs_worker);
+
+ fbdev[i]->update_regs_thread = kthread_run(kthread_worker_fn,
+ &fbdev[i]->update_regs_worker, "s3c-fb");
+ if (IS_ERR(fbdev[i]->update_regs_thread)) {
+ int err = PTR_ERR(fbdev[i]->update_regs_thread);
+ fbdev[i]->update_regs_thread = NULL;
+
+ dev_err(fbdev[i]->dev, "failed to run update_regs thread\n");
+ return err;
+ }
+ init_kthread_work(&fbdev[i]->update_regs_work, s3c_fb_update_regs_handler);
+ fbdev[i]->timeline = sw_sync_timeline_create("s3c-fb");
+ fbdev[i]->timeline_max = 0;
+#endif
+
/* irq */
fbdev[i]->irq = platform_get_irq(pdev, 0);
if (request_irq(fbdev[i]->irq, s3cfb_irq_frame, IRQF_SHARED,
@@ -463,7 +606,7 @@ static int s3cfb_probe(struct platform_device *pdev)
/* register fb_info */
if (s3cfb_register_framebuffer(fbdev[i])) {
dev_err(fbdev[i]->dev, "register error fimd[%d]\n", i);
- return -EINVAL;
+ ret = -EINVAL;
goto err3;
}
@@ -506,6 +649,20 @@ static int s3cfb_probe(struct platform_device *pdev)
register_early_suspend(&fbdev[i]->early_suspend);
#endif
#endif
+#if defined(CONFIG_FB_S5P_VSYNC_THREAD)
+ init_waitqueue_head(&fbdev[i]->vsync_info.wait);
+
+ /* Create vsync thread */
+ mutex_init(&fbdev[i]->vsync_info.irq_lock);
+
+ fbdev[i]->vsync_info.thread = kthread_run(
+ s3cfb_wait_for_vsync_thread,
+ fbdev[i], "s3c-fb-vsync");
+ if (fbdev[i]->vsync_info.thread == ERR_PTR(-ENOMEM)) {
+ dev_err(fbdev[i]->dev, "failed to run vsync thread\n");
+ fbdev[i]->vsync_info.thread = NULL;
+ }
+#endif
ret = device_create_file(fbdev[i]->dev, &dev_attr_fimd_dump);
if (ret < 0)
dev_err(fbdev[0]->dev, "failed to add sysfs entries\n");
@@ -524,12 +681,6 @@ static int s3cfb_probe(struct platform_device *pdev)
pdata->lcd_on(pdev);
#endif
- fbdev[0]->vsync_thread = kthread_run(s3cfb_wait_for_vsync_thread, fbdev[0], "s3cfb-vsync");
- if (fbdev[0]->vsync_thread == ERR_PTR(-ENOMEM)) {
- dev_err(fbdev[0]->dev, "failed to run vsync thread\n");
- fbdev[0]->vsync_thread = NULL;
- }
-
ret = device_create_file(&(pdev->dev), &dev_attr_win_power);
if (ret < 0)
dev_err(fbdev[0]->dev, "failed to add sysfs entries\n");
@@ -557,10 +708,18 @@ err3:
err2:
for (i = 0; i < FIMD_MAX; i++)
iounmap(fbdev[i]->regs);
+
+err_ioremap:
+ release_mem_region(res->start, res->end - res->start + 1);
+
err1:
- for (i = 0; i < FIMD_MAX; i++)
+ for (i = 0; i < FIMD_MAX; i++) {
pdata->clk_off(pdev, &fbdev[i]->clock);
+ kfree(fbfimd->fbdev[i]);
+ }
err0:
+ kfree(fbfimd);
+err_fimd_desc:
return ret;
}
@@ -600,9 +759,10 @@ static int s3cfb_remove(struct platform_device *pdev)
framebuffer_release(fb);
}
}
-
- if (fbdev[i]->vsync_thread)
- kthread_stop(fbdev[i]->vsync_thread);
+#if defined(CONFIG_FB_S5P_VSYNC_THREAD)
+ if (fbdev[i]->vsync_info.thread)
+ kthread_stop(fbdev[i]->vsync_info.thread);
+#endif
kfree(fbdev[i]->fb);
kfree(fbdev[i]);
@@ -694,6 +854,9 @@ void s3cfb_lcd0_pmu_off(void)
#ifdef CONFIG_PM
#ifdef CONFIG_HAS_EARLYSUSPEND
+void (*lcd_early_suspend)(void);
+void (*lcd_late_resume)(void);
+
void s3cfb_early_suspend(struct early_suspend *h)
{
struct s3cfb_global *info = container_of(h, struct s3cfb_global, early_suspend);
@@ -705,11 +868,8 @@ void s3cfb_early_suspend(struct early_suspend *h)
printk(KERN_INFO "+%s\n", __func__);
#ifdef CONFIG_FB_S5P_MIPI_DSIM
-#if defined(CONFIG_FB_S5P_S6E63M0)
- s6e63m0_early_suspend();
-#else
- s6e8ax0_early_suspend();
-#endif
+ if (lcd_early_suspend)
+ lcd_early_suspend();
#endif
for (i = 0; i < FIMD_MAX; i++) {
@@ -765,8 +925,15 @@ void s3cfb_early_suspend(struct early_suspend *h)
pm_runtime_put_sync(&pdev->dev);
#endif
- printk(KERN_INFO "-%s\n", __func__);
+#ifdef CONFIG_FB_S5P_SYSMMU
+ if (fbdev[0]->sysmmu.enabled == true) {
+ fbdev[0]->sysmmu.enabled = false;
+ fbdev[0]->sysmmu.pgd = 0;
+ s5p_sysmmu_disable(fbdev[0]->dev);
+ }
+#endif
+ printk(KERN_INFO "-%s\n", __func__);
return ;
}
@@ -780,28 +947,18 @@ void s3cfb_late_resume(struct early_suspend *h)
int i, j;
struct platform_device *pdev = to_platform_device(info->dev);
- printk(KERN_INFO "+%s\n", __func__);
+ dev_info(info->dev, "+%s\n", __func__);
dev_dbg(info->dev, "wake up from suspend\n");
#ifdef CONFIG_EXYNOS_DEV_PD
/* enable the power domain */
- printk(KERN_DEBUG "s3cfb - enable power domain\n");
+ dev_dbg(info->dev, "s3cfb - enable power domain\n");
pm_runtime_get_sync(&pdev->dev);
#endif
#ifdef CONFIG_FB_S5P_MIPI_DSIM
s5p_dsim_late_resume();
-
- if (s5p_dsim_fifo_clear() == 0) {
- s5p_dsim_early_suspend();
- usleep_range(10000, 10000);
- s5p_dsim_late_resume();
- if (s5p_dsim_fifo_clear() == 0)
- pr_info("dsim resume fail!!!\n");
- }
-
- usleep_range(10000, 10000);
#endif
#if defined(CONFIG_FB_S5P_DUMMYLCD)
@@ -819,6 +976,10 @@ void s3cfb_late_resume(struct early_suspend *h)
/* fbdev[i]->regs_org should be non-zero value */
BUG();
+#if defined(CONFIG_FB_MDNIE_PWM)
+ set_mdnie_pwm_value(g_mdnie, 0);
+#endif
+
if (pdata->set_display_path)
pdata->set_display_path();
@@ -848,6 +1009,9 @@ void s3cfb_late_resume(struct early_suspend *h)
/* Set alpha value width to 8-bit */
s3cfb_set_alpha_value_width(fbdev[i], i);
+#if defined(CONFIG_FB_RGBA_ORDER)
+ s3cfb_set_output(fbdev[i]);
+#else
for (j = 0; j < pdata->nr_wins; j++) {
fb = fbdev[i]->fb[j];
win = fb->par;
@@ -857,6 +1021,7 @@ void s3cfb_late_resume(struct early_suspend *h)
s3cfb_enable_window(fbdev[i], win->id);
}
}
+#endif
if (pdata->cfg_gpio)
pdata->cfg_gpio(pdev);
@@ -869,17 +1034,23 @@ void s3cfb_late_resume(struct early_suspend *h)
if (pdata->backlight_on)
pdata->backlight_on(pdev);
+
+#if defined(CONFIG_FB_S5P_VSYNC_THREAD)
+ mutex_lock(&fbdev[i]->vsync_info.irq_lock);
+ if (fbdev[i]->vsync_info.irq_refcount) {
+ s3cfb_set_global_interrupt(fbdev[i], 1);
+ s3cfb_set_vsync_interrupt(fbdev[i], 1);
+ }
+ mutex_unlock(&fbdev[i]->vsync_info.irq_lock);
+#endif
}
#ifdef CONFIG_FB_S5P_MIPI_DSIM
-#if defined(CONFIG_FB_S5P_S6E63M0)
- s6e63m0_late_resume();
-#else
- s6e8ax0_late_resume();
-#endif
+ if (lcd_late_resume)
+ lcd_late_resume();
#endif
- printk(KERN_INFO "-%s\n", __func__);
+ dev_info(info->dev, "-%s\n", __func__);
return;
}
diff --git a/drivers/video/samsung/s3cfb_mdnie.c b/drivers/video/samsung/s3cfb_mdnie.c
index 0fa2f60..a578dac 100644
--- a/drivers/video/samsung/s3cfb_mdnie.c
+++ b/drivers/video/samsung/s3cfb_mdnie.c
@@ -188,7 +188,7 @@ int s3c_mdnie_hw_init(void)
return -ENOENT;
}
- printk(KERN_INFO "%s : 0x%p\n", __func__, s3c_mdnie_base);
+ /* printk(KERN_INFO "%s : 0x%p\n", __func__, s3c_mdnie_base); */
return 0;
}
diff --git a/drivers/video/samsung/s3cfb_ops.c b/drivers/video/samsung/s3cfb_ops.c
index 82ece16..759fb63 100644
--- a/drivers/video/samsung/s3cfb_ops.c
+++ b/drivers/video/samsung/s3cfb_ops.c
@@ -15,6 +15,12 @@
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
+#include <linux/file.h>
+#include <linux/fs.h>
+#include <linux/sw_sync.h>
+#include <plat/regs-fb.h>
+#include <plat/regs-fb-s5p.h>
+
#if defined(CONFIG_CMA)
#include <linux/cma.h>
#elif defined(CONFIG_S5P_MEM_BOOTMEM)
@@ -43,6 +49,10 @@
#include <mach/dev.h>
#endif
+#ifdef CONFIG_FB_S5P_SYSMMU
+#include <plat/s5p-sysmmu.h>
+#endif
+
struct s3c_platform_fb *to_fb_plat(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
@@ -183,7 +193,10 @@ int s3cfb_enable_window(struct s3cfb_global *fbdev, int id)
#endif
#if defined(CONFIG_CPU_EXYNOS4212) || defined(CONFIG_CPU_EXYNOS4412)
#ifdef CONFIG_BUSFREQ_OPP
- if (id != CONFIG_FB_S5P_DEFAULT_WINDOW)
+ if (CONFIG_FB_S5P_DEFAULT_WINDOW == 3 &&
+ id == CONFIG_FB_S5P_DEFAULT_WINDOW-1)
+ dev_lock(fbdev->bus_dev, fbdev->dev, 267160);
+ else if (id != CONFIG_FB_S5P_DEFAULT_WINDOW)
dev_lock(fbdev->bus_dev, fbdev->dev, 133133);
#endif
#endif
@@ -394,6 +407,10 @@ int s3cfb_map_default_video_memory(struct s3cfb_global *fbdev,
memset(fb->screen_base, 0, fix->smem_len);
win->owner = DMA_MEM_FIMD;
+#ifdef CONFIG_FB_S5P_SYSMMU
+ fbdev->sysmmu.default_fb_addr = fix->smem_start;
+#endif
+
return 0;
}
@@ -457,11 +474,19 @@ int s3cfb_set_bitfield(struct fb_var_screeninfo *var)
break;
case 32:
+#if defined(CONFIG_FB_RGBA_ORDER)
+ var->red.offset = 0;
+#else
var->red.offset = 16;
+#endif
var->red.length = 8;
var->green.offset = 8;
var->green.length = 8;
+#if defined(CONFIG_FB_RGBA_ORDER)
+ var->blue.offset = 16;
+#else
var->blue.offset = 0;
+#endif
var->blue.length = 8;
var->transp.offset = 24;
var->transp.length = 8; /* added for LCD RGB32 */
@@ -1082,30 +1107,631 @@ int s3cfb_cursor(struct fb_info *fb, struct fb_cursor *cursor)
return 0;
}
-int s3cfb_vsync_timestamp_changed(struct s3cfb_global *fbdev, ktime_t prev_timestamp)
+#if !defined(CONFIG_FB_S5P_VSYNC_THREAD)
+int s3cfb_wait_for_vsync(struct s3cfb_global *fbdev)
{
- return !ktime_equal(prev_timestamp, fbdev->vsync_timestamp);
+ dev_dbg(fbdev->dev, "waiting for VSYNC interrupt\n");
+
+ sleep_on_timeout(&fbdev->wq, HZ / 10);
+
+ dev_dbg(fbdev->dev, "got a VSYNC interrupt\n");
+
+ return 0;
}
+#endif
-int s3cfb_wait_for_vsync(struct s3cfb_global *fbdev)
+
+/**
+ * s3c_fb_align_word() - align pixel count to word boundary
+ * @bpp: The number of bits per pixel
+ * @pix: The value to be aligned.
+ *
+ * Align the given pixel count so that it will start on an 32bit word
+ * boundary.
+ */
+static int s3c_fb_align_word(unsigned int bpp, unsigned int pix)
+{
+ int pix_per_word;
+
+ if (bpp > 16)
+ return pix;
+
+ pix_per_word = (8 * 32) / bpp;
+ return ALIGN(pix, pix_per_word);
+}
+
+static u32 s3c_fb_red_length(int format)
+{
+ switch (format) {
+ case S3C_FB_PIXEL_FORMAT_RGBA_8888:
+ case S3C_FB_PIXEL_FORMAT_RGBX_8888:
+ case S3C_FB_PIXEL_FORMAT_RGB_888:
+ case S3C_FB_PIXEL_FORMAT_BGRA_8888:
+ return 8;
+
+ case S3C_FB_PIXEL_FORMAT_RGB_565:
+ case S3C_FB_PIXEL_FORMAT_RGBA_5551:
+ return 5;
+
+ case S3C_FB_PIXEL_FORMAT_RGBA_4444:
+ return 4;
+
+ default:
+ pr_warn("s3c-fb: unrecognized pixel format %u\n", format);
+ return 0;
+ }
+}
+
+static u32 s3c_fb_red_offset(int format)
+{
+ switch (format) {
+ case S3C_FB_PIXEL_FORMAT_RGBA_8888:
+ case S3C_FB_PIXEL_FORMAT_RGBX_8888:
+ case S3C_FB_PIXEL_FORMAT_RGB_888:
+ case S3C_FB_PIXEL_FORMAT_RGB_565:
+ case S3C_FB_PIXEL_FORMAT_RGBA_5551:
+ case S3C_FB_PIXEL_FORMAT_RGBA_4444:
+ return 0;
+
+ case S3C_FB_PIXEL_FORMAT_BGRA_8888:
+ return 16;
+
+ default:
+ pr_warn("s3c-fb: unrecognized pixel format %u\n", format);
+ return 0;
+ }
+}
+
+static u32 s3c_fb_green_length(int format)
+{
+ if (format == S3C_FB_PIXEL_FORMAT_RGB_565)
+ return 6;
+
+ return s3c_fb_red_length(format);
+}
+
+static u32 s3c_fb_green_offset(int format)
+{
+ switch (format) {
+ case S3C_FB_PIXEL_FORMAT_RGBA_8888:
+ case S3C_FB_PIXEL_FORMAT_RGB_888:
+ case S3C_FB_PIXEL_FORMAT_BGRA_8888:
+ case S3C_FB_PIXEL_FORMAT_RGBX_8888:
+ return 8;
+
+ case S3C_FB_PIXEL_FORMAT_RGB_565:
+ case S3C_FB_PIXEL_FORMAT_RGBA_5551:
+ return 5;
+
+ case S3C_FB_PIXEL_FORMAT_RGBA_4444:
+ return 4;
+
+ default:
+ pr_warn("s3c-fb: unrecognized pixel format %u\n", format);
+ return 0;
+ }
+}
+
+static u32 s3c_fb_blue_length(int format)
+{
+ return s3c_fb_red_length(format);
+}
+
+static u32 s3c_fb_blue_offset(int format)
+{
+ switch (format) {
+ case S3C_FB_PIXEL_FORMAT_RGBA_8888:
+ case S3C_FB_PIXEL_FORMAT_RGB_888:
+ case S3C_FB_PIXEL_FORMAT_RGBX_8888:
+ return 16;
+
+ case S3C_FB_PIXEL_FORMAT_RGB_565:
+ return 11;
+
+ case S3C_FB_PIXEL_FORMAT_RGBA_5551:
+ return 10;
+
+ case S3C_FB_PIXEL_FORMAT_RGBA_4444:
+ return 8;
+
+ case S3C_FB_PIXEL_FORMAT_BGRA_8888:
+ return 0;
+
+ default:
+ pr_warn("s3c-fb: unrecognized pixel format %u\n", format);
+ return 0;
+ }
+}
+
+static u32 s3c_fb_transp_length(int format)
+{
+ switch (format) {
+ case S3C_FB_PIXEL_FORMAT_RGBA_8888:
+ case S3C_FB_PIXEL_FORMAT_BGRA_8888:
+ return 8;
+
+ case S3C_FB_PIXEL_FORMAT_RGBA_5551:
+ return 1;
+
+ case S3C_FB_PIXEL_FORMAT_RGBA_4444:
+ return 4;
+
+ case S3C_FB_PIXEL_FORMAT_RGB_888:
+ case S3C_FB_PIXEL_FORMAT_RGB_565:
+ case S3C_FB_PIXEL_FORMAT_RGBX_8888:
+ return 0;
+
+ default:
+ pr_warn("s3c-fb: unrecognized pixel format %u\n", format);
+ return 0;
+ }
+}
+
+static u32 s3c_fb_transp_offset(int format)
+{
+ switch (format) {
+ case S3C_FB_PIXEL_FORMAT_RGBA_8888:
+ case S3C_FB_PIXEL_FORMAT_BGRA_8888:
+ return 24;
+
+ case S3C_FB_PIXEL_FORMAT_RGBA_5551:
+ return 15;
+
+ case S3C_FB_PIXEL_FORMAT_RGBA_4444:
+ return 12;
+
+ case S3C_FB_PIXEL_FORMAT_RGB_888:
+ case S3C_FB_PIXEL_FORMAT_RGB_565:
+ case S3C_FB_PIXEL_FORMAT_RGBX_8888:
+ return s3c_fb_blue_offset(format);
+
+ default:
+ pr_warn("s3c-fb: unrecognized pixel format %u\n", format);
+ return 0;
+ }
+}
+
+static u32 s3c_fb_padding(int format)
+{
+ switch (format) {
+ case S3C_FB_PIXEL_FORMAT_RGBX_8888:
+ return 8;
+
+ case S3C_FB_PIXEL_FORMAT_RGB_565:
+ case S3C_FB_PIXEL_FORMAT_RGBA_8888:
+ case S3C_FB_PIXEL_FORMAT_RGBA_5551:
+ case S3C_FB_PIXEL_FORMAT_RGBA_4444:
+ return 0;
+
+ default:
+ pr_warn("s3c-fb: unrecognized pixel format %u\n", format);
+ return 0;
+ }
+
+}
+
+static inline u32 fb_visual(u32 bits_per_pixel, unsigned short palette_sz)
+{
+ switch (bits_per_pixel) {
+ case 32:
+ case 24:
+ case 16:
+ case 12:
+ return FB_VISUAL_TRUECOLOR;
+ case 8:
+ if (palette_sz >= 256)
+ return FB_VISUAL_PSEUDOCOLOR;
+ else
+ return FB_VISUAL_TRUECOLOR;
+ case 1:
+ return FB_VISUAL_MONO01;
+ default:
+ return FB_VISUAL_PSEUDOCOLOR;
+ }
+}
+
+
+static inline u32 fb_linelength(u32 xres_virtual, u32 bits_per_pixel)
+{
+ return (xres_virtual * bits_per_pixel) / 8;
+}
+
+static inline u16 fb_panstep(u32 res, u32 res_virtual)
+{
+ return res_virtual > res ? 1 : 0;
+}
+
+static inline u32 vidw_buf_size(u32 xres, u32 line_length, u32 bits_per_pixel)
+{
+ u32 pagewidth = (xres * bits_per_pixel) >> 3;
+ return VIDW_BUF_SIZE_OFFSET(line_length - pagewidth) |
+ VIDW_BUF_SIZE_PAGEWIDTH(pagewidth) |
+ VIDW_BUF_SIZE_OFFSET_E(line_length - pagewidth) |
+ VIDW_BUF_SIZE_PAGEWIDTH_E(pagewidth);
+}
+
+inline u32 vidosd_a(int x, int y)
+{
+ return VIDOSDxA_TOPLEFT_X(x) |
+ VIDOSDxA_TOPLEFT_Y(y) |
+ VIDOSDxA_TOPLEFT_X_E(x) |
+ VIDOSDxA_TOPLEFT_Y_E(y);
+}
+
+inline u32 vidosd_b(int x, int y, u32 xres, u32 yres, u32 bits_per_pixel)
+{
+ return VIDOSDxB_BOTRIGHT_X(s3c_fb_align_word(bits_per_pixel,
+ x + xres - 1)) |
+ VIDOSDxB_BOTRIGHT_Y(y + yres - 1) |
+ VIDOSDxB_BOTRIGHT_X_E(s3c_fb_align_word(bits_per_pixel,
+ x + xres - 1)) |
+ VIDOSDxB_BOTRIGHT_Y_E(y + yres - 1);
+}
+
+static inline u32 wincon(u32 bits_per_pixel, u32 transp_length, u32 red_length)
+{
+ u32 data = 0;
+
+ switch (bits_per_pixel) {
+ case 1:
+ data |= WINCON0_BPPMODE_1BPP;
+ data |= WINCONx_BITSWP;
+ data |= WINCONx_BURSTLEN_4WORD;
+ break;
+ case 2:
+ data |= WINCON0_BPPMODE_2BPP;
+ data |= WINCONx_BITSWP;
+ data |= WINCONx_BURSTLEN_8WORD;
+ break;
+ case 4:
+ data |= WINCON0_BPPMODE_4BPP;
+ data |= WINCONx_BITSWP;
+ data |= WINCONx_BURSTLEN_8WORD;
+ break;
+ case 8:
+ if (transp_length != 0)
+ data |= WINCON1_BPPMODE_8BPP_1232;
+ else
+ data |= WINCON0_BPPMODE_8BPP_PALETTE;
+ data |= WINCONx_BURSTLEN_8WORD;
+ data |= WINCONx_BYTSWP;
+ break;
+ case 16:
+ if (transp_length != 0)
+ data |= WINCON1_BPPMODE_16BPP_A1555;
+ else
+ data |= WINCON0_BPPMODE_16BPP_565;
+ data |= WINCONx_HAWSWP;
+ data |= WINCONx_BURSTLEN_16WORD;
+ break;
+ case 24:
+ case 32:
+ if (red_length == 6) {
+ if (transp_length != 0)
+ data |= WINCON1_BPPMODE_19BPP_A1666;
+ else
+ data |= WINCON1_BPPMODE_18BPP_666;
+ } else if (transp_length == 1)
+ data |= WINCON1_BPPMODE_25BPP_A1888
+ | WINCON1_BLD_PIX;
+ else if ((transp_length == 4) ||
+ (transp_length == 8))
+ data |= WINCON1_BPPMODE_28BPP_A4888
+ | WINCON1_BLD_PIX | WINCON1_ALPHA_SEL;
+ else
+ data |= WINCON0_BPPMODE_24BPP_888;
+
+ data |= WINCONx_WSWP;
+ data |= WINCONx_BURSTLEN_16WORD;
+ break;
+ }
+
+ return data;
+}
+
+void s3c_fb_update_regs(struct s3cfb_global *fbdev, struct s3c_reg_data *regs)
{
- ktime_t prev_timestamp;
+ struct s3c_platform_fb *pdata = to_fb_plat(fbdev->dev);
+ unsigned short i;
+ bool wait_for_vsync;
+ struct s3cfb_window *win;
+
+#if defined(CONFIG_CPU_EXYNOS4212) || defined(CONFIG_CPU_EXYNOS4412)
+#ifdef CONFIG_BUSFREQ_OPP
+ unsigned int new_num_of_win = 0;
+ unsigned int pre_num_of_win = 0;
+ unsigned int shadow_regs = 0;
+ unsigned int clkval = 0;
+
+ for (i = 0; i < pdata->nr_wins; i++)
+ if (regs->shadowcon & SHADOWCON_CHx_ENABLE(i))
+ new_num_of_win++;
+ shadow_regs = readl(fbdev->regs + S3C_WINSHMAP);
+ for (i = 0; i < pdata->nr_wins; i++)
+ if (shadow_regs & SHADOWCON_CHx_ENABLE(i))
+ pre_num_of_win++;
+
+ if (pre_num_of_win < new_num_of_win) {
+ switch(new_num_of_win) {
+ case 0:
+ case 1:
+ clkval = 100100;
+ break;
+ case 2:
+ clkval = 133133;
+ break;
+ case 3:
+ clkval = 133133;
+ break;
+ case 4:
+ clkval = 133133;
+ break;
+ case 5:
+ clkval = 133133;
+ break;
+ }
+ dev_lock(fbdev->bus_dev, fbdev->dev, clkval);
+ }
+#endif
+#endif
+
+ for (i = 0; i < pdata->nr_wins; i++)
+ s3cfb_set_window_protect(fbdev, i, 1);
+
+ for (i = 0; i < pdata->nr_wins; i++) {
+ win = fbdev->fb[i]->par;
+ writel(regs->wincon[i], fbdev->regs + S3C_WINCON(i));
+ writel(regs->vidosd_a[i], fbdev->regs + S3C_VIDOSD_A(i));
+ writel(regs->vidosd_b[i], fbdev->regs + S3C_VIDOSD_B(i));
+ writel(regs->vidosd_c[i], fbdev->regs + S3C_VIDOSD_C(i));
+ if (i == 1 || i == 2)
+ writel(regs->vidosd_d[i], fbdev->regs + S3C_VIDOSD_D(i));
+ writel(regs->vidw_buf_start[i],
+ fbdev->regs + S3C_VIDADDR_START0(i));
+ writel(regs->vidw_buf_end[i],
+ fbdev->regs + S3C_VIDADDR_END0(i));
+ writel(regs->vidw_buf_size[i],
+ fbdev->regs + S3C_VIDADDR_SIZE(i));
+
+ win->enabled = !!(regs->wincon[i] & WINCONx_ENWIN);
+ }
+
+ writel(regs->shadowcon, fbdev->regs + S3C_WINSHMAP);
+
+ for (i = 0; i < pdata->nr_wins; i++)
+ s3cfb_set_window_protect(fbdev, i, 0);
+
+ do {
+#if defined(CONFIG_FB_S5P_VSYNC_THREAD)
+ s3cfb_wait_for_vsync(fbdev, 0);
+#else
+ s3cfb_wait_for_vsync(fbdev);
+#endif
+ wait_for_vsync = false;
+
+ for (i = 0; i < pdata->nr_wins; i++) {
+ u32 new_start = regs->vidw_buf_start[i];
+ u32 shadow_start = s3cfb_get_win_cur_buf_addr(fbdev, i);
+ if (unlikely(new_start != shadow_start)) {
+ wait_for_vsync = true;
+ break;
+ }
+ }
+ } while (wait_for_vsync);
+
+ sw_sync_timeline_inc(fbdev->timeline, 1);
+
+#ifdef CONFIG_FB_S5P_SYSMMU
+ if ((fbdev->sysmmu.enabled == false) &&
+ (fbdev->sysmmu.pgd)) {
+ fbdev->sysmmu.enabled = true;
+ s5p_sysmmu_enable(fbdev->dev,
+ (unsigned long)virt_to_phys((unsigned int*)fbdev->sysmmu.pgd));
+ }
+#endif
+
+#if defined(CONFIG_CPU_EXYNOS4212) || defined(CONFIG_CPU_EXYNOS4412)
+#ifdef CONFIG_BUSFREQ_OPP
+ if (pre_num_of_win > new_num_of_win) {
+ switch(new_num_of_win) {
+ case 0:
+ case 1:
+ clkval = 100100;
+ break;
+ case 2:
+ clkval = 133133;
+ break;
+ case 3:
+ clkval = 133133;
+ break;
+ case 4:
+ clkval = 133133;
+ break;
+ case 5:
+ clkval = 133133;
+ break;
+ }
+ dev_lock(fbdev->bus_dev, fbdev->dev, clkval);
+ }
+#endif
+#endif
+}
+
+static int s3c_fb_set_win_buffer(struct s3cfb_global *fbdev,
+ struct fb_info *fb, struct s3c_fb_win_config *win_config,
+ struct s3c_reg_data *regs)
+{
+ struct s3cfb_window *win = fb->par;
+ struct fb_fix_screeninfo prev_fix = fb->fix;
+ struct fb_var_screeninfo prev_var = fb->var;
+ unsigned short win_no = win->id;
int ret;
+ size_t window_size;
+ u32 alpha, size;
- dev_dbg(fbdev->dev, "waiting for VSYNC interrupt\n");
+ if (win_config->format >= S3C_FB_PIXEL_FORMAT_MAX) {
+ dev_err(fbdev->dev, "unknown pixel format %u\n",
+ win_config->format);
+ return -EINVAL;
+ }
- prev_timestamp = fbdev->vsync_timestamp;
+ fb->var.red.length = s3c_fb_red_length(win_config->format);
+ fb->var.red.offset = s3c_fb_red_offset(win_config->format);
+ fb->var.green.length = s3c_fb_green_length(win_config->format);
+ fb->var.green.offset = s3c_fb_green_offset(win_config->format);
+ fb->var.blue.length = s3c_fb_blue_length(win_config->format);
+ fb->var.blue.offset = s3c_fb_blue_offset(win_config->format);
+ fb->var.transp.length = s3c_fb_transp_length(win_config->format);
+ fb->var.transp.offset = s3c_fb_transp_offset(win_config->format);
+ fb->var.bits_per_pixel = fb->var.red.length +
+ fb->var.green.length +
+ fb->var.blue.length +
+ fb->var.transp.length +
+ s3c_fb_padding(win_config->format);
+
+ window_size = win_config->stride * win_config->h;
+
+ if (win_config->phys_addr != 0)
+ fb->fix.smem_start = win_config->phys_addr + win_config->offset;
+ else
+ fb->fix.smem_start = win_config->virt_addr + win_config->offset;
+ fb->fix.smem_len = window_size;
+ fb->var.xres = win_config->w;
+ fb->var.xres_virtual = win_config->stride * 8 /
+ fb->var.bits_per_pixel;
+ fb->var.yres = fb->var.yres_virtual = win_config->h;
+ fb->var.xoffset = win_config->offset % win_config->stride;
+ fb->var.yoffset = win_config->offset / win_config->stride;
+
+ fb->fix.visual = fb_visual(fb->var.bits_per_pixel, 256);
+ fb->fix.line_length = win_config->stride;
+ fb->fix.xpanstep = fb_panstep(win_config->w,
+ fb->var.xres_virtual);
+ fb->fix.ypanstep = fb_panstep(win_config->h, win_config->h);
+
+#ifdef CONFIG_FB_S5P_SYSMMU
+ if ((fbdev->sysmmu.enabled == false) &&
+ (current->mm))
+ fbdev->sysmmu.pgd = (unsigned int)current->mm->pgd;
+#endif
- ret = wait_event_interruptible_timeout(fbdev->wq,
- s3cfb_vsync_timestamp_changed(fbdev, prev_timestamp),
- msecs_to_jiffies(100));
+#ifdef CONFIG_FB_S5P_SYSMMU
+ if (win_config->phys_addr != 0)
+ regs->vidw_buf_start[win_no] = (u32)phys_to_virt(fb->fix.smem_start);
+ else
+#endif
+ regs->vidw_buf_start[win_no] = fb->fix.smem_start;
- if (ret == 0)
- return -ETIMEDOUT;
- if (ret < 0)
- return ret;
+ regs->vidw_buf_end[win_no] = regs->vidw_buf_start[win_no] +
+ window_size;
- dev_dbg(fbdev->dev, "got a VSYNC interrupt\n");
+ regs->vidw_buf_size[win_no] = vidw_buf_size(win_config->w,
+ fb->fix.line_length,
+ fb->var.bits_per_pixel);
+
+#ifdef CONFIG_FB_S5P_SYSMMU
+ if ((fb->fix.smem_start) &&
+ (fb->fix.smem_start != fbdev->sysmmu.default_fb_addr))
+ s3cfb_clean_outer_pagetable(regs->vidw_buf_start[win_no],
+ regs->vidw_buf_end[win_no] - regs->vidw_buf_start[win_no]);
+#endif
+
+
+ regs->vidosd_a[win_no] = vidosd_a(win_config->x, win_config->y);
+ regs->vidosd_b[win_no] = vidosd_b(win_config->x, win_config->y,
+ win_config->w, win_config->h,
+ fb->var.bits_per_pixel);
+
+ alpha = VIDISD14C_ALPHA1_R(0xf) |
+ VIDISD14C_ALPHA1_G(0xf) |
+ VIDISD14C_ALPHA1_B(0xf);
+ regs->vidosd_c[win_no] = alpha;
+
+ if (win_no <= 2) {
+ size = win_config->w * win_config->h;
+ regs->vidosd_d[win_no] = size;
+ }
+
+ regs->shadowcon |= SHADOWCON_CHx_ENABLE(win_no);
+
+ regs->wincon[win_no] = wincon(fb->var.bits_per_pixel,
+ fb->var.transp.length,
+ fb->var.red.length);
+
+ return 0;
+}
+
+static int s3c_fb_set_win_config(struct s3cfb_global *fbdev,
+ struct s3c_fb_win_config_data *win_data)
+{
+ struct fb_info *fb;
+ struct s3c_platform_fb *pdata = to_fb_plat(fbdev->dev);
+ struct s3c_fb_win_config *win_config = win_data->config;
+ int ret = 0;
+ unsigned short i;
+ struct s3c_reg_data *regs = kzalloc(sizeof(struct s3c_reg_data),
+ GFP_KERNEL);
+ struct sync_fence *fence;
+ struct sync_pt *pt;
+ int fd;
+
+ if (!regs) {
+ dev_err(fbdev->dev, "could not allocate s3c_reg_data");
+ return -ENOMEM;
+ }
+
+ fd = get_unused_fd();
+
+ for (i = 0; i < pdata->nr_wins && !ret; i++) {
+ struct s3c_fb_win_config *config = &win_config[i];
+ bool enabled = 0;
+ u32 color_map = WINxMAP_MAP | WINxMAP_MAP_COLOUR(0);
+
+ fb = fbdev->fb[i];
+
+ switch (config->state) {
+ case S3C_FB_WIN_STATE_DISABLED:
+ break;
+ case S3C_FB_WIN_STATE_COLOR:
+ enabled = 1;
+ color_map |= WINxMAP_MAP_COLOUR(config->color);
+ break;
+ case S3C_FB_WIN_STATE_BUFFER:
+ ret = s3c_fb_set_win_buffer(fbdev, fb, config, regs);
+ if (!ret) {
+ enabled = 1;
+ color_map = 0;
+ }
+ break;
+ default:
+ dev_warn(fbdev->dev, "unrecognized window state %u",
+ config->state);
+ ret = -EINVAL;
+ break;
+ }
+
+ if (enabled)
+ regs->wincon[i] |= WINCONx_ENWIN;
+ else
+ regs->wincon[i] &= ~WINCONx_ENWIN;
+ regs->winmap[i] = color_map;
+ }
+
+ if (ret) {
+ put_unused_fd(fd);
+ kfree(regs);
+ } else {
+ mutex_lock(&fbdev->update_regs_list_lock);
+ fbdev->timeline_max++;
+ pt = sw_sync_pt_create(fbdev->timeline, fbdev->timeline_max);
+ fence = sync_fence_create("display", pt);
+ sync_fence_install(fence, fd);
+ win_data->fence = fd;
+
+ list_add_tail(&regs->list, &fbdev->update_regs_list);
+ mutex_unlock(&fbdev->update_regs_list_lock);
+ queue_kthread_work(&fbdev->update_regs_worker, &fbdev->update_regs_work);
+ }
return ret;
}
@@ -1128,6 +1754,7 @@ int s3cfb_ioctl(struct fb_info *fb, unsigned int cmd, unsigned long arg)
struct s3cfb_user_window user_window;
struct s3cfb_user_plane_alpha user_alpha;
struct s3cfb_user_chroma user_chroma;
+ struct s3c_fb_win_config_data win_data;
int vsync;
unsigned int alpha_mode;
} p;
@@ -1149,23 +1776,31 @@ int s3cfb_ioctl(struct fb_info *fb, unsigned int cmd, unsigned long arg)
if (fbdev->regs == 0)
return 0;
#if defined(CONFIG_CPU_EXYNOS4212) || defined(CONFIG_CPU_EXYNOS4412)
- /* Enable Vsync */
#ifdef CONFIG_CPU_EXYNOS4412
if (!fbdev->regs)
return ret;
#endif
+#if !defined(CONFIG_FB_S5P_VSYNC_THREAD)
+ /* Enable Vsync */
s3cfb_set_global_interrupt(fbdev, 1);
s3cfb_set_vsync_interrupt(fbdev, 1);
#endif
+#endif
/* Wait for Vsync */
+#if defined(CONFIG_FB_S5P_VSYNC_THREAD)
+ s3cfb_wait_for_vsync(fbdev, HZ/10);
+#else
s3cfb_wait_for_vsync(fbdev);
+#endif
if (fbdev->regs == 0)
return 0;
#if defined(CONFIG_CPU_EXYNOS4212) || defined(CONFIG_CPU_EXYNOS4412)
+#if !defined(CONFIG_FB_S5P_VSYNC_THREAD)
/* Disable Vsync */
s3cfb_set_global_interrupt(fbdev, 0);
s3cfb_set_vsync_interrupt(fbdev, 0);
#endif
+#endif
break;
case S3CFB_WIN_POSITION:
@@ -1238,8 +1873,12 @@ int s3cfb_ioctl(struct fb_info *fb, unsigned int cmd, unsigned long arg)
if (!fbdev->regs)
return ret;
#endif
+#if defined(CONFIG_FB_S5P_VSYNC_THREAD)
+ ret = s3cfb_set_vsync_int(fb, p.vsync);
+#else
s3cfb_set_global_interrupt(fbdev, p.vsync);
s3cfb_set_vsync_interrupt(fbdev, p.vsync);
+#endif
}
break;
@@ -1293,7 +1932,30 @@ int s3cfb_ioctl(struct fb_info *fb, unsigned int cmd, unsigned long arg)
else
s3cfb_set_alpha_mode(fbdev, win->id, p.alpha_mode);
break;
+
+#if defined(CONFIG_CPU_EXYNOS4212) || defined(CONFIG_CPU_EXYNOS4412)
+ case S3CFB_WIN_CONFIG:
+ if (copy_from_user(&p.win_data,
+ (struct s3c_fb_win_config_data __user *)arg,
+ sizeof(p.win_data))) {
+ ret = -EFAULT;
+ break;
+ }
+
+ ret = s3c_fb_set_win_config(fbdev, &p.win_data);
+ if (ret)
+ break;
+
+ if (copy_to_user((struct s3c_fb_win_config_data __user *)arg,
+ &p.win_data,
+ sizeof(p.win_data))) {
+ ret = -EFAULT;
+ break;
+ }
+ break;
+#endif
}
+
return ret;
}
diff --git a/drivers/video/samsung/s3cfb_s6c1372.c b/drivers/video/samsung/s3cfb_s6c1372.c
index 46c35ca..4d23708 100644
--- a/drivers/video/samsung/s3cfb_s6c1372.c
+++ b/drivers/video/samsung/s3cfb_s6c1372.c
@@ -83,8 +83,18 @@ static DEVICE_ATTR(lcd_type, 0664, lcdtype_show, NULL);
void s5c1372_ldi_enable(void)
{
+#if defined(CONFIG_FB_S5P_S6C1372)
+ gpio_set_value(GPIO_LCD_EN, GPIO_LEVEL_HIGH);
+ msleep(40);
+#else /* defined(CONFIG_FB_S5P_S6F1202A ) */
gpio_set_value(GPIO_LCD_EN, GPIO_LEVEL_HIGH);
+ gpio_set_value(GPIO_LCD_LDO_EN, GPIO_LEVEL_HIGH);
msleep(40);
+
+ /* Enable backlight PWM GPIO for P2 device. */
+ gpio_set_value(GPIO_LCD_BACKLIGHT_PWM, 0);
+ s3c_gpio_cfgpin(GPIO_LCD_BACKLIGHT_PWM, S3C_GPIO_SFN(3));
+#endif
}
void s5c1372_ldi_disable(void)
@@ -93,12 +103,21 @@ void s5c1372_ldi_disable(void)
s3c_gpio_cfgpin(GPIO_LCD_PCLK, S3C_GPIO_OUTPUT);
s3c_gpio_setpull(GPIO_LCD_PCLK, S3C_GPIO_PULL_NONE);
gpio_set_value(GPIO_LCD_PCLK, GPIO_LEVEL_LOW);
-#endif
msleep(40);
gpio_set_value(GPIO_LCD_EN, GPIO_LEVEL_LOW);
msleep(600);
+#else /* defined(CONFIG_FB_S5P_S6F1202A ) */
+ /* Disable backlight PWM GPIO for P2 device. */
+ gpio_set_value(GPIO_LCD_BACKLIGHT_PWM, GPIO_LEVEL_LOW);
+ s3c_gpio_cfgpin(GPIO_LCD_BACKLIGHT_PWM, S3C_GPIO_OUTPUT);
+
+ /* Disable LVDS Panel Power, 1.2, 1.8, display 3.3V */
+ gpio_set_value(GPIO_LCD_LDO_EN, GPIO_LEVEL_LOW);
+ gpio_set_value(GPIO_LCD_EN, GPIO_LEVEL_LOW);
+ msleep(300);
+#endif
}
static int __init s6c1372_probe(struct platform_device *pdev)
diff --git a/drivers/video/samsung/s3cfb_s6e39a0.c b/drivers/video/samsung/s3cfb_s6e39a0.c
index 3d0f534..a07e455 100644
--- a/drivers/video/samsung/s3cfb_s6e39a0.c
+++ b/drivers/video/samsung/s3cfb_s6e39a0.c
@@ -110,7 +110,10 @@ struct lcd_info {
struct dsim_global *dsim;
};
-static int s6e8ax0_write(struct lcd_info *lcd, const unsigned char *seq, int len)
+extern void (*lcd_early_suspend)(void);
+extern void (*lcd_late_resume)(void);
+
+static int s6e39a0_write(struct lcd_info *lcd, const unsigned char *seq, int len)
{
int size;
const unsigned char *wbuf;
@@ -135,7 +138,7 @@ static int s6e8ax0_write(struct lcd_info *lcd, const unsigned char *seq, int len
return 0;
}
-static int s6e8ax0_read(struct lcd_info *lcd, const u8 addr, u16 count, u8 *buf)
+static int s6e39a0_read(struct lcd_info *lcd, const u8 addr, u16 count, u8 *buf)
{
int ret = 0;
@@ -245,69 +248,69 @@ static int get_backlight_level_from_brightness(int brightness)
return backlightlevel;
}
-static int s6e8ax0_set_acl(struct lcd_info *lcd)
+static int s6e39a0_set_acl(struct lcd_info *lcd)
{
if (lcd->acl_enable) {
if (lcd->cur_acl == 0) {
if (lcd->bl == 0 || lcd->bl == 1) {
- s6e8ax0_write(lcd, SEQ_ACL_OFF, ARRAY_SIZE(SEQ_ACL_OFF));
+ s6e39a0_write(lcd, SEQ_ACL_OFF, ARRAY_SIZE(SEQ_ACL_OFF));
dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d\n", __func__, lcd->cur_acl);
} else
- s6e8ax0_write(lcd, SEQ_ACL_ON, ARRAY_SIZE(SEQ_ACL_ON));
+ s6e39a0_write(lcd, SEQ_ACL_ON, ARRAY_SIZE(SEQ_ACL_ON));
}
switch (lcd->bl) {
case 0 ... 1: /* 30cd ~ 40cd - 0%*/
if (lcd->cur_acl != 0) {
- s6e8ax0_write(lcd, SEQ_ACL_OFF, ARRAY_SIZE(SEQ_ACL_OFF));
+ s6e39a0_write(lcd, SEQ_ACL_OFF, ARRAY_SIZE(SEQ_ACL_OFF));
lcd->cur_acl = 0;
dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d\n", __func__, lcd->cur_acl);
}
break;
case 2 ... 12: /* 70cd ~ 180cd -40%*/
if (lcd->cur_acl != 40) {
- s6e8ax0_write(lcd, acl_cutoff_table[1], ACL_PARAM_SIZE);
+ s6e39a0_write(lcd, acl_cutoff_table[1], ACL_PARAM_SIZE);
lcd->cur_acl = 40;
dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d\n", __func__, lcd->cur_acl);
}
break;
case 13: /* 190cd - 43% */
if (lcd->cur_acl != 43) {
- s6e8ax0_write(lcd, acl_cutoff_table[2], ACL_PARAM_SIZE);
+ s6e39a0_write(lcd, acl_cutoff_table[2], ACL_PARAM_SIZE);
lcd->cur_acl = 43;
dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d\n", __func__, lcd->cur_acl);
}
break;
case 14: /* 200cd - 45% */
if (lcd->cur_acl != 45) {
- s6e8ax0_write(lcd, acl_cutoff_table[3], ACL_PARAM_SIZE);
+ s6e39a0_write(lcd, acl_cutoff_table[3], ACL_PARAM_SIZE);
lcd->cur_acl = 45;
dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d\n", __func__, lcd->cur_acl);
}
break;
case 15: /* 210cd - 47% */
if (lcd->cur_acl != 47) {
- s6e8ax0_write(lcd, acl_cutoff_table[4], ACL_PARAM_SIZE);
+ s6e39a0_write(lcd, acl_cutoff_table[4], ACL_PARAM_SIZE);
lcd->cur_acl = 47;
dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d\n", __func__, lcd->cur_acl);
}
break;
case 16: /* 220cd - 48% */
if (lcd->cur_acl != 48) {
- s6e8ax0_write(lcd, acl_cutoff_table[5], ACL_PARAM_SIZE);
+ s6e39a0_write(lcd, acl_cutoff_table[5], ACL_PARAM_SIZE);
lcd->cur_acl = 48;
dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d\n", __func__, lcd->cur_acl);
}
break;
default:
if (lcd->cur_acl != 50) {
- s6e8ax0_write(lcd, acl_cutoff_table[6], ACL_PARAM_SIZE);
+ s6e39a0_write(lcd, acl_cutoff_table[6], ACL_PARAM_SIZE);
lcd->cur_acl = 50;
dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d\n", __func__, lcd->cur_acl);
}
break;
}
} else {
- s6e8ax0_write(lcd, SEQ_ACL_OFF, ARRAY_SIZE(SEQ_ACL_OFF));
+ s6e39a0_write(lcd, SEQ_ACL_OFF, ARRAY_SIZE(SEQ_ACL_OFF));
lcd->cur_acl = 0;
dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d\n", __func__, lcd->cur_acl);
}
@@ -316,12 +319,12 @@ static int s6e8ax0_set_acl(struct lcd_info *lcd)
}
#ifndef SMART_DIMMING
-static int s6e8ax0_gamma_ctl(struct lcd_info *lcd)
+static int s6e39a0_gamma_ctl(struct lcd_info *lcd)
{
- s6e8ax0_write(lcd, gamma22_table[lcd->bl], GAMMA_PARAM_SIZE);
+ s6e39a0_write(lcd, gamma22_table[lcd->bl], GAMMA_PARAM_SIZE);
/* Gamma Set Update */
- s6e8ax0_write(lcd, SEQ_GAMMA_UPDATE, ARRAY_SIZE(SEQ_GAMMA_UPDATE));
+ s6e39a0_write(lcd, SEQ_GAMMA_UPDATE, ARRAY_SIZE(SEQ_GAMMA_UPDATE));
lcd->current_bl = lcd->bl;
@@ -332,20 +335,21 @@ static int update_brightness(struct lcd_info *lcd)
{
int ret;
-#if defined(CONFIG_MACH_C1) || defined(CONFIG_MACH_C1VZW) || \
+#if defined(CONFIG_MACH_C1) || \
+ defined(CONFIG_MACH_M3) || \
defined(CONFIG_MACH_M0) || defined(CONFIG_MACH_SLP_PQ) || \
- defined(CONFIG_MACH_SLP_PQ_LTE) || defined(CONFIG_MACH_M3)
+ defined(CONFIG_MACH_SLP_PQ_LTE)
#else
- ret = s6e8ax0_gamma_ctl(lcd);
+ ret = s6e39a0_gamma_ctl(lcd);
if (ret)
return -EPERM;
/*
- ret = s6e8ax0_set_elvss(lcd);
+ ret = s6e39a0_set_elvss(lcd);
if (ret)
return -EPERM;
- ret = s6e8ax0_set_acl(lcd);
+ ret = s6e39a0_set_acl(lcd);
if (ret)
return -EPERM;
*/
@@ -356,13 +360,13 @@ static int update_brightness(struct lcd_info *lcd)
#endif
#ifdef SMART_DIMMING
-static int s6e8ax0_read_mtp(struct lcd_info *lcd, u8 *mtp_data)
+static int s6e39a0_read_mtp(struct lcd_info *lcd, u8 *mtp_data)
{
int ret;
u8 retry_cnt = 3;
read_retry:
- ret = s6e8ax0_read(lcd, LDI_MTP_ADDR, LDI_MTP_LENGTH, mtp_data);
+ ret = s6e39a0_read(lcd, LDI_MTP_ADDR, LDI_MTP_LENGTH, mtp_data);
if (!ret) {
if (retry_cnt) {
printk(KERN_WARNING "[WARN:LCD] : %s : retry cnt : %d\n", __func__, retry_cnt);
@@ -481,9 +485,9 @@ static int s6e8aa0_update_brightness(struct lcd_info *lcd, u32 brightness)
calc_gamma_table(&lcd->smart, gamma, gamma_regs+2);
- s6e8ax0_write(lcd, gamma_regs, GAMMA_PARAM_SIZE);
+ s6e39a0_write(lcd, gamma_regs, GAMMA_PARAM_SIZE);
- s6e8ax0_write(lcd, SEQ_GAMMA_UPDATE, sizeof(SEQ_GAMMA_UPDATE));
+ s6e39a0_write(lcd, SEQ_GAMMA_UPDATE, sizeof(SEQ_GAMMA_UPDATE));
#if 0
printk(KERN_INFO "##### print gamma reg #####\n");
@@ -553,12 +557,12 @@ static int s6e8aa0_update_elvss(struct lcd_info *lcd, u32 candela)
elvss_cmd[2] = elvss;
printk(KERN_DEBUG "elvss reg : %02x\n", elvss_cmd[2]);
- s6e8ax0_write(lcd, elvss_cmd, sizeof(elvss_cmd));
+ s6e39a0_write(lcd, elvss_cmd, sizeof(elvss_cmd));
return 0;
}
-static int s6e8ax0_adb_brightness_update(struct lcd_info *lcd, u32 br, u32 force)
+static int s6e39a0_adb_brightness_update(struct lcd_info *lcd, u32 br, u32 force)
{
u32 gamma;
int ret = 0;
@@ -572,7 +576,7 @@ static int s6e8ax0_adb_brightness_update(struct lcd_info *lcd, u32 br, u32 force
ret = s6e8aa0_update_brightness(lcd, gamma);
- ret = s6e8ax0_set_acl(lcd);
+ ret = s6e39a0_set_acl(lcd);
if (lcd->support_elvss)
ret = s6e8aa0_update_elvss(lcd, gamma);
@@ -587,82 +591,82 @@ static int s6e8ax0_adb_brightness_update(struct lcd_info *lcd, u32 br, u32 force
}
#endif
-static int s6e8ax0_ldi_init(struct lcd_info *lcd)
+static int s6e39a0_ldi_init(struct lcd_info *lcd)
{
int ret = 0;
- s6e8ax0_write(lcd, SEQ_APPLY_LEVEL_2_KEY, \
+ s6e39a0_write(lcd, SEQ_APPLY_LEVEL_2_KEY, \
ARRAY_SIZE(SEQ_APPLY_LEVEL_2_KEY));
- s6e8ax0_write(lcd, SEQ_APPLY_LEVEL_3_KEY, \
+ s6e39a0_write(lcd, SEQ_APPLY_LEVEL_3_KEY, \
ARRAY_SIZE(SEQ_APPLY_LEVEL_3_KEY));
- s6e8ax0_write(lcd, SEQ_APPLY_LEVEL_4_KEY, \
+ s6e39a0_write(lcd, SEQ_APPLY_LEVEL_4_KEY, \
ARRAY_SIZE(SEQ_APPLY_LEVEL_4_KEY));
- s6e8ax0_write(lcd, SEQ_GAMMA_CONDITION_SET, \
+ s6e39a0_write(lcd, SEQ_GAMMA_CONDITION_SET, \
ARRAY_SIZE(SEQ_GAMMA_CONDITION_SET));
- s6e8ax0_write(lcd, SEQ_GAMMA_UPDATE,\
+ s6e39a0_write(lcd, SEQ_GAMMA_UPDATE,\
ARRAY_SIZE(SEQ_GAMMA_UPDATE));
- s6e8ax0_write(lcd, SEQ_PANEL_CONDITION_SET, \
+ s6e39a0_write(lcd, SEQ_PANEL_CONDITION_SET, \
ARRAY_SIZE(SEQ_PANEL_CONDITION_SET));
- s6e8ax0_write(lcd, SEQ_ETC_CONDITION_SET_2_0, \
+ s6e39a0_write(lcd, SEQ_ETC_CONDITION_SET_2_0, \
ARRAY_SIZE(SEQ_ETC_CONDITION_SET_2_0));
- s6e8ax0_write(lcd, SEQ_ETC_CONDITION_SET_2_1, \
+ s6e39a0_write(lcd, SEQ_ETC_CONDITION_SET_2_1, \
ARRAY_SIZE(SEQ_ETC_CONDITION_SET_2_1));
- s6e8ax0_write(lcd, SEQ_ETC_CONDITION_SET_2_2, \
+ s6e39a0_write(lcd, SEQ_ETC_CONDITION_SET_2_2, \
ARRAY_SIZE(SEQ_ETC_CONDITION_SET_2_2));
- s6e8ax0_write(lcd, SEQ_ETC_CONDITION_SET_2_3, \
+ s6e39a0_write(lcd, SEQ_ETC_CONDITION_SET_2_3, \
ARRAY_SIZE(SEQ_ETC_CONDITION_SET_2_3));
- s6e8ax0_write(lcd, SEQ_ETC_CONDITION_SET_2_4, \
+ s6e39a0_write(lcd, SEQ_ETC_CONDITION_SET_2_4, \
ARRAY_SIZE(SEQ_ETC_CONDITION_SET_2_4));
- s6e8ax0_write(lcd, SEQ_ETC_CONDITION_SET_2_5, \
+ s6e39a0_write(lcd, SEQ_ETC_CONDITION_SET_2_5, \
ARRAY_SIZE(SEQ_ETC_CONDITION_SET_2_5));
- s6e8ax0_write(lcd, SEQ_ETC_CONDITION_SET_2_6, \
+ s6e39a0_write(lcd, SEQ_ETC_CONDITION_SET_2_6, \
ARRAY_SIZE(SEQ_ETC_CONDITION_SET_2_6));
- s6e8ax0_write(lcd, SEQ_ETC_CONDITION_SET_2_7, \
+ s6e39a0_write(lcd, SEQ_ETC_CONDITION_SET_2_7, \
ARRAY_SIZE(SEQ_ETC_CONDITION_SET_2_7));
- s6e8ax0_write(lcd, SEQ_ETC_CONDITION_SET_2_8, \
+ s6e39a0_write(lcd, SEQ_ETC_CONDITION_SET_2_8, \
ARRAY_SIZE(SEQ_ETC_CONDITION_SET_2_8));
- s6e8ax0_write(lcd, SEQ_ETC_CONDITION_SET_2_9, \
+ s6e39a0_write(lcd, SEQ_ETC_CONDITION_SET_2_9, \
ARRAY_SIZE(SEQ_ETC_CONDITION_SET_2_9));
- s6e8ax0_write(lcd, SEQ_ETC_CONDITION_SET_2_10, \
+ s6e39a0_write(lcd, SEQ_ETC_CONDITION_SET_2_10, \
ARRAY_SIZE(SEQ_ETC_CONDITION_SET_2_10));
- s6e8ax0_write(lcd, SEQ_SLEEP_OUT, \
+ s6e39a0_write(lcd, SEQ_SLEEP_OUT, \
ARRAY_SIZE(SEQ_SLEEP_OUT));
mdelay(120);
- s6e8ax0_write(lcd, SEQ_MEMORY_WINDOW_SET_1_0, \
+ s6e39a0_write(lcd, SEQ_MEMORY_WINDOW_SET_1_0, \
ARRAY_SIZE(SEQ_MEMORY_WINDOW_SET_1_0));
- s6e8ax0_write(lcd, SEQ_MEMORY_WINDOW_SET_1_1, \
+ s6e39a0_write(lcd, SEQ_MEMORY_WINDOW_SET_1_1, \
ARRAY_SIZE(SEQ_MEMORY_WINDOW_SET_1_1));
mdelay(1);
- s6e8ax0_write(lcd, SEQ_MEMORY_WINDOW_SET_2_1, \
+ s6e39a0_write(lcd, SEQ_MEMORY_WINDOW_SET_2_1, \
ARRAY_SIZE(SEQ_MEMORY_WINDOW_SET_2_1));
- s6e8ax0_write(lcd, SEQ_MEMORY_WINDOW_SET_2_2, \
+ s6e39a0_write(lcd, SEQ_MEMORY_WINDOW_SET_2_2, \
ARRAY_SIZE(SEQ_MEMORY_WINDOW_SET_2_2));
- s6e8ax0_write(lcd, SEQ_MEMORY_WINDOW_SET_2_3, \
+ s6e39a0_write(lcd, SEQ_MEMORY_WINDOW_SET_2_3, \
ARRAY_SIZE(SEQ_MEMORY_WINDOW_SET_2_3));
- s6e8ax0_write(lcd, SEQ_MEMORY_WINDOW_SET_2_4, \
+ s6e39a0_write(lcd, SEQ_MEMORY_WINDOW_SET_2_4, \
ARRAY_SIZE(SEQ_MEMORY_WINDOW_SET_2_4));
return ret;
}
-static int s6e8ax0_ldi_enable(struct lcd_info *lcd)
+static int s6e39a0_ldi_enable(struct lcd_info *lcd)
{
int ret = 0;
- s6e8ax0_write(lcd, SEQ_DISPLAY_ON, ARRAY_SIZE(SEQ_DISPLAY_ON));
+ s6e39a0_write(lcd, SEQ_DISPLAY_ON, ARRAY_SIZE(SEQ_DISPLAY_ON));
return ret;
}
-static int s6e8ax0_ldi_disable(struct lcd_info *lcd)
+static int s6e39a0_ldi_disable(struct lcd_info *lcd)
{
int ret = 0;
- s6e8ax0_write(lcd, SEQ_DISPLAY_OFF, ARRAY_SIZE(SEQ_DISPLAY_OFF));
- s6e8ax0_write(lcd, SEQ_STANDBY_ON, ARRAY_SIZE(SEQ_STANDBY_ON));
+ s6e39a0_write(lcd, SEQ_DISPLAY_OFF, ARRAY_SIZE(SEQ_DISPLAY_OFF));
+ s6e39a0_write(lcd, SEQ_STANDBY_ON, ARRAY_SIZE(SEQ_STANDBY_ON));
return ret;
}
-static int s6e8ax0_power_on(struct lcd_info *lcd)
+static int s6e39a0_power_on(struct lcd_info *lcd)
{
int ret = 0;
struct lcd_platform_data *pd = NULL;
@@ -670,7 +674,7 @@ static int s6e8ax0_power_on(struct lcd_info *lcd)
/* dev_info(&lcd->ld->dev, "%s\n", __func__); */
- ret = s6e8ax0_ldi_init(lcd);
+ ret = s6e39a0_ldi_init(lcd);
if (ret) {
dev_err(&lcd->ld->dev, "failed to initialize ldi.\n");
@@ -679,7 +683,7 @@ static int s6e8ax0_power_on(struct lcd_info *lcd)
msleep(120);
- ret = s6e8ax0_ldi_enable(lcd);
+ ret = s6e39a0_ldi_enable(lcd);
if (ret) {
dev_err(&lcd->ld->dev, "failed to enable ldi.\n");
goto err;
@@ -688,7 +692,7 @@ static int s6e8ax0_power_on(struct lcd_info *lcd)
#ifdef SMART_DIMMING
lcd->ldi_enable = 1;
- s6e8ax0_adb_brightness_update(lcd, lcd->bd->props.brightness, 1);
+ s6e39a0_adb_brightness_update(lcd, lcd->bd->props.brightness, 1);
#else
update_brightness(lcd);
@@ -699,7 +703,7 @@ err:
return ret;
}
-static int s6e8ax0_power_off(struct lcd_info *lcd)
+static int s6e39a0_power_off(struct lcd_info *lcd)
{
int ret = 0;
@@ -707,21 +711,21 @@ static int s6e8ax0_power_off(struct lcd_info *lcd)
lcd->ldi_enable = 0;
- ret = s6e8ax0_ldi_disable(lcd);
+ ret = s6e39a0_ldi_disable(lcd);
msleep(120);
return ret;
}
-static int s6e8ax0_power(struct lcd_info *lcd, int power)
+static int s6e39a0_power(struct lcd_info *lcd, int power)
{
int ret = 0;
if (POWER_IS_ON(power) && !POWER_IS_ON(lcd->power))
- ret = s6e8ax0_power_on(lcd);
+ ret = s6e39a0_power_on(lcd);
else if (!POWER_IS_ON(power) && POWER_IS_ON(lcd->power))
- ret = s6e8ax0_power_off(lcd);
+ ret = s6e39a0_power_off(lcd);
if (!ret)
lcd->power = power;
@@ -729,7 +733,7 @@ static int s6e8ax0_power(struct lcd_info *lcd, int power)
return ret;
}
-static int s6e8ax0_set_power(struct lcd_device *ld, int power)
+static int s6e39a0_set_power(struct lcd_device *ld, int power)
{
struct lcd_info *lcd = lcd_get_data(ld);
@@ -739,10 +743,10 @@ static int s6e8ax0_set_power(struct lcd_device *ld, int power)
return -EINVAL;
}
- return s6e8ax0_power(lcd, power);
+ return s6e39a0_power(lcd, power);
}
-static int s6e8ax0_get_power(struct lcd_device *ld)
+static int s6e39a0_get_power(struct lcd_device *ld)
{
struct lcd_info *lcd = lcd_get_data(ld);
@@ -750,7 +754,7 @@ static int s6e8ax0_get_power(struct lcd_device *ld)
}
#ifdef SMART_DIMMING
-static int s6e8ax0_set_brightness(struct backlight_device *bd)
+static int s6e39a0_set_brightness(struct backlight_device *bd)
{
int ret = 0;
u32 brightness = (u32)bd->props.brightness;
@@ -766,12 +770,12 @@ static int s6e8ax0_set_brightness(struct backlight_device *bd)
/* dev_info(&lcd->ld->dev, "[%s] brightness=%d\n", __func__, brightness); */
- ret = s6e8ax0_adb_brightness_update(lcd, brightness, 0);
+ ret = s6e39a0_adb_brightness_update(lcd, brightness, 0);
return ret;
}
#else
-static int s6e8ax0_set_brightness(struct backlight_device *bd)
+static int s6e39a0_set_brightness(struct backlight_device *bd)
{
int ret = 0;
int brightness = bd->props.brightness;
@@ -802,19 +806,19 @@ static int s6e8ax0_set_brightness(struct backlight_device *bd)
}
#endif
-static int s6e8ax0_get_brightness(struct backlight_device *bd)
+static int s6e39a0_get_brightness(struct backlight_device *bd)
{
return bd->props.brightness;
}
-static struct lcd_ops s6e8ax0_lcd_ops = {
- .set_power = s6e8ax0_set_power,
- .get_power = s6e8ax0_get_power,
+static struct lcd_ops s6e39a0_lcd_ops = {
+ .set_power = s6e39a0_set_power,
+ .get_power = s6e39a0_get_power,
};
-static const struct backlight_ops s6e8ax0_backlight_ops = {
- .get_brightness = s6e8ax0_get_brightness,
- .update_status = s6e8ax0_set_brightness,
+static const struct backlight_ops s6e39a0_backlight_ops = {
+ .get_brightness = s6e39a0_get_brightness,
+ .update_status = s6e39a0_set_brightness,
};
static ssize_t lcd_type_show(struct device *dev,
@@ -855,7 +859,7 @@ static ssize_t power_reduce_store(struct device *dev,
lcd->acl_enable, value);
lcd->acl_enable = value;
if (lcd->ldi_enable)
- s6e8ax0_set_acl(lcd);
+ s6e39a0_set_acl(lcd);
}
return size;
}
@@ -865,36 +869,36 @@ static DEVICE_ATTR(power_reduce, 0664, power_reduce_show, power_reduce_store);
#ifdef CONFIG_HAS_EARLYSUSPEND
struct lcd_info *g_lcd;
-void s6e8ax0_early_suspend(void)
+void s6e39a0_early_suspend(void)
{
struct lcd_info *lcd = g_lcd;
dev_info(&lcd->ld->dev, "+%s\n", __func__);
- s6e8ax0_power(lcd, FB_BLANK_POWERDOWN);
+ s6e39a0_power(lcd, FB_BLANK_POWERDOWN);
dev_info(&lcd->ld->dev, "-%s\n", __func__);
return ;
}
-void s6e8ax0_late_resume(void)
+void s6e39a0_late_resume(void)
{
struct lcd_info *lcd = g_lcd;
dev_info(&lcd->ld->dev, "+%s\n", __func__);
- s6e8ax0_power(lcd, FB_BLANK_UNBLANK);
+ s6e39a0_power(lcd, FB_BLANK_UNBLANK);
dev_info(&lcd->ld->dev, "-%s\n", __func__);
return ;
}
#endif
-static void s6e8ax0_read_id(struct lcd_info *lcd, u8 *buf)
+static void s6e39a0_read_id(struct lcd_info *lcd, u8 *buf)
{
int ret = 0;
u8 retry_cnt = 3;
read_retry:
- ret = s6e8ax0_read(lcd, LDI_ID_REG, LDI_ID_LEN, buf);
+ ret = s6e39a0_read(lcd, LDI_ID_REG, LDI_ID_LEN, buf);
if (!ret) {
if (retry_cnt) {
printk(KERN_WARNING "[WARN:LCD] : %s : retry cnt : %d\n",\
@@ -936,7 +940,7 @@ static void s6e8aa0_check_id(struct lcd_info *lcd, u8 *idbuf)
}
#endif
-static int s6e8ax0_probe(struct device *dev)
+static int s6e39a0_probe(struct device *dev)
{
int ret = 0;
struct lcd_info *lcd;
@@ -955,7 +959,7 @@ static int s6e8ax0_probe(struct device *dev)
g_lcd = lcd;
lcd->ld = lcd_device_register("panel", dev, \
- lcd, &s6e8ax0_lcd_ops);
+ lcd, &s6e39a0_lcd_ops);
if (IS_ERR(lcd->ld)) {
pr_err("failed to register lcd device\n");
ret = PTR_ERR(lcd->ld);
@@ -963,7 +967,7 @@ static int s6e8ax0_probe(struct device *dev)
}
lcd->bd = backlight_device_register("panel", \
- dev, lcd, &s6e8ax0_backlight_ops, NULL);
+ dev, lcd, &s6e39a0_backlight_ops, NULL);
if (IS_ERR(lcd->bd)) {
pr_err("failed to register backlight device\n");
ret = PTR_ERR(lcd->bd);
@@ -999,8 +1003,8 @@ static int s6e8ax0_probe(struct device *dev)
#if 0
#ifdef CONFIG_HAS_EARLYSUSPEND
- lcd->early_suspend.suspend = s6e8ax0_early_suspend;
- lcd->early_suspend.resume = s6e8ax0_late_resume;
+ lcd->early_suspend.suspend = s6e39a0_early_suspend;
+ lcd->early_suspend.resume = s6e39a0_late_resume;
lcd->early_suspend.level = EARLY_SUSPEND_LEVEL_DISABLE_FB - 2;
register_early_suspend(&lcd->early_suspend);
#endif
@@ -1008,7 +1012,7 @@ static int s6e8ax0_probe(struct device *dev)
mutex_init(&lcd->lock);
- s6e8ax0_read_id(lcd, idbuf);
+ s6e39a0_read_id(lcd, idbuf);
dev_info(&lcd->ld->dev, "ID : %x, %x, %x\n", idbuf[0], idbuf[1], idbuf[2]);
@@ -1020,7 +1024,7 @@ static int s6e8ax0_probe(struct device *dev)
init_table_info(&lcd->smart);
- ret = s6e8ax0_read_mtp(lcd, mtp_data);
+ ret = s6e39a0_read_mtp(lcd, mtp_data);
if (!ret) {
printk(KERN_ERR "[LCD:ERROR] : %s read mtp failed\n", __func__);
/*return -EPERM;*/
@@ -1030,9 +1034,12 @@ static int s6e8ax0_probe(struct device *dev)
mutex_init(&lcd->bl_lock);
- s6e8ax0_adb_brightness_update(lcd, lcd->bd->props.brightness, 1);
+ s6e39a0_adb_brightness_update(lcd, lcd->bd->props.brightness, 1);
#endif
+ lcd_early_suspend = s6e39a0_early_suspend;
+ lcd_late_resume = s6e39a0_late_resume;
+
return 0;
out_free_backlight:
@@ -1048,11 +1055,11 @@ err_alloc:
return ret;
}
-static int __devexit s6e8ax0_remove(struct device *dev)
+static int __devexit s6e39a0_remove(struct device *dev)
{
struct lcd_info *lcd = dev_get_drvdata(dev);
- s6e8ax0_power(lcd, FB_BLANK_POWERDOWN);
+ s6e39a0_power(lcd, FB_BLANK_POWERDOWN);
lcd_device_unregister(lcd->ld);
backlight_device_unregister(lcd->bd);
kfree(lcd);
@@ -1061,34 +1068,34 @@ static int __devexit s6e8ax0_remove(struct device *dev)
}
/* Power down all displays on reboot, poweroff or halt. */
-static void s6e8ax0_shutdown(struct device *dev)
+static void s6e39a0_shutdown(struct device *dev)
{
struct lcd_info *lcd = dev_get_drvdata(dev);
dev_info(&lcd->ld->dev, "%s\n", __func__);
- s6e8ax0_power(lcd, FB_BLANK_POWERDOWN);
+ s6e39a0_power(lcd, FB_BLANK_POWERDOWN);
}
-static struct mipi_lcd_driver s6e8ax0_mipi_driver = {
+static struct mipi_lcd_driver s6e39a0_mipi_driver = {
.name = "s6e8aa0",
- .probe = s6e8ax0_probe,
- .remove = __devexit_p(s6e8ax0_remove),
- .shutdown = s6e8ax0_shutdown,
+ .probe = s6e39a0_probe,
+ .remove = __devexit_p(s6e39a0_remove),
+ .shutdown = s6e39a0_shutdown,
};
-static int s6e8ax0_init(void)
+static int s6e39a0_init(void)
{
- return s5p_dsim_register_lcd_driver(&s6e8ax0_mipi_driver);
+ return s5p_dsim_register_lcd_driver(&s6e39a0_mipi_driver);
}
-static void s6e8ax0_exit(void)
+static void s6e39a0_exit(void)
{
return;
}
-module_init(s6e8ax0_init);
-module_exit(s6e8ax0_exit);
+module_init(s6e39a0_init);
+module_exit(s6e39a0_exit);
MODULE_DESCRIPTION("MIPI-DSI S6E8AA0:AMS529HA01 (800x1280) Panel Driver");
MODULE_LICENSE("GPL");
diff --git a/drivers/video/samsung/s3cfb_s6e63m0.c b/drivers/video/samsung/s3cfb_s6e63m0.c
new file mode 100644
index 0000000..0babb31
--- /dev/null
+++ b/drivers/video/samsung/s3cfb_s6e63m0.c
@@ -0,0 +1,1718 @@
+/* linux/drivers/video/samsung/s3cfb_s6e63m0.c
+ *
+ * MIPI-DSI based AMS529HA01 AMOLED lcd panel 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/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/mutex.h>
+#include <linux/wait.h>
+#include <linux/ctype.h>
+#include <linux/io.h>
+#include <linux/delay.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/gpio.h>
+#include <linux/workqueue.h>
+#include <linux/backlight.h>
+#include <linux/lcd.h>
+#include <plat/gpio-cfg.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 "s5p-dsim.h"
+#include "s3cfb.h"
+#include "s6e63m0_gamma_l.h"
+
+#if defined(CONFIG_MACH_Q1_BD)
+#include "s6e8aa0_gamma_q1.h"
+#define SMART_DIMMING
+#else
+#include "s6e63m0_gamma_grande.h"
+#define SMART_DIMMING
+#endif
+
+#ifdef SMART_DIMMING
+#include "smart_dimming.h"
+#ifdef CONFIG_AID_DIMMING
+#include "aid_s6e8aa0.h"
+#endif
+#endif
+
+#define POWER_IS_ON(pwr) ((pwr) <= FB_BLANK_NORMAL)
+
+#define MIN_BRIGHTNESS 0
+#define MAX_BRIGHTNESS 255
+#if defined(CONFIG_MACH_Q1_BD)
+#define MAX_GAMMA 290
+#define DEFAULT_BRIGHTNESS 150
+#define DEFAULT_GAMMA_LEVEL GAMMA_150CD
+#else
+#define MAX_GAMMA 300
+#define DEFAULT_BRIGHTNESS 160
+#define DEFAULT_GAMMA_LEVEL GAMMA_160CD
+#endif
+
+#define LDI_ID_REG 0xD1
+#define LDI_ID_LEN 3
+
+#ifdef SMART_DIMMING
+#define PANEL_A1_M3 0xA1
+
+#define LDI_MTP_LENGTH 24
+#define LDI_MTP_ADDR 0xD3
+
+#define DYNAMIC_ELVSS_MIN_VALUE 0x81
+#define DYNAMIC_ELVSS_MAX_VALUE 0x9F
+
+#define ELVSS_MODE0_MIN_VOLTAGE 62
+#define ELVSS_MODE1_MIN_VOLTAGE 52
+
+struct str_elvss {
+ u8 reference;
+ u8 limit;
+};
+#endif
+
+struct lcd_info {
+ unsigned int bl;
+ unsigned int auto_brightness;
+ unsigned int acl_enable;
+ unsigned int cur_acl;
+ unsigned int current_bl;
+ unsigned int current_elvss;
+
+ unsigned int ldi_enable;
+ unsigned int power;
+ struct mutex lock;
+ struct mutex bl_lock;
+
+ struct device *dev;
+ struct lcd_device *ld;
+ struct backlight_device *bd;
+ struct lcd_platform_data *lcd_pd;
+ struct early_suspend early_suspend;
+
+ unsigned char id[LDI_ID_LEN];
+
+ unsigned char **gamma_table;
+ unsigned char **elvss_table;
+
+#ifdef SMART_DIMMING
+ unsigned int support_elvss;
+
+ struct str_smart_dim smart;
+ struct str_elvss elvss;
+#endif
+#ifdef CONFIG_AID_DIMMING
+ unsigned int support_aid;
+ unsigned char f8[ARRAY_SIZE(
+ SEQ_PANEL_CONDITION_SET_500MBPS)];
+#endif
+ unsigned int irq;
+ unsigned int connected;
+
+ struct dsim_global *dsim;
+};
+
+#ifdef CONFIG_AID_DIMMING
+static const unsigned int candela_table[GAMMA_MAX] = {
+ 20, 30, 40, 50, 60, 70, 80, 90, 100,
+ 110, 120, 130, 140, 150, 160, 170, 180,
+ 182, 184, 186, 188,
+ 190, 200, 210, 220, 230, 240, 250, MAX_GAMMA-1
+};
+
+static unsigned int aid_candela_table[GAMMA_MAX] = {
+ base_20to100, base_20to100, base_20to100, base_20to100,
+ base_20to100, base_20to100, base_20to100, base_20to100,
+ base_20to100,
+ AOR40_BASE_110, AOR40_BASE_120, AOR40_BASE_130, AOR40_BASE_140,
+ AOR40_BASE_150, AOR40_BASE_160, AOR40_BASE_170, AOR40_BASE_180,
+ AOR40_BASE_182, AOR40_BASE_184, AOR40_BASE_186, AOR40_BASE_188,
+ 190, 200, 210, 220, 230, 240, 250, MAX_GAMMA-1
+};
+
+static unsigned int elvss_offset_table[ELVSS_STATUS_MAX] = {
+ ELVSS_OFFSET_110,
+ ELVSS_OFFSET_120,
+ ELVSS_OFFSET_130,
+ ELVSS_OFFSET_140,
+ ELVSS_OFFSET_150,
+ ELVSS_OFFSET_160,
+ ELVSS_OFFSET_170,
+ ELVSS_OFFSET_180,
+ ELVSS_OFFSET_190,
+ ELVSS_OFFSET_200,
+ ELVSS_OFFSET_210,
+ ELVSS_OFFSET_220,
+ ELVSS_OFFSET_230,
+ ELVSS_OFFSET_240,
+ ELVSS_OFFSET_250,
+ ELVSS_OFFSET_260,
+ ELVSS_OFFSET_270,
+ ELVSS_OFFSET_280,
+ ELVSS_OFFSET_290,
+ ELVSS_OFFSET_300
+};
+#else
+static const unsigned int candela_table[GAMMA_MAX] = {
+ 30, 40, 50, 60, 70, 80, 90, 100, 110, 120,
+ 130, 140, 150, 160, 170, 180, 190, 200, 210, 220,
+ 230, 240, 250, MAX_GAMMA
+};
+
+static unsigned int elvss_offset_table[ELVSS_STATUS_MAX] = {
+ ELVSS_OFFSET_MIN,
+ ELVSS_OFFSET_1,
+ ELVSS_OFFSET_2,
+ ELVSS_OFFSET_MAX
+};
+#endif
+
+extern void (*lcd_early_suspend)(void);
+extern void (*lcd_late_resume)(void);
+
+#if defined(GPIO_OLED_DET)
+struct delayed_work hs_clk_re_try;
+unsigned int count_dsim;
+
+static void hs_clk_re_try_work(struct work_struct *work)
+{
+ int read_oled_det;
+
+ read_oled_det = gpio_get_value(GPIO_OLED_DET);
+
+ printk(KERN_INFO "%s, %d, %d\n", __func__,
+ count_dsim, read_oled_det);
+
+ if (read_oled_det == 0) {
+ if (count_dsim < 10) {
+ schedule_delayed_work(&hs_clk_re_try, HZ/8);
+ count_dsim++;
+ set_dsim_hs_clk_toggle_count(15);
+ } else
+ set_dsim_hs_clk_toggle_count(0);
+ } else
+ set_dsim_hs_clk_toggle_count(0);
+}
+
+static irqreturn_t oled_det_int(int irq, void *dev_id)
+{
+ printk(KERN_INFO "[DSIM] %s\n", __func__);
+
+ schedule_delayed_work(&hs_clk_re_try, HZ/16);
+
+ count_dsim = 0;
+
+ return IRQ_HANDLED;
+}
+#endif
+
+static int s6e63m0_write(struct lcd_info *lcd,
+ const unsigned char *seq, int len)
+{
+ int size;
+ const unsigned char *wbuf;
+
+ if (!lcd->connected)
+ return 0;
+
+ mutex_lock(&lcd->lock);
+
+ size = len;
+ wbuf = seq;
+
+ if (size == 1)
+ lcd->dsim->ops->cmd_write(lcd->dsim, DCS_WR_NO_PARA, wbuf[0], 0);
+ else if (size == 2)
+ lcd->dsim->ops->cmd_write(lcd->dsim, DCS_WR_1_PARA, wbuf[0], wbuf[1]);
+ else
+ lcd->dsim->ops->cmd_write(lcd->dsim, DCS_LONG_WR, (unsigned int)wbuf, size);
+
+ mutex_unlock(&lcd->lock);
+
+ return 0;
+}
+
+static int _s6e63m0_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_read(lcd->dsim, addr, count, buf);
+
+ mutex_unlock(&lcd->lock);
+
+ return ret;
+}
+
+static int s6e63m0_read(struct lcd_info *lcd, const u8 addr,
+ u16 count, u8 *buf, u8 retry_cnt)
+{
+ int ret = 0;
+
+read_retry:
+ ret = _s6e63m0_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;
+}
+
+#ifdef CONFIG_AID_DIMMING
+static int get_backlight_level_from_brightness(int brightness)
+{
+ int backlightlevel;
+
+ /* brightness setting from platform is from 0 to 255
+ * But in this driver, brightness is
+ only supported from 0 to 24 */
+
+ switch (brightness) {
+ case 0 ... 29:
+ backlightlevel = GAMMA_20CD;
+ break;
+ case 30 ... 39:
+ backlightlevel = GAMMA_30CD;
+ break;
+ case 40 ... 49:
+ backlightlevel = GAMMA_40CD;
+ break;
+ case 50 ... 59:
+ backlightlevel = GAMMA_50CD;
+ break;
+ case 60 ... 69:
+ backlightlevel = GAMMA_60CD;
+ break;
+ case 70 ... 79:
+ backlightlevel = GAMMA_70CD;
+ break;
+ case 80 ... 89:
+ backlightlevel = GAMMA_80CD;
+ break;
+ case 90 ... 99:
+ backlightlevel = GAMMA_90CD;
+ break;
+ case 100 ... 109:
+ backlightlevel = GAMMA_100CD;
+ break;
+ case 110 ... 119:
+ backlightlevel = GAMMA_110CD;
+ break;
+ case 120 ... 129:
+ backlightlevel = GAMMA_120CD;
+ break;
+ case 130 ... 139:
+ backlightlevel = GAMMA_130CD;
+ break;
+ case 140 ... 149:
+ backlightlevel = GAMMA_140CD;
+ break;
+ case 150 ... 159:
+ backlightlevel = GAMMA_150CD;
+ break;
+ case 160 ... 169:
+ backlightlevel = GAMMA_160CD;
+ break;
+ case 170 ... 179:
+ backlightlevel = GAMMA_170CD;
+ break;
+ case 180 ... 181:
+ backlightlevel = GAMMA_180CD;
+ break;
+ case 182 ... 183:
+ backlightlevel = GAMMA_182CD;
+ break;
+ case 184 ... 185:
+ backlightlevel = GAMMA_184CD;
+ break;
+ case 186 ... 187:
+ backlightlevel = GAMMA_186CD;
+ break;
+ case 188 ... 189:
+ backlightlevel = GAMMA_188CD;
+ break;
+ case 190 ... 199:
+ backlightlevel = GAMMA_190CD;
+ break;
+ case 200 ... 209:
+ backlightlevel = GAMMA_200CD;
+ break;
+ case 210 ... 219:
+ backlightlevel = GAMMA_210CD;
+ break;
+ case 220 ... 229:
+ backlightlevel = GAMMA_220CD;
+ break;
+ case 230 ... 239:
+ backlightlevel = GAMMA_230CD;
+ break;
+ case 240 ... 249:
+ backlightlevel = GAMMA_240CD;
+ break;
+ case 250 ... 254:
+ backlightlevel = GAMMA_250CD;
+ break;
+ case 255:
+ backlightlevel = GAMMA_300CD;
+ break;
+ default:
+ backlightlevel = DEFAULT_GAMMA_LEVEL;
+ break;
+ }
+ return backlightlevel;
+}
+
+static int s6e63m0_gamma_ctl(struct lcd_info *lcd)
+{
+ lcd->f8[0x12] = aid_command_table[lcd->bl][0];
+ lcd->f8[0x01] = aid_command_table[lcd->bl][1];
+
+ s6e63m0_write(lcd, lcd->gamma_table[lcd->bl],
+ GAMMA_PARAM_SIZE);
+ s6e63m0_write(lcd, SEQ_GAMMA_UPDATE,
+ ARRAY_SIZE(SEQ_GAMMA_UPDATE));
+
+ if (likely(lcd->support_aid))
+ s6e63m0_write(lcd, lcd->f8, AID_PARAM_SIZE);
+
+ return 0;
+}
+#else
+static int get_backlight_level_from_brightness(int brightness)
+{
+ int backlightlevel;
+
+ /* brightness setting from platform is from 0 to 255
+ * But in this driver, brightness is
+ only supported from 0 to 24 */
+
+ switch (brightness) {
+ case 0 ... 29:
+ backlightlevel = GAMMA_30CD;
+ break;
+ case 30 ... 254:
+ backlightlevel = (brightness - candela_table[0]) / 10;
+ break;
+ case 255:
+ backlightlevel = ARRAY_SIZE(candela_table) - 1;
+ break;
+ default:
+ backlightlevel = DEFAULT_GAMMA_LEVEL;
+ break;
+ }
+ return backlightlevel;
+}
+
+static int s6e63m0_gamma_ctl(struct lcd_info *lcd)
+{
+#if defined(CONFIG_MACH_M0_GRANDECTC) || defined(CONFIG_MACH_IRON)
+ s6e63m0_write(lcd, SEQ_GAMMA_CONDITION_SET,
+ ARRAY_SIZE(SEQ_GAMMA_CONDITION_SET));
+#else
+ s6e63m0_write(lcd, lcd->gamma_table[lcd->bl],
+ GAMMA_PARAM_SIZE);
+#endif
+
+ /* Gamma Set Update */
+ s6e63m0_write(lcd, SEQ_GAMMA_UPDATE,
+ ARRAY_SIZE(SEQ_GAMMA_UPDATE));
+
+ return 0;
+}
+#endif
+
+#if defined(CONFIG_MACH_Q1_BD)
+static int s6e63m0_set_acl(struct lcd_info *lcd)
+{
+ int ret = 0;
+
+ if (lcd->acl_enable) {
+ if (lcd->cur_acl == 0) {
+ if (lcd->bl == 0 || lcd->bl == 1) {
+ s6e63m0_write(lcd, SEQ_ACL_OFF,
+ ARRAY_SIZE(SEQ_ACL_OFF));
+ dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d, acl_off\n",
+ __func__, lcd->cur_acl);
+ } else {
+ s6e63m0_write(lcd, SEQ_ACL_ON,
+ ARRAY_SIZE(SEQ_ACL_ON));
+ dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d, acl_on\n",
+ __func__, lcd->cur_acl);
+ }
+ }
+ switch (lcd->bl) {
+ case GAMMA_30CD... GAMMA_40CD:
+ if (lcd->cur_acl != 0) {
+ s6e63m0_write(lcd, SEQ_ACL_OFF,
+ ARRAY_SIZE(SEQ_ACL_OFF));
+ lcd->cur_acl = 0;
+ dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d\n",
+ __func__, lcd->cur_acl);
+ }
+ break;
+ case GAMMA_50CD:
+ if (lcd->cur_acl != 200) {
+ s6e63m0_write(lcd, ACL_CUTOFF_TABLE[ACL_STATUS_20P],
+ ACL_PARAM_SIZE);
+ lcd->cur_acl = 200;
+ dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d\n",
+ __func__, lcd->cur_acl);
+ }
+ break;
+ case GAMMA_60CD:
+ if (lcd->cur_acl != 330) {
+ s6e63m0_write(lcd, ACL_CUTOFF_TABLE[ACL_STATUS_33P],
+ ACL_PARAM_SIZE);
+ lcd->cur_acl = 330;
+ dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d\n",
+ __func__, lcd->cur_acl);
+ }
+ break;
+ case GAMMA_70CD:
+ if (lcd->cur_acl != 430) {
+ s6e63m0_write(lcd, ACL_CUTOFF_TABLE[ACL_STATUS_43P],
+ ACL_PARAM_SIZE);
+ lcd->cur_acl = 430;
+ dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d\n",
+ __func__, lcd->cur_acl);
+ }
+ break;
+ case GAMMA_80CD:
+ if (lcd->cur_acl != 450) {
+ s6e63m0_write(lcd, ACL_CUTOFF_TABLE[ACL_STATUS_45P_80CD],
+ ACL_PARAM_SIZE);
+ lcd->cur_acl = 450;
+ dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d\n",
+ __func__, lcd->cur_acl);
+ }
+ break;
+ case GAMMA_90CD ... GAMMA_150CD:
+ if (lcd->cur_acl != 451) {
+ s6e63m0_write(lcd, ACL_CUTOFF_TABLE[ACL_STATUS_45P],
+ ACL_PARAM_SIZE);
+ lcd->cur_acl = 451;
+ dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d\n",
+ __func__, lcd->cur_acl);
+ }
+ break;
+ case GAMMA_160CD: /* 160cd */
+ if (lcd->cur_acl != 460) {
+ s6e63m0_write(lcd, ACL_CUTOFF_TABLE[ACL_STATUS_46P_160CD],
+ ACL_PARAM_SIZE);
+ lcd->cur_acl = 460;
+ dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d\n",
+ __func__, lcd->cur_acl);
+ }
+ break;
+ case GAMMA_170CD ... GAMMA_250CD:
+ if (lcd->cur_acl != 461) {
+ s6e63m0_write(lcd, ACL_CUTOFF_TABLE[ACL_STATUS_46P],
+ `ACL_PARAM_SIZE);
+ lcd->cur_acl = 461;
+ dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d\n",
+ __func__, lcd->cur_acl);
+ }
+ break;
+ default:
+ if (lcd->cur_acl != 550) {
+ s6e63m0_write(lcd, ACL_CUTOFF_TABLE[ACL_STATUS_50P],
+ ACL_PARAM_SIZE);
+ lcd->cur_acl = 550;
+ dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d\n",
+ __func__, lcd->cur_acl);
+ }
+ break;
+ }
+ } else {
+ s6e63m0_write(lcd, SEQ_ACL_OFF, ARRAY_SIZE(SEQ_ACL_OFF));
+ lcd->cur_acl = 0;
+ dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d, acl_off\n",
+ __func__, lcd->cur_acl);
+ }
+
+ if (ret) {
+ ret = -EPERM;
+ goto acl_err;
+ }
+
+acl_err:
+ return ret;
+}
+#else
+static int s6e63m0_set_acl(struct lcd_info *lcd)
+{
+#if !defined(CONFIG_MACH_M0_GRANDECTC) && !defined(CONFIG_MACH_IRON)
+ if (lcd->acl_enable) {
+ if (lcd->cur_acl == 0) {
+ if (lcd->bl == 0 || lcd->bl == 1) {
+ s6e63m0_write(lcd, SEQ_ACL_OFF, ARRAY_SIZE(SEQ_ACL_OFF));
+ dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d, acl_off\n",
+ __func__, lcd->cur_acl);
+ } else {
+ s6e63m0_write(lcd, SEQ_ACL_ON, ARRAY_SIZE(SEQ_ACL_ON));
+ dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d, acl_on\n",
+ __func__, lcd->cur_acl);
+ }
+ }
+ switch (lcd->bl) {
+ case GAMMA_20CD ... GAMMA_40CD: /* 30cd ~ 40cd - 0%*/
+ if (lcd->cur_acl != 0) {
+ s6e63m0_write(lcd, SEQ_ACL_OFF, ARRAY_SIZE(SEQ_ACL_OFF));
+ lcd->cur_acl = 0;
+ dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d\n",
+ __func__, lcd->cur_acl);
+ }
+ break;
+ case GAMMA_50CD: /* 50cd - 20%*/
+ if (lcd->cur_acl != 20) {
+ s6e63m0_write(lcd, ACL_CUTOFF_TABLE[ACL_STATUS_20P],
+ ACL_PARAM_SIZE);
+ lcd->cur_acl = 20;
+ dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d\n",
+ __func__, lcd->cur_acl);
+ }
+ break;
+ case GAMMA_60CD: /* 60cd - 33%*/
+ if (lcd->cur_acl != 33) {
+ s6e63m0_write(lcd, ACL_CUTOFF_TABLE[ACL_STATUS_33P],
+ ACL_PARAM_SIZE);
+ lcd->cur_acl = 33;
+ dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d\n",
+ __func__, lcd->cur_acl);
+ }
+ break;
+ case GAMMA_70CD ... GAMMA_250CD: /*70cd ~ 250cd - 40%*/
+ if (lcd->cur_acl != 40) {
+ s6e63m0_write(lcd, ACL_CUTOFF_TABLE[ACL_STATUS_40P],
+ ACL_PARAM_SIZE);
+ lcd->cur_acl = 40;
+ dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d\n",
+ __func__, lcd->cur_acl);
+ }
+ break;
+ default:
+ if (lcd->cur_acl != 50) {
+ s6e63m0_write(lcd, ACL_CUTOFF_TABLE[ACL_STATUS_50P],
+ ACL_PARAM_SIZE);
+ lcd->cur_acl = 50;
+ dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d\n",
+ __func__, lcd->cur_acl);
+ }
+ break;
+ }
+ } else {
+ s6e63m0_write(lcd, SEQ_ACL_OFF, ARRAY_SIZE(SEQ_ACL_OFF));
+ lcd->cur_acl = 0;
+ dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d, acl_off\n",
+ __func__, lcd->cur_acl);
+ }
+#endif
+
+ return 0;
+}
+#endif
+
+#ifdef SMART_DIMMING
+#ifdef CONFIG_AID_DIMMING
+static int s6e63m0_set_elvss(struct lcd_info *lcd)
+{
+ int ret = 0, elvss_level = 0;
+ u32 candela = aid_candela_table[lcd->bl];
+
+ switch (candela) {
+ case 0 ... 110:
+ elvss_level = ELVSS_110;
+ break;
+ case 111 ... 120:
+ elvss_level = ELVSS_120;
+ break;
+ case 121 ... 130:
+ elvss_level = ELVSS_130;
+ break;
+ case 131 ... 140:
+ elvss_level = ELVSS_140;
+ break;
+ case 141 ... 150:
+ elvss_level = ELVSS_150;
+ break;
+ case 151 ... 160:
+ elvss_level = ELVSS_160;
+ break;
+ case 161 ... 170:
+ elvss_level = ELVSS_170;
+ break;
+ case 171 ... 180:
+ elvss_level = ELVSS_180;
+ break;
+ case 181 ... 190:
+ elvss_level = ELVSS_190;
+ break;
+ case 191 ... 200:
+ elvss_level = ELVSS_200;
+ break;
+ case 201 ... 210:
+ elvss_level = ELVSS_210;
+ break;
+ case 211 ... 220:
+ elvss_level = ELVSS_220;
+ break;
+ case 221 ... 230:
+ elvss_level = ELVSS_230;
+ break;
+ case 231 ... 240:
+ elvss_level = ELVSS_240;
+ break;
+ case 241 ... 250:
+ elvss_level = ELVSS_250;
+ break;
+ case 251 ... 260:
+ elvss_level = ELVSS_260;
+ break;
+ case 261 ... 270:
+ elvss_level = ELVSS_270;
+ break;
+ case 271 ... 280:
+ elvss_level = ELVSS_280;
+ break;
+ case 281 ... 290:
+ elvss_level = ELVSS_290;
+ break;
+ case 291 ... 300:
+ elvss_level = ELVSS_300;
+ break;
+ }
+
+ if (lcd->current_elvss != lcd->elvss_table[elvss_level][2]) {
+ ret = s6e63m0_write(lcd, lcd->elvss_table[elvss_level],
+ ELVSS_PARAM_SIZE);
+ lcd->current_elvss = lcd->elvss_table[elvss_level][2];
+ }
+
+ dev_dbg(&lcd->ld->dev, "elvss = %x\n",
+ lcd->elvss_table[elvss_level][2]);
+
+ if (ret) {
+ ret = -EPERM;
+ goto elvss_err;
+ }
+
+elvss_err:
+ return ret;
+}
+#else
+static int s6e63m0_set_elvss(struct lcd_info *lcd)
+{
+ int ret = 0, elvss_level = 0;
+ u32 candela = candela_table[lcd->bl];
+
+ switch (candela) {
+ case 0 ... 100:
+ elvss_level = ELVSS_MIN;
+ break;
+ case 101 ... 160:
+ elvss_level = ELVSS_1;
+ break;
+ case 161 ... 200:
+ elvss_level = ELVSS_2;
+ break;
+ case 201 ... 300:
+ elvss_level = ELVSS_MAX;
+ break;
+ default:
+ break;
+ }
+
+ if (lcd->current_elvss != lcd->elvss_table[elvss_level][2]) {
+ ret = s6e63m0_write(lcd, lcd->elvss_table[elvss_level],
+ ELVSS_PARAM_SIZE);
+ lcd->current_elvss = lcd->elvss_table[elvss_level][2];
+ }
+
+ dev_dbg(&lcd->ld->dev, "elvss = %x\n",
+ lcd->elvss_table[elvss_level][2]);
+
+ if (ret) {
+ ret = -EPERM;
+ goto elvss_err;
+ }
+
+elvss_err:
+ return ret;
+}
+#endif
+static u8 get_elvss_value(struct lcd_info *lcd, u8 elvss_level)
+{
+ u8 ref = 0;
+ u8 offset;
+
+ if (lcd->elvss.limit == 0x00)
+ ref = (lcd->elvss.reference | 0x80);
+ else if (lcd->elvss.limit == 0x01)
+ ref = (lcd->elvss.reference + 0x40);
+ else {
+ printk(KERN_ERR "[ERROR:ELVSS]:%s undefined elvss limit value :%x\n",
+ __func__, lcd->elvss.limit);
+ return 0;
+ }
+
+ offset = elvss_offset_table[elvss_level];
+ ref += offset;
+
+ if (ref < DYNAMIC_ELVSS_MIN_VALUE)
+ ref = DYNAMIC_ELVSS_MIN_VALUE;
+ else if (ref > DYNAMIC_ELVSS_MAX_VALUE)
+ ref = DYNAMIC_ELVSS_MAX_VALUE;
+
+ return ref;
+}
+
+static int init_elvss_table(struct lcd_info *lcd)
+{
+ int i, ret = 0;
+#ifdef SMART_DIMMING_DEBUG
+ int j;
+#endif
+
+ lcd->elvss_table = kzalloc(ELVSS_STATUS_MAX * sizeof(u8 *), GFP_KERNEL);
+
+ if (IS_ERR_OR_NULL(lcd->elvss_table)) {
+ pr_err("failed to allocate elvss table\n");
+ ret = -ENOMEM;
+ goto err_alloc_elvss_table;
+ }
+
+ for (i = 0; i < ELVSS_STATUS_MAX; i++) {
+ lcd->elvss_table[i] = kzalloc(ELVSS_PARAM_SIZE * sizeof(u8),
+ GFP_KERNEL);
+ if (IS_ERR_OR_NULL(lcd->elvss_table[i])) {
+ pr_err("failed to allocate elvss\n");
+ ret = -ENOMEM;
+ goto err_alloc_elvss;
+ }
+ lcd->elvss_table[i][0] = 0xB1;
+ lcd->elvss_table[i][1] = 0x04;
+ lcd->elvss_table[i][2] = get_elvss_value(lcd, i);
+ }
+
+#ifdef SMART_DIMMING_DEBUG
+ for (i = 0; i < ELVSS_STATUS_MAX; i++) {
+ for (j = 0; j < ELVSS_PARAM_SIZE; j++)
+ pr_info("0x%02x, ", lcd->elvss_table[i][j]);
+ pr_info("\n");
+ }
+#endif
+
+ return 0;
+
+err_alloc_elvss:
+ while (i > 0) {
+ kfree(lcd->elvss_table[i-1]);
+ i--;
+ }
+ kfree(lcd->elvss_table);
+err_alloc_elvss_table:
+ return ret;
+}
+
+#ifdef CONFIG_AID_DIMMING
+static int init_gamma_table(struct lcd_info *lcd)
+{
+ int i, ret = 0;
+
+ lcd->gamma_table = kzalloc(GAMMA_MAX * sizeof(u8 *),
+ GFP_KERNEL);
+ if (IS_ERR_OR_NULL(lcd->gamma_table)) {
+ pr_err("failed to allocate gamma table\n");
+ ret = -ENOMEM;
+ goto err_alloc_gamma_table;
+ }
+
+ for (i = 0; i < GAMMA_MAX; i++) {
+ lcd->gamma_table[i] = kzalloc(GAMMA_PARAM_SIZE * sizeof(u8),
+ GFP_KERNEL);
+ if (IS_ERR_OR_NULL(lcd->gamma_table[i])) {
+ pr_err("failed to allocate gamma\n");
+ ret = -ENOMEM;
+ goto err_alloc_gamma;
+ }
+ lcd->gamma_table[i][0] = 0xFA;
+ lcd->gamma_table[i][1] = 0x01;
+ }
+
+ for (i = GAMMA_20CD; i <= GAMMA_180CD; i++)
+ calc_gamma_table(&lcd->smart, aid_candela_table[i],
+ &lcd->gamma_table[i][2], G_21);
+
+ for (i = GAMMA_182CD; i < GAMMA_MAX; i++) {
+ if ((i > GAMMA_188CD) && (i < GAMMA_200CD))
+ calc_gamma_table_215_190(&lcd->smart,
+ aid_candela_table[i], &lcd->gamma_table[i][2]);
+ if ((i > GAMMA_250CD) && (i < GAMMA_MAX))
+ calc_gamma_table(&lcd->smart, aid_candela_table[i],
+ &lcd->gamma_table[i][2], G_22);
+ else
+ calc_gamma_table(&lcd->smart, aid_candela_table[i],
+ &lcd->gamma_table[i][2], G_215);
+ }
+
+#ifdef SMART_DIMMING_DEBUG
+ for (i = 0; i < GAMMA_MAX; i++) {
+ for (j = 0; j < GAMMA_PARAM_SIZE; j++)
+ pr_info("%d, ", lcd->gamma_table[i][j]);
+ pr_info("\n");
+ }
+#endif
+ return 0;
+
+err_alloc_gamma:
+ while (i > 0) {
+ kfree(lcd->gamma_table[i-1]);
+ i--;
+ }
+ kfree(lcd->gamma_table);
+err_alloc_gamma_table:
+ return ret;
+}
+
+static int init_aid_dimming_table(struct lcd_info *lcd)
+{
+ unsigned int i, j;
+
+ for (i = 0; i < ARRAY_SIZE(aid_rgb_fix_table); i++) {
+ j = (aid_rgb_fix_table[i].gray * 3
+ + aid_rgb_fix_table[i].rgb) + 2;
+ lcd->gamma_table[aid_rgb_fix_table[i].candela_idx][j]
+ += aid_rgb_fix_table[i].offset;
+ }
+
+#ifdef SMART_DIMMING_DEBUG
+ for (i = 0; i < GAMMA_MAX; i++) {
+ for (j = 0; j < GAMMA_PARAM_SIZE; j++)
+ pr_info("%d, ", lcd->gamma_table[i][j]);
+ pr_info("\n");
+ }
+#endif
+ return 0;
+}
+#else
+static int init_gamma_table(struct lcd_info *lcd)
+{
+ int i, ret = 0;
+
+ lcd->gamma_table = kzalloc(GAMMA_MAX * sizeof(u8 *),
+ GFP_KERNEL);
+ if (IS_ERR_OR_NULL(lcd->gamma_table)) {
+ pr_err("failed to allocate gamma table\n");
+ ret = -ENOMEM;
+ goto err_alloc_gamma_table;
+ }
+
+ for (i = 0; i < GAMMA_MAX; i++) {
+ lcd->gamma_table[i] = kzalloc(GAMMA_PARAM_SIZE * sizeof(u8),
+ GFP_KERNEL);
+ if (IS_ERR_OR_NULL(lcd->gamma_table[i])) {
+ pr_err("failed to allocate gamma\n");
+ ret = -ENOMEM;
+ goto err_alloc_gamma;
+ }
+ lcd->gamma_table[i][0] = 0xFA;
+ lcd->gamma_table[i][1] = 0x01;
+ calc_gamma_table(&lcd->smart, candela_table[i]-1,
+ lcd->gamma_table[i]+2);
+ }
+
+#ifdef SMART_DIMMING_DEBUG
+ for (i = 0; i < GAMMA_MAX; i++) {
+ for (j = 0; j < GAMMA_PARAM_SIZE; j++)
+ pr_info("0x%02x, ", lcd->gamma_table[i][j]);
+ pr_info("\n");
+ }
+#endif
+ return 0;
+
+err_alloc_gamma:
+ while (i > 0) {
+ kfree(lcd->gamma_table[i-1]);
+ i--;
+ }
+ kfree(lcd->gamma_table);
+err_alloc_gamma_table:
+ return ret;
+}
+#endif
+#endif
+
+static int update_brightness(struct lcd_info *lcd, u8 force)
+{
+ int ret;
+ u32 brightness;
+
+ mutex_lock(&lcd->bl_lock);
+
+ brightness = lcd->bd->props.brightness;
+
+ if (unlikely(!lcd->auto_brightness && brightness > 250))
+ brightness = 250;
+
+ lcd->bl = get_backlight_level_from_brightness(brightness);
+
+ if ((force) || ((lcd->ldi_enable) &&
+ (lcd->current_bl != lcd->bl))) {
+
+ ret = s6e63m0_gamma_ctl(lcd);
+ /*ret = s6e63m0_set_acl(lcd);*/
+ /* W2013 temp block */
+ /*ret = s6e63m0_set_elvss(lcd);*/
+ /* W2013 temp block */
+
+ lcd->current_bl = lcd->bl;
+
+ dev_info(&lcd->ld->dev, "brightness=%d, bl=%d, candela=%d\n",
+ brightness, lcd->bl, candela_table[lcd->bl]);
+ }
+
+ mutex_unlock(&lcd->bl_lock);
+
+ return 0;
+}
+
+static int s6e63m0_ldi_init(struct lcd_info *lcd)
+{
+ int ret = 0;
+
+#if defined(CONFIG_MACH_M0_GRANDECTC) || defined(CONFIG_MACH_IRON)
+ mdelay(25); /* 25ms */
+ s6e63m0_write(lcd, SEQ_SW_RESET,
+ ARRAY_SIZE(SEQ_SW_RESET)); /* SW Reset */
+ mdelay(5); /* Wait 5ms more */
+ s6e63m0_write(lcd, SEQ_APPLY_LEVEL2_KEY_ENABLE,
+ ARRAY_SIZE(SEQ_APPLY_LEVEL2_KEY_ENABLE));
+ s6e63m0_write(lcd, SEQ_APPLY_MTP_KEY_ENABLE,
+ ARRAY_SIZE(SEQ_APPLY_MTP_KEY_ENABLE));
+ s6e63m0_write(lcd, SEQ_SLEEP_OUT,
+ ARRAY_SIZE(SEQ_SLEEP_OUT));
+ mdelay(10); /* 10ms */
+ s6e63m0_write(lcd, SEQ_PANEL_CONDITION_SET,
+ ARRAY_SIZE(SEQ_PANEL_CONDITION_SET));
+ s6e63m0_write(lcd, SEQ_DISPLAY_CONDITION_SET1,
+ ARRAY_SIZE(SEQ_DISPLAY_CONDITION_SET1));
+ s6e63m0_write(lcd, SEQ_DISPLAY_CONDITION_SET2,
+ ARRAY_SIZE(SEQ_DISPLAY_CONDITION_SET2));
+ s6e63m0_write(lcd, SEQ_GAMMA_CONDITION_SET,
+ ARRAY_SIZE(SEQ_GAMMA_CONDITION_SET));
+ s6e63m0_write(lcd, SEQ_GAMMA_UPDATE,
+ ARRAY_SIZE(SEQ_GAMMA_UPDATE));
+ s6e63m0_write(lcd, SEQ_ETC_SOURCE_CONTROL,
+ ARRAY_SIZE(SEQ_ETC_SOURCE_CONTROL));
+ s6e63m0_write(lcd, SEQ_ETC_CONTROL_B3h,
+ ARRAY_SIZE(SEQ_ETC_CONTROL_B3h));
+#if !defined(CONFIG_MACH_M0_GRANDECTC) && !defined(CONFIG_MACH_IRON)
+ s6e63m0_write(lcd, SEQ_ETC_CONTROL_B5h,
+ ARRAY_SIZE(SEQ_ETC_CONTROL_B5h));
+ s6e63m0_write(lcd, SEQ_ETC_CONTROL_B6h,
+ ARRAY_SIZE(SEQ_ETC_CONTROL_B6h));
+ s6e63m0_write(lcd, SEQ_ETC_CONTROL_B7h,
+ ARRAY_SIZE(SEQ_ETC_CONTROL_B7h));
+ s6e63m0_write(lcd, SEQ_ETC_CONTROL_B8h,
+ ARRAY_SIZE(SEQ_ETC_CONTROL_B8h));
+ s6e63m0_write(lcd, SEQ_ETC_CONTROL_B9h,
+ ARRAY_SIZE(SEQ_ETC_CONTROL_B9h));
+ s6e63m0_write(lcd, SEQ_ETC_CONTROL_BAh,
+ ARRAY_SIZE(SEQ_ETC_CONTROL_BAh));
+#endif
+ s6e63m0_write(lcd, SEQ_ELVSS_SET, ARRAY_SIZE(SEQ_ELVSS_SET));
+ s6e63m0_write(lcd, SEQ_ELVSS_ON, ARRAY_SIZE(SEQ_ELVSS_ON));
+
+#elif defined(CONFIG_MACH_Q1_BD)
+ s6e63m0_write(lcd, SEQ_APPLY_LEVEL_2_KEY,
+ ARRAY_SIZE(SEQ_APPLY_LEVEL_2_KEY));
+ msleep(20);
+ s6e63m0_write(lcd, SEQ_SLEEP_OUT, ARRAY_SIZE(SEQ_SLEEP_OUT));
+ msleep(5);
+ s6e63m0_write(lcd, SEQ_PANEL_CONDITION_SET,
+ ARRAY_SIZE(SEQ_PANEL_CONDITION_SET));
+ s6e63m0_write(lcd, SEQ_DISPLAY_CONDITION_SET,
+ ARRAY_SIZE(SEQ_DISPLAY_CONDITION_SET));
+ s6e63m0_gamma_ctl(lcd);
+ s6e63m0_write(lcd, SEQ_ETC_SOURCE_CONTROL,
+ ARRAY_SIZE(SEQ_ETC_SOURCE_CONTROL));
+ s6e63m0_write(lcd, SEQ_ETC_PENTILE_CONTROL,
+ ARRAY_SIZE(SEQ_ETC_PENTILE_CONTROL));
+ s6e63m0_write(lcd, SEQ_ETC_POWER_CONTROL,
+ ARRAY_SIZE(SEQ_ETC_POWER_CONTROL));
+ s6e63m0_write(lcd, SEQ_ELVSS_NVM_SETTING,
+ ARRAY_SIZE(SEQ_ELVSS_NVM_SETTING));
+ s6e63m0_write(lcd, SEQ_ELVSS_CONTROL,
+ ARRAY_SIZE(SEQ_ELVSS_CONTROL));
+#else
+ s6e63m0_write(lcd, SEQ_APPLY_LEVEL_2,
+ ARRAY_SIZE(SEQ_APPLY_LEVEL_2));
+ s6e63m0_write(lcd, SEQ_APPLY_MTP_KEY_ENABLE,
+ ARRAY_SIZE(SEQ_APPLY_MTP_KEY_ENABLE));
+ s6e63m0_write(lcd, SEQ_SLEEP_OUT, ARRAY_SIZE(SEQ_SLEEP_OUT));
+ msleep(5);
+
+ if (lcd->id[1] == 0x20) { /* 4.8" HD for M0/C1*/
+ s6e63m0_write(lcd, SEQ_PANEL_CONDITION_SET_500MBPS,
+ ARRAY_SIZE(SEQ_PANEL_CONDITION_SET_500MBPS));
+ s6e63m0_write(lcd, SEQ_DISPLAY_CONDITION_SET,
+ ARRAY_SIZE(SEQ_DISPLAY_CONDITION_SET));
+ s6e63m0_gamma_ctl(lcd);
+ s6e63m0_write(lcd, SEQ_ETC_SOURCE_CONTROL,
+ ARRAY_SIZE(SEQ_ETC_SOURCE_CONTROL));
+ s6e63m0_write(lcd, SEQ_ETC_PENTILE_CONTROL,
+ ARRAY_SIZE(SEQ_ETC_PENTILE_CONTROL));
+ s6e63m0_write(lcd, SEQ_ETC_NVM_SETTING,
+ ARRAY_SIZE(SEQ_ETC_NVM_SETTING));
+ s6e63m0_write(lcd, SEQ_ETC_POWER_CONTROL,
+ ARRAY_SIZE(SEQ_ETC_POWER_CONTROL));
+ } else if (lcd->id[1] == 0xae) {
+ s6e63m0_write(lcd, SEQ_PANEL_CONDITION_SET_480MBPS_46,
+ ARRAY_SIZE(SEQ_PANEL_CONDITION_SET_480MBPS_46));
+ s6e63m0_write(lcd, SEQ_DISPLAY_CONDITION_SET,
+ ARRAY_SIZE(SEQ_DISPLAY_CONDITION_SET));
+ s6e63m0_gamma_ctl(lcd);
+ s6e63m0_write(lcd, SEQ_ETC_SOURCE_CONTROL,
+ ARRAY_SIZE(SEQ_ETC_SOURCE_CONTROL));
+ s6e63m0_write(lcd, SEQ_ETC_PENTILE_CONTROL_46,
+ ARRAY_SIZE(SEQ_ETC_PENTILE_CONTROL_46));
+ s6e63m0_write(lcd, SEQ_ETC_NVM_SETTING_46,
+ ARRAY_SIZE(SEQ_ETC_NVM_SETTING_46));
+ s6e63m0_write(lcd, SEQ_ETC_POWER_CONTROL_46,
+ ARRAY_SIZE(SEQ_ETC_POWER_CONTROL_46));
+ } else {
+ s6e63m0_write(lcd, SEQ_PANEL_CONDITION_SET_500MBPS_46,
+ ARRAY_SIZE(SEQ_PANEL_CONDITION_SET_500MBPS_46));
+ s6e63m0_write(lcd, SEQ_DISPLAY_CONDITION_SET,
+ ARRAY_SIZE(SEQ_DISPLAY_CONDITION_SET));
+ s6e63m0_gamma_ctl(lcd);
+ s6e63m0_write(lcd, SEQ_ETC_SOURCE_CONTROL,
+ ARRAY_SIZE(SEQ_ETC_SOURCE_CONTROL));
+ s6e63m0_write(lcd, SEQ_ETC_PENTILE_CONTROL_46,
+ ARRAY_SIZE(SEQ_ETC_PENTILE_CONTROL_46));
+ s6e63m0_write(lcd, SEQ_ETC_NVM_SETTING_46,
+ ARRAY_SIZE(SEQ_ETC_NVM_SETTING_46));
+ s6e63m0_write(lcd, SEQ_ETC_POWER_CONTROL_46,
+ ARRAY_SIZE(SEQ_ETC_POWER_CONTROL_46));
+ }
+
+ s6e63m0_write(lcd, SEQ_ELVSS_CONTROL,
+ ARRAY_SIZE(SEQ_ELVSS_CONTROL));
+#endif
+
+ return ret;
+}
+
+static int s6e63m0_ldi_enable(struct lcd_info *lcd)
+{
+ int ret = 0;
+
+ s6e63m0_write(lcd, SEQ_DISPLAY_ON, ARRAY_SIZE(SEQ_DISPLAY_ON));
+
+ return ret;
+}
+
+static int s6e63m0_ldi_disable(struct lcd_info *lcd)
+{
+ int ret = 0;
+
+ s6e63m0_write(lcd, SEQ_DISPLAY_OFF,
+ ARRAY_SIZE(SEQ_DISPLAY_OFF));
+ s6e63m0_write(lcd, SEQ_STANDBY_ON,
+ ARRAY_SIZE(SEQ_STANDBY_ON));
+
+ return ret;
+}
+
+static int s6e63m0_power_on(struct lcd_info *lcd)
+{
+ int ret = 0;
+ struct lcd_platform_data *pd = NULL;
+ pd = lcd->lcd_pd;
+
+ /* dev_info(&lcd->ld->dev, "%s\n", __func__); */
+
+ ret = s6e63m0_ldi_init(lcd);
+ if (ret) {
+ dev_err(&lcd->ld->dev, "failed to initialize ldi.\n");
+ goto err;
+ }
+
+ msleep(120);
+
+ ret = s6e63m0_ldi_enable(lcd);
+ if (ret) {
+ dev_err(&lcd->ld->dev, "failed to enable ldi.\n");
+ goto err;
+ }
+
+ lcd->ldi_enable = 1;
+
+ update_brightness(lcd, 1);
+err:
+ return ret;
+}
+
+static int s6e63m0_power_off(struct lcd_info *lcd)
+{
+ int ret = 0;
+
+ dev_info(&lcd->ld->dev, "%s\n", __func__);
+
+ lcd->ldi_enable = 0;
+
+ ret = s6e63m0_ldi_disable(lcd);
+
+ msleep(135);
+
+ return ret;
+}
+
+static int s6e63m0_power(struct lcd_info *lcd, int power)
+{
+ int ret = 0;
+
+ if (POWER_IS_ON(power) && !POWER_IS_ON(lcd->power))
+ ret = s6e63m0_power_on(lcd);
+ else if (!POWER_IS_ON(power) && POWER_IS_ON(lcd->power))
+ ret = s6e63m0_power_off(lcd);
+
+ if (!ret)
+ lcd->power = power;
+
+ return ret;
+}
+
+static int s6e63m0_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 s6e63m0_power(lcd, power);
+}
+
+static int s6e63m0_get_power(struct lcd_device *ld)
+{
+ struct lcd_info *lcd = lcd_get_data(ld);
+
+ return lcd->power;
+}
+
+static int s6e63m0_set_brightness(struct backlight_device *bd)
+{
+ int ret = 0;
+ int brightness = bd->props.brightness;
+ struct lcd_info *lcd = bl_get_data(bd);
+
+ /* dev_info(&lcd->ld->dev, "%s: brightness=%d\n",
+ __func__, 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, MAX_BRIGHTNESS, brightness);
+ return -EINVAL;
+ }
+
+ if (lcd->ldi_enable) {
+ ret = update_brightness(lcd, 0);
+ if (ret < 0) {
+ dev_err(lcd->dev, "err in %s\n", __func__);
+ return -EINVAL;
+ }
+ }
+
+ return ret;
+}
+
+static int s6e63m0_get_brightness(struct backlight_device *bd)
+{
+ struct lcd_info *lcd = bl_get_data(bd);
+
+ return candela_table[lcd->bl];
+}
+
+static struct lcd_ops s6e63m0_lcd_ops = {
+ .set_power = s6e63m0_set_power,
+ .get_power = s6e63m0_get_power,
+};
+
+static const struct backlight_ops s6e63m0_backlight_ops = {
+ .get_brightness = s6e63m0_get_brightness,
+ .update_status = s6e63m0_set_brightness,
+};
+
+static ssize_t power_reduce_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct lcd_info *lcd = dev_get_drvdata(dev);
+ char temp[3];
+
+ sprintf(temp, "%d\n", lcd->acl_enable);
+ strcpy(buf, temp);
+
+ return strlen(buf);
+}
+
+static ssize_t power_reduce_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t size)
+{
+ struct lcd_info *lcd = 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 (lcd->acl_enable != value) {
+ dev_info(dev, "%s - %d, %d\n",
+ __func__, lcd->acl_enable, value);
+ mutex_lock(&lcd->bl_lock);
+ lcd->acl_enable = value;
+ if (lcd->ldi_enable)
+ s6e63m0_set_acl(lcd);
+ mutex_unlock(&lcd->bl_lock);
+ }
+ }
+ return size;
+}
+
+static DEVICE_ATTR(power_reduce, 0664, power_reduce_show,
+ power_reduce_store);
+
+static ssize_t lcd_type_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ char temp[15];
+#if defined(CONFIG_MACH_Q1_BD)
+ sprintf(temp, "SMD_AMS529HA01\n");
+#else
+ sprintf(temp, "SMD_AMS480GYXX\n");
+#endif
+ strcat(buf, temp);
+ return strlen(buf);
+}
+
+static DEVICE_ATTR(lcd_type, 0444, lcd_type_show, NULL);
+
+static ssize_t gamma_table_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct lcd_info *lcd = dev_get_drvdata(dev);
+ int i, j;
+
+ for (i = 0; i < GAMMA_MAX; i++) {
+ for (j = 0; j < GAMMA_PARAM_SIZE; j++)
+ pr_info("0x%02x, ", lcd->gamma_table[i][j]);
+ pr_info("\n");
+ }
+
+ for (i = 0; i < ELVSS_STATUS_MAX; i++) {
+ for (j = 0; j < ELVSS_PARAM_SIZE; j++)
+ pr_info("0x%02x, ", lcd->elvss_table[i][j]);
+ pr_info("\n");
+ }
+
+ return strlen(buf);
+}
+static DEVICE_ATTR(gamma_table, 0444, gamma_table_show, NULL);
+
+static ssize_t auto_brightness_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct lcd_info *lcd = dev_get_drvdata(dev);
+ char temp[3];
+
+ sprintf(temp, "%d\n", lcd->auto_brightness);
+ strcpy(buf, temp);
+
+ return strlen(buf);
+}
+
+static ssize_t auto_brightness_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t size)
+{
+ struct lcd_info *lcd = 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 (lcd->auto_brightness != value) {
+ dev_info(dev, "%s - %d, %d\n",
+ __func__, lcd->auto_brightness, value);
+ mutex_lock(&lcd->bl_lock);
+ lcd->auto_brightness = value;
+ mutex_unlock(&lcd->bl_lock);
+ if (lcd->ldi_enable)
+ update_brightness(lcd, 0);
+ }
+ }
+ return size;
+}
+
+static DEVICE_ATTR(auto_brightness, 0644, auto_brightness_show,
+ auto_brightness_store);
+
+#ifdef CONFIG_HAS_EARLYSUSPEND
+struct lcd_info *g_lcd;
+
+void s6e63m0_early_suspend(void)
+{
+ struct lcd_info *lcd = g_lcd;
+
+ set_dsim_lcd_enabled(0);
+
+ dev_info(&lcd->ld->dev, "+%s\n", __func__);
+#if defined(GPIO_OLED_DET)
+ disable_irq(lcd->irq);
+ gpio_request(GPIO_OLED_DET, "OLED_DET");
+ s3c_gpio_cfgpin(GPIO_OLED_DET, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_OLED_DET, S3C_GPIO_PULL_NONE);
+ gpio_direction_output(GPIO_OLED_DET, GPIO_LEVEL_LOW);
+ gpio_free(GPIO_OLED_DET);
+#endif
+ s6e63m0_power(lcd, FB_BLANK_POWERDOWN);
+ dev_info(&lcd->ld->dev, "-%s\n", __func__);
+
+ return ;
+}
+
+void s6e63m0_late_resume(void)
+{
+ struct lcd_info *lcd = g_lcd;
+
+ dev_info(&lcd->ld->dev, "+%s\n", __func__);
+ s6e63m0_power(lcd, FB_BLANK_UNBLANK);
+#if defined(GPIO_OLED_DET)
+ s3c_gpio_cfgpin(GPIO_OLED_DET, S3C_GPIO_SFN(0xf));
+ s3c_gpio_setpull(GPIO_OLED_DET, S3C_GPIO_PULL_NONE);
+ enable_irq(lcd->irq);
+#endif
+ dev_info(&lcd->ld->dev, "-%s\n", __func__);
+
+ set_dsim_lcd_enabled(1);
+
+ return ;
+}
+#endif
+
+#ifdef CONFIG_INPUT_FLIP
+void samsung_switching_lcd_suspend(int init, int flip)
+{
+ pr_info("%s: flip %s\n", __func__, (flip) ? "OPEN" : "CLOSE");
+ s6e63m0_early_suspend();/*LCD suspend*/
+ s5p_dsim_early_suspend();/*MIPI suspend*/
+}
+EXPORT_SYMBOL(samsung_switching_lcd_suspend);
+
+void samsung_switching_lcd_resume(int init, int flip)
+{
+ pr_info("%s: flip %s\n", __func__, (flip) ? "OPEN" : "CLOSE");
+ s5p_dsim_late_resume();/*MIPI wakeup*/
+#if 0
+ if (s5p_dsim_fifo_clear() == 0) {
+ s5p_dsim_early_suspend();
+ msleep(10);
+ s5p_dsim_late_resume();
+ if (s5p_dsim_fifo_clear() == 0)
+ pr_info("dsim resume fail!!!\n");
+ }
+#endif
+ s6e63m0_late_resume();/*LCD wakeup*/
+}
+EXPORT_SYMBOL(samsung_switching_lcd_resume);
+#endif
+
+static void s6e63m0_read_id(struct lcd_info *lcd, u8 *buf)
+{
+ int ret = 0;
+
+ ret = s6e63m0_read(lcd, LDI_ID_REG, LDI_ID_LEN, buf, 3);
+ if (!ret) {
+ lcd->connected = 0;
+ dev_info(&lcd->ld->dev, "panel is not connected well\n");
+ }
+}
+
+#ifdef SMART_DIMMING
+static int s6e63m0_read_mtp(struct lcd_info *lcd, u8 *mtp_data)
+{
+ int ret;
+
+ ret = s6e63m0_read(lcd, LDI_MTP_ADDR, LDI_MTP_LENGTH, mtp_data, 0);
+
+ return ret;
+}
+
+#if defined(CONFIG_MACH_Q1_BD)
+static void s6e63m0_check_id(struct lcd_info *lcd, u8 *idbuf)
+{
+ u32 i;
+
+ for (i = 0; i < LDI_ID_LEN; i++)
+ lcd->smart.panelid[i] = idbuf[i];
+
+ if (idbuf[2] == 0x33)
+ lcd->support_elvss = 0;
+ else {
+ lcd->support_elvss = 1;
+ lcd->elvss.limit = (idbuf[2] & 0xc0) >> 6;
+ lcd->elvss.reference = idbuf[2] & 0x3f;
+ printk(KERN_DEBUG "Dynamic ELVSS Information, 0x%x\n",
+ lcd->elvss.reference);
+ }
+}
+#else
+static void s6e63m0_check_id(struct lcd_info *lcd, u8 *idbuf)
+{
+ int i;
+
+ for (i = 0; i < LDI_ID_LEN; i++)
+ lcd->smart.panelid[i] = idbuf[i];
+
+ if (idbuf[0] == PANEL_A1_M3)
+ lcd->support_elvss = 0;
+ else {
+ lcd->support_elvss = 1;
+ lcd->elvss.reference = idbuf[2] & (BIT(0) | BIT(1) |
+ BIT(2) | BIT(3) | BIT(4));
+ printk(KERN_DEBUG "Dynamic ELVSS Information, 0x%x\n",
+ lcd->elvss.reference);
+ }
+}
+#endif
+#endif
+
+static int s6e63m0_probe(struct device *dev)
+{
+ int ret = 0;
+ struct lcd_info *lcd;
+#ifdef SMART_DIMMING
+ u8 mtp_data[LDI_MTP_LENGTH] = {0,};
+#endif
+
+ 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, &s6e63m0_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->bd = backlight_device_register("panel", dev, lcd,
+ &s6e63m0_backlight_ops, NULL);
+ if (IS_ERR(lcd->bd)) {
+ pr_err("failed to register backlight device\n");
+ ret = PTR_ERR(lcd->bd);
+ goto out_free_backlight;
+ }
+
+ lcd->dev = dev;
+ lcd->dsim = (struct dsim_global *)dev_get_drvdata(dev->parent);
+ lcd->bd->props.max_brightness = MAX_BRIGHTNESS;
+ lcd->bd->props.brightness = DEFAULT_BRIGHTNESS;
+ lcd->bl = DEFAULT_GAMMA_LEVEL;
+ lcd->current_bl = lcd->bl;
+
+ lcd->acl_enable = 0;
+ lcd->cur_acl = 0;
+
+ lcd->power = FB_BLANK_UNBLANK;
+ lcd->ldi_enable = 1;
+ lcd->connected = 1;
+ lcd->auto_brightness = 0;
+
+ ret = device_create_file(&lcd->ld->dev, &dev_attr_power_reduce);
+ if (ret < 0)
+ dev_err(&lcd->ld->dev, "failed to add sysfs entries, %d\n",
+ __LINE__);
+
+ ret = device_create_file(&lcd->ld->dev, &dev_attr_lcd_type);
+ if (ret < 0)
+ dev_err(&lcd->ld->dev, "failed to add sysfs entries, %d\n",
+ __LINE__);
+
+ ret = device_create_file(&lcd->ld->dev, &dev_attr_gamma_table);
+ if (ret < 0)
+ dev_err(&lcd->ld->dev, "failed to add sysfs entries, %d\n",
+ __LINE__);
+
+ ret = device_create_file(&lcd->bd->dev, &dev_attr_auto_brightness);
+ if (ret < 0)
+ dev_err(&lcd->ld->dev, "failed to add sysfs entries, %d\n",
+ __LINE__);
+
+ dev_set_drvdata(dev, lcd);
+
+ mutex_init(&lcd->lock);
+ mutex_init(&lcd->bl_lock);
+#if !defined(CONFIG_MACH_M0_GRANDECTC) && !defined(CONFIG_MACH_IRON)
+ s6e63m0_read_id(lcd, lcd->id);
+
+ dev_info(&lcd->ld->dev, "ID: %x, %x, %x\n", lcd->id[0],
+ lcd->id[1], lcd->id[2]);
+#endif
+
+ dev_info(&lcd->ld->dev, "s6e63m0 lcd panel driver has been probed.\n");
+
+#ifdef SMART_DIMMING
+#if !defined(CONFIG_MACH_M0_GRANDECTC) && !defined(CONFIG_MACH_IRON)
+ s6e63m0_check_id(lcd, lcd->id);
+#endif
+
+ init_table_info(&lcd->smart);
+#if !defined(CONFIG_MACH_M0_GRANDECTC) && !defined(CONFIG_MACH_IRON)
+ ret = s6e63m0_read_mtp(lcd, mtp_data);
+ if (!ret) {
+ printk(KERN_ERR "[LCD:ERROR] : %s read mtp failed\n", __func__);
+ /*return -EPERM;*/
+ }
+#endif
+
+ calc_voltage_table(&lcd->smart, mtp_data);
+
+ if (lcd->support_elvss)
+ ret = init_elvss_table(lcd);
+
+ ret = init_gamma_table(lcd);
+
+#ifdef CONFIG_AID_DIMMING
+#if !defined(CONFIG_MACH_M0_GRANDECTC) && !defined(CONFIG_MACH_IRON)
+ if (lcd->id[1] == 0x20) {
+ printk(KERN_INFO "AID Dimming is started\n");
+ lcd->support_aid = 1;
+ ret += init_aid_dimming_table(lcd);
+ memcpy(lcd->f8, SEQ_PANEL_CONDITION_SET_500MBPS,
+ AID_PARAM_SIZE);
+ }
+#endif
+#endif
+
+ if (ret) {
+ lcd->gamma_table = (unsigned char **)gamma22_table;
+ lcd->elvss_table = (unsigned char **)ELVSS_TABLE;
+ }
+
+ update_brightness(lcd, 1);
+#endif
+
+#if defined(GPIO_OLED_DET)
+ if (lcd->connected) {
+ INIT_DELAYED_WORK(&hs_clk_re_try, hs_clk_re_try_work);
+
+ lcd->irq = gpio_to_irq(GPIO_OLED_DET);
+
+ s3c_gpio_cfgpin(GPIO_OLED_DET, S3C_GPIO_SFN(0xf));
+ s3c_gpio_setpull(GPIO_OLED_DET, S3C_GPIO_PULL_NONE);
+ if (request_irq(lcd->irq, oled_det_int,
+ IRQF_TRIGGER_FALLING, "esd_detection", 0))
+ pr_err("failed to reqeust irq. %d\n", lcd->irq);
+ }
+#endif
+
+ lcd_early_suspend = s6e63m0_early_suspend;
+ lcd_late_resume = s6e63m0_late_resume;
+
+ return 0;
+
+out_free_backlight:
+ lcd_device_unregister(lcd->ld);
+ kfree(lcd);
+ return ret;
+
+out_free_lcd:
+ kfree(lcd);
+ return ret;
+
+err_alloc:
+ return ret;
+}
+
+static int __devexit s6e63m0_remove(struct device *dev)
+{
+ struct lcd_info *lcd = dev_get_drvdata(dev);
+
+ s6e63m0_power(lcd, FB_BLANK_POWERDOWN);
+ lcd_device_unregister(lcd->ld);
+ backlight_device_unregister(lcd->bd);
+ kfree(lcd);
+
+ return 0;
+}
+
+/* Power down all displays on reboot, poweroff or halt. */
+static void s6e63m0_shutdown(struct device *dev)
+{
+ struct lcd_info *lcd = dev_get_drvdata(dev);
+
+ dev_info(&lcd->ld->dev, "%s\n", __func__);
+
+ s6e63m0_power(lcd, FB_BLANK_POWERDOWN);
+}
+
+static struct mipi_lcd_driver s6e63m0_mipi_driver = {
+ .name = "s6e63m0",
+ .probe = s6e63m0_probe,
+ .remove = __devexit_p(s6e63m0_remove),
+ .shutdown = s6e63m0_shutdown,
+};
+
+static int s6e63m0_init(void)
+{
+ return s5p_dsim_register_lcd_driver(&s6e63m0_mipi_driver);
+}
+
+static void s6e63m0_exit(void)
+{
+ return;
+}
+
+module_init(s6e63m0_init);
+module_exit(s6e63m0_exit);
+
+MODULE_DESCRIPTION("MIPI-DSI S6E63M0:AMS397GEXX (480X800) Panel Driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/video/samsung/s3cfb_s6e8aa0.c b/drivers/video/samsung/s3cfb_s6e8aa0.c
index ff94492..00b543e 100644
--- a/drivers/video/samsung/s3cfb_s6e8aa0.c
+++ b/drivers/video/samsung/s3cfb_s6e8aa0.c
@@ -88,7 +88,7 @@ struct lcd_info {
unsigned int bl;
unsigned int auto_brightness;
unsigned int acl_enable;
- unsigned int cur_acl;
+ unsigned int current_acl;
unsigned int current_bl;
unsigned int current_elvss;
@@ -131,6 +131,7 @@ struct lcd_info {
#ifdef CONFIG_AID_DIMMING
static const unsigned int candela_table[GAMMA_MAX] = {
20, 30, 40, 50, 60, 70, 80, 90, 100,
+ 102, 104, 106, 108,
110, 120, 130, 140, 150, 160, 170, 180,
182, 184, 186, 188,
190, 200, 210, 220, 230, 240, 250, MAX_GAMMA-1
@@ -138,9 +139,9 @@ static const unsigned int candela_table[GAMMA_MAX] = {
static unsigned int aid_candela_table[GAMMA_MAX] = {
base_20to100, base_20to100, base_20to100, base_20to100, base_20to100, base_20to100, base_20to100, base_20to100, base_20to100,
- AOR40_BASE_110, AOR40_BASE_120, AOR40_BASE_130, AOR40_BASE_140, AOR40_BASE_150,
- AOR40_BASE_160, AOR40_BASE_170, AOR40_BASE_180, AOR40_BASE_182, AOR40_BASE_184,
- AOR40_BASE_186, AOR40_BASE_188,
+ AOR40_BASE_102, AOR40_BASE_104, AOR40_BASE_106, AOR40_BASE_108,
+ AOR40_BASE_110, AOR40_BASE_120, AOR40_BASE_130, AOR40_BASE_140, AOR40_BASE_150, AOR40_BASE_160, AOR40_BASE_170, AOR40_BASE_180,
+ AOR40_BASE_182, AOR40_BASE_184, AOR40_BASE_186, AOR40_BASE_188,
190, 200, 210, 220, 230, 240, 250, MAX_GAMMA-1
};
@@ -181,6 +182,9 @@ static unsigned int elvss_offset_table[ELVSS_STATUS_MAX] = {
};
#endif
+extern void (*lcd_early_suspend)(void);
+extern void (*lcd_late_resume)(void);
+
#if defined(GPIO_OLED_DET)
static void oled_detection_work(struct work_struct *work)
{
@@ -286,76 +290,100 @@ static int get_backlight_level_from_brightness(int brightness)
switch (brightness) {
case 0 ... 29:
- backlightlevel = GAMMA_30CD; //GAMMA_20CD;
+ backlightlevel = GAMMA_20CD;
break;
case 30 ... 39:
- backlightlevel = GAMMA_40CD; //GAMMA_30CD;
+ backlightlevel = GAMMA_30CD;
break;
case 40 ... 49:
- backlightlevel = GAMMA_50CD; //GAMMA_40CD;
+ backlightlevel = GAMMA_40CD;
break;
case 50 ... 59:
- backlightlevel = GAMMA_60CD; //GAMMA_50CD;
+ backlightlevel = GAMMA_50CD;
break;
case 60 ... 69:
- backlightlevel = GAMMA_70CD; //GAMMA_60CD;
+ backlightlevel = GAMMA_60CD;
break;
case 70 ... 79:
- backlightlevel = GAMMA_80CD; //GAMMA_70CD;
+ backlightlevel = GAMMA_70CD;
break;
case 80 ... 89:
- backlightlevel = GAMMA_90CD; //GAMMA_80CD;
+ backlightlevel = GAMMA_80CD;
break;
case 90 ... 99:
- backlightlevel = GAMMA_100CD; //GAMMA_90CD;
+ backlightlevel = GAMMA_90CD;
+ break;
+ case 100 ... 101:
+ backlightlevel = GAMMA_100CD;
+ break;
+ case 102 ... 103:
+ backlightlevel = GAMMA_102CD;
+ break;
+ case 104 ... 105:
+ backlightlevel = GAMMA_104CD;
+ break;
+ case 106 ... 107:
+ backlightlevel = GAMMA_106CD;
break;
- case 100 ... 109:
- backlightlevel = GAMMA_110CD; //GAMMA_100CD;
+ case 108 ... 109:
+ backlightlevel = GAMMA_108CD;
break;
case 110 ... 119:
- backlightlevel = GAMMA_130CD; //GAMMA_110CD;
+ backlightlevel = GAMMA_110CD;
break;
case 120 ... 129:
- backlightlevel = GAMMA_140CD; //GAMMA_120CD;
+ backlightlevel = GAMMA_120CD;
break;
case 130 ... 139:
- backlightlevel = GAMMA_150CD; //GAMMA_130CD;
+ backlightlevel = GAMMA_130CD;
break;
case 140 ... 149:
- backlightlevel = GAMMA_160CD; //GAMMA_140CD;
+ backlightlevel = GAMMA_140CD;
break;
case 150 ... 159:
- backlightlevel = GAMMA_180CD; //GAMMA_150CD;
+ backlightlevel = GAMMA_150CD;
break;
case 160 ... 169:
- backlightlevel = GAMMA_190CD; //GAMMA_160CD;
+ backlightlevel = GAMMA_160CD;
break;
case 170 ... 179:
- backlightlevel = GAMMA_200CD; //GAMMA_170CD;
+ backlightlevel = GAMMA_170CD;
break;
- case 180 ... 189:
- backlightlevel = GAMMA_210CD;
+ case 180 ... 181:
+ backlightlevel = GAMMA_180CD;
+ break;
+ case 182 ... 183:
+ backlightlevel = GAMMA_182CD;
+ break;
+ case 184 ... 185:
+ backlightlevel = GAMMA_184CD;
+ break;
+ case 186 ... 187:
+ backlightlevel = GAMMA_186CD;
+ break;
+ case 188 ... 189:
+ backlightlevel = GAMMA_188CD;
break;
case 190 ... 199:
- backlightlevel = GAMMA_220CD; //GAMMA_190CD;
+ backlightlevel = GAMMA_190CD;
break;
case 200 ... 209:
- backlightlevel = GAMMA_230CD; //GAMMA_200CD;
+ backlightlevel = GAMMA_200CD;
break;
case 210 ... 219:
- backlightlevel = GAMMA_240CD; //GAMMA_210CD;
+ backlightlevel = GAMMA_210CD;
break;
case 220 ... 229:
- backlightlevel = GAMMA_240CD; //GAMMA_220CD;
+ backlightlevel = GAMMA_220CD;
break;
case 230 ... 239:
- backlightlevel = GAMMA_250CD; //GAMMA_230CD;
+ backlightlevel = GAMMA_230CD;
break;
case 240 ... 249:
- backlightlevel = GAMMA_250CD; //GAMMA_240CD;
+ backlightlevel = GAMMA_240CD;
break;
case 250 ... 254:
- backlightlevel = GAMMA_300CD; //GAMMA_250CD;
+ backlightlevel = GAMMA_250CD;
break;
case 255:
backlightlevel = GAMMA_300CD;
@@ -367,14 +395,24 @@ static int get_backlight_level_from_brightness(int brightness)
return backlightlevel;
}
-static int s6e8ax0_aid_parameter_ctl(struct lcd_info *lcd , u8 force)
+static int s6e8ax0_aid_parameter_ctl(struct lcd_info *lcd, u8 force)
{
- if (likely(lcd->support_aid)) {
- if ((lcd->f8[lcd->bl][0x12] != lcd->f8[lcd->current_bl][0x12]) ||
- (lcd->f8[lcd->bl][0x01] != lcd->f8[lcd->current_bl][0x01]) || (force))
- s6e8ax0_write(lcd, lcd->f8[lcd->bl], AID_PARAM_SIZE);
- }
+ if (unlikely(!lcd->support_aid))
+ goto exit;
+
+ if (force)
+ goto aid_update;
+ else if (aid_command_table[lcd->bl][0] != aid_command_table[lcd->current_bl][0])
+ goto aid_update;
+ else if (aid_command_table[lcd->bl][1] != aid_command_table[lcd->current_bl][1])
+ goto aid_update;
+ else
+ goto exit;
+aid_update:
+ s6e8ax0_write(lcd, lcd->f8[lcd->bl], AID_PARAM_SIZE);
+
+exit:
return 0;
}
#else
@@ -414,149 +452,112 @@ static int s6e8ax0_gamma_ctl(struct lcd_info *lcd)
}
#if defined(CONFIG_S6E8AA0_AMS529HA01)
-static int s6e8ax0_set_acl(struct lcd_info *lcd)
+static int s6e8ax0_set_acl(struct lcd_info *lcd, u8 force)
{
- int ret = 0;
+ int ret = 0, enable, level;
+ u32 candela = candela_table[lcd->bl];
- if (lcd->acl_enable) {
- if (lcd->cur_acl == 0) {
- if (lcd->bl == 0 || lcd->bl == 1) {
- s6e8ax0_write(lcd, SEQ_ACL_OFF, ARRAY_SIZE(SEQ_ACL_OFF));
- dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d, acl_off\n", __func__, lcd->cur_acl);
- } else {
- s6e8ax0_write(lcd, SEQ_ACL_ON, ARRAY_SIZE(SEQ_ACL_ON));
- dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d, acl_on\n", __func__, lcd->cur_acl);
- }
- }
- switch (lcd->bl) {
- case GAMMA_30CD... GAMMA_40CD:
- if (lcd->cur_acl != 0) {
- s6e8ax0_write(lcd, SEQ_ACL_OFF, ARRAY_SIZE(SEQ_ACL_OFF));
- lcd->cur_acl = 0;
- dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d\n", __func__, lcd->cur_acl);
- }
- break;
- case GAMMA_50CD:
- if (lcd->cur_acl != 200) {
- s6e8ax0_write(lcd, ACL_CUTOFF_TABLE[ACL_STATUS_20P], ACL_PARAM_SIZE);
- lcd->cur_acl = 200;
- dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d\n", __func__, lcd->cur_acl);
- }
- break;
- case GAMMA_60CD:
- if (lcd->cur_acl != 330) {
- s6e8ax0_write(lcd, ACL_CUTOFF_TABLE[ACL_STATUS_33P], ACL_PARAM_SIZE);
- lcd->cur_acl = 330;
- dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d\n", __func__, lcd->cur_acl);
- }
- break;
- case GAMMA_70CD:
- if (lcd->cur_acl != 430) {
- s6e8ax0_write(lcd, ACL_CUTOFF_TABLE[ACL_STATUS_43P], ACL_PARAM_SIZE);
- lcd->cur_acl = 430;
- dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d\n", __func__, lcd->cur_acl);
- }
- break;
- case GAMMA_80CD:
- if (lcd->cur_acl != 450) {
- s6e8ax0_write(lcd, ACL_CUTOFF_TABLE[ACL_STATUS_45P_80CD], ACL_PARAM_SIZE);
- lcd->cur_acl = 450;
- dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d\n", __func__, lcd->cur_acl);
- }
- break;
- case GAMMA_90CD ... GAMMA_150CD:
- if (lcd->cur_acl != 451) {
- s6e8ax0_write(lcd, ACL_CUTOFF_TABLE[ACL_STATUS_45P], ACL_PARAM_SIZE);
- lcd->cur_acl = 451;
- dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d\n", __func__, lcd->cur_acl);
- }
- break;
- case GAMMA_160CD: /* 160cd */
- if (lcd->cur_acl != 460) {
- s6e8ax0_write(lcd, ACL_CUTOFF_TABLE[ACL_STATUS_46P_160CD], ACL_PARAM_SIZE);
- lcd->cur_acl = 460;
- dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d\n", __func__, lcd->cur_acl);
- }
- break;
- case GAMMA_170CD ... GAMMA_250CD:
- if (lcd->cur_acl != 461) {
- s6e8ax0_write(lcd, ACL_CUTOFF_TABLE[ACL_STATUS_46P], ACL_PARAM_SIZE);
- lcd->cur_acl = 461;
- dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d\n", __func__, lcd->cur_acl);
- }
- break;
- default:
- if (lcd->cur_acl != 550) {
- s6e8ax0_write(lcd, ACL_CUTOFF_TABLE[ACL_STATUS_50P], ACL_PARAM_SIZE);
- lcd->cur_acl = 550;
- dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d\n", __func__, lcd->cur_acl);
- }
- break;
- }
- } else {
- s6e8ax0_write(lcd, SEQ_ACL_OFF, ARRAY_SIZE(SEQ_ACL_OFF));
- lcd->cur_acl = 0;
- dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d, acl_off\n", __func__, lcd->cur_acl);
+ switch (candela) {
+ case 0 ... 49:
+ level = ACL_STATUS_0P;
+ break;
+ case 50 ... 59:
+ level = ACL_STATUS_20P;
+ break;
+ case 60 ... 69:
+ level = ACL_STATUS_33P;
+ break;
+ case 70 ... 79:
+ level = ACL_STATUS_43P;
+ break;
+ case 80 ... 89:
+ level = ACL_STATUS_45P_80CD;
+ break;
+ case 90 ... 159:
+ level = ACL_STATUS_45P;
+ break;
+ case 160 ... 169:
+ level = ACL_STATUS_46P_160CD;
+ break;
+ case 170 ... 250:
+ level = ACL_STATUS_46P;
+ break;
+ default:
+ level = ACL_STATUS_50P;
+ break;
}
- if (ret) {
+ if (!lcd->acl_enable)
+ level = ACL_STATUS_0P;
+
+ enable = !!level;
+
+ //if (force || lcd->acl_enable != enable) {
+ dev_dbg(&lcd->ld->dev, "acl turn %s\n", enable ? "on" : "off");
+ if (enable)
+ ret = s6e8ax0_write(lcd, SEQ_ACL_ON, ARRAY_SIZE(SEQ_ACL_ON));
+ else {
+ ret = s6e8ax0_write(lcd, SEQ_ACL_OFF, ARRAY_SIZE(SEQ_ACL_OFF));
+ goto exit;
+ }
+ //}
+
+ //if (force || lcd->current_acl != level) {
+ ret = s6e8ax0_write(lcd, ACL_CUTOFF_TABLE[level], ACL_PARAM_SIZE);
+ lcd->current_acl = level;
+ dev_dbg(&lcd->ld->dev, "current_acl = %d\n", lcd->current_acl);
+ //}
+
+ if (ret)
ret = -EPERM;
- goto acl_err;
- }
-acl_err:
+exit:
return ret;
}
#else
-static int s6e8ax0_set_acl(struct lcd_info *lcd)
+static int s6e8ax0_set_acl(struct lcd_info *lcd, u8 force)
{
- if (lcd->acl_enable) {
- if (lcd->cur_acl == 0) {
- if (lcd->bl == 0) {
- s6e8ax0_write(lcd, SEQ_ACL_OFF, ARRAY_SIZE(SEQ_ACL_OFF));
- dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d, acl_off\n", __func__, lcd->cur_acl);
- } else {
- s6e8ax0_write(lcd, SEQ_ACL_ON, ARRAY_SIZE(SEQ_ACL_ON));
- dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d, acl_on\n", __func__, lcd->cur_acl);
- }
- }
- switch (lcd->bl) {
- case 0:
- if (lcd->cur_acl != 0) {
- s6e8ax0_write(lcd, SEQ_ACL_OFF, ARRAY_SIZE(SEQ_ACL_OFF));
- lcd->cur_acl = 0;
- dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d\n", __func__, lcd->cur_acl);
- }
- break;
- case 1:
- if (lcd->cur_acl != 33) {
- s6e8ax0_write(lcd, ACL_CUTOFF_TABLE[ACL_STATUS_33P], ACL_PARAM_SIZE);
- lcd->cur_acl = 33;
- dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d\n", __func__, lcd->cur_acl);
- }
- break;
- case 2 ... GAMMA_250CD:
- if (lcd->cur_acl != 40) {
- s6e8ax0_write(lcd, ACL_CUTOFF_TABLE[ACL_STATUS_40P], ACL_PARAM_SIZE);
- lcd->cur_acl = 40;
- dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d\n", __func__, lcd->cur_acl);
- }
- break;
- default:
- if (lcd->cur_acl != 50) {
- s6e8ax0_write(lcd, ACL_CUTOFF_TABLE[ACL_STATUS_50P], ACL_PARAM_SIZE);
- lcd->cur_acl = 50;
- dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d\n", __func__, lcd->cur_acl);
- }
- break;
- }
- } else {
- s6e8ax0_write(lcd, SEQ_ACL_OFF, ARRAY_SIZE(SEQ_ACL_OFF));
- lcd->cur_acl = 0;
- dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d, acl_off\n", __func__, lcd->cur_acl);
+ int ret = 0, enable, level;
+ u32 candela = candela_table[lcd->bl];
+
+ switch (candela) {
+ case 0 ... 29:
+ level = ACL_STATUS_0P;
+ break;
+ case 30 ... 39:
+ level = ACL_STATUS_33P;
+ break;
+ default:
+ level = ACL_STATUS_40P;
+ break;
}
- return 0;
+ if ((!lcd->acl_enable) || (lcd->auto_brightness >= 5))
+ level = ACL_STATUS_0P;
+
+ enable = !!level;
+
+ //if (force || lcd->acl_enable != enable) {
+ dev_dbg(&lcd->ld->dev, "acl turn %s\n", enable ? "on" : "off");
+ if (enable)
+ ret = s6e8ax0_write(lcd, SEQ_ACL_ON, ARRAY_SIZE(SEQ_ACL_ON));
+ else {
+ ret = s6e8ax0_write(lcd, SEQ_ACL_OFF, ARRAY_SIZE(SEQ_ACL_OFF));
+ goto exit;
+ }
+ //}
+
+ //if (force || lcd->current_acl != level) {
+ ret = s6e8ax0_write(lcd, ACL_CUTOFF_TABLE[level], ACL_PARAM_SIZE);
+ lcd->current_acl = level;
+ dev_dbg(&lcd->ld->dev, "current_acl = %d\n", lcd->current_acl);
+ //}
+
+ if (ret)
+ ret = -EPERM;
+
+exit:
+ return ret;
}
#endif
@@ -630,7 +631,7 @@ static int s6e8ax0_set_elvss(struct lcd_info *lcd, u8 force)
break;
}
- if ((lcd->current_elvss != lcd->elvss_table[elvss_level][2]) || force) {
+ if (force || lcd->current_elvss != lcd->elvss_table[elvss_level][2]) {
ret = s6e8ax0_write(lcd, lcd->elvss_table[elvss_level], ELVSS_PARAM_SIZE);
lcd->current_elvss = lcd->elvss_table[elvss_level][2];
}
@@ -668,7 +669,7 @@ static int s6e8ax0_set_elvss(struct lcd_info *lcd, u8 force)
break;
}
- if ((lcd->current_elvss != lcd->elvss_table[elvss_level][2]) || force) {
+ if (force || lcd->current_elvss != lcd->elvss_table[elvss_level][2]) {
ret = s6e8ax0_write(lcd, lcd->elvss_table[elvss_level], ELVSS_PARAM_SIZE);
lcd->current_elvss = lcd->elvss_table[elvss_level][2];
}
@@ -893,16 +894,12 @@ static int update_brightness(struct lcd_info *lcd, u8 force)
lcd->bl = get_backlight_level_from_brightness(brightness);
if ((force) || ((lcd->ldi_enable) && (lcd->current_bl != lcd->bl))) {
+ s6e8ax0_gamma_ctl(lcd);
#ifdef CONFIG_AID_DIMMING
- if ((force) || unlikely(aid_candela_table[lcd->bl] != aid_candela_table[lcd->current_bl]))
-#endif
- s6e8ax0_gamma_ctl(lcd);
-
-#ifdef CONFIG_AID_DIMMING
- s6e8ax0_aid_parameter_ctl(lcd , force);
+ s6e8ax0_aid_parameter_ctl(lcd, force);
#endif
- s6e8ax0_set_acl(lcd);
+ s6e8ax0_set_acl(lcd, force);
s6e8ax0_set_elvss(lcd, force);
@@ -1152,9 +1149,9 @@ static ssize_t power_reduce_store(struct device *dev,
dev_info(dev, "%s - %d, %d\n", __func__, lcd->acl_enable, value);
mutex_lock(&lcd->bl_lock);
lcd->acl_enable = value;
- if (lcd->ldi_enable)
- s6e8ax0_set_acl(lcd);
mutex_unlock(&lcd->bl_lock);
+ if (lcd->ldi_enable)
+ update_brightness(lcd, 1);
}
}
return size;
@@ -1228,7 +1225,7 @@ static ssize_t auto_brightness_store(struct device *dev,
lcd->auto_brightness = value;
mutex_unlock(&lcd->bl_lock);
if (lcd->ldi_enable)
- update_brightness(lcd, 0);
+ update_brightness(lcd, 1);
}
}
return size;
@@ -1336,6 +1333,29 @@ static void s6e8aa0_check_id(struct lcd_info *lcd, u8 *idbuf)
#endif
#endif
+static ssize_t read_acl_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct lcd_info *lcd = dev_get_drvdata(dev);
+ char *pos = buf;
+ char temp[ACL_PARAM_SIZE] = {0,};
+ u32 i;
+
+ s6e8ax0_read(lcd, 0xC0, 3, temp, 0);
+ pos += sprintf(pos, "0xC0=0x%02x, 0x%02x\n", temp[0], temp[1]);
+
+ s6e8ax0_read(lcd, 0xC1, ACL_PARAM_SIZE, temp, 0);
+ for (i = 0; i < ACL_PARAM_SIZE; i++) {
+ pos += sprintf(pos, "0x%02x, ", temp[i]);
+ if ((i % 5) == 0)
+ pos += sprintf(pos, "\n");
+ }
+ pos += sprintf(pos, "\n");
+
+ return pos - buf;
+}
+static DEVICE_ATTR(read_acl, 0444, read_acl_show, NULL);
+
static int s6e8ax0_probe(struct device *dev)
{
int ret = 0;
@@ -1375,7 +1395,7 @@ static int s6e8ax0_probe(struct device *dev)
lcd->current_bl = lcd->bl;
lcd->acl_enable = 0;
- lcd->cur_acl = 0;
+ lcd->current_acl = 0;
lcd->power = FB_BLANK_UNBLANK;
lcd->ldi_enable = 1;
@@ -1394,6 +1414,10 @@ static int s6e8ax0_probe(struct device *dev)
if (ret < 0)
dev_err(&lcd->ld->dev, "failed to add sysfs entries, %d\n", __LINE__);
+ ret = device_create_file(&lcd->ld->dev, &dev_attr_read_acl);
+ if (ret < 0)
+ dev_err(&lcd->ld->dev, "failed to add sysfs entries, %d\n", __LINE__);
+
ret = device_create_file(&lcd->bd->dev, &dev_attr_auto_brightness);
if (ret < 0)
dev_err(&lcd->ld->dev, "failed to add sysfs entries, %d\n", __LINE__);
@@ -1461,6 +1485,10 @@ static int s6e8ax0_probe(struct device *dev)
pr_err("failed to reqeust irq. %d\n", lcd->irq);
}
#endif
+
+ lcd_early_suspend = s6e8ax0_early_suspend;
+ lcd_late_resume = s6e8ax0_late_resume;
+
return 0;
out_free_backlight:
@@ -1518,5 +1546,5 @@ static void s6e8ax0_exit(void)
module_init(s6e8ax0_init);
module_exit(s6e8ax0_exit);
-MODULE_DESCRIPTION("MIPI-DSI S6E8AA0:AMS529HA01 (800x1280) Panel Driver");
+MODULE_DESCRIPTION("MIPI-DSI S6E8AA0: AMS529HA01 (800x1280) / AMS480GYXX (720x1280) Panel Driver");
MODULE_LICENSE("GPL");
diff --git a/drivers/video/samsung/s3cfb_s6e8ab0.c b/drivers/video/samsung/s3cfb_s6e8ab0.c
index bc47c37..76a98d9 100644
--- a/drivers/video/samsung/s3cfb_s6e8ab0.c
+++ b/drivers/video/samsung/s3cfb_s6e8ab0.c
@@ -75,7 +75,7 @@ struct str_elvss {
struct lcd_info {
unsigned int bl;
unsigned int acl_enable;
- unsigned int cur_acl;
+ unsigned int current_acl;
unsigned int current_bl;
unsigned int ldi_enable;
@@ -105,6 +105,9 @@ struct lcd_info {
struct dsim_global *dsim;
};
+extern void (*lcd_early_suspend)(void);
+extern void (*lcd_late_resume)(void);
+
static int s6e8ax0_write(struct lcd_info *lcd, const unsigned char *seq, int len)
{
int size;
@@ -165,101 +168,6 @@ read_retry:
return ret;
}
-#if 0
-static int get_backlight_level_from_brightness(int brightness)
-{
- int backlightlevel;
-
- /* brightness setting from platform is from 0 to 255
- * But in this driver, brightness is only supported from 0 to 24 */
-
- switch (brightness) {
- case 0:
- backlightlevel = GAMMA_30CD;
- break;
- case 1 ... 29:
- backlightlevel = GAMMA_30CD;
- break;
- case 30 ... 34:
- backlightlevel = GAMMA_40CD;
- break;
- case 35 ... 44:
- backlightlevel = GAMMA_50CD;
- break;
- case 45 ... 54:
- backlightlevel = GAMMA_60CD;
- break;
- case 55 ... 64:
- backlightlevel = GAMMA_70CD;
- break;
- case 65 ... 74:
- backlightlevel = GAMMA_80CD;
- break;
- case 75 ... 83:
- backlightlevel = GAMMA_90CD;
- break;
- case 84 ... 93:
- backlightlevel = GAMMA_100CD;
- break;
- case 94 ... 103:
- backlightlevel = GAMMA_105CD;
- break;
- case 104 ... 113:
- backlightlevel = GAMMA_110CD;
- break;
- case 114 ... 122:
- backlightlevel = GAMMA_120CD;
- break;
- case 123 ... 132:
- backlightlevel = GAMMA_130CD;
- break;
- case 133 ... 142:
- backlightlevel = GAMMA_140CD;
- break;
- case 143 ... 152:
- backlightlevel = GAMMA_150CD;
- break;
- case 153 ... 162:
- backlightlevel = GAMMA_160CD;
- break;
- case 163 ... 171:
- backlightlevel = GAMMA_170CD;
- break;
- case 172 ... 181:
- backlightlevel = GAMMA_180CD;
- break;
- case 182 ... 191:
- backlightlevel = GAMMA_190CD;
- break;
- case 192 ... 201:
- backlightlevel = GAMMA_200CD;
- break;
- case 202 ... 210:
- backlightlevel = GAMMA_205CD;
- break;
- case 211 ... 220:
- backlightlevel = GAMMA_210CD;
- break;
- case 221 ... 230:
- backlightlevel = GAMMA_220CD;
- break;
- case 231 ... 240:
- backlightlevel = GAMMA_230CD;
- break;
- case 241 ... 250:
- backlightlevel = GAMMA_240CD;
- break;
- case 251 ... 255:
- backlightlevel = GAMMA_250CD;
- break;
- default:
- backlightlevel = DEFAULT_GAMMA_LEVEL;
- break;
- }
- return backlightlevel;
-}
-#endif
-
static int s6e8ax0_gamma_ctl(struct lcd_info *lcd)
{
/* Gamma Select */
@@ -273,47 +181,45 @@ static int s6e8ax0_gamma_ctl(struct lcd_info *lcd)
return 0;
}
-static int s6e8ax0_set_acl(struct lcd_info *lcd)
+static int s6e8ax0_set_acl(struct lcd_info *lcd, u8 force)
{
- int ret = 0;
+ int ret = 0, enable, level;
+ u32 candela = candela_table[lcd->bl];
- if (lcd->acl_enable) {
- if (lcd->cur_acl == 0) {
- if (lcd->bl == 0 || lcd->bl == 1) {
- s6e8ax0_write(lcd, SEQ_ACL_OFF, ARRAY_SIZE(SEQ_ACL_OFF));
- dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d, acl_off\n", __func__, lcd->cur_acl);
- } else
- s6e8ax0_write(lcd, SEQ_ACL_ON, ARRAY_SIZE(SEQ_ACL_ON));
- dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d, acl_on\n", __func__, lcd->cur_acl);
- }
- switch (lcd->bl) {
- case GAMMA_30CD ... GAMMA_40CD: /* 30cd ~ 40cd */
- if (lcd->cur_acl != 0) {
- s6e8ax0_write(lcd, SEQ_ACL_OFF, ARRAY_SIZE(SEQ_ACL_OFF));
- lcd->cur_acl = 0;
- dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d\n", __func__, lcd->cur_acl);
- }
- break;
- default:
- if (lcd->cur_acl != 40) {
- s6e8ax0_write(lcd, ACL_CUTOFF_TABLE[1], ACL_PARAM_SIZE);
- lcd->cur_acl = 40;
- dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d\n", __func__, lcd->cur_acl);
- }
- break;
- }
- } else {
- s6e8ax0_write(lcd, SEQ_ACL_OFF, ARRAY_SIZE(SEQ_ACL_OFF));
- lcd->cur_acl = 0;
- dev_dbg(&lcd->ld->dev, "%s : cur_acl=%d, acl_off\n", __func__, lcd->cur_acl);
+ switch (candela) {
+ case 0 ... 49:
+ level = ACL_STATUS_0P;
+ break;
+ default:
+ level = ACL_STATUS_40P;
+ break;
}
- if (ret) {
+ if (!lcd->acl_enable)
+ level = ACL_STATUS_0P;
+
+ enable = !!level;
+
+ //if (force || lcd->acl_enable != enable) {
+ dev_dbg(&lcd->ld->dev, "acl turn %s\n", enable ? "on" : "off");
+ if (enable)
+ ret = s6e8ax0_write(lcd, SEQ_ACL_ON, ARRAY_SIZE(SEQ_ACL_ON));
+ else {
+ ret = s6e8ax0_write(lcd, SEQ_ACL_OFF, ARRAY_SIZE(SEQ_ACL_OFF));
+ goto exit;
+ }
+ //}
+
+ //if (force || lcd->current_acl != level) {
+ ret = s6e8ax0_write(lcd, ACL_CUTOFF_TABLE[level], ACL_PARAM_SIZE);
+ lcd->current_acl = level;
+ dev_dbg(&lcd->ld->dev, "current_acl = %d\n", lcd->current_acl);
+ //}
+
+ if (ret)
ret = -EPERM;
- goto acl_err;
- }
-acl_err:
+exit:
return ret;
}
@@ -499,7 +405,7 @@ static int update_brightness(struct lcd_info *lcd, u8 force)
ret = s6e8ax0_gamma_ctl(lcd);
- ret = s6e8ax0_set_acl(lcd);
+ ret = s6e8ax0_set_acl(lcd, force);
ret = s6e8ax0_set_elvss(lcd);
@@ -720,7 +626,7 @@ static ssize_t power_reduce_store(struct device *dev,
dev_info(dev, "%s - %d, %d\n", __func__, lcd->acl_enable, value);
lcd->acl_enable = value;
if (lcd->ldi_enable)
- s6e8ax0_set_acl(lcd);
+ s6e8ax0_set_acl(lcd, 0);
}
}
return size;
@@ -863,7 +769,7 @@ static int s6e8ax0_probe(struct device *dev)
lcd->current_bl = lcd->bl;
lcd->acl_enable = 0;
- lcd->cur_acl = 0;
+ lcd->current_acl = 0;
lcd->power = FB_BLANK_UNBLANK;
lcd->ldi_enable = 1;
@@ -924,6 +830,9 @@ static int s6e8ax0_probe(struct device *dev)
update_brightness(lcd, 1);
#endif
+ lcd_early_suspend = s6e8ax0_early_suspend;
+ lcd_late_resume = s6e8ax0_late_resume;
+
return 0;
out_free_backlight:
diff --git a/drivers/video/samsung/s3cfb_s6evr02.c b/drivers/video/samsung/s3cfb_s6evr02.c
new file mode 100644
index 0000000..dc94822
--- /dev/null
+++ b/drivers/video/samsung/s3cfb_s6evr02.c
@@ -0,0 +1,1352 @@
+/* linux/drivers/video/samsung/s3cfb_s6evr02.c
+ *
+ * MIPI-DSI based AMS555HBxx AMOLED lcd panel 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/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/mutex.h>
+#include <linux/wait.h>
+#include <linux/ctype.h>
+#include <linux/io.h>
+#include <linux/delay.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/gpio.h>
+#include <linux/workqueue.h>
+#include <linux/backlight.h>
+#include <linux/lcd.h>
+#include <linux/rtc.h>
+#include <linux/reboot.h>
+#include <linux/syscalls.h> /* sys_sync */
+#include <plat/gpio-cfg.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 "s5p-dsim.h"
+#include "s3cfb.h"
+#include "s6evr02_param.h"
+
+#define SMART_DIMMING
+#undef SMART_DIMMING_DEBUG
+
+#ifdef SMART_DIMMING
+#include "smart_dimming_s6evr02.h"
+#include "aid_s6evr02.h"
+#endif
+
+
+#define POWER_IS_ON(pwr) ((pwr) <= FB_BLANK_NORMAL)
+
+#define MIN_BRIGHTNESS 0
+#define MAX_BRIGHTNESS 255
+#define MAX_GAMMA 300
+#define DEFAULT_BRIGHTNESS 130
+#define DEFAULT_GAMMA_LEVEL GAMMA_130CD
+
+#define LDI_ID_REG 0xD7
+#define LDI_ID_LEN 3
+#ifdef SMART_DIMMING
+#define LDI_MTP_LENGTH 33
+#define LDI_MTP_ADDR 0xC8
+#endif
+
+struct lcd_info {
+ unsigned int bl;
+ unsigned int auto_brightness;
+ unsigned int acl_enable;
+ unsigned int current_acl;
+ unsigned int current_bl;
+ unsigned int current_elvss;
+ unsigned int ldi_enable;
+ unsigned int power;
+ struct mutex lock;
+ struct mutex bl_lock;
+ struct device *dev;
+ struct lcd_device *ld;
+ struct backlight_device *bd;
+ struct lcd_platform_data *lcd_pd;
+ struct early_suspend early_suspend;
+ unsigned char id[LDI_ID_LEN];
+ unsigned char **gamma_table;
+ unsigned char **elvss_table;
+#ifdef SMART_DIMMING
+ struct str_smart_dim smart;
+ unsigned char aor[GAMMA_MAX][ARRAY_SIZE(SEQ_AOR_CONTROL)];
+#endif
+ unsigned int irq;
+ unsigned int connected;
+
+#if defined(GPIO_ERR_FG)
+ struct delayed_work err_fg_detection;
+ unsigned int err_fg_detection_count;
+#endif
+#if defined(GPIO_OLED_DET)
+ struct delayed_work oled_detection;
+ unsigned int oled_detection_count;
+#endif
+
+ struct dsim_global *dsim;
+};
+
+static const unsigned int candela_table[GAMMA_MAX] = {
+ 20, 30, 40, 50, 60, 70, 80, 90, 100,
+ 102, 104, 106, 108,
+ 110, 120, 130, 140, 150, 160, 170, 180,
+ 182, 184, 186, 188,
+ 190, 200, 210, 220, 230, 240, 250, MAX_GAMMA-1
+};
+
+#ifdef SMART_DIMMING
+static unsigned int aid_candela_table[GAMMA_MAX] = {
+ base_20to100, base_20to100, base_20to100, base_20to100, base_20to100, base_20to100, base_20to100, base_20to100, base_20to100,
+ AOR40_BASE_102, AOR40_BASE_104, AOR40_BASE_106, AOR40_BASE_108,
+ AOR40_BASE_110, AOR40_BASE_120, AOR40_BASE_130, AOR40_BASE_140, AOR40_BASE_150,
+ AOR40_BASE_160, AOR40_BASE_170, AOR40_BASE_180,
+ AOR40_BASE_182, AOR40_BASE_184, AOR40_BASE_186, AOR40_BASE_188,
+ 190, 200, 210, 220, 230, 240, 250, MAX_GAMMA-1
+};
+#endif
+
+extern void (*lcd_early_suspend)(void);
+extern void (*lcd_late_resume)(void);
+
+#if defined(GPIO_ERR_FG)
+static void err_fg_detection_work(struct work_struct *work)
+{
+ struct lcd_info *lcd =
+ container_of(work, struct lcd_info, err_fg_detection.work);
+
+ int err_fg_level = gpio_get_value(GPIO_ERR_FG);
+
+ dev_info(&lcd->ld->dev, "%s, %d, %d\n", __func__, lcd->err_fg_detection_count, err_fg_level);
+
+ if (!err_fg_level) {
+ if (lcd->err_fg_detection_count < 10) {
+ schedule_delayed_work(&lcd->err_fg_detection, HZ/8);
+ lcd->err_fg_detection_count++;
+ set_dsim_hs_clk_toggle_count(15);
+ } else
+ set_dsim_hs_clk_toggle_count(0);
+ } else
+ set_dsim_hs_clk_toggle_count(0);
+
+}
+
+static irqreturn_t err_fg_detection_int(int irq, void *_lcd)
+{
+ struct lcd_info *lcd = _lcd;
+
+ dev_info(&lcd->ld->dev, "\t\t%s\n", __func__);
+
+ lcd->err_fg_detection_count = 0;
+ schedule_delayed_work(&lcd->err_fg_detection, HZ/16);
+
+ return IRQ_HANDLED;
+}
+#endif
+
+#if defined(GPIO_OLED_DET)
+static void oled_detection_work(struct work_struct *work)
+{
+ struct lcd_info *lcd =
+ container_of(work, struct lcd_info, oled_detection.work);
+
+ struct file *fp;
+ char name[128];
+ struct timespec ts;
+ struct rtc_time tm;
+
+ int oled_det_level = gpio_get_value(GPIO_OLED_DET);
+
+ dev_info(&lcd->ld->dev, "%s, GPIO_OLED_DET is %s\n", __func__, oled_det_level ? "high" : "low");
+
+ if (!oled_det_level) {
+ if (lcd->oled_detection_count < 3) {
+ getnstimeofday(&ts);
+ rtc_time_to_tm(ts.tv_sec, &tm);
+ sprintf(name, "%s%02d-%02d_%02d:%02d:%02d_%02d",
+ "/sdcard/", tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, lcd->oled_detection_count);
+ fp = filp_open(name, O_CREAT, S_IRWXU | S_IRWXG | S_IRWXO);
+
+ if (IS_ERR_OR_NULL(fp))
+ dev_info(&lcd->ld->dev, "fail to create vgh detection log file, %s\n", name);
+
+ schedule_delayed_work(&lcd->oled_detection, msecs_to_jiffies(10));
+ lcd->oled_detection_count++;
+ } else {
+ dev_info(&lcd->ld->dev, "VGH IS NOT OK! LCD SMASH!!!\n");
+ getnstimeofday(&ts);
+ rtc_time_to_tm(ts.tv_sec, &tm);
+ sprintf(name, "%s%02d-%02d_%02d:%02d:%02d_POWEROFF",
+ "/sdcard/", tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec);
+ fp = filp_open(name, O_CREAT, S_IRWXU | S_IRWXG | S_IRWXO);
+
+ if (IS_ERR_OR_NULL(fp))
+ dev_info(&lcd->ld->dev, "fail to create vgh detection log file, %s\n", name);
+
+ sys_sync();
+ kernel_power_off();
+ }
+ } else
+ dev_info(&lcd->ld->dev, "VGH IS OK\n");
+
+}
+
+static irqreturn_t oled_detection_int(int irq, void *_lcd)
+{
+ struct lcd_info *lcd = _lcd;
+
+ dev_info(&lcd->ld->dev, "\t\t%s\n", __func__);
+
+ schedule_delayed_work(&lcd->oled_detection, msecs_to_jiffies(10));
+
+ return IRQ_HANDLED;
+}
+#endif
+
+static int _s6evr02_write(struct lcd_info *lcd, const unsigned char *seq, int len)
+{
+ int size;
+ const unsigned char *wbuf;
+ int ret = 0;
+
+ if (!lcd->connected)
+ return 0;
+
+ mutex_lock(&lcd->lock);
+
+ size = len;
+ wbuf = seq;
+
+ if (size == 1)
+ ret = lcd->dsim->ops->cmd_write(lcd->dsim, DCS_WR_NO_PARA, wbuf[0], 0);
+ else if (size == 2)
+ ret = lcd->dsim->ops->cmd_write(lcd->dsim, DCS_WR_1_PARA, wbuf[0], wbuf[1]);
+ else
+ ret = lcd->dsim->ops->cmd_write(lcd->dsim, DCS_LONG_WR, (unsigned int)wbuf, size);
+
+ mutex_unlock(&lcd->lock);
+
+ return ret;
+}
+
+static int s6evr02_write(struct lcd_info *lcd, const unsigned char *seq, int len)
+{
+ int ret = 0;
+ int retry_cnt = 1;
+
+retry:
+ ret = _s6evr02_write(lcd, seq, len);
+ 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[1]);
+ }
+
+ return ret;
+}
+
+static int _s6evr02_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_read(lcd->dsim, addr, count, buf);
+
+ mutex_unlock(&lcd->lock);
+
+ return ret;
+}
+
+static int s6evr02_read(struct lcd_info *lcd, const u8 addr, u16 count, u8 *buf, u8 retry_cnt)
+{
+ int ret = 0;
+
+retry:
+ ret = _s6evr02_read(lcd, addr, count, buf);
+ 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__, addr);
+ }
+
+ return ret;
+}
+
+static int get_backlight_level_from_brightness(int brightness)
+{
+ int backlightlevel;
+
+ /* brightness setting from platform is from 0 to 255
+ * But in this driver, brightness is only supported from 0 to 24 */
+
+ switch (brightness) {
+ case 0 ... 29:
+ backlightlevel = GAMMA_20CD;
+ break;
+ case 30 ... 39:
+ backlightlevel = GAMMA_30CD;
+ break;
+ case 40 ... 49:
+ backlightlevel = GAMMA_40CD;
+ break;
+ case 50 ... 59:
+ backlightlevel = GAMMA_50CD;
+ break;
+ case 60 ... 69:
+ backlightlevel = GAMMA_60CD;
+ break;
+ case 70 ... 79:
+ backlightlevel = GAMMA_70CD;
+ break;
+ case 80 ... 89:
+ backlightlevel = GAMMA_80CD;
+ break;
+ case 90 ... 99:
+ backlightlevel = GAMMA_90CD;
+ break;
+ case 100 ... 101:
+ backlightlevel = GAMMA_100CD;
+ break;
+ case 102 ... 103:
+ backlightlevel = GAMMA_102CD;
+ break;
+ case 104 ... 105:
+ backlightlevel = GAMMA_104CD;
+ break;
+ case 106 ... 107:
+ backlightlevel = GAMMA_106CD;
+ break;
+ case 108 ... 109:
+ backlightlevel = GAMMA_108CD;
+ break;
+ case 110 ... 119:
+ backlightlevel = GAMMA_110CD;
+ break;
+ case 120 ... 129:
+ backlightlevel = GAMMA_120CD;
+ break;
+ case 130 ... 139:
+ backlightlevel = GAMMA_130CD;
+ break;
+ case 140 ... 149:
+ backlightlevel = GAMMA_140CD;
+ break;
+ case 150 ... 159:
+ backlightlevel = GAMMA_150CD;
+ break;
+ case 160 ... 169:
+ backlightlevel = GAMMA_160CD;
+ break;
+ case 170 ... 179:
+ backlightlevel = GAMMA_170CD;
+ break;
+ case 180 ... 181:
+ backlightlevel = GAMMA_180CD;
+ break;
+ case 182 ... 183:
+ backlightlevel = GAMMA_182CD;
+ break;
+ case 184 ... 185:
+ backlightlevel = GAMMA_184CD;
+ break;
+ case 186 ... 187:
+ backlightlevel = GAMMA_186CD;
+ break;
+ case 188 ... 189:
+ backlightlevel = GAMMA_188CD;
+ break;
+ case 190 ... 199:
+ backlightlevel = GAMMA_190CD;
+ break;
+ case 200 ... 209:
+ backlightlevel = GAMMA_200CD;
+ break;
+ case 210 ... 219:
+ backlightlevel = GAMMA_210CD;
+ break;
+ case 220 ... 229:
+ backlightlevel = GAMMA_220CD;
+ break;
+ case 230 ... 239:
+ backlightlevel = GAMMA_230CD;
+ break;
+ case 240 ... 249:
+ backlightlevel = GAMMA_240CD;
+ break;
+ case 250 ... 254:
+ backlightlevel = GAMMA_250CD;
+ break;
+ case 255:
+ backlightlevel = GAMMA_300CD;
+ break;
+ default:
+ backlightlevel = DEFAULT_GAMMA_LEVEL;
+ break;
+ }
+ return backlightlevel;
+}
+
+#ifdef SMART_DIMMING
+static int s6evr02_aid_parameter_ctl(struct lcd_info *lcd, u8 force)
+{
+ if ((aid_command_table[lcd->bl][0] != aid_command_table[lcd->current_bl][0]) || force)
+ s6evr02_write(lcd, lcd->aor[lcd->bl], AID_PARAM_SIZE);
+
+ return 0;
+}
+#endif
+
+static int s6evr02_gamma_ctl(struct lcd_info *lcd)
+{
+ /* s6evr02_write(lcd, SEQ_APPLY_LEVEL_2_KEY, ARRAY_SIZE(SEQ_APPLY_LEVEL_2_KEY)); */
+ s6evr02_write(lcd, lcd->gamma_table[lcd->bl], GAMMA_PARAM_SIZE);
+ s6evr02_write(lcd, SEQ_GAMMA_UPDATE, ARRAY_SIZE(SEQ_GAMMA_UPDATE));
+ /* s6evr02_write(lcd, SEQ_BRIGHTNESS_CONTROL_ON, ARRAY_SIZE(SEQ_BRIGHTNESS_CONTROL_ON)); */
+
+ return 0;
+}
+
+static int s6evr02_set_acl(struct lcd_info *lcd, u8 force)
+{
+ int ret = 0, level = 0;
+ u32 candela = candela_table[lcd->bl];
+
+ switch (candela) {
+ case 0 ... 29:
+ level = ACL_STATUS_0P;
+ break;
+ case 30 ... 39:
+ level = ACL_STATUS_33P;
+ break;
+ default:
+ level = ACL_STATUS_40P;
+ break;
+ }
+
+ if ((!lcd->acl_enable) || (lcd->auto_brightness >= 5))
+ level = ACL_STATUS_0P;
+
+ if (force || lcd->current_acl != ACL_CUTOFF_TABLE[level][1]) {
+ ret = s6evr02_write(lcd, ACL_CUTOFF_TABLE[level], ACL_PARAM_SIZE);
+ lcd->current_acl = ACL_CUTOFF_TABLE[level][1];
+ dev_dbg(&lcd->ld->dev, "current_acl = %d\n", lcd->current_acl);
+ }
+
+ if (ret)
+ ret = -EPERM;
+
+ return ret;
+}
+
+static int s6evr02_set_elvss(struct lcd_info *lcd, u8 force)
+{
+ int ret = 0, elvss_level = 0;
+ u32 candela = candela_table[lcd->bl];
+
+ switch (candela) {
+ case 0 ... 49:
+ elvss_level = ELVSS_STATUS_20;
+ break;
+ case 50 ... 79:
+ elvss_level = ELVSS_STATUS_50;
+ break;
+ case 80 ... 99:
+ elvss_level = ELVSS_STATUS_80;
+ break;
+ case 100 ... 109:
+ elvss_level = ELVSS_STATUS_100;
+ break;
+ case 110 ... 119:
+ elvss_level = ELVSS_STATUS_110;
+ break;
+ case 120 ... 129:
+ elvss_level = ELVSS_STATUS_120;
+ break;
+ case 130 ... 139:
+ elvss_level = ELVSS_STATUS_130;
+ break;
+ case 140 ... 149:
+ elvss_level = ELVSS_STATUS_140;
+ break;
+ case 150 ... 159:
+ elvss_level = ELVSS_STATUS_150;
+ break;
+ case 160 ... 169:
+ elvss_level = ELVSS_STATUS_160;
+ break;
+ case 170 ... 179:
+ elvss_level = ELVSS_STATUS_170;
+ break;
+ case 180 ... 189:
+ elvss_level = ELVSS_STATUS_180;
+ break;
+ case 190 ... 199:
+ elvss_level = ELVSS_STATUS_190;
+ break;
+ case 200 ... 209:
+ elvss_level = ELVSS_STATUS_200;
+ break;
+ case 210 ... 219:
+ elvss_level = ELVSS_STATUS_210;
+ break;
+ case 220 ... 229:
+ elvss_level = ELVSS_STATUS_220;
+ break;
+ case 230 ... 239:
+ elvss_level = ELVSS_STATUS_230;
+ break;
+ case 240 ... 250:
+ elvss_level = ELVSS_STATUS_240;
+ break;
+ case 299:
+ elvss_level = ELVSS_STATUS_300;
+ break;
+ }
+
+ if (force || lcd->current_elvss != lcd->elvss_table[elvss_level][2]) {
+ ret = s6evr02_write(lcd, lcd->elvss_table[elvss_level], ELVSS_PARAM_SIZE);
+ lcd->current_elvss = lcd->elvss_table[elvss_level][2];
+ }
+
+ dev_dbg(&lcd->ld->dev, "elvss = %x\n", lcd->elvss_table[elvss_level][2]);
+
+ if (ret) {
+ ret = -EPERM;
+ goto elvss_err;
+ }
+
+elvss_err:
+ return ret;
+}
+
+static int init_elvss_table(struct lcd_info *lcd)
+{
+ int i, ret = 0;
+#ifdef SMART_DIMMING_DEBUG
+ int j;
+#endif
+
+ lcd->elvss_table = kzalloc(ELVSS_STATUS_MAX * sizeof(u8 *), GFP_KERNEL);
+
+ if (IS_ERR_OR_NULL(lcd->elvss_table)) {
+ pr_err("failed to allocate elvss table\n");
+ ret = -ENOMEM;
+ goto err_alloc_elvss_table;
+ }
+
+ for (i = 0; i < ELVSS_STATUS_MAX; i++) {
+ lcd->elvss_table[i] = kzalloc(ELVSS_PARAM_SIZE * sizeof(u8), GFP_KERNEL);
+ if (IS_ERR_OR_NULL(lcd->elvss_table[i])) {
+ pr_err("failed to allocate elvss\n");
+ ret = -ENOMEM;
+ goto err_alloc_elvss;
+ }
+ lcd->elvss_table[i][0] = 0xB6;
+ lcd->elvss_table[i][1] = 0x08;
+ lcd->elvss_table[i][2] = ELVSS_CONTROL_TABLE[i][2];
+ }
+
+#ifdef SMART_DIMMING_DEBUG
+ for (i = 0; i < ELVSS_STATUS_MAX; i++) {
+ for (j = 0; j < ELVSS_PARAM_SIZE; j++)
+ printk("0x%02x, ", lcd->elvss_table[i][j]);
+ printk("\n");
+ }
+#endif
+
+ return 0;
+
+err_alloc_elvss:
+ while (i > 0) {
+ kfree(lcd->elvss_table[i-1]);
+ i--;
+ }
+ kfree(lcd->elvss_table);
+err_alloc_elvss_table:
+ return ret;
+}
+
+#ifdef SMART_DIMMING
+static int init_gamma_table(struct lcd_info *lcd , const u8 *mtp_data)
+{
+ int i, ret = 0;
+
+ lcd->gamma_table = kzalloc(GAMMA_MAX * sizeof(u8 *), GFP_KERNEL);
+ if (IS_ERR_OR_NULL(lcd->gamma_table)) {
+ pr_err("failed to allocate gamma table\n");
+ ret = -ENOMEM;
+ goto err_alloc_gamma_table;
+ }
+
+ for (i = 0; i < GAMMA_MAX; i++) {
+ lcd->gamma_table[i] = kzalloc(GAMMA_PARAM_SIZE * sizeof(u8), GFP_KERNEL);
+ if (IS_ERR_OR_NULL(lcd->gamma_table[i])) {
+ pr_err("failed to allocate gamma\n");
+ ret = -ENOMEM;
+ goto err_alloc_gamma;
+ }
+ lcd->gamma_table[i][0] = 0xCA;
+ }
+
+ for (i = 0; i < GAMMA_MAX; i++) {
+ if (candela_table[i] == 20)
+ calc_gamma_table_210_20_100(&lcd->smart, aid_candela_table[i], &lcd->gamma_table[i][1], G_21, mtp_data);
+ else if (candela_table[i] == 30)
+ calc_gamma_table_210_20_100(&lcd->smart, aid_candela_table[i], &lcd->gamma_table[i][1], G_213, mtp_data);
+ else if (candela_table[i] == 40)
+ calc_gamma_table_210_20_100(&lcd->smart, aid_candela_table[i], &lcd->gamma_table[i][1], G_215, mtp_data);
+ else if (candela_table[i] == 50)
+ calc_gamma_table_210_20_100(&lcd->smart, aid_candela_table[i], &lcd->gamma_table[i][1], G_218, mtp_data);
+ else if (candela_table[i] == 60)
+ calc_gamma_table_210_20_100(&lcd->smart, aid_candela_table[i], &lcd->gamma_table[i][1], G_22, mtp_data);
+ else if (candela_table[i] == 70)
+ calc_gamma_table_210_20_100(&lcd->smart, aid_candela_table[i], &lcd->gamma_table[i][1], G_222, mtp_data);
+ else if (candela_table[i] == 80)
+ calc_gamma_table_210_20_100(&lcd->smart, aid_candela_table[i], &lcd->gamma_table[i][1], G_223, mtp_data);
+ else if (candela_table[i] == 90)
+ calc_gamma_table_210_20_100(&lcd->smart, aid_candela_table[i], &lcd->gamma_table[i][1], G_224, mtp_data);
+ else if (candela_table[i] == 100)
+ calc_gamma_table_210_20_100(&lcd->smart, aid_candela_table[i], &lcd->gamma_table[i][1], G_225, mtp_data);
+ else if (candela_table[i] == 102)
+ calc_gamma_table(&lcd->smart, aid_candela_table[i], &lcd->gamma_table[i][1], G_224, mtp_data);
+ else if (candela_table[i] == 104)
+ calc_gamma_table(&lcd->smart, aid_candela_table[i], &lcd->gamma_table[i][1], G_223, mtp_data);
+ else if (candela_table[i] == 106)
+ calc_gamma_table(&lcd->smart, aid_candela_table[i], &lcd->gamma_table[i][1], G_222, mtp_data);
+ else if (candela_table[i] == 108)
+ calc_gamma_table(&lcd->smart, aid_candela_table[i], &lcd->gamma_table[i][1], G_221, mtp_data);
+ else if (candela_table[i] == 182)
+ calc_gamma_table(&lcd->smart, aid_candela_table[i], &lcd->gamma_table[i][1], G_221, mtp_data);
+ else if (candela_table[i] == 184)
+ calc_gamma_table(&lcd->smart, aid_candela_table[i], &lcd->gamma_table[i][1], G_222, mtp_data);
+ else if (candela_table[i] == 186)
+ calc_gamma_table(&lcd->smart, aid_candela_table[i], &lcd->gamma_table[i][1], G_223, mtp_data);
+ else if (candela_table[i] == 188)
+ calc_gamma_table(&lcd->smart, aid_candela_table[i], &lcd->gamma_table[i][1], G_224, mtp_data);
+ else if (candela_table[i] == 190)
+ calc_gamma_table_215_190(&lcd->smart, aid_candela_table[i], &lcd->gamma_table[i][1], G_225, mtp_data);
+ else if ((candela_table[i] > 190) && (candela_table[i] < MAX_GAMMA-1))
+ calc_gamma_table(&lcd->smart, aid_candela_table[i], &lcd->gamma_table[i][1], G_225 , mtp_data);
+ else if (candela_table[i] == MAX_GAMMA-1)
+ calc_gamma_table(&lcd->smart, aid_candela_table[i], &lcd->gamma_table[i][1], G_22, mtp_data);
+ else
+ calc_gamma_table(&lcd->smart, aid_candela_table[i], &lcd->gamma_table[i][1], G_22, mtp_data);
+ }
+
+
+#ifdef SMART_DIMMING_DEBUG
+ for (i = 0; i < GAMMA_MAX; i++) {
+ for (j = 0; j < GAMMA_PARAM_SIZE; j++)
+ printk("%d,", lcd->gamma_table[i][j]);
+ printk("\n");
+ }
+#endif
+ return 0;
+
+err_alloc_gamma:
+ while (i > 0) {
+ kfree(lcd->gamma_table[i-1]);
+ i--;
+ }
+ kfree(lcd->gamma_table);
+err_alloc_gamma_table:
+ return ret;
+}
+
+static int init_aid_dimming_table(struct lcd_info *lcd)
+{
+ unsigned int i, j, c;
+ u16 reverse_seq[] = {0, 28, 29, 30, 31, 32, 33, 25, 26, 27, 22, 23, 24, 19, 20, 21, 16, 17, 18, 13, 14, 15, 10, 11, 12, 7, 8, 9, 4, 5, 6, 1, 2, 3};
+ u16 temp[GAMMA_PARAM_SIZE];
+
+ for (i = 0; i < ARRAY_SIZE(aid_rgb_fix_table); i++) {
+ j = (aid_rgb_fix_table[i].gray * 3 + aid_rgb_fix_table[i].rgb) + 1;
+ c = lcd->gamma_table[aid_rgb_fix_table[i].candela_idx][j] + aid_rgb_fix_table[i].offset;
+ if (c > 0xff)
+ lcd->gamma_table[aid_rgb_fix_table[i].candela_idx][j] = 0xff;
+ else
+ lcd->gamma_table[aid_rgb_fix_table[i].candela_idx][j] += aid_rgb_fix_table[i].offset;
+ }
+
+ for (i = 0; i < GAMMA_MAX; i++) {
+ memcpy(lcd->aor[i], SEQ_AOR_CONTROL, AID_PARAM_SIZE);
+ lcd->aor[i][0x01] = aid_command_table[i][0];
+ }
+
+#ifdef SMART_DIMMING_DEBUG
+ for (i = 0; i < GAMMA_MAX; i++) {
+ for (j = 0; j < GAMMA_PARAM_SIZE; j++)
+ printk("%d,", lcd->gamma_table[i][j]);
+ printk("\n");
+ }
+ printk("\n");
+#endif
+
+ for (i = 0; i < GAMMA_MAX; i++) {
+ for (j = 0; j < GAMMA_PARAM_SIZE; j++)
+ temp[j] = lcd->gamma_table[i][reverse_seq[j]];
+
+ for (j = 0; j < GAMMA_PARAM_SIZE; j++)
+ lcd->gamma_table[i][j] = temp[j];
+
+ for (c = CI_RED; c < CI_MAX ; c++)
+ lcd->gamma_table[i][31+c] = lcd->smart.default_gamma[30+c];
+ }
+
+#ifdef SMART_DIMMING_DEBUG
+ for (i = 0; i < GAMMA_MAX; i++) {
+ for (j = 0; j < GAMMA_PARAM_SIZE; j++)
+ printk("%d,", lcd->gamma_table[i][j]);
+ printk("\n");
+ }
+#endif
+
+ return 0;
+}
+#endif
+
+static int update_brightness(struct lcd_info *lcd, u8 force)
+{
+ u32 brightness;
+
+ mutex_lock(&lcd->bl_lock);
+
+ brightness = lcd->bd->props.brightness;
+
+ if (unlikely(!lcd->auto_brightness && brightness > 250))
+ brightness = 250;
+
+ lcd->bl = get_backlight_level_from_brightness(brightness);
+
+ if ((force) || ((lcd->ldi_enable) && (lcd->current_bl != lcd->bl))) {
+ s6evr02_gamma_ctl(lcd);
+
+ s6evr02_aid_parameter_ctl(lcd, force);
+
+ s6evr02_set_acl(lcd, force);
+
+ s6evr02_set_elvss(lcd, force);
+
+ lcd->current_bl = lcd->bl;
+
+ dev_info(&lcd->ld->dev, "brightness=%d, bl=%d, candela=%d\n", brightness, lcd->bl, candela_table[lcd->bl]);
+ }
+
+ mutex_unlock(&lcd->bl_lock);
+
+ return 0;
+}
+
+static int s6evr02_ldi_init(struct lcd_info *lcd)
+{
+ int ret = 0;
+ s6evr02_write(lcd, SEQ_APPLY_LEVEL_2_KEY, ARRAY_SIZE(SEQ_APPLY_LEVEL_2_KEY));
+ s6evr02_write(lcd, SEQ_SLEEP_OUT, ARRAY_SIZE(SEQ_SLEEP_OUT));
+
+ if (lcd->id[1] == 0x10) { /* for S.LSI UB(YOUM) */
+ msleep(20);
+ s6evr02_write(lcd, SEQ_GAMMA_CONDITION_SET_UB, ARRAY_SIZE(SEQ_GAMMA_CONDITION_SET_UB));
+ s6evr02_write(lcd, SEQ_GAMMA_UPDATE, ARRAY_SIZE(SEQ_GAMMA_UPDATE));
+ s6evr02_write(lcd, SEQ_BRIGHTNESS_CONTROL_ON, ARRAY_SIZE(SEQ_BRIGHTNESS_CONTROL_ON));
+ s6evr02_write(lcd, SEQ_AOR_CONTROL, ARRAY_SIZE(SEQ_AOR_CONTROL));
+ s6evr02_write(lcd, SEQ_ELVSS_CONDITION_SET_UB, ARRAY_SIZE(SEQ_ELVSS_CONDITION_SET_UB));
+ s6evr02_write(lcd, SEQ_ACL_OFF, ARRAY_SIZE(SEQ_ACL_OFF));
+ } else {
+ msleep(20);
+ s6evr02_gamma_ctl(lcd);
+ s6evr02_write(lcd, SEQ_BRIGHTNESS_CONTROL_ON, ARRAY_SIZE(SEQ_BRIGHTNESS_CONTROL_ON));
+ s6evr02_write(lcd, SEQ_AOR_CONTROL, ARRAY_SIZE(SEQ_AOR_CONTROL));
+ s6evr02_write(lcd, SEQ_ELVSS_CONDITION_SET, ARRAY_SIZE(SEQ_ELVSS_CONDITION_SET));
+ s6evr02_write(lcd, SEQ_ACL_OFF, ARRAY_SIZE(SEQ_ACL_OFF));
+ }
+
+ return ret;
+}
+
+static int s6evr02_ldi_enable(struct lcd_info *lcd)
+{
+ int ret = 0;
+
+ s6evr02_write(lcd, SEQ_DISPLAY_ON, ARRAY_SIZE(SEQ_DISPLAY_ON));
+
+ return ret;
+}
+
+static int s6evr02_ldi_disable(struct lcd_info *lcd)
+{
+ int ret = 0;
+
+ s6evr02_write(lcd, SEQ_DISPLAY_OFF, ARRAY_SIZE(SEQ_DISPLAY_OFF));
+
+ msleep(35);
+
+ s6evr02_write(lcd, SEQ_SLEEP_IN, ARRAY_SIZE(SEQ_SLEEP_IN));
+
+ msleep(100);
+
+ return ret;
+}
+
+static int s6evr02_power_on(struct lcd_info *lcd)
+{
+ int ret = 0;
+ struct lcd_platform_data *pd = NULL;
+ pd = lcd->lcd_pd;
+
+ dev_info(&lcd->ld->dev, "%s\n", __func__);
+
+ ret = s6evr02_ldi_init(lcd);
+ if (ret) {
+ dev_err(&lcd->ld->dev, "failed to initialize ldi.\n");
+ goto err;
+ }
+
+ msleep(120);
+
+ ret = s6evr02_ldi_enable(lcd);
+ if (ret) {
+ dev_err(&lcd->ld->dev, "failed to enable ldi.\n");
+ goto err;
+ }
+
+ lcd->ldi_enable = 1;
+
+ update_brightness(lcd, 1);
+err:
+ return ret;
+}
+
+static int s6evr02_power_off(struct lcd_info *lcd)
+{
+ int ret = 0;
+
+ dev_info(&lcd->ld->dev, "%s\n", __func__);
+
+ lcd->ldi_enable = 0;
+
+ ret = s6evr02_ldi_disable(lcd);
+
+ msleep(135);
+
+ return ret;
+}
+
+static int s6evr02_power(struct lcd_info *lcd, int power)
+{
+ int ret = 0;
+
+ if (POWER_IS_ON(power) && !POWER_IS_ON(lcd->power))
+ ret = s6evr02_power_on(lcd);
+ else if (!POWER_IS_ON(power) && POWER_IS_ON(lcd->power))
+ ret = s6evr02_power_off(lcd);
+
+ if (!ret)
+ lcd->power = power;
+
+ return ret;
+}
+
+static int s6evr02_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 s6evr02_power(lcd, power);
+}
+
+static int s6evr02_get_power(struct lcd_device *ld)
+{
+ struct lcd_info *lcd = lcd_get_data(ld);
+
+ return lcd->power;
+}
+
+
+static int s6evr02_set_brightness(struct backlight_device *bd)
+{
+ int ret = 0;
+ int brightness = bd->props.brightness;
+ struct lcd_info *lcd = bl_get_data(bd);
+
+ /* dev_info(&lcd->ld->dev, "%s: brightness=%d\n", __func__, 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, MAX_BRIGHTNESS, brightness);
+ return -EINVAL;
+ }
+
+ if (lcd->ldi_enable) {
+ ret = update_brightness(lcd, 0);
+ if (ret < 0) {
+ dev_err(lcd->dev, "err in %s\n", __func__);
+ return -EINVAL;
+ }
+ }
+
+ return ret;
+}
+
+static int s6evr02_get_brightness(struct backlight_device *bd)
+{
+ struct lcd_info *lcd = bl_get_data(bd);
+
+ return candela_table[lcd->bl];
+}
+
+static int s6evr02_check_fb(struct lcd_device *ld, struct fb_info *fb)
+{
+ struct s3cfb_window *win = fb->par;
+ struct lcd_info *lcd = lcd_get_data(ld);
+
+ dev_info(&lcd->ld->dev, "%s, fb%d\n", __func__, win->id);
+
+ return 0;
+}
+
+static struct lcd_ops s6evr02_lcd_ops = {
+ .set_power = s6evr02_set_power,
+ .get_power = s6evr02_get_power,
+ .check_fb = s6evr02_check_fb,
+};
+
+static const struct backlight_ops s6evr02_backlight_ops = {
+ .get_brightness = s6evr02_get_brightness,
+ .update_status = s6evr02_set_brightness,
+};
+
+static ssize_t power_reduce_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct lcd_info *lcd = dev_get_drvdata(dev);
+ char temp[3];
+
+ sprintf(temp, "%d\n", lcd->acl_enable);
+ strcpy(buf, temp);
+
+ return strlen(buf);
+}
+
+static ssize_t power_reduce_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t size)
+{
+ struct lcd_info *lcd = 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 (lcd->acl_enable != value) {
+ dev_info(dev, "%s - %d, %d\n", __func__, lcd->acl_enable, value);
+ mutex_lock(&lcd->bl_lock);
+ lcd->acl_enable = value;
+ mutex_unlock(&lcd->bl_lock);
+ if (lcd->ldi_enable)
+ update_brightness(lcd, 1);
+ }
+ }
+ return size;
+}
+
+static DEVICE_ATTR(power_reduce, 0664, power_reduce_show, power_reduce_store);
+
+static ssize_t lcd_type_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ char temp[15];
+
+ sprintf(temp, "SMD_AMS555HBxx\n");
+ strcat(buf, temp);
+ return strlen(buf);
+}
+
+static DEVICE_ATTR(lcd_type, 0444, lcd_type_show, NULL);
+
+static ssize_t window_type_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct lcd_info *lcd = dev_get_drvdata(dev);
+ char temp[15];
+
+ sprintf(temp, "%x %x %x\n", lcd->id[0], lcd->id[1], lcd->id[2]);
+
+ strcat(buf, temp);
+ return strlen(buf);
+}
+
+static DEVICE_ATTR(window_type, 0444, window_type_show, NULL);
+
+static ssize_t gamma_table_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct lcd_info *lcd = dev_get_drvdata(dev);
+ int i, j;
+
+ for (i = 0; i < GAMMA_MAX; i++) {
+ for (j = 0; j < GAMMA_PARAM_SIZE; j++)
+ printk("0x%02x, ", lcd->gamma_table[i][j]);
+ printk("\n");
+ }
+
+ for (i = 0; i < ELVSS_STATUS_MAX; i++) {
+ for (j = 0; j < ELVSS_PARAM_SIZE; j++)
+ printk("0x%02x, ", lcd->elvss_table[i][j]);
+ printk("\n");
+ }
+
+ return strlen(buf);
+}
+static DEVICE_ATTR(gamma_table, 0444, gamma_table_show, NULL);
+
+static ssize_t auto_brightness_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct lcd_info *lcd = dev_get_drvdata(dev);
+ char temp[3];
+
+ sprintf(temp, "%d\n", lcd->auto_brightness);
+ strcpy(buf, temp);
+
+ return strlen(buf);
+}
+
+static ssize_t auto_brightness_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t size)
+{
+ struct lcd_info *lcd = 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 (lcd->auto_brightness != value) {
+ dev_info(dev, "%s - %d, %d\n", __func__, lcd->auto_brightness, value);
+ mutex_lock(&lcd->bl_lock);
+ lcd->auto_brightness = value;
+ mutex_unlock(&lcd->bl_lock);
+ if (lcd->ldi_enable)
+ update_brightness(lcd, 1);
+ }
+ }
+ return size;
+}
+
+static DEVICE_ATTR(auto_brightness, 0644, auto_brightness_show, auto_brightness_store);
+
+#ifdef CONFIG_HAS_EARLYSUSPEND
+static struct lcd_info *g_lcd;
+
+void s6evr02_early_suspend(void)
+{
+ struct lcd_info *lcd = g_lcd;
+
+ set_dsim_lcd_enabled(0);
+
+ dev_info(&lcd->ld->dev, "+%s\n", __func__);
+
+#if defined(GPIO_ERR_FG)
+ disable_irq(lcd->irq);
+ gpio_request(GPIO_ERR_FG, "OLED_DET");
+ s3c_gpio_cfgpin(GPIO_ERR_FG, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_ERR_FG, S3C_GPIO_PULL_NONE);
+ gpio_direction_output(GPIO_ERR_FG, GPIO_LEVEL_LOW);
+ gpio_free(GPIO_ERR_FG);
+#endif
+#if defined(GPIO_OLED_DET)
+ disable_irq(gpio_to_irq(GPIO_OLED_DET));
+ gpio_request(GPIO_OLED_DET, "OLED_DET");
+ s3c_gpio_cfgpin(GPIO_OLED_DET, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_OLED_DET, S3C_GPIO_PULL_NONE);
+ gpio_direction_output(GPIO_OLED_DET, GPIO_LEVEL_LOW);
+ gpio_free(GPIO_OLED_DET);
+#endif
+
+ s6evr02_power(lcd, FB_BLANK_POWERDOWN);
+ dev_info(&lcd->ld->dev, "-%s\n", __func__);
+
+ return ;
+}
+
+void s6evr02_late_resume(void)
+{
+ struct lcd_info *lcd = g_lcd;
+
+ dev_info(&lcd->ld->dev, "+%s\n", __func__);
+ s6evr02_power(lcd, FB_BLANK_UNBLANK);
+
+#if defined(GPIO_ERR_FG)
+ s3c_gpio_cfgpin(GPIO_ERR_FG, S3C_GPIO_SFN(0xf));
+ s3c_gpio_setpull(GPIO_ERR_FG, S3C_GPIO_PULL_NONE);
+ enable_irq(lcd->irq);
+#endif
+#if defined(GPIO_OLED_DET)
+ s3c_gpio_cfgpin(GPIO_OLED_DET, S3C_GPIO_SFN(0xf));
+ s3c_gpio_setpull(GPIO_OLED_DET, S3C_GPIO_PULL_NONE);
+ enable_irq(gpio_to_irq(GPIO_OLED_DET));
+#endif
+
+ dev_info(&lcd->ld->dev, "-%s\n", __func__);
+
+ set_dsim_lcd_enabled(1);
+
+ return ;
+}
+#endif
+
+
+static void s6evr02_read_id(struct lcd_info *lcd, u8 *buf)
+{
+ int ret = 0;
+
+ ret = s6evr02_read(lcd, LDI_ID_REG, LDI_ID_LEN, buf, 2);
+ if (!ret) {
+ lcd->connected = 0;
+ dev_info(&lcd->ld->dev, "panel is not connected well\n");
+ }
+}
+
+#ifdef SMART_DIMMING
+static int s6evr02_read_mtp(struct lcd_info *lcd, u8 *mtp_data)
+{
+ int ret;
+ s6evr02_write(lcd, SEQ_APPLY_LEVEL_2_KEY, ARRAY_SIZE(SEQ_APPLY_LEVEL_2_KEY));
+ s6evr02_write(lcd, SEQ_APPLY_LEVEL_3_KEY, ARRAY_SIZE(SEQ_APPLY_LEVEL_3_KEY));
+ msleep(20); /* one frame delay befor reading MTP. */
+ ret = s6evr02_read(lcd, LDI_MTP_ADDR, LDI_MTP_LENGTH, mtp_data, 1);
+ s6evr02_write(lcd, SEQ_APPLY_LEVEL_3_KEY_DISABLE, ARRAY_SIZE(SEQ_APPLY_LEVEL_3_KEY_DISABLE));
+ /* s6evr02_write(lcd, SEQ_APPLY_LEVEL_2_KEY_DISABLE, ARRAY_SIZE(SEQ_APPLY_LEVEL_2_KEY_DISABLE)); */
+
+ return ret;
+}
+#endif
+
+static int s6evr02_probe(struct device *dev)
+{
+ int ret = 0, i;
+ struct lcd_info *lcd;
+
+#ifdef SMART_DIMMING
+ u8 mtp_data[LDI_MTP_LENGTH] = {0,};
+#endif
+
+ 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, &s6evr02_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->bd = backlight_device_register("panel", dev, lcd, &s6evr02_backlight_ops, NULL);
+ if (IS_ERR(lcd->bd)) {
+ pr_err("failed to register backlight device\n");
+ ret = PTR_ERR(lcd->bd);
+ goto out_free_backlight;
+ }
+
+ lcd->dev = dev;
+ lcd->dsim = (struct dsim_global *)dev_get_drvdata(dev->parent);
+ lcd->bd->props.max_brightness = MAX_BRIGHTNESS;
+ lcd->bd->props.brightness = DEFAULT_BRIGHTNESS;
+ lcd->bl = DEFAULT_GAMMA_LEVEL;
+ lcd->current_bl = lcd->bl;
+ lcd->acl_enable = 0;
+ lcd->current_acl = 0;
+ lcd->power = FB_BLANK_UNBLANK;
+ lcd->ldi_enable = 1;
+ lcd->connected = 1;
+ lcd->auto_brightness = 0;
+
+ ret = device_create_file(&lcd->ld->dev, &dev_attr_power_reduce);
+ if (ret < 0)
+ dev_err(&lcd->ld->dev, "failed to add sysfs entries, %d\n", __LINE__);
+
+ ret = device_create_file(&lcd->ld->dev, &dev_attr_lcd_type);
+ if (ret < 0)
+ dev_err(&lcd->ld->dev, "failed to add sysfs entries, %d\n", __LINE__);
+
+ ret = device_create_file(&lcd->ld->dev, &dev_attr_window_type);
+ if (ret < 0)
+ dev_err(&lcd->ld->dev, "failed to add sysfs entries, %d\n", __LINE__);
+
+ ret = device_create_file(&lcd->ld->dev, &dev_attr_gamma_table);
+ if (ret < 0)
+ dev_err(&lcd->ld->dev, "failed to add sysfs entries, %d\n", __LINE__);
+
+ ret = device_create_file(&lcd->bd->dev, &dev_attr_auto_brightness);
+ if (ret < 0)
+ dev_err(&lcd->ld->dev, "failed to add sysfs entries, %d\n", __LINE__);
+
+ dev_set_drvdata(dev, lcd);
+
+ mutex_init(&lcd->lock);
+ mutex_init(&lcd->bl_lock);
+
+ s6evr02_read_id(lcd, lcd->id);
+
+ dev_info(&lcd->ld->dev, "ID: %x, %x, %x\n", lcd->id[0], lcd->id[1], lcd->id[2]);
+
+ dev_info(&lcd->ld->dev, "%s lcd panel driver has been probed.\n", dev_name(dev));
+
+#ifdef SMART_DIMMING
+ for (i = 0; i < LDI_ID_LEN; i++) {
+ lcd->smart.panelid[i] = lcd->id[i];
+ }
+
+ init_table_info(&lcd->smart);
+
+ ret = s6evr02_read_mtp(lcd, mtp_data);
+/*
+ for (i = 0; i < LDI_MTP_LENGTH ; i++)
+ printk(" %dth mtp value is %x\n", i, mtp_data[i]);
+*/
+ if (!ret) {
+ printk(KERN_ERR "[LCD:ERROR] : %s read mtp failed\n", __func__);
+ /*return -EPERM;*/
+ }
+
+ calc_voltage_table(&lcd->smart, mtp_data);
+
+ ret = init_elvss_table(lcd);
+ ret += init_gamma_table(lcd, mtp_data);
+ ret += init_aid_dimming_table(lcd);
+
+ if (ret)
+ printk(KERN_ERR "gamma table generation is failed\n");
+
+
+ update_brightness(lcd, 1);
+#endif
+
+#if defined(GPIO_ERR_FG)
+ if (lcd->connected) {
+ INIT_DELAYED_WORK(&lcd->err_fg_detection, err_fg_detection_work);
+
+ lcd->irq = gpio_to_irq(GPIO_ERR_FG);
+
+ irq_set_irq_type(lcd->irq, IRQ_TYPE_EDGE_RISING);
+
+ s3c_gpio_cfgpin(GPIO_ERR_FG, S3C_GPIO_SFN(0xf));
+ s3c_gpio_setpull(GPIO_ERR_FG, S3C_GPIO_PULL_NONE);
+
+ if (request_irq(lcd->irq, err_fg_detection_int,
+ IRQF_TRIGGER_RISING, "err_fg_detection", lcd))
+ pr_err("failed to reqeust irq. %d\n", lcd->irq);
+ }
+#endif
+#if defined(GPIO_OLED_DET)
+ if (lcd->connected) {
+ INIT_DELAYED_WORK(&lcd->oled_detection, oled_detection_work);
+
+ s3c_gpio_cfgpin(GPIO_OLED_DET, S3C_GPIO_SFN(0xf));
+ s3c_gpio_setpull(GPIO_OLED_DET, S3C_GPIO_PULL_NONE);
+
+ if (request_irq(gpio_to_irq(GPIO_OLED_DET), oled_detection_int,
+ IRQF_TRIGGER_FALLING, "oled_detection", lcd))
+ pr_err("failed to reqeust irq. %d\n", gpio_to_irq(GPIO_OLED_DET));
+ }
+#endif
+
+ lcd_early_suspend = s6evr02_early_suspend;
+ lcd_late_resume = s6evr02_late_resume;
+
+ return 0;
+
+out_free_backlight:
+ lcd_device_unregister(lcd->ld);
+ kfree(lcd);
+ return ret;
+
+out_free_lcd:
+ kfree(lcd);
+ return ret;
+
+err_alloc:
+ return ret;
+}
+
+static int __devexit s6evr02_remove(struct device *dev)
+{
+ struct lcd_info *lcd = dev_get_drvdata(dev);
+
+ s6evr02_power(lcd, FB_BLANK_POWERDOWN);
+ lcd_device_unregister(lcd->ld);
+ backlight_device_unregister(lcd->bd);
+ kfree(lcd);
+
+ return 0;
+}
+
+/* Power down all displays on reboot, poweroff or halt. */
+static void s6evr02_shutdown(struct device *dev)
+{
+ struct lcd_info *lcd = dev_get_drvdata(dev);
+
+ dev_info(&lcd->ld->dev, "%s\n", __func__);
+
+ s6evr02_power(lcd, FB_BLANK_POWERDOWN);
+}
+
+static struct mipi_lcd_driver s6evr02_mipi_driver = {
+ .name = "s6evr02",
+ .probe = s6evr02_probe,
+ .remove = __devexit_p(s6evr02_remove),
+ .shutdown = s6evr02_shutdown,
+};
+
+static int s6evr02_init(void)
+{
+ return s5p_dsim_register_lcd_driver(&s6evr02_mipi_driver);
+}
+
+static void s6evr02_exit(void)
+{
+ return;
+}
+
+module_init(s6evr02_init);
+module_exit(s6evr02_exit);
+
+MODULE_DESCRIPTION("MIPI-DSI S6EVER02:AMS555HBXX (720x1280) Panel Driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/video/samsung/s5p-dsim.c b/drivers/video/samsung/s5p-dsim.c
index d128618..e206cf8 100644
--- a/drivers/video/samsung/s5p-dsim.c
+++ b/drivers/video/samsung/s5p-dsim.c
@@ -23,6 +23,7 @@
#include <linux/fb.h>
#include <linux/ctype.h>
#include <linux/platform_device.h>
+#include <linux/spinlock.h>
#include <linux/io.h>
#include <linux/irq.h>
#include <linux/memory.h>
@@ -240,7 +241,12 @@ unsigned char s5p_dsim_wr_data(void *ptr,
{
u32 uCnt = 0;
u32* pWordPtr = (u32 *)data0;
+ unsigned long flags;
+
+ spin_lock_irqsave(&dsim->slock, flags);
+
INIT_COMPLETION(dsim_wr_comp);
+ s5p_dsim_clear_interrupt(dsim_base, 0x01<<S5P_DSIM_INT_SFR_FIFO_EMPTY);
do {
s5p_dsim_wr_tx_data(dsim_base, pWordPtr[uCnt]);
@@ -251,6 +257,17 @@ unsigned char s5p_dsim_wr_data(void *ptr,
(unsigned char) (((unsigned short) data1) & 0xff),
(unsigned char) ((((unsigned short) data1) & 0xff00) >> 8));
+ /* check interrupt source if fifo empty interrupt source is rised directly after writing tx header.
+ if yes, we consider tx_data as fail. */
+ if (readl(dsim->reg_base + S5P_DSIM_INTSRC) & 0x01<<S5P_DSIM_INT_SFR_FIFO_EMPTY) {
+ dev_err(dsim->dev, "%s fifo empty is founded\n", __func__);
+ spin_unlock_irqrestore(&dsim->slock, flags);
+ mutex_unlock(&dsim_rd_wr_mutex);
+ return DSIM_FALSE;
+ }
+
+ spin_unlock_irqrestore(&dsim->slock, flags);
+
if (!wait_for_completion_interruptible_timeout(&dsim_wr_comp, DSIM_TIMEOUT)) {
dev_err(dsim->dev, "[DSIM:ERROR] %s Timeout\n", __func__);
mutex_unlock(&dsim_rd_wr_mutex);
@@ -386,6 +403,102 @@ clear_rx_fifo:
}
+int s5p_dsim_dcs_rd_data(void *ptr, u8 addr, u16 count, u8 *buf)
+{
+ u32 i, temp;
+ u8 response = 0;
+ u16 rxsize;
+ u32 txhd;
+ u32 rxhd;
+ int j;
+ struct dsim_global *dsim = ptr;
+ unsigned int reg_base = dsim->reg_base;
+
+ if (dsim->mipi_ddi_pd->resume_complete == 0) {
+ dev_err(dsim->dev, "DSIM Status: SUSPEND\n");
+ return DSIM_FALSE;
+ }
+
+ mutex_lock(&dsim_rd_wr_mutex);
+ INIT_COMPLETION(dsim_rd_comp);
+
+ switch (count) {
+ case 1:
+ response = MIPI_RESP_DCS_RD_1;
+ break;
+ case 2:
+ response = MIPI_RESP_DCS_RD_2;
+ break;
+ default:
+ response = MIPI_RESP_DCS_RD_LONG;
+ break;
+ }
+
+ /* set return packet size */
+ txhd = MIPI_CMD_DSI_SET_PKT_SZ | count << 8;
+
+ writel(txhd, reg_base + S5P_DSIM_PKTHDR);
+
+ /* set address to read */
+ txhd = MIPI_CMD_DSI_RD_0 | addr << 8;
+
+ writel(txhd, reg_base + S5P_DSIM_PKTHDR);
+
+ if (!wait_for_completion_interruptible_timeout(&dsim_rd_comp, DSIM_TIMEOUT)) {
+ dev_err(dsim->dev, "ERROR:%s timout\n", __func__);
+ mutex_unlock(&dsim_rd_wr_mutex);
+ return 0;
+ }
+
+ rxhd = readl(reg_base + S5P_DSIM_RXFIFO);
+ dev_info(dsim->dev, "rxhd : %x\n", rxhd);
+ if ((u8)(rxhd & 0xff) != response) {
+ dev_err(dsim->dev, "[DSIM:ERROR]:%s wrong response rxhd : %x, response:%x\n"
+ , __func__, rxhd, response);
+ goto error_read;
+ }
+ /* for short packet */
+ if (count <= 2) {
+ for (i = 0; i < count; i++)
+ buf[i] = (rxhd >> (8+(i*8))) & 0xff;
+ rxsize = count;
+ } else {
+ /* for long packet */
+ rxsize = (u16)((rxhd & 0x00ffff00) >> 8);
+ dev_info(dsim->dev, "rcv size : %d\n", rxsize);
+ if (rxsize != count) {
+ dev_err(dsim->dev, "[DSIM:ERROR]:%s received data size mismatch received : %d, requested : %d\n",
+ __func__, rxsize, count);
+ goto error_read;
+ }
+
+ for (i = 0; i < rxsize>>2; i++) {
+ temp = readl(reg_base + S5P_DSIM_RXFIFO);
+ dev_info(dsim->dev, "pkt : %08x\n", temp);
+ for (j = 0; j < 4; j++) {
+ buf[(i*4)+j] = (u8)(temp>>(j*8))&0xff;
+ /* printk("Value : %02x\n",(temp>>(j*8))&0xff); */
+ }
+ }
+ if (rxsize % 4) {
+ temp = readl(reg_base + S5P_DSIM_RXFIFO);
+ dev_info(dsim->dev, "pkt-l : %08x\n", temp);
+ for (j = 0; j < rxsize%4; j++) {
+ buf[(i*4)+j] = (u8)(temp>>(j*8))&0xff;
+ /* printk("Value : %02x\n",(temp>>(j*8))&0xff); */
+ }
+ }
+ }
+
+ mutex_unlock(&dsim_rd_wr_mutex);
+ return rxsize;
+
+error_read:
+ mutex_unlock(&dsim_rd_wr_mutex);
+ return 0;
+
+}
+
static irqreturn_t s5p_dsim_isr(int irq, void *dev_id)
{
int i;
@@ -457,7 +570,7 @@ static irqreturn_t s5p_dsim_isr(int irq, void *dev_id)
}
}
/* clear irq */
- writel(intsrc, dsim->reg_base + S5P_DSIM_INTSRC);
+ writel(intmsk, dsim->reg_base + S5P_DSIM_INTSRC);
return IRQ_HANDLED;
}
@@ -737,6 +850,24 @@ static int s5p_dsim_init_dsim(struct dsim_global *dsim)
}
#endif
+#if 0
+void s5p_dsim_set_lcd_freq_change(struct s3cfb_lcd_timing *timing)
+{
+ struct dsim_global *dsim = g_dsim;
+ struct dsim_lcd_config *main_lcd = dsim->dsim_lcd_info;
+ struct s3cfb_lcd *main_lcd_panel_info = NULL;
+ struct s3cfb_lcd_timing *main_timing = NULL;
+
+ main_lcd_panel_info = (struct s3cfb_lcd *)main_lcd->lcd_panel_info;
+ main_timing = &main_lcd_panel_info->timing;
+
+ main_timing->h_sw = timing->h_sw;
+ main_timing->h_bp = timing->h_bp;
+ main_timing->h_fp = timing->h_fp;
+}
+EXPORT_SYMBOL(s5p_dsim_set_lcd_freq_change);
+#endif
+
static void s5p_dsim_set_display_mode(struct dsim_global *dsim,
struct dsim_lcd_config *main_lcd, struct dsim_lcd_config *sub_lcd)
{
@@ -770,11 +901,11 @@ static void s5p_dsim_set_display_mode(struct dsim_global *dsim,
s5p_dsim_set_main_disp_vporch(dsim_base,
main_timing->cmd_allow_len,
- main_timing->stable_vfp, (u16) main_timing->v_bp);
+ main_timing->stable_vfp, (u16)main_timing->v_bp);
s5p_dsim_set_main_disp_hporch(dsim_base,
- main_timing->h_fp, (u16) main_timing->h_bp);
+ main_timing->h_fp, (u16)main_timing->h_bp);
s5p_dsim_set_main_disp_sync_area(dsim_base,
- main_timing->v_sw, (u16) main_timing->h_sw);
+ main_timing->v_sw, (u16)main_timing->h_sw);
/* in case of COMMAND MODE (CPU or I80 INTERFACE) */
} else {
@@ -990,10 +1121,10 @@ static void s5p_dsim_interrupt_mask_set(struct dsim_global *dsim)
writel(int_stat, dsim->reg_base + S5P_DSIM_INTMSK);
}
-int s5p_dsim_fifo_clear(void)
+#if defined(CONFIG_CPU_EXYNOS4210)
+static int s5p_dsim_fifo_clear(struct dsim_global *dsim)
{
int dsim_count = 0, ret;
- struct dsim_global *dsim = g_dsim;
writel(SwRstRelease, dsim->reg_base + S5P_DSIM_INTSRC);
@@ -1007,7 +1138,6 @@ int s5p_dsim_fifo_clear(void)
}
if (readl(dsim->reg_base + S5P_DSIM_INTSRC) & SwRstRelease) {
- s5p_dsim_interrupt_mask_set(dsim);
ret = 1;
break;
}
@@ -1015,6 +1145,7 @@ int s5p_dsim_fifo_clear(void)
return ret;
}
+#endif
#ifdef CONFIG_HAS_EARLYSUSPEND
void s5p_dsim_early_suspend(void)
@@ -1087,19 +1218,27 @@ void s5p_dsim_late_resume(void)
dsim->mipi_ddi_pd->lcd_power_on(dsim->dev, 1);
usleep_range(25000, 25000);
+ s5p_dsim_late_resume_init_dsim(dsim);
+ s5p_dsim_init_link(dsim);
+ usleep_range(10000, 10000);
+
if (dsim->mipi_ddi_pd->lcd_reset)
dsim->mipi_ddi_pd->lcd_reset();
usleep_range(5000, 5000);
- s5p_dsim_late_resume_init_dsim(dsim);
- s5p_dsim_init_link(dsim);
- usleep_range(10000, 10000);
s5p_dsim_set_hs_enable(dsim);
s5p_dsim_set_data_transfer_mode(dsim, DSIM_TRANSFER_BYCPU, 1);
s5p_dsim_set_display_mode(dsim, dsim->dsim_lcd_info, NULL);
s5p_dsim_set_data_transfer_mode(dsim, DSIM_TRANSFER_BYLCDC, 1);
/* s5p_dsim_set_interrupt_mask(dsim->reg_base, AllDsimIntr, 0); */
+#if defined(CONFIG_CPU_EXYNOS4210)
+ if (s5p_dsim_fifo_clear(dsim) == 0)
+ dev_err(dsim->dev, "dsim fifo clear fail!!!\n");
+#endif
+
+ s5p_dsim_interrupt_mask_set(dsim);
+
dsim->mipi_ddi_pd->resume_complete = 1;
dev_info(dsim->dev, "-%s\n", __func__);
@@ -1254,6 +1393,7 @@ static DEVICE_ATTR(dsim_dump, 0444, dsim_dump_show, NULL);
static struct dsim_ops s5p_dsim_ops = {
.cmd_write = s5p_dsim_wr_data,
.cmd_read = s5p_dsim_rd_data,
+ .cmd_dcs_read = s5p_dsim_dcs_rd_data,
.suspend = s5p_dsim_early_suspend,
.resume = s5p_dsim_late_resume,
};
@@ -1277,7 +1417,8 @@ static int s5p_dsim_probe(struct platform_device *pdev)
dsim->pd = to_dsim_plat(&pdev->dev);
if (!dsim->pd) {
dev_err(&pdev->dev, "platform data is NULL\n");
- return -EINVAL;
+ ret = -EINVAL;
+ goto err_plat;
}
dsim->dev = &pdev->dev;
@@ -1298,7 +1439,8 @@ static int s5p_dsim_probe(struct platform_device *pdev)
dsim->clock = clk_get(&pdev->dev, dsim->pd->clk_name);
if (IS_ERR(dsim->clock)) {
dev_err(&pdev->dev, "failed to get dsim clock source\n");
- return -EINVAL;
+ ret = -EINVAL;
+ goto err_clk_get;
}
clk_enable(dsim->clock);
@@ -1343,9 +1485,9 @@ static int s5p_dsim_probe(struct platform_device *pdev)
writel(int_stat, dsim->reg_base + S5P_DSIM_INTSRC);
/* enable interrupts */
- int_stat = readl(dsim->reg_base + S5P_DSIM_INTMSK);
+ /* int_stat = readl(dsim->reg_base + S5P_DSIM_INTMSK); */
- int_stat &= ~((0x01<<S5P_DSIM_INT_BTA) | (0x01<<S5P_DSIM_INT_RX_TIMEOUT) |
+ int_stat = ~((0x01<<S5P_DSIM_INT_BTA) | (0x01<<S5P_DSIM_INT_RX_TIMEOUT) |
(0x01<<S5P_DSIM_INT_BTA_TIMEOUT) | (0x01 << S5P_DSIM_INT_RX_DONE) |
(0x01<<S5P_DSIM_INT_RX_TE) | (0x01<<S5P_DSIM_INT_RX_ACK) |
(0x01<<S5P_DSIM_INT_RX_ECC_ERR) | (0x01<<S5P_DSIM_IMT_RX_CRC_ERR) |
@@ -1356,6 +1498,7 @@ static int s5p_dsim_probe(struct platform_device *pdev)
init_completion(&dsim_rd_comp);
init_completion(&dsim_wr_comp);
mutex_init(&dsim_rd_wr_mutex);
+ spin_lock_init(&dsim->slock);
dsim->mipi_ddi_pd->resume_complete = 1;
dsim->dsim_lcd_info->lcd_enabled = 1;
@@ -1433,6 +1576,11 @@ mipi_drv_err:
err_clk_disable:
clk_disable(dsim->clock);
+
+err_clk_get:
+err_plat:
+ kfree(dsim);
+
err_alloc:
return ret;
}
diff --git a/drivers/video/samsung/s5p-dsim.h b/drivers/video/samsung/s5p-dsim.h
index baf8f66..049e066 100644
--- a/drivers/video/samsung/s5p-dsim.h
+++ b/drivers/video/samsung/s5p-dsim.h
@@ -44,6 +44,7 @@ struct mipi_lcd_driver {
struct dsim_ops {
u8 (*cmd_write)(void *ptr, u32 data0, u32 data1, u32 data2);
int (*cmd_read)(void *ptr, u8 addr, u16 count, u8 *buf);
+ int (*cmd_dcs_read)(void *ptr, u8 addr, u16 count, u8 *buf);
void (*suspend)(void);
void (*resume)(void);
};
@@ -79,6 +80,8 @@ struct dsim_global {
struct delayed_work check_hs_toggle_work;
unsigned int dsim_toggle_per_frame_count;
+ spinlock_t slock;
+
struct dsim_ops *ops;
};
diff --git a/drivers/video/samsung/s6d6aa1.c b/drivers/video/samsung/s6d6aa1.c
index 2a4c4ad..e974b0a 100644
--- a/drivers/video/samsung/s6d6aa1.c
+++ b/drivers/video/samsung/s6d6aa1.c
@@ -37,13 +37,13 @@
#define MIN_BRIGHTNESS 0
#define MAX_BRIGHTNESS 255
-#define DEFAULT_BRIGHTNESS 170
+#define DEFAULT_BRIGHTNESS 160
+
struct lcd_info {
unsigned int bl;
unsigned int current_bl;
- unsigned int acl_enable;
-
+ unsigned int auto_brightness;
unsigned int ldi_enable;
unsigned int power;
struct mutex lock;
@@ -57,10 +57,69 @@ struct lcd_info {
unsigned int irq;
unsigned int connected;
+#if defined(GPIO_OLED_DET)
+ struct delayed_work oled_detection;
+ unsigned int oled_detection_count;
+#endif
struct dsim_global *dsim;
};
+static const unsigned char SEQ_PASSWD1[] = {
+ 0xF0,
+ 0x5A, 0x5A
+};
+
+static const unsigned char SEQ_PASSWD2[] = {
+ 0xF1,
+ 0x5A, 0x5A
+};
+
+static const unsigned char SEQ_SONY_IP_SET1[] = {
+ 0xC4,
+ 0x7C, 0xE6, 0x7C, 0xE6, 0x7C, 0xE6, 0x7C, 0x7C,
+ 0x05, 0x0F, 0x1F, 0x01, 0x00, 0x00,
+};
+
+static const unsigned char SEQ_SONY_IP_SET2[] = {
+ 0xC5,
+ 0x80, 0x80, 0x80, 0x41, 0x43, 0x34, 0x80, 0x80,
+ 0x01, 0xFF, 0x25, 0x58, 0x50
+};
+
+/* Should be removed when panel nvm is updated */
+static const unsigned char SEQ_PGAMMACTL[] = {
+ 0xFA, 0x9C, 0xBF, 0x1A, 0xD6, 0xE3, 0xE3, 0x1B,
+ 0xDA, 0x9B, 0x16, 0x51, 0x12, 0x15, 0xD9, 0x9B,
+ 0x1A, 0xDD, 0x62, 0x2D, 0x79, 0x6A, 0x2C, 0x7F,
+ 0x11, 0x09, 0x53, 0x91, 0x09, 0x08, 0xCA, 0x06,
+ 0x04, 0x87, 0x0B, 0x4E, 0xD2, 0x13, 0xD7, 0x18,
+ 0x1A, 0x9A, 0xC1, 0x0F, 0xFF, 0xD7, 0x53, 0x61,
+ 0xE2, 0x5A, 0x9A, 0xDC, 0x59, 0x96, 0x98, 0x5C,
+ 0x1F, 0xE3, 0x25, 0xE6, 0x27, 0x23, 0x23, 0x4C,
+};
+
+static const unsigned char SEQ_NGAMMACTL[] = {
+ 0xFB, 0x9C, 0xBF, 0x1A, 0xD6, 0xE3, 0xE3, 0x1B,
+ 0xDA, 0x9B, 0x16, 0x51, 0x12, 0x15, 0xD9, 0x9B,
+ 0x1A, 0xDD, 0x62, 0x2D, 0x79, 0x6A, 0x2C, 0x7F,
+ 0x11, 0x09, 0x53, 0x91, 0x09, 0x08, 0xCA, 0x06,
+ 0x04, 0x87, 0x0B, 0x4E, 0xD2, 0x13, 0xD7, 0x18,
+ 0x1A, 0x9A, 0xC1, 0x0F, 0xFF, 0xD7, 0x53, 0x61,
+ 0xE2, 0x5A, 0x9A, 0xDC, 0x59, 0x96, 0x98, 0x5C,
+ 0x1F, 0xE3, 0x25, 0xE6, 0x27, 0x23, 0x23, 0x4C,
+};
+
+static const unsigned char SEQ_PASSWD1_DISABLE[] = {
+ 0xF0,
+ 0xA5, 0xA5
+};
+
+static const unsigned char SEQ_PASSWD2_DISABLE[] = {
+ 0xF1,
+ 0xA5, 0xA5
+};
+
static const unsigned char SEQ_SLPOUT[] = {
0x11,
0x00,
@@ -73,12 +132,6 @@ static const unsigned char SEQ_DSCTL[] = {
0x00
};
-static const unsigned char SEQ_WRDISBV[] = {
- 0x51,
- 0xFF,
- 0x00
-};
-
static const unsigned char SEQ_WRCTRLD[] = {
0x53,
0x2C,
@@ -91,6 +144,12 @@ static const unsigned char SEQ_WRCABC[] = {
0x00
};
+static const unsigned char SEQ_WRCABC_OUTDOOR[] = {
+ 0x55,
+ 0x04,
+ 0x00
+};
+
static const unsigned char SEQ_DISPON[] = {
0x29,
0x00,
@@ -115,8 +174,85 @@ static unsigned char SEQ_WRDISBV_CTL[] = {
0x00
};
+static unsigned char TRANS_BRIGHTNESS[] = {
+ 0, 1, 1, 2, 2, 3, 3, 4,
+ 4, 5, 5, 6, 6, 7, 7, 8,
+ 8, 9, 9, 10, 11, 12, 13, 14,
+ 15, 16, 17, 18, 19, 20, 21, 23,
+ 24, 25, 26, 27, 28, 29, 30, 31,
+ 32, 33, 34, 35, 36, 37, 38, 39,
+ 40, 41, 42, 43, 44, 45, 46, 48,
+ 49, 50, 51, 52, 53, 54, 55, 56,
+ 57, 58, 59, 60, 61, 62, 63, 64,
+ 65, 66, 67, 68, 69, 70, 72, 73,
+ 74, 75, 76, 77, 78, 79, 80, 81,
+ 82, 83, 84, 85, 86, 87, 88, 89,
+ 90, 91, 92, 93, 94, 95, 97, 98,
+ 99, 100, 101, 102, 103, 104, 105, 106,
+ 107, 108, 109, 110, 111, 112, 113, 114,
+ 115, 116, 117, 118, 119, 121, 122, 123,
+ 124, 125, 126, 127, 128, 129, 130, 131,
+ 132, 133, 134, 135, 136, 137, 138, 139,
+ 140, 141, 142, 143, 144, 146, 147, 148,
+ 149, 150, 151, 152, 153, 154, 155, 156,
+ 157, 158, 159, 160, 161, 162, 163, 164,
+ 165, 166, 167, 168, 170, 171, 172, 173,
+ 174, 175, 176, 177, 178, 179, 180, 181,
+ 182, 183, 184, 185, 186, 187, 188, 189,
+ 190, 191, 192, 193, 195, 196, 197, 198,
+ 199, 200, 201, 202, 203, 204, 205, 206,
+ 207, 208, 209, 210, 211, 212, 213, 214,
+ 215, 216, 217, 219, 220, 221, 222, 223,
+ 224, 225, 226, 227, 228, 229, 230, 231,
+ 232, 233, 234, 235, 236, 237, 238, 239,
+ 240, 241, 242, 244, 245, 246, 247, 248,
+ 249, 250, 251, 252, 253, 254, 255, 255,
+};
+
+extern void (*lcd_early_suspend)(void);
+extern void (*lcd_late_resume)(void);
+
+#if defined(GPIO_OLED_DET)
+static void esd_reset_lcd(struct lcd_info *lcd)
+{
+ dev_info(&lcd->ld->dev, "++%s\n", __func__);
+ if (lcd_early_suspend)
+ lcd_early_suspend();
+ lcd->dsim->ops->suspend();
+
+ lcd->dsim->ops->resume();
+ if (lcd_late_resume)
+ lcd_late_resume();
+ dev_info(&lcd->ld->dev, "--%s\n", __func__);
+}
+
+static void oled_detection_work(struct work_struct *work)
+{
+ struct lcd_info *lcd =
+ container_of(work, struct lcd_info, oled_detection.work);
+
+ int oled_det_level = gpio_get_value(GPIO_OLED_DET);
+
+ dev_info(&lcd->ld->dev, "%s, %d, %d\n", __func__, lcd->oled_detection_count, oled_det_level);
+ if (!oled_det_level)
+ esd_reset_lcd(lcd);
+}
+
+static irqreturn_t oled_detection_int(int irq, void *_lcd)
+{
+ struct lcd_info *lcd = _lcd;
+
+ dev_info(&lcd->ld->dev, "%s\n", __func__);
+
+ lcd->oled_detection_count = 0;
+ schedule_delayed_work(&lcd->oled_detection, HZ/16);
+
+ return IRQ_HANDLED;
+}
+#endif
-static int s6e8ax0_write(struct lcd_info *lcd, const unsigned char *seq, int len)
+
+static int s6d6aa1_write(struct lcd_info *lcd, const unsigned char *seq, int len)
{
int size;
const unsigned char *wbuf;
@@ -141,7 +277,7 @@ static int s6e8ax0_write(struct lcd_info *lcd, const unsigned char *seq, int len
return 0;
}
-static int _s6e8ax0_read(struct lcd_info *lcd, const u8 addr, u16 count, u8 *buf)
+static int _s6d6aa1_read(struct lcd_info *lcd, const u8 addr, u16 count, u8 *buf)
{
int ret = 0;
@@ -158,12 +294,12 @@ static int _s6e8ax0_read(struct lcd_info *lcd, const u8 addr, u16 count, u8 *buf
return ret;
}
-static int s6e8ax0_read(struct lcd_info *lcd, const u8 addr, u16 count, u8 *buf, u8 retry_cnt)
+static int s6d6aa1_read(struct lcd_info *lcd, const u8 addr, u16 count, u8 *buf, u8 retry_cnt)
{
int ret = 0;
read_retry:
- ret = _s6e8ax0_read(lcd, addr, count, buf);
+ ret = _s6d6aa1_read(lcd, addr, count, buf);
if (!ret) {
if (retry_cnt) {
printk(KERN_WARNING "[WARN:LCD] %s : retry cnt : %d\n", __func__, retry_cnt);
@@ -180,23 +316,13 @@ static int get_backlight_level_from_brightness(int brightness)
{
int backlightlevel;
- /* brightness setting from platform is from 0 to 255
- * But in this driver, brightness is only supported from 0 to 24 */
+ backlightlevel = TRANS_BRIGHTNESS[brightness];
- switch (brightness) {
- case 0 ... 255:
- backlightlevel = brightness;
- break;
- default:
- backlightlevel = brightness;
- break;
- }
return backlightlevel;
}
static int update_brightness(struct lcd_info *lcd, u8 force)
{
- int ret;
u32 brightness;
mutex_lock(&lcd->bl_lock);
@@ -209,7 +335,7 @@ static int update_brightness(struct lcd_info *lcd, u8 force)
lcd->current_bl = lcd->bl;
SEQ_WRDISBV_CTL[1] = lcd->bl;
- s6e8ax0_write(lcd, SEQ_WRDISBV_CTL, \
+ s6d6aa1_write(lcd, SEQ_WRDISBV_CTL, \
ARRAY_SIZE(SEQ_WRDISBV_CTL));
dev_info(&lcd->ld->dev, "brightness=%d, bl=%d\n", brightness, lcd->bl);
@@ -220,43 +346,52 @@ static int update_brightness(struct lcd_info *lcd, u8 force)
return 0;
}
-static int s6e8ax0_ldi_init(struct lcd_info *lcd)
+static int s6d6aa1_ldi_init(struct lcd_info *lcd)
{
int ret = 0;
- s6e8ax0_write(lcd, SEQ_SLPOUT, ARRAY_SIZE(SEQ_SLPOUT));
+ msleep(15);
+
+ s6d6aa1_write(lcd, SEQ_SLPOUT, ARRAY_SIZE(SEQ_SLPOUT));
- msleep(200);
+ msleep(145);
- s6e8ax0_write(lcd, SEQ_DSCTL, ARRAY_SIZE(SEQ_DSCTL));
- s6e8ax0_write(lcd, SEQ_WRDISBV, ARRAY_SIZE(SEQ_WRDISBV));
- s6e8ax0_write(lcd, SEQ_WRCTRLD, ARRAY_SIZE(SEQ_WRCTRLD));
- s6e8ax0_write(lcd, SEQ_WRCABC, ARRAY_SIZE(SEQ_WRCABC));
+ s6d6aa1_write(lcd, SEQ_PASSWD1, ARRAY_SIZE(SEQ_PASSWD1));
+ s6d6aa1_write(lcd, SEQ_PASSWD2, ARRAY_SIZE(SEQ_PASSWD2));
+ s6d6aa1_write(lcd, SEQ_SONY_IP_SET1, ARRAY_SIZE(SEQ_SONY_IP_SET1));
+ s6d6aa1_write(lcd, SEQ_SONY_IP_SET2, ARRAY_SIZE(SEQ_SONY_IP_SET2));
+ s6d6aa1_write(lcd, SEQ_PGAMMACTL, ARRAY_SIZE(SEQ_PGAMMACTL));
+ s6d6aa1_write(lcd, SEQ_NGAMMACTL, ARRAY_SIZE(SEQ_NGAMMACTL));
+ s6d6aa1_write(lcd, SEQ_PASSWD1_DISABLE, ARRAY_SIZE(SEQ_PASSWD1_DISABLE));
+ s6d6aa1_write(lcd, SEQ_PASSWD2_DISABLE, ARRAY_SIZE(SEQ_PASSWD2_DISABLE));
+ s6d6aa1_write(lcd, SEQ_DSCTL, ARRAY_SIZE(SEQ_DSCTL));
+ s6d6aa1_write(lcd, SEQ_WRCTRLD, ARRAY_SIZE(SEQ_WRCTRLD));
+ s6d6aa1_write(lcd, SEQ_WRCABC, ARRAY_SIZE(SEQ_WRCABC));
return ret;
}
-static int s6e8ax0_ldi_enable(struct lcd_info *lcd)
+static int s6d6aa1_ldi_enable(struct lcd_info *lcd)
{
int ret = 0;
- s6e8ax0_write(lcd, SEQ_DISPON, ARRAY_SIZE(SEQ_DISPON));
+ s6d6aa1_write(lcd, SEQ_DISPON, ARRAY_SIZE(SEQ_DISPON));
return ret;
}
-static int s6e8ax0_ldi_disable(struct lcd_info *lcd)
+static int s6d6aa1_ldi_disable(struct lcd_info *lcd)
{
int ret = 0;
- s6e8ax0_write(lcd, SEQ_DISPOFF, ARRAY_SIZE(SEQ_DISPOFF));
- s6e8ax0_write(lcd, SEQ_SLPIN, ARRAY_SIZE(SEQ_SLPIN));
+ s6d6aa1_write(lcd, SEQ_DISPOFF, ARRAY_SIZE(SEQ_DISPOFF));
+ s6d6aa1_write(lcd, SEQ_SLPIN, ARRAY_SIZE(SEQ_SLPIN));
return ret;
}
-static int s6e8ax0_power_on(struct lcd_info *lcd)
+static int s6d6aa1_power_on(struct lcd_info *lcd)
{
int ret = 0;
struct lcd_platform_data *pd = NULL;
@@ -264,15 +399,14 @@ static int s6e8ax0_power_on(struct lcd_info *lcd)
/* dev_info(&lcd->ld->dev, "%s\n", __func__); */
- ret = s6e8ax0_ldi_init(lcd);
+ ret = s6d6aa1_ldi_init(lcd);
if (ret) {
dev_err(&lcd->ld->dev, "failed to initialize ldi.\n");
goto err;
}
- msleep(120);
- ret = s6e8ax0_ldi_enable(lcd);
+ ret = s6d6aa1_ldi_enable(lcd);
if (ret) {
dev_err(&lcd->ld->dev, "failed to enable ldi.\n");
goto err;
@@ -285,7 +419,7 @@ err:
return ret;
}
-static int s6e8ax0_power_off(struct lcd_info *lcd)
+static int s6d6aa1_power_off(struct lcd_info *lcd)
{
int ret = 0;
@@ -293,21 +427,21 @@ static int s6e8ax0_power_off(struct lcd_info *lcd)
lcd->ldi_enable = 0;
- ret = s6e8ax0_ldi_disable(lcd);
+ ret = s6d6aa1_ldi_disable(lcd);
msleep(135);
return ret;
}
-static int s6e8ax0_power(struct lcd_info *lcd, int power)
+static int s6d6aa1_power(struct lcd_info *lcd, int power)
{
int ret = 0;
if (POWER_IS_ON(power) && !POWER_IS_ON(lcd->power))
- ret = s6e8ax0_power_on(lcd);
+ ret = s6d6aa1_power_on(lcd);
else if (!POWER_IS_ON(power) && POWER_IS_ON(lcd->power))
- ret = s6e8ax0_power_off(lcd);
+ ret = s6d6aa1_power_off(lcd);
if (!ret)
lcd->power = power;
@@ -315,7 +449,7 @@ static int s6e8ax0_power(struct lcd_info *lcd, int power)
return ret;
}
-static int s6e8ax0_set_power(struct lcd_device *ld, int power)
+static int s6d6aa1_set_power(struct lcd_device *ld, int power)
{
struct lcd_info *lcd = lcd_get_data(ld);
@@ -325,17 +459,27 @@ static int s6e8ax0_set_power(struct lcd_device *ld, int power)
return -EINVAL;
}
- return s6e8ax0_power(lcd, power);
+ return s6d6aa1_power(lcd, power);
+}
+
+ static int s6d6aa1_check_fb(struct lcd_device *ld, struct fb_info *fb)
+{
+ struct s3cfb_window *win = fb->par;
+ struct lcd_info *lcd = lcd_get_data(ld);
+
+ dev_info(&lcd->ld->dev, "%s, fb%d\n", __func__, win->id);
+
+ return 0;
}
-static int s6e8ax0_get_power(struct lcd_device *ld)
+static int s6d6aa1_get_power(struct lcd_device *ld)
{
struct lcd_info *lcd = lcd_get_data(ld);
return lcd->power;
}
-static int s6e8ax0_set_brightness(struct backlight_device *bd)
+static int s6d6aa1_set_brightness(struct backlight_device *bd)
{
int ret = 0;
int brightness = bd->props.brightness;
@@ -361,7 +505,7 @@ static int s6e8ax0_set_brightness(struct backlight_device *bd)
return ret;
}
-static int s6e8ax0_get_brightness(struct backlight_device *bd)
+static int s6d6aa1_get_brightness(struct backlight_device *bd)
{
struct lcd_info *lcd = bl_get_data(bd);
@@ -369,28 +513,43 @@ static int s6e8ax0_get_brightness(struct backlight_device *bd)
}
static struct lcd_ops panel_lcd_ops = {
- .set_power = s6e8ax0_set_power,
- .get_power = s6e8ax0_get_power,
+ .set_power = s6d6aa1_set_power,
+ .get_power = s6d6aa1_get_power,
+ .check_fb = s6d6aa1_check_fb,
};
static const struct backlight_ops panel_backlight_ops = {
- .get_brightness = s6e8ax0_get_brightness,
- .update_status = s6e8ax0_set_brightness,
+ .get_brightness = s6d6aa1_get_brightness,
+ .update_status = s6d6aa1_set_brightness,
};
-static ssize_t power_reduce_show(struct device *dev,
+static ssize_t lcd_type_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ char temp[15];
+
+ sprintf(temp, "JDI_ACX445BLN\n");
+
+ strcat(buf, temp);
+
+ return strlen(buf);
+}
+
+static DEVICE_ATTR(lcd_type, 0444, lcd_type_show, NULL);
+
+static ssize_t auto_brightness_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct lcd_info *lcd = dev_get_drvdata(dev);
char temp[3];
- sprintf(temp, "%d\n", lcd->acl_enable);
+ sprintf(temp, "%d\n", lcd->auto_brightness);
strcpy(buf, temp);
return strlen(buf);
}
-static ssize_t power_reduce_store(struct device *dev,
+static ssize_t auto_brightness_store(struct device *dev,
struct device_attribute *attr, const char *buf, size_t size)
{
struct lcd_info *lcd = dev_get_drvdata(dev);
@@ -401,39 +560,21 @@ static ssize_t power_reduce_store(struct device *dev,
if (rc < 0)
return rc;
else {
- if (lcd->acl_enable != value) {
- dev_info(dev, "%s - %d, %d\n", __func__, lcd->acl_enable, value);
- mutex_lock(&lcd->bl_lock);
- lcd->acl_enable = value;
- if (lcd->ldi_enable)
- /*s6e8ax0_set_acl(lcd);*/
- mutex_unlock(&lcd->bl_lock);
- }
+ lcd->auto_brightness = value;
+ if (lcd->auto_brightness < 4)
+ s6d6aa1_write(lcd, SEQ_WRCABC, ARRAY_SIZE(SEQ_WRCABC));
+ else
+ s6d6aa1_write(lcd, SEQ_WRCABC_OUTDOOR, ARRAY_SIZE(SEQ_WRCABC_OUTDOOR));
}
return size;
}
-static DEVICE_ATTR(power_reduce, 0664, power_reduce_show, power_reduce_store);
-
-static ssize_t lcd_type_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- char temp[15];
-
- sprintf(temp, "SMD_AMS480GYXX\n");
-
- strcat(buf, temp);
-
- return strlen(buf);
-}
-
-static DEVICE_ATTR(lcd_type, 0444, lcd_type_show, NULL);
-
+static DEVICE_ATTR(auto_brightness, 0644, auto_brightness_show, auto_brightness_store);
#ifdef CONFIG_HAS_EARLYSUSPEND
struct lcd_info *g_lcd;
-void s6e8ax0_early_suspend(void)
+void s6d6aa1_early_suspend(void)
{
struct lcd_info *lcd = g_lcd;
@@ -441,21 +582,33 @@ void s6e8ax0_early_suspend(void)
dev_info(&lcd->ld->dev, "+%s\n", __func__);
- s6e8ax0_power(lcd, FB_BLANK_POWERDOWN);
+#if defined(GPIO_OLED_DET)
+ disable_irq(lcd->irq);
+ gpio_request(GPIO_OLED_DET, "OLED_DET");
+ s3c_gpio_cfgpin(GPIO_OLED_DET, S3C_GPIO_OUTPUT);
+ s3c_gpio_setpull(GPIO_OLED_DET, S3C_GPIO_PULL_NONE);
+ gpio_direction_output(GPIO_OLED_DET, GPIO_LEVEL_LOW);
+ gpio_free(GPIO_OLED_DET);
+#endif
+ s6d6aa1_power(lcd, FB_BLANK_POWERDOWN);
dev_info(&lcd->ld->dev, "-%s\n", __func__);
return ;
}
-void s6e8ax0_late_resume(void)
+void s6d6aa1_late_resume(void)
{
struct lcd_info *lcd = g_lcd;
dev_info(&lcd->ld->dev, "+%s\n", __func__);
- s6e8ax0_power(lcd, FB_BLANK_UNBLANK);
-
+ s6d6aa1_power(lcd, FB_BLANK_UNBLANK);
+#if defined(GPIO_OLED_DET)
+ s3c_gpio_cfgpin(GPIO_OLED_DET, S3C_GPIO_SFN(0xf));
+ s3c_gpio_setpull(GPIO_OLED_DET, S3C_GPIO_PULL_NONE);
+ enable_irq(lcd->irq);
+#endif
dev_info(&lcd->ld->dev, "-%s\n", __func__);
set_dsim_lcd_enabled(1);
@@ -464,20 +617,7 @@ void s6e8ax0_late_resume(void)
}
#endif
-#if 0
-static void s6e8ax0_read_id(struct lcd_info *lcd, u8 *buf)
-{
- int ret = 0;
-
- ret = s6e8ax0_read(lcd, LDI_ID_REG, LDI_ID_LEN, buf, 3);
- if (!ret) {
- lcd->connected = 0;
- dev_info(&lcd->ld->dev, "panel is not connected well\n");
- }
-}
-#endif
-
-static int s6e8ax0_probe(struct device *dev)
+static int s6d6aa1_probe(struct device *dev)
{
int ret = 0;
struct lcd_info *lcd;
@@ -512,17 +652,15 @@ static int s6e8ax0_probe(struct device *dev)
lcd->bl = 0;
lcd->current_bl = lcd->bl;
- lcd->acl_enable = 0;
-
lcd->power = FB_BLANK_UNBLANK;
lcd->ldi_enable = 1;
lcd->connected = 1;
- ret = device_create_file(&lcd->ld->dev, &dev_attr_power_reduce);
+ ret = device_create_file(&lcd->ld->dev, &dev_attr_lcd_type);
if (ret < 0)
dev_err(&lcd->ld->dev, "failed to add sysfs entries, %d\n", __LINE__);
- ret = device_create_file(&lcd->ld->dev, &dev_attr_lcd_type);
+ ret = device_create_file(&lcd->bd->dev, &dev_attr_auto_brightness);
if (ret < 0)
dev_err(&lcd->ld->dev, "failed to add sysfs entries, %d\n", __LINE__);
@@ -533,6 +671,23 @@ static int s6e8ax0_probe(struct device *dev)
dev_info(&lcd->ld->dev, "s6e8aa0 lcd panel driver has been probed.\n");
+#if defined(GPIO_OLED_DET)
+ if (lcd->connected) {
+ INIT_DELAYED_WORK(&lcd->oled_detection, oled_detection_work);
+
+ lcd->irq = gpio_to_irq(GPIO_OLED_DET);
+
+ s3c_gpio_cfgpin(GPIO_OLED_DET, S3C_GPIO_SFN(0xf));
+ s3c_gpio_setpull(GPIO_OLED_DET, S3C_GPIO_PULL_NONE);
+ if (request_irq(lcd->irq, oled_detection_int,
+ IRQF_TRIGGER_FALLING, "oled_detection", lcd))
+ pr_err("failed to reqeust irq. %d\n", lcd->irq);
+ }
+#endif
+
+ lcd_early_suspend = s6d6aa1_early_suspend;
+ lcd_late_resume = s6d6aa1_late_resume;
+
return 0;
out_free_backlight:
@@ -548,11 +703,11 @@ err_alloc:
return ret;
}
-static int __devexit s6e8ax0_remove(struct device *dev)
+static int __devexit s6d6aa1_remove(struct device *dev)
{
struct lcd_info *lcd = dev_get_drvdata(dev);
- s6e8ax0_power(lcd, FB_BLANK_POWERDOWN);
+ s6d6aa1_power(lcd, FB_BLANK_POWERDOWN);
lcd_device_unregister(lcd->ld);
backlight_device_unregister(lcd->bd);
kfree(lcd);
@@ -561,35 +716,35 @@ static int __devexit s6e8ax0_remove(struct device *dev)
}
/* Power down all displays on reboot, poweroff or halt. */
-static void s6e8ax0_shutdown(struct device *dev)
+static void s6d6aa1_shutdown(struct device *dev)
{
struct lcd_info *lcd = dev_get_drvdata(dev);
dev_info(&lcd->ld->dev, "%s\n", __func__);
- s6e8ax0_power(lcd, FB_BLANK_POWERDOWN);
+ s6d6aa1_power(lcd, FB_BLANK_POWERDOWN);
}
-static struct mipi_lcd_driver s6e8ax0_mipi_driver = {
+static struct mipi_lcd_driver s6d6aa1_mipi_driver = {
.name = "s6d6aa1",
- .probe = s6e8ax0_probe,
- .remove = __devexit_p(s6e8ax0_remove),
- .shutdown = s6e8ax0_shutdown,
+ .probe = s6d6aa1_probe,
+ .remove = __devexit_p(s6d6aa1_remove),
+ .shutdown = s6d6aa1_shutdown,
};
-static int s6e8ax0_init(void)
+static int s6d6aa1_init(void)
{
- return s5p_dsim_register_lcd_driver(&s6e8ax0_mipi_driver);
+ return s5p_dsim_register_lcd_driver(&s6d6aa1_mipi_driver);
}
-static void s6e8ax0_exit(void)
+static void s6d6aa1_exit(void)
{
return;
}
-module_init(s6e8ax0_init);
-module_exit(s6e8ax0_exit);
+module_init(s6d6aa1_init);
+module_exit(s6d6aa1_exit);
-MODULE_DESCRIPTION("MIPI-DSI S6E8AA0:AMS529HA01 (800x1280) Panel Driver");
+MODULE_DESCRIPTION("MIPI-DSI S6D6AA1:ACX445BLN SCLCD (720x1280) Panel Driver");
MODULE_LICENSE("GPL");
diff --git a/drivers/video/samsung/s6dr171.c b/drivers/video/samsung/s6dr171.c
index 167f658..868c006 100644
--- a/drivers/video/samsung/s6dr171.c
+++ b/drivers/video/samsung/s6dr171.c
@@ -79,7 +79,10 @@ struct lcd_info {
struct dsim_global *dsim;
};
-static int s6e8ax0_write(struct lcd_info *lcd, const unsigned char *seq, int len)
+extern void (*lcd_early_suspend)(void);
+extern void (*lcd_late_resume)(void);
+
+static int s6dr171_write(struct lcd_info *lcd, const unsigned char *seq, int len)
{
int size;
const unsigned char *wbuf;
@@ -104,7 +107,7 @@ static int s6e8ax0_write(struct lcd_info *lcd, const unsigned char *seq, int len
return 0;
}
-static int _s6e8ax0_read(struct lcd_info *lcd, const u8 addr, u16 count, u8 *buf)
+static int _s6dr171_read(struct lcd_info *lcd, const u8 addr, u16 count, u8 *buf)
{
int ret = 0;
@@ -121,12 +124,12 @@ static int _s6e8ax0_read(struct lcd_info *lcd, const u8 addr, u16 count, u8 *buf
return ret;
}
-static int s6e8ax0_read(struct lcd_info *lcd, const u8 addr, u16 count, u8 *buf, u8 retry_cnt)
+static int s6dr171_read(struct lcd_info *lcd, const u8 addr, u16 count, u8 *buf, u8 retry_cnt)
{
int ret = 0;
read_retry:
- ret = _s6e8ax0_read(lcd, addr, count, buf);
+ ret = _s6dr171_read(lcd, addr, count, buf);
if (!ret) {
if (retry_cnt) {
printk(KERN_WARNING "[WARN:LCD] %s : retry cnt : %d\n", __func__, retry_cnt);
@@ -139,55 +142,55 @@ read_retry:
return ret;
}
-static int s6e8ax0_ldi_init(struct lcd_info *lcd)
+static int s6dr171_ldi_init(struct lcd_info *lcd)
{
int ret = 0;
- s6e8ax0_write(lcd, SEQ_APPLY_LEVEL_1_KEY, ARRAY_SIZE(SEQ_APPLY_LEVEL_1_KEY));
- s6e8ax0_write(lcd, SEQ_APPLY_MTP_KEY_ENABLE, ARRAY_SIZE(SEQ_APPLY_MTP_KEY_ENABLE));
- s6e8ax0_write(lcd, SEQ_PWRSEQCTL, ARRAY_SIZE(SEQ_PWRSEQCTL));
- s6e8ax0_write(lcd, SEQ_DISPLAY_BRIGHTNESSS, ARRAY_SIZE(SEQ_DISPLAY_BRIGHTNESSS));
- s6e8ax0_write(lcd, SEQ_CONTROL_DISPLAY, ARRAY_SIZE(SEQ_CONTROL_DISPLAY));
- s6e8ax0_write(lcd, SEQ_SLEEP_OUT, ARRAY_SIZE(SEQ_SLEEP_OUT));
+ s6dr171_write(lcd, SEQ_APPLY_LEVEL_1_KEY, ARRAY_SIZE(SEQ_APPLY_LEVEL_1_KEY));
+ s6dr171_write(lcd, SEQ_APPLY_MTP_KEY_ENABLE, ARRAY_SIZE(SEQ_APPLY_MTP_KEY_ENABLE));
+ s6dr171_write(lcd, SEQ_PWRSEQCTL, ARRAY_SIZE(SEQ_PWRSEQCTL));
+ s6dr171_write(lcd, SEQ_DISPLAY_BRIGHTNESSS, ARRAY_SIZE(SEQ_DISPLAY_BRIGHTNESSS));
+ s6dr171_write(lcd, SEQ_CONTROL_DISPLAY, ARRAY_SIZE(SEQ_CONTROL_DISPLAY));
+ s6dr171_write(lcd, SEQ_SLEEP_OUT, ARRAY_SIZE(SEQ_SLEEP_OUT));
msleep(120);
- s6e8ax0_write(lcd, SEQ_PANEL_CONDITION_SET, ARRAY_SIZE(SEQ_PANEL_CONDITION_SET));
- s6e8ax0_write(lcd, SEQ_DISPLAY_CONDITION_SET, ARRAY_SIZE(SEQ_DISPLAY_CONDITION_SET));
- s6e8ax0_write(lcd, SEQ_GAMMA_CONDITION_SET, ARRAY_SIZE(SEQ_GAMMA_CONDITION_SET));
- s6e8ax0_write(lcd, SEQ_GAMMA_UPDATE, ARRAY_SIZE(SEQ_GAMMA_UPDATE));
+ s6dr171_write(lcd, SEQ_PANEL_CONDITION_SET, ARRAY_SIZE(SEQ_PANEL_CONDITION_SET));
+ s6dr171_write(lcd, SEQ_DISPLAY_CONDITION_SET, ARRAY_SIZE(SEQ_DISPLAY_CONDITION_SET));
+ s6dr171_write(lcd, SEQ_GAMMA_CONDITION_SET, ARRAY_SIZE(SEQ_GAMMA_CONDITION_SET));
+ s6dr171_write(lcd, SEQ_GAMMA_UPDATE, ARRAY_SIZE(SEQ_GAMMA_UPDATE));
msleep(20);
- s6e8ax0_write(lcd, SEQ_GAMMA_UPDATE2, ARRAY_SIZE(SEQ_GAMMA_UPDATE2));
+ s6dr171_write(lcd, SEQ_GAMMA_UPDATE2, ARRAY_SIZE(SEQ_GAMMA_UPDATE2));
msleep(20);
- s6e8ax0_write(lcd, SEQ_ETC_SOURCE_CONTROL, ARRAY_SIZE(SEQ_ETC_SOURCE_CONTROL));
- s6e8ax0_write(lcd, SEQ_ETC_NVM_SETTING, ARRAY_SIZE(SEQ_ETC_NVM_SETTING));
- s6e8ax0_write(lcd, SEQ_ETC_POWER_CONTROL, ARRAY_SIZE(SEQ_ETC_POWER_CONTROL));
+ s6dr171_write(lcd, SEQ_ETC_SOURCE_CONTROL, ARRAY_SIZE(SEQ_ETC_SOURCE_CONTROL));
+ s6dr171_write(lcd, SEQ_ETC_NVM_SETTING, ARRAY_SIZE(SEQ_ETC_NVM_SETTING));
+ s6dr171_write(lcd, SEQ_ETC_POWER_CONTROL, ARRAY_SIZE(SEQ_ETC_POWER_CONTROL));
- s6e8ax0_write(lcd, SEQ_ELVSS_CONTROL, ARRAY_SIZE(SEQ_ELVSS_CONTROL));
+ s6dr171_write(lcd, SEQ_ELVSS_CONTROL, ARRAY_SIZE(SEQ_ELVSS_CONTROL));
return ret;
}
-static int s6e8ax0_ldi_enable(struct lcd_info *lcd)
+static int s6dr171_ldi_enable(struct lcd_info *lcd)
{
int ret = 0;
- s6e8ax0_write(lcd, SEQ_DISPLAY_ON, ARRAY_SIZE(SEQ_DISPLAY_ON));
+ s6dr171_write(lcd, SEQ_DISPLAY_ON, ARRAY_SIZE(SEQ_DISPLAY_ON));
return ret;
}
-static int s6e8ax0_ldi_disable(struct lcd_info *lcd)
+static int s6dr171_ldi_disable(struct lcd_info *lcd)
{
int ret = 0;
- s6e8ax0_write(lcd, SEQ_DISPLAY_OFF, ARRAY_SIZE(SEQ_DISPLAY_OFF));
- s6e8ax0_write(lcd, SEQ_STANDBY_ON, ARRAY_SIZE(SEQ_STANDBY_ON));
+ s6dr171_write(lcd, SEQ_DISPLAY_OFF, ARRAY_SIZE(SEQ_DISPLAY_OFF));
+ s6dr171_write(lcd, SEQ_STANDBY_ON, ARRAY_SIZE(SEQ_STANDBY_ON));
return ret;
}
-static int s6e8ax0_power_on(struct lcd_info *lcd)
+static int s6dr171_power_on(struct lcd_info *lcd)
{
int ret = 0;
struct lcd_platform_data *pd = NULL;
@@ -195,7 +198,7 @@ static int s6e8ax0_power_on(struct lcd_info *lcd)
/* dev_info(&lcd->ld->dev, "%s\n", __func__); */
- ret = s6e8ax0_ldi_init(lcd);
+ ret = s6dr171_ldi_init(lcd);
if (ret) {
dev_err(&lcd->ld->dev, "failed to initialize ldi.\n");
goto err;
@@ -203,7 +206,7 @@ static int s6e8ax0_power_on(struct lcd_info *lcd)
msleep(120);
- ret = s6e8ax0_ldi_enable(lcd);
+ ret = s6dr171_ldi_enable(lcd);
if (ret) {
dev_err(&lcd->ld->dev, "failed to enable ldi.\n");
goto err;
@@ -216,7 +219,7 @@ err:
return ret;
}
-static int s6e8ax0_power_off(struct lcd_info *lcd)
+static int s6dr171_power_off(struct lcd_info *lcd)
{
int ret = 0;
@@ -224,21 +227,21 @@ static int s6e8ax0_power_off(struct lcd_info *lcd)
lcd->ldi_enable = 0;
- ret = s6e8ax0_ldi_disable(lcd);
+ ret = s6dr171_ldi_disable(lcd);
msleep(135);
return ret;
}
-static int s6e8ax0_power(struct lcd_info *lcd, int power)
+static int s6dr171_power(struct lcd_info *lcd, int power)
{
int ret = 0;
if (POWER_IS_ON(power) && !POWER_IS_ON(lcd->power))
- ret = s6e8ax0_power_on(lcd);
+ ret = s6dr171_power_on(lcd);
else if (!POWER_IS_ON(power) && POWER_IS_ON(lcd->power))
- ret = s6e8ax0_power_off(lcd);
+ ret = s6dr171_power_off(lcd);
if (!ret)
lcd->power = power;
@@ -246,7 +249,7 @@ static int s6e8ax0_power(struct lcd_info *lcd, int power)
return ret;
}
-static int s6e8ax0_set_power(struct lcd_device *ld, int power)
+static int s6dr171_set_power(struct lcd_device *ld, int power)
{
struct lcd_info *lcd = lcd_get_data(ld);
@@ -256,17 +259,17 @@ static int s6e8ax0_set_power(struct lcd_device *ld, int power)
return -EINVAL;
}
- return s6e8ax0_power(lcd, power);
+ return s6dr171_power(lcd, power);
}
-static int s6e8ax0_get_power(struct lcd_device *ld)
+static int s6dr171_get_power(struct lcd_device *ld)
{
struct lcd_info *lcd = lcd_get_data(ld);
return lcd->power;
}
-static int s6e8ax0_set_brightness(struct backlight_device *bd)
+static int s6dr171_set_brightness(struct backlight_device *bd)
{
int ret = 0;
int brightness = bd->props.brightness;
@@ -292,13 +295,13 @@ static int s6e8ax0_set_brightness(struct backlight_device *bd)
return ret;
}
-static struct lcd_ops s6e8ax0_lcd_ops = {
- .set_power = s6e8ax0_set_power,
- .get_power = s6e8ax0_get_power,
+static struct lcd_ops s6dr171_lcd_ops = {
+ .set_power = s6dr171_set_power,
+ .get_power = s6dr171_get_power,
};
-static const struct backlight_ops s6e8ax0_backlight_ops = {
- .update_status = s6e8ax0_set_brightness,
+static const struct backlight_ops s6dr171_backlight_ops = {
+ .update_status = s6dr171_set_brightness,
};
static ssize_t power_reduce_show(struct device *dev,
@@ -329,7 +332,7 @@ static ssize_t power_reduce_store(struct device *dev,
mutex_lock(&lcd->bl_lock);
lcd->acl_enable = value;
/* if (lcd->ldi_enable)
- s6e8ax0_set_acl(lcd); */
+ s6dr171_set_acl(lcd); */
mutex_unlock(&lcd->bl_lock);
}
}
@@ -389,25 +392,25 @@ static DEVICE_ATTR(auto_brightness, 0644, auto_brightness_show, auto_brightness_
#ifdef CONFIG_HAS_EARLYSUSPEND
struct lcd_info *g_lcd;
-void s6e8ax0_early_suspend(void)
+void s6dr171_early_suspend(void)
{
struct lcd_info *lcd = g_lcd;
set_dsim_lcd_enabled(0);
dev_info(&lcd->ld->dev, "+%s\n", __func__);
- s6e8ax0_power(lcd, FB_BLANK_POWERDOWN);
+ s6dr171_power(lcd, FB_BLANK_POWERDOWN);
dev_info(&lcd->ld->dev, "-%s\n", __func__);
return ;
}
-void s6e8ax0_late_resume(void)
+void s6dr171_late_resume(void)
{
struct lcd_info *lcd = g_lcd;
dev_info(&lcd->ld->dev, "+%s\n", __func__);
- s6e8ax0_power(lcd, FB_BLANK_UNBLANK);
+ s6dr171_power(lcd, FB_BLANK_UNBLANK);
dev_info(&lcd->ld->dev, "-%s\n", __func__);
set_dsim_lcd_enabled(1);
@@ -416,28 +419,28 @@ void s6e8ax0_late_resume(void)
}
#endif
-static int s6e8ax0_read_mtp(struct lcd_info *lcd, u8 *mtp_data)
+static int s6dr171_read_mtp(struct lcd_info *lcd, u8 *mtp_data)
{
int ret, i;
for (i = 0; i < 3; i++)
- ret = s6e8ax0_read(lcd, LDI_MTP_ADDR+i, LDI_MTP_LENGTH, mtp_data, 0);
+ ret = s6dr171_read(lcd, LDI_MTP_ADDR+i, LDI_MTP_LENGTH, mtp_data, 0);
return ret;
}
-static void s6e8ax0_read_id(struct lcd_info *lcd, u8 *buf)
+static void s6dr171_read_id(struct lcd_info *lcd, u8 *buf)
{
int ret = 0;
- ret = s6e8ax0_read(lcd, LDI_ID_REG, LDI_ID_LEN, buf, 3);
+ ret = s6dr171_read(lcd, LDI_ID_REG, LDI_ID_LEN, buf, 3);
if (!ret) {
lcd->connected = 0;
dev_info(&lcd->ld->dev, "panel is not connected well\n");
}
}
-static int s6e8ax0_probe(struct device *dev)
+static int s6dr171_probe(struct device *dev)
{
int ret = 0;
struct lcd_info *lcd;
@@ -452,14 +455,14 @@ static int s6e8ax0_probe(struct device *dev)
g_lcd = lcd;
- lcd->ld = lcd_device_register("panel", dev, lcd, &s6e8ax0_lcd_ops);
+ lcd->ld = lcd_device_register("panel", dev, lcd, &s6dr171_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->bd = backlight_device_register("panel", dev, lcd, &s6e8ax0_backlight_ops, NULL);
+ lcd->bd = backlight_device_register("panel", dev, lcd, &s6dr171_backlight_ops, NULL);
if (IS_ERR(lcd->bd)) {
pr_err("failed to register backlight device\n");
ret = PTR_ERR(lcd->bd);
@@ -498,18 +501,21 @@ static int s6e8ax0_probe(struct device *dev)
mutex_init(&lcd->lock);
mutex_init(&lcd->bl_lock);
- s6e8ax0_read_id(lcd, lcd->id);
+ s6dr171_read_id(lcd, lcd->id);
dev_info(&lcd->ld->dev, "ID: %x, %x, %x\n", lcd->id[0], lcd->id[1], lcd->id[2]);
dev_info(&lcd->ld->dev, "lcd panel driver has been probed.\n");
- ret = s6e8ax0_read_mtp(lcd, mtp_data);
+ ret = s6dr171_read_mtp(lcd, mtp_data);
if (!ret) {
printk(KERN_ERR "[LCD:ERROR] : %s read mtp failed\n", __func__);
/*return -EPERM;*/
}
+ lcd_early_suspend = s6dr171_early_suspend;
+ lcd_late_resume = s6dr171_late_resume;
+
return 0;
out_free_backlight:
@@ -525,11 +531,11 @@ err_alloc:
return ret;
}
-static int __devexit s6e8ax0_remove(struct device *dev)
+static int __devexit s6dr171_remove(struct device *dev)
{
struct lcd_info *lcd = dev_get_drvdata(dev);
- s6e8ax0_power(lcd, FB_BLANK_POWERDOWN);
+ s6dr171_power(lcd, FB_BLANK_POWERDOWN);
lcd_device_unregister(lcd->ld);
backlight_device_unregister(lcd->bd);
kfree(lcd);
@@ -538,34 +544,34 @@ static int __devexit s6e8ax0_remove(struct device *dev)
}
/* Power down all displays on reboot, poweroff or halt. */
-static void s6e8ax0_shutdown(struct device *dev)
+static void s6dr171_shutdown(struct device *dev)
{
struct lcd_info *lcd = dev_get_drvdata(dev);
dev_info(&lcd->ld->dev, "%s\n", __func__);
- s6e8ax0_power(lcd, FB_BLANK_POWERDOWN);
+ s6dr171_power(lcd, FB_BLANK_POWERDOWN);
}
-static struct mipi_lcd_driver s6e8ax0_mipi_driver = {
+static struct mipi_lcd_driver s6dr171_mipi_driver = {
.name = "s6e8aa0",
- .probe = s6e8ax0_probe,
- .remove = __devexit_p(s6e8ax0_remove),
- .shutdown = s6e8ax0_shutdown,
+ .probe = s6dr171_probe,
+ .remove = __devexit_p(s6dr171_remove),
+ .shutdown = s6dr171_shutdown,
};
-static int s6e8ax0_init(void)
+static int s6dr171_init(void)
{
- return s5p_dsim_register_lcd_driver(&s6e8ax0_mipi_driver);
+ return s5p_dsim_register_lcd_driver(&s6dr171_mipi_driver);
}
-static void s6e8ax0_exit(void)
+static void s6dr171_exit(void)
{
return;
}
-module_init(s6e8ax0_init);
-module_exit(s6e8ax0_exit);
+module_init(s6dr171_init);
+module_exit(s6dr171_exit);
-MODULE_DESCRIPTION("MIPI-DSI S6E8AA0:AMS529HA01 (800x1280) Panel Driver");
+MODULE_DESCRIPTION("MIPI-DSI S6DR171:AMS480GZ01-0 (720x1280) Panel Driver");
MODULE_LICENSE("GPL");
diff --git a/drivers/video/samsung/s6e63m0_gamma_grande.h b/drivers/video/samsung/s6e63m0_gamma_grande.h
new file mode 100644
index 0000000..4692a78
--- /dev/null
+++ b/drivers/video/samsung/s6e63m0_gamma_grande.h
@@ -0,0 +1,229 @@
+#ifndef __S6E63M0_GAMMA_H__
+#define __S6E63M0_GAMMA_H__
+
+#include "s6e63m0_param.h"
+
+#define ACL_PARAM_SIZE ARRAY_SIZE(acl_cutoff_50)
+#define AID_PARAM_SIZE ARRAY_SIZE(SEQ_PANEL_CONDITION_SET_500MBPS)
+
+static const unsigned char SEQ_PANEL_CONDITION_SET_500MBPS[] = {
+ 0xF8,
+ 0x19, 0x35, 0x00, 0x00, 0x00, 0x94, 0x00, 0x3C, 0x7D, 0x10,
+ 0x27, 0x08, 0x6E, 0x00, 0x00, 0x00, 0x00, 0x04, 0x08, 0x6E,
+ 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x23, 0x6E, 0xC0, 0xC1,
+ 0x01, 0x81, 0xC1, 0x00, 0xC3, 0xF6, 0xF6, 0xC1
+};
+
+static const unsigned char SEQ_PANEL_CONDITION_SET_500MBPS_46[] = {
+ 0xF8,
+ 0x3D, 0x35, 0x00, 0x00, 0x00, 0x93, 0x00, 0x3C, 0x7D, 0x08,
+ 0x27, 0x7D, 0x3F, 0x00, 0x00, 0x00, 0x20, 0x04, 0x08, 0x6E,
+ 0x00, 0x00, 0x00, 0x02, 0x08, 0x08, 0x23, 0x23, 0xC0, 0xC8,
+ 0x08, 0x48, 0xC1, 0x00, 0xC1, 0xFF, 0xFF, 0xC8
+};
+
+static const unsigned char SEQ_PANEL_CONDITION_SET_480MBPS_46[] = {
+ 0xF8,
+ 0x3D, 0x32, 0x00, 0x00, 0x00, 0x8D, 0x00, 0x39, 0x78, 0x08,
+ 0x26, 0x78, 0x3C, 0x00, 0x00, 0x00, 0x20, 0x04, 0x08, 0x69,
+ 0x00, 0x00, 0x00, 0x02, 0x07, 0x07, 0x21, 0x21, 0xC0, 0xC8,
+ 0x08, 0x48, 0xC1, 0x00, 0xC1, 0xFF, 0xFF, 0xC8
+};
+#if !defined(CONFIG_MACH_M0_GRANDECTC) && !defined(CONFIG_MACH_IRON)
+static const unsigned char SEQ_GAMMA_CONDITION_SET[] = {
+ 0xFA,
+ 0x01, 0x58, 0x1F, 0x63, 0xAC, 0xB4, 0x99, 0xAD, 0xBA, 0xA3,
+ 0xC0, 0xCB, 0xBB, 0x93, 0x9F, 0x8B, 0xAD, 0xB4, 0xA7, 0x00,
+ 0xBE, 0x00, 0xAB, 0x00, 0xE7
+};
+#endif
+static const unsigned char SEQ_GAMMA_CONDITION_SET_A1_SM2[] = {
+ 0xFA,
+ 0x01, 0x71, 0x31, 0x7B, 0xA4, 0xB6,
+ 0x95, 0xA9, 0xBC, 0xA2, 0xBB, 0xC9,
+ 0xB6, 0x91, 0xA3, 0x8B, 0xAD, 0xB6,
+ 0xA9, 0x00, 0xD6, 0x00, 0xBE, 0x00,
+ 0xFC,
+};
+
+static const unsigned char SEQ_GAMMA_CONDITION_SET_A2_SM2[] = {
+ 0xFA,
+ 0x01, 0x5F, 0x2E, 0x67, 0xAA, 0xC6,
+ 0xAC, 0xB0, 0xC8, 0xBB, 0xBE, 0xCB,
+ 0xBD, 0x97, 0xA5, 0x91, 0xAF, 0xB8,
+ 0xAB, 0x00, 0xC2, 0x00, 0xBA, 0x00, 0xE2,
+};
+#if !defined(CONFIG_MACH_M0_GRANDECTC) && !defined(CONFIG_MACH_IRON)
+static const unsigned char SEQ_ETC_SOURCE_CONTROL[] = {
+ 0xF6,
+ 0x00, 0x02, 0x00
+};
+#endif
+
+static const unsigned char SEQ_ETC_PENTILE_CONTROL[] = {
+ 0xB6,
+ 0x0C, 0x02, 0x03, 0x32, 0xC0,
+ 0x44, 0x44, 0xC0, 0x00
+};
+
+static const unsigned char SEQ_ETC_PENTILE_CONTROL_46[] = {
+ 0xB6,
+ 0x0C, 0x02, 0x03, 0x32, 0xFF,
+ 0x44, 0x44, 0xC0, 0x00
+};
+
+static const unsigned char SEQ_ETC_NVM_SETTING[] = {
+ 0xD9,
+ 0x14, 0x40, 0x0C, 0xCB, 0xCE,
+ 0x6E, 0xC4, 0x07, 0xC0, 0x41,
+ 0xC1, 0x00, 0x60, 0x19
+};
+
+static const unsigned char SEQ_ETC_NVM_SETTING_46[] = {
+ 0xD9,
+ 0x14, 0x40, 0x0C, 0xCB, 0xCE,
+ 0x6E, 0xC4, 0x07, 0xC0, 0x41,
+ 0xD0, 0x00, 0x60, 0x19
+};
+
+static const unsigned char SEQ_ETC_POWER_CONTROL[] = {
+ 0xF4,
+ 0xCF, 0x0A, 0x15, 0x10, 0x19, 0x33, 0x02
+};
+
+static const unsigned char SEQ_ETC_POWER_CONTROL_46[] = {
+ 0xF4,
+ 0xCF, 0x0A, 0x12, 0x10, 0x1E, 0x33, 0x02
+};
+
+
+enum {
+ ACL_STATUS_0P = 0,
+ ACL_STATUS_20P,
+ ACL_STATUS_33P,
+ ACL_STATUS_40P,
+ ACL_STATUS_43P,
+ ACL_STATUS_45P,
+ ACL_STATUS_48P,
+ ACL_STATUS_50P,
+ ACL_STATUS_52P,
+ ACL_STATUS_53P,
+ ACL_STATUS_55P,
+ ACL_STATUS_MAX
+} ACL_STATUS;
+
+const unsigned char acl_cutoff_20[] = {
+ 0xC1,
+ 0x47, 0x53, 0x13, 0x53, 0x00, 0x00,
+ 0x02, 0xCF, 0x00, 0x00, 0x04, 0xFF,
+ 0x00, 0x00, 0x00, 0x00, 0x00,
+
+ 0x01, 0x04, 0x07, 0x0A, 0x0D, 0x10,
+ 0x12, 0x15, 0x18, 0x1B, 0x1E
+};
+
+const unsigned char acl_cutoff_33[] = {
+ 0xC1,
+ 0x47, 0x53, 0x13, 0x53, 0x00, 0x00,
+ 0x02, 0xCF, 0x00, 0x00, 0x04, 0xFF,
+ 0x00, 0x00, 0x00, 0x00, 0x00,
+
+ 0x01, 0x06, 0x0A, 0x0F, 0x14, 0x19,
+ 0x1D, 0x22, 0x27, 0x2B, 0x30
+};
+
+const unsigned char acl_cutoff_40[] = {
+ 0xC1,
+ 0x47, 0x53, 0x13, 0x53, 0x00, 0x00,
+ 0x02, 0xCF, 0x00, 0x00, 0x04, 0xFF,
+ 0x00, 0x00, 0x00, 0x00, 0x00,
+
+ 0x01, 0x08, 0x0F, 0x15, 0x1C, 0x23,
+ 0x2A, 0x31, 0x37, 0x3E, 0x45
+};
+
+const unsigned char acl_cutoff_43[] = {
+ 0xC1,
+ 0x47, 0x53, 0x13, 0x53, 0x00, 0x00,
+ 0x02, 0xCF, 0x00, 0x00, 0x04, 0xFF,
+ 0x00, 0x00, 0x00, 0x00, 0x00,
+
+ 0x01, 0x07, 0x0D, 0x14, 0x1A, 0x20,
+ 0x26, 0x2C, 0x33, 0x39, 0x3F
+};
+
+const unsigned char acl_cutoff_45[] = {
+ 0xC1,
+ 0x47, 0x53, 0x13, 0x53, 0x00, 0x00,
+ 0x02, 0xCF, 0x00, 0x00, 0x04, 0xFF,
+ 0x00, 0x00, 0x00, 0x00, 0x00,
+
+ 0x01, 0x07, 0x0E, 0x14, 0x1B, 0x21,
+ 0x27, 0x2E, 0x34, 0x3B, 0x41
+};
+
+const unsigned char acl_cutoff_48[] = {
+ 0xC1,
+ 0x47, 0x53, 0x13, 0x53, 0x00, 0x00,
+ 0x02, 0xCF, 0x00, 0x00, 0x04, 0xFF,
+ 0x00, 0x00, 0x00, 0x00, 0x00,
+
+ 0x01, 0x08, 0x0F, 0x17, 0x1E, 0x25,
+ 0x2C, 0x33, 0x3B, 0x42, 0x49
+};
+
+const unsigned char acl_cutoff_50[] = {
+ 0xC1,
+ 0x47, 0x53, 0x13, 0x53, 0x00, 0x00,
+ 0x02, 0xCF, 0x00, 0x00, 0x04, 0xFF,
+ 0x00, 0x00, 0x00, 0x00, 0x00,
+
+ 0x01, 0x09, 0x10, 0x18, 0x1F, 0x27,
+ 0x2E, 0x36, 0x3D, 0x45, 0x4C
+};
+
+const unsigned char acl_cutoff_52[] = {
+ 0xC1,
+ 0x47, 0x53, 0x13, 0x53, 0x00, 0x00,
+ 0x02, 0xCF, 0x00, 0x00, 0x04, 0xFF,
+ 0x00, 0x00, 0x00, 0x00, 0x00,
+
+ 0x01, 0x09, 0x11, 0x19, 0x21, 0x29,
+ 0x31, 0x39, 0x41, 0x49, 0x51
+};
+
+const unsigned char acl_cutoff_53[] = {
+ 0xC1,
+ 0x47, 0x53, 0x13, 0x53, 0x00, 0x00,
+ 0x02, 0xCF, 0x00, 0x00, 0x04, 0xFF,
+ 0x00, 0x00, 0x00, 0x00, 0x00,
+
+ 0x01, 0x09, 0x11, 0x1A, 0x22, 0x2A,
+ 0x32, 0x3A, 0x43, 0x4B, 0x53
+};
+
+const unsigned char acl_cutoff_55[] = {
+ 0xC1,
+ 0x47, 0x53, 0x13, 0x53, 0x00, 0x00,
+ 0x02, 0xCF, 0x00, 0x00, 0x04, 0xFF,
+ 0x00, 0x00, 0x00, 0x00, 0x00,
+
+ 0x01, 0x0A, 0x12, 0x1B, 0x23, 0x2C,
+ 0x35, 0x3D, 0x46, 0x4E, 0x57
+};
+
+const unsigned char *ACL_CUTOFF_TABLE[ACL_STATUS_MAX] = {
+ SEQ_ACL_OFF,
+ acl_cutoff_20,
+ acl_cutoff_33,
+ acl_cutoff_40,
+ acl_cutoff_43,
+ acl_cutoff_45,
+ acl_cutoff_48,
+ acl_cutoff_50,
+ acl_cutoff_52,
+ acl_cutoff_53,
+ acl_cutoff_55,
+};
+
+#endif /* __S6E63M0_GAMMA_H__ */
diff --git a/drivers/video/samsung/s6e63m0_gamma_l.h b/drivers/video/samsung/s6e63m0_gamma_l.h
new file mode 100644
index 0000000..8d57c5a
--- /dev/null
+++ b/drivers/video/samsung/s6e63m0_gamma_l.h
@@ -0,0 +1,311 @@
+#ifndef __S6E63M0_GAMMA_L_H__
+#define __S6E63M0_GAMMA_L_H__
+
+#include "s6e63m0_param.h"
+#ifdef CONFIG_AID_DIMMING
+#include "aid_s6e8aa0.h"
+#endif
+
+static const unsigned char gamma22_20[] = {
+ 0xFA, 0x01,
+ 0x1F, 0x1F, 0x1F, 0xDF, 0x86, 0xF5,
+ 0xD5, 0xC7, 0xCF, 0xDF, 0xE0, 0xE0,
+ 0xC9, 0xC9, 0xCC, 0xD7, 0xD6, 0xD5,
+ 0x00, 0x68, 0x00, 0x68, 0x00, 0x75,
+};
+
+static const unsigned char gamma22_30[] = {
+ 0xFA, 0x01,
+ 0x1F, 0x1F, 0x1F, 0xDF, 0x86, 0xF5,
+ 0xD5, 0xC7, 0xCF, 0xDF, 0xE0, 0xE0,
+ 0xC9, 0xC9, 0xCC, 0xD7, 0xD6, 0xD5,
+ 0x00, 0x68, 0x00, 0x68, 0x00, 0x75,
+};
+
+static const unsigned char gamma22_40[] = {
+ 0xFA, 0x01,
+ 0x1F, 0x1F, 0x1F, 0xE5, 0xAA, 0xF2,
+ 0xD6, 0xCC, 0xCF, 0xE0, 0xE2, 0xE2,
+ 0xC8, 0xC9, 0xCA, 0xD2, 0xD2, 0xCF,
+ 0x00, 0x71, 0x00, 0x70, 0x00, 0x80,
+};
+
+static const unsigned char gamma22_50[] = {
+ 0xFA, 0x01,
+ 0x1F, 0x1F, 0x1F, 0xE7, 0xBB, 0xEE,
+ 0xD6, 0xCE, 0xD0, 0xE0, 0xE3, 0xE4,
+ 0xC5, 0xC4, 0xC5, 0xD2, 0xD2, 0xCF,
+ 0x00, 0x78, 0x00, 0x78, 0x00, 0x88,
+};
+
+static const unsigned char gamma22_60[] = {
+ 0xFA, 0x01,
+ 0x1F, 0x1F, 0x1F, 0xE9, 0xC4, 0xEB,
+ 0xD6, 0xD0, 0xD1, 0xE0, 0xE3, 0xE4,
+ 0xC3, 0xC2, 0xC2, 0xD2, 0xD1, 0xCF,
+ 0x00, 0x7E, 0x00, 0x7E, 0x00, 0x8F,
+};
+
+static const unsigned char gamma22_70[] = {
+ 0xFA, 0x01,
+ 0x1F, 0x1F, 0x1F, 0xEA, 0xC9, 0xEA,
+ 0xD6, 0xD2, 0xD2, 0xDF, 0xE1, 0xE3,
+ 0xC2, 0xC1, 0xC0, 0xD1, 0xD0, 0xCE,
+ 0x00, 0x84, 0x00, 0x84, 0x00, 0x96,
+};
+
+static const unsigned char gamma22_80[] = {
+ 0xFA, 0x01,
+ 0x1F, 0x1F, 0x1F, 0xEB, 0xCC, 0xE9,
+ 0xD5, 0xD4, 0xD3, 0xDE, 0xE1, 0xE2,
+ 0xC2, 0xBF, 0xBF, 0xCF, 0xCF, 0xCC,
+ 0x00, 0x89, 0x00, 0x89, 0x00, 0x9C,
+};
+
+static const unsigned char gamma22_90[] = {
+ 0xFA, 0x01,
+ 0x1F, 0x1F, 0x1F, 0xEB, 0xD0, 0xE9,
+ 0xD4, 0xD5, 0xD4, 0xDF, 0xE0, 0xE1,
+ 0xC1, 0xBE, 0xBD, 0xCD, 0xCD, 0xCA,
+ 0x00, 0x8E, 0x00, 0x8F, 0x00, 0xA2,
+};
+
+static const unsigned char gamma22_100[] = {
+ 0xFA, 0x01,
+ 0x1F, 0x1F, 0x1F, 0xEA, 0xD2, 0xE7,
+ 0xD7, 0xD6, 0xD6, 0xDF, 0xDF, 0xE2,
+ 0xBF, 0xBD, 0xBC, 0xCD, 0xCD, 0xC9,
+ 0x00, 0x92, 0x00, 0x93, 0x00, 0xA7,
+};
+
+static const unsigned char gamma22_110[] = {
+ 0xFA, 0x01,
+ 0x1F, 0x1F, 0x1F, 0xEB, 0xD4, 0xE5,
+ 0xD6, 0xD6, 0xD7, 0xDE, 0xDF, 0xE0,
+ 0xBE, 0xBC, 0xBB, 0xCE, 0xCC, 0xC9,
+ 0x00, 0x96, 0x00, 0x97, 0x00, 0xAC,
+};
+
+static const unsigned char gamma22_120[] = {
+ 0xFA, 0x01,
+ 0x1F, 0x1F, 0x1F, 0xED, 0xD6, 0xE6,
+ 0xD6, 0xD7, 0xD8, 0xDE, 0xDE, 0xE0,
+ 0xBC, 0xBC, 0xB9, 0xCD, 0xCA, 0xC8,
+ 0x00, 0x9A, 0x00, 0x9C, 0x00, 0xB1,
+};
+
+static const unsigned char gamma22_130[] = {
+ 0xFA, 0x01,
+ 0x1F, 0x1F, 0x1F, 0xEC, 0xD7, 0xE6,
+ 0xD3, 0xD8, 0xD7, 0xDE, 0xDD, 0xDF,
+ 0xBD, 0xBB, 0xB8, 0xCA, 0xC9, 0xC6,
+ 0x00, 0x9F, 0x00, 0xA0, 0x00, 0xB7,
+};
+
+static const unsigned char gamma22_140[] = {
+ 0xFA, 0x01,
+ 0x1F, 0x1F, 0x1F, 0xEC, 0xD9, 0xE5,
+ 0xD4, 0xD8, 0xD9, 0xDE, 0xDD, 0xDF,
+ 0xBB, 0xB9, 0xB7, 0xCA, 0xC9, 0xC5,
+ 0x00, 0xA3, 0x00, 0xA4, 0x00, 0xBB,
+};
+
+static const unsigned char gamma22_150[] = {
+ 0xFA, 0x01,
+ 0x1F, 0x1F, 0x1F, 0xEC, 0xDA, 0xE5,
+ 0xD4, 0xD8, 0xD9, 0xDD, 0xDD, 0xDD,
+ 0xBB, 0xB9, 0xB6, 0xC9, 0xC7, 0xC5,
+ 0x00, 0xA6, 0x00, 0xA8, 0x00, 0xBF,
+};
+
+static const unsigned char gamma22_160[] = {
+ 0xFA, 0x01,
+ 0x1F, 0x1F, 0x1F, 0xED, 0xDB, 0xE6,
+ 0xD4, 0xD7, 0xD9, 0xDC, 0xDD, 0xDD,
+ 0xB9, 0xB8, 0xB4, 0xC9, 0xC6, 0xC4,
+ 0x00, 0xAA, 0x00, 0xAC, 0x00, 0xC4,
+};
+
+static const unsigned char gamma22_170[] = {
+ 0xFA, 0x01,
+ 0x1F, 0x1F, 0x1F, 0xEC, 0xDC, 0xE5,
+ 0xD5, 0xD8, 0xD9, 0xDD, 0xDC, 0xDD,
+ 0xBA, 0xB7, 0xB5, 0xC7, 0xC6, 0xC3,
+ 0x00, 0xAD, 0x00, 0xAF, 0x00, 0xC7,
+};
+
+static const unsigned char gamma22_180[] = {
+ 0xFA, 0x01,
+ 0x1F, 0x1F, 0x1F, 0xEE, 0xDD, 0xE6,
+ 0xD4, 0xD7, 0xD9, 0xDB, 0xDC, 0xDB,
+ 0xB9, 0xB7, 0xB4, 0xC6, 0xC4, 0xC2,
+ 0x00, 0xB1, 0x00, 0xB3, 0x00, 0xCC,
+};
+
+#ifdef CONFIG_AID_DIMMING
+static const unsigned char gamma22_182[] = {
+ 0xFA, 0x01,
+ 0x1F, 0x1F, 0x1F, 0xEE, 0xDD, 0xE6,
+ 0xD4, 0xD7, 0xD9, 0xDB, 0xDC, 0xDB,
+ 0xB9, 0xB7, 0xB4, 0xC6, 0xC4, 0xC2,
+ 0x00, 0xB1, 0x00, 0xB3, 0x00, 0xCC,
+};
+
+static const unsigned char gamma22_184[] = {
+ 0xFA, 0x01,
+ 0x1F, 0x1F, 0x1F, 0xEE, 0xDD, 0xE6,
+ 0xD4, 0xD7, 0xD9, 0xDB, 0xDC, 0xDB,
+ 0xB9, 0xB7, 0xB4, 0xC6, 0xC4, 0xC2,
+ 0x00, 0xB1, 0x00, 0xB3, 0x00, 0xCC,
+};
+
+static const unsigned char gamma22_186[] = {
+ 0xFA, 0x01,
+ 0x1F, 0x1F, 0x1F, 0xEE, 0xDD, 0xE6,
+ 0xD4, 0xD7, 0xD9, 0xDB, 0xDC, 0xDB,
+ 0xB9, 0xB7, 0xB4, 0xC6, 0xC4, 0xC2,
+ 0x00, 0xB1, 0x00, 0xB3, 0x00, 0xCC,
+};
+
+static const unsigned char gamma22_188[] = {
+ 0xFA, 0x01,
+ 0x1F, 0x1F, 0x1F, 0xEE, 0xDD, 0xE6,
+ 0xD4, 0xD7, 0xD9, 0xDB, 0xDC, 0xDB,
+ 0xB9, 0xB7, 0xB4, 0xC6, 0xC4, 0xC2,
+ 0x00, 0xB1, 0x00, 0xB3, 0x00, 0xCC,
+};
+#endif
+
+static const unsigned char gamma22_190[] = {
+ 0xFA, 0x01,
+ 0x1F, 0x1F, 0x1F, 0xED, 0xDE, 0xE6,
+ 0xD3, 0xD8, 0xD8, 0xDD, 0xDB, 0xDC,
+ 0xB9, 0xB6, 0xB4, 0xC5, 0xC4, 0xC0,
+ 0x00, 0xB4, 0x00, 0xB6, 0x00, 0xD0,
+};
+
+static const unsigned char gamma22_200[] = {
+ 0xFA, 0x01,
+ 0x1F, 0x1F, 0x1F, 0xED, 0xDF, 0xE6,
+ 0xD3, 0xD7, 0xD8, 0xDB, 0xDB, 0xDA,
+ 0xB8, 0xB6, 0xB3, 0xC4, 0xC3, 0xC0,
+ 0x00, 0xB8, 0x00, 0xB9, 0x00, 0xD4,
+};
+
+static const unsigned char gamma22_210[] = {
+ 0xFA, 0x01,
+ 0x1F, 0x1F, 0x1F, 0xEC, 0xE0, 0xE5,
+ 0xD5, 0xD7, 0xD9, 0xDB, 0xDA, 0xDA,
+ 0xB7, 0xB5, 0xB1, 0xC4, 0xC2, 0xC0,
+ 0x00, 0xBA, 0x00, 0xBD, 0x00, 0xD7,
+};
+
+static const unsigned char gamma22_220[] = {
+ 0xFA, 0x01,
+ 0x1F, 0x1F, 0x1F, 0xED, 0xE0, 0xE6,
+ 0xD4, 0xD7, 0xD9, 0xDA, 0xDA, 0xD9,
+ 0xB7, 0xB4, 0xB1, 0xC2, 0xC2, 0xBE,
+ 0x00, 0xBE, 0x00, 0xC0, 0x00, 0xDC,
+};
+
+static const unsigned char gamma22_230[] = {
+ 0xFA, 0x01,
+ 0x1F, 0x1F, 0x1F, 0xEC, 0xE2, 0xE6,
+ 0xD3, 0xD6, 0xD8, 0xDC, 0xD9, 0xD9,
+ 0xB6, 0xB4, 0xB1, 0xC1, 0xC1, 0xBD,
+ 0x00, 0xC1, 0x00, 0xC3, 0x00, 0xDF,
+};
+
+static const unsigned char gamma22_240[] = {
+ 0xFA, 0x01,
+ 0x1F, 0x1F, 0x1F, 0xED, 0xE2, 0xE6,
+ 0xD4, 0xD6, 0xD8, 0xDA, 0xDA, 0xDA,
+ 0xB6, 0xB3, 0xB0, 0xC1, 0xBF, 0xBC,
+ 0x00, 0xC4, 0x00, 0xC7, 0x00, 0xE3,
+};
+
+static const unsigned char gamma22_250[] = {
+ 0xFA, 0x01,
+ 0x1F, 0x1F, 0x1F, 0xED, 0xE3, 0xE7,
+ 0xD4, 0xD6, 0xD8, 0xDB, 0xD9, 0xD9,
+ 0xB3, 0xB2, 0xAE, 0xC1, 0xC0, 0xBC,
+ 0x00, 0xC7, 0x00, 0xC9, 0x00, 0xE7,
+};
+
+static const unsigned char gamma22_260[] = {
+ 0xFA, 0x01,
+ 0x1F, 0x1F, 0x1F, 0xED, 0xE4, 0xE7,
+ 0xD4, 0xD5, 0xD7, 0xDA, 0xD9, 0xD9,
+ 0xB3, 0xB2, 0xAD, 0xC1, 0xBE, 0xBC,
+ 0x00, 0xC9, 0x00, 0xCD, 0x00, 0xEA,
+};
+
+static const unsigned char gamma22_270[] = {
+ 0xFA, 0x01,
+ 0x1F, 0x1F, 0x1F, 0xED, 0xE5, 0xE8,
+ 0xD3, 0xD5, 0xD5, 0xDB, 0xD9, 0xD9,
+ 0xB3, 0xB1, 0xAE, 0xBF, 0xBE, 0xBA,
+ 0x00, 0xCC, 0x00, 0xD0, 0x00, 0xEE,
+};
+
+static const unsigned char gamma22_280[] = {
+ 0xFA, 0x01,
+ 0x1F, 0x1F, 0x1F, 0xEC, 0xE5, 0xE6,
+ 0xD2, 0xD4, 0xD6, 0xDA, 0xD9, 0xD8,
+ 0xB3, 0xB1, 0xAD, 0xBF, 0xBD, 0xBA,
+ 0x00, 0xCF, 0x00, 0xD3, 0x00, 0xF1,
+};
+
+static const unsigned char gamma22_290[] = {
+ 0xFA, 0x01,
+ 0x1F, 0x1F, 0x1F, 0xEC, 0xE6, 0xE7,
+ 0xD2, 0xD4, 0xD5, 0xDB, 0xD8, 0xD8,
+ 0xB1, 0xB0, 0xAC, 0xBE, 0xBD, 0xB9,
+ 0x00, 0xD3, 0x00, 0xD6, 0x00, 0xF5,
+};
+
+static const unsigned char gamma22_300[] = {
+ 0xFA, 0x01,
+ 0x1F, 0x1F, 0x1F, 0xED, 0xE6, 0xE7,
+ 0xD1, 0xD3, 0xD4, 0xDA, 0xD8, 0xD7,
+ 0xB1, 0xAF, 0xAB, 0xBD, 0xBB, 0xB8,
+ 0x00, 0xD6, 0x00, 0xDA, 0x00, 0xFA,
+};
+
+static const unsigned char *gamma22_table[GAMMA_MAX] = {
+#ifdef CONFIG_AID_DIMMING
+ gamma22_20,
+#endif
+ gamma22_30,
+ gamma22_40,
+ gamma22_50,
+ gamma22_60,
+ gamma22_70,
+ gamma22_80,
+ gamma22_90,
+ gamma22_100,
+ gamma22_110,
+ gamma22_120,
+ gamma22_130,
+ gamma22_140,
+ gamma22_150,
+ gamma22_160,
+ gamma22_170,
+ gamma22_180,
+#ifdef CONFIG_AID_DIMMING
+ gamma22_182,
+ gamma22_184,
+ gamma22_186,
+ gamma22_188,
+#endif
+ gamma22_190,
+ gamma22_200,
+ gamma22_210,
+ gamma22_220,
+ gamma22_230,
+ gamma22_240,
+ gamma22_250,
+ gamma22_300,
+};
+
+#endif /* __S6E63M0_GAMMA_L_H__ */
diff --git a/drivers/video/samsung/s6e63m0_param.h b/drivers/video/samsung/s6e63m0_param.h
new file mode 100644
index 0000000..c69ed45b
--- /dev/null
+++ b/drivers/video/samsung/s6e63m0_param.h
@@ -0,0 +1,375 @@
+#ifndef __S6E63M0_PARAM_H__
+#define __S6E63M0_PARAM_H__
+
+#define GAMMA_PARAM_SIZE 26
+#define ELVSS_PARAM_SIZE 3
+
+#define ELVSS_OFFSET_300 0x00
+#define ELVSS_OFFSET_290 0x01
+#define ELVSS_OFFSET_280 0x02
+#define ELVSS_OFFSET_270 0x03
+#define ELVSS_OFFSET_260 0x04
+#define ELVSS_OFFSET_250 0x05
+#define ELVSS_OFFSET_240 0x06
+#define ELVSS_OFFSET_230 0x06
+#define ELVSS_OFFSET_220 0x07
+#define ELVSS_OFFSET_210 0x08
+#define ELVSS_OFFSET_200 0x09
+#define ELVSS_OFFSET_190 0x05
+#define ELVSS_OFFSET_180 0x05
+#define ELVSS_OFFSET_170 0x06
+#define ELVSS_OFFSET_160 0x07
+#define ELVSS_OFFSET_150 0x08
+#define ELVSS_OFFSET_140 0x09
+#define ELVSS_OFFSET_130 0x0A
+#define ELVSS_OFFSET_120 0x0B
+#define ELVSS_OFFSET_110 0x0C
+#define ELVSS_OFFSET_100 0x0D
+#define ELVSS_OFFSET_090 0x0E
+#define ELVSS_OFFSET_080 0x0F
+#define ELVSS_OFFSET_070 0x10
+#define ELVSS_OFFSET_060 0x11
+#define ELVSS_OFFSET_050 0x12
+
+#if defined(CONFIG_MACH_Q1_BD)
+#define ELVSS_OFFSET_MAX ELVSS_OFFSET_300
+#define ELVSS_OFFSET_1 ELVSS_OFFSET_210
+#define ELVSS_OFFSET_2 ELVSS_OFFSET_100
+#define ELVSS_OFFSET_MIN ELVSS_OFFSET_060
+#else
+#define ELVSS_OFFSET_MAX ELVSS_OFFSET_300
+#define ELVSS_OFFSET_1 ELVSS_OFFSET_210
+#define ELVSS_OFFSET_2 ELVSS_OFFSET_1
+#define ELVSS_OFFSET_MIN ELVSS_OFFSET_050
+#endif
+
+#ifdef CONFIG_AID_DIMMING
+enum {
+ ELVSS_110 = 0,
+ ELVSS_120,
+ ELVSS_130,
+ ELVSS_140,
+ ELVSS_150,
+ ELVSS_160,
+ ELVSS_170,
+ ELVSS_180,
+ ELVSS_190,
+ ELVSS_200,
+ ELVSS_210,
+ ELVSS_220,
+ ELVSS_230,
+ ELVSS_240,
+ ELVSS_250,
+ ELVSS_260,
+ ELVSS_270,
+ ELVSS_280,
+ ELVSS_290,
+ ELVSS_300,
+ ELVSS_STATUS_MAX,
+};
+
+#else
+enum {
+ ELVSS_MIN = 0,
+ ELVSS_1,
+ ELVSS_2,
+ ELVSS_MAX,
+ ELVSS_STATUS_MAX,
+};
+#endif
+
+enum {
+ GAMMA_20CD,
+#ifdef CONFIG_AID_DIMMING
+ GAMMA_30CD,
+#else
+ GAMMA_30CD = GAMMA_20CD,
+#endif
+ GAMMA_40CD,
+ GAMMA_50CD,
+ GAMMA_60CD,
+ GAMMA_70CD,
+ GAMMA_80CD,
+ GAMMA_90CD,
+ GAMMA_100CD,
+ GAMMA_110CD,
+ GAMMA_120CD,
+ GAMMA_130CD,
+ GAMMA_140CD,
+ GAMMA_150CD,
+ GAMMA_160CD,
+ GAMMA_170CD,
+ GAMMA_180CD,
+#ifdef CONFIG_AID_DIMMING
+ GAMMA_182CD,
+ GAMMA_184CD,
+ GAMMA_186CD,
+ GAMMA_188CD,
+#endif
+ GAMMA_190CD,
+ GAMMA_200CD,
+ GAMMA_210CD,
+ GAMMA_220CD,
+ GAMMA_230CD,
+ GAMMA_240CD,
+ GAMMA_250CD,
+ GAMMA_290CD,
+ GAMMA_300CD = GAMMA_290CD,
+ GAMMA_MAX
+};
+
+#if 0
+static const unsigned char SEQ_APPLY_LEVEL_2_KEY[] = {
+ 0xFC,
+ 0x5A, 0x5A
+};
+
+static const unsigned char SEQ_APPLY_LEVEL_2[] = {
+ 0xF0,
+ 0x5A, 0x5A
+};
+
+static const unsigned char SEQ_APPLY_MTP_KEY_ENABLE[] = {
+ 0xF1,
+ 0x5A, 0x5A
+};
+
+static const unsigned char SEQ_SLEEP_OUT[] = {
+ 0x11,
+ 0x00, 0x00
+};
+
+static const unsigned char SEQ_DISPLAY_CONDITION_SET[] = {
+ 0xF2,
+ 0x80, 0x03, 0x0D
+};
+
+static const unsigned char SEQ_GAMMA_UPDATE[] = {
+ 0xF7, 0x03,
+ 0x00
+};
+
+static const unsigned char SEQ_ELVSS_CONTROL[] = {
+ 0xB1,
+ 0x04, 0x00
+};
+
+static const unsigned char SEQ_DISPLAY_ON[] = {
+ 0x29,
+ 0x00, 0x00
+};
+
+static const unsigned char SEQ_DISPLAY_OFF[] = {
+ 0x28,
+ 0x00, 0x00
+};
+
+static const unsigned char SEQ_STANDBY_ON[] = {
+ 0x01,
+ 0x00, 0x00
+};
+
+static const unsigned char SEQ_ACL_ON[] = {
+ 0xC0, 0x01,
+ 0x00
+};
+
+static const unsigned char SEQ_ACL_OFF[] = {
+ 0xC0, 0x00,
+ 0x00
+};
+
+static const unsigned char SEQ_ELVSS_32[] = {
+ 0xB1,
+ 0x04, 0x9F
+};
+
+static const unsigned char SEQ_ELVSS_34[] = {
+ 0xB1,
+ 0x04, 0x9D
+};
+
+static const unsigned char SEQ_ELVSS_38[] = {
+ 0xB1,
+ 0x04, 0x99
+};
+
+static const unsigned char SEQ_ELVSS_47[] = {
+ 0xB1,
+ 0x04, 0x90
+};
+
+static const unsigned char *ELVSS_TABLE[] = {
+ SEQ_ELVSS_32,
+ SEQ_ELVSS_34,
+ SEQ_ELVSS_38,
+ SEQ_ELVSS_47,
+};
+#endif
+
+#if defined(CONFIG_MACH_M0_GRANDECTC) || defined(CONFIG_MACH_IRON)
+static const unsigned char SEQ_SW_RESET[] = {
+ 0x01,
+ 0x00, 0x00
+};
+#endif
+
+static const unsigned char SEQ_APPLY_LEVEL2_KEY_ENABLE[] = {
+ 0xF0,
+ 0x5A, 0x5A
+};
+
+static const unsigned char SEQ_APPLY_MTP_KEY_ENABLE[] = {
+ 0xF1,
+ 0x5A, 0x5A
+};
+
+static const unsigned char SEQ_SLEEP_OUT[] = {
+ 0x11,
+ 0x00, 0x00
+};
+
+static const unsigned char SEQ_GAMMA_CONDITION_SET[] = {
+ 0xFA,
+ 0x02, 0x18, 0x08, 0x24, 0x6B, 0x76, 0x57, 0xBD, 0xC3, 0xB5,
+ 0xB4, 0xBB, 0xAC, 0xC5, 0xC9, 0xC0, 0x00, 0xB7, 0x00, 0xAB,
+ 0x00, 0xCF,
+};
+
+const unsigned char SEQ_PANEL_CONDITION_SET[] = {
+ 0xF8,
+ 0x01, 0x27, 0x27, 0x07, 0x07, 0x54, 0x9F, 0x63, 0x86, 0x1A,
+ 0x33, 0x0D, 0x00, 0x00,
+};
+
+const unsigned char SEQ_DISPLAY_CONDITION_SET1[] = {
+ 0xF2,
+ 0x02, 0x03, 0x1C, 0x10, 0x10,
+};
+
+const unsigned char SEQ_DISPLAY_CONDITION_SET2[] = {
+ 0xF7,
+ 0x10, 0x00, 0x00,
+};
+
+static const unsigned char SEQ_GAMMA_UPDATE[] = {
+ 0xFA, 0x03,
+};
+
+static const unsigned char SEQ_ETC_SOURCE_CONTROL[] = {
+ 0xF6,
+ 0x00, 0x8E, 0x07,
+};
+
+static const unsigned char SEQ_ETC_CONTROL_B3h[] = {
+ 0xB3, 0x0C,
+};
+
+#if 0
+static const unsigned char SEQ_ETC_CONTROL_B5h[] = {
+ 0xB5,
+ 0x2C, 0x12, 0x0C, 0x0A, 0x10, 0x0E, 0x17, 0x13,
+ 0x1F, 0x1A, 0x2A, 0x24, 0x1F, 0x1B, 0x1A, 0x17,
+ 0x2B, 0x26, 0x22, 0x20, 0x3A, 0x34, 0x30, 0x2C,
+ 0x29, 0x26, 0x25, 0x23, 0x21, 0x20, 0x1E, 0x1E,
+};
+
+static const unsigned char SEQ_ETC_CONTROL_B6h[] = {
+ 0xB6,
+ 0x00, 0x00, 0x11, 0x22, 0x33, 0x44, 0x44, 0x44,
+ 0x55, 0x55, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
+};
+
+static const unsigned char SEQ_ETC_CONTROL_B7h[] = {
+ 0xB7,
+ 0x2C, 0x12, 0x0C, 0x0A, 0x10, 0x0E, 0x17, 0x13,
+ 0x1F, 0x1A, 0x2A, 0x24, 0x1F, 0x1B, 0x1A, 0x17,
+ 0x2B, 0x26, 0x22, 0x20, 0x3A, 0x34, 0x30, 0x2C,
+ 0x29, 0x26, 0x25, 0x23, 0x21, 0x20, 0x1E, 0x1E,
+};
+
+static const unsigned char SEQ_ETC_CONTROL_B8h[] = {
+ 0xB8,
+ 0x00, 0x00, 0x11, 0x22, 0x33, 0x44, 0x44, 0x44,
+ 0x55, 0x55, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
+};
+
+static const unsigned char SEQ_ETC_CONTROL_B9h[] = {
+ 0xB9,
+ 0x2C, 0x12, 0x0C, 0x0A, 0x10, 0x0E, 0x17, 0x13,
+ 0x1F, 0x1A, 0x2A, 0x24, 0x1F, 0x1B, 0x1A, 0x17,
+ 0x2B, 0x26, 0x22, 0x20, 0x3A, 0x34, 0x30, 0x2C,
+ 0x29, 0x26, 0x25, 0x23, 0x21, 0x20, 0x1E, 0x1E,
+};
+
+static const unsigned char SEQ_ETC_CONTROL_BAh[] = {
+ 0xBA,
+ 0x00, 0x00, 0x11, 0x22, 0x33, 0x44, 0x44, 0x44,
+ 0x55, 0x55, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
+};
+#endif
+
+const unsigned char SEQ_STANDBY_ON[] = {
+ 0x10,
+ 0x00, 0x00
+};
+
+const unsigned char SEQ_DISPLAY_ON[] = {
+ 0x29,
+ 0x00, 0x00
+};
+
+const unsigned char SEQ_DISPLAY_OFF[] = {
+ 0x28,
+ 0x00, 0x00
+};
+
+const unsigned char SEQ_ELVSS_SET[] = {
+ 0xB2,
+ 0x17, 0x17, 0x17, 0x17,
+};
+
+const unsigned char SEQ_ELVSS_ON[] = {
+ 0xB1, 0x0B,
+ 0x00,
+};
+
+
+static const unsigned char SEQ_ACL_ON[] = {
+ 0xC0, 0x01,
+ 0x00
+};
+
+static const unsigned char SEQ_ACL_OFF[] = {
+ 0xC0, 0x00,
+ 0x00
+};
+
+static const unsigned char SEQ_ELVSS_32[] = {
+ 0xB1,
+ 0x04, 0x9F
+};
+
+static const unsigned char SEQ_ELVSS_34[] = {
+ 0xB1,
+ 0x04, 0x9D
+};
+
+static const unsigned char SEQ_ELVSS_38[] = {
+ 0xB1,
+ 0x04, 0x99
+};
+
+static const unsigned char SEQ_ELVSS_47[] = {
+ 0xB1,
+ 0x04, 0x90
+};
+
+static const unsigned char *ELVSS_TABLE[] = {
+ SEQ_ELVSS_32,
+ SEQ_ELVSS_34,
+ SEQ_ELVSS_38,
+ SEQ_ELVSS_47,
+};
+
+#endif /* __S6E63M0_PARAM_H__ */
diff --git a/drivers/video/samsung/s6e8aa0_gamma_q1.h b/drivers/video/samsung/s6e8aa0_gamma_q1.h
index 075f66e4..b0b5f0d 100644
--- a/drivers/video/samsung/s6e8aa0_gamma_q1.h
+++ b/drivers/video/samsung/s6e8aa0_gamma_q1.h
@@ -29,7 +29,6 @@ static const unsigned char SEQ_PANEL_CONDITION_SET[] = {
0x01, 0x81, 0xC1, 0x00, 0xC8, 0xC1, 0xD3, 0x01
};
-
static const unsigned char SEQ_ETC_SOURCE_CONTROL[] = {
0xF6,
0x00, 0x02, 0x00
@@ -54,6 +53,11 @@ static const unsigned char SEQ_ELVSS_NVM_SETTING[] = {
0xD9, 0x00, 0x00, 0x00
};
+static const unsigned char SEQ_LTPS_DELAY[] = {
+ 0xFE,
+ 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x04, 0x0B, 0x53, 0x3C
+};
static const unsigned char SEQ_ACL_CUTOFF_20[] = {
0xC1,
diff --git a/drivers/video/samsung/s6e8aa0_param.h b/drivers/video/samsung/s6e8aa0_param.h
index 3ac11ad..8db68a6 100644
--- a/drivers/video/samsung/s6e8aa0_param.h
+++ b/drivers/video/samsung/s6e8aa0_param.h
@@ -96,6 +96,12 @@ enum {
GAMMA_80CD,
GAMMA_90CD,
GAMMA_100CD,
+#ifdef CONFIG_AID_DIMMING
+ GAMMA_102CD,
+ GAMMA_104CD,
+ GAMMA_106CD,
+ GAMMA_108CD,
+#endif
GAMMA_110CD,
GAMMA_120CD,
GAMMA_130CD,
diff --git a/drivers/video/samsung/s6e8aa1.c b/drivers/video/samsung/s6e8aa1.c
new file mode 100644
index 0000000..82effe4
--- /dev/null
+++ b/drivers/video/samsung/s6e8aa1.c
@@ -0,0 +1,568 @@
+/* linux/drivers/video/samsung/s6e8aa1.c
+ *
+ * MIPI-DSI based AMS529HA01 AMOLED lcd panel 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/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/mutex.h>
+#include <linux/wait.h>
+#include <linux/ctype.h>
+#include <linux/io.h>
+#include <linux/delay.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/gpio.h>
+#include <linux/workqueue.h>
+#include <linux/backlight.h>
+#include <linux/lcd.h>
+#include <plat/gpio-cfg.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 "s5p-dsim.h"
+#include "s3cfb.h"
+
+#include "s6e8aa1_param.h"
+
+#define POWER_IS_ON(pwr) ((pwr) <= FB_BLANK_NORMAL)
+
+#define MIN_BRIGHTNESS 0
+#define MAX_BRIGHTNESS 255
+#define MAX_GAMMA 300
+#define DEFAULT_BRIGHTNESS 160
+#define DEFAULT_GAMMA_LEVEL 0
+
+#define LDI_ID_REG 0xD1
+#define LDI_ID_LEN 3
+
+#define LDI_MTP_ADDR 0xCB
+#define LDI_MTP_LENGTH 63
+
+struct lcd_info {
+ unsigned int bl;
+ unsigned int auto_brightness;
+ unsigned int acl_enable;
+ unsigned int cur_acl;
+ unsigned int current_bl;
+ unsigned int current_elvss;
+
+ unsigned int ldi_enable;
+ unsigned int power;
+ struct mutex lock;
+ struct mutex bl_lock;
+
+ struct device *dev;
+ struct lcd_device *ld;
+ struct backlight_device *bd;
+ struct lcd_platform_data *lcd_pd;
+ struct early_suspend early_suspend;
+
+ unsigned char id[LDI_ID_LEN];
+
+ unsigned char **gamma_table;
+ unsigned char **elvss_table;
+
+ unsigned int irq;
+ unsigned int connected;
+
+ struct dsim_global *dsim;
+};
+
+static int s6e8ax0_write(struct lcd_info *lcd, const unsigned char *seq, int len)
+{
+ int size;
+ const unsigned char *wbuf;
+
+ if (!lcd->connected)
+ return 0;
+
+ mutex_lock(&lcd->lock);
+
+ size = len;
+ wbuf = seq;
+
+ if (size == 1)
+ lcd->dsim->ops->cmd_write(lcd->dsim, DCS_WR_NO_PARA, wbuf[0], 0);
+ else if (size == 2)
+ lcd->dsim->ops->cmd_write(lcd->dsim, DCS_WR_1_PARA, wbuf[0], wbuf[1]);
+ else
+ lcd->dsim->ops->cmd_write(lcd->dsim, DCS_LONG_WR, (unsigned int)wbuf, size);
+
+ mutex_unlock(&lcd->lock);
+
+ return 0;
+}
+
+static int _s6e8ax0_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_read(lcd->dsim, addr, count, buf);
+
+ mutex_unlock(&lcd->lock);
+
+ return ret;
+}
+
+static int s6e8ax0_read(struct lcd_info *lcd, const u8 addr, u16 count, u8 *buf, u8 retry_cnt)
+{
+ int ret = 0;
+
+read_retry:
+ ret = _s6e8ax0_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;
+}
+
+static int s6e8ax0_ldi_init(struct lcd_info *lcd)
+{
+ int ret = 0;
+
+ s6e8ax0_write(lcd, SEQ_APPLY_MTP_KEY_ENABLE, ARRAY_SIZE(SEQ_APPLY_MTP_KEY_ENABLE));
+ s6e8ax0_write(lcd, SEQ_SLEEP_OUT, ARRAY_SIZE(SEQ_SLEEP_OUT));
+ msleep(22);
+
+ s6e8ax0_write(lcd, SEQ_PANEL_CONDITION_SET, ARRAY_SIZE(SEQ_PANEL_CONDITION_SET));
+ s6e8ax0_write(lcd, SEQ_DISPLAY_CONDITION_SET, ARRAY_SIZE(SEQ_DISPLAY_CONDITION_SET));
+ s6e8ax0_write(lcd, SEQ_GAMMA_CONDITION_SET, ARRAY_SIZE(SEQ_GAMMA_CONDITION_SET));
+ s6e8ax0_write(lcd, SEQ_GAMMA_UPDATE, ARRAY_SIZE(SEQ_GAMMA_UPDATE));
+
+ s6e8ax0_write(lcd, SEQ_ETC_SOURCE_CONTROL, ARRAY_SIZE(SEQ_ETC_SOURCE_CONTROL));
+ s6e8ax0_write(lcd, SEQ_ETC_PENTILE_CONTROL, ARRAY_SIZE(SEQ_ETC_PENTILE_CONTROL));
+ s6e8ax0_write(lcd, SEQ_ELVSS_CONTROL, ARRAY_SIZE(SEQ_ELVSS_CONTROL));
+ s6e8ax0_write(lcd, SEQ_ETC_NVM_SETTING, ARRAY_SIZE(SEQ_ETC_NVM_SETTING));
+
+ return ret;
+}
+
+static int s6e8ax0_ldi_enable(struct lcd_info *lcd)
+{
+ int ret = 0;
+
+ s6e8ax0_write(lcd, SEQ_DISPLAY_ON, ARRAY_SIZE(SEQ_DISPLAY_ON));
+
+ return ret;
+}
+
+static int s6e8ax0_ldi_disable(struct lcd_info *lcd)
+{
+ int ret = 0;
+
+ s6e8ax0_write(lcd, SEQ_DISPLAY_OFF, ARRAY_SIZE(SEQ_DISPLAY_OFF));
+ s6e8ax0_write(lcd, SEQ_STANDBY_ON, ARRAY_SIZE(SEQ_STANDBY_ON));
+
+ return ret;
+}
+
+static int s6e8ax0_power_on(struct lcd_info *lcd)
+{
+ int ret = 0;
+ struct lcd_platform_data *pd = NULL;
+ pd = lcd->lcd_pd;
+
+ /* dev_info(&lcd->ld->dev, "%s\n", __func__); */
+
+ ret = s6e8ax0_ldi_init(lcd);
+ if (ret) {
+ dev_err(&lcd->ld->dev, "failed to initialize ldi.\n");
+ goto err;
+ }
+
+ msleep(120);
+
+ ret = s6e8ax0_ldi_enable(lcd);
+ if (ret) {
+ dev_err(&lcd->ld->dev, "failed to enable ldi.\n");
+ goto err;
+ }
+
+ lcd->ldi_enable = 1;
+
+ /* update_brightness(lcd, 1); */
+err:
+ return ret;
+}
+
+static int s6e8ax0_power_off(struct lcd_info *lcd)
+{
+ int ret = 0;
+
+ dev_info(&lcd->ld->dev, "%s\n", __func__);
+
+ lcd->ldi_enable = 0;
+
+ ret = s6e8ax0_ldi_disable(lcd);
+
+ msleep(135);
+
+ return ret;
+}
+
+static int s6e8ax0_power(struct lcd_info *lcd, int power)
+{
+ int ret = 0;
+
+ if (POWER_IS_ON(power) && !POWER_IS_ON(lcd->power))
+ ret = s6e8ax0_power_on(lcd);
+ else if (!POWER_IS_ON(power) && POWER_IS_ON(lcd->power))
+ ret = s6e8ax0_power_off(lcd);
+
+ if (!ret)
+ lcd->power = power;
+
+ return ret;
+}
+
+static int s6e8ax0_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 s6e8ax0_power(lcd, power);
+}
+
+static int s6e8ax0_get_power(struct lcd_device *ld)
+{
+ struct lcd_info *lcd = lcd_get_data(ld);
+
+ return lcd->power;
+}
+
+static int s6e8ax0_set_brightness(struct backlight_device *bd)
+{
+ int ret = 0;
+ int brightness = bd->props.brightness;
+ struct lcd_info *lcd = bl_get_data(bd);
+
+ /* dev_info(&lcd->ld->dev, "%s: brightness=%d\n", __func__, 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, MAX_BRIGHTNESS, brightness);
+ return -EINVAL;
+ }
+
+ if (lcd->ldi_enable) {
+ /* ret = update_brightness(lcd, 0); */
+ if (ret < 0) {
+ dev_err(lcd->dev, "err in %s\n", __func__);
+ return -EINVAL;
+ }
+ }
+
+ return ret;
+}
+
+static int s6e8ax0_check_fb(struct lcd_device *ld, struct fb_info *fb)
+{
+ struct s3cfb_window *win = fb->par;
+ struct lcd_info *lcd = lcd_get_data(ld);
+
+ dev_info(&lcd->ld->dev, "%s, fb%d\n", __func__, win->id);
+
+ return 0;
+}
+
+static struct lcd_ops s6e8ax0_lcd_ops = {
+ .set_power = s6e8ax0_set_power,
+ .get_power = s6e8ax0_get_power,
+ .check_fb = s6e8ax0_check_fb,
+};
+
+static const struct backlight_ops s6e8ax0_backlight_ops = {
+ .update_status = s6e8ax0_set_brightness,
+};
+
+static ssize_t power_reduce_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct lcd_info *lcd = dev_get_drvdata(dev);
+ char temp[3];
+
+ sprintf(temp, "%d\n", lcd->acl_enable);
+ strcpy(buf, temp);
+
+ return strlen(buf);
+}
+
+static ssize_t power_reduce_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t size)
+{
+ struct lcd_info *lcd = 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 (lcd->acl_enable != value) {
+ dev_info(dev, "%s - %d, %d\n", __func__, lcd->acl_enable, value);
+ mutex_lock(&lcd->bl_lock);
+ lcd->acl_enable = value;
+ /* if (lcd->ldi_enable)
+ s6e8ax0_set_acl(lcd); */
+ mutex_unlock(&lcd->bl_lock);
+ }
+ }
+ return size;
+}
+
+static DEVICE_ATTR(power_reduce, 0664, power_reduce_show, power_reduce_store);
+
+static ssize_t lcd_type_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ char temp[15];
+ sprintf(temp, "SMD_AMS480GZ01-0\n");
+ strcat(buf, temp);
+ return strlen(buf);
+}
+
+static DEVICE_ATTR(lcd_type, 0444, lcd_type_show, NULL);
+
+static ssize_t auto_brightness_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct lcd_info *lcd = dev_get_drvdata(dev);
+ char temp[3];
+
+ sprintf(temp, "%d\n", lcd->auto_brightness);
+ strcpy(buf, temp);
+
+ return strlen(buf);
+}
+
+static ssize_t auto_brightness_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t size)
+{
+ struct lcd_info *lcd = 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 (lcd->auto_brightness != value) {
+ dev_info(dev, "%s - %d, %d\n", __func__, lcd->auto_brightness, value);
+ mutex_lock(&lcd->bl_lock);
+ lcd->auto_brightness = value;
+ mutex_unlock(&lcd->bl_lock);
+ /* if (lcd->ldi_enable)
+ update_brightness(lcd, 0); */
+ }
+ }
+ return size;
+}
+
+static DEVICE_ATTR(auto_brightness, 0644, auto_brightness_show, auto_brightness_store);
+
+#ifdef CONFIG_HAS_EARLYSUSPEND
+struct lcd_info *g_lcd;
+
+void s6e8ax0_early_suspend(void)
+{
+ struct lcd_info *lcd = g_lcd;
+
+ set_dsim_lcd_enabled(0);
+
+ dev_info(&lcd->ld->dev, "+%s\n", __func__);
+ s6e8ax0_power(lcd, FB_BLANK_POWERDOWN);
+ dev_info(&lcd->ld->dev, "-%s\n", __func__);
+
+ return ;
+}
+
+void s6e8ax0_late_resume(void)
+{
+ struct lcd_info *lcd = g_lcd;
+
+ dev_info(&lcd->ld->dev, "+%s\n", __func__);
+ s6e8ax0_power(lcd, FB_BLANK_UNBLANK);
+ dev_info(&lcd->ld->dev, "-%s\n", __func__);
+
+ set_dsim_lcd_enabled(1);
+
+ return ;
+}
+#endif
+
+static int s6e8ax0_read_mtp(struct lcd_info *lcd, u8 *mtp_data)
+{
+ int ret, i;
+
+ for (i = 0; i < 3; i++)
+ ret = s6e8ax0_read(lcd, LDI_MTP_ADDR+i, LDI_MTP_LENGTH, mtp_data, 0);
+
+ return ret;
+}
+
+static void s6e8ax0_read_id(struct lcd_info *lcd, u8 *buf)
+{
+ int ret = 0;
+
+ ret = s6e8ax0_read(lcd, LDI_ID_REG, LDI_ID_LEN, buf, 3);
+ if (!ret) {
+ lcd->connected = 0;
+ dev_info(&lcd->ld->dev, "panel is not connected well\n");
+ }
+}
+
+static int s6e8ax0_probe(struct device *dev)
+{
+ int ret = 0;
+ struct lcd_info *lcd;
+ u8 mtp_data[LDI_MTP_LENGTH] = {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, &s6e8ax0_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->bd = backlight_device_register("panel", dev, lcd, &s6e8ax0_backlight_ops, NULL);
+ if (IS_ERR(lcd->bd)) {
+ pr_err("failed to register backlight device\n");
+ ret = PTR_ERR(lcd->bd);
+ goto out_free_backlight;
+ }
+
+ lcd->dev = dev;
+ lcd->dsim = (struct dsim_global *)dev_get_drvdata(dev->parent);
+ lcd->bd->props.max_brightness = MAX_BRIGHTNESS;
+ lcd->bd->props.brightness = DEFAULT_BRIGHTNESS;
+ lcd->bl = DEFAULT_GAMMA_LEVEL;
+ lcd->current_bl = lcd->bl;
+
+ lcd->acl_enable = 0;
+ lcd->cur_acl = 0;
+
+ lcd->power = FB_BLANK_UNBLANK;
+ lcd->ldi_enable = 1;
+ lcd->connected = 1;
+ lcd->auto_brightness = 0;
+
+ ret = device_create_file(&lcd->ld->dev, &dev_attr_power_reduce);
+ if (ret < 0)
+ dev_err(&lcd->ld->dev, "failed to add sysfs entries, %d\n", __LINE__);
+
+ ret = device_create_file(&lcd->ld->dev, &dev_attr_lcd_type);
+ if (ret < 0)
+ dev_err(&lcd->ld->dev, "failed to add sysfs entries, %d\n", __LINE__);
+
+ ret = device_create_file(&lcd->bd->dev, &dev_attr_auto_brightness);
+ if (ret < 0)
+ dev_err(&lcd->ld->dev, "failed to add sysfs entries, %d\n", __LINE__);
+
+ dev_set_drvdata(dev, lcd);
+
+ mutex_init(&lcd->lock);
+ mutex_init(&lcd->bl_lock);
+
+ s6e8ax0_read_id(lcd, lcd->id);
+
+ dev_info(&lcd->ld->dev, "ID: %x, %x, %x\n", lcd->id[0], lcd->id[1], lcd->id[2]);
+
+ dev_info(&lcd->ld->dev, "lcd panel driver has been probed.\n");
+
+ return 0;
+
+out_free_backlight:
+ lcd_device_unregister(lcd->ld);
+ kfree(lcd);
+ return ret;
+
+out_free_lcd:
+ kfree(lcd);
+ return ret;
+
+err_alloc:
+ return ret;
+}
+
+static int __devexit s6e8ax0_remove(struct device *dev)
+{
+ struct lcd_info *lcd = dev_get_drvdata(dev);
+
+ s6e8ax0_power(lcd, FB_BLANK_POWERDOWN);
+ lcd_device_unregister(lcd->ld);
+ backlight_device_unregister(lcd->bd);
+ kfree(lcd);
+
+ return 0;
+}
+
+/* Power down all displays on reboot, poweroff or halt. */
+static void s6e8ax0_shutdown(struct device *dev)
+{
+ struct lcd_info *lcd = dev_get_drvdata(dev);
+
+ dev_info(&lcd->ld->dev, "%s\n", __func__);
+
+ s6e8ax0_power(lcd, FB_BLANK_POWERDOWN);
+}
+
+static struct mipi_lcd_driver s6e8ax0_mipi_driver = {
+ .name = "s6e8aa0",
+ .probe = s6e8ax0_probe,
+ .remove = __devexit_p(s6e8ax0_remove),
+ .shutdown = s6e8ax0_shutdown,
+};
+
+static int s6e8ax0_init(void)
+{
+ return s5p_dsim_register_lcd_driver(&s6e8ax0_mipi_driver);
+}
+
+static void s6e8ax0_exit(void)
+{
+ return;
+}
+
+module_init(s6e8ax0_init);
+module_exit(s6e8ax0_exit);
+
+MODULE_DESCRIPTION("MIPI-DSI S6E8AA0:AMS529HA01 (800x1280) Panel Driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/video/samsung/s6e8aa1_param.h b/drivers/video/samsung/s6e8aa1_param.h
new file mode 100644
index 0000000..3232b88
--- /dev/null
+++ b/drivers/video/samsung/s6e8aa1_param.h
@@ -0,0 +1,74 @@
+#ifndef __S6E8AA1_PARAM_H__
+#define __S6E8AA1_PARAM_H__
+
+static const unsigned char SEQ_APPLY_MTP_KEY_ENABLE[] = {
+ 0xF1,
+ 0x5A, 0x5A
+};
+
+static const unsigned char SEQ_SLEEP_OUT[] = {
+ 0x11,
+ 0x00, 0x00
+};
+
+static const unsigned char SEQ_PANEL_CONDITION_SET[] = {
+ 0xF8,
+ 0x3D, 0x35, 0x00, 0x00, 0x00, 0x94, 0x00, 0x3C, 0x7D, 0x08,
+ 0x27, 0x08, 0x7D, 0x00, 0x00, 0x00, 0x00, 0x04, 0x08, 0x7D,
+ 0x00, 0x00, 0x00, 0x02, 0x08, 0x08, 0x23, 0x66, 0xC0, 0xC1,
+ 0x01, 0x81, 0xC1, 0x00, 0xC1, 0xF6, 0xF6, 0xC1
+};
+
+static const unsigned char SEQ_DISPLAY_CONDITION_SET[] = {
+ 0xF2,
+ 0x80, 0x03, 0x0D
+};
+
+static const unsigned char SEQ_GAMMA_CONDITION_SET[] = {
+ 0xFA,
+ 0x01, 0x40, 0x32, 0x49, 0xC5, 0xBB, 0xB6, 0xBC, 0xC5, 0xC0,
+ 0xC9, 0xC9, 0xC5, 0xA0, 0x9F, 0x98, 0xB3, 0xB3, 0xAF, 0x00,
+ 0xD0, 0x00, 0xCF, 0x00, 0xE7
+};
+
+static const unsigned char SEQ_GAMMA_UPDATE[] = {
+ 0xF7, 0x03,
+ 0x00
+};
+
+static const unsigned char SEQ_ETC_SOURCE_CONTROL[] = {
+ 0xF6,
+ 0x00, 0x02, 0x00
+};
+
+static const unsigned char SEQ_ETC_PENTILE_CONTROL[] = {
+ 0xB6,
+ 0x0C, 0x02, 0x03, 0x32, 0xFF, 0x44, 0x44, 0xC0, 0x10
+};
+
+static const unsigned char SEQ_ELVSS_CONTROL[] = {
+ 0xB1,
+ 0x08, 0x95, 0x41, 0xC4
+};
+
+static const unsigned char SEQ_ETC_NVM_SETTING[] = {
+ 0xD9,
+ 0x14, 0x40, 0x0C, 0xCB, 0xCE, 0x6E, 0xC4, 0x07, 0x40
+};
+
+static const unsigned char SEQ_DISPLAY_ON[] = {
+ 0x29,
+ 0x00, 0x00
+};
+
+static const unsigned char SEQ_DISPLAY_OFF[] = {
+ 0x28,
+ 0x00, 0x00
+};
+
+static const unsigned char SEQ_STANDBY_ON[] = {
+ 0x01,
+ 0x00, 0x00
+};
+
+#endif /* __S6E8AA1_PARAM_H__ */
diff --git a/drivers/video/samsung/s6evr02_param.h b/drivers/video/samsung/s6evr02_param.h
new file mode 100644
index 0000000..edc7a4e
--- /dev/null
+++ b/drivers/video/samsung/s6evr02_param.h
@@ -0,0 +1,351 @@
+#ifndef __S6EVR02_PARAM_H__
+#define __S6EVR02_PARAM_H__
+
+#define GAMMA_PARAM_SIZE 34
+#define ACL_PARAM_SIZE ARRAY_SIZE(acl_cutoff_33)
+#define ELVSS_PARAM_SIZE ARRAY_SIZE(elvss_control_set_20)
+#define AID_PARAM_SIZE ARRAY_SIZE(SEQ_AOR_CONTROL)
+
+enum {
+ GAMMA_20CD,
+ GAMMA_30CD,
+ GAMMA_40CD,
+ GAMMA_50CD,
+ GAMMA_60CD,
+ GAMMA_70CD,
+ GAMMA_80CD,
+ GAMMA_90CD,
+ GAMMA_100CD,
+ GAMMA_102CD,
+ GAMMA_104CD,
+ GAMMA_106CD,
+ GAMMA_108CD,
+ GAMMA_110CD,
+ GAMMA_120CD,
+ GAMMA_130CD,
+ GAMMA_140CD,
+ GAMMA_150CD,
+ GAMMA_160CD,
+ GAMMA_170CD,
+ GAMMA_180CD,
+ GAMMA_182CD,
+ GAMMA_184CD,
+ GAMMA_186CD,
+ GAMMA_188CD,
+ GAMMA_190CD,
+ GAMMA_200CD,
+ GAMMA_210CD,
+ GAMMA_220CD,
+ GAMMA_230CD,
+ GAMMA_240CD,
+ GAMMA_250CD,
+ GAMMA_300CD,
+ GAMMA_MAX
+};
+
+static const unsigned char SEQ_APPLY_LEVEL_2_KEY[] = {
+ 0xF0,
+ 0x5A, 0x5A
+};
+
+static const unsigned char SEQ_APPLY_LEVEL_2_KEY_DISABLE[] = {
+ 0xF0,
+ 0xA5, 0xA5
+};
+
+static const unsigned char SEQ_APPLY_LEVEL_3_KEY[] = {
+ 0xFC,
+ 0x5A, 0x5A
+};
+
+static const unsigned char SEQ_APPLY_LEVEL_3_KEY_DISABLE[] = {
+ 0xFC,
+ 0xA5, 0xA5
+};
+
+static const unsigned char SEQ_SLEEP_OUT[] = {
+ 0x11,
+ 0x00, 0x00
+};
+
+static const unsigned char SEQ_SLEEP_IN[] = {
+ 0x10,
+ 0x00, 0x00
+};
+
+static const unsigned char SEQ_GAMMA_CONDITION_SET[] = {
+ 0xCA,
+ 0x00, 0xFF, 0x01, 0x1C, 0x01, 0x2C, 0xDA, 0xD7, 0xDA, 0xD5,
+ 0xD2, 0xD6, 0xC1, 0xBC, 0xC2, 0xCA, 0xB9, 0xCB, 0xDC, 0xE5,
+ 0xDD, 0xDA, 0xD8, 0xDD, 0xBA, 0xA8, 0xC1, 0x6B, 0x20, 0xD7,
+ 0x02, 0x03, 0x02
+};
+
+static const unsigned char SEQ_GAMMA_CONDITION_SET_UB[] = {
+ 0xCA,
+ 0x01, 0x27, 0x01, 0x3D, 0x01, 0x47, 0xD1, 0xD7, 0xD1, 0xCA,
+ 0xCE, 0xCC, 0xC4, 0xB3, 0xB1, 0xA1, 0xB9, 0xB8, 0xA2, 0xCE,
+ 0xBA, 0xC8, 0xC9, 0xAD, 0x9B, 0x85, 0x53, 0x6A, 0x7E, 0xE3,
+ 0x09, 0x09, 0x0B
+};
+
+static const unsigned char SEQ_GAMMA_UPDATE[] = {
+ 0xF7,
+ 0x03, 0x00
+};
+
+static const unsigned char SEQ_BRIGHTNESS_CONTROL_ON[] = {
+ 0x53,
+ 0x20, 0x00
+};
+
+static const unsigned char SEQ_AOR_CONTROL[] = {
+ 0x51,
+ 0xFF, 0x00
+};
+
+static const unsigned char SEQ_ELVSS_CONDITION_SET_UB[] = {
+ 0xB6,
+ 0x08, 0x07
+};
+
+static const unsigned char SEQ_AVC2_SET[] = {
+ 0xF4,
+ 0x6B, 0x18, 0x95, 0x02, 0x11, 0x8C, 0x77, 0x01, 0x01
+};
+
+static const unsigned char SEQ_ELVSS_CONDITION_SET[] = {
+ 0xB6,
+ 0x08, 0x07
+};
+
+static const unsigned char SEQ_DISPLAY_ON[] = {
+ 0x29,
+ 0x00, 0x00
+};
+
+static const unsigned char SEQ_DISPLAY_OFF[] = {
+ 0x28,
+ 0x00, 0x00
+};
+
+
+enum {
+ ELVSS_STATUS_20,
+ ELVSS_STATUS_30,
+ ELVSS_STATUS_40,
+ ELVSS_STATUS_50,
+ ELVSS_STATUS_60,
+ ELVSS_STATUS_70,
+ ELVSS_STATUS_80,
+ ELVSS_STATUS_90,
+ ELVSS_STATUS_100,
+ ELVSS_STATUS_110,
+ ELVSS_STATUS_120,
+ ELVSS_STATUS_130,
+ ELVSS_STATUS_140,
+ ELVSS_STATUS_150,
+ ELVSS_STATUS_160,
+ ELVSS_STATUS_170,
+ ELVSS_STATUS_180,
+ ELVSS_STATUS_190,
+ ELVSS_STATUS_200,
+ ELVSS_STATUS_210,
+ ELVSS_STATUS_220,
+ ELVSS_STATUS_230,
+ ELVSS_STATUS_240,
+ ELVSS_STATUS_250,
+ ELVSS_STATUS_300,
+ ELVSS_STATUS_MAX
+};
+
+static const unsigned char elvss_control_set_20[] = {
+ 0xB6, 0x08,
+ 0x20
+};
+
+static const unsigned char elvss_control_set_30[] = {
+ 0xB6, 0x08,
+ 0x20
+};
+
+static const unsigned char elvss_control_set_40[] = {
+ 0xB6, 0x08,
+ 0x20
+};
+
+static const unsigned char elvss_control_set_50[] = {
+ 0xB6, 0x08,
+ 0x1F
+};
+
+static const unsigned char elvss_control_set_60[] = {
+ 0xB6, 0x08,
+ 0x1F
+};
+
+static const unsigned char elvss_control_set_70[] = {
+ 0xB6, 0x08,
+ 0x1F
+};
+
+static const unsigned char elvss_control_set_80[] = {
+ 0xB6, 0x08,
+ 0x1E
+};
+
+static const unsigned char elvss_control_set_90[] = {
+ 0xB6, 0x08,
+ 0x1E
+};
+
+static const unsigned char elvss_control_set_100[] = {
+ 0xB6, 0x08,
+ 0x1C
+};
+
+static const unsigned char elvss_control_set_110[] = {
+ 0xB6, 0x08,
+ 0x1B
+};
+
+static const unsigned char elvss_control_set_120[] = {
+ 0xB6, 0x08,
+ 0x19
+};
+
+static const unsigned char elvss_control_set_130[] = {
+ 0xB6, 0x08,
+ 0x17
+};
+
+static const unsigned char elvss_control_set_140[] = {
+ 0xB6, 0x08,
+ 0x16
+};
+
+static const unsigned char elvss_control_set_150[] = {
+ 0xB6, 0x08,
+ 0x14
+};
+
+static const unsigned char elvss_control_set_160[] = {
+ 0xB6, 0x08,
+ 0x12
+};
+
+static const unsigned char elvss_control_set_170[] = {
+ 0xB6, 0x08,
+ 0x10
+};
+
+static const unsigned char elvss_control_set_180[] = {
+ 0xB6, 0x08,
+ 0x0F
+};
+
+static const unsigned char elvss_control_set_190[] = {
+ 0xB6, 0x08,
+ 0x15
+};
+
+static const unsigned char elvss_control_set_200[] = {
+ 0xB6, 0x08,
+ 0x14
+};
+
+static const unsigned char elvss_control_set_210[] = {
+ 0xB6, 0x08,
+ 0x13
+};
+
+static const unsigned char elvss_control_set_220[] = {
+ 0xB6, 0x08,
+ 0x12
+};
+
+static const unsigned char elvss_control_set_230[] = {
+ 0xB6, 0x08,
+ 0x11
+};
+
+static const unsigned char elvss_control_set_240[] = {
+ 0xB6, 0x08,
+ 0x10
+};
+
+static const unsigned char elvss_control_set_250[] = {
+ 0xB6, 0x08,
+ 0x10
+};
+
+static const unsigned char elvss_control_set_300[] = {
+ 0xB6, 0x08,
+ 0x0B
+};
+
+
+static const unsigned char *ELVSS_CONTROL_TABLE[ELVSS_STATUS_MAX] = {
+ elvss_control_set_20,
+ elvss_control_set_30,
+ elvss_control_set_40,
+ elvss_control_set_50,
+ elvss_control_set_60,
+ elvss_control_set_70,
+ elvss_control_set_80,
+ elvss_control_set_90,
+ elvss_control_set_100,
+ elvss_control_set_110,
+ elvss_control_set_120,
+ elvss_control_set_130,
+ elvss_control_set_140,
+ elvss_control_set_150,
+ elvss_control_set_160,
+ elvss_control_set_170,
+ elvss_control_set_180,
+ elvss_control_set_190,
+ elvss_control_set_200,
+ elvss_control_set_210,
+ elvss_control_set_220,
+ elvss_control_set_230,
+ elvss_control_set_240,
+ elvss_control_set_250,
+ elvss_control_set_300
+};
+
+
+enum {
+ ACL_STATUS_0P = 0,
+ ACL_STATUS_33P,
+ ACL_STATUS_40P,
+ ACL_STATUS_50P,
+ ACL_STATUS_MAX
+};
+
+static const unsigned char SEQ_ACL_OFF[] = {
+ 0x55, 0x00,
+ 0x00
+};
+
+static const unsigned char acl_cutoff_33[] = {
+ 0x55, 0x01,
+ 0x00
+};
+
+static const unsigned char acl_cutoff_40[] = {
+ 0x55, 0x02,
+ 0x00
+};
+
+static const unsigned char acl_cutoff_50[] = {
+ 0x55, 0x03,
+ 0x00
+};
+
+static const unsigned char *ACL_CUTOFF_TABLE[ACL_STATUS_MAX] = {
+ SEQ_ACL_OFF,
+ acl_cutoff_33,
+ acl_cutoff_40,
+ acl_cutoff_50,
+};
+#endif /* __S6EVR02_PARAM_H__ */
diff --git a/drivers/video/samsung/s6evr02_volt_tbl.h b/drivers/video/samsung/s6evr02_volt_tbl.h
new file mode 100644
index 0000000..0706964
--- /dev/null
+++ b/drivers/video/samsung/s6evr02_volt_tbl.h
@@ -0,0 +1,665 @@
+#ifndef __REF_VOLT_TABLE_H__
+#define __REF_VOLT_TABLE_H__
+
+u32 volt_table_vt[16] = {
+ 399769600, 394199040, 388628480, 383057920,
+ 377487360, 371851264, 366280704, 360710144,
+ 355139584, 349569024, 335609856, 330956800,
+ 326303744, 321650688, 316997632, 313327616,
+};
+
+u32 volt_table_v255[505] = {
+ 366300517, 365835669, 365370820, 364905972, 364441124, 363976275, 363511427, 363046579,
+ 362581730, 362116882, 361652033, 361187185, 360722337, 360257488, 359792640, 359327792,
+ 358862943, 358398095, 357933247, 357468398, 357003550, 356538701, 356073853, 355609005,
+ 355144156, 354679308, 354214460, 353749611, 353284763, 352819914, 352355066, 351890218,
+ 351425369, 350960521, 350495673, 350030824, 349565976, 349101127, 348636279, 348171431,
+ 347706582, 347241734, 346776886, 346312037, 345847189, 345382340, 344917492, 344452644,
+ 343987795, 343522947, 343058099, 342593250, 342128402, 341663553, 341198705, 340733857,
+ 340269008, 339804160, 339339312, 338874463, 338409615, 337944767, 337479918, 337015070,
+ 336550221, 336085373, 335620525, 335155676, 334690828, 334225980, 333761131, 333296283,
+ 332831434, 332366586, 331901738, 331436889, 330972041, 330507193, 330042344, 329577496,
+ 329112647, 328647799, 328182951, 327718102, 327253254, 326788406, 326323557, 325858709,
+ 325393860, 324929012, 324464164, 323999315, 323534467, 323069619, 322604770, 322139922,
+ 321675073, 321210225, 320745377, 320280528, 319815680, 319350832, 318885983, 318421135,
+ 317956287, 317491438, 317026590, 316561741, 316096893, 315632045, 315167196, 314702348,
+ 314237500, 313772651, 313307803, 312842954, 312378106, 311913258, 311448409, 310983561,
+ 310518713, 310053864, 309589016, 309124167, 308659319, 308194471, 307729622, 307264774,
+ 306799926, 306335077, 305870229, 305405380, 304940532, 304475684, 304010835, 303545987,
+ 303081139, 302616290, 302151442, 301686593, 301221745, 300756897, 300292048, 299827200,
+ 299362352, 298897503, 298432655, 297967807, 297502958, 297038110, 296573261, 296108413,
+ 295643565, 295178716, 294713868, 294249020, 293784171, 293319323, 292854474, 292389626,
+ 291924778, 291459929, 290995081, 290530233, 290065384, 289600536, 289135687, 288670839,
+ 288205991, 287741142, 287276294, 286811446, 286346597, 285881749, 285416900, 284952052,
+ 284487204, 284022355, 283557507, 283092659, 282627810, 282162962, 281698113, 281233265,
+ 280768417, 280303568, 279838720, 279373872, 278909023, 278444175, 277979327, 277514478,
+ 277049630, 276584781, 276119933, 275655085, 275190236, 274725388, 274260540, 273795691,
+ 273330843, 272865994, 272401146, 271936298, 271471449, 271006601, 270541753, 270076904,
+ 269612056, 269147207, 268682359, 268217511, 267752662, 267287814, 266822966, 266358117,
+ 265893269, 265428420, 264963572, 264498724, 264033875, 263569027, 263104179, 262639330,
+ 262174482, 261709633, 261244785, 260779937, 260315088, 259850240, 259385392, 258920543,
+ 258455695, 257990847, 257525998, 257061150, 256596301, 256131453, 255666605, 255201756,
+ 254736908, 254272060, 253807211, 253342363, 252877514, 252412666, 251947818, 251482969,
+ 251018121, 250553273, 250088424, 249623576, 249158727, 248693879, 248229031, 247764182,
+ 247299334, 246834486, 246369637, 245904789, 245439940, 244975092, 244510244, 244045395,
+ 243580547, 243115699, 242650850, 242186002, 241721153, 241256305, 240791457, 240326608,
+ 239861760, 239396912, 238932063, 238467215, 238002367, 237537518, 237072670, 236607821,
+ 236142973, 235678125, 235213276, 234748428, 234283580, 233818731, 233353883, 232889034,
+ 232424186, 231959338, 231494489, 231029641, 230564793, 230099944, 229635096, 229170247,
+ 228705399, 228240551, 227775702, 227310854, 226846006, 226381157, 225916309, 225451460,
+ 224986612, 224521764, 224056915, 223592067, 223127219, 222662370, 222197522, 221732673,
+ 221267825, 220802977, 220338128, 219873280, 219408432, 218943583, 218478735, 218013887,
+ 217549038, 217084190, 216619341, 216154493, 215689645, 215224796, 214759948, 214295100,
+ 213830251, 213365403, 212900554, 212435706, 211970858, 211506009, 211041161, 210576313,
+ 210111464, 209646616, 209181767, 208716919, 208252071, 207787222, 207322374, 206857526,
+ 206392677, 205927829, 205462980, 204998132, 204533284, 204068435, 203603587, 203138739,
+ 202673890, 202209042, 201744193, 201279345, 200814497, 200349648, 199884800, 199419952,
+ 198955103, 198490255, 198025407, 197560558, 197095710, 196630861, 196166013, 195701165,
+ 195236316, 194771468, 194306620, 193841771, 193376923, 192912074, 192447226, 191982378,
+ 191517529, 191052681, 190587833, 190122984, 189658136, 189193287, 188728439, 188263591,
+ 187798742, 187333894, 186869046, 186404197, 185939349, 185474500, 185009652, 184544804,
+ 184079955, 183615107, 183150259, 182685410, 182220562, 181755713, 181290865, 180826017,
+ 180361168, 179896320, 179431472, 178966623, 178501775, 178036927, 177572078, 177107230,
+ 176642381, 176177533, 175712685, 175247836, 174782988, 174318140, 173853291, 173388443,
+ 172923594, 172458746, 171993898, 171529049, 171064201, 170599353, 170134504, 169669656,
+ 169204807, 168739959, 168275111, 167810262, 167345414, 166880566, 166415717, 165950869,
+ 165486020, 165021172, 164556324, 164091475, 163626627, 163161779, 162696930, 162232082,
+ 161767233, 161302385, 160837537, 160372688, 159907840, 159442992, 158978143, 158513295,
+ 158048447, 157583598, 157118750, 156653901, 156189053, 155724205, 155259356, 154794508,
+ 154329660, 153864811, 153399963, 152935114, 152470266, 152005418, 151540569, 151075721,
+ 150610873, 150146024, 149681176, 149216327, 148751479, 148286631, 147821782, 147356934,
+ 146892086, 146427237, 145962389, 145497540, 145032692, 144567844, 144102995, 143638147,
+ 143173299, 142708450, 142243602, 141778753, 141313905, 140849057, 140384208, 139919360,
+ 139454512, 138989663, 138524815, 138059967, 137595118, 137130270, 136665421, 136200573,
+ 135735725, 135270876, 134806028, 134341180, 133876331, 133411483, 132946634, 132481786,
+ 132016938,
+};
+
+u32 volt_table_cv_64_dv_320[256] = {
+ 13104, 13308, 13513, 13718, 13923, 14127, 14332, 14537,
+ 14742, 14946, 15151, 15356, 15561, 15765, 15970, 16175,
+ 16380, 16585, 16789, 16994, 17199, 17404, 17608, 17813,
+ 18018, 18223, 18427, 18632, 18837, 19042, 19246, 19451,
+ 19656, 19861, 20065, 20270, 20475, 20680, 20884, 21089,
+ 21294, 21499, 21703, 21908, 22113, 22318, 22522, 22727,
+ 22932, 23137, 23341, 23546, 23751, 23956, 24160, 24365,
+ 24570, 24775, 24979, 25184, 25389, 25594, 25798, 26003,
+ 26208, 26413, 26617, 26822, 27027, 27232, 27436, 27641,
+ 27846, 28051, 28255, 28460, 28665, 28870, 29074, 29279,
+ 29484, 29689, 29893, 30098, 30303, 30508, 30712, 30917,
+ 31122, 31327, 31531, 31736, 31941, 32146, 32350, 32555,
+ 32760, 32965, 33170, 33374, 33579, 33784, 33989, 34193,
+ 34398, 34603, 34808, 35012, 35217, 35422, 35627, 35831,
+ 36036, 36241, 36446, 36650, 36855, 37060, 37265, 37469,
+ 37674, 37879, 38084, 38288, 38493, 38698, 38903, 39107,
+ 39312, 39517, 39722, 39926, 40131, 40336, 40541, 40745,
+ 40950, 41155, 41360, 41564, 41769, 41974, 42179, 42383,
+ 42588, 42793, 42998, 43202, 43407, 43612, 43817, 44021,
+ 44226, 44431, 44636, 44840, 45045, 45250, 45455, 45659,
+ 45864, 46069, 46274, 46478, 46683, 46888, 47093, 47297,
+ 47502, 47707, 47912, 48116, 48321, 48526, 48731, 48935,
+ 49140, 49345, 49550, 49755, 49959, 50164, 50369, 50574,
+ 50778, 50983, 51188, 51393, 51597, 51802, 52007, 52212,
+ 52416, 52621, 52826, 53031, 53235, 53440, 53645, 53850,
+ 54054, 54259, 54464, 54669, 54873, 55078, 55283, 55488,
+ 55692, 55897, 56102, 56307, 56511, 56716, 56921, 57126,
+ 57330, 57535, 57740, 57945, 58149, 58354, 58559, 58764,
+ 58968, 59173, 59378, 59583, 59787, 59992, 60197, 60402,
+ 60606, 60811, 61016, 61221, 61425, 61630, 61835, 62040,
+ 62244, 62449, 62654, 62859, 63063, 63268, 63473, 63678,
+ 63882, 64087, 64292, 64497, 64701, 64906, 65111, 65316
+};
+
+const u32 gamma_300_gra_table[256] = {
+ 0, 2, 7, 17, 32, 53, 78, 110,
+ 148, 191, 241, 298, 361, 430, 506, 589,
+ 679, 776, 880, 991, 1109, 1235, 1368, 1508,
+ 1657, 1812, 1975, 2147, 2325, 2512, 2706, 2909,
+ 3119, 3338, 3564, 3799, 4042, 4293, 4553, 4820,
+ 5096, 5381, 5674, 5975, 6285, 6604, 6931, 7267,
+ 7611, 7965, 8327, 8697, 9077, 9465, 9863, 10269,
+ 10684, 11109, 11542, 11984, 12436, 12896, 13366, 13845,
+ 14333, 14830, 15337, 15852, 16378, 16912, 17456, 18009,
+ 18572, 19144, 19726, 20317, 20918, 21528, 22148, 22778,
+ 23417, 24066, 24724, 25392, 26070, 26758, 27456, 28163,
+ 28880, 29607, 30344, 31090, 31847, 32613, 33390, 34176,
+ 34973, 35779, 36596, 37422, 38259, 39106, 39963, 40830,
+ 41707, 42594, 43492, 44399, 45317, 46246, 47184, 48133,
+ 49092, 50062, 51042, 52032, 53032, 54043, 55065, 56097,
+ 57139, 58192, 59255, 60329, 61413, 62508, 63613, 64729,
+ 65856, 66993, 68141, 69299, 70469, 71648, 72839, 74040,
+ 75252, 76475, 77708, 78952, 80207, 81473, 82750, 84037,
+ 85336, 86645, 87965, 89296, 90638, 91990, 93354, 94729,
+ 96114, 97511, 98919, 100337, 101767, 103208, 104659, 106122,
+ 107596, 109081, 110577, 112085, 113603, 115132, 116673, 118225,
+ 119788, 121362, 122948, 124544, 126152, 127772, 129402, 131044,
+ 132697, 134361, 136037, 137724, 139422, 141132, 142853, 144586,
+ 146330, 148085, 149852, 151630, 153419, 155220, 157033, 158857,
+ 160692, 162540, 164398, 166268, 168150, 170043, 171948, 173864,
+ 175792, 177731, 179683, 181645, 183620, 185606, 187603, 189613,
+ 191634, 193667, 195711, 197767, 199835, 201915, 204006, 206109,
+ 208224, 210351, 212489, 214640, 216802, 218976, 221161, 223359,
+ 225569, 227790, 230023, 232268, 234525, 236794, 239075, 241368,
+ 243672, 245989, 248318, 250658, 253011, 255375, 257752, 260141,
+ 262541, 264954, 267379, 269815, 272264, 274725, 277198, 279683,
+ 282180, 284689, 287211, 289744, 292290, 294848, 297418, 300000
+};
+
+const u32 gamma_control_set_21[] = {
+ 0, 9, 38, 89, 163, 260, 381, 526,
+ 697, 892, 1113, 1359, 1632, 1930, 2255, 2607,
+ 2985, 3391, 3823, 4283, 4770, 5284, 5826, 6396,
+ 6994, 7620, 8274, 8957, 9668, 10407, 11175, 11971,
+ 12797, 13651, 14534, 15446, 16388, 17358, 18358, 19387,
+ 20446, 21534, 22652, 23799, 24976, 26183, 27420, 28687,
+ 29983, 31310, 32667, 34054, 35471, 36919, 38397, 39905,
+ 41444, 43014, 44614, 46244, 47906, 49598, 51321, 53074,
+ 54859, 56674, 58521, 60399, 62307, 64247, 66218, 68220,
+ 70253, 72318, 74414, 76542, 78700, 80891, 83113, 85366,
+ 87651, 89968, 92316, 94696, 97108, 99551, 102027, 104534,
+ 107073, 109644, 112248, 114883, 117550, 120249, 122980, 125744,
+ 128540, 131367, 134228, 137120, 140045, 143002, 145991, 149013,
+ 152068, 155155, 158274, 161426, 164610, 167827, 171077, 174359,
+ 177674, 181022, 184403, 187816, 191262, 194741, 198253, 201797,
+ 205375, 208985, 212629, 216305, 220015, 223758, 227533, 231342,
+ 235184, 239059, 242967, 246909, 250883, 254891, 258932, 263007,
+ 267115, 271256, 275431, 279639, 283880, 288155, 292464, 296806,
+ 301181, 305590, 310033, 314509, 319019, 323562, 328139, 332750,
+ 337394, 342073, 346785, 351530, 356310, 361123, 365971, 370852,
+ 375767, 380715, 385698, 390715, 395766, 400851, 405969, 411122,
+ 416309, 421530, 426785, 432074, 437397, 442754, 448146, 453572,
+ 459032, 464526, 470054, 475617, 481214, 486845, 492511, 498211,
+ 503945, 509714, 515517, 521355, 527227, 533133, 539074, 545050,
+ 551060, 557104, 563183, 569297, 575445, 581628, 587845, 594097,
+ 600384, 606705, 613061, 619452, 625877, 632338, 638833, 645362,
+ 651927, 658526, 665161, 671830, 678533, 685272, 692046, 698854,
+ 705698, 712576, 719490, 726438, 733421, 740440, 747493, 754581,
+ 761705, 768863, 776057, 783286, 790550, 797848, 805183, 812552,
+ 819956, 827396, 834871, 842381, 849926, 857506, 865122, 872773,
+ 880460, 888181, 895938, 903731, 911558, 919421, 927320, 935254,
+ 943223, 951228, 959268, 967343, 975454, 983601, 991783, 1000000
+};
+
+const u32 gamma_control_set_213[] = {
+ 0, 8, 33, 78, 144, 231, 341, 473,
+ 628, 807, 1010, 1237, 1489, 1766, 2067, 2395,
+ 2747, 3126, 3531, 3962, 4419, 4903, 5413, 5951,
+ 6516, 7107, 7727, 8373, 9048, 9750, 10480, 11238,
+ 12024, 12839, 13682, 14553, 15453, 16381, 17339, 18325,
+ 19341, 20385, 21459, 22561, 23694, 24855, 26047, 27268,
+ 28518, 29798, 31109, 32449, 33819, 35219, 36650, 38111,
+ 39602, 41123, 42675, 44258, 45871, 47515, 49189, 50894,
+ 52630, 54397, 56196, 58025, 59885, 61776, 63699, 65653,
+ 67638, 69655, 71703, 73782, 75894, 78036, 80211, 82417,
+ 84655, 86925, 89227, 91560, 93926, 96324, 98754, 101216,
+ 103710, 106236, 108795, 111386, 114009, 116665, 119353, 122074,
+ 124827, 127613, 130432, 133283, 136167, 139083, 142033, 145015,
+ 148031, 151079, 154160, 157274, 160422, 163602, 166816, 170063,
+ 173343, 176656, 180002, 183382, 186795, 190242, 193722, 197236,
+ 200783, 204363, 207978, 211626, 215307, 219023, 222772, 226554,
+ 230371, 234221, 238106, 242024, 245976, 249962, 253982, 258037,
+ 262125, 266247, 270404, 274594, 278819, 283079, 287372, 291700,
+ 296062, 300458, 304889, 309354, 313854, 318388, 322957, 327560,
+ 332198, 336870, 341577, 346319, 351096, 355907, 360753, 365633,
+ 370549, 375499, 380484, 385505, 390560, 395650, 400775, 405935,
+ 411130, 416360, 421625, 426925, 432260, 437631, 443037, 448478,
+ 453954, 459466, 465012, 470594, 476212, 481865, 487553, 493277,
+ 499036, 504831, 510661, 516526, 522428, 528364, 534337, 540345,
+ 546388, 552468, 558583, 564733, 570920, 577142, 583400, 589694,
+ 596024, 602389, 608791, 615228, 621702, 628211, 634756, 641337,
+ 647955, 654608, 661297, 668023, 674785, 681582, 688416, 695286,
+ 702193, 709135, 716114, 723129, 730180, 737268, 744392, 751552,
+ 758749, 765982, 773251, 780557, 787900, 795279, 802694, 810146,
+ 817634, 825159, 832721, 840319, 847954, 855625, 863333, 871078,
+ 878860, 886678, 894533, 902425, 910353, 918319, 926321, 934360,
+ 942436, 950548, 958698, 966885, 975108, 983369, 991666, 1000000
+};
+
+const u32 gamma_control_set_215[] = {
+ 0, 7, 30, 72, 132, 214, 316, 440,
+ 586, 755, 947, 1162, 1401, 1664, 1951, 2263,
+ 2599, 2961, 3348, 3761, 4200, 4664, 5155, 5671,
+ 6215, 6785, 7382, 8006, 8657, 9335, 10041, 10774,
+ 11535, 12324, 13141, 13986, 14859, 15761, 16691, 17650,
+ 18637, 19653, 20698, 21772, 22876, 24008, 25170, 26361,
+ 27581, 28832, 30111, 31421, 32761, 34130, 35530, 36959,
+ 38419, 39909, 41430, 42981, 44562, 46175, 47817, 49491,
+ 51195, 52931, 54697, 56494, 58323, 60182, 62073, 63995,
+ 65949, 67934, 69950, 71998, 74078, 76190, 78333, 80508,
+ 82715, 84954, 87225, 89528, 91863, 94231, 96630, 99062,
+ 101526, 104023, 106552, 109114, 111708, 114335, 116994, 119687,
+ 122412, 125170, 127961, 130784, 133641, 136531, 139454, 142410,
+ 145399, 148422, 151477, 154566, 157689, 160845, 164034, 167257,
+ 170513, 173803, 177127, 180485, 183876, 187301, 190759, 194252,
+ 197779, 201339, 204934, 208562, 212225, 215922, 219653, 223418,
+ 227217, 231051, 234919, 238821, 242758, 246729, 250735, 254775,
+ 258850, 262959, 267103, 271282, 275496, 279744, 284027, 288345,
+ 292697, 297085, 301507, 305965, 310457, 314985, 319548, 324145,
+ 328778, 333446, 338150, 342888, 347662, 352471, 357316, 362195,
+ 367111, 372062, 377048, 382070, 387127, 392220, 397348, 402513,
+ 407713, 412948, 418220, 423527, 428870, 434248, 439663, 445114,
+ 450600, 456123, 461681, 467276, 472906, 478573, 484276, 490014,
+ 495790, 501601, 507448, 513332, 519252, 525209, 531201, 537231,
+ 543296, 549398, 555537, 561712, 567923, 574171, 580456, 586777,
+ 593135, 599529, 605961, 612429, 618933, 625475, 632053, 638668,
+ 645320, 652009, 658735, 665497, 672297, 679133, 686007, 692918,
+ 699865, 706850, 713872, 720931, 728027, 735161, 742331, 749539,
+ 756784, 764067, 771387, 778744, 786138, 793570, 801039, 808546,
+ 816090, 823672, 831291, 838947, 846642, 854374, 862143, 869950,
+ 877795, 885677, 893597, 901555, 909551, 917584, 925655, 933764,
+ 941911, 950096, 958318, 966579, 974877, 983214, 991588, 1000000
+};
+
+const u32 gamma_control_set_218[] = {
+ 0 , 6, 26, 63, 117, 190, 282, 395,
+ 528, 683, 859, 1057, 1278, 1522, 1788, 2078,
+ 2392, 2730, 3092, 3479, 3891, 4327, 4789, 5277,
+ 5789, 6328, 6893, 7484, 8102, 8746, 9417, 10114,
+ 10839, 11591, 12370, 13177, 14012, 14874, 15765, 16683,
+ 17630, 18605, 19608, 20640, 21701, 22791, 23909, 25057,
+ 26234, 27440, 28675, 29940, 31235, 32559, 33913, 35297,
+ 36711, 38155, 39630, 41134, 42669, 44235, 45831, 47458,
+ 49116, 50804, 52523, 54274, 56055, 57868, 59712, 61587,
+ 63494, 65432, 67402, 69403, 71436, 73501, 75598, 77727,
+ 79888, 82081, 84306, 86564, 88853, 91175, 93530, 95917,
+ 98337, 100789, 103275, 105792, 108343, 110927, 113544, 116193,
+ 118876, 121592, 124342, 127124, 129940, 132790, 135673, 138589,
+ 141539, 144523, 147540, 150592, 153677, 156795, 159948, 163135,
+ 166356, 169611, 172900, 176224, 179582, 182974, 186400, 189861,
+ 193356, 196886, 200451, 204050, 207684, 211352, 215056, 218794,
+ 222567, 226375, 230218, 234096, 238010, 241958, 245941, 249960,
+ 254014, 258104, 262228, 266389, 270584, 274815, 279082, 283384,
+ 287722, 292096, 296505, 300950, 305431, 309948, 314501, 319090,
+ 323714, 328375, 333072, 337805, 342574, 347380, 352221, 357099,
+ 362013, 366964, 371951, 376974, 382034, 387131, 392264, 397434,
+ 402640, 407883, 413163, 418480, 423833, 429223, 434651, 440115,
+ 445616, 451154, 456729, 462341, 467990, 473677, 479401, 485161,
+ 490960, 496795, 502668, 508578, 514526, 520511, 526533, 532593,
+ 538691, 544826, 550999, 557209, 563457, 569743, 576067, 582428,
+ 588828, 595265, 601740, 608253, 614804, 621393, 628020, 634685,
+ 641388, 648129, 654909, 661726, 668582, 675477, 682409, 689380,
+ 696389, 703437, 710523, 717647, 724810, 732011, 739251, 746530,
+ 753847, 761203, 768598, 776031, 783503, 791014, 798563, 806152,
+ 813779, 821445, 829150, 836894, 844677, 852499, 860360, 868261,
+ 876200, 884178, 892196, 900252, 908348, 916484, 924658, 932872,
+ 941125, 949417, 957749, 966121, 974531, 982982, 991471, 1000000
+};
+
+const u32 gamma_control_set_22[] = {
+ 0, 6, 24, 57, 108, 176, 262, 368,
+ 493, 639, 805, 993, 1202, 1434, 1687, 1964,
+ 2263, 2586, 2933, 3303, 3698, 4117, 4560, 5029,
+ 5522, 6041, 6585, 7156, 7752, 8374, 9022, 9697,
+ 10398, 11127, 11882, 12664, 13474, 14311, 15176, 16068,
+ 16989, 17937, 18913, 19918, 20952, 22013, 23104, 24223,
+ 25372, 26549, 27756, 28992, 30257, 31552, 32876, 34231,
+ 35615, 37029, 38473, 39948, 41452, 42988, 44553, 46149,
+ 47776, 49434, 51123, 52842, 54593, 56375, 58188, 60032,
+ 61908, 63815, 65754, 67725, 69728, 71762, 73828, 75927,
+ 78057, 80220, 82415, 84642, 86902, 89194, 91519, 93876,
+ 96267, 98690, 101146, 103635, 106157, 108712, 111300, 113921,
+ 116576, 119265, 121986, 124741, 127530, 130353, 133209, 136099,
+ 139023, 141981, 144973, 147999, 151059, 154153, 157281, 160444,
+ 163641, 166873, 170139, 173440, 176775, 180145, 183549, 186989,
+ 190463, 193973, 197517, 201096, 204711, 208360, 212045, 215765,
+ 219520, 223311, 227137, 230999, 234896, 238828, 242797, 246801,
+ 250841, 254916, 259028, 263175, 267359, 271578, 275833, 280125,
+ 284453, 288816, 293217, 297653, 302126, 306635, 311181, 315763,
+ 320382, 325037, 329730, 334458, 339224, 344026, 348865, 353741,
+ 358654, 363604, 368591, 373616, 378677, 383775, 388911, 394084,
+ 399294, 404541, 409826, 415149, 420508, 425906, 431341, 436813,
+ 442323, 447871, 453457, 459080, 464742, 470441, 476178, 481953,
+ 487766, 493617, 499506, 505433, 511398, 517402, 523444, 529524,
+ 535642, 541799, 547994, 554228, 560500, 566810, 573159, 579547,
+ 585973, 592439, 598942, 605485, 612066, 618686, 625345, 632043,
+ 638780, 645556, 652371, 659224, 666117, 673050, 680021, 687031,
+ 694081, 701170, 708298, 715466, 722673, 729919, 737205, 744531,
+ 751896, 759300, 766744, 774228, 781751, 789314, 796917, 804560,
+ 812242, 819964, 827726, 835528, 843370, 851252, 859174, 867136,
+ 875138, 883180, 891263, 899385, 907548, 915751, 923994, 932277,
+ 940601, 948965, 957370, 965815, 974301, 982827, 991393, 1000000
+};
+
+const u32 gamma_control_set_221[] = {
+ 0, 5, 23, 55, 103, 169, 252, 355,
+ 476, 618, 780, 962, 1166, 1392, 1639, 1909,
+ 2202, 2517, 2856, 3219, 3605, 4015, 4450, 4909,
+ 5393, 5902, 6437, 6997, 7582, 8194, 8831, 9495,
+ 10185, 10901, 11645, 12415, 13213, 14037, 14890, 15769,
+ 16677, 17612, 18575, 19567, 20587, 21635, 22712, 23817,
+ 24952, 26115, 27307, 28529, 29780, 31060, 32370, 33710,
+ 35079, 36478, 37908, 39367, 40857, 42377, 43928, 45509,
+ 47120, 48763, 50436, 52141, 53876, 55642, 57440, 59269,
+ 61130, 63022, 64946, 66901, 68889, 70908, 72959, 75042,
+ 77157, 79305, 81485, 83697, 85942, 88219, 90530, 92872,
+ 95248, 97656, 100098, 102572, 105080, 107621, 110195, 112802,
+ 115443, 118117, 120825, 123567, 126342, 129151, 131994, 134871,
+ 137782, 140727, 143706, 146719, 149766, 152848, 155964, 159115,
+ 162300, 165520, 168775, 172064, 175388, 178747, 182141, 185569,
+ 189033, 192532, 196066, 199635, 203240, 206880, 210555, 214266,
+ 218012, 221794, 225612, 229465, 233354, 237279, 241240, 245236,
+ 249269, 253338, 257442, 261583, 265760, 269974, 274223, 278509,
+ 282832, 287191, 291586, 296018, 300487, 304992, 309534, 314113,
+ 318729, 323381, 328071, 332797, 337561, 342362, 347199, 352074,
+ 356987, 361936, 366923, 371947, 377009, 382108, 387245, 392419,
+ 397631, 402881, 408168, 413493, 418856, 424257, 429695, 435172,
+ 440686, 446239, 451830, 457459, 463126, 468831, 474575, 480356,
+ 486177, 492035, 497932, 503868, 509842, 515854, 521906, 527996,
+ 534124, 540292, 546498, 552743, 559027, 565349, 571711, 578112,
+ 584552, 591030, 597548, 604106, 610702, 617337, 624012, 630726,
+ 637480, 644273, 651105, 657977, 664888, 671839, 678830, 685860,
+ 692930, 700039, 707189, 714378, 721607, 728876, 736184, 743533,
+ 750922, 758350, 765819, 773328, 780877, 788466, 796095, 803765,
+ 811475, 819225, 827015, 834846, 842717, 850629, 858582, 866574,
+ 874608, 882682, 890796, 898952, 907148, 915384, 923662, 931980,
+ 940339, 948740, 957181, 965662, 974185, 982749, 991354, 1000000
+};
+
+const u32 gamma_control_set_222[] = {
+ 0, 5, 22, 53, 99, 162, 243, 342,
+ 460, 597, 755, 932, 1131, 1351, 1592, 1856,
+ 2142, 2450, 2781, 3136, 3514, 3916, 4342, 4792,
+ 5267, 5767, 6292, 6841, 7417, 8017, 8644, 9297,
+ 9976, 10681, 11413, 12171, 12957, 13769, 14609, 15476,
+ 16371, 17293, 18243, 19222, 20228, 21263, 22326, 23418,
+ 24538, 25688, 26866, 28073, 29310, 30576, 31871, 33197,
+ 34551, 35936, 37351, 38795, 40270, 41775, 43311, 44877,
+ 46473, 48101, 49759, 51448, 53169, 54920, 56703, 58516,
+ 60362, 62239, 64147, 66088, 68060, 70064, 72100, 74168,
+ 76268, 78401, 80566, 82763, 84993, 87256, 89551, 91879,
+ 94240, 96634, 99061, 101521, 104014, 106541, 109100, 111694,
+ 114321, 116981, 119675, 122403, 125165, 127961, 130790, 133654,
+ 136551, 139483, 142450, 145450, 148485, 151555, 154659, 157797,
+ 160970, 164178, 167421, 170699, 174012, 177360, 180742, 184160,
+ 187614, 191102, 194626, 198185, 201780, 205410, 209076, 212778,
+ 216515, 220288, 224097, 227942, 231823, 235740, 239692, 243682,
+ 247707, 251768, 255866, 260001, 264171, 268379, 272623, 276903,
+ 281220, 285574, 289965, 294392, 298856, 303358, 307896, 312471,
+ 317084, 321734, 326421, 331145, 335906, 340705, 345541, 350415,
+ 355327, 360276, 365262, 370286, 375349, 380448, 385586, 390762,
+ 395975, 401227, 406516, 411844, 417210, 422614, 428056, 433537,
+ 439055, 444613, 450208, 455843, 461515, 467227, 472977, 478765,
+ 484593, 490459, 496364, 502307, 508290, 514312, 520372, 526472,
+ 532611, 538789, 545006, 551262, 557558, 563892, 570267, 576680,
+ 583133, 589626, 596158, 602729, 609341, 615992, 622682, 629412,
+ 636183, 642992, 649842, 656732, 663662, 670631, 677641, 684691,
+ 691781, 698911, 706081, 713291, 720542, 727833, 735165, 742537,
+ 749949, 757402, 764895, 772429, 780003, 787618, 795274, 802971,
+ 810708, 818486, 826305, 834165, 842065, 850007, 857989, 866013,
+ 874078, 882183, 890330, 898518, 906748, 915018, 923330, 931683,
+ 940078, 948514, 956991, 965510, 974070, 982672, 991315, 1000000
+};
+
+const u32 gamma_control_set_223[] = {
+ 0, 5, 21, 50, 95, 156, 234, 330,
+ 444, 578, 731, 904, 1097, 1311, 1547, 1804,
+ 2083, 2385, 2709, 3056, 3426, 3820, 4237, 4679,
+ 5144, 5635, 6150, 6689, 7255, 7845, 8461, 9103,
+ 9771, 10465, 11185, 11932, 12705, 13506, 14333, 15188,
+ 16070, 16980, 17917, 18883, 19876, 20897, 21947, 23025,
+ 24132, 25267, 26432, 27625, 28848, 30099, 31381, 32691,
+ 34031, 35402, 36802, 38231, 39692, 41182, 42703, 44254,
+ 45835, 47448, 49091, 50765, 52470, 54207, 55974, 57773,
+ 59603, 61465, 63359, 65284, 67241, 69230, 71251, 73304,
+ 75389, 77507, 79657, 81839, 84054, 86302, 88583, 90896,
+ 93243, 95622, 98034, 100480, 102959, 105471, 108017, 110596,
+ 113209, 115856, 118536, 121251, 123999, 126781, 129597, 132448,
+ 135332, 138251, 141205, 144193, 147215, 150272, 153364, 156490,
+ 159651, 162848, 166079, 169345, 172647, 175983, 179355, 182762,
+ 186205, 189683, 193196, 196746, 200330, 203951, 207607, 211300,
+ 215028, 218792, 222592, 226429, 230301, 234210, 238155, 242137,
+ 246155, 250209, 254300, 258428, 262592, 266793, 271031, 275306,
+ 279618, 283966, 288352, 292775, 297235, 301732, 306267, 310838,
+ 315448, 320094, 324779, 329500, 334260, 339057, 343891, 348764,
+ 353674, 358623, 363609, 368633, 373695, 378796, 383934, 389111,
+ 394326, 399580, 404871, 410202, 415570, 420977, 426423, 431908,
+ 437431, 442992, 448593, 454232, 459911, 465628, 471384, 477180,
+ 483014, 488887, 494800, 500752, 506743, 512774, 518843, 524953,
+ 531102, 537290, 543518, 549785, 556092, 562439, 568826, 575252,
+ 581718, 588224, 594770, 601356, 607982, 614649, 621355, 628101,
+ 634888, 641715, 648582, 655489, 662437, 669425, 676454, 683524,
+ 690633, 697784, 704975, 712207, 719479, 726793, 734147, 741542,
+ 748977, 756454, 763972, 771531, 779131, 786772, 794454, 802177,
+ 809942, 817748, 825595, 833483, 841413, 849385, 857398, 865452,
+ 873548, 881685, 889865, 898085, 906348, 914652, 922998, 931386,
+ 939816, 948288, 956801, 965357, 973955, 982595, 991276, 1000000
+};
+
+const u32 gamma_control_set_224[] = {
+ 0, 5, 20, 48, 91, 150, 226, 318,
+ 429, 559, 707, 876, 1064, 1273, 1503, 1754,
+ 2026, 2321, 2638, 2977, 3340, 3725, 4135, 4567,
+ 5024, 5505, 6011, 6541, 7096, 7676, 8282, 8913,
+ 9570, 10253, 10962, 11697, 12459, 13248, 14063, 14906,
+ 15775, 16672, 17597, 18549, 19530, 20538, 21574, 22639,
+ 23732, 24854, 26005, 27184, 28393, 29630, 30897, 32194,
+ 33520, 34875, 36261, 37676, 39121, 40597, 42103, 43639,
+ 45206, 46804, 48432, 50091, 51781, 53503, 55255, 57039,
+ 58854, 60701, 62580, 64490, 66432, 68406, 70412, 72450,
+ 74520, 76623, 78758, 80926, 83126, 85359, 87625, 89924,
+ 92256, 94621, 97019, 99450, 101915, 104413, 106944, 109510,
+ 112109, 114742, 117408, 120109, 122843, 125612, 128415, 131252,
+ 134124, 137030, 139971, 142946, 145956, 149000, 152080, 155194,
+ 158343, 161528, 164747, 168002, 171292, 174617, 177978, 181375,
+ 184806, 188274, 191777, 195316, 198891, 202502, 206149, 209832,
+ 213551, 217306, 221098, 224925, 228790, 232690, 236628, 240602,
+ 244612, 248659, 252744, 256864, 261022, 265217, 269449, 273718,
+ 278024, 282368, 286748, 291167, 295622, 300115, 304646, 309214,
+ 313820, 318463, 323145, 327864, 332621, 337416, 342249, 347120,
+ 352030, 356977, 361963, 366987, 372050, 377150, 382290, 387468,
+ 392684, 397939, 403233, 408566, 413937, 419347, 424796, 430285,
+ 435812, 441378, 446983, 452628, 458312, 464035, 469797, 475599,
+ 481440, 487321, 493241, 499201, 505201, 511240, 517319, 523438,
+ 529597, 535795, 542034, 548312, 554631, 560989, 567388, 573827,
+ 580307, 586826, 593386, 599987, 606627, 613309, 620030, 626793,
+ 633596, 640439, 647324, 654249, 661215, 668222, 675270, 682358,
+ 689488, 696659, 703871, 711124, 718418, 725753, 733130, 740548,
+ 748007, 755508, 763050, 770634, 778259, 785926, 793635, 801385,
+ 809177, 817010, 824886, 832803, 840762, 848763, 856806, 864891,
+ 873018, 881188, 889399, 897653, 905948, 914286, 922667, 931089,
+ 939555, 948062, 956612, 965205, 973840, 982517, 991238, 1000000
+};
+
+const u32 gamma_control_set_225[] = {
+ 0, 4, 19, 46, 88, 144, 217, 307,
+ 415, 540, 685, 849, 1032, 1235, 1460, 1705,
+ 1971, 2259, 2569, 2901, 3256, 3634, 4034, 4459,
+ 4907, 5379, 5875, 6396, 6941, 7511, 8107, 8727,
+ 9373, 10045, 10743, 11467, 12218, 12994, 13798, 14628,
+ 15486, 16370, 17283, 18222, 19190, 20185, 21208, 22259,
+ 23339, 24448, 25584, 26750, 27945, 29168, 30421, 31704,
+ 33015, 34357, 35728, 37129, 38559, 40020, 41512, 43033,
+ 44586, 46168, 47782, 49426, 51102, 52808, 54546, 56314,
+ 58115, 59947, 61810, 63705, 65632, 67591, 69583, 71606,
+ 73661, 75749, 77870, 80023, 82208, 84427, 86678, 88962,
+ 91279, 93630, 96014, 98431, 100881, 103365, 105883, 108434,
+ 111019, 113638, 116291, 118978, 121699, 124454, 127244, 130068,
+ 132926, 135819, 138747, 141710, 144707, 147739, 150806, 153909,
+ 157046, 160218, 163426, 166669, 169948, 173262, 176612, 179997,
+ 183419, 186876, 190369, 193898, 197462, 201063, 204701, 208374,
+ 212084, 215830, 219613, 223432, 227288, 231181, 235110, 239076,
+ 243079, 247119, 251196, 255311, 259462, 263650, 267876, 272139,
+ 276440, 280778, 285154, 289567, 294018, 298507, 303034, 307598,
+ 312200, 316841, 321519, 326236, 330991, 335784, 340615, 345485,
+ 350393, 355339, 360325, 365348, 370411, 375512, 380652, 385831,
+ 391049, 396306, 401601, 406936, 412310, 417723, 423176, 428668,
+ 434199, 439769, 445379, 451029, 456718, 462447, 468215, 474024,
+ 479872, 485760, 491687, 497655, 503663, 509711, 515799, 521927,
+ 528096, 534305, 540554, 546843, 553173, 559544, 565955, 572406,
+ 578899, 585432, 592005, 598620, 605275, 611971, 618709, 625487,
+ 632306, 639167, 646068, 653011, 659995, 667020, 674087, 681195,
+ 688345, 695536, 702768, 710042, 717358, 724715, 732115, 739556,
+ 747038, 754563, 762130, 769738, 777389, 785081, 792816, 800593,
+ 808412, 816273, 824177, 832123, 840111, 848142, 856215, 864331,
+ 872489, 880690, 888934, 897220, 905549, 913921, 922335, 930793,
+ 939293, 947836, 956423, 965052, 973724, 982440, 991199, 1000000
+};
+
+const u32 *GAMMA_CONTROL_TABLE[G_MAX] = {
+ gamma_control_set_21,
+ gamma_control_set_213,
+ gamma_control_set_215,
+ gamma_control_set_218,
+ gamma_control_set_22,
+ gamma_control_set_221,
+ gamma_control_set_222,
+ gamma_control_set_223,
+ gamma_control_set_224,
+ gamma_control_set_225
+};
+
+const struct str_flookup_table flookup_table[302] = {
+ { 0, 0}, { 1, 20},
+ { 20, 7}, { 27, 5},
+ { 32, 4}, { 36, 4},
+ { 40, 4}, { 44, 3},
+ { 47, 3}, { 50, 2},
+ { 52, 3}, { 55, 2},
+ { 57, 3}, { 60, 2},
+ { 62, 2}, { 64, 2},
+ { 66, 2}, { 68, 2},
+ { 70, 1}, { 71, 2},
+ { 73, 2}, { 75, 2},
+ { 77, 1}, { 78, 2},
+ { 80, 1}, { 81, 2},
+ { 83, 1}, { 84, 2},
+ { 86, 1}, { 87, 2},
+ { 89, 1}, { 90, 1},
+ { 91, 2}, { 93, 1},
+ { 94, 1}, { 95, 2},
+ { 97, 1}, { 98, 1},
+ { 99, 1}, {100, 1},
+ {101, 2}, {103, 1},
+ {104, 1}, {105, 1},
+ {106, 1}, {107, 1},
+ {108, 1}, {109, 1},
+ {110, 1}, {111, 1},
+ {112, 1}, {113, 1},
+ {114, 1}, {115, 1},
+ {116, 1}, {117, 1},
+ {118, 1}, {119, 1},
+ {120, 1}, {121, 1},
+ {122, 1}, {123, 1},
+ {124, 1}, {125, 1},
+ {126, 1}, {127, 1},
+ {128, 1}, {129, 1},
+ { 0, 0}, {130, 1},
+ {131, 1}, {132, 1},
+ {133, 1}, {134, 1},
+ { 0, 0}, {135, 1},
+ {136, 1}, {137, 1},
+ {138, 1}, {139, 1},
+ { 0, 0}, {140, 1},
+ {141, 1}, {142, 1},
+ { 0, 0}, {143, 1},
+ {144, 1}, {145, 1},
+ {146, 1}, { 0, 0},
+ {147, 1}, {148, 1},
+ {149, 1}, { 0, 0},
+ {150, 1}, {151, 1},
+ { 0, 0}, {152, 1},
+ {153, 1}, {154, 1},
+ { 0, 0}, {155, 1},
+ {156, 1}, { 0, 0},
+ {157, 1}, {158, 1},
+ { 0, 0}, {159, 1},
+ {160, 1}, { 0, 0},
+ {161, 1}, {162, 1},
+ { 0, 0}, {163, 1},
+ {164, 1}, { 0, 0},
+ {165, 1}, {166, 1},
+ { 0, 0}, {167, 1},
+ {168, 1}, { 0, 0},
+ {169, 1}, {170, 1},
+ { 0, 0}, {171, 1},
+ { 0, 0}, {172, 1},
+ {173, 1}, { 0, 0},
+ {174, 1}, { 0, 0},
+ {175, 1}, {176, 1},
+ { 0, 0}, {177, 1},
+ { 0, 0}, {178, 1},
+ {179, 1}, { 0, 0},
+ {180, 1}, { 0, 0},
+ {181, 1}, {182, 1},
+ { 0, 0}, {183, 1},
+ { 0, 0}, {184, 1},
+ { 0, 0}, {185, 1},
+ {186, 1}, { 0, 0},
+ {187, 1}, { 0, 0},
+ {188, 1}, { 0, 0},
+ {189, 1}, { 0, 0},
+ {190, 1}, {191, 1},
+ { 0, 0}, {192, 1},
+ { 0, 0}, {193, 1},
+ { 0, 0}, {194, 1},
+ { 0, 0}, {195, 1},
+ { 0, 0}, {196, 1},
+ { 0, 0}, {197, 1},
+ {198, 1}, { 0, 0},
+ {199, 1}, { 0, 0},
+ {200, 1}, { 0, 0},
+ {201, 1}, { 0, 0},
+ {202, 1}, { 0, 0},
+ {203, 1}, { 0, 0},
+ {204, 1}, { 0, 0},
+ {205, 1}, { 0, 0},
+ {206, 1}, { 0, 0},
+ {207, 1}, { 0, 0},
+ {208, 1}, { 0, 0},
+ {209, 1}, { 0, 0},
+ {210, 1}, { 0, 0},
+ {211, 1}, { 0, 0},
+ {212, 1}, { 0, 0},
+ {213, 1}, { 0, 0},
+ { 0, 0}, {214, 1},
+ { 0, 0}, {215, 1},
+ { 0, 0}, {216, 1},
+ { 0, 0}, {217, 1},
+ { 0, 0}, {218, 1},
+ { 0, 0}, {219, 1},
+ { 0, 0}, {220, 1},
+ { 0, 0}, {221, 1},
+ { 0, 0}, { 0, 0},
+ {222, 1}, { 0, 0},
+ {223, 1}, { 0, 0},
+ {224, 1}, { 0, 0},
+ {225, 1}, { 0, 0},
+ { 0, 0}, {226, 1},
+ { 0, 0}, {227, 1},
+ { 0, 0}, {228, 1},
+ { 0, 0}, {229, 1},
+ { 0, 0}, { 0, 0},
+ {230, 1}, { 0, 0},
+ {231, 1}, { 0, 0},
+ {232, 1}, { 0, 0},
+ {233, 1}, { 0, 0},
+ { 0, 0}, {234, 1},
+ { 0, 0}, {235, 1},
+ { 0, 0}, { 0, 0},
+ {236, 1}, { 0, 0},
+ {237, 1}, { 0, 0},
+ {238, 1}, { 0, 0},
+ { 0, 0}, {239, 1},
+ { 0, 0}, {240, 1},
+ { 0, 0}, {241, 1},
+ { 0, 0}, { 0, 0},
+ {242, 1}, { 0, 0},
+ {243, 1}, { 0, 0},
+ { 0, 0}, {244, 1},
+ { 0, 0}, {245, 1},
+ { 0, 0}, { 0, 0},
+ {246, 1}, { 0, 0},
+ {247, 1}, { 0, 0},
+ { 0, 0}, {248, 1},
+ { 0, 0}, {249, 1},
+ { 0, 0}, { 0, 0},
+ {250, 1}, { 0, 0},
+ {251, 1}, { 0, 0},
+ { 0, 0}, {252, 1},
+ { 0, 0}, {253, 1},
+ { 0, 0}, { 0, 0},
+ {254, 1}, { 0, 0},
+ { 0, 0}, {255, 1},
+};
+
+#endif
diff --git a/drivers/video/samsung/smart_dimming_ea8061.c b/drivers/video/samsung/smart_dimming_ea8061.c
new file mode 100644
index 0000000..7a9175c
--- /dev/null
+++ b/drivers/video/samsung/smart_dimming_ea8061.c
@@ -0,0 +1,918 @@
+/* linux/drivers/video/samsung/smartdimming.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+
+ * Samsung Smart Dimming for OCTA
+ *
+ * Minwoo Kim, <minwoo7945.kim@samsung.com>
+ *
+*/
+
+#include "smart_dimming_ea8061.h"
+#include "ea8061_volt_tbl.h"
+
+#define VALUE_DIM_1000 1000
+#define VT_255_div_1000 605000
+#define VREG_OUT_1000 6100
+#define VREG_OUT_1000_1024 6246400
+#define VT_255_calc_param (VT_255_div_1000 / VREG_OUT_1000)
+
+static const u8 range_table_count[IV_TABLE_MAX] = {
+ 3, 8, 12, 12, 16, 36, 64, 52, 52, 1
+};
+
+static const u32 table_radio[IV_TABLE_MAX] = {
+ 16384, 4138, 2763, 2763, 2080, 918, 516, 636, 636, 0
+};
+
+static const u32 dv_value[IV_MAX] = {
+ 0, 3, 11, 23, 35, 51, 87, 151, 203, 255
+};
+
+static const char color_name[3] = {'R', 'G', 'B'};
+
+static const u8 *offset_table[IV_TABLE_MAX] = {
+ NULL, /*V3*/
+ NULL, /*V11*/
+ NULL, /*V23*/
+ NULL, /*V23*/
+ NULL, /*V35*/
+ NULL, /*V51*/
+ NULL, /*V87*/
+ NULL, /*V151*/
+ NULL, /*V203*/
+ NULL /*V255*/
+};
+
+static const unsigned char gamma_300cd_00[] = {
+ 0x00, 0xE8, 0x00, 0xF7, 0x01, 0x03,
+ 0xDB, 0xDB, 0xDC, 0xD9, 0xD8, 0xDA, 0xCB, 0xC8, 0xCB,
+ 0xD4, 0xD3, 0xD7, 0xE6, 0xE6, 0xEA, 0xE2, 0xE4, 0xE5,
+ 0xCE, 0xC3, 0xCF, 0xB9, 0x9D, 0xDE, 0x01, 0x01, 0x00
+};
+
+static const unsigned char gamma_300cd_02[] = {
+ 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x01, 0x03, 0x02
+};
+
+static const unsigned char *gamma_300cd_list[GAMMA_300CD_MAX] = {
+ gamma_300cd_00,
+ gamma_300cd_00,
+ gamma_300cd_02,
+ gamma_300cd_02,
+ gamma_300cd_02,
+ gamma_300cd_02,
+ gamma_300cd_02,
+ gamma_300cd_02,
+ gamma_300cd_02,
+};
+
+static const unsigned char gamma_id_list[GAMMA_300CD_MAX] = {
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x25, 0x26,
+};
+
+static s16 s9_to_s16(s16 v)
+{
+ return (s16)(v << 7) >> 7;
+}
+
+static u32 calc_vt_volt(s16 gamma, int rgb_index, u32 adjust_volt[CI_MAX][AD_IVMAX])
+{
+ u32 ret = 0;
+
+ ret = volt_table_vt[gamma] >> 16;
+
+ return ret;
+}
+
+static u32 calc_v3_volt(s16 gamma, int rgb_index, u32 adjust_volt[CI_MAX][AD_IVMAX])
+{
+ /* for CV : 64, DV :320 */
+ int ret = 0;
+ u32 v0 = VREG_OUT_1000, v11;
+ u32 ratio = 0;
+
+ /*vt = adjust_volt[rgb_index][AD_IVT];*/
+ v11 = adjust_volt[rgb_index][AD_IV11];
+ ratio = volt_table_cv_64_dv_320[gamma];
+
+ ret = (v0 << 16) - ((v0-v11)*ratio);
+ ret = ret >> 16;
+
+ return ret;
+}
+
+static u32 calc_v11_volt(s16 gamma, int rgb_index, u32 adjust_volt[CI_MAX][AD_IVMAX])
+{
+ /* for CV : 64, DV :320*/
+ int ret = 0;
+ u32 vt, v23;
+ u32 ratio = 0;
+
+ vt = adjust_volt[rgb_index][AD_IVT];
+ v23 = adjust_volt[rgb_index][AD_IV23];
+ ratio = volt_table_cv_64_dv_320[gamma];
+
+ ret = (vt << 16) - ((vt-v23)*ratio);
+ ret = ret >> 16;
+
+ return ret;
+}
+
+static u32 calc_v23_volt(s16 gamma, int rgb_index, u32 adjust_volt[CI_MAX][AD_IVMAX])
+{
+ /* for CV : 64, DV :319 */
+ int ret = 0;
+ u32 vt, v35;
+ u32 ratio = 0;
+
+ vt = adjust_volt[rgb_index][AD_IVT];
+ v35 = adjust_volt[rgb_index][AD_IV35];
+ ratio = volt_table_cv_64_dv_320[gamma];
+
+ ret = (vt << 16) - ((vt-v35)*ratio);
+ ret = ret >> 16;
+
+ return ret;
+}
+
+static u32 calc_v35_volt(s16 gamma, int rgb_index, u32 adjust_volt[CI_MAX][AD_IVMAX])
+{
+ /* for CV : 65, DV :319 */
+ int ret = 0;
+ u32 vt, v51;
+ u32 ratio = 0;
+
+ vt = adjust_volt[rgb_index][AD_IVT];
+ v51 = adjust_volt[rgb_index][AD_IV51];
+ ratio = volt_table_cv_64_dv_320[gamma];
+
+ ret = (vt << 16) - ((vt-v51)*ratio);
+ ret = ret >> 16;
+
+ return ret;
+}
+
+static u32 calc_v51_volt(s16 gamma, int rgb_index, u32 adjust_volt[CI_MAX][AD_IVMAX])
+{
+ /* for CV : 65, DV :319 */
+ int ret = 0;
+ u32 vt, v87;
+ u32 ratio = 0;
+
+ vt = adjust_volt[rgb_index][AD_IVT];
+ v87 = adjust_volt[rgb_index][AD_IV87];
+ ratio = volt_table_cv_64_dv_320[gamma];
+
+ ret = (vt << 16) - ((vt-v87)*ratio);
+ ret = ret >> 16;
+
+ return ret;
+
+}
+
+static u32 calc_v87_volt(s16 gamma, int rgb_index, u32 adjust_volt[CI_MAX][AD_IVMAX])
+{
+ /* for CV : 64, DV :319 */
+ int ret = 0;
+ u32 vt, v151;
+ u32 ratio = 0;
+
+ vt = adjust_volt[rgb_index][AD_IVT];
+ v151 = adjust_volt[rgb_index][AD_IV151];
+ ratio = volt_table_cv_64_dv_320[gamma];
+
+ ret = (vt << 16) - ((vt-v151)*ratio);
+ ret = ret >> 16;
+
+ return ret;
+}
+
+static u32 calc_v151_volt(s16 gamma, int rgb_index, u32 adjust_volt[CI_MAX][AD_IVMAX])
+{
+ /* for CV : 64, DV :319 */
+ int ret = 0;
+ u32 vt, v203;
+ u32 ratio = 0;
+
+ vt = adjust_volt[rgb_index][AD_IVT];
+ v203 = adjust_volt[rgb_index][AD_IV203];
+ ratio = volt_table_cv_64_dv_320[gamma];
+
+ ret = (vt << 16) - ((vt-v203)*ratio);
+ ret = ret >> 16;
+
+ return ret;
+}
+
+static u32 calc_v203_volt(s16 gamma, int rgb_index, u32 adjust_volt[CI_MAX][AD_IVMAX])
+{
+ /* for CV : 64, DV :319 */
+ int ret = 0;
+ u32 vt, v255;
+ u32 ratio = 0;
+
+ vt = adjust_volt[rgb_index][AD_IVT];
+ v255 = adjust_volt[rgb_index][AD_IV255];
+ ratio = volt_table_cv_64_dv_320[gamma];
+
+ ret = (vt << 16) - ((vt-v255)*ratio);
+ ret = ret >> 16;
+
+ return ret;
+}
+
+static u32 calc_v255_volt(s16 gamma, int rgb_index, u32 adjust_volt[CI_MAX][AD_IVMAX])
+{
+ u32 ret = 0;
+
+ ret = volt_table_v255[gamma] >> 16;
+
+ return ret;
+}
+
+u8 calc_voltage_table_ea8061(struct str_smart_dim *smart, const u8 *mtp)
+{
+ int c, i, j;
+#if defined(MTP_REVERSE)
+ int offset1 = 0;
+#endif
+ int offset = 0;
+ s16 t1, t2;
+ s16 adjust_mtp[CI_MAX][IV_MAX];
+ u8 range_index;
+ u8 table_index = 0;
+ u32 v1, v2;
+ u32 ratio;
+ u32(*calc_volt[IV_MAX])(s16 gamma, int rgb_index, u32 adjust_volt[CI_MAX][AD_IVMAX]) = {
+ calc_vt_volt,
+ calc_v3_volt,
+ calc_v11_volt,
+ calc_v23_volt,
+ calc_v35_volt,
+ calc_v51_volt,
+ calc_v87_volt,
+ calc_v151_volt,
+ calc_v203_volt,
+ calc_v255_volt,
+ };
+ u8 calc_seq[9] = { IV_VT, IV_203, IV_151, IV_87, IV_51, IV_35, IV_23, IV_11, IV_3};
+ u8 ad_seq[9] = {AD_IVT, AD_IV203, AD_IV151, AD_IV87, AD_IV51, AD_IV35, AD_IV23, AD_IV11, AD_IV3};
+
+ memset(adjust_mtp, 0, sizeof(adjust_mtp));
+
+ for (c = CI_RED; c < CI_MAX; c++) {
+ offset = c*2;
+ t1 = s9_to_s16(mtp[offset]<<8|mtp[offset+1]);
+ t2 = (smart->default_gamma[offset]<<8|smart->default_gamma[offset+1]) + t1;
+ smart->mtp[c][IV_255] = t1;
+ adjust_mtp[c][IV_255] = t2;
+ smart->adjust_volt[c][AD_IV255] = calc_volt[IV_255](t2, c, smart->adjust_volt);
+ /* for V0 All RGB Voltage Value is Reference Voltage */
+ smart->adjust_volt[c][AD_IVT] = VREG_OUT_1000;
+ }
+
+ for (i = IV_VT; i < IV_255; i++) {
+ for (c = CI_RED; c < CI_MAX; c++) {
+ if (i < IV_3) {
+ t1 = 0;
+ t2 = smart->default_gamma[CI_MAX*(10-calc_seq[i])+c] + t1;
+ smart->mtp[c][calc_seq[i]] = t1;
+ adjust_mtp[c][calc_seq[i]] = t2;
+ smart->adjust_volt[c][ad_seq[i]] = calc_volt[calc_seq[i]](t2, c, smart->adjust_volt);
+ } else {
+ t1 = (s8)mtp[CI_MAX*(10-calc_seq[i])+c];
+ t2 = smart->default_gamma[CI_MAX*(10-calc_seq[i])+c] + t1;
+ smart->mtp[c][calc_seq[i]] = t1;
+ adjust_mtp[c][calc_seq[i]] = t2;
+ smart->adjust_volt[c][ad_seq[i]] = calc_volt[calc_seq[i]](t2, c, smart->adjust_volt);
+ }
+ }
+ }
+
+ for (i = AD_IVT; i < AD_IVMAX; i++) {
+ for (c = CI_RED; c < CI_MAX; c++) {
+ if (i == 0)
+ smart->ve[table_index].v[c] = VREG_OUT_1000;
+ else
+ smart->ve[table_index].v[c] = smart->adjust_volt[c][i];
+ }
+ range_index = 0;
+
+ for (j = table_index+1; j < table_index+range_table_count[i]; j++) {
+ for (c = CI_RED; c < CI_MAX; c++) {
+ if (smart->t_info[i].offset_table != NULL)
+ ratio = smart->t_info[i].offset_table[range_index] * smart->t_info[i].rv;
+ else
+ ratio = (range_table_count[i]-(range_index+1)) * smart->t_info[i].rv;
+
+ v1 = smart->adjust_volt[c][i+1] << 15;
+ v2 = (smart->adjust_volt[c][i] - smart->adjust_volt[c][i+1])*ratio;
+ smart->ve[j].v[c] = ((v1+v2) >> 15);
+ }
+ range_index++;
+ }
+ table_index = j;
+ }
+
+ for (i = 1; i < 3; i++) {
+ for (c = CI_RED; c < CI_MAX; c++)
+ smart->ve[i].v[c] = smart->ve[3].v[c]+((smart->ve[0].v[c]-smart->ve[3].v[c])*(3-i)/3);
+ }
+
+#if 0
+ printk(KERN_INFO "++++++++++++++++++++++++++++++ MTP VALUE ++++++++++++++++++++++++++++++\n");
+ for (i = IV_VT; i < IV_MAX; i++) {
+ printk("V Level : %d - ", i);
+ for (c = CI_RED; c < CI_MAX; c++)
+ printk(" %c : 0x%08x(%04d)", color_name[c], smart->mtp[c][i], smart->mtp[c][i]);
+ printk("\n");
+ }
+
+ printk(KERN_INFO "\n\n++++++++++++++++++++++++++++++ ADJUST VALUE ++++++++++++++++++++++++++++++\n");
+ for (i = IV_VT; i < IV_MAX; i++) {
+ printk("V Level : %d - ", i);
+ for (c = CI_RED; c < CI_MAX; c++)
+ printk(" %c : 0x%08x(%04d)", color_name[c],
+ adjust_mtp[c][i], adjust_mtp[c][i]);
+ printk("\n");
+ }
+
+ printk(KERN_INFO "\n\n++++++++++++++++++++++++++++++ ADJUST VOLTAGE ++++++++++++++++++++++++++++++\n");
+ for (i = AD_IVT; i < AD_IVMAX; i++) {
+ printk("V Level : %d - ", i);
+ for (c = CI_RED; c < CI_MAX; c++)
+ printk(" %c : %04dV", color_name[c], smart->adjust_volt[c][i]);
+ printk("\n");
+ }
+
+ printk(KERN_INFO "\n\n++++++++++++++++++++++++++++++++++++++ VOLTAGE TABLE ++++++++++++++++++++++++++++++++++++++\n");
+ for (i = 0; i < 256; i++) {
+ printk("Gray Level : %03d - ", i);
+ for (c = CI_RED; c < CI_MAX; c++)
+ printk(" %c : %04dV", color_name[c], smart->ve[i].v[c]);
+ printk("\n");
+ }
+#endif
+ return 0;
+}
+
+
+int init_table_info_ea8061(struct str_smart_dim *smart)
+{
+ int i;
+ int offset = 0;
+
+ for (i = 0; i < IV_TABLE_MAX; i++) {
+ smart->t_info[i].count = (u8)range_table_count[i];
+ smart->t_info[i].offset_table = offset_table[i];
+ smart->t_info[i].rv = table_radio[i];
+ offset += range_table_count[i];
+ }
+
+ smart->flooktbl = flookup_table;
+ smart->g300_gra_tbl = gamma_300_gra_table;
+ smart->gamma_table[G_21] = GAMMA_CONTROL_TABLE[G_21];
+ smart->gamma_table[G_213] = GAMMA_CONTROL_TABLE[G_213];
+ smart->gamma_table[G_215] = GAMMA_CONTROL_TABLE[G_215];
+ smart->gamma_table[G_218] = GAMMA_CONTROL_TABLE[G_218];
+ smart->gamma_table[G_22] = GAMMA_CONTROL_TABLE[G_22];
+ smart->gamma_table[G_221] = GAMMA_CONTROL_TABLE[G_221];
+ smart->gamma_table[G_222] = GAMMA_CONTROL_TABLE[G_222];
+ smart->gamma_table[G_223] = GAMMA_CONTROL_TABLE[G_223];
+ smart->gamma_table[G_224] = GAMMA_CONTROL_TABLE[G_224];
+ smart->gamma_table[G_225] = GAMMA_CONTROL_TABLE[G_225];
+
+ for (i = 0; i < GAMMA_300CD_MAX; i++) {
+ if (smart->panelid[2] == gamma_id_list[i])
+ break;
+ }
+
+ if (i >= GAMMA_300CD_MAX) {
+ printk(KERN_ERR "[SMART DIMMING-WARNING] %s Can't found default gamma table\n", __func__);
+ smart->default_gamma = gamma_300cd_list[GAMMA_300CD_MAX-1];
+ } else
+ smart->default_gamma = gamma_300cd_list[i];
+
+ return 0;
+}
+
+static u32 lookup_vtbl_idx(struct str_smart_dim *smart, u32 gamma)
+{
+ u32 lookup_index;
+ u16 table_count, table_index;
+ u32 gap, i;
+ u32 minimum = smart->g300_gra_tbl[255];
+ u32 candidate = 0;
+ u32 offset = 0;
+
+ lookup_index = (gamma/VALUE_DIM_1000)+1;
+ if (lookup_index > MAX_GRADATION) {
+ /*printk(KERN_ERR "ERROR Wrong input value LOOKUP INDEX : %d\n", lookup_index);*/
+ return 0;
+ }
+
+ if (smart->flooktbl[lookup_index].count) {
+ if (smart->flooktbl[lookup_index-1].count) {
+ table_index = smart->flooktbl[lookup_index-1].entry;
+ table_count = smart->flooktbl[lookup_index].count + smart->flooktbl[lookup_index-1].count;
+ } else {
+ table_index = smart->flooktbl[lookup_index].entry;
+ table_count = smart->flooktbl[lookup_index].count;
+ }
+ } else {
+ offset += 1;
+ while (!(smart->flooktbl[lookup_index+offset].count || smart->flooktbl[lookup_index-offset].count))
+ offset++;
+
+ if (smart->flooktbl[lookup_index-offset].count)
+ table_index = smart->flooktbl[lookup_index-offset].entry;
+ else
+ table_index = smart->flooktbl[lookup_index+offset].entry;
+
+ table_count = smart->flooktbl[lookup_index+offset].count + smart->flooktbl[lookup_index-offset].count;
+ }
+
+ for (i = 0; i < table_count; i++) {
+ if (gamma > smart->g300_gra_tbl[table_index])
+ gap = gamma - smart->g300_gra_tbl[table_index];
+ else
+ gap = smart->g300_gra_tbl[table_index] - gamma;
+
+ if (gap == 0) {
+ candidate = table_index;
+ break;
+ }
+
+ if (gap < minimum) {
+ minimum = gap;
+ candidate = table_index;
+ }
+ table_index++;
+ }
+
+#if 0
+ printk(KERN_INFO "cal : found index : %d\n", candidate);
+ printk(KERN_INFO "gamma : %d, found index : %d found gamma : %d\n",
+ gamma, candidate, smart->g300_gra_tbl[candidate]);
+#endif
+ return candidate;
+}
+
+static u32 calc_vt_reg(int ci, u32 dv[CI_MAX][IV_MAX], u32 adjust_volt[CI_MAX][AD_IVMAX])
+{
+ return 0;
+}
+
+static u32 calc_v3_reg(int ci, u32 dv[CI_MAX][IV_MAX], u32 adjust_volt[CI_MAX][AD_IVMAX])
+{
+ u32 t1, t2;
+ u32 v0 = VREG_OUT_1000, v3, v11;
+ u32 ret;
+
+ /*v0 = dv[ci][IV_0];*/
+ v3 = dv[ci][IV_3];
+ v11 = dv[ci][IV_11];
+
+ t1 = (v0 - v3) << 10;
+ t2 = (v0 - v11) ? (v0 - v11) : (v0) ? v0 : 1;
+ ret = (320 * (t1/t2)) - (64 << 10);
+ ret >>= 10;
+
+ return ret;
+}
+
+static u32 calc_v11_reg(int ci, u32 dv[CI_MAX][IV_MAX], u32 adjust_volt[CI_MAX][AD_IVMAX])
+{
+ u32 t1, t2;
+ u32 vt, v11, v23;
+ u32 ret;
+
+ vt = adjust_volt[ci][AD_IVT];
+ v11 = dv[ci][IV_11];
+ v23 = dv[ci][IV_23];
+ t1 = (vt - v11) << 10;
+ t2 = (vt - v23) ? (vt - v23) : (vt) ? vt : 1;
+ ret = (320 * (t1/t2)) - (64 << 10);
+ ret >>= 10;
+
+ return ret;
+}
+
+static u32 calc_v23_reg(int ci, u32 dv[CI_MAX][IV_MAX], u32 adjust_volt[CI_MAX][AD_IVMAX])
+{
+ u32 t1, t2;
+ u32 vt, v23, v35;
+ u32 ret;
+
+ /*vt = dv[ci][IV_VT];*/
+ vt = adjust_volt[ci][AD_IVT];
+ v23 = dv[ci][IV_23];
+ v35 = dv[ci][IV_35];
+
+ t1 = (vt - v23) << 10;
+ t2 = (vt - v35) ? (vt - v35) : (vt) ? vt : 1;
+ ret = (320 * (t1/t2)) - (64 << 10);
+ ret >>= 10;
+
+ return ret;
+}
+
+static u32 calc_v35_reg(int ci, u32 dv[CI_MAX][IV_MAX], u32 adjust_volt[CI_MAX][AD_IVMAX])
+{
+ u32 t1, t2;
+ u32 vt, v35, v51;
+ u32 ret;
+
+ /*vt = dv[ci][IV_VT];*/
+ vt = adjust_volt[ci][AD_IVT];
+ v35 = dv[ci][IV_35];
+ v51 = dv[ci][IV_51];
+
+ t1 = (vt - v35) << 10;
+ t2 = (vt - v51) ? (vt - v51) : (vt) ? vt : 1;
+ ret = (320 * (t1/t2)) - (64 << 10);
+ ret >>= 10;
+
+ return ret;
+}
+
+static u32 calc_v51_reg(int ci, u32 dv[CI_MAX][IV_MAX], u32 adjust_volt[CI_MAX][AD_IVMAX])
+{
+ u32 t1, t2;
+ u32 vt, v51, v87;
+ u32 ret;
+
+ /*vt = dv[ci][IV_VT];*/
+ vt = adjust_volt[ci][AD_IVT];
+ v51 = dv[ci][IV_51];
+ v87 = dv[ci][IV_87];
+
+ t1 = (vt - v51) << 10;
+ t2 = (vt - v87) ? (vt - v87) : (vt) ? vt : 1;
+ ret = (320 * (t1/t2)) - (64 << 10);
+ ret >>= 10;
+
+ return ret;
+}
+
+
+static u32 calc_v87_reg(int ci, u32 dv[CI_MAX][IV_MAX], u32 adjust_volt[CI_MAX][AD_IVMAX])
+{
+ u32 t1, t2;
+ u32 vt, v87, v151;
+ u32 ret;
+
+ /*vt = dv[ci][IV_VT];*/
+ vt = adjust_volt[ci][AD_IVT];
+ v87 = dv[ci][IV_87];
+ v151 = dv[ci][IV_151];
+
+ t1 = (vt - v87) << 10;
+ t2 = (vt - v151) ? (vt - v151) : (vt) ? vt : 1;
+ ret = (320 * (t1/t2)) - (64 << 10);
+ ret >>= 10;
+
+ return ret;
+}
+
+static u32 calc_v151_reg(int ci, u32 dv[CI_MAX][IV_MAX], u32 adjust_volt[CI_MAX][AD_IVMAX])
+{
+ u32 t1, t2;
+ u32 vt, v151, v203;
+ u32 ret;
+
+ /*vt = dv[ci][IV_VT];*/
+ vt = adjust_volt[ci][AD_IVT];
+ v151 = dv[ci][IV_151];
+ v203 = dv[ci][IV_203];
+
+ t1 = (vt - v151) << 10;
+ t2 = (vt - v203) ? (vt - v203) : (vt) ? vt : 1;
+ ret = (320 * (t1/t2)) - (64 << 10);
+ ret >>= 10;
+
+ return ret;
+}
+
+static u32 calc_v203_reg(int ci, u32 dv[CI_MAX][IV_MAX], u32 adjust_volt[CI_MAX][AD_IVMAX])
+{
+ u32 t1, t2;
+ u32 vt, v151, v255;
+ u32 ret;
+
+ /*vt = dv[ci][IV_VT];*/
+ vt = adjust_volt[ci][IV_VT];
+ v151 = dv[ci][IV_203];
+ v255 = dv[ci][IV_255];
+
+ t1 = (vt - v151) << 10;
+ t2 = (vt - v255) ? (vt - v255) : (vt) ? vt : 1;
+ ret = (320 * (t1/t2)) - (64 << 10);
+ ret >>= 10;
+
+ return ret;
+}
+
+static u32 calc_v255_reg(int ci, u32 dv[CI_MAX][IV_MAX], u32 adjust_volt[CI_MAX][AD_IVMAX])
+{
+ u32 ret;
+ u32 v255;
+ v255 = dv[ci][IV_255];
+
+ ret = (559 * 1000) - (VT_255_calc_param * v255);
+ ret = ret / 1000;
+
+ return ret;
+}
+
+u32 calc_gamma_table_ea8061(struct str_smart_dim *smart, u32 gv, u8 result[], u8 gamma_curve, const u8 *mtp)
+{
+ u32 i, c, t1;
+ u32 temp;
+ u32 lidx;
+ u32 dv[CI_MAX][IV_MAX];
+ s16 gamma[CI_MAX][IV_MAX];
+ u16 offset;
+ u32(*calc_reg[IV_MAX])(int ci, u32 dv[CI_MAX][IV_MAX], u32 adjust_volt[CI_MAX][AD_IVMAX]) = {
+ calc_vt_reg,
+ calc_v3_reg,
+ calc_v11_reg,
+ calc_v23_reg,
+ calc_v35_reg,
+ calc_v51_reg,
+ calc_v87_reg,
+ calc_v151_reg,
+ calc_v203_reg,
+ calc_v255_reg,
+ };
+
+memset(gamma, 0, sizeof(gamma));
+
+#if 0
+ for (c = CI_RED; c < CI_MAX; c++)
+ dv[c][IV_VT] = smart->ve[AD_IVT].v[c]; /* not use V1 calculate value*/
+#endif
+
+ for (i = IV_3 ; i < IV_MAX; i++) {
+ temp = (smart->gamma_table[gamma_curve][dv_value[i]] * gv) / 1000;
+ lidx = lookup_vtbl_idx(smart, temp);
+ for (c = CI_RED; c < CI_MAX; c++)
+ dv[c][i] = smart->ve[lidx].v[c];
+ }
+
+ for (c = CI_RED; c < CI_MAX; c++) {
+ offset = c*2;
+ t1 = s9_to_s16(mtp[offset]<<8|mtp[offset+1]);
+ smart->mtp[c][IV_255] = t1;
+ }
+
+ for (i = 1; i < 10; i++) {
+ for (c = CI_RED; c < CI_MAX; c++) {
+ t1 = (s8)mtp[CI_MAX*(i + 1)+c];
+ smart->mtp[c][IV_255 - i] = t1;
+ }
+ }
+
+ /* for IV_1 does not calculate value */
+ /* Do not use gamma value (IV_1) */
+#if 0
+ for (c = CI_RED; c < CI_MAX; c++)
+ gamma[c][IV_VT] = smart->default_gamma[c];
+#endif
+
+ for (i = IV_3; i < IV_MAX; i++) {
+ for (c = CI_RED; c < CI_MAX; c++)
+ gamma[c][i] = (s16)calc_reg[i](c, dv, smart->adjust_volt) - smart->mtp[c][i];
+ }
+
+ for (c = CI_RED; c < CI_MAX; c++) {
+ offset = IV_255*CI_MAX+c*2;
+ result[offset+1] = gamma[c][IV_255] & 0xff;
+ result[offset] = (u8)((gamma[c][IV_255] >> 8) & 0xff);
+ }
+
+ for (c = CI_RED; c < CI_MAX; c++) {
+ for (i = IV_VT; i < IV_255; i++)
+ result[(CI_MAX*i)+c] = gamma[c][i];
+ }
+
+#if 0
+
+printk(KERN_INFO "\n\n++++++++++++++++++++++++++++++ FOUND VOLTAGE ++++++++++++++++++++++++++++++\n");
+for (i = IV_VT; i < IV_255; i++) {
+ printk("V Level : %d - ", i);
+ for (c = CI_RED; c < CI_MAX; c++)
+ printk("%c : %04dV", color_name[c], dv[c][i]);
+ printk("\n");
+}
+
+printk(KERN_INFO "\n\n++++++++++++++++++++++++++++++ FOUND REG ++++++++++++++++++++++++++++++\n");
+for (i = IV_VT; i < IV_255; i++) {
+ printk("V Level : %d - ", i);
+ for (c = CI_RED; c < CI_MAX; c++)
+ printk("%c : %3d, 0x%2x", color_name[c], gamma[c][i], gamma[c][i]);
+ printk("\n");
+}
+#endif
+return 0;
+}
+
+u32 calc_gamma_table_190_ea8061(struct str_smart_dim *smart, u32 gv, u8 result[], u8 gamma_curve, const u8 *mtp)
+{
+ u32 i, c, t1;
+ u32 temp;
+ u32 lidx_215_190;
+ u32 dv[CI_MAX][IV_MAX];
+ s16 gamma_215_190[CI_MAX][IV_MAX];
+ u16 offset;
+ u32(*calc_reg[IV_MAX])(int ci, u32 dv[CI_MAX][IV_MAX], u32 adjust_volt[CI_MAX][AD_IVMAX]) = {
+ calc_vt_reg,
+ calc_v3_reg,
+ calc_v11_reg,
+ calc_v23_reg,
+ calc_v35_reg,
+ calc_v51_reg,
+ calc_v87_reg,
+ calc_v151_reg,
+ calc_v203_reg,
+ calc_v255_reg,
+ };
+ memset(gamma_215_190, 0, sizeof(gamma_215_190));
+
+#if 0
+ for (c = CI_RED; c < CI_MAX; c++)
+ dv[c][IV_1] = smart->ve[AD_IV1].v[c];
+#endif
+
+ for (i = IV_3; i < IV_MAX; i++) {
+ if (i == IV_151) {
+ temp = (smart->gamma_table[gamma_curve][dv_value[i]] * gv)/1000;
+ lidx_215_190 = lookup_vtbl_idx(smart, temp)-1;
+ } else if ((i == IV_203) || (i == IV_255)) {
+ temp = (smart->gamma_table[gamma_curve][dv_value[i]] * gv)/1000;
+ lidx_215_190 = lookup_vtbl_idx(smart, temp)-2;
+ } else {
+ temp = (smart->gamma_table[gamma_curve][dv_value[i]] * gv)/1000;
+ lidx_215_190 = lookup_vtbl_idx(smart, temp);
+ }
+
+ for (c = CI_RED; c < CI_MAX; c++)
+ dv[c][i] = smart->ve[lidx_215_190].v[c];
+ }
+
+ for (c = CI_RED; c < CI_MAX; c++) {
+ offset = c*2;
+ t1 = s9_to_s16(mtp[offset]<<8|mtp[offset+1]);
+ smart->mtp[c][IV_255] = t1;
+ }
+
+ for (i = 1; i < 10; i++) {
+ for (c = CI_RED; c < CI_MAX; c++) {
+ t1 = (s8)mtp[CI_MAX*(i + 1)+c];
+ smart->mtp[c][IV_255 - i] = t1;
+ }
+ }
+
+ /* for IV1 does not calculate value */
+ /* just use default gamma value (IV1) */
+#if 0
+ for (c = CI_RED; c < CI_MAX; c++)
+ gamma_215_190[c][IV_VT] = smart->default_gamma[c];
+#endif
+
+ for (i = IV_3; i < IV_MAX; i++) {
+ for (c = CI_RED; c < CI_MAX; c++)
+ gamma_215_190[c][i] = (s16)calc_reg[i](c, dv, smart->adjust_volt) - smart->mtp[c][i];
+ }
+
+ for (c = CI_RED; c < CI_MAX; c++) {
+ offset = IV_255*CI_MAX+c*2;
+ result[offset+1] = gamma_215_190[c][IV_255] & 0xff;
+ result[offset] = (u8)((gamma_215_190[c][IV_255] >> 8) & 0xff);
+ }
+
+ for (c = CI_RED; c < CI_MAX; c++) {
+ for (i = IV_VT; i < IV_255; i++)
+ result[(CI_MAX*i)+c] = gamma_215_190[c][i];
+ }
+
+#if 0
+ printk(KERN_INFO "\n\n++++++++++++++++++++++++++++++ FOUND VOLTAGE ++++++++++++++++++++++++++++++\n");
+ for (i = IV_VT; i < IV_255; i++) {
+ printk("V Level : %d - ", i);
+ for (c = CI_RED; c < CI_MAX; c++)
+ printk("%c : %04dV", color_name[c], dv[c][i]);
+ printk("\n");
+ }
+
+ printk(KERN_INFO "\n\n++++++++++++++++++++++++++++++ FOUND REG ++++++++++++++++++++++++++++++\n");
+ for (i = IV_VT; i < IV_255; i++) {
+ printk("V Level : %d - ", i);
+ for (c = CI_RED; c < CI_MAX; c++)
+ printk("2.15Gamma %c : %3d, 0x%2x", color_name[c], gamma_215_190[c][i], gamma_215_190[c][i]);
+ printk("\n");
+ }
+#endif
+ return 0;
+}
+
+u32 calc_gamma_table_20_100_ea8061(struct str_smart_dim *smart, u32 gv, u8 result[], u8 gamma_curve, const u8 *mtp)
+{
+ u32 i, c, t1;
+ u32 temp;
+ u32 lidx_110;
+ u32 dv[CI_MAX][IV_MAX];
+ s16 gamma_110[CI_MAX][IV_MAX];
+ u16 offset;
+ u32(*calc_reg[IV_MAX])(int ci, u32 dv[CI_MAX][IV_MAX], u32 adjust_volt[CI_MAX][AD_IVMAX]) = {
+ calc_vt_reg,
+ calc_v3_reg,
+ calc_v11_reg,
+ calc_v23_reg,
+ calc_v35_reg,
+ calc_v51_reg,
+ calc_v87_reg,
+ calc_v151_reg,
+ calc_v203_reg,
+ calc_v255_reg,
+ };
+ memset(gamma_110, 0, sizeof(gamma_110));
+
+#if 0
+ for (c = CI_RED; c < CI_MAX; c++)
+ dv[c][IV_1] = smart->ve[AD_IV1].v[c];
+#endif
+
+ for (i = IV_3; i < IV_MAX; i++) {
+ if (i == IV_11) {
+ temp = (smart->gamma_table[gamma_curve][dv_value[i]] * gv)/1000;
+ lidx_110 = lookup_vtbl_idx(smart, temp)-1;
+ } else {
+ temp = (smart->gamma_table[gamma_curve][dv_value[i]] * gv)/1000;
+ lidx_110 = lookup_vtbl_idx(smart, temp);
+ }
+
+ for (c = CI_RED; c < CI_MAX; c++)
+ dv[c][i] = smart->ve[lidx_110].v[c];
+ }
+
+ for (c = CI_RED; c < CI_MAX; c++) {
+ offset = c*2;
+ t1 = s9_to_s16(mtp[offset]<<8|mtp[offset+1]);
+ smart->mtp[c][IV_255] = t1;
+ }
+
+ for (i = 1; i < 10; i++) {
+ for (c = CI_RED; c < CI_MAX; c++) {
+ t1 = (s8)mtp[CI_MAX*(i + 1)+c];
+ smart->mtp[c][IV_255 - i] = t1;
+ }
+ }
+
+ /* for IV1 does not calculate value */
+ /* just use default gamma value (IV1) */
+#if 0
+ for (c = CI_RED; c < CI_MAX; c++)
+ gamma_210_110[c][IV_VT] = smart->default_gamma[c];
+#endif
+
+ for (i = IV_3; i < IV_MAX; i++) {
+ for (c = CI_RED; c < CI_MAX; c++)
+ gamma_110[c][i] = (s16)calc_reg[i](c, dv, smart->adjust_volt) - smart->mtp[c][i];
+ }
+
+ for (c = CI_RED; c < CI_MAX; c++) {
+ offset = IV_255*CI_MAX+c*2;
+ result[offset+1] = gamma_110[c][IV_255] & 0xff;
+ result[offset] = (u8)((gamma_110[c][IV_255] >> 8) & 0xff);
+ }
+
+ for (c = CI_RED; c < CI_MAX; c++) {
+ for (i = IV_VT; i < IV_255; i++)
+ result[(CI_MAX*i)+c] = gamma_110[c][i];
+ }
+
+#if 0
+ printk(KERN_INFO "\n\n++++++++++++++++++++++++++++++ FOUND VOLTAGE ++++++++++++++++++++++++++++++\n");
+ for (i = IV_VT; i < IV_MAX; i++) {
+ printk("V Level : %d - ", i);
+ for (c = CI_RED; c < CI_MAX; c++)
+ printk("%c : %04dV", color_name[c], dv[c][i]);
+ printk("\n");
+ }
+
+ printk(KERN_INFO "\n\n++++++++++++++++++++++++++++++ FOUND REG ++++++++++++++++++++++++++++++\n");
+ for (i = IV_VT; i < IV_MAX; i++) {
+ printk("V Level : %d - ", i);
+ for (c = CI_RED; c < CI_MAX; c++)
+ printk("2.15Gamma %c : %3d, 0x%2x", color_name[c], gamma_110[c][i], gamma_210_110[c][i]);
+ printk("\n");
+ }
+#endif
+ return 0;
+}
diff --git a/drivers/video/samsung/smart_dimming_ea8061.h b/drivers/video/samsung/smart_dimming_ea8061.h
new file mode 100644
index 0000000..263c2e2
--- /dev/null
+++ b/drivers/video/samsung/smart_dimming_ea8061.h
@@ -0,0 +1,133 @@
+/* linux/drivers/video/samsung/smartdimming.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+
+ * Samsung Smart Dimming for OCTA
+ *
+ * Minwoo Kim, <minwoo7945.kim@samsung.com>
+ *
+*/
+
+
+#ifndef __SMART_DIMMING_H__
+#define __SMART_DIMMING_H__
+
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/mutex.h>
+#include <linux/wait.h>
+#include <linux/ctype.h>
+
+#define MAX_GRADATION 300
+#define PANEL_ID_MAX 3
+#define GAMMA_300CD_MAX 9
+
+
+enum {
+ CI_RED = 0,
+ CI_GREEN = 1,
+ CI_BLUE = 2,
+ CI_MAX = 3,
+};
+
+
+enum {
+ IV_VT ,
+ IV_3 ,
+ IV_11 ,
+ IV_23 ,
+ IV_35 ,
+ IV_51,
+ IV_87 ,
+ IV_151,
+ IV_203,
+ IV_255,
+ IV_MAX,
+ IV_TABLE_MAX,
+};
+
+
+enum {
+ AD_IVT,
+ AD_IV3,
+ AD_IV11,
+ AD_IV23 ,
+ AD_IV35,
+ AD_IV51 ,
+ AD_IV87 ,
+ AD_IV151 ,
+ AD_IV203 ,
+ AD_IV255 ,
+ AD_IVMAX ,
+};
+
+
+enum {
+ G_21,
+ G_213,
+ G_215,
+ G_218,
+ G_22,
+ G_221,
+ G_222,
+ G_223,
+ G_224,
+ G_225,
+ G_MAX,
+};
+
+
+struct str_voltage_entry {
+ u32 v[CI_MAX];
+};
+
+
+struct str_table_info {
+ /* et : start gray value */
+ u8 st;
+ /* end gray value, st + count */
+ u8 et;
+ u8 count;
+ const u8 *offset_table;
+ /* rv : ratio value */
+ u32 rv;
+};
+
+
+struct str_flookup_table {
+ u16 entry;
+ u16 count;
+};
+
+
+struct str_smart_dim {
+ u8 panelid[PANEL_ID_MAX];
+ s16 mtp[CI_MAX][IV_MAX];
+ struct str_voltage_entry ve[256];
+ const u8 *default_gamma;
+ struct str_table_info t_info[IV_TABLE_MAX];
+ const struct str_flookup_table *flooktbl;
+ const u32 *g22_tbl;
+ const u32 *gamma_table[G_MAX];
+ const u32 *g300_gra_tbl;
+ u32 adjust_volt[CI_MAX][AD_IVMAX];
+};
+
+struct rgb_offset_info {
+ unsigned int candela_idx;
+ unsigned int gray;
+ unsigned int rgb;
+ int offset;
+};
+
+
+int init_table_info_ea8061(struct str_smart_dim *smart);
+u8 calc_voltage_table_ea8061(struct str_smart_dim *smart, const u8 *mtp);
+u32 calc_gamma_table_ea8061(struct str_smart_dim *smart, u32 gv, u8 result[], u8 gamma_curve, const u8 *mtp);
+u32 calc_gamma_table_190_ea8061(struct str_smart_dim *smart, u32 gv, u8 result[], u8 gamma_curve, const u8 *mtp);
+u32 calc_gamma_table_20_100_ea8061(struct str_smart_dim *smart, u32 gv, u8 result[], u8 gamma_curve, const u8 *mtp);
+
+#endif
diff --git a/drivers/video/samsung/smart_dimming_s6evr02.c b/drivers/video/samsung/smart_dimming_s6evr02.c
new file mode 100644
index 0000000..9c0af0a
--- /dev/null
+++ b/drivers/video/samsung/smart_dimming_s6evr02.c
@@ -0,0 +1,948 @@
+/* linux/drivers/video/samsung/smartdimming.c
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+
+ * Samsung Smart Dimming for OCTA
+ *
+ * Minwoo Kim, <minwoo7945.kim@samsung.com>
+ *
+*/
+
+#include "smart_dimming_s6evr02.h"
+#include "s6evr02_volt_tbl.h"
+
+#define VALUE_DIM_1000 1000
+#define VT_255_div_1000 860000
+#define VREG_OUT_1000 6100
+#define VREG_OUT_1000_1024 6246400
+#define VT_255_calc_param (VT_255_div_1000 / VREG_OUT_1000)
+
+static const u8 range_table_count[IV_TABLE_MAX] = {
+ 3, 8, 12, 12, 16, 36, 64, 52, 52, 1
+};
+
+static const u32 table_radio[IV_TABLE_MAX] = {
+ 16384, 4138, 2763, 2763, 2080, 918, 516, 636, 636, 0
+};
+
+static const u32 dv_value[IV_MAX] = {
+ 0, 3, 11, 23, 35, 51, 87, 151, 203, 255
+};
+
+static const char color_name[3] = {'R', 'G', 'B'};
+
+static const u8 *offset_table[IV_TABLE_MAX] = {
+ NULL, /*V3*/
+ NULL, /*V11*/
+ NULL, /*V23*/
+ NULL, /*V23*/
+ NULL, /*V35*/
+ NULL, /*V51*/
+ NULL, /*V87*/
+ NULL, /*V151*/
+ NULL, /*V203*/
+ NULL /*V255*/
+};
+
+static const unsigned char gamma_300cd_80[] = {
+ 0x00, 0xFF, 0x01, 0x1C, 0x01, 0x2C,
+ 0xDA, 0xD7, 0xDA, 0xD5, 0xD2, 0xD6, 0xC1, 0xBC, 0xC2,
+ 0xCA, 0xB9, 0xCB, 0xDC, 0xE5, 0xDD, 0xDA, 0xD8, 0xDD,
+ 0xBA, 0xA8, 0xC1, 0x6B, 0x20, 0xD7, 0x02, 0x03, 0x02
+};
+
+static const unsigned char gamma_300cd_81[] = {
+ 0x00, 0xFF, 0x01, 0x1D, 0x01, 0x2D,
+ 0xDA, 0xD7, 0xDA, 0xD6, 0xD3, 0xD7, 0xC1, 0xBC, 0xC1,
+ 0xCB, 0xC6, 0xCC, 0xDC, 0xD9, 0xDD, 0xDA, 0xD8, 0xDE,
+ 0xBB, 0xAB, 0xC1, 0xC7, 0xBD, 0xE2, 0x02, 0x03, 0x02
+};
+
+static const unsigned char gamma_300cd_82[] = {
+ 0x01, 0x00, 0x01, 0x00, 0x01, 0x00,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x02, 0x03, 0x02
+};
+
+static const unsigned char *gamma_300cd_list[GAMMA_300CD_MAX] = {
+ gamma_300cd_80,
+ gamma_300cd_81,
+ gamma_300cd_82,
+ gamma_300cd_82,
+};
+
+static const unsigned char gamma_id_list[GAMMA_300CD_MAX] = {
+ 0x80, 0x81, 0x82, 0xA2
+};
+
+static s16 s9_to_s16(s16 v)
+{
+ return (s16)(v << 7) >> 7;
+}
+
+static u32 calc_vt_volt(s16 gamma, int rgb_index, u32 adjust_volt[CI_MAX][AD_IVMAX])
+{
+ u32 ret = 0;
+
+ ret = volt_table_vt[gamma] >> 16;
+
+ return ret;
+}
+
+static u32 calc_v3_volt(s16 gamma, int rgb_index, u32 adjust_volt[CI_MAX][AD_IVMAX])
+{
+ /* for CV : 64, DV :320 */
+ int ret = 0;
+ u32 v0 = VREG_OUT_1000, v11;
+ u32 ratio = 0;
+
+ /*vt = adjust_volt[rgb_index][AD_IVT];*/
+ v11 = adjust_volt[rgb_index][AD_IV11];
+ ratio = volt_table_cv_64_dv_320[gamma];
+
+ ret = (v0 << 16) - ((v0-v11)*ratio);
+ ret = ret >> 16;
+
+ return ret;
+}
+
+static u32 calc_v11_volt(s16 gamma, int rgb_index, u32 adjust_volt[CI_MAX][AD_IVMAX])
+{
+ /* for CV : 64, DV :320*/
+ int ret = 0;
+ u32 vt, v23;
+ u32 ratio = 0;
+
+ vt = adjust_volt[rgb_index][AD_IVT];
+ v23 = adjust_volt[rgb_index][AD_IV23];
+ ratio = volt_table_cv_64_dv_320[gamma];
+
+ ret = (vt << 16) - ((vt-v23)*ratio);
+ ret = ret >> 16;
+
+ return ret;
+}
+
+static u32 calc_v23_volt(s16 gamma, int rgb_index, u32 adjust_volt[CI_MAX][AD_IVMAX])
+{
+ /* for CV : 64, DV :319 */
+ int ret = 0;
+ u32 vt, v35;
+ u32 ratio = 0;
+
+ vt = adjust_volt[rgb_index][AD_IVT];
+ v35 = adjust_volt[rgb_index][AD_IV35];
+ ratio = volt_table_cv_64_dv_320[gamma];
+
+ ret = (vt << 16) - ((vt-v35)*ratio);
+ ret = ret >> 16;
+
+ return ret;
+}
+
+static u32 calc_v35_volt(s16 gamma, int rgb_index, u32 adjust_volt[CI_MAX][AD_IVMAX])
+{
+ /* for CV : 65, DV :319 */
+ int ret = 0;
+ u32 vt, v51;
+ u32 ratio = 0;
+
+ vt = adjust_volt[rgb_index][AD_IVT];
+ v51 = adjust_volt[rgb_index][AD_IV51];
+ ratio = volt_table_cv_64_dv_320[gamma];
+
+ ret = (vt << 16) - ((vt-v51)*ratio);
+ ret = ret >> 16;
+
+ return ret;
+}
+
+static u32 calc_v51_volt(s16 gamma, int rgb_index, u32 adjust_volt[CI_MAX][AD_IVMAX])
+{
+ /* for CV : 65, DV :319 */
+ int ret = 0;
+ u32 vt, v87;
+ u32 ratio = 0;
+
+ vt = adjust_volt[rgb_index][AD_IVT];
+ v87 = adjust_volt[rgb_index][AD_IV87];
+ ratio = volt_table_cv_64_dv_320[gamma];
+
+ ret = (vt << 16) - ((vt-v87)*ratio);
+ ret = ret >> 16;
+
+ return ret;
+
+}
+
+static u32 calc_v87_volt(s16 gamma, int rgb_index, u32 adjust_volt[CI_MAX][AD_IVMAX])
+{
+ /* for CV : 64, DV :319 */
+ int ret = 0;
+ u32 vt, v151;
+ u32 ratio = 0;
+
+ vt = adjust_volt[rgb_index][AD_IVT];
+ v151 = adjust_volt[rgb_index][AD_IV151];
+ ratio = volt_table_cv_64_dv_320[gamma];
+
+ ret = (vt << 16) - ((vt-v151)*ratio);
+ ret = ret >> 16;
+
+ return ret;
+}
+
+static u32 calc_v151_volt(s16 gamma, int rgb_index, u32 adjust_volt[CI_MAX][AD_IVMAX])
+{
+ /* for CV : 64, DV :319 */
+ int ret = 0;
+ u32 vt, v203;
+ u32 ratio = 0;
+
+ vt = adjust_volt[rgb_index][AD_IVT];
+ v203 = adjust_volt[rgb_index][AD_IV203];
+ ratio = volt_table_cv_64_dv_320[gamma];
+
+ ret = (vt << 16) - ((vt-v203)*ratio);
+ ret = ret >> 16;
+
+ return ret;
+}
+
+static u32 calc_v203_volt(s16 gamma, int rgb_index, u32 adjust_volt[CI_MAX][AD_IVMAX])
+{
+ /* for CV : 64, DV :319 */
+ int ret = 0;
+ u32 vt, v255;
+ u32 ratio = 0;
+
+ vt = adjust_volt[rgb_index][AD_IVT];
+ v255 = adjust_volt[rgb_index][AD_IV255];
+ ratio = volt_table_cv_64_dv_320[gamma];
+
+ ret = (vt << 16) - ((vt-v255)*ratio);
+ ret = ret >> 16;
+
+ return ret;
+}
+
+static u32 calc_v255_volt(s16 gamma, int rgb_index, u32 adjust_volt[CI_MAX][AD_IVMAX])
+{
+ u32 ret = 0;
+
+ ret = volt_table_v255[gamma] >> 16;
+
+ return ret;
+}
+
+u8 calc_voltage_table(struct str_smart_dim *smart, const u8 *mtp)
+{
+ int c, i, j;
+#if defined(MTP_REVERSE)
+ int offset1 = 0;
+#endif
+ int offset = 0;
+ s16 t1, t2;
+ s16 adjust_mtp[CI_MAX][IV_MAX];
+ u8 range_index;
+ u8 table_index = 0;
+ u32 v1, v2;
+ u32 ratio;
+ u32(*calc_volt[IV_MAX])(s16 gamma, int rgb_index, u32 adjust_volt[CI_MAX][AD_IVMAX]) = {
+ calc_vt_volt,
+ calc_v3_volt,
+ calc_v11_volt,
+ calc_v23_volt,
+ calc_v35_volt,
+ calc_v51_volt,
+ calc_v87_volt,
+ calc_v151_volt,
+ calc_v203_volt,
+ calc_v255_volt,
+ };
+ u8 calc_seq[9] = { IV_VT, IV_203, IV_151, IV_87, IV_51, IV_35, IV_23, IV_11, IV_3};
+ u8 ad_seq[9] = {AD_IVT, AD_IV203, AD_IV151, AD_IV87, AD_IV51, AD_IV35, AD_IV23, AD_IV11, AD_IV3};
+
+ memset(adjust_mtp, 0, sizeof(adjust_mtp));
+
+ for (c = CI_RED; c < CI_MAX; c++) {
+ offset = c*2;
+ if (mtp[offset] & 0x01)
+ t1 = mtp[offset + 1] * -1;
+ else
+ t1 = mtp[offset + 1];
+ t2 = (smart->default_gamma[offset]<<8|smart->default_gamma[offset+1]) + t1;
+ smart->mtp[c][IV_255] = t1;
+ adjust_mtp[c][IV_255] = t2;
+ smart->adjust_volt[c][AD_IV255] = calc_volt[IV_255](t2, c, smart->adjust_volt);
+ /* for V0 All RGB Voltage Value is Reference Voltage */
+ smart->adjust_volt[c][AD_IVT] = VREG_OUT_1000;
+ }
+
+ for (i = IV_VT; i < IV_255; i++) {
+ for (c = CI_RED; c < CI_MAX; c++) {
+ if (i < IV_3) {
+ t1 = 0;
+ t2 = smart->default_gamma[CI_MAX*(10-calc_seq[i])+c] + t1;
+ smart->mtp[c][calc_seq[i]] = t1;
+ adjust_mtp[c][calc_seq[i]] = t2;
+ smart->adjust_volt[c][ad_seq[i]] = calc_volt[calc_seq[i]](t2, c, smart->adjust_volt);
+ } else {
+ if (mtp[CI_MAX*(10-calc_seq[i])+c] & 0x80)
+ t1 = (mtp[CI_MAX*(10-calc_seq[i])+c] & 0x7f) * (-1);
+ else
+ t1 = (mtp[CI_MAX*(10-calc_seq[i])+c] & 0x7f);
+ t2 = smart->default_gamma[CI_MAX*(10-calc_seq[i])+c] + t1;
+ smart->mtp[c][calc_seq[i]] = t1;
+ adjust_mtp[c][calc_seq[i]] = t2;
+ smart->adjust_volt[c][ad_seq[i]] = calc_volt[calc_seq[i]](t2, c, smart->adjust_volt);
+ }
+ }
+ }
+
+ for (i = AD_IVT; i < AD_IVMAX; i++) {
+ for (c = CI_RED; c < CI_MAX; c++) {
+ if (i == 0)
+ smart->ve[table_index].v[c] = VREG_OUT_1000;
+ else
+ smart->ve[table_index].v[c] = smart->adjust_volt[c][i];
+ }
+ range_index = 0;
+
+ for (j = table_index+1; j < table_index+range_table_count[i]; j++) {
+ for (c = CI_RED; c < CI_MAX; c++) {
+ if (smart->t_info[i].offset_table != NULL)
+ ratio = smart->t_info[i].offset_table[range_index] * smart->t_info[i].rv;
+ else
+ ratio = (range_table_count[i]-(range_index+1)) * smart->t_info[i].rv;
+
+ v1 = smart->adjust_volt[c][i+1] << 15;
+ v2 = (smart->adjust_volt[c][i] - smart->adjust_volt[c][i+1])*ratio;
+ smart->ve[j].v[c] = ((v1+v2) >> 15);
+ }
+ range_index++;
+ }
+ table_index = j;
+ }
+
+ for (i = 1; i < 3; i++) {
+ for (c = CI_RED; c < CI_MAX; c++)
+ smart->ve[i].v[c] = smart->ve[3].v[c]+((smart->ve[0].v[c]-smart->ve[3].v[c])*(3-i)/3);
+ }
+
+#if 0
+ printk(KERN_INFO "++++++++++++++++++++++++++++++ MTP VALUE ++++++++++++++++++++++++++++++\n");
+ for (i = IV_VT; i < IV_MAX; i++) {
+ printk("V Level : %d - ", i);
+ for (c = CI_RED; c < CI_MAX; c++)
+ printk("%c : 0x%08x(%04d)", color_name[c], smart->mtp[c][i], smart->mtp[c][i]);
+ printk("\n");
+ }
+
+ printk(KERN_INFO "\n\n++++++++++++++++++++++++++++++ ADJUST VALUE ++++++++++++++++++++++++++++++\n");
+ for (i = IV_VT; i < IV_MAX; i++) {
+ printk("V Level : %d - ", i);
+ for (c = CI_RED; c < CI_MAX; c++)
+ printk("%c : 0x%08x(%04d)", color_name[c], adjust_mtp[c][i], adjust_mtp[c][i]);
+ printk("\n");
+ }
+
+ printk(KERN_INFO "\n\n++++++++++++++++++++++++++++++ ADJUST VOLTAGE ++++++++++++++++++++++++++++++\n");
+ for (i = AD_IVT; i < AD_IVMAX; i++) {
+ printk("V Level : %d - ", i);
+ for (c = CI_RED; c < CI_MAX; c++)
+ printk("%c : %04dV", color_name[c], smart->adjust_volt[c][i]);
+ printk("\n");
+ }
+
+ printk(KERN_INFO "\n\n++++++++++++++++++++++++++++++++++++++ VOLTAGE TABLE ++++++++++++++++++++++++++++++++++++++\n");
+ for (i = 0; i < 256; i++) {
+ printk("Gray Level : %03d - ", i);
+ for (c = CI_RED; c < CI_MAX; c++)
+ printk("%c : %04dV", color_name[c], smart->ve[i].v[c]);
+ printk("\n");
+ }
+#endif
+ return 0;
+}
+
+
+int init_table_info(struct str_smart_dim *smart)
+{
+ int i;
+ int offset = 0;
+
+ for (i = 0; i < IV_TABLE_MAX; i++) {
+ smart->t_info[i].count = (u8)range_table_count[i];
+ smart->t_info[i].offset_table = offset_table[i];
+ smart->t_info[i].rv = table_radio[i];
+ offset += range_table_count[i];
+ }
+
+ smart->flooktbl = flookup_table;
+ smart->g300_gra_tbl = gamma_300_gra_table;
+ smart->gamma_table[G_21] = GAMMA_CONTROL_TABLE[G_21];
+ smart->gamma_table[G_213] = GAMMA_CONTROL_TABLE[G_213];
+ smart->gamma_table[G_215] = GAMMA_CONTROL_TABLE[G_215];
+ smart->gamma_table[G_218] = GAMMA_CONTROL_TABLE[G_218];
+ smart->gamma_table[G_22] = GAMMA_CONTROL_TABLE[G_22];
+ smart->gamma_table[G_221] = GAMMA_CONTROL_TABLE[G_221];
+ smart->gamma_table[G_222] = GAMMA_CONTROL_TABLE[G_222];
+ smart->gamma_table[G_223] = GAMMA_CONTROL_TABLE[G_223];
+ smart->gamma_table[G_224] = GAMMA_CONTROL_TABLE[G_224];
+ smart->gamma_table[G_225] = GAMMA_CONTROL_TABLE[G_225];
+
+ for (i = 0; i < GAMMA_300CD_MAX; i++) {
+ if (smart->panelid[2] == gamma_id_list[i])
+ break;
+ }
+
+ if (i >= GAMMA_300CD_MAX) {
+ printk(KERN_ERR "[SMART DIMMING-WARNING] %s Can't found default gamma table\n", __func__);
+ smart->default_gamma = gamma_300cd_list[GAMMA_300CD_MAX-1];
+ } else
+ smart->default_gamma = gamma_300cd_list[i];
+
+ return 0;
+}
+
+static u32 lookup_vtbl_idx(struct str_smart_dim *smart, u32 gamma)
+{
+ u32 lookup_index;
+ u16 table_count, table_index;
+ u32 gap, i;
+ u32 minimum = smart->g300_gra_tbl[255];
+ u32 candidate = 0;
+ u32 offset = 0;
+
+ lookup_index = (gamma/VALUE_DIM_1000)+1;
+ if (lookup_index > MAX_GRADATION) {
+ /*printk(KERN_ERR "ERROR Wrong input value LOOKUP INDEX : %d\n", lookup_index);*/
+ return 0;
+ }
+
+ if (smart->flooktbl[lookup_index].count) {
+ if (smart->flooktbl[lookup_index-1].count) {
+ table_index = smart->flooktbl[lookup_index-1].entry;
+ table_count = smart->flooktbl[lookup_index].count + smart->flooktbl[lookup_index-1].count;
+ } else {
+ table_index = smart->flooktbl[lookup_index].entry;
+ table_count = smart->flooktbl[lookup_index].count;
+ }
+ } else {
+ offset += 1;
+ while (!(smart->flooktbl[lookup_index+offset].count || smart->flooktbl[lookup_index-offset].count))
+ offset++;
+
+ if (smart->flooktbl[lookup_index-offset].count)
+ table_index = smart->flooktbl[lookup_index-offset].entry;
+ else
+ table_index = smart->flooktbl[lookup_index+offset].entry;
+
+ table_count = smart->flooktbl[lookup_index+offset].count + smart->flooktbl[lookup_index-offset].count;
+ }
+
+ for (i = 0; i < table_count; i++) {
+ if (gamma > smart->g300_gra_tbl[table_index])
+ gap = gamma - smart->g300_gra_tbl[table_index];
+ else
+ gap = smart->g300_gra_tbl[table_index] - gamma;
+
+ if (gap == 0) {
+ candidate = table_index;
+ break;
+ }
+
+ if (gap < minimum) {
+ minimum = gap;
+ candidate = table_index;
+ }
+ table_index++;
+ }
+
+#if 0
+ printk(KERN_INFO "cal : found index : %d\n", candidate);
+ printk(KERN_INFO "gamma : %d, found index : %d found gamma : %d\n",
+ gamma, candidate, smart->g300_gra_tbl[candidate]);
+#endif
+ return candidate;
+}
+
+static u32 calc_vt_reg(int ci, u32 dv[CI_MAX][IV_MAX], u32 adjust_volt[CI_MAX][AD_IVMAX])
+{
+ return 0;
+}
+
+static u32 calc_v3_reg(int ci, u32 dv[CI_MAX][IV_MAX], u32 adjust_volt[CI_MAX][AD_IVMAX])
+{
+ u32 t1, t2;
+ u32 v0 = VREG_OUT_1000, v3, v11;
+ u32 ret;
+
+ /*v0 = dv[ci][IV_0];*/
+ v3 = dv[ci][IV_3];
+ v11 = dv[ci][IV_11];
+
+ t1 = (v0 - v3) << 10;
+ t2 = (v0 - v11) ? (v0 - v11) : (v0) ? v0 : 1;
+ ret = (320 * (t1/t2)) - (64 << 10);
+ ret >>= 10;
+
+ return ret;
+}
+
+static u32 calc_v11_reg(int ci, u32 dv[CI_MAX][IV_MAX], u32 adjust_volt[CI_MAX][AD_IVMAX])
+{
+ u32 t1, t2;
+ u32 vt, v11, v23;
+ u32 ret;
+
+ vt = adjust_volt[ci][AD_IVT];
+ v11 = dv[ci][IV_11];
+ v23 = dv[ci][IV_23];
+ t1 = (vt - v11) << 10;
+ t2 = (vt - v23) ? (vt - v23) : (vt) ? vt : 1;
+ ret = (320 * (t1/t2)) - (64 << 10);
+ ret >>= 10;
+
+ return ret;
+}
+
+static u32 calc_v23_reg(int ci, u32 dv[CI_MAX][IV_MAX], u32 adjust_volt[CI_MAX][AD_IVMAX])
+{
+ u32 t1, t2;
+ u32 vt, v23, v35;
+ u32 ret;
+
+ /*vt = dv[ci][IV_VT];*/
+ vt = adjust_volt[ci][AD_IVT];
+ v23 = dv[ci][IV_23];
+ v35 = dv[ci][IV_35];
+
+ t1 = (vt - v23) << 10;
+ t2 = (vt - v35) ? (vt - v35) : (vt) ? vt : 1;
+ ret = (320 * (t1/t2)) - (64 << 10);
+ ret >>= 10;
+
+ return ret;
+}
+
+static u32 calc_v35_reg(int ci, u32 dv[CI_MAX][IV_MAX], u32 adjust_volt[CI_MAX][AD_IVMAX])
+{
+ u32 t1, t2;
+ u32 vt, v35, v51;
+ u32 ret;
+
+ /*vt = dv[ci][IV_VT];*/
+ vt = adjust_volt[ci][AD_IVT];
+ v35 = dv[ci][IV_35];
+ v51 = dv[ci][IV_51];
+
+ t1 = (vt - v35) << 10;
+ t2 = (vt - v51) ? (vt - v51) : (vt) ? vt : 1;
+ ret = (320 * (t1/t2)) - (64 << 10);
+ ret >>= 10;
+
+ return ret;
+}
+
+static u32 calc_v51_reg(int ci, u32 dv[CI_MAX][IV_MAX], u32 adjust_volt[CI_MAX][AD_IVMAX])
+{
+ u32 t1, t2;
+ u32 vt, v51, v87;
+ u32 ret;
+
+ /*vt = dv[ci][IV_VT];*/
+ vt = adjust_volt[ci][AD_IVT];
+ v51 = dv[ci][IV_51];
+ v87 = dv[ci][IV_87];
+
+ t1 = (vt - v51) << 10;
+ t2 = (vt - v87) ? (vt - v87) : (vt) ? vt : 1;
+ ret = (320 * (t1/t2)) - (64 << 10);
+ ret >>= 10;
+
+ return ret;
+}
+
+
+static u32 calc_v87_reg(int ci, u32 dv[CI_MAX][IV_MAX], u32 adjust_volt[CI_MAX][AD_IVMAX])
+{
+ u32 t1, t2;
+ u32 vt, v87, v151;
+ u32 ret;
+
+ /*vt = dv[ci][IV_VT];*/
+ vt = adjust_volt[ci][AD_IVT];
+ v87 = dv[ci][IV_87];
+ v151 = dv[ci][IV_151];
+
+ t1 = (vt - v87) << 10;
+ t2 = (vt - v151) ? (vt - v151) : (vt) ? vt : 1;
+ ret = (320 * (t1/t2)) - (64 << 10);
+ ret >>= 10;
+
+ return ret;
+}
+
+static u32 calc_v151_reg(int ci, u32 dv[CI_MAX][IV_MAX], u32 adjust_volt[CI_MAX][AD_IVMAX])
+{
+ u32 t1, t2;
+ u32 vt, v151, v203;
+ u32 ret;
+
+ /*vt = dv[ci][IV_VT];*/
+ vt = adjust_volt[ci][AD_IVT];
+ v151 = dv[ci][IV_151];
+ v203 = dv[ci][IV_203];
+
+ t1 = (vt - v151) << 10;
+ t2 = (vt - v203) ? (vt - v203) : (vt) ? vt : 1;
+ ret = (320 * (t1/t2)) - (65 << 10);
+ ret >>= 10;
+
+ return ret;
+}
+
+static u32 calc_v203_reg(int ci, u32 dv[CI_MAX][IV_MAX], u32 adjust_volt[CI_MAX][AD_IVMAX])
+{
+ u32 t1, t2;
+ u32 vt, v151, v255;
+ u32 ret;
+
+ /*vt = dv[ci][IV_VT];*/
+ vt = adjust_volt[ci][IV_VT];
+ v151 = dv[ci][IV_203];
+ v255 = dv[ci][IV_255];
+
+ t1 = (vt - v151) << 10;
+ t2 = (vt - v255) ? (vt - v255) : (vt) ? vt : 1;
+ ret = (320 * (t1/t2)) - (64 << 10);
+ ret >>= 10;
+
+ return ret;
+}
+
+static u32 calc_v255_reg(int ci, u32 dv[CI_MAX][IV_MAX], u32 adjust_volt[CI_MAX][AD_IVMAX])
+{
+ u32 ret;
+ u32 v255;
+ v255 = dv[ci][IV_255];
+
+ ret = (788 * 1000) - (141 * v255);
+ ret = ret / 1000;
+
+ return ret;
+}
+
+u32 calc_gamma_table(struct str_smart_dim *smart, u32 gv, u8 result[], u8 gamma_curve, const u8 *mtp)
+{
+ u32 i, c, t1;
+ u32 temp;
+ u32 lidx;
+ u32 dv[CI_MAX][IV_MAX];
+ s16 gamma[CI_MAX][IV_MAX];
+ u16 offset;
+ u32(*calc_reg[IV_MAX])(int ci, u32 dv[CI_MAX][IV_MAX], u32 adjust_volt[CI_MAX][AD_IVMAX]) = {
+ calc_vt_reg,
+ calc_v3_reg,
+ calc_v11_reg,
+ calc_v23_reg,
+ calc_v35_reg,
+ calc_v51_reg,
+ calc_v87_reg,
+ calc_v151_reg,
+ calc_v203_reg,
+ calc_v255_reg,
+ };
+
+memset(gamma, 0, sizeof(gamma));
+
+#if 0
+ for (c = CI_RED; c < CI_MAX; c++)
+ dv[c][IV_VT] = smart->ve[AD_IVT].v[c]; /* not use V1 calculate value*/
+#endif
+
+ for (i = IV_3 ; i < IV_MAX; i++) {
+ temp = (smart->gamma_table[gamma_curve][dv_value[i]] * gv) / 1000;
+ lidx = lookup_vtbl_idx(smart, temp);
+ for (c = CI_RED; c < CI_MAX; c++)
+ dv[c][i] = smart->ve[lidx].v[c];
+ }
+
+ for (c = CI_RED; c < CI_MAX; c++) {
+ offset = c*2;
+ if (mtp[offset] & 0x01)
+ t1 = mtp[offset + 1] * -1;
+ else
+ t1 = mtp[offset + 1];
+
+ smart->mtp[c][IV_255] = t1;
+ }
+
+ for (i = 1; i < 10; i++) {
+ for (c = CI_RED; c < CI_MAX; c++) {
+ if (mtp[CI_MAX*(i + 1)+c] & 0x80)
+ t1 = (mtp[CI_MAX*(i + 1)+c] & 0x7f) * (-1);
+ else
+ t1 = (mtp[CI_MAX*(i + 1)+c] & 0x7f);
+
+ smart->mtp[c][IV_255 - i] = t1;
+ }
+ }
+
+ /* for IV_1 does not calculate value */
+ /* Do not use gamma value (IV_1) */
+#if 0
+ for (c = CI_RED; c < CI_MAX; c++)
+ gamma[c][IV_VT] = smart->default_gamma[c];
+#endif
+
+ for (i = IV_3; i < IV_MAX; i++) {
+ for (c = CI_RED; c < CI_MAX; c++)
+ gamma[c][i] = (s16)calc_reg[i](c, dv, smart->adjust_volt) - smart->mtp[c][i];
+ }
+
+ for (c = CI_RED; c < CI_MAX; c++) {
+ offset = IV_255*CI_MAX+c*2;
+ result[offset+1] = gamma[c][IV_255] & 0xff;
+ result[offset] = (u8)((gamma[c][IV_255] >> 8) & 0xff);
+ }
+
+ for (c = CI_RED; c < CI_MAX; c++) {
+ for (i = IV_VT; i < IV_255; i++)
+ result[(CI_MAX*i)+c] = gamma[c][i];
+ }
+
+#if 0
+ printk(KERN_INFO "\n\n++++++++++++++++++++++++++++++ FOUND VOLTAGE ++++++++++++++++++++++++++++++\n");
+ for (i = IV_3; i < IV_MAX; i++) {
+ printk("V Level : %d - ", i);
+ for (c = CI_RED; c < CI_MAX; c++)
+ printk("%c : %04dV", color_name[c], dv[c][i]);
+ printk("\n");
+ }
+
+printk(KERN_INFO "\n\n++++++++++++++++++++++++++++++ FOUND REG ++++++++++++++++++++++++++++++\n");
+ for (i = IV_3; i < IV_MAX; i++) {
+ printk("V Level : %d - ", i);
+ for (c = CI_RED; c < CI_MAX; c++)
+ printk("%c : %3d, 0x%2x", color_name[c], gamma[c][i], gamma[c][i]);
+ printk("\n");
+ }
+#endif
+return 0;
+}
+
+u32 calc_gamma_table_215_190(struct str_smart_dim *smart, u32 gv, u8 result[], u8 gamma_curve, const u8 *mtp)
+{
+ u32 i, c, t1;
+ u32 temp;
+ u32 lidx_215_190;
+ u32 dv[CI_MAX][IV_MAX];
+ s16 gamma_215_190[CI_MAX][IV_MAX];
+ u16 offset;
+ u32(*calc_reg[IV_MAX])(int ci, u32 dv[CI_MAX][IV_MAX], u32 adjust_volt[CI_MAX][AD_IVMAX]) = {
+ calc_vt_reg,
+ calc_v3_reg,
+ calc_v11_reg,
+ calc_v23_reg,
+ calc_v35_reg,
+ calc_v51_reg,
+ calc_v87_reg,
+ calc_v151_reg,
+ calc_v203_reg,
+ calc_v255_reg,
+ };
+ memset(gamma_215_190, 0, sizeof(gamma_215_190));
+
+#if 0
+ for (c = CI_RED; c < CI_MAX; c++)
+ dv[c][IV_1] = smart->ve[AD_IV1].v[c];
+#endif
+
+ for (i = IV_3; i < IV_MAX; i++) {
+ if (i == IV_151) {
+ temp = (smart->gamma_table[gamma_curve][dv_value[i]] * gv)/1000;
+ lidx_215_190 = lookup_vtbl_idx(smart, temp)-1;
+ } else if ((i == IV_203) || (i == IV_255)) {
+ temp = (smart->gamma_table[gamma_curve][dv_value[i]] * gv)/1000;
+ lidx_215_190 = lookup_vtbl_idx(smart, temp)-2;
+ } else {
+ temp = (smart->gamma_table[gamma_curve][dv_value[i]] * gv)/1000;
+ lidx_215_190 = lookup_vtbl_idx(smart, temp);
+ }
+
+ for (c = CI_RED; c < CI_MAX; c++)
+ dv[c][i] = smart->ve[lidx_215_190].v[c];
+ }
+
+ for (c = CI_RED; c < CI_MAX; c++) {
+ offset = c*2;
+ if (mtp[offset] & 0x01)
+ t1 = mtp[offset + 1] * -1;
+ else
+ t1 = mtp[offset + 1];
+
+ smart->mtp[c][IV_255] = t1;
+ }
+
+ for (i = 1; i < 10; i++) {
+ for (c = CI_RED; c < CI_MAX; c++) {
+ if (mtp[CI_MAX*(i + 1)+c] & 0x80)
+ t1 = (mtp[CI_MAX*(i + 1)+c] & 0x7f) * (-1);
+ else
+ t1 = (mtp[CI_MAX*(i + 1)+c] & 0x7f);
+
+ smart->mtp[c][IV_255 - i] = t1;
+ }
+ }
+
+ /* for IV1 does not calculate value */
+ /* just use default gamma value (IV1) */
+#if 0
+ for (c = CI_RED; c < CI_MAX; c++)
+ gamma_215_190[c][IV_VT] = smart->default_gamma[c];
+#endif
+
+ for (i = IV_3; i < IV_MAX; i++) {
+ for (c = CI_RED; c < CI_MAX; c++)
+ gamma_215_190[c][i] = (s16)calc_reg[i](c, dv, smart->adjust_volt) - smart->mtp[c][i];
+ }
+
+ for (c = CI_RED; c < CI_MAX; c++) {
+ offset = IV_255*CI_MAX+c*2;
+ result[offset+1] = gamma_215_190[c][IV_255] & 0xff;
+ result[offset] = (u8)((gamma_215_190[c][IV_255] >> 8) & 0xff);
+ }
+
+ for (c = CI_RED; c < CI_MAX; c++) {
+ for (i = IV_VT; i < IV_255; i++)
+ result[(CI_MAX*i)+c] = gamma_215_190[c][i];
+ }
+
+#if 0
+ printk(KERN_INFO "\n\n++++++++++++++++++++++++++++++ FOUND VOLTAGE ++++++++++++++++++++++++++++++\n");
+ for (i = IV_3; i < IV_MAX; i++) {
+ printk("V Level : %d - ", i);
+ for (c = CI_RED; c < CI_MAX; c++)
+ printk("%c : %04dV", color_name[c], dv[c][i]);
+ printk("\n");
+ }
+
+ printk(KERN_INFO "\n\n++++++++++++++++++++++++++++++ FOUND REG ++++++++++++++++++++++++++++++\n");
+ for (i = IV_3; i < IV_MAX; i++) {
+ printk("V Level : %d - ", i);
+ for (c = CI_RED; c < CI_MAX; c++)
+ printk("2.15Gamma %c : %3d, 0x%2x", color_name[c], gamma_215_190[c][i], gamma_215_190[c][i]);
+ printk("\n");
+ }
+#endif
+ return 0;
+}
+
+u32 calc_gamma_table_210_20_100(struct str_smart_dim *smart, u32 gv, u8 result[], u8 gamma_curve, const u8 *mtp)
+{
+ u32 i, c, t1;
+ u32 temp;
+ u32 lidx_210_110;
+ u32 dv[CI_MAX][IV_MAX];
+ s16 gamma_210_110[CI_MAX][IV_MAX];
+ u16 offset;
+ u32(*calc_reg[IV_MAX])(int ci, u32 dv[CI_MAX][IV_MAX], u32 adjust_volt[CI_MAX][AD_IVMAX]) = {
+ calc_vt_reg,
+ calc_v3_reg,
+ calc_v11_reg,
+ calc_v23_reg,
+ calc_v35_reg,
+ calc_v51_reg,
+ calc_v87_reg,
+ calc_v151_reg,
+ calc_v203_reg,
+ calc_v255_reg,
+ };
+ memset(gamma_210_110, 0, sizeof(gamma_210_110));
+
+#if 0
+ for (c = CI_RED; c < CI_MAX; c++)
+ dv[c][IV_1] = smart->ve[AD_IV1].v[c];
+#endif
+
+ for (i = IV_3; i < IV_MAX; i++) {
+ if (i == IV_11) {
+ temp = (smart->gamma_table[gamma_curve][dv_value[i]] * gv)/1000;
+ lidx_210_110 = lookup_vtbl_idx(smart, temp)-1;
+ } else {
+ temp = (smart->gamma_table[gamma_curve][dv_value[i]] * gv)/1000;
+ lidx_210_110 = lookup_vtbl_idx(smart, temp);
+ }
+
+ for (c = CI_RED; c < CI_MAX; c++)
+ dv[c][i] = smart->ve[lidx_210_110].v[c];
+ }
+
+ for (c = CI_RED; c < CI_MAX; c++) {
+ offset = c*2;
+ if (mtp[offset] & 0x01)
+ t1 = mtp[offset + 1] * -1;
+ else
+ t1 = mtp[offset + 1];
+
+ smart->mtp[c][IV_255] = t1;
+ }
+
+ for (i = 1; i < 10; i++) {
+ for (c = CI_RED; c < CI_MAX; c++) {
+ if (mtp[CI_MAX*(i + 1)+c] & 0x80)
+ t1 = (mtp[CI_MAX*(i + 1)+c] & 0x7f) * (-1);
+ else
+ t1 = (mtp[CI_MAX*(i + 1)+c] & 0x7f);
+
+ smart->mtp[c][IV_255 - i] = t1;
+ }
+ }
+
+ /* for IV1 does not calculate value */
+ /* just use default gamma value (IV1) */
+#if 0
+ for (c = CI_RED; c < CI_MAX; c++)
+ gamma_210_110[c][IV_VT] = smart->default_gamma[c];
+#endif
+
+ for (i = IV_3; i < IV_MAX; i++) {
+ for (c = CI_RED; c < CI_MAX; c++)
+ gamma_210_110[c][i] = (s16)calc_reg[i](c, dv, smart->adjust_volt) - smart->mtp[c][i];
+ }
+
+ for (c = CI_RED; c < CI_MAX; c++) {
+ offset = IV_255*CI_MAX+c*2;
+ result[offset+1] = gamma_210_110[c][IV_255] & 0xff;
+ result[offset] = (u8)((gamma_210_110[c][IV_255] >> 8) & 0xff);
+ }
+
+ for (c = CI_RED; c < CI_MAX; c++) {
+ for (i = IV_VT; i < IV_255; i++)
+ result[(CI_MAX*i)+c] = gamma_210_110[c][i];
+ }
+
+#if 0
+ printk(KERN_INFO "\n\n++++++++++++++++++++++++++++++ FOUND VOLTAGE ++++++++++++++++++++++++++++++\n");
+ for (i = IV_VT; i < IV_MAX; i++) {
+ printk("V Level : %d - ", i);
+ for (c = CI_RED; c < CI_MAX; c++)
+ printk("%c : %04dV", color_name[c], dv[c][i]);
+ printk("\n");
+ }
+
+ printk(KERN_INFO "\n\n++++++++++++++++++++++++++++++ FOUND REG ++++++++++++++++++++++++++++++\n");
+ for (i = IV_VT; i < IV_MAX; i++) {
+ printk("V Level : %d - ", i);
+ for (c = CI_RED; c < CI_MAX; c++)
+ printk("2.15Gamma %c : %3d, 0x%2x", color_name[c], gamma_210_110[c][i], gamma_210_110[c][i]);
+ printk("\n");
+ }
+#endif
+ return 0;
+}
diff --git a/drivers/video/samsung/smart_dimming_s6evr02.h b/drivers/video/samsung/smart_dimming_s6evr02.h
new file mode 100644
index 0000000..28fd3c0
--- /dev/null
+++ b/drivers/video/samsung/smart_dimming_s6evr02.h
@@ -0,0 +1,133 @@
+/* linux/drivers/video/samsung/smartdimming.h
+ *
+ * Copyright (c) 2010 Samsung Electronics Co., Ltd.
+ * http://www.samsung.com
+
+ * Samsung Smart Dimming for OCTA
+ *
+ * Minwoo Kim, <minwoo7945.kim@samsung.com>
+ *
+*/
+
+
+#ifndef __SMART_DIMMING_H__
+#define __SMART_DIMMING_H__
+
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/mutex.h>
+#include <linux/wait.h>
+#include <linux/ctype.h>
+
+#define MAX_GRADATION 300
+#define PANEL_ID_MAX 3
+#define GAMMA_300CD_MAX 4
+
+
+enum {
+ CI_RED = 0,
+ CI_GREEN = 1,
+ CI_BLUE = 2,
+ CI_MAX = 3,
+};
+
+
+enum {
+ IV_VT ,
+ IV_3 ,
+ IV_11 ,
+ IV_23 ,
+ IV_35 ,
+ IV_51,
+ IV_87 ,
+ IV_151,
+ IV_203,
+ IV_255,
+ IV_MAX,
+ IV_TABLE_MAX,
+};
+
+
+enum {
+ AD_IVT,
+ AD_IV3,
+ AD_IV11,
+ AD_IV23 ,
+ AD_IV35,
+ AD_IV51 ,
+ AD_IV87 ,
+ AD_IV151 ,
+ AD_IV203 ,
+ AD_IV255 ,
+ AD_IVMAX ,
+};
+
+
+enum {
+ G_21,
+ G_213,
+ G_215,
+ G_218,
+ G_22,
+ G_221,
+ G_222,
+ G_223,
+ G_224,
+ G_225,
+ G_MAX,
+};
+
+
+struct str_voltage_entry {
+ u32 v[CI_MAX];
+};
+
+
+struct str_table_info {
+ /* et : start gray value */
+ u8 st;
+ /* end gray value, st + count */
+ u8 et;
+ u8 count;
+ const u8 *offset_table;
+ /* rv : ratio value */
+ u32 rv;
+};
+
+
+struct str_flookup_table {
+ u16 entry;
+ u16 count;
+};
+
+
+struct str_smart_dim {
+ u8 panelid[PANEL_ID_MAX];
+ s16 mtp[CI_MAX][IV_MAX];
+ struct str_voltage_entry ve[256];
+ const u8 *default_gamma;
+ struct str_table_info t_info[IV_TABLE_MAX];
+ const struct str_flookup_table *flooktbl;
+ const u32 *g22_tbl;
+ const u32 *gamma_table[G_MAX];
+ const u32 *g300_gra_tbl;
+ u32 adjust_volt[CI_MAX][AD_IVMAX];
+};
+
+struct rgb_offset_info {
+ unsigned int candela_idx;
+ unsigned int gray;
+ unsigned int rgb;
+ int offset;
+};
+
+
+int init_table_info(struct str_smart_dim *smart);
+u8 calc_voltage_table(struct str_smart_dim *smart, const u8 *mtp);
+u32 calc_gamma_table(struct str_smart_dim *smart, u32 gv, u8 result[], u8 gamma_curve, const u8 *mtp);
+u32 calc_gamma_table_215_190(struct str_smart_dim *smart, u32 gv, u8 result[], u8 gamma_curve, const u8 *mtp);
+u32 calc_gamma_table_210_20_100(struct str_smart_dim *smart, u32 gv, u8 result[], u8 gamma_curve, const u8 *mtp);
+
+#endif
diff --git a/include/linux/fb.h b/include/linux/fb.h
index 8eff91e..15f6d10 100644
--- a/include/linux/fb.h
+++ b/include/linux/fb.h
@@ -1001,6 +1001,7 @@ extern ssize_t fb_sys_write(struct fb_info *info, const char __user *buf,
/* drivers/video/fbmem.c */
extern int register_framebuffer(struct fb_info *fb_info);
extern int unregister_framebuffer(struct fb_info *fb_info);
+extern int unlink_framebuffer(struct fb_info *fb_info);
extern void remove_conflicting_framebuffers(struct apertures_struct *a,
const char *name, bool primary);
extern int fb_prepare_logo(struct fb_info *fb_info, int rotate);
diff --git a/include/linux/sw_sync.h b/include/linux/sw_sync.h
new file mode 100644
index 0000000..bd6f208
--- /dev/null
+++ b/include/linux/sw_sync.h
@@ -0,0 +1,58 @@
+/*
+ * include/linux/sw_sync.h
+ *
+ * Copyright (C) 2012 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef _LINUX_SW_SYNC_H
+#define _LINUX_SW_SYNC_H
+
+#include <linux/types.h>
+
+#ifdef __KERNEL__
+
+#include <linux/sync.h>
+
+struct sw_sync_timeline {
+ struct sync_timeline obj;
+
+ u32 value;
+};
+
+struct sw_sync_pt {
+ struct sync_pt pt;
+
+ u32 value;
+};
+
+struct sw_sync_timeline *sw_sync_timeline_create(const char *name);
+void sw_sync_timeline_inc(struct sw_sync_timeline *obj, u32 inc);
+
+struct sync_pt *sw_sync_pt_create(struct sw_sync_timeline *obj, u32 value);
+
+#endif /* __KERNEL __ */
+
+struct sw_sync_create_fence_data {
+ __u32 value;
+ char name[32];
+ __s32 fence; /* fd of new fence */
+};
+
+#define SW_SYNC_IOC_MAGIC 'W'
+
+#define SW_SYNC_IOC_CREATE_FENCE _IOWR(SW_SYNC_IOC_MAGIC, 0,\
+ struct sw_sync_create_fence_data)
+#define SW_SYNC_IOC_INC _IOW(SW_SYNC_IOC_MAGIC, 1, __u32)
+
+
+#endif /* _LINUX_SW_SYNC_H */
diff --git a/include/linux/sync.h b/include/linux/sync.h
new file mode 100644
index 0000000..4f19938
--- /dev/null
+++ b/include/linux/sync.h
@@ -0,0 +1,390 @@
+/*
+ * include/linux/sync.h
+ *
+ * Copyright (C) 2012 Google, Inc.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef _LINUX_SYNC_H
+#define _LINUX_SYNC_H
+
+#include <linux/types.h>
+#ifdef __KERNEL__
+
+#include <linux/ktime.h>
+#include <linux/list.h>
+#include <linux/spinlock.h>
+#include <linux/wait.h>
+
+struct sync_timeline;
+struct sync_pt;
+struct sync_fence;
+
+/**
+ * struct sync_timeline_ops - sync object implementation ops
+ * @driver_name: name of the implentation
+ * @dup: duplicate a sync_pt
+ * @has_signaled: returns:
+ * 1 if pt has signaled
+ * 0 if pt has not signaled
+ * <0 on error
+ * @compare: returns:
+ * 1 if b will signal before a
+ * 0 if a and b will signal at the same time
+ * -1 if a will signabl before b
+ * @free_pt: called before sync_pt is freed
+ * @release_obj: called before sync_timeline is freed
+ * @print_obj: print aditional debug information about sync_timeline.
+ * should not print a newline
+ * @print_pt: print aditional debug information about sync_pt.
+ * should not print a newline
+ * @fill_driver_data: write implmentation specific driver data to data.
+ * should return an error if there is not enough room
+ * as specified by size. This information is returned
+ * to userspace by SYNC_IOC_FENCE_INFO.
+ */
+struct sync_timeline_ops {
+ const char *driver_name;
+
+ /* required */
+ struct sync_pt *(*dup)(struct sync_pt *pt);
+
+ /* required */
+ int (*has_signaled)(struct sync_pt *pt);
+
+ /* required */
+ int (*compare)(struct sync_pt *a, struct sync_pt *b);
+
+ /* optional */
+ void (*free_pt)(struct sync_pt *sync_pt);
+
+ /* optional */
+ void (*release_obj)(struct sync_timeline *sync_timeline);
+
+ /* optional */
+ void (*print_obj)(struct seq_file *s,
+ struct sync_timeline *sync_timeline);
+
+ /* optional */
+ void (*print_pt)(struct seq_file *s, struct sync_pt *sync_pt);
+
+ /* optional */
+ int (*fill_driver_data)(struct sync_pt *syncpt, void *data, int size);
+};
+
+/**
+ * struct sync_timeline - sync object
+ * @ops: ops that define the implementaiton of the sync_timeline
+ * @name: name of the sync_timeline. Useful for debugging
+ * @destoryed: set when sync_timeline is destroyed
+ * @child_list_head: list of children sync_pts for this sync_timeline
+ * @child_list_lock: lock protecting @child_list_head, destroyed, and
+ * sync_pt.status
+ * @active_list_head: list of active (unsignaled/errored) sync_pts
+ * @sync_timeline_list: membership in global sync_timeline_list
+ */
+struct sync_timeline {
+ const struct sync_timeline_ops *ops;
+ char name[32];
+
+ /* protected by child_list_lock */
+ bool destroyed;
+
+ struct list_head child_list_head;
+ spinlock_t child_list_lock;
+
+ struct list_head active_list_head;
+ spinlock_t active_list_lock;
+
+ struct list_head sync_timeline_list;
+};
+
+/**
+ * struct sync_pt - sync point
+ * @parent: sync_timeline to which this sync_pt belongs
+ * @child_list: membership in sync_timeline.child_list_head
+ * @active_list: membership in sync_timeline.active_list_head
+ * @fence: sync_fence to which the sync_pt belongs
+ * @pt_list: membership in sync_fence.pt_list_head
+ * @status: 1: signaled, 0:active, <0: error
+ * @timestamp: time which sync_pt status transitioned from active to
+ * singaled or error.
+ */
+struct sync_pt {
+ struct sync_timeline *parent;
+ struct list_head child_list;
+
+ struct list_head active_list;
+
+ struct sync_fence *fence;
+ struct list_head pt_list;
+
+ /* protected by parent->active_list_lock */
+ int status;
+
+ ktime_t timestamp;
+};
+
+/**
+ * struct sync_fence - sync fence
+ * @file: file representing this fence
+ * @name: name of sync_fence. Useful for debugging
+ * @pt_list_head: list of sync_pts in ths fence. immutable once fence
+ * is created
+ * @waiter_list_head: list of asynchronous waiters on this fence
+ * @waiter_list_lock: lock protecting @waiter_list_head and @status
+ * @status: 1: signaled, 0:active, <0: error
+ *
+ * @wq: wait queue for fence signaling
+ * @sync_fence_list: membership in global fence list
+ */
+struct sync_fence {
+ struct file *file;
+ char name[32];
+
+ /* this list is immutable once the fence is created */
+ struct list_head pt_list_head;
+
+ struct list_head waiter_list_head;
+ spinlock_t waiter_list_lock; /* also protects status */
+ int status;
+
+ wait_queue_head_t wq;
+
+ struct list_head sync_fence_list;
+};
+
+/**
+ * struct sync_fence_waiter - metadata for asynchronous waiter on a fence
+ * @waiter_list: membership in sync_fence.waiter_list_head
+ * @callback: function pointer to call when fence signals
+ * @callback_data: pointer to pass to @callback
+ */
+struct sync_fence_waiter {
+ struct list_head waiter_list;
+
+ void (*callback)(struct sync_fence *fence, void *data);
+ void *callback_data;
+};
+
+/*
+ * API for sync_timeline implementers
+ */
+
+/**
+ * sync_timeline_create() - creates a sync object
+ * @ops: specifies the implemention ops for the object
+ * @size: size to allocate for this obj
+ * @name: sync_timeline name
+ *
+ * Creates a new sync_timeline which will use the implemetation specified by
+ * @ops. @size bytes will be allocated allowing for implemntation specific
+ * data to be kept after the generic sync_timeline stuct.
+ */
+struct sync_timeline *sync_timeline_create(const struct sync_timeline_ops *ops,
+ int size, const char *name);
+
+/**
+ * sync_timeline_destory() - destorys a sync object
+ * @obj: sync_timeline to destroy
+ *
+ * A sync implemntation should call this when the @obj is going away
+ * (i.e. module unload.) @obj won't actually be freed until all its childern
+ * sync_pts are freed.
+ */
+void sync_timeline_destroy(struct sync_timeline *obj);
+
+/**
+ * sync_timeline_signal() - signal a status change on a sync_timeline
+ * @obj: sync_timeline to signal
+ *
+ * A sync implemntation should call this any time one of it's sync_pts
+ * has signaled or has an error condition.
+ */
+void sync_timeline_signal(struct sync_timeline *obj);
+
+/**
+ * sync_pt_create() - creates a sync pt
+ * @parent: sync_pt's parent sync_timeline
+ * @size: size to allocate for this pt
+ *
+ * Creates a new sync_pt as a chiled of @parent. @size bytes will be
+ * allocated allowing for implemntation specific data to be kept after
+ * the generic sync_timeline struct.
+ */
+struct sync_pt *sync_pt_create(struct sync_timeline *parent, int size);
+
+/**
+ * sync_pt_free() - frees a sync pt
+ * @pt: sync_pt to free
+ *
+ * This should only be called on sync_pts which have been created but
+ * not added to a fence.
+ */
+void sync_pt_free(struct sync_pt *pt);
+
+/**
+ * sync_fence_create() - creates a sync fence
+ * @name: name of fence to create
+ * @pt: sync_pt to add to the fence
+ *
+ * Creates a fence containg @pt. Once this is called, the fence takes
+ * ownership of @pt.
+ */
+struct sync_fence *sync_fence_create(const char *name, struct sync_pt *pt);
+
+/*
+ * API for sync_fence consumers
+ */
+
+/**
+ * sync_fence_merge() - merge two fences
+ * @name: name of new fence
+ * @a: fence a
+ * @b: fence b
+ *
+ * Creates a new fence which contains copies of all the sync_pts in both
+ * @a and @b. @a and @b remain valid, independent fences.
+ */
+struct sync_fence *sync_fence_merge(const char *name,
+ struct sync_fence *a, struct sync_fence *b);
+
+/**
+ * sync_fence_fdget() - get a fence from an fd
+ * @fd: fd referencing a fence
+ *
+ * Ensures @fd references a valid fence, increments the refcount of the backing
+ * file, and returns the fence.
+ */
+struct sync_fence *sync_fence_fdget(int fd);
+
+/**
+ * sync_fence_put() - puts a refernnce of a sync fence
+ * @fence: fence to put
+ *
+ * Puts a reference on @fence. If this is the last reference, the fence and
+ * all it's sync_pts will be freed
+ */
+void sync_fence_put(struct sync_fence *fence);
+
+/**
+ * sync_fence_install() - installs a fence into a file descriptor
+ * @fence: fence to instal
+ * @fd: file descriptor in which to install the fence
+ *
+ * Installs @fence into @fd. @fd's should be acquired through get_unused_fd().
+ */
+void sync_fence_install(struct sync_fence *fence, int fd);
+
+/**
+ * sync_fence_wait_async() - registers and async wait on the fence
+ * @fence: fence to wait on
+ * @callback: callback
+ * @callback_data data to pass to the callback
+ *
+ * Returns 1 if @fence has already signaled.
+ *
+ * Registers a callback to be called when @fence signals or has an error
+ */
+int sync_fence_wait_async(struct sync_fence *fence,
+ void (*callback)(struct sync_fence *, void *data),
+ void *callback_data);
+
+/**
+ * sync_fence_wait() - wait on fence
+ * @fence: fence to wait on
+ * @tiemout: timeout in ms
+ *
+ * Wait for @fence to be signaled or have an error. Waits indefintly
+ * if @timeout = 0
+ */
+int sync_fence_wait(struct sync_fence *fence, long timeout);
+
+#endif /* __KERNEL__ */
+
+/**
+ * struct sync_merge_data - data passed to merge ioctl
+ * @fd2: file descriptor of second fence
+ * @name: name of new fence
+ * @fence: returns the fd of the new fence to userspace
+ */
+struct sync_merge_data {
+ __s32 fd2; /* fd of second fence */
+ char name[32]; /* name of new fence */
+ __s32 fence; /* fd on newly created fence */
+};
+
+/**
+ * struct sync_pt_info - detailed sync_pt information
+ * @len: length of sync_pt_info including any driver_data
+ * @obj_name: name of parent sync_timeline
+ * @driver_name: name of driver implmenting the parent
+ * @status: status of the sync_pt 0:active 1:signaled <0:error
+ * @timestamp_ns: timestamp of status change in nanoseconds
+ * @driver_data: any driver dependant data
+ */
+struct sync_pt_info {
+ __u32 len;
+ char obj_name[32];
+ char driver_name[32];
+ __s32 status;
+ __u64 timestamp_ns;
+
+ __u8 driver_data[0];
+};
+
+/**
+ * struct sync_fence_info_data - data returned from fence info ioctl
+ * @len: ioctl caller writes the size of the buffer its passing in.
+ * ioctl returns length of sync_fence_data reutnred to userspace
+ * including pt_info.
+ * @name: name of fence
+ * @status: status of fence. 1: signaled 0:active <0:error
+ * @pt_info: a sync_pt_info struct for every sync_pt in the fence
+ */
+struct sync_fence_info_data {
+ __u32 len;
+ char name[32];
+ __s32 status;
+
+ __u8 pt_info[0];
+};
+
+#define SYNC_IOC_MAGIC '>'
+
+/**
+ * DOC: SYNC_IOC_WAIT - wait for a fence to signal
+ *
+ * pass timeout in milliseconds.
+ */
+#define SYNC_IOC_WAIT _IOW(SYNC_IOC_MAGIC, 0, __u32)
+
+/**
+ * DOC: SYNC_IOC_MERGE - merge two fences
+ *
+ * Takes a struct sync_merge_data. Creates a new fence containing copies of
+ * the sync_pts in both the calling fd and sync_merge_data.fd2. Returns the
+ * new fence's fd in sync_merge_data.fence
+ */
+#define SYNC_IOC_MERGE _IOWR(SYNC_IOC_MAGIC, 1, struct sync_merge_data)
+
+/**
+ * DOC: SYNC_IOC_FENCE_INFO - get detailed information on a fence
+ *
+ * Takes a struct sync_fence_info_data with extra space allocated for pt_info.
+ * Caller should write the size of the buffer into len. On return, len is
+ * updated to reflect the total size of the sync_fence_info_data including
+ * pt_info.
+ *
+ * pt_info is a buffer containing sync_pt_infos for every sync_pt in the fence.
+ * To itterate over the sync_pt_infos, use the sync_pt_info.len field.
+ */
+#define SYNC_IOC_FENCE_INFO _IOWR(SYNC_IOC_MAGIC, 2,\
+ struct sync_fence_info_data)
+
+#endif /* _LINUX_SYNC_H */
diff --git a/include/linux/videodev2_exynos_camera.h b/include/linux/videodev2_exynos_camera.h
index b9967ce..557b5e1 100644
--- a/include/linux/videodev2_exynos_camera.h
+++ b/include/linux/videodev2_exynos_camera.h
@@ -159,12 +159,8 @@ enum cam_vt_mode {
#define V4L2_CID_CAMERA_VGA_BLUR (V4L2_CID_PRIVATE_BASE + 49)
#define V4L2_CID_CAMERA_CAPTURE (V4L2_CID_PRIVATE_BASE + 50)
-#define V4L2_CID_CAMERA_HDR (V4L2_CID_PRIVATE_BASE + 51)
+#define V4L2_CID_CAMERA_HDR (V4L2_CID_PRIVATE_BASE + 51)
#define V4L2_CID_CAMERA_HYBRID (V4L2_CID_PRIVATE_BASE + 52)
-#define V4L2_CID_CAMERA_HYBRID_CAPTURE (V4L2_CID_PRIVATE_BASE + 62)
-#define V4L2_CID_CAMERA_POSTVIEW_CAPTURE (V4L2_CID_PRIVATE_BASE + 67)
-#define V4L2_CID_CAMERA_CAPTURE_MODE (V4L2_CID_PRIVATE_BASE + 68)
-#define V4L2_CID_CAMERA_YUV_CAPTURE (V4L2_CID_PRIVATE_BASE + 69)
#define V4L2_CID_MAIN_SW_DATE_INFO_YEAR (V4L2_CID_PRIVATE_BASE + 54)
#define V4L2_CID_MAIN_SW_DATE_INFO_MONTH (V4L2_CID_PRIVATE_BASE + 55)
@@ -173,9 +169,20 @@ enum cam_vt_mode {
#define V4L2_CID_MAIN_SW_FW_MAJOR_VER (V4L2_CID_PRIVATE_BASE + 58)
#define V4L2_CID_MAIN_SW_PRM_MINOR_VER (V4L2_CID_PRIVATE_BASE + 59)
#define V4L2_CID_MAIN_SW_PRM_MAJOR_VER (V4L2_CID_PRIVATE_BASE + 60)
+#define V4L2_CID_CAMERA_HYBRID_CAPTURE (V4L2_CID_PRIVATE_BASE + 62)
+#define V4L2_CID_CAMERA_FAST_MODE (V4L2_CID_PRIVATE_BASE + 66)
+enum cam_fast_mode {
+ FAST_MODE_SUBSAMPLING_NONE ,
+ FAST_MODE_SUBSAMPLING_HALF ,
+ FAST_MODE_SUBSAMPLING_QUARTER ,
+};
+#define V4L2_CID_CAMERA_POSTVIEW_CAPTURE (V4L2_CID_PRIVATE_BASE + 67)
+#define V4L2_CID_CAMERA_CAPTURE_MODE (V4L2_CID_PRIVATE_BASE + 68)
+#define V4L2_CID_CAMERA_YUV_CAPTURE (V4L2_CID_PRIVATE_BASE + 69)
#define V4L2_CID_FIMC_IS_BASE (V4L2_CTRL_CLASS_CAMERA | 0x1000)
#define V4L2_CID_FIMC_IS_TUNE_BASE (V4L2_CTRL_CLASS_CAMERA | 0x2000)
+#define V4L2_CID_FIMC_IS_ISP_DBG_BASE (V4L2_CTRL_CLASS_CAMERA | 0x3000)
#define V4L2_CID_IS_LOAD_FW (V4L2_CID_FIMC_IS_BASE + 10)
#define V4L2_CID_IS_INIT_PARAM (V4L2_CID_FIMC_IS_BASE + 11)
@@ -203,7 +210,7 @@ enum scenario_mode {
};
/* global */
-#define V4L2_CID_IS_CAMERA_SHOT_MODE_NORMAL (V4L2_CID_FIMC_IS_BASE + 101)
+#define V4L2_CID_IS_CAMERA_SHOT_MODE_NORMAL (V4L2_CID_FIMC_IS_BASE + 400)
/* value : 1 : single shot , >=2 : continuous shot */
#define V4L2_CID_IS_CAMERA_SENSOR_NUM (V4L2_CID_FIMC_IS_BASE + 201)
@@ -686,6 +693,7 @@ enum v4l2_scene_mode {
SCENE_MODE_FIREWORKS,
SCENE_MODE_TEXT,
SCENE_MODE_CANDLE_LIGHT,
+ SCENE_MODE_LOW_LIGHT,
SCENE_MODE_MAX,
};
@@ -747,6 +755,10 @@ enum v4l2_wb_mode {
WHITE_BALANCE_FLUORESCENT_L,
WHITE_BALANCE_CUSTOM,
WHITE_BALANCE_K,
+ WHITE_BALANCE_INCANDESCENT,
+ WHITE_BALANCE_PROHIBITION,
+ WHITE_BALANCE_HORIZON,
+ WHITE_BALANCE_LEDLIGHT,
WHITE_BALANCE_MAX,
};
@@ -770,6 +782,9 @@ enum v4l2_effect_mode {
IMAGE_EFFECT_POINT_RED_YELLOW,
IMAGE_EFFECT_POINT_COLOR_3,
IMAGE_EFFECT_POINT_GREEN,
+ IMAGE_EFFECT_POINT_RED,
+ IMAGE_EFFECT_POINT_YELLOW,
+ IMAGE_EFFECT_CARTOONIZE,
IMAGE_EFFECT_MAX,
};
@@ -782,6 +797,7 @@ enum v4l2_iso_mode {
ISO_400,
ISO_800,
ISO_1600,
+ ISO_3200,
ISO_SPORTS,
ISO_NIGHT,
ISO_MOVIE,
@@ -868,7 +884,9 @@ enum v4l2_vintage_mode {
};
#define V4L2_CID_CAMERA_JPEG_QUALITY (V4L2_CID_PRIVATE_BASE+85)
-/* (V4L2_CID_PRIVATE_BASE+86) */
+#define V4L2_CID_CAMERA_CAPTURE_THUMB (V4L2_CID_PRIVATE_BASE + 86)
+#define V4L2_CID_CAMERA_YUV_SNAPSHOT (V4L2_CID_PRIVATE_BASE + 87)
+#define V4L2_CID_CAMERA_LOW_LIGHT_MODE (V4L2_CID_PRIVATE_BASE + 88)
#define V4L2_CID_CAMERA_GPS_LATITUDE (V4L2_CID_CAMERA_CLASS_BASE+30)
/* (V4L2_CID_PRIVATE_BASE+87) */
#define V4L2_CID_CAMERA_GPS_LONGITUDE (V4L2_CID_CAMERA_CLASS_BASE + 31)
@@ -986,17 +1004,19 @@ enum v4l2_focusmode {
FOCUS_MODE_CONTINOUS_PICTURE_MACRO,
FOCUS_MODE_CONTINOUS_VIDEO,
FOCUS_MODE_TOUCH,
+ FOCUS_MODE_MANUAL,
+ FOCUS_MODE_MULTI,
+ FOCUS_MODE_OBJECT_TRACKING,
FOCUS_MODE_MAX,
FOCUS_MODE_DEFAULT = (1 << 8),
};
#define V4L2_CID_CAMERA_OBJ_TRACKING_STATUS (V4L2_CID_PRIVATE_BASE+100)
enum v4l2_obj_tracking_status {
- OBJECT_TRACKING_STATUS_BASE,
- OBJECT_TRACKING_STATUS_PROGRESSING,
- OBJECT_TRACKING_STATUS_SUCCESS,
- OBJECT_TRACKING_STATUS_FAIL,
- OBJECT_TRACKING_STATUS_MISSING,
+ OBJECT_TRACKING_STATUS_BASE = 0,
+ OBJECT_TRACKING_STATUS_SUCCESS = 1,
+ OBJECT_TRACKING_STATUS_MISSING = 2,
+ OBJECT_TRACKING_STATUS_FAIL = 3,
OBJECT_TRACKING_STATUS_MAX,
};
@@ -1042,7 +1062,8 @@ enum v4l2_anti_banding {
ANTI_BANDING_AUTO = 0,
ANTI_BANDING_50HZ = 1,
ANTI_BANDING_60HZ = 2,
- ANTI_BANDING_OFF = 3,
+ ANTI_BANDING_50_60Hz = 3,
+ ANTI_BANDING_OFF = 4,
};
#define V4L2_CID_CAMERA_SET_GAMMA (V4L2_CID_PRIVATE_BASE+106)
@@ -1167,6 +1188,7 @@ enum v4l2_face_bracket_aeb_value {
#define V4L2_CID_CAMERA_BRACKET_WBB (V4L2_CID_PRIVATE_BASE+136)
enum v4l2_face_bracket_wbb_value {
+ BRACKET_WBB_OFF = 0,
BRACKET_WBB_VALUE1 = 1,
BRACKET_WBB_VALUE2,
BRACKET_WBB_VALUE3,
@@ -1187,21 +1209,56 @@ enum v4l2_drive_dial {
enum v4l2_running_cap_mode {
RUNNING_MODE_SINGLE = 0,
RUNNING_MODE_CONTINUOUS,
- RUNNING_MODE_BRACKET,
+ RUNNING_MODE_BEST,
+ RUNNING_MODE_LOWLIGHT,
+ RUNNING_MODE_AE_BRACKET,
+ RUNNING_MODE_WB_BRACKET,
RUNNING_MODE_HDR,
RUNNING_MODE_BLINK,
+ RUNNING_MODE_RAW,
+ RUNNING_MODE_BURST,
RUNNING_MODE_MAX
};
+enum v4l2_continuous_mode {
+ CONTINUOUS_MODE_OFF = 0,
+ CONTINUOUS_MODE_ON,
+ CONTINUOUS_MODE_MAX,
+};
+
+enum v4l2_continuous_fps {
+ MULTI_CAPTURE_FPS_1 = 0,
+ MULTI_CAPTURE_FPS_10,
+ MULTI_CAPTURE_FPS_5,
+ MULTI_CAPTURE_FPS_3,
+ MULTI_CAPTURE_FPS_MAX,
+};
+
+enum v4l2_burst_mode {
+ BURST_MODE_OFF = 0,
+ BURST_MODE_ON,
+};
+
+enum v4l2_best_mode {
+ BEST_MODE_OFF = 0,
+ BEST_MODE_ON,
+ BEST_MODE_MAX,};
+
+enum v4l2_lowlight_mode {
+ LOWLIGHT_MODE_OFF = 0,
+ LOWLIGHT_MODE_ON,
+ LOWLIGHT_MODE_MAX,};
+
#define V4L2_CID_CAMERA_FD_EYE_BLINK_RESULT (V4L2_CID_PRIVATE_BASE+138)
#define V4L2_CID_CAMERA_OPTICAL_ZOOM_STEP (V4L2_CID_PRIVATE_BASE + 139)
#define V4L2_CID_CAMERA_OPTICAL_ZOOM_CTRL (V4L2_CID_PRIVATE_BASE + 140)
-
enum v4l2_optical_zoom_ctrl {
- V4L2_OPTICAL_ZOOM_TELE,
- V4L2_OPTICAL_ZOOM_WIDE,
V4L2_OPTICAL_ZOOM_STOP,
+ V4L2_OPTICAL_ZOOM_TELE_START,
+ V4L2_OPTICAL_ZOOM_WIDE_START,
+ V4L2_OPTICAL_ZOOM_SLOW_TELE_START,
+ V4L2_OPTICAL_ZOOM_SLOW_WIDE_START,
};
#define V4L2_CID_CAMERA_LDC (V4L2_CID_PRIVATE_BASE+142)
@@ -1216,6 +1273,542 @@ enum set_LSC_mode {
LSC_SET_ON = 1,
};
+#define V4L2_CID_CAMERA_FACTORY_OIS (V4L2_CID_PRIVATE_BASE+147)
+enum set_Factory_OIS {
+ FACTORY_OIS_RETURN_TO_CENTER = 0,
+ FACTORY_OIS_RUN = 1,
+ FACTORY_OIS_START = 2,
+ FACTORY_OIS_STOP = 3,
+ FACTORY_OIS_MODE_ON = 4,
+ FACTORY_OIS_MODE_OFF = 5,
+ FACTORY_OIS_LOG = 6,
+ FACTORY_OIS_ON = 7,
+};
+
+#define V4L2_CID_CAMERA_FACTORY_ZOOM_RANGE_CHECK_DATA_MIN \
+ (V4L2_CID_PRIVATE_BASE+148)
+#define V4L2_CID_CAMERA_FACTORY_ZOOM_RANGE_CHECK_DATA_MAX \
+ (V4L2_CID_PRIVATE_BASE+149)
+#define V4L2_CID_CAMERA_FACTORY_ZOOM_SLOPE_CHECK_DATA_MIN \
+ (V4L2_CID_PRIVATE_BASE+152)
+#define V4L2_CID_CAMERA_FACTORY_ZOOM_SLOPE_CHECK_DATA_MAX \
+ (V4L2_CID_PRIVATE_BASE+153)
+#define V4L2_CID_CAMERA_FACTORY_ZOOM_STEP (V4L2_CID_PRIVATE_BASE+154)
+#define V4L2_CID_CAMERA_FACTORY_ZOOM (V4L2_CID_PRIVATE_BASE+155)
+enum set_Factory_Zoom {
+ FACTORY_ZOOM_MOVE_STEP = 0,
+ FACTORY_ZOOM_RANGE_CHECK_START = 1,
+ FACTORY_ZOOM_RANGE_CHECK_STOP = 2,
+ FACTORY_ZOOM_SLOPE_CHECK_START = 3,
+ FACTORY_ZOOM_SLOPE_CHECK_STOP = 4,
+ FACTORY_ZOOM_SET_RANGE_CHECK_DATA = 5,
+ FACTORY_ZOOM_SET_SLOPE_CHECK_DATA = 6,
+ FACTORY_ZOOM_STEP_TELE = 7,
+ FACTORY_ZOOM_STEP_WIDE = 8,
+ FACTORY_ZOOM_MOVE_END_CHECK = 9,
+};
+
+#define V4L2_CID_CAMERA_FACTORY_PUNT_RANGE_DATA_MIN \
+ (V4L2_CID_PRIVATE_BASE+156)
+#define V4L2_CID_CAMERA_FACTORY_PUNT_RANGE_DATA_MAX \
+ (V4L2_CID_PRIVATE_BASE+157)
+#define V4L2_CID_CAMERA_FACTORY_PUNT_RANGE_DATA_NUM \
+ (V4L2_CID_PRIVATE_BASE+158)
+#define V4L2_CID_CAMERA_FACTORY_PUNT (V4L2_CID_PRIVATE_BASE+159)
+enum set_Factory_Punt {
+ FACTORY_PUNT_RANGE_START = 0,
+ FACTORY_PUNT_RANGE_STOP = 1,
+ FACTORY_PUNT_SHORT_SCAN_DATA = 2,
+ FACTORY_PUNT_SHORT_SCAN_START = 3,
+ FACTORY_PUNT_SHORT_SCAN_STOP = 4,
+ FACTORY_PUNT_LONG_SCAN_DATA = 5,
+ FACTORY_PUNT_LONG_SCAN_START = 6,
+ FACTORY_PUNT_LONG_SCAN_STOP = 7,
+ FACTORY_PUNT_LOG = 8,
+ FACTORY_PUNT_SET_RANGE_DATA = 9,
+ FACTORY_PUNT_EEP_WRITE = 10,
+};
+
+#define V4L2_CID_CAMERA_FACTORY_FAIL_STOP (V4L2_CID_PRIVATE_BASE+160)
+enum set_Factory_Fail_Stop {
+ FACTORY_FAIL_STOP_ON = 0,
+ FACTORY_FAIL_STOP_OFF = 1,
+ FACTORY_FAIL_STOP_RUN = 2,
+ FACTORY_FAIL_STOP_STOP = 3,
+};
+
+#define V4L2_CID_CAMERA_FACTORY_NODEFOCUS (V4L2_CID_PRIVATE_BASE+161)
+enum set_Factory_NoDeFocus {
+ FACTORY_NODEFOCUSYES_ON = 0,
+ FACTORY_NODEFOCUSYES_OFF = 1,
+ FACTORY_NODEFOCUSYES_RUN = 2,
+ FACTORY_NODEFOCUSYES_STOP = 3,
+};
+
+#define V4L2_CID_CAMERA_FACTORY_INTERPOLATION (V4L2_CID_PRIVATE_BASE+162)
+enum set_Factory_Interpolation {
+ FACTORY_INTERPOLATION_USE = 0,
+ FACTORY_INTERPOLATION_RELEASE = 1,
+};
+
+#define V4L2_CID_CAMERA_FACTORY_DOWN_RESULT (V4L2_CID_PRIVATE_BASE+163)
+#define V4L2_CID_CAMERA_FACTORY_END_RESULT (V4L2_CID_PRIVATE_BASE+164)
+#define V4L2_CID_CAMERA_FACTORY_COMMON (V4L2_CID_PRIVATE_BASE+165)
+enum set_Factory_Common {
+ FACTORY_FIRMWARE_DOWNLOAD = 0,
+ FACTORY_DOWNLOAD_CHECK = 1,
+ FACTORY_END_CHECK = 2,
+ FACTORY_COMMON_SET_FOCUS_ZONE_MACRO = 3,
+ FACTORY_FPS30_ON = 4,
+ FACTORY_FPS30_OFF = 5,
+};
+
+#define V4L2_CID_CAMERA_FACTORY_VIB (V4L2_CID_PRIVATE_BASE+166)
+enum set_Factory_Vib {
+ FACTORY_VIB_START = 0,
+ FACTORY_VIB_STOP = 1,
+ FACTORY_VIB_LOG = 2,
+};
+
+#define V4L2_CID_CAMERA_FACTORY_GYRO (V4L2_CID_PRIVATE_BASE+167)
+enum set_Factory_Gyro {
+ FACTORY_GYRO_START = 0,
+ FACTORY_GYRO_STOP = 1,
+ FACTORY_GYRO_LOG = 2,
+};
+
+#define V4L2_CID_CAMERA_FACTORY_BACKLASH (V4L2_CID_PRIVATE_BASE+168)
+enum set_Factory_Backlash {
+ FACTORY_BACKLASH_INPUT = 0,
+ FACTORY_BACKLASH_MAX_THR = 1,
+ FACTORY_BACKLASH_WIDE_RUN = 2,
+ FACTORY_BACKLASH_LOG = 3,
+};
+
+#define V4L2_CID_CAMERA_FACTORY_AF_STEP_SET (V4L2_CID_PRIVATE_BASE+169)
+#define V4L2_CID_CAMERA_FACTORY_AF_POSITION (V4L2_CID_PRIVATE_BASE+170)
+#define V4L2_CID_CAMERA_FACTORY_AF_INT_RESULT (V4L2_CID_PRIVATE_BASE+171)
+#define V4L2_CID_CAMERA_FACTORY_AF (V4L2_CID_PRIVATE_BASE+172)
+enum set_Factory_AF {
+ FACTORY_AF_LOCK_ON_SET = 0,
+ FACTORY_AF_LOCK_OFF_SET = 1,
+ FACTORY_AF_MOVE = 2,
+ FACTORY_AF_STEP_LOG = 3,
+ FACTORY_AF_LOCK_START = 4,
+ FACTORY_AF_LOCK_STOP = 5,
+ FACTORY_AF_FOCUS_LOG = 6,
+ FACTORY_AF_INT_SET = 7,
+ FACTORY_AF_SCAN_LIMIT_START = 8,
+ FACTORY_AF_SCAN_LIMIT_STOP = 10,
+ FACTORY_AF_SCAN_RANGE_START = 11,
+ FACTORY_AF_SCAN_RANGE_STOP = 12,
+ FACTORY_AF_STEP_SAVE = 13,
+ FACTORY_AF_LED_END_CHECK = 14,
+ FACTORY_AF_LED_LOG = 15,
+ FACTORY_AF_MOVE_END_CHECK = 16,
+ FACTORY_AF_SCAN_END_CHECK = 17,
+};
+
+#define V4L2_CID_CAMERA_FACTORY_DEFOCUS_WIDE (V4L2_CID_PRIVATE_BASE+173)
+#define V4L2_CID_CAMERA_FACTORY_DEFOCUS_TELE (V4L2_CID_PRIVATE_BASE+174)
+#define V4L2_CID_CAMERA_FACTORY_DEFOCUS (V4L2_CID_PRIVATE_BASE+175)
+enum set_Factory_DeFocus {
+ FACTORY_DEFOCUS_RUN = 0,
+ FACTORY_DEFOCUS_STOP = 1,
+};
+
+#define V4L2_CID_CAMERA_FACTORY_RESOL_CAP (V4L2_CID_PRIVATE_BASE+176)
+enum set_Factory_Resol_Cap {
+ FACTORY_CAP_COMP_ON = 0,
+ FACTORY_CAP_COMP_OFF = 1,
+ FACTORY_CAP_BARREL_ON = 2,
+ FACTORY_CAP_BARREL_OFF = 3,
+ FACTORY_CAP_BARREL_START = 4,
+ FACTORY_CAP_BARREL_STOP = 5,
+ FACTORY_CAP_COMP_START = 6,
+ FACTORY_CAP_COMP_STOP = 7,
+};
+
+#define V4L2_CID_CAMERA_SET_G_VALUE (V4L2_CID_PRIVATE_BASE + 177)
+#define V4L2_CID_CAMERA_SET_B_VALUE (V4L2_CID_PRIVATE_BASE + 178)
+#define V4L2_CID_CAMERA_SET_A_VALUE (V4L2_CID_PRIVATE_BASE + 179)
+#define V4L2_CID_CAMERA_SET_M_VALUE (V4L2_CID_PRIVATE_BASE + 180)
+#define V4L2_CID_CAMERA_SET_GBAM (V4L2_CID_PRIVATE_BASE + 181)
+#define V4L2_CID_CAMERA_SET_K_VALUE (V4L2_CID_PRIVATE_BASE + 182)
+#define V4L2_CID_CAMERA_SET_FLASH_EVC_STEP (V4L2_CID_PRIVATE_BASE + 183)
+
+#define V4L2_CID_CAMERA_APERTURE_CMD (V4L2_CID_PRIVATE_BASE+184)
+enum set_Factory_Aperture_Cmd {
+ FACTORY_CMD_PREVIEW = 0,
+ FACTORY_CMD_CAPTURE = 1,
+};
+
+#define V4L2_CID_CAMERA_FACTORY_OIS_RANGE_DATA_X_MIN (V4L2_CID_PRIVATE_BASE+185)
+#define V4L2_CID_CAMERA_FACTORY_OIS_RANGE_DATA_X_MAX (V4L2_CID_PRIVATE_BASE+186)
+#define V4L2_CID_CAMERA_FACTORY_OIS_RANGE_DATA_Y_MIN (V4L2_CID_PRIVATE_BASE+187)
+#define V4L2_CID_CAMERA_FACTORY_OIS_RANGE_DATA_Y_MAX (V4L2_CID_PRIVATE_BASE+188)
+#define V4L2_CID_CAMERA_FACTORY_OIS_RANGE_DATA_X_GAIN \
+ (V4L2_CID_PRIVATE_BASE+189)
+#define V4L2_CID_CAMERA_FACTORY_OIS_RANGE_DATA_PEAK_X \
+ (V4L2_CID_PRIVATE_BASE+190)
+#define V4L2_CID_CAMERA_FACTORY_OIS_RANGE_DATA_PEAK_Y \
+ (V4L2_CID_PRIVATE_BASE+191)
+
+#define V4L2_CID_CAMERA_FACTORY_VIB_RANGE_DATA_X_MIN (V4L2_CID_PRIVATE_BASE+192)
+#define V4L2_CID_CAMERA_FACTORY_VIB_RANGE_DATA_X_MAX (V4L2_CID_PRIVATE_BASE+193)
+#define V4L2_CID_CAMERA_FACTORY_VIB_RANGE_DATA_Y_MIN (V4L2_CID_PRIVATE_BASE+194)
+#define V4L2_CID_CAMERA_FACTORY_VIB_RANGE_DATA_Y_MAX (V4L2_CID_PRIVATE_BASE+195)
+#define V4L2_CID_CAMERA_FACTORY_VIB_RANGE_DATA_PEAK_X \
+ (V4L2_CID_PRIVATE_BASE+196)
+#define V4L2_CID_CAMERA_FACTORY_VIB_RANGE_DATA_PEAK_Y \
+ (V4L2_CID_PRIVATE_BASE+197)
+
+#define V4L2_CID_CAMERA_FACTORY_GYRO_RANGE_DATA_X_MIN \
+ (V4L2_CID_PRIVATE_BASE+198)
+#define V4L2_CID_CAMERA_FACTORY_GYRO_RANGE_DATA_X_MAX \
+ (V4L2_CID_PRIVATE_BASE+199)
+#define V4L2_CID_CAMERA_FACTORY_GYRO_RANGE_DATA_Y_MIN \
+ (V4L2_CID_PRIVATE_BASE+200)
+#define V4L2_CID_CAMERA_FACTORY_GYRO_RANGE_DATA_Y_MAX \
+ (V4L2_CID_PRIVATE_BASE+202)
+
+#define V4L2_CID_CAMERA_FACTORY_TEST_NUMBER (V4L2_CID_PRIVATE_BASE+203)
+
+#define V4L2_CID_CAMERA_FACTORY_BACKLASH_COUNT (V4L2_CID_PRIVATE_BASE+204)
+#define V4L2_CID_CAMERA_FACTORY_BACKLASH_MAXTHRESHOLD \
+ (V4L2_CID_PRIVATE_BASE+205)
+
+#define V4L2_CID_CAMERA_FACTORY_CAPTURE_CTRL (V4L2_CID_PRIVATE_BASE + 206)
+enum set_Factory_Cap_Ctrl {
+ FACTORY_STILL_CAP_NORMAL = 0,
+ FACTORY_STILL_CAP_DUALCAP = 1,
+ FACTORY_DUAL_CAP_ON = 2,
+ FACTORY_DUAL_CAP_OFF = 3,
+};
+
+#define V4L2_CID_CAMERA_DUAL_POSTVIEW (V4L2_CID_PRIVATE_BASE + 207)
+#define V4L2_CID_CAMERA_DUAL_CAPTURE (V4L2_CID_PRIVATE_BASE + 208)
+#define V4L2_CID_CAMERA_SET_DUAL_CAPTURE (V4L2_CID_PRIVATE_BASE + 209)
+#define V4L2_CID_CAMERA_DUAL_CAPTURE_MODE (V4L2_CID_PRIVATE_BASE + 210)
+
+#define V4L2_CID_CAMERA_FOCUS_AREA_MODE (V4L2_CID_PRIVATE_BASE + 211)
+enum set_fouce_area {
+ V4L2_FOCUS_AREA_CENTER = 0,
+ V4L2_FOCUS_AREA_MULTI = 1,
+ V4L2_FOCUS_AREA_SMART_TOUCH = 2,
+};
+
+#define V4L2_CID_CAMERA_FACTORY_AF_SCAN_LIMIT_MIN (V4L2_CID_PRIVATE_BASE+212)
+#define V4L2_CID_CAMERA_FACTORY_AF_SCAN_LIMIT_MAX (V4L2_CID_PRIVATE_BASE+213)
+#define V4L2_CID_CAMERA_FACTORY_AF_SCAN_RANGE_MIN (V4L2_CID_PRIVATE_BASE+214)
+#define V4L2_CID_CAMERA_FACTORY_AF_SCAN_RANGE_MAX (V4L2_CID_PRIVATE_BASE+215)
+#define V4L2_CID_CAM_APERTURE_PREVIEW (V4L2_CID_PRIVATE_BASE+216)
+#define V4L2_CID_CAM_APERTURE_CAPTURE (V4L2_CID_PRIVATE_BASE+217)
+
+#define V4L2_CID_CAMERA_FACTORY_AF_ZONE (V4L2_CID_PRIVATE_BASE+218)
+enum set_Factory_AFZone_Cmd {
+ FACTORY_AFZONE_NORMAL = 0,
+ FACTORY_AFZONE_MACRO,
+ FACTORY_AFZONE_AUTO,
+};
+
+#define V4L2_CID_CAMERA_FACTORY_OIS_SHIFT (V4L2_CID_PRIVATE_BASE+219)
+#define V4L2_CID_CAMERA_FACTORY_FLICKER (V4L2_CID_PRIVATE_BASE+220)
+enum set_Factory_Flicker_Cmd {
+ FACTORY_FLICKER_AUTO = 0,
+ FACTORY_FLICKER_50HZ,
+ FACTORY_FLICKER_60HZ,
+ FACTORY_FLICKER_50_60,
+ FACTORY_FLICKER_OFF,
+};
+
+#define V4L2_CID_CAMERA_FACTORY_AF_LENS (V4L2_CID_PRIVATE_BASE+221)
+enum set_Factory_AFLENS_Cmd {
+ FACTORY_AFLENS_OPEN = 0,
+ FACTORY_AFLENS_CLOSE,
+};
+
+#define V4L2_CID_CAMERA_FACTORY_LV_TARGET (V4L2_CID_PRIVATE_BASE+222)
+
+#define V4L2_CID_CAMERA_FACTORY_ADJ_IRIS_RANGE_MIN (V4L2_CID_PRIVATE_BASE+223)
+#define V4L2_CID_CAMERA_FACTORY_ADJ_IRIS_RANGE_MAX (V4L2_CID_PRIVATE_BASE+224)
+#define V4L2_CID_CAMERA_FACTORY_ADJ_IRIS (V4L2_CID_PRIVATE_BASE+225)
+enum set_Factory_Adj_IRIS_Cmd {
+ FACTORY_ADJ_IRIS_RUN = 0,
+ FACTORY_ADJ_IRIS_STOP,
+ FACTORY_ADJ_IRIS_END_CHECK,
+ FACTORY_ADJ_IRIS_LOG,
+};
+
+#define V4L2_CID_CAMERA_FACTORY_ADJ_GAIN_LIVEVIEW_RANGE_MIN \
+ (V4L2_CID_PRIVATE_BASE+226)
+#define V4L2_CID_CAMERA_FACTORY_ADJ_GAIN_LIVEVIEW_RANGE_MAX \
+ (V4L2_CID_PRIVATE_BASE+227)
+#define V4L2_CID_CAMERA_FACTORY_ADJ_GAIN_LIVEVIEW (V4L2_CID_PRIVATE_BASE+228)
+enum set_Factory_Adj_Gain_LiveView_Cmd {
+ FACTORY_ADJ_GAIN_LIVEVIEW_RUN = 0,
+ FACTORY_ADJ_GAIN_LIVEVIEW_STOP,
+ FACTORY_ADJ_GAIN_LIVEVIEW_END_CHECK,
+ FACTORY_ADJ_GAIN_LIVEVIEW_LOG,
+};
+
+#define V4L2_CID_CAMERA_FACTORY_SH_CLOSE_IRIS_NUM (V4L2_CID_PRIVATE_BASE+229)
+#define V4L2_CID_CAMERA_FACTORY_SH_CLOSE_SET_IRIS (V4L2_CID_PRIVATE_BASE+230)
+#define V4L2_CID_CAMERA_FACTORY_SH_CLOSE_ISO (V4L2_CID_PRIVATE_BASE+231)
+#define V4L2_CID_CAMERA_FACTORY_SH_CLOSE_RANGE (V4L2_CID_PRIVATE_BASE+232)
+#define V4L2_CID_CAMERA_FACTORY_SH_CLOSE_SPEEDTIME_X (V4L2_CID_PRIVATE_BASE+233)
+#define V4L2_CID_CAMERA_FACTORY_SH_CLOSE_SPEEDTIME_Y (V4L2_CID_PRIVATE_BASE+234)
+#define V4L2_CID_CAMERA_FACTORY_SH_CLOSE (V4L2_CID_PRIVATE_BASE+235)
+enum set_Factory_SH_Close_Cmd {
+ FACTORY_SH_CLOSE_RUN = 0,
+ FACTORY_SH_CLOSE_STOP,
+ FACTORY_SH_CLOSE_END_CHECK,
+ FACTORY_SH_CLOSE_LOG,
+};
+
+#define V4L2_CID_CAMERA_FACTORY_CAPTURE_GAIN_RANGE_MIN \
+ (V4L2_CID_PRIVATE_BASE+236)
+#define V4L2_CID_CAMERA_FACTORY_CAPTURE_GAIN_RANGE_MAX \
+ (V4L2_CID_PRIVATE_BASE+237)
+#define V4L2_CID_CAMERA_FACTORY_CAPTURE_GAIN (V4L2_CID_PRIVATE_BASE+238)
+enum set_Factory_Capture_Gain_Cmd {
+ FACTORY_CAPTURE_GAIN_RUN = 0,
+ FACTORY_CAPTURE_GAIN_STOP,
+ FACTORY_CAPTURE_GAIN_END_CHECK,
+ FACTORY_CAPTURE_GAIN_LOG,
+};
+
+#define V4L2_CID_CAMERA_FACTORY_LSC_TABLE (V4L2_CID_PRIVATE_BASE+239)
+#define V4L2_CID_CAMERA_FACTORY_LSC_REFERENCE (V4L2_CID_PRIVATE_BASE+240)
+
+#define V4L2_CID_CAMERA_FACTORY_PUNT_SHORT_SCAN_DATA (V4L2_CID_PRIVATE_BASE+241)
+#define V4L2_CID_CAMERA_FACTORY_PUNT_LONG_SCAN_DATA (V4L2_CID_PRIVATE_BASE+242)
+
+#define V4L2_CID_CAMERA_PASM_MODE (V4L2_CID_PRIVATE_BASE + 243)
+enum set_camera_mode_Cmd {
+ MODE_SMART_AUTO = 0,
+ MODE_PROGRAM,
+ MODE_A,
+ MODE_S,
+ MODE_M,
+ MODE_VIDEO,
+ MODE_BACKGROUND_BLUR,
+ MODE_HIGH_SPEED,
+ MODE_LIGHT_TRAIL_SHOT,
+ MODE_WATERFALL,
+ MODE_SILHOUETTE,
+ MODE_SUNSET,
+ MODE_CLOSE_UP,
+ MODE_FIREWORKS,
+ MODE_CROSS_FILTER,
+ MODE_BACKLIGHT,
+ MODE_BLUE_SKY,
+ MODE_NATURAL_GREEN,
+ MODE_BEST_GROUP_POSE,
+ MODE_FOOD,
+ MODE_START_FILTER,
+ MODE_MOVING_SHOT,
+};
+
+#define V4L2_CID_CAMERA_SHUTTER_SPEED (V4L2_CID_PRIVATE_BASE + 244)
+#define V4L2_CID_CAMERA_F_NUMBER (V4L2_CID_PRIVATE_BASE + 245)
+
+#define V4L2_CID_CAMERA_IMAGE_STABILIZER (V4L2_CID_PRIVATE_BASE + 246)
+enum set_Image_Stabilizer {
+ V4L2_IMAGE_STABILIZER_OFF = 0,
+ V4L2_IMAGE_STABILIZER_OIS = 1,
+ V4L2_IMAGE_STABILIZER_DUALIS = 2,
+};
+
+#define V4L2_CID_CAMERA_IS_OIS_MODE (V4L2_CID_PRIVATE_BASE + 247)
+enum set_IS_OIS_mode {
+ V4L2_IS_OIS_NONE = 0,
+ V4L2_IS_OIS_MOVIE = 1,
+ V4L2_IS_OIS_STILL = 2,
+ V4L2_IS_OIS_MULTI = 3,
+ V4L2_IS_OIS_VSS = 4,
+};
+
+#define V4L2_CID_CAMERA_FACTORY_AE_TARGET (V4L2_CID_PRIVATE_BASE + 248)
+
+#define V4L2_CID_CAMERA_AV (V4L2_CID_PRIVATE_BASE + 249)
+#define V4L2_CID_CAMERA_TV (V4L2_CID_PRIVATE_BASE + 250)
+#define V4L2_CID_CAMERA_SV (V4L2_CID_PRIVATE_BASE + 251)
+#define V4L2_CID_CAMERA_EV (V4L2_CID_PRIVATE_BASE + 252)
+
+#define V4L2_CID_CAMERA_SCENE_SUB_MODE (V4L2_CID_PRIVATE_BASE + 253)
+
+#define V4L2_CID_CAMERA_WB_CUSTOM_X (V4L2_CID_PRIVATE_BASE + 254)
+#define V4L2_CID_CAMERA_WB_CUSTOM_Y (V4L2_CID_PRIVATE_BASE + 255)
+#define V4L2_CID_CAMERA_WB_CUSTOM_VALUE (V4L2_CID_PRIVATE_BASE + 256)
+
+#define V4L2_CID_CAMERA_RED_EYE_FIX_RESULT (V4L2_CID_PRIVATE_BASE + 257)
+#define V4L2_CID_CAMERA_FACTORY_FLASH (V4L2_CID_PRIVATE_BASE + 258)
+enum set_Factory_Flash_Cmd {
+ FACTORY_FLASH_STROBE_CHECK_ON = 0,
+ FACTORY_FLASH_STROBE_CHECK_OFF = 1,
+ FACTORY_FLASH_CHARGE = 2,
+ FACTORY_FLASH_LOG = 3,
+ FACTORY_FLASH_CHARGE_END_CHECK = 4,
+ FACTORY_FLASH_STROBE_CHARGE_END_CHECK = 5,
+ FACTORY_FLASH_WB_LOG = 6,
+ FACTORY_ADJ_FLASH_WB_LOG = 7,
+ FACTORY_ADJ_FLASH_WB_END_CHECK = 8,
+};
+
+#define V4L2_CID_CAMERA_FACTORY_WB (V4L2_CID_PRIVATE_BASE + 259)
+enum set_Factory_WB_Cmd {
+ FACTORY_WB_INDOOR_RUN = 0,
+ FACTORY_WB_INDOOR_END_CHECK = 1,
+ FACTORY_WB_OUTDOOR_RUN = 2,
+ FACTORY_WB_OUTDOOR_END_CHECK = 3,
+ FACTORY_WB_LOG = 4,
+};
+
+#define V4L2_CID_CAMERA_FACTORY_FLASH_RANGE_X (V4L2_CID_PRIVATE_BASE + 260)
+#define V4L2_CID_CAMERA_FACTORY_FLASH_RANGE_Y (V4L2_CID_PRIVATE_BASE + 261)
+
+#define V4L2_CID_CAMERA_FACTORY_WB_IN_RG_VALUE (V4L2_CID_PRIVATE_BASE + 262)
+#define V4L2_CID_CAMERA_FACTORY_WB_IN_BG_VALUE (V4L2_CID_PRIVATE_BASE + 263)
+#define V4L2_CID_CAMERA_FACTORY_WB_OUT_RG_VALUE (V4L2_CID_PRIVATE_BASE + 264)
+#define V4L2_CID_CAMERA_FACTORY_WB_OUT_BG_VALUE (V4L2_CID_PRIVATE_BASE + 265)
+
+#define V4L2_CID_CAMERA_FACTORY_AFLED_RANGE_DATA_START_X \
+ (V4L2_CID_PRIVATE_BASE + 266)
+#define V4L2_CID_CAMERA_FACTORY_AFLED_RANGE_DATA_END_X \
+ (V4L2_CID_PRIVATE_BASE + 267)
+#define V4L2_CID_CAMERA_FACTORY_AFLED_RANGE_DATA_START_Y \
+ (V4L2_CID_PRIVATE_BASE + 268)
+#define V4L2_CID_CAMERA_FACTORY_AFLED_RANGE_DATA_END_Y \
+ (V4L2_CID_PRIVATE_BASE + 269)
+
+#define V4L2_CID_CAMERA_FACTORY_AF_LED_TIME (V4L2_CID_PRIVATE_BASE + 270)
+
+#define V4L2_CID_CAMERA_FACTORY_AF_DIFF_CHECK_MIN (V4L2_CID_PRIVATE_BASE + 271)
+#define V4L2_CID_CAMERA_FACTORY_AF_DIFF_CHECK_MAX (V4L2_CID_PRIVATE_BASE + 272)
+
+#define V4L2_CID_CAMERA_FACTORY_DEFECTPIXEL (V4L2_CID_PRIVATE_BASE + 273)
+enum set_Factory_DefectPixel_Cmd {
+ FACTORY_DEFECTPIXEL_SCENARIO_6 = 0,
+ FACTORY_DEFECTPIXEL_RUN,
+ FACTORY_DEFECTPIXEL_END_CHECK,
+ FACTORY_DEFECTPIXEL_LOG,
+ FACTORY_DEFECTPIXEL_CID_1,
+ FACTORY_DEFECTPIXEL_CID_2,
+ FACTORY_DEFECTPIXEL_CID_3,
+ FACTORY_DEFECTPIXEL_WRITE_BLACK,
+ FACTORY_DEFECTPIXEL_WRITE_WHITE,
+ FACTORY_DEFECTPIXEL_CID_WRITE,
+ FACTORY_DEFECTPIXEL_FLASH_MERGE,
+ FACTORY_DEFECTPIXEL_DOT_WRITE_CHECK,
+};
+
+#define V4L2_CID_CAMERA_FACTORY_DFPX_NLV_CAP (V4L2_CID_PRIVATE_BASE + 274)
+#define V4L2_CID_CAMERA_FACTORY_DFPX_NLV_DR0 (V4L2_CID_PRIVATE_BASE + 275)
+#define V4L2_CID_CAMERA_FACTORY_DFPX_NLV_DR1 (V4L2_CID_PRIVATE_BASE + 276)
+#define V4L2_CID_CAMERA_FACTORY_DFPX_NLV_DR2 (V4L2_CID_PRIVATE_BASE + 277)
+#define V4L2_CID_CAMERA_FACTORY_DFPX_NLV_DR_HS (V4L2_CID_PRIVATE_BASE + 278)
+
+#define V4L2_CID_CAMERA_FACTORY_AF_LED_LV_MIN (V4L2_CID_PRIVATE_BASE + 279)
+#define V4L2_CID_CAMERA_FACTORY_AF_LED_LV_MAX (V4L2_CID_PRIVATE_BASE + 280)
+
+#define V4L2_CID_CAMERA_FACTORY_CAM_SYS_MODE (V4L2_CID_PRIVATE_BASE + 281)
+enum set_Factory_Sysmode_Cmd {
+ FACTORY_SYSMODE_CAPTURE = 0,
+ FACTORY_SYSMODE_MONITOR = 1,
+ FACTORY_SYSMODE_PARAM = 2,
+};
+
+#define V4L2_CID_CAMERA_FACTORY_ISP_FW_CHECK (V4L2_CID_PRIVATE_BASE + 282)
+#define V4L2_CID_CAMERA_FACTORY_OIS_VER_CHECK (V4L2_CID_PRIVATE_BASE + 283)
+
+#define V4L2_CID_CAMERA_SMART_SCENE_DETECT (V4L2_CID_PRIVATE_BASE+284)
+enum set_smartscenedetect_mode {
+ SMART_SCENE_DETECT_OFF = 0,
+ SMART_SCENE_DETECT_ON = 1,
+};
+#define V4L2_CID_CAMERA_SMART_MOVIE_RECORDING (V4L2_CID_PRIVATE_BASE+285)
+#define V4L2_CID_CAMERA_SMART_AUTO_S1_PUSH (V4L2_CID_PRIVATE_BASE+286)
+
+#define V4L2_CID_CAMERA_FACTORY_WB_RANGE_FLASH_WRITE \
+ (V4L2_CID_PRIVATE_BASE + 287)
+
+#define V4L2_CID_CAMERA_FACTORY_FLASH_CHR_CHK_TM \
+ (V4L2_CID_PRIVATE_BASE + 288)
+
+#define V4L2_CID_CAMERA_EXIF_AV (V4L2_CID_PRIVATE_BASE + 289)
+#define V4L2_CID_CAMERA_FACE_DETECT_NUMBER (V4L2_CID_PRIVATE_BASE+290)
+#define V4L2_CID_CAMERA_EXIF_FL (V4L2_CID_PRIVATE_BASE + 291)
+
+#define V4L2_CID_CAMERA_SMART_ZOOM (V4L2_CID_PRIVATE_BASE + 292)
+enum set_Smart_Zoom {
+ V4L2_SMART_ZOOM_OFF = 0,
+ V4L2_SMART_ZOOM_ON = 1,
+};
+
+#define V4L2_CID_CAMERA_CAF (V4L2_CID_PRIVATE_BASE + 293)
+
+#define V4L2_CID_CAMERA_FACTORY_LIVEVIEW_OFFSET_MARK \
+ (V4L2_CID_PRIVATE_BASE + 294)
+#define V4L2_CID_CAMERA_FACTORY_LIVEVIEW_OFFSET_VAL \
+ (V4L2_CID_PRIVATE_BASE + 295)
+
+#define V4L2_CID_CAMERA_FACTORY_CAPTURE_GAIN_OFFSET_MARK \
+ (V4L2_CID_PRIVATE_BASE + 296)
+#define V4L2_CID_CAMERA_FACTORY_CAPTURE_GAIN_OFFSET_VAL \
+ (V4L2_CID_PRIVATE_BASE + 297)
+
+#define V4L2_CID_CAMERA_FACTORY_WB_RANGE (V4L2_CID_PRIVATE_BASE + 298)
+
+#define V4L2_CID_CAMERA_LV (V4L2_CID_PRIVATE_BASE + 299)
+
+#define V4L2_CID_PHYSICAL_ROTATION (V4L2_CID_PRIVATE_BASE + 300)
+
+#define V4L2_CID_CAMERA_FOCUS_RANGE (V4L2_CID_PRIVATE_BASE + 301)
+enum set_fouce_range {
+ V4L2_FOCUS_RANGE_AUTO = 0,
+ V4L2_FOCUS_RANGE_MACRO = 1,
+ V4L2_FOCUS_RANGE_AUTO_MACRO = 2,
+};
+
+#define V4L2_CID_CAMERA_TIME_INFO (V4L2_CID_PRIVATE_BASE + 302)
+
+#define V4L2_CID_CAMERA_AF_LED (V4L2_CID_PRIVATE_BASE + 303)
+enum set_AF_LED {
+ V4L2_AF_LED_OFF = 0,
+ V4L2_AF_LED_ON = 1,
+};
+
+#define V4L2_CID_CAMERA_LENS_TIMER (V4L2_CID_PRIVATE_BASE + 304)
+
+#define V4L2_CID_CAMERA_FLASH_BATT_INFO (V4L2_CID_PRIVATE_BASE + 305)
+enum set_FLASH_BATT_INFO {
+ V4L2_FLASH_NORMAL_BATT = 0,
+ V4L2_FLASH_LOW_BATT = 1,
+};
+
+#define V4L2_CID_CAMERA_STREAM_PART2 (V4L2_CID_PRIVATE_BASE + 306)
+
+#define V4L2_CID_CAMERA_WIDGET_MODE_LEVEL (V4L2_CID_PRIVATE_BASE+307)
+enum v4l2_widget_mode_level {
+ V4L2_WIDGET_MODE_LEVEL_1 = 1,
+ V4L2_WIDGET_MODE_LEVEL_2 = 2,
+ V4L2_WIDGET_MODE_LEVEL_3 = 3,
+};
+
+#define V4L2_CID_CAMERA_SMART_READ1 (V4L2_CID_PRIVATE_BASE + 308)
+#define V4L2_CID_CAMERA_SMART_READ2 (V4L2_CID_PRIVATE_BASE + 309)
+
+#define V4L2_CID_CAMERA_PREVIEW_WIDTH (V4L2_CID_PRIVATE_BASE + 310)
+#define V4L2_CID_CAMERA_PREVIEW_HEIGHT (V4L2_CID_PRIVATE_BASE + 311)
+#define V4L2_CID_CAMERA_PREVIEW_SIZE (V4L2_CID_PRIVATE_BASE + 312)
+
+#define V4L2_CID_CAMERA_WARNING_CONDITION (V4L2_CID_PRIVATE_BASE + 313)
+#define V4L2_CID_CAMERA_EXIF_FL_35mm (V4L2_CID_PRIVATE_BASE + 314)
+
+#define V4L2_CID_CAMERA_LENS_STATUS (V4L2_CID_PRIVATE_BASE + 315)
+#define V4L2_CID_CAMERA_HOLD_LENS (V4L2_CID_PRIVATE_BASE + 316)
+
/* Pixel format FOURCC depth Description */
enum v4l2_pix_format_mode {
V4L2_PIX_FMT_MODE_PREVIEW,
@@ -1225,6 +1818,97 @@ enum v4l2_pix_format_mode {
V4L2_PIX_FMT_MODE_VT_NONMIRROR,
};
+#define V4L2_CID_SET_CONTINUE_FPS (V4L2_CID_PRIVATE_BASE + 500)
+#define V4L2_CID_CONTINUESHOT_PROC (V4L2_CID_PRIVATE_BASE + 501)
+enum v4l2_continuecshot_proc_state {
+ V4L2_INT_STATE_FRAME_SYNC = 0,
+ V4L2_INT_STATE_CAPTURE_SYNC,
+ V4L2_INT_STATE_CONTINUE_CANCEL,
+ V4L2_INT_STATE_CONTINUE_END,
+ V4L2_INT_STATE_START_CAPTURE,
+};
+
+#define V4L2_CID_CAMERA_GET_MODE (V4L2_CID_PRIVATE_BASE + 502)
+
+#define V4L2_CID_CAMERA_FACTORY_SEND_SETTING \
+ (V4L2_CID_PRIVATE_BASE + 503)
+#define V4L2_CID_CAMERA_FACTORY_SEND_VALUE \
+ (V4L2_CID_PRIVATE_BASE + 504)
+
+#define V4L2_CID_CAMERA_FACTORY_TILT_SCAN_MIN \
+ (V4L2_CID_PRIVATE_BASE + 505)
+#define V4L2_CID_CAMERA_FACTORY_TILT_SCAN_MAX \
+ (V4L2_CID_PRIVATE_BASE + 506)
+#define V4L2_CID_CAMERA_FACTORY_TILT_FIELD \
+ (V4L2_CID_PRIVATE_BASE + 507)
+#define V4L2_CID_CAMERA_FACTORY_TILT_AF_RANGE_MIN \
+ (V4L2_CID_PRIVATE_BASE + 508)
+#define V4L2_CID_CAMERA_FACTORY_TILT_AF_RANGE_MAX \
+ (V4L2_CID_PRIVATE_BASE + 509)
+#define V4L2_CID_CAMERA_FACTORY_TILT_DIFF_RANGE_MIN \
+ (V4L2_CID_PRIVATE_BASE + 510)
+#define V4L2_CID_CAMERA_FACTORY_TILT_DIFF_RANGE_MAX \
+ (V4L2_CID_PRIVATE_BASE + 511)
+
+#define V4L2_CID_CAMERA_FACTORY_IR_R_GAIN_MIN \
+ (V4L2_CID_PRIVATE_BASE + 512)
+#define V4L2_CID_CAMERA_FACTORY_IR_R_GAIN_MAX \
+ (V4L2_CID_PRIVATE_BASE + 513)
+#define V4L2_CID_CAMERA_FACTORY_IR_B_GAIN_MIN \
+ (V4L2_CID_PRIVATE_BASE + 514)
+#define V4L2_CID_CAMERA_FACTORY_IR_B_GAIN_MAX \
+ (V4L2_CID_PRIVATE_BASE + 515)
+
+#define V4L2_CID_CAMERA_FACTORY_FLASH_MAN_CHARGE \
+ (V4L2_CID_PRIVATE_BASE + 516)
+#define V4L2_CID_CAMERA_FACTORY_FLASH_MAN_EN \
+ (V4L2_CID_PRIVATE_BASE + 517)
+
+#define V4L2_CID_CAMERA_FACTORY_SEND_WORD_VALUE \
+ (V4L2_CID_PRIVATE_BASE + 518)
+#define V4L2_CID_CAMERA_FACTORY_SEND_LONG_VALUE \
+ (V4L2_CID_PRIVATE_BASE + 519)
+
+#define V4L2_CID_CAMERA_FACTORY_DFPX_NLV_DR1_HD \
+ (V4L2_CID_PRIVATE_BASE + 520)
+
+#define V4L2_CID_BURSTSHOT_PROC (V4L2_CID_PRIVATE_BASE + 521)
+enum v4l2_burst_proc_state {
+ V4L2_INT_STATE_BURST_START = 0,
+ V4L2_INT_STATE_BURST_SYNC,
+ V4L2_INT_STATE_BURST_STOP,
+};
+
+#define V4L2_CID_CAMERA_FACTORY_TILT \
+ (V4L2_CID_PRIVATE_BASE + 522)
+enum set_Factory_Tilt {
+ FACTORY_TILT_ONE_SCRIPT_RUN = 0,
+ FACTORY_TILT_ONE_SCRIPT_DISP1,
+ FACTORY_TILT_ONE_SCRIPT_DISP2,
+ FACTORY_TILT_ONE_SCRIPT_DISP3,
+ FACTORY_TILT_ONE_SCRIPT_DISP4,
+ FACTORY_TILT_ONE_SCRIPT_DISP5,
+};
+
+#define V4L2_CID_CAMERA_FACTORY_IR_CHECK \
+ (V4L2_CID_PRIVATE_BASE + 523)
+enum set_Factory_IR_Check {
+ FACTORY_IR_CHECK_LOG = 0,
+};
+
+#define V4L2_CID_BURSTSHOT_SET_POSTVIEW_SIZE (V4L2_CID_PRIVATE_BASE + 524)
+
+#define V4L2_CID_BURSTSHOT_SET_SNAPSHOT_SIZE (V4L2_CID_PRIVATE_BASE + 525)
+
+/* ISP DEBUG CODE */
+#define V4L2_CID_ISP_DEBUG_READ (V4L2_CID_FIMC_IS_ISP_DBG_BASE + 1)
+#define V4L2_CID_ISP_DEBUG_WRITE (V4L2_CID_FIMC_IS_ISP_DBG_BASE + 2)
+#define V4L2_CID_ISP_DEBUG_READ_MEM (V4L2_CID_FIMC_IS_ISP_DBG_BASE + 3)
+#define V4L2_CID_ISP_DEBUG_WRITE_MEM (V4L2_CID_FIMC_IS_ISP_DBG_BASE + 4)
+#define V4L2_CID_ISP_DEBUG_READ_FILE (V4L2_CID_FIMC_IS_ISP_DBG_BASE + 5)
+#define V4L2_CID_ISP_DEBUG_WRITE_FILE (V4L2_CID_FIMC_IS_ISP_DBG_BASE + 6)
+#define V4L2_CID_ISP_DEBUG_LOGV (V4L2_CID_FIMC_IS_ISP_DBG_BASE + 7)
+
/* 12 Y/CbCr 4:2:0 64x32 macroblocks */
#define V4L2_PIX_FMT_NV12T v4l2_fourcc('T', 'V', '1', '2')
#define V4L2_PIX_FMT_NV21T v4l2_fourcc('T', 'V', '2', '1')