brintos

brintos / linux-shallow public Read only

0
0
Text · 37.6 KiB · 0af7db8 Raw
1539 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*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	4819#define PD692X0_MAX_MANAGERS		1220#define PD692X0_MAX_MANAGER_PORTS	821#define PD692X0_MAX_HW_PORTS	(PD692X0_MAX_MANAGERS * PD692X0_MAX_MANAGER_PORTS)22 23#define PD69200_BT_PROD_VER	2424#define PD69210_BT_PROD_VER	2625#define PD69220_BT_PROD_VER	2926 27#define PD692X0_FW_MAJ_VER	328#define PD692X0_FW_MIN_VER	529#define PD692X0_FW_PATCH_VER	530 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 = 0x5265};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_CNT82};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 here101 * constitute the fixed portion of the messages. The remaining bytes will102 * be configured later within the functions. Refer to the "PD692x0 BT Serial103 * Communication Protocol User Guide" for comprehensive details on messages104 * 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 scenarios278 * involving communication loss. Refer to the "Synchronization During279 * Communication Loss" section in the Communication Protocol document for280 * 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_mapping466pd692x0_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 void521pd692x0_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 4545/* 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_pw549pd692x0_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 int616pd692x0_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	else665		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	else670		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 int743pd692x0_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 int787pd692x0_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 int845pd692x0_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 int883pd692x0_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 int922pd692x0_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_current_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 mW, uV, uA, ret;1008	s64 tmp_64;1009 1010	msg = pd692x0_msg_template_list[PD692X0_MSG_GET_PORT_PARAM];1011	msg.sub[2] = id;1012	ret = pd692x0_sendrecv_msg(priv, &msg, &buf);1013	if (ret < 0)1014		return ret;1015 1016	ret = pd692x0_pi_get_pw_from_table(buf.data[2], buf.data[3]);1017	if (ret < 0)1018		return ret;1019	mW = ret;1020 1021	ret = pd692x0_pi_get_voltage(pcdev, id);1022	if (ret < 0)1023		return ret;1024	uV = ret;1025 1026	tmp_64 = mW;1027	tmp_64 *= 1000000000ull;1028	/* uA = mW * 1000000000 / uV */1029	uA = DIV_ROUND_CLOSEST_ULL(tmp_64, uV);1030	return uA;1031}1032 1033static int pd692x0_pi_set_current_limit(struct pse_controller_dev *pcdev,1034					int id, int max_uA)1035{1036	struct pd692x0_priv *priv = to_pd692x0_priv(pcdev);1037	struct device *dev = &priv->client->dev;1038	struct pd692x0_msg msg, buf = {0};1039	int uV, ret, mW;1040	s64 tmp_64;1041 1042	ret = pd692x0_fw_unavailable(priv);1043	if (ret)1044		return ret;1045 1046	ret = pd692x0_pi_get_voltage(pcdev, id);1047	if (ret < 0)1048		return ret;1049	uV = ret;1050 1051	msg = pd692x0_msg_template_list[PD692X0_MSG_SET_PORT_PARAM];1052	msg.sub[2] = id;1053	tmp_64 = uV;1054	tmp_64 *= max_uA;1055	/* mW = uV * uA / 1000000000 */1056	mW = DIV_ROUND_CLOSEST_ULL(tmp_64, 1000000000);1057	ret = pd692x0_pi_set_pw_from_table(dev, &msg, mW);1058	if (ret)1059		return ret;1060 1061	return pd692x0_sendrecv_msg(priv, &msg, &buf);1062}1063 1064static const struct pse_controller_ops pd692x0_ops = {1065	.setup_pi_matrix = pd692x0_setup_pi_matrix,1066	.ethtool_get_status = pd692x0_ethtool_get_status,1067	.pi_enable = pd692x0_pi_enable,1068	.pi_disable = pd692x0_pi_disable,1069	.pi_is_enabled = pd692x0_pi_is_enabled,1070	.pi_get_voltage = pd692x0_pi_get_voltage,1071	.pi_get_current_limit = pd692x0_pi_get_current_limit,1072	.pi_set_current_limit = pd692x0_pi_set_current_limit,1073};1074 1075#define PD692X0_FW_LINE_MAX_SZ 0xff1076static int pd692x0_fw_get_next_line(const u8 *data,1077				    char *line, size_t size)1078{1079	size_t line_size;1080	int i;1081 1082	line_size = min_t(size_t, size, PD692X0_FW_LINE_MAX_SZ);1083 1084	memset(line, 0, PD692X0_FW_LINE_MAX_SZ);1085	for (i = 0; i < line_size - 1; i++) {1086		if (*data == '\r' && *(data + 1) == '\n') {1087			line[i] = '\r';1088			line[i + 1] = '\n';1089			return i + 2;1090		}1091		line[i] = *data;1092		data++;1093	}1094 1095	return -EIO;1096}1097 1098static enum fw_upload_err1099pd692x0_fw_recv_resp(const struct i2c_client *client, unsigned long ms_timeout,1100		     const char *msg_ok, unsigned int msg_size)1101{1102	/* Maximum controller response size */1103	char fw_msg_buf[5] = {0};1104	unsigned long timeout;1105	int ret;1106 1107	if (msg_size > sizeof(fw_msg_buf))1108		return FW_UPLOAD_ERR_RW_ERROR;1109 1110	/* Read until we get something */1111	timeout = msecs_to_jiffies(ms_timeout) + jiffies;1112	while (true) {1113		if (time_is_before_jiffies(timeout))1114			return FW_UPLOAD_ERR_TIMEOUT;1115 1116		ret = i2c_master_recv(client, fw_msg_buf, 1);1117		if (ret < 0 || *fw_msg_buf == 0) {1118			usleep_range(1000, 2000);1119			continue;1120		} else {1121			break;1122		}1123	}1124 1125	/* Read remaining characters */1126	ret = i2c_master_recv(client, fw_msg_buf + 1, msg_size - 1);1127	if (strncmp(fw_msg_buf, msg_ok, msg_size)) {1128		dev_err(&client->dev,1129			"Wrong FW download process answer (%*pE)\n",1130			msg_size, fw_msg_buf);1131		return FW_UPLOAD_ERR_HW_ERROR;1132	}1133 1134	return FW_UPLOAD_ERR_NONE;1135}1136 1137static int pd692x0_fw_write_line(const struct i2c_client *client,1138				 const char line[PD692X0_FW_LINE_MAX_SZ],1139				 const bool last_line)1140{1141	int ret;1142 1143	while (*line != 0) {1144		ret = i2c_master_send(client, line, 1);1145		if (ret < 0)1146			return FW_UPLOAD_ERR_RW_ERROR;1147		line++;1148	}1149 1150	if (last_line) {1151		ret = pd692x0_fw_recv_resp(client, 100, "TP\r\n",1152					   sizeof("TP\r\n") - 1);1153		if (ret)1154			return ret;1155	} else {1156		ret = pd692x0_fw_recv_resp(client, 100, "T*\r\n",1157					   sizeof("T*\r\n") - 1);1158		if (ret)1159			return ret;1160	}1161 1162	return FW_UPLOAD_ERR_NONE;1163}1164 1165static enum fw_upload_err pd692x0_fw_reset(const struct i2c_client *client)1166{1167	const struct pd692x0_msg zero = {0};1168	struct pd692x0_msg buf = {0};1169	unsigned long timeout;1170	char cmd[] = "RST";1171	int ret;1172 1173	ret = i2c_master_send(client, cmd, strlen(cmd));1174	if (ret < 0) {1175		dev_err(&client->dev,1176			"Failed to reset the controller (%pe)\n",1177			ERR_PTR(ret));1178		return ret;1179	}1180 1181	timeout = msecs_to_jiffies(10000) + jiffies;1182	while (true) {1183		if (time_is_before_jiffies(timeout))1184			return FW_UPLOAD_ERR_TIMEOUT;1185 1186		ret = i2c_master_recv(client, (u8 *)&buf, sizeof(buf));1187		if (ret < 0 ||1188		    !memcmp(&buf, &zero, sizeof(buf)))1189			usleep_range(1000, 2000);1190		else1191			break;1192	}1193 1194	/* Is the reply a successful report message */1195	if (buf.key != PD692X0_KEY_TLM || buf.echo != 0xff ||1196	    buf.sub[0] & 0x01) {1197		dev_err(&client->dev, "PSE controller error\n");1198		return FW_UPLOAD_ERR_HW_ERROR;1199	}1200 1201	/* Is the firmware operational */1202	if (buf.sub[0] & 0x02) {1203		dev_err(&client->dev,1204			"PSE firmware error. Please update it.\n");1205		return FW_UPLOAD_ERR_HW_ERROR;1206	}1207 1208	return FW_UPLOAD_ERR_NONE;1209}1210 1211static enum fw_upload_err pd692x0_fw_prepare(struct fw_upload *fwl,1212					     const u8 *data, u32 size)1213{1214	struct pd692x0_priv *priv = fwl->dd_handle;1215	const struct i2c_client *client = priv->client;1216	enum pd692x0_fw_state last_fw_state;1217	int ret;1218 1219	priv->cancel_request = false;1220	last_fw_state = priv->fw_state;1221 1222	priv->fw_state = PD692X0_FW_PREPARE;1223 1224	/* Enter program mode */1225	if (last_fw_state == PD692X0_FW_BROKEN) {1226		const char *msg = "ENTR";1227		const char *c;1228 1229		c = msg;1230		do {1231			ret = i2c_master_send(client, c, 1);1232			if (ret < 0)1233				return FW_UPLOAD_ERR_RW_ERROR;1234			if (*(c + 1))1235				usleep_range(10000, 20000);1236		} while (*(++c));1237	} else {1238		struct pd692x0_msg msg, buf;1239 1240		msg = pd692x0_msg_template_list[PD692X0_MSG_DOWNLOAD_CMD];1241		ret = pd692x0_sendrecv_msg(priv, &msg, &buf);1242		if (ret < 0) {1243			dev_err(&client->dev,1244				"Failed to enter programming mode (%pe)\n",1245				ERR_PTR(ret));1246			return FW_UPLOAD_ERR_RW_ERROR;1247		}1248	}1249 1250	ret = pd692x0_fw_recv_resp(client, 100, "TPE\r\n", sizeof("TPE\r\n") - 1);1251	if (ret)1252		goto err_out;1253 1254	if (priv->cancel_request) {1255		ret = FW_UPLOAD_ERR_CANCELED;1256		goto err_out;1257	}1258 1259	return FW_UPLOAD_ERR_NONE;1260 1261err_out:1262	pd692x0_fw_reset(priv->client);1263	priv->fw_state = last_fw_state;1264	return ret;1265}1266 1267static enum fw_upload_err pd692x0_fw_write(struct fw_upload *fwl,1268					   const u8 *data, u32 offset,1269					   u32 size, u32 *written)1270{1271	struct pd692x0_priv *priv = fwl->dd_handle;1272	char line[PD692X0_FW_LINE_MAX_SZ];1273	const struct i2c_client *client;1274	int ret, i;1275	char cmd;1276 1277	client = priv->client;1278	priv->fw_state = PD692X0_FW_WRITE;1279 1280	/* Erase */1281	cmd = 'E';1282	ret = i2c_master_send(client, &cmd, 1);1283	if (ret < 0) {1284		dev_err(&client->dev,1285			"Failed to boot programming mode (%pe)\n",1286			ERR_PTR(ret));1287		return FW_UPLOAD_ERR_RW_ERROR;1288	}1289 1290	ret = pd692x0_fw_recv_resp(client, 100, "TOE\r\n", sizeof("TOE\r\n") - 1);1291	if (ret)1292		return ret;1293 1294	ret = pd692x0_fw_recv_resp(client, 5000, "TE\r\n", sizeof("TE\r\n") - 1);1295	if (ret)1296		dev_warn(&client->dev,1297			 "Failed to erase internal memory, however still try to write Firmware\n");1298 1299	ret = pd692x0_fw_recv_resp(client, 100, "TPE\r\n", sizeof("TPE\r\n") - 1);1300	if (ret)1301		dev_warn(&client->dev,1302			 "Failed to erase internal memory, however still try to write Firmware\n");1303 1304	if (priv->cancel_request)1305		return FW_UPLOAD_ERR_CANCELED;1306 1307	/* Program */1308	cmd = 'P';1309	ret = i2c_master_send(client, &cmd, sizeof(char));1310	if (ret < 0) {1311		dev_err(&client->dev,1312			"Failed to boot programming mode (%pe)\n",1313			ERR_PTR(ret));1314		return ret;1315	}1316 1317	ret = pd692x0_fw_recv_resp(client, 100, "TOP\r\n", sizeof("TOP\r\n") - 1);1318	if (ret)1319		return ret;1320 1321	i = 0;1322	while (i < size) {1323		ret = pd692x0_fw_get_next_line(data, line, size - i);1324		if (ret < 0) {1325			ret = FW_UPLOAD_ERR_FW_INVALID;1326			goto err;1327		}1328 1329		i += ret;1330		data += ret;1331		if (line[0] == 'S' && line[1] == '0') {1332			continue;1333		} else if (line[0] == 'S' && line[1] == '7') {1334			ret = pd692x0_fw_write_line(client, line, true);1335			if (ret)1336				goto err;1337		} else {1338			ret = pd692x0_fw_write_line(client, line, false);1339			if (ret)1340				goto err;1341		}1342 1343		if (priv->cancel_request) {1344			ret = FW_UPLOAD_ERR_CANCELED;1345			goto err;1346		}1347	}1348	*written = i;1349 1350	msleep(400);1351 1352	return FW_UPLOAD_ERR_NONE;1353 1354err:1355	strscpy_pad(line, "S7\r\n", sizeof(line));1356	pd692x0_fw_write_line(client, line, true);1357	return ret;1358}1359 1360static enum fw_upload_err pd692x0_fw_poll_complete(struct fw_upload *fwl)1361{1362	struct pd692x0_priv *priv = fwl->dd_handle;1363	const struct i2c_client *client = priv->client;1364	struct pd692x0_msg_ver ver;1365	int ret;1366 1367	priv->fw_state = PD692X0_FW_COMPLETE;1368 1369	ret = pd692x0_fw_reset(client);1370	if (ret)1371		return ret;1372 1373	ver = pd692x0_get_sw_version(priv);1374	if (ver.maj_sw_ver < PD692X0_FW_MAJ_VER) {1375		dev_err(&client->dev,1376			"Too old firmware version. Please update it\n");1377		priv->fw_state = PD692X0_FW_NEED_UPDATE;1378		return FW_UPLOAD_ERR_FW_INVALID;1379	}1380 1381	ret = pd692x0_setup_pi_matrix(&priv->pcdev);1382	if (ret < 0) {1383		dev_err(&client->dev, "Error configuring ports matrix (%pe)\n",1384			ERR_PTR(ret));1385		priv->fw_state = PD692X0_FW_NEED_UPDATE;1386		return FW_UPLOAD_ERR_HW_ERROR;1387	}1388 1389	priv->fw_state = PD692X0_FW_OK;1390	return FW_UPLOAD_ERR_NONE;1391}1392 1393static void pd692x0_fw_cancel(struct fw_upload *fwl)1394{1395	struct pd692x0_priv *priv = fwl->dd_handle;1396 1397	priv->cancel_request = true;1398}1399 1400static void pd692x0_fw_cleanup(struct fw_upload *fwl)1401{1402	struct pd692x0_priv *priv = fwl->dd_handle;1403 1404	switch (priv->fw_state) {1405	case PD692X0_FW_WRITE:1406		pd692x0_fw_reset(priv->client);1407		fallthrough;1408	case PD692X0_FW_COMPLETE:1409		priv->fw_state = PD692X0_FW_BROKEN;1410		break;1411	default:1412		break;1413	}1414}1415 1416static const struct fw_upload_ops pd692x0_fw_ops = {1417	.prepare = pd692x0_fw_prepare,1418	.write = pd692x0_fw_write,1419	.poll_complete = pd692x0_fw_poll_complete,1420	.cancel = pd692x0_fw_cancel,1421	.cleanup = pd692x0_fw_cleanup,1422};1423 1424static int pd692x0_i2c_probe(struct i2c_client *client)1425{1426	struct pd692x0_msg msg, buf = {0}, zero = {0};1427	struct device *dev = &client->dev;1428	struct pd692x0_msg_ver ver;1429	struct pd692x0_priv *priv;1430	struct fw_upload *fwl;1431	int ret;1432 1433	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {1434		dev_err(dev, "i2c check functionality failed\n");1435		return -ENXIO;1436	}1437 1438	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);1439	if (!priv)1440		return -ENOMEM;1441 1442	priv->client = client;1443	i2c_set_clientdata(client, priv);1444 1445	ret = i2c_master_recv(client, (u8 *)&buf, sizeof(buf));1446	if (ret != sizeof(buf)) {1447		dev_err(dev, "Failed to get device status\n");1448		return -EIO;1449	}1450 1451	/* Probe has been already run and the status dumped */1452	if (!memcmp(&buf, &zero, sizeof(buf))) {1453		/* Ask again the controller status */1454		msg = pd692x0_msg_template_list[PD692X0_MSG_GET_SYS_STATUS];1455		ret = pd692x0_sendrecv_msg(priv, &msg, &buf);1456		if (ret < 0) {1457			dev_err(dev, "Failed to get device status\n");1458			return ret;1459		}1460	}1461 1462	if (buf.key != 0x03 || buf.sub[0] & 0x01) {1463		dev_err(dev, "PSE controller error\n");1464		return -EIO;1465	}1466	if (buf.sub[0] & 0x02) {1467		dev_err(dev, "PSE firmware error. Please update it.\n");1468		priv->fw_state = PD692X0_FW_BROKEN;1469	} else {1470		ver = pd692x0_get_sw_version(priv);1471		dev_info(&client->dev, "Software version %d.%02d.%d.%d\n",1472			 ver.prod, ver.maj_sw_ver, ver.min_sw_ver,1473			 ver.pa_sw_ver);1474 1475		if (ver.maj_sw_ver < PD692X0_FW_MAJ_VER) {1476			dev_err(dev, "Too old firmware version. Please update it\n");1477			priv->fw_state = PD692X0_FW_NEED_UPDATE;1478		} else {1479			priv->fw_state = PD692X0_FW_OK;1480		}1481	}1482 1483	priv->np = dev->of_node;1484	priv->pcdev.nr_lines = PD692X0_MAX_PIS;1485	priv->pcdev.owner = THIS_MODULE;1486	priv->pcdev.ops = &pd692x0_ops;1487	priv->pcdev.dev = dev;1488	priv->pcdev.types = ETHTOOL_PSE_C33;1489	ret = devm_pse_controller_register(dev, &priv->pcdev);1490	if (ret)1491		return dev_err_probe(dev, ret,1492				     "failed to register PSE controller\n");1493 1494	fwl = firmware_upload_register(THIS_MODULE, dev, dev_name(dev),1495				       &pd692x0_fw_ops, priv);1496	if (IS_ERR(fwl))1497		return dev_err_probe(dev, PTR_ERR(fwl),1498				     "failed to register to the Firmware Upload API\n");1499	priv->fwl = fwl;1500 1501	return 0;1502}1503 1504static void pd692x0_i2c_remove(struct i2c_client *client)1505{1506	struct pd692x0_priv *priv = i2c_get_clientdata(client);1507 1508	firmware_upload_unregister(priv->fwl);1509}1510 1511static const struct i2c_device_id pd692x0_id[] = {1512	{ PD692X0_PSE_NAME },1513	{ }1514};1515MODULE_DEVICE_TABLE(i2c, pd692x0_id);1516 1517static const struct of_device_id pd692x0_of_match[] = {1518	{ .compatible = "microchip,pd69200", },1519	{ .compatible = "microchip,pd69210", },1520	{ .compatible = "microchip,pd69220", },1521	{ },1522};1523MODULE_DEVICE_TABLE(of, pd692x0_of_match);1524 1525static struct i2c_driver pd692x0_driver = {1526	.probe		= pd692x0_i2c_probe,1527	.remove		= pd692x0_i2c_remove,1528	.id_table	= pd692x0_id,1529	.driver		= {1530		.name		= PD692X0_PSE_NAME,1531		.of_match_table = pd692x0_of_match,1532	},1533};1534module_i2c_driver(pd692x0_driver);1535 1536MODULE_AUTHOR("Kory Maincent <kory.maincent@bootlin.com>");1537MODULE_DESCRIPTION("Microchip PD692x0 PoE PSE Controller driver");1538MODULE_LICENSE("GPL");1539