📄 lm85.c
字号:
static int lm85_detect(struct i2c_adapter *adapter, int address, int kind);static int lm85_detach_client(struct i2c_client *client);static int lm85_read_value(struct i2c_client *client, u8 register);static int lm85_write_value(struct i2c_client *client, u8 register, int value);static struct lm85_data *lm85_update_device(struct device *dev);static void lm85_init_client(struct i2c_client *client);static struct i2c_driver lm85_driver = { .owner = THIS_MODULE, .name = "lm85", .id = I2C_DRIVERID_LM85, .flags = I2C_DF_NOTIFY, .attach_adapter = lm85_attach_adapter, .detach_client = lm85_detach_client,};/* Unique ID assigned to each LM85 detected */static int lm85_id = 0;/* 4 Fans */static ssize_t show_fan(struct device *dev, char *buf, int nr){ struct lm85_data *data = lm85_update_device(dev); return sprintf(buf,"%d\n", FAN_FROM_REG(data->fan[nr]) );}static ssize_t show_fan_min(struct device *dev, char *buf, int nr){ struct lm85_data *data = lm85_update_device(dev); return sprintf(buf,"%d\n", FAN_FROM_REG(data->fan_min[nr]) );}static ssize_t set_fan_min(struct device *dev, const char *buf, size_t count, int nr){ struct i2c_client *client = to_i2c_client(dev); struct lm85_data *data = i2c_get_clientdata(client); int val; down(&data->update_lock); val = simple_strtol(buf, NULL, 10); data->fan_min[nr] = FAN_TO_REG(val); lm85_write_value(client, LM85_REG_FAN_MIN(nr), data->fan_min[nr]); up(&data->update_lock); return count;}#define show_fan_offset(offset) \static ssize_t show_fan_##offset (struct device *dev, char *buf) \{ \ return show_fan(dev, buf, 0x##offset - 1); \} \static ssize_t show_fan_##offset##_min (struct device *dev, char *buf) \{ \ return show_fan_min(dev, buf, 0x##offset - 1); \} \static ssize_t set_fan_##offset##_min (struct device *dev, \ const char *buf, size_t count) \{ \ return set_fan_min(dev, buf, count, 0x##offset - 1); \} \static DEVICE_ATTR(fan##offset##_input, S_IRUGO, show_fan_##offset, NULL);\static DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, \ show_fan_##offset##_min, set_fan_##offset##_min);show_fan_offset(1);show_fan_offset(2);show_fan_offset(3);show_fan_offset(4);/* vid, vrm, alarms */static ssize_t show_vid_reg(struct device *dev, char *buf){ struct lm85_data *data = lm85_update_device(dev); return sprintf(buf, "%ld\n", (long) vid_from_reg(data->vid, data->vrm));}static DEVICE_ATTR(in0_ref, S_IRUGO, show_vid_reg, NULL);static ssize_t show_vrm_reg(struct device *dev, char *buf){ struct lm85_data *data = lm85_update_device(dev); return sprintf(buf, "%ld\n", (long) data->vrm);}static ssize_t store_vrm_reg(struct device *dev, const char *buf, size_t count){ struct i2c_client *client = to_i2c_client(dev); struct lm85_data *data = i2c_get_clientdata(client); u32 val; val = simple_strtoul(buf, NULL, 10); data->vrm = val; return count;}static DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm_reg, store_vrm_reg);static ssize_t show_alarms_reg(struct device *dev, char *buf){ struct lm85_data *data = lm85_update_device(dev); return sprintf(buf, "%ld\n", (long) ALARMS_FROM_REG(data->alarms));}static DEVICE_ATTR(alarms, S_IRUGO, show_alarms_reg, NULL);/* pwm */static ssize_t show_pwm(struct device *dev, char *buf, int nr){ struct lm85_data *data = lm85_update_device(dev); return sprintf(buf,"%d\n", PWM_FROM_REG(data->pwm[nr]) );}static ssize_t set_pwm(struct device *dev, const char *buf, size_t count, int nr){ struct i2c_client *client = to_i2c_client(dev); struct lm85_data *data = i2c_get_clientdata(client); int val; down(&data->update_lock); val = simple_strtol(buf, NULL, 10); data->pwm[nr] = PWM_TO_REG(val); lm85_write_value(client, LM85_REG_PWM(nr), data->pwm[nr]); up(&data->update_lock); return count;}static ssize_t show_pwm_enable(struct device *dev, char *buf, int nr){ struct lm85_data *data = lm85_update_device(dev); int pwm_zone; pwm_zone = ZONE_FROM_REG(data->autofan[nr].config); return sprintf(buf,"%d\n", (pwm_zone != 0 && pwm_zone != -1) );}#define show_pwm_reg(offset) \static ssize_t show_pwm_##offset (struct device *dev, char *buf) \{ \ return show_pwm(dev, buf, 0x##offset - 1); \} \static ssize_t set_pwm_##offset (struct device *dev, \ const char *buf, size_t count) \{ \ return set_pwm(dev, buf, count, 0x##offset - 1); \} \static ssize_t show_pwm_enable##offset (struct device *dev, char *buf) \{ \ return show_pwm_enable(dev, buf, 0x##offset - 1); \} \static DEVICE_ATTR(fan##offset##_pwm, S_IRUGO | S_IWUSR, \ show_pwm_##offset, set_pwm_##offset); \static DEVICE_ATTR(fan##offset##_pwm_enable, S_IRUGO, show_pwm_enable##offset, NULL);show_pwm_reg(1);show_pwm_reg(2);show_pwm_reg(3);/* Voltages */static ssize_t show_in(struct device *dev, char *buf, int nr){ struct lm85_data *data = lm85_update_device(dev); return sprintf(buf,"%d\n", INS_FROM_REG(nr, data->in[nr]) );}static ssize_t show_in_min(struct device *dev, char *buf, int nr){ struct lm85_data *data = lm85_update_device(dev); return sprintf(buf,"%d\n", INS_FROM_REG(nr, data->in_min[nr]) );}static ssize_t set_in_min(struct device *dev, const char *buf, size_t count, int nr){ struct i2c_client *client = to_i2c_client(dev); struct lm85_data *data = i2c_get_clientdata(client); int val; down(&data->update_lock); val = simple_strtol(buf, NULL, 10); data->in_min[nr] = INS_TO_REG(nr, val); lm85_write_value(client, LM85_REG_IN_MIN(nr), data->in_min[nr]); up(&data->update_lock); return count;}static ssize_t show_in_max(struct device *dev, char *buf, int nr){ struct lm85_data *data = lm85_update_device(dev); return sprintf(buf,"%d\n", INS_FROM_REG(nr, data->in_max[nr]) );}static ssize_t set_in_max(struct device *dev, const char *buf, size_t count, int nr){ struct i2c_client *client = to_i2c_client(dev); struct lm85_data *data = i2c_get_clientdata(client); int val; down(&data->update_lock); val = simple_strtol(buf, NULL, 10); data->in_max[nr] = INS_TO_REG(nr, val); lm85_write_value(client, LM85_REG_IN_MAX(nr), data->in_max[nr]); up(&data->update_lock); return count;}#define show_in_reg(offset) \static ssize_t show_in_##offset (struct device *dev, char *buf) \{ \ return show_in(dev, buf, 0x##offset); \} \static ssize_t show_in_##offset##_min (struct device *dev, char *buf) \{ \ return show_in_min(dev, buf, 0x##offset); \} \static ssize_t show_in_##offset##_max (struct device *dev, char *buf) \{ \ return show_in_max(dev, buf, 0x##offset); \} \static ssize_t set_in_##offset##_min (struct device *dev, \ const char *buf, size_t count) \{ \ return set_in_min(dev, buf, count, 0x##offset); \} \static ssize_t set_in_##offset##_max (struct device *dev, \ const char *buf, size_t count) \{ \ return set_in_max(dev, buf, count, 0x##offset); \} \static DEVICE_ATTR(in##offset##_input, S_IRUGO, show_in_##offset, NULL); \static DEVICE_ATTR(in##offset##_min, S_IRUGO | S_IWUSR, \ show_in_##offset##_min, set_in_##offset##_min); \static DEVICE_ATTR(in##offset##_max, S_IRUGO | S_IWUSR, \ show_in_##offset##_max, set_in_##offset##_max);show_in_reg(0);show_in_reg(1);show_in_reg(2);show_in_reg(3);show_in_reg(4);/* Temps */static ssize_t show_temp(struct device *dev, char *buf, int nr){ struct lm85_data *data = lm85_update_device(dev); return sprintf(buf,"%d\n", TEMP_FROM_REG(data->temp[nr]) );}static ssize_t show_temp_min(struct device *dev, char *buf, int nr){ struct lm85_data *data = lm85_update_device(dev); return sprintf(buf,"%d\n", TEMP_FROM_REG(data->temp_min[nr]) );}static ssize_t set_temp_min(struct device *dev, const char *buf, size_t count, int nr){ struct i2c_client *client = to_i2c_client(dev); struct lm85_data *data = i2c_get_clientdata(client); int val; down(&data->update_lock); val = simple_strtol(buf, NULL, 10); data->temp_min[nr] = TEMP_TO_REG(val); lm85_write_value(client, LM85_REG_TEMP_MIN(nr), data->temp_min[nr]); up(&data->update_lock); return count;}static ssize_t show_temp_max(struct device *dev, char *buf, int nr){ struct lm85_data *data = lm85_update_device(dev); return sprintf(buf,"%d\n", TEMP_FROM_REG(data->temp_max[nr]) );}static ssize_t set_temp_max(struct device *dev, const char *buf, size_t count, int nr){ struct i2c_client *client = to_i2c_client(dev); struct lm85_data *data = i2c_get_clientdata(client); int val; down(&data->update_lock); val = simple_strtol(buf, NULL, 10); data->temp_max[nr] = TEMP_TO_REG(val); lm85_write_value(client, LM85_REG_TEMP_MAX(nr), data->temp_max[nr]); up(&data->update_lock); return count;}#define show_temp_reg(offset) \static ssize_t show_temp_##offset (struct device *dev, char *buf) \{ \ return show_temp(dev, buf, 0x##offset - 1); \} \static ssize_t show_temp_##offset##_min (struct device *dev, char *buf) \{ \ return show_temp_min(dev, buf, 0x##offset - 1); \} \static ssize_t show_temp_##offset##_max (struct device *dev, char *buf) \{ \ return show_temp_max(dev, buf, 0x##offset - 1); \} \static ssize_t set_temp_##offset##_min (struct device *dev, \ const char *buf, size_t count) \{ \ return set_temp_min(dev, buf, count, 0x##offset - 1); \} \static ssize_t set_temp_##offset##_max (struct device *dev, \ const char *buf, size_t count) \{ \ return set_temp_max(dev, buf, count, 0x##offset - 1); \} \static DEVICE_ATTR(temp##offset##_input, S_IRUGO, show_temp_##offset, NULL); \static DEVICE_ATTR(temp##offset##_min, S_IRUGO | S_IWUSR, \ show_temp_##offset##_min, set_temp_##offset##_min); \static DEVICE_ATTR(temp##offset##_max, S_IRUGO | S_IWUSR, \ show_temp_##offset##_max, set_temp_##offset##_max);show_temp_reg(1);show_temp_reg(2);show_temp_reg(3);int lm85_attach_adapter(struct i2c_adapter *adapter){ return i2c_detect(adapter, &addr_data, lm85_detect);}int lm85_detect(struct i2c_adapter *adapter, int address, int kind){ int company, verstep ; struct i2c_client *new_client = NULL; struct lm85_data *data; int err = 0; const char *type_name = ""; if (i2c_is_isa_adapter(adapter)) { /* This chip has no ISA interface */ goto ERROR0 ; }; if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { /* We need to be able to do byte I/O */ goto ERROR0 ; }; /* 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 lm85_{read,write}_value. */ if (!(data = kmalloc(sizeof(struct lm85_data), GFP_KERNEL))) { err = -ENOMEM; goto ERROR0; } memset(data, 0, sizeof(struct lm85_data)); new_client = &data->client; i2c_set_clientdata(new_client, data); new_client->addr = address; new_client->adapter = adapter; new_client->driver = &lm85_driver; new_client->flags = 0; /* Now, we do the remaining detection. */ company = lm85_read_value(new_client, LM85_REG_COMPANY); verstep = lm85_read_value(new_client, LM85_REG_VERSTEP); dev_dbg(&adapter->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(&adapter->dev, "Autodetecting device at %d,0x%02x ...\n", i2c_adapter_id(adapter), address ); if( company == LM85_COMPANY_NATIONAL && verstep == LM85_VERSTEP_LM85C ) { kind = lm85c ; } else if( company == LM85_COMPANY_NATIONAL && verstep == LM85_VERSTEP_LM85B ) { kind = lm85b ; } else if( company == LM85_COMPANY_NATIONAL && (verstep & 0xf0) == LM85_VERSTEP_GENERIC ) { dev_err(&adapter->dev, "Unrecognized version/stepping 0x%02x" " Defaulting to LM85.\n", verstep); kind = any_chip ; } else if( company == LM85_COMPANY_ANALOG_DEV && verstep == LM85_VERSTEP_ADM1027 ) { kind = adm1027 ;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -