mirror of
https://github.com/corundum/corundum.git
synced 2025-01-30 08:32:52 +08:00
Register I2C muxes and clients for NetFPGA SUME, VCU108, VCU118, VCU1525, and ZCU106
This commit is contained in:
parent
a46cb33b69
commit
639cc1d02b
@ -110,6 +110,8 @@ struct mqnic_dev {
|
|||||||
struct i2c_adapter i2c_adapter[MQNIC_MAX_I2C_ADAPTERS];
|
struct i2c_adapter i2c_adapter[MQNIC_MAX_I2C_ADAPTERS];
|
||||||
struct mqnic_i2c_priv i2c_priv[MQNIC_MAX_I2C_ADAPTERS];
|
struct mqnic_i2c_priv i2c_priv[MQNIC_MAX_I2C_ADAPTERS];
|
||||||
|
|
||||||
|
int mod_i2c_client_count;
|
||||||
|
struct i2c_client *mod_i2c_client[MQNIC_MAX_IF];
|
||||||
struct i2c_client *eeprom_i2c_client;
|
struct i2c_client *eeprom_i2c_client;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -32,6 +32,8 @@ either expressed or implied, of The Regents of the University of California.
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "mqnic.h"
|
#include "mqnic.h"
|
||||||
|
#include <linux/module.h>
|
||||||
|
#include <linux/i2c-mux.h>
|
||||||
#include <linux/version.h>
|
#include <linux/version.h>
|
||||||
|
|
||||||
void mqnic_i2c_set_scl(void *data, int state)
|
void mqnic_i2c_set_scl(void *data, int state)
|
||||||
@ -85,6 +87,11 @@ static const struct i2c_algo_bit_data mqnic_i2c_algo = {
|
|||||||
.timeout = 20
|
.timeout = 20
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const struct property_entry i2c_mux_props[] = {
|
||||||
|
PROPERTY_ENTRY_BOOL("i2c-mux-idle-disconnect"),
|
||||||
|
{ }
|
||||||
|
};
|
||||||
|
|
||||||
static struct i2c_client *create_i2c_client(struct i2c_adapter *adapter, const char *type, int addr, const struct property_entry *props)
|
static struct i2c_client *create_i2c_client(struct i2c_adapter *adapter, const char *type, int addr, const struct property_entry *props)
|
||||||
{
|
{
|
||||||
struct i2c_client *client;
|
struct i2c_client *client;
|
||||||
@ -107,9 +114,27 @@ static struct i2c_client *create_i2c_client(struct i2c_adapter *adapter, const c
|
|||||||
if (!client)
|
if (!client)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
// force driver load (mainly for muxes so we can talk to downstream devices)
|
||||||
|
device_attach(&client->dev);
|
||||||
|
|
||||||
return client;
|
return client;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct i2c_adapter *get_i2c_mux_channel(struct i2c_client *mux, u32 chan_id)
|
||||||
|
{
|
||||||
|
struct i2c_mux_core *muxc;
|
||||||
|
|
||||||
|
if (!mux)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
muxc = i2c_get_clientdata(mux);
|
||||||
|
|
||||||
|
if (!muxc || chan_id >= muxc->num_adapters)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return muxc->adapter[chan_id];
|
||||||
|
}
|
||||||
|
|
||||||
static struct i2c_adapter *mqnic_create_i2c_adapter(struct mqnic_dev *mqnic, u8 __iomem *reg)
|
static struct i2c_adapter *mqnic_create_i2c_adapter(struct mqnic_dev *mqnic, u8 __iomem *reg)
|
||||||
{
|
{
|
||||||
struct i2c_algo_bit_data *algo;
|
struct i2c_algo_bit_data *algo;
|
||||||
@ -156,11 +181,220 @@ static struct i2c_adapter *mqnic_create_i2c_adapter(struct mqnic_dev *mqnic, u8
|
|||||||
int mqnic_init_i2c(struct mqnic_dev *mqnic)
|
int mqnic_init_i2c(struct mqnic_dev *mqnic)
|
||||||
{
|
{
|
||||||
struct i2c_adapter *adapter;
|
struct i2c_adapter *adapter;
|
||||||
|
struct i2c_client *mux;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
// interface i2c interfaces
|
|
||||||
// TODO
|
|
||||||
|
|
||||||
// eeprom i2c interface
|
mqnic->mod_i2c_client_count = 0;
|
||||||
|
|
||||||
|
// Interface I2C bus
|
||||||
|
switch (mqnic->board_id) {
|
||||||
|
case MQNIC_BOARD_ID_NETFPGA_SUME:
|
||||||
|
// FPGA IC12
|
||||||
|
// TCA9548 IC31 0x74
|
||||||
|
// CH0: SFP1 IC3 0x50
|
||||||
|
// CH1: SFP2 IC5 0x50
|
||||||
|
// CH2: SFP3 IC6 0x50
|
||||||
|
// CH3: SFP4 IC8 0x50
|
||||||
|
// CH4: DDR3 IC27 0x51
|
||||||
|
// DDR3 IC28 0x52
|
||||||
|
// SI5324 IC20 0x68
|
||||||
|
// CH5: FMC
|
||||||
|
// CH6: PCON
|
||||||
|
// CH7: PMOD J11
|
||||||
|
|
||||||
|
request_module("i2c_mux_pca954x");
|
||||||
|
request_module("at24");
|
||||||
|
|
||||||
|
// I2C adapter
|
||||||
|
adapter = mqnic_create_i2c_adapter(mqnic, mqnic->hw_addr+MQNIC_REG_GPIO_I2C_0);
|
||||||
|
|
||||||
|
// IC31 TCA9548 I2C MUX
|
||||||
|
mux = create_i2c_client(adapter, "pca9548", 0x74, i2c_mux_props);
|
||||||
|
|
||||||
|
// IC3 SFP1
|
||||||
|
mqnic->mod_i2c_client[0] = create_i2c_client(get_i2c_mux_channel(mux, 0), "24c02", 0x50, NULL);
|
||||||
|
|
||||||
|
// IC5 SFP2
|
||||||
|
mqnic->mod_i2c_client[1] = create_i2c_client(get_i2c_mux_channel(mux, 1), "24c02", 0x50, NULL);
|
||||||
|
|
||||||
|
// IC6 SFP3
|
||||||
|
mqnic->mod_i2c_client[2] = create_i2c_client(get_i2c_mux_channel(mux, 2), "24c02", 0x50, NULL);
|
||||||
|
|
||||||
|
// IC8 SFP4
|
||||||
|
mqnic->mod_i2c_client[3] = create_i2c_client(get_i2c_mux_channel(mux, 3), "24c02", 0x50, NULL);
|
||||||
|
|
||||||
|
mqnic->mod_i2c_client_count = 4;
|
||||||
|
|
||||||
|
break;
|
||||||
|
case MQNIC_BOARD_ID_VCU108:
|
||||||
|
// FPGA U1
|
||||||
|
// TCA9548 U28 0x74
|
||||||
|
// CH0: SI570 Osc U32 0x5D
|
||||||
|
// CH1: TCA6416 Port Exp U89 0x21
|
||||||
|
// CH2: QSFP U145 0x50
|
||||||
|
// CH3: NC
|
||||||
|
// CH4: SI5328 U57 0x68
|
||||||
|
// CH5: HDMI U52 0x39
|
||||||
|
// CH6: SYSMON U1 0x32
|
||||||
|
// CH7: NC
|
||||||
|
// PCA9544 U80 0x75
|
||||||
|
// CH0: PMBUS
|
||||||
|
// CH1: FMC_HPC0 J22
|
||||||
|
// CH2: FMC_HPC1 J2
|
||||||
|
// CH3: M24C08 EEPROM U12 0x54
|
||||||
|
|
||||||
|
request_module("i2c_mux_pca954x");
|
||||||
|
request_module("at24");
|
||||||
|
|
||||||
|
// I2C adapter
|
||||||
|
adapter = mqnic_create_i2c_adapter(mqnic, mqnic->hw_addr+MQNIC_REG_GPIO_I2C_0);
|
||||||
|
|
||||||
|
// U28 TCA9548 I2C MUX
|
||||||
|
mux = create_i2c_client(adapter, "pca9548", 0x74, i2c_mux_props);
|
||||||
|
|
||||||
|
// U145 QSFP
|
||||||
|
mqnic->mod_i2c_client[0] = create_i2c_client(get_i2c_mux_channel(mux, 2), "24c02", 0x50, NULL);
|
||||||
|
|
||||||
|
// U80 PCA9544 I2C MUX
|
||||||
|
mux = create_i2c_client(adapter, "pca9544", 0x75, i2c_mux_props);
|
||||||
|
|
||||||
|
// U12 I2C EEPROM
|
||||||
|
mqnic->eeprom_i2c_client = create_i2c_client(get_i2c_mux_channel(mux, 3), "24c08", 0x54, NULL);
|
||||||
|
|
||||||
|
mqnic->mod_i2c_client_count = 1;
|
||||||
|
|
||||||
|
break;
|
||||||
|
case MQNIC_BOARD_ID_VCU118:
|
||||||
|
// FPGA U1
|
||||||
|
// TCA9548 U28 0x74
|
||||||
|
// CH0: SI570 Osc U32 0x5D
|
||||||
|
// CH1: NC
|
||||||
|
// CH2: QSFP1 U145 0x50
|
||||||
|
// CH3: QSFP2 U123 0x50
|
||||||
|
// CH4: SI5328 U57 0x68
|
||||||
|
// CH5: SI570 Osc U18 0x5D
|
||||||
|
// CH6: SYSMON U1 0x32
|
||||||
|
// CH7: FIREFLY J6 0x50
|
||||||
|
// TCA9548 U80 0x75
|
||||||
|
// CH0: PMBUS
|
||||||
|
// CH1: FMCP_HSPC J22
|
||||||
|
// CH2: FMC_HPC1 J2
|
||||||
|
// CH3: M24C08 EEPROM U12 0x54
|
||||||
|
// CH4: INA_PMBUS
|
||||||
|
// CH5: SI570 Osc U38 0x5D
|
||||||
|
// CH6: NC
|
||||||
|
// CH7: NC
|
||||||
|
|
||||||
|
request_module("i2c_mux_pca954x");
|
||||||
|
request_module("at24");
|
||||||
|
|
||||||
|
// I2C adapter
|
||||||
|
adapter = mqnic_create_i2c_adapter(mqnic, mqnic->hw_addr+MQNIC_REG_GPIO_I2C_0);
|
||||||
|
|
||||||
|
// U28 TCA9548 I2C MUX
|
||||||
|
mux = create_i2c_client(adapter, "pca9548", 0x74, i2c_mux_props);
|
||||||
|
|
||||||
|
// U145 QSFP1
|
||||||
|
mqnic->mod_i2c_client[0] = create_i2c_client(get_i2c_mux_channel(mux, 2), "24c02", 0x50, NULL);
|
||||||
|
|
||||||
|
// U123 QSFP2
|
||||||
|
mqnic->mod_i2c_client[1] = create_i2c_client(get_i2c_mux_channel(mux, 3), "24c02", 0x50, NULL);
|
||||||
|
|
||||||
|
// U80 PCA9548 I2C MUX
|
||||||
|
mux = create_i2c_client(adapter, "pca9548", 0x75, i2c_mux_props);
|
||||||
|
|
||||||
|
// U12 I2C EEPROM
|
||||||
|
mqnic->eeprom_i2c_client = create_i2c_client(get_i2c_mux_channel(mux, 3), "24c08", 0x54, NULL);
|
||||||
|
|
||||||
|
mqnic->mod_i2c_client_count = 2;
|
||||||
|
|
||||||
|
break;
|
||||||
|
case MQNIC_BOARD_ID_VCU1525:
|
||||||
|
// FPGA U13
|
||||||
|
// PCA9546 U28 0x74
|
||||||
|
// CH0: QSFP0 J7 0x50
|
||||||
|
// CH1: QSFP1 J9 0x50
|
||||||
|
// CH2: M24C08 EEPROM U62 0x54
|
||||||
|
// SI570 Osc U14 0x5D
|
||||||
|
// CH3: SYSMON U13 0x32
|
||||||
|
|
||||||
|
request_module("i2c_mux_pca954x");
|
||||||
|
request_module("at24");
|
||||||
|
|
||||||
|
// I2C adapter
|
||||||
|
adapter = mqnic_create_i2c_adapter(mqnic, mqnic->hw_addr+MQNIC_REG_GPIO_I2C_0);
|
||||||
|
|
||||||
|
// U28 TCA9546 I2C MUX
|
||||||
|
mux = create_i2c_client(adapter, "pca9546", 0x74, i2c_mux_props);
|
||||||
|
|
||||||
|
// J7 QSFP0
|
||||||
|
mqnic->mod_i2c_client[0] = create_i2c_client(get_i2c_mux_channel(mux, 0), "24c02", 0x50, NULL);
|
||||||
|
|
||||||
|
// J9 QSFP1
|
||||||
|
mqnic->mod_i2c_client[1] = create_i2c_client(get_i2c_mux_channel(mux, 1), "24c02", 0x50, NULL);
|
||||||
|
|
||||||
|
// U12 I2C EEPROM
|
||||||
|
mqnic->eeprom_i2c_client = create_i2c_client(get_i2c_mux_channel(mux, 2), "24c08", 0x54, NULL);
|
||||||
|
|
||||||
|
mqnic->mod_i2c_client_count = 2;
|
||||||
|
|
||||||
|
break;
|
||||||
|
case MQNIC_BOARD_ID_ZCU106:
|
||||||
|
// FPGA U1 / MSP430 U41 I2C0
|
||||||
|
// TCA6416 U61 0x21
|
||||||
|
// TCA6416 U97 0x20
|
||||||
|
// PCA9544 U60 0x75
|
||||||
|
// CH0: PS_PMBUS
|
||||||
|
// CH1: PL_PMBUS
|
||||||
|
// CH2: MAXIM_PMBUS
|
||||||
|
// CH3: SYSMON U1 0x32
|
||||||
|
// FPGA U1 / MSP430 U41 I2C1
|
||||||
|
// TCA9548 U34 0x74
|
||||||
|
// CH0: M24C08 EEPROM U23 0x54
|
||||||
|
// CH1: SI5341 U69 0x36
|
||||||
|
// CH2: SI570 Osc U42 0x5D
|
||||||
|
// CH3: SI570 Osc U56 0x5D
|
||||||
|
// CH4: SI5328 U20 0x68
|
||||||
|
// CH5: NC
|
||||||
|
// CH6: NC
|
||||||
|
// CH7: NC
|
||||||
|
// TCA9548 U135 0x75
|
||||||
|
// CH0: FMC_HPC0 J5
|
||||||
|
// CH1: FMC_HPC1 J4
|
||||||
|
// CH2: SYSMON U1 0x32
|
||||||
|
// CH3: DDR4 SODIMM 0x51
|
||||||
|
// CH4: NC
|
||||||
|
// CH5: NC
|
||||||
|
// CH6: SFP1 P2 0x50
|
||||||
|
// CH7: SFP0 P1 0x50
|
||||||
|
|
||||||
|
request_module("i2c_mux_pca954x");
|
||||||
|
request_module("at24");
|
||||||
|
|
||||||
|
// I2C adapter
|
||||||
|
adapter = mqnic_create_i2c_adapter(mqnic, mqnic->hw_addr+MQNIC_REG_GPIO_I2C_0);
|
||||||
|
|
||||||
|
// U34 TCA9548 I2C MUX
|
||||||
|
mux = create_i2c_client(adapter, "pca9548", 0x74, i2c_mux_props);
|
||||||
|
|
||||||
|
// U23 I2C EEPROM
|
||||||
|
mqnic->eeprom_i2c_client = create_i2c_client(get_i2c_mux_channel(mux, 0), "24c08", 0x54, NULL);
|
||||||
|
|
||||||
|
// U135 TCA9548 I2C MUX
|
||||||
|
mux = create_i2c_client(adapter, "pca9548", 0x75, i2c_mux_props);
|
||||||
|
|
||||||
|
// P1 SFP0
|
||||||
|
mqnic->mod_i2c_client[0] = create_i2c_client(get_i2c_mux_channel(mux, 7), "24c02", 0x50, NULL);
|
||||||
|
|
||||||
|
// P2 SFP1
|
||||||
|
mqnic->mod_i2c_client[1] = create_i2c_client(get_i2c_mux_channel(mux, 6), "24c02", 0x50, NULL);
|
||||||
|
|
||||||
|
mqnic->mod_i2c_client_count = 2;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// EEPROM I2C bus
|
||||||
switch (mqnic->board_id) {
|
switch (mqnic->board_id) {
|
||||||
case MQNIC_BOARD_ID_EXANIC_X10:
|
case MQNIC_BOARD_ID_EXANIC_X10:
|
||||||
case MQNIC_BOARD_ID_EXANIC_X25:
|
case MQNIC_BOARD_ID_EXANIC_X25:
|
||||||
@ -182,7 +416,16 @@ void mqnic_remove_i2c(struct mqnic_dev *mqnic)
|
|||||||
{
|
{
|
||||||
int k;
|
int k;
|
||||||
|
|
||||||
// eeprom i2c interface
|
// unregister I2C clients
|
||||||
|
for (k = 0; k < ARRAY_SIZE(mqnic->mod_i2c_client); k++)
|
||||||
|
{
|
||||||
|
if (mqnic->mod_i2c_client[k])
|
||||||
|
{
|
||||||
|
i2c_unregister_device(mqnic->mod_i2c_client[k]);
|
||||||
|
mqnic->mod_i2c_client[k] = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (mqnic->eeprom_i2c_client)
|
if (mqnic->eeprom_i2c_client)
|
||||||
{
|
{
|
||||||
i2c_unregister_device(mqnic->eeprom_i2c_client);
|
i2c_unregister_device(mqnic->eeprom_i2c_client);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user