parent
76cc29b19d
commit
72f9f51287
@ -1520,7 +1520,7 @@ class Sfp(SfpBase):
|
|||||||
if dom_control_raw is not None:
|
if dom_control_raw is not None:
|
||||||
dom_control_data = sfpd_obj.parse_control_bytes(
|
dom_control_data = sfpd_obj.parse_control_bytes(
|
||||||
dom_control_raw, 0)
|
dom_control_raw, 0)
|
||||||
return ('On' == dom_control_data['data']['PowerOverride'])
|
return ('On' == dom_control_data['data']['PowerOverride']['value'])
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
else:
|
else:
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* dx010_cpld.c - driver for SeaStone's CPLD
|
* dx010_cpld.c - driver for SeaStone's CPLD
|
||||||
*
|
*
|
||||||
* Copyright (C) 2017 Celestica Corp.
|
* Copyright (C) 2023 Celestica Corp.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@ -120,11 +120,11 @@
|
|||||||
#define SSRR_ID_BANK2 0x296
|
#define SSRR_ID_BANK2 0x296
|
||||||
#define SSRR_ID_BANK3 0x396
|
#define SSRR_ID_BANK3 0x396
|
||||||
|
|
||||||
#define HST_CNTL2_QUICK 0x00
|
#define SSRR_MASTER_ERR 0x80
|
||||||
#define HST_CNTL2_BYTE 0x01
|
#define SSRR_BUS_BUSY 0x40
|
||||||
#define HST_CNTL2_BYTE_DATA 0x02
|
|
||||||
#define HST_CNTL2_WORD_DATA 0x03
|
#define I2C_BAUD_RATE_100K 0x40
|
||||||
#define HST_CNTL2_BLOCK 0x05
|
|
||||||
|
|
||||||
struct dx010_i2c_data {
|
struct dx010_i2c_data {
|
||||||
int portid;
|
int portid;
|
||||||
@ -610,6 +610,166 @@ exit:
|
|||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read/Write eeprom of CPLD connected QSFP device.
|
||||||
|
* @param a i2c adapter.
|
||||||
|
* @param addr address to read.
|
||||||
|
* @param new_data QSFP port number struct.
|
||||||
|
* @param rw read/write flag
|
||||||
|
* @param cmd i2c command.
|
||||||
|
* @param size access size
|
||||||
|
* @return 0 if not error, else the error code.
|
||||||
|
*/
|
||||||
|
static int dx010_cpld_i2c_access(struct i2c_adapter *a, u16 addr,
|
||||||
|
struct dx010_i2c_data *new_data, char rw,
|
||||||
|
u8 cmd, int size, union i2c_smbus_data *data)
|
||||||
|
{
|
||||||
|
u32 reg;
|
||||||
|
int ioBase=0;
|
||||||
|
char byte;
|
||||||
|
char data_len = 0;
|
||||||
|
short temp;
|
||||||
|
short portid, opcode, devaddr, cmdbyte0, ssrr, writedata, readdata;
|
||||||
|
__u16 word_data;
|
||||||
|
__u8 byte_data;
|
||||||
|
int error = -EIO;
|
||||||
|
|
||||||
|
mutex_lock(&cpld_data->cpld_lock);
|
||||||
|
|
||||||
|
if (((new_data->portid >= PORT_BANK1_START)
|
||||||
|
&& (new_data->portid <= PORT_BANK1_END))
|
||||||
|
|| (new_data->portid == PORT_SFPP1)
|
||||||
|
|| (new_data->portid == PORT_SFPP2))
|
||||||
|
{
|
||||||
|
portid = PORT_ID_BANK1;
|
||||||
|
opcode = OPCODE_ID_BANK1;
|
||||||
|
devaddr = DEVADDR_ID_BANK1;
|
||||||
|
cmdbyte0 = CMDBYT_ID_BANK1;
|
||||||
|
ssrr = SSRR_ID_BANK1;
|
||||||
|
writedata = WRITE_ID_BANK1;
|
||||||
|
readdata = READ_ID_BANK1;
|
||||||
|
}else if ((new_data->portid >= PORT_BANK2_START) && (new_data->portid <= PORT_BANK2_END)){
|
||||||
|
portid = PORT_ID_BANK2;
|
||||||
|
opcode = OPCODE_ID_BANK2;
|
||||||
|
devaddr = DEVADDR_ID_BANK2;
|
||||||
|
cmdbyte0 = CMDBYT_ID_BANK2;
|
||||||
|
ssrr = SSRR_ID_BANK2;
|
||||||
|
writedata = WRITE_ID_BANK2;
|
||||||
|
readdata = READ_ID_BANK2;
|
||||||
|
}else if ((new_data->portid >= PORT_BANK3_START) && (new_data->portid <= PORT_BANK3_END)){
|
||||||
|
portid = PORT_ID_BANK3;
|
||||||
|
opcode = OPCODE_ID_BANK3;
|
||||||
|
devaddr = DEVADDR_ID_BANK3;
|
||||||
|
cmdbyte0 = CMDBYT_ID_BANK3;
|
||||||
|
ssrr = SSRR_ID_BANK3;
|
||||||
|
writedata = WRITE_ID_BANK3;
|
||||||
|
readdata = READ_ID_BANK3;
|
||||||
|
}else{
|
||||||
|
/* Invalid parameter! */
|
||||||
|
error = -EINVAL;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (size == I2C_SMBUS_BYTE || size == I2C_SMBUS_BYTE_DATA)
|
||||||
|
data_len = 1;
|
||||||
|
else if (size == I2C_SMBUS_WORD_DATA)
|
||||||
|
data_len = 2;
|
||||||
|
else {
|
||||||
|
error = -EINVAL;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
while ((inb(ioBase + ssrr) & SSRR_BUS_BUSY));
|
||||||
|
if ((inb(ioBase + ssrr) & SSRR_MASTER_ERR) == SSRR_MASTER_ERR) {
|
||||||
|
error = -EIO;
|
||||||
|
/* Read error reset the port */
|
||||||
|
outb(0x00, ioBase + ssrr);
|
||||||
|
udelay(3000);
|
||||||
|
outb(0x01, ioBase + ssrr);
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
byte = I2C_BAUD_RATE_100K + new_data->portid;
|
||||||
|
reg = cmd;
|
||||||
|
outb(byte, ioBase + portid);
|
||||||
|
outb(reg, ioBase + cmdbyte0);
|
||||||
|
byte = (data_len << 4) | 0x1;
|
||||||
|
outb(byte, ioBase + opcode);
|
||||||
|
addr = addr << 1;
|
||||||
|
if (rw == I2C_SMBUS_READ)
|
||||||
|
{
|
||||||
|
addr |= 0x01;
|
||||||
|
outb(addr, ioBase + devaddr);
|
||||||
|
while ((inb(ioBase + ssrr) & SSRR_BUS_BUSY))
|
||||||
|
{
|
||||||
|
udelay(100);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((inb(ioBase + ssrr) & SSRR_MASTER_ERR) == SSRR_MASTER_ERR) {
|
||||||
|
/* Read error reset the port */
|
||||||
|
error = -EIO;
|
||||||
|
outb(0x00, ioBase + ssrr);
|
||||||
|
udelay(3000);
|
||||||
|
outb(0x01, ioBase + ssrr);
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
temp = ioBase + readdata;
|
||||||
|
if (data_len == 1)
|
||||||
|
{
|
||||||
|
byte_data = inb(temp);
|
||||||
|
data->byte = byte_data;
|
||||||
|
}
|
||||||
|
else if (data_len == 2)
|
||||||
|
{
|
||||||
|
word_data = inb(temp);
|
||||||
|
word_data |= (inb(++temp) << 8);
|
||||||
|
data->word = word_data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else // do i2c write
|
||||||
|
{
|
||||||
|
temp = ioBase + writedata;
|
||||||
|
if (data_len == 1)
|
||||||
|
{
|
||||||
|
byte_data = data->byte;
|
||||||
|
outb(byte_data, temp);
|
||||||
|
}
|
||||||
|
else if (data_len == 2)
|
||||||
|
{
|
||||||
|
word_data = data->word;
|
||||||
|
outb((word_data & 0xff), temp);
|
||||||
|
outb((word_data >> 4), (++temp));
|
||||||
|
}
|
||||||
|
// write dev addr
|
||||||
|
outb(addr, ioBase + devaddr);
|
||||||
|
|
||||||
|
// check bus access status
|
||||||
|
while ((inb(ioBase + ssrr) & SSRR_BUS_BUSY))
|
||||||
|
{
|
||||||
|
udelay(100);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((inb(ioBase + ssrr) & SSRR_MASTER_ERR) == SSRR_MASTER_ERR) {
|
||||||
|
/* Read error reset the port */
|
||||||
|
error = -EIO;
|
||||||
|
outb(0x00, ioBase + ssrr);
|
||||||
|
udelay(3000);
|
||||||
|
outb(0x01, ioBase + ssrr);
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mutex_unlock(&cpld_data->cpld_lock);
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
exit:
|
||||||
|
mutex_unlock(&cpld_data->cpld_lock);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int dx010_i2c_access(struct i2c_adapter *a, u16 addr,
|
static int dx010_i2c_access(struct i2c_adapter *a, u16 addr,
|
||||||
unsigned short flags, char rw, u8 cmd,
|
unsigned short flags, char rw, u8 cmd,
|
||||||
int size, union i2c_smbus_data *data)
|
int size, union i2c_smbus_data *data)
|
||||||
@ -624,39 +784,19 @@ static int dx010_i2c_access(struct i2c_adapter *a, u16 addr,
|
|||||||
|
|
||||||
/* Map the size to what the chip understands */
|
/* Map the size to what the chip understands */
|
||||||
switch (size) {
|
switch (size) {
|
||||||
case I2C_SMBUS_QUICK:
|
|
||||||
size = HST_CNTL2_QUICK;
|
|
||||||
break;
|
|
||||||
case I2C_SMBUS_BYTE:
|
case I2C_SMBUS_BYTE:
|
||||||
size = HST_CNTL2_BYTE;
|
|
||||||
break;
|
|
||||||
case I2C_SMBUS_BYTE_DATA:
|
case I2C_SMBUS_BYTE_DATA:
|
||||||
size = HST_CNTL2_BYTE_DATA;
|
|
||||||
break;
|
|
||||||
case I2C_SMBUS_WORD_DATA:
|
case I2C_SMBUS_WORD_DATA:
|
||||||
size = HST_CNTL2_WORD_DATA;
|
if(0 == dx010_cpld_i2c_access(a, addr, new_data, rw, cmd, size, data)){
|
||||||
break;
|
|
||||||
case I2C_SMBUS_BLOCK_DATA:
|
|
||||||
size = HST_CNTL2_BLOCK;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
dev_warn(&a->dev, "Unsupported transaction %d\n", size);
|
|
||||||
error = -EOPNOTSUPP;
|
|
||||||
goto Done;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (size) {
|
|
||||||
case HST_CNTL2_BYTE: /* Result put in SMBHSTDAT0 */
|
|
||||||
break;
|
|
||||||
case HST_CNTL2_BYTE_DATA:
|
|
||||||
break;
|
|
||||||
case HST_CNTL2_WORD_DATA:
|
|
||||||
if( 0 == i2c_read_eeprom(a,addr,new_data,cmd,data)){
|
|
||||||
error = 0;
|
error = 0;
|
||||||
}else{
|
}else{
|
||||||
error = -EIO;
|
error = -EIO;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
dev_warn(&a->dev, "Unsupported transaction %d\n", size);
|
||||||
|
error = -EOPNOTSUPP;
|
||||||
|
goto Done;
|
||||||
}
|
}
|
||||||
|
|
||||||
Done:
|
Done:
|
||||||
@ -790,6 +930,6 @@ module_init(cel_dx010_lpc_init);
|
|||||||
module_exit(cel_dx010_lpc_exit);
|
module_exit(cel_dx010_lpc_exit);
|
||||||
|
|
||||||
MODULE_AUTHOR("Pradchaya P <pphuchar@celestica.com>");
|
MODULE_AUTHOR("Pradchaya P <pphuchar@celestica.com>");
|
||||||
MODULE_VERSION("1.0.1");
|
MODULE_VERSION("1.0.2");
|
||||||
MODULE_DESCRIPTION("Celestica SeaStone DX010 LPC Driver");
|
MODULE_DESCRIPTION("Celestica SeaStone DX010 LPC Driver");
|
||||||
MODULE_LICENSE("GPL");
|
MODULE_LICENSE("GPL");
|
||||||
|
Reference in New Issue
Block a user