3030#define AXP20X_PWR_STATUS_VBUS_PRESENT BIT(5)
3131#define AXP20X_PWR_STATUS_VBUS_USED BIT(4)
3232
33+ #define AXP717_PWR_STATUS_VBUS_GOOD BIT(5)
34+
3335#define AXP20X_USB_STATUS_VBUS_VALID BIT(2)
3436
37+ #define AXP717_PMU_FAULT_VBUS BIT(5)
38+ #define AXP717_PMU_FAULT_VSYS BIT(3)
39+
3540#define AXP20X_VBUS_VHOLD_uV (b ) (4000000 + (((b) >> 3) & 7) * 100000)
3641#define AXP20X_VBUS_VHOLD_MASK GENMASK(5, 3)
3742#define AXP20X_VBUS_VHOLD_OFFSET 3
3843
3944#define AXP20X_ADC_EN1_VBUS_CURR BIT(2)
4045#define AXP20X_ADC_EN1_VBUS_VOLT BIT(3)
4146
47+ #define AXP717_INPUT_VOL_LIMIT_MASK GENMASK(3, 0)
48+ #define AXP717_INPUT_CUR_LIMIT_MASK GENMASK(5, 0)
49+ #define AXP717_ADC_DATA_MASK GENMASK(14, 0)
50+
51+ #define AXP717_ADC_EN_VBUS_VOLT BIT(2)
52+
4253/*
4354 * Note do not raise the debounce time, we must report Vusb high within
4455 * 100ms otherwise we get Vbus errors in musb.
@@ -143,6 +154,24 @@ static void axp20x_usb_power_poll_vbus(struct work_struct *work)
143154 mod_delayed_work (system_power_efficient_wq , & power -> vbus_detect , DEBOUNCE_TIME );
144155}
145156
157+ static void axp717_usb_power_poll_vbus (struct work_struct * work )
158+ {
159+ struct axp20x_usb_power * power =
160+ container_of (work , struct axp20x_usb_power , vbus_detect .work );
161+ unsigned int val ;
162+ int ret ;
163+
164+ ret = regmap_read (power -> regmap , AXP717_ON_INDICATE , & val );
165+ if (ret )
166+ return ;
167+
168+ val &= AXP717_PWR_STATUS_VBUS_GOOD ;
169+ if (val != power -> old_status )
170+ power_supply_changed (power -> supply );
171+
172+ power -> old_status = val ;
173+ }
174+
146175static int axp20x_get_usb_type (struct axp20x_usb_power * power ,
147176 union power_supply_propval * val )
148177{
@@ -288,6 +317,91 @@ static int axp20x_usb_power_get_property(struct power_supply *psy,
288317 return 0 ;
289318}
290319
320+ static int axp717_usb_power_get_property (struct power_supply * psy ,
321+ enum power_supply_property psp , union power_supply_propval * val )
322+ {
323+ struct axp20x_usb_power * power = power_supply_get_drvdata (psy );
324+ unsigned int v ;
325+ int ret ;
326+
327+ switch (psp ) {
328+ case POWER_SUPPLY_PROP_HEALTH :
329+ val -> intval = POWER_SUPPLY_HEALTH_GOOD ;
330+ ret = regmap_read (power -> regmap , AXP717_ON_INDICATE , & v );
331+ if (ret )
332+ return ret ;
333+
334+ if (!(v & AXP717_PWR_STATUS_VBUS_GOOD ))
335+ val -> intval = POWER_SUPPLY_HEALTH_UNKNOWN ;
336+
337+ ret = regmap_read (power -> regmap , AXP717_PMU_FAULT_VBUS , & v );
338+ if (ret )
339+ return ret ;
340+
341+ v &= (AXP717_PMU_FAULT_VBUS | AXP717_PMU_FAULT_VSYS );
342+ if (v ) {
343+ val -> intval = POWER_SUPPLY_HEALTH_OVERVOLTAGE ;
344+ regmap_write (power -> regmap , AXP717_PMU_FAULT_VBUS , v );
345+ }
346+
347+ break ;
348+ case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT :
349+ ret = regmap_read (power -> regmap , AXP717_INPUT_CUR_LIMIT_CTRL , & v );
350+ if (ret )
351+ return ret ;
352+
353+ /* 50ma step size with 100ma offset. */
354+ v &= AXP717_INPUT_CUR_LIMIT_MASK ;
355+ val -> intval = (v * 50000 ) + 100000 ;
356+ break ;
357+ case POWER_SUPPLY_PROP_ONLINE :
358+ case POWER_SUPPLY_PROP_PRESENT :
359+ ret = regmap_read (power -> regmap , AXP717_ON_INDICATE , & v );
360+ if (ret )
361+ return ret ;
362+ val -> intval = !!(v & AXP717_PWR_STATUS_VBUS_GOOD );
363+ break ;
364+ case POWER_SUPPLY_PROP_USB_TYPE :
365+ return axp20x_get_usb_type (power , val );
366+ case POWER_SUPPLY_PROP_VOLTAGE_MIN :
367+ ret = regmap_read (power -> regmap , AXP717_INPUT_VOL_LIMIT_CTRL , & v );
368+ if (ret )
369+ return ret ;
370+
371+ /* 80mv step size with 3.88v offset. */
372+ v &= AXP717_INPUT_VOL_LIMIT_MASK ;
373+ val -> intval = (v * 80000 ) + 3880000 ;
374+ break ;
375+ case POWER_SUPPLY_PROP_VOLTAGE_NOW :
376+ if (IS_ENABLED (CONFIG_AXP20X_ADC )) {
377+ ret = iio_read_channel_processed (power -> vbus_v ,
378+ & val -> intval );
379+ if (ret )
380+ return ret ;
381+
382+ /*
383+ * IIO framework gives mV but Power Supply framework
384+ * gives uV.
385+ */
386+ val -> intval *= 1000 ;
387+ return 0 ;
388+ }
389+
390+ ret = axp20x_read_variable_width (power -> regmap ,
391+ AXP717_VBUS_V_H , 16 );
392+ if (ret < 0 )
393+ return ret ;
394+
395+ val -> intval = (ret % AXP717_ADC_DATA_MASK ) * 1000 ;
396+ break ;
397+ default :
398+ return - EINVAL ;
399+ }
400+
401+ return 0 ;
402+
403+ }
404+
291405static int axp20x_usb_power_set_voltage_min (struct axp20x_usb_power * power ,
292406 int intval )
293407{
@@ -314,6 +428,22 @@ static int axp20x_usb_power_set_voltage_min(struct axp20x_usb_power *power,
314428 return - EINVAL ;
315429}
316430
431+ static int axp717_usb_power_set_voltage_min (struct axp20x_usb_power * power ,
432+ int intval )
433+ {
434+ int val ;
435+
436+ /* Minimum value of 3.88v and maximum of 5.08v. */
437+ if (intval < 3880000 || intval > 5080000 )
438+ return - EINVAL ;
439+
440+ /* step size of 80ma with 3.88v offset. */
441+ val = (intval - 3880000 ) / 80000 ;
442+ return regmap_update_bits (power -> regmap ,
443+ AXP717_INPUT_VOL_LIMIT_CTRL ,
444+ AXP717_INPUT_VOL_LIMIT_MASK , val );
445+ }
446+
317447static int axp20x_usb_power_set_input_current_limit (struct axp20x_usb_power * power ,
318448 int intval )
319449{
@@ -354,6 +484,29 @@ static int axp20x_usb_power_set_input_current_limit(struct axp20x_usb_power *pow
354484 return regmap_field_write (power -> curr_lim_fld , reg );
355485}
356486
487+ static int axp717_usb_power_set_input_current_limit (struct axp20x_usb_power * power ,
488+ int intval )
489+ {
490+ int tmp ;
491+
492+ /* Minimum value of 100mA and maximum value of 3.25A*/
493+ if (intval < 100000 || intval > 3250000 )
494+ return - EINVAL ;
495+
496+ if (power -> max_input_cur && (intval > power -> max_input_cur )) {
497+ dev_warn (power -> dev ,
498+ "reqested current %d clamped to max current %d\n" ,
499+ intval , power -> max_input_cur );
500+ intval = power -> max_input_cur ;
501+ }
502+
503+ /* Minimum value of 100mA with step size of 50mA. */
504+ tmp = (intval - 100000 ) / 50000 ;
505+ return regmap_update_bits (power -> regmap ,
506+ AXP717_INPUT_CUR_LIMIT_CTRL ,
507+ AXP717_INPUT_CUR_LIMIT_MASK , tmp );
508+ }
509+
357510static int axp20x_usb_power_set_property (struct power_supply * psy ,
358511 enum power_supply_property psp ,
359512 const union power_supply_propval * val )
@@ -376,6 +529,24 @@ static int axp20x_usb_power_set_property(struct power_supply *psy,
376529 default :
377530 return - EINVAL ;
378531 }
532+ }
533+
534+ static int axp717_usb_power_set_property (struct power_supply * psy ,
535+ enum power_supply_property psp ,
536+ const union power_supply_propval * val )
537+ {
538+ struct axp20x_usb_power * power = power_supply_get_drvdata (psy );
539+
540+ switch (psp ) {
541+ case POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT :
542+ return axp717_usb_power_set_input_current_limit (power , val -> intval );
543+
544+ case POWER_SUPPLY_PROP_VOLTAGE_MIN :
545+ return axp717_usb_power_set_voltage_min (power , val -> intval );
546+
547+ default :
548+ return - EINVAL ;
549+ }
379550
380551 return - EINVAL ;
381552}
@@ -399,6 +570,13 @@ static int axp20x_usb_power_prop_writeable(struct power_supply *psy,
399570 psp == POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT ;
400571}
401572
573+ static int axp717_usb_power_prop_writeable (struct power_supply * psy ,
574+ enum power_supply_property psp )
575+ {
576+ return psp == POWER_SUPPLY_PROP_VOLTAGE_MIN ||
577+ psp == POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT ;
578+ }
579+
402580static int axp20x_configure_iio_channels (struct platform_device * pdev ,
403581 struct axp20x_usb_power * power )
404582{
@@ -419,6 +597,19 @@ static int axp20x_configure_iio_channels(struct platform_device *pdev,
419597 return 0 ;
420598}
421599
600+ static int axp717_configure_iio_channels (struct platform_device * pdev ,
601+ struct axp20x_usb_power * power )
602+ {
603+ power -> vbus_v = devm_iio_channel_get (& pdev -> dev , "vbus_v" );
604+ if (IS_ERR (power -> vbus_v )) {
605+ if (PTR_ERR (power -> vbus_v ) == - ENODEV )
606+ return - EPROBE_DEFER ;
607+ return PTR_ERR (power -> vbus_v );
608+ }
609+
610+ return 0 ;
611+ }
612+
422613static int axp20x_configure_adc_registers (struct axp20x_usb_power * power )
423614{
424615 /* Enable vbus voltage and current measurement */
@@ -429,6 +620,14 @@ static int axp20x_configure_adc_registers(struct axp20x_usb_power *power)
429620 AXP20X_ADC_EN1_VBUS_VOLT );
430621}
431622
623+ static int axp717_configure_adc_registers (struct axp20x_usb_power * power )
624+ {
625+ /* Enable vbus voltage measurement */
626+ return regmap_update_bits (power -> regmap , AXP717_ADC_CH_EN_CONTROL ,
627+ AXP717_ADC_EN_VBUS_VOLT ,
628+ AXP717_ADC_EN_VBUS_VOLT );
629+ }
630+
432631static enum power_supply_property axp20x_usb_power_properties [] = {
433632 POWER_SUPPLY_PROP_HEALTH ,
434633 POWER_SUPPLY_PROP_PRESENT ,
@@ -447,6 +646,16 @@ static enum power_supply_property axp22x_usb_power_properties[] = {
447646 POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT ,
448647};
449648
649+ static enum power_supply_property axp717_usb_power_properties [] = {
650+ POWER_SUPPLY_PROP_HEALTH ,
651+ POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT ,
652+ POWER_SUPPLY_PROP_ONLINE ,
653+ POWER_SUPPLY_PROP_PRESENT ,
654+ POWER_SUPPLY_PROP_USB_TYPE ,
655+ POWER_SUPPLY_PROP_VOLTAGE_MIN ,
656+ POWER_SUPPLY_PROP_VOLTAGE_NOW ,
657+ };
658+
450659static enum power_supply_property axp813_usb_power_properties [] = {
451660 POWER_SUPPLY_PROP_HEALTH ,
452661 POWER_SUPPLY_PROP_PRESENT ,
@@ -476,6 +685,20 @@ static const struct power_supply_desc axp22x_usb_power_desc = {
476685 .set_property = axp20x_usb_power_set_property ,
477686};
478687
688+ static const struct power_supply_desc axp717_usb_power_desc = {
689+ .name = "axp20x-usb" ,
690+ .type = POWER_SUPPLY_TYPE_USB ,
691+ .properties = axp717_usb_power_properties ,
692+ .num_properties = ARRAY_SIZE (axp717_usb_power_properties ),
693+ .property_is_writeable = axp717_usb_power_prop_writeable ,
694+ .get_property = axp717_usb_power_get_property ,
695+ .set_property = axp717_usb_power_set_property ,
696+ .usb_types = BIT (POWER_SUPPLY_USB_TYPE_SDP ) |
697+ BIT (POWER_SUPPLY_USB_TYPE_CDP ) |
698+ BIT (POWER_SUPPLY_USB_TYPE_DCP ) |
699+ BIT (POWER_SUPPLY_USB_TYPE_UNKNOWN ),
700+ };
701+
479702static const struct power_supply_desc axp813_usb_power_desc = {
480703 .name = "axp20x-usb" ,
481704 .type = POWER_SUPPLY_TYPE_USB ,
@@ -502,6 +725,12 @@ static const char * const axp22x_irq_names[] = {
502725 "VBUS_REMOVAL" ,
503726};
504727
728+ static const char * const axp717_irq_names [] = {
729+ "VBUS_PLUGIN" ,
730+ "VBUS_REMOVAL" ,
731+ "VBUS_OVER_V" ,
732+ };
733+
505734static int axp192_usb_curr_lim_table [] = {
506735 -1 ,
507736 -1 ,
@@ -589,6 +818,20 @@ static const struct axp_data axp223_data = {
589818 .axp20x_cfg_adc_reg = axp20x_configure_adc_registers ,
590819};
591820
821+ static const struct axp_data axp717_data = {
822+ .power_desc = & axp717_usb_power_desc ,
823+ .irq_names = axp717_irq_names ,
824+ .num_irq_names = ARRAY_SIZE (axp717_irq_names ),
825+ .curr_lim_fld = REG_FIELD (AXP717_INPUT_CUR_LIMIT_CTRL , 0 , 5 ),
826+ .usb_bc_en_bit = REG_FIELD (AXP717_MODULE_EN_CONTROL_1 , 4 , 4 ),
827+ .usb_bc_det_fld = REG_FIELD (AXP717_BC_DETECT , 5 , 7 ),
828+ .vbus_mon_bit = REG_FIELD (AXP717_ADC_CH_EN_CONTROL , 2 , 2 ),
829+ .vbus_needs_polling = false,
830+ .axp20x_read_vbus = & axp717_usb_power_poll_vbus ,
831+ .axp20x_cfg_iio_chan = axp717_configure_iio_channels ,
832+ .axp20x_cfg_adc_reg = axp717_configure_adc_registers ,
833+ };
834+
592835static const struct axp_data axp813_data = {
593836 .power_desc = & axp813_usb_power_desc ,
594837 .irq_names = axp22x_irq_names ,
@@ -816,6 +1059,9 @@ static const struct of_device_id axp20x_usb_power_match[] = {
8161059 }, {
8171060 .compatible = "x-powers,axp223-usb-power-supply" ,
8181061 .data = & axp223_data ,
1062+ }, {
1063+ .compatible = "x-powers,axp717-usb-power-supply" ,
1064+ .data = & axp717_data ,
8191065 }, {
8201066 .compatible = "x-powers,axp813-usb-power-supply" ,
8211067 .data = & axp813_data ,
0 commit comments