📄 w83627hf.c
字号:
static DEVICE_ATTR(in0_max, S_IRUGO | S_IWUSR, show_regs_in_max0, store_regs_in_max0);#define device_create_file_in(client, offset) \do { \device_create_file(&client->dev, &dev_attr_in##offset##_input); \device_create_file(&client->dev, &dev_attr_in##offset##_min); \device_create_file(&client->dev, &dev_attr_in##offset##_max); \} while (0)#define show_fan_reg(reg) \static ssize_t show_##reg (struct device *dev, char *buf, int nr) \{ \ struct w83627hf_data *data = w83627hf_update_device(dev); \ return sprintf(buf,"%ld\n", \ FAN_FROM_REG(data->reg[nr-1], \ (long)DIV_FROM_REG(data->fan_div[nr-1]))); \}show_fan_reg(fan);show_fan_reg(fan_min);static ssize_tstore_fan_min(struct device *dev, const char *buf, size_t count, int nr){ struct i2c_client *client = to_i2c_client(dev); struct w83627hf_data *data = i2c_get_clientdata(client); u32 val; val = simple_strtoul(buf, NULL, 10); data->fan_min[nr - 1] = FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr - 1])); w83627hf_write_value(client, W83781D_REG_FAN_MIN(nr), data->fan_min[nr - 1]); return count;}#define sysfs_fan_offset(offset) \static ssize_t show_regs_fan_##offset (struct device *dev, char *buf) \{ \ return show_fan(dev, buf, 0x##offset); \} \static DEVICE_ATTR(fan##offset##_input, S_IRUGO, show_regs_fan_##offset, NULL);#define sysfs_fan_min_offset(offset) \static ssize_t show_regs_fan_min##offset (struct device *dev, char *buf) \{ \ return show_fan_min(dev, buf, 0x##offset); \} \static ssize_t \store_regs_fan_min##offset (struct device *dev, const char *buf, size_t count) \{ \ return store_fan_min(dev, buf, count, 0x##offset); \} \static DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, \ show_regs_fan_min##offset, store_regs_fan_min##offset);sysfs_fan_offset(1);sysfs_fan_min_offset(1);sysfs_fan_offset(2);sysfs_fan_min_offset(2);sysfs_fan_offset(3);sysfs_fan_min_offset(3);#define device_create_file_fan(client, offset) \do { \device_create_file(&client->dev, &dev_attr_fan##offset##_input); \device_create_file(&client->dev, &dev_attr_fan##offset##_min); \} while (0)#define show_temp_reg(reg) \static ssize_t show_##reg (struct device *dev, char *buf, int nr) \{ \ struct w83627hf_data *data = w83627hf_update_device(dev); \ if (nr >= 2) { /* TEMP2 and TEMP3 */ \ return sprintf(buf,"%ld\n", \ (long)LM75_TEMP_FROM_REG(data->reg##_add[nr-2])); \ } else { /* TEMP1 */ \ return sprintf(buf,"%ld\n", (long)TEMP_FROM_REG(data->reg)); \ } \}show_temp_reg(temp);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 w83627hf_data *data = i2c_get_clientdata(client); \ u32 val; \ \ val = simple_strtoul(buf, NULL, 10); \ \ if (nr >= 2) { /* TEMP2 and TEMP3 */ \ data->temp_##reg##_add[nr-2] = LM75_TEMP_TO_REG(val); \ w83627hf_write_value(client, W83781D_REG_TEMP_##REG(nr), \ data->temp_##reg##_add[nr-2]); \ } else { /* TEMP1 */ \ data->temp_##reg = TEMP_TO_REG(val); \ w83627hf_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 w83627hf_data *data = w83627hf_update_device(dev); return sprintf(buf, "%ld\n", (long) vid_from_reg(data->vid, data->vrm));}static DEVICE_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 w83627hf_data *data = w83627hf_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 w83627hf_data *data = i2c_get_clientdata(client); u32 val; val = simple_strtoul(buf, NULL, 10); data->vrm = val; return count;}static DEVICE_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 w83627hf_data *data = w83627hf_update_device(dev); return sprintf(buf, "%ld\n", (long) data->alarms);}static DEVICE_ATTR(alarms, S_IRUGO, show_alarms_reg, NULL);#define device_create_file_alarms(client) \device_create_file(&client->dev, &dev_attr_alarms)#define show_beep_reg(REG, reg) \static ssize_t show_beep_##reg (struct device *dev, char *buf) \{ \ struct w83627hf_data *data = w83627hf_update_device(dev); \ return sprintf(buf,"%ld\n", \ (long)BEEP_##REG##_FROM_REG(data->beep_##reg)); \}show_beep_reg(ENABLE, enable)show_beep_reg(MASK, mask)#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 w83627hf_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); w83627hf_write_value(client, W83781D_REG_BEEP_INTS1, data->beep_mask & 0xff); w83627hf_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 = w83627hf_read_value(client, W83781D_REG_BEEP_INTS2) & 0x7f; data->beep_enable = BEEP_ENABLE_TO_REG(val); } w83627hf_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 w83627hf_data *data = w83627hf_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 w83627hf_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)); reg = (w83627hf_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)); w83627hf_write_value(client, nr==2 ? W83781D_REG_PIN : W83781D_REG_VID_FANDIV, reg); reg = (w83627hf_read_value(client, W83781D_REG_VBAT) & ~(1 << (5 + nr))) | ((data->fan_div[nr] & 0x04) << (3 + nr)); w83627hf_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])); w83627hf_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 w83627hf_data *data = w83627hf_update_device(dev); return sprintf(buf, "%ld\n", (long) data->pwm[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 w83627hf_data *data = i2c_get_clientdata(client); u32 val; val = simple_strtoul(buf, NULL, 10); if (data->type == w83627thf) { /* bits 0-3 are reserved in 627THF */ data->pwm[nr - 1] = PWM_TO_REG(val) & 0xf0; w83627hf_write_value(client, W836X7HF_REG_PWM(data->type, nr), data->pwm[nr - 1] | (w83627hf_read_value(client, W836X7HF_REG_PWM(data->type, nr)) & 0x0f)); } else { data->pwm[nr - 1] = PWM_TO_REG(val); w83627hf_write_value(client, W836X7HF_REG_PWM(data->type, nr), data->pwm[nr - 1]); } 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);sysfs_pwm(1);sysfs_pwm(2);sysfs_pwm(3);#define device_create_file_pwm(client, offset) \do { \device_create_file(&client->dev, &dev_attr_fan##offset##_pwm); \} while (0)static ssize_tshow_sensor_reg(struct device *dev, char *buf, int nr){ struct w83627hf_data *data = w83627hf_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 w83627hf_data *data = i2c_get_clientdata(client); u32 val, tmp; val = simple_strtoul(buf, NULL, 10); switch (val) { case 1: /* PII/Celeron diode */ tmp = w83627hf_read_value(client, W83781D_REG_SCFG1); w83627hf_write_value(client, W83781D_REG_SCFG1, tmp | BIT_SCFG1[nr - 1]); tmp = w83627hf_read_value(client, W83781D_REG_SCFG2); w83627hf_write_value(client, W83781D_REG_SCFG2, tmp | BIT_SCFG2[nr - 1]); data->sens[nr - 1] = val; break; case 2: /* 3904 */ tmp = w83627hf_read_value(client, W83781D_REG_SCFG1); w83627hf_write_value(client, W83781D_REG_SCFG1, tmp | BIT_SCFG1[nr - 1]); tmp = w83627hf_read_value(client, W83781D_REG_SCFG2); w83627hf_write_value(client, W83781D_REG_SCFG2, tmp & ~BIT_SCFG2[nr - 1]); data->sens[nr - 1] = val; break; case W83781D_DEFAULT_BETA: /* thermistor */ tmp = w83627hf_read_value(client, W83781D_REG_SCFG1); w83627hf_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)/* This function is called when: * w83627hf_driver is inserted (when this module is loaded), for each available adapter * when a new adapter is inserted (and w83627hf_driver is still present) */static int w83627hf_attach_adapter(struct i2c_adapter *adapter){ return i2c_detect(adapter, &addr_data, w83627hf_detect);}static int w83627hf_find(int *address){ u16 val; superio_enter(); val= superio_inb(DEVID); if(val != W627_DEVID && val != W627THF_DEVID && val != W697_DEVID && val != W637_DEVID) { superio_exit(); return -ENODEV; } superio_select(W83627HF_LD_HWM); val = (superio_inb(WINB_BASE_REG) << 8) | superio_inb(WINB_BASE_REG + 1); *address = val & ~(WINB_EXTENT - 1); if (*address == 0 && force_addr == 0) { superio_exit(); return -ENODEV; } if (force_addr) *address = force_addr; /* so detect will get called */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -