* [PATCH 1/2] mfd: (tps65086): Read DEVICE ID register 1 from device
@ 2023-08-09 10:14 werneazc
2023-08-09 10:14 ` [PATCH 2/2] regulator: (tps65086): Select dedicated regulator config for chip variant werneazc
2023-08-17 17:02 ` [PATCH 1/2] mfd: (tps65086): Read DEVICE ID register 1 from device Lee Jones
0 siblings, 2 replies; 5+ messages in thread
From: werneazc @ 2023-08-09 10:14 UTC (permalink / raw)
To: lgirdwood, broonie, lee; +Cc: linux-kernel, Andre Werner
From: Andre Werner <andre.werner@systec-electronic.com>
This commit prepares a following commit for the regulator part of the MFD.
The driver should support different device chips that differ in their
register definitions, for instance to control LDOA1 and SWB2.
So it is necessary to use a dedicated regulator description for a
specific device variant. Thus, the content from DEVICEID Register 1 is
used to choose a dedicated configuration between the different device
variants.
Signed-off-by: Andre Werner <andre.werner@systec-electronic.com>
---
drivers/mfd/tps65086.c | 37 ++++++++++++++++++++++++++++++------
include/linux/mfd/tps65086.h | 27 ++++++++++++++++++++------
2 files changed, 52 insertions(+), 12 deletions(-)
diff --git a/drivers/mfd/tps65086.c b/drivers/mfd/tps65086.c
index 6a21000aad4a..38f8572c265e 100644
--- a/drivers/mfd/tps65086.c
+++ b/drivers/mfd/tps65086.c
@@ -64,7 +64,7 @@ MODULE_DEVICE_TABLE(of, tps65086_of_match_table);
static int tps65086_probe(struct i2c_client *client)
{
struct tps65086 *tps;
- unsigned int version;
+ unsigned int version, id;
int ret;
tps = devm_kzalloc(&client->dev, sizeof(*tps), GFP_KERNEL);
@@ -81,16 +81,41 @@ static int tps65086_probe(struct i2c_client *client)
return PTR_ERR(tps->regmap);
}
- ret = regmap_read(tps->regmap, TPS65086_DEVICEID, &version);
+ ret = regmap_read(tps->regmap, TPS65086_DEVICEID1, &id);
if (ret) {
- dev_err(tps->dev, "Failed to read revision register\n");
+ dev_err(tps->dev, "Failed to read revision register 1\n");
+ return ret;
+ }
+
+ /* Store device ID to load regulator configuration that fit to IC variant */
+ switch (id) {
+ case TPS6508640_ID:
+ tps->chip_id = TPS6508640;
+ break;
+ case TPS65086401_ID:
+ tps->chip_id = TPS65086401;
+ break;
+ case TPS6508641_ID:
+ tps->chip_id = TPS6508641;
+ break;
+ case TPS65086470_ID:
+ tps->chip_id = TPS65086470;
+ break;
+ default:
+ dev_err(tps->dev, "Unknown device ID. Cannot determine regulator config.\n");
+ return -ENODEV;
+ }
+
+ ret = regmap_read(tps->regmap, TPS65086_DEVICEID2, &version);
+ if (ret) {
+ dev_err(tps->dev, "Failed to read revision register 2\n");
return ret;
}
dev_info(tps->dev, "Device: TPS65086%01lX, OTP: %c, Rev: %ld\n",
- (version & TPS65086_DEVICEID_PART_MASK),
- (char)((version & TPS65086_DEVICEID_OTP_MASK) >> 4) + 'A',
- (version & TPS65086_DEVICEID_REV_MASK) >> 6);
+ (version & TPS65086_DEVICEID2_PART_MASK),
+ (char)((version & TPS65086_DEVICEID2_OTP_MASK) >> 4) + 'A',
+ (version & TPS65086_DEVICEID2_REV_MASK) >> 6);
if (tps->irq > 0) {
ret = regmap_add_irq_chip(tps->regmap, tps->irq, IRQF_ONESHOT, 0,
diff --git a/include/linux/mfd/tps65086.h b/include/linux/mfd/tps65086.h
index 16f87cccc003..88df344b38df 100644
--- a/include/linux/mfd/tps65086.h
+++ b/include/linux/mfd/tps65086.h
@@ -13,8 +13,9 @@
#include <linux/regmap.h>
/* List of registers for TPS65086 */
-#define TPS65086_DEVICEID 0x01
-#define TPS65086_IRQ 0x02
+#define TPS65086_DEVICEID1 0x00
+#define TPS65086_DEVICEID2 0x01
+#define TPS65086_IRQ 0x02
#define TPS65086_IRQ_MASK 0x03
#define TPS65086_PMICSTAT 0x04
#define TPS65086_SHUTDNSRC 0x05
@@ -75,16 +76,29 @@
#define TPS65086_IRQ_SHUTDN_MASK BIT(3)
#define TPS65086_IRQ_FAULT_MASK BIT(7)
-/* DEVICEID Register field definitions */
-#define TPS65086_DEVICEID_PART_MASK GENMASK(3, 0)
-#define TPS65086_DEVICEID_OTP_MASK GENMASK(5, 4)
-#define TPS65086_DEVICEID_REV_MASK GENMASK(7, 6)
+/* DEVICEID1 Register field definitions */
+#define TPS6508640_ID 0x00
+#define TPS65086401_ID 0x01
+#define TPS6508641_ID 0x10
+#define TPS65086470_ID 0x70
+
+/* DEVICEID2 Register field definitions */
+#define TPS65086_DEVICEID2_PART_MASK GENMASK(3, 0)
+#define TPS65086_DEVICEID2_OTP_MASK GENMASK(5, 4)
+#define TPS65086_DEVICEID2_REV_MASK GENMASK(7, 6)
/* VID Masks */
#define BUCK_VID_MASK GENMASK(7, 1)
#define VDOA1_VID_MASK GENMASK(4, 1)
#define VDOA23_VID_MASK GENMASK(3, 0)
+enum tps65086_ids {
+ TPS6508640,
+ TPS65086401,
+ TPS6508641,
+ TPS65086470,
+};
+
/* Define the TPS65086 IRQ numbers */
enum tps65086_irqs {
TPS65086_IRQ_DIETEMP,
@@ -100,6 +114,7 @@ enum tps65086_irqs {
struct tps65086 {
struct device *dev;
struct regmap *regmap;
+ unsigned int chip_id;
/* IRQ Data */
int irq;
--
2.41.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH 2/2] regulator: (tps65086): Select dedicated regulator config for chip variant
2023-08-09 10:14 [PATCH 1/2] mfd: (tps65086): Read DEVICE ID register 1 from device werneazc
@ 2023-08-09 10:14 ` werneazc
2023-08-17 17:02 ` [PATCH 1/2] mfd: (tps65086): Read DEVICE ID register 1 from device Lee Jones
1 sibling, 0 replies; 5+ messages in thread
From: werneazc @ 2023-08-09 10:14 UTC (permalink / raw)
To: lgirdwood, broonie, lee; +Cc: linux-kernel, Andre Werner
From: Andre Werner <andre.werner@systec-electronic.com>
Some configurations differ between chip variants, e,g. the register
to control the on of state of LDOA1 and SWB2. Thus, it is necessary
to choose the correct configuration for a dedicated device.
If the wrong configuration was used, the LDOA1 output that was
disabled by the bootloader was enabled in Kernel again.
Each chip variant gets its dedicated configuration selected by
the chip ID previously collected from MFD probe function.
The VTT enum value (tps65086_regulators) is shifted because not all
chip variants have a separate SWB2 switch. Sometimes they are merged.
So the configuration possibilities differ, thus the regulator
configuration arrays have a different length.
Signed-off-by: Andre Werner <andre.werner@systec-electronic.com>
---
drivers/regulator/tps65086-regulator.c | 163 +++++++++++++++++++++++--
include/linux/mfd/tps65086.h | 3 +
2 files changed, 158 insertions(+), 8 deletions(-)
diff --git a/drivers/regulator/tps65086-regulator.c b/drivers/regulator/tps65086-regulator.c
index 663789198ba5..c4ae7a67dc77 100644
--- a/drivers/regulator/tps65086-regulator.c
+++ b/drivers/regulator/tps65086-regulator.c
@@ -15,7 +15,7 @@
#include <linux/mfd/tps65086.h>
enum tps65086_regulators { BUCK1, BUCK2, BUCK3, BUCK4, BUCK5, BUCK6, LDOA1,
- LDOA2, LDOA3, SWA1, SWB1, SWB2, VTT };
+ LDOA2, LDOA3, VTT, SWA1, SWB1, SWB2 };
#define TPS65086_REGULATOR(_name, _of, _id, _nv, _vr, _vm, _er, _em, _lr, _dr, _dm) \
[_id] = { \
@@ -57,12 +57,24 @@ enum tps65086_regulators { BUCK1, BUCK2, BUCK3, BUCK4, BUCK5, BUCK6, LDOA1,
}, \
}
+
+#define TPS65086_REGULATOR_CONFIG(_chip_id, _config) \
+ [_chip_id] = { \
+ .config = _config, \
+ .num_elems = ARRAY_SIZE(_config), \
+ }
+
struct tps65086_regulator {
struct regulator_desc desc;
unsigned int decay_reg;
unsigned int decay_mask;
};
+struct tps65086_regulator_config {
+ struct tps65086_regulator * const config;
+ const unsigned int num_elems;
+};
+
static const struct linear_range tps65086_10mv_ranges[] = {
REGULATOR_LINEAR_RANGE(0, 0x0, 0x0, 0),
REGULATOR_LINEAR_RANGE(410000, 0x1, 0x7F, 10000),
@@ -114,7 +126,125 @@ static int tps65086_of_parse_cb(struct device_node *dev,
const struct regulator_desc *desc,
struct regulator_config *config);
-static struct tps65086_regulator regulators[] = {
+static struct tps65086_regulator tps6508640_regulator_config[] = {
+ TPS65086_REGULATOR("BUCK1", "buck1", BUCK1, 0x80, TPS65086_BUCK1CTRL,
+ BUCK_VID_MASK, TPS65086_BUCK123CTRL, BIT(0),
+ tps65086_10mv_ranges, TPS65086_BUCK1CTRL,
+ BIT(0)),
+ TPS65086_REGULATOR("BUCK2", "buck2", BUCK2, 0x80, TPS65086_BUCK2CTRL,
+ BUCK_VID_MASK, TPS65086_BUCK123CTRL, BIT(1),
+ tps65086_10mv_ranges, TPS65086_BUCK2CTRL,
+ BIT(0)),
+ TPS65086_REGULATOR("BUCK3", "buck3", BUCK3, 0x80, TPS65086_BUCK3VID,
+ BUCK_VID_MASK, TPS65086_BUCK123CTRL, BIT(2),
+ tps65086_10mv_ranges, TPS65086_BUCK3DECAY,
+ BIT(0)),
+ TPS65086_REGULATOR("BUCK4", "buck4", BUCK4, 0x80, TPS65086_BUCK4VID,
+ BUCK_VID_MASK, TPS65086_BUCK4CTRL, BIT(0),
+ tps65086_10mv_ranges, TPS65086_BUCK4VID,
+ BIT(0)),
+ TPS65086_REGULATOR("BUCK5", "buck5", BUCK5, 0x80, TPS65086_BUCK5VID,
+ BUCK_VID_MASK, TPS65086_BUCK5CTRL, BIT(0),
+ tps65086_10mv_ranges, TPS65086_BUCK5CTRL,
+ BIT(0)),
+ TPS65086_REGULATOR("BUCK6", "buck6", BUCK6, 0x80, TPS65086_BUCK6VID,
+ BUCK_VID_MASK, TPS65086_BUCK6CTRL, BIT(0),
+ tps65086_10mv_ranges, TPS65086_BUCK6CTRL,
+ BIT(0)),
+ TPS65086_REGULATOR("LDOA1", "ldoa1", LDOA1, 0xF, TPS65086_LDOA1CTRL,
+ VDOA1_VID_MASK, TPS65086_SWVTT_EN, BIT(7),
+ tps65086_ldoa1_ranges, 0, 0),
+ TPS65086_REGULATOR("LDOA2", "ldoa2", LDOA2, 0x10, TPS65086_LDOA2VID,
+ VDOA23_VID_MASK, TPS65086_LDOA2CTRL, BIT(0),
+ tps65086_ldoa23_ranges, 0, 0),
+ TPS65086_REGULATOR("LDOA3", "ldoa3", LDOA3, 0x10, TPS65086_LDOA3VID,
+ VDOA23_VID_MASK, TPS65086_LDOA3CTRL, BIT(0),
+ tps65086_ldoa23_ranges, 0, 0),
+ TPS65086_SWITCH("VTT", "vtt", VTT, TPS65086_SWVTT_EN, BIT(4)),
+ TPS65086_SWITCH("SWA1", "swa1", SWA1, TPS65086_SWVTT_EN, BIT(5)),
+ TPS65086_SWITCH("SWB1", "swb1", SWB1, TPS65086_SWVTT_EN, BIT(6)),
+ TPS65086_SWITCH("SWB2", "swb2", SWB2, TPS65086_LDOA1CTRL, BIT(0)),
+};
+
+static struct tps65086_regulator tps65086401_regulator_config[] = {
+ TPS65086_REGULATOR("BUCK1", "buck1", BUCK1, 0x80, TPS65086_BUCK1CTRL,
+ BUCK_VID_MASK, TPS65086_BUCK123CTRL, BIT(0),
+ tps65086_10mv_ranges, TPS65086_BUCK1CTRL,
+ BIT(0)),
+ TPS65086_REGULATOR("BUCK2", "buck2", BUCK2, 0x80, TPS65086_BUCK2CTRL,
+ BUCK_VID_MASK, TPS65086_BUCK123CTRL, BIT(1),
+ tps65086_10mv_ranges, TPS65086_BUCK2CTRL,
+ BIT(0)),
+ TPS65086_REGULATOR("BUCK3", "buck3", BUCK3, 0x80, TPS65086_BUCK3VID,
+ BUCK_VID_MASK, TPS65086_BUCK123CTRL, BIT(2),
+ tps65086_10mv_ranges, TPS65086_BUCK3DECAY,
+ BIT(0)),
+ TPS65086_REGULATOR("BUCK4", "buck4", BUCK4, 0x80, TPS65086_BUCK4VID,
+ BUCK_VID_MASK, TPS65086_BUCK4CTRL, BIT(0),
+ tps65086_10mv_ranges, TPS65086_BUCK4VID,
+ BIT(0)),
+ TPS65086_REGULATOR("BUCK5", "buck5", BUCK5, 0x80, TPS65086_BUCK5VID,
+ BUCK_VID_MASK, TPS65086_BUCK5CTRL, BIT(0),
+ tps65086_10mv_ranges, TPS65086_BUCK5CTRL,
+ BIT(0)),
+ TPS65086_REGULATOR("BUCK6", "buck6", BUCK6, 0x80, TPS65086_BUCK6VID,
+ BUCK_VID_MASK, TPS65086_BUCK6CTRL, BIT(0),
+ tps65086_10mv_ranges, TPS65086_BUCK6CTRL,
+ BIT(0)),
+ TPS65086_REGULATOR("LDOA1", "ldoa1", LDOA1, 0xF, TPS65086_LDOA1CTRL,
+ VDOA1_VID_MASK, TPS65086_SWVTT_EN, BIT(7),
+ tps65086_ldoa1_ranges, 0, 0),
+ TPS65086_REGULATOR("LDOA2", "ldoa2", LDOA2, 0x10, TPS65086_LDOA2VID,
+ VDOA23_VID_MASK, TPS65086_LDOA2CTRL, BIT(0),
+ tps65086_ldoa23_ranges, 0, 0),
+ TPS65086_REGULATOR("LDOA3", "ldoa3", LDOA3, 0x10, TPS65086_LDOA3VID,
+ VDOA23_VID_MASK, TPS65086_LDOA3CTRL, BIT(0),
+ tps65086_ldoa23_ranges, 0, 0),
+ TPS65086_SWITCH("VTT", "vtt", VTT, TPS65086_SWVTT_EN, BIT(4)),
+ TPS65086_SWITCH("SWA1", "swa1", SWA1, TPS65086_SWVTT_EN, BIT(5)),
+ TPS65086_SWITCH("SWB1", "swb1", SWB1, TPS65086_SWVTT_EN, BIT(6)),
+};
+
+static struct tps65086_regulator tps6508641_regulator_config[] = {
+ TPS65086_REGULATOR("BUCK1", "buck1", BUCK1, 0x80, TPS65086_BUCK1CTRL,
+ BUCK_VID_MASK, TPS65086_BUCK123CTRL, BIT(0),
+ tps65086_10mv_ranges, TPS65086_BUCK1CTRL,
+ BIT(0)),
+ TPS65086_REGULATOR("BUCK2", "buck2", BUCK2, 0x80, TPS65086_BUCK2CTRL,
+ BUCK_VID_MASK, TPS65086_BUCK123CTRL, BIT(1),
+ tps65086_10mv_ranges, TPS65086_BUCK2CTRL,
+ BIT(0)),
+ TPS65086_REGULATOR("BUCK3", "buck3", BUCK3, 0x80, TPS65086_BUCK3VID,
+ BUCK_VID_MASK, TPS65086_BUCK123CTRL, BIT(2),
+ tps65086_10mv_ranges, TPS65086_BUCK3DECAY,
+ BIT(0)),
+ TPS65086_REGULATOR("BUCK4", "buck4", BUCK4, 0x80, TPS65086_BUCK4VID,
+ BUCK_VID_MASK, TPS65086_BUCK4CTRL, BIT(0),
+ tps65086_10mv_ranges, TPS65086_BUCK4VID,
+ BIT(0)),
+ TPS65086_REGULATOR("BUCK5", "buck5", BUCK5, 0x80, TPS65086_BUCK5VID,
+ BUCK_VID_MASK, TPS65086_BUCK5CTRL, BIT(0),
+ tps65086_10mv_ranges, TPS65086_BUCK5CTRL,
+ BIT(0)),
+ TPS65086_REGULATOR("BUCK6", "buck6", BUCK6, 0x80, TPS65086_BUCK6VID,
+ BUCK_VID_MASK, TPS65086_BUCK6CTRL, BIT(0),
+ tps65086_10mv_ranges, TPS65086_BUCK6CTRL,
+ BIT(0)),
+ TPS65086_REGULATOR("LDOA1", "ldoa1", LDOA1, 0xF, TPS65086_LDOA1CTRL,
+ VDOA1_VID_MASK, TPS65086_SWVTT_EN, BIT(7),
+ tps65086_ldoa1_ranges, 0, 0),
+ TPS65086_REGULATOR("LDOA2", "ldoa2", LDOA2, 0x10, TPS65086_LDOA2VID,
+ VDOA23_VID_MASK, TPS65086_LDOA2CTRL, BIT(0),
+ tps65086_ldoa23_ranges, 0, 0),
+ TPS65086_REGULATOR("LDOA3", "ldoa3", LDOA3, 0x10, TPS65086_LDOA3VID,
+ VDOA23_VID_MASK, TPS65086_LDOA3CTRL, BIT(0),
+ tps65086_ldoa23_ranges, 0, 0),
+ TPS65086_SWITCH("VTT", "vtt", VTT, TPS65086_SWVTT_EN, BIT(4)),
+ TPS65086_SWITCH("SWA1", "swa1", SWA1, TPS65086_SWVTT_EN, BIT(5)),
+ TPS65086_SWITCH("SWB1", "swb1", SWB1, TPS65086_SWVTT_EN, BIT(6)),
+};
+
+static struct tps65086_regulator tps65086470_regulator_config[] = {
TPS65086_REGULATOR("BUCK1", "buck1", BUCK1, 0x80, TPS65086_BUCK1CTRL,
BUCK_VID_MASK, TPS65086_BUCK123CTRL, BIT(0),
tps65086_10mv_ranges, TPS65086_BUCK1CTRL,
@@ -148,16 +278,25 @@ static struct tps65086_regulator regulators[] = {
TPS65086_REGULATOR("LDOA3", "ldoa3", LDOA3, 0x10, TPS65086_LDOA3VID,
VDOA23_VID_MASK, TPS65086_LDOA3CTRL, BIT(0),
tps65086_ldoa23_ranges, 0, 0),
+ TPS65086_SWITCH("VTT", "vtt", VTT, TPS65086_SWVTT_EN, BIT(4)),
TPS65086_SWITCH("SWA1", "swa1", SWA1, TPS65086_SWVTT_EN, BIT(5)),
TPS65086_SWITCH("SWB1", "swb1", SWB1, TPS65086_SWVTT_EN, BIT(6)),
TPS65086_SWITCH("SWB2", "swb2", SWB2, TPS65086_SWVTT_EN, BIT(7)),
- TPS65086_SWITCH("VTT", "vtt", VTT, TPS65086_SWVTT_EN, BIT(4)),
+};
+
+static const struct tps65086_regulator_config regulator_configs[] = {
+ TPS65086_REGULATOR_CONFIG(TPS6508640, tps6508640_regulator_config),
+ TPS65086_REGULATOR_CONFIG(TPS65086401, tps65086401_regulator_config),
+ TPS65086_REGULATOR_CONFIG(TPS6508641, tps6508641_regulator_config),
+ TPS65086_REGULATOR_CONFIG(TPS65086470, tps65086470_regulator_config)
};
static int tps65086_of_parse_cb(struct device_node *node,
const struct regulator_desc *desc,
struct regulator_config *config)
{
+ struct tps65086 * const tps = dev_get_drvdata(config->dev);
+ struct tps65086_regulator *regulators = tps->reg_config->config;
int ret;
/* Check for 25mV step mode */
@@ -202,10 +341,14 @@ static int tps65086_of_parse_cb(struct device_node *node,
static int tps65086_regulator_probe(struct platform_device *pdev)
{
struct tps65086 *tps = dev_get_drvdata(pdev->dev.parent);
+ unsigned int chip_id = tps->chip_id;
struct regulator_config config = { };
struct regulator_dev *rdev;
int i;
+ /* Select regulator configuration for used PMIC device */
+ tps->reg_config = ®ulator_configs[chip_id];
+
platform_set_drvdata(pdev, tps);
config.dev = &pdev->dev;
@@ -213,12 +356,16 @@ static int tps65086_regulator_probe(struct platform_device *pdev)
config.driver_data = tps;
config.regmap = tps->regmap;
- for (i = 0; i < ARRAY_SIZE(regulators); i++) {
- rdev = devm_regulator_register(&pdev->dev, ®ulators[i].desc,
- &config);
+ for (i = 0; i < tps->reg_config->num_elems; ++i) {
+ struct regulator_desc * const desc_ptr = &tps->reg_config->config[i].desc;
+
+ dev_dbg(tps->dev, "Index: %u; Regulator name: \"%s\"; Regulator ID: %d\n",
+ i, desc_ptr->name, desc_ptr->id);
+
+ rdev = devm_regulator_register(&pdev->dev, desc_ptr, &config);
if (IS_ERR(rdev)) {
- dev_err(tps->dev, "failed to register %s regulator\n",
- pdev->name);
+ dev_err(tps->dev, "failed to register %d \"%s\" regulator\n",
+ i, desc_ptr->name);
return PTR_ERR(rdev);
}
}
diff --git a/include/linux/mfd/tps65086.h b/include/linux/mfd/tps65086.h
index 88df344b38df..88ef5b556698 100644
--- a/include/linux/mfd/tps65086.h
+++ b/include/linux/mfd/tps65086.h
@@ -106,6 +106,8 @@ enum tps65086_irqs {
TPS65086_IRQ_FAULT,
};
+struct tps65086_regulator_config;
+
/**
* struct tps65086 - state holder for the tps65086 driver
*
@@ -115,6 +117,7 @@ struct tps65086 {
struct device *dev;
struct regmap *regmap;
unsigned int chip_id;
+ const struct tps65086_regulator_config *reg_config;
/* IRQ Data */
int irq;
--
2.41.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH 1/2] mfd: (tps65086): Read DEVICE ID register 1 from device
2023-08-09 10:14 [PATCH 1/2] mfd: (tps65086): Read DEVICE ID register 1 from device werneazc
2023-08-09 10:14 ` [PATCH 2/2] regulator: (tps65086): Select dedicated regulator config for chip variant werneazc
@ 2023-08-17 17:02 ` Lee Jones
2023-08-18 5:06 ` Andre Werner
1 sibling, 1 reply; 5+ messages in thread
From: Lee Jones @ 2023-08-17 17:02 UTC (permalink / raw)
To: werneazc; +Cc: lgirdwood, broonie, linux-kernel, Andre Werner
On Wed, 09 Aug 2023, werneazc@gmail.com wrote:
> From: Andre Werner <andre.werner@systec-electronic.com>
>
> This commit prepares a following commit for the regulator part of the MFD.
> The driver should support different device chips that differ in their
> register definitions, for instance to control LDOA1 and SWB2.
> So it is necessary to use a dedicated regulator description for a
> specific device variant. Thus, the content from DEVICEID Register 1 is
> used to choose a dedicated configuration between the different device
> variants.
>
> Signed-off-by: Andre Werner <andre.werner@systec-electronic.com>
> ---
> drivers/mfd/tps65086.c | 37 ++++++++++++++++++++++++++++++------
> include/linux/mfd/tps65086.h | 27 ++++++++++++++++++++------
> 2 files changed, 52 insertions(+), 12 deletions(-)
>
> diff --git a/drivers/mfd/tps65086.c b/drivers/mfd/tps65086.c
> index 6a21000aad4a..38f8572c265e 100644
> --- a/drivers/mfd/tps65086.c
> +++ b/drivers/mfd/tps65086.c
> @@ -64,7 +64,7 @@ MODULE_DEVICE_TABLE(of, tps65086_of_match_table);
> static int tps65086_probe(struct i2c_client *client)
> {
> struct tps65086 *tps;
> - unsigned int version;
> + unsigned int version, id;
> int ret;
>
> tps = devm_kzalloc(&client->dev, sizeof(*tps), GFP_KERNEL);
> @@ -81,16 +81,41 @@ static int tps65086_probe(struct i2c_client *client)
> return PTR_ERR(tps->regmap);
> }
>
> - ret = regmap_read(tps->regmap, TPS65086_DEVICEID, &version);
> + ret = regmap_read(tps->regmap, TPS65086_DEVICEID1, &id);
> if (ret) {
> - dev_err(tps->dev, "Failed to read revision register\n");
> + dev_err(tps->dev, "Failed to read revision register 1\n");
> + return ret;
> + }
> +
> + /* Store device ID to load regulator configuration that fit to IC variant */
> + switch (id) {
> + case TPS6508640_ID:
> + tps->chip_id = TPS6508640;
Why not use the meaningful TPS6508640_ID for the chip_id instead of an
arbitrary enum?
> + break;
> + case TPS65086401_ID:
> + tps->chip_id = TPS65086401;
> + break;
> + case TPS6508641_ID:
> + tps->chip_id = TPS6508641;
> + break;
> + case TPS65086470_ID:
> + tps->chip_id = TPS65086470;
> + break;
> + default:
> + dev_err(tps->dev, "Unknown device ID. Cannot determine regulator config.\n");
> + return -ENODEV;
> + }
> +
> + ret = regmap_read(tps->regmap, TPS65086_DEVICEID2, &version);
> + if (ret) {
> + dev_err(tps->dev, "Failed to read revision register 2\n");
> return ret;
> }
>
> dev_info(tps->dev, "Device: TPS65086%01lX, OTP: %c, Rev: %ld\n",
> - (version & TPS65086_DEVICEID_PART_MASK),
> - (char)((version & TPS65086_DEVICEID_OTP_MASK) >> 4) + 'A',
> - (version & TPS65086_DEVICEID_REV_MASK) >> 6);
> + (version & TPS65086_DEVICEID2_PART_MASK),
> + (char)((version & TPS65086_DEVICEID2_OTP_MASK) >> 4) + 'A',
> + (version & TPS65086_DEVICEID2_REV_MASK) >> 6);
>
> if (tps->irq > 0) {
> ret = regmap_add_irq_chip(tps->regmap, tps->irq, IRQF_ONESHOT, 0,
> diff --git a/include/linux/mfd/tps65086.h b/include/linux/mfd/tps65086.h
> index 16f87cccc003..88df344b38df 100644
> --- a/include/linux/mfd/tps65086.h
> +++ b/include/linux/mfd/tps65086.h
> @@ -13,8 +13,9 @@
> #include <linux/regmap.h>
>
> /* List of registers for TPS65086 */
> -#define TPS65086_DEVICEID 0x01
> -#define TPS65086_IRQ 0x02
> +#define TPS65086_DEVICEID1 0x00
> +#define TPS65086_DEVICEID2 0x01
> +#define TPS65086_IRQ 0x02
> #define TPS65086_IRQ_MASK 0x03
> #define TPS65086_PMICSTAT 0x04
> #define TPS65086_SHUTDNSRC 0x05
> @@ -75,16 +76,29 @@
> #define TPS65086_IRQ_SHUTDN_MASK BIT(3)
> #define TPS65086_IRQ_FAULT_MASK BIT(7)
>
> -/* DEVICEID Register field definitions */
> -#define TPS65086_DEVICEID_PART_MASK GENMASK(3, 0)
> -#define TPS65086_DEVICEID_OTP_MASK GENMASK(5, 4)
> -#define TPS65086_DEVICEID_REV_MASK GENMASK(7, 6)
> +/* DEVICEID1 Register field definitions */
> +#define TPS6508640_ID 0x00
> +#define TPS65086401_ID 0x01
> +#define TPS6508641_ID 0x10
> +#define TPS65086470_ID 0x70
> +
> +/* DEVICEID2 Register field definitions */
> +#define TPS65086_DEVICEID2_PART_MASK GENMASK(3, 0)
> +#define TPS65086_DEVICEID2_OTP_MASK GENMASK(5, 4)
> +#define TPS65086_DEVICEID2_REV_MASK GENMASK(7, 6)
>
> /* VID Masks */
> #define BUCK_VID_MASK GENMASK(7, 1)
> #define VDOA1_VID_MASK GENMASK(4, 1)
> #define VDOA23_VID_MASK GENMASK(3, 0)
>
> +enum tps65086_ids {
> + TPS6508640,
> + TPS65086401,
> + TPS6508641,
> + TPS65086470,
> +};
> +
> /* Define the TPS65086 IRQ numbers */
> enum tps65086_irqs {
> TPS65086_IRQ_DIETEMP,
> @@ -100,6 +114,7 @@ enum tps65086_irqs {
> struct tps65086 {
> struct device *dev;
> struct regmap *regmap;
> + unsigned int chip_id;
>
> /* IRQ Data */
> int irq;
> --
> 2.41.0
>
--
Lee Jones [李琼斯]
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH 1/2] mfd: (tps65086): Read DEVICE ID register 1 from device
2023-08-17 17:02 ` [PATCH 1/2] mfd: (tps65086): Read DEVICE ID register 1 from device Lee Jones
@ 2023-08-18 5:06 ` Andre Werner
2023-08-18 6:56 ` Lee Jones
0 siblings, 1 reply; 5+ messages in thread
From: Andre Werner @ 2023-08-18 5:06 UTC (permalink / raw)
To: Lee Jones; +Cc: werneazc, lgirdwood, broonie, linux-kernel, Andre Werner
[-- Attachment #1: Type: text/plain, Size: 5410 bytes --]
On Thu, 17 Aug 2023, Lee Jones wrote:
> On Wed, 09 Aug 2023, werneazc@gmail.com wrote:
>
>> From: Andre Werner <andre.werner@systec-electronic.com>
>>
>> This commit prepares a following commit for the regulator part of the MFD.
>> The driver should support different device chips that differ in their
>> register definitions, for instance to control LDOA1 and SWB2.
>> So it is necessary to use a dedicated regulator description for a
>> specific device variant. Thus, the content from DEVICEID Register 1 is
>> used to choose a dedicated configuration between the different device
>> variants.
>>
>> Signed-off-by: Andre Werner <andre.werner@systec-electronic.com>
>> ---
>> drivers/mfd/tps65086.c | 37 ++++++++++++++++++++++++++++++------
>> include/linux/mfd/tps65086.h | 27 ++++++++++++++++++++------
>> 2 files changed, 52 insertions(+), 12 deletions(-)
>>
>> diff --git a/drivers/mfd/tps65086.c b/drivers/mfd/tps65086.c
>> index 6a21000aad4a..38f8572c265e 100644
>> --- a/drivers/mfd/tps65086.c
>> +++ b/drivers/mfd/tps65086.c
>> @@ -64,7 +64,7 @@ MODULE_DEVICE_TABLE(of, tps65086_of_match_table);
>> static int tps65086_probe(struct i2c_client *client)
>> {
>> struct tps65086 *tps;
>> - unsigned int version;
>> + unsigned int version, id;
>> int ret;
>>
>> tps = devm_kzalloc(&client->dev, sizeof(*tps), GFP_KERNEL);
>> @@ -81,16 +81,41 @@ static int tps65086_probe(struct i2c_client *client)
>> return PTR_ERR(tps->regmap);
>> }
>>
>> - ret = regmap_read(tps->regmap, TPS65086_DEVICEID, &version);
>> + ret = regmap_read(tps->regmap, TPS65086_DEVICEID1, &id);
>> if (ret) {
>> - dev_err(tps->dev, "Failed to read revision register\n");
>> + dev_err(tps->dev, "Failed to read revision register 1\n");
>> + return ret;
>> + }
>> +
>> + /* Store device ID to load regulator configuration that fit to IC variant */
>> + switch (id) {
>> + case TPS6508640_ID:
>> + tps->chip_id = TPS6508640;
>
> Why not use the meaningful TPS6508640_ID for the chip_id instead of an
> arbitrary enum?
In the regulator part for this MFD I use this enum ID to select the
right configuration from an array. So the intention is using the enum as
the index for this table. I can move this selection into the regulator
part and store the meaningful TPS65086 IDs in the MFD data if you
prefer?
>
>> + break;
>> + case TPS65086401_ID:
>> + tps->chip_id = TPS65086401;
>> + break;
>> + case TPS6508641_ID:
>> + tps->chip_id = TPS6508641;
>> + break;
>> + case TPS65086470_ID:
>> + tps->chip_id = TPS65086470;
>> + break;
>> + default:
>> + dev_err(tps->dev, "Unknown device ID. Cannot determine regulator config.\n");
>> + return -ENODEV;
>> + }
>> +
>> + ret = regmap_read(tps->regmap, TPS65086_DEVICEID2, &version);
>> + if (ret) {
>> + dev_err(tps->dev, "Failed to read revision register 2\n");
>> return ret;
>> }
>>
>> dev_info(tps->dev, "Device: TPS65086%01lX, OTP: %c, Rev: %ld\n",
>> - (version & TPS65086_DEVICEID_PART_MASK),
>> - (char)((version & TPS65086_DEVICEID_OTP_MASK) >> 4) + 'A',
>> - (version & TPS65086_DEVICEID_REV_MASK) >> 6);
>> + (version & TPS65086_DEVICEID2_PART_MASK),
>> + (char)((version & TPS65086_DEVICEID2_OTP_MASK) >> 4) + 'A',
>> + (version & TPS65086_DEVICEID2_REV_MASK) >> 6);
>>
>> if (tps->irq > 0) {
>> ret = regmap_add_irq_chip(tps->regmap, tps->irq, IRQF_ONESHOT, 0,
>> diff --git a/include/linux/mfd/tps65086.h b/include/linux/mfd/tps65086.h
>> index 16f87cccc003..88df344b38df 100644
>> --- a/include/linux/mfd/tps65086.h
>> +++ b/include/linux/mfd/tps65086.h
>> @@ -13,8 +13,9 @@
>> #include <linux/regmap.h>
>>
>> /* List of registers for TPS65086 */
>> -#define TPS65086_DEVICEID 0x01
>> -#define TPS65086_IRQ 0x02
>> +#define TPS65086_DEVICEID1 0x00
>> +#define TPS65086_DEVICEID2 0x01
>> +#define TPS65086_IRQ 0x02
>> #define TPS65086_IRQ_MASK 0x03
>> #define TPS65086_PMICSTAT 0x04
>> #define TPS65086_SHUTDNSRC 0x05
>> @@ -75,16 +76,29 @@
>> #define TPS65086_IRQ_SHUTDN_MASK BIT(3)
>> #define TPS65086_IRQ_FAULT_MASK BIT(7)
>>
>> -/* DEVICEID Register field definitions */
>> -#define TPS65086_DEVICEID_PART_MASK GENMASK(3, 0)
>> -#define TPS65086_DEVICEID_OTP_MASK GENMASK(5, 4)
>> -#define TPS65086_DEVICEID_REV_MASK GENMASK(7, 6)
>> +/* DEVICEID1 Register field definitions */
>> +#define TPS6508640_ID 0x00
>> +#define TPS65086401_ID 0x01
>> +#define TPS6508641_ID 0x10
>> +#define TPS65086470_ID 0x70
>> +
>> +/* DEVICEID2 Register field definitions */
>> +#define TPS65086_DEVICEID2_PART_MASK GENMASK(3, 0)
>> +#define TPS65086_DEVICEID2_OTP_MASK GENMASK(5, 4)
>> +#define TPS65086_DEVICEID2_REV_MASK GENMASK(7, 6)
>>
>> /* VID Masks */
>> #define BUCK_VID_MASK GENMASK(7, 1)
>> #define VDOA1_VID_MASK GENMASK(4, 1)
>> #define VDOA23_VID_MASK GENMASK(3, 0)
>>
>> +enum tps65086_ids {
>> + TPS6508640,
>> + TPS65086401,
>> + TPS6508641,
>> + TPS65086470,
>> +};
>> +
>> /* Define the TPS65086 IRQ numbers */
>> enum tps65086_irqs {
>> TPS65086_IRQ_DIETEMP,
>> @@ -100,6 +114,7 @@ enum tps65086_irqs {
>> struct tps65086 {
>> struct device *dev;
>> struct regmap *regmap;
>> + unsigned int chip_id;
>>
>> /* IRQ Data */
>> int irq;
>> --
>> 2.41.0
>>
>
> --
> Lee Jones [李琼斯]
>
Regards,
André
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH 1/2] mfd: (tps65086): Read DEVICE ID register 1 from device
2023-08-18 5:06 ` Andre Werner
@ 2023-08-18 6:56 ` Lee Jones
0 siblings, 0 replies; 5+ messages in thread
From: Lee Jones @ 2023-08-18 6:56 UTC (permalink / raw)
To: Andre Werner; +Cc: werneazc, lgirdwood, broonie, linux-kernel
On Fri, 18 Aug 2023, Andre Werner wrote:
> On Thu, 17 Aug 2023, Lee Jones wrote:
>
> > On Wed, 09 Aug 2023, werneazc@gmail.com wrote:
> >
> > > From: Andre Werner <andre.werner@systec-electronic.com>
> > >
> > > This commit prepares a following commit for the regulator part of the MFD.
> > > The driver should support different device chips that differ in their
> > > register definitions, for instance to control LDOA1 and SWB2.
> > > So it is necessary to use a dedicated regulator description for a
> > > specific device variant. Thus, the content from DEVICEID Register 1 is
> > > used to choose a dedicated configuration between the different device
> > > variants.
> > >
> > > Signed-off-by: Andre Werner <andre.werner@systec-electronic.com>
> > > ---
> > > drivers/mfd/tps65086.c | 37 ++++++++++++++++++++++++++++++------
> > > include/linux/mfd/tps65086.h | 27 ++++++++++++++++++++------
> > > 2 files changed, 52 insertions(+), 12 deletions(-)
> > >
> > > diff --git a/drivers/mfd/tps65086.c b/drivers/mfd/tps65086.c
> > > index 6a21000aad4a..38f8572c265e 100644
> > > --- a/drivers/mfd/tps65086.c
> > > +++ b/drivers/mfd/tps65086.c
> > > @@ -64,7 +64,7 @@ MODULE_DEVICE_TABLE(of, tps65086_of_match_table);
> > > static int tps65086_probe(struct i2c_client *client)
> > > {
> > > struct tps65086 *tps;
> > > - unsigned int version;
> > > + unsigned int version, id;
> > > int ret;
> > >
> > > tps = devm_kzalloc(&client->dev, sizeof(*tps), GFP_KERNEL);
> > > @@ -81,16 +81,41 @@ static int tps65086_probe(struct i2c_client *client)
> > > return PTR_ERR(tps->regmap);
> > > }
> > >
> > > - ret = regmap_read(tps->regmap, TPS65086_DEVICEID, &version);
> > > + ret = regmap_read(tps->regmap, TPS65086_DEVICEID1, &id);
> > > if (ret) {
> > > - dev_err(tps->dev, "Failed to read revision register\n");
> > > + dev_err(tps->dev, "Failed to read revision register 1\n");
> > > + return ret;
> > > + }
> > > +
> > > + /* Store device ID to load regulator configuration that fit to IC variant */
> > > + switch (id) {
> > > + case TPS6508640_ID:
> > > + tps->chip_id = TPS6508640;
> >
> > Why not use the meaningful TPS6508640_ID for the chip_id instead of an
> > arbitrary enum?
>
> In the regulator part for this MFD I use this enum ID to select the
> right configuration from an array. So the intention is using the enum as
> the index for this table. I can move this selection into the regulator
> part and store the meaningful TPS65086 IDs in the MFD data if you
> prefer?
That would make more sense for the reader I feel. Thanks.
> > > + break;
> > > + case TPS65086401_ID:
> > > + tps->chip_id = TPS65086401;
> > > + break;
> > > + case TPS6508641_ID:
> > > + tps->chip_id = TPS6508641;
> > > + break;
> > > + case TPS65086470_ID:
> > > + tps->chip_id = TPS65086470;
> > > + break;
> > > + default:
> > > + dev_err(tps->dev, "Unknown device ID. Cannot determine regulator config.\n");
> > > + return -ENODEV;
> > > + }
> > > +
> > > + ret = regmap_read(tps->regmap, TPS65086_DEVICEID2, &version);
> > > + if (ret) {
> > > + dev_err(tps->dev, "Failed to read revision register 2\n");
> > > return ret;
> > > }
> > >
> > > dev_info(tps->dev, "Device: TPS65086%01lX, OTP: %c, Rev: %ld\n",
> > > - (version & TPS65086_DEVICEID_PART_MASK),
> > > - (char)((version & TPS65086_DEVICEID_OTP_MASK) >> 4) + 'A',
> > > - (version & TPS65086_DEVICEID_REV_MASK) >> 6);
> > > + (version & TPS65086_DEVICEID2_PART_MASK),
> > > + (char)((version & TPS65086_DEVICEID2_OTP_MASK) >> 4) + 'A',
> > > + (version & TPS65086_DEVICEID2_REV_MASK) >> 6);
> > >
> > > if (tps->irq > 0) {
> > > ret = regmap_add_irq_chip(tps->regmap, tps->irq, IRQF_ONESHOT, 0,
> > > diff --git a/include/linux/mfd/tps65086.h b/include/linux/mfd/tps65086.h
> > > index 16f87cccc003..88df344b38df 100644
> > > --- a/include/linux/mfd/tps65086.h
> > > +++ b/include/linux/mfd/tps65086.h
> > > @@ -13,8 +13,9 @@
> > > #include <linux/regmap.h>
> > >
> > > /* List of registers for TPS65086 */
> > > -#define TPS65086_DEVICEID 0x01
> > > -#define TPS65086_IRQ 0x02
> > > +#define TPS65086_DEVICEID1 0x00
> > > +#define TPS65086_DEVICEID2 0x01
> > > +#define TPS65086_IRQ 0x02
> > > #define TPS65086_IRQ_MASK 0x03
> > > #define TPS65086_PMICSTAT 0x04
> > > #define TPS65086_SHUTDNSRC 0x05
> > > @@ -75,16 +76,29 @@
> > > #define TPS65086_IRQ_SHUTDN_MASK BIT(3)
> > > #define TPS65086_IRQ_FAULT_MASK BIT(7)
> > >
> > > -/* DEVICEID Register field definitions */
> > > -#define TPS65086_DEVICEID_PART_MASK GENMASK(3, 0)
> > > -#define TPS65086_DEVICEID_OTP_MASK GENMASK(5, 4)
> > > -#define TPS65086_DEVICEID_REV_MASK GENMASK(7, 6)
> > > +/* DEVICEID1 Register field definitions */
> > > +#define TPS6508640_ID 0x00
> > > +#define TPS65086401_ID 0x01
> > > +#define TPS6508641_ID 0x10
> > > +#define TPS65086470_ID 0x70
> > > +
> > > +/* DEVICEID2 Register field definitions */
> > > +#define TPS65086_DEVICEID2_PART_MASK GENMASK(3, 0)
> > > +#define TPS65086_DEVICEID2_OTP_MASK GENMASK(5, 4)
> > > +#define TPS65086_DEVICEID2_REV_MASK GENMASK(7, 6)
> > >
> > > /* VID Masks */
> > > #define BUCK_VID_MASK GENMASK(7, 1)
> > > #define VDOA1_VID_MASK GENMASK(4, 1)
> > > #define VDOA23_VID_MASK GENMASK(3, 0)
> > >
> > > +enum tps65086_ids {
> > > + TPS6508640,
> > > + TPS65086401,
> > > + TPS6508641,
> > > + TPS65086470,
> > > +};
> > > +
> > > /* Define the TPS65086 IRQ numbers */
> > > enum tps65086_irqs {
> > > TPS65086_IRQ_DIETEMP,
> > > @@ -100,6 +114,7 @@ enum tps65086_irqs {
> > > struct tps65086 {
> > > struct device *dev;
> > > struct regmap *regmap;
> > > + unsigned int chip_id;
> > >
> > > /* IRQ Data */
> > > int irq;
> > > --
> > > 2.41.0
> > >
> >
> > --
> > Lee Jones [李琼斯]
> >
>
> Regards,
>
> André
--
Lee Jones [李琼斯]
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2023-08-18 6:57 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-08-09 10:14 [PATCH 1/2] mfd: (tps65086): Read DEVICE ID register 1 from device werneazc
2023-08-09 10:14 ` [PATCH 2/2] regulator: (tps65086): Select dedicated regulator config for chip variant werneazc
2023-08-17 17:02 ` [PATCH 1/2] mfd: (tps65086): Read DEVICE ID register 1 from device Lee Jones
2023-08-18 5:06 ` Andre Werner
2023-08-18 6:56 ` Lee Jones
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox