Lines Matching +full:pse +full:- +full:pd
1 // SPDX-License-Identifier: GPL-2.0-only
11 #include <linux/pse-pd/pse.h>
19 * struct pse_control - a PSE control
20 * @pcdev: a pointer to the PSE controller device
21 * this PSE control belongs to
22 * @ps: PSE PI supply of the PSE control
23 * @list: list entry for the pcdev's PSE controller list
24 * @id: ID of the PSE line in the PSE controller device
43 ret = of_property_read_string_index(node, "pairset-names", in of_load_single_pse_pi_pairset()
48 if (!strcmp(name, "alternative-a")) { in of_load_single_pse_pi_pairset()
49 pi->pairset[pairset_num].pinout = ALTERNATIVE_A; in of_load_single_pse_pi_pairset()
50 } else if (!strcmp(name, "alternative-b")) { in of_load_single_pse_pi_pairset()
51 pi->pairset[pairset_num].pinout = ALTERNATIVE_B; in of_load_single_pse_pi_pairset()
53 pr_err("pse: wrong pairset-names value %s (%pOF)\n", in of_load_single_pse_pi_pairset()
55 return -EINVAL; in of_load_single_pse_pi_pairset()
60 return -ENODEV; in of_load_single_pse_pi_pairset()
62 pi->pairset[pairset_num].np = pairset_np; in of_load_single_pse_pi_pairset()
68 * of_load_pse_pi_pairsets - load PSE PI pairsets pinout and polarity
70 * @pi: a pointer of the PSE PI to fill
81 ret = of_property_count_strings(node, "pairset-names"); in of_load_pse_pi_pairsets()
83 pr_err("pse: amount of pairsets and pairset-names is not equal %d != %d (%pOF)\n", in of_load_pse_pi_pairsets()
85 return -EINVAL; in of_load_pse_pi_pairsets()
95 pi->pairset[0].pinout == pi->pairset[1].pinout) { in of_load_pse_pi_pairsets()
96 pr_err("pse: two PI pairsets can not have identical pinout (%pOF)", in of_load_pse_pi_pairsets()
98 ret = -EINVAL; in of_load_pse_pi_pairsets()
104 of_node_put(pi->pairset[0].np); in of_load_pse_pi_pairsets()
105 pi->pairset[0].np = NULL; in of_load_pse_pi_pairsets()
106 of_node_put(pi->pairset[1].np); in of_load_pse_pi_pairsets()
107 pi->pairset[1].np = NULL; in of_load_pse_pi_pairsets()
117 for (i = 0; i < pcdev->nr_lines; i++) { in pse_release_pis()
118 of_node_put(pcdev->pi[i].pairset[0].np); in pse_release_pis()
119 of_node_put(pcdev->pi[i].pairset[1].np); in pse_release_pis()
120 of_node_put(pcdev->pi[i].np); in pse_release_pis()
122 kfree(pcdev->pi); in pse_release_pis()
126 * of_load_pse_pis - load all the PSE PIs
127 * @pcdev: a pointer to the PSE controller device
133 struct device_node *np = pcdev->dev->of_node; in of_load_pse_pis()
138 return -ENODEV; in of_load_pse_pis()
140 pcdev->pi = kcalloc(pcdev->nr_lines, sizeof(*pcdev->pi), GFP_KERNEL); in of_load_pse_pis()
141 if (!pcdev->pi) in of_load_pse_pis()
142 return -ENOMEM; in of_load_pse_pis()
144 pis = of_get_child_by_name(np, "pse-pis"); in of_load_pse_pis()
146 /* no description of PSE PIs */ in of_load_pse_pis()
147 pcdev->no_of_pse_pi = true; in of_load_pse_pis()
155 if (!of_node_name_eq(node, "pse-pi")) in of_load_pse_pis()
160 dev_err(pcdev->dev, in of_load_pse_pis()
166 if (id >= pcdev->nr_lines) { in of_load_pse_pis()
167 dev_err(pcdev->dev, in of_load_pse_pis()
169 id, pcdev->nr_lines, node); in of_load_pse_pis()
170 ret = -EINVAL; in of_load_pse_pis()
174 if (pcdev->pi[id].np) { in of_load_pse_pis()
175 dev_err(pcdev->dev, in of_load_pse_pis()
177 pcdev->pi[id].np, node); in of_load_pse_pis()
178 ret = -EINVAL; in of_load_pse_pis()
189 dev_err(pcdev->dev, in of_load_pse_pis()
192 ret = -EINVAL; in of_load_pse_pis()
198 memcpy(&pcdev->pi[id], &pi, sizeof(pi)); in of_load_pse_pis()
218 ops = pcdev->ops; in pse_pi_is_enabled()
219 if (!ops->pi_get_admin_state) in pse_pi_is_enabled()
220 return -EOPNOTSUPP; in pse_pi_is_enabled()
223 mutex_lock(&pcdev->lock); in pse_pi_is_enabled()
224 ret = ops->pi_get_admin_state(pcdev, id, &admin_state); in pse_pi_is_enabled()
233 mutex_unlock(&pcdev->lock); in pse_pi_is_enabled()
244 ops = pcdev->ops; in pse_pi_enable()
245 if (!ops->pi_enable) in pse_pi_enable()
246 return -EOPNOTSUPP; in pse_pi_enable()
249 mutex_lock(&pcdev->lock); in pse_pi_enable()
250 ret = ops->pi_enable(pcdev, id); in pse_pi_enable()
252 pcdev->pi[id].admin_state_enabled = 1; in pse_pi_enable()
253 mutex_unlock(&pcdev->lock); in pse_pi_enable()
264 ops = pcdev->ops; in pse_pi_disable()
265 if (!ops->pi_disable) in pse_pi_disable()
266 return -EOPNOTSUPP; in pse_pi_disable()
269 mutex_lock(&pcdev->lock); in pse_pi_disable()
270 ret = ops->pi_disable(pcdev, id); in pse_pi_disable()
272 pcdev->pi[id].admin_state_enabled = 0; in pse_pi_disable()
273 mutex_unlock(&pcdev->lock); in pse_pi_disable()
284 ops = pcdev->ops; in _pse_pi_get_voltage()
285 if (!ops->pi_get_voltage) in _pse_pi_get_voltage()
286 return -EOPNOTSUPP; in _pse_pi_get_voltage()
289 return ops->pi_get_voltage(pcdev, id); in _pse_pi_get_voltage()
297 mutex_lock(&pcdev->lock); in pse_pi_get_voltage()
299 mutex_unlock(&pcdev->lock); in pse_pi_get_voltage()
311 ops = pcdev->ops; in pse_pi_get_current_limit()
313 if (!ops->pi_get_pw_limit || !ops->pi_get_voltage) in pse_pi_get_current_limit()
314 return -EOPNOTSUPP; in pse_pi_get_current_limit()
316 mutex_lock(&pcdev->lock); in pse_pi_get_current_limit()
317 ret = ops->pi_get_pw_limit(pcdev, id); in pse_pi_get_current_limit()
324 dev_err(pcdev->dev, "Voltage null\n"); in pse_pi_get_current_limit()
325 ret = -ERANGE; in pse_pi_get_current_limit()
338 mutex_unlock(&pcdev->lock); in pse_pi_get_current_limit()
350 ops = pcdev->ops; in pse_pi_set_current_limit()
351 if (!ops->pi_set_pw_limit || !ops->pi_get_voltage) in pse_pi_set_current_limit()
352 return -EOPNOTSUPP; in pse_pi_set_current_limit()
355 return -ERANGE; in pse_pi_set_current_limit()
358 mutex_lock(&pcdev->lock); in pse_pi_set_current_limit()
361 dev_err(pcdev->dev, "Voltage null\n"); in pse_pi_set_current_limit()
362 ret = -ERANGE; in pse_pi_set_current_limit()
372 ret = ops->pi_set_pw_limit(pcdev, id, mW); in pse_pi_set_current_limit()
374 mutex_unlock(&pcdev->lock); in pse_pi_set_current_limit()
397 rinit_data = devm_kzalloc(pcdev->dev, sizeof(*rinit_data), in devm_pse_pi_regulator_register()
400 return -ENOMEM; in devm_pse_pi_regulator_register()
402 rdesc = devm_kzalloc(pcdev->dev, sizeof(*rdesc), GFP_KERNEL); in devm_pse_pi_regulator_register()
404 return -ENOMEM; in devm_pse_pi_regulator_register()
407 * PSE PI id for the well functioning of the PSE controls. in devm_pse_pi_regulator_register()
409 rdesc->id = id; in devm_pse_pi_regulator_register()
410 rdesc->name = name; in devm_pse_pi_regulator_register()
411 rdesc->type = REGULATOR_VOLTAGE; in devm_pse_pi_regulator_register()
412 rdesc->ops = &pse_pi_ops; in devm_pse_pi_regulator_register()
413 rdesc->owner = pcdev->owner; in devm_pse_pi_regulator_register()
415 rinit_data->constraints.valid_ops_mask = REGULATOR_CHANGE_STATUS; in devm_pse_pi_regulator_register()
417 if (pcdev->ops->pi_set_pw_limit) in devm_pse_pi_regulator_register()
418 rinit_data->constraints.valid_ops_mask |= in devm_pse_pi_regulator_register()
421 rinit_data->supply_regulator = "vpwr"; in devm_pse_pi_regulator_register()
423 rconfig.dev = pcdev->dev; in devm_pse_pi_regulator_register()
426 rconfig.of_node = pcdev->pi[id].np; in devm_pse_pi_regulator_register()
428 rdev = devm_regulator_register(pcdev->dev, rdesc, &rconfig); in devm_pse_pi_regulator_register()
430 dev_err_probe(pcdev->dev, PTR_ERR(rdev), in devm_pse_pi_regulator_register()
435 pcdev->pi[id].rdev = rdev; in devm_pse_pi_regulator_register()
441 * pse_controller_register - register a PSE controller device
442 * @pcdev: a pointer to the initialized PSE controller device
451 mutex_init(&pcdev->lock); in pse_controller_register()
452 INIT_LIST_HEAD(&pcdev->pse_control_head); in pse_controller_register()
454 if (!pcdev->nr_lines) in pse_controller_register()
455 pcdev->nr_lines = 1; in pse_controller_register()
457 if (!pcdev->ops->pi_get_admin_state || in pse_controller_register()
458 !pcdev->ops->pi_get_pw_status) { in pse_controller_register()
459 dev_err(pcdev->dev, in pse_controller_register()
461 return -EINVAL; in pse_controller_register()
468 if (pcdev->ops->setup_pi_matrix) { in pse_controller_register()
469 ret = pcdev->ops->setup_pi_matrix(pcdev); in pse_controller_register()
477 reg_name_len = strlen(dev_name(pcdev->dev)) + 18; in pse_controller_register()
480 for (i = 0; i < pcdev->nr_lines; i++) { in pse_controller_register()
484 if (!pcdev->no_of_pse_pi && !pcdev->pi[i].np) in pse_controller_register()
487 reg_name = devm_kzalloc(pcdev->dev, reg_name_len, GFP_KERNEL); in pse_controller_register()
489 return -ENOMEM; in pse_controller_register()
491 snprintf(reg_name, reg_name_len, "pse-%s_pi%d", in pse_controller_register()
492 dev_name(pcdev->dev), i); in pse_controller_register()
500 list_add(&pcdev->list, &pse_controller_list); in pse_controller_register()
508 * pse_controller_unregister - unregister a PSE controller device
509 * @pcdev: a pointer to the PSE controller device
515 list_del(&pcdev->list); in pse_controller_unregister()
526 * devm_pse_controller_register - resource managed pse_controller_register()
527 * @dev: device that is registering this PSE controller
528 * @pcdev: a pointer to the initialized PSE controller device
530 * Managed pse_controller_register(). For PSE controllers registered by
545 return -ENOMEM; in devm_pse_controller_register()
560 /* PSE control section */
569 if (psec->pcdev->pi[psec->id].admin_state_enabled) in __pse_control_release()
570 regulator_disable(psec->ps); in __pse_control_release()
571 devm_regulator_put(psec->ps); in __pse_control_release()
573 module_put(psec->pcdev->owner); in __pse_control_release()
575 list_del(&psec->list); in __pse_control_release()
583 kref_put(&psec->refcnt, __pse_control_release); in __pse_control_put_internal()
587 * pse_control_put - free the PSE control
588 * @psec: PSE control pointer
609 list_for_each_entry(psec, &pcdev->pse_control_head, list) { in pse_control_get_internal()
610 if (psec->id == index) { in pse_control_get_internal()
611 kref_get(&psec->refcnt); in pse_control_get_internal()
618 return ERR_PTR(-ENOMEM); in pse_control_get_internal()
620 if (!try_module_get(pcdev->owner)) { in pse_control_get_internal()
621 ret = -ENODEV; in pse_control_get_internal()
625 psec->ps = devm_regulator_get_exclusive(pcdev->dev, in pse_control_get_internal()
626 rdev_get_name(pcdev->pi[index].rdev)); in pse_control_get_internal()
627 if (IS_ERR(psec->ps)) { in pse_control_get_internal()
628 ret = PTR_ERR(psec->ps); in pse_control_get_internal()
632 ret = regulator_is_enabled(psec->ps); in pse_control_get_internal()
636 pcdev->pi[index].admin_state_enabled = ret; in pse_control_get_internal()
638 psec->pcdev = pcdev; in pse_control_get_internal()
639 list_add(&psec->list, &pcdev->pse_control_head); in pse_control_get_internal()
640 psec->id = index; in pse_control_get_internal()
641 kref_init(&psec->refcnt); in pse_control_get_internal()
646 devm_regulator_put(psec->ps); in pse_control_get_internal()
648 module_put(pcdev->owner); in pse_control_get_internal()
656 * of_pse_match_pi - Find the PSE PI id matching the device node phandle
657 * @pcdev: a pointer to the PSE controller device
660 * Return: id of the PSE PI, -EINVAL if not found
667 for (i = 0; i < pcdev->nr_lines; i++) { in of_pse_match_pi()
668 if (pcdev->pi[i].np == np) in of_pse_match_pi()
672 return -EINVAL; in of_pse_match_pi()
676 * psec_id_xlate - translate pse_spec to the PSE line number according
677 * to the number of pse-cells in case of no pse_pi node
678 * @pcdev: a pointer to the PSE controller device
679 * @pse_spec: PSE line specifier as found in the device tree
681 * Return: 0 if #pse-cells = <0>. Return PSE line number otherwise.
686 if (!pcdev->of_pse_n_cells) in psec_id_xlate()
689 if (pcdev->of_pse_n_cells > 1 || in psec_id_xlate()
690 pse_spec->args[0] >= pcdev->nr_lines) in psec_id_xlate()
691 return -EINVAL; in psec_id_xlate()
693 return pse_spec->args[0]; in psec_id_xlate()
705 return ERR_PTR(-EINVAL); in of_pse_control_get()
707 ret = of_parse_phandle_with_args(node, "pses", "#pse-cells", 0, &args); in of_pse_control_get()
714 if (!r->no_of_pse_pi) { in of_pse_control_get()
721 } else if (args.np == r->dev->of_node) { in of_pse_control_get()
728 psec = ERR_PTR(-EPROBE_DEFER); in of_pse_control_get()
732 if (WARN_ON(args.args_count != pcdev->of_pse_n_cells)) { in of_pse_control_get()
733 psec = ERR_PTR(-EINVAL); in of_pse_control_get()
737 if (pcdev->no_of_pse_pi) { in of_pse_control_get()
757 * pse_ethtool_get_status - get status of PSE control
758 * @psec: PSE control pointer
760 * @status: struct to store PSE status
774 pcdev = psec->pcdev; in pse_ethtool_get_status()
775 ops = pcdev->ops; in pse_ethtool_get_status()
776 mutex_lock(&pcdev->lock); in pse_ethtool_get_status()
777 ret = ops->pi_get_admin_state(pcdev, psec->id, &admin_state); in pse_ethtool_get_status()
780 status->podl_admin_state = admin_state.podl_admin_state; in pse_ethtool_get_status()
781 status->c33_admin_state = admin_state.c33_admin_state; in pse_ethtool_get_status()
783 ret = ops->pi_get_pw_status(pcdev, psec->id, &pw_status); in pse_ethtool_get_status()
786 status->podl_pw_status = pw_status.podl_pw_status; in pse_ethtool_get_status()
787 status->c33_pw_status = pw_status.c33_pw_status; in pse_ethtool_get_status()
789 if (ops->pi_get_ext_state) { in pse_ethtool_get_status()
792 ret = ops->pi_get_ext_state(pcdev, psec->id, in pse_ethtool_get_status()
797 memcpy(&status->c33_ext_state_info, in pse_ethtool_get_status()
799 sizeof(status->c33_ext_state_info)); in pse_ethtool_get_status()
802 if (ops->pi_get_pw_class) { in pse_ethtool_get_status()
803 ret = ops->pi_get_pw_class(pcdev, psec->id); in pse_ethtool_get_status()
807 status->c33_pw_class = ret; in pse_ethtool_get_status()
810 if (ops->pi_get_actual_pw) { in pse_ethtool_get_status()
811 ret = ops->pi_get_actual_pw(pcdev, psec->id); in pse_ethtool_get_status()
815 status->c33_actual_pw = ret; in pse_ethtool_get_status()
818 if (ops->pi_get_pw_limit) { in pse_ethtool_get_status()
819 ret = ops->pi_get_pw_limit(pcdev, psec->id); in pse_ethtool_get_status()
823 status->c33_avail_pw_limit = ret; in pse_ethtool_get_status()
826 if (ops->pi_get_pw_limit_ranges) { in pse_ethtool_get_status()
829 ret = ops->pi_get_pw_limit_ranges(pcdev, psec->id, in pse_ethtool_get_status()
834 status->c33_pw_limit_ranges = in pse_ethtool_get_status()
836 status->c33_pw_limit_nb_ranges = ret; in pse_ethtool_get_status()
839 mutex_unlock(&psec->pcdev->lock); in pse_ethtool_get_status()
852 switch (config->c33_admin_control) { in pse_ethtool_c33_set_config()
859 if (psec->pcdev->pi[psec->id].admin_state_enabled && in pse_ethtool_c33_set_config()
860 !regulator_is_enabled(psec->ps)) { in pse_ethtool_c33_set_config()
861 err = regulator_disable(psec->ps); in pse_ethtool_c33_set_config()
865 if (!psec->pcdev->pi[psec->id].admin_state_enabled) in pse_ethtool_c33_set_config()
866 err = regulator_enable(psec->ps); in pse_ethtool_c33_set_config()
869 if (psec->pcdev->pi[psec->id].admin_state_enabled) in pse_ethtool_c33_set_config()
870 err = regulator_disable(psec->ps); in pse_ethtool_c33_set_config()
873 err = -EOPNOTSUPP; in pse_ethtool_c33_set_config()
887 switch (config->podl_admin_control) { in pse_ethtool_podl_set_config()
889 if (!psec->pcdev->pi[psec->id].admin_state_enabled) in pse_ethtool_podl_set_config()
890 err = regulator_enable(psec->ps); in pse_ethtool_podl_set_config()
893 if (psec->pcdev->pi[psec->id].admin_state_enabled) in pse_ethtool_podl_set_config()
894 err = regulator_disable(psec->ps); in pse_ethtool_podl_set_config()
897 err = -EOPNOTSUPP; in pse_ethtool_podl_set_config()
904 * pse_ethtool_set_config - set PSE control configuration
905 * @psec: PSE control pointer
917 if (pse_has_c33(psec) && config->c33_admin_control) { in pse_ethtool_set_config()
923 if (pse_has_podl(psec) && config->podl_admin_control) in pse_ethtool_set_config()
931 * pse_ethtool_set_pw_limit - set PSE control power limit
932 * @psec: PSE control pointer
946 return -ERANGE; in pse_ethtool_set_pw_limit()
948 ret = regulator_get_voltage(psec->ps); in pse_ethtool_set_pw_limit()
951 "Can't calculate the current, PSE voltage read is 0"); in pse_ethtool_set_pw_limit()
952 return -ERANGE; in pse_ethtool_set_pw_limit()
956 "Error reading PSE voltage"); in pse_ethtool_set_pw_limit()
966 return regulator_set_current_limit(psec->ps, 0, uA); in pse_ethtool_set_pw_limit()
972 return psec->pcdev->types & ETHTOOL_PSE_PODL; in pse_has_podl()
978 return psec->pcdev->types & ETHTOOL_PSE_C33; in pse_has_c33()