Lines Matching +full:pse +full:- +full:pis
1 // SPDX-License-Identifier: GPL-2.0-only
3 * Driver for the Microchip PD692X0 PoE PSE Controller driver (I2C bus)
14 #include <linux/pse-pd/pse.h>
106 /* Template list of communication messages. The non-null bytes defined here
197 msg->echo = echo++; in pd692x0_build_msg()
201 for (i = 0; i < sizeof(*msg) - sizeof(msg->chksum); i++) in pd692x0_build_msg()
204 msg->chksum = cpu_to_be16(chksum); in pd692x0_build_msg()
211 const struct i2c_client *client = priv->client; in pd692x0_send_msg()
214 if (msg->key == PD692X0_KEY_CMD && priv->last_cmd_key) { in pd692x0_send_msg()
217 cmd_msleep = 30 - jiffies_to_msecs(jiffies - priv->last_cmd_key_time); in pd692x0_send_msg()
223 priv->msg_id = pd692x0_build_msg(msg, priv->msg_id); in pd692x0_send_msg()
227 return -EIO; in pd692x0_send_msg()
234 const struct i2c_client *client = priv->client; in pd692x0_reset()
241 dev_err(&client->dev, in pd692x0_reset()
250 return ret < 0 ? ret : -EIO; in pd692x0_reset()
254 return -EIO; in pd692x0_reset()
260 return ret < 0 ? ret : -EIO; in pd692x0_reset()
264 dev_err(&client->dev, "PSE controller error\n"); in pd692x0_reset()
265 return -EIO; in pd692x0_reset()
280 if (buf->key) in pd692x0_try_recv_msg()
287 if (buf->key) in pd692x0_try_recv_msg()
302 const struct i2c_client *client = priv->client; in pd692x0_recv_msg()
309 dev_warn(&client->dev, in pd692x0_recv_msg()
333 dev_warn(&client->dev, "Communication is back, rtnl is unlocked!"); in pd692x0_recv_msg()
335 if (msg->key == PD692X0_KEY_CMD) { in pd692x0_recv_msg()
336 priv->last_cmd_key = true; in pd692x0_recv_msg()
337 priv->last_cmd_key_time = jiffies; in pd692x0_recv_msg()
339 priv->last_cmd_key = false; in pd692x0_recv_msg()
349 struct device *dev = &priv->client->dev; in pd692x0_sendrecv_msg()
360 if (msg->echo != buf->echo) { in pd692x0_sendrecv_msg()
363 msg->echo, buf->echo); in pd692x0_sendrecv_msg()
364 return -EIO; in pd692x0_sendrecv_msg()
368 if (buf->key == PD692X0_KEY_REPORT && in pd692x0_sendrecv_msg()
369 (buf->sub[0] || buf->sub[1])) { in pd692x0_sendrecv_msg()
370 return -EIO; in pd692x0_sendrecv_msg()
383 switch (priv->fw_state) { in pd692x0_fw_unavailable()
389 dev_err(&priv->client->dev, "Firmware update in progress!\n"); in pd692x0_fw_unavailable()
390 return -EBUSY; in pd692x0_fw_unavailable()
394 dev_err(&priv->client->dev, in pd692x0_fw_unavailable()
396 return -EOPNOTSUPP; in pd692x0_fw_unavailable()
410 if (priv->admin_state[id] == ETHTOOL_C33_PSE_ADMIN_STATE_ENABLED) in pd692x0_pi_enable()
420 priv->admin_state[id] = ETHTOOL_C33_PSE_ADMIN_STATE_ENABLED; in pd692x0_pi_enable()
435 if (priv->admin_state[id] == ETHTOOL_C33_PSE_ADMIN_STATE_DISABLED) in pd692x0_pi_disable()
445 priv->admin_state[id] = ETHTOOL_C33_PSE_ADMIN_STATE_DISABLED; in pd692x0_pi_disable()
531 c33_ext_state_info = &ext_state_info->c33_ext_state_info; in pd692x0_pi_get_ext_state()
533 while (ext_state_map->status_code) { in pd692x0_pi_get_ext_state()
534 if (ext_state_map->status_code == buf.sub[0]) { in pd692x0_pi_get_ext_state()
535 c33_ext_state_info->c33_pse_ext_state = ext_state_map->pse_ext_state; in pd692x0_pi_get_ext_state()
536 c33_ext_state_info->__c33_pse_ext_substate = ext_state_map->pse_ext_substate; in pd692x0_pi_get_ext_state()
571 if (pw_table->class_cfg_value == op_mode) in pd692x0_pi_get_pw_from_table()
572 return pw_table->class_pw + added_pw * 100; in pd692x0_pi_get_pw_from_table()
575 return -ERANGE; in pd692x0_pi_get_pw_from_table()
585 if (pw < pw_table->class_pw) { in pd692x0_pi_set_pw_from_table()
587 "Power limit %dmW not supported. Ranges minimal available: [%d-%d]\n", in pd692x0_pi_set_pw_from_table()
589 pw_table->class_pw, in pd692x0_pi_set_pw_from_table()
590 pw_table->class_pw + pw_table->max_added_class_pw); in pd692x0_pi_set_pw_from_table()
591 return -ERANGE; in pd692x0_pi_set_pw_from_table()
595 if (pw > (pw_table->class_pw + pw_table->max_added_class_pw)) in pd692x0_pi_set_pw_from_table()
598 if (pw < pw_table->class_pw) { in pd692x0_pi_set_pw_from_table()
600 "Power limit %dmW not supported. Ranges available: [%d-%d] or [%d-%d]\n", in pd692x0_pi_set_pw_from_table()
602 (pw_table - 1)->class_pw, in pd692x0_pi_set_pw_from_table()
603 (pw_table - 1)->class_pw + (pw_table - 1)->max_added_class_pw, in pd692x0_pi_set_pw_from_table()
604 pw_table->class_pw, in pd692x0_pi_set_pw_from_table()
605 pw_table->class_pw + pw_table->max_added_class_pw); in pd692x0_pi_set_pw_from_table()
606 return -ERANGE; in pd692x0_pi_set_pw_from_table()
609 msg->data[2] = pw_table->class_cfg_value; in pd692x0_pi_set_pw_from_table()
610 msg->data[3] = (pw - pw_table->class_pw) / 100; in pd692x0_pi_set_pw_from_table()
614 pw_table--; in pd692x0_pi_set_pw_from_table()
617 pw, pw_table->class_pw + pw_table->max_added_class_pw); in pd692x0_pi_set_pw_from_table()
618 msg->data[2] = pw_table->class_cfg_value; in pd692x0_pi_set_pw_from_table()
619 msg->data[3] = pw_table->max_added_class_pw / 100; in pd692x0_pi_set_pw_from_table()
636 return -ENOMEM; in pd692x0_pi_get_pw_limit_ranges()
639 c33_pw_limit_ranges[i].min = pw_table->class_pw; in pd692x0_pi_get_pw_limit_ranges()
640 c33_pw_limit_ranges[i].max = pw_table->class_pw + in pd692x0_pi_get_pw_limit_ranges()
641 pw_table->max_added_class_pw; in pd692x0_pi_get_pw_limit_ranges()
644 pw_limit_ranges->c33_pw_limit_ranges = c33_pw_limit_ranges; in pd692x0_pi_get_pw_limit_ranges()
667 admin_state->c33_admin_state = in pd692x0_pi_get_admin_state()
670 admin_state->c33_admin_state = in pd692x0_pi_get_admin_state()
673 priv->admin_state[id] = admin_state->c33_admin_state; in pd692x0_pi_get_admin_state()
698 pw_status->c33_pw_status = in pd692x0_pi_get_pw_status()
701 pw_status->c33_pw_status = in pd692x0_pi_get_pw_status()
704 pw_status->c33_pw_status = in pd692x0_pi_get_pw_status()
707 pw_status->c33_pw_status = in pd692x0_pi_get_pw_status()
774 if (!buf.data[2] || buf.data[2] > pcdev->pis_prio_max + 1) in pd692x0_pi_get_prio()
775 return -ERANGE; in pd692x0_pi_get_prio()
777 /* PSE core priority start at 0 */ in pd692x0_pi_get_prio()
778 return buf.data[2] - 1; in pd692x0_pi_get_prio()
783 struct device *dev = &priv->client->dev; in pd692x0_get_sw_version()
791 dev_err(dev, "Failed to get PSE version (%pe)\n", ERR_PTR(ret)); in pd692x0_get_sw_version()
837 dev_err(&priv->client->dev, in pd692x0_of_get_ports_manager()
840 ret = -EINVAL; in pd692x0_of_get_ports_manager()
845 manager->port_node[port] = node; in pd692x0_of_get_ports_manager()
849 manager->nports = nports; in pd692x0_of_get_ports_manager()
854 of_node_put(manager->port_node[i]); in pd692x0_of_get_ports_manager()
855 manager->port_node[i] = NULL; in pd692x0_of_get_ports_manager()
868 if (!priv->np) in pd692x0_of_get_managers()
869 return -EINVAL; in pd692x0_of_get_managers()
872 managers_node = of_get_child_by_name(priv->np, "managers"); in pd692x0_of_get_managers()
874 return -EINVAL; in pd692x0_of_get_managers()
888 dev_err(&priv->client->dev, in pd692x0_of_get_managers()
891 ret = -EINVAL; in pd692x0_of_get_managers()
937 return ERR_PTR(-ENOMEM); in pd692x0_register_manager_regulator()
941 return ERR_PTR(-ENOMEM); in pd692x0_register_manager_regulator()
943 rdesc->name = reg_name; in pd692x0_register_manager_regulator()
944 rdesc->type = REGULATOR_VOLTAGE; in pd692x0_register_manager_regulator()
945 rdesc->ops = &dummy_ops; in pd692x0_register_manager_regulator()
946 rdesc->owner = THIS_MODULE; in pd692x0_register_manager_regulator()
948 rinit_data->supply_regulator = "vmain"; in pd692x0_register_manager_regulator()
969 struct device *dev = &priv->client->dev; in pd692x0_register_managers_regulator()
986 return -ENOMEM; in pd692x0_register_managers_regulator()
987 snprintf(reg_name, 26, "pse-%s-manager%d", dev_name(dev), i); in pd692x0_register_managers_regulator()
995 * virtual device rdev->dev. in pd692x0_register_managers_regulator()
997 ret = devm_regulator_bulk_get_enable(&rdev->dev, in pd692x0_register_managers_regulator()
1001 return dev_err_probe(&rdev->dev, ret, in pd692x0_register_managers_regulator()
1004 priv->manager_reg[i] = rdev; in pd692x0_register_managers_regulator()
1040 struct regulator *supply = priv->manager_reg[i]->supply; in pd692x0_configure_managers()
1055 priv->manager_pw_budget[i] = pw_budget; in pd692x0_configure_managers()
1072 if (!pairset->np) in pd692x0_set_port_matrix()
1080 if (pairset->np == manager[i].port_node[j]) { in pd692x0_set_port_matrix()
1092 return -ENODEV; in pd692x0_set_port_matrix()
1094 if (pairset->pinout == ALTERNATIVE_A) in pd692x0_set_port_matrix()
1095 port_matrix->hw_port_a = port_cnt; in pd692x0_set_port_matrix()
1096 else if (pairset->pinout == ALTERNATIVE_B) in pd692x0_set_port_matrix()
1097 port_matrix->hw_port_b = port_cnt; in pd692x0_set_port_matrix()
1108 struct pse_controller_dev *pcdev = &priv->pcdev; in pd692x0_set_ports_matrix()
1117 /* Update with values for every PSE PIs */ in pd692x0_set_ports_matrix()
1118 for (i = 0; i < pcdev->nr_lines; i++) { in pd692x0_set_ports_matrix()
1119 ret = pd692x0_set_port_matrix(&pcdev->pi[i].pairset[0], in pd692x0_set_ports_matrix()
1123 dev_err(&priv->client->dev, in pd692x0_set_ports_matrix()
1128 ret = pd692x0_set_port_matrix(&pcdev->pi[i].pairset[1], in pd692x0_set_ports_matrix()
1132 dev_err(&priv->client->dev, in pd692x0_set_ports_matrix()
1189 if (!priv->manager_reg[i] || !priv->manager_pw_budget[i]) in pd692x0_managers_free_pw_budget()
1192 supply = priv->manager_reg[i]->supply; in pd692x0_managers_free_pw_budget()
1197 priv->manager_pw_budget[i]); in pd692x0_managers_free_pw_budget()
1209 if (priv->fw_state != PD692X0_FW_OK && in pd692x0_setup_pi_matrix()
1210 priv->fw_state != PD692X0_FW_COMPLETE) in pd692x0_setup_pi_matrix()
1215 return -ENOMEM; in pd692x0_setup_pi_matrix()
1288 struct device *dev = &priv->client->dev; in pd692x0_pi_set_pw_limit()
1351 for (i = 0; i < line_size - 1; i++) { in pd692x0_fw_get_next_line()
1361 return -EIO; in pd692x0_fw_get_next_line()
1392 ret = i2c_master_recv(client, fw_msg_buf + 1, msg_size - 1); in pd692x0_fw_recv_resp()
1394 dev_err(&client->dev, in pd692x0_fw_recv_resp()
1418 sizeof("TP\r\n") - 1); in pd692x0_fw_write_line()
1423 sizeof("T*\r\n") - 1); in pd692x0_fw_write_line()
1441 dev_err(&client->dev, in pd692x0_fw_reset()
1463 dev_err(&client->dev, "PSE controller error\n"); in pd692x0_fw_reset()
1469 dev_err(&client->dev, in pd692x0_fw_reset()
1470 "PSE firmware error. Please update it.\n"); in pd692x0_fw_reset()
1480 struct pd692x0_priv *priv = fwl->dd_handle; in pd692x0_fw_prepare()
1481 const struct i2c_client *client = priv->client; in pd692x0_fw_prepare()
1485 priv->cancel_request = false; in pd692x0_fw_prepare()
1486 last_fw_state = priv->fw_state; in pd692x0_fw_prepare()
1488 priv->fw_state = PD692X0_FW_PREPARE; in pd692x0_fw_prepare()
1509 dev_err(&client->dev, in pd692x0_fw_prepare()
1516 ret = pd692x0_fw_recv_resp(client, 100, "TPE\r\n", sizeof("TPE\r\n") - 1); in pd692x0_fw_prepare()
1520 if (priv->cancel_request) { in pd692x0_fw_prepare()
1528 pd692x0_fw_reset(priv->client); in pd692x0_fw_prepare()
1529 priv->fw_state = last_fw_state; in pd692x0_fw_prepare()
1537 struct pd692x0_priv *priv = fwl->dd_handle; in pd692x0_fw_write()
1543 client = priv->client; in pd692x0_fw_write()
1544 priv->fw_state = PD692X0_FW_WRITE; in pd692x0_fw_write()
1550 dev_err(&client->dev, in pd692x0_fw_write()
1556 ret = pd692x0_fw_recv_resp(client, 100, "TOE\r\n", sizeof("TOE\r\n") - 1); in pd692x0_fw_write()
1560 ret = pd692x0_fw_recv_resp(client, 5000, "TE\r\n", sizeof("TE\r\n") - 1); in pd692x0_fw_write()
1562 dev_warn(&client->dev, in pd692x0_fw_write()
1565 ret = pd692x0_fw_recv_resp(client, 100, "TPE\r\n", sizeof("TPE\r\n") - 1); in pd692x0_fw_write()
1567 dev_warn(&client->dev, in pd692x0_fw_write()
1570 if (priv->cancel_request) in pd692x0_fw_write()
1577 dev_err(&client->dev, in pd692x0_fw_write()
1583 ret = pd692x0_fw_recv_resp(client, 100, "TOP\r\n", sizeof("TOP\r\n") - 1); in pd692x0_fw_write()
1589 ret = pd692x0_fw_get_next_line(data, line, size - i); in pd692x0_fw_write()
1609 if (priv->cancel_request) { in pd692x0_fw_write()
1628 struct pd692x0_priv *priv = fwl->dd_handle; in pd692x0_fw_poll_complete()
1629 const struct i2c_client *client = priv->client; in pd692x0_fw_poll_complete()
1633 priv->fw_state = PD692X0_FW_COMPLETE; in pd692x0_fw_poll_complete()
1641 dev_err(&client->dev, in pd692x0_fw_poll_complete()
1643 priv->fw_state = PD692X0_FW_NEED_UPDATE; in pd692x0_fw_poll_complete()
1647 ret = pd692x0_setup_pi_matrix(&priv->pcdev); in pd692x0_fw_poll_complete()
1649 dev_err(&client->dev, "Error configuring ports matrix (%pe)\n", in pd692x0_fw_poll_complete()
1651 priv->fw_state = PD692X0_FW_NEED_UPDATE; in pd692x0_fw_poll_complete()
1655 priv->fw_state = PD692X0_FW_OK; in pd692x0_fw_poll_complete()
1661 struct pd692x0_priv *priv = fwl->dd_handle; in pd692x0_fw_cancel()
1663 priv->cancel_request = true; in pd692x0_fw_cancel()
1668 struct pd692x0_priv *priv = fwl->dd_handle; in pd692x0_fw_cleanup()
1670 switch (priv->fw_state) { in pd692x0_fw_cleanup()
1672 pd692x0_fw_reset(priv->client); in pd692x0_fw_cleanup()
1675 priv->fw_state = PD692X0_FW_BROKEN; in pd692x0_fw_cleanup()
1694 struct device *dev = &client->dev; in pd692x0_i2c_probe()
1706 if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { in pd692x0_i2c_probe()
1708 return -ENXIO; in pd692x0_i2c_probe()
1713 return -ENOMEM; in pd692x0_i2c_probe()
1715 priv->client = client; in pd692x0_i2c_probe()
1721 return -EIO; in pd692x0_i2c_probe()
1736 dev_err(dev, "PSE controller error\n"); in pd692x0_i2c_probe()
1737 return -EIO; in pd692x0_i2c_probe()
1740 dev_err(dev, "PSE firmware error. Please update it.\n"); in pd692x0_i2c_probe()
1741 priv->fw_state = PD692X0_FW_BROKEN; in pd692x0_i2c_probe()
1744 dev_info(&client->dev, "Software version %d.%02d.%d.%d\n", in pd692x0_i2c_probe()
1750 priv->fw_state = PD692X0_FW_NEED_UPDATE; in pd692x0_i2c_probe()
1752 priv->fw_state = PD692X0_FW_OK; in pd692x0_i2c_probe()
1756 priv->np = dev->of_node; in pd692x0_i2c_probe()
1757 priv->pcdev.nr_lines = PD692X0_MAX_PIS; in pd692x0_i2c_probe()
1758 priv->pcdev.owner = THIS_MODULE; in pd692x0_i2c_probe()
1759 priv->pcdev.ops = &pd692x0_ops; in pd692x0_i2c_probe()
1760 priv->pcdev.dev = dev; in pd692x0_i2c_probe()
1761 priv->pcdev.types = ETHTOOL_PSE_C33; in pd692x0_i2c_probe()
1762 priv->pcdev.supp_budget_eval_strategies = PSE_BUDGET_EVAL_STRAT_DYNAMIC; in pd692x0_i2c_probe()
1763 priv->pcdev.pis_prio_max = 2; in pd692x0_i2c_probe()
1764 ret = devm_pse_controller_register(dev, &priv->pcdev); in pd692x0_i2c_probe()
1767 "failed to register PSE controller\n"); in pd692x0_i2c_probe()
1774 priv->fwl = fwl; in pd692x0_i2c_probe()
1784 firmware_upload_unregister(priv->fwl); in pd692x0_i2c_remove()
1813 MODULE_DESCRIPTION("Microchip PD692x0 PoE PSE Controller driver");