]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
mfd: bq257xx: Add support for BQ25703A core driver
authorChris Morgan <macromorgan@hotmail.com>
Thu, 4 Sep 2025 16:05:27 +0000 (11:05 -0500)
committerLee Jones <lee@kernel.org>
Thu, 11 Sep 2025 14:54:43 +0000 (15:54 +0100)
The Texas Instruments BQ25703A is an integrated charger manager and
boost converter.

The MFD driver initializes the device for the regulator driver
and power supply driver.

Signed-off-by: Chris Morgan <macromorgan@hotmail.com>
Link: https://lore.kernel.org/r/20250904160530.66178-3-macroalpha82@gmail.com
Signed-off-by: Lee Jones <lee@kernel.org>
drivers/mfd/Kconfig
drivers/mfd/Makefile
drivers/mfd/bq257xx.c [new file with mode: 0644]
include/linux/mfd/bq257xx.h [new file with mode: 0644]

index 425c5fba6cb1e7848dcea05bd77c729a71d48e2c..768417c973397e41f550ac94ac64eca7eeb2d4ee 100644 (file)
@@ -1641,6 +1641,17 @@ config MFD_TI_LMU
          LM36274.  It consists of backlight, LED and regulator driver.
          It provides consistent device controls for lighting functions.
 
+config MFD_BQ257XX
+       tristate "TI BQ257XX Buck/Boost Charge Controller"
+       depends on I2C
+       select MFD_CORE
+       select REGMAP_I2C
+       help
+         Support Texas Instruments BQ25703 Buck/Boost converter with
+         charge controller. It consists of regulators that provide
+         system voltage and OTG voltage, and a charger manager for
+         batteries containing one or more cells.
+
 config MFD_OMAP_USB_HOST
        bool "TI OMAP USBHS core and TLL driver"
        depends on USB_EHCI_HCD_OMAP || USB_OHCI_HCD_OMAP3
index f7bdedd5a66d16bf8ccee0da1236a441e6f085b0..3d700374a42d5842e91496d56a5c95f1c71fc7d2 100644 (file)
@@ -13,6 +13,7 @@ obj-$(CONFIG_MFD_SM501)               += sm501.o
 obj-$(CONFIG_ARCH_BCM2835)     += bcm2835-pm.o
 obj-$(CONFIG_MFD_BCM590XX)     += bcm590xx.o
 obj-$(CONFIG_MFD_BD9571MWV)    += bd9571mwv.o
+obj-$(CONFIG_MFD_BQ257XX)      += bq257xx.o
 obj-$(CONFIG_MFD_CGBC)         += cgbc-core.o
 obj-$(CONFIG_MFD_CROS_EC_DEV)  += cros_ec_dev.o
 obj-$(CONFIG_MFD_CS42L43)      += cs42l43.o
