Commit 3b1bbfb5 authored by Chris Morgan's avatar Chris Morgan Committed by Lee Jones
Browse files

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: default avatarChris Morgan <macromorgan@hotmail.com>
Link: https://lore.kernel.org/r/20250904160530.66178-3-macroalpha82@gmail.com


Signed-off-by: default avatarLee Jones <lee@kernel.org>
parent 76bc2203
Loading
Loading
Loading
Loading
+11 −0
Original line number Diff line number Diff line
@@ -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
+1 −0
Original line number Diff line number Diff line
@@ -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

drivers/mfd/bq257xx.c

0 → 100644
+99 −0
Original line number Diff line number Diff line
// 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");
+104 −0
Original line number Diff line number Diff line
/* 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;
};