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