@@ -95,6 +95,7 @@ struct bq25890_init_data {
9595
9696struct bq25890_state {
9797 u8 online ;
98+ u8 hiz ;
9899 u8 chrg_status ;
99100 u8 chrg_fault ;
100101 u8 vsys_status ;
@@ -119,6 +120,7 @@ struct bq25890_device {
119120
120121 bool skip_reset ;
121122 bool read_back_init_data ;
123+ bool force_hiz ;
122124 u32 pump_express_vbus_max ;
123125 enum bq25890_chip_version chip_version ;
124126 struct bq25890_init_data init_data ;
@@ -487,7 +489,7 @@ static int bq25890_power_supply_get_property(struct power_supply *psy,
487489
488490 switch (psp ) {
489491 case POWER_SUPPLY_PROP_STATUS :
490- if (!state .online )
492+ if (!state .online || state . hiz )
491493 val -> intval = POWER_SUPPLY_STATUS_DISCHARGING ;
492494 else if (state .chrg_status == STATUS_NOT_CHARGING )
493495 val -> intval = POWER_SUPPLY_STATUS_NOT_CHARGING ;
@@ -502,7 +504,8 @@ static int bq25890_power_supply_get_property(struct power_supply *psy,
502504 break ;
503505
504506 case POWER_SUPPLY_PROP_CHARGE_TYPE :
505- if (!state .online || state .chrg_status == STATUS_NOT_CHARGING ||
507+ if (!state .online || state .hiz ||
508+ state .chrg_status == STATUS_NOT_CHARGING ||
506509 state .chrg_status == STATUS_TERMINATION_DONE )
507510 val -> intval = POWER_SUPPLY_CHARGE_TYPE_NONE ;
508511 else if (state .chrg_status == STATUS_PRE_CHARGING )
@@ -522,7 +525,7 @@ static int bq25890_power_supply_get_property(struct power_supply *psy,
522525 break ;
523526
524527 case POWER_SUPPLY_PROP_ONLINE :
525- val -> intval = state .online ;
528+ val -> intval = state .online && ! state . hiz ;
526529 break ;
527530
528531 case POWER_SUPPLY_PROP_HEALTH :
@@ -676,7 +679,8 @@ static int bq25890_power_supply_set_property(struct power_supply *psy,
676679 const union power_supply_propval * val )
677680{
678681 struct bq25890_device * bq = power_supply_get_drvdata (psy );
679- int maxval ;
682+ struct bq25890_state state ;
683+ int maxval , ret ;
680684 u8 lval ;
681685
682686 switch (psp ) {
@@ -691,6 +695,12 @@ static int bq25890_power_supply_set_property(struct power_supply *psy,
691695 case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT :
692696 lval = bq25890_find_idx (val -> intval , TBL_IINLIM );
693697 return bq25890_field_write (bq , F_IINLIM , lval );
698+ case POWER_SUPPLY_PROP_ONLINE :
699+ ret = bq25890_field_write (bq , F_EN_HIZ , !val -> intval );
700+ if (!ret )
701+ bq -> force_hiz = !val -> intval ;
702+ bq25890_update_state (bq , psp , & state );
703+ return ret ;
694704 default :
695705 return - EINVAL ;
696706 }
@@ -703,6 +713,7 @@ static int bq25890_power_supply_property_is_writeable(struct power_supply *psy,
703713 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_CURRENT :
704714 case POWER_SUPPLY_PROP_CONSTANT_CHARGE_VOLTAGE :
705715 case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT :
716+ case POWER_SUPPLY_PROP_ONLINE :
706717 return true;
707718 default :
708719 return false;
@@ -757,6 +768,7 @@ static int bq25890_get_chip_state(struct bq25890_device *bq,
757768 } state_fields [] = {
758769 {F_CHG_STAT , & state -> chrg_status },
759770 {F_PG_STAT , & state -> online },
771+ {F_EN_HIZ , & state -> hiz },
760772 {F_VSYS_STAT , & state -> vsys_status },
761773 {F_BOOST_FAULT , & state -> boost_fault },
762774 {F_BAT_FAULT , & state -> bat_fault },
@@ -772,10 +784,11 @@ static int bq25890_get_chip_state(struct bq25890_device *bq,
772784 * state_fields [i ].data = ret ;
773785 }
774786
775- dev_dbg (bq -> dev , "S:CHG/PG/VSYS=%d/%d/%d, F:CHG/BOOST/BAT/NTC=%d/%d/%d/%d\n" ,
776- state -> chrg_status , state -> online , state -> vsys_status ,
777- state -> chrg_fault , state -> boost_fault , state -> bat_fault ,
778- state -> ntc_fault );
787+ dev_dbg (bq -> dev , "S:CHG/PG/HIZ/VSYS=%d/%d/%d/%d, F:CHG/BOOST/BAT/NTC=%d/%d/%d/%d\n" ,
788+ state -> chrg_status , state -> online ,
789+ state -> hiz , state -> vsys_status ,
790+ state -> chrg_fault , state -> boost_fault ,
791+ state -> bat_fault , state -> ntc_fault );
779792
780793 return 0 ;
781794}
@@ -792,16 +805,33 @@ static irqreturn_t __bq25890_handle_irq(struct bq25890_device *bq)
792805 if (!memcmp (& bq -> state , & new_state , sizeof (new_state )))
793806 return IRQ_NONE ;
794807
795- if (!new_state .online && bq -> state .online ) { /* power removed */
808+ /* power removed or HiZ */
809+ if ((!new_state .online || new_state .hiz ) && bq -> state .online ) {
796810 /* disable ADC */
797811 ret = bq25890_field_write (bq , F_CONV_RATE , 0 );
798812 if (ret < 0 )
799813 goto error ;
800- } else if (new_state .online && !bq -> state .online ) { /* power inserted */
801- /* enable ADC, to have control of charge current/voltage */
802- ret = bq25890_field_write (bq , F_CONV_RATE , 1 );
803- if (ret < 0 )
804- goto error ;
814+ } else if (new_state .online && !bq -> state .online ) {
815+ /*
816+ * Restore HiZ bit in case it was set by user.
817+ * The chip does not retain this bit once the
818+ * cable is re-plugged, hence the bit must be
819+ * reset manually here.
820+ */
821+ if (bq -> force_hiz ) {
822+ ret = bq25890_field_write (bq , F_EN_HIZ , bq -> force_hiz );
823+ if (ret < 0 )
824+ goto error ;
825+ new_state .hiz = 1 ;
826+ }
827+
828+ if (!new_state .hiz ) {
829+ /* power inserted and not HiZ */
830+ /* enable ADC, to have control of charge current/voltage */
831+ ret = bq25890_field_write (bq , F_CONV_RATE , 1 );
832+ if (ret < 0 )
833+ goto error ;
834+ }
805835 }
806836
807837 bq -> state = new_state ;
0 commit comments