diff --git a/drivers/mfd/bq257xx.c b/drivers/mfd/bq257xx.c
new file mode 100644 (file)
index 0000000..e9d49da
--- /dev/null
@@ -0,0 +1,99 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * BQ257XX Core Driver
+ * Copyright (C) 2025 Chris Morgan <macromorgan@hotmail.com>
+ */
+
+#include <linux/device.h>
+#include <linux/i2c.h>
+#include <linux/mfd/bq257xx.h>
+#include <linux/mfd/core.h>
+#include <linux/regmap.h>
+
+static const struct regmap_range bq25703_readonly_reg_ranges[] = {
+       regmap_reg_range(BQ25703_CHARGER_STATUS, BQ25703_MANUFACT_DEV_ID),
+};
+
+static const struct regmap_access_table bq25703_writeable_regs = {
+       .no_ranges = bq25703_readonly_reg_ranges,
+       .n_no_ranges = ARRAY_SIZE(bq25703_readonly_reg_ranges),
+};
+
+static const struct regmap_range bq25703_volatile_reg_ranges[] = {
+       regmap_reg_range(BQ25703_CHARGE_OPTION_0, BQ25703_IIN_HOST),
+       regmap_reg_range(BQ25703_CHARGER_STATUS, BQ25703_ADC_OPTION),
+};
+
+static const struct regmap_access_table bq25703_volatile_regs = {
+       .yes_ranges = bq25703_volatile_reg_ranges,
+       .n_yes_ranges = ARRAY_SIZE(bq25703_volatile_reg_ranges),
+};
+
+static const struct regmap_config bq25703_regmap_config = {
+       .reg_bits = 8,
+       .val_bits = 16,
+       .max_register = BQ25703_ADC_OPTION,
+       .cache_type = REGCACHE_MAPLE,
+       .wr_table = &bq25703_writeable_regs,
+       .volatile_table = &bq25703_volatile_regs,
+       .val_format_endian = REGMAP_ENDIAN_LITTLE,
+};
+
+static const struct mfd_cell cells[] = {
+       MFD_CELL_NAME("bq257xx-regulator"),
+       MFD_CELL_NAME("bq257xx-charger"),
+};
+
+static int bq257xx_probe(struct i2c_client *client)
+{
+       struct bq257xx_device *ddata;
+       int ret;
+
+       ddata = devm_kzalloc(&client->dev, sizeof(*ddata), GFP_KERNEL);
+       if (!ddata)
+               return -ENOMEM;
+
+       ddata->client = client;
+
+       ddata->regmap = devm_regmap_init_i2c(client, &bq25703_regmap_config);
+       if (IS_ERR(ddata->regmap)) {
+               return dev_err_probe(&client->dev, PTR_ERR(ddata->regmap),
+                                    "Failed to allocate register map\n");
+       }
+
+       i2c_set_clientdata(client, ddata);
+
+       ret = devm_mfd_add_devices(&client->dev, PLATFORM_DEVID_AUTO,
+                                  cells, ARRAY_SIZE(cells), NULL, 0, NULL);
+       if (ret)
+               return dev_err_probe(&client->dev, ret,
+                                    "Failed to register child devices\n");
+
+       return ret;
+}
+
+static const struct i2c_device_id bq257xx_i2c_ids[] = {
+       { "bq25703a" },
+       {}
+};
+MODULE_DEVICE_TABLE(i2c, bq257xx_i2c_ids);
+
+static const struct of_device_id bq257xx_of_match[] = {
+       { .compatible = "ti,bq25703a" },
+       {}
+};
+MODULE_DEVICE_TABLE(of, bq257xx_of_match);
+
+static struct i2c_driver bq257xx_driver = {
+       .driver = {
+               .name = "bq257xx",
+               .of_match_table = bq257xx_of_match,
+       },
+       .probe = bq257xx_probe,
+       .id_table = bq257xx_i2c_ids,
+};
+module_i2c_driver(bq257xx_driver);
+
+MODULE_DESCRIPTION("bq257xx buck/boost/charger driver");
+MODULE_AUTHOR("Chris Morgan <macromorgan@hotmail.com>");
+MODULE_LICENSE("GPL");
diff --git a/include/linux/mfd/bq257xx.h b/include/linux/mfd/bq257xx.h
new file mode 100644 (file)
index 0000000..1d6ddc7
--- /dev/null
@@ -0,0 +1,104 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Register definitions for TI BQ257XX
+ * Copyright (C) 2020 Texas Instruments Incorporated - http://www.ti.com/
+ */
+
+#define BQ25703_CHARGE_OPTION_0                        0x00
+#define BQ25703_CHARGE_CURRENT                 0x02
+#define BQ25703_MAX_CHARGE_VOLT                        0x04
+#define BQ25703_OTG_VOLT                       0x06
+#define BQ25703_OTG_CURRENT                    0x08
+#define BQ25703_INPUT_VOLTAGE                  0x0a
+#define BQ25703_MIN_VSYS                       0x0c
+#define BQ25703_IIN_HOST                       0x0e
+#define BQ25703_CHARGER_STATUS                 0x20
+#define BQ25703_PROCHOT_STATUS                 0x22
+#define BQ25703_IIN_DPM                                0x24
+#define BQ25703_ADCIBAT_CHG                    0x28
+#define BQ25703_ADCIINCMPIN                    0x2a
+#define BQ25703_ADCVSYSVBAT                    0x2c
+#define BQ25703_MANUFACT_DEV_ID                        0x2e
+#define BQ25703_CHARGE_OPTION_1                        0x30
+#define BQ25703_CHARGE_OPTION_2                        0x32
+#define BQ25703_CHARGE_OPTION_3                        0x34
+#define BQ25703_ADC_OPTION                     0x3a
+
+#define BQ25703_EN_LWPWR                       BIT(15)
+#define BQ25703_WDTMR_ADJ_MASK                 GENMASK(14, 13)
+#define BQ25703_WDTMR_DISABLE                  0
+#define BQ25703_WDTMR_5_SEC                    1
+#define BQ25703_WDTMR_88_SEC                   2
+#define BQ25703_WDTMR_175_SEC                  3
+
+#define BQ25703_ICHG_MASK                      GENMASK(12, 6)
+#define BQ25703_ICHG_STEP_UA                   64000
+#define BQ25703_ICHG_MIN_UA                    64000
+#define BQ25703_ICHG_MAX_UA                    8128000
+
+#define BQ25703_MAX_CHARGE_VOLT_MASK           GENMASK(15, 4)
+#define BQ25703_VBATREG_STEP_UV                        16000
+#define BQ25703_VBATREG_MIN_UV                 1024000
+#define BQ25703_VBATREG_MAX_UV                 19200000
+
+#define BQ25703_OTG_VOLT_MASK                  GENMASK(13, 6)
+#define BQ25703_OTG_VOLT_STEP_UV               64000
+#define BQ25703_OTG_VOLT_MIN_UV                        4480000
+#define BQ25703_OTG_VOLT_MAX_UV                        20800000
+#define BQ25703_OTG_VOLT_NUM_VOLT              256
+
+#define BQ25703_OTG_CUR_MASK                   GENMASK(14, 8)
+#define BQ25703_OTG_CUR_STEP_UA                        50000
+#define BQ25703_OTG_CUR_MAX_UA                 6350000
+
+#define BQ25703_MINVSYS_MASK                   GENMASK(13, 8)
+#define BQ25703_MINVSYS_STEP_UV                        256000
+#define BQ25703_MINVSYS_MIN_UV                 1024000
+#define BQ25703_MINVSYS_MAX_UV                 16128000
+
+#define BQ25703_STS_AC_STAT                    BIT(15)
+#define BQ25703_STS_IN_FCHRG                   BIT(10)
+#define BQ25703_STS_IN_PCHRG                   BIT(9)
+#define BQ25703_STS_FAULT_ACOV                 BIT(7)
+#define BQ25703_STS_FAULT_BATOC                        BIT(6)
+#define BQ25703_STS_FAULT_ACOC                 BIT(5)
+
+#define BQ25703_IINDPM_MASK                    GENMASK(14, 8)
+#define BQ25703_IINDPM_STEP_UA                 50000
+#define BQ25703_IINDPM_MIN_UA                  50000
+#define BQ25703_IINDPM_MAX_UA                  6400000
+#define BQ25703_IINDPM_DEFAULT_UA              3300000
+#define BQ25703_IINDPM_OFFSET_UA               50000
+
+#define BQ25703_ADCIBAT_DISCHG_MASK            GENMASK(6, 0)
+#define BQ25703_ADCIBAT_CHG_MASK               GENMASK(14, 8)
+#define BQ25703_ADCIBAT_CHG_STEP_UA            64000
+#define BQ25703_ADCIBAT_DIS_STEP_UA            256000
+
+#define BQ25703_ADCIIN                         GENMASK(15, 8)
+#define BQ25703_ADCIINCMPIN_STEP               50000
+
+#define BQ25703_ADCVSYS_MASK                   GENMASK(15, 8)
+#define BQ25703_ADCVBAT_MASK                   GENMASK(7, 0)
+#define BQ25703_ADCVSYSVBAT_OFFSET_UV          2880000
+#define BQ25703_ADCVSYSVBAT_STEP               64000
+
+#define BQ25703_ADC_CH_MASK                    GENMASK(7, 0)
+#define BQ25703_ADC_CONV_EN                    BIT(15)
+#define BQ25703_ADC_START                      BIT(14)
+#define BQ25703_ADC_FULL_SCALE                 BIT(13)
+#define BQ25703_ADC_CMPIN_EN                   BIT(7)
+#define BQ25703_ADC_VBUS_EN                    BIT(6)
+#define BQ25703_ADC_PSYS_EN                    BIT(5)
+#define BQ25703_ADC_IIN_EN                     BIT(4)
+#define BQ25703_ADC_IDCHG_EN                   BIT(3)
+#define BQ25703_ADC_ICHG_EN                    BIT(2)
+#define BQ25703_ADC_VSYS_EN                    BIT(1)
+#define BQ25703_ADC_VBAT_EN                    BIT(0)
+
+#define BQ25703_EN_OTG_MASK                    BIT(12)
+
+struct bq257xx_device {
+       struct i2c_client *client;
+       struct regmap *regmap;
+};