[PATCH 13/40] ab8500_charger: Prevent auto drop of VBUS

2013-02-15 Thread Lee Jones
Do not set higher current in stepping functionality if VBUS is dropping.
After VBUS has dropped try to set current once again. If dropping again
then we have found the maximum capability of the charger.

Signed-off-by: Lee Jones 
---
 drivers/power/ab8500_charger.c |  169 
 1 file changed, 120 insertions(+), 49 deletions(-)

diff --git a/drivers/power/ab8500_charger.c b/drivers/power/ab8500_charger.c
index f1d7123..547f6ea 100644
--- a/drivers/power/ab8500_charger.c
+++ b/drivers/power/ab8500_charger.c
@@ -58,6 +58,7 @@
 #define MAIN_CH_INPUT_CURR_SHIFT   4
 #define VBUS_IN_CURR_LIM_SHIFT 4
 #define AUTO_VBUS_IN_CURR_LIM_SHIFT4
+#define VBUS_IN_CURR_LIM_RETRY_SET_TIME30 /* seconds */
 
 #define LED_INDICATOR_PWM_ENA  0x01
 #define LED_INDICATOR_PWM_DIS  0x00
@@ -202,10 +203,15 @@ struct ab8500_charger_usb_state {
spinlock_t usb_lock;
 };
 
