Commit ae640fc6 authored by Chris Morgan's avatar Chris Morgan Committed by Sebastian Reichel

power: supply: axp20x_usb_power: Make VBUS and IIO config per device

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: default avatarChris Morgan <macromorgan@hotmail.com>
Acked-by: default avatarKrzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
Link: https://lore.kernel.org/r/20240821215456.962564-5-macroalpha82@gmail.comSigned-off-by: default avatarSebastian Reichel <sebastian.reichel@collabora.com>
parent db97fecb
......@@ -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;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment