Skip to content

Commit

Permalink
Merge pull request #78 from roger530-ho/support_fan_direction_of_dc_psu
Browse files Browse the repository at this point in the history
[AS5835-54T/X] support fan direction of DC PSU
  • Loading branch information
bryan1978 authored Jul 12, 2024
2 parents c175fd9 + bfc4f96 commit bd63711
Show file tree
Hide file tree
Showing 4 changed files with 322 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,6 @@
"attr_list":
[
{ "attr_name":"psu_present", "attr_devaddr":"0x60", "attr_devtype":"cpld", "attr_offset":"0x2", "attr_mask":"0x1", "attr_cmpval":"0x0", "attr_len":"1"},
{ "attr_name":"psu_model_name", "attr_devaddr":"0x58", "attr_devtype":"pmbus", "attr_offset":"0x9a", "attr_mask":"0x0", "attr_cmpval":"0xff", "attr_len":"10" },
{ "attr_name":"psu_power_good", "attr_devaddr":"0x60", "attr_devtype":"cpld", "attr_offset":"0x2", "attr_mask":"0x2", "attr_cmpval":"0x2", "attr_len":"1"},
{ "attr_name":"psu_mfr_id", "attr_devaddr":"0x58", "attr_devtype":"pmbus", "attr_offset":"0X99", "attr_mask":"0x0", "attr_cmpval":"0xff", "attr_len":"10" },
{ "attr_name":"psu_fan_dir", "attr_devaddr":"0x58", "attr_devtype":"pmbus", "attr_offset":"0xc3", "attr_mask":"0x0", "attr_cmpval":"0xff", "attr_len":"5"},
Expand All @@ -271,7 +270,8 @@
"topo_info":{ "parent_bus":"0xb", "dev_addr":"0x50", "dev_type":"psu_eeprom"},
"attr_list":
[
{ "attr_name":"psu_serial_num", "attr_devaddr":"0x50", "attr_devtype":"eeprom", "attr_offset":"0x35", "attr_mask":"0x0", "attr_cmpval":"0xff", "attr_len":"19" }
{ "attr_name":"psu_serial_num", "attr_devaddr":"0x50", "attr_devtype":"eeprom", "attr_offset":"0x35", "attr_mask":"0x0", "attr_cmpval":"0xff", "attr_len":"19" },
{ "attr_name":"psu_model_name", "attr_devaddr":"0x50", "attr_devtype":"eeprom", "attr_offset":"0x20", "attr_mask":"0x0", "attr_cmpval":"0xff", "attr_len":"12" }
]
}
},
Expand Down Expand Up @@ -299,7 +299,6 @@
"attr_list":
[
{ "attr_name":"psu_present", "attr_devaddr":"0x60", "attr_devtype":"cpld", "attr_offset":"0x2", "attr_mask":"0x10", "attr_cmpval":"0x0", "attr_len":"1"},
{ "attr_name":"psu_model_name", "attr_devaddr":"0x5b", "attr_devtype":"pmbus", "attr_offset":"0x9a", "attr_mask":"0x0", "attr_cmpval":"0xff", "attr_len":"10" },
{ "attr_name":"psu_power_good", "attr_devaddr":"0x60", "attr_devtype":"cpld", "attr_offset":"0x2", "attr_mask":"0x20", "attr_cmpval":"0x20", "attr_len":"1"},
{ "attr_name":"psu_mfr_id", "attr_devaddr":"0x5b", "attr_devtype":"pmbus", "attr_offset":"0X99", "attr_mask":"0x0", "attr_cmpval":"0xff", "attr_len":"10" },
{ "attr_name":"psu_fan_dir", "attr_devaddr":"0x5b", "attr_devtype":"pmbus", "attr_offset":"0xc3", "attr_mask":"0x0", "attr_cmpval":"0xff", "attr_len":"5"},
Expand All @@ -324,7 +323,8 @@
"topo_info":{ "parent_bus":"0xc", "dev_addr":"0x53", "dev_type":"psu_eeprom"},
"attr_list":
[
{ "attr_name":"psu_serial_num", "attr_devaddr":"0x53", "attr_devtype":"eeprom", "attr_offset":"0x35", "attr_mask":"0x0", "attr_cmpval":"0xff", "attr_len":"19" }
{ "attr_name":"psu_serial_num", "attr_devaddr":"0x53", "attr_devtype":"eeprom", "attr_offset":"0x35", "attr_mask":"0x0", "attr_cmpval":"0xff", "attr_len":"19" },
{ "attr_name":"psu_model_name", "attr_devaddr":"0x53", "attr_devtype":"eeprom", "attr_offset":"0x20", "attr_mask":"0x0", "attr_cmpval":"0xff", "attr_len":"12" }
]
}
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,6 @@
"attr_list":
[
{ "attr_name":"psu_present", "attr_devaddr":"0x60", "attr_devtype":"cpld", "attr_offset":"0x2", "attr_mask":"0x1", "attr_cmpval":"0x0", "attr_len":"1"},
{ "attr_name":"psu_model_name", "attr_devaddr":"0x58", "attr_devtype":"pmbus", "attr_offset":"0x9a", "attr_mask":"0x0", "attr_cmpval":"0xff", "attr_len":"10" },
{ "attr_name":"psu_power_good", "attr_devaddr":"0x60", "attr_devtype":"cpld", "attr_offset":"0x2", "attr_mask":"0x2", "attr_cmpval":"0x2", "attr_len":"1"},
{ "attr_name":"psu_mfr_id", "attr_devaddr":"0x58", "attr_devtype":"pmbus", "attr_offset":"0X99", "attr_mask":"0x0", "attr_cmpval":"0xff", "attr_len":"10" },
{ "attr_name":"psu_fan_dir", "attr_devaddr":"0x58", "attr_devtype":"pmbus", "attr_offset":"0xc3", "attr_mask":"0x0", "attr_cmpval":"0xff", "attr_len":"5"},
Expand All @@ -189,7 +188,8 @@
"topo_info":{ "parent_bus":"0xb", "dev_addr":"0x50", "dev_type":"psu_eeprom"},
"attr_list":
[
{ "attr_name":"psu_serial_num", "attr_devaddr":"0x50", "attr_devtype":"eeprom", "attr_offset":"0x35", "attr_mask":"0x0", "attr_cmpval":"0xff", "attr_len":"19" }
{ "attr_name":"psu_serial_num", "attr_devaddr":"0x50", "attr_devtype":"eeprom", "attr_offset":"0x35", "attr_mask":"0x0", "attr_cmpval":"0xff", "attr_len":"19" },
{ "attr_name":"psu_model_name", "attr_devaddr":"0x50", "attr_devtype":"eeprom", "attr_offset":"0x20", "attr_mask":"0x0", "attr_cmpval":"0xff", "attr_len":"12" }
]
}
},
Expand Down Expand Up @@ -217,7 +217,6 @@
"attr_list":
[
{ "attr_name":"psu_present", "attr_devaddr":"0x60", "attr_devtype":"cpld", "attr_offset":"0x2", "attr_mask":"0x10", "attr_cmpval":"0x0", "attr_len":"1"},
{ "attr_name":"psu_model_name", "attr_devaddr":"0x5b", "attr_devtype":"pmbus", "attr_offset":"0x9a", "attr_mask":"0x0", "attr_cmpval":"0xff", "attr_len":"10" },
{ "attr_name":"psu_power_good", "attr_devaddr":"0x60", "attr_devtype":"cpld", "attr_offset":"0x2", "attr_mask":"0x20", "attr_cmpval":"0x20", "attr_len":"1"},
{ "attr_name":"psu_mfr_id", "attr_devaddr":"0x5b", "attr_devtype":"pmbus", "attr_offset":"0X99", "attr_mask":"0x0", "attr_cmpval":"0xff", "attr_len":"10" },
{ "attr_name":"psu_fan_dir", "attr_devaddr":"0x5b", "attr_devtype":"pmbus", "attr_offset":"0xc3", "attr_mask":"0x0", "attr_cmpval":"0xff", "attr_len":"5"},
Expand All @@ -241,7 +240,8 @@
"topo_info":{ "parent_bus":"0xc", "dev_addr":"0x53", "dev_type":"psu_eeprom"},
"attr_list":
[
{ "attr_name":"psu_serial_num", "attr_devaddr":"0x53", "attr_devtype":"eeprom", "attr_offset":"0x35", "attr_mask":"0x0", "attr_cmpval":"0xff", "attr_len":"19" }
{ "attr_name":"psu_serial_num", "attr_devaddr":"0x53", "attr_devtype":"eeprom", "attr_offset":"0x35", "attr_mask":"0x0", "attr_cmpval":"0xff", "attr_len":"19" },
{ "attr_name":"psu_model_name", "attr_devaddr":"0x53", "attr_devtype":"eeprom", "attr_offset":"0x20", "attr_mask":"0x0", "attr_cmpval":"0xff", "attr_len":"12" }
]
}
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,31 @@
#include <linux/sysfs.h>
#include <linux/slab.h>
#include <linux/dmi.h>
#include "pddf_client_defs.h"
#include "pddf_psu_defs.h"
#include "pddf_psu_driver.h"
#include "pddf_psu_api.h"

