summaryrefslogtreecommitdiff
path: root/drivers/iio/accel
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>2015-05-09 18:15:50 +0200
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2015-05-09 18:15:50 +0200
commit5ccca155675a5a2d491257a441306dd8547695c2 (patch)
tree6dd32e67c98f00e4d302f2550c03529f97238d35 /drivers/iio/accel
parent7192a5dd54488b6fa81f071b2ae93e00b25f0ddd (diff)
parent1038a6872802bb4a07f627162ff989bf49e2e5cc (diff)
Merge tag 'iio-for-v4.2a' of git://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio into staging-next
Jonathan writes: First round of new drivers, functionality and cleanups for the 4.2 cycle New drivers / device support * st sensors driver, lsm303dlh magnetometer support. * ltr501 - support ltr301 and ltr559 chips. New functionality * IIO_CHAN_INFO_CALIBEMISSIVITY for thermopile sensors. * kxcjk1013 - make driver operational with external trigger. * Add iio targets to the tools Makefile. Cleanups * st sensors - more helpful error message if device id wrong or irq request fails, explicitly make the Block Data Update optional rather than relying on writes to address 0 not doing anything, make interrupt support optional (Not always wired, and not all devices actually have an interrupt line.) * kxcjk-1013 white space additions for readability, add the KXCJ9000 ACPI id as seen in the wild. * sx9500 - GPIO reset support, refactor the GPIO interrupt code, add power management, optimize power usage by powering down when possible, rename the gpio interrupt pin to be more useful, trivial return path simplification, trivial formatting fixes. * isl29018 - move towards ABI compliance with a view to moving this driver out of staging, add some brackets to ensure code works as expected. Note there is no actual bug as the condition being tested is always true (with current devices). * ltr501 - add regmap support to get caching etc for later patches, fix a parameter sanity check that always fails (bug introduced earlier in this series), ACPI enumeration support, interrupt rate control support, interrupt support in general and integration time control support, code alignment cleanups. * mma9553 - a number of little cleanups following a review from Hartmut after I'd already applied the original driver patch. * tmp006 - prefix some defines with TMP006 for consistency. * tsl4531 - cleanup some wrong prefixes, presumably from copy and paste. * mlx90614 - check for errors in read values, add power management, add emissivity setting, add device tree binding documentation, fix a duplicate const warning. * ti_am335x_adc - refactor the DT parsing into a separate function.
Diffstat (limited to 'drivers/iio/accel')
-rw-r--r--drivers/iio/accel/kxcjk-1013.c42
-rw-r--r--drivers/iio/accel/mma9551_core.c8
-rw-r--r--drivers/iio/accel/mma9551_core.h2
-rw-r--r--drivers/iio/accel/mma9553.c148
4 files changed, 91 insertions, 109 deletions
diff --git a/drivers/iio/accel/kxcjk-1013.c b/drivers/iio/accel/kxcjk-1013.c
index 51da3692d561..0d9bd35ff258 100644
--- a/drivers/iio/accel/kxcjk-1013.c
+++ b/drivers/iio/accel/kxcjk-1013.c
@@ -875,15 +875,18 @@ static int kxcjk1013_write_event_config(struct iio_dev *indio_dev,
return 0;
}
-static int kxcjk1013_validate_trigger(struct iio_dev *indio_dev,
- struct iio_trigger *trig)
+static int kxcjk1013_buffer_preenable(struct iio_dev *indio_dev)
{
struct kxcjk1013_data *data = iio_priv(indio_dev);
- if (data->dready_trig != trig && data->motion_trig != trig)
- return -EINVAL;
+ return kxcjk1013_set_power_state(data, true);
+}
- return 0;
+static int kxcjk1013_buffer_postdisable(struct iio_dev *indio_dev)
+{
+ struct kxcjk1013_data *data = iio_priv(indio_dev);
+
+ return kxcjk1013_set_power_state(data, false);
}
static IIO_CONST_ATTR_SAMP_FREQ_AVAIL(
@@ -935,6 +938,13 @@ static const struct iio_chan_spec kxcjk1013_channels[] = {
IIO_CHAN_SOFT_TIMESTAMP(3),
};
+static const struct iio_buffer_setup_ops kxcjk1013_buffer_setup_ops = {
+ .preenable = kxcjk1013_buffer_preenable,
+ .postenable = iio_triggered_buffer_postenable,
+ .postdisable = kxcjk1013_buffer_postdisable,
+ .predisable = iio_triggered_buffer_predisable,
+};
+
static const struct iio_info kxcjk1013_info = {
.attrs = &kxcjk1013_attrs_group,
.read_raw = kxcjk1013_read_raw,
@@ -943,7 +953,6 @@ static const struct iio_info kxcjk1013_info = {
.write_event_value = kxcjk1013_write_event,
.write_event_config = kxcjk1013_write_event_config,
.read_event_config = kxcjk1013_read_event_config,
- .validate_trigger = kxcjk1013_validate_trigger,
.driver_module = THIS_MODULE,
};
@@ -1147,8 +1156,10 @@ static const char *kxcjk1013_match_acpi_device(struct device *dev,
id = acpi_match_device(dev->driver->acpi_match_table, dev);
if (!id)
return NULL;
+
if (strcmp(id->id, "SMO8500") == 0)
*is_smo8500_device = true;
+
*chipset = (enum kx_chipset)id->driver_data;
return dev_name(dev);
@@ -1163,6 +1174,7 @@ static int kxcjk1013_gpio_probe(struct i2c_client *client,
if (!client)
return -EINVAL;
+
if (data->is_smo8500_device)
return -ENOTSUPP;
@@ -1276,16 +1288,15 @@ static int kxcjk1013_probe(struct i2c_client *client,
data->motion_trig = NULL;
goto err_trigger_unregister;
}
+ }
- ret = iio_triggered_buffer_setup(indio_dev,
- &iio_pollfunc_store_time,
- kxcjk1013_trigger_handler,
- NULL);
- if (ret < 0) {
- dev_err(&client->dev,
- "iio triggered buffer setup failed\n");
- goto err_trigger_unregister;
- }
+ ret = iio_triggered_buffer_setup(indio_dev,
+ &iio_pollfunc_store_time,
+ kxcjk1013_trigger_handler,
+ &kxcjk1013_buffer_setup_ops);
+ if (ret < 0) {
+ dev_err(&client->dev, "iio triggered buffer setup failed\n");
+ goto err_trigger_unregister;
}
ret = iio_device_register(indio_dev);
@@ -1418,6 +1429,7 @@ static const struct dev_pm_ops kxcjk1013_pm_ops = {
static const struct acpi_device_id kx_acpi_match[] = {
{"KXCJ1013", KXCJK1013},
{"KXCJ1008", KXCJ91008},
+ {"KXCJ9000", KXCJ91008},
{"KXTJ1009", KXTJ21009},
{"SMO8500", KXCJ91008},
{ },
diff --git a/drivers/iio/accel/mma9551_core.c b/drivers/iio/accel/mma9551_core.c
index 7f55a6d7cd03..54b3ae615a14 100644
--- a/drivers/iio/accel/mma9551_core.c
+++ b/drivers/iio/accel/mma9551_core.c
@@ -374,7 +374,7 @@ EXPORT_SYMBOL(mma9551_read_status_word);
* @app_id: Application ID
* @reg: Application register
* @len: Length of array to read in bytes
- * @val: Array of words to read
+ * @buf: Array of words to read
*
* Read multiple configuration registers (word-sized registers).
*
@@ -409,7 +409,7 @@ EXPORT_SYMBOL(mma9551_read_config_words);
* @app_id: Application ID
* @reg: Application register
* @len: Length of array to read in bytes
- * @val: Array of words to read
+ * @buf: Array of words to read
*
* Read multiple status registers (word-sized registers).
*
@@ -444,7 +444,7 @@ EXPORT_SYMBOL(mma9551_read_status_words);
* @app_id: Application ID
* @reg: Application register
* @len: Length of array to write in bytes
- * @val: Array of words to write
+ * @buf: Array of words to write
*
* Write multiple configuration registers (word-sized registers).
*
@@ -785,7 +785,7 @@ EXPORT_SYMBOL(mma9551_read_accel_scale);
*/
int mma9551_app_reset(struct i2c_client *client, u32 app_mask)
{
- return mma9551_write_config_byte(client, MMA9551_APPID_RCS,
+ return mma9551_write_config_byte(client, MMA9551_APPID_RSC,
MMA9551_RSC_RESET +
MMA9551_RSC_OFFSET(app_mask),
MMA9551_RSC_VAL(app_mask));
diff --git a/drivers/iio/accel/mma9551_core.h b/drivers/iio/accel/mma9551_core.h
index edaa56b1078e..79939e40805a 100644
--- a/drivers/iio/accel/mma9551_core.h
+++ b/drivers/iio/accel/mma9551_core.h
@@ -22,7 +22,7 @@
#define MMA9551_APPID_TILT 0x0B
#define MMA9551_APPID_SLEEP_WAKE 0x12
#define MMA9551_APPID_PEDOMETER 0x15
-#define MMA9551_APPID_RCS 0x17
+#define MMA9551_APPID_RSC 0x17
#define MMA9551_APPID_NONE 0xff
/* Reset/Suspend/Clear application app masks */
diff --git a/drivers/iio/accel/mma9553.c b/drivers/iio/accel/mma9553.c
index 2df1af7d43fc..9d649c4a21fd 100644
--- a/drivers/iio/accel/mma9553.c
+++ b/drivers/iio/accel/mma9553.c
@@ -62,8 +62,8 @@
#define MMA9553_MASK_STATUS_STEPCHG BIT(13)
#define MMA9553_MASK_STATUS_ACTCHG BIT(12)
#define MMA9553_MASK_STATUS_SUSP BIT(11)
-#define MMA9553_MASK_STATUS_ACTIVITY (BIT(10) | BIT(9) | BIT(8))
-#define MMA9553_MASK_STATUS_VERSION 0x00FF
+#define MMA9553_MASK_STATUS_ACTIVITY GENMASK(10, 8)
+#define MMA9553_MASK_STATUS_VERSION GENMASK(7, 0)
#define MMA9553_REG_STEPCNT 0x02
#define MMA9553_REG_DISTANCE 0x04
@@ -75,14 +75,15 @@
#define MMA9553_DEFAULT_GPIO_PIN mma9551_gpio6
#define MMA9553_DEFAULT_GPIO_POLARITY 0
-/* Bitnum used for gpio configuration = bit number in high status byte */
-#define STATUS_TO_BITNUM(bit) (ffs(bit) - 9)
+/* Bitnum used for GPIO configuration = bit number in high status byte */
+#define MMA9553_STATUS_TO_BITNUM(bit) (ffs(bit) - 9)
+#define MMA9553_MAX_BITNUM MMA9553_STATUS_TO_BITNUM(BIT(16))
#define MMA9553_DEFAULT_SAMPLE_RATE 30 /* Hz */
/*
* The internal activity level must be stable for ACTTHD samples before
- * ACTIVITY is updated.The ACTIVITY variable contains the current activity
+ * ACTIVITY is updated. The ACTIVITY variable contains the current activity
* level and is updated every time a step is detected or once a second
* if there are no steps.
*/
@@ -353,11 +354,11 @@ static int mma9553_conf_gpio(struct mma9553_data *data)
* This bit is the logical OR of the SUSPCHG, STEPCHG, and ACTCHG flags.
*/
if (activity_enabled && ev_step_detect->enabled)
- bitnum = STATUS_TO_BITNUM(MMA9553_MASK_STATUS_MRGFL);
+ bitnum = MMA9553_STATUS_TO_BITNUM(MMA9553_MASK_STATUS_MRGFL);
else if (ev_step_detect->enabled)
- bitnum = STATUS_TO_BITNUM(MMA9553_MASK_STATUS_STEPCHG);
+ bitnum = MMA9553_STATUS_TO_BITNUM(MMA9553_MASK_STATUS_STEPCHG);
else if (activity_enabled)
- bitnum = STATUS_TO_BITNUM(MMA9553_MASK_STATUS_ACTCHG);
+ bitnum = MMA9553_STATUS_TO_BITNUM(MMA9553_MASK_STATUS_ACTCHG);
else /* Reset */
appid = MMA9551_APPID_NONE;
@@ -365,9 +366,12 @@ static int mma9553_conf_gpio(struct mma9553_data *data)
return 0;
/* Save initial values for activity and stepcnt */
- if (activity_enabled || ev_step_detect->enabled)
- mma9553_read_activity_stepcnt(data, &data->activity,
- &data->stepcnt);
+ if (activity_enabled || ev_step_detect->enabled) {
+ ret = mma9553_read_activity_stepcnt(data, &data->activity,
+ &data->stepcnt);
+ if (ret < 0)
+ return ret;
+ }
ret = mma9551_gpio_config(data->client,
MMA9553_DEFAULT_GPIO_PIN,
@@ -398,13 +402,13 @@ static int mma9553_init(struct mma9553_data *data)
sizeof(data->conf), (u16 *) &data->conf);
if (ret < 0) {
dev_err(&data->client->dev,
- "device is not MMA9553L: failed to read cfg regs\n");
+ "failed to read configuration registers\n");
return ret;
}
- /* Reset gpio */
- data->gpio_bitnum = -1;
+ /* Reset GPIO */
+ data->gpio_bitnum = MMA9553_MAX_BITNUM;
ret = mma9553_conf_gpio(data);
if (ret < 0)
return ret;
@@ -438,6 +442,32 @@ static int mma9553_init(struct mma9553_data *data)
return mma9551_set_device_state(data->client, true);
}
+static int mma9553_read_status_word(struct mma9553_data *data, u16 reg,
+ u16 *tmp)
+{
+ bool powered_on;
+ int ret;
+
+ /*
+ * The HW only counts steps and other dependent
+ * parameters (speed, distance, calories, activity)
+ * if power is on (from enabling an event or the
+ * step counter).
+ */
+ powered_on = mma9553_is_any_event_enabled(data, false, 0) ||
+ data->stepcnt_enabled;
+ if (!powered_on) {
+ dev_err(&data->client->dev, "No channels enabled\n");
+ return -EINVAL;
+ }
+
+ mutex_lock(&data->mutex);
+ ret = mma9551_read_status_word(data->client, MMA9551_APPID_PEDOMETER,
+ reg, tmp);
+ mutex_unlock(&data->mutex);
+ return ret;
+}
+
static int mma9553_read_raw(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan,
int *val, int *val2, long mask)
@@ -446,69 +476,30 @@ static int mma9553_read_raw(struct iio_dev *indio_dev,
int ret;
u16 tmp;
u8 activity;
- bool powered_on;
switch (mask) {
case IIO_CHAN_INFO_PROCESSED:
switch (chan->type) {
case IIO_STEPS:
- /*
- * The HW only counts steps and other dependent
- * parameters (speed, distance, calories, activity)
- * if power is on (from enabling an event or the
- * step counter */
- powered_on =
- mma9553_is_any_event_enabled(data, false, 0) ||
- data->stepcnt_enabled;
- if (!powered_on) {
- dev_err(&data->client->dev,
- "No channels enabled\n");
- return -EINVAL;
- }
- mutex_lock(&data->mutex);
- ret = mma9551_read_status_word(data->client,
- MMA9551_APPID_PEDOMETER,
+ ret = mma9553_read_status_word(data,
MMA9553_REG_STEPCNT,
&tmp);
- mutex_unlock(&data->mutex);
if (ret < 0)
return ret;
*val = tmp;
return IIO_VAL_INT;
case IIO_DISTANCE:
- powered_on =
- mma9553_is_any_event_enabled(data, false, 0) ||
- data->stepcnt_enabled;
- if (!powered_on) {
- dev_err(&data->client->dev,
- "No channels enabled\n");
- return -EINVAL;
- }
- mutex_lock(&data->mutex);
- ret = mma9551_read_status_word(data->client,
- MMA9551_APPID_PEDOMETER,
+ ret = mma9553_read_status_word(data,
MMA9553_REG_DISTANCE,
&tmp);
- mutex_unlock(&data->mutex);
if (ret < 0)
return ret;
*val = tmp;
return IIO_VAL_INT;
case IIO_ACTIVITY:
- powered_on =
- mma9553_is_any_event_enabled(data, false, 0) ||
- data->stepcnt_enabled;
- if (!powered_on) {
- dev_err(&data->client->dev,
- "No channels enabled\n");
- return -EINVAL;
- }
- mutex_lock(&data->mutex);
- ret = mma9551_read_status_word(data->client,
- MMA9551_APPID_PEDOMETER,
+ ret = mma9553_read_status_word(data,
MMA9553_REG_STATUS,
&tmp);
- mutex_unlock(&data->mutex);
if (ret < 0)
return ret;
@@ -533,38 +524,17 @@ static int mma9553_read_raw(struct iio_dev *indio_dev,
case IIO_VELOCITY: /* m/h */
if (chan->channel2 != IIO_MOD_ROOT_SUM_SQUARED_X_Y_Z)
return -EINVAL;
- powered_on =
- mma9553_is_any_event_enabled(data, false, 0) ||
- data->stepcnt_enabled;
- if (!powered_on) {
- dev_err(&data->client->dev,
- "No channels enabled\n");
- return -EINVAL;
- }
- mutex_lock(&data->mutex);
- ret = mma9551_read_status_word(data->client,
- MMA9551_APPID_PEDOMETER,
- MMA9553_REG_SPEED, &tmp);
- mutex_unlock(&data->mutex);
+ ret = mma9553_read_status_word(data,
+ MMA9553_REG_SPEED,
+ &tmp);
if (ret < 0)
return ret;
*val = tmp;
return IIO_VAL_INT;
case IIO_ENERGY: /* Cal or kcal */
- powered_on =
- mma9553_is_any_event_enabled(data, false, 0) ||
- data->stepcnt_enabled;
- if (!powered_on) {
- dev_err(&data->client->dev,
- "No channels enabled\n");
- return -EINVAL;
- }
- mutex_lock(&data->mutex);
- ret = mma9551_read_status_word(data->client,
- MMA9551_APPID_PEDOMETER,
+ ret = mma9553_read_status_word(data,
MMA9553_REG_CALORIES,
&tmp);
- mutex_unlock(&data->mutex);
if (ret < 0)
return ret;
*val = tmp;
@@ -791,7 +761,7 @@ static int mma9553_write_event_config(struct iio_dev *indio_dev,
mutex_unlock(&data->mutex);
- return ret;
+ return 0;
err_conf_gpio:
if (state) {
@@ -896,7 +866,7 @@ static int mma9553_get_calibgender_mode(struct iio_dev *indio_dev,
gender = mma9553_get_bits(data->conf.filter, MMA9553_MASK_CONF_MALE);
/*
* HW expects 0 for female and 1 for male,
- * while iio index is 0 for male and 1 for female
+ * while iio index is 0 for male and 1 for female.
*/
return !gender;
}
@@ -943,11 +913,11 @@ static const struct iio_event_spec mma9553_activity_events[] = {
},
};
-static const char * const calibgender_modes[] = { "male", "female" };
+static const char * const mma9553_calibgender_modes[] = { "male", "female" };
static const struct iio_enum mma9553_calibgender_enum = {
- .items = calibgender_modes,
- .num_items = ARRAY_SIZE(calibgender_modes),
+ .items = mma9553_calibgender_modes,
+ .num_items = ARRAY_SIZE(mma9553_calibgender_modes),
.get = mma9553_get_calibgender_mode,
.set = mma9553_set_calibgender_mode,
};
@@ -1108,16 +1078,16 @@ static int mma9553_gpio_probe(struct i2c_client *client)
dev = &client->dev;
- /* data ready gpio interrupt pin */
+ /* data ready GPIO interrupt pin */
gpio = devm_gpiod_get_index(dev, MMA9553_GPIO_NAME, 0, GPIOD_IN);
if (IS_ERR(gpio)) {
- dev_err(dev, "acpi gpio get index failed\n");
+ dev_err(dev, "ACPI GPIO get index failed\n");
return PTR_ERR(gpio);
}
ret = gpiod_to_irq(gpio);
- dev_dbg(dev, "gpio resource, no:%d irq:%d\n", desc_to_gpio(gpio), ret);
+ dev_dbg(dev, "GPIO resource, no:%d irq:%d\n", desc_to_gpio(gpio), ret);
return ret;
}