⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dme1737.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	struct dme1737_data *data = dev_get_drvdata(dev);	struct i2c_client *client = &data->client;	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);	mutex_lock(&data->update_lock);	switch (fn) {	case SYS_ZONE_AUTO_POINT1_TEMP_HYST:		/* Refresh the cache */		data->zone_low[ix] = dme1737_read(client,						  DME1737_REG_ZONE_LOW(ix));		/* Modify the temp hyst value */		data->zone_hyst[ix == 2] = TEMP_HYST_TO_REG(					TEMP_FROM_REG(data->zone_low[ix], 8) -					val, ix, dme1737_read(client,					DME1737_REG_ZONE_HYST(ix == 2)));		dme1737_write(client, DME1737_REG_ZONE_HYST(ix == 2),			      data->zone_hyst[ix == 2]);		break;	case SYS_ZONE_AUTO_POINT1_TEMP:		data->zone_low[ix] = TEMP_TO_REG(val);		dme1737_write(client, DME1737_REG_ZONE_LOW(ix),			      data->zone_low[ix]);		break;	case SYS_ZONE_AUTO_POINT2_TEMP:		/* Refresh the cache */		data->zone_low[ix] = dme1737_read(client,						  DME1737_REG_ZONE_LOW(ix));		/* Modify the temp range value (which is stored in the upper		 * nibble of the pwm_freq register) */		data->pwm_freq[ix] = TEMP_RANGE_TO_REG(val -					TEMP_FROM_REG(data->zone_low[ix], 8),					dme1737_read(client,					DME1737_REG_PWM_FREQ(ix)));		dme1737_write(client, DME1737_REG_PWM_FREQ(ix),			      data->pwm_freq[ix]);		break;	case SYS_ZONE_AUTO_POINT3_TEMP:		data->zone_abs[ix] = TEMP_TO_REG(val);		dme1737_write(client, DME1737_REG_ZONE_ABS(ix),			      data->zone_abs[ix]);		break;	default:		dev_dbg(dev, "Unknown function %d.\n", fn);	}	mutex_unlock(&data->update_lock);	return count;}/* --------------------------------------------------------------------- * Fan sysfs attributes * ix = [0-5] * --------------------------------------------------------------------- */#define SYS_FAN_INPUT	0#define SYS_FAN_MIN	1#define SYS_FAN_MAX	2#define SYS_FAN_ALARM	3#define SYS_FAN_TYPE	4static ssize_t show_fan(struct device *dev, struct device_attribute *attr,			char *buf){	struct dme1737_data *data = dme1737_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 SYS_FAN_INPUT:		res = FAN_FROM_REG(data->fan[ix],				   ix < 4 ? 0 :				   FAN_TPC_FROM_REG(data->fan_opt[ix]));		break;	case SYS_FAN_MIN:		res = FAN_FROM_REG(data->fan_min[ix],				   ix < 4 ? 0 :				   FAN_TPC_FROM_REG(data->fan_opt[ix]));		break;	case SYS_FAN_MAX:		/* only valid for fan[5-6] */		res = FAN_MAX_FROM_REG(data->fan_max[ix - 4]);		break;	case SYS_FAN_ALARM:		res = (data->alarms >> DME1737_BIT_ALARM_FAN[ix]) & 0x01;		break;	case SYS_FAN_TYPE:		/* only valid for fan[1-4] */		res = FAN_TYPE_FROM_REG(data->fan_opt[ix]);		break;	default:		res = 0;		dev_dbg(dev, "Unknown function %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 dme1737_data *data = dev_get_drvdata(dev);	struct i2c_client *client = &data->client;	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);	mutex_lock(&data->update_lock);	switch (fn) {	case SYS_FAN_MIN:		if (ix < 4) {			data->fan_min[ix] = FAN_TO_REG(val, 0);		} else {			/* Refresh the cache */			data->fan_opt[ix] = dme1737_read(client,						DME1737_REG_FAN_OPT(ix));			/* Modify the fan min value */			data->fan_min[ix] = FAN_TO_REG(val,					FAN_TPC_FROM_REG(data->fan_opt[ix]));		}		dme1737_write(client, DME1737_REG_FAN_MIN(ix),			      data->fan_min[ix] & 0xff);		dme1737_write(client, DME1737_REG_FAN_MIN(ix) + 1,			      data->fan_min[ix] >> 8);		break;	case SYS_FAN_MAX:		/* Only valid for fan[5-6] */		data->fan_max[ix - 4] = FAN_MAX_TO_REG(val);		dme1737_write(client, DME1737_REG_FAN_MAX(ix),			      data->fan_max[ix - 4]);		break;	case SYS_FAN_TYPE:		/* Only valid for fan[1-4] */		if (!(val == 1 || val == 2 || val == 4)) {			count = -EINVAL;			dev_warn(dev, "Fan type value %ld not "				 "supported. Choose one of 1, 2, or 4.\n",				 val);			goto exit;		}		data->fan_opt[ix] = FAN_TYPE_TO_REG(val, dme1737_read(client,					DME1737_REG_FAN_OPT(ix)));		dme1737_write(client, DME1737_REG_FAN_OPT(ix),			      data->fan_opt[ix]);		break;	default:		dev_dbg(dev, "Unknown function %d.\n", fn);	}exit:	mutex_unlock(&data->update_lock);	return count;}/* --------------------------------------------------------------------- * PWM sysfs attributes * ix = [0-4] * --------------------------------------------------------------------- */#define SYS_PWM				0#define SYS_PWM_FREQ			1#define SYS_PWM_ENABLE			2#define SYS_PWM_RAMP_RATE		3#define SYS_PWM_AUTO_CHANNELS_ZONE	4#define SYS_PWM_AUTO_PWM_MIN		5#define SYS_PWM_AUTO_POINT1_PWM		6#define SYS_PWM_AUTO_POINT2_PWM		7static ssize_t show_pwm(struct device *dev, struct device_attribute *attr,			char *buf){	struct dme1737_data *data = dme1737_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 SYS_PWM:		if (PWM_EN_FROM_REG(data->pwm_config[ix]) == 0) {			res = 255;		} else {			res = data->pwm[ix];		}		break;	case SYS_PWM_FREQ:		res = PWM_FREQ_FROM_REG(data->pwm_freq[ix]);		break;	case SYS_PWM_ENABLE:		if (ix > 3) {			res = 1; /* pwm[5-6] hard-wired to manual mode */		} else {			res = PWM_EN_FROM_REG(data->pwm_config[ix]);		}		break;	case SYS_PWM_RAMP_RATE:		/* Only valid for pwm[1-3] */		res = PWM_RR_FROM_REG(data->pwm_rr[ix > 0], ix);		break;	case SYS_PWM_AUTO_CHANNELS_ZONE:		/* Only valid for pwm[1-3] */		if (PWM_EN_FROM_REG(data->pwm_config[ix]) == 2) {			res = PWM_ACZ_FROM_REG(data->pwm_config[ix]);		} else {			res = data->pwm_acz[ix];		}		break;	case SYS_PWM_AUTO_PWM_MIN:		/* Only valid for pwm[1-3] */		if (PWM_OFF_FROM_REG(data->pwm_rr[0], ix)) {			res = data->pwm_min[ix];		} else {			res = 0;		}		break;	case SYS_PWM_AUTO_POINT1_PWM:		/* Only valid for pwm[1-3] */		res = data->pwm_min[ix];		break;	case SYS_PWM_AUTO_POINT2_PWM:		/* Only valid for pwm[1-3] */		res = 255; /* hard-wired */		break;	default:		res = 0;		dev_dbg(dev, "Unknown function %d.\n", fn);	}	return sprintf(buf, "%d\n", res);}static struct attribute *dme1737_attr_pwm[];static void dme1737_chmod_file(struct device*, struct attribute*, mode_t);static ssize_t set_pwm(struct device *dev, struct device_attribute *attr,		       const char *buf, size_t count){	struct dme1737_data *data = dev_get_drvdata(dev);	struct i2c_client *client = &data->client;	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);	mutex_lock(&data->update_lock);	switch (fn) {	case SYS_PWM:		data->pwm[ix] = SENSORS_LIMIT(val, 0, 255);		dme1737_write(client, DME1737_REG_PWM(ix), data->pwm[ix]);		break;	case SYS_PWM_FREQ:		data->pwm_freq[ix] = PWM_FREQ_TO_REG(val, dme1737_read(client,						DME1737_REG_PWM_FREQ(ix)));		dme1737_write(client, DME1737_REG_PWM_FREQ(ix),			      data->pwm_freq[ix]);		break;	case SYS_PWM_ENABLE:		/* Only valid for pwm[1-3] */		if (val < 0 || val > 2) {			count = -EINVAL;			dev_warn(dev, "PWM enable %ld not "				 "supported. Choose one of 0, 1, or 2.\n",				 val);			goto exit;		}		/* Refresh the cache */		data->pwm_config[ix] = dme1737_read(client,						DME1737_REG_PWM_CONFIG(ix));		if (val == PWM_EN_FROM_REG(data->pwm_config[ix])) {			/* Bail out if no change */			goto exit;		}		/* Do some housekeeping if we are currently in auto mode */		if (PWM_EN_FROM_REG(data->pwm_config[ix]) == 2) {			/* Save the current zone channel assignment */			data->pwm_acz[ix] = PWM_ACZ_FROM_REG(							data->pwm_config[ix]);			/* Save the current ramp rate state and disable it */			data->pwm_rr[ix > 0] = dme1737_read(client,						DME1737_REG_PWM_RR(ix > 0));			data->pwm_rr_en &= ~(1 << ix);			if (PWM_RR_EN_FROM_REG(data->pwm_rr[ix > 0], ix)) {				data->pwm_rr_en |= (1 << ix);				data->pwm_rr[ix > 0] = PWM_RR_EN_TO_REG(0, ix,							data->pwm_rr[ix > 0]);				dme1737_write(client,					      DME1737_REG_PWM_RR(ix > 0),					      data->pwm_rr[ix > 0]);			}		}		/* Set the new PWM mode */		switch (val) {		case 0:			/* Change permissions of pwm[ix] to read-only */			dme1737_chmod_file(dev, dme1737_attr_pwm[ix],					   S_IRUGO);			/* Turn fan fully on */			data->pwm_config[ix] = PWM_EN_TO_REG(0,							data->pwm_config[ix]);			dme1737_write(client, DME1737_REG_PWM_CONFIG(ix),				      data->pwm_config[ix]);			break;		case 1:			/* Turn on manual mode */			data->pwm_config[ix] = PWM_EN_TO_REG(1,							data->pwm_config[ix]);			dme1737_write(client, DME1737_REG_PWM_CONFIG(ix),				      data->pwm_config[ix]);			/* Change permissions of pwm[ix] to read-writeable */			dme1737_chmod_file(dev, dme1737_attr_pwm[ix],					   S_IRUGO | S_IWUSR);			break;		case 2:			/* Change permissions of pwm[ix] to read-only */			dme1737_chmod_file(dev, dme1737_attr_pwm[ix],					   S_IRUGO);			/* Turn on auto mode using the saved zone channel			 * assignment */			data->pwm_config[ix] = PWM_ACZ_TO_REG(							data->pwm_acz[ix],							data->pwm_config[ix]);			dme1737_write(client, DME1737_REG_PWM_CONFIG(ix),				      data->pwm_config[ix]);			/* Enable PWM ramp rate if previously enabled */			if (data->pwm_rr_en & (1 << ix)) {				data->pwm_rr[ix > 0] = PWM_RR_EN_TO_REG(1, ix,						dme1737_read(client,						DME1737_REG_PWM_RR(ix > 0)));				dme1737_write(client,					      DME1737_REG_PWM_RR(ix > 0),					      data->pwm_rr[ix > 0]);			}			break;		}		break;	case SYS_PWM_RAMP_RATE:		/* Only valid for pwm[1-3] */		/* Refresh the cache */		data->pwm_config[ix] = dme1737_read(client,						DME1737_REG_PWM_CONFIG(ix));		data->pwm_rr[ix > 0] = dme1737_read(client,						DME1737_REG_PWM_RR(ix > 0));		/* Set the ramp rate value */		if (val > 0) {			data->pwm_rr[ix > 0] = PWM_RR_TO_REG(val, ix,							data->pwm_rr[ix > 0]);		}		/* Enable/disable the feature only if the associated PWM		 * output is in automatic mode. */		if (PWM_EN_FROM_REG(data->pwm_config[ix]) == 2) {			data->pwm_rr[ix > 0] = PWM_RR_EN_TO_REG(val > 0, ix,							data->pwm_rr[ix > 0]);		}		dme1737_write(client, DME1737_REG_PWM_RR(ix > 0),			      data->pwm_rr[ix > 0]);		break;	case SYS_PWM_AUTO_CHANNELS_ZONE:		/* Only valid for pwm[1-3] */		if (!(val == 1 || val == 2 || val == 4 ||		      val == 6 || val == 7)) {			count = -EINVAL;			dev_warn(dev, "PWM auto channels zone %ld "				 "not supported. Choose one of 1, 2, 4, 6, "				 "or 7.\n", val);			goto exit;		}		/* Refresh the cache */		data->pwm_config[ix] = dme1737_read(client,						DME1737_REG_PWM_CONFIG(ix));		if (PWM_EN_FROM_REG(data->pwm_config[ix]) == 2) {			/* PWM is already in auto mode so update the temp			 * channel assignment */			data->pwm_config[ix] = PWM_ACZ_TO_REG(val,						data->pwm_config[ix]);			dme1737_write(client, DME1737_REG_PWM_CONFIG(ix),				      data->pwm_config[ix]);		} else {			/* PWM is not in auto mode so we save the temp			 * channel assignment for later use */			data->pwm_acz[ix] = val;		}		break;	case SYS_PWM_AUTO_PWM_MIN:		/* Only valid for pwm[1-3] */		/* Refresh the cache */		data->pwm_min[ix] = dme1737_read(client,						DME1737_REG_PWM_MIN(ix));		/* There are only 2 values supported for the auto_pwm_min		 * value: 0 or auto_point1_pwm. So if the temperature drops		 * below the auto_point1_temp_hyst value, the fan either turns		 * off or runs at auto_point1_pwm duty-cycle. */		if (val > ((data->pwm_min[ix] + 1) / 2)) {			data->pwm_rr[0] = PWM_OFF_TO_REG(1, ix,						dme1737_read(client,						DME1737_REG_PWM_RR(0)));		} else {			data->pwm_rr[0] = PWM_OFF_TO_REG(0, ix,						dme1737_read(client,						DME1737_REG_PWM_RR(0)));		}		dme1737_write(client, DME1737_REG_PWM_RR(0),			      data->pwm_rr[0]);		break;	case SYS_PWM_AUTO_POINT1_PWM:		/* Only valid for pwm[1-3] */		data->pwm_min[ix] = SENSORS_LIMIT(val, 0, 255);		dme1737_write(client, DME1737_REG_PWM_MIN(ix),			      data->pwm_min[ix]);		break;	default:		dev_dbg(dev, "Unknown function %d.\n", fn);	}exit:	mutex_unlock(&data->update_lock);	return count;}/* --------------------------------------------------------------------- * Miscellaneous sysfs attributes * --------------------------------------------------------------------- */static ssize_t show_vrm(struct device *dev, struct device_attribute *attr,			char *buf){	struct i2c_client *client = to_i2c_client(dev);	struct dme1737_data *data = i2c_get_clientdata(client);	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 dme1737_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,

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -