lm73.c (91bba688016be0ba87ecb9d80d6490c2ebc63b0d) | lm73.c (8c14d126ae2efbcd094b24e5413b8cbe1d2c01e4) |
---|---|
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> --- 25 unchanged lines hidden (view full) --- 34#define LM73_REG_CTRL 0x04 35#define LM73_REG_ID 0x07 36 37#define LM73_ID 0x9001 /* 0x0190, byte-swapped */ 38#define DRVNAME "lm73" 39#define LM73_TEMP_MIN (-256000 / 250) 40#define LM73_TEMP_MAX (255750 / 250) 41 | 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> --- 25 unchanged lines hidden (view full) --- 34#define LM73_REG_CTRL 0x04 35#define LM73_REG_ID 0x07 36 37#define LM73_ID 0x9001 /* 0x0190, byte-swapped */ 38#define DRVNAME "lm73" 39#define LM73_TEMP_MIN (-256000 / 250) 40#define LM73_TEMP_MAX (255750 / 250) 41 |
42/*-----------------------------------------------------------------------*/ | 42#define LM73_CTRL_RES_SHIFT 5 43#define LM73_CTRL_RES_MASK (BIT(5) | BIT(6)) 44#define LM73_CTRL_TO_MASK BIT(7) |
43 | 45 |
46static const unsigned short lm73_convrates[] = { 47 14, /* 11-bits (0.25000 C/LSB): RES1 Bit = 0, RES0 Bit = 0 */ 48 28, /* 12-bits (0.12500 C/LSB): RES1 Bit = 0, RES0 Bit = 1 */ 49 56, /* 13-bits (0.06250 C/LSB): RES1 Bit = 1, RES0 Bit = 0 */ 50 112, /* 14-bits (0.03125 C/LSB): RES1 Bit = 1, RES0 Bit = 1 */ 51}; |
|
44 | 52 |
53struct lm73_data { 54 struct device *hwmon_dev; 55 struct mutex lock; 56 u8 ctrl; /* control register value */ 57}; 58 59/*-----------------------------------------------------------------------*/ 60 |
|
45static ssize_t set_temp(struct device *dev, struct device_attribute *da, 46 const char *buf, size_t count) 47{ 48 struct sensor_device_attribute *attr = to_sensor_dev_attr(da); 49 struct i2c_client *client = to_i2c_client(dev); 50 long temp; 51 short value; 52 s32 err; --- 20 unchanged lines hidden (view full) --- 73 return err; 74 75 /* use integer division instead of equivalent right shift to 76 guarantee arithmetic shift and preserve the sign */ 77 temp = (((s16) err) * 250) / 32; 78 return scnprintf(buf, PAGE_SIZE, "%d\n", temp); 79} 80 | 61static ssize_t set_temp(struct device *dev, struct device_attribute *da, 62 const char *buf, size_t count) 63{ 64 struct sensor_device_attribute *attr = to_sensor_dev_attr(da); 65 struct i2c_client *client = to_i2c_client(dev); 66 long temp; 67 short value; 68 s32 err; --- 20 unchanged lines hidden (view full) --- 89 return err; 90 91 /* use integer division instead of equivalent right shift to 92 guarantee arithmetic shift and preserve the sign */ 93 temp = (((s16) err) * 250) / 32; 94 return scnprintf(buf, PAGE_SIZE, "%d\n", temp); 95} 96 |
97static ssize_t set_convrate(struct device *dev, struct device_attribute *da, 98 const char *buf, size_t count) 99{ 100 struct i2c_client *client = to_i2c_client(dev); 101 struct lm73_data *data = i2c_get_clientdata(client); 102 unsigned long convrate; 103 s32 err; 104 int res = 0; |
|
81 | 105 |
106 err = kstrtoul(buf, 10, &convrate); 107 if (err < 0) 108 return err; 109 110 /* 111 * Convert the desired conversion rate into register bits. 112 * res is already initialized, and everything past the second-to-last 113 * value in the array is treated as belonging to the last value 114 * in the array. 115 */ 116 while (res < (ARRAY_SIZE(lm73_convrates) - 1) && 117 convrate > lm73_convrates[res]) 118 res++; 119 120 mutex_lock(&data->lock); 121 data->ctrl &= LM73_CTRL_TO_MASK; 122 data->ctrl |= res << LM73_CTRL_RES_SHIFT; 123 err = i2c_smbus_write_byte_data(client, LM73_REG_CTRL, data->ctrl); 124 mutex_unlock(&data->lock); 125 126 if (err < 0) 127 return err; 128 129 return count; 130} 131 132static ssize_t show_convrate(struct device *dev, struct device_attribute *da, 133 char *buf) 134{ 135 struct i2c_client *client = to_i2c_client(dev); 136 struct lm73_data *data = i2c_get_clientdata(client); 137 int res; 138 139 res = (data->ctrl & LM73_CTRL_RES_MASK) >> LM73_CTRL_RES_SHIFT; 140 return scnprintf(buf, PAGE_SIZE, "%hu\n", lm73_convrates[res]); 141} 142 |
|
82/*-----------------------------------------------------------------------*/ 83 84/* sysfs attributes for hwmon */ 85 86static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, 87 show_temp, set_temp, LM73_REG_MAX); 88static SENSOR_DEVICE_ATTR(temp1_min, S_IWUSR | S_IRUGO, 89 show_temp, set_temp, LM73_REG_MIN); 90static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, 91 show_temp, NULL, LM73_REG_INPUT); | 143/*-----------------------------------------------------------------------*/ 144 145/* sysfs attributes for hwmon */ 146 147static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, 148 show_temp, set_temp, LM73_REG_MAX); 149static SENSOR_DEVICE_ATTR(temp1_min, S_IWUSR | S_IRUGO, 150 show_temp, set_temp, LM73_REG_MIN); 151static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, 152 show_temp, NULL, LM73_REG_INPUT); |
153static SENSOR_DEVICE_ATTR(update_interval, S_IWUSR | S_IRUGO, 154 show_convrate, set_convrate, 0); |
|
92 | 155 |
93 | |
94static struct attribute *lm73_attributes[] = { 95 &sensor_dev_attr_temp1_input.dev_attr.attr, 96 &sensor_dev_attr_temp1_max.dev_attr.attr, 97 &sensor_dev_attr_temp1_min.dev_attr.attr, | 156static struct attribute *lm73_attributes[] = { 157 &sensor_dev_attr_temp1_input.dev_attr.attr, 158 &sensor_dev_attr_temp1_max.dev_attr.attr, 159 &sensor_dev_attr_temp1_min.dev_attr.attr, |
98 | 160 &sensor_dev_attr_update_interval.dev_attr.attr, |
99 NULL 100}; 101 102static const struct attribute_group lm73_group = { 103 .attrs = lm73_attributes, 104}; 105 106/*-----------------------------------------------------------------------*/ 107 108/* device probe and removal */ 109 110static int 111lm73_probe(struct i2c_client *client, const struct i2c_device_id *id) 112{ | 161 NULL 162}; 163 164static const struct attribute_group lm73_group = { 165 .attrs = lm73_attributes, 166}; 167 168/*-----------------------------------------------------------------------*/ 169 170/* device probe and removal */ 171 172static int 173lm73_probe(struct i2c_client *client, const struct i2c_device_id *id) 174{ |
113 struct device *hwmon_dev; | |
114 int status; | 175 int status; |
176 struct lm73_data *data; 177 int ctrl; |
|
115 | 178 |
179 data = devm_kzalloc(&client->dev, sizeof(struct lm73_data), 180 GFP_KERNEL); 181 if (!data) 182 return -ENOMEM; 183 184 i2c_set_clientdata(client, data); 185 mutex_init(&data->lock); 186 187 ctrl = i2c_smbus_read_byte_data(client, LM73_REG_CTRL); 188 if (ctrl < 0) 189 return ctrl; 190 data->ctrl = ctrl; 191 |
|
116 /* Register sysfs hooks */ 117 status = sysfs_create_group(&client->dev.kobj, &lm73_group); 118 if (status) 119 return status; 120 | 192 /* Register sysfs hooks */ 193 status = sysfs_create_group(&client->dev.kobj, &lm73_group); 194 if (status) 195 return status; 196 |
121 hwmon_dev = hwmon_device_register(&client->dev); 122 if (IS_ERR(hwmon_dev)) { 123 status = PTR_ERR(hwmon_dev); | 197 data->hwmon_dev = hwmon_device_register(&client->dev); 198 if (IS_ERR(data->hwmon_dev)) { 199 status = PTR_ERR(data->hwmon_dev); |
124 goto exit_remove; 125 } | 200 goto exit_remove; 201 } |
126 i2c_set_clientdata(client, hwmon_dev); | |
127 128 dev_info(&client->dev, "%s: sensor '%s'\n", | 202 203 dev_info(&client->dev, "%s: sensor '%s'\n", |
129 dev_name(hwmon_dev), client->name); | 204 dev_name(data->hwmon_dev), client->name); |
130 131 return 0; 132 133exit_remove: 134 sysfs_remove_group(&client->dev.kobj, &lm73_group); 135 return status; 136} 137 138static int lm73_remove(struct i2c_client *client) 139{ | 205 206 return 0; 207 208exit_remove: 209 sysfs_remove_group(&client->dev.kobj, &lm73_group); 210 return status; 211} 212 213static int lm73_remove(struct i2c_client *client) 214{ |
140 struct device *hwmon_dev = i2c_get_clientdata(client); | 215 struct lm73_data *data = i2c_get_clientdata(client); |
141 | 216 |
142 hwmon_device_unregister(hwmon_dev); | 217 hwmon_device_unregister(data->hwmon_dev); |
143 sysfs_remove_group(&client->dev.kobj, &lm73_group); 144 return 0; 145} 146 147static const struct i2c_device_id lm73_ids[] = { 148 { "lm73", 0 }, 149 { /* LIST END */ } 150}; --- 56 unchanged lines hidden --- | 218 sysfs_remove_group(&client->dev.kobj, &lm73_group); 219 return 0; 220} 221 222static const struct i2c_device_id lm73_ids[] = { 223 { "lm73", 0 }, 224 { /* LIST END */ } 225}; --- 56 unchanged lines hidden --- |