lm73.c (bf61c8840efe60fd8f91446860b63338fb424158) | lm73.c (3710263f136e629af1e4bae8df1c02b7fdec6260) |
---|---|
1/* 2 * LM73 Sensor driver 3 * Based on LM75 4 * 5 * Copyright (C) 2007, CenoSYS (www.cenosys.com). 6 * Copyright (C) 2009, Bollore telecom (www.bolloretelecom.eu). 7 * 8 * Guillaume Ligneul <guillaume.ligneul@gmail.com> --- 41 unchanged lines hidden (view full) --- 50static const unsigned short lm73_convrates[] = { 51 14, /* 11-bits (0.25000 C/LSB): RES1 Bit = 0, RES0 Bit = 0 */ 52 28, /* 12-bits (0.12500 C/LSB): RES1 Bit = 0, RES0 Bit = 1 */ 53 56, /* 13-bits (0.06250 C/LSB): RES1 Bit = 1, RES0 Bit = 0 */ 54 112, /* 14-bits (0.03125 C/LSB): RES1 Bit = 1, RES0 Bit = 1 */ 55}; 56 57struct lm73_data { | 1/* 2 * LM73 Sensor driver 3 * Based on LM75 4 * 5 * Copyright (C) 2007, CenoSYS (www.cenosys.com). 6 * Copyright (C) 2009, Bollore telecom (www.bolloretelecom.eu). 7 * 8 * Guillaume Ligneul <guillaume.ligneul@gmail.com> --- 41 unchanged lines hidden (view full) --- 50static const unsigned short lm73_convrates[] = { 51 14, /* 11-bits (0.25000 C/LSB): RES1 Bit = 0, RES0 Bit = 0 */ 52 28, /* 12-bits (0.12500 C/LSB): RES1 Bit = 0, RES0 Bit = 1 */ 53 56, /* 13-bits (0.06250 C/LSB): RES1 Bit = 1, RES0 Bit = 0 */ 54 112, /* 14-bits (0.03125 C/LSB): RES1 Bit = 1, RES0 Bit = 1 */ 55}; 56 57struct lm73_data { |
58 struct device *hwmon_dev; | 58 struct i2c_client *client; |
59 struct mutex lock; 60 u8 ctrl; /* control register value */ 61}; 62 63/*-----------------------------------------------------------------------*/ 64 65static ssize_t set_temp(struct device *dev, struct device_attribute *da, 66 const char *buf, size_t count) 67{ 68 struct sensor_device_attribute *attr = to_sensor_dev_attr(da); | 59 struct mutex lock; 60 u8 ctrl; /* control register value */ 61}; 62 63/*-----------------------------------------------------------------------*/ 64 65static ssize_t set_temp(struct device *dev, struct device_attribute *da, 66 const char *buf, size_t count) 67{ 68 struct sensor_device_attribute *attr = to_sensor_dev_attr(da); |
69 struct i2c_client *client = to_i2c_client(dev); | 69 struct lm73_data *data = dev_get_drvdata(dev); |
70 long temp; 71 short value; 72 s32 err; 73 74 int status = kstrtol(buf, 10, &temp); 75 if (status < 0) 76 return status; 77 78 /* Write value */ 79 value = clamp_val(temp / 250, LM73_TEMP_MIN, LM73_TEMP_MAX) << 5; | 70 long temp; 71 short value; 72 s32 err; 73 74 int status = kstrtol(buf, 10, &temp); 75 if (status < 0) 76 return status; 77 78 /* Write value */ 79 value = clamp_val(temp / 250, LM73_TEMP_MIN, LM73_TEMP_MAX) << 5; |
80 err = i2c_smbus_write_word_swapped(client, attr->index, value); | 80 err = i2c_smbus_write_word_swapped(data->client, attr->index, value); |
81 return (err < 0) ? err : count; 82} 83 84static ssize_t show_temp(struct device *dev, struct device_attribute *da, 85 char *buf) 86{ 87 struct sensor_device_attribute *attr = to_sensor_dev_attr(da); | 81 return (err < 0) ? err : count; 82} 83 84static ssize_t show_temp(struct device *dev, struct device_attribute *da, 85 char *buf) 86{ 87 struct sensor_device_attribute *attr = to_sensor_dev_attr(da); |
88 struct i2c_client *client = to_i2c_client(dev); | 88 struct lm73_data *data = dev_get_drvdata(dev); |
89 int temp; 90 | 89 int temp; 90 |
91 s32 err = i2c_smbus_read_word_swapped(client, attr->index); | 91 s32 err = i2c_smbus_read_word_swapped(data->client, attr->index); |
92 if (err < 0) 93 return err; 94 95 /* use integer division instead of equivalent right shift to 96 guarantee arithmetic shift and preserve the sign */ 97 temp = (((s16) err) * 250) / 32; 98 return scnprintf(buf, PAGE_SIZE, "%d\n", temp); 99} 100 101static ssize_t set_convrate(struct device *dev, struct device_attribute *da, 102 const char *buf, size_t count) 103{ | 92 if (err < 0) 93 return err; 94 95 /* use integer division instead of equivalent right shift to 96 guarantee arithmetic shift and preserve the sign */ 97 temp = (((s16) err) * 250) / 32; 98 return scnprintf(buf, PAGE_SIZE, "%d\n", temp); 99} 100 101static ssize_t set_convrate(struct device *dev, struct device_attribute *da, 102 const char *buf, size_t count) 103{ |
104 struct i2c_client *client = to_i2c_client(dev); 105 struct lm73_data *data = i2c_get_clientdata(client); | 104 struct lm73_data *data = dev_get_drvdata(dev); |
106 unsigned long convrate; 107 s32 err; 108 int res = 0; 109 110 err = kstrtoul(buf, 10, &convrate); 111 if (err < 0) 112 return err; 113 --- 5 unchanged lines hidden (view full) --- 119 */ 120 while (res < (ARRAY_SIZE(lm73_convrates) - 1) && 121 convrate > lm73_convrates[res]) 122 res++; 123 124 mutex_lock(&data->lock); 125 data->ctrl &= LM73_CTRL_TO_MASK; 126 data->ctrl |= res << LM73_CTRL_RES_SHIFT; | 105 unsigned long convrate; 106 s32 err; 107 int res = 0; 108 109 err = kstrtoul(buf, 10, &convrate); 110 if (err < 0) 111 return err; 112 --- 5 unchanged lines hidden (view full) --- 118 */ 119 while (res < (ARRAY_SIZE(lm73_convrates) - 1) && 120 convrate > lm73_convrates[res]) 121 res++; 122 123 mutex_lock(&data->lock); 124 data->ctrl &= LM73_CTRL_TO_MASK; 125 data->ctrl |= res << LM73_CTRL_RES_SHIFT; |
127 err = i2c_smbus_write_byte_data(client, LM73_REG_CTRL, data->ctrl); | 126 err = i2c_smbus_write_byte_data(data->client, LM73_REG_CTRL, 127 data->ctrl); |
128 mutex_unlock(&data->lock); 129 130 if (err < 0) 131 return err; 132 133 return count; 134} 135 136static ssize_t show_convrate(struct device *dev, struct device_attribute *da, 137 char *buf) 138{ | 128 mutex_unlock(&data->lock); 129 130 if (err < 0) 131 return err; 132 133 return count; 134} 135 136static ssize_t show_convrate(struct device *dev, struct device_attribute *da, 137 char *buf) 138{ |
139 struct i2c_client *client = to_i2c_client(dev); 140 struct lm73_data *data = i2c_get_clientdata(client); | 139 struct lm73_data *data = dev_get_drvdata(dev); |
141 int res; 142 143 res = (data->ctrl & LM73_CTRL_RES_MASK) >> LM73_CTRL_RES_SHIFT; 144 return scnprintf(buf, PAGE_SIZE, "%hu\n", lm73_convrates[res]); 145} 146 147static ssize_t show_maxmin_alarm(struct device *dev, 148 struct device_attribute *da, char *buf) 149{ | 140 int res; 141 142 res = (data->ctrl & LM73_CTRL_RES_MASK) >> LM73_CTRL_RES_SHIFT; 143 return scnprintf(buf, PAGE_SIZE, "%hu\n", lm73_convrates[res]); 144} 145 146static ssize_t show_maxmin_alarm(struct device *dev, 147 struct device_attribute *da, char *buf) 148{ |
150 struct i2c_client *client = to_i2c_client(dev); | |
151 struct sensor_device_attribute *attr = to_sensor_dev_attr(da); | 149 struct sensor_device_attribute *attr = to_sensor_dev_attr(da); |
152 struct lm73_data *data = i2c_get_clientdata(client); | 150 struct lm73_data *data = dev_get_drvdata(dev); |
153 s32 ctrl; 154 155 mutex_lock(&data->lock); | 151 s32 ctrl; 152 153 mutex_lock(&data->lock); |
156 ctrl = i2c_smbus_read_byte_data(client, LM73_REG_CTRL); | 154 ctrl = i2c_smbus_read_byte_data(data->client, LM73_REG_CTRL); |
157 if (ctrl < 0) 158 goto abort; 159 data->ctrl = ctrl; 160 mutex_unlock(&data->lock); 161 162 return scnprintf(buf, PAGE_SIZE, "%d\n", (ctrl >> attr->index) & 1); 163 164abort: --- 13 unchanged lines hidden (view full) --- 178 show_temp, NULL, LM73_REG_INPUT); 179static SENSOR_DEVICE_ATTR(update_interval, S_IWUSR | S_IRUGO, 180 show_convrate, set_convrate, 0); 181static SENSOR_DEVICE_ATTR(temp1_max_alarm, S_IRUGO, 182 show_maxmin_alarm, NULL, LM73_CTRL_HI_SHIFT); 183static SENSOR_DEVICE_ATTR(temp1_min_alarm, S_IRUGO, 184 show_maxmin_alarm, NULL, LM73_CTRL_LO_SHIFT); 185 | 155 if (ctrl < 0) 156 goto abort; 157 data->ctrl = ctrl; 158 mutex_unlock(&data->lock); 159 160 return scnprintf(buf, PAGE_SIZE, "%d\n", (ctrl >> attr->index) & 1); 161 162abort: --- 13 unchanged lines hidden (view full) --- 176 show_temp, NULL, LM73_REG_INPUT); 177static SENSOR_DEVICE_ATTR(update_interval, S_IWUSR | S_IRUGO, 178 show_convrate, set_convrate, 0); 179static SENSOR_DEVICE_ATTR(temp1_max_alarm, S_IRUGO, 180 show_maxmin_alarm, NULL, LM73_CTRL_HI_SHIFT); 181static SENSOR_DEVICE_ATTR(temp1_min_alarm, S_IRUGO, 182 show_maxmin_alarm, NULL, LM73_CTRL_LO_SHIFT); 183 |
186static struct attribute *lm73_attributes[] = { | 184static struct attribute *lm73_attrs[] = { |
187 &sensor_dev_attr_temp1_input.dev_attr.attr, 188 &sensor_dev_attr_temp1_max.dev_attr.attr, 189 &sensor_dev_attr_temp1_min.dev_attr.attr, 190 &sensor_dev_attr_update_interval.dev_attr.attr, 191 &sensor_dev_attr_temp1_max_alarm.dev_attr.attr, 192 &sensor_dev_attr_temp1_min_alarm.dev_attr.attr, 193 NULL 194}; | 185 &sensor_dev_attr_temp1_input.dev_attr.attr, 186 &sensor_dev_attr_temp1_max.dev_attr.attr, 187 &sensor_dev_attr_temp1_min.dev_attr.attr, 188 &sensor_dev_attr_update_interval.dev_attr.attr, 189 &sensor_dev_attr_temp1_max_alarm.dev_attr.attr, 190 &sensor_dev_attr_temp1_min_alarm.dev_attr.attr, 191 NULL 192}; |
193ATTRIBUTE_GROUPS(lm73); |
|
195 | 194 |
196static const struct attribute_group lm73_group = { 197 .attrs = lm73_attributes, 198}; 199 | |
200/*-----------------------------------------------------------------------*/ 201 202/* device probe and removal */ 203 204static int 205lm73_probe(struct i2c_client *client, const struct i2c_device_id *id) 206{ | 195/*-----------------------------------------------------------------------*/ 196 197/* device probe and removal */ 198 199static int 200lm73_probe(struct i2c_client *client, const struct i2c_device_id *id) 201{ |
207 int status; | 202 struct device *dev = &client->dev; 203 struct device *hwmon_dev; |
208 struct lm73_data *data; 209 int ctrl; 210 | 204 struct lm73_data *data; 205 int ctrl; 206 |
211 data = devm_kzalloc(&client->dev, sizeof(struct lm73_data), 212 GFP_KERNEL); | 207 data = devm_kzalloc(dev, sizeof(struct lm73_data), GFP_KERNEL); |
213 if (!data) 214 return -ENOMEM; 215 | 208 if (!data) 209 return -ENOMEM; 210 |
216 i2c_set_clientdata(client, data); | 211 data->client = client; |
217 mutex_init(&data->lock); 218 219 ctrl = i2c_smbus_read_byte_data(client, LM73_REG_CTRL); 220 if (ctrl < 0) 221 return ctrl; 222 data->ctrl = ctrl; 223 | 212 mutex_init(&data->lock); 213 214 ctrl = i2c_smbus_read_byte_data(client, LM73_REG_CTRL); 215 if (ctrl < 0) 216 return ctrl; 217 data->ctrl = ctrl; 218 |
224 /* Register sysfs hooks */ 225 status = sysfs_create_group(&client->dev.kobj, &lm73_group); 226 if (status) 227 return status; | 219 hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name, 220 data, lm73_groups); 221 if (IS_ERR(hwmon_dev)) 222 return PTR_ERR(hwmon_dev); |
228 | 223 |
229 data->hwmon_dev = hwmon_device_register(&client->dev); 230 if (IS_ERR(data->hwmon_dev)) { 231 status = PTR_ERR(data->hwmon_dev); 232 goto exit_remove; 233 } | 224 dev_info(dev, "sensor '%s'\n", client->name); |
234 | 225 |
235 dev_info(&client->dev, "%s: sensor '%s'\n", 236 dev_name(data->hwmon_dev), client->name); 237 | |
238 return 0; | 226 return 0; |
239 240exit_remove: 241 sysfs_remove_group(&client->dev.kobj, &lm73_group); 242 return status; | |
243} 244 | 227} 228 |
245static int lm73_remove(struct i2c_client *client) 246{ 247 struct lm73_data *data = i2c_get_clientdata(client); 248 249 hwmon_device_unregister(data->hwmon_dev); 250 sysfs_remove_group(&client->dev.kobj, &lm73_group); 251 return 0; 252} 253 | |
254static const struct i2c_device_id lm73_ids[] = { 255 { "lm73", 0 }, 256 { /* LIST END */ } 257}; 258MODULE_DEVICE_TABLE(i2c, lm73_ids); 259 260/* Return 0 if detection is successful, -ENODEV otherwise */ 261static int lm73_detect(struct i2c_client *new_client, --- 33 unchanged lines hidden (view full) --- 295} 296 297static struct i2c_driver lm73_driver = { 298 .class = I2C_CLASS_HWMON, 299 .driver = { 300 .name = "lm73", 301 }, 302 .probe = lm73_probe, | 229static const struct i2c_device_id lm73_ids[] = { 230 { "lm73", 0 }, 231 { /* LIST END */ } 232}; 233MODULE_DEVICE_TABLE(i2c, lm73_ids); 234 235/* Return 0 if detection is successful, -ENODEV otherwise */ 236static int lm73_detect(struct i2c_client *new_client, --- 33 unchanged lines hidden (view full) --- 270} 271 272static struct i2c_driver lm73_driver = { 273 .class = I2C_CLASS_HWMON, 274 .driver = { 275 .name = "lm73", 276 }, 277 .probe = lm73_probe, |
303 .remove = lm73_remove, | |
304 .id_table = lm73_ids, 305 .detect = lm73_detect, 306 .address_list = normal_i2c, 307}; 308 309module_i2c_driver(lm73_driver); 310 311MODULE_AUTHOR("Guillaume Ligneul <guillaume.ligneul@gmail.com>"); 312MODULE_DESCRIPTION("LM73 driver"); 313MODULE_LICENSE("GPL"); | 278 .id_table = lm73_ids, 279 .detect = lm73_detect, 280 .address_list = normal_i2c, 281}; 282 283module_i2c_driver(lm73_driver); 284 285MODULE_AUTHOR("Guillaume Ligneul <guillaume.ligneul@gmail.com>"); 286MODULE_DESCRIPTION("LM73 driver"); 287MODULE_LICENSE("GPL"); |