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 + -
显示快捷键?