@@ -152,6 +152,10 @@ struct bq20z75_info {
152152 bool gpio_detect ;
153153 bool enable_detection ;
154154 int irq ;
155+ int last_state ;
156+ int poll_time ;
157+ struct delayed_work work ;
158+ int ignore_changes ;
155159};
156160
157161static int bq20z75_read_word_data (struct i2c_client * client , u8 address )
@@ -279,6 +283,7 @@ static int bq20z75_get_battery_property(struct i2c_client *client,
279283 int reg_offset , enum power_supply_property psp ,
280284 union power_supply_propval * val )
281285{
286+ struct bq20z75_info * bq20z75_device = i2c_get_clientdata (client );
282287 s32 ret ;
283288
284289 ret = bq20z75_read_word_data (client ,
@@ -293,15 +298,24 @@ static int bq20z75_get_battery_property(struct i2c_client *client,
293298 if (ret >= bq20z75_data [reg_offset ].min_value &&
294299 ret <= bq20z75_data [reg_offset ].max_value ) {
295300 val -> intval = ret ;
296- if (psp == POWER_SUPPLY_PROP_STATUS ) {
297- if (ret & BATTERY_FULL_CHARGED )
298- val -> intval = POWER_SUPPLY_STATUS_FULL ;
299- else if (ret & BATTERY_FULL_DISCHARGED )
300- val -> intval = POWER_SUPPLY_STATUS_NOT_CHARGING ;
301- else if (ret & BATTERY_DISCHARGING )
302- val -> intval = POWER_SUPPLY_STATUS_DISCHARGING ;
303- else
304- val -> intval = POWER_SUPPLY_STATUS_CHARGING ;
301+ if (psp != POWER_SUPPLY_PROP_STATUS )
302+ return 0 ;
303+
304+ if (ret & BATTERY_FULL_CHARGED )
305+ val -> intval = POWER_SUPPLY_STATUS_FULL ;
306+ else if (ret & BATTERY_FULL_DISCHARGED )
307+ val -> intval = POWER_SUPPLY_STATUS_NOT_CHARGING ;
308+ else if (ret & BATTERY_DISCHARGING )
309+ val -> intval = POWER_SUPPLY_STATUS_DISCHARGING ;
310+ else
311+ val -> intval = POWER_SUPPLY_STATUS_CHARGING ;
312+
313+ if (bq20z75_device -> poll_time == 0 )
314+ bq20z75_device -> last_state = val -> intval ;
315+ else if (bq20z75_device -> last_state != val -> intval ) {
316+ cancel_delayed_work_sync (& bq20z75_device -> work );
317+ power_supply_changed (& bq20z75_device -> power_supply );
318+ bq20z75_device -> poll_time = 0 ;
305319 }
306320 } else {
307321 if (psp == POWER_SUPPLY_PROP_STATUS )
@@ -545,6 +559,60 @@ static irqreturn_t bq20z75_irq(int irq, void *devid)
545559 return IRQ_HANDLED ;
546560}
547561
562+ static void bq20z75_external_power_changed (struct power_supply * psy )
563+ {
564+ struct bq20z75_info * bq20z75_device ;
565+
566+ bq20z75_device = container_of (psy , struct bq20z75_info , power_supply );
567+
568+ if (bq20z75_device -> ignore_changes > 0 ) {
569+ bq20z75_device -> ignore_changes -- ;
570+ return ;
571+ }
572+
573+ /* cancel outstanding work */
574+ cancel_delayed_work_sync (& bq20z75_device -> work );
575+
576+ schedule_delayed_work (& bq20z75_device -> work , HZ );
577+ bq20z75_device -> poll_time = bq20z75_device -> pdata -> poll_retry_count ;
578+ }
579+
580+ static void bq20z75_delayed_work (struct work_struct * work )
581+ {
582+ struct bq20z75_info * bq20z75_device ;
583+ s32 ret ;
584+
585+ bq20z75_device = container_of (work , struct bq20z75_info , work .work );
586+
587+ ret = bq20z75_read_word_data (bq20z75_device -> client ,
588+ bq20z75_data [REG_STATUS ].addr );
589+ /* if the read failed, give up on this work */
590+ if (ret < 0 ) {
591+ bq20z75_device -> poll_time = 0 ;
592+ return ;
593+ }
594+
595+ if (ret & BATTERY_FULL_CHARGED )
596+ ret = POWER_SUPPLY_STATUS_FULL ;
597+ else if (ret & BATTERY_FULL_DISCHARGED )
598+ ret = POWER_SUPPLY_STATUS_NOT_CHARGING ;
599+ else if (ret & BATTERY_DISCHARGING )
600+ ret = POWER_SUPPLY_STATUS_DISCHARGING ;
601+ else
602+ ret = POWER_SUPPLY_STATUS_CHARGING ;
603+
604+ if (bq20z75_device -> last_state != ret ) {
605+ bq20z75_device -> poll_time = 0 ;
606+ power_supply_changed (& bq20z75_device -> power_supply );
607+ return ;
608+ }
609+ if (bq20z75_device -> poll_time > 0 ) {
610+ schedule_delayed_work (& bq20z75_device -> work , HZ );
611+ bq20z75_device -> poll_time -- ;
612+ return ;
613+ }
614+ }
615+
548616static int __devinit bq20z75_probe (struct i2c_client * client ,
549617 const struct i2c_device_id * id )
550618{
@@ -566,6 +634,13 @@ static int __devinit bq20z75_probe(struct i2c_client *client,
566634 bq20z75_device -> power_supply .num_properties =
567635 ARRAY_SIZE (bq20z75_properties );
568636 bq20z75_device -> power_supply .get_property = bq20z75_get_property ;
637+ /* ignore first notification of external change, it is generated
638+ * from the power_supply_register call back
639+ */
640+ bq20z75_device -> ignore_changes = 1 ;
641+ bq20z75_device -> last_state = POWER_SUPPLY_STATUS_UNKNOWN ;
642+ bq20z75_device -> power_supply .external_power_changed =
643+ bq20z75_external_power_changed ;
569644
570645 if (pdata ) {
571646 bq20z75_device -> gpio_detect =
@@ -625,6 +700,8 @@ static int __devinit bq20z75_probe(struct i2c_client *client,
625700 dev_info (& client -> dev ,
626701 "%s: battery gas gauge device registered\n" , client -> name );
627702
703+ INIT_DELAYED_WORK (& bq20z75_device -> work , bq20z75_delayed_work );
704+
628705 return 0 ;
629706
630707exit_psupply :
@@ -648,6 +725,9 @@ static int __devexit bq20z75_remove(struct i2c_client *client)
648725 gpio_free (bq20z75_device -> pdata -> battery_detect );
649726
650727 power_supply_unregister (& bq20z75_device -> power_supply );
728+
729+ cancel_delayed_work_sync (& bq20z75_device -> work );
730+
651731 kfree (bq20z75_device );
652732 bq20z75_device = NULL ;
653733
@@ -661,6 +741,9 @@ static int bq20z75_suspend(struct i2c_client *client,
661741 struct bq20z75_info * bq20z75_device = i2c_get_clientdata (client );
662742 s32 ret ;
663743
744+ if (bq20z75_device -> poll_time > 0 )
745+ cancel_delayed_work_sync (& bq20z75_device -> work );
746+
664747 /* write to manufacturer access with sleep command */
665748 ret = bq20z75_write_word_data (client ,
666749 bq20z75_data [REG_MANUFACTURER_DATA ].addr ,
0 commit comments