Skip to content

Instantly share code, notes, and snippets.

@Ahmed-Hady
Created October 8, 2016 12:01
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Ahmed-Hady/2d1ccd224b99a91a81ca88e9db22dc11 to your computer and use it in GitHub Desktop.
Save Ahmed-Hady/2d1ccd224b99a91a81ca88e9db22dc11 to your computer and use it in GitHub Desktop.
This file has been truncated, but you can view the full file.
From ba12856e9a3a24295a52ec921a723e66695ca3d7 Mon Sep 17 00:00:00 2001
From: Konsta <konsta09@gmail.com>
Date: Tue, 11 Mar 2014 19:06:57 +0200
Subject: [PATCH 1/3] Nokia RM-980 10.0.3
Merge Nokia X source release on top of CAF tag
AU_LINUX_ANDROID_JB_REL_2.0.3.04.01.02.21.114
and few targeted cherry-picks from CAF jb_rel_2.0.3
branch.
---
.../devicetree/bindings/vendor-prefixes.txt | 2 +-
Makefile | 9 +
arch/arm/configs/msm7627a-perf_defconfig | 84 +-
arch/arm/configs/msm7627a_defconfig | 61 +-
arch/arm/configs/normandy_b1_defconfig | 438 ++
arch/arm/configs/normandy_b2_defconfig | 436 ++
arch/arm/configs/normandy_b3_defconfig | 436 ++
arch/arm/configs/normandy_evb1_defconfig | 432 ++
arch/arm/configs/normandy_evb2_defconfig | 432 ++
arch/arm/configs/normandy_lv_defconfig | 432 ++
arch/arm/configs/normandy_mp_defconfig | 432 ++
arch/arm/configs/normandy_s11_defconfig | 434 ++
arch/arm/include/asm/hardware/cache-l2x0.h | 1 +
arch/arm/include/asm/mach/mmc.h | 1 +
arch/arm/include/asm/perf_event.h | 1 +
arch/arm/include/asm/pmu.h | 20 +-
arch/arm/include/asm/smp.h | 1 +
arch/arm/include/asm/thread_info.h | 2 +
arch/arm/include/asm/uaccess.h | 41 +-
arch/arm/kernel/perf_event.c | 40 +-
arch/arm/kernel/perf_event_msm.c | 2 -
arch/arm/kernel/perf_event_msm_krait.c | 49 -
arch/arm/kernel/smp.c | 14 +
arch/arm/kernel/traps.c | 24 +-
arch/arm/kernel/vmlinux.lds.S | 10 +-
arch/arm/mach-msm/Kconfig | 102 +-
arch/arm/mach-msm/Makefile | 18 +-
arch/arm/mach-msm/acpuclock-7627.c | 6 +-
arch/arm/mach-msm/acpuclock-8625q.c | 5 +-
arch/arm/mach-msm/acpuclock-arm11.c | 2 +-
arch/arm/mach-msm/audio-7627a-devices.c | 6 +
arch/arm/mach-msm/board-msm7627a-bt.c | 29 +-
arch/arm/mach-msm/board-msm7627a-camera.c | 1798 +++++-
arch/arm/mach-msm/board-msm7627a-display.c | 462 +-
arch/arm/mach-msm/board-msm7627a-io.c | 755 ++-
arch/arm/mach-msm/board-msm7627a-sensor.c | 624 ++
arch/arm/mach-msm/board-msm7627a-sensor.h | 19 +
arch/arm/mach-msm/board-msm7627a-storage.c | 37 +-
arch/arm/mach-msm/board-msm7627a-wlan.c | 85 +-
arch/arm/mach-msm/board-msm7x27a-regulator.c | 11 +-
arch/arm/mach-msm/board-msm7x27a.c | 134 +-
arch/arm/mach-msm/board-qrd7627a.c | 257 +-
arch/arm/mach-msm/board-qsd8x50.c | 8 +-
arch/arm/mach-msm/cache-ops.h | 73 +
arch/arm/mach-msm/clock-debug.c | 18 +
arch/arm/mach-msm/clock-pcom-lookup.c | 16 +
arch/arm/mach-msm/devices-msm7x27a.c | 145 +-
arch/arm/mach-msm/dma_test.c | 2 +-
arch/arm/mach-msm/enhance-debug.c | 53 +
arch/arm/mach-msm/fastboot.c | 326 +
arch/arm/mach-msm/gpiomux.c | 42 +-
arch/arm/mach-msm/idle.c | 2 +-
arch/arm/mach-msm/include/mach/board.h | 8 +-
arch/arm/mach-msm/include/mach/dma.h | 4 +-
arch/arm/mach-msm/include/mach/irqs-7xxx.h | 2 +-
arch/arm/mach-msm/include/mach/irqs-8625.h | 4 +-
arch/arm/mach-msm/include/mach/irqs-9625.h | 5 +
arch/arm/mach-msm/include/mach/msm_battery.h | 85 +-
arch/arm/mach-msm/include/mach/msm_hsusb.h | 3 +-
arch/arm/mach-msm/include/mach/msm_serial_pdata.h | 5 +-
arch/arm/mach-msm/include/mach/msm_smsm.h | 2 +-
arch/arm/mach-msm/include/mach/oem_rapi_client.h | 25 +-
arch/arm/mach-msm/include/mach/socinfo.h | 7 +
arch/arm/mach-msm/mpm-8625.c | 1 +
arch/arm/mach-msm/msm7k_fiq.c | 7 +-
arch/arm/mach-msm/msm_cpr.c | 48 +-
arch/arm/mach-msm/msm_cpr.h | 2 +-
arch/arm/mach-msm/msm_smem_iface.h | 16 +-
arch/arm/mach-msm/msm_vibrator.c | 63 +-
arch/arm/mach-msm/perf_event_msm_krait_l2.c | 54 +-
arch/arm/mach-msm/perf_event_msm_l2.c | 48 +-
arch/arm/mach-msm/perf_event_msm_pl310.c | 432 ++
arch/arm/mach-msm/pm-boot.c | 2 +-
arch/arm/mach-msm/pm2.c | 31 +
arch/arm/mach-msm/pmu.c | 132 +
arch/arm/mach-msm/proc_comm.c | 67 +
arch/arm/mach-msm/rmt_storage_client.c | 95 +-
arch/arm/mach-msm/rpc_hsusb.c | 12 +-
arch/arm/mach-msm/rpc_server_handset.c | 16 +-
arch/arm/mach-msm/sleep_monitor.c | 160 +
arch/arm/mach-msm/sm_event.c | 136 +
arch/arm/mach-msm/sm_event_driver.c | 450 ++
arch/arm/mach-msm/sm_event_log.c | 759 +++
arch/arm/mach-msm/smd.c | 8 +-
arch/arm/mach-msm/smd_rpcrouter.c | 62 +
arch/arm/mach-msm/smem_log.c | 4 +-
arch/arm/mach-msm/socinfo.c | 97 +-
arch/arm/mach-msm/timer.c | 17 +-
arch/arm/mm/cache-l2x0.c | 2 +-
arch/arm/mm/ioremap.c | 7 +-
arch/arm/mm/mmu.c | 54 +-
arch/arm/tools/mach-types | 7 +-
block/blk-settings.c | 3 +-
block/partition-generic.c | 7 +
drivers/Kconfig | 4 +-
drivers/Makefile | 3 +
drivers/base/cpu.c | 2 +
drivers/base/power/main.c | 5 +
drivers/bluetooth/hci_h4.c | 2 +-
drivers/bluetooth/hci_vhci.c | 2 +-
drivers/char/diag/diagchar_core.c | 6 +
drivers/char/diag/diagfwd.c | 6 +-
drivers/char/mem.c | 13 +
drivers/cpufreq/cpufreq_ondemand.c | 53 +-
drivers/cpufreq/cpufreq_stats.c | 4 +
drivers/hwmon/Kconfig | 16 +
drivers/hwmon/Makefile | 2 +
drivers/hwmon/bma2x2.c | 3347 ++++++++++
drivers/hwmon/ltr559.c | 2635 ++++++++
drivers/i2c/busses/i2c-qup.c | 164 +-
drivers/input/input.c | 8 +-
drivers/input/misc/Kconfig | 49 +
drivers/input/misc/Makefile | 7 +
drivers/input/misc/apds990x.c | 1179 ++++
drivers/input/misc/bma250.c | 933 +++
drivers/input/misc/isl29028.c | 816 +++
drivers/input/misc/lis3dh.c | 703 +++
drivers/input/misc/ltr502.c | 981 +++
drivers/input/misc/ltr558.c | 848 +++
drivers/input/misc/tmd2771x.c | 1119 ++++
drivers/input/touchscreen/Kconfig | 22 +
drivers/input/touchscreen/Makefile | 3 +
drivers/input/touchscreen/atmel_mxt_ts.c | 836 ++-
drivers/input/touchscreen/auo-pixcir-ts.c | 2 +-
drivers/input/touchscreen/focal_touch.c | 1073 ++++
drivers/input/touchscreen/ft5x06_ts.c | 3 +-
drivers/input/touchscreen/ft6306_touch.c | 2673 ++++++++
drivers/input/touchscreen/tp_work_func.c | 159 +
drivers/input/touchscreen/tp_work_func.h | 31 +
drivers/leds/Kconfig | 15 +
drivers/leds/Makefile | 2 +
drivers/leds/leds-pmic-mpp.c | 44 +-
drivers/leds/leds-pmic8029.c | 121 +
drivers/leds/leds-tricolor.c | 369 ++
drivers/media/radio/radio-tavarua.c | 24 +-
drivers/media/video/msm/Kconfig | 72 +-
drivers/media/video/msm/actuators/msm_actuator.c | 4 +-
drivers/media/video/msm/csi/msm_csic.c | 12 +-
drivers/media/video/msm/flash.c | 6 +-
drivers/media/video/msm/msm.c | 19 +-
drivers/media/video/msm/msm_mctl.c | 14 +-
drivers/media/video/msm/msm_mctl_buf.c | 7 +-
drivers/media/video/msm/msm_vfe7x27a_v4l2.c | 40 +-
drivers/media/video/msm/sensors/Makefile | 19 +-
drivers/media/video/msm/sensors/a8140_v4l2.c | 965 +++
drivers/media/video/msm/sensors/ar0542_v4l2.c | 1047 ++++
drivers/media/video/msm/sensors/ar0543_v4l2.c | 956 +++
.../video/msm/sensors/hi351_sunny_q3h01b_v4l2.c | 2406 +++++++
.../video/msm/sensors/hi351_sunny_q3h01b_v4l2.h | 6531 ++++++++++++++++++++
drivers/media/video/msm/sensors/msm_sensor.c | 142 +-
drivers/media/video/msm/sensors/msm_sensor.h | 8 +-
drivers/media/video/msm/sensors/mt9v115_v4l2.c | 621 ++
.../media/video/msm/sensors/odmm_ov7692_qrd_v4l2.c | 1804 ++++++
.../media/video/msm/sensors/odmm_ov7692_qrd_v4l2.h | 287 +
.../video/msm/sensors/ov5647_dl_bd631ac_v4l2.c | 1048 ++++
.../video/msm/sensors/ov5647_hq_dg806t_v4l2.c | 1048 ++++
.../video/msm/sensors/ov5647_partron_cm500_v4l2.c | 1317 ++++
.../video/msm/sensors/ov5647_truly_cm6868_v4l2.c | 1201 ++++
drivers/media/video/msm/sensors/ov5647_v4l2.c | 27 +-
.../video/msm/sensors/ov5648_truly_cm8352_v4l2.c | 2293 +++++++
drivers/media/video/msm/sensors/ov5648_v4l2.c | 2258 -------
drivers/media/video/msm/sensors/ov7692_v4l2.c | 182 +-
drivers/media/video/msm/sensors/ov7695_raw_v4l2.c | 80 +-
drivers/media/video/msm/sensors/ov8825_v4l2.c | 158 +-
.../media/video/msm/sensors/pip_ov5648_ov7695.h | 84 +-
.../video/msm/sensors/s5k3h2_sunny_q8s02e_v4l2.c | 2240 +++++++
.../media/video/msm/sensors/s5k5ca_darling_v4l2.c | 4350 +++++++++++++
.../media/video/msm/sensors/s5k5ca_darling_v4l2.h | 20 +
drivers/media/video/msm/sensors/s5k5ca_v4l2.c | 4310 +++++++++++++
drivers/media/video/msm/sensors/s5k5ca_v4l2.h | 20 +
drivers/misc/Kconfig | 16 +-
drivers/misc/Makefile | 3 +
drivers/misc/akm8975.c | 1638 +++--
drivers/misc/apanic_mmc.c | 986 +++
drivers/misc/glanceview.c | 319 +
drivers/misc/inv_mpu/Kconfig | 76 +
drivers/misc/inv_mpu/Makefile | 45 +
drivers/misc/inv_mpu/README | 104 +
drivers/misc/inv_mpu/accel/Kconfig | 133 +
drivers/misc/inv_mpu/accel/Makefile | 38 +
drivers/misc/inv_mpu/accel/adxl34x.c | 727 +++
drivers/misc/inv_mpu/accel/bma150.c | 776 +++
drivers/misc/inv_mpu/accel/bma222.c | 653 ++
drivers/misc/inv_mpu/accel/bma250.c | 786 +++
drivers/misc/inv_mpu/accel/cma3000.c | 221 +
drivers/misc/inv_mpu/accel/kxsd9.c | 263 +
drivers/misc/inv_mpu/accel/kxtf9.c | 840 +++
drivers/misc/inv_mpu/accel/lis331.c | 744 +++
drivers/misc/inv_mpu/accel/lis3dh.c | 727 +++
drivers/misc/inv_mpu/accel/lsm303dlx_a.c | 880 +++
drivers/misc/inv_mpu/accel/mma8450.c | 803 +++
drivers/misc/inv_mpu/accel/mma845x.c | 712 +++
drivers/misc/inv_mpu/accel/mpu6050.h | 27 +
drivers/misc/inv_mpu/compass/Kconfig | 129 +
drivers/misc/inv_mpu/compass/Makefile | 40 +
drivers/misc/inv_mpu/compass/ak8972.c | 498 ++
drivers/misc/inv_mpu/compass/ak8975.c | 500 ++
drivers/misc/inv_mpu/compass/ami306.c | 1019 +++
drivers/misc/inv_mpu/compass/ami30x.c | 307 +
drivers/misc/inv_mpu/compass/hmc5883.c | 390 ++
drivers/misc/inv_mpu/compass/hscdtd002b.c | 293 +
drivers/misc/inv_mpu/compass/hscdtd004a.c | 317 +
drivers/misc/inv_mpu/compass/lsm303dlx_m.c | 394 ++
drivers/misc/inv_mpu/compass/mmc314x.c | 312 +
drivers/misc/inv_mpu/compass/mmc328xms.c | 352 ++
drivers/misc/inv_mpu/compass/yas529-kernel.c | 610 ++
drivers/misc/inv_mpu/compass/yas530.c | 579 ++
drivers/misc/inv_mpu/log.h | 256 +
drivers/misc/inv_mpu/mldl_cfg.c | 1789 ++++++
drivers/misc/inv_mpu/mldl_cfg.h | 379 ++
drivers/misc/inv_mpu/mldl_print_cfg.c | 136 +
drivers/misc/inv_mpu/mldl_print_cfg.h | 37 +
drivers/misc/inv_mpu/mlsl-kernel.c | 420 ++
drivers/misc/inv_mpu/mlsl.h | 185 +
drivers/misc/inv_mpu/mltypes.h | 233 +
drivers/misc/inv_mpu/mpu-dev.c | 1251 ++++
drivers/misc/inv_mpu/mpu-dev.h | 35 +
drivers/misc/inv_mpu/mpu3050.h | 250 +
drivers/misc/inv_mpu/mpuirq.c | 256 +
drivers/misc/inv_mpu/mpuirq.h | 35 +
drivers/misc/inv_mpu/pressure/Kconfig | 20 +
drivers/misc/inv_mpu/pressure/Makefile | 8 +
drivers/misc/inv_mpu/pressure/bma085.c | 366 ++
drivers/misc/inv_mpu/slaveirq.c | 265 +
drivers/misc/inv_mpu/slaveirq.h | 35 +
drivers/misc/inv_mpu/timerirq.c | 295 +
drivers/misc/inv_mpu/timerirq.h | 29 +
drivers/mmc/card/block.c | 15 +-
drivers/mmc/core/core.c | 11 +-
drivers/mmc/core/mmc.c | 4 +-
drivers/mmc/core/mmc_ops.c | 2 +-
drivers/mmc/core/sd.c | 6 +
drivers/mmc/host/Kconfig | 10 +
drivers/mmc/host/Makefile | 1 +
drivers/mmc/host/msm_sdcc.c | 96 +-
drivers/mmc/host/msm_sdcc_raw.c | 2464 ++++++++
drivers/mtd/devices/msm_nand.c | 27 +-
drivers/net/wireless/ath/ath6kl/sdio.c | 3 +-
drivers/odmm/Kconfig | 2 +
drivers/odmm/Makefile | 6 +
drivers/odmm/nv_storage/Kconfig | 7 +
drivers/odmm/nv_storage/Makefile | 6 +
drivers/odmm/nv_storage/nvbk_storage_server.c | 195 +
drivers/platform/msm/ssbi.c | 2 +-
drivers/power/Kconfig | 7 +
drivers/power/msm_battery.c | 1962 +++---
drivers/power/power_supply_sysfs.c | 3 +-
drivers/regulator/onsemi-ncp6335d.c | 2 +
drivers/rtc/alarm-dev.c | 20 +-
drivers/rtc/alarm.c | 22 +
drivers/rtc/interface.c | 18 +
drivers/rtc/rtc-msm.c | 246 +-
drivers/staging/android/ashmem.c | 77 +-
drivers/staging/android/logger.c | 13 +
drivers/staging/android/lowmemorykiller.c | 176 +-
.../staging/ft1000/ft1000-usb/ft1000_download.c | 2 +-
drivers/staging/ft1000/ft1000-usb/ft1000_hw.c | 2 +-
drivers/staging/ft1000/ft1000-usb/ft1000_usb.c | 2 +-
drivers/staging/zram/Kconfig | 2 +-
drivers/staging/zram/zram_drv.c | 45 +-
drivers/staging/zram/zram_sysfs.c | 22 +-
drivers/staging/zsmalloc/Kconfig | 2 +-
drivers/staging/zsmalloc/zsmalloc-main.c | 55 +-
drivers/staging/zsmalloc/zsmalloc_int.h | 1 -
drivers/tty/serial/msm_serial.c | 7 +-
drivers/tty/vt/vt_ioctl.c | 51 +-
drivers/usb/Kconfig | 4 +
drivers/usb/gadget/android.c | 209 +-
drivers/usb/gadget/f_adb.c | 86 +-
drivers/usb/gadget/f_mass_storage.c | 95 +-
drivers/usb/gadget/f_mtp.c | 9 +-
drivers/usb/gadget/f_rmnet_smd.c | 39 +-
drivers/usb/gadget/f_serial.c | 18 +-
drivers/usb/gadget/f_winusb.c | 934 +++
drivers/usb/gadget/msm72k_udc.c | 89 +-
drivers/usb/gadget/qcom_maemo.c | 2 +-
drivers/usb/gadget/u_smd.c | 415 +-
drivers/usb/otg/msm72k_otg.c | 20 +
drivers/usb/serial/qcserial.c | 2 +-
drivers/video/fbmem.c | 38 +-
drivers/video/msm/Kconfig | 45 +
drivers/video/msm/Makefile | 36 +-
drivers/video/msm/mddi_hw.h | 2 +-
drivers/video/msm/mdp.c | 6 +-
drivers/video/msm/mdp_csc_table.h | 2 +-
drivers/video/msm/mdp_dma.c | 0
drivers/video/msm/mdp_hw.h | 2 +-
drivers/video/msm/mdp_hw40.c | 2 +-
drivers/video/msm/mdp_hw_init.c | 2 -
drivers/video/msm/mdp_ppp_v20.c | 2 +-
drivers/video/msm/mdp_scale_tables.c | 2 +-
drivers/video/msm/mdp_scale_tables.h | 2 +-
drivers/video/msm/mipi_NT35510.c | 60 +-
drivers/video/msm/mipi_NT35510_cmd_wvga_pt.c | 10 +-
drivers/video/msm/mipi_byd_otm9608a_wg451v.c | 789 +++
drivers/video/msm/mipi_div4_nt35510_cmd_wvga.c | 1185 ++++
drivers/video/msm/mipi_dsi.c | 44 +-
drivers/video/msm/mipi_dsi.h | 2 +
drivers/video/msm/mipi_dsi_host.c | 33 +-
drivers/video/msm/mipi_hx8389b.c | 171 +-
drivers/video/msm/mipi_hx8389b_cmd_qhd_pt.c | 97 -
drivers/video/msm/mipi_hx8389b_video_qhd_pt.c | 22 +-
drivers/video/msm/mipi_hx8392a.c | 422 ++
drivers/video/msm/mipi_hx8392a.h | 20 +
drivers/video/msm/mipi_hx8392a_video_720p_pt.c | 103 +
drivers/video/msm/mipi_nt35516_e808t.c | 825 +++
drivers/video/msm/mipi_otm9605a.c | 608 ++
drivers/video/msm/mipi_otm9605a.h | 20 +
drivers/video/msm/mipi_otm9605a_video_qhd_pt.c | 108 +
drivers/video/msm/mipi_yassy_otm9608a_wg451v.c | 814 +++
drivers/video/msm/msm_dss_io_7x27a.c | 38 +
drivers/video/msm/msm_fb.c | 295 +-
drivers/video/msm/msm_fb.h | 16 +
drivers/video/msm/msm_fb_bl.c | 2 +-
drivers/video/msm/msm_fb_panel.h | 4 +
fs/ext4/balloc.c | 8 +-
fs/fat/fat.h | 2 +-
fs/fat/misc.c | 40 +-
include/asm-generic/sections.h | 3 +
include/linux/akm8975.h | 69 +-
include/linux/apanic_mmc.h | 64 +
include/linux/diagchar.h | 1 +
include/linux/ft6306_touch.h | 102 +
include/linux/glanceview.h | 48 +
include/linux/input.h | 1 +
include/linux/input/apds990x.h | 39 +
include/linux/input/auo-pixcir-ts.h | 2 +-
include/linux/input/ft5x06_ts.h | 2 +-
include/linux/input/isl29028.h | 27 +
include/linux/input/ltr502.h | 28 +
include/linux/input/ltr5xx.h | 27 +
include/linux/input/tmd2771x.h | 27 +
include/linux/ion.h | 2 +-
include/linux/irqflags.h | 94 +-
include/linux/leds-pmic8029.h | 32 +
include/linux/leds.h | 22 +
include/linux/mm.h | 1 +
include/linux/mmc/msm_sdcc_raw.h | 28 +
include/linux/mpu.h | 366 ++
include/linux/power_supply.h | 1 +
include/linux/ppp-ioctl.h | 2 +
include/linux/rmt_storage_client.h | 23 +
include/linux/rtc.h | 13 +
include/linux/sched.h | 6 +-
include/linux/sm_event.h | 56 +
include/linux/sm_event_log.h | 227 +
include/linux/time.h | 1 +
include/linux/usb/otg.h | 1 -
include/linux/wakelock.h | 5 +-
include/media/msm_camera.h | 10 +-
include/net/bluetooth/sco.h | 2 +-
include/trace/events/cpu_hotplug.h | 29 +
include/trace/events/cpufreq.h | 31 +
kernel/cpu.c | 19 +
kernel/events/core.c | 1 -
kernel/exit.c | 6 +-
kernel/fork.c | 9 +-
kernel/irq/handle.c | 45 +
kernel/panic.c | 45 +
kernel/power/earlysuspend.c | 141 +-
kernel/power/suspend.c | 14 +
kernel/power/wakelock.c | 36 +-
kernel/printk.c | 111 +-
kernel/ptrace.c | 0
kernel/sched/core.c | 9 +
kernel/signal.c | 6 +-
kernel/sys.c | 1 +
kernel/time/timekeeping.c | 15 +
lib/Kconfig.debug | 16 +
lib/idr.c | 9 +-
lib/spinlock_debug.c | 5 +-
mm/init-mm.c | 2 +
mm/memory.c | 46 +
net/bluetooth/af_bluetooth.c | 2 +-
net/bluetooth/hci_conn.c | 1 +
net/bluetooth/hci_core.c | 28 +-
net/bluetooth/lib.c | 2 +-
net/bluetooth/sco.c | 2 +-
tools/perf/builtin-script.c | 6 +-
tools/perf/util/parse-events.c | 69 +-
tools/perf/util/parse-events.h | 6 +-
tools/perf/util/parse-events.y | 4 +-
382 files changed, 98527 insertions(+), 6151 deletions(-)
mode change 100644 => 100755 Makefile
mode change 100644 => 100755 arch/arm/configs/msm7627a-perf_defconfig
mode change 100644 => 100755 arch/arm/configs/msm7627a_defconfig
create mode 100755 arch/arm/configs/normandy_b1_defconfig
create mode 100755 arch/arm/configs/normandy_b2_defconfig
create mode 100755 arch/arm/configs/normandy_b3_defconfig
create mode 100755 arch/arm/configs/normandy_evb1_defconfig
create mode 100755 arch/arm/configs/normandy_evb2_defconfig
create mode 100755 arch/arm/configs/normandy_lv_defconfig
create mode 100755 arch/arm/configs/normandy_mp_defconfig
create mode 100755 arch/arm/configs/normandy_s11_defconfig
mode change 100644 => 100755 arch/arm/include/asm/thread_info.h
mode change 100644 => 100755 arch/arm/mach-msm/board-msm7627a-camera.c
mode change 100644 => 100755 arch/arm/mach-msm/board-msm7627a-display.c
create mode 100755 arch/arm/mach-msm/board-msm7627a-sensor.c
create mode 100644 arch/arm/mach-msm/board-msm7627a-sensor.h
mode change 100644 => 100755 arch/arm/mach-msm/board-msm7627a-storage.c
mode change 100644 => 100755 arch/arm/mach-msm/board-msm7x27a-regulator.c
mode change 100644 => 100755 arch/arm/mach-msm/board-msm7x27a.c
mode change 100644 => 100755 arch/arm/mach-msm/board-qrd7627a.c
create mode 100644 arch/arm/mach-msm/cache-ops.h
mode change 100644 => 100755 arch/arm/mach-msm/clock-pcom-lookup.c
mode change 100644 => 100755 arch/arm/mach-msm/devices-msm7x27a.c
create mode 100644 arch/arm/mach-msm/enhance-debug.c
create mode 100644 arch/arm/mach-msm/fastboot.c
mode change 100644 => 100755 arch/arm/mach-msm/gpiomux.c
mode change 100644 => 100755 arch/arm/mach-msm/include/mach/board.h
create mode 100644 arch/arm/mach-msm/perf_event_msm_pl310.c
mode change 100644 => 100755 arch/arm/mach-msm/proc_comm.c
mode change 100644 => 100755 arch/arm/mach-msm/rpc_server_handset.c
create mode 100644 arch/arm/mach-msm/sleep_monitor.c
create mode 100644 arch/arm/mach-msm/sm_event.c
create mode 100644 arch/arm/mach-msm/sm_event_driver.c
create mode 100644 arch/arm/mach-msm/sm_event_log.c
mode change 100644 => 100755 block/partition-generic.c
mode change 100644 => 100755 drivers/Kconfig
mode change 100644 => 100755 drivers/Makefile
mode change 100644 => 100755 drivers/char/diag/diagfwd.c
mode change 100644 => 100755 drivers/cpufreq/cpufreq_ondemand.c
mode change 100644 => 100755 drivers/hwmon/Kconfig
mode change 100644 => 100755 drivers/hwmon/Makefile
create mode 100755 drivers/hwmon/bma2x2.c
create mode 100755 drivers/hwmon/ltr559.c
mode change 100644 => 100755 drivers/i2c/busses/i2c-qup.c
create mode 100644 drivers/input/misc/apds990x.c
create mode 100644 drivers/input/misc/bma250.c
create mode 100644 drivers/input/misc/isl29028.c
create mode 100644 drivers/input/misc/lis3dh.c
create mode 100644 drivers/input/misc/ltr502.c
create mode 100644 drivers/input/misc/ltr558.c
create mode 100644 drivers/input/misc/tmd2771x.c
mode change 100644 => 100755 drivers/input/touchscreen/Kconfig
mode change 100644 => 100755 drivers/input/touchscreen/Makefile
create mode 100755 drivers/input/touchscreen/focal_touch.c
create mode 100755 drivers/input/touchscreen/ft6306_touch.c
create mode 100755 drivers/input/touchscreen/tp_work_func.c
create mode 100755 drivers/input/touchscreen/tp_work_func.h
create mode 100644 drivers/leds/leds-pmic8029.c
create mode 100644 drivers/leds/leds-tricolor.c
mode change 100644 => 100755 drivers/media/radio/radio-tavarua.c
mode change 100644 => 100755 drivers/media/video/msm/msm.c
mode change 100644 => 100755 drivers/media/video/msm/msm_vfe7x27a_v4l2.c
create mode 100755 drivers/media/video/msm/sensors/a8140_v4l2.c
create mode 100755 drivers/media/video/msm/sensors/ar0542_v4l2.c
create mode 100755 drivers/media/video/msm/sensors/ar0543_v4l2.c
create mode 100755 drivers/media/video/msm/sensors/hi351_sunny_q3h01b_v4l2.c
create mode 100755 drivers/media/video/msm/sensors/hi351_sunny_q3h01b_v4l2.h
create mode 100644 drivers/media/video/msm/sensors/mt9v115_v4l2.c
create mode 100755 drivers/media/video/msm/sensors/odmm_ov7692_qrd_v4l2.c
create mode 100755 drivers/media/video/msm/sensors/odmm_ov7692_qrd_v4l2.h
create mode 100755 drivers/media/video/msm/sensors/ov5647_dl_bd631ac_v4l2.c
create mode 100755 drivers/media/video/msm/sensors/ov5647_hq_dg806t_v4l2.c
create mode 100755 drivers/media/video/msm/sensors/ov5647_partron_cm500_v4l2.c
create mode 100755 drivers/media/video/msm/sensors/ov5647_truly_cm6868_v4l2.c
mode change 100644 => 100755 drivers/media/video/msm/sensors/ov5647_v4l2.c
create mode 100644 drivers/media/video/msm/sensors/ov5648_truly_cm8352_v4l2.c
delete mode 100755 drivers/media/video/msm/sensors/ov5648_v4l2.c
mode change 100644 => 100755 drivers/media/video/msm/sensors/ov7692_v4l2.c
mode change 100755 => 100644 drivers/media/video/msm/sensors/ov7695_raw_v4l2.c
create mode 100755 drivers/media/video/msm/sensors/s5k3h2_sunny_q8s02e_v4l2.c
create mode 100755 drivers/media/video/msm/sensors/s5k5ca_darling_v4l2.c
create mode 100755 drivers/media/video/msm/sensors/s5k5ca_darling_v4l2.h
create mode 100755 drivers/media/video/msm/sensors/s5k5ca_v4l2.c
create mode 100755 drivers/media/video/msm/sensors/s5k5ca_v4l2.h
mode change 100644 => 100755 drivers/misc/Kconfig
mode change 100644 => 100755 drivers/misc/Makefile
create mode 100755 drivers/misc/apanic_mmc.c
create mode 100755 drivers/misc/glanceview.c
create mode 100755 drivers/misc/inv_mpu/Kconfig
create mode 100644 drivers/misc/inv_mpu/Makefile
create mode 100644 drivers/misc/inv_mpu/README
create mode 100644 drivers/misc/inv_mpu/accel/Kconfig
create mode 100644 drivers/misc/inv_mpu/accel/Makefile
create mode 100644 drivers/misc/inv_mpu/accel/adxl34x.c
create mode 100644 drivers/misc/inv_mpu/accel/bma150.c
create mode 100644 drivers/misc/inv_mpu/accel/bma222.c
create mode 100644 drivers/misc/inv_mpu/accel/bma250.c
create mode 100644 drivers/misc/inv_mpu/accel/cma3000.c
create mode 100644 drivers/misc/inv_mpu/accel/kxsd9.c
create mode 100644 drivers/misc/inv_mpu/accel/kxtf9.c
create mode 100644 drivers/misc/inv_mpu/accel/lis331.c
create mode 100644 drivers/misc/inv_mpu/accel/lis3dh.c
create mode 100644 drivers/misc/inv_mpu/accel/lsm303dlx_a.c
create mode 100644 drivers/misc/inv_mpu/accel/mma8450.c
create mode 100644 drivers/misc/inv_mpu/accel/mma845x.c
create mode 100644 drivers/misc/inv_mpu/accel/mpu6050.h
create mode 100644 drivers/misc/inv_mpu/compass/Kconfig
create mode 100644 drivers/misc/inv_mpu/compass/Makefile
create mode 100644 drivers/misc/inv_mpu/compass/ak8972.c
create mode 100644 drivers/misc/inv_mpu/compass/ak8975.c
create mode 100644 drivers/misc/inv_mpu/compass/ami306.c
create mode 100644 drivers/misc/inv_mpu/compass/ami30x.c
create mode 100644 drivers/misc/inv_mpu/compass/hmc5883.c
create mode 100644 drivers/misc/inv_mpu/compass/hscdtd002b.c
create mode 100644 drivers/misc/inv_mpu/compass/hscdtd004a.c
create mode 100644 drivers/misc/inv_mpu/compass/lsm303dlx_m.c
create mode 100644 drivers/misc/inv_mpu/compass/mmc314x.c
create mode 100644 drivers/misc/inv_mpu/compass/mmc328xms.c
create mode 100644 drivers/misc/inv_mpu/compass/yas529-kernel.c
create mode 100644 drivers/misc/inv_mpu/compass/yas530.c
create mode 100644 drivers/misc/inv_mpu/log.h
create mode 100644 drivers/misc/inv_mpu/mldl_cfg.c
create mode 100644 drivers/misc/inv_mpu/mldl_cfg.h
create mode 100644 drivers/misc/inv_mpu/mldl_print_cfg.c
create mode 100644 drivers/misc/inv_mpu/mldl_print_cfg.h
create mode 100644 drivers/misc/inv_mpu/mlsl-kernel.c
create mode 100644 drivers/misc/inv_mpu/mlsl.h
create mode 100644 drivers/misc/inv_mpu/mltypes.h
create mode 100644 drivers/misc/inv_mpu/mpu-dev.c
create mode 100644 drivers/misc/inv_mpu/mpu-dev.h
create mode 100644 drivers/misc/inv_mpu/mpu3050.h
create mode 100644 drivers/misc/inv_mpu/mpuirq.c
create mode 100644 drivers/misc/inv_mpu/mpuirq.h
create mode 100644 drivers/misc/inv_mpu/pressure/Kconfig
create mode 100644 drivers/misc/inv_mpu/pressure/Makefile
create mode 100644 drivers/misc/inv_mpu/pressure/bma085.c
create mode 100644 drivers/misc/inv_mpu/slaveirq.c
create mode 100644 drivers/misc/inv_mpu/slaveirq.h
create mode 100644 drivers/misc/inv_mpu/timerirq.c
create mode 100644 drivers/misc/inv_mpu/timerirq.h
mode change 100644 => 100755 drivers/mmc/card/block.c
mode change 100644 => 100755 drivers/mmc/core/mmc.c
mode change 100644 => 100755 drivers/mmc/host/Kconfig
mode change 100644 => 100755 drivers/mmc/host/Makefile
create mode 100755 drivers/mmc/host/msm_sdcc_raw.c
create mode 100755 drivers/odmm/Kconfig
create mode 100755 drivers/odmm/Makefile
create mode 100755 drivers/odmm/nv_storage/Kconfig
create mode 100755 drivers/odmm/nv_storage/Makefile
create mode 100755 drivers/odmm/nv_storage/nvbk_storage_server.c
mode change 100644 => 100755 drivers/rtc/rtc-msm.c
mode change 100644 => 100755 drivers/staging/android/ashmem.c
mode change 100644 => 100755 drivers/staging/android/lowmemorykiller.c
mode change 100644 => 100755 drivers/staging/zram/zram_drv.c
mode change 100644 => 100755 drivers/staging/zram/zram_sysfs.c
mode change 100644 => 100755 drivers/usb/gadget/android.c
create mode 100755 drivers/usb/gadget/f_winusb.c
mode change 100644 => 100755 drivers/video/msm/mdp.c
mode change 100644 => 100755 drivers/video/msm/mdp_dma.c
create mode 100755 drivers/video/msm/mipi_byd_otm9608a_wg451v.c
create mode 100755 drivers/video/msm/mipi_div4_nt35510_cmd_wvga.c
mode change 100644 => 100755 drivers/video/msm/mipi_dsi.c
mode change 100644 => 100755 drivers/video/msm/mipi_dsi.h
mode change 100644 => 100755 drivers/video/msm/mipi_dsi_host.c
delete mode 100644 drivers/video/msm/mipi_hx8389b_cmd_qhd_pt.c
mode change 100644 => 100755 drivers/video/msm/mipi_hx8389b_video_qhd_pt.c
create mode 100644 drivers/video/msm/mipi_hx8392a.c
create mode 100644 drivers/video/msm/mipi_hx8392a.h
create mode 100644 drivers/video/msm/mipi_hx8392a_video_720p_pt.c
create mode 100755 drivers/video/msm/mipi_nt35516_e808t.c
create mode 100755 drivers/video/msm/mipi_otm9605a.c
create mode 100644 drivers/video/msm/mipi_otm9605a.h
create mode 100644 drivers/video/msm/mipi_otm9605a_video_qhd_pt.c
create mode 100755 drivers/video/msm/mipi_yassy_otm9608a_wg451v.c
mode change 100644 => 100755 drivers/video/msm/msm_dss_io_7x27a.c
mode change 100644 => 100755 drivers/video/msm/msm_fb.c
mode change 100644 => 100755 drivers/video/msm/msm_fb.h
mode change 100644 => 100755 drivers/video/msm/msm_fb_bl.c
mode change 100644 => 100755 drivers/video/msm/msm_fb_panel.h
create mode 100755 include/linux/apanic_mmc.h
create mode 100755 include/linux/ft6306_touch.h
create mode 100755 include/linux/glanceview.h
create mode 100644 include/linux/input/apds990x.h
create mode 100644 include/linux/input/isl29028.h
create mode 100644 include/linux/input/ltr502.h
create mode 100644 include/linux/input/ltr5xx.h
create mode 100644 include/linux/input/tmd2771x.h
create mode 100644 include/linux/leds-pmic8029.h
create mode 100755 include/linux/mmc/msm_sdcc_raw.h
create mode 100644 include/linux/mpu.h
mode change 100644 => 100755 include/linux/ppp-ioctl.h
mode change 100644 => 100755 include/linux/sched.h
create mode 100644 include/linux/sm_event.h
create mode 100644 include/linux/sm_event_log.h
create mode 100644 include/trace/events/cpu_hotplug.h
create mode 100644 include/trace/events/cpufreq.h
mode change 100644 => 100755 kernel/exit.c
mode change 100644 => 100755 kernel/fork.c
mode change 100644 => 100755 kernel/power/earlysuspend.c
mode change 100644 => 100755 kernel/power/wakelock.c
mode change 100644 => 100755 kernel/ptrace.c
diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt
index 82ac057..3e37941 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.txt
+++ b/Documentation/devicetree/bindings/vendor-prefixes.txt
@@ -32,7 +32,7 @@ nvidia NVIDIA
nxp NXP Semiconductors
picochip Picochip Ltd
powervr Imagination Technologies
-qcom Qualcomm, Inc.
+qcom Qualcomm Technologies, Inc.
ramtron Ramtron International
realtek Realtek Semiconductor Corp.
samsung Samsung Semiconductor
diff --git a/Makefile b/Makefile
old mode 100644
new mode 100755
index 75b36ae..e6f25a9
--- a/Makefile
+++ b/Makefile
@@ -380,6 +380,15 @@ KBUILD_AFLAGS_MODULE := -DMODULE
KBUILD_CFLAGS_MODULE := -DMODULE
KBUILD_LDFLAGS_MODULE := -T $(srctree)/scripts/module-common.lds
+# wang.junxian2@byd.com added for project & stage
+# begin
+
+ifneq ($(BYD_PROJECT_STAGE),)
+KBUILD_CFLAGS += -D$(BYD_PROJECT_STAGE)
+endif
+
+#end
+
# Read KERNELRELEASE from include/config/kernel.release (if it exists)
KERNELRELEASE = $(shell cat include/config/kernel.release 2> /dev/null)
KERNELVERSION = $(VERSION)$(if $(PATCHLEVEL),.$(PATCHLEVEL)$(if $(SUBLEVEL),.$(SUBLEVEL)))$(EXTRAVERSION)
diff --git a/arch/arm/configs/msm7627a-perf_defconfig b/arch/arm/configs/msm7627a-perf_defconfig
old mode 100644
new mode 100755
index cdf6e82..2561306
--- a/arch/arm/configs/msm7627a-perf_defconfig
+++ b/arch/arm/configs/msm7627a-perf_defconfig
@@ -1,7 +1,8 @@
# CONFIG_ARM_PATCH_PHYS_VIRT is not set
CONFIG_EXPERIMENTAL=y
CONFIG_LOCALVERSION="$(KERNEL_LOCAL_VERSION)-perf"
-# CONFIG_SWAP is not set
+CONFIG_SWAP=y
+CONFIG_ZRAM=m
CONFIG_SYSVIPC=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
@@ -10,6 +11,8 @@ CONFIG_CGROUP_FREEZER=y
CONFIG_CGROUP_DEVICE=y
CONFIG_CGROUP_CPUACCT=y
CONFIG_RESOURCE_COUNTERS=y
+CONFIG_CGROUP_MEM_RES_CTLR=y
+CONFIG_CGROUP_MEM_RES_CTLR_SWAP=y
CONFIG_CGROUP_SCHED=y
CONFIG_RT_GROUP_SCHED=y
CONFIG_BLK_DEV_INITRD=y
@@ -36,6 +39,7 @@ CONFIG_MSM_SOC_REV_A=y
CONFIG_MSM7X00A_USE_DG_TIMER=y
# CONFIG_MSM_FIQ_SUPPORT is not set
CONFIG_MSM_SMD=y
+CONFIG_MSM_AMSS_ENHANCE_DEBUG=y
CONFIG_MSM_SMD_PKG4=y
# CONFIG_MSM_SMD_DEBUG is not set
# CONFIG_MSM_RESET_MODEM is not set
@@ -49,11 +53,16 @@ CONFIG_MSM_RMT_STORAGE_CLIENT=y
CONFIG_MSM7X27A_AUDIO=y
CONFIG_MSM_DMA_TEST=y
CONFIG_MSM_SLEEP_STATS_DEVICE=y
+CONFIG_MSM_SM_EVENT=y
+CONFIG_MSM_SM_EVENT_LOG=m
+CONFIG_MSM_SLEEP_MONITOR=m
+CONFIG_MSM_FAST_BOOT=y
CONFIG_BT_MSM_PINTEST=y
CONFIG_MSM_RPC_VIBRATOR=y
CONFIG_PM8XXX_RPC_VIBRATOR=y
CONFIG_MSM_SPM_V2=y
CONFIG_MSM_MULTIMEDIA_USE_ION=y
+CONFIG_MSM_FUSE_INFO_DEBUG=y
CONFIG_MSM_CPR=y
CONFIG_MSM_VP_REGULATOR=y
CONFIG_MSM_FIQ=y
@@ -159,10 +168,14 @@ CONFIG_IP_NF_TARGET_MASQUERADE=y
CONFIG_IP_NF_TARGET_NETMAP=y
CONFIG_IP_NF_TARGET_REDIRECT=y
CONFIG_IP_NF_MANGLE=y
+CONFIG_IP_NF_RAW=y
CONFIG_IP_NF_ARPTABLES=y
CONFIG_IP_NF_ARPFILTER=y
CONFIG_IP_NF_ARP_MANGLE=y
CONFIG_IP6_NF_IPTABLES=y
+CONFIG_IP6_NF_FILTER=y
+CONFIG_IP6_NF_MANGLE=y
+CONFIG_IP6_NF_RAW=y
CONFIG_BT=y
CONFIG_BT_RFCOMM=y
CONFIG_BT_RFCOMM_TTY=y
@@ -185,6 +198,13 @@ CONFIG_MTD_CMDLINE_PARTS=y
CONFIG_MTD_CHAR=y
CONFIG_MTD_BLOCK=y
CONFIG_BLK_DEV_LOOP=y
+CONFIG_MISC_DEVICES=y
+#byd CONFIG_SENSORS_AK8975=y
+#byd CONFIG_MPU_SENSORS_TIMERIRQ=y
+#byd CONFIG_MPU_SENSORS_BMA250=y
+#byd CONFIG_MPU_SENSORS_MMC328X=y
+CONFIG_SENSORS_BMA2X2=y
+CONFIG_SENSORS_LTR559=y
CONFIG_SCSI=y
CONFIG_SCSI_TGT=y
CONFIG_BLK_DEV_SD=y
@@ -208,16 +228,22 @@ CONFIG_INPUT_EVBUG=m
# CONFIG_INPUT_KEYBOARD is not set
# CONFIG_INPUT_MOUSE is not set
CONFIG_INPUT_TOUCHSCREEN=y
-CONFIG_TOUCHSCREEN_ATMEL_MAXTOUCH=y
-CONFIG_TOUCHSCREEN_ATMEL_MXT=y
+#byd rm CONFIG_TOUCHSCREEN_ATMEL_MAXTOUCH=y
+#byd rm CONFIG_TOUCHSCREEN_ATMEL_MXT=y
CONFIG_TOUCHSCREEN_SYNAPTICS_RMI4_I2C=y
-CONFIG_TOUCHSCREEN_FT5X06=y
+#byd rm CONFIG_TOUCHSCREEN_FT5X06=y
+# CONFIG_TOUCHSCREEN_FOCAL=y
+CONFIG_TOUCHSCREEN_FT6306=y
CONFIG_INPUT_MISC=y
CONFIG_INPUT_UINPUT=y
CONFIG_INPUT_GPIO=y
-CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4=y
-CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_RMI4_DEV=y
-CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_FW_UPDATE=y
+#byd rm CONFIG_INPUT_LTR502=y
+#byd rm CONFIG_INPUT_LTR558=y
+#byd rm CONFIG_BOSCH_BMA250=y
+#byd rm CONFIG_INPUT_ISL29028=y
+#byd rm CONFIG_INPUT_LIS3DH=y
+#byd rm CONFIG_AVAGO_APDS990X=y
+#byd rm CONFIG_SENSORS_TMD2771X=y
# CONFIG_SERIO is not set
# CONFIG_LEGACY_PTYS is not set
CONFIG_SERIAL_MSM=y
@@ -250,20 +276,29 @@ CONFIG_VIDEO_V4L2_SUBDEV_API=y
CONFIG_VIDEOBUF2_MSM_MEM=y
CONFIG_V4L_PLATFORM_DRIVERS=y
CONFIG_MSM_CAMERA_V4L2=y
-CONFIG_OV5647=y
-CONFIG_OV5648=y
+# CONFIG_OV5647 is not set
+# CONFIG_OV5647_DALING_OVBD631AC is not set
+CONFIG_S5K5CA=y
+CONFIG_HI351_SUNNY_Q3H01B=y
+# CONFIG_OV5647_PARTRON_CM500 is not set
+# CONFIG_OV5647_HQ_O9B5_DG806T=y
+CONFIG_AR0542=y
+# CONFIG_OV5647_TRULY_CM6868 is not set
+# CONFIG_OV5648_TRULY_CM8352=y
CONFIG_AD5046_ACT=y
-CONFIG_WEBCAM_OV9726=y
-CONFIG_MT9E013=y
-CONFIG_S5K4E1=y
-CONFIG_DW9712_ACT=y
-CONFIG_MSM_CAMERA_FLASH_SC628A=y
+#byd rm CONFIG_WEBCAM_OV9726=y
+#byd rm CONFIG_MT9E013=y
+#byd rm CONFIG_S5K4E1=y
+#byd rm CONFIG_DW9712_ACT=y
+#CONFIG_MSM_CAMERA_FLASH_SC628A=y
CONFIG_OV8825=y
CONFIG_MSM_CAMERA_SENSOR=y
CONFIG_MSM_ACTUATOR=y
-CONFIG_OV7692=y
-CONFIG_OV7695_RAW=y
-CONFIG_OV7695=y
+#CONFIG_OV7692=y
+# CONFIG_WEBCAM_OV7692_QRD is not set
+# CONFIG_OV7695 is not set
+# CONFIG_OV7695_RAW=y
+# CONFIG_MT9V115=y
CONFIG_RADIO_TAVARUA=y
CONFIG_ION=y
CONFIG_ION_MSM=y
@@ -275,6 +310,7 @@ CONFIG_FB_MSM=y
CONFIG_FB_MSM_TRIPLE_BUFFER=y
CONFIG_FB_MSM_MDP30=y
CONFIG_FB_MSM_MDP303=y
+CONFIG_FB_MSM_MIPI_DIV4_WVGA_NT35510_PANEL=y
CONFIG_FB_MSM_LCDC_TRULY_HVGA_IPS3P2335_PT_PANEL=y
CONFIG_FB_MSM_MIPI_PANEL_DETECT=y
CONFIG_BACKLIGHT_LCD_SUPPORT=y
@@ -324,10 +360,10 @@ CONFIG_MMC_TEST=m
CONFIG_MMC_MSM=y
CONFIG_MMC_MSM_SDC3_SUPPORT=y
CONFIG_MMC_MSM_SDC3_8_BIT_SUPPORT=y
-CONFIG_LEDS_GPIO=y
CONFIG_LEDS_MSM_PDM=y
CONFIG_LEDS_PMIC_MPP=y
CONFIG_LEDS_MSM_TRICOLOR=y
+CONFIG_LEDS_GPIO=y
CONFIG_SWITCH=y
CONFIG_SWITCH_GPIO=y
CONFIG_RTC_CLASS=y
@@ -351,10 +387,14 @@ CONFIG_NLS_CODEPAGE_437=y
CONFIG_NLS_ASCII=y
CONFIG_NLS_ISO8859_1=y
CONFIG_PRINTK_TIME=y
+CONFIG_PRINTK_RTC_TIME=y
+CONFIG_PRINTK_CPU_ID=y
CONFIG_MAGIC_SYSRQ=y
CONFIG_DEBUG_SHIRQ=y
+# CONFIG_DEBUG_PREEMPT is not set
# CONFIG_SCHED_DEBUG is not set
CONFIG_TIMER_STATS=y
+CONFIG_DEBUG_SPINLOCK=y
CONFIG_DEBUG_STACK_USAGE=y
CONFIG_DEBUG_INFO=y
CONFIG_ENABLE_DEFAULT_TRACERS=y
@@ -362,3 +402,11 @@ CONFIG_DYNAMIC_DEBUG=y
CONFIG_DEBUG_USER=y
CONFIG_CRYPTO_TWOFISH=y
CONFIG_CRC_CCITT=y
+# Add 20120823 TS-FMC-V2 start
+CONFIG_FB_MSM_MIPI_OTM9608A_PT=y
+CONFIG_PPP=y
+CONFIG_PPP_ASYNC=y
+CONFIG_PPP_DEFLATE=y
+CONFIG_PPP_BSDCOMP=y
+# Add 20120823 TS-FMC-V2 end
+ONFIG_GLANCEVIEW=y
diff --git a/arch/arm/configs/msm7627a_defconfig b/arch/arm/configs/msm7627a_defconfig
old mode 100644
new mode 100755
index 8b284c0..7535d19
--- a/arch/arm/configs/msm7627a_defconfig
+++ b/arch/arm/configs/msm7627a_defconfig
@@ -1,7 +1,8 @@
# CONFIG_ARM_PATCH_PHYS_VIRT is not set
CONFIG_EXPERIMENTAL=y
CONFIG_LOCALVERSION="$(KERNEL_LOCAL_VERSION)"
-# CONFIG_SWAP is not set
+CONFIG_SWAP=y
+CONFIG_ZRAM=m
CONFIG_SYSVIPC=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
@@ -10,6 +11,8 @@ CONFIG_CGROUP_FREEZER=y
CONFIG_CGROUP_DEVICE=y
CONFIG_CGROUP_CPUACCT=y
CONFIG_RESOURCE_COUNTERS=y
+CONFIG_CGROUP_MEM_RES_CTLR=y
+CONFIG_CGROUP_MEM_RES_CTLR_SWAP=y
CONFIG_CGROUP_SCHED=y
CONFIG_RT_GROUP_SCHED=y
CONFIG_BLK_DEV_INITRD=y
@@ -36,8 +39,10 @@ CONFIG_MSM_SOC_REV_A=y
CONFIG_MSM7X00A_USE_DG_TIMER=y
# CONFIG_MSM_FIQ_SUPPORT is not set
CONFIG_MSM_SMD=y
+CONFIG_MSM_AMSS_ENHANCE_DEBUG=y
CONFIG_MSM_SMD_PKG4=y
# CONFIG_MSM_SMD_DEBUG is not set
+CONFIG_MSM_FAST_BOOT=y
# CONFIG_MSM_RESET_MODEM is not set
# CONFIG_MSM_SMD_NMEA is not set
# CONFIG_MSM_SMD_QMI is not set
@@ -49,11 +54,15 @@ CONFIG_MSM_RMT_STORAGE_CLIENT=y
CONFIG_MSM7X27A_AUDIO=y
CONFIG_MSM_DMA_TEST=y
CONFIG_MSM_SLEEP_STATS_DEVICE=y
+CONFIG_MSM_SM_EVENT=y
+CONFIG_MSM_SM_EVENT_LOG=m
+CONFIG_MSM_SLEEP_MONITOR=m
CONFIG_BT_MSM_PINTEST=y
CONFIG_MSM_RPC_VIBRATOR=y
CONFIG_PM8XXX_RPC_VIBRATOR=y
CONFIG_MSM_SPM_V2=y
CONFIG_MSM_MULTIMEDIA_USE_ION=y
+CONFIG_MSM_FUSE_INFO_DEBUG=y
CONFIG_MSM_CPR=y
CONFIG_MSM_VP_REGULATOR=y
CONFIG_MSM_FIQ=y
@@ -159,10 +168,14 @@ CONFIG_IP_NF_TARGET_MASQUERADE=y
CONFIG_IP_NF_TARGET_NETMAP=y
CONFIG_IP_NF_TARGET_REDIRECT=y
CONFIG_IP_NF_MANGLE=y
+CONFIG_IP_NF_RAW=y
CONFIG_IP_NF_ARPTABLES=y
CONFIG_IP_NF_ARPFILTER=y
CONFIG_IP_NF_ARP_MANGLE=y
CONFIG_IP6_NF_IPTABLES=y
+CONFIG_IP6_NF_FILTER=y
+CONFIG_IP6_NF_MANGLE=y
+CONFIG_IP6_NF_RAW=y
CONFIG_BT=y
CONFIG_BT_RFCOMM=y
CONFIG_BT_RFCOMM_TTY=y
@@ -185,6 +198,11 @@ CONFIG_MTD_CMDLINE_PARTS=y
CONFIG_MTD_CHAR=y
CONFIG_MTD_BLOCK=y
CONFIG_BLK_DEV_LOOP=y
+CONFIG_MISC_DEVICES=y
+#byd CONFIG_SENSORS_AK8975=y
+#byd CONFIG_MPU_SENSORS_TIMERIRQ=y
+#byd CONFIG_MPU_SENSORS_BMA250=y
+#byd CONFIG_MPU_SENSORS_MMC328X=y
CONFIG_SCSI=y
CONFIG_SCSI_TGT=y
CONFIG_BLK_DEV_SD=y
@@ -208,16 +226,20 @@ CONFIG_INPUT_EVBUG=m
# CONFIG_INPUT_KEYBOARD is not set
# CONFIG_INPUT_MOUSE is not set
CONFIG_INPUT_TOUCHSCREEN=y
-CONFIG_TOUCHSCREEN_ATMEL_MAXTOUCH=y
-CONFIG_TOUCHSCREEN_ATMEL_MXT=y
+#byd rm CONFIG_TOUCHSCREEN_ATMEL_MAXTOUCH=y
+#byd rm CONFIG_TOUCHSCREEN_ATMEL_MXT=y
CONFIG_TOUCHSCREEN_SYNAPTICS_RMI4_I2C=y
-CONFIG_TOUCHSCREEN_FT5X06=y
+#byd rm CONFIG_TOUCHSCREEN_FT5X06=y
CONFIG_INPUT_MISC=y
CONFIG_INPUT_UINPUT=y
CONFIG_INPUT_GPIO=y
-CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4=y
-CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_RMI4_DEV=y
-CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_FW_UPDATE=y
+#byd rm CONFIG_INPUT_LTR502=y
+#byd rm CONFIG_INPUT_LTR558=y
+#byd rm CONFIG_BOSCH_BMA250=y
+#byd rm CONFIG_INPUT_ISL29028=y
+#byd rm CONFIG_INPUT_LIS3DH=y
+#byd rm CONFIG_AVAGO_APDS990X=y
+#byd rm CONFIG_SENSORS_TMD2771X=y
# CONFIG_SERIO is not set
# CONFIG_LEGACY_PTYS is not set
CONFIG_SERIAL_MSM=y
@@ -251,7 +273,9 @@ CONFIG_VIDEOBUF2_MSM_MEM=y
CONFIG_V4L_PLATFORM_DRIVERS=y
CONFIG_MSM_CAMERA_V4L2=y
CONFIG_OV5647=y
-CONFIG_OV5648=y
+CONFIG_AR0542=y
+CONFIG_OV5647_TRULY_CM6868=y
+CONFIG_OV5648_TRULY_CM8352=y
CONFIG_AD5046_ACT=y
CONFIG_WEBCAM_OV9726=y
CONFIG_MT9E013=y
@@ -262,8 +286,9 @@ CONFIG_OV8825=y
CONFIG_MSM_CAMERA_SENSOR=y
CONFIG_MSM_ACTUATOR=y
CONFIG_OV7692=y
+# CONFIG_OV7695 is not set
CONFIG_OV7695_RAW=y
-CONFIG_OV7695=y
+CONFIG_MT9V115=y
CONFIG_RADIO_TAVARUA=y
CONFIG_ION=y
CONFIG_ION_MSM=y
@@ -275,6 +300,7 @@ CONFIG_FB_MSM=y
CONFIG_FB_MSM_TRIPLE_BUFFER=y
CONFIG_FB_MSM_MDP30=y
CONFIG_FB_MSM_MDP303=y
+CONFIG_FB_MSM_MIPI_DIV4_WVGA_NT35510_PANEL=y
CONFIG_FB_MSM_LCDC_TRULY_HVGA_IPS3P2335_PT_PANEL=y
CONFIG_FB_MSM_MIPI_PANEL_DETECT=y
CONFIG_BACKLIGHT_LCD_SUPPORT=y
@@ -327,6 +353,7 @@ CONFIG_MMC_MSM_SDC3_8_BIT_SUPPORT=y
CONFIG_LEDS_MSM_PDM=y
CONFIG_LEDS_PMIC_MPP=y
CONFIG_LEDS_MSM_TRICOLOR=y
+CONFIG_LEDS_GPIO=y
CONFIG_SWITCH=y
CONFIG_SWITCH_GPIO=y
CONFIG_RTC_CLASS=y
@@ -350,20 +377,32 @@ CONFIG_NLS_CODEPAGE_437=y
CONFIG_NLS_ASCII=y
CONFIG_NLS_ISO8859_1=y
CONFIG_PRINTK_TIME=y
+CONFIG_PRINTK_RTC_TIME=y
+CONFIG_PRINTK_CPU_ID=y
CONFIG_MAGIC_SYSRQ=y
CONFIG_DEBUG_SHIRQ=y
CONFIG_LOCKUP_DETECTOR=y
# CONFIG_SCHED_DEBUG is not set
CONFIG_TIMER_STATS=y
+# CONFIG_DEBUG_PREEMPT is not set
CONFIG_DEBUG_SPINLOCK=y
-CONFIG_DEBUG_MUTEXES=y
CONFIG_DEBUG_ATOMIC_SLEEP=y
CONFIG_DEBUG_STACK_USAGE=y
CONFIG_DEBUG_INFO=y
CONFIG_DEBUG_LIST=y
-CONFIG_DEBUG_PAGEALLOC=y
CONFIG_ENABLE_DEFAULT_TRACERS=y
CONFIG_DYNAMIC_DEBUG=y
CONFIG_DEBUG_USER=y
CONFIG_CRYPTO_TWOFISH=y
CONFIG_CRC_CCITT=y
+
+
+# Add 20120823 TS-FMC-V2 start
+CONFIG_PPP=y
+CONFIG_PPP_ASYNC=y
+CONFIG_PPP_DEFLATE=y
+CONFIG_PPP_BSDCOMP=y
+# Add 20120823 TS-FMC-V2 end
+#Add for nvbk
+CONFIG_NVBK_SHARE_MEM=y
+#end
\ No newline at end of file
diff --git a/arch/arm/configs/normandy_b1_defconfig b/arch/arm/configs/normandy_b1_defconfig
new file mode 100755
index 0000000..7d91012
--- /dev/null
+++ b/arch/arm/configs/normandy_b1_defconfig
@@ -0,0 +1,438 @@
+# CONFIG_ARM_PATCH_PHYS_VIRT is not set
+CONFIG_EXPERIMENTAL=y
+CONFIG_LOCALVERSION="$(KERNEL_LOCAL_VERSION)-perf"
+CONFIG_SWAP=y
+CONFIG_ZRAM=m
+CONFIG_SYSVIPC=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_CGROUPS=y
+CONFIG_CGROUP_FREEZER=y
+CONFIG_CGROUP_DEVICE=y
+CONFIG_CGROUP_CPUACCT=y
+CONFIG_RESOURCE_COUNTERS=y
+CONFIG_CGROUP_MEM_RES_CTLR=y
+CONFIG_CGROUP_MEM_RES_CTLR_SWAP=y
+CONFIG_CGROUP_SCHED=y
+CONFIG_RT_GROUP_SCHED=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_KALLSYMS_ALL=y
+CONFIG_ASHMEM=y
+CONFIG_EMBEDDED=y
+CONFIG_PROFILING=y
+CONFIG_OPROFILE=y
+CONFIG_KPROBES=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+# CONFIG_BLK_DEV_BSG is not set
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_IOSCHED_DEADLINE is not set
+CONFIG_ARCH_MSM=y
+CONFIG_ARCH_MSM7X27=y
+CONFIG_ARCH_MSM8625=y
+CONFIG_MSM_SOC_REV_A=y
+# CONFIG_MACH_MSM7X27_SURF is not set
+# CONFIG_MACH_MSM7X27_FFA is not set
+# CONFIG_MSM_STACKED_MEMORY is not set
+CONFIG_MSM7X00A_USE_DG_TIMER=y
+# CONFIG_MSM_FIQ_SUPPORT is not set
+CONFIG_KSM=y
+CONFIG_MSM_SMD=y
+CONFIG_MSM_AMSS_ENHANCE_DEBUG=y
+CONFIG_MSM_SMD_PKG4=y
+# CONFIG_MSM_SMD_DEBUG is not set
+# CONFIG_MSM_RESET_MODEM is not set
+# CONFIG_MSM_SMD_NMEA is not set
+# CONFIG_MSM_SMD_QMI is not set
+CONFIG_MSM_ONCRPCROUTER=y
+CONFIG_MSM_IPC_ROUTER=y
+# CONFIG_MSM_RPCSERVER_TIME_REMOTE is not set
+CONFIG_MSM_RMT_STORAGE_CLIENT=y
+# CONFIG_MSM_HW3D is not set
+CONFIG_MSM7X27A_AUDIO=y
+CONFIG_MSM_DMA_TEST=y
+CONFIG_MSM_SLEEP_STATS_DEVICE=y
+CONFIG_MSM_SM_EVENT=y
+CONFIG_MSM_SM_EVENT_LOG=m
+CONFIG_MSM_SLEEP_MONITOR=m
+CONFIG_MSM_FAST_BOOT=y
+CONFIG_BT_MSM_PINTEST=y
+CONFIG_MSM_RPC_VIBRATOR=y
+CONFIG_PM8XXX_RPC_VIBRATOR=y
+CONFIG_MSM_SPM_V2=y
+CONFIG_MSM_MULTIMEDIA_USE_ION=y
+CONFIG_MSM_FUSE_INFO_DEBUG=y
+CONFIG_MSM_CPR=y
+CONFIG_MSM_VP_REGULATOR=y
+CONFIG_MSM_FIQ=y
+CONFIG_MSM_PBUS=y
+CONFIG_ARM_THUMBEE=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_SMP=y
+CONFIG_PREEMPT=y
+CONFIG_AEABI=y
+CONFIG_HIGHMEM=y
+CONFIG_VMALLOC_RESERVE=0xC800000
+CONFIG_COMPACTION=y
+CONFIG_CP_ACCESS=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="init=/sbin/init root=/dev/ram rw initrd=0x11000000,16M console=ttyDCC0 mem=88M"
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_STAT_DETAILS=y
+CONFIG_CPU_FREQ_GOV_POWERSAVE=y
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_GOV_ONDEMAND=y
+CONFIG_CPU_FREQ_GOV_INTERACTIVE=y
+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
+CONFIG_VFP=y
+CONFIG_NEON=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_WAKELOCK=y
+CONFIG_PM_RUNTIME=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_IP_MULTIPLE_TABLES=y
+CONFIG_IPV6=y
+CONFIG_IPV6_PRIVACY=y
+CONFIG_IPV6_ROUTER_PREF=y
+CONFIG_IPV6_ROUTE_INFO=y
+CONFIG_IPV6_OPTIMISTIC_DAD=y
+CONFIG_INET6_AH=y
+CONFIG_INET6_ESP=y
+CONFIG_INET6_IPCOMP=y
+CONFIG_IPV6_MIP6=y
+CONFIG_IPV6_TUNNEL=y
+CONFIG_IPV6_MULTIPLE_TABLES=y
+CONFIG_IPV6_SUBTREES=y
+CONFIG_NETFILTER=y
+CONFIG_NETFILTER_NETLINK_LOG=y
+CONFIG_NF_CONNTRACK=y
+CONFIG_NF_CONNTRACK_EVENTS=y
+CONFIG_NF_CT_PROTO_DCCP=y
+CONFIG_NF_CT_PROTO_SCTP=y
+CONFIG_NF_CT_PROTO_UDPLITE=y
+CONFIG_NF_CONNTRACK_AMANDA=y
+CONFIG_NF_CONNTRACK_FTP=y
+CONFIG_NF_CONNTRACK_H323=y
+CONFIG_NF_CONNTRACK_IRC=y
+CONFIG_NF_CONNTRACK_NETBIOS_NS=y
+CONFIG_NF_CONNTRACK_PPTP=y
+CONFIG_NF_CONNTRACK_SANE=y
+CONFIG_NF_CONNTRACK_SIP=y
+CONFIG_NF_CONNTRACK_TFTP=y
+CONFIG_NF_CT_NETLINK=y
+CONFIG_NETFILTER_TPROXY=y
+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=y
+CONFIG_NETFILTER_XT_TARGET_CONNMARK=y
+CONFIG_NETFILTER_XT_TARGET_LOG=y
+CONFIG_NETFILTER_XT_TARGET_MARK=y
+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=y
+CONFIG_NETFILTER_XT_MATCH_COMMENT=y
+CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=y
+CONFIG_NETFILTER_XT_MATCH_CONNMARK=y
+CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y
+CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=y
+CONFIG_NETFILTER_XT_MATCH_HELPER=y
+CONFIG_NETFILTER_XT_MATCH_IPRANGE=y
+CONFIG_NETFILTER_XT_MATCH_LENGTH=y
+CONFIG_NETFILTER_XT_MATCH_LIMIT=y
+CONFIG_NETFILTER_XT_MATCH_MAC=y
+CONFIG_NETFILTER_XT_MATCH_MARK=y
+CONFIG_NETFILTER_XT_MATCH_POLICY=y
+CONFIG_NETFILTER_XT_MATCH_PKTTYPE=y
+CONFIG_NETFILTER_XT_MATCH_QTAGUID=y
+CONFIG_NETFILTER_XT_MATCH_QUOTA=y
+CONFIG_NETFILTER_XT_MATCH_QUOTA2=y
+CONFIG_NETFILTER_XT_MATCH_QUOTA2_LOG=y
+CONFIG_NETFILTER_XT_MATCH_SOCKET=y
+CONFIG_NETFILTER_XT_MATCH_STATE=y
+CONFIG_NETFILTER_XT_MATCH_STATISTIC=y
+CONFIG_NETFILTER_XT_MATCH_STRING=y
+CONFIG_NETFILTER_XT_MATCH_TIME=y
+CONFIG_NETFILTER_XT_MATCH_U32=y
+CONFIG_NF_CONNTRACK_IPV4=y
+CONFIG_IP_NF_IPTABLES=y
+CONFIG_IP_NF_MATCH_AH=y
+CONFIG_IP_NF_MATCH_ECN=y
+CONFIG_IP_NF_MATCH_TTL=y
+CONFIG_IP_NF_FILTER=y
+CONFIG_IP_NF_TARGET_REJECT=y
+CONFIG_NF_NAT=y
+CONFIG_IP_NF_TARGET_MASQUERADE=y
+CONFIG_IP_NF_TARGET_NETMAP=y
+CONFIG_IP_NF_TARGET_REDIRECT=y
+CONFIG_IP_NF_MANGLE=y
+CONFIG_IP_NF_RAW=y
+CONFIG_IP_NF_ARPTABLES=y
+CONFIG_IP_NF_ARPFILTER=y
+CONFIG_IP_NF_ARP_MANGLE=y
+CONFIG_IP6_NF_IPTABLES=y
+CONFIG_IP6_NF_FILTER=y
+CONFIG_IP6_NF_MANGLE=y
+CONFIG_IP6_NF_RAW=y
+CONFIG_BT=y
+CONFIG_BT_RFCOMM=y
+CONFIG_BT_RFCOMM_TTY=y
+CONFIG_BT_BNEP=y
+CONFIG_BT_BNEP_MC_FILTER=y
+CONFIG_BT_BNEP_PROTO_FILTER=y
+CONFIG_BT_HIDP=y
+CONFIG_BT_HCIUART=y
+CONFIG_BT_HCIUART_H4=y
+CONFIG_BT_HCIUART_IBS=y
+CONFIG_MSM_BT_POWER=y
+CONFIG_CFG80211=m
+# CONFIG_CFG80211_WEXT is not set
+CONFIG_RFKILL=y
+CONFIG_GENLOCK=y
+CONFIG_GENLOCK_MISCDEVICE=y
+CONFIG_MTD=n
+CONFIG_MTD_TESTS=n
+CONFIG_MTD_CMDLINE_PARTS=n
+CONFIG_MTD_CHAR=n
+CONFIG_MTD_BLOCK=n
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_MISC_DEVICES=y
+#byd CONFIG_SENSORS_AK8975=y
+#byd CONFIG_MPU_SENSORS_TIMERIRQ=y
+#byd CONFIG_MPU_SENSORS_BMA250=y
+#byd CONFIG_MPU_SENSORS_MMC328X=y
+CONFIG_SENSORS_BMA2X2=y
+CONFIG_SENSORS_LTR559=y
+CONFIG_SCSI=y
+CONFIG_SCSI_TGT=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_CHR_DEV_SG=y
+CONFIG_CHR_DEV_SCH=y
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_LOGGING=y
+CONFIG_SCSI_SCAN_ASYNC=y
+CONFIG_MD=y
+CONFIG_BLK_DEV_DM=y
+CONFIG_DM_CRYPT=y
+CONFIG_NETDEVICES=y
+CONFIG_TUN=y
+CONFIG_SMC91X=y
+CONFIG_SMSC911X=y
+CONFIG_LIBRA_SDIOIF=m
+# CONFIG_INPUT_MOUSEDEV is not set
+CONFIG_INPUT_EVDEV=y
+CONFIG_INPUT_EVBUG=m
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+#byd rm CONFIG_TOUCHSCREEN_ATMEL_MAXTOUCH=y
+#byd rm CONFIG_TOUCHSCREEN_ATMEL_MXT=y
+CONFIG_TOUCHSCREEN_SYNAPTICS_RMI4_I2C=y
+#byd rm CONFIG_TOUCHSCREEN_FT5X06=y
+# CONFIG_TOUCHSCREEN_FOCAL=y
+CONFIG_TOUCHSCREEN_FT6306=y
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_UINPUT=y
+CONFIG_INPUT_GPIO=y
+#byd rm CONFIG_INPUT_LTR502=y
+#byd rm CONFIG_INPUT_LTR558=y
+#byd rm CONFIG_BOSCH_BMA250=y
+#byd rm CONFIG_INPUT_ISL29028=y
+#byd rm CONFIG_INPUT_LIS3DH=y
+#byd rm CONFIG_AVAGO_APDS990X=y
+#byd rm CONFIG_SENSORS_TMD2771X=y
+# CONFIG_SERIO is not set
+# CONFIG_LEGACY_PTYS is not set
+CONFIG_SERIAL_MSM=y
+CONFIG_SERIAL_MSM_CONSOLE=y
+CONFIG_SERIAL_MSM_HS=y
+# CONFIG_SERIAL_MSM_CLOCK_CONTROL is not set
+CONFIG_DIAG_CHAR=y
+# CONFIG_HW_RANDOM is not set
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_GPIO=y
+# CONFIG_I2C_MSM is not set
+CONFIG_I2C_QUP=y
+CONFIG_DEBUG_GPIO=y
+CONFIG_GPIO_SYSFS=y
+CONFIG_GPIO_SX150X=y
+CONFIG_POWER_SUPPLY=y
+CONFIG_BATTERY_MSM=y
+CONFIG_SENSORS_MSM_ADC=y
+CONFIG_MARIMBA_CORE=y
+CONFIG_REGULATOR_FAN53555=y
+CONFIG_REGULATOR_ONSEMI_NCP6335D=y
+CONFIG_REGULATOR_MSM_GPIO=y
+CONFIG_MEDIA_SUPPORT=y
+CONFIG_MEDIA_CONTROLLER=y
+CONFIG_VIDEO_DEV=y
+CONFIG_VIDEO_V4L2_SUBDEV_API=y
+# CONFIG_RC_CORE is not set
+# CONFIG_MEDIA_TUNER_CUSTOMISE is not set
+CONFIG_VIDEOBUF2_MSM_MEM=y
+CONFIG_V4L_PLATFORM_DRIVERS=y
+CONFIG_MSM_CAMERA_V4L2=y
+# CONFIG_OV5647 is not set
+# CONFIG_OV5647_DALING_OVBD631AC is not set
+CONFIG_S5K5CA=y
+CONFIG_S5K5CA_DARLING=y
+# CONFIG_HI351_SUNNY_Q3H01B is not set
+# CONFIG_OV5647_PARTRON_CM500 is not set
+# CONFIG_OV5647_HQ_O9B5_DG806T=y
+CONFIG_AR0542=y
+# CONFIG_OV5647_TRULY_CM6868 is not set
+# CONFIG_OV5648_TRULY_CM8352=y
+CONFIG_AD5046_ACT=y
+#byd rm CONFIG_WEBCAM_OV9726=y
+#byd rm CONFIG_MT9E013=y
+#byd rm CONFIG_S5K4E1=y
+#byd rm CONFIG_DW9712_ACT=y
+#CONFIG_MSM_CAMERA_FLASH_SC628A=y
+CONFIG_OV8825=y
+CONFIG_MSM_CAMERA_SENSOR=y
+CONFIG_MSM_ACTUATOR=y
+#CONFIG_OV7692=y
+# CONFIG_WEBCAM_OV7692_QRD is not set
+# CONFIG_OV7695 is not set
+# CONFIG_OV7695_RAW=y
+# CONFIG_MT9V115=y
+CONFIG_RADIO_TAVARUA=y
+CONFIG_ION=y
+CONFIG_ION_MSM=y
+CONFIG_MSM_KGSL=y
+CONFIG_MSM_KGSL_DISABLE_SHADOW_WRITES=y
+CONFIG_KGSL_PER_PROCESS_PAGE_TABLE=y
+CONFIG_MSM_KGSL_PAGE_TABLE_COUNT=24
+CONFIG_FB=y
+CONFIG_FB_MSM=y
+# CONFIG_FB_MSM_BACKLIGHT is not set
+CONFIG_FB_MSM_TRIPLE_BUFFER=y
+CONFIG_FB_MSM_MDP30=y
+CONFIG_FB_MSM_MDP303=y
+CONFIG_FB_MSM_MIPI_DIV4_WVGA_NT35510_PANEL=y
+CONFIG_FB_MSM_LCDC_TRULY_HVGA_IPS3P2335_PT_PANEL=y
+CONFIG_FB_MSM_MIPI_PANEL_DETECT=y
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+CONFIG_SOUND=y
+CONFIG_SND=y
+CONFIG_SND_SOC=y
+CONFIG_SND_MSM_SOC=y
+CONFIG_HID_APPLE=y
+CONFIG_HID_MAGICMOUSE=y
+CONFIG_HID_MICROSOFT=y
+CONFIG_USB=y
+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
+CONFIG_USB_SUSPEND=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_EHSET=y
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
+# CONFIG_USB_EHCI_TT_NEWSCHED is not set
+CONFIG_USB_EHCI_MSM_72K=y
+CONFIG_USB_ACM=y
+CONFIG_USB_STORAGE=y
+CONFIG_USB_STORAGE_DATAFAB=y
+CONFIG_USB_STORAGE_FREECOM=y
+CONFIG_USB_STORAGE_ISD200=y
+CONFIG_USB_STORAGE_USBAT=y
+CONFIG_USB_STORAGE_SDDR09=y
+CONFIG_USB_STORAGE_SDDR55=y
+CONFIG_USB_STORAGE_JUMPSHOT=y
+CONFIG_USB_STORAGE_ALAUDA=y
+CONFIG_USB_STORAGE_ONETOUCH=y
+CONFIG_USB_STORAGE_KARMA=y
+CONFIG_USB_STORAGE_CYPRESS_ATACB=y
+CONFIG_USB_EHSET_TEST_FIXTURE=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_MSM_72K=y
+CONFIG_USB_G_ANDROID=y
+CONFIG_RMNET_SMD_CTL_CHANNEL="DATA40_CNTL"
+CONFIG_RMNET_SMD_DATA_CHANNEL="DATA40"
+CONFIG_MMC=y
+CONFIG_MMC_PERF_PROFILING=y
+CONFIG_MMC_UNSAFE_RESUME=y
+CONFIG_MMC_CLKGATE=y
+CONFIG_MMC_PARANOID_SD_INIT=y
+CONFIG_MMC_BLOCK_MINORS=32
+# CONFIG_MMC_BLOCK_BOUNCE is not set
+CONFIG_MMC_TEST=m
+CONFIG_MMC_MSM=y
+CONFIG_MMC_MSM_SDC3_SUPPORT=y
+CONFIG_MMC_MSM_SDC3_8_BIT_SUPPORT=y
+CONFIG_LEDS_MSM_PDM=y
+CONFIG_LEDS_PMIC_MPP=y
+CONFIG_LEDS_MSM_TRICOLOR=y
+CONFIG_LEDS_GPIO=y
+CONFIG_SWITCH=y
+CONFIG_SWITCH_GPIO=y
+CONFIG_RTC_CLASS=y
+CONFIG_STAGING=y
+CONFIG_ANDROID=y
+CONFIG_ANDROID_BINDER_IPC=y
+CONFIG_ANDROID_LOGGER=y
+CONFIG_ANDROID_LOW_MEMORY_KILLER=y
+CONFIG_ANDROID_LOW_MEMORY_KILLER_AUTODETECT_OOM_ADJ_VALUES=y
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
+CONFIG_EXT4_FS=y
+CONFIG_FUSE_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_TMPFS=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_PRINTK_TIME=y
+CONFIG_PRINTK_RTC_TIME=y
+CONFIG_PRINTK_CPU_ID=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_SHIRQ=y
+# CONFIG_DEBUG_PREEMPT is not set
+# CONFIG_SCHED_DEBUG is not set
+CONFIG_TIMER_STATS=y
+CONFIG_DEBUG_SPINLOCK=y
+CONFIG_DEBUG_STACK_USAGE=y
+CONFIG_DEBUG_INFO=y
+CONFIG_ENABLE_DEFAULT_TRACERS=y
+CONFIG_DYNAMIC_DEBUG=y
+CONFIG_DEBUG_USER=y
+CONFIG_CRYPTO_TWOFISH=y
+CONFIG_CRC_CCITT=y
+# Add 20120823 TS-FMC-V2 start
+CONFIG_FB_MSM_MIPI_OTM9608A_PT=y
+CONFIG_PPP=y
+CONFIG_PPP_ASYNC=y
+CONFIG_PPP_DEFLATE=y
+CONFIG_PPP_BSDCOMP=y
+CONFIG_INET_AH=y
+CONFIG_INET_ESP=y
+CONFIG_INET_IPCOMP=y
+CONFIG_L2TP=y
+CONFIG_L2TP_V3=y
+CONFIG_L2TP_IP=y
+CONFIG_L2TP_ETH=y
+CONFIG_IPX=y
+CONFIG_IPX_INTERN=y
+CONFIG_PPP_FILTER=y
+CONFIG_PPP_MPPE=y
+CONFIG_PPP_MULTILINK=y
+CONFIG_PPPOE=y
+CONFIG_PPPOL2TP=y
+CONFIG_PPPOLAC=y
+CONFIG_PPPOPNS=y
+CONFIG_PPP_SYNC_TTY=y
+CONFIG_TCP_MD5SIG=y
+# Add 20120823 TS-FMC-V2 end
+ONFIG_GLANCEVIEW=y
+#===================================================#
+# Added for apanic emmc #
+#===================================================#
+CONFIG_APANIC_MMC=y
+CONFIG_MMC_MSM_RAW=y
+CONFIG_LOG_BUF_SHIFT=16
diff --git a/arch/arm/configs/normandy_b2_defconfig b/arch/arm/configs/normandy_b2_defconfig
new file mode 100755
index 0000000..a8cc227
--- /dev/null
+++ b/arch/arm/configs/normandy_b2_defconfig
@@ -0,0 +1,436 @@
+# CONFIG_ARM_PATCH_PHYS_VIRT is not set
+CONFIG_EXPERIMENTAL=y
+CONFIG_LOCALVERSION="$(KERNEL_LOCAL_VERSION)-perf"
+CONFIG_SWAP=y
+CONFIG_ZRAM=m
+CONFIG_SYSVIPC=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_CGROUPS=y
+CONFIG_CGROUP_FREEZER=y
+CONFIG_CGROUP_DEVICE=y
+CONFIG_CGROUP_CPUACCT=y
+CONFIG_RESOURCE_COUNTERS=y
+CONFIG_CGROUP_MEM_RES_CTLR=y
+CONFIG_CGROUP_MEM_RES_CTLR_SWAP=y
+CONFIG_CGROUP_SCHED=y
+CONFIG_RT_GROUP_SCHED=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_KALLSYMS_ALL=y
+CONFIG_ASHMEM=y
+CONFIG_EMBEDDED=y
+CONFIG_PROFILING=y
+CONFIG_OPROFILE=y
+CONFIG_KPROBES=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+# CONFIG_BLK_DEV_BSG is not set
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_IOSCHED_DEADLINE is not set
+CONFIG_ARCH_MSM=y
+CONFIG_ARCH_MSM7X27=y
+CONFIG_ARCH_MSM8625=y
+CONFIG_MSM_SOC_REV_A=y
+# CONFIG_MACH_MSM7X27_SURF is not set
+# CONFIG_MACH_MSM7X27_FFA is not set
+# CONFIG_MSM_STACKED_MEMORY is not set
+CONFIG_MSM7X00A_USE_DG_TIMER=y
+# CONFIG_MSM_FIQ_SUPPORT is not set
+CONFIG_KSM=y
+CONFIG_MSM_SMD=y
+CONFIG_MSM_AMSS_ENHANCE_DEBUG=y
+CONFIG_MSM_SMD_PKG4=y
+# CONFIG_MSM_SMD_DEBUG is not set
+# CONFIG_MSM_RESET_MODEM is not set
+# CONFIG_MSM_SMD_NMEA is not set
+# CONFIG_MSM_SMD_QMI is not set
+CONFIG_MSM_ONCRPCROUTER=y
+CONFIG_MSM_IPC_ROUTER=y
+# CONFIG_MSM_RPCSERVER_TIME_REMOTE is not set
+CONFIG_MSM_RMT_STORAGE_CLIENT=y
+# CONFIG_MSM_HW3D is not set
+CONFIG_MSM7X27A_AUDIO=y
+CONFIG_MSM_DMA_TEST=y
+CONFIG_MSM_SLEEP_STATS_DEVICE=y
+CONFIG_MSM_SM_EVENT=y
+CONFIG_MSM_SM_EVENT_LOG=m
+CONFIG_MSM_SLEEP_MONITOR=m
+CONFIG_MSM_FAST_BOOT=y
+CONFIG_BT_MSM_PINTEST=y
+CONFIG_MSM_RPC_VIBRATOR=y
+CONFIG_PM8XXX_RPC_VIBRATOR=y
+CONFIG_MSM_SPM_V2=y
+CONFIG_MSM_MULTIMEDIA_USE_ION=y
+CONFIG_MSM_FUSE_INFO_DEBUG=y
+CONFIG_MSM_CPR=y
+CONFIG_MSM_VP_REGULATOR=y
+CONFIG_MSM_FIQ=y
+CONFIG_MSM_PBUS=y
+CONFIG_ARM_THUMBEE=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_SMP=y
+CONFIG_PREEMPT=y
+CONFIG_AEABI=y
+CONFIG_HIGHMEM=y
+CONFIG_VMALLOC_RESERVE=0xC800000
+CONFIG_COMPACTION=y
+CONFIG_CP_ACCESS=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="init=/sbin/init root=/dev/ram rw initrd=0x11000000,16M console=ttyDCC0 mem=88M"
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_STAT_DETAILS=y
+CONFIG_CPU_FREQ_GOV_POWERSAVE=y
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_GOV_ONDEMAND=y
+CONFIG_CPU_FREQ_GOV_INTERACTIVE=y
+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
+CONFIG_VFP=y
+CONFIG_NEON=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_WAKELOCK=y
+CONFIG_PM_RUNTIME=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_IP_MULTIPLE_TABLES=y
+CONFIG_IPV6=y
+CONFIG_IPV6_PRIVACY=y
+CONFIG_IPV6_ROUTER_PREF=y
+CONFIG_IPV6_ROUTE_INFO=y
+CONFIG_IPV6_OPTIMISTIC_DAD=y
+CONFIG_INET6_AH=y
+CONFIG_INET6_ESP=y
+CONFIG_INET6_IPCOMP=y
+CONFIG_IPV6_MIP6=y
+CONFIG_IPV6_TUNNEL=y
+CONFIG_IPV6_MULTIPLE_TABLES=y
+CONFIG_IPV6_SUBTREES=y
+CONFIG_NETFILTER=y
+CONFIG_NETFILTER_NETLINK_LOG=y
+CONFIG_NF_CONNTRACK=y
+CONFIG_NF_CONNTRACK_EVENTS=y
+CONFIG_NF_CT_PROTO_DCCP=y
+CONFIG_NF_CT_PROTO_SCTP=y
+CONFIG_NF_CT_PROTO_UDPLITE=y
+CONFIG_NF_CONNTRACK_AMANDA=y
+CONFIG_NF_CONNTRACK_FTP=y
+CONFIG_NF_CONNTRACK_H323=y
+CONFIG_NF_CONNTRACK_IRC=y
+CONFIG_NF_CONNTRACK_NETBIOS_NS=y
+CONFIG_NF_CONNTRACK_PPTP=y
+CONFIG_NF_CONNTRACK_SANE=y
+CONFIG_NF_CONNTRACK_SIP=y
+CONFIG_NF_CONNTRACK_TFTP=y
+CONFIG_NF_CT_NETLINK=y
+CONFIG_NETFILTER_TPROXY=y
+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=y
+CONFIG_NETFILTER_XT_TARGET_CONNMARK=y
+CONFIG_NETFILTER_XT_TARGET_LOG=y
+CONFIG_NETFILTER_XT_TARGET_MARK=y
+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=y
+CONFIG_NETFILTER_XT_MATCH_COMMENT=y
+CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=y
+CONFIG_NETFILTER_XT_MATCH_CONNMARK=y
+CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y
+CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=y
+CONFIG_NETFILTER_XT_MATCH_HELPER=y
+CONFIG_NETFILTER_XT_MATCH_IPRANGE=y
+CONFIG_NETFILTER_XT_MATCH_LENGTH=y
+CONFIG_NETFILTER_XT_MATCH_LIMIT=y
+CONFIG_NETFILTER_XT_MATCH_MAC=y
+CONFIG_NETFILTER_XT_MATCH_MARK=y
+CONFIG_NETFILTER_XT_MATCH_POLICY=y
+CONFIG_NETFILTER_XT_MATCH_PKTTYPE=y
+CONFIG_NETFILTER_XT_MATCH_QTAGUID=y
+CONFIG_NETFILTER_XT_MATCH_QUOTA=y
+CONFIG_NETFILTER_XT_MATCH_QUOTA2=y
+CONFIG_NETFILTER_XT_MATCH_QUOTA2_LOG=y
+CONFIG_NETFILTER_XT_MATCH_SOCKET=y
+CONFIG_NETFILTER_XT_MATCH_STATE=y
+CONFIG_NETFILTER_XT_MATCH_STATISTIC=y
+CONFIG_NETFILTER_XT_MATCH_STRING=y
+CONFIG_NETFILTER_XT_MATCH_TIME=y
+CONFIG_NETFILTER_XT_MATCH_U32=y
+CONFIG_NF_CONNTRACK_IPV4=y
+CONFIG_IP_NF_IPTABLES=y
+CONFIG_IP_NF_MATCH_AH=y
+CONFIG_IP_NF_MATCH_ECN=y
+CONFIG_IP_NF_MATCH_TTL=y
+CONFIG_IP_NF_FILTER=y
+CONFIG_IP_NF_TARGET_REJECT=y
+CONFIG_NF_NAT=y
+CONFIG_IP_NF_TARGET_MASQUERADE=y
+CONFIG_IP_NF_TARGET_NETMAP=y
+CONFIG_IP_NF_TARGET_REDIRECT=y
+CONFIG_IP_NF_MANGLE=y
+CONFIG_IP_NF_RAW=y
+CONFIG_IP_NF_ARPTABLES=y
+CONFIG_IP_NF_ARPFILTER=y
+CONFIG_IP_NF_ARP_MANGLE=y
+CONFIG_IP6_NF_IPTABLES=y
+CONFIG_IP6_NF_FILTER=y
+CONFIG_IP6_NF_MANGLE=y
+CONFIG_IP6_NF_RAW=y
+CONFIG_BT=y
+CONFIG_BT_RFCOMM=y
+CONFIG_BT_RFCOMM_TTY=y
+CONFIG_BT_BNEP=y
+CONFIG_BT_BNEP_MC_FILTER=y
+CONFIG_BT_BNEP_PROTO_FILTER=y
+CONFIG_BT_HIDP=y
+CONFIG_BT_HCIUART=y
+CONFIG_BT_HCIUART_H4=y
+CONFIG_BT_HCIUART_IBS=y
+CONFIG_MSM_BT_POWER=y
+CONFIG_CFG80211=m
+# CONFIG_CFG80211_WEXT is not set
+CONFIG_RFKILL=y
+CONFIG_GENLOCK=y
+CONFIG_GENLOCK_MISCDEVICE=y
+CONFIG_MTD=n
+CONFIG_MTD_TESTS=n
+CONFIG_MTD_CMDLINE_PARTS=n
+CONFIG_MTD_CHAR=n
+CONFIG_MTD_BLOCK=n
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_MISC_DEVICES=y
+#byd CONFIG_SENSORS_AK8975=y
+#byd CONFIG_MPU_SENSORS_TIMERIRQ=y
+#byd CONFIG_MPU_SENSORS_BMA250=y
+#byd CONFIG_MPU_SENSORS_MMC328X=y
+CONFIG_SENSORS_BMA2X2=y
+CONFIG_SENSORS_LTR559=y
+CONFIG_SCSI=y
+CONFIG_SCSI_TGT=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_CHR_DEV_SG=y
+CONFIG_CHR_DEV_SCH=y
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_LOGGING=y
+CONFIG_SCSI_SCAN_ASYNC=y
+CONFIG_MD=y
+CONFIG_BLK_DEV_DM=y
+CONFIG_DM_CRYPT=y
+CONFIG_NETDEVICES=y
+CONFIG_TUN=y
+CONFIG_SMC91X=y
+CONFIG_SMSC911X=y
+CONFIG_LIBRA_SDIOIF=m
+# CONFIG_INPUT_MOUSEDEV is not set
+CONFIG_INPUT_EVDEV=y
+CONFIG_INPUT_EVBUG=m
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+#byd rm CONFIG_TOUCHSCREEN_ATMEL_MAXTOUCH=y
+#byd rm CONFIG_TOUCHSCREEN_ATMEL_MXT=y
+CONFIG_TOUCHSCREEN_SYNAPTICS_RMI4_I2C=y
+#byd rm CONFIG_TOUCHSCREEN_FT5X06=y
+# CONFIG_TOUCHSCREEN_FOCAL=y
+CONFIG_TOUCHSCREEN_FT6306=y
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_UINPUT=y
+CONFIG_INPUT_GPIO=y
+#byd rm CONFIG_INPUT_LTR502=y
+#byd rm CONFIG_INPUT_LTR558=y
+#byd rm CONFIG_BOSCH_BMA250=y
+#byd rm CONFIG_INPUT_ISL29028=y
+#byd rm CONFIG_INPUT_LIS3DH=y
+#byd rm CONFIG_AVAGO_APDS990X=y
+#byd rm CONFIG_SENSORS_TMD2771X=y
+# CONFIG_SERIO is not set
+# CONFIG_LEGACY_PTYS is not set
+CONFIG_SERIAL_MSM=y
+CONFIG_SERIAL_MSM_CONSOLE=y
+CONFIG_SERIAL_MSM_HS=y
+# CONFIG_SERIAL_MSM_CLOCK_CONTROL is not set
+CONFIG_DIAG_CHAR=y
+# CONFIG_HW_RANDOM is not set
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_GPIO=y
+# CONFIG_I2C_MSM is not set
+CONFIG_I2C_QUP=y
+CONFIG_DEBUG_GPIO=y
+CONFIG_GPIO_SYSFS=y
+CONFIG_GPIO_SX150X=y
+CONFIG_POWER_SUPPLY=y
+CONFIG_BATTERY_MSM=y
+CONFIG_SENSORS_MSM_ADC=y
+CONFIG_MARIMBA_CORE=y
+CONFIG_REGULATOR_FAN53555=y
+CONFIG_REGULATOR_ONSEMI_NCP6335D=y
+CONFIG_REGULATOR_MSM_GPIO=y
+CONFIG_MEDIA_SUPPORT=y
+CONFIG_MEDIA_CONTROLLER=y
+CONFIG_VIDEO_DEV=y
+CONFIG_VIDEO_V4L2_SUBDEV_API=y
+# CONFIG_RC_CORE is not set
+# CONFIG_MEDIA_TUNER_CUSTOMISE is not set
+CONFIG_VIDEOBUF2_MSM_MEM=y
+CONFIG_V4L_PLATFORM_DRIVERS=y
+CONFIG_MSM_CAMERA_V4L2=y
+# CONFIG_OV5647 is not set
+# CONFIG_OV5647_DALING_OVBD631AC is not set
+CONFIG_S5K5CA=y
+CONFIG_S5K5CA_DARLING=y
+# CONFIG_HI351_SUNNY_Q3H01B is not set
+# CONFIG_OV5647_PARTRON_CM500 is not set
+# CONFIG_OV5647_HQ_O9B5_DG806T=y
+CONFIG_AR0542=y
+# CONFIG_OV5647_TRULY_CM6868 is not set
+# CONFIG_OV5648_TRULY_CM8352=y
+CONFIG_AD5046_ACT=y
+#byd rm CONFIG_WEBCAM_OV9726=y
+#byd rm CONFIG_MT9E013=y
+#byd rm CONFIG_S5K4E1=y
+#byd rm CONFIG_DW9712_ACT=y
+#CONFIG_MSM_CAMERA_FLASH_SC628A=y
+CONFIG_OV8825=y
+CONFIG_MSM_CAMERA_SENSOR=y
+CONFIG_MSM_ACTUATOR=y
+#CONFIG_OV7692=y
+# CONFIG_WEBCAM_OV7692_QRD is not set
+# CONFIG_OV7695 is not set
+# CONFIG_OV7695_RAW=y
+# CONFIG_MT9V115=y
+CONFIG_RADIO_TAVARUA=y
+CONFIG_ION=y
+CONFIG_ION_MSM=y
+CONFIG_MSM_KGSL=y
+CONFIG_MSM_KGSL_DISABLE_SHADOW_WRITES=y
+CONFIG_FB=y
+CONFIG_FB_MSM=y
+# CONFIG_FB_MSM_BACKLIGHT is not set
+CONFIG_FB_MSM_TRIPLE_BUFFER=y
+CONFIG_FB_MSM_MDP30=y
+CONFIG_FB_MSM_MDP303=y
+CONFIG_FB_MSM_MIPI_DIV4_WVGA_NT35510_PANEL=y
+CONFIG_FB_MSM_LCDC_TRULY_HVGA_IPS3P2335_PT_PANEL=y
+CONFIG_FB_MSM_MIPI_PANEL_DETECT=y
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+CONFIG_SOUND=y
+CONFIG_SND=y
+CONFIG_SND_SOC=y
+CONFIG_SND_MSM_SOC=y
+CONFIG_HID_APPLE=y
+CONFIG_HID_MAGICMOUSE=y
+CONFIG_HID_MICROSOFT=y
+CONFIG_USB=y
+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
+CONFIG_USB_SUSPEND=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_EHSET=y
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
+# CONFIG_USB_EHCI_TT_NEWSCHED is not set
+CONFIG_USB_EHCI_MSM_72K=y
+CONFIG_USB_ACM=y
+CONFIG_USB_STORAGE=y
+CONFIG_USB_STORAGE_DATAFAB=y
+CONFIG_USB_STORAGE_FREECOM=y
+CONFIG_USB_STORAGE_ISD200=y
+CONFIG_USB_STORAGE_USBAT=y
+CONFIG_USB_STORAGE_SDDR09=y
+CONFIG_USB_STORAGE_SDDR55=y
+CONFIG_USB_STORAGE_JUMPSHOT=y
+CONFIG_USB_STORAGE_ALAUDA=y
+CONFIG_USB_STORAGE_ONETOUCH=y
+CONFIG_USB_STORAGE_KARMA=y
+CONFIG_USB_STORAGE_CYPRESS_ATACB=y
+CONFIG_USB_EHSET_TEST_FIXTURE=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_MSM_72K=y
+CONFIG_USB_G_ANDROID=y
+CONFIG_RMNET_SMD_CTL_CHANNEL="DATA40_CNTL"
+CONFIG_RMNET_SMD_DATA_CHANNEL="DATA40"
+CONFIG_MMC=y
+CONFIG_MMC_PERF_PROFILING=y
+CONFIG_MMC_UNSAFE_RESUME=y
+CONFIG_MMC_CLKGATE=y
+CONFIG_MMC_PARANOID_SD_INIT=y
+CONFIG_MMC_BLOCK_MINORS=32
+# CONFIG_MMC_BLOCK_BOUNCE is not set
+CONFIG_MMC_TEST=m
+CONFIG_MMC_MSM=y
+CONFIG_MMC_MSM_SDC3_SUPPORT=y
+CONFIG_MMC_MSM_SDC3_8_BIT_SUPPORT=y
+CONFIG_LEDS_MSM_PDM=y
+CONFIG_LEDS_PMIC_MPP=y
+CONFIG_LEDS_MSM_TRICOLOR=y
+CONFIG_LEDS_GPIO=y
+CONFIG_SWITCH=y
+CONFIG_SWITCH_GPIO=y
+CONFIG_RTC_CLASS=y
+CONFIG_STAGING=y
+CONFIG_ANDROID=y
+CONFIG_ANDROID_BINDER_IPC=y
+CONFIG_ANDROID_LOGGER=y
+CONFIG_ANDROID_LOW_MEMORY_KILLER=y
+CONFIG_ANDROID_LOW_MEMORY_KILLER_AUTODETECT_OOM_ADJ_VALUES=y
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
+CONFIG_EXT4_FS=y
+CONFIG_FUSE_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_TMPFS=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_PRINTK_TIME=y
+CONFIG_PRINTK_RTC_TIME=y
+CONFIG_PRINTK_CPU_ID=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_SHIRQ=y
+# CONFIG_DEBUG_PREEMPT is not set
+# CONFIG_SCHED_DEBUG is not set
+CONFIG_TIMER_STATS=y
+CONFIG_DEBUG_SPINLOCK=y
+CONFIG_DEBUG_STACK_USAGE=y
+CONFIG_DEBUG_INFO=y
+CONFIG_ENABLE_DEFAULT_TRACERS=y
+CONFIG_DYNAMIC_DEBUG=y
+CONFIG_DEBUG_USER=y
+CONFIG_CRYPTO_TWOFISH=y
+CONFIG_CRC_CCITT=y
+# Add 20120823 TS-FMC-V2 start
+CONFIG_FB_MSM_MIPI_OTM9608A_PT=y
+CONFIG_PPP=y
+CONFIG_PPP_ASYNC=y
+CONFIG_PPP_DEFLATE=y
+CONFIG_PPP_BSDCOMP=y
+CONFIG_INET_AH=y
+CONFIG_INET_ESP=y
+CONFIG_INET_IPCOMP=y
+CONFIG_L2TP=y
+CONFIG_L2TP_V3=y
+CONFIG_L2TP_IP=y
+CONFIG_L2TP_ETH=y
+CONFIG_IPX=y
+CONFIG_IPX_INTERN=y
+CONFIG_PPP_FILTER=y
+CONFIG_PPP_MPPE=y
+CONFIG_PPP_MULTILINK=y
+CONFIG_PPPOE=y
+CONFIG_PPPOL2TP=y
+CONFIG_PPPOLAC=y
+CONFIG_PPPOPNS=y
+CONFIG_PPP_SYNC_TTY=y
+CONFIG_TCP_MD5SIG=y
+# Add 20120823 TS-FMC-V2 end
+ONFIG_GLANCEVIEW=y
+#===================================================#
+# Added for apanic emmc #
+#===================================================#
+CONFIG_APANIC_MMC=y
+CONFIG_MMC_MSM_RAW=y
+CONFIG_LOG_BUF_SHIFT=20
diff --git a/arch/arm/configs/normandy_b3_defconfig b/arch/arm/configs/normandy_b3_defconfig
new file mode 100755
index 0000000..a8cc227
--- /dev/null
+++ b/arch/arm/configs/normandy_b3_defconfig
@@ -0,0 +1,436 @@
+# CONFIG_ARM_PATCH_PHYS_VIRT is not set
+CONFIG_EXPERIMENTAL=y
+CONFIG_LOCALVERSION="$(KERNEL_LOCAL_VERSION)-perf"
+CONFIG_SWAP=y
+CONFIG_ZRAM=m
+CONFIG_SYSVIPC=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_CGROUPS=y
+CONFIG_CGROUP_FREEZER=y
+CONFIG_CGROUP_DEVICE=y
+CONFIG_CGROUP_CPUACCT=y
+CONFIG_RESOURCE_COUNTERS=y
+CONFIG_CGROUP_MEM_RES_CTLR=y
+CONFIG_CGROUP_MEM_RES_CTLR_SWAP=y
+CONFIG_CGROUP_SCHED=y
+CONFIG_RT_GROUP_SCHED=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_KALLSYMS_ALL=y
+CONFIG_ASHMEM=y
+CONFIG_EMBEDDED=y
+CONFIG_PROFILING=y
+CONFIG_OPROFILE=y
+CONFIG_KPROBES=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+# CONFIG_BLK_DEV_BSG is not set
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_IOSCHED_DEADLINE is not set
+CONFIG_ARCH_MSM=y
+CONFIG_ARCH_MSM7X27=y
+CONFIG_ARCH_MSM8625=y
+CONFIG_MSM_SOC_REV_A=y
+# CONFIG_MACH_MSM7X27_SURF is not set
+# CONFIG_MACH_MSM7X27_FFA is not set
+# CONFIG_MSM_STACKED_MEMORY is not set
+CONFIG_MSM7X00A_USE_DG_TIMER=y
+# CONFIG_MSM_FIQ_SUPPORT is not set
+CONFIG_KSM=y
+CONFIG_MSM_SMD=y
+CONFIG_MSM_AMSS_ENHANCE_DEBUG=y
+CONFIG_MSM_SMD_PKG4=y
+# CONFIG_MSM_SMD_DEBUG is not set
+# CONFIG_MSM_RESET_MODEM is not set
+# CONFIG_MSM_SMD_NMEA is not set
+# CONFIG_MSM_SMD_QMI is not set
+CONFIG_MSM_ONCRPCROUTER=y
+CONFIG_MSM_IPC_ROUTER=y
+# CONFIG_MSM_RPCSERVER_TIME_REMOTE is not set
+CONFIG_MSM_RMT_STORAGE_CLIENT=y
+# CONFIG_MSM_HW3D is not set
+CONFIG_MSM7X27A_AUDIO=y
+CONFIG_MSM_DMA_TEST=y
+CONFIG_MSM_SLEEP_STATS_DEVICE=y
+CONFIG_MSM_SM_EVENT=y
+CONFIG_MSM_SM_EVENT_LOG=m
+CONFIG_MSM_SLEEP_MONITOR=m
+CONFIG_MSM_FAST_BOOT=y
+CONFIG_BT_MSM_PINTEST=y
+CONFIG_MSM_RPC_VIBRATOR=y
+CONFIG_PM8XXX_RPC_VIBRATOR=y
+CONFIG_MSM_SPM_V2=y
+CONFIG_MSM_MULTIMEDIA_USE_ION=y
+CONFIG_MSM_FUSE_INFO_DEBUG=y
+CONFIG_MSM_CPR=y
+CONFIG_MSM_VP_REGULATOR=y
+CONFIG_MSM_FIQ=y
+CONFIG_MSM_PBUS=y
+CONFIG_ARM_THUMBEE=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_SMP=y
+CONFIG_PREEMPT=y
+CONFIG_AEABI=y
+CONFIG_HIGHMEM=y
+CONFIG_VMALLOC_RESERVE=0xC800000
+CONFIG_COMPACTION=y
+CONFIG_CP_ACCESS=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="init=/sbin/init root=/dev/ram rw initrd=0x11000000,16M console=ttyDCC0 mem=88M"
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_STAT_DETAILS=y
+CONFIG_CPU_FREQ_GOV_POWERSAVE=y
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_GOV_ONDEMAND=y
+CONFIG_CPU_FREQ_GOV_INTERACTIVE=y
+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
+CONFIG_VFP=y
+CONFIG_NEON=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_WAKELOCK=y
+CONFIG_PM_RUNTIME=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_IP_MULTIPLE_TABLES=y
+CONFIG_IPV6=y
+CONFIG_IPV6_PRIVACY=y
+CONFIG_IPV6_ROUTER_PREF=y
+CONFIG_IPV6_ROUTE_INFO=y
+CONFIG_IPV6_OPTIMISTIC_DAD=y
+CONFIG_INET6_AH=y
+CONFIG_INET6_ESP=y
+CONFIG_INET6_IPCOMP=y
+CONFIG_IPV6_MIP6=y
+CONFIG_IPV6_TUNNEL=y
+CONFIG_IPV6_MULTIPLE_TABLES=y
+CONFIG_IPV6_SUBTREES=y
+CONFIG_NETFILTER=y
+CONFIG_NETFILTER_NETLINK_LOG=y
+CONFIG_NF_CONNTRACK=y
+CONFIG_NF_CONNTRACK_EVENTS=y
+CONFIG_NF_CT_PROTO_DCCP=y
+CONFIG_NF_CT_PROTO_SCTP=y
+CONFIG_NF_CT_PROTO_UDPLITE=y
+CONFIG_NF_CONNTRACK_AMANDA=y
+CONFIG_NF_CONNTRACK_FTP=y
+CONFIG_NF_CONNTRACK_H323=y
+CONFIG_NF_CONNTRACK_IRC=y
+CONFIG_NF_CONNTRACK_NETBIOS_NS=y
+CONFIG_NF_CONNTRACK_PPTP=y
+CONFIG_NF_CONNTRACK_SANE=y
+CONFIG_NF_CONNTRACK_SIP=y
+CONFIG_NF_CONNTRACK_TFTP=y
+CONFIG_NF_CT_NETLINK=y
+CONFIG_NETFILTER_TPROXY=y
+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=y
+CONFIG_NETFILTER_XT_TARGET_CONNMARK=y
+CONFIG_NETFILTER_XT_TARGET_LOG=y
+CONFIG_NETFILTER_XT_TARGET_MARK=y
+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=y
+CONFIG_NETFILTER_XT_MATCH_COMMENT=y
+CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=y
+CONFIG_NETFILTER_XT_MATCH_CONNMARK=y
+CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y
+CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=y
+CONFIG_NETFILTER_XT_MATCH_HELPER=y
+CONFIG_NETFILTER_XT_MATCH_IPRANGE=y
+CONFIG_NETFILTER_XT_MATCH_LENGTH=y
+CONFIG_NETFILTER_XT_MATCH_LIMIT=y
+CONFIG_NETFILTER_XT_MATCH_MAC=y
+CONFIG_NETFILTER_XT_MATCH_MARK=y
+CONFIG_NETFILTER_XT_MATCH_POLICY=y
+CONFIG_NETFILTER_XT_MATCH_PKTTYPE=y
+CONFIG_NETFILTER_XT_MATCH_QTAGUID=y
+CONFIG_NETFILTER_XT_MATCH_QUOTA=y
+CONFIG_NETFILTER_XT_MATCH_QUOTA2=y
+CONFIG_NETFILTER_XT_MATCH_QUOTA2_LOG=y
+CONFIG_NETFILTER_XT_MATCH_SOCKET=y
+CONFIG_NETFILTER_XT_MATCH_STATE=y
+CONFIG_NETFILTER_XT_MATCH_STATISTIC=y
+CONFIG_NETFILTER_XT_MATCH_STRING=y
+CONFIG_NETFILTER_XT_MATCH_TIME=y
+CONFIG_NETFILTER_XT_MATCH_U32=y
+CONFIG_NF_CONNTRACK_IPV4=y
+CONFIG_IP_NF_IPTABLES=y
+CONFIG_IP_NF_MATCH_AH=y
+CONFIG_IP_NF_MATCH_ECN=y
+CONFIG_IP_NF_MATCH_TTL=y
+CONFIG_IP_NF_FILTER=y
+CONFIG_IP_NF_TARGET_REJECT=y
+CONFIG_NF_NAT=y
+CONFIG_IP_NF_TARGET_MASQUERADE=y
+CONFIG_IP_NF_TARGET_NETMAP=y
+CONFIG_IP_NF_TARGET_REDIRECT=y
+CONFIG_IP_NF_MANGLE=y
+CONFIG_IP_NF_RAW=y
+CONFIG_IP_NF_ARPTABLES=y
+CONFIG_IP_NF_ARPFILTER=y
+CONFIG_IP_NF_ARP_MANGLE=y
+CONFIG_IP6_NF_IPTABLES=y
+CONFIG_IP6_NF_FILTER=y
+CONFIG_IP6_NF_MANGLE=y
+CONFIG_IP6_NF_RAW=y
+CONFIG_BT=y
+CONFIG_BT_RFCOMM=y
+CONFIG_BT_RFCOMM_TTY=y
+CONFIG_BT_BNEP=y
+CONFIG_BT_BNEP_MC_FILTER=y
+CONFIG_BT_BNEP_PROTO_FILTER=y
+CONFIG_BT_HIDP=y
+CONFIG_BT_HCIUART=y
+CONFIG_BT_HCIUART_H4=y
+CONFIG_BT_HCIUART_IBS=y
+CONFIG_MSM_BT_POWER=y
+CONFIG_CFG80211=m
+# CONFIG_CFG80211_WEXT is not set
+CONFIG_RFKILL=y
+CONFIG_GENLOCK=y
+CONFIG_GENLOCK_MISCDEVICE=y
+CONFIG_MTD=n
+CONFIG_MTD_TESTS=n
+CONFIG_MTD_CMDLINE_PARTS=n
+CONFIG_MTD_CHAR=n
+CONFIG_MTD_BLOCK=n
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_MISC_DEVICES=y
+#byd CONFIG_SENSORS_AK8975=y
+#byd CONFIG_MPU_SENSORS_TIMERIRQ=y
+#byd CONFIG_MPU_SENSORS_BMA250=y
+#byd CONFIG_MPU_SENSORS_MMC328X=y
+CONFIG_SENSORS_BMA2X2=y
+CONFIG_SENSORS_LTR559=y
+CONFIG_SCSI=y
+CONFIG_SCSI_TGT=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_CHR_DEV_SG=y
+CONFIG_CHR_DEV_SCH=y
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_LOGGING=y
+CONFIG_SCSI_SCAN_ASYNC=y
+CONFIG_MD=y
+CONFIG_BLK_DEV_DM=y
+CONFIG_DM_CRYPT=y
+CONFIG_NETDEVICES=y
+CONFIG_TUN=y
+CONFIG_SMC91X=y
+CONFIG_SMSC911X=y
+CONFIG_LIBRA_SDIOIF=m
+# CONFIG_INPUT_MOUSEDEV is not set
+CONFIG_INPUT_EVDEV=y
+CONFIG_INPUT_EVBUG=m
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+#byd rm CONFIG_TOUCHSCREEN_ATMEL_MAXTOUCH=y
+#byd rm CONFIG_TOUCHSCREEN_ATMEL_MXT=y
+CONFIG_TOUCHSCREEN_SYNAPTICS_RMI4_I2C=y
+#byd rm CONFIG_TOUCHSCREEN_FT5X06=y
+# CONFIG_TOUCHSCREEN_FOCAL=y
+CONFIG_TOUCHSCREEN_FT6306=y
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_UINPUT=y
+CONFIG_INPUT_GPIO=y
+#byd rm CONFIG_INPUT_LTR502=y
+#byd rm CONFIG_INPUT_LTR558=y
+#byd rm CONFIG_BOSCH_BMA250=y
+#byd rm CONFIG_INPUT_ISL29028=y
+#byd rm CONFIG_INPUT_LIS3DH=y
+#byd rm CONFIG_AVAGO_APDS990X=y
+#byd rm CONFIG_SENSORS_TMD2771X=y
+# CONFIG_SERIO is not set
+# CONFIG_LEGACY_PTYS is not set
+CONFIG_SERIAL_MSM=y
+CONFIG_SERIAL_MSM_CONSOLE=y
+CONFIG_SERIAL_MSM_HS=y
+# CONFIG_SERIAL_MSM_CLOCK_CONTROL is not set
+CONFIG_DIAG_CHAR=y
+# CONFIG_HW_RANDOM is not set
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_GPIO=y
+# CONFIG_I2C_MSM is not set
+CONFIG_I2C_QUP=y
+CONFIG_DEBUG_GPIO=y
+CONFIG_GPIO_SYSFS=y
+CONFIG_GPIO_SX150X=y
+CONFIG_POWER_SUPPLY=y
+CONFIG_BATTERY_MSM=y
+CONFIG_SENSORS_MSM_ADC=y
+CONFIG_MARIMBA_CORE=y
+CONFIG_REGULATOR_FAN53555=y
+CONFIG_REGULATOR_ONSEMI_NCP6335D=y
+CONFIG_REGULATOR_MSM_GPIO=y
+CONFIG_MEDIA_SUPPORT=y
+CONFIG_MEDIA_CONTROLLER=y
+CONFIG_VIDEO_DEV=y
+CONFIG_VIDEO_V4L2_SUBDEV_API=y
+# CONFIG_RC_CORE is not set
+# CONFIG_MEDIA_TUNER_CUSTOMISE is not set
+CONFIG_VIDEOBUF2_MSM_MEM=y
+CONFIG_V4L_PLATFORM_DRIVERS=y
+CONFIG_MSM_CAMERA_V4L2=y
+# CONFIG_OV5647 is not set
+# CONFIG_OV5647_DALING_OVBD631AC is not set
+CONFIG_S5K5CA=y
+CONFIG_S5K5CA_DARLING=y
+# CONFIG_HI351_SUNNY_Q3H01B is not set
+# CONFIG_OV5647_PARTRON_CM500 is not set
+# CONFIG_OV5647_HQ_O9B5_DG806T=y
+CONFIG_AR0542=y
+# CONFIG_OV5647_TRULY_CM6868 is not set
+# CONFIG_OV5648_TRULY_CM8352=y
+CONFIG_AD5046_ACT=y
+#byd rm CONFIG_WEBCAM_OV9726=y
+#byd rm CONFIG_MT9E013=y
+#byd rm CONFIG_S5K4E1=y
+#byd rm CONFIG_DW9712_ACT=y
+#CONFIG_MSM_CAMERA_FLASH_SC628A=y
+CONFIG_OV8825=y
+CONFIG_MSM_CAMERA_SENSOR=y
+CONFIG_MSM_ACTUATOR=y
+#CONFIG_OV7692=y
+# CONFIG_WEBCAM_OV7692_QRD is not set
+# CONFIG_OV7695 is not set
+# CONFIG_OV7695_RAW=y
+# CONFIG_MT9V115=y
+CONFIG_RADIO_TAVARUA=y
+CONFIG_ION=y
+CONFIG_ION_MSM=y
+CONFIG_MSM_KGSL=y
+CONFIG_MSM_KGSL_DISABLE_SHADOW_WRITES=y
+CONFIG_FB=y
+CONFIG_FB_MSM=y
+# CONFIG_FB_MSM_BACKLIGHT is not set
+CONFIG_FB_MSM_TRIPLE_BUFFER=y
+CONFIG_FB_MSM_MDP30=y
+CONFIG_FB_MSM_MDP303=y
+CONFIG_FB_MSM_MIPI_DIV4_WVGA_NT35510_PANEL=y
+CONFIG_FB_MSM_LCDC_TRULY_HVGA_IPS3P2335_PT_PANEL=y
+CONFIG_FB_MSM_MIPI_PANEL_DETECT=y
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+CONFIG_SOUND=y
+CONFIG_SND=y
+CONFIG_SND_SOC=y
+CONFIG_SND_MSM_SOC=y
+CONFIG_HID_APPLE=y
+CONFIG_HID_MAGICMOUSE=y
+CONFIG_HID_MICROSOFT=y
+CONFIG_USB=y
+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
+CONFIG_USB_SUSPEND=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_EHSET=y
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
+# CONFIG_USB_EHCI_TT_NEWSCHED is not set
+CONFIG_USB_EHCI_MSM_72K=y
+CONFIG_USB_ACM=y
+CONFIG_USB_STORAGE=y
+CONFIG_USB_STORAGE_DATAFAB=y
+CONFIG_USB_STORAGE_FREECOM=y
+CONFIG_USB_STORAGE_ISD200=y
+CONFIG_USB_STORAGE_USBAT=y
+CONFIG_USB_STORAGE_SDDR09=y
+CONFIG_USB_STORAGE_SDDR55=y
+CONFIG_USB_STORAGE_JUMPSHOT=y
+CONFIG_USB_STORAGE_ALAUDA=y
+CONFIG_USB_STORAGE_ONETOUCH=y
+CONFIG_USB_STORAGE_KARMA=y
+CONFIG_USB_STORAGE_CYPRESS_ATACB=y
+CONFIG_USB_EHSET_TEST_FIXTURE=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_MSM_72K=y
+CONFIG_USB_G_ANDROID=y
+CONFIG_RMNET_SMD_CTL_CHANNEL="DATA40_CNTL"
+CONFIG_RMNET_SMD_DATA_CHANNEL="DATA40"
+CONFIG_MMC=y
+CONFIG_MMC_PERF_PROFILING=y
+CONFIG_MMC_UNSAFE_RESUME=y
+CONFIG_MMC_CLKGATE=y
+CONFIG_MMC_PARANOID_SD_INIT=y
+CONFIG_MMC_BLOCK_MINORS=32
+# CONFIG_MMC_BLOCK_BOUNCE is not set
+CONFIG_MMC_TEST=m
+CONFIG_MMC_MSM=y
+CONFIG_MMC_MSM_SDC3_SUPPORT=y
+CONFIG_MMC_MSM_SDC3_8_BIT_SUPPORT=y
+CONFIG_LEDS_MSM_PDM=y
+CONFIG_LEDS_PMIC_MPP=y
+CONFIG_LEDS_MSM_TRICOLOR=y
+CONFIG_LEDS_GPIO=y
+CONFIG_SWITCH=y
+CONFIG_SWITCH_GPIO=y
+CONFIG_RTC_CLASS=y
+CONFIG_STAGING=y
+CONFIG_ANDROID=y
+CONFIG_ANDROID_BINDER_IPC=y
+CONFIG_ANDROID_LOGGER=y
+CONFIG_ANDROID_LOW_MEMORY_KILLER=y
+CONFIG_ANDROID_LOW_MEMORY_KILLER_AUTODETECT_OOM_ADJ_VALUES=y
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
+CONFIG_EXT4_FS=y
+CONFIG_FUSE_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_TMPFS=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_PRINTK_TIME=y
+CONFIG_PRINTK_RTC_TIME=y
+CONFIG_PRINTK_CPU_ID=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_SHIRQ=y
+# CONFIG_DEBUG_PREEMPT is not set
+# CONFIG_SCHED_DEBUG is not set
+CONFIG_TIMER_STATS=y
+CONFIG_DEBUG_SPINLOCK=y
+CONFIG_DEBUG_STACK_USAGE=y
+CONFIG_DEBUG_INFO=y
+CONFIG_ENABLE_DEFAULT_TRACERS=y
+CONFIG_DYNAMIC_DEBUG=y
+CONFIG_DEBUG_USER=y
+CONFIG_CRYPTO_TWOFISH=y
+CONFIG_CRC_CCITT=y
+# Add 20120823 TS-FMC-V2 start
+CONFIG_FB_MSM_MIPI_OTM9608A_PT=y
+CONFIG_PPP=y
+CONFIG_PPP_ASYNC=y
+CONFIG_PPP_DEFLATE=y
+CONFIG_PPP_BSDCOMP=y
+CONFIG_INET_AH=y
+CONFIG_INET_ESP=y
+CONFIG_INET_IPCOMP=y
+CONFIG_L2TP=y
+CONFIG_L2TP_V3=y
+CONFIG_L2TP_IP=y
+CONFIG_L2TP_ETH=y
+CONFIG_IPX=y
+CONFIG_IPX_INTERN=y
+CONFIG_PPP_FILTER=y
+CONFIG_PPP_MPPE=y
+CONFIG_PPP_MULTILINK=y
+CONFIG_PPPOE=y
+CONFIG_PPPOL2TP=y
+CONFIG_PPPOLAC=y
+CONFIG_PPPOPNS=y
+CONFIG_PPP_SYNC_TTY=y
+CONFIG_TCP_MD5SIG=y
+# Add 20120823 TS-FMC-V2 end
+ONFIG_GLANCEVIEW=y
+#===================================================#
+# Added for apanic emmc #
+#===================================================#
+CONFIG_APANIC_MMC=y
+CONFIG_MMC_MSM_RAW=y
+CONFIG_LOG_BUF_SHIFT=20
diff --git a/arch/arm/configs/normandy_evb1_defconfig b/arch/arm/configs/normandy_evb1_defconfig
new file mode 100755
index 0000000..f1d6205
--- /dev/null
+++ b/arch/arm/configs/normandy_evb1_defconfig
@@ -0,0 +1,432 @@
+# CONFIG_ARM_PATCH_PHYS_VIRT is not set
+CONFIG_EXPERIMENTAL=y
+CONFIG_LOCALVERSION="$(KERNEL_LOCAL_VERSION)-perf"
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_CGROUPS=y
+CONFIG_CGROUP_FREEZER=y
+CONFIG_CGROUP_DEVICE=y
+CONFIG_CGROUP_CPUACCT=y
+CONFIG_RESOURCE_COUNTERS=y
+CONFIG_CGROUP_SCHED=y
+CONFIG_RT_GROUP_SCHED=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_KALLSYMS_ALL=y
+CONFIG_ASHMEM=y
+CONFIG_EMBEDDED=y
+CONFIG_PROFILING=y
+CONFIG_OPROFILE=y
+CONFIG_KPROBES=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+# CONFIG_BLK_DEV_BSG is not set
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_IOSCHED_DEADLINE is not set
+CONFIG_ARCH_MSM=y
+CONFIG_ARCH_MSM7X27=y
+CONFIG_ARCH_MSM8625=y
+CONFIG_MSM_SOC_REV_A=y
+# CONFIG_MACH_MSM7X27_SURF is not set
+# CONFIG_MACH_MSM7X27_FFA is not set
+# CONFIG_MSM_STACKED_MEMORY is not set
+CONFIG_MSM7X00A_USE_DG_TIMER=y
+# CONFIG_MSM_FIQ_SUPPORT is not set
+CONFIG_MSM_SMD=y
+CONFIG_MSM_AMSS_ENHANCE_DEBUG=y
+CONFIG_MSM_SMD_PKG4=y
+# CONFIG_MSM_SMD_DEBUG is not set
+# CONFIG_MSM_RESET_MODEM is not set
+# CONFIG_MSM_SMD_NMEA is not set
+# CONFIG_MSM_SMD_QMI is not set
+CONFIG_MSM_ONCRPCROUTER=y
+CONFIG_MSM_IPC_ROUTER=y
+# CONFIG_MSM_RPCSERVER_TIME_REMOTE is not set
+CONFIG_MSM_RMT_STORAGE_CLIENT=y
+# CONFIG_MSM_HW3D is not set
+CONFIG_MSM7X27A_AUDIO=y
+CONFIG_MSM_DMA_TEST=y
+CONFIG_MSM_SLEEP_STATS_DEVICE=y
+CONFIG_MSM_SM_EVENT=y
+CONFIG_MSM_SM_EVENT_LOG=m
+CONFIG_MSM_SLEEP_MONITOR=m
+CONFIG_MSM_FAST_BOOT=y
+CONFIG_BT_MSM_PINTEST=y
+CONFIG_MSM_RPC_VIBRATOR=y
+CONFIG_PM8XXX_RPC_VIBRATOR=y
+CONFIG_MSM_SPM_V2=y
+CONFIG_MSM_MULTIMEDIA_USE_ION=y
+CONFIG_MSM_FUSE_INFO_DEBUG=y
+CONFIG_MSM_CPR=y
+CONFIG_MSM_VP_REGULATOR=y
+CONFIG_MSM_FIQ=y
+CONFIG_MSM_PBUS=y
+CONFIG_ARM_THUMBEE=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_SMP=y
+CONFIG_PREEMPT=y
+CONFIG_AEABI=y
+CONFIG_HIGHMEM=y
+CONFIG_VMALLOC_RESERVE=0xC800000
+CONFIG_COMPACTION=y
+CONFIG_CP_ACCESS=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="init=/sbin/init root=/dev/ram rw initrd=0x11000000,16M console=ttyDCC0 mem=88M"
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_STAT_DETAILS=y
+CONFIG_CPU_FREQ_GOV_POWERSAVE=y
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_GOV_ONDEMAND=y
+CONFIG_CPU_FREQ_GOV_INTERACTIVE=y
+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
+CONFIG_VFP=y
+CONFIG_NEON=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_WAKELOCK=y
+CONFIG_PM_RUNTIME=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_IP_MULTIPLE_TABLES=y
+CONFIG_IPV6=y
+CONFIG_IPV6_PRIVACY=y
+CONFIG_IPV6_ROUTER_PREF=y
+CONFIG_IPV6_ROUTE_INFO=y
+CONFIG_IPV6_OPTIMISTIC_DAD=y
+CONFIG_INET6_AH=y
+CONFIG_INET6_ESP=y
+CONFIG_INET6_IPCOMP=y
+CONFIG_IPV6_MIP6=y
+CONFIG_IPV6_TUNNEL=y
+CONFIG_IPV6_MULTIPLE_TABLES=y
+CONFIG_IPV6_SUBTREES=y
+CONFIG_NETFILTER=y
+CONFIG_NETFILTER_NETLINK_LOG=y
+CONFIG_NF_CONNTRACK=y
+CONFIG_NF_CONNTRACK_EVENTS=y
+CONFIG_NF_CT_PROTO_DCCP=y
+CONFIG_NF_CT_PROTO_SCTP=y
+CONFIG_NF_CT_PROTO_UDPLITE=y
+CONFIG_NF_CONNTRACK_AMANDA=y
+CONFIG_NF_CONNTRACK_FTP=y
+CONFIG_NF_CONNTRACK_H323=y
+CONFIG_NF_CONNTRACK_IRC=y
+CONFIG_NF_CONNTRACK_NETBIOS_NS=y
+CONFIG_NF_CONNTRACK_PPTP=y
+CONFIG_NF_CONNTRACK_SANE=y
+CONFIG_NF_CONNTRACK_SIP=y
+CONFIG_NF_CONNTRACK_TFTP=y
+CONFIG_NF_CT_NETLINK=y
+CONFIG_NETFILTER_TPROXY=y
+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=y
+CONFIG_NETFILTER_XT_TARGET_CONNMARK=y
+CONFIG_NETFILTER_XT_TARGET_LOG=y
+CONFIG_NETFILTER_XT_TARGET_MARK=y
+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=y
+CONFIG_NETFILTER_XT_MATCH_COMMENT=y
+CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=y
+CONFIG_NETFILTER_XT_MATCH_CONNMARK=y
+CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y
+CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=y
+CONFIG_NETFILTER_XT_MATCH_HELPER=y
+CONFIG_NETFILTER_XT_MATCH_IPRANGE=y
+CONFIG_NETFILTER_XT_MATCH_LENGTH=y
+CONFIG_NETFILTER_XT_MATCH_LIMIT=y
+CONFIG_NETFILTER_XT_MATCH_MAC=y
+CONFIG_NETFILTER_XT_MATCH_MARK=y
+CONFIG_NETFILTER_XT_MATCH_POLICY=y
+CONFIG_NETFILTER_XT_MATCH_PKTTYPE=y
+CONFIG_NETFILTER_XT_MATCH_QTAGUID=y
+CONFIG_NETFILTER_XT_MATCH_QUOTA=y
+CONFIG_NETFILTER_XT_MATCH_QUOTA2=y
+CONFIG_NETFILTER_XT_MATCH_QUOTA2_LOG=y
+CONFIG_NETFILTER_XT_MATCH_SOCKET=y
+CONFIG_NETFILTER_XT_MATCH_STATE=y
+CONFIG_NETFILTER_XT_MATCH_STATISTIC=y
+CONFIG_NETFILTER_XT_MATCH_STRING=y
+CONFIG_NETFILTER_XT_MATCH_TIME=y
+CONFIG_NETFILTER_XT_MATCH_U32=y
+CONFIG_NF_CONNTRACK_IPV4=y
+CONFIG_IP_NF_IPTABLES=y
+CONFIG_IP_NF_MATCH_AH=y
+CONFIG_IP_NF_MATCH_ECN=y
+CONFIG_IP_NF_MATCH_TTL=y
+CONFIG_IP_NF_FILTER=y
+CONFIG_IP_NF_TARGET_REJECT=y
+CONFIG_NF_NAT=y
+CONFIG_IP_NF_TARGET_MASQUERADE=y
+CONFIG_IP_NF_TARGET_NETMAP=y
+CONFIG_IP_NF_TARGET_REDIRECT=y
+CONFIG_IP_NF_MANGLE=y
+CONFIG_IP_NF_RAW=y
+CONFIG_IP_NF_ARPTABLES=y
+CONFIG_IP_NF_ARPFILTER=y
+CONFIG_IP_NF_ARP_MANGLE=y
+CONFIG_IP6_NF_IPTABLES=y
+CONFIG_IP6_NF_FILTER=y
+CONFIG_IP6_NF_MANGLE=y
+CONFIG_IP6_NF_RAW=y
+CONFIG_BT=y
+CONFIG_BT_RFCOMM=y
+CONFIG_BT_RFCOMM_TTY=y
+CONFIG_BT_BNEP=y
+CONFIG_BT_BNEP_MC_FILTER=y
+CONFIG_BT_BNEP_PROTO_FILTER=y
+CONFIG_BT_HIDP=y
+CONFIG_BT_HCIUART=y
+CONFIG_BT_HCIUART_H4=y
+CONFIG_BT_HCIUART_IBS=y
+CONFIG_MSM_BT_POWER=y
+CONFIG_CFG80211=m
+# CONFIG_CFG80211_WEXT is not set
+CONFIG_RFKILL=y
+CONFIG_GENLOCK=y
+CONFIG_GENLOCK_MISCDEVICE=y
+CONFIG_MTD=n
+CONFIG_MTD_TESTS=n
+CONFIG_MTD_CMDLINE_PARTS=n
+CONFIG_MTD_CHAR=n
+CONFIG_MTD_BLOCK=n
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_MISC_DEVICES=y
+#byd CONFIG_SENSORS_AK8975=y
+#byd CONFIG_MPU_SENSORS_TIMERIRQ=y
+#byd CONFIG_MPU_SENSORS_BMA250=y
+#byd CONFIG_MPU_SENSORS_MMC328X=y
+CONFIG_SENSORS_BMA2X2=y
+CONFIG_SENSORS_LTR559=y
+CONFIG_SCSI=y
+CONFIG_SCSI_TGT=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_CHR_DEV_SG=y
+CONFIG_CHR_DEV_SCH=y
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_LOGGING=y
+CONFIG_SCSI_SCAN_ASYNC=y
+CONFIG_MD=y
+CONFIG_BLK_DEV_DM=y
+CONFIG_DM_CRYPT=y
+CONFIG_NETDEVICES=y
+CONFIG_TUN=y
+CONFIG_SMC91X=y
+CONFIG_SMSC911X=y
+CONFIG_LIBRA_SDIOIF=m
+# CONFIG_INPUT_MOUSEDEV is not set
+CONFIG_INPUT_EVDEV=y
+CONFIG_INPUT_EVBUG=m
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+#byd rm CONFIG_TOUCHSCREEN_ATMEL_MAXTOUCH=y
+#byd rm CONFIG_TOUCHSCREEN_ATMEL_MXT=y
+CONFIG_TOUCHSCREEN_SYNAPTICS_RMI4_I2C=y
+#byd rm CONFIG_TOUCHSCREEN_FT5X06=y
+# CONFIG_TOUCHSCREEN_FOCAL=y
+CONFIG_TOUCHSCREEN_FT6306=y
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_UINPUT=y
+CONFIG_INPUT_GPIO=y
+#byd rm CONFIG_INPUT_LTR502=y
+#byd rm CONFIG_INPUT_LTR558=y
+#byd rm CONFIG_BOSCH_BMA250=y
+#byd rm CONFIG_INPUT_ISL29028=y
+#byd rm CONFIG_INPUT_LIS3DH=y
+#byd rm CONFIG_AVAGO_APDS990X=y
+#byd rm CONFIG_SENSORS_TMD2771X=y
+# CONFIG_SERIO is not set
+# CONFIG_LEGACY_PTYS is not set
+CONFIG_SERIAL_MSM=y
+CONFIG_SERIAL_MSM_CONSOLE=y
+CONFIG_SERIAL_MSM_HS=y
+# CONFIG_SERIAL_MSM_CLOCK_CONTROL is not set
+CONFIG_DIAG_CHAR=y
+# CONFIG_HW_RANDOM is not set
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_GPIO=y
+# CONFIG_I2C_MSM is not set
+CONFIG_I2C_QUP=y
+CONFIG_DEBUG_GPIO=y
+CONFIG_GPIO_SYSFS=y
+CONFIG_GPIO_SX150X=y
+CONFIG_POWER_SUPPLY=y
+CONFIG_BATTERY_MSM=y
+CONFIG_SENSORS_MSM_ADC=y
+CONFIG_MARIMBA_CORE=y
+CONFIG_REGULATOR_FAN53555=y
+CONFIG_REGULATOR_ONSEMI_NCP6335D=y
+CONFIG_REGULATOR_MSM_GPIO=y
+CONFIG_MEDIA_SUPPORT=y
+CONFIG_MEDIA_CONTROLLER=y
+CONFIG_VIDEO_DEV=y
+CONFIG_VIDEO_V4L2_SUBDEV_API=y
+# CONFIG_RC_CORE is not set
+# CONFIG_MEDIA_TUNER_CUSTOMISE is not set
+CONFIG_VIDEOBUF2_MSM_MEM=y
+CONFIG_V4L_PLATFORM_DRIVERS=y
+CONFIG_MSM_CAMERA_V4L2=y
+# CONFIG_OV5647 is not set
+# CONFIG_OV5647_DALING_OVBD631AC is not set
+CONFIG_S5K5CA=y
+CONFIG_S5K5CA_DARLING=y
+# CONFIG_HI351_SUNNY_Q3H01B is not set
+# CONFIG_OV5647_PARTRON_CM500 is not set
+# CONFIG_OV5647_HQ_O9B5_DG806T=y
+CONFIG_AR0542=y
+# CONFIG_OV5647_TRULY_CM6868 is not set
+# CONFIG_OV5648_TRULY_CM8352=y
+CONFIG_AD5046_ACT=y
+#byd rm CONFIG_WEBCAM_OV9726=y
+#byd rm CONFIG_MT9E013=y
+#byd rm CONFIG_S5K4E1=y
+#byd rm CONFIG_DW9712_ACT=y
+#CONFIG_MSM_CAMERA_FLASH_SC628A=y
+CONFIG_OV8825=y
+CONFIG_MSM_CAMERA_SENSOR=y
+CONFIG_MSM_ACTUATOR=y
+#CONFIG_OV7692=y
+# CONFIG_WEBCAM_OV7692_QRD is not set
+# CONFIG_OV7695 is not set
+# CONFIG_OV7695_RAW=y
+# CONFIG_MT9V115=y
+CONFIG_RADIO_TAVARUA=y
+CONFIG_ION=y
+CONFIG_ION_MSM=y
+CONFIG_MSM_KGSL=y
+CONFIG_MSM_KGSL_DISABLE_SHADOW_WRITES=y
+CONFIG_FB=y
+CONFIG_FB_MSM=y
+# CONFIG_FB_MSM_BACKLIGHT is not set
+CONFIG_FB_MSM_TRIPLE_BUFFER=y
+CONFIG_FB_MSM_MDP30=y
+CONFIG_FB_MSM_MDP303=y
+CONFIG_FB_MSM_MIPI_DIV4_WVGA_NT35510_PANEL=y
+CONFIG_FB_MSM_LCDC_TRULY_HVGA_IPS3P2335_PT_PANEL=y
+CONFIG_FB_MSM_MIPI_PANEL_DETECT=y
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+CONFIG_SOUND=y
+CONFIG_SND=y
+CONFIG_SND_SOC=y
+CONFIG_SND_MSM_SOC=y
+CONFIG_HID_APPLE=y
+CONFIG_HID_MAGICMOUSE=y
+CONFIG_HID_MICROSOFT=y
+CONFIG_USB=y
+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
+CONFIG_USB_SUSPEND=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_EHSET=y
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
+# CONFIG_USB_EHCI_TT_NEWSCHED is not set
+CONFIG_USB_EHCI_MSM_72K=y
+CONFIG_USB_ACM=y
+CONFIG_USB_STORAGE=y
+CONFIG_USB_STORAGE_DATAFAB=y
+CONFIG_USB_STORAGE_FREECOM=y
+CONFIG_USB_STORAGE_ISD200=y
+CONFIG_USB_STORAGE_USBAT=y
+CONFIG_USB_STORAGE_SDDR09=y
+CONFIG_USB_STORAGE_SDDR55=y
+CONFIG_USB_STORAGE_JUMPSHOT=y
+CONFIG_USB_STORAGE_ALAUDA=y
+CONFIG_USB_STORAGE_ONETOUCH=y
+CONFIG_USB_STORAGE_KARMA=y
+CONFIG_USB_STORAGE_CYPRESS_ATACB=y
+CONFIG_USB_EHSET_TEST_FIXTURE=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_MSM_72K=y
+CONFIG_USB_G_ANDROID=y
+CONFIG_RMNET_SMD_CTL_CHANNEL="DATA40_CNTL"
+CONFIG_RMNET_SMD_DATA_CHANNEL="DATA40"
+CONFIG_MMC=y
+CONFIG_MMC_PERF_PROFILING=y
+CONFIG_MMC_UNSAFE_RESUME=y
+CONFIG_MMC_CLKGATE=y
+CONFIG_MMC_PARANOID_SD_INIT=y
+CONFIG_MMC_BLOCK_MINORS=32
+# CONFIG_MMC_BLOCK_BOUNCE is not set
+CONFIG_MMC_TEST=m
+CONFIG_MMC_MSM=y
+CONFIG_MMC_MSM_SDC3_SUPPORT=y
+CONFIG_MMC_MSM_SDC3_8_BIT_SUPPORT=y
+CONFIG_LEDS_MSM_PDM=y
+CONFIG_LEDS_PMIC_MPP=y
+CONFIG_LEDS_MSM_TRICOLOR=y
+CONFIG_LEDS_GPIO=y
+CONFIG_SWITCH=y
+CONFIG_SWITCH_GPIO=y
+CONFIG_RTC_CLASS=y
+CONFIG_STAGING=y
+CONFIG_ANDROID=y
+CONFIG_ANDROID_BINDER_IPC=y
+CONFIG_ANDROID_LOGGER=y
+CONFIG_ANDROID_LOW_MEMORY_KILLER=y
+CONFIG_ANDROID_LOW_MEMORY_KILLER_AUTODETECT_OOM_ADJ_VALUES=y
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
+CONFIG_EXT4_FS=y
+CONFIG_FUSE_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_TMPFS=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_PRINTK_TIME=y
+CONFIG_PRINTK_RTC_TIME=y
+CONFIG_PRINTK_CPU_ID=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_SHIRQ=y
+# CONFIG_DEBUG_PREEMPT is not set
+# CONFIG_SCHED_DEBUG is not set
+CONFIG_TIMER_STATS=y
+CONFIG_DEBUG_SPINLOCK=y
+CONFIG_DEBUG_STACK_USAGE=y
+CONFIG_DEBUG_INFO=y
+CONFIG_ENABLE_DEFAULT_TRACERS=y
+CONFIG_DYNAMIC_DEBUG=y
+CONFIG_DEBUG_USER=y
+CONFIG_CRYPTO_TWOFISH=y
+CONFIG_CRC_CCITT=y
+# Add 20120823 TS-FMC-V2 start
+CONFIG_FB_MSM_MIPI_OTM9608A_PT=y
+CONFIG_PPP=y
+CONFIG_PPP_ASYNC=y
+CONFIG_PPP_DEFLATE=y
+CONFIG_PPP_BSDCOMP=y
+CONFIG_INET_AH=y
+CONFIG_INET_ESP=y
+CONFIG_INET_IPCOMP=y
+CONFIG_L2TP=y
+CONFIG_L2TP_V3=y
+CONFIG_L2TP_IP=y
+CONFIG_L2TP_ETH=y
+CONFIG_IPX=y
+CONFIG_IPX_INTERN=y
+CONFIG_PPP_FILTER=y
+CONFIG_PPP_MPPE=y
+CONFIG_PPP_MULTILINK=y
+CONFIG_PPPOE=y
+CONFIG_PPPOL2TP=y
+CONFIG_PPPOLAC=y
+CONFIG_PPPOPNS=y
+CONFIG_PPP_SYNC_TTY=y
+CONFIG_TCP_MD5SIG=y
+# Add 20120823 TS-FMC-V2 end
+ONFIG_GLANCEVIEW=y
+#===================================================#
+# Added for apanic emmc #
+#===================================================#
+CONFIG_APANIC_MMC=y
+CONFIG_MMC_MSM_RAW=y
+CONFIG_LOG_BUF_SHIFT=16
diff --git a/arch/arm/configs/normandy_evb2_defconfig b/arch/arm/configs/normandy_evb2_defconfig
new file mode 100755
index 0000000..73a9399
--- /dev/null
+++ b/arch/arm/configs/normandy_evb2_defconfig
@@ -0,0 +1,432 @@
+# CONFIG_ARM_PATCH_PHYS_VIRT is not set
+CONFIG_EXPERIMENTAL=y
+CONFIG_LOCALVERSION="$(KERNEL_LOCAL_VERSION)-perf"
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_CGROUPS=y
+CONFIG_CGROUP_FREEZER=y
+CONFIG_CGROUP_DEVICE=y
+CONFIG_CGROUP_CPUACCT=y
+CONFIG_RESOURCE_COUNTERS=y
+CONFIG_CGROUP_SCHED=y
+CONFIG_RT_GROUP_SCHED=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_KALLSYMS_ALL=y
+CONFIG_ASHMEM=y
+CONFIG_EMBEDDED=y
+CONFIG_PROFILING=y
+CONFIG_OPROFILE=y
+CONFIG_KPROBES=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+# CONFIG_BLK_DEV_BSG is not set
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_IOSCHED_DEADLINE is not set
+CONFIG_ARCH_MSM=y
+CONFIG_ARCH_MSM7X27=y
+CONFIG_ARCH_MSM8625=y
+CONFIG_MSM_SOC_REV_A=y
+# CONFIG_MACH_MSM7X27_SURF is not set
+# CONFIG_MACH_MSM7X27_FFA is not set
+# CONFIG_MSM_STACKED_MEMORY is not set
+CONFIG_MSM7X00A_USE_DG_TIMER=y
+# CONFIG_MSM_FIQ_SUPPORT is not set
+CONFIG_MSM_SMD=y
+CONFIG_MSM_AMSS_ENHANCE_DEBUG=y
+CONFIG_MSM_SMD_PKG4=y
+# CONFIG_MSM_SMD_DEBUG is not set
+# CONFIG_MSM_RESET_MODEM is not set
+# CONFIG_MSM_SMD_NMEA is not set
+# CONFIG_MSM_SMD_QMI is not set
+CONFIG_MSM_ONCRPCROUTER=y
+CONFIG_MSM_IPC_ROUTER=y
+# CONFIG_MSM_RPCSERVER_TIME_REMOTE is not set
+CONFIG_MSM_RMT_STORAGE_CLIENT=y
+# CONFIG_MSM_HW3D is not set
+CONFIG_MSM7X27A_AUDIO=y
+CONFIG_MSM_DMA_TEST=y
+CONFIG_MSM_SLEEP_STATS_DEVICE=y
+CONFIG_MSM_SM_EVENT=y
+CONFIG_MSM_SM_EVENT_LOG=m
+CONFIG_MSM_SLEEP_MONITOR=m
+CONFIG_MSM_FAST_BOOT=y
+CONFIG_BT_MSM_PINTEST=y
+CONFIG_MSM_RPC_VIBRATOR=y
+CONFIG_PM8XXX_RPC_VIBRATOR=y
+CONFIG_MSM_SPM_V2=y
+CONFIG_MSM_MULTIMEDIA_USE_ION=y
+CONFIG_MSM_FUSE_INFO_DEBUG=y
+CONFIG_MSM_CPR=y
+CONFIG_MSM_VP_REGULATOR=y
+CONFIG_MSM_FIQ=y
+CONFIG_MSM_PBUS=y
+CONFIG_ARM_THUMBEE=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_SMP=y
+CONFIG_PREEMPT=y
+CONFIG_AEABI=y
+CONFIG_HIGHMEM=y
+CONFIG_VMALLOC_RESERVE=0xC800000
+CONFIG_COMPACTION=y
+CONFIG_CP_ACCESS=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="init=/sbin/init root=/dev/ram rw initrd=0x11000000,16M console=ttyDCC0 mem=88M"
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_STAT_DETAILS=y
+CONFIG_CPU_FREQ_GOV_POWERSAVE=y
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_GOV_ONDEMAND=y
+CONFIG_CPU_FREQ_GOV_INTERACTIVE=y
+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
+CONFIG_VFP=y
+CONFIG_NEON=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_WAKELOCK=y
+CONFIG_PM_RUNTIME=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_IP_MULTIPLE_TABLES=y
+CONFIG_IPV6=y
+CONFIG_IPV6_PRIVACY=y
+CONFIG_IPV6_ROUTER_PREF=y
+CONFIG_IPV6_ROUTE_INFO=y
+CONFIG_IPV6_OPTIMISTIC_DAD=y
+CONFIG_INET6_AH=y
+CONFIG_INET6_ESP=y
+CONFIG_INET6_IPCOMP=y
+CONFIG_IPV6_MIP6=y
+CONFIG_IPV6_TUNNEL=y
+CONFIG_IPV6_MULTIPLE_TABLES=y
+CONFIG_IPV6_SUBTREES=y
+CONFIG_NETFILTER=y
+CONFIG_NETFILTER_NETLINK_LOG=y
+CONFIG_NF_CONNTRACK=y
+CONFIG_NF_CONNTRACK_EVENTS=y
+CONFIG_NF_CT_PROTO_DCCP=y
+CONFIG_NF_CT_PROTO_SCTP=y
+CONFIG_NF_CT_PROTO_UDPLITE=y
+CONFIG_NF_CONNTRACK_AMANDA=y
+CONFIG_NF_CONNTRACK_FTP=y
+CONFIG_NF_CONNTRACK_H323=y
+CONFIG_NF_CONNTRACK_IRC=y
+CONFIG_NF_CONNTRACK_NETBIOS_NS=y
+CONFIG_NF_CONNTRACK_PPTP=y
+CONFIG_NF_CONNTRACK_SANE=y
+CONFIG_NF_CONNTRACK_SIP=y
+CONFIG_NF_CONNTRACK_TFTP=y
+CONFIG_NF_CT_NETLINK=y
+CONFIG_NETFILTER_TPROXY=y
+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=y
+CONFIG_NETFILTER_XT_TARGET_CONNMARK=y
+CONFIG_NETFILTER_XT_TARGET_LOG=y
+CONFIG_NETFILTER_XT_TARGET_MARK=y
+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=y
+CONFIG_NETFILTER_XT_MATCH_COMMENT=y
+CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=y
+CONFIG_NETFILTER_XT_MATCH_CONNMARK=y
+CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y
+CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=y
+CONFIG_NETFILTER_XT_MATCH_HELPER=y
+CONFIG_NETFILTER_XT_MATCH_IPRANGE=y
+CONFIG_NETFILTER_XT_MATCH_LENGTH=y
+CONFIG_NETFILTER_XT_MATCH_LIMIT=y
+CONFIG_NETFILTER_XT_MATCH_MAC=y
+CONFIG_NETFILTER_XT_MATCH_MARK=y
+CONFIG_NETFILTER_XT_MATCH_POLICY=y
+CONFIG_NETFILTER_XT_MATCH_PKTTYPE=y
+CONFIG_NETFILTER_XT_MATCH_QTAGUID=y
+CONFIG_NETFILTER_XT_MATCH_QUOTA=y
+CONFIG_NETFILTER_XT_MATCH_QUOTA2=y
+CONFIG_NETFILTER_XT_MATCH_QUOTA2_LOG=y
+CONFIG_NETFILTER_XT_MATCH_SOCKET=y
+CONFIG_NETFILTER_XT_MATCH_STATE=y
+CONFIG_NETFILTER_XT_MATCH_STATISTIC=y
+CONFIG_NETFILTER_XT_MATCH_STRING=y
+CONFIG_NETFILTER_XT_MATCH_TIME=y
+CONFIG_NETFILTER_XT_MATCH_U32=y
+CONFIG_NF_CONNTRACK_IPV4=y
+CONFIG_IP_NF_IPTABLES=y
+CONFIG_IP_NF_MATCH_AH=y
+CONFIG_IP_NF_MATCH_ECN=y
+CONFIG_IP_NF_MATCH_TTL=y
+CONFIG_IP_NF_FILTER=y
+CONFIG_IP_NF_TARGET_REJECT=y
+CONFIG_NF_NAT=y
+CONFIG_IP_NF_TARGET_MASQUERADE=y
+CONFIG_IP_NF_TARGET_NETMAP=y
+CONFIG_IP_NF_TARGET_REDIRECT=y
+CONFIG_IP_NF_MANGLE=y
+CONFIG_IP_NF_RAW=y
+CONFIG_IP_NF_ARPTABLES=y
+CONFIG_IP_NF_ARPFILTER=y
+CONFIG_IP_NF_ARP_MANGLE=y
+CONFIG_IP6_NF_IPTABLES=y
+CONFIG_IP6_NF_FILTER=y
+CONFIG_IP6_NF_MANGLE=y
+CONFIG_IP6_NF_RAW=y
+CONFIG_BT=y
+CONFIG_BT_RFCOMM=y
+CONFIG_BT_RFCOMM_TTY=y
+CONFIG_BT_BNEP=y
+CONFIG_BT_BNEP_MC_FILTER=y
+CONFIG_BT_BNEP_PROTO_FILTER=y
+CONFIG_BT_HIDP=y
+CONFIG_BT_HCIUART=y
+CONFIG_BT_HCIUART_H4=y
+CONFIG_BT_HCIUART_IBS=y
+CONFIG_MSM_BT_POWER=y
+CONFIG_CFG80211=m
+# CONFIG_CFG80211_WEXT is not set
+CONFIG_RFKILL=y
+CONFIG_GENLOCK=y
+CONFIG_GENLOCK_MISCDEVICE=y
+CONFIG_MTD=n
+CONFIG_MTD_TESTS=n
+CONFIG_MTD_CMDLINE_PARTS=n
+CONFIG_MTD_CHAR=n
+CONFIG_MTD_BLOCK=n
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_MISC_DEVICES=y
+#byd CONFIG_SENSORS_AK8975=y
+#byd CONFIG_MPU_SENSORS_TIMERIRQ=y
+#byd CONFIG_MPU_SENSORS_BMA250=y
+#byd CONFIG_MPU_SENSORS_MMC328X=y
+CONFIG_SENSORS_BMA2X2=y
+CONFIG_SENSORS_LTR559=y
+CONFIG_SCSI=y
+CONFIG_SCSI_TGT=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_CHR_DEV_SG=y
+CONFIG_CHR_DEV_SCH=y
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_LOGGING=y
+CONFIG_SCSI_SCAN_ASYNC=y
+CONFIG_MD=y
+CONFIG_BLK_DEV_DM=y
+CONFIG_DM_CRYPT=y
+CONFIG_NETDEVICES=y
+CONFIG_TUN=y
+CONFIG_SMC91X=y
+CONFIG_SMSC911X=y
+CONFIG_LIBRA_SDIOIF=m
+# CONFIG_INPUT_MOUSEDEV is not set
+CONFIG_INPUT_EVDEV=y
+CONFIG_INPUT_EVBUG=m
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+#byd rm CONFIG_TOUCHSCREEN_ATMEL_MAXTOUCH=y
+#byd rm CONFIG_TOUCHSCREEN_ATMEL_MXT=y
+CONFIG_TOUCHSCREEN_SYNAPTICS_RMI4_I2C=y
+#byd rm CONFIG_TOUCHSCREEN_FT5X06=y
+# CONFIG_TOUCHSCREEN_FOCAL=y
+CONFIG_TOUCHSCREEN_FT6306=y
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_UINPUT=y
+CONFIG_INPUT_GPIO=y
+#byd rm CONFIG_INPUT_LTR502=y
+#byd rm CONFIG_INPUT_LTR558=y
+#byd rm CONFIG_BOSCH_BMA250=y
+#byd rm CONFIG_INPUT_ISL29028=y
+#byd rm CONFIG_INPUT_LIS3DH=y
+#byd rm CONFIG_AVAGO_APDS990X=y
+#byd rm CONFIG_SENSORS_TMD2771X=y
+# CONFIG_SERIO is not set
+# CONFIG_LEGACY_PTYS is not set
+CONFIG_SERIAL_MSM=y
+CONFIG_SERIAL_MSM_CONSOLE=y
+CONFIG_SERIAL_MSM_HS=y
+# CONFIG_SERIAL_MSM_CLOCK_CONTROL is not set
+CONFIG_DIAG_CHAR=y
+# CONFIG_HW_RANDOM is not set
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_GPIO=y
+# CONFIG_I2C_MSM is not set
+CONFIG_I2C_QUP=y
+CONFIG_DEBUG_GPIO=y
+CONFIG_GPIO_SYSFS=y
+CONFIG_GPIO_SX150X=y
+CONFIG_POWER_SUPPLY=y
+CONFIG_BATTERY_MSM=y
+CONFIG_SENSORS_MSM_ADC=y
+CONFIG_MARIMBA_CORE=y
+CONFIG_REGULATOR_FAN53555=y
+CONFIG_REGULATOR_ONSEMI_NCP6335D=y
+CONFIG_REGULATOR_MSM_GPIO=y
+CONFIG_MEDIA_SUPPORT=y
+CONFIG_MEDIA_CONTROLLER=y
+CONFIG_VIDEO_DEV=y
+CONFIG_VIDEO_V4L2_SUBDEV_API=y
+# CONFIG_RC_CORE is not set
+# CONFIG_MEDIA_TUNER_CUSTOMISE is not set
+CONFIG_VIDEOBUF2_MSM_MEM=y
+CONFIG_V4L_PLATFORM_DRIVERS=y
+CONFIG_MSM_CAMERA_V4L2=y
+# CONFIG_OV5647 is not set
+# CONFIG_OV5647_DALING_OVBD631AC is not set
+CONFIG_S5K5CA=y
+CONFIG_S5K5CA_DARLING=y
+# CONFIG_HI351_SUNNY_Q3H01B is not set
+# CONFIG_OV5647_PARTRON_CM500 is not set
+# CONFIG_OV5647_HQ_O9B5_DG806T=y
+CONFIG_AR0542=y
+# CONFIG_OV5647_TRULY_CM6868 is not set
+# CONFIG_OV5648_TRULY_CM8352=y
+CONFIG_AD5046_ACT=y
+#byd rm CONFIG_WEBCAM_OV9726=y
+#byd rm CONFIG_MT9E013=y
+#byd rm CONFIG_S5K4E1=y
+#byd rm CONFIG_DW9712_ACT=y
+#CONFIG_MSM_CAMERA_FLASH_SC628A=y
+CONFIG_OV8825=y
+CONFIG_MSM_CAMERA_SENSOR=y
+CONFIG_MSM_ACTUATOR=y
+#CONFIG_OV7692=y
+# CONFIG_WEBCAM_OV7692_QRD is not set
+# CONFIG_OV7695 is not set
+# CONFIG_OV7695_RAW=y
+# CONFIG_MT9V115=y
+CONFIG_RADIO_TAVARUA=y
+CONFIG_ION=y
+CONFIG_ION_MSM=y
+CONFIG_MSM_KGSL=y
+CONFIG_MSM_KGSL_DISABLE_SHADOW_WRITES=y
+CONFIG_FB=y
+CONFIG_FB_MSM=y
+# CONFIG_FB_MSM_BACKLIGHT is not set
+CONFIG_FB_MSM_TRIPLE_BUFFER=y
+CONFIG_FB_MSM_MDP30=y
+CONFIG_FB_MSM_MDP303=y
+CONFIG_FB_MSM_MIPI_DIV4_WVGA_NT35510_PANEL=y
+CONFIG_FB_MSM_LCDC_TRULY_HVGA_IPS3P2335_PT_PANEL=y
+CONFIG_FB_MSM_MIPI_PANEL_DETECT=y
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+CONFIG_SOUND=y
+CONFIG_SND=y
+CONFIG_SND_SOC=y
+CONFIG_SND_MSM_SOC=y
+CONFIG_HID_APPLE=y
+CONFIG_HID_MAGICMOUSE=y
+CONFIG_HID_MICROSOFT=y
+CONFIG_USB=y
+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
+CONFIG_USB_SUSPEND=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_EHSET=y
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
+# CONFIG_USB_EHCI_TT_NEWSCHED is not set
+CONFIG_USB_EHCI_MSM_72K=y
+CONFIG_USB_ACM=y
+CONFIG_USB_STORAGE=y
+CONFIG_USB_STORAGE_DATAFAB=y
+CONFIG_USB_STORAGE_FREECOM=y
+CONFIG_USB_STORAGE_ISD200=y
+CONFIG_USB_STORAGE_USBAT=y
+CONFIG_USB_STORAGE_SDDR09=y
+CONFIG_USB_STORAGE_SDDR55=y
+CONFIG_USB_STORAGE_JUMPSHOT=y
+CONFIG_USB_STORAGE_ALAUDA=y
+CONFIG_USB_STORAGE_ONETOUCH=y
+CONFIG_USB_STORAGE_KARMA=y
+CONFIG_USB_STORAGE_CYPRESS_ATACB=y
+CONFIG_USB_EHSET_TEST_FIXTURE=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_MSM_72K=y
+CONFIG_USB_G_ANDROID=y
+CONFIG_RMNET_SMD_CTL_CHANNEL="DATA40_CNTL"
+CONFIG_RMNET_SMD_DATA_CHANNEL="DATA40"
+CONFIG_MMC=y
+CONFIG_MMC_PERF_PROFILING=y
+CONFIG_MMC_UNSAFE_RESUME=y
+CONFIG_MMC_CLKGATE=y
+CONFIG_MMC_PARANOID_SD_INIT=y
+CONFIG_MMC_BLOCK_MINORS=32
+# CONFIG_MMC_BLOCK_BOUNCE is not set
+CONFIG_MMC_TEST=m
+CONFIG_MMC_MSM=y
+CONFIG_MMC_MSM_SDC3_SUPPORT=y
+CONFIG_MMC_MSM_SDC3_8_BIT_SUPPORT=y
+CONFIG_LEDS_MSM_PDM=y
+CONFIG_LEDS_PMIC_MPP=y
+CONFIG_LEDS_MSM_TRICOLOR=y
+CONFIG_LEDS_GPIO=y
+CONFIG_SWITCH=y
+CONFIG_SWITCH_GPIO=y
+CONFIG_RTC_CLASS=y
+CONFIG_STAGING=y
+CONFIG_ANDROID=y
+CONFIG_ANDROID_BINDER_IPC=y
+CONFIG_ANDROID_LOGGER=y
+CONFIG_ANDROID_LOW_MEMORY_KILLER=y
+CONFIG_ANDROID_LOW_MEMORY_KILLER_AUTODETECT_OOM_ADJ_VALUES=y
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
+CONFIG_EXT4_FS=y
+CONFIG_FUSE_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_TMPFS=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_PRINTK_TIME=y
+CONFIG_PRINTK_RTC_TIME=y
+CONFIG_PRINTK_CPU_ID=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_SHIRQ=y
+# CONFIG_DEBUG_PREEMPT is not set
+# CONFIG_SCHED_DEBUG is not set
+CONFIG_TIMER_STATS=y
+CONFIG_DEBUG_SPINLOCK=y
+CONFIG_DEBUG_STACK_USAGE=y
+CONFIG_DEBUG_INFO=y
+CONFIG_ENABLE_DEFAULT_TRACERS=y
+CONFIG_DYNAMIC_DEBUG=y
+CONFIG_DEBUG_USER=y
+CONFIG_CRYPTO_TWOFISH=y
+CONFIG_CRC_CCITT=y
+# Add 20120823 TS-FMC-V2 start
+CONFIG_FB_MSM_MIPI_OTM9608A_PT=y
+CONFIG_PPP=y
+CONFIG_PPP_ASYNC=y
+CONFIG_PPP_DEFLATE=y
+CONFIG_PPP_BSDCOMP=y
+CONFIG_INET_AH=y
+CONFIG_INET_ESP=y
+CONFIG_INET_IPCOMP=y
+CONFIG_L2TP=y
+CONFIG_L2TP_V3=y
+CONFIG_L2TP_IP=y
+CONFIG_L2TP_ETH=y
+CONFIG_IPX=y
+CONFIG_IPX_INTERN=y
+CONFIG_PPP_FILTER=y
+CONFIG_PPP_MPPE=y
+CONFIG_PPP_MULTILINK=y
+CONFIG_PPPOE=y
+CONFIG_PPPOL2TP=y
+CONFIG_PPPOLAC=y
+CONFIG_PPPOPNS=y
+CONFIG_PPP_SYNC_TTY=y
+CONFIG_TCP_MD5SIG=y
+# Add 20120823 TS-FMC-V2 end
+ONFIG_GLANCEVIEW=y
+#===================================================#
+# Added for apanic emmc #
+#===================================================#
+CONFIG_APANIC_MMC=y
+CONFIG_MMC_MSM_RAW=y
+CONFIG_LOG_BUF_SHIFT=18
diff --git a/arch/arm/configs/normandy_lv_defconfig b/arch/arm/configs/normandy_lv_defconfig
new file mode 100755
index 0000000..8a4d602
--- /dev/null
+++ b/arch/arm/configs/normandy_lv_defconfig
@@ -0,0 +1,432 @@
+# CONFIG_ARM_PATCH_PHYS_VIRT is not set
+CONFIG_EXPERIMENTAL=y
+CONFIG_LOCALVERSION="$(KERNEL_LOCAL_VERSION)-perf"
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_CGROUPS=y
+CONFIG_CGROUP_FREEZER=y
+CONFIG_CGROUP_DEVICE=y
+CONFIG_CGROUP_CPUACCT=y
+CONFIG_RESOURCE_COUNTERS=y
+CONFIG_CGROUP_SCHED=y
+CONFIG_RT_GROUP_SCHED=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_KALLSYMS_ALL=y
+CONFIG_ASHMEM=y
+CONFIG_EMBEDDED=y
+CONFIG_PROFILING=y
+CONFIG_OPROFILE=y
+CONFIG_KPROBES=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+# CONFIG_BLK_DEV_BSG is not set
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_IOSCHED_DEADLINE is not set
+CONFIG_ARCH_MSM=y
+CONFIG_ARCH_MSM7X27=y
+CONFIG_ARCH_MSM8625=y
+CONFIG_MSM_SOC_REV_A=y
+# CONFIG_MACH_MSM7X27_SURF is not set
+# CONFIG_MACH_MSM7X27_FFA is not set
+# CONFIG_MSM_STACKED_MEMORY is not set
+CONFIG_MSM7X00A_USE_DG_TIMER=y
+# CONFIG_MSM_FIQ_SUPPORT is not set
+CONFIG_MSM_SMD=y
+CONFIG_MSM_AMSS_ENHANCE_DEBUG=y
+CONFIG_MSM_SMD_PKG4=y
+# CONFIG_MSM_SMD_DEBUG is not set
+# CONFIG_MSM_RESET_MODEM is not set
+# CONFIG_MSM_SMD_NMEA is not set
+# CONFIG_MSM_SMD_QMI is not set
+CONFIG_MSM_ONCRPCROUTER=y
+CONFIG_MSM_IPC_ROUTER=y
+# CONFIG_MSM_RPCSERVER_TIME_REMOTE is not set
+CONFIG_MSM_RMT_STORAGE_CLIENT=y
+# CONFIG_MSM_HW3D is not set
+CONFIG_MSM7X27A_AUDIO=y
+CONFIG_MSM_DMA_TEST=y
+CONFIG_MSM_SLEEP_STATS_DEVICE=y
+CONFIG_MSM_SM_EVENT=y
+CONFIG_MSM_SM_EVENT_LOG=m
+CONFIG_MSM_SLEEP_MONITOR=m
+CONFIG_MSM_FAST_BOOT=y
+CONFIG_BT_MSM_PINTEST=y
+CONFIG_MSM_RPC_VIBRATOR=y
+CONFIG_PM8XXX_RPC_VIBRATOR=y
+CONFIG_MSM_SPM_V2=y
+CONFIG_MSM_MULTIMEDIA_USE_ION=y
+CONFIG_MSM_FUSE_INFO_DEBUG=y
+CONFIG_MSM_CPR=y
+CONFIG_MSM_VP_REGULATOR=y
+CONFIG_MSM_FIQ=y
+CONFIG_MSM_PBUS=y
+CONFIG_ARM_THUMBEE=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_SMP=y
+CONFIG_PREEMPT=y
+CONFIG_AEABI=y
+CONFIG_HIGHMEM=y
+CONFIG_VMALLOC_RESERVE=0xC800000
+CONFIG_COMPACTION=y
+CONFIG_CP_ACCESS=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="init=/sbin/init root=/dev/ram rw initrd=0x11000000,16M console=ttyDCC0 mem=88M"
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_STAT_DETAILS=y
+CONFIG_CPU_FREQ_GOV_POWERSAVE=y
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_GOV_ONDEMAND=y
+CONFIG_CPU_FREQ_GOV_INTERACTIVE=y
+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
+CONFIG_VFP=y
+CONFIG_NEON=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_WAKELOCK=y
+CONFIG_PM_RUNTIME=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_IP_MULTIPLE_TABLES=y
+CONFIG_IPV6=y
+CONFIG_IPV6_PRIVACY=y
+CONFIG_IPV6_ROUTER_PREF=y
+CONFIG_IPV6_ROUTE_INFO=y
+CONFIG_IPV6_OPTIMISTIC_DAD=y
+CONFIG_INET6_AH=y
+CONFIG_INET6_ESP=y
+CONFIG_INET6_IPCOMP=y
+CONFIG_IPV6_MIP6=y
+CONFIG_IPV6_TUNNEL=y
+CONFIG_IPV6_MULTIPLE_TABLES=y
+CONFIG_IPV6_SUBTREES=y
+CONFIG_NETFILTER=y
+CONFIG_NETFILTER_NETLINK_LOG=y
+CONFIG_NF_CONNTRACK=y
+CONFIG_NF_CONNTRACK_EVENTS=y
+CONFIG_NF_CT_PROTO_DCCP=y
+CONFIG_NF_CT_PROTO_SCTP=y
+CONFIG_NF_CT_PROTO_UDPLITE=y
+CONFIG_NF_CONNTRACK_AMANDA=y
+CONFIG_NF_CONNTRACK_FTP=y
+CONFIG_NF_CONNTRACK_H323=y
+CONFIG_NF_CONNTRACK_IRC=y
+CONFIG_NF_CONNTRACK_NETBIOS_NS=y
+CONFIG_NF_CONNTRACK_PPTP=y
+CONFIG_NF_CONNTRACK_SANE=y
+CONFIG_NF_CONNTRACK_SIP=y
+CONFIG_NF_CONNTRACK_TFTP=y
+CONFIG_NF_CT_NETLINK=y
+CONFIG_NETFILTER_TPROXY=y
+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=y
+CONFIG_NETFILTER_XT_TARGET_CONNMARK=y
+CONFIG_NETFILTER_XT_TARGET_LOG=y
+CONFIG_NETFILTER_XT_TARGET_MARK=y
+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=y
+CONFIG_NETFILTER_XT_MATCH_COMMENT=y
+CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=y
+CONFIG_NETFILTER_XT_MATCH_CONNMARK=y
+CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y
+CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=y
+CONFIG_NETFILTER_XT_MATCH_HELPER=y
+CONFIG_NETFILTER_XT_MATCH_IPRANGE=y
+CONFIG_NETFILTER_XT_MATCH_LENGTH=y
+CONFIG_NETFILTER_XT_MATCH_LIMIT=y
+CONFIG_NETFILTER_XT_MATCH_MAC=y
+CONFIG_NETFILTER_XT_MATCH_MARK=y
+CONFIG_NETFILTER_XT_MATCH_POLICY=y
+CONFIG_NETFILTER_XT_MATCH_PKTTYPE=y
+CONFIG_NETFILTER_XT_MATCH_QTAGUID=y
+CONFIG_NETFILTER_XT_MATCH_QUOTA=y
+CONFIG_NETFILTER_XT_MATCH_QUOTA2=y
+CONFIG_NETFILTER_XT_MATCH_QUOTA2_LOG=y
+CONFIG_NETFILTER_XT_MATCH_SOCKET=y
+CONFIG_NETFILTER_XT_MATCH_STATE=y
+CONFIG_NETFILTER_XT_MATCH_STATISTIC=y
+CONFIG_NETFILTER_XT_MATCH_STRING=y
+CONFIG_NETFILTER_XT_MATCH_TIME=y
+CONFIG_NETFILTER_XT_MATCH_U32=y
+CONFIG_NF_CONNTRACK_IPV4=y
+CONFIG_IP_NF_IPTABLES=y
+CONFIG_IP_NF_MATCH_AH=y
+CONFIG_IP_NF_MATCH_ECN=y
+CONFIG_IP_NF_MATCH_TTL=y
+CONFIG_IP_NF_FILTER=y
+CONFIG_IP_NF_TARGET_REJECT=y
+CONFIG_NF_NAT=y
+CONFIG_IP_NF_TARGET_MASQUERADE=y
+CONFIG_IP_NF_TARGET_NETMAP=y
+CONFIG_IP_NF_TARGET_REDIRECT=y
+CONFIG_IP_NF_MANGLE=y
+CONFIG_IP_NF_RAW=y
+CONFIG_IP_NF_ARPTABLES=y
+CONFIG_IP_NF_ARPFILTER=y
+CONFIG_IP_NF_ARP_MANGLE=y
+CONFIG_IP6_NF_IPTABLES=y
+CONFIG_IP6_NF_FILTER=y
+CONFIG_IP6_NF_MANGLE=y
+CONFIG_IP6_NF_RAW=y
+CONFIG_BT=y
+CONFIG_BT_RFCOMM=y
+CONFIG_BT_RFCOMM_TTY=y
+CONFIG_BT_BNEP=y
+CONFIG_BT_BNEP_MC_FILTER=y
+CONFIG_BT_BNEP_PROTO_FILTER=y
+CONFIG_BT_HIDP=y
+CONFIG_BT_HCIUART=y
+CONFIG_BT_HCIUART_H4=y
+CONFIG_BT_HCIUART_IBS=y
+CONFIG_MSM_BT_POWER=y
+CONFIG_CFG80211=m
+# CONFIG_CFG80211_WEXT is not set
+CONFIG_RFKILL=y
+CONFIG_GENLOCK=y
+CONFIG_GENLOCK_MISCDEVICE=y
+CONFIG_MTD=n
+CONFIG_MTD_TESTS=n
+CONFIG_MTD_CMDLINE_PARTS=n
+CONFIG_MTD_CHAR=n
+CONFIG_MTD_BLOCK=n
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_MISC_DEVICES=y
+#byd CONFIG_SENSORS_AK8975=y
+#byd CONFIG_MPU_SENSORS_TIMERIRQ=y
+#byd CONFIG_MPU_SENSORS_BMA250=y
+#byd CONFIG_MPU_SENSORS_MMC328X=y
+CONFIG_SENSORS_BMA2X2=y
+CONFIG_SENSORS_LTR559=y
+CONFIG_SCSI=y
+CONFIG_SCSI_TGT=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_CHR_DEV_SG=y
+CONFIG_CHR_DEV_SCH=y
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_LOGGING=y
+CONFIG_SCSI_SCAN_ASYNC=y
+CONFIG_MD=y
+CONFIG_BLK_DEV_DM=y
+CONFIG_DM_CRYPT=y
+CONFIG_NETDEVICES=y
+CONFIG_TUN=y
+CONFIG_SMC91X=y
+CONFIG_SMSC911X=y
+CONFIG_LIBRA_SDIOIF=m
+# CONFIG_INPUT_MOUSEDEV is not set
+CONFIG_INPUT_EVDEV=y
+CONFIG_INPUT_EVBUG=m
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+#byd rm CONFIG_TOUCHSCREEN_ATMEL_MAXTOUCH=y
+#byd rm CONFIG_TOUCHSCREEN_ATMEL_MXT=y
+CONFIG_TOUCHSCREEN_SYNAPTICS_RMI4_I2C=y
+#byd rm CONFIG_TOUCHSCREEN_FT5X06=y
+# CONFIG_TOUCHSCREEN_FOCAL=y
+CONFIG_TOUCHSCREEN_FT6306=y
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_UINPUT=y
+CONFIG_INPUT_GPIO=y
+#byd rm CONFIG_INPUT_LTR502=y
+#byd rm CONFIG_INPUT_LTR558=y
+#byd rm CONFIG_BOSCH_BMA250=y
+#byd rm CONFIG_INPUT_ISL29028=y
+#byd rm CONFIG_INPUT_LIS3DH=y
+#byd rm CONFIG_AVAGO_APDS990X=y
+#byd rm CONFIG_SENSORS_TMD2771X=y
+# CONFIG_SERIO is not set
+# CONFIG_LEGACY_PTYS is not set
+CONFIG_SERIAL_MSM=y
+CONFIG_SERIAL_MSM_CONSOLE=y
+CONFIG_SERIAL_MSM_HS=y
+# CONFIG_SERIAL_MSM_CLOCK_CONTROL is not set
+CONFIG_DIAG_CHAR=y
+# CONFIG_HW_RANDOM is not set
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_GPIO=y
+# CONFIG_I2C_MSM is not set
+CONFIG_I2C_QUP=y
+CONFIG_DEBUG_GPIO=y
+CONFIG_GPIO_SYSFS=y
+CONFIG_GPIO_SX150X=y
+CONFIG_POWER_SUPPLY=y
+CONFIG_BATTERY_MSM=y
+CONFIG_SENSORS_MSM_ADC=y
+CONFIG_MARIMBA_CORE=y
+CONFIG_REGULATOR_FAN53555=y
+CONFIG_REGULATOR_ONSEMI_NCP6335D=y
+CONFIG_REGULATOR_MSM_GPIO=y
+CONFIG_MEDIA_SUPPORT=y
+CONFIG_MEDIA_CONTROLLER=y
+CONFIG_VIDEO_DEV=y
+CONFIG_VIDEO_V4L2_SUBDEV_API=y
+# CONFIG_RC_CORE is not set
+# CONFIG_MEDIA_TUNER_CUSTOMISE is not set
+CONFIG_VIDEOBUF2_MSM_MEM=y
+CONFIG_V4L_PLATFORM_DRIVERS=y
+CONFIG_MSM_CAMERA_V4L2=y
+# CONFIG_OV5647 is not set
+# CONFIG_OV5647_DALING_OVBD631AC is not set
+CONFIG_S5K5CA=y
+CONFIG_S5K5CA_DARLING=y
+# CONFIG_HI351_SUNNY_Q3H01B is not set
+# CONFIG_OV5647_PARTRON_CM500 is not set
+# CONFIG_OV5647_HQ_O9B5_DG806T=y
+CONFIG_AR0542=y
+# CONFIG_OV5647_TRULY_CM6868 is not set
+# CONFIG_OV5648_TRULY_CM8352=y
+CONFIG_AD5046_ACT=y
+#byd rm CONFIG_WEBCAM_OV9726=y
+#byd rm CONFIG_MT9E013=y
+#byd rm CONFIG_S5K4E1=y
+#byd rm CONFIG_DW9712_ACT=y
+#CONFIG_MSM_CAMERA_FLASH_SC628A=y
+CONFIG_OV8825=y
+CONFIG_MSM_CAMERA_SENSOR=y
+CONFIG_MSM_ACTUATOR=y
+#CONFIG_OV7692=y
+# CONFIG_WEBCAM_OV7692_QRD is not set
+# CONFIG_OV7695 is not set
+# CONFIG_OV7695_RAW=y
+# CONFIG_MT9V115=y
+CONFIG_RADIO_TAVARUA=y
+CONFIG_ION=y
+CONFIG_ION_MSM=y
+CONFIG_MSM_KGSL=y
+CONFIG_MSM_KGSL_DISABLE_SHADOW_WRITES=y
+CONFIG_FB=y
+CONFIG_FB_MSM=y
+# CONFIG_FB_MSM_BACKLIGHT is not set
+CONFIG_FB_MSM_TRIPLE_BUFFER=y
+CONFIG_FB_MSM_MDP30=y
+CONFIG_FB_MSM_MDP303=y
+CONFIG_FB_MSM_MIPI_DIV4_WVGA_NT35510_PANEL=y
+CONFIG_FB_MSM_LCDC_TRULY_HVGA_IPS3P2335_PT_PANEL=y
+CONFIG_FB_MSM_MIPI_PANEL_DETECT=y
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+CONFIG_SOUND=y
+CONFIG_SND=y
+CONFIG_SND_SOC=y
+CONFIG_SND_MSM_SOC=y
+CONFIG_HID_APPLE=y
+CONFIG_HID_MAGICMOUSE=y
+CONFIG_HID_MICROSOFT=y
+CONFIG_USB=y
+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
+CONFIG_USB_SUSPEND=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_EHSET=y
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
+# CONFIG_USB_EHCI_TT_NEWSCHED is not set
+CONFIG_USB_EHCI_MSM_72K=y
+CONFIG_USB_ACM=y
+CONFIG_USB_STORAGE=y
+CONFIG_USB_STORAGE_DATAFAB=y
+CONFIG_USB_STORAGE_FREECOM=y
+CONFIG_USB_STORAGE_ISD200=y
+CONFIG_USB_STORAGE_USBAT=y
+CONFIG_USB_STORAGE_SDDR09=y
+CONFIG_USB_STORAGE_SDDR55=y
+CONFIG_USB_STORAGE_JUMPSHOT=y
+CONFIG_USB_STORAGE_ALAUDA=y
+CONFIG_USB_STORAGE_ONETOUCH=y
+CONFIG_USB_STORAGE_KARMA=y
+CONFIG_USB_STORAGE_CYPRESS_ATACB=y
+CONFIG_USB_EHSET_TEST_FIXTURE=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_MSM_72K=y
+CONFIG_USB_G_ANDROID=y
+CONFIG_RMNET_SMD_CTL_CHANNEL="DATA40_CNTL"
+CONFIG_RMNET_SMD_DATA_CHANNEL="DATA40"
+CONFIG_MMC=y
+CONFIG_MMC_PERF_PROFILING=y
+CONFIG_MMC_UNSAFE_RESUME=y
+CONFIG_MMC_CLKGATE=y
+CONFIG_MMC_PARANOID_SD_INIT=y
+CONFIG_MMC_BLOCK_MINORS=32
+# CONFIG_MMC_BLOCK_BOUNCE is not set
+CONFIG_MMC_TEST=m
+CONFIG_MMC_MSM=y
+CONFIG_MMC_MSM_SDC3_SUPPORT=y
+CONFIG_MMC_MSM_SDC3_8_BIT_SUPPORT=y
+CONFIG_LEDS_MSM_PDM=y
+CONFIG_LEDS_PMIC_MPP=y
+CONFIG_LEDS_MSM_TRICOLOR=y
+CONFIG_LEDS_GPIO=y
+CONFIG_SWITCH=y
+CONFIG_SWITCH_GPIO=y
+CONFIG_RTC_CLASS=y
+CONFIG_STAGING=y
+CONFIG_ANDROID=y
+CONFIG_ANDROID_BINDER_IPC=y
+CONFIG_ANDROID_LOGGER=y
+CONFIG_ANDROID_LOW_MEMORY_KILLER=y
+CONFIG_ANDROID_LOW_MEMORY_KILLER_AUTODETECT_OOM_ADJ_VALUES=y
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
+CONFIG_EXT4_FS=y
+CONFIG_FUSE_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_TMPFS=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_PRINTK_TIME=y
+CONFIG_PRINTK_RTC_TIME=y
+CONFIG_PRINTK_CPU_ID=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_SHIRQ=y
+# CONFIG_DEBUG_PREEMPT is not set
+# CONFIG_SCHED_DEBUG is not set
+CONFIG_TIMER_STATS=y
+CONFIG_DEBUG_SPINLOCK=y
+CONFIG_DEBUG_STACK_USAGE=y
+CONFIG_DEBUG_INFO=y
+CONFIG_ENABLE_DEFAULT_TRACERS=y
+CONFIG_DYNAMIC_DEBUG=y
+CONFIG_DEBUG_USER=y
+CONFIG_CRYPTO_TWOFISH=y
+CONFIG_CRC_CCITT=y
+# Add 20120823 TS-FMC-V2 start
+CONFIG_FB_MSM_MIPI_OTM9608A_PT=y
+CONFIG_PPP=y
+CONFIG_PPP_ASYNC=y
+CONFIG_PPP_DEFLATE=y
+CONFIG_PPP_BSDCOMP=y
+CONFIG_INET_AH=y
+CONFIG_INET_ESP=y
+CONFIG_INET_IPCOMP=y
+CONFIG_L2TP=y
+CONFIG_L2TP_V3=y
+CONFIG_L2TP_IP=y
+CONFIG_L2TP_ETH=y
+CONFIG_IPX=y
+CONFIG_IPX_INTERN=y
+CONFIG_PPP_FILTER=y
+CONFIG_PPP_MPPE=y
+CONFIG_PPP_MULTILINK=y
+CONFIG_PPPOE=y
+CONFIG_PPPOL2TP=y
+CONFIG_PPPOLAC=y
+CONFIG_PPPOPNS=y
+CONFIG_PPP_SYNC_TTY=y
+CONFIG_TCP_MD5SIG=y
+# Add 20120823 TS-FMC-V2 end
+ONFIG_GLANCEVIEW=y
+#===================================================#
+# Added for apanic emmc #
+#===================================================#
+CONFIG_APANIC_MMC=y
+CONFIG_MMC_MSM_RAW=y
+CONFIG_LOG_BUF_SHIFT=20
diff --git a/arch/arm/configs/normandy_mp_defconfig b/arch/arm/configs/normandy_mp_defconfig
new file mode 100755
index 0000000..8a4d602
--- /dev/null
+++ b/arch/arm/configs/normandy_mp_defconfig
@@ -0,0 +1,432 @@
+# CONFIG_ARM_PATCH_PHYS_VIRT is not set
+CONFIG_EXPERIMENTAL=y
+CONFIG_LOCALVERSION="$(KERNEL_LOCAL_VERSION)-perf"
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_CGROUPS=y
+CONFIG_CGROUP_FREEZER=y
+CONFIG_CGROUP_DEVICE=y
+CONFIG_CGROUP_CPUACCT=y
+CONFIG_RESOURCE_COUNTERS=y
+CONFIG_CGROUP_SCHED=y
+CONFIG_RT_GROUP_SCHED=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_KALLSYMS_ALL=y
+CONFIG_ASHMEM=y
+CONFIG_EMBEDDED=y
+CONFIG_PROFILING=y
+CONFIG_OPROFILE=y
+CONFIG_KPROBES=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+# CONFIG_BLK_DEV_BSG is not set
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_IOSCHED_DEADLINE is not set
+CONFIG_ARCH_MSM=y
+CONFIG_ARCH_MSM7X27=y
+CONFIG_ARCH_MSM8625=y
+CONFIG_MSM_SOC_REV_A=y
+# CONFIG_MACH_MSM7X27_SURF is not set
+# CONFIG_MACH_MSM7X27_FFA is not set
+# CONFIG_MSM_STACKED_MEMORY is not set
+CONFIG_MSM7X00A_USE_DG_TIMER=y
+# CONFIG_MSM_FIQ_SUPPORT is not set
+CONFIG_MSM_SMD=y
+CONFIG_MSM_AMSS_ENHANCE_DEBUG=y
+CONFIG_MSM_SMD_PKG4=y
+# CONFIG_MSM_SMD_DEBUG is not set
+# CONFIG_MSM_RESET_MODEM is not set
+# CONFIG_MSM_SMD_NMEA is not set
+# CONFIG_MSM_SMD_QMI is not set
+CONFIG_MSM_ONCRPCROUTER=y
+CONFIG_MSM_IPC_ROUTER=y
+# CONFIG_MSM_RPCSERVER_TIME_REMOTE is not set
+CONFIG_MSM_RMT_STORAGE_CLIENT=y
+# CONFIG_MSM_HW3D is not set
+CONFIG_MSM7X27A_AUDIO=y
+CONFIG_MSM_DMA_TEST=y
+CONFIG_MSM_SLEEP_STATS_DEVICE=y
+CONFIG_MSM_SM_EVENT=y
+CONFIG_MSM_SM_EVENT_LOG=m
+CONFIG_MSM_SLEEP_MONITOR=m
+CONFIG_MSM_FAST_BOOT=y
+CONFIG_BT_MSM_PINTEST=y
+CONFIG_MSM_RPC_VIBRATOR=y
+CONFIG_PM8XXX_RPC_VIBRATOR=y
+CONFIG_MSM_SPM_V2=y
+CONFIG_MSM_MULTIMEDIA_USE_ION=y
+CONFIG_MSM_FUSE_INFO_DEBUG=y
+CONFIG_MSM_CPR=y
+CONFIG_MSM_VP_REGULATOR=y
+CONFIG_MSM_FIQ=y
+CONFIG_MSM_PBUS=y
+CONFIG_ARM_THUMBEE=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_SMP=y
+CONFIG_PREEMPT=y
+CONFIG_AEABI=y
+CONFIG_HIGHMEM=y
+CONFIG_VMALLOC_RESERVE=0xC800000
+CONFIG_COMPACTION=y
+CONFIG_CP_ACCESS=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="init=/sbin/init root=/dev/ram rw initrd=0x11000000,16M console=ttyDCC0 mem=88M"
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_STAT_DETAILS=y
+CONFIG_CPU_FREQ_GOV_POWERSAVE=y
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_GOV_ONDEMAND=y
+CONFIG_CPU_FREQ_GOV_INTERACTIVE=y
+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
+CONFIG_VFP=y
+CONFIG_NEON=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_WAKELOCK=y
+CONFIG_PM_RUNTIME=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_IP_MULTIPLE_TABLES=y
+CONFIG_IPV6=y
+CONFIG_IPV6_PRIVACY=y
+CONFIG_IPV6_ROUTER_PREF=y
+CONFIG_IPV6_ROUTE_INFO=y
+CONFIG_IPV6_OPTIMISTIC_DAD=y
+CONFIG_INET6_AH=y
+CONFIG_INET6_ESP=y
+CONFIG_INET6_IPCOMP=y
+CONFIG_IPV6_MIP6=y
+CONFIG_IPV6_TUNNEL=y
+CONFIG_IPV6_MULTIPLE_TABLES=y
+CONFIG_IPV6_SUBTREES=y
+CONFIG_NETFILTER=y
+CONFIG_NETFILTER_NETLINK_LOG=y
+CONFIG_NF_CONNTRACK=y
+CONFIG_NF_CONNTRACK_EVENTS=y
+CONFIG_NF_CT_PROTO_DCCP=y
+CONFIG_NF_CT_PROTO_SCTP=y
+CONFIG_NF_CT_PROTO_UDPLITE=y
+CONFIG_NF_CONNTRACK_AMANDA=y
+CONFIG_NF_CONNTRACK_FTP=y
+CONFIG_NF_CONNTRACK_H323=y
+CONFIG_NF_CONNTRACK_IRC=y
+CONFIG_NF_CONNTRACK_NETBIOS_NS=y
+CONFIG_NF_CONNTRACK_PPTP=y
+CONFIG_NF_CONNTRACK_SANE=y
+CONFIG_NF_CONNTRACK_SIP=y
+CONFIG_NF_CONNTRACK_TFTP=y
+CONFIG_NF_CT_NETLINK=y
+CONFIG_NETFILTER_TPROXY=y
+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=y
+CONFIG_NETFILTER_XT_TARGET_CONNMARK=y
+CONFIG_NETFILTER_XT_TARGET_LOG=y
+CONFIG_NETFILTER_XT_TARGET_MARK=y
+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=y
+CONFIG_NETFILTER_XT_MATCH_COMMENT=y
+CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=y
+CONFIG_NETFILTER_XT_MATCH_CONNMARK=y
+CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y
+CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=y
+CONFIG_NETFILTER_XT_MATCH_HELPER=y
+CONFIG_NETFILTER_XT_MATCH_IPRANGE=y
+CONFIG_NETFILTER_XT_MATCH_LENGTH=y
+CONFIG_NETFILTER_XT_MATCH_LIMIT=y
+CONFIG_NETFILTER_XT_MATCH_MAC=y
+CONFIG_NETFILTER_XT_MATCH_MARK=y
+CONFIG_NETFILTER_XT_MATCH_POLICY=y
+CONFIG_NETFILTER_XT_MATCH_PKTTYPE=y
+CONFIG_NETFILTER_XT_MATCH_QTAGUID=y
+CONFIG_NETFILTER_XT_MATCH_QUOTA=y
+CONFIG_NETFILTER_XT_MATCH_QUOTA2=y
+CONFIG_NETFILTER_XT_MATCH_QUOTA2_LOG=y
+CONFIG_NETFILTER_XT_MATCH_SOCKET=y
+CONFIG_NETFILTER_XT_MATCH_STATE=y
+CONFIG_NETFILTER_XT_MATCH_STATISTIC=y
+CONFIG_NETFILTER_XT_MATCH_STRING=y
+CONFIG_NETFILTER_XT_MATCH_TIME=y
+CONFIG_NETFILTER_XT_MATCH_U32=y
+CONFIG_NF_CONNTRACK_IPV4=y
+CONFIG_IP_NF_IPTABLES=y
+CONFIG_IP_NF_MATCH_AH=y
+CONFIG_IP_NF_MATCH_ECN=y
+CONFIG_IP_NF_MATCH_TTL=y
+CONFIG_IP_NF_FILTER=y
+CONFIG_IP_NF_TARGET_REJECT=y
+CONFIG_NF_NAT=y
+CONFIG_IP_NF_TARGET_MASQUERADE=y
+CONFIG_IP_NF_TARGET_NETMAP=y
+CONFIG_IP_NF_TARGET_REDIRECT=y
+CONFIG_IP_NF_MANGLE=y
+CONFIG_IP_NF_RAW=y
+CONFIG_IP_NF_ARPTABLES=y
+CONFIG_IP_NF_ARPFILTER=y
+CONFIG_IP_NF_ARP_MANGLE=y
+CONFIG_IP6_NF_IPTABLES=y
+CONFIG_IP6_NF_FILTER=y
+CONFIG_IP6_NF_MANGLE=y
+CONFIG_IP6_NF_RAW=y
+CONFIG_BT=y
+CONFIG_BT_RFCOMM=y
+CONFIG_BT_RFCOMM_TTY=y
+CONFIG_BT_BNEP=y
+CONFIG_BT_BNEP_MC_FILTER=y
+CONFIG_BT_BNEP_PROTO_FILTER=y
+CONFIG_BT_HIDP=y
+CONFIG_BT_HCIUART=y
+CONFIG_BT_HCIUART_H4=y
+CONFIG_BT_HCIUART_IBS=y
+CONFIG_MSM_BT_POWER=y
+CONFIG_CFG80211=m
+# CONFIG_CFG80211_WEXT is not set
+CONFIG_RFKILL=y
+CONFIG_GENLOCK=y
+CONFIG_GENLOCK_MISCDEVICE=y
+CONFIG_MTD=n
+CONFIG_MTD_TESTS=n
+CONFIG_MTD_CMDLINE_PARTS=n
+CONFIG_MTD_CHAR=n
+CONFIG_MTD_BLOCK=n
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_MISC_DEVICES=y
+#byd CONFIG_SENSORS_AK8975=y
+#byd CONFIG_MPU_SENSORS_TIMERIRQ=y
+#byd CONFIG_MPU_SENSORS_BMA250=y
+#byd CONFIG_MPU_SENSORS_MMC328X=y
+CONFIG_SENSORS_BMA2X2=y
+CONFIG_SENSORS_LTR559=y
+CONFIG_SCSI=y
+CONFIG_SCSI_TGT=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_CHR_DEV_SG=y
+CONFIG_CHR_DEV_SCH=y
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_LOGGING=y
+CONFIG_SCSI_SCAN_ASYNC=y
+CONFIG_MD=y
+CONFIG_BLK_DEV_DM=y
+CONFIG_DM_CRYPT=y
+CONFIG_NETDEVICES=y
+CONFIG_TUN=y
+CONFIG_SMC91X=y
+CONFIG_SMSC911X=y
+CONFIG_LIBRA_SDIOIF=m
+# CONFIG_INPUT_MOUSEDEV is not set
+CONFIG_INPUT_EVDEV=y
+CONFIG_INPUT_EVBUG=m
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+#byd rm CONFIG_TOUCHSCREEN_ATMEL_MAXTOUCH=y
+#byd rm CONFIG_TOUCHSCREEN_ATMEL_MXT=y
+CONFIG_TOUCHSCREEN_SYNAPTICS_RMI4_I2C=y
+#byd rm CONFIG_TOUCHSCREEN_FT5X06=y
+# CONFIG_TOUCHSCREEN_FOCAL=y
+CONFIG_TOUCHSCREEN_FT6306=y
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_UINPUT=y
+CONFIG_INPUT_GPIO=y
+#byd rm CONFIG_INPUT_LTR502=y
+#byd rm CONFIG_INPUT_LTR558=y
+#byd rm CONFIG_BOSCH_BMA250=y
+#byd rm CONFIG_INPUT_ISL29028=y
+#byd rm CONFIG_INPUT_LIS3DH=y
+#byd rm CONFIG_AVAGO_APDS990X=y
+#byd rm CONFIG_SENSORS_TMD2771X=y
+# CONFIG_SERIO is not set
+# CONFIG_LEGACY_PTYS is not set
+CONFIG_SERIAL_MSM=y
+CONFIG_SERIAL_MSM_CONSOLE=y
+CONFIG_SERIAL_MSM_HS=y
+# CONFIG_SERIAL_MSM_CLOCK_CONTROL is not set
+CONFIG_DIAG_CHAR=y
+# CONFIG_HW_RANDOM is not set
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_GPIO=y
+# CONFIG_I2C_MSM is not set
+CONFIG_I2C_QUP=y
+CONFIG_DEBUG_GPIO=y
+CONFIG_GPIO_SYSFS=y
+CONFIG_GPIO_SX150X=y
+CONFIG_POWER_SUPPLY=y
+CONFIG_BATTERY_MSM=y
+CONFIG_SENSORS_MSM_ADC=y
+CONFIG_MARIMBA_CORE=y
+CONFIG_REGULATOR_FAN53555=y
+CONFIG_REGULATOR_ONSEMI_NCP6335D=y
+CONFIG_REGULATOR_MSM_GPIO=y
+CONFIG_MEDIA_SUPPORT=y
+CONFIG_MEDIA_CONTROLLER=y
+CONFIG_VIDEO_DEV=y
+CONFIG_VIDEO_V4L2_SUBDEV_API=y
+# CONFIG_RC_CORE is not set
+# CONFIG_MEDIA_TUNER_CUSTOMISE is not set
+CONFIG_VIDEOBUF2_MSM_MEM=y
+CONFIG_V4L_PLATFORM_DRIVERS=y
+CONFIG_MSM_CAMERA_V4L2=y
+# CONFIG_OV5647 is not set
+# CONFIG_OV5647_DALING_OVBD631AC is not set
+CONFIG_S5K5CA=y
+CONFIG_S5K5CA_DARLING=y
+# CONFIG_HI351_SUNNY_Q3H01B is not set
+# CONFIG_OV5647_PARTRON_CM500 is not set
+# CONFIG_OV5647_HQ_O9B5_DG806T=y
+CONFIG_AR0542=y
+# CONFIG_OV5647_TRULY_CM6868 is not set
+# CONFIG_OV5648_TRULY_CM8352=y
+CONFIG_AD5046_ACT=y
+#byd rm CONFIG_WEBCAM_OV9726=y
+#byd rm CONFIG_MT9E013=y
+#byd rm CONFIG_S5K4E1=y
+#byd rm CONFIG_DW9712_ACT=y
+#CONFIG_MSM_CAMERA_FLASH_SC628A=y
+CONFIG_OV8825=y
+CONFIG_MSM_CAMERA_SENSOR=y
+CONFIG_MSM_ACTUATOR=y
+#CONFIG_OV7692=y
+# CONFIG_WEBCAM_OV7692_QRD is not set
+# CONFIG_OV7695 is not set
+# CONFIG_OV7695_RAW=y
+# CONFIG_MT9V115=y
+CONFIG_RADIO_TAVARUA=y
+CONFIG_ION=y
+CONFIG_ION_MSM=y
+CONFIG_MSM_KGSL=y
+CONFIG_MSM_KGSL_DISABLE_SHADOW_WRITES=y
+CONFIG_FB=y
+CONFIG_FB_MSM=y
+# CONFIG_FB_MSM_BACKLIGHT is not set
+CONFIG_FB_MSM_TRIPLE_BUFFER=y
+CONFIG_FB_MSM_MDP30=y
+CONFIG_FB_MSM_MDP303=y
+CONFIG_FB_MSM_MIPI_DIV4_WVGA_NT35510_PANEL=y
+CONFIG_FB_MSM_LCDC_TRULY_HVGA_IPS3P2335_PT_PANEL=y
+CONFIG_FB_MSM_MIPI_PANEL_DETECT=y
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+CONFIG_SOUND=y
+CONFIG_SND=y
+CONFIG_SND_SOC=y
+CONFIG_SND_MSM_SOC=y
+CONFIG_HID_APPLE=y
+CONFIG_HID_MAGICMOUSE=y
+CONFIG_HID_MICROSOFT=y
+CONFIG_USB=y
+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
+CONFIG_USB_SUSPEND=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_EHSET=y
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
+# CONFIG_USB_EHCI_TT_NEWSCHED is not set
+CONFIG_USB_EHCI_MSM_72K=y
+CONFIG_USB_ACM=y
+CONFIG_USB_STORAGE=y
+CONFIG_USB_STORAGE_DATAFAB=y
+CONFIG_USB_STORAGE_FREECOM=y
+CONFIG_USB_STORAGE_ISD200=y
+CONFIG_USB_STORAGE_USBAT=y
+CONFIG_USB_STORAGE_SDDR09=y
+CONFIG_USB_STORAGE_SDDR55=y
+CONFIG_USB_STORAGE_JUMPSHOT=y
+CONFIG_USB_STORAGE_ALAUDA=y
+CONFIG_USB_STORAGE_ONETOUCH=y
+CONFIG_USB_STORAGE_KARMA=y
+CONFIG_USB_STORAGE_CYPRESS_ATACB=y
+CONFIG_USB_EHSET_TEST_FIXTURE=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_MSM_72K=y
+CONFIG_USB_G_ANDROID=y
+CONFIG_RMNET_SMD_CTL_CHANNEL="DATA40_CNTL"
+CONFIG_RMNET_SMD_DATA_CHANNEL="DATA40"
+CONFIG_MMC=y
+CONFIG_MMC_PERF_PROFILING=y
+CONFIG_MMC_UNSAFE_RESUME=y
+CONFIG_MMC_CLKGATE=y
+CONFIG_MMC_PARANOID_SD_INIT=y
+CONFIG_MMC_BLOCK_MINORS=32
+# CONFIG_MMC_BLOCK_BOUNCE is not set
+CONFIG_MMC_TEST=m
+CONFIG_MMC_MSM=y
+CONFIG_MMC_MSM_SDC3_SUPPORT=y
+CONFIG_MMC_MSM_SDC3_8_BIT_SUPPORT=y
+CONFIG_LEDS_MSM_PDM=y
+CONFIG_LEDS_PMIC_MPP=y
+CONFIG_LEDS_MSM_TRICOLOR=y
+CONFIG_LEDS_GPIO=y
+CONFIG_SWITCH=y
+CONFIG_SWITCH_GPIO=y
+CONFIG_RTC_CLASS=y
+CONFIG_STAGING=y
+CONFIG_ANDROID=y
+CONFIG_ANDROID_BINDER_IPC=y
+CONFIG_ANDROID_LOGGER=y
+CONFIG_ANDROID_LOW_MEMORY_KILLER=y
+CONFIG_ANDROID_LOW_MEMORY_KILLER_AUTODETECT_OOM_ADJ_VALUES=y
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
+CONFIG_EXT4_FS=y
+CONFIG_FUSE_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_TMPFS=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_PRINTK_TIME=y
+CONFIG_PRINTK_RTC_TIME=y
+CONFIG_PRINTK_CPU_ID=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_SHIRQ=y
+# CONFIG_DEBUG_PREEMPT is not set
+# CONFIG_SCHED_DEBUG is not set
+CONFIG_TIMER_STATS=y
+CONFIG_DEBUG_SPINLOCK=y
+CONFIG_DEBUG_STACK_USAGE=y
+CONFIG_DEBUG_INFO=y
+CONFIG_ENABLE_DEFAULT_TRACERS=y
+CONFIG_DYNAMIC_DEBUG=y
+CONFIG_DEBUG_USER=y
+CONFIG_CRYPTO_TWOFISH=y
+CONFIG_CRC_CCITT=y
+# Add 20120823 TS-FMC-V2 start
+CONFIG_FB_MSM_MIPI_OTM9608A_PT=y
+CONFIG_PPP=y
+CONFIG_PPP_ASYNC=y
+CONFIG_PPP_DEFLATE=y
+CONFIG_PPP_BSDCOMP=y
+CONFIG_INET_AH=y
+CONFIG_INET_ESP=y
+CONFIG_INET_IPCOMP=y
+CONFIG_L2TP=y
+CONFIG_L2TP_V3=y
+CONFIG_L2TP_IP=y
+CONFIG_L2TP_ETH=y
+CONFIG_IPX=y
+CONFIG_IPX_INTERN=y
+CONFIG_PPP_FILTER=y
+CONFIG_PPP_MPPE=y
+CONFIG_PPP_MULTILINK=y
+CONFIG_PPPOE=y
+CONFIG_PPPOL2TP=y
+CONFIG_PPPOLAC=y
+CONFIG_PPPOPNS=y
+CONFIG_PPP_SYNC_TTY=y
+CONFIG_TCP_MD5SIG=y
+# Add 20120823 TS-FMC-V2 end
+ONFIG_GLANCEVIEW=y
+#===================================================#
+# Added for apanic emmc #
+#===================================================#
+CONFIG_APANIC_MMC=y
+CONFIG_MMC_MSM_RAW=y
+CONFIG_LOG_BUF_SHIFT=20
diff --git a/arch/arm/configs/normandy_s11_defconfig b/arch/arm/configs/normandy_s11_defconfig
new file mode 100755
index 0000000..3cabf97
--- /dev/null
+++ b/arch/arm/configs/normandy_s11_defconfig
@@ -0,0 +1,434 @@
+# CONFIG_ARM_PATCH_PHYS_VIRT is not set
+CONFIG_EXPERIMENTAL=y
+CONFIG_LOCALVERSION="$(KERNEL_LOCAL_VERSION)-perf"
+# CONFIG_SWAP is not set
+CONFIG_SYSVIPC=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_CGROUPS=y
+CONFIG_CGROUP_FREEZER=y
+CONFIG_CGROUP_DEVICE=y
+CONFIG_CGROUP_CPUACCT=y
+CONFIG_RESOURCE_COUNTERS=y
+CONFIG_CGROUP_SCHED=y
+CONFIG_RT_GROUP_SCHED=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_KALLSYMS_ALL=y
+CONFIG_ASHMEM=y
+CONFIG_EMBEDDED=y
+CONFIG_PROFILING=y
+CONFIG_OPROFILE=y
+CONFIG_KPROBES=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+# CONFIG_BLK_DEV_BSG is not set
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_IOSCHED_DEADLINE is not set
+CONFIG_ARCH_MSM=y
+CONFIG_ARCH_MSM7X27=y
+CONFIG_ARCH_MSM8625=y
+CONFIG_MSM_SOC_REV_A=y
+# CONFIG_MACH_MSM7X27_SURF is not set
+# CONFIG_MACH_MSM7X27_FFA is not set
+# CONFIG_MSM_STACKED_MEMORY is not set
+CONFIG_MSM7X00A_USE_DG_TIMER=y
+# CONFIG_MSM_FIQ_SUPPORT is not set
+CONFIG_MSM_SMD=y
+CONFIG_MSM_AMSS_ENHANCE_DEBUG=y
+CONFIG_MSM_SMD_PKG4=y
+# CONFIG_MSM_SMD_DEBUG is not set
+# CONFIG_MSM_RESET_MODEM is not set
+# CONFIG_MSM_SMD_NMEA is not set
+# CONFIG_MSM_SMD_QMI is not set
+CONFIG_MSM_ONCRPCROUTER=y
+CONFIG_MSM_IPC_ROUTER=y
+# CONFIG_MSM_RPCSERVER_TIME_REMOTE is not set
+CONFIG_MSM_RMT_STORAGE_CLIENT=y
+# CONFIG_MSM_HW3D is not set
+CONFIG_MSM7X27A_AUDIO=y
+CONFIG_MSM_DMA_TEST=y
+CONFIG_MSM_SLEEP_STATS_DEVICE=y
+CONFIG_MSM_SM_EVENT=y
+CONFIG_MSM_SM_EVENT_LOG=m
+CONFIG_MSM_SLEEP_MONITOR=m
+CONFIG_MSM_FAST_BOOT=y
+CONFIG_BT_MSM_PINTEST=y
+CONFIG_MSM_RPC_VIBRATOR=y
+CONFIG_PM8XXX_RPC_VIBRATOR=y
+CONFIG_MSM_SPM_V2=y
+CONFIG_MSM_MULTIMEDIA_USE_ION=y
+CONFIG_MSM_FUSE_INFO_DEBUG=y
+CONFIG_MSM_CPR=y
+CONFIG_MSM_VP_REGULATOR=y
+CONFIG_MSM_FIQ=y
+CONFIG_MSM_PBUS=y
+CONFIG_ARM_THUMBEE=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_SMP=y
+CONFIG_PREEMPT=y
+CONFIG_AEABI=y
+CONFIG_HIGHMEM=y
+CONFIG_VMALLOC_RESERVE=0xC800000
+CONFIG_COMPACTION=y
+CONFIG_CP_ACCESS=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="init=/sbin/init root=/dev/ram rw initrd=0x11000000,16M console=ttyDCC0 mem=88M"
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_STAT_DETAILS=y
+CONFIG_CPU_FREQ_GOV_POWERSAVE=y
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_GOV_ONDEMAND=y
+CONFIG_CPU_FREQ_GOV_INTERACTIVE=y
+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
+CONFIG_VFP=y
+CONFIG_NEON=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_WAKELOCK=y
+CONFIG_PM_RUNTIME=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_IP_MULTIPLE_TABLES=y
+CONFIG_IPV6=y
+CONFIG_IPV6_PRIVACY=y
+CONFIG_IPV6_ROUTER_PREF=y
+CONFIG_IPV6_ROUTE_INFO=y
+CONFIG_IPV6_OPTIMISTIC_DAD=y
+CONFIG_INET6_AH=y
+CONFIG_INET6_ESP=y
+CONFIG_INET6_IPCOMP=y
+CONFIG_IPV6_MIP6=y
+CONFIG_IPV6_TUNNEL=y
+CONFIG_IPV6_MULTIPLE_TABLES=y
+CONFIG_IPV6_SUBTREES=y
+CONFIG_NETFILTER=y
+CONFIG_NETFILTER_NETLINK_LOG=y
+CONFIG_NF_CONNTRACK=y
+CONFIG_NF_CONNTRACK_EVENTS=y
+CONFIG_NF_CT_PROTO_DCCP=y
+CONFIG_NF_CT_PROTO_SCTP=y
+CONFIG_NF_CT_PROTO_UDPLITE=y
+CONFIG_NF_CONNTRACK_AMANDA=y
+CONFIG_NF_CONNTRACK_FTP=y
+CONFIG_NF_CONNTRACK_H323=y
+CONFIG_NF_CONNTRACK_IRC=y
+CONFIG_NF_CONNTRACK_NETBIOS_NS=y
+CONFIG_NF_CONNTRACK_PPTP=y
+CONFIG_NF_CONNTRACK_SANE=y
+CONFIG_NF_CONNTRACK_SIP=y
+CONFIG_NF_CONNTRACK_TFTP=y
+CONFIG_NF_CT_NETLINK=y
+CONFIG_NETFILTER_TPROXY=y
+CONFIG_NETFILTER_XT_TARGET_CLASSIFY=y
+CONFIG_NETFILTER_XT_TARGET_CONNMARK=y
+CONFIG_NETFILTER_XT_TARGET_LOG=y
+CONFIG_NETFILTER_XT_TARGET_MARK=y
+CONFIG_NETFILTER_XT_TARGET_NFQUEUE=y
+CONFIG_NETFILTER_XT_MATCH_COMMENT=y
+CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=y
+CONFIG_NETFILTER_XT_MATCH_CONNMARK=y
+CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y
+CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=y
+CONFIG_NETFILTER_XT_MATCH_HELPER=y
+CONFIG_NETFILTER_XT_MATCH_IPRANGE=y
+CONFIG_NETFILTER_XT_MATCH_LENGTH=y
+CONFIG_NETFILTER_XT_MATCH_LIMIT=y
+CONFIG_NETFILTER_XT_MATCH_MAC=y
+CONFIG_NETFILTER_XT_MATCH_MARK=y
+CONFIG_NETFILTER_XT_MATCH_POLICY=y
+CONFIG_NETFILTER_XT_MATCH_PKTTYPE=y
+CONFIG_NETFILTER_XT_MATCH_QTAGUID=y
+CONFIG_NETFILTER_XT_MATCH_QUOTA=y
+CONFIG_NETFILTER_XT_MATCH_QUOTA2=y
+CONFIG_NETFILTER_XT_MATCH_QUOTA2_LOG=y
+CONFIG_NETFILTER_XT_MATCH_SOCKET=y
+CONFIG_NETFILTER_XT_MATCH_STATE=y
+CONFIG_NETFILTER_XT_MATCH_STATISTIC=y
+CONFIG_NETFILTER_XT_MATCH_STRING=y
+CONFIG_NETFILTER_XT_MATCH_TIME=y
+CONFIG_NETFILTER_XT_MATCH_U32=y
+CONFIG_NF_CONNTRACK_IPV4=y
+CONFIG_IP_NF_IPTABLES=y
+CONFIG_IP_NF_MATCH_AH=y
+CONFIG_IP_NF_MATCH_ECN=y
+CONFIG_IP_NF_MATCH_TTL=y
+CONFIG_IP_NF_FILTER=y
+CONFIG_IP_NF_TARGET_REJECT=y
+CONFIG_NF_NAT=y
+CONFIG_IP_NF_TARGET_MASQUERADE=y
+CONFIG_IP_NF_TARGET_NETMAP=y
+CONFIG_IP_NF_TARGET_REDIRECT=y
+CONFIG_IP_NF_MANGLE=y
+CONFIG_IP_NF_RAW=y
+CONFIG_IP_NF_ARPTABLES=y
+CONFIG_IP_NF_ARPFILTER=y
+CONFIG_IP_NF_ARP_MANGLE=y
+CONFIG_IP6_NF_IPTABLES=y
+CONFIG_IP6_NF_FILTER=y
+CONFIG_IP6_NF_MANGLE=y
+CONFIG_IP6_NF_RAW=y
+CONFIG_BT=y
+CONFIG_BT_RFCOMM=y
+CONFIG_BT_RFCOMM_TTY=y
+CONFIG_BT_BNEP=y
+CONFIG_BT_BNEP_MC_FILTER=y
+CONFIG_BT_BNEP_PROTO_FILTER=y
+CONFIG_BT_HIDP=y
+CONFIG_BT_HCIUART=y
+CONFIG_BT_HCIUART_H4=y
+CONFIG_BT_HCIUART_IBS=y
+CONFIG_MSM_BT_POWER=y
+CONFIG_CFG80211=m
+# CONFIG_CFG80211_WEXT is not set
+CONFIG_RFKILL=y
+CONFIG_GENLOCK=y
+CONFIG_GENLOCK_MISCDEVICE=y
+CONFIG_MTD=y
+CONFIG_MTD_TESTS=m
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLOCK=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_MISC_DEVICES=y
+#byd CONFIG_SENSORS_AK8975=y
+#byd CONFIG_MPU_SENSORS_TIMERIRQ=y
+#byd CONFIG_MPU_SENSORS_BMA250=y
+#byd CONFIG_MPU_SENSORS_MMC328X=y
+CONFIG_SENSORS_BMA2X2=y
+CONFIG_SENSORS_LTR559=y
+CONFIG_SCSI=y
+CONFIG_SCSI_TGT=y
+CONFIG_BLK_DEV_SD=y
+CONFIG_CHR_DEV_SG=y
+CONFIG_CHR_DEV_SCH=y
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_LOGGING=y
+CONFIG_SCSI_SCAN_ASYNC=y
+CONFIG_MD=y
+CONFIG_BLK_DEV_DM=y
+CONFIG_DM_CRYPT=y
+CONFIG_NETDEVICES=y
+CONFIG_TUN=y
+CONFIG_SMC91X=y
+CONFIG_SMSC911X=y
+CONFIG_LIBRA_SDIOIF=m
+# CONFIG_INPUT_MOUSEDEV is not set
+CONFIG_INPUT_EVDEV=y
+CONFIG_INPUT_EVBUG=m
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+#byd rm CONFIG_TOUCHSCREEN_ATMEL_MAXTOUCH=y
+#byd rm CONFIG_TOUCHSCREEN_ATMEL_MXT=y
+CONFIG_TOUCHSCREEN_SYNAPTICS_RMI4_I2C=y
+#byd rm CONFIG_TOUCHSCREEN_FT5X06=y
+# CONFIG_TOUCHSCREEN_FOCAL=y
+CONFIG_TOUCHSCREEN_FT6306=y
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_UINPUT=y
+CONFIG_INPUT_GPIO=y
+#byd rm CONFIG_INPUT_LTR502=y
+#byd rm CONFIG_INPUT_LTR558=y
+#byd rm CONFIG_BOSCH_BMA250=y
+#byd rm CONFIG_INPUT_ISL29028=y
+#byd rm CONFIG_INPUT_LIS3DH=y
+#byd rm CONFIG_AVAGO_APDS990X=y
+#byd rm CONFIG_SENSORS_TMD2771X=y
+# CONFIG_SERIO is not set
+# CONFIG_LEGACY_PTYS is not set
+CONFIG_SERIAL_MSM=y
+CONFIG_SERIAL_MSM_CONSOLE=y
+CONFIG_SERIAL_MSM_HS=y
+# CONFIG_SERIAL_MSM_CLOCK_CONTROL is not set
+CONFIG_DIAG_CHAR=y
+# CONFIG_HW_RANDOM is not set
+CONFIG_I2C=y
+CONFIG_I2C_CHARDEV=y
+CONFIG_I2C_GPIO=y
+# CONFIG_I2C_MSM is not set
+CONFIG_I2C_QUP=y
+CONFIG_DEBUG_GPIO=y
+CONFIG_GPIO_SYSFS=y
+CONFIG_GPIO_SX150X=y
+CONFIG_POWER_SUPPLY=y
+CONFIG_BATTERY_MSM=y
+CONFIG_SENSORS_MSM_ADC=y
+CONFIG_MARIMBA_CORE=y
+CONFIG_REGULATOR_FAN53555=y
+CONFIG_REGULATOR_ONSEMI_NCP6335D=y
+CONFIG_REGULATOR_MSM_GPIO=y
+CONFIG_MEDIA_SUPPORT=y
+CONFIG_MEDIA_CONTROLLER=y
+CONFIG_VIDEO_DEV=y
+CONFIG_VIDEO_V4L2_SUBDEV_API=y
+# CONFIG_RC_CORE is not set
+# CONFIG_MEDIA_TUNER_CUSTOMISE is not set
+CONFIG_VIDEOBUF2_MSM_MEM=y
+CONFIG_V4L_PLATFORM_DRIVERS=y
+CONFIG_MSM_CAMERA_V4L2=y
+# CONFIG_OV5647 is not set
+# CONFIG_OV5647_DALING_OVBD631AC is not set
+CONFIG_S5K5CA=y
+CONFIG_S5K5CA_DARLING=y
+# CONFIG_HI351_SUNNY_Q3H01B is not set
+# CONFIG_OV5647_PARTRON_CM500 is not set
+# CONFIG_OV5647_HQ_O9B5_DG806T=y
+CONFIG_AR0542=y
+# CONFIG_OV5647_TRULY_CM6868 is not set
+# CONFIG_OV5648_TRULY_CM8352=y
+CONFIG_AD5046_ACT=y
+#byd rm CONFIG_WEBCAM_OV9726=y
+#byd rm CONFIG_MT9E013=y
+#byd rm CONFIG_S5K4E1=y
+#byd rm CONFIG_DW9712_ACT=y
+#CONFIG_MSM_CAMERA_FLASH_SC628A=y
+CONFIG_OV8825=y
+CONFIG_MSM_CAMERA_SENSOR=y
+CONFIG_MSM_ACTUATOR=y
+#CONFIG_OV7692=y
+# CONFIG_WEBCAM_OV7692_QRD is not set
+# CONFIG_OV7695 is not set
+# CONFIG_OV7695_RAW=y
+# CONFIG_MT9V115=y
+CONFIG_RADIO_TAVARUA=y
+CONFIG_ION=y
+CONFIG_ION_MSM=y
+CONFIG_MSM_KGSL=y
+CONFIG_MSM_KGSL_DISABLE_SHADOW_WRITES=y
+CONFIG_FB=y
+CONFIG_FB_MSM=y
+# CONFIG_FB_MSM_BACKLIGHT is not set
+CONFIG_FB_MSM_TRIPLE_BUFFER=y
+CONFIG_FB_MSM_MDP30=y
+CONFIG_FB_MSM_MDP303=y
+CONFIG_FB_MSM_MIPI_DIV4_WVGA_NT35510_PANEL=y
+CONFIG_FB_MSM_LCDC_TRULY_HVGA_IPS3P2335_PT_PANEL=y
+CONFIG_FB_MSM_MIPI_PANEL_DETECT=y
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+CONFIG_SOUND=y
+CONFIG_SND=y
+CONFIG_SND_SOC=y
+CONFIG_SND_MSM_SOC=y
+CONFIG_HID_APPLE=y
+CONFIG_HID_MAGICMOUSE=y
+CONFIG_HID_MICROSOFT=y
+CONFIG_USB=y
+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
+CONFIG_USB_SUSPEND=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_EHSET=y
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
+# CONFIG_USB_EHCI_TT_NEWSCHED is not set
+CONFIG_USB_EHCI_MSM_72K=y
+CONFIG_USB_ACM=y
+CONFIG_USB_STORAGE=y
+CONFIG_USB_STORAGE_DATAFAB=y
+CONFIG_USB_STORAGE_FREECOM=y
+CONFIG_USB_STORAGE_ISD200=y
+CONFIG_USB_STORAGE_USBAT=y
+CONFIG_USB_STORAGE_SDDR09=y
+CONFIG_USB_STORAGE_SDDR55=y
+CONFIG_USB_STORAGE_JUMPSHOT=y
+CONFIG_USB_STORAGE_ALAUDA=y
+CONFIG_USB_STORAGE_ONETOUCH=y
+CONFIG_USB_STORAGE_KARMA=y
+CONFIG_USB_STORAGE_CYPRESS_ATACB=y
+CONFIG_USB_EHSET_TEST_FIXTURE=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_MSM_72K=y
+CONFIG_USB_G_ANDROID=y
+CONFIG_RMNET_SMD_CTL_CHANNEL="DATA40_CNTL"
+CONFIG_RMNET_SMD_DATA_CHANNEL="DATA40"
+CONFIG_MMC=y
+CONFIG_MMC_PERF_PROFILING=y
+CONFIG_MMC_UNSAFE_RESUME=y
+CONFIG_MMC_CLKGATE=y
+CONFIG_MMC_PARANOID_SD_INIT=y
+CONFIG_MMC_BLOCK_MINORS=32
+# CONFIG_MMC_BLOCK_BOUNCE is not set
+CONFIG_MMC_TEST=m
+CONFIG_MMC_MSM=y
+CONFIG_MMC_MSM_SDC3_SUPPORT=y
+CONFIG_MMC_MSM_SDC3_8_BIT_SUPPORT=y
+CONFIG_LEDS_MSM_PDM=y
+CONFIG_LEDS_PMIC_MPP=y
+CONFIG_LEDS_MSM_TRICOLOR=y
+CONFIG_LEDS_GPIO=y
+CONFIG_SWITCH=y
+CONFIG_SWITCH_GPIO=y
+CONFIG_RTC_CLASS=y
+CONFIG_STAGING=y
+CONFIG_ANDROID=y
+CONFIG_ANDROID_BINDER_IPC=y
+CONFIG_ANDROID_LOGGER=y
+CONFIG_ANDROID_LOW_MEMORY_KILLER=y
+CONFIG_ANDROID_LOW_MEMORY_KILLER_AUTODETECT_OOM_ADJ_VALUES=y
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT3_FS=y
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
+CONFIG_EXT4_FS=y
+CONFIG_FUSE_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_TMPFS=y
+CONFIG_YAFFS_FS=y
+CONFIG_YAFFS_DISABLE_TAGS_ECC=y
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_PRINTK_TIME=y
+CONFIG_PRINTK_RTC_TIME=y
+CONFIG_PRINTK_CPU_ID=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_SHIRQ=y
+# CONFIG_DEBUG_PREEMPT is not set
+# CONFIG_SCHED_DEBUG is not set
+CONFIG_TIMER_STATS=y
+CONFIG_DEBUG_SPINLOCK=y
+CONFIG_DEBUG_STACK_USAGE=y
+CONFIG_DEBUG_INFO=y
+CONFIG_ENABLE_DEFAULT_TRACERS=y
+CONFIG_DYNAMIC_DEBUG=y
+CONFIG_DEBUG_USER=y
+CONFIG_CRYPTO_TWOFISH=y
+CONFIG_CRC_CCITT=y
+# Add 20120823 TS-FMC-V2 start
+CONFIG_FB_MSM_MIPI_OTM9608A_PT=y
+CONFIG_PPP=y
+CONFIG_PPP_ASYNC=y
+CONFIG_PPP_DEFLATE=y
+CONFIG_PPP_BSDCOMP=y
+CONFIG_INET_AH=y
+CONFIG_INET_ESP=y
+CONFIG_INET_IPCOMP=y
+CONFIG_L2TP=y
+CONFIG_L2TP_V3=y
+CONFIG_L2TP_IP=y
+CONFIG_L2TP_ETH=y
+CONFIG_IPX=y
+CONFIG_IPX_INTERN=y
+CONFIG_PPP_FILTER=y
+CONFIG_PPP_MPPE=y
+CONFIG_PPP_MULTILINK=y
+CONFIG_PPPOE=y
+CONFIG_PPPOL2TP=y
+CONFIG_PPPOLAC=y
+CONFIG_PPPOPNS=y
+CONFIG_PPP_SYNC_TTY=y
+CONFIG_TCP_MD5SIG=y
+# Add 20120823 TS-FMC-V2 end
+ONFIG_GLANCEVIEW=y
+#===================================================#
+# Added for apanic emmc #
+#===================================================#
+CONFIG_APANIC_MMC=y
+CONFIG_MMC_MSM_RAW=y
+CONFIG_LOG_BUF_SHIFT=20
diff --git a/arch/arm/include/asm/hardware/cache-l2x0.h b/arch/arm/include/asm/hardware/cache-l2x0.h
index 926ac0e..27ecb3a 100644
--- a/arch/arm/include/asm/hardware/cache-l2x0.h
+++ b/arch/arm/include/asm/hardware/cache-l2x0.h
@@ -116,6 +116,7 @@
#define L2X0_PREFETCH_CTRL_WRAP8_SHIFT 30
#ifndef __ASSEMBLY__
+extern void __iomem *l2x0_base;
extern void l2cc_suspend(void);
extern void l2cc_resume(void);
extern void l2x0_cache_sync(void);
diff --git a/arch/arm/include/asm/mach/mmc.h b/arch/arm/include/asm/mach/mmc.h
index 562f13c..cb9f184 100644
--- a/arch/arm/include/asm/mach/mmc.h
+++ b/arch/arm/include/asm/mach/mmc.h
@@ -157,6 +157,7 @@ struct mmc_platform_data {
unsigned int msmsdcc_fmid;
unsigned int msmsdcc_fmax;
bool nonremovable;
+ bool hw_resetable;
unsigned int mpm_sdiowakeup_int;
unsigned int wpswitch_gpio;
bool is_wpswitch_active_low;
diff --git a/arch/arm/include/asm/perf_event.h b/arch/arm/include/asm/perf_event.h
index a40f81e..4f41fd6 100644
--- a/arch/arm/include/asm/perf_event.h
+++ b/arch/arm/include/asm/perf_event.h
@@ -22,6 +22,7 @@ enum arm_perf_pmu_ids {
ARM_PERF_PMU_ID_CA9,
ARM_PERF_PMU_ID_CA5,
ARM_PERF_PMU_ID_CA15,
+ ARM_PERF_PMU_ID_L2X0,
ARM_PERF_PMU_ID_CA7,
ARM_PERF_PMU_ID_SCORPION,
ARM_PERF_PMU_ID_SCORPIONMP,
diff --git a/arch/arm/include/asm/pmu.h b/arch/arm/include/asm/pmu.h
index 37cbfcb..5188dbf 100644
--- a/arch/arm/include/asm/pmu.h
+++ b/arch/arm/include/asm/pmu.h
@@ -32,6 +32,10 @@ enum arm_pmu_type {
* interrupt and passed the address of the low level handler,
* and can be used to implement any platform specific handling
* before or after calling it.
+ * @request_pmu_irq: an optional handler in case the platform wants
+ * to use a percpu IRQ API call. e.g. request_percpu_irq
+ * @free_pmu_irq: an optional handler in case the platform wants
+ * to use a percpu IRQ API call. e.g. free_percpu_irq
* @enable_irq: an optional handler which will be called after
* request_irq and be used to handle some platform specific
* irq enablement
@@ -42,6 +46,8 @@ enum arm_pmu_type {
struct arm_pmu_platdata {
irqreturn_t (*handle_irq)(int irq, void *dev,
irq_handler_t pmu_handler);
+ int (*request_pmu_irq)(int irq, irq_handler_t *irq_h);
+ void (*free_pmu_irq)(int irq);
void (*enable_irq)(int irq);
void (*disable_irq)(int irq);
};
@@ -108,9 +114,14 @@ struct arm_pmu {
enum arm_pmu_type type;
cpumask_t active_irqs;
const char *name;
+ int num_events;
+ atomic_t active_events;
+ struct mutex reserve_mutex;
+ u64 max_period;
+ struct platform_device *plat_device;
irqreturn_t (*handle_irq)(int irq_num, void *dev);
- int (*request_pmu_irq)(int irq, irq_handler_t *irq_h);
- void (*free_pmu_irq)(int irq);
+ int (*request_pmu_irq)(int irq, irq_handler_t *irq_h);
+ void (*free_pmu_irq)(int irq);
void (*enable)(struct hw_perf_event *evt, int idx, int cpu);
void (*disable)(struct hw_perf_event *evt, int idx);
int (*get_event_idx)(struct pmu_hw_events *hw_events,
@@ -123,11 +134,6 @@ struct arm_pmu {
void (*stop)(void);
void (*reset)(void *);
int (*map_event)(struct perf_event *event);
- int num_events;
- atomic_t active_events;
- struct mutex reserve_mutex;
- u64 max_period;
- struct platform_device *plat_device;
struct pmu_hw_events *(*get_hw_events)(void);
int (*test_set_event_constraints)(struct perf_event *event);
int (*clear_event_constraints)(struct perf_event *event);
diff --git a/arch/arm/include/asm/smp.h b/arch/arm/include/asm/smp.h
index 7f74b59..ce72022 100644
--- a/arch/arm/include/asm/smp.h
+++ b/arch/arm/include/asm/smp.h
@@ -94,5 +94,6 @@ extern void arch_send_call_function_single_ipi(int cpu);
extern void arch_send_call_function_ipi_mask(const struct cpumask *mask);
extern void smp_send_all_cpu_backtrace(void);
+extern void smp_send_all_cpu_ping(void);
#endif /* ifndef __ASM_ARM_SMP_H */
diff --git a/arch/arm/include/asm/thread_info.h b/arch/arm/include/asm/thread_info.h
old mode 100644
new mode 100755
index 0f04d84..99460ae
--- a/arch/arm/include/asm/thread_info.h
+++ b/arch/arm/include/asm/thread_info.h
@@ -154,6 +154,8 @@ extern int vfp_restore_user_hwstate(struct user_vfp __user *,
#define TIF_RESTORE_SIGMASK 20
#define TIF_SECCOMP 21
+#define TIF_MM_RELEASED 22 /* task MM has been released */
+
#define _TIF_SIGPENDING (1 << TIF_SIGPENDING)
#define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED)
#define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME)
diff --git a/arch/arm/include/asm/uaccess.h b/arch/arm/include/asm/uaccess.h
index 71f6536..cd0b330 100644
--- a/arch/arm/include/asm/uaccess.h
+++ b/arch/arm/include/asm/uaccess.h
@@ -101,28 +101,38 @@ extern int __get_user_1(void *);
extern int __get_user_2(void *);
extern int __get_user_4(void *);
-#define __get_user_x(__r2,__p,__e,__s,__i...) \
+#define __GUP_CLOBBER_1 "lr", "cc"
+#ifdef CONFIG_CPU_USE_DOMAINS
+#define __GUP_CLOBBER_2 "ip", "lr", "cc"
+#else
+#define __GUP_CLOBBER_2 "lr", "cc"
+#endif
+#define __GUP_CLOBBER_4 "lr", "cc"
+
+#define __get_user_x(__r2,__p,__e,__l,__s) \
__asm__ __volatile__ ( \
__asmeq("%0", "r0") __asmeq("%1", "r2") \
+ __asmeq("%3", "r1") \
"bl __get_user_" #__s \
: "=&r" (__e), "=r" (__r2) \
- : "0" (__p) \
- : __i, "cc")
-
+ : "0" (__p), "r" (__l) \
+ : __GUP_CLOBBER_##__s)
#define get_user(x,p) \
({ \
+ unsigned long __limit = current_thread_info()->addr_limit - 1; \
register const typeof(*(p)) __user *__p asm("r0") = (p);\
register unsigned long __r2 asm("r2"); \
+ register unsigned long __l asm("r1") = __limit; \
register int __e asm("r0"); \
switch (sizeof(*(__p))) { \
case 1: \
- __get_user_x(__r2, __p, __e, 1, "lr"); \
- break; \
+ __get_user_x(__r2, __p, __e, __l, 1); \
+ break; \
case 2: \
- __get_user_x(__r2, __p, __e, 2, "r3", "lr"); \
+ __get_user_x(__r2, __p, __e, __l, 2); \
break; \
case 4: \
- __get_user_x(__r2, __p, __e, 4, "lr"); \
+ __get_user_x(__r2, __p, __e, __l, 4); \
break; \
default: __e = __get_user_bad(); break; \
} \
@@ -135,31 +145,34 @@ extern int __put_user_2(void *, unsigned int);
extern int __put_user_4(void *, unsigned int);
extern int __put_user_8(void *, unsigned long long);
-#define __put_user_x(__r2,__p,__e,__s) \
+#define __put_user_x(__r2,__p,__e,__l,__s) \
__asm__ __volatile__ ( \
__asmeq("%0", "r0") __asmeq("%2", "r2") \
+ __asmeq("%3", "r1") \
"bl __put_user_" #__s \
: "=&r" (__e) \
- : "0" (__p), "r" (__r2) \
+ : "0" (__p), "r" (__r2), "r" (__l) \
: "ip", "lr", "cc")
#define put_user(x,p) \
({ \
+ unsigned long __limit = current_thread_info()->addr_limit - 1; \
register const typeof(*(p)) __r2 asm("r2") = (x); \
register const typeof(*(p)) __user *__p asm("r0") = (p);\
+ register unsigned long __l asm("r1") = __limit; \
register int __e asm("r0"); \
switch (sizeof(*(__p))) { \
case 1: \
- __put_user_x(__r2, __p, __e, 1); \
+ __put_user_x(__r2, __p, __e, __l, 1); \
break; \
case 2: \
- __put_user_x(__r2, __p, __e, 2); \
+ __put_user_x(__r2, __p, __e, __l, 2); \
break; \
case 4: \
- __put_user_x(__r2, __p, __e, 4); \
+ __put_user_x(__r2, __p, __e, __l, 4); \
break; \
case 8: \
- __put_user_x(__r2, __p, __e, 8); \
+ __put_user_x(__r2, __p, __e, __l, 8); \
break; \
default: __e = __put_user_bad(); break; \
} \
diff --git a/arch/arm/kernel/perf_event.c b/arch/arm/kernel/perf_event.c
index b18f01b..80cd0e9 100644
--- a/arch/arm/kernel/perf_event.c
+++ b/arch/arm/kernel/perf_event.c
@@ -41,6 +41,7 @@
*/
#define ARMPMU_MAX_HWEVENTS 32
+static DEFINE_PER_CPU(u32, from_idle);
static DEFINE_PER_CPU(struct perf_event * [ARMPMU_MAX_HWEVENTS], hw_events);
static DEFINE_PER_CPU(unsigned long [BITS_TO_LONGS(ARMPMU_MAX_HWEVENTS)], used_mask);
static DEFINE_PER_CPU(struct pmu_hw_events, cpu_hw_events);
@@ -113,10 +114,9 @@ static int
armpmu_map_event(const unsigned (*event_map)[PERF_COUNT_HW_MAX], u64 config)
{
int mapping;
-
if (config >= PERF_COUNT_HW_MAX)
- return -EINVAL;
-
+ return -ENOENT;
+
mapping = (*event_map)[config];
return mapping == HW_OP_UNSUPPORTED ? -ENOENT : mapping;
}
@@ -344,7 +344,6 @@ validate_event(struct pmu_hw_events *hw_events,
if (is_software_event(event))
return 1;
-
if (event->pmu != leader_pmu || event->state <= PERF_EVENT_STATE_OFF)
return 1;
@@ -444,6 +443,16 @@ armpmu_reserve_hardware(struct arm_pmu *armpmu)
else
handle_irq = armpmu->handle_irq;
+ if (plat && plat->request_pmu_irq)
+ armpmu->request_pmu_irq = plat->request_pmu_irq;
+ else if (!armpmu->request_pmu_irq)
+ armpmu->request_pmu_irq = armpmu_generic_request_irq;
+
+ if (plat && plat->free_pmu_irq)
+ armpmu->free_pmu_irq = plat->free_pmu_irq;
+ else if (!armpmu->free_pmu_irq)
+ armpmu->free_pmu_irq = armpmu_generic_free_irq;
+
irqs = min(pmu_device->num_resources, num_possible_cpus());
if (irqs < 1) {
pr_err("no irqs for PMUs defined\n");
@@ -608,6 +617,24 @@ static void armpmu_enable(struct pmu *pmu)
struct arm_pmu *armpmu = to_arm_pmu(pmu);
struct pmu_hw_events *hw_events = armpmu->get_hw_events();
int enabled = bitmap_weight(hw_events->used_mask, armpmu->num_events);
+ int idx;
+
+ if (__get_cpu_var(from_idle)) {
+ for (idx = 0; idx <= cpu_pmu->num_events; ++idx) {
+ struct perf_event *event = hw_events->events[idx];
+
+ if (!event)
+ continue;
+
+ armpmu->enable(&event->hw, idx, event->cpu);
+ }
+
+ /* Reset bit so we don't needlessly re-enable counters.*/
+ __get_cpu_var(from_idle) = 0;
+ }
+
+ /* So we don't start the PMU before enabling counters after idle. */
+ barrier();
if (enabled)
armpmu->start();
@@ -793,6 +820,11 @@ static int perf_cpu_pm_notifier(struct notifier_block *self, unsigned long cmd,
case CPU_PM_ENTER_FAILED:
case CPU_PM_EXIT:
if (cpu_has_active_perf() && cpu_pmu->reset) {
+ /*
+ * Flip this bit so armpmu_enable knows it needs
+ * to re-enable active counters.
+ */
+ __get_cpu_var(from_idle) = 1;
cpu_pmu->reset(NULL);
perf_pmu_enable(&cpu_pmu->pmu);
}
diff --git a/arch/arm/kernel/perf_event_msm.c b/arch/arm/kernel/perf_event_msm.c
index 5792004..92dc7c7 100644
--- a/arch/arm/kernel/perf_event_msm.c
+++ b/arch/arm/kernel/perf_event_msm.c
@@ -709,8 +709,6 @@ static void scorpion_pmu_reset(void *info)
static struct arm_pmu scorpion_pmu = {
.handle_irq = armv7pmu_handle_irq,
- .request_pmu_irq = msm_request_irq,
- .free_pmu_irq = msm_free_irq,
.enable = scorpion_pmu_enable_event,
.disable = scorpion_pmu_disable_event,
.read_counter = armv7pmu_read_counter,
diff --git a/arch/arm/kernel/perf_event_msm_krait.c b/arch/arm/kernel/perf_event_msm_krait.c
index 0dc7739..5708d74 100644
--- a/arch/arm/kernel/perf_event_msm_krait.c
+++ b/arch/arm/kernel/perf_event_msm_krait.c
@@ -520,53 +520,6 @@ static void krait_pmu_reset(void *info)
armv7_pmnc_write(ARMV7_PMNC_P | ARMV7_PMNC_C);
}
-static void enable_irq_callback(void *info)
-{
- int irq = *(unsigned int *)info;
-
- enable_percpu_irq(irq, IRQ_TYPE_EDGE_RISING);
-}
-
-static void disable_irq_callback(void *info)
-{
- int irq = *(unsigned int *)info;
-
- disable_percpu_irq(irq);
-}
-
-static int
-msm_request_irq(int irq, irq_handler_t *handle_irq)
-{
- int err = 0;
- int cpu;
-
- err = request_percpu_irq(irq, *handle_irq, "krait-l1-armpmu",
- &cpu_hw_events);
-
- if (!err) {
- for_each_cpu(cpu, cpu_online_mask) {
- smp_call_function_single(cpu,
- enable_irq_callback, &irq, 1);
- }
- }
-
- return err;
-}
-
-static void
-msm_free_irq(int irq)
-{
- int cpu;
-
- if (irq >= 0) {
- for_each_cpu(cpu, cpu_online_mask) {
- smp_call_function_single(cpu,
- disable_irq_callback, &irq, 1);
- }
- free_percpu_irq(irq, &cpu_hw_events);
- }
-}
-
/*
* We check for column exclusion constraints here.
* Two events cant have same reg and same group.
@@ -621,8 +574,6 @@ static int msm_clear_ev_constraint(struct perf_event *event)
static struct arm_pmu krait_pmu = {
.handle_irq = armv7pmu_handle_irq,
- .request_pmu_irq = msm_request_irq,
- .free_pmu_irq = msm_free_irq,
.enable = krait_pmu_enable_event,
.disable = krait_pmu_disable_event,
.read_counter = armv7pmu_read_counter,
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index 3ee6721..ed74b4c 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -554,6 +554,20 @@ void smp_send_all_cpu_backtrace(void)
smp_mb__after_clear_bit();
}
+void smp_send_all_cpu_ping(void)
+{
+ struct cpumask mask;
+ int cpu = smp_processor_id();
+
+ cpumask_copy(&mask, cpu_online_mask);
+ cpumask_clear_cpu(cpu, &mask);
+ if (!cpumask_empty(&mask)) {
+ pr_info("ping all the CPU from CPU%d\n", cpu);
+ smp_cross_call(&mask, IPI_CPU_START);
+ }
+}
+
+
/*
* ipi_cpu_backtrace - handle IPI from smp_send_all_cpu_backtrace()
*/
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
index 63d402f..747698b 100644
--- a/arch/arm/kernel/traps.c
+++ b/arch/arm/kernel/traps.c
@@ -1,4 +1,6 @@
-/*
+/*
+ * Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
* linux/arch/arm/kernel/traps.c
*
* Copyright (C) 1995-2009 Russell King
@@ -165,6 +167,9 @@ static void dump_instr(const char *lvl, struct pt_regs *regs)
#ifdef CONFIG_ARM_UNWIND
static inline void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk)
{
+#ifdef CONFIG_ARCH_MSM
+ flush_cache_all();
+#endif
unwind_backtrace(regs, tsk);
}
#else
@@ -233,11 +238,20 @@ void show_stack(struct task_struct *tsk, unsigned long *sp)
#define S_ISA " ARM"
#endif
+#ifdef CONFIG_ARCH_MSM
+#define __LOG_BUF_LEN (1 << CONFIG_LOG_BUF_SHIFT)
+extern char __log_buf[];
+extern void flush_log_buf(void *ignored);
+#endif
+
static int __die(const char *str, int err, struct thread_info *thread, struct pt_regs *regs)
{
struct task_struct *tsk = thread->task;
static int die_counter;
int ret;
+#if defined(CONFIG_ARCH_MSM) && defined(CONFIG_OUTER_CACHE)
+ unsigned long paddr;
+#endif
printk(KERN_EMERG "Internal error: %s: %x [#%d]" S_PREEMPT S_SMP
S_ISA "\n", str, err, ++die_counter);
@@ -259,6 +273,14 @@ static int __die(const char *str, int err, struct thread_info *thread, struct pt
dump_instr(KERN_EMERG, regs);
}
+#ifdef CONFIG_ARCH_MSM
+ flush_log_buf(NULL);
+#ifdef CONFIG_OUTER_CACHE
+ paddr = (unsigned long)__virt_to_phys((unsigned long)__log_buf);
+ outer_clean_range(paddr, paddr + __LOG_BUF_LEN);
+#endif
+#endif
+
return ret;
}
diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S
index a8f2858..d33f4a1 100644
--- a/arch/arm/kernel/vmlinux.lds.S
+++ b/arch/arm/kernel/vmlinux.lds.S
@@ -254,7 +254,15 @@ SECTIONS
_edata = .;
}
_edata_loc = __data_loc + SIZEOF(.data);
-
+#ifdef CONFIG_UNCACHED_BUF
+ . = ALIGN(1<<20);
+ .log.data : {
+ __uncached_track_buf = .;
+ *(.log.data)
+ . = ALIGN(1<<20);
+ __end_uncached_track_buf = .;
+ }
+#endif
#ifdef CONFIG_HAVE_TCM
/*
* We align everything to a page boundary so we can
diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig
index ceae39a..302679a 100644
--- a/arch/arm/mach-msm/Kconfig
+++ b/arch/arm/mach-msm/Kconfig
@@ -301,6 +301,7 @@ config ARCH_MSM8625
select MSM_RUN_QUEUE_STATS
select MIGHT_HAVE_CACHE_L2X0
select ARM_HAS_SG_CHAIN
+ select CPU_HAS_L2_PMU
config ARCH_MSM9625
bool "MSM9625"
@@ -311,6 +312,32 @@ config ARCH_MSM9625
select MSM_SMP
select CPU_V7
select MSM_GPIOMUX
+ select MSM_RPM_SMD
+ select MSM_NATIVE_RESTART
+ select MSM_RESTART_V2
+ select MSM_SPM_V2
+ select MSM_PM8X60 if PM
+ select MSM_SCM if SMP
+ select MULTI_IRQ_HANDLER
+ select GPIO_MSM_V3
+ select MAY_HAVE_SPARSE_IRQ
+ select SPARSE_IRQ
+ select MSM_MULTIMEDIA_USE_ION
+ select MSM_RPM_STATS_LOG
+ select MSM_QDSP6_APRV2
+ select MSM_QDSP6V2_CODECS
+ select MSM_AUDIO_QDSP6V2 if SND_SOC
+ select CPU_HAS_L2_PMU
+
+config ARCH_MSM8910
+ bool "MSM8910"
+ select ARM_GIC
+ select GIC_SECURE
+ select ARCH_MSM_CORTEXMP
+ select CPU_V7
+ select MSM_SCM if SMP
+ select MAY_HAVE_SPARSE_IRQ
+ select SPARSE_IRQ
select MULTI_IRQ_HANDLER
select GPIO_MSM_V2
@@ -387,6 +414,7 @@ config ARCH_MSM7X27A
select MIGHT_HAVE_CACHE_L2X0
select ARM_HAS_SG_CHAIN
select MSM_FIQ_SUPPORT
+ select CPU_HAS_L2_PMU
config MSM_VIC
bool
@@ -560,33 +588,29 @@ config MACH_MSM8625_EVB
help
Support for the Qualcomm MSM8625 Reference Design.
-config MACH_MSM8625_QRD7
- depends on ARCH_MSM8625
+config MACH_MSM7X27A_QRD5A
+ depends on ARCH_MSM7X27A
depends on !MSM_STACKED_MEMORY
default y
- bool "MSM8625 QRD7"
+ bool "QRD MSM7x27a SKU5A"
help
- Support for the Qualcomm MSM8625 Reference Design.
+ Support for the Qualcomm MSM7X27A QRD5A Reference Design.
-config MACH_MSM8625_EVT
+config MACH_MSM8625_QRD7
depends on ARCH_MSM8625
depends on !MSM_STACKED_MEMORY
default y
- bool "MSM8625 EVT"
+ bool "MSM8625 QRD7"
help
- Support for the Qualcomm MSM8625 Reference Design.
+ Support for the Qualcomm MSM8625 SKU7 Reference Design.
-config MACH_QRD_SKUD_PRIME
+config MACH_MSM8625_QRD5
depends on ARCH_MSM8625
depends on !MSM_STACKED_MEMORY
default y
- bool "MSM8625 SKUD PRIME"
+ bool "MSM8625 QRD5"
help
- Support for the Qualcomm MSM8625 SKUD prime Reference Design.
- Add support for a SKUD prime reference design based on MSM8x25
- chipset. This device is much closer to a phone than regular form
- factor devices, with new touch, display panel and other hardware
- configurations.
+ Support for the Qualcomm MSM8625 SKU5 Reference Design.
config MACH_MSM8625Q_EVBD
depends on ARCH_MSM8625
@@ -607,11 +631,19 @@ config MACH_MSM8625Q_SKUD
bool "MSM8625Q SKUD"
help
Support for the Qualcomm MSM8625Q SKUD Reference Design.
- Add support for a SKUD reference design based on MSM8x25Q
+ Add support for a EVBD reference design based on MSM8x25Q
chipset. This device is much closer to a phone than regular form
factor devices, with new touch, display panel and other hardware
configurations.
+config MACH_MSM8625Q_SKUE
+ depends on ARCH_MSM8625
+ depends on !MSM_STACKED_MEMORY
+ default y
+ bool "MSM8625Q SKUE"
+ help
+ Support for the Qualcomm MSM8625Q SKUE Reference Design.
+
config MACH_MSM7X30_SURF
depends on ARCH_MSM7X30
depends on !MSM_STACKED_MEMORY
@@ -1270,6 +1302,13 @@ config MSM_SMD
used to communicate with various services on the baseband
processor.
+config MSM_AMSS_ENHANCE_DEBUG
+ bool "MSM AMSS enhance debug"
+ help
+ Using RPC to tell the modem processer the some log addresses
+ in order that the modem will dump some logs in ap when ap
+ crashes.
+
choice
prompt "MSM Shared memory interface version"
depends on MSM_SMD
@@ -1299,13 +1338,20 @@ config MSM_RPC_SDIO_XPRT
help
SDIO Transport Layer for RPC Rouer
-config MSM_RPC_SDIO_DEBUG
+ config MSM_RPC_SDIO_DEBUG
+
depends on MSM_RPC_SDIO_XPRT
default y
bool "MSM SDIO XPRT debug support"
help
Support for debugging SDIO XPRT
+config MSM_FUSE_INFO_DEBUG
+ default y
+ bool "MSM FUSE debug support"
+ help
+ Support for debugging fuse info
+
config MSM_SMD_DEBUG
depends on MSM_SMD
default y
@@ -1314,6 +1360,12 @@ config MSM_SMD_DEBUG
Support for debugging the SMD for communication
between the ARM9 and ARM11
+config MSM_FAST_BOOT
+ default n
+ bool "MSM fast power on support"
+ help
+ Enable the fast power on support in MSM platform.
+
config MSM_SDIO_AL
depends on ((ARCH_MSM7X30 || MACH_MSM8X60_FUSN_FFA || MACH_TYPE_MSM8X60_FUSION) && HAS_WAKELOCK)
default y
@@ -2186,6 +2238,24 @@ config MSM_RUN_QUEUE_STATS
in user mode, called MPDecision will be using this data to decide
on when to switch off/on the other cores.
+config MSM_SM_EVENT
+ bool "Enable system event monitor
+ select UNCACHED_BUF
+ default n
+
+config MSM_SM_EVENT_LOG
+ depends on MSM_SM_EVENT
+ tristate "Enable system event log"
+ default n
+
+config UNCACHED_BUF
+ bool "reserve uncached memory segment"
+ default n
+
+config MSM_SLEEP_MONITOR
+ tristate "Enable sleep monitor"
+ default n
+
config MSM_STANDALONE_POWER_COLLAPSE
bool "Enable standalone power collapse"
default n
diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile
index f589c97..b811b58 100644
--- a/arch/arm/mach-msm/Makefile
+++ b/arch/arm/mach-msm/Makefile
@@ -22,6 +22,8 @@ endif
endif
endif
+obj-$(CONFIG_MSM_AMSS_ENHANCE_DEBUG) += enhance-debug.o
+
obj-y += acpuclock.o
obj-$(CONFIG_ARCH_MSM_KRAIT) += acpuclock-krait.o
obj-$(CONFIG_ARCH_MSM7X27) += acpuclock-7627.o acpuclock-8625q.o clock-pll.o
@@ -29,7 +31,12 @@ obj-$(CONFIG_ARCH_MSM_SCORPION) += pmu.o
obj-$(CONFIG_ARCH_MSM_SCORPIONMP) += perf_event_msm_l2.o
obj-$(CONFIG_ARCH_MSM_KRAIT) += msm-krait-l2-accessors.o pmu.o perf_event_msm_krait_l2.o
obj-$(CONFIG_ARCH_MSM_KRAIT) += krait-scm.o
-obj-$(CONFIG_ARCH_MSM7X27A) += pmu.o
+ifdef CONFIG_HW_PERF_EVENTS
+obj-$(CONFIG_ARCH_MSM7X27A) += pmu.o perf_event_msm_pl310.o
+obj-$(CONFIG_ARCH_MSM9625) += pmu.o perf_event_msm_pl310.o
+obj-$(CONFIG_ARCH_MSM8625) += pmu.o perf_event_msm_pl310.o
+obj-$(CONFIG_ARCH_MSM9615) += pmu.o perf_event_msm_pl310.o
+endif
ifndef CONFIG_MSM_SMP
obj-$(CONFIG_ARCH_MSM_SCORPION) += msm_fault_handlers.o
@@ -246,7 +253,7 @@ obj-$(CONFIG_MACH_MSM7X27_FFA) += board-msm7x27.o devices-msm7x27.o
obj-$(CONFIG_ARCH_MSM7X27A) += clock-pcom-lookup.o devices-msm7x27a.o
board-7627a-all-objs += board-msm7627a-storage.o board-msm7627a-bt.o board-msm7627a-camera.o
board-7627a-all-objs += audio-7627a-devices.o
-board-7627a-all-objs += board-msm7627a-display.o board-msm7627a-wlan.o board-msm7627a-io.o
+board-7627a-all-objs += board-msm7627a-display.o board-msm7627a-wlan.o board-msm7627a-io.o board-msm7627a-sensor.o
obj-$(CONFIG_MACH_MSM7X27A_RUMI3) += board-msm7x27a.o board-7627a-all.o
obj-$(CONFIG_MACH_MSM7X27A_SURF) += board-msm7x27a.o board-7627a-all.o
obj-$(CONFIG_MACH_MSM7X27A_FFA) += board-msm7x27a.o board-7627a-all.o
@@ -258,9 +265,8 @@ obj-$(CONFIG_MACH_MSM8625_RUMI3) += board-msm7x27a.o
obj-$(CONFIG_MACH_MSM8625_SURF) += board-msm7x27a.o board-7627a-all.o
obj-$(CONFIG_MACH_MSM8625_EVB) += board-qrd7627a.o board-7627a-all.o
obj-$(CONFIG_MACH_MSM8625_QRD7) += board-qrd7627a.o board-7627a-all.o
-obj-$(CONFIG_MACH_QRD_SKUD_PRIME) += board-qrd7627a.o board-7627a-all.o
obj-$(CONFIG_MACH_MSM8625_FFA) += board-msm7x27a.o board-7627a-all.o
-obj-$(CONFIG_MACH_MSM8625_EVT) += board-msm7x27a.o board-7627a-all.o
+obj-$(CONFIG_MACH_MSM8625_QRD5) += board-msm7x27a.o board-7627a-all.o
obj-$(CONFIG_ARCH_MSM7X30) += board-msm7x30.o devices-msm7x30.o memory_topology.o
obj-$(CONFIG_ARCH_MSM7X30) += clock-local.o clock-7x30.o acpuclock-7x30.o clock-pll.o
obj-$(CONFIG_MACH_MSM7X25_SURF) += board-msm7x27.o devices-msm7x25.o
@@ -356,6 +362,9 @@ obj-$(CONFIG_ARCH_MSM9625) += gpiomux-v2.o gpiomux.o
obj-$(CONFIG_MSM_SLEEP_STATS) += idle_stats.o
+obj-$(CONFIG_MSM_SM_EVENT) += sm_event.o
+obj-$(CONFIG_MSM_SM_EVENT_LOG) += sm_event_log.o sm_event_driver.o
+obj-$(CONFIG_MSM_SLEEP_MONITOR) += sleep_monitor.o
obj-$(CONFIG_MSM_SLEEP_STATS_DEVICE) += idle_stats_device.o
obj-$(CONFIG_MSM_DCVS) += msm_dcvs_scm.o msm_dcvs.o msm_dcvs_idle.o
obj-$(CONFIG_MSM_RUN_QUEUE_STATS) += msm_rq_stats.o
@@ -390,6 +399,7 @@ obj-$(CONFIG_MSM_VP_REGULATOR) += msm_vp.o
ifdef CONFIG_MSM_CPR
obj-$(CONFIG_DEBUG_FS) += msm_cpr-debug.o
endif
+obj-$(CONFIG_MSM_FAST_BOOT) += fastboot.o
obj-$(CONFIG_MSM_FIQ) += msm7k_fiq.o
obj-$(CONFIG_MSM_FIQ) += msm7k_fiq_handler.o
obj-$(CONFIG_MSM_PBUS) += pbus_support.o
diff --git a/arch/arm/mach-msm/acpuclock-7627.c b/arch/arm/mach-msm/acpuclock-7627.c
index b93f871..0c6c1b9 100644
--- a/arch/arm/mach-msm/acpuclock-7627.c
+++ b/arch/arm/mach-msm/acpuclock-7627.c
@@ -1016,7 +1016,7 @@ static void __devinit select_freq_plan(void)
* is conflicting with the 7627AA 1GHz parts since 8625 chips
* are using different clock plan based reprogramming method.
*/
- if (cpu_is_msm8625() && pll_mhz[ACPU_PLL_4] == 1008) {
+ if ((cpu_is_msm8625() || cpu_is_msm8625q()) && pll_mhz[ACPU_PLL_4] == 1008) {
if (pll_mhz[ACPU_PLL_1] == 245)
acpu_freq_tbl =
pll0_960_pll1_245_pll2_1200_pll4_1008_2p0;
@@ -1222,7 +1222,9 @@ static struct platform_driver acpuclk_7627_driver = {
static int __init acpuclk_7627_init(void)
{
- return platform_driver_register(&acpuclk_7627_driver);
+ if(!cpu_is_msm8625q())
+ return platform_driver_register(&acpuclk_7627_driver);
+ return 0;
}
postcore_initcall(acpuclk_7627_init);
diff --git a/arch/arm/mach-msm/acpuclock-8625q.c b/arch/arm/mach-msm/acpuclock-8625q.c
index 2ae650d..a0c29c4 100644
--- a/arch/arm/mach-msm/acpuclock-8625q.c
+++ b/arch/arm/mach-msm/acpuclock-8625q.c
@@ -905,7 +905,8 @@ static struct platform_driver acpuclk_8625q_driver = {
static int __init acpuclk_8625q_init(void)
{
-
- return platform_driver_register(&acpuclk_8625q_driver);
+ if(cpu_is_msm8625q())
+ return platform_driver_register(&acpuclk_8625q_driver);
+ return 0;
}
postcore_initcall(acpuclk_8625q_init);
diff --git a/arch/arm/mach-msm/acpuclock-arm11.c b/arch/arm/mach-msm/acpuclock-arm11.c
index 6f900d3..e214daa 100644
--- a/arch/arm/mach-msm/acpuclock-arm11.c
+++ b/arch/arm/mach-msm/acpuclock-arm11.c
@@ -3,7 +3,7 @@
* MSM architecture clock driver
*
* Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2007 QUALCOMM Incorporated
+ * Copyright (c) 2007 Qualcomm Technologies, Inc.
* Author: San Mehat <san@android.com>
*
* This software is licensed under the terms of the GNU General Public
diff --git a/arch/arm/mach-msm/audio-7627a-devices.c b/arch/arm/mach-msm/audio-7627a-devices.c
index 61d06e7..30a079f 100644
--- a/arch/arm/mach-msm/audio-7627a-devices.c
+++ b/arch/arm/mach-msm/audio-7627a-devices.c
@@ -37,6 +37,9 @@ static struct snd_endpoint snd_endpoints_list[] = {
SND(CURRENT, 0x7FFFFFFE),
SND(FM_ANALOG_STEREO_HEADSET, 35),
SND(FM_ANALOG_STEREO_HEADSET_CODEC, 36),
+ //start by fjz
+ SND(NO_MIC_HEADSET, 40),
+ //end
};
#undef SND
@@ -189,6 +192,9 @@ static struct cad_endpoint cad_endpoints_list[] = {
SNDDEV_CAP_VOICE)),
CAD(LP_FM_HEADSET_SPKR_STEREO_RX, 25, (SNDDEV_CAP_TX | SNDDEV_CAP_FM)),
CAD(I2S_RX, 26, (SNDDEV_CAP_RX)),
+ //start by fjz
+ CAD(NO_MIC_HEADSET, 40, (SNDDEV_CAP_RX | SNDDEV_CAP_VOICE)),
+ //end byf fjz
CAD(SPEAKER_PHONE_MIC_ENDFIRE, 45, (SNDDEV_CAP_TX | SNDDEV_CAP_VOICE)),
CAD(HANDSET_MIC_ENDFIRE, 46, (SNDDEV_CAP_TX | SNDDEV_CAP_VOICE)),
CAD(I2S_TX, 48, (SNDDEV_CAP_TX)),
diff --git a/arch/arm/mach-msm/board-msm7627a-bt.c b/arch/arm/mach-msm/board-msm7627a-bt.c
index 503d229..19a9c12 100644
--- a/arch/arm/mach-msm/board-msm7627a-bt.c
+++ b/arch/arm/mach-msm/board-msm7627a-bt.c
@@ -96,26 +96,29 @@ static unsigned fm_i2s_config_power_off[] = {
GPIO_CFG(71, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA),
};
-int gpio_bt_sys_rest_en = 133;
+//int gpio_bt_sys_rest_en = 133;
+int gpio_bt_sys_rest_en = 16;
static void gpio_bt_config(void)
{
+#if 0
u32 socinfo = socinfo_get_platform_version();
if (machine_is_msm7627a_qrd1())
gpio_bt_sys_rest_en = 114;
if (machine_is_msm7627a_evb() || machine_is_msm8625_evb()
- || machine_is_msm8625_evt())
+ || machine_is_msm8625_qrd5() || machine_is_msm7x27a_qrd5a())
gpio_bt_sys_rest_en = 16;
+ if(machine_is_msm8625q_skud() || machine_is_msm8625q_skue() || machine_is_msm8625q_evbd())
+ gpio_bt_sys_rest_en = 35;
if (machine_is_msm8625_qrd7())
gpio_bt_sys_rest_en = 88;
- if (machine_is_qrd_skud_prime() || machine_is_msm8625q_evbd()
- || machine_is_msm8625q_skud())
- gpio_bt_sys_rest_en = 35;
if (machine_is_msm7627a_qrd3()) {
if (socinfo == 0x70002)
gpio_bt_sys_rest_en = 88;
else
gpio_bt_sys_rest_en = 85;
}
+#endif
+ gpio_bt_sys_rest_en = 16;
}
static int bt_set_gpio(int on)
@@ -660,6 +663,10 @@ static int bluetooth_switch_regulators(int on)
goto reg_disable;
}
+ dev_info(&msm_bt_power_device.dev,
+ "%s: regulator_get_voltage of %s is %d\n",
+ __func__, bt_vregs[i].name, regulator_get_voltage(bt_vregs[i].reg));
+
if (bt_vregs[i].is_pin_controlled) {
rc = pmapp_vreg_lpm_pincntrl_vote(id,
bt_vregs[i].pmapp_id,
@@ -988,6 +995,7 @@ void __init msm7627a_bt_power_init(void)
int i, rc = 0;
struct device *dev;
+
gpio_bt_config();
rc = i2c_register_board_info(MSM_GSBI1_QUP_I2C_BUS_ID,
@@ -1014,6 +1022,17 @@ void __init msm7627a_bt_power_init(void)
__func__, bt_vregs[i].name, rc);
goto reg_get_fail;
}
+ if(!strcmp(bt_vregs[i].name, "bt")
+ && ( machine_is_msm7627a_evb()
+ || machine_is_msm8625_evb()
+ || machine_is_msm8625_qrd5()
+ || machine_is_msm8625q_skud()
+ || machine_is_msm8625q_skue()
+ || machine_is_msm8625_qrd7())) {
+ bt_vregs[i].min_level = 3300000;
+ dev_info(dev, "%s: set regulator %s min level to %d\n",
+ __func__, bt_vregs[i].name, bt_vregs[i].min_level);
+ }
}
dev->platform_data = &bluetooth_power;
diff --git a/arch/arm/mach-msm/board-msm7627a-camera.c b/arch/arm/mach-msm/board-msm7627a-camera.c
old mode 100644
new mode 100755
index a756f0b..df7a974
--- a/arch/arm/mach-msm/board-msm7627a-camera.c
+++ b/arch/arm/mach-msm/board-msm7627a-camera.c
@@ -32,27 +32,108 @@
#define GPIO_SKU3_CAM_5MP_CAM_DRIVER_PWDN 30
#define GPIO_SKUD_CAM_5MP_SHDN_N 23 /* PWDN */
-#define GPIO_SKUD_CAM_5MP_CAMIF_RESET 79 /* (board_is(EVT))?123:121 RESET */
+#define GPIO_SKUD_CAM_5MP_CAMIF_RESET 79
#define GPIO_SKUD_CAM_5MP_CAM_VCM_PWDN 16
#define GPIO_SKUD_CAM_1MP_PWDN 85
#define GPIO_SKUD_CAM_LED_EN 34
#define GPIO_SKUD_CAM_LED_FLASH_EN 48
+#define GPIO_SKUD_CAM_5MP_CAMID 127 /*CAMID*/
+
+ #ifndef CONFIG_ODMM
+//static int camera_gpio_front_qrd7[] = {91, 29};//PWDN, RESET
+#endif
+
+
+#define GPIO_SKUE_CAM_5MP_SHDN_N 23
+#define GPIO_SKUE_CAM_5MP_CAMIF_RESET 79
+#define GPIO_SKUE_CAM_LED_EN 34
+#define GPIO_SKUE_CAM_LED_FLASH_EN 48
+#define GPIO_SKUE_CAM_PWR_EN 33
+
#define GPIO_SKU7_CAM_VGA_SHDN 91
#define GPIO_SKU7_CAM_5MP_SHDN_N 93 /* PWDN */
#define GPIO_SKU7_CAM_5MP_CAMIF_RESET 23 /* (board_is(EVT))?123:121 RESET */
+
+#define GPIO_SKUE_CAM_VGA_SHDN 85
+
#define GPIO_NOT_CONFIGURED -1
#define MOUNT_ANGLE_NOT_CONFIGURED -1
+//for qrd7 camera gpio
+#ifdef CONFIG_OV5647
+static int camera_gpio_rear_qrd7[] = {93, 23, 30};//PWDN, RESET, DRIVER_PWDN
+#endif
+
+#ifndef ODMM_PROJECT_STAGE_EVB1
+#define GPIO_SENSOR_ID 29 //add by lwl for sensor id detected
+static int camera_id_status = 0;
+
+#endif
+extern int sku3_lcdc_lcd_camera_power_onoff(int on);
#ifdef CONFIG_MSM_CAMERA_V4L2
static uint32_t camera_off_gpio_table[] = {
GPIO_CFG(15, 0, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA),
+#ifdef CONFIG_OV5647_DALING_OVBD631AC
+ GPIO_CFG(35, 0, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_2MA),
+ GPIO_CFG(13, 0, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_2MA),
+ GPIO_CFG(40, 0, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_2MA),
+ GPIO_CFG(5, 0, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_2MA),
+ GPIO_CFG(6, 0, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_2MA),
+#endif
+//lwl modify
+#ifdef CONFIG_S5K5CA
+ GPIO_CFG(35, 0, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_2MA),
+ GPIO_CFG(13, 0, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_2MA),
+ GPIO_CFG(40, 0, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_2MA),
+ GPIO_CFG(5, 0, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_2MA),
+ GPIO_CFG(6, 0, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_2MA),
+#endif
+
+#ifdef CONFIG_OV5647_PARTRON_CM500
+ GPIO_CFG(35, 0, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_2MA),
+ GPIO_CFG(13, 0, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_2MA),
+ GPIO_CFG(40, 0, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_2MA),
+ GPIO_CFG(5, 0, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_2MA),
+ GPIO_CFG(6, 0, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_2MA),
+#endif
+#ifdef CONFIG_OV5647_HQ_O9B5_DG806T
+ GPIO_CFG(35, 0, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_2MA),
+ GPIO_CFG(13, 0, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_2MA),
+ GPIO_CFG(40, 0, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_2MA),
+ GPIO_CFG(5, 0, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_2MA),
+ GPIO_CFG(6, 0, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_2MA),
+#endif
};
static uint32_t camera_on_gpio_table[] = {
GPIO_CFG(15, 1, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA),
+#ifdef CONFIG_OV5647_DALING_OVBD631AC//shao.wenqi@byd.com; for daling ov5647
+ GPIO_CFG(35, 0, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_2MA),
+ GPIO_CFG(40, 0, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_2MA),
+ GPIO_CFG(5, 0, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_2MA),
+ GPIO_CFG(6, 0, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_2MA),
+ GPIO_CFG(13, 0, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_2MA), // gpio 98 is EBI2_CS2 , to control flash strobe pin
+#endif
+
+#ifdef CONFIG_OV5647_PARTRON_CM500//shao.wenqi@byd.com;add; for partrom module
+ GPIO_CFG(35, 0, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_2MA),
+ GPIO_CFG(40, 0, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_2MA),
+ GPIO_CFG(5, 0, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_2MA),
+ GPIO_CFG(6, 0, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_2MA),
+ GPIO_CFG(13, 0, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_2MA), // gpio 98 is EBI2_CS2 , to control flash strobe pin
+#endif
+
+#ifdef CONFIG_OV5647_HQ_O9B5_DG806T//shao.wenqi@byd.com; add ; for daling moduel
+ GPIO_CFG(35, 0, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_2MA),
+ GPIO_CFG(40, 0, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_2MA),
+ GPIO_CFG(5, 0, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_2MA),
+ GPIO_CFG(6, 0, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_2MA),
+ GPIO_CFG(13, 0, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, GPIO_CFG_2MA), // gpio 98 is EBI2_CS2 , to control flash strobe pin
+#endif
};
+#ifdef CONFIG_S5K4E1 // #suwg
static struct gpio s5k4e1_cam_req_gpio[] = {
{GPIO_CAM_GP_CAMIF_RESET_N, GPIOF_DIR_OUT, "CAM_RESET"},
};
@@ -73,24 +154,43 @@ static struct msm_camera_gpio_conf gpio_conf_s5k4e1 = {
.cam_gpio_set_tbl_size = ARRAY_SIZE(s5k4e1_cam_gpio_set_tbl),
.gpio_no_mux = 1,
};
+#endif
+#ifdef CONFIG_MT9E013 // #suwg
static struct msm_camera_gpio_conf gpio_conf_mt9e013 = {
.camera_off_table = camera_off_gpio_table,
.camera_on_table = camera_on_gpio_table,
.gpio_no_mux = 1,
};
+#endif
+#ifdef CONFIG_WEBCAM_OV9726 // #suwg
static struct msm_camera_gpio_conf gpio_conf_ov9726 = {
.camera_off_table = camera_off_gpio_table,
.camera_on_table = camera_on_gpio_table,
.gpio_no_mux = 1,
};
+#endif
+
+#ifdef CONFIG_WEBCAM_OV7692_QRD
+static struct msm_camera_gpio_conf gpio_conf_ov7692 = {
+ .camera_off_table = camera_off_gpio_table,
+ .camera_on_table = camera_on_gpio_table,
+ .gpio_no_mux = 1,
+};
+#endif
+
#ifdef CONFIG_OV7692
static struct gpio ov7692_cam_req_gpio[] = {
{GPIO_SKU1_CAM_VGA_RESET_N, GPIOF_DIR_OUT, "CAM_VGA_RESET"},
};
+static struct gpio ov7692_cam_req_gpio_sku7[] = {
+ {GPIO_SKU7_CAM_VGA_SHDN, GPIOF_DIR_OUT, "CAM_VGA_SHDN"},
+ {GPIO_SKU1_CAM_VGA_RESET_N, GPIOF_DIR_OUT, "CAM_VGA_RESET"},
+};
+
static struct msm_gpio_set_tbl ov7692_cam_gpio_set_tbl[] = {
{GPIO_SKU1_CAM_VGA_SHDN, GPIOF_OUT_INIT_HIGH, 5000},
{GPIO_SKU1_CAM_VGA_SHDN, GPIOF_OUT_INIT_LOW, 5000},
@@ -98,6 +198,13 @@ static struct msm_gpio_set_tbl ov7692_cam_gpio_set_tbl[] = {
{GPIO_SKU1_CAM_VGA_RESET_N, GPIOF_OUT_INIT_LOW, 5000},
};
+static struct msm_gpio_set_tbl ov7692_cam_gpio_set_tbl_sku7[] = {
+ {GPIO_SKU7_CAM_VGA_SHDN, GPIOF_OUT_INIT_HIGH, 5000},
+ {GPIO_SKU7_CAM_VGA_SHDN, GPIOF_OUT_INIT_LOW, 5000},
+ {GPIO_SKU1_CAM_VGA_RESET_N, GPIOF_OUT_INIT_HIGH, 5000},
+ {GPIO_SKU1_CAM_VGA_RESET_N, GPIOF_OUT_INIT_LOW, 5000},
+};
+
static struct msm_camera_gpio_conf gpio_conf_ov7692 = {
.cam_gpio_req_tbl = ov7692_cam_req_gpio,
.cam_gpio_req_tbl_size = ARRAY_SIZE(ov7692_cam_req_gpio),
@@ -105,6 +212,14 @@ static struct msm_camera_gpio_conf gpio_conf_ov7692 = {
.cam_gpio_set_tbl_size = ARRAY_SIZE(ov7692_cam_gpio_set_tbl),
.gpio_no_mux = 1,
};
+
+static struct msm_camera_gpio_conf sku7_gpio_conf_ov7692 = {
+ .cam_gpio_req_tbl = ov7692_cam_req_gpio_sku7,
+ .cam_gpio_req_tbl_size = ARRAY_SIZE(ov7692_cam_req_gpio_sku7),
+ .cam_gpio_set_tbl = ov7692_cam_gpio_set_tbl_sku7,
+ .cam_gpio_set_tbl_size = ARRAY_SIZE(ov7692_cam_gpio_set_tbl_sku7),
+ .gpio_no_mux = 1,
+};
#endif
#ifdef CONFIG_OV5647
@@ -114,23 +229,91 @@ static struct msm_camera_gpio_conf gpio_conf_ov5647 = {
.gpio_no_mux = 1,
};
#endif
+#ifdef CONFIG_OV5647_DALING_OVBD631AC
+static struct msm_camera_gpio_conf gpio_conf_ov5647_dl_bd631ac = {
+ .camera_off_table = camera_off_gpio_table,
+ .camera_on_table = camera_on_gpio_table,
+ .gpio_no_mux = 1,
+};
+#endif
+#ifdef CONFIG_OV5647_PARTRON_CM500
+static struct msm_camera_gpio_conf gpio_conf_ov5647_partron_cm500 = {
+ .camera_off_table = camera_off_gpio_table,
+ .camera_on_table = camera_on_gpio_table,
+ .gpio_no_mux = 1,
+};
+#endif
+#ifdef CONFIG_OV5647_HQ_O9B5_DG806T
+static struct msm_camera_gpio_conf gpio_conf_ov5647_hq_dg806t = {
+ .camera_off_table = camera_off_gpio_table,
+ .camera_on_table = camera_on_gpio_table,
+ .gpio_no_mux = 1,
+};
+#endif
+#ifdef CONFIG_OV5647_TRULY_CM6868
+static struct msm_camera_gpio_conf gpio_conf_ov5647_truly_cm6868 = {
+ .camera_off_table = camera_off_gpio_table,
+ .camera_on_table = camera_on_gpio_table,
+ .gpio_no_mux = 1,
+};
+#endif
-#ifdef CONFIG_OV5648
-static struct msm_camera_gpio_conf gpio_conf_ov5648 = {
+//lwl modify
+#ifdef CONFIG_S5K5CA
+static struct msm_camera_gpio_conf gpio_conf_s5k5ca = {
.camera_off_table = camera_off_gpio_table,
.camera_on_table = camera_on_gpio_table,
.gpio_no_mux = 1,
};
#endif
-#ifdef CONFIG_OV8825
-static struct msm_camera_gpio_conf gpio_conf_ov8825 = {
+#ifdef CONFIG_HI351_SUNNY_Q3H01B
+static struct msm_camera_gpio_conf gpio_conf_hi351_sunny_q3h01b = {
+ .camera_off_table = camera_off_gpio_table,
+ .camera_on_table = camera_on_gpio_table,
+ .gpio_no_mux = 1,
+};
+#endif
+
+
+#ifdef CONFIG_AR0543
+static struct msm_camera_gpio_conf gpio_conf_ar0543 = {
+ .camera_off_table = camera_off_gpio_table,
+ .camera_on_table = camera_on_gpio_table,
+ .gpio_no_mux = 1,
+};
+#endif
+#ifdef CONFIG_S5K3H2_SUNNY_Q8S02E
+static struct msm_camera_gpio_conf gpio_conf_s5k3h2_sunny_q8s02e = {
.camera_off_table = camera_off_gpio_table,
.camera_on_table = camera_on_gpio_table,
.gpio_no_mux = 1,
};
#endif
+#ifdef CONFIG_AR0542
+static struct msm_camera_gpio_conf gpio_conf_ar0542 = {
+ .camera_off_table = camera_off_gpio_table,
+ .camera_on_table = camera_on_gpio_table,
+ .gpio_no_mux = 1,
+};
+#endif
+
+#ifdef CONFIG_OV5648_TRULY_CM8352
+static struct msm_camera_gpio_conf gpio_conf_ov5648_truly_cm8352 = {
+ .camera_off_table = camera_off_gpio_table,
+ .camera_on_table = camera_on_gpio_table,
+ .gpio_no_mux = 1,
+};
+#endif
+#ifdef CONFIG_A8140
+static struct msm_camera_gpio_conf gpio_conf_a8140 = {
+ .camera_off_table = camera_off_gpio_table,
+ .camera_on_table = camera_on_gpio_table,
+ .gpio_no_mux = 1,
+};
+#endif
+#if 0 // #suwg
#ifdef CONFIG_MSM_CAMERA_FLASH
static struct msm_camera_sensor_flash_src msm_flash_src = {
.flash_sr_type = MSM_CAMERA_FLASH_SRC_EXT,
@@ -138,20 +321,39 @@ static struct msm_camera_sensor_flash_src msm_flash_src = {
._fsrc.ext_driver_src.led_flash_en = GPIO_CAM_GP_LED_EN2,
};
#endif
+#endif
static struct camera_vreg_t msm_cam_vreg[] = {
+#ifdef ODMM_PROJECT_STAGE_EVB2
+#ifdef CONFIG_S5K5CA
+ {"wlan3", REG_LDO, 1500000, 1500000, 0},// lwl modify lco6
+ {"wlan2", REG_LDO, 1800000, 1800000, 0},//lwl modify lco19
+#endif
+#ifdef CONFIG_HI351_SUNNY_Q3H01B
+ {"wlan3", REG_LDO, 1200000, 1200000, 0},// lwl modify lco6
+ {"wlan2", REG_LDO, 1800000, 1800000, 0},//lwl modify lco19
+#endif
+#else
{"msme1", REG_LDO, 1800000, 1800000, 0},
{"gp2", REG_LDO, 2850000, 2850000, 0},
- {"usb2", REG_LDO, 1800000, 1800000, 0},
+ {"usb", REG_LDO, 1200000, 1200000, 0},// lwl modify lco6
+ {"wlan2", REG_LDO, 1800000, 1800000, 0},//lwl modify lco19
+#endif
};
-
+#ifdef CONFIG_OV5647
static struct camera_vreg_t ov5647_gpio_vreg[] = {
{"cam_ov5647_avdd", REG_GPIO, 0, 0, 0},
{"cam_ov5647_vdd", REG_GPIO, 0, 0, 0},
};
-
-#ifdef CONFIG_OV5648
-static struct camera_vreg_t ov5648_gpio_vreg[] = {
+#endif
+#ifdef CONFIG_OV5647_TRULY_CM6868
+static struct camera_vreg_t ov5647_truly_cm6868_gpio_vreg[] = {
+ {"cam_ov5647_truly_cm6868_avdd", REG_GPIO, 0, 0, 0},
+ {"cam_ov5647_truly_cm6868_vdd", REG_GPIO, 0, 0, 0},
+};
+#endif
+#ifdef CONFIG_OV5648_TRULY_CM8352
+static struct camera_vreg_t ov5648_truly_cm8352_gpio_vreg[] = {
{"ldo12", REG_LDO, 2700000, 3300000, 0},
{"smps3", REG_LDO, 1800000, 1800000, 0},
};
@@ -169,7 +371,6 @@ static struct camera_vreg_t ov8825_gpio_vreg[] = {
{"cam_ov8825_avdd", REG_GPIO, 0, 0, 0},
{"cam_ov8825_vdd", REG_GPIO, 0, 0, 0},
};
-
static struct camera_vreg_t ov8825_gpio_vreg_evbd[] = {
{"ldo12", REG_LDO, 2700000, 3300000, 0},
{"smps3", REG_LDO, 1800000, 1800000, 0},
@@ -177,13 +378,39 @@ static struct camera_vreg_t ov8825_gpio_vreg_evbd[] = {
{"cam_ov8825_vdd", REG_GPIO, 0, 0, 0},
};
#endif
-
+#ifdef CONFIG_OV7692
static struct camera_vreg_t ov7692_gpio_vreg[] = {
{"cam_ov7692_avdd", REG_GPIO, 0, 0, 0},
{"cam_ov7692_vdd", REG_GPIO, 0, 0, 0},
};
+#endif
-static struct msm_camera_sensor_info msm_camera_sensor_s5k4e1_data;
+#ifdef CONFIG_AR0543
+static struct camera_vreg_t ar0543_gpio_vreg[] = {
+ {"cam_ar0543_avdd", REG_GPIO, 0, 0, 0},
+ {"cam_ar0543_vdd", REG_GPIO, 0, 0, 0},
+};
+#endif
+#ifdef CONFIG_A8140
+static struct camera_vreg_t a8140_gpio_vreg[] = {
+ {"cam_a8140_avdd", REG_GPIO, 0, 0, 0},
+ {"cam_a8140_vdd", REG_GPIO, 0, 0, 0},
+};
+#endif
+#ifdef CONFIG_S5K3H2_SUNNY_Q8S02E
+static struct camera_vreg_t s5k3h2_sunny_q8s02e_gpio_vreg[] = {
+ {"cam_s5k3h2_sunny_q8s02e_avdd", REG_GPIO, 0, 0, 0},
+ {"cam_s5k3h2_sunny_q8s02e_vdd", REG_GPIO, 0, 0, 0},
+};
+#endif
+#ifdef CONFIG_AR0542
+static struct camera_vreg_t ar0542_gpio_vreg[] = {
+// {"cam_ar0542_avdd", REG_GPIO, 0, 0, 0},
+// {"cam_ar0542_vdd", REG_GPIO, 0, 0, 0},
+};
+#endif
+
+// #suwg:static struct msm_camera_sensor_info msm_camera_sensor_s5k4e1_data;
struct msm_camera_device_platform_data msm_camera_device_data_csi1[] = {
{
@@ -219,6 +446,7 @@ static struct i2c_board_info msm_act_main_cam_i2c_info = {
I2C_BOARD_INFO("msm_actuator", 0x11),
};
+#if 0 // #suwg
static struct msm_actuator_info msm_act_main_cam_4_info = {
.board_info = &msm_act_main_cam_i2c_info,
.cam_name = MSM_ACTUATOR_MAIN_CAM_4,
@@ -226,7 +454,7 @@ static struct msm_actuator_info msm_act_main_cam_4_info = {
.vcm_pwd = GPIO_CAM_GP_CAM_PWDN,
.vcm_enable = 1,
};
-
+#endif
#ifdef CONFIG_S5K4E1
static struct msm_camera_sensor_flash_data flash_s5k4e1 = {
.flash_type = MSM_CAMERA_FLASH_LED,
@@ -253,6 +481,8 @@ static struct msm_camera_sensor_info msm_camera_sensor_s5k4e1_data = {
};
#endif
+
+
#ifdef CONFIG_OV7692
static struct msm_camera_sensor_platform_info sensor_board_info_ov7692 = {
.mount_angle = 270,
@@ -268,6 +498,53 @@ static struct msm_camera_sensor_flash_data flash_ov7692 = {
static struct msm_camera_sensor_info msm_camera_sensor_ov7692_data = {
.sensor_name = "ov7692",
.sensor_reset_enable = 0,
+ .sensor_reset = GPIO_NOT_CONFIGURED,
+ .sensor_pwd = GPIO_NOT_CONFIGURED,
+ .pdata = &msm_camera_device_data_csi0[0],
+ .flash_data = &flash_ov7692,
+ .sensor_platform_info = &sensor_board_info_ov7692,
+ .csi_if = 1,
+ .camera_type = FRONT_CAMERA_2D,
+ .sensor_type = YUV_SENSOR,
+};
+#endif
+
+#ifdef CONFIG_WEBCAM_OV7692_QRD
+
+//[ start ] lixujie 20120601 modify it for eg808t front camera orientation
+#ifdef CONFIG_ODMM
+static struct msm_camera_sensor_platform_info sensor_board_info_ov7692 = {
+ /* li.xujie@byd.com 20120813 modify it for EG808T front Camera ov7692
+ preview/snap Orientation (EG808T_P004990) */
+
+ .mount_angle = 90,
+ .cam_vreg = msm_cam_vreg,
+ .num_vreg = 0,
+ .gpio_conf = &gpio_conf_ov7692,
+};
+#else
+static struct msm_camera_sensor_platform_info sensor_board_info_ov7692 = {
+ .mount_angle = 90,
+ .cam_vreg = msm_cam_vreg,
+ .num_vreg = ARRAY_SIZE(msm_cam_vreg),
+ .gpio_conf = &gpio_conf_ov7692,
+};
+#endif
+//[ end ]
+
+static struct msm_camera_sensor_flash_data flash_ov7692 = {
+ .flash_type = MSM_CAMERA_FLASH_NONE,
+};
+
+static struct msm_camera_sensor_info msm_camera_sensor_ov7692_data = {
+ .sensor_name = "ov7692",
+ .sensor_reset_enable = 0,
+
+ #ifdef CONFIG_ODMM // [ start ] lixujie 20120511 modify it for EG808T front Camera
+ .pmic_gpio_enable = 0,
+ #else
+ .pmic_gpio_enable = 1,
+ #endif // [ end ]
.sensor_reset = GPIO_SKU1_CAM_VGA_RESET_N,
.sensor_pwd = GPIO_SKU1_CAM_VGA_SHDN,
.pdata = &msm_camera_device_data_csi0[0],
@@ -277,22 +554,76 @@ static struct msm_camera_sensor_info msm_camera_sensor_ov7692_data = {
.camera_type = FRONT_CAMERA_2D,
.sensor_type = YUV_SENSOR,
};
+
+// [ start ] lixujie 20120511 add it for EG808T front Camera
+
+static void ov7692_camera_gpio_cfg(void)
+{
+ int32_t rc = 0;
+ int32_t ov7692_pwrdwn_rst_pin ;
+
+ printk(" %s: L(%d) start \n",__func__,__LINE__);
+
+ if(msm_camera_sensor_ov7692_data.sensor_reset_enable){
+
+ ov7692_pwrdwn_rst_pin = msm_camera_sensor_ov7692_data.sensor_reset;
+
+ rc = gpio_request(ov7692_pwrdwn_rst_pin, "ov7692");
+ if (rc < 0){
+ pr_err("%s: gpio_request---ov7692_rst_pin failed!", __func__);
+ }
+
+ rc = gpio_tlmm_config(GPIO_CFG(ov7692_pwrdwn_rst_pin, 0,
+ GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP,GPIO_CFG_2MA), GPIO_CFG_ENABLE);
+
+ if (rc < 0) {
+ pr_err("%s:unable to enable ov7692_rst_pin gpio for frnt camera!\n", __func__);
+ gpio_free(ov7692_pwrdwn_rst_pin);
+ }
+ gpio_direction_output(ov7692_pwrdwn_rst_pin, 1);
+
+ }
+
+ ov7692_pwrdwn_rst_pin = msm_camera_sensor_ov7692_data.sensor_pwd;
+ rc = gpio_request(ov7692_pwrdwn_rst_pin, "ov7692");
+
+ if (rc < 0){
+
+ pr_err("%s: gpio_request---ov7692_pwdn_gpio failed!", __func__);
+
+ }
+
+ rc = gpio_tlmm_config(GPIO_CFG(ov7692_pwrdwn_rst_pin, 0,
+ GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP,GPIO_CFG_2MA), GPIO_CFG_ENABLE);
+
+ if (rc < 0) {
+
+ pr_err("%s:unable to enable Powr Dwn gpio for frnt camera!\n",__func__);
+ gpio_free(ov7692_pwrdwn_rst_pin);
+
+ }
+
+ gpio_direction_output(ov7692_pwrdwn_rst_pin, 1);
+
+}
+
+// [ end ]
+
#endif
+
#ifdef CONFIG_OV7695
-/*
static struct gpio ov7695_cam_req_gpio_skud[] = {
{GPIO_SKUD_CAM_1MP_PWDN, GPIOF_DIR_OUT, "CAM_VGA_SHDN"},
};
-*/
static struct msm_gpio_set_tbl ov7695_cam_gpio_set_tbl_skud[] = {
{GPIO_SKUD_CAM_1MP_PWDN, GPIOF_OUT_INIT_LOW, 5000},
{GPIO_SKUD_CAM_1MP_PWDN, GPIOF_OUT_INIT_HIGH, 5000},
};
static struct msm_camera_gpio_conf skud_gpio_conf_ov7695 = {
-// .cam_gpio_req_tbl = ov7695_cam_req_gpio_skud,
-// .cam_gpio_req_tbl_size = ARRAY_SIZE(ov7695_cam_req_gpio_skud),
+ .cam_gpio_req_tbl = ov7695_cam_req_gpio_skud,
+ .cam_gpio_req_tbl_size = ARRAY_SIZE(ov7695_cam_req_gpio_skud),
.cam_gpio_set_tbl = ov7695_cam_gpio_set_tbl_skud,
.cam_gpio_set_tbl_size = ARRAY_SIZE(ov7695_cam_gpio_set_tbl_skud),
.camera_off_table = camera_off_gpio_table,
@@ -372,18 +703,66 @@ static struct msm_camera_sensor_info msm_camera_sensor_ov7695_raw_data = {
};
#endif
+#ifdef CONFIG_MT9V115
+static struct gpio mt9v115_cam_req_gpio[] = {
+ {GPIO_SKUE_CAM_VGA_SHDN, GPIOF_DIR_OUT, "CAM_VGA_SHDN"},
+};
+
+static struct msm_gpio_set_tbl mt9v115_cam_gpio_set_tbl[] = {
+ {GPIO_SKUE_CAM_VGA_SHDN, GPIOF_OUT_INIT_HIGH, 5000},
+ {GPIO_SKUE_CAM_VGA_SHDN, GPIOF_OUT_INIT_LOW, 10000},
+};
+static struct msm_camera_gpio_conf gpio_conf_mt9v115 = {
+ .cam_gpio_req_tbl = mt9v115_cam_req_gpio,
+ .cam_gpio_req_tbl_size = ARRAY_SIZE(mt9v115_cam_req_gpio),
+ .cam_gpio_set_tbl = mt9v115_cam_gpio_set_tbl,
+ .cam_gpio_set_tbl_size = ARRAY_SIZE(mt9v115_cam_gpio_set_tbl),
+ .camera_off_table = camera_off_gpio_table,
+ .camera_on_table = camera_on_gpio_table,
+ .gpio_no_mux = 1,
+};
+
+static struct camera_vreg_t mt9v115_gpio_vreg[] = {
+ {"ldo12", REG_LDO, 2700000, 3300000, 0},
+ {"smps3", REG_LDO, 1800000, 1800000, 0},
+};
+static struct msm_camera_sensor_platform_info sensor_board_info_mt9v115 = {
+ .mount_angle = 90,
+ .cam_vreg = msm_cam_vreg,
+ .num_vreg = ARRAY_SIZE(msm_cam_vreg),
+ .gpio_conf = &gpio_conf_mt9v115,
+};
+
+static struct msm_camera_sensor_flash_data flash_mt9v115 = {
+ .flash_type = MSM_CAMERA_FLASH_NONE,
+};
+
+static struct msm_camera_sensor_info msm_camera_sensor_mt9v115_data = {
+ .sensor_name = "mt9v115",
+ .sensor_reset_enable = 0,
+ .sensor_reset = GPIO_NOT_CONFIGURED,
+ .sensor_pwd = GPIO_NOT_CONFIGURED,
+ .pdata = &msm_camera_device_data_csi0[0],
+ .flash_data = &flash_mt9v115,
+ .sensor_platform_info = &sensor_board_info_mt9v115,
+ .csi_if = 1,
+ .camera_type = FRONT_CAMERA_2D,
+ .sensor_type = YUV_SENSOR,
+};
+#endif
+
#ifdef CONFIG_OV5647
static struct msm_actuator_info msm_act_main_cam_5_info = {
.board_info = &msm_act_main_cam_i2c_info,
.cam_name = MSM_ACTUATOR_MAIN_CAM_5,
.bus_id = MSM_GSBI0_QUP_I2C_BUS_ID,
- .vcm_pwd = GPIO_SKU3_CAM_5MP_CAM_DRIVER_PWDN,
- .vcm_enable = 1,
+ .vcm_pwd = GPIO_NOT_CONFIGURED,
+ .vcm_enable = 0,
};
static struct msm_camera_sensor_platform_info sensor_board_info_ov5647 = {
- .mount_angle = 90,
+ .mount_angle = MOUNT_ANGLE_NOT_CONFIGURED,
.cam_vreg = msm_cam_vreg,
.num_vreg = ARRAY_SIZE(msm_cam_vreg),
.gpio_conf = &gpio_conf_ov5647,
@@ -403,9 +782,10 @@ static struct msm_camera_sensor_flash_data flash_ov5647 = {
static struct msm_camera_sensor_info msm_camera_sensor_ov5647_data = {
.sensor_name = "ov5647",
.sensor_reset_enable = 1,
- .sensor_reset = GPIO_SKU3_CAM_5MP_CAMIF_RESET,
- .sensor_pwd = GPIO_SKU3_CAM_5MP_SHDN_N,
- .pdata = &msm_camera_device_data_csi1[0],
+ .pmic_gpio_enable = 1,
+ .sensor_reset = GPIO_NOT_CONFIGURED,
+ .sensor_pwd = GPIO_NOT_CONFIGURED,
+ .pdata = &msm_camera_device_data_csi1[0],
.flash_data = &flash_ov5647,
.sensor_platform_info = &sensor_board_info_ov5647,
.csi_if = 1,
@@ -413,10 +793,132 @@ static struct msm_camera_sensor_info msm_camera_sensor_ov5647_data = {
.sensor_type = BAYER_SENSOR,
.actuator_info = &msm_act_main_cam_5_info,
};
+#endif
+//lwl modify
+#ifdef CONFIG_S5K5CA
+static struct msm_camera_sensor_platform_info sensor_board_info_s5k5ca = {
+ .mount_angle = 90,//270,//90,
+ .cam_vreg = msm_cam_vreg,
+ .num_vreg = ARRAY_SIZE(msm_cam_vreg),
+ .gpio_conf = &gpio_conf_s5k5ca,
+};
+
+#if 0
+static struct msm_camera_sensor_flash_src msm_flash_src_s5k5ca = {
+ #if 0
+ .flash_sr_type = MSM_CAMERA_FLASH_SRC_LED,
+ ._fsrc.led_src.led_name = "flashlight",
+ ._fsrc.led_src.led_name_len = 10,
+ #endif
+ //.flash_sr_type = ODMM_CAMERA_FLASH_SRC_LED,
+ ._fsrc.led_src.led_name = "ktd265",
+ ._fsrc.ext_driver_src = {
+ //.odmm_led_name = "ktd265",
+ .led_en = 98,
+ .led_flash_en = 98,
+ }
+};
+#endif
+
+static struct msm_camera_sensor_flash_data flash_s5k5ca = {
+ .flash_type =MSM_CAMERA_FLASH_NONE,// MSM_CAMERA_FLASH_LED,
+ //.flash_src = &msm_flash_src_s5k5ca,
+};
+
+
+static struct msm_camera_sensor_info msm_camera_sensor_s5k5ca_data = {
+ .sensor_name = "s5k5ca",
+ .sensor_reset_enable = 1,
+ .pmic_gpio_enable = 1,
+ .sensor_reset = 5,//GPIO_NOT_CONFIGURED,
+ .sensor_pwd = 6,//GPIO_NOT_CONFIGURED,
+ .pdata = &msm_camera_device_data_csi1[0],
+ .flash_data = &flash_s5k5ca,
+ .sensor_platform_info = &sensor_board_info_s5k5ca,
+ .csi_if = 1,
+ .camera_type = BACK_CAMERA_2D,
+ .sensor_type = YUV_SENSOR,
+};
+ #endif
+
+ #ifdef CONFIG_HI351_SUNNY_Q3H01B
+static struct msm_camera_sensor_platform_info sensor_board_info_hi351_sunny_q3h01b = {
+ .mount_angle = 90,
+ .cam_vreg = msm_cam_vreg,
+ .num_vreg = ARRAY_SIZE(msm_cam_vreg),
+ .gpio_conf = &gpio_conf_hi351_sunny_q3h01b,
+};
+#if 0
+static struct msm_camera_sensor_flash_src msm_flash_src_hi351_sunny_q3h01b = {
+ .flash_sr_type = MSM_CAMERA_FLASH_SRC_LED,
+ ._fsrc.led_src.led_name = "flashlight",
+ ._fsrc.led_src.led_name_len = 10,
+};
+#endif
+static struct msm_camera_sensor_flash_data flash_hi351_sunny_q3h01b = {
+ .flash_type = MSM_CAMERA_FLASH_NONE,//MSM_CAMERA_FLASH_LED,
+ //.flash_src = &msm_flash_src_hi351_sunny_q3h01b,
+};
+
+static struct msm_camera_sensor_info msm_camera_sensor_hi351_sunny_q3h01b_data = {
+ .sensor_name = "hi351",
+ .sensor_reset_enable = 1,
+ .pmic_gpio_enable = 1,
+ .sensor_reset = 5,//GPIO_NOT_CONFIGURED,
+ .sensor_pwd = 6,//GPIO_NOT_CONFIGURED,
+ .pdata = &msm_camera_device_data_csi1[0],
+ .flash_data = &flash_hi351_sunny_q3h01b,
+ .sensor_platform_info = &sensor_board_info_hi351_sunny_q3h01b,
+ .csi_if = 1,
+ .camera_type = BACK_CAMERA_2D,
+ .sensor_type = YUV_SENSOR,
+};
+#endif
+
+#ifdef CONFIG_OV5647_TRULY_CM6868
+static struct msm_actuator_info msm_act_main_cam_6_info = {
+ .board_info = &msm_act_main_cam_i2c_info,
+ .cam_name = MSM_ACTUATOR_MAIN_CAM_6,
+ .bus_id = MSM_GSBI0_QUP_I2C_BUS_ID,
+ .vcm_pwd = GPIO_NOT_CONFIGURED,
+ .vcm_enable = 0,
+};
+
+static struct msm_camera_sensor_platform_info sensor_board_info_ov5647_truly_cm6868 = {
+ .mount_angle = MOUNT_ANGLE_NOT_CONFIGURED,
+ .cam_vreg = msm_cam_vreg,
+ .num_vreg = ARRAY_SIZE(msm_cam_vreg),
+ .gpio_conf = &gpio_conf_ov5647_truly_cm6868,
+};
+static struct msm_camera_sensor_flash_src msm_flash_src_ov5647_truly_cm6868 = {
+ .flash_sr_type = MSM_CAMERA_FLASH_SRC_LED1,
+ ._fsrc.ext_driver_src.led_en = 13,
+ ._fsrc.ext_driver_src.led_flash_en = 32,
+};
+
+static struct msm_camera_sensor_flash_data flash_ov5647_truly_cm6868 = {
+ .flash_type = MSM_CAMERA_FLASH_LED,
+ .flash_src = &msm_flash_src_ov5647_truly_cm6868,
+};
+
+static struct msm_camera_sensor_info msm_camera_sensor_ov5647_truly_cm6868_data = {
+ .sensor_name = "ov5647_truly_cm6868",
+ .sensor_reset_enable = 1,
+ .pmic_gpio_enable = 1,
+ .sensor_reset = GPIO_NOT_CONFIGURED,
+ .sensor_pwd = GPIO_NOT_CONFIGURED,
+ .pdata = &msm_camera_device_data_csi1[0],
+ .flash_data = &flash_ov5647_truly_cm6868,
+ .sensor_platform_info = &sensor_board_info_ov5647_truly_cm6868,
+ .csi_if = 1,
+ .camera_type = BACK_CAMERA_2D,
+ .sensor_type = BAYER_SENSOR,
+ .actuator_info = &msm_act_main_cam_6_info,
+};
#endif
-#ifdef CONFIG_OV5648
+#ifdef CONFIG_OV5648_TRULY_CM8352
static struct msm_actuator_info msm_act_main_cam_7_info = {
.board_info = &msm_act_main_cam_i2c_info,
.cam_name = MSM_ACTUATOR_MAIN_CAM_7,
@@ -425,33 +927,33 @@ static struct msm_actuator_info msm_act_main_cam_7_info = {
.vcm_enable = 0,
};
-static struct msm_camera_sensor_platform_info sensor_board_info_ov5648 = {
+static struct msm_camera_sensor_platform_info sensor_board_info_ov5648_truly_cm8352 = {
.mount_angle = MOUNT_ANGLE_NOT_CONFIGURED,
.cam_vreg = msm_cam_vreg,
.num_vreg = ARRAY_SIZE(msm_cam_vreg),
- .gpio_conf = &gpio_conf_ov5648,
+ .gpio_conf = &gpio_conf_ov5648_truly_cm8352,
};
-static struct msm_camera_sensor_flash_src msm_flash_src_ov5648 = {
+static struct msm_camera_sensor_flash_src msm_flash_src_ov5648_truly_cm8352 = {
.flash_sr_type = MSM_CAMERA_FLASH_SRC_LED1,
._fsrc.ext_driver_src.led_en = GPIO_SKUD_CAM_LED_EN,
._fsrc.ext_driver_src.led_flash_en = GPIO_SKUD_CAM_LED_FLASH_EN,
};
-static struct msm_camera_sensor_flash_data flash_ov5648 = {
+static struct msm_camera_sensor_flash_data flash_ov5648_truly_cm8352 = {
.flash_type = MSM_CAMERA_FLASH_LED,
- .flash_src = &msm_flash_src_ov5648,
+ .flash_src = &msm_flash_src_ov5648_truly_cm8352,
};
-static struct msm_camera_sensor_info msm_camera_sensor_ov5648_data = {
- .sensor_name = "ov5648",
+static struct msm_camera_sensor_info msm_camera_sensor_ov5648_truly_cm8352_data = {
+ .sensor_name = "ov5648_truly_cm8352",
.sensor_reset_enable = 1,
.pmic_gpio_enable = 1,
.sensor_reset = GPIO_NOT_CONFIGURED,
.sensor_pwd = GPIO_NOT_CONFIGURED,
.pdata = &msm_camera_device_data_csi1[0],
- .flash_data = &flash_ov5648,
- .sensor_platform_info = &sensor_board_info_ov5648,
+ .flash_data = &flash_ov5648_truly_cm8352,
+ .sensor_platform_info = &sensor_board_info_ov5648_truly_cm8352,
.csi_if = 1,
.camera_type = BACK_CAMERA_2D,
.sensor_type = BAYER_SENSOR,
@@ -459,7 +961,14 @@ static struct msm_camera_sensor_info msm_camera_sensor_ov5648_data = {
};
#endif
+
#ifdef CONFIG_OV8825
+static struct msm_camera_gpio_conf gpio_conf_ov8825 = {
+ .camera_off_table = camera_off_gpio_table,
+ .camera_on_table = camera_on_gpio_table,
+ .gpio_no_mux = 1,
+};
+
static struct msm_camera_sensor_flash_src msm_flash_src_ov8825 = {
.flash_sr_type = MSM_CAMERA_FLASH_SRC_LED1,
._fsrc.ext_driver_src.led_en = 13,
@@ -472,7 +981,7 @@ static struct msm_camera_sensor_flash_data flash_ov8825 = {
};
static struct msm_camera_sensor_platform_info sensor_board_info_ov8825 = {
- .mount_angle = 90,
+ .mount_angle = MOUNT_ANGLE_NOT_CONFIGURED,
.cam_vreg = msm_cam_vreg,
.num_vreg = ARRAY_SIZE(msm_cam_vreg),
.gpio_conf = &gpio_conf_ov8825,
@@ -480,9 +989,9 @@ static struct msm_camera_sensor_platform_info sensor_board_info_ov8825 = {
static struct msm_actuator_info msm_act_main_cam_3_info = {
.board_info = &msm_act_main_cam_i2c_info,
- .cam_name = MSM_ACTUATOR_MAIN_CAM_3,
+ .cam_name = MSM_ACTUATOR_MAIN_CAM_3,
.bus_id = MSM_GSBI0_QUP_I2C_BUS_ID,
- .vcm_pwd = GPIO_SKU3_CAM_5MP_CAM_DRIVER_PWDN,
+ .vcm_pwd = GPIO_NOT_CONFIGURED,
.vcm_enable = 0,
};
@@ -490,8 +999,8 @@ static struct msm_camera_sensor_info msm_camera_sensor_ov8825_data = {
.sensor_name = "ov8825",
.sensor_reset_enable = 1,
.pmic_gpio_enable = 1,
- .sensor_reset = GPIO_SKU3_CAM_5MP_CAMIF_RESET,
- .sensor_pwd = GPIO_SKU3_CAM_5MP_SHDN_N,
+ .sensor_reset = GPIO_NOT_CONFIGURED,
+ .sensor_pwd = GPIO_NOT_CONFIGURED,
.pdata = &msm_camera_device_data_csi1[1],
.flash_data = &flash_ov8825,
.sensor_platform_info = &sensor_board_info_ov8825,
@@ -501,6 +1010,272 @@ static struct msm_camera_sensor_info msm_camera_sensor_ov8825_data = {
.actuator_info = &msm_act_main_cam_3_info,
};
#endif
+
+
+#ifdef CONFIG_OV5647_DALING_OVBD631AC//#ifndef CONFIG_ODMM comment by zy 20120712
+
+static struct msm_actuator_info odmm_msm_act_main_cam_dl_bd631ac_5_info = {
+ .board_info = &msm_act_main_cam_i2c_info,
+ .cam_name = ODMM_MSM_ACTUATOR_MAIN_CAM_DALING_OVBD631AC_5,
+ .bus_id = MSM_GSBI0_QUP_I2C_BUS_ID,
+ .vcm_pwd = GPIO_NOT_CONFIGURED,
+ .vcm_enable = 0,
+};
+
+static struct msm_camera_sensor_platform_info sensor_board_info_ov5647_dl_bd631ac = {
+ .mount_angle = 270, /*mod by zy 20120712 adjust angle*/
+ .cam_vreg = msm_cam_vreg,
+ .num_vreg = ARRAY_SIZE(msm_cam_vreg),
+ .gpio_conf = &gpio_conf_ov5647_dl_bd631ac,
+};
+
+static struct msm_camera_sensor_flash_src msm_flash_src_ov5647_dl_bd631ac = {
+ //.flash_sr_type = ODMM_CAMERA_FLASH_SRC_LED,
+ ._fsrc.led_src.led_name = "ktd265",
+ ._fsrc.ext_driver_src = {
+ //.odmm_led_name = "ktd265",
+ .led_en = 98,
+ .led_flash_en = 98,
+ }
+};
+
+static struct msm_camera_sensor_flash_data flash_ov5647_dl_bd631ac = {
+ .flash_type = MSM_CAMERA_FLASH_LED,
+ .flash_src = &msm_flash_src_ov5647_dl_bd631ac,
+};
+
+static struct msm_camera_sensor_info msm_camera_sensor_ov5647_dl_bd631ac_data = {
+ .sensor_name = "ov5647_dl_bd631ac",
+ .sensor_reset_enable = 1,
+ .pmic_gpio_enable = 1,
+ .sensor_reset = GPIO_NOT_CONFIGURED,
+ .sensor_pwd = GPIO_NOT_CONFIGURED,
+ .pdata = &msm_camera_device_data_csi1[0],
+ .flash_data = &flash_ov5647_dl_bd631ac,
+ .sensor_platform_info = &sensor_board_info_ov5647_dl_bd631ac,
+ .csi_if = 1,
+ .camera_type = BACK_CAMERA_2D,
+ .sensor_type = BAYER_SENSOR,
+ .actuator_info = &odmm_msm_act_main_cam_dl_bd631ac_5_info,
+};
+
+#endif
+#ifdef CONFIG_OV5647_PARTRON_CM500
+
+static struct msm_actuator_info odmm_msm_act_main_cam_partron_cm500_5_info = {
+ .board_info = &msm_act_main_cam_i2c_info,
+ .cam_name = ODMM_MSM_ACTUATOR_MAIN_CAM_PARTRON_CM500_5,
+ .bus_id = MSM_GSBI0_QUP_I2C_BUS_ID,
+ .vcm_pwd = GPIO_NOT_CONFIGURED,
+ .vcm_enable = 0,
+};
+
+static struct msm_camera_sensor_platform_info sensor_board_info_ov5647_partron_cm500 = {
+ .mount_angle = 270, /*mod by zy 20120712 adjust angle*/
+ .cam_vreg = msm_cam_vreg,
+ .num_vreg = ARRAY_SIZE(msm_cam_vreg),
+ .gpio_conf = &gpio_conf_ov5647_partron_cm500,
+};
+
+static struct msm_camera_sensor_flash_src msm_flash_src_ov5647_partron_cm500 = {
+ //.flash_sr_type = ODMM_CAMERA_FLASH_SRC_LED,
+ ._fsrc.led_src.led_name = "ktd265",
+ ._fsrc.ext_driver_src = {
+ //.odmm_led_name = "ktd265",
+ .led_en = 98,
+ .led_flash_en = 98,
+ }
+};
+
+static struct msm_camera_sensor_flash_data flash_ov5647_partron_cm500 = {
+ .flash_type = MSM_CAMERA_FLASH_LED,
+ .flash_src = &msm_flash_src_ov5647_partron_cm500,
+};
+
+static struct msm_camera_sensor_info msm_camera_sensor_ov5647_partron_cm500_data = {
+ .sensor_name = "ov5647_partr_cm500",
+ .sensor_reset_enable = 1,
+ .pmic_gpio_enable = 1,
+ .sensor_reset = GPIO_NOT_CONFIGURED,
+ .sensor_pwd = GPIO_NOT_CONFIGURED,
+ .pdata = &msm_camera_device_data_csi1[0],
+ .flash_data = &flash_ov5647_partron_cm500,
+ .sensor_platform_info = &sensor_board_info_ov5647_partron_cm500,
+ .csi_if = 1,
+ .camera_type = BACK_CAMERA_2D,
+ .sensor_type = BAYER_SENSOR,
+ .actuator_info = &odmm_msm_act_main_cam_partron_cm500_5_info,
+};
+
+#endif
+
+#ifdef CONFIG_OV5647_HQ_O9B5_DG806T
+
+static struct msm_actuator_info odmm_msm_act_main_cam_hq_dg806t_5_info = {
+ .board_info = &msm_act_main_cam_i2c_info,
+ .cam_name = ODMM_MSM_ACTUATOR_MAIN_CAM_HQ_DG806T_5,
+ .bus_id = MSM_GSBI0_QUP_I2C_BUS_ID,
+ .vcm_pwd = GPIO_NOT_CONFIGURED,
+ .vcm_enable = 0,
+};
+
+static struct msm_camera_sensor_platform_info sensor_board_info_ov5647_hq_dg806t = {
+ .mount_angle = 270, /*mod by zy 20120712 adjust angle*/
+ .cam_vreg = msm_cam_vreg,
+ .num_vreg = ARRAY_SIZE(msm_cam_vreg),
+ .gpio_conf = &gpio_conf_ov5647_hq_dg806t,
+};
+
+static struct msm_camera_sensor_flash_src msm_flash_src_ov5647_hq_dg806t = {
+ //.flash_sr_type = ODMM_CAMERA_FLASH_SRC_LED,
+ ._fsrc.led_src.led_name = "ktd265",
+ ._fsrc.ext_driver_src = {
+ //.odmm_led_name = "ktd265",
+ .led_en = 98,
+ .led_flash_en = 98,
+ }
+};
+
+static struct msm_camera_sensor_flash_data flash_ov5647_hq_dg806t = {
+ .flash_type = MSM_CAMERA_FLASH_LED,
+ .flash_src = &msm_flash_src_ov5647_hq_dg806t,
+};
+
+static struct msm_camera_sensor_info msm_camera_sensor_ov5647_hq_dg806t_data = {
+ .sensor_name = "ov5647_hq_dg806t",
+ .sensor_reset_enable = 1,
+ .pmic_gpio_enable = 1,
+ .sensor_reset = GPIO_NOT_CONFIGURED,
+ .sensor_pwd = GPIO_NOT_CONFIGURED,
+ .pdata = &msm_camera_device_data_csi1[0],
+ .flash_data = &flash_ov5647_hq_dg806t,
+ .sensor_platform_info = &sensor_board_info_ov5647_hq_dg806t,
+ .csi_if = 1,
+ .camera_type = BACK_CAMERA_2D,
+ .sensor_type = BAYER_SENSOR,
+ .actuator_info = &odmm_msm_act_main_cam_hq_dg806t_5_info,
+};
+
+#endif
+#ifdef CONFIG_AR0543
+static struct msm_camera_sensor_platform_info sensor_board_info_ar0543 = {
+ .mount_angle = MOUNT_ANGLE_NOT_CONFIGURED,
+ .cam_vreg = msm_cam_vreg,
+ .num_vreg = ARRAY_SIZE(msm_cam_vreg),
+ .gpio_conf = &gpio_conf_ar0543,
+};
+
+static struct msm_camera_sensor_flash_src msm_flash_src_ar0543 = {
+ .flash_sr_type = MSM_CAMERA_FLASH_SRC_LED1,
+ ._fsrc.ext_driver_src.led_en = 13,
+ ._fsrc.ext_driver_src.led_flash_en = 32,
+};
+
+static struct msm_camera_sensor_flash_data flash_ar0543 = {
+ .flash_type = MSM_CAMERA_FLASH_LED,
+ .flash_src = &msm_flash_src_ar0543,
+};
+
+static struct msm_camera_sensor_info msm_camera_sensor_ar0543_data = {
+ .sensor_name = "ar0543",
+ .sensor_reset_enable = 1,
+ .pmic_gpio_enable = 1,
+ .sensor_reset = GPIO_NOT_CONFIGURED,
+ .sensor_pwd = GPIO_NOT_CONFIGURED,
+ .pdata = &msm_camera_device_data_csi1[0],
+ .flash_data = &flash_ar0543,
+ .sensor_platform_info = &sensor_board_info_ar0543,
+ .csi_if = 1,
+ .camera_type = BACK_CAMERA_2D,
+ .sensor_type = BAYER_SENSOR,
+};
+#endif
+
+#ifdef CONFIG_S5K3H2_SUNNY_Q8S02E
+static struct msm_actuator_info msm_act_main_cam_9_info = {
+ .board_info = &msm_act_main_cam_i2c_info,
+ .cam_name = MSM_ACTUATOR_MAIN_CAM_9,
+ .bus_id = MSM_GSBI0_QUP_I2C_BUS_ID,
+ .vcm_pwd = GPIO_NOT_CONFIGURED,
+ .vcm_enable = 0,
+};
+
+static struct msm_camera_sensor_platform_info sensor_board_info_s5k3h2_sunny_q8s02e = {
+ .mount_angle = MOUNT_ANGLE_NOT_CONFIGURED,
+ .cam_vreg = msm_cam_vreg,
+ .num_vreg = ARRAY_SIZE(msm_cam_vreg),
+ .gpio_conf = &gpio_conf_s5k3h2_sunny_q8s02e,
+};
+
+static struct msm_camera_sensor_flash_src msm_flash_src_s5k3h2_sunny_q8s02e = {
+ .flash_sr_type = MSM_CAMERA_FLASH_SRC_LED1,
+ ._fsrc.ext_driver_src.led_en = 13,
+ ._fsrc.ext_driver_src.led_flash_en = 32,
+};
+
+static struct msm_camera_sensor_flash_data flash_s5k3h2_sunny_q8s02e = {
+ .flash_type = MSM_CAMERA_FLASH_LED,
+ .flash_src = &msm_flash_src_s5k3h2_sunny_q8s02e,
+};
+
+static struct msm_camera_sensor_info msm_camera_sensor_s5k3h2_sunny_q8s02e_data = {
+ .sensor_name = "s5k3h2_sunny_q8s02e",
+ .sensor_reset_enable = 1,
+ .pmic_gpio_enable = 1,
+ .sensor_reset = GPIO_NOT_CONFIGURED,
+ .sensor_pwd = GPIO_NOT_CONFIGURED,
+ .pdata = &msm_camera_device_data_csi1[0],
+ .flash_data = &flash_s5k3h2_sunny_q8s02e,
+ .sensor_platform_info = &sensor_board_info_s5k3h2_sunny_q8s02e,
+ .csi_if = 1,
+ .camera_type = BACK_CAMERA_2D,
+ .sensor_type = BAYER_SENSOR,
+ .actuator_info = &msm_act_main_cam_9_info,
+};
+#endif
+#ifdef CONFIG_AR0542
+static struct msm_camera_sensor_platform_info sensor_board_info_ar0542 = {
+ .mount_angle = MOUNT_ANGLE_NOT_CONFIGURED,
+ .cam_vreg = msm_cam_vreg,
+ .num_vreg = ARRAY_SIZE(msm_cam_vreg),
+ .gpio_conf = &gpio_conf_ar0542,
+};
+
+static struct msm_camera_sensor_flash_src msm_flash_src_ar0542 = {
+ .flash_sr_type = MSM_CAMERA_FLASH_SRC_LED1,
+ ._fsrc.ext_driver_src.led_en = 13,
+ ._fsrc.ext_driver_src.led_flash_en = 32,
+};
+
+static struct msm_camera_sensor_flash_data flash_ar0542 = {
+ .flash_type = MSM_CAMERA_FLASH_LED,
+ .flash_src = &msm_flash_src_ar0542,
+};
+
+static struct msm_actuator_info msm_act_main_cam_10_info = {
+ .board_info = &msm_act_main_cam_i2c_info,
+ .cam_name = MSM_ACTUATOR_MAIN_CAM_10,
+ .bus_id = MSM_GSBI0_QUP_I2C_BUS_ID,
+ .vcm_pwd = GPIO_NOT_CONFIGURED,
+ .vcm_enable = 0,
+};
+
+static struct msm_camera_sensor_info msm_camera_sensor_ar0542_data = {
+ .sensor_name = "ar0542",
+ .sensor_reset_enable = 1,
+ .pmic_gpio_enable = 1,
+ .sensor_reset = GPIO_NOT_CONFIGURED,
+ .sensor_pwd = GPIO_NOT_CONFIGURED,
+ .pdata = &msm_camera_device_data_csi1[0],
+ .flash_data = &flash_ar0542,
+ .sensor_platform_info = &sensor_board_info_ar0542,
+ .csi_if = 1,
+ .camera_type = BACK_CAMERA_2D,
+ .sensor_type = BAYER_SENSOR,
+ .actuator_info = &msm_act_main_cam_10_info,
+};
+#endif
+
#ifdef CONFIG_MT9E013
static struct msm_camera_sensor_flash_data flash_mt9e013 = {
.flash_type = MSM_CAMERA_FLASH_LED,
@@ -525,7 +1300,48 @@ static struct msm_camera_sensor_info msm_camera_sensor_mt9e013_data = {
.sensor_type = BAYER_SENSOR,
};
#endif
-
+#ifdef CONFIG_A8140
+static struct msm_actuator_info msm_act_main_cam_8_info = {
+ .board_info = &msm_act_main_cam_i2c_info,
+ .cam_name = MSM_ACTUATOR_MAIN_CAM_8,
+ .bus_id = MSM_GSBI0_QUP_I2C_BUS_ID,
+ .vcm_pwd = GPIO_NOT_CONFIGURED,
+ .vcm_enable = 0,
+};
+
+static struct msm_camera_sensor_platform_info sensor_board_info_a8140 = {
+ .mount_angle = MOUNT_ANGLE_NOT_CONFIGURED,
+ .cam_vreg = msm_cam_vreg,
+ .num_vreg = ARRAY_SIZE(msm_cam_vreg),
+ .gpio_conf = &gpio_conf_a8140,
+};
+
+static struct msm_camera_sensor_flash_src msm_flash_src_a8140 = {
+ .flash_sr_type = MSM_CAMERA_FLASH_SRC_LED1,
+ ._fsrc.ext_driver_src.led_en = 13,
+ ._fsrc.ext_driver_src.led_flash_en = 32,
+};
+
+static struct msm_camera_sensor_flash_data flash_a8140 = {
+ .flash_type = MSM_CAMERA_FLASH_LED,
+ .flash_src = &msm_flash_src_a8140,
+};
+
+static struct msm_camera_sensor_info msm_camera_sensor_a8140_data = {
+ .sensor_name = "a8140",
+ .sensor_reset_enable = 1,
+ .pmic_gpio_enable = 1,
+ .sensor_reset = GPIO_NOT_CONFIGURED,
+ .sensor_pwd = GPIO_NOT_CONFIGURED,
+ .pdata = &msm_camera_device_data_csi1[0],
+ .flash_data = &flash_a8140,
+ .sensor_platform_info = &sensor_board_info_a8140,
+ .csi_if = 1,
+ .camera_type = BACK_CAMERA_2D,
+ .sensor_type = BAYER_SENSOR,
+ .actuator_info = &msm_act_main_cam_8_info,
+};
+#endif
#ifdef CONFIG_WEBCAM_OV9726
static struct msm_camera_sensor_flash_data flash_ov9726 = {
.flash_type = MSM_CAMERA_FLASH_LED,
@@ -558,63 +1374,219 @@ static struct platform_device msm_camera_server = {
static void __init msm7x27a_init_cam(void)
{
- if (!(machine_is_msm7x27a_ffa() || machine_is_msm7625a_ffa()
- || machine_is_msm7627a_qrd1()
- || machine_is_msm8625q_evbd()
- || machine_is_msm8625q_skud()
- || machine_is_qrd_skud_prime()
- || machine_is_msm8625_ffa())) {
+
+ if (!(machine_is_msm7x27a_ffa() ||
+ machine_is_msm7625a_ffa() ||
+ machine_is_msm7627a_qrd1() ||
+ machine_is_msm8625_qrd7() ||
+ machine_is_msm7627a_qrd3() ||
+ machine_is_msm8625_evb() ||
+ machine_is_msm8625_qrd5() ||
+ machine_is_msm7x27a_qrd5a() ||
+ machine_is_msm8625q_evbd() ||
+ machine_is_msm8625q_skud() ||
+ machine_is_msm8625q_skue() ||
+ machine_is_msm8625_ffa())){
+#ifdef CONFIG_S5K4E1
sensor_board_info_s5k4e1.cam_vreg = NULL;
sensor_board_info_s5k4e1.num_vreg = 0;
+#endif
+#ifdef CONFIG_MT9E013
sensor_board_info_mt9e013.cam_vreg = NULL;
sensor_board_info_mt9e013.num_vreg = 0;
+#endif
+#ifdef CONFIG_WEBCAM_OV9726
sensor_board_info_ov9726.cam_vreg = NULL;
sensor_board_info_ov9726.num_vreg = 0;
+#endif
+//#ifdef CONFIG_OV7692
+#ifdef CONFIG_WEBCAM_OV7692_QRD
sensor_board_info_ov7692.cam_vreg = NULL;
sensor_board_info_ov7692.num_vreg = 0;
+#endif
+#ifdef CONFIG_OV7695
+ sensor_board_info_ov7695.cam_vreg = NULL;
+ sensor_board_info_ov7695.num_vreg = 0;
+#endif
+#ifdef CONFIG_MT9V115
+ sensor_board_info_mt9v115.cam_vreg = NULL;
+ sensor_board_info_mt9v115.num_vreg = 0;
+#endif
+#ifdef CONFIG_OV7695_RAW
+ sensor_board_info_ov7695_raw.cam_vreg = NULL;
+ sensor_board_info_ov7695_raw.num_vreg = 0;
+#endif
+#ifdef CONFIG_OV5647
sensor_board_info_ov5647.cam_vreg = NULL;
sensor_board_info_ov5647.num_vreg = 0;
+#endif
+// lwl modify
+#ifdef CONFIG_S5K5CA
+ sensor_board_info_s5k5ca.cam_vreg = NULL;
+ sensor_board_info_s5k5ca.num_vreg = 0;
+#endif
+#ifdef CONFIG_HI351_SUNNY_Q3H01B
+ sensor_board_info_hi351_sunny_q3h01b.cam_vreg = NULL;
+ sensor_board_info_hi351_sunny_q3h01b.num_vreg = 0;
+#endif
+#ifdef CONFIG_OV8825
sensor_board_info_ov8825.cam_vreg = NULL;
sensor_board_info_ov8825.num_vreg = 0;
+#endif
+#ifdef CONFIG_OV5647_DALING_OVBD631AC
+ sensor_board_info_ov5647_dl_bd631ac.cam_vreg = NULL;
+ sensor_board_info_ov5647_dl_bd631ac.num_vreg = 0;
+#endif
+#ifdef CONFIG_OV5647_PARTRON_CM500
+ sensor_board_info_ov5647_partron_cm500.cam_vreg = NULL;
+ sensor_board_info_ov5647_partron_cm500.num_vreg = 0;
+#endif
+#ifdef CONFIG_OV5647_HQ_O9B5_DG806T
+ sensor_board_info_ov5647_hq_dg806t.cam_vreg = NULL;
+ sensor_board_info_ov5647_hq_dg806t.num_vreg = 0;
+#endif
+ }else if (machine_is_msm8625_qrd7() || machine_is_msm7627a_qrd3())
+ {
+ //Add SKU7 specific settings
+#ifdef CONFIG_OV5647
+ msm_camera_sensor_ov5647_data.sensor_reset = camera_gpio_rear_qrd7[1];
+ msm_camera_sensor_ov5647_data.sensor_pwd = camera_gpio_rear_qrd7[0];
+ msm_camera_sensor_ov5647_data.vcm_pwd = 0;
+ msm_camera_sensor_ov5647_data.vcm_enable = 0;
+ msm_flash_src_ov5647.flash_sr_type = MSM_CAMERA_FLASH_LED;
+ msm_flash_src_ov5647._fsrc.ext_driver_src.led_en = 96;
+ msm_camera_sensor_ov5647_data.sensor_platform_info->ext_power_ctrl = sku3_lcdc_lcd_camera_power_onoff;
+ sensor_board_info_ov5647.mount_angle = 90;
+#endif
+#ifdef CONFIG_OV7692
+ msm_camera_sensor_ov7692_data.sensor_platform_info->ext_power_ctrl = sku3_lcdc_lcd_camera_power_onoff;
+ msm_camera_sensor_ov7692_data.vcm_pwd = 0;
+ msm_camera_sensor_ov7692_data.vcm_enable = 0;
+ sensor_board_info_ov7692.gpio_conf = &sku7_gpio_conf_ov7692;
+ sensor_board_info_ov7692.mount_angle = 90;
+#endif
+#ifdef CONFIG_WEBCAM_OV7692_QRD
+
+ // [ start ] lixujie 20120511 modify it for EG808T front Camera
+ #ifndef CONFIG_ODMM
+ msm_camera_sensor_ov7692_data.sensor_reset = camera_gpio_front_qrd7[1];
+ msm_camera_sensor_ov7692_data.sensor_pwd = camera_gpio_front_qrd7[0];
+ #endif
+#endif
+
+ }else if (machine_is_msm8625_evb())
+ {
+#ifdef CONFIG_OV7692
+ sensor_board_info_ov7692.cam_vreg = ov7692_gpio_vreg;
+ sensor_board_info_ov7692.num_vreg = ARRAY_SIZE(ov7692_gpio_vreg);
+#endif
+#ifdef CONFIG_WEBCAM_OV7692_QRD
+ // [ start ] lixujie 20120511 modify it for EG808T front Camera
+ #ifndef CONFIG_ODMM
+ sensor_board_info_ov7692.mount_angle = 270;
+ msm_camera_sensor_ov7692_data.sensor_reset = GPIO_SKU1_CAM_VGA_RESET_N;
+ msm_camera_sensor_ov7692_data.sensor_pwd = GPIO_SKU1_CAM_VGA_SHDN;
+ #endif
+#endif
+
+#ifdef CONFIG_OV5647
+ sensor_board_info_ov5647.cam_vreg = ov5647_gpio_vreg;
+ sensor_board_info_ov5647.num_vreg = ARRAY_SIZE(ov5647_gpio_vreg);
+ msm_act_main_cam_5_info.vcm_pwd = GPIO_SKU3_CAM_5MP_CAM_DRIVER_PWDN;
+ msm_act_main_cam_5_info.vcm_enable = 1;
+ msm_camera_sensor_ov5647_data.sensor_reset=GPIO_SKU3_CAM_5MP_CAMIF_RESET;
+ msm_camera_sensor_ov5647_data.sensor_pwd = GPIO_SKU3_CAM_5MP_SHDN_N;
+ sensor_board_info_ov5647.mount_angle = 90;
+#endif
+#ifdef CONFIG_OV8825
+ sensor_board_info_ov8825.cam_vreg = ov8825_gpio_vreg;
+ sensor_board_info_ov8825.num_vreg = ARRAY_SIZE(ov8825_gpio_vreg);
+ msm_act_main_cam_3_info.vcm_pwd = GPIO_SKU3_CAM_5MP_CAM_DRIVER_PWDN;
+ msm_act_main_cam_3_info.vcm_enable = 0;
+ msm_camera_sensor_ov8825_data.sensor_reset = GPIO_SKU3_CAM_5MP_CAMIF_RESET;
+ msm_camera_sensor_ov8825_data.sensor_pwd = GPIO_SKU3_CAM_5MP_SHDN_N;
+ sensor_board_info_ov8825.mount_angle = 90;
+#endif
}
- if (machine_is_msm8625_evb() || machine_is_msm7627a_evb()
- || machine_is_msm8625_evt()
- || machine_is_msm7627a_qrd3()
- || machine_is_msm8625_qrd7()) {
- sensor_board_info_ov7692.cam_vreg =
- ov7692_gpio_vreg;
- sensor_board_info_ov7692.num_vreg =
- ARRAY_SIZE(ov7692_gpio_vreg);
- sensor_board_info_ov5647.cam_vreg =
- ov5647_gpio_vreg;
- sensor_board_info_ov5647.num_vreg =
- ARRAY_SIZE(ov5647_gpio_vreg);
- sensor_board_info_ov8825.cam_vreg =
- ov8825_gpio_vreg;
- sensor_board_info_ov8825.num_vreg =
- ARRAY_SIZE(ov8825_gpio_vreg);
+ else if(machine_is_msm8625_qrd5() || machine_is_msm7x27a_qrd5a())
+ {
+#ifdef CONFIG_OV5647_TRULY_CM6868
+ sensor_board_info_ov5647_truly_cm6868.cam_vreg = ov5647_truly_cm6868_gpio_vreg;
+ sensor_board_info_ov5647_truly_cm6868.num_vreg = ARRAY_SIZE(ov5647_truly_cm6868_gpio_vreg);
+ msm_act_main_cam_6_info.vcm_pwd = GPIO_SKU3_CAM_5MP_CAM_DRIVER_PWDN;
+ msm_act_main_cam_6_info.vcm_enable = 1;
+ msm_camera_sensor_ov5647_truly_cm6868_data.sensor_reset=GPIO_SKU3_CAM_5MP_CAMIF_RESET;
+ msm_camera_sensor_ov5647_truly_cm6868_data.sensor_pwd = GPIO_SKU3_CAM_5MP_SHDN_N;
+ sensor_board_info_ov5647_truly_cm6868.mount_angle = 90;
+#endif
+#ifdef CONFIG_OV7692
+ sensor_board_info_ov7692.cam_vreg = ov7692_gpio_vreg;
+ sensor_board_info_ov7692.num_vreg = ARRAY_SIZE(ov7692_gpio_vreg);
+#endif
+#ifdef CONFIG_WEBCAM_OV7692_QRD
+
+ // [ start ] lixujie 20120511 modify it for EG808T front Camera
+ #ifndef CONFIG_ODMM
+ sensor_board_info_ov7692.mount_angle = 90;
+ msm_camera_sensor_ov7692_data.sensor_reset = GPIO_SKU1_CAM_VGA_RESET_N;
+ msm_camera_sensor_ov7692_data.sensor_pwd = GPIO_SKU1_CAM_VGA_SHDN;
+ #endif
+#endif
+#ifdef CONFIG_OV8825
+ sensor_board_info_ov8825.cam_vreg = ov8825_gpio_vreg;
+ sensor_board_info_ov8825.num_vreg = ARRAY_SIZE(ov8825_gpio_vreg);
+ msm_act_main_cam_3_info.vcm_pwd = GPIO_SKU3_CAM_5MP_CAM_DRIVER_PWDN;
+ msm_act_main_cam_3_info.vcm_enable = 0;
+ msm_camera_sensor_ov8825_data.sensor_reset = GPIO_SKU3_CAM_5MP_CAMIF_RESET;
+ msm_camera_sensor_ov8825_data.sensor_pwd = GPIO_SKU3_CAM_5MP_SHDN_N;
+ sensor_board_info_ov8825.mount_angle = 90;
+#endif
+#ifdef CONFIG_AR0543
+ sensor_board_info_ar0543.cam_vreg = ar0543_gpio_vreg;
+ sensor_board_info_ar0543.num_vreg = ARRAY_SIZE(ar0543_gpio_vreg);
+ msm_camera_sensor_ar0543_data.sensor_reset=GPIO_SKU3_CAM_5MP_CAMIF_RESET;
+ msm_camera_sensor_ar0543_data.sensor_pwd = GPIO_SKU3_CAM_5MP_SHDN_N;
+ sensor_board_info_ar0543.mount_angle = 90;
+#endif
+#ifdef CONFIG_A8140
+ sensor_board_info_a8140.cam_vreg = a8140_gpio_vreg;
+ sensor_board_info_a8140.num_vreg = ARRAY_SIZE(a8140_gpio_vreg);
+ msm_act_main_cam_8_info.vcm_pwd = GPIO_SKU3_CAM_5MP_CAM_DRIVER_PWDN;
+ msm_act_main_cam_8_info.vcm_enable = 1;
+ msm_camera_sensor_a8140_data.sensor_reset=GPIO_SKU3_CAM_5MP_CAMIF_RESET;
+ msm_camera_sensor_a8140_data.sensor_pwd = GPIO_SKU3_CAM_5MP_SHDN_N;
+ sensor_board_info_a8140.mount_angle = 90;
+#endif
+#ifdef CONFIG_S5K3H2_SUNNY_Q8S02E
+ sensor_board_info_s5k3h2_sunny_q8s02e.cam_vreg = s5k3h2_sunny_q8s02e_gpio_vreg;
+ sensor_board_info_s5k3h2_sunny_q8s02e.num_vreg = ARRAY_SIZE(s5k3h2_sunny_q8s02e_gpio_vreg);
+ msm_act_main_cam_9_info.vcm_pwd = GPIO_SKU3_CAM_5MP_CAM_DRIVER_PWDN;
+ msm_act_main_cam_9_info.vcm_enable = 1;
+ msm_camera_sensor_s5k3h2_sunny_q8s02e_data.sensor_reset=GPIO_SKU3_CAM_5MP_CAMIF_RESET;
+ msm_camera_sensor_s5k3h2_sunny_q8s02e_data.sensor_pwd = GPIO_SKU3_CAM_5MP_SHDN_N;
+ sensor_board_info_s5k3h2_sunny_q8s02e.mount_angle = 90;
+#endif
}
else if(machine_is_msm8625q_evbd()||
- machine_is_msm8625q_skud()||
- machine_is_qrd_skud_prime())
+ machine_is_msm8625q_skud())
{ //for SKUD
-#ifdef CONFIG_OV5648
+#ifdef CONFIG_OV5648_TRULY_CM8352
if(machine_is_msm8625q_evbd()) {
- sensor_board_info_ov5648.cam_vreg = ov5648_gpio_vreg_evbd;
- sensor_board_info_ov5648.num_vreg = ARRAY_SIZE(ov5648_gpio_vreg_evbd);
- sensor_board_info_ov5648.mount_angle = 270;
+ sensor_board_info_ov5648_truly_cm8352.cam_vreg = ov5648_gpio_vreg_evbd;
+ sensor_board_info_ov5648_truly_cm8352.num_vreg = ARRAY_SIZE(ov5648_gpio_vreg_evbd);
+ sensor_board_info_ov5648_truly_cm8352.mount_angle = 270;
} else {
- sensor_board_info_ov5648.cam_vreg = ov5648_gpio_vreg;
- sensor_board_info_ov5648.num_vreg = ARRAY_SIZE(ov5648_gpio_vreg);
- sensor_board_info_ov5648.mount_angle = 90;
+ sensor_board_info_ov5648_truly_cm8352.cam_vreg = ov5648_truly_cm8352_gpio_vreg;
+ sensor_board_info_ov5648_truly_cm8352.num_vreg = ARRAY_SIZE(ov5648_truly_cm8352_gpio_vreg);
+ sensor_board_info_ov5648_truly_cm8352.mount_angle = 90;
}
msm_act_main_cam_7_info.vcm_pwd = GPIO_SKUD_CAM_5MP_CAM_VCM_PWDN;
msm_act_main_cam_7_info.vcm_enable = 1;
- msm_camera_sensor_ov5648_data.sensor_reset=GPIO_SKUD_CAM_5MP_CAMIF_RESET;
- msm_camera_sensor_ov5648_data.sensor_pwd = GPIO_SKUD_CAM_5MP_SHDN_N;
- msm_flash_src_ov5648._fsrc.ext_driver_src.led_en = GPIO_SKUD_CAM_LED_EN;
- msm_flash_src_ov5648._fsrc.ext_driver_src.led_flash_en = GPIO_SKUD_CAM_LED_FLASH_EN;
+ msm_camera_sensor_ov5648_truly_cm8352_data.sensor_reset=GPIO_SKUD_CAM_5MP_CAMIF_RESET;
+ msm_camera_sensor_ov5648_truly_cm8352_data.sensor_pwd = GPIO_SKUD_CAM_5MP_SHDN_N;
+ msm_flash_src_ov5648_truly_cm8352._fsrc.ext_driver_src.led_en = GPIO_SKUD_CAM_LED_EN;
+ msm_flash_src_ov5648_truly_cm8352._fsrc.ext_driver_src.led_flash_en = GPIO_SKUD_CAM_LED_FLASH_EN;
#endif
#ifdef CONFIG_OV8825
@@ -642,7 +1614,7 @@ static void __init msm7x27a_init_cam(void)
msm_camera_sensor_ov7695_data.vcm_pwd = 0;
msm_camera_sensor_ov7695_data.vcm_enable = 0;
sensor_board_info_ov7695.gpio_conf = &skud_gpio_conf_ov7695;
- sensor_board_info_ov7695.mount_angle = 270;
+ sensor_board_info_ov7695.mount_angle = 90;
#endif
#ifdef CONFIG_OV7695_RAW
sensor_board_info_ov7695_raw.cam_vreg = ov7695_raw_gpio_vreg;
@@ -653,14 +1625,34 @@ static void __init msm7x27a_init_cam(void)
sensor_board_info_ov7695_raw.gpio_conf = &skud_gpio_conf_ov7695_raw;
sensor_board_info_ov7695_raw.mount_angle = 270;
#endif
+ }else if(machine_is_msm8625q_skue()) {
+#ifdef CONFIG_MT9V115
+ sensor_board_info_mt9v115.cam_vreg = mt9v115_gpio_vreg;
+ sensor_board_info_mt9v115.num_vreg = ARRAY_SIZE(mt9v115_gpio_vreg);
+ msm_camera_sensor_mt9v115_data.vcm_pwd = 0;
+ msm_camera_sensor_mt9v115_data.vcm_enable = 0;
+ msm_camera_sensor_mt9v115_data.sensor_pwd = GPIO_SKUE_CAM_VGA_SHDN;
+ sensor_board_info_mt9v115.gpio_conf = &gpio_conf_mt9v115;
+ sensor_board_info_mt9v115.mount_angle = 270;
+#endif
+#ifdef CONFIG_AR0542
+ sensor_board_info_ar0542.cam_vreg = ar0542_gpio_vreg;
+ sensor_board_info_ar0542.num_vreg = ARRAY_SIZE(ar0542_gpio_vreg);
+ msm_camera_sensor_ar0542_data.sensor_reset=GPIO_SKUE_CAM_5MP_CAMIF_RESET;
+ msm_camera_sensor_ar0542_data.sensor_pwd = GPIO_SKUE_CAM_5MP_SHDN_N;
+ sensor_board_info_ar0542.mount_angle = 90;
+ msm_flash_src_ar0542._fsrc.ext_driver_src.led_en = GPIO_SKUE_CAM_LED_EN;
+ msm_flash_src_ar0542._fsrc.ext_driver_src.led_flash_en = GPIO_SKUE_CAM_LED_FLASH_EN;
+#endif
}
+
platform_device_register(&msm_camera_server);
if (machine_is_msm8625_surf() || machine_is_msm8625_evb()
- || machine_is_msm8625_evt()
+ || machine_is_msm8625_qrd5() || machine_is_msm7x27a_qrd5a()
|| machine_is_msm8625_qrd7()
|| machine_is_msm8625q_evbd()
|| machine_is_msm8625q_skud()
- || machine_is_qrd_skud_prime()) {
+ || machine_is_msm8625q_skue()) {
platform_device_register(&msm8625_device_csic0);
platform_device_register(&msm8625_device_csic1);
} else {
@@ -668,77 +1660,155 @@ static void __init msm7x27a_init_cam(void)
platform_device_register(&msm7x27a_device_csic1);
}
if (machine_is_msm8625_evb()
- || machine_is_msm8625_evt()
+ || machine_is_msm8625_qrd5()
+ || machine_is_msm7627a_qrd3()
|| machine_is_msm8625_qrd7()
+ || machine_is_msm7x27a_qrd5a()
|| machine_is_msm8625q_evbd()
|| machine_is_msm8625q_skud()
- || machine_is_qrd_skud_prime())
+ || machine_is_msm8625q_skue())
*(int *) msm7x27a_device_clkctl.dev.platform_data = 1;
platform_device_register(&msm7x27a_device_clkctl);
platform_device_register(&msm7x27a_device_vfe);
}
static struct i2c_board_info i2c_camera_devices[] = {
+#ifdef CONFIG_S5K4E1
{
I2C_BOARD_INFO("s5k4e1", 0x36),
.platform_data = &msm_camera_sensor_s5k4e1_data,
},
+#endif
+#ifdef CONFIG_WEBCAM_OV9726
{
I2C_BOARD_INFO("ov9726", 0x10),
.platform_data = &msm_camera_sensor_ov9726_data,
},
+#endif
+#ifdef CONFIG_MT9E013
{
I2C_BOARD_INFO("mt9e013", 0x6C >> 2),
.platform_data = &msm_camera_sensor_mt9e013_data,
},
+#endif
+//#ifdef CONFIG_OV7692
+#ifdef CONFIG_WEBCAM_OV7692_QRD
+ {
+ I2C_BOARD_INFO("ov7692", 0x78),
+ .platform_data = &msm_camera_sensor_ov7692_data,
+ },
+#endif
+#ifdef CONFIG_OV5647
+ {
+ I2C_BOARD_INFO("ov5647", 0x36 << 1),
+ .platform_data = &msm_camera_sensor_ov5647_data,
+ },
+#endif
+#ifdef CONFIG_OV8825
+ {
+ I2C_BOARD_INFO("ov8825", 0x6C >> 3),
+ .platform_data = &msm_camera_sensor_ov8825_data,
+ },
+#endif
+ {
+ I2C_BOARD_INFO("sc628a", 0x6E),
+ },
+};
+
+static struct i2c_board_info i2c_camera_devices_sku5[] = {
+#ifdef CONFIG_OV5647_TRULY_CM6868
+ {
+ I2C_BOARD_INFO("ov5647_truly_cm6868", 0x36 << 1),//original
+ .platform_data = &msm_camera_sensor_ov5647_truly_cm6868_data,
+ },
+#endif
+#ifdef CONFIG_OV8825
+ {
+ I2C_BOARD_INFO("ov8825", 0x6C >> 3),
+ .platform_data = &msm_camera_sensor_ov8825_data,
+ },
+#endif
+//#ifdef CONFIG_OV7692
+#ifdef CONFIG_WEBCAM_OV7692_QRD
{
I2C_BOARD_INFO("ov7692", 0x78),
.platform_data = &msm_camera_sensor_ov7692_data,
},
+#endif
+#ifdef CONFIG_AR0543
+ {
+ I2C_BOARD_INFO("ar0543", 0x64),
+ .platform_data = &msm_camera_sensor_ar0543_data,
+ },
+#endif
+#ifdef CONFIG_A8140
+ {
+ I2C_BOARD_INFO("a8140", 0x62),
+ .platform_data = &msm_camera_sensor_a8140_data,
+ },
+#endif
+#ifdef CONFIG_S5K3H2_SUNNY_Q8S02E
{
- I2C_BOARD_INFO("ov5647", 0x36 << 1),
- .platform_data = &msm_camera_sensor_ov5647_data,
+ I2C_BOARD_INFO("s5k3h2_sunny_q8s02e", 0x32),
+ .platform_data = &msm_camera_sensor_s5k3h2_sunny_q8s02e_data,
},
+#endif
+};
+
+static struct i2c_board_info i2c_camera_devices_skud[] = {
+#ifdef CONFIG_OV8825
{
- I2C_BOARD_INFO("ov8825", 0x6C >> 3),
+ I2C_BOARD_INFO("ov8825", 0x6C >> 3), // 8MP sensor
.platform_data = &msm_camera_sensor_ov8825_data,
},
+#endif
+#ifdef CONFIG_OV7695
{
- I2C_BOARD_INFO("sc628a", 0x6E),
+ I2C_BOARD_INFO("ov7695", 0x21 << 1),
+ .platform_data = &msm_camera_sensor_ov7695_data,
},
-
-};
-static struct i2c_board_info i2c_camera_devices_qpr_skud[] = {
-#ifdef CONFIG_OV5648
- {
- I2C_BOARD_INFO("ov5648", 0x36 << 1),//original
- .platform_data = &msm_camera_sensor_ov5648_data,
- },
#endif
#ifdef CONFIG_OV7695_RAW
- {
- I2C_BOARD_INFO("ov7695_raw", 0x21 << 1),
- .platform_data = &msm_camera_sensor_ov7695_raw_data,
- },
+ {
+ I2C_BOARD_INFO("ov7695_raw", 0x21 << 1),
+ .platform_data = &msm_camera_sensor_ov7695_raw_data,
+ },
+#endif
+#ifdef CONFIG_OV5648_TRULY_CM8352
+ {
+ I2C_BOARD_INFO("ov5648_truly_cm8352", 0x36 << 1),//original
+ .platform_data = &msm_camera_sensor_ov5648_truly_cm8352_data,
+ },
#endif
};
-static struct i2c_board_info i2c_camera_devices_qpr[] = {
-#ifdef CONFIG_OV5648
+
+static struct i2c_board_info i2c_camera_devices_skue[] = {
+#ifdef CONFIG_AR0542
{
- I2C_BOARD_INFO("ov5648", 0x36 << 1),//original
- .platform_data = &msm_camera_sensor_ov5648_data,
+ I2C_BOARD_INFO("ar0542", 0x64),
+ .platform_data = &msm_camera_sensor_ar0542_data,
},
#endif
-#ifdef CONFIG_OV8825
+#ifdef CONFIG_MT9V115
{
- I2C_BOARD_INFO("ov8825", 0x6C >> 3), // 8MP sensor
- .platform_data = &msm_camera_sensor_ov8825_data,
+ I2C_BOARD_INFO("mt9v115", 0x7a),
+ .platform_data = &msm_camera_sensor_mt9v115_data,
},
#endif
-#ifdef CONFIG_OV7695
+};
+
+static struct i2c_board_info i2c_camera_devices_sku7[] = {
+#ifdef CONFIG_OV5647
{
- I2C_BOARD_INFO("ov7695", 0x21 << 1),
- .platform_data = &msm_camera_sensor_ov7695_data,
+ I2C_BOARD_INFO("ov5647", 0x36 << 1),
+ .platform_data = &msm_camera_sensor_ov5647_data,
+ },
+#endif
+//#ifdef CONFIG_OV7692
+#ifdef CONFIG_WEBCAM_OV7692_QRD
+ {
+ I2C_BOARD_INFO("ov7692", 0x78),
+ .platform_data = &msm_camera_sensor_ov7692_data,
},
#endif
};
@@ -828,47 +1898,48 @@ static void evb_camera_gpio_cfg(void)
{
int rc = 0;
- rc = gpio_request(msm_camera_sensor_ov5647_data.sensor_pwd, "ov5647");
+ rc = gpio_request(GPIO_SKU3_CAM_5MP_SHDN_N, "ov5647");
if (rc < 0)
pr_err("%s: gpio_request OV5647 sensor_pwd: %d failed!",
- __func__, msm_camera_sensor_ov5647_data.sensor_pwd);
+ __func__, GPIO_SKU3_CAM_5MP_SHDN_N);
- rc = gpio_tlmm_config(GPIO_CFG(msm_camera_sensor_ov5647_data.sensor_pwd,
+ rc = gpio_tlmm_config(GPIO_CFG(GPIO_SKU3_CAM_5MP_SHDN_N,
0, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_DOWN,
GPIO_CFG_2MA), GPIO_CFG_ENABLE);
if (rc < 0) {
pr_err("%s:unable to enable Powr Dwn gpio for main camera!\n",
__func__);
- gpio_free(msm_camera_sensor_ov5647_data.sensor_pwd);
+ gpio_free(GPIO_SKU3_CAM_5MP_SHDN_N);
}
- rc = gpio_direction_output(msm_camera_sensor_ov5647_data.sensor_pwd, 1);
+ rc = gpio_direction_output(GPIO_SKU3_CAM_5MP_SHDN_N, 1);
if (rc < 0)
pr_err("%s: unable to set gpio: %d direction for ov5647 camera\n",
- __func__, msm_camera_sensor_ov5647_data.sensor_pwd);
+ __func__, GPIO_SKU3_CAM_5MP_SHDN_N);
- rc = gpio_request(msm_camera_sensor_ov5647_data.sensor_reset, "ov5647");
+ rc = gpio_request(GPIO_SKU3_CAM_5MP_CAMIF_RESET, "ov5647");
if (rc < 0)
pr_err("%s: gpio_request OV5647 sensor_reset: %d failed!",
- __func__, msm_camera_sensor_ov5647_data.sensor_reset);
+ __func__, GPIO_SKU3_CAM_5MP_CAMIF_RESET);
rc = gpio_tlmm_config(GPIO_CFG(
- msm_camera_sensor_ov5647_data.sensor_reset,
+ GPIO_SKU3_CAM_5MP_CAMIF_RESET,
0, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_DOWN,
GPIO_CFG_2MA), GPIO_CFG_ENABLE);
if (rc < 0) {
pr_err("%s: unable to enable reset gpio for main camera!\n",
__func__);
- gpio_free(msm_camera_sensor_ov5647_data.sensor_reset);
+ gpio_free(GPIO_SKU3_CAM_5MP_CAMIF_RESET);
}
rc = gpio_direction_output(
- msm_camera_sensor_ov5647_data.sensor_reset, 1);
+ GPIO_SKU3_CAM_5MP_CAMIF_RESET, 1);
if (rc < 0)
pr_err("%s: unable to set gpio: %d direction for ov5647 camera\n",
- __func__, msm_camera_sensor_ov5647_data.sensor_reset);
+ __func__, GPIO_SKU3_CAM_5MP_CAMIF_RESET);
/*OV7692 GPIO Config*/
+ /*michael cong delete
rc = gpio_request(msm_camera_sensor_ov7692_data.sensor_pwd, "ov7692");
if (rc < 0)
pr_err("%s: gpio_request OV7692 sensor_pwd: %d failed!",
@@ -887,6 +1958,88 @@ static void evb_camera_gpio_cfg(void)
if (rc < 0)
pr_err("%s: unable to set gpio: %d direction for ov7692 camera\n",
__func__, msm_camera_sensor_ov7692_data.sensor_pwd);
+ */
+ // [ start ] lixujie 20120511 modify it for EG808T front Camera
+ #ifndef CONFIG_ODMM
+ rc = gpio_request(GPIO_SKU1_CAM_VGA_SHDN, "ov7692");
+ if (rc < 0)
+ pr_err("%s: gpio_request---GPIO_SKU1_CAM_VGA_SHDN failed!",
+ __func__);
+
+ rc = gpio_tlmm_config(GPIO_CFG(GPIO_SKU1_CAM_VGA_SHDN, 0,
+ GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP,
+ GPIO_CFG_2MA), GPIO_CFG_ENABLE);
+ if (rc < 0) {
+ pr_err("%s:unable to enable Powr Dwn gpio for frnt camera!\n",
+ __func__);
+ gpio_free(GPIO_SKU1_CAM_VGA_SHDN);
+ }
+
+ gpio_direction_output(GPIO_SKU1_CAM_VGA_SHDN, 1);
+
+ rc = gpio_request(GPIO_SKU1_CAM_VGA_RESET_N, "ov7692");
+ if (rc < 0)
+ pr_err("%s: gpio_request---GPIO_SKU1_CAM_VGA_RESET_N failed!",
+ __func__);
+
+ rc = gpio_tlmm_config(GPIO_CFG(GPIO_SKU1_CAM_VGA_RESET_N, 0,
+ GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP,
+ GPIO_CFG_2MA), GPIO_CFG_ENABLE);
+
+ if (rc < 0) {
+ pr_err("%s: unable to enable reset gpio for front camera!\n",
+ __func__);
+ gpio_free(GPIO_SKU1_CAM_VGA_RESET_N);
+ }
+ gpio_direction_output(GPIO_SKU1_CAM_VGA_RESET_N, 1);
+ #endif
+// [ end ]
+
+}
+
+static void sku5_camera_gpio_cfg(void)
+{
+ int rc = 0;
+
+ rc = gpio_request(GPIO_SKU3_CAM_5MP_SHDN_N, "ov5647");
+ if (rc < 0)
+ pr_err("%s: gpio_request OV5647 sensor_pwd: %d failed!",
+ __func__, GPIO_SKU3_CAM_5MP_SHDN_N);
+
+ rc = gpio_tlmm_config(GPIO_CFG(GPIO_SKU3_CAM_5MP_SHDN_N,
+ 0, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_DOWN,
+ GPIO_CFG_2MA), GPIO_CFG_ENABLE);
+ if (rc < 0) {
+ pr_err("%s:unable to enable Powr Dwn gpio for main camera!\n",
+ __func__);
+ gpio_free(GPIO_SKU3_CAM_5MP_SHDN_N);
+ }
+
+ rc = gpio_direction_output(GPIO_SKU3_CAM_5MP_SHDN_N, 1);
+ if (rc < 0)
+ pr_err("%s: unable to set gpio: %d direction for ov5647 camera\n",
+ __func__, GPIO_SKU3_CAM_5MP_SHDN_N);
+
+ rc = gpio_request(GPIO_SKU3_CAM_5MP_CAMIF_RESET, "ov5647");
+ if (rc < 0)
+ pr_err("%s: gpio_request OV5647 sensor_reset: %d failed!",
+ __func__, GPIO_SKU3_CAM_5MP_CAMIF_RESET);
+
+ rc = gpio_tlmm_config(GPIO_CFG(
+ GPIO_SKU3_CAM_5MP_CAMIF_RESET,
+ 0, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_DOWN,
+ GPIO_CFG_2MA), GPIO_CFG_ENABLE);
+ if (rc < 0) {
+ pr_err("%s: unable to enable reset gpio for main camera!\n",
+ __func__);
+ gpio_free(GPIO_SKU3_CAM_5MP_CAMIF_RESET);
+ }
+
+ rc = gpio_direction_output(
+ GPIO_SKU3_CAM_5MP_CAMIF_RESET, 1);
+ if (rc < 0)
+ pr_err("%s: unable to set gpio: %d direction for ov5647 camera\n",
+ __func__, GPIO_SKU3_CAM_5MP_CAMIF_RESET);
}
@@ -956,27 +2109,111 @@ static void skud_camera_gpio_cfg(void)
pr_err("%s: unable to set gpio: %d direction for ov7695 camera\n",
__func__, GPIO_SKUD_CAM_1MP_PWDN);
- printk("gpio request: GPIO_SKUD_CAM_5MP_CAM_VCM_PWDN is %d\n", GPIO_SKUD_CAM_5MP_CAM_VCM_PWDN);
- rc = gpio_request(GPIO_SKUD_CAM_5MP_CAM_VCM_PWDN, "msm_actuator");
+ // ================================
+ printk("gpio request: GPIO_SKUD_CAM_5MP_CAM_VCM_PWDN is %d\n", GPIO_SKUD_CAM_5MP_CAM_VCM_PWDN);
+ rc = gpio_request(GPIO_SKUD_CAM_5MP_CAM_VCM_PWDN, "msm_actuator");
if (rc < 0)
printk("%s: gpio_request msm_actuator : %d failed!",
__func__, GPIO_SKUD_CAM_5MP_CAM_VCM_PWDN);
rc = gpio_tlmm_config(GPIO_CFG(
- GPIO_SKUD_CAM_5MP_CAM_VCM_PWDN,
- 0, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_DOWN,
- GPIO_CFG_2MA), GPIO_CFG_ENABLE);
- if (rc < 0) {
+ GPIO_SKUD_CAM_5MP_CAM_VCM_PWDN,
+ 0, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_DOWN,
+ GPIO_CFG_2MA), GPIO_CFG_ENABLE);
+ if (rc < 0) {
printk("%s:unable to enable Powr Dwn gpio for msm_actuator!\n", __func__);
- gpio_free(GPIO_SKUD_CAM_5MP_CAM_VCM_PWDN);
- }
- rc = gpio_direction_output(GPIO_SKUD_CAM_5MP_CAM_VCM_PWDN, 0);
- if (rc < 0)
- pr_err("%s: unable to set gpio: %d direction for ov5648 camera\n",
- __func__, GPIO_SKUD_CAM_5MP_CAM_VCM_PWDN);
+ gpio_free(GPIO_SKUD_CAM_5MP_CAM_VCM_PWDN);
+ }
+ rc = gpio_direction_output(GPIO_SKUD_CAM_5MP_CAM_VCM_PWDN, 0);
+ if (rc < 0)
+ pr_err("%s: unable to set gpio: %d direction for ov5648 camera\n",
+ __func__, GPIO_SKUD_CAM_5MP_CAM_VCM_PWDN);
+
+ //Free the gpio for the actuator will request it again, only do tlmm config here.
+ gpio_free(GPIO_SKUD_CAM_5MP_CAM_VCM_PWDN);
+ //=================================
+
+ //Fix CAMID leak current issue when phone sleep.
+ printk("gpio request: set CAMID GPIO to INPUT, now the gpio is %d\n", GPIO_SKUD_CAM_5MP_CAMID);
+ rc = gpio_request(GPIO_SKUD_CAM_5MP_CAMID, "ov5648");
+ if (rc < 0)
+ printk("%s: gpio_request GPIO %d : failed!", __func__, GPIO_SKUD_CAM_5MP_CAMID);
+
+ gpio_tlmm_config(GPIO_CFG(
+ GPIO_SKUD_CAM_5MP_CAMID,
+ 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_UP,
+ GPIO_CFG_2MA), GPIO_CFG_ENABLE);
+
+ //Free the gpio, only do tlmm config to input pull high here.
+ gpio_free(GPIO_SKUD_CAM_5MP_CAMID);
+}
+
+
+static void skue_camera_gpio_cfg(void)
+{
+ int rc = 0;
+ printk("skuE_camera_gpio_cfg in, cfg gpio\n");
+ printk("gpio request: GPIO_SKUE_CAM_5MP_SHDN_N is %d\n", GPIO_SKUE_CAM_5MP_SHDN_N);
+ rc = gpio_request(GPIO_SKUE_CAM_5MP_SHDN_N, "AR0542");
+ if (rc < 0)
+ printk("%s: gpio_request AR0542 sensor_pwd: %d failed!",
+ __func__, GPIO_SKUE_CAM_5MP_SHDN_N);
+
+ rc = gpio_tlmm_config(GPIO_CFG(GPIO_SKUE_CAM_5MP_SHDN_N,
+ 0, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_DOWN,
+ GPIO_CFG_2MA), GPIO_CFG_ENABLE);
+ if (rc < 0) {
+ printk("%s:unable to enable Powr Dwn gpio for main camera!\n",
+ __func__);
+ gpio_free(GPIO_SKUE_CAM_5MP_SHDN_N);
+ }
+
+ rc = gpio_direction_output(GPIO_SKUE_CAM_5MP_SHDN_N, 1);
+ if (rc < 0)
+ pr_err("%s: unable to set gpio: %d direction for ov5648 camera\n",
+ __func__, GPIO_SKUE_CAM_5MP_SHDN_N);
+
+ printk("gpio request: GPIO_SKUE_CAM_5MP_CAMIF_RESET is %d\n", GPIO_SKUE_CAM_5MP_CAMIF_RESET);
+ rc = gpio_request(GPIO_SKUE_CAM_5MP_CAMIF_RESET, "AR0542");
+ if (rc < 0)
+ pr_err("%s: gpio_request AR0542 sensor_reset: %d failed!",
+ __func__, GPIO_SKUE_CAM_5MP_CAMIF_RESET);
+
+ rc = gpio_tlmm_config(GPIO_CFG(
+ GPIO_SKUE_CAM_5MP_CAMIF_RESET,
+ 0, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_DOWN,
+ GPIO_CFG_2MA), GPIO_CFG_ENABLE);
+ if (rc < 0) {
+ pr_err("%s: unable to enable reset gpio for main camera!\n",
+ __func__);
+ gpio_free(GPIO_SKUE_CAM_5MP_CAMIF_RESET);
+ }
+
+ rc = gpio_direction_output(
+ GPIO_SKUE_CAM_5MP_CAMIF_RESET, 1);
+ if (rc < 0)
+ pr_err("%s: unable to set gpio: %d direction for AR0542 camera\n",
+ __func__, GPIO_SKUE_CAM_5MP_CAMIF_RESET);
+
+ printk("gpio request: GPIO_SKUE_CAM_PWR_EN is %d\n", GPIO_SKUE_CAM_PWR_EN);
+ rc = gpio_request(GPIO_SKUE_CAM_PWR_EN, "AR0542");
+ if (rc < 0)
+ pr_err("%s: gpio_request AR0542 sensor_pwdn: %d failed!",
+ __func__, GPIO_SKUE_CAM_PWR_EN);
+
+ rc = gpio_tlmm_config(GPIO_CFG(
+ GPIO_SKUE_CAM_PWR_EN,
+ 0, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_DOWN,
+ GPIO_CFG_2MA), GPIO_CFG_ENABLE);
+ if (rc < 0) {
+ pr_err("%s: unable to enable reset gpio for front camera!\n", __func__);
+ gpio_free(GPIO_SKUE_CAM_PWR_EN);
+ }
- /*Free the gpio for the actuator will request it again, only do tlmm config here.*/
- gpio_free(GPIO_SKUD_CAM_5MP_CAM_VCM_PWDN);
+ rc = gpio_direction_output(GPIO_SKUE_CAM_PWR_EN, 1);
+ if (rc < 0)
+ pr_err("%s: unable to set gpio: %d direction for AR0542 camera\n",
+ __func__, GPIO_SKUE_CAM_PWR_EN);
}
@@ -1362,6 +2599,12 @@ static struct i2c_board_info i2c_camera_devices[] = {
{
I2C_BOARD_INFO("sc628a", 0x6E),
},
+ #ifdef CONFIG_WEBCAM_OV7692_QRD
+ {
+ I2C_BOARD_INFO("ov7692", 0x78),
+ .platform_data = &msm_camera_sensor_ov7692_data,
+ },
+#endif
};
static struct i2c_board_info i2c_camera_devices_qrd[] = {
@@ -1424,7 +2667,9 @@ static struct platform_device *camera_devices_evb[] __initdata = {
#ifdef CONFIG_WEBCAM_OV7692_QRD
&msm_camera_sensor_ov7692,
#endif
+#ifdef CONFIG_OV8825
&msm_camera_sensor_ov8825,
+#endif
};
#endif
@@ -1557,6 +2802,7 @@ int lcd_camera_power_onoff(int on)
}
EXPORT_SYMBOL(lcd_camera_power_onoff);
#endif
+
void camera_af_software_powerdown(struct i2c_client *client)
{
int rc = 0;
@@ -1571,8 +2817,8 @@ void camera_af_software_powerdown(struct i2c_client *client)
};
printk("camera_af_software_powerdown IN...\n");
/* send software powerdown cmd to AF motor, avoid current leak */
- if (machine_is_msm8625q_evbd()||
- machine_is_msm8625q_skud() ){
+ if (machine_is_msm8625_qrd5()|| machine_is_msm7x27a_qrd5a() || machine_is_msm8625q_evbd() ||
+ machine_is_msm8625q_skud() || machine_is_msm8625q_skue()){
printk("SKUA AF Motor software powerdown, write i2c saddr:0x18, waddr:0x80, wdata:0x00\n");
rc = i2c_transfer(client->adapter, msg, 1);
if (rc < 0)
@@ -1581,6 +2827,154 @@ void camera_af_software_powerdown(struct i2c_client *client)
}
}
EXPORT_SYMBOL(camera_af_software_powerdown);
+#ifdef CONFIG_S5K3H2_SUNNY_Q8S02E
+int lcd_camera_power_l5_onoff(int on)
+{
+ static struct regulator *ldo5;
+ int rc;
+
+ printk("%s: on = %d\n", __func__, on);
+ ldo5 = regulator_get(NULL, "ldo5");
+ if (IS_ERR(ldo5)) {
+ rc = PTR_ERR(ldo5);
+ pr_err("%s: could not get ldo5: %d\n", __func__, rc);
+ goto out;
+ }
+
+ rc = regulator_set_voltage(ldo5, 1200000, 1200000);
+ if (rc) {
+ pr_err("%s: could not set ldo5 voltage: %d\n", __func__, rc);
+ goto ldo5_free;
+ }
+
+ rc = regulator_enable(ldo5);
+ if (rc) {
+ pr_err("%s: could not enable ldo5: %d\n", __func__, rc);
+ goto ldo5_free;
+ }
+
+ if (on) {
+ rc = regulator_enable(ldo5);
+ if (rc) {
+ pr_err("'%s' regulator enable failed, rc=%d\n",
+ "ldo5", rc);
+ goto ldo5_free;
+ }
+ pr_debug("%s(on): success\n", __func__);
+ } else {
+ rc = regulator_disable(ldo5);
+ if (rc){
+ pr_warning("'%s' regulator disable failed, rc=%d\n",
+ "ldo5", rc);
+ goto ldo5_free;
+ }
+ pr_debug("%s(off): success\n", __func__);
+ }
+
+ldo5_free:
+ regulator_put(ldo5);
+out:
+ ldo5 = NULL;
+ return rc;
+}
+EXPORT_SYMBOL(lcd_camera_power_l5_onoff);
+#endif
+static struct i2c_board_info odmm_i2c_camera_devices[] = {
+
+ #ifdef CONFIG_WEBCAM_OV7692_QRD
+ {
+ I2C_BOARD_INFO("ov7692", 0x78),
+ .platform_data = &msm_camera_sensor_ov7692_data,
+ },
+#endif
+
+
+#ifdef CONFIG_OV5647 //add by zy 20120712
+ {
+ I2C_BOARD_INFO("ov5647", 0x6c),
+ .platform_data = &msm_camera_sensor_ov5647_data,
+ },
+#endif
+#ifdef CONFIG_OV5647_DALING_OVBD631AC
+ {
+ I2C_BOARD_INFO("ov5647_dl_bd631ac", 0x6c-1),
+ .platform_data = &msm_camera_sensor_ov5647_dl_bd631ac_data,
+ },
+#endif
+
+
+#ifdef CONFIG_OV5647_PARTRON_CM500
+ {
+ I2C_BOARD_INFO("ov5647_partr_cm500", 0x6c-2),
+ .platform_data = &msm_camera_sensor_ov5647_partron_cm500_data,
+ },
+#endif
+#ifdef CONFIG_OV5647_HQ_O9B5_DG806T
+ {
+ I2C_BOARD_INFO("ov5647_hq_dg806t", 0x6c-3),
+ .platform_data = &msm_camera_sensor_ov5647_hq_dg806t_data,
+ },
+#endif
+
+};
+
+// lwl modify for EVB1 and other HW board
+
+#ifdef ODMM_PROJECT_STAGE_EVB1
+static struct i2c_board_info odmm_i2c_camera_devices_evb1[] = {
+
+#ifdef CONFIG_S5K5CA
+ {
+ I2C_BOARD_INFO("s5k5ca", 0x78 ),
+ .platform_data = &msm_camera_sensor_s5k5ca_data,
+ },
+#endif
+#ifdef CONFIG_HI351_SUNNY_Q3H01B
+ {
+ I2C_BOARD_INFO("hi351", 0x40),
+ .platform_data = &msm_camera_sensor_hi351_sunny_q3h01b_data,
+ },
+#endif
+
+};
+
+#else
+
+
+static struct i2c_board_info odmm_i2c_camera_s5k5caga[] = {
+
+#ifdef CONFIG_S5K5CA
+ {
+ I2C_BOARD_INFO("s5k5ca", 0x78 ),
+ .platform_data = &msm_camera_sensor_s5k5ca_data,
+ },
+#endif
+
+};
+
+static struct i2c_board_info odmm_i2c_camera_s5k5caga_darling[] = {
+
+#ifdef CONFIG_S5K5CA_DARLING
+ {
+ I2C_BOARD_INFO("s5k5ca_darling", 0x78 ),
+ .platform_data = &msm_camera_sensor_s5k5ca_data,
+ },
+#endif
+
+};
+
+#ifdef CONFIG_HI351_SUNNY_Q3H01B
+static struct i2c_board_info odmm_i2c_camera_hi351[] = {
+
+ {
+ I2C_BOARD_INFO("hi351", 0x40),
+ .platform_data = &msm_camera_sensor_hi351_sunny_q3h01b_data,
+ },
+
+};
+#endif
+#endif
+
void __init msm7627a_camera_init(void)
{
@@ -1588,38 +2982,28 @@ void __init msm7627a_camera_init(void)
#ifndef CONFIG_MSM_CAMERA_V4L2
int rc;
#endif
- pr_debug("msm7627a_camera_init Entered\n");
- if (machine_is_msm7627a_qrd3() || machine_is_msm8625_qrd7()) {
- ov7692_cam_req_gpio[0].gpio =
- GPIO_SKU7_CAM_VGA_SHDN;
- ov7692_cam_gpio_set_tbl[0].gpio = GPIO_SKU7_CAM_VGA_SHDN;
- ov7692_cam_gpio_set_tbl[1].gpio = GPIO_SKU7_CAM_VGA_SHDN;
-
- msm_camera_sensor_ov5647_data.sensor_pwd =
- GPIO_SKU7_CAM_5MP_SHDN_N;
- msm_camera_sensor_ov5647_data.sensor_reset =
- GPIO_SKU7_CAM_5MP_CAMIF_RESET;
- }
+ printk("msm7627a_camera_init Entered\n");
/* LCD and camera power (VREG & LDO) init */
- if (machine_is_msm7627a_evb() || machine_is_msm8625_evb()
- || machine_is_msm8625_evt()
- || machine_is_msm7627a_qrd3()
- || machine_is_msm8625_qrd7()) {
+ if (machine_is_msm7627a_evb() || machine_is_msm8625_evb()) {
#ifndef CONFIG_MSM_CAMERA_V4L2
lcd_camera_power_init();
#endif
evb_camera_gpio_cfg();
- }
-
- if(machine_is_qrd_skud_prime() ||
- machine_is_msm8625q_skud()||
- machine_is_msm8625q_evbd())
+ }else if(machine_is_msm8625_qrd5()|| machine_is_msm7x27a_qrd5a()){
+ sku5_camera_gpio_cfg();
+ }else if(machine_is_msm8625q_skud()||
+ machine_is_msm8625q_evbd())
{
skud_camera_gpio_cfg();
- }
-
+ }else if(machine_is_msm8625q_skue())
+ {
+ skue_camera_gpio_cfg();
+ }
+#ifdef CONFIG_WEBCAM_OV7692_QRD
+ ov7692_camera_gpio_cfg();
+#endif
#ifndef CONFIG_MSM_CAMERA_V4L2
if (machine_is_msm7627a_qrd1()) {
qrd1_camera_gpio_cfg();
@@ -1627,12 +3011,13 @@ void __init msm7627a_camera_init(void)
ARRAY_SIZE(camera_devices_qrd));
} else if (machine_is_msm7627a_evb()
|| machine_is_msm8625_evb()
- || machine_is_msm8625_evt()
+ || machine_is_msm8625_qrd5()
+ || machine_is_msm7x27a_qrd5a()
|| machine_is_msm7627a_qrd3()
|| machine_is_msm8625_qrd7()
|| machine_is_msm8625q_evbd()
|| machine_is_msm8625q_skud()
- || machine_is_qrd_skud_prime()) {
+ || machine_is_msm8625q_skue()) {
platform_add_devices(camera_devices_evb,
ARRAY_SIZE(camera_devices_evb));
} else if (machine_is_msm7627a_qrd3())
@@ -1643,12 +3028,13 @@ void __init msm7627a_camera_init(void)
#endif
if (!machine_is_msm7627a_qrd1() || !machine_is_msm7627a_evb()
|| !machine_is_msm8625_evb()
- || !machine_is_msm8625_evt()
+ || !machine_is_msm8625_qrd5()
+ || !machine_is_msm7x27a_qrd5a()
|| !machine_is_msm7627a_qrd3()
|| !machine_is_msm8625_qrd7()
- || !machine_is_msm8625q_evbd()
+ || machine_is_msm8625q_evbd()
|| !machine_is_msm8625q_skud()
- || !machine_is_qrd_skud_prime())
+ || !machine_is_msm8625q_skue())
register_i2c_devices();
#ifndef CONFIG_MSM_CAMERA_V4L2
rc = regulator_bulk_get(NULL, ARRAY_SIZE(regs_camera), regs_camera);
@@ -1676,12 +3062,13 @@ void __init msm7627a_camera_init(void)
ARRAY_SIZE(i2c_camera_devices_qrd));
} else if (machine_is_msm7627a_evb()
|| machine_is_msm8625_evb()
- || machine_is_msm8625_evt()
+ || machine_is_msm8625_qrd5()
+ || machine_is_msm7x27a_qrd5a()
|| machine_is_msm7627a_qrd3()
|| machine_is_msm8625_qrd7()
|| machine_is_msm8625q_evbd()
|| machine_is_msm8625q_skud()
- || machine_is_qrd_skud_prime()) {
+ || machine_is_msm8625q_skue()) {
pr_debug("machine_is_msm7627a_evb i2c_register_board_info\n");
i2c_register_board_info(MSM_GSBI0_QUP_I2C_BUS_ID,
i2c_camera_devices_evb,
@@ -1689,18 +3076,77 @@ void __init msm7627a_camera_init(void)
} else
#endif
pr_debug("i2c_register_board_info\n");
- if (machine_is_qrd_skud_prime()||
- machine_is_msm8625q_evbd()) {
- i2c_register_board_info(MSM_GSBI0_QUP_I2C_BUS_ID,
- i2c_camera_devices_qpr,
- ARRAY_SIZE(i2c_camera_devices_qpr));
- } else if(machine_is_msm8625q_skud()){
+ if (machine_is_msm7627a_evb()|| machine_is_msm8625_evb()){
+ pr_debug("i2c_camera_devices_evb registered\n");
+ i2c_register_board_info(MSM_GSBI0_QUP_I2C_BUS_ID,
+ i2c_camera_devices,
+ ARRAY_SIZE(i2c_camera_devices));
+ }else if(machine_is_msm8625_qrd5()|| machine_is_msm7x27a_qrd5a()){
+ pr_debug("i2c_camera_devices_sku5 registered\n");
+ i2c_register_board_info(MSM_GSBI0_QUP_I2C_BUS_ID,
+ i2c_camera_devices_sku5,
+ ARRAY_SIZE(i2c_camera_devices_sku5));
+ }else if(machine_is_msm7627a_qrd3()|| machine_is_msm8625_qrd7()){
+ pr_debug("i2c_camera_devices_sku7 registered\n");
+ i2c_register_board_info(MSM_GSBI0_QUP_I2C_BUS_ID,
+ i2c_camera_devices_sku7,
+ ARRAY_SIZE(i2c_camera_devices_sku7));
+ }else if(machine_is_msm8625q_skud() || machine_is_msm8625q_evbd())
+ {
+ printk("i2c_camera_devices_SKUD registered\n");
+ i2c_register_board_info(MSM_GSBI0_QUP_I2C_BUS_ID,
+ i2c_camera_devices_skud,
+ ARRAY_SIZE(i2c_camera_devices_skud));
+ }else if(machine_is_msm8625q_skue())
+ {
+ printk("i2c_camera_devices_SKUE registered\n");
+ i2c_register_board_info(MSM_GSBI0_QUP_I2C_BUS_ID,
+ i2c_camera_devices_skue,
+ ARRAY_SIZE(i2c_camera_devices_skue));
+ }
+
i2c_register_board_info(MSM_GSBI0_QUP_I2C_BUS_ID,
- i2c_camera_devices_qpr_skud,
- ARRAY_SIZE(i2c_camera_devices_qpr_skud));
- } else {
+ odmm_i2c_camera_devices,
+ ARRAY_SIZE(odmm_i2c_camera_devices));
+
+#ifdef ODMM_PROJECT_STAGE_EVB1
i2c_register_board_info(MSM_GSBI0_QUP_I2C_BUS_ID,
- i2c_camera_devices,
- ARRAY_SIZE(i2c_camera_devices));
- }
+ odmm_i2c_camera_devices_evb1,
+ ARRAY_SIZE(odmm_i2c_camera_devices_evb1));
+#else
+
+
+
+
+ gpio_tlmm_config(GPIO_CFG(109, 0, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_DOWN,GPIO_CFG_4MA), GPIO_CFG_ENABLE);
+ gpio_tlmm_config(GPIO_CFG(GPIO_SENSOR_ID, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_UP,GPIO_CFG_4MA), GPIO_CFG_ENABLE);
+ gpio_request(109, "board-camera-id");
+ gpio_direction_output(109, 1);
+ msleep(20);
+ camera_id_status = gpio_get_value(GPIO_SENSOR_ID);
+ gpio_direction_output(109, 0);
+ gpio_free(109);
+
+ gpio_tlmm_config(GPIO_CFG(GPIO_SENSOR_ID, 0, GPIO_CFG_INPUT, GPIO_CFG_KEEPER,GPIO_CFG_4MA), GPIO_CFG_ENABLE);
+
+ printk("langwenlong&&&&&&&&&&&& #######camera_id_status = %d\n",camera_id_status);
+
+ if ( camera_id_status ==1) {
+ i2c_register_board_info(MSM_GSBI0_QUP_I2C_BUS_ID,
+ odmm_i2c_camera_s5k5caga,
+ ARRAY_SIZE(odmm_i2c_camera_s5k5caga));
+ }
+ else if ( camera_id_status == 0) {
+ i2c_register_board_info(MSM_GSBI0_QUP_I2C_BUS_ID,
+ odmm_i2c_camera_s5k5caga_darling,
+ ARRAY_SIZE(odmm_i2c_camera_s5k5caga_darling));
+ }
+ else {
+
+ printk("langwenlong none camera will be registed\n");
+ }
+
+
+#endif
+
}
diff --git a/arch/arm/mach-msm/board-msm7627a-display.c b/arch/arm/mach-msm/board-msm7627a-display.c
old mode 100644
new mode 100755
index 3e6b1f1..6e3ab7a
--- a/arch/arm/mach-msm/board-msm7627a-display.c
+++ b/arch/arm/mach-msm/board-msm7627a-display.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -10,6 +10,7 @@
* GNU General Public License for more details.
*
*/
+#define DEBUG
#include <linux/init.h>
#include <linux/ioport.h>
#include <linux/platform_device.h>
@@ -26,9 +27,18 @@
#include <mach/rpc_pmapp.h>
#include "devices.h"
#include "board-msm7627a.h"
+#include <linux/kernel.h>
+#include <linux/module.h>
#ifdef CONFIG_FB_MSM_TRIPLE_BUFFER
+#if 1 // #suwg.
+// for 960*800 lcd
+//#define MSM_FB_SIZE 0x5FA000
+//lwl modify fb size
+#define MSM_FB_SIZE 0x465000
+#else
#define MSM_FB_SIZE 0x4BF000
+#endif
#define MSM7x25A_MSM_FB_SIZE 0x1C2000
#define MSM8x25_MSM_FB_SIZE 0x5FA000
#define MSM8x25Q_MSM_FB_SIZE 0xAC8000
@@ -39,11 +49,31 @@
#define MSM8x25Q_MSM_FB_SIZE 0x730000
#endif
+#if 1 // #suwg.
+/*
+ * Reserve enough v4l2 space for a double buffered full screen
+ * res image (544x960x1.5x2)
+ */
+#define MSM_V4L2_VIDEO_OVERLAY_BUF_SIZE 1566720
+#else
/*
* Reserve enough v4l2 space for a double buffered full screen
* res image (864x480x1.5x2)
*/
#define MSM_V4L2_VIDEO_OVERLAY_BUF_SIZE 1244160
+#endif
+
+//add for panel module vender detect by wang.xiaojun3@byd.com @131209
+//patch: /sys/module/board_7627a_all/parameters/panel_name
+int ODMM_PANEL_ID = 0;
+char panel_detect_desc[16] = "NO PANEL";
+
+int msm_drm_debug = 0;
+
+MODULE_PARM_DESC(debug, "Enable debug output");
+MODULE_PARM_DESC(panel_name, "Print the panel module name");
+module_param_named(debug, msm_drm_debug, int, 0600);
+module_param_string(panel_name, panel_detect_desc, 20, 0600);
static unsigned fb_size = MSM_FB_SIZE;
static int __init fb_size_setup(char *p)
@@ -54,7 +84,7 @@ static int __init fb_size_setup(char *p)
early_param("fb_size", fb_size_setup);
-static uint32_t lcdc_truly_gpio_initialized;
+static uint32_t lcdc_truly_gpio_initialized = 0;
static struct regulator_bulk_data regs_truly_lcdc[] = {
{ .supply = "rfrx1", .min_uV = 1800000, .max_uV = 1800000 },
};
@@ -216,8 +246,14 @@ int sku3_lcdc_lcd_camera_power_onoff(int on)
{
int rc = 0;
u32 socinfo = socinfo_get_platform_type();
+ static int refcount = 0;
if (on) {
+ if (refcount > 0)
+ {
+ refcount++;
+ return rc;
+ }
if (socinfo == 0x0B)
gpio_set_value_cansleep(SKU3_LCDC_LCD_CAMERA_LDO_1V8,
1);
@@ -232,7 +268,14 @@ int sku3_lcdc_lcd_camera_power_onoff(int on)
if (rc)
pr_err("%s: could not enable regulators: %d\n",
__func__, rc);
+ else
+ refcount++;
} else {
+ if (refcount > 1)
+ {
+ refcount--;
+ return rc;
+ }
if (socinfo == 0x0B)
gpio_set_value_cansleep(SKU3_LCDC_LCD_CAMERA_LDO_1V8,
0);
@@ -247,10 +290,13 @@ int sku3_lcdc_lcd_camera_power_onoff(int on)
if (rc)
pr_err("%s: could not disable regulators: %d\n",
__func__, rc);
+ else
+ refcount--;
}
return rc;
}
+EXPORT_SYMBOL(sku3_lcdc_lcd_camera_power_onoff);
static int sku3_lcdc_power_save(int on)
{
@@ -309,7 +355,8 @@ static struct regulator_bulk_data regs_lcdc[] = {
{ .supply = "gp2", .min_uV = 2850000, .max_uV = 2850000 },
{ .supply = "msme1", .min_uV = 1800000, .max_uV = 1800000 },
};
-static uint32_t lcdc_gpio_initialized;
+
+static uint32_t lcdc_gpio_initialized = 0;
static void lcdc_toshiba_gpio_init(void)
{
@@ -492,10 +539,14 @@ static struct resource msm_v4l2_video_overlay_resources[] = {
#define LCDC_TOSHIBA_FWVGA_PANEL_NAME "lcdc_toshiba_fwvga_pt"
#define MIPI_CMD_RENESAS_FWVGA_PANEL_NAME "mipi_cmd_renesas_fwvga"
-static struct mipi_dsi_platform_data mipi_dsi_pdata;
static int msm_fb_detect_panel(const char *name)
{
int ret = -ENODEV;
+ #if 1 // #suwg
+
+ printk("xxx %s:%s\n ",__func__,name);
+ return ret;
+ #endif
if (machine_is_msm7x27a_surf() || machine_is_msm7625a_surf() ||
machine_is_msm8625_surf()) {
@@ -513,18 +564,16 @@ static int msm_fb_detect_panel(const char *name)
if (!strncmp(name, "lcdc_truly_hvga_ips3p2335_pt", 28))
ret = 0;
} else if (machine_is_msm7627a_evb() || machine_is_msm8625_evb() ||
- machine_is_msm8625_evt()) {
+ machine_is_msm8625_qrd5() || machine_is_msm7x27a_qrd5a()) {
if (!strncmp(name, "mipi_cmd_nt35510_wvga", 21))
ret = 0;
- } else if (machine_is_qrd_skud_prime()) {
- if (!strncmp(name, "mipi_video_hx8389b_qhd", 22))
- ret = 0;
- } else if (machine_is_msm8625q_evbd() || machine_is_msm8625q_skud()) {
- if (!strncmp(name, "mipi_video_hx8389b_qhd", 22)) {
- mipi_dsi_pdata.dlane_swap = 0x0;
- ret = 0;
- }
- }
+ } else if (machine_is_msm8625q_skud() || machine_is_msm8625q_evbd()) {
+ if (!strncmp(name, "mipi_video_hx8389b_qhd", 22))
+ ret = 0;
+ } else if (machine_is_msm8625q_skue()) {
+ if (!strncmp(name, "mipi_video_otm9605a_qhd", 23))
+ ret = 0;
+ }
#if !defined(CONFIG_FB_MSM_LCDC_AUTO_DETECT) && \
!defined(CONFIG_FB_MSM_MIPI_PANEL_AUTO_DETECT) && \
@@ -700,12 +749,23 @@ static int evb_backlight_control(int level, int mode)
static int mipi_NT35510_rotate_panel(void)
{
int rotate = 0;
- if (machine_is_msm8625_evt())
+ if (machine_is_msm8625_qrd5() || machine_is_msm7x27a_qrd5a())
rotate = 1;
return rotate;
}
+static int skue_backlight_control(int level, int mode)
+{
+ int ret = 0;
+
+ ret = pmapp_disp_backlight_set_brightness(level);
+ if (ret)
+ pr_err("%s: can't set lcd backlight!\n", __func__);
+
+ return ret;
+}
+
static struct msm_panel_common_pdata mipi_truly_pdata = {
.pmic_backlight = mipi_truly_set_bl,
};
@@ -744,6 +804,32 @@ static struct platform_device mipi_dsi_hx8389b_panel_device = {
}
};
+static struct msm_panel_common_pdata mipi_hx8392a_pdata = {
+ .backlight = evb_backlight_control,
+ .rotate_panel = NULL,
+};
+
+static struct platform_device mipi_dsi_hx8392a_panel_device = {
+ .name = "mipi_hx8392a",
+ .id = 0,
+ .dev = {
+ .platform_data = &mipi_hx8392a_pdata,
+ }
+};
+
+static struct msm_panel_common_pdata mipi_otm9605a_pdata = {
+ .backlight = skue_backlight_control,
+ .rotate_panel = NULL,
+};
+
+static struct platform_device mipi_dsi_otm9605a_panel_device = {
+ .name = "mipi_otm9605a",
+ .id = 0,
+ .dev = {
+ .platform_data = &mipi_otm9605a_pdata,
+ }
+};
+
static struct msm_panel_common_pdata mipi_NT35516_pdata = {
.backlight = evb_backlight_control,
};
@@ -797,8 +883,13 @@ static struct platform_device *evb_fb_devices[] __initdata = {
static struct platform_device *skud_fb_devices[] __initdata = {
&msm_fb_device,
&mipi_dsi_hx8389b_panel_device,
- &mipi_dsi_NT35510_panel_device,
&mipi_dsi_NT35590_panel_device,
+ &mipi_dsi_hx8392a_panel_device,
+};
+
+static struct platform_device *skue_fb_devices[] __initdata = {
+ &msm_fb_device,
+ &mipi_dsi_otm9605a_panel_device,
};
void __init msm_msm7627a_allocate_memory_regions(void)
@@ -809,8 +900,9 @@ void __init msm_msm7627a_allocate_memory_regions(void)
if (machine_is_msm7625a_surf() || machine_is_msm7625a_ffa())
fb_size = MSM7x25A_MSM_FB_SIZE;
else if (machine_is_msm7627a_evb() || machine_is_msm8625_evb()
- || machine_is_msm8625_evt()
- || machine_is_qrd_skud_prime())
+ || machine_is_msm8625_qrd5() || machine_is_msm7x27a_qrd5a()
+ || machine_is_msm8625q_skue()
+ )
fb_size = MSM8x25_MSM_FB_SIZE;
else if (machine_is_msm8625q_evbd() || machine_is_msm8625q_skud())
fb_size = MSM8x25Q_MSM_FB_SIZE;
@@ -876,6 +968,9 @@ static int msm_fb_get_lane_config(void)
{
/* For MSM7627A SURF/FFA and QRD */
int rc = DSI_TWO_LANES;
+ #if 1 // #suwg
+ return rc;
+ #endif
if (machine_is_msm7625a_surf() || machine_is_msm7625a_ffa()) {
rc = DSI_SINGLE_LANE;
pr_info("DSI_SINGLE_LANES\n");
@@ -1049,18 +1144,46 @@ static int msm_fb_dsi_client_skud_reset(void)
return rc;
}
-static int msm_fb_dsi_client_reset(void)
+#define GPIO_SKUE_LCD_BRDG_RESET_N 78
+
+static unsigned skue_mipi_dsi_gpio[] = {
+ GPIO_CFG(GPIO_SKUE_LCD_BRDG_RESET_N, 0, GPIO_CFG_OUTPUT,
+ GPIO_CFG_NO_PULL,
+ GPIO_CFG_2MA), /* GPIO_SKUE_LCD_BRDG_RESET_N */
+};
+
+static int msm_fb_dsi_client_skue_reset(void)
{
int rc = 0;
+ pr_debug("%s\n", __func__);
+
+ rc = gpio_request(GPIO_SKUE_LCD_BRDG_RESET_N, "skue_lcd_brdg_reset_n");
+ if (rc < 0) {
+ pr_err("failed to request skue lcd brdg reset_n\n");
+ return rc;
+ }
+
+ return rc;
+}
+
+
+static int msm_fb_dsi_client_reset(void)
+{
+ int rc = 0;
+#if 1 // #suwg.
+ printk("xxx %s \n",__func__);
+ return rc;
+#endif
if (machine_is_msm7627a_qrd1())
rc = msm_fb_dsi_client_qrd1_reset();
else if (machine_is_msm7627a_evb() || machine_is_msm8625_evb()
- || machine_is_msm8625_evt())
+ || machine_is_msm8625_qrd5() || machine_is_msm7x27a_qrd5a())
rc = msm_fb_dsi_client_qrd3_reset();
- else if (machine_is_qrd_skud_prime() || machine_is_msm8625q_evbd()
- || machine_is_msm8625q_skud())
- rc = msm_fb_dsi_client_skud_reset();
+ else if (machine_is_msm8625q_skud() || machine_is_msm8625q_evbd())
+ rc = msm_fb_dsi_client_skud_reset();
+ else if (machine_is_msm8625q_skue())
+ rc = msm_fb_dsi_client_skue_reset();
else
rc = msm_fb_dsi_client_msm_reset();
@@ -1073,7 +1196,7 @@ static struct regulator_bulk_data regs_dsi[] = {
{ .supply = "msme1", .min_uV = 1800000, .max_uV = 1800000 },
};
-static int dsi_gpio_initialized;
+static int dsi_gpio_initialized = 0;
static int mipi_dsi_panel_msm_power(int on)
{
@@ -1340,10 +1463,15 @@ static int mipi_dsi_panel_qrd3_power(int on)
msleep(20);
} else {
- gpio_tlmm_config(GPIO_CFG(GPIO_QRD3_LCD_BACKLIGHT_EN, 0,
+ /* FIXME: GPIO_QRD3_LCD_BACKLIGHT_EN can't be set as
+ * input by below statement, so just keep it output low
+ */
+ gpio_set_value_cansleep(GPIO_QRD3_LCD_BACKLIGHT_EN, 0);
+#if 0
+ gpio_tlmm_config(GPIO_CFG(GPIO_QRD3_LCD_BACKLIGHT_EN, 0,
GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN, GPIO_CFG_2MA),
GPIO_CFG_DISABLE);
-
+#endif
gpio_tlmm_config(GPIO_CFG(GPIO_QRD3_LCD_BRDG_RESET_N, 0,
GPIO_CFG_INPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA),
GPIO_CFG_DISABLE);
@@ -1360,7 +1488,7 @@ static int mipi_dsi_panel_qrd3_power(int on)
return rc;
}
-static int skud_dsi_gpio_initialized;
+static int skud_dsi_gpio_initialized = 0;
static int mipi_dsi_panel_skud_power(int on)
{
int rc = 0;
@@ -1379,8 +1507,7 @@ static int mipi_dsi_panel_skud_power(int on)
return rc;
}
- rc = gpio_direction_output(GPIO_SKUD_LCD_BRDG_RESET_N,
- 1);
+ rc = gpio_direction_output(GPIO_SKUD_LCD_BRDG_RESET_N, 1);
if (rc < 0) {
pr_err("Failed GPIO bridge Reset\n");
@@ -1410,9 +1537,9 @@ static int mipi_dsi_panel_skud_power(int on)
/*Toggle Bridge Reset GPIO*/
msleep(20);
gpio_set_value_cansleep(GPIO_SKUD_LCD_BRDG_RESET_N, 0);
- msleep(20);
+ msleep(5);
gpio_set_value_cansleep(GPIO_SKUD_LCD_BRDG_RESET_N, 1);
- msleep(20);
+ msleep(10);
} else {
gpio_tlmm_config(GPIO_CFG(GPIO_SKUD_LCD_BRDG_RESET_N, 0,
@@ -1423,32 +1550,32 @@ static int mipi_dsi_panel_skud_power(int on)
return rc;
}
-static int evbd_dsi_gpio_initialized;
-
-static int mipi_dsi_panel_evbd_power(int on)
+static int skue_dsi_gpio_initialized = 0;
+static int mipi_dsi_panel_skue_power(int on)
{
int rc = 0;
- if (!evbd_dsi_gpio_initialized) {
+ pr_debug("%s: on = %d\n", __func__, on);
+
+ if (!skue_dsi_gpio_initialized) {
pmapp_disp_backlight_init();
- evbd_dsi_gpio_initialized = 1;
+ skue_dsi_gpio_initialized = 1;
if (mdp_pdata.cont_splash_enabled) {
/*Configure LCD Bridge reset*/
- rc = gpio_tlmm_config(skud_mipi_dsi_gpio[0],
+ rc = gpio_tlmm_config(skue_mipi_dsi_gpio[0],
GPIO_CFG_ENABLE);
if (rc < 0) {
pr_err("Failed to enable LCD Bridge reset enable\n");
return rc;
}
- rc = gpio_direction_output(GPIO_SKUD_LCD_BRDG_RESET_N,
- 1);
+ rc = gpio_direction_output(GPIO_SKUE_LCD_BRDG_RESET_N, 1);
if (rc < 0) {
pr_err("Failed GPIO bridge Reset\n");
- gpio_free(GPIO_SKUD_LCD_BRDG_RESET_N);
+ gpio_free(GPIO_SKUE_LCD_BRDG_RESET_N);
return rc;
}
return 0;
@@ -1456,67 +1583,196 @@ static int mipi_dsi_panel_evbd_power(int on)
}
if (on) {
- /*Enable EXT_2.85 and 1.8 regulators*/
- rc = regulator_enable(gpio_reg_2p85v);
- if (rc < 0)
- pr_err("%s: reg enable failed\n", __func__);
- rc = regulator_enable(gpio_reg_1p8v);
- if (rc < 0)
- pr_err("%s: reg enable failed\n", __func__);
-
/*Configure LCD Bridge reset*/
- rc = gpio_tlmm_config(skud_mipi_dsi_gpio[0], GPIO_CFG_ENABLE);
+ rc = gpio_tlmm_config(skue_mipi_dsi_gpio[0], GPIO_CFG_ENABLE);
if (rc < 0) {
pr_err("Failed to enable LCD Bridge reset enable\n");
return rc;
}
- rc = gpio_direction_output(GPIO_SKUD_LCD_BRDG_RESET_N, 1);
+ rc = gpio_direction_output(GPIO_SKUE_LCD_BRDG_RESET_N, 1);
if (rc < 0) {
pr_err("Failed GPIO bridge Reset\n");
- gpio_free(GPIO_SKUD_LCD_BRDG_RESET_N);
+ gpio_free(GPIO_SKUE_LCD_BRDG_RESET_N);
return rc;
}
/*Toggle Bridge Reset GPIO*/
msleep(20);
- gpio_set_value_cansleep(GPIO_SKUD_LCD_BRDG_RESET_N, 0);
+ gpio_set_value_cansleep(GPIO_SKUE_LCD_BRDG_RESET_N, 0);
msleep(20);
- gpio_set_value_cansleep(GPIO_SKUD_LCD_BRDG_RESET_N, 1);
+ gpio_set_value_cansleep(GPIO_SKUE_LCD_BRDG_RESET_N, 1);
msleep(20);
} else {
- gpio_tlmm_config(GPIO_CFG(GPIO_SKUD_LCD_BRDG_RESET_N, 0,
- GPIO_CFG_INPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA),
- GPIO_CFG_DISABLE);
-
- rc = regulator_disable(gpio_reg_2p85v);
- if (rc < 0)
- pr_err("%s: reg disable failed\n", __func__);
- rc = regulator_disable(gpio_reg_1p8v);
- if (rc < 0)
- pr_err("%s: reg disable failed\n", __func__);
-
+ /*Pull down Reset GPIO*/
+ gpio_tlmm_config(GPIO_CFG(GPIO_SKUE_LCD_BRDG_RESET_N, 0,
+ GPIO_CFG_INPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA),
+ GPIO_CFG_DISABLE);
}
return rc;
}
+static int evbd_dsi_gpio_initialized;
+
+static int mipi_dsi_panel_evbd_power(int on)
+{
+ int rc = 0;
+
+ if (!evbd_dsi_gpio_initialized) {
+ pmapp_disp_backlight_init();
+
+ evbd_dsi_gpio_initialized = 1;
+
+ if (mdp_pdata.cont_splash_enabled) {
+ /*Configure LCD Bridge reset*/
+ rc = gpio_tlmm_config(skud_mipi_dsi_gpio[0],
+ GPIO_CFG_ENABLE);
+ if (rc < 0) {
+ pr_err("Failed to enable LCD Bridge reset enable\n");
+ return rc;
+ }
+
+ rc = gpio_direction_output(GPIO_SKUD_LCD_BRDG_RESET_N,
+ 1);
+
+ if (rc < 0) {
+ pr_err("Failed GPIO bridge Reset\n");
+ gpio_free(GPIO_SKUD_LCD_BRDG_RESET_N);
+ return rc;
+ }
+ return 0;
+ }
+ }
+
+ if (on) {
+ /*Enable EXT_2.85 and 1.8 regulators*/
+ rc = regulator_enable(gpio_reg_2p85v);
+ if (rc < 0)
+ pr_err("%s: reg enable failed\n", __func__);
+ rc = regulator_enable(gpio_reg_1p8v);
+ if (rc < 0)
+ pr_err("%s: reg enable failed\n", __func__);
+
+ /*Configure LCD Bridge reset*/
+ rc = gpio_tlmm_config(skud_mipi_dsi_gpio[0], GPIO_CFG_ENABLE);
+ if (rc < 0) {
+ pr_err("Failed to enable LCD Bridge reset enable\n");
+ return rc;
+ }
+
+ rc = gpio_direction_output(GPIO_SKUD_LCD_BRDG_RESET_N, 1);
+
+ if (rc < 0) {
+ pr_err("Failed GPIO bridge Reset\n");
+ gpio_free(GPIO_SKUD_LCD_BRDG_RESET_N);
+ return rc;
+ }
+
+ /*Toggle Bridge Reset GPIO*/
+ msleep(20);
+ gpio_set_value_cansleep(GPIO_SKUD_LCD_BRDG_RESET_N, 0);
+ msleep(20);
+ gpio_set_value_cansleep(GPIO_SKUD_LCD_BRDG_RESET_N, 1);
+ msleep(20);
+
+ } else {
+ gpio_tlmm_config(GPIO_CFG(GPIO_SKUD_LCD_BRDG_RESET_N, 0,
+ GPIO_CFG_INPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA),
+ GPIO_CFG_DISABLE);
+
+ rc = regulator_disable(gpio_reg_2p85v);
+ if (rc < 0)
+ pr_err("%s: reg disable failed\n", __func__);
+ rc = regulator_disable(gpio_reg_1p8v);
+ if (rc < 0)
+ pr_err("%s: reg disable failed\n", __func__);
+
+ }
+
+ return rc;
+}
+
+#if 1 // #suwg.
+#define ODMM_LCD_BACKLIGHT 96 /*LCD_BKLT_CTRL*/
+static int odmm_dsi_gpio_initialized;
+static struct regulator_bulk_data odmm_regs_dsi[] = {
+ { .supply = "gp2", .min_uV = 2850000, .max_uV = 2850000 },
+};
+
+#endif
+
static char mipi_dsi_splash_is_enabled(void);
static int mipi_dsi_panel_power(int on)
{
int rc = 0;
+#if 1 // #suwg.
+ if(!odmm_dsi_gpio_initialized){
+ rc = gpio_request(ODMM_LCD_BACKLIGHT,
+ "odmm_gpio_bkl_en");
+ if (rc < 0)
+ return rc;
+ rc = gpio_tlmm_config(GPIO_CFG(ODMM_LCD_BACKLIGHT, 0,
+ GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA),
+ GPIO_CFG_ENABLE);
+ if (rc < 0) {
+ pr_err("failed odmm GPIO_BACKLIGHT_EN tlmm config\n");
+ return rc;
+ }
+ rc = gpio_direction_output(ODMM_LCD_BACKLIGHT, 1);
+ if (rc < 0) {
+ pr_err("failed to enable backlight\n");
+ gpio_free(ODMM_LCD_BACKLIGHT);
+ return rc;
+ }
+ rc = regulator_bulk_get(NULL, ARRAY_SIZE(odmm_regs_dsi), odmm_regs_dsi);
+ if (rc) {
+ pr_err("%s: could not get regulators: %d\n",
+ __func__, rc);
+ goto fail_gpio2;
+ }
+
+ rc = regulator_bulk_set_voltage(ARRAY_SIZE(odmm_regs_dsi),
+ odmm_regs_dsi);
+ if (rc) {
+ pr_err("%s: could not set voltages: %d\n",
+ __func__, rc);
+ goto fail_vreg;
+ }
+
+ rc = regulator_bulk_enable(ARRAY_SIZE(odmm_regs_dsi), odmm_regs_dsi);
+ // regulator_bulk_disable(ARRAY_SIZE(odmm_regs_dsi), odmm_regs_dsi);
+
+ if (rc)
+ pr_err("%s: could not %sable regulators: %d\n",
+ __func__, on ? "en" : "dis", rc);
+
+ odmm_dsi_gpio_initialized = 1;
+
+ }
+
+
+ return rc;
+fail_vreg:
+ regulator_bulk_free(ARRAY_SIZE(odmm_regs_dsi), odmm_regs_dsi);
+fail_gpio2:
+ gpio_free(ODMM_LCD_BACKLIGHT);
+ return rc;
+#endif
if (machine_is_msm7627a_qrd1())
rc = mipi_dsi_panel_qrd1_power(on);
else if (machine_is_msm7627a_evb() || machine_is_msm8625_evb()
- || machine_is_msm8625_evt())
+ || machine_is_msm8625_qrd5() || machine_is_msm7x27a_qrd5a())
rc = mipi_dsi_panel_qrd3_power(on);
- else if (machine_is_qrd_skud_prime() || machine_is_msm8625q_skud())
- rc = mipi_dsi_panel_skud_power(on);
- else if (machine_is_msm8625q_evbd())
- rc = mipi_dsi_panel_evbd_power(on);
+ else if (machine_is_msm8625q_skud())
+ rc = mipi_dsi_panel_skud_power(on);
+ else if (machine_is_msm8625q_evbd())
+ rc = mipi_dsi_panel_evbd_power(on);
+ else if (machine_is_msm8625q_skue())
+ rc = mipi_dsi_panel_skue_power(on);
else
rc = mipi_dsi_panel_msm_power(on);
return rc;
@@ -1567,25 +1823,48 @@ void msm7x27a_set_display_params(char *prim_panel)
strnlen("mipi_video_nt35510_wvga",
PANEL_NAME_MAX_LEN)))
disable_splash = 1;
- else if (!(machine_is_msm7627a_evb() || machine_is_msm8625_evb()
- || machine_is_msm8625_evt()))
- disable_splash = 1;
-
}
- if (machine_is_msm8625q_evbd() || machine_is_msm8625q_skud())
- mipi_dsi_pdata.dlane_swap = 0x0;
+ if (machine_is_msm8625q_skue())
+ disable_splash = 1;
}
+ #if 1 // #suwg.
+static struct platform_device *odmm_fb_devices[] __initdata = {
+ &msm_fb_device,
+};
+#endif
void __init msm_fb_add_devices(void)
{
int rc = 0;
+ #if 1 // #suwg.
+ printk("xxx %s \n",__func__);
+ printk("machine_is_msm7627a_qrd1 %d\n",machine_is_msm7627a_qrd1());
+ printk("machine_is_msm8625q_skud %d\n",machine_is_msm8625q_skud());
+ printk("machine_is_msm7x27a_qrd5a %d\n",machine_is_msm7x27a_qrd5a());
+ printk("machine_is_msm8625_qrd5 %d\n",machine_is_msm8625_qrd5());
+ printk("disable_splash %d\n",disable_splash);
+
msm7x27a_set_display_params(prim_panel_name);
+ if (disable_splash)
+ mdp_pdata.cont_splash_enabled = 0x0;
+
+ platform_add_devices(odmm_fb_devices, ARRAY_SIZE(odmm_fb_devices));
+ msm_fb_register_device("mdp", &mdp_pdata);
+//#ifdef CONFIG_FB_MSM_MIPI_DSI
+ msm_fb_register_device("mipi_dsi", &mipi_dsi_pdata);
+//#endif
+
+ return;
+ #endif
+
+ msm7x27a_set_display_params(prim_panel_name);
+
if (machine_is_msm7627a_qrd1())
platform_add_devices(qrd_fb_devices,
ARRAY_SIZE(qrd_fb_devices));
else if (machine_is_msm7627a_evb() || machine_is_msm8625_evb()
- || machine_is_msm8625_evt()) {
+ || machine_is_msm8625_qrd5() || machine_is_msm7x27a_qrd5a()) {
mipi_NT35510_pdata.bl_lock = 1;
mipi_NT35516_pdata.bl_lock = 1;
if (disable_splash)
@@ -1598,13 +1877,32 @@ void __init msm_fb_add_devices(void)
mdp_pdata.cont_splash_enabled = 0x0;
platform_add_devices(qrd3_fb_devices,
ARRAY_SIZE(qrd3_fb_devices));
- } else if (machine_is_qrd_skud_prime() || machine_is_msm8625q_evbd()
- || machine_is_msm8625q_skud()) {
+ } else if (machine_is_msm8625q_skud() || machine_is_msm8625q_evbd()) {
if (disable_splash)
mdp_pdata.cont_splash_enabled = 0x0;
- platform_add_devices(skud_fb_devices,
+
+ /* SKUD and SKUD' use different lane connection */
+ if (cpu_is_msm8625q()){
+ if(!strncmp((char *)prim_panel_name, "mipi_video_hx8392a_720p", 23))
+ mipi_dsi_pdata.dlane_swap = 3;
+ else
+ mipi_dsi_pdata.dlane_swap = 0;
+
+ pr_info("[DISP] The prim panel name is %s, Swap lane is %d\n", prim_panel_name,mipi_dsi_pdata.dlane_swap);
+ }
+ platform_add_devices(skud_fb_devices,
ARRAY_SIZE(skud_fb_devices));
- } else {
+ } else if (machine_is_msm8625q_skue()) {
+ if (disable_splash)
+ mdp_pdata.cont_splash_enabled = 0x0;
+
+ /* SKUE and SKUE' use different lane connection */
+ if (cpu_is_msm8625q())
+ mipi_dsi_pdata.dlane_swap = 0;
+
+ platform_add_devices(skue_fb_devices,
+ ARRAY_SIZE(skue_fb_devices));
+ } else {
mdp_pdata.cont_splash_enabled = 0x0;
platform_add_devices(msm_fb_devices,
ARRAY_SIZE(msm_fb_devices));
@@ -1619,8 +1917,8 @@ void __init msm_fb_add_devices(void)
msm_fb_register_device("mipi_dsi", &mipi_dsi_pdata);
#endif
if (machine_is_msm7627a_evb() || machine_is_msm8625_evb()
- || machine_is_msm8625_evt() || machine_is_msm8625q_evbd()) {
-
+ || machine_is_msm8625_qrd5() || machine_is_msm7x27a_qrd5a()
+ || machine_is_msm8625q_evbd()) {
gpio_reg_2p85v = regulator_get(&mipi_dsi_device.dev,
"lcd_vdd");
if (IS_ERR(gpio_reg_2p85v))
diff --git a/arch/arm/mach-msm/board-msm7627a-io.c b/arch/arm/mach-msm/board-msm7627a-io.c
index bd94bb2..4490945 100755
--- a/arch/arm/mach-msm/board-msm7627a-io.c
+++ b/arch/arm/mach-msm/board-msm7627a-io.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2013, The Linux Foundation. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -30,7 +30,9 @@
#include <mach/socinfo.h>
#include "devices.h"
#include <linux/input/synaptics_dsx.h>
-
+#ifdef CONFIG_TOUCHSCREEN_FT6306
+#include <linux/ft6306_touch.h>
+#endif
#include "board-msm7627a.h"
#include "devices-msm7x2xa.h"
@@ -81,6 +83,7 @@ static struct i2c_board_info rmi4_i2c_devices[] = {
};
/******************** SYNAPTICS *********************************/
+#if 0
static unsigned int kp_row_gpios[] = {31, 32, 33, 34, 35};
static unsigned int kp_col_gpios[] = {36, 37, 38, 39, 40};
@@ -149,6 +152,7 @@ static struct platform_device kp_pdev = {
},
};
+#endif
/* 8625 keypad device information */
static unsigned int kp_row_gpios_8625[] = {31};
static unsigned int kp_col_gpios_8625[] = {36, 37};
@@ -158,7 +162,7 @@ static const unsigned short keymap_8625[] = {
KEY_VOLUMEDOWN,
};
-static const unsigned short keymap_8625_evt[] = {
+static const unsigned short keymap_8625_qrd5[] = {
KEY_VOLUMEDOWN,
KEY_VOLUMEUP,
};
@@ -194,6 +198,88 @@ static struct platform_device kp_pdev_8625 = {
},
};
+/* skud keypad device information */
+static unsigned int kp_row_gpios_skud[] = {31, 32};
+static unsigned int kp_col_gpios_skud[] = {37};
+
+static const unsigned short keymap_skud[] = {
+ KEY_VOLUMEUP,
+ KEY_VOLUMEDOWN,
+};
+
+static struct gpio_event_matrix_info kp_matrix_info_skud = {
+ .info.func = gpio_event_matrix_func,
+ .keymap = keymap_skud,
+ .output_gpios = kp_row_gpios_skud,
+ .input_gpios = kp_col_gpios_skud,
+ .noutputs = ARRAY_SIZE(kp_row_gpios_skud),
+ .ninputs = ARRAY_SIZE(kp_col_gpios_skud),
+ .settle_time.tv64 = 40 * NSEC_PER_USEC,
+ .poll_time.tv64 = 20 * NSEC_PER_MSEC,
+ .flags = GPIOKPF_LEVEL_TRIGGERED_IRQ | GPIOKPF_ACTIVE_HIGH |
+ GPIOKPF_PRINT_UNMAPPED_KEYS,
+};
+
+static struct gpio_event_info *kp_info_skud[] = {
+ &kp_matrix_info_skud.info,
+};
+
+static struct gpio_event_platform_data kp_pdata_skud = {
+ .name = "7x27a_kp",
+ .info = kp_info_skud,
+ .info_count = ARRAY_SIZE(kp_info_skud)
+};
+
+static struct platform_device kp_pdev_skud = {
+ .name = GPIO_EVENT_DEV_NAME,
+ .id = -1,
+ .dev = {
+ .platform_data = &kp_pdata_skud,
+ },
+};
+/* end of skud keypad device information */
+
+/* skue keypad device information */
+static unsigned int kp_row_gpios_skue[] = {31, 32};
+static unsigned int kp_col_gpios_skue[] = {37};
+
+static const unsigned short keymap_skue[] = {
+ KEY_VOLUMEUP,
+ KEY_VOLUMEDOWN,
+};
+
+static struct gpio_event_matrix_info kp_matrix_info_skue = {
+ .info.func = gpio_event_matrix_func,
+ .keymap = keymap_skue,
+ .output_gpios = kp_row_gpios_skue,
+ .input_gpios = kp_col_gpios_skue,
+ .noutputs = ARRAY_SIZE(kp_row_gpios_skue),
+ .ninputs = ARRAY_SIZE(kp_col_gpios_skue),
+ .settle_time.tv64 = 40 * NSEC_PER_USEC,
+ .poll_time.tv64 = 20 * NSEC_PER_MSEC,
+ .flags = GPIOKPF_LEVEL_TRIGGERED_IRQ | GPIOKPF_ACTIVE_HIGH |
+ GPIOKPF_PRINT_UNMAPPED_KEYS,
+};
+
+static struct gpio_event_info *kp_info_skue[] = {
+ &kp_matrix_info_skue.info,
+};
+
+static struct gpio_event_platform_data kp_pdata_skue = {
+ .name = "7x27a_kp",
+ .info = kp_info_skue,
+ .info_count = ARRAY_SIZE(kp_info_skue)
+};
+
+static struct platform_device kp_pdev_skue = {
+ .name = GPIO_EVENT_DEV_NAME,
+ .id = -1,
+ .dev = {
+ .platform_data = &kp_pdata_skue,
+ },
+};
+/* end of skue keypad device information */
+
#define LED_GPIO_PDM 96
#define MXT_TS_IRQ_GPIO 48
@@ -205,12 +291,12 @@ static ssize_t mxt_virtual_keys_register(struct kobject *kobj,
struct kobj_attribute *attr, char *buf)
{
char *virtual_keys = __stringify(EV_KEY) ":" __stringify(KEY_MENU) \
- ":60:840:120:80" ":" __stringify(EV_KEY) \
- ":" __stringify(KEY_HOME) ":180:840:120:80" \
+ ":60:860:110:80" ":" __stringify(EV_KEY) \
+ ":" __stringify(KEY_HOME) ":180:860:110:80" \
":" __stringify(EV_KEY) ":" \
- __stringify(KEY_BACK) ":300:840:120:80" \
+ __stringify(KEY_BACK) ":300:860:110:80" \
":" __stringify(EV_KEY) ":" \
- __stringify(KEY_SEARCH) ":420:840:120:80" "\n";
+ __stringify(KEY_SEARCH) ":420:860:110:80" "\n";
return snprintf(buf, strnlen(virtual_keys, MAX_VKEY_LEN) + 1 , "%s",
virtual_keys);
@@ -295,15 +381,15 @@ static const u8 mxt_config_data[] = {
80, 100, 15, 3,
};
-static const u8 mxt_config_data_evt[] = {
+static const u8 mxt_config_data_qrd5[] = {
/* T6 Object */
0, 0, 0, 0, 0, 0,
/* T38 Object */
- 20, 1, 0, 25, 9, 12, 0, 0,
+ 21, 0, 2, 0, 0, 0, 0, 0,
/* T7 Object */
24, 12, 10,
/* T8 Object */
- 30, 0, 20, 20, 0, 0, 0, 0, 10, 192,
+ 30, 0, 20, 20, 10, 0, 0, 0, 10, 192,
/* T9 Object */
131, 0, 0, 18, 11, 0, 16, 70, 2, 1,
0, 2, 1, 62, 10, 10, 10, 10, 107, 3,
@@ -340,6 +426,129 @@ static const u8 mxt_config_data_evt[] = {
80, 100, 15, 3,
};
+static const u8 mxt_config_data_qrd5a[] = {
+ /* T6 Object */
+ 0, 0, 0, 0, 0, 0,
+ /* T38 Object */
+ 21, 0, 3, 0, 0, 0, 0, 0,
+ /* T7 Object */
+ 24, 12, 10,
+ /* T8 Object */
+ 30, 0, 20, 20, 10, 0, 0, 0, 10, 192,
+ /* T9 Object */
+ 131, 0, 0, 18, 11, 0, 16, 70, 2, 1,
+ 0, 2, 1, 62, 10, 10, 10, 10, 107, 3,
+ 223, 1, 2, 2, 20, 20, 172, 40, 139, 110,
+ 10, 15, 0, 0, 0,
+ /* T15 Object */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0,
+ /* T18 Object */
+ 0, 0,
+ /* T19 Object */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ /* T23 Object */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ /* T25 Object */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ /* T40 Object */
+ 0, 0, 0, 0, 0,
+ /* T42 Object */
+ 3, 20, 45, 40, 128, 0, 0, 0,
+ /* T46 Object */
+ 0, 2, 16, 16, 0, 0, 0, 0, 0,
+ /* T47 Object */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ /* T48 Object */
+ 1, 12, 64, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 6, 6, 0, 0, 100, 4, 64,
+ 10, 0, 20, 5, 0, 38, 0, 20, 0, 0,
+ 0, 0, 0, 0, 16, 65, 3, 1, 1, 0,
+ 10, 10, 10, 0, 0, 15, 15, 154, 58, 145,
+ 80, 100, 15, 3,
+};
+
+
+static const u8 mxt_config_data_qrd5_truly[] = {
+ /* T6 Object */
+ 0, 0, 0, 0, 0, 0,
+ /* T38 Object */
+ 21, 0, 2, 0, 0, 0, 0, 85,
+ /* T7 Object */
+ 24, 12, 10,
+ /* T8 Object */
+ 30, 0, 20, 20, 10, 0, 0, 0, 10, 192,
+ /* T9 Object */
+ 131, 0, 0, 18, 11, 0, 16, 70, 2, 3,
+ 0, 2, 1, 62, 10, 10, 10, 10, 107, 3,
+ 223, 1, 2, 2, 20, 20, 172, 40, 139, 110,
+ 10, 15, 0, 0, 0,
+ /* T15 Object */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0,
+ /* T18 Object */
+ 0, 0,
+ /* T19 Object */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
+ /* T23 Object */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+ /* T25 Object */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ /* T40 Object */
+ 0, 0, 0, 0, 0,
+ /* T42 Object */
+ 3, 20, 45, 40, 128, 0, 0, 0,
+ /* T46 Object */
+ 0, 2, 16, 16, 0, 0, 0, 0, 0,
+ /* T47 Object */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ /* T48 Object */
+ 1, 12, 64, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 6, 6, 0, 0, 100, 4, 64,
+ 10, 0, 20, 5, 0, 38, 0, 20, 0, 0,
+ 0, 0, 0, 0, 16, 65, 3, 1, 1, 0,
+ 10, 10, 10, 0, 0, 15, 15, 154, 58, 145,
+ 80, 100, 15, 3,
+};
+
+static const u8 mxt_config_data_qrd5_new[] = {
+ /* T6 Object */
+ 0, 0, 0, 0, 0, 0,
+ /* T38 Object */
+ 25, 0, 4, 0, 0, 0, 0, 0,
+ /* T7 Object */
+ 24, 12, 10,
+ /* T8 Object */
+ 30, 0, 5, 5, 0, 0, 0, 0, 10, 192,
+ /* T9 Object */
+ 131, 0, 0, 18, 11, 0, 16, 70, 2, 3,
+ 0, 2, 1, 62, 10, 10, 10, 10, 107, 3,
+ 223, 1, 2, 2, 20, 20, 172, 40, 139, 110,
+ 10, 15, 0, 0, 0,
+ /* T25 Object */
+ 0, 0, 0, 0, 0, 0,
+ /* T42 Object */
+ 3, 20, 45, 40, 128, 0, 0, 0,
+ /* T46 Object */
+ 0, 2, 16, 16, 0, 0, 0, 0, 0,
+ /* T48 Object */
+ 1, 12, 64, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 6, 6, 0, 0, 100, 4, 64,
+ 10, 0, 20, 5, 0, 38, 0, 20, 0, 0,
+ 0, 0, 0, 0, 16, 65, 3, 1, 1, 0,
+ 10, 10, 10, 0, 0, 15, 15, 154, 58, 145,
+ 80, 100, 15, 3,
+ /* T64 Object */
+ 1, 32, 25, 40, 40, 0, 35,
+};
+
+
static struct mxt_config_info mxt_config_array[] = {
{
.config = mxt_config_data,
@@ -349,6 +558,23 @@ static struct mxt_config_info mxt_config_array[] = {
.version = 0x10,
.build = 0xAA,
},
+ {
+ .config = mxt_config_data_qrd5_truly,
+ .config_length = ARRAY_SIZE(mxt_config_data_qrd5_truly),
+ .family_id = 0x81,
+ .variant_id = 0x01,
+ .version = 0x10,
+ .build = 0xAA,
+ },
+ {
+ .config = mxt_config_data_qrd5_new,
+ .config_length = ARRAY_SIZE(mxt_config_data_qrd5_new),
+ .family_id = 0x81,
+ .variant_id = 0x18,
+ .version = 0x10,
+ .build = 0xAA,
+ .fw_name = "mxt224EC25.enc",
+ },
};
static int mxt_key_codes[MXT_KEYARRAY_MAX_KEYS] = {
@@ -369,7 +595,7 @@ static struct mxt_platform_data mxt_platform_data = {
.disp_maxx = 479,
.disp_miny = 0,
.disp_maxy = 799,
- .irqflags = IRQF_TRIGGER_FALLING,
+ .irqflags = IRQF_TRIGGER_LOW,
.i2c_pull_up = true,
.reset_gpio = MXT_TS_RESET_GPIO,
.irq_gpio = MXT_TS_IRQ_GPIO,
@@ -501,6 +727,90 @@ static int synaptics_touchpad_setup(void)
return retval;
}
#endif
+#ifdef CONFIG_TOUCHSCREEN_FOCAL
+struct virtual_key{
+ const char *menu;
+ const char *home;
+ const char *back;
+ const char *search;
+};
+
+struct tp_platform_data{
+ struct kobj_attribute byd_virtual_keys_attr;
+ const char *input_dev_name;
+ // [sun.yu5@byd.com, modify,WG703T2_C000133,support 2 touchscreen, define struct virtual_key vk from 1 to 2]
+ struct virtual_key vk[2];
+ // [sun.yu5@byd.com, end]
+ int lcd_x;
+ int lcd_y;
+ int tp_x;
+ int tp_y;
+ int irq;
+ int wakeup;
+};
+
+static struct tp_platform_data tp_pdata = {
+ .byd_virtual_keys_attr = {
+ .attr = {
+ .name = "virtualkeys.Focal touch",
+ .mode = S_IRUGO,
+ },
+ },
+ .input_dev_name = "Focal touch",
+ // [sun.yu5@byd.com, modify,WG703T2_C000133,support 2 touchscreen, define struct virtual_key vk from 1 to 2]
+ .vk[0]={
+ .menu = "60:1009:50:50",
+ .home = "180:1009:50:50",
+ .back = "300:1009:50:50",
+ .search = "420:1009:50:50",
+ },
+ .vk[1]={
+ .menu = "70:850:50:50",
+ .home = "195:850:50:50",
+ .back = "310:850:50:50",
+ .search = "435:850:50:50",
+ },
+ // [sun.yu5@byd.com, end]
+ .lcd_x = 540,
+ .lcd_y = 960,
+ .tp_x = 540,
+ .tp_y = 960,
+ .irq = 48,
+ .wakeup = 26,
+};
+
+static struct i2c_board_info focal_ts_i2c_info[] __initdata = {
+ {
+ I2C_BOARD_INFO("focal_ts", 0x38),
+ .irq = MSM_GPIO_TO_INT(48),
+ .platform_data = &tp_pdata,
+ },
+};
+#endif
+
+#ifdef CONFIG_TOUCHSCREEN_FT6306
+static struct ft6306_touch_platform_data ft6306_pdata ={
+
+ .maxx = 480,
+ .maxy = 800,
+ .reset = 26,
+ .irq = 48,
+
+ };
+
+void *ft6306_platform_data(void *info)
+{
+ return &ft6306_pdata;
+}
+
+static struct i2c_board_info ft6306_touch_i2c_info[] __initdata = {
+ {
+ I2C_BOARD_INFO("ft6306_touch", 0x38),
+ .irq = MSM_GPIO_TO_INT(48),
+ .platform_data = &ft6306_pdata,
+ },
+};
+#endif
static struct regulator_bulk_data regs_atmel[] = {
{ .supply = "ldo12", .min_uV = 2700000, .max_uV = 3300000 },
@@ -640,32 +950,43 @@ static struct platform_device hs_pdev = {
#define FT5X06_IRQ_GPIO 48
#define FT5X06_RESET_GPIO 26
-#define FT5X16_IRQ_GPIO 122
+#define FT5X06_IRQ_GPIO_QPR_SKUD 121
+#define FT5X06_RESET_GPIO_QPR_SKUD 26
+
+#define FT5X06_IRQ_GPIO_QPR_SKUD_PRIM 122
+#define FT5X06_RESET_GPIO_QPR_SKUD_PRIM 26
+
#define FT5X16_IRQ_GPIO_EVBD 115
-#define FT5X16_IRQ_GPIO_SKUD 121
+
+#define FT5X06_IRQ_GPIO_QPR_SKUE 121
+#define FT5X06_RESET_GPIO_QPR_SKUE 26
static ssize_t
ft5x06_virtual_keys_register(struct kobject *kobj,
struct kobj_attribute *attr,
char *buf)
{
- return snprintf(buf, 200,
- __stringify(EV_KEY) ":" __stringify(KEY_MENU) ":40:510:80:60"
- ":" __stringify(EV_KEY) ":" __stringify(KEY_HOME) ":120:510:80:60"
- ":" __stringify(EV_KEY) ":" __stringify(KEY_SEARCH) ":200:510:80:60"
- ":" __stringify(EV_KEY) ":" __stringify(KEY_BACK) ":280:510:80:60"
- "\n");
-}
-
-static ssize_t ft5x16_virtual_keys_register(struct kobject *kobj,
- struct kobj_attribute *attr, char *buf)
-{
- return snprintf(buf, 200, \
- __stringify(EV_KEY) ":" __stringify(KEY_HOME) ":68:992:135:64" \
- ":" __stringify(EV_KEY) ":" __stringify(KEY_MENU) ":203:992:135:64" \
- ":" __stringify(EV_KEY) ":" __stringify(KEY_BACK) ":338:992:135:64" \
- ":" __stringify(EV_KEY) ":" __stringify(KEY_SEARCH) ":473:992:135:64" \
- "\n");
+ if (machine_is_msm8625q_skud() || machine_is_msm8625q_evbd()) {
+ return snprintf(buf, 200,
+ __stringify(EV_KEY) ":" __stringify(KEY_HOME) ":67:1000:135:60"
+ ":" __stringify(EV_KEY) ":" __stringify(KEY_MENU) ":202:1000:135:60"
+ ":" __stringify(EV_KEY) ":" __stringify(KEY_BACK) ":337:1000:135:60"
+ ":" __stringify(EV_KEY) ":" __stringify(KEY_SEARCH) ":472:1000:135:60"
+ "\n");
+ } if (machine_is_msm8625q_skue()) {
+ return snprintf(buf, 200,
+ __stringify(EV_KEY) ":" __stringify(KEY_MENU) ":90:1020:170:40"
+ ":" __stringify(EV_KEY) ":" __stringify(KEY_HOME) ":270:1020:170:40"
+ ":" __stringify(EV_KEY) ":" __stringify(KEY_BACK) ":450:1020:170:40"
+ "\n");
+ } else {
+ return snprintf(buf, 200,
+ __stringify(EV_KEY) ":" __stringify(KEY_MENU) ":40:510:80:60"
+ ":" __stringify(EV_KEY) ":" __stringify(KEY_HOME) ":120:510:80:60"
+ ":" __stringify(EV_KEY) ":" __stringify(KEY_SEARCH) ":200:510:80:60"
+ ":" __stringify(EV_KEY) ":" __stringify(KEY_BACK) ":280:510:80:60"
+ "\n");
+ }
}
static struct kobj_attribute ft5x06_virtual_keys_attr = {
@@ -687,12 +1008,47 @@ static struct attribute_group ft5x06_virtual_key_properties_attr_group = {
struct kobject *ft5x06_virtual_key_properties_kobj;
+static struct regulator_bulk_data regs_ft5x06[] = {
+ { .supply = "ldo12", .min_uV = 2700000, .max_uV = 3300000 },
+ { .supply = "smps3", .min_uV = 1800000, .max_uV = 1800000 },
+};
+
+static int ft5x06_ts_power_on(bool on)
+{
+ int rc;
+
+ rc = regulator_bulk_get(NULL, ARRAY_SIZE(regs_ft5x06), regs_ft5x06);
+ if (rc) {
+ printk("%s: could not get regulators: %d\n",
+ __func__, rc);
+ }
+
+ rc = regulator_bulk_set_voltage(ARRAY_SIZE(regs_ft5x06), regs_ft5x06);
+ if (rc) {
+ printk("%s: could not set voltages: %d\n",
+ __func__, rc);
+ }
+
+ rc = on ?
+ regulator_bulk_enable(ARRAY_SIZE(regs_ft5x06), regs_ft5x06) :
+ regulator_bulk_disable(ARRAY_SIZE(regs_ft5x06), regs_ft5x06);
+
+ if (rc)
+ pr_err("%s: could not %sable regulators: %d\n",
+ __func__, on ? "en" : "dis", rc);
+ else
+ msleep(50);
+
+ return rc;
+}
+
static struct ft5x06_ts_platform_data ft5x06_platformdata = {
.x_max = 320,
.y_max = 480,
.reset_gpio = FT5X06_RESET_GPIO,
.irq_gpio = FT5X06_IRQ_GPIO,
.irqflags = IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
+ .power_on = ft5x06_ts_power_on,
};
static struct i2c_board_info ft5x06_device_info[] __initdata = {
@@ -706,54 +1062,48 @@ static struct i2c_board_info ft5x06_device_info[] __initdata = {
static void __init ft5x06_touchpad_setup(void)
{
int rc;
- int irq_gpio;
-
- if (machine_is_qrd_skud_prime()) {
- irq_gpio = FT5X16_IRQ_GPIO;
-
- ft5x06_platformdata.x_max = 540;
- ft5x06_platformdata.y_max = 960;
- ft5x06_platformdata.irq_gpio = FT5X16_IRQ_GPIO;
-
- ft5x06_device_info[0].irq = MSM_GPIO_TO_INT(FT5X16_IRQ_GPIO);
- ft5x06_virtual_keys_attr.show = &ft5x16_virtual_keys_register;
+ if (machine_is_msm8625q_skud()) {
+ if (cpu_is_msm8625()) {
+ ft5x06_platformdata.irq_gpio = FT5X06_IRQ_GPIO_QPR_SKUD_PRIM;
+ ft5x06_platformdata.reset_gpio = FT5X06_RESET_GPIO_QPR_SKUD_PRIM;
+ ft5x06_platformdata.x_max = 540;
+ ft5x06_platformdata.y_max = 960;
+ ft5x06_device_info[0].irq = MSM_GPIO_TO_INT(FT5X06_IRQ_GPIO_QPR_SKUD_PRIM);
+ } else {
+ ft5x06_platformdata.irq_gpio = FT5X06_IRQ_GPIO_QPR_SKUD;
+ ft5x06_platformdata.reset_gpio = FT5X06_RESET_GPIO_QPR_SKUD;
+ ft5x06_platformdata.x_max = 540;
+ ft5x06_platformdata.y_max = 960;
+ ft5x06_device_info[0].irq = MSM_GPIO_TO_INT(FT5X06_IRQ_GPIO_QPR_SKUD);
+ }
} else if(machine_is_msm8625q_evbd()) {
- irq_gpio = FT5X16_IRQ_GPIO_EVBD;
-
+ ft5x06_platformdata.irq_gpio = FT5X16_IRQ_GPIO_EVBD;
+ ft5x06_platformdata.reset_gpio = FT5X06_RESET_GPIO;
ft5x06_platformdata.x_max = 540;
ft5x06_platformdata.y_max = 960;
- ft5x06_platformdata.irq_gpio = FT5X16_IRQ_GPIO_EVBD;
-
ft5x06_device_info[0].irq = MSM_GPIO_TO_INT(FT5X16_IRQ_GPIO_EVBD);
-
- ft5x06_virtual_keys_attr.show = &ft5x16_virtual_keys_register;
- } else if(machine_is_msm8625q_skud()) {
- irq_gpio = FT5X16_IRQ_GPIO_SKUD;
-
+ } else if (machine_is_msm8625q_skue()) {
+ ft5x06_platformdata.irq_gpio = FT5X06_IRQ_GPIO_QPR_SKUE;
+ ft5x06_platformdata.reset_gpio = FT5X06_RESET_GPIO_QPR_SKUE;
ft5x06_platformdata.x_max = 540;
ft5x06_platformdata.y_max = 960;
- ft5x06_platformdata.irq_gpio = FT5X16_IRQ_GPIO_SKUD;
-
- ft5x06_device_info[0].irq = MSM_GPIO_TO_INT(FT5X16_IRQ_GPIO_SKUD);
-
- ft5x06_virtual_keys_attr.show = &ft5x16_virtual_keys_register;
- } else
- irq_gpio = FT5X06_IRQ_GPIO;
+ ft5x06_device_info[0].irq = MSM_GPIO_TO_INT(FT5X06_IRQ_GPIO_QPR_SKUE);
+ }
- rc = gpio_tlmm_config(GPIO_CFG(irq_gpio, 0,
+ rc = gpio_tlmm_config(GPIO_CFG(ft5x06_platformdata.irq_gpio, 0,
GPIO_CFG_INPUT, GPIO_CFG_PULL_UP,
GPIO_CFG_8MA), GPIO_CFG_ENABLE);
if (rc)
pr_err("%s: gpio_tlmm_config for %d failed\n",
- __func__, irq_gpio);
+ __func__, ft5x06_platformdata.irq_gpio);
- rc = gpio_tlmm_config(GPIO_CFG(FT5X06_RESET_GPIO, 0,
+ rc = gpio_tlmm_config(GPIO_CFG(ft5x06_platformdata.reset_gpio, 0,
GPIO_CFG_OUTPUT, GPIO_CFG_PULL_DOWN,
GPIO_CFG_8MA), GPIO_CFG_ENABLE);
if (rc)
pr_err("%s: gpio_tlmm_config for %d failed\n",
- __func__, FT5X06_RESET_GPIO);
+ __func__, ft5x06_platformdata.reset_gpio);
ft5x06_virtual_key_properties_kobj =
kobject_create_and_add("board_properties", NULL);
@@ -770,66 +1120,173 @@ static void __init ft5x06_touchpad_setup(void)
ARRAY_SIZE(ft5x06_device_info));
}
-/* SKU3/SKU7 keypad device information */
-#define KP_INDEX_SKU3(row, col) ((row)*ARRAY_SIZE(kp_col_gpios_sku3) + (col))
-static unsigned int kp_row_gpios_sku3[] = {31, 32};
-static unsigned int kp_col_gpios_sku3[] = {36, 37};
+/* skud flash led and touch*/
+#define FLASH_LED_SKUD 34
+#define FLASH_LED_TORCH_SKUD 48
-static const unsigned short keymap_sku3[] = {
- [KP_INDEX_SKU3(0, 0)] = KEY_VOLUMEUP,
- [KP_INDEX_SKU3(0, 1)] = KEY_VOLUMEDOWN,
- [KP_INDEX_SKU3(1, 1)] = KEY_CAMERA,
+static struct gpio_led gpio_flash_config_skud[] = {
+ {
+ .name = "flashlight",
+ .gpio = FLASH_LED_SKUD,
+ },
+ {
+ .name = "torch",
+ .gpio = FLASH_LED_TORCH_SKUD,
+ },
};
-static unsigned int kp_row_gpios_skud[] = {31, 32};
-static unsigned int kp_col_gpios_skud[] = {37};
+static struct gpio_led_platform_data gpio_flash_pdata_skud = {
+ .num_leds = ARRAY_SIZE(gpio_flash_config_skud),
+ .leds = gpio_flash_config_skud,
+};
+
+static struct platform_device gpio_flash_skud = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &gpio_flash_pdata_skud,
+ },
+};
+/* end of skud flash led and touch*/
+
+/* skue flash led*/
+#define FLASH_LED_SKUE 34
+
+static struct gpio_led gpio_flash_config_skue[] = {
+ {
+ .name = "flashlight",
+ .gpio = FLASH_LED_SKUE,
+ },
+};
+
+static struct gpio_led_platform_data gpio_flash_pdata_skue = {
+ .num_leds = ARRAY_SIZE(gpio_flash_config_skue),
+ .leds = gpio_flash_config_skue,
+};
+
+static struct platform_device gpio_flash_skue = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &gpio_flash_pdata_skue,
+ },
+};
+/* end of skue flash led*/
+
+
+#ifdef CONFIG_LEDS_TRICOLOR_FLAHSLIGHT
+
+#define LED_FLASH_EN1 13
+#define QRD7_LED_FLASH_EN 96
+
+static struct msm_gpio tricolor_leds_gpio_cfg_data[] = {
+{
+ GPIO_CFG(-1, 0, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA),
+ "flashlight"},
+};
+
+static int tricolor_leds_gpio_setup(void) {
+ int ret = 0;
+ if(machine_is_msm8625_qrd5() || machine_is_msm7x27a_qrd5a())
+ {
+ tricolor_leds_gpio_cfg_data[0].gpio_cfg = GPIO_CFG(LED_FLASH_EN1, 0, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA);
+ }
+ else if(machine_is_msm8625_qrd7())
+ {
+ tricolor_leds_gpio_cfg_data[0].gpio_cfg = GPIO_CFG(QRD7_LED_FLASH_EN, 0, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA);
+ }
+
+ ret = msm_gpios_request_enable(tricolor_leds_gpio_cfg_data,
+ sizeof(tricolor_leds_gpio_cfg_data)/sizeof(struct msm_gpio));
+ if( ret<0 )
+ printk(KERN_ERR "%s: Failed to obtain tricolor_leds GPIO . Code: %d\n",
+ __func__, ret);
+ return ret;
+}
+
+
+static struct platform_device msm_device_tricolor_leds = {
+ .name = "tricolor leds and flashlight",
+ .id = -1,
+};
+#endif
+/* SKU3/SKU7 keypad device information */
+#define KP_INDEX_SKU3(row, col) ((row)*ARRAY_SIZE(kp_col_gpios_qrd3) + (col))
+static unsigned int kp_row_gpios_qrd3[] = {31, 32};
+static unsigned int kp_col_gpios_qrd3[] = {36, 37};
static unsigned int kp_row_gpios_evbdp[] = {42, 37};
static unsigned int kp_col_gpios_evbdp[] = {31};
-static const unsigned short keymap_skud[] = {
+static const unsigned short keymap_qrd3[] = {
[KP_INDEX_SKU3(0, 0)] = KEY_VOLUMEUP,
[KP_INDEX_SKU3(0, 1)] = KEY_VOLUMEDOWN,
+ [KP_INDEX_SKU3(1, 1)] = KEY_CAMERA,
};
-
-static struct gpio_event_matrix_info kp_matrix_info_sku3 = {
+static struct gpio_event_matrix_info kp_matrix_info_qrd3 = {
.info.func = gpio_event_matrix_func,
- .keymap = keymap_sku3,
- .output_gpios = kp_row_gpios_sku3,
- .input_gpios = kp_col_gpios_sku3,
- .noutputs = ARRAY_SIZE(kp_row_gpios_sku3),
- .ninputs = ARRAY_SIZE(kp_col_gpios_sku3),
+ .keymap = keymap_qrd3,
+ .output_gpios = kp_row_gpios_qrd3,
+ .input_gpios = kp_col_gpios_qrd3,
+ .noutputs = ARRAY_SIZE(kp_row_gpios_qrd3),
+ .ninputs = ARRAY_SIZE(kp_col_gpios_qrd3),
.settle_time.tv64 = 40 * NSEC_PER_USEC,
.poll_time.tv64 = 20 * NSEC_PER_MSEC,
.flags = GPIOKPF_LEVEL_TRIGGERED_IRQ | GPIOKPF_DRIVE_INACTIVE |
GPIOKPF_PRINT_UNMAPPED_KEYS,
};
-static struct gpio_event_info *kp_info_sku3[] = {
- &kp_matrix_info_sku3.info,
+static struct gpio_event_info *kp_info_qrd3[] = {
+ &kp_matrix_info_qrd3.info,
};
-static struct gpio_event_platform_data kp_pdata_sku3 = {
+static struct gpio_event_platform_data kp_pdata_qrd3 = {
.name = "7x27a_kp",
- .info = kp_info_sku3,
- .info_count = ARRAY_SIZE(kp_info_sku3)
+ .info = kp_info_qrd3,
+ .info_count = ARRAY_SIZE(kp_info_qrd3)
};
-static struct platform_device kp_pdev_sku3 = {
+static struct platform_device kp_pdev_qrd3 = {
.name = GPIO_EVENT_DEV_NAME,
.id = -1,
.dev = {
- .platform_data = &kp_pdata_sku3,
+ .platform_data = &kp_pdata_qrd3,
},
};
-static struct led_info ctp_backlight_info = {
- .name = "button-backlight",
- .flags = PM_MPP__I_SINK__LEVEL_40mA << 16 | PM_MPP_7,
+static struct pmic8029_led_platform_data leds_data_skud[] = {
+ {
+ .name = "button-backlight",
+ .which = PM_MPP_8,
+ .type = PMIC8029_DRV_TYPE_CUR,
+ .max.cur = PM_MPP__I_SINK__LEVEL_5mA,
+ },
+};
+
+static struct pmic8029_leds_platform_data pmic8029_leds_pdata_skud = {
+ .leds = leds_data_skud,
+ .num_leds = 1,
+};
+
+static struct platform_device pmic_mpp_leds_pdev_skud = {
+ .name = "pmic-mpp-leds",
+ .id = -1,
+ .dev = {
+ .platform_data = &pmic8029_leds_pdata_skud,
+ },
+};
+
+static struct pmic8029_led_platform_data leds_data[] = {
+ {
+ .name = "button-backlight",
+ .which = PM_MPP_7,
+ .type = PMIC8029_DRV_TYPE_CUR,
+ .max.cur = PM_MPP__I_SINK__LEVEL_40mA,
+ },
};
-static struct led_platform_data ctp_backlight_pdata = {
- .leds = &ctp_backlight_info,
+static struct pmic8029_leds_platform_data pmic8029_leds_pdata = {
+ .leds = leds_data,
.num_leds = 1,
};
@@ -837,7 +1294,7 @@ static struct platform_device pmic_mpp_leds_pdev = {
.name = "pmic-mpp-leds",
.id = -1,
.dev = {
- .platform_data = &ctp_backlight_pdata,
+ .platform_data = &pmic8029_leds_pdata,
},
};
@@ -879,8 +1336,17 @@ void __init msm7627a_add_io_devices(void)
atmel_ts_i2c_info,
ARRAY_SIZE(atmel_ts_i2c_info));
/* keypad */
- platform_device_register(&kp_pdev);
-
+ platform_device_register(&kp_pdev_8625);
+#ifdef CONFIG_TOUCHSCREEN_FOCAL
+ i2c_register_board_info(MSM_GSBI1_QUP_I2C_BUS_ID,
+ focal_ts_i2c_info,
+ ARRAY_SIZE(focal_ts_i2c_info));
+#endif
+#ifdef CONFIG_TOUCHSCREEN_FT6306
+ i2c_register_board_info(MSM_GSBI1_QUP_I2C_BUS_ID,
+ ft6306_touch_i2c_info,
+ ARRAY_SIZE(ft6306_touch_i2c_info));
+#endif
/* headset */
platform_device_register(&hs_pdev);
@@ -894,9 +1360,9 @@ void __init msm7627a_add_io_devices(void)
platform_device_register(&led_pdev);
/* Vibrator */
- if (machine_is_msm7x27a_ffa() || machine_is_msm7625a_ffa()
- || machine_is_msm8625_ffa())
+#ifdef CONFIG_MSM_RPC_VIBRATOR
msm_init_pmic_vibrator();
+#endif
}
void __init qrd7627a_add_io_devices(void)
@@ -909,17 +1375,25 @@ void __init qrd7627a_add_io_devices(void)
synaptic_i2c_clearpad3k,
ARRAY_SIZE(synaptic_i2c_clearpad3k));
} else if (machine_is_msm7627a_evb() || machine_is_msm8625_evb() ||
- machine_is_msm8625_evt()) {
- /* Use configuration data for EVT */
- if (machine_is_msm8625_evt()) {
- mxt_config_array[0].config = mxt_config_data_evt;
+ machine_is_msm8625_qrd5() || machine_is_msm7x27a_qrd5a()) {
+ /* Use configuration data for sku5 */
+ if (machine_is_msm8625_qrd5()) {
+ mxt_config_array[0].config = mxt_config_data_qrd5;
mxt_config_array[0].config_length =
- ARRAY_SIZE(mxt_config_data_evt);
+ ARRAY_SIZE(mxt_config_data_qrd5);
mxt_platform_data.panel_maxy = 875;
mxt_platform_data.need_calibration = true;
mxt_vkey_setup();
}
+ if (machine_is_msm7x27a_qrd5a()) {
+ mxt_config_array[0].config = mxt_config_data_qrd5a;
+ mxt_config_array[0].config_length =
+ ARRAY_SIZE(mxt_config_data_qrd5a);
+ mxt_platform_data.panel_maxy = 875;
+ mxt_vkey_setup();
+ }
+
rc = gpio_tlmm_config(GPIO_CFG(MXT_TS_IRQ_GPIO, 0,
GPIO_CFG_INPUT, GPIO_CFG_PULL_UP,
GPIO_CFG_8MA), GPIO_CFG_ENABLE);
@@ -940,9 +1414,9 @@ void __init qrd7627a_add_io_devices(void)
mxt_device_info,
ARRAY_SIZE(mxt_device_info));
} else if (machine_is_msm7627a_qrd3() || machine_is_msm8625_qrd7()
- || machine_is_qrd_skud_prime()
|| machine_is_msm8625q_skud()
- || machine_is_msm8625q_evbd()) {
+ || machine_is_msm8625q_evbd()
+ || machine_is_msm8625q_skue()) {
ft5x06_touchpad_setup();
/* evbd+ can support synaptic as well */
if (machine_is_msm8625q_evbd() &&
@@ -1002,9 +1476,7 @@ void __init qrd7627a_add_io_devices(void)
}
}
- /* handset and power key*/
- /* ignore end key as this target doesn't need it */
- hs_platform_data.ignore_end_key = true;
+ /* headset */
platform_device_register(&hs_pdev);
/* vibrator */
@@ -1013,17 +1485,11 @@ void __init qrd7627a_add_io_devices(void)
#endif
/* keypad */
-
- if (machine_is_qrd_skud_prime() || machine_is_msm8625q_evbd()
- || machine_is_msm8625q_skud()) {
- kp_matrix_info_sku3.keymap = keymap_skud;
- kp_matrix_info_sku3.output_gpios = kp_row_gpios_skud;
- kp_matrix_info_sku3.input_gpios = kp_col_gpios_skud;
- kp_matrix_info_sku3.noutputs = ARRAY_SIZE(kp_row_gpios_skud);
- kp_matrix_info_sku3.ninputs = ARRAY_SIZE(kp_col_gpios_skud);
- /* keypad info for EVBD+ */
- if (machine_is_msm8625q_evbd() &&
- (socinfo_get_platform_type() == 0x13)) {
+ if (machine_is_msm8625_qrd5() || machine_is_msm7x27a_qrd5a())
+ kp_matrix_info_8625.keymap = keymap_8625_qrd5;
+ /* keypad info for EVBD+ */
+ if (machine_is_msm8625q_evbd() &&
+ (socinfo_get_platform_type() == 13)) {
gpio_tlmm_config(GPIO_CFG(37, 0,
GPIO_CFG_OUTPUT, GPIO_CFG_PULL_DOWN,
GPIO_CFG_8MA), GPIO_CFG_ENABLE);
@@ -1033,38 +1499,43 @@ void __init qrd7627a_add_io_devices(void)
gpio_tlmm_config(GPIO_CFG(31, 0,
GPIO_CFG_INPUT, GPIO_CFG_PULL_UP,
GPIO_CFG_8MA), GPIO_CFG_ENABLE);
- kp_matrix_info_sku3.output_gpios = kp_row_gpios_evbdp;
- kp_matrix_info_sku3.input_gpios = kp_col_gpios_evbdp;
- kp_matrix_info_sku3.noutputs = ARRAY_SIZE(kp_row_gpios_evbdp);
- kp_matrix_info_sku3.ninputs = ARRAY_SIZE(kp_col_gpios_evbdp);
- }
+ kp_matrix_info_skud.output_gpios = kp_row_gpios_evbdp;
+ kp_matrix_info_skud.input_gpios = kp_col_gpios_evbdp;
+ kp_matrix_info_skud.noutputs = ARRAY_SIZE(kp_row_gpios_evbdp);
+ kp_matrix_info_skud.ninputs = ARRAY_SIZE(kp_col_gpios_evbdp);
}
- if (machine_is_msm8625_evt())
- kp_matrix_info_8625.keymap = keymap_8625_evt;
-
if (machine_is_msm7627a_evb() || machine_is_msm8625_evb() ||
- machine_is_msm8625_evt())
+ machine_is_msm8625_qrd5() || machine_is_msm7x27a_qrd5a())
platform_device_register(&kp_pdev_8625);
- else if (machine_is_msm7627a_qrd3() || machine_is_msm8625_qrd7()
- || machine_is_qrd_skud_prime() || machine_is_msm8625q_evbd()
- || machine_is_msm8625q_skud())
- platform_device_register(&kp_pdev_sku3);
+ else if (machine_is_msm7627a_qrd3() || machine_is_msm8625_qrd7())
+ platform_device_register(&kp_pdev_qrd3);
+ else if (machine_is_msm8625q_skud()||machine_is_msm8625q_evbd())
+ platform_device_register(&kp_pdev_skud);
+ else if (machine_is_msm8625q_skue())
+ platform_device_register(&kp_pdev_skue);
/* leds */
+ if (machine_is_msm7627a_evb() || machine_is_msm8625_evb()
+ || machine_is_msm8625_qrd5() || machine_is_msm7x27a_qrd5a()) {
- if (machine_is_qrd_skud_prime() || machine_is_msm8625q_evbd()
- || machine_is_msm8625q_skud()) {
- ctp_backlight_info.flags =
- PM_MPP__I_SINK__LEVEL_40mA << 16 | PM_MPP_8;
- }
-
- if (machine_is_msm7627a_evb() || machine_is_msm8625_evb() ||
- machine_is_msm8625_evt() || machine_is_qrd_skud_prime()
- || machine_is_msm8625q_evbd() || machine_is_msm8625q_skud())
platform_device_register(&pmic_mpp_leds_pdev);
-
- if (machine_is_msm7627a_evb() || machine_is_msm8625_evb() ||
- machine_is_msm8625_evt() || machine_is_msm8625q_evbd())
platform_device_register(&tricolor_leds_pdev);
+ } else if (machine_is_msm8625q_skud() || machine_is_msm8625q_evbd()) {
+ platform_device_register(&pmic_mpp_leds_pdev_skud);
+ /* enable the skud flash and torch by gpio leds driver */
+ platform_device_register(&gpio_flash_skud);
+ } else if (machine_is_msm8625q_skue()) {
+ /* enable the skue flashlight by gpio leds driver */
+ platform_device_register(&gpio_flash_skue);
+ }
+
+#ifdef CONFIG_LEDS_TRICOLOR_FLAHSLIGHT
+ /*tricolor leds init*/
+ if (machine_is_msm7627a_evb() || machine_is_msm8625_evb()
+ || machine_is_msm8625_qrd5() || machine_is_msm7x27a_qrd5a()) {
+ platform_device_register(&msm_device_tricolor_leds);
+ tricolor_leds_gpio_setup();
+ }
+#endif
}
diff --git a/arch/arm/mach-msm/board-msm7627a-sensor.c b/arch/arm/mach-msm/board-msm7627a-sensor.c
new file mode 100755
index 0000000..e8aa3fa
--- /dev/null
+++ b/arch/arm/mach-msm/board-msm7627a-sensor.c
@@ -0,0 +1,624 @@
+/* Copyright (c) 2012-2013, The Linux Foundation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/gpio.h>
+#include <asm/mach-types.h>
+#include <linux/i2c.h>
+#include <devices-msm7x2xa.h>
+
+#ifdef CONFIG_AVAGO_APDS990X
+#include <linux/input/apds990x.h>
+#endif
+
+#ifdef CONFIG_SENSORS_TMD2771X
+#include <linux/input/tmd2771x.h>
+#endif
+
+#ifdef CONFIG_MPU_SENSORS_MPU3050
+#include <linux/mpu.h>
+#endif
+
+#ifdef CONFIG_INPUT_LTR502
+#include <linux/input/ltr502.h>
+#endif
+
+#ifdef CONFIG_SENSORS_AK8975
+#include <linux/akm8975.h>
+#endif
+
+#ifdef CONFIG_INPUT_LTR558
+#include <linux/input/ltr5xx.h>
+
+#ifndef LTR558_IRQ_GPIO
+#define LTR558_IRQ_GPIO 17
+#endif
+
+#endif /* !CONFIG_INPUT_LTR558 */
+
+#ifdef CONFIG_INPUT_ISL29028
+#include <linux/input/isl29028.h>
+
+#ifndef ISL29028_IRQ_GPIO
+#define ISL29028_IRQ_GPIO 17
+#endif
+
+#endif /* !CONFIG_INPUT_ISL29028 */
+
+#ifdef CONFIG_AVAGO_APDS990X
+#ifndef APDS990X_IRQ_GPIO
+#define APDS990X_IRQ_GPIO 17
+#endif
+
+#ifndef APDS990x_PS_DETECTION_THRESHOLD
+#define APDS990x_PS_DETECTION_THRESHOLD 600
+#endif
+
+#ifndef APDS990x_PS_HSYTERESIS_THRESHOLD
+#define APDS990x_PS_HSYTERESIS_THRESHOLD 500
+#endif
+
+#ifndef APDS990x_ALS_THRESHOLD_HSYTERESIS
+#define APDS990x_ALS_THRESHOLD_HSYTERESIS 20
+#endif
+
+#if defined(CONFIG_INPUT_KXTJ9)
+#include <linux/input/kxtj9.h>
+#endif
+
+static struct msm_gpio apds990x_cfg_data[] = {
+ {GPIO_CFG(APDS990X_IRQ_GPIO, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_UP, GPIO_CFG_6MA),"apds990x_irq"},
+};
+
+static struct apds990x_platform_data apds990x_platformdata = {
+ .irq = MSM_GPIO_TO_INT(APDS990X_IRQ_GPIO),
+ .ps_det_thld = APDS990x_PS_DETECTION_THRESHOLD,
+ .ps_hsyt_thld = APDS990x_PS_HSYTERESIS_THRESHOLD,
+ .als_hsyt_thld = APDS990x_ALS_THRESHOLD_HSYTERESIS,
+};
+
+static struct i2c_board_info i2c_info_apds990x = {
+ I2C_BOARD_INFO("apds990x", 0x39),
+ .platform_data = &apds990x_platformdata,
+};
+
+static int apds990x_setup(void)
+{
+ int retval = 0;
+
+ retval = msm_gpios_request_enable(apds990x_cfg_data, sizeof(apds990x_cfg_data)/sizeof(struct msm_gpio));
+ if(retval) {
+ printk(KERN_ERR "%s: Failed to obtain L/P sensor interrupt. Code: %d.", __func__, retval);
+ }
+
+ i2c_register_board_info(MSM_GSBI1_QUP_I2C_BUS_ID,
+ &i2c_info_apds990x, 1);
+
+ return retval;
+}
+#endif
+
+#ifdef CONFIG_SENSORS_TMD2771X
+#ifndef TMD2771X_IRQ_GPIO
+#define TMD2771X_IRQ_GPIO 17
+#endif
+
+#ifndef TMD2771X_PS_DETECTION_THRESHOLD
+#define TMD2771X_PS_DETECTION_THRESHOLD 600
+#endif
+
+#ifndef TMD2771X_PS_HSYTERESIS_THRESHOLD
+#define TMD2771X_PS_HSYTERESIS_THRESHOLD 500
+#endif
+
+#ifndef TMD2771X_ALS_THRESHOLD_HSYTERESIS
+#define TMD2771X_ALS_THRESHOLD_HSYTERESIS 20
+#endif
+
+#if defined(CONFIG_INPUT_KXTJ9)
+#include <linux/input/kxtj9.h>
+#endif
+
+static struct msm_gpio tmd2771x_cfg_data[] = {
+ {GPIO_CFG(TMD2771X_IRQ_GPIO, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_UP, GPIO_CFG_6MA),"tmd2771x_irq"},
+};
+
+static struct tmd2771x_platform_data tmd2771x_platformdata = {
+ .irq = MSM_GPIO_TO_INT(TMD2771X_IRQ_GPIO),
+ .ps_det_thld = TMD2771X_PS_DETECTION_THRESHOLD,
+ .ps_hsyt_thld = TMD2771X_PS_HSYTERESIS_THRESHOLD,
+ .als_hsyt_thld = TMD2771X_ALS_THRESHOLD_HSYTERESIS,
+};
+
+static struct i2c_board_info i2c_info_tmd2771x = {
+ I2C_BOARD_INFO("tmd2771x", 0x39),
+ .platform_data = &tmd2771x_platformdata,
+};
+
+static int tmd2771x_setup(void)
+{
+ int retval = 0;
+ int irbi;
+ retval = msm_gpios_request_enable(tmd2771x_cfg_data, sizeof(tmd2771x_cfg_data)/sizeof(struct msm_gpio));
+ if(retval) {
+ printk(KERN_ERR "%s: Failed to obtain L/P sensor interrupt. Code: %d.", __func__, retval);
+ }
+
+ irbi = i2c_register_board_info(MSM_GSBI1_QUP_I2C_BUS_ID,
+ &i2c_info_tmd2771x, 1);
+ return retval;
+}
+#endif
+
+#ifdef CONFIG_MPU_SENSORS_MPU3050
+
+#define GPIO_ACC_INT 28
+#define GPIO_GYRO_INT 27
+
+/* gyro x and z axis invert for EVB*/
+static struct mpu_platform_data mpu3050_data = {
+ .int_config = 0x10,
+ .orientation = { -1, 0, 0,
+ 0, 1, 0,
+ 0, 0, -1 },
+};
+
+/* accel x and z axis invert for EVB */
+static struct ext_slave_platform_data inv_mpu_bma250_data = {
+ .bus = EXT_SLAVE_BUS_SECONDARY,
+ .orientation = { -1, 0, 0,
+ 0, 1, 0,
+ 0, 0, -1 },
+};
+/* compass */
+static struct ext_slave_platform_data inv_mpu_mmc328xms_data = {
+ .bus = EXT_SLAVE_BUS_PRIMARY,
+ .orientation = { -1, 0, 0,
+ 0, 1, 0,
+ 0, 0, 1 },
+};
+
+/* gyro x and z axis invert for EVT*/
+static struct mpu_platform_data mpu3050_data_qrd5 = {
+ .int_config = 0x10,
+ .orientation = { 1, 0, 0,
+ 0, 1, 0,
+ 0, 0, 1 },
+};
+
+/* accel x and z axis invert for EVT */
+static struct ext_slave_platform_data inv_mpu_bma250_data_qrd5 = {
+ .bus = EXT_SLAVE_BUS_SECONDARY,
+ .orientation = { 1, 0, 0,
+ 0, 1, 0,
+ 0, 0, 1 },
+};
+/* compass for EVT */
+static struct ext_slave_platform_data inv_mpu_mmc328xms_data_qrd5 = {
+ .bus = EXT_SLAVE_BUS_PRIMARY,
+ .orientation = { 1, 0, 0,
+ 0, 1, 0,
+ 0, 0, -1 },
+};
+
+static struct i2c_board_info __initdata mpu3050_boardinfo[] = {
+ {
+ I2C_BOARD_INFO("mpu3050", 0x68),
+ .irq = MSM_GPIO_TO_INT(GPIO_GYRO_INT),
+ .platform_data = &mpu3050_data,
+ },
+ {
+ I2C_BOARD_INFO("bma250", 0x18),
+ .irq = MSM_GPIO_TO_INT(GPIO_ACC_INT),
+ .platform_data = &inv_mpu_bma250_data,
+ },
+ {
+ I2C_BOARD_INFO("mmc328xms", 0x30),
+ //.irq = (IH_GPIO_BASE + COMPASS_IRQ_GPIO),
+ .platform_data = &inv_mpu_mmc328xms_data,
+ },
+};
+
+static struct i2c_board_info __initdata mpu3050_boardinfo_qrd5[] = {
+ {
+ I2C_BOARD_INFO("mpu3050", 0x68),
+ .irq = MSM_GPIO_TO_INT(GPIO_GYRO_INT),
+ .platform_data = &mpu3050_data_qrd5,
+ },
+ {
+ I2C_BOARD_INFO("bma250", 0x18),
+ .irq = MSM_GPIO_TO_INT(GPIO_ACC_INT),
+ .platform_data = &inv_mpu_bma250_data_qrd5,
+ },
+ {
+ I2C_BOARD_INFO("mmc328xms", 0x30),
+ //.irq = (IH_GPIO_BASE + COMPASS_IRQ_GPIO),
+ .platform_data = &inv_mpu_mmc328xms_data_qrd5,
+ },
+};
+
+static struct msm_gpio mpu3050_gpio_cfg_data[] = {
+ { GPIO_CFG(GPIO_GYRO_INT, 0, GPIO_CFG_INPUT, GPIO_CFG_NO_PULL, GPIO_CFG_6MA),
+ "mpu3050_gyroint" },
+ { GPIO_CFG(GPIO_ACC_INT, 0, GPIO_CFG_INPUT, GPIO_CFG_NO_PULL, GPIO_CFG_6MA),
+ "mpu3050_accint" },
+};
+
+static int mpu3050_gpio_setup(void) {
+ int ret = 0;
+ ret = msm_gpios_request_enable(mpu3050_gpio_cfg_data,
+ sizeof(mpu3050_gpio_cfg_data)/sizeof(struct msm_gpio));
+ if( ret<0 )
+ printk(KERN_ERR "Failed to obtain mpu3050 int GPIO!\n");
+ else
+ printk("mpu3050 int GPIO request!\n");
+ if(machine_is_msm8625_qrd5() || machine_is_msm7x27a_qrd5a() ) {
+ if (ARRAY_SIZE(mpu3050_boardinfo_qrd5))
+ i2c_register_board_info(MSM_GSBI1_QUP_I2C_BUS_ID,
+ mpu3050_boardinfo_qrd5,
+ ARRAY_SIZE(mpu3050_boardinfo_qrd5));
+ } else {
+ if (ARRAY_SIZE(mpu3050_boardinfo))
+ i2c_register_board_info(MSM_GSBI1_QUP_I2C_BUS_ID,
+ mpu3050_boardinfo,
+ ARRAY_SIZE(mpu3050_boardinfo));
+ }
+ printk("i2c_register_board_info for MPU3050\n");
+
+ return ret;
+}
+#endif
+
+#ifdef CONFIG_BOSCH_BMA250
+static struct i2c_board_info bma250_i2c_info[] __initdata = {
+ {
+ I2C_BOARD_INFO("bma250", 0x18),
+ },
+};
+#endif
+
+#ifdef CONFIG_INPUT_ISL29028
+static struct isl29028_platform_data isl29028_pdata = {
+ .int_gpio = MSM_GPIO_TO_INT(ISL29028_IRQ_GPIO),
+};
+
+/* ISL29028 BUS0 ID 0x44 */
+static struct i2c_board_info isl29028_i2c_info[] __initdata = {
+ {
+ I2C_BOARD_INFO("isl29028", 0x44),
+ .platform_data = &isl29028_pdata
+ },
+};
+
+static struct msm_gpio isl29028_gpio_cfg_data[] = {
+ {GPIO_CFG(ISL29028_IRQ_GPIO, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_UP, GPIO_CFG_6MA), "isl29028_ALS_PS_int"},
+};
+
+static int isl29028_gpio_setup(void) {
+ int ret = 0;
+ ret = msm_gpios_request_enable(isl29028_gpio_cfg_data, 1);
+ if(ret < 0)
+ printk(KERN_ERR "%s: Failed to obtain acc int GPIO %d. Code: %d\n",
+ __func__, isl29028_pdata.int_gpio, ret);
+
+ return ret;
+}
+
+#endif
+
+#ifdef CONFIG_INPUT_LTR558
+static struct ltr5xx_platform_data ltr558_pdata = {
+ .int_gpio = MSM_GPIO_TO_INT(LTR558_IRQ_GPIO),
+};
+
+/* LTR558 BUS ID 0x23 */
+static struct i2c_board_info ltr558_i2c_info[] __initdata = {
+ {
+ I2C_BOARD_INFO("ltr558", 0x23),
+ .platform_data = &ltr558_pdata
+ },
+};
+
+static struct msm_gpio ltr558_gpio_cfg_data[] = {
+ {GPIO_CFG(LTR558_IRQ_GPIO, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_UP, GPIO_CFG_6MA), "ltr558_ALS_PS_int"},
+};
+
+static int ltr558_gpio_setup(void) {
+ int ret = 0;
+ ret = msm_gpios_request_enable(ltr558_gpio_cfg_data, 1);
+ if(ret < 0)
+ printk(KERN_ERR "%s: Failed to obtain acc int GPIO %d. Code: %d\n",
+ __func__, ltr558_pdata.int_gpio, ret);
+
+ return ret;
+}
+
+#endif /* !CONFIG_INPUT_LTR558 */
+
+#if defined(CONFIG_I2C) && defined(CONFIG_INPUT_LTR502)
+
+static struct ltr502_platform_data ltr502_pdata = {
+ .int_gpio = -1,
+};
+
+static struct i2c_board_info ltr502_light_i2c_info[] __initdata = {
+ {
+ I2C_BOARD_INFO("ltr502", 0x1c),
+ .platform_data = &ltr502_pdata,
+ },
+};
+
+static struct msm_gpio ltr502_light_gpio_cfg_data[] = {
+ {GPIO_CFG(-1, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_UP, GPIO_CFG_6MA), "ltr502_light_int"},
+};
+
+static int ltr502_light_gpio_setup(void) {
+ int ret = 0;
+ ltr502_pdata.int_gpio = 17;
+ ltr502_light_gpio_cfg_data[0].gpio_cfg =
+ GPIO_CFG(ltr502_pdata.int_gpio, 0,
+ GPIO_CFG_INPUT, GPIO_CFG_PULL_UP, GPIO_CFG_6MA);
+ ret = msm_gpios_request_enable(ltr502_light_gpio_cfg_data, 1);
+ if(ret < 0)
+ printk(KERN_ERR "%s: Failed to obtain acc int GPIO %d. Code: %d\n",
+ __func__, ltr502_pdata.int_gpio, ret);
+
+ return ret;
+}
+#endif
+
+#ifdef CONFIG_INPUT_LIS3DH
+
+#define GPIO_ACC_INT 28
+
+static struct i2c_board_info lis3dh_acc_i2c_info[] __initdata = {
+ {
+ I2C_BOARD_INFO("lis3dh", 0x19),
+ .irq = -1,
+ },
+};
+
+static struct msm_gpio lis3dh_acc_gpio_cfg_data[] = {
+ {
+ GPIO_CFG(GPIO_ACC_INT, 0, GPIO_CFG_INPUT, GPIO_CFG_NO_PULL, GPIO_CFG_6MA),
+ "lis3dh_acc_int"
+ },
+};
+
+static int lis3dh_acc_gpio_setup(void) {
+ int ret = 0;
+ ret = msm_gpios_request_enable(lis3dh_acc_gpio_cfg_data,
+ sizeof(lis3dh_acc_gpio_cfg_data)/sizeof(struct msm_gpio));
+ if( ret<0 )
+ printk(KERN_ERR "%s: Failed to obtain acc int GPIO %d. Code: %d\n",
+ __func__, GPIO_ACC_INT, ret);
+ //lis3dh_acc_i2c_info[0].irq = gpio_to_irq(GPIO_ACC_INT);
+ return ret;
+}
+#endif
+
+#ifdef CONFIG_SENSORS_AK8975
+
+static struct msm_gpio akm_gpio_cfg_data[] = {
+ {
+ GPIO_CFG(-1, 0, GPIO_CFG_INPUT, GPIO_CFG_NO_PULL, GPIO_CFG_6MA),
+ "akm_int"
+ },
+};
+
+static int akm_gpio_setup(void) {
+ int ret = 0;
+ akm_gpio_cfg_data[0].gpio_cfg =
+ GPIO_CFG(18, 0,
+ GPIO_CFG_INPUT, GPIO_CFG_NO_PULL, GPIO_CFG_6MA);
+ ret = msm_gpios_request_enable(akm_gpio_cfg_data,
+ sizeof(akm_gpio_cfg_data)/sizeof(struct msm_gpio));
+ return ret;
+}
+
+static struct akm8975_platform_data akm_platform_data_8975 = {
+ .gpio_DRDY = -1,
+};
+
+static struct i2c_board_info akm8975_i2c_info[] __initdata = {
+ {
+ I2C_BOARD_INFO("akm8975", 0x0e),
+ .platform_data = &akm_platform_data_8975,
+ .flags = I2C_CLIENT_WAKE,
+ .irq = -1,//MSM_GPIO_TO_INT(GPIO_COMPASS_DRDY_INDEX),
+ },
+};
+#endif
+
+#if defined(CONFIG_INPUT_KXTJ9)
+#define KXTJ9_DEVICE_MAP 7
+#define KXTJ9_MAP_X ((KXTJ9_DEVICE_MAP-1)%2)
+#define KXTJ9_MAP_Y (KXTJ9_DEVICE_MAP%2)
+#define KXTJ9_NEG_X (((KXTJ9_DEVICE_MAP+1)/2)%2)
+#define KXTJ9_NEG_Y (((KXTJ9_DEVICE_MAP+5)/4)%2)
+#define KXTJ9_NEG_Z ((KXTJ9_DEVICE_MAP-1)/4)
+
+struct kxtj9_platform_data kxtj9_pdata = {
+ .min_interval = 5,
+ .poll_interval = 200,
+
+ .axis_map_x = KXTJ9_MAP_X,
+ .axis_map_y = KXTJ9_MAP_Y,
+ .axis_map_z = 2,
+
+ .negate_x = KXTJ9_NEG_X,
+ .negate_y = KXTJ9_NEG_Y,
+ .negate_z = KXTJ9_NEG_Z,
+
+ .res_12bit = RES_12BIT,
+ .g_range = KXTJ9_G_2G,
+};
+
+static struct i2c_board_info accel_kxtj9_i2c_info[] __initdata = {
+ {
+ I2C_BOARD_INFO("kxtik", 0x0F),
+ .platform_data = &kxtj9_pdata,
+ },
+};
+#endif // CONFIG_INPUT_KXTJ9
+
+//pjn add for gsensor
+#if defined(CONFIG_SENSORS_BMA2X2)
+#define GPIO_ACC_INT 28
+
+static struct msm_gpio bma2x2_gpio_cfg_data[] = {
+ { GPIO_CFG(GPIO_ACC_INT, 0, GPIO_CFG_INPUT, GPIO_CFG_NO_PULL, GPIO_CFG_6MA),
+ "bma2x2_int" },
+};
+
+static struct i2c_board_info accel_bma2x2_i2c_info[] __initdata = {
+ {
+ I2C_BOARD_INFO("bma2x2", 0x18),
+ .irq=MSM_GPIO_TO_INT(GPIO_ACC_INT),
+ },
+};
+
+static int bma2x2_gpio_setup(void) {
+ int ret = 0;
+ ret= msm_gpios_request_enable(bma2x2_gpio_cfg_data,
+ sizeof(bma2x2_gpio_cfg_data)/sizeof(struct msm_gpio));
+ if( ret<0 )
+ printk(KERN_ERR "%s: Failed to obtain acc int GPIO %d. Code: %d\n",
+ __func__, GPIO_ACC_INT, ret);
+ return ret;
+}
+
+#endif
+//end
+//pjn add for p/l sensor
+#if defined(CONFIG_SENSORS_LTR559)
+#define GPIO17_PLSENSOR_INT 17
+static struct i2c_board_info ltr559_i2c_info[] __initdata = {
+ {
+ I2C_BOARD_INFO("ltr559alsps", 0x23),
+ .irq = MSM_GPIO_TO_INT(GPIO17_PLSENSOR_INT),
+ },
+};
+#endif
+
+void __init msm7627a_sensor_init(void)
+{
+#ifdef CONFIG_AVAGO_APDS990X
+ if ( machine_is_msm7627a_evb() || machine_is_msm8625_evb() || machine_is_msm8625_qrd5() || machine_is_msm7x27a_qrd5a()) {
+ pr_info("i2c_register_board_info APDS990X\n");
+ apds990x_setup();
+ }
+#endif
+
+#ifdef CONFIG_SENSORS_TMD2771X
+ if (machine_is_msm8625q_skue()) {
+ pr_info("i2c_register_board_info TMD2771X\n");
+ tmd2771x_setup();
+ }
+#endif
+
+#ifdef CONFIG_MPU_SENSORS_MPU3050
+ if (machine_is_msm7627a_evb() || machine_is_msm8625_evb() || machine_is_msm8625_qrd5() || machine_is_msm7x27a_qrd5a()) {
+ pr_info("i2c_register_board_info MPU3050\n");
+ mpu3050_gpio_setup();
+ }
+#endif
+
+#ifdef CONFIG_BOSCH_BMA250
+ if (machine_is_msm8625_qrd7() || machine_is_msm7627a_qrd3() || machine_is_msm8625q_skud()) {
+ pr_info("i2c_register_board_info BMA250 ACC\n");
+ i2c_register_board_info(MSM_GSBI1_QUP_I2C_BUS_ID,
+ bma250_i2c_info,
+ ARRAY_SIZE(bma250_i2c_info));
+ }
+#endif
+
+#ifdef CONFIG_INPUT_ISL29028
+ if (machine_is_msm8625q_skud()) {
+ pr_info("i2c_register_board_info ISL29028 ALP sensor!\n");
+ isl29028_gpio_setup();
+ i2c_register_board_info(MSM_GSBI0_QUP_I2C_BUS_ID,
+ isl29028_i2c_info,
+ ARRAY_SIZE(isl29028_i2c_info));
+ }
+#endif
+
+#ifdef CONFIG_INPUT_LTR558
+ if (machine_is_msm8625q_skue()) {
+ pr_info("i2c_register_board_info LTR558 ALP sensor!\n");
+ ltr558_gpio_setup();
+ i2c_register_board_info(MSM_GSBI1_QUP_I2C_BUS_ID,
+ ltr558_i2c_info,
+ ARRAY_SIZE(ltr558_i2c_info));
+ }
+#endif
+
+#ifdef CONFIG_INPUT_LIS3DH
+ if (machine_is_msm8625q_skue()) {
+ lis3dh_acc_gpio_setup();
+ pr_info("i2c_register_board_info LIS3DH ACC\n");
+ i2c_register_board_info(MSM_GSBI1_QUP_I2C_BUS_ID,
+ lis3dh_acc_i2c_info,
+ ARRAY_SIZE(lis3dh_acc_i2c_info));
+ }
+#endif
+
+#ifdef CONFIG_INPUT_LTR502
+ if (machine_is_msm8625_qrd7() || machine_is_msm7627a_qrd3()) {
+ pr_info("i2c_register_board_info LTR502\n");
+ ltr502_light_gpio_setup();
+ i2c_register_board_info(MSM_GSBI1_QUP_I2C_BUS_ID,
+ ltr502_light_i2c_info,
+ ARRAY_SIZE(ltr502_light_i2c_info));
+ }
+#endif
+
+#ifdef CONFIG_SENSORS_AK8975
+ if (machine_is_msm8625_qrd7() || machine_is_msm7627a_qrd3() || machine_is_msm8625q_skud()) {
+ pr_info("i2c_register_board_info AKM8975\n");
+ akm_gpio_setup();
+ akm_platform_data_8975.gpio_DRDY = 18;
+ akm8975_i2c_info[0].irq = gpio_to_irq(akm_platform_data_8975.gpio_DRDY);
+ i2c_register_board_info(MSM_GSBI1_QUP_I2C_BUS_ID,
+ akm8975_i2c_info,
+ ARRAY_SIZE(akm8975_i2c_info));
+ }
+#endif
+
+#ifdef CONFIG_INPUT_KXTJ9
+ if(machine_is_msm8625_skua()) {
+ pr_info("i2c_register_board_info KXTJ9\n");
+ i2c_register_board_info(MSM_GSBI1_QUP_I2C_BUS_ID,
+ accel_kxtj9_i2c_info,
+ ARRAY_SIZE(accel_kxtj9_i2c_info));
+ }
+#endif
+
+#ifdef CONFIG_SENSORS_BMA2X2
+ //if (machine_is_msm8625_qrd7() || machine_is_msm7627a_qrd3()) {
+ pr_info("i2c_register_board_info BMA2X2\n");
+ bma2x2_gpio_setup ();
+ i2c_register_board_info(MSM_GSBI1_QUP_I2C_BUS_ID,
+ accel_bma2x2_i2c_info,
+ ARRAY_SIZE(accel_bma2x2_i2c_info));
+ //}
+#endif
+
+#ifdef CONFIG_SENSORS_LTR559
+ pr_info("i2c_register_board_info LTR559\n");
+ i2c_register_board_info(MSM_GSBI1_QUP_I2C_BUS_ID,
+ ltr559_i2c_info,
+ ARRAY_SIZE(ltr559_i2c_info));
+#endif
+
+}
diff --git a/arch/arm/mach-msm/board-msm7627a-sensor.h b/arch/arm/mach-msm/board-msm7627a-sensor.h
new file mode 100644
index 0000000..94b84b1
--- /dev/null
+++ b/arch/arm/mach-msm/board-msm7627a-sensor.h
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __ARCH_ARM_MACH_MSM_BOARD_7627_REGULATOR_H__
+#define __ARCH_ARM_MACH_MSM_BOARD_7627_REGULATOR_H__
+
+extern void msm7627a_sensor_init(void);
+
+#endif
diff --git a/arch/arm/mach-msm/board-msm7627a-storage.c b/arch/arm/mach-msm/board-msm7627a-storage.c
old mode 100644
new mode 100755
index 23d51b2..03a95ec
--- a/arch/arm/mach-msm/board-msm7627a-storage.c
+++ b/arch/arm/mach-msm/board-msm7627a-storage.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2013, The Linux Foundation. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -147,7 +147,7 @@ static struct sdcc_gpio sdcc_cfg_data[] = {
},
};
-static int gpio_sdc1_hw_det = 85;
+static int gpio_sdc1_hw_det = 42;
static void gpio_sdc1_config(void)
{
if (machine_is_msm7627a_qrd1() || machine_is_msm7627a_evb()
@@ -155,6 +155,8 @@ static void gpio_sdc1_config(void)
|| machine_is_msm7627a_qrd3()
|| machine_is_msm8625_qrd7())
gpio_sdc1_hw_det = 42;
+ else if (machine_is_msm8625q_skue())
+ gpio_sdc1_hw_det = 112;
}
static struct regulator *sdcc_vreg_data[MAX_SDCC_CONTROLLER];
@@ -224,6 +226,9 @@ static uint32_t msm_sdcc_setup_power(struct device *dv, unsigned int vdd)
pdev = container_of(dv, struct platform_device, dev);
+ if (machine_is_msm8625q_skue() && (pdev->id == 1) && (!vdd))
+ return 0;
+
rc = msm_sdcc_setup_gpio(pdev->id, !!vdd);
if (rc)
goto out;
@@ -256,7 +261,8 @@ static unsigned int msm7627a_sdcc_slot_status(struct device *dev)
machine_is_msm7627a_evb() ||
machine_is_msm8625_evb() ||
machine_is_msm7627a_qrd3() ||
- machine_is_msm8625_qrd7())
+ machine_is_msm8625_qrd7() ||
+ machine_is_msm8625q_skue())
status = !gpio_get_value(gpio_sdc1_hw_det);
else
status = gpio_get_value(gpio_sdc1_hw_det);
@@ -275,6 +281,7 @@ static struct mmc_platform_data sdc1_plat_data = {
.msmsdcc_fmax = 49152000,
.status = msm7627a_sdcc_slot_status,
.irq_flags = IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
+ .hw_resetable = 1,
};
#endif
@@ -364,33 +371,31 @@ void __init msm7627a_init_mmc(void)
{
/* eMMC slot */
#ifdef CONFIG_MMC_MSM_SDC3_SUPPORT
-
+#if 1 // #suwg
+ if (mmc_regulator_init(3, "emmc", 3000000))
+ return;
+ msm_add_sdcc(3, &sdc3_plat_data);
+ msm_sdcc_setup_gpio(3, 1);
+ msm_sdcc_setup_vreg(3, 1);
+#else
/* There is no eMMC on SDC3 for QRD3 based devices */
if (!(machine_is_msm7627a_qrd3() || machine_is_msm8625_qrd7())) {
if (mmc_regulator_init(3, "emmc", 3000000))
return;
- /*
- * On 7x25A FFA data CRC errors are seen, which are
- * probably due to the proximity of SIM card and eMMC.
- * Hence, reducing the clock to 24.7Mhz from 49Mhz.
- */
- if (machine_is_msm7625a_ffa())
- sdc3_plat_data.msmsdcc_fmax =
- sdc3_plat_data.msmsdcc_fmid;
msm_add_sdcc(3, &sdc3_plat_data);
}
#endif
+#endif
/* Micro-SD slot */
#ifdef CONFIG_MMC_MSM_SDC1_SUPPORT
gpio_sdc1_config();
if (mmc_regulator_init(1, "mmc", 2850000))
return;
/* 8x25 EVT do not use hw detector */
- if (!((machine_is_msm8625_evt() || machine_is_qrd_skud_prime() ||
- machine_is_msm8625q_evbd() || machine_is_msm8625q_skud())))
+ if (!(machine_is_msm8625_qrd5()) && !(machine_is_msm7x27a_qrd5a()) && !(machine_is_msm8625q_skud())
+ && !(machine_is_msm8625q_evbd()) && !(machine_is_msm8625_surf()))
sdc1_plat_data.status_irq = MSM_GPIO_TO_INT(gpio_sdc1_hw_det);
- if (machine_is_msm8625_evt() || machine_is_qrd_skud_prime() ||
- machine_is_msm8625q_evbd() || machine_is_msm8625q_skud())
+ else
sdc1_plat_data.status = NULL;
msm_add_sdcc(1, &sdc1_plat_data);
diff --git a/arch/arm/mach-msm/board-msm7627a-wlan.c b/arch/arm/mach-msm/board-msm7627a-wlan.c
index af5f458..5e99e58 100644
--- a/arch/arm/mach-msm/board-msm7627a-wlan.c
+++ b/arch/arm/mach-msm/board-msm7627a-wlan.c
@@ -42,21 +42,23 @@ struct wlan_vreg_info {
static struct wlan_vreg_info vreg_info[] = {
{"msme1", 1800000, 1800000, 2, 0, NULL},
- {"bt", 3300000, 3300000, 21, 1, NULL},
- {"wlan4", 1800000, 1800000, 23, 1, NULL}
+ {"wlan3v3", 3300000, 3300000, 21, 1, NULL},
+ {"wlan1v8", 1800000, 1800000, 0, 0, NULL}
};
-int gpio_wlan_sys_rest_en = 134;
+int gpio_wlan_sys_rest_en = 124;
static void gpio_wlan_config(void)
{
if (machine_is_msm7627a_qrd1() || machine_is_msm7627a_evb()
|| machine_is_msm8625_evb()
- || machine_is_msm8625_evt()
+ || machine_is_msm8625_qrd5()
+ || machine_is_msm7x27a_qrd5a()
|| machine_is_msm7627a_qrd3()
|| machine_is_msm8625_qrd7())
gpio_wlan_sys_rest_en = 124;
- else if (machine_is_qrd_skud_prime() || machine_is_msm8625q_evbd()
- || machine_is_msm8625q_skud())
+ else if(machine_is_msm8625q_evbd()
+ || machine_is_msm8625q_skue()
+ || machine_is_msm8625q_skud())
gpio_wlan_sys_rest_en = 38;
}
@@ -129,7 +131,6 @@ static unsigned int wlan_switch_regulators(int on)
if (machine_is_msm7627a_qrd1())
index = 2;
-
for ( ; index < ARRAY_SIZE(vreg_info); index++) {
if (on) {
rc = regulator_set_voltage(vreg_info[index].reg,
@@ -244,11 +245,13 @@ static unsigned int msm_AR600X_setup_power(bool on)
*/
if (machine_is_msm7627a_qrd1() || machine_is_msm7627a_evb()
|| machine_is_msm8625_evb()
- || machine_is_msm8625_evt()
+ || machine_is_msm8625_qrd5()
+ || machine_is_msm7x27a_qrd5a()
|| machine_is_msm7627a_qrd3()
|| machine_is_msm8625_qrd7()
|| machine_is_msm8625q_evbd()
- || machine_is_qrd_skud_prime()) {
+ || machine_is_msm8625q_skue()
+ || machine_is_msm8625q_skud()) {
rc = gpio_tlmm_config(GPIO_CFG(gpio_wlan_sys_rest_en, 0,
GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL,
GPIO_CFG_2MA), GPIO_CFG_ENABLE);
@@ -298,8 +301,9 @@ set_gpio_fail:
setup_wlan_gpio(0);
gpio_fail:
if (!(machine_is_msm7627a_qrd1() || machine_is_msm7627a_evb() ||
- machine_is_msm8625_evb() || machine_is_msm8625_evt() ||
- machine_is_msm7627a_qrd3() || machine_is_msm8625_qrd7()))
+ machine_is_msm8625_evb() || machine_is_msm8625_qrd5() ||
+ machine_is_msm7627a_qrd3() || machine_is_msm8625_qrd7()||
+ machine_is_msm8625q_skud() || machine_is_msm8625q_skue()))
gpio_free(gpio_wlan_sys_rest_en);
qrd_gpio_fail:
/* GPIO_WLAN_3V3_EN is only required for the QRD7627a */
@@ -335,11 +339,13 @@ static unsigned int msm_AR600X_shutdown_power(bool on)
*/
if (machine_is_msm7627a_qrd1() || machine_is_msm7627a_evb()
|| machine_is_msm8625_evb()
- || machine_is_msm8625_evt()
+ || machine_is_msm8625_qrd5()
+ || machine_is_msm7x27a_qrd5a()
|| machine_is_msm7627a_qrd3()
|| machine_is_msm8625_qrd7()
|| machine_is_msm8625q_evbd()
- || machine_is_qrd_skud_prime()) {
+ || machine_is_msm8625q_skue()
+ || machine_is_msm8625q_skud()) {
rc = gpio_tlmm_config(GPIO_CFG(gpio_wlan_sys_rest_en, 0,
GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL,
GPIO_CFG_2MA), GPIO_CFG_ENABLE);
@@ -386,8 +392,9 @@ set_gpio_fail:
setup_wlan_gpio(0);
gpio_fail:
if (!(machine_is_msm7627a_qrd1() || machine_is_msm7627a_evb() ||
- machine_is_msm8625_evb() || machine_is_msm8625_evt() ||
- machine_is_msm7627a_qrd3() || machine_is_msm8625_qrd7()))
+ machine_is_msm8625_evb() || machine_is_msm8625_qrd5() ||
+ machine_is_msm7627a_qrd3() || machine_is_msm8625_qrd7()||
+ machine_is_msm8625q_skud() || machine_is_msm8625q_skue()))
gpio_free(gpio_wlan_sys_rest_en);
qrd_gpio_fail:
/* GPIO_WLAN_3V3_EN is only required for the QRD7627a */
@@ -408,3 +415,51 @@ int ar600x_wlan_power(bool on)
return 0;
}
+
+static int __init qrd_wlan_init(void)
+{
+ int rc;
+
+ pr_info("WLAN power init\n");
+ if (machine_is_msm7627a_qrd1() || machine_is_msm7627a_evb()
+ || machine_is_msm8625_evb()
+ || machine_is_msm8625_qrd5()
+ || machine_is_msm7627a_qrd3()
+ || machine_is_msm8625_qrd7()
+ || machine_is_msm8625q_skud()
+ || machine_is_msm8625q_skue()) {
+ rc = gpio_tlmm_config(GPIO_CFG(gpio_wlan_sys_rest_en, 0,
+ GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL,
+ GPIO_CFG_2MA), GPIO_CFG_ENABLE);
+ if (rc) {
+ pr_err("%s gpio_tlmm_config %d failed,error = %d\n",
+ __func__, gpio_wlan_sys_rest_en, rc);
+ goto exit;
+ }
+ gpio_set_value(gpio_wlan_sys_rest_en, 0);
+ } else {
+ gpio_request(gpio_wlan_sys_rest_en, "WLAN_DEEP_SLEEP_N");
+ rc = setup_wlan_gpio(false);
+ gpio_free(gpio_wlan_sys_rest_en);
+ if (rc) {
+ pr_err("%s: wlan_set_gpio = %d\n", __func__, rc);
+ goto exit;
+ }
+ }
+
+ /* GPIO_WLAN_3V3_EN is only required for the QRD7627a */
+ if (machine_is_msm7627a_qrd1()) {
+ rc = gpio_tlmm_config(GPIO_CFG(GPIO_WLAN_3V3_EN, 0,
+ GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL,
+ GPIO_CFG_2MA), GPIO_CFG_ENABLE);
+ if (rc) {
+ pr_err("%s gpio_tlmm_config %d failed,error = %d\n",
+ __func__, GPIO_WLAN_3V3_EN, rc);
+ goto exit;
+ }
+ gpio_set_value(GPIO_WLAN_3V3_EN, 0);
+ }
+exit:
+ return rc;
+}
+device_initcall(qrd_wlan_init);
diff --git a/arch/arm/mach-msm/board-msm7x27a-regulator.c b/arch/arm/mach-msm/board-msm7x27a-regulator.c
old mode 100644
new mode 100755
index 7c140cb..a87ffbc
--- a/arch/arm/mach-msm/board-msm7x27a-regulator.c
+++ b/arch/arm/mach-msm/board-msm7x27a-regulator.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011-2012, The Linux Foundation. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -188,6 +188,7 @@ PCOM_VREG_CONSUMERS(ldo16) = {
PCOM_VREG_CONSUMERS(ldo17) = {
REGULATOR_SUPPLY("ldo17", NULL),
REGULATOR_SUPPLY("bt", NULL),
+ REGULATOR_SUPPLY("wlan3v3", NULL),
};
PCOM_VREG_CONSUMERS(ldo18) = {
@@ -197,7 +198,7 @@ PCOM_VREG_CONSUMERS(ldo18) = {
PCOM_VREG_CONSUMERS(ldo19) = {
REGULATOR_SUPPLY("ldo19", NULL),
- REGULATOR_SUPPLY("wlan4", NULL),
+ REGULATOR_SUPPLY("wlan1v8", NULL),
};
PCOM_VREG_CONSUMERS(ncp) = {
@@ -222,8 +223,12 @@ static struct proccomm_regulator_info msm7x27a_pcom_vreg_info[] = {
PCOM_VREG_LDO(ldo02, 13, NULL, 2850000, 2850000, 0, -1, 0, 0, 0, 0, p),
PCOM_VREG_LDO(ldo03, 49, NULL, 1200000, 1200000, 0, -1, 0, 0, 0, 0, n),
PCOM_VREG_LDO(ldo04, 50, NULL, 1100000, 1100000, 0, -1, 0, 0, 0, 0, n),
+#ifdef CONFIG_S5K3H2_SUNNY_Q8S02E
+ PCOM_VREG_LDO(ldo05, 45, NULL, 1200000, 1200000, 0, -1, 0, 0, 0, 0, n),
+#else
PCOM_VREG_LDO(ldo05, 45, NULL, 1300000, 1350000, 0, -1, 0, 0, 0, 0, n),
- PCOM_VREG_LDO(ldo06, 51, NULL, 1200000, 1200000, 0, -1, 0, 0, 0, 0, n),
+#endif
+ PCOM_VREG_LDO(ldo06, 51, NULL, 1200000, 1525000, 0, -1, 0, 0, 0, 0, n),
PCOM_VREG_LDO(ldo07, 0, NULL, 2600000, 2600000, 0, -1, 0, 0, 0, 0, p),
PCOM_VREG_LDO(ldo08, 9, NULL, 2850000, 2850000, 0, -1, 0, 0, 0, 0, p),
PCOM_VREG_LDO(ldo09, 44, NULL, 1800000, 1800000, 0, -1, 0, 0, 0, 0, p),
diff --git a/arch/arm/mach-msm/board-msm7x27a.c b/arch/arm/mach-msm/board-msm7x27a.c
old mode 100644
new mode 100755
index 916a1b8..98e98a5
--- a/arch/arm/mach-msm/board-msm7x27a.c
+++ b/arch/arm/mach-msm/board-msm7x27a.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -61,11 +61,23 @@
#include <mach/socinfo.h>
#include "pm-boot.h"
#include "board-msm7627a.h"
+#include "board-msm7627a-sensor.h"
+
+#include <linux/delay.h>
+/*add QC pathc for MTBF test I2C time */
+#include <mach/gpiomux.h>
+
#define PMEM_KERNEL_EBI1_SIZE 0x3A000
#define MSM_PMEM_AUDIO_SIZE 0xF0000
#define BOOTLOADER_BASE_ADDR 0x10000
+//start yang.chenglei@byd added for smem_kpanic
+#ifdef CONFIG_MMC_MSM_RAW
+extern void __init msm_init_apanic(void);
+#endif /* CONFIG_MMC_MSM_RAW */
+//end yang.chenglei@byd added for smem_kpanic
+
#if defined(CONFIG_GPIO_SX150X)
enum {
SX150X_CORE,
@@ -118,9 +130,9 @@ static struct msm_gpio qup_i2c_gpios_io[] = {
"qup_scl" },
{ GPIO_CFG(61, 0, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_8MA),
"qup_sda" },
- { GPIO_CFG(131, 0, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_8MA),
+ { GPIO_CFG(131, 0, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_16MA),
"qup_scl" },
- { GPIO_CFG(132, 0, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_8MA),
+ { GPIO_CFG(132, 0, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_16MA),
"qup_sda" },
};
@@ -129,12 +141,36 @@ static struct msm_gpio qup_i2c_gpios_hw[] = {
"qup_scl" },
{ GPIO_CFG(61, 1, GPIO_CFG_INPUT, GPIO_CFG_NO_PULL, GPIO_CFG_8MA),
"qup_sda" },
- { GPIO_CFG(131, 2, GPIO_CFG_INPUT, GPIO_CFG_NO_PULL, GPIO_CFG_8MA),
+ { GPIO_CFG(131, 2, GPIO_CFG_INPUT, GPIO_CFG_NO_PULL, GPIO_CFG_16MA),
"qup_scl" },
- { GPIO_CFG(132, 2, GPIO_CFG_INPUT, GPIO_CFG_NO_PULL, GPIO_CFG_8MA),
+ { GPIO_CFG(132, 2, GPIO_CFG_INPUT, GPIO_CFG_NO_PULL, GPIO_CFG_16MA),
"qup_sda" },
};
-
+/*add QC pathc for MTBF test I2C time start*/
+static int qrd_gpios_request_enable(const struct msm_gpio *table, int size)
+{
+ int i;
+ const struct msm_gpio *g;
+ struct gpiomux_setting setting;
+ int rc = msm_gpios_request(table, size);
+ if (!rc){
+ for (i = 0; i < size; i++) {
+ g = table + i;
+ /* use msm_gpiomux_write which can save old configuration */
+ setting.func = GPIO_FUNC(g->gpio_cfg);
+ setting.dir = GPIO_DIR(g->gpio_cfg);
+ setting.pull = GPIO_PULL(g->gpio_cfg);
+ setting.drv = GPIO_DRVSTR(g->gpio_cfg);
+ msm_gpiomux_write(GPIO_PIN(g->gpio_cfg), GPIOMUX_ACTIVE, &setting, NULL);
+ pr_debug("I2C pin %d func %d dir %d pull %d drvstr %d\n",
+ GPIO_PIN(g->gpio_cfg), GPIO_FUNC(g->gpio_cfg),
+ GPIO_DIR(g->gpio_cfg), GPIO_PULL(g->gpio_cfg),
+ GPIO_DRVSTR(g->gpio_cfg));
+ }
+ }
+ return rc;
+}
+/*add QC pathc for MTBF test I2C time end*/
static void gsbi_qup_i2c_gpio_config(int adap_id, int config_type)
{
int rc;
@@ -143,26 +179,38 @@ static void gsbi_qup_i2c_gpio_config(int adap_id, int config_type)
return;
/* Each adapter gets 2 lines from the table */
+ /*ad QC pathc for MTBF test I2C time */
if (config_type)
- rc = msm_gpios_request_enable(&qup_i2c_gpios_hw[adap_id*2], 2);
+ rc = qrd_gpios_request_enable(&qup_i2c_gpios_hw[adap_id*2], 2);
else
- rc = msm_gpios_request_enable(&qup_i2c_gpios_io[adap_id*2], 2);
+ rc = qrd_gpios_request_enable(&qup_i2c_gpios_io[adap_id*2], 2);
if (rc < 0)
pr_err("QUP GPIO request/enable failed: %d\n", rc);
}
static struct msm_i2c_platform_data msm_gsbi0_qup_i2c_pdata = {
- .clk_freq = 100000,
+ .clk_freq = 400000,//100000,
.msm_i2c_config_gpio = gsbi_qup_i2c_gpio_config,
+ /*add QC pathc for MTBF test I2C time */
+ .rsl_id = "gsbi0",
+ .pri_clk=60,
+ .pri_dat=61,
};
static struct msm_i2c_platform_data msm_gsbi1_qup_i2c_pdata = {
.clk_freq = 100000,
.msm_i2c_config_gpio = gsbi_qup_i2c_gpio_config,
+ /*add QC pathc for MTBF test I2C time */
+ .rsl_id = "gsbi1",
+ .pri_clk=131,
+ .pri_dat=132,
};
#ifdef CONFIG_ARCH_MSM7X27A
+//lwl modify
#define MSM_PMEM_MDP_SIZE 0x2300000
+//#define MSM_PMEM_MDP_SIZE 0
+//end
#define MSM7x25A_MSM_PMEM_MDP_SIZE 0x1500000
#define MSM_PMEM_ADSP_SIZE 0x1300000
@@ -552,8 +600,12 @@ static u32 msm_calculate_batt_capacity(u32 current_voltage);
static struct msm_psy_batt_pdata msm_psy_batt_data = {
.voltage_min_design = 3200,
.voltage_max_design = 4200,
- .voltage_fail_safe = 3340,
- .avail_chg_sources = AC_CHG | USB_CHG ,
+// .voltage_fail_safe = 3340,
+#if 0
+ .avail_chg_sources = AC_CHG | USB_CHG //Baseline code
+#else
+ .avail_chg_sources = AC_CHG | USB_CHG | UNKNOWN_CHG, //Support unknown usb to fixed reset issue.
+#endif
.batt_technology = POWER_SUPPLY_TECHNOLOGY_LION,
.calculate_capacity = &msm_calculate_batt_capacity,
};
@@ -771,8 +823,8 @@ static void fix_sizes(void)
pmem_adsp_size = MSM_PMEM_ADSP_SIZE;
}
- if (get_ddr_size() > SZ_512M)
- pmem_adsp_size = CAMERA_ZSL_SIZE;
+ //if (get_ddr_size() > SZ_512M)
+ // pmem_adsp_size = CAMERA_ZSL_SIZE;
#ifdef CONFIG_ION_MSM
msm_ion_audio_size = MSM_PMEM_AUDIO_SIZE;
@@ -1093,9 +1145,14 @@ static void __init msm8625_rumi3_init(void)
#define UART1DM_RX_GPIO 45
#if defined(CONFIG_BT) && defined(CONFIG_MARIMBA_CORE)
+#define NV_ITEM_WLAN_MAC_ADDR 4678
+extern int msm_read_nv(unsigned int nv_item, void *buf);
+unsigned char wlan_mac_addr[6];
+
static int __init msm7x27a_init_ar6000pm(void)
{
msm_wlan_ar6000_pm_device.dev.platform_data = &ar600x_wlan_power;
+ msm_read_nv(NV_ITEM_WLAN_MAC_ADDR,wlan_mac_addr);
return platform_device_register(&msm_wlan_ar6000_pm_device);
}
#else
@@ -1175,12 +1232,37 @@ static void __init msm7x27a_pm_init(void)
msm_pm_register_irqs();
}
+#if 0
+void test_flash(void)
+{
+ int t1 = 13;
+ int t2 = 32;
+
+ gpio_request(t1, "kernel_test");
+ gpio_request(t2, "kernel_test");
+
+ gpio_direction_output(t1, 0);
+ gpio_direction_output(t1, 0);
+
+ while (1)
+ {
+ gpio_set_value(t1, 1);
+ gpio_set_value(t2, 1);
+ mdelay(200);
+ gpio_set_value(t1, 0);
+ gpio_set_value(t2, 0);
+ mdelay(200);
+ }
+}
+#endif
static void __init msm7x2x_init(void)
{
- msm7x2x_misc_init();
-
- /* Initialize regulators first so that other devices can use them */
+ gpio_set_value(13, 0);
+ gpio_set_value(32, 0);
+
+ msm7x2x_misc_init();
+ /* Initialize regulators first so that other devices can use them */
msm7x27a_init_regulators();
msm_adsp_add_pdev();
if (cpu_is_msm8625() || cpu_is_msm8625q())
@@ -1206,11 +1288,31 @@ static void __init msm7x2x_init(void)
msm7627a_bt_power_init();
#endif
msm7627a_camera_init();
+ msm7627a_sensor_init();
msm7627a_add_io_devices();
/*7x25a kgsl initializations*/
msm7x25a_kgsl_3d0_init();
/*8x25 kgsl initializations*/
msm8x25_kgsl_3d0_init();
+ //test_flash();
+ {
+
+ int t1 = 13;
+ int t2 = 32;
+
+ gpio_request(t1, "kernel_test");
+ gpio_request(t2, "kernel_test");
+
+ gpio_direction_output(t1, 0);
+ gpio_direction_output(t1, 0);
+
+ }
+//start yang.chenglei@byd added for smem_kpanic
+#ifdef CONFIG_MMC_MSM_RAW
+ msm_init_apanic();
+#endif /* CONFIG_MMC_MSM_RAW */
+//end yang.chenglei@byd added for smem_kpanic
+
}
static void __init msm7x2x_init_early(void)
diff --git a/arch/arm/mach-msm/board-qrd7627a.c b/arch/arm/mach-msm/board-qrd7627a.c
old mode 100644
new mode 100755
index 7b33ed1..fc7e6ba
--- a/arch/arm/mach-msm/board-qrd7627a.c
+++ b/arch/arm/mach-msm/board-qrd7627a.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -24,6 +24,7 @@
#include <linux/bootmem.h>
#include <linux/mfd/marimba.h>
#include <linux/power_supply.h>
+//#include <linux/leds-pmic8029.h>
#include <linux/input/rmi_platformdata.h>
#include <linux/input/rmi_i2c.h>
#include <linux/i2c/atmel_mxt_ts.h>
@@ -43,6 +44,7 @@
#include <asm/mach/arch.h>
#include <asm/hardware/gic.h>
#include <mach/board.h>
+#include <mach/gpiomux.h>
#include <mach/msm_iomap.h>
#include <mach/msm_hsusb.h>
#include <mach/rpc_hsusb.h>
@@ -50,7 +52,6 @@
#include <mach/usbdiag.h>
#include <mach/msm_memtypes.h>
#include <mach/msm_serial_hs.h>
-#include <mach/msm_serial_pdata.h>
#include <mach/pmic.h>
#include <mach/socinfo.h>
#include <mach/vreg.h>
@@ -58,6 +59,7 @@
#include <mach/msm_battery.h>
#include <mach/rpc_server_handset.h>
#include <mach/socinfo.h>
+#include <mach/oem_rapi_client.h>
#include "board-msm7x27a-regulator.h"
#include "devices.h"
#include "devices-msm7x2xa.h"
@@ -66,6 +68,7 @@
#include "pm-boot.h"
#include "board-msm7x27a-regulator.h"
#include "board-msm7627a.h"
+#include "board-msm7627a-sensor.h"
#define PMEM_KERNEL_EBI1_SIZE 0x3A000
#define MSM_PMEM_AUDIO_SIZE 0xF0000
@@ -83,15 +86,6 @@
#define I2C_NORMAL 0x40
-static struct platform_device msm_wlan_ar6000_pm_device = {
- .name = "wlan_ar6000_pm_dev",
- .id = -1,
-};
-
-static struct msm_serial_platform_data msm_8625_uart1_pdata = {
- .userid = 10,
-};
-
static struct msm_gpio qup_i2c_gpios_io[] = {
{ GPIO_CFG(60, 0, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_8MA),
"qup_scl" },
@@ -114,6 +108,32 @@ static struct msm_gpio qup_i2c_gpios_hw[] = {
"qup_sda" },
};
+static int qrd_gpios_request_enable(const struct msm_gpio *table, int size)
+{
+ int i;
+ const struct msm_gpio *g;
+ struct gpiomux_setting setting;
+
+ int rc = msm_gpios_request(table, size);
+
+ if (!rc){
+ for (i = 0; i < size; i++) {
+ g = table + i;
+ /* use msm_gpiomux_write which can save old configuration */
+ setting.func = GPIO_FUNC(g->gpio_cfg);
+ setting.dir = GPIO_DIR(g->gpio_cfg);
+ setting.pull = GPIO_PULL(g->gpio_cfg);
+ setting.drv = GPIO_DRVSTR(g->gpio_cfg);
+ msm_gpiomux_write(GPIO_PIN(g->gpio_cfg), GPIOMUX_ACTIVE, &setting, NULL);
+ pr_debug("I2C pin %d func %d dir %d pull %d drvstr %d\n",
+ GPIO_PIN(g->gpio_cfg), GPIO_FUNC(g->gpio_cfg),
+ GPIO_DIR(g->gpio_cfg), GPIO_PULL(g->gpio_cfg),
+ GPIO_DRVSTR(g->gpio_cfg));
+ }
+ }
+ return rc;
+}
+
static void gsbi_qup_i2c_gpio_config(int adap_id, int config_type)
{
int rc;
@@ -123,9 +143,9 @@ static void gsbi_qup_i2c_gpio_config(int adap_id, int config_type)
/* Each adapter gets 2 lines from the table */
if (config_type)
- rc = msm_gpios_request_enable(&qup_i2c_gpios_hw[adap_id*2], 2);
+ rc = qrd_gpios_request_enable(&qup_i2c_gpios_hw[adap_id*2], 2);
else
- rc = msm_gpios_request_enable(&qup_i2c_gpios_io[adap_id*2], 2);
+ rc = qrd_gpios_request_enable(&qup_i2c_gpios_io[adap_id*2], 2);
if (rc < 0)
pr_err("QUP GPIO request/enable failed: %d\n", rc);
}
@@ -392,7 +412,7 @@ static struct msm_pm_platform_data
.idle_supported = 1,
.suspend_supported = 1,
.idle_enabled = 0,
- .suspend_enabled = 0,
+ .suspend_enabled = 1,
.latency = 500,
.residency = 500,
},
@@ -411,7 +431,7 @@ static struct msm_pm_platform_data
.idle_supported = 1,
.suspend_supported = 1,
.idle_enabled = 0,
- .suspend_enabled = 0,
+ .suspend_enabled = 1,
.latency = 500,
.residency = 500,
},
@@ -430,7 +450,7 @@ static struct msm_pm_platform_data
.idle_supported = 1,
.suspend_supported = 1,
.idle_enabled = 0,
- .suspend_enabled = 0,
+ .suspend_enabled = 1,
.latency = 500,
.residency = 500,
},
@@ -449,7 +469,7 @@ static struct msm_pm_platform_data
.idle_supported = 1,
.suspend_supported = 1,
.idle_enabled = 0,
- .suspend_enabled = 0,
+ .suspend_enabled = 1,
.latency = 500,
.residency = 500,
},
@@ -529,10 +549,9 @@ static struct platform_device android_pmem_device = {
static u32 msm_calculate_batt_capacity(u32 current_voltage);
static struct msm_psy_batt_pdata msm_psy_batt_data = {
- .voltage_min_design = 3500,
- .voltage_max_design = 4200,
- .voltage_fail_safe = 3598,
- .avail_chg_sources = AC_CHG | USB_CHG ,
+ .voltage_min_design = 2800,
+ .voltage_max_design = 4300,
+ .avail_chg_sources = AC_CHG | USB_CHG | UNKNOWN_CHG,
.batt_technology = POWER_SUPPLY_TECHNOLOGY_LION,
.calculate_capacity = &msm_calculate_batt_capacity,
};
@@ -551,6 +570,11 @@ static u32 msm_calculate_batt_capacity(u32 current_voltage)
/ (high_voltage - low_voltage);
}
+static struct platform_device msm_fastboot_device = {
+ .name = "fastboot",
+ .id = -1,
+};
+
static struct platform_device msm_batt_device = {
.name = "msm-battery",
.id = -1,
@@ -593,21 +617,43 @@ static struct platform_device msm_adc_device = {
#define GPIO_VREG_ID_EXT_2P85V 0
#define GPIO_VREG_ID_EXT_1P8V 1
-#define GPIO_VREG_ID_EXT_2P85V_EVBD 2
-#define GPIO_VREG_ID_EXT_1P8V_EVBD 3
+#define GPIO_VREG_ID_EXT_2P85V_EVBD 2
+#define GPIO_VREG_ID_EXT_1P8V_EVBD 3
static struct regulator_consumer_supply vreg_consumers_EXT_2P85V[] = {
REGULATOR_SUPPLY("cam_ov5647_avdd", "0-006c"),
+ REGULATOR_SUPPLY("cam_ov5647_truly_cm6868_avdd", "0-006c"),
REGULATOR_SUPPLY("cam_ov7692_avdd", "0-0078"),
REGULATOR_SUPPLY("cam_ov8825_avdd", "0-000d"),
REGULATOR_SUPPLY("lcd_vdd", "mipi_dsi.1"),
+#ifdef CONFIG_AR0543
+ REGULATOR_SUPPLY("cam_ar0543_avdd", "0-0064"),
+#endif
+#ifdef CONFIG_A8140
+ REGULATOR_SUPPLY("cam_a8140_avdd", "0-0062"),
+#endif
+#ifdef CONFIG_S5K3H2_SUNNY_Q8S02E
+ REGULATOR_SUPPLY("cam_s5k3h2_sunny_q8s02e_avdd", "0-0032"),
+#endif
+ REGULATOR_SUPPLY("cam_ar0542_avdd", "0-0064"),
};
static struct regulator_consumer_supply vreg_consumers_EXT_1P8V[] = {
REGULATOR_SUPPLY("cam_ov5647_vdd", "0-006c"),
+ REGULATOR_SUPPLY("cam_ov5647_truly_cm6868_vdd", "0-006c"),
REGULATOR_SUPPLY("cam_ov7692_vdd", "0-0078"),
REGULATOR_SUPPLY("cam_ov8825_vdd", "0-000d"),
REGULATOR_SUPPLY("lcd_vddi", "mipi_dsi.1"),
+#ifdef CONFIG_AR0543
+ REGULATOR_SUPPLY("cam_ar0543_vdd", "0-0064"),
+#endif
+#ifdef CONFIG_A8140
+ REGULATOR_SUPPLY("cam_a8140_vdd", "0-0062"),
+#endif
+#ifdef CONFIG_S5K3H2_SUNNY_Q8S02E
+ REGULATOR_SUPPLY("cam_s5k3h2_sunny_q8s02e_vdd", "0-0032"),
+#endif
+ REGULATOR_SUPPLY("cam_ar0542_vdd", "0-0064"),
};
static struct regulator_consumer_supply vreg_consumers_EXT_2P85V_EVBD[] = {
@@ -628,10 +674,8 @@ static struct regulator_consumer_supply vreg_consumers_EXT_1P8V_EVBD[] = {
static struct gpio_regulator_platform_data msm_gpio_regulator_pdata[] = {
GPIO_VREG_INIT(EXT_2P85V, "ext_2p85v", "ext_2p85v_en", 35, 0),
GPIO_VREG_INIT(EXT_1P8V, "ext_1p8v", "ext_1p8v_en", 40, 0),
- GPIO_VREG_INIT(EXT_2P85V_EVBD, "ext_2p85v_evbd",
- "ext_2p85v_evbd_en", 5, 0),
- GPIO_VREG_INIT(EXT_1P8V_EVBD, "ext_1p8v_evbd",
- "ext_1p8v_evbd_en", 6, 0),
+ GPIO_VREG_INIT(EXT_2P85V_EVBD, "ext_2p85v_evbd", "ext_2p85v_evbd_en", 5, 0),
+ GPIO_VREG_INIT(EXT_1P8V_EVBD, "ext_1p8v_evbd", "ext_1p8v_evbd_en", 6, 0),
};
/* GPIO regulator */
@@ -654,21 +698,21 @@ static struct platform_device qrd_vreg_gpio_ext_1p8v __devinitdata = {
};
static struct platform_device evbd_vreg_gpio_ext_2p85v __devinitdata = {
- .name = GPIO_REGULATOR_DEV_NAME,
- .id = 5,
- .dev = {
- .platform_data =
- &msm_gpio_regulator_pdata[GPIO_VREG_ID_EXT_2P85V_EVBD],
- },
+ .name = GPIO_REGULATOR_DEV_NAME,
+ .id = 5,
+ .dev = {
+ .platform_data =
+ &msm_gpio_regulator_pdata[GPIO_VREG_ID_EXT_2P85V_EVBD],
+ },
};
static struct platform_device evbd_vreg_gpio_ext_1p8v __devinitdata = {
- .name = GPIO_REGULATOR_DEV_NAME,
- .id = 6,
- .dev = {
- .platform_data =
- &msm_gpio_regulator_pdata[GPIO_VREG_ID_EXT_1P8V_EVBD],
- },
+ .name = GPIO_REGULATOR_DEV_NAME,
+ .id = 6,
+ .dev = {
+ .platform_data =
+ &msm_gpio_regulator_pdata[GPIO_VREG_ID_EXT_1P8V_EVBD],
+ },
};
/* Regulator configuration for the NCP6335D buck */
struct regulator_consumer_supply ncp6335d_consumer_supplies[] = {
@@ -762,6 +806,15 @@ static struct platform_device *common_devices[] __initdata = {
#ifdef CONFIG_ION_MSM
&ion_dev,
#endif
+ &msm_fastboot_device,
+};
+
+
+static struct platform_device msm_wlan_ar6000_pm_device = {
+ .name = "wlan_ar6000_pm_dev",
+ .id = 1,
+ .num_resources = 0,
+ .resource = NULL,
};
static struct platform_device *qrd7627a_devices[] __initdata = {
@@ -795,13 +848,13 @@ static struct platform_device *msm8625_evb_devices[] __initdata = {
};
static struct platform_device *msm8625_lcd_camera_devices[] __initdata = {
- &qrd_vreg_gpio_ext_2p85v,
- &qrd_vreg_gpio_ext_1p8v,
+ &qrd_vreg_gpio_ext_2p85v,
+ &qrd_vreg_gpio_ext_1p8v,
};
static struct platform_device *msm8625q_lcd_camera_devices[] __initdata = {
- &evbd_vreg_gpio_ext_2p85v,
- &evbd_vreg_gpio_ext_1p8v,
+ &evbd_vreg_gpio_ext_2p85v,
+ &evbd_vreg_gpio_ext_1p8v,
};
static unsigned pmem_kernel_ebi1_size = PMEM_KERNEL_EBI1_SIZE;
@@ -825,7 +878,7 @@ static void fix_sizes(void)
if (get_ddr_size() > SZ_512M)
pmem_adsp_size = CAMERA_ZSL_SIZE;
else {
- if (machine_is_qrd_skud_prime() || machine_is_msm8625q_evbd()
+ if (machine_is_msm8625q_skue() || machine_is_msm8625q_evbd()
|| machine_is_msm8625q_skud())
pmem_mdp_size = 0;
}
@@ -1084,7 +1137,8 @@ static void __init msm8625_device_i2c_init(void)
= &msm_gsbi0_qup_i2c_pdata;
msm8625_gsbi1_qup_i2c_device.dev.platform_data
= &msm_gsbi1_qup_i2c_pdata;
- if (machine_is_qrd_skud_prime() || cpu_is_msm8625q()) {
+ if ( machine_is_msm8625q_skud() ||
+ machine_is_msm8625q_skue() || cpu_is_msm8625q()) {
for (i = 0 ; i < ARRAY_SIZE(msm8625q_i2c_gpio_config); i++) {
rc = gpio_tlmm_config(
msm8625q_i2c_gpio_config[i].gpio_cfg,
@@ -1115,6 +1169,8 @@ static void __init msm7627a_init_regulators(void)
__func__, rc);
}
+
+
static int __init msm_qrd_init_ar6000pm(void)
{
msm_wlan_ar6000_pm_device.dev.platform_data = &ar600x_wlan_power;
@@ -1130,31 +1186,30 @@ static void __init msm_add_footswitch_devices(void)
static void __init add_platform_devices(void)
{
if (machine_is_msm8625_evb() || machine_is_msm8625_qrd7()
- || machine_is_msm8625_evt()
+ || machine_is_msm8625_qrd5()
|| machine_is_msm8625q_evbd()
|| machine_is_msm8625q_skud()
- || machine_is_qrd_skud_prime()) {
- msm8625_device_uart1.dev.platform_data = &msm_8625_uart1_pdata;
+ || machine_is_msm8625q_skue()) {
platform_add_devices(msm8625_evb_devices,
ARRAY_SIZE(msm8625_evb_devices));
platform_add_devices(qrd3_devices,
ARRAY_SIZE(qrd3_devices));
- } else {
+ }
+ else {
platform_add_devices(qrd7627a_devices,
ARRAY_SIZE(qrd7627a_devices));
}
- if (machine_is_msm8625_evb() || machine_is_msm8625_evt())
- platform_add_devices(msm8625_lcd_camera_devices,
- ARRAY_SIZE(msm8625_lcd_camera_devices));
- else if (machine_is_msm8625q_evbd())
- platform_add_devices(msm8625q_lcd_camera_devices,
- ARRAY_SIZE(msm8625q_lcd_camera_devices));
+ if (machine_is_msm8625_evb() || machine_is_msm8625_qrd5())
+ platform_add_devices(msm8625_lcd_camera_devices,
+ ARRAY_SIZE(msm8625_lcd_camera_devices));
+ else if (machine_is_msm8625q_evbd())
+ platform_add_devices(msm8625q_lcd_camera_devices,
+ ARRAY_SIZE(msm8625q_lcd_camera_devices));
if (machine_is_msm7627a_qrd3() || machine_is_msm7627a_evb())
platform_add_devices(qrd3_devices,
ARRAY_SIZE(qrd3_devices));
-
platform_add_devices(common_devices,
ARRAY_SIZE(common_devices));
}
@@ -1235,15 +1290,15 @@ static void __init msm_qrd_init(void)
msm_pm_register_irqs();
msm_fb_add_devices();
- if (machine_is_qrd_skud_prime() || machine_is_msm8625q_evbd()
- || machine_is_msm8625q_skud())
+ if (machine_is_msm8625q_evbd() || machine_is_msm8625q_skud()
+ || machine_is_msm8625q_skue())
i2c_register_board_info(2, i2c2_info,
ARRAY_SIZE(i2c2_info));
#if defined(CONFIG_BT) && defined(CONFIG_MARIMBA_CORE)
msm7627a_bt_power_init();
#endif
-
+ msm7627a_sensor_init();
msm7627a_camera_init();
qrd7627a_add_io_devices();
msm7x25a_kgsl_3d0_init();
@@ -1255,6 +1310,68 @@ static void __init qrd7627a_init_early(void)
msm_msm7627a_allocate_memory_regions();
}
+#ifdef CONFIG_MSM_AMSS_ENHANCE_DEBUG
+#define TASK_OFFSET_SEND(member, name) \
+ do { \
+ input.extension.len = 2; \
+ input.extension.data[0] = (uint32_t)TASK_STRUCT_TAG; \
+ input.extension.data[1] = offsetof(struct task_struct, member); \
+ input.address = (uint32_t)__virt_to_phys((unsigned long)&init_task); \
+ input.size = sizeof(struct task_struct); \
+ strncpy(input.file_name, name, NZI_ITEM_FILE_NAME_LENGTH); \
+ input.file_name[NZI_ITEM_FILE_NAME_LENGTH - 1] = 0; \
+ send_modem_logaddr(&input); \
+ } while (0)
+
+static int __init qrd7627a_logbuf_init(void)
+{
+ nzi_buf_item_type input;
+ extern char __log_buf[];
+ extern unsigned long totalram_pages;
+ extern atomic_long_t vm_stat[];
+
+#ifdef CONFIG_PRINTK
+ /* send the kernel log address */
+ input.extension.len = 0;
+ input.address = (uint32_t)__virt_to_phys((unsigned long)__log_buf);
+ input.size = (1 << CONFIG_LOG_BUF_SHIFT);
+ strncpy(input.file_name, "dmesg", NZI_ITEM_FILE_NAME_LENGTH);
+ input.file_name[NZI_ITEM_FILE_NAME_LENGTH - 1] = 0;
+ send_modem_logaddr(&input);
+#endif
+
+ /* ******struct task_struct part ******/
+ TASK_OFFSET_SEND(tasks, "tasks_of");
+ TASK_OFFSET_SEND(thread_group, "tg_of");
+ TASK_OFFSET_SEND(mm, "mm_of");
+ TASK_OFFSET_SEND(comm, "comm_of");
+ TASK_OFFSET_SEND(pid, "pid_of");
+ TASK_OFFSET_SEND(tgid, "tgid_of");
+ /* ******struct task_struct end ******/
+
+ /* totalram_pages */
+ input.extension.len = 1;
+ input.extension.data[0] = (uint32_t)MEM_INFO_TAG;
+ input.address = (uint32_t)__virt_to_phys((unsigned long)&totalram_pages);
+ input.size = sizeof(totalram_pages);
+ strncpy(input.file_name, "totalram", NZI_ITEM_FILE_NAME_LENGTH);
+ input.file_name[NZI_ITEM_FILE_NAME_LENGTH - 1] = 0;
+ send_modem_logaddr(&input);
+
+ /* vm_stat[vm_stat[NR_VM_ZONE_STAT_ITEMS]; */
+ input.extension.len = 1;
+ input.extension.data[0] = (uint32_t)MEM_INFO_TAG;
+ input.address = (uint32_t)__virt_to_phys((unsigned long)vm_stat);
+ input.size = sizeof(vm_stat);
+ strncpy(input.file_name, "vm_stat", NZI_ITEM_FILE_NAME_LENGTH);
+ input.file_name[NZI_ITEM_FILE_NAME_LENGTH - 1] = 0;
+ send_modem_logaddr(&input);
+
+ return 0;
+}
+late_initcall(qrd7627a_logbuf_init);
+#endif
+
MACHINE_START(MSM7627A_QRD1, "QRD MSM7627a QRD1")
.atag_offset = 0x100,
.map_io = msm_common_io_init,
@@ -1295,6 +1412,18 @@ MACHINE_START(MSM8625_EVB, "QRD MSM8625 EVB")
.init_early = qrd7627a_init_early,
.handle_irq = gic_handle_irq,
MACHINE_END
+
+MACHINE_START(MSM7X27A_QRD5A, "QRD MSM7x27A QRD5A")
+ .atag_offset = 0x100,
+ .map_io = msm_common_io_init,
+ .reserve = msm7627a_reserve,
+ .init_irq = msm_init_irq,
+ .init_machine = msm_qrd_init,
+ .timer = &msm_timer,
+ .init_early = qrd7627a_init_early,
+ .handle_irq = vic_handle_irq,
+MACHINE_END
+
MACHINE_START(MSM8625_QRD7, "QRD MSM8625 QRD7")
.atag_offset = 0x100,
.map_io = msm8625_map_io,
@@ -1305,7 +1434,7 @@ MACHINE_START(MSM8625_QRD7, "QRD MSM8625 QRD7")
.init_early = qrd7627a_init_early,
.handle_irq = gic_handle_irq,
MACHINE_END
-MACHINE_START(MSM8625_EVT, "QRD MSM8625 EVT")
+MACHINE_START(MSM8625_QRD5, "QRD MSM8625 QRD5")
.atag_offset = 0x100,
.map_io = msm8625_map_io,
.reserve = msm8625_reserve,
@@ -1315,7 +1444,8 @@ MACHINE_START(MSM8625_EVT, "QRD MSM8625 EVT")
.init_early = qrd7627a_init_early,
.handle_irq = gic_handle_irq,
MACHINE_END
-MACHINE_START(QRD_SKUD_PRIME, "QRD MSM8625 SKUD PRIME")
+
+MACHINE_START(MSM8625Q_EVBD, "QRD MSM8625Q EVBD")
.atag_offset = 0x100,
.map_io = msm8625_map_io,
.reserve = msm8625_reserve,
@@ -1325,7 +1455,7 @@ MACHINE_START(QRD_SKUD_PRIME, "QRD MSM8625 SKUD PRIME")
.init_early = qrd7627a_init_early,
.handle_irq = gic_handle_irq,
MACHINE_END
-MACHINE_START(MSM8625Q_EVBD, "QRD MSM8625Q EVBD")
+MACHINE_START(MSM8625Q_SKUD, "QRD MSM8625Q SKUD")
.atag_offset = 0x100,
.map_io = msm8625_map_io,
.reserve = msm8625_reserve,
@@ -1335,7 +1465,8 @@ MACHINE_START(MSM8625Q_EVBD, "QRD MSM8625Q EVBD")
.init_early = qrd7627a_init_early,
.handle_irq = gic_handle_irq,
MACHINE_END
-MACHINE_START(MSM8625Q_SKUD, "QRD MSM8625Q SKUD")
+
+MACHINE_START(MSM8625Q_SKUE, "QRD MSM8625Q SKUE")
.atag_offset = 0x100,
.map_io = msm8625_map_io,
.reserve = msm8625_reserve,
diff --git a/arch/arm/mach-msm/board-qsd8x50.c b/arch/arm/mach-msm/board-qsd8x50.c
index 5954e49..8673fb4 100644
--- a/arch/arm/mach-msm/board-qsd8x50.c
+++ b/arch/arm/mach-msm/board-qsd8x50.c
@@ -195,7 +195,7 @@ static struct android_usb_product usb_products[] = {
static struct usb_mass_storage_platform_data mass_storage_pdata = {
.nluns = 1,
- .vendor = "Qualcomm Incorporated",
+ .vendor = "Qualcomm Technologies, Inc.",
.product = "Mass storage",
.release = 0x0100,
};
@@ -211,7 +211,7 @@ static struct platform_device usb_mass_storage_device = {
static struct usb_ether_platform_data rndis_pdata = {
/* ethaddr is filled by board_serialno_setup */
.vendorID = 0x05C6,
- .vendorDescr = "Qualcomm Incorporated",
+ .vendorDescr = "Qualcomm Technologies, Inc.",
};
static struct platform_device rndis_device = {
@@ -227,7 +227,7 @@ static struct android_usb_platform_data android_usb_pdata = {
.product_id = 0x9026,
.version = 0x0100,
.product_name = "Qualcomm HSUSB Device",
- .manufacturer_name = "Qualcomm Incorporated",
+ .manufacturer_name = "Qualcomm Technologies, Inc.",
.num_products = ARRAY_SIZE(usb_products),
.products = usb_products,
.num_functions = ARRAY_SIZE(usb_functions_all),
@@ -378,7 +378,7 @@ static struct msm_hsusb_platform_data msm_hsusb_pdata = {
.vendor_id = 0x5c6,
.product_name = "Qualcomm HSUSB Device",
.serial_number = "1234567890ABCDEF",
- .manufacturer_name = "Qualcomm Incorporated",
+ .manufacturer_name = "Qualcomm Technologies, Inc.",
.compositions = usb_func_composition,
.num_compositions = ARRAY_SIZE(usb_func_composition),
.function_map = usb_functions_map,
diff --git a/arch/arm/mach-msm/cache-ops.h b/arch/arm/mach-msm/cache-ops.h
new file mode 100644
index 0000000..b63871c
--- /dev/null
+++ b/arch/arm/mach-msm/cache-ops.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+#ifndef __CACHE_NOSYNC_H
+#define __CACHE_NOSYNC_H
+
+#if defined(CONFIG_CPU_V7)
+/*
+ * dcache_line_size - get the minimum D-cache line size from the CTR register
+ * on ARMv7.
+ */
+#define get_dcache_line_size(size) \
+ do { \
+ unsigned long temp; \
+ __asm__ __volatile__ ( \
+ "mrc p15, 0, %0, c0, c0, 1\n\t" \
+ "lsr %0, %0, #16\n\t" \
+ "and %0, %0, #0xf\n\t" \
+ "mov %1, #4\n\t" \
+ "mov %1, %1, lsl %0\n\t" \
+ : "=&r" (temp), "=r" (size) \
+ : : "cc"); \
+ } while (0)
+
+
+#define cache_clean_nosync(start, end, cachesize) \
+ do { \
+ unsigned long temp; \
+ __asm__ __volatile__ ( \
+ "sub %0, %3, #1\n\t" \
+ "bic %1, %1, %0\n\t" \
+ "1:\n\t" \
+ "mcr p15, 0, %1, c7, c10, 1\n\t" \
+ "add %1, %1, %3\n\t" \
+ "cmp %1, %2\n\t" \
+ "blo 1b\n\t" \
+ "dsb\n\t" \
+ : "=&r" (temp) \
+ : "r" (start), "r" (end), "r" (cachesize) \
+ : "cc", "memory"); \
+ } while (0)
+
+/* XXX: Is it safe to remove dsb? since later it will flush L2 cache */
+#define cache_clean_nosync_oneline(start, cachesize) \
+ do { \
+ unsigned long temp; \
+ __asm__ __volatile__ ( \
+ "sub %0, %2, #1\n\t" \
+ "bic %1, %1, %0\n\t" \
+ "mcr p15, 0, %1, c7, c10, 1\n\t" \
+ "dsb\n\t" \
+ : "=&r" (temp) \
+ : "r" (start), "r" (cachesize) \
+ : "cc", "memory"); \
+ } while (0)
+
+
+#elif defined(CONFIG_CPU_V6)
+
+#else
+#error "not supported the ARCH other than V6, V7"
+#endif
+
+#endif
diff --git a/arch/arm/mach-msm/clock-debug.c b/arch/arm/mach-msm/clock-debug.c
index 4cabb31..493372a 100644
--- a/arch/arm/mach-msm/clock-debug.c
+++ b/arch/arm/mach-msm/clock-debug.c
@@ -24,6 +24,10 @@
#include "clock.h"
+#ifdef CONFIG_MSM_SM_EVENT
+#include <linux/sm_event.h>
+#include <linux/sm_event_log.h>
+#endif
static int clock_debug_rate_set(void *data, u64 val)
{
struct clk *clock = data;
@@ -194,6 +198,20 @@ void clock_debug_print_enabled(void)
unsigned i;
int cnt = 0;
+#ifdef CONFIG_MSM_SM_EVENT
+ struct clk *clk;
+ for (i = 0; i < num_msm_clocks; i++) {
+ clk = msm_clocks[i].clk;
+
+ if (clk && clk->ops->is_enabled(clk)) {
+ // pr_info("\t%s\n", clk->dbg_name);
+ sm_add_event(SM_CLOCK_EVENT | SM_CLK_EVENT_SET_ENABLE, 0, 0, (void *)clk->dbg_name, strlen(clk->dbg_name)+1);
+ cnt++;
+ }
+ }
+
+#endif
+
if (likely(!debug_suspend))
return;
diff --git a/arch/arm/mach-msm/clock-pcom-lookup.c b/arch/arm/mach-msm/clock-pcom-lookup.c
old mode 100644
new mode 100755
index 61fa9a2..dbee282
--- a/arch/arm/mach-msm/clock-pcom-lookup.c
+++ b/arch/arm/mach-msm/clock-pcom-lookup.c
@@ -323,6 +323,19 @@ static struct clk_lookup msm_cmn_clk_7625a_7627a[] __initdata = {
CLK_LOOKUP("cam_clk", cam_m_clk.c, "0-006c"),
CLK_LOOKUP("cam_clk", cam_m_clk.c, "0-000d"),
CLK_LOOKUP("cam_clk", cam_m_clk.c, "0-0042"),
+ CLK_LOOKUP("cam_clk", cam_m_clk.c, "0-0064"),
+ CLK_LOOKUP("cam_clk", cam_m_clk.c, "0-0062"),
+
+ CLK_LOOKUP("cam_clk", cam_m_clk.c, "0-003c"),// lwl modify for sk5ca
+ CLK_LOOKUP("cam_clk", cam_m_clk.c, "0-002d"),// lwl modify for sk5ca
+ CLK_LOOKUP("cam_clk", cam_m_clk.c, "0-0020"),// lwl modify for hi351
+ CLK_LOOKUP("cam_clk", cam_m_clk.c, "0-0040"),// lwl modify for hi351
+ CLK_LOOKUP("cam_clk", cam_m_clk.c, "0-006b"), // [shao.wenqi@byd.com; for combine the ov5647 daling
+ CLK_LOOKUP("cam_clk", cam_m_clk.c, "0-006a"), // [shao.wenqi@byd.com; for combine the ov5647 partron
+ CLK_LOOKUP("cam_clk", cam_m_clk.c, "0-0069"), // [shao.wenqi@byd.com; for combine the ov5647 huaquan
+
+ CLK_LOOKUP("cam_clk", cam_m_clk.c, "0-0032"),
+ CLK_LOOKUP("cam_clk", cam_m_clk.c, "0-007a"),
CLK_LOOKUP("csi_clk", csi0_clk.c, "msm_camera_ov9726.0"),
CLK_LOOKUP("csi_pclk", csi0_p_clk.c, "msm_camera_ov9726.0"),
CLK_LOOKUP("csi_vfe_clk", csi0_vfe_clk.c, "msm_camera_ov9726.0"),
@@ -332,6 +345,9 @@ static struct clk_lookup msm_cmn_clk_7625a_7627a[] __initdata = {
CLK_LOOKUP("csi_clk", csi0_clk.c, "msm_camera_ov7695.0"),
CLK_LOOKUP("csi_pclk", csi0_p_clk.c, "msm_camera_ov7695.0"),
CLK_LOOKUP("csi_vfe_clk", csi0_vfe_clk.c, "msm_camera_ov7695.0"),
+ CLK_LOOKUP("csi_clk", csi0_clk.c, "msm_camera_mt9v115.0"),
+ CLK_LOOKUP("csi_pclk", csi0_p_clk.c, "msm_camera_mt9v115.0"),
+ CLK_LOOKUP("csi_vfe_clk", csi0_vfe_clk.c, "msm_camera_mt9v115.0"),
CLK_LOOKUP("csi_clk", csi1_clk.c, NULL),
CLK_LOOKUP("csi_pclk", csi1_p_clk.c, NULL),
CLK_LOOKUP("csi_vfe_clk", csi1_vfe_clk.c, NULL),
diff --git a/arch/arm/mach-msm/devices-msm7x27a.c b/arch/arm/mach-msm/devices-msm7x27a.c
old mode 100644
new mode 100755
index 6bb8146..789f3b2b
--- a/arch/arm/mach-msm/devices-msm7x27a.c
+++ b/arch/arm/mach-msm/devices-msm7x27a.c
@@ -30,6 +30,9 @@
#include <asm/cacheflush.h>
#include <mach/rpc_hsusb.h>
#include <mach/socinfo.h>
+#include <linux/seq_file.h>
+#include <linux/proc_fs.h>
+#include <linux/module.h>
#include "devices.h"
#include "devices-msm7x2xa.h"
@@ -932,9 +935,9 @@ static struct kgsl_device_platform_data kgsl_3d0_pdata = {
.init_level = 0,
.num_levels = 3,
.set_grp_async = set_grp_xbar_async,
- .idle_timeout = HZ,
- .strtstp_sleepwake = true,
- .nap_allowed = false,
+ .idle_timeout = HZ*5,
+ .strtstp_sleepwake = false,
+ .nap_allowed = true,
.clk_map = KGSL_CLK_CORE | KGSL_CLK_IFACE | KGSL_CLK_MEM,
};
@@ -1211,6 +1214,18 @@ static struct resource gsbi0_msm8625_qup_resources[] = {
.end = MSM8625_INT_PWB_I2C,
.flags = IORESOURCE_IRQ,
},
+ {
+ .name = "i2c_clk",
+ .start = 60,
+ .end = 60,
+ .flags = IORESOURCE_IO,
+ },
+ {
+ .name = "i2c_sda",
+ .start = 61,
+ .end = 61,
+ .flags = IORESOURCE_IO,
+ },
};
/* Use GSBI0 QUP for /dev/i2c-0 */
@@ -1240,13 +1255,25 @@ static struct resource gsbi1_msm8625_qup_i2c_resources[] = {
.end = MSM8625_INT_ARM11_DMA,
.flags = IORESOURCE_IRQ,
},
+ {
+ .name = "i2c_clk",
+ .start = 131,
+ .end = 131,
+ .flags = IORESOURCE_IO,
+ },
+ {
+ .name = "i2c_sda",
+ .start = 132,
+ .end = 132,
+ .flags = IORESOURCE_IO,
+ },
};
/* Use GSBI1 QUP for /dev/i2c-1 */
struct platform_device msm8625_gsbi1_qup_i2c_device = {
.name = "qup_i2c",
.id = MSM_GSBI1_QUP_I2C_BUS_ID,
- .num_resources = ARRAY_SIZE(gsbi1_qup_i2c_resources),
+ .num_resources = ARRAY_SIZE(gsbi1_msm8625_qup_i2c_resources),
.resource = gsbi1_msm8625_qup_i2c_resources,
};
@@ -1666,7 +1693,7 @@ static struct resource pl310_resources[] = {
},
{
.name = "l2_irq",
- .start = MSM8625_INT_L2CC_INTR,
+ .start = MSM8625_INT_SC_SICL2PERFMONIRPTREQ,
.flags = IORESOURCE_IRQ,
},
};
@@ -1704,8 +1731,6 @@ static int __init msm8625_cpu_id(void)
case 0x774:
case 0x781:
case 0x8D1:
- case 0x8E0:
- case 0x8E1:
cpu = MSM8625A;
break;
case 0x775:
@@ -1818,6 +1843,7 @@ static struct msm_cpr_config msm_cpr_pdata = {
.cpr_mode_data = &msm_cpr_mode_data,
.tgt_count_div_N = 1,
.floor = 0,
+ .pvs_fuse = 0,
.ceiling = 40,
.sw_vlevel = 20,
.up_threshold = 1,
@@ -1848,11 +1874,19 @@ static struct platform_device msm8625_vp_device = {
.name = "vp-regulator",
.id = -1,
};
+#if defined(CONFIG_MSM_FUSE_INFO_DEBUG)
+#define FUSE_INFO_LEN 1024
+char msm_fuse_info[FUSE_INFO_LEN];
+#endif
static void __init msm_cpr_init(void)
{
struct cpr_info_type *cpr_info = NULL;
uint8_t ring_osc = 0;
+#if defined(CONFIG_MSM_FUSE_INFO_DEBUG)
+ char tmp_buf[100] = "";
+ uint32_t fuse_len = 0;
+#endif
cpr_info = kzalloc(sizeof(struct cpr_info_type), GFP_KERNEL);
if (!cpr_info) {
@@ -1862,7 +1896,6 @@ static void __init msm_cpr_init(void)
msm_smem_get_cpr_info(cpr_info);
msm_cpr_pdata.disable_cpr = cpr_info->disable_cpr;
- msm_cpr_pdata.pvs_fuse = cpr_info->pvs_fuse;
/**
* Set the ring_osc based on efuse BIT(0)
@@ -1930,7 +1963,6 @@ static void __init msm_cpr_init(void)
pr_info("%s: cpr: turbo_quot: 0x%x\n", __func__, cpr_info->turbo_quot);
pr_info("%s: cpr: pvs_fuse: 0x%x\n", __func__, cpr_info->pvs_fuse);
pr_info("%s: cpr: floor_fuse: 0x%x\n", __func__, cpr_info->floor_fuse);
- kfree(cpr_info);
if ((msm8625_cpu_id() == MSM8625A) || cpu_is_msm8625q())
msm_cpr_pdata.max_freq = 1209600;
@@ -1945,6 +1977,35 @@ static void __init msm_cpr_init(void)
pr_info("%s: cpr: nom_Vmax: %d, turbo_Vmax: %d\n", __func__,
msm_cpr_mode_data.nom_Vmax,
msm_cpr_mode_data.turbo_Vmax);
+#if defined(CONFIG_MSM_FUSE_INFO_DEBUG)
+ memset(msm_fuse_info, FUSE_INFO_LEN, 0);
+ fuse_len += sprintf(tmp_buf, "MSM_FUSE_TAG : ");
+ if(fuse_len < FUSE_INFO_LEN)
+ strcat(msm_fuse_info, tmp_buf);
+ fuse_len += sprintf(tmp_buf, socinfo_buf);
+ if(fuse_len < FUSE_INFO_LEN)
+ strcat(msm_fuse_info, tmp_buf);
+ fuse_len += sprintf(tmp_buf, "cpr: ring_osc: 0x%x ",msm_cpr_mode_data.ring_osc);
+ if(fuse_len < FUSE_INFO_LEN)
+ strcat(msm_fuse_info, tmp_buf);
+ fuse_len += sprintf(tmp_buf, "cpr: turbo_quot: 0x%x ", cpr_info->turbo_quot);
+ if(fuse_len < FUSE_INFO_LEN)
+ strcat(msm_fuse_info, tmp_buf);
+ fuse_len += sprintf(tmp_buf, "cpr: floor_fuse: 0x%x ", cpr_info->floor_fuse);
+ if(fuse_len < FUSE_INFO_LEN)
+ strcat(msm_fuse_info, tmp_buf);
+ fuse_len += sprintf(tmp_buf, "cpr: pvs_fuse: 0x%x ", cpr_info->pvs_fuse);
+ if(fuse_len < FUSE_INFO_LEN)
+ strcat(msm_fuse_info, tmp_buf);
+ fuse_len += sprintf(tmp_buf, "cpr: nom_Vmin: %d, turbo_Vmin: %d", msm_cpr_mode_data.nom_Vmin, msm_cpr_mode_data.turbo_Vmin);
+ if(fuse_len < FUSE_INFO_LEN)
+ strcat(msm_fuse_info, tmp_buf);
+#endif
+
+ /*add this for debug the phone is which type*/
+ msm_cpr_pdata.pvs_fuse = cpr_info->pvs_fuse;
+ msm_cpr_pdata.floor = cpr_info->floor_fuse;
+ kfree(cpr_info);
if (cpu_is_msm8625())
platform_device_register(&msm8625_vp_device);
@@ -1952,6 +2013,47 @@ static void __init msm_cpr_init(void)
platform_device_register(&msm8625_device_cpr);
}
+#if defined(CONFIG_MSM_FUSE_INFO_DEBUG)
+#ifdef CONFIG_PROC_FS
+/*
+ * read /proc/fuseinfo to get some info about msm8x25 chip
+ */
+static int msm_fuse_proc_show(struct seq_file *m, void *v)
+{
+ seq_write(m, msm_fuse_info, strlen(msm_fuse_info));
+ return 0;
+}
+
+static int msm_fuse_proc_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, msm_fuse_proc_show, NULL);
+}
+
+static const struct file_operations proc_msm_fuse_operations = {
+ .owner = THIS_MODULE,
+ .open = msm_fuse_proc_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+
+};
+
+static void fuse_init_procfs(void)
+{
+ if (!proc_create("fuseinfo", S_IRUSR, NULL,
+ &proc_msm_fuse_operations))
+ pr_err("Failed to register fuse proc interface\n");
+}
+
+#else
+
+static inline void fuse_init_procfs(void)
+{
+}
+
+#endif /* CONFIG_PROC_FS */
+#endif
+
static struct resource pbus_resources[] = {
{
.name = "pbus_phys_addr",
@@ -2105,7 +2207,13 @@ static int __init msm_acpuclock_init(bool flag)
msm8625q_acpuclk_pdata.flag = flag;
return 0;
}
+#ifdef CONFIG_GLANCEVIEW
+struct platform_device glanceview_device = {
+ .name = "glanceview",
+ .id = -1,
+};
+#endif
int __init msm7x2x_misc_init(void)
{
if (machine_is_msm8625_rumi3()) {
@@ -2122,11 +2230,11 @@ int __init msm7x2x_misc_init(void)
msm_acpuclock_init(1);
platform_device_register(&msm8625q_device_acpuclk);
} else if (cpu_is_msm8625()) {
-
- if (machine_is_qrd_skud_prime()) {
- msm_acpuclock_init(0);
- platform_device_register(&msm8625q_device_acpuclk);
- } else if (msm8625_cpu_id() == MSM8625)
+ //if (machine_is_msm8625q_skud()) {
+ // msm_acpuclock_init(0);
+ // platform_device_register(&msm8625q_device_acpuclk);
+ //} else
+ if (msm8625_cpu_id() == MSM8625)
platform_device_register(&msm7x27aa_device_acpuclk);
else if (msm8625_cpu_id() == MSM8625A)
platform_device_register(&msm8625_device_acpuclk);
@@ -2146,13 +2254,20 @@ int __init msm7x2x_misc_init(void)
msm_cpr_init();
if (!cpu_is_msm8625() && !cpu_is_msm8625q())
- pl310_resources[1].start = INT_L2CC_INTR;
+ pl310_resources[1].start = SC_SICL2PERFMONIRPTREQ;
platform_device_register(&pl310_erp_device);
+#if defined(CONFIG_MSM_FUSE_INFO_DEBUG)
+ fuse_init_procfs();
+#endif
+
msm_pbus_init();
if (msm_gpio_config_gps() < 0)
pr_err("Error for gpio config for GPS gpio\n");
+#ifdef CONFIG_GLANCEVIEW
+ platform_device_register(&glanceview_device);
+#endif
return 0;
}
diff --git a/arch/arm/mach-msm/dma_test.c b/arch/arm/mach-msm/dma_test.c
index 3d13e4e..93c0794 100644
--- a/arch/arm/mach-msm/dma_test.c
+++ b/arch/arm/mach-msm/dma_test.c
@@ -352,7 +352,7 @@ static void dma_test_exit(void)
}
MODULE_LICENSE("GPL v2");
-MODULE_AUTHOR("David Brown, Qualcomm, Incorporated");
+MODULE_AUTHOR("David Brown, Qualcomm Technologies, Inc.");
MODULE_DESCRIPTION("Test for MSM DMA driver");
MODULE_VERSION("1.01");
diff --git a/arch/arm/mach-msm/enhance-debug.c b/arch/arm/mach-msm/enhance-debug.c
new file mode 100644
index 0000000..c13020d
--- /dev/null
+++ b/arch/arm/mach-msm/enhance-debug.c
@@ -0,0 +1,53 @@
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/string.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/err.h>
+#include <mach/oem_rapi_client.h>
+
+static struct msm_rpc_client *client = NULL;
+
+int send_modem_logaddr(nzi_buf_item_type *input)
+{
+ int ret;
+
+ struct oem_rapi_client_streaming_func_arg client_arg = {
+ OEM_RAPI_CLIENT_EVENT_QRDCOMPACTDUMP_NZIITEM_WRITE,
+ NULL,
+ (void *)NULL,
+ sizeof(*input),
+ (void *)input,
+ 0,
+ 0,
+ 0
+ };
+ struct oem_rapi_client_streaming_func_ret client_ret = {
+ (uint32_t *)NULL,
+ (char *)NULL
+ };
+
+ if (client == NULL) {
+ client = oem_rapi_client_init();
+ if (IS_ERR(client) || (!client)) {
+ client = NULL;
+ return -ENODEV;
+ }
+ }
+
+ ret = oem_rapi_client_streaming_function(client, &client_arg, &client_ret);
+
+ return ret;
+}
+EXPORT_SYMBOL(send_modem_logaddr);
diff --git a/arch/arm/mach-msm/fastboot.c b/arch/arm/mach-msm/fastboot.c
new file mode 100644
index 0000000..44c779f
--- /dev/null
+++ b/arch/arm/mach-msm/fastboot.c
@@ -0,0 +1,326 @@
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/err.h>
+#include <linux/slab.h>
+#include <linux/io.h>
+#include <linux/mutex.h>
+#include <linux/miscdevice.h>
+#include <linux/fs.h>
+#include <linux/kernel.h>
+#include <linux/ioctl.h>
+#include <linux/delay.h>
+#include <linux/reboot.h>
+#include <asm/mach-types.h>
+#include <mach/msm_rpcrouter.h>
+#include <mach/pmic.h>
+#include <mach/oem_rapi_client.h>
+#if defined(CONFIG_HAS_EARLYSUSPEND)
+#include <linux/earlysuspend.h>
+#endif
+/**
+ * fastboot_rpc_req_reply() - send request and wait for reply
+ * @tbuf: buffer contains arguments
+ * @rbuf: buffer to be filled with arguments at reply
+ * @proc: command/request id
+ *
+ * This function send request to modem and wait until reply received
+ */
+#define FASTBOOT_RPC_PROG 0x30000061
+#define FASTBOOT_RPC_PROG_START 0x00000010
+#define FASTBOOT_RPC_PROG_STOP 0x00000010
+
+#define FASTBOOT_RPC_VER_1_1 0x00010001
+#define FASTBOOT_RPC_VER_2_1 0x00020001
+#define FASTBOOT_RPC_VER_3_1 0x00030001
+#define FASTBOOT_RPC_VER_5_1 0x00050001
+#define FASTBOOT_RPC_VER_6_1 0x00060001
+
+#define FASTBOOT_RPC_TIMEOUT (5*HZ)
+#define FASTBOOT_BUFF_SIZE 64
+
+#define FB_ERR_FLAG__FEATURE_NOT_SUPPORTED (0x001F)
+
+typedef enum
+{
+ FAST_PWROFF_NONE,
+ FAST_PWROFF_ON,
+ FAST_PWROFF_LCDOFF,
+ FAST_PWROFF_OK,
+}FAST_PWROFF_STATUS;
+
+#define OEM_RAPI_CLIENT_EVENT_FAST_POWERON_REG_SET 32
+#define OEM_RAPI_CLIENT_EVENT_FAST_POWEROFF_REG_SET 33
+
+struct fastboot_buf {
+ char *start; /* buffer start addr */
+ char *end; /* buffer end addr */
+ int size; /* buffer size */
+ char *data; /* payload begin addr */
+ int len; /* payload len */
+};
+
+struct fastboot_ctrl {
+ struct fastboot_buf tbuf;
+ struct fastboot_buf rbuf;
+ struct msm_rpc_endpoint *endpoint;
+};
+
+struct fastboot_data {
+ unsigned long state;
+ unsigned long enabled;
+ struct fastboot_ctrl fb_ctrl;
+ struct device *dev;
+ struct mutex lock;
+#if defined(CONFIG_HAS_EARLYSUSPEND)
+ struct early_suspend early_suspend;
+#endif
+} *global_data = NULL;
+
+static DEFINE_MUTEX(fastboot_mtx);
+
+static ssize_t fastboot_start_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct fastboot_data *fb_data = dev_get_drvdata(dev);
+
+ return snprintf(buf, PAGE_SIZE, "%lu\n",
+ fb_data->state);
+}
+
+static int fastboot_send_rpc(char *input)
+{
+ int ret;
+ struct msm_rpc_client *client = NULL;
+
+ struct oem_rapi_client_streaming_func_arg client_arg = {
+ OEM_RAPI_CLIENT_EVENT_FAST_POWEROFF_REG_SET,
+ NULL,
+ (void *)NULL,
+ 1,
+ input,
+ 0,
+ 0,
+ 0
+ };
+
+ struct oem_rapi_client_streaming_func_ret client_ret = {
+ (uint32_t *)NULL,
+ (char *)NULL
+ };
+
+ printk("%s, %d\n", __func__,(int)input[0] );
+ client = oem_rapi_client_init();
+ if (IS_ERR(client) || (!client)) {
+ client = NULL;
+ printk(KERN_ERR
+ "oem_rapi_client_init() error\n");
+ return -ENODEV;
+ }
+
+ ret = oem_rapi_client_streaming_function(client, &client_arg, &client_ret);
+ if (ret)
+ printk(KERN_ERR
+ "oem_rapi_client_streaming_function() error=%d\n", ret);
+
+ return ret;
+}
+
+int fastboot_enabled(void)
+{
+ return global_data && global_data->enabled;
+}
+EXPORT_SYMBOL(fastboot_enabled);
+
+void fastboot_usb_callback(void)
+{
+ char *envp[2] = {"FASTBOOT_MSG=usb", NULL};
+
+ if (global_data)
+ kobject_uevent_env(&global_data->dev->kobj, KOBJ_CHANGE, envp);
+}
+EXPORT_SYMBOL(fastboot_usb_callback);
+
+extern void msm_otg_turn_on_usb(int on);
+static ssize_t fastboot_start_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf,
+ size_t n)
+{
+ unsigned long tmp;
+ char rpc_arg;
+ struct fastboot_data *fb_data = dev_get_drvdata(dev);
+
+ if (!strict_strtoul(buf, 10, &tmp)) {
+ mutex_lock(&fb_data->lock);
+ if (tmp == 1) {
+ rpc_arg = FAST_PWROFF_ON;
+ fastboot_send_rpc(&rpc_arg);
+ fb_data->state = 1;
+ }
+ else {
+ rpc_arg = FAST_PWROFF_NONE;
+ fastboot_send_rpc(&rpc_arg);
+ fb_data->state = 0;
+ }
+ mutex_unlock(&fb_data->lock);
+ return n;
+ } else {
+ pr_err("%s: unable to convert: %s to an int\n", __func__,
+ buf);
+ return -EINVAL;
+ }
+}
+
+static DEVICE_ATTR(fastboot, 0664, fastboot_start_show, fastboot_start_store);
+
+static struct attribute *fastboot_sysfs_attrs[] = {
+ &dev_attr_fastboot.attr,
+ NULL
+};
+
+static struct attribute_group fastboot_attribute_group = {
+ .attrs = fastboot_sysfs_attrs,
+};
+
+#ifdef CONFIG_HAS_EARLYSUSPEND
+static void fastboot_early_suspend(struct early_suspend *h)
+{
+ struct fastboot_data *fb_data = container_of(h, struct fastboot_data, early_suspend);
+ char rpc_arg;
+
+ if (fb_data->state) {
+ rpc_arg = FAST_PWROFF_LCDOFF;
+ fastboot_send_rpc(&rpc_arg);
+ usleep(10000);
+ fb_data->enabled = 1;
+ rpc_arg = FAST_PWROFF_OK;
+ fastboot_send_rpc(&rpc_arg);
+ }
+}
+
+static void fastboot_late_resume(struct early_suspend *h)
+{
+ struct fastboot_data *fb_data = container_of(h, struct fastboot_data, early_suspend);
+ char *envp[2] = {"FASTBOOT_MSG=resume", NULL};
+
+ if (fb_data->state) {
+ kobject_uevent_env(&fb_data->dev->kobj, KOBJ_CHANGE, envp);
+ fb_data->enabled = 0;
+ }
+}
+#endif
+
+static int __devinit fastboot_probe(struct platform_device *pdev)
+{
+ struct fastboot_data *fb_data = NULL;
+ int ret;
+
+ global_data = fb_data = kmalloc(sizeof(struct fastboot_data), GFP_KERNEL);
+ if (!fb_data) {
+ ret = -ENODEV;
+ goto fail_mem;
+ }
+ ret = sysfs_create_group(&pdev->dev.kobj,
+ &fastboot_attribute_group);
+ if (ret) {
+ pr_err("%s: could not create sysfs group\n", __func__);
+ ret = -EBUSY;
+ goto fail_sysfs;
+ }
+
+ mutex_init(&fb_data->lock);
+ //clear this addr
+ fb_data->state = 0;
+ fb_data->enabled = 0;
+ fb_data->dev = &pdev->dev;
+ platform_set_drvdata(pdev, fb_data);
+
+#ifdef CONFIG_HAS_EARLYSUSPEND
+ fb_data->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN;
+ fb_data->early_suspend.suspend = fastboot_early_suspend;
+ fb_data->early_suspend.resume = fastboot_late_resume;
+ register_early_suspend(&fb_data->early_suspend);
+#endif
+ return 0;
+
+fail_sysfs:
+ kfree(fb_data);
+fail_mem:
+ return ret;
+}
+
+static int __devexit fastboot_remove(struct platform_device *pdev)
+{
+ struct fastboot_data *fb_data = platform_get_drvdata(pdev);
+
+#ifdef CONFIG_HAS_EARLYSUSPEND
+ unregister_early_suspend(&fb_data->early_suspend);
+#endif
+ sysfs_remove_group(&pdev->dev.kobj, &fastboot_attribute_group);
+ kfree(fb_data);
+
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int
+fastboot_suspend(struct device *dev)
+{
+ return 0;
+}
+
+static int
+fastboot_resume(struct device *dev)
+{
+ return 0;
+}
+
+static struct dev_pm_ops fastboot_pm_ops = {
+ .suspend = fastboot_suspend,
+ .resume = fastboot_resume,
+};
+#endif
+
+static struct platform_driver fastboot_driver = {
+ .probe = fastboot_probe,
+ .remove = fastboot_remove,
+ .driver = {
+ .name = "fastboot",
+ .owner = THIS_MODULE,
+#ifdef CONFIG_PM
+ .pm = &fastboot_pm_ops,
+#endif
+ },
+};
+
+static int __init fastboot_init(void)
+{
+ return platform_driver_register(&fastboot_driver);
+}
+
+static void __exit fastboot_exit(void)
+{
+ platform_driver_unregister(&fastboot_driver);
+}
+
+module_init(fastboot_init);
+module_exit(fastboot_exit);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("msm fastboot driver");
+MODULE_VERSION("1.0");
+MODULE_ALIAS("fastboot");
diff --git a/arch/arm/mach-msm/gpiomux.c b/arch/arm/mach-msm/gpiomux.c
old mode 100644
new mode 100755
index 7e46134..3fb69c4
--- a/arch/arm/mach-msm/gpiomux.c
+++ b/arch/arm/mach-msm/gpiomux.c
@@ -31,12 +31,18 @@ int msm_gpiomux_write(unsigned gpio, enum msm_gpiomux_setting which,
unsigned long irq_flags;
struct gpiomux_setting *new_set;
int status = 0;
-
+ /*add QC pathc for MTBF test I2C time */
if (!msm_gpiomux_recs)
+ {
+ pr_err("%s: msm_gpiomux_recs\n", __func__);
return -EFAULT;
+ }
if (gpio >= msm_gpiomux_ngpio)
+ {
+ pr_err("%s: msm_gpiomux_ngpio: %d\n", __func__, msm_gpiomux_ngpio);
return -EINVAL;
+ }
spin_lock_irqsave(&gpiomux_lock, irq_flags);
@@ -56,8 +62,17 @@ int msm_gpiomux_write(unsigned gpio, enum msm_gpiomux_setting which,
new_set = rec->ref ? rec->sets[GPIOMUX_ACTIVE] :
rec->sets[GPIOMUX_SUSPENDED];
+ /*ad QC pathc for MTBF test I2C time */
if (new_set)
+ {
__msm_gpiomux_write(gpio, *new_set);
+ pr_err("%s: __msm_gpiomux_write line64 gpio=%d, rec->ref=%d, func=%d, drv=%d, pull=%d, dir=%d\n", __func__, gpio, rec->ref, new_set->func, new_set->drv, new_set->pull, new_set->dir);
+ }
+ else
+ {
+
+ pr_err("%s: new_set= NULL \n", __func__);
+ }
spin_unlock_irqrestore(&gpiomux_lock, irq_flags);
return status;
@@ -70,11 +85,15 @@ int msm_gpiomux_get(unsigned gpio)
unsigned long irq_flags;
if (!msm_gpiomux_recs)
+ {
+ pr_err("%s: line=%d\n", __func__,__LINE__);
return -EFAULT;
-
+ }
if (gpio >= msm_gpiomux_ngpio)
+ {
+ pr_err("%s: line=%d\n", __func__,__LINE__);
return -EINVAL;
-
+ }
spin_lock_irqsave(&gpiomux_lock, irq_flags);
if (rec->ref++ == 0 && rec->sets[GPIOMUX_ACTIVE])
__msm_gpiomux_write(gpio, *rec->sets[GPIOMUX_ACTIVE]);
@@ -89,11 +108,16 @@ int msm_gpiomux_put(unsigned gpio)
unsigned long irq_flags;
if (!msm_gpiomux_recs)
+ {
+ pr_err("%s: line=%d\n", __func__,__LINE__);
return -EFAULT;
+ }
if (gpio >= msm_gpiomux_ngpio)
+ {
+ pr_err("%s: line=%d\n", __func__,__LINE__);
return -EINVAL;
-
+ }
spin_lock_irqsave(&gpiomux_lock, irq_flags);
BUG_ON(rec->ref == 0);
if (--rec->ref == 0 && rec->sets[GPIOMUX_SUSPENDED])
@@ -107,15 +131,19 @@ int msm_gpiomux_init(size_t ngpio)
{
if (!ngpio)
return -EINVAL;
-
+ /*ad QC pathc for MTBF test I2C time */
if (msm_gpiomux_recs)
+ {
+ pr_err("%s: line=%d\n", __func__,__LINE__);
return -EPERM;
-
+ }
msm_gpiomux_recs = kzalloc(sizeof(struct msm_gpiomux_rec) * ngpio,
GFP_KERNEL);
if (!msm_gpiomux_recs)
+ {
+ pr_err("%s: line=%d\n", __func__,__LINE__);
return -ENOMEM;
-
+ }
/* There is no need to zero this memory, as clients will be blindly
* installing settings on top of it.
*/
diff --git a/arch/arm/mach-msm/idle.c b/arch/arm/mach-msm/idle.c
index 0c9e13c..692fb1f 100644
--- a/arch/arm/mach-msm/idle.c
+++ b/arch/arm/mach-msm/idle.c
@@ -2,7 +2,7 @@
*
* Idle processing for MSM7K - work around bugs with SWFI.
*
- * Copyright (c) 2007 QUALCOMM Incorporated.
+ * Copyright (c) 2007 Qualcomm Technologies, Inc.
* Copyright (C) 2007 Google, Inc.
*
* This software is licensed under the terms of the GNU General Public
diff --git a/arch/arm/mach-msm/include/mach/board.h b/arch/arm/mach-msm/include/mach/board.h
old mode 100644
new mode 100755
index c74b979..2015d53
--- a/arch/arm/mach-msm/include/mach/board.h
+++ b/arch/arm/mach-msm/include/mach/board.h
@@ -1,7 +1,7 @@
/* arch/arm/mach-msm/include/mach/board.h
*
* Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2008-2012, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2008-2012, The Linux Foundation. All Rights Reserved.
* Author: Brian Swetland <swetland@google.com>
*
* This software is licensed under the terms of the GNU General Public
@@ -253,6 +253,12 @@ enum msm_camera_actuator_name {
MSM_ACTUATOR_MAIN_CAM_5,
MSM_ACTUATOR_MAIN_CAM_6,
MSM_ACTUATOR_MAIN_CAM_7,
+ ODMM_MSM_ACTUATOR_MAIN_CAM_DALING_OVBD631AC_5,
+ ODMM_MSM_ACTUATOR_MAIN_CAM_PARTRON_CM500_5,
+ ODMM_MSM_ACTUATOR_MAIN_CAM_HQ_DG806T_5,
+ MSM_ACTUATOR_MAIN_CAM_8,
+ MSM_ACTUATOR_MAIN_CAM_9,
+ MSM_ACTUATOR_MAIN_CAM_10,
MSM_ACTUATOR_WEB_CAM_0,
MSM_ACTUATOR_WEB_CAM_1,
MSM_ACTUATOR_WEB_CAM_2,
diff --git a/arch/arm/mach-msm/include/mach/dma.h b/arch/arm/mach-msm/include/mach/dma.h
index 21bec61..43f7743 100644
--- a/arch/arm/mach-msm/include/mach/dma.h
+++ b/arch/arm/mach-msm/include/mach/dma.h
@@ -229,10 +229,10 @@ int msm_dmov_exec_cmd(unsigned id, unsigned int cmdptr);
#define DMOV_SDC1_CHAN 8
#define DMOV_SDC1_CRCI 6
-#define DMOV_SDC2_CHAN 8
+#define DMOV_SDC2_CHAN 5
#define DMOV_SDC2_CRCI 7
-#define DMOV_SDC3_CHAN 8
+#define DMOV_SDC3_CHAN 7
#define DMOV_SDC3_CRCI 12
#define DMOV_SDC4_CHAN 8
diff --git a/arch/arm/mach-msm/include/mach/irqs-7xxx.h b/arch/arm/mach-msm/include/mach/irqs-7xxx.h
index f4f894d..bff17ac 100644
--- a/arch/arm/mach-msm/include/mach/irqs-7xxx.h
+++ b/arch/arm/mach-msm/include/mach/irqs-7xxx.h
@@ -75,7 +75,7 @@
/* 22-31 are reserved except 7x27a*/
#if defined(CONFIG_ARCH_MSM7X27A)
#define INT_L2CC_EM (32 + 22)
-#define INT_L2CC_INTR (32 + 23)
+#define SC_SICL2PERFMONIRPTREQ (32 + 23)
#define INT_CE_IRQ (32 + 24)
#endif
diff --git a/arch/arm/mach-msm/include/mach/irqs-8625.h b/arch/arm/mach-msm/include/mach/irqs-8625.h
index c9a386f..5367b81 100644
--- a/arch/arm/mach-msm/include/mach/irqs-8625.h
+++ b/arch/arm/mach-msm/include/mach/irqs-8625.h
@@ -27,7 +27,7 @@
#endif
/* As per QGIC2 PPI 16 aka 0 is reserved */
-#define MSM8625_INT_A5_PMU_IRQ (GIC_PPI_START + 1)
+#define MSM8625_INT_ARMQC_PERFMON (GIC_PPI_START + 1)
#define MSM8625_INT_DEBUG_TIMER_EXP (GIC_PPI_START + 2)
#define MSM8625_INT_GP_TIMER_EXP (GIC_PPI_START + 3)
#define MSM8625_INT_COMMRX (GIC_PPI_START + 4)
@@ -92,7 +92,7 @@
#define MSM8625_INT_UART2DM_IRQ (GIC_SPI_START + 32 + 20)
#define MSM8625_INT_UART2DM_RX (GIC_SPI_START + 32 + 21)
#define MSM8625_INT_L2CC_EM (GIC_SPI_START + 32 + 22)
-#define MSM8625_INT_L2CC_INTR (GIC_SPI_START + 32 + 23)
+#define MSM8625_INT_SC_SICL2PERFMONIRPTREQ (GIC_SPI_START + 32 + 23)
#define MSM8625_INT_CE_IRQ (GIC_SPI_START + 32 + 24)
#define MSM8625_INT_CPR_IRQ0 (GIC_SPI_START + 32 + 25)
#define MSM8625_INT_CPR_IRQ1 (GIC_SPI_START + 32 + 26)
diff --git a/arch/arm/mach-msm/include/mach/irqs-9625.h b/arch/arm/mach-msm/include/mach/irqs-9625.h
index 2266140..f81fd59 100644
--- a/arch/arm/mach-msm/include/mach/irqs-9625.h
+++ b/arch/arm/mach-msm/include/mach/irqs-9625.h
@@ -21,6 +21,11 @@
* 32+: SPI (shared peripheral interrupts)
*/
+#define GIC_PPI_START 16
+
+#define INT_ARMQC_PERFMON (GIC_PPI_START + 7)
+
+#define GIC_SPI_START 32
#define APCC_QGICL2PERFMONIRPTREQ (GIC_SPI_START + 1)
#define SC_SICL2PERFMONIRPTREQ APCC_QGICL2PERFMONIRPTREQ
diff --git a/arch/arm/mach-msm/include/mach/msm_battery.h b/arch/arm/mach-msm/include/mach/msm_battery.h
index 959d8a8..5a90ff4 100644
--- a/arch/arm/mach-msm/include/mach/msm_battery.h
+++ b/arch/arm/mach-msm/include/mach/msm_battery.h
@@ -1,30 +1,81 @@
-/* Copyright (c) 2009, The Linux Foundation. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- */
-
#ifndef __MSM_BATTERY_H__
#define __MSM_BATTERY_H__
-#define AC_CHG 0x00000001
-#define USB_CHG 0x00000002
+#define AC_CHG 0x00000001
+#define USB_CHG 0x00000002
+#define UNKNOWN_CHG 0x00000004
struct msm_psy_batt_pdata {
u32 voltage_max_design;
u32 voltage_min_design;
- u32 voltage_fail_safe;
- u32 avail_chg_sources;
u32 batt_technology;
+ u32 avail_chg_sources;
u32 (*calculate_capacity)(u32 voltage);
};
+enum {
+ BATTERY_REGISTRATION_SUCCESSFUL = 0,
+ BATTERY_DEREGISTRATION_SUCCESSFUL = BATTERY_REGISTRATION_SUCCESSFUL,
+ BATTERY_MODIFICATION_SUCCESSFUL = BATTERY_REGISTRATION_SUCCESSFUL,
+ BATTERY_INTERROGATION_SUCCESSFUL = BATTERY_REGISTRATION_SUCCESSFUL,
+ BATTERY_CLIENT_TABLE_FULL = 1,
+ BATTERY_REG_PARAMS_WRONG = 2,
+ BATTERY_DEREGISTRATION_FAILED = 4,
+ BATTERY_MODIFICATION_FAILED = 8,
+ BATTERY_INTERROGATION_FAILED = 16,
+ /* Client's filter could not be set because perhaps it does not exist */
+ BATTERY_SET_FILTER_FAILED = 32,
+ /* Client's could not be found for enabling or disabling the individual
+ * client */
+ BATTERY_ENABLE_DISABLE_INDIVIDUAL_CLIENT_FAILED = 64,
+ BATTERY_LAST_ERROR = 128,
+};
+
+enum {
+ BATTERY_VOLTAGE_UP = 0,
+ BATTERY_VOLTAGE_DOWN,
+ BATTERY_VOLTAGE_ABOVE_THIS_LEVEL,
+ BATTERY_VOLTAGE_BELOW_THIS_LEVEL,
+ BATTERY_VOLTAGE_LEVEL,
+ BATTERY_ALL_ACTIVITY,
+ VBATT_CHG_EVENTS,
+ BATTERY_VOLTAGE_UNKNOWN
+};
+
+enum chg_charger_status_type {
+ CHARGER_STATUS_GOOD,
+ CHARGER_STATUS_WEAK,
+ CHARGER_STATUS_NULL
+};
+
+enum chg_charger_hardware_type {
+ CHARGER_TYPE_USB_PC,
+ CHARGER_TYPE_USB_WALL,
+ CHARGER_TYPE_USB_UNKNOWN,
+ CHARGER_TYPE_USB_CARKIT
+};
+
+enum chg_battery_status_type {
+ BATTERY_STATUS_GOOD,
+ BATTERY_STATUS_OVER_TEMPERATURE,
+ BATTERY_STATUS_NULL
+};
+
+struct msm_batt_gauge {
+ int (*get_battery_mvolts) (void);
+ int (*get_battery_temperature) (void);
+ int (*is_battery_present) (void);
+ int (*is_battery_temp_within_range) (void);
+ int (*is_battery_id_valid) (void);
+ int (*get_battery_status)(void);
+ int (*get_batt_remaining_capacity) (void);
+};
+
+#ifdef CONFIG_MSM_SM_EVENT
+uint32_t msm_batt_get_batt_voltage (void);
+#endif
+int msm_batt_fuel_register(struct msm_batt_gauge* batt);
+void msm_batt_fuel_unregister(struct msm_batt_gauge* batt);
+
#endif
diff --git a/arch/arm/mach-msm/include/mach/msm_hsusb.h b/arch/arm/mach-msm/include/mach/msm_hsusb.h
index 3e2d14d..4bb7f2a 100644
--- a/arch/arm/mach-msm/include/mach/msm_hsusb.h
+++ b/arch/arm/mach-msm/include/mach/msm_hsusb.h
@@ -94,7 +94,8 @@ enum chg_type {
USB_CHG_TYPE__SDP,
USB_CHG_TYPE__CARKIT,
USB_CHG_TYPE__WALLCHARGER,
- USB_CHG_TYPE__INVALID
+ USB_CHG_TYPE__UNKNOWN,
+ USB_CHG_TYPE__INVALID,
};
enum pre_emphasis_level {
diff --git a/arch/arm/mach-msm/include/mach/msm_serial_pdata.h b/arch/arm/mach-msm/include/mach/msm_serial_pdata.h
index 7c1319e..7d2fb40 100644
--- a/arch/arm/mach-msm/include/mach/msm_serial_pdata.h
+++ b/arch/arm/mach-msm/include/mach/msm_serial_pdata.h
@@ -10,8 +10,8 @@
* GNU General Public License for more details.
*/
-#ifndef __ASM_ARCH_MSM_SERIAL_H
-#define __ASM_ARCH_MSM_SERIAL_H
+#ifndef __ASM_ARCH_MSM_SERIAL_HS_H
+#define __ASM_ARCH_MSM_SERIAL_HS_H
#include <linux/serial_core.h>
@@ -22,7 +22,6 @@ struct msm_serial_platform_data {
/* bool: inject char into rx tty on wakeup */
unsigned char inject_rx_on_wakeup;
char rx_to_inject;
- int userid;
};
#endif
diff --git a/arch/arm/mach-msm/include/mach/msm_smsm.h b/arch/arm/mach-msm/include/mach/msm_smsm.h
index 1745815..4138aea 100644
--- a/arch/arm/mach-msm/include/mach/msm_smsm.h
+++ b/arch/arm/mach-msm/include/mach/msm_smsm.h
@@ -198,7 +198,7 @@ enum {
SMEM_VERSION_LAST = SMEM_VERSION_FIRST + 24,
SMEM_OSS_RRCASN1_BUF1,
SMEM_OSS_RRCASN1_BUF2,
- SMEM_ID_VENDOR0,
+ SMEM_ID_VENDOR0,/* wang.junxian2@byd.com used as HW BOARD ID */
SMEM_ID_VENDOR1,
SMEM_ID_VENDOR2,
SMEM_HW_SW_BUILD_ID,
diff --git a/arch/arm/mach-msm/include/mach/oem_rapi_client.h b/arch/arm/mach-msm/include/mach/oem_rapi_client.h
index 374124f..bf93291 100644
--- a/arch/arm/mach-msm/include/mach/oem_rapi_client.h
+++ b/arch/arm/mach-msm/include/mach/oem_rapi_client.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2009,2012 The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -21,12 +21,35 @@
#include <linux/types.h>
#include <mach/msm_rpcrouter.h>
+#ifdef CONFIG_MSM_AMSS_ENHANCE_DEBUG
+#define NZI_ITEM_FILE_NAME_LENGTH 8
+#define TASK_STRUCT_TAG 0x7461736b
+#define MEM_INFO_TAG 0x6d657369
+typedef struct {
+ uint32_t len;
+ uint32_t data[3];
+} extent_t;
+typedef struct {
+ extent_t extension;
+ uint32_t address;
+ char file_name[NZI_ITEM_FILE_NAME_LENGTH]; /* This indicate the log type */
+ uint32_t size; /* Size of the buffer */
+} nzi_buf_item_type;
+int send_modem_logaddr(nzi_buf_item_type *input);
+#endif
+
enum {
OEM_RAPI_CLIENT_EVENT_NONE = 0,
/*
* list of oem rapi client events
*/
+ OEM_RAPI_CLIENT_EVENT_TRI_COLOR_LED_WORK = 21,
+ OEM_RAPI_STREAMING_SILENT_PROFILE_SET = 30,
+ OEM_RAPI_STREAMING_SILENT_PROFILE_GET = 31,
+
+ OEM_RAPI_CLIENT_EVENT_QRDCOMPACTDUMP_NZIITEM_WRITE = 40,
+ OEM_RAPI_CLIENT_EVENT_DEBUG_SLEEP_MONITOR = 41,
OEM_RAPI_CLIENT_EVENT_MAX
diff --git a/arch/arm/mach-msm/include/mach/socinfo.h b/arch/arm/mach-msm/include/mach/socinfo.h
index 4abb69e..34c19cd 100644
--- a/arch/arm/mach-msm/include/mach/socinfo.h
+++ b/arch/arm/mach-msm/include/mach/socinfo.h
@@ -55,6 +55,12 @@
#define PLATFORM_SUBTYPE_SGLTE 6
+#define HW_VERSION(major, minor) (((major) << 16) | (minor))
+#define hw_version_is(major,minor) \
+ ({ \
+ HW_VERSION((major),(minor))==socinfo_get_platform_version(); \
+ })
+
enum msm_cpu {
MSM_CPU_UNKNOWN = 0,
MSM_CPU_7X01,
@@ -101,6 +107,7 @@ enum pmic_model {
PMIC_MODEL_UNKNOWN = 0xFFFFFFFF
};
+extern char socinfo_buf[200];
enum msm_cpu socinfo_get_msm_cpu(void);
uint32_t socinfo_get_id(void);
uint32_t socinfo_get_version(void);
diff --git a/arch/arm/mach-msm/mpm-8625.c b/arch/arm/mach-msm/mpm-8625.c
index c5b954d..228bffb 100644
--- a/arch/arm/mach-msm/mpm-8625.c
+++ b/arch/arm/mach-msm/mpm-8625.c
@@ -102,6 +102,7 @@ static uint8_t msm_gic_irq_to_smsm[NR_IRQS] = {
static uint16_t msm_bypassed_apps_irqs[] = {
MSM8625_INT_CPR_IRQ0,
MSM8625_INT_PBUS_ARM11,
+ MSM8625_INT_SC_SICL2PERFMONIRPTREQ,
};
/* Check IRQ falls into bypassed list are not */
diff --git a/arch/arm/mach-msm/msm7k_fiq.c b/arch/arm/mach-msm/msm7k_fiq.c
index 44e45d1..1bf349f 100644
--- a/arch/arm/mach-msm/msm7k_fiq.c
+++ b/arch/arm/mach-msm/msm7k_fiq.c
@@ -15,12 +15,13 @@
#include <linux/slab.h>
#include <linux/io.h>
#include <linux/irq.h>
+#include <linux/nmi.h>
#include <asm/fiq.h>
-#include <asm/unwind.h>
#include <asm/hardware/gic.h>
#include <asm/cacheflush.h>
#include <mach/irqs.h>
#include <mach/socinfo.h>
+#include <asm/unwind.h>
#include <mach/fiq.h>
#include <mach/msm_iomap.h>
@@ -48,6 +49,8 @@ void msm7k_fiq_handler(void)
pr_info("%s: Fiq is received on CPU%d\n", __func__, this_cpu);
fiq_counter += 1;
+ pr_err("%s msm_dump_cpu_ctx[this_cpu] usr_r0:0x%x", __func__, msm_dump_cpu_ctx[this_cpu].usr_r0);
+ pr_err("%s msm_dump_cpu_ctx[this_cpu] usr_r0:0x%x usr_r1:0x%x usr_r2:0x%x usr_r3:0x%x usr_r4:0x%x usr_r5:0x%x usr_r6:0x%x usr_r7:0x%x usr_r8:0x%x usr_r9:0x%x usr_r10:0x%x usr_r11:0x%x usr_r12:0x%x usr_r13:0x%x usr_r14:0x%x irq_spsr:0x%x irq_r13:0x%x irq_r14:0x%x svc_spsr:0x%x svc_r13:0x%x svc_r14:0x%x abt_spsr:0x%x abt_r13:0x%x abt_r14:0x%x und_spsr:0x%x und_r13:0x%x und_r14:0x%x fiq_spsr:0x%x fiq_r8:0x%x fiq_r9:0x%x fiq_r10:0x%x fiq_r11:0x%x fiq_r12:0x%x fiq_r13:0x%x fiq_r14:0x%x\n",__func__, msm_dump_cpu_ctx[this_cpu].usr_r0,msm_dump_cpu_ctx[this_cpu].usr_r1,msm_dump_cpu_ctx[this_cpu].usr_r2,msm_dump_cpu_ctx[this_cpu].usr_r3, msm_dump_cpu_ctx[this_cpu].usr_r4, msm_dump_cpu_ctx[this_cpu].usr_r5, msm_dump_cpu_ctx[this_cpu].usr_r6, msm_dump_cpu_ctx[this_cpu].usr_r7, msm_dump_cpu_ctx[this_cpu].usr_r8, msm_dump_cpu_ctx[this_cpu].usr_r9, msm_dump_cpu_ctx[this_cpu].usr_r10, msm_dump_cpu_ctx[this_cpu].usr_r11, msm_dump_cpu_ctx[this_cpu].usr_r12, msm_dump_cpu_ctx[this_cpu].usr_r13, msm_dump_cpu_ctx[this_cpu].usr_r14, msm_dump_cpu_ctx[this_cpu].irq_spsr, msm_dump_cpu_ctx[this_cpu].irq_r13, msm_dump_cpu_ctx[this_cpu].irq_r14, msm_dump_cpu_ctx[this_cpu].svc_spsr, msm_dump_cpu_ctx[this_cpu].svc_r13, msm_dump_cpu_ctx[this_cpu].svc_r14, msm_dump_cpu_ctx[this_cpu].abt_spsr,msm_dump_cpu_ctx[this_cpu].abt_r13, msm_dump_cpu_ctx[this_cpu].abt_r14, msm_dump_cpu_ctx[this_cpu].und_spsr,msm_dump_cpu_ctx[this_cpu].und_r13, msm_dump_cpu_ctx[this_cpu].und_r14, msm_dump_cpu_ctx[this_cpu].fiq_spsr,msm_dump_cpu_ctx[this_cpu].fiq_r8, msm_dump_cpu_ctx[this_cpu].fiq_r9, msm_dump_cpu_ctx[this_cpu].fiq_r10, msm_dump_cpu_ctx[this_cpu].fiq_r11, msm_dump_cpu_ctx[this_cpu].fiq_r12, msm_dump_cpu_ctx[this_cpu].fiq_r13, msm_dump_cpu_ctx[this_cpu].fiq_r14);
ctx_regs.ARM_pc = msm_dump_cpu_ctx[this_cpu].fiq_r14;
ctx_regs.ARM_lr = msm_dump_cpu_ctx[this_cpu].svc_r14;
ctx_regs.ARM_sp = msm_dump_cpu_ctx[this_cpu].svc_r13;
@@ -192,4 +195,4 @@ static int __init init7k_fiq(void)
return 0;
}
-fs_initcall(init7k_fiq);
+late_initcall(init7k_fiq);
diff --git a/arch/arm/mach-msm/msm_cpr.c b/arch/arm/mach-msm/msm_cpr.c
index 56ed48c..b59aedf 100644
--- a/arch/arm/mach-msm/msm_cpr.c
+++ b/arch/arm/mach-msm/msm_cpr.c
@@ -29,6 +29,7 @@
#include <linux/iopoll.h>
#include <linux/delay.h>
#include <linux/regulator/consumer.h>
+#include <linux/spinlock.h>
#include <mach/irqs.h>
#include <mach/msm_iomap.h>
@@ -54,6 +55,10 @@
/* Need platform device handle for suspend and resume APIs */
static struct platform_device *cpr_pdev;
+#if defined(CONFIG_MSM_FUSE_INFO_DEBUG)
+#define FUSE_INFO_LEN 1024
+extern char msm_fuse_info[FUSE_INFO_LEN];
+#endif
static bool enable = 1;
static bool disable_cpr = true;
@@ -73,7 +78,7 @@ MODULE_PARM_DESC(max_quot, "Max Quot");
extern struct regulator *ext_vreg_handle;
-static int msm_cpr_debug_mask;
+static int msm_cpr_debug_mask = 0; //disable cpr print info 7->0
module_param_named(
debug_mask, msm_cpr_debug_mask, int, S_IRUGO | S_IWUSR
);
@@ -104,7 +109,6 @@ struct msm_cpr {
uint32_t cur_Vmin;
uint32_t cur_Vmax;
uint32_t prev_volt_uV;
- struct mutex cpr_mutex;
spinlock_t cpr_lock;
struct regulator *vreg_cx;
struct msm_cpr_config *config;
@@ -387,9 +391,12 @@ cpr_up_event_handler(struct msm_cpr *cpr, uint32_t new_volt)
cpr_irq_clr_and_nack(cpr);
return;
}
-
- msm_cpr_debug(MSM_CPR_DEBUG_STEPS,
- "(railway_voltage: %d uV)\n", set_volt_uV);
+ if(cpr->prev_volt_uV != set_volt_uV){
+ printk("Current cpr chip the floor_fuse=%d pvs_fuse=%d RBCPR_GCNT_TARGET(%d): = 0x%x \n",
+ cpr->config->floor, cpr->config->pvs_fuse, cpr->curr_osc, readl_relaxed(cpr->base +
+ RBCPR_GCNT_TARGET(cpr->curr_osc)) & TARGET_M);
+ printk("cur_volt %d uV (railway_voltage: %d uV)\n",cpr->prev_volt_uV, set_volt_uV);
+ }
cpr->prev_volt_uV = set_volt_uV;
cpr->max_volt_set = (set_volt_uV == cpr->cur_Vmax) ? 1 : 0;
@@ -444,8 +451,13 @@ cpr_dn_event_handler(struct msm_cpr *cpr, uint32_t new_volt, uint32_t err_step)
return;
}
- msm_cpr_debug(MSM_CPR_DEBUG_STEPS,
- "(railway_voltage: %d uV)\n", set_volt_uV);
+ if(cpr->prev_volt_uV != set_volt_uV){
+ printk("Current cpr chip the floor_fuse=%d pvs_fuse=%d RBCPR_GCNT_TARGET(%d): = 0x%x \n",
+ cpr->config->floor, cpr->config->pvs_fuse, cpr->curr_osc, readl_relaxed(cpr->base +
+ RBCPR_GCNT_TARGET(cpr->curr_osc)) & TARGET_M);
+ printk("cur_volt %d uV (railway_voltage: %d uV)\n",cpr->prev_volt_uV, set_volt_uV);
+ }
+
cpr->prev_volt_uV = set_volt_uV;
cpr->max_volt_set = 0;
@@ -494,11 +506,13 @@ static void cpr_set_vdd(struct msm_cpr *cpr, enum cpr_action action)
msm_cpr_debug(MSM_CPR_DEBUG_STEPS,
"RBCPR_RESULT_0 Busy_b19=%d\n", (cpr_read_reg(cpr,
RBCPR_RESULT_0) >> 19) & 0x1);
+ msm_cpr_debug(MSM_CPR_DEBUG_STEPS,
+ "cpr chip the floor_fuse=%d pvs_fuse=%d\n", cpr->config->floor, cpr->config->pvs_fuse);
error_step &= 0xF;
curr_volt = regulator_get_voltage(cpr->vreg_cx);
msm_cpr_debug(MSM_CPR_DEBUG_STEPS,
- "Current voltage=%d\n", curr_volt);
+ "Current voltage=%d\n", curr_volt);
if (action == UP) {
/* Clear IRQ, NACK and return if Vdd already at Vmax */
@@ -948,6 +962,11 @@ static int __devinit msm_cpr_probe(struct platform_device *pdev)
void __iomem *base;
struct resource *mem;
struct msm_cpr_mode *chip_data;
+#if defined(CONFIG_MSM_FUSE_INFO_DEBUG)
+ char tmp_buf[100] = "";
+ uint32_t fuse_len = strlen(msm_fuse_info);
+ char *s = msm_fuse_info + fuse_len;
+#endif
uint32_t curr_volt, new_volt;
if (!enable)
@@ -959,6 +978,12 @@ static int __devinit msm_cpr_probe(struct platform_device *pdev)
return -EIO;
}
+#if defined(CONFIG_MSM_FUSE_INFO_DEBUG)
+ fuse_len += sprintf(tmp_buf, "the initial C2: %d \n", regulator_get_voltage(regulator_get(&pdev->dev, "vddx_cx")));
+ if(fuse_len < FUSE_INFO_LEN)
+ strcat(s, tmp_buf);
+#endif
+
if (pdata->disable_cpr == true) {
pr_err("CPR disabled by modem\n");
return -EPERM;
@@ -1045,6 +1070,11 @@ static int __devinit msm_cpr_probe(struct platform_device *pdev)
goto err_reg_get;
}
+#if defined(CONFIG_MSM_FUSE_INFO_DEBUG)
+ fuse_len += sprintf(tmp_buf, "the initial C2: %d \n", regulator_get_voltage(cpr->vreg_cx));
+ if(fuse_len < FUSE_INFO_LEN)
+ strcat(s, tmp_buf);
+#endif
/*
* Calculate the step size by adding 1mV to the current voltage.
* This moves the voltage by one regulator step. Diff between original
@@ -1138,9 +1168,9 @@ static int __devinit msm_cpr_probe(struct platform_device *pdev)
cpufreq_register_notifier(&cpr->freq_transition,
CPUFREQ_TRANSITION_NOTIFIER);
- disable_cpr = false;
pr_info("CPR: driver registered successfully\n");
+ disable_cpr = false;
return res;
err_cpr_config:
diff --git a/arch/arm/mach-msm/msm_cpr.h b/arch/arm/mach-msm/msm_cpr.h
index 737becd..d99db87 100644
--- a/arch/arm/mach-msm/msm_cpr.h
+++ b/arch/arm/mach-msm/msm_cpr.h
@@ -155,6 +155,7 @@ struct msm_cpr_config {
int min_down_step;
uint32_t tgt_count_div_N; /* Target Cnt(Nom) = Target Cnt(Turbo) / N */
uint32_t floor;
+ uint32_t pvs_fuse;
uint32_t ceiling;
uint32_t sw_vlevel;
uint32_t up_threshold;
@@ -166,7 +167,6 @@ struct msm_cpr_config {
uint32_t max_quot;
bool disable_cpr;
uint32_t step_size;
- uint8_t pvs_fuse;
uint32_t (*get_quot)(uint32_t max_quot, uint32_t max_freq,
uint32_t new_freq);
void (*clk_enable)(void);
diff --git a/arch/arm/mach-msm/msm_smem_iface.h b/arch/arm/mach-msm/msm_smem_iface.h
index bc3e73b..beb5dbd 100644
--- a/arch/arm/mach-msm/msm_smem_iface.h
+++ b/arch/arm/mach-msm/msm_smem_iface.h
@@ -41,6 +41,19 @@ struct cpr_info_type {
bool disable_cpr;
};
+//usb_device_info used only in save serialnum to SMEM:24bytes
+#define MAX_FASTBOOT_SERIALNUM_LEN 8
+typedef struct
+{
+ uint32_t magicNum;
+ uint16_t idVendor;
+ uint16_t idProduct;
+ uint32_t serialNumberLen;
+ char serialNumber[MAX_FASTBOOT_SERIALNUM_LEN];
+ uint16_t enableVerify;
+ char reserved[2];
+} usb_device_info;
+
struct boot_info_for_apps {
uint32_t apps_image_start_addr; /* apps image start address */
uint32_t boot_flags; /* bit mask of upto 32 flags */
@@ -48,8 +61,9 @@ struct boot_info_for_apps {
struct boot_symmetric_key_info key_info;
uint16_t boot_keys_pressed[MAX_KEY_EVENTS]; /* Log of key presses */
uint32_t timetick; /* Modem tick timer value before apps out of reset */
+ usb_device_info usb_info;
struct cpr_info_type cpr_info;
- uint8_t PAD[23];
+ uint8_t PAD[1];
};
void msm_smem_get_cpr_info(struct cpr_info_type *cpr_info);
diff --git a/arch/arm/mach-msm/msm_vibrator.c b/arch/arm/mach-msm/msm_vibrator.c
index 9f811ac..edb3881 100644
--- a/arch/arm/mach-msm/msm_vibrator.c
+++ b/arch/arm/mach-msm/msm_vibrator.c
@@ -2,7 +2,7 @@
*
* Copyright (C) 2008 HTC Corporation.
* Copyright (C) 2007 Google, Inc.
- * Copyright (c) 2011 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2013, The Linux Foundation. All Rights Reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
@@ -35,9 +35,9 @@
#define HTC_PROCEDURE_SET_VIB_ON_OFF 21
#define PMIC_VIBRATOR_LEVEL (3000)
-static struct work_struct work_vibrator_on;
-static struct work_struct work_vibrator_off;
-static struct hrtimer vibe_timer;
+static struct work_struct vibrator_work;
+static struct hrtimer vibrator_timer;
+static DEFINE_MUTEX(vibrator_mtx);
#ifdef CONFIG_PM8XXX_RPC_VIBRATOR
static void set_pmic_vibrator(int on)
@@ -66,12 +66,15 @@ static void set_pmic_vibrator(int on)
struct rpc_request_hdr hdr;
uint32_t data;
} req;
+ if(mutex_lock_interruptible(&vibe_mtx))
+ return;
if (!vib_endpoint) {
vib_endpoint = msm_rpc_connect(PM_LIBPROG, PM_LIBVERS, 0);
if (IS_ERR(vib_endpoint)) {
printk(KERN_ERR "init vib rpc failed!\n");
vib_endpoint = 0;
+ mutex_unlock(&vibe_mtx);
return;
}
}
@@ -84,50 +87,39 @@ static void set_pmic_vibrator(int on)
msm_rpc_call(vib_endpoint, HTC_PROCEDURE_SET_VIB_ON_OFF, &req,
sizeof(req), 5 * HZ);
-}
-#endif
-static void pmic_vibrator_on(struct work_struct *work)
-{
- set_pmic_vibrator(1);
+ mutex_unlock(&vibe_mtx);
}
+#endif
-static void pmic_vibrator_off(struct work_struct *work)
+static void update_vibrator(struct work_struct *work)
{
+ pr_debug("%s\n", __func__);
set_pmic_vibrator(0);
}
-static void timed_vibrator_on(struct timed_output_dev *sdev)
-{
- schedule_work(&work_vibrator_on);
-}
-
-static void timed_vibrator_off(struct timed_output_dev *sdev)
-{
- schedule_work(&work_vibrator_off);
-}
-
static void vibrator_enable(struct timed_output_dev *dev, int value)
{
- hrtimer_cancel(&vibe_timer);
+ mutex_lock(&vibrator_mtx);
+ hrtimer_cancel(&vibrator_timer);
+ cancel_work_sync(&vibrator_work);
- if (value == 0)
- timed_vibrator_off(dev);
- else {
+ if (value == 0) {
+ set_pmic_vibrator(0);
+ } else {
value = (value > 15000 ? 15000 : value);
-
- timed_vibrator_on(dev);
-
- hrtimer_start(&vibe_timer,
+ set_pmic_vibrator(value);
+ hrtimer_start(&vibrator_timer,
ktime_set(value / 1000, (value % 1000) * 1000000),
HRTIMER_MODE_REL);
}
+ mutex_unlock(&vibrator_mtx);
}
static int vibrator_get_time(struct timed_output_dev *dev)
{
- if (hrtimer_active(&vibe_timer)) {
- ktime_t r = hrtimer_get_remaining(&vibe_timer);
+ if (hrtimer_active(&vibrator_timer)) {
+ ktime_t r = hrtimer_get_remaining(&vibrator_timer);
struct timeval t = ktime_to_timeval(r);
return t.tv_sec * 1000 + t.tv_usec / 1000;
}
@@ -136,7 +128,8 @@ static int vibrator_get_time(struct timed_output_dev *dev)
static enum hrtimer_restart vibrator_timer_func(struct hrtimer *timer)
{
- timed_vibrator_off(NULL);
+ pr_debug("%s\n", __func__);
+ schedule_work(&vibrator_work);
return HRTIMER_NORESTART;
}
@@ -148,11 +141,9 @@ static struct timed_output_dev pmic_vibrator = {
void __init msm_init_pmic_vibrator(void)
{
- INIT_WORK(&work_vibrator_on, pmic_vibrator_on);
- INIT_WORK(&work_vibrator_off, pmic_vibrator_off);
-
- hrtimer_init(&vibe_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
- vibe_timer.function = vibrator_timer_func;
+ INIT_WORK(&vibrator_work, update_vibrator);
+ hrtimer_init(&vibrator_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
+ vibrator_timer.function = vibrator_timer_func;
timed_output_dev_register(&pmic_vibrator);
}
diff --git a/arch/arm/mach-msm/perf_event_msm_krait_l2.c b/arch/arm/mach-msm/perf_event_msm_krait_l2.c
index 6ee97b7..34b9426 100644
--- a/arch/arm/mach-msm/perf_event_msm_krait_l2.c
+++ b/arch/arm/mach-msm/perf_event_msm_krait_l2.c
@@ -72,9 +72,11 @@
*/
struct pmu_constraints {
u64 pmu_bitmap;
+ u8 codes[64];
raw_spinlock_t lock;
} l2_pmu_constraints = {
.pmu_bitmap = 0,
+ .codes = {-1},
.lock = __RAW_SPIN_LOCK_UNLOCKED(l2_pmu_constraints.lock),
};
@@ -335,8 +337,10 @@ static int krait_l2_get_event_idx(struct pmu_hw_events *cpuc,
int ctr = 0;
if (hwc->config_base == L2CYCLE_CTR_RAW_CODE) {
- if (!test_and_set_bit(l2_cycle_ctr_idx, cpuc->used_mask))
- return l2_cycle_ctr_idx;
+ if (test_and_set_bit(l2_cycle_ctr_idx, cpuc->used_mask))
+ return -EAGAIN;
+
+ return l2_cycle_ctr_idx;
}
for (ctr = 0; ctr < total_l2_ctrs - 1; ctr++) {
@@ -453,22 +457,48 @@ static int msm_l2_test_set_ev_constraint(struct perf_event *event)
{
u32 evt_type = event->attr.config & L2_EVT_MASK;
u8 reg = (evt_type & 0x0F000) >> 12;
- u8 group = evt_type & 0x0000F;
+ u8 group = evt_type & 0x0000F;
+ u8 code = (evt_type & 0x00FF0) >> 4;
unsigned long flags;
u32 err = 0;
u64 bitmap_t;
+ u32 shift_idx;
+
+ /*
+ * Cycle counter collision is detected in
+ * get_event_idx().
+ */
+ if (evt_type == L2CYCLE_CTR_RAW_CODE)
+ return err;
raw_spin_lock_irqsave(&l2_pmu_constraints.lock, flags);
- bitmap_t = 1 << ((reg * 4) + group);
+ shift_idx = ((reg * 4) + group);
+
+ bitmap_t = 1 << shift_idx;
if (!(l2_pmu_constraints.pmu_bitmap & bitmap_t)) {
l2_pmu_constraints.pmu_bitmap |= bitmap_t;
+ l2_pmu_constraints.codes[shift_idx] = code;
goto out;
+ } else {
+ /*
+ * If NRCCG's are identical,
+ * its not column exclusion.
+ */
+ if (l2_pmu_constraints.codes[shift_idx] != code)
+ err = -EPERM;
+ else
+ /*
+ * If the event is counted in syswide mode
+ * then we want to count only on one CPU
+ * and set its filter to count from all.
+ * This sets the event OFF on all but one
+ * CPU.
+ */
+ if (!(event->cpu < 0))
+ event->state = PERF_EVENT_STATE_OFF;
}
-
- /* Bit is already set. Constraint failed. */
- err = -EPERM;
out:
raw_spin_unlock_irqrestore(&l2_pmu_constraints.lock, flags);
return err;
@@ -481,14 +511,20 @@ static int msm_l2_clear_ev_constraint(struct perf_event *event)
u8 group = evt_type & 0x0000F;
unsigned long flags;
u64 bitmap_t;
+ u32 shift_idx;
raw_spin_lock_irqsave(&l2_pmu_constraints.lock, flags);
- bitmap_t = 1 << ((reg * 4) + group);
+ shift_idx = ((reg * 4) + group);
+
+ bitmap_t = 1 << shift_idx;
/* Clear constraint bit. */
l2_pmu_constraints.pmu_bitmap &= ~bitmap_t;
+ /* Clear code. */
+ l2_pmu_constraints.codes[shift_idx] = -1;
+
raw_spin_unlock_irqrestore(&l2_pmu_constraints.lock, flags);
return 1;
}
@@ -532,7 +568,7 @@ static int __devinit krait_l2_pmu_device_probe(struct platform_device *pdev)
{
krait_l2_pmu.plat_device = pdev;
- if (!armpmu_register(&krait_l2_pmu, "kraitl2", -1))
+ if (!armpmu_register(&krait_l2_pmu, "msm-l2", -1))
pmu_type = krait_l2_pmu.pmu.type;
return 0;
diff --git a/arch/arm/mach-msm/perf_event_msm_l2.c b/arch/arm/mach-msm/perf_event_msm_l2.c
index 96c43aa..f78487a 100644
--- a/arch/arm/mach-msm/perf_event_msm_l2.c
+++ b/arch/arm/mach-msm/perf_event_msm_l2.c
@@ -38,9 +38,11 @@
*/
struct pmu_constraints {
u64 pmu_bitmap;
+ u8 codes[64];
raw_spinlock_t lock;
} l2_pmu_constraints = {
.pmu_bitmap = 0,
+ .codes = {-1},
.lock = __RAW_SPIN_LOCK_UNLOCKED(l2_pmu_constraints.lock),
};
@@ -667,9 +669,11 @@ static int scorpion_l2_get_event_idx(struct pmu_hw_events *cpuc,
int ctr = 0;
if (hwc->config_base == SCORPION_L2CYCLE_CTR_RAW_CODE) {
- if (!test_and_set_bit(l2_cycle_ctr_idx,
+ if (test_and_set_bit(l2_cycle_ctr_idx,
cpuc->used_mask))
- return l2_cycle_ctr_idx;
+ return -EAGAIN;
+
+ return l2_cycle_ctr_idx;
}
for (ctr = 0; ctr < total_l2_ctrs - 1; ctr++) {
@@ -792,25 +796,50 @@ static int msm_l2_test_set_ev_constraint(struct perf_event *event)
u8 prefix = (evt_type & 0xF0000) >> 16;
u8 reg = (evt_type & 0x0F000) >> 12;
u8 group = evt_type & 0x0000F;
+ u8 code = (evt_type & 0x00FF0) >> 4;
unsigned long flags;
u32 err = 0;
u64 bitmap_t;
+ u32 shift_idx;
if (!prefix)
return 0;
+ /*
+ * Cycle counter collision is detected in
+ * get_event_idx().
+ */
+ if (evt_type == SCORPION_L2CYCLE_CTR_RAW_CODE)
+ return err;
raw_spin_lock_irqsave(&l2_pmu_constraints.lock, flags);
- bitmap_t = 1 << ((reg * 4) + group);
+ shift_idx = ((reg * 4) + group);
+
+ bitmap_t = 1 << shift_idx;
if (!(l2_pmu_constraints.pmu_bitmap & bitmap_t)) {
l2_pmu_constraints.pmu_bitmap |= bitmap_t;
+ l2_pmu_constraints.codes[shift_idx] = code;
goto out;
+ } else {
+ /*
+ * If NRCCG's are identical,
+ * its not column exclusion.
+ */
+ if (l2_pmu_constraints.codes[shift_idx] != code)
+ err = -EPERM;
+ else
+ /*
+ * If the event is counted in syswide mode
+ * then we want to count only on one CPU
+ * and set its filter to count from all.
+ * This sets the event OFF on all but one
+ * CPU.
+ */
+ if (!(event->cpu < 0))
+ event->state = PERF_EVENT_STATE_OFF;
}
- /* Bit is already set. Constraint failed. */
- err = -EPERM;
-
out:
raw_spin_unlock_irqrestore(&l2_pmu_constraints.lock, flags);
return err;
@@ -824,13 +853,16 @@ static int msm_l2_clear_ev_constraint(struct perf_event *event)
u8 group = evt_type & 0x0000F;
unsigned long flags;
u64 bitmap_t;
+ u32 shift_idx;
if (!prefix)
return 0;
raw_spin_lock_irqsave(&l2_pmu_constraints.lock, flags);
- bitmap_t = 1 << ((reg * 4) + group);
+ shift_idx = ((reg * 4) + group);
+
+ bitmap_t = 1 << shift_idx;
/* Clear constraint bit. */
l2_pmu_constraints.pmu_bitmap &= ~bitmap_t;
@@ -877,7 +909,7 @@ static int __devinit scorpion_l2_pmu_device_probe(struct platform_device *pdev)
{
scorpion_l2_pmu.plat_device = pdev;
- if (!armpmu_register(&scorpion_l2_pmu, "scorpionl2", -1))
+ if (!armpmu_register(&scorpion_l2_pmu, "msm-l2", -1))
pmu_type = scorpion_l2_pmu.pmu.type;
return 0;
diff --git a/arch/arm/mach-msm/perf_event_msm_pl310.c b/arch/arm/mach-msm/perf_event_msm_pl310.c
new file mode 100644
index 0000000..e2a580f
--- /dev/null
+++ b/arch/arm/mach-msm/perf_event_msm_pl310.c
@@ -0,0 +1,432 @@
+/*
+ * Copyright (C) 2007 ARM Limited
+ * Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/spinlock.h>
+#include <linux/platform_device.h>
+
+#include <asm/pmu.h>
+#include <asm/hardware/cache-l2x0.h>
+#include <mach/socinfo.h>
+
+static u32 rev1;
+
+/*
+ * Store dynamic PMU type after registration,
+ * to uniquely identify this PMU at runtime.
+ */
+static u32 pmu_type;
+
+/* This controller only supports 16 Events.*/
+PMU_FORMAT_ATTR(l2_config, "config:0-4");
+
+static struct attribute *arm_l2_ev_formats[] = {
+ &format_attr_l2_config.attr,
+ NULL,
+};
+
+/*
+ * Format group is essential to access PMU's from userspace
+ * via their .name field.
+ */
+static struct attribute_group arm_l2_pmu_format_group = {
+ .name = "format",
+ .attrs = arm_l2_ev_formats,
+};
+
+static const struct attribute_group *arm_l2_pmu_attr_grps[] = {
+ &arm_l2_pmu_format_group,
+ NULL,
+};
+
+#define L2X0_AUX_CTRL_EVENT_MONITOR_SHIFT 20
+#define L2X0_INTR_MASK_ECNTR 1
+
+/* L220/PL310 Event control register values */
+#define L2X0_EVENT_CNT_ENABLE_MASK 1
+#define L2X0_EVENT_CNT_ENABLE 1
+#define L2X0_EVENT_CNT_RESET(x) (1 << (x+1))
+
+/* Bit-shifted event counter config values */
+enum l2x0_perf_types {
+ L2X0_EVENT_CNT_CFG_DISABLED = 0x0,
+ L2X0_EVENT_CNT_CFG_CO = 0x1,
+ L2X0_EVENT_CNT_CFG_DRHIT = 0x2,
+ L2X0_EVENT_CNT_CFG_DRREQ = 0x3,
+ L2X0_EVENT_CNT_CFG_DWHIT = 0x4,
+ L2X0_EVENT_CNT_CFG_DWREQ = 0x5,
+ L2X0_EVENT_CNT_CFG_DWTREQ = 0x6,
+ L2X0_EVENT_CNT_CFG_IRHIT = 0x7,
+ L2X0_EVENT_CNT_CFG_IRREQ = 0x8,
+ L2X0_EVENT_CNT_CFG_WA = 0x9,
+
+ /* PL310 only */
+ L2X0_EVENT_CNT_CFG_IPFALLOC = 0xA,
+ L2X0_EVENT_CNT_CFG_EPFHIT = 0xB,
+ L2X0_EVENT_CNT_CFG_EPFALLOC = 0xC,
+ L2X0_EVENT_CNT_CFG_SRRCVD = 0xD,
+ L2X0_EVENT_CNT_CFG_SRCONF = 0xE,
+ L2X0_EVENT_CNT_CFG_EPFRCVD = 0xF,
+};
+
+#define PL310_EVENT_CNT_CFG_MAX L2X0_EVENT_CNT_CFG_EPFRCVD
+
+#define L2X0_EVENT_CNT_CFG_SHIFT 2
+#define L2X0_EVENT_CNT_CFG_MASK (0xF << 2)
+
+#define L2X0_EVENT_CNT_CFG_INTR_MASK 0x3
+#define L2X0_EVENT_CNT_CFG_INTR_DISABLED 0x0
+#define L2X0_EVENT_CNT_CFG_INTR_INCREMENT 0x1
+#define L2X0_EVENT_CNT_CFG_INTR_OVERFLOW 0x2
+
+#define L2X0_NUM_COUNTERS 2
+static struct arm_pmu l2x0_pmu;
+
+static u32 l2x0pmu_max_event_id = 0xf;
+
+static struct perf_event *events[2];
+static unsigned long used_mask[BITS_TO_LONGS(2)];
+static struct pmu_hw_events l2x0pmu_hw_events = {
+ .events = events,
+ .used_mask = used_mask,
+ .pmu_lock = __RAW_SPIN_LOCK_UNLOCKED(l2x0pmu_hw_events.pmu_lock),
+};
+
+#define COUNTER_CFG_ADDR(idx) (l2x0_base + L2X0_EVENT_CNT0_CFG - 4*idx)
+
+#define COUNTER_CTRL_ADDR (l2x0_base + L2X0_EVENT_CNT_CTRL)
+
+#define COUNTER_ADDR(idx) (l2x0_base + L2X0_EVENT_CNT0_VAL - 4*idx)
+
+static u32 l2x0_read_intr_mask(void)
+{
+ return readl_relaxed(l2x0_base + L2X0_INTR_MASK);
+}
+
+static void l2x0_write_intr_mask(u32 val)
+{
+ writel_relaxed(val, l2x0_base + L2X0_INTR_MASK);
+}
+
+static void l2x0_enable_counter_interrupt(void)
+{
+ u32 intr_mask = l2x0_read_intr_mask();
+ intr_mask |= L2X0_INTR_MASK_ECNTR;
+ l2x0_write_intr_mask(intr_mask);
+}
+
+static void l2x0_disable_counter_interrupt(void)
+{
+ u32 intr_mask = l2x0_read_intr_mask();
+ intr_mask &= ~L2X0_INTR_MASK_ECNTR;
+ l2x0_write_intr_mask(intr_mask);
+}
+
+static void l2x0_clear_interrupts(u32 flags)
+{
+ writel_relaxed(flags, l2x0_base + L2X0_INTR_CLEAR);
+}
+
+static struct pmu_hw_events *l2x0pmu_get_hw_events(void)
+{
+ return &l2x0pmu_hw_events;
+}
+
+static u32 l2x0pmu_read_ctrl(void)
+{
+ return readl_relaxed(COUNTER_CTRL_ADDR);
+}
+
+static void l2x0pmu_write_ctrl(u32 val)
+{
+ writel_relaxed(val, COUNTER_CTRL_ADDR);
+}
+
+static u32 l2x0pmu_read_cfg(int idx)
+{
+ return readl_relaxed(COUNTER_CFG_ADDR(idx));
+}
+
+static void l2x0pmu_write_cfg(u32 val, int idx)
+{
+ writel_relaxed(val, COUNTER_CFG_ADDR(idx));
+}
+
+static void l2x0pmu_enable_counter(u32 cfg, int idx)
+{
+ cfg |= L2X0_EVENT_CNT_CFG_INTR_OVERFLOW;
+ l2x0pmu_write_cfg(cfg, idx);
+}
+
+static u32 l2x0pmu_disable_counter(int idx)
+{
+ u32 cfg, oldcfg;
+
+ cfg = oldcfg = l2x0pmu_read_cfg(idx);
+
+ cfg &= ~L2X0_EVENT_CNT_CFG_MASK;
+ cfg &= ~L2X0_EVENT_CNT_CFG_INTR_MASK;
+ l2x0pmu_write_cfg(cfg, idx);
+
+ return oldcfg;
+}
+
+static u32 l2x0pmu_read_counter(int idx)
+{
+ u32 val = readl_relaxed(COUNTER_ADDR(idx));
+
+ return val;
+}
+
+static void l2x0pmu_write_counter(int idx, u32 val)
+{
+ /*
+ * L2X0 counters can only be written to when they are disabled.
+ * As perf core does not disable counters before writing to them
+ * under interrupts, we must do so here.
+ */
+ u32 cfg = l2x0pmu_disable_counter(idx);
+ writel_relaxed(val, COUNTER_ADDR(idx));
+ l2x0pmu_write_cfg(cfg, idx);
+}
+
+static int counter_is_saturated(int idx)
+{
+ return l2x0pmu_read_counter(idx) == 0xFFFFFFFF;
+}
+
+static void l2x0pmu_start(void)
+{
+ unsigned long flags;
+ u32 val;
+
+ raw_spin_lock_irqsave(&l2x0pmu_hw_events.pmu_lock, flags);
+
+ if (!rev1)
+ l2x0_enable_counter_interrupt();
+
+ val = l2x0pmu_read_ctrl();
+
+ val |= L2X0_EVENT_CNT_ENABLE;
+ l2x0pmu_write_ctrl(val);
+
+ raw_spin_unlock_irqrestore(&l2x0pmu_hw_events.pmu_lock, flags);
+}
+
+static void l2x0pmu_stop(void)
+{
+ unsigned long flags;
+ u32 val;
+
+ raw_spin_lock_irqsave(&l2x0pmu_hw_events.pmu_lock, flags);
+
+ val = l2x0pmu_read_ctrl();
+ val &= ~L2X0_EVENT_CNT_ENABLE_MASK;
+ l2x0pmu_write_ctrl(val);
+
+ if (!rev1)
+ l2x0_disable_counter_interrupt();
+
+ raw_spin_unlock_irqrestore(&l2x0pmu_hw_events.pmu_lock, flags);
+}
+
+static void l2x0pmu_enable(struct hw_perf_event *event, int idx, int cpu)
+{
+ unsigned long flags;
+ u32 cfg;
+
+ raw_spin_lock_irqsave(&l2x0pmu_hw_events.pmu_lock, flags);
+
+ cfg = (event->config_base << L2X0_EVENT_CNT_CFG_SHIFT) &
+ L2X0_EVENT_CNT_CFG_MASK;
+ l2x0pmu_enable_counter(cfg, idx);
+
+ raw_spin_unlock_irqrestore(&l2x0pmu_hw_events.pmu_lock, flags);
+}
+
+static void l2x0pmu_disable(struct hw_perf_event *event, int idx)
+{
+ unsigned long flags;
+
+ raw_spin_lock_irqsave(&l2x0pmu_hw_events.pmu_lock, flags);
+ l2x0pmu_disable_counter(idx);
+ raw_spin_unlock_irqrestore(&l2x0pmu_hw_events.pmu_lock, flags);
+}
+
+static int l2x0pmu_get_event_idx(struct pmu_hw_events *events,
+ struct hw_perf_event *hwc)
+{
+ int idx;
+
+ /* Counters are identical. Just grab a free one. */
+ for (idx = 0; idx < L2X0_NUM_COUNTERS; ++idx) {
+ if (!test_and_set_bit(idx, l2x0pmu_hw_events.used_mask))
+ return idx;
+ }
+
+ return -EAGAIN;
+}
+
+/*
+ * As System PMUs are affine to CPU0, the fact that interrupts are disabled
+ * during interrupt handling is enough to serialise our actions and make this
+ * safe. We do not need to grab our pmu_lock here.
+ */
+static irqreturn_t l2x0pmu_handle_irq(int irq, void *dev)
+{
+ irqreturn_t status = IRQ_NONE;
+ struct perf_sample_data data;
+ struct pt_regs *regs;
+ int idx;
+
+ regs = get_irq_regs();
+
+ for (idx = 0; idx < L2X0_NUM_COUNTERS; ++idx) {
+ struct perf_event *event = l2x0pmu_hw_events.events[idx];
+ struct hw_perf_event *hwc;
+
+ if (!counter_is_saturated(idx))
+ continue;
+
+ status = IRQ_HANDLED;
+
+ hwc = &event->hw;
+
+ /*
+ * The armpmu_* functions expect counters to overflow, but
+ * L220/PL310 counters saturate instead. Fake the overflow
+ * here so the hardware is in sync with what the framework
+ * expects.
+ */
+ l2x0pmu_write_counter(idx, 0);
+
+ armpmu_event_update(event, hwc, idx);
+ data.period = event->hw.last_period;
+
+ if (!armpmu_event_set_period(event, hwc, idx))
+ continue;
+
+ if (perf_event_overflow(event, &data, regs))
+ l2x0pmu_disable_counter(idx);
+ }
+
+ l2x0_clear_interrupts(L2X0_INTR_MASK_ECNTR);
+
+ irq_work_run();
+
+ return status;
+}
+
+static int map_l2x0_raw_event(u64 config)
+{
+ return (config <= l2x0pmu_max_event_id) ? config : -ENOENT;
+}
+
+static int l2x0pmu_map_event(struct perf_event *event)
+{
+ u64 config = event->attr.config;
+ u64 supported_samples = (PERF_SAMPLE_TIME |
+ PERF_SAMPLE_ID |
+ PERF_SAMPLE_PERIOD |
+ PERF_SAMPLE_STREAM_ID |
+ PERF_SAMPLE_RAW);
+
+ if ((pmu_type == 0) || (pmu_type != event->attr.type))
+ return -ENOENT;
+
+ if (event->attr.sample_type & ~supported_samples)
+ return -ENOENT;
+
+ return map_l2x0_raw_event(config);
+}
+
+static int
+arm_l2_pmu_generic_request_irq(int irq, irq_handler_t *handle_irq)
+{
+ return request_irq(irq, *handle_irq,
+ IRQF_DISABLED | IRQF_NOBALANCING,
+ "arm-l2-armpmu", NULL);
+}
+
+static void
+arm_l2_pmu_generic_free_irq(int irq)
+{
+ if (irq >= 0)
+ free_irq(irq, NULL);
+}
+
+static struct arm_pmu l2x0_pmu = {
+ .id = ARM_PERF_PMU_ID_L2X0,
+ .type = ARM_PMU_DEVICE_L2CC,
+ .name = "msm-l2",
+ .start = l2x0pmu_start,
+ .stop = l2x0pmu_stop,
+ .handle_irq = l2x0pmu_handle_irq,
+ .enable = l2x0pmu_enable,
+ .disable = l2x0pmu_disable,
+ .get_event_idx = l2x0pmu_get_event_idx,
+ .read_counter = l2x0pmu_read_counter,
+ .write_counter = l2x0pmu_write_counter,
+ .map_event = l2x0pmu_map_event,
+ .num_events = 2,
+ .max_period = 0xFFFFFFFF,
+ .get_hw_events = l2x0pmu_get_hw_events,
+ .pmu.attr_groups = arm_l2_pmu_attr_grps,
+ .request_pmu_irq = arm_l2_pmu_generic_request_irq,
+ .free_pmu_irq = arm_l2_pmu_generic_free_irq,
+};
+
+static int __devinit l2x0pmu_device_probe(struct platform_device *pdev)
+{
+ u32 aux = readl_relaxed(l2x0_base + L2X0_AUX_CTRL);
+ u32 debug = readl_relaxed(l2x0_base + L2X0_DEBUG_CTRL);
+ l2x0_pmu.plat_device = pdev;
+
+ if (!(aux & (1 << L2X0_AUX_CTRL_EVENT_MONITOR_SHIFT))) {
+ pr_err("Ev Monitor is OFF. L2 counters disabled.\n");
+ return -EOPNOTSUPP;
+ }
+
+ pr_info("L2CC PMU device found. DEBUG_CTRL: %x\n", debug);
+
+ /* Get value of dynamically allocated PMU type. */
+ if (!armpmu_register(&l2x0_pmu, "msm-l2", -1))
+ pmu_type = l2x0_pmu.pmu.type;
+ else {
+ pr_err("l2x0_pmu registration failed\n");
+ return -EOPNOTSUPP;
+ }
+
+ return 0;
+}
+
+static struct platform_driver l2x0pmu_driver = {
+ .driver = {
+ .name = "l2-arm-pmu",
+ },
+ .probe = l2x0pmu_device_probe,
+};
+
+static int __init register_pmu_driver(void)
+{
+ if (machine_is_msm9625())
+ rev1 = 1;
+
+ return platform_driver_register(&l2x0pmu_driver);
+}
+device_initcall(register_pmu_driver);
diff --git a/arch/arm/mach-msm/pm-boot.c b/arch/arm/mach-msm/pm-boot.c
index 1bdbe4d..036c108 100644
--- a/arch/arm/mach-msm/pm-boot.c
+++ b/arch/arm/mach-msm/pm-boot.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2012, The Linux Foundation. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
diff --git a/arch/arm/mach-msm/pm2.c b/arch/arm/mach-msm/pm2.c
index 8838226..99fba0b 100644
--- a/arch/arm/mach-msm/pm2.c
+++ b/arch/arm/mach-msm/pm2.c
@@ -46,6 +46,11 @@
#include <mach/proc_comm.h>
#include <asm/smp_scu.h>
+#ifdef CONFIG_MSM_SM_EVENT
+#include <linux/sm_event_log.h>
+#include <linux/sm_event.h>
+#endif
+
#include "smd_private.h"
#include "smd_rpcrouter.h"
#include "acpuclock.h"
@@ -884,6 +889,9 @@ static int msm_pm_power_collapse
struct msm_pm_polled_group state_grps[2];
unsigned long saved_acpuclk_rate;
int collapsed = 0;
+#ifdef CONFIG_MSM_SM_EVENT
+ uint64_t sclk_suspend_time = 0, sclk_resume_time, sclk_period;
+#endif
int ret;
int val;
int modem_early_exit = 0;
@@ -1002,6 +1010,10 @@ static int msm_pm_power_collapse
goto power_collapse_early_exit;
}
+#ifdef CONFIG_MSM_SM_EVENT
+ if (!from_idle)
+ sclk_suspend_time = msm_timer_get_sclk_time(&sclk_period);
+#endif
msm_pm_config_hw_before_power_down();
MSM_PM_DEBUG_PRINT_STATE("msm_pm_power_collapse(): pre power down");
@@ -1015,6 +1027,12 @@ static int msm_pm_power_collapse
goto power_collapse_early_exit;
}
+#ifdef CONFIG_MSM_SM_EVENT
+ if (!from_idle) {
+ sm_add_event(SM_POWER_EVENT | SM_POWER_EVENT_SUSPEND, SM_EVENT_END, 0, 0, 0);
+ }
+#endif
+
/* save the AHB clock registers */
if (cpu_is_msm8625q()) {
msm8x25q_ahb.sel = readl_relaxed(A11S_CLK_SEL_ADDR);
@@ -1215,6 +1233,19 @@ static int msm_pm_power_collapse
goto power_collapse_restore_gpio_bail;
}
+#ifdef CONFIG_MSM_SM_EVENT
+ if (!from_idle) {
+ int64_t time;
+ sm_set_system_state (SM_STATE_RESUME);
+ sclk_resume_time = msm_timer_get_sclk_time(NULL);
+
+ time = sclk_resume_time - sclk_suspend_time;
+ if (time < 0)
+ time += sclk_period;
+ do_div (time, 1000000);//milli-second
+ sm_add_event(SM_POWER_EVENT | SM_POWER_EVENT_RESUME, SM_EVENT_START, (uint32_t)time, (void *)msm_pm_smem_data, sizeof(*msm_pm_smem_data));
+ }
+#endif
*(uint32_t *)(virt_start_ptr + 0x30) = 0x16;
/* DEM Master == RUN */
diff --git a/arch/arm/mach-msm/pmu.c b/arch/arm/mach-msm/pmu.c
index ed3a651..21f65f8 100644
--- a/arch/arm/mach-msm/pmu.c
+++ b/arch/arm/mach-msm/pmu.c
@@ -11,8 +11,77 @@
*/
#include <linux/platform_device.h>
+#include <linux/irq.h>
#include <asm/pmu.h>
#include <mach/irqs.h>
+#include <mach/socinfo.h>
+
+/*
+ * If a GIC is present, then all IRQ's < 32 are PPI's and can only be
+ * requested and free'd using the percpu IRQ API.
+ * If a VIC is present, then only the traditional request, free API works.
+ *
+ * All MPCore's have GIC's. The Cortex A5 however may or may not be MPcore, but
+ * it still has a GIC. Except, the 7x27a, which is an A5 and yet has a VIC.
+ * So if the chip is A5 but does not have a GIC, default to the traditional
+ * IRQ {request, free}_irq API.
+ */
+
+#if defined(CONFIG_ARCH_MSM_KRAITMP) || defined(CONFIG_ARCH_MSM_SCORPIONMP) \
+ || defined(CONFIG_ARCH_MSM8625) || \
+ (defined(CONFIG_ARCH_MSM_CORTEX_A5) && !defined(CONFIG_MSM_VIC))
+static DEFINE_PER_CPU(u32, pmu_irq_cookie);
+
+static void enable_irq_callback(void *info)
+{
+ int irq = *(unsigned int *)info;
+ enable_percpu_irq(irq, IRQ_TYPE_EDGE_RISING);
+}
+
+static void disable_irq_callback(void *info)
+{
+ int irq = *(unsigned int *)info;
+ disable_percpu_irq(irq);
+}
+
+static int
+multicore_request_irq(int irq, irq_handler_t *handle_irq)
+{
+ int err = 0;
+ int cpu;
+
+ err = request_percpu_irq(irq, *handle_irq, "l1-armpmu",
+ &pmu_irq_cookie);
+
+ if (!err) {
+ for_each_cpu(cpu, cpu_online_mask) {
+ smp_call_function_single(cpu,
+ enable_irq_callback, &irq, 1);
+ }
+ }
+
+ return err;
+}
+
+static void
+multicore_free_irq(int irq)
+{
+ int cpu;
+
+ if (irq >= 0) {
+ for_each_cpu(cpu, cpu_online_mask) {
+ smp_call_function_single(cpu,
+ disable_irq_callback, &irq, 1);
+ }
+ free_percpu_irq(irq, &pmu_irq_cookie);
+ }
+}
+
+static struct arm_pmu_platdata multicore_data = {
+ .request_pmu_irq = multicore_request_irq,
+ .free_pmu_irq = multicore_free_irq,
+};
+#endif
static struct resource cpu_pmu_resource[] = {
{
@@ -47,6 +116,44 @@ static struct platform_device cpu_pmu_device = {
.num_resources = ARRAY_SIZE(cpu_pmu_resource),
};
+/*
+ * The 8625 is a special case. Due to the requirement of a single
+ * kernel image for the 7x27a and 8625 (which share IRQ headers),
+ * this target breaks the uniformity of IRQ names.
+ * See the file - arch/arm/mach-msm/include/mach/irqs-8625.h
+ */
+#ifdef CONFIG_ARCH_MSM8625
+static struct resource msm8625_cpu_pmu_resource[] = {
+ {
+ .start = MSM8625_INT_ARMQC_PERFMON,
+ .end = MSM8625_INT_ARMQC_PERFMON,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device msm8625_cpu_pmu_device = {
+ .name = "cpu-arm-pmu",
+ .id = ARM_PMU_DEVICE_CPU,
+ .resource = msm8625_cpu_pmu_resource,
+ .num_resources = ARRAY_SIZE(msm8625_cpu_pmu_resource),
+};
+
+static struct resource msm8625_l2_pmu_resource[] = {
+ {
+ .start = MSM8625_INT_SC_SICL2PERFMONIRPTREQ,
+ .end = MSM8625_INT_SC_SICL2PERFMONIRPTREQ,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device msm8625_l2_pmu_device = {
+ .name = "l2-arm-pmu",
+ .id = ARM_PMU_DEVICE_L2CC,
+ .resource = msm8625_l2_pmu_resource,
+ .num_resources = ARRAY_SIZE(msm8625_l2_pmu_resource),
+};
+#endif
+
static struct platform_device *pmu_devices[] = {
&cpu_pmu_device,
#ifdef CONFIG_CPU_HAS_L2_PMU
@@ -56,6 +163,31 @@ static struct platform_device *pmu_devices[] = {
static int __init msm_pmu_init(void)
{
+ /*
+ * For the targets we know are multicore's set the request/free IRQ
+ * handlers to call the percpu API.
+ * Defaults to unicore API {request,free}_irq().
+ * See arch/arm/kernel/perf_event.c
+ * See Comment above on the A5 and MSM_VIC.
+ */
+#if defined(CONFIG_ARCH_MSM_KRAITMP) || defined(CONFIG_ARCH_MSM_SCORPIONMP) \
+ || (defined(CONFIG_ARCH_MSM_CORTEX_A5) && !defined(CONFIG_MSM_VIC))
+ cpu_pmu_device.dev.platform_data = &multicore_data;
+#endif
+
+ /*
+ * The 7x27a and 8625 require a single kernel image.
+ * So we need to check if we're on an 8625 at runtime
+ * and point to the appropriate 'struct resource'.
+ */
+#ifdef CONFIG_ARCH_MSM8625
+ if (cpu_is_msm8625() || cpu_is_msm8625q()) {
+ pmu_devices[0] = &msm8625_cpu_pmu_device;
+ pmu_devices[1] = &msm8625_l2_pmu_device;
+ msm8625_cpu_pmu_device.dev.platform_data = &multicore_data;
+ }
+#endif
+
return platform_add_devices(pmu_devices, ARRAY_SIZE(pmu_devices));
}
diff --git a/arch/arm/mach-msm/proc_comm.c b/arch/arm/mach-msm/proc_comm.c
old mode 100644
new mode 100755
index c7705e7..031de94
--- a/arch/arm/mach-msm/proc_comm.c
+++ b/arch/arm/mach-msm/proc_comm.c
@@ -156,3 +156,70 @@ end:
return ret;
}
EXPORT_SYMBOL(msm_proc_comm);
+
+
+/*
+ Read NV item
+ App ARM calls this API to read NV item from Modem ARM
+*/
+int msm_read_nv(unsigned int nv_item, void *buf)
+{
+ int ret = -1;
+ uint32_t data1 = nv_item;
+ uint32_t data2 ;
+ unsigned char *dest = buf;
+ unsigned int i;
+ if (NULL == buf)
+ return ret;
+ ret = msm_proc_comm(PCOM_NV_READ, &data1, &data2);
+ if (ret)
+ return ret;
+ switch (nv_item)
+ {
+ case 4678:
+ for(i = 0; i < 6; i++ )
+ {
+ if(i < 4)
+ {
+ *dest++ = (unsigned char)(data2 >> (i*8));
+ }
+ else
+ {
+ *dest++ = (unsigned char)(data1 >> ((i-4)*8));
+ }
+ }
+ break;
+ default:
+ printk(KERN_ERR "%s:nv item %d is not supported now\n",__func__,nv_item);
+ ret = -EIO;
+ break;
+ }
+ return ret;
+}
+#define NV_ITEM_WLAN_MAC_ADDR 4678
+extern unsigned char wlan_mac_addr[6];
+int read_nv(unsigned int nv_item, void *buf)
+{
+ int ret = -EIO;
+ switch (nv_item)
+ {
+ case 4678:
+ if(memcmp(wlan_mac_addr,"\0\0\0\0\0\0",sizeof(wlan_mac_addr))!=0){
+ memcpy(buf,wlan_mac_addr,sizeof(wlan_mac_addr));
+ ret = 0;
+ } else {
+ msm_read_nv(NV_ITEM_WLAN_MAC_ADDR,wlan_mac_addr);
+ printk(KERN_ERR "%s: read mac addr from nv\n",__func__);
+ if(memcmp(wlan_mac_addr,"\0\0\0\0\0\0",sizeof(wlan_mac_addr))!=0){
+ memcpy(buf,wlan_mac_addr,sizeof(wlan_mac_addr));
+ ret = 0;
+ }
+ }
+ break;
+ default:
+ printk(KERN_ERR "%s:nv item %d is not supported now\n",__func__,nv_item);
+ break;
+ }
+ return ret;
+}
+EXPORT_SYMBOL(read_nv);
diff --git a/arch/arm/mach-msm/rmt_storage_client.c b/arch/arm/mach-msm/rmt_storage_client.c
index 577428e..c180fea1 100644
--- a/arch/arm/mach-msm/rmt_storage_client.c
+++ b/arch/arm/mach-msm/rmt_storage_client.c
@@ -98,6 +98,7 @@ struct rmt_storage_srv {
struct rmt_storage_client {
uint32_t handle;
uint32_t sid; /* Storage ID */
+ uint32_t usr_data;
char path[MAX_PATH_NAME];
struct rmt_storage_srv *srv;
struct list_head list;
@@ -141,9 +142,11 @@ struct rmt_storage_stats {
struct rmt_storage_op_stats rd_stats;
struct rmt_storage_op_stats wr_stats;
};
+
static struct rmt_storage_stats client_stats[MAX_NUM_CLIENTS];
static struct dentry *stats_dentry;
#endif
+static struct rmt_storage_event last_event;
#define MSM_RMT_STORAGE_APIPROG 0x300000A7
#define MDM_RMT_STORAGE_APIPROG 0x300100A7
@@ -180,6 +183,12 @@ static struct dentry *stats_dentry;
#define RAMFS_SHARED_SSD_RAM_BASE 0x42E00000
#define RAMFS_SHARED_SSD_RAM_SIZE 0x2000
+enum {
+ EVENT_NOT_HANDLED = 0,
+ EVENT_HANDLED,
+} event_status_type;
+static int32_t event_status = EVENT_HANDLED;
+
static struct rmt_storage_client *rmt_storage_get_client(uint32_t handle)
{
struct rmt_storage_client *rs_client;
@@ -946,12 +955,14 @@ static long rmt_storage_ioctl(struct file *fp, unsigned int cmd,
struct rmt_storage_send_sts status;
static struct msm_rpc_client *rpc_client;
struct rmt_shrd_mem_param usr_shrd_mem, *shrd_mem;
+ struct rmt_storage_client *rs_client;
#ifdef CONFIG_MSM_RMT_STORAGE_CLIENT_STATS
struct rmt_storage_stats *stats;
struct rmt_storage_op_stats *op_stats;
ktime_t curr_stat;
#endif
+ struct rmt_storage_revive_info revive_info;
switch (cmd) {
@@ -991,14 +1002,74 @@ static long rmt_storage_ioctl(struct file *fp, unsigned int cmd,
kevent = get_event(rmc);
WARN_ON(kevent == NULL);
+
+ if ((kevent->event.id == RMT_STORAGE_READ) || (kevent->event.id == RMT_STORAGE_WRITE)) {
+ event_status = EVENT_NOT_HANDLED;
+ memcpy(&last_event, &kevent->event, sizeof(struct rmt_storage_event));
+ }
+
+
+ /* Save usr_data infomation */
+ if (kevent->event.id == RMT_STORAGE_SEND_USER_DATA) {
+ if((rs_client = rmt_storage_get_client(kevent->event.handle)))
+ rs_client->usr_data = kevent->event.usr_data;
+ }
+
if (copy_to_user((void __user *)arg, &kevent->event,
sizeof(struct rmt_storage_event))) {
pr_err("%s: copy to user failed\n\n", __func__);
ret = -EFAULT;
}
- kfree(kevent);
+ kfree(kevent);
break;
+ /* Make the user revive and remember previous life */
+ case RMT_STORAGE_REVIVE:
+ pr_debug("%s: get revive request\n", __func__);
+
+ if(copy_from_user(&revive_info, (void __user*)arg, sizeof(struct rmt_storage_revive_info))) {
+ pr_debug("%s: revive_info.index=%d\n", __func__, revive_info.handle);
+ ret = -EFAULT;
+ break;
+ }
+
+ if (revive_info.type == RMT_REVIVE_CLIENT) {
+ pr_debug("%s: revive_info.handle=%d\n", __func__, revive_info.handle);
+
+ if((rs_client = rmt_storage_get_client(revive_info.handle))) {
+ memcpy(revive_info.path, rs_client->path, MAX_PATH_NAME);
+ revive_info.sid = rs_client->sid;
+ revive_info.usr_data = rs_client->usr_data;
+ if(copy_to_user((void __user *)arg, &revive_info, sizeof(struct rmt_storage_revive_info))) {
+ pr_err("%s: revive error\n", __func__);
+ ret = -EFAULT;
+ break;
+ }
+ /* The handle doesn't exist */
+ } else {
+ ret = -EINVAL;
+ break;
+ }
+ } else if (revive_info.type == RMT_REVIVE_EVENT) {
+
+ /* Tell the user what happed */
+ revive_info.event_status = event_status;
+ if(copy_to_user((void __user*)arg, &revive_info, sizeof(struct rmt_storage_revive_info))) {
+ pr_err("%s: revive error\n", __func__);
+ ret = -EFAULT;
+ break;
+ }
+
+ /* The the user the event need to process */
+ if(copy_to_user((void __user*)revive_info.event, (void*)&last_event, sizeof(struct rmt_storage_event))) {
+ pr_err("%s: revive error\n", __func__);
+ ret = -EFAULT;
+ break;
+ }
+ }
+
+ break;
+
case RMT_STORAGE_SEND_STATUS:
pr_info("%s: send status ioctl\n", __func__);
if (copy_from_user(&status, (void __user *)arg,
@@ -1036,6 +1107,8 @@ static long rmt_storage_ioctl(struct file *fp, unsigned int cmd,
if (ret < 0)
pr_err("%s: send status failed with ret val = %d\n",
__func__, ret);
+ else
+ event_status = EVENT_HANDLED;
if (atomic_dec_return(&rmc->wcount) == 0)
wake_unlock(&rmc->wlock);
break;
@@ -1350,6 +1423,9 @@ show_sync_sts(struct device *dev, struct device_attribute *attr, char *buf)
rmt_storage_get_sync_status(srv->rpc_client));
}
+static void rmt_storage_set_client_status(struct rmt_storage_srv *srv,
+ int enable);
+
/*
* Initiate the remote storage force sync and wait until
* sync status is done or maximum 4 seconds in the reboot notifier.
@@ -1362,11 +1438,13 @@ static int rmt_storage_reboot_call(
struct notifier_block *this, unsigned long code, void *cmd)
{
int ret, count = 0;
+ struct msm_rpc_client *rpc_client;
/*
* In recovery mode RMT daemon is not available,
* so return from reboot notifier without initiating
* force sync.
+ * add senario: in normal mode, if reboot or shutdown very early before the userspace open.
*/
spin_lock(&rmc->lock);
if (!rmc->open_excl) {
@@ -1376,6 +1454,14 @@ static int rmt_storage_reboot_call(
}
spin_unlock(&rmc->lock);
+
+ rpc_client = rmt_storage_get_rpc_client(last_event.handle);
+
+ if (!rpc_client) {
+ pr_err("%s: rpc_client is null\n", __func__);
+ return NOTIFY_DONE;
+ }
+
switch (code) {
case SYS_RESTART:
case SYS_HALT:
@@ -1413,7 +1499,10 @@ static int rmt_storage_reboot_call(
if (atomic_read(&rmc->wcount))
pr_err("%s: Efs_sync still incomplete\n", __func__);
- pr_info("%s: Un-register RMT storage client\n", __func__);
+ pr_info("%s: Un register RMT storage client.\n", __func__);
+
+ cancel_delayed_work_sync(&rmt_srv->restart_work);
+ rmt_storage_set_client_status(rmt_srv, 0);
msm_rpc_unregister_client(rmt_srv->rpc_client);
break;
@@ -1669,12 +1758,14 @@ unregister_client:
static void rmt_storage_client_shutdown(struct platform_device *pdev)
{
+#if 0
struct rpcsvr_platform_device *dev;
struct rmt_storage_srv *srv;
dev = container_of(pdev, struct rpcsvr_platform_device, base);
srv = rmt_storage_get_srv(dev->prog);
rmt_storage_set_client_status(srv, 0);
+#endif
}
static void rmt_storage_destroy_rmc(void)
diff --git a/arch/arm/mach-msm/rpc_hsusb.c b/arch/arm/mach-msm/rpc_hsusb.c
index 78666d7..40fa676 100644
--- a/arch/arm/mach-msm/rpc_hsusb.c
+++ b/arch/arm/mach-msm/rpc_hsusb.c
@@ -100,10 +100,10 @@ static int msm_chg_init_rpc(unsigned long vers)
if (IS_ERR(chg_ep))
return -ENODATA;
chg_rpc_ids.vers_comp = vers;
- chg_rpc_ids.chg_usb_charger_connected_proc = 7;
- chg_rpc_ids.chg_usb_charger_disconnected_proc = 8;
- chg_rpc_ids.chg_usb_i_is_available_proc = 9;
- chg_rpc_ids.chg_usb_i_is_not_available_proc = 10;
+ chg_rpc_ids.chg_usb_charger_connected_proc = 3;
+ chg_rpc_ids.chg_usb_charger_disconnected_proc = 4;
+ chg_rpc_ids.chg_usb_i_is_available_proc = 5;
+ chg_rpc_ids.chg_usb_i_is_not_available_proc = 6;
return 0;
} else
return -ENODATA;
@@ -644,7 +644,9 @@ void hsusb_chg_connected(enum chg_type chgtype)
char *chg_types[] = {"STD DOWNSTREAM PORT",
"CARKIT",
"DEDICATED CHARGER",
- "INVALID"};
+ "UNKNOWN",
+ "INVALID",
+ };
if (chgtype == USB_CHG_TYPE__INVALID) {
msm_chg_usb_i_is_not_available();
diff --git a/arch/arm/mach-msm/rpc_server_handset.c b/arch/arm/mach-msm/rpc_server_handset.c
old mode 100644
new mode 100755
index 13953dd..7fa0876
--- a/arch/arm/mach-msm/rpc_server_handset.c
+++ b/arch/arm/mach-msm/rpc_server_handset.c
@@ -1,6 +1,6 @@
/* arch/arm/mach-msm/rpc_server_handset.c
*
- * Copyright (c) 2008-2010,2012 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2008-2010,2012 The Linux Foundation. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -187,8 +187,13 @@ static const uint32_t hs_key_map[] = {
KEY(HS_HEADSET_HEADPHONE_K, SW_HEADPHONE_INSERT),
KEY(HS_HEADSET_MICROPHONE_K, SW_MICROPHONE_INSERT),
KEY(HS_HEADSET_SWITCH_K, KEY_MEDIA),
+#if 0
KEY(HS_HEADSET_SWITCH_2_K, KEY_VOLUMEUP),
KEY(HS_HEADSET_SWITCH_3_K, KEY_VOLUMEDOWN),
+#else
+ KEY(HS_HEADSET_SWITCH_2_K, KEY_NEXTSONG),
+ KEY(HS_HEADSET_SWITCH_3_K, KEY_PREVIOUSSONG),
+#endif
0
};
@@ -276,20 +281,22 @@ static void report_hs_key(uint32_t key_code, uint32_t key_parm)
if (key_parm == HS_REL_K)
key_code = key_parm;
-
+ printk("%s %d key = %d \n",__func__,__LINE__,key);
switch (key) {
case KEY_POWER:
case KEY_END:
if (hs->hs_pdata->ignore_end_key)
input_report_key(hs->ipdev, KEY_POWER,
(key_code != HS_REL_K));
- else
+ else
input_report_key(hs->ipdev, key,
(key_code != HS_REL_K));
break;
case KEY_MEDIA:
case KEY_VOLUMEUP:
case KEY_VOLUMEDOWN:
+ case KEY_PREVIOUSSONG:
+ case KEY_NEXTSONG:
input_report_key(hs->ipdev, key, (key_code != HS_REL_K));
break;
case SW_HEADPHONE_INSERT_W_MIC:
@@ -648,6 +655,9 @@ static int __devinit hs_probe(struct platform_device *pdev)
input_set_capability(ipdev, EV_SW, SW_MICROPHONE_INSERT);
input_set_capability(ipdev, EV_KEY, KEY_POWER);
input_set_capability(ipdev, EV_KEY, KEY_END);
+ input_set_capability(ipdev, EV_KEY, KEY_NEXTSONG);
+ input_set_capability(ipdev, EV_KEY, KEY_PREVIOUSSONG);
+ set_bit(INPUT_PROP_NO_FAKE_RELEASE, ipdev->propbit);
rc = input_register_device(ipdev);
if (rc) {
diff --git a/arch/arm/mach-msm/sleep_monitor.c b/arch/arm/mach-msm/sleep_monitor.c
new file mode 100644
index 0000000..c5a9ace
--- /dev/null
+++ b/arch/arm/mach-msm/sleep_monitor.c
@@ -0,0 +1,160 @@
+/*
+ * Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/errno.h>
+
+#include <linux/fs.h>
+#include <asm/uaccess.h>
+#include <linux/device.h>
+#include <linux/sysfs.h>
+
+#include <mach/oem_rapi_client.h>
+
+#define DEVICE_NAME "sleepm"
+
+enum sleep_monitor_state {
+ SLEEP_MONITOR_DISABLE,
+ SLEEP_MONITOR_ENABLE,
+ SLEEP_MONITOR_MAX
+};
+
+static struct msm_rpc_client *client = NULL;
+static int control = SLEEP_MONITOR_DISABLE;
+
+static int call_oem_rapi_client_streaming_function(char *input)
+{
+ int ret;
+
+ struct oem_rapi_client_streaming_func_arg client_arg = {
+ OEM_RAPI_CLIENT_EVENT_DEBUG_SLEEP_MONITOR,
+ NULL,
+ (void *)NULL,
+ sizeof(input),
+ input,
+ 0,
+ 0,
+ 0
+ };
+ struct oem_rapi_client_streaming_func_ret client_ret = {
+ (uint32_t *)NULL,
+ (char *)NULL
+ };
+
+ if (client == NULL) {
+ client = oem_rapi_client_init();
+ if (IS_ERR(client) || (!client)) {
+ client = NULL;
+ return -ENODEV;
+ }
+ }
+
+ ret = oem_rapi_client_streaming_function(client, &client_arg, &client_ret);
+ if (ret)
+ printk(KERN_ERR
+ "oem_rapi_client_streaming_function() error=%d\n", ret);
+ return ret;
+}
+
+ssize_t sleepm_show_control(struct device *ddev,
+ struct device_attribute *attr, char *buf)
+{
+ return snprintf(buf, PAGE_SIZE, "%d\n", control);
+}
+ssize_t sleepm_store_control(struct device *ddev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ int tmp;
+
+ sscanf(buf, "%d", &tmp);
+ control = tmp;
+ switch((enum sleep_monitor_state)tmp){
+ case SLEEP_MONITOR_DISABLE:
+ printk(KERN_INFO DEVICE_NAME ": Disable sleep monitor\n");
+ break;
+ case SLEEP_MONITOR_ENABLE:
+ printk(KERN_INFO DEVICE_NAME ": Enable sleep monitor\n");
+ break;
+ default:
+ printk(KERN_INFO DEVICE_NAME ": Extend Command %d\n", tmp);
+ break;
+ }
+
+ call_oem_rapi_client_streaming_function((char*)&control);
+
+ return count;
+}
+
+static DEVICE_ATTR(control, S_IRUGO | S_IWUSR, sleepm_show_control, sleepm_store_control);
+
+static struct class *sleepm_class;
+static struct device *sleepm_device;
+static dev_t sleepm_devno;
+
+static int __init sleep_monitor_module_init(void)
+{
+ int ret;
+
+ ret = alloc_chrdev_region(&sleepm_devno, 0, 1, DEVICE_NAME);
+ if (ret < 0) {
+ printk(KERN_ERR DEVICE_NAME ": Fail to alloc chardev region (%d)\n", ret);
+ goto alloc_chrdev_region_fail;
+ }
+
+ //Create sleep monitor class
+ sleepm_class = class_create(THIS_MODULE, "sleep_monitor");
+ if (IS_ERR(sleepm_class)) {
+ ret = PTR_ERR(sleepm_class);
+ goto class_create_fail;
+ }
+
+ sleepm_device = device_create(sleepm_class, NULL, sleepm_devno, NULL, DEVICE_NAME);
+ if (IS_ERR(sleepm_device)) {
+ ret = -ENOMEM;
+ goto device_create_fail;
+ }
+
+ ret = device_create_file(sleepm_device, &dev_attr_control);
+ if (ret) {
+ pr_err("%s: device_create_file(%s)=%d\n",
+ __func__, dev_attr_control.attr.name, ret);
+ goto device_create_file_fail;
+ }
+
+ return 0;
+
+device_create_file_fail:
+ device_destroy(sleepm_class, sleepm_devno);
+device_create_fail:
+ class_destroy(sleepm_class);
+class_create_fail:
+ unregister_chrdev_region(sleepm_devno, 1);
+alloc_chrdev_region_fail:
+ return ret;
+}
+
+static void __exit sleep_monitor_module_exit(void)
+{
+ device_remove_file(sleepm_device, &dev_attr_control);
+ device_destroy(sleepm_class, sleepm_devno);
+ class_destroy(sleepm_class);
+ unregister_chrdev_region(sleepm_devno, 1);
+}
+
+module_init(sleep_monitor_module_init);
+module_exit(sleep_monitor_module_exit);
+
+MODULE_DESCRIPTION("MSM system event monitor driver");
+MODULE_LICENSE("GPL v2");
diff --git a/arch/arm/mach-msm/sm_event.c b/arch/arm/mach-msm/sm_event.c
new file mode 100644
index 0000000..17ca2bf
--- /dev/null
+++ b/arch/arm/mach-msm/sm_event.c
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/sched.h>
+#include <linux/sm_event.h>
+#include <linux/sm_event_log.h>
+
+static sm_event_ops *event_ops = NULL;
+unsigned int event_mask;
+static atomic_t event_use_count;
+static int32_t enable_flag = 0;
+
+static sm_event_item_t *sm_event_buffer;
+EXPORT_SYMBOL(event_mask);
+
+int32_t sm_event_register (sm_event_ops *ops, sm_event_item_t *event_pool)
+{
+ if (event_ops == NULL) {
+ event_ops = ops;
+ sm_event_buffer = event_pool;
+ atomic_set (&event_use_count, 0);
+ smp_mb();
+ enable_flag = 1;
+ return 0;
+ }
+
+ return -EBUSY;
+}
+EXPORT_SYMBOL(sm_event_register);
+
+int32_t sm_event_unregister (sm_event_ops *ops)
+{
+ if (event_ops == ops) {
+ int32_t retry;
+
+ enable_flag = 0;
+ barrier();
+
+ retry = 3;
+
+ while (retry-- > 0) {
+ if (!atomic_read (&event_use_count)) {
+ event_ops = NULL;
+ sm_event_buffer = NULL;
+ return 0;
+ }
+ schedule();
+ }
+
+ return -EBUSY;
+ }
+
+ return -EINVAL;
+}
+EXPORT_SYMBOL(sm_event_unregister);
+
+int32_t sm_sprint_info (char *buf, int32_t buf_sz, sm_event_item_t *ev, uint32_t count)
+{
+ if (event_ops && event_ops->sm_sprint_info) {
+ uint32_t rc = 0;
+ atomic_inc (&event_use_count);
+
+ if (enable_flag)
+ rc = event_ops->sm_sprint_info(buf, buf_sz, ev, count);
+ atomic_dec (&event_use_count);
+ return rc;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL(sm_sprint_info);
+
+int32_t __sm_add_event(uint32_t event_id, uint32_t param1, int param2, void *data, uint32_t data_len)
+{
+ if (event_ops && event_ops->sm_add_event) {
+ uint32_t rc = 0;
+ atomic_inc (&event_use_count);
+ if (enable_flag)
+ rc = event_ops->sm_add_event(event_id, param1, param2, data, data_len);
+ atomic_dec (&event_use_count);
+ return rc;
+ }
+ return -EINVAL;
+}
+EXPORT_SYMBOL(__sm_add_event);
+
+int32_t sm_get_event_and_data (sm_event_item_t *ev, uint32_t *start, uint32_t *count, uint32_t flag)
+{
+ if (event_ops && event_ops->sm_get_event_and_data) {
+ int32_t rc = 0;
+ atomic_inc (&event_use_count);
+ if (enable_flag)
+ rc = event_ops->sm_get_event_and_data(ev, start, count, flag);
+ atomic_dec (&event_use_count);
+ return rc;
+ }
+
+ return -EINVAL;
+}
+EXPORT_SYMBOL(sm_get_event_and_data);
+
+void sm_set_event_mask(uint32_t mask)
+{
+ event_mask = mask;
+}
+EXPORT_SYMBOL(sm_set_event_mask);
+
+uint32_t sm_get_event_mask(void)
+{
+ return event_mask;
+}
+EXPORT_SYMBOL(sm_get_event_mask);
+
+void sm_set_system_state(int want_state)
+{
+ if (event_ops && event_ops->sm_set_system_state) {
+ atomic_inc (&event_use_count);
+ if (enable_flag)
+ event_ops->sm_set_system_state(want_state);
+ atomic_dec (&event_use_count);
+ }
+}
+EXPORT_SYMBOL(sm_set_system_state);
diff --git a/arch/arm/mach-msm/sm_event_driver.c b/arch/arm/mach-msm/sm_event_driver.c
new file mode 100644
index 0000000..10ca62d
--- /dev/null
+++ b/arch/arm/mach-msm/sm_event_driver.c
@@ -0,0 +1,450 @@
+/*
+ * Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/errno.h>
+#include <linux/cdev.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/types.h>
+#include <linux/delay.h>
+#include <linux/fs.h>
+#include <linux/err.h>
+#include <linux/sched.h>
+#include <linux/poll.h>
+#include <linux/platform_device.h>
+#include <linux/debugfs.h>
+
+#include <asm/uaccess.h>
+#include <asm/byteorder.h>
+
+#include <mach/peripheral-loader.h>
+#include <linux/sm_event_log.h>
+#include <linux/sm_event.h>
+
+#include "smd_rpc_sym.h"
+#include "smd_rpcrouter.h"
+
+#define SM_EVENT_READ_MAXIMUM 10
+
+#ifdef __SM_DEBUG
+static int32_t lock_count = 0;
+
+#define INIT_LOCK(x) \
+{ \
+ mutex_init(x); \
+ lock_count = 0; \
+ printk ("mutex_init: lock_count = %d, addr = %p, actual = %d\n", lock_count, x, ((x)->count).counter); \
+}
+
+#define LOCK(x) \
+{ \
+ lock_count++; \
+ printk ("mutex_lock: lock_count = %d, addr = %p, actual = %d\n", lock_count, x, ((x)->count).counter); \
+ mutex_lock(x); \
+}
+
+#define UNLOCK(x) \
+{ \
+ lock_count--; \
+ printk ("mutex_unlock: lock_count = %d, addr = %p, actual = %d\n", lock_count, x, ((x)->count).counter); \
+ mutex_unlock(x); \
+}
+#else
+#define INIT_LOCK(x) mutex_init(x)
+#define LOCK(x) mutex_lock(x)
+#define UNLOCK(x) mutex_unlock(x)
+#endif
+
+struct sm_event_info
+{
+ int event_cur_pos;
+ struct mutex lock;
+ sm_event_item_t event[SM_EVENT_READ_MAXIMUM];
+};
+
+struct sm_event_debug_info
+{
+ int event_cur_pos;
+ struct mutex lock;
+ sm_event_item_t event[SM_EVENT_READ_MAXIMUM];
+ char debug_buf[PAGE_SIZE];
+ uint32_t read_avail;
+};
+
+struct class *sm_event_class;
+dev_t sm_event_devno;
+static struct device *sm_event_device;
+static struct cdev sm_event_cdev;
+
+struct dentry *sm_event_dir;
+struct dentry *sm_event_log_debugfs;
+struct dentry *sm_event_log_mask_debugfs;
+
+static struct sm_event_debug_info sm_debugfs_info;
+
+static long sm_event_ioctl(struct file *filp, unsigned int cmd,
+ unsigned long arg)
+{
+ return -EINVAL;
+}
+
+static int sm_event_open(struct inode *inode, struct file *filp)
+{
+ struct sm_event_info *log_info;
+
+ log_info = kzalloc(sizeof(struct sm_event_info), GFP_KERNEL);
+
+ log_info->event_cur_pos = 0;
+
+ if (!log_info)
+ return -ENOMEM;
+
+ filp->private_data = log_info;
+ INIT_LOCK (&(log_info->lock));
+ return 0;
+}
+
+static int sm_event_release(struct inode *inode, struct file *filp)
+{
+ kfree (filp->private_data);
+ return 0;
+}
+
+static ssize_t sm_event_read(struct file *filp, char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ uint32_t start, r_count;
+ struct sm_event_info *log_info;
+ sm_event_item_t *ev;
+ int32_t rc = -EFAULT;
+
+ log_info = (struct sm_event_info *)filp->private_data;
+ LOCK(&(log_info->lock));
+
+ r_count = count/sizeof(sm_event_item_t);
+
+ if (r_count > SM_EVENT_READ_MAXIMUM)
+ r_count = SM_EVENT_READ_MAXIMUM;
+
+ start = log_info->event_cur_pos;
+ ev = log_info->event;
+
+ if ((rc = sm_get_event_and_data (ev, &start, &r_count, GET_EVENT_ENABLE_REINDEX)) > 0) {
+ if (!copy_to_user(buf, ev, (r_count * sizeof(sm_event_item_t)))) {
+ log_info->event_cur_pos = start + r_count;
+ rc = 0;
+ } else {
+ rc = -EFAULT;
+ }
+ }
+
+ UNLOCK(&(log_info->lock));
+
+ if (rc)
+ return rc;
+
+ return (r_count * sizeof(sm_event_item_t));
+}
+
+/*
+ * write 0 to reset the read offset
+ */
+static ssize_t sm_event_write(struct file *filp, const char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ struct sm_event_info *log_info;
+ char k_buffer[4];
+ size_t len;
+
+ log_info = (struct sm_event_info *)filp->private_data;
+ LOCK(&(log_info->lock));
+
+ len = count;
+ if (len > sizeof(k_buffer))
+ len = sizeof(k_buffer);
+
+ if (copy_from_user(k_buffer, buf, len)) {
+ UNLOCK(&(log_info->lock));
+ return -EFAULT;
+ }
+
+ /*
+ * reset the read position
+ */
+ if ((k_buffer[0] == '0') || (k_buffer[0] == 0)) {
+ log_info->event_cur_pos = 0;
+ } else {
+ UNLOCK(&(log_info->lock));
+ return -EFAULT;
+ }
+
+ UNLOCK(&(log_info->lock));
+ return 0;
+}
+
+static struct file_operations sm_event_fops = {
+ .owner = THIS_MODULE,
+ .open = sm_event_open,
+ .release = sm_event_release,
+ .read = sm_event_read,
+ .write = sm_event_write,
+ .unlocked_ioctl = sm_event_ioctl,
+};
+
+static int sm_event_debugfs_open(struct inode *inode, struct file *file)
+{
+ return 0;
+}
+
+static int sm_event_debugfs_release(struct inode *inode, struct file *file)
+{
+ return 0;
+}
+
+static ssize_t sm_event_debugfs_read(
+ struct file *file,
+ char __user *buff,
+ size_t buff_count,
+ loff_t *ppos)
+
+{
+ uint32_t start, r_count, e_count;
+ struct sm_event_debug_info *debug_info;
+ sm_event_item_t *ev;
+ int32_t rc = 0;
+
+ debug_info = &sm_debugfs_info;
+
+retry:
+ LOCK(&(debug_info->lock));
+ if (debug_info->read_avail > 0) {
+ r_count = buff_count;
+ if (buff_count > debug_info->read_avail)
+ r_count = debug_info->read_avail;
+
+ if (copy_to_user(buff, debug_info->debug_buf, r_count)) {
+ UNLOCK(&(debug_info->lock));
+ return -EFAULT;
+ }
+
+ debug_info->read_avail -= r_count;
+ UNLOCK(&(debug_info->lock));
+ return r_count;
+ }
+
+ e_count = SM_EVENT_READ_MAXIMUM;
+ if (e_count > SM_EVENT_READ_MAXIMUM)
+ e_count = SM_EVENT_READ_MAXIMUM;
+
+ start = debug_info->event_cur_pos;
+ ev = debug_info->event;
+
+ if ((rc = sm_get_event_and_data (ev,
+ &start,
+ &e_count,
+ GET_EVENT_WAIT_WAKE_ONE | GET_EVENT_ENABLE_REINDEX)) > 0) {
+ rc = sm_sprint_info (debug_info->debug_buf, PAGE_SIZE, ev, e_count);
+ debug_info->event_cur_pos = start + e_count;
+ debug_info->read_avail = rc;
+ UNLOCK(&(debug_info->lock));
+ goto retry;
+ }
+
+ UNLOCK(&(debug_info->lock));
+ return rc;
+}
+
+static ssize_t sm_event_debugfs_write(
+ struct file *file,
+ const char __user *buff,
+ size_t count,
+ loff_t *ppos)
+{
+ struct sm_event_debug_info *debug_info;
+
+ debug_info = &sm_debugfs_info;
+ LOCK(&(debug_info->lock));
+ debug_info->event_cur_pos = 0;
+ debug_info->read_avail = 0;
+ UNLOCK(&(debug_info->lock));
+
+ return 0;
+}
+
+int32_t sm_debugfs_event_callback (sm_event_item_t *ev)
+{
+ return 0;
+}
+
+static const struct file_operations sm_event_log_debug_fops = {
+ .open = sm_event_debugfs_open,
+ .read = sm_event_debugfs_read,
+ .write = sm_event_debugfs_write,
+ .release = sm_event_debugfs_release,
+ .owner = THIS_MODULE,
+};
+
+static int sm_event_log_mask_debugfs_open(struct inode *inode, struct file *file)
+{
+ return 0;
+}
+
+static int sm_event_log_mask_debugfs_release(struct inode *inode, struct file *file)
+{
+ return 0;
+}
+
+static ssize_t sm_event_log_mask_debugfs_read(
+ struct file *file,
+ char __user *buff,
+ size_t buff_count,
+ loff_t *ppos)
+{
+ char mask_value[12];
+ int len;
+
+ len = snprintf(mask_value, 12, "0x%08x\n", sm_get_event_mask());
+
+ return simple_read_from_buffer(buff, buff_count, ppos, mask_value, len);
+}
+
+static ssize_t sm_event_log_mask_debugfs_write(
+ struct file *file,
+ const char __user *buff,
+ size_t count,
+ loff_t *ppos)
+{
+ char buf[64];
+ unsigned long val;
+ int ret;
+
+ if (count >= sizeof(buf))
+ return -EINVAL;
+
+ if (copy_from_user(&buf, buff, count))
+ return -EFAULT;
+
+ buf[count] = 0;
+ ret = strict_strtoul(buf, 0, &val);
+ if (ret < 0)
+ return ret;
+
+ sm_set_event_mask((uint32_t)val);
+
+ return count;
+}
+
+static const struct file_operations sm_event_log_mask_debug_fops = {
+ .open = sm_event_log_mask_debugfs_open,
+ .read = sm_event_log_mask_debugfs_read,
+ .write = sm_event_log_mask_debugfs_write,
+ .release = sm_event_log_mask_debugfs_release,
+ .owner = THIS_MODULE,
+};
+
+static void debugfs_init (void)
+{
+ sm_debugfs_info.event_cur_pos = 0;
+ sm_debugfs_info.read_avail = 0;
+ INIT_LOCK (&(sm_debugfs_info.lock));
+}
+
+static void __exit sm_event_exit(void)
+{
+ cdev_del(&sm_event_cdev);
+ debugfs_remove(sm_event_log_debugfs);
+ debugfs_remove(sm_event_log_mask_debugfs);
+ debugfs_remove(sm_event_dir);
+ device_destroy(sm_event_class, sm_event_devno);
+ unregister_chrdev_region(sm_event_devno, 1);
+ class_destroy(sm_event_class);
+}
+
+static int __init sm_event_init(void)
+{
+ int rc;
+ int major;
+
+ /* Create the device nodes */
+ sm_event_class = class_create(THIS_MODULE, "sm_event_driver");
+
+ if (IS_ERR(sm_event_class)) {
+ rc = -ENOMEM;
+ printk(KERN_ERR
+ "sm_event_driver: failed to create event log class\n");
+ goto alloc_class_fail;
+ }
+
+ rc = alloc_chrdev_region(&sm_event_devno, 0, 1, "sm_event_log");
+ if (rc < 0) {
+ printk(KERN_ERR
+ "sm_event_driver: Failed to alloc chardev region (%d)\n", rc);
+ goto alloc_chr_region_fail;
+ }
+
+ major = MAJOR(sm_event_devno);
+ sm_event_device = device_create(sm_event_class, NULL, sm_event_devno, NULL, "sm_event_log");
+ if (IS_ERR(sm_event_device)) {
+ rc = -ENOMEM;
+ goto device_create_fail;
+ }
+
+ debugfs_init ();
+ sm_event_dir = debugfs_create_file("sm_event", S_IFDIR | S_IRWXU | S_IRWXG | S_IRWXO,
+ NULL, NULL, NULL);
+ if (IS_ERR(sm_event_dir))
+ goto debugfs_create_dir_fail;
+
+ sm_event_log_debugfs = debugfs_create_file("sm_event_log", S_IRWXUGO, sm_event_dir, NULL,
+ &sm_event_log_debug_fops);
+ if (sm_event_log_debugfs == NULL)
+ goto sm_event_log_debugfs_fail;
+
+ sm_event_log_mask_debugfs = debugfs_create_file("sm_event_mask", S_IRWXUGO, sm_event_dir, NULL,
+ &sm_event_log_mask_debug_fops);
+ if (sm_event_log_mask_debugfs == NULL)
+ goto sm_event_log_mask_debugfs_fail;
+
+ cdev_init(&sm_event_cdev, &sm_event_fops);
+ sm_event_cdev.owner = THIS_MODULE;
+
+ rc = cdev_add(&sm_event_cdev, sm_event_devno, 1);
+ if (rc < 0)
+ goto add_cdev_fail;
+
+ return 0;
+
+add_cdev_fail:
+ debugfs_remove(sm_event_log_mask_debugfs);
+sm_event_log_mask_debugfs_fail:
+ debugfs_remove(sm_event_log_debugfs);
+sm_event_log_debugfs_fail:
+ debugfs_remove(sm_event_dir);
+debugfs_create_dir_fail:
+ device_destroy(sm_event_class, sm_event_devno);
+device_create_fail:
+ unregister_chrdev_region(sm_event_devno, 1);
+alloc_chr_region_fail:
+ class_destroy(sm_event_class);
+alloc_class_fail:
+ return rc;
+}
+
+module_init(sm_event_init);
+module_exit(sm_event_exit);
+MODULE_DESCRIPTION("MSM system event monitor driver");
+MODULE_LICENSE("GPL v2");
diff --git a/arch/arm/mach-msm/sm_event_log.c b/arch/arm/mach-msm/sm_event_log.c
new file mode 100644
index 0000000..6dd83c4
--- /dev/null
+++ b/arch/arm/mach-msm/sm_event_log.c
@@ -0,0 +1,759 @@
+/*
+ * Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include "timer.h"
+
+#include <linux/jiffies.h>
+#include <linux/sm_event.h>
+#include <linux/sm_event_log.h>
+#include <mach/msm_battery.h>
+
+#include "smd_rpc_sym.h"
+#include "smd_rpcrouter.h"
+#include <asm/io.h>
+#include <linux/dma-mapping.h>
+#include <mach/msm_iomap.h>
+#include <asm/hardware/cache-l2x0.h>
+#include "cache-ops.h"
+#include <mach/oem_rapi_client.h>
+
+#define CLEAN_ADDR (L2X0_CLEAN_LINE_PA + MSM_L2CC_BASE)
+#define outer_cache_one_line(start) \
+ writel_relaxed((start), CLEAN_ADDR)
+
+#define cache_clean(vaddr) \
+ do { \
+ unsigned long paddr; \
+ cache_clean_nosync_oneline(vaddr, 32); \
+ paddr = (unsigned long)__virt_to_phys(vaddr); \
+ outer_cache_one_line(paddr); \
+ } while (0)
+/*
+ * SM_MAXIMUM_EVENT should be (2^n)
+ */
+#define SM_MAXIMUM_EVENT (1<<10)
+#define SM_MAXIMUM_EVENT_MASK (SM_MAXIMUM_EVENT - 1)
+
+struct sm_event_notify_t
+{
+ struct list_head link;
+ event_notify notify;
+};
+
+struct sm_events_t
+{
+ sm_event_item_t *event_pool;
+ atomic_t read_pos;
+ atomic_t write_pos;
+ uint32_t event_mask;
+ wait_queue_head_t wait_wakeone_q;
+ wait_queue_head_t wait_wakeall_q;
+ uint32_t wait_flag;
+};
+
+typedef int32_t (* sm_event_callback)(uint32_t event_id, uint32_t param1, int param2, void *data, uint32_t data_len);
+struct sm_event_filter
+{
+ sm_state state_start;
+ sm_state state_end;
+ uint32_t event_filter;
+ sm_event_callback callback;
+};
+
+static uint32_t sm_current_state = SM_STATE_NONE;
+sm_periodical_status_data_t sm_periodcal_status;
+
+/*
+ * rtc time in AP may not ready, wait about 10 seconds
+ */
+static uint32_t sm_periodical_ktime_sec_report = 10;
+
+static struct sm_events_t sm_events;
+
+static atomic_t sm_status_report_event;
+
+static struct sm_event_filter sm_event_pre_filter[] =
+{
+ {SM_STATE_EARLYSUSPEND, SM_STATE_LATERESUME, SM_WAKELOCK_EVENT | 0xffff, NULL},
+ {SM_STATE_SUSPEND, SM_STATE_RESUME, SM_CLOCK_EVENT | 0xffff, NULL},
+};
+
+static inline void sm_get_ktime (uint32_t *sec, uint32_t *nanosec);
+static int32_t sm_add_log_event (uint32_t event_id, uint32_t param1, int param2, void *data, uint32_t data_len);
+static int32_t sm_get_log_event_and_data (sm_event_item_t *ev, uint32_t *start, uint32_t *count, uint32_t flag);
+static void sm_set_log_system_state(int want_state);
+static int32_t sm_sprint_log_info (char *buf, int32_t buf_sz, sm_event_item_t *ev, uint32_t count);
+
+sm_event_ops event_log_ops =
+{
+ .sm_add_event = sm_add_log_event,
+ .sm_get_event_and_data = sm_get_log_event_and_data,
+ .sm_set_system_state = sm_set_log_system_state,
+ .sm_sprint_info = sm_sprint_log_info,
+};
+
+static inline int sm_get_event_state(void)
+{
+ return sm_current_state;
+}
+
+static size_t sm_sprint_battery_status (sm_msm_battery_data_t *battery_info, char *buf, int32_t buf_sz)
+{
+ size_t len = 0;
+
+ if (battery_info->charger_status == CHARGER_STATUS_GOOD)
+ len += snprintf(buf + len, buf_sz - len, "charger good, ");
+ else if (battery_info->charger_status == CHARGER_STATUS_WEAK)
+ len += snprintf(buf + len, buf_sz - len, "charger weak, ");
+ else if (battery_info->charger_status == CHARGER_STATUS_NULL)
+ len += snprintf(buf + len, buf_sz - len, "none charger, ");
+
+ len += snprintf(buf + len, buf_sz - len, "battery voltage = %u mV, ",
+ battery_info->battery_voltage);
+
+ len += snprintf(buf + len, buf_sz - len, "battery temp = %u",
+ battery_info->battery_temp);
+
+ return len;
+}
+
+static inline size_t sm_sprint_string_name (char *string_name, char *buf, int32_t buf_sz)
+{
+ return snprintf(buf, buf_sz, "%s ", string_name);
+}
+
+static size_t sm_sprint_wakeup_reason (sm_msm_pm_smem_t *reason, char *buf, int32_t buf_sz)
+{
+ sm_msm_pm_smem_t *wakeup_reason;
+ ssize_t len = 0;
+
+ wakeup_reason = reason;
+ len += snprintf(buf + len, buf_sz - len, ";Wakeup reason ");
+
+ switch(wakeup_reason->wakeup_reason) {
+ case DEM_WAKEUP_REASON_NONE:
+ len += snprintf(buf + len, buf_sz - len, "<none>");
+ break;
+ case DEM_WAKEUP_REASON_SMD:
+ len += snprintf(buf + len, buf_sz - len, "<smd = %s>", wakeup_reason->smd_port_name);
+ break;
+ case DEM_WAKEUP_REASON_INT:
+ len += snprintf(buf + len, buf_sz - len, "<interrupt, pending = 0x%x>", wakeup_reason->pending_irqs);
+ break;
+ case DEM_WAKEUP_REASON_GPIO:
+ len += snprintf(buf + len, buf_sz - len, "<gpio = 0x%x>", wakeup_reason->reserved2);
+ break;
+ case DEM_WAKEUP_REASON_TIMER:
+ len += snprintf(buf + len, buf_sz - len, "<timer>");
+ break;
+ case DEM_WAKEUP_REASON_ALARM:
+ len += snprintf(buf + len, buf_sz - len, "<alarm>");
+ break;
+ case DEM_WAKEUP_REASON_RESET:
+ len += snprintf(buf + len, buf_sz - len, "<reset>");
+ break;
+ case DEM_WAKEUP_REASON_OTHER:
+ len += snprintf(buf + len, buf_sz - len, "<other>");
+ break;
+ case DEM_WAKEUP_REASON_REMOTE:
+ len += snprintf(buf + len, buf_sz - len, "<remote>");
+ break;
+ default:
+ len += snprintf(buf + len, buf_sz - len, "<unknow>");
+ }
+
+ return len;
+}
+
+static char *rpc_type_to_str(int i)
+{
+ switch (i) {
+ case RPCROUTER_CTRL_CMD_DATA:
+ return "data ";
+ case RPCROUTER_CTRL_CMD_HELLO:
+ return "hello ";
+ case RPCROUTER_CTRL_CMD_BYE:
+ return "bye ";
+ case RPCROUTER_CTRL_CMD_NEW_SERVER:
+ return "new_srvr";
+ case RPCROUTER_CTRL_CMD_REMOVE_SERVER:
+ return "rmv_srvr";
+ case RPCROUTER_CTRL_CMD_REMOVE_CLIENT:
+ return "rmv_clnt";
+ case RPCROUTER_CTRL_CMD_RESUME_TX:
+ return "resum_tx";
+ case RPCROUTER_CTRL_CMD_EXIT:
+ return "cmd_exit";
+ default:
+ return "invalid";
+ }
+}
+
+static inline size_t sm_sprint_one_info (char *buf, int32_t buf_sz, sm_event_item_t *ev_item)
+{
+ ssize_t len = 0;
+ sm_msm_rpc_data_t *rpc_data;
+ sm_periodical_status_data_t *status_data;
+ sm_msm_irq_data_t *irq_data;
+
+ len += snprintf(buf + len, buf_sz - len, "[%5u.%06u] Event %d: ",
+ ev_item->sec_time, ev_item->nanosec_time/1000, ev_item->event_seq);
+ switch(ev_item->event_id) {
+ case (SM_POWER_EVENT | SM_POWER_EVENT_EARLY_SUSPEND):
+ len += snprintf(buf + len, buf_sz - len, "EARLY SUSPEND %s",
+ ev_item->param1 == SM_EVENT_START?"start":"success");
+ break;
+ case (SM_POWER_EVENT | SM_POWER_EVENT_SUSPEND):
+ len += snprintf(buf + len, buf_sz - len, "SUSPEND %s",
+ ev_item->param1 == SM_EVENT_START?"start":"success");
+ break;
+ case (SM_POWER_EVENT | SM_POWER_EVENT_RESUME):
+ len += snprintf(buf + len, buf_sz - len, "RESUME %s",
+ ev_item->param1 == SM_EVENT_START?"start":"success");
+ if (ev_item->param1 == SM_EVENT_START) {
+ len += snprintf(buf + len, buf_sz - len, ", slept %d msec ", ev_item->param2);
+ if (ev_item->data_len > 0)
+ len += sm_sprint_wakeup_reason ((sm_msm_pm_smem_t *)&(ev_item->data.wakeup_reason), buf + len, buf_sz - len);
+ }
+ break;
+ case (SM_POWER_EVENT | SM_POWER_EVENT_LATE_RESUME):
+ len += snprintf(buf + len, buf_sz - len, "LATE RESUME %s", ev_item->param1 == SM_EVENT_START?"start":"success");
+ break;
+ case (SM_POWER_EVENT | SM_POWER_EVENT_BATTERY_UPDATE):
+ len += snprintf(buf + len, buf_sz - len, "BATTERY UPDATE, ");
+
+ if (ev_item->data_len > 0)
+ len += sm_sprint_battery_status ((sm_msm_battery_data_t *)&(ev_item->data.battery_info), buf + len, buf_sz - len);
+ break;
+ case (SM_WAKELOCK_EVENT | WAKELOCK_EVENT_ON):
+ len += snprintf(buf + len, buf_sz - len, "WAKE LOCK ");
+
+ if (ev_item->data_len > 0)
+ len += sm_sprint_string_name (ev_item->data.wakelock_name, buf + len, buf_sz - len);
+ len += snprintf(buf + len, buf_sz - len, " on");
+ break;
+ case (SM_WAKELOCK_EVENT | WAKELOCK_EVENT_OFF):
+ len += snprintf(buf + len, buf_sz - len, "WAKE LOCK ");
+
+ if (ev_item->data_len > 0)
+ len += sm_sprint_string_name (ev_item->data.wakelock_name, buf + len, buf_sz - len);
+ len += snprintf(buf + len, buf_sz - len, " off");
+ break;
+ case (SM_DEVICE_EVENT | SM_DEVICE_EVENT_SUSPEND):
+ len += snprintf(buf + len, buf_sz - len, "DEVICE SUSPEND %dus, ", ev_item->param1);
+ if (ev_item->data_len > 0)
+ len += sm_sprint_string_name (ev_item->data.device_name, buf + len, buf_sz - len);
+ break;
+ case (SM_DEVICE_EVENT | SM_DEVICE_EVENT_RESUME):
+ len += snprintf(buf + len, buf_sz - len, "DEVICE RESUME %dus, ", ev_item->param1);
+ if (ev_item->data_len > 0)
+ len += sm_sprint_string_name (ev_item->data.device_name, buf + len, buf_sz - len);
+ break;
+ case (SM_CLOCK_EVENT | SM_CLK_EVENT_SET_ENABLE):
+ len += snprintf(buf + len, buf_sz - len, "CLK, ");
+ if (ev_item->data_len > 0)
+ len += sm_sprint_string_name (ev_item->data.clk_name, buf + len, buf_sz - len);
+ len += snprintf(buf + len, buf_sz - len, " is still enable");
+ break;
+ case (SM_RPCROUTER_EVENT | RPCROUTER_WRITE_CALL):
+ rpc_data = (sm_msm_rpc_data_t *)&(ev_item->data);
+ len += snprintf(buf + len, buf_sz - len, "RPC Call AP--->MP, cid(0x%08x--->0x%08x), 0x%08x:0x%08x(%s), type=%s, %d bytes",
+ rpc_data->src_cid, rpc_data->dst_cid,
+ be32_to_cpu(rpc_data->version), be32_to_cpu(rpc_data->prog),smd_rpc_get_sym(be32_to_cpu(rpc_data->prog)),
+ rpc_type_to_str(rpc_data->type),ev_item->param1);
+ break;
+ case (SM_RPCROUTER_EVENT | RPCROUTER_WRITE_REPLY):
+ rpc_data = (sm_msm_rpc_data_t *)&(ev_item->data);
+ len += snprintf(buf + len, buf_sz - len, "RPC reply AP--->MP, cid(0x%08x--->0x%08x), type=%s, %d bytes",
+ rpc_data->src_cid, rpc_data->dst_cid,
+ rpc_type_to_str(rpc_data->type), ev_item->param1);
+ break;
+ case (SM_RPCROUTER_EVENT | RPCROUTER_READ_CALL):
+ rpc_data = (sm_msm_rpc_data_t *)&(ev_item->data);
+ len += snprintf(buf + len, buf_sz - len, "RPC Call AP<---MP, cid(0x%08x<---0x%08x), 0x%08x:0x%08x(%s), type=%s, %d bytes",
+ rpc_data->dst_cid, rpc_data->src_cid,
+ be32_to_cpu(rpc_data->version), be32_to_cpu(rpc_data->prog),smd_rpc_get_sym(be32_to_cpu(rpc_data->prog)),
+ rpc_type_to_str(rpc_data->type),ev_item->param1);
+ break;
+ case (SM_RPCROUTER_EVENT | RPCROUTER_READ_REPLY):
+ rpc_data = (sm_msm_rpc_data_t *)&(ev_item->data);
+ len += snprintf(buf + len, buf_sz - len, "RPC reply AP<---MP, cid(0x%08x<---0x%08x), type=%s, %d bytes",
+ rpc_data->dst_cid, rpc_data->src_cid,
+ rpc_type_to_str(rpc_data->type), ev_item->param1);
+ break;
+ case (SM_IRQ_EVENT | IRQ_EVENT_ENTER):
+ irq_data = (sm_msm_irq_data_t*)&(ev_item->data);
+ len += snprintf(buf + len, buf_sz - len, "entering irq, irq num = 0x%x, func = %p",
+ irq_data->irq_num, (void*)irq_data->func_addr);
+ break;
+ case (SM_STATUS_EVENT | STATUS_PERIODICAL_SYNC):
+ status_data = (sm_periodical_status_data_t*)&(ev_item->data);
+ len += snprintf(buf + len, buf_sz - len, "PERIODICAL REPORT, rtc time: %u.%9u, battery = %d mV, status = %d",
+ status_data->rtime_sec, status_data->rtime_nanosec,
+ status_data->battery_voltage,
+ ev_item->param1);
+ break;
+ default:
+ len += snprintf(buf + len, buf_sz - len, "unknow event: id = %x, param = 0x%x", ev_item->event_id, ev_item->param1);
+ break;
+ }
+
+ return len;
+}
+
+static void print_event_info (sm_event_item_t *ev)
+{
+#ifdef __SM_DEBUG
+ static char print_buf[4096];
+ sm_sprint_info (print_buf, sizeof(print_buf), ev, 1);
+ printk ("%s", print_buf);
+#endif
+}
+
+static inline int sm_is_event_index_valid (uint32_t index)
+{
+ uint32_t range_min;
+
+ if(atomic_read(&sm_events.read_pos) >= SM_MAXIMUM_EVENT)
+ range_min = atomic_read(&sm_events.read_pos) - SM_MAXIMUM_EVENT;
+ else
+ range_min = 0;
+
+ if ((index > range_min) && (index <= atomic_read(&sm_events.read_pos))) {
+ return 1;
+ }
+
+ return 0;
+}
+
+/*
+ * return valid event count, return < 0 for fail
+ * if start index not in range of the current saved index, return error
+ */
+static int32_t sm_get_event (sm_event_item_t *event, uint32_t *start, uint32_t *count)
+{
+ uint32_t buf_start, buf_count, buf_index;
+ sm_event_item_t *ev;
+
+ if (*count < 1)
+ return -EINVAL;
+
+ if (!sm_is_event_index_valid (*start)) {
+ return -EINVAL;
+ }
+
+ buf_start = *start;
+ buf_count = *count;
+
+ if ((buf_start + buf_count) > (atomic_read(&sm_events.read_pos) + 1))
+ buf_count = atomic_read(&sm_events.read_pos) + 1 - buf_start;
+
+ buf_index = 0;
+ ev = event;
+ while (buf_index++ < buf_count) {
+ memcpy (ev, &sm_events.event_pool[buf_start&SM_MAXIMUM_EVENT_MASK], sizeof(sm_event_item_t));
+ //the buffer is flushed
+ if (ev->event_seq != buf_start) {
+ buf_start++;
+ continue;
+ }
+
+ buf_start++;
+ ev++;
+ }
+
+ if (ev == event)
+ return -EAGAIN;
+
+ *count = buf_count;
+ return buf_count;
+}
+
+static void sm_notify_event (sm_event_item_t *ev)
+{
+ if (sm_events.wait_flag & GET_EVENT_WAIT_WAKE_ALL) {
+ sm_events.wait_flag &= ~GET_EVENT_WAIT_WAKE_ALL;
+ wake_up_all (&sm_events.wait_wakeall_q);
+ }
+
+ if (sm_events.wait_flag & GET_EVENT_WAIT_WAKE_ONE) {
+ sm_events.wait_flag &= ~(GET_EVENT_WAIT_WAKE_ONE);
+ wake_up (&sm_events.wait_wakeone_q);
+ }
+}
+
+static void fixup_event (sm_event_item_t *ev)
+{
+ if (ev->sec_time >= sm_periodical_ktime_sec_report) {
+ sm_periodical_ktime_sec_report = ev->sec_time + 30*60;
+ atomic_set(&sm_status_report_event, 1);
+ }
+}
+
+static inline int32_t sm_event_pre_handle (uint32_t event_id, uint32_t param1, int param2, void *data, uint32_t data_len)
+{
+ int32_t i;
+ struct sm_event_filter *filter;
+
+ for ( i = 0; i < sizeof(sm_event_pre_filter)/sizeof(sm_event_pre_filter[0]); i++) {
+ filter = &sm_event_pre_filter[i];
+
+ if ((filter->event_filter & event_id) == event_id) {
+ if ((sm_current_state >= filter->state_start) && (sm_current_state <= filter->state_end)) {
+ if (filter->callback)
+ filter->callback (event_id, param1, param2, data, data_len);
+ return 0;
+ }
+ else
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+static void sm_update_read_pos (sm_event_item_t *ev)
+{
+ uint32_t start, end, i, ev_index;
+ sm_event_item_t *ev_item;
+
+ start = atomic_read (&sm_events.read_pos);
+ end = atomic_read (&sm_events.write_pos);
+
+ for (i = start + 1; i <= end; i++) {
+ ev_item = &(sm_events.event_pool[i&SM_MAXIMUM_EVENT_MASK]);
+ ev_index = ev_item->event_seq;
+
+ if (atomic_read(&ev_item->done) != ev_index)
+ return;
+ }
+
+ if (end == atomic_read(&sm_events.write_pos)) {
+ atomic_set (&sm_events.read_pos, end);
+ sm_notify_event (ev);
+ }
+}
+
+static inline void sm_get_ktime (uint32_t *sec, uint32_t *nanosec)
+{
+ int this_cpu;
+ unsigned long flags;
+ unsigned long long t;
+
+ raw_local_irq_save(flags);
+ this_cpu = smp_processor_id();
+ t = cpu_clock(this_cpu);
+ raw_local_irq_restore(flags);
+
+ *nanosec = do_div(t, 1000000000);
+ *sec= (unsigned long)t;
+}
+
+static void sm_report_periodical_status (void)
+{
+ struct timespec ts;
+
+ getnstimeofday(&ts);
+ sm_periodcal_status.rtime_sec = ts.tv_sec;
+ sm_periodcal_status.rtime_nanosec = ts.tv_nsec;
+ sm_periodcal_status.battery_voltage = msm_batt_get_batt_voltage();
+
+ sm_add_log_event(SM_STATUS_EVENT | STATUS_PERIODICAL_SYNC, sm_current_state,
+ 0, (void *)&sm_periodcal_status, sizeof(sm_periodical_status_data_t));
+}
+
+static __always_inline void log_irq_info(unsigned long ip, unsigned int flags, unsigned long caller, unsigned long r0)
+{
+ unsigned int irq_idx;
+
+#ifdef CONFIG_SMP
+ irq_idx = atomic_inc_return(&g_track_index);
+ irq_idx = irq_idx & (TRACK_BUF_SIZE - 1);
+#else
+ g_track_index++;
+ irq_idx = g_track_index & (TRACK_BUF_SIZE - 1);
+#endif
+ g_track_irq_buf[irq_idx].ip = ip;
+ g_track_irq_buf[irq_idx].flags = flags;
+ g_track_irq_buf[irq_idx].caller = caller;
+#ifdef CONFIG_SMP
+ g_track_irq_buf[irq_idx].cpuid = smp_processor_id();
+#endif
+ g_track_irq_buf[irq_idx].reserved[0] = current->pid;
+ g_track_irq_buf[irq_idx].reserved[1] = r0;
+
+ g_track_irq_buf[irq_idx].cycles = jiffies;
+
+/*
+ cache_clean((unsigned long)(g_track_irq_buf + g_track_index));
+ cache_clean((unsigned long)(&g_track_index));
+*/
+}
+
+static int32_t sm_add_log_event(uint32_t event_id, uint32_t param1, int param2, void *data, uint32_t data_len)
+{
+ sm_event_item_t *ev;
+ sm_event_data_t *ev_data;
+ uint32_t cur_index;
+ int32_t rc;
+
+ /* for performace reason, irqs on/off occurs more frequently */
+ if (likely(event_id & SM_IRQ_ONOFF_EVENT)) {
+ /* no need to check if data is NULL since it
+ * is called by track_hardirqs_on/off
+ */
+ log_irq_info(param1, param2, ((unsigned long*)data)[0], ((unsigned long*)data)[1]);
+ return 0;
+ }
+
+ rc = sm_event_pre_handle (event_id, param1, param2, data, data_len);
+ if (rc ) {
+ return rc;
+ }
+
+ cur_index = atomic_inc_return (&sm_events.write_pos);
+ ev = &(sm_events.event_pool[cur_index&SM_MAXIMUM_EVENT_MASK]);
+
+ ev_data = &(ev->data);
+ ev->event_seq = cur_index;
+ barrier();
+ ev->event_id = event_id;
+ ev->param1 = param1;
+ ev->param2 = param2;
+ ev->data_len = data_len;
+
+ if ((data_len > 0) && (data_len <= sizeof(sm_event_data_t))) {
+ memcpy (ev_data, data, data_len);
+ } else if (data_len > sizeof(sm_event_data_t)) {
+ printk ("%s: Warning: the data buffer is too small to store event\n", __func__);
+ printk ("event_seq = 0x%x, event_id = 0x%x, ev_param = 0x%x, param2 = 0x%x, data len = %d\n",
+ ev->event_seq, ev->event_id, ev->param1, ev->param2, data_len);
+ ev->data_len = 0;
+ ((char *)ev_data)[0] = 0;
+ }
+
+ sm_get_ktime (&ev->sec_time, &ev->nanosec_time);
+ fixup_event (ev);
+
+ barrier();
+ atomic_set(&ev->done, cur_index);
+
+ sm_update_read_pos (ev);
+ print_event_info(ev);
+
+ if (atomic_cmpxchg(&sm_status_report_event, 1, 0) == 1)
+ sm_report_periodical_status ();
+ return 0;
+}
+
+static unsigned long get_phys(unsigned long virtp)
+{
+ pgd_t *pgd;
+ pud_t *pud;
+ pmd_t *pmd;
+ pte_t *pte;
+ struct mm_struct *mm = &init_mm;
+
+ /* built-in case */
+ if (virtp >= PAGE_OFFSET)
+ return (__pa(virtp));
+
+ /* kernel module case */
+ pgd = pgd_offset(mm, virtp);
+ if (!(pgd_none(*pgd) || pgd_bad(*pgd))) {
+ /* XXX: need to check if pud is valid */
+ pud = pud_offset(pgd, virtp);
+ pmd = pmd_offset(pud, virtp);
+ if (!(pmd_none(*pmd) || pmd_bad(*pmd))) {
+ pte = pte_offset_kernel(pmd, virtp);
+ if (pte_present(*pte)) {
+ return __pa(page_address(pte_page(*pte)) +
+ (virtp & ~PAGE_MASK));
+ }
+ }
+ }
+
+ return 0;
+}
+
+static int32_t sm_log_event_init (void)
+{
+#ifdef CONFIG_MSM_AMSS_ENHANCE_DEBUG
+ nzi_buf_item_type input;
+#endif
+
+ sm_events.event_pool = (sm_event_item_t *)kmalloc(sizeof(sm_event_item_t)*SM_MAXIMUM_EVENT, GFP_KERNEL);
+ if (sm_events.event_pool == NULL) {
+ printk ("%s: ERROR, can't malloc %d size of data\n",
+ __func__, sizeof(sm_event_item_t)*SM_MAXIMUM_EVENT);
+ return -ENOMEM;
+ }
+#ifdef CONFIG_MSM_AMSS_ENHANCE_DEBUG
+ input.extension.len = 1;
+ input.extension.data[0] = (uint32_t)get_phys((unsigned long)&sm_events.write_pos);
+ input.address = (uint32_t)__virt_to_phys((unsigned long)sm_events.event_pool);
+ input.size = sizeof(sm_event_item_t) * SM_MAXIMUM_EVENT;
+ strncpy(input.file_name, "smevent",
+ NZI_ITEM_FILE_NAME_LENGTH);
+ input.file_name[NZI_ITEM_FILE_NAME_LENGTH - 1] = 0;
+ send_modem_logaddr(&input);
+
+ input.extension.len = 1;
+ input.extension.data[0] = (uint32_t)__virt_to_phys((unsigned long)&g_track_index);
+ input.address = (uint32_t)__virt_to_phys((unsigned long)g_track_irq_buf);
+ input.size = sizeof(struct traceirq_entry) * TRACK_BUF_SIZE;
+ strncpy(input.file_name, "irqx",
+ NZI_ITEM_FILE_NAME_LENGTH);
+ input.file_name[NZI_ITEM_FILE_NAME_LENGTH - 1] = 0;
+ send_modem_logaddr(&input);
+#endif
+
+ init_waitqueue_head(&(sm_events.wait_wakeone_q));
+ init_waitqueue_head(&(sm_events.wait_wakeall_q));
+ sm_events.wait_flag = 0;
+ atomic_set(&sm_events.read_pos, 0);
+ atomic_set(&sm_events.write_pos, 0);
+ sm_set_log_system_state (SM_STATE_RUNNING);
+ return 0;
+}
+
+static void sm_log_event_cleanup (void)
+{
+ kfree (sm_events.event_pool);
+ sm_events.event_pool = NULL;
+}
+
+int32_t sm_sprint_log_info (char *buf, int32_t buf_sz, sm_event_item_t *ev, uint32_t count)
+{
+ uint32_t i;
+ ssize_t len = 0;
+
+ for (i = 0; i < count; i++)
+ {
+ len += sm_sprint_one_info (buf + len, buf_sz - len, ev + i);
+ len += snprintf(buf + len, buf_sz - len, "\n");
+ }
+
+ return len;
+}
+
+static int32_t sm_get_log_event_and_data (sm_event_item_t *ev, uint32_t *start, uint32_t *count, uint32_t flag)
+{
+ int32_t rc = 0;
+ uint32_t new_start = 0, new_count = 0;
+
+ if (ev == NULL) {
+ printk ("%s: can't store event to NULL address\n", __func__);
+ return -EINVAL;
+ }
+
+retry:
+ new_start = *start;
+ new_count = *count;
+
+ if (flag & GET_EVENT_ENABLE_REINDEX) {
+ new_start = *start;
+
+ if ((new_start + SM_MAXIMUM_EVENT <= atomic_read(&sm_events.read_pos)))
+ new_start = atomic_read(&sm_events.read_pos) - SM_MAXIMUM_EVENT + 1;
+
+ if (new_start == 0)
+ new_start = 1;
+ }
+
+ if (new_start > atomic_read(&sm_events.read_pos)) {
+ if (flag & GET_EVENT_WAIT_WAKE_ONE) {
+ sm_events.wait_flag |= GET_EVENT_WAIT_WAKE_ONE;
+ rc = wait_event_interruptible (sm_events.wait_wakeone_q,
+ new_start <= atomic_read(&sm_events.read_pos));
+
+ if (rc )
+ return rc;
+ } else if (flag & GET_EVENT_WAIT_WAKE_ALL) {
+ sm_events.wait_flag |= GET_EVENT_WAIT_WAKE_ALL;
+ rc = wait_event_interruptible (sm_events.wait_wakeall_q,
+ new_start <= atomic_read(&sm_events.read_pos));
+ if (rc )
+ return rc;
+ } else {
+ return -ERANGE;
+ }
+ }
+
+ if((rc = sm_get_event (ev, &new_start, &new_count)) > 0) {
+ *start = new_start;
+ *count = new_count;
+ }
+
+ if (rc == -EAGAIN)
+ goto retry;
+
+ return rc;
+}
+
+static void sm_set_log_system_state(int want_state)
+{
+ if(want_state > SM_STATE_NONE && want_state < SM_STATE_INVALID)
+ sm_current_state = want_state;
+}
+
+int32_t sm_log_event_register (void)
+{
+ int32_t rc;
+
+ rc = sm_log_event_init ();
+ if (rc)
+ return rc;
+ rc = sm_event_register (&event_log_ops, sm_events.event_pool);
+ if (rc) {
+ sm_log_event_cleanup();
+ return rc;
+ }
+
+ printk ("%s\n", __func__);
+ return 0;
+}
+
+int32_t sm_log_event_unregister (void)
+{
+ int32_t rc;
+
+ rc = sm_event_unregister (&event_log_ops);
+
+ if (rc)
+ return rc;
+
+ sm_log_event_cleanup ();
+ return 0;
+}
+
+static int __init sm_log_event_module_init(void)
+{
+ return sm_log_event_register ();
+}
+
+static void __exit sm_log_event_module_exit(void)
+{
+ sm_log_event_unregister ();
+}
+
+module_init(sm_log_event_module_init);
+module_exit(sm_log_event_module_exit);
+MODULE_DESCRIPTION("MSM system event monitor driver");
+MODULE_LICENSE("GPL v2");
diff --git a/arch/arm/mach-msm/smd.c b/arch/arm/mach-msm/smd.c
index 67da5d5..2f4a410 100644
--- a/arch/arm/mach-msm/smd.c
+++ b/arch/arm/mach-msm/smd.c
@@ -1,5 +1,5 @@
/* arch/arm/mach-msm/smd.c
- *
+ * Copyright (c) 2012, The Linux Foundation. All Rights Reserved.
* Copyright (C) 2007 Google, Inc.
* Copyright (c) 2008-2012, The Linux Foundation. All rights reserved.
* Author: Brian Swetland <swetland@google.com>
@@ -76,6 +76,7 @@ uint32_t SMSM_NUM_HOSTS = 3;
#define LEGACY_MODEM_SMSM_MASK (SMSM_RESET | SMSM_INIT | SMSM_SMDINIT \
| SMSM_RUN | SMSM_SYSTEM_DOWNLOAD)
+
enum {
MSM_SMD_DEBUG = 1U << 0,
MSM_SMSM_DEBUG = 1U << 1,
@@ -2615,7 +2616,7 @@ static irqreturn_t smsm_irq_handler(int irq, void *data)
old_apps = apps = __raw_readl(SMSM_STATE_ADDR(SMSM_APPS_STATE));
- SMSM_DBG("<SM %08x %08x>\n", apps, modm);
+ SMSM_INFO("<SM %08x %08x>\n", apps, modm);
if (apps & SMSM_RESET) {
/* If we get an interrupt and the apps SMSM_RESET
bit is already set, the modem is acking the
@@ -2638,7 +2639,8 @@ static irqreturn_t smsm_irq_handler(int irq, void *data)
outer_flush_all();
}
modem_queue_start_reset_notify();
-
+ modm |= SMSM_SYSTEM_DOWNLOAD; //this will result the MP reset and go into download mode
+ smsm_change_state(SMSM_APPS_STATE, modm, modm);
} else if (modm & SMSM_INIT) {
if (!(apps & SMSM_INIT)) {
apps |= SMSM_INIT;
diff --git a/arch/arm/mach-msm/smd_rpcrouter.c b/arch/arm/mach-msm/smd_rpcrouter.c
index 2a23ee6..7de4b34 100644
--- a/arch/arm/mach-msm/smd_rpcrouter.c
+++ b/arch/arm/mach-msm/smd_rpcrouter.c
@@ -53,6 +53,11 @@
#include "smd_rpc_sym.h"
#include "smd_private.h"
+#ifdef CONFIG_MSM_SM_EVENT
+ #include <linux/sm_event_log.h>
+ #include <linux/sm_event.h>
+#endif
+
enum {
SMEM_LOG = 1U << 0,
RTR_DBG = 1U << 1,
@@ -1567,6 +1572,9 @@ int msm_rpc_write(struct msm_rpc_endpoint *ept, void *buffer, int count)
int first_pkt = 1;
uint32_t mid;
unsigned long flags;
+#ifdef CONFIG_MSM_SM_EVENT
+ sm_msm_rpc_data_t tmp;
+#endif
/* snoop the RPC packet and enforce permissions */
@@ -1665,6 +1673,31 @@ int msm_rpc_write(struct msm_rpc_endpoint *ept, void *buffer, int count)
}
write_release_lock:
+#ifdef CONFIG_MSM_SM_EVENT
+ //RPC CALL
+ if (rq->type == 0) {
+ tmp.prog = ept->dst_prog;
+ tmp.version = ept->dst_vers;
+ tmp.type = hdr.type;
+ tmp.src_pid = hdr.src_pid;
+ tmp.src_cid = hdr.src_cid;
+ tmp.confirm_rx = hdr.confirm_rx;
+ tmp.size = hdr.size;
+ tmp.dst_pid = hdr.dst_pid;
+ tmp.dst_cid = hdr.dst_cid;
+ sm_add_event(SM_RPCROUTER_EVENT | RPCROUTER_WRITE_CALL, count, 0, (void*)&tmp, sizeof(tmp));
+ } else {
+ tmp.dst_pid = hdr.dst_pid;
+ tmp.type = hdr.type;
+ tmp.src_pid = hdr.src_pid;
+ tmp.src_cid = hdr.src_cid;
+ tmp.confirm_rx = hdr.confirm_rx;
+ tmp.size = hdr.size;
+ tmp.dst_cid = hdr.dst_cid;
+ sm_add_event(SM_RPCROUTER_EVENT | RPCROUTER_WRITE_REPLY, count, 0, (void*)&tmp, sizeof(tmp));
+ }
+#endif
+
/* if reply, release wakelock after writing to the transport */
if (rq->type != 0) {
/* Upon failure, add reply tag to the pending list.
@@ -1827,6 +1860,9 @@ int __msm_rpc_read(struct msm_rpc_endpoint *ept,
struct msm_rpc_reply *reply;
unsigned long flags;
int rc;
+#ifdef CONFIG_MSM_SM_EVENT
+ sm_msm_rpc_data_t tmp;
+#endif
rc = wait_for_restart_and_notify(ept);
if (rc)
@@ -1898,6 +1934,32 @@ int __msm_rpc_read(struct msm_rpc_endpoint *ept,
*frag_ret = pkt->first;
rq = (void*) pkt->first->data;
+#ifdef CONFIG_MSM_SM_EVENT
+
+ //RPC CALL
+ if (rq->type == 0) {
+ tmp.prog = rq->prog;
+ tmp.version = rq->vers;
+ tmp.type = pkt->hdr.type;
+ tmp.src_pid = pkt->hdr.src_pid;
+ tmp.src_cid = pkt->hdr.src_cid;
+ tmp.confirm_rx = pkt->hdr.confirm_rx;
+ tmp.size = pkt->hdr.size;
+ tmp.dst_pid = pkt->hdr.dst_pid;
+ tmp.dst_cid = pkt->hdr.dst_cid;
+ sm_add_event(SM_RPCROUTER_EVENT | RPCROUTER_READ_CALL , rc, 0, (void*)&tmp, sizeof(tmp));
+ } else {
+ tmp.type = pkt->hdr.type;
+ tmp.src_pid = pkt->hdr.src_pid;
+ tmp.src_cid = pkt->hdr.src_cid;
+ tmp.confirm_rx = pkt->hdr.confirm_rx;
+ tmp.size = pkt->hdr.size;
+ tmp.dst_pid = pkt->hdr.dst_pid;
+ tmp.dst_cid = pkt->hdr.dst_cid;
+ sm_add_event(SM_RPCROUTER_EVENT | RPCROUTER_READ_REPLY, rc, 0, (void*)&tmp, sizeof(tmp));
+ }
+#endif
+
if ((rc >= (sizeof(uint32_t) * 3)) && (rq->type == 0)) {
/* RPC CALL */
reply = get_avail_reply(ept);
diff --git a/arch/arm/mach-msm/smem_log.c b/arch/arm/mach-msm/smem_log.c
index 1798bd3..e43e0a8 100644
--- a/arch/arm/mach-msm/smem_log.c
+++ b/arch/arm/mach-msm/smem_log.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008-2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2008-2013, The Linux Foundation. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -2002,7 +2002,7 @@ static int smem_log_initialize(void)
return ret;
}
- smem_log_enable = 1;
+ smem_log_enable = 0;
smem_log_initialized = 1;
smem_log_debugfs_init();
return ret;
diff --git a/arch/arm/mach-msm/socinfo.c b/arch/arm/mach-msm/socinfo.c
index b82604c..e57f5f7 100644
--- a/arch/arm/mach-msm/socinfo.c
+++ b/arch/arm/mach-msm/socinfo.c
@@ -21,6 +21,7 @@
#include <mach/socinfo.h>
#include "smd_private.h"
+#include <mach/proc_comm.h>
#define BUILD_ID_LENGTH 32
@@ -35,7 +36,14 @@ enum {
HW_PLATFORM_LIQUID = 9,
/* Dragonboard platform id is assigned as 10 in CDT */
HW_PLATFORM_DRAGON = 10,
+ HW_PLATFORM_8X25_EVB = 0xC,
HW_PLATFORM_EVBD = 13,
+ HW_PLATFORM_SKU7 = 0xF,
+ HW_PLATFORM_ALASKA = 0xA0,
+ HW_PLATFORM_8X25_QRD5 = 0xA2,
+ HW_PLATFORM_7X27_QRD5A = 0xA3,
+ HW_PLATFORM_8X25Q_SKUD = 0xA7,
+ HW_PLATFORM_8X25Q_SKUE = 0xA8,
HW_PLATFORM_INVALID
};
@@ -49,10 +57,28 @@ const char *hw_platform[] = {
[HW_PLATFORM_MTP] = "MTP",
[HW_PLATFORM_LIQUID] = "Liquid",
[HW_PLATFORM_EVBD] = "EVBD",
- [HW_PLATFORM_DRAGON] = "Dragon"
+ [HW_PLATFORM_DRAGON] = "Dragon",
+ [HW_PLATFORM_8X25_EVB] = "msm8x25_evb",
+ [HW_PLATFORM_SKU7] = "msm7627a_sku7",
+ [HW_PLATFORM_ALASKA] = "msm7627a_skua",
+ [HW_PLATFORM_8X25_QRD5] = "msm8x25_sku5",
+ [HW_PLATFORM_7X27_QRD5A] = "msm7x27_sku5a",
+ [HW_PLATFORM_8X25Q_SKUD] = "msm8x25q_skud",
+ [HW_PLATFORM_8X25Q_SKUE] = "msm8x25q_skue"
};
enum {
+ MULTI_NO_DSDS = 0,
+ MULTI = 1,
+ UMTS = 2
+};
+
+const char *modem_type[] = {
+ [MULTI_NO_DSDS] = "MULTI_NO_DSDS",
+ [MULTI] = "MULTI",
+ [UMTS] = "UMTS"
+};
+enum {
ACCESSORY_CHIP_UNKNOWN = 0,
ACCESSORY_CHIP_CHARM = 58,
};
@@ -414,6 +440,26 @@ socinfo_show_version(struct sys_device *dev,
}
static ssize_t
+socinfo_show_modem_type(struct sys_device *dev,
+ struct sysdev_attribute *attr,
+ char *buf)
+{
+ uint32_t version;
+ int ret;
+
+ if (!socinfo) {
+ pr_err("%s: No socinfo found!\n", __func__);
+ return 0;
+ }
+
+ ret = msm_proc_comm(PCOM_GET_MODEM_VERSION, &version, NULL);
+ if ((ret >= 0) && (version <= UMTS))
+ return snprintf(buf, PAGE_SIZE, "%s\n", modem_type[version]);
+ else
+ return 0;
+}
+
+static ssize_t
socinfo_show_build_id(struct sys_device *dev,
struct sysdev_attribute *attr,
char *buf)
@@ -588,6 +634,7 @@ static struct sysdev_attribute socinfo_v1_files[] = {
_SYSDEV_ATTR(id, 0444, socinfo_show_id, NULL),
_SYSDEV_ATTR(version, 0444, socinfo_show_version, NULL),
_SYSDEV_ATTR(build_id, 0444, socinfo_show_build_id, NULL),
+ _SYSDEV_ATTR(modem_type, 0444, socinfo_show_modem_type, NULL),
};
static struct sysdev_attribute socinfo_v2_files[] = {
@@ -731,8 +778,11 @@ static void * __init setup_dummy_socinfo(void)
return (void *) &dummy_socinfo;
}
+char socinfo_buf[200];
int __init socinfo_init(void)
{
+ char *s = socinfo_buf;
+ memset(socinfo_buf, 0 , 200);
socinfo = smem_alloc(SMEM_HW_SW_BUILD_ID, sizeof(struct socinfo_v7));
if (!socinfo)
@@ -774,52 +824,57 @@ int __init socinfo_init(void)
switch (socinfo->v1.format) {
case 1:
- pr_info("%s: v%u, id=%u, ver=%u.%u\n",
- __func__, socinfo->v1.format, socinfo->v1.id,
+ sprintf(s, "v%u, id=%u, ver=%u.%u ",
+ socinfo->v1.format, socinfo->v1.id,
SOCINFO_VERSION_MAJOR(socinfo->v1.version),
SOCINFO_VERSION_MINOR(socinfo->v1.version));
+ pr_info("%s %s\n", __func__, socinfo_buf);
break;
case 2:
- pr_info("%s: v%u, id=%u, ver=%u.%u, "
- "raw_id=%u, raw_ver=%u\n",
- __func__, socinfo->v1.format, socinfo->v1.id,
+ sprintf(s,"v%u, id=%u, ver=%u.%u, "
+ "raw_id=%u, raw_ver=%u",
+ socinfo->v1.format, socinfo->v1.id,
SOCINFO_VERSION_MAJOR(socinfo->v1.version),
SOCINFO_VERSION_MINOR(socinfo->v1.version),
socinfo->v2.raw_id, socinfo->v2.raw_version);
+ pr_info("%s %s\n", __func__, socinfo_buf);
break;
case 3:
- pr_info("%s: v%u, id=%u, ver=%u.%u, "
- "raw_id=%u, raw_ver=%u, hw_plat=%u\n",
- __func__, socinfo->v1.format, socinfo->v1.id,
+ sprintf(s,"v%u, id=%u, ver=%u.%u, "
+ "raw_id=%u, raw_ver=%u, hw_plat=%u ",
+ socinfo->v1.format, socinfo->v1.id,
SOCINFO_VERSION_MAJOR(socinfo->v1.version),
SOCINFO_VERSION_MINOR(socinfo->v1.version),
socinfo->v2.raw_id, socinfo->v2.raw_version,
socinfo->v3.hw_platform);
+ pr_info("%s %s\n", __func__, socinfo_buf);
break;
case 4:
- pr_info("%s: v%u, id=%u, ver=%u.%u, "
- "raw_id=%u, raw_ver=%u, hw_plat=%u, hw_plat_ver=%u\n",
- __func__, socinfo->v1.format, socinfo->v1.id,
+ sprintf(s,"v%u, id=%u, ver=%u.%u, "
+ "raw_id=%u, raw_ver=%u, hw_plat=%u, hw_plat_ver=%u",
+ socinfo->v1.format, socinfo->v1.id,
SOCINFO_VERSION_MAJOR(socinfo->v1.version),
SOCINFO_VERSION_MINOR(socinfo->v1.version),
socinfo->v2.raw_id, socinfo->v2.raw_version,
socinfo->v3.hw_platform, socinfo->v4.platform_version);
+ pr_info("%s %s\n", __func__, socinfo_buf);
break;
case 5:
- pr_info("%s: v%u, id=%u, ver=%u.%u, "
- "raw_id=%u, raw_ver=%u, hw_plat=%u, hw_plat_ver=%u\n"
- " accessory_chip=%u\n", __func__, socinfo->v1.format,
+ sprintf(s,"v%u, id=%u, ver=%u.%u, "
+ "raw_id=%u, raw_ver=%u, hw_plat=%u, hw_plat_ver=%u"
+ " accessory_chip=%u\n", socinfo->v1.format,
socinfo->v1.id,
SOCINFO_VERSION_MAJOR(socinfo->v1.version),
SOCINFO_VERSION_MINOR(socinfo->v1.version),
socinfo->v2.raw_id, socinfo->v2.raw_version,
socinfo->v3.hw_platform, socinfo->v4.platform_version,
socinfo->v5.accessory_chip);
+ pr_info("%s %s\n", __func__, socinfo_buf);
break;
case 6:
- pr_info("%s: v%u, id=%u, ver=%u.%u, "
- "raw_id=%u, raw_ver=%u, hw_plat=%u, hw_plat_ver=%u\n"
- " accessory_chip=%u hw_plat_subtype=%u\n", __func__,
+ sprintf(s,"v%u, id=%u, ver=%u.%u, "
+ "raw_id=%u, raw_ver=%u, hw_plat=%u, hw_plat_ver=%u"
+ " accessory_chip=%u hw_plat_subtype=%u\n",
socinfo->v1.format,
socinfo->v1.id,
SOCINFO_VERSION_MAJOR(socinfo->v1.version),
@@ -828,10 +883,10 @@ int __init socinfo_init(void)
socinfo->v3.hw_platform, socinfo->v4.platform_version,
socinfo->v5.accessory_chip,
socinfo->v6.hw_platform_subtype);
+ pr_info("%s %s\n", __func__, socinfo_buf);
break;
case 7:
- pr_info("%s: v%u, id=%u, ver=%u.%u, raw_id=%u, raw_ver=%u, hw_plat=%u, hw_plat_ver=%u\n accessory_chip=%u, hw_plat_subtype=%u, pmic_model=%u, pmic_die_revision=%u\n",
- __func__,
+ sprintf(s,"v%u, id=%u, ver=%u.%u, raw_id=%u, raw_ver=%u, hw_plat=%u, hw_plat_ver=%u\n accessory_chip=%u, hw_plat_subtype=%u, pmic_model=%u, pmic_die_revision=%u",
socinfo->v1.format,
socinfo->v1.id,
SOCINFO_VERSION_MAJOR(socinfo->v1.version),
@@ -842,12 +897,12 @@ int __init socinfo_init(void)
socinfo->v6.hw_platform_subtype,
socinfo->v7.pmic_model,
socinfo->v7.pmic_die_revision);
+ pr_info("%s %s\n", __func__, socinfo_buf);
break;
default:
pr_err("%s: Unknown format found\n", __func__);
break;
}
-
return 0;
}
diff --git a/arch/arm/mach-msm/timer.c b/arch/arm/mach-msm/timer.c
index 91384bb..eceeae0 100644
--- a/arch/arm/mach-msm/timer.c
+++ b/arch/arm/mach-msm/timer.c
@@ -231,9 +231,14 @@ static uint32_t msm_read_timer_count(struct msm_clock *clock, int global)
if ((t2 >= t1) && (t3 >= t2))
return t2;
if (++loop_count == 5) {
- pr_err("msm_read_timer_count timer %s did not "
- "stabilize: %u -> %u -> %u\n",
- clock->clockevent.name, t1, t2, t3);
+ /* FIXME: this "printk_rtc" has the race condition in SMP case */
+ /*
+ extern bool printk_rtc;
+ if (!printk_rtc)
+ pr_err("msm_read_timer_count timer %s did not "
+ "stabilize: %u -> %u -> %u\n",
+ clock->clockevent.name, t1, t2, t3);
+ */
return t3;
}
}
@@ -1021,7 +1026,7 @@ static void __init msm_timer_init(void)
if (cpu_is_msm7x01() || cpu_is_msm7x25() || cpu_is_msm7x27() ||
cpu_is_msm7x25a() || cpu_is_msm7x27a() || cpu_is_msm7x25aa() ||
cpu_is_msm7x27aa() || cpu_is_msm8625() || cpu_is_msm7x25ab() ||
- cpu_is_msm8625q()) {
+ cpu_is_msm8625q()) {
dgt->shift = MSM_DGT_SHIFT;
dgt->freq = 19200000 >> MSM_DGT_SHIFT;
dgt->clockevent.shift = 32 + MSM_DGT_SHIFT;
@@ -1125,8 +1130,8 @@ static void __init msm_timer_init(void)
ce->irq = clock->irq;
if (cpu_is_msm8x60() || cpu_is_msm8960() || cpu_is_apq8064() ||
cpu_is_msm8930() || cpu_is_msm8930aa() ||
- cpu_is_msm9615() || cpu_is_msm8625() || cpu_is_msm8627() ||
- cpu_is_msm8625q()) {
+ cpu_is_msm9615() || cpu_is_msm8625() || cpu_is_msm8627()
+ || cpu_is_msm8625q()) {
clock->percpu_evt = alloc_percpu(struct clock_event_device *);
if (!clock->percpu_evt) {
pr_err("msm_timer_init: memory allocation "
diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c
index 0321122..5045424 100644
--- a/arch/arm/mm/cache-l2x0.c
+++ b/arch/arm/mm/cache-l2x0.c
@@ -29,7 +29,7 @@
#define CACHE_LINE_SIZE 32
-static void __iomem *l2x0_base;
+void __iomem *l2x0_base;
static DEFINE_RAW_SPINLOCK(l2x0_lock);
static u32 l2x0_way_mask; /* Bitmask of active ways */
static u32 l2x0_size;
diff --git a/arch/arm/mm/ioremap.c b/arch/arm/mm/ioremap.c
index 8df41e2..7f1f921 100644
--- a/arch/arm/mm/ioremap.c
+++ b/arch/arm/mm/ioremap.c
@@ -234,7 +234,12 @@ void __iomem * __arm_ioremap_pfn_caller(unsigned long pfn,
continue;
if ((area->flags & VM_ARM_MTYPE_MASK) != VM_ARM_MTYPE(mtype))
continue;
- if (__phys_to_pfn(area->phys_addr) > pfn ||
+ /*
+ * Some platform such as msm7x27a need to map the physical address 0 before entering
+ * sleep mode. But the original the logic will provide a wrong virtual address which can't
+ * be accessed(The area may not have enough pages).
+ */
+ if (((area->nr_pages << PAGE_SHIFT) < size) || __phys_to_pfn(area->phys_addr) > pfn ||
__pfn_to_phys(pfn) + size-1 > area->phys_addr + area->size-1)
continue;
/* we can drop the lock here as we know *area is static */
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index bae23b0..7ed9aa0 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -2,6 +2,7 @@
* linux/arch/arm/mm/mmu.c
*
* Copyright (C) 1995-2005 Russell King
+ * Copyright (c) 2012, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -1320,6 +1321,7 @@ void mem_text_write_kernel_word(unsigned long *addr, unsigned long word)
EXPORT_SYMBOL(mem_text_write_kernel_word);
extern char __init_data[];
+volatile __section(.log.data) int reserved_area = 0;
static void __init map_lowmem(void)
{
@@ -1327,6 +1329,11 @@ static void __init map_lowmem(void)
phys_addr_t start;
phys_addr_t end;
struct map_desc map;
+#ifdef CONFIG_UNCACHED_BUF
+ unsigned long uncached_start = (unsigned long)__uncached_track_buf;
+ unsigned long uncached_end = (unsigned long)__end_uncached_track_buf;
+ unsigned long uncached_size = uncached_end - uncached_start;
+#endif
/* Map all the lowmem memory banks. */
for_each_memblock(memory, reg) {
@@ -1367,20 +1374,63 @@ static void __init map_lowmem(void)
map.type = MT_MEMORY;
create_mapping(&map, false);
+#ifdef CONFIG_UNCACHED_BUF
+ map.pfn = __phys_to_pfn(__pa(__init_data));
+ map.virtual = (unsigned long)__init_data;
+ map.length = uncached_start - (unsigned int)__init_data;
+ map.type = MT_MEMORY_RW;
+
+ create_mapping(&map, false);
+ map.pfn = __phys_to_pfn(__virt_to_phys(uncached_start));
+ map.virtual = uncached_start;
+ map.length = uncached_size;
+ map.type = MT_DEVICE;
+
+ create_mapping(&map, false);
+
+ map.pfn = __phys_to_pfn(__virt_to_phys(uncached_end));
+ map.virtual = uncached_end;
+ map.length = end - __virt_to_phys(uncached_end);
+ map.type = MT_MEMORY_RW;
+#else
map.pfn = __phys_to_pfn(__pa(__init_data));
map.virtual = (unsigned long)__init_data;
map.length = __phys_to_virt(end) - (unsigned int)__init_data;
map.type = MT_MEMORY_RW;
+#endif
} else {
map.length = end - start;
map.type = MT_MEMORY_RW;
}
#else
- map.length = end - start;
- map.type = MT_MEMORY;
+#ifdef CONFIG_UNCACHED_BUF
+ if ((__pa(uncached_start) > start) && (__pa(uncached_end) < end)) {
+ map.pfn = __phys_to_pfn(start);
+ map.virtual = __phys_to_virt(start);
+ map.length = uncached_start - map.virtual;
+ map.type = MT_MEMORY;
+ create_mapping(&map, false);
+
+ map.pfn = __phys_to_pfn(__virt_to_phys(uncached_start));
+ map.virtual = uncached_start;
+ map.length = uncached_size;
+ map.type = MT_DEVICE;
+ create_mapping(&map, false);
+
+ map.pfn = __phys_to_pfn(__virt_to_phys(uncached_end));
+ map.virtual = uncached_end;
+ map.length = end - __virt_to_phys(uncached_end);
+ map.type = MT_MEMORY;
+ } else {
#endif
+ map.length = end - start;
+ map.type = MT_MEMORY;
+#ifdef CONFIG_UNCACHED_BUF
+ }
+#endif
+#endif
create_mapping(&map, false);
}
diff --git a/arch/arm/tools/mach-types b/arch/arm/tools/mach-types
index 04c8df8..3b907f8 100644
--- a/arch/arm/tools/mach-types
+++ b/arch/arm/tools/mach-types
@@ -1195,7 +1195,8 @@ msm8625_surf MACH_MSM8625_SURF MSM8625_SURF 4037
msm8625_evb MACH_MSM8625_EVB MSM8625_EVB 4042
msm8625_qrd7 MACH_MSM8625_QRD7 MSM8625_QRD7 4095
msm8625_ffa MACH_MSM8625_FFA MSM8625_FFA 4166
-msm8625_evt MACH_MSM8625_EVT MSM8625_EVT 4193
-qrd_skud_prime MACH_QRD_SKUD_PRIME QRD_SKUD_PRIME 4393
+msm8625_qrd5 MACH_MSM8625_QRD5 MSM8625_QRD5 4193
+msm7x27a_qrd5a MACH_MSM7X27A_QRD5A MSM7X27A_QRD5A 4052
msm8625q_evbd MACH_MSM8625Q_EVBD MSM8625Q_EVBD 4447
-msm8625q_skud MACH_MSM8625Q_SKUD MSM8625Q_SKUD 4456
+msm8625q_skud MACH_MSM8625Q_SKUD MSM8625Q_SKUD 4055
+msm8625q_skue MACH_MSM8625Q_SKUE MSM8625Q_SKUE 4056
diff --git a/block/blk-settings.c b/block/blk-settings.c
index d3234fc..374357a 100644
--- a/block/blk-settings.c
+++ b/block/blk-settings.c
@@ -118,7 +118,8 @@ void blk_set_default_limits(struct queue_limits *lim)
lim->discard_alignment = 0;
lim->discard_misaligned = 0;
lim->discard_zeroes_data = 0;
- lim->logical_block_size = lim->physical_block_size = lim->io_min = 512;
+ lim->logical_block_size = 512;
+ lim->physical_block_size = lim->io_min = 4096;
lim->bounce_pfn = (unsigned long)(BLK_BOUNCE_ANY >> PAGE_SHIFT);
lim->alignment_offset = 0;
lim->io_opt = 0;
diff --git a/block/partition-generic.c b/block/partition-generic.c
old mode 100644
new mode 100755
index 803d151..557617b
--- a/block/partition-generic.c
+++ b/block/partition-generic.c
@@ -18,6 +18,10 @@
#include <linux/genhd.h>
#include <linux/blktrace_api.h>
+#ifdef CONFIG_APANIC_MMC
+#include <linux/apanic_mmc.h>
+#endif /* CONFIG_APANIC_MMC */
+
#include "partitions/check.h"
#ifdef CONFIG_BLK_DEV_MD
@@ -220,6 +224,9 @@ static int part_uevent(struct device *dev, struct kobj_uevent_env *env)
{
struct hd_struct *part = dev_to_part(dev);
+#ifdef CONFIG_APANIC_MMC
+ apanic_mmc_parition_add(part); /*Added by wang.junxian2@byd.com for apanic mmc */
+#endif /* CONFIG_APANIC_MMC */
add_uevent_var(env, "PARTN=%u", part->partno);
if (part->info && part->info->volname[0])
add_uevent_var(env, "PARTNAME=%s", part->info->volname);
diff --git a/drivers/Kconfig b/drivers/Kconfig
old mode 100644
new mode 100755
index a73d713..bfd9258
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -149,5 +149,7 @@ source "drivers/devfreq/Kconfig"
source "drivers/gud/Kconfig"
source "drivers/coresight/Kconfig"
-
+#add for nvbk
+source "drivers/odmm/Kconfig"
+#end
endmenu
diff --git a/drivers/Makefile b/drivers/Makefile
old mode 100644
new mode 100755
index bd18a62..79c8c37
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -142,3 +142,6 @@ obj-$(CONFIG_PM_DEVFREQ) += devfreq/
obj-$(CONFIG_MOBICORE_SUPPORT) += gud/
obj-$(CONFIG_MSM_QDSS) += coresight/
+#add for nvbk
+obj-y += odmm/
+#end
\ No newline at end of file
diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c
index adf937b..7f2090a 100644
--- a/drivers/base/cpu.c
+++ b/drivers/base/cpu.c
@@ -44,11 +44,13 @@ static ssize_t __ref store_online(struct device *dev,
cpu_hotplug_driver_lock();
switch (buf[0]) {
case '0':
+ printk("%s: cpu down\n", current->comm);
ret = cpu_down(cpu->dev.id);
if (!ret)
kobject_uevent(&dev->kobj, KOBJ_OFFLINE);
break;
case '1':
+ printk("%s: cpu up\n", current->comm);
ret = cpu_up(cpu->dev.id);
if (!ret)
kobject_uevent(&dev->kobj, KOBJ_ONLINE);
diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
index b5d38d5..e01aad9 100644
--- a/drivers/base/power/main.c
+++ b/drivers/base/power/main.c
@@ -3,6 +3,7 @@
*
* Copyright (c) 2003 Patrick Mochel
* Copyright (c) 2003 Open Source Development Lab
+ * Copyright (c) 2012, The Linux Foundation. All rights reserved.
*
* This file is released under the GPLv2
*
@@ -35,6 +36,10 @@
typedef int (*pm_callback_t)(struct device *);
+#ifdef CONFIG_MSM_SM_EVENT
+#include <linux/sm_event_log.h>
+#include <linux/sm_event.h>
+#endif
/*
* The entries in the dpm_list list are in a depth first order, simply
* because children are guaranteed to be discovered after parents, and
diff --git a/drivers/bluetooth/hci_h4.c b/drivers/bluetooth/hci_h4.c
index 2fcd8b3..da4cfb0 100644
--- a/drivers/bluetooth/hci_h4.c
+++ b/drivers/bluetooth/hci_h4.c
@@ -2,7 +2,7 @@
*
* Bluetooth HCI UART driver
*
- * Copyright (C) 2000-2001 Qualcomm Incorporated
+ * Copyright (C) 2000-2001 Qualcomm Technologies, Inc.
* Copyright (C) 2002-2003 Maxim Krasnyansky <maxk@qualcomm.com>
* Copyright (C) 2004-2005 Marcel Holtmann <marcel@holtmann.org>
*
diff --git a/drivers/bluetooth/hci_vhci.c b/drivers/bluetooth/hci_vhci.c
index 67c180c..0dd54dd 100644
--- a/drivers/bluetooth/hci_vhci.c
+++ b/drivers/bluetooth/hci_vhci.c
@@ -2,7 +2,7 @@
*
* Bluetooth virtual HCI driver
*
- * Copyright (C) 2000-2001 Qualcomm Incorporated
+ * Copyright (C) 2000-2001 Qualcomm Technologies, Inc.
* Copyright (C) 2002-2003 Maxim Krasnyansky <maxk@qualcomm.com>
* Copyright (C) 2004-2006 Marcel Holtmann <marcel@holtmann.org>
*
diff --git a/drivers/char/diag/diagchar_core.c b/drivers/char/diag/diagchar_core.c
index 8d11526..fbdd238 100644
--- a/drivers/char/diag/diagchar_core.c
+++ b/drivers/char/diag/diagchar_core.c
@@ -947,6 +947,12 @@ static int diagchar_write(struct file *file, const char __user *buf,
return 0;
}
+ if(pkt_type == DIAG_NV_WRITE){
+ err = copy_from_user(driver->user_space_data,buf + 4,payload_size);
+ diag_process_hdlc((void *)(driver->user_space_data),payload_size);
+
+ return 0;
+ }
if (payload_size > itemsize) {
pr_err("diag: Dropping packet, packet payload size crosses"
"4KB limit. Current payload size %d\n",
diff --git a/drivers/char/diag/diagfwd.c b/drivers/char/diag/diagfwd.c
old mode 100644
new mode 100755
index f2b1882..8b2728f
--- a/drivers/char/diag/diagfwd.c
+++ b/drivers/char/diag/diagfwd.c
@@ -1,4 +1,5 @@
-/* Copyright (c) 2008-2012, The Linux Foundation. All rights reserved.
+ /*
+ * Copyright (c) 2012, The Linux Foundation. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -69,6 +70,9 @@ do { \
/* mimic the last entry as actual_last while creation */ \
*(int *)(msg_mask_tbl_ptr) = MSG_SSID_ ## XX ## _LAST; \
msg_mask_tbl_ptr += 4; \
+ /* mimic the last entry as actual_last while creation */ \
+ *(int *)(msg_mask_tbl_ptr) = MSG_SSID_ ## XX ## _LAST; \
+ msg_mask_tbl_ptr += 4; \
/* increment by MAX_SSID_PER_RANGE cells */ \
msg_mask_tbl_ptr += MAX_SSID_PER_RANGE * sizeof(int); \
} while (0)
diff --git a/drivers/char/mem.c b/drivers/char/mem.c
index 67e19b6..1526f14 100644
--- a/drivers/char/mem.c
+++ b/drivers/char/mem.c
@@ -855,8 +855,21 @@ out:
return ret;
}
+extern int dev_read_kmsg(char __user *buf, int len);
+static ssize_t kmsg_read(struct file * file, char __user * buf,
+ size_t count, loff_t *ppos)
+{
+ int ret;
+
+ ret = dev_read_kmsg(buf, count);
+ if (ret > 0)
+ *ppos += ret;
+ return ret;
+}
+
static const struct file_operations kmsg_fops = {
.aio_write = kmsg_writev,
+ .read = kmsg_read,
.llseek = noop_llseek,
};
diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c
old mode 100644
new mode 100755
index 54bfaae..255d8a7
--- a/drivers/cpufreq/cpufreq_ondemand.c
+++ b/drivers/cpufreq/cpufreq_ondemand.c
@@ -25,7 +25,7 @@
#include <linux/input.h>
#include <linux/workqueue.h>
#include <linux/slab.h>
-
+#include <mach/socinfo.h>
/*
* dbs is used in this file as a shortform for demandbased switching
* It helps to keep variable names smaller, simpler
@@ -41,7 +41,6 @@
#define MIN_FREQUENCY_UP_THRESHOLD (11)
#define MAX_FREQUENCY_UP_THRESHOLD (100)
#define MIN_FREQUENCY_DOWN_DIFFERENTIAL (1)
-
/*
* The polling frequency of this governor depends on the capability of
* the processor. Default polling frequency is 1000 times the transition
@@ -130,6 +129,7 @@ static struct dbs_tuners {
unsigned int sampling_down_factor;
int powersave_bias;
unsigned int io_is_busy;
+ u64 hispeed_freq;
} dbs_tuners_ins = {
.up_threshold = DEF_FREQUENCY_UP_THRESHOLD,
.sampling_down_factor = DEF_SAMPLING_DOWN_FACTOR,
@@ -297,6 +297,12 @@ show_one(down_differential, down_differential);
show_one(sampling_down_factor, sampling_down_factor);
show_one(ignore_nice_load, ignore_nice);
+static ssize_t show_hispeed_freq
+(struct kobject *kobj, struct attribute *attr, char *buf)
+{
+ return sprintf(buf, "%llu\n", dbs_tuners_ins.hispeed_freq);
+}
+
static ssize_t show_powersave_bias
(struct kobject *kobj, struct attribute *attr, char *buf)
{
@@ -384,6 +390,19 @@ static ssize_t store_io_is_busy(struct kobject *a, struct attribute *b,
return count;
}
+static ssize_t store_hispeed_freq(struct kobject *a, struct attribute *b,
+ const char *buf, size_t count)
+{
+ u64 input;
+ int ret;
+
+ ret = sscanf(buf, "%llu", &input);
+ if (ret != 1)
+ return -EINVAL;
+ dbs_tuners_ins.hispeed_freq = input;
+ return count;
+}
+
static ssize_t store_up_threshold(struct kobject *a, struct attribute *b,
const char *buf, size_t count)
{
@@ -577,6 +596,7 @@ skip_this_cpu_bypass:
define_one_global_rw(sampling_rate);
define_one_global_rw(io_is_busy);
define_one_global_rw(up_threshold);
+define_one_global_rw(hispeed_freq);
define_one_global_rw(down_differential);
define_one_global_rw(sampling_down_factor);
define_one_global_rw(ignore_nice_load);
@@ -591,6 +611,7 @@ static struct attribute *dbs_attributes[] = {
&ignore_nice_load.attr,
&powersave_bias.attr,
&io_is_busy.attr,
+ &hispeed_freq.attr,
NULL
};
@@ -858,14 +879,14 @@ static void dbs_refresh_callback(struct work_struct *work)
goto bail_incorrect_governor;
}
- if (policy->cur < policy->max) {
+ if (policy->cur < dbs_tuners_ins.hispeed_freq) {
/*
* Arch specific cpufreq driver may fail.
* Don't update governor frequency upon failure.
*/
- if (__cpufreq_driver_target(policy, policy->max,
+ if (__cpufreq_driver_target(policy, dbs_tuners_ins.hispeed_freq,
CPUFREQ_RELATION_L) >= 0)
- policy->cur = policy->max;
+ policy->cur = dbs_tuners_ins.hispeed_freq;
this_dbs_info->prev_cpu_idle = get_cpu_idle_time(cpu,
&this_dbs_info->prev_cpu_wall);
@@ -932,7 +953,21 @@ static void dbs_input_disconnect(struct input_handle *handle)
}
static const struct input_device_id dbs_ids[] = {
- { .driver_info = 1 },
+ {
+ .flags = INPUT_DEVICE_ID_MATCH_EVBIT |
+ INPUT_DEVICE_ID_MATCH_ABSBIT,
+ .evbit = { BIT_MASK(EV_ABS) },
+ .absbit = { [BIT_WORD(ABS_MT_POSITION_X)] =
+ BIT_MASK(ABS_MT_POSITION_X) |
+ BIT_MASK(ABS_MT_POSITION_Y) },
+ }, /* multi-touch touchscreen */
+ {
+ .flags = INPUT_DEVICE_ID_MATCH_KEYBIT |
+ INPUT_DEVICE_ID_MATCH_ABSBIT,
+ .keybit = { [BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH) },
+ .absbit = { [BIT_WORD(ABS_X)] =
+ BIT_MASK(ABS_X) | BIT_MASK(ABS_Y) },
+ }, /* touchpad */
{ },
};
@@ -1001,6 +1036,12 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy,
max(min_sampling_rate,
latency * LATENCY_MULTIPLIER);
dbs_tuners_ins.io_is_busy = should_io_be_busy();
+ if ((cpu_is_msm8625()) || (cpu_is_msm8625q())) {
+ /* Set hispeed to 1GHz based on performance tuning result here */
+ dbs_tuners_ins.hispeed_freq = 1008000;
+ } else {
+ dbs_tuners_ins.hispeed_freq = policy->max;
+ }
}
if (!cpu)
rc = input_register_handler(&dbs_input_handler);
diff --git a/drivers/cpufreq/cpufreq_stats.c b/drivers/cpufreq/cpufreq_stats.c
index 1a9a6a5..01c8d2b 100644
--- a/drivers/cpufreq/cpufreq_stats.c
+++ b/drivers/cpufreq/cpufreq_stats.c
@@ -22,6 +22,9 @@
#include <linux/notifier.h>
#include <asm/cputime.h>
+#define CREATE_TRACE_POINTS
+#include <trace/events/cpufreq.h>
+
static spinlock_t cpufreq_stats_lock;
#define CPUFREQ_STATDEVICE_ATTR(_name, _mode, _show) \
@@ -306,6 +309,7 @@ static int cpufreq_stat_notifier_trans(struct notifier_block *nb,
if (old_index == new_index)
return 0;
+ trace_cpufreq_chg(freq->cpu, freq->new);
spin_lock(&cpufreq_stats_lock);
stat->last_index = new_index;
#ifdef CONFIG_CPU_FREQ_STAT_DETAILS
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
old mode 100644
new mode 100755
index b050db2..5927501
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -867,7 +867,23 @@ config SENSORS_EPM_ADC
help
Provides interface for measuring the current on specific power rails
through the channels on ADC1158 ADC
+
+config SENSORS_BMA2X2
+ tristate "BMA255/BMA250E/BMA222E/BMA280 acceleration sensor support"
+ depends on I2C
+ default n
+ help
+ If you say yes here you get support for Bosch Sensortec's
+ acceleration sensors BMA255/BMA250E/BMA222E/BMA280.
+config SENSORS_LTR559
+ tristate "LTR559 Digital P/L sensor support"
+ depends on I2C
+ default n
+ help
+ If you say yes here you get support for LITEON
+ P/L sensors LTR559.
+
config SENSORS_PC87360
tristate "National Semiconductor PC87360 family"
depends on !PPC
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
old mode 100644
new mode 100755
index 228c4e9..dd20840
--- a/drivers/hwmon/Makefile
+++ b/drivers/hwmon/Makefile
@@ -130,6 +130,8 @@ obj-$(CONFIG_SENSORS_WPCE775X) += wpce775x.o
obj-$(CONFIG_SENSORS_MSM_ADC) += msm_adc.o m_adcproc.o
obj-$(CONFIG_SENSORS_PM8XXX_ADC) += pm8xxx-adc.o pm8xxx-adc-scale.o
obj-$(CONFIG_SENSORS_EPM_ADC) += epm_adc.o
+obj-$(CONFIG_SENSORS_BMA2X2) += bma2x2.o
+obj-$(CONFIG_SENSORS_LTR559) += ltr559.o
obj-$(CONFIG_PMBUS) += pmbus/
diff --git a/drivers/hwmon/bma2x2.c b/drivers/hwmon/bma2x2.c
new file mode 100755
index 0000000..c7ec9f5
--- /dev/null
+++ b/drivers/hwmon/bma2x2.c
@@ -0,0 +1,3347 @@
+/* Date: 2012/6/13 10:00:00
+ * Revision: 1.4
+ */
+
+/*
+ * This software program is licensed subject to the GNU General Public License
+ * (GPL).Version 2,June 1991, available at http://www.fsf.org/copyleft/gpl.html
+
+ * (C) Copyright 2011 Bosch Sensortec GmbH
+ * All Rights Reserved
+ */
+
+
+/* file BMA2X2.c
+ brief This file contains all function implementations for the BMA2X2 in linux
+
+*/
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/i2c.h>
+#include <linux/input.h>
+#include <linux/workqueue.h>
+#include <linux/mutex.h>
+#include <linux/slab.h>
+#include <linux/mutex.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/wakelock.h>
+
+#ifdef CONFIG_HAS_EARLYSUSPEND
+#include <linux/earlysuspend.h>
+#endif
+#define BMA2X2_ENABLE_INT1
+#define BMA2X2_WAKEUP_BY_2TAP
+#ifdef BMA2X2_WAKEUP_BY_2TAP
+#include <linux/glanceview.h>
+#endif
+//#include <../arch/arm/mach-omap2/mux.h>
+
+
+//#define SENSOR_IDENTIFICATION_ENABLE 1
+
+
+#define SENSOR_NAME "bma2x2"
+#define ABSMIN -512
+#define ABSMAX 512
+#define SLOPE_THRESHOLD_VALUE 32
+#define SLOPE_DURATION_VALUE 1
+#define INTERRUPT_LATCH_MODE 13
+#define INTERRUPT_ENABLE 1
+#define INTERRUPT_DISABLE 0
+#define MAP_SLOPE_INTERRUPT 2
+#define SLOPE_X_INDEX 5
+#define SLOPE_Y_INDEX 6
+#define SLOPE_Z_INDEX 7
+#define BMA2X2_MAX_DELAY 200
+#define BMA2X2_RANGE_SET 3 /* +/- 2G */
+#define BMA2X2_BW_SET 15 /* 1000HZ */
+
+#define LOW_G_INTERRUPT REL_Z
+#define HIGH_G_INTERRUPT REL_HWHEEL
+#define SLOP_INTERRUPT REL_DIAL
+#define DOUBLE_TAP_INTERRUPT REL_WHEEL
+#define SINGLE_TAP_INTERRUPT REL_MISC
+#define ORIENT_INTERRUPT ABS_PRESSURE
+#define FLAT_INTERRUPT ABS_DISTANCE
+
+
+#define HIGH_G_INTERRUPT_X_HAPPENED 1
+#define HIGH_G_INTERRUPT_Y_HAPPENED 2
+#define HIGH_G_INTERRUPT_Z_HAPPENED 3
+#define HIGH_G_INTERRUPT_X_NEGATIVE_HAPPENED 4
+#define HIGH_G_INTERRUPT_Y_NEGATIVE_HAPPENED 5
+#define HIGH_G_INTERRUPT_Z_NEGATIVE_HAPPENED 6
+#define SLOPE_INTERRUPT_X_HAPPENED 7
+#define SLOPE_INTERRUPT_Y_HAPPENED 8
+#define SLOPE_INTERRUPT_Z_HAPPENED 9
+#define SLOPE_INTERRUPT_X_NEGATIVE_HAPPENED 10
+#define SLOPE_INTERRUPT_Y_NEGATIVE_HAPPENED 11
+#define SLOPE_INTERRUPT_Z_NEGATIVE_HAPPENED 12
+#define DOUBLE_TAP_INTERRUPT_HAPPENED 13
+#define SINGLE_TAP_INTERRUPT_HAPPENED 14
+#define UPWARD_PORTRAIT_UP_INTERRUPT_HAPPENED 15
+#define UPWARD_PORTRAIT_DOWN_INTERRUPT_HAPPENED 16
+#define UPWARD_LANDSCAPE_LEFT_INTERRUPT_HAPPENED 17
+#define UPWARD_LANDSCAPE_RIGHT_INTERRUPT_HAPPENED 18
+#define DOWNWARD_PORTRAIT_UP_INTERRUPT_HAPPENED 19
+#define DOWNWARD_PORTRAIT_DOWN_INTERRUPT_HAPPENED 20
+#define DOWNWARD_LANDSCAPE_LEFT_INTERRUPT_HAPPENED 21
+#define DOWNWARD_LANDSCAPE_RIGHT_INTERRUPT_HAPPENED 22
+#define FLAT_INTERRUPT_TURE_HAPPENED 23
+#define FLAT_INTERRUPT_FALSE_HAPPENED 24
+#define LOW_G_INTERRUPT_HAPPENED 25
+
+#define PAD_LOWG 0
+#define PAD_HIGHG 1
+#define PAD_SLOP 2
+#define PAD_DOUBLE_TAP 3
+#define PAD_SINGLE_TAP 4
+#define PAD_ORIENT 5
+#define PAD_FLAT 6
+
+
+#define BMA2X2_EEP_OFFSET 0x16
+#define BMA2X2_IMAGE_BASE 0x38
+#define BMA2X2_IMAGE_LEN 22
+
+
+#define BMA2X2_CHIP_ID_REG 0x00
+#define BMA2X2_VERSION_REG 0x01
+#define BMA2X2_X_AXIS_LSB_REG 0x02
+#define BMA2X2_X_AXIS_MSB_REG 0x03
+#define BMA2X2_Y_AXIS_LSB_REG 0x04
+#define BMA2X2_Y_AXIS_MSB_REG 0x05
+#define BMA2X2_Z_AXIS_LSB_REG 0x06
+#define BMA2X2_Z_AXIS_MSB_REG 0x07
+#define BMA2X2_TEMP_RD_REG 0x08
+#define BMA2X2_STATUS1_REG 0x09
+#define BMA2X2_STATUS2_REG 0x0A
+#define BMA2X2_STATUS_TAP_SLOPE_REG 0x0B
+#define BMA2X2_STATUS_ORIENT_HIGH_REG 0x0C
+#define BMA2X2_STATUS_FIFO_REG 0x0E
+#define BMA2X2_RANGE_SEL_REG 0x0F
+#define BMA2X2_BW_SEL_REG 0x10
+#define BMA2X2_MODE_CTRL_REG 0x11
+#define BMA2X2_LOW_NOISE_CTRL_REG 0x12
+#define BMA2X2_DATA_CTRL_REG 0x13
+#define BMA2X2_RESET_REG 0x14
+#define BMA2X2_INT_ENABLE1_REG 0x16
+#define BMA2X2_INT_ENABLE2_REG 0x17
+#define BMA2X2_INT_SLO_NO_MOT_REG 0x18
+#define BMA2X2_INT1_PAD_SEL_REG 0x19
+#define BMA2X2_INT_DATA_SEL_REG 0x1A
+#define BMA2X2_INT2_PAD_SEL_REG 0x1B
+#define BMA2X2_INT_SRC_REG 0x1E
+#define BMA2X2_INT_SET_REG 0x20
+#define BMA2X2_INT_CTRL_REG 0x21
+#define BMA2X2_LOW_DURN_REG 0x22
+#define BMA2X2_LOW_THRES_REG 0x23
+#define BMA2X2_LOW_HIGH_HYST_REG 0x24
+#define BMA2X2_HIGH_DURN_REG 0x25
+#define BMA2X2_HIGH_THRES_REG 0x26
+#define BMA2X2_SLOPE_DURN_REG 0x27
+#define BMA2X2_SLOPE_THRES_REG 0x28
+#define BMA2X2_SLO_NO_MOT_THRES_REG 0x29
+#define BMA2X2_TAP_PARAM_REG 0x2A
+#define BMA2X2_TAP_THRES_REG 0x2B
+#define BMA2X2_ORIENT_PARAM_REG 0x2C
+#define BMA2X2_THETA_BLOCK_REG 0x2D
+#define BMA2X2_THETA_FLAT_REG 0x2E
+#define BMA2X2_FLAT_HOLD_TIME_REG 0x2F
+#define BMA2X2_FIFO_WML_TRIG 0x30
+#define BMA2X2_SELF_TEST_REG 0x32
+#define BMA2X2_EEPROM_CTRL_REG 0x33
+#define BMA2X2_SERIAL_CTRL_REG 0x34
+#define BMA2X2_EXTMODE_CTRL_REG 0x35
+#define BMA2X2_OFFSET_CTRL_REG 0x36
+#define BMA2X2_OFFSET_PARAMS_REG 0x37
+#define BMA2X2_OFFSET_X_AXIS_REG 0x38
+#define BMA2X2_OFFSET_Y_AXIS_REG 0x39
+#define BMA2X2_OFFSET_Z_AXIS_REG 0x3A
+#define BMA2X2_GP0_REG 0x3B
+#define BMA2X2_GP1_REG 0x3C
+#define BMA2X2_FIFO_MODE_REG 0x3E
+#define BMA2X2_FIFO_DATA_OUTPUT_REG 0x3F
+
+
+
+
+#define BMA2X2_CHIP_ID__POS 0
+#define BMA2X2_CHIP_ID__MSK 0xFF
+#define BMA2X2_CHIP_ID__LEN 8
+#define BMA2X2_CHIP_ID__REG BMA2X2_CHIP_ID_REG
+
+#define BMA2X2_VERSION__POS 0
+#define BMA2X2_VERSION__LEN 8
+#define BMA2X2_VERSION__MSK 0xFF
+#define BMA2X2_VERSION__REG BMA2X2_VERSION_REG
+
+
+
+#define BMA2X2_NEW_DATA_X__POS 0
+#define BMA2X2_NEW_DATA_X__LEN 1
+#define BMA2X2_NEW_DATA_X__MSK 0x01
+#define BMA2X2_NEW_DATA_X__REG BMA2X2_X_AXIS_LSB_REG
+
+#define BMA2X2_ACC_X14_LSB__POS 2
+#define BMA2X2_ACC_X14_LSB__LEN 6
+#define BMA2X2_ACC_X14_LSB__MSK 0xFC
+#define BMA2X2_ACC_X14_LSB__REG BMA2X2_X_AXIS_LSB_REG
+
+#define BMA2X2_ACC_X12_LSB__POS 4
+#define BMA2X2_ACC_X12_LSB__LEN 4
+#define BMA2X2_ACC_X12_LSB__MSK 0xF0
+#define BMA2X2_ACC_X12_LSB__REG BMA2X2_X_AXIS_LSB_REG
+
+#define BMA2X2_ACC_X10_LSB__POS 6
+#define BMA2X2_ACC_X10_LSB__LEN 2
+#define BMA2X2_ACC_X10_LSB__MSK 0xC0
+#define BMA2X2_ACC_X10_LSB__REG BMA2X2_X_AXIS_LSB_REG
+
+#define BMA2X2_ACC_X8_LSB__POS 0
+#define BMA2X2_ACC_X8_LSB__LEN 0
+#define BMA2X2_ACC_X8_LSB__MSK 0x00
+#define BMA2X2_ACC_X8_LSB__REG BMA2X2_X_AXIS_LSB_REG
+
+#define BMA2X2_ACC_X_MSB__POS 0
+#define BMA2X2_ACC_X_MSB__LEN 8
+#define BMA2X2_ACC_X_MSB__MSK 0xFF
+#define BMA2X2_ACC_X_MSB__REG BMA2X2_X_AXIS_MSB_REG
+
+#define BMA2X2_NEW_DATA_Y__POS 0
+#define BMA2X2_NEW_DATA_Y__LEN 1
+#define BMA2X2_NEW_DATA_Y__MSK 0x01
+#define BMA2X2_NEW_DATA_Y__REG BMA2X2_Y_AXIS_LSB_REG
+
+#define BMA2X2_ACC_Y14_LSB__POS 2
+#define BMA2X2_ACC_Y14_LSB__LEN 6
+#define BMA2X2_ACC_Y14_LSB__MSK 0xFC
+#define BMA2X2_ACC_Y14_LSB__REG BMA2X2_Y_AXIS_LSB_REG
+
+#define BMA2X2_ACC_Y12_LSB__POS 4
+#define BMA2X2_ACC_Y12_LSB__LEN 4
+#define BMA2X2_ACC_Y12_LSB__MSK 0xF0
+#define BMA2X2_ACC_Y12_LSB__REG BMA2X2_Y_AXIS_LSB_REG
+
+#define BMA2X2_ACC_Y10_LSB__POS 6
+#define BMA2X2_ACC_Y10_LSB__LEN 2
+#define BMA2X2_ACC_Y10_LSB__MSK 0xC0
+#define BMA2X2_ACC_Y10_LSB__REG BMA2X2_Y_AXIS_LSB_REG
+
+#define BMA2X2_ACC_Y8_LSB__POS 0
+#define BMA2X2_ACC_Y8_LSB__LEN 0
+#define BMA2X2_ACC_Y8_LSB__MSK 0x00
+#define BMA2X2_ACC_Y8_LSB__REG BMA2X2_Y_AXIS_LSB_REG
+
+#define BMA2X2_ACC_Y_MSB__POS 0
+#define BMA2X2_ACC_Y_MSB__LEN 8
+#define BMA2X2_ACC_Y_MSB__MSK 0xFF
+#define BMA2X2_ACC_Y_MSB__REG BMA2X2_Y_AXIS_MSB_REG
+
+#define BMA2X2_NEW_DATA_Z__POS 0
+#define BMA2X2_NEW_DATA_Z__LEN 1
+#define BMA2X2_NEW_DATA_Z__MSK 0x01
+#define BMA2X2_NEW_DATA_Z__REG BMA2X2_Z_AXIS_LSB_REG
+
+#define BMA2X2_ACC_Z14_LSB__POS 2
+#define BMA2X2_ACC_Z14_LSB__LEN 6
+#define BMA2X2_ACC_Z14_LSB__MSK 0xFC
+#define BMA2X2_ACC_Z14_LSB__REG BMA2X2_Z_AXIS_LSB_REG
+
+#define BMA2X2_ACC_Z12_LSB__POS 4
+#define BMA2X2_ACC_Z12_LSB__LEN 4
+#define BMA2X2_ACC_Z12_LSB__MSK 0xF0
+#define BMA2X2_ACC_Z12_LSB__REG BMA2X2_Z_AXIS_LSB_REG
+
+#define BMA2X2_ACC_Z10_LSB__POS 6
+#define BMA2X2_ACC_Z10_LSB__LEN 2
+#define BMA2X2_ACC_Z10_LSB__MSK 0xC0
+#define BMA2X2_ACC_Z10_LSB__REG BMA2X2_Z_AXIS_LSB_REG
+
+#define BMA2X2_ACC_Z8_LSB__POS 0
+#define BMA2X2_ACC_Z8_LSB__LEN 0
+#define BMA2X2_ACC_Z8_LSB__MSK 0x00
+#define BMA2X2_ACC_Z8_LSB__REG BMA2X2_Z_AXIS_LSB_REG
+
+#define BMA2X2_ACC_Z_MSB__POS 0
+#define BMA2X2_ACC_Z_MSB__LEN 8
+#define BMA2X2_ACC_Z_MSB__MSK 0xFF
+#define BMA2X2_ACC_Z_MSB__REG BMA2X2_Z_AXIS_MSB_REG
+
+#define BMA2X2_TEMPERATURE__POS 0
+#define BMA2X2_TEMPERATURE__LEN 8
+#define BMA2X2_TEMPERATURE__MSK 0xFF
+#define BMA2X2_TEMPERATURE__REG BMA2X2_TEMP_RD_REG
+
+#define BMA2X2_LOWG_INT_S__POS 0
+#define BMA2X2_LOWG_INT_S__LEN 1
+#define BMA2X2_LOWG_INT_S__MSK 0x01
+#define BMA2X2_LOWG_INT_S__REG BMA2X2_STATUS1_REG
+
+#define BMA2X2_HIGHG_INT_S__POS 1
+#define BMA2X2_HIGHG_INT_S__LEN 1
+#define BMA2X2_HIGHG_INT_S__MSK 0x02
+#define BMA2X2_HIGHG_INT_S__REG BMA2X2_STATUS1_REG
+
+#define BMA2X2_SLOPE_INT_S__POS 2
+#define BMA2X2_SLOPE_INT_S__LEN 1
+#define BMA2X2_SLOPE_INT_S__MSK 0x04
+#define BMA2X2_SLOPE_INT_S__REG BMA2X2_STATUS1_REG
+
+
+#define BMA2X2_SLO_NO_MOT_INT_S__POS 3
+#define BMA2X2_SLO_NO_MOT_INT_S__LEN 1
+#define BMA2X2_SLO_NO_MOT_INT_S__MSK 0x08
+#define BMA2X2_SLO_NO_MOT_INT_S__REG BMA2X2_STATUS1_REG
+
+#define BMA2X2_DOUBLE_TAP_INT_S__POS 4
+#define BMA2X2_DOUBLE_TAP_INT_S__LEN 1
+#define BMA2X2_DOUBLE_TAP_INT_S__MSK 0x10
+#define BMA2X2_DOUBLE_TAP_INT_S__REG BMA2X2_STATUS1_REG
+
+#define BMA2X2_SINGLE_TAP_INT_S__POS 5
+#define BMA2X2_SINGLE_TAP_INT_S__LEN 1
+#define BMA2X2_SINGLE_TAP_INT_S__MSK 0x20
+#define BMA2X2_SINGLE_TAP_INT_S__REG BMA2X2_STATUS1_REG
+
+#define BMA2X2_ORIENT_INT_S__POS 6
+#define BMA2X2_ORIENT_INT_S__LEN 1
+#define BMA2X2_ORIENT_INT_S__MSK 0x40
+#define BMA2X2_ORIENT_INT_S__REG BMA2X2_STATUS1_REG
+
+#define BMA2X2_FLAT_INT_S__POS 7
+#define BMA2X2_FLAT_INT_S__LEN 1
+#define BMA2X2_FLAT_INT_S__MSK 0x80
+#define BMA2X2_FLAT_INT_S__REG BMA2X2_STATUS1_REG
+
+#define BMA2X2_FIFO_FULL_INT_S__POS 5
+#define BMA2X2_FIFO_FULL_INT_S__LEN 1
+#define BMA2X2_FIFO_FULL_INT_S__MSK 0x20
+#define BMA2X2_FIFO_FULL_INT_S__REG BMA2X2_STATUS2_REG
+
+#define BMA2X2_FIFO_WM_INT_S__POS 6
+#define BMA2X2_FIFO_WM_INT_S__LEN 1
+#define BMA2X2_FIFO_WM_INT_S__MSK 0x40
+#define BMA2X2_FIFO_WM_INT_S__REG BMA2X2_STATUS2_REG
+
+#define BMA2X2_DATA_INT_S__POS 7
+#define BMA2X2_DATA_INT_S__LEN 1
+#define BMA2X2_DATA_INT_S__MSK 0x80
+#define BMA2X2_DATA_INT_S__REG BMA2X2_STATUS2_REG
+
+#define BMA2X2_SLOPE_FIRST_X__POS 0
+#define BMA2X2_SLOPE_FIRST_X__LEN 1
+#define BMA2X2_SLOPE_FIRST_X__MSK 0x01
+#define BMA2X2_SLOPE_FIRST_X__REG BMA2X2_STATUS_TAP_SLOPE_REG
+
+#define BMA2X2_SLOPE_FIRST_Y__POS 1
+#define BMA2X2_SLOPE_FIRST_Y__LEN 1
+#define BMA2X2_SLOPE_FIRST_Y__MSK 0x02
+#define BMA2X2_SLOPE_FIRST_Y__REG BMA2X2_STATUS_TAP_SLOPE_REG
+
+#define BMA2X2_SLOPE_FIRST_Z__POS 2
+#define BMA2X2_SLOPE_FIRST_Z__LEN 1
+#define BMA2X2_SLOPE_FIRST_Z__MSK 0x04
+#define BMA2X2_SLOPE_FIRST_Z__REG BMA2X2_STATUS_TAP_SLOPE_REG
+
+#define BMA2X2_SLOPE_SIGN_S__POS 3
+#define BMA2X2_SLOPE_SIGN_S__LEN 1
+#define BMA2X2_SLOPE_SIGN_S__MSK 0x08
+#define BMA2X2_SLOPE_SIGN_S__REG BMA2X2_STATUS_TAP_SLOPE_REG
+
+#define BMA2X2_TAP_FIRST_X__POS 4
+#define BMA2X2_TAP_FIRST_X__LEN 1
+#define BMA2X2_TAP_FIRST_X__MSK 0x10
+#define BMA2X2_TAP_FIRST_X__REG BMA2X2_STATUS_TAP_SLOPE_REG
+
+#define BMA2X2_TAP_FIRST_Y__POS 5
+#define BMA2X2_TAP_FIRST_Y__LEN 1
+#define BMA2X2_TAP_FIRST_Y__MSK 0x20
+#define BMA2X2_TAP_FIRST_Y__REG BMA2X2_STATUS_TAP_SLOPE_REG
+
+#define BMA2X2_TAP_FIRST_Z__POS 6
+#define BMA2X2_TAP_FIRST_Z__LEN 1
+#define BMA2X2_TAP_FIRST_Z__MSK 0x40
+#define BMA2X2_TAP_FIRST_Z__REG BMA2X2_STATUS_TAP_SLOPE_REG
+
+#define BMA2X2_TAP_SIGN_S__POS 7
+#define BMA2X2_TAP_SIGN_S__LEN 1
+#define BMA2X2_TAP_SIGN_S__MSK 0x80
+#define BMA2X2_TAP_SIGN_S__REG BMA2X2_STATUS_TAP_SLOPE_REG
+
+#define BMA2X2_HIGHG_FIRST_X__POS 0
+#define BMA2X2_HIGHG_FIRST_X__LEN 1
+#define BMA2X2_HIGHG_FIRST_X__MSK 0x01
+#define BMA2X2_HIGHG_FIRST_X__REG BMA2X2_STATUS_ORIENT_HIGH_REG
+
+#define BMA2X2_HIGHG_FIRST_Y__POS 1
+#define BMA2X2_HIGHG_FIRST_Y__LEN 1
+#define BMA2X2_HIGHG_FIRST_Y__MSK 0x02
+#define BMA2X2_HIGHG_FIRST_Y__REG BMA2X2_STATUS_ORIENT_HIGH_REG
+
+#define BMA2X2_HIGHG_FIRST_Z__POS 2
+#define BMA2X2_HIGHG_FIRST_Z__LEN 1
+#define BMA2X2_HIGHG_FIRST_Z__MSK 0x04
+#define BMA2X2_HIGHG_FIRST_Z__REG BMA2X2_STATUS_ORIENT_HIGH_REG
+
+#define BMA2X2_HIGHG_SIGN_S__POS 3
+#define BMA2X2_HIGHG_SIGN_S__LEN 1
+#define BMA2X2_HIGHG_SIGN_S__MSK 0x08
+#define BMA2X2_HIGHG_SIGN_S__REG BMA2X2_STATUS_ORIENT_HIGH_REG
+
+#define BMA2X2_ORIENT_S__POS 4
+#define BMA2X2_ORIENT_S__LEN 3
+#define BMA2X2_ORIENT_S__MSK 0x70
+#define BMA2X2_ORIENT_S__REG BMA2X2_STATUS_ORIENT_HIGH_REG
+
+#define BMA2X2_FLAT_S__POS 7
+#define BMA2X2_FLAT_S__LEN 1
+#define BMA2X2_FLAT_S__MSK 0x80
+#define BMA2X2_FLAT_S__REG BMA2X2_STATUS_ORIENT_HIGH_REG
+
+#define BMA2X2_FIFO_FRAME_COUNTER_S__POS 0
+#define BMA2X2_FIFO_FRAME_COUNTER_S__LEN 7
+#define BMA2X2_FIFO_FRAME_COUNTER_S__MSK 0x7F
+#define BMA2X2_FIFO_FRAME_COUNTER_S__REG BMA2X2_STATUS_FIFO_REG
+
+#define BMA2X2_FIFO_OVERRUN_S__POS 7
+#define BMA2X2_FIFO_OVERRUN_S__LEN 1
+#define BMA2X2_FIFO_OVERRUN_S__MSK 0x80
+#define BMA2X2_FIFO_OVERRUN_S__REG BMA2X2_STATUS_FIFO_REG
+
+#define BMA2X2_RANGE_SEL__POS 0
+#define BMA2X2_RANGE_SEL__LEN 4
+#define BMA2X2_RANGE_SEL__MSK 0x0F
+#define BMA2X2_RANGE_SEL__REG BMA2X2_RANGE_SEL_REG
+
+#define BMA2X2_BANDWIDTH__POS 0
+#define BMA2X2_BANDWIDTH__LEN 5
+#define BMA2X2_BANDWIDTH__MSK 0x1F
+#define BMA2X2_BANDWIDTH__REG BMA2X2_BW_SEL_REG
+
+#define BMA2X2_SLEEP_DUR__POS 1
+#define BMA2X2_SLEEP_DUR__LEN 4
+#define BMA2X2_SLEEP_DUR__MSK 0x1E
+#define BMA2X2_SLEEP_DUR__REG BMA2X2_MODE_CTRL_REG
+
+#define BMA2X2_MODE_CTRL__POS 5
+#define BMA2X2_MODE_CTRL__LEN 3
+#define BMA2X2_MODE_CTRL__MSK 0xE0
+#define BMA2X2_MODE_CTRL__REG BMA2X2_MODE_CTRL_REG
+
+#define BMA2X2_DEEP_SUSPEND__POS 5
+#define BMA2X2_DEEP_SUSPEND__LEN 1
+#define BMA2X2_DEEP_SUSPEND__MSK 0x20
+#define BMA2X2_DEEP_SUSPEND__REG BMA2X2_MODE_CTRL_REG
+
+#define BMA2X2_EN_LOW_POWER__POS 6
+#define BMA2X2_EN_LOW_POWER__LEN 1
+#define BMA2X2_EN_LOW_POWER__MSK 0x40
+#define BMA2X2_EN_LOW_POWER__REG BMA2X2_MODE_CTRL_REG
+
+#define BMA2X2_EN_SUSPEND__POS 7
+#define BMA2X2_EN_SUSPEND__LEN 1
+#define BMA2X2_EN_SUSPEND__MSK 0x80
+#define BMA2X2_EN_SUSPEND__REG BMA2X2_MODE_CTRL_REG
+
+#define BMA2X2_SLEEP_TIMER__POS 5
+#define BMA2X2_SLEEP_TIMER__LEN 1
+#define BMA2X2_SLEEP_TIMER__MSK 0x20
+#define BMA2X2_SLEEP_TIMER__REG BMA2X2_LOW_NOISE_CTRL_REG
+
+#define BMA2X2_LOW_POWER_MODE__POS 6
+#define BMA2X2_LOW_POWER_MODE__LEN 1
+#define BMA2X2_LOW_POWER_MODE__MSK 0x40
+#define BMA2X2_LOW_POWER_MODE__REG BMA2X2_LOW_NOISE_CTRL_REG
+
+#define BMA2X2_EN_LOW_NOISE__POS 7
+#define BMA2X2_EN_LOW_NOISE__LEN 1
+#define BMA2X2_EN_LOW_NOISE__MSK 0x80
+#define BMA2X2_EN_LOW_NOISE__REG BMA2X2_LOW_NOISE_CTRL_REG
+
+#define BMA2X2_DIS_SHADOW_PROC__POS 6
+#define BMA2X2_DIS_SHADOW_PROC__LEN 1
+#define BMA2X2_DIS_SHADOW_PROC__MSK 0x40
+#define BMA2X2_DIS_SHADOW_PROC__REG BMA2X2_DATA_CTRL_REG
+
+#define BMA2X2_EN_DATA_HIGH_BW__POS 7
+#define BMA2X2_EN_DATA_HIGH_BW__LEN 1
+#define BMA2X2_EN_DATA_HIGH_BW__MSK 0x80
+#define BMA2X2_EN_DATA_HIGH_BW__REG BMA2X2_DATA_CTRL_REG
+
+#define BMA2X2_EN_SOFT_RESET__POS 0
+#define BMA2X2_EN_SOFT_RESET__LEN 8
+#define BMA2X2_EN_SOFT_RESET__MSK 0xFF
+#define BMA2X2_EN_SOFT_RESET__REG BMA2X2_RESET_REG
+
+#define BMA2X2_EN_SOFT_RESET_VALUE 0xB6
+
+#define BMA2X2_EN_SLOPE_X_INT__POS 0
+#define BMA2X2_EN_SLOPE_X_INT__LEN 1
+#define BMA2X2_EN_SLOPE_X_INT__MSK 0x01
+#define BMA2X2_EN_SLOPE_X_INT__REG BMA2X2_INT_ENABLE1_REG
+
+#define BMA2X2_EN_SLOPE_Y_INT__POS 1
+#define BMA2X2_EN_SLOPE_Y_INT__LEN 1
+#define BMA2X2_EN_SLOPE_Y_INT__MSK 0x02
+#define BMA2X2_EN_SLOPE_Y_INT__REG BMA2X2_INT_ENABLE1_REG
+
+#define BMA2X2_EN_SLOPE_Z_INT__POS 2
+#define BMA2X2_EN_SLOPE_Z_INT__LEN 1
+#define BMA2X2_EN_SLOPE_Z_INT__MSK 0x04
+#define BMA2X2_EN_SLOPE_Z_INT__REG BMA2X2_INT_ENABLE1_REG
+
+#define BMA2X2_EN_DOUBLE_TAP_INT__POS 4
+#define BMA2X2_EN_DOUBLE_TAP_INT__LEN 1
+#define BMA2X2_EN_DOUBLE_TAP_INT__MSK 0x10
+#define BMA2X2_EN_DOUBLE_TAP_INT__REG BMA2X2_INT_ENABLE1_REG
+
+#define BMA2X2_EN_SINGLE_TAP_INT__POS 5
+#define BMA2X2_EN_SINGLE_TAP_INT__LEN 1
+#define BMA2X2_EN_SINGLE_TAP_INT__MSK 0x20
+#define BMA2X2_EN_SINGLE_TAP_INT__REG BMA2X2_INT_ENABLE1_REG
+
+#define BMA2X2_EN_ORIENT_INT__POS 6
+#define BMA2X2_EN_ORIENT_INT__LEN 1
+#define BMA2X2_EN_ORIENT_INT__MSK 0x40
+#define BMA2X2_EN_ORIENT_INT__REG BMA2X2_INT_ENABLE1_REG
+
+#define BMA2X2_EN_FLAT_INT__POS 7
+#define BMA2X2_EN_FLAT_INT__LEN 1
+#define BMA2X2_EN_FLAT_INT__MSK 0x80
+#define BMA2X2_EN_FLAT_INT__REG BMA2X2_INT_ENABLE1_REG
+
+#define BMA2X2_EN_HIGHG_X_INT__POS 0
+#define BMA2X2_EN_HIGHG_X_INT__LEN 1
+#define BMA2X2_EN_HIGHG_X_INT__MSK 0x01
+#define BMA2X2_EN_HIGHG_X_INT__REG BMA2X2_INT_ENABLE2_REG
+
+#define BMA2X2_EN_HIGHG_Y_INT__POS 1
+#define BMA2X2_EN_HIGHG_Y_INT__LEN 1
+#define BMA2X2_EN_HIGHG_Y_INT__MSK 0x02
+#define BMA2X2_EN_HIGHG_Y_INT__REG BMA2X2_INT_ENABLE2_REG
+
+#define BMA2X2_EN_HIGHG_Z_INT__POS 2
+#define BMA2X2_EN_HIGHG_Z_INT__LEN 1
+#define BMA2X2_EN_HIGHG_Z_INT__MSK 0x04
+#define BMA2X2_EN_HIGHG_Z_INT__REG BMA2X2_INT_ENABLE2_REG
+
+#define BMA2X2_EN_LOWG_INT__POS 3
+#define BMA2X2_EN_LOWG_INT__LEN 1
+#define BMA2X2_EN_LOWG_INT__MSK 0x08
+#define BMA2X2_EN_LOWG_INT__REG BMA2X2_INT_ENABLE2_REG
+
+#define BMA2X2_EN_NEW_DATA_INT__POS 4
+#define BMA2X2_EN_NEW_DATA_INT__LEN 1
+#define BMA2X2_EN_NEW_DATA_INT__MSK 0x10
+#define BMA2X2_EN_NEW_DATA_INT__REG BMA2X2_INT_ENABLE2_REG
+
+#define BMA2X2_INT_FFULL_EN_INT__POS 5
+#define BMA2X2_INT_FFULL_EN_INT__LEN 1
+#define BMA2X2_INT_FFULL_EN_INT__MSK 0x20
+#define BMA2X2_INT_FFULL_EN_INT__REG BMA2X2_INT_ENABLE2_REG
+
+#define BMA2X2_INT_FWM_EN_INT__POS 6
+#define BMA2X2_INT_FWM_EN_INT__LEN 1
+#define BMA2X2_INT_FWM_EN_INT__MSK 0x40
+#define BMA2X2_INT_FWM_EN_INT__REG BMA2X2_INT_ENABLE2_REG
+
+#define BMA2X2_INT_SLO_NO_MOT_EN_X_INT__POS 0
+#define BMA2X2_INT_SLO_NO_MOT_EN_X_INT__LEN 1
+#define BMA2X2_INT_SLO_NO_MOT_EN_X_INT__MSK 0x01
+#define BMA2X2_INT_SLO_NO_MOT_EN_X_INT__REG BMA2X2_INT_SLO_NO_MOT_REG
+
+#define BMA2X2_INT_SLO_NO_MOT_EN_Y_INT__POS 1
+#define BMA2X2_INT_SLO_NO_MOT_EN_Y_INT__LEN 1
+#define BMA2X2_INT_SLO_NO_MOT_EN_Y_INT__MSK 0x02
+#define BMA2X2_INT_SLO_NO_MOT_EN_Y_INT__REG BMA2X2_INT_SLO_NO_MOT_REG
+
+#define BMA2X2_INT_SLO_NO_MOT_EN_Z_INT__POS 2
+#define BMA2X2_INT_SLO_NO_MOT_EN_Z_INT__LEN 1
+#define BMA2X2_INT_SLO_NO_MOT_EN_Z_INT__MSK 0x04
+#define BMA2X2_INT_SLO_NO_MOT_EN_Z_INT__REG BMA2X2_INT_SLO_NO_MOT_REG
+
+#define BMA2X2_INT_SLO_NO_MOT_EN_SEL_INT__POS 3
+#define BMA2X2_INT_SLO_NO_MOT_EN_SEL_INT__LEN 1
+#define BMA2X2_INT_SLO_NO_MOT_EN_SEL_INT__MSK 0x08
+#define BMA2X2_INT_SLO_NO_MOT_EN_SEL_INT__REG BMA2X2_INT_SLO_NO_MOT_REG
+
+#define BMA2X2_EN_INT1_PAD_LOWG__POS 0
+#define BMA2X2_EN_INT1_PAD_LOWG__LEN 1
+#define BMA2X2_EN_INT1_PAD_LOWG__MSK 0x01
+#define BMA2X2_EN_INT1_PAD_LOWG__REG BMA2X2_INT1_PAD_SEL_REG
+
+#define BMA2X2_EN_INT1_PAD_HIGHG__POS 1
+#define BMA2X2_EN_INT1_PAD_HIGHG__LEN 1
+#define BMA2X2_EN_INT1_PAD_HIGHG__MSK 0x02
+#define BMA2X2_EN_INT1_PAD_HIGHG__REG BMA2X2_INT1_PAD_SEL_REG
+
+#define BMA2X2_EN_INT1_PAD_SLOPE__POS 2
+#define BMA2X2_EN_INT1_PAD_SLOPE__LEN 1
+#define BMA2X2_EN_INT1_PAD_SLOPE__MSK 0x04
+#define BMA2X2_EN_INT1_PAD_SLOPE__REG BMA2X2_INT1_PAD_SEL_REG
+
+#define BMA2X2_EN_INT1_PAD_SLO_NO_MOT__POS 3
+#define BMA2X2_EN_INT1_PAD_SLO_NO_MOT__LEN 1
+#define BMA2X2_EN_INT1_PAD_SLO_NO_MOT__MSK 0x08
+#define BMA2X2_EN_INT1_PAD_SLO_NO_MOT__REG BMA2X2_INT1_PAD_SEL_REG
+
+#define BMA2X2_EN_INT1_PAD_DB_TAP__POS 4
+#define BMA2X2_EN_INT1_PAD_DB_TAP__LEN 1
+#define BMA2X2_EN_INT1_PAD_DB_TAP__MSK 0x10
+#define BMA2X2_EN_INT1_PAD_DB_TAP__REG BMA2X2_INT1_PAD_SEL_REG
+
+#define BMA2X2_EN_INT1_PAD_SNG_TAP__POS 5
+#define BMA2X2_EN_INT1_PAD_SNG_TAP__LEN 1
+#define BMA2X2_EN_INT1_PAD_SNG_TAP__MSK 0x20
+#define BMA2X2_EN_INT1_PAD_SNG_TAP__REG BMA2X2_INT1_PAD_SEL_REG
+
+#define BMA2X2_EN_INT1_PAD_ORIENT__POS 6
+#define BMA2X2_EN_INT1_PAD_ORIENT__LEN 1
+#define BMA2X2_EN_INT1_PAD_ORIENT__MSK 0x40
+#define BMA2X2_EN_INT1_PAD_ORIENT__REG BMA2X2_INT1_PAD_SEL_REG
+
+#define BMA2X2_EN_INT1_PAD_FLAT__POS 7
+#define BMA2X2_EN_INT1_PAD_FLAT__LEN 1
+#define BMA2X2_EN_INT1_PAD_FLAT__MSK 0x80
+#define BMA2X2_EN_INT1_PAD_FLAT__REG BMA2X2_INT1_PAD_SEL_REG
+
+#define BMA2X2_EN_INT2_PAD_LOWG__POS 0
+#define BMA2X2_EN_INT2_PAD_LOWG__LEN 1
+#define BMA2X2_EN_INT2_PAD_LOWG__MSK 0x01
+#define BMA2X2_EN_INT2_PAD_LOWG__REG BMA2X2_INT2_PAD_SEL_REG
+
+#define BMA2X2_EN_INT2_PAD_HIGHG__POS 1
+#define BMA2X2_EN_INT2_PAD_HIGHG__LEN 1
+#define BMA2X2_EN_INT2_PAD_HIGHG__MSK 0x02
+#define BMA2X2_EN_INT2_PAD_HIGHG__REG BMA2X2_INT2_PAD_SEL_REG
+
+#define BMA2X2_EN_INT2_PAD_SLOPE__POS 2
+#define BMA2X2_EN_INT2_PAD_SLOPE__LEN 1
+#define BMA2X2_EN_INT2_PAD_SLOPE__MSK 0x04
+#define BMA2X2_EN_INT2_PAD_SLOPE__REG BMA2X2_INT2_PAD_SEL_REG
+
+#define BMA2X2_EN_INT2_PAD_SLO_NO_MOT__POS 3
+#define BMA2X2_EN_INT2_PAD_SLO_NO_MOT__LEN 1
+#define BMA2X2_EN_INT2_PAD_SLO_NO_MOT__MSK 0x08
+#define BMA2X2_EN_INT2_PAD_SLO_NO_MOT__REG BMA2X2_INT2_PAD_SEL_REG
+
+#define BMA2X2_EN_INT2_PAD_DB_TAP__POS 4
+#define BMA2X2_EN_INT2_PAD_DB_TAP__LEN 1
+#define BMA2X2_EN_INT2_PAD_DB_TAP__MSK 0x10
+#define BMA2X2_EN_INT2_PAD_DB_TAP__REG BMA2X2_INT2_PAD_SEL_REG
+
+#define BMA2X2_EN_INT2_PAD_SNG_TAP__POS 5
+#define BMA2X2_EN_INT2_PAD_SNG_TAP__LEN 1
+#define BMA2X2_EN_INT2_PAD_SNG_TAP__MSK 0x20
+#define BMA2X2_EN_INT2_PAD_SNG_TAP__REG BMA2X2_INT2_PAD_SEL_REG
+
+#define BMA2X2_EN_INT2_PAD_ORIENT__POS 6
+#define BMA2X2_EN_INT2_PAD_ORIENT__LEN 1
+#define BMA2X2_EN_INT2_PAD_ORIENT__MSK 0x40
+#define BMA2X2_EN_INT2_PAD_ORIENT__REG BMA2X2_INT2_PAD_SEL_REG
+
+#define BMA2X2_EN_INT2_PAD_FLAT__POS 7
+#define BMA2X2_EN_INT2_PAD_FLAT__LEN 1
+#define BMA2X2_EN_INT2_PAD_FLAT__MSK 0x80
+#define BMA2X2_EN_INT2_PAD_FLAT__REG BMA2X2_INT2_PAD_SEL_REG
+
+#define BMA2X2_EN_INT1_PAD_NEWDATA__POS 0
+#define BMA2X2_EN_INT1_PAD_NEWDATA__LEN 1
+#define BMA2X2_EN_INT1_PAD_NEWDATA__MSK 0x01
+#define BMA2X2_EN_INT1_PAD_NEWDATA__REG BMA2X2_INT_DATA_SEL_REG
+
+#define BMA2X2_EN_INT1_PAD_FWM__POS 1
+#define BMA2X2_EN_INT1_PAD_FWM__LEN 1
+#define BMA2X2_EN_INT1_PAD_FWM__MSK 0x02
+#define BMA2X2_EN_INT1_PAD_FWM__REG BMA2X2_INT_DATA_SEL_REG
+
+#define BMA2X2_EN_INT1_PAD_FFULL__POS 2
+#define BMA2X2_EN_INT1_PAD_FFULL__LEN 1
+#define BMA2X2_EN_INT1_PAD_FFULL__MSK 0x04
+#define BMA2X2_EN_INT1_PAD_FFULL__REG BMA2X2_INT_DATA_SEL_REG
+
+#define BMA2X2_EN_INT2_PAD_FFULL__POS 5
+#define BMA2X2_EN_INT2_PAD_FFULL__LEN 1
+#define BMA2X2_EN_INT2_PAD_FFULL__MSK 0x20
+#define BMA2X2_EN_INT2_PAD_FFULL__REG BMA2X2_INT_DATA_SEL_REG
+
+#define BMA2X2_EN_INT2_PAD_FWM__POS 6
+#define BMA2X2_EN_INT2_PAD_FWM__LEN 1
+#define BMA2X2_EN_INT2_PAD_FWM__MSK 0x40
+#define BMA2X2_EN_INT2_PAD_FWM__REG BMA2X2_INT_DATA_SEL_REG
+
+#define BMA2X2_EN_INT2_PAD_NEWDATA__POS 7
+#define BMA2X2_EN_INT2_PAD_NEWDATA__LEN 1
+#define BMA2X2_EN_INT2_PAD_NEWDATA__MSK 0x80
+#define BMA2X2_EN_INT2_PAD_NEWDATA__REG BMA2X2_INT_DATA_SEL_REG
+
+#define BMA2X2_UNFILT_INT_SRC_LOWG__POS 0
+#define BMA2X2_UNFILT_INT_SRC_LOWG__LEN 1
+#define BMA2X2_UNFILT_INT_SRC_LOWG__MSK 0x01
+#define BMA2X2_UNFILT_INT_SRC_LOWG__REG BMA2X2_INT_SRC_REG
+
+#define BMA2X2_UNFILT_INT_SRC_HIGHG__POS 1
+#define BMA2X2_UNFILT_INT_SRC_HIGHG__LEN 1
+#define BMA2X2_UNFILT_INT_SRC_HIGHG__MSK 0x02
+#define BMA2X2_UNFILT_INT_SRC_HIGHG__REG BMA2X2_INT_SRC_REG
+
+#define BMA2X2_UNFILT_INT_SRC_SLOPE__POS 2
+#define BMA2X2_UNFILT_INT_SRC_SLOPE__LEN 1
+#define BMA2X2_UNFILT_INT_SRC_SLOPE__MSK 0x04
+#define BMA2X2_UNFILT_INT_SRC_SLOPE__REG BMA2X2_INT_SRC_REG
+
+#define BMA2X2_UNFILT_INT_SRC_SLO_NO_MOT__POS 3
+#define BMA2X2_UNFILT_INT_SRC_SLO_NO_MOT__LEN 1
+#define BMA2X2_UNFILT_INT_SRC_SLO_NO_MOT__MSK 0x08
+#define BMA2X2_UNFILT_INT_SRC_SLO_NO_MOT__REG BMA2X2_INT_SRC_REG
+
+#define BMA2X2_UNFILT_INT_SRC_TAP__POS 4
+#define BMA2X2_UNFILT_INT_SRC_TAP__LEN 1
+#define BMA2X2_UNFILT_INT_SRC_TAP__MSK 0x10
+#define BMA2X2_UNFILT_INT_SRC_TAP__REG BMA2X2_INT_SRC_REG
+
+#define BMA2X2_UNFILT_INT_SRC_DATA__POS 5
+#define BMA2X2_UNFILT_INT_SRC_DATA__LEN 1
+#define BMA2X2_UNFILT_INT_SRC_DATA__MSK 0x20
+#define BMA2X2_UNFILT_INT_SRC_DATA__REG BMA2X2_INT_SRC_REG
+
+#define BMA2X2_INT1_PAD_ACTIVE_LEVEL__POS 0
+#define BMA2X2_INT1_PAD_ACTIVE_LEVEL__LEN 1
+#define BMA2X2_INT1_PAD_ACTIVE_LEVEL__MSK 0x01
+#define BMA2X2_INT1_PAD_ACTIVE_LEVEL__REG BMA2X2_INT_SET_REG
+
+#define BMA2X2_INT2_PAD_ACTIVE_LEVEL__POS 2
+#define BMA2X2_INT2_PAD_ACTIVE_LEVEL__LEN 1
+#define BMA2X2_INT2_PAD_ACTIVE_LEVEL__MSK 0x04
+#define BMA2X2_INT2_PAD_ACTIVE_LEVEL__REG BMA2X2_INT_SET_REG
+
+#define BMA2X2_INT1_PAD_OUTPUT_TYPE__POS 1
+#define BMA2X2_INT1_PAD_OUTPUT_TYPE__LEN 1
+#define BMA2X2_INT1_PAD_OUTPUT_TYPE__MSK 0x02
+#define BMA2X2_INT1_PAD_OUTPUT_TYPE__REG BMA2X2_INT_SET_REG
+
+#define BMA2X2_INT2_PAD_OUTPUT_TYPE__POS 3
+#define BMA2X2_INT2_PAD_OUTPUT_TYPE__LEN 1
+#define BMA2X2_INT2_PAD_OUTPUT_TYPE__MSK 0x08
+#define BMA2X2_INT2_PAD_OUTPUT_TYPE__REG BMA2X2_INT_SET_REG
+
+#define BMA2X2_INT_MODE_SEL__POS 0
+#define BMA2X2_INT_MODE_SEL__LEN 4
+#define BMA2X2_INT_MODE_SEL__MSK 0x0F
+#define BMA2X2_INT_MODE_SEL__REG BMA2X2_INT_CTRL_REG
+
+#define BMA2X2_RESET_INT__POS 7
+#define BMA2X2_RESET_INT__LEN 1
+#define BMA2X2_RESET_INT__MSK 0x80
+#define BMA2X2_RESET_INT__REG BMA2X2_INT_CTRL_REG
+
+#define BMA2X2_LOWG_DUR__POS 0
+#define BMA2X2_LOWG_DUR__LEN 8
+#define BMA2X2_LOWG_DUR__MSK 0xFF
+#define BMA2X2_LOWG_DUR__REG BMA2X2_LOW_DURN_REG
+
+#define BMA2X2_LOWG_THRES__POS 0
+#define BMA2X2_LOWG_THRES__LEN 8
+#define BMA2X2_LOWG_THRES__MSK 0xFF
+#define BMA2X2_LOWG_THRES__REG BMA2X2_LOW_THRES_REG
+
+#define BMA2X2_LOWG_HYST__POS 0
+#define BMA2X2_LOWG_HYST__LEN 2
+#define BMA2X2_LOWG_HYST__MSK 0x03
+#define BMA2X2_LOWG_HYST__REG BMA2X2_LOW_HIGH_HYST_REG
+
+#define BMA2X2_LOWG_INT_MODE__POS 2
+#define BMA2X2_LOWG_INT_MODE__LEN 1
+#define BMA2X2_LOWG_INT_MODE__MSK 0x04
+#define BMA2X2_LOWG_INT_MODE__REG BMA2X2_LOW_HIGH_HYST_REG
+
+#define BMA2X2_HIGHG_DUR__POS 0
+#define BMA2X2_HIGHG_DUR__LEN 8
+#define BMA2X2_HIGHG_DUR__MSK 0xFF
+#define BMA2X2_HIGHG_DUR__REG BMA2X2_HIGH_DURN_REG
+
+#define BMA2X2_HIGHG_THRES__POS 0
+#define BMA2X2_HIGHG_THRES__LEN 8
+#define BMA2X2_HIGHG_THRES__MSK 0xFF
+#define BMA2X2_HIGHG_THRES__REG BMA2X2_HIGH_THRES_REG
+
+#define BMA2X2_HIGHG_HYST__POS 6
+#define BMA2X2_HIGHG_HYST__LEN 2
+#define BMA2X2_HIGHG_HYST__MSK 0xC0
+#define BMA2X2_HIGHG_HYST__REG BMA2X2_LOW_HIGH_HYST_REG
+
+#define BMA2X2_SLOPE_DUR__POS 0
+#define BMA2X2_SLOPE_DUR__LEN 2
+#define BMA2X2_SLOPE_DUR__MSK 0x03
+#define BMA2X2_SLOPE_DUR__REG BMA2X2_SLOPE_DURN_REG
+
+#define BMA2X2_SLO_NO_MOT_DUR__POS 2
+#define BMA2X2_SLO_NO_MOT_DUR__LEN 6
+#define BMA2X2_SLO_NO_MOT_DUR__MSK 0xFC
+#define BMA2X2_SLO_NO_MOT_DUR__REG BMA2X2_SLOPE_DURN_REG
+
+#define BMA2X2_SLOPE_THRES__POS 0
+#define BMA2X2_SLOPE_THRES__LEN 8
+#define BMA2X2_SLOPE_THRES__MSK 0xFF
+#define BMA2X2_SLOPE_THRES__REG BMA2X2_SLOPE_THRES_REG
+
+#define BMA2X2_SLO_NO_MOT_THRES__POS 0
+#define BMA2X2_SLO_NO_MOT_THRES__LEN 8
+#define BMA2X2_SLO_NO_MOT_THRES__MSK 0xFF
+#define BMA2X2_SLO_NO_MOT_THRES__REG BMA2X2_SLO_NO_MOT_THRES_REG
+
+#define BMA2X2_TAP_DUR__POS 0
+#define BMA2X2_TAP_DUR__LEN 3
+#define BMA2X2_TAP_DUR__MSK 0x07
+#define BMA2X2_TAP_DUR__REG BMA2X2_TAP_PARAM_REG
+
+#define BMA2X2_TAP_SHOCK_DURN__POS 6
+#define BMA2X2_TAP_SHOCK_DURN__LEN 1
+#define BMA2X2_TAP_SHOCK_DURN__MSK 0x40
+#define BMA2X2_TAP_SHOCK_DURN__REG BMA2X2_TAP_PARAM_REG
+
+#define BMA2X2_ADV_TAP_INT__POS 5
+#define BMA2X2_ADV_TAP_INT__LEN 1
+#define BMA2X2_ADV_TAP_INT__MSK 0x20
+#define BMA2X2_ADV_TAP_INT__REG BMA2X2_TAP_PARAM_REG
+
+#define BMA2X2_TAP_QUIET_DURN__POS 7
+#define BMA2X2_TAP_QUIET_DURN__LEN 1
+#define BMA2X2_TAP_QUIET_DURN__MSK 0x80
+#define BMA2X2_TAP_QUIET_DURN__REG BMA2X2_TAP_PARAM_REG
+
+#define BMA2X2_TAP_THRES__POS 0
+#define BMA2X2_TAP_THRES__LEN 5
+#define BMA2X2_TAP_THRES__MSK 0x1F
+#define BMA2X2_TAP_THRES__REG BMA2X2_TAP_THRES_REG
+
+#define BMA2X2_TAP_SAMPLES__POS 6
+#define BMA2X2_TAP_SAMPLES__LEN 2
+#define BMA2X2_TAP_SAMPLES__MSK 0xC0
+#define BMA2X2_TAP_SAMPLES__REG BMA2X2_TAP_THRES_REG
+
+#define BMA2X2_ORIENT_MODE__POS 0
+#define BMA2X2_ORIENT_MODE__LEN 2
+#define BMA2X2_ORIENT_MODE__MSK 0x03
+#define BMA2X2_ORIENT_MODE__REG BMA2X2_ORIENT_PARAM_REG
+
+#define BMA2X2_ORIENT_BLOCK__POS 2
+#define BMA2X2_ORIENT_BLOCK__LEN 2
+#define BMA2X2_ORIENT_BLOCK__MSK 0x0C
+#define BMA2X2_ORIENT_BLOCK__REG BMA2X2_ORIENT_PARAM_REG
+
+#define BMA2X2_ORIENT_HYST__POS 4
+#define BMA2X2_ORIENT_HYST__LEN 3
+#define BMA2X2_ORIENT_HYST__MSK 0x70
+#define BMA2X2_ORIENT_HYST__REG BMA2X2_ORIENT_PARAM_REG
+
+#define BMA2X2_ORIENT_AXIS__POS 7
+#define BMA2X2_ORIENT_AXIS__LEN 1
+#define BMA2X2_ORIENT_AXIS__MSK 0x80
+#define BMA2X2_ORIENT_AXIS__REG BMA2X2_THETA_BLOCK_REG
+
+#define BMA2X2_ORIENT_UD_EN__POS 6
+#define BMA2X2_ORIENT_UD_EN__LEN 1
+#define BMA2X2_ORIENT_UD_EN__MSK 0x40
+#define BMA2X2_ORIENT_UD_EN__REG BMA2X2_THETA_BLOCK_REG
+
+#define BMA2X2_THETA_BLOCK__POS 0
+#define BMA2X2_THETA_BLOCK__LEN 6
+#define BMA2X2_THETA_BLOCK__MSK 0x3F
+#define BMA2X2_THETA_BLOCK__REG BMA2X2_THETA_BLOCK_REG
+
+#define BMA2X2_THETA_FLAT__POS 0
+#define BMA2X2_THETA_FLAT__LEN 6
+#define BMA2X2_THETA_FLAT__MSK 0x3F
+#define BMA2X2_THETA_FLAT__REG BMA2X2_THETA_FLAT_REG
+
+#define BMA2X2_FLAT_HOLD_TIME__POS 4
+#define BMA2X2_FLAT_HOLD_TIME__LEN 2
+#define BMA2X2_FLAT_HOLD_TIME__MSK 0x30
+#define BMA2X2_FLAT_HOLD_TIME__REG BMA2X2_FLAT_HOLD_TIME_REG
+
+#define BMA2X2_FLAT_HYS__POS 0
+#define BMA2X2_FLAT_HYS__LEN 3
+#define BMA2X2_FLAT_HYS__MSK 0x07
+#define BMA2X2_FLAT_HYS__REG BMA2X2_FLAT_HOLD_TIME_REG
+
+#define BMA2X2_FIFO_WML_TRIG_RETAIN__POS 0
+#define BMA2X2_FIFO_WML_TRIG_RETAIN__LEN 6
+#define BMA2X2_FIFO_WML_TRIG_RETAIN__MSK 0x3F
+#define BMA2X2_FIFO_WML_TRIG_RETAIN__REG BMA2X2_FIFO_WML_TRIG
+
+#define BMA2X2_EN_SELF_TEST__POS 0
+#define BMA2X2_EN_SELF_TEST__LEN 2
+#define BMA2X2_EN_SELF_TEST__MSK 0x03
+#define BMA2X2_EN_SELF_TEST__REG BMA2X2_SELF_TEST_REG
+
+#define BMA2X2_NEG_SELF_TEST__POS 2
+#define BMA2X2_NEG_SELF_TEST__LEN 1
+#define BMA2X2_NEG_SELF_TEST__MSK 0x04
+#define BMA2X2_NEG_SELF_TEST__REG BMA2X2_SELF_TEST_REG
+
+#define BMA2X2_SELF_TEST_AMP__POS 4
+#define BMA2X2_SELF_TEST_AMP__LEN 3
+#define BMA2X2_SELF_TEST_AMP__MSK 0x70
+#define BMA2X2_SELF_TEST_AMP__REG BMA2X2_SELF_TEST_REG
+
+#define BMA2X2_UNLOCK_EE_PROG_MODE__POS 0
+#define BMA2X2_UNLOCK_EE_PROG_MODE__LEN 1
+#define BMA2X2_UNLOCK_EE_PROG_MODE__MSK 0x01
+#define BMA2X2_UNLOCK_EE_PROG_MODE__REG BMA2X2_EEPROM_CTRL_REG
+
+#define BMA2X2_START_EE_PROG_TRIG__POS 1
+#define BMA2X2_START_EE_PROG_TRIG__LEN 1
+#define BMA2X2_START_EE_PROG_TRIG__MSK 0x02
+#define BMA2X2_START_EE_PROG_TRIG__REG BMA2X2_EEPROM_CTRL_REG
+
+#define BMA2X2_EE_PROG_READY__POS 2
+#define BMA2X2_EE_PROG_READY__LEN 1
+#define BMA2X2_EE_PROG_READY__MSK 0x04
+#define BMA2X2_EE_PROG_READY__REG BMA2X2_EEPROM_CTRL_REG
+
+#define BMA2X2_UPDATE_IMAGE__POS 3
+#define BMA2X2_UPDATE_IMAGE__LEN 1
+#define BMA2X2_UPDATE_IMAGE__MSK 0x08
+#define BMA2X2_UPDATE_IMAGE__REG BMA2X2_EEPROM_CTRL_REG
+
+#define BMA2X2_EE_REMAIN__POS 4
+#define BMA2X2_EE_REMAIN__LEN 4
+#define BMA2X2_EE_REMAIN__MSK 0xF0
+#define BMA2X2_EE_REMAIN__REG BMA2X2_EEPROM_CTRL_REG
+
+#define BMA2X2_EN_SPI_MODE_3__POS 0
+#define BMA2X2_EN_SPI_MODE_3__LEN 1
+#define BMA2X2_EN_SPI_MODE_3__MSK 0x01
+#define BMA2X2_EN_SPI_MODE_3__REG BMA2X2_SERIAL_CTRL_REG
+
+#define BMA2X2_I2C_WATCHDOG_PERIOD__POS 1
+#define BMA2X2_I2C_WATCHDOG_PERIOD__LEN 1
+#define BMA2X2_I2C_WATCHDOG_PERIOD__MSK 0x02
+#define BMA2X2_I2C_WATCHDOG_PERIOD__REG BMA2X2_SERIAL_CTRL_REG
+
+#define BMA2X2_EN_I2C_WATCHDOG__POS 2
+#define BMA2X2_EN_I2C_WATCHDOG__LEN 1
+#define BMA2X2_EN_I2C_WATCHDOG__MSK 0x04
+#define BMA2X2_EN_I2C_WATCHDOG__REG BMA2X2_SERIAL_CTRL_REG
+
+#define BMA2X2_EXT_MODE__POS 7
+#define BMA2X2_EXT_MODE__LEN 1
+#define BMA2X2_EXT_MODE__MSK 0x80
+#define BMA2X2_EXT_MODE__REG BMA2X2_EXTMODE_CTRL_REG
+
+#define BMA2X2_ALLOW_UPPER__POS 6
+#define BMA2X2_ALLOW_UPPER__LEN 1
+#define BMA2X2_ALLOW_UPPER__MSK 0x40
+#define BMA2X2_ALLOW_UPPER__REG BMA2X2_EXTMODE_CTRL_REG
+
+#define BMA2X2_MAP_2_LOWER__POS 5
+#define BMA2X2_MAP_2_LOWER__LEN 1
+#define BMA2X2_MAP_2_LOWER__MSK 0x20
+#define BMA2X2_MAP_2_LOWER__REG BMA2X2_EXTMODE_CTRL_REG
+
+#define BMA2X2_MAGIC_NUMBER__POS 0
+#define BMA2X2_MAGIC_NUMBER__LEN 5
+#define BMA2X2_MAGIC_NUMBER__MSK 0x1F
+#define BMA2X2_MAGIC_NUMBER__REG BMA2X2_EXTMODE_CTRL_REG
+
+#define BMA2X2_UNLOCK_EE_WRITE_TRIM__POS 4
+#define BMA2X2_UNLOCK_EE_WRITE_TRIM__LEN 4
+#define BMA2X2_UNLOCK_EE_WRITE_TRIM__MSK 0xF0
+#define BMA2X2_UNLOCK_EE_WRITE_TRIM__REG BMA2X2_CTRL_UNLOCK_REG
+
+#define BMA2X2_EN_SLOW_COMP_X__POS 0
+#define BMA2X2_EN_SLOW_COMP_X__LEN 1
+#define BMA2X2_EN_SLOW_COMP_X__MSK 0x01
+#define BMA2X2_EN_SLOW_COMP_X__REG BMA2X2_OFFSET_CTRL_REG
+
+#define BMA2X2_EN_SLOW_COMP_Y__POS 1
+#define BMA2X2_EN_SLOW_COMP_Y__LEN 1
+#define BMA2X2_EN_SLOW_COMP_Y__MSK 0x02
+#define BMA2X2_EN_SLOW_COMP_Y__REG BMA2X2_OFFSET_CTRL_REG
+
+#define BMA2X2_EN_SLOW_COMP_Z__POS 2
+#define BMA2X2_EN_SLOW_COMP_Z__LEN 1
+#define BMA2X2_EN_SLOW_COMP_Z__MSK 0x04
+#define BMA2X2_EN_SLOW_COMP_Z__REG BMA2X2_OFFSET_CTRL_REG
+
+#define BMA2X2_FAST_CAL_RDY_S__POS 4
+#define BMA2X2_FAST_CAL_RDY_S__LEN 1
+#define BMA2X2_FAST_CAL_RDY_S__MSK 0x10
+#define BMA2X2_FAST_CAL_RDY_S__REG BMA2X2_OFFSET_CTRL_REG
+
+#define BMA2X2_CAL_TRIGGER__POS 5
+#define BMA2X2_CAL_TRIGGER__LEN 2
+#define BMA2X2_CAL_TRIGGER__MSK 0x60
+#define BMA2X2_CAL_TRIGGER__REG BMA2X2_OFFSET_CTRL_REG
+
+#define BMA2X2_RESET_OFFSET_REGS__POS 7
+#define BMA2X2_RESET_OFFSET_REGS__LEN 1
+#define BMA2X2_RESET_OFFSET_REGS__MSK 0x80
+#define BMA2X2_RESET_OFFSET_REGS__REG BMA2X2_OFFSET_CTRL_REG
+
+#define BMA2X2_COMP_CUTOFF__POS 0
+#define BMA2X2_COMP_CUTOFF__LEN 1
+#define BMA2X2_COMP_CUTOFF__MSK 0x01
+#define BMA2X2_COMP_CUTOFF__REG BMA2X2_OFFSET_PARAMS_REG
+
+#define BMA2X2_COMP_TARGET_OFFSET_X__POS 1
+#define BMA2X2_COMP_TARGET_OFFSET_X__LEN 2
+#define BMA2X2_COMP_TARGET_OFFSET_X__MSK 0x06
+#define BMA2X2_COMP_TARGET_OFFSET_X__REG BMA2X2_OFFSET_PARAMS_REG
+
+#define BMA2X2_COMP_TARGET_OFFSET_Y__POS 3
+#define BMA2X2_COMP_TARGET_OFFSET_Y__LEN 2
+#define BMA2X2_COMP_TARGET_OFFSET_Y__MSK 0x18
+#define BMA2X2_COMP_TARGET_OFFSET_Y__REG BMA2X2_OFFSET_PARAMS_REG
+
+#define BMA2X2_COMP_TARGET_OFFSET_Z__POS 5
+#define BMA2X2_COMP_TARGET_OFFSET_Z__LEN 2
+#define BMA2X2_COMP_TARGET_OFFSET_Z__MSK 0x60
+#define BMA2X2_COMP_TARGET_OFFSET_Z__REG BMA2X2_OFFSET_PARAMS_REG
+
+#define BMA2X2_FIFO_DATA_SELECT__POS 0
+#define BMA2X2_FIFO_DATA_SELECT__LEN 2
+#define BMA2X2_FIFO_DATA_SELECT__MSK 0x03
+#define BMA2X2_FIFO_DATA_SELECT__REG BMA2X2_FIFO_MODE_REG
+
+#define BMA2X2_FIFO_TRIGGER_SOURCE__POS 2
+#define BMA2X2_FIFO_TRIGGER_SOURCE__LEN 2
+#define BMA2X2_FIFO_TRIGGER_SOURCE__MSK 0x0C
+#define BMA2X2_FIFO_TRIGGER_SOURCE__REG BMA2X2_FIFO_MODE_REG
+
+#define BMA2X2_FIFO_TRIGGER_ACTION__POS 4
+#define BMA2X2_FIFO_TRIGGER_ACTION__LEN 2
+#define BMA2X2_FIFO_TRIGGER_ACTION__MSK 0x30
+#define BMA2X2_FIFO_TRIGGER_ACTION__REG BMA2X2_FIFO_MODE_REG
+
+#define BMA2X2_FIFO_MODE__POS 6
+#define BMA2X2_FIFO_MODE__LEN 2
+#define BMA2X2_FIFO_MODE__MSK 0xC0
+#define BMA2X2_FIFO_MODE__REG BMA2X2_FIFO_MODE_REG
+
+
+#define BMA2X2_STATUS1 0
+#define BMA2X2_STATUS2 1
+#define BMA2X2_STATUS3 2
+#define BMA2X2_STATUS4 3
+#define BMA2X2_STATUS5 4
+
+
+#define BMA2X2_RANGE_2G 3
+#define BMA2X2_RANGE_4G 5
+#define BMA2X2_RANGE_8G 8
+#define BMA2X2_RANGE_16G 12
+
+
+#define BMA2X2_BW_7_81HZ 0x08
+#define BMA2X2_BW_15_63HZ 0x09
+#define BMA2X2_BW_31_25HZ 0x0A
+#define BMA2X2_BW_62_50HZ 0x0B
+#define BMA2X2_BW_125HZ 0x0C
+#define BMA2X2_BW_250HZ 0x0D
+#define BMA2X2_BW_500HZ 0x0E
+#define BMA2X2_BW_1000HZ 0x0F
+
+#define BMA2X2_SLEEP_DUR_0_5MS 0x05
+#define BMA2X2_SLEEP_DUR_1MS 0x06
+#define BMA2X2_SLEEP_DUR_2MS 0x07
+#define BMA2X2_SLEEP_DUR_4MS 0x08
+#define BMA2X2_SLEEP_DUR_6MS 0x09
+#define BMA2X2_SLEEP_DUR_10MS 0x0A
+#define BMA2X2_SLEEP_DUR_25MS 0x0B
+#define BMA2X2_SLEEP_DUR_50MS 0x0C
+#define BMA2X2_SLEEP_DUR_100MS 0x0D
+#define BMA2X2_SLEEP_DUR_500MS 0x0E
+#define BMA2X2_SLEEP_DUR_1S 0x0F
+
+#define BMA2X2_LATCH_DUR_NON_LATCH 0x00
+#define BMA2X2_LATCH_DUR_250MS 0x01
+#define BMA2X2_LATCH_DUR_500MS 0x02
+#define BMA2X2_LATCH_DUR_1S 0x03
+#define BMA2X2_LATCH_DUR_2S 0x04
+#define BMA2X2_LATCH_DUR_4S 0x05
+#define BMA2X2_LATCH_DUR_8S 0x06
+#define BMA2X2_LATCH_DUR_LATCH 0x07
+#define BMA2X2_LATCH_DUR_NON_LATCH1 0x08
+#define BMA2X2_LATCH_DUR_250US 0x09
+#define BMA2X2_LATCH_DUR_500US 0x0A
+#define BMA2X2_LATCH_DUR_1MS 0x0B
+#define BMA2X2_LATCH_DUR_12_5MS 0x0C
+#define BMA2X2_LATCH_DUR_25MS 0x0D
+#define BMA2X2_LATCH_DUR_50MS 0x0E
+#define BMA2X2_LATCH_DUR_LATCH1 0x0F
+
+#define BMA2X2_MODE_NORMAL 0
+#define BMA2X2_MODE_LOWPOWER1 1
+#define BMA2X2_MODE_SUSPEND 2
+#define BMA2X2_MODE_DEEP_SUSPEND 3
+#define BMA2X2_MODE_LOWPOWER2 4
+#define BMA2X2_MODE_STANDBY 5
+
+#define BMA2X2_X_AXIS 0
+#define BMA2X2_Y_AXIS 1
+#define BMA2X2_Z_AXIS 2
+
+#define BMA2X2_Low_G_Interrupt 0
+#define BMA2X2_High_G_X_Interrupt 1
+#define BMA2X2_High_G_Y_Interrupt 2
+#define BMA2X2_High_G_Z_Interrupt 3
+#define BMA2X2_DATA_EN 4
+#define BMA2X2_Slope_X_Interrupt 5
+#define BMA2X2_Slope_Y_Interrupt 6
+#define BMA2X2_Slope_Z_Interrupt 7
+#define BMA2X2_Single_Tap_Interrupt 8
+#define BMA2X2_Double_Tap_Interrupt 9
+#define BMA2X2_Orient_Interrupt 10
+#define BMA2X2_Flat_Interrupt 11
+#define BMA2X2_FFULL_INTERRUPT 12
+#define BMA2X2_FWM_INTERRUPT 13
+
+#define BMA2X2_INT1_LOWG 0
+#define BMA2X2_INT2_LOWG 1
+#define BMA2X2_INT1_HIGHG 0
+#define BMA2X2_INT2_HIGHG 1
+#define BMA2X2_INT1_SLOPE 0
+#define BMA2X2_INT2_SLOPE 1
+#define BMA2X2_INT1_SLO_NO_MOT 0
+#define BMA2X2_INT2_SLO_NO_MOT 1
+#define BMA2X2_INT1_DTAP 0
+#define BMA2X2_INT2_DTAP 1
+#define BMA2X2_INT1_STAP 0
+#define BMA2X2_INT2_STAP 1
+#define BMA2X2_INT1_ORIENT 0
+#define BMA2X2_INT2_ORIENT 1
+#define BMA2X2_INT1_FLAT 0
+#define BMA2X2_INT2_FLAT 1
+#define BMA2X2_INT1_NDATA 0
+#define BMA2X2_INT2_NDATA 1
+#define BMA2X2_INT1_FWM 0
+#define BMA2X2_INT2_FWM 1
+#define BMA2X2_INT1_FFULL 0
+#define BMA2X2_INT2_FFULL 1
+
+#define BMA2X2_SRC_LOWG 0
+#define BMA2X2_SRC_HIGHG 1
+#define BMA2X2_SRC_SLOPE 2
+#define BMA2X2_SRC_SLO_NO_MOT 3
+#define BMA2X2_SRC_TAP 4
+#define BMA2X2_SRC_DATA 5
+
+#define BMA2X2_INT1_OUTPUT 0
+#define BMA2X2_INT2_OUTPUT 1
+#define BMA2X2_INT1_LEVEL 0
+#define BMA2X2_INT2_LEVEL 1
+
+#define BMA2X2_LOW_DURATION 0
+#define BMA2X2_HIGH_DURATION 1
+#define BMA2X2_SLOPE_DURATION 2
+#define BMA2X2_SLO_NO_MOT_DURATION 3
+
+#define BMA2X2_LOW_THRESHOLD 0
+#define BMA2X2_HIGH_THRESHOLD 1
+#define BMA2X2_SLOPE_THRESHOLD 2
+#define BMA2X2_SLO_NO_MOT_THRESHOLD 3
+
+
+#define BMA2X2_LOWG_HYST 0
+#define BMA2X2_HIGHG_HYST 1
+
+#define BMA2X2_ORIENT_THETA 0
+#define BMA2X2_FLAT_THETA 1
+
+#define BMA2X2_I2C_SELECT 0
+#define BMA2X2_I2C_EN 1
+
+#define BMA2X2_SLOW_COMP_X 0
+#define BMA2X2_SLOW_COMP_Y 1
+#define BMA2X2_SLOW_COMP_Z 2
+
+#define BMA2X2_CUT_OFF 0
+#define BMA2X2_OFFSET_TRIGGER_X 1
+#define BMA2X2_OFFSET_TRIGGER_Y 2
+#define BMA2X2_OFFSET_TRIGGER_Z 3
+
+#define BMA2X2_GP0 0
+#define BMA2X2_GP1 1
+
+#define BMA2X2_SLO_NO_MOT_EN_X 0
+#define BMA2X2_SLO_NO_MOT_EN_Y 1
+#define BMA2X2_SLO_NO_MOT_EN_Z 2
+#define BMA2X2_SLO_NO_MOT_EN_SEL 3
+
+#define BMA2X2_WAKE_UP_DUR_20MS 0
+#define BMA2X2_WAKE_UP_DUR_80MS 1
+#define BMA2X2_WAKE_UP_DUR_320MS 2
+#define BMA2X2_WAKE_UP_DUR_2560MS 3
+
+#define BMA2X2_SELF_TEST0_ON 1
+#define BMA2X2_SELF_TEST1_ON 2
+
+#define BMA2X2_EE_W_OFF 0
+#define BMA2X2_EE_W_ON 1
+
+#define BMA2X2_LOW_TH_IN_G(gthres, range) ((256 * gthres) / range)
+
+
+#define BMA2X2_HIGH_TH_IN_G(gthres, range) ((256 * gthres) / range)
+
+
+#define BMA2X2_LOW_HY_IN_G(ghyst, range) ((32 * ghyst) / range)
+
+
+#define BMA2X2_HIGH_HY_IN_G(ghyst, range) ((32 * ghyst) / range)
+
+
+#define BMA2X2_SLOPE_TH_IN_G(gthres, range) ((128 * gthres) / range)
+
+
+#define BMA2X2_GET_BITSLICE(regvar, bitname)\
+ ((regvar & bitname##__MSK) >> bitname##__POS)
+
+
+#define BMA2X2_SET_BITSLICE(regvar, bitname, val)\
+ ((regvar & ~bitname##__MSK) | ((val<<bitname##__POS)&bitname##__MSK))
+
+
+#define BMA255_CHIP_ID 0XFA
+#define BMA250E_CHIP_ID 0XF9
+#define BMA222E_CHIP_ID 0XF8
+#define BMA280_CHIP_ID 0XFB
+
+#define BMA255_TYPE 0
+#define BMA250E_TYPE 1
+#define BMA222E_TYPE 2
+#define BMA280_TYPE 3
+
+#define MAX_FIFO_F_LEVEL 32
+#define MAX_FIFO_F_BYTES 6
+#define BMA_MAX_RETRY_I2C_XFER (100)
+
+unsigned char *sensor_name[] = { "BMA255", "BMA250E", "BMA222E", "BMA280" };
+
+struct bma2x2acc{
+ s16 x,
+ y,
+ z;
+} ;
+
+struct bma2x2_data {
+ struct i2c_client *bma2x2_client;
+ atomic_t delay;
+ atomic_t enable;
+ unsigned int chip_id;
+ unsigned char mode;
+ signed char sensor_type;
+ struct input_dev *input;
+ struct bma2x2acc value;
+ struct mutex value_mutex;
+ struct mutex enable_mutex;
+ struct mutex mode_mutex;
+ struct delayed_work work;
+ struct work_struct irq_work;
+#ifdef CONFIG_HAS_EARLYSUSPEND
+ struct early_suspend early_suspend;
+#endif
+#ifdef BMA2X2_WAKEUP_BY_2TAP
+ atomic_t en_2taps_wake;
+ struct wake_lock bma_wake_lock;
+#else
+ int IRQ;
+#endif
+};
+
+#ifdef CONFIG_HAS_EARLYSUSPEND
+static void bma2x2_early_suspend(struct early_suspend *h);
+static void bma2x2_late_resume(struct early_suspend *h);
+#endif
+
+static int bma2x2_smbus_read_byte(struct i2c_client *client,
+ unsigned char reg_addr, unsigned char *data)
+{
+ s32 dummy;
+ dummy = i2c_smbus_read_byte_data(client, reg_addr);
+ if (dummy < 0)
+ return -1;
+ *data = dummy & 0x000000ff;
+
+ return 0;
+}
+
+static int bma2x2_smbus_write_byte(struct i2c_client *client,
+ unsigned char reg_addr, unsigned char *data)
+{
+ s32 dummy;
+
+ dummy = i2c_smbus_write_byte_data(client, reg_addr, *data);
+ if (dummy < 0)
+ return -1;
+ return 0;
+}
+
+static int bma2x2_smbus_read_byte_block(struct i2c_client *client,
+ unsigned char reg_addr, unsigned char *data, unsigned char len)
+{
+ s32 dummy;
+ dummy = i2c_smbus_read_i2c_block_data(client, reg_addr, len, data);
+ if (dummy < 0)
+ return -1;
+ return 0;
+}
+#ifdef BMA2X2_WAKEUP_BY_2TAP
+ static int bma2x2_set_int1_pad_sel_2tap(struct i2c_client *client,int en)
+ {
+ int comres = 0;
+ unsigned char data=0;
+ unsigned char state;
+ state = 0x01;
+
+ if(en)
+ data = BMA2X2_SET_BITSLICE(data, BMA2X2_EN_INT1_PAD_DB_TAP,
+ state);
+ comres = bma2x2_smbus_write_byte(client,
+ BMA2X2_EN_INT1_PAD_DB_TAP__REG, &data);
+
+ return comres;
+}
+#else
+#ifdef BMA2X2_ENABLE_INT1
+static int bma2x2_set_int1_pad_sel(struct i2c_client *client, unsigned char
+ int1sel)
+{
+ int comres = 0;
+ unsigned char data;
+ unsigned char state;
+ state = 0x01;
+
+
+ switch (int1sel) {
+ case 0:
+ comres = bma2x2_smbus_read_byte(client,
+ BMA2X2_EN_INT1_PAD_LOWG__REG, &data);
+ data = BMA2X2_SET_BITSLICE(data, BMA2X2_EN_INT1_PAD_LOWG,
+ state);
+ comres = bma2x2_smbus_write_byte(client,
+ BMA2X2_EN_INT1_PAD_LOWG__REG, &data);
+ break;
+ case 1:
+ comres = bma2x2_smbus_read_byte(client,
+ BMA2X2_EN_INT1_PAD_HIGHG__REG, &data);
+ data = BMA2X2_SET_BITSLICE(data, BMA2X2_EN_INT1_PAD_HIGHG,
+ state);
+ comres = bma2x2_smbus_write_byte(client,
+ BMA2X2_EN_INT1_PAD_HIGHG__REG, &data);
+ break;
+ case 2:
+ comres = bma2x2_smbus_read_byte(client,
+ BMA2X2_EN_INT1_PAD_SLOPE__REG, &data);
+ data = BMA2X2_SET_BITSLICE(data, BMA2X2_EN_INT1_PAD_SLOPE,
+ state);
+ comres = bma2x2_smbus_write_byte(client,
+ BMA2X2_EN_INT1_PAD_SLOPE__REG, &data);
+ break;
+ case 3:
+ comres = bma2x2_smbus_read_byte(client,
+ BMA2X2_EN_INT1_PAD_DB_TAP__REG, &data);
+ data = BMA2X2_SET_BITSLICE(data, BMA2X2_EN_INT1_PAD_DB_TAP,
+ state);
+ comres = bma2x2_smbus_write_byte(client,
+ BMA2X2_EN_INT1_PAD_DB_TAP__REG, &data);
+ break;
+ case 4:
+ comres = bma2x2_smbus_read_byte(client,
+ BMA2X2_EN_INT1_PAD_SNG_TAP__REG, &data);
+ data = BMA2X2_SET_BITSLICE(data, BMA2X2_EN_INT1_PAD_SNG_TAP,
+ state);
+ comres = bma2x2_smbus_write_byte(client,
+ BMA2X2_EN_INT1_PAD_SNG_TAP__REG, &data);
+ break;
+ case 5:
+ comres = bma2x2_smbus_read_byte(client,
+ BMA2X2_EN_INT1_PAD_ORIENT__REG, &data);
+ data = BMA2X2_SET_BITSLICE(data, BMA2X2_EN_INT1_PAD_ORIENT,
+ state);
+ comres = bma2x2_smbus_write_byte(client,
+ BMA2X2_EN_INT1_PAD_ORIENT__REG, &data);
+ break;
+ case 6:
+ comres = bma2x2_smbus_read_byte(client,
+ BMA2X2_EN_INT1_PAD_FLAT__REG, &data);
+ data = BMA2X2_SET_BITSLICE(data, BMA2X2_EN_INT1_PAD_FLAT,
+ state);
+ comres = bma2x2_smbus_write_byte(client,
+ BMA2X2_EN_INT1_PAD_FLAT__REG, &data);
+ break;
+ default:
+ break;
+ }
+
+ return comres;
+}
+#endif /* BMA2X2_ENABLE_INT1 */
+#endif
+#ifdef BMA2X2_ENABLE_INT2
+static int bma2x2_set_int2_pad_sel(struct i2c_client *client, unsigned char
+ int2sel)
+{
+ int comres = 0;
+ unsigned char data;
+ unsigned char state;
+ state = 0x01;
+
+
+ switch (int2sel) {
+ case 0:
+ comres = bma2x2_smbus_read_byte(client,
+ BMA2X2_EN_INT2_PAD_LOWG__REG, &data);
+ data = BMA2X2_SET_BITSLICE(data, BMA2X2_EN_INT2_PAD_LOWG,
+ state);
+ comres = bma2x2_smbus_write_byte(client,
+ BMA2X2_EN_INT2_PAD_LOWG__REG, &data);
+ break;
+ case 1:
+ comres = bma2x2_smbus_read_byte(client,
+ BMA2X2_EN_INT2_PAD_HIGHG__REG, &data);
+ data = BMA2X2_SET_BITSLICE(data, BMA2X2_EN_INT2_PAD_HIGHG,
+ state);
+ comres = bma2x2_smbus_write_byte(client,
+ BMA2X2_EN_INT2_PAD_HIGHG__REG, &data);
+ break;
+ case 2:
+ comres = bma2x2_smbus_read_byte(client,
+ BMA2X2_EN_INT2_PAD_SLOPE__REG, &data);
+ data = BMA2X2_SET_BITSLICE(data, BMA2X2_EN_INT2_PAD_SLOPE,
+ state);
+ comres = bma2x2_smbus_write_byte(client,
+ BMA2X2_EN_INT2_PAD_SLOPE__REG, &data);
+ break;
+ case 3:
+ comres = bma2x2_smbus_read_byte(client,
+ BMA2X2_EN_INT2_PAD_DB_TAP__REG, &data);
+ data = BMA2X2_SET_BITSLICE(data, BMA2X2_EN_INT2_PAD_DB_TAP,
+ state);
+ comres = bma2x2_smbus_write_byte(client,
+ BMA2X2_EN_INT2_PAD_DB_TAP__REG, &data);
+ break;
+ case 4:
+ comres = bma2x2_smbus_read_byte(client,
+ BMA2X2_EN_INT2_PAD_SNG_TAP__REG, &data);
+ data = BMA2X2_SET_BITSLICE(data, BMA2X2_EN_INT2_PAD_SNG_TAP,
+ state);
+ comres = bma2x2_smbus_write_byte(client,
+ BMA2X2_EN_INT2_PAD_SNG_TAP__REG, &data);
+ break;
+ case 5:
+ comres = bma2x2_smbus_read_byte(client,
+ BMA2X2_EN_INT2_PAD_ORIENT__REG, &data);
+ data = BMA2X2_SET_BITSLICE(data, BMA2X2_EN_INT2_PAD_ORIENT,
+ state);
+ comres = bma2x2_smbus_write_byte(client,
+ BMA2X2_EN_INT2_PAD_ORIENT__REG, &data);
+ break;
+ case 6:
+ comres = bma2x2_smbus_read_byte(client,
+ BMA2X2_EN_INT2_PAD_FLAT__REG, &data);
+ data = BMA2X2_SET_BITSLICE(data, BMA2X2_EN_INT2_PAD_FLAT,
+ state);
+ comres = bma2x2_smbus_write_byte(client,
+ BMA2X2_EN_INT2_PAD_FLAT__REG, &data);
+ break;
+ default:
+ break;
+ }
+
+ return comres;
+}
+#endif /* BMA2X2_ENABLE_INT2 */
+
+static int bma2x2_set_Int_Enable(struct i2c_client *client, unsigned char
+ InterruptType , unsigned char value)
+{
+ int comres = 0;
+ unsigned char data1, data2;
+
+
+ comres = bma2x2_smbus_read_byte(client, BMA2X2_INT_ENABLE1_REG, &data1);
+ comres = bma2x2_smbus_read_byte(client, BMA2X2_INT_ENABLE2_REG, &data2);
+
+ value = value & 1;
+ switch (InterruptType) {
+ case 0:
+ /* Low G Interrupt */
+ data2 = BMA2X2_SET_BITSLICE(data2, BMA2X2_EN_LOWG_INT, value);
+ break;
+ case 1:
+ /* High G X Interrupt */
+
+ data2 = BMA2X2_SET_BITSLICE(data2, BMA2X2_EN_HIGHG_X_INT,
+ value);
+ break;
+ case 2:
+ /* High G Y Interrupt */
+
+ data2 = BMA2X2_SET_BITSLICE(data2, BMA2X2_EN_HIGHG_Y_INT,
+ value);
+ break;
+ case 3:
+ /* High G Z Interrupt */
+
+ data2 = BMA2X2_SET_BITSLICE(data2, BMA2X2_EN_HIGHG_Z_INT,
+ value);
+ break;
+ case 4:
+ /* New Data Interrupt */
+
+ data2 = BMA2X2_SET_BITSLICE(data2, BMA2X2_EN_NEW_DATA_INT,
+ value);
+ break;
+ case 5:
+ /* Slope X Interrupt */
+
+ data1 = BMA2X2_SET_BITSLICE(data1, BMA2X2_EN_SLOPE_X_INT,
+ value);
+ break;
+ case 6:
+ /* Slope Y Interrupt */
+
+ data1 = BMA2X2_SET_BITSLICE(data1, BMA2X2_EN_SLOPE_Y_INT,
+ value);
+ break;
+ case 7:
+ /* Slope Z Interrupt */
+
+ data1 = BMA2X2_SET_BITSLICE(data1, BMA2X2_EN_SLOPE_Z_INT,
+ value);
+ break;
+ case 8:
+ /* Single Tap Interrupt */
+
+ data1 = BMA2X2_SET_BITSLICE(data1, BMA2X2_EN_SINGLE_TAP_INT,
+ value);
+ break;
+ case 9:
+ /* Double Tap Interrupt */
+
+ data1 = BMA2X2_SET_BITSLICE(data1, BMA2X2_EN_DOUBLE_TAP_INT,
+ value);
+ break;
+ case 10:
+ /* Orient Interrupt */
+
+ data1 = BMA2X2_SET_BITSLICE(data1, BMA2X2_EN_ORIENT_INT, value);
+ break;
+ case 11:
+ /* Flat Interrupt */
+
+ data1 = BMA2X2_SET_BITSLICE(data1, BMA2X2_EN_FLAT_INT, value);
+ break;
+ default:
+ break;
+ }
+ comres = bma2x2_smbus_write_byte(client, BMA2X2_INT_ENABLE1_REG,
+ &data1);
+ comres = bma2x2_smbus_write_byte(client, BMA2X2_INT_ENABLE2_REG,
+ &data2);
+
+ return comres;
+}
+
+
+#if defined(BMA2X2_ENABLE_INT1) || defined(BMA2X2_ENABLE_INT2)
+#ifndef BMA2X2_WAKEUP_BY_2TAP
+static int bma2x2_get_interruptstatus1(struct i2c_client *client, unsigned char
+ *intstatus)
+{
+ int comres = 0;
+ unsigned char data;
+
+ comres = bma2x2_smbus_read_byte(client, BMA2X2_STATUS1_REG, &data);
+ *intstatus = data;
+
+ return comres;
+}
+
+static int bma2x2_get_HIGH_first(struct i2c_client *client, unsigned char
+ param, unsigned char *intstatus)
+{
+ int comres = 0;
+ unsigned char data;
+
+ switch (param) {
+ case 0:
+ comres = bma2x2_smbus_read_byte(client,
+ BMA2X2_STATUS_ORIENT_HIGH_REG, &data);
+ data = BMA2X2_GET_BITSLICE(data, BMA2X2_HIGHG_FIRST_X);
+ *intstatus = data;
+ break;
+ case 1:
+ comres = bma2x2_smbus_read_byte(client,
+ BMA2X2_STATUS_ORIENT_HIGH_REG, &data);
+ data = BMA2X2_GET_BITSLICE(data, BMA2X2_HIGHG_FIRST_Y);
+ *intstatus = data;
+ break;
+ case 2:
+ comres = bma2x2_smbus_read_byte(client,
+ BMA2X2_STATUS_ORIENT_HIGH_REG, &data);
+ data = BMA2X2_GET_BITSLICE(data, BMA2X2_HIGHG_FIRST_Z);
+ *intstatus = data;
+ break;
+ default:
+ break;
+ }
+
+ return comres;
+}
+
+
+static int bma2x2_get_HIGH_sign(struct i2c_client *client, unsigned char
+ *intstatus)
+{
+ int comres = 0;
+ unsigned char data;
+
+ comres = bma2x2_smbus_read_byte(client, BMA2X2_STATUS_ORIENT_HIGH_REG,
+ &data);
+ data = BMA2X2_GET_BITSLICE(data, BMA2X2_HIGHG_SIGN_S);
+ *intstatus = data;
+
+ return comres;
+}
+
+
+static int bma2x2_get_slope_first(struct i2c_client *client, unsigned char
+ param, unsigned char *intstatus)
+{
+ int comres = 0;
+ unsigned char data;
+
+ switch (param) {
+ case 0:
+ comres = bma2x2_smbus_read_byte(client,
+ BMA2X2_STATUS_TAP_SLOPE_REG, &data);
+ data = BMA2X2_GET_BITSLICE(data, BMA2X2_SLOPE_FIRST_X);
+ *intstatus = data;
+ break;
+ case 1:
+ comres = bma2x2_smbus_read_byte(client,
+ BMA2X2_STATUS_TAP_SLOPE_REG, &data);
+ data = BMA2X2_GET_BITSLICE(data, BMA2X2_SLOPE_FIRST_Y);
+ *intstatus = data;
+ break;
+ case 2:
+ comres = bma2x2_smbus_read_byte(client,
+ BMA2X2_STATUS_TAP_SLOPE_REG, &data);
+ data = BMA2X2_GET_BITSLICE(data, BMA2X2_SLOPE_FIRST_Z);
+ *intstatus = data;
+ break;
+ default:
+ break;
+ }
+
+ return comres;
+}
+
+static int bma2x2_get_slope_sign(struct i2c_client *client, unsigned char
+ *intstatus)
+{
+ int comres = 0;
+ unsigned char data;
+
+ comres = bma2x2_smbus_read_byte(client, BMA2X2_STATUS_TAP_SLOPE_REG,
+ &data);
+ data = BMA2X2_GET_BITSLICE(data, BMA2X2_SLOPE_SIGN_S);
+ *intstatus = data;
+
+ return comres;
+}
+
+static int bma2x2_get_orient_status(struct i2c_client *client, unsigned char
+ *intstatus)
+{
+ int comres = 0;
+ unsigned char data;
+
+ comres = bma2x2_smbus_read_byte(client, BMA2X2_STATUS_ORIENT_HIGH_REG,
+ &data);
+ data = BMA2X2_GET_BITSLICE(data, BMA2X2_ORIENT_S);
+ *intstatus = data;
+
+ return comres;
+}
+
+static int bma2x2_get_orient_flat_status(struct i2c_client *client, unsigned
+ char *intstatus)
+{
+ int comres = 0;
+ unsigned char data;
+
+ comres = bma2x2_smbus_read_byte(client, BMA2X2_STATUS_ORIENT_HIGH_REG,
+ &data);
+ data = BMA2X2_GET_BITSLICE(data, BMA2X2_FLAT_S);
+ *intstatus = data;
+
+ return comres;
+}
+#endif
+#endif /* defined(BMA2X2_ENABLE_INT1)||defined(BMA2X2_ENABLE_INT2) */
+static int bma2x2_set_Int_Mode(struct i2c_client *client, unsigned char Mode)
+{
+ int comres = 0;
+ unsigned char data;
+
+
+ comres = bma2x2_smbus_read_byte(client,
+ BMA2X2_INT_MODE_SEL__REG, &data);
+ data = BMA2X2_SET_BITSLICE(data, BMA2X2_INT_MODE_SEL, Mode);
+ comres = bma2x2_smbus_write_byte(client,
+ BMA2X2_INT_MODE_SEL__REG, &data);
+
+
+ return comres;
+}
+
+static int bma2x2_set_tap_duration(struct i2c_client *client, unsigned char
+ duration)
+{
+ int comres = 0;
+ unsigned char data;
+
+ comres = bma2x2_smbus_read_byte(client, BMA2X2_TAP_DUR__REG, &data);
+ data = BMA2X2_SET_BITSLICE(data, BMA2X2_TAP_DUR, duration);
+ comres = bma2x2_smbus_write_byte(client, BMA2X2_TAP_DUR__REG, &data);
+
+ return comres;
+}
+
+static int bma2x2_get_tap_duration(struct i2c_client *client, unsigned char
+ *status)
+{
+ int comres = 0;
+ unsigned char data;
+
+ comres = bma2x2_smbus_read_byte(client, BMA2X2_TAP_PARAM_REG, &data);
+ data = BMA2X2_GET_BITSLICE(data, BMA2X2_TAP_DUR);
+ *status = data;
+
+ return comres;
+}
+
+static int bma2x2_set_tap_shock(struct i2c_client *client, unsigned char setval)
+{
+ int comres = 0;
+ unsigned char data;
+
+ comres = bma2x2_smbus_read_byte(client, BMA2X2_TAP_SHOCK_DURN__REG,
+ &data);
+ data = BMA2X2_SET_BITSLICE(data, BMA2X2_TAP_SHOCK_DURN, setval);
+ comres = bma2x2_smbus_write_byte(client, BMA2X2_TAP_SHOCK_DURN__REG,
+ &data);
+
+ return comres;
+}
+
+static int bma2x2_get_tap_shock(struct i2c_client *client, unsigned char
+ *status)
+{
+ int comres = 0;
+ unsigned char data;
+
+ comres = bma2x2_smbus_read_byte(client, BMA2X2_TAP_PARAM_REG, &data);
+ data = BMA2X2_GET_BITSLICE(data, BMA2X2_TAP_SHOCK_DURN);
+ *status = data;
+
+ return comres;
+}
+
+static int bma2x2_set_tap_quiet(struct i2c_client *client, unsigned char
+ duration)
+{
+ int comres = 0;
+ unsigned char data;
+
+ comres = bma2x2_smbus_read_byte(client, BMA2X2_TAP_QUIET_DURN__REG,
+ &data);
+ data = BMA2X2_SET_BITSLICE(data, BMA2X2_TAP_QUIET_DURN, duration);
+ comres = bma2x2_smbus_write_byte(client, BMA2X2_TAP_QUIET_DURN__REG,
+ &data);
+
+ return comres;
+}
+
+static int bma2x2_get_tap_quiet(struct i2c_client *client, unsigned char
+ *status)
+{
+ int comres = 0;
+ unsigned char data;
+
+ comres = bma2x2_smbus_read_byte(client, BMA2X2_TAP_PARAM_REG, &data);
+ data = BMA2X2_GET_BITSLICE(data, BMA2X2_TAP_QUIET_DURN);
+ *status = data;
+
+ return comres;
+}
+
+static int bma2x2_set_tap_threshold(struct i2c_client *client, unsigned char
+ threshold)
+{
+ int comres = 0;
+ unsigned char data;
+
+ comres = bma2x2_smbus_read_byte(client, BMA2X2_TAP_THRES__REG, &data);
+ data = BMA2X2_SET_BITSLICE(data, BMA2X2_TAP_THRES, threshold);
+ comres = bma2x2_smbus_write_byte(client, BMA2X2_TAP_THRES__REG, &data);
+
+ return comres;
+}
+
+static int bma2x2_get_tap_threshold(struct i2c_client *client, unsigned char
+ *status)
+{
+ int comres = 0;
+ unsigned char data;
+
+ comres = bma2x2_smbus_read_byte(client, BMA2X2_TAP_THRES_REG, &data);
+ data = BMA2X2_GET_BITSLICE(data, BMA2X2_TAP_THRES);
+ *status = data;
+
+ return comres;
+}
+
+static int bma2x2_set_tap_samp(struct i2c_client *client, unsigned char samp)
+{
+ int comres = 0;
+ unsigned char data;
+
+ comres = bma2x2_smbus_read_byte(client, BMA2X2_TAP_SAMPLES__REG, &data);
+ data = BMA2X2_SET_BITSLICE(data, BMA2X2_TAP_SAMPLES, samp);
+ comres = bma2x2_smbus_write_byte(client, BMA2X2_TAP_SAMPLES__REG,
+ &data);
+
+ return comres;
+}
+
+static int bma2x2_get_tap_samp(struct i2c_client *client, unsigned char *status)
+{
+ int comres = 0;
+ unsigned char data;
+
+ comres = bma2x2_smbus_read_byte(client, BMA2X2_TAP_THRES_REG, &data);
+ data = BMA2X2_GET_BITSLICE(data, BMA2X2_TAP_SAMPLES);
+ *status = data;
+
+ return comres;
+}
+
+static int bma2x2_set_mode(struct i2c_client *client, unsigned char Mode)
+{
+ int comres = 0;
+ unsigned char data1, data2;
+
+ if (Mode < 6) {
+ comres = bma2x2_smbus_read_byte(client, BMA2X2_MODE_CTRL_REG,
+ &data1);
+ comres = bma2x2_smbus_read_byte(client,
+ BMA2X2_LOW_NOISE_CTRL_REG,
+ &data2);
+ switch (Mode) {
+ case BMA2X2_MODE_NORMAL:
+ data1 = BMA2X2_SET_BITSLICE(data1,
+ BMA2X2_MODE_CTRL, 0);
+ data2 = BMA2X2_SET_BITSLICE(data2,
+ BMA2X2_LOW_POWER_MODE, 0);
+ bma2x2_smbus_write_byte(client,
+ BMA2X2_MODE_CTRL_REG, &data1);
+ mdelay(1);
+ bma2x2_smbus_write_byte(client,
+ BMA2X2_LOW_NOISE_CTRL_REG, &data2);
+ break;
+ case BMA2X2_MODE_LOWPOWER1:
+ data1 = BMA2X2_SET_BITSLICE(data1,
+ BMA2X2_MODE_CTRL, 2);
+ data2 = BMA2X2_SET_BITSLICE(data2,
+ BMA2X2_LOW_POWER_MODE, 0);
+ bma2x2_smbus_write_byte(client,
+ BMA2X2_MODE_CTRL_REG, &data1);
+ mdelay(1);
+ bma2x2_smbus_write_byte(client,
+ BMA2X2_LOW_NOISE_CTRL_REG, &data2);
+ break;
+ case BMA2X2_MODE_SUSPEND:
+ data1 = BMA2X2_SET_BITSLICE(data1,
+ BMA2X2_MODE_CTRL, 4);
+ data2 = BMA2X2_SET_BITSLICE(data2,
+ BMA2X2_LOW_POWER_MODE, 0);
+ bma2x2_smbus_write_byte(client,
+ BMA2X2_LOW_NOISE_CTRL_REG, &data2);
+ mdelay(1);
+ bma2x2_smbus_write_byte(client,
+ BMA2X2_MODE_CTRL_REG, &data1);
+ break;
+ case BMA2X2_MODE_DEEP_SUSPEND:
+ data1 = BMA2X2_SET_BITSLICE(data1,
+ BMA2X2_MODE_CTRL, 1);
+ data2 = BMA2X2_SET_BITSLICE(data2,
+ BMA2X2_LOW_POWER_MODE, 1);
+ bma2x2_smbus_write_byte(client,
+ BMA2X2_MODE_CTRL_REG, &data1);
+ mdelay(1);
+ bma2x2_smbus_write_byte(client,
+ BMA2X2_LOW_NOISE_CTRL_REG, &data2);
+ break;
+ case BMA2X2_MODE_LOWPOWER2:
+ data1 = BMA2X2_SET_BITSLICE(data1,
+ BMA2X2_MODE_CTRL, 2);
+ data2 = BMA2X2_SET_BITSLICE(data2,
+ BMA2X2_LOW_POWER_MODE, 1);
+ bma2x2_smbus_write_byte(client,
+ BMA2X2_MODE_CTRL_REG, &data1);
+ mdelay(1);
+ bma2x2_smbus_write_byte(client,
+ BMA2X2_LOW_NOISE_CTRL_REG, &data2);
+ break;
+ case BMA2X2_MODE_STANDBY:
+ data1 = BMA2X2_SET_BITSLICE(data1,
+ BMA2X2_MODE_CTRL, 4);
+ data2 = BMA2X2_SET_BITSLICE(data2,
+ BMA2X2_LOW_POWER_MODE, 1);
+ bma2x2_smbus_write_byte(client,
+ BMA2X2_LOW_NOISE_CTRL_REG, &data2);
+ mdelay(1);
+ bma2x2_smbus_write_byte(client,
+ BMA2X2_MODE_CTRL_REG, &data1);
+ break;
+ }
+ } else {
+ comres = -1 ;
+ }
+
+
+ return comres;
+}
+
+
+static int bma2x2_get_mode(struct i2c_client *client, unsigned char *Mode)
+{
+ int comres = 0;
+ unsigned char data1, data2;
+
+ comres = bma2x2_smbus_read_byte(client, BMA2X2_MODE_CTRL_REG, &data1);
+ comres = bma2x2_smbus_read_byte(client, BMA2X2_LOW_NOISE_CTRL_REG,
+ &data2);
+
+ data1 = (data1 & 0xE0) >> 5;
+ data2 = (data2 & 0x40) >> 6;
+
+
+ if ((data1 == 0x00) && (data2 == 0x00)) {
+ *Mode = BMA2X2_MODE_NORMAL;
+ } else {
+ if ((data1 == 0x02) && (data2 == 0x00)) {
+ *Mode = BMA2X2_MODE_LOWPOWER1;
+ } else {
+ if ((data1 == 0x04 || data1 == 0x06) &&
+ (data2 == 0x00)) {
+ *Mode = BMA2X2_MODE_SUSPEND;
+ } else {
+ if (((data1 & 0x01) == 0x01)) {
+ *Mode = BMA2X2_MODE_DEEP_SUSPEND;
+ } else {
+ if ((data1 == 0x02) &&
+ (data2 == 0x01)) {
+ *Mode = BMA2X2_MODE_LOWPOWER2;
+ } else {
+ if ((data1 == 0x04) && (data2 ==
+ 0x01)) {
+ *Mode =
+ BMA2X2_MODE_STANDBY;
+ } else {
+ *Mode =
+ BMA2X2_MODE_DEEP_SUSPEND;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return comres;
+}
+
+static int bma2x2_set_range(struct i2c_client *client, unsigned char Range)
+{
+ int comres = 0 ;
+ unsigned char data1;
+
+ if ((Range == 3) || (Range == 5) || (Range == 8) || (Range == 12)) {
+ comres = bma2x2_smbus_read_byte(client, BMA2X2_RANGE_SEL_REG,
+ &data1);
+ switch (Range) {
+ case BMA2X2_RANGE_2G:
+ data1 = BMA2X2_SET_BITSLICE(data1,
+ BMA2X2_RANGE_SEL, 3);
+ break;
+ case BMA2X2_RANGE_4G:
+ data1 = BMA2X2_SET_BITSLICE(data1,
+ BMA2X2_RANGE_SEL, 5);
+ break;
+ case BMA2X2_RANGE_8G:
+ data1 = BMA2X2_SET_BITSLICE(data1,
+ BMA2X2_RANGE_SEL, 8);
+ break;
+ case BMA2X2_RANGE_16G:
+ data1 = BMA2X2_SET_BITSLICE(data1,
+ BMA2X2_RANGE_SEL, 12);
+ break;
+ default:
+ break;
+ }
+ comres += bma2x2_smbus_write_byte(client, BMA2X2_RANGE_SEL_REG,
+ &data1);
+ } else {
+ comres = -1 ;
+ }
+
+ return comres;
+}
+
+static int bma2x2_get_range(struct i2c_client *client, unsigned char *Range)
+{
+ int comres = 0;
+ unsigned char data;
+
+ comres = bma2x2_smbus_read_byte(client, BMA2X2_RANGE_SEL__REG, &data);
+ data = BMA2X2_GET_BITSLICE(data, BMA2X2_RANGE_SEL);
+ *Range = data;
+
+ return comres;
+}
+
+
+static int bma2x2_set_bandwidth(struct i2c_client *client, unsigned char BW)
+{
+ int comres = 0;
+ unsigned char data;
+ int Bandwidth = 0;
+
+ if (BW > 7 && BW < 16) {
+ switch (BW) {
+ case BMA2X2_BW_7_81HZ:
+ Bandwidth = BMA2X2_BW_7_81HZ;
+
+ /* 7.81 Hz 64000 uS */
+ break;
+ case BMA2X2_BW_15_63HZ:
+ Bandwidth = BMA2X2_BW_15_63HZ;
+
+ /* 15.63 Hz 32000 uS */
+ break;
+ case BMA2X2_BW_31_25HZ:
+ Bandwidth = BMA2X2_BW_31_25HZ;
+
+ /* 31.25 Hz 16000 uS */
+ break;
+ case BMA2X2_BW_62_50HZ:
+ Bandwidth = BMA2X2_BW_62_50HZ;
+
+ /* 62.50 Hz 8000 uS */
+ break;
+ case BMA2X2_BW_125HZ:
+ Bandwidth = BMA2X2_BW_125HZ;
+
+ /* 125 Hz 4000 uS */
+ break;
+ case BMA2X2_BW_250HZ:
+ Bandwidth = BMA2X2_BW_250HZ;
+
+ /* 250 Hz 2000 uS */
+ break;
+ case BMA2X2_BW_500HZ:
+ Bandwidth = BMA2X2_BW_500HZ;
+
+ /* 500 Hz 1000 uS */
+ break;
+ case BMA2X2_BW_1000HZ:
+ Bandwidth = BMA2X2_BW_1000HZ;
+
+ /* 1000 Hz 500 uS */
+ break;
+ default:
+ break;
+ }
+ comres = bma2x2_smbus_read_byte(client, BMA2X2_BANDWIDTH__REG,
+ &data);
+ data = BMA2X2_SET_BITSLICE(data, BMA2X2_BANDWIDTH, Bandwidth);
+ comres += bma2x2_smbus_write_byte(client, BMA2X2_BANDWIDTH__REG,
+ &data);
+ } else {
+ comres = -1 ;
+ }
+
+ return comres;
+}
+
+static int bma2x2_get_bandwidth(struct i2c_client *client, unsigned char *BW)
+{
+ int comres = 0;
+ unsigned char data;
+
+ comres = bma2x2_smbus_read_byte(client, BMA2X2_BANDWIDTH__REG, &data);
+ data = BMA2X2_GET_BITSLICE(data, BMA2X2_BANDWIDTH);
+ *BW = data ;
+
+ return comres;
+}
+
+static int bma2x2_write_reg(struct i2c_client *client, unsigned char addr,
+ unsigned char *data)
+{
+ int comres = 0 ;
+ comres = bma2x2_smbus_write_byte(client, addr, data);
+
+ return comres;
+}
+
+static ssize_t bma2x2_tap_threshold_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ unsigned char data;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct bma2x2_data *bma2x2 = i2c_get_clientdata(client);
+
+ if (bma2x2_get_tap_threshold(bma2x2->bma2x2_client, &data) < 0)
+ return sprintf(buf, "Read error\n");
+
+ return sprintf(buf, "%d\n", data);
+
+}
+
+static ssize_t bma2x2_tap_threshold_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long data;
+ int error;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct bma2x2_data *bma2x2 = i2c_get_clientdata(client);
+
+ error = strict_strtoul(buf, 10, &data);
+ if (error)
+ return error;
+ if (bma2x2_set_tap_threshold(bma2x2->bma2x2_client, (unsigned char)data)
+ < 0)
+ return -EINVAL;
+
+ return count;
+}
+static ssize_t bma2x2_tap_duration_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ unsigned char data;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct bma2x2_data *bma2x2 = i2c_get_clientdata(client);
+
+ if (bma2x2_get_tap_duration(bma2x2->bma2x2_client, &data) < 0)
+ return sprintf(buf, "Read error\n");
+
+ return sprintf(buf, "%d\n", data);
+
+}
+
+static ssize_t bma2x2_tap_duration_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long data;
+ int error;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct bma2x2_data *bma2x2 = i2c_get_clientdata(client);
+
+ error = strict_strtoul(buf, 10, &data);
+ if (error)
+ return error;
+
+ if (bma2x2_set_tap_duration(bma2x2->bma2x2_client, (unsigned char)data)
+ < 0)
+ return -EINVAL;
+
+ return count;
+}
+static ssize_t bma2x2_tap_quiet_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ unsigned char data;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct bma2x2_data *bma2x2 = i2c_get_clientdata(client);
+
+ if (bma2x2_get_tap_quiet(bma2x2->bma2x2_client, &data) < 0)
+ return sprintf(buf, "Read error\n");
+
+ return sprintf(buf, "%d\n", data);
+
+}
+
+static ssize_t bma2x2_tap_quiet_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long data;
+ int error;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct bma2x2_data *bma2x2 = i2c_get_clientdata(client);
+
+ error = strict_strtoul(buf, 10, &data);
+ if (error)
+ return error;
+
+ if (bma2x2_set_tap_quiet(bma2x2->bma2x2_client, (unsigned char)data) <
+ 0)
+ return -EINVAL;
+
+ return count;
+}
+
+static ssize_t bma2x2_tap_shock_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ unsigned char data;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct bma2x2_data *bma2x2 = i2c_get_clientdata(client);
+
+ if (bma2x2_get_tap_shock(bma2x2->bma2x2_client, &data) < 0)
+ return sprintf(buf, "Read error\n");
+
+ return sprintf(buf, "%d\n", data);
+
+}
+
+static ssize_t bma2x2_tap_shock_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long data;
+ int error;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct bma2x2_data *bma2x2 = i2c_get_clientdata(client);
+
+ error = strict_strtoul(buf, 10, &data);
+ if (error)
+ return error;
+
+ if (bma2x2_set_tap_shock(bma2x2->bma2x2_client, (unsigned char)data) <
+ 0)
+ return -EINVAL;
+
+ return count;
+}
+
+static ssize_t bma2x2_tap_samp_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ unsigned char data;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct bma2x2_data *bma2x2 = i2c_get_clientdata(client);
+
+ if (bma2x2_get_tap_samp(bma2x2->bma2x2_client, &data) < 0)
+ return sprintf(buf, "Read error\n");
+
+ return sprintf(buf, "%d\n", data);
+
+}
+
+static ssize_t bma2x2_tap_samp_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long data;
+ int error;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct bma2x2_data *bma2x2 = i2c_get_clientdata(client);
+
+ error = strict_strtoul(buf, 10, &data);
+ if (error)
+ return error;
+
+ if (bma2x2_set_tap_samp(bma2x2->bma2x2_client, (unsigned char)data) < 0)
+ return -EINVAL;
+
+ return count;
+}
+
+static int bma2x2_read_accel_xyz(struct i2c_client *client,
+ signed char sensor_type, struct bma2x2acc *acc)
+{
+ int comres = 0;
+ unsigned char data[6];
+#ifdef SENSOR_IDENTIFICATION_ENABLE
+ comres = bma2x2_smbus_read_byte_block(client,
+ BMA2X2_ACC_X12_LSB__REG, data, 6);
+ acc->x = (data[1]<<8)|data[0];
+ acc->y = (data[3]<<8)|data[2];
+ acc->z = (data[5]<<8)|data[4];
+
+#else
+ switch (sensor_type) {
+ case 0:
+ comres = bma2x2_smbus_read_byte_block(client,
+ BMA2X2_ACC_X12_LSB__REG, data, 6);
+ acc->x = BMA2X2_GET_BITSLICE(data[0], BMA2X2_ACC_X12_LSB)|
+ (BMA2X2_GET_BITSLICE(data[1],
+ BMA2X2_ACC_X_MSB)<<(BMA2X2_ACC_X12_LSB__LEN));
+ acc->x = acc->x << (sizeof(short)*8-(BMA2X2_ACC_X12_LSB__LEN +
+ BMA2X2_ACC_X_MSB__LEN));
+ acc->x = acc->x >> (sizeof(short)*8-(BMA2X2_ACC_X12_LSB__LEN +
+ BMA2X2_ACC_X_MSB__LEN));
+
+ acc->y = BMA2X2_GET_BITSLICE(data[2], BMA2X2_ACC_Y12_LSB)|
+ (BMA2X2_GET_BITSLICE(data[3],
+ BMA2X2_ACC_Y_MSB)<<(BMA2X2_ACC_Y12_LSB__LEN
+ ));
+ acc->y = acc->y << (sizeof(short)*8-(BMA2X2_ACC_Y12_LSB__LEN +
+ BMA2X2_ACC_Y_MSB__LEN));
+ acc->y = acc->y >> (sizeof(short)*8-(BMA2X2_ACC_Y12_LSB__LEN +
+ BMA2X2_ACC_Y_MSB__LEN));
+
+ acc->z = BMA2X2_GET_BITSLICE(data[4], BMA2X2_ACC_Z12_LSB)|
+ (BMA2X2_GET_BITSLICE(data[5],
+ BMA2X2_ACC_Z_MSB)<<(BMA2X2_ACC_Z12_LSB__LEN));
+ acc->z = acc->z << (sizeof(short)*8-(BMA2X2_ACC_Z12_LSB__LEN +
+ BMA2X2_ACC_Z_MSB__LEN));
+ acc->z = acc->z >> (sizeof(short)*8-(BMA2X2_ACC_Z12_LSB__LEN +
+ BMA2X2_ACC_Z_MSB__LEN));
+ break;
+ case 1:
+ comres = bma2x2_smbus_read_byte_block(client,
+ BMA2X2_ACC_X10_LSB__REG, data, 6);
+ acc->x = BMA2X2_GET_BITSLICE(data[0], BMA2X2_ACC_X10_LSB)|
+ (BMA2X2_GET_BITSLICE(data[1],
+ BMA2X2_ACC_X_MSB)<<(BMA2X2_ACC_X10_LSB__LEN));
+ acc->x = acc->x << (sizeof(short)*8-(BMA2X2_ACC_X10_LSB__LEN +
+ BMA2X2_ACC_X_MSB__LEN));
+ acc->x = acc->x >> (sizeof(short)*8-(BMA2X2_ACC_X10_LSB__LEN +
+ BMA2X2_ACC_X_MSB__LEN));
+
+ acc->y = BMA2X2_GET_BITSLICE(data[2], BMA2X2_ACC_Y10_LSB)|
+ (BMA2X2_GET_BITSLICE(data[3],
+ BMA2X2_ACC_Y_MSB)<<(BMA2X2_ACC_Y10_LSB__LEN
+ ));
+ acc->y = acc->y << (sizeof(short)*8-(BMA2X2_ACC_Y10_LSB__LEN +
+ BMA2X2_ACC_Y_MSB__LEN));
+ acc->y = acc->y >> (sizeof(short)*8-(BMA2X2_ACC_Y10_LSB__LEN +
+ BMA2X2_ACC_Y_MSB__LEN));
+
+ acc->z = BMA2X2_GET_BITSLICE(data[4], BMA2X2_ACC_Z10_LSB)|
+ (BMA2X2_GET_BITSLICE(data[5],
+ BMA2X2_ACC_Z_MSB)<<(BMA2X2_ACC_Z10_LSB__LEN));
+ acc->z = acc->z << (sizeof(short)*8-(BMA2X2_ACC_Z10_LSB__LEN +
+ BMA2X2_ACC_Z_MSB__LEN));
+ acc->z = acc->z >> (sizeof(short)*8-(BMA2X2_ACC_Z10_LSB__LEN +
+ BMA2X2_ACC_Z_MSB__LEN));
+ break;
+ case 2:
+ comres = bma2x2_smbus_read_byte_block(client,
+ BMA2X2_ACC_X8_LSB__REG, data, 6);
+ acc->x = BMA2X2_GET_BITSLICE(data[0], BMA2X2_ACC_X8_LSB)|
+ (BMA2X2_GET_BITSLICE(data[1],
+ BMA2X2_ACC_X_MSB)<<(BMA2X2_ACC_X8_LSB__LEN));
+ acc->x = acc->x << (sizeof(short)*8-(BMA2X2_ACC_X8_LSB__LEN +
+ BMA2X2_ACC_X_MSB__LEN));
+ acc->x = acc->x >> (sizeof(short)*8-(BMA2X2_ACC_X8_LSB__LEN +
+ BMA2X2_ACC_X_MSB__LEN));
+
+ acc->y = BMA2X2_GET_BITSLICE(data[2], BMA2X2_ACC_Y8_LSB)|
+ (BMA2X2_GET_BITSLICE(data[3],
+ BMA2X2_ACC_Y_MSB)<<(BMA2X2_ACC_Y8_LSB__LEN
+ ));
+ acc->y = acc->y << (sizeof(short)*8-(BMA2X2_ACC_Y8_LSB__LEN +
+ BMA2X2_ACC_Y_MSB__LEN));
+ acc->y = acc->y >> (sizeof(short)*8-(BMA2X2_ACC_Y8_LSB__LEN +
+ BMA2X2_ACC_Y_MSB__LEN));
+
+ acc->z = BMA2X2_GET_BITSLICE(data[4], BMA2X2_ACC_Z8_LSB)|
+ (BMA2X2_GET_BITSLICE(data[5],
+ BMA2X2_ACC_Z_MSB)<<(BMA2X2_ACC_Z8_LSB__LEN));
+ acc->z = acc->z << (sizeof(short)*8-(BMA2X2_ACC_Z8_LSB__LEN +
+ BMA2X2_ACC_Z_MSB__LEN));
+ acc->z = acc->z >> (sizeof(short)*8-(BMA2X2_ACC_Z8_LSB__LEN +
+ BMA2X2_ACC_Z_MSB__LEN));
+ break;
+ case 3:
+ comres = bma2x2_smbus_read_byte_block(client,
+ BMA2X2_ACC_X14_LSB__REG, data, 6);
+ acc->x = BMA2X2_GET_BITSLICE(data[0], BMA2X2_ACC_X14_LSB)|
+ (BMA2X2_GET_BITSLICE(data[1],
+ BMA2X2_ACC_X_MSB)<<(BMA2X2_ACC_X14_LSB__LEN));
+ acc->x = acc->x << (sizeof(short)*8-(BMA2X2_ACC_X14_LSB__LEN +
+ BMA2X2_ACC_X_MSB__LEN));
+ acc->x = acc->x >> (sizeof(short)*8-(BMA2X2_ACC_X14_LSB__LEN +
+ BMA2X2_ACC_X_MSB__LEN));
+
+ acc->y = BMA2X2_GET_BITSLICE(data[2], BMA2X2_ACC_Y14_LSB)|
+ (BMA2X2_GET_BITSLICE(data[3],
+ BMA2X2_ACC_Y_MSB)<<(BMA2X2_ACC_Y14_LSB__LEN
+ ));
+ acc->y = acc->y << (sizeof(short)*8-(BMA2X2_ACC_Y14_LSB__LEN +
+ BMA2X2_ACC_Y_MSB__LEN));
+ acc->y = acc->y >> (sizeof(short)*8-(BMA2X2_ACC_Y14_LSB__LEN +
+ BMA2X2_ACC_Y_MSB__LEN));
+
+ acc->z = BMA2X2_GET_BITSLICE(data[4], BMA2X2_ACC_Z14_LSB)|
+ (BMA2X2_GET_BITSLICE(data[5],
+ BMA2X2_ACC_Z_MSB)<<(BMA2X2_ACC_Z14_LSB__LEN));
+ acc->z = acc->z << (sizeof(short)*8-(BMA2X2_ACC_Z14_LSB__LEN +
+ BMA2X2_ACC_Z_MSB__LEN));
+ acc->z = acc->z >> (sizeof(short)*8-(BMA2X2_ACC_Z14_LSB__LEN +
+ BMA2X2_ACC_Z_MSB__LEN));
+ break;
+ default:
+ break;
+ }
+#endif
+ return comres;
+}
+
+static void bma2x2_work_func(struct work_struct *work)
+{
+ struct bma2x2_data *bma2x2 = container_of((struct delayed_work *)work,
+ struct bma2x2_data, work);
+ static struct bma2x2acc acc;
+ unsigned long delay = msecs_to_jiffies(atomic_read(&bma2x2->delay));
+
+ bma2x2_read_accel_xyz(bma2x2->bma2x2_client, bma2x2->sensor_type,
+ &acc);
+ input_report_abs(bma2x2->input, ABS_X, acc.x);
+ input_report_abs(bma2x2->input, ABS_Y, acc.y);
+ input_report_abs(bma2x2->input, ABS_Z, acc.z);
+ input_sync(bma2x2->input);
+
+ schedule_delayed_work(&bma2x2->work, delay);
+}
+
+
+static ssize_t bma2x2_register_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int address, value;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct bma2x2_data *bma2x2 = i2c_get_clientdata(client);
+
+ sscanf(buf, "%d%d", &address, &value);
+ if (bma2x2_write_reg(bma2x2->bma2x2_client, (unsigned char)address,
+ (unsigned char *)&value) < 0)
+ return -EINVAL;
+ return count;
+}
+static ssize_t bma2x2_register_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+
+ struct i2c_client *client = to_i2c_client(dev);
+ struct bma2x2_data *bma2x2 = i2c_get_clientdata(client);
+
+ size_t count = 0;
+ u8 reg[0x40];
+ int i;
+
+ for (i = 0; i < 0x40; i++) {
+ bma2x2_smbus_read_byte(bma2x2->bma2x2_client, i, reg+i);
+
+ count += sprintf(&buf[count], "0x%x: %d\n", i, reg[i]);
+ }
+ return count;
+
+
+}
+
+static ssize_t bma2x2_range_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ unsigned char data;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct bma2x2_data *bma2x2 = i2c_get_clientdata(client);
+
+ if (bma2x2_get_range(bma2x2->bma2x2_client, &data) < 0)
+ return sprintf(buf, "Read error\n");
+
+ return sprintf(buf, "%d\n", data);
+}
+
+static ssize_t bma2x2_range_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long data;
+ int error;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct bma2x2_data *bma2x2 = i2c_get_clientdata(client);
+
+ error = strict_strtoul(buf, 10, &data);
+ if (error)
+ return error;
+ if (bma2x2_set_range(bma2x2->bma2x2_client, (unsigned char) data) < 0)
+ return -EINVAL;
+
+ return count;
+}
+
+static ssize_t bma2x2_bandwidth_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ unsigned char data;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct bma2x2_data *bma2x2 = i2c_get_clientdata(client);
+
+ if (bma2x2_get_bandwidth(bma2x2->bma2x2_client, &data) < 0)
+ return sprintf(buf, "Read error\n");
+
+ return sprintf(buf, "%d\n", data);
+
+}
+
+static ssize_t bma2x2_bandwidth_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long data;
+ int error;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct bma2x2_data *bma2x2 = i2c_get_clientdata(client);
+
+ error = strict_strtoul(buf, 10, &data);
+ if (error)
+ return error;
+
+ if (bma2x2->sensor_type == BMA280_TYPE)
+ if ((unsigned char) data > 14)
+ return -EINVAL;
+
+ if (bma2x2_set_bandwidth(bma2x2->bma2x2_client,
+ (unsigned char) data) < 0)
+ return -EINVAL;
+
+ return count;
+}
+
+static ssize_t bma2x2_mode_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ unsigned char data;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct bma2x2_data *bma2x2 = i2c_get_clientdata(client);
+
+ if (bma2x2_get_mode(bma2x2->bma2x2_client, &data) < 0)
+ return sprintf(buf, "Read error\n");
+
+ return sprintf(buf, "%d\n", data);
+}
+
+static ssize_t bma2x2_mode_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long data;
+ int error;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct bma2x2_data *bma2x2 = i2c_get_clientdata(client);
+
+ error = strict_strtoul(buf, 10, &data);
+ if (error)
+ return error;
+ if (bma2x2_set_mode(bma2x2->bma2x2_client, (unsigned char) data) < 0)
+ return -EINVAL;
+
+ return count;
+}
+static ssize_t bma2x2_value_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct input_dev *input = to_input_dev(dev);
+ struct bma2x2_data *bma2x2 = input_get_drvdata(input);
+ struct bma2x2acc acc_value;
+
+ bma2x2_read_accel_xyz(bma2x2->bma2x2_client, bma2x2->sensor_type,
+ &acc_value);
+
+ return sprintf(buf, "%d %d %d\n", acc_value.x, acc_value.y,
+ acc_value.z);
+}
+
+static ssize_t bma2x2_delay_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct bma2x2_data *bma2x2 = i2c_get_clientdata(client);
+
+ return sprintf(buf, "%d\n", atomic_read(&bma2x2->delay));
+
+}
+
+static ssize_t bma2x2_chip_id_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct bma2x2_data *bma2x2 = i2c_get_clientdata(client);
+
+ return sprintf(buf, "%d\n", bma2x2->chip_id);
+
+}
+static ssize_t bma2x2_delay_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long data;
+ int error;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct bma2x2_data *bma2x2 = i2c_get_clientdata(client);
+
+ error = strict_strtoul(buf, 10, &data);
+ if (error)
+ return error;
+ if (data > BMA2X2_MAX_DELAY)
+ data = BMA2X2_MAX_DELAY;
+ atomic_set(&bma2x2->delay, (unsigned int) data);
+
+ return count;
+}
+
+
+static ssize_t bma2x2_enable_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct bma2x2_data *bma2x2 = i2c_get_clientdata(client);
+
+ return sprintf(buf, "%d\n", atomic_read(&bma2x2->enable));
+
+}
+
+static void bma2x2_set_enable(struct device *dev, int enable)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct bma2x2_data *bma2x2 = i2c_get_clientdata(client);
+ int pre_enable = atomic_read(&bma2x2->enable);
+
+ mutex_lock(&bma2x2->enable_mutex);
+ if (enable) {
+ if (pre_enable == 0) {
+ bma2x2_set_mode(bma2x2->bma2x2_client,
+ BMA2X2_MODE_NORMAL);
+ schedule_delayed_work(&bma2x2->work,
+ msecs_to_jiffies(atomic_read(&bma2x2->delay)));
+ atomic_set(&bma2x2->enable, 1);
+ }
+
+ } else {
+ if (pre_enable == 1) {
+#ifdef BMA2X2_WAKEUP_BY_2TAP
+ if(glanceview_filter(gv_device_id_gsensor,gv_gvmode)==gv_bypass)
+#endif
+ {
+ bma2x2_set_mode(bma2x2->bma2x2_client,
+ BMA2X2_MODE_SUSPEND);
+ cancel_delayed_work_sync(&bma2x2->work);
+ atomic_set(&bma2x2->enable, 0);
+ }
+ }
+ }
+ mutex_unlock(&bma2x2->enable_mutex);
+
+}
+
+static ssize_t bma2x2_enable_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long data;
+ int error;
+
+ error = strict_strtoul(buf, 10, &data);
+ if (error)
+ return error;
+ if ((data == 0) || (data == 1))
+ bma2x2_set_enable(dev, data);
+
+
+ return count;
+}
+
+static DEVICE_ATTR(range, S_IRUGO|S_IWUSR|S_IWGRP,
+ bma2x2_range_show, bma2x2_range_store);
+static DEVICE_ATTR(bandwidth, S_IRUGO|S_IWUSR|S_IWGRP,
+ bma2x2_bandwidth_show, bma2x2_bandwidth_store);
+static DEVICE_ATTR(mode, S_IRUGO|S_IWUSR|S_IWGRP,
+ bma2x2_mode_show, bma2x2_mode_store);
+static DEVICE_ATTR(value, S_IRUGO,
+ bma2x2_value_show, NULL);
+static DEVICE_ATTR(delay, S_IRUGO|S_IWUSR|S_IWGRP,
+ bma2x2_delay_show, bma2x2_delay_store);
+static DEVICE_ATTR(enable, S_IRUGO|S_IWUSR|S_IWGRP,
+ bma2x2_enable_show, bma2x2_enable_store);
+static DEVICE_ATTR(reg, S_IRUGO|S_IWUSR|S_IWGRP,
+ bma2x2_register_show, bma2x2_register_store);
+static DEVICE_ATTR(chip_id, S_IRUGO,
+ bma2x2_chip_id_show, NULL);
+static DEVICE_ATTR(tap_duration, S_IRUGO|S_IWUSR|S_IWGRP,
+ bma2x2_tap_duration_show, bma2x2_tap_duration_store);
+static DEVICE_ATTR(tap_threshold, S_IRUGO|S_IWUSR|S_IWGRP,
+ bma2x2_tap_threshold_show, bma2x2_tap_threshold_store);
+static DEVICE_ATTR(tap_quiet, S_IRUGO|S_IWUSR|S_IWGRP,
+ bma2x2_tap_quiet_show, bma2x2_tap_quiet_store);
+static DEVICE_ATTR(tap_shock, S_IRUGO|S_IWUSR|S_IWGRP,
+ bma2x2_tap_shock_show, bma2x2_tap_shock_store);
+static DEVICE_ATTR(tap_samp, S_IRUGO|S_IWUSR|S_IWGRP,
+ bma2x2_tap_samp_show, bma2x2_tap_samp_store);
+
+
+static struct attribute *bma2x2_attributes[] = {
+ &dev_attr_range.attr,
+ &dev_attr_bandwidth.attr,
+ &dev_attr_mode.attr,
+ &dev_attr_value.attr,
+ &dev_attr_delay.attr,
+ &dev_attr_enable.attr,
+ &dev_attr_reg.attr,
+ &dev_attr_chip_id.attr,
+ &dev_attr_tap_threshold.attr,
+ &dev_attr_tap_duration.attr,
+ &dev_attr_tap_quiet.attr,
+ &dev_attr_tap_shock.attr,
+ &dev_attr_tap_samp.attr,
+ NULL
+};
+
+static struct attribute_group bma2x2_attribute_group = {
+ .attrs = bma2x2_attributes
+};
+
+
+
+
+#if defined(BMA2X2_ENABLE_INT1) || defined(BMA2X2_ENABLE_INT2)
+#ifdef BMA2X2_WAKEUP_BY_2TAP
+static void bma2x2_irq_work_func_2tap(struct work_struct *work)
+{
+
+ struct bma2x2_data *bma2x2 = container_of((struct work_struct *)work,
+ struct bma2x2_data, irq_work);
+
+ printk(KERN_INFO "sdl double tap interrupt happened\n");
+ if(atomic_read(&bma2x2->en_2taps_wake)==1)
+ {
+ input_report_key(bma2x2->input, KEY_POWER, 1);
+ input_sync(bma2x2->input);
+ input_report_key(bma2x2->input, KEY_POWER, 0);
+ input_sync(bma2x2->input);
+ }
+ input_report_rel(bma2x2->input, DOUBLE_TAP_INTERRUPT,
+ DOUBLE_TAP_INTERRUPT_HAPPENED);
+}
+#else
+unsigned char *orient[] = {"upward looking portrait upright", \
+ "upward looking portrait upside-down", \
+ "upward looking landscape left", \
+ "upward looking landscape right", \
+ "downward looking portrait upright", \
+ "downward looking portrait upside-down", \
+ "downward looking landscape left", \
+ "downward looking landscape right"};
+
+static void bma2x2_irq_work_func(struct work_struct *work)
+{
+ struct bma2x2_data *bma2x2 = container_of((struct work_struct *)work,
+ struct bma2x2_data, irq_work);
+
+ unsigned char status = 0;
+ unsigned char i;
+ unsigned char first_value = 0;
+ unsigned char sign_value = 0;
+
+ bma2x2_set_mode(bma2x2->bma2x2_client, BMA2X2_MODE_NORMAL);
+ bma2x2_get_interruptstatus1(bma2x2->bma2x2_client, &status);
+ switch (status) {
+
+ case 0x01:
+ printk(KERN_INFO "Low G interrupt happened\n");
+ input_report_rel(bma2x2->input, LOW_G_INTERRUPT,
+ LOW_G_INTERRUPT_HAPPENED);
+ break;
+ case 0x02:
+ for (i = 0; i < 3; i++) {
+ bma2x2_get_HIGH_first(bma2x2->bma2x2_client, i,
+ &first_value);
+ if (first_value == 1) {
+
+ bma2x2_get_HIGH_sign(bma2x2->bma2x2_client,
+ &sign_value);
+
+ if (sign_value == 1) {
+ if (i == 0)
+ input_report_rel(bma2x2->input,
+ HIGH_G_INTERRUPT,
+ HIGH_G_INTERRUPT_X_NEGATIVE_HAPPENED);
+ if (i == 1)
+ input_report_rel(bma2x2->input,
+ HIGH_G_INTERRUPT,
+ HIGH_G_INTERRUPT_Y_NEGATIVE_HAPPENED);
+ if (i == 2)
+ input_report_rel(bma2x2->input,
+ HIGH_G_INTERRUPT,
+ HIGH_G_INTERRUPT_Z_NEGATIVE_HAPPENED);
+ } else {
+ if (i == 0)
+ input_report_rel(bma2x2->input,
+ HIGH_G_INTERRUPT,
+ HIGH_G_INTERRUPT_X_HAPPENED);
+ if (i == 1)
+ input_report_rel(bma2x2->input,
+ HIGH_G_INTERRUPT,
+ HIGH_G_INTERRUPT_Y_HAPPENED);
+ if (i == 2)
+ input_report_rel(bma2x2->input,
+ HIGH_G_INTERRUPT,
+ HIGH_G_INTERRUPT_Z_HAPPENED);
+ }
+ }
+
+ printk(KERN_INFO "High G interrupt happened,exis is %d,"
+ "first is %d,sign is %d\n", i,
+ first_value, sign_value);
+ }
+ break;
+ case 0x04:
+ for (i = 0; i < 3; i++) {
+ bma2x2_get_slope_first(bma2x2->bma2x2_client, i,
+ &first_value);
+ if (first_value == 1) {
+
+ bma2x2_get_slope_sign(bma2x2->bma2x2_client,
+ &sign_value);
+
+ if (sign_value == 1) {
+ if (i == 0)
+ input_report_rel(bma2x2->input,
+ SLOP_INTERRUPT,
+ SLOPE_INTERRUPT_X_NEGATIVE_HAPPENED);
+ else if (i == 1)
+ input_report_rel(bma2x2->input,
+ SLOP_INTERRUPT,
+ SLOPE_INTERRUPT_Y_NEGATIVE_HAPPENED);
+ else if (i == 2)
+ input_report_rel(bma2x2->input,
+ SLOP_INTERRUPT,
+ SLOPE_INTERRUPT_Z_NEGATIVE_HAPPENED);
+ } else {
+ if (i == 0)
+ input_report_rel(bma2x2->input,
+ SLOP_INTERRUPT,
+ SLOPE_INTERRUPT_X_HAPPENED);
+ else if (i == 1)
+ input_report_rel(bma2x2->input,
+ SLOP_INTERRUPT,
+ SLOPE_INTERRUPT_Y_HAPPENED);
+ else if (i == 2)
+ input_report_rel(bma2x2->input,
+ SLOP_INTERRUPT,
+ SLOPE_INTERRUPT_Z_HAPPENED);
+
+ }
+ }
+
+ printk(KERN_INFO "Slop interrupt happened,exis is %d,"
+ "first is %d,sign is %d\n", i,
+ first_value, sign_value);
+ }
+ break;
+
+ case 0x10:
+ printk(KERN_INFO "double tap interrupt happened\n");
+ input_report_rel(bma2x2->input, DOUBLE_TAP_INTERRUPT,
+ DOUBLE_TAP_INTERRUPT_HAPPENED);
+ break;
+ case 0x20:
+ printk(KERN_INFO "single tap interrupt happened\n");
+ input_report_rel(bma2x2->input, SINGLE_TAP_INTERRUPT,
+ SINGLE_TAP_INTERRUPT_HAPPENED);
+ break;
+ case 0x40:
+ bma2x2_get_orient_status(bma2x2->bma2x2_client,
+ &first_value);
+ printk(KERN_INFO "orient interrupt happened,%s\n",
+ orient[first_value]);
+ if (first_value == 0)
+ input_report_abs(bma2x2->input, ORIENT_INTERRUPT,
+ UPWARD_PORTRAIT_UP_INTERRUPT_HAPPENED);
+ else if (first_value == 1)
+ input_report_abs(bma2x2->input, ORIENT_INTERRUPT,
+ UPWARD_PORTRAIT_DOWN_INTERRUPT_HAPPENED);
+ else if (first_value == 2)
+ input_report_abs(bma2x2->input, ORIENT_INTERRUPT,
+ UPWARD_LANDSCAPE_LEFT_INTERRUPT_HAPPENED);
+ else if (first_value == 3)
+ input_report_abs(bma2x2->input, ORIENT_INTERRUPT,
+ UPWARD_LANDSCAPE_RIGHT_INTERRUPT_HAPPENED);
+ else if (first_value == 4)
+ input_report_abs(bma2x2->input, ORIENT_INTERRUPT,
+ DOWNWARD_PORTRAIT_UP_INTERRUPT_HAPPENED);
+ else if (first_value == 5)
+ input_report_abs(bma2x2->input, ORIENT_INTERRUPT,
+ DOWNWARD_PORTRAIT_DOWN_INTERRUPT_HAPPENED);
+ else if (first_value == 6)
+ input_report_abs(bma2x2->input, ORIENT_INTERRUPT,
+ DOWNWARD_LANDSCAPE_LEFT_INTERRUPT_HAPPENED);
+ else if (first_value == 7)
+ input_report_abs(bma2x2->input, ORIENT_INTERRUPT,
+ DOWNWARD_LANDSCAPE_RIGHT_INTERRUPT_HAPPENED);
+ break;
+ case 0x80:
+ bma2x2_get_orient_flat_status(bma2x2->bma2x2_client,
+ &sign_value);
+ printk(KERN_INFO "flat interrupt happened,flat status is %d\n",
+ sign_value);
+ if (sign_value == 1) {
+ input_report_abs(bma2x2->input, FLAT_INTERRUPT,
+ FLAT_INTERRUPT_TURE_HAPPENED);
+ } else {
+ input_report_abs(bma2x2->input, FLAT_INTERRUPT,
+ FLAT_INTERRUPT_FALSE_HAPPENED);
+ }
+ break;
+ default:
+ break;
+ }
+}
+#endif
+
+static irqreturn_t bma2x2_irq_handler(int irq, void *handle)
+{
+
+
+ struct bma2x2_data *data = handle;
+
+
+ if (data == NULL)
+ return IRQ_HANDLED;
+ if (data->bma2x2_client == NULL)
+ return IRQ_HANDLED;
+ wake_lock_timeout(&data->bma_wake_lock, HZ / 2);
+
+ schedule_work(&data->irq_work);
+
+ return IRQ_HANDLED;
+
+
+}
+#endif /* defined(BMA2X2_ENABLE_INT1)||defined(BMA2X2_ENABLE_INT2) */
+#ifdef BMA2X2_WAKEUP_BY_2TAP
+void bma2x2_gv_on_mode(struct device * dev)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct bma2x2_data *bma2x2 = i2c_get_clientdata(client);
+
+ if(atomic_read(&bma2x2->en_2taps_wake)==1)
+ {
+ bma2x2_set_Int_Enable(client, 9, 0);
+ bma2x2_set_int1_pad_sel_2tap(client,0);
+ disable_irq_wake(client->irq);
+ atomic_set(&bma2x2->en_2taps_wake,0);
+ }
+ if (atomic_read(&bma2x2->enable) == 0)
+ {
+ bma2x2_set_mode(bma2x2->bma2x2_client,
+ BMA2X2_MODE_SUSPEND);
+ cancel_delayed_work_sync(&bma2x2->work);
+ }
+ else
+ {
+ bma2x2_set_mode(bma2x2->bma2x2_client, BMA2X2_MODE_NORMAL);
+ schedule_delayed_work(&bma2x2->work,
+ msecs_to_jiffies(atomic_read(&bma2x2->delay)));
+ }
+}
+
+void bma2x2_gv_off_mode(struct device * dev)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct bma2x2_data *bma2x2 = i2c_get_clientdata(client);
+ if (atomic_read(&bma2x2->enable) == 1)
+ {
+ cancel_delayed_work_sync(&bma2x2->work);
+ }
+ bma2x2_set_mode(bma2x2->bma2x2_client,
+ BMA2X2_MODE_LOWPOWER2);
+ if(atomic_read(&bma2x2->en_2taps_wake)==0)
+ {
+ enable_irq_wake(client->irq);
+ bma2x2_set_Int_Enable(client, 9, 1);
+ bma2x2_set_int1_pad_sel_2tap(client,1);
+ atomic_set(&bma2x2->en_2taps_wake,1);
+ }
+
+}
+void bma2x2_gv_gv_mode(struct device * dev)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct bma2x2_data *bma2x2 = i2c_get_clientdata(client);
+ if(atomic_read(&bma2x2->en_2taps_wake)==0)
+ {
+ bma2x2_set_mode(bma2x2->bma2x2_client,
+ BMA2X2_MODE_SUSPEND);
+ cancel_delayed_work_sync(&bma2x2->work);
+ }
+ atomic_set(&bma2x2->enable, 0);
+
+}
+
+int bma2x2_gv_mode(struct device * dev,enum glanceview_op op)
+{
+ if(dev==NULL)
+ {
+ return -1;
+ }
+ switch(op){
+ case gv_enable:
+ bma2x2_gv_on_mode(dev);
+ break;
+ case gv_disable:
+ bma2x2_gv_off_mode(dev);
+ break;
+ case gv_gvmode:
+ bma2x2_gv_gv_mode(dev);
+ break;
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+static struct glanceview_ops gv_dev=
+{
+ .gv_glance_mode=bma2x2_gv_mode,
+};
+#endif
+
+static int bma2x2_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ int err = 0;
+ int tempvalue;
+ unsigned char tmp_chip_id;
+ struct bma2x2_data *data;
+ struct input_dev *dev;
+ printk("entry %s\n",__func__);
+ //omap_mux_init_gpio(145, OMAP_PIN_INPUT);
+ //omap_mux_init_gpio(146, OMAP_PIN_INPUT);
+
+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
+ printk(KERN_INFO "i2c_check_functionality error\n");
+ goto exit;
+ }
+ data = kzalloc(sizeof(struct bma2x2_data), GFP_KERNEL);
+ if (!data) {
+ err = -ENOMEM;
+ goto exit;
+ }
+ /* read chip id */
+ tempvalue = i2c_smbus_read_word_data(client, BMA2X2_CHIP_ID_REG);
+ tmp_chip_id = tempvalue&0x00ff;
+
+ switch (tmp_chip_id) {
+ case BMA255_CHIP_ID:
+ data->sensor_type = BMA255_TYPE;
+ break;
+ case BMA250E_CHIP_ID:
+ data->sensor_type = BMA250E_TYPE;
+ break;
+ case BMA222E_CHIP_ID:
+ data->sensor_type = BMA222E_TYPE;
+ break;
+ case BMA280_CHIP_ID:
+ data->sensor_type = BMA280_TYPE;
+ break;
+ default:
+ data->sensor_type = -1;
+ }
+ if (data->sensor_type != -1) {
+ data->chip_id = tmp_chip_id;
+ printk(KERN_INFO "Bosch Sensortec Device detected!\n"
+ "%s registered I2C driver!\n",
+ sensor_name[data->sensor_type]);
+ } else{
+ printk(KERN_INFO "Bosch Sensortec Device not found"
+ "i2c error %d \n", tempvalue);
+ err = -ENODEV;
+ goto exit;
+ }
+ i2c_set_clientdata(client, data);
+ data->bma2x2_client = client;
+ mutex_init(&data->value_mutex);
+ mutex_init(&data->mode_mutex);
+ mutex_init(&data->enable_mutex);
+ bma2x2_set_bandwidth(client, BMA2X2_BW_SET);
+ bma2x2_set_range(client, BMA2X2_RANGE_SET);
+
+
+#if defined(BMA2X2_ENABLE_INT1) || defined(BMA2X2_ENABLE_INT2)
+ bma2x2_set_Int_Mode(client, 1);/*latch interrupt 250ms*/
+#endif
+ /*8,single tap
+ 9,double tap
+ 10,orient
+ 11,flat*/
+ bma2x2_set_Int_Enable(client, 8, 0);
+ bma2x2_set_Int_Enable(client, 9, 1);
+ bma2x2_set_Int_Enable(client, 10, 0);
+ bma2x2_set_Int_Enable(client, 11, 0);
+
+#ifdef BMA2X2_ENABLE_INT1
+ /* maps interrupt to INT1 pin */
+#ifdef BMA2X2_WAKEUP_BY_2TAP
+ bma2x2_set_int1_pad_sel_2tap(client,1);
+#else
+ bma2x2_set_int1_pad_sel(client, PAD_LOWG);
+ bma2x2_set_int1_pad_sel(client, PAD_HIGHG);
+ bma2x2_set_int1_pad_sel(client, PAD_SLOP);
+ bma2x2_set_int1_pad_sel(client, PAD_DOUBLE_TAP);
+ bma2x2_set_int1_pad_sel(client, PAD_SINGLE_TAP);
+ bma2x2_set_int1_pad_sel(client, PAD_ORIENT);
+ bma2x2_set_int1_pad_sel(client, PAD_FLAT);
+#endif
+#endif
+
+#ifdef BMA2X2_ENABLE_INT2
+ /* maps interrupt to INT2 pin */
+ bma2x2_set_int2_pad_sel(client, PAD_LOWG);
+ bma2x2_set_int2_pad_sel(client, PAD_HIGHG);
+ bma2x2_set_int2_pad_sel(client, PAD_SLOP);
+ bma2x2_set_int2_pad_sel(client, PAD_DOUBLE_TAP);
+ bma2x2_set_int2_pad_sel(client, PAD_SINGLE_TAP);
+ bma2x2_set_int2_pad_sel(client, PAD_ORIENT);
+ bma2x2_set_int2_pad_sel(client, PAD_FLAT);
+#endif
+#ifndef BMA2X2_WAKEUP_BY_2TAP
+#if defined(BMA2X2_ENABLE_INT1) || defined(BMA2X2_ENABLE_INT2)
+ data->IRQ = client->irq;
+ err = request_irq(data->IRQ, bma2x2_irq_handler, IRQF_TRIGGER_RISING,
+ "bma2x2", data);
+ if (err)
+ printk(KERN_ERR "could not request irq\n");
+
+ INIT_WORK(&data->irq_work, bma2x2_irq_work_func);
+#endif
+#else
+#if defined(BMA2X2_ENABLE_INT1) || defined(BMA2X2_ENABLE_INT2)
+ INIT_WORK(&data->irq_work, bma2x2_irq_work_func_2tap);
+ device_init_wakeup(&client->dev,1);
+ wake_lock_init(&data->bma_wake_lock, WAKE_LOCK_SUSPEND, "bma");
+#endif
+#endif
+ INIT_DELAYED_WORK(&data->work, bma2x2_work_func);
+ atomic_set(&data->delay, BMA2X2_MAX_DELAY);
+ atomic_set(&data->enable, 0);
+
+ dev = input_allocate_device();
+ if (!dev)
+ return -ENOMEM;
+ dev->name = SENSOR_NAME;
+ dev->id.bustype = BUS_I2C;
+
+ input_set_capability(dev, EV_REL, LOW_G_INTERRUPT);
+ input_set_capability(dev, EV_REL, HIGH_G_INTERRUPT);
+ input_set_capability(dev, EV_REL, SLOP_INTERRUPT);
+ input_set_capability(dev, EV_REL, DOUBLE_TAP_INTERRUPT);
+ input_set_capability(dev, EV_REL, SINGLE_TAP_INTERRUPT);
+ input_set_capability(dev, EV_ABS, ORIENT_INTERRUPT);
+ input_set_capability(dev, EV_ABS, FLAT_INTERRUPT);
+#ifdef BMA2X2_WAKEUP_BY_2TAP
+ input_set_capability(dev, EV_KEY, KEY_POWER);
+#endif
+ input_set_abs_params(dev, ABS_X, ABSMIN, ABSMAX, 0, 0);
+ input_set_abs_params(dev, ABS_Y, ABSMIN, ABSMAX, 0, 0);
+ input_set_abs_params(dev, ABS_Z, ABSMIN, ABSMAX, 0, 0);
+
+ input_set_drvdata(dev, data);
+
+ err = input_register_device(dev);
+ if (err < 0) {
+ input_free_device(dev);
+ goto kfree_exit;
+ }
+
+ data->input = dev;
+
+ err = sysfs_create_group(&data->input->dev.kobj,
+ &bma2x2_attribute_group);
+ if (err < 0)
+ goto error_sysfs;
+
+#ifdef CONFIG_HAS_EARLYSUSPEND
+ data->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1;
+ data->early_suspend.suspend = bma2x2_early_suspend;
+ data->early_suspend.resume = bma2x2_late_resume;
+ register_early_suspend(&data->early_suspend);
+#endif
+#ifdef BMA2X2_WAKEUP_BY_2TAP
+ atomic_set(&data->en_2taps_wake,0);
+ glanceview_register(gv_device_id_gsensor,&gv_dev,&client->dev);
+#if defined(BMA2X2_ENABLE_INT1) || defined(BMA2X2_ENABLE_INT2)
+ err=request_threaded_irq(client->irq,
+ NULL, bma2x2_irq_handler,
+ IRQF_TRIGGER_RISING,
+ "bma2x2", data);
+ if (err<0)
+ printk(KERN_ERR "could not request irq\n");
+
+#endif
+ bma2x2_set_tap_shock(client,1);
+ bma2x2_set_tap_duration(client,3);
+ bma2x2_set_tap_quiet(client,1);
+ bma2x2_set_tap_threshold(client,8);
+#endif
+ return 0;
+
+error_sysfs:
+ input_unregister_device(data->input);
+
+kfree_exit:
+ kfree(data);
+ wake_lock_destroy(&data->bma_wake_lock) ;
+ device_init_wakeup(&client->dev,0);
+exit:
+ return err;
+}
+
+#ifdef CONFIG_HAS_EARLYSUSPEND
+static void bma2x2_early_suspend(struct early_suspend *h)
+{
+ struct bma2x2_data *data =
+ container_of(h, struct bma2x2_data, early_suspend);
+
+ mutex_lock(&data->enable_mutex);
+#ifdef BMA2X2_WAKEUP_BY_2TAP
+ if(glanceview_filter(gv_device_id_gsensor,gv_disable)==gv_bypass)
+#endif
+ {
+ if (atomic_read(&data->enable) == 1) {
+ bma2x2_set_mode(data->bma2x2_client, BMA2X2_MODE_SUSPEND);
+ cancel_delayed_work_sync(&data->work);
+ }
+ }
+ mutex_unlock(&data->enable_mutex);
+}
+
+
+static void bma2x2_late_resume(struct early_suspend *h)
+{
+ struct bma2x2_data *data =
+ container_of(h, struct bma2x2_data, early_suspend);
+
+ mutex_lock(&data->enable_mutex);
+#ifdef BMA2X2_WAKEUP_BY_2TAP
+ if(glanceview_filter(gv_device_id_gsensor,gv_enable)==gv_bypass)
+#endif
+ {
+
+ if (atomic_read(&data->enable) == 1) {
+ bma2x2_set_mode(data->bma2x2_client, BMA2X2_MODE_NORMAL);
+ schedule_delayed_work(&data->work,
+ msecs_to_jiffies(atomic_read(&data->delay)));
+ }
+ }
+ mutex_unlock(&data->enable_mutex);
+}
+#endif
+
+static int __devexit bma2x2_remove(struct i2c_client *client)
+{
+ struct bma2x2_data *data = i2c_get_clientdata(client);
+
+ bma2x2_set_enable(&client->dev, 0);
+#ifdef CONFIG_HAS_EARLYSUSPEND
+ unregister_early_suspend(&data->early_suspend);
+#endif
+ sysfs_remove_group(&data->input->dev.kobj, &bma2x2_attribute_group);
+ input_unregister_device(data->input);
+ kfree(data);
+ wake_lock_destroy(&data->bma_wake_lock) ;
+ device_init_wakeup(&client->dev,0);
+ return 0;
+}
+#ifdef CONFIG_PM
+
+static int bma2x2_suspend(struct i2c_client *client, pm_message_t mesg)
+{
+ struct bma2x2_data *data = i2c_get_clientdata(client);
+
+ mutex_lock(&data->enable_mutex);
+ if (atomic_read(&data->enable) == 1) {
+ bma2x2_set_mode(data->bma2x2_client, BMA2X2_MODE_SUSPEND);
+ cancel_delayed_work_sync(&data->work);
+ }
+ mutex_unlock(&data->enable_mutex);
+
+ return 0;
+}
+
+static int bma2x2_resume(struct i2c_client *client)
+{
+ struct bma2x2_data *data = i2c_get_clientdata(client);
+
+ mutex_lock(&data->enable_mutex);
+ if (atomic_read(&data->enable) == 1) {
+ bma2x2_set_mode(data->bma2x2_client, BMA2X2_MODE_NORMAL);
+ schedule_delayed_work(&data->work,
+ msecs_to_jiffies(atomic_read(&data->delay)));
+ }
+ mutex_unlock(&data->enable_mutex);
+
+ return 0;
+}
+
+#else
+
+#define bma2x2_suspend NULL
+#define bma2x2_resume NULL
+
+#endif /* CONFIG_PM */
+
+static const struct i2c_device_id bma2x2_id[] = {
+ { SENSOR_NAME, 0 },
+ { }
+};
+
+MODULE_DEVICE_TABLE(i2c, bma2x2_id);
+
+static struct i2c_driver bma2x2_driver = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = SENSOR_NAME,
+ },
+ .suspend = bma2x2_suspend,
+ .resume = bma2x2_resume,
+ .id_table = bma2x2_id,
+ .probe = bma2x2_probe,
+ .remove = __devexit_p(bma2x2_remove),
+
+};
+
+static int __init BMA2X2_init(void)
+{
+ return i2c_add_driver(&bma2x2_driver);
+}
+
+static void __exit BMA2X2_exit(void)
+{
+ i2c_del_driver(&bma2x2_driver);
+}
+
+MODULE_AUTHOR("Albert Zhang <xu.zhang@bosch-sensortec.com>");
+MODULE_DESCRIPTION("BMA2X2 accelerometer sensor driver");
+MODULE_LICENSE("GPL");
+
+module_init(BMA2X2_init);
+module_exit(BMA2X2_exit);
+
diff --git a/drivers/hwmon/ltr559.c b/drivers/hwmon/ltr559.c
new file mode 100755
index 0000000..9aa7586
--- /dev/null
+++ b/drivers/hwmon/ltr559.c
@@ -0,0 +1,2635 @@
+/* Lite-On LTR-559ALS Android / Linux Driver
+ *
+ * Copyright (C) 2013 Lite-On Technology Corp (Singapore)
+ *
+ * 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.
+ *
+ */
+
+
+#include <linux/delay.h>
+#include <linux/earlysuspend.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/fs.h>
+#include <linux/gfp.h>
+#include <linux/gpio.h>
+#include <linux/i2c.h>
+#include <linux/init.h>
+#include <linux/input.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/kernel.h>
+#include <linux/miscdevice.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/platform_device.h>
+#include <linux/pm.h>
+#include <linux/poll.h>
+#include <linux/slab.h>
+#include <linux/wakelock.h>
+#include <linux/workqueue.h>
+#include <asm/uaccess.h>
+#include <asm/mach-types.h>
+#include <asm/setup.h>
+#include <linux/version.h>
+
+
+/* LTR-559 Registers */
+#define LTR559_ALS_CONTR 0x80
+#define LTR559_PS_CONTR 0x81
+#define LTR559_PS_LED 0x82
+#define LTR559_PS_N_PULSES 0x83
+#define LTR559_PS_MEAS_RATE 0x84
+#define LTR559_ALS_MEAS_RATE 0x85
+#define LTR559_PART_ID 0x86
+#define LTR559_MANUFACTURER_ID 0x87
+#define LTR559_ALS_DATA_CH1_0 0x88
+#define LTR559_ALS_DATA_CH1_1 0x89
+#define LTR559_ALS_DATA_CH0_0 0x8A
+#define LTR559_ALS_DATA_CH0_1 0x8B
+#define LTR559_ALS_PS_STATUS 0x8C
+#define LTR559_PS_DATA_0 0x8D
+#define LTR559_PS_DATA_1 0x8E
+#define LTR559_INTERRUPT 0x8F
+#define LTR559_PS_THRES_UP_0 0x90
+#define LTR559_PS_THRES_UP_1 0x91
+#define LTR559_PS_THRES_LOW_0 0x92
+#define LTR559_PS_THRES_LOW_1 0x93
+#define LTR559_PS_OFFSET_1 0x94
+#define LTR559_PS_OFFSET_0 0x95
+#define LTR559_ALS_THRES_UP_0 0x97
+#define LTR559_ALS_THRES_UP_1 0x98
+#define LTR559_ALS_THRES_LOW_0 0x99
+#define LTR559_ALS_THRES_LOW_1 0x9A
+#define LTR559_INTERRUPT_PRST 0x9E
+/* LTR-559 Registers */
+
+
+#define SET_BIT 1
+#define CLR_BIT 0
+
+#define ALS 0
+#define PS 1
+#define ALSPS 2
+#define PS_W_SATURATION_BIT 3
+
+/* address 0x80 */
+#define ALS_MODE_ACTIVE (1 << 0)
+#define ALS_MODE_STDBY (0 << 0)
+#define ALS_SW_RESET (1 << 1)
+#define ALS_SW_NRESET (0 << 1)
+#define ALS_GAIN_1x (0 << 2)
+#define ALS_GAIN_2x (1 << 2)
+#define ALS_GAIN_4x (2 << 2)
+#define ALS_GAIN_8x (3 << 2)
+#define ALS_GAIN_48x (6 << 2)
+#define ALS_GAIN_96x (7 << 2)
+#define ALS_MODE_RDBCK 0
+#define ALS_SWRT_RDBCK 1
+#define ALS_GAIN_RDBCK 2
+#define ALS_CONTR_RDBCK 3
+
+/* address 0x81 */
+#define PS_MODE_ACTIVE (3 << 0)
+#define PS_MODE_STDBY (0 << 0)
+#define PS_GAIN_16x (0 << 2)
+#define PS_GAIN_32x (2 << 2)
+#define PS_GAIN_64x (3 << 2)
+#define PS_SATUR_INDIC_EN (1 << 5)
+#define PS_SATU_INDIC_DIS (0 << 5)
+#define PS_MODE_RDBCK 0
+#define PS_GAIN_RDBCK 1
+#define PS_SATUR_RDBCK 2
+#define PS_CONTR_RDBCK 3
+
+/* address 0x82 */
+#define LED_CURR_5MA (0 << 0)
+#define LED_CURR_10MA (1 << 0)
+#define LED_CURR_20MA (2 << 0)
+#define LED_CURR_50MA (3 << 0)
+#define LED_CURR_100MA (4 << 0)
+#define LED_CURR_DUTY_25PC (0 << 3)
+#define LED_CURR_DUTY_50PC (1 << 3)
+#define LED_CURR_DUTY_75PC (2 << 3)
+#define LED_CURR_DUTY_100PC (3 << 3)
+#define LED_PUL_FREQ_30KHZ (0 << 5)
+#define LED_PUL_FREQ_40KHZ (1 << 5)
+#define LED_PUL_FREQ_50KHZ (2 << 5)
+#define LED_PUL_FREQ_60KHZ (3 << 5)
+#define LED_PUL_FREQ_70KHZ (4 << 5)
+#define LED_PUL_FREQ_80KHZ (5 << 5)
+#define LED_PUL_FREQ_90KHZ (6 << 5)
+#define LED_PUL_FREQ_100KHZ (7 << 5)
+#define LED_CURR_RDBCK 0
+#define LED_CURR_DUTY_RDBCK 1
+#define LED_PUL_FREQ_RDBCK 2
+#define PS_LED_RDBCK 3
+
+/* address 0x84 */
+#define PS_MEAS_RPT_RATE_50MS (0 << 0)
+#define PS_MEAS_RPT_RATE_70MS (1 << 0)
+#define PS_MEAS_RPT_RATE_100MS (2 << 0)
+#define PS_MEAS_RPT_RATE_200MS (3 << 0)
+#define PS_MEAS_RPT_RATE_500MS (4 << 0)
+#define PS_MEAS_RPT_RATE_1000MS (5 << 0)
+#define PS_MEAS_RPT_RATE_2000MS (6 << 0)
+#define PS_MEAS_RPT_RATE_10MS (8 << 0)
+
+/* address 0x85 */
+#define ALS_MEAS_RPT_RATE_50MS (0 << 0)
+#define ALS_MEAS_RPT_RATE_100MS (1 << 0)
+#define ALS_MEAS_RPT_RATE_200MS (2 << 0)
+#define ALS_MEAS_RPT_RATE_500MS (3 << 0)
+#define ALS_MEAS_RPT_RATE_1000MS (4 << 0)
+#define ALS_MEAS_RPT_RATE_2000MS (5 << 0)
+#define ALS_INTEG_TM_100MS (0 << 3)
+#define ALS_INTEG_TM_50MS (1 << 3)
+#define ALS_INTEG_TM_200MS (2 << 3)
+#define ALS_INTEG_TM_400MS (3 << 3)
+#define ALS_INTEG_TM_150MS (4 << 3)
+#define ALS_INTEG_TM_250MS (5 << 3)
+#define ALS_INTEG_TM_300MS (6 << 3)
+#define ALS_INTEG_TM_350MS (7 << 3)
+#define ALS_MEAS_RPT_RATE_RDBCK 0
+#define ALS_INTEG_TM_RDBCK 1
+#define ALS_MEAS_RATE_RDBCK 2
+
+/* address 0x86 */
+#define PART_NUM_ID_RDBCK 0
+#define REVISION_ID_RDBCK 1
+#define PART_ID_REG_RDBCK 2
+
+/* address 0x8C */
+#define PS_DATA_STATUS_RDBCK 0
+#define PS_INTERR_STATUS_RDBCK 1
+#define ALS_DATA_STATUS_RDBCK 2
+#define ALS_INTERR_STATUS_RDBCK 3
+#define ALS_GAIN_STATUS_RDBCK 4
+#define ALS_VALID_STATUS_RDBCK 5
+#define ALS_PS_STATUS_RDBCK 6
+
+/* address 0x8F */
+#define INT_MODE_00 (0 << 0)
+#define INT_MODE_PS_TRIG (1 << 0)
+#define INT_MODE_ALS_TRIG (2 << 0)
+#define INT_MODE_ALSPS_TRIG (3 << 0)
+#define INT_POLAR_ACT_LO (0 << 2)
+#define INT_POLAR_ACT_HI (1 << 2)
+#define INT_MODE_RDBCK 0
+#define INT_POLAR_RDBCK 1
+#define INT_INTERRUPT_RDBCK 2
+
+/* address 0x9E */
+#define ALS_PERSIST_SHIFT 0
+#define PS_PERSIST_SHIFT 4
+#define ALS_PRST_RDBCK 0
+#define PS_PRST_RDBCK 1
+#define ALSPS_PRST_RDBCK 2
+
+#define PON_DELAY 600
+
+#define ALS_MIN_MEASURE_VAL 0
+#define ALS_MAX_MEASURE_VAL 65535
+#define ALS_VALID_MEASURE_MASK ALS_MAX_MEASURE_VAL
+#define PS_MIN_MEASURE_VAL 0
+#define PS_MAX_MEASURE_VAL 2047
+#define PS_VALID_MEASURE_MASK PS_MAX_MEASURE_VAL
+#define LO_LIMIT 0
+#define HI_LIMIT 1
+#define LO_N_HI_LIMIT 2
+#define PS_OFFSET_MIN_VAL 0
+#define PS_OFFSET_MAX_VAL 1023
+
+#define DRIVER_VERSION "1.00"
+#define PARTID 0x92
+#define MANUID 0x05
+
+#define I2C_RETRY 5
+
+#define DEVICE_NAME "ltr559alsps"
+#define GPIO17_PLSENSOR_INT 17
+#define DEBUG
+
+#define PS_SET_LOWTHRESH (1150)
+#define PS_SET_HIGHTHRESH (1200)
+
+
+/*
+ * Magic Number
+ * ============
+ * Refer to file ioctl-number.txt for allocation
+ */
+#define LTR559_IOCTL_MAGIC 'c'
+
+/* IOCTLs for ltr559 device */
+#define LTR559_IOCTL_PS_ENABLE _IOR(LTR559_IOCTL_MAGIC, 1, int *)
+#define LTR559_IOCTL_PS_GET_ENABLED _IOW(LTR559_IOCTL_MAGIC, 2, int *)
+#define LTR559_IOCTL_ALS_ENABLE _IOR(LTR559_IOCTL_MAGIC, 3, int *)
+#define LTR559_IOCTL_ALS_GET_ENABLED _IOW(LTR559_IOCTL_MAGIC, 4, int *)
+
+//pjn add for psensor calibration
+uint16_t ps_set_lowthresh = PS_SET_LOWTHRESH;
+uint16_t ps_set_highthresh = PS_SET_HIGHTHRESH;
+
+//(Linux RTOS)>
+#if 0
+struct ltr559_platform_data {
+ /* ALS */
+ uint16_t pfd_levels[5];
+ uint16_t pfd_als_lowthresh;
+ uint16_t pfd_als_highthresh;
+ int pfd_disable_als_on_suspend;
+
+ /* PS */
+ uint16_t pfd_ps_lowthresh;
+ uint16_t pfd_ps_highthresh;
+ int pfd_disable_ps_on_suspend;
+
+ /* Interrupt */
+ int pfd_gpio_int_no;
+};
+#endif
+//(Linux RTOS)<
+
+
+struct ltr559_data {
+ /* Device */
+ struct i2c_client *i2c_client;
+ struct input_dev *als_input_dev;
+ struct input_dev *ps_input_dev;
+ struct workqueue_struct *workqueue;
+ struct early_suspend early_suspend;
+ struct wake_lock ps_wake_lock;
+
+ /* Device mode
+ * 0 = ALS
+ * 1 = PS
+ */
+ uint8_t mode;
+
+ /* ALS */
+ uint8_t als_enable_flag;
+ uint8_t als_suspend_enable_flag;
+ uint8_t als_irq_flag;
+ uint8_t als_opened;
+ uint16_t als_lowthresh;
+ uint16_t als_highthresh;
+ uint16_t default_als_lowthresh;
+ uint16_t default_als_highthresh;
+ uint16_t *adc_levels;
+ /* Flag to suspend ALS on suspend or not */
+ uint8_t disable_als_on_suspend;
+
+ /* PS */
+ uint8_t ps_enable_flag;
+ uint8_t ps_suspend_enable_flag;
+ uint8_t ps_irq_flag;
+ uint8_t ps_opened;
+ uint16_t ps_lowthresh;
+ uint16_t ps_highthresh;
+ uint16_t default_ps_lowthresh;
+ uint16_t default_ps_highthresh;
+ /* Flag to suspend PS on suspend or not */
+ uint8_t disable_ps_on_suspend;
+ unsigned int ps_direction; /* 0 = near-to-far; 1 = far-to-near */
+
+ /* LED */
+ int led_pulse_freq;
+ int led_duty_cyc;
+ int led_peak_curr;
+ int led_pulse_count;
+
+ /* Interrupt */
+ int irq;
+ int gpio_int_no;
+ int is_suspend;
+};
+
+struct ltr559_data *sensor_info;
+
+
+/* I2C Read */
+static int8_t I2C_Read(uint8_t *rxData, uint8_t length)
+{
+ int8_t index;
+ struct i2c_msg data[] = {
+ {
+ .addr = sensor_info->i2c_client->addr,
+ .flags = 0,
+ .len = 1,
+ .buf = rxData,
+ },
+ {
+ .addr = sensor_info->i2c_client->addr,
+ .flags = I2C_M_RD,
+ .len = length,
+ .buf = rxData,
+ },
+ };
+
+ for (index = 0; index < I2C_RETRY; index++) {
+ if (i2c_transfer(sensor_info->i2c_client->adapter, data, 2) > 0)
+ break;
+
+ mdelay(10);
+ }
+
+ if (index >= I2C_RETRY) {
+ pr_alert("%s I2C Read Fail !!!!\n",__func__);
+ return -EIO;
+ }
+
+ return 0;
+}
+
+
+/* I2C Write */
+static int8_t I2C_Write(uint8_t *txData, uint8_t length)
+{
+ int8_t index;
+ struct i2c_msg data[] = {
+ {
+ .addr = sensor_info->i2c_client->addr,
+ .flags = 0,
+ .len = length,
+ .buf = txData,
+ },
+ };
+
+ for (index = 0; index < I2C_RETRY; index++) {
+ if (i2c_transfer(sensor_info->i2c_client->adapter, data, 1) > 0)
+ break;
+
+ mdelay(10);
+ }
+
+ if (index >= I2C_RETRY) {
+ pr_alert("%s I2C Write Fail !!!!\n", __func__);
+ return -EIO;
+ }
+
+ return 0;
+}
+
+
+/* Set register bit */
+static int8_t _ltr559_set_bit(struct i2c_client *client, uint8_t set, uint8_t cmd, uint8_t data)
+{
+ uint8_t buffer[2];
+ uint8_t value;
+ int8_t ret = 0;
+
+ buffer[0] = cmd;
+ ret = I2C_Read(buffer, 1);
+ if (ret < 0) {
+ dev_err(&client->dev, "%s | 0x%02X", __func__, buffer[0]);
+ return ret;
+ }
+
+ value = buffer[0];
+
+ if (set)
+ value |= data;
+ else
+ value &= ~data;
+
+ buffer[0] = cmd;
+ buffer[1] = value;
+ ret = I2C_Write(buffer, 2);
+ if (ret < 0) {
+ dev_err(&client->dev, "%s | 0x%02X", __func__, buffer[0]);
+ return -EIO;
+ }
+
+ return ret;
+}
+
+
+static uint16_t lux_formula(uint16_t ch0_adc, uint16_t ch1_adc)
+{
+ uint16_t luxval = 0;
+ int ch0_coeff = 0;
+ int ch1_coeff = 0;
+ uint16_t ch0_calc;
+ int ratio;
+ int8_t ret;
+ uint8_t buffer[2];
+
+ buffer[0] = LTR559_ALS_CONTR;
+ ret = I2C_Read(buffer, 1);
+ if (ret < 0) {
+ pr_alert("%s | 0x%02X", __func__, buffer[0]);
+ return ret;
+ }
+
+ ch0_calc = ch0_adc;
+#if 0
+ if ((buffer[0] & 0x20) == 0x20) {
+ ch0_calc = ch0_adc - ch1_adc;
+ }
+#endif
+ if ((ch1_adc + ch0_calc) == 0) {
+ ratio = 100;
+ } else {
+ ratio = (100 * ch1_adc)/(ch1_adc + ch0_calc);
+ }
+
+ if (ratio < 45) {
+ ch0_coeff = 17743;
+ ch1_coeff = 11059;
+ } else if ((ratio >= 45) && (ratio < 64)) {
+ ch0_coeff = 42785;
+ ch1_coeff = -19548;
+ } else if ((ratio >= 64) && (ratio < 85)) {
+ ch0_coeff = 5926;
+ ch1_coeff = 1185;
+ } else if (ratio >= 85) {
+ ch0_coeff = 0;
+ ch1_coeff = 0;
+ }
+
+ luxval = ((ch0_calc * ch0_coeff) + (ch1_adc * ch1_coeff))/10000;
+ return luxval;
+}
+
+
+/* Read ADC Value */
+static uint16_t read_adc_value(struct ltr559_data *ltr559)
+{
+
+ int8_t ret = -99;
+ uint16_t value = -99;
+ uint16_t ps_val;
+ int ch0_val;
+ int ch1_val;
+
+ uint8_t buffer[4];
+
+ switch (ltr559->mode) {
+ case 0 :
+ /* ALS */
+ buffer[0] = LTR559_ALS_DATA_CH1_0;
+
+ /* read data bytes from data regs */
+ ret = I2C_Read(buffer, 4);
+ break;
+
+ case 1 :
+ case 3 : /* PS with saturation bit */
+ /* PS */
+ buffer[0] = LTR559_PS_DATA_0;
+
+ /* read data bytes from data regs */
+ ret = I2C_Read(buffer, 2);
+ break;
+ }
+
+ if (ret < 0) {
+ dev_err(&ltr559->i2c_client->dev, "%s | 0x%02X", __func__, buffer[0]);
+ return ret;
+ }
+
+
+ switch (ltr559->mode) {
+ case 0 :
+ /* ALS Ch0 */
+ ch0_val = (uint16_t)buffer[2] | ((uint16_t)buffer[3] << 8);
+ dev_dbg(&ltr559->i2c_client->dev,
+ "%s | als_ch0 value = 0x%04X\n", __func__,
+ ch0_val);
+
+ if (ch0_val > ALS_MAX_MEASURE_VAL) {
+ dev_err(&ltr559->i2c_client->dev,
+ "%s: ALS Value Error: 0x%X\n", __func__,
+ ch0_val);
+ }
+ ch0_val &= ALS_VALID_MEASURE_MASK;
+
+ /* ALS Ch1 */
+ ch1_val = (uint16_t)buffer[0] | ((uint16_t)buffer[1] << 8);
+ dev_dbg(&ltr559->i2c_client->dev,
+ "%s | als_ch1 value = 0x%04X\n", __func__,
+ ch1_val);
+
+ if (ch1_val > ALS_MAX_MEASURE_VAL) {
+ dev_err(&ltr559->i2c_client->dev,
+ "%s: ALS Value Error: 0x%X\n", __func__,
+ ch1_val);
+ }
+ ch1_val &= ALS_VALID_MEASURE_MASK;
+
+ /* ALS Lux Conversion */
+ value = lux_formula(ch0_val, ch1_val);
+
+ break;
+
+ case 1 :
+ case 3 : /* PS with saturation bit */
+ /* PS */
+ ps_val = (uint16_t)buffer[0] | ((uint16_t)buffer[1] << 8);
+ dev_dbg(&ltr559->i2c_client->dev,
+ "%s | ps value = 0x%04X\n", __func__,
+ ps_val);
+
+ if (ltr559->mode == 1) {
+ if (ps_val > PS_MAX_MEASURE_VAL) {
+ dev_err(&ltr559->i2c_client->dev,
+ "%s: PS Value Error: 0x%X\n", __func__,
+ ps_val);
+ }
+ ps_val &= PS_VALID_MEASURE_MASK;
+ } else if (ltr559->mode == 3) {
+ ps_val &= 0x87FF;
+ }
+
+ value = ps_val;
+
+ break;
+
+ }
+
+ return value;
+}
+
+static int8_t als_mode_setup (uint8_t alsMode_set_reset, struct ltr559_data *ltr559)
+{
+ int8_t ret = 0;
+
+ ret = _ltr559_set_bit(ltr559->i2c_client, alsMode_set_reset, LTR559_ALS_CONTR, ALS_MODE_ACTIVE);
+ if (ret < 0) {
+ dev_err(&ltr559->i2c_client->dev, "%s ALS mode setup fail...\n", __func__);
+ return ret;
+ }
+
+ return ret;
+}
+
+static int8_t als_contr_setup(uint8_t als_contr_val, struct ltr559_data *ltr559)
+{
+ int8_t ret = 0;
+ uint8_t buffer[3];
+
+ buffer[0] = LTR559_ALS_CONTR;
+
+ /* Default settings used for now. */
+ buffer[1] = als_contr_val;
+ buffer[1] &= 0x1F;
+ ret = I2C_Write(buffer, 2);
+ if (ret < 0) {
+ dev_err(&ltr559->i2c_client->dev, "%s | ALS_CONTR (0x%02X) setup fail...", __func__, buffer[0]);
+ }
+
+ return ret;
+}
+
+
+static int8_t als_contr_readback (uint8_t rdbck_type, uint8_t *retVal, struct ltr559_data *ltr559)
+{
+ int8_t ret = 0;
+ uint8_t buffer[2], value;
+
+ buffer[0] = LTR559_ALS_CONTR;
+ ret = I2C_Read(buffer, 1);
+ if (ret < 0) {
+ dev_err(&ltr559->i2c_client->dev, "%s | 0x%02X", __func__, buffer[0]);
+ return ret;
+ }
+
+ value = buffer[0];
+
+ if (rdbck_type == ALS_MODE_RDBCK) {
+ *retVal = value & 0x01;
+ } else if (rdbck_type == ALS_SWRT_RDBCK) {
+ *retVal = (value & 0x02) >> 1;
+ } else if (rdbck_type == ALS_GAIN_RDBCK) {
+ *retVal = (value & 0x1C) >> 2;
+ } else if (rdbck_type == ALS_CONTR_RDBCK) {
+ *retVal = value & 0x1F;
+ }
+
+ return ret;
+}
+
+static int8_t ps_mode_setup (uint8_t psMode_set_reset, struct ltr559_data *ltr559)
+{
+ int8_t ret = 0;
+
+ ret = _ltr559_set_bit(ltr559->i2c_client, psMode_set_reset, LTR559_PS_CONTR, PS_MODE_ACTIVE);
+ if (ret < 0) {
+ dev_err(&ltr559->i2c_client->dev, "%s PS mode setup fail...\n", __func__);
+ return ret;
+ }
+
+ return ret;
+}
+
+static int8_t ps_contr_setup(uint8_t ps_contr_val, struct ltr559_data *ltr559)
+{
+ int8_t ret = 0;
+ uint8_t buffer[3];
+
+ buffer[0] = LTR559_PS_CONTR;
+
+ /* Default settings used for now. */
+ buffer[1] = ps_contr_val;
+ buffer[1] &= 0x2F;
+ ret = I2C_Write(buffer, 2);
+ if (ret < 0) {
+ dev_err(&ltr559->i2c_client->dev, "%s | PS_CONTR (0x%02X) setup fail...", __func__, buffer[0]);
+ }
+
+ return ret;
+}
+
+
+static int8_t ps_contr_readback (uint8_t rdbck_type, uint8_t *retVal, struct ltr559_data *ltr559)
+{
+ int8_t ret = 0;
+ uint8_t buffer[2], value;
+
+ buffer[0] = LTR559_PS_CONTR;
+ ret = I2C_Read(buffer, 1);
+ if (ret < 0) {
+ dev_err(&ltr559->i2c_client->dev, "%s | 0x%02X", __func__, buffer[0]);
+ return ret;
+ }
+
+ value = buffer[0];
+
+ if (rdbck_type == PS_MODE_RDBCK) {
+ *retVal = (value & 0x03);
+ } else if (rdbck_type == PS_GAIN_RDBCK) {
+ *retVal = (value & 0x0C) >> 2;
+ } else if (rdbck_type == PS_SATUR_RDBCK) {
+ *retVal = (value & 0x20) >> 5;
+ } else if (rdbck_type == PS_CONTR_RDBCK) {
+ *retVal = value & 0x2F;
+ }
+
+ return ret;
+}
+
+
+/* LED Setup */
+static int8_t ps_led_setup(uint8_t ps_led_val, struct ltr559_data *ltr559)
+{
+ int8_t ret = 0;
+ uint8_t buffer[3];
+
+ buffer[0] = LTR559_PS_LED;
+
+ /* Default settings used for now. */
+ buffer[1] = ps_led_val;
+ ret = I2C_Write(buffer, 2);
+ if (ret < 0) {
+ dev_err(&ltr559->i2c_client->dev, "%s | PS_LED (0x%02X) setup fail...", __func__, buffer[0]);
+ }
+
+ return ret;
+}
+
+static int8_t ps_ledPulseCount_setup(uint8_t pspulsecount_val, struct ltr559_data *ltr559)
+{
+ int8_t ret = 0;
+ uint8_t buffer[3];
+
+ buffer[0] = LTR559_PS_N_PULSES;
+
+ /* Default settings used for now. */
+ if (pspulsecount_val > 15) {
+ pspulsecount_val = 15;
+ }
+ buffer[1] = pspulsecount_val;
+ buffer[1] &= 0x0F;
+ ret = I2C_Write(buffer, 2);
+ if (ret < 0) {
+ dev_err(&ltr559->i2c_client->dev, "%s | PS_LED_COUNT (0x%02X) setup fail...", __func__, buffer[0]);
+ }
+
+ return ret;
+}
+
+static int8_t ps_meas_rate_setup(uint16_t meas_rate_val, struct ltr559_data *ltr559)
+{
+ int8_t ret = 0;
+ uint8_t buffer[2], value;
+
+ buffer[0] = LTR559_PS_MEAS_RATE;
+ ret = I2C_Read(buffer, 1);
+ if (ret < 0) {
+ dev_err(&ltr559->i2c_client->dev, "%s | 0x%02X", __func__, buffer[0]);
+ return ret;
+ }
+
+ value = buffer[0];
+ value &= 0xF0;
+
+ if (meas_rate_val == 50) {
+ value |= PS_MEAS_RPT_RATE_50MS;
+ } else if (meas_rate_val == 70) {
+ value |= PS_MEAS_RPT_RATE_70MS;
+ } else if (meas_rate_val == 100) {
+ value |= PS_MEAS_RPT_RATE_100MS;
+ } else if (meas_rate_val == 200) {
+ value |= PS_MEAS_RPT_RATE_200MS;
+ } else if (meas_rate_val == 500) {
+ value |= PS_MEAS_RPT_RATE_500MS;
+ } else if (meas_rate_val == 1000) {
+ value |= PS_MEAS_RPT_RATE_1000MS;
+ } else if (meas_rate_val == 2000) {
+ value |= PS_MEAS_RPT_RATE_2000MS;
+ } else if (meas_rate_val == 10) {
+ value |= PS_MEAS_RPT_RATE_10MS;
+ }
+
+ buffer[0] = LTR559_PS_MEAS_RATE;
+ buffer[1] = value;
+ ret = I2C_Write(buffer, 2);
+ if (ret < 0) {
+ dev_err(&ltr559->i2c_client->dev, "%s PS measurement rate setup fail...\n", __func__);
+ return ret;
+ }
+
+ return ret;
+}
+
+static int8_t als_meas_rate_reg_setup(uint8_t als_meas_rate_reg_val, struct ltr559_data *ltr559)
+{
+ int8_t ret = 0;
+ uint8_t buffer[3];
+
+ buffer[0] = LTR559_ALS_MEAS_RATE;
+
+ buffer[1] = als_meas_rate_reg_val;
+ buffer[1] &= 0x3F;
+ ret = I2C_Write(buffer, 2);
+ if (ret < 0) {
+ dev_err(&ltr559->i2c_client->dev, "%s | ALS_MEAS_RATE (0x%02X) setup fail...", __func__, buffer[0]);
+ }
+
+ return ret;
+}
+
+static int8_t part_ID_reg_readback (uint8_t rdbck_type, uint8_t *retVal, struct ltr559_data *ltr559)
+{
+ int8_t ret = 0;
+ uint8_t buffer[1], value;
+
+ buffer[0] = LTR559_PART_ID;
+ ret = I2C_Read(buffer, 1);
+ if (ret < 0) {
+ dev_err(&ltr559->i2c_client->dev, "%s | 0x%02X", __func__, buffer[0]);
+ return ret;
+ }
+
+ value = buffer[0];
+
+ if (rdbck_type == PART_NUM_ID_RDBCK) {
+ *retVal = (value & 0xF0) >> 4;
+ } else if (rdbck_type == REVISION_ID_RDBCK) {
+ *retVal = value & 0x0F;
+ } else if (rdbck_type == PART_ID_REG_RDBCK) {
+ *retVal = value;
+ }
+
+ return ret;
+}
+
+
+static int8_t manu_ID_reg_readback (uint8_t *retVal, struct ltr559_data *ltr559)
+{
+ int8_t ret = 0;
+ uint8_t buffer[1], value;
+
+ buffer[0] = LTR559_MANUFACTURER_ID;
+ ret = I2C_Read(buffer, 1);
+ if (ret < 0) {
+ dev_err(&ltr559->i2c_client->dev, "%s | 0x%02X", __func__, buffer[0]);
+ return ret;
+ }
+
+ value = buffer[0];
+ *retVal = value;
+
+ return ret;
+}
+
+
+static int8_t als_ps_status_reg (uint8_t data_status_type, uint8_t *retVal, struct ltr559_data *ltr559)
+{
+ int8_t ret = 0;
+ uint8_t buffer[2], value;
+
+ buffer[0] = LTR559_ALS_PS_STATUS;
+ ret = I2C_Read(buffer, 1);
+ if (ret < 0) {
+ dev_err(&ltr559->i2c_client->dev, "%s | 0x%02X", __func__, buffer[0]);
+ return ret;
+ }
+
+ value = buffer[0];
+
+ if (data_status_type == PS_DATA_STATUS_RDBCK) {
+ *retVal = (value & 0x01);
+ } else if (data_status_type == PS_INTERR_STATUS_RDBCK) {
+ *retVal = (value & 0x02) >> 1;
+ } else if (data_status_type == ALS_DATA_STATUS_RDBCK) {
+ *retVal = (value & 0x04) >> 2;
+ } else if (data_status_type == ALS_INTERR_STATUS_RDBCK) {
+ *retVal = (value & 0x08) >> 3;
+ } else if (data_status_type == ALS_GAIN_STATUS_RDBCK) {
+ *retVal = (value & 0x70) >> 4;
+ } else if (data_status_type == ALS_VALID_STATUS_RDBCK) {
+ *retVal = (value & 0x80) >> 7;
+ } else if (data_status_type == ALS_PS_STATUS_RDBCK) {
+ *retVal = value;
+ }
+
+ return ret;
+}
+
+/* Set ALS range */
+static int8_t set_als_range(uint16_t lt, uint16_t ht, uint8_t lo_hi)
+{
+ int8_t ret;
+ uint8_t buffer[5], num_data = 0;
+
+ if (lo_hi == LO_LIMIT) {
+ buffer[0] = LTR559_ALS_THRES_LOW_0;
+ buffer[1] = lt & 0xFF;
+ buffer[2] = (lt >> 8) & 0xFF;
+ num_data = 3;
+ } else if (lo_hi == HI_LIMIT) {
+ buffer[0] = LTR559_ALS_THRES_UP_0;
+ buffer[1] = ht & 0xFF;
+ buffer[2] = (ht >> 8) & 0xFF;
+ num_data = 3;
+ } else if (lo_hi == LO_N_HI_LIMIT) {
+ buffer[0] = LTR559_ALS_THRES_UP_0;
+ buffer[1] = ht & 0xFF;
+ buffer[2] = (ht >> 8) & 0xFF;
+ buffer[3] = lt & 0xFF;
+ buffer[4] = (lt >> 8) & 0xFF;
+ num_data = 5;
+ }
+
+ ret = I2C_Write(buffer, num_data);
+ if (ret <0) {
+ pr_alert("%s | 0x%02X", __func__, buffer[0]);
+ return ret;
+ }
+ dev_dbg(&sensor_info->i2c_client->dev, "%s Set als range:0x%04x"
+ " - 0x%04x\n", __func__, lt, ht);
+
+ return ret;
+}
+
+
+static int8_t als_range_readback (uint16_t *lt, uint16_t *ht, struct ltr559_data *ltr559)
+{
+ int8_t ret = 0;
+ uint8_t buffer[5];
+ uint16_t value_lo, value_hi;
+
+ buffer[0] = LTR559_ALS_THRES_UP_0;
+ ret = I2C_Read(buffer, 4);
+ if (ret < 0) {
+ dev_err(&ltr559->i2c_client->dev, "%s | 0x%02X", __func__, buffer[0]);
+ return ret;
+ }
+
+ value_lo = buffer[3];
+ value_lo <<= 8;
+ value_lo += buffer[2];
+ *lt = value_lo;
+
+ value_hi = buffer[1];
+ value_hi <<= 8;
+ value_hi += buffer[0];
+ *ht = value_hi;
+
+ return ret;
+}
+
+
+/* Set PS range */
+static int8_t set_ps_range(uint16_t lt, uint16_t ht, uint8_t lo_hi)
+{
+ int8_t ret;
+ uint8_t buffer[5], num_data = 0;
+
+ if (lo_hi == LO_LIMIT) {
+ buffer[0] = LTR559_PS_THRES_LOW_0;
+ buffer[1] = lt & 0xFF;
+ buffer[2] = (lt >> 8) & 0x07;
+ num_data = 3;
+ } else if (lo_hi == HI_LIMIT) {
+ buffer[0] = LTR559_PS_THRES_UP_0;
+ buffer[1] = ht & 0xFF;
+ buffer[2] = (ht >> 8) & 0x07;
+ num_data = 3;
+ } else if (lo_hi == LO_N_HI_LIMIT) {
+ buffer[0] = LTR559_PS_THRES_UP_0;
+ buffer[1] = ht & 0xFF;
+ buffer[2] = (ht >> 8) & 0x07;
+ buffer[3] = lt & 0xFF;
+ buffer[4] = (lt >> 8) & 0x07;
+ num_data = 5;
+ }
+
+ ret = I2C_Write(buffer, num_data);
+ if (ret <0) {
+ pr_alert("%s | 0x%02X", __func__, buffer[0]);
+ return ret;
+ }
+ dev_dbg(&sensor_info->i2c_client->dev, "%s Set ps range:0x%04x"
+ " - 0x%04x\n", __func__, lt, ht);
+
+ return ret;
+}
+
+
+static int8_t ps_range_readback (uint16_t *lt, uint16_t *ht, struct ltr559_data *ltr559)
+{
+ int8_t ret = 0;
+ uint8_t buffer[5];
+ uint16_t value_lo, value_hi;
+
+ buffer[0] = LTR559_PS_THRES_UP_0;
+ ret = I2C_Read(buffer, 4);
+ if (ret < 0) {
+ dev_err(&ltr559->i2c_client->dev, "%s | 0x%02X", __func__, buffer[0]);
+ return ret;
+ }
+
+ value_lo = buffer[3];
+ value_lo <<= 8;
+ value_lo += buffer[2];
+ *lt = value_lo;
+
+ value_hi = buffer[1];
+ value_hi <<= 8;
+ value_hi += buffer[0];
+ *ht = value_hi;
+
+ return ret;
+}
+
+
+//(Linux RTOS)>
+/* Report PS input event */
+static void report_ps_input_event(struct ltr559_data *ltr559)
+{
+ //int8_t ret;
+ uint16_t adc_value;
+ //int thresh_hi, thresh_lo, thresh_delta;
+
+ ltr559->mode = PS;
+ adc_value = read_adc_value (ltr559);
+
+ if (adc_value > ps_set_highthresh){
+ ltr559->ps_direction = 0;//1; //far to near
+ /*
+ ret = set_ps_range(PS_SET_LOWTHRESH, PS_MAX_MEASURE_VAL, LO_N_HI_LIMIT);
+ if (ret < 0) {
+ dev_err(&ltr559->i2c_client->dev, "%s : PS thresholds setting Fail...\n", __func__);
+ }*/
+ }else if (adc_value < ps_set_lowthresh){
+ ltr559->ps_direction = 1;//0; //near to far
+ /*
+ ret = set_ps_range(0, PS_SET_HIGHTHRESH, LO_N_HI_LIMIT);
+ if (ret < 0) {
+ dev_err(&ltr559->i2c_client->dev, "%s : PS thresholds setting Fail...\n", __func__);
+ }*/
+ }
+ //printk("%s,adc_val:%d,hithresh:%d,lowthresh:%d,report_val:%d\n",__func__,
+ // adc_value,ps_set_highthresh,ps_set_lowthresh, ltr559->ps_direction);
+ input_report_abs(ltr559->ps_input_dev, ABS_DISTANCE, ltr559->ps_direction);
+ input_sync(ltr559->ps_input_dev);
+
+ //input_report_abs(ltr559->ps_input_dev, ABS_DISTANCE, adc_value);
+ //input_sync(ltr559->ps_input_dev);
+
+ /* Adjust measurement range using a crude filter to prevent interrupt jitter */
+ /*
+ thresh_delta = (adc_value >> 10)+2;
+ thresh_lo = adc_value - thresh_delta;
+ thresh_hi = adc_value + thresh_delta;
+ if (thresh_lo < PS_MIN_MEASURE_VAL) {
+ thresh_lo = PS_MIN_MEASURE_VAL;
+ }
+ if (thresh_hi > PS_MAX_MEASURE_VAL) {
+ thresh_hi = PS_MAX_MEASURE_VAL;
+ }
+
+ ret = set_ps_range((uint16_t)thresh_lo, (uint16_t)thresh_hi, LO_N_HI_LIMIT);
+ if (ret < 0) {
+ dev_err(&ltr559->i2c_client->dev, "%s : PS thresholds setting Fail...\n", __func__);
+ }
+ */
+
+
+
+}
+
+
+/* Report ALS input event */
+static void report_als_input_event(struct ltr559_data *ltr559)
+{
+ int8_t ret;
+ uint16_t adc_value;
+ int thresh_hi, thresh_lo, thresh_delta;
+
+ ltr559->mode = ALS;
+ adc_value = read_adc_value (ltr559);
+ input_report_abs(ltr559->als_input_dev, ABS_MISC, adc_value);
+ input_sync(ltr559->als_input_dev);
+
+ /* Adjust measurement range using a crude filter to prevent interrupt jitter */
+ thresh_delta = (adc_value >> 12)+2;
+ thresh_lo = adc_value - thresh_delta;
+ thresh_hi = adc_value + thresh_delta;
+ if (thresh_lo < ALS_MIN_MEASURE_VAL) {
+ thresh_lo = ALS_MIN_MEASURE_VAL;
+ }
+ if (thresh_hi > ALS_MAX_MEASURE_VAL) {
+ thresh_hi = ALS_MAX_MEASURE_VAL;
+ }
+
+ ret = set_als_range((uint16_t)thresh_lo, (uint16_t)thresh_hi, LO_N_HI_LIMIT);
+ if (ret < 0) {
+ dev_err(&ltr559->i2c_client->dev, "%s : ALS thresholds setting Fail...\n", __func__);
+ }
+}
+
+
+/* Work when interrupt */
+static void ltr559_schedwork(struct work_struct *work)
+{
+ int8_t ret;
+ uint8_t status, i_ctr = 0;
+ uint8_t interrupt_stat, newdata;
+ struct ltr559_data *ltr559 = sensor_info;
+ uint8_t buffer[2], buf[40];
+
+ buffer[0] = LTR559_ALS_PS_STATUS;
+ ret = I2C_Read(buffer, 1);
+ if (ret < 0) {
+ dev_err(&ltr559->i2c_client->dev, "%s | 0x%02X", __func__, buffer[0]);
+ return;
+ }
+ status = buffer[0];
+ interrupt_stat = status & 0x0A;
+ newdata = status & 0x05;
+
+ if (!interrupt_stat) {
+ /* there is an interrupt with no work to do */
+ dev_info(&ltr559->i2c_client->dev,"%s Unexpected received interrupt with no work to do status:0x%02x\n", __func__, status);
+ buf[0] = 0x80;
+ I2C_Read(buf, sizeof(buf));
+ for (i_ctr = 0; i_ctr < sizeof(buf); i_ctr++) {
+ dev_info(&ltr559->i2c_client->dev, "%s reg:0x%02x val:0x%02x\n", __func__, 0x80+i_ctr, buf[i_ctr]);
+ }
+ } else {
+ // PS interrupt and PS with new data
+ if ((interrupt_stat & 0x02) && (newdata & 0x01)) {
+ ltr559->ps_irq_flag = 1;
+ report_ps_input_event(ltr559);
+ }
+
+ // ALS interrupt and ALS with new data
+ if ((interrupt_stat & 0x08) && (newdata & 0x04)) {
+ ltr559->als_irq_flag = 1;
+ report_als_input_event(ltr559);
+ }
+ }
+ enable_irq(ltr559->irq);
+}
+
+static DECLARE_WORK(irq_workqueue, ltr559_schedwork);
+
+
+/* IRQ Handler */
+static irqreturn_t ltr559_irq_handler(int irq, void *data)
+{
+ struct ltr559_data *ltr559 = data;
+
+ /* disable an irq without waiting */
+ disable_irq_nosync(ltr559->irq);
+
+ schedule_work(&irq_workqueue);
+
+ return IRQ_HANDLED;
+}
+
+
+#if 1
+static int ltr559_gpio_irq(struct ltr559_data *ltr559)
+{
+ int rc = 0;
+
+ rc = gpio_request(ltr559->gpio_int_no, DEVICE_NAME);
+ if (rc < 0) {
+ dev_err(&ltr559->i2c_client->dev,"%s: GPIO %d Request Fail (%d)\n", __func__, ltr559->gpio_int_no, rc);
+ return rc;
+ }
+
+ gpio_tlmm_config(GPIO_CFG(ltr559->gpio_int_no,0,GPIO_CFG_INPUT, GPIO_CFG_NO_PULL,GPIO_CFG_2MA), GPIO_CFG_ENABLE);
+ rc = gpio_direction_input(ltr559->gpio_int_no);
+ if (rc < 0) {
+ dev_err(&ltr559->i2c_client->dev, "%s: Set GPIO %d as Input Fail (%d)\n", __func__, ltr559->gpio_int_no, rc);
+ goto out1;
+ }
+
+ /* Configure an active low trigger interrupt for the device */
+ rc = request_irq(ltr559->irq, ltr559_irq_handler, IRQF_TRIGGER_LOW, DEVICE_NAME, ltr559);
+ if (rc < 0) {
+ dev_err(&ltr559->i2c_client->dev, "%s: Request IRQ (%d) for GPIO %d Fail (%d)\n", __func__, ltr559->irq,
+ ltr559->gpio_int_no, rc);
+ goto out1;
+ }
+
+ return rc;
+
+out1:
+ gpio_free(ltr559->gpio_int_no);
+
+ return rc;
+}
+#endif
+//(Linux RTOS)<
+
+
+/* PS Enable */
+static int8_t ps_device_init(struct ltr559_data *ltr559)
+{
+ int8_t rc = 0;
+
+ if (ltr559->ps_enable_flag) {
+ dev_info(&ltr559->i2c_client->dev, "%s: already enabled\n", __func__);
+ return 0;
+ }
+
+ /* Set thresholds*/
+ rc = set_ps_range(PS_SET_LOWTHRESH, PS_SET_HIGHTHRESH, LO_N_HI_LIMIT);
+ if (rc < 0) {
+ dev_err(&ltr559->i2c_client->dev, "%s : PS Thresholds Write Fail...\n", __func__);
+ return rc;
+ }
+
+ //(Linux RTOS)>
+#if 0
+ /* Allows this interrupt to wake the system */
+ //rc = irq_set_irq_wake(ltr559->irq, 1);
+ rc = set_irq_wake(ltr559->irq, 1);
+ if (rc < 0) {
+ dev_err(&ltr559->i2c_client->dev, "%s: IRQ-%d WakeUp Enable Fail...\n", __func__, ltr559->irq);
+ return rc;
+ }
+#endif
+ //(Linux RTOS)<
+
+ rc = ps_led_setup(0x7F, ltr559);
+ if (rc < 0) {
+ dev_err(&ltr559->i2c_client->dev, "%s: PS LED Setup Fail...\n", __func__);
+ return rc;
+ }
+
+ rc = ps_ledPulseCount_setup(0x08, ltr559);
+ if (rc < 0) {
+ dev_err(&ltr559->i2c_client->dev, "%s: PS LED pulse count setup Fail...\n", __func__);
+ }
+
+ rc = ps_meas_rate_setup(100, ltr559);
+ if (rc < 0) {
+ dev_err(&ltr559->i2c_client->dev, "%s: PS MeasRate Setup Fail...\n", __func__);
+ return rc;
+ }
+
+ return rc;
+}
+
+/*ps enable*/
+static int8_t ltr559_ps_enable(struct ltr559_data *ltr559)
+{
+ int8_t rc = 0;
+ uint8_t buffer[1];
+
+ if (ltr559->ps_enable_flag) {
+ //dev_info(&ltr559->i2c_client->dev, "%s: already enabled\n", __func__);
+ return 0;
+ }
+
+ rc = ps_contr_setup(0x03, ltr559);
+ if (rc < 0) {
+ dev_err(&ltr559->i2c_client->dev, "%s: PS Enable Fail...\n", __func__);
+ return rc;
+ }
+ buffer[0] = LTR559_PS_CONTR;
+ rc = I2C_Read(buffer, 1);
+ //printk("PS Enable Statte, 0x81 = %d...\n", buffer[0]);
+
+ ltr559->ps_enable_flag = 1;
+ wake_lock(&(ltr559->ps_wake_lock));
+
+ return rc;
+}
+
+
+/* ps disable */
+static int8_t ps_disable(struct ltr559_data *ltr559)
+{
+ int8_t rc = 0;
+
+ if (ltr559->ps_enable_flag == 0) {
+ //dev_info(&ltr559->i2c_client->dev, "%s: already disabled\n", __func__);
+ return 0;
+ }
+
+ //(Linux RTOS)>
+#if 0
+ /* Don't allow this interrupt to wake the system anymore */
+ //rc = irq_set_irq_wake(ltr559->irq, 0);
+ rc = set_irq_wake(ltr559->irq, 0);
+ if (rc < 0) {
+ dev_err(&ltr559->i2c_client->dev, "%s: IRQ-%d WakeUp Disable Fail...\n", __func__, ltr559->irq);
+ return rc;
+ }
+#endif
+ //(Linux RTOS)<
+
+ //rc = _ltr559_set_bit(ltr559->i2c_client, CLR_BIT, LTR559_PS_CONTR, PS_MODE);
+ rc = ps_mode_setup(CLR_BIT, ltr559);
+ if (rc < 0) {
+ dev_err(&ltr559->i2c_client->dev, "%s: PS Disable Fail...\n", __func__);
+ return rc;
+ }
+
+ ltr559->ps_enable_flag = 0;
+ wake_unlock(&(ltr559->ps_wake_lock));
+
+ return rc;
+}
+
+
+/* PS open fops */
+ssize_t ps_open(struct inode *inode, struct file *file)
+{
+ struct ltr559_data *ltr559 = sensor_info;
+
+ if (ltr559->ps_opened)
+ return -EBUSY;
+
+ ltr559->ps_opened = 1;
+
+ return 0;
+}
+
+
+/* PS release fops */
+ssize_t ps_release(struct inode *inode, struct file *file)
+{
+ struct ltr559_data *ltr559 = sensor_info;
+
+ ltr559->ps_opened = 0;
+
+ return ps_disable(ltr559);
+}
+
+
+/* PS IOCTL */
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,35))
+static int ps_ioctl (struct inode *ino, struct file *file, unsigned int cmd, unsigned long arg)
+#else
+static long ps_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+#endif
+{
+ int rc = 0, val = 0;
+ struct ltr559_data *ltr559 = sensor_info;
+
+ pr_info("%s cmd %d\n", __func__, _IOC_NR(cmd));
+
+ switch (cmd) {
+ case LTR559_IOCTL_PS_ENABLE:
+ if (get_user(val, (unsigned long __user *)arg)) {
+ rc = -EFAULT;
+ break;
+ }
+ pr_info("%s value = %d\n", __func__, val);
+ rc = val ? ltr559_ps_enable(ltr559) : ps_disable(ltr559);
+
+ break;
+ case LTR559_IOCTL_PS_GET_ENABLED:
+ rc = put_user(ltr559->ps_enable_flag, (unsigned long __user *)arg);
+
+ break;
+ default:
+ pr_err("%s: INVALID COMMAND %d\n", __func__, _IOC_NR(cmd));
+ rc = -EINVAL;
+ }
+
+ return rc;
+}
+
+static const struct file_operations ps_fops = {
+ .owner = THIS_MODULE,
+ .open = ps_open,
+ .release = ps_release,
+ #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,35))
+ .ioctl = ps_ioctl
+ #else
+ .unlocked_ioctl = ps_ioctl
+ #endif
+};
+
+struct miscdevice ps_misc = {
+ .minor = MISC_DYNAMIC_MINOR,
+ .name = "ltr559_ps",
+ .fops = &ps_fops
+};
+
+
+static int8_t als_device_init(struct ltr559_data *ltr559)
+{
+ int8_t rc = 0;
+
+ rc = als_meas_rate_reg_setup(0x03, ltr559);
+ if (rc < 0) {
+ dev_err(&ltr559->i2c_client->dev, "%s: ALS_Meas_Rate register Setup Fail...\n", __func__);
+ return rc;
+ }
+
+ /* Set minimummax thresholds where interrupt will *not* be generated */
+ //rc = set_als_range(ALS_MIN_MEASURE_VAL, ALS_MAX_MEASURE_VAL, LO_N_HI_LIMIT);
+ rc = set_als_range(ALS_MIN_MEASURE_VAL, ALS_MIN_MEASURE_VAL, LO_N_HI_LIMIT);
+ if (rc < 0) {
+ dev_err(&ltr559->i2c_client->dev, "%s : ALS Thresholds Write Fail...\n", __func__);
+ return rc;
+ }
+ return rc;
+}
+
+//als enable
+static int8_t ltr559_als_enable(struct ltr559_data *ltr559)
+{
+ int8_t rc = 0;
+ uint8_t buffer[1];
+
+ /* if device not enabled, enable it */
+ if (ltr559->als_enable_flag) {
+ //dev_err(&ltr559->i2c_client->dev, "%s: ALS already enabled...\n", __func__);
+ return rc;
+ }
+ rc = als_contr_setup(0x0D, ltr559);
+ if (rc < 0) {
+ dev_err(&ltr559->i2c_client->dev, "%s: ALS Enable Fail...\n", __func__);
+ return rc;
+ }
+ buffer[0] = LTR559_ALS_CONTR;
+ rc = I2C_Read(buffer, 1);
+ //printk("ALS Enable Statte, 0x80 = %d...\n", buffer[0]);
+
+ ltr559->als_enable_flag = 1;
+
+ return rc;
+}
+
+
+static int8_t als_disable(struct ltr559_data *ltr559)
+{
+ int8_t rc = 0;
+
+ if (ltr559->als_enable_flag == 0) {
+ //dev_err(&ltr559->i2c_client->dev, "%s : ALS already disabled...\n", __func__);
+ return rc;
+ }
+
+ //rc = _ltr559_set_bit(ltr559->i2c_client, CLR_BIT, LTR559_ALS_CONTR, ALS_MODE);
+ rc = als_mode_setup(CLR_BIT, ltr559);
+ if (rc < 0) {
+ dev_err(&ltr559->i2c_client->dev,"%s: ALS Disable Fail...\n", __func__);
+ return rc;
+ }
+ ltr559->als_enable_flag = 0;
+
+ return rc;
+}
+
+
+ssize_t als_open(struct inode *inode, struct file *file)
+{
+ struct ltr559_data *ltr559 = sensor_info;
+ int8_t rc = 0;
+
+ if (ltr559->als_opened) {
+ dev_err(&ltr559->i2c_client->dev, "%s: ALS already Opened...\n", __func__);
+ rc = -EBUSY;
+ }
+ ltr559->als_opened = 1;
+
+ return rc;
+}
+
+
+ssize_t als_release(struct inode *inode, struct file *file)
+{
+ struct ltr559_data *ltr559 = sensor_info;
+
+ ltr559->als_opened = 0;
+
+ //return 0;
+ return als_disable(ltr559);
+}
+
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,35))
+static int als_ioctl (struct inode *ino, struct file *file, unsigned int cmd, unsigned long arg)
+#else
+static long als_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+#endif
+{
+ int rc = 0, val = 0;
+ struct ltr559_data *ltr559 = sensor_info;
+
+ pr_debug("%s cmd %d\n", __func__, _IOC_NR(cmd));
+
+ switch (cmd) {
+ case LTR559_IOCTL_ALS_ENABLE:
+ if (get_user(val, (unsigned long __user *)arg)) {
+ rc = -EFAULT;
+ break;
+ }
+ /*pr_info("%s value = %d\n", __func__, val);*/
+ rc = val ? ltr559_als_enable(ltr559) : als_disable(ltr559);
+
+ break;
+ case LTR559_IOCTL_ALS_GET_ENABLED:
+ val = ltr559->als_enable_flag;
+ /*pr_info("%s enabled %d\n", __func__, val);*/
+ rc = put_user(val, (unsigned long __user *)arg);
+
+ break;
+ default:
+ pr_err("%s: INVALID COMMAND %d\n", __func__, _IOC_NR(cmd));
+ rc = -EINVAL;
+ }
+
+ return rc;
+}
+
+
+static const struct file_operations als_fops = {
+ .owner = THIS_MODULE,
+ .open = als_open,
+ .release = als_release,
+ #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,35))
+ .ioctl = als_ioctl
+ #else
+ .unlocked_ioctl = als_ioctl
+ #endif
+};
+
+static struct miscdevice als_misc = {
+ .minor = MISC_DYNAMIC_MINOR,
+ .name = "ltr559_ls",
+ .fops = &als_fops
+};
+
+
+static ssize_t als_adc_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ uint16_t value;
+ int ret;
+ struct ltr559_data *ltr559 = sensor_info;
+
+ ltr559->mode = ALS;
+ value = read_adc_value(ltr559);
+ //ret = sprintf(buf, "%d\n", value);
+ ret = sprintf(buf, "%d", value);
+
+ return ret;
+}
+
+static DEVICE_ATTR(als_adc, 0444, als_adc_show, NULL);
+
+
+static ssize_t ps_adc_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ uint16_t value;
+ int ret;
+ struct ltr559_data *ltr559 = sensor_info;
+
+ ltr559->mode = PS;
+ value = read_adc_value(ltr559);
+ //ret = sprintf(buf, "%d\n", value);
+ ret = sprintf(buf, "%d", value);
+
+ return ret;
+}
+
+static DEVICE_ATTR(ps_adc, 0444, ps_adc_show, NULL);
+
+static ssize_t alscontrsetup_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ int8_t ret = 0;
+ uint8_t rdback_val = 0;
+ struct ltr559_data *ltr559 = sensor_info;
+
+ ret = als_contr_readback(ALS_CONTR_RDBCK, &rdback_val, ltr559);
+ if (ret < 0) {
+ dev_err(&ltr559->i2c_client->dev, "%s: ALS_CONTR_RDBCK Fail...\n", __func__);
+ return (-1);
+ }
+
+ ret = sprintf(buf, "%d\n", rdback_val);
+
+ return ret;
+}
+
+static ssize_t alscontrsetup_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+{
+ int8_t ret;
+ uint8_t param;
+ //int *param_temp = buf;
+ int param_temp[2];
+
+ struct ltr559_data *ltr559 = sensor_info;
+
+ //sscanf(buf, "%d", param_temp);
+ param_temp[0] = buf[0];
+ param_temp[1] = buf[1];
+
+ if (count <= 1) {
+ param_temp[0] = 48;
+ param_temp[1] = 48;
+ } else if (count == 2) {
+ param_temp[1] = param_temp[0];
+ param_temp[0] = 48;
+ }
+
+
+ if (param_temp[0] >= 65 && param_temp[0] <= 70) {
+ param_temp[0] -= 55;
+ } else if (param_temp[0] >= 97 && param_temp[0] <= 102) {
+ param_temp[0] -= 87;
+ } else if (param_temp[0] >= 48 && param_temp[0] <= 57) {
+ param_temp[0] -= 48;
+ } else {
+ param_temp[0] = 0;
+ }
+
+ if (param_temp[1] >= 65 && param_temp[1] <= 70) {
+ param_temp[1] -= 55;
+ } else if (param_temp[1] >= 97 && param_temp[1] <= 102) {
+ param_temp[1] -= 87;
+ } else if (param_temp[1] >= 48 && param_temp[1] <= 57) {
+ param_temp[1] -= 48;
+ } else {
+ param_temp[1] = 0;
+ }
+
+ param = ((param_temp[0] << 4) + (param_temp[1]));
+ dev_dbg(&ltr559->i2c_client->dev, "%s: store value = %d\n", __func__, param);
+
+ ret = als_contr_setup(param, ltr559);
+ if (ret < 0) {
+ dev_err(&ltr559->i2c_client->dev, "%s: ALS contr setup Fail...\n", __func__);
+ return (-1);
+ }
+
+ return count;
+}
+
+static DEVICE_ATTR(alscontrsetup, 0664, alscontrsetup_show, alscontrsetup_store);
+
+static ssize_t pscontrsetup_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ int8_t ret = 0;
+ uint8_t rdback_val = 0;
+ struct ltr559_data *ltr559 = sensor_info;
+
+ ret = ps_contr_readback(PS_CONTR_RDBCK, &rdback_val, ltr559);
+ if (ret < 0) {
+ dev_err(&ltr559->i2c_client->dev, "%s: PS_CONTR_RDBCK Fail...\n", __func__);
+ return (-1);
+ }
+
+ ret = sprintf(buf, "%d\n", rdback_val);
+
+ return ret;
+}
+
+
+static ssize_t pscontrsetup_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+{
+ int8_t ret;
+ uint8_t param;
+ //int *param_temp = buf;
+ int param_temp[2];
+
+ struct ltr559_data *ltr559 = sensor_info;
+
+ //sscanf(buf, "%d", param_temp);
+ param_temp[0] = buf[0];
+ param_temp[1] = buf[1];
+
+ if (count <= 1) {
+ param_temp[0] = 48;
+ param_temp[1] = 48;
+ } else if (count == 2) {
+ param_temp[1] = param_temp[0];
+ param_temp[0] = 48;
+ }
+
+ if (param_temp[0] >= 65 && param_temp[0] <= 70) {
+ param_temp[0] -= 55;
+ } else if (param_temp[0] >= 97 && param_temp[0] <= 102) {
+ param_temp[0] -= 87;
+ } else if (param_temp[0] >= 48 && param_temp[0] <= 57) {
+ param_temp[0] -= 48;
+ } else {
+ param_temp[0] = 0;
+ }
+
+ if (param_temp[1] >= 65 && param_temp[1] <= 70) {
+ param_temp[1] -= 55;
+ } else if (param_temp[1] >= 97 && param_temp[1] <= 102) {
+ param_temp[1] -= 87;
+ } else if (param_temp[1] >= 48 && param_temp[1] <= 57) {
+ param_temp[1] -= 48;
+ } else {
+ param_temp[1] = 0;
+ }
+
+ param = ((param_temp[0] << 4) + (param_temp[1]));
+ dev_dbg(&ltr559->i2c_client->dev, "%s: store value = %d\n", __func__, param);
+
+ ret = ps_contr_setup(param, ltr559);
+ if (ret < 0) {
+ dev_err(&ltr559->i2c_client->dev, "%s: PS contr setup Fail...\n", __func__);
+ return (-1);
+ }
+
+ return count;
+}
+
+static DEVICE_ATTR(pscontrsetup, 0664, pscontrsetup_show, pscontrsetup_store);
+
+static ssize_t partidreg_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ int8_t ret = 0;
+ uint8_t rdback_val = 0;
+ struct ltr559_data *ltr559 = sensor_info;
+
+ ret = part_ID_reg_readback(PART_ID_REG_RDBCK, &rdback_val, ltr559);
+ if (ret < 0) {
+ dev_err(&ltr559->i2c_client->dev, "%s: PART_ID_REG_RDBCK Fail...\n", __func__);
+ return (-1);
+ }
+
+ ret = sprintf(buf, "%d\n", rdback_val);
+
+ return ret;
+}
+
+static DEVICE_ATTR(partidreg, 0444, partidreg_show, NULL);
+
+
+static ssize_t manuid_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ int8_t ret = 0;
+ uint8_t rdback_val = 0;
+ struct ltr559_data *ltr559 = sensor_info;
+
+ ret = manu_ID_reg_readback(&rdback_val, ltr559);
+ if (ret < 0) {
+ dev_err(&ltr559->i2c_client->dev, "%s: Manufacturing ID readback Fail...\n", __func__);
+ return (-1);
+ }
+
+ ret = sprintf(buf, "%d\n", rdback_val);
+
+ return ret;
+}
+
+static DEVICE_ATTR(manuid, 0444, manuid_show, NULL);
+
+static ssize_t reg_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ int8_t ret = 0;
+ int i = 0;
+ uint8_t bufdata[1];
+ int count=0;
+
+ for(i = 0;i < 31 ;i++)
+ {
+ bufdata[0] = 0x80+i;
+ ret = I2C_Read(bufdata, 1);
+ count+= sprintf(buf+count,"[%x] = (%x)\n",0x80+i,bufdata[0]);
+ }
+
+ return count;
+}
+
+static DEVICE_ATTR(reg, 0444, reg_show, NULL);
+
+static ssize_t alspsstatusreg_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ int8_t ret = 0;
+ uint8_t rdback_val = 0;
+ struct ltr559_data *ltr559 = sensor_info;
+
+ ret = als_ps_status_reg(ALS_PS_STATUS_RDBCK, &rdback_val, ltr559);
+ if (ret < 0) {
+ dev_err(&ltr559->i2c_client->dev, "%s: ALS_PS_STATUS_RDBCK Fail...\n", __func__);
+ return (-1);
+ }
+
+ ret = sprintf(buf, "%d\n", rdback_val);
+
+ return ret;
+
+}
+
+static DEVICE_ATTR(alspsstatusreg, 0444, alspsstatusreg_show, NULL);
+
+static ssize_t setalslothrerange_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+{
+ int8_t ret;
+ int lo_thr = 0;
+ uint8_t param_temp[5];
+ struct ltr559_data *ltr559 = sensor_info;
+
+ param_temp[0] = buf[0];
+ param_temp[1] = buf[1];
+ param_temp[2] = buf[2];
+ param_temp[3] = buf[3];
+ param_temp[4] = buf[4];
+
+ if (count <= 1) {
+ param_temp[0] = 0;
+ param_temp[1] = 0;
+ param_temp[2] = 0;
+ param_temp[3] = 0;
+ param_temp[4] = 0;
+ } else if (count == 2) { // 1 digit
+ param_temp[0] -= 48;
+ param_temp[1] = 0;
+ param_temp[2] = 0;
+ param_temp[3] = 0;
+ param_temp[4] = 0;
+
+ param_temp[4] = param_temp[0];
+ param_temp[3] = 0;
+ param_temp[2] = 0;
+ param_temp[1] = 0;
+ param_temp[0] = 0;
+ } else if (count == 3) { // 2 digits
+ param_temp[0] -= 48;
+ param_temp[1] -= 48;
+ param_temp[2] = 0;
+ param_temp[3] = 0;
+ param_temp[4] = 0;
+
+ param_temp[4] = param_temp[1];
+ param_temp[3] = param_temp[0];
+ param_temp[2] = 0;
+ param_temp[1] = 0;
+ param_temp[0] = 0;
+ } else if (count == 4) { // 3 digits
+ param_temp[0] -= 48;
+ param_temp[1] -= 48;
+ param_temp[2] -= 48;
+ param_temp[3] = 0;
+ param_temp[4] = 0;
+
+ param_temp[4] = param_temp[2];
+ param_temp[3] = param_temp[1];
+ param_temp[2] = param_temp[0];
+ param_temp[1] = 0;
+ param_temp[0] = 0;
+ } else if (count == 5) { // 4 digits
+ param_temp[0] -= 48;
+ param_temp[1] -= 48;
+ param_temp[2] -= 48;
+ param_temp[3] -= 48;
+ param_temp[4] = 0;
+
+ param_temp[4] = param_temp[3];
+ param_temp[3] = param_temp[2];
+ param_temp[2] = param_temp[1];
+ param_temp[1] = param_temp[0];
+ param_temp[0] = 0;
+ } else if (count >= 6) { // 5 digits
+ param_temp[0] -= 48;
+ param_temp[1] -= 48;
+ param_temp[2] -= 48;
+ param_temp[3] -= 48;
+ param_temp[4] -= 48;
+ }
+
+ //for (i_ctr = 0; i_ctr < sizeof(param_temp); i_ctr++) {
+ // if ((param_temp[i_ctr] < 0) ||(param_temp[i_ctr] > 9)) {
+ // param_temp[i_ctr] = 0;
+ // }
+ //}
+
+ lo_thr = ((param_temp[0] * 10000) + (param_temp[1] * 1000) + (param_temp[2] * 100) + (param_temp[3] * 10) + param_temp[4]);
+ if (lo_thr > 65535) {
+ lo_thr = 65535;
+ }
+ dev_dbg(&ltr559->i2c_client->dev, "%s: store value = %d\n", __func__, lo_thr);
+
+ ret = set_als_range((uint16_t)lo_thr, 0, LO_LIMIT);
+ if (ret < 0) {
+ dev_err(&ltr559->i2c_client->dev, "%s: set ALS lo threshold Fail...\n", __func__);
+ return (-1);
+ }
+
+ return count;
+}
+
+static DEVICE_ATTR(setalslothrerange, 0660, NULL, setalslothrerange_store);
+
+
+static ssize_t setalshithrerange_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+{
+ int8_t ret;
+ int hi_thr = 0;
+ uint8_t param_temp[5];
+ struct ltr559_data *ltr559 = sensor_info;
+
+ param_temp[0] = buf[0];
+ param_temp[1] = buf[1];
+ param_temp[2] = buf[2];
+ param_temp[3] = buf[3];
+ param_temp[4] = buf[4];
+
+ if (count <= 1) {
+ param_temp[0] = 0;
+ param_temp[1] = 0;
+ param_temp[2] = 0;
+ param_temp[3] = 0;
+ param_temp[4] = 0;
+ } else if (count == 2) { // 1 digit
+ param_temp[0] -= 48;
+ param_temp[1] = 0;
+ param_temp[2] = 0;
+ param_temp[3] = 0;
+ param_temp[4] = 0;
+
+ param_temp[4] = param_temp[0];
+ param_temp[3] = 0;
+ param_temp[2] = 0;
+ param_temp[1] = 0;
+ param_temp[0] = 0;
+ } else if (count == 3) { // 2 digits
+ param_temp[0] -= 48;
+ param_temp[1] -= 48;
+ param_temp[2] = 0;
+ param_temp[3] = 0;
+ param_temp[4] = 0;
+
+ param_temp[4] = param_temp[1];
+ param_temp[3] = param_temp[0];
+ param_temp[2] = 0;
+ param_temp[1] = 0;
+ param_temp[0] = 0;
+ } else if (count == 4) { // 3 digits
+ param_temp[0] -= 48;
+ param_temp[1] -= 48;
+ param_temp[2] -= 48;
+ param_temp[3] = 0;
+ param_temp[4] = 0;
+
+ param_temp[4] = param_temp[2];
+ param_temp[3] = param_temp[1];
+ param_temp[2] = param_temp[0];
+ param_temp[1] = 0;
+ param_temp[0] = 0;
+ } else if (count == 5) { // 4 digits
+ param_temp[0] -= 48;
+ param_temp[1] -= 48;
+ param_temp[2] -= 48;
+ param_temp[3] -= 48;
+ param_temp[4] = 0;
+
+ param_temp[4] = param_temp[3];
+ param_temp[3] = param_temp[2];
+ param_temp[2] = param_temp[1];
+ param_temp[1] = param_temp[0];
+ param_temp[0] = 0;
+ } else if (count >= 6) { // 5 digits
+ param_temp[0] -= 48;
+ param_temp[1] -= 48;
+ param_temp[2] -= 48;
+ param_temp[3] -= 48;
+ param_temp[4] -= 48;
+ }
+
+ //for (i_ctr = 0; i_ctr < sizeof(param_temp); i_ctr++) {
+ // if ((param_temp[i_ctr] < 0) ||(param_temp[i_ctr] > 9)) {
+ // param_temp[i_ctr] = 0;
+ // }
+ //}
+
+ hi_thr = ((param_temp[0] * 10000) + (param_temp[1] * 1000) + (param_temp[2] * 100) + (param_temp[3] * 10) + param_temp[4]);
+ if (hi_thr > 65535) {
+ hi_thr = 65535;
+ }
+ dev_dbg(&ltr559->i2c_client->dev, "%s: store value = %d\n", __func__, hi_thr);
+
+ ret = set_als_range(0, (uint16_t)hi_thr, HI_LIMIT);
+ if (ret < 0) {
+ dev_err(&ltr559->i2c_client->dev, "%s: set ALS hi threshold Fail...\n", __func__);
+ return (-1);
+ }
+
+ return count;
+}
+
+static DEVICE_ATTR(setalshithrerange, 0660, NULL, setalshithrerange_store);
+
+
+static ssize_t dispalsthrerange_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ int8_t ret = 0;
+ uint16_t rdback_lo, rdback_hi;
+ struct ltr559_data *ltr559 = sensor_info;
+
+ ret = als_range_readback(&rdback_lo, &rdback_hi, ltr559);
+ if (ret < 0) {
+ dev_err(&ltr559->i2c_client->dev, "%s: ALS threshold range readback Fail...\n", __func__);
+ return (-1);
+ }
+
+ ret = sprintf(buf, "%d %d\n", rdback_lo, rdback_hi);
+
+ return ret;
+}
+
+static DEVICE_ATTR(dispalsthrerange, 0444, dispalsthrerange_show, NULL);
+
+
+static ssize_t setpslothrerange_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+{
+ int8_t ret;
+ uint16_t lo_thr = 0;
+ uint8_t param_temp[4];
+ struct ltr559_data *ltr559 = sensor_info;
+
+ param_temp[0] = buf[0];
+ param_temp[1] = buf[1];
+ param_temp[2] = buf[2];
+ param_temp[3] = buf[3];
+
+ if (count <= 1) {
+ param_temp[0] = 0;
+ param_temp[1] = 0;
+ param_temp[2] = 0;
+ param_temp[3] = 0;
+ } else if (count == 2) { // 1 digit
+ param_temp[0] -= 48;
+ param_temp[1] = 0;
+ param_temp[2] = 0;
+ param_temp[3] = 0;
+
+ param_temp[3] = param_temp[0];
+ param_temp[2] = 0;
+ param_temp[1] = 0;
+ param_temp[0] = 0;
+ } else if (count == 3) { // 2 digits
+ param_temp[0] -= 48;
+ param_temp[1] -= 48;
+ param_temp[2] = 0;
+ param_temp[3] = 0;
+
+ param_temp[3] = param_temp[1];
+ param_temp[2] = param_temp[0];
+ param_temp[1] = 0;
+ param_temp[0] = 0;
+ } else if (count == 4) { // 3 digits
+ param_temp[0] -= 48;
+ param_temp[1] -= 48;
+ param_temp[2] -= 48;
+ param_temp[3] = 0;
+
+ param_temp[3] = param_temp[2];
+ param_temp[2] = param_temp[1];
+ param_temp[1] = param_temp[0];
+ param_temp[0] = 0;
+ } else if (count >= 5) { // 4 digits
+ param_temp[0] -= 48;
+ param_temp[1] -= 48;
+ param_temp[2] -= 48;
+ param_temp[3] -= 48;
+ }
+
+ //for (i_ctr = 0; i_ctr < sizeof(param_temp); i_ctr++) {
+ // if ((param_temp[i_ctr] < 0) ||(param_temp[i_ctr] > 9)) {
+ // param_temp[i_ctr] = 0;
+ // }
+ //}
+
+ lo_thr = ((param_temp[0] * 1000) + (param_temp[1] * 100) + (param_temp[2] * 10) + param_temp[3]);
+ if (lo_thr > 2047) {
+ lo_thr = 2047;
+ }
+ dev_dbg(&ltr559->i2c_client->dev, "%s: store value = %d\n", __func__, lo_thr);
+ ps_set_lowthresh = lo_thr;
+ printk("%s,lo_thr:%d,ps_set_lowthresh:%d\n",__func__,lo_thr,ps_set_lowthresh);
+
+ ret = set_ps_range(lo_thr, 0, LO_LIMIT);
+ if (ret < 0) {
+ dev_err(&ltr559->i2c_client->dev, "%s: set PS lo threshold Fail...\n", __func__);
+ return (-1);
+ }
+
+ return count;
+}
+
+static DEVICE_ATTR(setpslothrerange, 0660, NULL, setpslothrerange_store);
+
+
+static ssize_t setpshithrerange_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+{
+ int8_t ret;
+ uint16_t hi_thr = 0;
+ uint8_t param_temp[4];
+ struct ltr559_data *ltr559 = sensor_info;
+
+ param_temp[0] = buf[0];
+ param_temp[1] = buf[1];
+ param_temp[2] = buf[2];
+ param_temp[3] = buf[3];
+
+ if (count <= 1) {
+ param_temp[0] = 0;
+ param_temp[1] = 0;
+ param_temp[2] = 0;
+ param_temp[3] = 0;
+ } else if (count == 2) { // 1 digit
+ param_temp[0] -= 48;
+ param_temp[1] = 0;
+ param_temp[2] = 0;
+ param_temp[3] = 0;
+
+ param_temp[3] = param_temp[0];
+ param_temp[2] = 0;
+ param_temp[1] = 0;
+ param_temp[0] = 0;
+ } else if (count == 3) { // 2 digits
+ param_temp[0] -= 48;
+ param_temp[1] -= 48;
+ param_temp[2] = 0;
+ param_temp[3] = 0;
+
+ param_temp[3] = param_temp[1];
+ param_temp[2] = param_temp[0];
+ param_temp[1] = 0;
+ param_temp[0] = 0;
+ } else if (count == 4) { // 3 digits
+ param_temp[0] -= 48;
+ param_temp[1] -= 48;
+ param_temp[2] -= 48;
+ param_temp[3] = 0;
+
+ param_temp[3] = param_temp[2];
+ param_temp[2] = param_temp[1];
+ param_temp[1] = param_temp[0];
+ param_temp[0] = 0;
+ } else if (count >= 5) { // 4 digits
+ param_temp[0] -= 48;
+ param_temp[1] -= 48;
+ param_temp[2] -= 48;
+ param_temp[3] -= 48;
+ }
+
+ //for (i_ctr = 0; i_ctr < sizeof(param_temp); i_ctr++) {
+ // if ((param_temp[i_ctr] < 0) ||(param_temp[i_ctr] > 9)) {
+ // param_temp[i_ctr] = 0;
+ // }
+ //}
+
+ hi_thr = ((param_temp[0] * 1000) + (param_temp[1] * 100) + (param_temp[2] * 10) + param_temp[3]);
+ if (hi_thr > 2047) {
+ hi_thr = 2047;
+ }
+ dev_dbg(&ltr559->i2c_client->dev, "%s: store value = %d\n", __func__, hi_thr);
+ ps_set_highthresh = hi_thr;
+ printk("%s,hi_thr:%d,ps_set_highthresh:%d\n",__func__,hi_thr,ps_set_highthresh);
+
+ ret = set_ps_range(0, hi_thr, HI_LIMIT);
+ if (ret < 0) {
+ dev_err(&ltr559->i2c_client->dev, "%s: set PS hi threshold Fail...\n", __func__);
+ return (-1);
+ }
+
+ return count;
+}
+
+static DEVICE_ATTR(setpshithrerange, 0660, NULL, setpshithrerange_store);
+
+
+static ssize_t disppsthrerange_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ int8_t ret = 0;
+ uint16_t rdback_lo, rdback_hi;
+ struct ltr559_data *ltr559 = sensor_info;
+
+ ret = ps_range_readback(&rdback_lo, &rdback_hi, ltr559);
+ if (ret < 0) {
+ dev_err(&ltr559->i2c_client->dev, "%s: PS threshold range readback Fail...\n", __func__);
+ return (-1);
+ }
+
+ ret = sprintf(buf, "%d %d\n", rdback_lo, rdback_hi);
+
+ return ret;
+}
+
+static DEVICE_ATTR(disppsthrerange, 0444, disppsthrerange_show, NULL);
+
+static ssize_t als_enable_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ struct ltr559_data *ltr559 = sensor_info;
+
+ return sprintf(buf, "%d\n", ltr559->als_enable_flag);
+}
+
+static ssize_t als_enable_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+{
+ unsigned long data;
+ int error;
+ struct ltr559_data *ltr559 = sensor_info;
+
+ error = strict_strtoul(buf, 10, &data);
+ if (error)
+ return error;
+
+ if (data)
+ error = ltr559_als_enable(ltr559);
+ else
+ error = als_disable(ltr559);
+
+ if(error){
+ dev_err(&ltr559->i2c_client->dev, "%s: als set enable fail...\n", __func__);
+ return error;
+ }
+
+ return count;
+}
+
+static DEVICE_ATTR(als_enable, 0664, als_enable_show, als_enable_store);
+
+static ssize_t ps_enable_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ struct ltr559_data *ltr559 = sensor_info;
+
+ return sprintf(buf, "%d\n", ltr559->ps_enable_flag);
+}
+
+static ssize_t ps_enable_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+{
+ unsigned long data;
+ int error;
+ struct ltr559_data *ltr559 = sensor_info;
+
+ error = strict_strtoul(buf, 10, &data);
+ if (error)
+ return error;
+
+ if (data)
+ error = ltr559_ps_enable(ltr559);
+ else
+ error = ps_disable(ltr559);
+
+ if(error){
+ dev_err(&ltr559->i2c_client->dev, "%s: ps set enable fail...\n", __func__);
+ return error;
+ }
+
+ return count;
+}
+
+static DEVICE_ATTR(ps_enable, 0664, ps_enable_show, ps_enable_store);
+
+static void sysfs_register_device(struct i2c_client *client)
+{
+ int rc = 0;
+
+ rc += device_create_file(&client->dev, &dev_attr_als_adc);
+ rc += device_create_file(&client->dev, &dev_attr_ps_adc);
+ rc += device_create_file(&client->dev, &dev_attr_alscontrsetup); //0X80
+ rc += device_create_file(&client->dev, &dev_attr_pscontrsetup); //0X81
+ rc += device_create_file(&client->dev, &dev_attr_partidreg); //0x86
+ rc += device_create_file(&client->dev, &dev_attr_manuid); //0x87
+ rc += device_create_file(&client->dev, &dev_attr_reg);
+ rc += device_create_file(&client->dev, &dev_attr_alspsstatusreg); //0x8c
+ rc += device_create_file(&client->dev, &dev_attr_setalslothrerange);
+ rc += device_create_file(&client->dev, &dev_attr_setalshithrerange);
+ rc += device_create_file(&client->dev, &dev_attr_dispalsthrerange);
+ rc += device_create_file(&client->dev, &dev_attr_setpslothrerange);
+ rc += device_create_file(&client->dev, &dev_attr_setpshithrerange);
+ rc += device_create_file(&client->dev, &dev_attr_disppsthrerange);
+ rc += device_create_file(&client->dev, &dev_attr_als_enable);
+ rc += device_create_file(&client->dev, &dev_attr_ps_enable);
+
+ if (rc) {
+ dev_err(&client->dev, "%s Unable to create sysfs files\n", __func__);
+ } else {
+ dev_dbg(&client->dev, "%s Created sysfs files\n", __func__);
+ }
+}
+
+
+static int als_setup(struct ltr559_data *ltr559)
+{
+ int ret;
+
+ ltr559->als_input_dev = input_allocate_device();
+ if (!ltr559->als_input_dev) {
+ dev_err(&ltr559->i2c_client->dev, "%s: ALS Input Allocate Device Fail...\n", __func__);
+ return -ENOMEM;
+ }
+ ltr559->als_input_dev->name = "ltr559_als";
+ set_bit(EV_ABS, ltr559->als_input_dev->evbit);
+ input_set_abs_params(ltr559->als_input_dev, ABS_MISC, ALS_MIN_MEASURE_VAL, ALS_MAX_MEASURE_VAL, 0, 0);
+
+ ret = input_register_device(ltr559->als_input_dev);
+ if (ret < 0) {
+ dev_err(&ltr559->i2c_client->dev, "%s: ALS Register Input Device Fail...\n", __func__);
+ goto err_als_register_input_device;
+ }
+
+ ret = misc_register(&als_misc);
+ if (ret < 0) {
+ dev_err(&ltr559->i2c_client->dev, "%s: ALS Register Misc Device Fail...\n", __func__);
+ goto err_als_register_misc_device;
+ }
+
+ return ret;
+
+err_als_register_misc_device:
+ input_unregister_device(ltr559->als_input_dev);
+err_als_register_input_device:
+ input_free_device(ltr559->als_input_dev);
+
+ return ret;
+}
+
+
+static int ps_setup(struct ltr559_data *ltr559)
+{
+ int ret;
+
+ ltr559->ps_input_dev = input_allocate_device();
+ if (!ltr559->ps_input_dev) {
+ dev_err(&ltr559->i2c_client->dev, "%s: PS Input Allocate Device Fail...\n", __func__);
+ return -ENOMEM;
+ }
+ ltr559->ps_input_dev->name = "ltr559_ps";
+ set_bit(EV_ABS, ltr559->ps_input_dev->evbit);
+ input_set_abs_params(ltr559->ps_input_dev, ABS_DISTANCE, PS_MIN_MEASURE_VAL, PS_MAX_MEASURE_VAL, 0, 0);
+
+ ret = input_register_device(ltr559->ps_input_dev);
+ if (ret < 0) {
+ dev_err(&ltr559->i2c_client->dev, "%s: PS Register Input Device Fail...\n", __func__);
+ goto err_ps_register_input_device;
+ }
+
+ ret = misc_register(&ps_misc);
+ if (ret < 0) {
+ dev_err(&ltr559->i2c_client->dev, "%s: PS Register Misc Device Fail...\n", __func__);
+ goto err_ps_register_misc_device;
+ }
+
+ return ret;
+
+err_ps_register_misc_device:
+ input_unregister_device(ltr559->ps_input_dev);
+err_ps_register_input_device:
+ input_free_device(ltr559->ps_input_dev);
+
+ return ret;
+}
+
+
+static int _check_part_id(struct ltr559_data *ltr559)
+{
+ uint8_t ret;
+ uint8_t buffer[2];
+
+ buffer[0] = LTR559_PART_ID;
+ ret = I2C_Read(buffer, 1);
+ if (ret < 0) {
+ dev_err(&ltr559->i2c_client->dev, "%s: Read failure :0x%02X",
+ __func__, buffer[0]);
+ return -1;
+ }
+
+ if (buffer[0] != PARTID) {
+ dev_err(&ltr559->i2c_client->dev, "%s: Part failure miscompare"
+ " act:0x%02x exp:0x%02x\n", __func__, buffer[0], PARTID);
+ return -2;
+ }
+
+ return 0;
+}
+
+
+static int ltr559_setup(struct ltr559_data *ltr559)
+{
+ int ret = 0;
+
+ /* Reset the devices */
+ ret = _ltr559_set_bit(ltr559->i2c_client, SET_BIT, LTR559_ALS_CONTR, ALS_SW_RESET);
+ if (ret < 0) {
+ dev_err(&ltr559->i2c_client->dev, "%s: ALS reset fail...\n", __func__);
+ goto err_out1;
+ }
+
+ ret = _ltr559_set_bit(ltr559->i2c_client, CLR_BIT, LTR559_PS_CONTR, PS_MODE_ACTIVE);
+ if (ret < 0) {
+ dev_err(&ltr559->i2c_client->dev, "%s: PS reset fail...\n", __func__);
+ goto err_out1;
+ }
+
+ msleep(PON_DELAY);
+ dev_dbg(&ltr559->i2c_client->dev, "%s: Reset ltr559 device\n", __func__);
+
+ /* Do another part read to ensure we have exited reset */
+ if (_check_part_id(ltr559) < 0) {
+ dev_err(&ltr559->i2c_client->dev, "%s: Part ID Read Fail after reset...\n", __func__);
+ goto err_out1;
+ }
+
+ //(Linux RTOS)>
+#if 1
+ ret = ltr559_gpio_irq(ltr559);
+ if (ret < 0) {
+ dev_err(&ltr559->i2c_client->dev, "%s: GPIO Request Fail...\n", __func__);
+ goto err_out1;
+ }
+ dev_dbg(&ltr559->i2c_client->dev, "%s Requested interrupt\n", __func__);
+#endif
+ //(Linux RTOS)<
+
+ /* Set count of measurements outside data range before interrupt is generated */
+ ret = _ltr559_set_bit(ltr559->i2c_client, SET_BIT, LTR559_INTERRUPT_PRST, 0x11);
+ if (ret < 0) {
+ dev_err(&ltr559->i2c_client->dev, "%s: ALS Set Persist Fail...\n", __func__);
+ goto err_out2;
+ }
+
+ /* Enable interrupts on the device and clear only when status is read */
+ ret = _ltr559_set_bit(ltr559->i2c_client, SET_BIT, LTR559_INTERRUPT, INT_MODE_ALSPS_TRIG);
+ if (ret < 0) {
+ dev_err(&ltr559->i2c_client->dev, "%s: Enabled interrupts failed...\n", __func__);
+ goto err_out2;
+ }
+ dev_dbg(&ltr559->i2c_client->dev, "%s Enabled interrupt to device\n", __func__);
+
+ /* Turn on ALS and PS */
+ ret = als_device_init(ltr559);
+ if (ret < 0) {
+ dev_err(&ltr559->i2c_client->dev, "%s Unable to enable ALS", __func__);
+ goto err_out2;
+ }
+ dev_info(&ltr559->i2c_client->dev, "%s Turned on ambient light sensor\n", __func__);
+
+ ret = ps_device_init(ltr559);
+ if (ret < 0) {
+ dev_err(&ltr559->i2c_client->dev, "%s Unable to enable PS", __func__);
+ goto err_out2;
+ }
+ dev_info(&ltr559->i2c_client->dev, "%s Turned on proximity sensor\n", __func__);
+
+ return ret;
+
+err_out2:
+ free_irq(ltr559->irq, ltr559);
+ gpio_free(ltr559->gpio_int_no);
+
+err_out1:
+ dev_err(&ltr559->i2c_client->dev, "%s Unable to setup device\n", __func__);
+
+ return ret;
+}
+
+
+//(Linux RTOS)>
+#if 1
+static void ltr559_early_suspend(struct early_suspend *h)
+{
+ int ret = 0;
+ struct ltr559_data *ltr559 = sensor_info;
+
+ ltr559->is_suspend = 1;
+
+ ret = als_disable(ltr559);
+#if 0
+ /* Save away the state of the devices at suspend point */
+ ltr559->als_suspend_enable_flag = ltr559->als_enable_flag;
+ ltr559->ps_suspend_enable_flag = ltr559->ps_enable_flag;
+
+ /* Disable the devices for suspend if configured */
+ if (ltr559->disable_als_on_suspend && ltr559->als_enable_flag) {
+ ret += als_disable(ltr559);
+ }
+#endif
+
+ if (ret) {
+ dev_err(&ltr559->i2c_client->dev, "%s Unable to complete suspend\n", __func__);
+ } else {
+ dev_info(&ltr559->i2c_client->dev, "%s Suspend completed\n", __func__);
+ }
+}
+
+
+static void ltr559_late_resume(struct early_suspend *h)
+{
+ struct ltr559_data *ltr559 = sensor_info;
+ int ret = 0;
+
+ ltr559->is_suspend = 0;
+ ret = ltr559_als_enable(ltr559);
+
+#if 0
+ /* If PS was enbled before suspend, enable during resume */
+ if (ltr559->ps_suspend_enable_flag) {
+ ret += ltr559_ps_enable(ltr559);
+ ltr559->ps_suspend_enable_flag = 0;
+ }
+#endif
+
+ if (ret) {
+ dev_err(&ltr559->i2c_client->dev, "%s Unable to complete resume\n", __func__);
+ } else {
+ dev_info(&ltr559->i2c_client->dev, "%s Resume completed\n", __func__);
+ }
+}
+#endif
+//(Linux RTOS)<
+
+
+static int ltr559_probe(struct i2c_client *client, const struct i2c_device_id *id)
+{
+ int ret = 0;
+ struct ltr559_data *ltr559;
+
+ printk("entry %s\n",__func__);
+//(Linux RTOS)>
+#if 0
+ struct ltr559_platform_data *platdata;
+#endif
+//(Linux RTOS)<
+
+ ltr559 = kzalloc(sizeof(struct ltr559_data), GFP_KERNEL);
+ if (!ltr559)
+ {
+ dev_err(&ltr559->i2c_client->dev, "%s: Mem Alloc Fail...\n", __func__);
+ return -ENOMEM;
+ }
+
+ /* Global pointer for this device */
+ sensor_info = ltr559;
+
+ /* Set initial defaults */
+ ltr559->als_enable_flag = 0;
+ ltr559->ps_enable_flag = 0;
+
+ ltr559->i2c_client = client;
+ ltr559->irq = client->irq;
+ ltr559->gpio_int_no = GPIO17_PLSENSOR_INT;
+
+ i2c_set_clientdata(client, ltr559);
+
+ /* Parse the platform data */
+ //(Linux RTOS)>
+#if 0
+ platdata = client->dev.platform_data;
+ if (!platdata) {
+ dev_err(&ltr559->i2c_client->dev, "%s: Platform Data assign Fail...\n", __func__);
+ ret = -EBUSY;
+ goto err_out;
+ }
+
+ ltr559->gpio_int_no = platdata->pfd_gpio_int_no;
+ //ltr559->adc_levels = platdata->pfd_levels;
+ ltr559->default_ps_lowthresh = platdata->pfd_ps_lowthresh;
+ ltr559->default_ps_highthresh = platdata->pfd_ps_highthresh;
+
+ /* Configuration to set or disable devices upon suspend */
+ //ltr559->disable_als_on_suspend = platdata->pfd_disable_als_on_suspend;
+ //ltr559->disable_ps_on_suspend = platdata->pfd_disable_ps_on_suspend;
+#endif
+ //(Linux RTOS)<
+
+ if (_check_part_id(ltr559) < 0) {
+ dev_err(&ltr559->i2c_client->dev, "%s: Part ID Read Fail...\n", __func__);
+ goto err_out;
+ }
+
+ /* Setup the input subsystem for the ALS */
+ ret = als_setup(ltr559);
+ if (ret < 0) {
+ dev_err(&ltr559->i2c_client->dev,"%s: ALS Setup Fail...\n", __func__);
+ goto err_out;
+ }
+
+ /* Setup the input subsystem for the PS */
+ ret = ps_setup(ltr559);
+ if (ret < 0) {
+ dev_err(&ltr559->i2c_client->dev, "%s: PS Setup Fail...\n", __func__);
+ goto err_out;
+ }
+
+ /* Create the workqueue for the interrup handler */
+ //(Linux RTOS)>
+#if 1
+ ltr559->workqueue = create_singlethread_workqueue("ltr559_wq");
+ if (!ltr559->workqueue) {
+ dev_err(&ltr559->i2c_client->dev, "%s: Create WorkQueue Fail...\n", __func__);
+ ret = -ENOMEM;
+ goto err_out;
+ }
+
+ /* Wake lock option for promity sensor */
+ wake_lock_init(&(ltr559->ps_wake_lock), WAKE_LOCK_SUSPEND, "proximity");
+#endif
+ //(Linux RTOS)<
+
+ /* Setup and configure both the ALS and PS on the ltr559 device */
+ ret = ltr559_setup(ltr559);
+ if (ret < 0) {
+ dev_err(&ltr559->i2c_client->dev, "%s: Setup Fail...\n", __func__);
+ goto err_ltr559_setup;
+ }
+
+ /* Setup the suspend and resume functionality */
+ //(Linux RTOS)>
+#if 1
+ ltr559->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1;
+ ltr559->early_suspend.suspend = ltr559_early_suspend;
+ ltr559->early_suspend.resume = ltr559_late_resume;
+ register_early_suspend(&ltr559->early_suspend);
+#endif
+ //(Linux RTOS)<
+
+
+ /* Register the sysfs files */
+ sysfs_register_device(client);
+ //sysfs_register_als_device(client, &ltr559->als_input_dev->dev);
+ //sysfs_register_ps_device(client, &ltr559->ps_input_dev->dev);
+
+ dev_dbg(&ltr559->i2c_client->dev, "%s: probe complete\n", __func__);
+ return ret;
+
+err_ltr559_setup:
+ destroy_workqueue(ltr559->workqueue);
+err_out:
+ kfree(ltr559);
+
+ return ret;
+}
+
+
+static const struct i2c_device_id ltr559_id[] = {
+ { DEVICE_NAME, 0 },
+ {}
+};
+
+static struct i2c_driver ltr559_driver = {
+ .probe = ltr559_probe,
+ .id_table = ltr559_id,
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = DEVICE_NAME,
+ },
+};
+
+
+static int __init ltr559_init(void)
+{
+ return i2c_add_driver(&ltr559_driver);
+}
+
+static void __exit ltr559_exit(void)
+{
+ i2c_del_driver(&ltr559_driver);
+}
+
+
+module_init(ltr559_init)
+module_exit(ltr559_exit)
+
+MODULE_AUTHOR("Lite-On Technology Corp");
+MODULE_DESCRIPTION("LTR-559ALSPS Driver");
+MODULE_LICENSE("Dual BSD/GPL");
+MODULE_VERSION(DRIVER_VERSION);
+
+
diff --git a/drivers/i2c/busses/i2c-qup.c b/drivers/i2c/busses/i2c-qup.c
old mode 100644
new mode 100755
index 5a8b66a..88a40e6
--- a/drivers/i2c/busses/i2c-qup.c
+++ b/drivers/i2c/busses/i2c-qup.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009-2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2009-2012, Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -136,7 +136,13 @@ static struct gpiomux_setting recovery_config = {
.drv = GPIOMUX_DRV_8MA,
.pull = GPIOMUX_PULL_NONE,
};
-
+/*add QC pathc for MTBF test I2C time start*/
+static struct gpiomux_setting i2c_config = {
+ .func = GPIOMUX_FUNC_2,
+ .drv = GPIOMUX_DRV_16MA,
+ .pull = GPIOMUX_PULL_NONE,
+};
+/*add QC pathc for MTBF test I2C time end*/
struct qup_i2c_dev {
struct device *dev;
void __iomem *base; /* virtual */
@@ -676,33 +682,47 @@ static void qup_i2c_recover_bus_busy(struct qup_i2c_dev *dev)
bool gpio_clk_status = false;
uint32_t status = readl_relaxed(dev->base + QUP_I2C_STATUS);
struct gpiomux_setting old_gpio_setting;
-
- if (dev->pdata->msm_i2c_config_gpio)
+ /*ad QC pathc for MTBF test I2C time */
+ dev_err(dev->dev, "qup_i2c_recover_bus_busy()clk=%d,data=%d\n",dev->pdata->pri_clk,dev->pdata->pri_dat);
+ if (!dev->pdata->pri_clk && !dev->pdata->pri_dat)
+ {
+ if(dev->msg)
+ {
+ dev_err(dev->dev, "Recovery failed, pri_clk|pri_dat = 0, addr: 0x%x\n",dev->msg->addr);
+ }
return;
+ }
if (!(status & (I2C_STATUS_BUS_ACTIVE)) ||
(status & (I2C_STATUS_BUS_MASTER)))
+ {
+ dev_err(dev->dev, "qup_i2c_recover_bus_busy() status:%d\n",status);
return;
+ }
- gpio_clk = dev->i2c_gpios[0];
- gpio_dat = dev->i2c_gpios[1];
+ //gpio_clk = dev->i2c_gpios[0];
+ //gpio_dat = dev->i2c_gpios[1];
+ gpio_clk = dev->pdata->pri_clk;
+ gpio_dat = dev->pdata->pri_dat;
- if ((gpio_clk == -1) && (gpio_dat == -1)) {
+ if ((gpio_clk == -1) && (gpio_dat == -1))
+ {
dev_err(dev->dev, "Recovery failed due to undefined GPIO's\n");
return;
}
+ dev->i2c_gpios[0] = gpio_clk;
+ dev->i2c_gpios[1] = gpio_dat;
disable_irq(dev->err_irq);
for (i = 0; i < ARRAY_SIZE(i2c_rsrcs); ++i) {
if (msm_gpiomux_write(dev->i2c_gpios[i], GPIOMUX_ACTIVE,
&recovery_config, &old_gpio_setting)) {
- dev_err(dev->dev, "GPIO pins have no active setting\n");
+ dev_err(dev->dev, "GPIO pins have no active setting i= %d,gpio=%d\n",i, dev->i2c_gpios[i]);
goto recovery_end;
}
}
- dev_warn(dev->dev, "i2c_scl: %d, i2c_sda: %d\n",
- gpio_get_value(gpio_clk), gpio_get_value(gpio_dat));
+ dev_warn(dev->dev, "i2c_scl: %d, i2c_sda: %d\n",gpio_get_value(gpio_clk), gpio_get_value(gpio_dat));
for (i = 0; i < 9; i++) {
if (gpio_get_value(gpio_dat) && gpio_clk_status)
@@ -721,11 +741,15 @@ static void qup_i2c_recover_bus_busy(struct qup_i2c_dev *dev)
gpio_direction_input(gpio_dat);
udelay(5);
}
-
+ /*ad QC pathc for MTBF test I2C time */
+ udelay(10);
/* Configure ALT funciton to QUP I2C*/
for (i = 0; i < ARRAY_SIZE(i2c_rsrcs); ++i) {
- msm_gpiomux_write(dev->i2c_gpios[i], GPIOMUX_ACTIVE,
- &old_gpio_setting, NULL);
+ if (msm_gpiomux_write(dev->i2c_gpios[i], GPIOMUX_ACTIVE,
+ &i2c_config, NULL))
+ {
+ dev_err(dev->dev, "GPIO pins have no active setting:i=%d,gpio=%d\n",i,dev->i2c_gpios[i]);
+ }
}
udelay(10);
@@ -743,7 +767,61 @@ static void qup_i2c_recover_bus_busy(struct qup_i2c_dev *dev)
recovery_end:
enable_irq(dev->err_irq);
}
+/*ad QC pathc for MTBF test I2C time */
+#if 0
+static void qup_i2c_gpio(struct qup_i2c_dev *dev)
+{
+ int i;
+ int gpio_clk;
+ int gpio_dat;
+ //bool gpio_clk_status = false;
+ struct gpiomux_setting old_gpio_setting;
+
+ dev_err(dev->dev, "-----------qup_i2c_gpio gpio_clk=%d, gpio_dat=%d\n", dev->pdata->pri_clk, dev->pdata->pri_dat);
+ gpio_clk = dev->pdata->pri_clk;
+ gpio_dat = dev->pdata->pri_dat;
+
+ if ((gpio_clk == -1) && (gpio_dat == -1)) {
+ dev_err(dev->dev, "Recovery failed due to undefined GPIO's\n");
+ return;
+ }
+ dev->i2c_gpios[0] = gpio_clk;
+ dev->i2c_gpios[1] = gpio_dat;
+
+ if ((gpio_clk == -1) && (gpio_dat == -1)) {
+ dev_err(dev->dev, "Recovery failed due to undefined GPIO's\n");
+ return;
+ }
+ disable_irq(dev->err_irq);
+ for (i = 0; i < ARRAY_SIZE(i2c_rsrcs); ++i) {
+ if (msm_gpiomux_write(dev->i2c_gpios[i], GPIOMUX_ACTIVE,
+ &recovery_config, &old_gpio_setting)) {
+ //dev_err(dev->dev, "GPIO pins have no active setting\n");
+ dev_err(dev->dev, "msm_gpiomux_write recovery_config GPIO pins have no active setting i=%d, dev->i2c_gpios=%d\n", i, dev->i2c_gpios[i]);
+ }
+ }
+
+
+
+ dev_warn(dev->dev, "i2c_scl: %d, i2c_sda: %d\n",
+ gpio_get_value(gpio_clk), gpio_get_value(gpio_dat));
+
+ /* Configure ALT funciton to QUP I2C*/
+ for (i = 0; i < ARRAY_SIZE(i2c_rsrcs); ++i) {
+ if (msm_gpiomux_write(dev->i2c_gpios[i], GPIOMUX_ACTIVE,
+ &old_gpio_setting, NULL)){
+ dev_err(dev->dev, "msm_gpiomux_write old_gpio_setting GPIO pins have no active setting i=%d, dev->i2c_gpios=%d\n", i, dev->i2c_gpios[i]);
+ }
+ }
+
+ udelay(10);
+ dev_warn(dev->dev, "-----------qup_i2c_gpio end\n");
+
+enable_irq(dev->err_irq);
+
+}
+#endif
static int
qup_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
{
@@ -848,7 +926,7 @@ qup_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
ret = -EIO;
goto out_err;
}
-
+ //dev_err(dev->dev, "qup_i2c_xfer():qup_print_status()1\n");
qup_print_status(dev);
/* HW limits Read upto 256 bytes in 1 read without stop */
if (dev->msg->flags & I2C_M_RD) {
@@ -869,7 +947,7 @@ qup_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
ret = err;
goto out_err;
}
-
+ //dev_err(dev->dev, "qup_i2c_xfer()qup_print_status()2\n");
qup_print_status(dev);
writel_relaxed(dev->clk_ctl, dev->base + QUP_I2C_CLK_CTL);
/* CLK_CTL register is not in the same 1K region as other QUP
@@ -888,7 +966,7 @@ qup_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
ret = err;
goto out_err;
}
-
+ //dev_err(dev->dev, "qup_i2c_xfer()qup_print_status()3\n");
qup_print_status(dev);
/* This operation is Write, check the next operation
* and decide mode
@@ -933,10 +1011,10 @@ qup_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
}
dev_dbg(dev->dev, "idx:%d, rem:%d, num:%d, mode:%d\n",
idx, rem, num, dev->mode);
-
+ //dev_err(dev->dev, "qup_i2c_xfer()qup_print_status()4\n");
qup_print_status(dev);
timeout = wait_for_completion_timeout(&complete,
- msecs_to_jiffies(dev->out_fifo_sz));
+ msecs_to_jiffies(dev->out_fifo_sz)*1);
if (!timeout) {
uint32_t istatus = readl_relaxed(dev->base +
QUP_I2C_STATUS);
@@ -944,7 +1022,32 @@ qup_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
QUP_ERROR_FLAGS);
uint32_t op_flgs = readl_relaxed(dev->base +
QUP_OPERATIONAL);
-
+#if 0
+ uint32_t Q_CONFIG = readl_relaxed(dev->base +
+ QUP_CONFIG);
+ uint32_t Q_STATE = readl_relaxed(dev->base +
+ QUP_STATE);
+ uint32_t Q_IO_MODE = readl_relaxed(dev->base +
+ QUP_IO_MODE);
+ uint32_t Q_SW_RESET = readl_relaxed(dev->base +
+ QUP_SW_RESET);
+ uint32_t Q_ERROR_FLAGS = readl_relaxed(dev->base +
+ QUP_ERROR_FLAGS_EN);
+ uint32_t Q_MX_READ = readl_relaxed(dev->base +
+ QUP_MX_READ_CNT);
+ uint32_t Q_MX_INPUT = readl_relaxed(dev->base +
+ QUP_MX_INPUT_CNT);
+ uint32_t Q_MX_WR_CNT = readl_relaxed(dev->base +
+ QUP_MX_WR_CNT);
+ uint32_t Q_OUT_DEBUG = readl_relaxed(dev->base +
+ QUP_OUT_DEBUG);
+ uint32_t Q_IN_READ_CUR = readl_relaxed(dev->base +
+ QUP_IN_READ_CUR);
+ uint32_t Q_IN_DEBUG = readl_relaxed(dev->base +
+ QUP_IN_DEBUG);
+ uint32_t Q_I2C_CLK_CTL = readl_relaxed(dev->base +
+ QUP_I2C_CLK_CTL);
+#endif
/*
* Dont wait for 1 sec if i2c sees the bus
* active and controller is not master.
@@ -966,6 +1069,20 @@ qup_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
dev_err(dev->dev, "I2C Status: %x\n", istatus);
dev_err(dev->dev, "QUP Status: %x\n", qstatus);
dev_err(dev->dev, "OP Flags: %x\n", op_flgs);
+#if 0
+ dev_err(dev->dev, "QUP_CONFIG: %x\n", Q_CONFIG);
+ dev_err(dev->dev, "QUP_STATE: %x\n", Q_STATE);
+ dev_err(dev->dev, "QUP_IO_MODE: %x\n", Q_IO_MODE);
+ dev_err(dev->dev, "QUP_SW_RESET: %x\n", Q_SW_RESET);
+ dev_err(dev->dev, "QUP_ERROR_FLAGS_EN: %x\n", Q_ERROR_FLAGS);
+ dev_err(dev->dev, "QUP_MX_READ_CNT: %x\n", Q_MX_READ);
+ dev_err(dev->dev, "QUP_MX_INPUT_CNT: %x\n", Q_MX_INPUT);
+ dev_err(dev->dev, "QUP_MX_WR_CNT: %x\n", Q_MX_WR_CNT);
+ dev_err(dev->dev, "QUP_OUT_DEBUG: %x\n", Q_OUT_DEBUG);
+ dev_err(dev->dev, "QUP_IN_READ_CUR: %x\n", Q_IN_READ_CUR);
+ dev_err(dev->dev, "QUP_IN_DEBUG: %x\n", Q_IN_DEBUG);
+ dev_err(dev->dev, "QUP_I2C_CLK_CTL: %x\n", Q_I2C_CLK_CTL);
+#endif
writel_relaxed(1, dev->base + QUP_SW_RESET);
/* Make sure that the write has gone through
* before returning from the function
@@ -1236,9 +1353,12 @@ blsp_core_init:
dev->i2c_gpios[i] = res ? res->start : -1;
}
- ret = qup_i2c_request_gpios(dev);
- if (ret)
- goto err_request_gpio_failed;
+ /* Request gpio only when custom gpio configuration function is NOT defined*/
+ if(!pdata->msm_i2c_config_gpio){
+ ret = qup_i2c_request_gpios(dev);
+ if (ret)
+ goto err_request_gpio_failed;
+ }
platform_set_drvdata(pdev, dev);
diff --git a/drivers/input/input.c b/drivers/input/input.c
index 8921c61..487f7c2 100644
--- a/drivers/input/input.c
+++ b/drivers/input/input.c
@@ -1574,9 +1574,11 @@ void input_reset_device(struct input_dev *dev)
* Keys that have been pressed at suspend time are unlikely
* to be still pressed when we resume.
*/
- spin_lock_irq(&dev->event_lock);
- input_dev_release_keys(dev);
- spin_unlock_irq(&dev->event_lock);
+ if (!test_bit(INPUT_PROP_NO_FAKE_RELEASE, dev->propbit)) {
+ spin_lock_irq(&dev->event_lock);
+ input_dev_release_keys(dev);
+ spin_unlock_irq(&dev->event_lock);
+ }
}
mutex_unlock(&dev->mutex);
diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
index 8fb19dc..b0b3a97 100644
--- a/drivers/input/misc/Kconfig
+++ b/drivers/input/misc/Kconfig
@@ -647,4 +647,53 @@ config BOSCH_BMA150
If you say yes here you get support for Bosch Sensortec's
acceleration sensors SMB380/BMA150.
+config INPUT_LTR502
+ tristate "LTR502 light/proximity sensor support"
+ depends on I2C
+ default n
+ help
+ Driver for LTR502 light/proximity sensor.
+
+config INPUT_LTR558
+ tristate "LTR558 light/proximity sensor support"
+ depends on I2C
+ default n
+ help
+ Driver for LTR558 light/proximity sensor.
+
+config BOSCH_BMA250
+ tristate "BMA250 acceleration sensor support"
+ depends on I2C=y
+ help
+ If you say yes here you get support for Bosch Sensortec's
+ acceleration sensors BMA250.
+
+config AVAGO_APDS990X
+ tristate "Avago apds990x light/proximity sensor support"
+ depends on I2C=y
+ help
+ If you say yes here you get support for Avago
+ light/proximity sensors apds990x.
+
+config INPUT_ISL29028
+ tristate "Intersil ISL29028 light/proximity sensor support"
+ depends on I2C=y
+ help
+ If you say yes here you get support for Intersil
+ light/proximity sensors ISL29028.
+
+config INPUT_LIS3DH
+ tristate "LIS3DH acceleration sensor support"
+ depends on I2C=y
+ help
+ If you say yes here you get support for ST
+ acceleration sensor LIS3DH.
+
+config SENSORS_TMD2771X
+ tristate "TAOS TMD2771X proximity and ambient light sensor"
+ depends on I2C=y
+ help
+ If you say yes here you get support for TAOS TMD27711, TMD27713
+ proximity and ambient light sensor.
+
endif
diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile
index eecee4e..9da7251 100644
--- a/drivers/input/misc/Makefile
+++ b/drivers/input/misc/Makefile
@@ -60,3 +60,10 @@ obj-$(CONFIG_INPUT_YEALINK) += yealink.o
obj-$(CONFIG_PMIC8058_OTHC) += pmic8058-othc.o
obj-$(CONFIG_INPUT_PMIC8058_VIBRA_MEMLESS) += pmic8058-vib-memless.o
obj-$(CONFIG_BOSCH_BMA150) += bma150.o
+obj-$(CONFIG_INPUT_LTR502) += ltr502.o
+obj-$(CONFIG_INPUT_LTR558) += ltr558.o
+obj-$(CONFIG_BOSCH_BMA250) += bma250.o
+obj-$(CONFIG_AVAGO_APDS990X) += apds990x.o
+obj-$(CONFIG_INPUT_ISL29028) += isl29028.o
+obj-$(CONFIG_INPUT_LIS3DH) += lis3dh.o
+obj-$(CONFIG_SENSORS_TMD2771X) += tmd2771x.o
diff --git a/drivers/input/misc/apds990x.c b/drivers/input/misc/apds990x.c
new file mode 100644
index 0000000..fcf5fe9
--- /dev/null
+++ b/drivers/input/misc/apds990x.c
@@ -0,0 +1,1179 @@
+/*
+ * This file is part of the APDS990x sensor driver.
+ * Chip is combined proximity and ambient light sensor.
+ *
+ * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+ * Copyright (c) 2012 The Linux Foundation. All Rights Reserved.
+ *
+ * Contact: Samu Onkalo <samu.p.onkalo@nokia.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., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/mutex.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/input.h>
+#include <linux/input/apds990x.h>
+#include <linux/wakelock.h>
+
+#define APDS990x_DRV_NAME "apds990x"
+#define DRIVER_VERSION "1.0.4"
+
+#define APDS990x_POWER_ONOFF(pdata, onoff) \
+ do { \
+ if ((pdata)->power_onoff) { \
+ (pdata)->power_onoff(onoff); \
+ } \
+ } \
+ while(0)
+
+/* Change History
+ *
+ * 1.0.1 Functions apds990x_show_rev(), apds990x_show_id() and apds990x_show_status()
+ * have missing CMD_BYTE in the i2c_smbus_read_byte_data(). APDS-990x needs
+ * CMD_BYTE for i2c write/read byte transaction.
+ *
+ *
+ * 1.0.2 Include PS switching threshold level when interrupt occurred
+ *
+ *
+ * 1.0.3 Implemented ISR and delay_work, correct PS threshold storing
+ *
+ * 1.0.4 Added Input Report Event
+ */
+
+/*
+ * Defines
+ */
+
+#define APDS990x_ENABLE_REG 0x00
+#define APDS990x_ATIME_REG 0x01
+#define APDS990x_PTIME_REG 0x02
+#define APDS990x_WTIME_REG 0x03
+#define APDS990x_AILTL_REG 0x04
+#define APDS990x_AILTH_REG 0x05
+#define APDS990x_AIHTL_REG 0x06
+#define APDS990x_AIHTH_REG 0x07
+#define APDS990x_PILTL_REG 0x08
+#define APDS990x_PILTH_REG 0x09
+#define APDS990x_PIHTL_REG 0x0A
+#define APDS990x_PIHTH_REG 0x0B
+#define APDS990x_PERS_REG 0x0C
+#define APDS990x_CONFIG_REG 0x0D
+#define APDS990x_PPCOUNT_REG 0x0E
+#define APDS990x_CONTROL_REG 0x0F
+#define APDS990x_REV_REG 0x11
+#define APDS990x_ID_REG 0x12
+#define APDS990x_STATUS_REG 0x13
+#define APDS990x_CDATAL_REG 0x14
+#define APDS990x_CDATAH_REG 0x15
+#define APDS990x_IRDATAL_REG 0x16
+#define APDS990x_IRDATAH_REG 0x17
+#define APDS990x_PDATAL_REG 0x18
+#define APDS990x_PDATAH_REG 0x19
+
+#define CMD_BYTE 0x80
+#define CMD_WORD 0xA0
+#define CMD_SPECIAL 0xE0
+
+#define CMD_CLR_PS_INT 0xE5
+#define CMD_CLR_ALS_INT 0xE6
+#define CMD_CLR_PS_ALS_INT 0xE7
+
+/*
+ * Structs
+ */
+
+struct apds990x_data {
+ //put the platform special resource in platform code
+ struct apds990x_platform_data *pdata;
+ struct i2c_client *client;
+ struct mutex update_lock;
+ //use a dedicated spinlock instead of dwork.wait_lock
+ spinlock_t wq_lock;
+ struct delayed_work dwork; /* for PS interrupt */
+ struct delayed_work als_dwork; /* for ALS polling */
+ struct input_dev *input_dev_als;
+ struct input_dev *input_dev_ps;
+ struct wake_lock prx_wake_lock;
+
+ unsigned int enable;
+ unsigned int atime;
+ unsigned int ptime;
+ unsigned int wtime;
+ unsigned int ailt;
+ unsigned int aiht;
+ unsigned int pilt;
+ unsigned int piht;
+ unsigned int pers;
+ unsigned int config;
+ unsigned int ppcount;
+ unsigned int control;
+
+ /* control flag from HAL */
+ unsigned int enable_ps_sensor;
+ unsigned int enable_als_sensor;
+
+ /* PS parameters */
+ unsigned int ps_threshold;
+ unsigned int ps_hysteresis_threshold; /* always lower than ps_threshold */
+ unsigned int ps_detection; /* 1 = near-to-far; 0 = far-to-near */
+ unsigned int ps_data; /* to store PS data */
+
+ /* ALS parameters */
+ unsigned int als_threshold_l; /* low threshold */
+ unsigned int als_threshold_h; /* high threshold */
+ unsigned int als_data; /* to store ALS data */
+
+ unsigned int als_gain; /* needed for Lux calculation */
+ unsigned int als_poll_delay; /* needed for light sensor polling : micro-second (us) */
+ unsigned int als_atime; /* storage for als integratiion time */
+};
+
+/*
+ * Global data
+ */
+
+/*
+ * Management functions
+ */
+
+static int apds990x_set_command(struct i2c_client *client, int command)
+{
+ int ret;
+ int clearInt;
+
+ if (command == 0)
+ clearInt = CMD_CLR_PS_INT;
+ else if (command == 1)
+ clearInt = CMD_CLR_ALS_INT;
+ else
+ clearInt = CMD_CLR_PS_ALS_INT;
+ //It`s unnecessary to lock mutex before i2c_smbus_write_byte, which is thread-safe and SMP safe.
+ ret = i2c_smbus_write_byte(client, clearInt);
+
+ return ret;
+}
+
+static int apds990x_set_enable(struct i2c_client *client, int enable)
+{
+ struct apds990x_data *data = i2c_get_clientdata(client);
+ int ret;
+
+ //Yes, the mutex is necessary for modify data->data, but I will lock it before call this function
+ ret = i2c_smbus_write_byte_data(client, CMD_BYTE|APDS990x_ENABLE_REG, enable);
+ data->enable = enable;
+
+ return ret;
+}
+
+static int apds990x_set_atime(struct i2c_client *client, int atime)
+{
+ struct apds990x_data *data = i2c_get_clientdata(client);
+ int ret;
+
+ ret = i2c_smbus_write_byte_data(client, CMD_BYTE|APDS990x_ATIME_REG, atime);
+ data->atime = atime;
+
+ return ret;
+}
+
+static int apds990x_set_ptime(struct i2c_client *client, int ptime)
+{
+ struct apds990x_data *data = i2c_get_clientdata(client);
+ int ret;
+
+ ret = i2c_smbus_write_byte_data(client, CMD_BYTE|APDS990x_PTIME_REG, ptime);
+ data->ptime = ptime;
+
+ return ret;
+}
+
+static int apds990x_set_wtime(struct i2c_client *client, int wtime)
+{
+ struct apds990x_data *data = i2c_get_clientdata(client);
+ int ret;
+
+ ret = i2c_smbus_write_byte_data(client, CMD_BYTE|APDS990x_WTIME_REG, wtime);
+ data->wtime = wtime;
+
+ return ret;
+}
+
+static int apds990x_set_ailt(struct i2c_client *client, int threshold)
+{
+ struct apds990x_data *data = i2c_get_clientdata(client);
+ int ret;
+
+ ret = i2c_smbus_write_word_data(client, CMD_WORD|APDS990x_AILTL_REG, threshold);
+ data->ailt = threshold;
+
+ return ret;
+}
+
+static int apds990x_set_aiht(struct i2c_client *client, int threshold)
+{
+ struct apds990x_data *data = i2c_get_clientdata(client);
+ int ret;
+
+ ret = i2c_smbus_write_word_data(client, CMD_WORD|APDS990x_AIHTL_REG, threshold);
+ data->aiht = threshold;
+
+ return ret;
+}
+
+static int apds990x_set_pilt(struct i2c_client *client, int threshold)
+{
+ struct apds990x_data *data = i2c_get_clientdata(client);
+ int ret;
+
+ ret = i2c_smbus_write_word_data(client, CMD_WORD|APDS990x_PILTL_REG, threshold);
+ data->pilt = threshold;
+
+ return ret;
+}
+
+static int apds990x_set_piht(struct i2c_client *client, int threshold)
+{
+ struct apds990x_data *data = i2c_get_clientdata(client);
+ int ret;
+
+ ret = i2c_smbus_write_word_data(client, CMD_WORD|APDS990x_PIHTL_REG, threshold);
+ data->piht = threshold;
+
+ return ret;
+}
+
+static int apds990x_set_pers(struct i2c_client *client, int pers)
+{
+ struct apds990x_data *data = i2c_get_clientdata(client);
+ int ret;
+
+ ret = i2c_smbus_write_byte_data(client, CMD_BYTE|APDS990x_PERS_REG, pers);
+ data->pers = pers;
+
+ return ret;
+}
+
+static int apds990x_set_config(struct i2c_client *client, int config)
+{
+ struct apds990x_data *data = i2c_get_clientdata(client);
+ int ret;
+
+ ret = i2c_smbus_write_byte_data(client, CMD_BYTE|APDS990x_CONFIG_REG, config);
+ data->config = config;
+
+ return ret;
+}
+
+static int apds990x_set_ppcount(struct i2c_client *client, int ppcount)
+{
+ struct apds990x_data *data = i2c_get_clientdata(client);
+ int ret;
+
+ ret = i2c_smbus_write_byte_data(client, CMD_BYTE|APDS990x_PPCOUNT_REG, ppcount);
+ data->ppcount = ppcount;
+
+ return ret;
+}
+
+static int apds990x_set_control(struct i2c_client *client, int control)
+{
+ struct apds990x_data *data = i2c_get_clientdata(client);
+ int ret;
+
+ ret = i2c_smbus_write_byte_data(client, CMD_BYTE|APDS990x_CONTROL_REG, control);
+ data->control = control;
+
+ /* obtain ALS gain value */
+ if ((control&0x03) == 0x00) /* 1X Gain */
+ data->als_gain = 1;
+ else if ((control&0x03) == 0x01) /* 8X Gain */
+ data->als_gain = 8;
+ else if ((control&0x03) == 0x02) /* 16X Gain */
+ data->als_gain = 16;
+ else /* 120X Gain */
+ data->als_gain = 120;
+
+ return ret;
+}
+
+static int LuxCalculation(struct i2c_client *client, int cdata, int irdata)
+{
+ struct apds990x_data *data = i2c_get_clientdata(client);
+ int luxValue=0;
+
+ int IAC1=0;
+ int IAC2=0;
+ int IAC=0;
+ int GA=1064; /* 0.48 without glass window */
+ int COE_B=210; /* 2.23 without glass window */
+ int COE_C=29; /* 0.70 without glass window */
+ int COE_D=57; /* 1.42 without glass window */
+ int DF=52;
+
+ IAC1 = (cdata - (COE_B*irdata)/100); // re-adjust COE_B to avoid 2 decimal point
+ IAC2 = ((COE_C*cdata)/100 - (COE_D*irdata)/100); // re-adjust COE_C and COE_D to void 2 decimal point
+
+ if (IAC1 > IAC2)
+ IAC = IAC1;
+ else if (IAC1 <= IAC2)
+ IAC = IAC2;
+ else
+ IAC = 0;
+
+ luxValue = ((IAC*GA*DF)/100)/(((272*(256-data->atime))/100)*data->als_gain);
+
+ return luxValue;
+}
+
+static void apds990x_change_ps_threshold(struct i2c_client *client)
+{
+ struct apds990x_data *data = i2c_get_clientdata(client);
+ int retval;
+
+ retval = i2c_smbus_read_word_data(client, CMD_WORD|APDS990x_PDATAL_REG);
+ if (retval < 0)
+ return;
+
+ data->ps_data = retval;
+ if ( (data->ps_data > data->pilt) && (data->ps_data >= data->piht) ) {
+ /* far-to-near detected */
+ data->ps_detection = 1;
+
+ input_report_abs(data->input_dev_ps, ABS_DISTANCE, 0);/* FAR-to-NEAR detection */
+ input_sync(data->input_dev_ps);
+
+ i2c_smbus_write_word_data(client, CMD_WORD|APDS990x_PILTL_REG, data->ps_hysteresis_threshold);
+ i2c_smbus_write_word_data(client, CMD_WORD|APDS990x_PIHTL_REG, 1023);
+
+ data->pilt = data->ps_hysteresis_threshold;
+ data->piht = 1023;
+
+ pr_debug("far-to-near detected\n");
+ }
+ else if ( (data->ps_data <= data->pilt) && (data->ps_data < data->piht) ) {
+ /* near-to-far detected */
+ data->ps_detection = 0;
+
+ input_report_abs(data->input_dev_ps, ABS_DISTANCE, 1);/* NEAR-to-FAR detection */
+ input_sync(data->input_dev_ps);
+
+ i2c_smbus_write_word_data(client, CMD_WORD|APDS990x_PILTL_REG, 0);
+ i2c_smbus_write_word_data(client, CMD_WORD|APDS990x_PIHTL_REG, data->ps_threshold);
+
+ data->pilt = 0;
+ data->piht = data->ps_threshold;
+
+ pr_debug("near-to-far detected\n");
+ } else {
+ pr_debug("data->ps_data = %d, data->pilt = %d, data->piht = %d\n", data->ps_data, data->pilt, data->piht);
+ }
+}
+
+static void apds990x_change_als_threshold(struct i2c_client *client)
+{
+ struct apds990x_data *data = i2c_get_clientdata(client);
+ int cdata, irdata;
+ int luxValue=0;
+
+ cdata = i2c_smbus_read_word_data(client, CMD_WORD|APDS990x_CDATAL_REG);
+ irdata = i2c_smbus_read_word_data(client, CMD_WORD|APDS990x_IRDATAL_REG);
+
+ luxValue = LuxCalculation(client, cdata, irdata);
+
+ luxValue = luxValue>0 ? luxValue : 0;
+ luxValue = luxValue<10000 ? luxValue : 10000;
+ // check PS under sunlight
+ if ( (data->ps_detection == 1) && (cdata > (75*(1024*(256-data->atime)))/100)) // PS was previously in far-to-near condition
+ {
+ // need to inform input event as there will be no interrupt from the PS
+ input_report_abs(data->input_dev_ps, ABS_DISTANCE, 1);/* NEAR-to-FAR detection */
+ input_sync(data->input_dev_ps);
+
+ i2c_smbus_write_word_data(client, CMD_WORD|APDS990x_PILTL_REG, 0);
+ i2c_smbus_write_word_data(client, CMD_WORD|APDS990x_PIHTL_REG, data->ps_threshold);
+
+ data->pilt = 0;
+ data->piht = data->ps_threshold;
+
+ data->ps_detection = 0; /* near-to-far detected */
+
+ pr_debug("apds_990x_proximity_handler = FAR\n");
+ }
+
+ input_report_abs(data->input_dev_als, ABS_MISC, luxValue); // report the lux level
+ input_sync(data->input_dev_als);
+
+ data->als_data = cdata;
+ data->als_threshold_l = (data->als_data * (100-data->pdata->als_hsyt_thld) ) /100;
+ data->als_threshold_h = (data->als_data * (100+data->pdata->als_hsyt_thld) ) /100;
+
+ if (data->als_threshold_h >= 65535) data->als_threshold_h = 65535;
+
+ i2c_smbus_write_word_data(client, CMD_WORD|APDS990x_AILTL_REG, data->als_threshold_l);
+ i2c_smbus_write_word_data(client, CMD_WORD|APDS990x_AIHTL_REG, data->als_threshold_h);
+}
+
+/* ALS polling routine */
+static void apds990x_als_polling_work_handler(struct work_struct *work)
+{
+ struct apds990x_data *data = container_of(work, struct apds990x_data, als_dwork.work);
+ struct i2c_client *client=data->client;
+ int cdata, irdata, pdata;
+ int luxValue=0;
+
+ //1. work queue is reentrant in SMP.
+ //2. serveral function here calls need mutex.
+ mutex_lock(&data->update_lock);
+ cdata = i2c_smbus_read_word_data(client, CMD_WORD|APDS990x_CDATAL_REG);
+ irdata = i2c_smbus_read_word_data(client, CMD_WORD|APDS990x_IRDATAL_REG);
+ pdata = i2c_smbus_read_word_data(client, CMD_WORD|APDS990x_PDATAL_REG);
+
+ if ((cdata < 0) || (irdata < 0) || (pdata < 0)) {
+ mutex_unlock(&data->update_lock);
+ return;
+ }
+
+ luxValue = LuxCalculation(client, cdata, irdata);
+ luxValue = luxValue>0 ? luxValue : 0;
+ luxValue = luxValue<10000 ? luxValue : 10000;
+ //pr_debug("%s: lux = %d cdata = %x irdata = %x pdata = %x \n", __func__, luxValue, cdata, irdata, pdata);
+ // check PS under sunlight
+ if ( (data->ps_detection == 1) && (cdata > (75*(1024*(256-data->atime)))/100)) // PS was previously in far-to-near condition
+ {
+ // need to inform input event as there will be no interrupt from the PS
+ input_report_abs(data->input_dev_ps, ABS_DISTANCE, 1);/* NEAR-to-FAR detection */
+ input_sync(data->input_dev_ps);
+
+ i2c_smbus_write_word_data(client, CMD_WORD|APDS990x_PILTL_REG, 0);
+ i2c_smbus_write_word_data(client, CMD_WORD|APDS990x_PIHTL_REG, data->ps_threshold);
+
+ data->pilt = 0;
+ data->piht = data->ps_threshold;
+
+ data->ps_detection = 0; /* near-to-far detected */
+
+ pr_debug("apds_990x_proximity_handler = FAR\n");
+ }
+
+ input_report_abs(data->input_dev_als, ABS_MISC, luxValue); // report the lux level
+ input_sync(data->input_dev_als);
+
+ schedule_delayed_work(&data->als_dwork, msecs_to_jiffies(data->als_poll_delay)); // restart timer
+ mutex_unlock(&data->update_lock);
+}
+
+/* PS interrupt routine */
+static void apds990x_work_handler(struct work_struct *work)
+{
+ struct apds990x_data *data = container_of(work, struct apds990x_data, dwork.work);
+ struct i2c_client *client=data->client;
+ int status;
+ int cdata;
+ int retry_count = 3;
+
+retry:
+ status = i2c_smbus_read_byte_data(client, CMD_BYTE|APDS990x_STATUS_REG);
+ if (status < 0) {
+ pr_warning("fail to read data,status = %x\n", status);
+ if (retry_count--) {
+ usleep(50000);
+ goto retry;
+ } else {
+ return;
+ }
+ }
+
+ i2c_smbus_write_byte_data(client, CMD_BYTE|APDS990x_ENABLE_REG, 1); /* disable 990x's ADC first */
+
+ pr_debug("status = %x, enable = %x\n", status, data->enable);
+ //Interrupt is not reentrant both in UP and MP. But some variant/function here need to thread-safe.
+ mutex_lock(&data->update_lock);
+
+ if ((status & data->enable & 0x30) == 0x30) {
+ /* both PS and ALS are interrupted */
+ apds990x_change_als_threshold(client);
+
+ cdata = i2c_smbus_read_word_data(client, CMD_WORD|APDS990x_CDATAL_REG);
+ if (cdata < (75*(1024*(256-data->atime)))/100)
+ apds990x_change_ps_threshold(client);
+ else {
+ if (data->ps_detection == 1) {
+ apds990x_change_ps_threshold(client);
+ }
+ else {
+ pr_debug("Triggered by background ambient noise\n");
+ }
+ }
+
+ apds990x_set_command(client, 2); /* 2 = CMD_CLR_PS_ALS_INT */
+ }
+ else if ((status & data->enable & 0x20) == 0x20) {
+ /* only PS is interrupted */
+ /* check if this is triggered by background ambient noise */
+ cdata = i2c_smbus_read_word_data(client, CMD_WORD|APDS990x_CDATAL_REG);
+ if (cdata < (75*(1024*(256-data->atime)))/100)
+ apds990x_change_ps_threshold(client);
+ else {
+ if (data->ps_detection == 1) {
+ apds990x_change_ps_threshold(client);
+ }
+ else {
+ pr_debug("Triggered by background ambient noise\n");
+ }
+ }
+
+ apds990x_set_command(client, 0); /* 0 = CMD_CLR_PS_INT */
+ }
+ else if ((status & data->enable & 0x10) == 0x10) {
+ /* only ALS is interrupted */
+ apds990x_change_als_threshold(client);
+ apds990x_set_command(client, 1); /* 1 = CMD_CLR_ALS_INT */
+ }
+ i2c_smbus_write_byte_data(client, CMD_BYTE|APDS990x_ENABLE_REG, data->enable);
+ mutex_unlock(&data->update_lock);
+}
+
+/* assume this is ISR */
+static irqreturn_t apds990x_interrupt(int vec, void *info)
+{
+ struct i2c_client *client=(struct i2c_client *)info;
+ struct apds990x_data *data = i2c_get_clientdata(client);
+
+ pr_debug("==> apds990x_interrupt (timeout)\n");
+ wake_lock_timeout(&data->prx_wake_lock, HZ / 2);
+ //Seems linux-3.0 trends to use threaded-interrupt, so we can call the work directly.
+ apds990x_work_handler(&data->dwork.work);
+
+ return IRQ_HANDLED;
+}
+
+/*
+ * SysFS support
+ */
+static ssize_t apds990x_show_ps_sensor_thld(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct apds990x_data *data = i2c_get_clientdata(client);
+
+ return sprintf(buf, "%d %d\n", data->pdata->ps_hsyt_thld, data->pdata->ps_det_thld);
+}
+
+static ssize_t apds990x_store_ps_sensor_thld(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct apds990x_data *data = i2c_get_clientdata(client);
+ char *next_buf;
+ unsigned long hsyt_val = simple_strtoul(buf, &next_buf, 10);
+ unsigned long det_val = simple_strtoul(++next_buf, NULL, 10);
+
+ if ((det_val < 0) || (det_val > 1023) || (hsyt_val < 0) || (hsyt_val >= det_val)) {
+ pr_err("%s:store unvalid det_val=%ld, hsyt_val=%ld\n", __func__, det_val, hsyt_val);
+ return -EINVAL;
+ }
+ mutex_lock(&data->update_lock);
+ data->pdata->ps_det_thld = det_val;
+ data->pdata->ps_hsyt_thld = hsyt_val;
+ mutex_unlock(&data->update_lock);
+
+ return count;
+}
+
+static DEVICE_ATTR(ps_sensor_thld, S_IWUGO | S_IRUGO,
+ apds990x_show_ps_sensor_thld, apds990x_store_ps_sensor_thld);
+
+static ssize_t apds990x_show_enable_ps_sensor(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct apds990x_data *data = i2c_get_clientdata(client);
+
+ return sprintf(buf, "%d\n", data->enable_ps_sensor);
+}
+
+static ssize_t apds990x_store_enable_ps_sensor(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct apds990x_data *data = i2c_get_clientdata(client);
+ unsigned long val = simple_strtoul(buf, NULL, 10);
+ unsigned long flags;
+
+ pr_debug("%s: enable ps senosr ( %ld)\n", __func__, val);
+
+ if ((val != 0) && (val != 1)) {
+ pr_err("%s:store unvalid value=%ld\n", __func__, val);
+ return count;
+ }
+ //some variant/function here need to thread-safe. And it`s better to finish all the steps in one time.
+ mutex_lock(&data->update_lock);
+
+ if(val == 1) {
+ //turn on p sensor
+ if (data->enable_ps_sensor==0) {
+ data->enable_ps_sensor= 1;
+ apds990x_set_enable(client,0); /* Power Off */
+ apds990x_set_atime(client, 0xf6); /* 27.2ms */
+ apds990x_set_ptime(client, 0xff); /* 2.72ms */
+ apds990x_set_ppcount(client, 8); /* 8-pulse */
+ apds990x_set_control(client, 0x60); /* 100mA, IR-diode, 1X PGAIN, 1X AGAIN */
+ apds990x_set_pilt(client, 0); // init threshold for proximity
+ apds990x_set_piht(client, data->pdata->ps_det_thld);
+ data->ps_threshold = data->pdata->ps_det_thld;
+ data->ps_hysteresis_threshold = data->pdata->ps_hsyt_thld;
+ apds990x_set_ailt( client, 0);
+ apds990x_set_aiht( client, 0xffff);
+ apds990x_set_pers(client, 0x33); /* 3 persistence */
+
+ if (data->enable_als_sensor==0) {
+
+ /* we need this polling timer routine for sunlight canellation */
+ spin_lock_irqsave(&data->wq_lock, flags);
+
+ /*
+ * If work is already scheduled then subsequent schedules will not
+ * change the scheduled time that's why we have to cancel it first.
+ */
+ __cancel_delayed_work(&data->als_dwork);
+ schedule_delayed_work(&data->als_dwork, msecs_to_jiffies(data->als_poll_delay)); // 100ms
+
+ spin_unlock_irqrestore(&data->wq_lock, flags);
+ }
+
+ apds990x_set_enable(client, 0x27); /* only enable PS interrupt */
+ }
+ }
+ else {
+ //turn off p sensor - kk 25 Apr 2011 we can't turn off the entire sensor, the light sensor may be needed by HAL
+ data->enable_ps_sensor = 0;
+ if (data->enable_als_sensor) {
+ // reconfigute light sensor setting
+ apds990x_set_enable(client,0); /* Power Off */
+ apds990x_set_atime(client, data->als_atime); /* previous als poll delay */
+ apds990x_set_ailt( client, 0);
+ apds990x_set_aiht( client, 0xffff);
+ apds990x_set_control(client, 0x60); /* 100mA, IR-diode, 1X PGAIN, 1X AGAIN */
+ apds990x_set_pers(client, 0x33); /* 3 persistence */
+ apds990x_set_enable(client, 0x3); /* only enable light sensor */
+ /*
+ * If work is already scheduled then subsequent schedules will not
+ * change the scheduled time that's why we have to cancel it first.
+ */
+ spin_lock_irqsave(&data->wq_lock, flags);
+
+ __cancel_delayed_work(&data->als_dwork);
+ schedule_delayed_work(&data->als_dwork, msecs_to_jiffies(data->als_poll_delay)); // 100ms
+
+ spin_unlock_irqrestore(&data->wq_lock, flags);
+ }
+ else {
+ apds990x_set_enable(client, 0);
+ /*
+ * If work is already scheduled then subsequent schedules will not
+ * change the scheduled time that's why we have to cancel it first.
+ */
+ spin_lock_irqsave(&data->wq_lock, flags);
+
+ __cancel_delayed_work(&data->als_dwork);
+
+ spin_unlock_irqrestore(&data->wq_lock, flags);
+ }
+ }
+
+ mutex_unlock(&data->update_lock);
+
+ return count;
+}
+
+static DEVICE_ATTR(enable_ps_sensor, S_IWUSR | S_IWGRP | S_IRUGO,
+ apds990x_show_enable_ps_sensor, apds990x_store_enable_ps_sensor);
+
+static ssize_t apds990x_show_enable_als_sensor(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct apds990x_data *data = i2c_get_clientdata(client);
+
+ return sprintf(buf, "%d\n", data->enable_als_sensor);
+}
+
+static ssize_t apds990x_store_enable_als_sensor(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct apds990x_data *data = i2c_get_clientdata(client);
+ unsigned long val = simple_strtoul(buf, NULL, 10);
+ unsigned long flags;
+
+ pr_debug("%s: enable als sensor ( %ld)\n", __func__, val);
+
+ if ((val != 0) && (val != 1))
+ {
+ pr_err("%s: enable als sensor=%ld\n", __func__, val);
+ return count;
+ }
+
+ mutex_lock(&data->update_lock);
+
+ if(val == 1) {
+ //turn on light sensor
+ if (data->enable_als_sensor==0) {
+ data->enable_als_sensor = 1;
+ apds990x_set_enable(client,0); /* Power Off */
+ apds990x_set_atime(client, data->als_atime); /* 100.64ms */
+ apds990x_set_ailt( client, 0);
+ apds990x_set_aiht( client, 0xffff);
+ apds990x_set_control(client, 0x60); /* 100mA, IR-diode, 1X PGAIN, 1X AGAIN */
+ apds990x_set_pers(client, 0x33); /* 3 persistence */
+
+ if (data->enable_ps_sensor) {
+ apds990x_set_ptime(client, 0xff); /* 2.72ms */
+ apds990x_set_ppcount(client, 8); /* 8-pulse */
+ apds990x_set_enable(client, 0x27); /* if prox sensor was activated previously */
+ }
+ else {
+ apds990x_set_enable(client, 0x3); /* only enable light sensor */
+ }
+ /*
+ * If work is already scheduled then subsequent schedules will not
+ * change the scheduled time that's why we have to cancel it first.
+ */
+ spin_lock_irqsave(&data->wq_lock, flags);
+
+ __cancel_delayed_work(&data->als_dwork);
+ schedule_delayed_work(&data->als_dwork, msecs_to_jiffies(data->als_poll_delay));
+
+ spin_unlock_irqrestore(&data->wq_lock, flags);
+ }
+ }
+ else {
+ if (data->enable_als_sensor==1) {
+ data->enable_als_sensor = 0;
+ if (data->enable_ps_sensor) {
+ apds990x_set_enable(client,0); /* Power Off */
+ apds990x_set_atime(client, 0xf6); /* 27.2ms */
+ apds990x_set_ptime(client, 0xff); /* 2.72ms */
+ apds990x_set_ppcount(client, 8); /* 8-pulse */
+ apds990x_set_control(client, 0x60); /* 100mA, IR-diode, 1X PGAIN, 1X AGAIN */
+ apds990x_set_piht(client, 0);
+ apds990x_set_piht(client, data->pdata->ps_det_thld);
+ apds990x_set_ailt( client, 0);
+ apds990x_set_aiht( client, 0xffff);
+ apds990x_set_pers(client, 0x33); /* 3 persistence */
+ apds990x_set_enable(client, 0x27); /* only enable prox sensor with interrupt */
+ }
+ else {
+ apds990x_set_enable(client, 0);
+ }
+
+ /*
+ * If work is already scheduled then subsequent schedules will not
+ * change the scheduled time that's why we have to cancel it first.
+ */
+ spin_lock_irqsave(&data->wq_lock, flags);
+
+ __cancel_delayed_work(&data->als_dwork);
+
+ spin_unlock_irqrestore(&data->wq_lock, flags);
+ }
+ }
+ mutex_unlock(&data->update_lock);
+
+ return count;
+}
+
+static DEVICE_ATTR(enable_als_sensor, S_IWUSR | S_IWGRP | S_IRUGO,
+ apds990x_show_enable_als_sensor, apds990x_store_enable_als_sensor);
+
+static ssize_t apds990x_show_als_poll_delay(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct apds990x_data *data = i2c_get_clientdata(client);
+
+ return sprintf(buf, "%d\n", data->als_poll_delay*1000); // return in micro-second
+}
+
+static ssize_t apds990x_store_als_poll_delay(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct apds990x_data *data = i2c_get_clientdata(client);
+ unsigned long val = simple_strtoul(buf, NULL, 10);
+ int ret;
+ int poll_delay=0;
+ unsigned long flags;
+
+ if (val<5000)
+ val = 5000; // minimum 5ms
+
+ mutex_lock(&data->update_lock);
+ data->als_poll_delay = val/1000; // convert us => ms
+
+ // val * 2 uses bigger integration time, which will provide more accurate output.
+ poll_delay = 256 - (val * 2 / 2720); // the minimum is 2.72ms = 2720 us, maximum is 696.32ms
+ if (poll_delay >= 256)
+ data->als_atime = 255;
+ else if (poll_delay < 0)
+ data->als_atime = 0;
+ else
+ data->als_atime = poll_delay;
+
+ ret = apds990x_set_atime(client, data->als_atime);
+
+ if (ret < 0)
+ return ret;
+
+ /* we need this polling timer routine for sunlight canellation */
+ /*
+ * If work is already scheduled then subsequent schedules will not
+ * change the scheduled time that's why we have to cancel it first.
+ */
+ spin_lock_irqsave(&data->wq_lock, flags);
+
+ __cancel_delayed_work(&data->als_dwork);
+ schedule_delayed_work(&data->als_dwork, msecs_to_jiffies(data->als_poll_delay)); // 100ms
+
+ spin_unlock_irqrestore(&data->wq_lock, flags);
+
+ mutex_unlock(&data->update_lock);
+
+ return count;
+}
+
+static DEVICE_ATTR(als_poll_delay, S_IWUSR | S_IWGRP | S_IRUGO,
+ apds990x_show_als_poll_delay, apds990x_store_als_poll_delay);
+
+static struct attribute *apds990x_attributes[] = {
+ &dev_attr_enable_ps_sensor.attr,
+ &dev_attr_enable_als_sensor.attr,
+ &dev_attr_als_poll_delay.attr,
+ &dev_attr_ps_sensor_thld.attr,
+ NULL
+};
+
+
+static const struct attribute_group apds990x_attr_group = {
+ .attrs = apds990x_attributes,
+};
+
+/*
+ * Initialization function
+ */
+
+static int apds990x_init_client(struct i2c_client *client)
+{
+ struct apds990x_data *data = i2c_get_clientdata(client);
+ int err;
+ int id;
+
+ err = apds990x_set_enable(client, 0);
+
+ if (err < 0)
+ return err;
+
+ id = i2c_smbus_read_byte_data(client, CMD_BYTE|APDS990x_ID_REG);
+ if (id == 0x20) {
+ pr_debug("APDS-9901\n");
+ }
+ else if (id == 0x29) {
+ pr_debug("APDS-990x\n");
+ }
+ else {
+ pr_err("Neither APDS-9901 nor APDS-9901\n");
+ return -EIO;
+ }
+
+ apds990x_set_atime(client, 0xDB); // 100.64ms ALS integration time
+ apds990x_set_ptime(client, 0xFF); // 2.72ms Prox integration time
+ apds990x_set_wtime(client, 0xFF); // 2.72ms Wait time
+
+ apds990x_set_ppcount(client, 0x08); // 8-Pulse for proximity
+ apds990x_set_config(client, 0); // no long wait
+ apds990x_set_control(client, 0x60); // 100mA, IR-diode, 1X PGAIN, 1X AGAIN
+
+ apds990x_set_pilt(client, 0); // init threshold for proximity
+ apds990x_set_piht(client, data->pdata->ps_det_thld);
+
+ data->ps_threshold = data->pdata->ps_det_thld;
+ data->ps_hysteresis_threshold = data->pdata->ps_hsyt_thld;
+
+ apds990x_set_ailt(client, 0); // init threshold for als
+ apds990x_set_aiht(client, 0xFFFF);
+
+ apds990x_set_pers(client, 0x22); // 2 consecutive Interrupt persistence
+
+ // sensor is in disabled mode but all the configurations are preset
+
+ return 0;
+}
+
+/*
+ * I2C init/probing/exit functions
+ */
+
+static struct i2c_driver apds990x_driver;
+static int __devinit apds990x_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
+ struct apds990x_data *data;
+ int err = 0;
+ struct apds990x_platform_data *pdata = client->dev.platform_data;
+
+ if (!pdata || (pdata->irq <= 0)) {
+ pr_err("%s: platform resource is no enough!\n", __func__);
+ return -ENODEV;
+ }
+
+ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE)) {
+ err = -EIO;
+ goto exit;
+ }
+
+ data = kzalloc(sizeof(struct apds990x_data), GFP_KERNEL);
+ if (!data) {
+ err = -ENOMEM;
+ goto exit;
+ }
+ data->pdata = pdata;
+ data->client = client;
+ i2c_set_clientdata(client, data);
+
+ data->enable = 0; /* default mode is standard */
+ data->ps_threshold = 0;
+ data->ps_hysteresis_threshold = 0;
+ data->ps_detection = 0; /* default to no detection */
+ data->enable_als_sensor = 0; // default to 0
+ data->enable_ps_sensor = 0; // default to 0
+ data->als_poll_delay = 100; // default to 100ms
+ data->als_atime = 0xdb; // work in conjuction with als_poll_delay
+
+ pr_debug("enable = %x\n", data->enable);
+
+ mutex_init(&data->update_lock);
+ spin_lock_init(&data->wq_lock);
+
+ wake_lock_init(&data->prx_wake_lock, WAKE_LOCK_SUSPEND,
+ "prx_wake_lock");
+ INIT_DELAYED_WORK(&data->dwork, apds990x_work_handler);
+ INIT_DELAYED_WORK(&data->als_dwork, apds990x_als_polling_work_handler);
+
+ pr_debug("%s interrupt is hooked\n", __func__);
+
+ /* Initialize the APDS990x chip */
+ err = apds990x_init_client(client);
+ if (err)
+ goto exit_kfree;
+
+ /* Register to Input Device */
+ data->input_dev_als = input_allocate_device();
+ if (!data->input_dev_als) {
+ err = -ENOMEM;
+ pr_err("Failed to allocate input device als\n");
+ goto exit_kfree;
+ }
+
+ data->input_dev_ps = input_allocate_device();
+ if (!data->input_dev_ps) {
+ err = -ENOMEM;
+ pr_err("Failed to allocate input device ps\n");
+ goto exit_free_dev_als;
+ }
+
+ set_bit(EV_ABS, data->input_dev_als->evbit);
+ set_bit(EV_ABS, data->input_dev_ps->evbit);
+
+ input_set_abs_params(data->input_dev_als, ABS_MISC, 0, 10000, 0, 0);
+ input_set_abs_params(data->input_dev_ps, ABS_DISTANCE, 0, 1, 0, 0);
+
+ data->input_dev_als->name = "Avago light sensor";
+ data->input_dev_ps->name = "Avago proximity sensor";
+
+ err = input_register_device(data->input_dev_als);
+ if (err) {
+ err = -ENOMEM;
+ pr_err("Unable to register input device als: %s\n",
+ data->input_dev_als->name);
+ goto exit_free_dev_ps;
+ }
+
+ err = input_register_device(data->input_dev_ps);
+ if (err) {
+ err = -ENOMEM;
+ pr_err("Unable to register input device ps: %s\n",
+ data->input_dev_ps->name);
+ goto exit_unregister_dev_als;
+ }
+
+ /* Register sysfs hooks */
+ err = sysfs_create_group(&client->dev.kobj, &apds990x_attr_group);
+ if (err)
+ goto exit_unregister_dev_ps;
+
+ err = request_threaded_irq(data->pdata->irq, NULL, apds990x_interrupt, IRQ_TYPE_EDGE_FALLING,
+ APDS990x_DRV_NAME, (void *)client);
+ if (err) {
+ pr_err("%s Could not allocate irq(%d) !\n", __func__, data->pdata->irq);
+ goto exit_remove_sysfs;
+ }
+ device_init_wakeup(&client->dev, 1);
+ pr_debug("%s support ver. %s enabled\n", __func__, DRIVER_VERSION);
+
+ return 0;
+
+exit_remove_sysfs:
+ sysfs_remove_group(&client->dev.kobj, &apds990x_attr_group);
+exit_unregister_dev_ps:
+ input_unregister_device(data->input_dev_ps);
+exit_unregister_dev_als:
+ input_unregister_device(data->input_dev_als);
+exit_free_dev_ps:
+ input_free_device(data->input_dev_ps);
+exit_free_dev_als:
+ input_free_device(data->input_dev_als);
+exit_kfree:
+ wake_lock_destroy(&data->prx_wake_lock);
+ kfree(data);
+exit:
+ return err;
+}
+
+static int __devexit apds990x_remove(struct i2c_client *client)
+{
+ struct apds990x_data *data = i2c_get_clientdata(client);
+
+ disable_irq(data->pdata->irq);
+ device_init_wakeup(&client->dev, 0);
+ cancel_delayed_work_sync(&data->als_dwork);
+
+ input_unregister_device(data->input_dev_als);
+ input_unregister_device(data->input_dev_ps);
+
+ input_free_device(data->input_dev_als);
+ input_free_device(data->input_dev_ps);
+
+ free_irq(data->pdata->irq, client);
+
+ sysfs_remove_group(&client->dev.kobj, &apds990x_attr_group);
+
+ /* Power down the device */
+ apds990x_set_enable(client, 0);
+
+ wake_lock_destroy(&data->prx_wake_lock);
+ kfree(data);
+
+ return 0;
+}
+
+#ifdef CONFIG_PM
+
+static int apds990x_suspend(struct i2c_client *client, pm_message_t mesg)
+{
+ struct apds990x_data *data = i2c_get_clientdata(client);
+ int enable = 0;
+
+ disable_irq(data->pdata->irq);
+ if (data->enable_als_sensor)
+ cancel_delayed_work_sync(&data->als_dwork);
+
+ if (data->enable_ps_sensor) {
+ enable = 0x27;
+ enable_irq_wake(data->pdata->irq);
+ }
+
+ if (enable != data->enable)
+ apds990x_set_enable(client, enable);
+
+ return 0;
+}
+
+static int apds990x_resume(struct i2c_client *client)
+{
+ struct apds990x_data *data = i2c_get_clientdata(client);
+ int enable = 0;
+
+ if (data->enable_als_sensor)
+ enable |= 0x03;
+
+ if (data->enable_ps_sensor) {
+ enable |= 0x27;
+ disable_irq_wake(data->pdata->irq);
+ }
+
+ if (enable != 0x27)
+ apds990x_set_enable(client, enable);
+
+ if (data->enable_als_sensor)
+ schedule_delayed_work(&data->als_dwork, msecs_to_jiffies(data->als_poll_delay));
+
+ enable_irq(data->pdata->irq);
+
+ return 0;
+}
+
+#else
+
+#define apds990x_suspend NULL
+#define apds990x_resume NULL
+
+#endif /* CONFIG_PM */
+
+static const struct i2c_device_id apds990x_id[] = {
+ { "apds990x", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, apds990x_id);
+
+static struct i2c_driver apds990x_driver = {
+ .driver = {
+ .name = APDS990x_DRV_NAME,
+ .owner = THIS_MODULE,
+ },
+ .suspend = apds990x_suspend,
+ .resume = apds990x_resume,
+ .probe = apds990x_probe,
+ .remove = __devexit_p(apds990x_remove),
+ .id_table = apds990x_id,
+};
+
+static int __init apds990x_init(void)
+{
+ return i2c_add_driver(&apds990x_driver);
+}
+
+static void __exit apds990x_exit(void)
+{
+ i2c_del_driver(&apds990x_driver);
+}
+
+MODULE_DESCRIPTION("APDS990X combined ALS and proximity sensor");
+MODULE_AUTHOR("Samu Onkalo, Nokia Corporation");
+MODULE_LICENSE("GPL v2");
+MODULE_VERSION(DRIVER_VERSION);
+
+module_init(apds990x_init);
+module_exit(apds990x_exit);
diff --git a/drivers/input/misc/bma250.c b/drivers/input/misc/bma250.c
new file mode 100644
index 0000000..dbee078
--- /dev/null
+++ b/drivers/input/misc/bma250.c
@@ -0,0 +1,933 @@
+/*
+ * Copyright (c) 2012-2013, The Linux Foundation. All Rights Reserved.
+ * Copyright (C) 2011, Bosch Sensortec GmbH All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * Date: 2011/4/8 11:00:00
+ * Revision: 2.5
+ *
+ * file BMA250.c
+ * brief This file contains all function implementations for the BMA250 in linux
+ *
+*/
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/i2c.h>
+#include <linux/input.h>
+#include <linux/workqueue.h>
+#include <linux/mutex.h>
+#include <linux/slab.h>
+#include <linux/mutex.h>
+#include <linux/earlysuspend.h>
+
+#define SENSOR_NAME "bma250"
+#define GRAVITY_EARTH 9806550
+#define ABSMIN_2G (-GRAVITY_EARTH * 2)
+#define ABSMAX_2G (GRAVITY_EARTH * 2)
+#define SLOPE_THRESHOLD_VALUE 32
+#define SLOPE_DURATION_VALUE 1
+#define INTERRUPT_LATCH_MODE 13
+#define INTERRUPT_ENABLE 1
+#define INTERRUPT_DISABLE 0
+#define MAP_SLOPE_INTERRUPT 2
+#define SLOPE_X_INDEX 5
+#define SLOPE_Y_INDEX 6
+#define SLOPE_Z_INDEX 7
+#define BMA250_MAX_DELAY 200
+#define BMA250_CHIP_ID 3
+#define BMA250E_CHIP_ID1 0xF8
+#define BMA250E_CHIP_ID2 0xF9
+#define BMA250_RANGE_SET 0
+#define BMA250_BW_SET 4
+
+/*
+ *
+ * register definitions
+ *
+ */
+
+#define BMA250_CHIP_ID_REG 0x00
+#define BMA250_VERSION_REG 0x01
+#define BMA250_X_AXIS_LSB_REG 0x02
+#define BMA250_X_AXIS_MSB_REG 0x03
+#define BMA250_Y_AXIS_LSB_REG 0x04
+#define BMA250_Y_AXIS_MSB_REG 0x05
+#define BMA250_Z_AXIS_LSB_REG 0x06
+#define BMA250_Z_AXIS_MSB_REG 0x07
+#define BMA250_TEMP_RD_REG 0x08
+#define BMA250_STATUS1_REG 0x09
+#define BMA250_STATUS2_REG 0x0A
+#define BMA250_STATUS_TAP_SLOPE_REG 0x0B
+#define BMA250_STATUS_ORIENT_HIGH_REG 0x0C
+#define BMA250_RANGE_SEL_REG 0x0F
+#define BMA250_BW_SEL_REG 0x10
+#define BMA250_MODE_CTRL_REG 0x11
+#define BMA250_LOW_NOISE_CTRL_REG 0x12
+#define BMA250_DATA_CTRL_REG 0x13
+#define BMA250_RESET_REG 0x14
+#define BMA250_INT_ENABLE1_REG 0x16
+#define BMA250_INT_ENABLE2_REG 0x17
+#define BMA250_INT1_PAD_SEL_REG 0x19
+#define BMA250_INT_DATA_SEL_REG 0x1A
+#define BMA250_INT2_PAD_SEL_REG 0x1B
+#define BMA250_INT_SRC_REG 0x1E
+#define BMA250_INT_SET_REG 0x20
+#define BMA250_INT_CTRL_REG 0x21
+#define BMA250_LOW_DURN_REG 0x22
+#define BMA250_LOW_THRES_REG 0x23
+#define BMA250_LOW_HIGH_HYST_REG 0x24
+#define BMA250_HIGH_DURN_REG 0x25
+#define BMA250_HIGH_THRES_REG 0x26
+#define BMA250_SLOPE_DURN_REG 0x27
+#define BMA250_SLOPE_THRES_REG 0x28
+#define BMA250_TAP_PARAM_REG 0x2A
+#define BMA250_TAP_THRES_REG 0x2B
+#define BMA250_ORIENT_PARAM_REG 0x2C
+#define BMA250_THETA_BLOCK_REG 0x2D
+#define BMA250_THETA_FLAT_REG 0x2E
+#define BMA250_FLAT_HOLD_TIME_REG 0x2F
+#define BMA250_STATUS_LOW_POWER_REG 0x31
+#define BMA250_SELF_TEST_REG 0x32
+#define BMA250_EEPROM_CTRL_REG 0x33
+#define BMA250_SERIAL_CTRL_REG 0x34
+#define BMA250_CTRL_UNLOCK_REG 0x35
+#define BMA250_OFFSET_CTRL_REG 0x36
+#define BMA250_OFFSET_PARAMS_REG 0x37
+#define BMA250_OFFSET_FILT_X_REG 0x38
+#define BMA250_OFFSET_FILT_Y_REG 0x39
+#define BMA250_OFFSET_FILT_Z_REG 0x3A
+#define BMA250_OFFSET_UNFILT_X_REG 0x3B
+#define BMA250_OFFSET_UNFILT_Y_REG 0x3C
+#define BMA250_OFFSET_UNFILT_Z_REG 0x3D
+#define BMA250_SPARE_0_REG 0x3E
+#define BMA250_SPARE_1_REG 0x3F
+
+#define BMA250_ACC_X_LSB__POS 6
+#define BMA250_ACC_X_LSB__LEN 2
+#define BMA250_ACC_X_LSB__MSK 0xC0
+#define BMA250_ACC_X_LSB__REG BMA250_X_AXIS_LSB_REG
+
+#define BMA250_ACC_X_MSB__POS 0
+#define BMA250_ACC_X_MSB__LEN 8
+#define BMA250_ACC_X_MSB__MSK 0xFF
+#define BMA250_ACC_X_MSB__REG BMA250_X_AXIS_MSB_REG
+
+#define BMA250_ACC_Y_LSB__POS 6
+#define BMA250_ACC_Y_LSB__LEN 2
+#define BMA250_ACC_Y_LSB__MSK 0xC0
+#define BMA250_ACC_Y_LSB__REG BMA250_Y_AXIS_LSB_REG
+
+#define BMA250_ACC_Y_MSB__POS 0
+#define BMA250_ACC_Y_MSB__LEN 8
+#define BMA250_ACC_Y_MSB__MSK 0xFF
+#define BMA250_ACC_Y_MSB__REG BMA250_Y_AXIS_MSB_REG
+
+#define BMA250_ACC_Z_LSB__POS 6
+#define BMA250_ACC_Z_LSB__LEN 2
+#define BMA250_ACC_Z_LSB__MSK 0xC0
+#define BMA250_ACC_Z_LSB__REG BMA250_Z_AXIS_LSB_REG
+
+#define BMA250_ACC_Z_MSB__POS 0
+#define BMA250_ACC_Z_MSB__LEN 8
+#define BMA250_ACC_Z_MSB__MSK 0xFF
+#define BMA250_ACC_Z_MSB__REG BMA250_Z_AXIS_MSB_REG
+
+#define BMA250_RANGE_SEL__POS 0
+#define BMA250_RANGE_SEL__LEN 4
+#define BMA250_RANGE_SEL__MSK 0x0F
+#define BMA250_RANGE_SEL__REG BMA250_RANGE_SEL_REG
+
+#define BMA250_BANDWIDTH__POS 0
+#define BMA250_BANDWIDTH__LEN 5
+#define BMA250_BANDWIDTH__MSK 0x1F
+#define BMA250_BANDWIDTH__REG BMA250_BW_SEL_REG
+
+#define BMA250_EN_LOW_POWER__POS 6
+#define BMA250_EN_LOW_POWER__LEN 1
+#define BMA250_EN_LOW_POWER__MSK 0x40
+#define BMA250_EN_LOW_POWER__REG BMA250_MODE_CTRL_REG
+
+#define BMA250_EN_SUSPEND__POS 7
+#define BMA250_EN_SUSPEND__LEN 1
+#define BMA250_EN_SUSPEND__MSK 0x80
+#define BMA250_EN_SUSPEND__REG BMA250_MODE_CTRL_REG
+
+#define BMA250_EN_LOW__POS 1
+#define BMA250_EN_LOW__LEN 4
+#define BMA250_EN_LOW__MSK 0x1E
+#define BMA250_EN_LOW__REG BMA250_MODE_CTRL_REG
+
+#define BMA250_GET_BITSLICE(regvar, bitname)\
+ ((regvar & bitname##__MSK) >> bitname##__POS)
+
+#define BMA250_SET_BITSLICE(regvar, bitname, val)\
+ ((regvar & ~bitname##__MSK) | ((val<<bitname##__POS)&bitname##__MSK))
+
+/* range and bandwidth */
+
+#define BMA250_RANGE_2G 0
+#define BMA250_RANGE_4G 1
+#define BMA250_RANGE_8G 2
+#define BMA250_RANGE_16G 3
+
+#define BMA250_BW_7_81HZ 0x08
+#define BMA250_BW_15_63HZ 0x09
+#define BMA250_BW_31_25HZ 0x0A
+#define BMA250_BW_62_50HZ 0x0B
+#define BMA250_BW_125HZ 0x0C
+#define BMA250_BW_250HZ 0x0D
+#define BMA250_BW_500HZ 0x0E
+#define BMA250_BW_1000HZ 0x0F
+
+/* mode settings */
+
+#define BMA250_MODE_NORMAL 0
+#define BMA250_MODE_LOWPOWER 1
+#define BMA250_MODE_SUSPEND 2
+
+struct bma250acc {
+ s16 x, y, z;
+};
+
+struct bma250_data {
+ struct i2c_client *bma250_client;
+ atomic_t delay;
+ atomic_t enable;
+ unsigned char mode;
+ struct input_dev *input;
+ struct bma250acc value;
+ struct mutex value_mutex;
+ struct mutex enable_mutex;
+ struct mutex mode_mutex;
+ struct delayed_work work;
+ struct work_struct irq_work;
+ struct early_suspend early_suspend;
+};
+
+static void bma250_early_suspend(struct early_suspend *h);
+static void bma250_late_resume(struct early_suspend *h);
+
+static int bma250_smbus_read_byte(struct i2c_client *client,
+ unsigned char reg_addr, unsigned char *data)
+{
+ s32 dummy;
+ dummy = i2c_smbus_read_byte_data(client, reg_addr);
+ if (dummy < 0)
+ return -1;
+ *data = dummy & 0x000000ff;
+
+ return 0;
+}
+
+static int bma250_smbus_write_byte(struct i2c_client *client,
+ unsigned char reg_addr, unsigned char *data)
+{
+ s32 dummy;
+ dummy = i2c_smbus_write_byte_data(client, reg_addr, *data);
+ if (dummy < 0)
+ return -1;
+ return 0;
+}
+
+static int bma250_smbus_read_byte_block(struct i2c_client *client,
+ unsigned char reg_addr,
+ unsigned char *data, unsigned char len)
+{
+ s32 dummy;
+ dummy = i2c_smbus_read_i2c_block_data(client, reg_addr, len, data);
+ if (dummy < 0)
+ return -1;
+ return 0;
+}
+
+static int bma250_set_mode(struct i2c_client *client, unsigned char Mode)
+{
+ int comres = 0;
+ unsigned char data1 = 0;
+
+ if (client == NULL) {
+ comres = -1;
+ } else {
+ if (Mode < 3) {
+ comres = bma250_smbus_read_byte(client,
+ BMA250_EN_LOW_POWER__REG,
+ &data1);
+ switch (Mode) {
+ case BMA250_MODE_NORMAL:
+ data1 = BMA250_SET_BITSLICE(data1,
+ BMA250_EN_LOW_POWER,
+ 0);
+ data1 =
+ BMA250_SET_BITSLICE(data1,
+ BMA250_EN_SUSPEND, 0);
+ break;
+ case BMA250_MODE_LOWPOWER:
+ data1 = BMA250_SET_BITSLICE(data1,
+ BMA250_EN_LOW_POWER,
+ 1);
+ data1 =
+ BMA250_SET_BITSLICE(data1,
+ BMA250_EN_SUSPEND, 0);
+ break;
+ case BMA250_MODE_SUSPEND:
+ data1 = BMA250_SET_BITSLICE(data1,
+ BMA250_EN_LOW_POWER,
+ 0);
+ data1 =
+ BMA250_SET_BITSLICE(data1,
+ BMA250_EN_SUSPEND, 1);
+ break;
+ default:
+ break;
+ }
+
+ comres += bma250_smbus_write_byte(client,
+ BMA250_EN_LOW_POWER__REG,
+ &data1);
+ } else {
+ comres = -1;
+ }
+ }
+
+ return comres;
+}
+
+static int bma250_get_mode(struct i2c_client *client, unsigned char *Mode)
+{
+ int comres = 0;
+
+ if (client == NULL) {
+ comres = -1;
+ } else {
+ comres = bma250_smbus_read_byte(client,
+ BMA250_EN_LOW_POWER__REG, Mode);
+ *Mode = (*Mode) >> 6;
+ }
+
+ return comres;
+}
+
+static int bma250_set_range(struct i2c_client *client, unsigned char Range)
+{
+ int comres = 0;
+ unsigned char data1 = '\0';
+
+ if (client == NULL) {
+ comres = -1;
+ } else {
+ if (Range < 4) {
+ comres = bma250_smbus_read_byte(client,
+ BMA250_RANGE_SEL_REG,
+ &data1);
+ switch (Range) {
+ case 0:
+ data1 = BMA250_SET_BITSLICE(data1,
+ BMA250_RANGE_SEL,
+ 0);
+ break;
+ case 1:
+ data1 = BMA250_SET_BITSLICE(data1,
+ BMA250_RANGE_SEL,
+ 5);
+ break;
+ case 2:
+ data1 = BMA250_SET_BITSLICE(data1,
+ BMA250_RANGE_SEL,
+ 8);
+ break;
+ case 3:
+ data1 = BMA250_SET_BITSLICE(data1,
+ BMA250_RANGE_SEL,
+ 12);
+ break;
+ default:
+ break;
+ }
+ comres += bma250_smbus_write_byte(client,
+ BMA250_RANGE_SEL_REG,
+ &data1);
+ } else {
+ comres = -1;
+ }
+ }
+
+ return comres;
+}
+
+static int bma250_get_range(struct i2c_client *client, unsigned char *Range)
+{
+ int comres = 0;
+ unsigned char data = '\0';
+
+ if (client == NULL) {
+ comres = -1;
+ } else {
+ comres = bma250_smbus_read_byte(client, BMA250_RANGE_SEL__REG,
+ &data);
+ data = BMA250_GET_BITSLICE(data, BMA250_RANGE_SEL);
+ *Range = data;
+ }
+
+ return comres;
+}
+
+static int bma250_set_bandwidth(struct i2c_client *client, unsigned char BW)
+{
+ int comres = 0;
+ unsigned char data = '\0';
+ int Bandwidth = 0;
+
+ if (client == NULL) {
+ comres = -1;
+ } else {
+ if (BW < 8) {
+ switch (BW) {
+ case 0:
+ Bandwidth = BMA250_BW_7_81HZ;
+ break;
+ case 1:
+ Bandwidth = BMA250_BW_15_63HZ;
+ break;
+ case 2:
+ Bandwidth = BMA250_BW_31_25HZ;
+ break;
+ case 3:
+ Bandwidth = BMA250_BW_62_50HZ;
+ break;
+ case 4:
+ Bandwidth = BMA250_BW_125HZ;
+ break;
+ case 5:
+ Bandwidth = BMA250_BW_250HZ;
+ break;
+ case 6:
+ Bandwidth = BMA250_BW_500HZ;
+ break;
+ case 7:
+ Bandwidth = BMA250_BW_1000HZ;
+ break;
+ default:
+ break;
+ }
+ comres = bma250_smbus_read_byte(client,
+ BMA250_BANDWIDTH__REG,
+ &data);
+ data =
+ BMA250_SET_BITSLICE(data, BMA250_BANDWIDTH,
+ Bandwidth);
+ comres +=
+ bma250_smbus_write_byte(client,
+ BMA250_BANDWIDTH__REG,
+ &data);
+ } else {
+ comres = -1;
+ }
+ }
+
+ return comres;
+}
+
+static int bma250_get_bandwidth(struct i2c_client *client, unsigned char *BW)
+{
+ int comres = 0;
+ unsigned char data = '\0';
+
+ if (client == NULL) {
+ comres = -1;
+ } else {
+ comres = bma250_smbus_read_byte(client, BMA250_BANDWIDTH__REG,
+ &data);
+ data = BMA250_GET_BITSLICE(data, BMA250_BANDWIDTH);
+ if (data <= 8) {
+ *BW = 0;
+ } else {
+ if (data >= 0x0F)
+ *BW = 7;
+ else
+ *BW = data - 8;
+
+ }
+ }
+
+ return comres;
+}
+
+static int bma250_read_accel_xyz(struct i2c_client *client,
+ struct bma250acc *acc)
+{
+ int comres;
+ unsigned char data[6];
+ if (client == NULL) {
+ comres = -1;
+ } else {
+ comres = bma250_smbus_read_byte_block(client,
+ BMA250_ACC_X_LSB__REG,
+ data, 6);
+
+ acc->x = BMA250_GET_BITSLICE(data[0], BMA250_ACC_X_LSB)
+ | (BMA250_GET_BITSLICE(data[1],
+ BMA250_ACC_X_MSB) <<
+ BMA250_ACC_X_LSB__LEN);
+ acc->x =
+ acc->x << (sizeof(short) * 8 -
+ (BMA250_ACC_X_LSB__LEN + BMA250_ACC_X_MSB__LEN));
+ acc->x =
+ acc->x >> (sizeof(short) * 8 -
+ (BMA250_ACC_X_LSB__LEN + BMA250_ACC_X_MSB__LEN));
+ acc->y = BMA250_GET_BITSLICE(data[2], BMA250_ACC_Y_LSB)
+ | (BMA250_GET_BITSLICE(data[3],
+ BMA250_ACC_Y_MSB) <<
+ BMA250_ACC_Y_LSB__LEN);
+ acc->y =
+ acc->y << (sizeof(short) * 8 -
+ (BMA250_ACC_Y_LSB__LEN + BMA250_ACC_Y_MSB__LEN));
+ acc->y =
+ acc->y >> (sizeof(short) * 8 -
+ (BMA250_ACC_Y_LSB__LEN + BMA250_ACC_Y_MSB__LEN));
+
+ acc->z = BMA250_GET_BITSLICE(data[4], BMA250_ACC_Z_LSB)
+ | (BMA250_GET_BITSLICE(data[5],
+ BMA250_ACC_Z_MSB) <<
+ BMA250_ACC_Z_LSB__LEN);
+ acc->z =
+ acc->z << (sizeof(short) * 8 -
+ (BMA250_ACC_Z_LSB__LEN + BMA250_ACC_Z_MSB__LEN));
+ acc->z =
+ acc->z >> (sizeof(short) * 8 -
+ (BMA250_ACC_Z_LSB__LEN + BMA250_ACC_Z_MSB__LEN));
+ }
+
+ return comres;
+}
+
+static void bma250_work_func(struct work_struct *work)
+{
+ struct bma250_data *bma250 = container_of((struct delayed_work *)work,
+ struct bma250_data, work);
+ static struct bma250acc acc;
+ unsigned long delay = msecs_to_jiffies(atomic_read(&bma250->delay));
+
+ bma250_read_accel_xyz(bma250->bma250_client, &acc);
+ /*adjust the data output for skud compatible */
+ input_report_rel(bma250->input, REL_RX, -acc.y * 4);
+ input_report_rel(bma250->input, REL_RY, acc.x * 4);
+ input_report_rel(bma250->input, REL_RZ, acc.z * 4);
+ input_sync(bma250->input);
+ mutex_lock(&bma250->value_mutex);
+ bma250->value = acc;
+ mutex_unlock(&bma250->value_mutex);
+ schedule_delayed_work(&bma250->work, delay);
+}
+
+static ssize_t bma250_range_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ unsigned char data;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct bma250_data *bma250 = i2c_get_clientdata(client);
+
+ if (bma250_get_range(bma250->bma250_client, &data) < 0)
+ return sprintf(buf, "Read error\n");
+
+ return sprintf(buf, "%d\n", data);
+}
+
+static ssize_t bma250_range_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long data;
+ int error;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct bma250_data *bma250 = i2c_get_clientdata(client);
+
+ error = strict_strtoul(buf, 10, &data);
+ if (error)
+ return error;
+ if (bma250_set_range(bma250->bma250_client, (unsigned char)data) < 0)
+ return -EINVAL;
+
+ return count;
+}
+
+static ssize_t bma250_bandwidth_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ unsigned char data;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct bma250_data *bma250 = i2c_get_clientdata(client);
+
+ if (bma250_get_bandwidth(bma250->bma250_client, &data) < 0)
+ return sprintf(buf, "Read error\n");
+
+ return sprintf(buf, "%d\n", data);
+
+}
+
+static ssize_t bma250_bandwidth_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long data;
+ int error;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct bma250_data *bma250 = i2c_get_clientdata(client);
+
+ error = strict_strtoul(buf, 10, &data);
+ if (error)
+ return error;
+ if (bma250_set_bandwidth(bma250->bma250_client,
+ (unsigned char)data) < 0)
+ return -EINVAL;
+
+ return count;
+}
+
+static ssize_t bma250_mode_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ unsigned char data;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct bma250_data *bma250 = i2c_get_clientdata(client);
+
+ if (bma250_get_mode(bma250->bma250_client, &data) < 0)
+ return sprintf(buf, "Read error\n");
+
+ return sprintf(buf, "%d\n", data);
+}
+
+static ssize_t bma250_mode_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long data;
+ int error;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct bma250_data *bma250 = i2c_get_clientdata(client);
+
+ error = strict_strtoul(buf, 10, &data);
+ if (error)
+ return error;
+ if (bma250_set_mode(bma250->bma250_client, (unsigned char)data) < 0)
+ return -EINVAL;
+
+ return count;
+}
+
+static ssize_t bma250_value_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct input_dev *input = to_input_dev(dev);
+ struct bma250_data *bma250 = input_get_drvdata(input);
+ struct bma250acc acc_value;
+
+ mutex_lock(&bma250->value_mutex);
+ acc_value = bma250->value;
+ mutex_unlock(&bma250->value_mutex);
+
+ return sprintf(buf, "%d %d %d\n", acc_value.x, acc_value.y,
+ acc_value.z);
+}
+
+static ssize_t bma250_delay_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct bma250_data *bma250 = i2c_get_clientdata(client);
+
+ return sprintf(buf, "%d\n", atomic_read(&bma250->delay));
+
+}
+
+static ssize_t bma250_delay_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long data;
+ int error;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct bma250_data *bma250 = i2c_get_clientdata(client);
+
+ error = strict_strtoul(buf, 10, &data);
+ if (error)
+ return error;
+ if (data > BMA250_MAX_DELAY)
+ data = BMA250_MAX_DELAY;
+ atomic_set(&bma250->delay, (unsigned int)data);
+
+ return count;
+}
+
+static ssize_t bma250_enable_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct bma250_data *bma250 = i2c_get_clientdata(client);
+
+ return sprintf(buf, "%d\n", atomic_read(&bma250->enable));
+
+}
+
+static void bma250_set_enable(struct device *dev, int enable)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct bma250_data *bma250 = i2c_get_clientdata(client);
+ int pre_enable = atomic_read(&bma250->enable);
+
+ mutex_lock(&bma250->enable_mutex);
+ if (enable) {
+ if (pre_enable == 0) {
+ bma250_set_mode(bma250->bma250_client,
+ BMA250_MODE_NORMAL);
+ schedule_delayed_work(&bma250->work,
+ msecs_to_jiffies(atomic_read
+ (&bma250->
+ delay)));
+ atomic_set(&bma250->enable, 1);
+ }
+
+ } else {
+ if (pre_enable == 1) {
+ bma250_set_mode(bma250->bma250_client,
+ BMA250_MODE_SUSPEND);
+ cancel_delayed_work_sync(&bma250->work);
+ atomic_set(&bma250->enable, 0);
+ }
+ }
+ mutex_unlock(&bma250->enable_mutex);
+
+}
+
+static ssize_t bma250_enable_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ unsigned long data;
+ int error;
+
+ error = strict_strtoul(buf, 10, &data);
+ if (error)
+ return error;
+ if ((data == 0) || (data == 1)) {
+ bma250_set_enable(dev, data);
+ }
+
+ return count;
+}
+
+static DEVICE_ATTR(range, S_IRUGO | S_IWUSR | S_IWGRP,
+ bma250_range_show, bma250_range_store);
+static DEVICE_ATTR(bandwidth, S_IRUGO | S_IWUSR | S_IWGRP,
+ bma250_bandwidth_show, bma250_bandwidth_store);
+static DEVICE_ATTR(mode, S_IRUGO | S_IWUSR | S_IWGRP,
+ bma250_mode_show, bma250_mode_store);
+static DEVICE_ATTR(value, S_IRUGO, bma250_value_show, NULL);
+static DEVICE_ATTR(poll_delay, S_IRUGO | S_IWUSR | S_IWGRP,
+ bma250_delay_show, bma250_delay_store);
+static DEVICE_ATTR(enable, S_IRUGO | S_IWUSR | S_IWGRP,
+ bma250_enable_show, bma250_enable_store);
+
+static struct attribute *bma250_attributes[] = {
+ &dev_attr_range.attr,
+ &dev_attr_bandwidth.attr,
+ &dev_attr_mode.attr,
+ &dev_attr_value.attr,
+ &dev_attr_poll_delay.attr,
+ &dev_attr_enable.attr,
+ NULL
+};
+
+static struct attribute_group bma250_attribute_group = {
+ .attrs = bma250_attributes
+};
+
+static int bma250_input_init(struct bma250_data *bma250)
+{
+ struct input_dev *dev;
+ int err;
+
+ dev = input_allocate_device();
+ if (!dev)
+ return -ENOMEM;
+ dev->name = "acc"; //SENSOR_NAME; changed for sku1 compatible
+ dev->id.bustype = BUS_I2C;
+
+ /* X */
+ input_set_capability(dev, EV_REL, REL_RX);
+ input_set_abs_params(dev, REL_RX, ABSMIN_2G, ABSMAX_2G, 0, 0);
+ /* Y */
+ input_set_capability(dev, EV_REL, REL_RY);
+ input_set_abs_params(dev, REL_RY, ABSMIN_2G, ABSMAX_2G, 0, 0);
+ /* Z */
+ input_set_capability(dev, EV_REL, REL_RZ);
+ input_set_abs_params(dev, REL_RZ, ABSMIN_2G, ABSMAX_2G, 0, 0);
+ input_set_drvdata(dev, bma250);
+
+ err = input_register_device(dev);
+ if (err < 0) {
+ input_free_device(dev);
+ return err;
+ }
+ bma250->input = dev;
+
+ return 0;
+}
+
+static void bma250_input_delete(struct bma250_data *bma250)
+{
+ struct input_dev *dev = bma250->input;
+
+ input_unregister_device(dev);
+ input_free_device(dev);
+}
+
+static int bma250_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ int err = 0;
+ int tempvalue;
+ struct bma250_data *data;
+
+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
+ printk(KERN_INFO "i2c_check_functionality error\n");
+ goto exit;
+ }
+ data = kzalloc(sizeof(struct bma250_data), GFP_KERNEL);
+ if (!data) {
+ err = -ENOMEM;
+ goto exit;
+ }
+ /* read chip id */
+ tempvalue = 0;
+ tempvalue = i2c_smbus_read_word_data(client, BMA250_CHIP_ID_REG) & 0x00FF;
+ /* SKUD board is using BMA250E chip! */
+ if (tempvalue == BMA250E_CHIP_ID1 || tempvalue == BMA250E_CHIP_ID2) {
+ printk(KERN_INFO "Bosch Sensortec Device detected!\n"
+ "BMA250 registered I2C driver!\n");
+ } else {
+ printk(KERN_INFO "Bosch Sensortec Device not found, \
+ i2c error %d \n", tempvalue);
+ err = -1;
+ goto kfree_exit;
+ }
+ i2c_set_clientdata(client, data);
+ data->bma250_client = client;
+ mutex_init(&data->value_mutex);
+ mutex_init(&data->mode_mutex);
+ mutex_init(&data->enable_mutex);
+ bma250_set_bandwidth(client, BMA250_BW_SET);
+ bma250_set_range(client, BMA250_RANGE_SET);
+
+ INIT_DELAYED_WORK(&data->work, bma250_work_func);
+ atomic_set(&data->delay, BMA250_MAX_DELAY);
+ atomic_set(&data->enable, 0);
+ err = bma250_input_init(data);
+ if (err < 0)
+ goto kfree_exit;
+
+ err = sysfs_create_group(&data->input->dev.kobj,
+ &bma250_attribute_group);
+ if (err < 0)
+ goto error_sysfs;
+
+ data->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1;
+ data->early_suspend.suspend = bma250_early_suspend;
+ data->early_suspend.resume = bma250_late_resume;
+ register_early_suspend(&data->early_suspend);
+ /* try to reduce the power comsuption */
+ bma250_set_mode(data->bma250_client, BMA250_MODE_SUSPEND);
+
+ return 0;
+
+error_sysfs:
+ bma250_input_delete(data);
+
+kfree_exit:
+ kfree(data);
+exit:
+ return err;
+}
+
+static void bma250_early_suspend(struct early_suspend *h)
+{
+ struct bma250_data *data =
+ container_of(h, struct bma250_data, early_suspend);
+
+ mutex_lock(&data->enable_mutex);
+ if (atomic_read(&data->enable) == 1) {
+ bma250_set_mode(data->bma250_client, BMA250_MODE_SUSPEND);
+ cancel_delayed_work_sync(&data->work);
+ }
+ mutex_unlock(&data->enable_mutex);
+}
+
+static void bma250_late_resume(struct early_suspend *h)
+{
+ struct bma250_data *data =
+ container_of(h, struct bma250_data, early_suspend);
+
+ mutex_lock(&data->enable_mutex);
+ if (atomic_read(&data->enable) == 1) {
+ bma250_set_mode(data->bma250_client, BMA250_MODE_NORMAL);
+ schedule_delayed_work(&data->work,
+ msecs_to_jiffies(atomic_read
+ (&data->delay)));
+ }
+ mutex_unlock(&data->enable_mutex);
+}
+
+static int bma250_remove(struct i2c_client *client)
+{
+ struct bma250_data *data = i2c_get_clientdata(client);
+
+ bma250_set_enable(&client->dev, 0);
+ unregister_early_suspend(&data->early_suspend);
+ sysfs_remove_group(&data->input->dev.kobj, &bma250_attribute_group);
+ bma250_input_delete(data);
+ kfree(data);
+ return 0;
+}
+
+static const struct i2c_device_id bma250_id[] = {
+ {SENSOR_NAME, 0},
+ {}
+};
+
+MODULE_DEVICE_TABLE(i2c, bma250_id);
+
+static struct i2c_driver bma250_driver = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = SENSOR_NAME,
+ },
+ .id_table = bma250_id,
+ .probe = bma250_probe,
+ .remove = bma250_remove,
+
+};
+
+static int __init BMA250_init(void)
+{
+ return i2c_add_driver(&bma250_driver);
+}
+
+static void __exit BMA250_exit(void)
+{
+ i2c_del_driver(&bma250_driver);
+}
+
+MODULE_AUTHOR("Albert Zhang <xu.zhang@bosch-sensortec.com>");
+MODULE_DESCRIPTION("BMA250 driver");
+MODULE_LICENSE("GPL");
+
+module_init(BMA250_init);
+module_exit(BMA250_exit);
diff --git a/drivers/input/misc/isl29028.c b/drivers/input/misc/isl29028.c
new file mode 100644
index 0000000..93cc32a
--- /dev/null
+++ b/drivers/input/misc/isl29028.c
@@ -0,0 +1,816 @@
+/*
+ * Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <asm/uaccess.h>
+#include <asm/atomic.h>
+#include <asm/signal.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/fs.h>
+#include <linux/seq_file.h>
+#include <linux/proc_fs.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/device.h>
+#include <linux/poll.h>
+#include <linux/stat.h>
+#include <linux/time.h>
+#include <linux/workqueue.h>
+#include <linux/input.h>
+#include <linux/i2c.h>
+#include <linux/delay.h>
+#include <linux/wakelock.h>
+#include <linux/semaphore.h>
+#include <linux/sysfs.h>
+#include <linux/mutex.h>
+#include <linux/irq.h>
+#include <linux/miscdevice.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/earlysuspend.h>
+#include <linux/input/isl29028.h>
+
+
+#define ISL29028_MODULE_NAME "isl29028"
+#define DRIVER_VERSION "1.0.0"
+#define ISL29028_I2C_ADDR 0x44
+#define ISL29028_INTR 17
+
+#define DEFAULT_PROX_INTERVAL 200//ms200-100 inprove performance
+#define DEFAULT_ALS_INTERVAL 500//ms
+
+#define CONFIG_ALS_H_RANGE
+#ifdef CONFIG_ALS_H_RANGE
+#define CONFIG_VAL (ALS_H_RANGE | SLP_200MS)//proximity sleep pulse 200ms
+#else
+#define CONFIG_VAL 0x00
+#endif
+#define INTERRUPT_VAL 0x20
+
+//isl29028
+#define ISL29028_CONFIG 0x01
+#define ISL29028_INTCONFIG 0x02
+//PROX
+#define ISL29028_PROX_LT 0x03
+#define ISL29028_PROX_HT 0x04
+//ALS
+#define ISL29028_ALSIR_TH1 0x05
+#define ISL29028_ALSIR_TH2 0x06
+#define ISL29028_ALSIR_TH3 0x07
+//PROX
+#define ISL29028_PROX_DATA 0x08
+//ALS
+#define ISL29028_ALSIR_DATA1 0x09
+#define ISL29028_ALSIR_DATA2 0x0A
+
+#define ISl29028_TEST1 0x0E
+#define ISl29028_TEST2 0x0F
+
+#define ALS_H_RANGE (1<<1)
+#define ALS_EN (1<<2)
+#define PROX_DR (1<<3)
+#define PROX_EN (1<<7)
+#define PROX_SLP (0x07<<4)
+#define SLP_800MS (0<<4)
+#define SLP_400MS (1<<4)
+#define SLP_200MS (2<<4)
+#define SLP_100MS (3<<4)
+#define SLP_75MS (4<<4)
+#define SLP_50MS (5<<4)
+#define SLP_12DOT5MS (6<<4)
+
+#define PROX_FLAG (1<<7)
+#define ALS_FLAG (1<<3)
+
+#define ID_TYPE_LIGHT (1<<31)
+#define ID_TYPE_PROX (1<<30)
+
+#define CURRENT_100MA (100 <<8)
+#define CURRENT_200MA (200 <<8)
+#define PROXIMITY_MAX 140
+//#define THRESHOLD 50
+#define STEP 15
+#define ADJ_DBG
+#define NUM 5
+
+//#define ISL_DEBUG
+#ifdef ISL_DEBUG
+#define PR_DEB_IF(cond,fmt,args...) do \
+ {if(cond) printk(KERN_DEBUG "-ISL29028-SENSOR-" fmt,##args);}while(0)
+
+#define PR_DEB(fmt,args...) do \
+ {printk(KERN_DEBUG "-ISL29028-SENSOR-" fmt,##args);}while(0)
+#else
+#define PR_DEB_IF(cond,...)
+#define PR_DEB(...)
+#endif
+
+struct isl29028_data{
+ struct i2c_client *client;
+ struct input_dev *proximity_input_dev;
+ struct input_dev *light_input_dev;
+ struct delayed_work als_work;
+ struct work_struct prox_work;
+ int prox_interval;
+ int als_interval;
+ struct wake_lock prox_wake_lock;
+ atomic_t als_working;
+ atomic_t prox_working;
+ atomic_t prox_locking;
+ struct isl29028_platform_data *pdata;
+ bool ps_near;
+};
+
+static struct workqueue_struct *wq;
+static struct mutex prox_lock;
+static struct mutex als_lock;
+
+static int prox_threshold_hi = 50; //Default value
+static int prox_threshold_lo = 30;
+
+//static int threshold = THRESHOLD;
+
+/* set 3 level light sensor level*/
+#define ISL_LUX_LEVELS 3
+static const u16 isl_lux_levels[ISL_LUX_LEVELS] = {
+ 2,
+ 259,
+ 525
+};
+
+static u16 pre_lux_level = -1;
+static u16 pre_prox_cm = -1;
+
+static int isl29028_read_reg(struct i2c_client *client,
+ u8 reg, u8 *val)
+{
+ *val = i2c_smbus_read_byte_data(client, reg);
+ if (!val) {
+ pr_err("%s:i2c read failed!\n", __func__);
+ return -EIO;
+ }
+ return 0;
+}
+
+static int isl29028_write_reg(struct i2c_client *client,
+ u8 reg, u8 val)
+{
+ int ret = 0;
+
+ ret = i2c_smbus_write_byte_data(client, reg, val);
+ if (ret) {
+ pr_err("%s:i2c write failed!\n", __func__);
+ ret = -EIO;
+ }
+ return ret;
+}
+static int isl29028_prox_read(struct i2c_client *client,
+ u8 *val)
+{
+ int ret;
+
+ ret = isl29028_read_reg(client, ISL29028_PROX_DATA, val);
+ return ret;
+}
+static int isl29028_als_read(struct i2c_client *client,
+ u16 *val)
+{
+ u8 lb,hb;
+ int ret = 0;
+
+ ret |= isl29028_read_reg(client, ISL29028_ALSIR_DATA1, &lb);
+ ret |= isl29028_read_reg(client, ISL29028_ALSIR_DATA2, &hb);
+ *val = ((hb & 0x0F) << 8) | lb;
+ return ret;
+}
+static int isl29028_enable_prox(struct i2c_client *client)
+{
+ u8 temp;
+ int ret = 0;
+ char buf[2] = {0};
+
+ buf[0] = prox_threshold_hi & 0xff;
+ buf[1] = prox_threshold_lo & 0xff;
+ isl29028_write_reg(client,ISL29028_PROX_LT,buf[1]);
+ isl29028_write_reg(client,ISL29028_PROX_HT,buf[0]);
+
+ ret |= isl29028_read_reg(client, ISL29028_CONFIG, &temp);
+ temp|= PROX_EN;
+ ret |= isl29028_write_reg(client, ISL29028_CONFIG, temp);
+
+ return ret;
+}
+static int isl29028_disable_prox(struct i2c_client *client)
+{
+ u8 temp;
+ int ret = 0;
+
+ ret |= isl29028_read_reg(client, ISL29028_CONFIG, &temp);
+ temp&= ~PROX_EN;
+ ret |= isl29028_write_reg(client, ISL29028_CONFIG, temp);
+
+ return ret;
+}
+static int isl29028_enable_als(struct i2c_client *client)
+{
+ u8 temp;
+ int ret = 0;
+
+ ret |= isl29028_read_reg(client, ISL29028_CONFIG, &temp);
+ temp|= ALS_EN;
+ ret |= isl29028_write_reg(client, ISL29028_CONFIG, temp);
+
+ return ret;
+}
+static int isl29028_disable_als(struct i2c_client *client)
+{
+ u8 temp;
+ int ret = 0;
+
+ ret |= isl29028_read_reg(client, ISL29028_CONFIG, &temp);
+ temp&= ~ALS_EN;
+ ret |= isl29028_write_reg(client, ISL29028_CONFIG, temp);
+
+ return ret;
+}
+
+static void sysfs_enable_prox(int enable,struct isl29028_data *data)
+{
+ if(enable){
+ if(!atomic_read(&data->prox_working)){
+ atomic_set(&data->prox_working,1);
+ /*lock system*/
+ wake_lock(&data->prox_wake_lock);
+ atomic_set(&data->prox_locking,1);
+ PR_DEB("Enter SYSFS_EN_PROX and locked prox_locking=%d\n",
+ atomic_read(&data->prox_locking));
+
+ isl29028_enable_prox(data->client);
+ pre_prox_cm = -1;
+ /*delay for 20ms to makesure prox enable*/
+// queue_delayed_work(wq, &data->prox_work,20);
+ }else{
+ PR_DEB("Prox thread has running\n");
+ }
+ }else{
+ if(atomic_read(&data->prox_working)){
+ atomic_set(&data->prox_working,0);
+ /*unlock system*/
+ wake_unlock(&data->prox_wake_lock);
+ atomic_set(&data->prox_locking,0);
+ PR_DEB("SYSFS_DIS_PROX and unlocked prox_locking=%d\n",
+ atomic_read(&data->prox_locking));
+
+ cancel_work_sync(&data->prox_work);
+ isl29028_disable_prox(data->client);
+ }else{
+ PR_DEB("Prox thread has not running already\n");
+ }
+ }
+}
+static void sysfs_enable_als(int enable,struct isl29028_data *data)
+{
+ if(enable){
+ if(!atomic_read(&data->als_working)){
+ PR_DEB("Enter SYSFS_EN_ALS\n");
+ atomic_set(&data->als_working,1);
+ isl29028_enable_als(data->client);
+ pre_lux_level = -1;
+ /*delay for 20ms to makesure als enable*/
+ queue_delayed_work(wq, &data->als_work,20);
+ }else{
+ PR_DEB("Als thread has running\n");
+ }
+ }else{
+ if(atomic_read(&data->als_working)){
+ PR_DEB("Enter SYSFS_DIS_ALS\n");
+ atomic_set(&data->als_working,0);
+ cancel_delayed_work(&data->als_work);
+ isl29028_disable_als(data->client);
+ }else{
+ PR_DEB("Als thread has not running already\n");
+ }
+
+ }
+}
+
+/* sysfs interface*/
+static ssize_t light_enable_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int state;
+ struct isl29028_data *data = dev_get_drvdata(dev);
+ mutex_lock(&als_lock);
+ state = atomic_read(&data->als_working);
+ mutex_unlock(&als_lock);
+ PR_DEB("GET_ALS_STATE:state = %d\n",state);
+ return sprintf(buf, "%d\n", state);
+}
+
+static ssize_t proximity_enable_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ int state;
+ struct isl29028_data *data = dev_get_drvdata(dev);
+ mutex_lock(&prox_lock);
+ state = atomic_read(&data->prox_working);
+ mutex_unlock(&prox_lock);
+ PR_DEB("GET_PROX_STATE:state = %d\n",state);
+ return sprintf(buf, "%d\n", state);
+}
+
+static ssize_t light_enable_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+ struct isl29028_data *data = dev_get_drvdata(dev);
+ int new_value;
+ if (sysfs_streq(buf, "1"))
+ new_value = 1;
+ else if (sysfs_streq(buf, "0"))
+ new_value = 0;
+ else {
+ pr_err("%s: invalid value %d\n", __func__, *buf);
+ return -EINVAL;
+ }
+ PR_DEB("SYSFS_EN_ALS %d\n", new_value);
+ mutex_lock(&als_lock);
+ sysfs_enable_als(new_value,data);
+ mutex_unlock(&als_lock);
+ return size;
+}
+
+static ssize_t proximity_enable_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+ struct isl29028_data *data = dev_get_drvdata(dev);
+ int new_value;
+ u8 int_flag;
+ if (sysfs_streq(buf, "1"))
+ new_value = 1;
+ else if (sysfs_streq(buf, "0"))
+ new_value = 0;
+ else {
+ pr_err("%s: invalid value %d\n", __func__, *buf);
+ return -EINVAL;
+ }
+ PR_DEB("SYSFS_EN_PROX %d\n", new_value);
+ mutex_lock(&prox_lock);
+ isl29028_read_reg(data->client,ISL29028_INTCONFIG,&int_flag);
+ sysfs_enable_prox(new_value,data);
+ mutex_unlock(&prox_lock);
+ return size;
+}
+
+static struct device_attribute dev_attr_light_enable =
+ __ATTR(enable, S_IRUGO | S_IWUSR | S_IWGRP,
+ light_enable_show, light_enable_store);
+
+static struct device_attribute dev_attr_proximity_enable =
+ __ATTR(enable, S_IRUGO | S_IWUSR | S_IWGRP,
+ proximity_enable_show, proximity_enable_store);
+
+static struct attribute *light_sysfs_attrs[] = {
+ &dev_attr_light_enable.attr,
+ NULL
+};
+
+static struct attribute_group light_attribute_group = {
+ .attrs = light_sysfs_attrs,
+};
+
+static struct attribute *proximity_sysfs_attrs[] = {
+ &dev_attr_proximity_enable.attr,
+ NULL
+};
+
+static struct attribute_group proximity_attribute_group = {
+ .attrs = proximity_sysfs_attrs,
+};
+/* end of sysfs */
+
+static int isl29028_init_client(struct i2c_client *client)
+{
+ int ret = 0;
+ ret |= isl29028_write_reg(client, ISL29028_CONFIG, CONFIG_VAL);
+ ret |= isl29028_write_reg(client, ISL29028_INTCONFIG, INTERRUPT_VAL);
+ return ret;
+}
+
+static void prox_work_func(struct work_struct *work)
+{
+ int cm = 0;
+ u8 val;
+ struct isl29028_data *data = container_of(work,struct isl29028_data,prox_work);
+
+retry:
+ isl29028_prox_read(data->client, &val);
+ if(val < prox_threshold_lo){ //far
+ cm = 2;
+ data->ps_near = false;
+ isl29028_write_reg(data->client,ISL29028_PROX_LT,0);
+ isl29028_write_reg(data->client,ISL29028_PROX_LT,prox_threshold_hi & 0xff);
+ input_report_abs(data->proximity_input_dev, ABS_DISTANCE, cm);
+ input_sync(data->proximity_input_dev);
+ }else if (val > prox_threshold_hi){ //near
+ cm = 0;
+ data->ps_near = true;
+ isl29028_write_reg(data->client,ISL29028_PROX_HT,0xff);
+ isl29028_write_reg(data->client,ISL29028_PROX_LT,prox_threshold_lo & 0xff);
+ input_report_abs(data->proximity_input_dev, ABS_DISTANCE, cm);
+ input_sync(data->proximity_input_dev);
+ msleep(500);
+ goto retry;
+ }
+ else{
+ isl29028_write_reg(data->client,ISL29028_PROX_HT,0xff);
+ isl29028_write_reg(data->client,ISL29028_PROX_LT,0x00);
+ msleep(500);
+ goto retry;
+ }
+
+ PR_DEB("############prox_data cm = %d\n",cm);
+ pre_prox_cm = cm;
+ isl29028_enable_prox(data->client);
+// queue_work(wq, &data->prox_work);
+}
+
+/* this is ISR*/
+static irqreturn_t isl29028_interrupt(int vec, void *info)
+{
+ struct i2c_client *client=(struct i2c_client *)info;
+ struct isl29028_data *data = i2c_get_clientdata(client);
+ u8 int_flag;
+
+ wake_lock(&data->prox_wake_lock);
+ prox_work_func(&data->prox_work);
+ isl29028_read_reg(client,ISL29028_INTCONFIG,&int_flag);
+ if(int_flag & PROX_FLAG){
+ int_flag &=~(PROX_FLAG);
+ int_flag &=~(ALS_FLAG);
+ isl29028_write_reg(client,ISL29028_INTCONFIG,int_flag);
+ }
+ wake_unlock(&data->prox_wake_lock);
+
+ return IRQ_HANDLED;
+}
+
+static int to_lux(struct i2c_client *client,u16 data)
+{
+ int res = 0;
+ u8 temp;
+
+ isl29028_read_reg(client, ISL29028_CONFIG, &temp);
+ if(temp & ALS_H_RANGE)
+ res = (data * 522)/100; //adjust the gain from 1000 to 100
+ else
+ res = (data * 326)/1000;
+
+ return res;
+}
+static void als_work_func(struct work_struct *work)
+{
+ u16 val,val2,val3;
+ int level=0;
+ struct isl29028_data *data = container_of(work,struct isl29028_data,als_work.work);
+
+ isl29028_als_read(data->client, &val);
+ msleep(500);
+ isl29028_als_read(data->client, &val2);
+ msleep(500);
+ isl29028_als_read(data->client, &val3);
+ val = (val + val2 + val3) / 3;
+ val = to_lux(data->client,val);
+ PR_DEB("@@@@@@@@@@@@@@@@als_data = %d\n",val);
+
+ while (level < ISL_LUX_LEVELS && val > isl_lux_levels[level]){
+ level++;
+ }
+
+ if (level >= ISL_LUX_LEVELS) {
+ level = ISL_LUX_LEVELS -1;
+ }
+
+ PR_DEB("@@@@@@@@@@@@@@@@als_level = %d\n",level);
+ input_report_abs(data->light_input_dev, ABS_MISC, (int)val);
+ input_sync(data->light_input_dev);
+
+ if (level != pre_lux_level) {
+ pre_lux_level =level;
+ }
+ PR_DEB("als-msecs=%d\n",(int)msecs_to_jiffies(data->als_interval));
+ if(atomic_read(&data->als_working))
+ queue_delayed_work(wq, &data->als_work,msecs_to_jiffies(data->als_interval));
+}
+
+/* isl290828 reset*/
+static int isl29028_reset(struct i2c_client *client)
+{
+ int ret=0;
+
+ //step 1
+ ret |= isl29028_write_reg(client, ISl29028_TEST2, 0x29);//0x0F
+ //step 2
+ ret |= isl29028_write_reg(client, ISl29028_TEST1, 0x00);//0x0E
+ ret |= isl29028_write_reg(client, ISl29028_TEST2, 0x00);//0x0F
+ ret |= isl29028_write_reg(client, ISL29028_CONFIG, 0x00);//0x01
+ //step 3 wait ~1ms or more
+ msleep(10);
+ if(ret != 0)
+ PR_DEB("isl29028_reset failure!\n");
+ return ret;
+}
+
+static int __devinit isl29028_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ int err = -ENODEV;
+ struct input_dev *input_dev;
+ struct isl29028_data *data;
+ PR_DEB("isl29028_probe\n");
+
+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
+ return err;
+ }
+
+ data = kzalloc(sizeof(struct isl29028_data), GFP_KERNEL);
+ if (data == NULL) {
+ err = -ENOMEM;
+ goto exit;
+ }
+
+ data->pdata = client->dev.platform_data;
+ data->client = client;
+ data->ps_near = false;
+ i2c_set_clientdata(client, data);
+
+ dev_info(&client->dev, "support ver. %s enabled\n", DRIVER_VERSION);
+
+ /* allocate proximity input_device */
+ input_dev = input_allocate_device();
+ if (input_dev == NULL) {
+ err = -ENOMEM;
+ dev_err(&data->client->dev, "proximity input device allocate failed\n");
+ goto exit0;
+ }
+ input_set_drvdata(input_dev, data);
+ input_dev->name = "proximity";
+ input_set_capability(input_dev, EV_ABS, ABS_DISTANCE);
+ input_set_abs_params(input_dev, ABS_DISTANCE, 0, 1, 0, 0);
+
+ PR_DEB("registering proximity input device\n");
+ err = input_register_device(input_dev);
+ if (err) {
+ pr_err("%s: could not register input device\n", __func__);
+ goto exit1;
+ }
+ data->proximity_input_dev = input_dev;
+ /* create proximity sysfs interface */
+ err = sysfs_create_group(&input_dev->dev.kobj, &proximity_attribute_group);
+ if (err) {
+ pr_err("%s: could not create sysfs group\n", __func__);
+ goto exit2;
+ }
+
+ /* allocate light input_device */
+ input_dev = input_allocate_device();
+ if (input_dev == NULL) {
+ err = -ENOMEM;
+ dev_err(&data->client->dev, "light input device allocate failed\n");
+ goto exit2;
+ }
+ input_set_drvdata(input_dev, data);
+ input_dev->name = "light";
+ input_set_capability(input_dev, EV_ABS, ABS_MISC);
+ input_set_abs_params(input_dev, ABS_MISC, 0, 1, 0, 0);
+
+ PR_DEB("registering light input device\n");
+ err = input_register_device(input_dev);
+ if (err) {
+ pr_err("%s: could not register input device\n", __func__);
+ goto exit3;
+ }
+ data->light_input_dev = input_dev;
+ /* create proximity sysfs interface */
+ err = sysfs_create_group(&input_dev->dev.kobj, &light_attribute_group);
+ if (err) {
+ pr_err("%s: could not create sysfs group\n", __func__);
+ goto exit4;
+ }
+
+ wq = create_workqueue("isl29028_workqueue");
+ if (wq == NULL) {
+ PR_DEB("can't create a workqueue\n");
+ err = -1;
+ goto exit4;
+ }
+ INIT_WORK(&data->prox_work, prox_work_func);
+ INIT_DELAYED_WORK(&data->als_work, als_work_func);
+
+ /*isl29028 reset*/
+ isl29028_reset(client);
+ /*isl29028 init*/
+ err = isl29028_init_client(client);
+ if(err)
+ goto exit5;
+
+ wake_lock_init(&data->prox_wake_lock, WAKE_LOCK_SUSPEND, "prox_wake_lock");
+ /* setup interrupt and wakeup */
+ device_init_wakeup(&client->dev, true);
+ err = request_threaded_irq(data->pdata->int_gpio, NULL, isl29028_interrupt, IRQ_TYPE_EDGE_FALLING, ISL29028_MODULE_NAME, (void *)client);
+ if(err){
+ pr_err("%s Could not allocate irq(%d) !\n", __func__, data->pdata->int_gpio);
+ goto exit_irq;
+ }
+
+ /*init mutex for prox */
+ mutex_init(&prox_lock);
+ /*init mutex for als */
+ mutex_init(&als_lock);
+
+ /*set init state to not-working*/
+ atomic_set(&data->als_working,0);
+ atomic_set(&data->prox_working,0);
+ /*set init state to not-locking*/
+ atomic_set(&data->prox_locking,0);
+
+ /*set default interval*/
+ data->prox_interval = DEFAULT_PROX_INTERVAL;
+ data->als_interval = DEFAULT_ALS_INTERVAL;
+
+ dev_info(&client->dev, "sensor driver probe successful\n");
+ goto exit;
+
+exit_irq:
+ device_init_wakeup(&client->dev, false);
+ wake_lock_destroy(&data->prox_wake_lock);
+exit5:
+ destroy_workqueue(wq);
+exit4:
+ sysfs_remove_group(&data->light_input_dev->dev.kobj, &light_attribute_group);
+exit3:
+ input_unregister_device(data->light_input_dev);
+ input_free_device(data->light_input_dev);
+exit2:
+ sysfs_remove_group(&data->proximity_input_dev->dev.kobj, &proximity_attribute_group);
+exit1:
+ input_unregister_device(data->proximity_input_dev);
+ input_free_device(data->proximity_input_dev);
+exit0:
+ kfree(data);
+
+exit:
+ return err;
+}
+
+static int __devexit isl29028_remove(struct i2c_client *client)
+{
+
+ struct isl29028_data *data = i2c_get_clientdata(client);
+
+ free_irq(data->pdata->int_gpio,(void *)client);
+ device_init_wakeup(&client->dev,false);
+
+ if(atomic_read(&data->prox_working)){
+ isl29028_disable_prox(data->client);
+ cancel_work_sync(&data->prox_work);
+ }
+
+ if(atomic_read(&data->als_working)){
+ isl29028_disable_prox(data->client);
+ cancel_delayed_work_sync(&data->als_work);
+ }
+ flush_workqueue(wq);
+ destroy_workqueue(wq);
+ wq = NULL;
+
+ mutex_destroy(&prox_lock);
+ mutex_destroy(&als_lock);
+
+ input_unregister_device(data->proximity_input_dev);
+ input_unregister_device(data->light_input_dev);
+ input_free_device(data->proximity_input_dev);
+ input_free_device(data->light_input_dev);
+
+ wake_lock_destroy(&data->prox_wake_lock);
+ kfree(data);
+
+ return 0;
+}
+#ifdef CONFIG_PM
+static int isl29028_suspend(struct i2c_client *client, pm_message_t mesg)
+{
+ int ret = 0,prox_s,als_s;
+ u8 status;
+ struct isl29028_data *data = i2c_get_clientdata(client);
+
+ prox_s = atomic_read(&data->prox_working);
+ als_s = atomic_read(&data->als_working);
+ isl29028_read_reg(client,ISL29028_CONFIG,&status);
+
+ if(status & ALS_EN){
+ isl29028_disable_als(data->client);
+ }
+
+ if(status & PROX_EN){
+ enable_irq_wake(data->pdata->int_gpio);
+ }
+
+ PR_DEB("Enter %s:prox_state:%d,als_state:%d\n",
+ __func__,prox_s,als_s);
+
+ if(prox_s){
+ cancel_work_sync(&data->prox_work);
+ isl29028_disable_prox(data->client);
+ }
+ if(als_s){
+ cancel_delayed_work_sync(&data->als_work);
+ isl29028_disable_prox(data->client);
+ }
+ PR_DEB("Exit %s\n",__func__);
+ return ret;
+}
+
+static int isl29028_resume(struct i2c_client *client)
+{
+ int ret = 0,prox_s,als_s;
+ u8 status;
+ struct isl29028_data *data = i2c_get_clientdata(client);
+ prox_s = atomic_read(&data->prox_working);
+ als_s = atomic_read(&data->als_working);
+
+ isl29028_read_reg(client,ISL29028_CONFIG,&status);
+
+ if(status & ALS_EN){
+ isl29028_enable_als(data->client);
+ }
+
+ if(status & PROX_EN){
+ disable_irq_wake(data->pdata->int_gpio);
+ }
+
+ PR_DEB("Enter %s:prox_state:%d,als_state:%d\n",
+ __func__,prox_s,als_s);
+
+ if(prox_s){
+ isl29028_enable_prox(data->client);
+// queue_delayed_work(wq, &data->prox_work,20);
+ }
+ if(als_s){
+ isl29028_enable_als(data->client);
+ queue_delayed_work(wq, &data->als_work,20);
+ }
+ PR_DEB("Exit %s\n",__func__);
+ return ret;
+}
+#else
+#define isl29028_suspend NULL
+#define isl29028_resume NULL
+#endif
+
+static const struct i2c_device_id isl29028_id[] = {
+ { "isl29028", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, isl29028_id);
+
+static struct i2c_driver isl29028_driver = {
+ .driver = {
+ .name = ISL29028_MODULE_NAME,
+ .owner = THIS_MODULE,
+ },
+ .suspend = isl29028_suspend,
+ .resume = isl29028_resume,
+ .probe = isl29028_probe,
+ .remove = __devexit_p(isl29028_remove),
+ .id_table= isl29028_id,
+};
+
+static int __init isl29028_init(void)
+{
+ return i2c_add_driver(&isl29028_driver);
+}
+
+static void __exit isl29028_exit(void)
+{
+ i2c_del_driver(&isl29028_driver);
+}
+
+MODULE_DESCRIPTION("ISL29028 ambient light and proximity sensor driver");
+MODULE_LICENSE("GPLv2");
+MODULE_VERSION(DRIVER_VERSION);
+
+module_init(isl29028_init);
+module_exit(isl29028_exit);
diff --git a/drivers/input/misc/lis3dh.c b/drivers/input/misc/lis3dh.c
new file mode 100644
index 0000000..14e8d53
--- /dev/null
+++ b/drivers/input/misc/lis3dh.c
@@ -0,0 +1,703 @@
+/*
+ * Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/gpio.h>
+#include <linux/miscdevice.h>
+#include <linux/uaccess.h>
+#include <linux/delay.h>
+#include <linux/completion.h>
+#include <linux/poll.h>
+#include <linux/slab.h>
+#include <linux/input.h>
+#include <asm/div64.h>
+
+/* Registers defines */
+#define G_MAX 16000
+
+#define SENSITIVITY_2G 1 /* mg/LSB */
+#define SENSITIVITY_4G 2 /* mg/LSB */
+#define SENSITIVITY_8G 4 /* mg/LSB */
+#define SENSITIVITY_16G 12 /* mg/LSB */
+
+/* Accelerometer Sensor Operating Mode */
+#define LIS3DH_ACC_ENABLE 0x01
+#define LIS3DH_ACC_DISABLE 0x00
+#define HIGH_RESOLUTION 0x08 /* for control reg 4 */
+#define AXISDATA_REG 0x28 /* Begin from OUT_X_L */
+#define WHOAMI_LIS3DH_ACC 0x33 /* Expected content for WAI */
+
+/* CONTROL REGISTERS */
+#define WHO_AM_I 0x0F /* WhoAmI register */
+#define TEMP_CFG_REG 0x1F /* temper sens control reg */
+
+/* ctrl 1: ODR3 ODR2 ODR ODR0 LPen Zenable Yenable Zenable */
+#define CTRL_REG1 0x20 /* control reg 1 */
+#define CTRL_REG2 0x21 /* control reg 2 */
+#define CTRL_REG3 0x22 /* control reg 3 */
+#define CTRL_REG4 0x23 /* control reg 4 */
+#define CTRL_REG5 0x24 /* control reg 5 */
+#define CTRL_REG6 0x25 /* control reg 6 */
+#define STATUS_REG 0x27
+#define OUT_X_L 0x28
+#define OUT_X 0x29
+#define OUT_Y_L 0x2A
+#define OUT_Y 0x2B
+#define OUT_Z_L 0x2C
+#define OUT_Z 0x2D
+#define FIFO_CTRL_REG 0x2E /* FiFo control reg */
+#define FIFO_SRC_REG 0x2F /* FiFo src reg */
+#define INT_CFG1 0x30 /* interrupt 1 config */
+#define INT_SRC1 0x31 /* interrupt 1 source */
+#define INT_THS1 0x32 /* interrupt 1 threshold */
+#define INT_DUR1 0x33 /* interrupt 1 duration */
+#define TT_CFG 0x38 /* tap config */
+#define TT_SRC 0x39 /* tap source */
+#define TT_THS 0x3A /* tap threshold */
+#define TT_LIM 0x3B /* tap time limit */
+#define TT_TLAT 0x3C /* tap time latency */
+#define TT_TW 0x3D /* tap time window */
+/* end CONTROL REGISTRES */
+
+#define ENABLE_HIGH_RESOLUTION 1
+#define LIS3DH_ACC_PM_OFF 0x00
+#define LIS3DH_ACC_ENABLE_ALL_AXES 0x07
+
+#define FIFO_EMPTY 0x20
+#define FSS_MASK 0x1F
+#define PMODE_MASK 0x08
+#define ODR_MASK 0XF0
+
+#define ODR1 0x10 /* 1Hz output data rate */
+#define ODR10 0x20 /* 10Hz output data rate */
+#define ODR25 0x30 /* 25Hz output data rate */
+#define ODR50 0x40 /* 50Hz output data rate */
+#define ODR100 0x50 /* 100Hz output data rate */
+#define ODR200 0x60 /* 200Hz output data rate */
+#define ODR400 0x70 /* 400Hz output data rate */
+#define ODR1250 0x90 /* 1250Hz output data rate */
+
+#define IA 0x40
+#define ZH 0x20
+#define ZL 0x10
+#define YH 0x08
+#define YL 0x04
+#define XH 0x02
+#define XL 0x01
+
+/* CTRL REG BITS*/
+#define CTRL_REG3_I1_AOI1 0x40
+#define CTRL_REG6_I2_TAPEN 0x80
+#define CTRL_REG6_HLACTIVE 0x02
+/* MASK */
+#define NO_MASK 0xFF
+#define INT1_DURATION_MASK 0x7F
+#define INT1_THRESHOLD_MASK 0x7F
+#define TAP_CFG_MASK 0x3F
+#define TAP_THS_MASK 0x7F
+#define TAP_TLIM_MASK 0x7F
+#define TAP_TLAT_MASK NO_MASK
+#define TAP_TW_MASK NO_MASK
+
+/* TAP_SOURCE_REG BIT */
+#define DTAP 0x20
+#define STAP 0x10
+#define SIGNTAP 0x08
+#define ZTAP 0x04
+#define YTAP 0x02
+#define XTAZ 0x01
+#define FUZZ 0
+#define FLAT 0
+#define I2C_RETRY_DELAY 5
+#define I2C_RETRIES 5
+#define I2C_AUTO_INCREMENT 0x80
+
+/* RESUME STATE INDICES */
+#define RES_CTRL_REG1 0
+#define RES_CTRL_REG2 1
+#define RES_CTRL_REG3 2
+#define RES_CTRL_REG4 3
+#define RES_CTRL_REG5 4
+#define RES_CTRL_REG6 5
+#define RES_INT_CFG1 6
+#define RES_INT_THS1 7
+#define RES_INT_DUR1 8
+#define RES_TT_CFG 9
+#define RES_TT_THS 10
+#define RES_TT_LIM 11
+#define RES_TT_TLAT 12
+#define RES_TT_TW 13
+#define RES_TEMP_CFG_REG 14
+#define RES_REFERENCE_REG 15
+#define RES_FIFO_CTRL_REG 16
+#define RESUME_ENTRIES 17
+/* end RESUME STATE INDICES */
+
+#define BYPASS_MODE 0x00
+#define FIFO_MODE 0x40
+#define AC (1 << 7) /* register auto-increment bit */
+#define MAX_ENTRY 1
+#define MAX_DELAY (MAX_ENTRY * 9523809LL)
+#define READ_REPEAT_SHIFT 3
+#define READ_REPEAT (1 << READ_REPEAT_SHIFT)
+
+//#define ACC_DEBUG
+
+#ifdef ACC_DEBUG
+#define acc_debug(fmt,arg...) \
+ printk(fmt,##arg)
+#else
+#define acc_debug(fmt,arg...)
+#endif
+
+/* default register setting for device init */
+static const char default_ctrl_regs[] = {
+ 0x77, /* 400HZ, PM-normal, xyz enable */
+ 0x00, /* normal mode */
+ 0x00, /* No interrupt eanble */
+ 0x88, /* Block data updata, LSB, Full scale 2G, High resolution output */
+ 0x00, /* fifo disable */
+};
+
+static const struct odr_delay {
+ u8 odr; /* odr reg setting */
+ s64 delay_ns; /* odr in ns */
+} odr_delay_table[] = {
+ { ODR400, 2500000LL << READ_REPEAT_SHIFT }, /* 400Hz */
+ { ODR100, 10000000LL << READ_REPEAT_SHIFT }, /* 100Hz */
+ { ODR50, 20000000LL << READ_REPEAT_SHIFT }, /* 50Hz */
+ { ODR10, 100000000LL << READ_REPEAT_SHIFT }, /* 10Hz */
+ { ODR1, 1000000000LL << READ_REPEAT_SHIFT }, /* 1Hz */
+};
+
+/* LIS3DH acceleration data */
+struct lis3dh_t {
+ s16 x;
+ s16 y;
+ s16 z;
+};
+
+struct lis3dh_data {
+ struct i2c_client *client;
+ struct input_dev *input_dev;
+ struct mutex lock;
+ struct workqueue_struct *lis3dh_wq;
+ struct work_struct work;
+ struct hrtimer timer;
+ bool enable;
+ bool drop_next_event;
+ bool interruptible; /* interrupt or polling? */
+ int entries; /* number of fifo entries */
+ u8 ctrl_regs[5]; /* saving register settings */
+ u32 time_to_read; /* time needed to read one entry */
+ ktime_t polling_delay; /* polling time for timer */
+ struct completion data_ready;
+ bool timer_enable; /* prevent workqueue and timer risk*/
+ bool work_enable;
+};
+
+static void set_polling_delay(struct lis3dh_data *lis3dh_data, int res)
+{
+ s64 delay_ns;
+ delay_ns = lis3dh_data->entries + 1 - res;
+ if (delay_ns < 0)
+ delay_ns = 0;
+ delay_ns = delay_ns * lis3dh_data->time_to_read;
+ lis3dh_data->polling_delay = ns_to_ktime(delay_ns);
+}
+
+/* data readout */
+static int lis3dh_read_acc_values(struct i2c_client *client,
+ struct lis3dh_t *data, int total_read)
+{
+ int err;
+ s8 reg = OUT_X_L | AC; /* read from OUT_X_L to OUT_Z by auto-inc */
+ s8 acc_data[6];
+ acc_debug("enter funtion %s\n",__func__);
+ err = i2c_smbus_read_i2c_block_data(client, reg,sizeof(acc_data), acc_data);
+ if (err != sizeof(acc_data)) {
+ pr_err("%s : failed to read 5 bytes for getting x/y/z\n", __func__);
+ return -EIO;
+ }
+
+ data->x = ((acc_data[1] << 8) + acc_data[0]) >> 4;
+ data->y = ((acc_data[3] << 8) + acc_data[1]) >> 4;
+ data->z = ((acc_data[5] << 8) + acc_data[4]) >> 4;
+
+ /*for test*/
+ acc_debug("ACC sensor report rel x0 %d\n",acc_data[0]);
+ acc_debug("ACC sensor report rel x1 %d\n",acc_data[1]);
+ acc_debug("ACC sensor report rel y0 %d\n",acc_data[2]);
+ acc_debug("ACC sensor report rel y1 %d\n",acc_data[3]);
+ acc_debug("ACC sensor report rel z0 %d\n",acc_data[4]);
+ acc_debug("ACC sensor report rel z1 %d\n",acc_data[5]);
+ acc_debug("ACC sensor data x = %d8 , y = %8d , z = %8d \n", data->x, data->y, data->z);
+
+ return 0;
+}
+
+static int lis3dh_report_acc_values(struct lis3dh_data *lis3dh_data)
+{
+ int res;
+ struct lis3dh_t data;
+
+ res = lis3dh_read_acc_values(lis3dh_data->client, &data,6);
+ if (res < 0)
+ return res;
+
+ input_report_rel(lis3dh_data->input_dev, REL_RX, -data.y);
+ input_report_rel(lis3dh_data->input_dev, REL_RY, -data.x);
+ input_report_rel(lis3dh_data->input_dev, REL_RZ, -data.z);
+ input_sync(lis3dh_data->input_dev);
+ return res;
+}
+
+static enum hrtimer_restart lis3dh_timer_func(struct hrtimer *timer)
+{
+ struct lis3dh_data *lis3dh_data = container_of(timer, struct lis3dh_data, timer);
+ if(likely(lis3dh_data->timer_enable))
+ queue_work(lis3dh_data->lis3dh_wq, &lis3dh_data->work);
+ return HRTIMER_NORESTART;
+}
+
+static void lis3dh_work_func(struct work_struct *work)
+{
+ int res;
+ struct lis3dh_data *lis3dh_data = container_of(work, struct lis3dh_data, work);
+
+ acc_debug("enter funtion %s\n",__func__);
+ /* read the status register */
+ res = i2c_smbus_read_byte_data(lis3dh_data->client, STATUS_REG);
+ acc_debug("ACC sensor src status(0x27) is %d\n",res);
+ if(res & 0x80) {
+ res = lis3dh_report_acc_values(lis3dh_data);
+ if (res < 0)
+ return;
+ }
+ if(likely(lis3dh_data->work_enable))
+ hrtimer_start(&lis3dh_data->timer, lis3dh_data->polling_delay, HRTIMER_MODE_REL);
+}
+
+static irqreturn_t lis3dh_interrupt_thread(int irq, void *lis3dh_data_p)
+{
+ int res;
+ struct lis3dh_data *lis3dh_data = lis3dh_data_p;
+ acc_debug("enter funtion %s\n",__func__);
+ res = lis3dh_report_acc_values(lis3dh_data);
+ if (res < 0)
+ pr_err("%s: failed to report acc values\n", __func__);
+ return IRQ_HANDLED;
+}
+
+static ssize_t lis3dh_show_enable(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct lis3dh_data *lis3dh_data = dev_get_drvdata(dev);
+ return sprintf(buf, "%d\n", lis3dh_data->enable);
+}
+
+static ssize_t lis3dh_set_enable(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t size)
+{
+ int err = 0;
+ struct lis3dh_data *lis3dh_data = dev_get_drvdata(dev);
+ bool new_enable;
+ acc_debug("enter funtion %s\n",__func__);
+
+ if (sysfs_streq(buf, "1"))
+ new_enable = true;
+ else if (sysfs_streq(buf, "0"))
+ new_enable = false;
+ else {
+ pr_debug("%s: invalid value %d\n", __func__, *buf);
+ return -EINVAL;
+ }
+
+ if (new_enable == lis3dh_data->enable)
+ return size;
+
+ mutex_lock(&lis3dh_data->lock);
+ if (new_enable) {
+ /* turning on */
+ err = i2c_smbus_write_i2c_block_data(lis3dh_data->client,
+ CTRL_REG1 | AC, sizeof(lis3dh_data->ctrl_regs),
+ lis3dh_data->ctrl_regs);
+ if (err < 0) {
+ err = -EIO;
+ goto unlock;
+ }
+
+ lis3dh_data->timer_enable = 1;
+ lis3dh_data->work_enable = 1;
+
+ if (lis3dh_data->interruptible)
+ enable_irq(lis3dh_data->client->irq);
+ else {
+ set_polling_delay(lis3dh_data, 0);
+ hrtimer_start(&lis3dh_data->timer, lis3dh_data->polling_delay, HRTIMER_MODE_REL);
+ }
+ } else {
+ lis3dh_data->timer_enable = 0;
+ lis3dh_data->work_enable = 0;
+
+ if (lis3dh_data->interruptible)
+ disable_irq(lis3dh_data->client->irq);
+ else {
+ hrtimer_cancel(&lis3dh_data->timer);
+ cancel_work_sync(&lis3dh_data->work);
+ }
+ /* turning off */
+ err = i2c_smbus_write_byte_data(lis3dh_data->client,
+ CTRL_REG1, LIS3DH_ACC_DISABLE);
+ if (err < 0)
+ goto unlock;
+ }
+ lis3dh_data->enable = new_enable;
+
+unlock:
+ mutex_unlock(&lis3dh_data->lock);
+
+ return err ? err : size;
+}
+
+static ssize_t lis3dh_show_delay(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct lis3dh_data *lis3dh_data = dev_get_drvdata(dev);
+ u64 delay;
+
+ delay = lis3dh_data->time_to_read * lis3dh_data->entries;
+ delay = ktime_to_ns(ns_to_ktime(delay));
+
+ return sprintf(buf, "%lld\n", delay);
+}
+
+static ssize_t lis3dh_set_delay(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t size)
+{
+ struct lis3dh_data *lis3dh_data = dev_get_drvdata(dev);
+ int odr_value = ODR100;
+ int res = 0;
+ int i;
+ u64 delay_ns;
+ u8 ctrl;
+
+ res = strict_strtoll(buf, 10, &delay_ns);
+ if (res < 0)
+ return res;
+
+ mutex_lock(&lis3dh_data->lock);
+ if (!lis3dh_data->interruptible)
+ hrtimer_cancel(&lis3dh_data->timer);
+ else
+ disable_irq(lis3dh_data->client->irq);
+
+ /* round to the nearest supported ODR that is equal or above than
+ * the requested value
+ */
+ for (i = 0; i < ARRAY_SIZE(odr_delay_table); i++) {
+ if (delay_ns < odr_delay_table[i].delay_ns)
+ break;
+ }
+ if (i > 0)
+ i--;
+
+ odr_value = odr_delay_table[i].odr;
+ delay_ns = odr_delay_table[i].delay_ns;
+ lis3dh_data->time_to_read = delay_ns;
+ lis3dh_data->entries = 1;
+
+ if (delay_ns >= odr_delay_table[3].delay_ns) {
+ if (delay_ns >= MAX_DELAY) {
+ lis3dh_data->entries = MAX_ENTRY;
+ delay_ns = MAX_DELAY;
+ } else {
+ do_div(delay_ns, odr_delay_table[3].delay_ns);
+ lis3dh_data->entries = delay_ns;
+ }
+ lis3dh_data->time_to_read = odr_delay_table[3].delay_ns;
+ }
+
+ if (odr_value != (lis3dh_data->ctrl_regs[0] & ODR_MASK)) {
+ ctrl = (lis3dh_data->ctrl_regs[0] & ~ODR_MASK);
+ ctrl |= odr_value;
+ lis3dh_data->ctrl_regs[0] = ctrl;
+ res = i2c_smbus_write_byte_data(lis3dh_data->client, CTRL_REG1, ctrl);
+ }
+ /* we see a noise in the first sample or two after we
+ * change rates. this delay helps eliminate that noise.
+ */
+ //msleep((u32)delay_ns * 2 / NSEC_PER_MSEC);
+
+ if (!lis3dh_data->interruptible) {
+ delay_ns = lis3dh_data->entries * lis3dh_data->time_to_read;
+ lis3dh_data->polling_delay = ns_to_ktime(delay_ns);
+ if (lis3dh_data->enable)
+ hrtimer_start(&lis3dh_data->timer,
+ lis3dh_data->polling_delay, HRTIMER_MODE_REL);
+ } else
+ enable_irq(lis3dh_data->client->irq);
+
+ mutex_unlock(&lis3dh_data->lock);
+ return size;
+}
+
+static DEVICE_ATTR(enable, S_IRUGO | S_IWUSR | S_IWGRP,
+ lis3dh_show_enable, lis3dh_set_enable);
+static DEVICE_ATTR(poll_delay, S_IRUGO | S_IWUSR | S_IWGRP,
+ lis3dh_show_delay, lis3dh_set_delay);
+
+static int lis3dh_probe(struct i2c_client *client,
+ const struct i2c_device_id *devid)
+{
+ int ret;
+ int err = 0;
+ struct lis3dh_data *data;
+ struct input_dev *input_dev;
+
+ data = kzalloc(sizeof(*data), GFP_KERNEL);
+ if (data == NULL) {
+ dev_err(&client->dev, "failed to allocate memory for module data\n");
+ err = -ENOMEM;
+ goto exit;
+ }
+
+ data->client = client;
+
+ /* read chip id */
+ ret = i2c_smbus_read_byte_data(client, WHO_AM_I);
+ if (ret != WHOAMI_LIS3DH_ACC) {
+ if (ret < 0) {
+ pr_err("%s: i2c for reading chip id failed\n", __func__);
+ err = ret;
+ } else {
+ pr_err("%s : Device identification failed\n", __func__);
+ err = -ENODEV;
+ }
+ goto err_read_reg;
+ }
+
+ mutex_init(&data->lock);
+
+ /* allocate acc input_device */
+ input_dev = input_allocate_device();
+ if (!input_dev) {
+ pr_err("%s: could not allocate input device\n", __func__);
+ err = -ENOMEM;
+ goto err_input_allocate_device;
+ }
+
+ data->input_dev = input_dev;
+ input_set_drvdata(input_dev, data);
+ input_dev->name = "acc";
+ /* X */
+ input_set_capability(input_dev, EV_REL, REL_RX);
+ input_set_abs_params(input_dev, REL_RX, -32768, 32767, 0, 0);
+ /* Y */
+ input_set_capability(input_dev, EV_REL, REL_RY);
+ input_set_abs_params(input_dev, REL_RY, -32768, 32767, 0, 0);
+ /* Z */
+ input_set_capability(input_dev, EV_REL, REL_RZ);
+ input_set_abs_params(input_dev, REL_RZ, -32768, 32767, 0, 0);
+
+ err = input_register_device(input_dev);
+ if (err < 0) {
+ pr_err("%s: could not register input device\n", __func__);
+ input_free_device(data->input_dev);
+ goto err_input_register_device;
+ }
+
+ memcpy(&data->ctrl_regs, &default_ctrl_regs, sizeof(default_ctrl_regs));
+
+ if (data->client->irq >= 0) { /* interrupt */
+ data->interruptible = true;
+ err = request_threaded_irq(data->client->irq, NULL,
+ lis3dh_interrupt_thread, IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
+ "lis3dh", data);
+ if (err < 0) {
+ pr_err("%s: can't allocate irq.\n", __func__);
+ goto err_request_irq;
+ }
+ disable_irq(data->client->irq);
+ } else { /* polling */
+ u64 delay_ns;
+ data->ctrl_regs[2] = 0x00; /* disable interrupt */
+ /* hrtimer settings. we poll for acc values using a timer. */
+ acc_debug("enter polling mode %s\n",__func__);
+ hrtimer_init(&data->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
+ data->polling_delay = ns_to_ktime(200 * NSEC_PER_MSEC); //this data need to carefully modified
+ data->time_to_read = 10000000LL;
+ delay_ns = ktime_to_ns(data->polling_delay);
+ do_div(delay_ns, data->time_to_read);
+ data->entries = delay_ns;
+ data->timer.function = lis3dh_timer_func;
+
+ /* the timer just fires off a work queue request.
+ We need a thread to read i2c (can be slow and blocking). */
+ data->lis3dh_wq = create_singlethread_workqueue("lis3dh_wq");
+ if (!data->lis3dh_wq) {
+ err = -ENOMEM;
+ pr_err("%s: could not create workqueue\n", __func__);
+ goto err_create_workqueue;
+ }
+ /* this is the thread function we run on the work queue */
+ INIT_WORK(&data->work, lis3dh_work_func);
+ }
+
+ if (device_create_file(&input_dev->dev, &dev_attr_enable) < 0) {
+ pr_err("Failed to create device file(%s)!\n", dev_attr_enable.attr.name);
+ goto err_device_create_file;
+ }
+
+ if (device_create_file(&input_dev->dev, &dev_attr_poll_delay) < 0) {
+ pr_err("Failed to create device file(%s)!\n",
+ dev_attr_poll_delay.attr.name);
+ goto err_device_create_file2;
+ }
+
+ i2c_set_clientdata(client, data);
+ dev_set_drvdata(&input_dev->dev, data);
+
+ return 0;
+
+err_device_create_file2:
+ device_remove_file(&input_dev->dev, &dev_attr_enable);
+err_device_create_file:
+ if (data->interruptible) {
+ enable_irq(data->client->irq);
+ free_irq(data->client->irq, data);
+ } else
+ destroy_workqueue(data->lis3dh_wq);
+ input_unregister_device(data->input_dev);
+err_create_workqueue:
+err_request_irq:
+err_input_register_device:
+err_input_allocate_device:
+ mutex_destroy(&data->lock);
+err_read_reg:
+ kfree(data);
+exit:
+ return err;
+}
+
+static int lis3dh_remove(struct i2c_client *client)
+{
+ int err = 0;
+ struct lis3dh_data *lis3dh_data = i2c_get_clientdata(client);
+
+ device_remove_file(&lis3dh_data->input_dev->dev, &dev_attr_enable);
+ device_remove_file(&lis3dh_data->input_dev->dev, &dev_attr_poll_delay);
+
+ if (lis3dh_data->enable)
+ err = i2c_smbus_write_byte_data(lis3dh_data->client,
+ CTRL_REG1, LIS3DH_ACC_DISABLE);
+ if (lis3dh_data->interruptible) {
+ if (!lis3dh_data->enable) /* no disable_irq before free_irq */
+ enable_irq(lis3dh_data->client->irq);
+ free_irq(lis3dh_data->client->irq, lis3dh_data);
+ } else {
+ hrtimer_cancel(&lis3dh_data->timer);
+ cancel_work_sync(&lis3dh_data->work);
+ destroy_workqueue(lis3dh_data->lis3dh_wq);
+ }
+
+ input_unregister_device(lis3dh_data->input_dev);
+ mutex_destroy(&lis3dh_data->lock);
+ kfree(lis3dh_data);
+
+ return err;
+}
+
+static int lis3dh_suspend(struct device *dev)
+{
+ int err = 0;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct lis3dh_data *lis3dh_data = i2c_get_clientdata(client);
+
+ if (lis3dh_data->enable) {
+ mutex_lock(&lis3dh_data->lock);
+ if (!lis3dh_data->interruptible) {
+ hrtimer_cancel(&lis3dh_data->timer);
+ cancel_work_sync(&lis3dh_data->work);
+ }
+ err = i2c_smbus_write_byte_data(lis3dh_data->client,
+ CTRL_REG1, LIS3DH_ACC_DISABLE);
+ mutex_unlock(&lis3dh_data->lock);
+ }
+
+ return err;
+}
+
+static int lis3dh_resume(struct device *dev)
+{
+ int err = 0;
+ struct i2c_client *client = to_i2c_client(dev);
+ struct lis3dh_data *lis3dh_data = i2c_get_clientdata(client);
+
+ if (lis3dh_data->enable) {
+ mutex_lock(&lis3dh_data->lock);
+ if (!lis3dh_data->interruptible)
+ hrtimer_start(&lis3dh_data->timer,
+ lis3dh_data->polling_delay, HRTIMER_MODE_REL);
+ err = i2c_smbus_write_i2c_block_data(client,
+ CTRL_REG1 | AC, sizeof(lis3dh_data->ctrl_regs),
+ lis3dh_data->ctrl_regs);
+ mutex_unlock(&lis3dh_data->lock);
+ }
+
+ return err;
+}
+
+static const struct dev_pm_ops lis3dh_pm_ops = {
+ .suspend = lis3dh_suspend,
+ .resume = lis3dh_resume
+};
+
+static const struct i2c_device_id lis3dh_id[] = {
+ { "lis3dh", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, lis3dh_id);
+
+static struct i2c_driver lis3dh_driver = {
+ .probe = lis3dh_probe,
+ .remove = __devexit_p(lis3dh_remove),
+ .id_table = lis3dh_id,
+ .driver = {
+ .pm = &lis3dh_pm_ops,
+ .owner = THIS_MODULE,
+ .name = "lis3dh"
+ },
+};
+
+static int __init lis3dh_init(void)
+{
+ return i2c_add_driver(&lis3dh_driver);
+}
+
+static void __exit lis3dh_exit(void)
+{
+ i2c_del_driver(&lis3dh_driver);
+}
+
+module_init(lis3dh_init);
+module_exit(lis3dh_exit);
+
+MODULE_DESCRIPTION("lis3dh digital accelerometer sensor driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/input/misc/ltr502.c b/drivers/input/misc/ltr502.c
new file mode 100644
index 0000000..6f392df
--- /dev/null
+++ b/drivers/input/misc/ltr502.c
@@ -0,0 +1,981 @@
+/* linux/driver/input/misc/ltr502.c
+ * Copyright (C) 2010 Samsung Electronics. All rights reserved.
+ * Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/i2c.h>
+#include <linux/fs.h>
+#include <linux/errno.h>
+#include <linux/device.h>
+#include <linux/delay.h>
+#include <linux/miscdevice.h>
+#include <linux/platform_device.h>
+#include <linux/leds.h>
+#include <linux/gpio.h>
+#include <linux/wakelock.h>
+#include <linux/slab.h>
+#include <linux/input.h>
+#include <linux/workqueue.h>
+#include <linux/uaccess.h>
+#include <linux/input/ltr502.h>
+#include <linux/earlysuspend.h>
+#include <linux/regulator/consumer.h>
+
+
+/* Note about power vs enable/disable:
+ * The chip has two functions, proximity and ambient light sensing.
+ * There is no separate power enablement to the two functions (unlike
+ * the Capella CM3602/3623).
+ * This module implements two drivers: /dev/proximity and /dev/light.
+ * When either driver is enabled (via sysfs attributes), we give power
+ * to the chip. When both are disabled, we remove power from the chip.
+ * In suspend, we remove power if light is disabled but not if proximity is
+ * enabled (proximity is allowed to wakeup from suspend).
+ *
+ * There are no ioctls for either driver interfaces. Output is via
+ * input device framework and control via sysfs attributes.
+ */
+#undef DEBUG_LTR502
+#ifdef DEBUG_LTR502
+#define ltr502_dbgmsg(str, args...) printk("%s: " str, __func__, ##args)
+#else
+#define ltr502_dbgmsg(str, args...)
+#endif
+
+#define SENSOR_NAME "ltr502"
+
+/* register addr */
+#define REGS_CONFIG 0x0 /* Read Only */
+#define REGS_TIMING 0x1 /* Write Only */
+#define REGS_DLS_CTL 0x2 /* Write Only */
+#define REGS_INT_STATUS 0x3 /* Write Only */
+#define REGS_DPS_CTL 0x4 /* Write Only */
+#define REGS_DATA 0x5 /* Write Only */
+#define REGS_WINDOW 0x8 /* Write Only */
+
+/* sensor type */
+#define LIGHT 0
+#define PROXIMITY 1
+#define ALL 2
+
+/* sensor operation mode */
+#define OPERATION_MASK 0x03 /*operation mask */
+#define DLS_ACTIVE 0x00 /*DLS active operation mode */
+#define DPS_ACTIVE 0x01 /*DPS active operation mode */
+#define ALL_ACTIVE 0x02 /*DLS and DPS active operation mode */
+#define ALL_IDLE 0x03 /*Idle operation mode */
+
+#define POWER_MASK (0x03<<2) /*mode mask */
+#define POWER_UP (0x00<<2) /*Idle mode */
+#define POWER_DOWN (0x02<<2) /*Idle mode */
+
+/* sensor operation mode */
+#define DPS_INT 0x02 /*DPS INT */
+#define DLS_INT 0x01 /*DLS INT */
+
+static struct regulator *reg_ext_2v8;
+
+static int lux_table[64] = {
+ 1, 1, 1, 2, 2, 2, 3, 4, 4, 5,
+ 6, 7, 9, 11, 13, 16, 19, 22, 27, 32,
+ 39, 46, 56, 67, 80, 96, 116, 139, 167, 200,
+ 240, 289, 346, 416, 499, 599, 720, 864, 1037, 1245,
+ 1495, 1795, 2154, 2586, 3105, 3728, 4475, 5372, 6449, 7743,
+ 9295, 11159, 13396, 16082, 19307, 23178, 27826, 33405, 40103, 48144,
+ 57797, 69386, 83298, 100000,
+};
+
+struct ltr502_data;
+
+enum {
+ LIGHT_ENABLED = BIT(0),
+ PROXIMITY_ENABLED = BIT(1),
+};
+
+/* driver data */
+struct ltr502_data {
+ bool on;
+ u8 power_state;
+ struct ltr502_platform_data *pdata;
+ struct i2c_client *i2c_client;
+ struct mutex lock;
+ struct workqueue_struct *wq;
+ struct early_suspend early_suspend;
+
+ struct input_dev *light_input_dev;
+ struct work_struct work_light;
+ struct hrtimer light_timer;
+ ktime_t light_poll_delay;
+
+ struct input_dev *proximity_input_dev;
+ struct work_struct work_proximity;
+ struct hrtimer proximity_timer;
+ ktime_t proximity_poll_delay;
+ struct wake_lock prx_wake_lock;
+};
+
+static void ltr502_early_suspend(struct early_suspend *h);
+static void ltr502_late_resume(struct early_suspend *h);
+
+int ltr502_i2c_write(struct ltr502_data *ltr502, u8 reg, u8 * val)
+{
+ int err = 0;
+ struct i2c_msg msg[1];
+ unsigned char data[2];
+ int retry = 10;
+ struct i2c_client *client = ltr502->i2c_client;
+
+ if ((client == NULL) || (!client->adapter))
+ return -ENODEV;
+
+ while (retry--) {
+ data[0] = reg;
+ data[1] = *val;
+
+ msg->addr = client->addr;
+ msg->flags = 0; /* write */
+ msg->len = 2;
+ msg->buf = data;
+
+ err = i2c_transfer(client->adapter, msg, 1);
+
+ if (err >= 0)
+ return 0;
+
+ usleep(10000);
+ }
+ return err;
+}
+
+int ltr502_i2c_read(struct ltr502_data *ltr502, u8 reg, u8 * data)
+{
+ int err = 0;
+ struct i2c_msg msg[2];
+ int retry = 10;
+ struct i2c_client *client = ltr502->i2c_client;
+
+ if ((client == NULL) || (!client->adapter))
+ return -ENODEV;
+
+ while (retry--) {
+ msg[0].addr = client->addr;
+ msg[0].flags = 0; /* write */
+ msg[0].len = 1;
+ msg[0].buf = &reg;
+
+ msg[1].addr = client->addr;
+ msg[1].flags = I2C_M_RD; /* read */
+ msg[1].len = 1;
+ msg[1].buf = data;
+
+ err = i2c_transfer(client->adapter, msg, 2);
+
+ if (err >= 0)
+ return 0;
+
+ usleep(10000);
+ }
+ return err;
+}
+
+static int ltr502_light_enable(struct ltr502_data *ltr502)
+{
+ u8 mode;
+ int ret = 0;
+
+ ltr502_dbgmsg("starting poll timer, delay %lldns\n",
+ ktime_to_ns(ltr502->light_poll_delay));
+
+ if (!ltr502_i2c_read(ltr502, REGS_CONFIG, &mode)) {
+ if( mode & POWER_UP ){
+ ltr502_dbgmsg("LTR502 chip has been power up ");
+ } else {
+ mode &= ~(POWER_MASK);
+ mode |= (POWER_UP);
+ if (ltr502_i2c_write(ltr502, REGS_CONFIG, &mode)) {
+ pr_err("fail to write REGS_CONFIG\n");
+ }
+ }
+ if ((mode & OPERATION_MASK) == DPS_ACTIVE) {
+ mode &= ~(OPERATION_MASK);
+ mode |= (ALL_ACTIVE);
+ ret = ltr502_i2c_write(ltr502, REGS_CONFIG, &mode);
+ if (ret) {
+ pr_err("fail to write REGS_CONFIG\n");
+ return ret;
+ }
+ } else if ((mode & OPERATION_MASK) == ALL_IDLE) {
+ mode &= ~(OPERATION_MASK);
+ mode |= (DLS_ACTIVE);
+ ret = ltr502_i2c_write(ltr502, REGS_CONFIG, &mode);
+ if (ret) {
+ pr_err("fail to write REGS_CONFIG\n");
+ return ret;
+ }
+ } else {
+ pr_err("light sensor has been enable\n");
+ return -1;
+ }
+ } else {
+ pr_err("fail to read REGS_CONFIG\n");
+ return -1;
+ }
+
+ return ret;
+}
+
+static int ltr502_light_disable(struct ltr502_data *ltr502)
+{
+ u8 mode;
+ int ret = 0;
+ /* cancel p-sensor work queue to prevent error read */
+ if (ltr502->power_state & PROXIMITY_ENABLED) {
+ hrtimer_cancel(&ltr502->proximity_timer);
+ cancel_work_sync(&ltr502->work_proximity);
+ }
+ if (!ltr502_i2c_read(ltr502, REGS_CONFIG, &mode)) {
+ if ((mode & OPERATION_MASK) == DLS_ACTIVE) {
+ mode &= ~(OPERATION_MASK);
+ mode |= (ALL_IDLE);
+ ret = ltr502_i2c_write(ltr502, REGS_CONFIG, &mode);
+ if (ret) {
+ pr_err("fail to write REGS_CONFIG\n");
+ return ret;
+ }
+ } else if ((mode & OPERATION_MASK) == ALL_ACTIVE) {
+ mode &= ~(OPERATION_MASK);
+ mode |= (DPS_ACTIVE);
+ ret = ltr502_i2c_write(ltr502, REGS_CONFIG, &mode);
+ if (ret) {
+ pr_err("fail to write REGS_CONFIG\n");
+ return ret;
+ }
+ } else {
+ pr_err("light sensor has been disable\n");
+ return -1;
+ }
+ } else {
+ pr_err("fail to read REGS_CONFIG\n");
+ return -1;
+ }
+ /* reload p-sensor workqueue and delay 200ms before reading the register */
+ if (ltr502->power_state & PROXIMITY_ENABLED) {
+ usleep(200000);
+ hrtimer_start(&ltr502->proximity_timer,
+ ltr502->proximity_poll_delay, HRTIMER_MODE_REL);
+ }
+ return ret;
+}
+
+static ssize_t light_poll_delay_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct ltr502_data *ltr502 = dev_get_drvdata(dev);
+ return sprintf(buf, "%lld\n", ktime_to_ns(ltr502->light_poll_delay));
+}
+
+static ssize_t light_poll_delay_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+ struct ltr502_data *ltr502 = dev_get_drvdata(dev);
+ int64_t new_delay;
+ int err;
+
+ err = strict_strtoll(buf, 10, &new_delay);
+ if (err < 0)
+ return err;
+
+ ltr502_dbgmsg("new delay = %lldns, old delay = %lldns\n",
+ new_delay, ktime_to_ns(ltr502->light_poll_delay));
+ mutex_lock(&ltr502->lock);
+ if (new_delay != ktime_to_ns(ltr502->light_poll_delay)) {
+ ltr502->light_poll_delay = ns_to_ktime(new_delay);
+ if (ltr502->power_state & LIGHT_ENABLED) {
+ hrtimer_cancel(&ltr502->light_timer);
+ cancel_work_sync(&ltr502->work_light);
+ hrtimer_start(&ltr502->light_timer,
+ ltr502->light_poll_delay,
+ HRTIMER_MODE_REL);
+ }
+ }
+ mutex_unlock(&ltr502->lock);
+
+ return size;
+}
+
+static ssize_t light_enable_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct ltr502_data *ltr502 = dev_get_drvdata(dev);
+ return sprintf(buf, "%d\n",
+ (ltr502->power_state & LIGHT_ENABLED) ? 1 : 0);
+}
+
+static ssize_t light_enable_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+ struct ltr502_data *ltr502 = dev_get_drvdata(dev);
+ bool new_value;
+ int ret = -EINVAL;
+
+ if (sysfs_streq(buf, "1"))
+ new_value = true;
+ else if (sysfs_streq(buf, "0"))
+ new_value = false;
+ else {
+ pr_err("%s: invalid value %d\n", __func__, *buf);
+ return ret;
+ }
+
+ mutex_lock(&ltr502->lock);
+ ltr502_dbgmsg("new_value = %d, old state = %d\n",
+ new_value, (ltr502->power_state & LIGHT_ENABLED) ? 1 : 0);
+ if (new_value && !(ltr502->power_state & LIGHT_ENABLED)) {
+ if (!ltr502_light_enable(ltr502)) {
+ ret = size;
+ ltr502->power_state |= LIGHT_ENABLED;
+ hrtimer_start(&ltr502->light_timer,
+ ltr502->light_poll_delay,
+ HRTIMER_MODE_REL);
+ }
+ } else if (!new_value && (ltr502->power_state & LIGHT_ENABLED)) {
+ if (!ltr502_light_disable(ltr502)) {
+ ret = size;
+ ltr502->power_state &= ~LIGHT_ENABLED;
+ hrtimer_cancel(&ltr502->light_timer);
+ cancel_work_sync(&ltr502->work_light);
+ }
+ }
+ mutex_unlock(&ltr502->lock);
+
+ return ret;
+}
+
+static int ltr502_proximity_enable(struct ltr502_data *ltr502)
+{
+ u8 mode;
+ int ret = 0;
+
+ if (!ltr502_i2c_read(ltr502, REGS_CONFIG, &mode)) {
+ if( mode & POWER_UP ){
+ ltr502_dbgmsg("LTR502 chip has been power up ");
+ } else {
+ mode &= ~(POWER_MASK);
+ mode |= (POWER_UP);
+ if (ltr502_i2c_write(ltr502, REGS_CONFIG, &mode)) {
+ pr_err("fail to write REGS_CONFIG\n");
+ }
+ }
+ if ((mode & OPERATION_MASK) == DLS_ACTIVE) {
+ mode &= ~(OPERATION_MASK);
+ mode |= (ALL_ACTIVE);
+ ret = ltr502_i2c_write(ltr502, REGS_CONFIG, &mode);
+ regulator_enable(reg_ext_2v8); //vote to turn on LDO 2.8V
+ if (ret) {
+ pr_err("fail to write REGS_CONFIG\n");
+
+ }
+ } else if ((mode & OPERATION_MASK) == ALL_IDLE) {
+ mode &= ~(OPERATION_MASK);
+ mode |= (DPS_ACTIVE);
+ ret = ltr502_i2c_write(ltr502, REGS_CONFIG, &mode);
+ regulator_enable(reg_ext_2v8); //vote to turn on LDO 2.8V
+ if (ret) {
+ pr_err("fail to write REGS_CONFIG\n");
+ return ret;
+ }
+ } else {
+ pr_err("proximity has been enable!\n");
+ return -1;
+ }
+ } else {
+ pr_err("fail to write REGS_CONFIG\n");
+ return -1;
+ }
+
+ return ret;
+}
+
+static int ltr502_proximity_disable(struct ltr502_data *ltr502)
+{
+ u8 mode;
+ int ret = 0;
+ if (!ltr502_i2c_read(ltr502, REGS_CONFIG, &mode)) {
+ if ((mode & OPERATION_MASK) == DPS_ACTIVE) {
+ mode &= ~(OPERATION_MASK);
+ mode |= (ALL_IDLE);
+ ret = ltr502_i2c_write(ltr502, REGS_CONFIG, &mode);
+ regulator_disable(reg_ext_2v8); //vote to turn off LDO 2.8V
+ if (ret) {
+ pr_err("fail to write REGS_CONFIG\n");
+ return ret;
+ }
+ } else if ((mode & OPERATION_MASK) == ALL_ACTIVE) {
+ mode &= ~(OPERATION_MASK);
+ mode |= DLS_ACTIVE;
+ ret = ltr502_i2c_write(ltr502, REGS_CONFIG, &mode);
+ regulator_disable(reg_ext_2v8); //vote to turn off LDO 2.8V
+ if (ret) {
+ pr_err("fail to write REGS_CONFIG\n");
+ return ret;
+ }
+ } else {
+ pr_err("proximity has been disable!\n");
+ return -1;
+ }
+ } else {
+ pr_err("fail to read REGS_CONFIG\n");
+ return -1;
+ }
+
+ return ret;
+}
+
+static ssize_t proximity_poll_delay_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct ltr502_data *ltr502 = dev_get_drvdata(dev);
+ return sprintf(buf, "%lld\n",
+ ktime_to_ns(ltr502->proximity_poll_delay));
+}
+
+static ssize_t proximity_poll_delay_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+ struct ltr502_data *ltr502 = dev_get_drvdata(dev);
+ int64_t new_delay;
+ int err;
+
+ err = strict_strtoll(buf, 10, &new_delay);
+ if (err < 0)
+ return err;
+
+ ltr502_dbgmsg("new delay = %lldns, old delay = %lldns\n",
+ new_delay, ktime_to_ns(ltr502->proximity_poll_delay));
+ mutex_lock(&ltr502->lock);
+ if (new_delay != ktime_to_ns(ltr502->proximity_poll_delay)) {
+ ltr502->proximity_poll_delay = ns_to_ktime(new_delay);
+ if (ltr502->power_state & PROXIMITY_ENABLED) {
+ hrtimer_cancel(&ltr502->proximity_timer);
+ cancel_work_sync(&ltr502->work_proximity);
+ hrtimer_start(&ltr502->proximity_timer,
+ ltr502->proximity_poll_delay,
+ HRTIMER_MODE_REL);
+ }
+ }
+ mutex_unlock(&ltr502->lock);
+
+ return size;
+}
+
+static ssize_t proximity_enable_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct ltr502_data *ltr502 = dev_get_drvdata(dev);
+ return sprintf(buf, "%d\n",
+ (ltr502->power_state & PROXIMITY_ENABLED) ? 1 : 0);
+}
+
+static ssize_t proximity_enable_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+ struct ltr502_data *ltr502 = dev_get_drvdata(dev);
+ bool new_value;
+ int ret = -EINVAL;
+
+ if (sysfs_streq(buf, "1"))
+ new_value = true;
+ else if (sysfs_streq(buf, "0"))
+ new_value = false;
+ else {
+ pr_err("%s: invalid value %d\n", __func__, *buf);
+ return ret;
+ }
+
+ mutex_lock(&ltr502->lock);
+ ltr502_dbgmsg("new_value = %d, old state = %d\n",
+ new_value,
+ (ltr502->power_state & PROXIMITY_ENABLED) ? 1 : 0);
+ if (new_value && !(ltr502->power_state & PROXIMITY_ENABLED)) {
+ if (!ltr502_proximity_enable(ltr502)) {
+ ret = size;
+ ltr502->power_state |= PROXIMITY_ENABLED;
+ wake_lock(&ltr502->prx_wake_lock);
+ hrtimer_start(&ltr502->proximity_timer,
+ ltr502->proximity_poll_delay,
+ HRTIMER_MODE_REL);
+ }
+ } else if (!new_value && (ltr502->power_state & PROXIMITY_ENABLED)) {
+ if (!ltr502_proximity_disable(ltr502)) {
+ ret = size;
+ ltr502->power_state &= ~PROXIMITY_ENABLED;
+ wake_unlock(&ltr502->prx_wake_lock);
+ hrtimer_cancel(&ltr502->proximity_timer);
+ cancel_work_sync(&ltr502->work_proximity);
+ }
+ }
+ mutex_unlock(&ltr502->lock);
+
+ return ret;
+}
+
+static DEVICE_ATTR(light_poll_delay, S_IRUGO | S_IWUSR | S_IWGRP,
+ light_poll_delay_show, light_poll_delay_store);
+
+static struct device_attribute dev_attr_light_enable =
+__ATTR(enable, S_IRUGO | S_IWUSR | S_IWGRP,
+ light_enable_show, light_enable_store);
+
+static struct attribute *light_sysfs_attrs[] = {
+ &dev_attr_light_enable.attr,
+ &dev_attr_light_poll_delay.attr,
+ NULL
+};
+
+static struct attribute_group light_attribute_group = {
+ .attrs = light_sysfs_attrs,
+};
+
+static DEVICE_ATTR(proximity_poll_delay, S_IRUGO | S_IWUSR | S_IWGRP,
+ proximity_poll_delay_show, proximity_poll_delay_store);
+
+static struct device_attribute dev_attr_proximity_enable =
+__ATTR(enable, S_IRUGO | S_IWUSR | S_IWGRP,
+ proximity_enable_show, proximity_enable_store);
+
+static struct attribute *proximity_sysfs_attrs[] = {
+ &dev_attr_proximity_enable.attr,
+ &dev_attr_proximity_poll_delay.attr,
+
+ NULL
+};
+
+static struct attribute_group proximity_attribute_group = {
+ .attrs = proximity_sysfs_attrs,
+};
+
+static void ltr502_work_func_proximity(struct work_struct *work)
+{
+ struct ltr502_data *ltr502 = container_of(work, struct ltr502_data,
+ work_proximity);
+ u8 data;
+ int rc;
+
+ rc = ltr502_i2c_read(ltr502, REGS_DATA, &data);
+ if (rc) {
+ pr_err("Fail to read the data regs!\n");
+ return;
+ }
+ /* 0 is close, 1 is far */
+ ltr502_dbgmsg("ltr502: DPS data = %x\n", data);
+ data = (data & 0x80) ? 0 : 1;
+ input_report_abs(ltr502->proximity_input_dev, ABS_DISTANCE, data);
+ input_sync(ltr502->proximity_input_dev);
+}
+
+static void ltr502_work_func_light(struct work_struct *work)
+{
+ struct ltr502_data *ltr502 = container_of(work, struct ltr502_data,
+ work_light);
+ u8 data;
+ u8 pdata;
+ int rc;
+
+ rc = ltr502_i2c_read(ltr502, REGS_DATA, &data);
+ if (rc) {
+ pr_err("Fail to read the data regs!\n");
+ return;
+ }
+ pdata = (data & 0x80) ? 0 : 1;
+ data &= 0x3f;
+ ltr502_dbgmsg("ltr502: DLS data = %d,lux = %d\n", data,
+ lux_table[data]);
+ if (lux_table[data] > 2) //prevent noise data "1 lux"
+ {
+ input_report_abs(ltr502->light_input_dev, ABS_MISC,
+ lux_table[data] * 2);
+ input_sync(ltr502->light_input_dev);
+ }
+
+}
+
+/* This function is for light sensor. It operates every a few seconds.
+ * It asks for work to be done on a thread because i2c needs a thread
+ * context (slow and blocking) and then reschedules the timer to run again.
+ */
+static enum hrtimer_restart ltr502_light_timer_func(struct hrtimer *timer)
+{
+ struct ltr502_data *ltr502 =
+ container_of(timer, struct ltr502_data, light_timer);
+ queue_work(ltr502->wq, &ltr502->work_light);
+ hrtimer_forward_now(&ltr502->light_timer, ltr502->light_poll_delay);
+ return HRTIMER_RESTART;
+}
+
+/* This function is for light sensor. It operates every a few seconds.
+ * It asks for work to be done on a thread because i2c needs a thread
+ * context (slow and blocking) and then reschedules the timer to run again.
+ */
+static enum hrtimer_restart ltr502_pxy_timer_func(struct hrtimer *timer)
+{
+ struct ltr502_data *ltr502 = container_of(timer, struct ltr502_data,
+ proximity_timer);
+ queue_work(ltr502->wq, &ltr502->work_proximity);
+ hrtimer_forward_now(&ltr502->proximity_timer,
+ ltr502->proximity_poll_delay);
+ return HRTIMER_RESTART;
+}
+
+static int ltr502_hardware_init(struct ltr502_data *ltr502)
+{
+ int rc = -EIO;
+ u8 int_status, data;
+ /* wait 200ms for hardware init, no need anymore */
+ //usleep(200000);
+ ltr502_dbgmsg("start\n");
+ //write default value to resume the sensor
+ data = 0x11;
+ rc = ltr502_i2c_write(ltr502, REGS_TIMING, &data);
+ if (rc) {
+ pr_err
+ ("fail to write REGS_TIMING,try to write REGS_DPS_CTL..\n");
+ data = 0x44;
+ rc = ltr502_i2c_write(ltr502, REGS_DPS_CTL, &data);
+ if (rc) {
+ pr_err("fail to write REGS_DPS_CTL\n");
+ return rc;
+ }
+ }
+ //enter the idle
+ data = 0x03;
+ rc = ltr502_i2c_write(ltr502, REGS_CONFIG, &data);
+ if (rc) {
+ pr_err("fail to write REGS_CONFIG\n");
+ return rc;
+ }
+ //DPS_CTL level 80mm
+ data = 0x44;
+ rc = ltr502_i2c_write(ltr502, REGS_DPS_CTL, &data);
+ if (rc) {
+ pr_err("fail to write REGS_DPS_CTL\n");
+ return rc;
+ }
+
+ /*FIXME:DLS 0x0F Window 93.5% loss for 7x27A version 1.5 due to the high window loss */
+ /*FIXME:DLS 0x08 Window 72.2% loss for 7x27A version PVT */
+ data = 0x08;
+ rc = ltr502_i2c_write(ltr502, REGS_WINDOW, &data);
+ if (rc) {
+ pr_err("fail to write REGS_WINDOW\n");
+ return rc;
+ }
+ //read the status
+ rc = ltr502_i2c_read(ltr502, REGS_INT_STATUS, &int_status);
+ if (rc) {
+ pr_err("fail to write REGS_INT_STATUS\n");
+ return rc;
+ }
+ //read data
+ rc = ltr502_i2c_read(ltr502, REGS_DATA, &data);
+ if (rc) {
+ pr_err("fail to write REGS_INT_STATUS\n");
+ return rc;
+ }
+
+ ltr502_dbgmsg("success\n");
+ return rc;
+}
+
+static int ltr502_i2c_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ int ret = -ENODEV;
+ struct input_dev *input_dev;
+ struct ltr502_data *ltr502;
+ struct ltr502_platform_data *pdata = client->dev.platform_data;
+
+ if (!pdata) {
+ pr_err("%s: missing pdata!\n", __func__);
+ return ret;
+ }
+
+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
+ pr_err("%s: i2c functionality check failed!\n", __func__);
+ return ret;
+ }
+
+ ltr502 = kzalloc(sizeof(struct ltr502_data), GFP_KERNEL);
+ if (!ltr502) {
+ pr_err("%s: failed to alloc memory for module data\n",
+ __func__);
+ return -ENOMEM;
+ }
+
+ /* ext_2v8 control */
+ if (!reg_ext_2v8) {
+ reg_ext_2v8 = regulator_get(NULL, "ext_2p85v");
+ if (IS_ERR(reg_ext_2v8)) {
+ pr_err("'%s' regulator not found, rc=%ld\n",
+ "ext_2v8", IS_ERR(reg_ext_2v8));
+ reg_ext_2v8 = NULL;
+ goto err_hardware_init;
+ }
+ }
+
+ ltr502->power_state = 0;
+ ltr502->pdata = pdata;
+ ltr502->i2c_client = client;
+ i2c_set_clientdata(client, ltr502);
+
+ if (ltr502_hardware_init(ltr502)) {
+ pr_err("LTR502 hardware init failed!");
+ goto err_hardware_init;
+ }
+
+ /* wake lock init */
+ wake_lock_init(&ltr502->prx_wake_lock, WAKE_LOCK_SUSPEND,
+ "prx_wake_lock");
+ mutex_init(&ltr502->lock);
+
+ /* allocate proximity input_device */
+ input_dev = input_allocate_device();
+ if (!input_dev) {
+ pr_err("%s: could not allocate input device\n", __func__);
+ goto err_input_allocate_device_proximity;
+ }
+ ltr502->proximity_input_dev = input_dev;
+ input_set_drvdata(input_dev, ltr502);
+ input_dev->name = "proximity";
+ input_set_capability(input_dev, EV_ABS, ABS_DISTANCE);
+ input_set_abs_params(input_dev, ABS_DISTANCE, 0, 1, 0, 0);
+
+ ltr502_dbgmsg("registering proximity input device\n");
+ ret = input_register_device(input_dev);
+ if (ret < 0) {
+ pr_err("%s: could not register input device\n", __func__);
+ goto err_input_register_device_proximity;
+ }
+
+ ret = sysfs_create_group(&input_dev->dev.kobj,
+ &proximity_attribute_group);
+ if (ret) {
+ pr_err("%s: could not create sysfs group\n", __func__);
+ goto err_sysfs_create_group_proximity;
+ }
+ /* this is the thread function we run on the work queue */
+ INIT_WORK(&ltr502->work_proximity, ltr502_work_func_proximity);
+
+ /* proximity hrtimer settings. we poll for light values using a timer. */
+ hrtimer_init(&ltr502->proximity_timer, CLOCK_MONOTONIC,
+ HRTIMER_MODE_REL);
+ ltr502->proximity_poll_delay = ns_to_ktime(200 * NSEC_PER_MSEC);
+ ltr502->proximity_timer.function = ltr502_pxy_timer_func;
+
+ /* light hrtimer settings. we poll for light values using a timer. */
+ hrtimer_init(&ltr502->light_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
+ ltr502->light_poll_delay = ns_to_ktime(200 * NSEC_PER_MSEC);
+ ltr502->light_timer.function = ltr502_light_timer_func;
+
+ /* the timer just fires off a work queue request. we need a thread
+ to read the i2c (can be slow and blocking). */
+ ltr502->wq = create_singlethread_workqueue("ltr502_wq");
+ if (!ltr502->wq) {
+ ret = -ENOMEM;
+ pr_err("%s: could not create workqueue\n", __func__);
+ goto err_create_workqueue;
+ }
+ /* this is the thread function we run on the work queue */
+ INIT_WORK(&ltr502->work_light, ltr502_work_func_light);
+
+ /* allocate lightsensor-level input_device */
+ input_dev = input_allocate_device();
+ if (!input_dev) {
+ pr_err("%s: could not allocate input device\n", __func__);
+ ret = -ENOMEM;
+ goto err_input_allocate_device_light;
+ }
+ input_set_drvdata(input_dev, ltr502);
+ input_dev->name = "light";
+ input_set_capability(input_dev, EV_ABS, ABS_MISC);
+ input_set_abs_params(input_dev, ABS_MISC, 0, 1, 0, 0);
+
+ ltr502_dbgmsg("registering light sensor input device\n");
+ ret = input_register_device(input_dev);
+ if (ret < 0) {
+ pr_err("%s: could not register input device\n", __func__);
+ input_free_device(input_dev);
+ goto err_input_register_device_light;
+ }
+ ltr502->light_input_dev = input_dev;
+ ret = sysfs_create_group(&input_dev->dev.kobj, &light_attribute_group);
+ if (ret) {
+ pr_err("%s: could not create sysfs group\n", __func__);
+ goto err_sysfs_create_group_light;
+ }
+
+ ltr502->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN;
+ ltr502->early_suspend.suspend = ltr502_early_suspend;
+ ltr502->early_suspend.resume = ltr502_late_resume;
+ register_early_suspend(&ltr502->early_suspend);
+
+ goto done;
+
+ /* error, unwind it all */
+err_sysfs_create_group_light:
+ input_unregister_device(ltr502->light_input_dev);
+err_input_register_device_light:
+err_input_allocate_device_light:
+ destroy_workqueue(ltr502->wq);
+err_create_workqueue:
+ sysfs_remove_group(&ltr502->proximity_input_dev->dev.kobj,
+ &proximity_attribute_group);
+err_sysfs_create_group_proximity:
+ input_unregister_device(ltr502->proximity_input_dev);
+err_input_register_device_proximity:
+ input_free_device(input_dev);
+err_input_allocate_device_proximity:
+ mutex_destroy(&ltr502->lock);
+ wake_lock_destroy(&ltr502->prx_wake_lock);
+err_hardware_init:
+ kfree(ltr502);
+ regulator_put(reg_ext_2v8);
+done:
+ return ret;
+}
+
+static void ltr502_early_suspend(struct early_suspend *h)
+{
+ /* We disable power only if proximity is disabled. If proximity
+ is enabled, we leave power on because proximity is allowed
+ to wake up device. We remove power without changing
+ ltr502->power_state because we use that state in resume.
+ */
+ u8 mode;
+ struct ltr502_data *ltr502 =
+ container_of(h, struct ltr502_data, early_suspend);
+
+ ltr502_dbgmsg("early suspend\n");
+
+ if (ltr502->power_state & LIGHT_ENABLED)
+ ltr502_light_disable(ltr502);
+
+ if (!(ltr502->power_state & PROXIMITY_ENABLED)) {
+ ltr502_dbgmsg("enter power down\n");
+ if (!ltr502_i2c_read(ltr502, REGS_CONFIG, &mode)) {
+ mode &= ~(POWER_MASK);
+ mode |= (POWER_DOWN);
+ if (ltr502_i2c_write(ltr502, REGS_CONFIG, &mode)) {
+ pr_err("fail to write REGS_DPS_CTL\n");
+ }
+ } else {
+ pr_err("fail to write REGS_CONFIG\n");
+ }
+ }
+}
+
+static void ltr502_late_resume(struct early_suspend *h)
+{
+ /* Turn power back on if we were before suspend. */
+ u8 mode;
+ struct ltr502_data *ltr502 =
+ container_of(h, struct ltr502_data, early_suspend);
+
+ ltr502_dbgmsg("late resume\n");
+
+ if (ltr502->power_state & LIGHT_ENABLED)
+ ltr502_light_enable(ltr502);
+
+ if (!(ltr502->power_state & PROXIMITY_ENABLED)) {
+ ltr502_dbgmsg("exit power down\n");
+ if (!ltr502_i2c_read(ltr502, REGS_CONFIG, &mode)) {
+ mode &= ~(POWER_MASK);
+ mode |= (POWER_UP);
+ if (ltr502_i2c_write(ltr502, REGS_CONFIG, &mode)) {
+ pr_err("fail to write REGS_CONFIG\n");
+ }
+ } else {
+ pr_err("fail to write REGS_CONFIG\n");
+ }
+ }
+}
+
+static int ltr502_i2c_remove(struct i2c_client *client)
+{
+ struct ltr502_data *ltr502 = i2c_get_clientdata(client);
+ sysfs_remove_group(&ltr502->light_input_dev->dev.kobj,
+ &light_attribute_group);
+ input_unregister_device(ltr502->light_input_dev);
+ sysfs_remove_group(&ltr502->proximity_input_dev->dev.kobj,
+ &proximity_attribute_group);
+ input_unregister_device(ltr502->proximity_input_dev);
+ if (ltr502->power_state) {
+ if (ltr502->power_state & PROXIMITY_ENABLED) {
+ hrtimer_cancel(&ltr502->proximity_timer);
+ cancel_work_sync(&ltr502->work_proximity);
+ ltr502_proximity_disable(ltr502);
+ }
+ if (ltr502->power_state & LIGHT_ENABLED) {
+ hrtimer_cancel(&ltr502->proximity_timer);
+ cancel_work_sync(&ltr502->work_proximity);
+ ltr502_light_disable(ltr502);
+ }
+ ltr502->power_state = 0;
+ }
+ destroy_workqueue(ltr502->wq);
+ mutex_destroy(&ltr502->lock);
+ wake_lock_destroy(&ltr502->prx_wake_lock);
+ unregister_early_suspend(&ltr502->early_suspend);
+ kfree(ltr502);
+ return 0;
+}
+
+static const struct i2c_device_id ltr502_device_id[] = {
+ {SENSOR_NAME, 0},
+ {}
+};
+
+MODULE_DEVICE_TABLE(i2c, ltr502_device_id);
+
+static struct i2c_driver ltr502_i2c_driver = {
+ .driver = {
+ .name = SENSOR_NAME,
+ .owner = THIS_MODULE,
+ },
+ .probe = ltr502_i2c_probe,
+ .remove = ltr502_i2c_remove,
+ .id_table = ltr502_device_id,
+};
+
+static int __init ltr502_init(void)
+{
+ return i2c_add_driver(&ltr502_i2c_driver);
+}
+
+static void __exit ltr502_exit(void)
+{
+ i2c_del_driver(&ltr502_i2c_driver);
+}
+
+module_init(ltr502_init);
+module_exit(ltr502_exit);
+
+MODULE_AUTHOR("mjchen@sta.samsung.com");
+MODULE_DESCRIPTION("Optical Sensor driver for ltr502");
+MODULE_LICENSE("GPL");
diff --git a/drivers/input/misc/ltr558.c b/drivers/input/misc/ltr558.c
new file mode 100644
index 0000000..0d322fe
--- /dev/null
+++ b/drivers/input/misc/ltr558.c
@@ -0,0 +1,848 @@
+/*
+ * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/i2c.h>
+#include <linux/fs.h>
+#include <linux/errno.h>
+#include <linux/device.h>
+#include <linux/delay.h>
+#include <linux/miscdevice.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/wakelock.h>
+#include <linux/slab.h>
+#include <linux/input.h>
+#include <linux/workqueue.h>
+#include <linux/uaccess.h>
+#include <linux/earlysuspend.h>
+#include <linux/input/ltr5xx.h>
+
+
+//#define DEBUG_LTR558
+#ifdef DEBUG_LTR558
+#define LTR558_DBGMSG(str, args...) printk("%s: " str, __func__, ##args)
+#else
+#define LTR558_DBGMSG(str, args...)
+#endif
+
+/* LTR-558 Registers */
+#define LTR558_ALS_CONTR 0x80
+#define LTR558_PS_CONTR 0x81
+#define LTR558_PS_LED 0x82
+#define LTR558_PS_N_PULSES 0x83
+#define LTR558_PS_MEAS_RATE 0x84
+#define LTR558_ALS_MEAS_RATE 0x85
+#define LTR558_MANUFACTURER_ID 0x87
+
+#define LTR558_INTERRUPT 0x8F
+#define LTR558_PS_THRES_UP_0 0x90
+#define LTR558_PS_THRES_UP_1 0x91
+#define LTR558_PS_THRES_LOW_0 0x92
+#define LTR558_PS_THRES_LOW_1 0x93
+
+#define LTR558_ALS_THRES_UP_0 0x97
+#define LTR558_ALS_THRES_UP_1 0x98
+#define LTR558_ALS_THRES_LOW_0 0x99
+#define LTR558_ALS_THRES_LOW_1 0x9A
+
+#define LTR558_INTERRUPT_PERSIST 0x9E
+
+/* 558's Read Only Registers */
+#define LTR558_ALS_DATA_CH1_0 0x88
+#define LTR558_ALS_DATA_CH1_1 0x89
+#define LTR558_ALS_DATA_CH0_0 0x8A
+#define LTR558_ALS_DATA_CH0_1 0x8B
+#define LTR558_ALS_PS_STATUS 0x8C
+#define LTR558_PS_DATA_0 0x8D
+#define LTR558_PS_DATA_1 0x8E
+
+/* Basic Operating Modes */
+#define MODE_ALS_ON_Range1 0x0b
+#define MODE_ALS_ON_Range2 0x03
+#define MODE_ALS_StdBy 0x00
+#define MODE_ALS_ON_FLAG 0x02
+
+
+#define MODE_PS_ON_Gain1 0x03
+#define MODE_PS_ON_Gain4 0x07
+#define MODE_PS_ON_Gain8 0x0B
+#define MODE_PS_ON_Gain16 0x0f
+#define MODE_PS_StdBy 0x00
+#define MODE_ACTIVE 0x02
+
+#define INTERRUPT_OP_MODE 0x08 /* updated after every measurement*/
+#define INTERRUPT_POLARITY 0x00 /* low active */
+#define ENABLE_PS_INTERRUPT 0x01
+#define ENABLE_ALS_INTERRUPT 0x02
+
+#define DEFAULT_INT_MODE (INTERRUPT_OP_MODE | INTERRUPT_POLARITY)
+
+#define PS_RANGE1 1
+#define PS_RANGE2 2
+#define PS_RANGE4 4
+#define PS_RANGE8 8
+
+#define ALS_RANGE1_320 1
+#define ALS_RANGE2_64K 2
+
+#define PON_DELAY 600
+#define WAKEUP_DELAY 10
+#define ALS_INTEGRATION_TIME 100
+
+#define SENSOR_NAME "ltr558"
+
+enum {
+ LIGHT_ENABLED = BIT(0),
+ PROXIMITY_ENABLED = BIT(1),
+};
+
+/* driver data */
+struct ltr558_data {
+ bool on;
+ u8 power_state; /* sensor power control state */
+ struct ltr5xx_platform_data *pdata;
+ struct i2c_client *i2c_client;
+ struct mutex lock;
+ struct workqueue_struct *wq;
+ struct early_suspend early_suspend;
+ struct wake_lock prx_wake_lock;
+
+ struct input_dev *light_input_dev;
+ struct work_struct work_light;
+ struct hrtimer light_timer;
+ ktime_t light_poll_delay;
+
+ struct input_dev *proximity_input_dev;
+ struct work_struct work_proximity;
+ bool ps_is_near_state;
+};
+
+static int ps_gainrange;
+static int als_gainrange;
+static int als_integration_time;
+static struct i2c_client *ltr588_client = NULL;
+static int prox_threshold_hi = 200; //Default value
+static int prox_threshold_lo = 160;
+
+static void ltr558_early_suspend(struct early_suspend *h);
+static void ltr558_late_resume(struct early_suspend *h);
+
+static int ltr558_i2c_read_reg(u8 regnum)
+{
+ int readdata;
+ readdata = i2c_smbus_read_byte_data(ltr588_client, regnum);
+ return readdata;
+}
+
+static int ltr558_i2c_write_reg(u8 regnum, u8 value)
+{
+ int writeerror;
+ writeerror = i2c_smbus_write_byte_data(ltr588_client, regnum, value);
+ if (writeerror < 0)
+ return writeerror;
+ else
+ return 0;
+}
+
+static int ltr558_light_enable(struct ltr558_data *ltr558)
+{
+ int error=0;
+ LTR558_DBGMSG("ltr558_light_enable\n");
+ /* ===============
+ * ** IMPORTANT **
+ * ===============
+ * Other settings like timing and threshold to be set here, if required.
+ * Not set and kept as device default for now.
+ */
+ ltr558_i2c_write_reg(LTR558_ALS_THRES_LOW_0, 0xff); //0xff
+ ltr558_i2c_write_reg(LTR558_ALS_THRES_LOW_1, 0xff); //0xff
+ ltr558_i2c_write_reg(LTR558_ALS_THRES_UP_0, 0); //0
+ ltr558_i2c_write_reg(LTR558_ALS_THRES_UP_1, 0); //0
+
+ if (als_gainrange == 1)
+ error = ltr558_i2c_write_reg(LTR558_ALS_CONTR, MODE_ALS_ON_Range1);
+ else if (als_gainrange == 2)
+ error = ltr558_i2c_write_reg(LTR558_ALS_CONTR, MODE_ALS_ON_Range2);//03
+ else
+ error = 1;//flase arg value
+
+ msleep(WAKEUP_DELAY);
+ return error;
+}
+
+static int ltr558_light_disable(struct ltr558_data *ltr558)
+{
+ int error;
+ error = ltr558_i2c_write_reg(LTR558_ALS_CONTR, MODE_ALS_StdBy);
+ return error;
+}
+
+static ssize_t light_poll_delay_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct ltr558_data *ltr558 = dev_get_drvdata(dev);
+ return sprintf(buf, "%lld\n", ktime_to_ns(ltr558->light_poll_delay));
+}
+
+static ssize_t light_poll_delay_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+ struct ltr558_data *ltr558 = dev_get_drvdata(dev);
+ int64_t new_delay;
+ int err;
+
+ err = strict_strtoll(buf, 10, &new_delay);
+ if (err < 0)
+ return err;
+
+ LTR558_DBGMSG("new delay = %lldns, old delay = %lldns\n",
+ new_delay, ktime_to_ns(ltr558->light_poll_delay));
+ mutex_lock(&ltr558->lock);
+ if (new_delay != ktime_to_ns(ltr558->light_poll_delay)) {
+ ltr558->light_poll_delay = ns_to_ktime(new_delay);
+ if (ltr558->power_state & LIGHT_ENABLED) {
+ hrtimer_cancel(&ltr558->light_timer);
+ cancel_work_sync(&ltr558->work_light);
+ hrtimer_start(&ltr558->light_timer,
+ ltr558->light_poll_delay,
+ HRTIMER_MODE_REL);
+ }
+ }
+ mutex_unlock(&ltr558->lock);
+ return size;
+}
+
+static ssize_t light_enable_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct ltr558_data *ltr558 = dev_get_drvdata(dev);
+ return sprintf(buf, "%d\n",
+ (ltr558->power_state & LIGHT_ENABLED) ? 1 : 0);
+}
+
+static ssize_t light_enable_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+ struct ltr558_data *ltr558 = dev_get_drvdata(dev);
+ bool new_value;
+ int ret = -EINVAL;
+
+ if (sysfs_streq(buf, "1"))
+ new_value = true;
+ else if (sysfs_streq(buf, "0"))
+ new_value = false;
+ else {
+ pr_err("%s: invalid value %d\n", __func__, *buf);
+ return ret;
+ }
+
+ mutex_lock(&ltr558->lock);
+ LTR558_DBGMSG("new_value = %d, old state = %d\n",
+ new_value, (ltr558->power_state & LIGHT_ENABLED) ? 1 : 0);
+ if (new_value && !(ltr558->power_state & LIGHT_ENABLED)) {
+ if (!ltr558_light_enable(ltr558)) {
+ ret = size;
+ ltr558->power_state |= LIGHT_ENABLED;
+ hrtimer_start(&ltr558->light_timer,
+ ltr558->light_poll_delay,
+ HRTIMER_MODE_REL);
+ }
+ } else if (!new_value && (ltr558->power_state & LIGHT_ENABLED)) {
+ if (!ltr558_light_disable(ltr558)) {
+ ret = size;
+ ltr558->power_state &= ~LIGHT_ENABLED;
+ hrtimer_cancel(&ltr558->light_timer);
+ cancel_work_sync(&ltr558->work_light);
+ }
+ }
+ mutex_unlock(&ltr558->lock);
+
+ return ret;
+}
+
+static int ltr558_proximity_enable(struct ltr558_data *ltr558)
+{
+ int setgain;
+ int read_val;
+ char buf[4] = {0};
+
+ LTR558_DBGMSG("ltr558_proximity_enable\n");
+
+ buf[0] = prox_threshold_lo & 0x0ff;
+ buf[1] = (prox_threshold_lo >> 8) & 0x07;
+ buf[2] = prox_threshold_hi & 0x0ff; //up
+ buf[3] = (prox_threshold_hi >> 8) & 0x07;
+ ltr558_i2c_write_reg(LTR558_PS_THRES_LOW_0, buf[0]);
+ ltr558_i2c_write_reg(LTR558_PS_THRES_LOW_1, buf[1]);
+ ltr558_i2c_write_reg(LTR558_PS_THRES_UP_0, buf[2]);
+ ltr558_i2c_write_reg(LTR558_PS_THRES_UP_1, buf[3]);
+
+ switch (ps_gainrange) {
+ case PS_RANGE1:
+ setgain = MODE_PS_ON_Gain1;//03
+ break;
+ case PS_RANGE2:
+ setgain = MODE_PS_ON_Gain4;
+ break;
+ case PS_RANGE4:
+ setgain = MODE_PS_ON_Gain8;
+ break;
+ case PS_RANGE8:
+ setgain = MODE_PS_ON_Gain16;
+ break;
+ default:
+ setgain = MODE_PS_ON_Gain1;
+ break;
+ }
+
+ setgain |= MODE_ACTIVE;
+ if(ltr558_i2c_write_reg(LTR558_PS_CONTR, setgain)){
+ pr_err("%s: write PS control error .\n", __func__);
+ }
+ /* enable ALS sensor to ensure PS working proprely */
+ read_val = ltr558_i2c_read_reg(LTR558_ALS_CONTR);
+ if(read_val < 0 ){
+ pr_err("%s: read PS control error .\n", __func__);
+ }
+ else if(!(read_val & MODE_ALS_ON_FLAG)){
+ if(ltr558_i2c_write_reg(LTR558_ALS_CONTR, (read_val | MODE_ALS_ON_FLAG))){
+ pr_err("%s: turn on ALS control error .\n", __func__);
+ }
+ }
+
+ msleep(WAKEUP_DELAY);
+
+ LTR558_DBGMSG("WAKEUP_DELAY 10ms after write cmd register.\n");
+ return 0; /* always return true since error state is not handled by caller */
+}
+
+static int ltr558_proximity_disable(struct ltr558_data *ltr558)
+{
+ int err;
+
+ if(!(ltr558->power_state & LIGHT_ENABLED)){
+ /* turn off ALS if light is not enable by uplayer*/
+ if(ltr558_i2c_write_reg(LTR558_ALS_CONTR, MODE_ALS_StdBy)){
+ pr_err("%s: turn off ALS control error .\n", __func__);
+ }
+ }
+
+ err = ltr558_i2c_write_reg(LTR558_PS_CONTR, MODE_PS_StdBy);
+ if(err){
+ pr_err("%s: write PS interrupt control error %d.\n", __func__, err);
+ }
+ return err;
+}
+
+
+static ssize_t proximity_enable_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct ltr558_data *ltr558 = dev_get_drvdata(dev);
+ return sprintf(buf, "%d\n",
+ (ltr558->power_state & PROXIMITY_ENABLED) ? 1 : 0);
+}
+
+static ssize_t proximity_enable_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+ struct ltr558_data *ltr558 = dev_get_drvdata(dev);
+ bool new_value;
+ int ret = -EINVAL;
+
+ if (sysfs_streq(buf, "1"))
+ new_value = true;
+ else if (sysfs_streq(buf, "0"))
+ new_value = false;
+ else {
+ pr_err("%s: invalid value %d\n", __func__, *buf);
+ return ret;
+ }
+
+ mutex_lock(&ltr558->lock);
+ LTR558_DBGMSG("%s, new_value = %d, old state = %d\n",
+ __func__, new_value,
+ (ltr558->power_state & PROXIMITY_ENABLED) ? 1 : 0);
+ if (new_value && !(ltr558->power_state & PROXIMITY_ENABLED)) {
+ if (!ltr558_proximity_enable(ltr558)) {
+ ret = size;
+ ltr558->power_state |= PROXIMITY_ENABLED;
+ }
+ } else if (!new_value && (ltr558->power_state & PROXIMITY_ENABLED)) {
+ if (!ltr558_proximity_disable(ltr558)) {
+ ret = size;
+ ltr558->power_state &= ~PROXIMITY_ENABLED;
+ cancel_work_sync(&ltr558->work_proximity);
+ }
+ }
+ mutex_unlock(&ltr558->lock);
+
+ return ret;
+}
+
+static DEVICE_ATTR(light_poll_delay, S_IRUGO | S_IWUSR | S_IWGRP,
+ light_poll_delay_show, light_poll_delay_store);
+
+static struct device_attribute dev_attr_light_enable =
+__ATTR(enable, S_IRUGO | S_IWUSR | S_IWGRP,
+ light_enable_show, light_enable_store);
+
+static struct attribute *light_sysfs_attrs[] = {
+ &dev_attr_light_enable.attr,
+ &dev_attr_light_poll_delay.attr,
+ NULL
+};
+
+static struct attribute_group light_attribute_group = {
+ .attrs = light_sysfs_attrs,
+};
+
+
+static struct device_attribute dev_attr_proximity_enable =
+__ATTR(enable, S_IRUGO | S_IWUSR | S_IWGRP,
+ proximity_enable_show, proximity_enable_store);
+
+static struct attribute *proximity_sysfs_attrs[] = {
+ &dev_attr_proximity_enable.attr,
+ NULL
+};
+
+static struct attribute_group proximity_attribute_group = {
+ .attrs = proximity_sysfs_attrs,
+};
+
+static void ltr558_work_func_proximity(struct work_struct *work)
+{
+ struct ltr558_data *ltr558 = container_of(work, struct ltr558_data,
+ work_proximity);
+ int psval_lo, psval_hi, psdata;
+ int retry_count = 3;
+ int data = 0;
+
+ for(psval_lo =-1, psval_hi=-1; retry_count > 0 ; retry_count--){
+ psval_lo = ltr558_i2c_read_reg(LTR558_PS_DATA_0);
+ psval_hi = ltr558_i2c_read_reg(LTR558_PS_DATA_1);
+ if ((psval_lo < 0) || (psval_hi < 0)){
+ usleep(50000);
+ continue;
+ }
+ }
+ if(psval_lo < 0 || psval_hi < 0 ){
+ goto out;
+ }
+ psdata = ((psval_hi & 7)* 256) + psval_lo;
+ if (psdata < prox_threshold_lo){ /* far */
+ data = 2;
+ ltr558->ps_is_near_state = false;
+ ltr558_i2c_write_reg(LTR558_PS_THRES_LOW_0, 0);
+ ltr558_i2c_write_reg(LTR558_PS_THRES_LOW_1, 0);
+ ltr558_i2c_write_reg(LTR558_PS_THRES_UP_0, prox_threshold_hi & 0xFF);
+ ltr558_i2c_write_reg(LTR558_PS_THRES_UP_1, ((prox_threshold_hi >> 8) & 0x07));
+ input_report_abs(ltr558->proximity_input_dev, ABS_DISTANCE, data);
+ input_sync(ltr558->proximity_input_dev);
+ }
+ else if (psdata > prox_threshold_hi){ /* near */
+ data = 0;
+ ltr558->ps_is_near_state = true;
+
+ ltr558_i2c_write_reg(LTR558_PS_THRES_LOW_0, prox_threshold_lo & 0xFF);
+ ltr558_i2c_write_reg(LTR558_PS_THRES_LOW_1, ((prox_threshold_lo >> 8) & 0x07));
+ ltr558_i2c_write_reg(LTR558_PS_THRES_UP_0, 0xFF);
+ ltr558_i2c_write_reg(LTR558_PS_THRES_UP_1, 0x07);
+ input_report_abs(ltr558->proximity_input_dev, ABS_DISTANCE, data);
+ input_sync(ltr558->proximity_input_dev);
+ }
+ else{
+ /* setup threshold for next interrupt detection */
+ ltr558_i2c_write_reg(LTR558_PS_THRES_LOW_0, prox_threshold_lo & 0x0ff);
+ ltr558_i2c_write_reg(LTR558_PS_THRES_LOW_1, ((prox_threshold_lo >> 8) & 0x07));
+ ltr558_i2c_write_reg(LTR558_PS_THRES_UP_0, prox_threshold_hi & 0x0ff);
+ ltr558_i2c_write_reg(LTR558_PS_THRES_UP_1, ((prox_threshold_hi >> 8) & 0x07));
+ }
+ LTR558_DBGMSG(">>>%s : primitive prox_data psdata = %d mode=%d.\n", __func__, psdata, data);
+ return;
+
+out:
+ pr_err("%s, error occured psval_lo=%d, psval_hi=%d.\n", __func__, psval_lo, psval_hi);
+ return;
+}
+
+static void ltr558_work_func_light(struct work_struct *work)
+{
+ int als_ps_status;
+ int interrupt, newdata;
+
+ struct ltr558_data *ltr558 = container_of(work, struct ltr558_data,work_light);
+ int alsval_ch0_lo, alsval_ch0_hi, alsval_ch0;
+ int alsval_ch1_lo, alsval_ch1_hi, alsval_ch1;
+ int ratio;
+ int lux_val;
+ int ch0_coeff,ch1_coeff;
+
+ als_ps_status = ltr558_i2c_read_reg(LTR558_ALS_PS_STATUS);
+ interrupt = als_ps_status & 10;
+ newdata = als_ps_status & 5;
+ if ((newdata == 4) | (newdata == 5)){
+ alsval_ch1_lo = ltr558_i2c_read_reg(LTR558_ALS_DATA_CH1_0);
+ alsval_ch1_hi = ltr558_i2c_read_reg(LTR558_ALS_DATA_CH1_1);
+ alsval_ch1 = (alsval_ch1_hi * 256) + alsval_ch1_lo;
+
+ alsval_ch0_lo = ltr558_i2c_read_reg(LTR558_ALS_DATA_CH0_0);
+ alsval_ch0_hi = ltr558_i2c_read_reg(LTR558_ALS_DATA_CH0_1);
+ alsval_ch0 = (alsval_ch0_hi * 256) + alsval_ch0_lo;
+
+ ratio = (alsval_ch1 * 1000) / (alsval_ch0+alsval_ch1); //*1000
+
+ if (ratio > 850){
+ ch0_coeff = 0;
+ ch1_coeff = 0;
+ }else if(ratio > 640){
+ ch0_coeff = 16900; //*10000
+ ch1_coeff = 1690;
+ }else if(ratio > 450){
+ ch0_coeff = 37725;
+ ch1_coeff = 13363;
+ }else{
+ ch0_coeff = 17743;
+ ch1_coeff = -11059;
+ }
+
+ lux_val = (alsval_ch0*ch0_coeff - alsval_ch1*ch1_coeff)/100000; //0 to 75 in lux adjust 10000->100000
+ LTR558_DBGMSG(">>>>>%s: lux = %d, ch0=%d, ch1=%d, ratio=%d \n", __func__, lux_val, alsval_ch0, alsval_ch1, ratio);
+ input_report_abs(ltr558->light_input_dev, ABS_MISC,lux_val);
+ input_sync(ltr558->light_input_dev);
+ }
+
+}
+
+/* This function is for light sensor. It operates every a few seconds.
+ * It asks for work to be done on a thread because i2c needs a thread
+ * context (slow and blocking) and then reschedules the timer to run again.
+ */
+static enum hrtimer_restart ltr558_light_timer_func(struct hrtimer *timer)
+{
+ struct ltr558_data *ltr558 =
+ container_of(timer, struct ltr558_data, light_timer);
+ queue_work(ltr558->wq, &ltr558->work_light);
+ hrtimer_forward_now(&ltr558->light_timer, ltr558->light_poll_delay);
+ return HRTIMER_RESTART;
+}
+
+/* assume this is ISR */
+static irqreturn_t ltr558_interrupt(int vec, void *info)
+{
+ struct i2c_client *client=(struct i2c_client *)info;
+ struct ltr558_data *data = i2c_get_clientdata(client);
+
+ LTR558_DBGMSG("==> ltr558_interrupt (timeout)\n");
+ //Seems linux-3.0 trends to use threaded-interrupt, so we can call the work directly.
+ wake_lock(&data->prx_wake_lock);
+ ltr558_work_func_proximity(&data->work_proximity);
+ wake_unlock(&data->prx_wake_lock);
+
+ return IRQ_HANDLED;
+}
+
+static int ltr558_hardware_init(void)
+{
+ int ret = 0;
+ int init_ps_gain;
+ int init_als_gain;
+
+ msleep(PON_DELAY);
+
+ // full Gain1 at startup
+ init_ps_gain = PS_RANGE1;
+ ps_gainrange = init_ps_gain;
+
+ // Full Range at startup
+ init_als_gain = ALS_RANGE1_320;
+ als_gainrange = init_als_gain;
+ als_integration_time = ALS_INTEGRATION_TIME;
+ /* Must enable INT before activate */
+ ret = ltr558_i2c_write_reg(LTR558_INTERRUPT, DEFAULT_INT_MODE | ENABLE_PS_INTERRUPT);
+ if (ret < 0) {
+ LTR558_DBGMSG("ltr558_hardware_init fail\n");
+ return ret;
+ }
+ ltr558_i2c_write_reg(LTR558_PS_LED, 0x7b); /* 60K HZ 100% duty cycle 50mA */
+ ltr558_i2c_write_reg(LTR558_PS_N_PULSES, 0x08); /* 8 pulses */
+ ltr558_i2c_write_reg(LTR558_PS_MEAS_RATE, 0x02); /* 100ms integration, 200ms repreat */
+ ltr558_i2c_write_reg(LTR558_INTERRUPT_PERSIST, 0x00);
+
+ LTR558_DBGMSG("ltr558_hardware_init success\n");
+ return ret;
+}
+
+static int ltr558_i2c_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ int ret = -ENODEV;
+ struct input_dev *input_dev;
+ struct ltr558_data *ltr558;
+
+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
+ pr_err("%s: i2c functionality check failed!\n", __func__);
+ return ret;
+ }
+
+ ltr558 = kzalloc(sizeof(struct ltr558_data), GFP_KERNEL);
+ if (!ltr558) {
+ pr_err("%s: failed to alloc memory for module data\n",
+ __func__);
+ return -ENOMEM;
+ }
+
+ ltr558->pdata = client->dev.platform_data;
+ ltr558->power_state = 0;
+ ltr558->i2c_client = client;
+ ltr558->ps_is_near_state = false;
+ ltr588_client = ltr558->i2c_client;
+ i2c_set_clientdata(client, ltr558);
+
+ ret = ltr558_hardware_init();
+ if(ret < 0)
+ goto err_hardware_init;
+ /* wake lock init */
+ wake_lock_init(&ltr558->prx_wake_lock, WAKE_LOCK_SUSPEND,
+ "prx_wake_lock");
+ mutex_init(&ltr558->lock);
+
+ /* allocate proximity input_device */
+ input_dev = input_allocate_device();
+ if (!input_dev) {
+ pr_err("%s: could not allocate input device\n", __func__);
+ goto err_input_allocate_device_proximity;
+ }
+ ltr558->proximity_input_dev = input_dev;
+ input_set_drvdata(input_dev, ltr558);
+ input_dev->name = "proximity";
+ input_set_capability(input_dev, EV_ABS, ABS_DISTANCE);
+ input_set_abs_params(input_dev, ABS_DISTANCE, 0, 1, 0, 0);
+
+ LTR558_DBGMSG("registering proximity input device\n");
+ ret = input_register_device(input_dev);
+ if (ret < 0) {
+ pr_err("%s: could not register input device\n", __func__);
+ goto err_input_register_device_proximity;
+ }
+
+ ret = sysfs_create_group(&input_dev->dev.kobj,
+ &proximity_attribute_group);
+ if (ret) {
+ pr_err("%s: could not create sysfs group\n", __func__);
+ goto err_sysfs_create_group_proximity;
+ }
+ /* allocate lightsensor-level input_device */
+ input_dev = input_allocate_device();
+ if (!input_dev) {
+ pr_err("%s: could not allocate input device\n", __func__);
+ ret = -ENOMEM;
+ goto err_input_allocate_device_light;
+ }
+ input_set_drvdata(input_dev, ltr558);
+ input_dev->name = "light";
+ input_set_capability(input_dev, EV_ABS, ABS_MISC);
+ input_set_abs_params(input_dev, ABS_MISC, 0, 1, 0, 0);
+
+ LTR558_DBGMSG("registering light sensor input device\n");
+ ret = input_register_device(input_dev);
+ if (ret < 0) {
+ pr_err("%s: could not register input device\n", __func__);
+ input_free_device(input_dev);
+ goto err_input_register_device_light;
+ }
+ ltr558->light_input_dev = input_dev;
+ ret = sysfs_create_group(&input_dev->dev.kobj, &light_attribute_group);
+ if (ret) {
+ pr_err("%s: could not create sysfs group\n", __func__);
+ goto err_sysfs_create_group_light;
+ }
+
+ /* initialize timer for polling and workqueue for i2c reading */
+ /* light hrtimer settings. we poll for light values using a timer. */
+ hrtimer_init(&ltr558->light_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
+ ltr558->light_poll_delay = ns_to_ktime(1000 * NSEC_PER_MSEC);
+ ltr558->light_timer.function = ltr558_light_timer_func;
+
+ /* the timer just fires off a work queue request. we need a thread
+ to read the i2c (can be slow and blocking). */
+ ltr558->wq = create_singlethread_workqueue("ltr558_wq");
+ if (!ltr558->wq) {
+ ret = -ENOMEM;
+ pr_err("%s: could not create workqueue\n", __func__);
+ goto err_create_workqueue;
+ }
+ /* this is the thread function we run on the work queue */
+ INIT_WORK(&ltr558->work_light, ltr558_work_func_light);
+
+ /* this is the thread function we run on the work queue */
+ INIT_WORK(&ltr558->work_proximity, ltr558_work_func_proximity);
+#ifdef CONFIG_HAS_EARLYSUSPEND
+ /* register suspend/resume function */
+ ltr558->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN;
+ ltr558->early_suspend.suspend = ltr558_early_suspend;
+ ltr558->early_suspend.resume = ltr558_late_resume;
+ register_early_suspend(&ltr558->early_suspend);
+#endif /* !CONFIG_HAS_EARLYSUSPEND */
+
+ /* setup interrupt and wakeup */
+ device_init_wakeup(&client->dev, true);
+ /* Looks there will receive a fake interrupt after this request, careful */
+ /* keep this as the last statement in this function to avoid interrupt by interrupt */
+ ret = request_threaded_irq(ltr558->pdata->int_gpio, NULL, ltr558_interrupt, IRQ_TYPE_EDGE_FALLING,
+ SENSOR_NAME, (void *)client);
+ if (ret) {
+ pr_err("%s Could not allocate irq(%d) !\n", __func__, ltr558->pdata->int_gpio);
+ goto err_request_irq;
+ }
+
+ goto done;
+
+ /* error, unwind it all */
+err_request_irq:
+ device_init_wakeup(&client->dev, false);
+ destroy_workqueue(ltr558->wq);
+
+err_create_workqueue:
+ sysfs_remove_group(&ltr558->light_input_dev->dev.kobj,
+ &light_attribute_group);
+
+err_sysfs_create_group_light:
+ input_unregister_device(ltr558->light_input_dev);
+
+err_input_register_device_light:
+err_input_allocate_device_light:
+ sysfs_remove_group(&ltr558->proximity_input_dev->dev.kobj,
+ &proximity_attribute_group);
+
+err_sysfs_create_group_proximity:
+ input_unregister_device(ltr558->proximity_input_dev);
+
+err_input_register_device_proximity:
+ input_free_device(input_dev);
+
+err_input_allocate_device_proximity:
+ mutex_destroy(&ltr558->lock);
+ wake_lock_destroy(&ltr558->prx_wake_lock);
+
+err_hardware_init:
+ kfree(ltr558);
+
+done:
+ return ret;
+}
+
+static int ltr558_i2c_remove(struct i2c_client *client)
+{
+ struct ltr558_data *ltr558 = i2c_get_clientdata(client);
+
+ free_irq(ltr558->pdata->int_gpio, (void *)client);
+ device_init_wakeup(&client->dev, false);
+ sysfs_remove_group(&ltr558->light_input_dev->dev.kobj,
+ &light_attribute_group);
+ input_unregister_device(ltr558->light_input_dev);
+ sysfs_remove_group(&ltr558->proximity_input_dev->dev.kobj,
+ &proximity_attribute_group);
+ input_unregister_device(ltr558->proximity_input_dev);
+ if (ltr558->power_state) { /* May have unreleased resource if this variable is corrupted */
+ if (ltr558->power_state & PROXIMITY_ENABLED) {
+ cancel_work_sync(&ltr558->work_proximity);
+ ltr558_proximity_disable(ltr558);
+ }
+ if (ltr558->power_state & LIGHT_ENABLED) {
+ hrtimer_cancel(&ltr558->light_timer);
+ cancel_work_sync(&ltr558->work_light);
+ ltr558_light_disable(ltr558);
+ }
+ ltr558->power_state = 0;
+ }
+ destroy_workqueue(ltr558->wq);
+ mutex_destroy(&ltr558->lock);
+ wake_lock_destroy(&ltr558->prx_wake_lock);
+#ifdef CONFIG_HAS_EARLYSUSPEND
+ unregister_early_suspend(&ltr558->early_suspend);
+#endif /* !CONFIG_HAS_EARLYSUSPEND */
+ kfree(ltr558);
+ return 0;
+}
+
+static void ltr558_early_suspend(struct early_suspend *h)
+{
+ struct ltr558_data *ltr558 =
+ container_of(h, struct ltr558_data, early_suspend);
+
+ LTR558_DBGMSG("ltr558_early_suspend.\n");
+
+ if (ltr558->power_state & LIGHT_ENABLED)
+ ltr558_light_disable(ltr558);
+
+ if (ltr558->power_state & PROXIMITY_ENABLED) {
+ enable_irq_wake(ltr558->pdata->int_gpio);
+ }
+}
+
+static void ltr558_late_resume(struct early_suspend *h)
+{
+ /* Turn power back on if we were before suspend. */
+ struct ltr558_data *ltr558 =
+ container_of(h, struct ltr558_data, early_suspend);
+
+ LTR558_DBGMSG("ltr558_late_resume.\n");
+
+ if (ltr558->power_state & PROXIMITY_ENABLED) {
+ disable_irq_wake(ltr558->pdata->int_gpio);
+ }
+ if (ltr558->power_state & LIGHT_ENABLED){
+ ltr558_light_enable(ltr558);
+ }
+}
+
+static const struct i2c_device_id ltr558_device_id[] = {
+ {SENSOR_NAME, 0},
+ {}
+};
+
+MODULE_DEVICE_TABLE(i2c, ltr558_device_id);
+
+static struct i2c_driver ltr558_i2c_driver = {
+ .driver = {
+ .name = SENSOR_NAME,
+ .owner = THIS_MODULE,
+ },
+ .probe = ltr558_i2c_probe,
+ .remove = ltr558_i2c_remove,
+ .id_table = ltr558_device_id,
+};
+
+static int __init ltr558_init(void)
+{
+ return i2c_add_driver(&ltr558_i2c_driver);
+}
+
+static void __exit ltr558_exit(void)
+{
+ i2c_del_driver(&ltr558_i2c_driver);
+}
+
+module_init(ltr558_init);
+module_exit(ltr558_exit);
+
+MODULE_DESCRIPTION("ALP Sensor driver for ltr558");
+MODULE_LICENSE("GPLv2");
diff --git a/drivers/input/misc/tmd2771x.c b/drivers/input/misc/tmd2771x.c
new file mode 100644
index 0000000..a2fff10
--- /dev/null
+++ b/drivers/input/misc/tmd2771x.c
@@ -0,0 +1,1119 @@
+/*
+ * Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/mutex.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/input.h>
+#include <linux/input/tmd2771x.h>
+#include <linux/wakelock.h>
+
+#define TMD2771X_DRV_NAME "tmd2771x"
+#define DRIVER_VERSION "1.0"
+
+#define TMD2771X__POWER_ONOFF(pdata, onoff) \
+ do { \
+ if ((pdata)->power_onoff) { \
+ (pdata)->power_onoff(onoff); \
+ } \
+ } \
+ while(0)
+
+#define TMD2771X__ENABLE_REG 0x00
+#define TMD2771X__ATIME_REG 0x01
+#define TMD2771X__PTIME_REG 0x02
+#define TMD2771X__WTIME_REG 0x03
+#define TMD2771X__AILTL_REG 0x04
+#define TMD2771X_AILTH_REG 0x05
+#define TMD2771X_AIHTL_REG 0x06
+#define TMD2771X_AIHTH_REG 0x07
+#define TMD2771X_PILTL_REG 0x08
+#define TMD2771X_PILTH_REG 0x09
+#define TMD2771X_PIHTL_REG 0x0A
+#define TMD2771X_PIHTH_REG 0x0B
+#define TMD2771X_PERS_REG 0x0C
+#define TMD2771X_CONFIG_REG 0x0D
+#define TMD2771X_PPCOUNT_REG 0x0E
+#define TMD2771X_CONTROL_REG 0x0F
+#define TMD2771X_REV_REG 0x11
+#define TMD2771X_ID_REG 0x12
+#define TMD2771X_STATUS_REG 0x13
+#define TMD2771X_CDATAL_REG 0x14
+#define TMD2771X_CDATAH_REG 0x15
+#define TMD2771X_IRDATAL_REG 0x16
+#define TMD2771X_IRDATAH_REG 0x17
+#define TMD2771X_PDATAL_REG 0x18
+#define TMD2771X_PDATAH_REG 0x19
+
+#define CMD_BYTE 0x80
+#define CMD_WORD 0xA0
+#define CMD_SPECIAL 0xE0
+
+#define CMD_CLR_PS_INT 0xE5
+#define CMD_CLR_ALS_INT 0xE6
+#define CMD_CLR_PS_ALS_INT 0xE7
+
+/*
+ * Structs
+ */
+
+struct tmd2771x_data {
+ //put the platform special resource in platform code
+ struct tmd2771x_platform_data *pdata;
+ struct i2c_client *client;
+ struct mutex update_lock;
+ //use a dedicated spinlock instead of dwork.wait_lock
+ spinlock_t wq_lock;
+ struct delayed_work dwork; /* for PS interrupt */
+ struct delayed_work als_dwork; /* for ALS polling */
+ struct input_dev *input_dev_als;
+ struct input_dev *input_dev_ps;
+ struct wake_lock prx_wake_lock;
+
+ unsigned int enable;
+ unsigned int atime;
+ unsigned int ptime;
+ unsigned int wtime;
+ unsigned int ailt;
+ unsigned int aiht;
+ unsigned int pilt;
+ unsigned int piht;
+ unsigned int pers;
+ unsigned int config;
+ unsigned int ppcount;
+ unsigned int control;
+
+ /* control flag from HAL */
+ unsigned int enable_ps_sensor;
+ unsigned int enable_als_sensor;
+
+ /* PS parameters */
+ unsigned int ps_threshold;
+ unsigned int ps_hysteresis_threshold; /* always lower than ps_threshold */
+ unsigned int ps_detection; /* 1 = near-to-far; 0 = far-to-near */
+ unsigned int ps_data; /* to store PS data */
+
+ /* ALS parameters */
+ unsigned int als_threshold_l; /* low threshold */
+ unsigned int als_threshold_h; /* high threshold */
+ unsigned int als_data; /* to store ALS data */
+
+ unsigned int als_gain; /* needed for Lux calculation */
+ unsigned int als_poll_delay; /* needed for light sensor polling : micro-second (us) */
+ unsigned int als_atime; /* storage for als integratiion time */
+};
+
+/*
+ * Global data
+ */
+static int light_data;
+static int proximity_data;
+static struct tmd2771x_data *data;
+/*
+ * Management functions
+ */
+
+static int tmd2771x_set_command(struct i2c_client *client, int command)
+{
+ int ret;
+ int clearInt;
+
+ if (command == 0)
+ clearInt = CMD_CLR_PS_INT;
+ else if (command == 1)
+ clearInt = CMD_CLR_ALS_INT;
+ else
+ clearInt = CMD_CLR_PS_ALS_INT;
+
+ //It`s unnecessary to lock mutex before i2c_smbus_write_byte, which is thread-safe and SMP safe.
+ ret = i2c_smbus_write_byte(client, clearInt);
+
+ return ret;
+}
+
+static int tmd2771x_set_enable(struct i2c_client *client, int enable)
+{
+ int ret;
+ //Yes, the mutex is necessary for modify data->data, but I will lock it before call this function
+ ret = i2c_smbus_write_byte_data(client, CMD_BYTE|TMD2771X__ENABLE_REG, enable);
+ data->enable = enable;
+
+ return ret;
+}
+
+static int tmd2771x_set_atime(struct i2c_client *client, int atime)
+{
+ int ret;
+ ret = i2c_smbus_write_byte_data(client, CMD_BYTE|TMD2771X__ATIME_REG, atime);
+ data->atime = atime;
+
+ return ret;
+}
+
+static int tmd2771x_set_ptime(struct i2c_client *client, int ptime)
+{
+ int ret;
+ ret = i2c_smbus_write_byte_data(client, CMD_BYTE|TMD2771X__PTIME_REG, ptime);
+ data->ptime = ptime;
+
+ return ret;
+}
+
+static int tmd2771x_set_wtime(struct i2c_client *client, int wtime)
+{
+ int ret;
+ ret = i2c_smbus_write_byte_data(client, CMD_BYTE|TMD2771X__WTIME_REG, wtime);
+ data->wtime = wtime;
+
+ return ret;
+}
+
+static int tmd2771x_set_ailt(struct i2c_client *client, int threshold)
+{
+ int ret;
+ ret = i2c_smbus_write_word_data(client, CMD_WORD|TMD2771X__AILTL_REG, threshold);
+ data->ailt = threshold;
+
+ return ret;
+}
+
+static int tmd2771x_set_aiht(struct i2c_client *client, int threshold)
+{
+ int ret;
+ ret = i2c_smbus_write_word_data(client, CMD_WORD|TMD2771X_AIHTL_REG, threshold);
+ data->aiht = threshold;
+
+ return ret;
+}
+
+static int tmd2771x_set_pilt(struct i2c_client *client, int threshold)
+{
+ int ret;
+ ret = i2c_smbus_write_word_data(client, CMD_WORD|TMD2771X_PILTL_REG, threshold);
+ data->pilt = threshold;
+
+ return ret;
+}
+
+static int tmd2771x_set_piht(struct i2c_client *client, int threshold)
+{
+ int ret;
+ ret = i2c_smbus_write_word_data(client, CMD_WORD|TMD2771X_PIHTL_REG, threshold);
+ data->piht = threshold;
+
+ return ret;
+}
+
+static int tmd2771x_set_pers(struct i2c_client *client, int pers)
+{
+ int ret;
+ ret = i2c_smbus_write_byte_data(client, CMD_BYTE|TMD2771X_PERS_REG, pers);
+ data->pers = pers;
+
+ return ret;
+}
+
+static int tmd2771x_set_config(struct i2c_client *client, int config)
+{
+ int ret;
+ ret = i2c_smbus_write_byte_data(client, CMD_BYTE|TMD2771X_CONFIG_REG, config);
+ data->config = config;
+
+ return ret;
+}
+
+static int tmd2771x_set_ppcount(struct i2c_client *client, int ppcount)
+{
+ int ret;
+ ret = i2c_smbus_write_byte_data(client, CMD_BYTE|TMD2771X_PPCOUNT_REG, ppcount);
+ data->ppcount = ppcount;
+
+ return ret;
+}
+
+static int tmd2771x_set_control(struct i2c_client *client, int control)
+{
+ int ret;
+ ret = i2c_smbus_write_byte_data(client, CMD_BYTE|TMD2771X_CONTROL_REG, control);
+ data->control = control;
+
+ /* obtain ALS gain value */
+ if ((control&0x03) == 0x00) /* 1X Gain */
+ data->als_gain = 1;
+ else if ((control&0x03) == 0x01) /* 8X Gain */
+ data->als_gain = 8;
+ else if ((control&0x03) == 0x02) /* 16X Gain */
+ data->als_gain = 16;
+ else /* 120X Gain */
+ data->als_gain = 120;
+
+ return ret;
+}
+
+static int LuxCalculation(struct i2c_client *client, int cdata, int irdata)
+{
+ int luxValue=0;
+
+ int IAC1=0;
+ int IAC2=0;
+ int IAC=0;
+ int GA=1064; /* 0.48 without glass window */
+ int COE_B=210; /* 2.23 without glass window */
+ int COE_C=29; /* 0.70 without glass window */
+ int COE_D=57; /* 1.42 without glass window */
+ int DF=52;
+
+ IAC1 = (cdata - (COE_B*irdata)/100); // re-adjust COE_B to avoid 2 decimal point
+ IAC2 = ((COE_C*cdata)/100 - (COE_D*irdata)/100); // re-adjust COE_C and COE_D to void 2 decimal point
+
+ if (IAC1 > IAC2)
+ IAC = IAC1;
+ else if (IAC1 <= IAC2)
+ IAC = IAC2;
+ else
+ IAC = 0;
+
+ luxValue = ((IAC*GA*DF)/100)/(((272*(256-data->atime))/100)*data->als_gain);
+
+ return luxValue;
+}
+
+static void tmd2771x_change_ps_threshold(struct i2c_client *client)
+{
+ int retval;
+
+ retval = i2c_smbus_read_word_data(client, CMD_WORD|TMD2771X_PDATAL_REG);
+ if (retval < 0)
+ return;
+
+ proximity_data = retval;
+ data->ps_data = retval;
+ if ( (data->ps_data > data->pilt) && (data->ps_data >= data->piht) ) {
+ /* far-to-near detected */
+ data->ps_detection = 1;
+
+ input_report_abs(data->input_dev_ps, ABS_DISTANCE, 0);/* FAR-to-NEAR detection */
+ input_sync(data->input_dev_ps);
+
+ i2c_smbus_write_word_data(client, CMD_WORD|TMD2771X_PILTL_REG, data->ps_hysteresis_threshold);
+ i2c_smbus_write_word_data(client, CMD_WORD|TMD2771X_PIHTL_REG, 1023);
+
+ data->pilt = data->ps_hysteresis_threshold;
+ data->piht = 1023;
+ printk("far-to-near detected\n");
+ }
+ else if ( (data->ps_data <= data->pilt) && (data->ps_data < data->piht) ) {
+ /* near-to-far detected */
+ data->ps_detection = 0;
+
+ input_report_abs(data->input_dev_ps, ABS_DISTANCE, 1);/* NEAR-to-FAR detection */
+ input_sync(data->input_dev_ps);
+
+ i2c_smbus_write_word_data(client, CMD_WORD|TMD2771X_PILTL_REG, 0);
+ i2c_smbus_write_word_data(client, CMD_WORD|TMD2771X_PIHTL_REG, data->ps_threshold);
+
+ data->pilt = 0;
+ data->piht = data->ps_threshold;
+
+ printk("near-to-far detected\n");
+ } else {
+ printk("data->ps_data = %d, data->pilt = %d, data->piht = %d\n", data->ps_data, data->pilt, data->piht);
+ }
+}
+
+static void tmd2771x_change_als_threshold(struct i2c_client *client)
+{
+ int cdata, irdata;
+ int luxValue=0;
+
+ cdata = i2c_smbus_read_word_data(client, CMD_WORD|TMD2771X_CDATAL_REG);
+ irdata = i2c_smbus_read_word_data(client, CMD_WORD|TMD2771X_IRDATAL_REG);
+
+ luxValue = LuxCalculation(client, cdata, irdata);
+
+ luxValue = luxValue>0 ? luxValue : 0;
+ luxValue = luxValue<10000 ? luxValue : 10000;
+ light_data = luxValue;
+ // check PS under sunlight
+ if ( (data->ps_detection == 1) && (cdata > (75*(1024*(256-data->atime)))/100)) // PS was previously in far-to-near condition
+ {
+ // need to inform input event as there will be no interrupt from the PS
+ input_report_abs(data->input_dev_ps, ABS_DISTANCE, 1);/* NEAR-to-FAR detection */
+ input_sync(data->input_dev_ps);
+
+ i2c_smbus_write_word_data(client, CMD_WORD|TMD2771X_PILTL_REG, 0);
+ i2c_smbus_write_word_data(client, CMD_WORD|TMD2771X_PIHTL_REG, data->ps_threshold);
+
+ data->pilt = 0;
+ data->piht = data->ps_threshold;
+
+ data->ps_detection = 0; /* near-to-far detected */
+
+ printk("tmd2771x_proximity_handler = FAR\n");
+ }
+
+ input_report_abs(data->input_dev_als, ABS_MISC, luxValue); // report the lux level
+ input_sync(data->input_dev_als);
+
+ data->als_data = cdata;
+ data->als_threshold_l = (data->als_data * (100-data->pdata->als_hsyt_thld) ) /100;
+ data->als_threshold_h = (data->als_data * (100+data->pdata->als_hsyt_thld) ) /100;
+
+ if (data->als_threshold_h >= 65535) data->als_threshold_h = 65535;
+
+ i2c_smbus_write_word_data(client, CMD_WORD|TMD2771X__AILTL_REG, data->als_threshold_l);
+ i2c_smbus_write_word_data(client, CMD_WORD|TMD2771X_AIHTL_REG, data->als_threshold_h);
+}
+
+/* ALS polling routine */
+static void tmd2771x_als_polling_work_handler(struct work_struct *work)
+{
+ struct i2c_client *client=data->client;
+ int cdata, irdata, pdata;
+ int luxValue=0;
+
+ //1. work queue is reentrant in SMP.
+ //2. serveral function here calls need mutex.
+ mutex_lock(&data->update_lock);
+ cdata = i2c_smbus_read_word_data(client, CMD_WORD|TMD2771X_CDATAL_REG);
+ irdata = i2c_smbus_read_word_data(client, CMD_WORD|TMD2771X_IRDATAL_REG);
+ pdata = i2c_smbus_read_word_data(client, CMD_WORD|TMD2771X_PDATAL_REG);
+
+ if ((cdata < 0) || (irdata < 0) || (pdata < 0)) {
+ mutex_unlock(&data->update_lock);
+ return;
+ }
+
+ luxValue = LuxCalculation(client, cdata, irdata);
+ luxValue = luxValue>0 ? luxValue : 0;
+ luxValue = luxValue<10000 ? luxValue : 10000;
+ light_data = luxValue;
+ //printk("%s: lux = %d cdata = %x irdata = %x pdata = %x \n", __func__, luxValue, cdata, irdata, pdata);
+ // check PS under sunlight
+ if ( (data->ps_detection == 1) && (cdata > (75*(1024*(256-data->atime)))/100)) // PS was previously in far-to-near condition
+ {
+ // need to inform input event as there will be no interrupt from the PS
+ input_report_abs(data->input_dev_ps, ABS_DISTANCE, 1);/* NEAR-to-FAR detection */
+ input_sync(data->input_dev_ps);
+
+ i2c_smbus_write_word_data(client, CMD_WORD|TMD2771X_PILTL_REG, 0);
+ i2c_smbus_write_word_data(client, CMD_WORD|TMD2771X_PIHTL_REG, data->ps_threshold);
+
+ data->pilt = 0;
+ data->piht = data->ps_threshold;
+
+ data->ps_detection = 0; /* near-to-far detected */
+
+ printk("tmd2771x_proximity_handler = FAR\n");
+ }
+
+ input_report_abs(data->input_dev_als, ABS_MISC, luxValue); // report the lux level
+ input_sync(data->input_dev_als);
+
+ schedule_delayed_work(&data->als_dwork, msecs_to_jiffies(data->als_poll_delay)); // restart timer
+ mutex_unlock(&data->update_lock);
+}
+
+/* PS interrupt routine */
+static void tmd2771x_work_handler(struct work_struct *work)
+{
+ struct i2c_client *client=data->client;
+ int status;
+ int cdata;
+ int retry_count = 3;
+
+retry:
+ status = i2c_smbus_read_byte_data(client, CMD_BYTE|TMD2771X_STATUS_REG);
+ if (status < 0) {
+ printk("fail to read data,status = %x\n", status);
+ if (retry_count--) {
+ usleep(50000);
+ goto retry;
+ } else {
+ return;
+ }
+ }
+
+ i2c_smbus_write_byte_data(client, CMD_BYTE|TMD2771X__ENABLE_REG, 1); /* disable 2771x's ADC first */
+
+ printk("status = %x, enable = %x\n", status, data->enable);
+ //Interrupt is not reentrant both in UP and MP. But some variant/function here need to thread-safe.
+ mutex_lock(&data->update_lock);
+
+ if ((status & data->enable & 0x30) == 0x30) {
+ /* both PS and ALS are interrupted */
+ tmd2771x_change_als_threshold(client);
+
+ cdata = i2c_smbus_read_word_data(client, CMD_WORD|TMD2771X_CDATAL_REG);
+ if (cdata < (75*(1024*(256-data->atime)))/100)
+ tmd2771x_change_ps_threshold(client);
+ else {
+ if (data->ps_detection == 1) {
+ tmd2771x_change_ps_threshold(client);
+ }
+ else {
+ printk("Triggered by background ambient noise\n");
+ }
+ }
+
+ tmd2771x_set_command(client, 2); /* 2 = CMD_CLR_PS_ALS_INT */
+ }
+ else if ((status & data->enable & 0x20) == 0x20) {
+ /* only PS is interrupted */
+ /* check if this is triggered by background ambient noise */
+ cdata = i2c_smbus_read_word_data(client, CMD_WORD|TMD2771X_CDATAL_REG);
+ if (cdata < (75*(1024*(256-data->atime)))/100)
+ tmd2771x_change_ps_threshold(client);
+ else {
+ if (data->ps_detection == 1) {
+ tmd2771x_change_ps_threshold(client);
+ }
+ else {
+ printk("Triggered by background ambient noise\n");
+ }
+ }
+
+ tmd2771x_set_command(client, 0); /* 0 = CMD_CLR_PS_INT */
+ }
+ else if ((status & data->enable & 0x10) == 0x10) {
+ /* only ALS is interrupted */
+ tmd2771x_change_als_threshold(client);
+ tmd2771x_set_command(client, 1); /* 1 = CMD_CLR_ALS_INT */
+ }
+ i2c_smbus_write_byte_data(client, CMD_BYTE|TMD2771X__ENABLE_REG, data->enable);
+ mutex_unlock(&data->update_lock);
+}
+
+/* assume this is ISR */
+static irqreturn_t tmd2771x_interrupt(int vec, void *info)
+{
+ struct i2c_client *client=(struct i2c_client *)info;
+ data = i2c_get_clientdata(client);
+ printk("==> tmd2771x_interrupt (timeout)\n");
+ wake_lock_timeout(&data->prx_wake_lock, HZ / 2);
+ //Seems linux-3.0 trends to use threaded-interrupt, so we can call the work directly.
+ tmd2771x_work_handler(&data->dwork.work);
+
+ return IRQ_HANDLED;
+}
+
+/*
+ * SysFS support
+ */
+static ssize_t tmd2771x_show_ps_sensor_thld(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ return sprintf(buf, "%d %d\n", data->pdata->ps_hsyt_thld, data->pdata->ps_det_thld);
+}
+
+static ssize_t tmd2771x_store_ps_sensor_thld(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ char *next_buf;
+ unsigned long hsyt_val = simple_strtoul(buf, &next_buf, 10);
+ unsigned long det_val = simple_strtoul(++next_buf, NULL, 10);
+
+ if ((det_val < 0) || (det_val > 1023) || (hsyt_val < 0) || (hsyt_val >= det_val)) {
+ printk("%s:store unvalid det_val=%ld, hsyt_val=%ld\n", __func__, det_val, hsyt_val);
+ return -EINVAL;
+ }
+ mutex_lock(&data->update_lock);
+ data->pdata->ps_det_thld = det_val;
+ data->pdata->ps_hsyt_thld = hsyt_val;
+ mutex_unlock(&data->update_lock);
+
+ return count;
+}
+
+static DEVICE_ATTR(ps_sensor_thld, S_IWUGO | S_IRUGO,
+ tmd2771x_show_ps_sensor_thld, tmd2771x_store_ps_sensor_thld);
+
+static ssize_t tmd2771x_show_proximity_enable(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ return sprintf(buf, "%d\n", data->enable_ps_sensor);
+}
+
+static ssize_t tmd2771x_store_proximity_enable(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ struct i2c_client *client = data->client;
+ unsigned long val = simple_strtoul(buf, NULL, 10);
+ unsigned long flags;
+ printk("%s: enable ps senosr ( %ld)\n", __func__, val);
+
+ if ((val != 0) && (val != 1)) {
+ printk("%s:store unvalid value=%ld\n", __func__, val);
+ return count;
+ }
+ //some variant/function here need to thread-safe. And it`s better to finish all the steps in one time.
+ mutex_lock(&data->update_lock);
+
+ if(val == 1) {
+ //turn on p sensor
+ if (data->enable_ps_sensor==0) {
+ data->enable_ps_sensor= 1;
+ tmd2771x_set_enable(client,0); /* Power Off */
+ tmd2771x_set_atime(client, 0xf6); /* 27.2ms */
+ tmd2771x_set_ptime(client, 0xff); /* 2.72ms */
+ tmd2771x_set_ppcount(client, 8); /* 8-pulse */
+ tmd2771x_set_control(client, 0x60); /* 100mA, IR-diode, 1X PGAIN, 1X AGAIN */
+ tmd2771x_set_pilt(client, 0); // init threshold for proximity
+ tmd2771x_set_piht(client, data->pdata->ps_det_thld);
+ data->ps_threshold = data->pdata->ps_det_thld;
+ data->ps_hysteresis_threshold = data->pdata->ps_hsyt_thld;
+ tmd2771x_set_ailt( client, 0);
+ tmd2771x_set_aiht( client, 0xffff);
+ tmd2771x_set_pers(client, 0x33); /* 3 persistence */
+
+ if (data->enable_als_sensor==0) {
+
+ /* we need this polling timer routine for sunlight canellation */
+ spin_lock_irqsave(&data->wq_lock, flags);
+
+ /*
+ * If work is already scheduled then subsequent schedules will not
+ * change the scheduled time that's why we have to cancel it first.
+ */
+ __cancel_delayed_work(&data->als_dwork);
+ schedule_delayed_work(&data->als_dwork, msecs_to_jiffies(data->als_poll_delay)); // 100ms
+
+ spin_unlock_irqrestore(&data->wq_lock, flags);
+ }
+ tmd2771x_set_enable(client, 0x27); /* only enable PS interrupt */
+ }
+ }
+ else {
+ //turn off p sensor - kk 25 Apr 2011 we can't turn off the entire sensor, the light sensor may be needed by HAL
+ data->enable_ps_sensor = 0;
+ if (data->enable_als_sensor) {
+ // reconfigute light sensor setting
+ tmd2771x_set_enable(client,0); /* Power Off */
+ tmd2771x_set_atime(client, data->als_atime); /* previous als poll delay */
+ tmd2771x_set_ailt( client, 0);
+ tmd2771x_set_aiht( client, 0xffff);
+ tmd2771x_set_control(client, 0x60); /* 100mA, IR-diode, 1X PGAIN, 1X AGAIN */
+ tmd2771x_set_pers(client, 0x33); /* 3 persistence */
+ tmd2771x_set_enable(client, 0x3); /* only enable light sensor */
+ /*
+ * If work is already scheduled then subsequent schedules will not
+ * change the scheduled time that's why we have to cancel it first.
+ */
+ spin_lock_irqsave(&data->wq_lock, flags);
+
+ __cancel_delayed_work(&data->als_dwork);
+ schedule_delayed_work(&data->als_dwork, msecs_to_jiffies(data->als_poll_delay)); // 100ms
+
+ spin_unlock_irqrestore(&data->wq_lock, flags);
+ }
+ else {
+ tmd2771x_set_enable(client, 0);
+ /*
+ * If work is already scheduled then subsequent schedules will not
+ * change the scheduled time that's why we have to cancel it first.
+ */
+ spin_lock_irqsave(&data->wq_lock, flags);
+
+ __cancel_delayed_work(&data->als_dwork);
+
+ spin_unlock_irqrestore(&data->wq_lock, flags);
+ }
+ }
+
+ mutex_unlock(&data->update_lock);
+
+ return count;
+}
+
+static struct device_attribute dev_attr_proximity_enable = __ATTR(enable, S_IWUSR | S_IWGRP | S_IRUGO,
+ tmd2771x_show_proximity_enable, tmd2771x_store_proximity_enable);
+
+static ssize_t tmd2771x_show_light_enable(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ return sprintf(buf, "%d\n", data->enable_als_sensor);
+}
+
+static ssize_t tmd2771x_store_light_enable(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ struct i2c_client *client = data->client;
+ unsigned long val = simple_strtoul(buf, NULL, 10);
+ unsigned long flags;
+
+ printk("%s: enable als sensor ( %ld)\n", __func__, val);
+
+ if ((val != 0) && (val != 1))
+ {
+ printk("%s: enable als sensor=%ld\n", __func__, val);
+ return count;
+ }
+
+ mutex_lock(&data->update_lock);
+
+ if(val == 1) {
+ //turn on light sensor
+ if (data->enable_als_sensor==0) {
+ data->enable_als_sensor = 1;
+ tmd2771x_set_enable(client,0); /* Power Off */
+ tmd2771x_set_atime(client, data->als_atime); /* 100.64ms */
+ tmd2771x_set_ailt( client, 0);
+ tmd2771x_set_aiht( client, 0xffff);
+ tmd2771x_set_control(client, 0x60); /* 100mA, IR-diode, 1X PGAIN, 1X AGAIN */
+ tmd2771x_set_pers(client, 0x33); /* 3 persistence */
+
+ if (data->enable_ps_sensor) {
+ tmd2771x_set_ptime(client, 0xff); /* 2.72ms */
+ tmd2771x_set_ppcount(client, 8); /* 8-pulse */
+ tmd2771x_set_enable(client, 0x27); /* if prox sensor was activated previously */
+ }
+ else {
+ tmd2771x_set_enable(client, 0x3); /* only enable light sensor */
+ }
+ /*
+ * If work is already scheduled then subsequent schedules will not
+ * change the scheduled time that's why we have to cancel it first.
+ */
+ spin_lock_irqsave(&data->wq_lock, flags);
+
+ __cancel_delayed_work(&data->als_dwork);
+ schedule_delayed_work(&data->als_dwork, msecs_to_jiffies(data->als_poll_delay));
+
+ spin_unlock_irqrestore(&data->wq_lock, flags);
+ }
+ }
+ else {
+ if (data->enable_als_sensor==1) {
+ data->enable_als_sensor = 0;
+ if (data->enable_ps_sensor) {
+ tmd2771x_set_enable(client,0); /* Power Off */
+ tmd2771x_set_atime(client, 0xf6); /* 27.2ms */
+ tmd2771x_set_ptime(client, 0xff); /* 2.72ms */
+ tmd2771x_set_ppcount(client, 8); /* 8-pulse */
+ tmd2771x_set_control(client, 0x60); /* 100mA, IR-diode, 1X PGAIN, 1X AGAIN */
+ tmd2771x_set_piht(client, 0);
+ tmd2771x_set_piht(client, data->pdata->ps_det_thld);
+ tmd2771x_set_ailt( client, 0);
+ tmd2771x_set_aiht( client, 0xffff);
+ tmd2771x_set_pers(client, 0x33); /* 3 persistence */
+ tmd2771x_set_enable(client, 0x27); /* only enable prox sensor with interrupt */
+ }
+ else {
+ tmd2771x_set_enable(client, 0);
+ }
+
+ /*
+ * If work is already scheduled then subsequent schedules will not
+ * change the scheduled time that's why we have to cancel it first.
+ */
+ spin_lock_irqsave(&data->wq_lock, flags);
+
+ __cancel_delayed_work(&data->als_dwork);
+
+ spin_unlock_irqrestore(&data->wq_lock, flags);
+ }
+ }
+ mutex_unlock(&data->update_lock);
+
+ return count;
+}
+
+static struct device_attribute dev_attr_light_enable = __ATTR(enable, S_IWUSR | S_IWGRP | S_IRUGO,
+ tmd2771x_show_light_enable, tmd2771x_store_light_enable);
+
+static ssize_t tmd2771x_show_als_poll_delay(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ return sprintf(buf, "%d\n", data->als_poll_delay*1000); // return in micro-second
+}
+
+static ssize_t tmd2771x_store_als_poll_delay(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ struct i2c_client *client = data->client;
+ unsigned long val = simple_strtoul(buf, NULL, 10);
+ int ret;
+ int poll_delay=0;
+ unsigned long flags;
+
+ if (val<5000)
+ val = 5000; // minimum 5ms
+
+ mutex_lock(&data->update_lock);
+ data->als_poll_delay = val/1000; // convert us => ms
+
+ poll_delay = 256 - (val/2720); // the minimum is 2.72ms = 2720 us, maximum is 696.32ms
+ if (poll_delay >= 256)
+ data->als_atime = 255;
+ else if (poll_delay < 0)
+ data->als_atime = 0;
+ else
+ data->als_atime = poll_delay;
+ ret = tmd2771x_set_atime(client, data->als_atime);
+
+ if (ret < 0)
+ return ret;
+
+ /* we need this polling timer routine for sunlight canellation */
+ /*
+ * If work is already scheduled then subsequent schedules will not
+ * change the scheduled time that's why we have to cancel it first.
+ */
+ spin_lock_irqsave(&data->wq_lock, flags);
+
+ __cancel_delayed_work(&data->als_dwork);
+ schedule_delayed_work(&data->als_dwork, msecs_to_jiffies(data->als_poll_delay)); // 100ms
+
+ spin_unlock_irqrestore(&data->wq_lock, flags);
+
+ mutex_unlock(&data->update_lock);
+
+ return count;
+}
+
+static DEVICE_ATTR(als_poll_delay, S_IWUSR | S_IWGRP | S_IRUGO,
+ tmd2771x_show_als_poll_delay, tmd2771x_store_als_poll_delay);
+
+static struct attribute *tmd2771x_proximity_attributes[] = {
+ &dev_attr_proximity_enable.attr,
+ &dev_attr_ps_sensor_thld.attr,
+ NULL
+};
+
+static struct attribute *tmd2771x_light_attributes[] = {
+ &dev_attr_light_enable.attr,
+ &dev_attr_als_poll_delay.attr,
+ NULL
+};
+
+static const struct attribute_group tmd2771x_ps_attr_group = {
+ .attrs = tmd2771x_proximity_attributes,
+};
+
+static const struct attribute_group tmd2771x_als_attr_group = {
+ .attrs = tmd2771x_light_attributes,
+};
+/*
+ * Initialization function
+ */
+
+static int tmd2771x_init_client(struct i2c_client *client)
+{
+ int err;
+ int id;
+
+ err = tmd2771x_set_enable(client, 0);
+
+ if (err < 0)
+ return err;
+
+ id = i2c_smbus_read_byte_data(client, CMD_BYTE|TMD2771X_ID_REG);
+ if (id == 0x20) {
+ printk("TMD27711\n");
+ }
+ else if (id == 0x29) {
+ printk("TMD27713\n");
+ }
+ else {
+ printk("Neither TMD27711 nor TMD27713\n");
+ return -EIO;
+ }
+
+ tmd2771x_set_atime(client, 0xDB); // 100.64ms ALS integration time
+ tmd2771x_set_ptime(client, 0xFF); // 2.72ms Prox integration time
+ tmd2771x_set_wtime(client, 0xFF); // 2.72ms Wait time
+
+ tmd2771x_set_ppcount(client, 0x08); // 8-Pulse for proximity
+ tmd2771x_set_config(client, 0); // no long wait
+ tmd2771x_set_control(client, 0x60); // 100mA, IR-diode, 1X PGAIN, 1X AGAIN
+
+ tmd2771x_set_pilt(client, 0); // init threshold for proximity
+ tmd2771x_set_piht(client, data->pdata->ps_det_thld);
+
+ data->ps_threshold = data->pdata->ps_det_thld;
+ data->ps_hysteresis_threshold = data->pdata->ps_hsyt_thld;
+
+ tmd2771x_set_ailt(client, 0); // init threshold for als
+ tmd2771x_set_aiht(client, 0xFFFF);
+
+ tmd2771x_set_pers(client, 0x22); // 2 consecutive Interrupt persistence
+
+ // sensor is in disabled mode but all the configurations are preset
+
+ return 0;
+}
+
+/*
+ * I2C init/probing/exit functions
+ */
+
+static struct i2c_driver tmd2771x_driver;
+static int __devinit tmd2771x_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
+ int err = 0;
+ struct tmd2771x_platform_data *pdata = client->dev.platform_data;
+ struct input_dev *input_dev;
+ if (!pdata || (pdata->irq <= 0)) {
+ pr_err("%s: platform resource is no enough!\n", __func__);
+ return -ENODEV;
+ }
+
+ if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE)) {
+ err = -EIO;
+ goto exit;
+ }
+
+ data = kzalloc(sizeof(struct tmd2771x_data), GFP_KERNEL);
+ if (!data) {
+ err = -ENOMEM;
+ goto exit;
+ }
+ data->pdata = pdata;
+ data->client = client;
+ i2c_set_clientdata(client, data);
+
+ data->enable = 0; /* default mode is standard */
+ data->ps_threshold = 0;
+ data->ps_hysteresis_threshold = 0;
+ data->ps_detection = 0; /* default to no detection */
+ data->enable_als_sensor = 0; // default to 0
+ data->enable_ps_sensor = 0; // default to 0
+ data->als_poll_delay = 100; // default to 100ms
+ data->als_atime = 0xdb; // work in conjuction with als_poll_delay
+
+ printk("enable = %x\n", data->enable);
+
+ mutex_init(&data->update_lock);
+ spin_lock_init(&data->wq_lock);
+
+ wake_lock_init(&data->prx_wake_lock, WAKE_LOCK_SUSPEND,
+ "prx_wake_lock");
+
+ printk("%s interrupt is hooked\n", __func__);
+
+ /* proximity */
+ input_dev = input_allocate_device();
+ if (input_dev == NULL) {
+ err = -ENOMEM;
+ printk( "proximity input device allocate failed\n");
+ goto exit_kfree;
+ }
+
+ input_set_drvdata(input_dev, data);
+ input_dev->name = "proximity";
+ input_set_capability(input_dev, EV_ABS, ABS_DISTANCE);
+ input_set_abs_params(input_dev, ABS_DISTANCE, 0, 1, 0, 0);
+ data->input_dev_ps = input_dev;
+
+ err = input_register_device(input_dev);
+ if (err) {
+ err = -ENOMEM;
+ printk("Unable to register input device ps: %s\n",
+ input_dev->name);
+ goto exit_free_ps_dev;
+ }
+
+ err = sysfs_create_group(&input_dev->dev.kobj,
+ &tmd2771x_ps_attr_group);
+ if (err) {
+ pr_err("%s: could not create sysfs group\n", __func__);
+ goto exit_unregister_ps_dev;
+ }
+
+ /* light */
+ input_dev = input_allocate_device();
+ if (input_dev == NULL) {
+ err = -ENOMEM;
+ printk("light input device allocate failed\n");
+ goto exit_remove_ps_sysfs;
+ }
+ input_set_drvdata(input_dev, data);
+ input_dev->name = "light";
+ input_set_capability(input_dev, EV_ABS, ABS_MISC);
+ input_set_abs_params(input_dev, ABS_MISC, 0, 1, 0, 0);
+ data->input_dev_als = input_dev;
+
+ err = input_register_device(input_dev);
+ if (err) {
+ err = -ENOMEM;
+ printk("Unable to register input device als: %s\n",
+ input_dev->name);
+ goto exit_free_als_dev;
+ }
+ err = sysfs_create_group(&input_dev->dev.kobj,
+ &tmd2771x_als_attr_group);
+ if (err) {
+ pr_err("%s: could not create sysfs group\n", __func__);
+ goto exit_unregister_als_dev;
+ }
+ INIT_DELAYED_WORK(&data->dwork, tmd2771x_work_handler);
+ INIT_DELAYED_WORK(&data->als_dwork, tmd2771x_als_polling_work_handler);
+ /* Initialize the tmd2771x chip */
+ err = tmd2771x_init_client(client);
+ if (err)
+ goto exit_remove_als_sysfs;
+
+ err = request_threaded_irq(data->pdata->irq, NULL, tmd2771x_interrupt, IRQ_TYPE_EDGE_FALLING,
+ TMD2771X_DRV_NAME, (void *)client);
+ if (err) {
+ printk("%s Could not allocate irq(%d) !\n", __func__, data->pdata->irq);
+ goto exit_remove_als_sysfs;
+ }
+
+ device_init_wakeup(&client->dev, 1);
+ printk("%s support ver. %s enabled\n", __func__, DRIVER_VERSION);
+
+ return 0;
+
+exit_remove_als_sysfs:
+ sysfs_remove_group(&(data->input_dev_als)->dev.kobj,
+ &tmd2771x_als_attr_group);
+exit_unregister_als_dev:
+ input_unregister_device(data->input_dev_als);
+exit_free_als_dev:
+ input_free_device(data->input_dev_als);
+exit_remove_ps_sysfs:
+ sysfs_remove_group(&(data->input_dev_ps)->dev.kobj,
+ &tmd2771x_ps_attr_group);
+exit_unregister_ps_dev:
+ input_unregister_device(data->input_dev_ps);
+exit_free_ps_dev:
+ input_free_device(data->input_dev_ps);
+exit_kfree:
+ wake_lock_destroy(&data->prx_wake_lock);
+ kfree(data);
+exit:
+ return err;
+}
+
+static int __devexit tmd2771x_remove(struct i2c_client *client)
+{
+ disable_irq(data->pdata->irq);
+ device_init_wakeup(&client->dev, 0);
+ cancel_delayed_work_sync(&data->als_dwork);
+ /* Power down the device */
+ tmd2771x_set_enable(client, 0);
+
+ sysfs_remove_group(&(data->input_dev_als)->dev.kobj,
+ &tmd2771x_als_attr_group);
+ sysfs_remove_group(&(data->input_dev_ps)->dev.kobj,
+ &tmd2771x_ps_attr_group);
+
+ input_unregister_device(data->input_dev_als);
+ input_unregister_device(data->input_dev_ps);
+
+ input_free_device(data->input_dev_als);
+ input_free_device(data->input_dev_ps);
+
+ free_irq(data->pdata->irq, client);
+
+ wake_lock_destroy(&data->prx_wake_lock);
+ kfree(data);
+
+ return 0;
+}
+
+#ifdef CONFIG_PM
+
+static int tmd2771x_suspend(struct i2c_client *client, pm_message_t mesg)
+{
+ int enable = 0;
+
+ disable_irq(data->pdata->irq);
+ if (data->enable_als_sensor)
+ cancel_delayed_work_sync(&data->als_dwork);
+
+ if (data->enable_ps_sensor) {
+ enable = 0x27;
+ enable_irq_wake(data->pdata->irq);
+ }
+
+ if (enable != data->enable)
+ tmd2771x_set_enable(client, enable);
+
+ return 0;
+}
+
+static int tmd2771x_resume(struct i2c_client *client)
+{
+ int enable = 0;
+
+ if (data->enable_als_sensor)
+ enable |= 0x03;
+
+ if (data->enable_ps_sensor) {
+ enable |= 0x27;
+ disable_irq_wake(data->pdata->irq);
+ }
+
+ if (enable != 0x27)
+ tmd2771x_set_enable(client, enable);
+
+ if (data->enable_als_sensor)
+ schedule_delayed_work(&data->als_dwork, msecs_to_jiffies(data->als_poll_delay));
+
+ enable_irq(data->pdata->irq);
+
+ return 0;
+}
+
+#else
+
+#define tmd2771x_suspend NULL
+#define tmd2771x_resume NULL
+
+#endif /* CONFIG_PM */
+
+static const struct i2c_device_id tmd2771x_id[] = {
+ { "tmd2771x", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, tmd2771x_id);
+
+static struct i2c_driver tmd2771x_driver = {
+ .driver = {
+ .name = TMD2771X_DRV_NAME,
+ .owner = THIS_MODULE,
+ },
+ .suspend = tmd2771x_suspend,
+ .resume = tmd2771x_resume,
+ .probe = tmd2771x_probe,
+ .remove = __devexit_p(tmd2771x_remove),
+ .id_table = tmd2771x_id,
+};
+
+static int __init tmd2771x_init(void)
+{
+ return i2c_add_driver(&tmd2771x_driver);
+}
+
+static void __exit tmd2771x_exit(void)
+{
+ i2c_del_driver(&tmd2771x_driver);
+}
+
+MODULE_DESCRIPTION("TAOS tmd2771x ps and als sensor");
+MODULE_LICENSE("GPL v2");
+MODULE_VERSION(DRIVER_VERSION);
+
+module_init(tmd2771x_init);
+module_exit(tmd2771x_exit);
+
diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig
old mode 100644
new mode 100755
index 9f66bb6..2c78fe9
--- a/drivers/input/touchscreen/Kconfig
+++ b/drivers/input/touchscreen/Kconfig
@@ -10,7 +10,18 @@ menuconfig INPUT_TOUCHSCREEN
If unsure, say Y.
if INPUT_TOUCHSCREEN
+config TOUCHSCREEN_FOCAL
+ tristate "focal I2C Touchscreen for wg451v"
+ depends on I2C
+ help
+ Say Y here if you have Atmel mXT series I2C touchscreen,
+ such as FOCAL, connected to your system.
+ If unsure, say N.
+
+ To compile this driver as a module, choose M here: the
+ module will be called focal_ts.
+
config TOUCHSCREEN_88PM860X
tristate "Marvell 88PM860x touchscreen"
depends on MFD_88PM860X
@@ -988,4 +999,15 @@ config TOUCHSCREEN_SYNAPTICS_DSX_FW_UPDATE
To compile this driver as a module, choose M here: the
module will be called synaptics_dsx_fw_update.
+config TOUCHSCREEN_FT6306
+ tristate "ft6306 I2C Touchscreen for normandy"
+ depends on I2C
+ help
+ Say Y here if you have Atmel mXT series I2C touchscreen,
+ such as FT6306, connected to your system.
+
+ If unsure, say N.
+
+ To compile this driver as a module, choose M here: the
+ module will be called ft6306_touch.
endif
diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile
old mode 100644
new mode 100755
index 6ba2167..f9eb477
--- a/drivers/input/touchscreen/Makefile
+++ b/drivers/input/touchscreen/Makefile
@@ -6,6 +6,7 @@
wm97xx-ts-y := wm97xx-core.o
+obj-$(CONFIG_TOUCHSCREEN_FOCAL) += focal_touch.o tp_work_func.o
obj-$(CONFIG_TOUCHSCREEN_88PM860X) += 88pm860x-ts.o
obj-$(CONFIG_TOUCHSCREEN_AD7877) += ad7877.o
obj-$(CONFIG_TOUCHSCREEN_AD7879) += ad7879.o
@@ -76,6 +77,7 @@ obj-$(CONFIG_TOUCHSCREEN_WM97XX_MAINSTONE) += mainstone-wm97xx.o
obj-$(CONFIG_TOUCHSCREEN_WM97XX_ZYLONITE) += zylonite-wm97xx.o
obj-$(CONFIG_TOUCHSCREEN_W90X900) += w90p910_ts.o
obj-$(CONFIG_TOUCHSCREEN_TPS6507X) += tps6507x-ts.o
+obj-$(CONFIG_TOUCHSCREEN_FT5X06) += ft5x06_ts.o
obj-$(CONFIG_TOUCHSCREEN_MSM_LEGACY) += msm_touch.o
obj-$(CONFIG_TOUCHSCREEN_CY8C_TS) += cy8c_ts.o
obj-$(CONFIG_TOUCHSCREEN_CYTTSP_I2C_QC) += cyttsp-i2c-qc.o
@@ -83,3 +85,4 @@ obj-$(CONFIG_TOUCHSCREEN_FT5X06) += ft5x06_ts.o
obj-$(CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4) += synaptics_i2c_rmi4.o
obj-$(CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_RMI4_DEV) += synaptics_rmi_dev.o
obj-$(CONFIG_TOUCHSCREEN_SYNAPTICS_DSX_FW_UPDATE) += synaptics_fw_update.o
+obj-$(CONFIG_TOUCHSCREEN_FT6306) += ft6306_touch.o
diff --git a/drivers/input/touchscreen/atmel_mxt_ts.c b/drivers/input/touchscreen/atmel_mxt_ts.c
index dfb3a05..d637436 100644
--- a/drivers/input/touchscreen/atmel_mxt_ts.c
+++ b/drivers/input/touchscreen/atmel_mxt_ts.c
@@ -38,6 +38,10 @@
#define MXT224E_ID 0x81
#define MXT1386_ID 0xA0
+/* limit to disable T8 */
+#define MXT_X_LIMIT_TO_CLOSE_T8 100
+#define MXT_Y_LIMIT_TO_CLOSE_T8 100
+
/* Version */
#define MXT_VER_20 20
#define MXT_VER_21 21
@@ -50,14 +54,14 @@ struct mxt_address_pair {
};
static const struct mxt_address_pair mxt_slave_addresses[] = {
- { 0x24, 0x4a },
- { 0x25, 0x4b },
- { 0x25, 0x4b },
- { 0x26, 0x4c },
- { 0x27, 0x4d },
- { 0x34, 0x5a },
- { 0x35, 0x5b },
- { 0 },
+ {0x24, 0x4a},
+ {0x25, 0x4b},
+ {0x25, 0x4b},
+ {0x26, 0x4c},
+ {0x27, 0x4d},
+ {0x34, 0x5a},
+ {0x35, 0x5b},
+ {0},
};
enum mxt_device_state { INIT, APPMODE, BOOTLOADER };
@@ -111,6 +115,7 @@ enum mxt_device_state { INIT, APPMODE, BOOTLOADER };
#define MXT_SPT_DIGITIZER_T43 43
#define MXT_SPT_MESSAGECOUNT_T44 44
#define MXT_SPT_CTECONFIG_T46 46
+#define MXT_SPT_REFRELOAD_T64 64
/* MXT_GEN_COMMAND_T6 field */
#define MXT_COMMAND_RESET 0
@@ -119,6 +124,10 @@ enum mxt_device_state { INIT, APPMODE, BOOTLOADER };
#define MXT_COMMAND_REPORTALL 3
#define MXT_COMMAND_DIAGNOSTIC 5
+/* MXT_GEN_COMMAND_T6 message field */
+#define MXT_COMMAND_MSG_CALIBRATE (1 << 4)
+#define MXT_COMMAND_MSG_RESET (1 << 7)
+
/* MXT_GEN_POWER_T7 field */
#define MXT_POWER_IDLEACQINT 0
#define MXT_POWER_ACTVACQINT 1
@@ -132,6 +141,8 @@ enum mxt_device_state { INIT, APPMODE, BOOTLOADER };
#define MXT_ACQUIRE_SYNC 5
#define MXT_ACQUIRE_ATCHCALST 6
#define MXT_ACQUIRE_ATCHCALSTHR 7
+#define MXT_ACQUIRE_ATCHFRCCALTHR 8
+#define MXT_ACQUIRE_ATCHFRCCALRATIO 9
/* MXT_TOUCH_MULT_T9 field */
#define MXT_TOUCH_CTRL 0
@@ -205,9 +216,15 @@ enum mxt_device_state { INIT, APPMODE, BOOTLOADER };
#define MXT_CTE_ACTVGCAFDEPTH 4
#define MXT_CTE_VOLTAGE 5
+/* MXT_PROCI_TOUCHSUPPRESSION_T42 message field */
+#define MXT_TCHSUP_MSG_ACTIVE (1 << 0)
+
#define MXT_VOLTAGE_DEFAULT 2700000
#define MXT_VOLTAGE_STEP 10000
+/* MXT_PROCI_TOUCHSUPPRESSION_T42 config field*/
+#define MXT_TCHSUP_CONFIG_ENABLE 0
+
/* Analog voltage @2.7 V */
#define MXT_VTG_MIN_UV 2700000
#define MXT_VTG_MAX_UV 3300000
@@ -238,6 +255,28 @@ enum mxt_device_state { INIT, APPMODE, BOOTLOADER };
#define MXT_WAKE_TIME 25
+#define MXT_T6_DIAGNOSTIC_CMD_PAGEUP 0x01
+#define MXT_T6_DIAGNOSTIC_CMD_PAGEDOWN 0x02
+#define MXT_T6_DIAGNOSTIC_CMD_DELTAS 0x10
+#define MXT_T6_DIAGNOSTIC_CMD_REF 0x11
+#define MXT_T6_DIAGNOSTIC_CMD_CTE 0x31
+#define MXT_T6_DIAGNOSTIC_CMD_TCH 0xF3
+/* Define for MXT_DEBUG_DIAGNOSTIC_T37 */
+#define MXT_T37_PAGE_SIZE 128
+#define MXT_T37_TCH_FLAG_SIZE 80
+#define MXT_T37_TCH_FLAG_IDX 0
+#define MXT_T37_ATCH_FLAG_IDX 40
+#define MXT_T37_MODE 0
+#define MXT_T37_PAGE 1
+#define MXT_T37_DATA 2 /* n bytes */
+#define MXT_T37_PAGE_NUM0 0
+#define MXT_T37_PAGE_NUM1 1
+#define MXT_T37_PAGE_NUM2 2
+#define MXT_T37_PAGE_NUM3 3
+
+/* Define for MXT_SPT_CTECONFIG_T46 */
+#define MXT_T46_CFG_MODE0_X 18
+
/* Command to unlock bootloader */
#define MXT_UNLOCK_CMD_MSB 0xaa
#define MXT_UNLOCK_CMD_LSB 0xdc
@@ -285,6 +324,11 @@ enum mxt_device_state { INIT, APPMODE, BOOTLOADER };
#define MXT_COORDS_ARR_SIZE 4
+/* anti-touch calibration */
+#define MXT_RECALIB_NEED 0
+#define MXT_RECALIB_NG 1
+#define MXT_RECALIB_DONE 2
+
#define MXT_DEBUGFS_DIR "atmel_mxt_ts"
#define MXT_DEBUGFS_FILE "object"
@@ -298,6 +342,11 @@ struct mxt_info {
u8 object_num;
};
+struct touch_ch {
+ u8 atch_ch;
+ u8 tch_ch;
+};
+
struct mxt_object {
u8 type;
u16 start_address;
@@ -329,9 +378,13 @@ struct mxt_data {
struct input_dev *input_dev;
const struct mxt_platform_data *pdata;
const struct mxt_config_info *config_info;
+ struct workqueue_struct *atmel_wq;
+ struct work_struct work;
+ struct delayed_work delayed_work;
enum mxt_device_state state;
struct mxt_object *object_table;
struct mxt_info info;
+ struct mxt_finger pre_finger[MXT_MAX_FINGER];
struct mxt_finger finger[MXT_MAX_FINGER];
unsigned int irq;
struct regulator *vcc_ana;
@@ -341,6 +394,7 @@ struct mxt_data {
struct early_suspend early_suspend;
#endif
+ u8 t6_reportid;
u8 t7_data[T7_DATA_SIZE];
u16 t7_start_addr;
u32 keyarray_old;
@@ -351,8 +405,14 @@ struct mxt_data {
u8 t15_min_reportid;
u8 t42_max_reportid;
u8 t42_min_reportid;
+ u8 t48_reportid;
+ u8 recal_flag;
+ u8 config_t8[6];
+ u8 config_t42[1];
+ u8 cfg_vendorid[1];
u8 cfg_version[MXT_CFG_VERSION_LEN];
int cfg_version_idx;
+ int cfg_vendorid_idx;
int t38_start_addr;
bool update_cfg;
const char *fw_name;
@@ -360,6 +420,8 @@ struct mxt_data {
static struct dentry *debug_base;
+static void mxt_release_all(struct mxt_data *data);
+
static bool mxt_object_readable(unsigned int type)
{
switch (type) {
@@ -389,6 +451,7 @@ static bool mxt_object_readable(unsigned int type)
case MXT_SPT_USERDATA_T38:
case MXT_SPT_DIGITIZER_T43:
case MXT_SPT_CTECONFIG_T46:
+ case MXT_SPT_REFRELOAD_T64:
case MXT_PROCI_ADAPTIVETHRESHOLD_T55:
return true;
default:
@@ -423,6 +486,7 @@ static bool mxt_object_writable(unsigned int type)
case MXT_SPT_USERDATA_T38:
case MXT_SPT_DIGITIZER_T43:
case MXT_SPT_CTECONFIG_T46:
+ case MXT_SPT_REFRELOAD_T64:
case MXT_PROCI_ADAPTIVETHRESHOLD_T55:
return true;
default:
@@ -430,18 +494,14 @@ static bool mxt_object_writable(unsigned int type)
}
}
-static void mxt_dump_message(struct device *dev,
- struct mxt_message *message)
+static void mxt_dump_message(struct device *dev, struct mxt_message *message)
{
- dev_dbg(dev, "reportid:\t0x%x\n", message->reportid);
- dev_dbg(dev, "message1:\t0x%x\n", message->message[0]);
- dev_dbg(dev, "message2:\t0x%x\n", message->message[1]);
- dev_dbg(dev, "message3:\t0x%x\n", message->message[2]);
- dev_dbg(dev, "message4:\t0x%x\n", message->message[3]);
- dev_dbg(dev, "message5:\t0x%x\n", message->message[4]);
- dev_dbg(dev, "message6:\t0x%x\n", message->message[5]);
- dev_dbg(dev, "message7:\t0x%x\n", message->message[6]);
- dev_dbg(dev, "checksum:\t0x%x\n", message->checksum);
+ dev_dbg(dev, "\t0x%x \t0x%x \t0x%x \t0x%x \t0x%x\n",
+ message->reportid,
+ message->message[0],
+ message->message[1],
+ message->message[2],
+ message->message[3]);
}
static int mxt_switch_to_bootloader_address(struct mxt_data *data)
@@ -454,12 +514,12 @@ static int mxt_switch_to_bootloader_address(struct mxt_data *data)
return -EINVAL;
}
- for (i = 0; mxt_slave_addresses[i].application != 0; i++) {
+ for (i = 0; mxt_slave_addresses[i].application != 0; i++) {
if (mxt_slave_addresses[i].application == client->addr) {
- dev_info(&client->dev, "Changing to bootloader address: "
- "%02x -> %02x",
- client->addr,
- mxt_slave_addresses[i].bootloader);
+ dev_info(&client->dev,
+ "Changing to bootloader address: "
+ "%02x -> %02x", client->addr,
+ mxt_slave_addresses[i].bootloader);
client->addr = mxt_slave_addresses[i].bootloader;
data->state = BOOTLOADER;
@@ -468,7 +528,7 @@ static int mxt_switch_to_bootloader_address(struct mxt_data *data)
}
dev_err(&client->dev, "Address 0x%02x not found in address table",
- client->addr);
+ client->addr);
return -EINVAL;
}
@@ -482,13 +542,13 @@ static int mxt_switch_to_appmode_address(struct mxt_data *data)
return -EINVAL;
}
- for (i = 0; mxt_slave_addresses[i].application != 0; i++) {
+ for (i = 0; mxt_slave_addresses[i].application != 0; i++) {
if (mxt_slave_addresses[i].bootloader == client->addr) {
dev_info(&client->dev,
- "Changing to application mode address: "
- "0x%02x -> 0x%02x",
- client->addr,
- mxt_slave_addresses[i].application);
+ "Changing to application mode address: "
+ "0x%02x -> 0x%02x",
+ client->addr,
+ mxt_slave_addresses[i].application);
client->addr = mxt_slave_addresses[i].application;
data->state = APPMODE;
@@ -497,7 +557,7 @@ static int mxt_switch_to_appmode_address(struct mxt_data *data)
}
dev_err(&client->dev, "Address 0x%02x not found in address table",
- client->addr);
+ client->addr);
return -EINVAL;
}
@@ -505,23 +565,23 @@ static int mxt_get_bootloader_version(struct i2c_client *client, u8 val)
{
u8 buf[3];
- if (val | MXT_BOOT_EXTENDED_ID) {
+ if (val | MXT_BOOT_EXTENDED_ID) {
dev_dbg(&client->dev,
- "Retrieving extended mode ID information");
+ "Retrieving extended mode ID information");
if (i2c_master_recv(client, &buf[0], 3) != 3) {
dev_err(&client->dev, "%s: i2c recv failed\n",
- __func__);
+ __func__);
return -EIO;
}
dev_info(&client->dev, "Bootloader ID:%d Version:%d",
- buf[1], buf[2]);
+ buf[1], buf[2]);
return buf[0];
} else {
dev_info(&client->dev, "Bootloader ID:%d",
- val & MXT_BOOT_ID_MASK);
+ val & MXT_BOOT_ID_MASK);
return val;
}
@@ -537,23 +597,22 @@ static int mxt_get_bootloader_id(struct i2c_client *client)
return -EIO;
}
- if (val | MXT_BOOT_EXTENDED_ID) {
+ if (val | MXT_BOOT_EXTENDED_ID) {
if (i2c_master_recv(client, &buf[0], 3) != 3) {
dev_err(&client->dev, "%s: i2c recv failed\n",
- __func__);
+ __func__);
return -EIO;
}
return buf[1];
} else {
dev_info(&client->dev, "Bootloader ID:%d",
- val & MXT_BOOT_ID_MASK);
+ val & MXT_BOOT_ID_MASK);
return val & MXT_BOOT_ID_MASK;
}
}
-static int mxt_check_bootloader(struct i2c_client *client,
- unsigned int state)
+static int mxt_check_bootloader(struct i2c_client *client, unsigned int state)
{
u8 val;
@@ -609,7 +668,7 @@ static int mxt_unlock_bootloader(struct i2c_client *client)
}
static int mxt_fw_write(struct i2c_client *client,
- const u8 *data, unsigned int frame_size)
+ const u8 * data, unsigned int frame_size)
{
if (i2c_master_send(client, data, frame_size) != frame_size) {
dev_err(&client->dev, "%s: i2c send failed\n", __func__);
@@ -620,7 +679,7 @@ static int mxt_fw_write(struct i2c_client *client,
}
static int __mxt_read_reg(struct i2c_client *client,
- u16 reg, u16 len, void *val)
+ u16 reg, u16 len, void *val)
{
struct i2c_msg xfer[2];
u8 buf[2];
@@ -651,13 +710,13 @@ static int __mxt_read_reg(struct i2c_client *client,
return -EIO;
}
-static int mxt_read_reg(struct i2c_client *client, u16 reg, u8 *val)
+static int mxt_read_reg(struct i2c_client *client, u16 reg, u8 * val)
{
return __mxt_read_reg(client, reg, 1, val);
}
static int __mxt_write_reg(struct i2c_client *client,
- u16 addr, u16 length, u8 *value)
+ u16 addr, u16 length, u8 * value)
{
u8 buf[MXT_BLOCK_SIZE + 2];
int i, tries = 0;
@@ -686,14 +745,12 @@ static int mxt_write_reg(struct i2c_client *client, u16 reg, u8 val)
}
static int mxt_read_object_table(struct i2c_client *client,
- u16 reg, u8 *object_buf)
+ u16 reg, u8 * object_buf)
{
- return __mxt_read_reg(client, reg, MXT_OBJECT_SIZE,
- object_buf);
+ return __mxt_read_reg(client, reg, MXT_OBJECT_SIZE, object_buf);
}
-static struct mxt_object *
-mxt_get_object(struct mxt_data *data, u8 type)
+static struct mxt_object *mxt_get_object(struct mxt_data *data, u8 type)
{
struct mxt_object *object;
int i;
@@ -708,8 +765,7 @@ mxt_get_object(struct mxt_data *data, u8 type)
return NULL;
}
-static int mxt_read_message(struct mxt_data *data,
- struct mxt_message *message)
+static int mxt_read_message(struct mxt_data *data, struct mxt_message *message)
{
struct mxt_object *object;
u16 reg;
@@ -720,11 +776,10 @@ static int mxt_read_message(s
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment