diff options
Diffstat (limited to 'drivers/hwmon/hp_accel.c')
-rw-r--r-- | drivers/hwmon/hp_accel.c | 99 |
1 files changed, 38 insertions, 61 deletions
diff --git a/drivers/hwmon/hp_accel.c b/drivers/hwmon/hp_accel.c index de26b1c3a96c..55d3dc565be6 100644 --- a/drivers/hwmon/hp_accel.c +++ b/drivers/hwmon/hp_accel.c | |||
@@ -85,25 +85,31 @@ MODULE_DEVICE_TABLE(acpi, lis3lv02d_device_ids); | |||
85 | 85 | ||
86 | /** | 86 | /** |
87 | * lis3lv02d_acpi_init - ACPI _INI method: initialize the device. | 87 | * lis3lv02d_acpi_init - ACPI _INI method: initialize the device. |
88 | * @handle: the handle of the device | 88 | * @lis3: pointer to the device struct |
89 | * | 89 | * |
90 | * Returns AE_OK on success. | 90 | * Returns 0 on success. |
91 | */ | 91 | */ |
92 | acpi_status lis3lv02d_acpi_init(acpi_handle handle) | 92 | int lis3lv02d_acpi_init(struct lis3lv02d *lis3) |
93 | { | 93 | { |
94 | return acpi_evaluate_object(handle, METHOD_NAME__INI, NULL, NULL); | 94 | struct acpi_device *dev = lis3->bus_priv; |
95 | if (acpi_evaluate_object(dev->handle, METHOD_NAME__INI, | ||
96 | NULL, NULL) != AE_OK) | ||
97 | return -EINVAL; | ||
98 | |||
99 | return 0; | ||
95 | } | 100 | } |
96 | 101 | ||
97 | /** | 102 | /** |
98 | * lis3lv02d_acpi_read - ACPI ALRD method: read a register | 103 | * lis3lv02d_acpi_read - ACPI ALRD method: read a register |
99 | * @handle: the handle of the device | 104 | * @lis3: pointer to the device struct |
100 | * @reg: the register to read | 105 | * @reg: the register to read |
101 | * @ret: result of the operation | 106 | * @ret: result of the operation |
102 | * | 107 | * |
103 | * Returns AE_OK on success. | 108 | * Returns 0 on success. |
104 | */ | 109 | */ |
105 | acpi_status lis3lv02d_acpi_read(acpi_handle handle, int reg, u8 *ret) | 110 | int lis3lv02d_acpi_read(struct lis3lv02d *lis3, int reg, u8 *ret) |
106 | { | 111 | { |
112 | struct acpi_device *dev = lis3->bus_priv; | ||
107 | union acpi_object arg0 = { ACPI_TYPE_INTEGER }; | 113 | union acpi_object arg0 = { ACPI_TYPE_INTEGER }; |
108 | struct acpi_object_list args = { 1, &arg0 }; | 114 | struct acpi_object_list args = { 1, &arg0 }; |
109 | unsigned long long lret; | 115 | unsigned long long lret; |
@@ -111,21 +117,22 @@ acpi_status lis3lv02d_acpi_read(acpi_handle handle, int reg, u8 *ret) | |||
111 | 117 | ||
112 | arg0.integer.value = reg; | 118 | arg0.integer.value = reg; |
113 | 119 | ||
114 | status = acpi_evaluate_integer(handle, "ALRD", &args, &lret); | 120 | status = acpi_evaluate_integer(dev->handle, "ALRD", &args, &lret); |
115 | *ret = lret; | 121 | *ret = lret; |
116 | return status; | 122 | return (status != AE_OK) ? -EINVAL : 0; |
117 | } | 123 | } |
118 | 124 | ||
119 | /** | 125 | /** |
120 | * lis3lv02d_acpi_write - ACPI ALWR method: write to a register | 126 | * lis3lv02d_acpi_write - ACPI ALWR method: write to a register |
121 | * @handle: the handle of the device | 127 | * @lis3: pointer to the device struct |
122 | * @reg: the register to write to | 128 | * @reg: the register to write to |
123 | * @val: the value to write | 129 | * @val: the value to write |
124 | * | 130 | * |
125 | * Returns AE_OK on success. | 131 | * Returns 0 on success. |
126 | */ | 132 | */ |
127 | acpi_status lis3lv02d_acpi_write(acpi_handle handle, int reg, u8 val) | 133 | int lis3lv02d_acpi_write(struct lis3lv02d *lis3, int reg, u8 val) |
128 | { | 134 | { |
135 | struct acpi_device *dev = lis3->bus_priv; | ||
129 | unsigned long long ret; /* Not used when writting */ | 136 | unsigned long long ret; /* Not used when writting */ |
130 | union acpi_object in_obj[2]; | 137 | union acpi_object in_obj[2]; |
131 | struct acpi_object_list args = { 2, in_obj }; | 138 | struct acpi_object_list args = { 2, in_obj }; |
@@ -135,7 +142,10 @@ acpi_status lis3lv02d_acpi_write(acpi_handle handle, int reg, u8 val) | |||
135 | in_obj[1].type = ACPI_TYPE_INTEGER; | 142 | in_obj[1].type = ACPI_TYPE_INTEGER; |
136 | in_obj[1].integer.value = val; | 143 | in_obj[1].integer.value = val; |
137 | 144 | ||
138 | return acpi_evaluate_integer(handle, "ALWR", &args, &ret); | 145 | if (acpi_evaluate_integer(dev->handle, "ALWR", &args, &ret) != AE_OK) |
146 | return -EINVAL; | ||
147 | |||
148 | return 0; | ||
139 | } | 149 | } |
140 | 150 | ||
141 | static int lis3lv02d_dmi_matched(const struct dmi_system_id *dmi) | 151 | static int lis3lv02d_dmi_matched(const struct dmi_system_id *dmi) |
@@ -217,7 +227,7 @@ static struct dmi_system_id lis3lv02d_dmi_ids[] = { | |||
217 | 227 | ||
218 | static void hpled_set(struct delayed_led_classdev *led_cdev, enum led_brightness value) | 228 | static void hpled_set(struct delayed_led_classdev *led_cdev, enum led_brightness value) |
219 | { | 229 | { |
220 | acpi_handle handle = lis3_dev.device->handle; | 230 | struct acpi_device *dev = lis3_dev.bus_priv; |
221 | unsigned long long ret; /* Not used when writing */ | 231 | unsigned long long ret; /* Not used when writing */ |
222 | union acpi_object in_obj[1]; | 232 | union acpi_object in_obj[1]; |
223 | struct acpi_object_list args = { 1, in_obj }; | 233 | struct acpi_object_list args = { 1, in_obj }; |
@@ -225,7 +235,7 @@ static void hpled_set(struct delayed_led_classdev *led_cdev, enum led_brightness | |||
225 | in_obj[0].type = ACPI_TYPE_INTEGER; | 235 | in_obj[0].type = ACPI_TYPE_INTEGER; |
226 | in_obj[0].integer.value = !!value; | 236 | in_obj[0].integer.value = !!value; |
227 | 237 | ||
228 | acpi_evaluate_integer(handle, "ALED", &args, &ret); | 238 | acpi_evaluate_integer(dev->handle, "ALED", &args, &ret); |
229 | } | 239 | } |
230 | 240 | ||
231 | static struct delayed_led_classdev hpled_led = { | 241 | static struct delayed_led_classdev hpled_led = { |
@@ -262,23 +272,6 @@ static void lis3lv02d_enum_resources(struct acpi_device *device) | |||
262 | printk(KERN_DEBUG DRIVER_NAME ": Error getting resources\n"); | 272 | printk(KERN_DEBUG DRIVER_NAME ": Error getting resources\n"); |
263 | } | 273 | } |
264 | 274 | ||
265 | static s16 lis3lv02d_read_16(acpi_handle handle, int reg) | ||
266 | { | ||
267 | u8 lo, hi; | ||
268 | |||
269 | lis3_dev.read(handle, reg - 1, &lo); | ||
270 | lis3_dev.read(handle, reg, &hi); | ||
271 | /* In "12 bit right justified" mode, bit 6, bit 7, bit 8 = bit 5 */ | ||
272 | return (s16)((hi << 8) | lo); | ||
273 | } | ||
274 | |||
275 | static s16 lis3lv02d_read_8(acpi_handle handle, int reg) | ||
276 | { | ||
277 | s8 lo; | ||
278 | lis3_dev.read(handle, reg, &lo); | ||
279 | return lo; | ||
280 | } | ||
281 | |||
282 | static int lis3lv02d_add(struct acpi_device *device) | 275 | static int lis3lv02d_add(struct acpi_device *device) |
283 | { | 276 | { |
284 | int ret; | 277 | int ret; |
@@ -286,7 +279,7 @@ static int lis3lv02d_add(struct acpi_device *device) | |||
286 | if (!device) | 279 | if (!device) |
287 | return -EINVAL; | 280 | return -EINVAL; |
288 | 281 | ||
289 | lis3_dev.device = device; | 282 | lis3_dev.bus_priv = device; |
290 | lis3_dev.init = lis3lv02d_acpi_init; | 283 | lis3_dev.init = lis3lv02d_acpi_init; |
291 | lis3_dev.read = lis3lv02d_acpi_read; | 284 | lis3_dev.read = lis3lv02d_acpi_read; |
292 | lis3_dev.write = lis3lv02d_acpi_write; | 285 | lis3_dev.write = lis3lv02d_acpi_write; |
@@ -294,23 +287,8 @@ static int lis3lv02d_add(struct acpi_device *device) | |||
294 | strcpy(acpi_device_class(device), ACPI_MDPS_CLASS); | 287 | strcpy(acpi_device_class(device), ACPI_MDPS_CLASS); |
295 | device->driver_data = &lis3_dev; | 288 | device->driver_data = &lis3_dev; |
296 | 289 | ||
297 | lis3lv02d_acpi_read(device->handle, WHO_AM_I, &lis3_dev.whoami); | 290 | /* obtain IRQ number of our device from ACPI */ |
298 | switch (lis3_dev.whoami) { | 291 | lis3lv02d_enum_resources(device); |
299 | case LIS_DOUBLE_ID: | ||
300 | printk(KERN_INFO DRIVER_NAME ": 2-byte sensor found\n"); | ||
301 | lis3_dev.read_data = lis3lv02d_read_16; | ||
302 | lis3_dev.mdps_max_val = 2048; | ||
303 | break; | ||
304 | case LIS_SINGLE_ID: | ||
305 | printk(KERN_INFO DRIVER_NAME ": 1-byte sensor found\n"); | ||
306 | lis3_dev.read_data = lis3lv02d_read_8; | ||
307 | lis3_dev.mdps_max_val = 128; | ||
308 | break; | ||
309 | default: | ||
310 | printk(KERN_ERR DRIVER_NAME | ||
311 | ": unknown sensor type 0x%X\n", lis3_dev.whoami); | ||
312 | return -EINVAL; | ||
313 | } | ||
314 | 292 | ||
315 | /* If possible use a "standard" axes order */ | 293 | /* If possible use a "standard" axes order */ |
316 | if (dmi_check_system(lis3lv02d_dmi_ids) == 0) { | 294 | if (dmi_check_system(lis3lv02d_dmi_ids) == 0) { |
@@ -319,18 +297,17 @@ static int lis3lv02d_add(struct acpi_device *device) | |||
319 | lis3_dev.ac = lis3lv02d_axis_normal; | 297 | lis3_dev.ac = lis3lv02d_axis_normal; |
320 | } | 298 | } |
321 | 299 | ||
322 | INIT_WORK(&hpled_led.work, delayed_set_status_worker); | 300 | /* call the core layer do its init */ |
323 | ret = led_classdev_register(NULL, &hpled_led.led_classdev); | 301 | ret = lis3lv02d_init_device(&lis3_dev); |
324 | if (ret) | 302 | if (ret) |
325 | return ret; | 303 | return ret; |
326 | 304 | ||
327 | /* obtain IRQ number of our device from ACPI */ | 305 | INIT_WORK(&hpled_led.work, delayed_set_status_worker); |
328 | lis3lv02d_enum_resources(lis3_dev.device); | 306 | ret = led_classdev_register(NULL, &hpled_led.led_classdev); |
329 | |||
330 | ret = lis3lv02d_init_device(&lis3_dev); | ||
331 | if (ret) { | 307 | if (ret) { |
308 | lis3lv02d_joystick_disable(); | ||
309 | lis3lv02d_poweroff(&lis3_dev); | ||
332 | flush_work(&hpled_led.work); | 310 | flush_work(&hpled_led.work); |
333 | led_classdev_unregister(&hpled_led.led_classdev); | ||
334 | return ret; | 311 | return ret; |
335 | } | 312 | } |
336 | 313 | ||
@@ -343,7 +320,7 @@ static int lis3lv02d_remove(struct acpi_device *device, int type) | |||
343 | return -EINVAL; | 320 | return -EINVAL; |
344 | 321 | ||
345 | lis3lv02d_joystick_disable(); | 322 | lis3lv02d_joystick_disable(); |
346 | lis3lv02d_poweroff(device->handle); | 323 | lis3lv02d_poweroff(&lis3_dev); |
347 | 324 | ||
348 | flush_work(&hpled_led.work); | 325 | flush_work(&hpled_led.work); |
349 | led_classdev_unregister(&hpled_led.led_classdev); | 326 | led_classdev_unregister(&hpled_led.led_classdev); |
@@ -356,7 +333,7 @@ static int lis3lv02d_remove(struct acpi_device *device, int type) | |||
356 | static int lis3lv02d_suspend(struct acpi_device *device, pm_message_t state) | 333 | static int lis3lv02d_suspend(struct acpi_device *device, pm_message_t state) |
357 | { | 334 | { |
358 | /* make sure the device is off when we suspend */ | 335 | /* make sure the device is off when we suspend */ |
359 | lis3lv02d_poweroff(device->handle); | 336 | lis3lv02d_poweroff(&lis3_dev); |
360 | return 0; | 337 | return 0; |
361 | } | 338 | } |
362 | 339 | ||
@@ -365,9 +342,9 @@ static int lis3lv02d_resume(struct acpi_device *device) | |||
365 | /* put back the device in the right state (ACPI might turn it on) */ | 342 | /* put back the device in the right state (ACPI might turn it on) */ |
366 | mutex_lock(&lis3_dev.lock); | 343 | mutex_lock(&lis3_dev.lock); |
367 | if (lis3_dev.usage > 0) | 344 | if (lis3_dev.usage > 0) |
368 | lis3lv02d_poweron(device->handle); | 345 | lis3lv02d_poweron(&lis3_dev); |
369 | else | 346 | else |
370 | lis3lv02d_poweroff(device->handle); | 347 | lis3lv02d_poweroff(&lis3_dev); |
371 | mutex_unlock(&lis3_dev.lock); | 348 | mutex_unlock(&lis3_dev.lock); |
372 | return 0; | 349 | return 0; |
373 | } | 350 | } |