diff options
author | Jacek Anaszewski <j.anaszewski@samsung.com> | 2013-05-07 06:41:00 -0400 |
---|---|---|
committer | Jonathan Cameron <jic23@kernel.org> | 2013-05-22 17:16:49 -0400 |
commit | 94a6d5cf7caa5003e3b4d0c61a047329f26092f3 (patch) | |
tree | 14fae3f2f65c06d246a870b20cf6c27f8dce0ac5 /drivers/iio/magnetometer | |
parent | f4b7f751c6fd2bd7e6d3a83385ee292c39995bdb (diff) |
iio:ak8975 Implement data ready interrupt handling
Implement "data ready" interrupt handling in addition to the
two existing read modes - DRDY GPIO polling and ST1 register
DRDY bit polling.
Signed-off-by: Jacek Anaszewski <j.anaszewski@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Signed-off-by: Jonathan Cameron <jic23@kernel.org>
Diffstat (limited to 'drivers/iio/magnetometer')
-rw-r--r-- | drivers/iio/magnetometer/ak8975.c | 91 |
1 files changed, 89 insertions, 2 deletions
diff --git a/drivers/iio/magnetometer/ak8975.c b/drivers/iio/magnetometer/ak8975.c index d75cc23e8ae7..7105f22d6cd7 100644 --- a/drivers/iio/magnetometer/ak8975.c +++ b/drivers/iio/magnetometer/ak8975.c | |||
@@ -24,10 +24,11 @@ | |||
24 | #include <linux/kernel.h> | 24 | #include <linux/kernel.h> |
25 | #include <linux/slab.h> | 25 | #include <linux/slab.h> |
26 | #include <linux/i2c.h> | 26 | #include <linux/i2c.h> |
27 | #include <linux/interrupt.h> | ||
27 | #include <linux/err.h> | 28 | #include <linux/err.h> |
28 | #include <linux/mutex.h> | 29 | #include <linux/mutex.h> |
29 | #include <linux/delay.h> | 30 | #include <linux/delay.h> |
30 | 31 | #include <linux/bitops.h> | |
31 | #include <linux/gpio.h> | 32 | #include <linux/gpio.h> |
32 | #include <linux/of_gpio.h> | 33 | #include <linux/of_gpio.h> |
33 | 34 | ||
@@ -83,6 +84,7 @@ | |||
83 | */ | 84 | */ |
84 | #define AK8975_MAX_CONVERSION_TIMEOUT 500 | 85 | #define AK8975_MAX_CONVERSION_TIMEOUT 500 |
85 | #define AK8975_CONVERSION_DONE_POLL_TIME 10 | 86 | #define AK8975_CONVERSION_DONE_POLL_TIME 10 |
87 | #define AK8975_DATA_READY_TIMEOUT ((100*HZ)/1000) | ||
86 | 88 | ||
87 | /* | 89 | /* |
88 | * Per-instance context data for the device. | 90 | * Per-instance context data for the device. |
@@ -95,6 +97,9 @@ struct ak8975_data { | |||
95 | long raw_to_gauss[3]; | 97 | long raw_to_gauss[3]; |
96 | u8 reg_cache[AK8975_MAX_REGS]; | 98 | u8 reg_cache[AK8975_MAX_REGS]; |
97 | int eoc_gpio; | 99 | int eoc_gpio; |
100 | int eoc_irq; | ||
101 | wait_queue_head_t data_ready_queue; | ||
102 | unsigned long flags; | ||
98 | }; | 103 | }; |
99 | 104 | ||
100 | static const int ak8975_index_to_reg[] = { | 105 | static const int ak8975_index_to_reg[] = { |
@@ -124,6 +129,51 @@ static int ak8975_write_data(struct i2c_client *client, | |||
124 | } | 129 | } |
125 | 130 | ||
126 | /* | 131 | /* |
132 | * Handle data ready irq | ||
133 | */ | ||
134 | static irqreturn_t ak8975_irq_handler(int irq, void *data) | ||
135 | { | ||
136 | struct ak8975_data *ak8975 = data; | ||
137 | |||
138 | set_bit(0, &ak8975->flags); | ||
139 | wake_up(&ak8975->data_ready_queue); | ||
140 | |||
141 | return IRQ_HANDLED; | ||
142 | } | ||
143 | |||
144 | /* | ||
145 | * Install data ready interrupt handler | ||
146 | */ | ||
147 | static int ak8975_setup_irq(struct ak8975_data *data) | ||
148 | { | ||
149 | struct i2c_client *client = data->client; | ||
150 | int rc; | ||
151 | int irq; | ||
152 | |||
153 | if (client->irq) | ||
154 | irq = client->irq; | ||
155 | else | ||
156 | irq = gpio_to_irq(data->eoc_gpio); | ||
157 | |||
158 | rc = request_irq(irq, ak8975_irq_handler, | ||
159 | IRQF_TRIGGER_RISING | IRQF_ONESHOT, | ||
160 | dev_name(&client->dev), data); | ||
161 | if (rc < 0) { | ||
162 | dev_err(&client->dev, | ||
163 | "irq %d request failed, (gpio %d): %d\n", | ||
164 | irq, data->eoc_gpio, rc); | ||
165 | return rc; | ||
166 | } | ||
167 | |||
168 | init_waitqueue_head(&data->data_ready_queue); | ||
169 | clear_bit(0, &data->flags); | ||
170 | data->eoc_irq = irq; | ||
171 | |||
172 | return rc; | ||
173 | } | ||
174 | |||
175 | |||
176 | /* | ||
127 | * Perform some start-of-day setup, including reading the asa calibration | 177 | * Perform some start-of-day setup, including reading the asa calibration |
128 | * values and caching them. | 178 | * values and caching them. |
129 | */ | 179 | */ |
@@ -171,6 +221,16 @@ static int ak8975_setup(struct i2c_client *client) | |||
171 | AK8975_REG_CNTL_MODE_POWER_DOWN, | 221 | AK8975_REG_CNTL_MODE_POWER_DOWN, |
172 | AK8975_REG_CNTL_MODE_MASK, | 222 | AK8975_REG_CNTL_MODE_MASK, |
173 | AK8975_REG_CNTL_MODE_SHIFT); | 223 | AK8975_REG_CNTL_MODE_SHIFT); |
224 | |||
225 | if (data->eoc_gpio > 0 || client->irq) { | ||
226 | ret = ak8975_setup_irq(data); | ||
227 | if (ret < 0) { | ||
228 | dev_err(&client->dev, | ||
229 | "Error setting data ready interrupt\n"); | ||
230 | return ret; | ||
231 | } | ||
232 | } | ||
233 | |||
174 | if (ret < 0) { | 234 | if (ret < 0) { |
175 | dev_err(&client->dev, "Error in setting power-down mode\n"); | 235 | dev_err(&client->dev, "Error in setting power-down mode\n"); |
176 | return ret; | 236 | return ret; |
@@ -267,9 +327,23 @@ static int wait_conversion_complete_polled(struct ak8975_data *data) | |||
267 | dev_err(&client->dev, "Conversion timeout happened\n"); | 327 | dev_err(&client->dev, "Conversion timeout happened\n"); |
268 | return -EINVAL; | 328 | return -EINVAL; |
269 | } | 329 | } |
330 | |||
270 | return read_status; | 331 | return read_status; |
271 | } | 332 | } |
272 | 333 | ||
334 | /* Returns 0 if the end of conversion interrupt occured or -ETIME otherwise */ | ||
335 | static int wait_conversion_complete_interrupt(struct ak8975_data *data) | ||
336 | { | ||
337 | int ret; | ||
338 | |||
339 | ret = wait_event_timeout(data->data_ready_queue, | ||
340 | test_bit(0, &data->flags), | ||
341 | AK8975_DATA_READY_TIMEOUT); | ||
342 | clear_bit(0, &data->flags); | ||
343 | |||
344 | return ret > 0 ? 0 : -ETIME; | ||
345 | } | ||
346 | |||
273 | /* | 347 | /* |
274 | * Emits the raw flux value for the x, y, or z axis. | 348 | * Emits the raw flux value for the x, y, or z axis. |
275 | */ | 349 | */ |
@@ -295,13 +369,16 @@ static int ak8975_read_axis(struct iio_dev *indio_dev, int index, int *val) | |||
295 | } | 369 | } |
296 | 370 | ||
297 | /* Wait for the conversion to complete. */ | 371 | /* Wait for the conversion to complete. */ |
298 | if (gpio_is_valid(data->eoc_gpio)) | 372 | if (data->eoc_irq) |
373 | ret = wait_conversion_complete_interrupt(data); | ||
374 | else if (gpio_is_valid(data->eoc_gpio)) | ||
299 | ret = wait_conversion_complete_gpio(data); | 375 | ret = wait_conversion_complete_gpio(data); |
300 | else | 376 | else |
301 | ret = wait_conversion_complete_polled(data); | 377 | ret = wait_conversion_complete_polled(data); |
302 | if (ret < 0) | 378 | if (ret < 0) |
303 | goto exit; | 379 | goto exit; |
304 | 380 | ||
381 | /* This will be executed only for non-interrupt based waiting case */ | ||
305 | if (ret & AK8975_REG_ST1_DRDY_MASK) { | 382 | if (ret & AK8975_REG_ST1_DRDY_MASK) { |
306 | ret = i2c_smbus_read_byte_data(client, AK8975_REG_ST2); | 383 | ret = i2c_smbus_read_byte_data(client, AK8975_REG_ST2); |
307 | if (ret < 0) { | 384 | if (ret < 0) { |
@@ -415,6 +492,11 @@ static int ak8975_probe(struct i2c_client *client, | |||
415 | } | 492 | } |
416 | data = iio_priv(indio_dev); | 493 | data = iio_priv(indio_dev); |
417 | i2c_set_clientdata(client, indio_dev); | 494 | i2c_set_clientdata(client, indio_dev); |
495 | |||
496 | data->client = client; | ||
497 | data->eoc_gpio = eoc_gpio; | ||
498 | data->eoc_irq = 0; | ||
499 | |||
418 | /* Perform some basic start-of-day setup of the device. */ | 500 | /* Perform some basic start-of-day setup of the device. */ |
419 | err = ak8975_setup(client); | 501 | err = ak8975_setup(client); |
420 | if (err < 0) { | 502 | if (err < 0) { |
@@ -439,6 +521,8 @@ static int ak8975_probe(struct i2c_client *client, | |||
439 | 521 | ||
440 | exit_free_iio: | 522 | exit_free_iio: |
441 | iio_device_free(indio_dev); | 523 | iio_device_free(indio_dev); |
524 | if (data->eoc_irq) | ||
525 | free_irq(data->eoc_irq, data); | ||
442 | exit_gpio: | 526 | exit_gpio: |
443 | if (gpio_is_valid(eoc_gpio)) | 527 | if (gpio_is_valid(eoc_gpio)) |
444 | gpio_free(eoc_gpio); | 528 | gpio_free(eoc_gpio); |
@@ -453,6 +537,9 @@ static int ak8975_remove(struct i2c_client *client) | |||
453 | 537 | ||
454 | iio_device_unregister(indio_dev); | 538 | iio_device_unregister(indio_dev); |
455 | 539 | ||
540 | if (data->eoc_irq) | ||
541 | free_irq(data->eoc_irq, data); | ||
542 | |||
456 | if (gpio_is_valid(data->eoc_gpio)) | 543 | if (gpio_is_valid(data->eoc_gpio)) |
457 | gpio_free(data->eoc_gpio); | 544 | gpio_free(data->eoc_gpio); |
458 | 545 | ||