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

📄 w83791d.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
static ssize_t show_##reg(struct device *dev, struct device_attribute *attr, \				char *buf) \{ \	struct sensor_device_attribute *sensor_attr = \						to_sensor_dev_attr(attr); \	struct w83791d_data *data = w83791d_update_device(dev); \	int nr = sensor_attr->index; \	return sprintf(buf,"%d\n", \		FAN_FROM_REG(data->reg[nr], DIV_FROM_REG(data->fan_div[nr]))); \}show_fan_reg(fan);show_fan_reg(fan_min);static ssize_t store_fan_min(struct device *dev, struct device_attribute *attr,				const char *buf, size_t count){	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);	struct i2c_client *client = to_i2c_client(dev);	struct w83791d_data *data = i2c_get_clientdata(client);	unsigned long val = simple_strtoul(buf, NULL, 10);	int nr = sensor_attr->index;	mutex_lock(&data->update_lock);	data->fan_min[nr] = fan_to_reg(val, DIV_FROM_REG(data->fan_div[nr]));	w83791d_write(client, W83791D_REG_FAN_MIN[nr], data->fan_min[nr]);	mutex_unlock(&data->update_lock);	return count;}static ssize_t show_fan_div(struct device *dev, struct device_attribute *attr,				char *buf){	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);	int nr = sensor_attr->index;	struct w83791d_data *data = w83791d_update_device(dev);	return sprintf(buf, "%u\n", DIV_FROM_REG(data->fan_div[nr]));}/* Note: we save and restore the fan minimum here, because its value is   determined in part by the fan divisor.  This follows the principle of   least suprise; the user doesn't expect the fan minimum to change just   because the divisor changed. */static ssize_t store_fan_div(struct device *dev, struct device_attribute *attr,				const char *buf, size_t count){	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);	struct i2c_client *client = to_i2c_client(dev);	struct w83791d_data *data = i2c_get_clientdata(client);	int nr = sensor_attr->index;	unsigned long min;	u8 tmp_fan_div;	u8 fan_div_reg;	int indx = 0;	u8 keep_mask = 0;	u8 new_shift = 0;	/* Save fan_min */	min = FAN_FROM_REG(data->fan_min[nr], DIV_FROM_REG(data->fan_div[nr]));	mutex_lock(&data->update_lock);	data->fan_div[nr] = div_to_reg(nr, simple_strtoul(buf, NULL, 10));	switch (nr) {	case 0:		indx = 0;		keep_mask = 0xcf;		new_shift = 4;		break;	case 1:		indx = 0;		keep_mask = 0x3f;		new_shift = 6;		break;	case 2:		indx = 1;		keep_mask = 0x3f;		new_shift = 6;		break;	case 3:		indx = 2;		keep_mask = 0xf8;		new_shift = 0;		break;	case 4:		indx = 2;		keep_mask = 0x8f;		new_shift = 4;		break;#ifdef DEBUG	default:		dev_warn(dev, "store_fan_div: Unexpected nr seen: %d\n", nr);		count = -EINVAL;		goto err_exit;#endif	}	fan_div_reg = w83791d_read(client, W83791D_REG_FAN_DIV[indx])			& keep_mask;	tmp_fan_div = (data->fan_div[nr] << new_shift) & ~keep_mask;	w83791d_write(client, W83791D_REG_FAN_DIV[indx],				fan_div_reg | tmp_fan_div);	/* Restore fan_min */	data->fan_min[nr] = fan_to_reg(min, DIV_FROM_REG(data->fan_div[nr]));	w83791d_write(client, W83791D_REG_FAN_MIN[nr], data->fan_min[nr]);#ifdef DEBUGerr_exit:#endif	mutex_unlock(&data->update_lock);	return count;}static struct sensor_device_attribute sda_fan_input[] = {	SENSOR_ATTR(fan1_input, S_IRUGO, show_fan, NULL, 0),	SENSOR_ATTR(fan2_input, S_IRUGO, show_fan, NULL, 1),	SENSOR_ATTR(fan3_input, S_IRUGO, show_fan, NULL, 2),	SENSOR_ATTR(fan4_input, S_IRUGO, show_fan, NULL, 3),	SENSOR_ATTR(fan5_input, S_IRUGO, show_fan, NULL, 4),};static struct sensor_device_attribute sda_fan_min[] = {	SENSOR_ATTR(fan1_min, S_IWUSR | S_IRUGO,			show_fan_min, store_fan_min, 0),	SENSOR_ATTR(fan2_min, S_IWUSR | S_IRUGO,			show_fan_min, store_fan_min, 1),	SENSOR_ATTR(fan3_min, S_IWUSR | S_IRUGO,			show_fan_min, store_fan_min, 2),	SENSOR_ATTR(fan4_min, S_IWUSR | S_IRUGO,			show_fan_min, store_fan_min, 3),	SENSOR_ATTR(fan5_min, S_IWUSR | S_IRUGO,			show_fan_min, store_fan_min, 4),};static struct sensor_device_attribute sda_fan_div[] = {	SENSOR_ATTR(fan1_div, S_IWUSR | S_IRUGO,			show_fan_div, store_fan_div, 0),	SENSOR_ATTR(fan2_div, S_IWUSR | S_IRUGO,			show_fan_div, store_fan_div, 1),	SENSOR_ATTR(fan3_div, S_IWUSR | S_IRUGO,			show_fan_div, store_fan_div, 2),	SENSOR_ATTR(fan4_div, S_IWUSR | S_IRUGO,			show_fan_div, store_fan_div, 3),	SENSOR_ATTR(fan5_div, S_IWUSR | S_IRUGO,			show_fan_div, store_fan_div, 4),};static struct sensor_device_attribute sda_fan_beep[] = {	SENSOR_ATTR(fan1_beep, S_IWUSR | S_IRUGO, show_beep, store_beep, 6),	SENSOR_ATTR(fan2_beep, S_IWUSR | S_IRUGO, show_beep, store_beep, 7),	SENSOR_ATTR(fan3_beep, S_IWUSR | S_IRUGO, show_beep, store_beep, 11),	SENSOR_ATTR(fan4_beep, S_IWUSR | S_IRUGO, show_beep, store_beep, 21),	SENSOR_ATTR(fan5_beep, S_IWUSR | S_IRUGO, show_beep, store_beep, 22),};static struct sensor_device_attribute sda_fan_alarm[] = {	SENSOR_ATTR(fan1_alarm, S_IRUGO, show_alarm, NULL, 6),	SENSOR_ATTR(fan2_alarm, S_IRUGO, show_alarm, NULL, 7),	SENSOR_ATTR(fan3_alarm, S_IRUGO, show_alarm, NULL, 11),	SENSOR_ATTR(fan4_alarm, S_IRUGO, show_alarm, NULL, 21),	SENSOR_ATTR(fan5_alarm, S_IRUGO, show_alarm, NULL, 22),};/* read/write the temperature1, includes measured value and limits */static ssize_t show_temp1(struct device *dev, struct device_attribute *devattr,				char *buf){	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);	struct w83791d_data *data = w83791d_update_device(dev);	return sprintf(buf, "%d\n", TEMP1_FROM_REG(data->temp1[attr->index]));}static ssize_t store_temp1(struct device *dev, struct device_attribute *devattr,				const char *buf, size_t count){	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);	struct i2c_client *client = to_i2c_client(dev);	struct w83791d_data *data = i2c_get_clientdata(client);	long val = simple_strtol(buf, NULL, 10);	int nr = attr->index;	mutex_lock(&data->update_lock);	data->temp1[nr] = TEMP1_TO_REG(val);	w83791d_write(client, W83791D_REG_TEMP1[nr], data->temp1[nr]);	mutex_unlock(&data->update_lock);	return count;}/* read/write temperature2-3, includes measured value and limits */static ssize_t show_temp23(struct device *dev, struct device_attribute *devattr,				char *buf){	struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr);	struct w83791d_data *data = w83791d_update_device(dev);	int nr = attr->nr;	int index = attr->index;	return sprintf(buf, "%d\n", TEMP23_FROM_REG(data->temp_add[nr][index]));}static ssize_t store_temp23(struct device *dev,				struct device_attribute *devattr,				const char *buf, size_t count){	struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr);	struct i2c_client *client = to_i2c_client(dev);	struct w83791d_data *data = i2c_get_clientdata(client);	long val = simple_strtol(buf, NULL, 10);	int nr = attr->nr;	int index = attr->index;	mutex_lock(&data->update_lock);	data->temp_add[nr][index] = TEMP23_TO_REG(val);	w83791d_write(client, W83791D_REG_TEMP_ADD[nr][index * 2],				data->temp_add[nr][index] >> 8);	w83791d_write(client, W83791D_REG_TEMP_ADD[nr][index * 2 + 1],				data->temp_add[nr][index] & 0x80);	mutex_unlock(&data->update_lock);	return count;}static struct sensor_device_attribute_2 sda_temp_input[] = {	SENSOR_ATTR_2(temp1_input, S_IRUGO, show_temp1, NULL, 0, 0),	SENSOR_ATTR_2(temp2_input, S_IRUGO, show_temp23, NULL, 0, 0),	SENSOR_ATTR_2(temp3_input, S_IRUGO, show_temp23, NULL, 1, 0),};static struct sensor_device_attribute_2 sda_temp_max[] = {	SENSOR_ATTR_2(temp1_max, S_IRUGO | S_IWUSR,			show_temp1, store_temp1, 0, 1),	SENSOR_ATTR_2(temp2_max, S_IRUGO | S_IWUSR,			show_temp23, store_temp23, 0, 1),	SENSOR_ATTR_2(temp3_max, S_IRUGO | S_IWUSR,			show_temp23, store_temp23, 1, 1),};static struct sensor_device_attribute_2 sda_temp_max_hyst[] = {	SENSOR_ATTR_2(temp1_max_hyst, S_IRUGO | S_IWUSR,			show_temp1, store_temp1, 0, 2),	SENSOR_ATTR_2(temp2_max_hyst, S_IRUGO | S_IWUSR,			show_temp23, store_temp23, 0, 2),	SENSOR_ATTR_2(temp3_max_hyst, S_IRUGO | S_IWUSR,			show_temp23, store_temp23, 1, 2),};/* Note: The bitmask for the beep enable/disable is different than   the bitmask for the alarm. */static struct sensor_device_attribute sda_temp_beep[] = {	SENSOR_ATTR(temp1_beep, S_IWUSR | S_IRUGO, show_beep, store_beep, 4),	SENSOR_ATTR(temp2_beep, S_IWUSR | S_IRUGO, show_beep, store_beep, 5),	SENSOR_ATTR(temp3_beep, S_IWUSR | S_IRUGO, show_beep, store_beep, 1),};static struct sensor_device_attribute sda_temp_alarm[] = {	SENSOR_ATTR(temp1_alarm, S_IRUGO, show_alarm, NULL, 4),	SENSOR_ATTR(temp2_alarm, S_IRUGO, show_alarm, NULL, 5),	SENSOR_ATTR(temp3_alarm, S_IRUGO, show_alarm, NULL, 13),};/* get reatime status of all sensors items: voltage, temp, fan */static ssize_t show_alarms_reg(struct device *dev,				struct device_attribute *attr, char *buf){	struct w83791d_data *data = w83791d_update_device(dev);	return sprintf(buf, "%u\n", data->alarms);}static DEVICE_ATTR(alarms, S_IRUGO, show_alarms_reg, NULL);/* Beep control */#define GLOBAL_BEEP_ENABLE_SHIFT	15#define GLOBAL_BEEP_ENABLE_MASK		(1 << GLOBAL_BEEP_ENABLE_SHIFT)static ssize_t show_beep_enable(struct device *dev,				struct device_attribute *attr, char *buf){	struct w83791d_data *data = w83791d_update_device(dev);	return sprintf(buf, "%d\n", data->beep_enable);}static ssize_t show_beep_mask(struct device *dev,				struct device_attribute *attr, char *buf){	struct w83791d_data *data = w83791d_update_device(dev);	return sprintf(buf, "%d\n", BEEP_MASK_FROM_REG(data->beep_mask));}static ssize_t store_beep_mask(struct device *dev,				struct device_attribute *attr,				const char *buf, size_t count){	struct i2c_client *client = to_i2c_client(dev);	struct w83791d_data *data = i2c_get_clientdata(client);	long val = simple_strtol(buf, NULL, 10);	int i;	mutex_lock(&data->update_lock);	/* The beep_enable state overrides any enabling request from	   the masks */	data->beep_mask = BEEP_MASK_TO_REG(val) & ~GLOBAL_BEEP_ENABLE_MASK;	data->beep_mask |= (data->beep_enable << GLOBAL_BEEP_ENABLE_SHIFT);	val = data->beep_mask;	for (i = 0; i < 3; i++) {		w83791d_write(client, W83791D_REG_BEEP_CTRL[i], (val & 0xff));		val >>= 8;	}	mutex_unlock(&data->update_lock);	return count;}static ssize_t store_beep_enable(struct device *dev,				struct device_attribute *attr,				const char *buf, size_t count){	struct i2c_client *client = to_i2c_client(dev);	struct w83791d_data *data = i2c_get_clientdata(client);	long val = simple_strtol(buf, NULL, 10);	mutex_lock(&data->update_lock);	data->beep_enable = val ? 1 : 0;	/* Keep the full mask value in sync with the current enable */	data->beep_mask &= ~GLOBAL_BEEP_ENABLE_MASK;	data->beep_mask |= (data->beep_enable << GLOBAL_BEEP_ENABLE_SHIFT);	/* The global control is in the second beep control register	   so only need to update that register */	val = (data->beep_mask >> 8) & 0xff;	w83791d_write(client, W83791D_REG_BEEP_CTRL[1], val);	mutex_unlock(&data->update_lock);	return count;}static struct sensor_device_attribute sda_beep_ctrl[] = {	SENSOR_ATTR(beep_enable, S_IRUGO | S_IWUSR,			show_beep_enable, store_beep_enable, 0),	SENSOR_ATTR(beep_mask, S_IRUGO | S_IWUSR,			show_beep_mask, store_beep_mask, 1)};/* cpu voltage regulation information */static ssize_t show_vid_reg(struct device *dev,				struct device_attribute *attr, char *buf){	struct w83791d_data *data = w83791d_update_device(dev);	return sprintf(buf, "%d\n", vid_from_reg(data->vid, data->vrm));}static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid_reg, NULL);static ssize_t show_vrm_reg(struct device *dev,				struct device_attribute *attr, char *buf){	struct w83791d_data *data = dev_get_drvdata(dev);	return sprintf(buf, "%d\n", data->vrm);}static ssize_t store_vrm_reg(struct device *dev,				struct device_attribute *attr,				const char *buf, size_t count){	struct i2c_client *client = to_i2c_client(dev);	struct w83791d_data *data = i2c_get_clientdata(client);	unsigned long val = simple_strtoul(buf, NULL, 10);	/* No lock needed as vrm is internal to the driver	   (not read from a chip register) and so is not	   updated in w83791d_update_device() */	data->vrm = val;	return count;}static DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm_reg, store_vrm_reg);#define IN_UNIT_ATTRS(X) \	&sda_in_input[X].dev_attr.attr, \	&sda_in_min[X].dev_attr.attr,   \	&sda_in_max[X].dev_attr.attr,   \	&sda_in_beep[X].dev_attr.attr,  \	&sda_in_alarm[X].dev_attr.attr#define FAN_UNIT_ATTRS(X) \	&sda_fan_input[X].dev_attr.attr,        \	&sda_fan_min[X].dev_attr.attr,          \	&sda_fan_div[X].dev_attr.attr,          \	&sda_fan_beep[X].dev_attr.attr,         \	&sda_fan_alarm[X].dev_attr.attr#define TEMP_UNIT_ATTRS(X) \	&sda_temp_input[X].dev_attr.attr,       \	&sda_temp_max[X].dev_attr.attr,         \	&sda_temp_max_hyst[X].dev_attr.attr,    \	&sda_temp_beep[X].dev_attr.attr,        \	&sda_temp_alarm[X].dev_attr.attrstatic struct attribute *w83791d_attributes[] = {	IN_UNIT_ATTRS(0),	IN_UNIT_ATTRS(1),	IN_UNIT_ATTRS(2),	IN_UNIT_ATTRS(3),	IN_UNIT_ATTRS(4),	IN_UNIT_ATTRS(5),	IN_UNIT_ATTRS(6),	IN_UNIT_ATTRS(7),	IN_UNIT_ATTRS(8),	IN_UNIT_ATTRS(9),	FAN_UNIT_ATTRS(0),	FAN_UNIT_ATTRS(1),	FAN_UNIT_ATTRS(2),	FAN_UNIT_ATTRS(3),	FAN_UNIT_ATTRS(4),	TEMP_UNIT_ATTRS(0),	TEMP_UNIT_ATTRS(1),	TEMP_UNIT_ATTRS(2),	&dev_attr_alarms.attr,	&sda_beep_ctrl[0].dev_attr.attr,	&sda_beep_ctrl[1].dev_attr.attr,	&dev_attr_cpu0_vid.attr,	&dev_attr_vrm.attr,	NULL};static const struct attribute_group w83791d_group = {	.attrs = w83791d_attributes,};/* This function is called when:     * w83791d_driver is inserted (when this module is loaded), for each       available adapter     * when a new adapter is inserted (and w83791d_driver is still present) */static int w83791d_attach_adapter(struct i2c_adapter *adapter){	if (!(adapter->class & I2C_CLASS_HWMON))		return 0;	return i2c_probe(adapter, &addr_data, w83791d_detect);}static int w83791d_create_subclient(struct i2c_adapter *adapter,				struct i2c_client *client, int addr,				struct i2c_client **sub_cli){	int err;	struct i2c_client *sub_client;	(*sub_cli) = sub_client =			kzalloc(sizeof(struct i2c_client), GFP_KERNEL);	if (!(sub_client)) {		return -ENOMEM;	}

⌨️ 快捷键说明

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