w83627hf.c

来自「linux 内核源代码」· C语言 代码 · 共 1,707 行 · 第 1/4 页

C
1,707
字号
				     (w83627hf_read_value(data,				     W836X7HF_REG_PWM(data->type, nr)) & 0x0f));	} else {		data->pwm[nr] = PWM_TO_REG(val);		w83627hf_write_value(data,				     W836X7HF_REG_PWM(data->type, nr),				     data->pwm[nr]);	}	mutex_unlock(&data->update_lock);	return count;}static SENSOR_DEVICE_ATTR(pwm1, S_IRUGO|S_IWUSR, show_pwm, store_pwm, 0);static SENSOR_DEVICE_ATTR(pwm2, S_IRUGO|S_IWUSR, show_pwm, store_pwm, 1);static SENSOR_DEVICE_ATTR(pwm3, S_IRUGO|S_IWUSR, show_pwm, store_pwm, 2);static ssize_tshow_pwm_freq(struct device *dev, struct device_attribute *devattr, char *buf){	int nr = to_sensor_dev_attr(devattr)->index;	struct w83627hf_data *data = w83627hf_update_device(dev);	if (data->type == w83627hf)		return sprintf(buf, "%ld\n",			pwm_freq_from_reg_627hf(data->pwm_freq[nr]));	else		return sprintf(buf, "%ld\n",			pwm_freq_from_reg(data->pwm_freq[nr]));}static ssize_tstore_pwm_freq(struct device *dev, struct device_attribute *devattr,	       const char *buf, size_t count){	int nr = to_sensor_dev_attr(devattr)->index;	struct w83627hf_data *data = dev_get_drvdata(dev);	static const u8 mask[]={0xF8, 0x8F};	u32 val;	val = simple_strtoul(buf, NULL, 10);	mutex_lock(&data->update_lock);	if (data->type == w83627hf) {		data->pwm_freq[nr] = pwm_freq_to_reg_627hf(val);		w83627hf_write_value(data, W83627HF_REG_PWM_FREQ,				(data->pwm_freq[nr] << (nr*4)) |				(w83627hf_read_value(data,				W83627HF_REG_PWM_FREQ) & mask[nr]));	} else {		data->pwm_freq[nr] = pwm_freq_to_reg(val);		w83627hf_write_value(data, W83637HF_REG_PWM_FREQ[nr],				data->pwm_freq[nr]);	}	mutex_unlock(&data->update_lock);	return count;}static SENSOR_DEVICE_ATTR(pwm1_freq, S_IRUGO|S_IWUSR,			  show_pwm_freq, store_pwm_freq, 0);static SENSOR_DEVICE_ATTR(pwm2_freq, S_IRUGO|S_IWUSR,			  show_pwm_freq, store_pwm_freq, 1);static SENSOR_DEVICE_ATTR(pwm3_freq, S_IRUGO|S_IWUSR,			  show_pwm_freq, store_pwm_freq, 2);static ssize_tshow_temp_type(struct device *dev, struct device_attribute *devattr,	       char *buf){	int nr = to_sensor_dev_attr(devattr)->index;	struct w83627hf_data *data = w83627hf_update_device(dev);	return sprintf(buf, "%ld\n", (long) data->sens[nr]);}static ssize_tstore_temp_type(struct device *dev, struct device_attribute *devattr,		const char *buf, size_t count){	int nr = to_sensor_dev_attr(devattr)->index;	struct w83627hf_data *data = dev_get_drvdata(dev);	u32 val, tmp;	val = simple_strtoul(buf, NULL, 10);	mutex_lock(&data->update_lock);	switch (val) {	case 1:		/* PII/Celeron diode */		tmp = w83627hf_read_value(data, W83781D_REG_SCFG1);		w83627hf_write_value(data, W83781D_REG_SCFG1,				    tmp | BIT_SCFG1[nr]);		tmp = w83627hf_read_value(data, W83781D_REG_SCFG2);		w83627hf_write_value(data, W83781D_REG_SCFG2,				    tmp | BIT_SCFG2[nr]);		data->sens[nr] = val;		break;	case 2:		/* 3904 */		tmp = w83627hf_read_value(data, W83781D_REG_SCFG1);		w83627hf_write_value(data, W83781D_REG_SCFG1,				    tmp | BIT_SCFG1[nr]);		tmp = w83627hf_read_value(data, W83781D_REG_SCFG2);		w83627hf_write_value(data, W83781D_REG_SCFG2,				    tmp & ~BIT_SCFG2[nr]);		data->sens[nr] = val;		break;	case W83781D_DEFAULT_BETA:		dev_warn(dev, "Sensor type %d is deprecated, please use 4 "			 "instead\n", W83781D_DEFAULT_BETA);		/* fall through */	case 4:		/* thermistor */		tmp = w83627hf_read_value(data, W83781D_REG_SCFG1);		w83627hf_write_value(data, W83781D_REG_SCFG1,				    tmp & ~BIT_SCFG1[nr]);		data->sens[nr] = val;		break;	default:		dev_err(dev,		       "Invalid sensor type %ld; must be 1, 2, or 4\n",		       (long) val);		break;	}	mutex_unlock(&data->update_lock);	return count;}#define sysfs_temp_type(offset) \static SENSOR_DEVICE_ATTR(temp##offset##_type, S_IRUGO | S_IWUSR, \			  show_temp_type, store_temp_type, offset - 1);sysfs_temp_type(1);sysfs_temp_type(2);sysfs_temp_type(3);static ssize_tshow_name(struct device *dev, struct device_attribute *devattr, char *buf){	struct w83627hf_data *data = dev_get_drvdata(dev);	return sprintf(buf, "%s\n", data->name);}static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);static int __init w83627hf_find(int sioaddr, unsigned short *addr,				struct w83627hf_sio_data *sio_data){	int err = -ENODEV;	u16 val;	static const __initdata char *names[] = {		"W83627HF",		"W83627THF",		"W83697HF",		"W83637HF",		"W83687THF",	};	REG = sioaddr;	VAL = sioaddr + 1;	superio_enter();	val= superio_inb(DEVID);	switch (val) {	case W627_DEVID:		sio_data->type = w83627hf;		break;	case W627THF_DEVID:		sio_data->type = w83627thf;		break;	case W697_DEVID:		sio_data->type = w83697hf;		break;	case W637_DEVID:		sio_data->type = w83637hf;		break;	case W687THF_DEVID:		sio_data->type = w83687thf;		break;	case 0xff:	/* No device at all */		goto exit;	default:		pr_debug(DRVNAME ": Unsupported chip (DEVID=0x%02x)\n", val);		goto exit;	}	superio_select(W83627HF_LD_HWM);	force_addr &= WINB_ALIGNMENT;	if (force_addr) {		printk(KERN_WARNING DRVNAME ": Forcing address 0x%x\n",		       force_addr);		superio_outb(WINB_BASE_REG, force_addr >> 8);		superio_outb(WINB_BASE_REG + 1, force_addr & 0xff);	}	val = (superio_inb(WINB_BASE_REG) << 8) |	       superio_inb(WINB_BASE_REG + 1);	*addr = val & WINB_ALIGNMENT;	if (*addr == 0) {		printk(KERN_WARNING DRVNAME ": Base address not set, "		       "skipping\n");		goto exit;	}	val = superio_inb(WINB_ACT_REG);	if (!(val & 0x01)) {		printk(KERN_WARNING DRVNAME ": Enabling HWM logical device\n");		superio_outb(WINB_ACT_REG, val | 0x01);	}	err = 0;	pr_info(DRVNAME ": Found %s chip at %#x\n",		names[sio_data->type], *addr); exit:	superio_exit();	return err;}#define VIN_UNIT_ATTRS(_X_)	\	&sensor_dev_attr_in##_X_##_input.dev_attr.attr,		\	&sensor_dev_attr_in##_X_##_min.dev_attr.attr,		\	&sensor_dev_attr_in##_X_##_max.dev_attr.attr#define FAN_UNIT_ATTRS(_X_)	\	&sensor_dev_attr_fan##_X_##_input.dev_attr.attr,	\	&sensor_dev_attr_fan##_X_##_min.dev_attr.attr,		\	&sensor_dev_attr_fan##_X_##_div.dev_attr.attr#define TEMP_UNIT_ATTRS(_X_)	\	&sensor_dev_attr_temp##_X_##_input.dev_attr.attr,	\	&sensor_dev_attr_temp##_X_##_max.dev_attr.attr,		\	&sensor_dev_attr_temp##_X_##_max_hyst.dev_attr.attr,	\	&sensor_dev_attr_temp##_X_##_type.dev_attr.attrstatic struct attribute *w83627hf_attributes[] = {	&dev_attr_in0_input.attr,	&dev_attr_in0_min.attr,	&dev_attr_in0_max.attr,	VIN_UNIT_ATTRS(2),	VIN_UNIT_ATTRS(3),	VIN_UNIT_ATTRS(4),	VIN_UNIT_ATTRS(7),	VIN_UNIT_ATTRS(8),	FAN_UNIT_ATTRS(1),	FAN_UNIT_ATTRS(2),	TEMP_UNIT_ATTRS(1),	TEMP_UNIT_ATTRS(2),	&dev_attr_alarms.attr,	&dev_attr_beep_enable.attr,	&dev_attr_beep_mask.attr,	&sensor_dev_attr_pwm1.dev_attr.attr,	&sensor_dev_attr_pwm2.dev_attr.attr,	&dev_attr_name.attr,	NULL};static const struct attribute_group w83627hf_group = {	.attrs = w83627hf_attributes,};static struct attribute *w83627hf_attributes_opt[] = {	VIN_UNIT_ATTRS(1),	VIN_UNIT_ATTRS(5),	VIN_UNIT_ATTRS(6),	FAN_UNIT_ATTRS(3),	TEMP_UNIT_ATTRS(3),	&sensor_dev_attr_pwm3.dev_attr.attr,	&sensor_dev_attr_pwm1_freq.dev_attr.attr,	&sensor_dev_attr_pwm2_freq.dev_attr.attr,	&sensor_dev_attr_pwm3_freq.dev_attr.attr,	NULL};static const struct attribute_group w83627hf_group_opt = {	.attrs = w83627hf_attributes_opt,};static int __devinit w83627hf_probe(struct platform_device *pdev){	struct device *dev = &pdev->dev;	struct w83627hf_sio_data *sio_data = dev->platform_data;	struct w83627hf_data *data;	struct resource *res;	int err, i;	static const char *names[] = {		"w83627hf",		"w83627thf",		"w83697hf",		"w83637hf",		"w83687thf",	};	res = platform_get_resource(pdev, IORESOURCE_IO, 0);	if (!request_region(res->start, WINB_REGION_SIZE, DRVNAME)) {		dev_err(dev, "Failed to request region 0x%lx-0x%lx\n",			(unsigned long)res->start,			(unsigned long)(res->start + WINB_REGION_SIZE - 1));		err = -EBUSY;		goto ERROR0;	}	if (!(data = kzalloc(sizeof(struct w83627hf_data), GFP_KERNEL))) {		err = -ENOMEM;		goto ERROR1;	}	data->addr = res->start;	data->type = sio_data->type;	data->name = names[sio_data->type];	mutex_init(&data->lock);	mutex_init(&data->update_lock);	platform_set_drvdata(pdev, data);	/* Initialize the chip */	w83627hf_init_device(pdev);	/* A few vars need to be filled upon startup */	for (i = 0; i <= 2; i++)		data->fan_min[i] = w83627hf_read_value(					data, W83627HF_REG_FAN_MIN(i));	w83627hf_update_fan_div(data);	/* Register common device attributes */	if ((err = sysfs_create_group(&dev->kobj, &w83627hf_group)))		goto ERROR3;	/* Register chip-specific device attributes */	if (data->type == w83627hf || data->type == w83697hf)		if ((err = device_create_file(dev,				&sensor_dev_attr_in5_input.dev_attr))		 || (err = device_create_file(dev,				&sensor_dev_attr_in5_min.dev_attr))		 || (err = device_create_file(dev,				&sensor_dev_attr_in5_max.dev_attr))		 || (err = device_create_file(dev,				&sensor_dev_attr_in6_input.dev_attr))		 || (err = device_create_file(dev,				&sensor_dev_attr_in6_min.dev_attr))		 || (err = device_create_file(dev,				&sensor_dev_attr_in6_max.dev_attr))		 || (err = device_create_file(dev,				&sensor_dev_attr_pwm1_freq.dev_attr))		 || (err = device_create_file(dev,				&sensor_dev_attr_pwm2_freq.dev_attr)))			goto ERROR4;	if (data->type != w83697hf)		if ((err = device_create_file(dev,				&sensor_dev_attr_in1_input.dev_attr))		 || (err = device_create_file(dev,				&sensor_dev_attr_in1_min.dev_attr))		 || (err = device_create_file(dev,				&sensor_dev_attr_in1_max.dev_attr))		 || (err = device_create_file(dev,				&sensor_dev_attr_fan3_input.dev_attr))		 || (err = device_create_file(dev,				&sensor_dev_attr_fan3_min.dev_attr))		 || (err = device_create_file(dev,				&sensor_dev_attr_fan3_div.dev_attr))		 || (err = device_create_file(dev,				&sensor_dev_attr_temp3_input.dev_attr))		 || (err = device_create_file(dev,				&sensor_dev_attr_temp3_max.dev_attr))		 || (err = device_create_file(dev,				&sensor_dev_attr_temp3_max_hyst.dev_attr))		 || (err = device_create_file(dev,				&sensor_dev_attr_temp3_type.dev_attr)))			goto ERROR4;	if (data->type != w83697hf && data->vid != 0xff) {		/* Convert VID to voltage based on VRM */		data->vrm = vid_which_vrm();		if ((err = device_create_file(dev, &dev_attr_cpu0_vid))		 || (err = device_create_file(dev, &dev_attr_vrm)))			goto ERROR4;	}	if (data->type == w83627thf || data->type == w83637hf	 || data->type == w83687thf)		if ((err = device_create_file(dev,				&sensor_dev_attr_pwm3.dev_attr)))			goto ERROR4;	if (data->type == w83637hf || data->type == w83687thf)		if ((err = device_create_file(dev,				&sensor_dev_attr_pwm1_freq.dev_attr))		 || (err = device_create_file(dev,				&sensor_dev_attr_pwm2_freq.dev_attr))		 || (err = device_create_file(dev,				&sensor_dev_attr_pwm3_freq.dev_attr)))			goto ERROR4;	data->hwmon_dev = hwmon_device_register(dev);	if (IS_ERR(data->hwmon_dev)) {		err = PTR_ERR(data->hwmon_dev);		goto ERROR4;	}	return 0;      ERROR4:	sysfs_remove_group(&dev->kobj, &w83627hf_group);	sysfs_remove_group(&dev->kobj, &w83627hf_group_opt);      ERROR3:	platform_set_drvdata(pdev, NULL);	kfree(data);      ERROR1:	release_region(res->start, WINB_REGION_SIZE);      ERROR0:	return err;}static int __devexit w83627hf_remove(struct platform_device *pdev){	struct w83627hf_data *data = platform_get_drvdata(pdev);	struct resource *res;	hwmon_device_unregister(data->hwmon_dev);	sysfs_remove_group(&pdev->dev.kobj, &w83627hf_group);

⌨️ 快捷键说明

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