rk3288:ricoh619&syb827:support pmic ricoh619 and dcdc syb827
author张晴 <zhangqing@rock-chips.com>
Mon, 14 Apr 2014 06:39:17 +0000 (14:39 +0800)
committer张晴 <zhangqing@rock-chips.com>
Mon, 14 Apr 2014 06:39:17 +0000 (14:39 +0800)
23 files changed:
arch/arm/boot/dts/ricoh619.dtsi [new file with mode: 0644]
arch/arm/boot/dts/rk3288-tb.dts [changed mode: 0755->0644]
arch/arm/configs/rockchip_defconfig
drivers/input/misc/Kconfig [changed mode: 0644->0755]
drivers/input/misc/Makefile [changed mode: 0644->0755]
drivers/input/misc/ricoh619-pwrkey.c [changed mode: 0644->0755]
drivers/mfd/Kconfig
drivers/mfd/Makefile
drivers/mfd/ricoh619-irq.c [changed mode: 0644->0755]
drivers/mfd/ricoh619.c
drivers/power/Kconfig [changed mode: 0644->0755]
drivers/power/Makefile [changed mode: 0644->0755]
drivers/power/ricoh619-battery.c [changed mode: 0644->0755]
drivers/regulator/Kconfig [changed mode: 0644->0755]
drivers/regulator/Makefile [changed mode: 0644->0755]
drivers/regulator/ricoh619-regulator.c
drivers/regulator/syb827.c [new file with mode: 0755]
drivers/rtc/Kconfig [changed mode: 0644->0755]
drivers/rtc/Makefile [changed mode: 0644->0755]
drivers/rtc/rtc-ricoh619.c
include/linux/mfd/ricoh619.h [changed mode: 0644->0755]
include/linux/power/ricoh619_battery.h [changed mode: 0644->0755]
include/linux/power/ricoh61x_battery_init.h

diff --git a/arch/arm/boot/dts/ricoh619.dtsi b/arch/arm/boot/dts/ricoh619.dtsi
new file mode 100644 (file)
index 0000000..99af2fa
--- /dev/null
@@ -0,0 +1,169 @@
+/*
+ * Copyright (C) 2014 Ricoh Electronic Devices Co., Ltd. - http://www.rioch.com/LSI
+ *
+ * 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.
+ */
+
+/*
+ * Integrated Power Management Chip
+ * http://www.ricoh.com/LSI/product_pmic/multiple-pmu/rc5t619/
+ */
+
+&ricoh619
+{
+       compatible = "ricoh,ricoh619";
+       interrupt-controller;
+       #interrupt-cells = <0>;
+       
+       pwrkey: pwrkey@0 {
+               compatible = "ricoh,ricoh619-pwrkey";
+               ricoh,pwrkey-delay-ms = <20>;           
+       };
+
+       rtc {
+               compatible = "ricoh,ricoh619-rtc";
+               ricoh,rtc-tm-year = <2014>;
+               ricoh,rtc-tm-month = <1>;
+               ricoh,rtc-tm-mday = <1>;
+               ricoh,rtc-tm-hour = <8>;
+               ricoh,rtc-tm-min = <0>;
+               ricoh,rtc-tm-sec = <0>;
+       };
+
+       battery {
+               compatible = "ricoh,ricoh619-battery";
+               ricoh,alarm-vol-mv = <3300>;
+               ricoh,multiple = <100>;
+               ricoh,monitor-time = <1>;
+
+               ricoh,ch-vfchg = <0xff>;/* VFCHG        = 0 - 4 (4.05v, 4.10v, 4.15v, 4.20v, 4.35v) */
+               ricoh,ch-vrchg = <0xff>;/* VRCHG        = 0 - 4 (3.85v, 3.90v, 3.95v, 4.00v, 4.10v) */
+               ricoh,ch-vbatovset = <0xff>;/* VBATOVSET        = 0 or 1 (0 : 4.38v(up)/3.95v(down) 1: 4.53v(up)/4.10v(down)) */
+               ricoh,ch-ichg = <0xff>;/* ICHG          = 0 - 0x1D (100mA - 3000mA) */
+               ricoh,ch-ilim-adp = <0xff>;/* ILIM_ADP  = 0 - 0x1D (100mA - 3000mA) */
+               ricoh,ch-ilim-usb = <0xff>;/* ILIM_USB  = 0 - 0x1D (100mA - 3000mA) */
+               ricoh,ch-icchg = <0x03>;/* ICCHG        = 0 - 3 (50mA 100mA 150mA 200mA) */
+               ricoh,fg-target-vsys = <3000>;/* This value is the target one to DSOC=0% */
+               ricoh,fg-target-ibat = <1000>;/* This value is the target one to DSOC=0% */
+               ricoh,fg-poff-vbat = <0>;/* setting value of 0 per Vbat */
+               ricoh,jt-en = <0>;/* JEITA Enable         = 0 or 1 (1:enable, 0:disable) */
+               ricoh,jt-hw-sw = <1>;/* JEITA HW or SW = 0 or 1 (1:HardWare, 0:SoftWare) */
+               ricoh,jt-temp-h = <50>;/* degree C */
+               ricoh,jt-temp-l = <12>;/* degree C */
+               ricoh,jt-vfchg-h = <0x03>;/* VFCHG High         = 0 - 4 (4.05v, 4.10v, 4.15v, 4.20v, 4.35v) */
+               ricoh,jt-vfchg-l = <0>;/* VFCHG High    = 0 - 4 (4.05v, 4.10v, 4.15v, 4.20v, 4.35v) */
+               ricoh,jt-ichg-h = <0x0D>;/* VFCHG Low   = 0 - 4 (4.05v, 4.10v, 4.15v, 4.20v, 4.35v) */
+               ricoh,jt-ichg-l = <0x09>;/* ICHG Low    = 0 - 0x1D (100mA - 3000mA) */
+       };
+
+       regulators {
+               #address-cells = <1>;
+               #size-cells = <0>;      
+               
+               ricoh619_dcdc1_reg: regulator@0 {
+                       reg = <0>;
+                       regulator-compatible = "ricoh619_dc1";
+                       regulator-always-on;
+                       regulator-boot-on;
+               };
+               ricoh619_dcdc2_reg: regulator@1 {
+                       reg = <1>;
+                       regulator-compatible = "ricoh619_dc2";
+                       regulator-always-on;
+                       regulator-boot-on;
+               };
+               ricoh619_dcdc3_reg: regulator@2 {
+                       reg = <2>;
+                       regulator-compatible = "ricoh619_dc3";
+                       regulator-always-on;
+                       regulator-boot-on;
+               };
+               ricoh619_dcdc4_reg: regulator@3 {
+                       reg = <3>;
+                       regulator-compatible = "ricoh619_dc4";
+                       regulator-always-on;
+                       regulator-boot-on;
+               };
+               ricoh619_dcdc5_reg: regulator@4 {
+                       reg = <4>;
+                       regulator-compatible = "ricoh619_dc5";
+                       regulator-always-on;
+                       regulator-boot-on;
+               };
+               ricoh619_ldo1_reg: regulator@5  {
+                       reg = <5>;
+                       regulator-compatible = "ricoh619_ldo1";
+                       regulator-always-on;
+                       regulator-boot-on;
+               };
+               ricoh619_ldo2_reg: regulator@6  {
+                       reg = <6>;
+                       regulator-compatible = "ricoh619_ldo2";
+                       regulator-always-on;
+                       regulator-boot-on;
+               };
+               ricoh619_ldo3_reg: regulator@7  {
+                       reg = <7>;
+                       regulator-compatible = "ricoh619_ldo3";
+                       regulator-always-on;
+                       regulator-boot-on;
+               };
+               ricoh619_ldo4_reg: regulator@8  {
+                       reg = <8>;
+                       regulator-compatible = "ricoh619_ldo4";
+                       regulator-always-on;
+                       regulator-boot-on;
+               };
+               ricoh619_ldo5_reg: regulator@9  {
+                       reg = <9>;
+                       regulator-compatible = "ricoh619_ldo5";
+                       regulator-always-on;
+                       regulator-boot-on;
+               };
+               ricoh619_ldo6_reg: regulator@10  {
+                       reg = <10>;
+                       regulator-compatible = "ricoh619_ldo6";
+                       regulator-always-on;
+                       regulator-boot-on;
+               };
+               ricoh619_ldo7_reg: regulator@11  {
+                       reg = <11>;
+                       regulator-compatible = "ricoh619_ldo7";
+                       regulator-always-on;
+                       regulator-boot-on;
+               };
+               ricoh619_ldo8_reg: regulator@12  {
+                       reg = <12>;
+                       regulator-compatible = "ricoh619_ldo8";
+                       regulator-always-on;
+                       regulator-boot-on;
+               };
+               ricoh619_ldo9_reg: regulator@13  {
+                       reg = <13>;
+                       regulator-compatible = "ricoh619_ldo9";
+                       regulator-always-on;
+                       regulator-boot-on;
+               };
+               ricoh619_ldo10_reg: regulator@14  {
+                       reg = <14>;
+                       regulator-compatible = "ricoh619_ldo10";
+                       regulator-always-on;
+                       regulator-boot-on;
+               };
+               ricoh619_ldortc1_reg: regulator@15  {
+                       reg = <15>;
+                       regulator-compatible = "ricoh619_ldortc1";
+                       regulator-always-on;
+                       regulator-boot-on;
+               };
+               ricoh619_ldortc2_reg: regulator@16  {
+                       reg = <16>;
+                       regulator-compatible = "ricoh619_ldortc2";
+                       regulator-always-on;
+                       regulator-boot-on;
+               };
+       };
+};
+
old mode 100755 (executable)
new mode 100644 (file)
index b885f60..9ff8b30
                reg = <0x1b>;
                status = "okay";
        };
-       
+               syb827b: syb827b@40 {
+               compatible = "silergy,syb827";
+       reg = <0x40>;
+               status = "okay";
+               regulators {
+                       #address-cells = <1>;
+                       #size-cells = <0>;      
+                       syb827b_dc1: regulator@0 {
+                       reg = <0>;
+                       regulator-compatible = "syb827_dcdc1";
+                       regulator-name = "vdd_arm";
+                       regulator-min-microvolt = <712500>;
+                       regulator-max-microvolt = <1500000>;
+                       regulator-always-on;
+                       regulator-boot-on;
+                       regulator-initial-mode = <0x2>;
+                       regulator-initial-state = <3>;
+                       regulator-state-mem {
+                               regulator-state-mode = <0x2>;
+                               regulator-state-disabled;
+                               regulator-state-uv = <900000>;
+                       };
+               };
+          };
+       };
+       syb827c: syb827c@41 {
+               compatible = "silergy,syb827";
+               reg = <0x41>;
+               status = "okay";
+               regulators {
+                       #address-cells = <1>;
+                       #size-cells = <0>;      
+                       syb827c_dc1: regulator@0 {
+                       reg = <0>;
+                       regulator-compatible = "syb827_dcdc1";
+                       regulator-name = "vdd_gpu";
+                       regulator-min-microvolt = <712500>;
+                       regulator-max-microvolt = <1500000>;
+                       regulator-always-on;
+               regulator-boot-on;
+                       regulator-initial-mode = <0x2>;
+                       regulator-initial-state = <3>;
+                       regulator-state-mem {
+                               regulator-state-mode = <0x2>;
+                               regulator-state-enabled;
+                               regulator-state-uv = <900000>;
+                       };      
+               };
+          };
+       };
+
+       ricoh619: ricoh619@32 {
+               reg = <0x32>;
+               status = "okay";
+       };
        bq24296: bq24296@6b {
                compatible = "ti,bq24296";
                reg = <0x6b>;
                bq24296,chg_current = <1000 2000 3000>;
                status = "okay";
        };
+       
        bq27320: bq27320@55 {
                compatible = "ti,bq27320";
                reg = <0x55>;
@@ -527,7 +582,7 @@ rockchip,power_type = <GPIO>;
                        label = "volume down";
                        rockchip,adc_value = <170>;
                };
-
+               
                power-key {
                        gpios = <&gpio0 GPIO_A5 GPIO_ACTIVE_LOW>;
                        linux,code = <116>;
@@ -732,6 +787,185 @@ rockchip,power_type = <GPIO>;
        };
 };
 
+/include/ "ricoh619.dtsi"
+&ricoh619 {
+       gpios =<&gpio0 GPIO_A4 GPIO_ACTIVE_HIGH>,<&gpio0 GPIO_B3 GPIO_ACTIVE_LOW>;
+       ricoh619,system-power-controller;
+       
+       regulators {
+               ricoh619_dcdc1_reg: regulator@0 {
+                       regulator-name = "vdd_logic";
+                       regulator-min-microvolt = < 700000>;
+                       regulator-max-microvolt = <1500000>;
+                       regulator-initial-mode = <0x2>;
+                       regulator-initial-state = <3>;
+                       regulator-state-mem {
+                               regulator-state-mode = <0x2>;
+                               regulator-state-enabled;
+                               regulator-state-uv = <900000>;
+                       };      
+               };
+               ricoh619_dcdc2_reg: regulator@1 {
+                       regulator-name = "ricoh619_dcdc2";
+                       regulator-min-microvolt = <1200000>;
+                       regulator-max-microvolt = <1200000>;
+                       regulator-initial-mode = <0x2>;
+                       regulator-initial-state = <3>;
+                       regulator-state-mem {
+                               regulator-state-mode = <0x2>;
+                               regulator-state-enabled;
+                               regulator-state-uv = <1200000>;
+                       };      
+               };
+               ricoh619_dcdc3_reg: regulator@2 {
+                       regulator-name = "ricoh619_dcdc3";
+                       regulator-min-microvolt = < 1200000>;
+                       regulator-max-microvolt = <1200000>;
+                       regulator-initial-mode = <0x2>;
+                       regulator-initial-state = <3>;
+                       regulator-state-mem {
+                               regulator-state-mode = <0x2>;
+                               regulator-state-enabled;
+                               regulator-state-uv = <1200000>;
+                       };      
+               };
+               ricoh619_dcdc4_reg: regulator@3 {
+                       regulator-name = "ricoh619_dcdc4";
+                       regulator-min-microvolt = < 3300000>;
+                       regulator-max-microvolt = <3300000>;
+                       regulator-initial-mode = <0x2>;
+                       regulator-initial-state = <3>;
+                       regulator-state-mem {
+                               regulator-state-mode = <0x2>;
+                               regulator-state-enabled;
+                               regulator-state-uv = <2800000>;
+                       };      
+               };
+               ricoh619_dcdc5_reg: regulator@4 {
+                       regulator-name = "ricoh619_dcdc5";
+                       regulator-min-microvolt = < 2000000>;
+                       regulator-max-microvolt = <2000000>;
+                       regulator-initial-mode = <0x2>;
+                       regulator-initial-state = <3>;
+                       regulator-state-mem {
+                               regulator-state-mode = <0x2>;
+                               regulator-state-enabled;
+                               regulator-state-uv = <2000000>;
+                       };      
+               };
+               ricoh619_ldo1_reg: regulator@5  {
+                       regulator-name = "ricoh619_ldo1";
+                       regulator-min-microvolt = <3300000>;
+                       regulator-max-microvolt = <3300000>;
+                       regulator-initial-state = <3>;
+                       regulator-state-mem {
+                               regulator-state-enabled;
+                               regulator-state-uv = <3300000>;
+                       };      
+               };
+               ricoh619_ldo2_reg: regulator@6  {
+                       regulator-name = "ricoh619_ldo2";
+                       regulator-min-microvolt = <3300000>;
+                       regulator-max-microvolt = <3300000>;
+                       regulator-initial-state = <3>;
+                       regulator-state-mem {
+                               regulator-state-enabled;
+                               regulator-state-uv = <3300000>;
+                       };
+               };
+               ricoh619_ldo3_reg: regulator@7  {
+                       regulator-name = "ricoh619_ldo3";
+                       regulator-min-microvolt = <3300000>;
+                       regulator-max-microvolt = <3300000>;
+                       regulator-initial-state = <3>;
+                       regulator-state-mem {
+                               regulator-state-enabled;
+                               regulator-state-uv = <3300000>;
+                       };
+               };
+               ricoh619_ldo4_reg: regulator@8  {
+                       regulator-name = "vcc_sd";
+                       regulator-min-microvolt = <3300000>;
+                       regulator-max-microvolt = <3300000>;
+                       regulator-initial-state = <3>;
+                       regulator-state-mem {
+                               regulator-state-enabled;
+                               regulator-state-uv = <3300000>;
+                       };
+               };
+               ricoh619_ldo5_reg: regulator@9  {
+                       regulator-name = "ricoh619_ldo5";
+                       regulator-min-microvolt = <3300000>;
+                       regulator-max-microvolt = <3300000>;
+                       regulator-initial-state = <3>;
+                       regulator-state-mem {
+                               regulator-state-enabled;
+                               regulator-state-uv = <3300000>;
+                       };
+               };
+               ricoh619_ldo6_reg: regulator@10  {
+                       regulator-name = "ricoh619_ldo6";
+                       regulator-min-microvolt = <1800000>;
+                       regulator-max-microvolt = <1800000>;
+                       regulator-initial-state = <3>;
+                       regulator-state-mem {
+                               regulator-state-enabled;
+                               regulator-state-uv = <1800000>;
+                       };
+               };
+               ricoh619_ldo7_reg: regulator@11  {
+                       regulator-name = "ricoh619_ldo7";
+                       regulator-min-microvolt = <1000000>;
+                       regulator-max-microvolt = <1000000>;
+                       regulator-initial-state = <3>;
+                       regulator-state-mem {
+                               regulator-state-enabled;
+                               regulator-state-uv = <3300000>;
+                       };
+               };
+               ricoh619_ldo8_reg: regulator@12  {
+                       regulator-name = "ricoh619_ldo8";
+                       regulator-min-microvolt = <1800000>;
+                       regulator-max-microvolt = <1800000>;
+                       regulator-initial-state = <3>;
+                       regulator-state-mem {
+                               regulator-state-enabled;
+                               regulator-state-uv = <3300000>;
+                       };
+               };
+               ricoh619_ldo9_reg: regulator@13  {
+                       regulator-name = "ricoh619_ldo9";
+                       regulator-min-microvolt = <1000000>;
+                       regulator-max-microvolt = <1000000>;
+                       regulator-initial-state = <3>;
+                       regulator-state-mem {
+                               regulator-state-enabled;
+                               regulator-state-uv = <3300000>;
+                       };
+               };
+               ricoh619_ldo10_reg: regulator@14  {
+                       regulator-name = "ricoh619_ldo10";
+                       regulator-min-microvolt = <1800000>;
+                       regulator-max-microvolt = <1800000>;
+                       regulator-initial-state = <3>;
+                       regulator-state-mem {
+                               regulator-state-enabled;
+                               regulator-state-uv = <3300000>;
+                       };
+               };
+               ricoh619_ldortc1_reg: regulator@15  {
+                       regulator-name = "ricoh619_ldortc1";
+                       regulator-min-microvolt = < 3300000>;
+                       regulator-max-microvolt = <3300000>;
+               };
+               ricoh619_ldortc2_reg: regulator@16  {
+                       regulator-name = "ricoh619_ldortc2";
+                       regulator-min-microvolt = < 3300000>;
+                       regulator-max-microvolt = <3300000>;
+               };
+       };
+};
+
 &lcdc_vdd_domain {
        regulator-name = "vcc30_lcd";
        };
index fd5aaa74f5a0bd5ed27f1d6f70535ba8083f62d1..2c67100fc12e7c731d2b0589aa42d07dd706056d 100755 (executable)
@@ -295,6 +295,7 @@ CONFIG_TOUCHSCREEN_GT8XX=y
 CONFIG_CT36X_TS=y
 CONFIG_INPUT_MISC=y
 CONFIG_INPUT_KEYCHORD=y
+CONFIG_INPUT_RICOH619_PWRKEY=y
 CONFIG_INPUT_UINPUT=y
 CONFIG_INPUT_GPIO=y
 # CONFIG_GS_LIS3DH is not set
@@ -319,16 +320,20 @@ CONFIG_SPI_ROCKCHIP_DMA=y
 CONFIG_SPI_ROCKCHIP_TEST=y
 CONFIG_DEBUG_GPIO=y
 CONFIG_GPIO_SYSFS=y
+CONFIG_BATTERY_RICOH619=y
 CONFIG_BATTERY_BQ24296=y
 CONFIG_BATTERY_BQ27320=y
 CONFIG_CW2015_BATTERY=y
 CONFIG_SENSORS_ROCKCHIP_TSADC=y
 CONFIG_THERMAL=y
 CONFIG_MFD_RK808=y
+CONFIG_MFD_RICOH619=y
 CONFIG_REGULATOR=y
 CONFIG_REGULATOR_FIXED_VOLTAGE=y
 CONFIG_REGULATOR_ACT8846=y
 CONFIG_ROCKCHIP_PWM_REGULATOR=y
+CONFIG_REGULATOR_SYB827=y
+CONFIG_REGULATOR_RICOH619=y
 CONFIG_MEDIA_SUPPORT=y
 CONFIG_MEDIA_CAMERA_SUPPORT=y
 CONFIG_MEDIA_RC_SUPPORT=y
@@ -482,6 +487,7 @@ CONFIG_SWITCH=y
 CONFIG_RTC_CLASS=y
 CONFIG_RTC_DRV_PCF8563=y
 CONFIG_RK808_RTC=y
+CONFIG_RTC_DRV_RC5T619=y
 CONFIG_STAGING=y
 CONFIG_ANDROID=y
 CONFIG_ANDROID_BINDER_IPC=y
old mode 100644 (file)
new mode 100755 (executable)
index 4abf046..c74bfdd
@@ -405,6 +405,15 @@ config INPUT_TWL4030_PWRBUTTON
          To compile this driver as a module, choose M here. The module will
          be called twl4030_pwrbutton.
 
+config INPUT_RICOH619_PWRKEY
+       tristate "RICOH RC5T619 PMU PWRKEY driver"
+       depends on MFD_RICOH619
+       default n
+       help
+         If you say yes here you get support for the RICOH RC5T619 PWRKEY module.
+
+         This driver can also be built as a module. If so, the module
+         will be called rc5t619-pwrkey.
 config INPUT_TWL4030_VIBRA
        tristate "Support for TWL4030 Vibrator"
        depends on TWL4030_CORE
old mode 100644 (file)
new mode 100755 (executable)
index 6b0e8a6..3a96132
@@ -62,3 +62,4 @@ obj-$(CONFIG_INPUT_WISTRON_BTNS)      += wistron_btns.o
 obj-$(CONFIG_INPUT_WM831X_ON)          += wm831x-on.o
 obj-$(CONFIG_INPUT_XEN_KBDDEV_FRONTEND)        += xen-kbdfront.o
 obj-$(CONFIG_INPUT_YEALINK)            += yealink.o
