diff options
author | Carolyn Wyborny <carolyn.wyborny@intel.com> | 2012-12-06 22:00:30 -0500 |
---|---|---|
committer | Jeff Kirsher <jeffrey.t.kirsher@intel.com> | 2013-01-18 07:55:21 -0500 |
commit | 441fc6fdb47ae739eeda625dce5b069941a54db3 (patch) | |
tree | 4f50c10e7166b3fa6da7c9a20b1371b3f23d5dc0 /drivers/net/ethernet/intel/igb/igb_main.c | |
parent | fa44f2f185f7f9da19d331929bb1b56c1ccd1d93 (diff) |
igb: Add i2c interface to igb.
Some of our adapters have sensors on them accessible via i2c and a private
interface. This patch implements the kernel interface for i2c to those sensors.
Subsequent patches will provide functions to export that data.
Signed-off-by: Carolyn Wyborny <carolyn.wyborny@intel.com>
Tested-by: Jeff Pieper <jeffrey.e.pieper@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Diffstat (limited to 'drivers/net/ethernet/intel/igb/igb_main.c')
-rw-r--r-- | drivers/net/ethernet/intel/igb/igb_main.c | 269 |
1 files changed, 269 insertions, 0 deletions
diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c index 342bbd661d3b..0173b6118424 100644 --- a/drivers/net/ethernet/intel/igb/igb_main.c +++ b/drivers/net/ethernet/intel/igb/igb_main.c | |||
@@ -57,6 +57,7 @@ | |||
57 | #ifdef CONFIG_IGB_DCA | 57 | #ifdef CONFIG_IGB_DCA |
58 | #include <linux/dca.h> | 58 | #include <linux/dca.h> |
59 | #endif | 59 | #endif |
60 | #include <linux/i2c.h> | ||
60 | #include "igb.h" | 61 | #include "igb.h" |
61 | 62 | ||
62 | #define MAJ 4 | 63 | #define MAJ 4 |
@@ -567,6 +568,91 @@ exit: | |||
567 | return; | 568 | return; |
568 | } | 569 | } |
569 | 570 | ||
571 | /* igb_get_i2c_data - Reads the I2C SDA data bit | ||
572 | * @hw: pointer to hardware structure | ||
573 | * @i2cctl: Current value of I2CCTL register | ||
574 | * | ||
575 | * Returns the I2C data bit value | ||
576 | */ | ||
577 | static int igb_get_i2c_data(void *data) | ||
578 | { | ||
579 | struct igb_adapter *adapter = (struct igb_adapter *)data; | ||
580 | struct e1000_hw *hw = &adapter->hw; | ||
581 | s32 i2cctl = rd32(E1000_I2CPARAMS); | ||
582 | |||
583 | return ((i2cctl & E1000_I2C_DATA_IN) != 0); | ||
584 | } | ||
585 | |||
586 | /* igb_set_i2c_data - Sets the I2C data bit | ||
587 | * @data: pointer to hardware structure | ||
588 | * @state: I2C data value (0 or 1) to set | ||
589 | * | ||
590 | * Sets the I2C data bit | ||
591 | */ | ||
592 | static void igb_set_i2c_data(void *data, int state) | ||
593 | { | ||
594 | struct igb_adapter *adapter = (struct igb_adapter *)data; | ||
595 | struct e1000_hw *hw = &adapter->hw; | ||
596 | s32 i2cctl = rd32(E1000_I2CPARAMS); | ||
597 | |||
598 | if (state) | ||
599 | i2cctl |= E1000_I2C_DATA_OUT; | ||
600 | else | ||
601 | i2cctl &= ~E1000_I2C_DATA_OUT; | ||
602 | |||
603 | i2cctl &= ~E1000_I2C_DATA_OE_N; | ||
604 | i2cctl |= E1000_I2C_CLK_OE_N; | ||
605 | wr32(E1000_I2CPARAMS, i2cctl); | ||
606 | wrfl(); | ||
607 | |||
608 | } | ||
609 | |||
610 | /* igb_set_i2c_clk - Sets the I2C SCL clock | ||
611 | * @data: pointer to hardware structure | ||
612 | * @state: state to set clock | ||
613 | * | ||
614 | * Sets the I2C clock line to state | ||
615 | */ | ||
616 | static void igb_set_i2c_clk(void *data, int state) | ||
617 | { | ||
618 | struct igb_adapter *adapter = (struct igb_adapter *)data; | ||
619 | struct e1000_hw *hw = &adapter->hw; | ||
620 | s32 i2cctl = rd32(E1000_I2CPARAMS); | ||
621 | |||
622 | if (state) { | ||
623 | i2cctl |= E1000_I2C_CLK_OUT; | ||
624 | i2cctl &= ~E1000_I2C_CLK_OE_N; | ||
625 | } else { | ||
626 | i2cctl &= ~E1000_I2C_CLK_OUT; | ||
627 | i2cctl &= ~E1000_I2C_CLK_OE_N; | ||
628 | } | ||
629 | wr32(E1000_I2CPARAMS, i2cctl); | ||
630 | wrfl(); | ||
631 | } | ||
632 | |||
633 | /* igb_get_i2c_clk - Gets the I2C SCL clock state | ||
634 | * @data: pointer to hardware structure | ||
635 | * | ||
636 | * Gets the I2C clock state | ||
637 | */ | ||
638 | static int igb_get_i2c_clk(void *data) | ||
639 | { | ||
640 | struct igb_adapter *adapter = (struct igb_adapter *)data; | ||
641 | struct e1000_hw *hw = &adapter->hw; | ||
642 | s32 i2cctl = rd32(E1000_I2CPARAMS); | ||
643 | |||
644 | return ((i2cctl & E1000_I2C_CLK_IN) != 0); | ||
645 | } | ||
646 | |||
647 | static const struct i2c_algo_bit_data igb_i2c_algo = { | ||
648 | .setsda = igb_set_i2c_data, | ||
649 | .setscl = igb_set_i2c_clk, | ||
650 | .getsda = igb_get_i2c_data, | ||
651 | .getscl = igb_get_i2c_clk, | ||
652 | .udelay = 5, | ||
653 | .timeout = 20, | ||
654 | }; | ||
655 | |||
570 | /** | 656 | /** |
571 | * igb_get_hw_dev - return device | 657 | * igb_get_hw_dev - return device |
572 | * used by hardware layer to print debugging information | 658 | * used by hardware layer to print debugging information |
@@ -1824,6 +1910,37 @@ void igb_set_fw_version(struct igb_adapter *adapter) | |||
1824 | return; | 1910 | return; |
1825 | } | 1911 | } |
1826 | 1912 | ||
1913 | static const struct i2c_board_info i350_sensor_info = { | ||
1914 | I2C_BOARD_INFO("i350bb", 0Xf8), | ||
1915 | }; | ||
1916 | |||
1917 | /* igb_init_i2c - Init I2C interface | ||
1918 | * @adapter: pointer to adapter structure | ||
1919 | * | ||
1920 | */ | ||
1921 | static s32 igb_init_i2c(struct igb_adapter *adapter) | ||
1922 | { | ||
1923 | s32 status = E1000_SUCCESS; | ||
1924 | |||
1925 | /* I2C interface supported on i350 devices */ | ||
1926 | if (adapter->hw.mac.type != e1000_i350) | ||
1927 | return E1000_SUCCESS; | ||
1928 | |||
1929 | /* Initialize the i2c bus which is controlled by the registers. | ||
1930 | * This bus will use the i2c_algo_bit structue that implements | ||
1931 | * the protocol through toggling of the 4 bits in the register. | ||
1932 | */ | ||
1933 | adapter->i2c_adap.owner = THIS_MODULE; | ||
1934 | adapter->i2c_algo = igb_i2c_algo; | ||
1935 | adapter->i2c_algo.data = adapter; | ||
1936 | adapter->i2c_adap.algo_data = &adapter->i2c_algo; | ||
1937 | adapter->i2c_adap.dev.parent = &adapter->pdev->dev; | ||
1938 | strlcpy(adapter->i2c_adap.name, "igb BB", | ||
1939 | sizeof(adapter->i2c_adap.name)); | ||
1940 | status = i2c_bit_add_bus(&adapter->i2c_adap); | ||
1941 | return status; | ||
1942 | } | ||
1943 | |||
1827 | /** | 1944 | /** |
1828 | * igb_probe - Device Initialization Routine | 1945 | * igb_probe - Device Initialization Routine |
1829 | * @pdev: PCI device information struct | 1946 | * @pdev: PCI device information struct |
@@ -2116,6 +2233,13 @@ static int igb_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
2116 | /* reset the hardware with the new settings */ | 2233 | /* reset the hardware with the new settings */ |
2117 | igb_reset(adapter); | 2234 | igb_reset(adapter); |
2118 | 2235 | ||
2236 | /* Init the I2C interface */ | ||
2237 | err = igb_init_i2c(adapter); | ||
2238 | if (err) { | ||
2239 | dev_err(&pdev->dev, "failed to init i2c interface\n"); | ||
2240 | goto err_eeprom; | ||
2241 | } | ||
2242 | |||
2119 | /* let the f/w know that the h/w is now under the control of the | 2243 | /* let the f/w know that the h/w is now under the control of the |
2120 | * driver. */ | 2244 | * driver. */ |
2121 | igb_get_hw_control(adapter); | 2245 | igb_get_hw_control(adapter); |
@@ -2177,6 +2301,7 @@ static int igb_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
2177 | 2301 | ||
2178 | err_register: | 2302 | err_register: |
2179 | igb_release_hw_control(adapter); | 2303 | igb_release_hw_control(adapter); |
2304 | memset(&adapter->i2c_adap, 0, sizeof(adapter->i2c_adap)); | ||
2180 | err_eeprom: | 2305 | err_eeprom: |
2181 | if (!igb_check_reset_block(hw)) | 2306 | if (!igb_check_reset_block(hw)) |
2182 | igb_reset_phy(hw); | 2307 | igb_reset_phy(hw); |
@@ -2290,6 +2415,18 @@ out: | |||
2290 | } | 2415 | } |
2291 | 2416 | ||
2292 | #endif | 2417 | #endif |
2418 | /* | ||
2419 | * igb_remove_i2c - Cleanup I2C interface | ||
2420 | * @adapter: pointer to adapter structure | ||
2421 | * | ||
2422 | */ | ||
2423 | static void igb_remove_i2c(struct igb_adapter *adapter) | ||
2424 | { | ||
2425 | |||
2426 | /* free the adapter bus structure */ | ||
2427 | i2c_del_adapter(&adapter->i2c_adap); | ||
2428 | } | ||
2429 | |||
2293 | /** | 2430 | /** |
2294 | * igb_remove - Device Removal Routine | 2431 | * igb_remove - Device Removal Routine |
2295 | * @pdev: PCI device information struct | 2432 | * @pdev: PCI device information struct |
@@ -2306,6 +2443,8 @@ static void igb_remove(struct pci_dev *pdev) | |||
2306 | struct e1000_hw *hw = &adapter->hw; | 2443 | struct e1000_hw *hw = &adapter->hw; |
2307 | 2444 | ||
2308 | pm_runtime_get_noresume(&pdev->dev); | 2445 | pm_runtime_get_noresume(&pdev->dev); |
2446 | igb_remove_i2c(adapter); | ||
2447 | |||
2309 | igb_ptp_stop(adapter); | 2448 | igb_ptp_stop(adapter); |
2310 | 2449 | ||
2311 | /* | 2450 | /* |
@@ -7425,4 +7564,134 @@ static void igb_init_dmac(struct igb_adapter *adapter, u32 pba) | |||
7425 | } | 7564 | } |
7426 | } | 7565 | } |
7427 | 7566 | ||
7567 | static DEFINE_SPINLOCK(i2c_clients_lock); | ||
7568 | |||
7569 | /* igb_get_i2c_client - returns matching client | ||
7570 | * in adapters's client list. | ||
7571 | * @adapter: adapter struct | ||
7572 | * @dev_addr: device address of i2c needed. | ||
7573 | */ | ||
7574 | struct i2c_client * | ||
7575 | igb_get_i2c_client(struct igb_adapter *adapter, u8 dev_addr) | ||
7576 | { | ||
7577 | ulong flags; | ||
7578 | struct igb_i2c_client_list *client_list; | ||
7579 | struct i2c_client *client = NULL; | ||
7580 | struct i2c_board_info client_info = { | ||
7581 | I2C_BOARD_INFO("igb", 0x00), | ||
7582 | }; | ||
7583 | |||
7584 | spin_lock_irqsave(&i2c_clients_lock, flags); | ||
7585 | client_list = adapter->i2c_clients; | ||
7586 | |||
7587 | /* See if we already have an i2c_client */ | ||
7588 | while (client_list) { | ||
7589 | if (client_list->client->addr == (dev_addr >> 1)) { | ||
7590 | client = client_list->client; | ||
7591 | goto exit; | ||
7592 | } else { | ||
7593 | client_list = client_list->next; | ||
7594 | } | ||
7595 | } | ||
7596 | |||
7597 | /* no client_list found, create a new one */ | ||
7598 | client_list = kzalloc(sizeof(*client_list), GFP_KERNEL); | ||
7599 | if (client_list == NULL) | ||
7600 | goto exit; | ||
7601 | |||
7602 | /* dev_addr passed to us is left-shifted by 1 bit | ||
7603 | * i2c_new_device call expects it to be flush to the right. | ||
7604 | */ | ||
7605 | client_info.addr = dev_addr >> 1; | ||
7606 | client_info.platform_data = adapter; | ||
7607 | client_list->client = i2c_new_device(&adapter->i2c_adap, &client_info); | ||
7608 | if (client_list->client == NULL) { | ||
7609 | dev_info(&adapter->pdev->dev, "Failed to create new i2c device..\n"); | ||
7610 | goto err_no_client; | ||
7611 | } | ||
7612 | |||
7613 | /* insert new client at head of list */ | ||
7614 | client_list->next = adapter->i2c_clients; | ||
7615 | adapter->i2c_clients = client_list; | ||
7616 | |||
7617 | spin_unlock_irqrestore(&i2c_clients_lock, flags); | ||
7618 | |||
7619 | client = client_list->client; | ||
7620 | goto exit; | ||
7621 | |||
7622 | err_no_client: | ||
7623 | kfree(client_list); | ||
7624 | exit: | ||
7625 | spin_unlock_irqrestore(&i2c_clients_lock, flags); | ||
7626 | return client; | ||
7627 | } | ||
7628 | |||
7629 | /* igb_read_i2c_byte - Reads 8 bit word over I2C | ||
7630 | * @hw: pointer to hardware structure | ||
7631 | * @byte_offset: byte offset to read | ||
7632 | * @dev_addr: device address | ||
7633 | * @data: value read | ||
7634 | * | ||
7635 | * Performs byte read operation over I2C interface at | ||
7636 | * a specified device address. | ||
7637 | */ | ||
7638 | s32 igb_read_i2c_byte(struct e1000_hw *hw, u8 byte_offset, | ||
7639 | u8 dev_addr, u8 *data) | ||
7640 | { | ||
7641 | struct igb_adapter *adapter = container_of(hw, struct igb_adapter, hw); | ||
7642 | struct i2c_client *this_client = igb_get_i2c_client(adapter, dev_addr); | ||
7643 | s32 status; | ||
7644 | u16 swfw_mask = 0; | ||
7645 | |||
7646 | if (!this_client) | ||
7647 | return E1000_ERR_I2C; | ||
7648 | |||
7649 | swfw_mask = E1000_SWFW_PHY0_SM; | ||
7650 | |||
7651 | if (hw->mac.ops.acquire_swfw_sync(hw, swfw_mask) | ||
7652 | != E1000_SUCCESS) | ||
7653 | return E1000_ERR_SWFW_SYNC; | ||
7654 | |||
7655 | status = i2c_smbus_read_byte_data(this_client, byte_offset); | ||
7656 | hw->mac.ops.release_swfw_sync(hw, swfw_mask); | ||
7657 | |||
7658 | if (status < 0) | ||
7659 | return E1000_ERR_I2C; | ||
7660 | else { | ||
7661 | *data = status; | ||
7662 | return E1000_SUCCESS; | ||
7663 | } | ||
7664 | } | ||
7665 | |||
7666 | /* igb_write_i2c_byte - Writes 8 bit word over I2C | ||
7667 | * @hw: pointer to hardware structure | ||
7668 | * @byte_offset: byte offset to write | ||
7669 | * @dev_addr: device address | ||
7670 | * @data: value to write | ||
7671 | * | ||
7672 | * Performs byte write operation over I2C interface at | ||
7673 | * a specified device address. | ||
7674 | */ | ||
7675 | s32 igb_write_i2c_byte(struct e1000_hw *hw, u8 byte_offset, | ||
7676 | u8 dev_addr, u8 data) | ||
7677 | { | ||
7678 | struct igb_adapter *adapter = container_of(hw, struct igb_adapter, hw); | ||
7679 | struct i2c_client *this_client = igb_get_i2c_client(adapter, dev_addr); | ||
7680 | s32 status; | ||
7681 | u16 swfw_mask = E1000_SWFW_PHY0_SM; | ||
7682 | |||
7683 | if (!this_client) | ||
7684 | return E1000_ERR_I2C; | ||
7685 | |||
7686 | if (hw->mac.ops.acquire_swfw_sync(hw, swfw_mask) != E1000_SUCCESS) | ||
7687 | return E1000_ERR_SWFW_SYNC; | ||
7688 | status = i2c_smbus_write_byte_data(this_client, byte_offset, data); | ||
7689 | hw->mac.ops.release_swfw_sync(hw, swfw_mask); | ||
7690 | |||
7691 | if (status) | ||
7692 | return E1000_ERR_I2C; | ||
7693 | else | ||
7694 | return E1000_SUCCESS; | ||
7695 | |||
7696 | } | ||
7428 | /* igb_main.c */ | 7697 | /* igb_main.c */ |