diff options
author | Eilon Greenstein <eilong@broadcom.com> | 2009-02-12 03:36:52 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-02-16 02:31:20 -0500 |
commit | 4acac6a53a3c9dfc604a9a8647f16b0242080e93 (patch) | |
tree | d21f2687f4d580f22e0aa018dc9eccaaa56de005 /drivers | |
parent | 87942b467880fb65381af87a5ff61fdb7ede5eb3 (diff) |
bnx2x: GPIO accessories
A GPIO is used with the 8726 PHY. Adding the GPIO related functions in this
Signed-off-by: Eilon Greenstein <eilong@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/bnx2x.h | 2 | ||||
-rw-r--r-- | drivers/net/bnx2x_main.c | 80 | ||||
-rw-r--r-- | drivers/net/bnx2x_reg.h | 29 |
3 files changed, 109 insertions, 2 deletions
diff --git a/drivers/net/bnx2x.h b/drivers/net/bnx2x.h index 2397a891e1ba..d66be72d8321 100644 --- a/drivers/net/bnx2x.h +++ b/drivers/net/bnx2x.h | |||
@@ -982,7 +982,9 @@ struct bnx2x { | |||
982 | void bnx2x_read_dmae(struct bnx2x *bp, u32 src_addr, u32 len32); | 982 | void bnx2x_read_dmae(struct bnx2x *bp, u32 src_addr, u32 len32); |
983 | void bnx2x_write_dmae(struct bnx2x *bp, dma_addr_t dma_addr, u32 dst_addr, | 983 | void bnx2x_write_dmae(struct bnx2x *bp, dma_addr_t dma_addr, u32 dst_addr, |
984 | u32 len32); | 984 | u32 len32); |
985 | int bnx2x_get_gpio(struct bnx2x *bp, int gpio_num, u8 port); | ||
985 | int bnx2x_set_gpio(struct bnx2x *bp, int gpio_num, u32 mode, u8 port); | 986 | int bnx2x_set_gpio(struct bnx2x *bp, int gpio_num, u32 mode, u8 port); |
987 | int bnx2x_set_gpio_int(struct bnx2x *bp, int gpio_num, u32 mode, u8 port); | ||
986 | 988 | ||
987 | static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms, | 989 | static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms, |
988 | int wait) | 990 | int wait) |
diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c index 9c40b02b65f6..95f8e58e73b4 100644 --- a/drivers/net/bnx2x_main.c +++ b/drivers/net/bnx2x_main.c | |||
@@ -626,8 +626,8 @@ static void bnx2x_int_enable(struct bnx2x *bp) | |||
626 | if (IS_E1HMF(bp)) { | 626 | if (IS_E1HMF(bp)) { |
627 | val = (0xee0f | (1 << (BP_E1HVN(bp) + 4))); | 627 | val = (0xee0f | (1 << (BP_E1HVN(bp) + 4))); |
628 | if (bp->port.pmf) | 628 | if (bp->port.pmf) |
629 | /* enable nig attention */ | 629 | /* enable nig and gpio3 attention */ |
630 | val |= 0x0100; | 630 | val |= 0x1100; |
631 | } else | 631 | } else |
632 | val = 0xffff; | 632 | val = 0xffff; |
633 | 633 | ||
@@ -1836,6 +1836,36 @@ static void bnx2x_release_phy_lock(struct bnx2x *bp) | |||
1836 | mutex_unlock(&bp->port.phy_mutex); | 1836 | mutex_unlock(&bp->port.phy_mutex); |
1837 | } | 1837 | } |
1838 | 1838 | ||
1839 | int bnx2x_get_gpio(struct bnx2x *bp, int gpio_num, u8 port) | ||
1840 | { | ||
1841 | /* The GPIO should be swapped if swap register is set and active */ | ||
1842 | int gpio_port = (REG_RD(bp, NIG_REG_PORT_SWAP) && | ||
1843 | REG_RD(bp, NIG_REG_STRAP_OVERRIDE)) ^ port; | ||
1844 | int gpio_shift = gpio_num + | ||
1845 | (gpio_port ? MISC_REGISTERS_GPIO_PORT_SHIFT : 0); | ||
1846 | u32 gpio_mask = (1 << gpio_shift); | ||
1847 | u32 gpio_reg; | ||
1848 | int value; | ||
1849 | |||
1850 | if (gpio_num > MISC_REGISTERS_GPIO_3) { | ||
1851 | BNX2X_ERR("Invalid GPIO %d\n", gpio_num); | ||
1852 | return -EINVAL; | ||
1853 | } | ||
1854 | |||
1855 | /* read GPIO value */ | ||
1856 | gpio_reg = REG_RD(bp, MISC_REG_GPIO); | ||
1857 | |||
1858 | /* get the requested pin value */ | ||
1859 | if ((gpio_reg & gpio_mask) == gpio_mask) | ||
1860 | value = 1; | ||
1861 | else | ||
1862 | value = 0; | ||
1863 | |||
1864 | DP(NETIF_MSG_LINK, "pin %d value 0x%x\n", gpio_num, value); | ||
1865 | |||
1866 | return value; | ||
1867 | } | ||
1868 | |||
1839 | int bnx2x_set_gpio(struct bnx2x *bp, int gpio_num, u32 mode, u8 port) | 1869 | int bnx2x_set_gpio(struct bnx2x *bp, int gpio_num, u32 mode, u8 port) |
1840 | { | 1870 | { |
1841 | /* The GPIO should be swapped if swap register is set and active */ | 1871 | /* The GPIO should be swapped if swap register is set and active */ |
@@ -1889,6 +1919,52 @@ int bnx2x_set_gpio(struct bnx2x *bp, int gpio_num, u32 mode, u8 port) | |||
1889 | return 0; | 1919 | return 0; |
1890 | } | 1920 | } |
1891 | 1921 | ||
1922 | int bnx2x_set_gpio_int(struct bnx2x *bp, int gpio_num, u32 mode, u8 port) | ||
1923 | { | ||
1924 | /* The GPIO should be swapped if swap register is set and active */ | ||
1925 | int gpio_port = (REG_RD(bp, NIG_REG_PORT_SWAP) && | ||
1926 | REG_RD(bp, NIG_REG_STRAP_OVERRIDE)) ^ port; | ||
1927 | int gpio_shift = gpio_num + | ||
1928 | (gpio_port ? MISC_REGISTERS_GPIO_PORT_SHIFT : 0); | ||
1929 | u32 gpio_mask = (1 << gpio_shift); | ||
1930 | u32 gpio_reg; | ||
1931 | |||
1932 | if (gpio_num > MISC_REGISTERS_GPIO_3) { | ||
1933 | BNX2X_ERR("Invalid GPIO %d\n", gpio_num); | ||
1934 | return -EINVAL; | ||
1935 | } | ||
1936 | |||
1937 | bnx2x_acquire_hw_lock(bp, HW_LOCK_RESOURCE_GPIO); | ||
1938 | /* read GPIO int */ | ||
1939 | gpio_reg = REG_RD(bp, MISC_REG_GPIO_INT); | ||
1940 | |||
1941 | switch (mode) { | ||
1942 | case MISC_REGISTERS_GPIO_INT_OUTPUT_CLR: | ||
1943 | DP(NETIF_MSG_LINK, "Clear GPIO INT %d (shift %d) -> " | ||
1944 | "output low\n", gpio_num, gpio_shift); | ||
1945 | /* clear SET and set CLR */ | ||
1946 | gpio_reg &= ~(gpio_mask << MISC_REGISTERS_GPIO_INT_SET_POS); | ||
1947 | gpio_reg |= (gpio_mask << MISC_REGISTERS_GPIO_INT_CLR_POS); | ||
1948 | break; | ||
1949 | |||
1950 | case MISC_REGISTERS_GPIO_INT_OUTPUT_SET: | ||
1951 | DP(NETIF_MSG_LINK, "Set GPIO INT %d (shift %d) -> " | ||
1952 | "output high\n", gpio_num, gpio_shift); | ||
1953 | /* clear CLR and set SET */ | ||
1954 | gpio_reg &= ~(gpio_mask << MISC_REGISTERS_GPIO_INT_CLR_POS); | ||
1955 | gpio_reg |= (gpio_mask << MISC_REGISTERS_GPIO_INT_SET_POS); | ||
1956 | break; | ||
1957 | |||
1958 | default: | ||
1959 | break; | ||
1960 | } | ||
1961 | |||
1962 | REG_WR(bp, MISC_REG_GPIO_INT, gpio_reg); | ||
1963 | bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_GPIO); | ||
1964 | |||
1965 | return 0; | ||
1966 | } | ||
1967 | |||
1892 | static int bnx2x_set_spio(struct bnx2x *bp, int spio_num, u32 mode) | 1968 | static int bnx2x_set_spio(struct bnx2x *bp, int spio_num, u32 mode) |
1893 | { | 1969 | { |
1894 | u32 spio_mask = (1 << spio_num); | 1970 | u32 spio_mask = (1 << spio_num); |
diff --git a/drivers/net/bnx2x_reg.h b/drivers/net/bnx2x_reg.h index 713b5f9ea1e2..6fc1d0df9789 100644 --- a/drivers/net/bnx2x_reg.h +++ b/drivers/net/bnx2x_reg.h | |||
@@ -1438,6 +1438,29 @@ | |||
1438 | This is the result value of the pin; not the drive value. Writing these | 1438 | This is the result value of the pin; not the drive value. Writing these |
1439 | bits will have not effect. */ | 1439 | bits will have not effect. */ |
1440 | #define MISC_REG_GPIO 0xa490 | 1440 | #define MISC_REG_GPIO 0xa490 |
1441 | /* [RW 8] These bits enable the GPIO_INTs to signals event to the | ||
1442 | IGU/MCP.according to the following map: [0] p0_gpio_0; [1] p0_gpio_1; [2] | ||
1443 | p0_gpio_2; [3] p0_gpio_3; [4] p1_gpio_0; [5] p1_gpio_1; [6] p1_gpio_2; | ||
1444 | [7] p1_gpio_3; */ | ||
1445 | #define MISC_REG_GPIO_EVENT_EN 0xa2bc | ||
1446 | /* [RW 32] GPIO INT. [31-28] OLD_CLR port1; [27-24] OLD_CLR port0; Writing a | ||
1447 | '1' to these bit clears the corresponding bit in the #OLD_VALUE register. | ||
1448 | This will acknowledge an interrupt on the falling edge of corresponding | ||
1449 | GPIO input (reset value 0). [23-16] OLD_SET [23-16] port1; OLD_SET port0; | ||
1450 | Writing a '1' to these bit sets the corresponding bit in the #OLD_VALUE | ||
1451 | register. This will acknowledge an interrupt on the rising edge of | ||
1452 | corresponding SPIO input (reset value 0). [15-12] OLD_VALUE [11-8] port1; | ||
1453 | OLD_VALUE port0; RO; These bits indicate the old value of the GPIO input | ||
1454 | value. When the ~INT_STATE bit is set; this bit indicates the OLD value | ||
1455 | of the pin such that if ~INT_STATE is set and this bit is '0'; then the | ||
1456 | interrupt is due to a low to high edge. If ~INT_STATE is set and this bit | ||
1457 | is '1'; then the interrupt is due to a high to low edge (reset value 0). | ||
1458 | [7-4] INT_STATE port1; [3-0] INT_STATE RO port0; These bits indicate the | ||
1459 | current GPIO interrupt state for each GPIO pin. This bit is cleared when | ||
1460 | the appropriate #OLD_SET or #OLD_CLR command bit is written. This bit is | ||
1461 | set when the GPIO input does not match the current value in #OLD_VALUE | ||
1462 | (reset value 0). */ | ||
1463 | #define MISC_REG_GPIO_INT 0xa494 | ||
1441 | /* [R 28] this field hold the last information that caused reserved | 1464 | /* [R 28] this field hold the last information that caused reserved |
1442 | attention. bits [19:0] - address; [22:20] function; [23] reserved; | 1465 | attention. bits [19:0] - address; [22:20] function; [23] reserved; |
1443 | [27:24] the master that caused the attention - according to the following | 1466 | [27:24] the master that caused the attention - according to the following |
@@ -5162,6 +5185,10 @@ | |||
5162 | #define MISC_REGISTERS_GPIO_FLOAT_POS 24 | 5185 | #define MISC_REGISTERS_GPIO_FLOAT_POS 24 |
5163 | #define MISC_REGISTERS_GPIO_HIGH 1 | 5186 | #define MISC_REGISTERS_GPIO_HIGH 1 |
5164 | #define MISC_REGISTERS_GPIO_INPUT_HI_Z 2 | 5187 | #define MISC_REGISTERS_GPIO_INPUT_HI_Z 2 |
5188 | #define MISC_REGISTERS_GPIO_INT_CLR_POS 24 | ||
5189 | #define MISC_REGISTERS_GPIO_INT_OUTPUT_CLR 0 | ||
5190 | #define MISC_REGISTERS_GPIO_INT_OUTPUT_SET 1 | ||
5191 | #define MISC_REGISTERS_GPIO_INT_SET_POS 16 | ||
5165 | #define MISC_REGISTERS_GPIO_LOW 0 | 5192 | #define MISC_REGISTERS_GPIO_LOW 0 |
5166 | #define MISC_REGISTERS_GPIO_OUTPUT_HIGH 1 | 5193 | #define MISC_REGISTERS_GPIO_OUTPUT_HIGH 1 |
5167 | #define MISC_REGISTERS_GPIO_OUTPUT_LOW 0 | 5194 | #define MISC_REGISTERS_GPIO_OUTPUT_LOW 0 |
@@ -5220,6 +5247,8 @@ | |||
5220 | #define AEU_INPUTS_ATTN_BITS_DMAE_HW_INTERRUPT (1<<11) | 5247 | #define AEU_INPUTS_ATTN_BITS_DMAE_HW_INTERRUPT (1<<11) |
5221 | #define AEU_INPUTS_ATTN_BITS_DOORBELLQ_HW_INTERRUPT (1<<13) | 5248 | #define AEU_INPUTS_ATTN_BITS_DOORBELLQ_HW_INTERRUPT (1<<13) |
5222 | #define AEU_INPUTS_ATTN_BITS_DOORBELLQ_PARITY_ERROR (1<<12) | 5249 | #define AEU_INPUTS_ATTN_BITS_DOORBELLQ_PARITY_ERROR (1<<12) |
5250 | #define AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_0 (1<<5) | ||
5251 | #define AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_1 (1<<9) | ||
5223 | #define AEU_INPUTS_ATTN_BITS_IGU_PARITY_ERROR (1<<12) | 5252 | #define AEU_INPUTS_ATTN_BITS_IGU_PARITY_ERROR (1<<12) |
5224 | #define AEU_INPUTS_ATTN_BITS_MISC_HW_INTERRUPT (1<<15) | 5253 | #define AEU_INPUTS_ATTN_BITS_MISC_HW_INTERRUPT (1<<15) |
5225 | #define AEU_INPUTS_ATTN_BITS_MISC_PARITY_ERROR (1<<14) | 5254 | #define AEU_INPUTS_ATTN_BITS_MISC_PARITY_ERROR (1<<14) |