ssize_t pddf_show_custom_psu_v_out(struct device *dev, struct device_attribute *da, char *buf);
extern PSU_SYSFS_ATTR_DATA access_psu_v_out;
int pddf_post_get_custom_psu_model_name(void *i2c_client, PSU_DATA_ATTR *adata, void *data);
extern PSU_SYSFS_ATTR_DATA access_psu_model_name;
int pddf_post_get_custom_psu_fan_dir(void *i2c_client, PSU_DATA_ATTR *adata, void *data);
extern PSU_SYSFS_ATTR_DATA access_psu_fan_dir;
int pddf_custom_psu_post_probe(struct i2c_client *client, const struct i2c_device_id *dev_id);
int pddf_custom_psu_post_remove(struct i2c_client *client);
extern struct pddf_ops_t pddf_psu_ops;

const char FAN_DIR_F2B[] = "F2B\0";
const char FAN_DIR_B2F[] = "B2F\0";

static LIST_HEAD(psu_eeprom_client_list);
static struct mutex list_lock;

struct psu_eeprom_client_node {
struct i2c_client *client;
struct list_head list;
};

static int two_complement_to_int(u16 data, u8 valid_bit, int mask)
{
Expand Down Expand Up @@ -95,11 +116,147 @@ ssize_t pddf_show_custom_psu_v_out(struct device *dev, struct device_attribute *
}


int pddf_post_get_custom_psu_model_name(void *i2c_client, PSU_DATA_ATTR *adata, void *data)
{
struct psu_attr_info *sysfs_attr_info = (struct psu_attr_info *)data;

if (strlen(sysfs_attr_info->val.strval) > 8) {
sysfs_attr_info->val.strval[8] = '-';
}

return 0;
}

/*
* Get the PSU EEPROM I2C client with the same bus number.
*/
static struct i2c_client *find_psu_eeprom_client(struct i2c_client *pmbus_client)
{
struct list_head *list_node = NULL;
struct psu_eeprom_client_node *psu_eeprom_node = NULL;
struct i2c_client *eeprom_client = NULL;

mutex_lock(&list_lock);
list_for_each(list_node, &psu_eeprom_client_list) {
psu_eeprom_node = list_entry(list_node, struct psu_eeprom_client_node, list);
/* Check if the bus adapter is the same or not. */
if (psu_eeprom_node->client->adapter == pmbus_client->adapter) {
eeprom_client = psu_eeprom_node->client;
break;
}
}
mutex_unlock(&list_lock);

return eeprom_client;
}

int pddf_post_get_custom_psu_fan_dir(void *i2c_client, PSU_DATA_ATTR *adata, void *data)
{
int i;
struct i2c_client *client = (struct i2c_client *)i2c_client;
struct psu_attr_info *psu_fan_dir_attr_info = (struct psu_attr_info *)data;
struct psu_data *psu_eeprom_client_data = NULL;
struct psu_attr_info *psu_eeprom_model_name = NULL;
struct i2c_client *psu_eeprom_client = NULL;

psu_eeprom_client = find_psu_eeprom_client(client);
if (!psu_eeprom_client) {
return 0;
}

/*
* Get the model name from the PSU EEPROM I2C client.
*/
psu_eeprom_client_data = i2c_get_clientdata(psu_eeprom_client);
if (!psu_eeprom_client_data) {
return 0;
}
for (i = 0; i < psu_eeprom_client_data->num_attr; i++) {
if (strcmp(psu_eeprom_client_data->attr_info[i].name, "psu_model_name") == 0) {
psu_eeprom_model_name = &psu_eeprom_client_data->attr_info[i];
break;
}
}
if (!psu_eeprom_model_name) {
return 0;
}

/*
* Compare the model name, then replace the content of psu_fan_dir.
*/
if (strcmp(psu_eeprom_model_name->val.strval, "YM-2401H-CR") == 0) {
strscpy(psu_fan_dir_attr_info->val.strval,
FAN_DIR_F2B,
sizeof(psu_fan_dir_attr_info->val.strval));
} else if (strcmp(psu_eeprom_model_name->val.strval, "YM-2401H-DR") == 0) {
strscpy(psu_fan_dir_attr_info->val.strval,
FAN_DIR_B2F,
sizeof(psu_fan_dir_attr_info->val.strval));
}

return 0;
}

int pddf_custom_psu_post_probe(struct i2c_client *client, const struct i2c_device_id *dev_id)
{
struct psu_eeprom_client_node *psu_eeprom_node;

if (strcmp(dev_id->name, "psu_eeprom") != 0) {
return 0;
}

psu_eeprom_node = kzalloc(sizeof(struct psu_eeprom_client_node), GFP_KERNEL);
if (!psu_eeprom_node) {
dev_dbg(&client->dev, "Can't allocate psu_eeprom_client_node (0x%x)\n", client->addr);
return -ENOMEM;
}

psu_eeprom_node->client = client;

mutex_lock(&list_lock);
list_add(&psu_eeprom_node->list, &psu_eeprom_client_list);
mutex_unlock(&list_lock);

return 0;
}

int pddf_custom_psu_post_remove(struct i2c_client *client)
{
struct list_head *list_node = NULL;
struct psu_eeprom_client_node *psu_eeprom_node = NULL;
int found = 0;

mutex_lock(&list_lock);

list_for_each(list_node, &psu_eeprom_client_list) {
psu_eeprom_node = list_entry(list_node, struct psu_eeprom_client_node, list);

if (psu_eeprom_node->client == client) {
list_del_init(&psu_eeprom_node->list);
found = 1;
break;
}
}

if (found) {
kfree(psu_eeprom_node);
}

mutex_unlock(&list_lock);

return 0;
}


static int __init pddf_custom_psu_init(void)
{
mutex_init(&list_lock);
access_psu_v_out.show = pddf_show_custom_psu_v_out;
access_psu_v_out.do_get = NULL;
access_psu_model_name.post_get = pddf_post_get_custom_psu_model_name;
access_psu_fan_dir.post_get = pddf_post_get_custom_psu_fan_dir;
pddf_psu_ops.post_probe = pddf_custom_psu_post_probe;
pddf_psu_ops.post_remove = pddf_custom_psu_post_remove;
return 0;
}

Expand Down
Loading

0 comments on commit bd63711

Please sign in to comment.