+obj-$(CONFIG_INPUT_RICOH619_PWRKEY)    += ricoh619-pwrkey.o
old mode 100644 (file)
new mode 100755 (executable)
index 95018d2..db624e7
-/*\r
-* driver/input/misc/ricoh619-pwrkey.c\r
-*\r
-* Power Key driver for RICOH RC5T619 power management chip.\r
-*\r
-* Copyright (C) 2012-2013 RICOH COMPANY,LTD\r
-*\r
-*\r
-* This program is free software; you can redistribute it and/or modify\r
-* it under the terms of the GNU General Public License as published by\r
-* the Free Software Foundation; either version 2 of the License, or\r
-* (at your option) any later version.\r
-*\r
-* This program is distributed in the hope that it will be useful, but WITHOUT\r
-* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\r
-* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for\r
-* more details.\r
-*\r
-* You should have received a copy of the GNU General Public License\r
-* along with this program. If not, see <http://www.gnu.org/licenses/>.\r
-*\r
-*/\r
-#include <linux/module.h>\r
-#include <linux/init.h>\r
-#include <linux/kernel.h>\r
-#include <linux/errno.h>\r
-#include <linux/input.h>\r
-#include <linux/interrupt.h>\r
-#include <linux/platform_device.h>\r
-#include <linux/mfd/ricoh619.h>\r
-#include <linux/spinlock.h>\r
-#include <linux/timer.h>\r
-#include <linux/pm.h>\r
-#include <linux/slab.h>\r
-#include <linux/pm_runtime.h>\r
-#include <linux/workqueue.h>\r
-#include <linux/gpio.h>\r
-\r
-#include <linux/mfd/ricoh619.h>\r
-\r
-#define RICOH619_ONKEY_TRIGGER_LEVEL   0\r
-#define RICOH619_ONKEY_OFF_IRQ         0\r
-\r
-struct ricoh619_pwrkey {\r
-       struct device *dev;\r
-       struct input_dev *pwr;\r
-       #if RICOH619_ONKEY_TRIGGER_LEVEL\r
-               struct timer_list timer;\r
-       #endif\r
-       struct workqueue_struct *workqueue;\r
-       struct work_struct work;\r
-       unsigned long delay;\r
-       int key_irq;\r
-       bool pressed_first;\r
-       struct ricoh619_pwrkey_platform_data *pdata;\r
-       spinlock_t lock;\r
-};\r
-\r
-struct ricoh619_pwrkey *g_pwrkey;\r
-\r
-#if RICOH619_ONKEY_TRIGGER_LEVEL\r
-void ricoh619_pwrkey_timer(unsigned long t)\r
-{\r
-       queue_work(g_pwrkey->workqueue, &g_pwrkey->work);\r
-}\r
-#endif\r
-\r
-static void ricoh619_irq_work(struct work_struct *work)\r
-{\r
-       /* unsigned long flags; */\r
-       uint8_t val;\r
-\r
-//     printk("PMU: %s: \n",__func__);\r
-       //spin_lock_irqsave(&g_pwrkey->lock, flags);\r
-\r
-       if(pwrkey_wakeup){\r
-//             printk("PMU: %s: pwrkey_wakeup\n",__func__);\r
-               pwrkey_wakeup = 0;\r
-               input_event(g_pwrkey->pwr, EV_KEY, KEY_POWER, 1);\r
-               input_event(g_pwrkey->pwr, EV_SYN, 0, 0);\r
-               input_event(g_pwrkey->pwr, EV_KEY, KEY_POWER, 0);\r
-               input_event(g_pwrkey->pwr, EV_SYN, 0, 0);\r
-               \r
-               return;\r
-       }\r
-       ricoh619_read(g_pwrkey->dev->parent, RICOH619_INT_MON_SYS, &val);\r
-       dev_dbg(g_pwrkey->dev, "pwrkey is pressed?(0x%x): 0x%x\n",\r
-                                               RICOH619_INT_MON_SYS, val);\r
-//     printk(KERN_INFO "PMU: %s: val=0x%x\n", __func__, val);\r
-       val &= 0x1;\r
-       if(val){\r
-               #if (RICOH619_ONKEY_TRIGGER_LEVEL)\r
-               g_pwrkey->timer.expires = jiffies + g_pwrkey->delay;\r
-               dd_timer(&g_pwrkey->timer);\r
-               #endif\r
-               if (!g_pwrkey->pressed_first){\r
-                       g_pwrkey->pressed_first = true;\r
-//                     printk("PMU1: %s: Power Key!!!\n",__func__);\r
-                       //input_report_key(g_pwrkey->pwr, KEY_POWER, 1);\r
-                       //input_sync(g_pwrkey->pwr);\r
-                       input_event(g_pwrkey->pwr, EV_KEY, KEY_POWER, 1);\r
-                       input_event(g_pwrkey->pwr, EV_SYN, 0, 0);\r
-               }\r
-       } else {\r
-               if (g_pwrkey->pressed_first) {\r
-//                     printk(KERN_INFO "PMU2: %s: Power Key!!!\n", __func__);\r
-                       /* input_report_key(g_pwrkey->pwr, KEY_POWER, 0); */\r
-                       /* input_sync(g_pwrkey->pwr); */\r
-                       input_event(g_pwrkey->pwr, EV_KEY, KEY_POWER, 0);\r
-                       input_event(g_pwrkey->pwr, EV_SYN, 0, 0);\r
-               }\r
-               g_pwrkey->pressed_first = false;\r
-       }\r
-\r
-       /* spin_unlock_irqrestore(&g_pwrkey->lock, flags); */\r
-}\r
-\r
-static irqreturn_t pwrkey_irq(int irq, void *_pwrkey)\r
-{\r
-//     printk(KERN_INFO "PMU: %s:\n", __func__);\r
-\r
-       #if (RICOH619_ONKEY_TRIGGER_LEVEL)\r
-       g_pwrkey->timer.expires = jiffies + g_pwrkey->delay;\r
-       add_timer(&g_pwrkey->timer);\r
-       #else\r
-       queue_work(g_pwrkey->workqueue, &g_pwrkey->work);\r
-       #endif\r
-       return IRQ_HANDLED;\r
-}\r
-\r
-#if RICOH619_ONKEY_OFF_IRQ\r
-static irqreturn_t pwrkey_irq_off(int irq, void *_pwrkey)\r
-{\r
-       dev_warn(g_pwrkey->dev, "ONKEY is pressed long time!\n");\r
-       return IRQ_HANDLED;\r
-}\r
-#endif\r
-\r
-static int __devinit ricoh619_pwrkey_probe(struct platform_device *pdev)\r
-{\r
-       struct input_dev *pwr;\r
-       int key_irq;\r
-       int err;\r
-       struct ricoh619_pwrkey *pwrkey;\r
-       struct ricoh619_pwrkey_platform_data *pdata = pdev->dev.platform_data;\r
-       uint8_t val;\r
-\r
-//     printk("PMU: %s: \n",__func__);\r
-\r
-       if (!pdata) {\r
-               dev_err(&pdev->dev, "power key platform data not supplied\n");\r
-               return -EINVAL;\r
-       }\r
-       key_irq = (pdata->irq + RICOH619_IRQ_POWER_ON);\r
-       printk(KERN_INFO "PMU1: %s: key_irq=%d\n", __func__, key_irq);\r
-       pwrkey = kzalloc(sizeof(*pwrkey), GFP_KERNEL);\r
-       if (!pwrkey)\r
-               return -ENOMEM;\r
-\r
-       pwrkey->dev = &pdev->dev;\r
-       pwrkey->pdata = pdata;\r
-       pwrkey->pressed_first = false;\r
-       pwrkey->delay = HZ / 1000 * pdata->delay_ms;\r
-       g_pwrkey = pwrkey;\r
-       pwr = input_allocate_device();\r
-       if (!pwr) {\r
-               dev_dbg(&pdev->dev, "Can't allocate power button\n");\r
-               err = -ENOMEM;\r
-               goto free_pwrkey;\r
-       }\r
-       input_set_capability(pwr, EV_KEY, KEY_POWER);\r
-       pwr->name = "ricoh619_pwrkey";\r
-       pwr->phys = "ricoh619_pwrkey/input0";\r
-       pwr->dev.parent = &pdev->dev;\r
-\r
-       #if RICOH619_ONKEY_TRIGGER_LEVEL\r
-       init_timer(&pwrkey->timer);\r
-       pwrkey->timer.function = ricoh619_pwrkey_timer;\r
-       #endif\r
-\r
-       spin_lock_init(&pwrkey->lock);\r
-       err = input_register_device(pwr);\r
-       if (err) {\r
-               dev_dbg(&pdev->dev, "Can't register power key: %d\n", err);\r
-               goto free_input_dev;\r
-       }\r
-       pwrkey->key_irq = key_irq;\r
-       pwrkey->pwr = pwr;\r
-       platform_set_drvdata(pdev, pwrkey);\r
-\r
-       /* Check if power-key is pressed at boot up */\r
-       err = ricoh619_read(pwrkey->dev->parent, RICOH619_INT_MON_SYS, &val);\r
-       if (err < 0) {\r
-               dev_err(&pdev->dev, "Key-press status at boot failed rc=%d\n",\r
-                                                                        err);\r
-               goto unreg_input_dev;\r
-       }\r
-       val &= 0x1;\r
-       if (val) {\r
-               input_report_key(pwrkey->pwr, KEY_POWER, 1);\r
-//             printk(KERN_INFO "******KEY_POWER:1\n");\r
-               input_sync(pwrkey->pwr);\r
-               pwrkey->pressed_first = true;\r
-       }\r
-\r
-       #if !(RICOH619_ONKEY_TRIGGER_LEVEL)\r
-               /* trigger both edge */\r
-               ricoh619_set_bits(pwrkey->dev->parent, RICOH619_PWR_IRSEL, 0x1);\r
-       #endif\r
-\r
-       err = request_threaded_irq(key_irq, NULL, pwrkey_irq,\r
-               IRQF_ONESHOT, "ricoh619_pwrkey", pwrkey);\r
-       if (err < 0) {\r
-               dev_err(&pdev->dev, "Can't get %d IRQ for pwrkey: %d\n",\r
-                                                               key_irq, err);\r
-               goto unreg_input_dev;\r
-       }\r
-\r
-       #if RICOH619_ONKEY_OFF_IRQ\r
-       err = request_threaded_irq(key_irq + RICOH619_IRQ_ONKEY_OFF, NULL,\r
-                                               pwrkey_irq_off, IRQF_ONESHOT,\r
-                                               "ricoh619_pwrkey_off", pwrkey);\r
-       if (err < 0) {\r
-               dev_err(&pdev->dev, "Can't get %d IRQ for pwrkey: %d\n",\r
-                       key_irq + RICOH619_IRQ_ONKEY_OFF, err);\r
-               free_irq(key_irq, pwrkey);\r
-               goto unreg_input_dev;\r
-       }\r
-       #endif\r
-\r
-       pwrkey->workqueue = create_singlethread_workqueue("ricoh619_pwrkey");\r
-       INIT_WORK(&pwrkey->work, ricoh619_irq_work);\r
-\r
-       /* Enable power key IRQ */\r
-       /* trigger both edge */\r
-       ricoh619_set_bits(pwrkey->dev->parent, RICOH619_PWR_IRSEL, 0x1);\r
-       /* Enable system interrupt */\r
-       ricoh619_set_bits(pwrkey->dev->parent, RICOH619_INTC_INTEN, 0x1);\r
-       /* Enable power-on interrupt */\r
-       ricoh619_set_bits(pwrkey->dev->parent, RICOH619_INT_EN_SYS, 0x1);\r
-//     printk(KERN_INFO "PMU: %s is OK!\n", __func__);\r
-       return 0;\r
-\r
-unreg_input_dev:\r
-       input_unregister_device(pwr);\r
-       pwr = NULL;\r
-\r
-free_input_dev:\r
-       input_free_device(pwr);\r
-       free_pwrkey:\r
-       kfree(pwrkey);\r
-\r
-       return err;\r
-}\r
-\r
-static int __devexit ricoh619_pwrkey_remove(struct platform_device *pdev)\r
-{\r
-       struct ricoh619_pwrkey *pwrkey = platform_get_drvdata(pdev);\r
-\r
-       flush_workqueue(pwrkey->workqueue);\r
-       destroy_workqueue(pwrkey->workqueue);\r
-       free_irq(pwrkey->key_irq, pwrkey);\r
-       input_unregister_device(pwrkey->pwr);\r
-       kfree(pwrkey);\r
-\r
-       return 0;\r
-}\r
-\r
-#ifdef CONFIG_PM\r
-static int ricoh619_pwrkey_suspend(struct device *dev)\r
-{\r
-       struct ricoh619_pwrkey *info = dev_get_drvdata(dev);\r
-\r
-//     printk(KERN_INFO "PMU: %s\n", __func__);\r
-\r
-       if (info->key_irq)\r
-               disable_irq(info->key_irq);\r
-       cancel_work_sync(&info->work);\r
-       flush_workqueue(info->workqueue);\r
-\r
-       return 0;\r
-}\r
-\r
-static int ricoh619_pwrkey_resume(struct device *dev)\r
-{\r
-       struct ricoh619_pwrkey *info = dev_get_drvdata(dev);\r
-\r
-//     printk(KERN_INFO "PMU: %s\n", __func__);\r
-       queue_work(info->workqueue, &info->work);\r
-       if (info->key_irq)\r
-               enable_irq(info->key_irq);\r
-\r
-       return 0;\r
-}\r
-\r
-static const struct dev_pm_ops ricoh619_pwrkey_pm_ops = {\r
-       .suspend        = ricoh619_pwrkey_suspend,\r
-       .resume         = ricoh619_pwrkey_resume,\r
-};\r
-#endif\r
-\r
-static struct platform_driver ricoh619_pwrkey_driver = {\r
-       .probe = ricoh619_pwrkey_probe,\r
-       .remove = __devexit_p(ricoh619_pwrkey_remove),\r
-       .driver = {\r
-               .name = "ricoh619-pwrkey",\r
-               .owner = THIS_MODULE,\r
-#ifdef CONFIG_PM\r
-               .pm     = &ricoh619_pwrkey_pm_ops,\r
-#endif\r
-       },\r
-};\r
-\r
-static int __init ricoh619_pwrkey_init(void)\r
-{\r
-       return platform_driver_register(&ricoh619_pwrkey_driver);\r
-}\r
-subsys_initcall_sync(ricoh619_pwrkey_init);\r
-\r
-static void __exit ricoh619_pwrkey_exit(void)\r
-{\r
-       platform_driver_unregister(&ricoh619_pwrkey_driver);\r
-}\r
-module_exit(ricoh619_pwrkey_exit);\r
-\r
-\r
-MODULE_ALIAS("platform:ricoh619-pwrkey");\r
-MODULE_AUTHOR("zhangqing <zhangqing@rock-chips.com>");\r
-MODULE_DESCRIPTION("ricoh619 Power Key");\r
-MODULE_LICENSE("GPL v2");
\ No newline at end of file
+/*
+* driver/input/misc/ricoh619-pwrkey.c
+*
+* Power Key driver for RICOH RC5T619 power management chip.
+*
+* Copyright (C) 2012-2013 RICOH COMPANY,LTD
+*
+*
+* This program is free software; you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation; either version 2 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful, but WITHOUT
+* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+* more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>.
+*
+*/
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/input.h>
+#include <linux/interrupt.h>
+#include <linux/platform_device.h>
+#include <linux/mfd/ricoh619.h>
+#include <linux/spinlock.h>
+#include <linux/timer.h>
+#include <linux/pm.h>
+#include <linux/slab.h>
+#include <linux/pm_runtime.h>
+#include <linux/workqueue.h>
+#include <linux/gpio.h>
+#include <linux/of.h>
+
+#include <linux/mfd/ricoh619.h>
+#include <linux/irq.h>
+#include <linux/irqdomain.h>
+
+#define RICOH619_ONKEY_TRIGGER_LEVEL   0
+#define RICOH619_ONKEY_OFF_IRQ         0
+
+struct ricoh619_pwrkey {
+       struct device *dev;
+       struct input_dev *pwr;
+       #if RICOH619_ONKEY_TRIGGER_LEVEL
+               struct timer_list timer;
+       #endif
+       struct workqueue_struct *workqueue;
+       struct work_struct work;
+       unsigned long delay;
+       int key_irq;
+       bool pressed_first;
+       struct ricoh619_pwrkey_platform_data *pdata;
+       spinlock_t lock;
+};
+
+struct ricoh619_pwrkey *g_pwrkey;
+
+#if RICOH619_ONKEY_TRIGGER_LEVEL
+void ricoh619_pwrkey_timer(unsigned long t)
+{
+       queue_work(g_pwrkey->workqueue, &g_pwrkey->work);
+}
+#endif
+
+static void ricoh619_irq_work(struct work_struct *work)
+{
+       /* unsigned long flags; */
+       uint8_t val;
+
+//     printk("PMU: %s: \n",__func__);
+       //spin_lock_irqsave(&g_pwrkey->lock, flags);
+
+       if(pwrkey_wakeup){
+//             printk("PMU: %s: pwrkey_wakeup\n",__func__);
+               pwrkey_wakeup = 0;
+               input_event(g_pwrkey->pwr, EV_KEY, KEY_POWER, 1);
+               input_event(g_pwrkey->pwr, EV_SYN, 0, 0);
+               input_event(g_pwrkey->pwr, EV_KEY, KEY_POWER, 0);
+               input_event(g_pwrkey->pwr, EV_SYN, 0, 0);
+               
+               return;
+       }
+       ricoh619_read(g_pwrkey->dev->parent, RICOH619_INT_MON_SYS, &val);
+       dev_dbg(g_pwrkey->dev, "pwrkey is pressed?(0x%x): 0x%x\n",
+                                               RICOH619_INT_MON_SYS, val);
+//     printk(KERN_INFO "PMU: %s: val=0x%x\n", __func__, val);
+       val &= 0x1;
+       if(val){
+               #if (RICOH619_ONKEY_TRIGGER_LEVEL)
+               g_pwrkey->timer.expires = jiffies + g_pwrkey->delay;
+               dd_timer(&g_pwrkey->timer);
+               #endif
+               if (!g_pwrkey->pressed_first){
+                       g_pwrkey->pressed_first = true;
+//                     printk("PMU1: %s: Power Key!!!\n",__func__);
+                       //input_report_key(g_pwrkey->pwr, KEY_POWER, 1);
+                       //input_sync(g_pwrkey->pwr);
+                       input_event(g_pwrkey->pwr, EV_KEY, KEY_POWER, 1);
+                       input_event(g_pwrkey->pwr, EV_SYN, 0, 0);
+               }
+       } else {
+               if (g_pwrkey->pressed_first) {
+//                     printk(KERN_INFO "PMU2: %s: Power Key!!!\n", __func__);
+                       /* input_report_key(g_pwrkey->pwr, KEY_POWER, 0); */
+                       /* input_sync(g_pwrkey->pwr); */
+                       input_event(g_pwrkey->pwr, EV_KEY, KEY_POWER, 0);
+                       input_event(g_pwrkey->pwr, EV_SYN, 0, 0);
+               }
+               g_pwrkey->pressed_first = false;
+       }
+
+       /* spin_unlock_irqrestore(&g_pwrkey->lock, flags); */
+}
+extern void rk_send_wakeup_key(void);
+static irqreturn_t pwrkey_irq(int irq, void *_pwrkey)
+{
+//     printk(KERN_INFO "PMU: %s:\n", __func__);
+//     rk_send_wakeup_key();
+       #if (RICOH619_ONKEY_TRIGGER_LEVEL)
+       g_pwrkey->timer.expires = jiffies + g_pwrkey->delay;
+       add_timer(&g_pwrkey->timer);
+       #else
+       queue_work(g_pwrkey->workqueue, &g_pwrkey->work);
+       #endif
+       return IRQ_HANDLED;
+}
+
+#if RICOH619_ONKEY_OFF_IRQ
+static irqreturn_t pwrkey_irq_off(int irq, void *_pwrkey)
+{
+       dev_warn(g_pwrkey->dev, "ONKEY is pressed long time!\n");
+       return IRQ_HANDLED;
+}
+#endif
+
+#ifdef CONFIG_OF
+static struct ricoh619_pwrkey_platform_data *
+ricoh619_pwrkey_dt_init(struct platform_device *pdev)
+{
+       struct device_node *nproot = pdev->dev.parent->of_node;
+       struct device_node *np;
+       struct ricoh619_pwrkey_platform_data *pdata;
+
+       if (!nproot)
+               return pdev->dev.platform_data;
+
+       np = of_find_node_by_name(nproot, "pwrkey");
+       if (!np) {
+               dev_err(&pdev->dev, "failed to find pwrkey node\n");
+               return NULL;
+       }
+
+       pdata = devm_kzalloc(&pdev->dev,
+                       sizeof(struct ricoh619_pwrkey_platform_data),
+                       GFP_KERNEL);
+
+       of_property_read_u32(np, "ricoh,pwrkey-delay-ms", &pdata->delay_ms);
+       of_node_put(np);
+
+       return pdata;
+}
+#else
+static struct ricoh619_pwrkey_platform_data *
+ricoh619_pwrkey_dt_init(struct platform_device *pdev)
+{
+       return pdev->dev.platform_data;
+}
+#endif
+
+static int ricoh619_pwrkey_probe(struct platform_device *pdev)
+{
+       struct input_dev *pwr;
+       int key_irq;
+       int err;
+       struct ricoh619_pwrkey *pwrkey;
+       struct ricoh619_pwrkey_platform_data *pdata;
+       struct ricoh619 *ricoh619 = dev_get_drvdata(pdev->dev.parent);
+       uint8_t val;
+
+//     printk("PMU: %s: \n",__func__);
+
+       pdata = ricoh619_pwrkey_dt_init(pdev);
+       if (!pdata) {
+               dev_err(&pdev->dev, "platform data isn't assigned to "
+                       "power key\n");
+               return -EINVAL;
+       }
+       key_irq  = irq_create_mapping(ricoh619->irq_domain, RICOH619_IRQ_POWER_ON);
+       printk(KERN_INFO "PMU1: %s: key_irq=%d\n", __func__, key_irq);
+       pwrkey = kzalloc(sizeof(*pwrkey), GFP_KERNEL);
+       if (!pwrkey)
+               return -ENOMEM;
+
+       pwrkey->dev = &pdev->dev;
+       pwrkey->pdata = pdata;
+       pwrkey->pressed_first = false;
+       pwrkey->delay = HZ / 1000 * pdata->delay_ms;
+       g_pwrkey = pwrkey;
+       pwr = input_allocate_device();
+       if (!pwr) {
+               dev_dbg(&pdev->dev, "Can't allocate power button\n");
+               err = -ENOMEM;
+               goto free_pwrkey;
+       }
+       input_set_capability(pwr, EV_KEY, KEY_POWER);
+       pwr->name = "ricoh619_pwrkey";
+       pwr->phys = "ricoh619_pwrkey/input0";
+       pwr->dev.parent = &pdev->dev;
+
+       #if RICOH619_ONKEY_TRIGGER_LEVEL
+       init_timer(&pwrkey->timer);
+       pwrkey->timer.function = ricoh619_pwrkey_timer;
+       #endif
+
+       spin_lock_init(&pwrkey->lock);
+       err = input_register_device(pwr);
+       if (err) {
+               dev_dbg(&pdev->dev, "Can't register power key: %d\n", err);
+               goto free_input_dev;
+       }
+       pwrkey->key_irq = key_irq;
+       pwrkey->pwr = pwr;
+       platform_set_drvdata(pdev, pwrkey);
+
+       /* Check if power-key is pressed at boot up */
+       err = ricoh619_read(pwrkey->dev->parent, RICOH619_INT_MON_SYS, &val);
+       if (err < 0) {
+               dev_err(&pdev->dev, "Key-press status at boot failed rc=%d\n",
+                                                                        err);
+               goto unreg_input_dev;
+       }
+       val &= 0x1;
+       if (val) {
+               input_report_key(pwrkey->pwr, KEY_POWER, 1);
+//             printk(KERN_INFO "******KEY_POWER:1\n");
+               input_sync(pwrkey->pwr);
+               pwrkey->pressed_first = true;
+       }
+
+       #if !(RICOH619_ONKEY_TRIGGER_LEVEL)
+               /* trigger both edge */
+               ricoh619_set_bits(pwrkey->dev->parent, RICOH619_PWR_IRSEL, 0x1);
+       #endif
+       err = request_threaded_irq(key_irq, NULL, pwrkey_irq,IRQF_ONESHOT, "ricoh619_pwrkey", pwrkey);
+       if (err < 0) {
+               dev_err(&pdev->dev, "Can't get %d IRQ for pwrkey: %d\n",
+                                                               key_irq, err);
+               goto unreg_input_dev;
+       }
+       /*
+       #if RICOH619_ONKEY_OFF_IRQ
+       err = request_threaded_irq( key_irq +RICOH619_ONKEY_OFF_IRQ, NULL,pwrkey_irq_off, IRQF_ONESHOT,
+                                               "ricoh619_pwrkey_off", pwrkey);
+       if (err < 0) {
+               dev_err(&pdev->dev, "Can't get %d IRQ for ricoh619_pwrkey_off: %d\n",
+                       key_irq + RICOH619_ONKEY_OFF_IRQ, err);
+               free_irq(key_irq, pwrkey);
+               goto unreg_input_dev;
+       }
+       #endif
+*/
+       pwrkey->workqueue = create_singlethread_workqueue("ricoh619_pwrkey");
+       INIT_WORK(&pwrkey->work, ricoh619_irq_work);
+
+       /* Enable power key IRQ */
+       /* trigger both edge */
+       ricoh619_set_bits(pwrkey->dev->parent, RICOH619_PWR_IRSEL, 0x1);
+       /* Enable system interrupt */
+       ricoh619_set_bits(pwrkey->dev->parent, RICOH619_INTC_INTEN, 0x1);
+       /* Enable power-on interrupt */
+       ricoh619_set_bits(pwrkey->dev->parent, RICOH619_INT_EN_SYS, 0x1);
+//     printk(KERN_INFO "PMU: %s is OK!\n", __func__);
+       return 0;
+
+unreg_input_dev:
+       input_unregister_device(pwr);
+       pwr = NULL;
+
+free_input_dev:
+       input_free_device(pwr);
+       free_pwrkey:
+       kfree(pwrkey);
+
+       return err;
+}
+
+static int ricoh619_pwrkey_remove(struct platform_device *pdev)
+{
+       struct ricoh619_pwrkey *pwrkey = platform_get_drvdata(pdev);
+
+       flush_workqueue(pwrkey->workqueue);
+       destroy_workqueue(pwrkey->workqueue);
+       free_irq(pwrkey->key_irq, pwrkey);
+       input_unregister_device(pwrkey->pwr);
+       kfree(pwrkey);
+
+       return 0;
+}
+
+#ifdef CONFIG_PM
+static int ricoh619_pwrkey_suspend(struct device *dev)
+{
+       struct ricoh619_pwrkey *info = dev_get_drvdata(dev);
+
+//     printk(KERN_INFO "PMU: %s\n", __func__);
+
+//     if (info->key_irq)
+//             disable_irq(info->key_irq);
+       cancel_work_sync(&info->work);
+       flush_workqueue(info->workqueue);
+
+       return 0;
+}
+
+static int ricoh619_pwrkey_resume(struct device *dev)
+{
+       struct ricoh619_pwrkey *info = dev_get_drvdata(dev);
+
+//     printk(KERN_INFO "PMU: %s\n", __func__);
+       queue_work(info->workqueue, &info->work);
+//     if (info->key_irq)
+//             enable_irq(info->key_irq);
+
+       return 0;
+}
+
+#ifdef CONFIG_OF
+static const struct of_device_id ricoh619_pwrkey_dt_match[] = {
+       { .compatible = "ricoh,ricoh619-pwrkey", },
+       {},
+};
+MODULE_DEVICE_TABLE(of, ricoh619_pwrkey_dt_match);
+#endif
+
+static const struct dev_pm_ops ricoh619_pwrkey_pm_ops = {
+       .suspend        = ricoh619_pwrkey_suspend,
+       .resume         = ricoh619_pwrkey_resume,
+};
+#endif
+
+static struct platform_driver ricoh619_pwrkey_driver = {
+       .probe = ricoh619_pwrkey_probe,
+       .remove = ricoh619_pwrkey_remove,
+       .driver = {
+               .name = "ricoh619-pwrkey",
+               .owner = THIS_MODULE,
+               .of_match_table = of_match_ptr(ricoh619_pwrkey_dt_match),
+#ifdef CONFIG_PM
+               .pm     = &ricoh619_pwrkey_pm_ops,
+#endif
+       },
+};
+
+static int __init ricoh619_pwrkey_init(void)
+{
+       return platform_driver_register(&ricoh619_pwrkey_driver);
+}
+subsys_initcall_sync(ricoh619_pwrkey_init);
+
+static void __exit ricoh619_pwrkey_exit(void)
+{
+       platform_driver_unregister(&ricoh619_pwrkey_driver);
+}
+module_exit(ricoh619_pwrkey_exit);
+
+
+MODULE_ALIAS("platform:ricoh619-pwrkey");
+MODULE_AUTHOR("zhangqing <zhangqing@rock-chips.com>");
+MODULE_DESCRIPTION("ricoh619 Power Key");
+MODULE_LICENSE("GPL v2");
index 50f1c09957a5bc3f42e6cf6486f4f2dec1af3b88..2301511ec409d3db0539fa052365aae5b4f841be 100755 (executable)
@@ -922,6 +922,18 @@ config TWL6040_CORE
          This driver provides common support for accessing the device,
          additional drivers must be enabled in order to use the
          functionality of the device (audio, vibra).
+         
+config MFD_RICOH619
+       bool "Ricoh RC5T619 Power Management system device"
+       depends on I2C && GPIOLIB && GENERIC_HARDIRQS
+       select MFD_CORE
+       default n
+       help
+         If you say yes here you get support for the RICOH619 Power
+         Management system device.
+         This driver provides common support for accessing the device,
+         additional drivers must be enabled in order to use the
+         functionality of the device.
 
 config MENELAUS
        bool "TI TWL92330/Menelaus PM chip"
index 4eb11e7690ae532cac98035f5c398bfbb6a09e87..94150e881d86f42b3bb315cda548c78d834d31cf 100755 (executable)
@@ -145,6 +145,7 @@ obj-$(CONFIG_MFD_PM8XXX_IRQ)        += pm8xxx-irq.o
 obj-$(CONFIG_TPS65911_COMPARATOR)      += tps65911-comparator.o
 obj-$(CONFIG_MFD_TPS65090)     += tps65090.o
 obj-$(CONFIG_MFD_RK808)        += rk808.o rk808-irq.o
+obj-$(CONFIG_MFD_RICOH619)     += ricoh619.o ricoh619-irq.o
 obj-$(CONFIG_MFD_AAT2870_CORE) += aat2870-core.o
 obj-$(CONFIG_MFD_INTEL_MSIC)   += intel_msic.o
 obj-$(CONFIG_MFD_PALMAS)       += palmas.o
old mode 100644 (file)
new mode 100755 (executable)
index 5bf56f1..e35604e
@@ -29,6 +29,7 @@
 #include <linux/init.h>
 #include <linux/i2c.h>
 #include <linux/mfd/ricoh619.h>
