Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
W
White Rabbit Switch - Software
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
86
Issues
86
List
Board
Labels
Milestones
Merge Requests
4
Merge Requests
4
CI / CD
CI / CD
Pipelines
Schedules
Wiki
Wiki
image/svg+xml
Discourse
Discourse
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
Projects
White Rabbit Switch - Software
Commits
2aaa11f2
Commit
2aaa11f2
authored
Apr 24, 2024
by
Quentin Genoud
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
restore I2C as it was to compile libwr
parent
ef4f7357
Pipeline
#5320
failed with stage
in 9 seconds
Changes
4
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
251 additions
and
213 deletions
+251
-213
i2c.c
userspace/libwr/i2c.c
+44
-121
i2c.h
userspace/libwr/i2c.h
+24
-17
i2c_sfp.c
userspace/libwr/i2c_sfp.c
+174
-73
i2c_sfp.h
userspace/libwr/i2c_sfp.h
+9
-2
No files found.
userspace/libwr/i2c.c
View file @
2aaa11f2
/*
** 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 "i2c.h"
int
i2c_init_bus
(
struct
i2c_bus
*
bus
)
{
/* Open I2C controller (i2c-dev) file from /dev */
bus
->
fd
=
open
(
bus
->
dev_name
,
O_RDWR
);
if
(
bus
->
fd
<
0
)
return
bus
->
fd
;
else
return
0
;
}
#include "i2c_bitbang.h"
#include "i2c_fpga_reg.h"
#include <libwr/wrs-msg.h>
#include <libwr/util.h>
int
32_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
;
//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
;
/* 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
;
if
(
bus
->
type
==
I2C_TYPE_BITBANG
)
ret
=
i2c_bitbang_init_bus
(
bus
);
else
if
(
bus
->
type
==
I2C_BUS_TYPE_FPGA_REG
)
ret
=
i2c_fpga_reg_init_bus
(
bus
);
else
ret
=
-
1
;
/* All good, return number of bytes written */
bus
->
err
=
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
;
//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
;
return
bus
->
transfer
(
bus
,
address
,
to_write
,
to_read
,
data
);
}
/* Check that we read as much bytes as requested */
if
(
ret
<
count
)
return
-
1
;
int32_t
i2c_write
(
struct
i2c_bus
*
bus
,
uint32_t
address
,
uint32_t
to_write
,
uint8_t
*
data
)
{
//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 */
return
ret
;
int32_t
i2c_read
(
struct
i2c_bus
*
bus
,
uint32_t
address
,
uint32_t
to_read
,
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
)
{
const
uint8_t
first_valid_address
=
0
;
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
)
if
(
!
bus
)
return
I2C_NULL_PARAM
;
/* Check that the bus is initialized (device open) */
if
(
bus
->
fd
<=
0
)
return
I2C_NULL_PARAM
;
// const int devices = 128;
/* 16 bytes * 8 addresses per byte == 128 addresses */
memset
((
void
*
)
data
,
0
,
16
);
int
address
;
/* Check all I2C addresses to find any device on the bus */
for
(
address
=
first_valid_address
;
address
<=
last_valid_address
;
address
++
)
{
/* Set current slave address */
res
=
ioctl
(
bus
->
fd
,
I2C_SLAVE
,
address
);
const
int
first_valid_address
=
0
;
const
int
last_valid_address
=
0x7f
;
memset
((
void
*
)
data
,
0
,
16
);
//16 bytes * 8 addresses per byte == 128 addresses
/* We want to perform an operation on register @ 0x00 */
res
=
write
(
bus
->
fd
,
&
reg
,
1
);
int
found
=
0
;
/* Device detected */
if
(
res
>
0
)
for
(
address
=
first_valid_address
;
address
<=
last_valid_address
;
address
++
)
{
int
res
=
bus
->
scan
(
bus
,
address
);
if
(
res
)
//device present
{
offset
=
address
>>
3
;
//choose proper byte
bit
=
(
1
<<
(
address
%
8
));
//choose proper bit
int
offset
=
address
>>
3
;
//choose proper byte
int
bit
=
(
1
<<
(
address
%
8
));
//choose proper bit
data
[
offset
]
|=
bit
;
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
;
}
userspace/libwr/i2c.h
View file @
2aaa11f2
/*
i2c.h
Q. GENOUD CERN 2024
B.Bielawski CERN 2012
*/
#ifndef I2C_H
...
...
@@ -8,33 +8,40 @@
#include <stdint.h>
#define I2C_OK
0
#define I2C_DEV_NOT_FOUND
-1
#define I2C_NO_ACK_RCVD
-2
#define I2C_ALLOC_ERROR
-0x10
#define I2C_NULL_PARAM
-0x11
#define I2C_BUS_MISMATCH
-0x12
#define I2C_OK
0
#define I2C_DEV_NOT_FOUND -1
#define I2C_NO_ACK_RCVD -2
#define I2C_ALLOC_ERROR -0x10
#define I2C_NULL_PARAM -0x11
#define I2C_BUS_MISMATCH -0x12
#define I2C_TYPE_BITBANG
0
#define I2C_TYPE_BITBANG 0
#define I2C_BUS_TYPE_FPGA_REG 1
#define I2C_WRITE
0
#define I2C_READ
1
#define I2C_WRITE 0
#define I2C_READ 1
typedef
struct
i2c_bus
{
const
char
*
name
;
int
fd
;
int32_t
(
*
write
)
(
struct
i2c_bus
*
bus
,
uint32_t
address
,
uint32_t
count
,
uint8_t
*
data
);
int32_t
(
*
read
)
(
struct
i2c_bus
*
bus
,
uint32_t
address
,
uint32_t
count
,
uint8_t
*
data
);
int32_t
(
*
scan
)
(
struct
i2c_bus
*
bus
,
uint8_t
*
data
);
int
type
;
void
*
type_specific
;
int32_t
(
*
transfer
)
(
struct
i2c_bus
*
bus
,
uint32_t
address
,
uint32_t
to_write
,
uint32_t
to_read
,
uint8_t
*
data
);
int32_t
(
*
scan
)
(
struct
i2c_bus
*
bus
,
uint32_t
address
);
int
err
;
}
i2c_bus_t
;
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_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
);
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
userspace/libwr/i2c_sfp.c
View file @
2aaa11f2
...
...
@@ -49,67 +49,154 @@
#define SFP_LED_WRMODE_MASK(t) ((t) ? (1 << 5) : (1 << 3))
#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
[]
=
{
{
.
name
=
"/dev/i2c-0"
,
},
{
.
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
=
"fpga_bus0"
,
.
type
=
I2C_BUS_TYPE_FPGA_REG
,
.
type_specific
=
&
fpga_bus0_reg
,
},
{
.
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
=
"/dev/i2c-18"
,
},
{
.
name
=
"/dev/i2c-19"
,
.
name
=
"wr_sfp0_link1"
,
.
type
=
I2C_TYPE_BITBANG
,
.
type_specific
=
&
wr_link1_reg
,
},
};
...
...
@@ -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
)
{
if
(
num
<
0
||
num
>
WR_SFP_PORT_NB
-
1
)
if
(
num
>
17
||
num
<
0
)
return
-
1
;
return
num
;
}
...
...
@@ -319,14 +406,23 @@ int32_t shw_sfp_read(int num, uint32_t addr, int off, int len, uint8_t * buf)
if
(
id
<
0
)
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 */
if
(
off
>=
0
)
i2c_write
(
bus
,
addr
,
1
,
(
uint8_t
*
)
&
off
);
i2c_transfer
(
bus
,
addr
,
1
,
0
,
(
uint8_t
*
)
&
off
);
/* 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)
if
(
id
<
0
)
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 */
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)
{
pr_debug
(
"Writing %d bytes to EEPROM address %02x
\n
"
,
i
,
page
[
0
]);
ret
=
i2c_
write
(
bus
,
addr
,
i
+
1
,
page
);
ret
=
i2c_
transfer
(
bus
,
addr
,
i
+
1
,
0
,
page
);
if
(
ret
<
0
)
{
pr_error
(
"i2c_
write
error code 0x%x
\n
"
,
pr_error
(
"i2c_
transfer
error code 0x%x
\n
"
,
ret
);
return
-
1
;
}
...
...
@@ -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
"
,
i
,
page
[
0
]);
ret
=
i2c_
write
(
bus
,
addr
,
i
+
1
,
page
);
ret
=
i2c_
transfer
(
bus
,
addr
,
i
+
1
,
0
,
page
);
if
(
ret
<
0
)
{
pr_error
(
"i2c_transfer error code 0x%x
\n
"
,
ret
);
return
-
1
;
...
...
@@ -397,7 +503,7 @@ uint32_t shw_sfp_module_scan(void)
int
ret
;
uint32_t
mask
=
0
;
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
);
if
(
ret
==
I2C_DEV_NOT_FOUND
)
continue
;
...
...
@@ -408,8 +514,6 @@ uint32_t shw_sfp_module_scan(void)
void
shw_sfp_gpio_init
(
void
)
{
#if 0
int
i
;
uint8_t
addr
=
0x20
;
uint8_t
conf_output
[]
=
{
0x3
,
0x0
};
...
...
@@ -438,12 +542,11 @@ void shw_sfp_gpio_init(void)
shw_sfp_set_generic
(
i
,
0
,
SFP_LED_WRMODE1
|
SFP_LED_WRMODE2
);
shw_udelay
(
7000
);
}
#endif
}
void
shw_sfp_gpio_set
(
int
num
,
uint8_t
state
)
{
#if 0
int
id
;
int
top
;
struct
i2c_bus
*
bus
;
...
...
@@ -487,13 +590,12 @@ void shw_sfp_gpio_set(int num, uint8_t state)
send
[
1
]
=
curr
;
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);
}
uint8_t
shw_sfp_gpio_get
(
int
num
)
{
#if 0
int
id
;
int
top
;
struct
i2c_bus
*
bus
;
...
...
@@ -529,9 +631,6 @@ uint8_t shw_sfp_gpio_get(int num)
out
|=
SFP_TX_DISABLE
;
return
out
;
#endif
return
0
;
}
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
;
}
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
);
if
(
ret
==
I2C_DEV_NOT_FOUND
)
{
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)
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
);
if
(
ret
==
I2C_DEV_NOT_FOUND
)
{
pr_error
(
"shw_sfp_read_header: I2C_DEV_NOT_FOUND
\n
"
);
...
...
userspace/libwr/i2c_sfp.h
View file @
2aaa11f2
...
...
@@ -9,8 +9,15 @@
#define I2C_SFP_ADDRESS 0x50
// From SFF-8472, but right-shifted one bit as I2C addresses are only 7 bits.
#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
[];
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment