1*c3e382adSJiawen Wu // SPDX-License-Identifier: GPL-2.0
2*c3e382adSJiawen Wu /* Copyright (c) 2015 - 2023 Beijing WangXun Technology Co., Ltd. */
3*c3e382adSJiawen Wu 
4*c3e382adSJiawen Wu #include <linux/gpio/property.h>
5*c3e382adSJiawen Wu #include <linux/i2c.h>
6*c3e382adSJiawen Wu #include <linux/pci.h>
7*c3e382adSJiawen Wu 
8*c3e382adSJiawen Wu #include "../libwx/wx_type.h"
9*c3e382adSJiawen Wu #include "txgbe_type.h"
10*c3e382adSJiawen Wu #include "txgbe_phy.h"
11*c3e382adSJiawen Wu 
12*c3e382adSJiawen Wu static int txgbe_swnodes_register(struct txgbe *txgbe)
13*c3e382adSJiawen Wu {
14*c3e382adSJiawen Wu 	struct txgbe_nodes *nodes = &txgbe->nodes;
15*c3e382adSJiawen Wu 	struct pci_dev *pdev = txgbe->wx->pdev;
16*c3e382adSJiawen Wu 	struct software_node *swnodes;
17*c3e382adSJiawen Wu 	u32 id;
18*c3e382adSJiawen Wu 
19*c3e382adSJiawen Wu 	id = (pdev->bus->number << 8) | pdev->devfn;
20*c3e382adSJiawen Wu 
21*c3e382adSJiawen Wu 	snprintf(nodes->gpio_name, sizeof(nodes->gpio_name), "txgbe_gpio-%x", id);
22*c3e382adSJiawen Wu 	snprintf(nodes->i2c_name, sizeof(nodes->i2c_name), "txgbe_i2c-%x", id);
23*c3e382adSJiawen Wu 	snprintf(nodes->sfp_name, sizeof(nodes->sfp_name), "txgbe_sfp-%x", id);
24*c3e382adSJiawen Wu 	snprintf(nodes->phylink_name, sizeof(nodes->phylink_name), "txgbe_phylink-%x", id);
25*c3e382adSJiawen Wu 
26*c3e382adSJiawen Wu 	swnodes = nodes->swnodes;
27*c3e382adSJiawen Wu 
28*c3e382adSJiawen Wu 	/* GPIO 0: tx fault
29*c3e382adSJiawen Wu 	 * GPIO 1: tx disable
30*c3e382adSJiawen Wu 	 * GPIO 2: sfp module absent
31*c3e382adSJiawen Wu 	 * GPIO 3: rx signal lost
32*c3e382adSJiawen Wu 	 * GPIO 4: rate select, 1G(0) 10G(1)
33*c3e382adSJiawen Wu 	 * GPIO 5: rate select, 1G(0) 10G(1)
34*c3e382adSJiawen Wu 	 */
35*c3e382adSJiawen Wu 	nodes->gpio_props[0] = PROPERTY_ENTRY_STRING("pinctrl-names", "default");
36*c3e382adSJiawen Wu 	swnodes[SWNODE_GPIO] = NODE_PROP(nodes->gpio_name, nodes->gpio_props);
37*c3e382adSJiawen Wu 	nodes->gpio0_ref[0] = SOFTWARE_NODE_REFERENCE(&swnodes[SWNODE_GPIO], 0, GPIO_ACTIVE_HIGH);
38*c3e382adSJiawen Wu 	nodes->gpio1_ref[0] = SOFTWARE_NODE_REFERENCE(&swnodes[SWNODE_GPIO], 1, GPIO_ACTIVE_HIGH);
39*c3e382adSJiawen Wu 	nodes->gpio2_ref[0] = SOFTWARE_NODE_REFERENCE(&swnodes[SWNODE_GPIO], 2, GPIO_ACTIVE_LOW);
40*c3e382adSJiawen Wu 	nodes->gpio3_ref[0] = SOFTWARE_NODE_REFERENCE(&swnodes[SWNODE_GPIO], 3, GPIO_ACTIVE_HIGH);
41*c3e382adSJiawen Wu 	nodes->gpio4_ref[0] = SOFTWARE_NODE_REFERENCE(&swnodes[SWNODE_GPIO], 4, GPIO_ACTIVE_HIGH);
42*c3e382adSJiawen Wu 	nodes->gpio5_ref[0] = SOFTWARE_NODE_REFERENCE(&swnodes[SWNODE_GPIO], 5, GPIO_ACTIVE_HIGH);
43*c3e382adSJiawen Wu 
44*c3e382adSJiawen Wu 	nodes->i2c_props[0] = PROPERTY_ENTRY_STRING("compatible", "snps,designware-i2c");
45*c3e382adSJiawen Wu 	nodes->i2c_props[1] = PROPERTY_ENTRY_BOOL("wx,i2c-snps-model");
46*c3e382adSJiawen Wu 	nodes->i2c_props[2] = PROPERTY_ENTRY_U32("clock-frequency", I2C_MAX_STANDARD_MODE_FREQ);
47*c3e382adSJiawen Wu 	swnodes[SWNODE_I2C] = NODE_PROP(nodes->i2c_name, nodes->i2c_props);
48*c3e382adSJiawen Wu 	nodes->i2c_ref[0] = SOFTWARE_NODE_REFERENCE(&swnodes[SWNODE_I2C]);
49*c3e382adSJiawen Wu 
50*c3e382adSJiawen Wu 	nodes->sfp_props[0] = PROPERTY_ENTRY_STRING("compatible", "sff,sfp");
51*c3e382adSJiawen Wu 	nodes->sfp_props[1] = PROPERTY_ENTRY_REF_ARRAY("i2c-bus", nodes->i2c_ref);
52*c3e382adSJiawen Wu 	nodes->sfp_props[2] = PROPERTY_ENTRY_REF_ARRAY("tx-fault-gpios", nodes->gpio0_ref);
53*c3e382adSJiawen Wu 	nodes->sfp_props[3] = PROPERTY_ENTRY_REF_ARRAY("tx-disable-gpios", nodes->gpio1_ref);
54*c3e382adSJiawen Wu 	nodes->sfp_props[4] = PROPERTY_ENTRY_REF_ARRAY("mod-def0-gpios", nodes->gpio2_ref);
55*c3e382adSJiawen Wu 	nodes->sfp_props[5] = PROPERTY_ENTRY_REF_ARRAY("los-gpios", nodes->gpio3_ref);
56*c3e382adSJiawen Wu 	nodes->sfp_props[6] = PROPERTY_ENTRY_REF_ARRAY("rate-select1-gpios", nodes->gpio4_ref);
57*c3e382adSJiawen Wu 	nodes->sfp_props[7] = PROPERTY_ENTRY_REF_ARRAY("rate-select0-gpios", nodes->gpio5_ref);
58*c3e382adSJiawen Wu 	swnodes[SWNODE_SFP] = NODE_PROP(nodes->sfp_name, nodes->sfp_props);
59*c3e382adSJiawen Wu 	nodes->sfp_ref[0] = SOFTWARE_NODE_REFERENCE(&swnodes[SWNODE_SFP]);
60*c3e382adSJiawen Wu 
61*c3e382adSJiawen Wu 	nodes->phylink_props[0] = PROPERTY_ENTRY_STRING("managed", "in-band-status");
62*c3e382adSJiawen Wu 	nodes->phylink_props[1] = PROPERTY_ENTRY_REF_ARRAY("sfp", nodes->sfp_ref);
63*c3e382adSJiawen Wu 	swnodes[SWNODE_PHYLINK] = NODE_PROP(nodes->phylink_name, nodes->phylink_props);
64*c3e382adSJiawen Wu 
65*c3e382adSJiawen Wu 	nodes->group[SWNODE_GPIO] = &swnodes[SWNODE_GPIO];
66*c3e382adSJiawen Wu 	nodes->group[SWNODE_I2C] = &swnodes[SWNODE_I2C];
67*c3e382adSJiawen Wu 	nodes->group[SWNODE_SFP] = &swnodes[SWNODE_SFP];
68*c3e382adSJiawen Wu 	nodes->group[SWNODE_PHYLINK] = &swnodes[SWNODE_PHYLINK];
69*c3e382adSJiawen Wu 
70*c3e382adSJiawen Wu 	return software_node_register_node_group(nodes->group);
71*c3e382adSJiawen Wu }
72*c3e382adSJiawen Wu 
73*c3e382adSJiawen Wu int txgbe_init_phy(struct txgbe *txgbe)
74*c3e382adSJiawen Wu {
75*c3e382adSJiawen Wu 	int ret;
76*c3e382adSJiawen Wu 
77*c3e382adSJiawen Wu 	ret = txgbe_swnodes_register(txgbe);
78*c3e382adSJiawen Wu 	if (ret) {
79*c3e382adSJiawen Wu 		wx_err(txgbe->wx, "failed to register software nodes\n");
80*c3e382adSJiawen Wu 		return ret;
81*c3e382adSJiawen Wu 	}
82*c3e382adSJiawen Wu 
83*c3e382adSJiawen Wu 	return 0;
84*c3e382adSJiawen Wu }
85*c3e382adSJiawen Wu 
86*c3e382adSJiawen Wu void txgbe_remove_phy(struct txgbe *txgbe)
87*c3e382adSJiawen Wu {
88*c3e382adSJiawen Wu 	software_node_unregister_node_group(txgbe->nodes.group);
89*c3e382adSJiawen Wu }
90