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

📄 adm1026.c

📁 h内核
💻 C
📖 第 1 页 / 共 5 页
字号:
}static ssize_t show_auto_pwm_min(struct device *dev, char *buf){	struct adm1026_data *data = adm1026_update_device(dev);	return sprintf(buf,"%d\n", data->pwm1.auto_pwm_min);}static ssize_t set_auto_pwm_min(struct device *dev, const char *buf,		size_t count){	struct i2c_client *client = to_i2c_client(dev);	struct adm1026_data *data = i2c_get_clientdata(client);	int     val;	down(&data->update_lock);	val = simple_strtol(buf, NULL, 10);	data->pwm1.auto_pwm_min = SENSORS_LIMIT(val,0,255);	if (data->pwm1.enable == 2) { /* apply immediately */		data->pwm1.pwm = PWM_TO_REG((data->pwm1.pwm & 0x0f) |			PWM_MIN_TO_REG(data->pwm1.auto_pwm_min)); 		adm1026_write_value(client, ADM1026_REG_PWM, data->pwm1.pwm);	}	up(&data->update_lock);	return count;}static ssize_t show_auto_pwm_max(struct device *dev, char *buf){	return sprintf(buf,"%d\n", ADM1026_PWM_MAX);}static ssize_t show_pwm_enable(struct device *dev, char *buf){	struct adm1026_data *data = adm1026_update_device(dev);	return sprintf(buf,"%d\n", data->pwm1.enable);}static ssize_t set_pwm_enable(struct device *dev, const char *buf,		size_t count){	struct i2c_client *client = to_i2c_client(dev);	struct adm1026_data *data = i2c_get_clientdata(client);	int     val;	int     old_enable;	val = simple_strtol(buf, NULL, 10);	if ((val >= 0) && (val < 3)) {		down(&data->update_lock);		old_enable = data->pwm1.enable;		data->pwm1.enable = val;		data->config1 = (data->config1 & ~CFG1_PWM_AFC)				| ((val == 2) ? CFG1_PWM_AFC : 0);		adm1026_write_value(client, ADM1026_REG_CONFIG1,			data->config1);		if (val == 2) {  /* apply pwm1_auto_pwm_min to pwm1 */			data->pwm1.pwm = PWM_TO_REG((data->pwm1.pwm & 0x0f) |				PWM_MIN_TO_REG(data->pwm1.auto_pwm_min)); 			adm1026_write_value(client, ADM1026_REG_PWM, 				data->pwm1.pwm);		} else if (!((old_enable == 1) && (val == 1))) {			/* set pwm to safe value */			data->pwm1.pwm = 255;			adm1026_write_value(client, ADM1026_REG_PWM, 				data->pwm1.pwm);		}		up(&data->update_lock);	}	return count;}/* enable PWM fan control */static DEVICE_ATTR(pwm1, S_IRUGO | S_IWUSR, show_pwm_reg, set_pwm_reg); static DEVICE_ATTR(pwm2, S_IRUGO | S_IWUSR, show_pwm_reg, set_pwm_reg); static DEVICE_ATTR(pwm3, S_IRUGO | S_IWUSR, show_pwm_reg, set_pwm_reg); static DEVICE_ATTR(pwm1_enable, S_IRUGO | S_IWUSR, show_pwm_enable, 	set_pwm_enable);static DEVICE_ATTR(pwm2_enable, S_IRUGO | S_IWUSR, show_pwm_enable, 	set_pwm_enable);static DEVICE_ATTR(pwm3_enable, S_IRUGO | S_IWUSR, show_pwm_enable, 	set_pwm_enable);static DEVICE_ATTR(temp1_auto_point1_pwm, S_IRUGO | S_IWUSR, 	show_auto_pwm_min, set_auto_pwm_min);static DEVICE_ATTR(temp2_auto_point1_pwm, S_IRUGO | S_IWUSR, 	show_auto_pwm_min, set_auto_pwm_min);static DEVICE_ATTR(temp3_auto_point1_pwm, S_IRUGO | S_IWUSR, 	show_auto_pwm_min, set_auto_pwm_min);static DEVICE_ATTR(temp1_auto_point2_pwm, S_IRUGO, show_auto_pwm_max, NULL);static DEVICE_ATTR(temp2_auto_point2_pwm, S_IRUGO, show_auto_pwm_max, NULL);static DEVICE_ATTR(temp3_auto_point2_pwm, S_IRUGO, show_auto_pwm_max, NULL);int adm1026_detect(struct i2c_adapter *adapter, int address,		int kind){	int company, verstep;	struct i2c_client *new_client;	struct adm1026_data *data;	int err = 0;	const char *type_name = "";	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {		/* We need to be able to do byte I/O */		goto exit;	};	/* OK. For now, we presume we have a valid client. We now create the	   client structure, even though we cannot fill it completely yet.	   But it allows us to access adm1026_{read,write}_value. */	if (!(data = kmalloc(sizeof(struct adm1026_data), GFP_KERNEL))) {		err = -ENOMEM;		goto exit;	}	memset(data, 0, sizeof(struct adm1026_data));	new_client = &data->client;	i2c_set_clientdata(new_client, data);	new_client->addr = address;	new_client->adapter = adapter;	new_client->driver = &adm1026_driver;	new_client->flags = 0;	/* Now, we do the remaining detection. */	company = adm1026_read_value(new_client, ADM1026_REG_COMPANY);	verstep = adm1026_read_value(new_client, ADM1026_REG_VERSTEP);	dev_dbg(&new_client->dev, "Detecting device at %d,0x%02x with"		" COMPANY: 0x%02x and VERSTEP: 0x%02x\n",		i2c_adapter_id(new_client->adapter), new_client->addr,		company, verstep);	/* If auto-detecting, Determine the chip type. */	if (kind <= 0) {		dev_dbg(&new_client->dev, "Autodetecting device at %d,0x%02x "			"...\n", i2c_adapter_id(adapter), address);		if (company == ADM1026_COMPANY_ANALOG_DEV		    && verstep == ADM1026_VERSTEP_ADM1026) {			kind = adm1026;		} else if (company == ADM1026_COMPANY_ANALOG_DEV			&& (verstep & 0xf0) == ADM1026_VERSTEP_GENERIC) {			dev_err(&adapter->dev, ": Unrecognized stepping "				"0x%02x. Defaulting to ADM1026.\n", verstep);			kind = adm1026;		} else if ((verstep & 0xf0) == ADM1026_VERSTEP_GENERIC) {			dev_err(&adapter->dev, ": Found version/stepping "				"0x%02x. Assuming generic ADM1026.\n",				verstep);			kind = any_chip;		} else {			dev_dbg(&new_client->dev, ": Autodetection "				"failed\n");			/* Not an ADM1026 ... */			if (kind == 0)  { /* User used force=x,y */				dev_err(&adapter->dev, "Generic ADM1026 not "					"found at %d,0x%02x.  Try "					"force_adm1026.\n",					i2c_adapter_id(adapter), address);			}			err = 0;			goto exitfree;		}	}	/* Fill in the chip specific driver values */	switch (kind) {	case any_chip :		type_name = "adm1026";		break;	case adm1026 :		type_name = "adm1026";		break;	default :		dev_err(&adapter->dev, ": Internal error, invalid "			"kind (%d)!", kind);		err = -EFAULT;		goto exitfree;	}	strlcpy(new_client->name, type_name, I2C_NAME_SIZE);	/* Fill in the remaining client fields */	new_client->id = adm1026_id++;	data->type = kind;	data->valid = 0;	init_MUTEX(&data->update_lock);	dev_dbg(&new_client->dev, "(%d): Assigning ID %d to %s at %d,0x%02x\n",		new_client->id, new_client->id, new_client->name,		i2c_adapter_id(new_client->adapter),		new_client->addr);	/* Tell the I2C layer a new client has arrived */	if ((err = i2c_attach_client(new_client)))		goto exitfree;	/* Set the VRM version */	data->vrm = i2c_which_vrm();	/* Initialize the ADM1026 chip */	adm1026_init_client(new_client);	/* Register sysfs hooks */	device_create_file(&new_client->dev, &dev_attr_in0_input);	device_create_file(&new_client->dev, &dev_attr_in0_max);	device_create_file(&new_client->dev, &dev_attr_in0_min);	device_create_file(&new_client->dev, &dev_attr_in1_input);	device_create_file(&new_client->dev, &dev_attr_in1_max);	device_create_file(&new_client->dev, &dev_attr_in1_min);	device_create_file(&new_client->dev, &dev_attr_in2_input);	device_create_file(&new_client->dev, &dev_attr_in2_max);	device_create_file(&new_client->dev, &dev_attr_in2_min);	device_create_file(&new_client->dev, &dev_attr_in3_input);	device_create_file(&new_client->dev, &dev_attr_in3_max);	device_create_file(&new_client->dev, &dev_attr_in3_min);	device_create_file(&new_client->dev, &dev_attr_in4_input);	device_create_file(&new_client->dev, &dev_attr_in4_max);	device_create_file(&new_client->dev, &dev_attr_in4_min);	device_create_file(&new_client->dev, &dev_attr_in5_input);	device_create_file(&new_client->dev, &dev_attr_in5_max);	device_create_file(&new_client->dev, &dev_attr_in5_min);	device_create_file(&new_client->dev, &dev_attr_in6_input);	device_create_file(&new_client->dev, &dev_attr_in6_max);	device_create_file(&new_client->dev, &dev_attr_in6_min);	device_create_file(&new_client->dev, &dev_attr_in7_input);	device_create_file(&new_client->dev, &dev_attr_in7_max);	device_create_file(&new_client->dev, &dev_attr_in7_min);	device_create_file(&new_client->dev, &dev_attr_in8_input);	device_create_file(&new_client->dev, &dev_attr_in8_max);	device_create_file(&new_client->dev, &dev_attr_in8_min);	device_create_file(&new_client->dev, &dev_attr_in9_input);	device_create_file(&new_client->dev, &dev_attr_in9_max);	device_create_file(&new_client->dev, &dev_attr_in9_min);	device_create_file(&new_client->dev, &dev_attr_in10_input);	device_create_file(&new_client->dev, &dev_attr_in10_max);	device_create_file(&new_client->dev, &dev_attr_in10_min);	device_create_file(&new_client->dev, &dev_attr_in11_input);	device_create_file(&new_client->dev, &dev_attr_in11_max);	device_create_file(&new_client->dev, &dev_attr_in11_min);	device_create_file(&new_client->dev, &dev_attr_in12_input);	device_create_file(&new_client->dev, &dev_attr_in12_max);	device_create_file(&new_client->dev, &dev_attr_in12_min);	device_create_file(&new_client->dev, &dev_attr_in13_input);	device_create_file(&new_client->dev, &dev_attr_in13_max);	device_create_file(&new_client->dev, &dev_attr_in13_min);	device_create_file(&new_client->dev, &dev_attr_in14_input);	device_create_file(&new_client->dev, &dev_attr_in14_max);	device_create_file(&new_client->dev, &dev_attr_in14_min);	device_create_file(&new_client->dev, &dev_attr_in15_input);	device_create_file(&new_client->dev, &dev_attr_in15_max);	device_create_file(&new_client->dev, &dev_attr_in15_min);	device_create_file(&new_client->dev, &dev_attr_in16_input);	device_create_file(&new_client->dev, &dev_attr_in16_max);	device_create_file(&new_client->dev, &dev_attr_in16_min);	device_create_file(&new_client->dev, &dev_attr_fan1_input);	device_create_file(&new_client->dev, &dev_attr_fan1_div);	device_create_file(&new_client->dev, &dev_attr_fan1_min);	device_create_file(&new_client->dev, &dev_attr_fan2_input);	device_create_file(&new_client->dev, &dev_attr_fan2_div);	device_create_file(&new_client->dev, &dev_attr_fan2_min);	device_create_file(&new_client->dev, &dev_attr_fan3_input);	device_create_file(&new_client->dev, &dev_attr_fan3_div);	device_create_file(&new_client->dev, &dev_attr_fan3_min);	device_create_file(&new_client->dev, &dev_attr_fan4_input);	device_create_file(&new_client->dev, &dev_attr_fan4_div);	device_create_file(&new_client->dev, &dev_attr_fan4_min);	device_create_file(&new_client->dev, &dev_attr_fan5_input);	device_create_file(&new_client->dev, &dev_attr_fan5_div);	device_create_file(&new_client->dev, &dev_attr_fan5_min);	device_create_file(&new_client->dev, &dev_attr_fan6_input);	device_create_file(&new_client->dev, &dev_attr_fan6_div);	device_create_file(&new_client->dev, &dev_attr_fan6_min);	device_create_file(&new_client->dev, &dev_attr_fan7_input);	device_create_file(&new_client->dev, &dev_attr_fan7_div);	device_create_file(&new_client->dev, &dev_attr_fan7_min);	device_create_file(&new_client->dev, &dev_attr_fan8_input);	device_create_file(&new_client->dev, &dev_attr_fan8_div);	device_create_file(&new_client->dev, &dev_attr_fan8_min);	device_create_file(&new_client->dev, &dev_attr_temp1_input);	device_create_file(&new_client->dev, &dev_attr_temp1_max);	device_create_file(&new_client->dev, &dev_attr_temp1_min);	device_create_file(&new_client->dev, &dev_attr_temp2_input);	device_create_file(&new_client->dev, &dev_attr_temp2_max);	device_create_file(&new_client->dev, &dev_attr_temp2_min);	device_create_file(&new_client->dev, &dev_attr_temp3_input);	device_create_file(&new_client->dev, &dev_attr_temp3_max);	device_create_file(&new_client->dev, &dev_attr_temp3_min);	device_create_file(&new_client->dev, &dev_attr_temp1_offset);	device_create_file(&new_client->dev, &dev_attr_temp2_offset);	device_create_file(&new_client->dev, &dev_attr_temp3_offset);	device_create_file(&new_client->dev, 		&dev_attr_temp1_auto_point1_temp);	device_create_file(&new_client->dev, 		&dev_attr_temp2_auto_point1_temp);	device_create_file(&new_client->dev, 		&dev_attr_temp3_auto_point1_temp);	device_create_file(&new_client->dev,		&dev_attr_temp1_auto_point1_temp_hyst);	device_create_file(&new_client->dev,		&dev_attr_temp2_auto_point1_temp_hyst);	device_create_file(&new_client->dev,		&dev_attr_temp3_auto_point1_temp_hyst);	device_create_file(&new_client->dev, 		&dev_attr_temp1_auto_point2_temp);	device_create_file(&new_client->dev, 		&dev_attr_temp2_auto_point2_temp);	device_create_file(&new_client->dev, 		&dev_attr_temp3_auto_point2_temp);	device_create_file(&new_client->dev, &dev_attr_temp1_crit);	device_create_file(&new_client->dev, &dev_attr_temp2_crit);	device_create_file(&new_client->dev, &dev_attr_temp3_crit);	device_create_file(&new_client->dev, &dev_attr_temp1_crit_enable);	device_create_file(&new_client->dev, &dev_attr_temp2_crit_enable);	device_create_file(&new_client->dev, &dev_attr_temp3_crit_enable);	device_create_file(&new_client->dev, &dev_attr_vid);	device_create_file(&new_client->dev, &dev_attr_vrm);	device_create_file(&new_client->dev, &dev_attr_alarms);	device_create_file(&new_client->dev, &dev_attr_alarm_mask);	device_create_file(&new_client->dev, &dev_attr_gpio);	device_create_file(&new_client->dev, &dev_attr_gpio_mask);	device_create_file(&new_client->dev, &dev_attr_pwm1);	device_create_file(&new_client->dev, &dev_attr_pwm2);	device_create_file(&new_client->dev, &dev_attr_pwm3);	device_create_file(&new_client->dev, &dev_attr_pwm1_enable);	device_create_file(&new_client->dev, &dev_attr_pwm2_enable);	device_create_file(&new_client->dev, &dev_attr_pwm3_enable);	device_create_file(&new_client->dev, &dev_attr_temp1_auto_point1_pwm);	device_create_file(&new_client->dev, &dev_attr_temp2_auto_point1_pwm);	device_create_file(&new_client->dev, &dev_attr_temp3_auto_point1_pwm);	device_create_file(&new_client->dev, &dev_attr_temp1_auto_point2_pwm);	device_create_file(&new_client->dev, &dev_attr_temp2_auto_point2_pwm);	device_create_file(&new_client->dev, &dev_attr_temp3_auto_point2_pwm);	device_create_file(&new_client->dev, &dev_attr_analog_out);	return 0;	/* Error out and cleanup code */exitfree:	kfree(new_client);exit:	return err;}static int __init sm_adm1026_init(void){	return i2c_add_driver(&adm1026_driver);}static void  __exit sm_adm1026_exit(void){	i2c_del_driver(&adm1026_driver);}MODULE_LICENSE("GPL");MODULE_AUTHOR("Philip Pokorny <ppokorny@penguincomputing.com>, "              "Justin Thiessen <jthiessen@penguincomputing.com>");MODULE_DESCRIPTION("ADM1026 driver");module_init(sm_adm1026_init);module_exit(sm_adm1026_exit);

⌨️ 快捷键说明

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