📄 w83781d.c
字号:
show_temp_reg(temp_max);show_temp_reg(temp_max_hyst);#define store_temp_reg(REG, reg) \static ssize_t store_temp_##reg (struct device *dev, const char *buf, size_t count, int nr) \{ \ struct i2c_client *client = to_i2c_client(dev); \ struct w83781d_data *data = i2c_get_clientdata(client); \ s32 val; \ \ val = simple_strtol(buf, NULL, 10); \ \ if (nr >= 2) { /* TEMP2 and TEMP3 */ \ if (data->type == as99127f) \ data->temp_##reg##_add[nr-2] = AS99127_TEMP_ADD_TO_REG(val); \ else \ data->temp_##reg##_add[nr-2] = LM75_TEMP_TO_REG(val); \ \ w83781d_write_value(client, W83781D_REG_TEMP_##REG(nr), \ data->temp_##reg##_add[nr-2]); \ } else { /* TEMP1 */ \ data->temp_##reg = TEMP_TO_REG(val); \ w83781d_write_value(client, W83781D_REG_TEMP_##REG(nr), \ data->temp_##reg); \ } \ \ return count; \}store_temp_reg(OVER, max);store_temp_reg(HYST, max_hyst);#define sysfs_temp_offset(offset) \static ssize_t \show_regs_temp_##offset (struct device *dev, char *buf) \{ \ return show_temp(dev, buf, 0x##offset); \} \static DEVICE_ATTR(temp##offset##_input, S_IRUGO, show_regs_temp_##offset, NULL);#define sysfs_temp_reg_offset(reg, offset) \static ssize_t show_regs_temp_##reg##offset (struct device *dev, char *buf) \{ \ return show_temp_##reg (dev, buf, 0x##offset); \} \static ssize_t store_regs_temp_##reg##offset (struct device *dev, const char *buf, size_t count) \{ \ return store_temp_##reg (dev, buf, count, 0x##offset); \} \static DEVICE_ATTR(temp##offset##_##reg, S_IRUGO| S_IWUSR, show_regs_temp_##reg##offset, store_regs_temp_##reg##offset);#define sysfs_temp_offsets(offset) \sysfs_temp_offset(offset); \sysfs_temp_reg_offset(max, offset); \sysfs_temp_reg_offset(max_hyst, offset);sysfs_temp_offsets(1);sysfs_temp_offsets(2);sysfs_temp_offsets(3);#define device_create_file_temp(client, offset) \do { \device_create_file(&client->dev, &dev_attr_temp##offset##_input); \device_create_file(&client->dev, &dev_attr_temp##offset##_max); \device_create_file(&client->dev, &dev_attr_temp##offset##_max_hyst); \} while (0)static ssize_tshow_vid_reg(struct device *dev, char *buf){ struct w83781d_data *data = w83781d_update_device(dev); return sprintf(buf, "%ld\n", (long) vid_from_reg(data->vid, data->vrm));}staticDEVICE_ATTR(in0_ref, S_IRUGO, show_vid_reg, NULL);#define device_create_file_vid(client) \device_create_file(&client->dev, &dev_attr_in0_ref);static ssize_tshow_vrm_reg(struct device *dev, char *buf){ struct w83781d_data *data = w83781d_update_device(dev); return sprintf(buf, "%ld\n", (long) data->vrm);}static ssize_tstore_vrm_reg(struct device *dev, const char *buf, size_t count){ struct i2c_client *client = to_i2c_client(dev); struct w83781d_data *data = i2c_get_clientdata(client); u32 val; val = simple_strtoul(buf, NULL, 10); data->vrm = val; return count;}staticDEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm_reg, store_vrm_reg);#define device_create_file_vrm(client) \device_create_file(&client->dev, &dev_attr_vrm);static ssize_tshow_alarms_reg(struct device *dev, char *buf){ struct w83781d_data *data = w83781d_update_device(dev); return sprintf(buf, "%ld\n", (long) ALARMS_FROM_REG(data->alarms));}staticDEVICE_ATTR(alarms, S_IRUGO, show_alarms_reg, NULL);#define device_create_file_alarms(client) \device_create_file(&client->dev, &dev_attr_alarms);static ssize_t show_beep_mask (struct device *dev, char *buf){ struct w83781d_data *data = w83781d_update_device(dev); return sprintf(buf, "%ld\n", (long)BEEP_MASK_FROM_REG(data->beep_mask, data->type));}static ssize_t show_beep_enable (struct device *dev, char *buf){ struct w83781d_data *data = w83781d_update_device(dev); return sprintf(buf, "%ld\n", (long)BEEP_ENABLE_FROM_REG(data->beep_enable));}#define BEEP_ENABLE 0 /* Store beep_enable */#define BEEP_MASK 1 /* Store beep_mask */static ssize_tstore_beep_reg(struct device *dev, const char *buf, size_t count, int update_mask){ struct i2c_client *client = to_i2c_client(dev); struct w83781d_data *data = i2c_get_clientdata(client); u32 val, val2; val = simple_strtoul(buf, NULL, 10); if (update_mask == BEEP_MASK) { /* We are storing beep_mask */ data->beep_mask = BEEP_MASK_TO_REG(val, data->type); w83781d_write_value(client, W83781D_REG_BEEP_INTS1, data->beep_mask & 0xff); if ((data->type != w83781d) && (data->type != as99127f)) { w83781d_write_value(client, W83781D_REG_BEEP_INTS3, ((data->beep_mask) >> 16) & 0xff); } val2 = (data->beep_mask >> 8) & 0x7f; } else { /* We are storing beep_enable */ val2 = w83781d_read_value(client, W83781D_REG_BEEP_INTS2) & 0x7f; data->beep_enable = BEEP_ENABLE_TO_REG(val); } w83781d_write_value(client, W83781D_REG_BEEP_INTS2, val2 | data->beep_enable << 7); return count;}#define sysfs_beep(REG, reg) \static ssize_t show_regs_beep_##reg (struct device *dev, char *buf) \{ \ return show_beep_##reg(dev, buf); \} \static ssize_t store_regs_beep_##reg (struct device *dev, const char *buf, size_t count) \{ \ return store_beep_reg(dev, buf, count, BEEP_##REG); \} \static DEVICE_ATTR(beep_##reg, S_IRUGO | S_IWUSR, show_regs_beep_##reg, store_regs_beep_##reg);sysfs_beep(ENABLE, enable);sysfs_beep(MASK, mask);#define device_create_file_beep(client) \do { \device_create_file(&client->dev, &dev_attr_beep_enable); \device_create_file(&client->dev, &dev_attr_beep_mask); \} while (0)static ssize_tshow_fan_div_reg(struct device *dev, char *buf, int nr){ struct w83781d_data *data = w83781d_update_device(dev); return sprintf(buf, "%ld\n", (long) DIV_FROM_REG(data->fan_div[nr - 1]));}/* Note: we save and restore the fan minimum here, because its value is determined in part by the fan divisor. This follows the principle of least suprise; the user doesn't expect the fan minimum to change just because the divisor changed. */static ssize_tstore_fan_div_reg(struct device *dev, const char *buf, size_t count, int nr){ struct i2c_client *client = to_i2c_client(dev); struct w83781d_data *data = i2c_get_clientdata(client); unsigned long min; u8 reg; /* Save fan_min */ min = FAN_FROM_REG(data->fan_min[nr], DIV_FROM_REG(data->fan_div[nr])); data->fan_div[nr] = DIV_TO_REG(simple_strtoul(buf, NULL, 10), data->type); reg = (w83781d_read_value(client, nr==2 ? W83781D_REG_PIN : W83781D_REG_VID_FANDIV) & (nr==0 ? 0xcf : 0x3f)) | ((data->fan_div[nr] & 0x03) << (nr==0 ? 4 : 6)); w83781d_write_value(client, nr==2 ? W83781D_REG_PIN : W83781D_REG_VID_FANDIV, reg); /* w83781d and as99127f don't have extended divisor bits */ if (data->type != w83781d && data->type != as99127f) { reg = (w83781d_read_value(client, W83781D_REG_VBAT) & ~(1 << (5 + nr))) | ((data->fan_div[nr] & 0x04) << (3 + nr)); w83781d_write_value(client, W83781D_REG_VBAT, reg); } /* Restore fan_min */ data->fan_min[nr] = FAN_TO_REG(min, DIV_FROM_REG(data->fan_div[nr])); w83781d_write_value(client, W83781D_REG_FAN_MIN(nr+1), data->fan_min[nr]); return count;}#define sysfs_fan_div(offset) \static ssize_t show_regs_fan_div_##offset (struct device *dev, char *buf) \{ \ return show_fan_div_reg(dev, buf, offset); \} \static ssize_t store_regs_fan_div_##offset (struct device *dev, const char *buf, size_t count) \{ \ return store_fan_div_reg(dev, buf, count, offset - 1); \} \static DEVICE_ATTR(fan##offset##_div, S_IRUGO | S_IWUSR, show_regs_fan_div_##offset, store_regs_fan_div_##offset);sysfs_fan_div(1);sysfs_fan_div(2);sysfs_fan_div(3);#define device_create_file_fan_div(client, offset) \do { \device_create_file(&client->dev, &dev_attr_fan##offset##_div); \} while (0)static ssize_tshow_pwm_reg(struct device *dev, char *buf, int nr){ struct w83781d_data *data = w83781d_update_device(dev); return sprintf(buf, "%ld\n", (long) PWM_FROM_REG(data->pwm[nr - 1]));}static ssize_tshow_pwmenable_reg(struct device *dev, char *buf, int nr){ struct w83781d_data *data = w83781d_update_device(dev); return sprintf(buf, "%ld\n", (long) data->pwmenable[nr - 1]);}static ssize_tstore_pwm_reg(struct device *dev, const char *buf, size_t count, int nr){ struct i2c_client *client = to_i2c_client(dev); struct w83781d_data *data = i2c_get_clientdata(client); u32 val; val = simple_strtoul(buf, NULL, 10); data->pwm[nr - 1] = PWM_TO_REG(val); w83781d_write_value(client, W83781D_REG_PWM(nr), data->pwm[nr - 1]); return count;}static ssize_tstore_pwmenable_reg(struct device *dev, const char *buf, size_t count, int nr){ struct i2c_client *client = to_i2c_client(dev); struct w83781d_data *data = i2c_get_clientdata(client); u32 val, reg; val = simple_strtoul(buf, NULL, 10); switch (val) { case 0: case 1: reg = w83781d_read_value(client, W83781D_REG_PWMCLK12); w83781d_write_value(client, W83781D_REG_PWMCLK12, (reg & 0xf7) | (val << 3)); reg = w83781d_read_value(client, W83781D_REG_BEEP_CONFIG); w83781d_write_value(client, W83781D_REG_BEEP_CONFIG, (reg & 0xef) | (!val << 4)); data->pwmenable[nr - 1] = val; break; default: return -EINVAL; } return count;}#define sysfs_pwm(offset) \static ssize_t show_regs_pwm_##offset (struct device *dev, char *buf) \{ \ return show_pwm_reg(dev, buf, offset); \} \static ssize_t store_regs_pwm_##offset (struct device *dev, const char *buf, size_t count) \{ \ return store_pwm_reg(dev, buf, count, offset); \} \static DEVICE_ATTR(fan##offset##_pwm, S_IRUGO | S_IWUSR, show_regs_pwm_##offset, store_regs_pwm_##offset);#define sysfs_pwmenable(offset) \static ssize_t show_regs_pwmenable_##offset (struct device *dev, char *buf) \{ \ return show_pwmenable_reg(dev, buf, offset); \} \static ssize_t store_regs_pwmenable_##offset (struct device *dev, const char *buf, size_t count) \{ \ return store_pwmenable_reg(dev, buf, count, offset); \} \static DEVICE_ATTR(fan##offset##_pwm_enable, S_IRUGO | S_IWUSR, show_regs_pwmenable_##offset, store_regs_pwmenable_##offset);sysfs_pwm(1);sysfs_pwm(2);sysfs_pwmenable(2); /* only PWM2 can be enabled/disabled */sysfs_pwm(3);sysfs_pwm(4);#define device_create_file_pwm(client, offset) \do { \device_create_file(&client->dev, &dev_attr_fan##offset##_pwm); \} while (0)#define device_create_file_pwmenable(client, offset) \do { \device_create_file(&client->dev, &dev_attr_fan##offset##_pwm_enable); \} while (0)static ssize_tshow_sensor_reg(struct device *dev, char *buf, int nr){ struct w83781d_data *data = w83781d_update_device(dev); return sprintf(buf, "%ld\n", (long) data->sens[nr - 1]);}static ssize_tstore_sensor_reg(struct device *dev, const char *buf, size_t count, int nr){ struct i2c_client *client = to_i2c_client(dev); struct w83781d_data *data = i2c_get_clientdata(client); u32 val, tmp; val = simple_strtoul(buf, NULL, 10); switch (val) { case 1: /* PII/Celeron diode */ tmp = w83781d_read_value(client, W83781D_REG_SCFG1); w83781d_write_value(client, W83781D_REG_SCFG1, tmp | BIT_SCFG1[nr - 1]); tmp = w83781d_read_value(client, W83781D_REG_SCFG2); w83781d_write_value(client, W83781D_REG_SCFG2, tmp | BIT_SCFG2[nr - 1]); data->sens[nr - 1] = val; break; case 2: /* 3904 */ tmp = w83781d_read_value(client, W83781D_REG_SCFG1); w83781d_write_value(client, W83781D_REG_SCFG1, tmp | BIT_SCFG1[nr - 1]); tmp = w83781d_read_value(client, W83781D_REG_SCFG2); w83781d_write_value(client, W83781D_REG_SCFG2, tmp & ~BIT_SCFG2[nr - 1]); data->sens[nr - 1] = val; break; case W83781D_DEFAULT_BETA: /* thermistor */ tmp = w83781d_read_value(client, W83781D_REG_SCFG1); w83781d_write_value(client, W83781D_REG_SCFG1, tmp & ~BIT_SCFG1[nr - 1]); data->sens[nr - 1] = val; break; default: dev_err(&client->dev, "Invalid sensor type %ld; must be 1, 2, or %d\n", (long) val, W83781D_DEFAULT_BETA); break; } return count;}#define sysfs_sensor(offset) \static ssize_t show_regs_sensor_##offset (struct device *dev, char *buf) \{ \ return show_sensor_reg(dev, buf, offset); \} \static ssize_t store_regs_sensor_##offset (struct device *dev, const char *buf, size_t count) \{ \ return store_sensor_reg(dev, buf, count, offset); \} \static DEVICE_ATTR(temp##offset##_type, S_IRUGO | S_IWUSR, show_regs_sensor_##offset, store_regs_sensor_##offset);sysfs_sensor(1);sysfs_sensor(2);sysfs_sensor(3);#define device_create_file_sensor(client, offset) \do { \device_create_file(&client->dev, &dev_attr_temp##offset##_type); \} while (0)#ifdef W83781D_RTstatic ssize_tshow_rt_reg(struct device *dev, char *buf, int nr){ struct w83781d_data *data = w83781d_update_device(dev); int i, j = 0; for (i = 0; i < 32; i++) { if (i > 0) j += sprintf(buf, " %ld", (long) data->rt[nr - 1][i]); else j += sprintf(buf, "%ld", (long) data->rt[nr - 1][i]); } j += sprintf(buf, "\n"); return j;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -