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

📄 w83781d.c

📁 《linux驱动程序设计从入门到精通》一书中所有的程序代码含驱动和相应的应用程序
💻 C
📖 第 1 页 / 共 4 页
字号:
show_temp_reg(temp_max);show_temp_reg(temp_max_hyst);#define store_temp_reg(REG, reg) \static ssize_t store_temp_##reg (struct device *dev, const char *buf, size_t count, int nr) \{ \	struct i2c_client *client = to_i2c_client(dev); \	struct w83781d_data *data = i2c_get_clientdata(client); \	s32 val; \	 \	val = simple_strtol(buf, NULL, 10); \	 \	if (nr >= 2) {	/* TEMP2 and TEMP3 */ \		if (data->type == as99127f) \			data->temp_##reg##_add[nr-2] = AS99127_TEMP_ADD_TO_REG(val); \		else \			data->temp_##reg##_add[nr-2] = LM75_TEMP_TO_REG(val); \		 \		w83781d_write_value(client, W83781D_REG_TEMP_##REG(nr), \				data->temp_##reg##_add[nr-2]); \	} else {	/* TEMP1 */ \		data->temp_##reg = TEMP_TO_REG(val); \		w83781d_write_value(client, W83781D_REG_TEMP_##REG(nr), \			data->temp_##reg); \	} \	 \	return count; \}store_temp_reg(OVER, max);store_temp_reg(HYST, max_hyst);#define sysfs_temp_offset(offset) \static ssize_t \show_regs_temp_##offset (struct device *dev, char *buf) \{ \	return show_temp(dev, buf, 0x##offset); \} \static DEVICE_ATTR(temp##offset##_input, S_IRUGO, show_regs_temp_##offset, NULL);#define sysfs_temp_reg_offset(reg, offset) \static ssize_t show_regs_temp_##reg##offset (struct device *dev, char *buf) \{ \	return show_temp_##reg (dev, buf, 0x##offset); \} \static ssize_t store_regs_temp_##reg##offset (struct device *dev, const char *buf, size_t count) \{ \	return store_temp_##reg (dev, buf, count, 0x##offset); \} \static DEVICE_ATTR(temp##offset##_##reg, S_IRUGO| S_IWUSR, show_regs_temp_##reg##offset, store_regs_temp_##reg##offset);#define sysfs_temp_offsets(offset) \sysfs_temp_offset(offset); \sysfs_temp_reg_offset(max, offset); \sysfs_temp_reg_offset(max_hyst, offset);sysfs_temp_offsets(1);sysfs_temp_offsets(2);sysfs_temp_offsets(3);#define device_create_file_temp(client, offset) \do { \device_create_file(&client->dev, &dev_attr_temp##offset##_input); \device_create_file(&client->dev, &dev_attr_temp##offset##_max); \device_create_file(&client->dev, &dev_attr_temp##offset##_max_hyst); \} while (0)static ssize_tshow_vid_reg(struct device *dev, char *buf){	struct w83781d_data *data = w83781d_update_device(dev);	return sprintf(buf, "%ld\n", (long) vid_from_reg(data->vid, data->vrm));}staticDEVICE_ATTR(in0_ref, S_IRUGO, show_vid_reg, NULL);#define device_create_file_vid(client) \device_create_file(&client->dev, &dev_attr_in0_ref);static ssize_tshow_vrm_reg(struct device *dev, char *buf){	struct w83781d_data *data = w83781d_update_device(dev);	return sprintf(buf, "%ld\n", (long) data->vrm);}static ssize_tstore_vrm_reg(struct device *dev, const char *buf, size_t count){	struct i2c_client *client = to_i2c_client(dev);	struct w83781d_data *data = i2c_get_clientdata(client);	u32 val;	val = simple_strtoul(buf, NULL, 10);	data->vrm = val;	return count;}staticDEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm_reg, store_vrm_reg);#define device_create_file_vrm(client) \device_create_file(&client->dev, &dev_attr_vrm);static ssize_tshow_alarms_reg(struct device *dev, char *buf){	struct w83781d_data *data = w83781d_update_device(dev);	return sprintf(buf, "%ld\n", (long) ALARMS_FROM_REG(data->alarms));}staticDEVICE_ATTR(alarms, S_IRUGO, show_alarms_reg, NULL);#define device_create_file_alarms(client) \device_create_file(&client->dev, &dev_attr_alarms);static ssize_t show_beep_mask (struct device *dev, char *buf){	struct w83781d_data *data = w83781d_update_device(dev);	return sprintf(buf, "%ld\n",		       (long)BEEP_MASK_FROM_REG(data->beep_mask, data->type));}static ssize_t show_beep_enable (struct device *dev, char *buf){	struct w83781d_data *data = w83781d_update_device(dev);	return sprintf(buf, "%ld\n",		       (long)BEEP_ENABLE_FROM_REG(data->beep_enable));}#define BEEP_ENABLE			0	/* Store beep_enable */#define BEEP_MASK			1	/* Store beep_mask */static ssize_tstore_beep_reg(struct device *dev, const char *buf, size_t count,	       int update_mask){	struct i2c_client *client = to_i2c_client(dev);	struct w83781d_data *data = i2c_get_clientdata(client);	u32 val, val2;	val = simple_strtoul(buf, NULL, 10);	if (update_mask == BEEP_MASK) {	/* We are storing beep_mask */		data->beep_mask = BEEP_MASK_TO_REG(val, data->type);		w83781d_write_value(client, W83781D_REG_BEEP_INTS1,				    data->beep_mask & 0xff);		if ((data->type != w83781d) && (data->type != as99127f)) {			w83781d_write_value(client, W83781D_REG_BEEP_INTS3,					    ((data->beep_mask) >> 16) & 0xff);		}		val2 = (data->beep_mask >> 8) & 0x7f;	} else {		/* We are storing beep_enable */		val2 = w83781d_read_value(client, W83781D_REG_BEEP_INTS2) & 0x7f;		data->beep_enable = BEEP_ENABLE_TO_REG(val);	}	w83781d_write_value(client, W83781D_REG_BEEP_INTS2,			    val2 | data->beep_enable << 7);	return count;}#define sysfs_beep(REG, reg) \static ssize_t show_regs_beep_##reg (struct device *dev, char *buf) \{ \	return show_beep_##reg(dev, buf); \} \static ssize_t store_regs_beep_##reg (struct device *dev, const char *buf, size_t count) \{ \	return store_beep_reg(dev, buf, count, BEEP_##REG); \} \static DEVICE_ATTR(beep_##reg, S_IRUGO | S_IWUSR, show_regs_beep_##reg, store_regs_beep_##reg);sysfs_beep(ENABLE, enable);sysfs_beep(MASK, mask);#define device_create_file_beep(client) \do { \device_create_file(&client->dev, &dev_attr_beep_enable); \device_create_file(&client->dev, &dev_attr_beep_mask); \} while (0)static ssize_tshow_fan_div_reg(struct device *dev, char *buf, int nr){	struct w83781d_data *data = w83781d_update_device(dev);	return sprintf(buf, "%ld\n",		       (long) DIV_FROM_REG(data->fan_div[nr - 1]));}/* 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_tstore_fan_div_reg(struct device *dev, const char *buf, size_t count, int nr){	struct i2c_client *client = to_i2c_client(dev);	struct w83781d_data *data = i2c_get_clientdata(client);	unsigned long min;	u8 reg;	/* Save fan_min */	min = FAN_FROM_REG(data->fan_min[nr],			   DIV_FROM_REG(data->fan_div[nr]));	data->fan_div[nr] = DIV_TO_REG(simple_strtoul(buf, NULL, 10),				      data->type);	reg = (w83781d_read_value(client, nr==2 ? W83781D_REG_PIN : W83781D_REG_VID_FANDIV)	       & (nr==0 ? 0xcf : 0x3f))	    | ((data->fan_div[nr] & 0x03) << (nr==0 ? 4 : 6));	w83781d_write_value(client, nr==2 ? W83781D_REG_PIN : W83781D_REG_VID_FANDIV, reg);	/* w83781d and as99127f don't have extended divisor bits */	if (data->type != w83781d && data->type != as99127f) {		reg = (w83781d_read_value(client, W83781D_REG_VBAT)		       & ~(1 << (5 + nr)))		    | ((data->fan_div[nr] & 0x04) << (3 + nr));		w83781d_write_value(client, W83781D_REG_VBAT, reg);	}	/* Restore fan_min */	data->fan_min[nr] = FAN_TO_REG(min, DIV_FROM_REG(data->fan_div[nr]));	w83781d_write_value(client, W83781D_REG_FAN_MIN(nr+1), data->fan_min[nr]);	return count;}#define sysfs_fan_div(offset) \static ssize_t show_regs_fan_div_##offset (struct device *dev, char *buf) \{ \	return show_fan_div_reg(dev, buf, offset); \} \static ssize_t store_regs_fan_div_##offset (struct device *dev, const char *buf, size_t count) \{ \	return store_fan_div_reg(dev, buf, count, offset - 1); \} \static DEVICE_ATTR(fan##offset##_div, S_IRUGO | S_IWUSR, show_regs_fan_div_##offset, store_regs_fan_div_##offset);sysfs_fan_div(1);sysfs_fan_div(2);sysfs_fan_div(3);#define device_create_file_fan_div(client, offset) \do { \device_create_file(&client->dev, &dev_attr_fan##offset##_div); \} while (0)static ssize_tshow_pwm_reg(struct device *dev, char *buf, int nr){	struct w83781d_data *data = w83781d_update_device(dev);	return sprintf(buf, "%ld\n", (long) PWM_FROM_REG(data->pwm[nr - 1]));}static ssize_tshow_pwmenable_reg(struct device *dev, char *buf, int nr){	struct w83781d_data *data = w83781d_update_device(dev);	return sprintf(buf, "%ld\n", (long) data->pwmenable[nr - 1]);}static ssize_tstore_pwm_reg(struct device *dev, const char *buf, size_t count, int nr){	struct i2c_client *client = to_i2c_client(dev);	struct w83781d_data *data = i2c_get_clientdata(client);	u32 val;	val = simple_strtoul(buf, NULL, 10);	data->pwm[nr - 1] = PWM_TO_REG(val);	w83781d_write_value(client, W83781D_REG_PWM(nr), data->pwm[nr - 1]);	return count;}static ssize_tstore_pwmenable_reg(struct device *dev, const char *buf, size_t count, int nr){	struct i2c_client *client = to_i2c_client(dev);	struct w83781d_data *data = i2c_get_clientdata(client);	u32 val, reg;	val = simple_strtoul(buf, NULL, 10);	switch (val) {	case 0:	case 1:		reg = w83781d_read_value(client, W83781D_REG_PWMCLK12);		w83781d_write_value(client, W83781D_REG_PWMCLK12,				    (reg & 0xf7) | (val << 3));		reg = w83781d_read_value(client, W83781D_REG_BEEP_CONFIG);		w83781d_write_value(client, W83781D_REG_BEEP_CONFIG,				    (reg & 0xef) | (!val << 4));		data->pwmenable[nr - 1] = val;		break;	default:		return -EINVAL;	}	return count;}#define sysfs_pwm(offset) \static ssize_t show_regs_pwm_##offset (struct device *dev, char *buf) \{ \	return show_pwm_reg(dev, buf, offset); \} \static ssize_t store_regs_pwm_##offset (struct device *dev, const char *buf, size_t count) \{ \	return store_pwm_reg(dev, buf, count, offset); \} \static DEVICE_ATTR(fan##offset##_pwm, S_IRUGO | S_IWUSR, show_regs_pwm_##offset, store_regs_pwm_##offset);#define sysfs_pwmenable(offset) \static ssize_t show_regs_pwmenable_##offset (struct device *dev, char *buf) \{ \	return show_pwmenable_reg(dev, buf, offset); \} \static ssize_t store_regs_pwmenable_##offset (struct device *dev, const char *buf, size_t count) \{ \	return store_pwmenable_reg(dev, buf, count, offset); \} \static DEVICE_ATTR(fan##offset##_pwm_enable, S_IRUGO | S_IWUSR, show_regs_pwmenable_##offset, store_regs_pwmenable_##offset);sysfs_pwm(1);sysfs_pwm(2);sysfs_pwmenable(2);		/* only PWM2 can be enabled/disabled */sysfs_pwm(3);sysfs_pwm(4);#define device_create_file_pwm(client, offset) \do { \device_create_file(&client->dev, &dev_attr_fan##offset##_pwm); \} while (0)#define device_create_file_pwmenable(client, offset) \do { \device_create_file(&client->dev, &dev_attr_fan##offset##_pwm_enable); \} while (0)static ssize_tshow_sensor_reg(struct device *dev, char *buf, int nr){	struct w83781d_data *data = w83781d_update_device(dev);	return sprintf(buf, "%ld\n", (long) data->sens[nr - 1]);}static ssize_tstore_sensor_reg(struct device *dev, const char *buf, size_t count, int nr){	struct i2c_client *client = to_i2c_client(dev);	struct w83781d_data *data = i2c_get_clientdata(client);	u32 val, tmp;	val = simple_strtoul(buf, NULL, 10);	switch (val) {	case 1:		/* PII/Celeron diode */		tmp = w83781d_read_value(client, W83781D_REG_SCFG1);		w83781d_write_value(client, W83781D_REG_SCFG1,				    tmp | BIT_SCFG1[nr - 1]);		tmp = w83781d_read_value(client, W83781D_REG_SCFG2);		w83781d_write_value(client, W83781D_REG_SCFG2,				    tmp | BIT_SCFG2[nr - 1]);		data->sens[nr - 1] = val;		break;	case 2:		/* 3904 */		tmp = w83781d_read_value(client, W83781D_REG_SCFG1);		w83781d_write_value(client, W83781D_REG_SCFG1,				    tmp | BIT_SCFG1[nr - 1]);		tmp = w83781d_read_value(client, W83781D_REG_SCFG2);		w83781d_write_value(client, W83781D_REG_SCFG2,				    tmp & ~BIT_SCFG2[nr - 1]);		data->sens[nr - 1] = val;		break;	case W83781D_DEFAULT_BETA:	/* thermistor */		tmp = w83781d_read_value(client, W83781D_REG_SCFG1);		w83781d_write_value(client, W83781D_REG_SCFG1,				    tmp & ~BIT_SCFG1[nr - 1]);		data->sens[nr - 1] = val;		break;	default:		dev_err(&client->dev,		       "Invalid sensor type %ld; must be 1, 2, or %d\n",		       (long) val, W83781D_DEFAULT_BETA);		break;	}	return count;}#define sysfs_sensor(offset) \static ssize_t show_regs_sensor_##offset (struct device *dev, char *buf) \{ \    return show_sensor_reg(dev, buf, offset); \} \static ssize_t store_regs_sensor_##offset (struct device *dev, const char *buf, size_t count) \{ \    return store_sensor_reg(dev, buf, count, offset); \} \static DEVICE_ATTR(temp##offset##_type, S_IRUGO | S_IWUSR, show_regs_sensor_##offset, store_regs_sensor_##offset);sysfs_sensor(1);sysfs_sensor(2);sysfs_sensor(3);#define device_create_file_sensor(client, offset) \do { \device_create_file(&client->dev, &dev_attr_temp##offset##_type); \} while (0)#ifdef W83781D_RTstatic ssize_tshow_rt_reg(struct device *dev, char *buf, int nr){	struct w83781d_data *data = w83781d_update_device(dev);	int i, j = 0;	for (i = 0; i < 32; i++) {		if (i > 0)			j += sprintf(buf, " %ld", (long) data->rt[nr - 1][i]);		else			j += sprintf(buf, "%ld", (long) data->rt[nr - 1][i]);	}	j += sprintf(buf, "\n");	return j;

⌨️ 快捷键说明

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