diff options
author | Mustapha Ben Zoubeir <mustapha.ben.zoubeir-nonst@stericsson.com> | 2012-06-27 09:40:58 -0400 |
---|---|---|
committer | Lee Jones <lee.jones@linaro.org> | 2013-03-06 23:35:41 -0500 |
commit | 49fddeec9fbb0dd58507185104812fde77c38def (patch) | |
tree | 787aeff79e1cc268e0754af2da681f3259c81901 /drivers/power/pm2301_charger.c | |
parent | 54fbbb6242247d06d21e21bbcf4ae8339bd75592 (diff) |
pm2301-charger: Resolve I2C detection problem on ab9540
Signed-off-by: Mustapha Ben Zoubeir <mustapha.ben.zoubeir-nonst@stericsson.com>
Signed-off-by: Lee Jones <lee.jones@linaro.org>
Reviewed-by: Marcus COOPER <marcus.xm.cooper@stericsson.com>
Reviewed-by: Philippe LANGLAIS <philippe.langlais@stericsson.com>
Tested-by: Olivier CLERGEAUD <olivier.clergeaud@stericsson.com>
Diffstat (limited to 'drivers/power/pm2301_charger.c')
-rw-r--r-- | drivers/power/pm2301_charger.c | 35 |
1 files changed, 26 insertions, 9 deletions
diff --git a/drivers/power/pm2301_charger.c b/drivers/power/pm2301_charger.c index 3f02636c48a5..a95edae925f8 100644 --- a/drivers/power/pm2301_charger.c +++ b/drivers/power/pm2301_charger.c | |||
@@ -34,6 +34,8 @@ | |||
34 | 34 | ||
35 | #define to_pm2xxx_charger_ac_device_info(x) container_of((x), \ | 35 | #define to_pm2xxx_charger_ac_device_info(x) container_of((x), \ |
36 | struct pm2xxx_charger, ac_chg) | 36 | struct pm2xxx_charger, ac_chg) |
37 | #define SLEEP_MIN 50 | ||
38 | #define SLEEP_MAX 100 | ||
37 | 39 | ||
38 | static int pm2xxx_interrupt_registers[] = { | 40 | static int pm2xxx_interrupt_registers[] = { |
39 | PM2XXX_REG_INT1, | 41 | PM2XXX_REG_INT1, |
@@ -113,17 +115,14 @@ static const struct i2c_device_id pm2xxx_ident[] = { | |||
113 | 115 | ||
114 | static void set_lpn_pin(struct pm2xxx_charger *pm2) | 116 | static void set_lpn_pin(struct pm2xxx_charger *pm2) |
115 | { | 117 | { |
116 | if (pm2->ac.charger_connected) | ||
117 | return; | ||
118 | gpio_set_value(pm2->lpn_pin, 1); | 118 | gpio_set_value(pm2->lpn_pin, 1); |
119 | usleep_range(SLEEP_MIN, SLEEP_MAX); | ||
119 | 120 | ||
120 | return; | 121 | return; |
121 | } | 122 | } |
122 | 123 | ||
123 | static void clear_lpn_pin(struct pm2xxx_charger *pm2) | 124 | static void clear_lpn_pin(struct pm2xxx_charger *pm2) |
124 | { | 125 | { |
125 | if (pm2->ac.charger_connected) | ||
126 | return; | ||
127 | gpio_set_value(pm2->lpn_pin, 0); | 126 | gpio_set_value(pm2->lpn_pin, 0); |
128 | 127 | ||
129 | return; | 128 | return; |
@@ -139,7 +138,6 @@ static int pm2xxx_reg_read(struct pm2xxx_charger *pm2, int reg, u8 *val) | |||
139 | * and receive I2C "acknowledge" from PM2301. | 138 | * and receive I2C "acknowledge" from PM2301. |
140 | */ | 139 | */ |
141 | mutex_lock(&pm2->lock); | 140 | mutex_lock(&pm2->lock); |
142 | set_lpn_pin(pm2); | ||
143 | 141 | ||
144 | ret = i2c_smbus_read_i2c_block_data(pm2->config.pm2xxx_i2c, reg, | 142 | ret = i2c_smbus_read_i2c_block_data(pm2->config.pm2xxx_i2c, reg, |
145 | 1, val); | 143 | 1, val); |
@@ -147,7 +145,6 @@ static int pm2xxx_reg_read(struct pm2xxx_charger *pm2, int reg, u8 *val) | |||
147 | dev_err(pm2->dev, "Error reading register at 0x%x\n", reg); | 145 | dev_err(pm2->dev, "Error reading register at 0x%x\n", reg); |
148 | else | 146 | else |
149 | ret = 0; | 147 | ret = 0; |
150 | clear_lpn_pin(pm2); | ||
151 | mutex_unlock(&pm2->lock); | 148 | mutex_unlock(&pm2->lock); |
152 | 149 | ||
153 | return ret; | 150 | return ret; |
@@ -163,7 +160,6 @@ static int pm2xxx_reg_write(struct pm2xxx_charger *pm2, int reg, u8 val) | |||
163 | * and receive I2C "acknowledge" from PM2301. | 160 | * and receive I2C "acknowledge" from PM2301. |
164 | */ | 161 | */ |
165 | mutex_lock(&pm2->lock); | 162 | mutex_lock(&pm2->lock); |
166 | set_lpn_pin(pm2); | ||
167 | 163 | ||
168 | ret = i2c_smbus_write_i2c_block_data(pm2->config.pm2xxx_i2c, reg, | 164 | ret = i2c_smbus_write_i2c_block_data(pm2->config.pm2xxx_i2c, reg, |
169 | 1, &val); | 165 | 1, &val); |
@@ -171,7 +167,6 @@ static int pm2xxx_reg_write(struct pm2xxx_charger *pm2, int reg, u8 val) | |||
171 | dev_err(pm2->dev, "Error writing register at 0x%x\n", reg); | 167 | dev_err(pm2->dev, "Error writing register at 0x%x\n", reg); |
172 | else | 168 | else |
173 | ret = 0; | 169 | ret = 0; |
174 | clear_lpn_pin(pm2); | ||
175 | mutex_unlock(&pm2->lock); | 170 | mutex_unlock(&pm2->lock); |
176 | 171 | ||
177 | return ret; | 172 | return ret; |
@@ -478,7 +473,6 @@ static int pm2_int_reg5(void *pm2_data, int val) | |||
478 | struct pm2xxx_charger *pm2 = pm2_data; | 473 | struct pm2xxx_charger *pm2 = pm2_data; |
479 | int ret = 0; | 474 | int ret = 0; |
480 | 475 | ||
481 | |||
482 | if (val & (PM2XXX_INT6_ITVPWR2DROP | PM2XXX_INT6_ITVPWR1DROP)) { | 476 | if (val & (PM2XXX_INT6_ITVPWR2DROP | PM2XXX_INT6_ITVPWR1DROP)) { |
483 | dev_dbg(pm2->dev, "VMPWR drop to VBAT level\n"); | 477 | dev_dbg(pm2->dev, "VMPWR drop to VBAT level\n"); |
484 | } | 478 | } |
@@ -899,12 +893,34 @@ static struct pm2xxx_irq pm2xxx_charger_irq[] = { | |||
899 | 893 | ||
900 | static int pm2xxx_wall_charger_resume(struct i2c_client *i2c_client) | 894 | static int pm2xxx_wall_charger_resume(struct i2c_client *i2c_client) |
901 | { | 895 | { |
896 | struct pm2xxx_charger *pm2; | ||
897 | |||
898 | pm2 = (struct pm2xxx_charger *)i2c_get_clientdata(i2c_client); | ||
899 | set_lpn_pin(pm2); | ||
900 | |||
901 | /* If we still have a HW failure, schedule a new check */ | ||
902 | if (pm2->flags.ovv) | ||
903 | queue_delayed_work(pm2->charger_wq, | ||
904 | &pm2->check_hw_failure_work, 0); | ||
905 | |||
902 | return 0; | 906 | return 0; |
903 | } | 907 | } |
904 | 908 | ||
905 | static int pm2xxx_wall_charger_suspend(struct i2c_client *i2c_client, | 909 | static int pm2xxx_wall_charger_suspend(struct i2c_client *i2c_client, |
906 | pm_message_t state) | 910 | pm_message_t state) |
907 | { | 911 | { |
912 | struct pm2xxx_charger *pm2; | ||
913 | |||
914 | pm2 = (struct pm2xxx_charger *)i2c_get_clientdata(i2c_client); | ||
915 | clear_lpn_pin(pm2); | ||
916 | |||
917 | /* Cancel any pending HW failure check */ | ||
918 | if (delayed_work_pending(&pm2->check_hw_failure_work)) | ||
919 | cancel_delayed_work(&pm2->check_hw_failure_work); | ||
920 | |||
921 | flush_work(&pm2->ac_work); | ||
922 | flush_work(&pm2->check_main_thermal_prot_work); | ||
923 | |||
908 | return 0; | 924 | return 0; |
909 | } | 925 | } |
910 | 926 | ||
@@ -1056,6 +1072,7 @@ static int pm2xxx_wall_charger_probe(struct i2c_client *i2c_client, | |||
1056 | goto free_gpio; | 1072 | goto free_gpio; |
1057 | } | 1073 | } |
1058 | 1074 | ||
1075 | set_lpn_pin(pm2); | ||
1059 | ret = pm2xxx_charger_detection(pm2, &val); | 1076 | ret = pm2xxx_charger_detection(pm2, &val); |
1060 | 1077 | ||
1061 | if ((ret == 0) && val) { | 1078 | if ((ret == 0) && val) { |