projects
/
cascardo
/
linux.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
Merge tag 'iio-for-3.20a_take2' of git://git.kernel.org/pub/scm/linux/kernel/git...
[cascardo/linux.git]
/
drivers
/
iio
/
accel
/
kxcjk-1013.c
diff --git
a/drivers/iio/accel/kxcjk-1013.c
b/drivers/iio/accel/kxcjk-1013.c
index
da2fe93
..
567de26
100644
(file)
--- a/
drivers/iio/accel/kxcjk-1013.c
+++ b/
drivers/iio/accel/kxcjk-1013.c
@@
-108,6
+108,7
@@
struct kxcjk1013_data {
bool motion_trigger_on;
int64_t timestamp;
enum kx_chipset chipset;
bool motion_trigger_on;
int64_t timestamp;
enum kx_chipset chipset;
+ bool is_smo8500_device;
};
enum kxcjk1013_axis {
};
enum kxcjk1013_axis {
@@
-377,6
+378,7
@@
static int kxcjk1013_get_startup_times(struct kxcjk1013_data *data)
static int kxcjk1013_set_power_state(struct kxcjk1013_data *data, bool on)
{
static int kxcjk1013_set_power_state(struct kxcjk1013_data *data, bool on)
{
+#ifdef CONFIG_PM
int ret;
if (on)
int ret;
if (on)
@@
-388,8
+390,11
@@
static int kxcjk1013_set_power_state(struct kxcjk1013_data *data, bool on)
if (ret < 0) {
dev_err(&data->client->dev,
"Failed: kxcjk1013_set_power_state for %d\n", on);
if (ret < 0) {
dev_err(&data->client->dev,
"Failed: kxcjk1013_set_power_state for %d\n", on);
+ if (on)
+ pm_runtime_put_noidle(&data->client->dev);
return ret;
}
return ret;
}
+#endif
return 0;
}
return 0;
}
@@
-858,6
+863,8
@@
static int kxcjk1013_write_event_config(struct iio_dev *indio_dev,
ret = kxcjk1013_setup_any_motion_interrupt(data, state);
if (ret < 0) {
ret = kxcjk1013_setup_any_motion_interrupt(data, state);
if (ret < 0) {
+ kxcjk1013_set_power_state(data, false);
+ data->ev_enable_state = 0;
mutex_unlock(&data->mutex);
return ret;
}
mutex_unlock(&data->mutex);
return ret;
}
@@
-1008,6
+1015,7
@@
static int kxcjk1013_data_rdy_trigger_set_state(struct iio_trigger *trig,
else
ret = kxcjk1013_setup_new_data_interrupt(data, state);
if (ret < 0) {
else
ret = kxcjk1013_setup_new_data_interrupt(data, state);
if (ret < 0) {
+ kxcjk1013_set_power_state(data, false);
mutex_unlock(&data->mutex);
return ret;
}
mutex_unlock(&data->mutex);
return ret;
}
@@
-1131,12
+1139,16
@@
static irqreturn_t kxcjk1013_data_rdy_trig_poll(int irq, void *private)
}
static const char *kxcjk1013_match_acpi_device(struct device *dev,
}
static const char *kxcjk1013_match_acpi_device(struct device *dev,
- enum kx_chipset *chipset)
+ enum kx_chipset *chipset,
+ bool *is_smo8500_device)
{
const struct acpi_device_id *id;
{
const struct acpi_device_id *id;
+
id = acpi_match_device(dev->driver->acpi_match_table, dev);
if (!id)
return NULL;
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);
*chipset = (enum kx_chipset)id->driver_data;
return dev_name(dev);
@@
-1151,6
+1163,8
@@
static int kxcjk1013_gpio_probe(struct i2c_client *client,
if (!client)
return -EINVAL;
if (!client)
return -EINVAL;
+ if (data->is_smo8500_device)
+ return -ENOTSUPP;
dev = &client->dev;
dev = &client->dev;
@@
-1200,7
+1214,8
@@
static int kxcjk1013_probe(struct i2c_client *client,
name = id->name;
} else if (ACPI_HANDLE(&client->dev)) {
name = kxcjk1013_match_acpi_device(&client->dev,
name = id->name;
} else if (ACPI_HANDLE(&client->dev)) {
name = kxcjk1013_match_acpi_device(&client->dev,
- &data->chipset);
+ &data->chipset,
+ &data->is_smo8500_device);
} else
return -ENODEV;
} else
return -ENODEV;
@@
-1228,21
+1243,25
@@
static int kxcjk1013_probe(struct i2c_client *client,
KXCJK1013_IRQ_NAME,
indio_dev);
if (ret)
KXCJK1013_IRQ_NAME,
indio_dev);
if (ret)
-
return ret
;
+
goto err_poweroff
;
data->dready_trig = devm_iio_trigger_alloc(&client->dev,
"%s-dev%d",
indio_dev->name,
indio_dev->id);
data->dready_trig = devm_iio_trigger_alloc(&client->dev,
"%s-dev%d",
indio_dev->name,
indio_dev->id);
- if (!data->dready_trig)
- return -ENOMEM;
+ if (!data->dready_trig) {
+ ret = -ENOMEM;
+ goto err_poweroff;
+ }
data->motion_trig = devm_iio_trigger_alloc(&client->dev,
"%s-any-motion-dev%d",
indio_dev->name,
indio_dev->id);
data->motion_trig = devm_iio_trigger_alloc(&client->dev,
"%s-any-motion-dev%d",
indio_dev->name,
indio_dev->id);
- if (!data->motion_trig)
- return -ENOMEM;
+ if (!data->motion_trig) {
+ ret = -ENOMEM;
+ goto err_poweroff;
+ }
data->dready_trig->dev.parent = &client->dev;
data->dready_trig->ops = &kxcjk1013_trigger_ops;
data->dready_trig->dev.parent = &client->dev;
data->dready_trig->ops = &kxcjk1013_trigger_ops;
@@
-1251,7
+1270,7
@@
static int kxcjk1013_probe(struct i2c_client *client,
iio_trigger_get(indio_dev->trig);
ret = iio_trigger_register(data->dready_trig);
if (ret)
iio_trigger_get(indio_dev->trig);
ret = iio_trigger_register(data->dready_trig);
if (ret)
-
return ret
;
+
goto err_poweroff
;
data->motion_trig->dev.parent = &client->dev;
data->motion_trig->ops = &kxcjk1013_trigger_ops;
data->motion_trig->dev.parent = &client->dev;
data->motion_trig->ops = &kxcjk1013_trigger_ops;
@@
-1300,6
+1319,8
@@
err_trigger_unregister:
iio_trigger_unregister(data->dready_trig);
if (data->motion_trig)
iio_trigger_unregister(data->motion_trig);
iio_trigger_unregister(data->dready_trig);
if (data->motion_trig)
iio_trigger_unregister(data->motion_trig);
+err_poweroff:
+ kxcjk1013_set_mode(data, STANDBY);
return ret;
}
return ret;
}
@@
-1349,10
+1370,7
@@
static int kxcjk1013_resume(struct device *dev)
int ret = 0;
mutex_lock(&data->mutex);
int ret = 0;
mutex_lock(&data->mutex);
- /* Check, if the suspend occured while active */
- if (data->dready_trigger_on || data->motion_trigger_on ||
- data->ev_enable_state)
- ret = kxcjk1013_set_mode(data, OPERATION);
+ ret = kxcjk1013_set_mode(data, OPERATION);
mutex_unlock(&data->mutex);
return ret;
mutex_unlock(&data->mutex);
return ret;
@@
-1364,8
+1382,14
@@
static int kxcjk1013_runtime_suspend(struct device *dev)
{
struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
struct kxcjk1013_data *data = iio_priv(indio_dev);
{
struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
struct kxcjk1013_data *data = iio_priv(indio_dev);
+ int ret;
- return kxcjk1013_set_mode(data, STANDBY);
+ ret = kxcjk1013_set_mode(data, STANDBY);
+ if (ret < 0) {
+ dev_err(&data->client->dev, "powering off device failed\n");
+ return -EAGAIN;
+ }
+ return 0;
}
static int kxcjk1013_runtime_resume(struct device *dev)
}
static int kxcjk1013_runtime_resume(struct device *dev)
@@
-1399,6
+1423,7
@@
static const struct acpi_device_id kx_acpi_match[] = {
{"KXCJ1013", KXCJK1013},
{"KXCJ1008", KXCJ91008},
{"KXTJ1009", KXTJ21009},
{"KXCJ1013", KXCJK1013},
{"KXCJ1008", KXCJ91008},
{"KXTJ1009", KXTJ21009},
+ {"SMO8500", KXCJ91008},
{ },
};
MODULE_DEVICE_TABLE(acpi, kx_acpi_match);
{ },
};
MODULE_DEVICE_TABLE(acpi, kx_acpi_match);
@@
-1407,6
+1432,7
@@
static const struct i2c_device_id kxcjk1013_id[] = {
{"kxcjk1013", KXCJK1013},
{"kxcj91008", KXCJ91008},
{"kxtj21009", KXTJ21009},
{"kxcjk1013", KXCJK1013},
{"kxcj91008", KXCJ91008},
{"kxtj21009", KXTJ21009},
+ {"SMO8500", KXCJ91008},
{}
};
{}
};