[Delta]: Modify delta-ag9032v1 driver for kernel 4.9 (#20)

Signed-off-by: neal tai <neal.tai@deltaww.com>
This commit is contained in:
nealtai 2018-03-01 16:55:28 +08:00 committed by Guohan Lu
parent 025dad0e11
commit 4142d7f4bf
8 changed files with 217 additions and 30 deletions

View File

@ -7,7 +7,7 @@ include $(PLATFORM_PATH)/platform-modules-ingrasys.mk
include $(PLATFORM_PATH)/platform-modules-accton.mk
include $(PLATFORM_PATH)/platform-modules-inventec.mk
include $(PLATFORM_PATH)/platform-modules-cel.mk
#include $(PLATFORM_PATH)/platform-modules-delta.mk
include $(PLATFORM_PATH)/platform-modules-delta.mk
include $(PLATFORM_PATH)/platform-modules-quanta.mk
#include $(PLATFORM_PATH)/platform-modules-mitac.mk
include $(PLATFORM_PATH)/docker-orchagent-brcm.mk

View File

@ -1,2 +1 @@
obj-m := dni_ag9032v1_psu.o dni_emc2305.o delta_ag9032v1_platform.o delta_ag9032v1_cpupld.o

View File

@ -248,25 +248,25 @@ static struct i2c_device_platform_data ag9032v1_i2c_device_platform_data[] = {
{
/* psu 1 (0x58) */
.parent = 40,
.info = { .type = "dni_ag9032v1_psu", .addr = 0x58, .platform_data = 0 },
.info = { .type = "dni_ag9032v1_psu", .addr = 0x58, .platform_data = (void *) 0 },
.client = NULL,
},
{
/* psu 2 (0x58) */
.parent = 41,
.info = { .type = "dni_ag9032v1_psu", .addr = 0x58, .platform_data = 1 },
.info = { .type = "dni_ag9032v1_psu", .addr = 0x58, .platform_data = (void *) 1 },
.client = NULL,
},
{
/* hot-swap 1 (0x40) */
.parent = 42,
.info = { .type = "ltc4215", .addr = 0x40, .platform_data = 0 },
.info = { .type = "ltc4215", .addr = 0x40, .platform_data = (void *) 0 },
.client = NULL,
},
{
/* hot-swap 2 (0x40) */
.parent = 43,
.info = { .type = "ltc4215", .addr = 0x40, .platform_data = 1 },
.info = { .type = "ltc4215", .addr = 0x40, .platform_data = (void *) 1 },
.client = NULL,
},
{
@ -1043,22 +1043,22 @@ static ssize_t get_present(struct device *dev, struct device_attribute \
ret = i2c_smbus_read_byte_data(pdata[system_cpld].client, SFP_PRESENCE_1);
if (ret < 0)
return sprintf(buf, "error number(%ld)",ret);
return sprintf(buf, "error number(%d)",ret);
data = (u32)reverse_8bits(ret) & 0xff;
ret = i2c_smbus_read_byte_data(pdata[system_cpld].client, SFP_PRESENCE_2);
if (ret < 0)
return sprintf(buf, "error number(%ld)",ret);
return sprintf(buf, "error number(%d)",ret);
data |= (u32)(reverse_8bits(ret) & 0xff) << 8;
ret = i2c_smbus_read_byte_data(pdata[system_cpld].client, SFP_PRESENCE_3);
if (ret < 0)
return sprintf(buf, "error number(%ld)",ret);
return sprintf(buf, "error number(%d)",ret);
data |= (u32)(reverse_8bits(ret) & 0xff) << 16;
ret = i2c_smbus_read_byte_data(pdata[system_cpld].client, SFP_PRESENCE_4);
if (ret < 0)
return sprintf(buf, "error number(%ld)",ret);
return sprintf(buf, "error number(%d)",ret);
data |= (u32)(reverse_8bits(ret) & 0xff) << 24;
return sprintf(buf, "0x%08x\n", data); //return 32bits data
@ -1072,22 +1072,22 @@ static ssize_t get_lpmode(struct device *dev, struct device_attribute *devattr,
ret = i2c_smbus_read_byte_data(pdata[system_cpld].client, SFP_LP_MODE_1);
if (ret < 0)
return sprintf(buf, "error number(%ld)",ret);
return sprintf(buf, "error number(%d)",ret);
data = (u32)(reverse_8bits(ret) & 0xff);
ret = i2c_smbus_read_byte_data(pdata[system_cpld].client, SFP_LP_MODE_2);
if (ret < 0)
return sprintf(buf, "error number(%ld)",ret);
return sprintf(buf, "error number(%d)",ret);
data |= (u32)(reverse_8bits(ret) & 0xff) << 8;
ret = i2c_smbus_read_byte_data(pdata[system_cpld].client, SFP_LP_MODE_3);
if (ret < 0)
return sprintf(buf, "error number(%ld)",ret);
return sprintf(buf, "error number(%d)",ret);
data |= (u32)(reverse_8bits(ret) & 0xff) << 16;
ret = i2c_smbus_read_byte_data(pdata[system_cpld].client, SFP_LP_MODE_4);
if (ret < 0)
return sprintf(buf, "error number(%ld)",ret);
return sprintf(buf, "error number(%d)",ret);
data |= (u32)(reverse_8bits(ret) & 0xff) << 24;
return sprintf(buf, "0x%08x\n", data); //return 32bits data
@ -1119,22 +1119,22 @@ static ssize_t get_reset(struct device *dev, struct device_attribute *devattr, c
ret = i2c_smbus_read_byte_data(pdata[system_cpld].client, SFP_RESET_1);
if (ret < 0)
return sprintf(buf, "error number(%ld)",ret);
return sprintf(buf, "error number(%d)",ret);
data = (u32)(reverse_8bits(ret) & 0xff);
ret = i2c_smbus_read_byte_data(pdata[system_cpld].client, SFP_RESET_2);
if (ret < 0)
return sprintf(buf, "error number(%ld)",ret);
return sprintf(buf, "error number(%d)",ret);
data |= (u32)(reverse_8bits(ret) & 0xff) << 8;
ret = i2c_smbus_read_byte_data(pdata[system_cpld].client, SFP_RESET_3);
if (ret < 0)
return sprintf(buf, "error number(%ld)",ret);
return sprintf(buf, "error number(%d)",ret);
data |= (u32)(reverse_8bits(ret) & 0xff) << 16;
ret = i2c_smbus_read_byte_data(pdata[system_cpld].client, SFP_RESET_4);
if (ret < 0)
return sprintf(buf, "error number(%ld)",ret);
return sprintf(buf, "error number(%d)",ret);
data |= (u32)(reverse_8bits(ret) & 0xff) << 24;
return sprintf(buf, "0x%08x\n", data); //return 32bits data
@ -1166,22 +1166,22 @@ static ssize_t get_response(struct device *dev, struct device_attribute *devattr
ret = i2c_smbus_read_byte_data(pdata[system_cpld].client, SFP_RESPONSE_1);
if (ret < 0)
return sprintf(buf, "error number(%ld)",ret);
return sprintf(buf, "error number(%d)",ret);
data = (u32)(reverse_8bits(ret) & 0xff);
ret = i2c_smbus_read_byte_data(pdata[system_cpld].client, SFP_RESPONSE_2);
if (ret < 0)
return sprintf(buf, "error number(%ld)",ret);
return sprintf(buf, "error number(%d)",ret);
data |= (u32)(reverse_8bits(ret) & 0xff) << 8;
ret = i2c_smbus_read_byte_data(pdata[system_cpld].client, SFP_RESPONSE_3);
if (ret < 0)
return sprintf(buf, "error number(%ld)",ret);
return sprintf(buf, "error number(%d)",ret);
data |= (u32)(reverse_8bits(ret) & 0xff) << 16;
ret = i2c_smbus_read_byte_data(pdata[system_cpld].client, SFP_RESPONSE_4);
if (ret < 0)
return sprintf(buf, "error number(%ld)",ret);
return sprintf(buf, "error number(%d)",ret);
data |= (u32)(reverse_8bits(ret) & 0xff) << 24;
return sprintf(buf, "0x%08x\n", data); //return 32bits data
@ -2048,6 +2048,7 @@ static int cpld_reg_write_byte(struct i2c_client *client, u8 regaddr, u8 val)
regaddr, I2C_SMBUS_BYTE_DATA, &data);
}
#if LINUX_VERSION_CODE < KERNEL_VERSION(4,7,0)
static int swpld_mux_select(struct i2c_adapter *adap, void *data, u8 chan)
{
struct swpld_mux *mux = data;
@ -2123,7 +2124,86 @@ static int swpld_mux_select(struct i2c_adapter *adap, void *data, u8 chan)
}
return cpld_reg_write_byte(mux->data.cpld, mux->data.reg_addr, (u8)(swpld_mux_val & 0xff));
}
#else // #if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0)
static int swpld_mux_select(struct i2c_mux_core *muxc, u32 chan)
{
struct swpld_mux *mux = i2c_mux_priv(muxc);
u8 swpld_mux_val=0;
if ( mux->data.base_nr == BUS3_BASE_NUM )
{
switch (chan) {
case 0:
swpld_mux_val = TEMP_FAN_VAL;
break;
case 1:
swpld_mux_val = FAN_EEPROM1_VAL;
break;
case 2:
swpld_mux_val = FAN_EEPROM2_VAL;
break;
case 3:
swpld_mux_val = FAN_EEPROM3_VAL;
break;
case 4:
swpld_mux_val = FAN_EEPROM4_VAL;
break;
case 5:
swpld_mux_val = FAN_EEPROM5_VAL;
break;
case 6:
swpld_mux_val = FANIO_CTL_VAL;
break;
case 7:
case 8:
swpld_mux_val = FAN_CTRL_VAL;
break;
}
}
else if ( mux->data.base_nr == BUS4_BASE_NUM )
{
switch (chan) {
case 0:
swpld_mux_val = PSU1_VAL;
break;
case 1:
swpld_mux_val = PSU2_VAL;
break;
case 2:
swpld_mux_val = HOT_SWAP1_VAL;
break;
case 3:
swpld_mux_val = HOT_SWAP2_VAL;
break;
}
}
else if ( mux->data.base_nr == BUS5_BASE_NUM ){
if (chan < 9){
swpld_mux_val = (u8)(chan) + 0x01;
}
else if (8 < chan && chan < 19){
swpld_mux_val = (u8)(chan - 9) + 0x10;
}
else if (18 < chan && chan < 29){
swpld_mux_val = (u8)(chan - 19) + 0x20;
}
else if (28 < chan && chan < 39){
swpld_mux_val = (u8)(chan - 29) + 0x30;
}
else{
swpld_mux_val = 0x00;
}
}
else
{
swpld_mux_val = 0x00;
}
return cpld_reg_write_byte(mux->data.cpld, mux->data.reg_addr, (u8)(swpld_mux_val & 0xff));
}
#endif // #if LINUX_VERSION_CODE < KERNEL_VERSION(4,7,0)
#if LINUX_VERSION_CODE < KERNEL_VERSION(4,7,0)
static int __init swpld_mux_probe(struct platform_device *pdev)
{
struct swpld_mux *mux;
@ -2202,8 +2282,89 @@ alloc_failed:
return ret;
}
#else // #if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0)
static int __init swpld_mux_probe(struct platform_device *pdev)
{
struct i2c_mux_core *muxc;
struct swpld_mux *mux;
struct swpld_mux_platform_data *pdata;
struct i2c_adapter *parent;
int i, ret, dev_num;
pdata = pdev->dev.platform_data;
if (!pdata) {
dev_err(&pdev->dev, "SWPLD platform data not found\n");
return -ENODEV;
}
mux = kzalloc(sizeof(*mux), GFP_KERNEL);
if (!mux) {
printk(KERN_ERR "Failed to allocate memory for mux\n");
return -ENOMEM;
}
mux->data = *pdata;
parent = i2c_get_adapter(pdata->parent);
if (!parent) {
kfree(mux);
dev_err(&pdev->dev, "Parent adapter (%d) not found\n", pdata->parent);
return -ENODEV;
}
/* Judge bus number to decide how many devices*/
switch (pdata->parent) {
case BUS3:
dev_num = BUS3_DEV_NUM;
break;
case BUS4:
dev_num = BUS4_DEV_NUM;
break;
case BUS5:
dev_num = BUS5_DEV_NUM;
break;
default :
dev_num = DEFAULT_NUM;
break;
}
muxc = i2c_mux_alloc(parent, &pdev->dev, dev_num, 0, 0,
swpld_mux_select, NULL);
if (!muxc) {
ret = -ENOMEM;
goto alloc_failed;
}
muxc->priv = mux;
platform_set_drvdata(pdev, muxc);
for (i = 0; i < dev_num; i++) {
int nr = pdata->base_nr + i;
unsigned int class = 0;
ret = i2c_mux_add_adapter(muxc, nr, i, class);
if (ret) {
dev_err(&pdev->dev, "Failed to add adapter %d\n", i);
goto add_adapter_failed;
}
}
dev_info(&pdev->dev, "%d port mux on %s adapter\n", dev_num, parent->name);
return 0;
add_adapter_failed:
i2c_mux_del_adapters(muxc);
alloc_failed:
kfree(mux);
i2c_put_adapter(parent);
return ret;
}
#endif // #if LINUX_VERSION_CODE < KERNEL_VERSION(4,7,0)
#if LINUX_VERSION_CODE < KERNEL_VERSION(4,7,0)
static int __exit swpld_mux_remove(struct platform_device *pdev)
{
int i;
@ -2249,6 +2410,18 @@ static int __exit swpld_mux_remove(struct platform_device *pdev)
return 0;
}
#else // #if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0)
static int __exit swpld_mux_remove(struct platform_device *pdev)
{
struct i2c_mux_core *muxc = platform_get_drvdata(pdev);
struct i2c_adapter *parent=muxc->parent;
i2c_mux_del_adapters(muxc);
i2c_put_adapter(parent);
return 0;
}
#endif
static struct platform_driver swpld_mux_driver = {
.probe = swpld_mux_probe,
@ -2261,9 +2434,9 @@ static struct platform_driver swpld_mux_driver = {
/*---------------- MUX - end ------------- */
/*---------------- module initialization ------------- */
static void __init delta_ag9032v1_platform_init(void)
static int __init delta_ag9032v1_platform_init(void)
{
struct i2c_client *client;
// struct i2c_client *client;
struct i2c_adapter *adapter;
struct cpld_platform_data *cpld_pdata;
struct swpld_mux_platform_data *swpld_mux_pdata;
@ -2342,7 +2515,7 @@ error_ag9032v1_swpld_mux:
for (; i >= 0; i--) {
platform_device_unregister(&ag9032v1_swpld_mux[i]);
}
platform_driver_unregister(&ag9032v1_cpld);
platform_driver_unregister((struct platform_driver *) &ag9032v1_cpld);
error_ag9032v1_cpld:
platform_driver_unregister(&i2c_device_driver);
error_i2c_device_driver:

View File

@ -24,8 +24,8 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/i2c.h>
#include <linux/slab.h>
@ -43,6 +43,7 @@
u8 psu_member_data = 0x00;
/* Address scanned */
static const unsigned short normal_i2c[] = { 0x58, I2C_CLIENT_END };
@ -419,7 +420,7 @@ static SENSOR_DEVICE_ATTR(temp1_input, \
S_IRUGO, for_linear_data, NULL, PSU_TEMP1_INPUT);
static SENSOR_DEVICE_ATTR(fan1_target, \
S_IRUGO, for_fan_target, NULL, PSU_FAN1_FAULT);
static SENSOR_DEVICE_ATTR(fan1_set_percentage, S_IWUGO | S_IRUGO, \
static SENSOR_DEVICE_ATTR(fan1_set_percentage, S_IWUSR | S_IRUGO, \
for_linear_data, set_fan_duty_cycle_input, PSU_FAN1_DUTY_CYCLE);
static SENSOR_DEVICE_ATTR(fan1_input, \
S_IRUGO, for_linear_data, NULL, PSU_FAN1_SPEED);
@ -427,7 +428,7 @@ static SENSOR_DEVICE_ATTR(psu_mfr_model, \
S_IRUGO, for_ascii, NULL, PSU_MFR_MODEL);
static SENSOR_DEVICE_ATTR(psu_mfr_serial, \
S_IRUGO, for_ascii, NULL, PSU_MFR_SERIAL);
static SENSOR_DEVICE_ATTR(psu_select_member, S_IWUGO | S_IRUGO, \
static SENSOR_DEVICE_ATTR(psu_select_member, S_IWUSR | S_IRUGO, \
for_r_member_data, set_w_member_data, PSU_SELECT_MEMBER);
static struct attribute *dps_800ab_16_d_attributes[] = {

View File

@ -7,7 +7,7 @@ Standards-Version: 3.9.3
Package: platform-modules-ag9032v1
Architecture: amd64
Depends: linux-image-3.16.0-5-amd64
Depends: linux-image-4.9.0-5-amd64
Description: kernel modules for platform devices such as fan, led, sfp
Package: platform-modules-ag9064

View File

@ -1,3 +1,4 @@
ag9032v1/scripts/ag9032v1_platform_init.sh usr/local/bin
ag9032v1/scripts/led_status.sh usr/local/bin
ag9032v1/cfg/ag9032v1-modules.conf etc/modules-load.d
systemd/platform-modules-ag9032v1.service lib/systemd/system

View File

@ -8,7 +8,7 @@ MOD_SRC_DIR:= $(shell pwd)
MODULE_DIRS:= ag9032v1 ag9064 ag5648
%:
dh $@
dh $@ --with=systemd
override_dh_auto_build:
(for mod in $(MODULE_DIRS); do \

View File

@ -0,0 +1,13 @@
[Unit]
Description=Delta ag9032v1 Platform modules
After=local-fs.target
Before=pmon.service
[Service]
Type=oneshot
ExecStart=-/etc/init.d/platform-modules-ag9032v1 start
ExecStop=-/etc/init.d/platform-modules-ag9032v1 stop
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target