+struct ab8500_charger_max_usb_in_curr {
+   int usb_type_max;
+   int set_max;
+   int calculated_max;
+};
+
 /**
  * struct ab8500_charger - ab8500 Charger device information
  * @dev:   Pointer to the structure device
- * @max_usb_in_curr:   Max USB charger input current
  * @vbus_detected: VBUS detected
  * @vbus_detected_start:
  * VBUS detected during startup
@@ -220,7 +226,6 @@ struct ab8500_charger_usb_state {
  * @autopower  Indicate if we should have automatic pwron after pwrloss
  * @autopower_cfg  platform specific power config support for "pwron after 
pwrloss"
  * @invalid_charger_detect_state State when forcing AB to use invalid charger
- * @is_usb_host:   Indicate if last detected USB type is host
  * @is_aca_rid:Incicate if accessory is ACA type
  * @current_stepping_sessions:
  * Counter for current stepping sessions
@@ -229,6 +234,7 @@ struct ab8500_charger_usb_state {
  * @bm:Platform specific battery management information
  * @flags: Structure for information about events triggered
  * @usb_state: Structure for usb stack information
+ * @max_usb_in_curr:   Max USB charger input current
  * @ac_chg:AC charger power supply
  * @usb_chg:   USB charger power supply
  * @ac:Structure that holds the AC charger properties
@@ -260,7 +266,6 @@ struct ab8500_charger_usb_state {
  */
 struct ab8500_charger {
struct device *dev;
-   int max_usb_in_curr;
bool vbus_detected;
bool vbus_detected_start;
bool ac_conn;
@@ -272,7 +277,6 @@ struct ab8500_charger {
bool autopower;
bool autopower_cfg;
int invalid_charger_detect_state;
-   bool is_usb_host;
int is_aca_rid;
atomic_t current_stepping_sessions;
struct ab8500 *parent;
@@ -280,6 +284,7 @@ struct ab8500_charger {
struct abx500_bm_data *bm;
struct ab8500_charger_event_flags flags;
struct ab8500_charger_usb_state usb_state;
+   struct ab8500_charger_max_usb_in_curr max_usb_in_curr;
struct ux500_charger ac_chg;
struct ux500_charger usb_chg;
struct ab8500_charger_info ac;
@@ -421,6 +426,10 @@ static void ab8500_charger_set_usb_connected(struct 
ab8500_charger *di,
if (connected != di->usb.charger_connected) {
dev_dbg(di->dev, "USB connected:%i\n", connected);
di->usb.charger_connected = connected;
+
+   if (!connected)
+   di->flags.vbus_drop_end = false;
+
sysfs_notify(>usb_chg.psy.dev->kobj, NULL, "present");
 
if (connected) {
@@ -674,23 +683,19 @@ static int ab8500_charger_max_usb_curr(struct 
ab8500_charger *di,
case USB_STAT_STD_HOST_C_S:
dev_dbg(di->dev, "USB Type - Standard host is "
"detected through USB driver\n");
-   di->max_usb_in_curr = USB_CH_IP_CUR_LVL_0P5;
-   di->is_usb_host = true;
+   di->max_usb_in_curr.usb_type_max = USB_CH_IP_CUR_LVL_0P5;
di->is_aca_rid = 0;
break;
case USB_STAT_HOST_CHG_HS_CHIRP:
-   di->max_usb_in_curr = USB_CH_IP_CUR_LVL_0P5;
-   di->is_usb_host = true;
+   di->max_usb_in_curr.usb_type_max = USB_CH_IP_CUR_LVL_0P5;
di->is_aca_rid = 0;
break;
case USB_STAT_HOST_CHG_HS:
-   di->max_usb_in_curr = USB_CH_IP_CUR_LVL_0P5;
-   di->is_usb_host = true;
+   di->max_usb_in_curr.usb_type_max = USB_CH_IP_CUR_LVL_0P5;
di->is_aca_rid = 0;
break;
case USB_STAT_ACA_RID_C_HS:
-   di->max_usb_in_curr = USB_CH_IP_CUR_LVL_0P9;
-   di->is_usb_host = false;
+   di->max_usb_in_curr.usb_type_max = USB_CH_IP_CUR_LVL_0P9;
di->is_aca_rid = 0;
break;
case 

[PATCH 13/40] ab8500_charger: Prevent auto drop of VBUS

2013-02-15 Thread Lee Jones
Do not set higher current in stepping functionality if VBUS is dropping.
After VBUS has dropped try to set current once again. If dropping again
then we have found the maximum capability of the charger.

Signed-off-by: Lee Jones lee.jo...@linaro.org
---
 drivers/power/ab8500_charger.c |  169 
 1 file changed, 120 insertions(+), 49 deletions(-)

diff --git a/drivers/power/ab8500_charger.c b/drivers/power/ab8500_charger.c
index f1d7123..547f6ea 100644
--- a/drivers/power/ab8500_charger.c
+++ b/drivers/power/ab8500_charger.c
@@ -58,6 +58,7 @@
 #define MAIN_CH_INPUT_CURR_SHIFT   4
 #define VBUS_IN_CURR_LIM_SHIFT 4
 #define AUTO_VBUS_IN_CURR_LIM_SHIFT4
+#define VBUS_IN_CURR_LIM_RETRY_SET_TIME30 /* seconds */
 
 #define LED_INDICATOR_PWM_ENA  0x01
 #define LED_INDICATOR_PWM_DIS  0x00
@@ -202,10 +203,15 @@ struct ab8500_charger_usb_state {
spinlock_t usb_lock;
 };
 
+struct ab8500_charger_max_usb_in_curr {
+   int usb_type_max;
+   int set_max;
+   int calculated_max;
+};
+
 /**
  * struct ab8500_charger - ab8500 Charger device information
  * @dev:   Pointer to the structure device
- * @max_usb_in_curr:   Max USB charger input current
  * @vbus_detected: VBUS detected
  * @vbus_detected_start:
  * VBUS detected during startup
@@ -220,7 +226,6 @@ struct ab8500_charger_usb_state {
  * @autopower  Indicate if we should have automatic pwron after pwrloss
  * @autopower_cfg  platform specific power config support for pwron after 
pwrloss
  * @invalid_charger_detect_state State when forcing AB to use invalid charger
- * @is_usb_host:   Indicate if last detected USB type is host
  * @is_aca_rid:Incicate if accessory is ACA type
  * @current_stepping_sessions:
  * Counter for current stepping sessions
@@ -229,6 +234,7 @@ struct ab8500_charger_usb_state {
  * @bm:Platform specific battery management information
  * @flags: Structure for information about events triggered
  * @usb_state: Structure for usb stack information
+ * @max_usb_in_curr:   Max USB charger input current
  * @ac_chg:AC charger power supply
  * @usb_chg:   USB charger power supply
  * @ac:Structure that holds the AC charger properties
@@ -260,7 +266,6 @@ struct ab8500_charger_usb_state {
  */
 struct ab8500_charger {
struct device *dev;
-   int max_usb_in_curr;
bool vbus_detected;
bool vbus_detected_start;
bool ac_conn;
@@ -272,7 +277,6 @@ struct ab8500_charger {
bool autopower;
bool autopower_cfg;
int invalid_charger_detect_state;
-   bool is_usb_host;
int is_aca_rid;
atomic_t current_stepping_sessions;
struct ab8500 *parent;
@@ -280,6 +284,7 @@ struct ab8500_charger {
struct abx500_bm_data *bm;
struct ab8500_charger_event_flags flags;
struct ab8500_charger_usb_state usb_state;
+   struct ab8500_charger_max_usb_in_curr max_usb_in_curr;
struct ux500_charger ac_chg;
struct ux500_charger usb_chg;
struct ab8500_charger_info ac;
@@ -421,6 +426,10 @@ static void ab8500_charger_set_usb_connected(struct 
ab8500_charger *di,
if (connected != di-usb.charger_connected) {
dev_dbg(di-dev, USB connected:%i\n, connected);
di-usb.charger_connected = connected;
+
+   if (!connected)
+   di-flags.vbus_drop_end = false;
+
sysfs_notify(di-usb_chg.psy.dev-kobj, NULL, present);
 
if (connected) {
@@ -674,23 +683,19 @@ static int ab8500_charger_max_usb_curr(struct 
ab8500_charger *di,
case USB_STAT_STD_HOST_C_S:
dev_dbg(di-dev, USB Type - Standard host is 
detected through USB driver\n);
-   di-max_usb_in_curr = USB_CH_IP_CUR_LVL_0P5;
-   di-is_usb_host = true;
+   di-max_usb_in_curr.usb_type_max = USB_CH_IP_CUR_LVL_0P5;
di-is_aca_rid = 0;
break;
case USB_STAT_HOST_CHG_HS_CHIRP:
-   di-max_usb_in_curr = USB_CH_IP_CUR_LVL_0P5;
-   di-is_usb_host = true;
+   di-max_usb_in_curr.usb_type_max = USB_CH_IP_CUR_LVL_0P5;
di-is_aca_rid = 0;
break;
case USB_STAT_HOST_CHG_HS:
-   di-max_usb_in_curr = USB_CH_IP_CUR_LVL_0P5;
-   di-is_usb_host = true;
+   di-max_usb_in_curr.usb_type_max = USB_CH_IP_CUR_LVL_0P5;
di-is_aca_rid = 0;
break;
case USB_STAT_ACA_RID_C_HS:
-   di-max_usb_in_curr = USB_CH_IP_CUR_LVL_0P9;
-   di-is_usb_host = false;
+   di-max_usb_in_curr.usb_type_max = USB_CH_IP_CUR_LVL_0P9;
di-is_aca_rid = 0;
break;
case