From 9d40ac5867b9aefe0722bc1f110b965ff294d30d Mon Sep 17 00:00:00 2001
From: Kevin
Date: Sat, 15 Nov 2014 10:00:36 +0800
Subject: add via modify part source code for wm8880 4.4 kitkat
---
ANDROID_3.4.5/drivers/input/Kconfig | 5 +
ANDROID_3.4.5/drivers/input/Makefile | 4 +
ANDROID_3.4.5/drivers/input/keyboard/Kconfig | 18 +
ANDROID_3.4.5/drivers/input/keyboard/Makefile | 2 +
ANDROID_3.4.5/drivers/input/keyboard/wmt_kpad.c | 466 +++
ANDROID_3.4.5/drivers/input/keyboard/wmt_saradc.c | 718 ++++
ANDROID_3.4.5/drivers/input/physics_key/Kconfig | 27 +
ANDROID_3.4.5/drivers/input/physics_key/Makefile | 41 +
ANDROID_3.4.5/drivers/input/physics_key/pkey.c | 261 ++
ANDROID_3.4.5/drivers/input/remote_input.c | 195 ++
ANDROID_3.4.5/drivers/input/rmtctl/Kconfig | 25 +
ANDROID_3.4.5/drivers/input/rmtctl/Makefile | 8 +
ANDROID_3.4.5/drivers/input/rmtctl/oem-dev.h | 186 +
ANDROID_3.4.5/drivers/input/rmtctl/wmt-rmtctl.c | 1515 +++++++++
ANDROID_3.4.5/drivers/input/rmtctl/wmt-rmtctl.h | 50 +
ANDROID_3.4.5/drivers/input/sensor/Kconfig | 224 ++
ANDROID_3.4.5/drivers/input/sensor/Makefile | 26 +
.../drivers/input/sensor/TP_DRIVER_NOT_USE/Kconfig | 50 +
.../input/sensor/TP_DRIVER_NOT_USE/Makefile | 13 +
.../TP_DRIVER_NOT_USE/dmt08_gsensor/Makefile | 6 +
.../sensor/TP_DRIVER_NOT_USE/dmt08_gsensor/dmt08.c | 870 +++++
.../sensor/TP_DRIVER_NOT_USE/dmt08_gsensor/dmt08.h | 105 +
.../TP_DRIVER_NOT_USE/dmt10_gsensor/Makefile | 6 +
.../sensor/TP_DRIVER_NOT_USE/dmt10_gsensor/dmt10.c | 950 ++++++
.../sensor/TP_DRIVER_NOT_USE/dmt10_gsensor/dmt10.h | 187 +
.../input/sensor/TP_DRIVER_NOT_USE/gsensor.c | 180 +
.../input/sensor/TP_DRIVER_NOT_USE/gsensor.h | 43 +
.../TP_DRIVER_NOT_USE/kxti9_gsensor/Makefile | 6 +
.../sensor/TP_DRIVER_NOT_USE/kxti9_gsensor/kxti9.c | 1134 +++++++
.../sensor/TP_DRIVER_NOT_USE/kxti9_gsensor/kxti9.h | 103 +
ANDROID_3.4.5/drivers/input/sensor/cm3232/Makefile | 34 +
ANDROID_3.4.5/drivers/input/sensor/cm3232/cm3232.c | 855 +++++
.../drivers/input/sensor/dmard06_gsensor/Makefile | 34 +
.../drivers/input/sensor/dmard06_gsensor/dmard06.c | 980 ++++++
.../drivers/input/sensor/dmard08_gsensor/Makefile | 34 +
.../input/sensor/dmard08_gsensor/cyclequeue.c | 68 +
.../input/sensor/dmard08_gsensor/cyclequeue.h | 18 +
.../drivers/input/sensor/dmard08_gsensor/dmard08.c | 1019 ++++++
.../drivers/input/sensor/dmard08_gsensor/dmard08.h | 75 +
.../drivers/input/sensor/dmard09_gsensor/Makefile | 35 +
.../drivers/input/sensor/dmard09_gsensor/dmt09.c | 1685 +++++++++
.../drivers/input/sensor/dmard09_gsensor/dmt09.h | 183 +
.../drivers/input/sensor/dmard10_gsensor/Makefile | 34 +
.../drivers/input/sensor/dmard10_gsensor/dmt10.c | 1702 ++++++++++
.../drivers/input/sensor/dmard10_gsensor/dmt10.h | 192 ++
.../drivers/input/sensor/isl29023_lsensor/Makefile | 34 +
.../input/sensor/isl29023_lsensor/isl29023.c | 1164 +++++++
.../drivers/input/sensor/kionix_gsensor/Makefile | 35 +
.../input/sensor/kionix_gsensor/kionix_accel.c | 2427 +++++++++++++
.../input/sensor/kionix_gsensor/kionix_accel.h | 85 +
.../drivers/input/sensor/kxte9_gsensor/Makefile | 34 +
.../drivers/input/sensor/kxte9_gsensor/kxte9.c | 1798 ++++++++++
.../drivers/input/sensor/kxte9_gsensor/kxte9.h | 116 +
.../drivers/input/sensor/kxte9_gsensor/readme.txt | 47 +
.../drivers/input/sensor/l3g4200d_gyro/Makefile | 5 +
.../drivers/input/sensor/l3g4200d_gyro/l3g4200d.h | 108 +
.../input/sensor/l3g4200d_gyro/l3g4200d_gyr.c | 1681 +++++++++
.../drivers/input/sensor/mc3230_gsensor/Makefile | 34 +
.../drivers/input/sensor/mc3230_gsensor/mc32x0.c | 2580 ++++++++++++++
.../input/sensor/mc3230_gsensor/mc32x0_driver.c | 505 +++
.../input/sensor/mc3230_gsensor/mc32x0_driver.h | 219 ++
.../drivers/input/sensor/mc3xxx_gsensor/Makefile | 34 +
.../drivers/input/sensor/mc3xxx_gsensor/mc3xxx.c | 2719 +++++++++++++++
.../drivers/input/sensor/mma7660_gsensor/Makefile | 34 +
.../drivers/input/sensor/mma7660_gsensor/mma7660.c | 1052 ++++++
.../drivers/input/sensor/mma7660_gsensor/mma7660.h | 106 +
.../drivers/input/sensor/mma8452q_gsensor/Makefile | 34 +
.../input/sensor/mma8452q_gsensor/mma8x5x.c | 982 ++++++
.../input/sensor/mma8452q_gsensor/mma8x5x.h | 107 +
.../drivers/input/sensor/mmc328x_msensor/Makefile | 4 +
.../drivers/input/sensor/mmc328x_msensor/mecs.c | 433 +++
.../drivers/input/sensor/mmc328x_msensor/mecs.h | 60 +
.../drivers/input/sensor/mmc328x_msensor/mmc328x.c | 505 +++
.../drivers/input/sensor/mmc328x_msensor/mmc328x.h | 91 +
.../drivers/input/sensor/mxc622x_gsensor/Makefile | 34 +
.../drivers/input/sensor/mxc622x_gsensor/mxc622x.c | 1151 +++++++
.../drivers/input/sensor/mxc622x_gsensor/mxc622x.h | 83 +
ANDROID_3.4.5/drivers/input/sensor/sensor.c | 114 +
ANDROID_3.4.5/drivers/input/sensor/sensor.h | 91 +
.../drivers/input/sensor/stk3310/Makefile | 34 +
.../drivers/input/sensor/stk3310/stk3310.c | 644 ++++
.../drivers/input/sensor/stk8312_gsensor/Makefile | 34 +
.../drivers/input/sensor/stk8312_gsensor/stk8312.h | 51 +
.../drivers/input/sensor/stk8312_gsensor/stk8313.h | 52 +
.../drivers/input/sensor/stk8312_gsensor/stk831x.c | 3590 ++++++++++++++++++++
.../drivers/input/sensor/us5182_lpsensor/Makefile | 34 +
.../drivers/input/sensor/us5182_lpsensor/us5182.c | 1098 ++++++
.../drivers/input/sensor/us5182_lpsensor/us5182.h | 255 ++
ANDROID_3.4.5/drivers/input/touchscreen/Kconfig | 24 +
ANDROID_3.4.5/drivers/input/touchscreen/Makefile | 16 +
.../input/touchscreen/aw5306_ts/AW5306_Base.b | Bin 0 -> 41612 bytes
.../input/touchscreen/aw5306_ts/AW5306_Clb.b | Bin 0 -> 32804 bytes
.../input/touchscreen/aw5306_ts/AW5306_Drv.b | Bin 0 -> 114476 bytes
.../input/touchscreen/aw5306_ts/AW5306_Drv.h | 158 +
.../input/touchscreen/aw5306_ts/AW5306_Reg.h | 187 +
.../input/touchscreen/aw5306_ts/AW5306_ts.c | 1614 +++++++++
.../input/touchscreen/aw5306_ts/AW5306_userpara.c | 196 ++
.../input/touchscreen/aw5306_ts/AW5306_userpara.h | 99 +
.../drivers/input/touchscreen/aw5306_ts/Kconfig | 11 +
.../drivers/input/touchscreen/aw5306_ts/Makefile | 35 +
.../drivers/input/touchscreen/aw5306_ts/irq_gpio.c | 149 +
.../drivers/input/touchscreen/aw5306_ts/irq_gpio.h | 13 +
.../drivers/input/touchscreen/cyp140_ts/Kconfig | 16 +
.../drivers/input/touchscreen/cyp140_ts/Makefile | 33 +
.../input/touchscreen/cyp140_ts/cyp140_i2c.c | 1412 ++++++++
.../drivers/input/touchscreen/cyp140_ts/cyttsp.h | 696 ++++
.../touchscreen/cyp140_ts/cyttsp_fw_upgrade.c | 993 ++++++
.../drivers/input/touchscreen/cyp140_ts/debug.txt | 3 +
.../drivers/input/touchscreen/cyp140_ts/wmt_ts.c | 1094 ++++++
.../drivers/input/touchscreen/cyp140_ts/wmt_ts.h | 120 +
.../drivers/input/touchscreen/ft5x0x/Kconfig | 11 +
.../drivers/input/touchscreen/ft5x0x/Makefile | 34 +
.../input/touchscreen/ft5x0x/ft5402_config.c | 2295 +++++++++++++
.../input/touchscreen/ft5x0x/ft5402_config.h | 71 +
.../input/touchscreen/ft5x0x/ft5402_ini_config.h | 411 +++
.../drivers/input/touchscreen/ft5x0x/ft5x0x.c | 937 +++++
.../drivers/input/touchscreen/ft5x0x/ft5x0x.h | 207 ++
.../drivers/input/touchscreen/ft5x0x/ft5x0x_upg.c | 506 +++
.../drivers/input/touchscreen/ft5x0x/ini.c | 406 +++
.../drivers/input/touchscreen/ft5x0x/ini.h | 43 +
.../drivers/input/touchscreen/ft6x0x/Kconfig | 11 +
.../drivers/input/touchscreen/ft6x0x/Makefile | 34 +
.../input/touchscreen/ft6x0x/focaltech_ctl.h | 27 +
.../input/touchscreen/ft6x0x/ft5402_config.c | 2295 +++++++++++++
.../input/touchscreen/ft6x0x/ft5402_config.h | 71 +
.../input/touchscreen/ft6x0x/ft5402_ini_config.h | 411 +++
.../drivers/input/touchscreen/ft6x0x/ft5x0x.c | 896 +++++
.../drivers/input/touchscreen/ft6x0x/ft5x0x.h | 205 ++
.../drivers/input/touchscreen/ft6x0x/ft5x0x_upg.c | 506 +++
.../input/touchscreen/ft6x0x/ft6x06_ex_fun.c | 1021 ++++++
.../input/touchscreen/ft6x0x/ft6x06_ex_fun.h | 79 +
.../drivers/input/touchscreen/ft6x0x/ft6x06_ts.c | 511 +++
.../drivers/input/touchscreen/ft6x0x/ft6x06_ts.h | 52 +
.../drivers/input/touchscreen/ft6x0x/ini.c | 406 +++
.../drivers/input/touchscreen/ft6x0x/ini.h | 43 +
.../drivers/input/touchscreen/gsl1680_ts/Kconfig | 16 +
.../drivers/input/touchscreen/gsl1680_ts/Makefile | 33 +
.../drivers/input/touchscreen/gsl1680_ts/gslX680.c | 1416 ++++++++
.../drivers/input/touchscreen/gsl1680_ts/gslX680.h | 35 +
.../input/touchscreen/gsl1680_ts/gsl_point_id.b | Bin 0 -> 38321 bytes
.../drivers/input/touchscreen/gsl1680_ts/wmt_ts.c | 1102 ++++++
.../drivers/input/touchscreen/gsl1680_ts/wmt_ts.h | 117 +
.../drivers/input/touchscreen/gt9xx_ts/Kconfig | 11 +
.../drivers/input/touchscreen/gt9xx_ts/Makefile | 34 +
.../input/touchscreen/gt9xx_ts/goodix_tool.c | 615 ++++
.../drivers/input/touchscreen/gt9xx_ts/gt9xx.c | 2163 ++++++++++++
.../drivers/input/touchscreen/gt9xx_ts/gt9xx.h | 278 ++
.../input/touchscreen/gt9xx_ts/gt9xx_firmware.h | 6 +
.../input/touchscreen/gt9xx_ts/gt9xx_update.c | 1939 +++++++++++
.../drivers/input/touchscreen/icn83xx_ts/Kconfig | 16 +
.../drivers/input/touchscreen/icn83xx_ts/Makefile | 32 +
.../drivers/input/touchscreen/icn83xx_ts/flash.c | 973 ++++++
.../drivers/input/touchscreen/icn83xx_ts/icn83xx.c | 2034 +++++++++++
.../drivers/input/touchscreen/icn83xx_ts/icn83xx.h | 434 +++
.../input/touchscreen/icn83xx_ts/icn83xx_fw.h | 3 +
.../drivers/input/touchscreen/icn85xx_ts/Kconfig | 16 +
.../drivers/input/touchscreen/icn85xx_ts/Makefile | 32 +
.../drivers/input/touchscreen/icn85xx_ts/icn85xx.c | 2431 +++++++++++++
.../drivers/input/touchscreen/icn85xx_ts/icn85xx.h | 500 +++
.../input/touchscreen/icn85xx_ts/icn85xx_flash.c | 1050 ++++++
.../input/touchscreen/icn85xx_ts/icn85xx_fw.h | 2517 ++++++++++++++
.../drivers/input/touchscreen/lw86x0_ts/Kconfig | 11 +
.../drivers/input/touchscreen/lw86x0_ts/Makefile | 34 +
.../input/touchscreen/lw86x0_ts/lw86x0_ts.c | 1321 +++++++
.../input/touchscreen/lw86x0_ts/lw86x0_ts.h | 53 +
.../drivers/input/touchscreen/lw86x0_ts/wmt_ts.c | 1165 +++++++
.../drivers/input/touchscreen/lw86x0_ts/wmt_ts.h | 98 +
.../drivers/input/touchscreen/metusb/Makefile | 33 +
.../drivers/input/touchscreen/metusb/metusb.c | 856 +++++
.../drivers/input/touchscreen/semisens/Makefile | 33 +
.../touchscreen/semisens/sn310m-touch-pdata.h | 201 ++
.../input/touchscreen/semisens/sn310m-touch.c | 332 ++
.../input/touchscreen/semisens/sn310m-touch.h | 97 +
.../drivers/input/touchscreen/semisens/touch.c | 1121 ++++++
.../drivers/input/touchscreen/semisens/touch.h | 54 +
.../input/touchscreen/sis_usbhid_ts/Kconfig | 16 +
.../input/touchscreen/sis_usbhid_ts/Makefile | 32 +
.../input/touchscreen/sis_usbhid_ts/hid-sis.c | 1104 ++++++
.../drivers/input/touchscreen/sitronix/Kconfig | 11 +
.../drivers/input/touchscreen/sitronix/Makefile | 34 +
.../drivers/input/touchscreen/sitronix/irq_gpio.c | 148 +
.../drivers/input/touchscreen/sitronix/irq_gpio.h | 13 +
.../input/touchscreen/sitronix/sitronix_i2c.c | 817 +++++
.../input/touchscreen/sitronix/sitronix_i2c.h | 137 +
.../drivers/input/touchscreen/ssd253x_ts/Kconfig | 16 +
.../drivers/input/touchscreen/ssd253x_ts/Makefile | 32 +
.../input/touchscreen/ssd253x_ts/ssd253x-ts.c | 1827 ++++++++++
.../input/touchscreen/ssd253x_ts/ssd253x-ts.h | 28 +
.../drivers/input/touchscreen/ssd253x_ts/wmt_ts.c | 810 +++++
.../drivers/input/touchscreen/ssd253x_ts/wmt_ts.h | 116 +
.../drivers/input/touchscreen/vt1609_ts/Makefile | 4 +
.../input/touchscreen/vt1609_ts/vt1609_dual.c | 692 ++++
.../input/touchscreen/vt1609_ts/vt1609_ts.c | 1481 ++++++++
.../input/touchscreen/vt1609_ts/vt1609_ts.h | 301 ++
.../drivers/input/touchscreen/zet6221_ts/Kconfig | 16 +
.../drivers/input/touchscreen/zet6221_ts/Makefile | 32 +
.../drivers/input/touchscreen/zet6221_ts/wmt_ts.c | 833 +++++
.../drivers/input/touchscreen/zet6221_ts/wmt_ts.h | 149 +
.../touchscreen/zet6221_ts/zet6221_downloader.c | 1209 +++++++
.../input/touchscreen/zet6221_ts/zet6221_i2c.c | 2786 +++++++++++++++
.../input/touchscreen/zet6221_ts/zet6221_ts.h | 6 +
201 files changed, 92890 insertions(+)
create mode 100755 ANDROID_3.4.5/drivers/input/keyboard/wmt_kpad.c
create mode 100755 ANDROID_3.4.5/drivers/input/keyboard/wmt_saradc.c
create mode 100755 ANDROID_3.4.5/drivers/input/physics_key/Kconfig
create mode 100755 ANDROID_3.4.5/drivers/input/physics_key/Makefile
create mode 100755 ANDROID_3.4.5/drivers/input/physics_key/pkey.c
create mode 100755 ANDROID_3.4.5/drivers/input/remote_input.c
create mode 100755 ANDROID_3.4.5/drivers/input/rmtctl/Kconfig
create mode 100755 ANDROID_3.4.5/drivers/input/rmtctl/Makefile
create mode 100755 ANDROID_3.4.5/drivers/input/rmtctl/oem-dev.h
create mode 100755 ANDROID_3.4.5/drivers/input/rmtctl/wmt-rmtctl.c
create mode 100755 ANDROID_3.4.5/drivers/input/rmtctl/wmt-rmtctl.h
create mode 100755 ANDROID_3.4.5/drivers/input/sensor/Kconfig
create mode 100755 ANDROID_3.4.5/drivers/input/sensor/Makefile
create mode 100755 ANDROID_3.4.5/drivers/input/sensor/TP_DRIVER_NOT_USE/Kconfig
create mode 100755 ANDROID_3.4.5/drivers/input/sensor/TP_DRIVER_NOT_USE/Makefile
create mode 100755 ANDROID_3.4.5/drivers/input/sensor/TP_DRIVER_NOT_USE/dmt08_gsensor/Makefile
create mode 100755 ANDROID_3.4.5/drivers/input/sensor/TP_DRIVER_NOT_USE/dmt08_gsensor/dmt08.c
create mode 100755 ANDROID_3.4.5/drivers/input/sensor/TP_DRIVER_NOT_USE/dmt08_gsensor/dmt08.h
create mode 100755 ANDROID_3.4.5/drivers/input/sensor/TP_DRIVER_NOT_USE/dmt10_gsensor/Makefile
create mode 100755 ANDROID_3.4.5/drivers/input/sensor/TP_DRIVER_NOT_USE/dmt10_gsensor/dmt10.c
create mode 100755 ANDROID_3.4.5/drivers/input/sensor/TP_DRIVER_NOT_USE/dmt10_gsensor/dmt10.h
create mode 100755 ANDROID_3.4.5/drivers/input/sensor/TP_DRIVER_NOT_USE/gsensor.c
create mode 100755 ANDROID_3.4.5/drivers/input/sensor/TP_DRIVER_NOT_USE/gsensor.h
create mode 100755 ANDROID_3.4.5/drivers/input/sensor/TP_DRIVER_NOT_USE/kxti9_gsensor/Makefile
create mode 100755 ANDROID_3.4.5/drivers/input/sensor/TP_DRIVER_NOT_USE/kxti9_gsensor/kxti9.c
create mode 100755 ANDROID_3.4.5/drivers/input/sensor/TP_DRIVER_NOT_USE/kxti9_gsensor/kxti9.h
create mode 100755 ANDROID_3.4.5/drivers/input/sensor/cm3232/Makefile
create mode 100755 ANDROID_3.4.5/drivers/input/sensor/cm3232/cm3232.c
create mode 100755 ANDROID_3.4.5/drivers/input/sensor/dmard06_gsensor/Makefile
create mode 100755 ANDROID_3.4.5/drivers/input/sensor/dmard06_gsensor/dmard06.c
create mode 100755 ANDROID_3.4.5/drivers/input/sensor/dmard08_gsensor/Makefile
create mode 100755 ANDROID_3.4.5/drivers/input/sensor/dmard08_gsensor/cyclequeue.c
create mode 100755 ANDROID_3.4.5/drivers/input/sensor/dmard08_gsensor/cyclequeue.h
create mode 100755 ANDROID_3.4.5/drivers/input/sensor/dmard08_gsensor/dmard08.c
create mode 100755 ANDROID_3.4.5/drivers/input/sensor/dmard08_gsensor/dmard08.h
create mode 100755 ANDROID_3.4.5/drivers/input/sensor/dmard09_gsensor/Makefile
create mode 100755 ANDROID_3.4.5/drivers/input/sensor/dmard09_gsensor/dmt09.c
create mode 100755 ANDROID_3.4.5/drivers/input/sensor/dmard09_gsensor/dmt09.h
create mode 100755 ANDROID_3.4.5/drivers/input/sensor/dmard10_gsensor/Makefile
create mode 100755 ANDROID_3.4.5/drivers/input/sensor/dmard10_gsensor/dmt10.c
create mode 100755 ANDROID_3.4.5/drivers/input/sensor/dmard10_gsensor/dmt10.h
create mode 100755 ANDROID_3.4.5/drivers/input/sensor/isl29023_lsensor/Makefile
create mode 100755 ANDROID_3.4.5/drivers/input/sensor/isl29023_lsensor/isl29023.c
create mode 100755 ANDROID_3.4.5/drivers/input/sensor/kionix_gsensor/Makefile
create mode 100755 ANDROID_3.4.5/drivers/input/sensor/kionix_gsensor/kionix_accel.c
create mode 100755 ANDROID_3.4.5/drivers/input/sensor/kionix_gsensor/kionix_accel.h
create mode 100755 ANDROID_3.4.5/drivers/input/sensor/kxte9_gsensor/Makefile
create mode 100755 ANDROID_3.4.5/drivers/input/sensor/kxte9_gsensor/kxte9.c
create mode 100755 ANDROID_3.4.5/drivers/input/sensor/kxte9_gsensor/kxte9.h
create mode 100755 ANDROID_3.4.5/drivers/input/sensor/kxte9_gsensor/readme.txt
create mode 100755 ANDROID_3.4.5/drivers/input/sensor/l3g4200d_gyro/Makefile
create mode 100755 ANDROID_3.4.5/drivers/input/sensor/l3g4200d_gyro/l3g4200d.h
create mode 100755 ANDROID_3.4.5/drivers/input/sensor/l3g4200d_gyro/l3g4200d_gyr.c
create mode 100755 ANDROID_3.4.5/drivers/input/sensor/mc3230_gsensor/Makefile
create mode 100755 ANDROID_3.4.5/drivers/input/sensor/mc3230_gsensor/mc32x0.c
create mode 100755 ANDROID_3.4.5/drivers/input/sensor/mc3230_gsensor/mc32x0_driver.c
create mode 100755 ANDROID_3.4.5/drivers/input/sensor/mc3230_gsensor/mc32x0_driver.h
create mode 100644 ANDROID_3.4.5/drivers/input/sensor/mc3xxx_gsensor/Makefile
create mode 100644 ANDROID_3.4.5/drivers/input/sensor/mc3xxx_gsensor/mc3xxx.c
create mode 100755 ANDROID_3.4.5/drivers/input/sensor/mma7660_gsensor/Makefile
create mode 100755 ANDROID_3.4.5/drivers/input/sensor/mma7660_gsensor/mma7660.c
create mode 100755 ANDROID_3.4.5/drivers/input/sensor/mma7660_gsensor/mma7660.h
create mode 100755 ANDROID_3.4.5/drivers/input/sensor/mma8452q_gsensor/Makefile
create mode 100755 ANDROID_3.4.5/drivers/input/sensor/mma8452q_gsensor/mma8x5x.c
create mode 100755 ANDROID_3.4.5/drivers/input/sensor/mma8452q_gsensor/mma8x5x.h
create mode 100755 ANDROID_3.4.5/drivers/input/sensor/mmc328x_msensor/Makefile
create mode 100755 ANDROID_3.4.5/drivers/input/sensor/mmc328x_msensor/mecs.c
create mode 100755 ANDROID_3.4.5/drivers/input/sensor/mmc328x_msensor/mecs.h
create mode 100755 ANDROID_3.4.5/drivers/input/sensor/mmc328x_msensor/mmc328x.c
create mode 100755 ANDROID_3.4.5/drivers/input/sensor/mmc328x_msensor/mmc328x.h
create mode 100755 ANDROID_3.4.5/drivers/input/sensor/mxc622x_gsensor/Makefile
create mode 100755 ANDROID_3.4.5/drivers/input/sensor/mxc622x_gsensor/mxc622x.c
create mode 100755 ANDROID_3.4.5/drivers/input/sensor/mxc622x_gsensor/mxc622x.h
create mode 100755 ANDROID_3.4.5/drivers/input/sensor/sensor.c
create mode 100755 ANDROID_3.4.5/drivers/input/sensor/sensor.h
create mode 100755 ANDROID_3.4.5/drivers/input/sensor/stk3310/Makefile
create mode 100755 ANDROID_3.4.5/drivers/input/sensor/stk3310/stk3310.c
create mode 100755 ANDROID_3.4.5/drivers/input/sensor/stk8312_gsensor/Makefile
create mode 100755 ANDROID_3.4.5/drivers/input/sensor/stk8312_gsensor/stk8312.h
create mode 100755 ANDROID_3.4.5/drivers/input/sensor/stk8312_gsensor/stk8313.h
create mode 100755 ANDROID_3.4.5/drivers/input/sensor/stk8312_gsensor/stk831x.c
create mode 100755 ANDROID_3.4.5/drivers/input/sensor/us5182_lpsensor/Makefile
create mode 100755 ANDROID_3.4.5/drivers/input/sensor/us5182_lpsensor/us5182.c
create mode 100755 ANDROID_3.4.5/drivers/input/sensor/us5182_lpsensor/us5182.h
create mode 100755 ANDROID_3.4.5/drivers/input/touchscreen/aw5306_ts/AW5306_Base.b
create mode 100755 ANDROID_3.4.5/drivers/input/touchscreen/aw5306_ts/AW5306_Clb.b
create mode 100755 ANDROID_3.4.5/drivers/input/touchscreen/aw5306_ts/AW5306_Drv.b
create mode 100755 ANDROID_3.4.5/drivers/input/touchscreen/aw5306_ts/AW5306_Drv.h
create mode 100755 ANDROID_3.4.5/drivers/input/touchscreen/aw5306_ts/AW5306_Reg.h
create mode 100755 ANDROID_3.4.5/drivers/input/touchscreen/aw5306_ts/AW5306_ts.c
create mode 100755 ANDROID_3.4.5/drivers/input/touchscreen/aw5306_ts/AW5306_userpara.c
create mode 100755 ANDROID_3.4.5/drivers/input/touchscreen/aw5306_ts/AW5306_userpara.h
create mode 100755 ANDROID_3.4.5/drivers/input/touchscreen/aw5306_ts/Kconfig
create mode 100755 ANDROID_3.4.5/drivers/input/touchscreen/aw5306_ts/Makefile
create mode 100755 ANDROID_3.4.5/drivers/input/touchscreen/aw5306_ts/irq_gpio.c
create mode 100755 ANDROID_3.4.5/drivers/input/touchscreen/aw5306_ts/irq_gpio.h
create mode 100755 ANDROID_3.4.5/drivers/input/touchscreen/cyp140_ts/Kconfig
create mode 100755 ANDROID_3.4.5/drivers/input/touchscreen/cyp140_ts/Makefile
create mode 100755 ANDROID_3.4.5/drivers/input/touchscreen/cyp140_ts/cyp140_i2c.c
create mode 100755 ANDROID_3.4.5/drivers/input/touchscreen/cyp140_ts/cyttsp.h
create mode 100755 ANDROID_3.4.5/drivers/input/touchscreen/cyp140_ts/cyttsp_fw_upgrade.c
create mode 100755 ANDROID_3.4.5/drivers/input/touchscreen/cyp140_ts/debug.txt
create mode 100755 ANDROID_3.4.5/drivers/input/touchscreen/cyp140_ts/wmt_ts.c
create mode 100755 ANDROID_3.4.5/drivers/input/touchscreen/cyp140_ts/wmt_ts.h
create mode 100755 ANDROID_3.4.5/drivers/input/touchscreen/ft5x0x/Kconfig
create mode 100755 ANDROID_3.4.5/drivers/input/touchscreen/ft5x0x/Makefile
create mode 100755 ANDROID_3.4.5/drivers/input/touchscreen/ft5x0x/ft5402_config.c
create mode 100755 ANDROID_3.4.5/drivers/input/touchscreen/ft5x0x/ft5402_config.h
create mode 100755 ANDROID_3.4.5/drivers/input/touchscreen/ft5x0x/ft5402_ini_config.h
create mode 100755 ANDROID_3.4.5/drivers/input/touchscreen/ft5x0x/ft5x0x.c
create mode 100755 ANDROID_3.4.5/drivers/input/touchscreen/ft5x0x/ft5x0x.h
create mode 100755 ANDROID_3.4.5/drivers/input/touchscreen/ft5x0x/ft5x0x_upg.c
create mode 100755 ANDROID_3.4.5/drivers/input/touchscreen/ft5x0x/ini.c
create mode 100755 ANDROID_3.4.5/drivers/input/touchscreen/ft5x0x/ini.h
create mode 100755 ANDROID_3.4.5/drivers/input/touchscreen/ft6x0x/Kconfig
create mode 100755 ANDROID_3.4.5/drivers/input/touchscreen/ft6x0x/Makefile
create mode 100755 ANDROID_3.4.5/drivers/input/touchscreen/ft6x0x/focaltech_ctl.h
create mode 100755 ANDROID_3.4.5/drivers/input/touchscreen/ft6x0x/ft5402_config.c
create mode 100755 ANDROID_3.4.5/drivers/input/touchscreen/ft6x0x/ft5402_config.h
create mode 100755 ANDROID_3.4.5/drivers/input/touchscreen/ft6x0x/ft5402_ini_config.h
create mode 100755 ANDROID_3.4.5/drivers/input/touchscreen/ft6x0x/ft5x0x.c
create mode 100755 ANDROID_3.4.5/drivers/input/touchscreen/ft6x0x/ft5x0x.h
create mode 100755 ANDROID_3.4.5/drivers/input/touchscreen/ft6x0x/ft5x0x_upg.c
create mode 100755 ANDROID_3.4.5/drivers/input/touchscreen/ft6x0x/ft6x06_ex_fun.c
create mode 100755 ANDROID_3.4.5/drivers/input/touchscreen/ft6x0x/ft6x06_ex_fun.h
create mode 100755 ANDROID_3.4.5/drivers/input/touchscreen/ft6x0x/ft6x06_ts.c
create mode 100755 ANDROID_3.4.5/drivers/input/touchscreen/ft6x0x/ft6x06_ts.h
create mode 100755 ANDROID_3.4.5/drivers/input/touchscreen/ft6x0x/ini.c
create mode 100755 ANDROID_3.4.5/drivers/input/touchscreen/ft6x0x/ini.h
create mode 100755 ANDROID_3.4.5/drivers/input/touchscreen/gsl1680_ts/Kconfig
create mode 100755 ANDROID_3.4.5/drivers/input/touchscreen/gsl1680_ts/Makefile
create mode 100755 ANDROID_3.4.5/drivers/input/touchscreen/gsl1680_ts/gslX680.c
create mode 100755 ANDROID_3.4.5/drivers/input/touchscreen/gsl1680_ts/gslX680.h
create mode 100755 ANDROID_3.4.5/drivers/input/touchscreen/gsl1680_ts/gsl_point_id.b
create mode 100755 ANDROID_3.4.5/drivers/input/touchscreen/gsl1680_ts/wmt_ts.c
create mode 100755 ANDROID_3.4.5/drivers/input/touchscreen/gsl1680_ts/wmt_ts.h
create mode 100755 ANDROID_3.4.5/drivers/input/touchscreen/gt9xx_ts/Kconfig
create mode 100755 ANDROID_3.4.5/drivers/input/touchscreen/gt9xx_ts/Makefile
create mode 100755 ANDROID_3.4.5/drivers/input/touchscreen/gt9xx_ts/goodix_tool.c
create mode 100755 ANDROID_3.4.5/drivers/input/touchscreen/gt9xx_ts/gt9xx.c
create mode 100755 ANDROID_3.4.5/drivers/input/touchscreen/gt9xx_ts/gt9xx.h
create mode 100755 ANDROID_3.4.5/drivers/input/touchscreen/gt9xx_ts/gt9xx_firmware.h
create mode 100755 ANDROID_3.4.5/drivers/input/touchscreen/gt9xx_ts/gt9xx_update.c
create mode 100755 ANDROID_3.4.5/drivers/input/touchscreen/icn83xx_ts/Kconfig
create mode 100755 ANDROID_3.4.5/drivers/input/touchscreen/icn83xx_ts/Makefile
create mode 100755 ANDROID_3.4.5/drivers/input/touchscreen/icn83xx_ts/flash.c
create mode 100755 ANDROID_3.4.5/drivers/input/touchscreen/icn83xx_ts/icn83xx.c
create mode 100755 ANDROID_3.4.5/drivers/input/touchscreen/icn83xx_ts/icn83xx.h
create mode 100755 ANDROID_3.4.5/drivers/input/touchscreen/icn83xx_ts/icn83xx_fw.h
create mode 100755 ANDROID_3.4.5/drivers/input/touchscreen/icn85xx_ts/Kconfig
create mode 100755 ANDROID_3.4.5/drivers/input/touchscreen/icn85xx_ts/Makefile
create mode 100755 ANDROID_3.4.5/drivers/input/touchscreen/icn85xx_ts/icn85xx.c
create mode 100755 ANDROID_3.4.5/drivers/input/touchscreen/icn85xx_ts/icn85xx.h
create mode 100755 ANDROID_3.4.5/drivers/input/touchscreen/icn85xx_ts/icn85xx_flash.c
create mode 100755 ANDROID_3.4.5/drivers/input/touchscreen/icn85xx_ts/icn85xx_fw.h
create mode 100755 ANDROID_3.4.5/drivers/input/touchscreen/lw86x0_ts/Kconfig
create mode 100755 ANDROID_3.4.5/drivers/input/touchscreen/lw86x0_ts/Makefile
create mode 100755 ANDROID_3.4.5/drivers/input/touchscreen/lw86x0_ts/lw86x0_ts.c
create mode 100755 ANDROID_3.4.5/drivers/input/touchscreen/lw86x0_ts/lw86x0_ts.h
create mode 100755 ANDROID_3.4.5/drivers/input/touchscreen/lw86x0_ts/wmt_ts.c
create mode 100755 ANDROID_3.4.5/drivers/input/touchscreen/lw86x0_ts/wmt_ts.h
create mode 100755 ANDROID_3.4.5/drivers/input/touchscreen/metusb/Makefile
create mode 100755 ANDROID_3.4.5/drivers/input/touchscreen/metusb/metusb.c
create mode 100755 ANDROID_3.4.5/drivers/input/touchscreen/semisens/Makefile
create mode 100755 ANDROID_3.4.5/drivers/input/touchscreen/semisens/sn310m-touch-pdata.h
create mode 100755 ANDROID_3.4.5/drivers/input/touchscreen/semisens/sn310m-touch.c
create mode 100755 ANDROID_3.4.5/drivers/input/touchscreen/semisens/sn310m-touch.h
create mode 100755 ANDROID_3.4.5/drivers/input/touchscreen/semisens/touch.c
create mode 100755 ANDROID_3.4.5/drivers/input/touchscreen/semisens/touch.h
create mode 100755 ANDROID_3.4.5/drivers/input/touchscreen/sis_usbhid_ts/Kconfig
create mode 100755 ANDROID_3.4.5/drivers/input/touchscreen/sis_usbhid_ts/Makefile
create mode 100755 ANDROID_3.4.5/drivers/input/touchscreen/sis_usbhid_ts/hid-sis.c
create mode 100755 ANDROID_3.4.5/drivers/input/touchscreen/sitronix/Kconfig
create mode 100755 ANDROID_3.4.5/drivers/input/touchscreen/sitronix/Makefile
create mode 100755 ANDROID_3.4.5/drivers/input/touchscreen/sitronix/irq_gpio.c
create mode 100755 ANDROID_3.4.5/drivers/input/touchscreen/sitronix/irq_gpio.h
create mode 100755 ANDROID_3.4.5/drivers/input/touchscreen/sitronix/sitronix_i2c.c
create mode 100755 ANDROID_3.4.5/drivers/input/touchscreen/sitronix/sitronix_i2c.h
create mode 100755 ANDROID_3.4.5/drivers/input/touchscreen/ssd253x_ts/Kconfig
create mode 100755 ANDROID_3.4.5/drivers/input/touchscreen/ssd253x_ts/Makefile
create mode 100755 ANDROID_3.4.5/drivers/input/touchscreen/ssd253x_ts/ssd253x-ts.c
create mode 100755 ANDROID_3.4.5/drivers/input/touchscreen/ssd253x_ts/ssd253x-ts.h
create mode 100755 ANDROID_3.4.5/drivers/input/touchscreen/ssd253x_ts/wmt_ts.c
create mode 100755 ANDROID_3.4.5/drivers/input/touchscreen/ssd253x_ts/wmt_ts.h
create mode 100755 ANDROID_3.4.5/drivers/input/touchscreen/vt1609_ts/Makefile
create mode 100755 ANDROID_3.4.5/drivers/input/touchscreen/vt1609_ts/vt1609_dual.c
create mode 100755 ANDROID_3.4.5/drivers/input/touchscreen/vt1609_ts/vt1609_ts.c
create mode 100755 ANDROID_3.4.5/drivers/input/touchscreen/vt1609_ts/vt1609_ts.h
create mode 100755 ANDROID_3.4.5/drivers/input/touchscreen/zet6221_ts/Kconfig
create mode 100755 ANDROID_3.4.5/drivers/input/touchscreen/zet6221_ts/Makefile
create mode 100755 ANDROID_3.4.5/drivers/input/touchscreen/zet6221_ts/wmt_ts.c
create mode 100755 ANDROID_3.4.5/drivers/input/touchscreen/zet6221_ts/wmt_ts.h
create mode 100755 ANDROID_3.4.5/drivers/input/touchscreen/zet6221_ts/zet6221_downloader.c
create mode 100755 ANDROID_3.4.5/drivers/input/touchscreen/zet6221_ts/zet6221_i2c.c
create mode 100755 ANDROID_3.4.5/drivers/input/touchscreen/zet6221_ts/zet6221_ts.h
(limited to 'ANDROID_3.4.5/drivers/input')
diff --git a/ANDROID_3.4.5/drivers/input/Kconfig b/ANDROID_3.4.5/drivers/input/Kconfig
index 69d36863..3eb8298e 100644
--- a/ANDROID_3.4.5/drivers/input/Kconfig
+++ b/ANDROID_3.4.5/drivers/input/Kconfig
@@ -186,8 +186,13 @@ source "drivers/input/tablet/Kconfig"
source "drivers/input/touchscreen/Kconfig"
+source "drivers/input/rmtctl/Kconfig"
+
+source "drivers/input/physics_key/Kconfig"
+
source "drivers/input/misc/Kconfig"
+source "drivers/input/sensor/Kconfig"
endif
menu "Hardware I/O ports"
diff --git a/ANDROID_3.4.5/drivers/input/Makefile b/ANDROID_3.4.5/drivers/input/Makefile
index cf643bee..b53e788c 100644
--- a/ANDROID_3.4.5/drivers/input/Makefile
+++ b/ANDROID_3.4.5/drivers/input/Makefile
@@ -21,8 +21,12 @@ obj-$(CONFIG_INPUT_MOUSE) += mouse/
obj-$(CONFIG_INPUT_JOYSTICK) += joystick/
obj-$(CONFIG_INPUT_TABLET) += tablet/
obj-$(CONFIG_INPUT_TOUCHSCREEN) += touchscreen/
+obj-$(CONFIG_INPUT_RMTCTL) += rmtctl/
+obj-$(CONFIG_INPUT_PKEY) += physics_key/
obj-$(CONFIG_INPUT_MISC) += misc/
obj-$(CONFIG_INPUT_APMPOWER) += apm-power.o
obj-$(CONFIG_INPUT_OF_MATRIX_KEYMAP) += of_keymap.o
obj-$(CONFIG_INPUT_KEYRESET) += keyreset.o
+obj-$(CONFIG_INPUT_SENSOR) += sensor/
+obj-m += remote_input.o
diff --git a/ANDROID_3.4.5/drivers/input/keyboard/Kconfig b/ANDROID_3.4.5/drivers/input/keyboard/Kconfig
index f354813a..906d86aa 100644
--- a/ANDROID_3.4.5/drivers/input/keyboard/Kconfig
+++ b/ANDROID_3.4.5/drivers/input/keyboard/Kconfig
@@ -502,6 +502,24 @@ config KEYBOARD_DAVINCI
To compile this driver as a module, choose M here: the
module will be called davinci_keyscan.
+config KEYBOARD_WMT
+ tristate "WMT keypad support"
+ depends on INPUT && INPUT_KEYBOARD
+ ---help---
+ Say Y here if you want to use keypad on WMT based EVB.
+
+ To compile this driver as a module, choose M here: the
+ module will be called wmt_keypad.
+
+config SARADC_WMT
+ tristate "WMT saradc support"
+ depends on INPUT && INPUT_KEYBOARD
+ ---help---
+ Say Y here if you want to use keypad on WMT based EVB.
+
+ To compile this driver as a module, choose M here: the
+ module will be called wmt_saradc.
+
config KEYBOARD_OMAP
tristate "TI OMAP keypad support"
depends on (ARCH_OMAP1 || ARCH_OMAP2)
diff --git a/ANDROID_3.4.5/drivers/input/keyboard/Makefile b/ANDROID_3.4.5/drivers/input/keyboard/Makefile
index df7061f1..587a9f25 100644
--- a/ANDROID_3.4.5/drivers/input/keyboard/Makefile
+++ b/ANDROID_3.4.5/drivers/input/keyboard/Makefile
@@ -51,4 +51,6 @@ obj-$(CONFIG_KEYBOARD_TEGRA) += tegra-kbc.o
obj-$(CONFIG_KEYBOARD_TNETV107X) += tnetv107x-keypad.o
obj-$(CONFIG_KEYBOARD_TWL4030) += twl4030_keypad.o
obj-$(CONFIG_KEYBOARD_XTKBD) += xtkbd.o
+obj-$(CONFIG_KEYBOARD_WMT) += wmt_kpad.o
obj-$(CONFIG_KEYBOARD_W90P910) += w90p910_keypad.o
+obj-$(CONFIG_SARADC_WMT) += wmt_saradc.o
diff --git a/ANDROID_3.4.5/drivers/input/keyboard/wmt_kpad.c b/ANDROID_3.4.5/drivers/input/keyboard/wmt_kpad.c
new file mode 100755
index 00000000..cf50cf1c
--- /dev/null
+++ b/ANDROID_3.4.5/drivers/input/keyboard/wmt_kpad.c
@@ -0,0 +1,466 @@
+/*++
+linux/drivers/input/keyboard/wmt_kpad.c
+
+Some descriptions of such software. Copyright (c) 2008 WonderMedia Technologies, Inc.
+
+This program is free software: you can redistribute it and/or modify it under the
+terms of the GNU General Public License as published by the Free Software Foundation,
+either version 2 of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+PARTICULAR PURPOSE. See the GNU General Public License for more details.
+You should have received a copy of the GNU General Public License along with
+this program. If not, see .
+
+WonderMedia Technologies, Inc.
+10F, 529, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C.
+--*/
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+
+/* Debug macros */
+#if 0
+#define DPRINTK(fmt, args...) printk(KERN_ALERT "[%s]: " fmt, __func__ , ## args)
+#else
+#define DPRINTK(fmt, args...)
+#endif
+
+//#define USE_HOME
+#define wmt_kpad_timeout (HZ/50)
+
+#define WMT_KPAD_FUNCTION_NUM 7
+
+
+static unsigned int wmt_kpad_codes[WMT_KPAD_FUNCTION_NUM] = {
+ [0] = KEY_VOLUMEUP,
+ [1] = KEY_VOLUMEDOWN,
+ [2] = KEY_BACK,
+ [3] = KEY_HOME,
+ [4] = KEY_MENU,
+ [5] = KEY_CAMERA,
+ [6] = KEY_PLAYPAUSE,
+};
+
+
+enum {
+ KEY_ST_up,
+ KEY_ST_down,
+ KEY_ST_debounce,
+};
+
+static struct input_dev *kpad_dev;
+
+int key_num = 0;
+
+struct wmt_key{
+ int gpio;
+ int keycode;
+
+ int status;
+ int debounce;
+ struct timer_list timer;
+} ;
+struct wmt_key gpio_key[5];
+
+#ifdef CONFIG_CPU_FREQ
+/*
+ * Well, the debounce time is not very critical while zac2_clk
+ * rescaling, but we still do it.
+ */
+
+/* kpad_clock_notifier()
+ *
+ * When changing the processor core clock frequency, it is necessary
+ * to adjust the KPMIR register.
+ *
+ * Returns: 0 on success, -1 on error
+ */
+static int kpad_clock_notifier(struct notifier_block *nb, unsigned long event,
+ void *data)
+{
+ return 0;
+}
+
+/*
+ * Notify callback while issusing zac2_clk rescale.
+ */
+static struct notifier_block kpad_clock_nblock = {
+ .notifier_call = kpad_clock_notifier,
+ .priority = 1
+};
+#endif
+
+static int wmt_kpad_gpio_requst(void)
+{
+ int i,j,ret;
+ DPRINTK("Start\n");
+ for(i=0; i< key_num; i++){
+ ret = gpio_request(gpio_key[i].gpio,"kpad");
+ if(ret)
+ goto exit;
+ }
+
+ DPRINTK("End\n");
+ return ret;
+exit:
+ for(j=0; j < i; j++)
+ gpio_free(gpio_key[j].gpio);
+ return ret;
+}
+
+static int wmt_kpad_gpio_init(void)
+{
+ int i;
+ for(i=0; igpio) == 0) { /*Active Low*/
+ if(gpk->status == KEY_ST_up){
+ gpk->debounce = 5;
+ gpk->status = KEY_ST_debounce;
+ DPRINTK("vd down to debounce\n");
+ }
+
+ if(gpk->status == KEY_ST_debounce){
+ if(--gpk->debounce == 0){
+ gpk->status = KEY_ST_down;
+ /* report volume down key down */
+ input_report_key(kpad_dev, gpk->keycode, 1);
+ input_sync(kpad_dev);
+ DPRINTK("WMT Volume up keep press\n");
+ }
+ }
+ //DPRINTK("vd level is low,status=%d\n",vu_status);
+
+ }
+ else {/* Level High */
+ if(gpk->status == KEY_ST_down){
+ gpk->status = KEY_ST_up;
+ /*Volume down release*/
+ input_report_key(kpad_dev, gpk->keycode, 0); /*row4 key is release*/
+ input_sync(kpad_dev);
+ DPRINTK("WMT_Volume down release key = %d \n", gpk->keycode);
+ }
+
+ if(gpk->status == KEY_ST_debounce){
+ if(--gpk->debounce == 0){
+ gpk->status = KEY_ST_up;
+ }
+ }
+
+ //DPRINTK("vd level is high,status=%d\n",vu_status);
+
+ }
+
+ mod_timer(&gpk->timer, jiffies + wmt_kpad_timeout);
+ //DPRINTK("End\n");
+
+ return;
+}
+
+static int init_key_timer(void)
+{
+ int i;
+ for(i=0; inum_resources = 0x%x\n",pdev->num_resources);
+ if (pdev->num_resources < 0 || pdev->num_resources > 2) {
+ ret = -ENODEV;
+ goto kpad_probe_out;
+ }
+
+ /* Register an input event device. */
+ kpad_dev->name = "keypad",
+ kpad_dev->phys = "keypad",
+
+ /*
+ * Let kpad to implement key repeat.
+ */
+
+ set_bit(EV_KEY, kpad_dev->evbit);
+
+ for (i = 0; i < WMT_KPAD_FUNCTION_NUM; i++)
+ set_bit(wmt_kpad_codes[i], kpad_dev->keybit);
+
+ kpad_dev->keycode = wmt_kpad_codes;
+ kpad_dev->keycodesize = sizeof(unsigned int);
+ kpad_dev->keycodemax = WMT_KPAD_FUNCTION_NUM;
+
+ /*
+ * For better view of /proc/bus/input/devices
+ */
+ kpad_dev->id.bustype = 0;
+ kpad_dev->id.vendor = 0;
+ kpad_dev->id.product = 0;
+ kpad_dev->id.version = 0;
+
+ input_register_device(kpad_dev);
+ kpad_open(kpad_dev);
+ DPRINTK("End2\n");
+kpad_probe_out:
+
+#ifndef CONFIG_SKIP_DRIVER_MSG
+ printk(KERN_INFO "WMT keypad driver initialized: %s\n",
+ (ret == 0) ? "ok" : "failed");
+#endif
+ DPRINTK("End3\n");
+ return ret;
+}
+
+static int wmt_kpad_remove(struct platform_device *pdev)
+{
+ int ret;
+ DPRINTK("Start\n");
+ kpad_close(kpad_dev);
+ wmt_kpad_gpio_free();
+ DPRINTK("End\n");
+#ifdef CONFIG_CPU_FREQ
+ ret = cpufreq_unregister_notifier(&kpad_clock_nblock, \
+ CPUFREQ_TRANSITION_NOTIFIER);
+
+ if (ret) {
+ printk(KERN_ERR "Unable to unregister CPU frequency " \
+ "change notifier (%d)\n", ret);
+ }
+#endif
+ return 0;
+}
+
+static int wmt_kpad_suspend(struct platform_device *pdev, pm_message_t state)
+{
+ DPRINTK("Start\n");
+
+ switch (state.event) {
+ case PM_EVENT_SUSPEND:
+ del_key_timer();
+ break;
+ case PM_EVENT_FREEZE:
+ case PM_EVENT_PRETHAW:
+
+ default:
+ break;
+ }
+
+ DPRINTK("End2\n");
+ return 0;
+}
+
+static int wmt_kpad_resume(struct platform_device *pdev)
+{
+ DPRINTK("Start\n");
+ wmt_kpad_gpio_init();
+ start_key_timer();
+ DPRINTK("End\n");
+ return 0;
+}
+
+static void wmt_kpad_release(struct device *dev)
+{
+ return ;
+}
+
+static struct platform_driver wmt_kpad_driver = {
+ .driver.name = "wmt-kpad",
+ .probe = &wmt_kpad_probe,
+ .remove = &wmt_kpad_remove,
+ .suspend = &wmt_kpad_suspend,
+ .resume = &wmt_kpad_resume
+};
+
+static struct resource wmt_kpad_resources[] = {
+ [0] = {
+ .start = IRQ_GPIO,
+ .end = IRQ_GPIO,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device wmt_kpad_device = {
+ .name = "wmt-kpad",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(wmt_kpad_resources),
+ .resource = wmt_kpad_resources,
+ .dev = {
+ .release = wmt_kpad_release,
+ }
+};
+
+extern int wmt_getsyspara(char *varname, unsigned char *varval, int *varlen);
+
+static int __init kpad_init(void)
+{
+ int i,ret;
+ int retval;
+ unsigned char buf[80];
+ int varlen = 80;
+ char *varname = "wmt.io.kpad";
+ char *p=NULL;
+ int gpio,code;
+
+ DPRINTK(KERN_ALERT "Start\n");
+ retval = wmt_getsyspara(varname, buf, &varlen);
+ if (retval == 0) {
+ sscanf(buf,"%d:", &key_num);
+ if (key_num <= 0)
+ return -ENODEV;
+ p = buf;
+ for(i=0; i.
+
+WonderMedia Technologies, Inc.
+10F, 529, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C.
+--*/
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+
+/* #define COUNTTIMER */
+#ifdef COUNTTIMER
+unsigned int start_time;
+#endif
+
+/* Debug macros */
+#if 0
+#define DPRINTK(fmt, args...) printk(KERN_ALERT "[%s]: " fmt, __func__ , ## args)
+#else
+#define DPRINTK(fmt, args...)
+#endif
+
+/* the shortest response time is 20 ms, original timeout (HZ/100)*100 */
+#define wmt_saradc_timeout ((HZ/100)*2)
+#define WMT_SARADC_FUNCTION_NUM 6
+#define SAMETIMES 2
+unsigned int HW_Hz;
+unsigned int SW_timeout;
+unsigned int INT_timeout;
+
+enum adc_func {
+ FUNC_KPAD,
+ FUNC_BAT,
+ FUNC_NONE,
+};
+unsigned int func = FUNC_NONE;
+
+/* SARADC battery */
+unsigned int BatteryCODE;
+static unsigned int bat_interval = 3;
+static struct delayed_work bat_work;
+
+static unsigned int wmt_saradc_codes[WMT_SARADC_FUNCTION_NUM] = {
+ [0] = KEY_VOLUMEUP,
+ [1] = KEY_VOLUMEDOWN,
+ [2] = KEY_BACK,
+ [3] = KEY_MENU,
+ [4] = KEY_HOME,
+ [5] = KEY_RESERVED,
+};
+
+/*high resolution timer */
+static struct hrtimer wmt_saradc_hrtimer;
+static struct input_dev *saradc_dev;
+
+static struct wmt_saradc_s saradc = {
+ .ref = 0,
+ .res = NULL,
+ .regs = NULL,
+ .irq = 0,
+};
+
+int count_sample_rate(unsigned APB_clock, int Hz)
+{
+ int temp_slot;
+ /* the Hz that we want */
+ temp_slot = APB_clock/(4096 * Hz); /* (APB clock/32)/ (128 * HZ)*/
+ return temp_slot;
+}
+
+static int saradc_sample_rate(unsigned ADC_clock, int Hz)
+{
+ int temp_slot;
+ /* the Hz that we want */
+ temp_slot = ADC_clock/(128 * Hz); /* ADC clock/ (128 * HZ)*/
+ return temp_slot;
+}
+
+int saradc_event_table(unsigned int eventcode)
+{
+ DPRINTK("eventcode = %d\n", eventcode);
+ if (eventcode >= 39 && eventcode <= 42)
+ return 0;
+ else if (eventcode >= 63 && eventcode <= 64)
+ return 1;
+ else if (eventcode >= 84 && eventcode <= 85)
+ return 2;
+ else if (eventcode >= 18 && eventcode <= 20)
+ return 3;
+ else if (eventcode == 0)
+ return 4;
+ else if (eventcode >= 29 && eventcode <= 31)
+ return 5;
+ else if (eventcode == 127)
+ return 5;
+ else
+ return 5;
+}
+
+static void wmt_saradc_hw_init(void)
+{
+ unsigned int auto_temp_slot;
+ //unsigned int APB_clk;
+ unsigned int ADC_clk;
+ DPRINTK("Start\n");
+
+ /*
+ * Turn on saradc clocks.
+ */
+ auto_pll_divisor(DEV_ADC, CLK_ENABLE, 0, 0);
+
+ /* Set the ADC clock to 4.8 MHz */
+ auto_pll_divisor(DEV_ADC, SET_DIV, 1, 4800);
+
+ /* Turn on SARADC controll power */
+ saradc.regs->Ctr0 &= ~PD;
+
+ /* Enable SARADC digital clock */
+ saradc.regs->Ctr0 |= DigClkEn;
+
+ /* Simply clean all previous saradc status. */
+ saradc.regs->Ctr0 |= (ClrIntADC | ClrIntTOut);
+ saradc.regs->Ctr1 |= ClrIntValDet;
+
+ if (((saradc.regs->Ctr2 & EndcIntStatus) == EndcIntStatus) ||
+ ((saradc.regs->Ctr2 & TOutStatus) == TOutStatus) ||
+ ((saradc.regs->Ctr2 & ValDetIntStatus) == ValDetIntStatus))
+ printk(KERN_ERR "[saradc] clear status failed! status = %x\n", saradc.regs->Ctr2);
+
+ /*Set Timeout Value*/
+ saradc.regs->Ctr0 &= 0xffff0000;
+ saradc.regs->Ctr0 |= TOutDly(0xffff);
+
+ /* get APB clock & count sample rate*/
+ ADC_clk = auto_pll_divisor(DEV_ADC, GET_FREQ, 0, 0);
+ DPRINTK("[%s] ADC_clk = %d\n", __func__, ADC_clk);
+ /* sample rate: 500 Hz , 1 ms/sample */
+ auto_temp_slot = saradc_sample_rate(ADC_clk, 500);
+#if 0
+ /* get APB clock & count sample rate*/
+ APB_clk = auto_pll_divisor(DEV_APB, GET_FREQ, 0, 0);
+ /* sample rate: 1000 Hz , 1 ms/sample */
+ auto_temp_slot = count_sample_rate(APB_clk, HW_Hz);
+ DPRINTK("[%s] APB_clk = %d\n", __func__, APB_clk);
+#endif
+ /*Set Sample Rate*/
+ saradc.regs->Ctr1 &= 0x0000ffff;
+ saradc.regs->Ctr1 |= (auto_temp_slot << 16);
+ DPRINTK("[%s] auto_temp_slot = %x ctr1: %x\n", __func__, auto_temp_slot, saradc.regs->Ctr1);
+ /* Set saradc as auto mode */
+ saradc.regs->Ctr0 |= AutoMode;
+
+ msleep(200);
+
+ /* Enable value changing interrupt and Buffer data valid */
+ saradc.regs->Ctr1 |= (ValDetIntEn | BufRd);
+ /* saradc.regs->Ctr0 |= TOutEn; */
+
+ DPRINTK("End\n");
+}
+
+enum hrtimer_restart wmt_saradc_timeout_hrtimer(struct hrtimer *timer)
+{
+ unsigned int SARCODE = 0xffff;
+ static unsigned int OLDCODE = 0xffff;
+ static int time, same;
+ static bool saradc_flag = 1; /* 0: report event state, 1: get SARCODE value state */
+ int new_event = -1;
+ static int pre_event = -1, button_press;
+ ktime_t ktime;
+ /* count timeout value */
+#ifdef COUNTTIMER
+ unsigned int end_time;
+ end_time = wmt_read_oscr();
+ printk(KERN_ERR "time = %d\n", (end_time - start_time)/3);
+#endif
+ ktime = ktime_set(0, SW_timeout * 1000);
+
+ DPRINTK("[%s] Start\n", __func__);
+ while ((saradc.regs->Ctr2 & EndcIntStatus) == 0)
+ ;
+ SARCODE = SARCode(saradc.regs->Ctr1);
+
+ if (saradc_flag && time < 10) {
+ if ((SARCODE/4 - OLDCODE/4) <= 1 || (SARCODE/4 - OLDCODE/4) >= -1) {
+ same++;
+ DPRINTK("time:%d SARCODE=%u SARCODE/4=%u, OLDCODE=%u, OLDCODE/4=%u, same=%d\n",
+ time, SARCODE, SARCODE/4, OLDCODE, OLDCODE/4, same);
+ if (same == SAMETIMES)
+ saradc_flag = 0; /* get the new event */
+ } else
+ same = 0;
+
+ DPRINTK("time:%d SARCODE=%u SARCODE/4=%u, OLDCODE=%u, OLDCODE/4=%u, same=%d\n",
+ time, SARCODE, SARCODE/4, OLDCODE, OLDCODE/4, same);
+ OLDCODE = SARCODE;
+ time++;
+
+ /* don't call timer when 10th get SARCODE or enough same time */
+ if (time < 10 && same != SAMETIMES) {
+ hrtimer_start(&wmt_saradc_hrtimer, ktime, HRTIMER_MODE_REL);
+ /* count timer from callback function to callback function */
+#ifdef COUNTTIMER
+ start_time = wmt_read_oscr();
+#endif
+ }
+ /* if not get stable SARCODE value in 10 times, report SARACODE is NONE event */
+ if (time == 10 && same != SAMETIMES) {
+ SARCODE = 508;
+ DPRINTK("time %d SARCODE %u", time, SARCODE);
+ }
+ }
+ if (time == 10 || saradc_flag == 0)
+ time = 0;
+
+ /* disable BufRd */
+ saradc.regs->Ctr1 &= ~BufRd;
+
+ new_event = saradc_event_table(SARCODE/4);
+
+ if (SARCODE == 0xffff) {
+ printk(KERN_ERR "Auto mode witn INT test fail\n");
+ /*Disable interrupt*/
+ saradc.regs->Ctr1 &= ~ValDetIntEn;
+ /* Clean all previous saradc status. */
+ saradc.regs->Ctr0 |= (ClrIntTOut | ClrIntADC);
+ saradc.regs->Ctr1 |= ClrIntValDet;
+ } else {
+ /*DPRINTK("Buf_rdata = %u Buf_rdata/4 = %u\n", data, data/4);*/
+ DPRINTK("SARCODE = %u SARCODE/4 = %u\n", SARCODE, SARCODE/4);
+ /*Disable interrupt*/
+ saradc.regs->Ctr1 &= ~ValDetIntEn;
+ /* Clean all previous saradc status. */
+ saradc.regs->Ctr0 |= (ClrIntTOut | ClrIntADC);
+ saradc.regs->Ctr1 |= ClrIntValDet;
+ }
+
+ if (saradc_flag == 0) {
+ /* switch other button means release button*/
+ if ((pre_event != new_event) && (SARCODE/4 != 127)) {
+ button_press = 0;
+ DPRINTK("Different event, pre_event = %d, new_event = %d\n", pre_event, new_event);
+ DPRINTK("WMT_ROW1_KEY_NUM release key = %d, event=%d\n", SARCODE/4, pre_event);
+ input_report_key(saradc_dev, wmt_saradc_codes[pre_event], 0); /* key is release*/
+ input_sync(saradc_dev);
+ }
+
+ if (SARCODE/4 == 127 || SARCODE/4 == 126) { /*Active Low*/
+ DPRINTK("WMT_ROW1_KEY_NUM release key = %d, event=%d\n", SARCODE/4, pre_event);
+ input_report_key(saradc_dev, wmt_saradc_codes[pre_event], 0); /* key is release*/
+ input_sync(saradc_dev);
+ button_press = 0;
+ } else {
+ if (button_press == 0) {
+ DPRINTK("new event = %d\n", new_event);
+ input_report_key(saradc_dev, wmt_saradc_codes[new_event], 1);/* key is press*/
+ input_sync(saradc_dev);
+ DPRINTK("saradc code = %d\n", wmt_saradc_codes[new_event]);
+ button_press = 1;
+ }
+ DPRINTK("WMT_ROW1_KEY_NUM keep press key = %d, event=%d\n", SARCODE/4, new_event);
+ }
+ pre_event = new_event;
+ saradc_flag = 1; /* report new event to Android, get new SARCODE */
+ same = 0;
+ }
+ saradc.regs->Ctr1 |= ValDetIntEn;
+ DPRINTK("[%s] End\n", __func__);
+ return HRTIMER_NORESTART; /* avoid to timer restart */
+}
+
+static irqreturn_t
+saradc_interrupt(int irq, void *dev_id)
+{
+ ktime_t ktime;
+ ktime = ktime_set(0, INT_timeout * 1000); /* ms */
+ DPRINTK("[%s] Start\n", __func__);
+ DPRINTK("status = %x\n", saradc.regs->Ctr2);
+ /* Disable interrupt */
+ /* disable_irq_nosync(saradc.irq);*/
+ saradc.regs->Ctr1 &= ~ValDetIntEn;
+
+ saradc.regs->Ctr1 |= BufRd;
+ /*
+ * Get saradc interrupt status and clean interrput source.
+ */
+
+ /* if (((saradc.regs->Ctr1 & ValDetIntEn) == ValDetIntEn) && */
+ if ((saradc.regs->Ctr2 & ValDetIntStatus) == ValDetIntStatus) {
+ /* clear value chaning interrupt */
+ saradc.regs->Ctr1 |= ClrIntValDet;
+ /* start hrtimer */
+ hrtimer_start(&wmt_saradc_hrtimer, ktime, HRTIMER_MODE_REL);
+
+ /* count timer from interrupt to callback function */
+#ifdef COUNTTIMER
+ start_time = wmt_read_oscr();
+#endif
+ }
+
+ if ((saradc.regs->Ctr2 & ValDetIntStatus) == ValDetIntStatus)
+ printk(KERN_ERR "[saradc] status clear failed!\n");
+
+
+ /* Enable interrupt */
+ /* saradc.regs->Ctr1 |= ValDetIntEn; // enable INT in wmt_saradc_timeout_timer*/
+ DPRINTK("[%s] End\n", __func__);
+ return IRQ_HANDLED;
+}
+
+
+static unsigned int saradc_read(void)
+{
+ int i;
+ int min=0xfff,max=0;
+ int total=0,val;
+
+ for(i=0; i < 7; i++){
+ while ((saradc.regs->Ctr2 & EndcIntStatus) == 0);
+
+ val = SARCode(saradc.regs->Ctr1);
+ //printk("%d--",val);
+
+ if(max < val) max = val;
+ if(min > val) min = val;
+ total +=val;
+ }
+ //printk("value %d\n",(total-max-min)/5);
+ return (total-max-min)/5;
+
+}
+
+/* Read SARADC BATTRTY CODE */
+unsigned int ReadBattery(void)
+{
+ return BatteryCODE;
+}
+EXPORT_SYMBOL_GPL(ReadBattery);
+
+/* Update SARCODE BATTERY CODE */
+static void WriteBattery(unsigned int value)
+{
+ BatteryCODE = value;
+}
+static void saradc_bat_handler(struct work_struct *work)
+{
+ unsigned int sarcode = 0xffff;
+
+ DPRINTK("Start\n");
+ /* disable value change interrupt */
+ saradc.regs->Ctr1 &= ~ValDetIntEn;
+ /* Switch to BATTERY channel and clear INT status */
+ saradc.regs->Ctr0 |= (AdcChSel | ClrIntADC | ClrIntTOut);
+ saradc.regs->Ctr1 |= (ClrIntValDet);
+ msleep(20);
+ //printk("bat:\n");
+ sarcode = saradc_read();
+ WriteBattery(sarcode/4);
+ DPRINTK("sarcode = %d\n", sarcode);
+ /* Switch to ADC channel */
+ saradc.regs->Ctr0 &= ~AdcChSel;
+ /* too early to clear status will cause interrupts */
+ msleep(5);
+ /* Switch to BATTERY channel and clear INT status */
+ saradc.regs->Ctr0 |= (ClrIntADC | ClrIntTOut);
+ saradc.regs->Ctr1 |= (ClrIntValDet);
+
+ /* enable value change interrupt */
+ saradc.regs->Ctr1 |= ValDetIntEn;
+
+ schedule_delayed_work(&bat_work, bat_interval*HZ);
+ DPRINTK("End\n\n\n");
+ return ;
+}
+
+static int saradc_open(struct input_dev *dev)
+{
+ int ret = 0;
+ unsigned int i;
+ DPRINTK("Start saradc.ref = %d\n", saradc.ref);
+
+ if (saradc.ref++) {
+ /* Return success, but not initialize again. */
+ DPRINTK("End 1 saradc.ref=%d\n", saradc.ref);
+ return 0;
+ }
+
+ if (func != FUNC_KPAD)
+ goto bat_init;
+
+ ret = request_irq(saradc.irq, saradc_interrupt, IRQF_DISABLED, "saradc", dev);
+
+ if (ret) {
+ printk(KERN_ERR "%s: Can't allocate irq %d\n", __func__, IRQ_TSC);
+ saradc.ref--;
+ free_irq(saradc.irq, dev);
+ goto saradc_open_out;
+ }
+
+ /* Init hr timer */
+ hrtimer_init(&wmt_saradc_hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
+ wmt_saradc_hrtimer.function = &wmt_saradc_timeout_hrtimer;
+
+ /* Register an input event device. */
+ dev->name = "saradc",
+ dev->phys = "saradc",
+
+ /*
+ * Let kpad to implement key repeat.
+ */
+
+ set_bit(EV_KEY, dev->evbit);
+
+ for (i = 0; i < WMT_SARADC_FUNCTION_NUM; i++)
+ set_bit(wmt_saradc_codes[i], dev->keybit);
+
+
+ dev->keycode = wmt_saradc_codes;
+ dev->keycodesize = sizeof(unsigned int);
+ dev->keycodemax = WMT_SARADC_FUNCTION_NUM;
+
+ /*
+ * For better view of /proc/bus/input/devices
+ */
+ dev->id.bustype = 0;
+ dev->id.vendor = 0;
+ dev->id.product = 0;
+ dev->id.version = 0;
+
+ input_register_device(dev);
+
+bat_init:
+ if (func == FUNC_BAT) {
+ INIT_DELAYED_WORK(&bat_work,saradc_bat_handler);
+ schedule_delayed_work(&bat_work, HZ);
+ }
+
+ wmt_saradc_hw_init();
+
+ DPRINTK("End2\n");
+saradc_open_out:
+ DPRINTK("End3\n");
+ return ret;
+}
+
+static void saradc_close(struct input_dev *dev)
+{
+ DPRINTK("Start\n");
+ if (--saradc.ref) {
+ DPRINTK("End1\n");
+ return;
+ }
+
+ /* Free interrupt resource */
+ free_irq(saradc.irq, dev);
+
+ /*Disable clock*/
+ auto_pll_divisor(DEV_ADC, CLK_DISABLE, 0, 0);
+
+ /* Unregister input device driver */
+ input_unregister_device(dev);
+ DPRINTK("End2\n");
+}
+
+static int wmt_saradc_probe(struct platform_device *pdev)
+{
+ unsigned long base;
+ int ret = 0;
+ DPRINTK("Start\n");
+ saradc_dev = input_allocate_device();
+ if (saradc_dev == NULL) {
+ DPRINTK("End 1\n");
+ return -1;
+ }
+ /*
+ * Simply check resources parameters.
+ */
+ if (pdev->num_resources < 2 || pdev->num_resources > 3) {
+ ret = -ENODEV;
+ goto saradc_probe_out;
+ }
+
+ base = pdev->resource[0].start;
+
+ saradc.irq = pdev->resource[1].start;
+
+ saradc.regs = (struct saradc_regs_s *)ADC_BASE_ADDR;
+
+ if (!saradc.regs) {
+ ret = -ENOMEM;
+ goto saradc_probe_out;
+ }
+
+ saradc_dev->open = saradc_open,
+ saradc_dev->close = saradc_close,
+
+ saradc_open(saradc_dev);
+ DPRINTK("End2\n");
+saradc_probe_out:
+
+#ifndef CONFIG_SKIP_DRIVER_MSG
+ printk(KERN_INFO "WMT saradc driver initialized: %s\n",
+ (ret == 0) ? "ok" : "failed");
+#endif
+ DPRINTK("End3\n");
+ return ret;
+}
+
+static int wmt_saradc_remove(struct platform_device *pdev)
+{
+ DPRINTK("Start\n");
+ saradc_close(saradc_dev);
+
+ /*
+ * Free allocated resource
+ */
+ /*kfree(kpad.res);
+ kpad.res = NULL;
+
+ if (kpad.regs) {
+ iounmap(kpad.regs);
+ kpad.regs = NULL;
+ }*/
+
+ saradc.ref = 0;
+ saradc.irq = 0;
+
+ DPRINTK("End\n");
+ return 0;
+}
+
+static int wmt_saradc_suspend(struct platform_device *pdev, pm_message_t state)
+{
+ DPRINTK("Start\n");
+
+ switch (state.event) {
+ case PM_EVENT_SUSPEND:
+ /*Disable clock*/
+ auto_pll_divisor(DEV_ADC, CLK_DISABLE, 0, 0);
+ break;
+ case PM_EVENT_FREEZE:
+ case PM_EVENT_PRETHAW:
+
+ default:
+ break;
+ }
+
+ DPRINTK("End2\n");
+ return 0;
+}
+
+static int wmt_saradc_resume(struct platform_device *pdev)
+{
+ DPRINTK("Start\n");
+ wmt_saradc_hw_init();
+ DPRINTK("End\n");
+ return 0;
+}
+
+static struct platform_driver wmt_saradc_driver = {
+ .driver.name = "wmt-saradc",
+ .probe = &wmt_saradc_probe,
+ .remove = &wmt_saradc_remove,
+ .suspend = &wmt_saradc_suspend,
+ .resume = &wmt_saradc_resume
+};
+
+static struct resource wmt_saradc_resources[] = {
+ [0] = {
+ .start = ADC_BASE_ADDR,
+ .end = (ADC_BASE_ADDR + 0xFFFF),
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = IRQ_TSC,
+ .end = IRQ_TSC,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device wmt_saradc_device = {
+ .name = "wmt-saradc",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(wmt_saradc_resources),
+ .resource = wmt_saradc_resources,
+};
+
+static int __init saradc_init(void)
+{
+ int ret;
+ int retval;
+ unsigned char buf[80];
+ int varlen = 80;
+ char *varname1 = "wmt.keypad.param";
+ char *varname2 = "wmt.battery.param";
+ char *p;
+ int temp = 0, enable_saradc = 0, function_sel = 0;
+
+ DPRINTK(KERN_ALERT "Start\n");
+ /*read keypad enable*/
+ retval = wmt_getsyspara(varname1, buf, &varlen);
+ if (retval == 0) {
+ sscanf(buf, "%X:%d:%d:%d", &temp, &HW_Hz, &INT_timeout, &SW_timeout);
+ enable_saradc = temp & 0xf;
+ function_sel = (temp >> 4) & 0xf;
+ printk(KERN_ALERT "wmt.keypad.param = %x:%d:%d:%d, enable = %x, function = %x\n",
+ temp, HW_Hz, INT_timeout, SW_timeout, enable_saradc, function_sel);
+
+ if (enable_saradc != 1 || function_sel != 1) {
+ printk(KERN_ALERT "Disable SARADC as keypad function!!\n");
+ goto bat;
+ } else if (enable_saradc == 1 && function_sel == 1)
+ printk(KERN_ALERT "HW_HZ = %d, INT_time = %d, SW_timeout = %d\n",
+ HW_Hz, INT_timeout, SW_timeout);
+ if ((HW_Hz == 0) || (INT_timeout == 0) || (SW_timeout == 0)) {
+ HW_Hz = 1000; /* 1000 Hz */
+ INT_timeout = 20000; /* 20 ms */
+ SW_timeout = 1000; /* 1 ms */
+ printk(KERN_ALERT "wmt.keypad.param isn't correct. Set the default value\n");
+ printk(KERN_ALERT "Default HW_HZ = %d, INT_time = %d, SW_timeout = %d\n",
+ HW_Hz, INT_timeout, SW_timeout);
+ }
+ func = FUNC_KPAD;
+ } else {
+ printk(KERN_ALERT "##Warning: \"wmt.keypad.param\" not find\n");
+ printk(KERN_ALERT "Default wmt.keypad.param = %x\n", temp);
+ //return -ENODEV;
+ }
+
+bat:
+ if (func != FUNC_KPAD) {
+ memset(buf, 0x00,sizeof(buf));
+ /* read battery enable, dev name and */
+ retval = wmt_getsyspara(varname2, buf, &varlen);
+ if (retval == 0) {
+ p = buf;
+ if(!strncmp(p,"saradc", 6)){
+ p = strchr(p,':');
+ if(p){
+ p++;
+ sscanf(p,"%d",&bat_interval);
+ }
+ printk("Bat ADC sample period = %ds\n", bat_interval);
+ func = FUNC_BAT;
+ }
+ }
+ }
+
+ if (func == FUNC_NONE) {
+ printk("SARADC not enable\n");
+ return -ENODEV;
+ }
+
+/* check saradc can switch freq.
+#ifdef CONFIG_CPU_FREQ
+ ret = cpufreq_register_notifier(&kpad_clock_nblock, \
+ CPUFREQ_TRANSITION_NOTIFIER);
+
+ if (ret) {
+ printk(KERN_ERR "Unable to register CPU frequency " \
+ "change notifier (%d)\n", ret);
+ }
+#endif
+*/
+ ret = platform_device_register(&wmt_saradc_device);
+ if (ret != 0) {
+ DPRINTK("End1 ret = %x\n", ret);
+ return -ENODEV;
+ }
+
+ ret = platform_driver_register(&wmt_saradc_driver);
+ DPRINTK("End2 ret = %x\n", ret);
+ return ret;
+}
+
+static void __exit saradc_exit(void)
+{
+ DPRINTK("Start\n");
+ platform_driver_unregister(&wmt_saradc_driver);
+ platform_device_unregister(&wmt_saradc_device);
+ DPRINTK("End\n");
+}
+
+module_init(saradc_init);
+module_exit(saradc_exit);
+
+MODULE_AUTHOR("WonderMedia Technologies, Inc.");
+MODULE_DESCRIPTION("WMT [generic saradc] driver");
+MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/drivers/input/physics_key/Kconfig b/ANDROID_3.4.5/drivers/input/physics_key/Kconfig
new file mode 100755
index 00000000..98178500
--- /dev/null
+++ b/ANDROID_3.4.5/drivers/input/physics_key/Kconfig
@@ -0,0 +1,27 @@
+#
+# Input core configuration
+#
+config INPUT_PKEY
+ bool "physics_key" if EMBEDDED || !X86
+ default y
+ depends on INPUT
+ help
+ Say Y here, and a list of supported remote control devices will
+ be displayed. This option doesn't affect the kernel.
+
+ If unsure, say y.
+
+config PKEY_WonderMedia
+ tristate "WonderMedia physics_key support" if !PC
+ default y
+ depends on INPUT && INPUT_PKEY
+ help
+ Say Y here if you want remote control support for WonderMedia.
+
+ If unsure, say Y.
+
+ To compile this driver as a module, choose M here: the
+ module will be called wmt-pkey.
+
+
+
diff --git a/ANDROID_3.4.5/drivers/input/physics_key/Makefile b/ANDROID_3.4.5/drivers/input/physics_key/Makefile
new file mode 100755
index 00000000..f6c7a3f7
--- /dev/null
+++ b/ANDROID_3.4.5/drivers/input/physics_key/Makefile
@@ -0,0 +1,41 @@
+#
+# Makefile for the input core drivers.
+#
+
+# Each configuration option enables a list of files.
+
+KERNELDIR=../../../
+#KERNELDIR=/home/hangyan/android8850/kernel/ANDROID_3.0.8
+CROSS = arm_1103_le-
+CC= $(CROSS)gcc
+LD= $(CROSS)ld
+STRIP = $(CROSS)strip
+
+DEBUG = n
+
+# Add your debugging flag (or not) to EXTRA_CFLAGS
+ifeq ($(DEBUG),y)
+# DEBFLAGS = -O -g -DSCULL_DEBUG # "-O" is needed to expand inlines
+DEBFLAGS = -O0 -g -DSCULL_DEBUG # "-O" is needed to expand inlines
+
+else
+ DEBFLAGS = -O2 -Wall
+endif
+
+EXTRA_CFLAGS += $(DEBFLAGS)
+
+
+MY_MODULE_NAME=wmt-pkey
+
+$(MY_MODULE_NAME)-objs := pkey.o
+obj-m := $(MY_MODULE_NAME).o
+
+
+default:
+ $(MAKE) -C $(KERNELDIR) SUBDIRS=$(PWD) modules
+ $(STRIP) --strip-debug $(MY_MODULE_NAME).ko
+ rm -rf *.o *~ core .depend .*.cmd *.mod.c .tmp_versions
+
+clean:
+ rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions *.order *.symvers
+
diff --git a/ANDROID_3.4.5/drivers/input/physics_key/pkey.c b/ANDROID_3.4.5/drivers/input/physics_key/pkey.c
new file mode 100755
index 00000000..429b57f3
--- /dev/null
+++ b/ANDROID_3.4.5/drivers/input/physics_key/pkey.c
@@ -0,0 +1,261 @@
+/*++
+ *
+ * WonderMedia input remote control driver
+ *
+ * Copyright c 2010 WonderMedia Technologies, Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ * WonderMedia Technologies, Inc.
+ * 4F, 533, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C
+--*/
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+
+#include
+#include
+#include
+
+
+static struct pkey_pdata {
+ unsigned int gpio_no;
+
+ struct input_dev *idev;
+ struct timer_list *p_key_timer;
+ unsigned long timer_expires;
+};
+
+static int key_codes[2]={KEY_F1,KEY_BACK};
+
+static inline void physics_key_timeout(unsigned long fcontext)
+{
+ struct pkey_pdata *p_key = (struct pkey_pdata *)fcontext;
+ int keycode;
+
+ keycode = __gpio_get_value(p_key->gpio_no)?key_codes[1]:key_codes[0];
+
+ input_report_key(p_key->idev, keycode, 1);
+ input_sync(p_key->idev);
+ mdelay(50);
+ input_report_key(p_key->idev, keycode, 0);
+ input_sync(p_key->idev);
+
+ p_key->timer_expires = 0;
+}
+
+static irqreturn_t physics_key_isr(int irq, void *dev_id)
+{
+ unsigned long expires;
+ struct pkey_pdata *p_key = (struct pkey_pdata *)dev_id;
+
+ if(gpio_irqstatus(p_key->gpio_no))
+ {
+
+ wmt_gpio_ack_irq(p_key->gpio_no);
+ expires = jiffies + msecs_to_jiffies(50);
+ if (!expires)
+ expires = 1;
+
+ if(!(p_key->timer_expires) || time_after(expires, p_key->timer_expires)){
+ mod_timer(p_key->p_key_timer, expires);
+ p_key->timer_expires = expires;
+ }
+
+ return IRQ_HANDLED;
+ }
+
+ return IRQ_NONE;
+}
+
+static int hw_init(struct platform_device *pdev)
+{
+ struct pkey_pdata *p_key = pdev->dev.platform_data;
+
+
+ int ret = gpio_request(p_key->gpio_no,"physics_key");
+ if(ret < 0) {
+ printk(KERN_ERR"gpio request fail for physics_key\n");
+ return ret;
+ }
+
+ gpio_direction_input(p_key->gpio_no);
+ wmt_gpio_set_irq_type(p_key->gpio_no,IRQ_TYPE_EDGE_BOTH);
+ wmt_gpio_unmask_irq(p_key->gpio_no);
+
+ request_irq(IRQ_GPIO, physics_key_isr, IRQF_SHARED, "physics_key", p_key);
+
+ return 0;
+}
+
+static int physics_key_probe(struct platform_device *pdev)
+{
+ int i;
+ struct pkey_pdata *p_key = pdev->dev.platform_data;
+
+ hw_init(pdev);
+
+ if ((p_key->idev = input_allocate_device()) == NULL)
+ return -ENOMEM;
+
+ set_bit(EV_KEY, p_key->idev->evbit);
+ for (i = 0; i < ARRAY_SIZE(key_codes); i++) {
+ set_bit(key_codes[i], p_key->idev->keybit);
+ }
+
+ p_key->idev->name = "physics_key";
+ p_key->idev->phys = "physics_key";
+ input_register_device(p_key->idev);
+
+ p_key->p_key_timer = (struct timer_list *)kzalloc(sizeof(struct timer_list), GFP_KERNEL);
+ init_timer(p_key->p_key_timer);
+ p_key->p_key_timer->data = (unsigned long)p_key;
+ p_key->p_key_timer->function = physics_key_timeout;
+
+
+ return 0;
+}
+
+static int physics_key_remove(struct platform_device *dev)
+{
+ struct pkey_pdata *p_key = dev->dev.platform_data;
+
+ if(p_key->p_key_timer)
+ {
+ del_timer_sync(p_key->p_key_timer);
+ free_irq(IRQ_GPIO, p_key);
+ input_unregister_device(p_key->idev);
+ input_free_device(p_key->idev);
+
+ kfree(p_key);
+ }
+
+ return 0;
+}
+
+void pkey_pdevice_release(struct device *dev)
+{
+
+}
+
+#ifdef CONFIG_PM
+static int physics_key_suspend(struct platform_device *dev, pm_message_t state)
+{
+ struct pkey_pdata *p_key = dev->dev.platform_data;
+
+ del_timer_sync(p_key->p_key_timer);
+
+ wmt_gpio_mask_irq(p_key->gpio_no);
+
+ return 0;
+}
+
+static int physics_key_resume(struct platform_device *dev)
+{
+ struct pkey_pdata *p_key = dev->dev.platform_data;
+
+ wmt_gpio_set_irq_type(p_key->gpio_no,IRQ_TYPE_EDGE_BOTH);
+ wmt_gpio_unmask_irq(p_key->gpio_no);
+
+ return 0;
+}
+#else
+#define physics_key_suspend NULL
+#define physics_key_resume NULL
+#endif
+
+
+
+
+static struct platform_device pkey_pdevice = {
+ .name = "physics_key",
+ .id = 0,
+ .dev = {
+ .release = pkey_pdevice_release,
+ },
+};
+
+static struct platform_driver pkey_driver = {
+ .probe = physics_key_probe,
+ .remove = physics_key_remove,
+ .suspend = physics_key_suspend,
+ .resume = physics_key_resume,
+
+ .driver = {
+ .name = "physics_key",
+ },
+};
+
+extern int wmt_getsyspara(char *varname, unsigned char *varval, int *varlen);
+
+static int __init physics_key_init(void)
+{
+ char buf[128];
+ int ret = 0;
+ int varlen;
+ int ubootvar[1];
+
+
+ memset(buf ,0, sizeof(buf));
+ varlen = sizeof(buf);
+ if (wmt_getsyspara("wmt.gpo.physics_switch", buf, &varlen)) {
+ printk(KERN_ERR"wmt.gpo.physics_switch isn't set in u-boot env! -> Use default\n");
+ return -1;
+ }
+ ret = sscanf(buf, "%d",
+ &ubootvar[0]
+ );
+
+ struct pkey_pdata *p_key = (struct pkey_pdata *)kzalloc(sizeof(struct pkey_pdata), GFP_KERNEL);
+ if (p_key == NULL)
+ return -ENOMEM;
+
+ p_key->gpio_no = ubootvar[0];
+
+ pkey_pdevice.dev.platform_data = (void *)p_key;
+
+ if (platform_device_register(&pkey_pdevice))
+ return -1;
+
+ ret = platform_driver_register(&pkey_driver);
+
+ return ret;
+}
+
+static void __exit physics_key_exit(void)
+{
+ platform_driver_unregister(&pkey_driver);
+ platform_device_unregister(&pkey_pdevice);
+}
+
+module_init(physics_key_init);
+module_exit(physics_key_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("WonderMedia Technologies, Inc.");
+MODULE_DESCRIPTION("WMT driver");
+
diff --git a/ANDROID_3.4.5/drivers/input/remote_input.c b/ANDROID_3.4.5/drivers/input/remote_input.c
new file mode 100755
index 00000000..b5919416
--- /dev/null
+++ b/ANDROID_3.4.5/drivers/input/remote_input.c
@@ -0,0 +1,195 @@
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+
+#define INPUT_IOC_MAGIC 'x'
+#define INPUT_IOC_CMD_INPUT _IOR(INPUT_IOC_MAGIC, 1, int)
+#define INPUT_IOC_MAXNR 1
+
+static struct input_dev *g_input = NULL;
+static int lcdX, lcdY;
+static int g_Major;
+static struct mutex ioc_mutex;
+static struct class *dev_class = NULL;
+
+extern int wmt_getsyspara(char *varname, unsigned char *varval, int *varlen);
+
+static struct input_dev *input_dev_alloc(void)
+{
+ int err;
+ struct input_dev *input_dev;
+ input_dev = input_allocate_device();
+ if (!input_dev) {
+ printk("failed to allocate input device\n");
+ return NULL;
+ }
+
+ input_dev->name = "remote_input";
+ input_dev->evbit[0] = BIT_MASK(EV_SYN) | BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS) | BIT_MASK(EV_REL);
+ set_bit(INPUT_PROP_DIRECT, input_dev->propbit);
+ //set_bit(ABS_MT_TRACKING_ID, input_dev->absbit);
+
+ input_set_abs_params(input_dev,
+ ABS_MT_POSITION_X, 0, lcdX, 0, 0);
+ input_set_abs_params(input_dev,
+ ABS_MT_POSITION_Y, 0, lcdY, 0, 0);
+ //input_set_abs_params(input_dev,
+ // ABS_MT_TRACKING_ID, 0, 5, 0, 0);
+
+ set_bit(KEY_BACK, input_dev->keybit);
+ set_bit(KEY_HOME, input_dev->keybit);
+ set_bit(KEY_MENU, input_dev->keybit);
+ set_bit(KEY_SEARCH, input_dev->keybit);
+
+ set_bit(KEY_ENTER, input_dev->keybit);
+ set_bit(KEY_UP, input_dev->keybit);
+ set_bit(KEY_PAGEUP, input_dev->keybit);
+ set_bit(KEY_LEFT, input_dev->keybit);
+ set_bit(KEY_RIGHT, input_dev->keybit);
+ set_bit(KEY_DOWN, input_dev->keybit);
+ set_bit(KEY_PAGEDOWN, input_dev->keybit);
+ set_bit(KEY_VOLUMEDOWN, input_dev->keybit);
+ set_bit(KEY_VOLUMEUP, input_dev->keybit);
+
+ set_bit(BTN_LEFT, input_dev->keybit);
+ set_bit(BTN_RIGHT, input_dev->keybit);
+ set_bit(BTN_MIDDLE, input_dev->keybit);
+ set_bit(BTN_SIDE, input_dev->keybit);
+
+ set_bit(REL_X, input_dev->relbit);
+ set_bit(REL_Y, input_dev->relbit);
+ set_bit(REL_WHEEL, input_dev->relbit);
+
+ err = input_register_device(input_dev);
+ if (err) {
+ printk("input_dev_alloc: failed to register input device.\n");
+ input_free_device(input_dev);
+ input_dev = NULL;
+ }
+
+ return input_dev;
+}
+
+static long input_ioctl(struct file *dev, unsigned int cmd, unsigned long arg)
+{
+ struct input_event event;
+ if (_IOC_TYPE(cmd) != INPUT_IOC_MAGIC){
+ printk("CMD ERROR!");
+ return -ENOTTY;
+ }
+
+ if (_IOC_NR(cmd) > INPUT_IOC_MAXNR){
+ printk("NO SUCH IO CMD!\n");
+ return -ENOTTY;
+ }
+
+ switch (cmd) {
+ case INPUT_IOC_CMD_INPUT:
+ copy_from_user(&event, (struct input_event*)arg, sizeof(struct input_event));
+ mutex_lock(&ioc_mutex);
+ input_event(g_input, event.type, event.code, event.value);
+ mutex_unlock(&ioc_mutex);
+ return 0;
+ }
+ return -EINVAL;
+}
+
+static int input_open(struct inode *inode, struct file *filp)
+{
+ int ret = 0;
+ return ret;
+}
+
+static int input_close(struct inode *inode, struct file *filp)
+{
+ return 0;
+}
+
+
+static struct file_operations input_fops = {
+ .unlocked_ioctl = input_ioctl,
+ .open = input_open,
+ .release = input_close,
+};
+
+
+static int __init remote_init(void)
+{
+ struct device *dev = NULL;
+ int len = 127;
+ char retval[128] = {0},*p=NULL;
+ int tmp[6];
+
+ mutex_init(&ioc_mutex);
+
+ if (wmt_getsyspara("wmt.display.fb0", retval, &len)) {
+ printk(KERN_ERR "Can't get display param. \n");
+ return -EIO;
+ }
+ p = retval;
+ sscanf(p, "%d:[%d:%d:%d:%d:%d", &tmp[0], &tmp[1], &tmp[2], &tmp[3], &tmp[4], &tmp[5]);
+ lcdX = tmp[4];
+ lcdY = tmp[5];
+
+ g_input = input_dev_alloc();
+ if (!g_input){
+ printk(KERN_ERR "Alloc input device failed. \n");
+ return -ENODEV;
+ }
+
+ if ((g_Major = register_chrdev(0, "remote_input", &input_fops)) < 0) {
+ printk(KERN_ERR "Can't register char device. \n");
+ return -EIO;
+ }
+
+ dev_class = class_create(THIS_MODULE,"remote_input");
+ if (IS_ERR(dev_class)) {
+ unregister_chrdev(g_Major, "remote_input");
+ printk(KERN_ERR "Class create failed. \n");
+ return PTR_ERR(dev_class);
+ }
+
+ dev = device_create(dev_class, NULL, MKDEV(g_Major, 0), NULL,"remote_input");
+ if(!dev){
+ printk(KERN_ERR "Create device failed. \n");
+ return -ENODEV;
+ }
+
+ return 0;
+}
+module_init(remote_init);
+
+static void __exit remote_exit(void)
+{
+ device_destroy(dev_class, MKDEV(g_Major, 0));
+ class_destroy(dev_class);
+ unregister_chrdev(g_Major, "remote_input");
+
+ input_unregister_device(g_input);
+ //input_free_device(g_input);
+ mutex_destroy(&ioc_mutex);
+}
+module_exit(remote_exit);
+
+MODULE_DESCRIPTION("Remote Input driver");
+MODULE_LICENSE("GPL v2");
diff --git a/ANDROID_3.4.5/drivers/input/rmtctl/Kconfig b/ANDROID_3.4.5/drivers/input/rmtctl/Kconfig
new file mode 100755
index 00000000..f95174a0
--- /dev/null
+++ b/ANDROID_3.4.5/drivers/input/rmtctl/Kconfig
@@ -0,0 +1,25 @@
+#
+# Input core configuration
+#
+config INPUT_RMTCTL
+ bool "Remote controllers" if EMBEDDED || !X86
+ default y
+ depends on INPUT
+ help
+ Say Y here, and a list of supported remote control devices will
+ be displayed. This option doesn't affect the kernel.
+
+ If unsure, say Y.
+
+config RMTCTL_WonderMedia
+ tristate "WonderMedia remote control support" if !PC
+ default y
+ depends on INPUT && INPUT_RMTCTL
+ help
+ Say Y here if you want remote control support for WonderMedia.
+
+ If unsure, say Y.
+
+ To compile this driver as a module, choose M here: the
+ module will be called atkbd.
+
diff --git a/ANDROID_3.4.5/drivers/input/rmtctl/Makefile b/ANDROID_3.4.5/drivers/input/rmtctl/Makefile
new file mode 100755
index 00000000..7a9a2167
--- /dev/null
+++ b/ANDROID_3.4.5/drivers/input/rmtctl/Makefile
@@ -0,0 +1,8 @@
+#
+# Makefile for the input core drivers.
+#
+
+# Each configuration option enables a list of files.
+
+obj-$(CONFIG_RMTCTL_WonderMedia) += wmt-rmtctl.o
+
diff --git a/ANDROID_3.4.5/drivers/input/rmtctl/oem-dev.h b/ANDROID_3.4.5/drivers/input/rmtctl/oem-dev.h
new file mode 100755
index 00000000..7066753e
--- /dev/null
+++ b/ANDROID_3.4.5/drivers/input/rmtctl/oem-dev.h
@@ -0,0 +1,186 @@
+/*++
+ * linux/drivers/input/rmtctl/oem-dev-table.h
+ * WonderMedia input remote control driver
+ *
+ * Copyright c 2012 WonderMedia Technologies, Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ * WonderMedia Technologies, Inc.
+ * 4F, 533, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C
+--*/
+#ifndef OEM_DEV_TABLE_H
+/* To assert that only one occurrence is included */
+#define OEM_DEV_TABLE_H
+
+#ifdef OEM_DEV_TABLE_H
+ #define EXTERN
+#else
+ #define EXTERN extern
+#endif /* ifdef OEM_DEV_TABLE_H */
+
+
+#define RMCTL_WMT_1
+#define RMCTL_WMT_2
+#define RMCTL_TV_BOX
+
+
+EXTERN struct rmt_dev {
+ char *vendor_name;
+ int vender_id;
+ unsigned int key_codes[128];
+};
+
+
+EXTERN struct rmt_dev rmt_dev_tbl[ ] = {
+ #ifdef RMCTL_WMT_1
+ {
+ .vendor_name = "WMT_1",
+ .vender_id = 0x00ff,
+ .key_codes = {
+ [0] = KEY_POWER,
+ [1] = KEY_RESERVED,
+ [2] = KEY_RESERVED,
+ [3] = KEY_MUTE,
+ [4] = KEY_CLEAR,
+ [5] = KEY_UP,
+ [6] = KEY_ESC,
+ [7] = KEY_SCREEN, /* P/N */
+ [8] = KEY_LEFT,
+ [9] = KEY_ENTER,
+ [10] = KEY_RIGHT,
+ [11] = KEY_SETUP,
+ [12] = KEY_F1,
+ [13] = KEY_DOWN,
+ [14] = KEY_F2,
+ [15] = KEY_STOP,
+ [16] = KEY_1,
+ [17] = KEY_2,
+ [18] = KEY_3,
+ [19] = KEY_TIME,
+ [20] = KEY_4,
+ [21] = KEY_5,
+ [22] = KEY_6,
+ [23] = KEY_PLAYPAUSE,
+ [24] = KEY_7,
+ [25] = KEY_8,
+ [26] = KEY_9,
+ [27] = KEY_VOLUMEUP,
+ [28] = KEY_0,
+ [29] = KEY_BACK,
+ [30] = KEY_FORWARD,
+ [31] = KEY_VOLUMEDOWN
+ },
+ },
+ #endif
+ #ifdef RMCTL_WMT_2
+ {
+ .vendor_name = "WMT_2",
+ .vender_id = 0x40bf,
+ .key_codes = {
+ [0] = KEY_RESERVED, /* KARAOKE */
+ [1] = KEY_RESERVED, /* FUN- */
+ [2] = KEY_RESERVED, /* ANGLE */
+ [3] = KEY_VOLUMEDOWN,
+ [4] = KEY_CLEAR,
+ [5] = KEY_0,
+ [6] = KEY_F1, /* DIGEST */
+ [7] = KEY_ZOOM,
+ [8] = KEY_7,
+ [9] = KEY_8,
+ [10] = KEY_NEXT,
+ [11] = KEY_VOLUMEUP,
+ [12] = KEY_4,
+ [13] = KEY_5,
+ [14] = KEY_POWER,
+ [15] = KEY_MUTE,
+ [16] = KEY_1,
+ [17] = KEY_2,
+ [18] = KEY_SUBTITLE,
+ [19] = KEY_RESERVED, /* RETURN */
+ [20] = KEY_RECORD,
+ [21] = KEY_RESERVED, /* STEP */
+ [22] = KEY_RESERVED, /* A-B */
+ [23] = KEY_RESERVED, /* STEP B*/
+ [24] = KEY_BACK,
+ [25] = KEY_PLAY,
+ [26] = KEY_EJECTCD,
+ [27] = KEY_RESERVED, /* FF */
+ [28] = KEY_LEFT,
+ [29] = KEY_DOWN,
+ [30] = KEY_F2, /* Menu/PBC */
+ [31] = KEY_PLAYPAUSE, /* SF */
+ /* Keycode 32 - 63 are invalid. */
+ [64] = KEY_AUDIO,
+ [65] = KEY_SETUP,
+ [66] = KEY_RESERVED, /* FUN+ */
+ [67] = KEY_RESERVED, /* MARK */
+ [68] = KEY_UP,
+ [69] = KEY_RESERVED, /* +10 */
+ [70] = KEY_RESERVED, /* INVALID */
+ [71] = KEY_RESERVED, /* SURR */
+ [72] = KEY_RIGHT,
+ [73] = KEY_9,
+ [74] = KEY_RESERVED, /* INVALID */
+ [75] = KEY_RESERVED, /* VOCAL */
+ [76] = KEY_TV,
+ [77] = KEY_6,
+ [78] = KEY_RESERVED, /* INVALID */
+ [79] = KEY_PROGRAM, /* PROG */
+ [80] = KEY_RESERVED, /* DISPLAY */
+ [81] = KEY_3,
+ [82] = KEY_RESERVED, /* INVALID */
+ [83] = KEY_RESERVED, /* INVALID */
+ [84] = KEY_GOTO,
+ [85] = KEY_PREVIOUS, /* Prev/ASV- */
+ [86] = KEY_RESERVED, /* INVALID */
+ [87] = KEY_RESERVED, /* INVALID */
+ [88] = KEY_RESERVED, /* Repeat */
+ [89] = KEY_STOP,
+ [90] = KEY_RESERVED, /* INVALID */
+ [91] = KEY_RESERVED, /* INVALID */
+ [92] = KEY_ENTER,
+ [93] = KEY_TITLE
+ },
+ },
+ #endif
+ #ifdef RMCTL_TV_BOX
+ {
+ .vendor_name = "TV_BOX",
+ .vender_id = 0x2fd,
+ .key_codes = {
+ [0x57] = KEY_END, /* power down */
+ [0x56] = KEY_VOLUMEDOWN, /* vol- */
+ [0x14] = KEY_VOLUMEUP, /* vol+ */
+ [0x53] = KEY_HOME, /* home */
+ [0x11] = KEY_MENU, /* menu */
+ [0x10] = KEY_BACK, /* back */
+ [0x4b] = KEY_ZOOMOUT, /* zoom out */
+ [0x08] = KEY_ZOOMIN, /* zoom in */
+ [0x0d] = KEY_UP, /* up */
+ [0x4e] = KEY_LEFT, /* left */
+ [0x19] = KEY_REPLY, /* OK */
+ [0x0c] = KEY_RIGHT, /* right */
+ [0x4f] = KEY_DOWN, /* down */
+ [0x09] = KEY_PAGEUP, /* page up */
+ [0x47] = KEY_REWIND, /* rewind */
+ [0x05] = KEY_PAGEDOWN, /* page down */
+ [0x04] = KEY_FASTFORWARD /* forward */
+ },
+ },
+ #endif
+};
+#undef EXTERN
+
+#endif
diff --git a/ANDROID_3.4.5/drivers/input/rmtctl/wmt-rmtctl.c b/ANDROID_3.4.5/drivers/input/rmtctl/wmt-rmtctl.c
new file mode 100755
index 00000000..44f3b30b
--- /dev/null
+++ b/ANDROID_3.4.5/drivers/input/rmtctl/wmt-rmtctl.c
@@ -0,0 +1,1515 @@
+/*++
+ * linux/drivers/input/rmtctl/wmt-rmtctl.c
+ * WonderMedia input remote control driver
+ *
+ * Copyright c 2010 WonderMedia Technologies, Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ * WonderMedia Technologies, Inc.
+ * 4F, 533, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C
+--*/
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "wmt-rmtctl.h"
+
+enum CIR_CODEC_TYPE {
+ CIR_CODEC_NEC = 0,
+ CIR_CODEC_TOSHIBA = 1,
+ CIR_CODEC_PHILIPS_RC6 = 2,
+ CIR_CODEC_MAX,
+};
+
+struct cir_param {
+ enum CIR_CODEC_TYPE codec;
+ unsigned int param[7];
+ unsigned int repeat_timeout;
+};
+
+struct cir_vendor_info {
+ char *vendor_name;
+ enum CIR_CODEC_TYPE codec;
+
+ unsigned int vendor_code;
+ unsigned int wakeup_code;
+ unsigned int key_codes[258]; // usb-keyboard standard
+};
+
+#define RMTCTL_DEBUG 0
+#define REL_DELTA 20
+#define WMT_RMTCTL_VENDOR_ENV "wmt.io.rmtctl.vendorcode"
+struct rmtctl_led{
+ int gpio;
+ int active;
+ int on;
+ int enable;
+ struct timer_list timer;
+};
+
+struct rmtctl_rel {
+ int on;
+ unsigned int code;
+ struct timer_list timer;
+ struct input_dev *input;
+};
+
+struct rmtctl_priv {
+ enum CIR_CODEC_TYPE codec;
+ int vendor_index;
+ int table_index;
+ unsigned int saved_vcode;
+ unsigned int vendor_code;
+ unsigned int scan_code;
+
+ struct input_dev *idev;
+ struct timer_list timer;
+ struct delayed_work delaywork;
+
+ struct rmtctl_led led;//led control
+
+ struct rmtctl_rel rel_dev;//remote cursor removing
+};
+
+static struct cir_param rmtctl_params[] = {
+ // NEC : |9ms carrier wave| + |4.5ms interval|
+ [CIR_CODEC_NEC] = {
+ .codec = CIR_CODEC_NEC,
+ .param = { 0x10a, 0x8e, 0x42, 0x55, 0x9, 0x13, 0x13 },
+ .repeat_timeout = 17965000,
+ },
+
+ // TOSHIBA : |4.5ms carrier wave| + |4.5ms interval|
+ [CIR_CODEC_TOSHIBA] = {
+ .codec = CIR_CODEC_TOSHIBA,
+ .param = { 0x8e, 0x8e, 0x42, 0x55, 0x9, 0x13, 0x13 },
+ .repeat_timeout = 17965000,
+ },
+
+ [CIR_CODEC_PHILIPS_RC6] = {
+ .codec = CIR_CODEC_PHILIPS_RC6,
+ .param = { 0x7, 0x15, 0x23, 0x31, 0x40, 0x4C, 0x5B },
+ .repeat_timeout = 17965000,
+ },
+};
+
+static struct cir_vendor_info rmtctl_vendors[] = {
+ // SRC1804 0
+ {
+ .vendor_name = "SRC1804",
+ .codec = CIR_CODEC_NEC,
+ .vendor_code = 0x02fd,
+ .wakeup_code = 0x57,
+ .key_codes = {
+ [0x57] = KEY_POWER, /* power down */
+ [0x56] = KEY_VOLUMEDOWN, /* vol- */
+ [0x14] = KEY_VOLUMEUP, /* vol+ */
+ [0x53] = KEY_HOME, /* home */
+ [0x11] = KEY_MENU, /* menu */
+ [0x10] = KEY_BACK, /* back */
+ [0x4b] = KEY_ZOOMOUT, /* zoom out */
+ [0x08] = KEY_ZOOMIN, /* zoom in */
+ [0x0d] = KEY_UP, /* up */
+ [0x4e] = KEY_LEFT, /* left */
+ [0x19] = KEY_ENTER, /* OK */
+ [0x0c] = KEY_RIGHT, /* right */
+ [0x4f] = KEY_DOWN, /* down */
+ [0x09] = KEY_PAGEUP, /* page up */
+ [0x47] = KEY_PREVIOUSSONG, /* rewind */
+ [0x05] = KEY_PAGEDOWN, /* page down */
+ [0x04] = KEY_NEXTSONG /* forward */
+ },
+ },
+
+ // IH8950 1
+ {
+ .vendor_name = "IH8950",
+ .codec = CIR_CODEC_NEC,
+ .vendor_code = 0x0909,
+ .wakeup_code = 0xdc,
+ .key_codes = {
+ [0xdc] = KEY_POWER, /* power down */
+ [0x81] = KEY_VOLUMEDOWN, /* vol- */
+ [0x80] = KEY_VOLUMEUP, /* vol+ */
+ [0x82] = KEY_HOME, /* home */
+ [0xc5] = KEY_BACK, /* back */
+ [0xca] = KEY_UP, /* up */
+ [0x99] = KEY_LEFT, /* left */
+ [0xce] = KEY_ENTER, /* OK */
+ [0xc1] = KEY_RIGHT, /* right */
+ [0xd2] = KEY_DOWN, /* down */
+ [0x9c] = KEY_MUTE,
+ [0x95] = KEY_PLAYPAUSE,
+ [0x88] = KEY_MENU,
+ },
+ },
+
+ // sunday 2
+ {
+ .vendor_name = "sunday",
+ .codec = CIR_CODEC_NEC,
+ .vendor_code = 0x02fd,
+ .wakeup_code = 0x1a,
+ .key_codes = {
+ [0x1a] = KEY_POWER, /* power down */
+ [0x16] = KEY_VOLUMEDOWN, /* vol- */
+ [0x44] = KEY_VOLUMEUP, /* vol+ */
+ [0x59] = KEY_HOME, /* home */
+ [0x1b] = KEY_BACK, /* back */
+ [0x06] = KEY_UP, /* up */
+ [0x5d] = KEY_LEFT, /* left */
+ [0x1e] = KEY_ENTER, /* OK */
+ [0x5c] = KEY_RIGHT, /* right */
+ [0x1f] = KEY_DOWN, /* down */
+ [0x55] = KEY_PLAYPAUSE,
+ [0x54] = KEY_REWIND,
+ [0x17] = KEY_FASTFORWARD,
+ [0x58] = KEY_AGAIN, /* recent app */
+ },
+ },
+
+ /* F1 - F12 */
+ // KT-9211 3
+ {
+ .vendor_name = "KT-9211",
+ .codec = CIR_CODEC_NEC,
+ .vendor_code = 0x02fd,
+ .wakeup_code = 0x57,
+ .key_codes = {
+ [0x57] = KEY_POWER, /* power down */
+ [0x56] = KEY_VOLUMEDOWN, /* volume- */
+ [0x15] = KEY_MUTE, /* mute */
+ [0x14] = KEY_VOLUMEUP, /* volume+ */
+ [0x0d] = KEY_UP, /* up */
+ [0x4e] = KEY_LEFT, /* left */
+ [0x19] = KEY_ENTER, /* OK */
+ [0x0c] = KEY_RIGHT, /* right */
+ [0x4f] = KEY_DOWN, /* down */
+ [0x53] = KEY_HOME, /* home */
+ [0x09] = KEY_F5, /* my photo in default */
+ [0x11] = KEY_F12, /* setting apk in default */
+ [0x47] = KEY_F3, /* My Music in default */
+ [0x10] = KEY_BACK, /* Back */
+ [0x08] = KEY_F4, /* my video in default */
+ [0x17] = KEY_F1, /* web browser in default */
+
+ //Following items are configured manually.
+ [0x05] = KEY_F10, /* file browser in default */
+ [0x04] = KEY_F2, /* camera in default */
+ [0x4b] = KEY_F11, /* calendar in default */
+ [0x16] = KEY_SCREEN, /* calculator in default */
+ [0x18] = KEY_F9, /* recorder in default */
+ },
+ },
+
+ // KT-8830 4
+ {
+ .vendor_name = "KT-8830",
+ .codec = CIR_CODEC_NEC,
+ .vendor_code = 0x866b,
+ .wakeup_code = 0x1c,
+ .key_codes = {
+ [0x1c] = KEY_POWER,
+ [0x14] = KEY_MUTE,
+ [0x09] = KEY_1,
+ [0x1d] = KEY_2,
+ [0x1f] = KEY_3,
+ [0x0d] = KEY_4,
+ [0x19] = KEY_5,
+ [0x1b] = KEY_6,
+ [0x11] = KEY_7,
+ [0x15] = KEY_8,
+ [0x17] = KEY_9,
+ [0x12] = KEY_0,
+ [0x16] = KEY_VOLUMEDOWN,
+ [0x04] = KEY_VOLUMEUP,
+ [0x40] = KEY_HOME,
+ [0x4c] = KEY_BACK,
+ [0x00] = KEY_F12, // setup
+ [0x13] = KEY_MENU,
+ [0x03] = KEY_UP,
+ [0x0e] = KEY_LEFT,
+ [0x1a] = KEY_RIGHT,
+ [0x02] = KEY_DOWN,
+ [0x07] = KEY_ENTER,
+ [0x47] = KEY_F4, // video
+ [0x10] = KEY_F3, // music
+ [0x0f] = KEY_FASTFORWARD,
+ [0x43] = KEY_REWIND,
+ [0x18] = KEY_F1, // browser
+ [0x0b] = KEY_YEN, // multi-functions
+ [0x4e] = KEY_PLAYPAUSE,
+ },
+ },
+
+ // Haier-OTT 5
+ {
+ .vendor_name = "Haier-OTT",
+ .codec = CIR_CODEC_NEC,
+ .vendor_code = 0xb34c,
+ .wakeup_code = 0xdc,
+ .key_codes = {
+ [0xdc] = KEY_POWER,
+ [0x9c] = KEY_MUTE,
+ [0xca] = KEY_UP,
+ [0x99] = KEY_LEFT,
+ [0xc1] = KEY_RIGHT,
+ [0xd2] = KEY_DOWN,
+ [0xce] = KEY_ENTER,
+ [0x80] = KEY_VOLUMEDOWN,
+ [0x81] = KEY_VOLUMEUP,
+ [0xc5] = KEY_HOME,
+ [0x95] = KEY_BACK,
+ [0x88] = KEY_MENU,
+ [0x82] = KEY_F12, /* setting apk in default */
+ },
+ },
+
+ // GPRC-11933 6
+ {
+ .vendor_name = "GPRC-11933",
+ .codec = CIR_CODEC_NEC,
+ .vendor_code = 0x4040,
+ .wakeup_code = 0x4D,
+ .key_codes = {
+ [0x4D] = KEY_POWER, /* power down */
+ [0x53] = KEY_PLAYPAUSE,
+ [0x5B] = KEY_F3, /* My Music in default */
+ [0x57] = KEY_F1, /* web browser in default */
+ [0x54] = KEY_F10, /* file browser in default */
+
+ [0x17] = KEY_VOLUMEDOWN, /* volume- */
+ [0x43] = KEY_MUTE, /* mute */
+ [0x18] = KEY_VOLUMEUP, /* volume+ */
+ [0x1F] = KEY_PREVIOUSSONG, /* rewind */
+ [0x1E] = KEY_NEXTSONG, /* forward */
+
+ [0x0B] = KEY_UP, /* up */
+ [0x10] = KEY_LEFT, /* left */
+ [0x0D] = KEY_ENTER, /* OK */
+ [0x11] = KEY_RIGHT, /* right */
+ [0x0E] = KEY_DOWN, /* down */
+ [0x1A] = KEY_HOME, /* home */
+ [0x42] = KEY_BACK, /* Back */
+
+ [0x45] = KEY_F12, /* setting apk in default */
+ [0x47] = KEY_KATAKANA, /* multi-functions */
+ [0x01] = KEY_1,
+ [0x02] = KEY_2,
+ [0x03] = KEY_3,
+ [0x04] = KEY_4,
+ [0x05] = KEY_5,
+ [0x06] = KEY_6,
+ [0x07] = KEY_7,
+ [0x08] = KEY_8,
+ [0x09] = KEY_9,
+ [0x00] = KEY_0,
+ [0x44] = KEY_MENU,
+ [0x0C] = KEY_BACKSPACE,
+ },
+ },
+
+ // TS-Y118 7
+ {
+ .vendor_name = "TS-Y118",
+ .codec = CIR_CODEC_NEC,
+ .vendor_code = 0xb34c,
+ .wakeup_code = 0xdc,
+ .key_codes = {
+ [0xdc] = KEY_POWER,
+ [0x9c] = KEY_MUTE,
+ [0x8d] = KEY_F12, // apk-settings
+ [0x88] = KEY_HOME,
+ [0xca] = KEY_UP,
+ [0xd2] = KEY_DOWN,
+ [0x99] = KEY_LEFT,
+ [0xc1] = KEY_RIGHT,
+ [0xce] = KEY_ENTER,
+ [0x95] = KEY_PLAYPAUSE,
+ [0xc5] = KEY_BACK,
+ [0x80] = KEY_VOLUMEUP,
+ [0x81] = KEY_VOLUMEDOWN,
+ [0xdd] = KEY_PAGEUP,
+ [0x8c] = KEY_PAGEDOWN,
+ [0x92] = KEY_1,
+ [0x93] = KEY_2,
+ [0xcc] = KEY_3,
+ [0x8e] = KEY_4,
+ [0x8f] = KEY_5,
+ [0xc8] = KEY_6,
+ [0x8a] = KEY_7,
+ [0x8b] = KEY_8,
+ [0xc4] = KEY_9,
+ [0x87] = KEY_0,
+ },
+ },
+
+ // Hisense 8
+ {
+ .vendor_name = "Hisense",
+ .codec = CIR_CODEC_NEC,
+ .vendor_code = 0x00ff,
+ .wakeup_code = 0x14,
+ .key_codes = {
+ [0x14] = KEY_POWER,
+ [0x1c] = KEY_MUTE,
+ [0x40] = KEY_PAGEUP,
+ [0x44] = KEY_PAGEDOWN,
+ [0x0b] = KEY_VOLUMEUP,
+ [0x58] = KEY_VOLUMEDOWN,
+ [0x01] = KEY_MENU,
+ [0x03] = KEY_UP,
+ [0x02] = KEY_DOWN,
+ [0x0e] = KEY_LEFT,
+ [0x1a] = KEY_RIGHT,
+ [0x07] = KEY_ENTER,
+ [0x48] = KEY_HOME,
+ [0x5c] = KEY_BACK,
+ [0x09] = KEY_1,
+ [0x1d] = KEY_2,
+ [0x1f] = KEY_3,
+ [0x0d] = KEY_4,
+ [0x19] = KEY_5,
+ [0x1b] = KEY_6,
+ [0x11] = KEY_7,
+ [0x15] = KEY_8,
+ [0x17] = KEY_9,
+ [0x12] = KEY_0,
+ [0x06] = KEY_DOT,
+ [0x16] = KEY_DELETE,
+ [0x0c] = KEY_ZOOMIN,
+ [0x4c] = KEY_F11,
+ [0x13] = KEY_YEN,
+ },
+ },
+
+ // Mountain 9
+ {
+ .vendor_name = "TV BOX Mountain",
+ .codec = CIR_CODEC_NEC,
+ .vendor_code = 0x00df,
+ .wakeup_code = 0x1c,
+ .key_codes = {
+ [0x1c] = KEY_POWER, /* power down */
+ [0x08] = KEY_MUTE, /* volume mute */
+ [0x1a] = KEY_UP, /* up */
+ [0x47] = KEY_LEFT, /* left */
+ [0x06] = KEY_ENTER, /* OK */
+ [0x07] = KEY_RIGHT, /* right */
+ [0x48] = KEY_DOWN, /* down */
+ [0x4f] = KEY_VOLUMEDOWN, /* vol- */
+ [0x4b] = KEY_VOLUMEUP, /* vol+ */
+ [0x0a] = KEY_BACK, /* back */
+ [0x03] = KEY_HOME, /* home */
+ [0x42] = KEY_KATAKANA, /* TV */
+ [0x55] = KEY_MENU, /* menu */
+ },
+ },
+
+ // GPRC-11933 10
+ {
+ .vendor_name = "GPRC-11933A",
+ .codec = CIR_CODEC_NEC,
+ .vendor_code = 0x00FF,
+ .wakeup_code = 0x57,
+ .key_codes = {
+ [0x57] = KEY_POWER, /* power down */
+ [0x5B] = KEY_MUTE, /* mute */
+
+ [0x16] = KEY_F3, /* My Musicin default */
+ [0x5A] = KEY_F1, /* web browser in default */
+ [0x52] = KEY_PLAYPAUSE,
+ [0x50] = KEY_KATAKANA, /* cursor */
+
+ [0x0F] = KEY_PREVIOUSSONG, /* rewind */
+ [0x4C] = KEY_NEXTSONG, /* forward */
+ [0x58] = KEY_VOLUMEDOWN, /* volume- */
+ [0x1B] = KEY_VOLUMEUP, /* volume+ */
+
+ [0x4F] = KEY_F12, /* setting apk in default */
+ [0x1A] = KEY_MENU,
+
+ [0x43] = KEY_UP, /* up */
+
+ [0x06] = KEY_LEFT, /* left */
+ [0x02] = KEY_ENTER, /* OK */
+ [0x0E] = KEY_RIGHT, /* right */
+
+ [0x0A] = KEY_DOWN, /* down */
+
+ [0x4E] = KEY_HOME, /* home */
+ [0x4D] = KEY_BACK, /* back */
+
+ [0x10] = KEY_1,
+ [0x11] = KEY_2,
+ [0x12] = KEY_3,
+ [0x13] = KEY_4,
+ [0x14] = KEY_5,
+ [0x15] = KEY_6,
+ [0x17] = KEY_7,
+ [0x18] = KEY_8,
+ [0x19] = KEY_9,
+ [0x1D] = KEY_0,
+
+ [0x1C] = KEY_F1,
+ [0x1E] = KEY_BACKSPACE,
+ },
+ },
+
+ //China Telecom White 11
+ {
+ .vendor_name = "TS-Y118A",
+ .codec = CIR_CODEC_NEC,
+ .vendor_code = 0xb34c,
+ .wakeup_code = 0xdc,
+ .key_codes = {
+ [0xdc] = KEY_POWER,
+
+ [0x98] =KEY_AUDIO,
+ [0x9c] = KEY_MUTE,
+
+ [0x8d] = KEY_SETUP,
+ [0xd6] = KEY_LAST,
+
+ [0xcd] = KEY_RED,
+ [0x91] = KEY_GREEN,
+ [0x83] = KEY_YELLOW,
+ [0xc3] = KEY_BLUE,
+
+ [0x88] = KEY_HOMEPAGE,
+ [0xca] = KEY_UP,
+ [0x82] = KEY_HOME,
+
+ [0x99] = KEY_LEFT,
+ [0xce] = KEY_SELECT,
+ [0xc1] = KEY_RIGHT,
+
+ [0x95] = KEY_PLAYPAUSE,
+ [0xd2] = KEY_DOWN,
+ [0xc5] = KEY_BACK,
+
+ [0x80] = KEY_VOLUMEUP,
+ [0x81] = KEY_VOLUMEDOWN,
+
+ [0xdd] = KEY_PAGEUP,
+ [0x8c] = KEY_PAGEDOWN,
+
+ [0x85] = KEY_CHANNELUP,
+ [0x86] = KEY_CHANNELDOWN,
+
+ [0x92] = KEY_1,
+ [0x93] = KEY_2,
+ [0xcc] = KEY_3,
+ [0x8e] = KEY_4,
+ [0x8f] = KEY_5,
+ [0xc8] = KEY_6,
+ [0x8a] = KEY_7,
+ [0x8b] = KEY_8,
+ [0xc4] = KEY_9,
+ [0x87] = KEY_0,
+
+ [0xda] = KEY_NUMERIC_STAR,
+ [0xd0] = KEY_NUMERIC_POUND,
+ },
+ },
+
+ //China Telecom Black 12
+ {
+ .vendor_name = "TS-Y118B",
+ .codec = CIR_CODEC_NEC,
+ .vendor_code = 0xb24d,
+ .wakeup_code = 0xdc,
+ .key_codes = {
+ [0xdc] = KEY_POWER,
+
+ [0x98] =KEY_AUDIO,
+ [0x9c] = KEY_MUTE,
+
+ [0x8d] = KEY_SETUP,
+ [0xd6] = KEY_LAST,
+
+ [0xcd] = KEY_RED,
+ [0x91] = KEY_GREEN,
+ [0x83] = KEY_YELLOW,
+ [0xc3] = KEY_BLUE,
+
+ [0x88] = KEY_HOMEPAGE,
+ [0xca] = KEY_UP,
+ [0x82] = KEY_HOME,
+
+ [0x99] = KEY_LEFT,
+ [0xce] = KEY_SELECT,
+ [0xc1] = KEY_RIGHT,
+
+ [0x95] = KEY_PLAYPAUSE,
+ [0xd2] = KEY_DOWN,
+ [0xc5] = KEY_BACK,
+
+ [0x80] = KEY_VOLUMEUP,
+ [0x81] = KEY_VOLUMEDOWN,
+
+ [0xdd] = KEY_PAGEUP,
+ [0x8c] = KEY_PAGEDOWN,
+
+ [0x85] = KEY_CHANNELUP,
+ [0x86] = KEY_CHANNELDOWN,
+
+ [0x92] = KEY_1,
+ [0x93] = KEY_2,
+ [0xcc] = KEY_3,
+ [0x8e] = KEY_4,
+ [0x8f] = KEY_5,
+ [0xc8] = KEY_6,
+ [0x8a] = KEY_7,
+ [0x8b] = KEY_8,
+ [0xc4] = KEY_9,
+ [0x87] = KEY_0,
+
+ [0xda] = KEY_NUMERIC_STAR,
+ [0xd0] = KEY_NUMERIC_POUND,
+ },
+ },
+
+ // Jensen 13
+ {
+ .vendor_name = "Jensen",
+ .codec = CIR_CODEC_NEC,
+ .vendor_code = 0x00ff,
+ .wakeup_code = 0x46,
+ .key_codes = {
+ [0x08] = KEY_RESERVED,
+
+ [0x5a] = KEY_VOLUMEUP,
+ [0x4a] = KEY_VOLUMEDOWN,
+
+ [0x19] = KEY_UP,
+ [0x1c] = KEY_DOWN,
+ [0x0c] = KEY_LEFT,
+ [0x5e] = KEY_RIGHT,
+ [0x18] = KEY_ENTER,
+
+ [0x0d] = KEY_BACK,
+ [0x45] = KEY_1,
+ [0x46] = KEY_POWER,
+ [0x47] = KEY_3,
+ [0x44] = KEY_4,
+ [0x40] = KEY_F1,
+ [0x43] = KEY_6,
+ [0x07] = KEY_7,
+ [0x15] = KEY_BACK,
+ [0x09] = KEY_9,
+ [0x16] = KEY_0,
+
+ [0x42] = KEY_PREVIOUSSONG, /* rewind */
+ [0x52] = KEY_NEXTSONG, /* forward */
+
+ },
+ },
+ // Foxconn 14
+ {
+ .vendor_name = "CIR-9F",
+ .codec = CIR_CODEC_NEC,
+ .vendor_code = 0x009f,
+ .wakeup_code = 0x57,
+ .key_codes = {
+ [0x57] = KEY_POWER, /* power */
+ [0x5d] = KEY_VOLUMEDOWN, /* vol- */
+ [0xff] = KEY_VOLUMEUP, /* vol+ */
+ [0x47] = KEY_HOME, /* home */
+ [0x16] = KEY_MENU, /* menu */
+ [0x4f] = KEY_BACK, /* back */
+ [0x43] = KEY_UP, /* up */
+ [0x06] = KEY_LEFT, /* left */
+ [0x02] = KEY_ENTER, /* PLAYPAUSE */
+ //[0x02] = KEY_PLAYPAUSE, /* PLAYPAUSE */
+ [0x0e] = KEY_RIGHT, /* right */
+ [0x0a] = KEY_DOWN, /* down */
+ [0x0b] = KEY_REWIND, /* rewind data is 0x36*/
+ [0x0f] = KEY_FASTFORWARD, /* forward */
+
+ [0x5b] = KEY_ENTER /* OK - notify */
+ },
+ },
+
+ // Philips 15
+ {
+ .vendor_name = "PHILIPS",
+ .codec = CIR_CODEC_PHILIPS_RC6,
+ .vendor_code = 60,
+ .wakeup_code = 12,
+ .key_codes = {
+ [12] = KEY_POWER,
+ [146] = KEY_HOME,
+ [84] = KEY_MENU,
+ [92] = KEY_ENTER,
+ [88] = KEY_UP,
+ [89] = KEY_DOWN,
+ [90] = KEY_LEFT,
+ [91] = KEY_RIGHT,
+ [83] = BTN_DEAD,
+ [131] = KEY_BACK,
+ },
+ },
+
+ //Ronsheng 16
+ {
+ .vendor_name = "Ronsheng",
+ .codec = CIR_CODEC_NEC,
+ .vendor_code = 0x00FF,
+ .wakeup_code = 0x18,
+ .key_codes = {
+ [0x18] = KEY_POWER, /* power down */
+
+ [0x56] = KEY_F3, /* My Musicin default */
+ [0x57] = KEY_F1, /* web browser in default */
+
+ [0x1f] = KEY_PREVIOUSSONG, /* rewind */
+ [0x5b] = KEY_NEXTSONG, /* forward */
+
+ [0x14] = KEY_VOLUMEDOWN, /* volume- */
+ [0x08] = KEY_MUTE, /* mute */
+ [0x10] = KEY_VOLUMEUP, /* volume+ */
+
+ [0x17] = KEY_KATAKANA, /* cursor */
+ [0x04] = KEY_MENU,
+
+ [0x46] = KEY_UP, /* up */
+ [0x47] = KEY_LEFT, /* left */
+ [0x55] = KEY_ENTER, /* OK */
+ [0x15] = KEY_RIGHT, /* right */
+ [0x16] = KEY_DOWN, /* down */
+
+ [0x06] = KEY_HOME, /* home */
+ [0x40] = KEY_BACK, /* back */
+
+ [0x54] = KEY_1,
+ [0x48] = KEY_2,
+ [0x07] = KEY_3,
+ [0x50] = KEY_4,
+ [0x12] = KEY_5,
+ [0x11] = KEY_6,
+ [0x4c] = KEY_7,
+ [0x0e] = KEY_8,
+ [0x0d] = KEY_9,
+ [0x0c] = KEY_0,
+ [0x41] = KEY_RESERVED,
+ [0x4b] = KEY_BACKSPACE,
+
+ },
+ },
+
+ // GPRC-11933 17
+ {
+ .vendor_name = "GPRC-11933",
+ .codec = CIR_CODEC_NEC,
+ .vendor_code = 0x4040,
+ .wakeup_code = 0x4D,
+ .key_codes = {
+ [0x4D] = KEY_POWER, /* power down */
+ [0x53] = KEY_F1,
+ [0x5B] = KEY_F2,
+ [0x57] = KEY_F3,
+ [0x54] = KEY_F4,
+
+ [0x17] = KEY_VOLUMEDOWN, /* volume- */
+ [0x43] = KEY_MUTE, /* mute */
+ [0x18] = KEY_VOLUMEUP, /* volume+ */
+
+ [0x1F] = KEY_F12, /* setting */
+ [0x1E] = KEY_F5,
+
+ [0x0B] = KEY_UP, /* up */
+ [0x10] = KEY_LEFT, /* left */
+ [0x0D] = KEY_ENTER, /* OK */
+ [0x11] = KEY_RIGHT, /* right */
+ [0x0E] = KEY_DOWN, /* down */
+ [0x1A] = KEY_HOME, /* home */
+ [0x47] = KEY_BACK, /* Back */
+
+ [0x45] = KEY_MENU, /* MENU */
+ [0x42] = KEY_KATAKANA, /* multi-functions */
+ [0x01] = KEY_1,
+ [0x02] = KEY_2,
+ [0x03] = KEY_3,
+ [0x04] = KEY_4,
+ [0x05] = KEY_5,
+ [0x06] = KEY_6,
+ [0x07] = KEY_7,
+ [0x08] = KEY_8,
+ [0x09] = KEY_9,
+ [0x00] = KEY_0,
+ [0x44] = KEY_AGAIN,
+ [0x0C] = KEY_BACKSPACE,
+ },
+ },
+
+
+};
+
+extern int wmt_getsyspara(char *varname, unsigned char *varval, int *varlen);
+extern int wmt_setsyspara(char *varname, char *varval);
+
+static int rmtctl_report_rel(struct rmtctl_rel *rel_dev,const unsigned int code )
+{
+ switch (code) {
+ case KEY_UP:
+ input_report_rel(rel_dev->input, REL_X, 0);
+ input_report_rel(rel_dev->input, REL_Y, -REL_DELTA);
+ input_sync(rel_dev->input);
+ break;
+ case KEY_DOWN:
+ input_report_rel(rel_dev->input, REL_X, 0);
+ input_report_rel(rel_dev->input, REL_Y, REL_DELTA);
+ input_sync(rel_dev->input);
+ break;
+ case KEY_LEFT:
+ input_report_rel(rel_dev->input, REL_X, -REL_DELTA);
+ input_report_rel(rel_dev->input, REL_Y, 0);
+ input_sync(rel_dev->input);
+ break;
+ case KEY_RIGHT:
+ input_report_rel(rel_dev->input, REL_X, REL_DELTA);
+ input_report_rel(rel_dev->input, REL_Y, 0);
+ input_sync(rel_dev->input);
+ break;
+ default:
+ break;
+ }
+ return 0;
+}
+
+static void rmtctl_report_event(unsigned int *code, int repeat)
+{
+ static unsigned int last_code = KEY_RESERVED;
+ int ret;
+ struct rmtctl_priv *priv = container_of(code, struct rmtctl_priv, scan_code);
+
+ ret = del_timer(&priv->timer);
+
+ if (!repeat) {
+ // new code coming
+ if (ret == 1) {
+ // del_timer() of active timer returns 1 means that active timer has been stoped by new key,
+ // so report last key up event
+ if (RMTCTL_DEBUG)
+ printk("[%d] up reported caused by new key[%d]\n", last_code, *code);
+
+ if (priv->rel_dev.on) {
+ switch (*code) {
+ case KEY_UP:
+ case KEY_DOWN:
+ case KEY_LEFT:
+ case KEY_RIGHT:
+ del_timer(&priv->rel_dev.timer); //stop report mouse
+ break;
+ case KEY_ENTER:
+ input_report_key(priv->rel_dev.input, BTN_LEFT, 0);
+ input_sync(priv->rel_dev.input);
+ del_timer(&priv->rel_dev.timer); //stop report mouse
+ break;
+ default:
+ input_report_key(priv->idev, last_code, 0);
+ input_sync(priv->idev);
+ break;
+ }
+ }
+ else {
+ input_report_key(priv->idev, last_code, 0);
+ input_sync(priv->idev);
+ }
+
+ if (*code == KEY_KATAKANA) {
+ if (priv->rel_dev.on == 0) {
+ input_report_rel(priv->rel_dev.input, REL_X, 1);
+ input_report_rel(priv->rel_dev.input, REL_Y, 1);
+ input_sync(priv->rel_dev.input);
+ priv->rel_dev.on = 1;
+ }
+ else
+ priv->rel_dev.on = 0;
+ }
+
+ }
+
+ if (RMTCTL_DEBUG)
+ printk("[%d] down\n", *code);
+
+ // report key down event, mod_timer() to report key up event later for measure key repeat.
+
+ if (priv->rel_dev.on) {
+ switch (*code) {
+ case KEY_UP:
+ case KEY_DOWN:
+ case KEY_LEFT:
+ case KEY_RIGHT:
+ rmtctl_report_rel(&priv->rel_dev,*code);
+ break;
+ case KEY_ENTER:
+ input_report_key(priv->rel_dev.input, BTN_LEFT, 1);
+ input_sync(priv->rel_dev.input);
+ break;
+ default:
+ input_event(priv->idev, EV_KEY, *code, 1);
+ input_sync(priv->idev);
+ break;
+ }
+ }
+ else {
+ input_event(priv->idev, EV_KEY, *code, 1);
+ input_sync(priv->idev);
+ }
+
+ if(priv->led.enable){
+ priv->led.on = 0;
+ gpio_direction_output(priv->led.gpio, !priv->led.active);
+ mod_timer(&priv->led.timer, jiffies+HZ/20);
+ }
+
+ priv->timer.data = (unsigned long)code;
+ mod_timer(&priv->timer, jiffies + 250*HZ/1000);
+ }
+ else {
+ // report key up event after report repeat event according to usb-keyboard standard
+ priv->timer.data = (unsigned long)code;
+ mod_timer(&priv->timer, jiffies + 250*HZ/1000);
+
+ // detect 'repeat' flag, report repeat event
+ if (*code != KEY_POWER && *code != KEY_END) {
+ if (RMTCTL_DEBUG)
+ printk("[%d] repeat\n", *code);
+
+ if (priv->rel_dev.on) {
+ switch (*code) {
+ case KEY_UP:
+ case KEY_DOWN:
+ case KEY_LEFT:
+ case KEY_RIGHT:
+ case KEY_ENTER:
+ priv->rel_dev.code = *code;
+ mod_timer(&priv->rel_dev.timer, jiffies+HZ/100); //ready to repeat report mouse event
+ break;
+ default:
+ input_event(priv->idev, EV_KEY, *code, 2);
+ input_sync(priv->idev);
+ break;
+ }
+ }
+ else {
+ input_event(priv->idev, EV_KEY, *code, 2);
+ input_sync(priv->idev);
+ }
+ }
+ }
+
+ last_code = *code;
+}
+
+/** no hw repeat detect, so we measure repeat timeout event by timer */
+static void rmtctl_report_event_without_hwrepeat(unsigned int *code)
+{
+ static unsigned int last_code = KEY_RESERVED;
+ static unsigned long last_jiffies = 0;
+ int repeat = (jiffies_to_msecs(jiffies - last_jiffies) <250 && *code==last_code) ? 1 : 0;
+
+ last_code = *code;
+ last_jiffies = jiffies;
+
+ rmtctl_report_event(code, repeat);
+}
+
+static void rmtctl_timer_handler(unsigned long data)
+{
+ struct rmtctl_priv *priv = container_of((void *)data, struct rmtctl_priv, scan_code);
+ unsigned int code = *(unsigned int *)data;
+
+ // report key up event
+ if (RMTCTL_DEBUG)
+ printk("[%d] up reported by timer\n", code);
+
+ if (priv->rel_dev.on) {
+ switch (code) {
+ case KEY_UP:
+ case KEY_DOWN:
+ case KEY_LEFT:
+ case KEY_RIGHT:
+ del_timer(&priv->rel_dev.timer);
+ break;
+ case KEY_ENTER:
+ input_report_key(priv->rel_dev.input, BTN_LEFT, 0);
+ input_sync(priv->rel_dev.input);
+ break;
+ default:
+ input_report_key(priv->idev, code, 0);
+ input_sync(priv->idev);
+ break;
+ }
+ }
+ else {
+ input_report_key(priv->idev, code, 0);
+ input_sync(priv->idev);
+ }
+
+ if (code == KEY_KATAKANA) {
+ if (priv->rel_dev.on == 0) {
+ input_report_rel(priv->rel_dev.input, REL_X, 1);
+ input_report_rel(priv->rel_dev.input, REL_Y, 1);
+ input_sync(priv->rel_dev.input);
+ priv->rel_dev.on = 1;
+ }
+ else
+ priv->rel_dev.on = 0;
+ }
+
+ if(priv->led.enable){
+ del_timer_sync(&priv->led.timer);
+ gpio_direction_output(priv->led.gpio,priv->led.active);
+ }
+}
+
+static irqreturn_t rmtctl_interrupt(int irq, void *dev_id)
+{
+ unsigned int status, ir_data, ir_code,vendor, repeat;
+ unsigned char *key;
+ int i;
+
+ struct rmtctl_priv *priv = (struct rmtctl_priv *)dev_id;
+
+ /* get IR status. */
+ status = REG32_VAL(IRSTS);
+
+ /* check 'IR received data' flag. */
+ if ((status & 0x1) == 0x0) {
+ printk("IR IRQ was triggered without data received. (0x%x)\n",
+ status);
+ return IRQ_NONE;
+ }
+
+ /* read IR data. */
+ ir_data = REG32_VAL(IRDATA(0)) ;
+ key = (char *) &ir_data;
+
+ /* clear INT status*/
+ REG32_VAL(IRSTS)=0x1 ;
+
+ if (RMTCTL_DEBUG){
+ printk("ir_data = 0x%08x, status = 0x%x \n", ir_data, status);
+ }
+
+ if(priv->codec == CIR_CODEC_PHILIPS_RC6){
+ vendor = key[1];
+ ir_code = key[0];
+ //trailer = key[2] & 0x01;
+ }
+ else{//NEC
+ /* get vendor ID. */
+ vendor = (key[0] << 8) | (key[1]);
+
+ /* check if key is valid. Key[3] is XORed t o key[2]. */
+ if (key[2] & key[3]) {
+ printk("Invalid IR key received. (0x%x, 0x%x)\n", key[2], key[3]);
+ return IRQ_NONE;
+ }
+
+ /* keycode mapping. */
+ ir_code = key[2];
+ }
+
+ if ( priv->vendor_index >= 0 ) {
+ if (vendor == rmtctl_vendors[priv->vendor_index].vendor_code &&
+ rmtctl_vendors[priv->vendor_index].codec == priv->codec) {
+ priv->table_index = priv->vendor_index;
+ priv->scan_code = rmtctl_vendors[priv->vendor_index].key_codes[ir_code];
+ }
+ else{
+ if(vendor != priv->vendor_code){
+ for (i = 0; i < ARRAY_SIZE(rmtctl_vendors); i++) {
+ if (vendor == rmtctl_vendors[i].vendor_code &&
+ rmtctl_vendors[i].codec == priv->codec) {
+ priv->table_index = i;
+ priv->scan_code = rmtctl_vendors[i].key_codes[ir_code];
+ break;
+ }
+ }
+
+ if(i==ARRAY_SIZE(rmtctl_vendors))
+ return IRQ_HANDLED;
+ }
+ else{
+ priv->scan_code = rmtctl_vendors[priv->table_index].key_codes[ir_code];
+ }
+ }
+ }
+ else {
+ if(vendor != priv->vendor_code){
+ for (i = 0; i < ARRAY_SIZE(rmtctl_vendors); i++) {
+ if (vendor == rmtctl_vendors[i].vendor_code &&
+ rmtctl_vendors[i].codec == priv->codec) {
+ priv->table_index = i;
+ priv->scan_code = rmtctl_vendors[i].key_codes[ir_code];
+ break;
+ }
+ }
+
+ if(i==ARRAY_SIZE(rmtctl_vendors))
+ return IRQ_HANDLED;
+ }
+ else{
+ priv->scan_code = rmtctl_vendors[priv->table_index].key_codes[ir_code];
+ }
+ }
+
+ //switch to a new remote controller shoud reset cursor mode
+ if (priv->vendor_code != vendor)
+ priv->rel_dev.on = 0;
+
+
+ if ((status & 0x2) || (priv->scan_code == KEY_RESERVED)) {
+ /* ignore repeated or reserved keys. */
+ }
+ else if (priv->codec == CIR_CODEC_NEC) {
+ /* check 'IR code repeat' flag. */
+ repeat = status & 0x10;
+ rmtctl_report_event(&priv->scan_code, repeat);
+ }
+ else if(priv->codec == CIR_CODEC_PHILIPS_RC6){
+ //repeat = !(trailer^key[2]);
+ //trailer = key[2];
+ //printk("RCV philips rc6,repeat=%d\n",repeat);
+
+ rmtctl_report_event_without_hwrepeat(&priv->scan_code);
+ }
+ else {
+ rmtctl_report_event_without_hwrepeat(&priv->scan_code);
+ }
+
+ if (priv->vendor_code != vendor) {
+ priv->vendor_code = vendor;
+ /* save new vendor code to env
+ *1.remote controller configed index is active, no need to save it's vendor code
+ *2.current vendor code is saved, no need to save again
+ */
+ if(priv->table_index != priv->vendor_index && vendor != priv->saved_vcode){
+ priv->saved_vcode = vendor;
+ //schedule_delayed_work(&priv->delaywork, msecs_to_jiffies(20));
+ }
+ }
+
+ return IRQ_HANDLED;
+}
+
+static void rmtctl_hw_suspend(unsigned long data)
+{
+ unsigned int wakeup_code;
+ int i;
+ struct rmtctl_priv *priv = (struct rmtctl_priv *)data;
+
+ if (priv->vendor_index >= 0 && priv->vendor_index == priv->table_index) {
+ i = priv->vendor_index;
+ }
+ else {
+ for (i = 0; i < ARRAY_SIZE(rmtctl_vendors); i++)
+ if (priv->vendor_code == rmtctl_vendors[i].vendor_code &&
+ priv->codec == rmtctl_vendors[i].codec)
+ break;
+
+ if (i == ARRAY_SIZE(rmtctl_vendors))
+ goto out;
+ }
+
+ if(priv->codec == CIR_CODEC_PHILIPS_RC6){
+ wakeup_code =
+ ((unsigned char)(rmtctl_vendors[i].vendor_code & 0xff) << 8) |
+ (unsigned char)(rmtctl_vendors[i].wakeup_code) ;
+ REG32_VAL(WAKEUP_CMD2(0)) = 0x10000| wakeup_code;
+ }else{
+ wakeup_code =
+ ((unsigned char)(~rmtctl_vendors[i].wakeup_code) << 24) |
+ ((unsigned char)(rmtctl_vendors[i].wakeup_code) << 16 ) |
+ ((unsigned char)(rmtctl_vendors[i].vendor_code & 0xff) << 8) |
+ ((unsigned char)((rmtctl_vendors[i].vendor_code) >> 8) << 0 );
+
+ }
+ REG32_VAL(WAKEUP_CMD1(0)) = wakeup_code;
+ REG32_VAL(WAKEUP_CMD1(1)) = 0x0;
+ REG32_VAL(WAKEUP_CMD1(2)) = 0x0;
+ REG32_VAL(WAKEUP_CMD1(3)) = 0x0;
+ REG32_VAL(WAKEUP_CMD1(4)) = 0x0;
+
+out:
+ REG32_VAL(WAKEUP_CTRL) = 0x101;
+}
+
+static void rmtctl_hw_init(unsigned long data)
+{
+ unsigned int st;
+ int i, retries = 0;
+ struct rmtctl_priv *priv = (struct rmtctl_priv *)data;
+
+ /*setting shared pin*/
+ GPIO_CTRL_GP62_WAKEUP_SUS_BYTE_VAL &= 0xFFFD;
+ PULL_EN_GP62_WAKEUP_SUS_BYTE_VAL |= 0x02;
+ PULL_CTRL_GP62_WAKEUP_SUS_BYTE_VAL |= 0x02;
+
+ /* turn off CIR SW reset. */
+ REG32_VAL(IRSWRST) = 1;
+ REG32_VAL(IRSWRST) = 0;
+
+ for (i = 0; i < ARRAY_SIZE(rmtctl_params[priv->codec].param); i++)
+ REG32_VAL(PARAMETER(i)) = rmtctl_params[priv->codec].param[i];
+
+ if (priv->codec == CIR_CODEC_NEC || priv->codec == CIR_CODEC_TOSHIBA) {
+ printk("NEC\n");
+ REG32_VAL(NEC_REPEAT_TIME_OUT_CTRL) = 0x1;
+ REG32_VAL(NEC_REPEAT_TIME_OUT_COUNT) = rmtctl_params[priv->codec].repeat_timeout;
+ REG32_VAL(IRCTL) = 0X100; //NEC repeat key
+ }
+ else if(priv->codec == CIR_CODEC_PHILIPS_RC6){
+ printk("PHILIPS RC6\n");
+ REG32_VAL(IRCTL) =0x40; //PHILIPS RC6
+ REG32_VAL(INT_MASK_COUNT) = 40*1000000*1/4;
+ //REG32_VAL(IRCTL_2) =0xFE;//Enable PHILIPS RC6 mode 0,Mask mode1-7 ?
+ }else{
+ REG32_VAL(IRCTL) = 0; //NEC repeat key
+ REG32_VAL(INT_MASK_COUNT) = 28*1000000*1/4; //0x47868C0/4;//count for 1 sec 0x47868C0
+ }
+
+ REG32_VAL(IRCTL) |= (0x1<<25);
+ REG32_VAL(INT_MASK_CTRL) = 0x1;
+
+ /* IR_EN */
+ REG32_VAL(IRCTL) |= 0x1;
+ while(retries++ < 100 && !(REG32_VAL(IRCTL)&0x01)){
+ REG32_VAL(IRCTL) |= 0x1;
+ udelay(5);
+ }
+
+ /* read CIR status to clear IR interrupt. */
+ st = REG32_VAL(IRSTS);
+}
+
+static void rmtctl_refresh_vendorcode(struct work_struct *work)
+{
+ unsigned char data[64];
+ struct rmtctl_priv *priv = container_of(work, struct rmtctl_priv, delaywork.work);
+ sprintf(data, "0x%x", priv->vendor_code);
+ wmt_setsyspara(WMT_RMTCTL_VENDOR_ENV, data);
+}
+
+static void rel_handler(unsigned long data)
+{
+ struct rmtctl_rel *rel = (struct rmtctl_rel *)data;
+ struct rmtctl_priv *priv = container_of(rel, struct rmtctl_priv, rel_dev);
+
+ rmtctl_report_rel(&priv->rel_dev, rel->code);
+ mod_timer(&rel->timer, jiffies+HZ/15); // report rate 15pps
+}
+
+static void rmtctl_rel_init(struct rmtctl_rel *rel)
+{
+ struct input_dev *input;
+
+ input = input_allocate_device();
+ input->name = "rmtctl-rel";
+
+ /* register the device as mouse */
+ set_bit(EV_REL, input->evbit);
+ set_bit(REL_X, input->relbit);
+ set_bit(REL_Y, input->relbit);
+
+ /* register device's buttons and keys */
+ set_bit(EV_KEY, input->evbit);
+ set_bit(BTN_LEFT, input->keybit);
+ set_bit(BTN_RIGHT, input->keybit);
+
+ input_register_device(input);
+ rel->input = input;
+
+ init_timer(&rel->timer);
+ rel->timer.data = (unsigned long)rel;
+ rel->timer.function = rel_handler;
+}
+
+void led_handler(unsigned long data)
+{
+ struct rmtctl_led *led = (struct rmtctl_led*)data;
+
+ gpio_direction_output(led->gpio, led->on++%2);
+ mod_timer(&led->timer, jiffies+HZ/20);
+ return;
+}
+
+static void rmtctl_led_init(struct rmtctl_led *led)
+{
+ init_timer(&led->timer);
+ led->timer.data = (unsigned long)led;
+ led->timer.function = led_handler;
+
+ gpio_direction_output(led->gpio, led->active);
+
+ return;
+}
+
+static int rmtctl_probe(struct platform_device *dev)
+{
+ int i,ivendor, ikeycode;
+ char buf[64];
+ int varlen = sizeof(buf);
+ struct rmtctl_priv *priv;
+
+ priv = kzalloc(sizeof(struct rmtctl_priv), GFP_KERNEL);
+ if (priv == NULL)
+ return -ENOMEM;
+ platform_set_drvdata(dev, priv);
+
+ // get codec type of cir device
+ if (wmt_getsyspara("wmt.io.rmtctl", buf, &varlen) == 0) {
+ sscanf(buf, "%d", &priv->codec);
+ if (priv->codec < CIR_CODEC_NEC || priv->codec >= CIR_CODEC_MAX){
+ kfree(priv);
+ return -EINVAL;
+ }
+ }
+ else {
+ kfree(priv);
+ return -EINVAL;
+ }
+
+ // using assigned cir device?
+ if (wmt_getsyspara("wmt.io.rmtctl.index", buf, &varlen) == 0) {
+ sscanf(buf, "%d", &priv->vendor_index);
+ if (priv->vendor_index >= ARRAY_SIZE(rmtctl_vendors) ||
+ rmtctl_vendors[priv->vendor_index].codec != priv->codec)
+ priv->vendor_index = -1;
+
+ priv->table_index = priv->vendor_index;
+ }
+ else
+ priv->vendor_index = -1;
+
+ // get last vendor code saved in uboot environment
+#if 0
+ if (wmt_getsyspara(WMT_RMTCTL_VENDOR_ENV, buf, &varlen) == 0){
+ sscanf(buf, "0x%x", &priv->vendor_code);
+ priv->saved_vcode = priv->vendor_code;
+ for (i = 0; i < ARRAY_SIZE(rmtctl_vendors); i++) {
+ if (priv->vendor_code == rmtctl_vendors[i].vendor_code &&
+ rmtctl_vendors[i].codec == priv->codec) {
+ priv->table_index = i;
+ break;
+ }
+ }
+ }else
+#endif
+ priv->vendor_code = 0xffff;
+
+ if (wmt_getsyspara("wmt.io.rmtctl.led", buf, &varlen) == 0) {
+ sscanf(buf, "%d:%d", &priv->led.gpio, &priv->led.active);
+ priv->led.enable = 1;
+ }
+
+ /* register an input device. */
+ if ((priv->idev = input_allocate_device()) == NULL)
+ return -ENOMEM;
+
+ set_bit(EV_KEY, priv->idev->evbit);
+
+ for (ivendor = 0; ivendor < ARRAY_SIZE(rmtctl_vendors); ivendor++) {
+ if (priv->codec == rmtctl_vendors[ivendor].codec) {
+ for (ikeycode = 0; ikeycode < ARRAY_SIZE(rmtctl_vendors[ivendor].key_codes); ikeycode++) {
+ if (rmtctl_vendors[ivendor].key_codes[ikeycode]) {
+ set_bit(rmtctl_vendors[ivendor].key_codes[ikeycode], priv->idev->keybit);
+ }
+ }
+ }
+ }
+
+ priv->idev->name = "rmtctl";
+ priv->idev->phys = "rmtctl";
+ input_register_device(priv->idev);
+ rmtctl_rel_init(&priv->rel_dev);
+ if(priv->led.enable){
+ gpio_request(priv->led.gpio,"rmtctl-led");
+ rmtctl_led_init(&priv->led);
+ }
+ INIT_DELAYED_WORK(&priv->delaywork, rmtctl_refresh_vendorcode);
+
+ init_timer(&priv->timer);
+ priv->timer.data = (unsigned long)priv->idev;
+ priv->timer.function = rmtctl_timer_handler;
+
+ /* Register an ISR */
+ request_irq(IRQ_CIR, rmtctl_interrupt, IRQF_SHARED, "rmtctl", priv);
+
+ /* Initial H/W */
+ rmtctl_hw_init((unsigned long)priv);
+
+ if (RMTCTL_DEBUG)
+ printk("WonderMedia rmtctl driver v0.98 initialized: ok\n");
+
+ return 0;
+}
+
+static int rmtctl_remove(struct platform_device *dev)
+{
+ struct rmtctl_priv *priv = platform_get_drvdata(dev);
+
+ if (RMTCTL_DEBUG)
+ printk("rmtctl_remove\n");
+
+ del_timer_sync(&priv->timer);
+ cancel_delayed_work_sync(&priv->delaywork);
+ del_timer_sync(&priv->rel_dev.timer);
+ input_unregister_device(priv->rel_dev.input);
+ input_free_device(priv->rel_dev.input);
+ if(priv->led.enable){
+ del_timer_sync(&priv->led.timer);
+ gpio_direction_output(priv->led.gpio, priv->led.active);
+ gpio_free(priv->led.gpio);
+ }
+
+ free_irq(IRQ_CIR, priv);
+ input_unregister_device(priv->idev);
+ input_free_device(priv->idev);
+
+ kfree(priv);
+
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int rmtctl_suspend(struct platform_device *dev, pm_message_t state)
+{
+ struct rmtctl_priv *priv = platform_get_drvdata(dev);
+
+ del_timer_sync(&priv->timer);
+ cancel_delayed_work_sync(&priv->delaywork);
+ del_timer_sync(&priv->rel_dev.timer);
+ if(priv->led.enable){
+ priv->led.on = 0;
+ del_timer(&priv->led.timer);
+ gpio_direction_output(priv->led.gpio, priv->led.active);
+ }
+
+ /* Nothing to suspend? */
+ rmtctl_hw_init((unsigned long)priv);
+ rmtctl_hw_suspend((unsigned long)priv);
+
+ disable_irq(IRQ_CIR);
+
+ /* Enable rmt wakeup */
+ PMWE_VAL |= (1 << WKS_CIR);
+
+ return 0;
+}
+
+static int rmtctl_resume(struct platform_device *dev)
+{
+ volatile unsigned int regval;
+ int i =0 ;
+ struct rmtctl_priv *priv = platform_get_drvdata(dev);
+
+ /* Initial H/W */
+ REG32_VAL(WAKEUP_CTRL) &=~ BIT0;
+
+ for (i=0;i<10;i++)
+ {
+ regval = REG32_VAL(WAKEUP_STS) ;
+
+ if (regval & BIT0){
+ REG32_VAL(WAKEUP_STS) |= BIT4;
+
+ }else{
+ break;
+ }
+ msleep_interruptible(5);
+ }
+
+ regval = REG32_VAL(WAKEUP_STS) ;
+ if (regval & BIT0)
+ printk("CIR resume NG WAKEUP_STS 0x%08x \n",regval);
+
+ rmtctl_hw_init((unsigned long)priv);
+ if(priv->led.enable)
+ rmtctl_led_init(&priv->led);
+ enable_irq(IRQ_CIR);
+ return 0;
+}
+#else
+#define rmtctl_suspend NULL
+#define rmtctl_resume NULL
+#endif
+
+static struct platform_driver rmtctl_driver = {
+ .driver.name = "wmt-rmtctl",
+ //.bus = &platform_bus_type,
+ //.probe = rmtctl_probe,
+ .remove = rmtctl_remove,
+ .suspend = rmtctl_suspend,
+ .resume = rmtctl_resume
+};
+
+static void rmtctl_release(struct device *dev)
+{
+ /* Nothing to release? */
+}
+
+static u64 rmtctl_dmamask = 0xffffffff;
+
+static struct platform_device rmtctl_device = {
+ .name = "wmt-rmtctl",
+ .id = 0,
+ .dev = {
+ .release = rmtctl_release,
+ .dma_mask = &rmtctl_dmamask,
+ },
+ .num_resources = 0,
+ .resource = NULL,
+};
+
+static int __init rmtctl_init(void)
+{
+ int ret;
+
+ if (platform_device_register(&rmtctl_device))
+ return -1;
+ ret = platform_driver_probe(&rmtctl_driver, rmtctl_probe);
+
+ return ret;
+}
+
+static void __exit rmtctl_exit(void)
+{
+ platform_driver_unregister(&rmtctl_driver);
+ platform_device_unregister(&rmtctl_device);
+}
+
+module_init(rmtctl_init);
+module_exit(rmtctl_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("WonderMedia Technologies, Inc.");
+MODULE_DESCRIPTION("WMT [Remoter] driver");
diff --git a/ANDROID_3.4.5/drivers/input/rmtctl/wmt-rmtctl.h b/ANDROID_3.4.5/drivers/input/rmtctl/wmt-rmtctl.h
new file mode 100755
index 00000000..7094f6dd
--- /dev/null
+++ b/ANDROID_3.4.5/drivers/input/rmtctl/wmt-rmtctl.h
@@ -0,0 +1,50 @@
+/*++
+ * linux/drivers/input/rmtctl/wmt-rmtctl.h
+ * WonderMedia input remote control driver
+ *
+ * Copyright c 2010 WonderMedia Technologies, Inc.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ * WonderMedia Technologies, Inc.
+ * 4F, 533, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C
+--*/
+
+
+#define REG_BASE_IR CIR_BASE_ADDR
+
+#define IRSWRST REG_BASE_IR+0x00 // [0x00] IR Software Reset register
+#define IRCTL REG_BASE_IR+0x04 // [0x04] IR Control register
+#define IRCTL_2 REG_BASE_IR+0x08 // [0x08] IR Control register
+#define IRSTS REG_BASE_IR+0x0c // [0x0c] IR Status register
+#define IRDATA(i) REG_BASE_IR+0x10+i*0x4 // [0x10-0x20] IR Received Data register
+#define PARAMETER(i) REG_BASE_IR+0x24+i*0x4 // [0x24-0x3c]IR Parameter Register for Remote Controller Vendor "NEC"
+#define NEC_REPEAT_TIME_OUT_CTRL REG_BASE_IR+0x40 // [0X40]
+#define NEC_REPEAT_TIME_OUT_COUNT REG_BASE_IR+0x44 // [0X44]
+#define NEC_REPEAT_TIME_OUT_STS REG_BASE_IR+0x48 // [0X48]
+#define JVC_CONTI_CTRL REG_BASE_IR+0x50 // [0X50]
+#define JVC_CONTI_COUNT REG_BASE_IR+0x54 // [0X54]
+#define JVC_CONTI_STS REG_BASE_IR+0x58 // [0X58]
+#define INT_MASK_CTRL REG_BASE_IR+0x60 // [0X60]
+#define INT_MASK_COUNT REG_BASE_IR+0x64 // [0X64]
+#define INT_MASK_STS REG_BASE_IR+0x68 // [0X68]
+#define WAKEUP_CMD1(i) REG_BASE_IR+0x70+i*0x4 // [0X70-0x80]
+#define WAKEUP_CMD2(i) REG_BASE_IR+0x84+i*0x4 // [0X84-0x94]
+#define WAKEUP_CTRL REG_BASE_IR+0x98 // [0X98]
+#define WAKEUP_STS REG_BASE_IR+0x9c // [0X9C]
+#define IRFSM REG_BASE_IR+0xa0 // [0Xa0]
+#define IRHSPMC REG_BASE_IR+0xa4 // [0xa4] IR Host-Synchronous-Pulse Measure Counter register
+#define IRHSPTC REG_BASE_IR+0xa8 // [0xa8] IR Host-Synchronous-Pulse Tolerance Counter register
+
+
diff --git a/ANDROID_3.4.5/drivers/input/sensor/Kconfig b/ANDROID_3.4.5/drivers/input/sensor/Kconfig
new file mode 100755
index 00000000..cff1aa40
--- /dev/null
+++ b/ANDROID_3.4.5/drivers/input/sensor/Kconfig
@@ -0,0 +1,224 @@
+#
+# WMT Sensor configuration
+#
+menuconfig INPUT_SENSOR
+ bool "WMT Sensor"
+ default y
+ help
+ Say Y here, and a list of supported sensor will be displayed.
+ This option doesn't affect the kernel.
+
+ If unsure, say Y.
+
+if INPUT_SENSOR
+
+config WMT_SENSOR_KXTE9
+ tristate "KXTE9 G-Sensor Support"
+ depends on ARCH_WMT
+ default n
+ help
+ Say Y here if you have an WMT based board with g-sensor
+ attached to it.
+
+ If unsure, say N.
+
+ To compile this driver as a module, choose M here: the
+ module will be called s_wmt_gsensor_mc3230.
+config WMT_SENSOR_KIONIX
+ tristate "KIONIX G-Sensor Support"
+ depends on ARCH_WMT
+ default n
+ help
+ Say Y here if you have an WMT based board with g-sensor
+ attached to it.
+
+ If unsure, say N.
+
+ To compile this driver as a module, choose M here: the
+ module will be called s_wmt_gsensor_kionix.
+config WMT_SENSOR_MC3XXX
+ tristate "Mcube G-Sensor Support"
+ depends on ARCH_WMT
+ default m
+ help
+ Say Y here if you have an WMT based board with g-sensor
+ attached to it.
+
+ If unsure, say N.
+
+ To compile this driver as a module, choose M here: the
+ module will be called s_wmt_gsensor_mc3xxx.
+
+config WMT_SENSOR_DMARD08
+ tristate "DMARD08 G-Sensor Support"
+ depends on ARCH_WMT
+ default y
+ help
+ Say Y here if you have an WMT based board with g-sensor
+ attached to it.
+
+ If unsure, say N.
+
+ To compile this driver as a module, choose M here: the
+ module will be called sensor_dmard08.
+config WMT_SENSOR_DMARD06
+ tristate "DMARD06 G-Sensor Support"
+ depends on ARCH_WMT
+ default y
+ help
+ Say Y here if you have an WMT based board with g-sensor
+ attached to it.
+
+ If unsure, say N.
+
+ To compile this driver as a module, choose M here: the
+ module will be called sensor_dmard06.
+config WMT_SENSOR_DMARD10
+ tristate "DMARD10 G-Sensor Support"
+ depends on ARCH_WMT
+ default y
+ help
+ Say Y here if you have an WMT based board with g-sensor
+ attached to it.
+
+ If unsure, say N.
+
+ To compile this driver as a module, choose M here: the
+ module will be called sensor_dmard10.
+config WMT_SENSOR_DMARD09
+ tristate "DMARD09 G-Sensor Support"
+ depends on ARCH_WMT
+ default y
+ help
+ Say Y here if you have an WMT based board with g-sensor
+ attached to it.
+
+ If unsure, say N.
+
+ To compile this driver as a module, choose M here: the
+ module will be called sensor_dmard09.
+config WMT_SENSOR_MXC622X
+ tristate "MXC622X G-Sensor Support"
+ depends on ARCH_WMT
+ default y
+ help
+ Say Y here if you have an WMT based board with g-sensor
+ attached to it.
+
+ If unsure, say N.
+
+ To compile this driver as a module, choose M here: the
+ module will be called sensor_mxc622x.
+config WMT_SENSOR_MMA7660
+ tristate "MMA7660 G-Sensor Support"
+ depends on ARCH_WMT
+ default y
+ help
+ Say Y here if you have an WMT based board with g-sensor
+ attached to it.
+
+ If unsure, say N.
+
+ To compile this driver as a module, choose M here: the
+ module will be called sensor_mma7660.
+config WMT_SENSOR_MMC328x
+ tristate "MMC328x M-Sensor Support"
+ depends on ARCH_WMT
+ default y
+ help
+ Say Y here if you have an WMT based board with m-sensor
+ attached to it.
+
+ If unsure, say N.
+
+ To compile this driver as a module, choose M here: the
+ module will be called sensor_mmc328x.
+config WMT_SENSOR_ISL29023
+ tristate "ISL29023 Light sensor Support"
+ depends on ARCH_WMT
+ default y
+ help
+ Say Y here if you have an WMT based board with l-sensor
+ attached to it.
+
+ If unsure, say N.
+
+ To compile this driver as a module, choose M here: the
+ module will be called sensor_isl29023.
+config WMT_SENSOR_CM3232
+ tristate "CM3232 Light sensor Support"
+ depends on ARCH_WMT
+ default y
+ help
+ Say Y here if you have an WMT based board with l-sensor
+ attached to it.
+
+ If unsure, say N.
+
+ To compile this driver as a module, choose M here: the
+ module will be called sensor_cm3232.
+config WMT_SENSOR_STK3310
+ tristate "STK3310 Light sensor Support"
+ depends on ARCH_WMT
+ default y
+ help
+ Say Y here if you have an WMT based board with l-sensor
+ attached to it.
+
+ If unsure, say N.
+
+ To compile this driver as a module, choose M here: the
+ module will be called sensor_stk3310.
+config WMT_GYRO_L3G4200D
+ tristate "L3G4200D Gyroscope Support"
+ depends on ARCH_WMT
+ default m
+ help
+ Say Y here if you have an WMT based board with ST L3g4200d
+ gyroscope attached to it.
+
+ If unsure, say N.
+
+ To compile this driver as a module, choose M here: the
+ module will be called s_wmt_gyro_l3g4200d.
+
+config WMT_SENSOR_US5182
+ tristate "US5182 Light&Promixity sensor Support"
+ depends on ARCH_WMT
+ default m
+ help
+ Say Y here if you have an WMT based board with l&p-sensor
+ attached to it.
+
+ If unsure, say N.
+
+ To compile this driver as a module, choose M here: the
+ module will be called s_wmt_lsensor_us5182.
+
+config WMT_SENSOR_MMA8452Q
+ tristate "MMA8452Q G-Sensor Support"
+ depends on ARCH_WMT
+ default m
+ help
+ Say Y here if you have an WMT based board with g-sensor
+ attached to it.
+
+ If unsure, say N.
+
+ To compile this driver as a module, choose M here: the
+ module will be called s_wmt_gsensor_mma8542.
+
+config WMT_SENSOR_STK8312
+ tristate "STK8312 G-Sensor Support"
+ depends on ARCH_WMT
+ default m
+ help
+ Say Y here if you have an WMT based board with g-sensor
+ attached to it.
+
+ If unsure, say N.
+
+ To compile this driver as a module, choose M here: the
+ module will be called s_wmt_gsensor_STK8312.
+
+endif
diff --git a/ANDROID_3.4.5/drivers/input/sensor/Makefile b/ANDROID_3.4.5/drivers/input/sensor/Makefile
new file mode 100755
index 00000000..cc06e871
--- /dev/null
+++ b/ANDROID_3.4.5/drivers/input/sensor/Makefile
@@ -0,0 +1,26 @@
+#
+# Makefile for the Sensor driver
+#
+
+# Each configuration option enables a list of files.
+
+#obj-$(CONFIG_INPUT_SENSOR) += gsensor.o
+obj-y += sensor.o
+obj-$(CONFIG_WMT_SENSOR_KXTE9) += kxte9_gsensor/
+obj-$(CONFIG_WMT_SENSOR_MC3XXX) += mc3xxx_gsensor/
+obj-$(CONFIG_WMT_SENSOR_DMARD08) += dmard08_gsensor/
+obj-$(CONFIG_WMT_SENSOR_DMARD06) += dmard06_gsensor/
+obj-$(CONFIG_WMT_SENSOR_MMA7660) += mma7660_gsensor/
+obj-$(CONFIG_WMT_SENSOR_ISL29023) += isl29023_lsensor/
+obj-$(CONFIG_WMT_SENSOR_CM3232) += cm3232/
+obj-$(CONFIG_WMT_SENSOR_CM3232) += stk3310/
+obj-$(CONFIG_WMT_SENSOR_DMARD10) += dmard10_gsensor/
+obj-$(CONFIG_WMT_SENSOR_DMARD09) += dmard09_gsensor/
+obj-$(CONFIG_WMT_SENSOR_MXC622X) += mxc622x_gsensor/
+obj-$(CONFIG_WMT_SENSOR_MMC328x) += mmc328x_msensor/
+#obj-$(CONFIG_WMT_SENSOR_CM3232) += cm3232/cm3232.o
+obj-$(CONFIG_WMT_GYRO_L3G4200D) += l3g4200d_gyro/
+obj-$(CONFIG_WMT_SENSOR_US5182) += us5182_lpsensor/
+obj-$(CONFIG_WMT_SENSOR_MMA8452Q) += mma8452q_gsensor/
+obj-$(CONFIG_WMT_SENSOR_STK8312) += stk8312_gsensor/
+obj-$(CONFIG_WMT_SENSOR_KIONIX) += kionix_gsensor/
\ No newline at end of file
diff --git a/ANDROID_3.4.5/drivers/input/sensor/TP_DRIVER_NOT_USE/Kconfig b/ANDROID_3.4.5/drivers/input/sensor/TP_DRIVER_NOT_USE/Kconfig
new file mode 100755
index 00000000..9bf96e92
--- /dev/null
+++ b/ANDROID_3.4.5/drivers/input/sensor/TP_DRIVER_NOT_USE/Kconfig
@@ -0,0 +1,50 @@
+#
+# WMT Sensor configuration
+#
+menuconfig INPUT_SENSOR
+ bool "WMT Sensor"
+ help
+ Say Y here, and a list of supported sensor will be displayed.
+ This option doesn't affect the kernel.
+
+ If unsure, say Y.
+
+if INPUT_SENSOR
+
+
+config WMT_SENSOR_KXTI9
+ tristate "KXTI9 G-Sensor Support"
+ depends on ARCH_WMT
+ help
+ Say Y here if you have an WMT based board with g-sensor
+ attached to it.
+
+ If unsure, say N.
+
+ To compile this driver as a module, choose M here: the
+ module will be called sensor_kxti9.
+
+config WMT_SENSOR_DMT08
+ tristate "DMT08 G-Sensor Support"
+ depends on ARCH_WMT
+ help
+ Say Y here if you have an WMT based board with g-sensor
+ attached to it.
+
+ If unsure, say N.
+
+ To compile this driver as a module, choose M here: the
+ module will be called sensor_dmt08.
+
+config WMT_SENSOR_DMT10
+ tristate "DMT10 G-Sensor Support"
+ depends on ARCH_WMT
+ help
+ Say Y here if you have an WMT based board with g-sensor
+ attached to it.
+
+ If unsure, say N.
+
+ To compile this driver as a module, choose M here: the
+ module will be called sensor_dmt10.
+endif
diff --git a/ANDROID_3.4.5/drivers/input/sensor/TP_DRIVER_NOT_USE/Makefile b/ANDROID_3.4.5/drivers/input/sensor/TP_DRIVER_NOT_USE/Makefile
new file mode 100755
index 00000000..ee1a0ac5
--- /dev/null
+++ b/ANDROID_3.4.5/drivers/input/sensor/TP_DRIVER_NOT_USE/Makefile
@@ -0,0 +1,13 @@
+#
+# Makefile for the Sensor driver
+#
+
+# Each configuration option enables a list of files.
+
+obj-$(CONFIG_INPUT_SENSOR) += gsensor.o
+
+obj-$(CONFIG_WMT_SENSOR_KXTI9) += kxti9_gsensor/
+
+obj-$(CONFIG_WMT_SENSOR_DMT08) += dmt08_gsensor/
+
+obj-$(CONFIG_WMT_SENSOR_DMT10) += dmt10_gsensor/
diff --git a/ANDROID_3.4.5/drivers/input/sensor/TP_DRIVER_NOT_USE/dmt08_gsensor/Makefile b/ANDROID_3.4.5/drivers/input/sensor/TP_DRIVER_NOT_USE/dmt08_gsensor/Makefile
new file mode 100755
index 00000000..6edce54a
--- /dev/null
+++ b/ANDROID_3.4.5/drivers/input/sensor/TP_DRIVER_NOT_USE/dmt08_gsensor/Makefile
@@ -0,0 +1,6 @@
+#
+# Makefile for the DMARD06 Sensor driver
+#
+
+sensor_dmt08-objs := dmt08.o
+obj-$(CONFIG_WMT_SENSOR_DMT08) += sensor_dmt08.o
diff --git a/ANDROID_3.4.5/drivers/input/sensor/TP_DRIVER_NOT_USE/dmt08_gsensor/dmt08.c b/ANDROID_3.4.5/drivers/input/sensor/TP_DRIVER_NOT_USE/dmt08_gsensor/dmt08.c
new file mode 100755
index 00000000..2ed5f502
--- /dev/null
+++ b/ANDROID_3.4.5/drivers/input/sensor/TP_DRIVER_NOT_USE/dmt08_gsensor/dmt08.c
@@ -0,0 +1,870 @@
+/*
+ * @file drivers/misc/dmt0308.c
+ * @brief DMT g-sensor Linux device driver
+ * @author Domintech Technology Co., Ltd (http://www.domintech.com.tw)
+ * @version 1.31
+ * @date 2012/3/27
+ *
+ * @section LICENSE
+ *
+ * Copyright 2011 Domintech Technology Co., Ltd
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ *
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include "dmt08.h"
+#include "../gsensor.h"
+
+wait_queue_head_t open_wq;
+atomic_t active;
+static unsigned int interval;
+struct mutex DMT_mutex;
+struct delayed_work work;
+struct work_struct irq_work;
+atomic_t delay;
+
+static struct gsensor_conf gs_conf;
+
+void gsensor_write_offset_to_file(void);
+void gsensor_read_offset_from_file(void);
+char OffsetFileName[] = "/data/misc/dmt/offset.txt";
+static int Device_First_Time_Opened_flag=1;
+//*************************************************
+static char const *const ACCELEMETER_CLASS_NAME = "accelemeter";
+#define CHIP_ENABLE 137
+#if (defined(CONFIG_SENSORS_DMARD03) || defined(CONFIG_SENSORS_DMARD03_MODULE))
+static char const *const GSENSOR_DEVICE_NAME = "dmard03";
+#elif (defined(CONFIG_SENSORS_DMARD08) || defined(CONFIG_SENSORS_DMARD08_MODULE) || defined(CONFIG_WMT_SENSOR_DMT08))
+static char const *const GSENSOR_DEVICE_NAME = "dmard08";
+#endif
+
+static int device_init(void);
+static void device_exit(void);
+
+static int device_open(struct inode*, struct file*);
+static ssize_t device_write(struct file*, const char*, size_t, loff_t*);
+static ssize_t device_read(struct file*, char*, size_t, loff_t*);
+static long device_ioctl(struct file *filp, unsigned int cmd, unsigned long arg);
+static int device_close(struct inode*, struct file*);
+
+//static int device_i2c_suspend(struct i2c_client *client, pm_message_t mesg);
+//static int device_i2c_resume(struct i2c_client *client);
+static int __devinit device_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id);
+static int __devexit device_i2c_remove(struct i2c_client *client);
+static inline void device_i2c_correct_accel_sign(s16 *val);
+void device_i2c_read_xyz(struct i2c_client *client, s16 *xyz);
+void device_i2c_merge_register_values(struct i2c_client *client, s16 *val, u8 msb, u8 lsb);
+
+struct input_dev *input;
+
+static int DMT_GetOpenStatus(void)
+{
+#if DMT_DEBUG_DATA
+ IN_FUNC_MSG;
+ printk("%s:start active=%d\n",__func__,active.counter);
+#endif
+ wait_event_interruptible(open_wq, (atomic_read(&active) != 0));
+ return 0;
+}
+
+static int DMT_GetCloseStatus(void)
+{
+#if DMT_DEBUG_DATA
+ IN_FUNC_MSG;
+ printk("%s:start active=%d\n",__func__,active.counter);
+#endif
+ wait_event_interruptible(open_wq, (atomic_read(&active) <= 0));
+ return 0;
+}
+
+static void DMT_sysfs_update_active_status(int en)
+{
+ unsigned long dmt_delay;
+ if(en)
+ {
+ dmt_delay = msecs_to_jiffies(atomic_read(&delay));
+ if(dmt_delay < 1)
+ dmt_delay = 1;
+ //printk("schedule_delayed_work start with delay time=%lu\n",dmt_delay);
+ schedule_delayed_work(&work,dmt_delay);
+ }
+ else
+ cancel_delayed_work_sync(&work);
+}
+
+static ssize_t DMT_enable_acc_show( struct device *dev, struct device_attribute *attr, char *buf)
+{
+ buf="show";
+ return 1;
+}
+
+static ssize_t DMT_enable_acc_store( struct device *dev, struct device_attribute *attr, char const *buf, size_t count)
+{
+ int en;
+#if DMT_DEBUG_DATA
+ printk("%s:buf=%x %x\n",__func__,buf[0],buf[1]);
+#endif
+ if(buf[0]!= 0x30 && buf[0]!= 0x31)
+ {
+ printk("%s:illegle data !!\n",__func__);
+ return 0;
+ }
+ en= (buf[0]-0x30 > 0) ? 1:0;
+ DMT_sysfs_update_active_status(en);
+ return 1;
+}
+
+static ssize_t DMT_delay_acc_show( struct device *dev, struct device_attribute *attr, char *buf){
+ return 1;
+}
+
+static ssize_t DMT_delay_acc_store( struct device *dev, struct device_attribute *attr,char const *buf, size_t count)
+{
+ int error;
+ unsigned long data;
+ error = strict_strtoul(buf, 10, &data);
+ if(error) {
+ pr_err("%s strict_strtoul error\n", __FUNCTION__);
+ return -1;
+ }
+ mutex_lock(&DMT_mutex);
+ interval=(unsigned int)data;
+ mutex_unlock(&DMT_mutex);
+ atomic_set(&delay, (unsigned int) data);
+#if DMT_DEBUG_DATA
+ printk("Driver attribute set delay =%lu\n",data);
+#endif
+ return 1;
+}
+
+static struct device_attribute DMT_attributes[] = {
+ __ATTR(enable_acc, 0755, DMT_enable_acc_show, DMT_enable_acc_store),
+ __ATTR(delay_acc, 0755, DMT_delay_acc_show, DMT_delay_acc_store),
+ __ATTR_NULL,
+};
+
+static int create_device_attributes(struct device *dev, struct device_attribute *attrs)
+{
+ int i;
+ int err = 0;
+#if DMT_DEBUG_DATA
+ IN_FUNC_MSG;
+#endif
+ for (i = 0 ; NULL != attrs[i].attr.name ; ++i) {
+ err = device_create_file(dev, &attrs[i]);
+ if (0 != err)
+ break;
+ }
+
+ if (0 != err) {
+ for (; i >= 0 ; --i)
+ device_remove_file(dev, &attrs[i]);
+ }
+ return err;
+}
+
+int input_init(void)
+{
+ int err=0;
+ input=input_allocate_device();
+ if (!input)
+ return -ENOMEM;
+ else
+ printk("input device allocate Success !!\n");
+ /* Setup input device */
+ set_bit(EV_ABS, input->evbit);
+ /* Accelerometer [-78.5, 78.5]m/s2 in Q16*/
+ input_set_abs_params(input, ABS_X, -1024, 1024, 0, 0);
+ input_set_abs_params(input, ABS_Y, -1024, 1024, 0, 0);
+ input_set_abs_params(input, ABS_Z, -1024, 1024, 0, 0);
+
+ /* Set name */
+ input->name = "g-sensor";
+
+ /* Register */
+ err = input_register_device(input);
+ if (err) {
+ input_free_device(input);
+ return err;
+ }
+ atomic_set(&active, 0);
+#if DMT_DEBUG_DATA
+ printk("in driver ,active=%d\n",active.counter);
+#endif
+ init_waitqueue_head(&open_wq);
+
+ return err;
+}
+
+typedef union {
+ struct {
+ s16 x;
+ s16 y;
+ s16 z;
+ } u;
+ s16 v[SENSOR_DATA_SIZE];
+} raw_data;
+static raw_data offset;
+
+struct dev_data {
+ dev_t devno;
+ struct cdev cdev;
+ struct class *class;
+ struct i2c_client *client;
+};
+static struct dev_data dev;
+
+s16 sensorlayout[3][3] = {
+#if defined(CONFIG_GSEN_LAYOUT_PAT_1)
+ { 1, 0, 0}, { 0, 1, 0}, { 0, 0, 1},
+#elif defined(CONFIG_GSEN_LAYOUT_PAT_2)
+ { 0, 1, 0}, {-1, 0, 0}, { 0, 0, 1},
+#elif defined(CONFIG_GSEN_LAYOUT_PAT_3)
+ {-1, 0, 0}, { 0,-1, 0}, { 0, 0, 1},
+#elif defined(CONFIG_GSEN_LAYOUT_PAT_4)
+ { 0,-1, 0}, { 1, 0, 0}, { 0, 0, 1},
+#elif defined(CONFIG_GSEN_LAYOUT_PAT_5)
+ {-1, 0, 0}, { 0, 1, 0}, { 0, 0,-1},
+#elif defined(CONFIG_GSEN_LAYOUT_PAT_6)
+ { 0,-1, 0}, {-1, 0, 0}, { 0, 0,-1},
+#elif defined(CONFIG_GSEN_LAYOUT_PAT_7)
+ { 1, 0, 0}, { 0,-1, 0}, { 0, 0,-1},
+#elif defined(CONFIG_GSEN_LAYOUT_PAT_8)
+ { 0, 1, 0}, { 1, 0, 0}, { 0, 0,-1},
+#endif
+};
+
+void gsensor_read_accel_avg(int num_avg, raw_data *avg_p )
+{
+ long xyz_acc[SENSOR_DATA_SIZE];
+ s16 xyz[SENSOR_DATA_SIZE];
+ int i, j;
+
+ //initialize the accumulation buffer
+ for(i = 0; i < SENSOR_DATA_SIZE; ++i)
+ xyz_acc[i] = 0;
+
+ for(i = 0; i < num_avg; i++)
+ {
+ device_i2c_read_xyz(dev.client, (s16 *)&xyz);
+ for(j = 0; j < SENSOR_DATA_SIZE; j++)
+ xyz_acc[j] += xyz[j];
+ }
+
+ // calculate averages
+ for(i = 0; i < SENSOR_DATA_SIZE; i++)
+ avg_p->v[i] = (s16) (xyz_acc[i] / num_avg);
+}
+/* calc delta offset */
+int gsensor_calculate_offset(int gAxis,raw_data avg)
+{
+ switch(gAxis)
+ {
+ case CONFIG_GSEN_CALIBRATION_GRAVITY_ON_Z_NEGATIVE:
+ offset.u.x = avg.u.x ;
+ offset.u.y = avg.u.y ;
+ offset.u.z = avg.u.z + DEFAULT_SENSITIVITY;
+ break;
+ case CONFIG_GSEN_CALIBRATION_GRAVITY_ON_X_POSITIVE:
+ offset.u.x = avg.u.x + DEFAULT_SENSITIVITY;
+ offset.u.y = avg.u.y ;
+ offset.u.z = avg.u.z ;
+ break;
+ case CONFIG_GSEN_CALIBRATION_GRAVITY_ON_Z_POSITIVE:
+ offset.u.x = avg.u.x ;
+ offset.u.y = avg.u.y ;
+ offset.u.z = avg.u.z - DEFAULT_SENSITIVITY;
+ break;
+ case CONFIG_GSEN_CALIBRATION_GRAVITY_ON_X_NEGATIVE:
+ offset.u.x = avg.u.x - DEFAULT_SENSITIVITY;
+ offset.u.y = avg.u.y ;
+ offset.u.z = avg.u.z ;
+ break;
+ case CONFIG_GSEN_CALIBRATION_GRAVITY_ON_Y_NEGATIVE:
+ offset.u.x = avg.u.x ;
+ offset.u.y = avg.u.y + DEFAULT_SENSITIVITY;
+ offset.u.z = avg.u.z ;
+ break;
+ case CONFIG_GSEN_CALIBRATION_GRAVITY_ON_Y_POSITIVE:
+ offset.u.x = avg.u.x ;
+ offset.u.y = avg.u.y - DEFAULT_SENSITIVITY;
+ offset.u.z = avg.u.z ;
+ break;
+ default:
+ return -ENOTTY;
+ }
+ return 0;
+}
+
+void gsensor_calibrate(int side){
+ raw_data avg;
+ int avg_num = 16;
+#if DMT_DEBUG_DATA
+ IN_FUNC_MSG;
+#endif
+ // get acceleration average reading
+ gsensor_read_accel_avg(avg_num, &avg);
+ // calculate and set the offset
+ gsensor_calculate_offset(side, avg);
+}
+
+void ce_on(void){
+ //omap_mux_set_gpio(OMAP_PIN_INPUT_PULLUP, CHIP_ENABLE);
+}
+
+void ce_off(void){
+ //omap_mux_set_gpio(OMAP_PIN_INPUT_PULLDOWN, CHIP_ENABLE);
+}
+
+void gsensor_reset(void){
+ ce_off();
+ msleep(300);
+ ce_on();
+}
+
+void gsensor_set_offset(int val[3])
+{
+ int i;
+#if DMT_DEBUG_DATA
+ IN_FUNC_MSG;
+#endif
+ for(i = 0; i < SENSOR_DATA_SIZE; ++i)
+ offset.v[i] = (s16) val[i];
+}
+
+static int device_i2c_suspend(struct i2c_client *client, pm_message_t mesg)
+{
+ return 0;
+}
+
+static int device_i2c_resume(struct i2c_client *client)
+{
+ return 0;
+}
+
+static void device_i2c_shutdown(struct i2c_client *client)
+{
+ flush_delayed_work_sync(&work);
+ cancel_delayed_work_sync(&work);
+}
+
+struct file_operations dmt_g_sensor_fops = {
+ .owner = THIS_MODULE,
+ .read = device_read,
+ .write = device_write,
+ .unlocked_ioctl = device_ioctl,
+ .open = device_open,
+ .release = device_close,
+};
+
+static const struct i2c_device_id device_i2c_ids[] = {
+ {DEVICE_I2C_NAME, 0},
+ {}
+};
+
+MODULE_DEVICE_TABLE(i2c, device_i2c_ids);
+
+static struct i2c_driver device_i2c_driver = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = DEVICE_I2C_NAME,
+ },
+ .class = I2C_CLASS_HWMON,
+ .probe = device_i2c_probe,
+ .remove = __devexit_p(device_i2c_remove),
+ .suspend = device_i2c_suspend,
+ .resume = device_i2c_resume,
+ .shutdown = device_i2c_shutdown,
+ .id_table = device_i2c_ids,
+};
+
+static int device_open(struct inode *inode, struct file *filp){
+#if DMT_DEBUG_DATA
+ IN_FUNC_MSG;
+#endif
+ //Device_First_Time_Opened_flag
+ if(Device_First_Time_Opened_flag)
+ {
+ Device_First_Time_Opened_flag=0;
+ //gsensor_read_offset_from_file();
+ }
+ return 0;
+}
+
+static ssize_t device_write(struct file *filp, const char *buf, size_t count, loff_t *f_pos)
+{
+ return 0;
+}
+
+static ssize_t device_read(struct file *filp, char *buf, size_t count, loff_t *f_pos)
+{
+ s16 xyz[SENSOR_DATA_SIZE];
+ int i;
+
+ device_i2c_read_xyz(dev.client, (s16 *)&xyz);
+ //offset compensation
+ for(i = 0; i < SENSOR_DATA_SIZE; ++i)
+ xyz[i] -= offset.v[i];
+
+ if(copy_to_user(buf, &xyz, count))
+ return -EFAULT;
+#if DMT_DEBUG_DATA
+ IN_FUNC_MSG;
+ PRINT_X_Y_Z(xyz[0], xyz[1], xyz[2]);
+#endif
+
+ return count;
+}
+
+static long device_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
+{
+ int err = 0, ret = 0, i;
+ int intBuf[SENSOR_DATA_SIZE];
+ s16 xyz[SENSOR_DATA_SIZE];
+ //check type and number
+ if (_IOC_TYPE(cmd) != IOCTL_MAGIC) return -ENOTTY;
+ if (_IOC_NR(cmd) > SENSOR_MAXNR) return -ENOTTY;
+
+ //check user space pointer is valid
+ if (_IOC_DIR(cmd) & _IOC_READ)
+ err = !access_ok(VERIFY_WRITE, (void __user *)arg, _IOC_SIZE(cmd));
+ else if (_IOC_DIR(cmd) & _IOC_WRITE)
+ err = !access_ok(VERIFY_READ, (void __user *)arg, _IOC_SIZE(cmd));
+ if (err) return -EFAULT;
+
+ switch(cmd)
+ {
+ case SENSOR_RESET:
+ //gsensor_reset();
+ printk("RUN RESET");
+ return ret;
+
+ case SENSOR_CALIBRATION:
+ // get orientation info
+ if(copy_from_user(&intBuf, (int*)arg, sizeof(int))) return -EFAULT;
+ gsensor_calibrate(intBuf[0]);
+ // write in to file
+ gsensor_write_offset_to_file();
+
+ // return the offset
+ for(i = 0; i < SENSOR_DATA_SIZE; ++i)
+ intBuf[i] = offset.v[i];
+
+ ret = copy_to_user((int *)arg, &intBuf, sizeof(intBuf));
+ return ret;
+
+ case SENSOR_GET_OFFSET:
+ // get offset from file
+ gsensor_read_offset_from_file();
+
+ for(i = 0; i < SENSOR_DATA_SIZE; ++i)
+ intBuf[i] = offset.v[i];
+
+ ret = copy_to_user((int *)arg, &intBuf, sizeof(intBuf));
+ return ret;
+
+ case SENSOR_SET_OFFSET:
+ ret = copy_from_user(&intBuf, (int *)arg, sizeof(intBuf));
+ gsensor_set_offset(intBuf);
+ // write in to file
+ gsensor_write_offset_to_file();
+ return ret;
+
+ case SENSOR_READ_ACCEL_XYZ:
+ device_i2c_read_xyz(dev.client, (s16 *)&xyz);
+ for(i = 0; i < SENSOR_DATA_SIZE; ++i)
+ intBuf[i] = xyz[i] - offset.v[i];
+
+ ret = copy_to_user((int*)arg, &intBuf, sizeof(intBuf));
+ return ret;
+ case SENSOR_SETYPR:
+ if(copy_from_user(&intBuf, (int*)arg, sizeof(intBuf)))
+ {
+ printk("%s:copy_from_user(&intBuf, (int*)arg, sizeof(intBuf)) ERROR, -EFAULT\n",__func__);
+ return -EFAULT;
+ }
+ input_report_abs(input, ABS_X, intBuf[0]);
+ input_report_abs(input, ABS_Y, intBuf[1]);
+ input_report_abs(input, ABS_Z, intBuf[2]);
+ input_sync(input);
+ //printk("%s:SENSOR_SETYPR OK! x=%d,y=%d,z=%d\n",__func__,intBuf[0],intBuf[1],intBuf[2]);
+
+ return 1;
+ case SENSOR_GET_OPEN_STATUS:
+ //printk("%s:Going into DMT_GetOpenStatus()\n",__func__);
+ DMT_GetOpenStatus();
+ //printk("%s:DMT_GetOpenStatus() finished\n",__func__);
+ return 1;
+ break;
+ case SENSOR_GET_CLOSE_STATUS:
+ //printk("%s:Going into DMT_GetCloseStatus()\n",__func__);
+ DMT_GetCloseStatus();
+ //printk("%s:DMT_GetCloseStatus() finished\n",__func__);
+ return 1;
+ break;
+ case SENSOR_GET_DELAY:
+
+ ret = copy_to_user((int*)arg, &interval, sizeof(interval));
+ return 1;
+ break;
+ default: /* redundant, as cmd was checked against MAXNR */
+ return -ENOTTY;
+ }
+
+ return 0;
+}
+
+static int device_close(struct inode *inode, struct file *filp)
+{
+ printk("Close device\n");
+ return 0;
+}
+
+static int device_i2c_xyz_read_reg(struct i2c_client *client,u8 *buffer, int length)
+{
+ struct i2c_msg msg[] =
+ {
+ {.addr = client->addr, .flags = 0, .len = 1, .buf = buffer,},
+ {.addr = client->addr, .flags = I2C_M_RD, .len = length, .buf = buffer,},
+ };
+#if DMT_DEBUG_DATA
+ IN_FUNC_MSG;
+#endif
+ return i2c_transfer(client->adapter, msg, 2);
+}
+
+void device_i2c_read_xyz(struct i2c_client *client, s16 *xyz_p)
+{
+ u8 buffer[6];
+ s16 xyzTmp[SENSOR_DATA_SIZE];
+ int i, j;
+
+ //get xyz high/low bytes, 0x02~0x07
+ buffer[0] = 2;
+ device_i2c_xyz_read_reg(client, buffer, 6);
+
+ //merge to 11-bits value
+ for(i = 0; i < SENSOR_DATA_SIZE; ++i){
+ xyz_p[i] = 0;
+ device_i2c_merge_register_values(client, (xyzTmp + i), buffer[2*i], buffer[2*i + 1]);
+ //transfer to the default layout
+ for(j = 0; j < 3; j++)
+ xyz_p[i] += sensorlayout[i][j] * xyzTmp[j];
+ }
+}
+
+void device_i2c_merge_register_values(struct i2c_client *client, s16 *val, u8 msb, u8 lsb)
+{
+ *val = (((u16)msb) << 3) | (u16)lsb;
+ device_i2c_correct_accel_sign(val);
+}
+
+static inline void device_i2c_correct_accel_sign(s16 *val)
+{
+ *val<<= (sizeof(s16) * BITS_PER_BYTE - 11);
+ *val>>= (sizeof(s16) * BITS_PER_BYTE - 11);
+}
+
+static void DMT_work_func(struct work_struct *fakework)
+{
+ int i;
+ static int firsttime=0;
+ s16 xyz[SENSOR_DATA_SIZE];
+ unsigned long t=atomic_read(&delay);
+ unsigned long dmt_delay = msecs_to_jiffies(t);
+ if(!firsttime)
+ {
+ //gsensor_read_offset_from_file();
+ firsttime=1;
+ }
+
+ //dmt_delay/=1000;
+
+#if DMT_DEBUG_DATA
+ IN_FUNC_MSG;
+ printk("t=%lu ,dmt_delay=%lu\n",t,dmt_delay);
+#endif
+
+ device_i2c_read_xyz(dev.client, (s16 *)&xyz);
+ for(i = 0; i < SENSOR_DATA_SIZE; ++i)
+ xyz[i] -= offset.v[i];
+
+#if DMT_DEBUG_DATA
+ printk("x: %d, y: %d, z: %d\n", xyz[0], xyz[1], xyz[2]);
+#endif
+ input_report_abs(input, ABS_X, xyz[gs_conf.xyz_axis[ABS_X][0]]*gs_conf.xyz_axis[ABS_X][1]);
+ input_report_abs(input, ABS_Y, xyz[gs_conf.xyz_axis[ABS_Y][0]]*gs_conf.xyz_axis[ABS_Y][1]);
+ input_report_abs(input, ABS_Z, xyz[gs_conf.xyz_axis[ABS_Z][0]]*gs_conf.xyz_axis[ABS_Z][1]);
+ input_sync(input);
+
+ if(dmt_delay<1)
+ dmt_delay=1;
+
+ schedule_delayed_work(&work, dmt_delay);
+}
+
+
+static int __devinit device_i2c_probe(struct i2c_client *client,const struct i2c_device_id *id)
+{
+ u8 buffer[4];
+ int i;
+
+ for(i = 0; i < SENSOR_DATA_SIZE; ++i)
+ offset.v[i] = 0;
+
+ if(!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
+ {
+ printk("%s, functionality check failed\n", __func__);
+ return -1;
+ }
+
+ gsensor_reset();
+
+ buffer[0] = CONTROL_REGISTERS;
+ device_i2c_xyz_read_reg(client, buffer, 4);
+ if( buffer[0] == 0x00 && buffer[1] == 0x00 && buffer[2] == 0x88 && buffer[3] == 0x08)
+ {
+ printk(KERN_INFO "i2c Read 0x08 = %d!\n",buffer[0]);
+ printk(KERN_INFO "i2c Read 0x09 = %d!\n",buffer[1]);
+ printk(KERN_INFO "i2c Read 0x0a = %d!\n",buffer[2]);
+ printk(KERN_INFO "i2c Read 0x0b = %d!\n",buffer[3]);
+ printk(KERN_INFO "@@@ %s DMT_DEVICE_NAME registered I2C driver!\n",__FUNCTION__);
+ dev.client = client;
+ }
+ else
+ {
+ printk(KERN_INFO "err : i2c Read 0x08 = %d!\n",buffer[0]);
+ printk(KERN_INFO "err : i2c Read 0x09 = %d!\n",buffer[1]);
+ printk(KERN_INFO "err : i2c Read 0x0a = %d!\n",buffer[2]);
+ printk(KERN_INFO "err : i2c Read 0x0b = %d!\n",buffer[3]);
+ dev.client = NULL;
+ return -1;
+ }
+#if DMT_DEBUG_DATA
+ IN_FUNC_MSG;
+ //check sensorlayout[i][j]
+ for(i = 0; i < 3; ++i)
+ {
+ for(j = 0; j < 3; j++)
+ printk("%d",sensorlayout[i][j]);
+ printk("\n");
+ }
+#endif
+ return 0;
+}
+
+static int __devexit device_i2c_remove(struct i2c_client *client)
+{
+#if DMT_DEBUG_DATA
+ IN_FUNC_MSG;
+#endif
+ return 0;
+}
+
+int dmt08_enable(int en)
+{
+ printk(KERN_DEBUG "%s: enable = %d\n", __func__, en);
+ DMT_sysfs_update_active_status(en);
+ return 0;
+}
+
+int dmt08_setDelay(int mdelay)
+{
+ printk(KERN_DEBUG "%s: delay = %d\n", __func__, mdelay);
+ atomic_set(&delay, mdelay);
+ return 0;
+}
+
+int dmt08_getLSG(int *lsg)
+{
+ *lsg = 256;
+ return 0;
+}
+
+struct gsensor_data dmt08_gs_data = {
+ .i2c_addr = DMT08_I2C_ADDR,
+ .enable = dmt08_enable,
+ .setDelay = dmt08_setDelay,
+ .getLSG = dmt08_getLSG,
+};
+
+static int __init device_init(void)
+{
+ int err=-1;
+ struct device *device;
+ int ret = 0;
+ IN_FUNC_MSG;
+
+ if (get_gsensor_conf(&gs_conf))
+ return -1;
+
+ if (gs_conf.op != 1)
+ return -1;
+
+ printk("G-Sensor dmt08 init\n");
+
+ if (gsensor_register(&dmt08_gs_data))
+ return -1;
+
+ if (gsensor_i2c_register_device() < 0)
+ return -1;
+
+ atomic_set(&delay, 200);
+
+ ret = alloc_chrdev_region(&dev.devno, 0, 1, GSENSOR_DEVICE_NAME);
+ if(ret)
+ {
+ printk("%s, can't allocate chrdev\n", __func__);
+ return ret;
+ }
+ printk("%s, register chrdev(%d, %d)\n", __func__, MAJOR(dev.devno), MINOR(dev.devno));
+
+ cdev_init(&dev.cdev, &dmt_g_sensor_fops);
+ dev.cdev.owner = THIS_MODULE;
+ ret = cdev_add(&dev.cdev, dev.devno, 1);
+ if(ret < 0)
+ {
+ printk("%s, add character device error, ret %d\n", __func__, ret);
+ return ret;
+ }
+ dev.class = class_create(THIS_MODULE, ACCELEMETER_CLASS_NAME);
+ if(IS_ERR(dev.class))
+ {
+ printk("%s, create class, error\n", __func__);
+ return ret;
+ }
+ device=device_create(dev.class, NULL, dev.devno, NULL, GSENSOR_DEVICE_NAME);
+
+ mutex_init(&DMT_mutex);
+
+ INIT_DELAYED_WORK(&work, DMT_work_func);
+ printk("DMT: INIT_DELAYED_WORK\n");
+
+ err=input_init();
+ if(err)
+ {
+ printk("%s:input_init fail, error code= %d\n", __func__, err);
+ }
+
+ err = create_device_attributes(device,DMT_attributes);
+
+ return i2c_add_driver(&device_i2c_driver);
+}
+
+
+static void __exit device_exit(void)
+{
+ IN_FUNC_MSG;
+ input_unregister_device(input);
+ input_free_device(input);
+ cdev_del(&dev.cdev);
+ unregister_chrdev_region(dev.devno, 1);
+ device_destroy(dev.class, dev.devno);
+ class_destroy(dev.class);
+ i2c_del_driver(&device_i2c_driver);
+}
+
+
+void gsensor_write_offset_to_file(void)
+{
+ char data[18];
+ unsigned int orgfs;
+ long lfile=-1;
+ spinlock_t lock; //add by yang
+ spin_lock_init(&lock); //add by yang
+ sprintf(data,"%5d %5d %5d",offset.u.x,offset.u.y,offset.u.z);
+
+ orgfs = get_fs();
+// Set segment descriptor associated to kernel space
+ set_fs(KERNEL_DS);
+
+ lfile=sys_open(OffsetFileName,O_WRONLY|O_CREAT, 0777);
+ if (lfile < 0)
+ {
+ printk("sys_open %s error!!. %ld\n",OffsetFileName,lfile);
+ }
+ else
+ {
+ spin_lock(&lock); //add by yang
+ sys_write(lfile, data,18);
+ sys_close(lfile);
+ spin_unlock(&lock); //add by yang
+ }
+ set_fs(orgfs);
+}
+
+void gsensor_read_offset_from_file(void)
+{
+ unsigned int orgfs;
+ char data[18];
+ long lfile=-1;
+ orgfs = get_fs();
+// Set segment descriptor associated to kernel space
+ set_fs(KERNEL_DS);
+
+ lfile = sys_open(OffsetFileName, O_RDONLY, 0);
+ if (lfile < 0)
+ {
+ printk("sys_open %s error!!. %ld\n",OffsetFileName,lfile);
+ strcpy(data,"00000 00000 00000");
+
+ }
+ else
+ {
+ sys_read(lfile, data, 18);
+ sys_close(lfile);
+ }
+ sscanf(data,"%hd %hd %hd",&offset.u.x,&offset.u.y,&offset.u.z);
+ printk("%5d %5d %5d",offset.u.x,offset.u.y,offset.u.z);
+ set_fs(orgfs);
+}
+
+MODULE_AUTHOR("DMT_RD");
+MODULE_DESCRIPTION("DMT Gsensor Driver");
+MODULE_LICENSE("GPL");
+
+module_init(device_init);
+module_exit(device_exit);
diff --git a/ANDROID_3.4.5/drivers/input/sensor/TP_DRIVER_NOT_USE/dmt08_gsensor/dmt08.h b/ANDROID_3.4.5/drivers/input/sensor/TP_DRIVER_NOT_USE/dmt08_gsensor/dmt08.h
new file mode 100755
index 00000000..5a1ac3b7
--- /dev/null
+++ b/ANDROID_3.4.5/drivers/input/sensor/TP_DRIVER_NOT_USE/dmt08_gsensor/dmt08.h
@@ -0,0 +1,105 @@
+/*
+ * @file include/linux/dmt.h
+ * @brief DMARD05 & DMARD06 & DMARD07 g-sensor Linux device driver
+ * @author Domintech Technology Co., Ltd (http://www.domintech.com.tw)
+ * @version 1.31
+ * @date 2012/3/27
+ *
+ * @section LICENSE
+ *
+ * Copyright 2011 Domintech Technology Co., Ltd
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ *
+ */
+#ifndef DMT_H
+#define DMT_H
+
+#if (defined(CONFIG_SENSORS_DMARD05) || defined(CONFIG_SENSORS_DMARD05_MODULE))
+#define DEVICE_I2C_NAME "dmard05"
+#define DEFAULT_SENSITIVITY 64
+#define WHO_AM_I_VALUE 0x05
+#define X_OUT 0x41
+#define SW_RESET 0x53
+#define WHO_AM_I 0x0f
+#elif (defined(CONFIG_SENSORS_DMARD06) || defined(CONFIG_SENSORS_DMARD06_MODULE))
+#define DEVICE_I2C_NAME "dmard06"
+#define DEFAULT_SENSITIVITY 32
+#define WHO_AM_I_VALUE 0x06
+#define X_OUT 0x41
+#define SW_RESET 0x53
+#define WHO_AM_I 0x0f
+#elif (defined(CONFIG_SENSORS_DMARD07) || defined(CONFIG_SENSORS_DMARD07_MODULE))
+#define DEVICE_I2C_NAME "dmard07"
+#define DEFAULT_SENSITIVITY 64
+#define WHO_AM_I_VALUE 0x07
+#define X_OUT 0x41
+#define SW_RESET 0x53
+#define WHO_AM_I 0x0f
+#elif (defined(CONFIG_SENSORS_DMARD03) || defined(CONFIG_SENSORS_DMARD03_MODULE))
+#define DEVICE_I2C_NAME "dmard03"
+#define DEFAULT_SENSITIVITY 256
+#define CONTROL_REGISTERS 0x08
+#elif (defined(CONFIG_SENSORS_DMARD08) || defined(CONFIG_SENSORS_DMARD08_MODULE) || defined(CONFIG_WMT_SENSOR_DMT08))
+#define DEVICE_I2C_NAME "g-sensor"
+#define DEFAULT_SENSITIVITY 256
+#define CONTROL_REGISTERS 0x08
+#define DMT08_I2C_ADDR 0x1c
+#endif
+
+//#define DMT_DEBUG_DATA 1
+#define DMT_DEBUG_DATA 0
+
+#if DMT_DEBUG_DATA
+#define IN_FUNC_MSG printk(KERN_INFO "@DMT@ In %s\n", __func__)
+#define PRINT_X_Y_Z(x, y, z) printk(KERN_INFO "@DMT@ X/Y/Z axis: %04d , %04d , %04d\n", (x), (y), (z))
+#define PRINT_OFFSET(x, y, z) printk(KERN_INFO "@offset@ X/Y/Z axis: %04d , %04d , %04d\n",offset.x,offset.y,offset.z);
+#else
+#define IN_FUNC_MSG
+#define PRINT_X_Y_Z(x, y, z)
+#define PRINT_OFFSET(x, y, z)
+#endif
+
+//g-senor layout configuration, choose one of the following configuration
+#define CONFIG_GSEN_LAYOUT_PAT_1
+//#define CONFIG_GSEN_LAYOUT_PAT_2
+//#define CONFIG_GSEN_LAYOUT_PAT_3
+//#define CONFIG_GSEN_LAYOUT_PAT_4
+//#define CONFIG_GSEN_LAYOUT_PAT_5
+//#define CONFIG_GSEN_LAYOUT_PAT_6
+//#define CONFIG_GSEN_LAYOUT_PAT_7
+//#define CONFIG_GSEN_LAYOUT_PAT_8
+
+#define CONFIG_GSEN_CALIBRATION_GRAVITY_ON_Z_NEGATIVE 1
+#define CONFIG_GSEN_CALIBRATION_GRAVITY_ON_Z_POSITIVE 2
+#define CONFIG_GSEN_CALIBRATION_GRAVITY_ON_Y_NEGATIVE 3
+#define CONFIG_GSEN_CALIBRATION_GRAVITY_ON_Y_POSITIVE 4
+#define CONFIG_GSEN_CALIBRATION_GRAVITY_ON_X_NEGATIVE 5
+#define CONFIG_GSEN_CALIBRATION_GRAVITY_ON_X_POSITIVE 6
+
+#define AVG_NUM 16
+
+#define IOCTL_MAGIC 0x09
+#define SENSOR_DATA_SIZE 3
+
+#define SENSOR_RESET _IO(IOCTL_MAGIC, 0)
+#define SENSOR_CALIBRATION _IOWR(IOCTL_MAGIC, 1, int[SENSOR_DATA_SIZE])
+#define SENSOR_GET_OFFSET _IOR(IOCTL_MAGIC, 2, int[SENSOR_DATA_SIZE])
+#define SENSOR_SET_OFFSET _IOWR(IOCTL_MAGIC, 3, int[SENSOR_DATA_SIZE])
+#define SENSOR_READ_ACCEL_XYZ _IOR(IOCTL_MAGIC, 4, int[SENSOR_DATA_SIZE])
+#define SENSOR_SETYPR _IOW(IOCTL_MAGIC, 5, int[SENSOR_DATA_SIZE])
+#define SENSOR_GET_OPEN_STATUS _IO(IOCTL_MAGIC, 6)
+#define SENSOR_GET_CLOSE_STATUS _IO(IOCTL_MAGIC, 7)
+#define SENSOR_GET_DELAY _IOR(IOCTL_MAGIC, 8, unsigned int*)
+
+#define SENSOR_MAXNR 8
+
+#endif
diff --git a/ANDROID_3.4.5/drivers/input/sensor/TP_DRIVER_NOT_USE/dmt10_gsensor/Makefile b/ANDROID_3.4.5/drivers/input/sensor/TP_DRIVER_NOT_USE/dmt10_gsensor/Makefile
new file mode 100755
index 00000000..de723bf5
--- /dev/null
+++ b/ANDROID_3.4.5/drivers/input/sensor/TP_DRIVER_NOT_USE/dmt10_gsensor/Makefile
@@ -0,0 +1,6 @@
+#
+# Makefile for the DMARD10 Sensor driver
+#
+
+sensor_dmt10-objs := dmt10.o
+obj-$(CONFIG_WMT_SENSOR_DMT10) += sensor_dmt10.o
diff --git a/ANDROID_3.4.5/drivers/input/sensor/TP_DRIVER_NOT_USE/dmt10_gsensor/dmt10.c b/ANDROID_3.4.5/drivers/input/sensor/TP_DRIVER_NOT_USE/dmt10_gsensor/dmt10.c
new file mode 100755
index 00000000..e8e7b288
--- /dev/null
+++ b/ANDROID_3.4.5/drivers/input/sensor/TP_DRIVER_NOT_USE/dmt10_gsensor/dmt10.c
@@ -0,0 +1,950 @@
+/*
+ * @file drivers/misc/dmt10.c
+ * @brief DMT g-sensor Linux device driver
+ * @author Domintech Technology Co., Ltd (http://www.domintech.com.tw)
+ * @version 1.03
+ *
+ * @section LICENSE
+ *
+ * Copyright 2012 Domintech Technology Co., Ltd
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * V1.00 D10 First Release date 2012/09/21
+ * V1.01 static struct dmt_data s_dmt Refresh to device_i2c_probe date 2012/11/23
+ * V1.02 0x0D cck : adjustment 204.8KHz core clock date 2012/11/30
+ * V1.03 write TCGYZ & TCGX : set value to 0x00 date 2012/12/10
+ *
+ * @DMT Package version D10_General_driver v1.4
+ *
+ */
+#include "dmt10.h"
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include "../gsensor.h"
+
+static struct gsensor_conf gs_conf;
+
+static unsigned int interval;
+void gsensor_write_offset_to_file(void);
+void gsensor_read_offset_from_file(void);
+char OffsetFileName[] = "/data/misc/dmt/offset.txt"; /* FILE offset.txt */
+static raw_data offset;
+static struct dmt_data *s_dmt;
+static int device_init(void);
+static void device_exit(void);
+
+static int device_open(struct inode*, struct file*);
+static long device_ioctl(struct file *filp, unsigned int cmd, unsigned long arg);
+static int device_close(struct inode*, struct file*);
+
+static int device_i2c_suspend(struct i2c_client *client, pm_message_t mesg);
+static int device_i2c_resume(struct i2c_client *client);
+static int __devinit device_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id);
+static int __devexit device_i2c_remove(struct i2c_client *client);
+void device_i2c_read_xyz(struct i2c_client *client, s16 *xyz);
+static int device_i2c_rxdata(struct i2c_client *client, unsigned char *rxDat, int length);
+static int device_i2c_txdata(struct i2c_client *client, unsigned char *txData, int length);
+
+static int DMT_GetOpenStatus(struct i2c_client *client){
+ struct dmt_data *dmt = i2c_get_clientdata(client);
+ GSE_LOG("start active=%d\n",dmt->active.counter);
+ wait_event_interruptible(dmt->open_wq, (atomic_read(&dmt->active) != 0));
+ return 0;
+}
+
+static int DMT_GetCloseStatus(struct i2c_client *client){
+ struct dmt_data *dmt = i2c_get_clientdata(client);
+ GSE_LOG("start active=%d\n",dmt->active.counter);
+ wait_event_interruptible(dmt->open_wq, (atomic_read(&dmt->active) <= 0));
+ return 0;
+}
+
+static void DMT_sysfs_update_active_status(struct dmt_data *dmt , int en){
+ unsigned long dmt_delay;
+ if(en){
+ dmt_delay = msecs_to_jiffies(atomic_read(&dmt->delay));
+ if(dmt_delay < 1)
+ dmt_delay = 1;
+
+ GSE_LOG("schedule_delayed_work start with delay time=%lu\n",dmt_delay);
+ schedule_delayed_work(&dmt->delaywork,dmt_delay);
+ }
+ else
+ cancel_delayed_work_sync(&dmt->delaywork);
+}
+
+static bool get_value_as_int(char const *buf, size_t size, int *value){
+ long tmp;
+ if (size == 0)
+ return false;
+ /* maybe text format value */
+ if ((buf[0] == '0') && (size > 1)) {
+ if ((buf[1] == 'x') || (buf[1] == 'X')) {
+ /* hexadecimal format */
+ if (0 != strict_strtol(buf, 16, &tmp))
+ return false;
+ } else {
+ /* octal format */
+ if (0 != strict_strtol(buf, 8, &tmp))
+ return false;
+ }
+ } else {
+ /* decimal format */
+ if (0 != strict_strtol(buf, 10, &tmp))
+ return false;
+ }
+
+ if (tmp > INT_MAX)
+ return false;
+
+ *value = tmp;
+ return true;
+}
+static bool get_value_as_int64(char const *buf, size_t size, long long *value)
+{
+ long long tmp;
+ if (size == 0)
+ return false;
+ /* maybe text format value */
+ if ((buf[0] == '0') && (size > 1)) {
+ if ((buf[1] == 'x') || (buf[1] == 'X')) {
+ /* hexadecimal format */
+ if (0 != strict_strtoll(buf, 16, &tmp))
+ return false;
+ } else {
+ /* octal format */
+ if (0 != strict_strtoll(buf, 8, &tmp))
+ return false;
+ }
+ } else {
+ /* decimal format */
+ if (0 != strict_strtoll(buf, 10, &tmp))
+ return false;
+ }
+
+ if (tmp > LLONG_MAX)
+ return false;
+
+ *value = tmp;
+ return true;
+}
+
+static ssize_t dmt_sysfs_enable_show(
+ struct dmt_data *dmt, char *buf, int pos)
+{
+ char str[2][16]={"ACC enable OFF","ACC enable ON"};
+ int flag;
+ flag=atomic_read(&dmt->enable);
+ return sprintf(buf, "%s\n", str[flag]);
+}
+
+static ssize_t dmt_sysfs_enable_store(
+ struct dmt_data *dmt, char const *buf, size_t count, int pos)
+{
+ int en = 0;
+ if (NULL == buf)
+ return -EINVAL;
+ GSE_LOG("buf=%x %x\n", buf[0], buf[1]);
+ if (0 == count)
+ return 0;
+
+ if (false == get_value_as_int(buf, count, &en))
+ return -EINVAL;
+
+ en = en ? 1 : 0;
+
+ atomic_set(&dmt->enable,en);
+ DMT_sysfs_update_active_status(dmt , en);
+ return count;
+}
+
+/***** Acceleration ***/
+static ssize_t DMT_enable_acc_show(struct device *dev, struct device_attribute *attr, char *buf){
+ return dmt_sysfs_enable_show( dev_get_drvdata(dev), buf, ACC_DATA_FLAG);
+}
+
+static ssize_t DMT_enable_acc_store( struct device *dev, struct device_attribute *attr, char const *buf, size_t count){
+ return dmt_sysfs_enable_store( dev_get_drvdata(dev), buf, count, ACC_DATA_FLAG);
+}
+
+/***** sysfs delay **************************************************/
+static ssize_t dmt_sysfs_delay_show( struct dmt_data *dmt, char *buf, int pos){
+ return sprintf(buf, "%d\n", atomic_read(&dmt->delay));
+}
+
+static ssize_t dmt_sysfs_delay_store( struct dmt_data *dmt, char const *buf, size_t count, int pos){
+ long long val = 0;
+
+ if (NULL == buf)
+ return -EINVAL;
+
+ if (0 == count)
+ return 0;
+
+ if (false == get_value_as_int64(buf, count, &val))
+ return -EINVAL;
+
+ atomic_set(&dmt->delay, (unsigned int) val);
+ GSE_LOG("Driver attribute set delay =%lld\n", val);
+
+ return count;
+}
+
+/***** Accelerometer ***/
+static ssize_t DMT_delay_acc_show( struct device *dev, struct device_attribute *attr, char *buf){
+ return dmt_sysfs_delay_show( dev_get_drvdata(dev), buf, ACC_DATA_FLAG);
+}
+
+static ssize_t DMT_delay_acc_store( struct device *dev, struct device_attribute *attr,char const *buf, size_t count){
+ return dmt_sysfs_delay_store( dev_get_drvdata(dev), buf, count, ACC_DATA_FLAG);
+}
+
+static struct device_attribute DMT_attributes[] = {
+ __ATTR(enable_acc, 0755, DMT_enable_acc_show, DMT_enable_acc_store),
+ __ATTR(delay_acc, 0755, DMT_delay_acc_show, DMT_delay_acc_store),
+ __ATTR_NULL,
+};
+
+static char const *const ACCELEMETER_CLASS_NAME = "accelemeter";
+static char const *const GSENSOR_DEVICE_NAME = "dmard10";
+static char const *const device_link_name = "i2c";
+static dev_t const dmt_device_dev_t = MKDEV(MISC_MAJOR, 240);
+
+/***** dmt sysfs functions ******************************************/
+static int create_device_attributes(struct device *dev, struct device_attribute *attrs){
+ int i;
+ int err = 0;
+ for (i = 0 ; NULL != attrs[i].attr.name ; ++i) {
+ err = device_create_file(dev, &attrs[i]);
+ if (0 != err)
+ break;
+ }
+
+ if (0 != err) {
+ for (; i >= 0 ; --i)
+ device_remove_file(dev, &attrs[i]);
+ }
+ return err;
+}
+
+static void remove_device_attributes(
+ struct device *dev,
+ struct device_attribute *attrs)
+{
+ int i;
+
+ for (i = 0 ; NULL != attrs[i].attr.name ; ++i)
+ device_remove_file(dev, &attrs[i]);
+}
+
+static int create_sysfs_interfaces(struct dmt_data *dmt)
+{
+ int err;
+
+ if (NULL == dmt)
+ return -EINVAL;
+
+ err = 0;
+ dmt->class = class_create(THIS_MODULE, ACCELEMETER_CLASS_NAME);
+ if (IS_ERR(dmt->class)) {
+ err = PTR_ERR(dmt->class);
+ goto exit_class_create_failed;
+ }
+
+ dmt->class_dev = device_create(
+ dmt->class,
+ NULL,
+ dmt_device_dev_t,
+ dmt,
+ GSENSOR_DEVICE_NAME);
+ if (IS_ERR(dmt->class_dev)) {
+ err = PTR_ERR(dmt->class_dev);
+ goto exit_class_device_create_failed;
+ }
+
+ err = sysfs_create_link(
+ &dmt->class_dev->kobj,
+ &dmt->client->dev.kobj,
+ device_link_name);
+ if (0 > err)
+ goto exit_sysfs_create_link_failed;
+
+ err = create_device_attributes(
+ dmt->class_dev,
+ DMT_attributes);
+ if (0 > err)
+ goto exit_device_attributes_create_failed;
+#if 0
+ err = create_device_binary_attributes(
+ &dmt->class_dev->kobj,
+ dmt_bin_attributes);
+ if (0 > err)
+ goto exit_device_binary_attributes_create_failed;
+#endif
+
+ return err;
+
+#if 0
+exit_device_binary_attributes_create_failed:
+ remove_device_attributes(dmt->class_dev, dmt_attributes);
+#endif
+exit_device_attributes_create_failed:
+ sysfs_remove_link(&dmt->class_dev->kobj, device_link_name);
+exit_sysfs_create_link_failed:
+ device_destroy(dmt->class, dmt_device_dev_t);
+exit_class_device_create_failed:
+ dmt->class_dev = NULL;
+ class_destroy(dmt->class);
+exit_class_create_failed:
+ dmt->class = NULL;
+ return err;
+}
+
+static void remove_sysfs_interfaces(struct dmt_data *dmt)
+{
+ if (NULL == dmt)
+ return;
+
+ if (NULL != dmt->class_dev) {
+
+ remove_device_attributes(
+ dmt->class_dev,
+ DMT_attributes);
+ sysfs_remove_link(
+ &dmt->class_dev->kobj,
+ device_link_name);
+ dmt->class_dev = NULL;
+ }
+ if (NULL != dmt->class) {
+ device_destroy(
+ dmt->class,
+ dmt_device_dev_t);
+ class_destroy(dmt->class);
+ dmt->class = NULL;
+ }
+}
+
+int input_init(struct i2c_client *client){
+ struct dmt_data *dmt = i2c_get_clientdata(client);
+ int err=0;
+ dmt->input=input_allocate_device();
+ if (!dmt->input){
+ GSE_ERR("input device allocate ERROR !!\n");
+ return -ENOMEM;
+ }
+ else
+ GSE_LOG("input device allocate Success !!\n");
+ /* Setup input device */
+ set_bit(EV_ABS, dmt->input->evbit);
+ /* Accelerometer [-78.5, 78.5]m/s2 in Q16 */
+ input_set_abs_params(dmt->input, ABS_X, -1024, 1024, 0, 0);
+ input_set_abs_params(dmt->input, ABS_Y, -1024, 1024, 0, 0);
+ input_set_abs_params(dmt->input, ABS_Z, -1024, 1024, 0, 0);
+ /* Set InputDevice Name */
+ dmt->input->name = INPUT_NAME_ACC;
+ /* Register */
+ err = input_register_device(dmt->input);
+ if (err) {
+ GSE_ERR("input_register_device ERROR !!\n");
+ input_free_device(dmt->input);
+ return err;
+ }
+ GSE_LOG("input_register_device SUCCESS %d !! \n",err);
+
+ return err;
+}
+
+int gsensor_calibrate(void)
+{
+ //struct dmt_data *dmt = i2c_get_clientdata(client);
+ raw_data avg;
+ int i, j;
+ long xyz_acc[SENSOR_DATA_SIZE];
+ s16 xyz[SENSOR_DATA_SIZE];
+
+ offset.u.x=0;
+ offset.u.y=0;
+ offset.u.z=0;
+ /* initialize the accumulation buffer */
+ for(i = 0; i < SENSOR_DATA_SIZE; ++i)
+ xyz_acc[i] = 0;
+
+ for(i = 0; i < AVG_NUM; i++) {
+ device_i2c_read_xyz(s_dmt->client, (s16 *)&xyz);
+ for(j = 0; j < SENSOR_DATA_SIZE; ++j)
+ xyz_acc[j] += xyz[j];
+ }
+ /* calculate averages */
+ for(i = 0; i < SENSOR_DATA_SIZE; ++i)
+ avg.v[i] = (s16) (xyz_acc[i] / AVG_NUM);
+
+ if(avg.v[2] < 0){
+ offset.u.x = avg.v[0] ;
+ offset.u.y = avg.v[1] ;
+ offset.u.z = avg.v[2] + DEFAULT_SENSITIVITY;
+ return CONFIG_GSEN_CALIBRATION_GRAVITY_ON_Z_POSITIVE;
+ }
+ else{
+ offset.u.x = avg.v[0] ;
+ offset.u.y = avg.v[1] ;
+ offset.u.z = avg.v[2] - DEFAULT_SENSITIVITY;
+ return CONFIG_GSEN_CALIBRATION_GRAVITY_ON_Z_NEGATIVE;
+ }
+ return 0;
+}
+
+int gsensor_reset(struct i2c_client *client){
+ unsigned char buffer[7], buffer2[2];
+ /* 1. check D10 , VALUE_STADR = 0x55 , VALUE_STAINT = 0xAA */
+ buffer[0] = REG_STADR;
+ buffer2[0] = REG_STAINT;
+
+ device_i2c_rxdata(client, buffer, 2);
+ device_i2c_rxdata(client, buffer2, 2);
+
+ if( buffer[0] == VALUE_STADR || buffer2[0] == VALUE_STAINT){
+ GSE_LOG(" REG_STADR_VALUE = %d , REG_STAINT_VALUE = %d\n", buffer[0], buffer2[0]);
+ }
+ else{
+ GSE_LOG(" REG_STADR_VALUE = %d , REG_STAINT_VALUE = %d \n", buffer[0], buffer2[0]);
+ return -1;
+ }
+ /* 2. Powerdown reset */
+ buffer[0] = REG_PD;
+ buffer[1] = VALUE_PD_RST;
+ device_i2c_txdata(client, buffer, 2);
+ /* 3. ACTR => Standby mode => Download OTP to parameter reg => Standby mode => Reset data path => Standby mode */
+ buffer[0] = REG_ACTR;
+ buffer[1] = MODE_Standby;
+ buffer[2] = MODE_ReadOTP;
+ buffer[3] = MODE_Standby;
+ buffer[4] = MODE_ResetDataPath;
+ buffer[5] = MODE_Standby;
+ device_i2c_txdata(client, buffer, 6);
+ /* 4. OSCA_EN = 1 ,TSTO = b'000(INT1 = normal, TEST0 = normal) */
+ buffer[0] = REG_MISC2;
+ buffer[1] = VALUE_MISC2_OSCA_EN;
+ device_i2c_txdata(client, buffer, 2);
+ /* 5. AFEN = 1(AFE will powerdown after ADC) */
+ buffer[0] = REG_AFEM;
+ buffer[1] = VALUE_AFEM_AFEN_Normal;
+ buffer[2] = VALUE_CKSEL_ODR_100_204;
+ buffer[3] = VALUE_INTC;
+ buffer[4] = VALUE_TAPNS_Ave_2;
+ buffer[5] = 0x00; // DLYC, no delay timing
+ buffer[6] = 0x07; // INTD=1 (push-pull), INTA=1 (active high), AUTOT=1 (enable T)
+ device_i2c_txdata(client, buffer, 7);
+ /* 6. write TCGYZ & TCGX */
+ buffer[0] = REG_WDAL; // REG:0x01
+ buffer[1] = 0x00; // set TC of Y,Z gain value
+ buffer[2] = 0x00; // set TC of X gain value
+ buffer[3] = 0x03; // Temperature coefficient of X,Y,Z gain
+ device_i2c_txdata(client, buffer, 4);
+
+ buffer[0] = REG_ACTR; // REG:0x00
+ buffer[1] = MODE_Standby; // Standby
+ buffer[2] = MODE_WriteOTPBuf; // WriteOTPBuf
+ buffer[3] = MODE_Standby; // Standby
+ device_i2c_txdata(client, buffer, 4);
+ //buffer[0] = REG_TCGYZ;
+ //device_i2c_rxdata(client, buffer, 2);
+ //GSE_LOG(" TCGYZ = %d, TCGX = %d \n", buffer[0], buffer[1]);
+
+ /* 7. Activation mode */
+ buffer[0] = REG_ACTR;
+ buffer[1] = MODE_Active;
+ device_i2c_txdata(client, buffer, 2);
+ return 0;
+}
+
+void gsensor_set_offset(int val[3]){
+ int i;
+ for(i = 0; i < SENSOR_DATA_SIZE; ++i)
+ offset.v[i] = (s16) val[i];
+}
+
+struct file_operations dmt_g_sensor_fops = {
+ .owner = THIS_MODULE,
+ .unlocked_ioctl = device_ioctl,
+ .open = device_open,
+ .release = device_close,
+};
+
+static struct miscdevice dmt_device = {
+ .minor = MISC_DYNAMIC_MINOR,
+ .name = DEVICE_I2C_NAME,
+ .fops = &dmt_g_sensor_fops,
+};
+
+static int sensor_close_dev(struct i2c_client *client){
+ char buffer[3];
+ buffer[0] = REG_ACTR;
+ buffer[1] = MODE_Standby;
+ buffer[2] = MODE_Off;
+ GSE_FUN();
+ return device_i2c_txdata(client,buffer, 3);
+}
+
+static int device_i2c_suspend(struct i2c_client *client, pm_message_t mesg){
+ GSE_FUN();
+ return sensor_close_dev(client);
+}
+
+static int device_i2c_resume(struct i2c_client *client){
+ GSE_FUN();
+ return gsensor_reset(client);
+}
+
+static void device_i2c_shutdown(struct i2c_client *client)
+{
+ struct dmt_data *dmt = i2c_get_clientdata(client);
+ flush_delayed_work_sync(&dmt->delaywork);
+ cancel_delayed_work_sync(&dmt->delaywork);
+}
+
+static int __devexit device_i2c_remove(struct i2c_client *client){
+ return 0;
+}
+
+static const struct i2c_device_id device_i2c_ids[] = {
+ {DEVICE_I2C_NAME, 0},
+ {}
+};
+
+//MODULE_DEVICE_TABLE(i2c, device_i2c_ids);
+
+static struct i2c_driver device_i2c_driver =
+{
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = DEVICE_I2C_NAME,
+ },
+ .class = I2C_CLASS_HWMON,
+ .id_table = device_i2c_ids,
+ .probe = device_i2c_probe,
+ .remove = __devexit_p(device_i2c_remove),
+ .shutdown = device_i2c_shutdown,
+#ifndef CONFIG_ANDROID_POWER
+ .suspend = device_i2c_suspend,
+ .resume = device_i2c_resume,
+#endif
+
+};
+
+static int device_open(struct inode *inode, struct file *filp)
+{
+ return 0;
+}
+
+static long device_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
+{
+ //struct i2c_client *client = (struct i2c_client*)filp->private_data;
+ //struct dmt_data *dmt = (struct dmt_data*)i2c_get_clientdata(client);
+
+ int err = 0, ret = 0, i;
+ int intBuf[SENSOR_DATA_SIZE];
+ s16 xyz[SENSOR_DATA_SIZE];
+ /* check type */
+ if (_IOC_TYPE(cmd) != IOCTL_MAGIC) return -ENOTTY;
+
+ /* check user space pointer is valid */
+ if (_IOC_DIR(cmd) & _IOC_READ)
+ err = !access_ok(VERIFY_WRITE, (void __user *)arg, _IOC_SIZE(cmd));
+ else if (_IOC_DIR(cmd) & _IOC_WRITE)
+ err = !access_ok(VERIFY_READ, (void __user *)arg, _IOC_SIZE(cmd));
+ if (err) return -EFAULT;
+
+ switch(cmd)
+ {
+ case SENSOR_RESET:
+ gsensor_reset(s_dmt->client);
+ return ret;
+
+ case SENSOR_CALIBRATION:
+ /* get orientation info */
+ //if(copy_from_user(&intBuf, (int*)arg, sizeof(intBuf))) return -EFAULT;
+ gsensor_calibrate();
+ GSE_LOG("Sensor_calibration:%d %d %d\n",offset.u.x,offset.u.y,offset.u.z);
+ /* save file */
+ gsensor_write_offset_to_file();
+
+ /* return the offset */
+ for(i = 0; i < SENSOR_DATA_SIZE; ++i)
+ intBuf[i] = offset.v[i];
+
+ ret = copy_to_user((int *)arg, &intBuf, sizeof(intBuf));
+ return ret;
+
+ case SENSOR_GET_OFFSET:
+ /* get data from file */
+ gsensor_read_offset_from_file();
+ for(i = 0; i < SENSOR_DATA_SIZE; ++i)
+ intBuf[i] = offset.v[i];
+
+ ret = copy_to_user((int *)arg, &intBuf, sizeof(intBuf));
+ return ret;
+
+ case SENSOR_SET_OFFSET:
+ ret = copy_from_user(&intBuf, (int *)arg, sizeof(intBuf));
+ gsensor_set_offset(intBuf);
+ /* write in to file */
+ gsensor_write_offset_to_file();
+ return ret;
+
+ case SENSOR_READ_ACCEL_XYZ:
+ device_i2c_read_xyz(s_dmt->client, (s16 *)&xyz);
+ for(i = 0; i < SENSOR_DATA_SIZE; ++i)
+ intBuf[i] = xyz[i] - offset.v[i];
+
+ ret = copy_to_user((int*)arg, &intBuf, sizeof(intBuf));
+ return ret;
+
+ case SENSOR_SETYPR:
+ if(copy_from_user(&intBuf, (int*)arg, sizeof(intBuf))) {
+ GSE_LOG("%s:copy_from_user(&intBuf, (int*)arg, sizeof(intBuf)) ERROR, -EFAULT\n",__func__);
+ return -EFAULT;
+ }
+ input_report_abs(s_dmt->input, ABS_X, intBuf[0]);
+ input_report_abs(s_dmt->input, ABS_Y, -intBuf[1]);
+ input_report_abs(s_dmt->input, ABS_Z, -intBuf[2]);
+ input_sync(s_dmt->input);
+ GSE_LOG(KERN_INFO "%s:SENSOR_SETYPR OK! x=%d,y=%d,z=%d\n",__func__,intBuf[0],intBuf[1],intBuf[2]);
+ return 1;
+
+ case SENSOR_GET_OPEN_STATUS:
+ GSE_LOG(KERN_INFO "%s:Going into DMT_GetOpenStatus()\n",__func__);
+ DMT_GetOpenStatus(s_dmt->client);
+ GSE_LOG(KERN_INFO "%s:DMT_GetOpenStatus() finished\n",__func__);
+ return 1;
+ break;
+
+ case SENSOR_GET_CLOSE_STATUS:
+ GSE_LOG(KERN_INFO "%s:Going into DMT_GetCloseStatus()\n",__func__);
+ DMT_GetCloseStatus(s_dmt->client);
+ GSE_LOG(KERN_INFO "%s:DMT_GetCloseStatus() finished\n",__func__);
+ return 1;
+ break;
+
+ case SENSOR_GET_DELAY:
+ ret = copy_to_user((int*)arg, &interval, sizeof(interval));
+ return 1;
+ break;
+
+ default: /* redundant, as cmd was checked against MAXNR */
+ return -ENOTTY;
+ }
+
+ return 0;
+}
+
+static int device_close(struct inode *inode, struct file *filp)
+{
+ return 0;
+}
+
+/***** I2C I/O function ***********************************************/
+static int device_i2c_rxdata( struct i2c_client *client, unsigned char *rxData, int length)
+{
+ struct i2c_msg msgs[] =
+ {
+ {.addr = client->addr, .flags = 0, .len = 1, .buf = rxData,},
+ {.addr = client->addr, .flags = I2C_M_RD, .len = length, .buf = rxData,},
+ };
+ //unsigned char addr = rxData[0];
+ if (i2c_transfer(client->adapter, msgs, 2) < 0) {
+ dev_err(&client->dev, "%s: transfer failed.", __func__);
+ return -EIO;
+ }
+ //DMT_DATA(&client->dev, "RxData: len=%02x, addr=%02x, data=%02x\n",
+ //length, addr, rxData[0]);
+
+ return 0;
+}
+
+static int device_i2c_txdata( struct i2c_client *client, unsigned char *txData, int length)
+{
+ struct i2c_msg msg[] =
+ {
+ {.addr = client->addr, .flags = 0, .len = length, .buf = txData,},
+ };
+
+ if (i2c_transfer(client->adapter, msg, 1) < 0) {
+ dev_err(&client->dev, "%s: transfer failed.", __func__);
+ return -EIO;
+ }
+ //DMT_DATA(&client->dev, "TxData: len=%02x, addr=%02x data=%02x\n",
+ //length, txData[0], txData[1]);
+ return 0;
+}
+/* 1g = 128 becomes 1g = 1024 */
+static inline void device_i2c_correct_accel_sign(s16 *val){
+ *val<<= 3;
+}
+
+void device_i2c_merge_register_values(struct i2c_client *client, s16 *val, u8 msb, u8 lsb){
+ *val = (((u16)msb) << 8) | (u16)lsb;
+ device_i2c_correct_accel_sign(val);
+}
+
+void device_i2c_read_xyz(struct i2c_client *client, s16 *xyz_p){
+ u8 buffer[11];
+ s16 xyzTmp[SENSOR_DATA_SIZE];
+ int i, j;
+ /* get xyz high/low bytes, 0x12 */
+ buffer[0] = REG_STADR;
+ device_i2c_rxdata(client, buffer, 10);
+
+ /* merge to 10-bits value */
+ for(i = 0; i < SENSOR_DATA_SIZE; ++i){
+ xyz_p[i] = 0;
+ device_i2c_merge_register_values(client, (xyzTmp + i), buffer[2*(i+1)+1], buffer[2*(i+1)]);
+ /* transfer to the default layout */
+ for(j = 0; j < 3; j++)
+ xyz_p[i] += sensorlayout[i][j] * xyzTmp[j];
+ }
+ GSE_LOG("xyz_p: %04d , %04d , %04d\n", xyz_p[0], xyz_p[1], xyz_p[2]);
+}
+
+static void DMT_work_func(struct work_struct *delaywork)
+{
+ struct dmt_data *dmt = container_of(delaywork, struct dmt_data, delaywork.work);
+ int i;
+ static int firsttime=0;
+ s16 xyz[SENSOR_DATA_SIZE];
+
+ unsigned long t=atomic_read(&dmt->delay);
+ unsigned long dmt_delay = msecs_to_jiffies(t);
+ if(!firsttime){
+ //gsensor_read_offset_from_file();
+ firsttime=1;
+ }
+
+ GSE_LOG("t=%lu , dmt_delay=%lu\n", t, dmt_delay);
+ device_i2c_read_xyz(dmt->client, (s16 *)&xyz);
+ for(i = 0; i < SENSOR_DATA_SIZE; ++i)
+ xyz[i] -= offset.v[i];
+
+ GSE_LOG("@DMTRaw@ X/Y/Z axis: %04d , %04d , %04d\n", xyz[0], xyz[1], xyz[2]);
+ GSE_LOG("@Offset@ X/Y/Z axis: %04d , %04d , %04d\n", offset.u.x, offset.u.y, offset.u.z);
+ input_report_abs(dmt->input, ABS_X, xyz[gs_conf.xyz_axis[ABS_X][0]]*gs_conf.xyz_axis[ABS_X][1]);
+ input_report_abs(dmt->input, ABS_Y, xyz[gs_conf.xyz_axis[ABS_Y][0]]*gs_conf.xyz_axis[ABS_Y][1]);
+ input_report_abs(dmt->input, ABS_Z, xyz[gs_conf.xyz_axis[ABS_Z][0]]*gs_conf.xyz_axis[ABS_Z][1]);
+ input_sync(dmt->input);
+
+ if(dmt_delay < 1)
+ dmt_delay = 1;
+ schedule_delayed_work(&dmt->delaywork, dmt_delay);
+}
+
+static int __devinit device_i2c_probe(struct i2c_client *client,const struct i2c_device_id *id){
+ int i, ret = 0;
+ //struct dmt_data *s_dmt;
+
+ GSE_FUN();
+ for(i = 0; i < SENSOR_DATA_SIZE; ++i)
+ offset.v[i] = 0;
+
+ if(!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)){
+ GSE_ERR("check_functionality failed.\n");
+ ret = -ENODEV;
+ goto exit0;
+ }
+
+ /* Allocate memory for driver data */
+ s_dmt = kzalloc(sizeof(struct dmt_data), GFP_KERNEL);
+ memset(s_dmt, 0, sizeof(struct dmt_data));
+ if (s_dmt == NULL) {
+ GSE_ERR("alloc data failed.\n");
+ ret = -ENOMEM;
+ goto exit1;
+ }
+
+ /***** I2C initialization *****/
+ s_dmt->client = client;
+ /* set client data */
+ i2c_set_clientdata(client, s_dmt);
+ ret = gsensor_reset(client);
+ if (ret < 0)
+ goto exit2;
+
+ /***** input *****/
+ ret = input_init(client);
+ if (ret){
+ GSE_ERR("input_init fail, error code= %d\n",ret);
+ goto exit3;
+ }
+
+ /**** initialize variables in dmt_data *****/
+ init_waitqueue_head(&s_dmt->open_wq);
+ atomic_set(&s_dmt->active, 0);
+ atomic_set(&s_dmt->enable, 0);
+ atomic_set(&s_dmt->delay, 0);
+ mutex_init(&s_dmt->sensor_mutex);
+ /***** misc *****/
+ /* we have been register miscdevice in device_init, and
+ * marked by Eason 2013/2/4*/
+ /*ret = misc_register(&dmt_device);
+ if (ret){
+ GSE_ERR("dmt_dev register failed");
+ goto exit5;
+ }*/
+
+ /***** sysfs *****/
+ ret = create_sysfs_interfaces(s_dmt);
+ if (ret < 0){
+ GSE_ERR("create sysfs failed.");
+ goto exit6;
+ }
+
+ INIT_DELAYED_WORK(&s_dmt->delaywork, DMT_work_func);
+ GSE_LOG("DMT: INIT_DELAYED_WORK\n");
+ return 0;
+
+exit6:
+ //misc_deregister(&dmt_device);
+exit5:
+ input_unregister_device(s_dmt->input);
+exit3:
+ kfree(s_dmt);
+exit2:
+exit1:
+exit0:
+ return ret;
+}
+
+int dmt10_enable(int en)
+{
+ printk(KERN_DEBUG "%s: enable = %d\n", __func__, en);
+ DMT_sysfs_update_active_status(s_dmt,en);
+ return 0;
+}
+
+int dmt10_setDelay(int mdelay)
+{
+ printk(KERN_DEBUG "%s: delay = %d\n", __func__, mdelay);
+ atomic_set(&s_dmt->delay, mdelay);
+ return 0;
+}
+
+int dmt10_getLSG(int *lsg)
+{
+ *lsg = 1024;
+ return 0;
+}
+
+struct gsensor_data dmt10_gs_data = {
+ .i2c_addr = DMT10_I2C_ADDR,
+ .enable = dmt10_enable,
+ .setDelay = dmt10_setDelay,
+ .getLSG = dmt10_getLSG,
+};
+
+static int __init device_init(void){
+ int ret = 0;
+
+ if (get_gsensor_conf(&gs_conf))
+ return -1;
+
+ if (gs_conf.op != 3)
+ return -1;
+ printk("G-Sensor dmt10 init\n");
+
+ if (gsensor_register(&dmt10_gs_data))
+ return -1;
+
+ if (gsensor_i2c_register_device() < 0)
+ return -1;
+
+ return i2c_add_driver(&device_i2c_driver);
+}
+
+static void __exit device_exit(void){
+ i2c_del_driver(&device_i2c_driver);
+}
+
+void gsensor_write_offset_to_file(void){
+ char data[18];
+ unsigned int orgfs;
+ struct file *fp;
+
+ sprintf(data,"%5d %5d %5d",offset.u.x,offset.u.y,offset.u.z);
+ orgfs = get_fs();
+ /* Set segment descriptor associated to kernel space */
+ set_fs(KERNEL_DS);
+ fp = filp_open(OffsetFileName, O_RDWR | O_CREAT, 0777);
+ if(IS_ERR(fp)){
+ GSE_ERR("filp_open %s error!!.\n",OffsetFileName);
+ }
+ else{
+ GSE_LOG("filp_open %s SUCCESS!!.\n",OffsetFileName);
+ fp->f_op->write(fp,data,18, &fp->f_pos);
+ filp_close(fp,NULL);
+ }
+ set_fs(orgfs);
+}
+
+void gsensor_read_offset_from_file(void){
+ unsigned int orgfs;
+ char data[18];
+ struct file *fp;
+ int ux,uy,uz;
+ orgfs = get_fs();
+ /* Set segment descriptor associated to kernel space */
+ set_fs(KERNEL_DS);
+
+ fp = filp_open(OffsetFileName, O_RDWR , 0);
+ GSE_FUN();
+ if(IS_ERR(fp)){
+ GSE_ERR("Sorry,file open ERROR !\n");
+ offset.u.x=0;offset.u.y=0;offset.u.z=0;
+#if AUTO_CALIBRATION
+ /* get acceleration average reading */
+ gsensor_calibrate();
+ gsensor_write_offset_to_file();
+#endif
+ }
+ else{
+ GSE_LOG("filp_open %s SUCCESS!!.\n",OffsetFileName);
+ fp->f_op->read(fp,data,18, &fp->f_pos);
+ GSE_LOG("filp_read result %s\n",data);
+ sscanf(data,"%d %d %d",&ux,&uy,&uz);
+ offset.u.x=ux;
+ offset.u.y=uy;
+ offset.u.z=uz;
+ filp_close(fp,NULL);
+ }
+ set_fs(orgfs);
+}
+//*********************************************************************************************************
+MODULE_AUTHOR("DMT_RD");
+MODULE_DESCRIPTION("DMT Gsensor Driver");
+MODULE_LICENSE("GPL");
+
+module_init(device_init);
+module_exit(device_exit);
diff --git a/ANDROID_3.4.5/drivers/input/sensor/TP_DRIVER_NOT_USE/dmt10_gsensor/dmt10.h b/ANDROID_3.4.5/drivers/input/sensor/TP_DRIVER_NOT_USE/dmt10_gsensor/dmt10.h
new file mode 100755
index 00000000..61343657
--- /dev/null
+++ b/ANDROID_3.4.5/drivers/input/sensor/TP_DRIVER_NOT_USE/dmt10_gsensor/dmt10.h
@@ -0,0 +1,187 @@
+/*
+ * @file include/linux/dmt10.h
+ * @brief DMT g-sensor Linux device driver
+ * @author Domintech Technology Co., Ltd (http://www.domintech.com.tw)
+ * @version 1.02
+ * @date 2012/12/10
+ *
+ * @section LICENSE
+ *
+ * Copyright 2012 Domintech Technology Co., Ltd
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * @DMT Package version D10_General_driver v1.4
+ *
+ *
+ */
+#ifndef DMT10_H
+#define DMT10_H
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#define AUTO_CALIBRATION 0
+
+#define DMT_DEBUG_DATA 0
+#define GSE_TAG "[DMT_Gsensor]"
+#if DMT_DEBUG_DATA
+#define GSE_ERR(fmt, args...) printk(KERN_ERR GSE_TAG"%s %d : "fmt, __FUNCTION__, __LINE__, ##args)
+#define GSE_LOG(fmt, args...) printk(KERN_INFO GSE_TAG fmt, ##args)
+#define GSE_FUN(f) printk(KERN_INFO GSE_TAG" %s: %s: %i\n", __FILE__, __func__, __LINE__)
+#define DMT_DATA(dev, ...) dev_dbg((dev), ##__VA_ARGS__)
+#else
+#define GSE_ERR(fmt, args...)
+#define GSE_LOG(fmt, args...)
+#define GSE_FUN(f)
+#define DMT_DATA(dev, format, ...)
+#endif
+
+#define DMT10_I2C_ADDR 0x18
+
+
+#define INPUT_NAME_ACC "g-sensor" /* Input Device Name */
+#define DEVICE_I2C_NAME "g-sensor" /* Device name for DMARD10 misc. device */
+#define REG_ACTR 0x00
+#define REG_WDAL 0x01
+#define REG_TAPNS 0x0f
+#define REG_MISC2 0x1f
+#define REG_AFEM 0x0c
+#define REG_CKSEL 0x0d
+#define REG_INTC 0x0e
+#define REG_STADR 0x12
+#define REG_STAINT 0x1C
+#define REG_PD 0x21
+#define REG_TCGYZ 0x26
+#define REG_X_OUT 0x41
+
+#define MODE_Off 0x00
+#define MODE_ResetAtOff 0x01
+#define MODE_Standby 0x02
+#define MODE_ResetAtStandby 0x03
+#define MODE_Active 0x06
+#define MODE_Trigger 0x0a
+#define MODE_ReadOTP 0x12
+#define MODE_WriteOTP 0x22
+#define MODE_WriteOTPBuf 0x42
+#define MODE_ResetDataPath 0x82
+
+#define VALUE_STADR 0x55
+#define VALUE_STAINT 0xAA
+#define VALUE_AFEM_AFEN_Normal 0x8f// AFEN set 1 , ATM[2:0]=b'000(normal),EN_Z/Y/X/T=1
+#define VALUE_AFEM_Normal 0x0f// AFEN set 0 , ATM[2:0]=b'000(normal),EN_Z/Y/X/T=1
+#define VALUE_INTC 0x00// INTC[6:5]=b'00
+#define VALUE_INTC_Interrupt_En 0x20// INTC[6:5]=b'01 (Data ready interrupt enable, active high at INT0)
+#define VALUE_CKSEL_ODR_0_204 0x04// ODR[3:0]=b'0000 (0.78125Hz), CCK[3:0]=b'0100 (204.8kHZ)
+#define VALUE_CKSEL_ODR_1_204 0x14// ODR[3:0]=b'0001 (1.5625Hz), CCK[3:0]=b'0100 (204.8kHZ)
+#define VALUE_CKSEL_ODR_3_204 0x24// ODR[3:0]=b'0010 (3.125Hz), CCK[3:0]=b'0100 (204.8kHZ)
+#define VALUE_CKSEL_ODR_6_204 0x34// ODR[3:0]=b'0011 (6.25Hz), CCK[3:0]=b'0100 (204.8kHZ)
+#define VALUE_CKSEL_ODR_12_204 0x44// ODR[3:0]=b'0100 (12.5Hz), CCK[3:0]=b'0100 (204.8kHZ)
+#define VALUE_CKSEL_ODR_25_204 0x54// ODR[3:0]=b'0101 (25Hz), CCK[3:0]=b'0100 (204.8kHZ)
+#define VALUE_CKSEL_ODR_50_204 0x64// ODR[3:0]=b'0110 (50Hz), CCK[3:0]=b'0100 (204.8kHZ)
+#define VALUE_CKSEL_ODR_100_204 0x74// ODR[3:0]=b'0111 (100Hz), CCK[3:0]=b'0100 (204.8kHZ)
+
+#define VALUE_TAPNS_NoFilter 0x00 // TAP1/TAP2 NO FILTER
+#define VALUE_TAPNS_Ave_2 0x11 // TAP1/TAP2 Average 2
+#define VALUE_TAPNS_Ave_4 0x22 // TAP1/TAP2 Average 4
+#define VALUE_TAPNS_Ave_8 0x33 // TAP1/TAP2 Average 8
+#define VALUE_TAPNS_Ave_16 0x44 // TAP1/TAP2 Average 16
+#define VALUE_TAPNS_Ave_32 0x55 // TAP1/TAP2 Average 32
+#define VALUE_MISC2_OSCA_EN 0x08
+#define VALUE_PD_RST 0x52
+
+#define CONFIG_GSEN_CALIBRATION_GRAVITY_ON_Z_NEGATIVE 1
+#define CONFIG_GSEN_CALIBRATION_GRAVITY_ON_Z_POSITIVE 2
+#define CONFIG_GSEN_CALIBRATION_GRAVITY_ON_Y_NEGATIVE 3
+#define CONFIG_GSEN_CALIBRATION_GRAVITY_ON_Y_POSITIVE 4
+#define CONFIG_GSEN_CALIBRATION_GRAVITY_ON_X_NEGATIVE 5
+#define CONFIG_GSEN_CALIBRATION_GRAVITY_ON_X_POSITIVE 6
+
+#define AVG_NUM 16
+#define SENSOR_DATA_SIZE 3
+#define DEFAULT_SENSITIVITY 1024
+
+#define IOCTL_MAGIC 0x09
+#define SENSOR_RESET _IO(IOCTL_MAGIC, 0)
+#define SENSOR_CALIBRATION _IOWR(IOCTL_MAGIC, 1, int[SENSOR_DATA_SIZE])
+#define SENSOR_GET_OFFSET _IOR(IOCTL_MAGIC, 2, int[SENSOR_DATA_SIZE])
+#define SENSOR_SET_OFFSET _IOWR(IOCTL_MAGIC, 3, int[SENSOR_DATA_SIZE])
+#define SENSOR_READ_ACCEL_XYZ _IOR(IOCTL_MAGIC, 4, int[SENSOR_DATA_SIZE])
+#define SENSOR_SETYPR _IOW(IOCTL_MAGIC, 5, int[SENSOR_DATA_SIZE])
+#define SENSOR_GET_OPEN_STATUS _IO(IOCTL_MAGIC, 6)
+#define SENSOR_GET_CLOSE_STATUS _IO(IOCTL_MAGIC, 7)
+#define SENSOR_GET_DELAY _IOR(IOCTL_MAGIC, 8, unsigned int*)
+#define SENSOR_MAXNR 8
+
+/* g-senor layout configuration, choose one of the following configuration */
+#define CONFIG_GSEN_LAYOUT_PAT_1 1
+#define CONFIG_GSEN_LAYOUT_PAT_2 0
+#define CONFIG_GSEN_LAYOUT_PAT_3 0
+#define CONFIG_GSEN_LAYOUT_PAT_4 0
+#define CONFIG_GSEN_LAYOUT_PAT_5 0
+#define CONFIG_GSEN_LAYOUT_PAT_6 0
+#define CONFIG_GSEN_LAYOUT_PAT_7 0
+#define CONFIG_GSEN_LAYOUT_PAT_8 0
+
+s16 sensorlayout[3][3] = {
+#if CONFIG_GSEN_LAYOUT_PAT_1
+ { 1, 0, 0}, { 0, 1, 0}, { 0, 0, 1},
+#elif CONFIG_GSEN_LAYOUT_PAT_2
+ { 0, 1, 0}, {-1, 0, 0}, { 0, 0, 1},
+#elif CONFIG_GSEN_LAYOUT_PAT_3
+ {-1, 0, 0}, { 0,-1, 0}, { 0, 0, 1},
+#elif CONFIG_GSEN_LAYOUT_PAT_4
+ { 0,-1, 0}, { 1, 0, 0}, { 0, 0, 1},
+#elif CONFIG_GSEN_LAYOUT_PAT_5
+ {-1, 0, 0}, { 0, 1, 0}, { 0, 0,-1},
+#elif CONFIG_GSEN_LAYOUT_PAT_6
+ { 0,-1, 0}, {-1, 0, 0}, { 0, 0,-1},
+#elif CONFIG_GSEN_LAYOUT_PAT_7
+ { 1, 0, 0}, { 0,-1, 0}, { 0, 0,-1},
+#elif CONFIG_GSEN_LAYOUT_PAT_8
+ { 0, 1, 0}, { 1, 0, 0}, { 0, 0,-1},
+#endif
+};
+
+typedef union {
+ struct {
+ s16 x;
+ s16 y;
+ s16 z;
+ } u;
+ s16 v[SENSOR_DATA_SIZE];
+} raw_data;
+
+struct dmt_data {
+ dev_t devno;
+ struct cdev cdev;
+ struct device *class_dev;
+ struct class *class;
+ struct input_dev *input;
+ struct i2c_client *client;
+ struct delayed_work delaywork;
+ struct work_struct work;
+ struct mutex sensor_mutex;
+ wait_queue_head_t open_wq;
+ atomic_t active;
+ atomic_t delay;
+ atomic_t enable;
+};
+
+#define ACC_DATA_FLAG 0
+#define MAG_DATA_FLAG 1
+#define ORI_DATA_FLAG 2
+#define DMT_NUM_SENSORS 3
+#endif
diff --git a/ANDROID_3.4.5/drivers/input/sensor/TP_DRIVER_NOT_USE/gsensor.c b/ANDROID_3.4.5/drivers/input/sensor/TP_DRIVER_NOT_USE/gsensor.c
new file mode 100755
index 00000000..bd0b16af
--- /dev/null
+++ b/ANDROID_3.4.5/drivers/input/sensor/TP_DRIVER_NOT_USE/gsensor.c
@@ -0,0 +1,180 @@
+/*++
+Copyright (c) 2012 WonderMedia Technologies, Inc. All Rights Reserved.
+This PROPRIETARY SOFTWARE is the property of WonderMedia Technologies, Inc.
+and may contain trade secrets and/or other confidential information of
+WonderMedia Technologies, Inc. This file shall not be disclosed to any
+third party, in whole or in part, without prior written consent of
+WonderMedia.
+
+THIS PROPRIETARY SOFTWARE AND ANY RELATED DOCUMENTATION ARE PROVIDED
+AS IS, WITH ALL FAULTS, AND WITHOUT WARRANTY OF ANY KIND EITHER EXPRESS
+OR IMPLIED, AND WonderMedia TECHNOLOGIES, INC. DISCLAIMS ALL EXPRESS
+OR IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE,
+QUIET ENJOYMENT OR NON-INFRINGEMENT.
+--*/
+
+#include
+#include
+#include
+#include
+#include
+#include "gsensor.h"
+
+#define GSENSOR_I2C_NAME "g-sensor"
+
+#ifdef CONFIG_WMT_SENSOR_DMT08
+#define GSENSOR_I2C_ADDR 0x1c
+#elif defined CONFIG_WMT_SENSOR_KXTI9
+#define GSENSOR_I2C_ADDR 0x0f
+#endif
+
+struct gsensor_data *gs_data;
+
+extern int wmt_getsyspara(char *varname, unsigned char *varval, int *varlen);
+
+struct i2c_board_info gsensor_i2c_board_info = {
+ .type = GSENSOR_I2C_NAME,
+ .flags = 0x00,
+ .platform_data = NULL,
+ .archdata = NULL,
+ .irq = -1,
+};
+
+int gsensor_i2c_register_device (void)
+{
+ struct i2c_board_info *gsensor_i2c_bi;
+ struct i2c_adapter *adapter = NULL;
+ struct i2c_client *client = NULL;
+ gsensor_i2c_bi = &gsensor_i2c_board_info;
+ adapter = i2c_get_adapter(0);/*in bus 0*/
+
+ if (NULL == adapter) {
+ printk("can not get i2c adapter, client address error\n");
+ return -1;
+ }
+ gsensor_i2c_bi->addr = gs_data->i2c_addr;
+ client = i2c_new_device(adapter, gsensor_i2c_bi);
+ if (client == NULL) {
+ printk("allocate i2c client failed\n");
+ return -1;
+ }
+ i2c_put_adapter(adapter);
+ return 0;
+}
+
+/*
+ * Get the configure of sensor from u-boot.
+ * Return: 0--success, other--error.
+ */
+int get_gsensor_conf(struct gsensor_conf *gs_conf)
+{
+ char varbuf[64];
+ int n;
+ int varlen;
+
+ memset(varbuf, 0, sizeof(varbuf));
+ varlen = sizeof(varbuf);
+ if (wmt_getsyspara("wmt.io.gsensor", varbuf, &varlen)) {
+ printk("wmt.io.gsensor not defined!\n");
+ return -1;
+ } else {
+ n = sscanf(varbuf, "%d:%d:%d:%d:%d:%d:%d:%d",
+ &gs_conf->op,
+ &gs_conf->samp,
+ &(gs_conf->xyz_axis[0][0]),
+ &(gs_conf->xyz_axis[0][1]),
+ &(gs_conf->xyz_axis[1][0]),
+ &(gs_conf->xyz_axis[1][1]),
+ &(gs_conf->xyz_axis[2][0]),
+ &(gs_conf->xyz_axis[2][1]));
+ printk(KERN_INFO "wmt.io.gsensor = %d:%d:%d:%d:%d:%d:%d:%d\n",
+ gs_conf->op,
+ gs_conf->samp,
+ gs_conf->xyz_axis[0][0],
+ gs_conf->xyz_axis[0][1],
+ gs_conf->xyz_axis[1][0],
+ gs_conf->xyz_axis[1][1],
+ gs_conf->xyz_axis[2][0],
+ gs_conf->xyz_axis[2][1]);
+ if (n != 8) {
+ printk("wmt.io.gsensor format is incorrect!\n");
+ return -1;
+ }
+
+ if (gs_conf->op <= 0) {
+ printk(KERN_INFO "wmt.io.gsensor is disabled\n");
+ return -1;
+ }
+ }
+ return 0;
+}
+
+static long gsensor_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+ void __user *argp = (void __user *)arg;
+ int flag;
+
+ if (!gs_data)
+ return -1;
+
+ switch (cmd) {
+ case WMT_IOCTL_APP_SET_AFLAG:
+ if (copy_from_user(&flag, argp, sizeof(flag)))
+ return -EFAULT;
+ else {
+ if (flag < 0 || flag > 1)
+ return -EINVAL;
+ gs_data->enable(flag);
+ }
+ break;
+ case WMT_IOCTL_APP_GET_AFLAG:
+ if (copy_to_user(argp, &flag, sizeof(flag)))
+ return -EFAULT;
+ break;
+ case WMT_IOCTL_APP_SET_DELAY:
+ if (copy_from_user(&flag, argp, sizeof(flag)))
+ return -EFAULT;
+ else
+ gs_data->setDelay(flag);
+
+ break;
+ case WMT_IOCTL_APP_GET_DELAY:
+ if (copy_to_user(argp, &flag, sizeof(flag)))
+ return -EFAULT;
+ break;
+ case WMT_IOCTL_APP_GET_LSG:
+ gs_data->getLSG(&flag);
+ if (copy_to_user(argp, &flag, sizeof(flag)))
+ return -EFAULT;
+ break;
+ default:
+ return -ENOTTY;
+ }
+ return 0;
+}
+
+struct file_operations gsensor_fops = {
+ .owner = THIS_MODULE,
+ .unlocked_ioctl = gsensor_ioctl,
+};
+
+struct miscdevice gsensor_device = {
+ .minor = MISC_DYNAMIC_MINOR,
+ .name = "g-sensor",
+ .fops = &gsensor_fops,
+};
+
+int gsensor_register(struct gsensor_data *data)
+{
+ int err=-1;
+
+ gs_data = data;
+ err = misc_register(&gsensor_device);
+ if (err)
+ printk(KERN_ERR "%s: gsensor misc register failed\n", __func__);
+ return err;
+}
+
+EXPORT_SYMBOL_GPL(gsensor_i2c_register_device);
+EXPORT_SYMBOL_GPL(get_gsensor_conf);
+EXPORT_SYMBOL_GPL(gsensor_register);
diff --git a/ANDROID_3.4.5/drivers/input/sensor/TP_DRIVER_NOT_USE/gsensor.h b/ANDROID_3.4.5/drivers/input/sensor/TP_DRIVER_NOT_USE/gsensor.h
new file mode 100755
index 00000000..db644d77
--- /dev/null
+++ b/ANDROID_3.4.5/drivers/input/sensor/TP_DRIVER_NOT_USE/gsensor.h
@@ -0,0 +1,43 @@
+/*++
+Copyright (c) 2012 WonderMedia Technologies, Inc. All Rights Reserved.
+This PROPRIETARY SOFTWARE is the property of WonderMedia Technologies, Inc.
+and may contain trade secrets and/or other confidential information of
+WonderMedia Technologies, Inc. This file shall not be disclosed to any
+third party, in whole or in part, without prior written consent of
+WonderMedia.
+
+THIS PROPRIETARY SOFTWARE AND ANY RELATED DOCUMENTATION ARE PROVIDED
+AS IS, WITH ALL FAULTS, AND WITHOUT WARRANTY OF ANY KIND EITHER EXPRESS
+OR IMPLIED, AND WonderMedia TECHNOLOGIES, INC. DISCLAIMS ALL EXPRESS
+OR IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE,
+QUIET ENJOYMENT OR NON-INFRINGEMENT.
+--*/
+
+#ifndef __GSENSOR_H__
+#define __GSENSOR_H__
+
+#define IOCTL_WMT 0x01
+#define WMT_IOCTL_APP_SET_AFLAG _IOW(IOCTL_WMT, 0x01, int)
+#define WMT_IOCTL_APP_SET_DELAY _IOW(IOCTL_WMT, 0x02, int)
+#define WMT_IOCTL_APP_GET_AFLAG _IOW(IOCTL_WMT, 0x03, int)
+#define WMT_IOCTL_APP_GET_DELAY _IOW(IOCTL_WMT, 0x04, int)
+#define WMT_IOCTL_APP_GET_LSG _IOW(IOCTL_WMT, 0x05, int)
+
+struct gsensor_conf {
+ int op;
+ int samp;
+ int xyz_axis[3][2];
+};
+
+struct gsensor_data {
+ int i2c_addr;
+ int (*enable) (int en);
+ int (*setDelay) (int mdelay);
+ int (*getLSG) (int *lsg);
+};
+
+extern int gsensor_i2c_register_device (void);
+extern int get_gsensor_conf(struct gsensor_conf *gs_conf);
+extern int gsensor_register(struct gsensor_data *gs_data);
+
+#endif
\ No newline at end of file
diff --git a/ANDROID_3.4.5/drivers/input/sensor/TP_DRIVER_NOT_USE/kxti9_gsensor/Makefile b/ANDROID_3.4.5/drivers/input/sensor/TP_DRIVER_NOT_USE/kxti9_gsensor/Makefile
new file mode 100755
index 00000000..3df5b74c
--- /dev/null
+++ b/ANDROID_3.4.5/drivers/input/sensor/TP_DRIVER_NOT_USE/kxti9_gsensor/Makefile
@@ -0,0 +1,6 @@
+#
+# Makefile for the KXTI9 Sensor driver
+#
+
+sensor_kxti9-objs := kxti9.o
+obj-$(CONFIG_WMT_SENSOR_KXTI9) += sensor_kxti9.o
diff --git a/ANDROID_3.4.5/drivers/input/sensor/TP_DRIVER_NOT_USE/kxti9_gsensor/kxti9.c b/ANDROID_3.4.5/drivers/input/sensor/TP_DRIVER_NOT_USE/kxti9_gsensor/kxti9.c
new file mode 100755
index 00000000..c385842e
--- /dev/null
+++ b/ANDROID_3.4.5/drivers/input/sensor/TP_DRIVER_NOT_USE/kxti9_gsensor/kxti9.c
@@ -0,0 +1,1134 @@
+/*
+ * Copyright (C) 2009 Kionix, Inc.
+ * Written by Chris Hudson
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ * 02111-1307, USA
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#ifdef KXTI9_INT_MODE
+#include
+#include
+#include
+#endif
+#include
+#include
+#include
+#include "kxti9.h"
+#include "../gsensor.h"
+
+#define NAME "g-sensor"
+#define G_MAX 2048 //8000
+/* OUTPUT REGISTERS */
+#define XOUT_L 0x06
+#define INT_SRC_REG1 0x15
+#define INT_STATUS_REG 0x16
+#define TILT_POS_CUR 0x10
+#define INT_REL 0x1A
+#define WHO_AM_I 0x0F
+/* CONTROL REGISTERS */
+#define DATA_CTRL 0x21
+#define CTRL_REG1 0x1B
+#define INT_CTRL1 0x1E
+#define CTRL_REG3 0x1D
+#define TILT_TIMER 0x28
+#define WUF_TIMER 0x29
+#define WUF_THRESH 0x5A
+#define TDT_TIMER 0x2B
+/* CONTROL REGISTER 1 BITS */
+#define PC1_OFF 0x00
+#define PC1_ON 0x80
+/* INTERRUPT SOURCE 2 BITS */
+#define TPS 0x01
+#define TDTS0 0x04
+#define TDTS1 0x08
+/* INPUT_ABS CONSTANTS */
+#define FUZZ 0 //32
+#define FLAT 0 //32
+/* RESUME STATE INDICES */
+#define RES_DATA_CTRL 0
+#define RES_CTRL_REG1 1
+#define RES_INT_CTRL1 2
+#define RES_TILT_TIMER 3
+#define RES_CTRL_REG3 4
+#define RES_WUF_TIMER 5
+#define RES_WUF_THRESH 6
+#define RES_TDT_TIMER 7
+#define RES_TDT_H_THRESH 8
+#define RES_TDT_L_THRESH 9
+#define RES_TAP_TIMER 10
+#define RES_TOTAL_TIMER 11
+#define RES_LAT_TIMER 12
+#define RES_WIN_TIMER 13
+#define RESUME_ENTRIES 14
+
+static struct gsensor_conf gs_conf;
+static struct kxti9_data *gs_ti9;
+
+extern int gsensor_i2c_register_device (void);
+
+struct kxti9_platform_data kxti9_pdata = {
+ .min_interval = 1,
+ .poll_interval = 200,//1000,
+
+ .g_range = KXTI9_G_2G,
+ .shift_adj = SHIFT_ADJ_2G,
+
+ .axis_map_x = 0,
+ .axis_map_y = 1,
+ .axis_map_z = 2,
+
+ .negate_x = 0,
+ .negate_y = 0,
+ .negate_z = 0,
+
+ .data_odr_init = ODR12_5F,
+#ifdef KXTI9_INT_MODE
+ .ctrl_reg1_init = KXTI9_G_8G | RES_12BIT | TDTE | WUFE | TPE,
+ .int_ctrl_init = KXTI9_IEN | KXTI9_IEA | KXTI9_IEL,
+#else
+ .ctrl_reg1_init = KXTI9_G_2G | RES_12BIT,
+ .int_ctrl_init = 0,
+#endif
+ .tilt_timer_init = 0x03,
+ .engine_odr_init = OTP12_5 | OWUF50 | OTDT400,
+ .wuf_timer_init = 0x16,
+ .wuf_thresh_init = 0x28,
+ .tdt_timer_init = 0x78,
+ .tdt_h_thresh_init = 0xFF,
+ .tdt_l_thresh_init = 0x14,
+ .tdt_tap_timer_init = 0x53,
+ .tdt_total_timer_init = 0x24,
+ .tdt_latency_timer_init = 0x10,
+ .tdt_window_timer_init = 0xA0,
+};
+
+/*
+ * The following table lists the maximum appropriate poll interval for each
+ * available output data rate.
+ */
+struct {
+ unsigned int cutoff;
+ u8 mask;
+} kxti9_odr_table[] = {
+ {
+ 3, ODR800F}, {
+ 5, ODR400F}, {
+ 10, ODR200F}, {
+ 20, ODR100F}, {
+ 40, ODR50F}, {
+ 80, ODR25F}, {
+ 0, ODR12_5F},
+};
+
+struct kxti9_data {
+ struct i2c_client *client;
+ struct kxti9_platform_data *pdata;
+ struct mutex lock;
+ struct delayed_work input_work;
+ struct input_dev *input_dev;
+#ifdef KXTI9_INT_MODE
+ struct work_struct irq_work;
+#endif
+
+ int hw_initialized;
+ atomic_t enabled;
+ u8 resume[RESUME_ENTRIES];
+ int res_interval;
+#ifdef KXTI9_INT_MODE
+ int irq;
+#endif
+};
+
+static int kxti9_i2c_read(struct kxti9_data *ti9, u8 addr, u8 *data, int len)
+{
+ int err;
+
+ struct i2c_msg msgs[] = {
+ {
+ .addr = ti9->client->addr,
+ .flags = ti9->client->flags & I2C_M_TEN,
+ .len = 1,
+ .buf = &addr,
+ },
+ {
+ .addr = ti9->client->addr,
+ .flags = (ti9->client->flags & I2C_M_TEN) | I2C_M_RD,
+ .len = len,
+ .buf = data,
+ },
+ };
+ err = i2c_transfer(ti9->client->adapter, msgs, 2);
+
+ if (err != 2)
+ dev_err(&ti9->client->dev, "read transfer error\n");
+ else
+ err = 0;
+
+ return err;
+}
+
+static int kxti9_i2c_write(struct kxti9_data *ti9, u8 addr, u8 *data, int len)
+{
+ int err;
+ int i;
+ u8 buf[len + 1];
+
+ struct i2c_msg msgs[] = {
+ {
+ .addr = ti9->client->addr,
+ .flags = ti9->client->flags & I2C_M_TEN,
+ .len = len + 1,
+ .buf = buf,
+ },
+ };
+
+ buf[0] = addr;
+ for (i = 0; i < len; i++) {
+ buf[i + 1] = data[i];
+ }
+
+ err = i2c_transfer(ti9->client->adapter, msgs, 1);
+
+ if (err != 1)
+ dev_err(&ti9->client->dev, "write transfer error\n");
+ else
+ err = 0;
+
+ return err;
+}
+
+static int kxti9_verify(struct kxti9_data *ti9)
+{
+ int err;
+ u8 buf;
+
+ err = kxti9_i2c_read(ti9, WHO_AM_I, &buf, 1);
+ /*** DEBUG OUTPUT - REMOVE ***/
+ dev_info(&ti9->client->dev, "WHO_AM_I = 0x%02x\n", buf);
+ /*** DEBUG OUTPUT - REMOVE ***/
+ if (err < 0)
+ dev_err(&ti9->client->dev, "read err int source\n");
+ if (buf != 0x04 && buf != 0x08) // jakie add 0x8 for kxtj9
+ err = -1;
+ return err;
+}
+
+int kxti9_update_g_range(struct kxti9_data *ti9, u8 new_g_range)
+{
+ int err;
+ u8 shift;
+ u8 buf;
+
+ switch (new_g_range) {
+ case KXTI9_G_2G:
+ shift = SHIFT_ADJ_2G;
+ break;
+ case KXTI9_G_4G:
+ shift = SHIFT_ADJ_4G;
+ break;
+ case KXTI9_G_8G:
+ shift = SHIFT_ADJ_8G;
+ break;
+ default:
+ dev_err(&ti9->client->dev, "invalid g range request\n");
+ return -EINVAL;
+ }
+ if (shift != ti9->pdata->shift_adj) {
+ if (ti9->pdata->shift_adj > shift)
+ ti9->resume[RES_WUF_THRESH] >>=
+ (ti9->pdata->shift_adj - shift);
+ if (ti9->pdata->shift_adj < shift)
+ ti9->resume[RES_WUF_THRESH] <<=
+ (shift - ti9->pdata->shift_adj);
+
+ if (atomic_read(&ti9->enabled)) {
+ buf = PC1_OFF;
+ err = kxti9_i2c_write(ti9, CTRL_REG1, &buf, 1);
+ if (err < 0)
+ return err;
+ buf = ti9->resume[RES_WUF_THRESH];
+ err = kxti9_i2c_write(ti9, WUF_THRESH, &buf, 1);
+ if (err < 0)
+ return err;
+ buf = (ti9->resume[RES_CTRL_REG1] & 0xE7) | new_g_range;
+ err = kxti9_i2c_write(ti9, CTRL_REG1, &buf, 1);
+ if (err < 0)
+ return err;
+ ti9->resume[RES_CTRL_REG1] = buf;
+ ti9->pdata->shift_adj = shift;
+ }
+ }
+ return 0;
+}
+
+int kxti9_update_odr(struct kxti9_data *ti9, int poll_interval)
+{
+ int err = -1;
+ int i;
+ u8 config;
+
+ /* Convert the poll interval into an output data rate configuration
+ * that is as low as possible. The ordering of these checks must be
+ * maintained due to the cascading cut off values - poll intervals are
+ * checked from shortest to longest. At each check, if the next slower
+ * ODR cannot support the current poll interval, we stop searching */
+ for (i = 0; i < ARRAY_SIZE(kxti9_odr_table); i++) {
+ config = kxti9_odr_table[i].mask;
+ if (poll_interval < kxti9_odr_table[i].cutoff)
+ break;
+ }
+
+ if (atomic_read(&ti9->enabled)) {
+ err = kxti9_i2c_write(ti9, DATA_CTRL, &config, 1);
+ if (err < 0)
+ return err;
+ /*
+ * Latch on input_dev - indicates that kxti9_input_init passed
+ * and this workqueue is available
+ */
+ if (ti9->input_dev) {
+ cancel_delayed_work_sync(&ti9->input_work);
+ schedule_delayed_work(&ti9->input_work,
+ msecs_to_jiffies(poll_interval));
+ }
+ }
+ ti9->resume[RES_DATA_CTRL] = config;
+
+ return 0;
+}
+
+static int kxti9_hw_init(struct kxti9_data *ti9)
+{
+ int err = -1;
+ u8 buf[7];
+
+ buf[0] = PC1_OFF;
+ err = kxti9_i2c_write(ti9, CTRL_REG1, buf, 1);
+ if (err < 0)
+ return err;
+ err = kxti9_i2c_write(ti9, DATA_CTRL, &ti9->resume[RES_DATA_CTRL], 1);
+ if (err < 0)
+ return err;
+ err = kxti9_i2c_write(ti9, CTRL_REG3, &ti9->resume[RES_CTRL_REG3], 1);
+ if (err < 0)
+ return err;
+ err = kxti9_i2c_write(ti9, TILT_TIMER, &ti9->resume[RES_TILT_TIMER], 1);
+ if (err < 0)
+ return err;
+ err = kxti9_i2c_write(ti9, WUF_TIMER, &ti9->resume[RES_WUF_TIMER], 1);
+ if (err < 0)
+ return err;
+ err = kxti9_i2c_write(ti9, WUF_THRESH, &ti9->resume[RES_WUF_THRESH], 1);
+ if (err < 0)
+ return err;
+ buf[0] = ti9->resume[RES_TDT_TIMER];
+ buf[1] = ti9->resume[RES_TDT_H_THRESH];
+ buf[2] = ti9->resume[RES_TDT_L_THRESH];
+ buf[3] = ti9->resume[RES_TAP_TIMER];
+ buf[4] = ti9->resume[RES_TOTAL_TIMER];
+ buf[5] = ti9->resume[RES_LAT_TIMER];
+ buf[6] = ti9->resume[RES_WIN_TIMER];
+ err = kxti9_i2c_write(ti9, TDT_TIMER, buf, 7);
+ if (err < 0)
+ return err;
+ err = kxti9_i2c_write(ti9, INT_CTRL1, &ti9->resume[RES_INT_CTRL1], 1);
+ if (err < 0)
+ return err;
+ buf[0] = (ti9->resume[RES_CTRL_REG1] | PC1_ON);
+ err = kxti9_i2c_write(ti9, CTRL_REG1, buf, 1);
+ if (err < 0)
+ return err;
+ ti9->resume[RES_CTRL_REG1] = buf[0];
+ ti9->hw_initialized = 1;
+
+ return 0;
+}
+
+static void kxti9_device_power_off(struct kxti9_data *ti9)
+{
+ int err;
+ u8 buf = PC1_OFF;
+
+ err = kxti9_i2c_write(ti9, CTRL_REG1, &buf, 1);
+ if (err < 0)
+ dev_err(&ti9->client->dev, "soft power off failed\n");
+#ifdef KXTI9_INT_MODE
+ disable_irq(ti9->irq);
+#endif
+ if (ti9->pdata->power_off)
+ ti9->pdata->power_off();
+ ti9->hw_initialized = 0;
+}
+
+static int kxti9_device_power_on(struct kxti9_data *ti9)
+{
+ int err;
+
+ if (ti9->pdata->power_on) {
+ err = ti9->pdata->power_on();
+ if (err < 0)
+ return err;
+ }
+#ifdef KXTI9_INT_MODE
+ enable_irq(ti9->irq);
+#endif
+ if (!ti9->hw_initialized) {
+ msleep(100);
+ err = kxti9_hw_init(ti9);
+ if (err < 0) {
+ kxti9_device_power_off(ti9);
+ return err;
+ }
+ }
+
+ return 0;
+}
+
+#ifdef KXTI9_INT_MODE
+static irqreturn_t kxti9_isr(int irq, void *dev)
+{
+ struct kxti9_data *ti9 = dev;
+
+ disable_irq_nosync(irq);
+ schedule_work(&ti9->irq_work);
+
+ return IRQ_HANDLED;
+}
+#endif
+
+static u8 kxti9_resolve_dir(struct kxti9_data *ti9, u8 dir)
+{
+ switch (dir) {
+ case 0x20: /* -X */
+ if (ti9->pdata->negate_x)
+ dir = 0x10;
+ if (ti9->pdata->axis_map_y == 0)
+ dir >>= 2;
+ if (ti9->pdata->axis_map_z == 0)
+ dir >>= 4;
+ break;
+ case 0x10: /* +X */
+ if (ti9->pdata->negate_x)
+ dir = 0x20;
+ if (ti9->pdata->axis_map_y == 0)
+ dir >>= 2;
+ if (ti9->pdata->axis_map_z == 0)
+ dir >>= 4;
+ break;
+ case 0x08: /* -Y */
+ if (ti9->pdata->negate_y)
+ dir = 0x04;
+ if (ti9->pdata->axis_map_x == 1)
+ dir <<= 2;
+ if (ti9->pdata->axis_map_z == 1)
+ dir >>= 2;
+ break;
+ case 0x04: /* +Y */
+ if (ti9->pdata->negate_y)
+ dir = 0x08;
+ if (ti9->pdata->axis_map_x == 1)
+ dir <<= 2;
+ if (ti9->pdata->axis_map_z == 1)
+ dir >>= 2;
+ break;
+ case 0x02: /* -Z */
+ if (ti9->pdata->negate_z)
+ dir = 0x01;
+ if (ti9->pdata->axis_map_x == 2)
+ dir <<= 4;
+ if (ti9->pdata->axis_map_y == 2)
+ dir <<= 2;
+ break;
+ case 0x01: /* +Z */
+ if (ti9->pdata->negate_z)
+ dir = 0x02;
+ if (ti9->pdata->axis_map_x == 2)
+ dir <<= 4;
+ if (ti9->pdata->axis_map_y == 2)
+ dir <<= 2;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return dir;
+}
+
+static int kxti9_get_acceleration_data(struct kxti9_data *ti9, int *xyz)
+{
+ int err;
+ /* Data bytes from hardware xL, xH, yL, yH, zL, zH */
+ u8 acc_data[6];
+ /* x,y,z hardware values */
+ int hw_d[3];
+
+ err = kxti9_i2c_read(ti9, XOUT_L, acc_data, 6);
+ if (err < 0)
+ return err;
+
+ hw_d[0] = (int) (((acc_data[1]) << 8) | acc_data[0]);
+ hw_d[1] = (int) (((acc_data[3]) << 8) | acc_data[2]);
+ hw_d[2] = (int) (((acc_data[5]) << 8) | acc_data[4]);
+
+ hw_d[0] = (hw_d[0] & 0x8000) ? ((hw_d[0] | 0xFFFF0000) + 1) : (hw_d[0]);
+ hw_d[1] = (hw_d[1] & 0x8000) ? ((hw_d[1] | 0xFFFF0000) + 1) : (hw_d[1]);
+ hw_d[2] = (hw_d[2] & 0x8000) ? ((hw_d[2] | 0xFFFF0000) + 1) : (hw_d[2]);
+
+ hw_d[0] >>= 4;
+ hw_d[1] >>= 4;
+ hw_d[2] >>= 4;
+
+ xyz[0] = ((ti9->pdata->negate_x) ? (-hw_d[ti9->pdata->axis_map_x])
+ : (hw_d[ti9->pdata->axis_map_x]));
+ xyz[1] = ((ti9->pdata->negate_y) ? (-hw_d[ti9->pdata->axis_map_y])
+ : (hw_d[ti9->pdata->axis_map_y]));
+ xyz[2] = ((ti9->pdata->negate_z) ? (-hw_d[ti9->pdata->axis_map_z])
+ : (hw_d[ti9->pdata->axis_map_z]));
+
+ /*** DEBUG OUTPUT - REMOVE ***/
+ //dev_info(&ti9->client->dev, "x:%d y:%d z:%d\n", xyz[0], xyz[1], xyz[2]);
+ /*** DEBUG OUTPUT - REMOVE ***/
+
+ return err;
+}
+
+static void kxti9_report_values(struct kxti9_data *ti9, int *xyz)
+{
+ input_report_abs(ti9->input_dev, ABS_X, xyz[gs_conf.xyz_axis[ABS_X][0]]*gs_conf.xyz_axis[ABS_X][1]);
+ input_report_abs(ti9->input_dev, ABS_Y, xyz[gs_conf.xyz_axis[ABS_Y][0]]*gs_conf.xyz_axis[ABS_Y][1]);
+ input_report_abs(ti9->input_dev, ABS_Z, xyz[gs_conf.xyz_axis[ABS_Z][0]]*gs_conf.xyz_axis[ABS_Z][1]);
+ input_sync(ti9->input_dev);
+}
+
+#ifdef KXTI9_INT_MODE
+static void kxti9_irq_work_func(struct work_struct *work)
+{
+/*
+ * int_status output:
+ * [INT_SRC_REG2][INT_SRC_REG1][TILT_POS_PRE][TILT_POS_CUR]
+ * INT_SRC_REG1, TILT_POS_PRE, and TILT_POS_CUR directions are translated
+ * based on platform data variables.
+ */
+
+ int err;
+ int int_status = 0;
+ u8 status;
+ u8 buf[2];
+
+ struct kxti9_data *ti9
+ = container_of(work, struct kxti9_data, irq_work);
+
+ err = kxti9_i2c_read(ti9, INT_STATUS_REG, &status, 1);
+ if (err < 0)
+ dev_err(&ti9->client->dev, "read err int source\n");
+ int_status = status << 24;
+ if ((status & TPS) > 0) {
+ err = kxti9_i2c_read(ti9, TILT_POS_CUR, buf, 2);
+ if (err < 0)
+ dev_err(&ti9->client->dev, "read err tilt dir\n");
+ int_status |= kxti9_resolve_dir(ti9, buf[0]);
+ int_status |= kxti9_resolve_dir(ti9, buf[1]) << 8;
+ /*** DEBUG OUTPUT - REMOVE ***/
+ dev_info(&ti9->client->dev, "IRQ TILT [%x]\n",
+ kxti9_resolve_dir(ti9, buf[0]));
+ /*** DEBUG OUTPUT - REMOVE ***/
+ }
+ if (((status & TDTS0) | (status & TDTS1)) > 0) {
+ err = kxti9_i2c_read(ti9, INT_SRC_REG1, buf, 1);
+ if (err < 0)
+ dev_err(&ti9->client->dev, "read err tap dir\n");
+ int_status |= (kxti9_resolve_dir(ti9, buf[0])) << 16;
+ /*** DEBUG OUTPUT - REMOVE ***/
+ dev_info(&ti9->client->dev, "IRQ TAP%d [%x]\n",
+ ((status & TDTS1) ? (2) : (1)), kxti9_resolve_dir(ti9, buf[0]));
+ /*** DEBUG OUTPUT - REMOVE ***/
+ }
+ /*** DEBUG OUTPUT - REMOVE ***/
+ if ((status & 0x02) > 0) {
+ if (((status & TDTS0) | (status & TDTS1)) > 0)
+ dev_info(&ti9->client->dev, "IRQ WUF + TAP\n");
+ else
+ dev_info(&ti9->client->dev, "IRQ WUF\n");
+ }
+ /*** DEBUG OUTPUT - REMOVE ***/
+ if (int_status & 0x2FFF) {
+ input_report_abs(ti9->input_dev, ABS_MISC, int_status);
+ input_sync(ti9->input_dev);
+ }
+ err = kxti9_i2c_read(ti9, INT_REL, buf, 1);
+ if (err < 0)
+ dev_err(&ti9->client->dev,
+ "error clearing interrupt status: %d\n", err);
+
+ enable_irq(ti9->irq);
+}
+#endif
+
+static int kxti9_enable(struct kxti9_data *ti9)
+{
+ int err;
+ int int_status = 0;
+ u8 buf;
+
+ if (!atomic_cmpxchg(&ti9->enabled, 0, 1)) {
+ err = kxti9_device_power_on(ti9);
+ err = kxti9_i2c_read(ti9, INT_REL, &buf, 1);
+ if (err < 0) {
+ dev_err(&ti9->client->dev,
+ "error clearing interrupt: %d\n", err);
+ atomic_set(&ti9->enabled, 0);
+ return err;
+ }
+ if ((ti9->resume[RES_CTRL_REG1] & TPE) > 0) {
+ err = kxti9_i2c_read(ti9, TILT_POS_CUR, &buf, 1);
+ if (err < 0) {
+ dev_err(&ti9->client->dev,
+ "read err current tilt\n");
+ int_status |= kxti9_resolve_dir(ti9, buf);
+ input_report_abs(ti9->input_dev, ABS_MISC, int_status);
+ input_sync(ti9->input_dev);
+ }
+ }
+ schedule_delayed_work(&ti9->input_work,
+ msecs_to_jiffies(ti9->res_interval));
+ }
+
+ return 0;
+}
+
+static int kxti9_disable(struct kxti9_data *ti9)
+{
+ if (atomic_cmpxchg(&ti9->enabled, 1, 0)) {
+ cancel_delayed_work_sync(&ti9->input_work);
+ kxti9_device_power_off(ti9);
+ }
+
+ return 0;
+}
+
+static void kxti9_input_work_func(struct work_struct *work)
+{
+ struct kxti9_data *ti9 = container_of((struct delayed_work *)work,
+ struct kxti9_data, input_work);
+ int xyz[3] = { 0 };
+
+ mutex_lock(&ti9->lock);
+
+ if (kxti9_get_acceleration_data(ti9, xyz) == 0)
+ kxti9_report_values(ti9, xyz);
+
+ schedule_delayed_work(&ti9->input_work,
+ msecs_to_jiffies(ti9->res_interval));
+
+ mutex_unlock(&ti9->lock);
+}
+
+int kxti9_input_open(struct input_dev *input)
+{
+ struct kxti9_data *ti9 = input_get_drvdata(input);
+
+ return kxti9_enable(ti9);
+}
+
+void kxti9_input_close(struct input_dev *dev)
+{
+ struct kxti9_data *ti9 = input_get_drvdata(dev);
+
+ kxti9_disable(ti9);
+}
+
+static int kxti9_input_init(struct kxti9_data *ti9)
+{
+ int err;
+
+ INIT_DELAYED_WORK(&ti9->input_work, kxti9_input_work_func);
+ ti9->input_dev = input_allocate_device();
+ if (!ti9->input_dev) {
+ err = -ENOMEM;
+ dev_err(&ti9->client->dev, "input device allocate failed\n");
+ goto err0;
+ }
+ //ti9->input_dev->open = kxti9_input_open;
+ //ti9->input_dev->close = kxti9_input_close;
+
+ input_set_drvdata(ti9->input_dev, ti9);
+
+ set_bit(EV_ABS, ti9->input_dev->evbit);
+ set_bit(ABS_MISC, ti9->input_dev->absbit);
+
+ input_set_abs_params(ti9->input_dev, ABS_X, -G_MAX, G_MAX, FUZZ, FLAT);
+ input_set_abs_params(ti9->input_dev, ABS_Y, -G_MAX, G_MAX, FUZZ, FLAT);
+ input_set_abs_params(ti9->input_dev, ABS_Z, -G_MAX, G_MAX, FUZZ, FLAT);
+
+ ti9->input_dev->name = "g-sensor";
+
+ err = input_register_device(ti9->input_dev);
+ if (err) {
+ dev_err(&ti9->client->dev,
+ "unable to register input polled device %s: %d\n",
+ ti9->input_dev->name, err);
+ goto err1;
+ }
+
+ return 0;
+err1:
+ input_free_device(ti9->input_dev);
+err0:
+ return err;
+}
+
+static void kxti9_input_cleanup(struct kxti9_data *ti9)
+{
+ input_unregister_device(ti9->input_dev);
+}
+
+/* sysfs */
+static ssize_t kxti9_delay_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct kxti9_data *ti9 = i2c_get_clientdata(client);
+ return sprintf(buf, "%d\n", ti9->res_interval);
+}
+
+static ssize_t kxti9_delay_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct kxti9_data *ti9 = i2c_get_clientdata(client);
+ int val = simple_strtoul(buf, NULL, 10);
+
+ ti9->res_interval = max(val, ti9->pdata->min_interval);
+ kxti9_update_odr(ti9, ti9->res_interval);
+
+ return count;
+}
+
+static ssize_t kxti9_enable_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct kxti9_data *ti9 = i2c_get_clientdata(client);
+ return sprintf(buf, "%d\n", atomic_read(&ti9->enabled));
+}
+
+static ssize_t kxti9_enable_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct kxti9_data *ti9 = i2c_get_clientdata(client);
+ int val = simple_strtoul(buf, NULL, 10);
+ if (val)
+ kxti9_enable(ti9);
+ else
+ kxti9_disable(ti9);
+ return count;
+}
+
+static ssize_t kxti9_tilt_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct kxti9_data *ti9 = i2c_get_clientdata(client);
+ u8 tilt;
+
+ if (ti9->resume[RES_CTRL_REG1] & TPE) {
+ kxti9_i2c_read(ti9, TILT_POS_CUR, &tilt, 1);
+ return sprintf(buf, "%d\n", kxti9_resolve_dir(ti9, tilt));
+ } else {
+ return sprintf(buf, "%d\n", 0);
+ }
+}
+
+static ssize_t kxti9_tilt_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct kxti9_data *ti9 = i2c_get_clientdata(client);
+ int val = simple_strtoul(buf, NULL, 10);
+ if (val)
+ ti9->resume[RES_CTRL_REG1] |= TPE;
+ else
+ ti9->resume[RES_CTRL_REG1] &= (~TPE);
+ kxti9_i2c_write(ti9, CTRL_REG1, &ti9->resume[RES_CTRL_REG1], 1);
+ return count;
+}
+
+static ssize_t kxti9_wake_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct kxti9_data *ti9 = i2c_get_clientdata(client);
+ u8 val = ti9->resume[RES_CTRL_REG1] & WUFE;
+ if (val)
+ return sprintf(buf, "%d\n", 1);
+ else
+ return sprintf(buf, "%d\n", 0);
+}
+
+static ssize_t kxti9_wake_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct kxti9_data *ti9 = i2c_get_clientdata(client);
+ int val = simple_strtoul(buf, NULL, 10);
+ if (val)
+ ti9->resume[RES_CTRL_REG1] |= WUFE;
+ else
+ ti9->resume[RES_CTRL_REG1] &= (~WUFE);
+ kxti9_i2c_write(ti9, CTRL_REG1, &ti9->resume[RES_CTRL_REG1], 1);
+ return count;
+}
+
+static ssize_t kxti9_tap_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct kxti9_data *ti9 = i2c_get_clientdata(client);
+ u8 val = ti9->resume[RES_CTRL_REG1] & TDTE;
+ if (val)
+ return sprintf(buf, "%d\n", 1);
+ else
+ return sprintf(buf, "%d\n", 0);
+}
+
+static ssize_t kxti9_tap_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct kxti9_data *ti9 = i2c_get_clientdata(client);
+ int val = simple_strtoul(buf, NULL, 10);
+ if (val)
+ ti9->resume[RES_CTRL_REG1] |= TDTE;
+ else
+ ti9->resume[RES_CTRL_REG1] &= (~TDTE);
+ kxti9_i2c_write(ti9, CTRL_REG1, &ti9->resume[RES_CTRL_REG1], 1);
+ return count;
+}
+
+static ssize_t kxti9_selftest_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct i2c_client *client = to_i2c_client(dev);
+ struct kxti9_data *ti9 = i2c_get_clientdata(client);
+ int val = simple_strtoul(buf, NULL, 10);
+ u8 ctrl = 0x00;
+ if (val)
+ ctrl = 0xCA;
+ kxti9_i2c_write(ti9, 0x3A, &ctrl, 1);
+ return count;
+}
+
+static DEVICE_ATTR(delay, S_IRUGO|S_IWUSR, kxti9_delay_show, kxti9_delay_store);
+static DEVICE_ATTR(enable, S_IRUGO|S_IWUSR, kxti9_enable_show,
+ kxti9_enable_store);
+static DEVICE_ATTR(tilt, S_IRUGO|S_IWUSR, kxti9_tilt_show, kxti9_tilt_store);
+static DEVICE_ATTR(wake, S_IRUGO|S_IWUSR, kxti9_wake_show, kxti9_wake_store);
+static DEVICE_ATTR(tap, S_IRUGO|S_IWUSR, kxti9_tap_show, kxti9_tap_store);
+static DEVICE_ATTR(selftest, S_IWUSR, NULL, kxti9_selftest_store);
+
+static struct attribute *kxti9_attributes[] = {
+ &dev_attr_delay.attr,
+ &dev_attr_enable.attr,
+ &dev_attr_tilt.attr,
+ &dev_attr_wake.attr,
+ &dev_attr_tap.attr,
+ &dev_attr_selftest.attr,
+ NULL
+};
+
+static struct attribute_group kxti9_attribute_group = {
+ .attrs = kxti9_attributes
+};
+/* /sysfs */
+static int __devinit kxti9_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ int err = -1;
+ struct kxti9_data *ti9 = kzalloc(sizeof(*ti9), GFP_KERNEL);
+ gs_ti9 = ti9;
+ if (ti9 == NULL) {
+ dev_err(&client->dev,
+ "failed to allocate memory for module data\n");
+ err = -ENOMEM;
+ goto err0;
+ }
+ /*
+ if (client->dev.platform_data == NULL) {
+ dev_err(&client->dev, "platform data is NULL; exiting\n");
+ err = -ENODEV;
+ goto err0;
+ }
+ */
+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
+ dev_err(&client->dev, "client not i2c capable\n");
+ err = -ENODEV;
+ goto err0;
+ }
+ mutex_init(&ti9->lock);
+ mutex_lock(&ti9->lock);
+ ti9->client = client;
+ i2c_set_clientdata(client, ti9);
+
+#ifdef KXTI9_INT_MODE
+ INIT_WORK(&ti9->irq_work, kxti9_irq_work_func);
+#endif
+ ti9->pdata = kmalloc(sizeof(*ti9->pdata), GFP_KERNEL);
+ if (ti9->pdata == NULL)
+ goto err1;
+
+ err = sysfs_create_group(&client->dev.kobj, &kxti9_attribute_group);
+ if (err)
+ goto err1;
+
+ //memcpy(ti9->pdata, client->dev.platform_data, sizeof(*ti9->pdata));
+ memcpy(ti9->pdata, &kxti9_pdata, sizeof(*ti9->pdata));
+
+ if (ti9->pdata->init) {
+ err = ti9->pdata->init();
+ if (err < 0)
+ goto err2;
+ }
+
+#ifdef KXTI9_INT_MODE
+ ti9->irq = gpio_to_irq(ti9->pdata->gpio);
+#endif
+
+ memset(ti9->resume, 0, ARRAY_SIZE(ti9->resume));
+ ti9->resume[RES_DATA_CTRL] = ti9->pdata->data_odr_init;
+ ti9->resume[RES_CTRL_REG1] = ti9->pdata->ctrl_reg1_init;
+ ti9->resume[RES_INT_CTRL1] = ti9->pdata->int_ctrl_init;
+ ti9->resume[RES_TILT_TIMER] = ti9->pdata->tilt_timer_init;
+ ti9->resume[RES_CTRL_REG3] = ti9->pdata->engine_odr_init;
+ ti9->resume[RES_WUF_TIMER] = ti9->pdata->wuf_timer_init;
+ ti9->resume[RES_WUF_THRESH] = ti9->pdata->wuf_thresh_init;
+ ti9->resume[RES_TDT_TIMER] = ti9->pdata->tdt_timer_init;
+ ti9->resume[RES_TDT_H_THRESH] = ti9->pdata->tdt_h_thresh_init;
+ ti9->resume[RES_TDT_L_THRESH] = ti9->pdata->tdt_l_thresh_init;
+ ti9->resume[RES_TAP_TIMER] = ti9->pdata->tdt_tap_timer_init;
+ ti9->resume[RES_TOTAL_TIMER] = ti9->pdata->tdt_total_timer_init;
+ ti9->resume[RES_LAT_TIMER] = ti9->pdata->tdt_latency_timer_init;
+ ti9->resume[RES_WIN_TIMER] = ti9->pdata->tdt_window_timer_init;
+ ti9->res_interval = ti9->pdata->poll_interval;
+
+ err = kxti9_device_power_on(ti9);
+ if (err < 0)
+ goto err3;
+ atomic_set(&ti9->enabled, 1);
+
+ err = kxti9_verify(ti9);
+ if (err < 0) {
+ dev_err(&client->dev, "unresolved i2c client\n");
+ goto err4;
+ }
+
+ err = kxti9_update_g_range(ti9, ti9->pdata->g_range);
+ if (err < 0)
+ goto err4;
+
+ err = kxti9_update_odr(ti9, ti9->res_interval);
+ if (err < 0)
+ goto err4;
+
+ err = kxti9_input_init(ti9);
+ if (err < 0)
+ goto err4;
+
+ kxti9_device_power_off(ti9);
+ atomic_set(&ti9->enabled, 0);
+
+#ifdef KXTI9_INT_MODE
+ err = request_irq(ti9->irq, kxti9_isr,
+ IRQF_TRIGGER_RISING | IRQF_DISABLED, "kxti9-irq", ti9);
+ if (err < 0) {
+ pr_err("%s: request irq failed: %d\n", __func__, err);
+ goto err5;
+ }
+ disable_irq_nosync(ti9->irq);
+#endif
+
+ mutex_unlock(&ti9->lock);
+
+ return 0;
+
+#ifdef KXTI9_INT_MODE
+err5:
+#endif
+ kxti9_input_cleanup(ti9);
+err4:
+ kxti9_device_power_off(ti9);
+err3:
+ if (ti9->pdata->exit)
+ ti9->pdata->exit();
+err2:
+ kfree(ti9->pdata);
+ sysfs_remove_group(&client->dev.kobj, &kxti9_attribute_group);
+err1:
+ mutex_unlock(&ti9->lock);
+ kfree(ti9);
+err0:
+ return err;
+}
+
+static int __devexit kxti9_remove(struct i2c_client *client)
+{
+ struct kxti9_data *ti9 = i2c_get_clientdata(client);
+
+#ifdef KXTI9_INT_MODE
+ free_irq(ti9->irq, ti9);
+ gpio_free(ti9->pdata->gpio);
+#endif
+ kxti9_input_cleanup(ti9);
+ kxti9_device_power_off(ti9);
+ if (ti9->pdata->exit)
+ ti9->pdata->exit();
+ kfree(ti9->pdata);
+ sysfs_remove_group(&client->dev.kobj, &kxti9_attribute_group);
+ kfree(ti9);
+
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int kxti9_resume(struct i2c_client *client)
+{
+ //struct kxti9_data *ti9 = i2c_get_clientdata(client);
+ //return kxti9_enable(ti9);
+ return 0;
+}
+
+static int kxti9_suspend(struct i2c_client *client, pm_message_t mesg)
+{
+ //struct kxti9_data *ti9 = i2c_get_clientdata(client);
+ //return kxti9_disable(ti9);
+ return 0;
+}
+
+static void kxti9_shutdown(struct i2c_client *client)
+{
+ struct kxti9_data *ti9 = i2c_get_clientdata(client);
+ if (atomic_read(&ti9->enabled)) {
+ flush_delayed_work_sync(&ti9->input_work);
+ cancel_delayed_work_sync(&ti9->input_work);
+ }
+}
+#endif
+
+static const struct i2c_device_id kxti9_id[] = {
+ {NAME, 0},
+ {},
+};
+
+MODULE_DEVICE_TABLE(i2c, kxti9_id);
+
+static struct i2c_driver kxti9_driver = {
+ .driver = {
+ .name = NAME,
+ },
+ .probe = kxti9_probe,
+ .remove = __devexit_p(kxti9_remove),
+ .resume = kxti9_resume,
+ .suspend = kxti9_suspend,
+ .shutdown = kxti9_shutdown,
+ .id_table = kxti9_id,
+};
+
+int kxti9_enable_accel(int en)
+{
+ printk(KERN_DEBUG "%s: enable = %d\n", __func__, en);
+ if (en)
+ kxti9_enable(gs_ti9);
+ else
+ kxti9_disable(gs_ti9);
+ return 0;
+}
+
+int kxti9_setDelay(int mdelay)
+{
+ printk(KERN_DEBUG "%s: delay = %d\n", __func__, mdelay);
+ gs_ti9->res_interval = mdelay;
+ return kxti9_update_odr(gs_ti9, gs_ti9->res_interval);
+}
+
+int kxti9_getLSG(int *lsg)
+{
+ int max_count;
+ if (gs_ti9->resume[RES_CTRL_REG1] & RES_12BIT)
+ max_count = 2048;
+ else
+ max_count = 128;
+
+ if ((gs_ti9->resume[RES_CTRL_REG1] & 0x18) == KXTI9_G_2G)
+ *lsg = max_count >> 1;
+ else if ((gs_ti9->resume[RES_CTRL_REG1] & 0x18) == KXTI9_G_4G)
+ *lsg = max_count >> 2;
+ else if ((gs_ti9->resume[RES_CTRL_REG1] & 0x18) == KXTI9_G_8G)
+ *lsg = max_count >> 3;
+
+ printk(KERN_DEBUG "%s: LSG = %d\n", __func__, *lsg);
+ return 0;
+}
+
+struct gsensor_data kxti9_gs_data = {
+ .i2c_addr = KXTI9_I2C_ADDR,
+ .enable = kxti9_enable_accel,
+ .setDelay = kxti9_setDelay,
+ .getLSG = kxti9_getLSG,
+};
+
+static int __init kxti9_init(void)
+{
+ if (get_gsensor_conf(&gs_conf))
+ return -1;
+
+ if (gs_conf.op != 2)
+ return -1;
+
+ printk("G-Sensor kxti9 init\n");
+
+ if (gsensor_register(&kxti9_gs_data))
+ return -1;
+
+ if (gsensor_i2c_register_device() < 0)
+ return -1;
+
+ return i2c_add_driver(&kxti9_driver);
+}
+
+static void __exit kxti9_exit(void)
+{
+ i2c_del_driver(&kxti9_driver);
+}
+
+module_init(kxti9_init);
+module_exit(kxti9_exit);
+
+MODULE_DESCRIPTION("KXTI9 accelerometer driver");
+MODULE_AUTHOR("Chris Hudson ");
+MODULE_LICENSE("GPL");
diff --git a/ANDROID_3.4.5/drivers/input/sensor/TP_DRIVER_NOT_USE/kxti9_gsensor/kxti9.h b/ANDROID_3.4.5/drivers/input/sensor/TP_DRIVER_NOT_USE/kxti9_gsensor/kxti9.h
new file mode 100755
index 00000000..c66c740a
--- /dev/null
+++ b/ANDROID_3.4.5/drivers/input/sensor/TP_DRIVER_NOT_USE/kxti9_gsensor/kxti9.h
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2009, Kionix, Inc. All Rights Reserved.
+ * Written by Chris Hudson
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+
+#ifndef __KXTI9_H__
+#define __KXTI9_H__
+
+#define KXTI9_I2C_ADDR 0x0F
+/* CONTROL REGISTER 1 BITS */
+#define RES_12BIT 0x40
+#define KXTI9_G_2G 0x00
+#define KXTI9_G_4G 0x08
+#define KXTI9_G_8G 0x10
+#define SHIFT_ADJ_2G 4
+#define SHIFT_ADJ_4G 3
+#define SHIFT_ADJ_8G 2
+#define TPE 0x01 /* tilt position function enable bit */
+#define WUFE 0x02 /* wake-up function enable bit */
+#define TDTE 0x04 /* tap/double-tap function enable bit */
+/* CONTROL REGISTER 3 BITS */
+#define OTP1_6 0x00 /* tilt ODR masks */
+#define OTP6_3 0x20
+#define OTP12_5 0x40
+#define OTP50 0x60
+#define OWUF25 0x00 /* wuf ODR masks */
+#define OWUF50 0x01
+#define OWUF100 0x02
+#define OWUF200 0x03
+#define OTDT50 0x00 /* tdt ODR masks */
+#define OTDT100 0x04
+#define OTDT200 0x08
+#define OTDT400 0x0C
+/* INTERRUPT CONTROL REGISTER 1 BITS */
+#define KXTI9_IEN 0x20 /* interrupt enable */
+#define KXTI9_IEA 0x10 /* interrupt polarity */
+#define KXTI9_IEL 0x08 /* interrupt response */
+#define IEU 0x04 /* alternate unlatched response */
+/* DATA CONTROL REGISTER BITS */
+#define ODR800F 0x06 /* lpf output ODR masks */
+#define ODR400F 0x05
+#define ODR200F 0x04
+#define ODR100F 0x03
+#define ODR50F 0x02
+#define ODR25F 0x01
+#define ODR12_5F 0x00
+
+#ifdef __KERNEL__
+struct kxti9_platform_data {
+ int poll_interval;
+ int min_interval;
+
+ u8 g_range;
+ u8 shift_adj;
+
+ u8 axis_map_x;
+ u8 axis_map_y;
+ u8 axis_map_z;
+
+ u8 negate_x;
+ u8 negate_y;
+ u8 negate_z;
+
+ u8 data_odr_init;
+ u8 ctrl_reg1_init;
+ u8 int_ctrl_init;
+ u8 tilt_timer_init;
+ u8 engine_odr_init;
+ u8 wuf_timer_init;
+ u8 wuf_thresh_init;
+ u8 tdt_timer_init;
+ u8 tdt_h_thresh_init;
+ u8 tdt_l_thresh_init;
+ u8 tdt_tap_timer_init;
+ u8 tdt_total_timer_init;
+ u8 tdt_latency_timer_init;
+ u8 tdt_window_timer_init;
+
+ int (*init)(void);
+ void (*exit)(void);
+ int (*power_on)(void);
+ int (*power_off)(void);
+
+ int gpio;
+};
+#endif /* __KERNEL__ */
+
+#endif /* __KXTI9_H__ */
+
diff --git a/ANDROID_3.4.5/drivers/input/sensor/cm3232/Makefile b/ANDROID_3.4.5/drivers/input/sensor/cm3232/Makefile
new file mode 100755
index 00000000..06c28edd
--- /dev/null
+++ b/ANDROID_3.4.5/drivers/input/sensor/cm3232/Makefile
@@ -0,0 +1,34 @@
+KERNELDIR=../../../../
+#KERNELDIR=/home/hangyan/android8850/kernel/ANDROID_3.0.8
+CROSS = arm_1103_le-
+CC= $(CROSS)gcc
+LD= $(CROSS)ld
+STRIP = $(CROSS)strip
+
+DEBUG = n
+
+# Add your debugging flag (or not) to EXTRA_CFLAGS
+ifeq ($(DEBUG),y)
+# DEBFLAGS = -O -g -DSCULL_DEBUG # "-O" is needed to expand inlines
+DEBFLAGS = -O0 -g -DSCULL_DEBUG # "-O" is needed to expand inlines
+
+else
+ DEBFLAGS = -O2 -Wall
+endif
+
+EXTRA_CFLAGS += $(DEBFLAGS)
+
+
+MY_MODULE_NAME=s_wmt_lsensor_cm3232
+
+obj-m := $(MY_MODULE_NAME).o
+$(MY_MODULE_NAME)-objs := cm3232.o
+
+default:
+ $(MAKE) -C $(KERNELDIR) SUBDIRS=$(PWD) modules
+ $(STRIP) --strip-debug $(MY_MODULE_NAME).ko
+ rm -rf *.o *~ core .depend .*.cmd *.mod.c .tmp_versions
+
+clean:
+ rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions *.order *.symvers
+
diff --git a/ANDROID_3.4.5/drivers/input/sensor/cm3232/cm3232.c b/ANDROID_3.4.5/drivers/input/sensor/cm3232/cm3232.c
new file mode 100755
index 00000000..207ddd3a
--- /dev/null
+++ b/ANDROID_3.4.5/drivers/input/sensor/cm3232/cm3232.c
@@ -0,0 +1,855 @@
+/*
+ * cm3232.c - Intersil cm3232 ALS & Proximity Driver
+ *
+ * By Intersil Corp
+ * Michael DiGioia
+ *
+ * Based on isl29011.c
+ * by Mike DiGioia
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+//#include
+
+#include "../sensor.h"
+
+/* Insmod parameters */
+//I2C_CLIENT_INSMOD_1(cm3232);
+#define SENSOR_I2C_NAME "cm3232"
+#define SENSOR_I2C_ADDR 0x10
+#define MODULE_NAME "cm3232"
+
+#define REG_CMD_1 0x00
+#define REG_CMD_2 0x01
+#define REG_DATA_LSB 0x02
+#define REG_DATA_MSB 0x03
+#define ISL_MOD_MASK 0xE0
+#define ISL_MOD_POWERDOWN 0
+#define ISL_MOD_ALS_ONCE 1
+#define ISL_MOD_IR_ONCE 2
+#define ISL_MOD_RESERVED 4
+#define ISL_MOD_ALS_CONT 5
+#define ISL_MOD_IR_CONT 6
+#define IR_CURRENT_MASK 0xC0
+#define IR_FREQ_MASK 0x30
+#define SENSOR_RANGE_MASK 0x03
+#define ISL_RES_MASK 0x0C
+
+
+#undef dbg
+#define dbg(fmt, args...) //printk(KERN_ALERT "[%s]: " fmt, __FUNCTION__ , ## args)
+
+#undef errlog
+#undef klog
+#define errlog(fmt, args...) printk(KERN_ERR "[%s]: " fmt, __FUNCTION__, ## args)
+#define klog(fmt, args...) printk(KERN_ALERT "[%s]: " fmt, __FUNCTION__, ## args)
+
+extern int wmt_getsyspara(char *varname, unsigned char *varval, int *varlen);
+static int no_adc_map = 1;
+static int last_mod;
+
+static struct i2c_client *this_client = NULL;
+
+struct isl_device {
+ struct input_polled_dev* input_poll_dev;
+ struct i2c_client* client;
+ int resolution;
+ int range;
+ int isdbg;
+#ifdef CONFIG_HAS_EARLYSUSPEND
+ struct early_suspend earlysuspend;
+#endif
+
+};
+
+static struct isl_device* l_sensorconfig = NULL;
+static struct kobject *android_lsensor_kobj = NULL;
+static int l_enable = 0; // 0:don't report data, 1
+
+static DEFINE_MUTEX(mutex);
+
+#if 0
+static int isl_set_mod(struct i2c_client *client, int mod)
+{
+ int ret, val, freq;
+
+ switch (mod) {
+ case ISL_MOD_POWERDOWN:
+ case ISL_MOD_RESERVED:
+ goto setmod;
+ case ISL_MOD_ALS_ONCE:
+ case ISL_MOD_ALS_CONT:
+ freq = 0;
+ break;
+ case ISL_MOD_IR_ONCE:
+ case ISL_MOD_IR_CONT:
+ freq = 1;
+ break;
+ default:
+ return -EINVAL;
+ }
+ /* set IR frequency */
+ val = i2c_smbus_read_byte_data(client, REG_CMD_2);
+ if (val < 0)
+ return -EINVAL;
+ val &= ~IR_FREQ_MASK;
+ if (freq)
+ val |= IR_FREQ_MASK;
+ ret = i2c_smbus_write_byte_data(client, REG_CMD_2, val);
+ if (ret < 0)
+ return -EINVAL;
+
+setmod:
+ /* set operation mod */
+ val = i2c_smbus_read_byte_data(client, REG_CMD_1);
+ if (val < 0)
+ return -EINVAL;
+ val &= ~ISL_MOD_MASK;
+ val |= (mod << 5);
+ ret = i2c_smbus_write_byte_data(client, REG_CMD_1, val);
+ if (ret < 0)
+ return -EINVAL;
+
+ if (mod != ISL_MOD_POWERDOWN)
+ last_mod = mod;
+
+ return mod;
+}
+
+static int isl_get_res(struct i2c_client *client)
+{
+ int val;
+
+ printk(KERN_INFO MODULE_NAME ": %s cm3232 get_res call, \n", __func__);
+ val = i2c_smbus_read_word_data(client, 0)>>8 & 0xff;
+
+ if (val < 0)
+ return -EINVAL;
+
+ val &= ISL_RES_MASK;
+ val >>= 2;
+
+ switch (val) {
+ case 0:
+ return 65536;
+ case 1:
+ return 4096;
+ case 2:
+ return 256;
+ case 3:
+ return 16;
+ default:
+ return -EINVAL;
+ }
+}
+
+static int isl_get_range(struct i2c_client* client)
+{
+ switch (i2c_smbus_read_word_data(client, 0)>>8 & 0xff & 0x3) {
+ case 0: return 1000;
+ case 1: return 4000;
+ case 2: return 16000;
+ case 3: return 64000;
+ default: return -EINVAL;
+ }
+}
+#endif
+//Fixme plan to transfer the adc value to the config.xml lux 2013-5-10
+static __u16 uadc[8] = {2, 8, 100, 400, 900, 1000, 1500, 1900};//customize
+static __u16 ulux[9] = {128, 200, 1300, 2000, 3000, 4000, 5000, 6000, 7000};
+static __u16 adc_to_lux(__u16 adc)
+{
+ static long long var = 0;
+ int i = 0; //length of array is 8,9
+ for (i=0; i<8; i++) {
+ if ( adc < uadc[i]){
+ break;
+ }
+ }
+ if ( i<9)
+ {
+ var++;
+ if (var%2)
+ return ulux[i]+0;
+ else
+ return ulux[i]+1;
+ }
+ return ulux[4];
+}
+
+
+
+static int isl_get_lux_data(struct i2c_client* client)
+{
+ //struct isl_device* idev = i2c_get_clientdata(client);
+
+ //__u16 resH = 0, resL = 0;
+ __s16 resH = 0, resL = 0;
+ //int range;
+ resL = i2c_smbus_read_word_data(client, 0x50);
+ //resH = i2c_smbus_read_word_data(client, 0x51)&0xff00;
+ if ((resL < 0) || (resH < 0))
+ {
+ errlog("Error to read lux_data!\n");
+
+ return 3000;//???
+ //return -1;
+ }
+ //Fixme plan to transfer the adc value to the config.xml lux 2013-5-10
+ if (!no_adc_map)
+ resL = adc_to_lux(resL);
+ //printk("<<<< lux %d\n", resL);
+ return resL ;//* idev->range / idev->resolution;
+ return (resH | resL) ;//* idev->range / idev->resolution;
+}
+
+
+static int isl_set_default_config(struct i2c_client *client)
+{
+ //struct isl_device* idev = i2c_get_clientdata(client);
+
+ int ret=0;
+ //ret = _cm3232_I2C_Write_Byte(CM3232_SLAVE_addr, CM3232_ALS_RESET);
+ ret = i2c_smbus_write_byte_data(client, 0, (1 << 6));
+ if (ret < 0)
+ return -EINVAL;
+ //if(ret<0)
+ //return ret;
+ msleep(10);
+
+ //ret = _cm3232_I2C_Write_Byte(CM3232_SLAVE_addr, CM3232_ALS_IT_200ms | CM3232_ALS_HS_HIGH );
+ ret = i2c_smbus_write_byte_data(client, 0, (1 << 2)|(1 << 1));
+ if (ret < 0)
+ return -EINVAL;
+ msleep(10);
+ return 0;
+/* We don't know what it does ... */
+// ret = i2c_smbus_write_byte_data(client, REG_CMD_1, 0xE0);
+// ret = i2c_smbus_write_byte_data(client, REG_CMD_2, 0xC3);
+/* Set default to ALS continuous */
+ ret = i2c_smbus_write_byte_data(client, REG_CMD_1, 0xA0);
+ if (ret < 0)
+ return -EINVAL;
+/* Range: 0~16000, number of clock cycles: 65536 */
+ ret = i2c_smbus_write_byte_data(client, REG_CMD_2, 0x02); // vivienne
+ if (ret < 0)
+ return -EINVAL;
+ //idev->resolution = isl_get_res(client);
+ //idev->range = isl_get_range(client);;
+ dbg("cm3232 set_default_config call, \n");
+
+ return 0;
+}
+
+/* Return 0 if detection is successful, -ENODEV otherwise */
+static int cm3232_detect(struct i2c_client *client/*, int kind,
+ struct i2c_board_info *info*/)
+{
+
+
+ return 0;
+}
+
+int isl_input_open(struct input_dev* input)
+{
+ return 0;
+}
+
+void isl_input_close(struct input_dev* input)
+{
+}
+
+static void isl_input_lux_poll(struct input_polled_dev *dev)
+{
+ struct isl_device* idev = dev->private;
+ struct input_dev* input = idev->input_poll_dev->input;
+ struct i2c_client* client = idev->client;
+ static unsigned int val=0;
+
+ //printk("%s\n", __FUNCTION__);
+ if (l_enable != 0)
+ {
+ mutex_lock(&mutex);
+ //pm_runtime_get_sync(dev);
+ #if 0
+ if(val>0x2000)
+ val=0;
+ val+=100;
+ #endif
+ //printk(KERN_ALERT "by flashchen val is %x",val);
+ input_report_abs(input, ABS_MISC, isl_get_lux_data(client));
+ //input_report_abs(input, ABS_MISC, val);//isl_get_lux_data(client));
+ input_sync(input);
+ //pm_runtime_put_sync(dev);
+ mutex_unlock(&mutex);
+ }
+}
+
+static struct i2c_device_id cm3232_id[] = {
+ {"cm3232", 0},
+ {}
+};
+
+#if 0
+static int cm3232_runtime_suspend(struct device *dev)
+{
+
+ dev_dbg(dev, "suspend\n");
+
+ mutex_lock(&mutex);
+ pm_runtime_get_sync(dev);
+ //isl_set_mod(client, ISL_MOD_POWERDOWN);
+ pm_runtime_put_sync(dev);
+ mutex_unlock(&mutex);
+
+ printk(KERN_INFO MODULE_NAME ": %s cm3232 suspend call, \n", __func__);
+ return 0;
+}
+
+static int cm3232_runtime_resume(struct device *dev)
+{
+
+ dev_dbg(dev, "resume\n");
+
+ mutex_lock(&mutex);
+ pm_runtime_get_sync(dev);
+ //isl_set_mod(client, last_mod);
+ pm_runtime_put_sync(dev);
+ mutex_unlock(&mutex);
+
+ printk(KERN_INFO MODULE_NAME ": %s cm3232 resume call, \n", __func__);
+ return 0;
+}
+#endif
+MODULE_DEVICE_TABLE(i2c, cm3232_id);
+
+/*static const struct dev_pm_ops cm3232_pm_ops = {
+ .runtime_suspend = cm3232_runtime_suspend,
+ .runtime_resume = cm3232_runtime_resume,
+};
+
+static struct i2c_board_info isl_info = {
+ I2C_BOARD_INFO("cm3232", 0x44),
+};
+
+static struct i2c_driver cm3232_driver = {
+ .driver = {
+ .name = "cm3232",
+ .pm = &cm3232_pm_ops,
+ },
+ .probe = cm3232_probe,
+ .remove = cm3232_remove,
+ .id_table = cm3232_id,
+ .detect = cm3232_detect,
+ //.address_data = &addr_data,
+};*/
+
+static int mmad_open(struct inode *inode, struct file *file)
+{
+ dbg("Open the l-sensor node...\n");
+ return 0;
+}
+
+static int mmad_release(struct inode *inode, struct file *file)
+{
+ dbg("Close the l-sensor node...\n");
+ return 0;
+}
+
+static ssize_t mmad_read(struct file *fl, char __user *buf, size_t cnt, loff_t *lf)
+{
+ int lux_data = 0;
+
+ mutex_lock(&mutex);
+ lux_data = isl_get_lux_data(l_sensorconfig->client);
+ mutex_unlock(&mutex);
+ if (lux_data < 0)
+ {
+ errlog("Failed to read lux data!\n");
+ return -1;
+ }
+ printk(KERN_ALERT "lux_data is %x\n",lux_data);
+ //return 0;
+ copy_to_user(buf, &lux_data, sizeof(lux_data));
+ return sizeof(lux_data);
+}
+
+static long
+mmad_ioctl(/*struct inode *inode,*/ struct file *file, unsigned int cmd,
+ unsigned long arg)
+{
+ void __user *argp = (void __user *)arg;
+ //char rwbuf[5];
+ short enable; //amsr = -1;
+ unsigned int uval;
+
+ dbg("l-sensor ioctr...\n");
+ //memset(rwbuf, 0, sizeof(rwbuf));
+ switch (cmd) {
+ case LIGHT_IOCTL_SET_ENABLE:
+ // enable/disable sensor
+ if (copy_from_user(&enable, argp, sizeof(short)))
+ {
+ printk(KERN_ERR "Can't get enable flag!!!\n");
+ return -EFAULT;
+ }
+ dbg("enable=%d\n",enable);
+ if ((enable >=0) && (enable <=1))
+ {
+ dbg("driver: disable/enable(%d) gsensor.\n", enable);
+
+ //l_sensorconfig.sensor_enable = enable;
+ dbg("Should to implement d/e the light sensor!\n");
+ l_enable = enable;
+
+ } else {
+ printk(KERN_ERR "Wrong enable argument in %s !!!\n", __FUNCTION__);
+ return -EINVAL;
+ }
+ break;
+ case WMT_IOCTL_SENSOR_GET_DRVID:
+#define CM3232_DRVID 0
+ uval = CM3232_DRVID ;
+ if (copy_to_user((unsigned int*)arg, &uval, sizeof(unsigned int)))
+ {
+ return -EFAULT;
+ }
+ dbg("cm3232_driver_id:%d\n",uval);
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+
+static struct file_operations mmad_fops = {
+ .owner = THIS_MODULE,
+ .open = mmad_open,
+ .release = mmad_release,
+ .read = mmad_read,
+ .unlocked_ioctl = mmad_ioctl,
+};
+
+
+static struct miscdevice mmad_device = {
+ .minor = MISC_DYNAMIC_MINOR,
+ .name = "lsensor_ctrl",
+ .fops = &mmad_fops,
+};
+
+#ifdef CONFIG_HAS_EARLYSUSPEND
+static void cm3232_early_suspend(struct early_suspend *h)
+{
+ struct i2c_client *client = l_sensorconfig->client;
+
+ dbg("start\n");
+ mutex_lock(&mutex);
+ //pm_runtime_get_sync(dev);
+ //isl_set_mod(client, ISL_MOD_POWERDOWN);
+ //pm_runtime_put_sync(dev);
+ mutex_unlock(&mutex);
+ dbg("exit\n");
+}
+
+static void cm3232_late_resume(struct early_suspend *h)
+{
+ struct i2c_client *client = l_sensorconfig->client;
+
+ dbg("start\n");
+ mutex_lock(&mutex);
+ //pm_runtime_get_sync(dev);
+ //isl_set_mod(client, last_mod);
+ isl_set_default_config(client);
+ //pm_runtime_put_sync(dev);
+ mutex_unlock(&mutex);
+ dbg("exit\n");
+}
+#endif
+static ssize_t adc_show(struct device *dev, struct device_attribute *attr, char *buf)
+{
+
+ int i;
+ int size = sizeof(uadc)/sizeof(uadc[0]);
+ printk("<<<%s\n", __FUNCTION__);
+ for (i=0; i>>\n", buf);
+ n = sscanf(buf, "%d:%d", &index, &tmp);
+ printk("<<<=0 && index=0; i--)
+ device_remove_file(dev, &attr[i]);//&attr[i].attr
+ }
+ return err;
+}
+
+static void device_remove_attribute(struct device *dev, struct device_attribute *attr)
+{
+ int i;
+ for (i=0; attr[i].attr.name != NULL; i++)
+ device_remove_file(dev, &attr[i]); //&attr[i].attr
+}
+
+
+static int get_adc_val(void)
+{
+ int i, varlen, n;
+ __u32 buf[8];
+ char varbuf[50];
+ char *name = "wmt.io.lsensor";
+
+ varlen = sizeof(varbuf);
+ if (wmt_getsyspara(name, varbuf, &varlen))
+ {
+ printk("<<<dev);
+ idev->input_poll_dev = input_allocate_polled_device();
+ if(!idev->input_poll_dev)
+ {
+ res = -ENOMEM;
+ goto err_input_allocate_device;
+ }
+ idev->client = client;
+ idev->input_poll_dev->private = idev;
+ idev->input_poll_dev->poll = isl_input_lux_poll;
+ idev->input_poll_dev->poll_interval = 100;//50;
+ idev->input_poll_dev->input->open = isl_input_open;
+ idev->input_poll_dev->input->close = isl_input_close;
+ idev->input_poll_dev->input->name = "lsensor_lux";
+ idev->input_poll_dev->input->id.bustype = BUS_I2C;
+ idev->input_poll_dev->input->dev.parent = &client->dev;
+ input_set_drvdata(idev->input_poll_dev->input, idev);
+ input_set_capability(idev->input_poll_dev->input, EV_ABS, ABS_MISC);
+ input_set_abs_params(idev->input_poll_dev->input, ABS_MISC, 0, 16000, 0, 0);
+ i2c_set_clientdata(client, idev);
+ /* set default config after set_clientdata */
+ res = isl_set_default_config(client);
+ res = misc_register(&mmad_device);
+ if (res) {
+ errlog("mmad_device register failed\n");
+ goto err_misc_register;
+ }
+ res = input_register_polled_device(idev->input_poll_dev);
+ if(res < 0)
+ goto err_input_register_device;
+ // suspend/resume register
+#ifdef CONFIG_HAS_EARLYSUSPEND
+ idev->earlysuspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1;
+ idev->earlysuspend.suspend = cm3232_early_suspend;
+ idev->earlysuspend.resume = cm3232_late_resume;
+ register_early_suspend(&(idev->earlysuspend));
+#endif
+
+ dbg("cm3232 probe succeed!\n");
+ //create class device sysdevice 2013-5-10
+ //get_adc_val();
+ sclass = class_create(THIS_MODULE, "cm3232");
+ if (IS_ERR(sclass))
+ {
+ printk("<<<%s fail to create class!\n", __FUNCTION__);
+ return 0;
+ }
+
+
+ sret = alloc_chrdev_region(&sdev_no, 0, 1, "cm3232_devno");
+ if (sret)
+ {
+ printk("<<<<%s alloc_chrdev_region fail!\n", __FUNCTION__);
+ class_destroy(sclass);
+ return 0;
+ }
+ sdevice = device_create(sclass, NULL, sdev_no, NULL, "cm3232_dev");
+ if (IS_ERR(sdevice))
+ {
+ printk("<<<%s device_create fail!\n", __FUNCTION__);
+ class_destroy(sclass);
+ return 0;
+ }
+ device_create_attribute(sdevice, cm3232_attr);
+
+ return 0;
+err_input_register_device:
+ misc_deregister(&mmad_device);
+ input_free_polled_device(idev->input_poll_dev);
+err_misc_register:
+err_input_allocate_device:
+ //__pm_runtime_disable(&client->dev, false);
+
+ kobject_del(android_lsensor_kobj);
+
+ kfree(idev);
+ return res;
+}
+
+static int cm3232_remove(struct i2c_client *client)
+{
+ struct isl_device* idev = i2c_get_clientdata(client);
+ if (!IS_ERR(sdevice))
+ {
+ device_remove_attribute(sdevice, cm3232_attr);
+ device_destroy(sclass, sdev_no);
+ class_destroy(sclass);
+
+ }
+ //unregister_early_suspend(&(idev->earlysuspend));
+ misc_deregister(&mmad_device);
+ input_unregister_polled_device(idev->input_poll_dev);
+ input_free_polled_device(idev->input_poll_dev);
+ //sysfs_remove_group(android_lsensor_kobj, &m_isl_gr);
+ kobject_del(android_lsensor_kobj);
+ //__pm_runtime_disable(&client->dev, false);
+ kfree(idev);
+ printk(KERN_INFO MODULE_NAME ": %s cm3232 remove call, \n", __func__);
+ return 0;
+}
+//****************add platform_device & platform_driver for suspend &resume 2013-7-2
+static int ls_probe(struct platform_device *pdev){
+ //printk("<<<%s\n", __FUNCTION__);
+ return 0;
+}
+static int ls_remove(struct platform_device *pdev){
+ //printk("<<<%s\n", __FUNCTION__);
+ return 0;
+}
+static int ls_suspend(struct platform_device *pdev, pm_message_t state){
+ printk("<<<%s\n", __FUNCTION__);
+
+ return 0;
+}
+
+static int ls_resume(struct platform_device *pdev){
+ //return 0;
+ int ret = 0;
+ int count = 0;
+ printk("<<<%s\n", __FUNCTION__);
+RETRY:
+ ret = isl_set_default_config(this_client);
+ if (ret < 0){
+ printk("%s isl_set_default_config fail!\n", __FUNCTION__);
+ count++;
+ if (count < 5){
+ mdelay(2);
+ goto RETRY;
+ }
+ else
+ return ret;
+ }
+ return 0;
+
+}
+static void lsdev_release(struct device *dev)
+{
+ return;
+}
+static struct platform_device lsdev = {
+ .name = "lsdevice",
+ .id = -1,
+ .dev = {
+ .release = lsdev_release,
+ },
+};
+static struct platform_driver lsdrv = {
+ .probe = ls_probe,
+ .remove = ls_remove,
+ .suspend = ls_suspend,
+ .resume = ls_resume,
+ .driver = {
+ .name = "lsdevice",
+ },
+};
+//********************************************************************
+
+static int __init sensor_cm3232_init(void)
+{
+ int ret = 0;
+ printk(KERN_INFO MODULE_NAME ": %s cm3232 init call, \n", __func__);
+ /*
+ * Force device to initialize: i2c-15 0x44
+ * If i2c_new_device is not called, even cm3232_detect will not run
+ * TODO: rework to automatically initialize the device
+ */
+ //i2c_new_device(i2c_get_adapter(15), &isl_info);
+ //return i2c_add_driver(&cm3232_driver);
+ if (!(this_client = sensor_i2c_register_device(2, SENSOR_I2C_ADDR, SENSOR_I2C_NAME)))
+ {
+ printk(KERN_EMERG"Can't register gsensor i2c device!\n");
+ return -1;
+ }
+ if (cm3232_detect(this_client))
+ {
+ errlog("Can't find light sensor cm3232!\n");
+ goto detect_fail;
+ }
+ get_adc_val();
+ if(cm3232_probe(this_client))
+ {
+ errlog("Erro for probe!\n");
+ goto detect_fail;
+ }
+
+ ret = platform_device_register(&lsdev);
+ if (ret){
+ printk("<<
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+//#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+//////////////////////////////////////////////////////////
+#define AKMIO 0xA1
+
+/* IOCTLs for AKM library */
+#define ECS_IOCTL_INIT _IO(AKMIO, 0x01)
+#define ECS_IOCTL_WRITE _IOW(AKMIO, 0x02, char[5])
+#define ECS_IOCTL_READ _IOWR(AKMIO, 0x03, char[5])
+#define ECS_IOCTL_RESET _IO(AKMIO, 0x04)
+#define ECS_IOCTL_INT_STATUS _IO(AKMIO, 0x05)
+#define ECS_IOCTL_FFD_STATUS _IO(AKMIO, 0x06)
+#define ECS_IOCTL_SET_MODE _IOW(AKMIO, 0x07, short)
+#define ECS_IOCTL_GETDATA _IOR(AKMIO, 0x08, char[RBUFF_SIZE+1])
+#define ECS_IOCTL_GET_NUMFRQ _IOR(AKMIO, 0x09, char[2])
+#define ECS_IOCTL_SET_PERST _IO(AKMIO, 0x0A)
+#define ECS_IOCTL_SET_G0RST _IO(AKMIO, 0x0B)
+#define ECS_IOCTL_SET_YPR _IOW(AKMIO, 0x0C, short[12])
+#define ECS_IOCTL_GET_OPEN_STATUS _IOR(AKMIO, 0x0D, int)
+#define ECS_IOCTL_GET_CLOSE_STATUS _IOR(AKMIO, 0x0E, int)
+#define ECS_IOCTL_GET_CALI_DATA _IOR(AKMIO, 0x0F, char[MAX_CALI_SIZE])
+#define ECS_IOCTL_GET_DELAY _IOR(AKMIO, 0x30, short)
+
+/* IOCTLs for APPs */
+#define ECS_IOCTL_APP_SET_MODE _IOW(AKMIO, 0x10, short)
+#define ECS_IOCTL_APP_SET_MFLAG _IOW(AKMIO, 0x11, short)
+#define ECS_IOCTL_APP_GET_MFLAG _IOW(AKMIO, 0x12, short)
+//#define ECS_IOCTL_APP_SET_AFLAG _IOW(AKMIO, 0x13, short)
+#define ECS_IOCTL_APP_GET_AFLAG _IOR(AKMIO, 0x14, short)
+#define ECS_IOCTL_APP_SET_TFLAG _IOR(AKMIO, 0x15, short)
+#define ECS_IOCTL_APP_GET_TFLAG _IOR(AKMIO, 0x16, short)
+#define ECS_IOCTL_APP_RESET_PEDOMETER _IO(AKMIO, 0x17)
+//#define ECS_IOCTL_APP_SET_DELAY _IOW(AKMIO, 0x18, short)
+#define ECS_IOCTL_APP_GET_DELAY ECS_IOCTL_GET_DELAY
+#define ECS_IOCTL_APP_SET_MVFLAG _IOW(AKMIO, 0x19, short) /* Set raw magnetic vector flag */
+#define ECS_IOCTL_APP_GET_MVFLAG _IOR(AKMIO, 0x1A, short) /* Get raw magnetic vector flag */
+
+#define WMTGSENSOR_IOCTL_MAGIC 0x09
+#define WMT_IOCTL_SENSOR_CAL_OFFSET _IOW(WMTGSENSOR_IOCTL_MAGIC, 0x01, int) //offset calibration
+#define ECS_IOCTL_APP_SET_AFLAG _IOW(WMTGSENSOR_IOCTL_MAGIC, 0x02, short)
+#define ECS_IOCTL_APP_SET_DELAY _IOW(WMTGSENSOR_IOCTL_MAGIC, 0x03, short)
+#define WMT_IOCTL_SENSOR_GET_DRVID _IOW(WMTGSENSOR_IOCTL_MAGIC, 0x04, unsigned int)
+
+
+/* IOCTLs for pedometer */
+#define ECS_IOCTL_SET_STEP_CNT _IOW(AKMIO, 0x20, short)
+//////////////////////////////////////////////////////////////////
+#define SENSOR_DELAY_FASTEST 0
+#define SENSOR_DELAY_GAME 20
+#define SENSOR_DELAY_UI 60
+#define SENSOR_DELAY_NORMAL 200
+
+#define DMARD06_DRVID 3
+
+/////////////////////////////////////////////////////////////////
+
+#undef dbg
+#define dbg(fmt, args...) if (l_sensorconfig.isdbg) printk(KERN_ALERT "[%s]: " fmt, __FUNCTION__, ## args)
+
+#undef errlog
+#undef klog
+#define errlog(fmt, args...) printk(KERN_ERR "[%s]: " fmt, __FUNCTION__, ## args)
+#define klog(fmt, args...) printk(KERN_ALERT "[%s]: " fmt, __FUNCTION__, ## args)
+
+#define DMARD06_I2C_NAME "dmard06"
+#define DMARD06_I2C_ADDR 0x1c
+
+#define GSENSOR_PROC_NAME "gsensor_config"
+#define GSENSOR_MAJOR 161
+#define GSENSOR_NAME "dmard06"
+#define GSENSOR_DRIVER_NAME "dmard06_drv"
+
+#define GSENDMARD06_UBOOT_NAME "wmt.io.d06sensor"
+
+#define MAX_WR_DMARD06_LEN (1+1)
+
+#define LSG 32
+
+static char const *const ACCELEMETER_CLASS_NAME = "accelemeter";
+static char const *const DMARD06_DEVICE_NAME = "dmard06";
+////////////////////////////////////////////////////////////
+#define ID_REG_ADDR 0x0F
+#define SWRESET_REG_ADDR 0x53
+#define T_REG_ADDR 0x40
+#define XYZ_REG_ADDR 0x41
+#define CTR1_REG_ADDR 0x44
+#define CTR2_REG_ADDR 0x45
+#define CTR3_REG_ADDR 0x46
+#define CTR4_REG_ADDR 0x47
+#define CTR5_REG_ADDR 0x48
+#define STAT_REG_ADDR 0x49
+
+
+
+static int dmard06_init(void);
+static void dmard06_exit(void);
+
+static int dmard06_file_open(struct inode*, struct file*);
+static ssize_t dmard06_file_write(struct file*, const char*, size_t, loff_t*);
+static ssize_t dmard06_file_read(struct file*, char*, size_t, loff_t*);
+static int dmard06_file_close(struct inode*, struct file*);
+
+static int dmard06_i2c_suspend(struct platform_device *pdev, pm_message_t state);
+static int dmard06_i2c_resume(struct platform_device *pdev);
+static int dmard06_i2c_probe(void);
+static int dmard06_i2c_remove(void);
+static void dmard06_i2c_read_xyz(s8 *x, s8 *y, s8 *z);
+static void dmard06_i2c_accel_value(s8 *val);
+static int dmard06_probe(
+ struct platform_device *pdev);
+static int dmard06_remove(struct platform_device *pdev);
+static int dmard06_i2c_xyz_read_reg(u8* index ,u8 *buffer, int length);
+
+
+
+//extern int wmt_i2c_xfer_continue_if_4(struct i2c_msg *msg, unsigned int num, int bus_id);
+extern int i2c_api_do_send(int bus_id, char chip_addr, char sub_addr, char *buf, unsigned int size);
+extern int i2c_api_do_recv(int bus_id, char chip_addr, char sub_addr, char *buf, unsigned int size);
+
+extern int wmt_setsyspara(char *varname, unsigned char *varval);
+
+/////////////////////////////////////////////////////////////////
+struct work_struct poll_work;
+static struct mutex sense_data_mutex;
+
+
+struct dmard06_config
+{
+ int op;
+ int int_gpio; //0-3
+ int samp;
+ int xyz_axis[3][3]; // (axis,direction)
+ int irq;
+ struct proc_dir_entry* sensor_proc;
+ //int sensorlevel;
+ //int shake_enable; // 1--enable shake, 0--disable shake
+ //int manual_rotation; // 0--landance, 90--vertical
+ struct input_dev *input_dev;
+ //struct work_struct work;
+ struct delayed_work work; // for polling
+ struct workqueue_struct *queue;
+ int isdbg; // 0-- no debug log, 1--show debug log
+ int sensor_samp; //
+ int sensor_enable; // 0 --> disable sensor, 1 --> enable sensor
+ int test_pass;
+ spinlock_t spinlock;
+ int pollcnt; // the counts of polling
+ int offset[3]; // for calibration
+#ifdef CONFIG_HAS_EARLYSUSPEND
+ struct early_suspend earlysuspend;
+#endif
+};
+
+static struct dmard06_config l_sensorconfig = {
+ .op = 0,
+ .int_gpio = 3,
+ .samp = 16,
+ .xyz_axis = {
+ {ABS_X, -1},
+ {ABS_Y, 1},
+ {ABS_Z, -1},
+ },
+ .irq = 6,
+ .int_gpio = 3,
+ .sensor_proc = NULL,
+ //.sensorlevel = SENSOR_GRAVITYGAME_MODE,
+ //.shake_enable = 0, // default enable shake
+ .isdbg = 0,
+ .sensor_samp = 1, // 1 sample/second
+ .sensor_enable = 1, // enable sensor
+ .test_pass = 0, // for test program
+ .pollcnt = 0, // Don't report the x,y,z when the driver is loaded until 2~3 seconds
+ .offset = {0, 0, 0},
+};
+
+static struct class* l_dev_class = NULL;
+static struct device *l_clsdevice = NULL;
+
+
+struct raw_data
+{
+ short x;
+ short y;
+ short z;
+};
+
+struct dev_data
+{
+ dev_t devno;
+ struct cdev cdev;
+ struct class *class;
+ struct i2c_client *client;
+};
+
+static struct dev_data dev;
+
+struct file_operations dmard06_fops =
+{
+ .owner = THIS_MODULE,
+ .read = dmard06_file_read,
+ .write = dmard06_file_write,
+ .open = dmard06_file_open,
+ .release = dmard06_file_close,
+};
+
+static int dmard06_file_open(struct inode *inode, struct file *filp)
+{
+ dbg("open...\n");
+
+ return 0;
+}
+
+static ssize_t dmard06_file_write(struct file *filp, const char *buf, size_t count, loff_t *f_pos)
+{
+ dbg("write...\n");
+
+ return 0;
+}
+
+unsigned int sample_rate_2_memsec(unsigned int rate)
+{
+ return (1000/rate);
+}
+
+static int dmard06_packet_rptValue(int x, int y, int z)
+{
+ return ((0xFF&z) | ((0xFF&y)<<8) | ((0xFF&x)<<16));
+}
+
+
+static void dmard06_work_func(struct work_struct *work)
+{
+ u8 buffer[3];
+ //buffer[0] = 0x41;
+ u8 index = 0x41;
+ s8 x,y,z;
+ int xyz,tx,ty,tz;
+
+ mutex_lock(&sense_data_mutex);
+ //read data
+ dmard06_i2c_xyz_read_reg(&index, buffer, 3);
+ mutex_unlock(&sense_data_mutex);
+ // check whether it's valid
+ // report the data
+ x = (s8)buffer[0];
+ y = (s8)buffer[1];
+ z = (s8)buffer[2];
+ dmard06_i2c_accel_value(&x);
+ dmard06_i2c_accel_value(&y);
+ dmard06_i2c_accel_value(&z);
+ tx = x*l_sensorconfig.xyz_axis[0][1]+l_sensorconfig.offset[0];
+ ty = y*l_sensorconfig.xyz_axis[1][1]+l_sensorconfig.offset[1];
+ tz = z*l_sensorconfig.xyz_axis[2][1]+l_sensorconfig.offset[2];
+ xyz = dmard06_packet_rptValue(tx, ty, tz);
+ input_report_abs(l_sensorconfig.input_dev, ABS_X, xyz);
+
+ //input_report_abs(l_sensorconfig.input_dev, l_sensorconfig.xyz_axis[0][0],
+ // x*l_sensorconfig.xyz_axis[0][1]+l_sensorconfig.offset[0]);
+ //input_report_abs(l_sensorconfig.input_dev, l_sensorconfig.xyz_axis[1][0],
+ // y*l_sensorconfig.xyz_axis[1][1]+l_sensorconfig.offset[1]);
+ //input_report_abs(l_sensorconfig.input_dev, l_sensorconfig.xyz_axis[2][0],
+ //z*l_sensorconfig.xyz_axis[2][1]+l_sensorconfig.offset[2]);
+ input_sync(l_sensorconfig.input_dev);
+ dbg("x=%2x(tx=%2x),y=%2x(ty=%2x),z=%2x(tz=%2x),xyz=%x",
+ (char)x, (char)tx, (char)y, (char)ty, (char)z, (char)tz, xyz);
+
+ // for next polling
+ queue_delayed_work(l_sensorconfig.queue, &l_sensorconfig.work, msecs_to_jiffies(sample_rate_2_memsec(l_sensorconfig.sensor_samp)));
+ //klog("%d=%d,%d=%d,%d=%d\n", l_sensorconfig.xyz_axis[0][0], x*l_sensorconfig.xyz_axis[0][1],
+ // l_sensorconfig.xyz_axis[1][0], y*l_sensorconfig.xyz_axis[1][1],
+ // l_sensorconfig.xyz_axis[2][0], z*l_sensorconfig.xyz_axis[2][1]);
+ //klog("the polling period:%d\n", msecs_to_jiffies(sample_rate_2_memsec(l_sensorconfig.sensor_samp)));
+
+}
+
+
+static ssize_t dmard06_file_read(struct file *filp, char *buf, size_t count, loff_t *f_pos)
+{
+ int ret;
+ s8 x, y, z;
+ struct raw_data rdata;
+
+ dbg("read...\n");
+ mutex_lock(&sense_data_mutex);
+ dmard06_i2c_read_xyz(&x, &y, &z);
+ rdata.x = x;
+ rdata.y = y;
+ rdata.z = z;
+
+ ret = copy_to_user(buf, &rdata, count);
+ mutex_unlock(&sense_data_mutex);
+
+ return count;
+}
+
+static int dmard06_file_close(struct inode *inode, struct file *filp)
+{
+ dbg("close...\n");
+
+ return 0;
+}
+
+static void dmard06_platform_release(struct device *device)
+{
+ return;
+}
+
+
+static struct platform_device dmard06_device = {
+ .name = GSENSOR_NAME,
+ .id = 0,
+ .dev = {
+ .release = dmard06_platform_release,
+ },
+};
+
+static struct platform_driver dmard06_driver = {
+ .probe = dmard06_probe,
+ .remove = dmard06_remove,
+ .suspend = dmard06_i2c_suspend,
+ .resume = dmard06_i2c_resume,
+ .driver = {
+ .name = GSENSOR_NAME,
+ },
+};
+
+static int dmard06_i2c_xyz_write_reg(u8* index ,u8 *buffer, int length)
+{
+ /*int ret = 0;
+ u8 buf[MAX_WR_DMARD06_LEN];
+ struct i2c_msg msg[1];
+
+ buf[0] = *index;
+ memcpy(buf+1, buffer, length);
+ msg[0].addr = DMARD06_I2C_ADDR;
+ msg[0].flags = 0 ;
+ msg[0].flags &= ~(I2C_M_RD);
+ msg[0].len = length+1;
+ msg[0].buf = buf;
+ if ((ret = wmt_i2c_xfer_continue_if_4(msg,1,0)) <= 0)
+ {
+ errlog("write error!\n");
+ }
+ return ret;*/
+ return i2c_api_do_send(0, DMARD06_I2C_ADDR, index, buffer, length);
+}
+
+static int dmard06_i2c_xyz_read_reg(u8* index ,u8 *buffer, int length)
+{
+ /*int ret = 0;
+
+ struct i2c_msg msg[] =
+ {
+ {.addr = DMARD06_I2C_ADDR, .flags = 0, .len = 1, .buf = index,},
+ {.addr = DMARD06_I2C_ADDR, .flags = I2C_M_RD, .len = length, .buf = buffer,},
+ };
+ ret = wmt_i2c_xfer_continue_if_4(msg, 2,0);
+ if (ret <= 0)
+ {
+ errlog("read error!\n");
+ }
+ return ret;*/
+ return i2c_api_do_recv(0, DMARD06_I2C_ADDR, index, buffer, length);
+}
+
+static void dmard06_i2c_read_xyz(s8 *x, s8 *y, s8 *z)
+{
+
+ u8 buffer[3];
+ //buffer[0] = 0x41;
+ u8 index = 0x41;
+
+ dmard06_i2c_xyz_read_reg(&index, buffer, 3);
+ *x = (s8)buffer[0];
+ *y = (s8)buffer[1];
+ *z = (s8)buffer[2];
+ dmard06_i2c_accel_value(x);
+ dmard06_i2c_accel_value(y);
+ dmard06_i2c_accel_value(z);
+ if (ABS_X == l_sensorconfig.xyz_axis[0][0])
+ {
+ *x = l_sensorconfig.xyz_axis[0][1]*(*x);
+ *y = l_sensorconfig.xyz_axis[1][1]*(*y);
+ } else {
+ *x = l_sensorconfig.xyz_axis[0][1]*(*y);
+ *y = l_sensorconfig.xyz_axis[1][1]*(*x);
+ }
+ *z = l_sensorconfig.xyz_axis[2][1]*(*z);
+
+ dbg("dmrd06:x=%x,y=%x,z=%x\n", *x, *y, *z);
+}
+
+static void dmard06_i2c_accel_value(s8 *val)
+{
+ *val >>= 1;
+}
+
+static int dmard06_CalOffset(int side)
+{
+ u8 buffer[3];
+ //buffer[0] = 0x41;
+ u8 index = 0x41;
+ s8 x,y,z;
+
+ //mutex_lock(&sense_data_mutex);
+ //read data
+ dmard06_i2c_xyz_read_reg(&index, buffer, 3);
+ //mutex_unlock(&sense_data_mutex);
+ // check whether it's valid
+ // report the data
+ x = (s8)buffer[0];
+ y = (s8)buffer[1];
+ z = (s8)buffer[2];
+ dmard06_i2c_accel_value(&x);
+ dmard06_i2c_accel_value(&y);
+ dmard06_i2c_accel_value(&z);
+ l_sensorconfig.offset[0] = 0 - x*l_sensorconfig.xyz_axis[0][1];
+ l_sensorconfig.offset[1] = 0 - y*l_sensorconfig.xyz_axis[1][1];
+ l_sensorconfig.offset[2] = LSG - z*l_sensorconfig.xyz_axis[2][1];
+ return 0;
+
+}
+
+static int dmard06_i2c_suspend(struct platform_device *pdev, pm_message_t state)
+{
+ dbg("...\n");
+ cancel_delayed_work_sync(&l_sensorconfig.work);
+
+ return 0;
+}
+
+static int is_dmard06(void)
+{
+ int err = 0;
+ u8 cAddress = 0, cData = 0;
+ char buf[4];
+
+ cAddress = 0x53;
+ //i2c_master_send( client, (char*)&cAddress, 1);
+ //i2c_master_recv( client, (char*)&cData, 1);
+ if (dmard06_i2c_xyz_read_reg(&cAddress, &cData,1) <= 0)
+ {
+ errlog("Error to read SW_RESET register!\n");
+ }
+ dbg("i2c Read 0x53 = %x \n", cData);
+
+ cAddress = 0x0f;
+ //i2c_master_send( client, (char*)&cAddress, 1);
+ //i2c_master_recv( client, (char*)&cData, 1);
+ if (dmard06_i2c_xyz_read_reg(&cAddress, &cData,1) <= 0)
+ {
+ errlog("Can't find dmard06!\n");
+ return -1;
+ }
+ dbg("i2c Read 0x0f = %d \n", cData);
+
+ if(( cData&0x00FF) == 0x0006)
+ {
+ klog("Find DMARD06!\n");
+ }
+ else
+ {
+ errlog("ID isn't 0x06.(0x%x) !\n",cData);
+ return -1;
+ }
+
+ return 0;
+}
+
+static int dmard06_i2c_remove(void)
+{
+
+ return 0;
+}
+
+static int dmard06_i2c_resume(struct platform_device *pdev)
+{
+ dbg("...\n");
+ queue_delayed_work(l_sensorconfig.queue, &l_sensorconfig.work, msecs_to_jiffies(sample_rate_2_memsec(l_sensorconfig.sensor_samp)));
+
+
+ return 0;
+}
+
+static int sensor_writeproc( struct file *file,
+ const char *buffer,
+ unsigned long count,
+ void *data )
+{
+
+ int inputval = -1;
+ int enable, sample = -1;
+ char tembuf[8];
+ unsigned int amsr = 0;
+ int test = 0;
+
+ mutex_lock(&sense_data_mutex);
+ memset(tembuf, 0, sizeof(tembuf));
+ // get sensor level and set sensor level
+ if (sscanf(buffer, "isdbg=%d\n", &l_sensorconfig.isdbg))
+ {
+ // only set the dbg flag
+ } else if (sscanf(buffer, "samp=%d\n", &sample))
+ {
+ if (sample > 0)
+ {
+ if (sample != l_sensorconfig.sensor_samp)
+ {
+ }
+ //printk(KERN_ALERT "sensor samp=%d(amsr:%d) has been set.\n", sample, amsr);
+ } else {
+ printk(KERN_ALERT "Wrong sample argumnet of sensor.\n");
+ }
+ } else if (sscanf(buffer, "enable=%d\n", &enable))
+ {
+ if ((enable < 0) || (enable > 1))
+ {
+ printk(KERN_ERR "The argument to enable/disable g-sensor should be 0 or 1 !!!\n");
+ } else if (enable != l_sensorconfig.sensor_enable)
+ {
+ //mma_enable_disable(enable);
+ l_sensorconfig.sensor_enable = enable;
+ }
+ } else if (sscanf(buffer, "sensor_test=%d\n", &test))
+ { // for test begin
+ l_sensorconfig.test_pass = 0;
+ } else if (sscanf(buffer, "sensor_testend=%d\n", &test))
+ { // Don nothing only to be compatible the before testing program
+ }
+ mutex_unlock(&sense_data_mutex);
+ return count;
+}
+
+static int sensor_readproc(char *page, char **start, off_t off,
+ int count, int *eof, void *data)
+{
+ int len = 0;
+
+ len = sprintf(page,
+ "test_pass=%d\nisdbg=%d\nrate=%d\nenable=%d\n",
+ l_sensorconfig.test_pass,
+ l_sensorconfig.isdbg,
+ l_sensorconfig.sensor_samp,
+ l_sensorconfig.sensor_enable
+ );
+ return len;
+}
+
+
+extern int wmt_getsyspara(char *varname, unsigned char *varval, int *varlen);
+static int get_axisset(void* param)
+{
+ char varbuf[64];
+ int n;
+ int varlen;
+
+ memset(varbuf, 0, sizeof(varbuf));
+ varlen = sizeof(varbuf);
+ if (wmt_getsyspara("wmt.io.d06sensor", varbuf, &varlen)) {
+ printk(KERN_DEBUG "Can't get gsensor config in u-boot!!!!\n");
+ return -1;
+ } else {
+ n = sscanf(varbuf, "%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d",
+ &l_sensorconfig.op,
+ &l_sensorconfig.int_gpio,
+ &l_sensorconfig.samp,
+ &(l_sensorconfig.xyz_axis[0][0]),
+ &(l_sensorconfig.xyz_axis[0][1]),
+ &(l_sensorconfig.xyz_axis[1][0]),
+ &(l_sensorconfig.xyz_axis[1][1]),
+ &(l_sensorconfig.xyz_axis[2][0]),
+ &(l_sensorconfig.xyz_axis[2][1]),
+ &l_sensorconfig.offset[0],
+ &l_sensorconfig.offset[1],
+ &l_sensorconfig.offset[2]);
+ if (n != 12) {
+ printk(KERN_ERR "gsensor format is error in u-boot!!!\n");
+ return -1;
+ }
+ l_sensorconfig.sensor_samp = l_sensorconfig.samp;
+
+ dbg("get the sensor config: %d:%d:%d:%d:%d:%d:%d:%d:%d\n",
+ l_sensorconfig.op,
+ l_sensorconfig.int_gpio,
+ l_sensorconfig.samp,
+ l_sensorconfig.xyz_axis[0][0],
+ l_sensorconfig.xyz_axis[0][1],
+ l_sensorconfig.xyz_axis[1][0],
+ l_sensorconfig.xyz_axis[1][1],
+ l_sensorconfig.xyz_axis[2][0],
+ l_sensorconfig.xyz_axis[2][1]
+ );
+ }
+ return 0;
+}
+
+// To contol the g-sensor for UI
+static int mmad_open(struct inode *inode, struct file *file)
+{
+ dbg("Open the g-sensor node...\n");
+ return 0;
+}
+
+static int mmad_release(struct inode *inode, struct file *file)
+{
+ dbg("Close the g-sensor node...\n");
+ return 0;
+}
+
+
+static int
+mmad_ioctl(/*struct inode *inode,*/ struct file *file, unsigned int cmd,
+ unsigned long arg)
+{
+ void __user *argp = (void __user *)arg;
+ char rwbuf[5];
+ short delay, enable, amsr = -1;
+ unsigned int sample;
+ int ret = 0;
+ int side;
+ char varbuff[80];
+ unsigned int uval = 0;
+
+ dbg("g-sensor ioctr...\n");
+ memset(rwbuf, 0, sizeof(rwbuf));
+ mutex_lock(&sense_data_mutex);
+ switch (cmd) {
+ case ECS_IOCTL_APP_SET_DELAY:
+ // set the rate of g-sensor
+ if (copy_from_user(&delay, argp, sizeof(short)))
+ {
+ printk(KERN_ALERT "Can't get set delay!!!\n");
+ ret = -EFAULT;
+ goto errioctl;
+ }
+ klog("set delay=%d \n", delay);
+ //klog("before change sensor sample:%d...\n", l_sensorconfig.sensor_samp);
+ if ((delay >=0) && (delay < 20))
+ {
+ delay = 20;
+ } else if (delay > 200)
+ {
+ delay = 200;
+ }
+ if (delay > 0)
+ {
+ l_sensorconfig.sensor_samp = 1000/delay;
+ } else {
+ errlog("error delay argument(delay=%d)!!!\n",delay);
+ ret = -EFAULT;
+ goto errioctl;
+ }
+ break;
+ case ECS_IOCTL_APP_SET_AFLAG:
+ // enable/disable sensor
+ if (copy_from_user(&enable, argp, sizeof(short)))
+ {
+ printk(KERN_ERR "Can't get enable flag!!!\n");
+ ret = -EFAULT;
+ goto errioctl;
+ }
+ if ((enable >=0) && (enable <=1))
+ {
+ dbg("driver: disable/enable(%d) gsensor.\n", enable);
+
+ if (enable != l_sensorconfig.sensor_enable)
+ {
+ //mma_enable_disable(enable);
+ /*if (enable != 0)
+ {
+ queue_delayed_work(l_sensorconfig.queue, &l_sensorconfig.work, msecs_to_jiffies(sample_rate_2_memsec(l_sensorconfig.sensor_samp)));
+ } else {
+ cancel_delayed_work_sync(&l_sensorconfig.work);
+ flush_workqueue(l_sensorconfig.queue);
+ }*/
+ l_sensorconfig.sensor_enable = enable;
+
+ }
+ } else {
+ printk(KERN_ERR "Wrong enable argument in %s !!!\n", __FUNCTION__);
+ ret = -EFAULT;
+ goto errioctl;
+ }
+ break;
+ case WMT_IOCTL_SENSOR_GET_DRVID:
+ uval = DMARD06_DRVID;
+ if (copy_to_user((unsigned int*)arg, &uval, sizeof(unsigned int)))
+ {
+ ret = -EFAULT;
+ goto errioctl;
+ }
+ dbg("dmard06_driver_id:%d\n",uval);
+ break;
+ case WMT_IOCTL_SENSOR_CAL_OFFSET:
+ klog("-->WMT_IOCTL_SENSOR_CAL_OFFSET\n");
+ if(copy_from_user(&side, (int*)argp, sizeof(int)))
+ {
+ ret = -EFAULT;
+ goto errioctl;
+ }
+ dbg("side=%d\n",side);
+ if (dmard06_CalOffset(side) != 0)
+ {
+ ret = -EFAULT;
+ goto errioctl;
+ }
+ // save the param
+ sprintf(varbuff, "%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d",
+ l_sensorconfig.op,
+ l_sensorconfig.int_gpio,
+ 10,//l_sensorconfig.samp,
+ (l_sensorconfig.xyz_axis[0][0]),
+ (l_sensorconfig.xyz_axis[0][1]),
+ (l_sensorconfig.xyz_axis[1][0]),
+ (l_sensorconfig.xyz_axis[1][1]),
+ (l_sensorconfig.xyz_axis[2][0]),
+ (l_sensorconfig.xyz_axis[2][1]),
+ l_sensorconfig.offset[0],
+ l_sensorconfig.offset[1],
+ l_sensorconfig.offset[2]
+ );
+ wmt_setsyspara(GSENDMARD06_UBOOT_NAME, varbuff);
+ ret = 0;
+ break;
+ default:
+ break;
+ }
+
+
+ /*switch (cmd) {
+ case ECS_IOCTL_READ:
+ if (copy_to_user(argp, &rwbuf, sizeof(rwbuf)))
+ return -EFAULT;
+ break;
+ default:
+ break;
+ }*/
+errioctl:
+ mutex_unlock(&sense_data_mutex);
+ return ret;
+}
+
+
+static struct file_operations mmad_fops = {
+ .owner = THIS_MODULE,
+ .open = mmad_open,
+ .release = mmad_release,
+ .unlocked_ioctl = mmad_ioctl,
+};
+
+
+static struct miscdevice mmad_device = {
+ .minor = MISC_DYNAMIC_MINOR,
+ .name = "sensor_ctrl",
+ .fops = &mmad_fops,
+};
+
+static int dmard06_probe(
+ struct platform_device *pdev)
+{
+ int err = 0;
+
+ //register ctrl dev
+ err = misc_register(&mmad_device);
+ if (err != 0)
+ {
+ errlog("Can't register mma_device!\n");
+ return -1;
+ }
+ // register rd/wr proc
+ l_sensorconfig.sensor_proc = create_proc_entry(GSENSOR_PROC_NAME, 0666, NULL/*&proc_root*/);
+ if (l_sensorconfig.sensor_proc != NULL)
+ {
+ l_sensorconfig.sensor_proc->write_proc = sensor_writeproc;
+ l_sensorconfig.sensor_proc->read_proc = sensor_readproc;
+ }
+ // init work queue
+ l_sensorconfig.queue = create_singlethread_workqueue("sensor-data-report");
+ //INIT_WORK(&l_sensorconfig.work, mma_work_func);
+ INIT_DELAYED_WORK(&l_sensorconfig.work, dmard06_work_func);
+ mutex_init(&sense_data_mutex);
+ l_sensorconfig.input_dev = input_allocate_device();
+ if (!l_sensorconfig.input_dev) {
+ err = -ENOMEM;
+ errlog("Failed to allocate input device\n");
+ goto exit_input_dev_alloc_failed;
+ }
+ //set_bit(EV_KEY, l_sensorconfig.input_dev->evbit);
+ //set_bit(EV_ABS, l_sensorconfig.input_dev->evbit);
+ l_sensorconfig.input_dev->evbit[0] = BIT(EV_ABS) | BIT_MASK(EV_KEY);
+ //set_bit(KEY_NEXTSONG, l_sensorconfig.input_dev->keybit);
+
+ /* yaw */
+ //input_set_abs_params(l_sensorconfig.input_dev, ABS_RX, 0, 360*100, 0, 0);
+ /* pitch */
+ //input_set_abs_params(l_sensorconfig.input_dev, ABS_RY, -180*100, 180*100, 0, 0);
+ /* roll */
+ //input_set_abs_params(l_sensorconfig.input_dev, ABS_RZ, -90*100, 90*100, 0, 0);
+ /* x-axis acceleration */
+ input_set_abs_params(l_sensorconfig.input_dev, ABS_X, -128, 128, 0, 0);
+ /* y-axis acceleration */
+ input_set_abs_params(l_sensorconfig.input_dev, ABS_Y, -128, 128, 0, 0);
+ /* z-axis acceleration */
+ input_set_abs_params(l_sensorconfig.input_dev, ABS_Z, -128, 128, 0, 0);
+
+ l_sensorconfig.input_dev->name = "g-sensor";
+
+ err = input_register_device(l_sensorconfig.input_dev);
+
+ if (err) {
+ errlog("Unable to register input device: %s\n",
+ l_sensorconfig.input_dev->name);
+ goto exit_input_register_device_failed;
+ }
+
+ return 0;
+exit_input_register_device_failed:
+ input_free_device(l_sensorconfig.input_dev);
+exit_input_dev_alloc_failed:
+ // release proc
+ remove_proc_entry(GSENSOR_PROC_NAME, NULL);
+ l_sensorconfig.sensor_proc = NULL;
+ // unregister the ctrl dev
+ misc_deregister(&mmad_device);
+ return err;
+}
+
+static int dmard06_remove(struct platform_device *pdev)
+{
+ if (NULL != l_sensorconfig.queue)
+ {
+ cancel_delayed_work_sync(&l_sensorconfig.work);
+ flush_workqueue(l_sensorconfig.queue);
+ destroy_workqueue(l_sensorconfig.queue);
+ l_sensorconfig.queue = NULL;
+ }
+ if (l_sensorconfig.sensor_proc != NULL)
+ {
+ remove_proc_entry(GSENSOR_PROC_NAME, NULL);
+ l_sensorconfig.sensor_proc = NULL;
+ }
+ misc_deregister(&mmad_device);
+ return 0;
+}
+#if 0
+static void dmard06_early_suspend(struct early_suspend *h)
+{
+ dbg("start\n");
+ cancel_delayed_work_sync(&l_sensorconfig.work);
+ dbg("exit\n");
+}
+
+static void dmard06_late_resume(struct early_suspend *h)
+{
+ dbg("start\n");
+ // init
+ queue_delayed_work(l_sensorconfig.queue, &l_sensorconfig.work, msecs_to_jiffies(sample_rate_2_memsec(l_sensorconfig.sensor_samp)));
+ dbg("exit\n");
+}
+#endif
+
+static int __init dmard06_init(void)
+{
+ int ret = 0;
+
+ // detech the device
+ if (is_dmard06() != 0)
+ {
+ return -1;
+ }
+ // parse g-sensor u-boot arg
+ ret = get_axisset(NULL);
+ if (ret < 0)
+ {
+ printk("<<<<<%s user choose to no sensor chip!\n", __func__);
+ return ret;
+ }
+ /*if ((ret != 0) || !l_sensorconfig.op)
+ return -EINVAL;
+ */
+
+ // Create device node
+ if (register_chrdev (GSENSOR_MAJOR, GSENSOR_NAME, &dmard06_fops)) {
+ printk (KERN_ERR "unable to get major %d\n", GSENSOR_MAJOR);
+ return -EIO;
+ }
+
+ l_dev_class = class_create(THIS_MODULE, GSENSOR_NAME);
+ if (IS_ERR(l_dev_class)){
+ ret = PTR_ERR(l_dev_class);
+ printk(KERN_ERR "Can't class_create gsensor device !!\n");
+ return ret;
+ }
+ l_clsdevice = device_create(l_dev_class, NULL, MKDEV(GSENSOR_MAJOR, 0), NULL, GSENSOR_NAME);
+ if (IS_ERR(l_clsdevice)){
+ ret = PTR_ERR(l_clsdevice);
+ printk(KERN_ERR "Failed to create device %s !!!",GSENSOR_NAME);
+ return ret;
+ }
+ INIT_WORK(&poll_work, dmard06_work_func);
+
+
+ if((ret = platform_device_register(&dmard06_device)))
+ {
+ printk(KERN_ERR "%s Can't register mma7660 platform devcie!!!\n", __FUNCTION__);
+ return ret;
+ }
+ if ((ret = platform_driver_register(&dmard06_driver)) != 0)
+ {
+ printk(KERN_ERR "%s Can't register mma7660 platform driver!!!\n", __FUNCTION__);
+ return ret;
+ }
+#ifdef CONFIG_HAS_EARLYSUSPEND
+ l_sensorconfig.earlysuspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1;
+ l_sensorconfig.earlysuspend.suspend = dmard06_early_suspend;
+ l_sensorconfig.earlysuspend.resume = dmard06_late_resume;
+ register_early_suspend(&l_sensorconfig.earlysuspend);
+#endif
+
+ klog("dmard06 g-sensor driver load!\n");
+ queue_delayed_work(l_sensorconfig.queue, &l_sensorconfig.work, msecs_to_jiffies(sample_rate_2_memsec(l_sensorconfig.sensor_samp)));
+
+ return 0;
+}
+
+static void __exit dmard06_exit(void)
+{
+ //unregister_early_suspend(&l_sensorconfig.earlysuspend);
+ platform_driver_unregister(&dmard06_driver);
+ platform_device_unregister(&dmard06_device);
+ device_destroy(l_dev_class, MKDEV(GSENSOR_MAJOR, 0));
+ unregister_chrdev(GSENSOR_MAJOR, GSENSOR_NAME);
+ class_destroy(l_dev_class);
+
+}
+
+MODULE_AUTHOR("DMT_RD");
+MODULE_DESCRIPTION("DMARD06 g-sensor Driver");
+MODULE_LICENSE("GPL");
+
+module_init(dmard06_init);
+module_exit(dmard06_exit);
diff --git a/ANDROID_3.4.5/drivers/input/sensor/dmard08_gsensor/Makefile b/ANDROID_3.4.5/drivers/input/sensor/dmard08_gsensor/Makefile
new file mode 100755
index 00000000..82f27563
--- /dev/null
+++ b/ANDROID_3.4.5/drivers/input/sensor/dmard08_gsensor/Makefile
@@ -0,0 +1,34 @@
+KERNELDIR=../../../../
+#KERNELDIR=/home/hangyan/android8850/kernel/ANDROID_3.0.8
+CROSS = arm_1103_le-
+CC= $(CROSS)gcc
+LD= $(CROSS)ld
+STRIP = $(CROSS)strip
+
+DEBUG = n
+
+# Add your debugging flag (or not) to EXTRA_CFLAGS
+ifeq ($(DEBUG),y)
+# DEBFLAGS = -O -g -DSCULL_DEBUG # "-O" is needed to expand inlines
+DEBFLAGS = -O0 -g -DSCULL_DEBUG # "-O" is needed to expand inlines
+
+else
+ DEBFLAGS = -O2 -Wall
+endif
+
+EXTRA_CFLAGS += $(DEBFLAGS)
+
+
+MY_MODULE_NAME=s_wmt_gsensor_dmard08
+
+obj-m := $(MY_MODULE_NAME).o
+$(MY_MODULE_NAME)-objs := dmard08.o cyclequeue.o
+
+default:
+ $(MAKE) -C $(KERNELDIR) SUBDIRS=$(PWD) modules
+ $(STRIP) --strip-debug $(MY_MODULE_NAME).ko
+ rm -rf *.o *~ core .depend .*.cmd *.mod.c .tmp_versions
+
+clean:
+ rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions *.order *.symvers
+
diff --git a/ANDROID_3.4.5/drivers/input/sensor/dmard08_gsensor/cyclequeue.c b/ANDROID_3.4.5/drivers/input/sensor/dmard08_gsensor/cyclequeue.c
new file mode 100755
index 00000000..4d6b97cd
--- /dev/null
+++ b/ANDROID_3.4.5/drivers/input/sensor/dmard08_gsensor/cyclequeue.c
@@ -0,0 +1,68 @@
+#include
+
+
+#include "cyclequeue.h"
+
+static struct que_data que[QUEUE_LEN];
+static unsigned int head = -1; // point to the first valaid queue data
+static unsigned int tail = 0; // point to the next to the last valaid queue data
+static DEFINE_MUTEX(que_mutex);
+
+// Whether queue is full
+// return 1--full,0 -- no full
+int clque_is_full(void)
+{
+ int ret = 0;
+
+ mutex_lock(&que_mutex);
+ ret = ((tail+1)%QUEUE_LEN) == head ? 1 : 0;
+ mutex_unlock(&que_mutex);
+ return ret;
+}
+
+// Whether queue is empty
+// return 1--empty,0--no empty
+int clque_is_empty(void)
+{
+ int ret = 0;
+
+ mutex_lock(&que_mutex);
+ ret = (tail == head) ? 1: 0;
+ mutex_unlock(&que_mutex);
+ return ret;
+}
+
+// add to queue
+// return:0--successful,-1--queue is full
+int clque_in(struct que_data* data)
+{
+ /*if (clque_is_full())
+ {
+ return -1;
+ }*/
+ mutex_lock(&que_mutex);
+ que[tail].data[0] = data->data[0];
+ que[tail].data[1] = data->data[1];
+ que[tail].data[2] = data->data[2];
+ tail = (tail+1)%QUEUE_LEN;
+ mutex_unlock(&que_mutex);
+ return 0;
+}
+
+// out to queue
+// return:0--successful,-1--queue is empty
+int clque_out(struct que_data* data)
+{
+ /*if (clque_is_empty())
+ {
+ return -1;
+ }*/
+ mutex_lock(&que_mutex);
+ data->data[0]= que[head].data[0];
+ data->data[1]= que[head].data[1];
+ data->data[2]= que[head].data[2];
+ head = (head+1)%QUEUE_LEN;
+ mutex_unlock(&que_mutex);
+ return 0;
+}
+
diff --git a/ANDROID_3.4.5/drivers/input/sensor/dmard08_gsensor/cyclequeue.h b/ANDROID_3.4.5/drivers/input/sensor/dmard08_gsensor/cyclequeue.h
new file mode 100755
index 00000000..52b9996f
--- /dev/null
+++ b/ANDROID_3.4.5/drivers/input/sensor/dmard08_gsensor/cyclequeue.h
@@ -0,0 +1,18 @@
+#ifndef __CYCLEQUEUE_163704111637_H
+#define __CYCLEQUEUE_163704111637_H
+
+#define DATA_TYPE short
+#define QUEUE_LEN 16
+
+struct que_data {
+ DATA_TYPE data[3];
+};
+
+extern int clque_in(struct que_data* data);
+extern int clque_out(struct que_data* data);
+extern int clque_is_full(void);
+extern int clque_is_empty(void);
+#endif
+
+
+
diff --git a/ANDROID_3.4.5/drivers/input/sensor/dmard08_gsensor/dmard08.c b/ANDROID_3.4.5/drivers/input/sensor/dmard08_gsensor/dmard08.c
new file mode 100755
index 00000000..3cbe2ac7
--- /dev/null
+++ b/ANDROID_3.4.5/drivers/input/sensor/dmard08_gsensor/dmard08.c
@@ -0,0 +1,1019 @@
+/*
+ * @file drivers/i2c/dmard08.c
+ * @brief DMARD08 g-sensor Linux device driver
+ * @author Domintech Technology Co., Ltd (http://www.domintech.com.tw)
+ * @version 1.22
+ * @date 2011/12/01
+ *
+ * @section LICENSE
+ *
+ * Copyright 2011 Domintech Technology Co., Ltd
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ *
+ */
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+//#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+// ****Add by Steve Huang*********2011-11-18********
+#include
+#include "../sensor.h"
+//#include "cyclequeue.h"
+// ************************************************
+
+#define GSENSOR_I2C_NAME "dmard08"
+#define GSENSOR_I2C_ADDR 0x1c
+
+#define SENSOR_DATA_SIZE 3
+
+static struct i2c_client *this_client = NULL;
+static struct mutex sense_data_mutex;
+static struct class* l_dev_class = NULL;
+
+static struct wmt_gsensor_data l_sensorconfig = {
+ .op = 0,
+ .int_gpio = 3,
+ .samp = 5,
+ .xyz_axis = {
+ {ABS_X, -1},
+ {ABS_Y, 1},
+ {ABS_Z, -1},
+ },
+ .sensor_proc = NULL,
+ .isdbg = 0,
+ .sensor_samp = 10, // 1 sample/second
+ .sensor_enable = 1, // enable sensor
+ .test_pass = 0, // for test program
+ .offset={0,0,0},
+};
+
+
+// ****Add by Steve Huang*********2011-11-18********
+/*void gsensor_write_offset_to_file(void);
+void gsensor_read_offset_from_file(void);
+char OffsetFileName[] = "/data/misc/dmt/offset.txt";*/
+//**************************************************
+
+
+
+extern int wmt_getsyspara(char *varname, unsigned char *varval, int *varlen);
+
+/*static int dmard08_i2c_suspend(struct i2c_client *client, pm_message_t mesg);
+static int dmard08_i2c_resume(struct i2c_client *client);*/
+//static int __devinit dmard08_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id);
+//static int __devexit dmard08_i2c_remove(struct i2c_client *client);
+void dmard08_i2c_read_xyz(struct i2c_client *client, s16 *xyz);
+static inline void dmard08_i2c_correct_accel_sign(s16 *val); //check output is correct
+void dmard08_i2c_merge_register_values(struct i2c_client *client, s16 *val, u8 msb, u8 lsb); //merge the register values
+
+struct raw_data {
+ short x;
+ short y;
+ short z;
+};
+
+struct raw_data rdata;
+//static struct raw_data offset;
+
+struct dev_data
+{
+ dev_t devno;
+ struct cdev cdev;
+ struct class *class;
+ struct i2c_client *client;
+};
+//static struct dev_data dev;
+
+
+unsigned int sample_rate_2_memsec(unsigned int rate)
+{
+ return (1000/rate);
+}
+
+
+/*void gsensor_read_accel_avg(int num_avg, raw_data *avg_p) // marked by eason check again!!
+{
+ long xyz_acc[SENSOR_DATA_SIZE];
+ s16 xyz[SENSOR_DATA_SIZE];
+ int i, j;
+
+ //initialize the accumulation buffer
+ for(i = 0; i < SENSOR_DATA_SIZE; ++i)
+ xyz_acc[i] = 0;
+
+ for(i = 0; i < num_avg; i++)
+ {
+ device_i2c_read_xyz(l_sensorconfig.client, (s16 *)&xyz);
+ for(j = 0; j < SENSOR_DATA_SIZE; j++)
+ xyz_acc[j] += xyz[j];
+ }
+
+ // calculate averages
+ for(i = 0; i < SENSOR_DATA_SIZE; i++)
+ avg_p->v[i] = (s16) (xyz_acc[i] / num_avg);
+}*/
+
+/*void gsensor_calibrate(int side) //marked by eason check again
+{
+ raw_data avg;
+ int avg_num = 16;
+
+ //IN_FUNC_MSG;
+ // get acceleration average reading
+ gsensor_read_accel_avg(avg_num, &avg);
+ // calculate and set the offset
+ gsensor_calculate_offset(side, avg);
+}*/
+
+/*void ce_on(void) //marked by eason check again
+{
+ int gppdat;
+ gppdat = __raw_readl(S3C64XX_GPPDAT);
+ gppdat |= (1 << 0);
+
+ __raw_writel(gppdat,S3C64XX_GPPDAT);
+}
+
+void ce_off(void)
+{
+ int gppdat;
+ gppdat = __raw_readl(S3C64XX_GPPDAT);
+ gppdat &= ~(1 << 0);
+
+ __raw_writel(gppdat,S3C64XX_GPPDAT);
+}
+
+void config_ce_pin(void)
+{
+ unsigned int value;
+ //D08's CE (pin#12) is connected to S3C64XX AP processor's port P0
+ //Below codes set port P0 as digital output
+ value = readl(S3C64XX_GPPCON);
+ value &= ~ (0x3);
+ value |= 1 ; //Output =01 , Input = 00 , Ext. Interrupt = 10
+ writel(value, S3C64XX_GPPCON); //save S3C64XX_GPPCON change
+}
+
+void gsensor_reset(void)
+{
+ ce_off();
+ msleep(300);
+ ce_on();
+}*/
+
+/*void gsensor_set_offset(int val[3]) //marked by eason check again
+{
+ int i;
+ IN_FUNC_MSG;
+ for(i = 0; i < SENSOR_DATA_SIZE; ++i)
+ offset.v[i] = (s16) val[i];
+}*/
+
+/*
+static const struct i2c_device_id dmard08_i2c_ids[] =
+{
+ {GSENSOR_I2C_NAME, 0},
+ {}
+};
+
+MODULE_DEVICE_TABLE(i2c, dmard08_i2c_ids);
+
+
+static struct i2c_driver dmard08_i2c_driver =
+{
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = GSENSOR_I2C_NAME,
+ },
+ .class = I2C_CLASS_HWMON,
+ .probe = dmard08_i2c_probe,
+ .remove = __devexit_p(dmard08_i2c_remove),
+ //.suspend = dmard08_i2c_suspend,
+ //.resume = dmard08_i2c_resume,
+ .id_table = dmard08_i2c_ids,
+};
+*/
+
+static int dmard08_i2c_xyz_read_reg(struct i2c_client *client,u8 *buffer, int length) //OK
+{
+
+ struct i2c_msg msg[] =
+ {
+ {.addr = client->addr, .flags = 0, .len = 1, .buf = buffer,},
+ {.addr = client->addr, .flags = I2C_M_RD, .len = length, .buf = buffer,},
+ };
+ return i2c_transfer(client->adapter, msg, 2);
+}
+
+static int dmard08_i2c_xyz_write_reg(struct i2c_client *client,u8 *buffer, int length) //write reg OK
+{
+ struct i2c_msg msg[] =
+ {
+ {.addr = client->addr, .flags = 0, .len = length, .buf = buffer,},
+ };
+ return i2c_transfer(client->adapter, msg, 1);
+}
+
+//static void dmard08_i2c_read_xyz(struct i2c_client, s16 *x, s16 *y, s16 *z) //add by eason
+void dmard08_i2c_read_xyz(struct i2c_client *client, s16 *xyz_p)
+{
+// s16 xTmp,yTmp,zTmp; //added by eason
+ s16 xyzTmp[SENSOR_DATA_SIZE];
+ int i;
+/*get xyz high/low bytes, 0x02~0x07*/
+ u8 buffer[6];
+ buffer[0] = 0x2;
+ mutex_lock(&sense_data_mutex);
+ dmard08_i2c_xyz_read_reg(client, buffer, 6);
+ mutex_unlock(&sense_data_mutex);
+
+ //merge to 11-bits value
+ for(i = 0; i < SENSOR_DATA_SIZE; ++i){
+ dmard08_i2c_merge_register_values(client, (xyzTmp + i), buffer[2*i], buffer[2*i + 1]);
+ }
+ //transfer to the default layout
+ for(i = 0; i < SENSOR_DATA_SIZE; ++i)
+ {
+ xyz_p[i] = xyzTmp[i]; // add by eason
+/* xyz_p[i] = 0;
+ for(j = 0; j < 3; j++)
+ xyz_p[i] += sensorlayout[i][j] * xyzTmp[j]; */
+ }
+ dbg("%x,%x,%x,",xyz_p[0], xyz_p[1], xyz_p[2]);
+ //printk("@DMT@ dmard08_i2c_read_xyz: X-axis: %d ,Y-axis: %d ,Z-axis: %d\n", xyz_p[0], xyz_p[1], xyz_p[2]);
+}
+
+void dmard08_i2c_merge_register_values(struct i2c_client *client, s16 *val, u8 msb, u8 lsb)
+{
+
+ *val = (((u16)msb) << 3) | (u16)lsb;
+ dmard08_i2c_correct_accel_sign(val);
+}
+
+static inline void dmard08_i2c_correct_accel_sign(s16 *val)
+{
+
+ *val<<= (sizeof(s16) * BITS_PER_BYTE - 11);
+ *val>>= (sizeof(s16) * BITS_PER_BYTE - 11);
+}
+
+/*
+static int dmard08_i2c_suspend(struct i2c_client *client, pm_message_t mesg)
+{
+ dbg("...\n");
+ return 0;
+}
+*/
+
+//static int __devinit dmard08_i2c_probe(struct i2c_client *client,const struct i2c_device_id *id)
+static int __devinit dmard08_hw_init(struct i2c_client *client/*,const struct i2c_device_id *id*/)
+{
+ char cAddress = 0 , cData = 0;
+ u8 buffer[2];
+
+ //for(i = 0; i < SENSOR_DATA_SIZE; ++i) //marked by eason check again
+ // offset.v[i] = 0;
+
+
+ if(!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
+ {
+ dbg("I2C_FUNC_I2C not support\n");
+ return -1;
+ }
+ //config_ce_pin(); //how used?
+ //gsensor_reset(); //how used?
+ /* check SW RESET */
+ cAddress = 0x08;
+ i2c_master_send( client, (char*)&cAddress, 1);
+ i2c_master_recv( client, (char*)&cData, 1);
+ dbg( "i2c Read 0x08 = %d \n", cData);
+ if( cData == 0x00)
+ {
+ cAddress = 0x09;
+ i2c_master_send( client, (char*)&cAddress, 1);
+ i2c_master_recv( client, (char*)&cData, 1);
+ dbg( "i2c Read 0x09 = %d \n", cData);
+ if( cData == 0x00)
+ {
+ cAddress = 0x0a;
+ i2c_master_send( client, (char*)&cAddress, 1);
+ i2c_master_recv( client, (char*)&cData, 1);
+ dbg( "i2c Read 0x0a = %d \n", cData);
+ if( cData == 0x88)
+ {
+ cAddress = 0x0b;
+ i2c_master_send( client, (char*)&cAddress, 1);
+ i2c_master_recv( client, (char*)&cData, 1);
+ dbg( "i2c Read 0x0b = %d \n", cData);
+ if( cData == 0x08)
+ {
+ dbg( "DMT_DEVICE_NAME registered I2C driver!\n");
+ l_sensorconfig.client = client;
+ }
+ else
+ {
+ dbg( "err : i2c Read 0x0B = %d!\n",cData);
+ l_sensorconfig.client = NULL;
+ return -1;
+ }
+ }
+ else
+ {
+ dbg( "err : i2c Read 0x0A = %d!\n",cData);
+ l_sensorconfig.client = NULL;
+ return -1;
+ }
+ }
+ else
+ {
+ dbg( "err : i2c Read 0x09 = %d!\n",cData);
+ l_sensorconfig.client = NULL;
+ return -1;
+ }
+ }
+ else
+ {
+ dbg( "err : i2c Read 0x08 = %d!\n",cData);
+ l_sensorconfig.client = NULL;
+
+ return -1;
+ }
+
+ /* set sampling period if samp = 1, set the sampling frequency = 684
+ otherwise set the sample frequency = 342 (default) added by eason 2012/3/7*/
+ if (l_sensorconfig.samp == 1) {
+ buffer[0] = 0x08;
+ buffer[1] = 0x04;
+ dmard08_i2c_xyz_write_reg(client, buffer, 2);
+ }
+
+ /*check sensorlayout[i][j] //eason
+ for(i = 0; i < 3; ++i)
+ {
+ for(j = 0; j < 3; j++)
+ printk("%d",sensorlayout[i][j]);
+ printk("\n");
+ } */
+
+ return 0;
+}
+
+static int __devexit dmard08_i2c_remove(struct i2c_client *client) //OK
+{
+ dbg("...\n");
+
+ return 0;
+}
+
+/*
+static int dmard08_i2c_resume(struct i2c_client *client) //OK
+{
+ dbg("...\n");
+
+ return 0;
+}
+*/
+static int get_axisset(void)
+{
+ char varbuf[64];
+ int n;
+ int varlen;
+
+ memset(varbuf, 0, sizeof(varbuf));
+ varlen = sizeof(varbuf);
+ if (wmt_getsyspara("wmt.io.dm08sensor", varbuf, &varlen)) {
+ errlog("Can't get gsensor config in u-boot!!!!\n");
+ return -1;
+ } else {
+ n = sscanf(varbuf, "%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d",
+ &l_sensorconfig.op,
+ &l_sensorconfig.int_gpio,
+ &l_sensorconfig.samp,
+ &(l_sensorconfig.xyz_axis[0][0]),
+ &(l_sensorconfig.xyz_axis[0][1]),
+ &(l_sensorconfig.xyz_axis[1][0]),
+ &(l_sensorconfig.xyz_axis[1][1]),
+ &(l_sensorconfig.xyz_axis[2][0]),
+ &(l_sensorconfig.xyz_axis[2][1]),
+ &(l_sensorconfig.offset[0]),
+ &(l_sensorconfig.offset[1]),
+ &(l_sensorconfig.offset[2])
+ );
+ if (n != 12) {
+ errlog("gsensor format is error in u-boot!!!\n");
+ return -1;
+ }
+ l_sensorconfig.sensor_samp = l_sensorconfig.samp;
+
+ dbg("get the sensor config: %d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d:%d\n",
+ l_sensorconfig.op,
+ l_sensorconfig.int_gpio,
+ l_sensorconfig.samp,
+ l_sensorconfig.xyz_axis[0][0],
+ l_sensorconfig.xyz_axis[0][1],
+ l_sensorconfig.xyz_axis[1][0],
+ l_sensorconfig.xyz_axis[1][1],
+ l_sensorconfig.xyz_axis[2][0],
+ l_sensorconfig.xyz_axis[2][1],
+ l_sensorconfig.offset[0],
+ l_sensorconfig.offset[1],
+ l_sensorconfig.offset[2]
+ );
+ }
+ return 0;
+}
+
+static void dmard08_platform_release(struct device *device)
+{
+ dbg("...\n");
+ return;
+}
+
+
+static struct platform_device dmard08_device = {
+ .name = GSENSOR_I2C_NAME,
+ .id = 0,
+ .dev = {
+ .release = dmard08_platform_release,
+ },
+};
+
+static int dmard08_suspend(struct platform_device *pdev, pm_message_t state)
+{
+ dbg("...\n");
+ cancel_delayed_work_sync(&l_sensorconfig.work);
+
+ return 0;
+}
+
+
+static int dmard08_open(struct inode *node, struct file *fle)
+{
+ dbg("open...\n");
+ return 0;
+}
+
+/* release command for dmard08 device file */
+static int dmard08_close(struct inode *node, struct file *fle)
+{
+ dbg("close...\n");
+ return 0;
+}
+
+/* ioctl command for dmard08 device file */
+static long dmard08_ioctl(/*struct inode *inode,*/ struct file *file, unsigned int cmd, unsigned long arg)
+{
+ int err = 0;
+ //unsigned char data[6];
+ short delay = 0;
+ short enable = 0;
+ unsigned int uval = 0;
+
+ if (WMT_IOCTL_SENSOR_CAL_OFFSET == cmd)
+ {
+ return 0;// now do nothing
+ }
+
+ /* cmd mapping */
+ mutex_lock(&sense_data_mutex);
+ switch(cmd)
+ {
+
+ case ECS_IOCTL_APP_SET_DELAY:
+ // set the rate of g-sensor
+ dbg("ECS_IOCTL_APP_SET_DELAY\n");
+ if (copy_from_user(&delay,(short*)arg, sizeof(short)))
+ {
+ errlog("Can't get set delay!!!\n");
+ err = -EFAULT;
+ goto errioctl;
+ }
+ klog("set delay=%d \n", delay);
+ //klog("before change sensor sample:%d...\n", l_sensorconfig.sensor_samp);
+ if ((delay >=0) && (delay < 20))
+ {
+ delay = 20;
+ } else if (delay > 200)
+ {
+ delay = 200;
+ }
+ if (delay > 0)
+ {
+ l_sensorconfig.sensor_samp = 1000/delay;
+ } else {
+ errlog("error delay argument(delay=%d)!!!\n",delay);
+ err = -EFAULT;
+ goto errioctl;
+ }
+ break;
+ case ECS_IOCTL_APP_SET_AFLAG:
+ dbg("ECS_IOCTL_APP_SET_AFLAG\n");
+ // enable/disable sensor
+ if (copy_from_user(&enable, (short*)arg, sizeof(short)))
+ {
+ errlog("Can't get enable flag!!!\n");
+ err = -EFAULT;
+ goto errioctl;
+ }
+ if ((enable >=0) && (enable <=1))
+ {
+ dbg("driver: disable/enable(%d) gsensor.\n", enable);
+
+ if (enable != l_sensorconfig.sensor_enable)
+ {
+ // do sth ???
+ //mma_enable_disable(enable);
+ /*if (enable != 0)
+ {
+ queue_delayed_work(l_sensorconfig.queue, &l_sensorconfig.work, msecs_to_jiffies(sample_rate_2_memsec(l_sensorconfig.sensor_samp)));
+ } else {
+ cancel_delayed_work_sync(&l_sensorconfig.work);
+ flush_workqueue(l_sensorconfig.queue);
+ }*/
+ l_sensorconfig.sensor_enable = enable;
+
+ }
+ } else {
+ errlog("Wrong enable argument!!!\n");
+ err = -EFAULT;
+ goto errioctl;
+ }
+ break;
+ case WMT_IOCTL_SENSOR_GET_DRVID:
+ uval = DMARD08_DRVID;
+ if (copy_to_user((unsigned int*)arg, &uval, sizeof(unsigned int)))
+ {
+ return -EFAULT;
+ }
+ dbg("dmard08_driver_id:%d\n",uval);
+ break;
+ default:
+ break;
+ }
+errioctl:
+ mutex_unlock(&sense_data_mutex);
+ return err;
+}
+
+/*
+static ssize_t dmard08_read(struct file *file, char __user *buf, size_t count, loff_t *offset)
+{
+ struct que_data data;
+ short xyz_temp[3];
+
+ // read data from cycle queue
+ while (clque_is_empty()) msleep(10);
+ clque_out(&data);
+ xyz_temp[0] = data.data[0];
+ xyz_temp[1] = data.data[1];
+ xyz_temp[2] = data.data[2];
+
+
+ if(copy_to_user(buf, &xyz_temp, sizeof(xyz_temp)))
+ return -EFAULT;
+ dbg("x=%x,y=%x,z=%x\n",xyz_temp[0], xyz_temp[1], xyz_temp[2]);
+ return sizeof(xyz_temp);
+}
+*/
+/*
+static ssize_t dmard08_write(struct file *file, const char __user *buf, size_t count, loff_t *offset)
+{
+ dbg("write...\n");
+ return 0;
+}
+*/
+
+static const struct file_operations d08_fops = {
+ .owner = THIS_MODULE,
+ .open = dmard08_open,
+ .release = dmard08_close,
+ //.read = dmard08_read,
+ //.wirte = dmard08_write,
+ .unlocked_ioctl = dmard08_ioctl,
+};
+
+static struct miscdevice d08_device = {
+ .minor = MISC_DYNAMIC_MINOR,
+ .name = GSENSOR_DEV_NODE,
+ .fops = &d08_fops,
+};
+
+
+static int dmard08_resume(struct platform_device *pdev)
+{
+ char buffer[2];
+ dbg("...\n");
+
+ if (l_sensorconfig.samp == 1) {
+ buffer[0] = 0x08;
+ buffer[1] = 0x04;
+ dmard08_i2c_xyz_write_reg(l_sensorconfig.client, buffer, 2);
+ }
+
+ queue_delayed_work(l_sensorconfig.queue, &l_sensorconfig.work, msecs_to_jiffies(sample_rate_2_memsec(l_sensorconfig.sensor_samp)));
+ return 0;
+}
+
+static int sensor_writeproc( struct file *file,
+ const char *buffer,
+ unsigned long count,
+ void *data )
+{
+
+ //int inputval = -1;
+ int enable, sample = -1;
+ char tembuf[8];
+ //unsigned int amsr = 0;
+ int test = 0;
+
+ mutex_lock(&sense_data_mutex);
+ memset(tembuf, 0, sizeof(tembuf));
+ // get sensor level and set sensor level
+ if (sscanf(buffer, "isdbg=%d\n", &l_sensorconfig.isdbg))
+ {
+ // only set the dbg flag
+ } else if (sscanf(buffer, "samp=%d\n", &sample))
+ {
+ if (sample > 0)
+ {
+ if (sample != l_sensorconfig.sensor_samp)
+ {
+ // should do sth
+ }
+ //printk(KERN_ALERT "sensor samp=%d(amsr:%d) has been set.\n", sample, amsr);
+ } else {
+ klog("Wrong sample argumnet of sensor.\n");
+ }
+ } else if (sscanf(buffer, "enable=%d\n", &enable))
+ {
+ if ((enable < 0) || (enable > 1))
+ {
+ klog("The argument to enable/disable g-sensor should be 0 or 1 !!!\n");
+ } else if (enable != l_sensorconfig.sensor_enable)
+ {
+ //mma_enable_disable(enable);
+ l_sensorconfig.sensor_enable = enable;
+ }
+ } else if (sscanf(buffer, "sensor_test=%d\n", &test))
+ { // for test begin
+ l_sensorconfig.test_pass = 0;
+ } else if (sscanf(buffer, "sensor_testend=%d\n", &test))
+ { // Don nothing only to be compatible the before testing program
+ }
+ mutex_unlock(&sense_data_mutex);
+ return count;
+}
+
+static int sensor_readproc(char *page, char **start, off_t off,
+ int count, int *eof, void *data)
+{
+ int len = 0;
+
+ len = sprintf(page,
+ "test_pass=%d\nisdbg=%d\nrate=%d\nenable=%d\n",
+ l_sensorconfig.test_pass,
+ l_sensorconfig.isdbg,
+ l_sensorconfig.sensor_samp,
+ l_sensorconfig.sensor_enable
+ );
+ return len;
+}
+
+static void read_work_func(struct work_struct *work)
+{
+ s16 xyz[SENSOR_DATA_SIZE];
+ s16 txyz[SENSOR_DATA_SIZE];
+
+ if (! l_sensorconfig.sensor_enable)
+ {
+ // no report data
+ queue_delayed_work(l_sensorconfig.queue, &l_sensorconfig.work, msecs_to_jiffies(sample_rate_2_memsec(l_sensorconfig.sensor_samp)));
+ return;
+ }
+ // read data to one cycle que
+ //dbg("read...\n");
+ dmard08_i2c_read_xyz(l_sensorconfig.client, (s16 *)xyz);
+
+ // x
+ txyz[0] = xyz[l_sensorconfig.xyz_axis[0][0]]*l_sensorconfig.xyz_axis[0][1]+l_sensorconfig.offset[0];
+ // y
+ txyz[1] = xyz[l_sensorconfig.xyz_axis[1][0]]*l_sensorconfig.xyz_axis[1][1]+l_sensorconfig.offset[1];
+ // z
+ txyz[2] = xyz[l_sensorconfig.xyz_axis[2][0]]*l_sensorconfig.xyz_axis[2][1]+l_sensorconfig.offset[2];
+
+ input_report_abs(l_sensorconfig.input_dev, ABS_X, txyz[0]);
+ input_report_abs(l_sensorconfig.input_dev, ABS_Y, txyz[1]);
+ input_report_abs(l_sensorconfig.input_dev, ABS_Z, txyz[2]);
+ input_sync(l_sensorconfig.input_dev);
+ l_sensorconfig.test_pass = 1; // for testing
+ // read next
+ queue_delayed_work(l_sensorconfig.queue, &l_sensorconfig.work, msecs_to_jiffies(sample_rate_2_memsec(l_sensorconfig.sensor_samp)));
+}
+
+
+static int dmard08_probe(struct platform_device *pdev)
+{
+ int err = 0;
+
+ //register ctrl dev
+ err = misc_register(&d08_device);
+ if (err !=0) {
+ errlog("Can't register d08_device!\n");
+ return -1;
+ }
+ // register rd/wr proc
+ l_sensorconfig.sensor_proc = create_proc_entry(GSENSOR_PROC_NAME, 0666, NULL/*&proc_root*/);
+ if (l_sensorconfig.sensor_proc != NULL)
+ {
+ l_sensorconfig.sensor_proc->write_proc = sensor_writeproc;
+ l_sensorconfig.sensor_proc->read_proc = sensor_readproc;
+ }
+ // init work queue
+ l_sensorconfig.queue = create_singlethread_workqueue("sensor-report");
+ INIT_DELAYED_WORK(&l_sensorconfig.work, read_work_func);
+ mutex_init(&sense_data_mutex);
+ // init input device
+ l_sensorconfig.input_dev = input_allocate_device();
+ if (!l_sensorconfig.input_dev) {
+ err = -ENOMEM;
+ errlog("Failed to allocate input device\n");
+ goto exit_input_dev_alloc_failed;
+ }
+ l_sensorconfig.input_dev->evbit[0] = BIT(EV_ABS) | BIT_MASK(EV_KEY);
+ /* x-axis acceleration */
+ input_set_abs_params(l_sensorconfig.input_dev, ABS_X, -1024, 1024, 0, 0);
+ /* y-axis acceleration */
+ input_set_abs_params(l_sensorconfig.input_dev, ABS_Y, -1024, 1024, 0, 0);
+ /* z-axis acceleration */
+ input_set_abs_params(l_sensorconfig.input_dev, ABS_Z, -1024, 1024, 0, 0);
+
+ l_sensorconfig.input_dev->name = GSENSOR_INPUT_NAME;
+
+ err = input_register_device(l_sensorconfig.input_dev);
+
+ if (err) {
+ errlog("Unable to register input device: %s\n",
+ l_sensorconfig.input_dev->name);
+ goto exit_input_register_device_failed;
+ }
+
+ return 0;
+exit_input_register_device_failed:
+ // free inut
+ input_free_device(l_sensorconfig.input_dev);
+exit_input_dev_alloc_failed:
+ // free queue
+ destroy_workqueue(l_sensorconfig.queue);
+ l_sensorconfig.queue = NULL;
+ // free proc
+ if (l_sensorconfig.sensor_proc != NULL)
+ {
+ remove_proc_entry(GSENSOR_PROC_NAME, NULL);
+ l_sensorconfig.sensor_proc = NULL;
+ }
+ // free work
+ // unregister ctrl dev
+ misc_deregister(&d08_device);
+ return err;
+}
+
+static int dmard08_remove(struct platform_device *pdev)
+{
+ if (NULL != l_sensorconfig.queue)
+ {
+ cancel_delayed_work_sync(&l_sensorconfig.work);
+ flush_workqueue(l_sensorconfig.queue);
+ destroy_workqueue(l_sensorconfig.queue);
+ l_sensorconfig.queue = NULL;
+ }
+ if (l_sensorconfig.sensor_proc != NULL)
+ {
+ remove_proc_entry(GSENSOR_PROC_NAME, NULL);
+ l_sensorconfig.sensor_proc = NULL;
+ }
+ misc_deregister(&d08_device);
+ input_unregister_device(l_sensorconfig.input_dev);
+ return 0;
+}
+
+
+static struct platform_driver dmard08_driver = {
+ .probe = dmard08_probe,
+ .remove = dmard08_remove,
+ .suspend = dmard08_suspend,
+ .resume = dmard08_resume,
+ .driver = {
+ .name = GSENSOR_I2C_NAME,
+ },
+};
+
+#if 0
+static void dmard08_early_suspend(struct early_suspend *h)
+{
+ dbg("start\n");
+ cancel_delayed_work_sync(&l_sensorconfig.work);
+ dbg("exit\n");
+}
+
+static void dmard08_late_resume(struct early_suspend *h)
+{
+ dbg("start\n");
+ // init
+ queue_delayed_work(l_sensorconfig.queue, &l_sensorconfig.work, msecs_to_jiffies(sample_rate_2_memsec(l_sensorconfig.sensor_samp)));
+ dbg("exit\n");
+}
+#endif
+
+static int __init dmard08_init(void) //OK
+{
+ int ret = 0;
+
+ // parse g-sensor u-boot arg
+ ret = get_axisset();
+ if (ret < 0)
+ {
+ printk("<<<<<%s user choose to no sensor chip!\n", __func__);
+ return ret;
+ }
+ /*if ((ret != 0) || !l_sensorconfig.op)
+ {
+ dbg("Can't load gsensor dmar08 driver for error u-boot arg!\n");
+ return -EINVAL;
+ }*/
+ if (!(this_client = sensor_i2c_register_device(0, GSENSOR_I2C_ADDR, GSENSOR_I2C_NAME)))
+ {
+ printk(KERN_EMERG"Can't register gsensor i2c device!\n");
+ return -1;
+ }
+ // find the device
+ /*if(i2c_add_driver(&dmard08_i2c_driver) != 0)
+ {
+ ret = -1;
+ dbg("Can't find gsensor dmard08!\n");
+ goto err_i2c_add_driver;
+ }*/
+ if(dmard08_hw_init(this_client))
+ {
+ ret = -1;
+ dbg("Can't find gsensor dmard08!\n");
+ goto err_i2c_add_driver;
+ }
+
+
+ // create the platform device
+ l_dev_class = class_create(THIS_MODULE, GSENSOR_I2C_NAME);
+ if (IS_ERR(l_dev_class)){
+ ret = PTR_ERR(l_dev_class);
+ printk(KERN_ERR "Can't class_create gsensor device !!\n");
+ return ret;
+ }
+ if((ret = platform_device_register(&dmard08_device)))
+ {
+ klog("Can't register mc3230 platform devcie!!!\n");
+ return ret;
+ }
+ if ((ret = platform_driver_register(&dmard08_driver)) != 0)
+ {
+ errlog("Can't register mc3230 platform driver!!!\n");
+ return ret;
+ }
+#ifdef CONFIG_HAS_EARLYSUSPEND
+ l_sensorconfig.earlysuspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1;
+ l_sensorconfig.earlysuspend.suspend = dmard08_early_suspend;
+ l_sensorconfig.earlysuspend.resume = dmard08_late_resume;
+ register_early_suspend(&l_sensorconfig.earlysuspend);
+#endif
+
+ queue_delayed_work(l_sensorconfig.queue, &l_sensorconfig.work, msecs_to_jiffies(sample_rate_2_memsec(l_sensorconfig.sensor_samp)));
+
+ return 0;
+
+err_i2c_add_driver:
+ sensor_i2c_unregister_device(this_client);
+ return ret;
+}
+
+static void __exit dmard08_exit(void) //OK
+{
+ platform_driver_unregister(&dmard08_driver);
+ platform_device_unregister(&dmard08_device);
+ class_destroy(l_dev_class);
+ sensor_i2c_unregister_device(this_client);
+}
+
+//*********************************************************************************************************
+// 2011-11-30
+// Add by Steve Huang
+// function definition
+/*
+void gsensor_write_offset_to_file(void)
+{
+ char data[18];
+ unsigned int orgfs;
+ long lfile=-1;
+
+ //sprintf(data,"%5d %5d %5d",offset.u.x,offset.u.y,offset.u.z); //marked by eason check again
+
+ orgfs = get_fs();
+// Set segment descriptor associated to kernel space
+ set_fs(KERNEL_DS);
+
+ lfile=sys_open(OffsetFileName,O_WRONLY|O_CREAT, 0777);
+ if (lfile < 0)
+ {
+ printk("sys_open %s error!!. %ld\n",OffsetFileName,lfile);
+ }
+ else
+ {
+ sys_write(lfile, data,18);
+ sys_close(lfile);
+ }
+ set_fs(orgfs);
+
+ return;
+}
+
+void gsensor_read_offset_from_file(void)
+{
+ unsigned int orgfs;
+ char data[18];
+ long lfile=-1;
+ orgfs = get_fs();
+// Set segment descriptor associated to kernel space
+ set_fs(KERNEL_DS);
+
+ lfile=sys_open(OffsetFileName, O_RDONLY, 0);
+ if (lfile < 0)
+ {
+ printk("sys_open %s error!!. %ld\n",OffsetFileName,lfile);
+ if(lfile==-2)
+ {
+ lfile=sys_open(OffsetFileName,O_WRONLY|O_CREAT, 0777);
+ if(lfile >=0)
+ {
+ strcpy(data,"00000 00000 00000");
+ printk("sys_open %s OK!!. %ld\n",OffsetFileName,lfile);
+ sys_write(lfile,data,18);
+ sys_read(lfile, data, 18);
+ sys_close(lfile);
+ }
+ else
+ printk("sys_open %s error!!. %ld\n",OffsetFileName,lfile);
+ }
+
+ }
+ else
+ {
+ sys_read(lfile, data, 18);
+ sys_close(lfile);
+ }
+ //sscanf(data,"%hd %hd %hd",&offset.u.x,&offset.u.y,&offset.u.z); //marked by eason check again
+ set_fs(orgfs);
+
+}
+*/
+//*********************************************************************************************************
+MODULE_AUTHOR("DMT_RD");
+MODULE_DESCRIPTION("DMARD08 g-sensor Driver");
+MODULE_LICENSE("GPL");
+
+module_init(dmard08_init);
+module_exit(dmard08_exit);
+
diff --git a/ANDROID_3.4.5/drivers/input/sensor/dmard08_gsensor/dmard08.h b/ANDROID_3.4.5/drivers/input/sensor/dmard08_gsensor/dmard08.h
new file mode 100755
index 00000000..e6a6c935
--- /dev/null
+++ b/ANDROID_3.4.5/drivers/input/sensor/dmard08_gsensor/dmard08.h
@@ -0,0 +1,75 @@
+/*
+ * @file include/linux/dmard08.h
+ * @brief DMT g-sensor Linux device driver
+ * @author Domintech Technology Co., Ltd (http://www.domintech.com.tw)
+ * @version 1.2
+ * @date 2011/11/14
+ *
+ * @section LICENSE
+ *
+ * Copyright 2011 Domintech Technology Co., Ltd
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ *
+ */
+#ifndef DMARD08_H
+#define DMARD08_H
+
+#define GSENSOR_I2C_NAME "dmard08"
+#define GSENSOR_I2C_ADDR 0x1c
+/*
+#define DEVICE_I2C_NAME "dmard08"
+
+//#define DMT_DEBUG_DATA 1
+#define DMT_DEBUG_DATA 0
+
+#if DMT_DEBUG_DATA
+#define IN_FUNC_MSG printk(KERN_INFO "@DMT@ In %s\n", __func__)
+#define PRINT_X_Y_Z(x, y, z) printk(KERN_INFO "@DMT@ X/Y/Z axis: %04d , %04d , %04d\n", (x), (y), (z))
+#define PRINT_OFFSET(x, y, z) printk(KERN_INFO "@offset@ X/Y/Z axis: %04d , %04d , %04d\n",offset.x,offset.y,offset.z);
+#else
+#define IN_FUNC_MSG
+#define PRINT_X_Y_Z(x, y, z)
+#define PRINT_OFFSET(x, y, z)
+#endif
+*/
+
+//g-senor layout configuration, choose one of the following configuration
+#define CONFIG_GSEN_LAYOUT_PAT_1
+//#define CONFIG_GSEN_LAYOUT_PAT_2
+//#define CONFIG_GSEN_LAYOUT_PAT_3
+//#define CONFIG_GSEN_LAYOUT_PAT_4
+//#define CONFIG_GSEN_LAYOUT_PAT_5
+//#define CONFIG_GSEN_LAYOUT_PAT_6
+//#define CONFIG_GSEN_LAYOUT_PAT_7
+//#define CONFIG_GSEN_LAYOUT_PAT_8
+
+#define CONFIG_GSEN_CALIBRATION_GRAVITY_ON_Z_NEGATIVE 1
+#define CONFIG_GSEN_CALIBRATION_GRAVITY_ON_Z_POSITIVE 2
+#define CONFIG_GSEN_CALIBRATION_GRAVITY_ON_Y_NEGATIVE 3
+#define CONFIG_GSEN_CALIBRATION_GRAVITY_ON_Y_POSITIVE 4
+#define CONFIG_GSEN_CALIBRATION_GRAVITY_ON_X_NEGATIVE 5
+#define CONFIG_GSEN_CALIBRATION_GRAVITY_ON_X_POSITIVE 6
+
+#define DEFAULT_SENSITIVITY 256
+#define IOCTL_MAGIC 0x09
+#define SENSOR_DATA_SIZE 3
+
+#define SENSOR_RESET _IO(IOCTL_MAGIC, 0)
+#define SENSOR_CALIBRATION _IOWR(IOCTL_MAGIC, 1, int[SENSOR_DATA_SIZE])
+#define SENSOR_GET_OFFSET _IOR(IOCTL_MAGIC, 2, int[SENSOR_DATA_SIZE])
+#define SENSOR_SET_OFFSET _IOWR(IOCTL_MAGIC, 3, int[SENSOR_DATA_SIZE])
+#define SENSOR_READ_ACCEL_XYZ _IOR(IOCTL_MAGIC, 4, int[SENSOR_DATA_SIZE])
+
+#define SENSOR_MAXNR 4
+
+#endif
+
diff --git a/ANDROID_3.4.5/drivers/input/sensor/dmard09_gsensor/Makefile b/ANDROID_3.4.5/drivers/input/sensor/dmard09_gsensor/Makefile
new file mode 100755
index 00000000..d9242020
--- /dev/null
+++ b/ANDROID_3.4.5/drivers/input/sensor/dmard09_gsensor/Makefile
@@ -0,0 +1,35 @@
+KERNELDIR=../../../../
+#KERNELDIR=/home/hangyan/android8850/kernel/ANDROID_3.0.8
+CROSS = arm_1103_le-
+CC= $(CROSS)gcc
+LD= $(CROSS)ld
+STRIP = $(CROSS)strip
+
+DEBUG = n
+
+# Add your debugging flag (or not) to EXTRA_CFLAGS
+ifeq ($(DEBUG),y)
+# DEBFLAGS = -O -g -DSCULL_DEBUG # "-O" is needed to expand inlines
+DEBFLAGS = -O0 -g -DSCULL_DEBUG # "-O" is needed to expand inlines
+
+else
+ DEBFLAGS = -O2 -Wall
+endif
+
+
+EXTRA_CFLAGS += $(DEBFLAGS)
+
+
+MY_MODULE_NAME=s_wmt_gsensor_dmard09
+
+obj-m := $(MY_MODULE_NAME).o
+$(MY_MODULE_NAME)-objs := dmt09.o
+
+default:
+ $(MAKE) -C $(KERNELDIR) SUBDIRS=$(PWD) modules
+ $(STRIP) --strip-debug $(MY_MODULE_NAME).ko
+ rm -rf *.o *~ core .depend .*.cmd *.mod.c .tmp_versions
+
+clean:
+ rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions *.order *.symvers
+
diff --git a/ANDROID_3.4.5/drivers/input/sensor/dmard09_gsensor/dmt09.c b/ANDROID_3.4.5/drivers/input/sensor/dmard09_gsensor/dmt09.c
new file mode 100755
index 00000000..90b03aa3
--- /dev/null
+++ b/ANDROID_3.4.5/drivers/input/sensor/dmard09_gsensor/dmt09.c
@@ -0,0 +1,1685 @@
+/*
+ * @file drivers/misc/dmt09.c
+ * @brief DMT g-sensor Linux device driver
+ * @author Domintech Technology Co., Ltd (http://www.domintech.com.tw)
+ * @version 1.06
+ * @date 2013/08/14
+ * @section LICENSE
+ *
+ * Copyright 2012 Domintech Technology Co., Ltd
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+#include "dmt09.h"
+#include
+#include
+#include