From de0f0d2cbc3c9f0694628012623be3aafcdb3da5 Mon Sep 17 00:00:00 2001
From: =?utf8?q?=E5=BC=A0=E6=99=B4?= <zhangqing@rock-chips.com>
Date: Tue, 29 Apr 2014 11:15:29 +0800
Subject: [PATCH] rk3288:ricoh619:add dc_det function,add ricoh619.txt

---
 .../devicetree/bindings/mfd/ricoh619.txt      | 229 ++++++++++++++++++
 arch/arm/boot/dts/rk3288-tb.dts               |   2 +-
 drivers/mfd/ricoh619.c                        |  10 +-
 drivers/power/ricoh619-battery.c              |  35 ++-
 include/linux/mfd/ricoh619.h                  |   2 +
 5 files changed, 270 insertions(+), 8 deletions(-)
 create mode 100755 Documentation/devicetree/bindings/mfd/ricoh619.txt

diff --git a/Documentation/devicetree/bindings/mfd/ricoh619.txt b/Documentation/devicetree/bindings/mfd/ricoh619.txt
new file mode 100755
index 000000000000..1abdec339617
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/ricoh619.txt
@@ -0,0 +1,229 @@
+ricoh619 Power Management Integrated Circuit
+
+Required properties:
+- compatible: "rockchip,ricoh619" 
+- reg: I2C slave address
+- gpios: the interrupt pin\ sleep pin \dc_dec pin
+  use gpio get IRQ number
+  get adp plug in or out
+- regulators: This is the list of child nodes that specify the regulator
+  initialization data for defined regulators. Not all regulators for the given
+  device need to be present. The definition for each of these nodes is defined
+  using the standard binding for regulators found at
+  Documentation/devicetree/bindings/regulator/regulator.txt.
+  The regulator is matched with the regulator-compatible.
+
+  The valid regulator-compatible values are:
+  ricoh619: ricoh619_dc1, ricoh619_dc2, ricoh619_dc3, ricoh619_dc4, ricoh619_dc5,ricoh619_ldo1, ricoh619_ldo2, ricoh619_ldo3, ricoh619_ldo4, ricoh619_ldo5, ricoh619_ldo6,
+            ricoh619_ldo7, ricoh619_ldo8,ricoh619_ldo9,ricoh619_ldo10,ricoh619_ldortc1,ricoh619_ldortc2
+
+Optional properties:
+- gpios: 
+	gpios 0 :irq pin gpio
+	gpios 1 :sleep pin gpio
+	gpios 2 :dc det pin
+- regulator-initial-mode: default mode to set on startup
+- regulator-initial-state: suspend state to set at init
+- regulator-state-mem, regulator-state-disk, regulator-state-standby:
+	defines regulator suspend to memory, suspend to disk (hibernate) and standby respectively.
+	have following sub-constarints:
+	- regulator-state-uv: suspend voltage
+	- regulator-state-mode: suspend regulator operating mode
+	- regulator-state-enabled: is regulator enabled in this suspend state
+	- regulator-state-disabled: is the regulator disbled in this suspend state
+-regulator-initial-mode and regulator-state-mode is set as:
+	REGULATOR_MODE_FAST			0x1
+	REGULATOR_MODE_NORMAL			0x2
+	REGULATOR_MODE_IDLE			0x4
+	REGULATOR_MODE_STANDBY			0x8
+ 
+Example:
+
+	ricoh619: ricoh619@32 {
+		reg = <0x32>;
+		status = "okay";
+	};
+
+	gpios =<&gpio0 GPIO_A4 GPIO_ACTIVE_HIGH>,<&gpio0 GPIO_B3 GPIO_ACTIVE_LOW>,<&gpio0 GPIO_B0 GPIO_ACTIVE_HIGH>;
+	ricoh619,system-power-controller;  //support power off
+
+&ricoh619 {
+	compatible = "ricoh,ricoh619";
+	
+	regulators {
+		#address-cells = <1>;
+		#size-cells = <0>;	
+
+		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>;
+		};
+	};
+};
diff --git a/arch/arm/boot/dts/rk3288-tb.dts b/arch/arm/boot/dts/rk3288-tb.dts
index 61945492476f..17dd881c0cfe 100755
--- a/arch/arm/boot/dts/rk3288-tb.dts
+++ b/arch/arm/boot/dts/rk3288-tb.dts
@@ -807,7 +807,7 @@ rockchip,power_type = <GPIO>;
 
 /include/ "ricoh619.dtsi"
 &ricoh619 {
-	gpios =<&gpio0 GPIO_A4 GPIO_ACTIVE_HIGH>,<&gpio0 GPIO_B3 GPIO_ACTIVE_LOW>;
+	gpios =<&gpio0 GPIO_A4 GPIO_ACTIVE_HIGH>,<&gpio0 GPIO_B3 GPIO_ACTIVE_LOW>,<&gpio0 GPIO_B0 GPIO_ACTIVE_HIGH>;
 	ricoh619,system-power-controller;
 	
 	regulators {
diff --git a/drivers/mfd/ricoh619.c b/drivers/mfd/ricoh619.c
index 4b5f98e74091..03f427fbefc5 100755
--- a/drivers/mfd/ricoh619.c
+++ b/drivers/mfd/ricoh619.c
@@ -728,6 +728,11 @@ static struct ricoh619_platform_data *ricoh619_parse_dt(struct ricoh619 *ricoh61
 			if (!gpio_is_valid(pdata->pmic_sleep_gpio)) {
 				printk("invalid gpio: %d\n",  pdata->pmic_sleep_gpio);
 		}
+
+	pdata->dc_det = of_get_named_gpio(ricoh619_pmic_np,"gpios",2);
+			if (!gpio_is_valid(pdata->dc_det)) {
+				printk("invalid gpio: %d\n",  pdata->dc_det);
+		}
 	pdata->pmic_sleep = true;
 	
 	pdata->pm_off = of_property_read_bool(ricoh619_pmic_np,"ricoh619,system-power-controller");
@@ -812,7 +817,10 @@ static int ricoh619_i2c_probe(struct i2c_client *client,
 	
 	if (ricoh619->dev->of_node)
 		pdata = ricoh619_parse_dt(ricoh619);
-
+	
+	if (gpio_is_valid(pdata->dc_det)) 
+		ricoh619->dc_det = pdata->dc_det;
+	
 	/******************************set sleep vol & dcdc mode******************/
 	#ifdef CONFIG_OF
 	if (pdata->pmic_sleep_gpio) {
diff --git a/drivers/power/ricoh619-battery.c b/drivers/power/ricoh619-battery.c
index 8bfc7d679c11..9fb1b9a5585e 100755
--- a/drivers/power/ricoh619-battery.c
+++ b/drivers/power/ricoh619-battery.c
@@ -3071,7 +3071,7 @@ static int get_power_supply_Android_status(struct ricoh619_battery_info *info)
 
 	return POWER_SUPPLY_STATUS_UNKNOWN;
 }
-
+extern struct ricoh619 *g_ricoh619;
 static void charger_irq_work(struct work_struct *work)
 {
 	struct ricoh619_battery_info *info
@@ -3088,11 +3088,34 @@ static void charger_irq_work(struct work_struct *work)
 	
 	if (info->chg_stat1 & 0x01) {
 		ricoh619_read(info->dev->parent, CHGSTATE_REG, &reg_val);
-		if (reg_val & 0x40) { /* USE ADP */
-			/* set adp limit current 2A */
-			ricoh619_write(info->dev->parent, REGISET1_REG, 0x13);
-			/* set charge current 2A */
-			ricoh619_write(info->dev->parent, CHGISET_REG, 0xD3);
+		if (reg_val & 0x40) { /* USE ADP */	
+			if (gpio_is_valid(g_ricoh619->dc_det)){
+				ret = gpio_request(g_ricoh619->dc_det, "ricoh619_dc_det");
+				if (ret < 0) {
+					RICOH_FG_DBG("Failed to request gpio %d with ret:""%d\n",g_ricoh619->dc_det, ret);
+				}
+				gpio_direction_input(g_ricoh619->dc_det);
+				ret = gpio_get_value(g_ricoh619->dc_det);
+				if (ret ==0){
+					/* set adp limit current 2A */
+					ricoh619_write(info->dev->parent, REGISET1_REG, 0x13);
+					/* set charge current 2A */
+					ricoh619_write(info->dev->parent, CHGISET_REG, 0xD3);
+ 				}
+				else {
+					/* set adp limit current 500ma */
+					ricoh619_write(info->dev->parent, REGISET1_REG, 0x04);
+					/* set charge current 500ma */
+					ricoh619_write(info->dev->parent, CHGISET_REG, 0xc4); 
+				}
+				gpio_free(g_ricoh619->dc_det);
+			}
+			else{
+				/* set adp limit current 2A */
+				ricoh619_write(info->dev->parent, REGISET1_REG, 0x13);
+				/* set charge current 2A */
+				ricoh619_write(info->dev->parent, CHGISET_REG, 0xD3); 
+			}
 		}
 		else if (reg_val & 0x80) { /* USE USB */
 			queue_work(info->usb_workqueue, &info->usb_irq_work);
diff --git a/include/linux/mfd/ricoh619.h b/include/linux/mfd/ricoh619.h
index fad38587744b..dfaa09b0a455 100755
--- a/include/linux/mfd/ricoh619.h
+++ b/include/linux/mfd/ricoh619.h
@@ -319,6 +319,7 @@ struct ricoh619 {
 
 	int			bank_num;
 	struct irq_domain *irq_domain;
+	int dc_det;
 };
 
 struct ricoh619_platform_data {
@@ -334,6 +335,7 @@ struct ricoh619_platform_data {
 	struct regulator_init_data *reg_init_data[RICOH619_NUM_REGULATOR];
 	int irq_gpio;
 	int pmic_sleep_gpio; /* */
+	int dc_det; 
 	bool pmic_sleep;
 };
 
-- 
2.34.1