Message ID | 20250212010744.2554574-3-james.a.macinnes@gmail.com (mailing list archive) |
---|---|
State | Not Applicable |
Headers | show |
Series | Add PMI8998 VBUS Regulator Support v2 | expand |
On Tue, Feb 11, 2025 at 05:07:43PM -0800, James A. MacInnes wrote: > This patch extends the Qualcomm USB VBUS regulator driver to support > PMI8998 PMIC alongside the existing support for PM8150B. Please modify this commit message according to follow the example I provided for the patch 3. If you are unsure `git log drivers/regulator` will provide you with good enough examples. > > Key changes: > - Added current limit tables specific to PMI8998. > - Dynamically configure the VBUS regulator based on the PMIC type. > - Updated debug messages to reflect successful initialization for > supported PMICs. > - Changed registration log message > > These changes ensure proper VBUS current limit configuration and > compatibility across multiple Qualcomm PMICs. > > Signed-off-by: James A. MacInnes <james.a.macinnes@gmail.com> > --- > drivers/regulator/qcom_usb_vbus-regulator.c | 38 ++++++++++++++++++--- > 1 file changed, 33 insertions(+), 5 deletions(-) > > diff --git a/drivers/regulator/qcom_usb_vbus-regulator.c b/drivers/regulator/qcom_usb_vbus-regulator.c > index cd94ed67621f..804dd1a9e057 100644 > --- a/drivers/regulator/qcom_usb_vbus-regulator.c > +++ b/drivers/regulator/qcom_usb_vbus-regulator.c > @@ -20,10 +20,30 @@ > #define OTG_CFG 0x53 > #define OTG_EN_SRC_CFG BIT(1) > > -static const unsigned int curr_table[] = { > +struct msm_vbus_desc { > + const unsigned int *curr_table; > + unsigned int n_current_limits; > +}; > + > +static const unsigned int curr_table_pm8150b[] = { > 500000, 1000000, 1500000, 2000000, 2500000, 3000000, > }; > > +static const unsigned int curr_table_pmi8998[] = { > + 250000, 500000, 750000, 1000000, > + 1250000, 1500000, 1750000, 2000000, > +}; > + > +static const struct msm_vbus_desc msm_vbus_desc_pm8150b = { > + .curr_table = curr_table_pm8150b, > + .n_current_limits = ARRAY_SIZE(curr_table_pm8150b), > +}; > + > +static const struct msm_vbus_desc msm_vbus_desc_pmi8998 = { > + .curr_table = curr_table_pmi8998, > + .n_current_limits = ARRAY_SIZE(curr_table_pmi8998), > +}; > + > static const struct regulator_ops qcom_usb_vbus_reg_ops = { > .enable = regulator_enable_regmap, > .disable = regulator_disable_regmap, > @@ -37,8 +57,6 @@ static struct regulator_desc qcom_usb_vbus_rdesc = { > .ops = &qcom_usb_vbus_reg_ops, > .owner = THIS_MODULE, > .type = REGULATOR_VOLTAGE, > - .curr_table = curr_table, > - .n_current_limits = ARRAY_SIZE(curr_table), > }; > > static int qcom_usb_vbus_regulator_probe(struct platform_device *pdev) > @@ -48,6 +66,7 @@ static int qcom_usb_vbus_regulator_probe(struct platform_device *pdev) > struct regmap *regmap; > struct regulator_config config = { }; > struct regulator_init_data *init_data; > + const struct msm_vbus_desc *quirks; > int ret; > u32 base; > > @@ -68,6 +87,12 @@ static int qcom_usb_vbus_regulator_probe(struct platform_device *pdev) > if (!init_data) > return -ENOMEM; > > + quirks = of_device_get_match_data(dev); > + if (!quirks) > + return -ENODEV; > + > + qcom_usb_vbus_rdesc.curr_table = quirks->curr_table; > + qcom_usb_vbus_rdesc.n_current_limits = quirks->n_current_limits; > qcom_usb_vbus_rdesc.enable_reg = base + CMD_OTG; > qcom_usb_vbus_rdesc.enable_mask = OTG_EN; > qcom_usb_vbus_rdesc.csel_reg = base + OTG_CURRENT_LIMIT_CFG; > @@ -80,18 +105,21 @@ static int qcom_usb_vbus_regulator_probe(struct platform_device *pdev) > rdev = devm_regulator_register(dev, &qcom_usb_vbus_rdesc, &config); > if (IS_ERR(rdev)) { > ret = PTR_ERR(rdev); > - dev_err(dev, "not able to register vbus reg %d\n", ret); > + dev_err(dev, "Failed to register vbus reg %d\n", ret); > return ret; > } > > /* Disable HW logic for VBUS enable */ > regmap_update_bits(regmap, base + OTG_CFG, OTG_EN_SRC_CFG, 0); > > + dev_dbg(dev, "Registered QCOM VBUS regulator\n"); > + > return 0; > } > > static const struct of_device_id qcom_usb_vbus_regulator_match[] = { > - { .compatible = "qcom,pm8150b-vbus-reg" }, > + { .compatible = "qcom,pm8150b-vbus-reg", .data = &msm_vbus_desc_pm8150b }, > + { .compatible = "qcom,pmi8998-vbus-reg", .data = &msm_vbus_desc_pmi8998 }, > { } > }; > MODULE_DEVICE_TABLE(of, qcom_usb_vbus_regulator_match); > -- > 2.43.0 >
On 12.02.2025 2:07 AM, James A. MacInnes wrote: > This patch extends the Qualcomm USB VBUS regulator driver to support > PMI8998 PMIC alongside the existing support for PM8150B. > > Key changes: > - Added current limit tables specific to PMI8998. > - Dynamically configure the VBUS regulator based on the PMIC type. > - Updated debug messages to reflect successful initialization for > supported PMICs. > - Changed registration log message > > These changes ensure proper VBUS current limit configuration and > compatibility across multiple Qualcomm PMICs. > > Signed-off-by: James A. MacInnes <james.a.macinnes@gmail.com> > --- > drivers/regulator/qcom_usb_vbus-regulator.c | 38 ++++++++++++++++++--- > 1 file changed, 33 insertions(+), 5 deletions(-) > > diff --git a/drivers/regulator/qcom_usb_vbus-regulator.c b/drivers/regulator/qcom_usb_vbus-regulator.c > index cd94ed67621f..804dd1a9e057 100644 > --- a/drivers/regulator/qcom_usb_vbus-regulator.c > +++ b/drivers/regulator/qcom_usb_vbus-regulator.c > @@ -20,10 +20,30 @@ > #define OTG_CFG 0x53 > #define OTG_EN_SRC_CFG BIT(1) > > -static const unsigned int curr_table[] = { > +struct msm_vbus_desc { > + const unsigned int *curr_table; > + unsigned int n_current_limits; > +}; > + > +static const unsigned int curr_table_pm8150b[] = { > 500000, 1000000, 1500000, 2000000, 2500000, 3000000, > }; > > +static const unsigned int curr_table_pmi8998[] = { > + 250000, 500000, 750000, 1000000, > + 1250000, 1500000, 1750000, 2000000, > +}; To the best of my understanding these numbers are correct > + > +static const struct msm_vbus_desc msm_vbus_desc_pm8150b = { > + .curr_table = curr_table_pm8150b, > + .n_current_limits = ARRAY_SIZE(curr_table_pm8150b), > +}; > + > +static const struct msm_vbus_desc msm_vbus_desc_pmi8998 = { > + .curr_table = curr_table_pmi8998, > + .n_current_limits = ARRAY_SIZE(curr_table_pmi8998), > +}; > + > static const struct regulator_ops qcom_usb_vbus_reg_ops = { > .enable = regulator_enable_regmap, > .disable = regulator_disable_regmap, > @@ -37,8 +57,6 @@ static struct regulator_desc qcom_usb_vbus_rdesc = { > .ops = &qcom_usb_vbus_reg_ops, > .owner = THIS_MODULE, > .type = REGULATOR_VOLTAGE, > - .curr_table = curr_table, > - .n_current_limits = ARRAY_SIZE(curr_table), > }; > > static int qcom_usb_vbus_regulator_probe(struct platform_device *pdev) > @@ -48,6 +66,7 @@ static int qcom_usb_vbus_regulator_probe(struct platform_device *pdev) > struct regmap *regmap; > struct regulator_config config = { }; > struct regulator_init_data *init_data; > + const struct msm_vbus_desc *quirks; 'quirks' is one way to put it ;) I'd call it 'desc' or 'data' but it's totally a potayto/potahto discussion > int ret; > u32 base; > > @@ -68,6 +87,12 @@ static int qcom_usb_vbus_regulator_probe(struct platform_device *pdev) > if (!init_data) > return -ENOMEM; > > + quirks = of_device_get_match_data(dev); > + if (!quirks) > + return -ENODEV; > + > + qcom_usb_vbus_rdesc.curr_table = quirks->curr_table; > + qcom_usb_vbus_rdesc.n_current_limits = quirks->n_current_limits; > qcom_usb_vbus_rdesc.enable_reg = base + CMD_OTG; > qcom_usb_vbus_rdesc.enable_mask = OTG_EN; > qcom_usb_vbus_rdesc.csel_reg = base + OTG_CURRENT_LIMIT_CFG; > @@ -80,18 +105,21 @@ static int qcom_usb_vbus_regulator_probe(struct platform_device *pdev) > rdev = devm_regulator_register(dev, &qcom_usb_vbus_rdesc, &config); > if (IS_ERR(rdev)) { > ret = PTR_ERR(rdev); > - dev_err(dev, "not able to register vbus reg %d\n", ret); > + dev_err(dev, "Failed to register vbus reg %d\n", ret); > return ret; > } > > /* Disable HW logic for VBUS enable */ > regmap_update_bits(regmap, base + OTG_CFG, OTG_EN_SRC_CFG, 0); > > + dev_dbg(dev, "Registered QCOM VBUS regulator\n"); Not sure how useful this is given the previous call creates a sysfs entry on success, but sure Konrad
Hi James, On 2/12/25 01:07, James A. MacInnes wrote: > This patch extends the Qualcomm USB VBUS regulator driver to support > PMI8998 PMIC alongside the existing support for PM8150B. Thanks for the patch! > > Key changes: > - Added current limit tables specific to PMI8998. I also played around with vbus on PMI8998 before for type-c support (unfortunately didn't make it's way to the lists yet...) and I needed some additional changes for this to work correctly. I found that it was possible for the overcurrent protection to be hit if the type-c port manager allowed the peripheral to pull current too early, and it's necessary to allow 2.5ms enable time. PM8150b doesn't have these limitations (and supports the instant power role switch feature that's part of the type-c PD spec, allowing the power role to be switched without either side losing power e.g. when you unplug the power supply from a dock), hence it's only necessary for PMI8998. I would suggest implementing a proper .is_enabled op to poll the status register for OTG_STATE_ENABLED and configuring qcom_usb_vbus_rdesc.enable_time = 250000; Kind regards, > - Dynamically configure the VBUS regulator based on the PMIC type. > - Updated debug messages to reflect successful initialization for > supported PMICs. > - Changed registration log message > > These changes ensure proper VBUS current limit configuration and > compatibility across multiple Qualcomm PMICs. > > Signed-off-by: James A. MacInnes <james.a.macinnes@gmail.com> > --- > drivers/regulator/qcom_usb_vbus-regulator.c | 38 ++++++++++++++++++--- > 1 file changed, 33 insertions(+), 5 deletions(-) > > diff --git a/drivers/regulator/qcom_usb_vbus-regulator.c b/drivers/regulator/qcom_usb_vbus-regulator.c > index cd94ed67621f..804dd1a9e057 100644 > --- a/drivers/regulator/qcom_usb_vbus-regulator.c > +++ b/drivers/regulator/qcom_usb_vbus-regulator.c > @@ -20,10 +20,30 @@ > #define OTG_CFG 0x53 > #define OTG_EN_SRC_CFG BIT(1) > > -static const unsigned int curr_table[] = { > +struct msm_vbus_desc { > + const unsigned int *curr_table; > + unsigned int n_current_limits; > +}; > + > +static const unsigned int curr_table_pm8150b[] = { > 500000, 1000000, 1500000, 2000000, 2500000, 3000000, > }; > > +static const unsigned int curr_table_pmi8998[] = { > + 250000, 500000, 750000, 1000000, > + 1250000, 1500000, 1750000, 2000000, > +}; > + > +static const struct msm_vbus_desc msm_vbus_desc_pm8150b = { > + .curr_table = curr_table_pm8150b, > + .n_current_limits = ARRAY_SIZE(curr_table_pm8150b), > +}; > + > +static const struct msm_vbus_desc msm_vbus_desc_pmi8998 = { > + .curr_table = curr_table_pmi8998, > + .n_current_limits = ARRAY_SIZE(curr_table_pmi8998), > +}; > + > static const struct regulator_ops qcom_usb_vbus_reg_ops = { > .enable = regulator_enable_regmap, > .disable = regulator_disable_regmap, > @@ -37,8 +57,6 @@ static struct regulator_desc qcom_usb_vbus_rdesc = { > .ops = &qcom_usb_vbus_reg_ops, > .owner = THIS_MODULE, > .type = REGULATOR_VOLTAGE, > - .curr_table = curr_table, > - .n_current_limits = ARRAY_SIZE(curr_table), > }; > > static int qcom_usb_vbus_regulator_probe(struct platform_device *pdev) > @@ -48,6 +66,7 @@ static int qcom_usb_vbus_regulator_probe(struct platform_device *pdev) > struct regmap *regmap; > struct regulator_config config = { }; > struct regulator_init_data *init_data; > + const struct msm_vbus_desc *quirks; > int ret; > u32 base; > > @@ -68,6 +87,12 @@ static int qcom_usb_vbus_regulator_probe(struct platform_device *pdev) > if (!init_data) > return -ENOMEM; > > + quirks = of_device_get_match_data(dev); > + if (!quirks) > + return -ENODEV; > + > + qcom_usb_vbus_rdesc.curr_table = quirks->curr_table; > + qcom_usb_vbus_rdesc.n_current_limits = quirks->n_current_limits; > qcom_usb_vbus_rdesc.enable_reg = base + CMD_OTG; > qcom_usb_vbus_rdesc.enable_mask = OTG_EN; > qcom_usb_vbus_rdesc.csel_reg = base + OTG_CURRENT_LIMIT_CFG; > @@ -80,18 +105,21 @@ static int qcom_usb_vbus_regulator_probe(struct platform_device *pdev) > rdev = devm_regulator_register(dev, &qcom_usb_vbus_rdesc, &config); > if (IS_ERR(rdev)) { > ret = PTR_ERR(rdev); > - dev_err(dev, "not able to register vbus reg %d\n", ret); > + dev_err(dev, "Failed to register vbus reg %d\n", ret); > return ret; > } > > /* Disable HW logic for VBUS enable */ > regmap_update_bits(regmap, base + OTG_CFG, OTG_EN_SRC_CFG, 0); > > + dev_dbg(dev, "Registered QCOM VBUS regulator\n"); > + > return 0; > } > > static const struct of_device_id qcom_usb_vbus_regulator_match[] = { > - { .compatible = "qcom,pm8150b-vbus-reg" }, > + { .compatible = "qcom,pm8150b-vbus-reg", .data = &msm_vbus_desc_pm8150b }, > + { .compatible = "qcom,pmi8998-vbus-reg", .data = &msm_vbus_desc_pmi8998 }, > { } > }; > MODULE_DEVICE_TABLE(of, qcom_usb_vbus_regulator_match);
On Wed, Feb 12, 2025 at 03:29:54PM +0000, Caleb Connolly wrote: > I would suggest implementing a proper .is_enabled op to poll the status > register for OTG_STATE_ENABLED and configuring No, that would be buggy. Implement a get_status() operation if the device can report status. is_enabled() should report what the driver asked for.
On 2/12/25 15:37, Mark Brown wrote: > On Wed, Feb 12, 2025 at 03:29:54PM +0000, Caleb Connolly wrote: > >> I would suggest implementing a proper .is_enabled op to poll the status >> register for OTG_STATE_ENABLED and configuring > > No, that would be buggy. Implement a get_status() operation if the > device can report status. is_enabled() should report what the driver > asked for. Ahh yep, that's right. it should implement .get_status() (as per the polling code in _regulator_do_enable()).
On Wed, 12 Feb 2025 13:55:59 +0100 Konrad Dybcio <konrad.dybcio@oss.qualcomm.com> wrote: > On 12.02.2025 2:07 AM, James A. MacInnes wrote: > > This patch extends the Qualcomm USB VBUS regulator driver to support > > PMI8998 PMIC alongside the existing support for PM8150B. > > > > Key changes: > > - Added current limit tables specific to PMI8998. > > - Dynamically configure the VBUS regulator based on the PMIC type. > > - Updated debug messages to reflect successful initialization for > > supported PMICs. > > - Changed registration log message > > > > These changes ensure proper VBUS current limit configuration and > > compatibility across multiple Qualcomm PMICs. > > > > Signed-off-by: James A. MacInnes <james.a.macinnes@gmail.com> > > --- > > drivers/regulator/qcom_usb_vbus-regulator.c | 38 > > ++++++++++++++++++--- 1 file changed, 33 insertions(+), 5 > > deletions(-) > > > > diff --git a/drivers/regulator/qcom_usb_vbus-regulator.c > > b/drivers/regulator/qcom_usb_vbus-regulator.c index > > cd94ed67621f..804dd1a9e057 100644 --- > > a/drivers/regulator/qcom_usb_vbus-regulator.c +++ > > b/drivers/regulator/qcom_usb_vbus-regulator.c @@ -20,10 +20,30 @@ > > #define OTG_CFG 0x53 > > #define OTG_EN_SRC_CFG BIT(1) > > > > -static const unsigned int curr_table[] = { > > +struct msm_vbus_desc { > > + const unsigned int *curr_table; > > + unsigned int n_current_limits; > > +}; > > + > > +static const unsigned int curr_table_pm8150b[] = { > > 500000, 1000000, 1500000, 2000000, 2500000, 3000000, > > }; > > > > +static const unsigned int curr_table_pmi8998[] = { > > + 250000, 500000, 750000, 1000000, > > + 1250000, 1500000, 1750000, 2000000, > > +}; > > To the best of my understanding these numbers are correct > Hopefully it is all correct. I pulled the numbers from the datasheet, but they are known to lie. > > + > > +static const struct msm_vbus_desc msm_vbus_desc_pm8150b = { > > + .curr_table = curr_table_pm8150b, > > + .n_current_limits = ARRAY_SIZE(curr_table_pm8150b), > > +}; > > + > > +static const struct msm_vbus_desc msm_vbus_desc_pmi8998 = { > > + .curr_table = curr_table_pmi8998, > > + .n_current_limits = ARRAY_SIZE(curr_table_pmi8998), > > +}; > > + > > static const struct regulator_ops qcom_usb_vbus_reg_ops = { > > .enable = regulator_enable_regmap, > > .disable = regulator_disable_regmap, > > @@ -37,8 +57,6 @@ static struct regulator_desc qcom_usb_vbus_rdesc > > = { .ops = &qcom_usb_vbus_reg_ops, > > .owner = THIS_MODULE, > > .type = REGULATOR_VOLTAGE, > > - .curr_table = curr_table, > > - .n_current_limits = ARRAY_SIZE(curr_table), > > }; > > > > static int qcom_usb_vbus_regulator_probe(struct platform_device > > *pdev) @@ -48,6 +66,7 @@ static int > > qcom_usb_vbus_regulator_probe(struct platform_device *pdev) struct > > regmap *regmap; struct regulator_config config = { }; > > struct regulator_init_data *init_data; > > + const struct msm_vbus_desc *quirks; > > 'quirks' is one way to put it ;) I'd call it 'desc' or 'data' but it's > totally a potayto/potahto discussion > Is there a reasonable name for that? I suspect that later chips may add more to the structure. I am happy to change it as there is at least one more revision for this series. > > int ret; > > u32 base; > > > > @@ -68,6 +87,12 @@ static int qcom_usb_vbus_regulator_probe(struct > > platform_device *pdev) if (!init_data) > > return -ENOMEM; > > > > + quirks = of_device_get_match_data(dev); > > + if (!quirks) > > + return -ENODEV; > > + > > + qcom_usb_vbus_rdesc.curr_table = quirks->curr_table; > > + qcom_usb_vbus_rdesc.n_current_limits = > > quirks->n_current_limits; qcom_usb_vbus_rdesc.enable_reg = base + > > CMD_OTG; qcom_usb_vbus_rdesc.enable_mask = OTG_EN; > > qcom_usb_vbus_rdesc.csel_reg = base + > > OTG_CURRENT_LIMIT_CFG; @@ -80,18 +105,21 @@ static int > > qcom_usb_vbus_regulator_probe(struct platform_device *pdev) rdev = > > devm_regulator_register(dev, &qcom_usb_vbus_rdesc, &config); if > > (IS_ERR(rdev)) { ret = PTR_ERR(rdev); > > - dev_err(dev, "not able to register vbus reg %d\n", > > ret); > > + dev_err(dev, "Failed to register vbus reg %d\n", > > ret); return ret; > > } > > > > /* Disable HW logic for VBUS enable */ > > regmap_update_bits(regmap, base + OTG_CFG, OTG_EN_SRC_CFG, > > 0); > > + dev_dbg(dev, "Registered QCOM VBUS regulator\n"); > > Not sure how useful this is given the previous call creates a sysfs > entry on success, but sure > > Konrad I like having a "I'm here" message so I can see when something is loaded and to know where in the boot log it happened. Happy to remove it if that is the standard. James
On Wed, 12 Feb 2025 15:29:54 +0000 Caleb Connolly <caleb.connolly@linaro.org> wrote: Hi Caleb, > Hi James, > > On 2/12/25 01:07, James A. MacInnes wrote: > > This patch extends the Qualcomm USB VBUS regulator driver to support > > PMI8998 PMIC alongside the existing support for PM8150B. > > Thanks for the patch! Happy to try and contribute. I know that the working Type-C port is going to be a misery after the relative simplicity of pushing the VBUS upstream. > > > > Key changes: > > - Added current limit tables specific to PMI8998. > > I also played around with vbus on PMI8998 before for type-c support > (unfortunately didn't make it's way to the lists yet...) and I needed > some additional changes for this to work correctly. I found that it > was possible for the overcurrent protection to be hit if the type-c > port manager allowed the peripheral to pull current too early, and > it's necessary to allow 2.5ms enable time. > > PM8150b doesn't have these limitations (and supports the instant > power role switch feature that's part of the type-c PD spec, allowing > the power role to be switched without either side losing power e.g. > when you unplug the power supply from a dock), hence it's only > necessary for PMI8998. > > I would suggest implementing a proper .is_enabled op to poll the > status register for OTG_STATE_ENABLED and configuring > qcom_usb_vbus_rdesc.enable_time = 250000; > > Kind regards, > Technical question for you in regards to the VBUS overcurrent and timing for the PMI8998. I would like to try and reproduce what you have seen as my system hasn't had switching issues, but then again the TCPM system may be covering the exact bug you are mentioning. I also searched for some definite bit in the 4.9 Android driver and was left wanting. As of yet, I have not had issues with the overcurrent protecction. I will be all too happy to migrate to the PM8150B and its associated SoCs and leave the 845 platform to history. Thank you for your feedback and I look forward to narrowing down this issue. Best wishes,
Hi James, On 2/12/25 16:56, James A. MacInnes wrote: > On Wed, 12 Feb 2025 15:29:54 +0000 > Caleb Connolly <caleb.connolly@linaro.org> wrote: > > > Hi Caleb, > >> Hi James, >> >> On 2/12/25 01:07, James A. MacInnes wrote: >>> This patch extends the Qualcomm USB VBUS regulator driver to support >>> PMI8998 PMIC alongside the existing support for PM8150B. >> >> Thanks for the patch! > > Happy to try and contribute. I know that the working Type-C port is > going to be a misery after the relative simplicity of pushing the VBUS > upstream. Yeah, it's hard to get used to the process... I'm happy to hear you're trying to get type-c working on this platform though! This will make a bunch of folks very happy if it finally lands, folks have been doing all sorts of workarounds for this over on https://wiki.postmarketos.org/wiki/OnePlus_6_(oneplus-enchilada)#OTG_doesn't_work >>> >>> Key changes: >>> - Added current limit tables specific to PMI8998. >> >> I also played around with vbus on PMI8998 before for type-c support >> (unfortunately didn't make it's way to the lists yet...) and I needed >> some additional changes for this to work correctly. I found that it >> was possible for the overcurrent protection to be hit if the type-c >> port manager allowed the peripheral to pull current too early, and >> it's necessary to allow 2.5ms enable time. >> >> PM8150b doesn't have these limitations (and supports the instant >> power role switch feature that's part of the type-c PD spec, allowing >> the power role to be switched without either side losing power e.g. >> when you unplug the power supply from a dock), hence it's only >> necessary for PMI8998. >> >> I would suggest implementing a proper .is_enabled op to poll the >> status register for OTG_STATE_ENABLED and configuring >> qcom_usb_vbus_rdesc.enable_time = 250000; >> >> Kind regards, >> > > Technical question for you in regards to the VBUS overcurrent and > timing for the PMI8998. I would like to try and reproduce what you have > seen as my system hasn't had switching issues, but then again the TCPM > system may be covering the exact bug you are mentioning. I also > searched for some definite bit in the 4.9 Android driver and was left > wanting. As of yet, I have not had issues with the overcurrent > protecction. I guess there could be differences in our implementations, there is a delay after enabling the regulator for pm8150b type-c iirc I never got around to chasing some of the remaining issues and sending this upstream, but maybe my patches will be useful for you: https://git.codelinaro.org/caleb_connolly/kernel/-/commits/b4/pmi8998-typec/?ref_type=heads I spent many many hours pouring over the smb2 driver downstream, so feel free to reach out if you have some specific questions. > > I will be all too happy to migrate to the PM8150B and its associated > SoCs and leave the 845 platform to history. Well I for one am always happy to see SDM845 getting attention, it has a special place in my heart :> And still gets love over here, even if not nearly enough of these patches have made it upstream: https://gitlab.com/sdm845-mainline/linux/-/commits/sdm845/6.13-release?ref_type=heads Kind regards, > > Thank you for your feedback and I look forward to narrowing down this > issue. > > Best wishes,
On Wed, 12 Feb 2025 16:09:01 +0000 Caleb Connolly <caleb.connolly@linaro.org> wrote: > On 2/12/25 15:37, Mark Brown wrote: > > On Wed, Feb 12, 2025 at 03:29:54PM +0000, Caleb Connolly wrote: > > > >> I would suggest implementing a proper .is_enabled op to poll the > >> status register for OTG_STATE_ENABLED and configuring > > > > No, that would be buggy. Implement a get_status() operation if the > > device can report status. is_enabled() should report what the > > driver asked for. > > Ahh yep, that's right. it should implement .get_status() (as per the > polling code in _regulator_do_enable()). > I am happy to implement the proper get_status() operation, but the other half of this, the type-c driver (that is functional on the 845), is managing the status portion. With my testing so far, I see the regulator resets the USB hub when I remove power and then supplies from its own battery. Is this the expected operation? As of yet, I am not seeing any failures and the original Android driver lacked the knowledge of the output is status. I can dive back into the original driver and the documentation to verify. Any other thoughts? Thank you,
diff --git a/drivers/regulator/qcom_usb_vbus-regulator.c b/drivers/regulator/qcom_usb_vbus-regulator.c index cd94ed67621f..804dd1a9e057 100644 --- a/drivers/regulator/qcom_usb_vbus-regulator.c +++ b/drivers/regulator/qcom_usb_vbus-regulator.c @@ -20,10 +20,30 @@ #define OTG_CFG 0x53 #define OTG_EN_SRC_CFG BIT(1) -static const unsigned int curr_table[] = { +struct msm_vbus_desc { + const unsigned int *curr_table; + unsigned int n_current_limits; +}; + +static const unsigned int curr_table_pm8150b[] = { 500000, 1000000, 1500000, 2000000, 2500000, 3000000, }; +static const unsigned int curr_table_pmi8998[] = { + 250000, 500000, 750000, 1000000, + 1250000, 1500000, 1750000, 2000000, +}; + +static const struct msm_vbus_desc msm_vbus_desc_pm8150b = { + .curr_table = curr_table_pm8150b, + .n_current_limits = ARRAY_SIZE(curr_table_pm8150b), +}; + +static const struct msm_vbus_desc msm_vbus_desc_pmi8998 = { + .curr_table = curr_table_pmi8998, + .n_current_limits = ARRAY_SIZE(curr_table_pmi8998), +}; + static const struct regulator_ops qcom_usb_vbus_reg_ops = { .enable = regulator_enable_regmap, .disable = regulator_disable_regmap, @@ -37,8 +57,6 @@ static struct regulator_desc qcom_usb_vbus_rdesc = { .ops = &qcom_usb_vbus_reg_ops, .owner = THIS_MODULE, .type = REGULATOR_VOLTAGE, - .curr_table = curr_table, - .n_current_limits = ARRAY_SIZE(curr_table), }; static int qcom_usb_vbus_regulator_probe(struct platform_device *pdev) @@ -48,6 +66,7 @@ static int qcom_usb_vbus_regulator_probe(struct platform_device *pdev) struct regmap *regmap; struct regulator_config config = { }; struct regulator_init_data *init_data; + const struct msm_vbus_desc *quirks; int ret; u32 base; @@ -68,6 +87,12 @@ static int qcom_usb_vbus_regulator_probe(struct platform_device *pdev) if (!init_data) return -ENOMEM; + quirks = of_device_get_match_data(dev); + if (!quirks) + return -ENODEV; + + qcom_usb_vbus_rdesc.curr_table = quirks->curr_table; + qcom_usb_vbus_rdesc.n_current_limits = quirks->n_current_limits; qcom_usb_vbus_rdesc.enable_reg = base + CMD_OTG; qcom_usb_vbus_rdesc.enable_mask = OTG_EN; qcom_usb_vbus_rdesc.csel_reg = base + OTG_CURRENT_LIMIT_CFG; @@ -80,18 +105,21 @@ static int qcom_usb_vbus_regulator_probe(struct platform_device *pdev) rdev = devm_regulator_register(dev, &qcom_usb_vbus_rdesc, &config); if (IS_ERR(rdev)) { ret = PTR_ERR(rdev); - dev_err(dev, "not able to register vbus reg %d\n", ret); + dev_err(dev, "Failed to register vbus reg %d\n", ret); return ret; } /* Disable HW logic for VBUS enable */ regmap_update_bits(regmap, base + OTG_CFG, OTG_EN_SRC_CFG, 0); + dev_dbg(dev, "Registered QCOM VBUS regulator\n"); + return 0; } static const struct of_device_id qcom_usb_vbus_regulator_match[] = { - { .compatible = "qcom,pm8150b-vbus-reg" }, + { .compatible = "qcom,pm8150b-vbus-reg", .data = &msm_vbus_desc_pm8150b }, + { .compatible = "qcom,pmi8998-vbus-reg", .data = &msm_vbus_desc_pmi8998 }, { } }; MODULE_DEVICE_TABLE(of, qcom_usb_vbus_regulator_match);
This patch extends the Qualcomm USB VBUS regulator driver to support PMI8998 PMIC alongside the existing support for PM8150B. Key changes: - Added current limit tables specific to PMI8998. - Dynamically configure the VBUS regulator based on the PMIC type. - Updated debug messages to reflect successful initialization for supported PMICs. - Changed registration log message These changes ensure proper VBUS current limit configuration and compatibility across multiple Qualcomm PMICs. Signed-off-by: James A. MacInnes <james.a.macinnes@gmail.com> --- drivers/regulator/qcom_usb_vbus-regulator.c | 38 ++++++++++++++++++--- 1 file changed, 33 insertions(+), 5 deletions(-)