aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTeodora Baluta <teodora.baluta@intel.com>2015-08-20 10:37:33 -0400
committerJonathan Cameron <jic23@kernel.org>2015-08-31 12:58:49 -0400
commit47196620c82f8d8cef0dc61b87b76f18278537dd (patch)
tree3f2feb9f2aba1c7be26d2811567047b047f32505
parent1ce0eda0f75747b3131a9047aee19291f59c18c9 (diff)
iio: mxc4005: add data ready trigger for mxc4005
Add iio trigger for the data ready interrupt that signals new measurements for the X, Y and Z axes. Signed-off-by: Teodora Baluta <teodora.baluta@intel.com> Signed-off-by: Jonathan Cameron <jic23@kernel.org>
-rw-r--r--drivers/iio/accel/mxc4005.c142
1 files changed, 141 insertions, 1 deletions
diff --git a/drivers/iio/accel/mxc4005.c b/drivers/iio/accel/mxc4005.c
index 390eaf8cb2f8..e72e218c2696 100644
--- a/drivers/iio/accel/mxc4005.c
+++ b/drivers/iio/accel/mxc4005.c
@@ -17,13 +17,16 @@
17#include <linux/i2c.h> 17#include <linux/i2c.h>
18#include <linux/iio/iio.h> 18#include <linux/iio/iio.h>
19#include <linux/acpi.h> 19#include <linux/acpi.h>
20#include <linux/gpio/consumer.h>
20#include <linux/regmap.h> 21#include <linux/regmap.h>
21#include <linux/iio/sysfs.h> 22#include <linux/iio/sysfs.h>
23#include <linux/iio/trigger.h>
22#include <linux/iio/buffer.h> 24#include <linux/iio/buffer.h>
23#include <linux/iio/triggered_buffer.h> 25#include <linux/iio/triggered_buffer.h>
24#include <linux/iio/trigger_consumer.h> 26#include <linux/iio/trigger_consumer.h>
25 27
26#define MXC4005_DRV_NAME "mxc4005" 28#define MXC4005_DRV_NAME "mxc4005"
29#define MXC4005_IRQ_NAME "mxc4005_event"
27#define MXC4005_REGMAP_NAME "mxc4005_regmap" 30#define MXC4005_REGMAP_NAME "mxc4005_regmap"
28 31
29#define MXC4005_REG_XOUT_UPPER 0x03 32#define MXC4005_REG_XOUT_UPPER 0x03
@@ -33,6 +36,12 @@
33#define MXC4005_REG_ZOUT_UPPER 0x07 36#define MXC4005_REG_ZOUT_UPPER 0x07
34#define MXC4005_REG_ZOUT_LOWER 0x08 37#define MXC4005_REG_ZOUT_LOWER 0x08
35 38
39#define MXC4005_REG_INT_MASK1 0x0B
40#define MXC4005_REG_INT_MASK1_BIT_DRDYE 0x01
41
42#define MXC4005_REG_INT_CLR1 0x01
43#define MXC4005_REG_INT_CLR1_BIT_DRDYC 0x01
44
36#define MXC4005_REG_CONTROL 0x0D 45#define MXC4005_REG_CONTROL 0x0D
37#define MXC4005_REG_CONTROL_MASK_FSR GENMASK(6, 5) 46#define MXC4005_REG_CONTROL_MASK_FSR GENMASK(6, 5)
38#define MXC4005_CONTROL_FSR_SHIFT 5 47#define MXC4005_CONTROL_FSR_SHIFT 5
@@ -55,7 +64,9 @@ struct mxc4005_data {
55 struct device *dev; 64 struct device *dev;
56 struct mutex mutex; 65 struct mutex mutex;
57 struct regmap *regmap; 66 struct regmap *regmap;
67 struct iio_trigger *dready_trig;
58 __be16 buffer[8]; 68 __be16 buffer[8];
69 bool trigger_enabled;
59}; 70};
60 71
61/* 72/*
@@ -107,6 +118,8 @@ static bool mxc4005_is_readable_reg(struct device *dev, unsigned int reg)
107static bool mxc4005_is_writeable_reg(struct device *dev, unsigned int reg) 118static bool mxc4005_is_writeable_reg(struct device *dev, unsigned int reg)
108{ 119{
109 switch (reg) { 120 switch (reg) {
121 case MXC4005_REG_INT_CLR1:
122 case MXC4005_REG_INT_MASK1:
110 case MXC4005_REG_CONTROL: 123 case MXC4005_REG_CONTROL:
111 return true; 124 return true;
112 default: 125 default:
@@ -307,6 +320,91 @@ err:
307 return IRQ_HANDLED; 320 return IRQ_HANDLED;
308} 321}
309 322
323static int mxc4005_clr_intr(struct mxc4005_data *data)
324{
325 int ret;
326
327 /* clear interrupt */
328 ret = regmap_write(data->regmap, MXC4005_REG_INT_CLR1,
329 MXC4005_REG_INT_CLR1_BIT_DRDYC);
330 if (ret < 0) {
331 dev_err(data->dev, "failed to write to reg_int_clr1\n");
332 return ret;
333 }
334
335 return 0;
336}
337
338static int mxc4005_set_trigger_state(struct iio_trigger *trig,
339 bool state)
340{
341 struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig);
342 struct mxc4005_data *data = iio_priv(indio_dev);
343 int ret;
344
345 mutex_lock(&data->mutex);
346 if (state) {
347 ret = regmap_write(data->regmap, MXC4005_REG_INT_MASK1,
348 MXC4005_REG_INT_MASK1_BIT_DRDYE);
349 } else {
350 ret = regmap_write(data->regmap, MXC4005_REG_INT_MASK1,
351 ~MXC4005_REG_INT_MASK1_BIT_DRDYE);
352 }
353
354 if (ret < 0) {
355 mutex_unlock(&data->mutex);
356 dev_err(data->dev, "failed to update reg_int_mask1");
357 return ret;
358 }
359
360 data->trigger_enabled = state;
361 mutex_unlock(&data->mutex);
362
363 return 0;
364}
365
366static int mxc4005_trigger_try_reen(struct iio_trigger *trig)
367{
368 struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig);
369 struct mxc4005_data *data = iio_priv(indio_dev);
370
371 if (!data->dready_trig)
372 return 0;
373
374 return mxc4005_clr_intr(data);
375}
376
377static const struct iio_trigger_ops mxc4005_trigger_ops = {
378 .set_trigger_state = mxc4005_set_trigger_state,
379 .try_reenable = mxc4005_trigger_try_reen,
380 .owner = THIS_MODULE,
381};
382
383static int mxc4005_gpio_probe(struct i2c_client *client,
384 struct mxc4005_data *data)
385{
386 struct device *dev;
387 struct gpio_desc *gpio;
388 int ret;
389
390 if (!client)
391 return -EINVAL;
392
393 dev = &client->dev;
394
395 gpio = devm_gpiod_get_index(dev, "mxc4005_int", 0, GPIOD_IN);
396 if (IS_ERR(gpio)) {
397 dev_err(dev, "failed to get acpi gpio index\n");
398 return PTR_ERR(gpio);
399 }
400
401 ret = gpiod_to_irq(gpio);
402
403 dev_dbg(dev, "GPIO resource, no:%d irq:%d\n", desc_to_gpio(gpio), ret);
404
405 return ret;
406}
407
310static int mxc4005_chip_init(struct mxc4005_data *data) 408static int mxc4005_chip_init(struct mxc4005_data *data)
311{ 409{
312 int ret; 410 int ret;
@@ -363,7 +461,7 @@ static int mxc4005_probe(struct i2c_client *client,
363 indio_dev->info = &mxc4005_info; 461 indio_dev->info = &mxc4005_info;
364 462
365 ret = iio_triggered_buffer_setup(indio_dev, 463 ret = iio_triggered_buffer_setup(indio_dev,
366 &iio_pollfunc_store_time, 464 iio_pollfunc_store_time,
367 mxc4005_trigger_handler, 465 mxc4005_trigger_handler,
368 NULL); 466 NULL);
369 if (ret < 0) { 467 if (ret < 0) {
@@ -372,6 +470,43 @@ static int mxc4005_probe(struct i2c_client *client,
372 return ret; 470 return ret;
373 } 471 }
374 472
473 if (client->irq < 0)
474 client->irq = mxc4005_gpio_probe(client, data);
475
476 if (client->irq > 0) {
477 data->dready_trig = devm_iio_trigger_alloc(&client->dev,
478 "%s-dev%d",
479 indio_dev->name,
480 indio_dev->id);
481 if (!data->dready_trig)
482 return -ENOMEM;
483
484 ret = devm_request_threaded_irq(&client->dev, client->irq,
485 iio_trigger_generic_data_rdy_poll,
486 NULL,
487 IRQF_TRIGGER_FALLING |
488 IRQF_ONESHOT,
489 MXC4005_IRQ_NAME,
490 data->dready_trig);
491 if (ret) {
492 dev_err(&client->dev,
493 "failed to init threaded irq\n");
494 goto err_buffer_cleanup;
495 }
496
497 data->dready_trig->dev.parent = &client->dev;
498 data->dready_trig->ops = &mxc4005_trigger_ops;
499 iio_trigger_set_drvdata(data->dready_trig, indio_dev);
500 indio_dev->trig = data->dready_trig;
501 iio_trigger_get(indio_dev->trig);
502 ret = iio_trigger_register(data->dready_trig);
503 if (ret) {
504 dev_err(&client->dev,
505 "failed to register trigger\n");
506 goto err_trigger_unregister;
507 }
508 }
509
375 ret = iio_device_register(indio_dev); 510 ret = iio_device_register(indio_dev);
376 if (ret < 0) { 511 if (ret < 0) {
377 dev_err(&client->dev, 512 dev_err(&client->dev,
@@ -381,6 +516,8 @@ static int mxc4005_probe(struct i2c_client *client,
381 516
382 return 0; 517 return 0;
383 518
519err_trigger_unregister:
520 iio_trigger_unregister(data->dready_trig);
384err_buffer_cleanup: 521err_buffer_cleanup:
385 iio_triggered_buffer_cleanup(indio_dev); 522 iio_triggered_buffer_cleanup(indio_dev);
386 523
@@ -390,10 +527,13 @@ err_buffer_cleanup:
390static int mxc4005_remove(struct i2c_client *client) 527static int mxc4005_remove(struct i2c_client *client)
391{ 528{
392 struct iio_dev *indio_dev = i2c_get_clientdata(client); 529 struct iio_dev *indio_dev = i2c_get_clientdata(client);
530 struct mxc4005_data *data = iio_priv(indio_dev);
393 531
394 iio_device_unregister(indio_dev); 532 iio_device_unregister(indio_dev);
395 533
396 iio_triggered_buffer_cleanup(indio_dev); 534 iio_triggered_buffer_cleanup(indio_dev);
535 if (data->dready_trig)
536 iio_trigger_unregister(data->dready_trig);
397 537
398 return 0; 538 return 0;
399} 539}