Commit 2aaa11f2 authored by Quentin Genoud's avatar Quentin Genoud

restore I2C as it was to compile libwr

parent ef4f7357
Pipeline #5320 failed with stage
in 9 seconds
/*
** This work is part of the White Rabbit project
*
* Copyright (C) 2024 CERN (www.cern.ch)
* Author: Quentin Genoud Duvillaret <quentin.genoud@cern.ch>
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <linux/i2c-dev.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h> #include <string.h>
#include "i2c.h" #include "i2c.h"
int i2c_init_bus(struct i2c_bus *bus) #include "i2c_bitbang.h"
{ #include "i2c_fpga_reg.h"
/* Open I2C controller (i2c-dev) file from /dev */
bus->fd = open(bus->dev_name, O_RDWR); #include <libwr/wrs-msg.h>
if(bus->fd < 0) #include <libwr/util.h>
return bus->fd;
else
return 0;
}
int32_t i2c_write(struct i2c_bus *bus, uint32_t address, uint32_t count, uint8_t *data) int i2c_init_bus(struct i2c_bus *bus)
{ {
int ret; int ret;
if (bus->type == I2C_TYPE_BITBANG)
//pr_info("%s (0x%X): 0x%X 2w:%d %d\n",bus->dev_name,bus,address,to_write,data[0]); ret = i2c_bitbang_init_bus(bus);
else if (bus->type == I2C_BUS_TYPE_FPGA_REG)
/* Check that the bus structure has been allocated */ ret = i2c_fpga_reg_init_bus(bus);
if(!bus) else
return I2C_NULL_PARAM; ret = -1;
/* Check that the bus is initialized (device open) */
if(bus->fd <= 0)
return I2C_NULL_PARAM;
/* Set the slave address */
ret = ioctl(bus->fd, I2C_SLAVE, address);
if(ret < 0)
return -1;
/* Write the data */
ret = write(bus->fd, data, count);
/* Check that we were able to write data */
if(ret < 0)
return ret;
/* Check that we wrote as much bytes as requested */
if(ret < count)
return -1;
/* All good, return number of bytes written */ bus->err = ret;
return ret; return ret;
} }
int32_t i2c_read(struct i2c_bus *bus, uint32_t address, uint32_t count, uint8_t *data) int32_t i2c_transfer(struct i2c_bus * bus, uint32_t address, uint32_t to_write,
uint32_t to_read, uint8_t * data)
{ {
int ret; return bus->transfer(bus, address, to_write, to_read, data);
}
//pr_info("%s (0x%X): 0x%X 2w:%d %d\n",bus->dev_name,bus,address,to_write,data[0]);
/* Check that the bus structure has been allocated */
if(!bus)
return I2C_NULL_PARAM;
/* Check that the bus is initialized (device open) */
if(bus->fd <= 0)
return I2C_NULL_PARAM;
/* Set the slave address */
ret = ioctl(bus->fd, I2C_SLAVE, address);
if(ret < 0)
return -1;
/* Read the data */
ret = read(bus->fd, data, count);
/* Check that we were able to read data */
if(ret < 0)
return ret;
/* Check that we read as much bytes as requested */ int32_t i2c_write(struct i2c_bus *bus, uint32_t address, uint32_t to_write,
if(ret < count) uint8_t * data)
return -1; {
//pr_info("%s (0x%X): 0x%X 2w:%d 2r:%d %d\n",bus->name,bus,address,to_write,0,data[0]);
return bus->transfer(bus, address, to_write, 0, data);
}
/* All good, return number of bytes read */ int32_t i2c_read(struct i2c_bus * bus, uint32_t address, uint32_t to_read,
return ret; uint8_t * data)
{
return bus->transfer(bus, address, 0, to_read, data);
//pr_info("%s (0x%X): 0x%X 2w:%d 2r:%d %d\n",bus->name,bus,address,0,to_read,data[0]);
} }
int32_t i2c_scan(struct i2c_bus * bus, uint8_t * data) int32_t i2c_scan(struct i2c_bus * bus, uint8_t * data)
{ {
const uint8_t first_valid_address = 0; if (!bus)
const uint8_t last_valid_address = 0x7f;
uint8_t address;
int32_t found = 0;
int res;
uint8_t reg = 0;
uint32_t offset;
uint32_t bit;
/* Check that the bus structure has been allocated */
if(!bus)
return I2C_NULL_PARAM; return I2C_NULL_PARAM;
/* Check that the bus is initialized (device open) */ // const int devices = 128;
if(bus->fd <= 0)
return I2C_NULL_PARAM;
/* 16 bytes * 8 addresses per byte == 128 addresses */ int address;
memset((void *)data, 0, 16);
/* Check all I2C addresses to find any device on the bus */ const int first_valid_address = 0;
for (address = first_valid_address; address <= last_valid_address; const int last_valid_address = 0x7f;
address++) {
memset((void *)data, 0, 16); //16 bytes * 8 addresses per byte == 128 addresses
/* Set current slave address */
res = ioctl(bus->fd, I2C_SLAVE, address);
/* We want to perform an operation on register @ 0x00 */ int found = 0;
res = write(bus->fd, &reg, 1);
/* Device detected */ for (address = first_valid_address; address <= last_valid_address;
if(res > 0) address++) {
int res = bus->scan(bus, address);
if (res) //device present
{ {
offset = address >> 3; //choose proper byte int offset = address >> 3; //choose proper byte
bit = (1 << (address % 8)); //choose proper bit int bit = (1 << (address % 8)); //choose proper bit
data[offset] |= bit; data[offset] |= bit;
found++; found++;
} }
} }
//pr_debug("%s (%p): ndev=%d\n", bus->name, bus, found); pr_debug("%s (%p): ndev=%d\n", bus->name, bus, found);
return found; return found;
} }
/* /*
i2c.h i2c.h
Q. GENOUD CERN 2024 B.Bielawski CERN 2012
*/ */
#ifndef I2C_H #ifndef I2C_H
...@@ -8,33 +8,40 @@ ...@@ -8,33 +8,40 @@
#include <stdint.h> #include <stdint.h>
#define I2C_OK 0 #define I2C_OK 0
#define I2C_DEV_NOT_FOUND -1 #define I2C_DEV_NOT_FOUND -1
#define I2C_NO_ACK_RCVD -2 #define I2C_NO_ACK_RCVD -2
#define I2C_ALLOC_ERROR -0x10 #define I2C_ALLOC_ERROR -0x10
#define I2C_NULL_PARAM -0x11 #define I2C_NULL_PARAM -0x11
#define I2C_BUS_MISMATCH -0x12 #define I2C_BUS_MISMATCH -0x12
#define I2C_TYPE_BITBANG 0 #define I2C_TYPE_BITBANG 0
#define I2C_BUS_TYPE_FPGA_REG 1 #define I2C_BUS_TYPE_FPGA_REG 1
#define I2C_WRITE 0 #define I2C_WRITE 0
#define I2C_READ 1 #define I2C_READ 1
typedef struct i2c_bus { typedef struct i2c_bus {
const char *name; const char *name;
int fd; int type;
int32_t(*write) (struct i2c_bus *bus, uint32_t address, uint32_t count, uint8_t *data); void *type_specific;
int32_t(*read) (struct i2c_bus *bus, uint32_t address, uint32_t count, uint8_t *data); int32_t(*transfer) (struct i2c_bus * bus, uint32_t address,
int32_t(*scan) (struct i2c_bus *bus, uint8_t *data); uint32_t to_write, uint32_t to_read,
uint8_t * data);
int32_t(*scan) (struct i2c_bus * bus, uint32_t address);
int err; int err;
} i2c_bus_t; } i2c_bus_t;
int i2c_init_bus(struct i2c_bus *bus); int i2c_init_bus(struct i2c_bus *bus);
int32_t i2c_write(struct i2c_bus *bus, uint32_t address, uint32_t count, uint8_t *data); int32_t i2c_transfer(struct i2c_bus *bus, uint32_t address, uint32_t to_write,
int32_t i2c_read(struct i2c_bus *bus, uint32_t address, uint32_t count, uint8_t *data); uint32_t to_read, uint8_t * data);
int32_t i2c_scan(struct i2c_bus *bus, uint8_t *data); int32_t i2c_write(struct i2c_bus *bus, uint32_t address, uint32_t to_write,
uint8_t * data);
int32_t i2c_read(struct i2c_bus *bus, uint32_t address, uint32_t to_read,
uint8_t * data);
int32_t i2c_scan(struct i2c_bus *bus, uint8_t * data);
#endif //I2C_H #endif //I2C_H
...@@ -49,67 +49,154 @@ ...@@ -49,67 +49,154 @@
#define SFP_LED_WRMODE_MASK(t) ((t) ? (1 << 5) : (1 << 3)) #define SFP_LED_WRMODE_MASK(t) ((t) ? (1 << 5) : (1 << 3))
#define SFP_TX_DISABLE_MASK(t) ((t) ? (1 << 7) : (1 << 2)) #define SFP_TX_DISABLE_MASK(t) ((t) ? (1 << 7) : (1 << 2))
/* 20 I2C busses: one for each SFP port */ /* Either 8 or 16 byte pages, so we use the smaller */
#define SFP_PAGE_SIZE 8
/*
* We need these tables because the schematics are messed up
* The first one is for figuring out the masks in the pca9548's
* The second table is for the connections of the pca9554's
*/
uint32_t bus_masks[] = {
[WR_SFP2_BUS] = 8,
[WR_SFP3_BUS] = 9,
[WR_SFP4_BUS] = 10,
[WR_SFP5_BUS] = 11,
[WR_SFP6_BUS] = 12,
[WR_SFP7_BUS] = 13,
[WR_SFP8_BUS] = 14,
[WR_SFP9_BUS] = 15,
[WR_SFP10_BUS] = 0,
[WR_SFP11_BUS] = 1,
[WR_SFP12_BUS] = 2,
[WR_SFP13_BUS] = 3,
[WR_SFP14_BUS] = 4,
[WR_SFP15_BUS] = 5,
[WR_SFP16_BUS] = 6,
[WR_SFP17_BUS] = 7,
};
uint32_t pca9554_masks[] = {
[WR_SFP2_BUS] = 14,
[WR_SFP3_BUS] = 15,
[WR_SFP4_BUS] = 12,
[WR_SFP5_BUS] = 13,
[WR_SFP6_BUS] = 10,
[WR_SFP7_BUS] = 11,
[WR_SFP8_BUS] = 8,
[WR_SFP9_BUS] = 9,
[WR_SFP10_BUS] = 6,
[WR_SFP11_BUS] = 7,
[WR_SFP12_BUS] = 4,
[WR_SFP13_BUS] = 5,
[WR_SFP14_BUS] = 2,
[WR_SFP15_BUS] = 3,
[WR_SFP16_BUS] = 0,
[WR_SFP17_BUS] = 1,
};
/* The two FPGA i2c masters */
i2c_fpga_reg_t fpga_bus0_reg = {
.base_address = FPGA_I2C_ADDRESS,
.if_num = FPGA_I2C0_IFNUM,
.prescaler = 500,
};
i2c_fpga_reg_t fpga_bus1_reg = {
.base_address = FPGA_I2C_ADDRESS,
.if_num = FPGA_I2C1_IFNUM,
.prescaler = 500,
};
/* I2C pins are set to input to avoid wrong transfers (which can lead to
* e.g. overwrite of SFP's eeprom) on i2c buses if HAL was killed in
* the middle of a transfer (by e.g. system reset). */
/* The Bit-Banged I2C bus connected to the PCA9548A Multiplexers. WORKS */
pio_pin_t wr_mux_scl = {
.port = PIOB,
.pin = 25,
.mode = PIO_MODE_GPIO,
.dir = PIO_IN, /* Set as input to avoid toggle after reset */
};
pio_pin_t wr_mux_sda = {
.port = PIOB,
.pin = 27,
.mode = PIO_MODE_GPIO,
.dir = PIO_IN, /* Set as input to avoid toggle after reset */
};
struct i2c_bitbang wr_mux_bus_reg = {
.scl = &wr_mux_scl,
.sda = &wr_mux_sda,
};
/* The Bit-Banged I2C bus connected to the SFP 0 (Link 0). WORKS */
pio_pin_t wr_link0_sda = {
.port = PIOB,
.pin = 23,
.mode = PIO_MODE_GPIO,
.dir = PIO_IN, /* Set as input to avoid toggle after reset */
};
pio_pin_t wr_link0_scl = {
.port = PIOB,
.pin = 26,
.mode = PIO_MODE_GPIO,
.dir = PIO_IN, /* Set as input to avoid toggle after reset */
};
struct i2c_bitbang wr_link0_reg = {
.scl = &wr_link0_scl,
.sda = &wr_link0_sda,
};
/* The Bit-Banged I2C bus connected to the SFP 1 (Link 1). WORKS */
pio_pin_t wr_link1_sda = {
.port = PIOB,
.pin = 22,
.mode = PIO_MODE_GPIO,
.dir = PIO_IN, /* Set as input to avoid toggle after reset */
};
pio_pin_t wr_link1_scl = {
.port = PIOB,
.pin = 21,
.mode = PIO_MODE_GPIO,
.dir = PIO_IN, /* Set as input to avoid toggle after reset */
};
struct i2c_bitbang wr_link1_reg = {
.scl = &wr_link1_scl,
.sda = &wr_link1_sda,
};
struct i2c_bus i2c_buses[] = { struct i2c_bus i2c_buses[] = {
{ {
.name = "/dev/i2c-0", .name = "fpga_bus0",
}, .type = I2C_BUS_TYPE_FPGA_REG,
{ .type_specific = &fpga_bus0_reg,
.name = "/dev/i2c-1",
},
{
.name = "/dev/i2c-2",
},
{
.name = "/dev/i2c-3",
},
{
.name = "/dev/i2c-4",
},
{
.name = "/dev/i2c-5",
},
{
.name = "/dev/i2c-6",
},
{
.name = "/dev/i2c-7",
},
{
.name = "/dev/i2c-8",
},
{
.name = "/dev/i2c-9",
},
{
.name = "/dev/i2c-10",
},
{
.name = "/dev/i2c-11",
},
{
.name = "/dev/i2c-12",
},
{
.name = "/dev/i2c-13",
}, },
{ {
.name = "/dev/i2c-14", .name = "fpga_bus1",
.type = I2C_BUS_TYPE_FPGA_REG,
.type_specific = &fpga_bus1_reg,
}, },
{ {
.name = "/dev/i2c-15", .name = "wr_mux_bus",
.type = I2C_TYPE_BITBANG,
.type_specific = &wr_mux_bus_reg,
}, },
{ {
.name = "/dev/i2c-16", .name = "wr_sfp0_link0",
.type = I2C_TYPE_BITBANG,
.type_specific = &wr_link0_reg,
}, },
{ {
.name = "/dev/i2c-17", .name = "wr_sfp0_link1",
}, .type = I2C_TYPE_BITBANG,
{ .type_specific = &wr_link1_reg,
.name = "/dev/i2c-18",
},
{
.name = "/dev/i2c-19",
}, },
}; };
...@@ -301,10 +388,10 @@ void shw_sfp_dom_dump(struct shw_sfp_dom *dom) ...@@ -301,10 +388,10 @@ void shw_sfp_dom_dump(struct shw_sfp_dom *dom)
} }
/* Get the SFP ID from the SFP number */ /* Get the SFP ID from the SFP number (0 to 17) */
inline int shw_sfp_id(int num) inline int shw_sfp_id(int num)
{ {
if (num < 0 || num > WR_SFP_PORT_NB-1) if (num > 17 || num < 0)
return -1; return -1;
return num; return num;
} }
...@@ -319,14 +406,23 @@ int32_t shw_sfp_read(int num, uint32_t addr, int off, int len, uint8_t * buf) ...@@ -319,14 +406,23 @@ int32_t shw_sfp_read(int num, uint32_t addr, int off, int len, uint8_t * buf)
if (id < 0) if (id < 0)
return -1; return -1;
bus = &i2c_buses[id]; bus = &i2c_buses[WR_MUX_BUS];
if (id == 0 || id == 1)
bus = &i2c_buses[WR_SFP0_BUS + id];
if (id > 1) {
/* Set the mask in the PCA9548 */
byte1 = (1 << bus_masks[id]) & 0xff;
byte2 = ((1 << bus_masks[id]) >> 8) & 0xff;
i2c_transfer(bus, 0x70, 1, 0, &byte1);
i2c_transfer(bus, 0x71, 1, 0, &byte2);
}
/* Send the offset we want to read from */ /* Send the offset we want to read from */
if (off >= 0) if (off >= 0)
i2c_write(bus, addr, 1, (uint8_t*)&off); i2c_transfer(bus, addr, 1, 0, (uint8_t *) & off);
/* Do the read */ /* Do the read */
return i2c_read(bus, addr, len, buf); return i2c_transfer(bus, addr, 0, len, buf);
} }
...@@ -349,7 +445,17 @@ int32_t shw_sfp_write(int num, uint32_t addr, int off, int len, uint8_t * buf) ...@@ -349,7 +445,17 @@ int32_t shw_sfp_write(int num, uint32_t addr, int off, int len, uint8_t * buf)
if (id < 0) if (id < 0)
return -1; return -1;
bus = &i2c_buses[id]; bus = &i2c_buses[WR_MUX_BUS];
if (id == 0 || id == 1)
bus = &i2c_buses[WR_SFP0_BUS + id];
if (id != 0 && id != 1) {
/* Set the mask in the PCA9548 */
byte1 = (1 << bus_masks[id]) & 0xff;
byte2 = ((1 << bus_masks[id]) >> 8) & 0xff;
i2c_transfer(bus, 0x70, 1, 0, &byte1);
i2c_transfer(bus, 0x71, 1, 0, &byte2);
}
/* Write in a paged mode, 1 byte address */ /* Write in a paged mode, 1 byte address */
page[0] = (counter + off) & 0xff; page[0] = (counter + off) & 0xff;
...@@ -362,9 +468,9 @@ int32_t shw_sfp_write(int num, uint32_t addr, int off, int len, uint8_t * buf) ...@@ -362,9 +468,9 @@ int32_t shw_sfp_write(int num, uint32_t addr, int off, int len, uint8_t * buf)
{ {
pr_debug("Writing %d bytes to EEPROM address %02x\n", pr_debug("Writing %d bytes to EEPROM address %02x\n",
i, page[0]); i, page[0]);
ret = i2c_write(bus, addr, i + 1, page); ret = i2c_transfer(bus, addr, i + 1, 0, page);
if (ret < 0) { if (ret < 0) {
pr_error("i2c_write error code 0x%x\n", pr_error("i2c_transfer error code 0x%x\n",
ret); ret);
return -1; return -1;
} }
...@@ -381,7 +487,7 @@ int32_t shw_sfp_write(int num, uint32_t addr, int off, int len, uint8_t * buf) ...@@ -381,7 +487,7 @@ int32_t shw_sfp_write(int num, uint32_t addr, int off, int len, uint8_t * buf)
{ {
pr_debug("Writing last %d bytes to EEPROM address %02x\n", pr_debug("Writing last %d bytes to EEPROM address %02x\n",
i, page[0]); i, page[0]);
ret = i2c_write(bus, addr, i + 1, page); ret = i2c_transfer(bus, addr, i + 1, 0, page);
if (ret < 0) { if (ret < 0) {
pr_error("i2c_transfer error code 0x%x\n", ret); pr_error("i2c_transfer error code 0x%x\n", ret);
return -1; return -1;
...@@ -397,7 +503,7 @@ uint32_t shw_sfp_module_scan(void) ...@@ -397,7 +503,7 @@ uint32_t shw_sfp_module_scan(void)
int ret; int ret;
uint32_t mask = 0; uint32_t mask = 0;
uint8_t test; uint8_t test;
for (i = 0; i < WR_SFP_PORT_NB; i++) { for (i = 0; i < 18; i++) {
ret = shw_sfp_read(i, 0x50, 0x0, sizeof(test), &test); ret = shw_sfp_read(i, 0x50, 0x0, sizeof(test), &test);
if (ret == I2C_DEV_NOT_FOUND) if (ret == I2C_DEV_NOT_FOUND)
continue; continue;
...@@ -408,8 +514,6 @@ uint32_t shw_sfp_module_scan(void) ...@@ -408,8 +514,6 @@ uint32_t shw_sfp_module_scan(void)
void shw_sfp_gpio_init(void) void shw_sfp_gpio_init(void)
{ {
#if 0
int i; int i;
uint8_t addr = 0x20; uint8_t addr = 0x20;
uint8_t conf_output[] = { 0x3, 0x0 }; uint8_t conf_output[] = { 0x3, 0x0 };
...@@ -438,12 +542,11 @@ void shw_sfp_gpio_init(void) ...@@ -438,12 +542,11 @@ void shw_sfp_gpio_init(void)
shw_sfp_set_generic(i, 0, SFP_LED_WRMODE1 | SFP_LED_WRMODE2); shw_sfp_set_generic(i, 0, SFP_LED_WRMODE1 | SFP_LED_WRMODE2);
shw_udelay(7000); shw_udelay(7000);
} }
#endif
} }
void shw_sfp_gpio_set(int num, uint8_t state) void shw_sfp_gpio_set(int num, uint8_t state)
{ {
#if 0
int id; int id;
int top; int top;
struct i2c_bus *bus; struct i2c_bus *bus;
...@@ -487,13 +590,12 @@ void shw_sfp_gpio_set(int num, uint8_t state) ...@@ -487,13 +590,12 @@ void shw_sfp_gpio_set(int num, uint8_t state)
send[1] = curr; send[1] = curr;
i2c_transfer(bus, addr, 2, 0, send); i2c_transfer(bus, addr, 2, 0, send);
#endif
//pr_info("%d: 0x%x 0x%x s=%d, send=%d,%d c=%d, \n",num,bus,addr,state,send[0],send[1],curr); //pr_info("%d: 0x%x 0x%x s=%d, send=%d,%d c=%d, \n",num,bus,addr,state,send[0],send[1],curr);
} }
uint8_t shw_sfp_gpio_get(int num) uint8_t shw_sfp_gpio_get(int num)
{ {
#if 0
int id; int id;
int top; int top;
struct i2c_bus *bus; struct i2c_bus *bus;
...@@ -529,9 +631,6 @@ uint8_t shw_sfp_gpio_get(int num) ...@@ -529,9 +631,6 @@ uint8_t shw_sfp_gpio_get(int num)
out |= SFP_TX_DISABLE; out |= SFP_TX_DISABLE;
return out; return out;
#endif
return 0;
} }
int shw_sfp_read_header(int num, struct shw_sfp_header *head) int shw_sfp_read_header(int num, struct shw_sfp_header *head)
...@@ -549,7 +648,8 @@ int shw_sfp_read_header(int num, struct shw_sfp_header *head) ...@@ -549,7 +648,8 @@ int shw_sfp_read_header(int num, struct shw_sfp_header *head)
return -2; return -2;
} }
ret = shw_sfp_read(num, I2C_SFP_ADDRESS, 0x0, ret =
shw_sfp_read(num, I2C_SFP_ADDRESS, 0x0,
sizeof(struct shw_sfp_header), (uint8_t *) head); sizeof(struct shw_sfp_header), (uint8_t *) head);
if (ret == I2C_DEV_NOT_FOUND) { if (ret == I2C_DEV_NOT_FOUND) {
pr_error("shw_sfp_read_header: I2C_DEV_NOT_FOUND\n"); pr_error("shw_sfp_read_header: I2C_DEV_NOT_FOUND\n");
...@@ -574,7 +674,8 @@ int shw_sfp_read_dom(int num, struct shw_sfp_dom *dom) ...@@ -574,7 +674,8 @@ int shw_sfp_read_dom(int num, struct shw_sfp_dom *dom)
return -2; return -2;
} }
ret = shw_sfp_read(num, I2C_SFP_DOM_ADDRESS, 0x0, ret =
shw_sfp_read(num, I2C_SFP_DOM_ADDRESS, 0x0,
sizeof(struct shw_sfp_dom), (uint8_t *) dom); sizeof(struct shw_sfp_dom), (uint8_t *) dom);
if (ret == I2C_DEV_NOT_FOUND) { if (ret == I2C_DEV_NOT_FOUND) {
pr_error("shw_sfp_read_header: I2C_DEV_NOT_FOUND\n"); pr_error("shw_sfp_read_header: I2C_DEV_NOT_FOUND\n");
......
...@@ -9,8 +9,15 @@ ...@@ -9,8 +9,15 @@
#define I2C_SFP_ADDRESS 0x50 #define I2C_SFP_ADDRESS 0x50
// From SFF-8472, but right-shifted one bit as I2C addresses are only 7 bits. // From SFF-8472, but right-shifted one bit as I2C addresses are only 7 bits.
#define I2C_SFP_DOM_ADDRESS 0x51 #define I2C_SFP_DOM_ADDRESS 0x51
// Number of SFP ports (20 on WRS v4)
#define WR_SFP_PORT_NB 18 /* The two FPGA buses */
#define WR_FPGA_BUS0 0
#define WR_FPGA_BUS1 1
/* The multiplexer bus */
#define WR_MUX_BUS 2
/* Individual buses. 0 and 1 are weird */
#define WR_SFP0_BUS 3
#define WR_SFP1_BUS 4
extern struct i2c_bus i2c_buses[]; extern struct i2c_bus i2c_buses[];
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment