Commit af6e1d99 authored by Dmitry Torokhov's avatar Dmitry Torokhov

Input: adxl34 - make enable/disable separate from suspend/resume

Suspending and resuming the device should be separate from enabling
and disabling it through sysfs attribute and thus should not alter
ac->disabled flag.

[michael.hennerich@analog.com: various fixups]
Tested-by: default avatarMichael Hennerich <michael.hennerich@analog.com>
Signed-off-by: default avatarDmitry Torokhov <dtor@mail.ru>
parent 963ce8ae
...@@ -58,14 +58,14 @@ static int adxl34x_i2c_read_block(struct device *dev, ...@@ -58,14 +58,14 @@ static int adxl34x_i2c_read_block(struct device *dev,
return 0; return 0;
} }
static const struct adxl34x_bus_ops adx134x_smbus_bops = { static const struct adxl34x_bus_ops adxl34x_smbus_bops = {
.bustype = BUS_I2C, .bustype = BUS_I2C,
.write = adxl34x_smbus_write, .write = adxl34x_smbus_write,
.read = adxl34x_smbus_read, .read = adxl34x_smbus_read,
.read_block = adxl34x_smbus_read_block, .read_block = adxl34x_smbus_read_block,
}; };
static const struct adxl34x_bus_ops adx134x_i2c_bops = { static const struct adxl34x_bus_ops adxl34x_i2c_bops = {
.bustype = BUS_I2C, .bustype = BUS_I2C,
.write = adxl34x_smbus_write, .write = adxl34x_smbus_write,
.read = adxl34x_smbus_read, .read = adxl34x_smbus_read,
...@@ -88,7 +88,7 @@ static int __devinit adxl34x_i2c_probe(struct i2c_client *client, ...@@ -88,7 +88,7 @@ static int __devinit adxl34x_i2c_probe(struct i2c_client *client,
ac = adxl34x_probe(&client->dev, client->irq, false, ac = adxl34x_probe(&client->dev, client->irq, false,
i2c_check_functionality(client->adapter, i2c_check_functionality(client->adapter,
I2C_FUNC_SMBUS_READ_I2C_BLOCK) ? I2C_FUNC_SMBUS_READ_I2C_BLOCK) ?
&adx134x_smbus_bops : &adx134x_i2c_bops); &adxl34x_smbus_bops : &adxl34x_i2c_bops);
if (IS_ERR(ac)) if (IS_ERR(ac))
return PTR_ERR(ac); return PTR_ERR(ac);
...@@ -105,26 +105,26 @@ static int __devexit adxl34x_i2c_remove(struct i2c_client *client) ...@@ -105,26 +105,26 @@ static int __devexit adxl34x_i2c_remove(struct i2c_client *client)
} }
#ifdef CONFIG_PM #ifdef CONFIG_PM
static int adxl34x_suspend(struct i2c_client *client, pm_message_t message) static int adxl34x_i2c_suspend(struct i2c_client *client, pm_message_t message)
{ {
struct adxl34x *ac = i2c_get_clientdata(client); struct adxl34x *ac = i2c_get_clientdata(client);
adxl34x_disable(ac); adxl34x_suspend(ac);
return 0; return 0;
} }
static int adxl34x_resume(struct i2c_client *client) static int adxl34x_i2c_resume(struct i2c_client *client)
{ {
struct adxl34x *ac = i2c_get_clientdata(client); struct adxl34x *ac = i2c_get_clientdata(client);
adxl34x_enable(ac); adxl34x_resume(ac);
return 0; return 0;
} }
#else #else
# define adxl34x_suspend NULL # define adxl34x_i2c_suspend NULL
# define adxl34x_resume NULL # define adxl34x_i2c_resume NULL
#endif #endif
static const struct i2c_device_id adxl34x_id[] = { static const struct i2c_device_id adxl34x_id[] = {
...@@ -141,8 +141,8 @@ static struct i2c_driver adxl34x_driver = { ...@@ -141,8 +141,8 @@ static struct i2c_driver adxl34x_driver = {
}, },
.probe = adxl34x_i2c_probe, .probe = adxl34x_i2c_probe,
.remove = __devexit_p(adxl34x_i2c_remove), .remove = __devexit_p(adxl34x_i2c_remove),
.suspend = adxl34x_suspend, .suspend = adxl34x_i2c_suspend,
.resume = adxl34x_resume, .resume = adxl34x_i2c_resume,
.id_table = adxl34x_id, .id_table = adxl34x_id,
}; };
......
...@@ -94,26 +94,26 @@ static int __devexit adxl34x_spi_remove(struct spi_device *spi) ...@@ -94,26 +94,26 @@ static int __devexit adxl34x_spi_remove(struct spi_device *spi)
} }
#ifdef CONFIG_PM #ifdef CONFIG_PM
static int adxl34x_suspend(struct spi_device *spi, pm_message_t message) static int adxl34x_spi_suspend(struct spi_device *spi, pm_message_t message)
{ {
struct adxl34x *ac = dev_get_drvdata(&spi->dev); struct adxl34x *ac = dev_get_drvdata(&spi->dev);
adxl34x_disable(ac); adxl34x_suspend(ac);
return 0; return 0;
} }
static int adxl34x_resume(struct spi_device *spi) static int adxl34x_spi_resume(struct spi_device *spi)
{ {
struct adxl34x *ac = dev_get_drvdata(&spi->dev); struct adxl34x *ac = dev_get_drvdata(&spi->dev);
adxl34x_enable(ac); adxl34x_resume(ac);
return 0; return 0;
} }
#else #else
# define adxl34x_suspend NULL # define adxl34x_spi_suspend NULL
# define adxl34x_resume NULL # define adxl34x_spi_resume NULL
#endif #endif
static struct spi_driver adxl34x_driver = { static struct spi_driver adxl34x_driver = {
...@@ -124,8 +124,8 @@ static struct spi_driver adxl34x_driver = { ...@@ -124,8 +124,8 @@ static struct spi_driver adxl34x_driver = {
}, },
.probe = adxl34x_spi_probe, .probe = adxl34x_spi_probe,
.remove = __devexit_p(adxl34x_spi_remove), .remove = __devexit_p(adxl34x_spi_remove),
.suspend = adxl34x_suspend, .suspend = adxl34x_spi_suspend,
.resume = adxl34x_resume, .resume = adxl34x_spi_resume,
}; };
static int __init adxl34x_spi_init(void) static int __init adxl34x_spi_init(void)
......
...@@ -200,6 +200,7 @@ struct adxl34x { ...@@ -200,6 +200,7 @@ struct adxl34x {
unsigned orient3d_saved; unsigned orient3d_saved;
bool disabled; /* P: mutex */ bool disabled; /* P: mutex */
bool opened; /* P: mutex */ bool opened; /* P: mutex */
bool suspended; /* P: mutex */
bool fifo_delay; bool fifo_delay;
int irq; int irq;
unsigned model; unsigned model;
...@@ -399,41 +400,44 @@ static irqreturn_t adxl34x_irq(int irq, void *handle) ...@@ -399,41 +400,44 @@ static irqreturn_t adxl34x_irq(int irq, void *handle)
static void __adxl34x_disable(struct adxl34x *ac) static void __adxl34x_disable(struct adxl34x *ac)
{ {
if (!ac->disabled && ac->opened) { /*
/* * A '0' places the ADXL34x into standby mode
* A '0' places the ADXL34x into standby mode * with minimum power consumption.
* with minimum power consumption. */
*/ AC_WRITE(ac, POWER_CTL, 0);
AC_WRITE(ac, POWER_CTL, 0);
ac->disabled = true;
}
} }
static void __adxl34x_enable(struct adxl34x *ac) static void __adxl34x_enable(struct adxl34x *ac)
{ {
if (ac->disabled && ac->opened) { AC_WRITE(ac, POWER_CTL, ac->pdata.power_mode | PCTL_MEASURE);
AC_WRITE(ac, POWER_CTL, ac->pdata.power_mode | PCTL_MEASURE);
ac->disabled = false;
}
} }
void adxl34x_disable(struct adxl34x *ac) void adxl34x_suspend(struct adxl34x *ac)
{ {
mutex_lock(&ac->mutex); mutex_lock(&ac->mutex);
__adxl34x_disable(ac);
if (!ac->suspended && !ac->disabled && ac->opened)
__adxl34x_disable(ac);
ac->suspended = true;
mutex_unlock(&ac->mutex); mutex_unlock(&ac->mutex);
} }
EXPORT_SYMBOL_GPL(adxl34x_disable); EXPORT_SYMBOL_GPL(adxl34x_suspend);
void adxl34x_enable(struct adxl34x *ac) void adxl34x_resume(struct adxl34x *ac)
{ {
mutex_lock(&ac->mutex); mutex_lock(&ac->mutex);
__adxl34x_enable(ac);
if (ac->suspended && !ac->disabled && ac->opened)
__adxl34x_enable(ac);
ac->suspended= false;
mutex_unlock(&ac->mutex); mutex_unlock(&ac->mutex);
} }
EXPORT_SYMBOL_GPL(adxl34x_enable); EXPORT_SYMBOL_GPL(adxl34x_resume);
static ssize_t adxl34x_disable_show(struct device *dev, static ssize_t adxl34x_disable_show(struct device *dev,
struct device_attribute *attr, char *buf) struct device_attribute *attr, char *buf)
...@@ -455,10 +459,21 @@ static ssize_t adxl34x_disable_store(struct device *dev, ...@@ -455,10 +459,21 @@ static ssize_t adxl34x_disable_store(struct device *dev,
if (error) if (error)
return error; return error;
if (val) mutex_lock(&ac->mutex);
adxl34x_disable(ac);
else if (!ac->suspended && ac->opened) {
adxl34x_enable(ac); if (val) {
if (!ac->disabled)
__adxl34x_disable(ac);
} else {
if (ac->disabled)
__adxl34x_enable(ac);
}
}
ac->disabled = !!val;
mutex_unlock(&ac->mutex);
return count; return count;
} }
...@@ -575,7 +590,7 @@ static ssize_t adxl34x_autosleep_store(struct device *dev, ...@@ -575,7 +590,7 @@ static ssize_t adxl34x_autosleep_store(struct device *dev,
else else
ac->pdata.power_mode &= ~(PCTL_AUTO_SLEEP | PCTL_LINK); ac->pdata.power_mode &= ~(PCTL_AUTO_SLEEP | PCTL_LINK);
if (!ac->disabled && ac->opened) if (!ac->disabled && !ac->suspended && ac->opened)
AC_WRITE(ac, POWER_CTL, ac->pdata.power_mode | PCTL_MEASURE); AC_WRITE(ac, POWER_CTL, ac->pdata.power_mode | PCTL_MEASURE);
mutex_unlock(&ac->mutex); mutex_unlock(&ac->mutex);
...@@ -649,8 +664,12 @@ static int adxl34x_input_open(struct input_dev *input) ...@@ -649,8 +664,12 @@ static int adxl34x_input_open(struct input_dev *input)
struct adxl34x *ac = input_get_drvdata(input); struct adxl34x *ac = input_get_drvdata(input);
mutex_lock(&ac->mutex); mutex_lock(&ac->mutex);
if (!ac->suspended && !ac->disabled)
__adxl34x_enable(ac);
ac->opened = true; ac->opened = true;
__adxl34x_enable(ac);
mutex_unlock(&ac->mutex); mutex_unlock(&ac->mutex);
return 0; return 0;
...@@ -661,8 +680,12 @@ static void adxl34x_input_close(struct input_dev *input) ...@@ -661,8 +680,12 @@ static void adxl34x_input_close(struct input_dev *input)
struct adxl34x *ac = input_get_drvdata(input); struct adxl34x *ac = input_get_drvdata(input);
mutex_lock(&ac->mutex); mutex_lock(&ac->mutex);
__adxl34x_disable(ac);
if (!ac->suspended && !ac->disabled)
__adxl34x_disable(ac);
ac->opened = false; ac->opened = false;
mutex_unlock(&ac->mutex); mutex_unlock(&ac->mutex);
} }
...@@ -878,7 +901,6 @@ EXPORT_SYMBOL_GPL(adxl34x_probe); ...@@ -878,7 +901,6 @@ EXPORT_SYMBOL_GPL(adxl34x_probe);
int adxl34x_remove(struct adxl34x *ac) int adxl34x_remove(struct adxl34x *ac)
{ {
adxl34x_disable(ac);
sysfs_remove_group(&ac->dev->kobj, &adxl34x_attr_group); sysfs_remove_group(&ac->dev->kobj, &adxl34x_attr_group);
free_irq(ac->irq, ac); free_irq(ac->irq, ac);
input_unregister_device(ac->input); input_unregister_device(ac->input);
......
...@@ -20,8 +20,8 @@ struct adxl34x_bus_ops { ...@@ -20,8 +20,8 @@ struct adxl34x_bus_ops {
int (*write)(struct device *, unsigned char, unsigned char); int (*write)(struct device *, unsigned char, unsigned char);
}; };
void adxl34x_disable(struct adxl34x *ac); void adxl34x_suspend(struct adxl34x *ac);
void adxl34x_enable(struct adxl34x *ac); void adxl34x_resume(struct adxl34x *ac);
struct adxl34x *adxl34x_probe(struct device *dev, int irq, struct adxl34x *adxl34x_probe(struct device *dev, int irq,
bool fifo_delay_default, bool fifo_delay_default,
const struct adxl34x_bus_ops *bops); const struct adxl34x_bus_ops *bops);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment