vt1211.c
来自「linux 内核源代码」· C语言 代码 · 共 1,371 行 · 第 1/3 页
C
1,371 行
} mutex_unlock(&data->update_lock); return count;}/* --------------------------------------------------------------------- * Fan sysfs interfaces * ix = [0-1] * --------------------------------------------------------------------- */#define SHOW_FAN_INPUT 0#define SHOW_SET_FAN_MIN 1#define SHOW_SET_FAN_DIV 2#define SHOW_FAN_ALARM 3static ssize_t show_fan(struct device *dev, struct device_attribute *attr, char *buf){ struct vt1211_data *data = vt1211_update_device(dev); struct sensor_device_attribute_2 *sensor_attr_2 = to_sensor_dev_attr_2(attr); int ix = sensor_attr_2->index; int fn = sensor_attr_2->nr; int res; switch (fn) { case SHOW_FAN_INPUT: res = RPM_FROM_REG(data->fan[ix], data->fan_div[ix]); break; case SHOW_SET_FAN_MIN: res = RPM_FROM_REG(data->fan_min[ix], data->fan_div[ix]); break; case SHOW_SET_FAN_DIV: res = DIV_FROM_REG(data->fan_div[ix]); break; case SHOW_FAN_ALARM: res = (data->alarms >> bitalarmfan[ix]) & 1; break; default: res = 0; dev_dbg(dev, "Unknown attr fetch (%d)\n", fn); } return sprintf(buf, "%d\n", res);}static ssize_t set_fan(struct device *dev, struct device_attribute *attr, const char *buf, size_t count){ struct vt1211_data *data = dev_get_drvdata(dev); struct sensor_device_attribute_2 *sensor_attr_2 = to_sensor_dev_attr_2(attr); int ix = sensor_attr_2->index; int fn = sensor_attr_2->nr; long val = simple_strtol(buf, NULL, 10); int reg; mutex_lock(&data->update_lock); /* sync the data cache */ reg = vt1211_read8(data, VT1211_REG_FAN_DIV); data->fan_div[0] = (reg >> 4) & 3; data->fan_div[1] = (reg >> 6) & 3; data->fan_ctl = reg & 0xf; switch (fn) { case SHOW_SET_FAN_MIN: data->fan_min[ix] = RPM_TO_REG(val, data->fan_div[ix]); vt1211_write8(data, VT1211_REG_FAN_MIN(ix), data->fan_min[ix]); break; case SHOW_SET_FAN_DIV: switch (val) { case 1: data->fan_div[ix] = 0; break; case 2: data->fan_div[ix] = 1; break; case 4: data->fan_div[ix] = 2; break; case 8: data->fan_div[ix] = 3; break; default: count = -EINVAL; dev_warn(dev, "fan div value %ld not " "supported. Choose one of 1, 2, " "4, or 8.\n", val); goto EXIT; } vt1211_write8(data, VT1211_REG_FAN_DIV, ((data->fan_div[1] << 6) | (data->fan_div[0] << 4) | data->fan_ctl)); break; default: dev_dbg(dev, "Unknown attr fetch (%d)\n", fn); }EXIT: mutex_unlock(&data->update_lock); return count;}/* --------------------------------------------------------------------- * PWM sysfs interfaces * ix = [0-1] * --------------------------------------------------------------------- */#define SHOW_PWM 0#define SHOW_SET_PWM_ENABLE 1#define SHOW_SET_PWM_FREQ 2#define SHOW_SET_PWM_AUTO_CHANNELS_TEMP 3static ssize_t show_pwm(struct device *dev, struct device_attribute *attr, char *buf){ struct vt1211_data *data = vt1211_update_device(dev); struct sensor_device_attribute_2 *sensor_attr_2 = to_sensor_dev_attr_2(attr); int ix = sensor_attr_2->index; int fn = sensor_attr_2->nr; int res; switch (fn) { case SHOW_PWM: res = data->pwm[ix]; break; case SHOW_SET_PWM_ENABLE: res = ((data->pwm_ctl[ix] >> 3) & 1) ? 2 : 0; break; case SHOW_SET_PWM_FREQ: res = 90000 >> (data->pwm_clk & 7); break; case SHOW_SET_PWM_AUTO_CHANNELS_TEMP: res = (data->pwm_ctl[ix] & 7) + 1; break; default: res = 0; dev_dbg(dev, "Unknown attr fetch (%d)\n", fn); } return sprintf(buf, "%d\n", res);}static ssize_t set_pwm(struct device *dev, struct device_attribute *attr, const char *buf, size_t count){ struct vt1211_data *data = dev_get_drvdata(dev); struct sensor_device_attribute_2 *sensor_attr_2 = to_sensor_dev_attr_2(attr); int ix = sensor_attr_2->index; int fn = sensor_attr_2->nr; long val = simple_strtol(buf, NULL, 10); int tmp, reg; mutex_lock(&data->update_lock); switch (fn) { case SHOW_SET_PWM_ENABLE: /* sync the data cache */ reg = vt1211_read8(data, VT1211_REG_FAN_DIV); data->fan_div[0] = (reg >> 4) & 3; data->fan_div[1] = (reg >> 6) & 3; data->fan_ctl = reg & 0xf; reg = vt1211_read8(data, VT1211_REG_PWM_CTL); data->pwm_ctl[0] = reg & 0xf; data->pwm_ctl[1] = (reg >> 4) & 0xf; switch (val) { case 0: data->pwm_ctl[ix] &= 7; /* disable SmartGuardian if both PWM outputs are * disabled */ if ((data->pwm_ctl[ix ^ 1] & 1) == 0) { data->fan_ctl &= 0xe; } break; case 2: data->pwm_ctl[ix] |= 8; data->fan_ctl |= 1; break; default: count = -EINVAL; dev_warn(dev, "pwm mode %ld not supported. " "Choose one of 0 or 2.\n", val); goto EXIT; } vt1211_write8(data, VT1211_REG_PWM_CTL, ((data->pwm_ctl[1] << 4) | data->pwm_ctl[0])); vt1211_write8(data, VT1211_REG_FAN_DIV, ((data->fan_div[1] << 6) | (data->fan_div[0] << 4) | data->fan_ctl)); break; case SHOW_SET_PWM_FREQ: val = 135000 / SENSORS_LIMIT(val, 135000 >> 7, 135000); /* calculate tmp = log2(val) */ tmp = 0; for (val >>= 1; val > 0; val >>= 1) { tmp++; } /* sync the data cache */ reg = vt1211_read8(data, VT1211_REG_PWM_CLK); data->pwm_clk = (reg & 0xf8) | tmp; vt1211_write8(data, VT1211_REG_PWM_CLK, data->pwm_clk); break; case SHOW_SET_PWM_AUTO_CHANNELS_TEMP: if ((val < 1) || (val > 7)) { count = -EINVAL; dev_warn(dev, "temp channel %ld not supported. " "Choose a value between 1 and 7.\n", val); goto EXIT; } if (!ISTEMP(val - 1, data->uch_config)) { count = -EINVAL; dev_warn(dev, "temp channel %ld is not available.\n", val); goto EXIT; } /* sync the data cache */ reg = vt1211_read8(data, VT1211_REG_PWM_CTL); data->pwm_ctl[0] = reg & 0xf; data->pwm_ctl[1] = (reg >> 4) & 0xf; data->pwm_ctl[ix] = (data->pwm_ctl[ix] & 8) | (val - 1); vt1211_write8(data, VT1211_REG_PWM_CTL, ((data->pwm_ctl[1] << 4) | data->pwm_ctl[0])); break; default: dev_dbg(dev, "Unknown attr fetch (%d)\n", fn); }EXIT: mutex_unlock(&data->update_lock); return count;}/* --------------------------------------------------------------------- * PWM auto point definitions * ix = [0-1] * ap = [0-3] * --------------------------------------------------------------------- *//* * pwm[ix+1]_auto_point[ap+1]_temp mapping table: * Note that there is only a single set of temp auto points that controls both * PWM controllers. We still create 2 sets of sysfs files to make it look * more consistent even though they map to the same registers. * * ix ap : description * ------------------- * 0 0 : pwm1/2 off temperature (pwm_auto_temp[0]) * 0 1 : pwm1/2 low speed temperature (pwm_auto_temp[1]) * 0 2 : pwm1/2 high speed temperature (pwm_auto_temp[2]) * 0 3 : pwm1/2 full speed temperature (pwm_auto_temp[3]) * 1 0 : pwm1/2 off temperature (pwm_auto_temp[0]) * 1 1 : pwm1/2 low speed temperature (pwm_auto_temp[1]) * 1 2 : pwm1/2 high speed temperature (pwm_auto_temp[2]) * 1 3 : pwm1/2 full speed temperature (pwm_auto_temp[3]) */static ssize_t show_pwm_auto_point_temp(struct device *dev, struct device_attribute *attr, char *buf){ struct vt1211_data *data = vt1211_update_device(dev); struct sensor_device_attribute_2 *sensor_attr_2 = to_sensor_dev_attr_2(attr); int ix = sensor_attr_2->index; int ap = sensor_attr_2->nr; return sprintf(buf, "%d\n", TEMP_FROM_REG(data->pwm_ctl[ix] & 7, data->pwm_auto_temp[ap]));}static ssize_t set_pwm_auto_point_temp(struct device *dev, struct device_attribute *attr, const char *buf, size_t count){ struct vt1211_data *data = dev_get_drvdata(dev); struct sensor_device_attribute_2 *sensor_attr_2 = to_sensor_dev_attr_2(attr); int ix = sensor_attr_2->index; int ap = sensor_attr_2->nr; long val = simple_strtol(buf, NULL, 10); int reg; mutex_lock(&data->update_lock); /* sync the data cache */ reg = vt1211_read8(data, VT1211_REG_PWM_CTL); data->pwm_ctl[0] = reg & 0xf; data->pwm_ctl[1] = (reg >> 4) & 0xf; data->pwm_auto_temp[ap] = TEMP_TO_REG(data->pwm_ctl[ix] & 7, val); vt1211_write8(data, VT1211_REG_PWM_AUTO_TEMP(ap), data->pwm_auto_temp[ap]); mutex_unlock(&data->update_lock); return count;}/* * pwm[ix+1]_auto_point[ap+1]_pwm mapping table: * Note that the PWM auto points 0 & 3 are hard-wired in the VT1211 and can't * be changed. * * ix ap : description * ------------------- * 0 0 : pwm1 off (pwm_auto_pwm[0][0], hard-wired to 0) * 0 1 : pwm1 low speed duty cycle (pwm_auto_pwm[0][1]) * 0 2 : pwm1 high speed duty cycle (pwm_auto_pwm[0][2]) * 0 3 : pwm1 full speed (pwm_auto_pwm[0][3], hard-wired to 255) * 1 0 : pwm2 off (pwm_auto_pwm[1][0], hard-wired to 0) * 1 1 : pwm2 low speed duty cycle (pwm_auto_pwm[1][1]) * 1 2 : pwm2 high speed duty cycle (pwm_auto_pwm[1][2]) * 1 3 : pwm2 full speed (pwm_auto_pwm[1][3], hard-wired to 255)*/static ssize_t show_pwm_auto_point_pwm(struct device *dev, struct device_attribute *attr, char *buf){ struct vt1211_data *data = vt1211_update_device(dev); struct sensor_device_attribute_2 *sensor_attr_2 = to_sensor_dev_attr_2(attr); int ix = sensor_attr_2->index; int ap = sensor_attr_2->nr; return sprintf(buf, "%d\n", data->pwm_auto_pwm[ix][ap]);}static ssize_t set_pwm_auto_point_pwm(struct device *dev, struct device_attribute *attr, const char *buf, size_t count){ struct vt1211_data *data = dev_get_drvdata(dev); struct sensor_device_attribute_2 *sensor_attr_2 = to_sensor_dev_attr_2(attr); int ix = sensor_attr_2->index; int ap = sensor_attr_2->nr; long val = simple_strtol(buf, NULL, 10); if ((val < 0) || (val > 255)) { dev_err(dev, "pwm value %ld is out of range. " "Choose a value between 0 and 255.\n" , val); return -EINVAL; } mutex_lock(&data->update_lock); data->pwm_auto_pwm[ix][ap] = val; vt1211_write8(data, VT1211_REG_PWM_AUTO_PWM(ix, ap), data->pwm_auto_pwm[ix][ap]); mutex_unlock(&data->update_lock); return count;}/* --------------------------------------------------------------------- * Miscellaneous sysfs interfaces (VRM, VID, name, and (legacy) alarms) * --------------------------------------------------------------------- */static ssize_t show_vrm(struct device *dev, struct device_attribute *attr, char *buf){ struct vt1211_data *data = dev_get_drvdata(dev); return sprintf(buf, "%d\n", data->vrm);}static ssize_t set_vrm(struct device *dev, struct device_attribute *attr, const char *buf, size_t count){ struct vt1211_data *data = dev_get_drvdata(dev); long val = simple_strtol(buf, NULL, 10); data->vrm = val; return count;}static ssize_t show_vid(struct device *dev, struct device_attribute *attr, char *buf){ struct vt1211_data *data = dev_get_drvdata(dev); return sprintf(buf, "%d\n", vid_from_reg(data->vid, data->vrm));}static ssize_t show_name(struct device *dev, struct device_attribute *attr, char *buf){ struct vt1211_data *data = dev_get_drvdata(dev); return sprintf(buf, "%s\n", data->name);}static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, char *buf){ struct vt1211_data *data = vt1211_update_device(dev); return sprintf(buf, "%d\n", data->alarms);}/* --------------------------------------------------------------------- * Device attribute structs * --------------------------------------------------------------------- */#define SENSOR_ATTR_IN_INPUT(ix) \ SENSOR_ATTR_2(in##ix##_input, S_IRUGO, \ show_in, NULL, SHOW_IN_INPUT, ix)static struct sensor_device_attribute_2 vt1211_sysfs_in_input[] = { SENSOR_ATTR_IN_INPUT(0), SENSOR_ATTR_IN_INPUT(1), SENSOR_ATTR_IN_INPUT(2), SENSOR_ATTR_IN_INPUT(3), SENSOR_ATTR_IN_INPUT(4), SENSOR_ATTR_IN_INPUT(5),};#define SENSOR_ATTR_IN_MIN(ix) \ SENSOR_ATTR_2(in##ix##_min, S_IRUGO | S_IWUSR, \ show_in, set_in, SHOW_SET_IN_MIN, ix)static struct sensor_device_attribute_2 vt1211_sysfs_in_min[] = { SENSOR_ATTR_IN_MIN(0), SENSOR_ATTR_IN_MIN(1), SENSOR_ATTR_IN_MIN(2), SENSOR_ATTR_IN_MIN(3), SENSOR_ATTR_IN_MIN(4), SENSOR_ATTR_IN_MIN(5),};#define SENSOR_ATTR_IN_MAX(ix) \ SENSOR_ATTR_2(in##ix##_max, S_IRUGO | S_IWUSR, \ show_in, set_in, SHOW_SET_IN_MAX, ix)static struct sensor_device_attribute_2 vt1211_sysfs_in_max[] = { SENSOR_ATTR_IN_MAX(0), SENSOR_ATTR_IN_MAX(1), SENSOR_ATTR_IN_MAX(2), SENSOR_ATTR_IN_MAX(3), SENSOR_ATTR_IN_MAX(4), SENSOR_ATTR_IN_MAX(5),};#define SENSOR_ATTR_IN_ALARM(ix) \ SENSOR_ATTR_2(in##ix##_alarm, S_IRUGO, \ show_in, NULL, SHOW_IN_ALARM, ix)static struct sensor_device_attribute_2 vt1211_sysfs_in_alarm[] = { SENSOR_ATTR_IN_ALARM(0), SENSOR_ATTR_IN_ALARM(1), SENSOR_ATTR_IN_ALARM(2), SENSOR_ATTR_IN_ALARM(3), SENSOR_ATTR_IN_ALARM(4), SENSOR_ATTR_IN_ALARM(5),};#define SENSOR_ATTR_TEMP_INPUT(ix) \
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?