Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.1.
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * Driver for the Microchip PD692X0 PoE PSE Controller driver (I2C bus)
   4 *
   5 * Copyright (c) 2023 Bootlin, Kory Maincent <kory.maincent@bootlin.com>
   6 */
   7
   8#include <linux/delay.h>
   9#include <linux/firmware.h>
  10#include <linux/i2c.h>
  11#include <linux/module.h>
  12#include <linux/of.h>
  13#include <linux/platform_device.h>
  14#include <linux/pse-pd/pse.h>
  15
  16#define PD692X0_PSE_NAME "pd692x0_pse"
  17
  18#define PD692X0_MAX_PIS	48
  19#define PD692X0_MAX_MANAGERS		12
  20#define PD692X0_MAX_MANAGER_PORTS	8
  21#define PD692X0_MAX_HW_PORTS	(PD692X0_MAX_MANAGERS * PD692X0_MAX_MANAGER_PORTS)
  22
  23#define PD69200_BT_PROD_VER	24
  24#define PD69210_BT_PROD_VER	26
  25#define PD69220_BT_PROD_VER	29
  26
  27#define PD692X0_FW_MAJ_VER	3
  28#define PD692X0_FW_MIN_VER	5
  29#define PD692X0_FW_PATCH_VER	5
  30
  31enum pd692x0_fw_state {
  32	PD692X0_FW_UNKNOWN,
  33	PD692X0_FW_OK,
  34	PD692X0_FW_BROKEN,
  35	PD692X0_FW_NEED_UPDATE,
  36	PD692X0_FW_PREPARE,
  37	PD692X0_FW_WRITE,
  38	PD692X0_FW_COMPLETE,
  39};
  40
  41struct pd692x0_msg {
  42	u8 key;
  43	u8 echo;
  44	u8 sub[3];
  45	u8 data[8];
  46	__be16 chksum;
  47} __packed;
  48
  49struct pd692x0_msg_ver {
  50	u8 prod;
  51	u8 maj_sw_ver;
  52	u8 min_sw_ver;
  53	u8 pa_sw_ver;
  54	u8 param;
  55	u8 build;
  56};
  57
  58enum {
  59	PD692X0_KEY_CMD,
  60	PD692X0_KEY_PRG,
  61	PD692X0_KEY_REQ,
  62	PD692X0_KEY_TLM,
  63	PD692X0_KEY_TEST,
  64	PD692X0_KEY_REPORT = 0x52
  65};
  66
  67enum {
  68	PD692X0_MSG_RESET,
  69	PD692X0_MSG_GET_SYS_STATUS,
  70	PD692X0_MSG_GET_SW_VER,
  71	PD692X0_MSG_SET_TMP_PORT_MATRIX,
  72	PD692X0_MSG_PRG_PORT_MATRIX,
  73	PD692X0_MSG_SET_PORT_PARAM,
  74	PD692X0_MSG_GET_PORT_STATUS,
  75	PD692X0_MSG_DOWNLOAD_CMD,
  76	PD692X0_MSG_GET_PORT_CLASS,
  77	PD692X0_MSG_GET_PORT_MEAS,
  78	PD692X0_MSG_GET_PORT_PARAM,
  79
  80	/* add new message above here */
  81	PD692X0_MSG_CNT
  82};
  83
  84struct pd692x0_priv {
  85	struct i2c_client *client;
  86	struct pse_controller_dev pcdev;
  87	struct device_node *np;
  88
  89	enum pd692x0_fw_state fw_state;
  90	struct fw_upload *fwl;
  91	bool cancel_request;
  92
  93	u8 msg_id;
  94	bool last_cmd_key;
  95	unsigned long last_cmd_key_time;
  96
  97	enum ethtool_c33_pse_admin_state admin_state[PD692X0_MAX_PIS];
  98};
  99
 100/* Template list of communication messages. The non-null bytes defined here
 101 * constitute the fixed portion of the messages. The remaining bytes will
 102 * be configured later within the functions. Refer to the "PD692x0 BT Serial
 103 * Communication Protocol User Guide" for comprehensive details on messages
 104 * content.
 105 */
 106static const struct pd692x0_msg pd692x0_msg_template_list[PD692X0_MSG_CNT] = {
 107	[PD692X0_MSG_RESET] = {
 108		.key = PD692X0_KEY_CMD,
 109		.sub = {0x07, 0x55, 0x00},
 110		.data = {0x55, 0x00, 0x55, 0x4e,
 111			 0x4e, 0x4e, 0x4e, 0x4e},
 112	},
 113	[PD692X0_MSG_GET_SYS_STATUS] = {
 114		.key = PD692X0_KEY_REQ,
 115		.sub = {0x07, 0xd0, 0x4e},
 116		.data = {0x4e, 0x4e, 0x4e, 0x4e,
 117			 0x4e, 0x4e, 0x4e, 0x4e},
 118	},
 119	[PD692X0_MSG_GET_SW_VER] = {
 120		.key = PD692X0_KEY_REQ,
 121		.sub = {0x07, 0x1e, 0x21},
 122		.data = {0x4e, 0x4e, 0x4e, 0x4e,
 123			 0x4e, 0x4e, 0x4e, 0x4e},
 124	},
 125	[PD692X0_MSG_SET_TMP_PORT_MATRIX] = {
 126		.key = PD692X0_KEY_CMD,
 127		.sub	 = {0x05, 0x43},
 128		.data = {   0, 0x4e, 0x4e, 0x4e,
 129			 0x4e, 0x4e, 0x4e, 0x4e},
 130	},
 131	[PD692X0_MSG_PRG_PORT_MATRIX] = {
 132		.key = PD692X0_KEY_CMD,
 133		.sub = {0x07, 0x43, 0x4e},
 134		.data = {0x4e, 0x4e, 0x4e, 0x4e,
 135			 0x4e, 0x4e, 0x4e, 0x4e},
 136	},
 137	[PD692X0_MSG_SET_PORT_PARAM] = {
 138		.key = PD692X0_KEY_CMD,
 139		.sub = {0x05, 0xc0},
 140		.data = { 0xf, 0xff, 0xff, 0xff,
 141			 0x4e, 0x4e, 0x4e, 0x4e},
 142	},
 143	[PD692X0_MSG_GET_PORT_STATUS] = {
 144		.key = PD692X0_KEY_REQ,
 145		.sub = {0x05, 0xc1},
 146		.data = {0x4e, 0x4e, 0x4e, 0x4e,
 147			 0x4e, 0x4e, 0x4e, 0x4e},
 148	},
 149	[PD692X0_MSG_DOWNLOAD_CMD] = {
 150		.key = PD692X0_KEY_PRG,
 151		.sub = {0xff, 0x99, 0x15},
 152		.data = {0x16, 0x16, 0x99, 0x4e,
 153			 0x4e, 0x4e, 0x4e, 0x4e},
 154	},
 155	[PD692X0_MSG_GET_PORT_CLASS] = {
 156		.key = PD692X0_KEY_REQ,
 157		.sub = {0x05, 0xc4},
 158		.data = {0x4e, 0x4e, 0x4e, 0x4e,
 159			 0x4e, 0x4e, 0x4e, 0x4e},
 160	},
 161	[PD692X0_MSG_GET_PORT_MEAS] = {
 162		.key = PD692X0_KEY_REQ,
 163		.sub = {0x05, 0xc5},
 164		.data = {0x4e, 0x4e, 0x4e, 0x4e,
 165			 0x4e, 0x4e, 0x4e, 0x4e},
 166	},
 167	[PD692X0_MSG_GET_PORT_PARAM] = {
 168		.key = PD692X0_KEY_REQ,
 169		.sub = {0x05, 0xc0},
 170		.data = {0x4e, 0x4e, 0x4e, 0x4e,
 171			 0x4e, 0x4e, 0x4e, 0x4e},
 172	},
 173};
 174
 175static u8 pd692x0_build_msg(struct pd692x0_msg *msg, u8 echo)
 176{
 177	u8 *data = (u8 *)msg;
 178	u16 chksum = 0;
 179	int i;
 180
 181	msg->echo = echo++;
 182	if (echo == 0xff)
 183		echo = 0;
 184
 185	for (i = 0; i < sizeof(*msg) - sizeof(msg->chksum); i++)
 186		chksum += data[i];
 187
 188	msg->chksum = cpu_to_be16(chksum);
 189
 190	return echo;
 191}
 192
 193static int pd692x0_send_msg(struct pd692x0_priv *priv, struct pd692x0_msg *msg)
 194{
 195	const struct i2c_client *client = priv->client;
 196	int ret;
 197
 198	if (msg->key == PD692X0_KEY_CMD && priv->last_cmd_key) {
 199		int cmd_msleep;
 200
 201		cmd_msleep = 30 - jiffies_to_msecs(jiffies - priv->last_cmd_key_time);
 202		if (cmd_msleep > 0)
 203			msleep(cmd_msleep);
 204	}
 205
 206	/* Add echo and checksum bytes to the message */
 207	priv->msg_id = pd692x0_build_msg(msg, priv->msg_id);
 208
 209	ret = i2c_master_send(client, (u8 *)msg, sizeof(*msg));
 210	if (ret != sizeof(*msg))
 211		return -EIO;
 212
 213	return 0;
 214}
 215
 216static int pd692x0_reset(struct pd692x0_priv *priv)
 217{
 218	const struct i2c_client *client = priv->client;
 219	struct pd692x0_msg msg, buf = {0};
 220	int ret;
 221
 222	msg = pd692x0_msg_template_list[PD692X0_MSG_RESET];
 223	ret = pd692x0_send_msg(priv, &msg);
 224	if (ret) {
 225		dev_err(&client->dev,
 226			"Failed to reset the controller (%pe)\n", ERR_PTR(ret));
 227		return ret;
 228	}
 229
 230	msleep(30);
 231
 232	ret = i2c_master_recv(client, (u8 *)&buf, sizeof(buf));
 233	if (ret != sizeof(buf))
 234		return ret < 0 ? ret : -EIO;
 235
 236	/* Is the reply a successful report message */
 237	if (buf.key != PD692X0_KEY_REPORT || buf.sub[0] || buf.sub[1])
 238		return -EIO;
 239
 240	msleep(300);
 241
 242	ret = i2c_master_recv(client, (u8 *)&buf, sizeof(buf));
 243	if (ret != sizeof(buf))
 244		return ret < 0 ? ret : -EIO;
 245
 246	/* Is the boot status without error */
 247	if (buf.key != 0x03 || buf.echo != 0xff || buf.sub[0] & 0x1) {
 248		dev_err(&client->dev, "PSE controller error\n");
 249		return -EIO;
 250	}
 251
 252	return 0;
 253}
 254
 255static bool pd692x0_try_recv_msg(const struct i2c_client *client,
 256				 struct pd692x0_msg *msg,
 257				 struct pd692x0_msg *buf)
 258{
 259	/* Wait 30ms before readback as mandated by the protocol */
 260	msleep(30);
 261
 262	memset(buf, 0, sizeof(*buf));
 263	i2c_master_recv(client, (u8 *)buf, sizeof(*buf));
 264	if (buf->key)
 265		return 0;
 266
 267	msleep(100);
 268
 269	memset(buf, 0, sizeof(*buf));
 270	i2c_master_recv(client, (u8 *)buf, sizeof(*buf));
 271	if (buf->key)
 272		return 0;
 273
 274	return 1;
 275}
 276
 277/* Implementation of I2C communication, specifically addressing scenarios
 278 * involving communication loss. Refer to the "Synchronization During
 279 * Communication Loss" section in the Communication Protocol document for
 280 * further details.
 281 */
 282static int pd692x0_recv_msg(struct pd692x0_priv *priv,
 283			    struct pd692x0_msg *msg,
 284			    struct pd692x0_msg *buf)
 285{
 286	const struct i2c_client *client = priv->client;
 287	int ret;
 288
 289	ret = pd692x0_try_recv_msg(client, msg, buf);
 290	if (!ret)
 291		goto out_success;
 292
 293	dev_warn(&client->dev,
 294		 "Communication lost, rtnl is locked until communication is back!");
 295
 296	ret = pd692x0_send_msg(priv, msg);
 297	if (ret)
 298		return ret;
 299
 300	ret = pd692x0_try_recv_msg(client, msg, buf);
 301	if (!ret)
 302		goto out_success2;
 303
 304	msleep(10000);
 305
 306	ret = pd692x0_send_msg(priv, msg);
 307	if (ret)
 308		return ret;
 309
 310	ret = pd692x0_try_recv_msg(client, msg, buf);
 311	if (!ret)
 312		goto out_success2;
 313
 314	return pd692x0_reset(priv);
 315
 316out_success2:
 317	dev_warn(&client->dev, "Communication is back, rtnl is unlocked!");
 318out_success:
 319	if (msg->key == PD692X0_KEY_CMD) {
 320		priv->last_cmd_key = true;
 321		priv->last_cmd_key_time = jiffies;
 322	} else {
 323		priv->last_cmd_key = false;
 324	}
 325
 326	return 0;
 327}
 328
 329static int pd692x0_sendrecv_msg(struct pd692x0_priv *priv,
 330				struct pd692x0_msg *msg,
 331				struct pd692x0_msg *buf)
 332{
 333	struct device *dev = &priv->client->dev;
 334	int ret;
 335
 336	ret = pd692x0_send_msg(priv, msg);
 337	if (ret)
 338		return ret;
 339
 340	ret = pd692x0_recv_msg(priv, msg, buf);
 341	if (ret)
 342		return ret;
 343
 344	if (msg->echo != buf->echo) {
 345		dev_err(dev,
 346			"Wrong match in message ID, expect %d received %d.\n",
 347			msg->echo, buf->echo);
 348		return -EIO;
 349	}
 350
 351	/* If the reply is a report message is it successful */
 352	if (buf->key == PD692X0_KEY_REPORT &&
 353	    (buf->sub[0] || buf->sub[1])) {
 354		return -EIO;
 355	}
 356
 357	return 0;
 358}
 359
 360static struct pd692x0_priv *to_pd692x0_priv(struct pse_controller_dev *pcdev)
 361{
 362	return container_of(pcdev, struct pd692x0_priv, pcdev);
 363}
 364
 365static int pd692x0_fw_unavailable(struct pd692x0_priv *priv)
 366{
 367	switch (priv->fw_state) {
 368	case PD692X0_FW_OK:
 369		return 0;
 370	case PD692X0_FW_PREPARE:
 371	case PD692X0_FW_WRITE:
 372	case PD692X0_FW_COMPLETE:
 373		dev_err(&priv->client->dev, "Firmware update in progress!\n");
 374		return -EBUSY;
 375	case PD692X0_FW_BROKEN:
 376	case PD692X0_FW_NEED_UPDATE:
 377	default:
 378		dev_err(&priv->client->dev,
 379			"Firmware issue. Please update it!\n");
 380		return -EOPNOTSUPP;
 381	}
 382}
 383
 384static int pd692x0_pi_enable(struct pse_controller_dev *pcdev, int id)
 385{
 386	struct pd692x0_priv *priv = to_pd692x0_priv(pcdev);
 387	struct pd692x0_msg msg, buf = {0};
 388	int ret;
 389
 390	ret = pd692x0_fw_unavailable(priv);
 391	if (ret)
 392		return ret;
 393
 394	if (priv->admin_state[id] == ETHTOOL_C33_PSE_ADMIN_STATE_ENABLED)
 395		return 0;
 396
 397	msg = pd692x0_msg_template_list[PD692X0_MSG_SET_PORT_PARAM];
 398	msg.data[0] = 0x1;
 399	msg.sub[2] = id;
 400	ret = pd692x0_sendrecv_msg(priv, &msg, &buf);
 401	if (ret < 0)
 402		return ret;
 403
 404	priv->admin_state[id] = ETHTOOL_C33_PSE_ADMIN_STATE_ENABLED;
 405
 406	return 0;
 407}
 408
 409static int pd692x0_pi_disable(struct pse_controller_dev *pcdev, int id)
 410{
 411	struct pd692x0_priv *priv = to_pd692x0_priv(pcdev);
 412	struct pd692x0_msg msg, buf = {0};
 413	int ret;
 414
 415	ret = pd692x0_fw_unavailable(priv);
 416	if (ret)
 417		return ret;
 418
 419	if (priv->admin_state[id] == ETHTOOL_C33_PSE_ADMIN_STATE_DISABLED)
 420		return 0;
 421
 422	msg = pd692x0_msg_template_list[PD692X0_MSG_SET_PORT_PARAM];
 423	msg.data[0] = 0x0;
 424	msg.sub[2] = id;
 425	ret = pd692x0_sendrecv_msg(priv, &msg, &buf);
 426	if (ret < 0)
 427		return ret;
 428
 429	priv->admin_state[id] = ETHTOOL_C33_PSE_ADMIN_STATE_DISABLED;
 430
 431	return 0;
 432}
 433
 434static int pd692x0_pi_is_enabled(struct pse_controller_dev *pcdev, int id)
 435{
 436	struct pd692x0_priv *priv = to_pd692x0_priv(pcdev);
 437	struct pd692x0_msg msg, buf = {0};
 438	int ret;
 439
 440	ret = pd692x0_fw_unavailable(priv);
 441	if (ret)
 442		return ret;
 443
 444	msg = pd692x0_msg_template_list[PD692X0_MSG_GET_PORT_STATUS];
 445	msg.sub[2] = id;
 446	ret = pd692x0_sendrecv_msg(priv, &msg, &buf);
 447	if (ret < 0)
 448		return ret;
 449
 450	if (buf.sub[1]) {
 451		priv->admin_state[id] = ETHTOOL_C33_PSE_ADMIN_STATE_ENABLED;
 452		return 1;
 453	} else {
 454		priv->admin_state[id] = ETHTOOL_C33_PSE_ADMIN_STATE_DISABLED;
 455		return 0;
 456	}
 457}
 458
 459struct pd692x0_pse_ext_state_mapping {
 460	u32 status_code;
 461	enum ethtool_c33_pse_ext_state pse_ext_state;
 462	u32 pse_ext_substate;
 463};
 464
 465static const struct pd692x0_pse_ext_state_mapping
 466pd692x0_pse_ext_state_map[] = {
 467	{0x06, ETHTOOL_C33_PSE_EXT_STATE_OPTION_VPORT_LIM,
 468		ETHTOOL_C33_PSE_EXT_SUBSTATE_OPTION_VPORT_LIM_HIGH_VOLTAGE},
 469	{0x07, ETHTOOL_C33_PSE_EXT_STATE_OPTION_VPORT_LIM,
 470		ETHTOOL_C33_PSE_EXT_SUBSTATE_OPTION_VPORT_LIM_LOW_VOLTAGE},
 471	{0x08, ETHTOOL_C33_PSE_EXT_STATE_MR_PSE_ENABLE,
 472		ETHTOOL_C33_PSE_EXT_SUBSTATE_MR_PSE_ENABLE_DISABLE_PIN_ACTIVE},
 473	{0x0C, ETHTOOL_C33_PSE_EXT_STATE_ERROR_CONDITION,
 474		ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_NON_EXISTING_PORT},
 475	{0x11, ETHTOOL_C33_PSE_EXT_STATE_ERROR_CONDITION,
 476		ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_UNDEFINED_PORT},
 477	{0x12, ETHTOOL_C33_PSE_EXT_STATE_ERROR_CONDITION,
 478		ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_INTERNAL_HW_FAULT},
 479	{0x1B, ETHTOOL_C33_PSE_EXT_STATE_OPTION_DETECT_TED,
 480		ETHTOOL_C33_PSE_EXT_SUBSTATE_OPTION_DETECT_TED_DET_IN_PROCESS},
 481	{0x1C, ETHTOOL_C33_PSE_EXT_STATE_ERROR_CONDITION,
 482		ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_UNKNOWN_PORT_STATUS},
 483	{0x1E, ETHTOOL_C33_PSE_EXT_STATE_MR_MPS_VALID,
 484		ETHTOOL_C33_PSE_EXT_SUBSTATE_MR_MPS_VALID_DETECTED_UNDERLOAD},
 485	{0x1F, ETHTOOL_C33_PSE_EXT_STATE_OVLD_DETECTED,
 486		ETHTOOL_C33_PSE_EXT_SUBSTATE_OVLD_DETECTED_OVERLOAD},
 487	{0x20, ETHTOOL_C33_PSE_EXT_STATE_POWER_NOT_AVAILABLE,
 488		ETHTOOL_C33_PSE_EXT_SUBSTATE_POWER_NOT_AVAILABLE_BUDGET_EXCEEDED},
 489	{0x21, ETHTOOL_C33_PSE_EXT_STATE_ERROR_CONDITION,
 490		ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_INTERNAL_HW_FAULT},
 491	{0x22, ETHTOOL_C33_PSE_EXT_STATE_ERROR_CONDITION,
 492		ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_CONFIG_CHANGE},
 493	{0x24, ETHTOOL_C33_PSE_EXT_STATE_OPTION_VPORT_LIM,
 494		ETHTOOL_C33_PSE_EXT_SUBSTATE_OPTION_VPORT_LIM_VOLTAGE_INJECTION},
 495	{0x25, ETHTOOL_C33_PSE_EXT_STATE_ERROR_CONDITION,
 496		ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_UNKNOWN_PORT_STATUS},
 497	{0x34, ETHTOOL_C33_PSE_EXT_STATE_SHORT_DETECTED,
 498		ETHTOOL_C33_PSE_EXT_SUBSTATE_SHORT_DETECTED_SHORT_CONDITION},
 499	{0x35, ETHTOOL_C33_PSE_EXT_STATE_ERROR_CONDITION,
 500		ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_DETECTED_OVER_TEMP},
 501	{0x36, ETHTOOL_C33_PSE_EXT_STATE_ERROR_CONDITION,
 502		ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_DETECTED_OVER_TEMP},
 503	{0x37, ETHTOOL_C33_PSE_EXT_STATE_ERROR_CONDITION,
 504		ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_UNKNOWN_PORT_STATUS},
 505	{0x3C, ETHTOOL_C33_PSE_EXT_STATE_POWER_NOT_AVAILABLE,
 506		ETHTOOL_C33_PSE_EXT_SUBSTATE_POWER_NOT_AVAILABLE_PORT_PW_LIMIT_EXCEEDS_CONTROLLER_BUDGET},
 507	{0x3D, ETHTOOL_C33_PSE_EXT_STATE_POWER_NOT_AVAILABLE,
 508		ETHTOOL_C33_PSE_EXT_SUBSTATE_POWER_NOT_AVAILABLE_PD_REQUEST_EXCEEDS_PORT_LIMIT},
 509	{0x41, ETHTOOL_C33_PSE_EXT_STATE_POWER_NOT_AVAILABLE,
 510		ETHTOOL_C33_PSE_EXT_SUBSTATE_POWER_NOT_AVAILABLE_HW_PW_LIMIT},
 511	{0x43, ETHTOOL_C33_PSE_EXT_STATE_ERROR_CONDITION,
 512		ETHTOOL_C33_PSE_EXT_SUBSTATE_ERROR_CONDITION_UNKNOWN_PORT_STATUS},
 513	{0xA7, ETHTOOL_C33_PSE_EXT_STATE_OPTION_DETECT_TED,
 514		ETHTOOL_C33_PSE_EXT_SUBSTATE_OPTION_DETECT_TED_CONNECTION_CHECK_ERROR},
 515	{0xA8, ETHTOOL_C33_PSE_EXT_STATE_MR_MPS_VALID,
 516		ETHTOOL_C33_PSE_EXT_SUBSTATE_MR_MPS_VALID_CONNECTION_OPEN},
 517	{ /* sentinel */ }
 518};
 519
 520static void
 521pd692x0_get_ext_state(struct ethtool_c33_pse_ext_state_info *c33_ext_state_info,
 522		      u32 status_code)
 523{
 524	const struct pd692x0_pse_ext_state_mapping *ext_state_map;
 525
 526	ext_state_map = pd692x0_pse_ext_state_map;
 527	while (ext_state_map->status_code) {
 528		if (ext_state_map->status_code == status_code) {
 529			c33_ext_state_info->c33_pse_ext_state = ext_state_map->pse_ext_state;
 530			c33_ext_state_info->__c33_pse_ext_substate = ext_state_map->pse_ext_substate;
 531			return;
 532		}
 533		ext_state_map++;
 534	}
 535}
 536
 537struct pd692x0_class_pw {
 538	int class;
 539	int class_cfg_value;
 540	int class_pw;
 541	int max_added_class_pw;
 542};
 543
 544#define PD692X0_CLASS_PW_TABLE_SIZE 4
 545/* 4/2 pairs class configuration power table in compliance mode.
 546 * Need to be arranged in ascending order of power support.
 547 */
 548static const struct pd692x0_class_pw
 549pd692x0_class_pw_table[PD692X0_CLASS_PW_TABLE_SIZE] = {
 550	{.class = 3, .class_cfg_value = 0x3, .class_pw = 15000, .max_added_class_pw = 3100},
 551	{.class = 4, .class_cfg_value = 0x2, .class_pw = 30000, .max_added_class_pw = 8000},
 552	{.class = 6, .class_cfg_value = 0x1, .class_pw = 60000, .max_added_class_pw = 5000},
 553	{.class = 8, .class_cfg_value = 0x0, .class_pw = 90000, .max_added_class_pw = 7500},
 554};
 555
 556static int pd692x0_pi_get_pw_from_table(int op_mode, int added_pw)
 557{
 558	const struct pd692x0_class_pw *pw_table;
 559	int i;
 560
 561	pw_table = pd692x0_class_pw_table;
 562	for (i = 0; i < PD692X0_CLASS_PW_TABLE_SIZE; i++, pw_table++) {
 563		if (pw_table->class_cfg_value == op_mode)
 564			return pw_table->class_pw + added_pw * 100;
 565	}
 566
 567	return -ERANGE;
 568}
 569
 570static int pd692x0_pi_set_pw_from_table(struct device *dev,
 571					struct pd692x0_msg *msg, int pw)
 572{
 573	const struct pd692x0_class_pw *pw_table;
 574	int i;
 575
 576	pw_table = pd692x0_class_pw_table;
 577	if (pw < pw_table->class_pw) {
 578		dev_err(dev,
 579			"Power limit %dmW not supported. Ranges minimal available: [%d-%d]\n",
 580			pw,
 581			pw_table->class_pw,
 582			pw_table->class_pw + pw_table->max_added_class_pw);
 583		return -ERANGE;
 584	}
 585
 586	for (i = 0; i < PD692X0_CLASS_PW_TABLE_SIZE; i++, pw_table++) {
 587		if (pw > (pw_table->class_pw + pw_table->max_added_class_pw))
 588			continue;
 589
 590		if (pw < pw_table->class_pw) {
 591			dev_err(dev,
 592				"Power limit %dmW not supported. Ranges available: [%d-%d] or [%d-%d]\n",
 593				pw,
 594				(pw_table - 1)->class_pw,
 595				(pw_table - 1)->class_pw + (pw_table - 1)->max_added_class_pw,
 596				pw_table->class_pw,
 597				pw_table->class_pw + pw_table->max_added_class_pw);
 598			return -ERANGE;
 599		}
 600
 601		msg->data[2] = pw_table->class_cfg_value;
 602		msg->data[3] = (pw - pw_table->class_pw) / 100;
 603		return 0;
 604	}
 605
 606	pw_table--;
 607	dev_warn(dev,
 608		 "Power limit %dmW not supported. Set to highest power limit %dmW\n",
 609		 pw, pw_table->class_pw + pw_table->max_added_class_pw);
 610	msg->data[2] = pw_table->class_cfg_value;
 611	msg->data[3] = pw_table->max_added_class_pw / 100;
 612	return 0;
 613}
 614
 615static int
 616pd692x0_pi_get_pw_ranges(struct pse_control_status *st)
 617{
 618	const struct pd692x0_class_pw *pw_table;
 619	int i;
 620
 621	pw_table = pd692x0_class_pw_table;
 622	st->c33_pw_limit_ranges = kcalloc(PD692X0_CLASS_PW_TABLE_SIZE,
 623					  sizeof(struct ethtool_c33_pse_pw_limit_range),
 624					  GFP_KERNEL);
 625	if (!st->c33_pw_limit_ranges)
 626		return -ENOMEM;
 627
 628	for (i = 0; i < PD692X0_CLASS_PW_TABLE_SIZE; i++, pw_table++) {
 629		st->c33_pw_limit_ranges[i].min = pw_table->class_pw;
 630		st->c33_pw_limit_ranges[i].max = pw_table->class_pw + pw_table->max_added_class_pw;
 631	}
 632
 633	st->c33_pw_limit_nb_ranges = i;
 634	return 0;
 635}
 636
 637static int pd692x0_ethtool_get_status(struct pse_controller_dev *pcdev,
 638				      unsigned long id,
 639				      struct netlink_ext_ack *extack,
 640				      struct pse_control_status *status)
 641{
 642	struct pd692x0_priv *priv = to_pd692x0_priv(pcdev);
 643	struct pd692x0_msg msg, buf = {0};
 644	u32 class;
 645	int ret;
 646
 647	ret = pd692x0_fw_unavailable(priv);
 648	if (ret)
 649		return ret;
 650
 651	msg = pd692x0_msg_template_list[PD692X0_MSG_GET_PORT_STATUS];
 652	msg.sub[2] = id;
 653	ret = pd692x0_sendrecv_msg(priv, &msg, &buf);
 654	if (ret < 0)
 655		return ret;
 656
 657	/* Compare Port Status (Communication Protocol Document par. 7.1) */
 658	if ((buf.sub[0] & 0xf0) == 0x80 || (buf.sub[0] & 0xf0) == 0x90)
 659		status->c33_pw_status = ETHTOOL_C33_PSE_PW_D_STATUS_DELIVERING;
 660	else if (buf.sub[0] == 0x1b || buf.sub[0] == 0x22)
 661		status->c33_pw_status = ETHTOOL_C33_PSE_PW_D_STATUS_SEARCHING;
 662	else if (buf.sub[0] == 0x12)
 663		status->c33_pw_status = ETHTOOL_C33_PSE_PW_D_STATUS_FAULT;
 664	else
 665		status->c33_pw_status = ETHTOOL_C33_PSE_PW_D_STATUS_DISABLED;
 666
 667	if (buf.sub[1])
 668		status->c33_admin_state = ETHTOOL_C33_PSE_ADMIN_STATE_ENABLED;
 669	else
 670		status->c33_admin_state = ETHTOOL_C33_PSE_ADMIN_STATE_DISABLED;
 671
 672	priv->admin_state[id] = status->c33_admin_state;
 673
 674	pd692x0_get_ext_state(&status->c33_ext_state_info, buf.sub[0]);
 675	status->c33_actual_pw = (buf.data[0] << 4 | buf.data[1]) * 100;
 676
 677	msg = pd692x0_msg_template_list[PD692X0_MSG_GET_PORT_PARAM];
 678	msg.sub[2] = id;
 679	memset(&buf, 0, sizeof(buf));
 680	ret = pd692x0_sendrecv_msg(priv, &msg, &buf);
 681	if (ret < 0)
 682		return ret;
 683
 684	ret = pd692x0_pi_get_pw_from_table(buf.data[0], buf.data[1]);
 685	if (ret < 0)
 686		return ret;
 687	status->c33_avail_pw_limit = ret;
 688
 689	memset(&buf, 0, sizeof(buf));
 690	msg = pd692x0_msg_template_list[PD692X0_MSG_GET_PORT_CLASS];
 691	msg.sub[2] = id;
 692	ret = pd692x0_sendrecv_msg(priv, &msg, &buf);
 693	if (ret < 0)
 694		return ret;
 695
 696	class = buf.data[3] >> 4;
 697	if (class <= 8)
 698		status->c33_pw_class = class;
 699
 700	ret = pd692x0_pi_get_pw_ranges(status);
 701	if (ret < 0)
 702		return ret;
 703
 704	return 0;
 705}
 706
 707static struct pd692x0_msg_ver pd692x0_get_sw_version(struct pd692x0_priv *priv)
 708{
 709	struct device *dev = &priv->client->dev;
 710	struct pd692x0_msg msg, buf = {0};
 711	struct pd692x0_msg_ver ver = {0};
 712	int ret;
 713
 714	msg = pd692x0_msg_template_list[PD692X0_MSG_GET_SW_VER];
 715	ret = pd692x0_sendrecv_msg(priv, &msg, &buf);
 716	if (ret < 0) {
 717		dev_err(dev, "Failed to get PSE version (%pe)\n", ERR_PTR(ret));
 718		return ver;
 719	}
 720
 721	/* Extract version from the message */
 722	ver.prod = buf.sub[2];
 723	ver.maj_sw_ver = (buf.data[0] << 8 | buf.data[1]) / 100;
 724	ver.min_sw_ver = ((buf.data[0] << 8 | buf.data[1]) / 10) % 10;
 725	ver.pa_sw_ver = (buf.data[0] << 8 | buf.data[1]) % 10;
 726	ver.param = buf.data[2];
 727	ver.build = buf.data[3];
 728
 729	return ver;
 730}
 731
 732struct pd692x0_manager {
 733	struct device_node *port_node[PD692X0_MAX_MANAGER_PORTS];
 734	int nports;
 735};
 736
 737struct pd692x0_matrix {
 738	u8 hw_port_a;
 739	u8 hw_port_b;
 740};
 741
 742static int
 743pd692x0_of_get_ports_manager(struct pd692x0_priv *priv,
 744			     struct pd692x0_manager *manager,
 745			     struct device_node *np)
 746{
 747	struct device_node *node;
 748	int ret, nports, i;
 749
 750	nports = 0;
 751	for_each_child_of_node(np, node) {
 752		u32 port;
 753
 754		if (!of_node_name_eq(node, "port"))
 755			continue;
 756
 757		ret = of_property_read_u32(node, "reg", &port);
 758		if (ret)
 759			goto out;
 760
 761		if (port >= PD692X0_MAX_MANAGER_PORTS || port != nports) {
 762			dev_err(&priv->client->dev,
 763				"wrong number or order of manager ports (%d)\n",
 764				port);
 765			ret = -EINVAL;
 766			goto out;
 767		}
 768
 769		of_node_get(node);
 770		manager->port_node[port] = node;
 771		nports++;
 772	}
 773
 774	manager->nports = nports;
 775	return 0;
 776
 777out:
 778	for (i = 0; i < nports; i++) {
 779		of_node_put(manager->port_node[i]);
 780		manager->port_node[i] = NULL;
 781	}
 782	of_node_put(node);
 783	return ret;
 784}
 785
 786static int
 787pd692x0_of_get_managers(struct pd692x0_priv *priv,
 788			struct pd692x0_manager manager[PD692X0_MAX_MANAGERS])
 789{
 790	struct device_node *managers_node, *node;
 791	int ret, nmanagers, i, j;
 792
 793	if (!priv->np)
 794		return -EINVAL;
 795
 796	nmanagers = 0;
 797	managers_node = of_get_child_by_name(priv->np, "managers");
 798	if (!managers_node)
 799		return -EINVAL;
 800
 801	for_each_child_of_node(managers_node, node) {
 802		u32 manager_id;
 803
 804		if (!of_node_name_eq(node, "manager"))
 805			continue;
 806
 807		ret = of_property_read_u32(node, "reg", &manager_id);
 808		if (ret)
 809			goto out;
 810
 811		if (manager_id >= PD692X0_MAX_MANAGERS ||
 812		    manager_id != nmanagers) {
 813			dev_err(&priv->client->dev,
 814				"wrong number or order of managers (%d)\n",
 815				manager_id);
 816			ret = -EINVAL;
 817			goto out;
 818		}
 819
 820		ret = pd692x0_of_get_ports_manager(priv, &manager[manager_id],
 821						   node);
 822		if (ret)
 823			goto out;
 824
 825		nmanagers++;
 826	}
 827
 828	of_node_put(managers_node);
 829	return nmanagers;
 830
 831out:
 832	for (i = 0; i < nmanagers; i++) {
 833		for (j = 0; j < manager[i].nports; j++) {
 834			of_node_put(manager[i].port_node[j]);
 835			manager[i].port_node[j] = NULL;
 836		}
 837	}
 838
 839	of_node_put(node);
 840	of_node_put(managers_node);
 841	return ret;
 842}
 843
 844static int
 845pd692x0_set_port_matrix(const struct pse_pi_pairset *pairset,
 846			const struct pd692x0_manager *manager,
 847			int nmanagers, struct pd692x0_matrix *port_matrix)
 848{
 849	int i, j, port_cnt;
 850	bool found = false;
 851
 852	if (!pairset->np)
 853		return 0;
 854
 855	/* Look on every managers */
 856	port_cnt = 0;
 857	for (i = 0; i < nmanagers; i++) {
 858		/* Look on every ports of the manager */
 859		for (j = 0; j < manager[i].nports; j++) {
 860			if (pairset->np == manager[i].port_node[j]) {
 861				found = true;
 862				break;
 863			}
 864		}
 865		port_cnt += j;
 866
 867		if (found)
 868			break;
 869	}
 870
 871	if (!found)
 872		return -ENODEV;
 873
 874	if (pairset->pinout == ALTERNATIVE_A)
 875		port_matrix->hw_port_a = port_cnt;
 876	else if (pairset->pinout == ALTERNATIVE_B)
 877		port_matrix->hw_port_b = port_cnt;
 878
 879	return 0;
 880}
 881
 882static int
 883pd692x0_set_ports_matrix(struct pd692x0_priv *priv,
 884			 const struct pd692x0_manager *manager,
 885			 int nmanagers,
 886			 struct pd692x0_matrix port_matrix[PD692X0_MAX_PIS])
 887{
 888	struct pse_controller_dev *pcdev = &priv->pcdev;
 889	int i, ret;
 890
 891	/* Init Matrix */
 892	for (i = 0; i < PD692X0_MAX_PIS; i++) {
 893		port_matrix[i].hw_port_a = 0xff;
 894		port_matrix[i].hw_port_b = 0xff;
 895	}
 896
 897	/* Update with values for every PSE PIs */
 898	for (i = 0; i < pcdev->nr_lines; i++) {
 899		ret = pd692x0_set_port_matrix(&pcdev->pi[i].pairset[0],
 900					      manager, nmanagers,
 901					      &port_matrix[i]);
 902		if (ret) {
 903			dev_err(&priv->client->dev,
 904				"unable to configure pi %d pairset 0", i);
 905			return ret;
 906		}
 907
 908		ret = pd692x0_set_port_matrix(&pcdev->pi[i].pairset[1],
 909					      manager, nmanagers,
 910					      &port_matrix[i]);
 911		if (ret) {
 912			dev_err(&priv->client->dev,
 913				"unable to configure pi %d pairset 1", i);
 914			return ret;
 915		}
 916	}
 917
 918	return 0;
 919}
 920
 921static int
 922pd692x0_write_ports_matrix(struct pd692x0_priv *priv,
 923			   const struct pd692x0_matrix port_matrix[PD692X0_MAX_PIS])
 924{
 925	struct pd692x0_msg msg, buf;
 926	int ret, i;
 927
 928	/* Write temporary Matrix */
 929	msg = pd692x0_msg_template_list[PD692X0_MSG_SET_TMP_PORT_MATRIX];
 930	for (i = 0; i < PD692X0_MAX_PIS; i++) {
 931		msg.sub[2] = i;
 932		msg.data[0] = port_matrix[i].hw_port_b;
 933		msg.data[1] = port_matrix[i].hw_port_a;
 934
 935		ret = pd692x0_sendrecv_msg(priv, &msg, &buf);
 936		if (ret < 0)
 937			return ret;
 938	}
 939
 940	/* Program Matrix */
 941	msg = pd692x0_msg_template_list[PD692X0_MSG_PRG_PORT_MATRIX];
 942	ret = pd692x0_sendrecv_msg(priv, &msg, &buf);
 943	if (ret < 0)
 944		return ret;
 945
 946	return 0;
 947}
 948
 949static int pd692x0_setup_pi_matrix(struct pse_controller_dev *pcdev)
 950{
 951	struct pd692x0_manager manager[PD692X0_MAX_MANAGERS] = {0};
 952	struct pd692x0_priv *priv = to_pd692x0_priv(pcdev);
 953	struct pd692x0_matrix port_matrix[PD692X0_MAX_PIS];
 954	int ret, i, j, nmanagers;
 955
 956	/* Should we flash the port matrix */
 957	if (priv->fw_state != PD692X0_FW_OK &&
 958	    priv->fw_state != PD692X0_FW_COMPLETE)
 959		return 0;
 960
 961	ret = pd692x0_of_get_managers(priv, manager);
 962	if (ret < 0)
 963		return ret;
 964
 965	nmanagers = ret;
 966	ret = pd692x0_set_ports_matrix(priv, manager, nmanagers, port_matrix);
 967	if (ret)
 968		goto out;
 969
 970	ret = pd692x0_write_ports_matrix(priv, port_matrix);
 971	if (ret)
 972		goto out;
 973
 974out:
 975	for (i = 0; i < nmanagers; i++) {
 976		for (j = 0; j < manager[i].nports; j++)
 977			of_node_put(manager[i].port_node[j]);
 978	}
 979	return ret;
 980}
 981
 982static int pd692x0_pi_get_voltage(struct pse_controller_dev *pcdev, int id)
 983{
 984	struct pd692x0_priv *priv = to_pd692x0_priv(pcdev);
 985	struct pd692x0_msg msg, buf = {0};
 986	int ret;
 987
 988	ret = pd692x0_fw_unavailable(priv);
 989	if (ret)
 990		return ret;
 991
 992	msg = pd692x0_msg_template_list[PD692X0_MSG_GET_PORT_MEAS];
 993	msg.sub[2] = id;
 994	ret = pd692x0_sendrecv_msg(priv, &msg, &buf);
 995	if (ret < 0)
 996		return ret;
 997
 998	/* Convert 0.1V unit to uV */
 999	return (buf.sub[0] << 8 | buf.sub[1]) * 100000;
1000}
1001
1002static int pd692x0_pi_get_pw_limit(struct pse_controller_dev *pcdev,
1003				   int id)
1004{
1005	struct pd692x0_priv *priv = to_pd692x0_priv(pcdev);
1006	struct pd692x0_msg msg, buf = {0};
1007	int ret;
1008
1009	msg = pd692x0_msg_template_list[PD692X0_MSG_GET_PORT_PARAM];
1010	msg.sub[2] = id;
1011	ret = pd692x0_sendrecv_msg(priv, &msg, &buf);
1012	if (ret < 0)
1013		return ret;
1014
1015	return pd692x0_pi_get_pw_from_table(buf.data[0], buf.data[1]);
1016}
1017
1018static int pd692x0_pi_set_pw_limit(struct pse_controller_dev *pcdev,
1019				   int id, int max_mW)
1020{
1021	struct pd692x0_priv *priv = to_pd692x0_priv(pcdev);
1022	struct device *dev = &priv->client->dev;
1023	struct pd692x0_msg msg, buf = {0};
1024	int ret;
1025
1026	ret = pd692x0_fw_unavailable(priv);
1027	if (ret)
1028		return ret;
1029
1030	msg = pd692x0_msg_template_list[PD692X0_MSG_SET_PORT_PARAM];
1031	msg.sub[2] = id;
1032	ret = pd692x0_pi_set_pw_from_table(dev, &msg, max_mW);
1033	if (ret)
1034		return ret;
1035
1036	return pd692x0_sendrecv_msg(priv, &msg, &buf);
1037}
1038
1039static const struct pse_controller_ops pd692x0_ops = {
1040	.setup_pi_matrix = pd692x0_setup_pi_matrix,
1041	.ethtool_get_status = pd692x0_ethtool_get_status,
1042	.pi_enable = pd692x0_pi_enable,
1043	.pi_disable = pd692x0_pi_disable,
1044	.pi_is_enabled = pd692x0_pi_is_enabled,
1045	.pi_get_voltage = pd692x0_pi_get_voltage,
1046	.pi_get_pw_limit = pd692x0_pi_get_pw_limit,
1047	.pi_set_pw_limit = pd692x0_pi_set_pw_limit,
1048};
1049
1050#define PD692X0_FW_LINE_MAX_SZ 0xff
1051static int pd692x0_fw_get_next_line(const u8 *data,
1052				    char *line, size_t size)
1053{
1054	size_t line_size;
1055	int i;
1056
1057	line_size = min_t(size_t, size, PD692X0_FW_LINE_MAX_SZ);
1058
1059	memset(line, 0, PD692X0_FW_LINE_MAX_SZ);
1060	for (i = 0; i < line_size - 1; i++) {
1061		if (*data == '\r' && *(data + 1) == '\n') {
1062			line[i] = '\r';
1063			line[i + 1] = '\n';
1064			return i + 2;
1065		}
1066		line[i] = *data;
1067		data++;
1068	}
1069
1070	return -EIO;
1071}
1072
1073static enum fw_upload_err
1074pd692x0_fw_recv_resp(const struct i2c_client *client, unsigned long ms_timeout,
1075		     const char *msg_ok, unsigned int msg_size)
1076{
1077	/* Maximum controller response size */
1078	char fw_msg_buf[5] = {0};
1079	unsigned long timeout;
1080	int ret;
1081
1082	if (msg_size > sizeof(fw_msg_buf))
1083		return FW_UPLOAD_ERR_RW_ERROR;
1084
1085	/* Read until we get something */
1086	timeout = msecs_to_jiffies(ms_timeout) + jiffies;
1087	while (true) {
1088		if (time_is_before_jiffies(timeout))
1089			return FW_UPLOAD_ERR_TIMEOUT;
1090
1091		ret = i2c_master_recv(client, fw_msg_buf, 1);
1092		if (ret < 0 || *fw_msg_buf == 0) {
1093			usleep_range(1000, 2000);
1094			continue;
1095		} else {
1096			break;
1097		}
1098	}
1099
1100	/* Read remaining characters */
1101	ret = i2c_master_recv(client, fw_msg_buf + 1, msg_size - 1);
1102	if (strncmp(fw_msg_buf, msg_ok, msg_size)) {
1103		dev_err(&client->dev,
1104			"Wrong FW download process answer (%*pE)\n",
1105			msg_size, fw_msg_buf);
1106		return FW_UPLOAD_ERR_HW_ERROR;
1107	}
1108
1109	return FW_UPLOAD_ERR_NONE;
1110}
1111
1112static int pd692x0_fw_write_line(const struct i2c_client *client,
1113				 const char line[PD692X0_FW_LINE_MAX_SZ],
1114				 const bool last_line)
1115{
1116	int ret;
1117
1118	while (*line != 0) {
1119		ret = i2c_master_send(client, line, 1);
1120		if (ret < 0)
1121			return FW_UPLOAD_ERR_RW_ERROR;
1122		line++;
1123	}
1124
1125	if (last_line) {
1126		ret = pd692x0_fw_recv_resp(client, 100, "TP\r\n",
1127					   sizeof("TP\r\n") - 1);
1128		if (ret)
1129			return ret;
1130	} else {
1131		ret = pd692x0_fw_recv_resp(client, 100, "T*\r\n",
1132					   sizeof("T*\r\n") - 1);
1133		if (ret)
1134			return ret;
1135	}
1136
1137	return FW_UPLOAD_ERR_NONE;
1138}
1139
1140static enum fw_upload_err pd692x0_fw_reset(const struct i2c_client *client)
1141{
1142	const struct pd692x0_msg zero = {0};
1143	struct pd692x0_msg buf = {0};
1144	unsigned long timeout;
1145	char cmd[] = "RST";
1146	int ret;
1147
1148	ret = i2c_master_send(client, cmd, strlen(cmd));
1149	if (ret < 0) {
1150		dev_err(&client->dev,
1151			"Failed to reset the controller (%pe)\n",
1152			ERR_PTR(ret));
1153		return ret;
1154	}
1155
1156	timeout = msecs_to_jiffies(10000) + jiffies;
1157	while (true) {
1158		if (time_is_before_jiffies(timeout))
1159			return FW_UPLOAD_ERR_TIMEOUT;
1160
1161		ret = i2c_master_recv(client, (u8 *)&buf, sizeof(buf));
1162		if (ret < 0 ||
1163		    !memcmp(&buf, &zero, sizeof(buf)))
1164			usleep_range(1000, 2000);
1165		else
1166			break;
1167	}
1168
1169	/* Is the reply a successful report message */
1170	if (buf.key != PD692X0_KEY_TLM || buf.echo != 0xff ||
1171	    buf.sub[0] & 0x01) {
1172		dev_err(&client->dev, "PSE controller error\n");
1173		return FW_UPLOAD_ERR_HW_ERROR;
1174	}
1175
1176	/* Is the firmware operational */
1177	if (buf.sub[0] & 0x02) {
1178		dev_err(&client->dev,
1179			"PSE firmware error. Please update it.\n");
1180		return FW_UPLOAD_ERR_HW_ERROR;
1181	}
1182
1183	return FW_UPLOAD_ERR_NONE;
1184}
1185
1186static enum fw_upload_err pd692x0_fw_prepare(struct fw_upload *fwl,
1187					     const u8 *data, u32 size)
1188{
1189	struct pd692x0_priv *priv = fwl->dd_handle;
1190	const struct i2c_client *client = priv->client;
1191	enum pd692x0_fw_state last_fw_state;
1192	int ret;
1193
1194	priv->cancel_request = false;
1195	last_fw_state = priv->fw_state;
1196
1197	priv->fw_state = PD692X0_FW_PREPARE;
1198
1199	/* Enter program mode */
1200	if (last_fw_state == PD692X0_FW_BROKEN) {
1201		const char *msg = "ENTR";
1202		const char *c;
1203
1204		c = msg;
1205		do {
1206			ret = i2c_master_send(client, c, 1);
1207			if (ret < 0)
1208				return FW_UPLOAD_ERR_RW_ERROR;
1209			if (*(c + 1))
1210				usleep_range(10000, 20000);
1211		} while (*(++c));
1212	} else {
1213		struct pd692x0_msg msg, buf;
1214
1215		msg = pd692x0_msg_template_list[PD692X0_MSG_DOWNLOAD_CMD];
1216		ret = pd692x0_sendrecv_msg(priv, &msg, &buf);
1217		if (ret < 0) {
1218			dev_err(&client->dev,
1219				"Failed to enter programming mode (%pe)\n",
1220				ERR_PTR(ret));
1221			return FW_UPLOAD_ERR_RW_ERROR;
1222		}
1223	}
1224
1225	ret = pd692x0_fw_recv_resp(client, 100, "TPE\r\n", sizeof("TPE\r\n") - 1);
1226	if (ret)
1227		goto err_out;
1228
1229	if (priv->cancel_request) {
1230		ret = FW_UPLOAD_ERR_CANCELED;
1231		goto err_out;
1232	}
1233
1234	return FW_UPLOAD_ERR_NONE;
1235
1236err_out:
1237	pd692x0_fw_reset(priv->client);
1238	priv->fw_state = last_fw_state;
1239	return ret;
1240}
1241
1242static enum fw_upload_err pd692x0_fw_write(struct fw_upload *fwl,
1243					   const u8 *data, u32 offset,
1244					   u32 size, u32 *written)
1245{
1246	struct pd692x0_priv *priv = fwl->dd_handle;
1247	char line[PD692X0_FW_LINE_MAX_SZ];
1248	const struct i2c_client *client;
1249	int ret, i;
1250	char cmd;
1251
1252	client = priv->client;
1253	priv->fw_state = PD692X0_FW_WRITE;
1254
1255	/* Erase */
1256	cmd = 'E';
1257	ret = i2c_master_send(client, &cmd, 1);
1258	if (ret < 0) {
1259		dev_err(&client->dev,
1260			"Failed to boot programming mode (%pe)\n",
1261			ERR_PTR(ret));
1262		return FW_UPLOAD_ERR_RW_ERROR;
1263	}
1264
1265	ret = pd692x0_fw_recv_resp(client, 100, "TOE\r\n", sizeof("TOE\r\n") - 1);
1266	if (ret)
1267		return ret;
1268
1269	ret = pd692x0_fw_recv_resp(client, 5000, "TE\r\n", sizeof("TE\r\n") - 1);
1270	if (ret)
1271		dev_warn(&client->dev,
1272			 "Failed to erase internal memory, however still try to write Firmware\n");
1273
1274	ret = pd692x0_fw_recv_resp(client, 100, "TPE\r\n", sizeof("TPE\r\n") - 1);
1275	if (ret)
1276		dev_warn(&client->dev,
1277			 "Failed to erase internal memory, however still try to write Firmware\n");
1278
1279	if (priv->cancel_request)
1280		return FW_UPLOAD_ERR_CANCELED;
1281
1282	/* Program */
1283	cmd = 'P';
1284	ret = i2c_master_send(client, &cmd, sizeof(char));
1285	if (ret < 0) {
1286		dev_err(&client->dev,
1287			"Failed to boot programming mode (%pe)\n",
1288			ERR_PTR(ret));
1289		return ret;
1290	}
1291
1292	ret = pd692x0_fw_recv_resp(client, 100, "TOP\r\n", sizeof("TOP\r\n") - 1);
1293	if (ret)
1294		return ret;
1295
1296	i = 0;
1297	while (i < size) {
1298		ret = pd692x0_fw_get_next_line(data, line, size - i);
1299		if (ret < 0) {
1300			ret = FW_UPLOAD_ERR_FW_INVALID;
1301			goto err;
1302		}
1303
1304		i += ret;
1305		data += ret;
1306		if (line[0] == 'S' && line[1] == '0') {
1307			continue;
1308		} else if (line[0] == 'S' && line[1] == '7') {
1309			ret = pd692x0_fw_write_line(client, line, true);
1310			if (ret)
1311				goto err;
1312		} else {
1313			ret = pd692x0_fw_write_line(client, line, false);
1314			if (ret)
1315				goto err;
1316		}
1317
1318		if (priv->cancel_request) {
1319			ret = FW_UPLOAD_ERR_CANCELED;
1320			goto err;
1321		}
1322	}
1323	*written = i;
1324
1325	msleep(400);
1326
1327	return FW_UPLOAD_ERR_NONE;
1328
1329err:
1330	strscpy_pad(line, "S7\r\n", sizeof(line));
1331	pd692x0_fw_write_line(client, line, true);
1332	return ret;
1333}
1334
1335static enum fw_upload_err pd692x0_fw_poll_complete(struct fw_upload *fwl)
1336{
1337	struct pd692x0_priv *priv = fwl->dd_handle;
1338	const struct i2c_client *client = priv->client;
1339	struct pd692x0_msg_ver ver;
1340	int ret;
1341
1342	priv->fw_state = PD692X0_FW_COMPLETE;
1343
1344	ret = pd692x0_fw_reset(client);
1345	if (ret)
1346		return ret;
1347
1348	ver = pd692x0_get_sw_version(priv);
1349	if (ver.maj_sw_ver < PD692X0_FW_MAJ_VER) {
1350		dev_err(&client->dev,
1351			"Too old firmware version. Please update it\n");
1352		priv->fw_state = PD692X0_FW_NEED_UPDATE;
1353		return FW_UPLOAD_ERR_FW_INVALID;
1354	}
1355
1356	ret = pd692x0_setup_pi_matrix(&priv->pcdev);
1357	if (ret < 0) {
1358		dev_err(&client->dev, "Error configuring ports matrix (%pe)\n",
1359			ERR_PTR(ret));
1360		priv->fw_state = PD692X0_FW_NEED_UPDATE;
1361		return FW_UPLOAD_ERR_HW_ERROR;
1362	}
1363
1364	priv->fw_state = PD692X0_FW_OK;
1365	return FW_UPLOAD_ERR_NONE;
1366}
1367
1368static void pd692x0_fw_cancel(struct fw_upload *fwl)
1369{
1370	struct pd692x0_priv *priv = fwl->dd_handle;
1371
1372	priv->cancel_request = true;
1373}
1374
1375static void pd692x0_fw_cleanup(struct fw_upload *fwl)
1376{
1377	struct pd692x0_priv *priv = fwl->dd_handle;
1378
1379	switch (priv->fw_state) {
1380	case PD692X0_FW_WRITE:
1381		pd692x0_fw_reset(priv->client);
1382		fallthrough;
1383	case PD692X0_FW_COMPLETE:
1384		priv->fw_state = PD692X0_FW_BROKEN;
1385		break;
1386	default:
1387		break;
1388	}
1389}
1390
1391static const struct fw_upload_ops pd692x0_fw_ops = {
1392	.prepare = pd692x0_fw_prepare,
1393	.write = pd692x0_fw_write,
1394	.poll_complete = pd692x0_fw_poll_complete,
1395	.cancel = pd692x0_fw_cancel,
1396	.cleanup = pd692x0_fw_cleanup,
1397};
1398
1399static int pd692x0_i2c_probe(struct i2c_client *client)
1400{
1401	struct pd692x0_msg msg, buf = {0}, zero = {0};
1402	struct device *dev = &client->dev;
1403	struct pd692x0_msg_ver ver;
1404	struct pd692x0_priv *priv;
1405	struct fw_upload *fwl;
1406	int ret;
1407
1408	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
1409		dev_err(dev, "i2c check functionality failed\n");
1410		return -ENXIO;
1411	}
1412
1413	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
1414	if (!priv)
1415		return -ENOMEM;
1416
1417	priv->client = client;
1418	i2c_set_clientdata(client, priv);
1419
1420	ret = i2c_master_recv(client, (u8 *)&buf, sizeof(buf));
1421	if (ret != sizeof(buf)) {
1422		dev_err(dev, "Failed to get device status\n");
1423		return -EIO;
1424	}
1425
1426	/* Probe has been already run and the status dumped */
1427	if (!memcmp(&buf, &zero, sizeof(buf))) {
1428		/* Ask again the controller status */
1429		msg = pd692x0_msg_template_list[PD692X0_MSG_GET_SYS_STATUS];
1430		ret = pd692x0_sendrecv_msg(priv, &msg, &buf);
1431		if (ret < 0) {
1432			dev_err(dev, "Failed to get device status\n");
1433			return ret;
1434		}
1435	}
1436
1437	if (buf.key != 0x03 || buf.sub[0] & 0x01) {
1438		dev_err(dev, "PSE controller error\n");
1439		return -EIO;
1440	}
1441	if (buf.sub[0] & 0x02) {
1442		dev_err(dev, "PSE firmware error. Please update it.\n");
1443		priv->fw_state = PD692X0_FW_BROKEN;
1444	} else {
1445		ver = pd692x0_get_sw_version(priv);
1446		dev_info(&client->dev, "Software version %d.%02d.%d.%d\n",
1447			 ver.prod, ver.maj_sw_ver, ver.min_sw_ver,
1448			 ver.pa_sw_ver);
1449
1450		if (ver.maj_sw_ver < PD692X0_FW_MAJ_VER) {
1451			dev_err(dev, "Too old firmware version. Please update it\n");
1452			priv->fw_state = PD692X0_FW_NEED_UPDATE;
1453		} else {
1454			priv->fw_state = PD692X0_FW_OK;
1455		}
1456	}
1457
1458	priv->np = dev->of_node;
1459	priv->pcdev.nr_lines = PD692X0_MAX_PIS;
1460	priv->pcdev.owner = THIS_MODULE;
1461	priv->pcdev.ops = &pd692x0_ops;
1462	priv->pcdev.dev = dev;
1463	priv->pcdev.types = ETHTOOL_PSE_C33;
1464	ret = devm_pse_controller_register(dev, &priv->pcdev);
1465	if (ret)
1466		return dev_err_probe(dev, ret,
1467				     "failed to register PSE controller\n");
1468
1469	fwl = firmware_upload_register(THIS_MODULE, dev, dev_name(dev),
1470				       &pd692x0_fw_ops, priv);
1471	if (IS_ERR(fwl))
1472		return dev_err_probe(dev, PTR_ERR(fwl),
1473				     "failed to register to the Firmware Upload API\n");
1474	priv->fwl = fwl;
1475
1476	return 0;
1477}
1478
1479static void pd692x0_i2c_remove(struct i2c_client *client)
1480{
1481	struct pd692x0_priv *priv = i2c_get_clientdata(client);
1482
1483	firmware_upload_unregister(priv->fwl);
1484}
1485
1486static const struct i2c_device_id pd692x0_id[] = {
1487	{ PD692X0_PSE_NAME },
1488	{ }
1489};
1490MODULE_DEVICE_TABLE(i2c, pd692x0_id);
1491
1492static const struct of_device_id pd692x0_of_match[] = {
1493	{ .compatible = "microchip,pd69200", },
1494	{ .compatible = "microchip,pd69210", },
1495	{ .compatible = "microchip,pd69220", },
1496	{ },
1497};
1498MODULE_DEVICE_TABLE(of, pd692x0_of_match);
1499
1500static struct i2c_driver pd692x0_driver = {
1501	.probe		= pd692x0_i2c_probe,
1502	.remove		= pd692x0_i2c_remove,
1503	.id_table	= pd692x0_id,
1504	.driver		= {
1505		.name		= PD692X0_PSE_NAME,
1506		.of_match_table = pd692x0_of_match,
1507	},
1508};
1509module_i2c_driver(pd692x0_driver);
1510
1511MODULE_AUTHOR("Kory Maincent <kory.maincent@bootlin.com>");
1512MODULE_DESCRIPTION("Microchip PD692x0 PoE PSE Controller driver");
1513MODULE_LICENSE("GPL");