📄 adm1026.c
字号:
data->vid = (data->gpio >> 11) & 0x1f; data->valid = 1; up(&data->update_lock); return data;}static ssize_t show_in(struct device *dev, char *buf, int nr){ struct adm1026_data *data = adm1026_update_device(dev); return sprintf(buf,"%d\n", INS_FROM_REG(nr, data->in[nr]));}static ssize_t show_in_min(struct device *dev, char *buf, int nr) { struct adm1026_data *data = adm1026_update_device(dev); return sprintf(buf,"%d\n", INS_FROM_REG(nr, data->in_min[nr]));}static ssize_t set_in_min(struct device *dev, const char *buf, size_t count, int nr){ struct i2c_client *client = to_i2c_client(dev); struct adm1026_data *data = i2c_get_clientdata(client); int val; down(&data->update_lock); val = simple_strtol(buf, NULL, 10); data->in_min[nr] = INS_TO_REG(nr, val); adm1026_write_value(client, ADM1026_REG_IN_MIN[nr], data->in_min[nr]); up(&data->update_lock); return count; }static ssize_t show_in_max(struct device *dev, char *buf, int nr){ struct adm1026_data *data = adm1026_update_device(dev); return sprintf(buf,"%d\n", INS_FROM_REG(nr, data->in_max[nr]));}static ssize_t set_in_max(struct device *dev, const char *buf, size_t count, int nr){ struct i2c_client *client = to_i2c_client(dev); struct adm1026_data *data = i2c_get_clientdata(client); int val; down(&data->update_lock); val = simple_strtol(buf, NULL, 10); data->in_max[nr] = INS_TO_REG(nr, val); adm1026_write_value(client, ADM1026_REG_IN_MAX[nr], data->in_max[nr]); up(&data->update_lock); return count;}#define in_reg(offset) \static ssize_t show_in##offset (struct device *dev, char *buf) \{ \ return show_in(dev, buf, offset); \} \static ssize_t show_in##offset##_min (struct device *dev, char *buf) \{ \ return show_in_min(dev, buf, offset); \} \static ssize_t set_in##offset##_min (struct device *dev, \ const char *buf, size_t count) \{ \ return set_in_min(dev, buf, count, offset); \} \static ssize_t show_in##offset##_max (struct device *dev, char *buf) \{ \ return show_in_max(dev, buf, offset); \} \static ssize_t set_in##offset##_max (struct device *dev, \ const char *buf, size_t count) \{ \ return set_in_max(dev, buf, count, offset); \} \static DEVICE_ATTR(in##offset##_input, S_IRUGO, show_in##offset, NULL); \static DEVICE_ATTR(in##offset##_min, S_IRUGO | S_IWUSR, \ show_in##offset##_min, set_in##offset##_min); \static DEVICE_ATTR(in##offset##_max, S_IRUGO | S_IWUSR, \ show_in##offset##_max, set_in##offset##_max);in_reg(0);in_reg(1);in_reg(2);in_reg(3);in_reg(4);in_reg(5);in_reg(6);in_reg(7);in_reg(8);in_reg(9);in_reg(10);in_reg(11);in_reg(12);in_reg(13);in_reg(14);in_reg(15);static ssize_t show_in16(struct device *dev, char *buf){ struct adm1026_data *data = adm1026_update_device(dev); return sprintf(buf,"%d\n", INS_FROM_REG(16, data->in[16]) - NEG12_OFFSET);}static ssize_t show_in16_min(struct device *dev, char *buf) { struct adm1026_data *data = adm1026_update_device(dev); return sprintf(buf,"%d\n", INS_FROM_REG(16, data->in_min[16]) - NEG12_OFFSET);}static ssize_t set_in16_min(struct device *dev, const char *buf, size_t count){ struct i2c_client *client = to_i2c_client(dev); struct adm1026_data *data = i2c_get_clientdata(client); int val; down(&data->update_lock); val = simple_strtol(buf, NULL, 10); data->in_min[16] = INS_TO_REG(16, val + NEG12_OFFSET); adm1026_write_value(client, ADM1026_REG_IN_MIN[16], data->in_min[16]); up(&data->update_lock); return count; }static ssize_t show_in16_max(struct device *dev, char *buf){ struct adm1026_data *data = adm1026_update_device(dev); return sprintf(buf,"%d\n", INS_FROM_REG(16, data->in_max[16]) - NEG12_OFFSET);}static ssize_t set_in16_max(struct device *dev, const char *buf, size_t count){ struct i2c_client *client = to_i2c_client(dev); struct adm1026_data *data = i2c_get_clientdata(client); int val; down(&data->update_lock); val = simple_strtol(buf, NULL, 10); data->in_max[16] = INS_TO_REG(16, val+NEG12_OFFSET); adm1026_write_value(client, ADM1026_REG_IN_MAX[16], data->in_max[16]); up(&data->update_lock); return count;}static DEVICE_ATTR(in16_input, S_IRUGO, show_in16, NULL);static DEVICE_ATTR(in16_min, S_IRUGO | S_IWUSR, show_in16_min, set_in16_min);static DEVICE_ATTR(in16_max, S_IRUGO | S_IWUSR, show_in16_max, set_in16_max);/* Now add fan read/write functions */static ssize_t show_fan(struct device *dev, char *buf, int nr){ struct adm1026_data *data = adm1026_update_device(dev); return sprintf(buf,"%d\n", FAN_FROM_REG(data->fan[nr], data->fan_div[nr]));}static ssize_t show_fan_min(struct device *dev, char *buf, int nr){ struct adm1026_data *data = adm1026_update_device(dev); return sprintf(buf,"%d\n", FAN_FROM_REG(data->fan_min[nr], data->fan_div[nr]));}static ssize_t set_fan_min(struct device *dev, const char *buf, size_t count, int nr){ struct i2c_client *client = to_i2c_client(dev); struct adm1026_data *data = i2c_get_clientdata(client); int val; down(&data->update_lock); val = simple_strtol(buf, NULL, 10); data->fan_min[nr] = FAN_TO_REG(val, data->fan_div[nr]); adm1026_write_value(client, ADM1026_REG_FAN_MIN(nr), data->fan_min[nr]); up(&data->update_lock); return count;}#define fan_offset(offset) \static ssize_t show_fan_##offset (struct device *dev, char *buf) \{ \ return show_fan(dev, buf, offset - 1); \} \static ssize_t show_fan_##offset##_min (struct device *dev, char *buf) \{ \ return show_fan_min(dev, buf, offset - 1); \} \static ssize_t set_fan_##offset##_min (struct device *dev, \ const char *buf, size_t count) \{ \ return set_fan_min(dev, buf, count, offset - 1); \} \static DEVICE_ATTR(fan##offset##_input, S_IRUGO, show_fan_##offset, NULL); \static DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, \ show_fan_##offset##_min, set_fan_##offset##_min);fan_offset(1);fan_offset(2);fan_offset(3);fan_offset(4);fan_offset(5);fan_offset(6);fan_offset(7);fan_offset(8);/* Adjust fan_min to account for new fan divisor */static void fixup_fan_min(struct device *dev, int fan, int old_div){ struct i2c_client *client = to_i2c_client(dev); struct adm1026_data *data = i2c_get_clientdata(client); int new_min; int new_div = data->fan_div[fan]; /* 0 and 0xff are special. Don't adjust them */ if (data->fan_min[fan] == 0 || data->fan_min[fan] == 0xff) { return; } new_min = data->fan_min[fan] * old_div / new_div; new_min = SENSORS_LIMIT(new_min, 1, 254); data->fan_min[fan] = new_min; adm1026_write_value(client, ADM1026_REG_FAN_MIN(fan), new_min);}/* Now add fan_div read/write functions */static ssize_t show_fan_div(struct device *dev, char *buf, int nr){ struct adm1026_data *data = adm1026_update_device(dev); return sprintf(buf,"%d\n", data->fan_div[nr]);}static ssize_t set_fan_div(struct device *dev, const char *buf, size_t count, int nr){ struct i2c_client *client = to_i2c_client(dev); struct adm1026_data *data = i2c_get_clientdata(client); int val,orig_div,new_div,shift; val = simple_strtol(buf, NULL, 10); new_div = DIV_TO_REG(val); if (new_div == 0) { return -EINVAL; } down(&data->update_lock); orig_div = data->fan_div[nr]; data->fan_div[nr] = DIV_FROM_REG(new_div); if (nr < 4) { /* 0 <= nr < 4 */ shift = 2 * nr; adm1026_write_value(client, ADM1026_REG_FAN_DIV_0_3, ((DIV_TO_REG(orig_div) & (~(0x03 << shift))) | (new_div << shift))); } else { /* 3 < nr < 8 */ shift = 2 * (nr - 4); adm1026_write_value(client, ADM1026_REG_FAN_DIV_4_7, ((DIV_TO_REG(orig_div) & (~(0x03 << (2 * shift)))) | (new_div << shift))); } if (data->fan_div[nr] != orig_div) { fixup_fan_min(dev,nr,orig_div); } up(&data->update_lock); return count;}#define fan_offset_div(offset) \static ssize_t show_fan_##offset##_div (struct device *dev, char *buf) \{ \ return show_fan_div(dev, buf, offset - 1); \} \static ssize_t set_fan_##offset##_div (struct device *dev, \ const char *buf, size_t count) \{ \ return set_fan_div(dev, buf, count, offset - 1); \} \static DEVICE_ATTR(fan##offset##_div, S_IRUGO | S_IWUSR, \ show_fan_##offset##_div, set_fan_##offset##_div);fan_offset_div(1);fan_offset_div(2);fan_offset_div(3);fan_offset_div(4);fan_offset_div(5);fan_offset_div(6);fan_offset_div(7);fan_offset_div(8);/* Temps */static ssize_t show_temp(struct device *dev, char *buf, int nr){ struct adm1026_data *data = adm1026_update_device(dev); return sprintf(buf,"%d\n", TEMP_FROM_REG(data->temp[nr]));}static ssize_t show_temp_min(struct device *dev, char *buf, int nr){ struct adm1026_data *data = adm1026_update_device(dev); return sprintf(buf,"%d\n", TEMP_FROM_REG(data->temp_min[nr]));}static ssize_t set_temp_min(struct device *dev, const char *buf, size_t count, int nr){ struct i2c_client *client = to_i2c_client(dev); struct adm1026_data *data = i2c_get_clientdata(client); int val; down(&data->update_lock); val = simple_strtol(buf, NULL, 10); data->temp_min[nr] = TEMP_TO_REG(val); adm1026_write_value(client, ADM1026_REG_TEMP_MIN[nr], data->temp_min[nr]); up(&data->update_lock); return count;}static ssize_t show_temp_max(struct device *dev, char *buf, int nr){ struct adm1026_data *data = adm1026_update_device(dev); return sprintf(buf,"%d\n", TEMP_FROM_REG(data->temp_max[nr]));}static ssize_t set_temp_max(struct device *dev, const char *buf, size_t count, int nr){ struct i2c_client *client = to_i2c_client(dev); struct adm1026_data *data = i2c_get_clientdata(client); int val; down(&data->update_lock); val = simple_strtol(buf, NULL, 10); data->temp_max[nr] = TEMP_TO_REG(val); adm1026_write_value(client, ADM1026_REG_TEMP_MAX[nr], data->temp_max[nr]); up(&data->update_lock); return count;}#define temp_reg(offset) \static ssize_t show_temp_##offset (struct device *dev, char *buf) \{ \ return show_temp(dev, buf, offset - 1); \} \static ssize_t show_temp_##offset##_min (struct device *dev, char *buf) \{ \ return show_temp_min(dev, buf, offset - 1); \} \static ssize_t show_temp_##offset##_max (struct device *dev, char *buf) \{ \ return show_temp_max(dev, buf, offset - 1); \} \static ssize_t set_temp_##offset##_min (struct device *dev, \ const char *buf, size_t count) \{ \ return set_temp_min(dev, buf, count, offset - 1); \} \static ssize_t set_temp_##offset##_max (struct device *dev, \ const char *buf, size_t count) \{ \ return set_temp_max(dev, buf, count, offset - 1); \} \static DEVICE_ATTR(temp##offset##_input, S_IRUGO, show_temp_##offset, NULL); \
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -