diff options
Diffstat (limited to 'drivers/hwmon/lis3lv02d.c')
-rw-r--r-- | drivers/hwmon/lis3lv02d.c | 288 |
1 files changed, 162 insertions, 126 deletions
diff --git a/drivers/hwmon/lis3lv02d.c b/drivers/hwmon/lis3lv02d.c index 8bb2158f0453..778eb7795983 100644 --- a/drivers/hwmon/lis3lv02d.c +++ b/drivers/hwmon/lis3lv02d.c | |||
@@ -36,7 +36,6 @@ | |||
36 | #include <linux/freezer.h> | 36 | #include <linux/freezer.h> |
37 | #include <linux/uaccess.h> | 37 | #include <linux/uaccess.h> |
38 | #include <linux/miscdevice.h> | 38 | #include <linux/miscdevice.h> |
39 | #include <acpi/acpi_drivers.h> | ||
40 | #include <asm/atomic.h> | 39 | #include <asm/atomic.h> |
41 | #include "lis3lv02d.h" | 40 | #include "lis3lv02d.h" |
42 | 41 | ||
@@ -53,13 +52,30 @@ | |||
53 | * joystick. | 52 | * joystick. |
54 | */ | 53 | */ |
55 | 54 | ||
56 | struct acpi_lis3lv02d adev = { | 55 | struct lis3lv02d lis3_dev = { |
57 | .misc_wait = __WAIT_QUEUE_HEAD_INITIALIZER(adev.misc_wait), | 56 | .misc_wait = __WAIT_QUEUE_HEAD_INITIALIZER(lis3_dev.misc_wait), |
58 | }; | 57 | }; |
59 | 58 | ||
60 | EXPORT_SYMBOL_GPL(adev); | 59 | EXPORT_SYMBOL_GPL(lis3_dev); |
61 | 60 | ||
62 | static int lis3lv02d_add_fs(struct acpi_device *device); | 61 | static s16 lis3lv02d_read_8(struct lis3lv02d *lis3, int reg) |
62 | { | ||
63 | s8 lo; | ||
64 | if (lis3->read(lis3, reg, &lo) < 0) | ||
65 | return 0; | ||
66 | |||
67 | return lo; | ||
68 | } | ||
69 | |||
70 | static s16 lis3lv02d_read_16(struct lis3lv02d *lis3, int reg) | ||
71 | { | ||
72 | u8 lo, hi; | ||
73 | |||
74 | lis3->read(lis3, reg - 1, &lo); | ||
75 | lis3->read(lis3, reg, &hi); | ||
76 | /* In "12 bit right justified" mode, bit 6, bit 7, bit 8 = bit 5 */ | ||
77 | return (s16)((hi << 8) | lo); | ||
78 | } | ||
63 | 79 | ||
64 | /** | 80 | /** |
65 | * lis3lv02d_get_axis - For the given axis, give the value converted | 81 | * lis3lv02d_get_axis - For the given axis, give the value converted |
@@ -78,36 +94,36 @@ static inline int lis3lv02d_get_axis(s8 axis, int hw_values[3]) | |||
78 | 94 | ||
79 | /** | 95 | /** |
80 | * lis3lv02d_get_xyz - Get X, Y and Z axis values from the accelerometer | 96 | * lis3lv02d_get_xyz - Get X, Y and Z axis values from the accelerometer |
81 | * @handle: the handle to the device | 97 | * @lis3: pointer to the device struct |
82 | * @x: where to store the X axis value | 98 | * @x: where to store the X axis value |
83 | * @y: where to store the Y axis value | 99 | * @y: where to store the Y axis value |
84 | * @z: where to store the Z axis value | 100 | * @z: where to store the Z axis value |
85 | * | 101 | * |
86 | * Note that 40Hz input device can eat up about 10% CPU at 800MHZ | 102 | * Note that 40Hz input device can eat up about 10% CPU at 800MHZ |
87 | */ | 103 | */ |
88 | static void lis3lv02d_get_xyz(acpi_handle handle, int *x, int *y, int *z) | 104 | static void lis3lv02d_get_xyz(struct lis3lv02d *lis3, int *x, int *y, int *z) |
89 | { | 105 | { |
90 | int position[3]; | 106 | int position[3]; |
91 | 107 | ||
92 | position[0] = adev.read_data(handle, OUTX); | 108 | position[0] = lis3_dev.read_data(lis3, OUTX); |
93 | position[1] = adev.read_data(handle, OUTY); | 109 | position[1] = lis3_dev.read_data(lis3, OUTY); |
94 | position[2] = adev.read_data(handle, OUTZ); | 110 | position[2] = lis3_dev.read_data(lis3, OUTZ); |
95 | 111 | ||
96 | *x = lis3lv02d_get_axis(adev.ac.x, position); | 112 | *x = lis3lv02d_get_axis(lis3_dev.ac.x, position); |
97 | *y = lis3lv02d_get_axis(adev.ac.y, position); | 113 | *y = lis3lv02d_get_axis(lis3_dev.ac.y, position); |
98 | *z = lis3lv02d_get_axis(adev.ac.z, position); | 114 | *z = lis3lv02d_get_axis(lis3_dev.ac.z, position); |
99 | } | 115 | } |
100 | 116 | ||
101 | void lis3lv02d_poweroff(acpi_handle handle) | 117 | void lis3lv02d_poweroff(struct lis3lv02d *lis3) |
102 | { | 118 | { |
103 | adev.is_on = 0; | 119 | lis3_dev.is_on = 0; |
104 | } | 120 | } |
105 | EXPORT_SYMBOL_GPL(lis3lv02d_poweroff); | 121 | EXPORT_SYMBOL_GPL(lis3lv02d_poweroff); |
106 | 122 | ||
107 | void lis3lv02d_poweron(acpi_handle handle) | 123 | void lis3lv02d_poweron(struct lis3lv02d *lis3) |
108 | { | 124 | { |
109 | adev.is_on = 1; | 125 | lis3_dev.is_on = 1; |
110 | adev.init(handle); | 126 | lis3_dev.init(lis3); |
111 | } | 127 | } |
112 | EXPORT_SYMBOL_GPL(lis3lv02d_poweron); | 128 | EXPORT_SYMBOL_GPL(lis3lv02d_poweron); |
113 | 129 | ||
@@ -116,13 +132,13 @@ EXPORT_SYMBOL_GPL(lis3lv02d_poweron); | |||
116 | * device will always be on until a call to lis3lv02d_decrease_use(). Not to be | 132 | * device will always be on until a call to lis3lv02d_decrease_use(). Not to be |
117 | * used from interrupt context. | 133 | * used from interrupt context. |
118 | */ | 134 | */ |
119 | static void lis3lv02d_increase_use(struct acpi_lis3lv02d *dev) | 135 | static void lis3lv02d_increase_use(struct lis3lv02d *dev) |
120 | { | 136 | { |
121 | mutex_lock(&dev->lock); | 137 | mutex_lock(&dev->lock); |
122 | dev->usage++; | 138 | dev->usage++; |
123 | if (dev->usage == 1) { | 139 | if (dev->usage == 1) { |
124 | if (!dev->is_on) | 140 | if (!dev->is_on) |
125 | lis3lv02d_poweron(dev->device->handle); | 141 | lis3lv02d_poweron(dev); |
126 | } | 142 | } |
127 | mutex_unlock(&dev->lock); | 143 | mutex_unlock(&dev->lock); |
128 | } | 144 | } |
@@ -131,12 +147,12 @@ static void lis3lv02d_increase_use(struct acpi_lis3lv02d *dev) | |||
131 | * To be called whenever a usage of the device is stopped. | 147 | * To be called whenever a usage of the device is stopped. |
132 | * It will make sure to turn off the device when there is not usage. | 148 | * It will make sure to turn off the device when there is not usage. |
133 | */ | 149 | */ |
134 | static void lis3lv02d_decrease_use(struct acpi_lis3lv02d *dev) | 150 | static void lis3lv02d_decrease_use(struct lis3lv02d *dev) |
135 | { | 151 | { |
136 | mutex_lock(&dev->lock); | 152 | mutex_lock(&dev->lock); |
137 | dev->usage--; | 153 | dev->usage--; |
138 | if (dev->usage == 0) | 154 | if (dev->usage == 0) |
139 | lis3lv02d_poweroff(dev->device->handle); | 155 | lis3lv02d_poweroff(dev); |
140 | mutex_unlock(&dev->lock); | 156 | mutex_unlock(&dev->lock); |
141 | } | 157 | } |
142 | 158 | ||
@@ -147,10 +163,10 @@ static irqreturn_t lis302dl_interrupt(int irq, void *dummy) | |||
147 | * the lid is closed. This leads to interrupts as soon as a little move | 163 | * the lid is closed. This leads to interrupts as soon as a little move |
148 | * is done. | 164 | * is done. |
149 | */ | 165 | */ |
150 | atomic_inc(&adev.count); | 166 | atomic_inc(&lis3_dev.count); |
151 | 167 | ||
152 | wake_up_interruptible(&adev.misc_wait); | 168 | wake_up_interruptible(&lis3_dev.misc_wait); |
153 | kill_fasync(&adev.async_queue, SIGIO, POLL_IN); | 169 | kill_fasync(&lis3_dev.async_queue, SIGIO, POLL_IN); |
154 | return IRQ_HANDLED; | 170 | return IRQ_HANDLED; |
155 | } | 171 | } |
156 | 172 | ||
@@ -158,10 +174,10 @@ static int lis3lv02d_misc_open(struct inode *inode, struct file *file) | |||
158 | { | 174 | { |
159 | int ret; | 175 | int ret; |
160 | 176 | ||
161 | if (test_and_set_bit(0, &adev.misc_opened)) | 177 | if (test_and_set_bit(0, &lis3_dev.misc_opened)) |
162 | return -EBUSY; /* already open */ | 178 | return -EBUSY; /* already open */ |
163 | 179 | ||
164 | atomic_set(&adev.count, 0); | 180 | atomic_set(&lis3_dev.count, 0); |
165 | 181 | ||
166 | /* | 182 | /* |
167 | * The sensor can generate interrupts for free-fall and direction | 183 | * The sensor can generate interrupts for free-fall and direction |
@@ -174,25 +190,25 @@ static int lis3lv02d_misc_open(struct inode *inode, struct file *file) | |||
174 | * io-apic is not configurable (and generates a warning) but I keep it | 190 | * io-apic is not configurable (and generates a warning) but I keep it |
175 | * in case of support for other hardware. | 191 | * in case of support for other hardware. |
176 | */ | 192 | */ |
177 | ret = request_irq(adev.irq, lis302dl_interrupt, IRQF_TRIGGER_RISING, | 193 | ret = request_irq(lis3_dev.irq, lis302dl_interrupt, IRQF_TRIGGER_RISING, |
178 | DRIVER_NAME, &adev); | 194 | DRIVER_NAME, &lis3_dev); |
179 | 195 | ||
180 | if (ret) { | 196 | if (ret) { |
181 | clear_bit(0, &adev.misc_opened); | 197 | clear_bit(0, &lis3_dev.misc_opened); |
182 | printk(KERN_ERR DRIVER_NAME ": IRQ%d allocation failed\n", adev.irq); | 198 | printk(KERN_ERR DRIVER_NAME ": IRQ%d allocation failed\n", lis3_dev.irq); |
183 | return -EBUSY; | 199 | return -EBUSY; |
184 | } | 200 | } |
185 | lis3lv02d_increase_use(&adev); | 201 | lis3lv02d_increase_use(&lis3_dev); |
186 | printk("lis3: registered interrupt %d\n", adev.irq); | 202 | printk("lis3: registered interrupt %d\n", lis3_dev.irq); |
187 | return 0; | 203 | return 0; |
188 | } | 204 | } |
189 | 205 | ||
190 | static int lis3lv02d_misc_release(struct inode *inode, struct file *file) | 206 | static int lis3lv02d_misc_release(struct inode *inode, struct file *file) |
191 | { | 207 | { |
192 | fasync_helper(-1, file, 0, &adev.async_queue); | 208 | fasync_helper(-1, file, 0, &lis3_dev.async_queue); |
193 | lis3lv02d_decrease_use(&adev); | 209 | lis3lv02d_decrease_use(&lis3_dev); |
194 | free_irq(adev.irq, &adev); | 210 | free_irq(lis3_dev.irq, &lis3_dev); |
195 | clear_bit(0, &adev.misc_opened); /* release the device */ | 211 | clear_bit(0, &lis3_dev.misc_opened); /* release the device */ |
196 | return 0; | 212 | return 0; |
197 | } | 213 | } |
198 | 214 | ||
@@ -207,10 +223,10 @@ static ssize_t lis3lv02d_misc_read(struct file *file, char __user *buf, | |||
207 | if (count < 1) | 223 | if (count < 1) |
208 | return -EINVAL; | 224 | return -EINVAL; |
209 | 225 | ||
210 | add_wait_queue(&adev.misc_wait, &wait); | 226 | add_wait_queue(&lis3_dev.misc_wait, &wait); |
211 | while (true) { | 227 | while (true) { |
212 | set_current_state(TASK_INTERRUPTIBLE); | 228 | set_current_state(TASK_INTERRUPTIBLE); |
213 | data = atomic_xchg(&adev.count, 0); | 229 | data = atomic_xchg(&lis3_dev.count, 0); |
214 | if (data) | 230 | if (data) |
215 | break; | 231 | break; |
216 | 232 | ||
@@ -240,22 +256,22 @@ static ssize_t lis3lv02d_misc_read(struct file *file, char __user *buf, | |||
240 | 256 | ||
241 | out: | 257 | out: |
242 | __set_current_state(TASK_RUNNING); | 258 | __set_current_state(TASK_RUNNING); |
243 | remove_wait_queue(&adev.misc_wait, &wait); | 259 | remove_wait_queue(&lis3_dev.misc_wait, &wait); |
244 | 260 | ||
245 | return retval; | 261 | return retval; |
246 | } | 262 | } |
247 | 263 | ||
248 | static unsigned int lis3lv02d_misc_poll(struct file *file, poll_table *wait) | 264 | static unsigned int lis3lv02d_misc_poll(struct file *file, poll_table *wait) |
249 | { | 265 | { |
250 | poll_wait(file, &adev.misc_wait, wait); | 266 | poll_wait(file, &lis3_dev.misc_wait, wait); |
251 | if (atomic_read(&adev.count)) | 267 | if (atomic_read(&lis3_dev.count)) |
252 | return POLLIN | POLLRDNORM; | 268 | return POLLIN | POLLRDNORM; |
253 | return 0; | 269 | return 0; |
254 | } | 270 | } |
255 | 271 | ||
256 | static int lis3lv02d_misc_fasync(int fd, struct file *file, int on) | 272 | static int lis3lv02d_misc_fasync(int fd, struct file *file, int on) |
257 | { | 273 | { |
258 | return fasync_helper(fd, file, on, &adev.async_queue); | 274 | return fasync_helper(fd, file, on, &lis3_dev.async_queue); |
259 | } | 275 | } |
260 | 276 | ||
261 | static const struct file_operations lis3lv02d_misc_fops = { | 277 | static const struct file_operations lis3lv02d_misc_fops = { |
@@ -283,12 +299,12 @@ static int lis3lv02d_joystick_kthread(void *data) | |||
283 | int x, y, z; | 299 | int x, y, z; |
284 | 300 | ||
285 | while (!kthread_should_stop()) { | 301 | while (!kthread_should_stop()) { |
286 | lis3lv02d_get_xyz(adev.device->handle, &x, &y, &z); | 302 | lis3lv02d_get_xyz(&lis3_dev, &x, &y, &z); |
287 | input_report_abs(adev.idev, ABS_X, x - adev.xcalib); | 303 | input_report_abs(lis3_dev.idev, ABS_X, x - lis3_dev.xcalib); |
288 | input_report_abs(adev.idev, ABS_Y, y - adev.ycalib); | 304 | input_report_abs(lis3_dev.idev, ABS_Y, y - lis3_dev.ycalib); |
289 | input_report_abs(adev.idev, ABS_Z, z - adev.zcalib); | 305 | input_report_abs(lis3_dev.idev, ABS_Z, z - lis3_dev.zcalib); |
290 | 306 | ||
291 | input_sync(adev.idev); | 307 | input_sync(lis3_dev.idev); |
292 | 308 | ||
293 | try_to_freeze(); | 309 | try_to_freeze(); |
294 | msleep_interruptible(MDPS_POLL_INTERVAL); | 310 | msleep_interruptible(MDPS_POLL_INTERVAL); |
@@ -299,11 +315,11 @@ static int lis3lv02d_joystick_kthread(void *data) | |||
299 | 315 | ||
300 | static int lis3lv02d_joystick_open(struct input_dev *input) | 316 | static int lis3lv02d_joystick_open(struct input_dev *input) |
301 | { | 317 | { |
302 | lis3lv02d_increase_use(&adev); | 318 | lis3lv02d_increase_use(&lis3_dev); |
303 | adev.kthread = kthread_run(lis3lv02d_joystick_kthread, NULL, "klis3lv02d"); | 319 | lis3_dev.kthread = kthread_run(lis3lv02d_joystick_kthread, NULL, "klis3lv02d"); |
304 | if (IS_ERR(adev.kthread)) { | 320 | if (IS_ERR(lis3_dev.kthread)) { |
305 | lis3lv02d_decrease_use(&adev); | 321 | lis3lv02d_decrease_use(&lis3_dev); |
306 | return PTR_ERR(adev.kthread); | 322 | return PTR_ERR(lis3_dev.kthread); |
307 | } | 323 | } |
308 | 324 | ||
309 | return 0; | 325 | return 0; |
@@ -311,45 +327,46 @@ static int lis3lv02d_joystick_open(struct input_dev *input) | |||
311 | 327 | ||
312 | static void lis3lv02d_joystick_close(struct input_dev *input) | 328 | static void lis3lv02d_joystick_close(struct input_dev *input) |
313 | { | 329 | { |
314 | kthread_stop(adev.kthread); | 330 | kthread_stop(lis3_dev.kthread); |
315 | lis3lv02d_decrease_use(&adev); | 331 | lis3lv02d_decrease_use(&lis3_dev); |
316 | } | 332 | } |
317 | 333 | ||
318 | static inline void lis3lv02d_calibrate_joystick(void) | 334 | static inline void lis3lv02d_calibrate_joystick(void) |
319 | { | 335 | { |
320 | lis3lv02d_get_xyz(adev.device->handle, &adev.xcalib, &adev.ycalib, &adev.zcalib); | 336 | lis3lv02d_get_xyz(&lis3_dev, |
337 | &lis3_dev.xcalib, &lis3_dev.ycalib, &lis3_dev.zcalib); | ||
321 | } | 338 | } |
322 | 339 | ||
323 | int lis3lv02d_joystick_enable(void) | 340 | int lis3lv02d_joystick_enable(void) |
324 | { | 341 | { |
325 | int err; | 342 | int err; |
326 | 343 | ||
327 | if (adev.idev) | 344 | if (lis3_dev.idev) |
328 | return -EINVAL; | 345 | return -EINVAL; |
329 | 346 | ||
330 | adev.idev = input_allocate_device(); | 347 | lis3_dev.idev = input_allocate_device(); |
331 | if (!adev.idev) | 348 | if (!lis3_dev.idev) |
332 | return -ENOMEM; | 349 | return -ENOMEM; |
333 | 350 | ||
334 | lis3lv02d_calibrate_joystick(); | 351 | lis3lv02d_calibrate_joystick(); |
335 | 352 | ||
336 | adev.idev->name = "ST LIS3LV02DL Accelerometer"; | 353 | lis3_dev.idev->name = "ST LIS3LV02DL Accelerometer"; |
337 | adev.idev->phys = DRIVER_NAME "/input0"; | 354 | lis3_dev.idev->phys = DRIVER_NAME "/input0"; |
338 | adev.idev->id.bustype = BUS_HOST; | 355 | lis3_dev.idev->id.bustype = BUS_HOST; |
339 | adev.idev->id.vendor = 0; | 356 | lis3_dev.idev->id.vendor = 0; |
340 | adev.idev->dev.parent = &adev.pdev->dev; | 357 | lis3_dev.idev->dev.parent = &lis3_dev.pdev->dev; |
341 | adev.idev->open = lis3lv02d_joystick_open; | 358 | lis3_dev.idev->open = lis3lv02d_joystick_open; |
342 | adev.idev->close = lis3lv02d_joystick_close; | 359 | lis3_dev.idev->close = lis3lv02d_joystick_close; |
343 | 360 | ||
344 | set_bit(EV_ABS, adev.idev->evbit); | 361 | set_bit(EV_ABS, lis3_dev.idev->evbit); |
345 | input_set_abs_params(adev.idev, ABS_X, -adev.mdps_max_val, adev.mdps_max_val, 3, 3); | 362 | input_set_abs_params(lis3_dev.idev, ABS_X, -lis3_dev.mdps_max_val, lis3_dev.mdps_max_val, 3, 3); |
346 | input_set_abs_params(adev.idev, ABS_Y, -adev.mdps_max_val, adev.mdps_max_val, 3, 3); | 363 | input_set_abs_params(lis3_dev.idev, ABS_Y, -lis3_dev.mdps_max_val, lis3_dev.mdps_max_val, 3, 3); |
347 | input_set_abs_params(adev.idev, ABS_Z, -adev.mdps_max_val, adev.mdps_max_val, 3, 3); | 364 | input_set_abs_params(lis3_dev.idev, ABS_Z, -lis3_dev.mdps_max_val, lis3_dev.mdps_max_val, 3, 3); |
348 | 365 | ||
349 | err = input_register_device(adev.idev); | 366 | err = input_register_device(lis3_dev.idev); |
350 | if (err) { | 367 | if (err) { |
351 | input_free_device(adev.idev); | 368 | input_free_device(lis3_dev.idev); |
352 | adev.idev = NULL; | 369 | lis3_dev.idev = NULL; |
353 | } | 370 | } |
354 | 371 | ||
355 | return err; | 372 | return err; |
@@ -358,71 +375,40 @@ EXPORT_SYMBOL_GPL(lis3lv02d_joystick_enable); | |||
358 | 375 | ||
359 | void lis3lv02d_joystick_disable(void) | 376 | void lis3lv02d_joystick_disable(void) |
360 | { | 377 | { |
361 | if (!adev.idev) | 378 | if (!lis3_dev.idev) |
362 | return; | 379 | return; |
363 | 380 | ||
364 | misc_deregister(&lis3lv02d_misc_device); | 381 | misc_deregister(&lis3lv02d_misc_device); |
365 | input_unregister_device(adev.idev); | 382 | input_unregister_device(lis3_dev.idev); |
366 | adev.idev = NULL; | 383 | lis3_dev.idev = NULL; |
367 | } | 384 | } |
368 | EXPORT_SYMBOL_GPL(lis3lv02d_joystick_disable); | 385 | EXPORT_SYMBOL_GPL(lis3lv02d_joystick_disable); |
369 | 386 | ||
370 | /* | ||
371 | * Initialise the accelerometer and the various subsystems. | ||
372 | * Should be rather independant of the bus system. | ||
373 | */ | ||
374 | int lis3lv02d_init_device(struct acpi_lis3lv02d *dev) | ||
375 | { | ||
376 | mutex_init(&dev->lock); | ||
377 | lis3lv02d_add_fs(dev->device); | ||
378 | lis3lv02d_increase_use(dev); | ||
379 | |||
380 | if (lis3lv02d_joystick_enable()) | ||
381 | printk(KERN_ERR DRIVER_NAME ": joystick initialization failed\n"); | ||
382 | |||
383 | printk("lis3_init_device: irq %d\n", dev->irq); | ||
384 | |||
385 | /* if we did not get an IRQ from ACPI - we have nothing more to do */ | ||
386 | if (!dev->irq) { | ||
387 | printk(KERN_ERR DRIVER_NAME | ||
388 | ": No IRQ in ACPI. Disabling /dev/freefall\n"); | ||
389 | goto out; | ||
390 | } | ||
391 | |||
392 | printk("lis3: registering device\n"); | ||
393 | if (misc_register(&lis3lv02d_misc_device)) | ||
394 | printk(KERN_ERR DRIVER_NAME ": misc_register failed\n"); | ||
395 | out: | ||
396 | lis3lv02d_decrease_use(dev); | ||
397 | return 0; | ||
398 | } | ||
399 | EXPORT_SYMBOL_GPL(lis3lv02d_init_device); | ||
400 | |||
401 | /* Sysfs stuff */ | 387 | /* Sysfs stuff */ |
402 | static ssize_t lis3lv02d_position_show(struct device *dev, | 388 | static ssize_t lis3lv02d_position_show(struct device *dev, |
403 | struct device_attribute *attr, char *buf) | 389 | struct device_attribute *attr, char *buf) |
404 | { | 390 | { |
405 | int x, y, z; | 391 | int x, y, z; |
406 | 392 | ||
407 | lis3lv02d_increase_use(&adev); | 393 | lis3lv02d_increase_use(&lis3_dev); |
408 | lis3lv02d_get_xyz(adev.device->handle, &x, &y, &z); | 394 | lis3lv02d_get_xyz(&lis3_dev, &x, &y, &z); |
409 | lis3lv02d_decrease_use(&adev); | 395 | lis3lv02d_decrease_use(&lis3_dev); |
410 | return sprintf(buf, "(%d,%d,%d)\n", x, y, z); | 396 | return sprintf(buf, "(%d,%d,%d)\n", x, y, z); |
411 | } | 397 | } |
412 | 398 | ||
413 | static ssize_t lis3lv02d_calibrate_show(struct device *dev, | 399 | static ssize_t lis3lv02d_calibrate_show(struct device *dev, |
414 | struct device_attribute *attr, char *buf) | 400 | struct device_attribute *attr, char *buf) |
415 | { | 401 | { |
416 | return sprintf(buf, "(%d,%d,%d)\n", adev.xcalib, adev.ycalib, adev.zcalib); | 402 | return sprintf(buf, "(%d,%d,%d)\n", lis3_dev.xcalib, lis3_dev.ycalib, lis3_dev.zcalib); |
417 | } | 403 | } |
418 | 404 | ||
419 | static ssize_t lis3lv02d_calibrate_store(struct device *dev, | 405 | static ssize_t lis3lv02d_calibrate_store(struct device *dev, |
420 | struct device_attribute *attr, | 406 | struct device_attribute *attr, |
421 | const char *buf, size_t count) | 407 | const char *buf, size_t count) |
422 | { | 408 | { |
423 | lis3lv02d_increase_use(&adev); | 409 | lis3lv02d_increase_use(&lis3_dev); |
424 | lis3lv02d_calibrate_joystick(); | 410 | lis3lv02d_calibrate_joystick(); |
425 | lis3lv02d_decrease_use(&adev); | 411 | lis3lv02d_decrease_use(&lis3_dev); |
426 | return count; | 412 | return count; |
427 | } | 413 | } |
428 | 414 | ||
@@ -434,9 +420,9 @@ static ssize_t lis3lv02d_rate_show(struct device *dev, | |||
434 | u8 ctrl; | 420 | u8 ctrl; |
435 | int val; | 421 | int val; |
436 | 422 | ||
437 | lis3lv02d_increase_use(&adev); | 423 | lis3lv02d_increase_use(&lis3_dev); |
438 | adev.read(adev.device->handle, CTRL_REG1, &ctrl); | 424 | lis3_dev.read(&lis3_dev, CTRL_REG1, &ctrl); |
439 | lis3lv02d_decrease_use(&adev); | 425 | lis3lv02d_decrease_use(&lis3_dev); |
440 | val = (ctrl & (CTRL1_DF0 | CTRL1_DF1)) >> 4; | 426 | val = (ctrl & (CTRL1_DF0 | CTRL1_DF1)) >> 4; |
441 | return sprintf(buf, "%d\n", lis3lv02dl_df_val[val]); | 427 | return sprintf(buf, "%d\n", lis3lv02dl_df_val[val]); |
442 | } | 428 | } |
@@ -458,23 +444,73 @@ static struct attribute_group lis3lv02d_attribute_group = { | |||
458 | }; | 444 | }; |
459 | 445 | ||
460 | 446 | ||
461 | static int lis3lv02d_add_fs(struct acpi_device *device) | 447 | static int lis3lv02d_add_fs(struct lis3lv02d *lis3) |
462 | { | 448 | { |
463 | adev.pdev = platform_device_register_simple(DRIVER_NAME, -1, NULL, 0); | 449 | lis3_dev.pdev = platform_device_register_simple(DRIVER_NAME, -1, NULL, 0); |
464 | if (IS_ERR(adev.pdev)) | 450 | if (IS_ERR(lis3_dev.pdev)) |
465 | return PTR_ERR(adev.pdev); | 451 | return PTR_ERR(lis3_dev.pdev); |
466 | 452 | ||
467 | return sysfs_create_group(&adev.pdev->dev.kobj, &lis3lv02d_attribute_group); | 453 | return sysfs_create_group(&lis3_dev.pdev->dev.kobj, &lis3lv02d_attribute_group); |
468 | } | 454 | } |
469 | 455 | ||
470 | int lis3lv02d_remove_fs(void) | 456 | int lis3lv02d_remove_fs(void) |
471 | { | 457 | { |
472 | sysfs_remove_group(&adev.pdev->dev.kobj, &lis3lv02d_attribute_group); | 458 | sysfs_remove_group(&lis3_dev.pdev->dev.kobj, &lis3lv02d_attribute_group); |
473 | platform_device_unregister(adev.pdev); | 459 | platform_device_unregister(lis3_dev.pdev); |
474 | return 0; | 460 | return 0; |
475 | } | 461 | } |
476 | EXPORT_SYMBOL_GPL(lis3lv02d_remove_fs); | 462 | EXPORT_SYMBOL_GPL(lis3lv02d_remove_fs); |
477 | 463 | ||
464 | /* | ||
465 | * Initialise the accelerometer and the various subsystems. | ||
466 | * Should be rather independant of the bus system. | ||
467 | */ | ||
468 | int lis3lv02d_init_device(struct lis3lv02d *dev) | ||
469 | { | ||
470 | dev->whoami = lis3lv02d_read_8(dev, WHO_AM_I); | ||
471 | |||
472 | switch (dev->whoami) { | ||
473 | case LIS_DOUBLE_ID: | ||
474 | printk(KERN_INFO DRIVER_NAME ": 2-byte sensor found\n"); | ||
475 | dev->read_data = lis3lv02d_read_16; | ||
476 | dev->mdps_max_val = 2048; | ||
477 | break; | ||
478 | case LIS_SINGLE_ID: | ||
479 | printk(KERN_INFO DRIVER_NAME ": 1-byte sensor found\n"); | ||
480 | dev->read_data = lis3lv02d_read_8; | ||
481 | dev->mdps_max_val = 128; | ||
482 | break; | ||
483 | default: | ||
484 | printk(KERN_ERR DRIVER_NAME | ||
485 | ": unknown sensor type 0x%X\n", lis3_dev.whoami); | ||
486 | return -EINVAL; | ||
487 | } | ||
488 | |||
489 | mutex_init(&dev->lock); | ||
490 | lis3lv02d_add_fs(dev); | ||
491 | lis3lv02d_increase_use(dev); | ||
492 | |||
493 | if (lis3lv02d_joystick_enable()) | ||
494 | printk(KERN_ERR DRIVER_NAME ": joystick initialization failed\n"); | ||
495 | |||
496 | printk("lis3_init_device: irq %d\n", dev->irq); | ||
497 | |||
498 | /* bail if we did not get an IRQ from the bus layer */ | ||
499 | if (!dev->irq) { | ||
500 | printk(KERN_ERR DRIVER_NAME | ||
501 | ": No IRQ. Disabling /dev/freefall\n"); | ||
502 | goto out; | ||
503 | } | ||
504 | |||
505 | printk("lis3: registering device\n"); | ||
506 | if (misc_register(&lis3lv02d_misc_device)) | ||
507 | printk(KERN_ERR DRIVER_NAME ": misc_register failed\n"); | ||
508 | out: | ||
509 | lis3lv02d_decrease_use(dev); | ||
510 | return 0; | ||
511 | } | ||
512 | EXPORT_SYMBOL_GPL(lis3lv02d_init_device); | ||
513 | |||
478 | MODULE_DESCRIPTION("ST LIS3LV02Dx three-axis digital accelerometer driver"); | 514 | MODULE_DESCRIPTION("ST LIS3LV02Dx three-axis digital accelerometer driver"); |
479 | MODULE_AUTHOR("Yan Burman, Eric Piel, Pavel Machek"); | 515 | MODULE_AUTHOR("Yan Burman, Eric Piel, Pavel Machek"); |
480 | MODULE_LICENSE("GPL"); | 516 | MODULE_LICENSE("GPL"); |