lm93.c
来自「linux 内核源代码」· C语言 代码 · 共 2,063 行 · 第 1/5 页
C
2,063 行
lm93_write_word(client,LM93_REG_FAN_MIN(nr),data->block8[nr]); mutex_unlock(&data->update_lock); return count;}static SENSOR_DEVICE_ATTR(fan1_min, S_IWUSR | S_IRUGO, show_fan_min, store_fan_min, 0);static SENSOR_DEVICE_ATTR(fan2_min, S_IWUSR | S_IRUGO, show_fan_min, store_fan_min, 1);static SENSOR_DEVICE_ATTR(fan3_min, S_IWUSR | S_IRUGO, show_fan_min, store_fan_min, 2);static SENSOR_DEVICE_ATTR(fan4_min, S_IWUSR | S_IRUGO, show_fan_min, store_fan_min, 3);/* some tedious bit-twiddling here to deal with the register format: data->sf_tach_to_pwm: (tach to pwm mapping bits) bit | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 T4:P2 T4:P1 T3:P2 T3:P1 T2:P2 T2:P1 T1:P2 T1:P1 data->sfc2: (enable bits) bit | 3 | 2 | 1 | 0 T4 T3 T2 T1*/static ssize_t show_fan_smart_tach(struct device *dev, struct device_attribute *attr, char *buf){ int nr = (to_sensor_dev_attr(attr))->index; struct lm93_data *data = lm93_update_device(dev); long rc = 0; int mapping; /* extract the relevant mapping */ mapping = (data->sf_tach_to_pwm >> (nr * 2)) & 0x03; /* if there's a mapping and it's enabled */ if (mapping && ((data->sfc2 >> nr) & 0x01)) rc = mapping; return sprintf(buf,"%ld\n",rc);}/* helper function - must grab data->update_lock before calling fan is 0-3, indicating fan1-fan4 */static void lm93_write_fan_smart_tach(struct i2c_client *client, struct lm93_data *data, int fan, long value){ /* insert the new mapping and write it out */ data->sf_tach_to_pwm = lm93_read_byte(client, LM93_REG_SF_TACH_TO_PWM); data->sf_tach_to_pwm &= ~(0x3 << fan * 2); data->sf_tach_to_pwm |= value << fan * 2; lm93_write_byte(client, LM93_REG_SF_TACH_TO_PWM, data->sf_tach_to_pwm); /* insert the enable bit and write it out */ data->sfc2 = lm93_read_byte(client, LM93_REG_SFC2); if (value) data->sfc2 |= 1 << fan; else data->sfc2 &= ~(1 << fan); lm93_write_byte(client, LM93_REG_SFC2, data->sfc2);}static ssize_t store_fan_smart_tach(struct device *dev, struct device_attribute *attr, const char *buf, size_t count){ int nr = (to_sensor_dev_attr(attr))->index; struct i2c_client *client = to_i2c_client(dev); struct lm93_data *data = i2c_get_clientdata(client); u32 val = simple_strtoul(buf, NULL, 10); mutex_lock(&data->update_lock); /* sanity test, ignore the write otherwise */ if (0 <= val && val <= 2) { /* can't enable if pwm freq is 22.5KHz */ if (val) { u8 ctl4 = lm93_read_byte(client, LM93_REG_PWM_CTL(val-1,LM93_PWM_CTL4)); if ((ctl4 & 0x07) == 0) val = 0; } lm93_write_fan_smart_tach(client, data, nr, val); } mutex_unlock(&data->update_lock); return count;}static SENSOR_DEVICE_ATTR(fan1_smart_tach, S_IWUSR | S_IRUGO, show_fan_smart_tach, store_fan_smart_tach, 0);static SENSOR_DEVICE_ATTR(fan2_smart_tach, S_IWUSR | S_IRUGO, show_fan_smart_tach, store_fan_smart_tach, 1);static SENSOR_DEVICE_ATTR(fan3_smart_tach, S_IWUSR | S_IRUGO, show_fan_smart_tach, store_fan_smart_tach, 2);static SENSOR_DEVICE_ATTR(fan4_smart_tach, S_IWUSR | S_IRUGO, show_fan_smart_tach, store_fan_smart_tach, 3);static ssize_t show_pwm(struct device *dev, struct device_attribute *attr, char *buf){ int nr = (to_sensor_dev_attr(attr))->index; struct lm93_data *data = lm93_update_device(dev); u8 ctl2, ctl4; long rc; ctl2 = data->block9[nr][LM93_PWM_CTL2]; ctl4 = data->block9[nr][LM93_PWM_CTL4]; if (ctl2 & 0x01) /* show user commanded value if enabled */ rc = data->pwm_override[nr]; else /* show present h/w value if manual pwm disabled */ rc = LM93_PWM_FROM_REG(ctl2 >> 4, (ctl4 & 0x07) ? LM93_PWM_MAP_LO_FREQ : LM93_PWM_MAP_HI_FREQ); return sprintf(buf,"%ld\n",rc);}static ssize_t store_pwm(struct device *dev, struct device_attribute *attr, const char *buf, size_t count){ int nr = (to_sensor_dev_attr(attr))->index; struct i2c_client *client = to_i2c_client(dev); struct lm93_data *data = i2c_get_clientdata(client); u32 val = simple_strtoul(buf, NULL, 10); u8 ctl2, ctl4; mutex_lock(&data->update_lock); ctl2 = lm93_read_byte(client,LM93_REG_PWM_CTL(nr,LM93_PWM_CTL2)); ctl4 = lm93_read_byte(client, LM93_REG_PWM_CTL(nr,LM93_PWM_CTL4)); ctl2 = (ctl2 & 0x0f) | LM93_PWM_TO_REG(val,(ctl4 & 0x07) ? LM93_PWM_MAP_LO_FREQ : LM93_PWM_MAP_HI_FREQ) << 4; /* save user commanded value */ data->pwm_override[nr] = LM93_PWM_FROM_REG(ctl2 >> 4, (ctl4 & 0x07) ? LM93_PWM_MAP_LO_FREQ : LM93_PWM_MAP_HI_FREQ); lm93_write_byte(client,LM93_REG_PWM_CTL(nr,LM93_PWM_CTL2),ctl2); mutex_unlock(&data->update_lock); return count;}static SENSOR_DEVICE_ATTR(pwm1, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 0);static SENSOR_DEVICE_ATTR(pwm2, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 1);static ssize_t show_pwm_enable(struct device *dev, struct device_attribute *attr, char *buf){ int nr = (to_sensor_dev_attr(attr))->index; struct lm93_data *data = lm93_update_device(dev); u8 ctl2; long rc; ctl2 = data->block9[nr][LM93_PWM_CTL2]; if (ctl2 & 0x01) /* manual override enabled ? */ rc = ((ctl2 & 0xF0) == 0xF0) ? 0 : 1; else rc = 2; return sprintf(buf,"%ld\n",rc);}static ssize_t store_pwm_enable(struct device *dev, struct device_attribute *attr, const char *buf, size_t count){ int nr = (to_sensor_dev_attr(attr))->index; struct i2c_client *client = to_i2c_client(dev); struct lm93_data *data = i2c_get_clientdata(client); u32 val = simple_strtoul(buf, NULL, 10); u8 ctl2; mutex_lock(&data->update_lock); ctl2 = lm93_read_byte(client,LM93_REG_PWM_CTL(nr,LM93_PWM_CTL2)); switch (val) { case 0: ctl2 |= 0xF1; /* enable manual override, set PWM to max */ break; case 1: ctl2 |= 0x01; /* enable manual override */ break; case 2: ctl2 &= ~0x01; /* disable manual override */ break; default: mutex_unlock(&data->update_lock); return -EINVAL; } lm93_write_byte(client,LM93_REG_PWM_CTL(nr,LM93_PWM_CTL2),ctl2); mutex_unlock(&data->update_lock); return count;}static SENSOR_DEVICE_ATTR(pwm1_enable, S_IWUSR | S_IRUGO, show_pwm_enable, store_pwm_enable, 0);static SENSOR_DEVICE_ATTR(pwm2_enable, S_IWUSR | S_IRUGO, show_pwm_enable, store_pwm_enable, 1);static ssize_t show_pwm_freq(struct device *dev, struct device_attribute *attr, char *buf){ int nr = (to_sensor_dev_attr(attr))->index; struct lm93_data *data = lm93_update_device(dev); u8 ctl4; ctl4 = data->block9[nr][LM93_PWM_CTL4]; return sprintf(buf,"%d\n",LM93_PWM_FREQ_FROM_REG(ctl4));}/* helper function - must grab data->update_lock before calling pwm is 0-1, indicating pwm1-pwm2 this disables smart tach for all tach channels bound to the given pwm */static void lm93_disable_fan_smart_tach(struct i2c_client *client, struct lm93_data *data, int pwm){ int mapping = lm93_read_byte(client, LM93_REG_SF_TACH_TO_PWM); int mask; /* collapse the mapping into a mask of enable bits */ mapping = (mapping >> pwm) & 0x55; mask = mapping & 0x01; mask |= (mapping & 0x04) >> 1; mask |= (mapping & 0x10) >> 2; mask |= (mapping & 0x40) >> 3; /* disable smart tach according to the mask */ data->sfc2 = lm93_read_byte(client, LM93_REG_SFC2); data->sfc2 &= ~mask; lm93_write_byte(client, LM93_REG_SFC2, data->sfc2);}static ssize_t store_pwm_freq(struct device *dev, struct device_attribute *attr, const char *buf, size_t count){ int nr = (to_sensor_dev_attr(attr))->index; struct i2c_client *client = to_i2c_client(dev); struct lm93_data *data = i2c_get_clientdata(client); u32 val = simple_strtoul(buf, NULL, 10); u8 ctl4; mutex_lock(&data->update_lock); ctl4 = lm93_read_byte(client,LM93_REG_PWM_CTL(nr,LM93_PWM_CTL4)); ctl4 = (ctl4 & 0xf8) | LM93_PWM_FREQ_TO_REG(val); data->block9[nr][LM93_PWM_CTL4] = ctl4; /* ctl4 == 0 -> 22.5KHz -> disable smart tach */ if (!ctl4) lm93_disable_fan_smart_tach(client, data, nr); lm93_write_byte(client, LM93_REG_PWM_CTL(nr,LM93_PWM_CTL4), ctl4); mutex_unlock(&data->update_lock); return count;}static SENSOR_DEVICE_ATTR(pwm1_freq, S_IWUSR | S_IRUGO, show_pwm_freq, store_pwm_freq, 0);static SENSOR_DEVICE_ATTR(pwm2_freq, S_IWUSR | S_IRUGO, show_pwm_freq, store_pwm_freq, 1);static ssize_t show_pwm_auto_channels(struct device *dev, struct device_attribute *attr, char *buf){ int nr = (to_sensor_dev_attr(attr))->index; struct lm93_data *data = lm93_update_device(dev); return sprintf(buf,"%d\n",data->block9[nr][LM93_PWM_CTL1]);}static ssize_t store_pwm_auto_channels(struct device *dev, struct device_attribute *attr, const char *buf, size_t count){ int nr = (to_sensor_dev_attr(attr))->index; struct i2c_client *client = to_i2c_client(dev); struct lm93_data *data = i2c_get_clientdata(client); u32 val = simple_strtoul(buf, NULL, 10); mutex_lock(&data->update_lock); data->block9[nr][LM93_PWM_CTL1] = SENSORS_LIMIT(val, 0, 255); lm93_write_byte(client, LM93_REG_PWM_CTL(nr,LM93_PWM_CTL1), data->block9[nr][LM93_PWM_CTL1]); mutex_unlock(&data->update_lock); return count;}static SENSOR_DEVICE_ATTR(pwm1_auto_channels, S_IWUSR | S_IRUGO, show_pwm_auto_channels, store_pwm_auto_channels, 0);static SENSOR_DEVICE_ATTR(pwm2_auto_channels, S_IWUSR | S_IRUGO, show_pwm_auto_channels, store_pwm_auto_channels, 1);static ssize_t show_pwm_auto_spinup_min(struct device *dev, struct device_attribute *attr,char *buf){ int nr = (to_sensor_dev_attr(attr))->index; struct lm93_data *data = lm93_update_device(dev); u8 ctl3, ctl4; ctl3 = data->block9[nr][LM93_PWM_CTL3]; ctl4 = data->block9[nr][LM93_PWM_CTL4]; return sprintf(buf,"%d\n", LM93_PWM_FROM_REG(ctl3 & 0x0f, (ctl4 & 0x07) ? LM93_PWM_MAP_LO_FREQ : LM93_PWM_MAP_HI_FREQ));}static ssize_t store_pwm_auto_spinup_min(struct device *dev, struct device_attribute *attr, const char *buf, size_t count){ int nr = (to_sensor_dev_attr(attr))->index; struct i2c_client *client = to_i2c_client(dev); struct lm93_data *data = i2c_get_clientdata(client); u32 val = simple_strtoul(buf, NULL, 10); u8 ctl3, ctl4; mutex_lock(&data->update_lock); ctl3 = lm93_read_byte(client,LM93_REG_PWM_CTL(nr, LM93_PWM_CTL3)); ctl4 = lm93_read_byte(client,LM93_REG_PWM_CTL(nr, LM93_PWM_CTL4)); ctl3 = (ctl3 & 0xf0) | LM93_PWM_TO_REG(val, (ctl4 & 0x07) ? LM93_PWM_MAP_LO_FREQ : LM93_PWM_MAP_HI_FREQ); data->block9[nr][LM93_PWM_CTL3] = ctl3; lm93_write_byte(client,LM93_REG_PWM_CTL(nr, LM93_PWM_CTL3), ctl3); mutex_unlock(&data->update_lock); return count;}static SENSOR_DEVICE_ATTR(pwm1_auto_spinup_min, S_IWUSR | S_IRUGO, show_pwm_auto_spinup_min, store_pwm_auto_spinup_min, 0);static SENSOR_DEVICE_ATTR(pwm2_auto_spinup_min, S_IWUSR | S_IRUGO, show_pwm_auto_spinup_min, store_pwm_auto_spinup_min, 1);static ssize_t show_pwm_auto_spinup_time(struct device *dev, struct device_attribute *attr, char *buf){ int nr = (to_sensor_dev_attr(attr))->index; struct lm93_data *data = lm93_update_device(dev); return sprintf(buf,"%d\n",LM93_SPINUP_TIME_FROM_REG( data->block9[nr][LM93_PWM_CTL3]));}static ssize_t store_pwm_auto_spinup_time(struct device *dev, struct device_attribute *attr, const char *buf, size_t count){ int nr = (to_sensor_dev_attr(attr))->index; struct i2c_client *client = to_i2c_client(dev); struct lm93_data *data = i2c_get_clientdata(client); u32 val = simple_strtoul(buf, NULL, 10); u8 ctl3; mutex_lock(&data->update_lock); ctl3 = lm93_read_byte(client,LM93_REG_PWM_CTL(nr, LM93_PWM_CTL3)); ctl3 = (ctl3 & 0x1f) | (LM93_SPINUP_TIME_TO_REG(val) << 5 & 0xe0); data->block9[nr][LM93_PWM_CTL3] = ctl3; lm93_write_byte(client,LM93_REG_PWM_CTL(nr, LM93_PWM_CTL3), ctl3); mutex_unlock(&data->update_lock); return count;}static SENSOR_DEVICE_ATTR(pwm1_auto_spinup_time, S_IWUSR | S_IRUGO, show_pwm_auto_spinup_time, store_pwm_auto_spinup_time, 0);static SENSOR_DEVICE_ATTR(pwm2_auto_spinup_time, S_IWUSR | S_IRUGO, show_pwm_auto_spinup_time, store_pwm_auto_spinup_time, 1);static ssize_t show_pwm_auto_prochot_ramp(struct device *dev, struct device_attribute *attr, char *buf){ struct lm93_data *data = lm93_update_device(dev); return sprintf(buf,"%d\n", LM93_RAMP_FROM_REG(data->pwm_ramp_ctl >> 4 & 0x0f));}static ssize_t store_pwm_auto_prochot_ramp(struct device *dev, struct device_attribute *attr, const char *buf, size_t count){ struct i2c_client *client = to_i2c_client(dev); struct lm93_data *data = i2c_get_clientdata(client); u32 val = simple_strtoul(buf, NULL, 10); u8 ramp; mutex_lock(&data->update_lock); ramp = lm93_read_byte(client, LM93_REG_PWM_RAMP_CTL); ramp = (ramp & 0x0f) | (LM93_RAMP_TO_REG(val) << 4 & 0xf0); lm93_write_byte(client, LM93_REG_PWM_RAMP_CTL, ramp); mutex_unlock(&data->update_lock); return count;}static DEVICE_ATTR(pwm_auto_prochot_ramp, S_IRUGO | S_IWUSR, show_pwm_auto_prochot_ramp, store_pwm_auto_prochot_ramp);static ssize_t show_pwm_auto_vrdhot_ramp(struct device *dev, struct device_attribute *attr, char *buf){ struct lm93_data *data = lm93_update_device(dev); return sprintf(buf,"%d\n", LM93_RAMP_FROM_REG(data->pwm_ramp_ctl & 0x0f));}static ssize_t store_pwm_auto_vrdhot_ramp(struct device *dev, struct device_attribute *attr, const char *buf, size_t count){ struct i2c_client *client = to_i2c_client(dev); struct lm93_data *data = i2c_get_clientdata(client); u32 val = simple_strtoul(buf, NULL, 10); u8 ramp; mutex_lock(&data->update_lock); ramp = lm93_read_byte(client, LM93_REG_PWM_RAMP_CTL); ramp = (ramp & 0xf0) | (LM9
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?