+#include <linux/irqdomain.h>
 
 
 enum int_type {
@@ -209,7 +210,11 @@ static const struct ricoh619_irq_data ricoh619_irqs[RICOH619_NR_IRQS] = {
        [RICOH619_IRQ_FWARN_ADP]        = RICOH619_IRQ(CHG_INT, 6, 32, 3, 12),
 
 };
-
+static const inline struct ricoh619_irq_data * irq_to_ricoh619_irq(struct ricoh619 *ricoh619, int irq)
+{
+       struct irq_data *data = irq_get_irq_data(irq);
+       return &ricoh619_irqs[data->hwirq];
+}
 static void ricoh619_irq_lock(struct irq_data *irq_data)
 {
        struct ricoh619 *ricoh619 = irq_data_get_irq_chip_data(irq_data);
@@ -220,8 +225,7 @@ static void ricoh619_irq_lock(struct irq_data *irq_data)
 static void ricoh619_irq_unmask(struct irq_data *irq_data)
 {
        struct ricoh619 *ricoh619 = irq_data_get_irq_chip_data(irq_data);
-       unsigned int __irq = irq_data->irq - ricoh619->irq_base;
-       const struct ricoh619_irq_data *data = &ricoh619_irqs[__irq];
+       const struct ricoh619_irq_data *data= irq_to_ricoh619_irq(ricoh619,irq_data->irq);
 
        ricoh619->group_irq_en[data->master_bit] |= (1 << data->grp_index);
        if (ricoh619->group_irq_en[data->master_bit])
@@ -238,8 +242,7 @@ static void ricoh619_irq_unmask(struct irq_data *irq_data)
 static void ricoh619_irq_mask(struct irq_data *irq_data)
 {
        struct ricoh619 *ricoh619 = irq_data_get_irq_chip_data(irq_data);
-       unsigned int __irq = irq_data->irq - ricoh619->irq_base;
-       const struct ricoh619_irq_data *data = &ricoh619_irqs[__irq];
+       const struct ricoh619_irq_data *data= irq_to_ricoh619_irq(ricoh619,irq_data->irq);
 
        ricoh619->group_irq_en[data->master_bit] &= ~(1 << data->grp_index);
        if (!ricoh619->group_irq_en[data->master_bit])
@@ -260,27 +263,20 @@ static void ricoh619_irq_sync_unlock(struct irq_data *irq_data)
 
        for (i = 0; i < ARRAY_SIZE(ricoh619->gpedge_reg); i++) {
                if (ricoh619->gpedge_reg[i] != ricoh619->gpedge_cache[i]) {
-                       if (!WARN_ON(ricoh619_write(ricoh619->dev,
-                                                   gpedge_add[i],
-                                                   ricoh619->gpedge_reg[i])))
-                               ricoh619->gpedge_cache[i] =
-                                               ricoh619->gpedge_reg[i];
+                       if (!WARN_ON(ricoh619_write(ricoh619->dev, gpedge_add[i],ricoh619->gpedge_reg[i])))
+                               ricoh619->gpedge_cache[i] =ricoh619->gpedge_reg[i];
                }
        }
 
        for (i = 0; i < ARRAY_SIZE(ricoh619->irq_en_reg); i++) {
                if (ricoh619->irq_en_reg[i] != ricoh619->irq_en_cache[i]) {
-                       if (!WARN_ON(ricoh619_write(ricoh619->dev,
-                                                   irq_en_add[i],
-                                                   ricoh619->irq_en_reg[i])))
-                               ricoh619->irq_en_cache[i] =
-                                               ricoh619->irq_en_reg[i];
+                       if (!WARN_ON(ricoh619_write(ricoh619->dev, irq_en_add[i],ricoh619->irq_en_reg[i])))
+                               ricoh619->irq_en_cache[i] =ricoh619->irq_en_reg[i];
                }
        }
 
        if (ricoh619->intc_inten_reg != ricoh619->intc_inten_cache) {
-               if (!WARN_ON(ricoh619_write(ricoh619->dev,
-                               RICOH619_INTC_INTEN, ricoh619->intc_inten_reg)))
+               if (!WARN_ON(ricoh619_write(ricoh619->dev,RICOH619_INTC_INTEN, ricoh619->intc_inten_reg)))
                        ricoh619->intc_inten_cache = ricoh619->intc_inten_reg;
        }
 
@@ -290,8 +286,7 @@ static void ricoh619_irq_sync_unlock(struct irq_data *irq_data)
 static int ricoh619_irq_set_type(struct irq_data *irq_data, unsigned int type)
 {
        struct ricoh619 *ricoh619 = irq_data_get_irq_chip_data(irq_data);
-       unsigned int __irq = irq_data->irq - ricoh619->irq_base;
-       const struct ricoh619_irq_data *data = &ricoh619_irqs[__irq];
+       const struct ricoh619_irq_data *data= irq_to_ricoh619_irq(ricoh619,irq_data->irq);
        int val = 0;
        int gpedge_index;
        int gpedge_bit_pos;
@@ -331,7 +326,8 @@ static irqreturn_t ricoh619_irq(int irq, void *data)
        int i;
        int ret;
        unsigned int rtc_int_sts = 0;
-
+       int cur_irq;
+       
        /* Clear the status */
        for (i = 0; i < MAX_INTERRUPT_MASKS; i++)
                int_sts[i] = 0;
@@ -349,8 +345,8 @@ static irqreturn_t ricoh619_irq(int irq, void *data)
                /* Even if INTC_INTMON register = 1, INT signal might not output
                 because INTC_INTMON register indicates only interrupt facter level.
                 So remove the following procedure */
-//             if (!(master_int & main_int_type[i]))
-//                     continue;
+               if (!(master_int & main_int_type[i]))
+                       continue;
                        
                ret = ricoh619_read(ricoh619->dev,
                                irq_mon_add[i], &int_sts[i]);
@@ -361,7 +357,9 @@ static irqreturn_t ricoh619_irq(int irq, void *data)
                        int_sts[i] = 0;
                        continue;
                }
-               
+               if (!int_sts[i])
+                       continue;
+
                if (main_int_type[i] & RTC_INT) {
                        // Changes status bit position from RTCCNT2 to RTCCNT1 
                        rtc_int_sts = 0;
@@ -370,21 +368,28 @@ static irqreturn_t ricoh619_irq(int irq, void *data)
                        if (int_sts[i] & 0x4)
                                rtc_int_sts |= BIT(0);
                }
-               if (i != 2) {
+
+               if(irq_clr_add[i] == RICOH619_INT_IR_RTC)
+               {
+                       int_sts[i] &= ~0x85;
                        ret = ricoh619_write(ricoh619->dev,
-                               irq_clr_add[i], ~int_sts[i]);
-                       if (ret < 0) {
+                               irq_clr_add[i], int_sts[i]);
+                       if (ret < 0)
                                dev_err(ricoh619->dev, "Error in writing reg 0x%02x "
                                        "error: %d\n", irq_clr_add[i], ret);
-                       }
                }
-               
-               if (main_int_type[i] & RTC_INT)
-                       int_sts[i] = rtc_int_sts;
+               else
+               {
+                       ret = ricoh619_write(ricoh619->dev,
+                               irq_clr_add[i], ~int_sts[i]);
+                       if (ret < 0)
+                               dev_err(ricoh619->dev, "Error in reading reg 0x%02x "
+                               "error: %d\n", irq_clr_add[i], ret);
+               }
                
                /* Mask Charger Interrupt */
                if (main_int_type[i] & CHG_INT) {
-                       if (int_sts[i])
+                       if (int_sts[i]) {
                                ret = ricoh619_write(ricoh619->dev,
                                                        irq_en_add[i], 0xff);
                                if (ret < 0) {
@@ -392,10 +397,11 @@ static irqreturn_t ricoh619_irq(int irq, void *data)
                                                "Error in write reg 0x%02x error: %d\n",
                                                        irq_en_add[i], ret);
                                }
+                       }
                }
                /* Mask ADC Interrupt */
                if (main_int_type[i] & ADC_INT) {
-                       if (int_sts[i])
+                       if (int_sts[i]) {
                                ret = ricoh619_write(ricoh619->dev,
                                                        irq_en_add[i], 0);
                                if (ret < 0) {
@@ -403,8 +409,11 @@ static irqreturn_t ricoh619_irq(int irq, void *data)
                                                "Error in write reg 0x%02x error: %d\n",
                                                        irq_en_add[i], ret);
                                }
+                       }
                }
-               
+
+               if (main_int_type[i] & RTC_INT)
+                       int_sts[i] = rtc_int_sts;
 
        }
 
@@ -412,12 +421,13 @@ static irqreturn_t ricoh619_irq(int irq, void *data)
        int_sts[6] |= int_sts[7];
 
        /* Call interrupt handler if enabled */
-       for (i = 0; i < RICOH619_NR_IRQS; ++i) {
+
+       for (i = 0; i <RICOH619_NR_IRQS; ++i) {
                const struct ricoh619_irq_data *data = &ricoh619_irqs[i];
-               if ((int_sts[data->mask_reg_index] & (1 << data->int_en_bit)) &&
-                       (ricoh619->group_irq_en[data->master_bit] & 
-                                                       (1 << data->grp_index)))
-                       handle_nested_irq(ricoh619->irq_base + i);
+               if ((int_sts[data->mask_reg_index] & (1 << data->int_en_bit)) &&(ricoh619->group_irq_en[data->master_bit] & (1 << data->grp_index)))
+                       cur_irq = irq_find_mapping(ricoh619->irq_domain, i);
+               if (cur_irq)
+                       handle_nested_irq(cur_irq);
        }
 
 //     printk(KERN_INFO "PMU: %s: out\n", __func__);
@@ -434,17 +444,39 @@ static struct irq_chip ricoh619_irq_chip = {
        .irq_set_wake = ricoh619_irq_set_wake,
 };
 
+static int ricoh619_irq_domain_map(struct irq_domain *d, unsigned int irq,
+                                       irq_hw_number_t hw)
+{
+       struct ricoh619 *ricoh619 = d->host_data;
+
+       irq_set_chip_data(irq, ricoh619);
+       irq_set_chip_and_handler(irq, &ricoh619_irq_chip, handle_edge_irq);
+       irq_set_nested_thread(irq, 1);
+#ifdef CONFIG_ARM
+       set_irq_flags(irq, IRQF_VALID);
+#else
+       irq_set_noprobe(irq);
+#endif
+       return 0;
+}
+
+static struct irq_domain_ops ricoh619_irq_domain_ops = {
+       .map = ricoh619_irq_domain_map,
+};
+
 int ricoh619_irq_init(struct ricoh619 *ricoh619, int irq,
-                               int irq_base)
+                               struct ricoh619_platform_data *pdata)
 {
-       int i, ret;
+       int i, ret,val;
        u8 reg_data = 0;
-
-       if (!irq_base) {
-               dev_warn(ricoh619->dev, "No interrupt support on IRQ base\n");
-               return -EINVAL;
+       struct irq_domain *domain;
+       
+       //      printk("%s,line=%d\n", __func__,__LINE__);      
+       if (!irq) {
+               dev_warn(ricoh619->dev, "No interrupt support, no core IRQ\n");
+               return 0;
        }
-
+       
        mutex_init(&ricoh619->irq_lock);
 
        /* Initialize all locals to 0 */
@@ -527,40 +559,41 @@ int ricoh619_irq_init(struct ricoh619 *ricoh619, int irq,
                }
        }
 
-       ricoh619->irq_base = irq_base;
-       ricoh619->chip_irq = irq;
+       if (pdata->irq_gpio && !ricoh619->chip_irq) {
+               ricoh619->chip_irq = gpio_to_irq(pdata->irq_gpio);
 
-       for (i = 0; i < RICOH619_NR_IRQS; i++) {
-               int __irq = i + ricoh619->irq_base;
-               irq_set_chip_data(__irq, ricoh619);
-               irq_set_chip_and_handler(__irq, &ricoh619_irq_chip,
-                                        handle_simple_irq);
-               irq_set_nested_thread(__irq, 1);
-#ifdef CONFIG_ARM
-               set_irq_flags(__irq, IRQF_VALID);
-#endif
+               if (pdata->irq_gpio) {
+                       ret = gpio_request(pdata->irq_gpio, "ricoh619_pmic_irq");
+                       if (ret < 0) {
+                               dev_err(ricoh619->dev,
+                                       "Failed to request gpio %d with ret:"
+                                       "%d\n", pdata->irq_gpio, ret);
+                               return IRQ_NONE;
+                       }
+                       gpio_direction_input(pdata->irq_gpio);
+                       val = gpio_get_value(pdata->irq_gpio);
+                       gpio_free(pdata->irq_gpio);
+                       pr_info("%s: ricoh619_pmic_irq=%x\n", __func__, val);
+               }
        }
-
-       ret = request_threaded_irq(irq, NULL, ricoh619_irq,
-                       IRQ_TYPE_LEVEL_LOW|IRQF_DISABLED|IRQF_ONESHOT,
-                                                  "ricoh619", ricoh619);
-       if (ret < 0)
-               dev_err(ricoh619->dev, "Error in registering interrupt "
-                               "error: %d\n", ret);
-/*
-       if (!ret) {
-               device_init_wakeup(ricoh619->dev, 1);
-               enable_irq_wake(irq);
+       
+       domain = irq_domain_add_linear(NULL, RICOH619_NR_IRQS,
+                                       &ricoh619_irq_domain_ops, ricoh619);
+       if (!domain) {
+               dev_err(ricoh619->dev, "could not create irq domain\n");
+               return -ENODEV;
        }
-*/
+       ricoh619->irq_domain = domain;
+       ret = devm_request_threaded_irq(ricoh619->dev,ricoh619->chip_irq, NULL, ricoh619_irq, IRQF_TRIGGER_FALLING |IRQF_ONESHOT, "ricoh619", ricoh619);
+//     ret = devm_request_threaded_irq(ricoh619->dev,ricoh619->chip_irq, NULL, ricoh619_irq, IRQF_TRIGGER_FALLING | IRQF_ONESHOT , "ricoh619", ricoh619);
 
+       irq_set_irq_type(ricoh619->chip_irq, IRQ_TYPE_LEVEL_LOW);
+       enable_irq_wake(ricoh619->chip_irq);
        return ret;
 }
 
 int ricoh619_irq_exit(struct ricoh619 *ricoh619)
 {
-       if (ricoh619->chip_irq)
-               free_irq(ricoh619->chip_irq, ricoh619);
        return 0;
 }
 
index bdceb2ccd1c41172249024ad30afd93de18ddd74..4b5f98e7409149be1c174b4411840944b1be179f 100755 (executable)
 #include <linux/mfd/core.h>
 #include <linux/mfd/ricoh619.h>
 #include <linux/power/ricoh619_battery.h>
+#include <linux/of_irq.h>
+#include <linux/of_gpio.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/regulator/of_regulator.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/machine.h>
+#include <linux/regmap.h>
 
 
 struct ricoh619 *g_ricoh619;
 struct sleep_control_data {
        u8 reg_add;
 };
+static struct mfd_cell ricoh619s[] = {
+       {
+               .name = "ricoh619-regulator",
+       },
+       {
+               .name = "ricoh619-battery",
+       },
+       {
+               .name = "ricoh619-rtc",
+       },
+       {
+               .name = "ricoh619-pwrkey",
+       },
+};
+
 
 #define SLEEP_INIT(_id, _reg)          \
        [RICOH619_DS_##_id] = {.reg_add = _reg}
@@ -68,12 +91,10 @@ static struct sleep_control_data sleep_data[] = {
        SLEEP_INIT(PSO4, 0x29),
        SLEEP_INIT(LDORTC1, 0x2A),
 };
-
 static inline int __ricoh619_read(struct i2c_client *client,
                                  u8 reg, uint8_t *val)
 {
-       int ret;
-
+       int ret =0;
        ret = i2c_smbus_read_byte_data(client, reg);
        if (ret < 0) {
                dev_err(&client->dev, "failed reading at 0x%02x\n", reg);
@@ -107,7 +128,7 @@ static inline int __ricoh619_bulk_reads(struct i2c_client *client, u8 reg,
 static inline int __ricoh619_write(struct i2c_client *client,
                                 u8 reg, uint8_t val)
 {
-       int ret;
+       int ret=0;
 
        dev_dbg(&client->dev, "ricoh619: reg write  reg=%x, val=%x\n",
                                reg, val);
@@ -117,14 +138,13 @@ static inline int __ricoh619_write(struct i2c_client *client,
                                val, reg);
                return ret;
        }
-
        return 0;
 }
 
 static inline int __ricoh619_bulk_writes(struct i2c_client *client, u8 reg,
                                  int len, uint8_t *val)
 {
-       int ret;
+       int ret=0;
        int i;
 
        for (i = 0; i < len; ++i) {
@@ -137,7 +157,6 @@ static inline int __ricoh619_bulk_writes(struct i2c_client *client, u8 reg,
                dev_err(&client->dev, "failed writings to 0x%02x\n", reg);
                return ret;
        }
-
        return 0;
 }
 
@@ -162,11 +181,11 @@ int ricoh619_write(struct device *dev, u8 reg, uint8_t val)
        struct ricoh619 *ricoh619 = dev_get_drvdata(dev);
        int ret = 0;
 
-       mutex_lock(&ricoh619->io_lock);
+//     mutex_lock(&ricoh619->io_lock);
        ret = set_bank_ricoh619(dev, 0);
        if( !ret )
                ret = __ricoh619_write(to_i2c_client(dev), reg, val);
-       mutex_unlock(&ricoh619->io_lock);
+//     mutex_unlock(&ricoh619->io_lock);
 
        return ret;
 }
@@ -288,7 +307,7 @@ int ricoh619_set_bits(struct device *dev, u8 reg, uint8_t bit_mask)
        ret = set_bank_ricoh619(dev, 0);
        if (!ret) {
                ret = __ricoh619_read(to_i2c_client(dev), reg, &reg_val);
-               if (ret)
+               if (ret<0)
                        goto out;
 
                if ((reg_val & bit_mask) != bit_mask) {
@@ -313,7 +332,7 @@ int ricoh619_clr_bits(struct device *dev, u8 reg, uint8_t bit_mask)
        ret = set_bank_ricoh619(dev, 0);
        if( !ret ){
                ret = __ricoh619_read(to_i2c_client(dev), reg, &reg_val);
-               if (ret)
+               if (ret<0)
                        goto out;
 
                if (reg_val & bit_mask) {
@@ -338,7 +357,7 @@ int ricoh619_update(struct device *dev, u8 reg, uint8_t val, uint8_t mask)
        ret = set_bank_ricoh619(dev, 0);
        if( !ret ){
                ret = __ricoh619_read(ricoh619->client, reg, &reg_val);
-               if (ret)
+               if (ret<0)
                        goto out;
 
                if ((reg_val & mask) != val) {
@@ -362,7 +381,7 @@ int ricoh619_update_bank1(struct device *dev, u8 reg, uint8_t val, uint8_t mask)
        ret = set_bank_ricoh619(dev, 1);
        if( !ret ){
                ret = __ricoh619_read(ricoh619->client, reg, &reg_val);
-               if (ret)
+               if (ret<0)
                        goto out;
 
                if ((reg_val & mask) != val) {
@@ -376,14 +395,14 @@ out:
 }
 
 static struct i2c_client *ricoh619_i2c_client;
-int ricoh619_power_off(void)
+static int ricoh619_power_off(void)
 {
        int ret;
        uint8_t val;
        int err = -1;
        int status, charge_state;
        struct ricoh619 *ricoh619 = g_ricoh619;
-
+#ifdef CONFIG_BATTERY_RICOH619
        val = g_soc;
        val &= 0x7f;
        ricoh619_read(ricoh619->dev, 0xBD, &status);
@@ -405,13 +424,9 @@ int ricoh619_power_off(void)
        err = ricoh619_set_bits(ricoh619->dev, TIMSET_REG, 0x03);
        if (err < 0)
                dev_err(ricoh619->dev, "Error in writing the TIMSET_Reg\n");
-  
-        ret = ricoh619_write(ricoh619->dev, RICOH619_INTC_INTEN, 0); 
-
-       if (!ricoh619_i2c_client)
-               return -EINVAL;
-//__ricoh618_write(ricoh618_i2c_client, RICOH618_PWR_REP_CNT, 0x0); //Not repeat power ON after power off(Power Off/N_OE)
-//     __ricoh618_write(ricoh618_i2c_client, RICOH618_PWR_SLP_CNT, 0x1); //Power OFF
+#endif  
+       ret = ricoh619_clr_bits(ricoh619->dev, 0xae, (0x1 <<6)); //disable alam_d
+       ret = ricoh619_write(ricoh619->dev, RICOH619_INTC_INTEN, 0); 
        ret = ricoh619_clr_bits(ricoh619->dev,RICOH619_PWR_REP_CNT,(0x1<<0));//Not repeat power ON after power off(Power Off/N_OE)
 
        if(( charge_state == CHG_STATE_CHG_TRICKLE)||( charge_state == CHG_STATE_CHG_RAPID))
@@ -479,7 +494,7 @@ static int ricoh619_gpio_to_irq(struct gpio_chip *gc, unsigned off)
 }
 
 
-static void __devinit ricoh619_gpio_init(struct ricoh619 *ricoh619,
+static void ricoh619_gpio_init(struct ricoh619 *ricoh619,
        struct ricoh619_platform_data *pdata)
 {
        int ret;
@@ -564,7 +579,7 @@ static int ricoh619_remove_subdevs(struct ricoh619 *ricoh619)
                                     ricoh619_remove_subdev);
 }
 
-static int __devinit ricoh619_add_subdevs(struct ricoh619 *ricoh619,
+static int ricoh619_add_subdevs(struct ricoh619 *ricoh619,
                                struct ricoh619_platform_data *pdata)
 {
        struct ricoh619_subdev_info *subdev;
@@ -687,119 +702,165 @@ static void __init ricoh619_debuginit(struct ricoh619 *ricoh)
 }
 #endif
 
-static void __devinit ricoh619_noe_init(struct ricoh619 *ricoh)
+#ifdef CONFIG_OF
+static struct ricoh619_platform_data *ricoh619_parse_dt(struct ricoh619 *ricoh619)
 {
-       struct i2c_client *client = ricoh->client;
+       struct ricoh619_platform_data *pdata;
+       struct device_node *regs,*ricoh619_pmic_np;
+       int i, count;
+
+       ricoh619_pmic_np = of_node_get(ricoh619->dev->of_node);
+       if (!ricoh619_pmic_np) {
+               printk("could not find pmic sub-node\n");
+               return NULL;
+       }
+       pdata = devm_kzalloc(ricoh619->dev, sizeof(*pdata), GFP_KERNEL);
+       if (!pdata)
+               return NULL;
+
+       pdata->irq_gpio = of_get_named_gpio(ricoh619_pmic_np,"gpios",0);
+               if (!gpio_is_valid(pdata->irq_gpio)) {
+                       printk("invalid gpio: %d\n",  pdata->irq_gpio);
+                       return NULL;
+               }
+
+       pdata->pmic_sleep_gpio = of_get_named_gpio(ricoh619_pmic_np,"gpios",1);
+                       if (!gpio_is_valid(pdata->pmic_sleep_gpio)) {
+                               printk("invalid gpio: %d\n",  pdata->pmic_sleep_gpio);
+               }
+       pdata->pmic_sleep = true;
+       
+       pdata->pm_off = of_property_read_bool(ricoh619_pmic_np,"ricoh619,system-power-controller");
+               
+       return pdata;
+}
+
+#else
+static struct ricoh619_platform_data *ricoh619_parse_dt(struct ricoh619 *ricoh619)
+{
+       return NULL;
+}
+#endif
+
+static void ricoh619_noe_init(struct ricoh619 *ricoh)
+{
+       int ret;
+       
+       /***************set noe time 128ms**************/
+       ret = ricoh619_set_bits(ricoh->dev,0x11,(0x1 <<3));
+       ret = ricoh619_clr_bits(ricoh->dev,0x11,(0x7 <<0));
+       ret = ricoh619_clr_bits(ricoh->dev,0x11,(0x1 <<3));//N_OE timer setting to 128mS
+       /**********************************************/
+       ret = ricoh619_clr_bits(ricoh->dev,RICOH619_PWR_REP_CNT,(1 << 0));  //Repeat power ON after reset (Power Off/N_OE) :1:reset 0:power off
+}
+
+static int ricoh619_pre_init(struct ricoh619 *ricoh619)
+{
+       int ret=0;
+       u8 val;
+        printk("%s,line=%d\n", __func__,__LINE__);
+        /*
+       ret = ricoh619_read(ricoh619->dev,0x09,&val);
+       printk("%s,line=%d ricoh619 power on his %08x\n", __func__,__LINE__,val);
+       ret = ricoh619_read(ricoh619->dev,0x0a,&val);
+       printk("%s,line=%d ricoh619 power off his %08x\n", __func__,__LINE__,val);
+       */
+       ricoh619_set_bits(ricoh619->dev, 0xae, (0x1 <<6));//enable alam_d
        
-       __ricoh619_write(client, RICOH619_PWR_NOE_TIMSET, 0x0); //N_OE timer setting to 128mS
-       __ricoh619_write(client, RICOH619_PWR_REP_CNT, 0x1); //Repeat power ON after reset (Power Off/N_OE)
+       ricoh619_noe_init(ricoh619);
+       /***************set PKEY long press time 0sec*******/
+       ret = ricoh619_set_bits(ricoh619->dev,0x10,(0x1 <<7));
+       ret = ricoh619_clr_bits(ricoh619->dev,0x10,(0x1 <<3));
+       ret = ricoh619_clr_bits(ricoh619->dev,0x10,(0x1 <<7));
+       /**********************************************/
+       ret = ricoh619_set_bits(ricoh619->dev,BATSET2_REG,(3 << 0)); 
+       ret = ricoh619_clr_bits(ricoh619->dev,BATSET2_REG,(1 << 2)); //set vrchg 4v
+       return ret;
 }
 
 static int ricoh619_i2c_probe(struct i2c_client *client,
                              const struct i2c_device_id *id)
 {
        struct ricoh619 *ricoh619;
-       struct ricoh619_platform_data *pdata = client->dev.platform_data;
+       struct ricoh619_platform_data *pdata;
        int ret;
        uint8_t control;
-       printk(KERN_INFO "PMU: %s:\n", __func__);
+        printk("%s,line=%d\n", __func__,__LINE__);
 
-       ricoh619 = kzalloc(sizeof(struct ricoh619), GFP_KERNEL);
+       ricoh619 = devm_kzalloc(&client->dev,sizeof(struct ricoh619), GFP_KERNEL);
        if (ricoh619 == NULL)
                return -ENOMEM;
 
        ricoh619->client = client;
        ricoh619->dev = &client->dev;
        i2c_set_clientdata(client, ricoh619);
-
        mutex_init(&ricoh619->io_lock);
 
        ret = ricoh619_read(ricoh619->dev, 0x36, &control);
-       if ((control < 0) || (control == 0xff) || (control == 0)) {
-               printk(KERN_INFO "The device is not ricoh619\n");
-               return 0;
+       if ((ret <0) || (control < 0) || (control == 0xff) || (control == 0) ){
+               printk(KERN_INFO "The device is not ricoh619 %08x %d\n",control,ret);
+               goto err;
        }
-       /***************set noe time 128ms**************/
-       ret = ricoh619_set_bits(ricoh619->dev,0x11,(0x1 <<3));
-       ret = ricoh619_clr_bits(ricoh619->dev,0x11,(0x7 <<0));
-       ret = ricoh619_clr_bits(ricoh619->dev,0x11,(0x1 <<3));
-       /**********************************************/
 
-       /***************set PKEY long press time 0sec*******/
-       ret = ricoh619_set_bits(ricoh619->dev,0x10,(0x1 <<7));
-       ret = ricoh619_clr_bits(ricoh619->dev,0x10,(0x1 <<3));
-       ret = ricoh619_clr_bits(ricoh619->dev,0x10,(0x1 <<7));
-       /**********************************************/
+       ret = ricoh619_pre_init(ricoh619);
+       if (ret < 0){
+               printk("The ricoh619_pre_init failed %d\n",ret);
+               goto err;
+       }
 
        ricoh619->bank_num = 0;
-
-//     ret = pdata->init_port(client->irq); // For init PMIC_IRQ port
-       if (client->irq) {
-               ret = ricoh619_irq_init(ricoh619, client->irq, pdata->irq_base);
-               if (ret) {
-                       dev_err(&client->dev, "IRQ init failed: %d\n", ret);
-                       goto err_irq_init;
-               }
-       }
        
-       ret = ricoh619_add_subdevs(ricoh619, pdata);
-       if (ret) {
-               dev_err(&client->dev, "add devices failed: %d\n", ret);
-               goto err_add_devs;
-       }
-       ricoh619_noe_init(ricoh619);
+       if (ricoh619->dev->of_node)
+               pdata = ricoh619_parse_dt(ricoh619);
+
+       /******************************set sleep vol & dcdc mode******************/
+       #ifdef CONFIG_OF
+       if (pdata->pmic_sleep_gpio) {
+                       ret = gpio_request(pdata->pmic_sleep_gpio, "ricoh619_pmic_sleep");
+                       if (ret < 0) {
+                               dev_err(ricoh619->dev,"Failed to request gpio %d with ret:""%d\n",      pdata->pmic_sleep_gpio, ret);
+                               return IRQ_NONE;
+                       }
+                       gpio_direction_output(pdata->pmic_sleep_gpio,0);
+                       ret = gpio_get_value(pdata->pmic_sleep_gpio);
+                       gpio_free(pdata->pmic_sleep_gpio);
+                       pr_info("%s: ricoh619_pmic_sleep=%x\n", __func__, ret);
+       }       
+       #endif
+       /**********************************************************/
+       ret = ricoh619_irq_init(ricoh619, pdata->irq_gpio, pdata);
+       if (ret < 0)
+               goto err;
        
+       ret = mfd_add_devices(ricoh619->dev, -1,
+                            ricoh619s, ARRAY_SIZE(ricoh619s),
+                             NULL, 0,NULL);
        g_ricoh619 = ricoh619;
-       if (pdata && pdata->pre_init) {
-               ret = pdata->pre_init(ricoh619);
-               if (ret != 0) {
-                       dev_err(ricoh619->dev, "pre_init() failed: %d\n", ret);
-                       goto err;
-               }
+       if (pdata->pm_off && !pm_power_off) {
+               pm_power_off = ricoh619_power_off;
        }
-
-       //ricoh619_gpio_init(ricoh619, pdata);
-
        ricoh619_debuginit(ricoh619);
 
-       if (pdata && pdata->post_init) {
-               ret = pdata->post_init(ricoh619);
-               if (ret != 0) {
-                       dev_err(ricoh619->dev, "post_init() failed: %d\n", ret);
-                       goto err;
-               }
-       }
-
        ricoh619_i2c_client = client;
        return 0;
 err:
        mfd_remove_devices(ricoh619->dev);
-       kfree(ricoh619);
-err_add_devs:
-       if (client->irq)
-               ricoh619_irq_exit(ricoh619);
-err_irq_init:
-       kfree(ricoh619);
        return ret;
 }
 
-static int  __devexit ricoh619_i2c_remove(struct i2c_client *client)
+static int ricoh619_i2c_remove(struct i2c_client *client)
 {
        struct ricoh619 *ricoh619 = i2c_get_clientdata(client);
-
-       if (client->irq)
-               ricoh619_irq_exit(ricoh619);
-
        ricoh619_remove_subdevs(ricoh619);
-       kfree(ricoh619);
        return 0;
 }
 
 #ifdef CONFIG_PM
 static int ricoh619_i2c_suspend(struct i2c_client *client, pm_message_t state)
 {
-       if (client->irq)
-               disable_irq(client->irq);
+//     if (g_ricoh619->chip_irq)
+//             disable_irq(g_ricoh619->chip_irq);
+//     printk("PMU: %s: \n",__func__);
        return 0;
 }
 
@@ -808,15 +869,13 @@ static int ricoh619_i2c_resume(struct i2c_client *client)
 {
        uint8_t reg_val;
        int ret;
-
        ret = __ricoh619_read(client, RICOH619_INT_IR_SYS, &reg_val);
        if(reg_val & 0x01) { //If PWR_KEY wakeup
 //             printk("PMU: %s: PWR_KEY Wakeup\n",__func__);
                pwrkey_wakeup = 1;
                __ricoh619_write(client, RICOH619_INT_IR_SYS, 0x0); //Clear PWR_KEY IRQ
        }
-
-       enable_irq(client->irq);
+//     enable_irq(g_ricoh619->chip_irq);
        return 0;
 }
 
@@ -826,16 +885,25 @@ static const struct i2c_device_id ricoh619_i2c_id[] = {
        {"ricoh619", 0},
        {}
 };
-
 MODULE_DEVICE_TABLE(i2c, ricoh619_i2c_id);
 
+#ifdef CONFIG_OF
+static const struct of_device_id ricoh619_dt_match[] = {
+       { .compatible = "ricoh,ricoh619", },
+       {},
+};
+MODULE_DEVICE_TABLE(of, ricoh619_dt_match);
+#endif
+
+
 static struct i2c_driver ricoh619_i2c_driver = {
        .driver = {
                   .name = "ricoh619",
                   .owner = THIS_MODULE,
+                  .of_match_table = of_match_ptr(ricoh619_dt_match),
                   },
        .probe = ricoh619_i2c_probe,
-       .remove = __devexit_p(ricoh619_i2c_remove),
+       .remove = ricoh619_i2c_remove,
 #ifdef CONFIG_PM
        .suspend = ricoh619_i2c_suspend,
        .resume = ricoh619_i2c_resume,
old mode 100644 (file)
new mode 100755 (executable)
index e9e85f5..a59488a
@@ -64,6 +64,13 @@ config WM8350_POWER
           Say Y here to enable support for the power management unit
          provided by the Wolfson Microelectronics WM8350 PMIC.
 
+config BATTERY_RICOH619
+       tristate "Ricoh RC5T619 PMIC battery driver"
+       depends on MFD_RICOH619 && I2C && GENERIC_HARDIRQS
+       help
+         Say Y to enable support for the battery control of the Ricoh RC5T619
+         Power Management device.
+
 config TEST_POWER
        tristate "Test power driver"
        help
old mode 100644 (file)
new mode 100755 (executable)
index dfe34f6..4dc7f07
@@ -56,5 +56,6 @@ obj-$(CONFIG_POWER_AVS)               += avs/
 obj-$(CONFIG_CHARGER_SMB347)   += smb347-charger.o
 obj-$(CONFIG_CHARGER_TPS65090) += tps65090-charger.o
 obj-$(CONFIG_CW2015_BATTERY)  += cw2015_battery.o
+obj-$(CONFIG_BATTERY_RICOH619) += ricoh619-battery.o
 obj-$(CONFIG_CHARGER_DISPLAY)          += rk29_charger_display.o
 obj-$(CONFIG_POWER_RESET)      += reset/
old mode 100644 (file)
new mode 100755 (executable)
index ecab67f..8bfc7d6
@@ -19,6 +19,9 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  *
  */
+#define RICOH619_BATTERY_VERSION "RICOH619_BATTERY_VERSION: 2014.03.28"
+
+
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/power/ricoh61x_battery_init.h>
 #include <linux/delay.h>
 #include <linux/workqueue.h>
-#include <linux/delay.h>
-#include <mach/board.h>
+#include <linux/of.h>
 
 
 #include <linux/interrupt.h>
 #include <linux/irq.h>
+#include <linux/irqdomain.h>
 
 
 /* define for function */
@@ -45,7 +48,7 @@
 #define ENABLE_FACTORY_MODE
 #define DISABLE_CHARGER_TIMER
 /* #define ENABLE_FG_KEEP_ON_MODE */
-#define ENABLE_OCV_TABLE_CALIB
+/* #define ENABLE_OCV_TABLE_CALIB */
 
 
 
@@ -78,12 +81,17 @@ enum int_type {
 #define RICOH619_GET_CHARGE_NUM                10
 #define RICOH619_UPDATE_COUNT_DISP             4
 #define RICOH619_UPDATE_COUNT_FULL             4
+#define RICOH619_UPDATE_COUNT_FULL_RESET       7
 #define RICOH619_CHARGE_UPDATE_TIME            3
-#define RICOH619_FULL_WAIT_TIME                        2
+#define RICOH619_FULL_WAIT_TIME                        4
 #define RE_CAP_GO_DOWN                         10      /* 40 */
 #define RICOH619_ENTER_LOW_VOL                 70
-#define RICOH619_TAH_SEL2                              5
-#define RICOH619_TAL_SEL2                              6
+#define RICOH619_TAH_SEL2                      5
+#define RICOH619_TAL_SEL2                      6
+
+#define RICOH619_OCV_OFFSET_BOUND      3
+#define RICOH619_OCV_OFFSET_RATIO      2
+
 /* define for FG status */
 enum {
        RICOH619_SOCA_START,
@@ -106,6 +114,7 @@ struct ricoh619_soca_info {
        int n_cap;
        int ocv_table_def[11];
        int ocv_table[11];
+       int ocv_table_low[11];
        int soc;                /* Latest FG SOC value */
        int displayed_soc;
        int suspend_soc;
@@ -114,26 +123,29 @@ struct ricoh619_soca_info {
        int chg_status;         /* chg_status */
        int soc_delta;          /* soc delta for status3(DISP) */
        int cc_delta;
+       int cc_cap_offset;
        int last_soc;
+       int last_displayed_soc;
        int ready_fg;
        int reset_count;
        int reset_soc[3];
-       int reset_flg_90;
-       int reset_flg_95;
-       int f_chg_margin;
        int chg_cmp_times;
        int dischg_state;
        int Vbat[RICOH619_GET_CHARGE_NUM];
        int Vsys[RICOH619_GET_CHARGE_NUM];
        int Ibat[RICOH619_GET_CHARGE_NUM];
        int Vbat_ave;
+       int Vbat_old;
        int Vsys_ave;
        int Ibat_ave;
        int chg_count;
-       int update_count;
+       int full_reset_count;
+       int soc_full;
+       int fc_cap;
        /* for LOW VOL state */
        int target_use_cap;
        int hurry_up_flg;
+       int zero_flg;
        int re_cap_old;
        int cutoff_ocv;
        int Rsys;
@@ -142,6 +154,10 @@ struct ricoh619_soca_info {
        int jt_limit;
        int OCV100_min;
        int OCV100_max;
+       int R_low;
+       int rsoc_ready_flag;
+       int init_pswr;
+       int last_cc_sum;
 };
 
 struct ricoh619_battery_info {
@@ -199,6 +215,7 @@ struct ricoh619_battery_info {
        int             ch_icchg;
        int             fg_target_vsys;
        int             fg_target_ibat;
+       int             fg_poff_vbat;
        int             jt_en;
        int             jt_hw_sw;
        int             jt_temp_h;
@@ -211,16 +228,19 @@ struct ricoh619_battery_info {
        int             num;
        };
 
+struct power_supply powerac;
+struct power_supply powerusb;
+
+int g_full_flag;
 int charger_irq;
 /* this value is for mfd fucntion */
 int g_soc;
 int g_fg_on_mode;
-extern int dwc_vbus_status(void);
+int type_n;
+extern int dwc_otg_check_dpdm(bool wait);
 /*This is for full state*/
-int g_full_flag;
 static int BatteryTableFlagDef=0;
 static int BatteryTypeDef=0;
-static void ricoh619_scaling_OCV_table(struct ricoh619_battery_info *info, int cutoff_vol, int full_vol, int *start_per, int *end_per);
 static int Battery_Type(void)
 {
        return BatteryTypeDef;
@@ -253,14 +273,17 @@ static int get_check_fuel_gauge_reg(struct ricoh619_battery_info *info,
                                         int Reg_h, int Reg_l, int enable_bit);
 static int calc_capacity_in_period(struct ricoh619_battery_info *info,
                                 int *cc_cap, bool *is_charging, bool cc_rst);
-static int get_charge_priority(struct ricoh619_battery_info *info, bool *data);
-static int set_charge_priority(struct ricoh619_battery_info *info, bool *data);
+//static int get_charge_priority(struct ricoh619_battery_info *info, bool *data);
+//static int set_charge_priority(struct ricoh619_battery_info *info, bool *data);
 static int get_power_supply_status(struct ricoh619_battery_info *info);
+static int get_power_supply_Android_status(struct ricoh619_battery_info *info);
 static int measure_vsys_ADC(struct ricoh619_battery_info *info, int *data);
 static int Calc_Linear_Interpolation(int x0, int y0, int x1, int y1, int y);
 static int get_battery_temp(struct ricoh619_battery_info *info);
 static int get_battery_temp_2(struct ricoh619_battery_info *info);
 static int check_jeita_status(struct ricoh619_battery_info *info, bool *is_jeita_updated);
+static void ricoh619_scaling_OCV_table(struct ricoh619_battery_info *info, int cutoff_vol, int full_vol, int *start_per, int *end_per);
+static int ricoh619_Check_OCV_Offset(struct ricoh619_battery_info *info);
 
 static int calc_ocv(struct ricoh619_battery_info *info)
 {
@@ -277,18 +300,213 @@ static int calc_ocv(struct ricoh619_battery_info *info)
        return ocv;
 }
 
+
+static int set_Rlow(struct ricoh619_battery_info *info)
+{
+       int err;
+       int Rbat_low_max;
+       uint8_t val;
+       int Vocv;
+       int temp;
+
+       if (info->soca->Rbat == 0)
+                       info->soca->Rbat = get_OCV_init_Data(info, 12) * 1000 / 512
+                                                        * 5000 / 4095;
+       
+       Vocv = calc_ocv(info);
+       Rbat_low_max = info->soca->Rbat * 1.5;
+
+       if (Vocv < get_OCV_voltage(info,3))
+       {
+               info->soca->R_low = Calc_Linear_Interpolation(info->soca->Rbat,get_OCV_voltage(info,3),
+                       Rbat_low_max, get_OCV_voltage(info,0), Vocv);
+               RICOH_FG_DBG("PMU: Modify RBAT from %d to %d ", info->soca->Rbat, info->soca->R_low);
+               temp = info->soca->R_low *4095/5000*512/1000;
+               
+               val = info->soca->R_low>>8;
+               err = ricoh619_write_bank1(info->dev->parent, 0xD4, val);
+               if (err < 0) {
+                       dev_err(info->dev, "batterry initialize error\n");
+                       return err;
+               }
+
+               val = info->soca->R_low & 0xff;
+               err = ricoh619_write_bank1(info->dev->parent, 0xD5, val);
+               if (err < 0) {
+                       dev_err(info->dev, "batterry initialize error\n");
+                       return err;
+               }
+       }
+       else  info->soca->R_low = 0;
+               
+
+       return err;
+}
+
+static int Set_back_ocv_table(struct ricoh619_battery_info *info)
+{
+       int err;
+       uint8_t val;
+       int temp;
+       int i;
+       uint8_t debug_disp[22];
+
+       /* Modify back ocv table */
+
+       if (0 != info->soca->ocv_table_low[0])
+       {
+               for (i = 0 ; i < 11; i++){
+                       battery_init_para[info->num][i*2 + 1] = info->soca->ocv_table_low[i];
+                       battery_init_para[info->num][i*2] = info->soca->ocv_table_low[i] >> 8;
+               }
+               err = ricoh619_clr_bits(info->dev->parent, FG_CTRL_REG, 0x01);
+
+               err = ricoh619_bulk_writes_bank1(info->dev->parent,
+                       BAT_INIT_TOP_REG, 22, battery_init_para[info->num]);
+
+               err = ricoh619_set_bits(info->dev->parent, FG_CTRL_REG, 0x01);
+
+               /* debug comment start*/
+               err = ricoh619_bulk_reads_bank1(info->dev->parent,
+                       BAT_INIT_TOP_REG, 22, debug_disp);
+               for (i = 0; i < 11; i++){
+                       RICOH_FG_DBG("PMU : %s : after OCV table %d 0x%x\n",__func__, i * 10, (debug_disp[i*2] << 8 | debug_disp[i*2+1]));
+               }
+               /* end */
+               /* clear table*/
+               for(i = 0; i < 11; i++)
+               {
+                       info->soca->ocv_table_low[i] = 0;
+               }
+       }
+       
+       /* Modify back Rbat */
+       if (0!=info->soca->R_low)
+       {               
+               RICOH_FG_DBG("PMU: Modify back RBAT from %d to %d ",  info->soca->R_low,info->soca->Rbat);
+               temp = info->soca->Rbat*4095/5000*512/1000;
+               
+               val = info->soca->R_low>>8;
+               err = ricoh619_write_bank1(info->dev->parent, 0xD4, val);
+               if (err < 0) {
+                       dev_err(info->dev, "batterry initialize error\n");
+                       return err;
+               }
+
+               val = info->soca->R_low & 0xff;
+               err = ricoh619_write_bank1(info->dev->parent, 0xD5, val);
+               if (err < 0) {
+                       dev_err(info->dev, "batterry initialize error\n");
+                       return err;
+               }
+
+               info->soca->R_low = 0;
+       }
+       return 0;
+}
+
+/**
+**/
+static int ricoh619_Check_OCV_Offset(struct ricoh619_battery_info *info)
+{
+       int ocv_table[11]; // HEX value
+       int i;
+       int temp;
+       int ret;
+       uint8_t debug_disp[22];
+       uint8_t val = 0;
+
+       RICOH_FG_DBG("PMU : %s : calc ocv %d get OCV %d\n",__func__,calc_ocv(info),get_OCV_voltage(info, RICOH619_OCV_OFFSET_BOUND));
+
+       /* check adp/usb status */
+       ret = ricoh619_read(info->dev->parent, CHGSTATE_REG, &val);
+       if (ret < 0) {
+               dev_err(info->dev, "Error in reading the control register\n");
+               return ret;
+       }
+
+       val = (val & 0xC0) >> 6;
+
+       if (val != 0){ /* connect adp or usb */
+               if (calc_ocv(info) < get_OCV_voltage(info, RICOH619_OCV_OFFSET_BOUND) )
+               {
+                       if(0 == info->soca->ocv_table_low[0]){
+                               for (i = 0 ; i < 11; i++){
+                               ocv_table[i] = (battery_init_para[info->num][i*2]<<8) | (battery_init_para[info->num][i*2+1]);
+                               RICOH_FG_DBG("PMU : %s : OCV table %d 0x%x\n",__func__,i * 10, ocv_table[i]);
+                               info->soca->ocv_table_low[i] = ocv_table[i];
+                               }
+
+                               for (i = 0 ; i < 11; i++){
+                                       temp = ocv_table[i] * (100 + RICOH619_OCV_OFFSET_RATIO) / 100;
+
+                                       battery_init_para[info->num][i*2 + 1] = temp;
+                                       battery_init_para[info->num][i*2] = temp >> 8;
+                               }
+                               ret = ricoh619_clr_bits(info->dev->parent, FG_CTRL_REG, 0x01);
+
+                               ret = ricoh619_bulk_writes_bank1(info->dev->parent,
+                                       BAT_INIT_TOP_REG, 22, battery_init_para[info->num]);
+
+                               ret = ricoh619_set_bits(info->dev->parent, FG_CTRL_REG, 0x01);
+
+                               /* debug comment start*/
+                               ret = ricoh619_bulk_reads_bank1(info->dev->parent,
+                                       BAT_INIT_TOP_REG, 22, debug_disp);
+                               for (i = 0; i < 11; i++){
+                                       RICOH_FG_DBG("PMU : %s : after OCV table %d 0x%x\n",__func__, i * 10, (debug_disp[i*2] << 8 | debug_disp[i*2+1]));
+                               }
+                               /* end */
+                       }
+               }
+       }
+       
+       return 0;
+}
+
+static int reset_FG_process(struct ricoh619_battery_info *info)
+{
+       int err;
+
+       //err = set_Rlow(info);
+       //err = ricoh619_Check_OCV_Offset(info);
+       err = ricoh619_write(info->dev->parent,
+                                        FG_CTRL_REG, 0x51);
+       info->soca->ready_fg = 0;
+       return err;
+}
+
+
 static int check_charge_status_2(struct ricoh619_battery_info *info, int displayed_soc_temp)
 {
        if (displayed_soc_temp < 0)
                        displayed_soc_temp = 0;
        
        get_power_supply_status(info);
-       /* for issue 5 */
+       info->soca->soc = calc_capacity(info) * 100;
+
        if (POWER_SUPPLY_STATUS_FULL == info->soca->chg_status) {
-               g_full_flag = 1;
-               info->soca->displayed_soc = 100*100;
+               if ((info->first_pwon == 1)
+                       && (RICOH619_SOCA_START == info->soca->status)) {
+                               g_full_flag = 1;
+                               info->soca->soc_full = info->soca->soc;
+                               info->soca->displayed_soc = 100*100;
+                               info->soca->full_reset_count = 0;
+               } else {
+                       if ( (displayed_soc_temp > 97*100)
+                               && (calc_ocv(info) > (get_OCV_voltage(info, 9) + (get_OCV_voltage(info, 10) - get_OCV_voltage(info, 9))*7/10)  )){
+                               g_full_flag = 1;
+                               info->soca->soc_full = info->soca->soc;
+                               info->soca->displayed_soc = 100*100;
+                               info->soca->full_reset_count = 0;
+                       } else {
+                               g_full_flag = 0;
+                               info->soca->displayed_soc = displayed_soc_temp;
+                       }
+
+               }
        }
-       if (info->soca->Ibat_ave >= 0) {        /* for issue 3 */
+       if (info->soca->Ibat_ave >= 0) {
                if (g_full_flag == 1) {
                        info->soca->displayed_soc = 100*100;
                } else {
@@ -301,10 +519,10 @@ static int check_charge_status_2(struct ricoh619_battery_info *info, int display
        }
        if (info->soca->Ibat_ave < 0) {
                if (g_full_flag == 1) {
-                       if ((calc_ocv(info) < (get_OCV_voltage(info, 9) + (get_OCV_voltage(info, 10) - get_OCV_voltage(info, 9))*3/10) )
-                       && (info->soca->soc/100 <= 98) ) {
+                       if (calc_ocv(info) < (get_OCV_voltage(info, 9) + (get_OCV_voltage(info, 10) - get_OCV_voltage(info, 9))*7/10)  ) {
                                g_full_flag = 0;
-                               info->soca->displayed_soc = 100*100;
+                               //info->soca->displayed_soc = 100*100;
+                               info->soca->displayed_soc = displayed_soc_temp;
                        } else {
                                info->soca->displayed_soc = 100*100;
                        }
@@ -333,15 +551,18 @@ static int calc_capacity_in_period(struct ricoh619_battery_info *info,
                                 int *cc_cap, bool *is_charging, bool cc_rst)
 {
        int err;
-       uint8_t cc_sum_reg[4];
-       uint8_t cc_clr[4] = {0, 0, 0, 0};
-       uint8_t fa_cap_reg[2];
-       uint16_t fa_cap;
-       uint32_t cc_sum;
-       int     cc_stop_flag;
-       uint8_t status;
-       uint8_t charge_state;
-       int Ocv;
+       uint8_t         cc_sum_reg[4];
+       uint8_t         cc_clr[4] = {0, 0, 0, 0};
+       uint8_t         fa_cap_reg[2];
+       uint16_t        fa_cap;
+       uint32_t        cc_sum;
+       int             cc_stop_flag;
+       uint8_t         status;
+       uint8_t         charge_state;
+       int             Ocv;
+       uint32_t        cc_cap_temp;
+       uint32_t        cc_cap_min;
+       int             cc_cap_res;
 
        *is_charging = true;    /* currrent state initialize -> charging */
 
@@ -448,9 +669,34 @@ static int calc_capacity_in_period(struct ricoh619_battery_info *info,
                cc_sum = (cc_sum^0xffffffff)+0x01;
                *is_charging = false;           /* discharge */
        }
+       /* (CC_SUM x 10000)/3600/FA_CAP */
+       *cc_cap = cc_sum*25/9/fa_cap;           /* unit is 0.01% */
 
-       *cc_cap = cc_sum*25/9/fa_cap;   /* CC_SUM/3600/FA_CAP */
-
+       //////////////////////////////////////////////////////////////////      
+       cc_cap_min = fa_cap*3600/100/100/100;   /* Unit is 0.0001% */
+       cc_cap_temp = cc_sum / cc_cap_min;
+               
+       cc_cap_res = cc_cap_temp % 100;
+       
+       RICOH_FG_DBG("PMU: cc_sum = %d: cc_cap_res= %d: \n", cc_sum, cc_cap_res);
+       
+       
+       if(*is_charging) {
+               info->soca->cc_cap_offset += cc_cap_res;
+               if (info->soca->cc_cap_offset >= 100) {
+                       *cc_cap += 1;
+                       info->soca->cc_cap_offset %= 100;
+               }
+       } else {
+               info->soca->cc_cap_offset -= cc_cap_res;
+               if (info->soca->cc_cap_offset <= -100) {
+                       *cc_cap += 1;
+                       info->soca->cc_cap_offset %= 100;
+               }
+       }
+       RICOH_FG_DBG("PMU: cc_cap_offset= %d: \n", info->soca->cc_cap_offset);
+       
+       //////////////////////////////////////////////////////////////////
        return 0;
 out:
        dev_err(info->dev, "Error !!-----\n");
@@ -461,10 +707,10 @@ out:
 **/
 static int get_target_use_cap(struct ricoh619_battery_info *info)
 {
-       int i;
+       int i,j;
        int ocv_table[11];
        int temp;
-       int Target_Cutoff_Vol;
+       int Target_Cutoff_Vol = 0;
        int Ocv_ZeroPer_now;
        int Ibat_now;
        int fa_cap,use_cap;
@@ -474,6 +720,12 @@ static int get_target_use_cap(struct ricoh619_battery_info *info)
        int CC_OnePer_step;
        int Ibat_min;
 
+       int Ocv_now;
+       int Ocv_now_table;
+       int soc_per;
+       int use_cap_now;
+       int Rsys_now;
+
        /* get const value */
        Ibat_min = -1 * info->soca->target_ibat;
        if (info->soca->Ibat_ave > Ibat_min) /* I bat is minus */
@@ -485,22 +737,37 @@ static int get_target_use_cap(struct ricoh619_battery_info *info)
        fa_cap = get_check_fuel_gauge_reg(info, FA_CAP_H_REG, FA_CAP_L_REG,
                                                                0x7fff);
        use_cap = fa_cap - info->soca->re_cap_old;
-       
-       Ocv_ZeroPer_now = info->soca->target_vsys * 1000 - Ibat_now * info->soca->Rsys;
-
-       RICOH_FG_DBG("PMU: -------  Rsys= %d: cutoff_ocv= %d: Ocv_ZeroPer_now= %d =======\n",
-              info->soca->Rsys, info->soca->cutoff_ocv, Ocv_ZeroPer_now);
 
-       /* get FA_CAP_now */
-       /* Check Start % */
+       /* get OCV table % */
        for (i = 0; i <= 10; i = i+1) {
                temp = (battery_init_para[info->num][i*2]<<8)
                         | (battery_init_para[info->num][i*2+1]);
                /* conversion unit 1 Unit is 1.22mv (5000/4095 mv) */
                temp = ((temp * 50000 * 10 / 4095) + 5) / 10;
                ocv_table[i] = temp;
+               RICOH_FG_DBG("PMU : %s : ocv_table %d is %d v\n",__func__, i, ocv_table[i]);
        }
+
+       /* Find out Current OCV */
+       i = info->soca->soc/1000;
+       j = info->soca->soc - info->soca->soc/1000*1000;
+       Ocv_now_table = ocv_table[i]*100+(ocv_table[i+1]-ocv_table[i])*j/10;
+
+               Rsys_now = (info->soca->Vsys_ave - Ocv_now_table) / info->soca->Ibat_ave;       
+
+       Ocv_ZeroPer_now = info->soca->target_vsys * 1000 - Ibat_now * Rsys_now;
+
+       RICOH_FG_DBG("PMU: -------  Ocv_now_table= %d: Rsys_now= %d =======\n",
+              Ocv_now_table, Rsys_now);
+
+       RICOH_FG_DBG("PMU: -------  Rsys= %d: cutoff_ocv= %d: Ocv_ZeroPer_now= %d =======\n",
+              info->soca->Rsys, info->soca->cutoff_ocv, Ocv_ZeroPer_now);
+
+       /* get FA_CAP_now */
+
+       
        for (i = 1; i < 11; i++) {
+               RICOH_FG_DBG("PMU : %s : ocv_table %d is %d v Ocv_ZerPernow is %d\n",__func__, i, ocv_table[i],(Ocv_ZeroPer_now / 100));
                if (ocv_table[i] >= Ocv_ZeroPer_now / 100) {
                        /* unit is 0.001% */
                        start_per = Calc_Linear_Interpolation(
@@ -510,6 +777,8 @@ static int get_target_use_cap(struct ricoh619_battery_info *info)
                }
        }
 
+       start_per = max(0, start_per);
+
        FA_CAP_now = fa_cap * ((10000 - start_per) / 100 ) / 100;
 
        RICOH_FG_DBG("PMU: -------  Target_Cutoff_Vol= %d: Ocv_ZeroPer_now= %d: start_per= %d =======\n",
@@ -518,22 +787,31 @@ static int get_target_use_cap(struct ricoh619_battery_info *info)
        /* get RE_CAP_now */
        RE_CAP_now = FA_CAP_now - use_cap;
        
-       if (RE_CAP_now < RE_CAP_GO_DOWN || info->soca->Vsys_ave < info->soca->target_vsys*1000) {
+       if (RE_CAP_now < RE_CAP_GO_DOWN) {
                info->soca->hurry_up_flg = 1;
-       } else {
-               info->soca->hurry_up_flg = 0;
-               /* get CC_OnePer_step */
-               if (info->soca->displayed_soc > 0) { /* avoid divide-by-0 */
-                       CC_OnePer_step = RE_CAP_now / (info->soca->displayed_soc / 100);
+       } else if (info->soca->Vsys_ave < info->soca->target_vsys*1000) {
+               info->soca->hurry_up_flg = 1;
+       } else if (info->fg_poff_vbat != 0) {
+               if (info->soca->Vbat_ave < info->fg_poff_vbat*1000) {
+                       info->soca->hurry_up_flg = 1;
                } else {
-                       CC_OnePer_step = 0;
+                       info->soca->hurry_up_flg = 0;
                }
-               /* get info->soca->target_use_cap */
-               info->soca->target_use_cap = use_cap + CC_OnePer_step;
+       } else {
+               info->soca->hurry_up_flg = 0;
+       }
+
+       /* get CC_OnePer_step */
+       if (info->soca->displayed_soc > 0) { /* avoid divide-by-0 */
+               CC_OnePer_step = RE_CAP_now / (info->soca->displayed_soc / 100 + 1);
+       } else {
+               CC_OnePer_step = 0;
        }
+       /* get info->soca->target_use_cap */
+       info->soca->target_use_cap = use_cap + CC_OnePer_step;
        
-       RICOH_FG_DBG("PMU: -------  FA_CAP_now= %d: RE_CAP_now= %d: target_use_cap= %d: hurry_up_flg= %d -------\n",
-              FA_CAP_now, RE_CAP_now, info->soca->target_use_cap, info->soca->hurry_up_flg);
+       RICOH_FG_DBG("PMU: ------- FA_CAP_now= %d: RE_CAP_now= %d: CC_OnePer_step= %d: target_use_cap= %d: hurry_up_flg= %d -------\n",
+              FA_CAP_now, RE_CAP_now, CC_OnePer_step, info->soca->target_use_cap, info->soca->hurry_up_flg);
        
        return 0;
 }
@@ -550,7 +828,8 @@ static int calib_ocvTable(struct ricoh619_battery_info *info, int vbat_ocv)
        int cutoff_ocv;
        int i;
        int ocv100_new;
-       int start_per,end_per;
+       int start_per = 0;
+       int end_per = 0;
        
        RICOH_FG_DBG("PMU: %s\n", __func__);
        
@@ -577,7 +856,6 @@ static int calib_ocvTable(struct ricoh619_battery_info *info, int vbat_ocv)
                goto err;
        }
 
-       info->soca->ready_fg = 0;
 
        //cutoff_ocv = (battery_init_para[info->num][0]<<8) | (battery_init_para[info->num][1]);
        cutoff_ocv = get_OCV_voltage(info, 0);
@@ -600,14 +878,14 @@ static int calib_ocvTable(struct ricoh619_battery_info *info, int vbat_ocv)
        }
        
        /* FG_En on & Reset*/
-       ret = ricoh619_write(info->dev->parent, FG_CTRL_REG, 0x51);
+       ret = reset_FG_process(info);
        if (ret < 0) {
                dev_err("PMU: %s Error in FG_En On & Reset\n", __func__);
                goto err;
        }
 
        RICOH_FG_DBG("PMU: %s Exit \n", __func__);
-       return 0;                       
+       return 0;
 err:
        return ret;
 
@@ -626,16 +904,15 @@ static void ricoh619_displayed_work(struct work_struct *work)
        int disp_dec;
        int cc_cap = 0;
        bool is_charging = true;
-       int i;
        int re_cap,fa_cap,use_cap;
        bool is_jeita_updated;
        uint8_t reg_val;
        int delay_flag = 0;
        int Vbat = 0;
        int Ibat = 0;
-       int ret;
-       int ocv;
+       int Vsys = 0;
        int temp_ocv;
+       int fc_delta = 0;
 
        struct ricoh619_battery_info *info = container_of(work,
        struct ricoh619_battery_info, displayed_work.work);
@@ -656,7 +933,7 @@ static void ricoh619_displayed_work(struct work_struct *work)
                 || (RICOH619_SOCA_FULL == info->soca->status))
                info->soca->ready_fg = 1;
 
-       /* judege Full state or Moni Vsys state */
+       /* judge Full state or Moni Vsys state */
        if ((RICOH619_SOCA_DISP == info->soca->status)
                 || (RICOH619_SOCA_STABLE == info->soca->status))
        {
@@ -664,31 +941,26 @@ static void ricoh619_displayed_work(struct work_struct *work)
                temp_ocv = get_OCV_voltage(info, 10) -
                                        (get_OCV_voltage(info, 10) - get_OCV_voltage(info, 9))/2;
                
-               if ((POWER_SUPPLY_STATUS_FULL == info->soca->chg_status)
-                       && (calc_ocv(info) > temp_ocv)) {
+               if(g_full_flag == 1){   /* for issue 1 solution start*/
                        info->soca->status = RICOH619_SOCA_FULL;
-                       info->soca->update_count = 0;
-               }
-               /* for issue 1 solution start*/
-               if(g_full_flag == 1){
+               }else if ((POWER_SUPPLY_STATUS_FULL == info->soca->chg_status)
+                       && (calc_ocv(info) > temp_ocv)) {
                        info->soca->status = RICOH619_SOCA_FULL;
-                       info->soca->update_count = 0;
-               }
-               /* for issue1 solution end */
-               /* check Full state or not*/
-               if (info->soca->Ibat_ave >= -20) {
+                       g_full_flag = 0;
+               } else if (info->soca->Ibat_ave >= -20) {
+                       /* for issue1 solution end */
+                       /* check Full state or not*/
                        if ((calc_ocv(info) > (get_OCV_voltage(info, 9) + (get_OCV_voltage(info, 10) - get_OCV_voltage(info, 9))*7/10))
-                               || (info->soca->displayed_soc/100 >= 99))
+                               || (POWER_SUPPLY_STATUS_FULL == info->soca->chg_status)
+                               || (info->soca->displayed_soc > 9850))
                        {
-                               g_full_flag = 0;
                                info->soca->status = RICOH619_SOCA_FULL;
-                               info->soca->update_count = 0;
+                               g_full_flag = 0;
                        } else if ((calc_ocv(info) > (get_OCV_voltage(info, 9)))
                                && (info->soca->Ibat_ave < 300))
                        {
-                               g_full_flag = 0;
                                info->soca->status = RICOH619_SOCA_FULL;
-                               info->soca->update_count = 0;
+                               g_full_flag = 0;
                        }
                } else { /* dis-charging */
                        if (info->soca->displayed_soc/100 < RICOH619_ENTER_LOW_VOL) {
@@ -700,68 +972,8 @@ static void ricoh619_displayed_work(struct work_struct *work)
 
        if (RICOH619_SOCA_STABLE == info->soca->status) {
                info->soca->soc = calc_capacity_2(info);
-               soc_round = info->soca->soc / 100;
-               last_soc_round = info->soca->last_soc / 100;
-
                info->soca->soc_delta = info->soca->soc - info->soca->last_soc;
 
-               //get charge status
-               if (info->soca->chg_status == POWER_SUPPLY_STATUS_CHARGING) {
-                       if (soc_round >= 90) {
-                               if(soc_round < 95) {
-                                       if (info->soca->reset_flg_90 == 0) {
-                                               err = ricoh619_write(info->dev->parent,
-                                                FG_CTRL_REG, 0x51);
-                                               if (err< 0)
-                                                       dev_err(info->dev, "Error in writing the control register\n");
-
-                                               info->soca->ready_fg = 0;
-
-                                               for (i = 0; i < 3; i = i+1) {
-                                                       info->soca->reset_soc[i] = 0;
-                                               }
-                                               info->soca->stable_count = 0;
-
-                                               info->soca->status = RICOH619_SOCA_FG_RESET;
-                                               /* Delay for addition Reset Time (6s) */
-                                               info->soca->stable_count = 1;
-                                               queue_delayed_work(info->monitor_wqueue,
-                                                               &info->charge_stable_work,
-                                                               RICOH619_FG_RESET_TIME*HZ);
-
-                                               info->soca->reset_flg_90 = 1;
-                                               goto end_flow;
-                                       }
-                               } else if (soc_round < 100) {
-                                       if (info->soca->reset_flg_95 == 0) {
-                                               err = ricoh619_write(info->dev->parent,
-                                                FG_CTRL_REG, 0x51);
-                                               if (err < 0)
-                                                       dev_err(info->dev, "Error in writing the control register\n");
-
-                                               info->soca->ready_fg = 0;
-
-                                               for (i = 0; i < 3; i = i+1) {
-                                                       info->soca->reset_soc[i] = 0;
-                                               }
-
-                                               info->soca->stable_count = 0;
-                                               info->soca->status = RICOH619_SOCA_FG_RESET;
-                                               info->soca->stable_count = 1;
-                                               queue_delayed_work(info->monitor_wqueue,
-                                                               &info->charge_stable_work,
-                                                               RICOH619_FG_RESET_TIME*HZ);
-
-                                               info->soca->reset_flg_95 = 1;
-                                               goto end_flow;
-                                       }
-                               }
-                       } else {
-                               info->soca->reset_flg_90 = 0;
-                               info->soca->reset_flg_95 = 0;
-                       }
-               }
-
                if (info->soca->soc_delta >= -100 && info->soca->soc_delta <= 100) {
                        info->soca->displayed_soc = info->soca->soc;
                } else {
@@ -781,34 +993,55 @@ static void ricoh619_displayed_work(struct work_struct *work)
                if (info->soca->Ibat_ave >= -20) { /* charging */
                        if (0 == info->soca->jt_limit) {
                                if (g_full_flag == 1) {
-                                       /* caluc 95% ocv */
-                                       //temp_ocv = get_OCV_voltage(info, 10) -
-                                       //                      (get_OCV_voltage(info, 10) - get_OCV_voltage(info, 9))/2;
-                                       temp_ocv = get_OCV_voltage(info, 9);
-                                       info->soca->update_count++;
-                                       info->soca->chg_cmp_times = 0;
-                                       if (info->soca->update_count >= RICOH619_UPDATE_COUNT_FULL) {
-                                               if (calc_ocv(info) < temp_ocv) {
-                                                       if(info->soca->displayed_soc > info->soca->soc) {
-                                                               info->soca->displayed_soc = info->soca->displayed_soc - 1;
-                                                       } else {
-                                                               info->soca->displayed_soc = info->soca->soc;
-                                                       }
-                                               } else {
-                                                       info->soca->displayed_soc = 100*100;
+                                       
+                                       if (POWER_SUPPLY_STATUS_FULL == info->soca->chg_status) {
+                                               if(info->soca->full_reset_count < RICOH619_UPDATE_COUNT_FULL_RESET) {
+                                                       info->soca->full_reset_count++;
+                                               } else if (info->soca->full_reset_count < (RICOH619_UPDATE_COUNT_FULL_RESET + 1)) {
+                                                       err = reset_FG_process(info);
+                                                       if (err < 0)
+                                                               dev_err(info->dev, "Error in writing the control register\n");
+                                                       info->soca->full_reset_count++;
+                                                       goto end_flow;
+                                               } else if(info->soca->full_reset_count < (RICOH619_UPDATE_COUNT_FULL_RESET + 2)) {
+                                                       info->soca->full_reset_count++;
+                                                       info->soca->fc_cap = 0;
+                                                       info->soca->soc_full = info->soca->soc;
+                                               }
+                                       } else {
+                                               if(info->soca->fc_cap < -1 * 200) {
+                                                       g_full_flag = 0;
+                                                       info->soca->displayed_soc = 99 * 100;
                                                }
-                                               info->soca->update_count = 0;
+                                               info->soca->full_reset_count = 0;
+                                       }
+                                       
+
+                                       info->soca->chg_cmp_times = 0;
+                                       err = calc_capacity_in_period(info, &cc_cap, &is_charging, true);
+                                       if (err < 0)
+                                       dev_err(info->dev, "Read cc_sum Error !!-----\n");
+
+                                       fc_delta = (is_charging == true) ? cc_cap : -cc_cap;
+
+                                       info->soca->fc_cap = info->soca->fc_cap + fc_delta;
+
+                                       if (g_full_flag == 1){
+                                               info->soca->displayed_soc = 100*100;
                                        }
                                } else {
                                        if (calc_ocv(info) < (get_OCV_voltage(info, 8))) { /* fail safe*/
                                                g_full_flag = 0;
                                                info->soca->status = RICOH619_SOCA_DISP;
                                                info->soca->soc_delta = 0;
-                                       } else if (POWER_SUPPLY_STATUS_FULL == info->soca->chg_status) {
-                                               if(info->soca->chg_cmp_times >= RICOH619_FULL_WAIT_TIME) {
+                                       } else if ((POWER_SUPPLY_STATUS_FULL == info->soca->chg_status) 
+                                               && (info->soca->displayed_soc >= 9890)){
+                                               if(info->soca->chg_cmp_times > RICOH619_FULL_WAIT_TIME) {
                                                        info->soca->displayed_soc = 100*100;
-                                                       info->soca->update_count = 0;
                                                        g_full_flag = 1;
+                                                       info->soca->full_reset_count = 0;
+                                                       info->soca->soc_full = info->soca->soc;
+                                                       info->soca->fc_cap = 0;
 #ifdef ENABLE_OCV_TABLE_CALIB
                                                        err = calib_ocvTable(info,calc_ocv(info));
                                                        if (err < 0)
@@ -818,31 +1051,56 @@ static void ricoh619_displayed_work(struct work_struct *work)
                                                        info->soca->chg_cmp_times++;
                                                }
                                        } else {
-                                               info->soca->chg_cmp_times = 0;
-                                               if (info->soca->displayed_soc/100 < 99) {
-                                                       info->soca->update_count++;
-                                                       if (info->soca->update_count
-                                                       >= RICOH619_UPDATE_COUNT_FULL) {
-                                                               info->soca->displayed_soc = info->soca->displayed_soc + 100;
-                                                               info->soca->update_count = 0;
+                                               fa_cap = get_check_fuel_gauge_reg(info, FA_CAP_H_REG, FA_CAP_L_REG,
+                                                       0x7fff);
+                                               
+                                               if (info->soca->displayed_soc >= 9950) {
+                                                       if((info->soca->soc_full - info->soca->soc) < 200) {
+                                                               goto end_flow;
                                                        }
-                                               } else {
+                                               }
+                                               info->soca->chg_cmp_times = 0;
+
+                                               err = calc_capacity_in_period(info, &cc_cap, &is_charging, true);
+                                               if (err < 0)
+                                               dev_err(info->dev, "Read cc_sum Error !!-----\n");
+                                               info->soca->cc_delta
+                                                        = (is_charging == true) ? cc_cap : -cc_cap;
+
+                                               if((POWER_SUPPLY_STATUS_FULL == info->soca->chg_status)
+                                               //      || (info->soca->Ibat_ave > 200))
+                                               || (info->soca->Ibat_ave < info->ch_icchg*50 + 100) || (info->soca->displayed_soc<9700))
+                                               {
+                                                       info->soca->displayed_soc += 13 * 3000 / fa_cap;
+                                               }
+                                               else {
+                                                       info->soca->displayed_soc
+                                                      = info->soca->displayed_soc + info->soca->cc_delta*8/10;
+                                               }
+                                               
+                                               info->soca->displayed_soc
+                                                        = min(10000, info->soca->displayed_soc);
+                                               info->soca->displayed_soc = max(0, info->soca->displayed_soc);
+
+                                               if (info->soca->displayed_soc >= 9890) {
                                                        info->soca->displayed_soc = 99 * 100;
-                                                       info->soca->update_count = 0;
                                                }
                                        }
                                }
                        } else {
-                               info->soca->update_count = 0;
+                               info->soca->full_reset_count = 0;
                        }
                } else { /* discharging */
-                       if (g_full_flag == 1) {
+                       if (info->soca->displayed_soc >= 9950) {
                                if (info->soca->Ibat_ave <= -1 * RICOH619_REL1_SEL_VALUE) {
                                        if ((calc_ocv(info) < (get_OCV_voltage(info, 9) + (get_OCV_voltage(info, 10) - get_OCV_voltage(info, 9))*3/10))
-                                               && (info->soca->soc/100 <= 98)) {
+                                               || ((info->soca->soc_full - info->soca->soc) > 200)) {
+
                                                g_full_flag = 0;
+                                               info->soca->full_reset_count = 0;
                                                info->soca->displayed_soc = 100 * 100;
                                                info->soca->status = RICOH619_SOCA_DISP;
+                                               info->soca->last_soc = info->soca->soc;
                                                info->soca->soc_delta = 0;
                                        } else {
                                                info->soca->displayed_soc = 100 * 100;
@@ -853,8 +1111,10 @@ static void ricoh619_displayed_work(struct work_struct *work)
                                                info->soca->displayed_soc = 100 * 100;
                                        } else {
                                                g_full_flag = 0;
+                                               info->soca->full_reset_count = 0;
                                                info->soca->displayed_soc = 100 * 100;
                                                info->soca->status = RICOH619_SOCA_DISP;
+                                               info->soca->last_soc = info->soca->soc;
                                                info->soca->soc_delta = 0;
                                        }
                                }
@@ -862,6 +1122,8 @@ static void ricoh619_displayed_work(struct work_struct *work)
                                g_full_flag = 0;
                                info->soca->status = RICOH619_SOCA_DISP;
                                info->soca->soc_delta = 0;
+                               info->soca->full_reset_count = 0;
+                               info->soca->last_soc = info->soca->soc;
                        }
                }
        } else if (RICOH619_SOCA_LOW_VOL == info->soca->status) {
@@ -899,8 +1161,8 @@ static void ricoh619_displayed_work(struct work_struct *work)
 
                info->soca->soc = calc_capacity_2(info);
 
-               soc_round = info->soca->soc / 100;
-               last_soc_round = info->soca->last_soc / 100;
+               soc_round = (info->soca->soc + 50) / 100;
+               last_soc_round = (info->soca->last_soc + 50) / 100;
                last_disp_round = (info->soca->displayed_soc + 50) / 100;
 
                info->soca->soc_delta =
@@ -931,7 +1193,7 @@ static void ricoh619_displayed_work(struct work_struct *work)
                                                if ((50 <= disp_dec) && (disp_dec <= 74))
                                                        info->soca->soc_delta = 0;
                                        }
-                                       if (info->soca->displayed_soc/100
+                                       if ((info->soca->displayed_soc + 50)/100
                                                                 >= soc_round) {
                                                info->soca->displayed_soc
                                                        = info->soca->soc ;
@@ -945,7 +1207,7 @@ static void ricoh619_displayed_work(struct work_struct *work)
                                                info->soca->displayed_soc += 100;
                                                info->soca->soc_delta -= 300;
                                        }
-                                       if (info->soca->displayed_soc/100
+                                       if ((info->soca->displayed_soc + 50)/100
                                                                 <= soc_round) {
                                                info->soca->displayed_soc
                                                        = info->soca->soc ;
@@ -973,7 +1235,7 @@ static void ricoh619_displayed_work(struct work_struct *work)
                                        if ((25 <= disp_dec) && (disp_dec <= 49))
                                                info->soca->soc_delta = 0;
                                }
-                               if (info->soca->displayed_soc/100
+                               if ((info->soca->displayed_soc + 50)/100
                                                         <= soc_round) {
                                        info->soca->displayed_soc
                                                = info->soca->soc ;
@@ -987,7 +1249,7 @@ static void ricoh619_displayed_work(struct work_struct *work)
                                        info->soca->displayed_soc -= 100;
                                        info->soca->soc_delta += 300;
                                }
-                               if (info->soca->displayed_soc/100
+                               if ((info->soca->displayed_soc + 50)/100
                                                         >= soc_round) {
                                        info->soca->displayed_soc
                                                = info->soca->soc ;
@@ -998,6 +1260,50 @@ static void ricoh619_displayed_work(struct work_struct *work)
                        }
                }
        } else if (RICOH619_SOCA_UNSTABLE == info->soca->status) {
+               /* caluc 95% ocv */
+               temp_ocv = get_OCV_voltage(info, 10) -
+                                       (get_OCV_voltage(info, 10) - get_OCV_voltage(info, 9))/2;
+               
+               if(g_full_flag == 1){   /* for issue 1 solution start*/
+                       info->soca->status = RICOH619_SOCA_FULL;
+                       err = reset_FG_process(info);
+                       if (err < 0)
+                               dev_err(info->dev, "Error in writing the control register\n");
+                       
+                       goto end_flow;
+               }else if ((POWER_SUPPLY_STATUS_FULL == info->soca->chg_status)
+                       && (calc_ocv(info) > temp_ocv)) {
+                       info->soca->status = RICOH619_SOCA_FULL;
+                       g_full_flag = 0;
+                       err = reset_FG_process(info);
+                       if (err < 0)
+                               dev_err(info->dev, "Error in writing the control register\n");
+                       goto end_flow;
+               } else if (info->soca->Ibat_ave >= -20) {
+                       /* for issue1 solution end */
+                       /* check Full state or not*/
+                       if ((calc_ocv(info) > (get_OCV_voltage(info, 9) + (get_OCV_voltage(info, 10) - get_OCV_voltage(info, 9))*7/10))
+                               || (POWER_SUPPLY_STATUS_FULL == info->soca->chg_status)
+                               || (info->soca->displayed_soc > 9850))
+                       {
+                               info->soca->status = RICOH619_SOCA_FULL;
+                               g_full_flag = 0;
+                               err = reset_FG_process(info);
+                               if (err < 0)
+                                       dev_err(info->dev, "Error in writing the control register\n");
+                               goto end_flow;
+                       } else if ((calc_ocv(info) > (get_OCV_voltage(info, 9)))
+                               && (info->soca->Ibat_ave < 300))
+                       {
+                               info->soca->status = RICOH619_SOCA_FULL;
+                               g_full_flag = 0;
+                               err = reset_FG_process(info);
+                               if (err < 0)
+                                       dev_err(info->dev, "Error in writing the control register\n");                          
+                               goto end_flow;
+                       }
+               }
+
                err = ricoh619_read(info->dev->parent, PSWR_REG, &val);
                val &= 0x7f;
                info->soca->soc = val * 100;
@@ -1021,17 +1327,23 @@ static void ricoh619_displayed_work(struct work_struct *work)
                if (displayed_soc_temp < 0)
                        displayed_soc_temp = 0;
                displayed_soc_temp
-                        = min(10000, displayed_soc_temp);
+                        = min(9850, displayed_soc_temp);
                displayed_soc_temp = max(0, displayed_soc_temp);
 
-               if (0 == info->soca->jt_limit) {
-                       check_charge_status_2(info, displayed_soc_temp);
-               } else {
-                       info->soca->displayed_soc = displayed_soc_temp;
-               }
+               info->soca->displayed_soc = displayed_soc_temp;
+
        } else if (RICOH619_SOCA_FG_RESET == info->soca->status) {
                /* No update */
        } else if (RICOH619_SOCA_START == info->soca->status) {
+
+               err = measure_Ibatt_FG(info, &Ibat);
+               err = measure_vbatt_FG(info, &Vbat);
+               err = measure_vsys_ADC(info, &Vsys);
+
+               info->soca->Ibat_ave = Ibat;
+               info->soca->Vbat_ave = Vbat;
+               info->soca->Vsys_ave = Vsys;
+
                err = check_jeita_status(info, &is_jeita_updated);
                is_jeita_updated = false;
                if (err < 0) {
@@ -1039,15 +1351,6 @@ static void ricoh619_displayed_work(struct work_struct *work)
                }
                err = ricoh619_read(info->dev->parent, PSWR_REG, &val);
                val &= 0x7f;
-               ////debug for Zero state///
-               ret = measure_vbatt_FG(info, &Vbat);
-               ret = measure_Ibatt_FG(info, &Ibat);
-               ocv = Vbat - Ibat * info->soca->Rbat;
-               RICOH_FG_DBG("Check ZERO state : Vbat %d, Ibat %d, ocv %d Rbat %d %d\n",Vbat,Ibat,ocv,info->soca->Rbat);
-               info->soca->soc = calc_capacity(info) * 100;
-               RICOH_FG_DBG("Check ZERO state : first_pwon %d, RSOC is %d OCV is %d\n",info->first_pwon,info->soca->soc/100,calc_ocv(info));
-               RICOH_FG_DBG("Check ZERO state : g_fg_on_mode %d, get ocv voltage %d\n",g_fg_on_mode,get_OCV_voltage(info, 0));
-               ///////////////////////////
                if (info->first_pwon) {
                        info->soca->soc = calc_capacity(info) * 100;
                        val = (info->soca->soc + 50)/100;
@@ -1067,7 +1370,22 @@ static void ricoh619_displayed_work(struct work_struct *work)
                                } else {
                                        info->soca->displayed_soc = info->soca->soc;
                                }
-                               info->soca->status = RICOH619_SOCA_UNSTABLE;
+                               if (Ibat < 0) {
+                                       if (info->soca->displayed_soc < 300) {
+                                               info->soca->target_use_cap = 0;
+                                               info->soca->status = RICOH619_SOCA_LOW_VOL;
+                                       } else {
+                                               if ((info->fg_poff_vbat != 0)
+                                                     && (Vbat < info->fg_poff_vbat * 1000) ){
+                                                         info->soca->target_use_cap = 0;
+                                                         info->soca->status = RICOH619_SOCA_LOW_VOL;
+                                                 } else { 
+                                                         info->soca->status = RICOH619_SOCA_UNSTABLE;
+                                                 }
+                                       }
+                               } else {
+                                       info->soca->status = RICOH619_SOCA_UNSTABLE;
+                               }
                        }
                } else if (g_fg_on_mode && (val == 0x7f)) {
                        info->soca->soc = calc_capacity(info) * 100;
@@ -1117,30 +1435,67 @@ static void ricoh619_displayed_work(struct work_struct *work)
                                        info->soca->displayed_soc = displayed_soc_temp;
                                }
                                info->soca->last_soc = calc_capacity(info) * 100;
-                               info->soca->status = RICOH619_SOCA_UNSTABLE;
+                               if (Ibat < 0) {
+                                       if (info->soca->displayed_soc < 300) {
+                                               info->soca->target_use_cap = 0;
+                                               info->soca->status = RICOH619_SOCA_LOW_VOL;
+                                       } else {
+                                               if ((info->fg_poff_vbat != 0)
+                                                     && (Vbat < info->fg_poff_vbat * 1000)){
+                                                         info->soca->target_use_cap = 0;
+                                                         info->soca->status = RICOH619_SOCA_LOW_VOL;
+                                                 } else { 
+                                                         info->soca->status = RICOH619_SOCA_UNSTABLE;
+                                                 }
+                                       }
+                               } else {
+                                       info->soca->status = RICOH619_SOCA_UNSTABLE;
+                               }
                        }
                }
        } else if (RICOH619_SOCA_ZERO == info->soca->status) {
                if (calc_ocv(info) > get_OCV_voltage(info, 0)) {
-                       err = ricoh619_write(info->dev->parent,
-                                                        FG_CTRL_REG, 0x51);
+                       err = reset_FG_process(info);
                        if (err < 0)
                                dev_err(info->dev, "Error in writing the control register\n");
                        info->soca->last_soc = calc_capacity_2(info);
                        info->soca->status = RICOH619_SOCA_STABLE;
-                       info->soca->ready_fg = 0;
                }
                info->soca->displayed_soc = 0;
        }
 end_flow:
+       /* keep DSOC = 1 when Vbat is over 3.4V*/
+       if( info->fg_poff_vbat != 0) {
+               if (info->soca->zero_flg == 1) {
+                       if(info->soca->Ibat_ave >= 0) {
+                               info->soca->zero_flg = 0;
+                       }
+                       info->soca->displayed_soc = 0;
+               } else if (info->soca->displayed_soc < 50) {
+                       if (info->soca->Vbat_ave < 2000*1000) { /* error value */
+                               info->soca->displayed_soc = 100;
+                       } else if (info->soca->Vbat_ave < info->fg_poff_vbat*1000) {
+                               info->soca->displayed_soc = 0;
+                               info->soca->zero_flg = 1;
+                       } else {
+                               info->soca->displayed_soc = 100;
+                       }
+               }
+       }
+
        if (g_fg_on_mode
                 && (info->soca->status == RICOH619_SOCA_STABLE)) {
                err = ricoh619_write(info->dev->parent, PSWR_REG, 0x7f);
                if (err < 0)
                        dev_err(info->dev, "Error in writing PSWR_REG\n");
                g_soc = 0x7F;
+               err = calc_capacity_in_period(info, &cc_cap,
+                                                       &is_charging, true);
+               if (err < 0)
+                       dev_err(info->dev, "Read cc_sum Error !!-----\n");
+
        } else if (RICOH619_SOCA_UNSTABLE != info->soca->status) {
-               if (info->soca->displayed_soc <= 0) {
+               if ((info->soca->displayed_soc + 50) / 100 <= 1) {
                        val = 1;
                } else {
                        val = (info->soca->displayed_soc + 50)/100;
@@ -1206,10 +1561,13 @@ end_flow:
                                         RICOH619_DISPLAY_UPDATE_TIME * HZ);
 
        mutex_unlock(&info->lock);
-       
-       if(true == is_jeita_updated)
+
+       if((true == is_jeita_updated)
+       || (info->soca->last_displayed_soc/100 != (info->soca->displayed_soc+50)/100))
                power_supply_changed(&info->battery);
 
+       info->soca->last_displayed_soc = info->soca->displayed_soc+50;
+
        return;
 }
 
@@ -1232,11 +1590,9 @@ static void ricoh619_stable_charge_countdown_work(struct work_struct *work)
        if (2 <= info->soca->stable_count) {
                if (3 == info->soca->stable_count
                        && RICOH619_SOCA_FG_RESET == info->soca->status) {
-                       ret = ricoh619_write(info->dev->parent,
-                                                        FG_CTRL_REG, 0x51);
+                       ret = reset_FG_process(info);
                        if (ret < 0)
                                dev_err(info->dev, "Error in writing the control register\n");
-                       info->soca->ready_fg = 0;
                }
                info->soca->stable_count = info->soca->stable_count - 1;
                queue_delayed_work(info->monitor_wqueue,
@@ -1256,12 +1612,10 @@ static void ricoh619_stable_charge_countdown_work(struct work_struct *work)
                                return;
                        }
                        /* Do reset setting */
-                       ret = ricoh619_write(info->dev->parent,
-                                                FG_CTRL_REG, 0x51);
+                       ret = reset_FG_process(info);
                        if (ret < 0)
                                dev_err(info->dev, "Error in writing the control register\n");
 
-                       info->soca->ready_fg = 0;
                        info->soca->status = RICOH619_SOCA_FG_RESET;
 
                        /* Delay for addition Reset Time (6s) */
@@ -1296,13 +1650,10 @@ static void ricoh619_stable_charge_countdown_work(struct work_struct *work)
                                goto adjust;
                        } else {
                                /* Do reset setting */
-                               ret = ricoh619_write(info->dev->parent,
-                                                        FG_CTRL_REG, 0x51);
+                               ret = reset_FG_process(info);
                                if (ret < 0)
                                        dev_err(info->dev, "Error in writing the control register\n");
 
-                               info->soca->ready_fg = 0;
-
                                /* Delay for addition Reset Time (6s) */
                                queue_delayed_work(info->monitor_wqueue,
                                                 &info->charge_stable_work,
@@ -1463,6 +1814,8 @@ static int ricoh619_init_fgsoca(struct ricoh619_battery_info *info)
        int i;
        int err;
        uint8_t val;
+       int cc_cap = 0;
+       bool is_charging = true;
 
        for (i = 0; i <= 10; i = i+1) {
                info->soca->ocv_table[i] = get_OCV_voltage(info, i);
@@ -1494,6 +1847,8 @@ static int ricoh619_init_fgsoca(struct ricoh619_battery_info *info)
                                dev_err(info->dev, "Error in writing the control register\n");
                }
 
+               err = calc_capacity_in_period(info, &cc_cap, &is_charging, true);
+
                msleep(6000);
 
                err = ricoh619_write(info->dev->parent, CHGISET_REG, val);
@@ -1507,20 +1862,22 @@ static int ricoh619_init_fgsoca(struct ricoh619_battery_info *info)
                                                         * 5000 / 4095;
        info->soca->n_cap = get_OCV_init_Data(info, 11);
 
-       info->soca->f_chg_margin = (get_OCV_voltage(info, 10) -
-                                                               get_OCV_voltage(info, 9)) / 10;
 
        info->soca->displayed_soc = 0;
+       info->soca->last_displayed_soc = 0;
        info->soca->suspend_soc = 0;
        info->soca->ready_fg = 0;
        info->soca->soc_delta = 0;
-       info->soca->update_count = 0;
+       info->soca->full_reset_count = 0;
+       info->soca->soc_full = 0;
+       info->soca->fc_cap = 0;
        info->soca->status = RICOH619_SOCA_START;
        /* stable count down 11->2, 1: reset; 0: Finished; */
        info->soca->stable_count = 11;
        info->soca->chg_cmp_times = 0;
        info->soca->dischg_state = 0;
        info->soca->Vbat_ave = 0;
+       info->soca->Vbat_old = 0;
        info->soca->Vsys_ave = 0;
        info->soca->Ibat_ave = 0;
        info->soca->chg_count = 0;
@@ -1528,13 +1885,19 @@ static int ricoh619_init_fgsoca(struct ricoh619_battery_info *info)
        info->soca->hurry_up_flg = 0;
        info->soca->re_cap_old = 0;
        info->soca->jt_limit = 0;
+       info->soca->zero_flg = 0;
+       info->soca->cc_cap_offset = 0;
+
+       for (i = 0; i < 11; i++) {
+               info->soca->ocv_table_low[i] = 0;
+       }
 
        for (i = 0; i < RICOH619_GET_CHARGE_NUM; i++) {
                info->soca->Vbat[i] = 0;
                info->soca->Vsys[i] = 0;
                info->soca->Ibat[i] = 0;
        }
-       
+
        g_full_flag = 0;
        
 #ifdef ENABLE_FG_KEEP_ON_MODE
@@ -1617,7 +1980,6 @@ static int check_jeita_status(struct ricoh619_battery_info *info, bool *is_jeita
 {
        int temp;
        int err = 0;
-       uint8_t val;
        int vfchg;
        uint8_t chgiset_org;
        uint8_t batset2_org;
@@ -1727,6 +2089,7 @@ static int check_jeita_status(struct ricoh619_battery_info *info, bool *is_jeita
                                goto out;
                        }
                        info->soca->jt_limit = 0;
+                       *is_jeita_updated = true;
                } else
                        RICOH_FG_DBG(KERN_INFO "PMU: %s *** 12<Temp<50, already set vfchg==%d, so no need to update ******\n", 
                                        __func__, info->jt_vfchg_h);
@@ -1914,7 +2277,6 @@ static int Calc_Linear_Interpolation(int x0, int y0, int x1, int y1, int y)
 
 static void ricoh619_scaling_OCV_table(struct ricoh619_battery_info *info, int cutoff_vol, int full_vol, int *start_per, int *end_per)
 {
-       int             ret = 0;
        int             i, j;
        int             temp;
        int             percent_step;
@@ -1930,13 +2292,18 @@ static void ricoh619_scaling_OCV_table(struct ricoh619_battery_info *info, int c
        //                       __func__, cutoff_vol,full_vol);
 
        /* Check Start % */
-       for (i = 1; i < 11; i++) {
-               if (info->soca->ocv_table_def[i] >= cutoff_vol * 1000) {
-                       /* unit is 0.001% */
-                       *start_per = Calc_Linear_Interpolation(
-                               (i-1)*1000, info->soca->ocv_table_def[i-1], i*1000,
-                                info->soca->ocv_table_def[i], (cutoff_vol * 1000));
-                       i = 11;
+       if (info->soca->ocv_table_def[0] > cutoff_vol * 1000) {
+               *start_per = 0;
+               RICOH_FG_DBG("PMU : %s : setting value of cuttoff_vol(%d) is out of range(%d) \n",__func__, cutoff_vol, info->soca->ocv_table_def[0]);
+       } else {
+               for (i = 1; i < 11; i++) {
+                       if (info->soca->ocv_table_def[i] >= cutoff_vol * 1000) {
+                               /* unit is 0.001% */
+                               *start_per = Calc_Linear_Interpolation(
+                                       (i-1)*1000, info->soca->ocv_table_def[i-1], i*1000,
+                                       info->soca->ocv_table_def[i], (cutoff_vol * 1000));
+                               break;
+                       }
                }
        }
 
@@ -1947,7 +2314,7 @@ static void ricoh619_scaling_OCV_table(struct ricoh619_battery_info *info, int c
                        *end_per = Calc_Linear_Interpolation(
                                (i-1)*1000, info->soca->ocv_table_def[i-1], i*1000,
                                 info->soca->ocv_table_def[i], (full_vol * 1000));
-                       i = 11;
+                       break;
                }
        }
 
@@ -1974,7 +2341,7 @@ static void ricoh619_scaling_OCV_table(struct ricoh619_battery_info *info, int c
                                battery_init_para[info->num][i*2 + 1] = temp;
                                battery_init_para[info->num][i*2] = temp >> 8;
 
-                               j = 11;
+                               break;
                        }
                }
        }
@@ -1992,20 +2359,14 @@ static void ricoh619_scaling_OCV_table(struct ricoh619_battery_info *info, int c
 static int ricoh619_set_OCV_table(struct ricoh619_battery_info *info)
 {
        int             ret = 0;
-       int             OCV_set_table[11];
-       int             i, j;
+       int             i;
        int             full_ocv;
        int             available_cap;
        int             available_cap_ori;
-       int             OCV_100_def;
-       int             OCV_0_def;
-       int             OCV_100_diff;
-       int             OCV_0_diff;
        int             temp;
-       int             start_per;
-       int             end_per;
-       int             percent_step;
-       int             OCV_percent_new[11];
+       int             temp1;
+       int             start_per = 0;
+       int             end_per = 0;
        int             Rbat;
        int             Ibat_min;
        uint8_t val;
@@ -2020,19 +2381,42 @@ static int ricoh619_set_OCV_table(struct ricoh619_battery_info *info)
                         __func__, i, info->soca->ocv_table_def[i]);
        }
 
-       info->soca->target_vsys = info->fg_target_vsys;
-       info->soca->target_ibat = info->fg_target_ibat;
+       temp =  (battery_init_para[info->num][24]<<8) | (battery_init_para[info->num][25]);
+       Rbat = temp * 1000 / 512 * 5000 / 4095;
+       info->soca->Rsys = Rbat + 55;
+
+       if ((info->fg_target_ibat == 0) || (info->fg_target_vsys == 0)) {       /* normal version */
+
+               temp =  (battery_init_para[info->num][22]<<8) | (battery_init_para[info->num][23]);
+               //fa_cap = get_check_fuel_gauge_reg(info, FA_CAP_H_REG, FA_CAP_L_REG,
+               //                              0x7fff);
+
+               info->soca->target_ibat = temp*2/10; /* calc 0.2C*/
+               temp1 =  (battery_init_para[info->num][0]<<8) | (battery_init_para[info->num][1]);
+
+               info->soca->target_vsys = temp1 + ( info->soca->target_ibat * info->soca->Rsys ) / 1000;
+               
+
+       } else {
+               info->soca->target_ibat = info->fg_target_ibat;
+               /* calc min vsys value */
+               temp1 =  (battery_init_para[info->num][0]<<8) | (battery_init_para[info->num][1]);
+               temp = temp1 + ( info->soca->target_ibat * info->soca->Rsys ) / 1000;
+               if( temp < info->fg_target_vsys) {
+                       info->soca->target_vsys = info->fg_target_vsys;
+               } else {
+                       info->soca->target_vsys = temp;
+                       RICOH_FG_DBG("PMU : %s : setting value of target vsys(%d) is out of range(%d)\n",__func__, info->fg_target_vsys, temp);
+               }
+       }
 
        //for debug
        RICOH_FG_DBG("PMU : %s : target_vsys is %d target_ibat is %d\n",__func__,info->soca->target_vsys,info->soca->target_ibat);
        
        if ((info->soca->target_ibat == 0) || (info->soca->target_vsys == 0)) { /* normal version */
        } else {        /*Slice cutoff voltage version. */
-               temp =  (battery_init_para[info->num][24]<<8) | (battery_init_para[info->num][25]);
-               Rbat = temp * 1000 / 512 * 5000 / 4095;
 
                Ibat_min = -1 * info->soca->target_ibat;
-               info->soca->Rsys = Rbat + 55;
                info->soca->cutoff_ocv = info->soca->target_vsys - Ibat_min * info->soca->Rsys / 1000;
                
                full_ocv = (battery_init_para[info->num][20]<<8) | (battery_init_para[info->num][21]);
@@ -2059,58 +2443,6 @@ static int ricoh619_set_OCV_table(struct ricoh619_battery_info *info)
                dev_err(info->dev, "error in FG_En off\n");
                goto err;
        }
-       ////////////////////////////////
-       ////////////////////////////////
-       //check OCV calibration or not
-       /* get ocv table from setting */
-       for (i = 0; i < 11; i++){
-               ret = ricoh619_read_bank1(info->dev->parent, (0xBC + i*2), &val);
-               if (ret < 0) {
-               dev_err(info->dev, "batterry initialize error\n");
-               return ret;
-               }
-               ret = ricoh619_read_bank1(info->dev->parent, (0xBD + i*2), &val2);
-               if (ret < 0) {
-                       dev_err(info->dev, "batterry initialize error\n");
-                       return ret;
-               }
-               val &= 0x0F;
-               OCV_set_table[i] = val2 + (val << 8);
-               RICOH_FG_DBG("PMU : %s : no %d OCV_set_table %x\n", __func__, i, OCV_set_table[i]);
-
-       }
-
-       OCV_100_def = (battery_init_para[info->num][20]<<8)
-                                | (battery_init_para[info->num][21]);
-
-       OCV_0_def = (battery_init_para[info->num][0]<<8)
-                                | (battery_init_para[info->num][1]);
-       
-       if(OCV_100_def < OCV_set_table[10]) {
-               OCV_100_diff = OCV_set_table[10] - OCV_100_def;
-       } else {
-               OCV_100_diff = OCV_100_def - OCV_set_table[10];
-       }
-
-       if(OCV_0_def < OCV_set_table[0]) {
-               OCV_0_diff = OCV_set_table[0] - OCV_0_def;
-       } else {
-               OCV_0_diff = OCV_0_def - OCV_set_table[0];
-       }
-       RICOH_FG_DBG("PMU : %s : def OCV 100 %x OCV 0 %x \n", __func__, OCV_100_def, OCV_0_def);
-       RICOH_FG_DBG("PMU : %s : OCV 100 %x OCV 0 %x \n", __func__, OCV_set_table[10], OCV_set_table[0]);
-       RICOH_FG_DBG("PMU : %s : diff OCV 100 %x OCV 0 %x \n", __func__, OCV_100_diff, OCV_0_diff);
-
-       if ( (OCV_100_diff > 5)
-               &&(OCV_0_diff < 5))
-       {/* keep setting OCV table */
-               for (i = 0; i < 11; i++) {
-                       RICOH_FG_DBG("PMU : 1\n");
-                       battery_init_para[info->num][i*2+1] = OCV_set_table[i];
-                       battery_init_para[info->num][i*2] = OCV_set_table[i] >> 8;
-               }
-       }
-
        /////////////////////////////////
        ret = ricoh619_read_bank1(info->dev->parent, 0xDC, &val);
        if (ret < 0) {
@@ -2175,7 +2507,7 @@ static int ricoh619_set_OCV_table(struct ricoh619_battery_info *info)
                        }
                        
                        for (i = 0; i < 6; i++) {
-                               ret = ricoh619_write_bank1(info->dev->parent, 0xD4+i, battery_init_para[info->num][23+i]);
+                               ret = ricoh619_write_bank1(info->dev->parent, 0xD4+i, battery_init_para[info->num][24+i]);
                                if (ret < 0) {
                                        dev_err(info->dev, "batterry initialize error\n");
                                        return ret;
@@ -2208,13 +2540,13 @@ static int ricoh619_init_battery(struct ricoh619_battery_info *info)
        /* -------------------------- */
 #ifdef ENABLE_FUEL_GAUGE_FUNCTION
 
-       /* set kanwa state */
+       /* set relaxation state */
        if (RICOH619_REL1_SEL_VALUE > 240)
                val = 0x0F;
        else
                val = RICOH619_REL1_SEL_VALUE / 16 ;
 
-       /* set kanwa state */
+       /* set relaxation state */
        if (RICOH619_REL2_SEL_VALUE > 120)
                val2 = 0x0F;
        else
@@ -2286,7 +2618,6 @@ static int ricoh619_init_battery(struct ricoh619_battery_info *info)
 static int ricoh619_init_charger(struct ricoh619_battery_info *info)
 {
        int err;
-       int i;
        uint8_t val;
        uint8_t val2;
        uint8_t val3;
@@ -2394,7 +2725,7 @@ static int ricoh619_init_charger(struct ricoh619_battery_info *info)
        if ((info->ch_icchg != 0xFF) || (info->ch_icchg <= 0x03)) {
                val3 = info->ch_icchg << 6;
        } else { /* Keep OTP value */
-               val3 = (val & 0xC);
+               val3 = (val & 0xC0);
        }
 
        val = val2 + val3;
@@ -2700,6 +3031,47 @@ static int get_power_supply_status(struct ricoh619_battery_info *info)
        return info->soca->chg_status;
 }
 
+static int get_power_supply_Android_status(struct ricoh619_battery_info *info)
+{
+
+       get_power_supply_status(info);
+
+       /* get  power supply status */
+       if (info->entry_factory_mode)
+                       return POWER_SUPPLY_STATUS_NOT_CHARGING;
+
+       switch (info->soca->chg_status) {
+               case    POWER_SUPPLY_STATUS_UNKNOWN:
+                               return POWER_SUPPLY_STATUS_UNKNOWN;
+                               break;
+
+               case    POWER_SUPPLY_STATUS_NOT_CHARGING:
+                               return POWER_SUPPLY_STATUS_NOT_CHARGING;
+                               break;
+
+               case    POWER_SUPPLY_STATUS_DISCHARGING:
+                               return POWER_SUPPLY_STATUS_DISCHARGING;
+                               break;
+
+               case    POWER_SUPPLY_STATUS_CHARGING:
+                               return POWER_SUPPLY_STATUS_CHARGING;
+                               break;
+
+               case    POWER_SUPPLY_STATUS_FULL:
+                               if(info->soca->displayed_soc == 100 * 100) {
+                                       return POWER_SUPPLY_STATUS_FULL;
+                               } else {
+                                       return POWER_SUPPLY_STATUS_CHARGING;
+                               }
+                               break;
+               default:
+                               return POWER_SUPPLY_STATUS_UNKNOWN;
+                               break;
+       }
+
+       return POWER_SUPPLY_STATUS_UNKNOWN;
+}
+
 static void charger_irq_work(struct work_struct *work)
 {
        struct ricoh619_battery_info *info
@@ -2709,8 +3081,10 @@ static void charger_irq_work(struct work_struct *work)
        RICOH_FG_DBG("PMU:%s In\n", __func__);
 
        power_supply_changed(&info->battery);
+       power_supply_changed(&powerac);
+       power_supply_changed(&powerusb);
 
-       mutex_lock(&info->lock);
+//     mutex_lock(&info->lock);
        
        if (info->chg_stat1 & 0x01) {
                ricoh619_read(info->dev->parent, CHGSTATE_REG, &reg_val);
@@ -2741,7 +3115,7 @@ static void charger_irq_work(struct work_struct *work)
                         "%s(): Error in enable charger mask INT %d\n",
                         __func__, ret);
 
-       mutex_unlock(&info->lock);
+//     mutex_unlock(&info->lock);
        RICOH_FG_DBG("PMU:%s Out\n", __func__);
 }
 
@@ -2771,14 +3145,16 @@ static void ricoh619_usb_charge_det(void)
 {
        struct ricoh619 *ricoh619 = g_ricoh619;
        ricoh619_set_bits(ricoh619->dev,REGISET2_REG,(1 << 7));  //set usb limit current  when SDP or other mode
-       if(2 == dwc_vbus_status()){
+       if(2 == dwc_otg_check_dpdm(0)){
        ricoh619_write(ricoh619->dev,REGISET2_REG,0x13);  //set usb limit current  2A
        ricoh619_write(ricoh619->dev,CHGISET_REG,0xD3);  //set charge current  2A
        }
-       else if(1 == dwc_vbus_status()){
+       else {
        ricoh619_write(ricoh619->dev,REGISET2_REG,0x04);  //set usb limit current  500ma
        ricoh619_write(ricoh619->dev,CHGISET_REG,0xC4);  //set charge current   500ma
        }
+       power_supply_changed(&powerac);
+       power_supply_changed(&powerusb);
 }
 
 static void usb_det_irq_work(struct work_struct *work)
@@ -2787,11 +3163,12 @@ static void usb_det_irq_work(struct work_struct *work)
                 struct ricoh619_battery_info, usb_irq_work);
        int ret = 0;
        uint8_t sts;
-       int time =0;
 
        RICOH_FG_DBG("PMU:%s In\n", __func__);
 
        power_supply_changed(&info->battery);
+       power_supply_changed(&powerac);
+       power_supply_changed(&powerusb);
 
        mutex_lock(&info->lock);
 
@@ -2810,13 +3187,7 @@ static void usb_det_irq_work(struct work_struct *work)
 
        sts &= 0x02;
        if (sts) {
-               //time = 60;
-               //do {
-               //ricoh619_usb_charge_det();
-               //time --;
-               //mdelay(1000);
-               //}while(time >0);
-       
+               ricoh619_usb_charge_det();
        } else {
                /*********************/
                /* No process ??     */
@@ -2826,18 +3197,16 @@ static void usb_det_irq_work(struct work_struct *work)
        RICOH_FG_DBG("PMU:%s Out\n", __func__);
 }
 
-extern void rk28_send_wakeup_key(void);
+extern void rk_send_wakeup_key(void);
 static irqreturn_t charger_in_isr(int irq, void *battery_info)
 {
        struct ricoh619_battery_info *info = battery_info;
-       struct ricoh619 *ricoh619 = g_ricoh619;
-
        RICOH_FG_DBG("PMU:%s\n", __func__); 
 
        info->chg_stat1 |= 0x01;
 
        queue_work(info->workqueue, &info->irq_work);
-//     rk28_send_wakeup_key();
+//     rk_send_wakeup_key();
 
        return IRQ_HANDLED;
 }
@@ -2849,7 +3218,7 @@ static irqreturn_t charger_complete_isr(int irq, void *battery_info)
 
        info->chg_stat1 |= 0x02;
        queue_work(info->workqueue, &info->irq_work);
-       rk28_send_wakeup_key();
+//     rk_send_wakeup_key();
        
        return IRQ_HANDLED;
 }
@@ -2867,7 +3236,7 @@ static irqreturn_t charger_usb_isr(int irq, void *battery_info)
        info->soca->chg_count = 0;
 
 //     queue_work(info->usb_workqueue, &info->usb_irq_work);
-//     rk28_send_wakeup_key(); 
+       rk_send_wakeup_key(); 
         
        if (RICOH619_SOCA_UNSTABLE == info->soca->status
                || RICOH619_SOCA_FG_RESET == info->soca->status)
@@ -2879,12 +3248,11 @@ static irqreturn_t charger_usb_isr(int irq, void *battery_info)
 static irqreturn_t charger_adp_isr(int irq, void *battery_info)
 {
        struct ricoh619_battery_info *info = battery_info;
-       struct ricoh619 *ricoh619 = g_ricoh619;
        RICOH_FG_DBG("PMU:%s\n", __func__);
 
        info->chg_ctr |= 0x01;
        queue_work(info->workqueue, &info->irq_work);
-       rk28_send_wakeup_key(); 
+       rk_send_wakeup_key(); 
 
        info->soca->dischg_state = 0;
        info->soca->chg_count = 0;
@@ -2916,7 +3284,7 @@ static irqreturn_t adc_vsysl_isr(int irq, void *battery_info)
 
        RICOH_FG_DBG("PMU:%s\n", __func__);
 //     ricoh619_write(info->dev->parent, RICOH619_INT_EN_ADC1, 0x10);
-//     rk28_send_wakeup_key(); 
+       rk_send_wakeup_key(); 
 
        return IRQ_HANDLED;
 }
@@ -2929,6 +3297,7 @@ static irqreturn_t adc_vsysl_isr(int irq, void *battery_info)
  *         true : VUSB
  *         false: VADP
  */
+ /*
 static int get_charge_priority(struct ricoh619_battery_info *info, bool *data)
 {
        int ret = 0;
@@ -2940,6 +3309,7 @@ static int get_charge_priority(struct ricoh619_battery_info *info, bool *data)
 
        return ret;
 }
+*/
 
 /*
  * Set Charger Priority
@@ -2948,18 +3318,20 @@ static int get_charge_priority(struct ricoh619_battery_info *info, bool *data)
  *         true : VUSB
  *         false: VADP
  */
+ /*
 static int set_charge_priority(struct ricoh619_battery_info *info, bool *data)
 {
        int ret = 0;
-       uint8_t val = 0;
+       uint8_t val = 0x80;
 
-       val = *data << 7;
-       val &= 0x80;
+       if (*data == 1)
+               ret = ricoh619_set_bits(info->dev->parent, CHGCTL1_REG, val);
+       else
+               ret = ricoh619_clr_bits(info->dev->parent, CHGCTL1_REG, val);
 
-       ret = ricoh619_set_bits(info->dev->parent, CHGCTL1_REG, val);
        return ret;
 }
-
+*/
 #ifdef ENABLE_FUEL_GAUGE_FUNCTION
 static int get_check_fuel_gauge_reg(struct ricoh619_battery_info *info,
                                         int Reg_h, int Reg_l, int enable_bit)
@@ -3023,6 +3395,9 @@ static int calc_capacity(struct ricoh619_battery_info *info)
 
        temp = capacity * 100 * 100 / (10000 - nt);
 
+       temp = min(100, temp);
+       temp = max(0, temp);
+       
        return temp;            /* Unit is 1% */
 }
 
@@ -3052,9 +3427,9 @@ static int calc_capacity_2(struct ricoh619_battery_info *info)
                                                0x7fff);
 
        if (fa_cap != 0) {
-               capacity = ((long)re_cap * 100 * 100 / fa_cap) + 50;
-               capacity = min(10000, capacity);
-               capacity = max(0, capacity);
+               capacity = ((long)re_cap * 100 * 100 / fa_cap);
+               capacity = (long)(min(10000, (int)capacity));
+               capacity = (long)(max(0, (int)capacity));
        } else {
                ret = ricoh619_read(info->dev->parent, SOC_REG, &val);
                if (ret < 0) {
@@ -3067,6 +3442,9 @@ static int calc_capacity_2(struct ricoh619_battery_info *info)
 
        temp = (int)(capacity * 100 * 100 / (10000 - nt));
 
+       temp = min(10000, temp);
+       temp = max(0, temp);
+
        return temp;            /* Unit is 0.01% */
 }
 
@@ -3274,18 +3652,23 @@ static int measure_vbatt_FG(struct ricoh619_battery_info *info, int *data)
 {
        int ret = 0;
 
-       ret = get_check_fuel_gauge_reg(info, VOLTAGE_1_REG, VOLTAGE_2_REG,
-                                                               0x0fff);
-       if (ret < 0) {
-               dev_err(info->dev, "Error in reading the fuel gauge control register\n");
-               return ret;
-       }
+       if(info->soca->ready_fg == 1) {
+               ret = get_check_fuel_gauge_reg(info, VOLTAGE_1_REG, VOLTAGE_2_REG,
+                                                                       0x0fff);
+               if (ret < 0) {
+                       dev_err(info->dev, "Error in reading the fuel gauge control register\n");
+                       return ret;
+               }
 
-       *data = ret;
-       /* conversion unit 1 Unit is 1.22mv (5000/4095 mv) */
-       *data = *data * 50000 / 4095;
-       /* return unit should be 1uV */
-       *data = *data * 100;
+               *data = ret;
+               /* conversion unit 1 Unit is 1.22mv (5000/4095 mv) */
+               *data = *data * 50000 / 4095;
+               /* return unit should be 1uV */
+               *data = *data * 100;
+               info->soca->Vbat_old = *data;
+       } else {
+               *data = info->soca->Vbat_old;
+       }
 
        return ret;
 }
@@ -3441,7 +3824,7 @@ static int ricoh619_batt_get_prop(struct power_supply *psy,
        mutex_lock(&info->lock);
 
        switch (psp) {
-#if 0
+
        case POWER_SUPPLY_PROP_ONLINE:
                ret = ricoh619_read(info->dev->parent, CHGSTATE_REG, &status);
                if (ret < 0) {
@@ -3454,10 +3837,9 @@ static int ricoh619_batt_get_prop(struct power_supply *psy,
                else if (psy->type == POWER_SUPPLY_TYPE_USB)
                        val->intval = (status & 0x80 ? 1 : 0);
                break;
-#endif
        /* this setting is same as battery driver of 584 */
        case POWER_SUPPLY_PROP_STATUS:
-               ret = get_power_supply_status(info);
+               ret = get_power_supply_Android_status(info);
                val->intval = ret;
                info->status = ret;
                /* RICOH_FG_DBG("Power Supply Status is %d\n",
@@ -3478,7 +3860,7 @@ static int ricoh619_batt_get_prop(struct power_supply *psy,
                else {
                        //val->intval = -EINVAL;
                        data = info->cur_voltage * 1000;
-                       /* RICOH_FG_DBG( "battery voltage is not ready\n"); */
+                        RICOH_FG_DBG( "battery voltage is not ready\n"); 
                }
 #else
                ret = measure_vbatt_ADC(info, &data);
@@ -3498,14 +3880,14 @@ static int ricoh619_batt_get_prop(struct power_supply *psy,
                        val->intval = 100;
                        info->capacity = 100;
                } else if (info->soca->displayed_soc <= 0) {
-                       val->intval = 0;
-                       info->capacity = 0;
+                       val->intval = 10;
+                       info->capacity = 10;
                } else {
                        val->intval = (info->soca->displayed_soc + 50)/100;
                        info->capacity = (info->soca->displayed_soc + 50)/100;
                }
-               /* RICOH_FG_DBG("battery capacity is %d%%\n",
-                                                       info->capacity); */
+                RICOH_FG_DBG("battery capacity is %d%%\n",
+                                                       info->capacity); 
                break;
 
        /* current temperature of battery */
@@ -3608,58 +3990,152 @@ struct power_supply    powerusb = {
                .get_property = ricoh619_batt_get_prop,
 };
 
-static __devinit int ricoh619_battery_probe(struct platform_device *pdev)
+#ifdef CONFIG_OF
+static struct ricoh619_battery_platform_data *
+ricoh619_battery_dt_init(struct platform_device *pdev)
+{
+       struct device_node *nproot = pdev->dev.parent->of_node;
+       struct device_node *np;
+       struct ricoh619_battery_platform_data *pdata;
+       int temp;
+
+       if (!nproot)
+               return pdev->dev.platform_data;
+
+       np = of_find_node_by_name(nproot, "battery");
+       if (!np) {
+               dev_err(&pdev->dev, "failed to find battery node\n");
+               return NULL;
+       }
+
+       pdata = devm_kzalloc(&pdev->dev,
+                       sizeof(struct ricoh619_battery_platform_data),
+                       GFP_KERNEL);
+
+       of_property_read_u32(np, "ricoh,monitor-time", &pdata->monitor_time);
+       of_property_read_u32(np, "ricoh,alarm-vol-mv", &pdata->alarm_vol_mv);
+
+       /* check rage of b,.attery type */
+       type_n = Battery_Type();
+       RICOH_FG_DBG("%s type_n=%d,temp is %d\n", __func__, type_n,temp);
+
+       switch (type_n) {
+       case (0):
+               of_property_read_u32(np, "ricoh,ch-vfchg", &pdata->type[0].ch_vfchg);
+               of_property_read_u32(np, "ricoh,ch-vrchg", &pdata->type[0].ch_vrchg);
+               of_property_read_u32(np, "ricoh,ch-vbatovset", &pdata->type[0].ch_vbatovset);
+               of_property_read_u32(np, "ricoh,ch-ichg", &pdata->type[0].ch_ichg);
+               of_property_read_u32(np, "ricoh,ch-ilim-adp", &pdata->type[0].ch_ilim_adp);
+               of_property_read_u32(np, "ricoh,ch-ilim-usb", &pdata->type[0].ch_ilim_usb);
+               of_property_read_u32(np, "ricoh,ch-icchg", &pdata->type[0].ch_icchg);
+               of_property_read_u32(np, "ricoh,fg-target-vsys", &pdata->type[0].fg_target_vsys);
+               of_property_read_u32(np, "ricoh,fg-target-ibat", &pdata->type[0].fg_target_ibat);
+               of_property_read_u32(np, "ricoh,fg-poff-vbat", &pdata->type[0].fg_poff_vbat);
+               of_property_read_u32(np, "ricoh,jt-en", &pdata->type[0].jt_en);
+               of_property_read_u32(np, "ricoh,jt-hw-sw", &pdata->type[0].jt_hw_sw);
+               of_property_read_u32(np, "ricoh,jt-temp-h", &pdata->type[0].jt_temp_h);
+               of_property_read_u32(np, "ricoh,jt-temp-l", &pdata->type[0].jt_temp_l);
+               of_property_read_u32(np, "ricoh,jt-vfchg-h", &pdata->type[0].jt_vfchg_h);
+               of_property_read_u32(np, "ricoh,jt-vfchg-l", &pdata->type[0].jt_vfchg_l);
+               of_property_read_u32(np, "ricoh,jt-ichg-h", &pdata->type[0].jt_ichg_h);
+               of_property_read_u32(np, "ricoh,jt-ichg-l", &pdata->type[0].jt_ichg_l);
+               break;
+#if 0
+       case (1):
+               of_property_read_u32(np, "ricoh,ch-vfchg-1", &pdata->type[1].ch_vfchg);
+               of_property_read_u32(np, "ricoh,ch-vrchg-1", &pdata->type[1].ch_vrchg);
+               of_property_read_u32(np, "ricoh,ch-vbatovset-1", &pdata->type[1].ch_vbatovset);
+               of_property_read_u32(np, "ricoh,ch-ichg-1", &pdata->type[1].ch_ichg);
+               of_property_read_u32(np, "ricoh,ch-ilim-adp-1", &pdata->type[1].ch_ilim_adp);
+               of_property_read_u32(np, "ricoh,ch-ilim-usb-1", &pdata->type[1].ch_ilim_usb);
+               of_property_read_u32(np, "ricoh,ch-icchg-1", &pdata->type[1].ch_icchg);
+               of_property_read_u32(np, "ricoh,fg-target-vsys-1", &pdata->type[1].fg_target_vsys);
+               of_property_read_u32(np, "ricoh,fg-target-ibat-1", &pdata->type[1].fg_target_ibat);
+               of_property_read_u32(np, "ricoh,fg-poff-vbat-1", &pdata->type[1].fg_poff_vbat);
+               of_property_read_u32(np, "ricoh,jt-en-1", &pdata->type[1].jt_en);
+               of_property_read_u32(np, "ricoh,jt-hw-sw-1", &pdata->type[1].jt_hw_sw);
+               of_property_read_u32(np, "ricoh,jt-temp-h-1", &pdata->type[1].jt_temp_h);
+               of_property_read_u32(np, "ricoh,jt-temp-l-1", &pdata->type[1].jt_temp_l);
+               of_property_read_u32(np, "ricoh,jt-vfchg-h-1", &pdata->type[1].jt_vfchg_h);
+               of_property_read_u32(np, "ricoh,jt-vfchg-l-1", &pdata->type[1].jt_vfchg_l);
+               of_property_read_u32(np, "ricoh,jt-ichg-h-1", &pdata->type[1].jt_ichg_h);
+               of_property_read_u32(np, "ricoh,jt-ichg-l-1", &pdata->type[1].jt_ichg_l);
+               break;
+#endif
+       default:
+               of_node_put(np);
+               return 0;
+       }
+
+       of_node_put(np);
+
+       return pdata;
+}
+#else
+static struct ricoh619_battery_platform_data *
+ricoh619_battery_dt_init(struct platform_device *pdev)
+{
+       return pdev->dev.platform_data;
+}
+#endif
+
+static int ricoh619_battery_probe(struct platform_device *pdev)
 {
        struct ricoh619_battery_info *info;
        struct ricoh619_battery_platform_data *pdata;
-       int type_n;
+       struct ricoh619 *ricoh619 = dev_get_drvdata(pdev->dev.parent);
        int ret, temp;
 
-       RICOH_FG_DBG("PMU:2013.8.3 %s\n", __func__);
-       
-       info = kzalloc(sizeof(struct ricoh619_battery_info), GFP_KERNEL);
+       RICOH_FG_DBG(KERN_INFO "PMU: %s : version is %s\n", __func__,RICOH619_BATTERY_VERSION);
+
+       pdata = ricoh619_battery_dt_init(pdev);
+       if (!pdata) {
+               dev_err(&pdev->dev, "platform data isn't assigned to "
+                       "power supply\n");
+               return -EINVAL;
+       }
+       info = devm_kzalloc(ricoh619->dev,sizeof(struct ricoh619_battery_info), GFP_KERNEL);
        if (!info)
                return -ENOMEM;
-       info->soca = kzalloc(sizeof(struct ricoh619_soca_info), GFP_KERNEL);
+       info->soca = devm_kzalloc(ricoh619->dev,sizeof(struct ricoh619_soca_info), GFP_KERNEL);
                if (!info->soca)
                        return -ENOMEM;
 
        info->dev = &pdev->dev;
        info->status = POWER_SUPPLY_STATUS_CHARGING;
-       pdata = pdev->dev.platform_data;
        info->monitor_time = pdata->monitor_time * HZ;
        info->alarm_vol_mv = pdata->alarm_vol_mv;
 
-       type_n = Battery_Type();
+       /* check rage of battery num */
        info->num = Battery_Table();
        temp = sizeof(battery_init_para)/(sizeof(uint8_t)*32);
-       RICOH_FG_DBG("%s temp=%d\n", __func__, temp);
        if(info->num >= (sizeof(battery_init_para)/(sizeof(uint8_t)*32)))
-               info->num = 0;
-       RICOH_FG_DBG("%s type_n=%d\n", __func__, type_n);
-       RICOH_FG_DBG("%s info->num=%d\n", __func__, info->num);
-       /* these valuse are set in platform */
-       if (type_n == 0)
        {
-               info->ch_vfchg = pdata->ch_vfchg;
-               info->ch_vrchg = pdata->ch_vrchg;
-               info->ch_vbatovset = pdata->ch_vbatovset;
-               info->ch_ichg = pdata->ch_ichg;
-               info->ch_ilim_adp = pdata->ch_ilim_adp;
-               info->ch_ilim_usb = pdata->ch_ilim_usb;
-               info->ch_icchg = pdata->ch_icchg;
-               info->fg_target_vsys = pdata->fg_target_vsys;
-               info->fg_target_ibat = pdata->fg_target_ibat;
-               info->jt_en = pdata->jt_en;
-               info->jt_hw_sw = pdata->jt_hw_sw;
-               info->jt_temp_h = pdata->jt_temp_h;
-               info->jt_temp_l = pdata->jt_temp_l;
-               info->jt_vfchg_h = pdata->jt_vfchg_h;
-               info->jt_vfchg_l = pdata->jt_vfchg_l;
-               info->jt_ichg_h = pdata->jt_ichg_h;
-               info->jt_ichg_l = pdata->jt_ichg_l;
-       } else {
+               RICOH_FG_DBG("%s : Battery num is out of range\n", __func__);
+               info->num = 0;
        }
+       RICOH_FG_DBG("%s info->num=%d,temp is %d\n", __func__, info->num,temp);
+
+       /* these valuse are set in platform */
+       info->ch_vfchg = pdata->type[type_n].ch_vfchg;
+       info->ch_vrchg = pdata->type[type_n].ch_vrchg;
+       info->ch_vbatovset = pdata->type[type_n].ch_vbatovset;
+       info->ch_ichg = pdata->type[type_n].ch_ichg;
+       info->ch_ilim_adp = pdata->type[type_n].ch_ilim_adp;
+       info->ch_ilim_usb = pdata->type[type_n].ch_ilim_usb;
+       info->ch_icchg = pdata->type[type_n].ch_icchg;
+       info->fg_target_vsys = pdata->type[type_n].fg_target_vsys;
+       info->fg_target_ibat = pdata->type[type_n].fg_target_ibat;
+       info->fg_poff_vbat = pdata->type[type_n].fg_poff_vbat;
+       info->jt_en = pdata->type[type_n].jt_en;
+       info->jt_hw_sw = pdata->type[type_n].jt_hw_sw;
+       info->jt_temp_h = pdata->type[type_n].jt_temp_h;
+       info->jt_temp_l = pdata->type[type_n].jt_temp_l;
+       info->jt_vfchg_h = pdata->type[type_n].jt_vfchg_h;
+       info->jt_vfchg_l = pdata->type[type_n].jt_vfchg_l;
+       info->jt_ichg_h = pdata->type[type_n].jt_ichg_h;
+       info->jt_ichg_l = pdata->type[type_n].jt_ichg_l;
+
        info->adc_vdd_mv = ADC_VDD_MV;          /* 2800; */
        info->min_voltage = MIN_VOLTAGE;        /* 3100; */
        info->max_voltage = MAX_VOLTAGE;        /* 4200; */
@@ -3681,28 +4157,28 @@ static __devinit int ricoh619_battery_probe(struct platform_device *pdev)
        /* Disable Charger/ADC interrupt */
        ret = ricoh619_clr_bits(info->dev->parent, RICOH619_INTC_INTEN,
                                                         CHG_INT | ADC_INT);
-       if (ret)
+       if (ret<0)
                goto out;
 
        ret = ricoh619_init_battery(info);
-       if (ret)
+       if (ret<0)
                goto out;
-
+/*
 #ifdef ENABLE_FACTORY_MODE
        info->factory_mode_wqueue
                = create_singlethread_workqueue("ricoh619_factory_mode");
-       INIT_DELAYED_WORK_DEFERRABLE(&info->factory_mode_work,
+       INIT_DEFERRABLE_WORK(&info->factory_mode_work,
                                         check_charging_state_work);
 
        ret = ricoh619_factory_mode(info);
-       if (ret)
+       if (ret<0)
                goto out;
 
 #endif
-
+*/
        ret = power_supply_register(&pdev->dev, &info->battery);
 
-       if (ret)
+       if (ret<0)
                info->battery.dev->parent = &pdev->dev;
 
        ret = power_supply_register(&pdev->dev, &powerac);
@@ -3718,52 +4194,43 @@ static __devinit int ricoh619_battery_probe(struct platform_device *pdev)
                = create_singlethread_workqueue("rc5t619_usb_det");
        INIT_WORK(&info->usb_irq_work, usb_det_irq_work);
 
-       INIT_DELAYED_WORK_DEFERRABLE(&info->monitor_work,
+       INIT_DEFERRABLE_WORK(&info->monitor_work,
                                         ricoh619_battery_work);
-       INIT_DELAYED_WORK_DEFERRABLE(&info->displayed_work,
+       INIT_DEFERRABLE_WORK(&info->displayed_work,
                                         ricoh619_displayed_work);
-       INIT_DELAYED_WORK_DEFERRABLE(&info->charge_stable_work,
+       INIT_DEFERRABLE_WORK(&info->charge_stable_work,
                                         ricoh619_stable_charge_countdown_work);
-       INIT_DELAYED_WORK_DEFERRABLE(&info->charge_monitor_work,
+       INIT_DEFERRABLE_WORK(&info->charge_monitor_work,
                                         ricoh619_charge_monitor_work);
-       INIT_DELAYED_WORK_DEFERRABLE(&info->get_charge_work,
+       INIT_DEFERRABLE_WORK(&info->get_charge_work,
                                         ricoh619_get_charge_work);
-       INIT_DELAYED_WORK_DEFERRABLE(&info->jeita_work, ricoh619_jeita_work);
+       INIT_DEFERRABLE_WORK(&info->jeita_work, ricoh619_jeita_work);
        INIT_DELAYED_WORK(&info->changed_work, ricoh619_changed_work);
 
        /* Charger IRQ workqueue settings */
-       charger_irq = pdata->irq;
 
-       ret = request_threaded_irq(charger_irq + RICOH619_IRQ_FONCHGINT,
-                                       NULL, charger_in_isr, IRQF_ONESHOT,
+       ret = request_threaded_irq( irq_create_mapping(ricoh619->irq_domain, RICOH619_IRQ_FONCHGINT),NULL, charger_in_isr, IRQF_ONESHOT,
                                                "rc5t619_charger_in", info);
        if (ret < 0) {
-               dev_err(&pdev->dev, "Can't get CHG_INT IRQ for chrager: %d\n",
-                                                                       ret);
+               dev_err(&pdev->dev, "Can't get CHG_INT IRQ for chrager: %d\n",ret);
                goto out;
        }
 
-       ret = request_threaded_irq(charger_irq + RICOH619_IRQ_FCHGCMPINT,
-                                               NULL, charger_complete_isr,
-                                       IRQF_ONESHOT, "rc5t619_charger_comp",
-                                                               info);
+       ret = request_threaded_irq(irq_create_mapping(ricoh619->irq_domain, RICOH619_IRQ_FCHGCMPINT),NULL, charger_complete_isr,
+                                       IRQF_ONESHOT, "rc5t619_charger_comp",info);
        if (ret < 0) {
-               dev_err(&pdev->dev, "Can't get CHG_COMP IRQ for chrager: %d\n",
-                                                                        ret);
+               dev_err(&pdev->dev, "Can't get CHG_COMP IRQ for chrager: %d\n",ret);
                goto out;
        }
 
-       ret = request_threaded_irq(charger_irq + RICOH619_IRQ_FVUSBDETSINT,
-                                       NULL, charger_usb_isr, IRQF_ONESHOT,
+       ret = request_threaded_irq(irq_create_mapping(ricoh619->irq_domain, RICOH619_IRQ_FVUSBDETSINT) ,NULL, charger_usb_isr, IRQF_ONESHOT,
                                                "rc5t619_usb_det", info);
        if (ret < 0) {
-               dev_err(&pdev->dev, "Can't get USB_DET IRQ for chrager: %d\n",
-                                                                        ret);
+               dev_err(&pdev->dev, "Can't get USB_DET IRQ for chrager: %d\n",ret);
                goto out;
        }
 
-       ret = request_threaded_irq(charger_irq + RICOH619_IRQ_FVADPDETSINT,
-                                       NULL, charger_adp_isr, IRQF_ONESHOT,
+       ret = request_threaded_irq(irq_create_mapping(ricoh619->irq_domain, RICOH619_IRQ_FVADPDETSINT),NULL, charger_adp_isr, IRQF_ONESHOT,
                                                "rc5t619_adp_det", info);
        if (ret < 0) {
                dev_err(&pdev->dev,
@@ -3772,21 +4239,20 @@ static __devinit int ricoh619_battery_probe(struct platform_device *pdev)
        }
 
 #ifdef ENABLE_LOW_BATTERY_DETECTION
-       ret = request_threaded_irq(charger_irq + RICOH619_IRQ_VSYSLIR,
-                                       NULL, adc_vsysl_isr, IRQF_ONESHOT,
+       ret = request_threaded_irq(irq_create_mapping(ricoh619->irq_domain, RICOH619_IRQ_VSYSLIR) ,NULL, adc_vsysl_isr, IRQF_ONESHOT,
                                                "rc5t619_adc_vsysl", info);
        if (ret < 0) {
                dev_err(&pdev->dev,
                        "Can't get ADC_VSYSL IRQ for chrager: %d\n", ret);
                goto out;
        }
-       INIT_DELAYED_WORK_DEFERRABLE(&info->low_battery_work,
+       INIT_DEFERRABLE_WORK(&info->low_battery_work,
                                         low_battery_irq_work);
 #endif
 
        /* Charger init and IRQ setting */
        ret = ricoh619_init_charger(info);
-       if (ret)
+       if (ret<0)
                goto out;
 
 #ifdef ENABLE_FUEL_GAUGE_FUNCTION
@@ -3795,8 +4261,8 @@ static __devinit int ricoh619_battery_probe(struct platform_device *pdev)
        queue_delayed_work(info->monitor_wqueue, &info->monitor_work,
                                        RICOH619_MONITOR_START_TIME*HZ);
 
-       /* Enable Charger interrupt */
-       ricoh619_set_bits(info->dev->parent, RICOH619_INTC_INTEN, CHG_INT);
+       /* Enable Charger/ADC interrupt */
+       ricoh619_set_bits(info->dev->parent, RICOH619_INTC_INTEN, CHG_INT | ADC_INT);
 
        return 0;
 
@@ -3805,9 +4271,10 @@ out:
        return ret;
 }
 
-static int __devexit ricoh619_battery_remove(struct platform_device *pdev)
+static int ricoh619_battery_remove(struct platform_device *pdev)
 {
        struct ricoh619_battery_info *info = platform_get_drvdata(pdev);
+       struct ricoh619 *ricoh619 = dev_get_drvdata(pdev->dev.parent);
        uint8_t val;
        int ret;
        int err;
@@ -3853,12 +4320,12 @@ static int __devexit ricoh619_battery_remove(struct platform_device *pdev)
                dev_err(info->dev, "Error in writing the control register\n");
        }
        
-       free_irq(charger_irq + RICOH619_IRQ_FONCHGINT, &info);
-       free_irq(charger_irq + RICOH619_IRQ_FCHGCMPINT, &info);
-       free_irq(charger_irq + RICOH619_IRQ_FVUSBDETSINT, &info);
-       free_irq(charger_irq + RICOH619_IRQ_FVADPDETSINT, &info);
+       free_irq(irq_create_mapping(ricoh619->irq_domain, RICOH619_IRQ_FONCHGINT), &info);
+       free_irq(irq_create_mapping(ricoh619->irq_domain, RICOH619_IRQ_FCHGCMPINT), &info);
+       free_irq(irq_create_mapping(ricoh619->irq_domain, RICOH619_IRQ_FVUSBDETSINT), &info);
+       free_irq(irq_create_mapping(ricoh619->irq_domain, RICOH619_IRQ_FVADPDETSINT) , &info);
 #ifdef ENABLE_LOW_BATTERY_DETECTION
-       free_irq(charger_irq + RICOH619_IRQ_VSYSLIR, &info);
+       free_irq(irq_create_mapping(ricoh619->irq_domain, RICOH619_IRQ_VSYSLIR), &info);
 #endif
 
        cancel_delayed_work(&info->monitor_work);
@@ -3902,6 +4369,7 @@ static int ricoh619_battery_suspend(struct device *dev)
        int err;
        int cc_cap = 0;
        bool is_charging = true;
+       int displayed_soc_temp;
 
        if (g_fg_on_mode
                 && (info->soca->status == RICOH619_SOCA_STABLE)) {
@@ -3910,6 +4378,11 @@ static int ricoh619_battery_suspend(struct device *dev)
                        dev_err(info->dev, "Error in writing PSWR_REG\n");
                 g_soc = 0x7F;
                info->soca->suspend_soc = info->soca->displayed_soc;
+               ret = calc_capacity_in_period(info, &cc_cap,
+                                                        &is_charging, true);
+               if (ret < 0)
+                       dev_err(info->dev, "Read cc_sum Error !!-----\n");
+
        } else if (info->soca->status != RICOH619_SOCA_START
                && info->soca->status != RICOH619_SOCA_UNSTABLE) {
                if (info->soca->displayed_soc <= 0) {
@@ -3924,12 +4397,23 @@ static int ricoh619_battery_suspend(struct device *dev)
 
                g_soc = val;
 
-               info->soca->suspend_soc = info->soca->displayed_soc;
-
                ret = calc_capacity_in_period(info, &cc_cap,
                                                         &is_charging, true);
                if (ret < 0)
                        dev_err(info->dev, "Read cc_sum Error !!-----\n");
+                       
+               if (info->soca->status != RICOH619_SOCA_STABLE) {
+                       info->soca->cc_delta
+                                = (is_charging == true) ? cc_cap : -cc_cap;
+
+                       displayed_soc_temp
+                              = info->soca->displayed_soc + info->soca->cc_delta;
+                       displayed_soc_temp = min(10000, displayed_soc_temp);
+                       displayed_soc_temp = max(0, displayed_soc_temp);
+                       info->soca->displayed_soc = displayed_soc_temp;
+               }
+               info->soca->suspend_soc = info->soca->displayed_soc;
+                                       
        } else if (info->soca->status == RICOH619_SOCA_START
                || info->soca->status == RICOH619_SOCA_UNSTABLE) {
 
@@ -3968,7 +4452,7 @@ static int ricoh619_battery_suspend(struct device *dev)
 #ifdef ENABLE_LOW_BATTERY_DETECTION
 //     disable_irq(charger_irq + RICOH619_IRQ_VSYSLIR);
 #endif
-
+#if 0
        flush_delayed_work(&info->monitor_work);
        flush_delayed_work(&info->displayed_work);
        flush_delayed_work(&info->charge_stable_work);
@@ -3983,7 +4467,22 @@ static int ricoh619_battery_suspend(struct device *dev)
        
 //     flush_work(&info->irq_work);
 //     flush_work(&info->usb_irq_work);
+#else
+       cancel_delayed_work(&info->monitor_work);
+       cancel_delayed_work(&info->displayed_work);
+       cancel_delayed_work(&info->charge_stable_work);
+       cancel_delayed_work(&info->charge_monitor_work);
+       cancel_delayed_work(&info->get_charge_work);
+       cancel_delayed_work(&info->changed_work);
+#ifdef ENABLE_LOW_BATTERY_DETECTION
+       cancel_delayed_work(&info->low_battery_work);
+#endif
+       cancel_delayed_work(&info->factory_mode_work);
+       cancel_delayed_work(&info->jeita_work);
        
+//     flush_work(&info->irq_work);
+//     flush_work(&info->usb_irq_work);
+#endif
 
        return 0;
 }
@@ -4036,11 +4535,10 @@ static int ricoh619_battery_resume(struct device *dev)
                        displayed_soc_temp = max(0, displayed_soc_temp);
                        info->soca->displayed_soc = displayed_soc_temp;
 
-                       ret = ricoh619_write(info->dev->parent,
-                                                        FG_CTRL_REG, 0x51);
+                       ret = reset_FG_process(info);
+
                        if (ret < 0)
                                dev_err(info->dev, "Error in writing the control register\n");
-                       info->soca->ready_fg = 0;
                        info->soca->status = RICOH619_SOCA_FG_RESET;
 
                } else
@@ -4063,8 +4561,26 @@ static int ricoh619_battery_resume(struct device *dev)
                info->soca->cc_delta = (is_charging == true) ? cc_cap : -cc_cap;
 
                displayed_soc_temp = info->soca->soc + info->soca->cc_delta;
-               if (displayed_soc_temp < 0)
+               if (info->soca->zero_flg == 1) {
+                       if((info->soca->Ibat_ave >= 0) 
+                       || (displayed_soc_temp >= 100)){
+                               info->soca->zero_flg = 0;
+                       } else {
                                displayed_soc_temp = 0;
+                       }
+               } else if (displayed_soc_temp < 100) {
+                       /* keep DSOC = 1 when Vbat is over 3.4V*/
+                       if( info->fg_poff_vbat != 0) {
+                               if (info->soca->Vbat_ave < 2000*1000) { /* error value */
+                                       displayed_soc_temp = 100;
+                               } else if (info->soca->Vbat_ave < info->fg_poff_vbat*1000) {
+                                       displayed_soc_temp = 0;
+                                       info->soca->zero_flg = 1;
+                               } else {
+                                       displayed_soc_temp = 100;
+                               }
+                       }
+               }
                displayed_soc_temp = min(10000, displayed_soc_temp);
                displayed_soc_temp = max(0, displayed_soc_temp);
 
@@ -4078,7 +4594,6 @@ static int ricoh619_battery_resume(struct device *dev)
                        info->soca->last_soc = calc_capacity_2(info);
                }
        }
-       info->soca->update_count = 0;
 
        ret = measure_vbatt_FG(info, &info->soca->Vbat_ave);
        ret = measure_vsys_ADC(info, &info->soca->Vsys_ave);
@@ -4131,6 +4646,15 @@ static int ricoh619_battery_resume(struct device *dev)
        return 0;
 }
 
+#ifdef CONFIG_OF
+static const struct of_device_id ricoh619_battery_dt_match[] = {
+       { .compatible = "ricoh,ricoh619-battery", },
+       {},
+};
+MODULE_DEVICE_TABLE(of, ricoh619_battery_dt_match);
+#endif
+
+
 static const struct dev_pm_ops ricoh619_battery_pm_ops = {
        .suspend        = ricoh619_battery_suspend,
        .resume         = ricoh619_battery_resume,
@@ -4141,12 +4665,13 @@ static struct platform_driver ricoh619_battery_driver = {
        .driver = {
                                .name   = "ricoh619-battery",
                                .owner  = THIS_MODULE,
+                               .of_match_table = of_match_ptr(ricoh619_battery_dt_match),
 #ifdef CONFIG_PM
                                .pm     = &ricoh619_battery_pm_ops,
 #endif
        },
        .probe  = ricoh619_battery_probe,
-       .remove = __devexit_p(ricoh619_battery_remove),
+       .remove = ricoh619_battery_remove,
 };
 
 static int __init ricoh619_battery_init(void)
@@ -4154,7 +4679,7 @@ static int __init ricoh619_battery_init(void)
        RICOH_FG_DBG("PMU: %s\n", __func__);
        return platform_driver_register(&ricoh619_battery_driver);
 }
-subsys_initcall_sync(ricoh619_battery_init);
+fs_initcall_sync(ricoh619_battery_init);
 
 static void __exit ricoh619_battery_exit(void)
 {
old mode 100644 (file)
new mode 100755 (executable)
index 3afbb5d..fdfde54
@@ -267,6 +267,12 @@ config ROCKCHIP_PWM_REGULATOR
        help
          Say Y to enable support for the voltage regulators control on the ROCKCHIP.
 
+config REGULATOR_SYB827
+       tristate "SYB827 DCDC SUPPORT REGULATOR"
+       depends on I2C
+       help
+         Support the voltage and current regulators of the SYB827 series of DCDC devices.
+
 config REGULATOR_PCAP
        tristate "Motorola PCAP2 regulator driver"
        depends on EZX_PCAP
@@ -524,6 +530,12 @@ config REGULATOR_WM8994
          This driver provides support for the voltage regulators on the
          WM8994 CODEC.
 
+config REGULATOR_RICOH619
+       tristate "RICOH 619 Power regulators"
+       depends on MFD_RICOH619
+       default n
+       help
+         This driver supports regulator driver for RICOH619 PMIC.
 config REGULATOR_AS3711
        tristate "AS3711 PMIC"
        depends on MFD_AS3711
old mode 100644 (file)
new mode 100755 (executable)
index 6ed3740..d38b465
@@ -74,6 +74,8 @@ obj-$(CONFIG_REGULATOR_WM8350) += wm8350-regulator.o
 obj-$(CONFIG_REGULATOR_WM8400) += wm8400-regulator.o
 obj-$(CONFIG_REGULATOR_WM8994) += wm8994-regulator.o
 obj-$(CONFIG_REGULATOR_ACT8846) += act8846.o
+obj-$(CONFIG_REGULATOR_SYB827) += syb827.o
+obj-$(CONFIG_REGULATOR_RICOH619) += ricoh619-regulator.o
 
 obj-$(CONFIG_ARCH_ROCKCHIP) += rockchip_io_vol_domain.o
 
index 900f25ef9eee012a892b421b36dc4e621728856e..b840ce9ae19c22bf70ca6d7c9129d68b37c98a9d 100644 (file)
@@ -35,6 +35,8 @@
 #include <linux/regulator/machine.h>
 #include <linux/mfd/ricoh619.h>
 #include <linux/regulator/ricoh619-regulator.h>
+#include <linux/of.h>
+#include <linux/regulator/of_regulator.h>
 
 struct ricoh619_regulator {
        int             id;
@@ -203,10 +205,12 @@ static int ricoh619_set_suspend_voltage(struct regulator_dev *rdev,
 static int ricoh619_get_voltage(struct regulator_dev *rdev)
 {
        struct ricoh619_regulator *ri = rdev_get_drvdata(rdev);
+       struct device *parent = to_ricoh619_dev(rdev);
        uint8_t vsel;
+       int ret;
 
-       vsel = ri->vout_reg_cache & ri->vout_mask;
-       return ri->min_uV + vsel * ri->step_uV;
+       ret = ricoh619_read(parent, ri->vout_reg, &vsel);
+       return ricoh619_list_voltage(rdev,vsel);
 }
 
  int ricoh619_regulator_enable_eco_mode(struct regulator_dev *rdev)
@@ -331,7 +335,55 @@ static int ricoh619_dcdc_set_voltage_time_sel(struct regulator_dev *rdev,   unsi
 
        return DIV_ROUND_UP(abs(old_volt - new_volt)*2, 14000);
 }
+static int ricoh619_dcdc_set_suspend_mode(struct regulator_dev *rdev, unsigned int mode)
+{
+       struct ricoh619_regulator *ri = rdev_get_drvdata(rdev);
+       struct device *parent = to_ricoh619_dev(rdev);
+       int ret;
+       uint8_t control;
+       
+       ret = ricoh619_read(parent, ri->reg_en_reg,&control);
+       switch(mode)
+       {
+       case REGULATOR_MODE_FAST:
+               return ricoh619_write(parent, ri->reg_en_reg, ((control & 0x3f) | 0x40));
+       case REGULATOR_MODE_NORMAL:
+               return ricoh619_write(parent, ri->reg_en_reg, (control & 0x3f));
+       case REGULATOR_MODE_STANDBY:
+               return ricoh619_write(parent, ri->reg_en_reg, ((control & 0x3f) | 0x80));       
+       default:
+               printk("error:pmu_619 only powersave pwm psm mode\n");
+               return -EINVAL;
+       }
+       
+
+}
+static int ricoh619_reg_suspend_enable(struct regulator_dev *rdev)
+{
+       struct ricoh619_regulator *ri = rdev_get_drvdata(rdev);
+       struct device *parent = to_ricoh619_dev(rdev);
+       int ret;
+       u8 vout_val;
+       ret = ricoh619_set_bits(parent, (0x16 + ri->id), (0xf << 0));
+       if (ret < 0) {
+               dev_err(&rdev->dev, "Error in updating the STATE register\n");
+               return ret;
+       }
+       udelay(ri->delay);
+       return ret;
+}
+
+static int ricoh619_reg_suspend_disable(struct regulator_dev *rdev)
+{
+       struct ricoh619_regulator *ri = rdev_get_drvdata(rdev);
+       struct device *parent = to_ricoh619_dev(rdev);
+       int ret;
+       ret = ricoh619_clr_bits(parent, (0x16 + ri->id), (0xf <<0));
+       if (ret < 0)
+               dev_err(&rdev->dev, "Error in updating the STATE register\n");
 
+       return ret;
+}
 
 static struct regulator_ops ricoh619_ops = {
        .list_voltage                   = ricoh619_list_voltage,
@@ -343,6 +395,9 @@ static struct regulator_ops ricoh619_ops = {
        .set_mode = ricoh619_dcdc_set_mode,
        .enable                         = ricoh619_reg_enable,
        .disable                                = ricoh619_reg_disable,
+       .set_suspend_mode = ricoh619_dcdc_set_suspend_mode,
+       .set_suspend_enable                             = ricoh619_reg_suspend_enable,
+       .set_suspend_disable                            = ricoh619_reg_suspend_disable,
        .is_enabled                     = ricoh619_reg_is_enabled,
 };
 
@@ -378,7 +433,7 @@ static struct regulator_ops ricoh619_ops = {
        },                                                      \
 }
 
-static struct ricoh619_regulator ricoh619_regulator[] = {
+static struct ricoh619_regulator ricoh619_regulator_data[] = {
        RICOH619_REG(DC1, 0x2C, 0, 0x2C, 1, 0x36, 0xFF, 0x3B,
                        600000, 3500000, 12500, 0xE8, ricoh619_ops, 500,
                        0x00, 0, 0x00, 0),
@@ -447,13 +502,14 @@ static struct ricoh619_regulator ricoh619_regulator[] = {
                        900000, 3500000, 25000, 0x68, ricoh619_ops, 500,
                        0x00, 0, 0x00, 0),
 };
+
 static inline struct ricoh619_regulator *find_regulator_info(int id)
 {
        struct ricoh619_regulator *ri;
        int i;
 
-       for (i = 0; i < ARRAY_SIZE(ricoh619_regulator); i++) {
-               ri = &ricoh619_regulator[i];
+       for (i = 0; i < ARRAY_SIZE(ricoh619_regulator_data); i++) {
+               ri = &ricoh619_regulator_data[i];
                if (ri->desc.id == id)
                        return ri;
        }
@@ -502,47 +558,105 @@ static inline int ricoh619_cache_regulator_register(struct device *parent,
        return ricoh619_read(parent, ri->vout_reg, &ri->vout_reg_cache);
 }
 
-static int __devinit ricoh619_regulator_probe(struct platform_device *pdev)
+#ifdef CONFIG_OF
+static struct of_regulator_match ricoh619_regulator_matches[] = {
+       { .name = "ricoh619_dc1",},
+       { .name = "ricoh619_dc2",},
+       { .name = "ricoh619_dc3",},
+       { .name = "ricoh619_dc4",},
+       { .name = "ricoh619_dc5",},
+       { .name = "ricoh619_ldo1",},
+       { .name = "ricoh619_ldo2",},
+       { .name = "ricoh619_ldo3",},
+       { .name = "ricoh619_ldo4",},
+       { .name = "ricoh619_ldo5",},
+       { .name = "ricoh619_ldo6",},
+       { .name = "ricoh619_ldo7",},
+       { .name = "ricoh619_ldo8",},
+       { .name = "ricoh619_ldo9",},
+       { .name = "ricoh619_ldo10",},
+       { .name = "ricoh619_ldortc1",},
+       { .name = "ricoh619_ldortc2",},
+};
+#endif
+
+#ifdef CONFIG_OF
+static int ricoh619_regulator_dt_init(struct platform_device *pdev,
+                                   struct regulator_config *config,
+                                   int regidx)
+{
+       struct device_node *nproot, *np;
+       int rcount;
+       nproot = of_node_get(pdev->dev.parent->of_node);
+       if (!nproot)
+               return -ENODEV;
+       np = of_find_node_by_name(nproot, "regulators");
+       if (!np) {
+               dev_err(&pdev->dev, "failed to find regulators node\n");
+               return -ENODEV;
+       }
+
+       rcount = of_regulator_match(&pdev->dev, np,
+                               &ricoh619_regulator_matches[regidx], 1);
+       of_node_put(np);
+       if (rcount < 0)
+               return -ENODEV;
+       config->init_data = ricoh619_regulator_matches[regidx].init_data;
+       config->of_node = ricoh619_regulator_matches[regidx].of_node;
+
+       return 0;
+}
+#else
+#define ricoh619_regulator_dt_init(x, y, z)    (-1)
+#endif
+
+static int ricoh619_regulator_probe(struct platform_device *pdev)
 {
        struct ricoh619_regulator *ri = NULL;
        struct regulator_dev *rdev;
-       struct ricoh619_regulator_platform_data *tps_pdata;
-       int id = pdev->id;
-       int err;
+       struct regulator_config config = { };
+       struct regulator_init_data *pdata_regulator = dev_get_platdata(&pdev->dev);
+       int err,id=0;
+       
+       rdev = devm_kzalloc(&pdev->dev, RICOH619_NUM_REGULATOR *
+                               sizeof(*rdev), GFP_KERNEL);
+       if (!rdev) {
+               dev_err(&pdev->dev, "Mmemory alloc failed\n");
+               return -ENOMEM;
+       }
+
+       for (id = 0; id < RICOH619_NUM_REGULATOR; ++id) {
 
        ri = find_regulator_info(id);
-       if (ri == NULL) {
+       if (!ri) {
                dev_err(&pdev->dev, "invalid regulator ID specified\n");
-               return -EINVAL;
+               err = -EINVAL;
        }
-       tps_pdata = pdev->dev.platform_data;
+
        ri->dev = &pdev->dev;
-/*
-       err = ricoh619_cache_regulator_register(pdev->dev.parent, ri);
-       if (err) {
-               dev_err(&pdev->dev, "Fail in caching register\n");
-               return err;
-       }
+       config.dev = &pdev->dev;
+       config.driver_data = ri;
 
-       err = ricoh619_regulator_preinit(pdev->dev.parent, ri, tps_pdata);
-       if (err) {
-               dev_err(&pdev->dev, "Fail in pre-initialisation\n");
-               return err;
-       }
-       */
-       rdev = regulator_register(&ri->desc, &pdev->dev,
-                               &tps_pdata->regulator, ri);
+       if (ricoh619_regulator_matches)
+               config.of_node = ricoh619_regulator_matches[id].of_node;
+
+       if (ricoh619_regulator_dt_init(pdev, &config, id))
+               if (pdata_regulator)
+                       config.init_data = &pdata_regulator;
+
+       rdev = regulator_register(&ri->desc, &config);
        if (IS_ERR_OR_NULL(rdev)) {
                dev_err(&pdev->dev, "failed to register regulator %s\n",
                                ri->desc.name);
                return PTR_ERR(rdev);
        }
+       }
 
        platform_set_drvdata(pdev, rdev);
        return 0;
 }
 
-static int __devexit ricoh619_regulator_remove(struct platform_device *pdev)
+static int ricoh619_regulator_remove(struct platform_device *pdev)
 {
        struct regulator_dev *rdev = platform_get_drvdata(pdev);
 
@@ -556,7 +670,7 @@ static struct platform_driver ricoh619_regulator_driver = {
                .owner  = THIS_MODULE,
        },
        .probe          = ricoh619_regulator_probe,
-       .remove         = __devexit_p(ricoh619_regulator_remove),
+       .remove         = ricoh619_regulator_remove,
 };
 
 static int __init ricoh619_regulator_init(void)
diff --git a/drivers/regulator/syb827.c b/drivers/regulator/syb827.c
new file mode 100755 (executable)
index 0000000..ec1ada5
--- /dev/null
@@ -0,0 +1,584 @@
+/*
+ * Regulator driver for syb827 DCDC chip for rk32xx
+ *
+ * Copyright (C) 2010, 2011 ROCKCHIP, Inc.
+
+ * Based on syb827.c that is work by zhangqing<zhangqing@rock-chips.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/bug.h>
+#include <linux/err.h>
+#include <linux/i2c.h>
+#include <linux/kernel.h>
+#include <linux/regulator/driver.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <linux/mutex.h>
+#include <linux/mfd/core.h>
+
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/of_irq.h>
+#include <linux/of_gpio.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/regulator/of_regulator.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/machine.h>
+#include <linux/regmap.h>
+
+#if 0
+#define DBG(x...)      printk(KERN_INFO x)
+#else
+#define DBG(x...)
+#endif
+#if 1
+#define DBG_INFO(x...) printk(KERN_INFO x)
+#else
+#define DBG_INFO(x...)
+#endif
+#define PM_CONTROL
+
+#define SYB827_SPEED 200*1000
+#define syb827_NUM_REGULATORS 1
+
+struct syb827 {
+       struct device *dev;
+       struct mutex io_lock;
+       struct i2c_client *i2c;
+       int num_regulators;
+       struct regulator_dev **rdev;
+       int irq_base;
+       int chip_irq;
+       int sleep_gpio; /* */
+       unsigned int dcdc_slp_voltage[3]; /* buckx_voltage in uV */
+       bool pmic_sleep;
+       struct regmap *regmap;
+};
+
+struct syb827_regulator {
+       struct device           *dev;
+       struct regulator_desc   *desc;
+       struct regulator_dev    *rdev;
+};
+struct syb827_board {
+       int irq;
+       int irq_base;
+       struct regulator_init_data *syb827_init_data[syb827_NUM_REGULATORS];
+       struct device_node *of_node[syb827_NUM_REGULATORS];
+       int sleep_gpio; /* */
+       unsigned int dcdc_slp_voltage[3]; /* buckx_voltage in uV */
+       bool sleep;
+};
+
+struct syb827_regulator_subdev {
+       int id;
+       struct regulator_init_data *initdata;
+       struct device_node *reg_node;
+};
+
+struct syb827_platform_data {
+       int ono;
+       int num_regulators;
+       struct syb827_regulator_subdev *regulators;
+       
+       int sleep_gpio; /* */
+       unsigned int dcdc_slp_voltage[3]; /* buckx_voltage in uV */
+       bool sleep;
+};
+struct syb827 *g_syb827;
+
+static u8 syb827_reg_read(struct syb827 *syb827, u8 reg);
+static int syb827_set_bits(struct syb827 *syb827, u8 reg, u16 mask, u16 val);
+
+
+#define SYB827_BUCK1_SET_VOL_BASE 0x00
+#define SYB827_BUCK1_SLP_VOL_BASE 0x01
+#define SYB827_CONTR_REG1 0x02
+#define SYB827_ID1_REG 0x03
+#define SYB827_ID2_REG 0x04
+#define SYB827_CONTR_REG2 0x05
+
+#define BUCK_VOL_MASK 0x3f
+#define VOL_MIN_IDX 0x00
+#define VOL_MAX_IDX 0x3f
+
+const static int buck_voltage_map[] = {
+        712500, 725000, 737500,750000, 762500,775000,787500,800000,
+        812500, 825000, 837500,850000, 862500,875000,887500,900000,
+        912500, 925000, 937500,950000, 962500,975000,987500,1000000,
+        1012500, 1025000, 1037500,1050000, 1062500,1075000,1087500,1100000,
+        1112500, 1125000, 1137500,1150000, 1162500,1175000,1187500,1200000,
+        1212500, 1225000, 1237500,1250000, 1262500,1275000,1287500,1300000,
+        1312500, 1325000, 1337500,1350000, 1362500,1375000,1387500,1400000,
+        1412500, 1425000, 1437500,1450000, 1462500,1475000,1487500,1500000,
+};
+
+static int syb827_dcdc_list_voltage(struct regulator_dev *dev, unsigned index)
+{
+       if (index >= ARRAY_SIZE(buck_voltage_map))
+               return -EINVAL;
+       return  buck_voltage_map[index];
+}
+static int syb827_dcdc_is_enabled(struct regulator_dev *dev)
+{
+       struct syb827 *syb827 = rdev_get_drvdata(dev);
+       u16 val;
+       u16 mask=0x80;  
+       val = syb827_reg_read(syb827, SYB827_BUCK1_SET_VOL_BASE);
+       if (val < 0)
+               return val;
+        val=val&~0x7f;
+       if (val & mask)
+               return 1;
+       else
+               return 0;       
+}
+static int syb827_dcdc_enable(struct regulator_dev *dev)
+{
+       struct syb827 *syb827 = rdev_get_drvdata(dev);
+       u16 mask=0x80;  
+
+       return syb827_set_bits(syb827, SYB827_BUCK1_SET_VOL_BASE, mask, 0x80);
+
+}
+static int syb827_dcdc_disable(struct regulator_dev *dev)
+{
+       struct syb827 *syb827 = rdev_get_drvdata(dev);
+       u16 mask=0x80;
+        return syb827_set_bits(syb827, SYB827_BUCK1_SET_VOL_BASE, mask, 0);
+}
+static int syb827_dcdc_get_voltage(struct regulator_dev *dev)
+{
+       struct syb827 *syb827 = rdev_get_drvdata(dev);
+       u16 reg = 0;
+       int val;
+       reg = syb827_reg_read(syb827,SYB827_BUCK1_SET_VOL_BASE);
+       reg &= BUCK_VOL_MASK;
+       val = buck_voltage_map[reg];    
+       return val;
+}
+static int syb827_dcdc_set_voltage(struct regulator_dev *dev,
+                                 int min_uV, int max_uV,unsigned *selector)
+{
+       struct syb827 *syb827 = rdev_get_drvdata(dev);
+       const int *vol_map = buck_voltage_map;
+       u16 val;
+       int ret = 0;
+       
+       if (min_uV < vol_map[VOL_MIN_IDX] ||
+           min_uV > vol_map[VOL_MAX_IDX])
+               return -EINVAL;
+
+       for (val = VOL_MIN_IDX; val <= VOL_MAX_IDX; val++){
+               if (vol_map[val] >= min_uV)
+                       break;
+        }
+
+       if (vol_map[val] > max_uV)
+               printk("WARNING:this voltage is not support!voltage set is %d mv\n",vol_map[val]);
+
+       ret = syb827_set_bits(syb827, SYB827_BUCK1_SET_VOL_BASE ,BUCK_VOL_MASK, val);
+       
+       return ret;
+}
+
+static unsigned int syb827_dcdc_get_mode(struct regulator_dev *dev)
+{
+       struct syb827 *syb827 = rdev_get_drvdata(dev);
+       u16 mask = 0x40;
+       u16 val;
+       val = syb827_reg_read(syb827, SYB827_BUCK1_SET_VOL_BASE);
+        if (val < 0) {
+                return val;
+        }
+       val=val & mask;
+       if (val== mask)
+               return REGULATOR_MODE_FAST;
+       else
+               return REGULATOR_MODE_NORMAL;
+
+}
+static int syb827_dcdc_set_mode(struct regulator_dev *dev, unsigned int mode)
+{
+       struct syb827 *syb827 = rdev_get_drvdata(dev);
+       u16 mask = 0x40;
+
+       switch(mode)
+       {
+       case REGULATOR_MODE_FAST:
+               return syb827_set_bits(syb827,SYB827_BUCK1_SET_VOL_BASE, mask, mask);
+       case REGULATOR_MODE_NORMAL:
+               return syb827_set_bits(syb827, SYB827_BUCK1_SET_VOL_BASE, mask, 0);
+       default:
+               printk("error:dcdc_syb827 only auto and pwm mode\n");
+               return -EINVAL;
+       }
+}
+static int syb827_dcdc_set_voltage_time_sel(struct regulator_dev *dev,   unsigned int old_selector,
+                                    unsigned int new_selector)
+{
+       int old_volt, new_volt;
+       
+       old_volt = syb827_dcdc_list_voltage(dev, old_selector);
+       if (old_volt < 0)
+               return old_volt;
+       
+       new_volt = syb827_dcdc_list_voltage(dev, new_selector);
+       if (new_volt < 0)
+               return new_volt;
+
+       return DIV_ROUND_UP(abs(old_volt - new_volt), 10000);
+}
+static int syb827_dcdc_suspend_enable(struct regulator_dev *dev)
+{
+       struct syb827 *syb827 = rdev_get_drvdata(dev);
+       u16 mask=0x80;  
+       
+       return syb827_set_bits(syb827, SYB827_BUCK1_SLP_VOL_BASE, mask, 0x80);
+
+}
+static int syb827_dcdc_suspend_disable(struct regulator_dev *dev)
+{
+       struct syb827 *syb827 = rdev_get_drvdata(dev);
+       u16 mask=0x80;
+        return syb827_set_bits(syb827, SYB827_BUCK1_SLP_VOL_BASE, mask, 0);
+}
+static int syb827_dcdc_set_sleep_voltage(struct regulator_dev *dev,
+                                           int uV)
+{
+       struct syb827 *syb827 = rdev_get_drvdata(dev);
+       const int *vol_map = buck_voltage_map;
+       u16 val;
+       int ret = 0;
+       
+       if (uV < vol_map[VOL_MIN_IDX] ||
+           uV > vol_map[VOL_MAX_IDX])
+               return -EINVAL;
+
+       for (val = VOL_MIN_IDX; val <= VOL_MAX_IDX; val++){
+               if (vol_map[val] >= uV)
+                       break;
+        }
+
+       if (vol_map[val] > uV)
+               printk("WARNING:this voltage is not support!voltage set is %d mv\n",vol_map[val]);
+       ret = syb827_set_bits(syb827,SYB827_BUCK1_SLP_VOL_BASE ,BUCK_VOL_MASK, val);    
+       return ret;
+}
+
+
+static int syb827_dcdc_set_suspend_mode(struct regulator_dev *dev, unsigned int mode)
+{
+       struct syb827 *syb827 = rdev_get_drvdata(dev);
+       u16 mask = 0x40;
+
+       switch(mode)
+       {
+       case REGULATOR_MODE_FAST:
+               return syb827_set_bits(syb827,SYB827_BUCK1_SLP_VOL_BASE, mask, mask);
+       case REGULATOR_MODE_NORMAL:
+               return syb827_set_bits(syb827, SYB827_BUCK1_SLP_VOL_BASE, mask, 0);
+       default:
+               printk("error:dcdc_syb827 only auto and pwm mode\n");
+               return -EINVAL;
+       }
+}
+
+static struct regulator_ops syb827_dcdc_ops = { 
+       .set_voltage = syb827_dcdc_set_voltage,
+       .get_voltage = syb827_dcdc_get_voltage,
+       .list_voltage= syb827_dcdc_list_voltage,
+       .is_enabled = syb827_dcdc_is_enabled,
+       .enable = syb827_dcdc_enable,
+       .disable = syb827_dcdc_disable,
+       .get_mode = syb827_dcdc_get_mode,
+       .set_mode = syb827_dcdc_set_mode,
+       .set_suspend_voltage = syb827_dcdc_set_sleep_voltage,
+       .set_suspend_enable = syb827_dcdc_suspend_enable,
+       .set_suspend_disable = syb827_dcdc_suspend_disable,
+       .set_suspend_mode = syb827_dcdc_set_suspend_mode,
+       .set_voltage_time_sel = syb827_dcdc_set_voltage_time_sel,
+};
+static struct regulator_desc regulators[] = {
+
+        {
+               .name = "SY_DCDC1",
+               .id = 0,
+               .ops = &syb827_dcdc_ops,
+               .n_voltages = ARRAY_SIZE(buck_voltage_map),
+               .type = REGULATOR_VOLTAGE,
+               .owner = THIS_MODULE,
+       },
+};
+
+static int syb827_i2c_read(struct i2c_client *i2c, char reg, int count,        u16 *dest)
+{
+      int ret;
+    struct i2c_adapter *adap;
+    struct i2c_msg msgs[2];
+
+    if(!i2c)
+               return ret;
+
+       if (count != 1)
+               return -EIO;  
+  
+    adap = i2c->adapter;               
+    
+    msgs[0].addr = i2c->addr;
+    msgs[0].buf = &reg;
+    msgs[0].flags = i2c->flags;
+    msgs[0].len = 1;
+    msgs[0].scl_rate = SYB827_SPEED;
+    
+    msgs[1].buf = (u8 *)dest;
+    msgs[1].addr = i2c->addr;
+    msgs[1].flags = i2c->flags | I2C_M_RD;
+    msgs[1].len = 1;
+    msgs[1].scl_rate = SYB827_SPEED;
+    ret = i2c_transfer(adap, msgs, 2);
+
+       DBG("***run in %s %d msgs[1].buf = %d\n",__FUNCTION__,__LINE__,*(msgs[1].buf));
+
+       return 0;   
+}
+
+static int syb827_i2c_write(struct i2c_client *i2c, char reg, int count, const u16 src)
+{
+       int ret=-1;
+       
+       struct i2c_adapter *adap;
+       struct i2c_msg msg;
+       char tx_buf[2];
+
+       if(!i2c)
+               return ret;
+       if (count != 1)
+               return -EIO;
+    
+       adap = i2c->adapter;            
+       tx_buf[0] = reg;
+       tx_buf[1] = src;
+       
+       msg.addr = i2c->addr;
+       msg.buf = &tx_buf[0];
+       msg.len = 1 +1;
+       msg.flags = i2c->flags;   
+       msg.scl_rate = SYB827_SPEED;    
+
+       ret = i2c_transfer(adap, &msg, 1);
+       return ret;     
+}
+
+static u8 syb827_reg_read(struct syb827 *syb827, u8 reg)
+{
+       u16 val = 0;
+
+       mutex_lock(&syb827->io_lock);
+
+       syb827_i2c_read(syb827->i2c, reg, 1, &val);
+
+       DBG("reg read 0x%02x -> 0x%02x\n", (int)reg, (unsigned)val&0xff);
+
+       mutex_unlock(&syb827->io_lock);
+
+       return val & 0xff;      
+}
+
+static int syb827_set_bits(struct syb827 *syb827, u8 reg, u16 mask, u16 val)
+{
+       u16 tmp;
+       int ret;
+
+       mutex_lock(&syb827->io_lock);
+
+       ret = syb827_i2c_read(syb827->i2c, reg, 1, &tmp);
+       DBG("1 reg read 0x%02x -> 0x%02x\n", (int)reg, (unsigned)tmp&0xff);
+       tmp = (tmp & ~mask) | val;
+       if (ret == 0) {
+               ret = syb827_i2c_write(syb827->i2c, reg, 1, tmp);
+               DBG("reg write 0x%02x -> 0x%02x\n", (int)reg, (unsigned)val&0xff);
+       }
+       syb827_i2c_read(syb827->i2c, reg, 1, &tmp);
+       DBG("2 reg read 0x%02x -> 0x%02x\n", (int)reg, (unsigned)tmp&0xff);
+       mutex_unlock(&syb827->io_lock);
+
+       return 0;//ret; 
+}
+
+#ifdef CONFIG_OF
+static struct of_device_id syb827_of_match[] = {
+       { .compatible = "silergy,syb827"},
+       { },
+};
+MODULE_DEVICE_TABLE(of, syb827_of_match);
+#endif
+#ifdef CONFIG_OF
+static struct of_regulator_match syb827_reg_matches[] = {
+       { .name = "syb827_dcdc1" ,.driver_data = (void *)0},
+};
+
+static struct syb827_board *syb827_parse_dt(struct syb827 *syb827)
+{
+       struct syb827_board *pdata;
+       struct device_node *regs;
+       struct device_node *syb827_np;
+       int gpio,count;
+       DBG("%s,line=%d\n", __func__,__LINE__); 
+       
+       syb827_np = of_node_get(syb827->dev->of_node);
+       if (!syb827_np) {
+               printk("could not find pmic sub-node\n");
+               return NULL;
+       }
+       
+       regs = of_find_node_by_name(syb827_np, "regulators");
+       if (!regs)
+               return NULL;
+       count = of_regulator_match(syb827->dev, regs, syb827_reg_matches,
+                                  syb827_NUM_REGULATORS);
+       of_node_put(regs);
+       pdata = devm_kzalloc(syb827->dev, sizeof(*pdata), GFP_KERNEL);
+       if (!pdata)
+               return NULL;
+       pdata->syb827_init_data[0] = syb827_reg_matches[0].init_data;
+       pdata->of_node[0] = syb827_reg_matches[0].of_node;
+       
+       return pdata;
+}
+
+#else
+static struct syb827_board *syb827_parse_dt(struct i2c_client *i2c)
+{
+       return NULL;
+}
+#endif
+
+static int syb827_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id)
+{
+       struct syb827 *syb827;  
+       struct syb827_board *pdev ;
+       const struct of_device_id *match;
+       struct regulator_config config = { };
+       struct regulator_dev *sy_rdev;
+       struct regulator_init_data *reg_data;
+       const char *rail_name = NULL;
+       int ret;
+       
+       DBG("%s,line=%d\n", __func__,__LINE__); 
+
+       if (i2c->dev.of_node) {
+               match = of_match_device(syb827_of_match, &i2c->dev);
+               if (!match) {
+                       printk("Failed to find matching dt id\n");
+                       return -EINVAL;
+               }
+       }
+
+       syb827 = devm_kzalloc(&i2c->dev,sizeof(struct syb827), GFP_KERNEL);
+       if (syb827 == NULL) {
+               ret = -ENOMEM;          
+               goto err;
+       }
+       syb827->i2c = i2c;
+       syb827->dev = &i2c->dev;
+       i2c_set_clientdata(i2c, syb827);
+       g_syb827 = syb827;
+               
+       mutex_init(&syb827->io_lock);   
+
+       ret = syb827_reg_read(syb827,SYB827_ID1_REG);
+       if ((ret <0) ||(ret ==0xff) ||(ret ==0)){
+               printk("The device is not syb827 %x \n",ret);
+               goto err;
+       }
+
+       if (syb827->dev->of_node)
+               pdev = syb827_parse_dt(syb827);
+       
+       if (pdev) {
+               syb827->num_regulators = syb827_NUM_REGULATORS;
+               syb827->rdev = kcalloc(syb827_NUM_REGULATORS,sizeof(struct regulator_dev *), GFP_KERNEL);
+               if (!syb827->rdev) {
+                       return -ENOMEM;
+               }
+               /* Instantiate the regulators */
+               reg_data = pdev->syb827_init_data[0];
+               config.dev = syb827->dev;
+               config.driver_data = syb827;
+               if (syb827->dev->of_node)
+                       config.of_node = pdev->of_node[0];
+                       if (reg_data && reg_data->constraints.name)
+                               rail_name = reg_data->constraints.name;
+                       else
+                               rail_name = regulators[0].name;
+                       reg_data->supply_regulator = rail_name;
+       
+               config.init_data =reg_data;
+               sy_rdev = regulator_register(&regulators[0],&config);
+               if (IS_ERR(sy_rdev)) {
+                       printk("failed to register regulator\n");
+               goto err;
+               }
+               syb827->rdev[0] = sy_rdev;
+       }
+       return 0;
+err:
+       return ret;     
+
+}
+
+static int  syb827_i2c_remove(struct i2c_client *i2c)
+{
+       struct syb827 *syb827 = i2c_get_clientdata(i2c);
+
+       if (syb827->rdev[0])
+               regulator_unregister(syb827->rdev[0]);
+       i2c_set_clientdata(i2c, NULL);
+       return 0;
+}
+
+static const struct i2c_device_id syb827_i2c_id[] = {
+       { "syb827", 0 },
+       { }
+};
+
+MODULE_DEVICE_TABLE(i2c, syb827_i2c_id);
+
+static struct i2c_driver syb827_i2c_driver = {
+       .driver = {
+               .name = "syb827",
+               .owner = THIS_MODULE,
+               .of_match_table =of_match_ptr(syb827_of_match),
+       },
+       .probe    = syb827_i2c_probe,
+       .remove   = syb827_i2c_remove,
+       .id_table = syb827_i2c_id,
+};
+
+static int __init syb827_module_init(void)
+{
+       int ret;
+       ret = i2c_add_driver(&syb827_i2c_driver);
+       if (ret != 0)
+               pr_err("Failed to register I2C driver: %d\n", ret);
+       return ret;
+}
+subsys_initcall_sync(syb827_module_init);
+
+static void __exit syb827_module_exit(void)
+{
+       i2c_del_driver(&syb827_i2c_driver);
+}
+module_exit(syb827_module_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("zhangqing <zhangqing@rock-chips.com>");
+MODULE_DESCRIPTION("syb827 PMIC driver");
+
old mode 100644 (file)
new mode 100755 (executable)
index 33d86af..33b6eb4
@@ -1253,6 +1253,16 @@ config RTC_DRV_HID_SENSOR_TIME
 
          If this driver is compiled as a module, it will be named
          rtc-hid-sensor-time.
+         
+config RTC_DRV_RC5T619
+       tristate "RICOH RC5T619 PMU RTC driver"
+       depends on MFD_RICOH619
+       default n
+       help
+         If you say yes here you get support for the RICOH RC5T619 RTC module.
+
+         This driver can also be built as a module. If so, the module
+         will be called rtc-rc5t619.
 
 
 endif # RTC_CLASS
old mode 100644 (file)
new mode 100755 (executable)
index d90aa26..8cd446a
@@ -129,3 +129,5 @@ obj-$(CONFIG_RTC_DRV_WM831X)        += rtc-wm831x.o
 obj-$(CONFIG_RK808_RTC)  += rtc-rk808.o
 obj-$(CONFIG_RTC_DRV_WM8350)   += rtc-wm8350.o
 obj-$(CONFIG_RTC_DRV_X1205)    += rtc-x1205.o
+obj-$(CONFIG_RTC_DRV_RC5T619)  += rtc-ricoh619.o
+
index 1db0367b0141e8b7ffd92b8853e5a8c294202820..b70507aa4b6aab00bf512c73f4a1478985ed0157 100755 (executable)
 #include <linux/err.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
+#include <linux/module.h>
 #include <linux/mfd/ricoh619.h>
 #include <linux/rtc/rtc-ricoh619.h>
 #include <linux/platform_device.h>
 #include <linux/rtc.h>
 #include <linux/slab.h>
+#include <linux/irqdomain.h>
+
 
 struct ricoh619_rtc {
        int                     irq;
@@ -76,7 +79,7 @@ static int ricoh619_rtc_valid_tm(struct device *dev, struct rtc_time *tm)
                || tm->tm_mon > 11 || tm->tm_mon < 0
                || tm->tm_mday < 1
                || tm->tm_mday > rtc_month_days(tm->tm_mon, tm->tm_year + os_ref_year)
-               || tm->tm_hour >= 24 || tm->tm_hour <0
+               || tm->tm_hour >= 24 || tm->tm_hour < 0
                || tm->tm_min < 0 || tm->tm_min >= 60
                || tm->tm_sec < 0 || tm->tm_sec >= 60   
                ) 
@@ -144,14 +147,14 @@ static int ricoh619_rtc_periodic_disable(struct device *dev)
        err = ricoh619_read_regs(dev, rtc_ctrl2, 1, &reg_data);
        if(err < 0)
        {
-               dev_err(dev->parent, "read rtc_ctrl1 error=0x%x\n", err);
+               dev_err(dev->parent, "read rtc_ctrl2 error=0x%x\n", err);
                return err;
        }
        reg_data &= ~0x85;// 1000-0101
        err = ricoh619_write_regs(dev, rtc_ctrl2, 1, &reg_data);
        if(err < 0)
        {
-               dev_err(dev->parent, "read rtc_ctrl1 error=0x%x\n", err);
+               dev_err(dev->parent, "read rtc_ctrl2 error=0x%x\n", err);
                return err;
        }
 
@@ -168,7 +171,7 @@ static int ricoh619_rtc_Pon_get_clr(struct device *dev, uint8_t *Pon_f)
        int err;
        uint8_t reg_data;
        
-       err = ricoh619_read_regs(dev, rtc_ctrl2, 1, &reg_data);
+       err = ricoh619_read_regs(dev, rtc_ctrl2,1,&reg_data);
        if(err < 0)
        {
                dev_err(dev->parent, "rtc_ctrl1 read err=0x%x\n", err);
@@ -182,7 +185,7 @@ static int ricoh619_rtc_Pon_get_clr(struct device *dev, uint8_t *Pon_f)
                //clear VDET PON
                reg_data &= ~0x5b;// 0101-1011
                reg_data |= 0x20; // 0010-0000
-               err = ricoh619_write_regs(dev, rtc_ctrl2, 1, &reg_data);
+               err = ricoh619_write_regs(dev, rtc_ctrl2, 1,&reg_data);
                if(err < 0)
                {
                        dev_err(dev->parent, "rtc_ctrl1 write err=0x%x\n", err);
@@ -245,9 +248,7 @@ static int ricoh619_rtc_read_time(struct device *dev, struct rtc_time *tm)
        u8 buff[7];
        int err;
        int cent_flag;
-       int i;
 
-//     printk(KERN_INFO "PMU: %s\n", __func__);
        err = ricoh619_read_regs(dev, rtc_seconds_reg, sizeof(buff), buff);
                
        if (err < 0) {
@@ -272,7 +273,10 @@ static int ricoh619_rtc_read_time(struct device *dev, struct rtc_time *tm)
        tm->tm_year = buff[6] + 100 * cent_flag;
        print_time(dev, tm);    //for print
        tm->tm_mon  = buff[5] - 1;  //back to system 0-11 
-               
+
+//     printk(KERN_INFO "PMU: %s year=%d mon=%d day=% hour=%d min =%d sec=%d\n", __func__,
+//     tm->tm_year,tm->tm_mon  ,tm->tm_mday,tm->tm_hour,tm->tm_min,tm->tm_sec );
+
        return 0;
 }
 
@@ -282,7 +286,8 @@ static int ricoh619_rtc_set_time(struct device *dev, struct rtc_time *tm)
        int err;
        int cent_flag;
 
-//     printk(KERN_INFO "PMU: %s\n", __func__);        
+//     printk(KERN_INFO "PMU: %s year=%d mon=%d day=% hour=%d min =%d sec=%d\n", __func__,
+//     tm->tm_year,tm->tm_mon  ,tm->tm_mday,tm->tm_hour,tm->tm_min,tm->tm_sec );
 
        if(ricoh619_rtc_valid_tm(dev, tm) != 0)
        {
@@ -325,10 +330,10 @@ static int ricoh619_rtc_alarm_is_enabled(struct device *dev,  uint8_t *enabled)
        uint8_t reg_data;
 
        err = 0;
-       err = ricoh619_read_regs(dev, rtc_ctrl1, 1,&reg_data);
-       if(err)
+       err = ricoh619_read_regs(dev, rtc_ctrl1,1,&reg_data);
+       if(err<0)
        {
-               dev_err(dev->parent, "read rtc_ctrl1 error 0x%lx\n", err);
+               dev_err(dev->parent, "read rtc_ctrl1 error 0x%x\n", err);
                *enabled = 0;
        }
        else
@@ -415,14 +420,14 @@ static int ricoh619_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
                cent_flag = 0;
 
        err = ricoh619_read_regs(dev, rtc_alarm_y_sec, sizeof(buff), buff);
-       if(err)
+       if(err <0)
        {
                dev_err(dev->parent, "RTC: %s *** read rtc_alarm timer error 0x%lx\n", __func__, err);
                return err;
        }
        
        err = ricoh619_read_regs(dev, rtc_ctrl1, 1,&enabled_flag);
-       if(err)
+       if(err<0)
        {
                dev_err(dev->parent, "RTC: %s *** read rtc_enable flag error 0x%lx\n", __func__, err);
                return err;
@@ -487,7 +492,7 @@ static int ricoh619_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
        convert_decimal_to_bcd(buff, sizeof(buff));
        buff[3] |= 0x80;        /* set DAL_EXT */
        err = ricoh619_write_regs(dev, rtc_alarm_y_sec, sizeof(buff), buff);
-       if (err) {
+       if (err<0) {
                dev_err(dev->parent, "\n unable to set alarm\n");
                err = -EBUSY;
                goto ERR;
@@ -514,13 +519,13 @@ static int ricoh619_rtc_alarm_flag_clr(struct device *dev)
 
        /* clear alarm-D status bits.*/
        err = ricoh619_read_regs(dev, rtc_ctrl2, 1, &reg_data);
-       if (err)
+       if (err<0)
                dev_err(dev->parent, "unable to read rtc_ctrl2 reg\n");
 
        /* to clear alarm-D flag, and set adjustment parameter */
        reg_data &= ~0x81;
        err = ricoh619_write_regs(dev, rtc_ctrl2, 1, &reg_data);
-       if (err)
+       if (err<0)
                dev_err(dev->parent, "unable to program rtc_status reg\n");
        return err;
 }
@@ -537,31 +542,70 @@ static irqreturn_t ricoh619_rtc_irq(int irq, void *data)
        return IRQ_HANDLED;
 }
 
-static int __devinit ricoh619_rtc_probe(struct platform_device *pdev)
+#ifdef CONFIG_OF
+static struct ricoh619_rtc_platform_data *ricoh619_rtc_dt_init(struct platform_device *pdev)
+{
+       struct device_node *nproot = pdev->dev.parent->of_node;
+       struct device_node *np;
+       struct ricoh619_rtc_platform_data *pdata;
+
+       if (!nproot)
+               return pdev->dev.platform_data;
+
+       np = of_find_node_by_name(nproot, "rtc");
+       if (!np) {
+               dev_err(&pdev->dev, "failed to find rtc node\n");
+               return NULL;
+       }
+
+       pdata = devm_kzalloc(&pdev->dev,
+                       sizeof(struct ricoh619_rtc_platform_data),
+                       GFP_KERNEL);
+
+       of_property_read_u32(np, "ricoh,rtc-tm-year", &pdata->time.tm_year);
+       of_property_read_u32(np, "ricoh,rtc-tm-month", &pdata->time.tm_mon);
+       of_property_read_u32(np, "ricoh,rtc-tm-mday", &pdata->time.tm_mday);
+       of_property_read_u32(np, "ricoh,rtc-tm-hour", &pdata->time.tm_hour);
+       of_property_read_u32(np, "ricoh,rtc-tm-min", &pdata->time.tm_min);
+       of_property_read_u32(np, "ricoh,rtc-tm-sec", &pdata->time.tm_sec);
+       of_node_put(np);
+
+       return pdata;
+}
+#else
+static struct ricoh619_rtc_platform_data *
+ricoh619_rtc_dt_init(struct platform_device *pdev)
+{
+       return pdev->dev.platform_data;
+}
+#endif
+
+static int ricoh619_rtc_probe(struct platform_device *pdev)
 {
-       struct ricoh619_rtc_platform_data *pdata = pdev->dev.platform_data;
+       struct ricoh619_rtc_platform_data *pdata;
+       struct ricoh619 *ricoh619 = dev_get_drvdata(pdev->dev.parent);
        struct ricoh619_rtc *rtc;
        struct rtc_time tm;
        uint8_t Pon_flag,Alarm_flag;
        int err;
        uint8_t buff[6];
 
-//     printk(KERN_INFO "******PMU RTC: Version 2013-08-01 REDS!******\n");
-//     printk(KERN_INFO "PMU RTC: %s, ricoh619 driver run at 24H-mode\n", __func__);
-//     printk(KERN_INFO "PMU RTC: we never using periodic function and interrupt\n");
+//     printk(KERN_INFO "******PMU RTC: Version 2014-01-01 REDS!******\n");
 
-       if(!pdata) 
-       {
-               dev_err(&pdev->dev, "no platform_data specified\n");
+       pdata = ricoh619_rtc_dt_init(pdev);
+       if (!pdata) {
+               dev_err(&pdev->dev, "platform data isn't assigned to "
+                       "rtc\n");
                return -EINVAL;
        }
+        printk("%s,line=%d\n", __func__,__LINE__);
 
-       rtc = kzalloc(sizeof(*rtc), GFP_KERNEL);
+       rtc = devm_kzalloc(ricoh619->dev,sizeof(*rtc), GFP_KERNEL);
        if(IS_ERR(rtc))
        {
                err = PTR_ERR(rtc);
                dev_err(&pdev->dev, "no enough memory for ricoh619_rtc using\n");
-               return err;
+               return -ENOMEM;
        }
        
        dev_set_drvdata(&pdev->dev, rtc);
@@ -570,22 +614,19 @@ static int __devinit ricoh619_rtc_probe(struct platform_device *pdev)
                err = PTR_ERR(rtc->rtc);
                goto fail;
        }
-
-       if(pdata->irq < 0)
+       
+       rtc->irq  = irq_create_mapping(ricoh619->irq_domain, RICOH619_IRQ_DALE);
+       if(rtc->irq  < 0)
        {
                dev_err(&pdev->dev, "\n no irq specified, wakeup is disabled\n");
                rtc->irq = -1;
                rtc->irq_en = 0;
        }
        else
-       {
-               rtc->irq = pdata->irq;
                rtc->irq_en = 1;
-       }
-
        //get interrupt flag
        err = ricoh619_rtc_alarm_is_enabled(&pdev->dev, &Alarm_flag);
-       if(err)
+       if (err<0)
        {
                dev_err(&pdev->dev, "5T619 RTC: Disable alarm interrupt error\n");
                goto fail;
@@ -594,7 +635,7 @@ static int __devinit ricoh619_rtc_probe(struct platform_device *pdev)
 
        // get PON flag
        err = ricoh619_rtc_Pon_get_clr(&pdev->dev, &Pon_flag);
-       if(err)
+       if (err<0)
        {
                dev_err(&pdev->dev, "5T619 RTC: get PON flag error\n");
                goto fail;
@@ -602,7 +643,7 @@ static int __devinit ricoh619_rtc_probe(struct platform_device *pdev)
 
        // disable rtc periodic function
        err = ricoh619_rtc_periodic_disable(&pdev->dev);
-       if(err)
+       if (err<0)
        {
                dev_err(&pdev->dev, "5T619 RTC: disable rtc periodic int error\n");
                goto fail;
@@ -610,7 +651,7 @@ static int __devinit ricoh619_rtc_probe(struct platform_device *pdev)
 
        // clearing RTC Adjust register
        err = ricoh619_rtc_clk_adjust(&pdev->dev, 0);
-       if(err) 
+       if (err<0)
        {
                dev_err(&pdev->dev, "unable to program rtc_adjust reg\n");
                err = -EBUSY;
@@ -619,7 +660,7 @@ static int __devinit ricoh619_rtc_probe(struct platform_device *pdev)
 
        //disable interrupt
        err = ricoh619_rtc_alarm_enable(&pdev->dev, 0);
-       if(err)
+       if (err<0)
        {
                dev_err(&pdev->dev, "5T619 RTC: Disable alarm interrupt error\n");
                goto fail;
@@ -631,7 +672,7 @@ static int __devinit ricoh619_rtc_probe(struct platform_device *pdev)
                Alarm_flag = 0;
                // clear int flag
                err = ricoh619_rtc_alarm_flag_clr(&pdev->dev);
-               if(err)
+               if (err<0)
                {
                        dev_err(&pdev->dev, "5T619 RTC: Pon=1 clear alarm flag error\n");
                        goto fail;
@@ -639,7 +680,7 @@ static int __devinit ricoh619_rtc_probe(struct platform_device *pdev)
 
                // using 24h-mode
                err = ricoh619_rtc_hour_mode_set(&pdev->dev,1);
-               if(err)
+               if (err<0)
                {
                        dev_err(&pdev->dev, "5T619 RTC: Pon=1 set 24h-mode error\n");
                        goto fail;
@@ -691,7 +732,7 @@ static int __devinit ricoh619_rtc_probe(struct platform_device *pdev)
                buff[4] = tm.tm_mon +1;
                
                err = ricoh619_rtc_set_time(&pdev->dev, &tm);
-               if(err) 
+               if (err<0)
                {
                        dev_err(&pdev->dev, "5t619 RTC:\n failed to set time\n");
                        goto fail;
@@ -701,7 +742,7 @@ static int __devinit ricoh619_rtc_probe(struct platform_device *pdev)
                buff[3] |= 0x80;        /* set DAL_EXT */
 
                err = ricoh619_write_regs(&pdev->dev, rtc_alarm_y_sec, sizeof(buff), buff);
-               if (err
+               if (err<0)
                        printk( "\n unable to set alarm\n");
 
        }
@@ -713,29 +754,26 @@ static int __devinit ricoh619_rtc_probe(struct platform_device *pdev)
                                       &ricoh619_rtc_ops, THIS_MODULE);
 
        // set interrupt and enable it
-       if(rtc->irq != -1) 
-       {
-               rtc->irq = rtc->irq + RICOH619_IRQ_DALE;
-               err = request_threaded_irq(rtc->irq, NULL, ricoh619_rtc_irq,
+       if(rtc->irq != -1) {
+               err = devm_request_threaded_irq(&pdev->dev,rtc->irq, NULL, ricoh619_rtc_irq,
                                        IRQF_ONESHOT, "rtc_ricoh619", &pdev->dev);
-               if(err) 
+               if (err<0)
                {
                        dev_err(&pdev->dev, "request IRQ:%d fail\n", rtc->irq);
                        rtc->irq = -1;
                        err = ricoh619_rtc_alarm_enable(&pdev->dev, 0);
-                       if(err)
+                       if (err<0)
                        {
                                dev_err(&pdev->dev, "5T619 RTC: enable rtc alarm error\n");
                                goto fail;
                        }
                }
-               else
-               {
+               else{
                        // enable wake  
                        enable_irq_wake(rtc->irq);
                        // enable alarm_d
                        err = ricoh619_rtc_alarm_enable(&pdev->dev, Alarm_flag);
-                       if(err) 
+                       if (err<0)
                        {
                                dev_err(&pdev->dev, "failed rtc setup\n");
                                err = -EBUSY;
@@ -747,14 +785,13 @@ static int __devinit ricoh619_rtc_probe(struct platform_device *pdev)
        {
                // system don't want to using alarm interrupt, so close it
                err = ricoh619_rtc_alarm_enable(&pdev->dev, 0);
-               if(err)
+               if (err<0)
                {
                        dev_err(&pdev->dev, "5T619 RTC: Disable rtc alarm error\n");
                        goto fail;
                }
                dev_err(&pdev->dev, "ricoh619 interrupt is disabled\n");
        }
-
        printk(KERN_INFO "RICOH619 RTC Register Success\n");
        
        ricoh619_read_regs(&pdev->dev, rtc_ctrl1, 1,&buff[0]);
@@ -769,24 +806,31 @@ fail:
        return err;
 }
 
-static int __devexit ricoh619_rtc_remove(struct platform_device *pdev)
+static int ricoh619_rtc_remove(struct platform_device *pdev)
 {
        struct ricoh619_rtc *rtc = dev_get_drvdata(&pdev->dev);
 
-       if (rtc->irq != -1)
-               free_irq(rtc->irq, rtc);
        rtc_device_unregister(rtc->rtc);
        kfree(rtc);
        return 0;
 }
 
+#ifdef CONFIG_OF
+static const struct of_device_id ricoh619_rtc_dt_match[] = {
+       { .compatible = "ricoh,ricoh619-rtc", },
+       {},
+};
+MODULE_DEVICE_TABLE(of, ricoh619_rtc_dt_match);
+#endif
+
 static struct platform_driver ricoh619_rtc_driver = {
        .driver = {
-               .name   = "rtc_ricoh619",
+               .name   = "ricoh619-rtc",
                .owner  = THIS_MODULE,
+               .of_match_table = of_match_ptr(ricoh619_rtc_dt_match),
        },
        .probe  = ricoh619_rtc_probe,
-       .remove = __devexit_p(ricoh619_rtc_remove),
+       .remove = ricoh619_rtc_remove,
 };
 
 static int __init ricoh619_rtc_init(void)
old mode 100644 (file)
new mode 100755 (executable)
index b0936d0..fad3858
 #define RICOH_LDO9_SLOT 0x23
 #define RICOH_LDO10_SLOT 0x24
 
-
+#define        RICOH619_NUM_REGULATOR 17
 
 /* RICOH619 IRQ definitions */
 enum {
@@ -318,6 +318,7 @@ struct ricoh619 {
        u8                      gpedge_reg[MAX_GPEDGE_REG];
 
        int                     bank_num;
+       struct irq_domain *irq_domain;
 };
 
 struct ricoh619_platform_data {
@@ -329,8 +330,11 @@ struct ricoh619_platform_data {
        struct ricoh619_gpio_init_data *gpio_init_data;
        int num_gpioinit_data;
        bool enable_shutdown_pin;
-       int (*pre_init)(struct ricoh619 *ricoh619);
-       int (*post_init)(struct ricoh619 *ricoh619);
+       bool pm_off;
+       struct regulator_init_data *reg_init_data[RICOH619_NUM_REGULATOR];
+       int irq_gpio;
+       int pmic_sleep_gpio; /* */
+       bool pmic_sleep;
 };
 
 /* ==================================== */
@@ -366,9 +370,7 @@ extern int ricoh619_update(struct device *dev, u8 reg, uint8_t val,
                                                                uint8_t mask);
 extern int ricoh619_update_bank1(struct device *dev, u8 reg, uint8_t val,
                                                                uint8_t mask);
-extern int ricoh619_power_off(void);
-extern int ricoh619_irq_init(struct ricoh619 *ricoh619, int irq, int irq_base);
+extern int ricoh619_irq_init(struct ricoh619 *ricoh619, int irq, struct ricoh619_platform_data *pdata);
 extern int ricoh619_irq_exit(struct ricoh619 *ricoh619);
-extern int ricoh619_power_off(void);
 
 #endif
old mode 100644 (file)
new mode 100755 (executable)
index 32738df..ec8c4fa
@@ -1,5 +1,5 @@
 /*
- * include/linux/power/ricoh619-battery.c
+ * include/linux/power/ricoh619_battery.h
  *
  * RICOH RC5T619 Charger Driver
  * 
 #define RICOH_FG_DBG(fmt, args...) {while(0);}
 #endif
 
-/* Defined buttery information */
+/* Defined battery information */
 #define        ADC_VDD_MV      2800
 #define        MIN_VOLTAGE     3100
 #define        MAX_VOLTAGE     4200
 #define        B_VALUE         3435
 
-
 /* 619 Register information */
 /* bank 0 */
 #define PSWR_REG               0x07
 #define        ADCCNT3_REG             0x66
 #define        VBATDATAH_REG           0x6A
 #define        VBATDATAL_REG           0x6B
-
-#define VSYSDATAH_REG  0x70
-#define VSYSDATAL_REG  0x71
+#define        VSYSDATAH_REG           0x70
+#define        VSYSDATAL_REG           0x71
 
 #define CHGCTL1_REG            0xB3
-#define        REGISET1_REG    0xB6
-#define        REGISET2_REG    0xB7
+#define        REGISET1_REG            0xB6
+#define        REGISET2_REG            0xB7
 #define        CHGISET_REG             0xB8
 #define        TIMSET_REG              0xB9
 #define        BATSET1_REG             0xBA
@@ -88,8 +86,8 @@
 /* bank 1 */
 /* Top address for battery initial setting */
 #define        BAT_INIT_TOP_REG        0xBC
-#define        TEMP_GAIN_H_REG 0xD6
-#define        TEMP_OFF_H_REG  0xB8
+#define        TEMP_GAIN_H_REG         0xD6
+#define        TEMP_OFF_H_REG          0xD8
 #define        BAT_REL_SEL_REG         0xDA
 #define        BAT_TA_SEL_REG          0xDB
 /**************************/
@@ -119,20 +117,17 @@ enum SupplyState {
        SUPPLY_STATE_USB,
 } ;
 
-struct ricoh619_battery_platform_data {
-       int     irq;
-       int     alarm_vol_mv;
-       int     multiple;
-       unsigned long   monitor_time;
+struct ricoh619_battery_type_data {
        int     ch_vfchg;
        int     ch_vrchg;
        int     ch_vbatovset;
        int     ch_ichg;
+       int     ch_icchg;
        int     ch_ilim_adp;
        int     ch_ilim_usb;
-       int     ch_icchg;
        int     fg_target_vsys;
        int     fg_target_ibat;
+       int     fg_poff_vbat;
        int     jt_en;
        int     jt_hw_sw;
        int     jt_temp_h;
@@ -143,6 +138,15 @@ struct ricoh619_battery_platform_data {
        int     jt_ichg_l;
 };
 
+#define BATTERY_TYPE_NUM 1
+struct ricoh619_battery_platform_data {
+       int     irq;
+       int     alarm_vol_mv;
+       int     multiple;
+       unsigned long   monitor_time;
+       struct ricoh619_battery_type_data type[BATTERY_TYPE_NUM];
+};
+
 extern struct ricoh619 *g_ricoh619;
 
 
index e30ac142b2d647fed2261c9c4edbdbc0aedcd129..9acfd09f49690bed5c3b7226652ce3f5a3439563 100755 (executable)
@@ -22,7 +22,7 @@
  */
 #ifndef __LINUX_POWER_RICOH61X_BATTERY_INIT_H
 #define __LINUX_POWER_RICOH61X_BATTERY_INIT_H
-
+/*
 
 uint8_t battery_init_para[][32] = {
         0x0B, 0x3F, 0x0B, 0xCB, 0x0B, 0xEE, 0x0C, 0x08, 0x0C, 0x1E, 0x0C, 0x38, 0x0C, 0x5B, 0x0C, 0x94,
@@ -34,12 +34,20 @@ uint8_t battery_init_para[][32] = {
                //0x0c, 0x92, 0x0c, 0xf4, 0x0d, 0x6f, 0x08, 0xca,
                //0x00, 0x36, 0x0f, 0xc8, 0x05, 0x2c, 0x22, 0x56
 };
+*/
+
 
+uint8_t battery_init_para[][32] = {
+    {
+  0x0A, 0xB1, 0x0B, 0x44, 0x0B, 0xAE, 0x0C, 0x00, 0x0C, 0x11, 0x0C, 0x1B,0x0C, 0x42, 0x0C, 0x7D,
+  0x0C, 0xB5, 0x0C, 0xFA, 0x0D, 0x53, 0x0A, 0xEC, 0x00, 0x46, 0x0F, 0xC8,0x05, 0x2C, 0x22, 0x56
+    }
+};
 #endif
 
 /*
 <Other Parameter>
-nominal_capacity=3800
+nominal_capacity=2800
 cut-off_v=3400
 thermistor_b=3435
 board_impe=0