Commit 29f7ae9e authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files

Merge branch 'net-pse-pd-add-tps23881b-support'

Thomas Wismer says:

====================
net: pse-pd: Add TPS23881B support

This patch series aims at adding support for the TI TPS23881B PoE
PSE controller.
====================

Link: https://patch.msgid.link/20251029212312.108749-1-thomas@wismer.xyz


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents a7aca10c 32032eb1
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@ properties:
  compatible:
    enum:
      - ti,tps23881
      - ti,tps23881b

  reg:
    maxItems: 1
+54 −15
Original line number Diff line number Diff line
@@ -55,8 +55,6 @@
#define TPS23881_REG_TPON	BIT(0)
#define TPS23881_REG_FWREV	0x41
#define TPS23881_REG_DEVID	0x43
#define TPS23881_REG_DEVID_MASK	0xF0
#define TPS23881_DEVICE_ID	0x02
#define TPS23881_REG_CHAN1_CLASS	0x4c
#define TPS23881_REG_SRAM_CTRL	0x60
#define TPS23881_REG_SRAM_DATA	0x61
@@ -1012,8 +1010,28 @@ static const struct pse_controller_ops tps23881_ops = {
	.pi_get_pw_req = tps23881_pi_get_pw_req,
};

static const char fw_parity_name[] = "ti/tps23881/tps23881-parity-14.bin";
static const char fw_sram_name[] = "ti/tps23881/tps23881-sram-14.bin";
struct tps23881_info {
	u8 dev_id;	/* device ID and silicon revision */
	const char *fw_parity_name;	/* parity code firmware file name */
	const char *fw_sram_name;	/* SRAM code firmware file name */
};

enum tps23881_model {
	TPS23881,
	TPS23881B,
};

static const struct tps23881_info tps23881_info[] = {
	[TPS23881] = {
		.dev_id = 0x22,
		.fw_parity_name = "ti/tps23881/tps23881-parity-14.bin",
		.fw_sram_name = "ti/tps23881/tps23881-sram-14.bin",
	},
	[TPS23881B] = {
		.dev_id = 0x24,
		/* skip SRAM load, ROM provides Clause 145 hardware-level support */
	},
};

struct tps23881_fw_conf {
	u8 reg;
@@ -1085,16 +1103,17 @@ static int tps23881_flash_sram_fw_part(struct i2c_client *client,
	return ret;
}

static int tps23881_flash_sram_fw(struct i2c_client *client)
static int tps23881_flash_sram_fw(struct i2c_client *client,
				  const struct tps23881_info *info)
{
	int ret;

	ret = tps23881_flash_sram_fw_part(client, fw_parity_name,
	ret = tps23881_flash_sram_fw_part(client, info->fw_parity_name,
					  tps23881_fw_parity_conf);
	if (ret)
		return ret;

	ret = tps23881_flash_sram_fw_part(client, fw_sram_name,
	ret = tps23881_flash_sram_fw_part(client, info->fw_sram_name,
					  tps23881_fw_sram_conf);
	if (ret)
		return ret;
@@ -1412,6 +1431,7 @@ static int tps23881_setup_irq(struct tps23881_priv *priv, int irq)
static int tps23881_i2c_probe(struct i2c_client *client)
{
	struct device *dev = &client->dev;
	const struct tps23881_info *info;
	struct tps23881_priv *priv;
	struct gpio_desc *reset;
	int ret;
@@ -1422,6 +1442,10 @@ static int tps23881_i2c_probe(struct i2c_client *client)
		return -ENXIO;
	}

	info = i2c_get_match_data(client);
	if (!info)
		return -EINVAL;

	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
	if (!priv)
		return -ENOMEM;
@@ -1440,7 +1464,7 @@ static int tps23881_i2c_probe(struct i2c_client *client)
		 * to Load TPS2388x SRAM and Parity Code over I2C" (Rev E))
		 * indicates we should delay that programming by at least 50ms. So
		 * we'll wait the entire 50ms here to ensure we're safe to go to the
		 * SRAM loading proceedure.
		 * SRAM loading procedure.
		 */
		msleep(50);
	}
@@ -1449,20 +1473,27 @@ static int tps23881_i2c_probe(struct i2c_client *client)
	if (ret < 0)
		return ret;

	if (FIELD_GET(TPS23881_REG_DEVID_MASK, ret) != TPS23881_DEVICE_ID) {
	if (ret != info->dev_id) {
		dev_err(dev, "Wrong device ID\n");
		return -ENXIO;
	}

	ret = tps23881_flash_sram_fw(client);
	if (info->fw_sram_name) {
		ret = tps23881_flash_sram_fw(client, info);
		if (ret < 0)
			return ret;
	}

	ret = i2c_smbus_read_byte_data(client, TPS23881_REG_FWREV);
	if (ret < 0)
		return ret;

	dev_info(&client->dev, "Firmware revision 0x%x\n", ret);
	if (ret == 0xFF) {
		dev_err(&client->dev, "Device entered safe mode\n");
		return -ENXIO;
	}
	dev_info(&client->dev, "Firmware revision 0x%x%s\n", ret,
		 ret == 0x00 ? " (ROM firmware)" : "");

	/* Set configuration B, 16 bit access on a single device address */
	ret = i2c_smbus_read_byte_data(client, TPS23881_REG_GEN_MASK);
@@ -1498,13 +1529,21 @@ static int tps23881_i2c_probe(struct i2c_client *client)
}

static const struct i2c_device_id tps23881_id[] = {
	{ "tps23881" },
	{ "tps23881", .driver_data = (kernel_ulong_t)&tps23881_info[TPS23881] },
	{ "tps23881b", .driver_data = (kernel_ulong_t)&tps23881_info[TPS23881B] },
	{ }
};
MODULE_DEVICE_TABLE(i2c, tps23881_id);

static const struct of_device_id tps23881_of_match[] = {
	{ .compatible = "ti,tps23881", },
	{
		.compatible = "ti,tps23881",
		.data = &tps23881_info[TPS23881]
	},
	{
		.compatible = "ti,tps23881b",
		.data = &tps23881_info[TPS23881B]
	},
	{ },
};
MODULE_DEVICE_TABLE(of, tps23881_of_match);