Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

mfd: bq257xx: Add support for BQ25703A core driver

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>

authored by

Chris Morgan and committed by
Lee Jones
3b1bbfb5 76bc2203

+215
+11
drivers/mfd/Kconfig
··· 1641 1641 LM36274. It consists of backlight, LED and regulator driver. 1642 1642 It provides consistent device controls for lighting functions. 1643 1643 1644 + config MFD_BQ257XX 1645 + tristate "TI BQ257XX Buck/Boost Charge Controller" 1646 + depends on I2C 1647 + select MFD_CORE 1648 + select REGMAP_I2C 1649 + help 1650 + Support Texas Instruments BQ25703 Buck/Boost converter with 1651 + charge controller. It consists of regulators that provide 1652 + system voltage and OTG voltage, and a charger manager for 1653 + batteries containing one or more cells. 1654 + 1644 1655 config MFD_OMAP_USB_HOST 1645 1656 bool "TI OMAP USBHS core and TLL driver" 1646 1657 depends on USB_EHCI_HCD_OMAP || USB_OHCI_HCD_OMAP3
+1
drivers/mfd/Makefile
··· 13 13 obj-$(CONFIG_ARCH_BCM2835) += bcm2835-pm.o 14 14 obj-$(CONFIG_MFD_BCM590XX) += bcm590xx.o 15 15 obj-$(CONFIG_MFD_BD9571MWV) += bd9571mwv.o 16 + obj-$(CONFIG_MFD_BQ257XX) += bq257xx.o 16 17 obj-$(CONFIG_MFD_CGBC) += cgbc-core.o 17 18 obj-$(CONFIG_MFD_CROS_EC_DEV) += cros_ec_dev.o 18 19 obj-$(CONFIG_MFD_CS42L43) += cs42l43.o
+99
drivers/mfd/bq257xx.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * BQ257XX Core Driver 4 + * Copyright (C) 2025 Chris Morgan <macromorgan@hotmail.com> 5 + */ 6 + 7 + #include <linux/device.h> 8 + #include <linux/i2c.h> 9 + #include <linux/mfd/bq257xx.h> 10 + #include <linux/mfd/core.h> 11 + #include <linux/regmap.h> 12 + 13 + static const struct regmap_range bq25703_readonly_reg_ranges[] = { 14 + regmap_reg_range(BQ25703_CHARGER_STATUS, BQ25703_MANUFACT_DEV_ID), 15 + }; 16 + 17 + static const struct regmap_access_table bq25703_writeable_regs = { 18 + .no_ranges = bq25703_readonly_reg_ranges, 19 + .n_no_ranges = ARRAY_SIZE(bq25703_readonly_reg_ranges), 20 + }; 21 + 22 + static const struct regmap_range bq25703_volatile_reg_ranges[] = { 23 + regmap_reg_range(BQ25703_CHARGE_OPTION_0, BQ25703_IIN_HOST), 24 + regmap_reg_range(BQ25703_CHARGER_STATUS, BQ25703_ADC_OPTION), 25 + }; 26 + 27 + static const struct regmap_access_table bq25703_volatile_regs = { 28 + .yes_ranges = bq25703_volatile_reg_ranges, 29 + .n_yes_ranges = ARRAY_SIZE(bq25703_volatile_reg_ranges), 30 + }; 31 + 32 + static const struct regmap_config bq25703_regmap_config = { 33 + .reg_bits = 8, 34 + .val_bits = 16, 35 + .max_register = BQ25703_ADC_OPTION, 36 + .cache_type = REGCACHE_MAPLE, 37 + .wr_table = &bq25703_writeable_regs, 38 + .volatile_table = &bq25703_volatile_regs, 39 + .val_format_endian = REGMAP_ENDIAN_LITTLE, 40 + }; 41 + 42 + static const struct mfd_cell cells[] = { 43 + MFD_CELL_NAME("bq257xx-regulator"), 44 + MFD_CELL_NAME("bq257xx-charger"), 45 + }; 46 + 47 + static int bq257xx_probe(struct i2c_client *client) 48 + { 49 + struct bq257xx_device *ddata; 50 + int ret; 51 + 52 + ddata = devm_kzalloc(&client->dev, sizeof(*ddata), GFP_KERNEL); 53 + if (!ddata) 54 + return -ENOMEM; 55 + 56 + ddata->client = client; 57 + 58 + ddata->regmap = devm_regmap_init_i2c(client, &bq25703_regmap_config); 59 + if (IS_ERR(ddata->regmap)) { 60 + return dev_err_probe(&client->dev, PTR_ERR(ddata->regmap), 61 + "Failed to allocate register map\n"); 62 + } 63 + 64 + i2c_set_clientdata(client, ddata); 65 + 66 + ret = devm_mfd_add_devices(&client->dev, PLATFORM_DEVID_AUTO, 67 + cells, ARRAY_SIZE(cells), NULL, 0, NULL); 68 + if (ret) 69 + return dev_err_probe(&client->dev, ret, 70 + "Failed to register child devices\n"); 71 + 72 + return ret; 73 + } 74 + 75 + static const struct i2c_device_id bq257xx_i2c_ids[] = { 76 + { "bq25703a" }, 77 + {} 78 + }; 79 + MODULE_DEVICE_TABLE(i2c, bq257xx_i2c_ids); 80 + 81 + static const struct of_device_id bq257xx_of_match[] = { 82 + { .compatible = "ti,bq25703a" }, 83 + {} 84 + }; 85 + MODULE_DEVICE_TABLE(of, bq257xx_of_match); 86 + 87 + static struct i2c_driver bq257xx_driver = { 88 + .driver = { 89 + .name = "bq257xx", 90 + .of_match_table = bq257xx_of_match, 91 + }, 92 + .probe = bq257xx_probe, 93 + .id_table = bq257xx_i2c_ids, 94 + }; 95 + module_i2c_driver(bq257xx_driver); 96 + 97 + MODULE_DESCRIPTION("bq257xx buck/boost/charger driver"); 98 + MODULE_AUTHOR("Chris Morgan <macromorgan@hotmail.com>"); 99 + MODULE_LICENSE("GPL");
+104
include/linux/mfd/bq257xx.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + /* 3 + * Register definitions for TI BQ257XX 4 + * Copyright (C) 2020 Texas Instruments Incorporated - http://www.ti.com/ 5 + */ 6 + 7 + #define BQ25703_CHARGE_OPTION_0 0x00 8 + #define BQ25703_CHARGE_CURRENT 0x02 9 + #define BQ25703_MAX_CHARGE_VOLT 0x04 10 + #define BQ25703_OTG_VOLT 0x06 11 + #define BQ25703_OTG_CURRENT 0x08 12 + #define BQ25703_INPUT_VOLTAGE 0x0a 13 + #define BQ25703_MIN_VSYS 0x0c 14 + #define BQ25703_IIN_HOST 0x0e 15 + #define BQ25703_CHARGER_STATUS 0x20 16 + #define BQ25703_PROCHOT_STATUS 0x22 17 + #define BQ25703_IIN_DPM 0x24 18 + #define BQ25703_ADCIBAT_CHG 0x28 19 + #define BQ25703_ADCIINCMPIN 0x2a 20 + #define BQ25703_ADCVSYSVBAT 0x2c 21 + #define BQ25703_MANUFACT_DEV_ID 0x2e 22 + #define BQ25703_CHARGE_OPTION_1 0x30 23 + #define BQ25703_CHARGE_OPTION_2 0x32 24 + #define BQ25703_CHARGE_OPTION_3 0x34 25 + #define BQ25703_ADC_OPTION 0x3a 26 + 27 + #define BQ25703_EN_LWPWR BIT(15) 28 + #define BQ25703_WDTMR_ADJ_MASK GENMASK(14, 13) 29 + #define BQ25703_WDTMR_DISABLE 0 30 + #define BQ25703_WDTMR_5_SEC 1 31 + #define BQ25703_WDTMR_88_SEC 2 32 + #define BQ25703_WDTMR_175_SEC 3 33 + 34 + #define BQ25703_ICHG_MASK GENMASK(12, 6) 35 + #define BQ25703_ICHG_STEP_UA 64000 36 + #define BQ25703_ICHG_MIN_UA 64000 37 + #define BQ25703_ICHG_MAX_UA 8128000 38 + 39 + #define BQ25703_MAX_CHARGE_VOLT_MASK GENMASK(15, 4) 40 + #define BQ25703_VBATREG_STEP_UV 16000 41 + #define BQ25703_VBATREG_MIN_UV 1024000 42 + #define BQ25703_VBATREG_MAX_UV 19200000 43 + 44 + #define BQ25703_OTG_VOLT_MASK GENMASK(13, 6) 45 + #define BQ25703_OTG_VOLT_STEP_UV 64000 46 + #define BQ25703_OTG_VOLT_MIN_UV 4480000 47 + #define BQ25703_OTG_VOLT_MAX_UV 20800000 48 + #define BQ25703_OTG_VOLT_NUM_VOLT 256 49 + 50 + #define BQ25703_OTG_CUR_MASK GENMASK(14, 8) 51 + #define BQ25703_OTG_CUR_STEP_UA 50000 52 + #define BQ25703_OTG_CUR_MAX_UA 6350000 53 + 54 + #define BQ25703_MINVSYS_MASK GENMASK(13, 8) 55 + #define BQ25703_MINVSYS_STEP_UV 256000 56 + #define BQ25703_MINVSYS_MIN_UV 1024000 57 + #define BQ25703_MINVSYS_MAX_UV 16128000 58 + 59 + #define BQ25703_STS_AC_STAT BIT(15) 60 + #define BQ25703_STS_IN_FCHRG BIT(10) 61 + #define BQ25703_STS_IN_PCHRG BIT(9) 62 + #define BQ25703_STS_FAULT_ACOV BIT(7) 63 + #define BQ25703_STS_FAULT_BATOC BIT(6) 64 + #define BQ25703_STS_FAULT_ACOC BIT(5) 65 + 66 + #define BQ25703_IINDPM_MASK GENMASK(14, 8) 67 + #define BQ25703_IINDPM_STEP_UA 50000 68 + #define BQ25703_IINDPM_MIN_UA 50000 69 + #define BQ25703_IINDPM_MAX_UA 6400000 70 + #define BQ25703_IINDPM_DEFAULT_UA 3300000 71 + #define BQ25703_IINDPM_OFFSET_UA 50000 72 + 73 + #define BQ25703_ADCIBAT_DISCHG_MASK GENMASK(6, 0) 74 + #define BQ25703_ADCIBAT_CHG_MASK GENMASK(14, 8) 75 + #define BQ25703_ADCIBAT_CHG_STEP_UA 64000 76 + #define BQ25703_ADCIBAT_DIS_STEP_UA 256000 77 + 78 + #define BQ25703_ADCIIN GENMASK(15, 8) 79 + #define BQ25703_ADCIINCMPIN_STEP 50000 80 + 81 + #define BQ25703_ADCVSYS_MASK GENMASK(15, 8) 82 + #define BQ25703_ADCVBAT_MASK GENMASK(7, 0) 83 + #define BQ25703_ADCVSYSVBAT_OFFSET_UV 2880000 84 + #define BQ25703_ADCVSYSVBAT_STEP 64000 85 + 86 + #define BQ25703_ADC_CH_MASK GENMASK(7, 0) 87 + #define BQ25703_ADC_CONV_EN BIT(15) 88 + #define BQ25703_ADC_START BIT(14) 89 + #define BQ25703_ADC_FULL_SCALE BIT(13) 90 + #define BQ25703_ADC_CMPIN_EN BIT(7) 91 + #define BQ25703_ADC_VBUS_EN BIT(6) 92 + #define BQ25703_ADC_PSYS_EN BIT(5) 93 + #define BQ25703_ADC_IIN_EN BIT(4) 94 + #define BQ25703_ADC_IDCHG_EN BIT(3) 95 + #define BQ25703_ADC_ICHG_EN BIT(2) 96 + #define BQ25703_ADC_VSYS_EN BIT(1) 97 + #define BQ25703_ADC_VBAT_EN BIT(0) 98 + 99 + #define BQ25703_EN_OTG_MASK BIT(12) 100 + 101 + struct bq257xx_device { 102 + struct i2c_client *client; 103 + struct regmap *regmap; 104 + };