#include #include #include #include #include #include #include #include #include "gpioregs.h" extern struct kobject *hwmon_kobj; int sysfs_power_off_flag = 0; static int wait_ibf(void) { int i = 0; while (inb(EC_CMD_PORT) & EC_IBF) { if (++i > TIMEOUT_LOOPS) { return -1; } udelay(1); } return 0; } static int wait_obf(void) { int i = 0; while (!(inb(EC_CMD_PORT) & EC_OBF)) { if (++i > TIMEOUT_LOOPS) { return -1; } udelay(1); } return 0; } static int oem_ec_read_ram(uint8_t page, uint8_t offset, uint8_t *data) { unsigned char WEC, REC; switch (page) { case 0: { WEC = 0x96; REC = 0x95; break; } case 1: { WEC = 0x98; REC = 0x97; break; } default: { WEC = 0x81; REC = 0x80; break; } } if (wait_ibf() < 0) return -1; outb(REC, EC_CMD_PORT); if (wait_ibf() < 0) return -1; outb(offset, EC_DATA_PORT); if (wait_obf() < 0) return -1; *data = inb(EC_DATA_PORT); return 0; } static ssize_t ac_power_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) { int ac_power_flag = 0; uint8_t val = 0x00; if (oem_ec_read_ram(2, 0x36, &val) < 0) return -1; ac_power_flag = (val & 0x03) ? 1 : 0; if(sysfs_power_off_flag == 1) { ac_power_flag = 0; } return sprintf(buf, "%d\n", ac_power_flag); } static ssize_t ac_power_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count) { u32 val; int ret; ret = kstrtou32(buf, 10, &val); if (ret < 0) { pr_err("ac_power_store format error\n"); return ret; } if(val != 0) { pr_err("ac_power_store only support 0\n"); return -EINVAL; } if(val == 0) { sysfs_power_off_flag = 1; } return count; } static struct kobj_attribute ac_power = __ATTR(ac_power, 0644, ac_power_show, ac_power_store); static struct attribute *sysfs_power_attrs[] = { &ac_power.attr, NULL, }; static struct attribute_group sysfs_power_attr_group = { .attrs = sysfs_power_attrs, }; int sysfs_power_init(void) { int ret = 0; ret = sysfs_create_group(hwmon_kobj, &sysfs_power_attr_group); return ret; } void sysfs_power_exit(void) { sysfs_remove_group(hwmon_kobj, &sysfs_power_attr_group); }