]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
power: supply: axp20x_usb_power: Make VBUS and IIO config per device
authorChris Morgan <macromorgan@hotmail.com>
Wed, 21 Aug 2024 21:54:45 +0000 (16:54 -0500)
committerSebastian Reichel <sebastian.reichel@collabora.com>
Tue, 27 Aug 2024 16:12:25 +0000 (18:12 +0200)
Make reading of the vbus value and configuring of the iio channels
device specific, to allow additional devices (such as the AXP717) to
be supported by this driver.

Signed-off-by: Chris Morgan <macromorgan@hotmail.com>
Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
Link: https://lore.kernel.org/r/20240821215456.962564-5-macroalpha82@gmail.com
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
drivers/power/supply/axp20x_usb_power.c

index dae7e5cfc54e1b3226881303e48c1bcbef1d411a..cd9e92f2ce71ff3ca184409fe8e63aa7e15abe96 100644 (file)
@@ -45,6 +45,8 @@
  */
 #define DEBOUNCE_TIME                  msecs_to_jiffies(50)
 
+struct axp20x_usb_power;
+
 struct axp_data {
        const struct power_supply_desc  *power_desc;
        const char * const              *irq_names;
@@ -58,6 +60,10 @@ struct axp_data {
        struct reg_field                usb_bc_det_fld;
        struct reg_field                vbus_disable_bit;
        bool                            vbus_needs_polling: 1;
+       void (*axp20x_read_vbus)(struct work_struct *work);
+       int (*axp20x_cfg_iio_chan)(struct platform_device *pdev,
+                                  struct axp20x_usb_power *power);
+       int (*axp20x_cfg_adc_reg)(struct axp20x_usb_power *power);
 };
 
 struct axp20x_usb_power {
@@ -385,6 +391,36 @@ static int axp20x_usb_power_prop_writeable(struct power_supply *psy,
               psp == POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT;
 }
 
+static int axp20x_configure_iio_channels(struct platform_device *pdev,
+                                        struct axp20x_usb_power *power)
+{
+       power->vbus_v = devm_iio_channel_get(&pdev->dev, "vbus_v");
+       if (IS_ERR(power->vbus_v)) {
+               if (PTR_ERR(power->vbus_v) == -ENODEV)
+                       return -EPROBE_DEFER;
+               return PTR_ERR(power->vbus_v);
+       }
+
+       power->vbus_i = devm_iio_channel_get(&pdev->dev, "vbus_i");
+       if (IS_ERR(power->vbus_i)) {
+               if (PTR_ERR(power->vbus_i) == -ENODEV)
+                       return -EPROBE_DEFER;
+               return PTR_ERR(power->vbus_i);
+       }
+
+       return 0;
+}
+
+static int axp20x_configure_adc_registers(struct axp20x_usb_power *power)
+{
+       /* Enable vbus voltage and current measurement */
+       return regmap_update_bits(power->regmap, AXP20X_ADC_EN1,
+                                 AXP20X_ADC_EN1_VBUS_CURR |
+                                 AXP20X_ADC_EN1_VBUS_VOLT,
+                                 AXP20X_ADC_EN1_VBUS_CURR |
+                                 AXP20X_ADC_EN1_VBUS_VOLT);
+}
+
 static enum power_supply_property axp20x_usb_power_properties[] = {
        POWER_SUPPLY_PROP_HEALTH,
        POWER_SUPPLY_PROP_PRESENT,
@@ -505,6 +541,9 @@ static const struct axp_data axp192_data = {
        .curr_lim_fld   = REG_FIELD(AXP20X_VBUS_IPSOUT_MGMT, 0, 1),
        .vbus_valid_bit = REG_FIELD(AXP192_USB_OTG_STATUS, 2, 2),
        .vbus_mon_bit   = REG_FIELD(AXP20X_VBUS_MON, 3, 3),
+       .axp20x_read_vbus = &axp20x_usb_power_poll_vbus,
+       .axp20x_cfg_iio_chan = axp20x_configure_iio_channels,
+       .axp20x_cfg_adc_reg = axp20x_configure_adc_registers,
 };
 
 static const struct axp_data axp202_data = {
@@ -516,6 +555,9 @@ static const struct axp_data axp202_data = {
        .curr_lim_fld   = REG_FIELD(AXP20X_VBUS_IPSOUT_MGMT, 0, 1),
        .vbus_valid_bit = REG_FIELD(AXP20X_USB_OTG_STATUS, 2, 2),
        .vbus_mon_bit   = REG_FIELD(AXP20X_VBUS_MON, 3, 3),
+       .axp20x_read_vbus = &axp20x_usb_power_poll_vbus,
+       .axp20x_cfg_iio_chan = axp20x_configure_iio_channels,
+       .axp20x_cfg_adc_reg = axp20x_configure_adc_registers,
 };
 
 static const struct axp_data axp221_data = {
@@ -526,6 +568,9 @@ static const struct axp_data axp221_data = {
        .curr_lim_table_size = ARRAY_SIZE(axp221_usb_curr_lim_table),
        .curr_lim_fld   = REG_FIELD(AXP20X_VBUS_IPSOUT_MGMT, 0, 1),
        .vbus_needs_polling = true,
+       .axp20x_read_vbus = &axp20x_usb_power_poll_vbus,
+       .axp20x_cfg_iio_chan = axp20x_configure_iio_channels,
+       .axp20x_cfg_adc_reg = axp20x_configure_adc_registers,
 };
 
 static const struct axp_data axp223_data = {
@@ -536,6 +581,9 @@ static const struct axp_data axp223_data = {
        .curr_lim_table_size = ARRAY_SIZE(axp20x_usb_curr_lim_table),
        .curr_lim_fld   = REG_FIELD(AXP20X_VBUS_IPSOUT_MGMT, 0, 1),
        .vbus_needs_polling = true,
+       .axp20x_read_vbus = &axp20x_usb_power_poll_vbus,
+       .axp20x_cfg_iio_chan = axp20x_configure_iio_channels,
+       .axp20x_cfg_adc_reg = axp20x_configure_adc_registers,
 };
 
 static const struct axp_data axp813_data = {
@@ -549,6 +597,9 @@ static const struct axp_data axp813_data = {
        .usb_bc_det_fld = REG_FIELD(AXP288_BC_DET_STAT, 5, 7),
        .vbus_disable_bit = REG_FIELD(AXP20X_VBUS_IPSOUT_MGMT, 7, 7),
        .vbus_needs_polling = true,
+       .axp20x_read_vbus = &axp20x_usb_power_poll_vbus,
+       .axp20x_cfg_iio_chan = axp20x_configure_iio_channels,
+       .axp20x_cfg_adc_reg = axp20x_configure_adc_registers,
 };
 
 #ifdef CONFIG_PM_SLEEP
@@ -590,36 +641,6 @@ static int axp20x_usb_power_resume(struct device *dev)
 static SIMPLE_DEV_PM_OPS(axp20x_usb_power_pm_ops, axp20x_usb_power_suspend,
                                                  axp20x_usb_power_resume);
 
-static int configure_iio_channels(struct platform_device *pdev,
-                                 struct axp20x_usb_power *power)
-{
-       power->vbus_v = devm_iio_channel_get(&pdev->dev, "vbus_v");
-       if (IS_ERR(power->vbus_v)) {
-               if (PTR_ERR(power->vbus_v) == -ENODEV)
-                       return -EPROBE_DEFER;
-               return PTR_ERR(power->vbus_v);
-       }
-
-       power->vbus_i = devm_iio_channel_get(&pdev->dev, "vbus_i");
-       if (IS_ERR(power->vbus_i)) {
-               if (PTR_ERR(power->vbus_i) == -ENODEV)
-                       return -EPROBE_DEFER;
-               return PTR_ERR(power->vbus_i);
-       }
-
-       return 0;
-}
-
-static int configure_adc_registers(struct axp20x_usb_power *power)
-{
-       /* Enable vbus voltage and current measurement */
-       return regmap_update_bits(power->regmap, AXP20X_ADC_EN1,
-                                 AXP20X_ADC_EN1_VBUS_CURR |
-                                 AXP20X_ADC_EN1_VBUS_VOLT,
-                                 AXP20X_ADC_EN1_VBUS_CURR |
-                                 AXP20X_ADC_EN1_VBUS_VOLT);
-}
-
 static int axp20x_regmap_field_alloc_optional(struct device *dev,
                                              struct regmap *regmap,
                                              struct reg_field fdesc,
@@ -707,7 +728,7 @@ static int axp20x_usb_power_probe(struct platform_device *pdev)
                return ret;
 
        ret = devm_delayed_work_autocancel(&pdev->dev, &power->vbus_detect,
-                                          axp20x_usb_power_poll_vbus);
+                                          axp_data->axp20x_read_vbus);
        if (ret)
                return ret;
 
@@ -718,9 +739,9 @@ static int axp20x_usb_power_probe(struct platform_device *pdev)
                        return ret;
 
                if (IS_ENABLED(CONFIG_AXP20X_ADC))
-                       ret = configure_iio_channels(pdev, power);
+                       ret = axp_data->axp20x_cfg_iio_chan(pdev, power);
                else
-                       ret = configure_adc_registers(power);
+                       ret = axp_data->axp20x_cfg_adc_reg(power);
 
                if (ret)
                        return ret;