Lines Matching +full:sub +full:- +full:message

1 // SPDX-License-Identifier: GPL-2.0-only
14 #include <linux/pse-pd/pse.h>
44 u8 sub[3]; member
80 /* add new message above here */
100 /* Template list of communication messages. The non-null bytes defined here
109 .sub = {0x07, 0x55, 0x00},
115 .sub = {0x07, 0xd0, 0x4e},
121 .sub = {0x07, 0x1e, 0x21},
127 .sub = {0x05, 0x43},
133 .sub = {0x07, 0x43, 0x4e},
139 .sub = {0x05, 0xc0},
145 .sub = {0x05, 0xc1},
151 .sub = {0xff, 0x99, 0x15},
157 .sub = {0x05, 0xc4},
163 .sub = {0x05, 0xc5},
169 .sub = {0x05, 0xc0},
181 msg->echo = echo++; in pd692x0_build_msg()
185 for (i = 0; i < sizeof(*msg) - sizeof(msg->chksum); i++) in pd692x0_build_msg()
188 msg->chksum = cpu_to_be16(chksum); in pd692x0_build_msg()
195 const struct i2c_client *client = priv->client; in pd692x0_send_msg()
198 if (msg->key == PD692X0_KEY_CMD && priv->last_cmd_key) { in pd692x0_send_msg()
201 cmd_msleep = 30 - jiffies_to_msecs(jiffies - priv->last_cmd_key_time); in pd692x0_send_msg()
206 /* Add echo and checksum bytes to the message */ in pd692x0_send_msg()
207 priv->msg_id = pd692x0_build_msg(msg, priv->msg_id); in pd692x0_send_msg()
211 return -EIO; in pd692x0_send_msg()
218 const struct i2c_client *client = priv->client; in pd692x0_reset()
225 dev_err(&client->dev, in pd692x0_reset()
234 return ret < 0 ? ret : -EIO; in pd692x0_reset()
236 /* Is the reply a successful report message */ in pd692x0_reset()
237 if (buf.key != PD692X0_KEY_REPORT || buf.sub[0] || buf.sub[1]) in pd692x0_reset()
238 return -EIO; in pd692x0_reset()
244 return ret < 0 ? ret : -EIO; in pd692x0_reset()
247 if (buf.key != 0x03 || buf.echo != 0xff || buf.sub[0] & 0x1) { in pd692x0_reset()
248 dev_err(&client->dev, "PSE controller error\n"); in pd692x0_reset()
249 return -EIO; in pd692x0_reset()
264 if (buf->key) in pd692x0_try_recv_msg()
271 if (buf->key) in pd692x0_try_recv_msg()
286 const struct i2c_client *client = priv->client; in pd692x0_recv_msg()
293 dev_warn(&client->dev, in pd692x0_recv_msg()
317 dev_warn(&client->dev, "Communication is back, rtnl is unlocked!"); in pd692x0_recv_msg()
319 if (msg->key == PD692X0_KEY_CMD) { in pd692x0_recv_msg()
320 priv->last_cmd_key = true; in pd692x0_recv_msg()
321 priv->last_cmd_key_time = jiffies; in pd692x0_recv_msg()
323 priv->last_cmd_key = false; in pd692x0_recv_msg()
333 struct device *dev = &priv->client->dev; in pd692x0_sendrecv_msg()
344 if (msg->echo != buf->echo) { in pd692x0_sendrecv_msg()
346 "Wrong match in message ID, expect %d received %d.\n", in pd692x0_sendrecv_msg()
347 msg->echo, buf->echo); in pd692x0_sendrecv_msg()
348 return -EIO; in pd692x0_sendrecv_msg()
351 /* If the reply is a report message is it successful */ in pd692x0_sendrecv_msg()
352 if (buf->key == PD692X0_KEY_REPORT && in pd692x0_sendrecv_msg()
353 (buf->sub[0] || buf->sub[1])) { in pd692x0_sendrecv_msg()
354 return -EIO; in pd692x0_sendrecv_msg()
367 switch (priv->fw_state) { in pd692x0_fw_unavailable()
373 dev_err(&priv->client->dev, "Firmware update in progress!\n"); in pd692x0_fw_unavailable()
374 return -EBUSY; in pd692x0_fw_unavailable()
378 dev_err(&priv->client->dev, in pd692x0_fw_unavailable()
380 return -EOPNOTSUPP; in pd692x0_fw_unavailable()
394 if (priv->admin_state[id] == ETHTOOL_C33_PSE_ADMIN_STATE_ENABLED) in pd692x0_pi_enable()
399 msg.sub[2] = id; in pd692x0_pi_enable()
404 priv->admin_state[id] = ETHTOOL_C33_PSE_ADMIN_STATE_ENABLED; in pd692x0_pi_enable()
419 if (priv->admin_state[id] == ETHTOOL_C33_PSE_ADMIN_STATE_DISABLED) in pd692x0_pi_disable()
424 msg.sub[2] = id; in pd692x0_pi_disable()
429 priv->admin_state[id] = ETHTOOL_C33_PSE_ADMIN_STATE_DISABLED; in pd692x0_pi_disable()
510 msg.sub[2] = id; in pd692x0_pi_get_ext_state()
515 c33_ext_state_info = &ext_state_info->c33_ext_state_info; in pd692x0_pi_get_ext_state()
517 while (ext_state_map->status_code) { in pd692x0_pi_get_ext_state()
518 if (ext_state_map->status_code == buf.sub[0]) { in pd692x0_pi_get_ext_state()
519 c33_ext_state_info->c33_pse_ext_state = ext_state_map->pse_ext_state; in pd692x0_pi_get_ext_state()
520 c33_ext_state_info->__c33_pse_ext_substate = ext_state_map->pse_ext_substate; in pd692x0_pi_get_ext_state()
555 if (pw_table->class_cfg_value == op_mode) in pd692x0_pi_get_pw_from_table()
556 return pw_table->class_pw + added_pw * 100; in pd692x0_pi_get_pw_from_table()
559 return -ERANGE; in pd692x0_pi_get_pw_from_table()
569 if (pw < pw_table->class_pw) { in pd692x0_pi_set_pw_from_table()
571 "Power limit %dmW not supported. Ranges minimal available: [%d-%d]\n", in pd692x0_pi_set_pw_from_table()
573 pw_table->class_pw, in pd692x0_pi_set_pw_from_table()
574 pw_table->class_pw + pw_table->max_added_class_pw); in pd692x0_pi_set_pw_from_table()
575 return -ERANGE; in pd692x0_pi_set_pw_from_table()
579 if (pw > (pw_table->class_pw + pw_table->max_added_class_pw)) in pd692x0_pi_set_pw_from_table()
582 if (pw < pw_table->class_pw) { in pd692x0_pi_set_pw_from_table()
584 "Power limit %dmW not supported. Ranges available: [%d-%d] or [%d-%d]\n", in pd692x0_pi_set_pw_from_table()
586 (pw_table - 1)->class_pw, in pd692x0_pi_set_pw_from_table()
587 (pw_table - 1)->class_pw + (pw_table - 1)->max_added_class_pw, in pd692x0_pi_set_pw_from_table()
588 pw_table->class_pw, in pd692x0_pi_set_pw_from_table()
589 pw_table->class_pw + pw_table->max_added_class_pw); in pd692x0_pi_set_pw_from_table()
590 return -ERANGE; in pd692x0_pi_set_pw_from_table()
593 msg->data[2] = pw_table->class_cfg_value; in pd692x0_pi_set_pw_from_table()
594 msg->data[3] = (pw - pw_table->class_pw) / 100; in pd692x0_pi_set_pw_from_table()
598 pw_table--; in pd692x0_pi_set_pw_from_table()
601 pw, pw_table->class_pw + pw_table->max_added_class_pw); in pd692x0_pi_set_pw_from_table()
602 msg->data[2] = pw_table->class_cfg_value; in pd692x0_pi_set_pw_from_table()
603 msg->data[3] = pw_table->max_added_class_pw / 100; in pd692x0_pi_set_pw_from_table()
620 return -ENOMEM; in pd692x0_pi_get_pw_limit_ranges()
623 c33_pw_limit_ranges[i].min = pw_table->class_pw; in pd692x0_pi_get_pw_limit_ranges()
624 c33_pw_limit_ranges[i].max = pw_table->class_pw + in pd692x0_pi_get_pw_limit_ranges()
625 pw_table->max_added_class_pw; in pd692x0_pi_get_pw_limit_ranges()
628 pw_limit_ranges->c33_pw_limit_ranges = c33_pw_limit_ranges; in pd692x0_pi_get_pw_limit_ranges()
645 msg.sub[2] = id; in pd692x0_pi_get_admin_state()
650 if (buf.sub[1]) in pd692x0_pi_get_admin_state()
651 admin_state->c33_admin_state = in pd692x0_pi_get_admin_state()
654 admin_state->c33_admin_state = in pd692x0_pi_get_admin_state()
657 priv->admin_state[id] = admin_state->c33_admin_state; in pd692x0_pi_get_admin_state()
675 msg.sub[2] = id; in pd692x0_pi_get_pw_status()
681 if ((buf.sub[0] & 0xf0) == 0x80 || (buf.sub[0] & 0xf0) == 0x90) in pd692x0_pi_get_pw_status()
682 pw_status->c33_pw_status = in pd692x0_pi_get_pw_status()
684 else if (buf.sub[0] == 0x1b || buf.sub[0] == 0x22) in pd692x0_pi_get_pw_status()
685 pw_status->c33_pw_status = in pd692x0_pi_get_pw_status()
687 else if (buf.sub[0] == 0x12) in pd692x0_pi_get_pw_status()
688 pw_status->c33_pw_status = in pd692x0_pi_get_pw_status()
691 pw_status->c33_pw_status = in pd692x0_pi_get_pw_status()
710 msg.sub[2] = id; in pd692x0_pi_get_pw_class()
734 msg.sub[2] = id; in pd692x0_pi_get_actual_pw()
744 struct device *dev = &priv->client->dev; in pd692x0_get_sw_version()
756 /* Extract version from the message */ in pd692x0_get_sw_version()
757 ver.prod = buf.sub[2]; in pd692x0_get_sw_version()
797 dev_err(&priv->client->dev, in pd692x0_of_get_ports_manager()
800 ret = -EINVAL; in pd692x0_of_get_ports_manager()
805 manager->port_node[port] = node; in pd692x0_of_get_ports_manager()
809 manager->nports = nports; in pd692x0_of_get_ports_manager()
814 of_node_put(manager->port_node[i]); in pd692x0_of_get_ports_manager()
815 manager->port_node[i] = NULL; in pd692x0_of_get_ports_manager()
828 if (!priv->np) in pd692x0_of_get_managers()
829 return -EINVAL; in pd692x0_of_get_managers()
832 managers_node = of_get_child_by_name(priv->np, "managers"); in pd692x0_of_get_managers()
834 return -EINVAL; in pd692x0_of_get_managers()
848 dev_err(&priv->client->dev, in pd692x0_of_get_managers()
851 ret = -EINVAL; in pd692x0_of_get_managers()
887 if (!pairset->np) in pd692x0_set_port_matrix()
895 if (pairset->np == manager[i].port_node[j]) { in pd692x0_set_port_matrix()
907 return -ENODEV; in pd692x0_set_port_matrix()
909 if (pairset->pinout == ALTERNATIVE_A) in pd692x0_set_port_matrix()
910 port_matrix->hw_port_a = port_cnt; in pd692x0_set_port_matrix()
911 else if (pairset->pinout == ALTERNATIVE_B) in pd692x0_set_port_matrix()
912 port_matrix->hw_port_b = port_cnt; in pd692x0_set_port_matrix()
923 struct pse_controller_dev *pcdev = &priv->pcdev; in pd692x0_set_ports_matrix()
933 for (i = 0; i < pcdev->nr_lines; i++) { in pd692x0_set_ports_matrix()
934 ret = pd692x0_set_port_matrix(&pcdev->pi[i].pairset[0], in pd692x0_set_ports_matrix()
938 dev_err(&priv->client->dev, in pd692x0_set_ports_matrix()
943 ret = pd692x0_set_port_matrix(&pcdev->pi[i].pairset[1], in pd692x0_set_ports_matrix()
947 dev_err(&priv->client->dev, in pd692x0_set_ports_matrix()
966 msg.sub[2] = i; in pd692x0_write_ports_matrix()
992 if (priv->fw_state != PD692X0_FW_OK && in pd692x0_setup_pi_matrix()
993 priv->fw_state != PD692X0_FW_COMPLETE) in pd692x0_setup_pi_matrix()
1028 msg.sub[2] = id; in pd692x0_pi_get_voltage()
1034 return (buf.sub[0] << 8 | buf.sub[1]) * 100000; in pd692x0_pi_get_voltage()
1045 msg.sub[2] = id; in pd692x0_pi_get_pw_limit()
1057 struct device *dev = &priv->client->dev; in pd692x0_pi_set_pw_limit()
1066 msg.sub[2] = id; in pd692x0_pi_set_pw_limit()
1099 for (i = 0; i < line_size - 1; i++) { in pd692x0_fw_get_next_line()
1109 return -EIO; in pd692x0_fw_get_next_line()
1140 ret = i2c_master_recv(client, fw_msg_buf + 1, msg_size - 1); in pd692x0_fw_recv_resp()
1142 dev_err(&client->dev, in pd692x0_fw_recv_resp()
1166 sizeof("TP\r\n") - 1); in pd692x0_fw_write_line()
1171 sizeof("T*\r\n") - 1); in pd692x0_fw_write_line()
1189 dev_err(&client->dev, in pd692x0_fw_reset()
1208 /* Is the reply a successful report message */ in pd692x0_fw_reset()
1210 buf.sub[0] & 0x01) { in pd692x0_fw_reset()
1211 dev_err(&client->dev, "PSE controller error\n"); in pd692x0_fw_reset()
1216 if (buf.sub[0] & 0x02) { in pd692x0_fw_reset()
1217 dev_err(&client->dev, in pd692x0_fw_reset()
1228 struct pd692x0_priv *priv = fwl->dd_handle; in pd692x0_fw_prepare()
1229 const struct i2c_client *client = priv->client; in pd692x0_fw_prepare()
1233 priv->cancel_request = false; in pd692x0_fw_prepare()
1234 last_fw_state = priv->fw_state; in pd692x0_fw_prepare()
1236 priv->fw_state = PD692X0_FW_PREPARE; in pd692x0_fw_prepare()
1257 dev_err(&client->dev, in pd692x0_fw_prepare()
1264 ret = pd692x0_fw_recv_resp(client, 100, "TPE\r\n", sizeof("TPE\r\n") - 1); in pd692x0_fw_prepare()
1268 if (priv->cancel_request) { in pd692x0_fw_prepare()
1276 pd692x0_fw_reset(priv->client); in pd692x0_fw_prepare()
1277 priv->fw_state = last_fw_state; in pd692x0_fw_prepare()
1285 struct pd692x0_priv *priv = fwl->dd_handle; in pd692x0_fw_write()
1291 client = priv->client; in pd692x0_fw_write()
1292 priv->fw_state = PD692X0_FW_WRITE; in pd692x0_fw_write()
1298 dev_err(&client->dev, in pd692x0_fw_write()
1304 ret = pd692x0_fw_recv_resp(client, 100, "TOE\r\n", sizeof("TOE\r\n") - 1); in pd692x0_fw_write()
1308 ret = pd692x0_fw_recv_resp(client, 5000, "TE\r\n", sizeof("TE\r\n") - 1); in pd692x0_fw_write()
1310 dev_warn(&client->dev, in pd692x0_fw_write()
1313 ret = pd692x0_fw_recv_resp(client, 100, "TPE\r\n", sizeof("TPE\r\n") - 1); in pd692x0_fw_write()
1315 dev_warn(&client->dev, in pd692x0_fw_write()
1318 if (priv->cancel_request) in pd692x0_fw_write()
1325 dev_err(&client->dev, in pd692x0_fw_write()
1331 ret = pd692x0_fw_recv_resp(client, 100, "TOP\r\n", sizeof("TOP\r\n") - 1); in pd692x0_fw_write()
1337 ret = pd692x0_fw_get_next_line(data, line, size - i); in pd692x0_fw_write()
1357 if (priv->cancel_request) { in pd692x0_fw_write()
1376 struct pd692x0_priv *priv = fwl->dd_handle; in pd692x0_fw_poll_complete()
1377 const struct i2c_client *client = priv->client; in pd692x0_fw_poll_complete()
1381 priv->fw_state = PD692X0_FW_COMPLETE; in pd692x0_fw_poll_complete()
1389 dev_err(&client->dev, in pd692x0_fw_poll_complete()
1391 priv->fw_state = PD692X0_FW_NEED_UPDATE; in pd692x0_fw_poll_complete()
1395 ret = pd692x0_setup_pi_matrix(&priv->pcdev); in pd692x0_fw_poll_complete()
1397 dev_err(&client->dev, "Error configuring ports matrix (%pe)\n", in pd692x0_fw_poll_complete()
1399 priv->fw_state = PD692X0_FW_NEED_UPDATE; in pd692x0_fw_poll_complete()
1403 priv->fw_state = PD692X0_FW_OK; in pd692x0_fw_poll_complete()
1409 struct pd692x0_priv *priv = fwl->dd_handle; in pd692x0_fw_cancel()
1411 priv->cancel_request = true; in pd692x0_fw_cancel()
1416 struct pd692x0_priv *priv = fwl->dd_handle; in pd692x0_fw_cleanup()
1418 switch (priv->fw_state) { in pd692x0_fw_cleanup()
1420 pd692x0_fw_reset(priv->client); in pd692x0_fw_cleanup()
1423 priv->fw_state = PD692X0_FW_BROKEN; in pd692x0_fw_cleanup()
1441 struct device *dev = &client->dev; in pd692x0_i2c_probe()
1447 if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { in pd692x0_i2c_probe()
1449 return -ENXIO; in pd692x0_i2c_probe()
1454 return -ENOMEM; in pd692x0_i2c_probe()
1456 priv->client = client; in pd692x0_i2c_probe()
1462 return -EIO; in pd692x0_i2c_probe()
1476 if (buf.key != 0x03 || buf.sub[0] & 0x01) { in pd692x0_i2c_probe()
1478 return -EIO; in pd692x0_i2c_probe()
1480 if (buf.sub[0] & 0x02) { in pd692x0_i2c_probe()
1482 priv->fw_state = PD692X0_FW_BROKEN; in pd692x0_i2c_probe()
1485 dev_info(&client->dev, "Software version %d.%02d.%d.%d\n", in pd692x0_i2c_probe()
1491 priv->fw_state = PD692X0_FW_NEED_UPDATE; in pd692x0_i2c_probe()
1493 priv->fw_state = PD692X0_FW_OK; in pd692x0_i2c_probe()
1497 priv->np = dev->of_node; in pd692x0_i2c_probe()
1498 priv->pcdev.nr_lines = PD692X0_MAX_PIS; in pd692x0_i2c_probe()
1499 priv->pcdev.owner = THIS_MODULE; in pd692x0_i2c_probe()
1500 priv->pcdev.ops = &pd692x0_ops; in pd692x0_i2c_probe()
1501 priv->pcdev.dev = dev; in pd692x0_i2c_probe()
1502 priv->pcdev.types = ETHTOOL_PSE_C33; in pd692x0_i2c_probe()
1503 ret = devm_pse_controller_register(dev, &priv->pcdev); in pd692x0_i2c_probe()
1513 priv->fwl = fwl; in pd692x0_i2c_probe()
1522 firmware_upload_unregister(priv->fwl); in pd692x0_i2c_remove()