Modified: trunk/drivers/input/misc/adxl34x-i2c.c (9004 => 9005)
--- trunk/drivers/input/misc/adxl34x-i2c.c 2010-07-21 13:13:23 UTC (rev 9004)
+++ trunk/drivers/input/misc/adxl34x-i2c.c 2010-07-21 13:41:17 UTC (rev 9005)
@@ -16,6 +16,7 @@
static int adxl34x_smbus_read(struct device *dev, unsigned char reg)
{
struct i2c_client *client = to_i2c_client(dev);
+
return i2c_smbus_read_byte_data(client, reg);
}
@@ -23,20 +24,22 @@
unsigned char reg, unsigned char val)
{
struct i2c_client *client = to_i2c_client(dev);
+
return i2c_smbus_write_byte_data(client, reg, val);
}
static int adxl34x_smbus_read_block(struct device *dev,
unsigned char reg, int count,
- unsigned char *buf)
+ void *buf)
{
struct i2c_client *client = to_i2c_client(dev);
+
return i2c_smbus_read_i2c_block_data(client, reg, count, buf);
}
static int adxl34x_i2c_read_block(struct device *dev,
unsigned char reg, int count,
- unsigned char *buf)
+ void *buf)
{
struct i2c_client *client = to_i2c_client(dev);
int ret;
@@ -44,19 +47,34 @@
ret = i2c_master_send(client, ®, 1);
if (ret < 0)
return ret;
+
ret = i2c_master_recv(client, buf, count);
if (ret < 0)
return ret;
+
if (ret != count)
return -EIO;
return 0;
}
+static const struct adxl34x_bus_ops adx134x_smbus_bops = {
+ .bustype = BUS_I2C,
+ .write = adxl34x_smbus_write,
+ .read = adxl34x_smbus_read,
+ .read_block = adxl34x_smbus_read_block,
+};
+
+static const struct adxl34x_bus_ops adx134x_i2c_bops = {
+ .bustype = BUS_I2C,
+ .write = adxl34x_smbus_write,
+ .read = adxl34x_smbus_read,
+ .read_block = adxl34x_i2c_read_block,
+};
+
static int __devinit adxl34x_i2c_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
- struct adxl34x_bus_ops bops;
struct adxl34x *ac;
int error;
@@ -67,36 +85,41 @@
return -EIO;
}
- bops.bustype = BUS_I2C;
- bops.write = adxl34x_smbus_write;
- bops.read = adxl34x_smbus_read;
- if (i2c_check_functionality(client->adapter,
- I2C_FUNC_SMBUS_READ_I2C_BLOCK))
- bops.read_block = adxl34x_smbus_read_block;
- else
- bops.read_block = adxl34x_i2c_read_block;
+ ac = adxl34x_probe(&client->dev, client->irq, false,
+ i2c_check_functionality(client->adapter,
+ I2C_FUNC_SMBUS_READ_I2C_BLOCK) ?
+ &adx134x_smbus_bops : &adx134x_i2c_bops);
+ if (IS_ERR(ac))
+ return PTR_ERR(ac);
- error = adxl34x_probe(&ac, &client->dev, client->irq, 0, &bops);
i2c_set_clientdata(client, ac);
- return error;
+ return 0;
}
static int __devexit adxl34x_i2c_remove(struct i2c_client *client)
{
- return adxl34x_remove(i2c_get_clientdata(client));
+ struct adxl34x *ac = i2c_get_clientdata(client);
+
+ return adxl34x_remove(ac);
}
#ifdef CONFIG_PM
static int adxl34x_suspend(struct i2c_client *client, pm_message_t message)
{
- adxl34x_disable(i2c_get_clientdata(client));
+ struct adxl34x *ac = i2c_get_clientdata(client);
+
+ adxl34x_disable(ac);
+
return 0;
}
static int adxl34x_resume(struct i2c_client *client)
{
- adxl34x_enable(i2c_get_clientdata(client));
+ struct adxl34x *ac = i2c_get_clientdata(client);
+
+ adxl34x_enable(ac);
+
return 0;
}
#else
Modified: trunk/drivers/input/misc/adxl34x.c (9004 => 9005)
--- trunk/drivers/input/misc/adxl34x.c 2010-07-21 13:13:23 UTC (rev 9004)
+++ trunk/drivers/input/misc/adxl34x.c 2010-07-21 13:41:17 UTC (rev 9005)
@@ -15,9 +15,6 @@
#include <linux/irq.h>
#include <linux/slab.h>
#include <linux/workqueue.h>
-#include <linux/spi/spi.h>
-#include <linux/i2c.h>
-
#include <linux/input/adxl34x.h>
#include "adxl34x.h"
@@ -181,8 +178,8 @@
#define ADXL_Y_AXIS 1
#define ADXL_Z_AXIS 2
-#define AC_READ(ac, reg) ((ac)->read((ac)->dev, reg))
-#define AC_WRITE(ac, reg, val) ((ac)->write((ac)->dev, reg, val))
+#define AC_READ(ac, reg) ((ac)->bops->read((ac)->dev, reg))
+#define AC_WRITE(ac, reg, val) ((ac)->bops->write((ac)->dev, reg, val))
struct axis_triple {
int x;
@@ -192,9 +189,7 @@
struct adxl34x {
struct device *dev;
- int irq;
struct input_dev *input;
- struct work_struct work;
struct mutex mutex; /* reentrant protection for struct */
struct adxl34x_platform_data pdata;
struct axis_triple swcal;
@@ -203,15 +198,14 @@
char phys[32];
unsigned orient2d_saved;
unsigned orient3d_saved;
- unsigned disabled:1; /* P: mutex */
- unsigned opened:1; /* P: mutex */
- unsigned fifo_delay:1;
+ bool disabled; /* P: mutex */
+ bool opened; /* P: mutex */
+ bool fifo_delay;
+ int irq;
unsigned model;
unsigned int_mask;
- adxl34x_read_t *read;
- adxl34x_read_block_t *read_block;
- adxl34x_write_t *write;
+ const struct adxl34x_bus_ops *bops;
};
static const struct adxl34x_platform_data adxl34x_default_init = {
@@ -244,8 +238,7 @@
{
short buf[3];
- ac->read_block(ac->dev, DATAX0, DATAZ1 - DATAX0 + 1,
- (unsigned char *)buf);
+ ac->bops->read_block(ac->dev, DATAX0, DATAZ1 - DATAX0 + 1, buf);
mutex_lock(&ac->mutex);
ac->saved.x = (s16) le16_to_cpu(buf[0]);
@@ -301,9 +294,9 @@
adxl34x_send_key_events(ac, pdata, status, false);
}
-static void adxl34x_work(struct work_struct *work)
+static irqreturn_t adxl34x_irq(int irq, void *handle)
{
- struct adxl34x *ac = container_of(work, struct adxl34x, work);
+ struct adxl34x *ac = handle;
struct adxl34x_platform_data *pdata = &ac->pdata;
int int_stat, tap_stat, samples, orient, orient_code;
@@ -347,7 +340,7 @@
if (pdata->orientation_enable) {
orient = AC_READ(ac, ORIENT);
if ((pdata->orientation_enable & ADXL_EN_ORIENTATION_2D) &&
- (orient & ADXL346_2D_VALID)) {
+ (orient & ADXL346_2D_VALID)) {
orient_code = ADXL346_2D_ORIENT(orient);
/* Report orientation only when it changes */
@@ -359,7 +352,7 @@
}
if ((pdata->orientation_enable & ADXL_EN_ORIENTATION_3D) &&
- (orient & ADXL346_3D_VALID)) {
+ (orient & ADXL346_3D_VALID)) {
orient_code = ADXL346_3D_ORIENT(orient) - 1;
/* Report orientation only when it changes */
@@ -400,33 +393,35 @@
}
input_sync(ac->input);
- enable_irq(ac->irq);
-}
-static irqreturn_t adxl34x_irq(int irq, void *handle)
-{
- struct adxl34x *ac = handle;
-
- disable_irq_nosync(irq);
- schedule_work(&ac->work);
-
return IRQ_HANDLED;
}
-void adxl34x_disable(struct adxl34x *ac)
+static void __adxl34x_disable(struct adxl34x *ac)
{
- mutex_lock(&ac->mutex);
if (!ac->disabled && ac->opened) {
- ac->disabled = 1;
- /* Balance interrupts disables/enables */
- if (cancel_work_sync(&ac->work))
- enable_irq(ac->irq);
/*
* A '0' places the ADXL34x into standby mode
* with minimum power consumption.
*/
AC_WRITE(ac, POWER_CTL, 0);
+
+ ac->disabled = true;
}
+}
+
+static void __adxl34x_enable(struct adxl34x *ac)
+{
+ if (ac->disabled && ac->opened) {
+ AC_WRITE(ac, POWER_CTL, ac->pdata.power_mode | PCTL_MEASURE);
+ ac->disabled = false;
+ }
+}
+
+void adxl34x_disable(struct adxl34x *ac)
+{
+ mutex_lock(&ac->mutex);
+ __adxl34x_disable(ac);
mutex_unlock(&ac->mutex);
}
EXPORT_SYMBOL_GPL(adxl34x_disable);
@@ -434,12 +429,10 @@
void adxl34x_enable(struct adxl34x *ac)
{
mutex_lock(&ac->mutex);
- if (ac->disabled && ac->opened) {
- AC_WRITE(ac, POWER_CTL, ac->pdata.power_mode | PCTL_MEASURE);
- ac->disabled = 0;
- }
+ __adxl34x_enable(ac);
mutex_unlock(&ac->mutex);
}
+
EXPORT_SYMBOL_GPL(adxl34x_enable);
static ssize_t adxl34x_disable_show(struct device *dev,
@@ -479,7 +472,8 @@
ssize_t count;
mutex_lock(&ac->mutex);
- count = sprintf(buf, "%d,%d,%d\n", ac->hwcal.x * 4 + ac->swcal.x,
+ count = sprintf(buf, "%d,%d,%d\n",
+ ac->hwcal.x * 4 + ac->swcal.x,
ac->hwcal.y * 4 + ac->swcal.y,
ac->hwcal.z * 4 + ac->swcal.z);
mutex_unlock(&ac->mutex);
@@ -516,20 +510,15 @@
return count;
}
-static DEVICE_ATTR(calibrate, 0664, adxl34x_calibrate_show,
- adxl34x_calibrate_store);
+static DEVICE_ATTR(calibrate, 0664,
+ adxl34x_calibrate_show, adxl34x_calibrate_store);
static ssize_t adxl34x_rate_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct adxl34x *ac = dev_get_drvdata(dev);
- ssize_t count;
- mutex_lock(&ac->mutex);
- count = sprintf(buf, "%u\n", RATE(ac->pdata.data_rate));
- mutex_unlock(&ac->mutex);
-
- return count;
+ return sprintf(buf, "%u\n", RATE(ac->pdata.data_rate));
}
static ssize_t adxl34x_rate_store(struct device *dev,
@@ -540,15 +529,17 @@
unsigned long val;
int error;
- mutex_lock(&ac->mutex);
error = strict_strtoul(buf, 10, &val);
if (error)
return error;
+ mutex_lock(&ac->mutex);
+
ac->pdata.data_rate = RATE(val);
+ AC_WRITE(ac, BW_RATE,
+ ac->pdata.data_rate |
+ (ac->pdata.low_power_mode ? LOW_POWER : 0));
- AC_WRITE(ac, BW_RATE, ac->pdata.data_rate |
- (ac->pdata.low_power_mode ? LOW_POWER : 0));
mutex_unlock(&ac->mutex);
return count;
@@ -560,14 +551,9 @@
struct device_attribute *attr, char *buf)
{
struct adxl34x *ac = dev_get_drvdata(dev);
- ssize_t count;
- mutex_lock(&ac->mutex);
- count = sprintf(buf, "%u\n", ac->pdata.power_mode &
- (PCTL_AUTO_SLEEP | PCTL_LINK) ? 1 : 0);
- mutex_unlock(&ac->mutex);
-
- return count;
+ return sprintf(buf, "%u\n",
+ ac->pdata.power_mode & (PCTL_AUTO_SLEEP | PCTL_LINK) ? 1 : 0);
}
static ssize_t adxl34x_autosleep_store(struct device *dev,
@@ -578,11 +564,12 @@
unsigned long val;
int error;
- mutex_lock(&ac->mutex);
error = strict_strtoul(buf, 10, &val);
if (error)
return error;
+ mutex_lock(&ac->mutex);
+
if (val)
ac->pdata.power_mode |= (PCTL_AUTO_SLEEP | PCTL_LINK);
else
@@ -596,8 +583,8 @@
return count;
}
-static DEVICE_ATTR(autosleep, 0664, adxl34x_autosleep_show,
- adxl34x_autosleep_store);
+static DEVICE_ATTR(autosleep, 0664,
+ adxl34x_autosleep_show, adxl34x_autosleep_store);
static ssize_t adxl34x_position_show(struct device *dev,
struct device_attribute *attr, char *buf)
@@ -606,16 +593,14 @@
ssize_t count;
mutex_lock(&ac->mutex);
-
count = sprintf(buf, "(%d, %d, %d)\n",
ac->saved.x, ac->saved.y, ac->saved.z);
-
mutex_unlock(&ac->mutex);
return count;
}
-static DEVICE_ATTR(position, 0444, adxl34x_position_show, NULL);
+static DEVICE_ATTR(position, S_IRUGO, adxl34x_position_show, NULL);
#ifdef ADXL_DEBUG
static ssize_t adxl34x_write_store(struct device *dev,
@@ -629,11 +614,11 @@
/*
* This allows basic ADXL register write access for debug purposes.
*/
- mutex_lock(&ac->mutex);
error = strict_strtoul(buf, 16, &val);
if (error)
return error;
+ mutex_lock(&ac->mutex);
AC_WRITE(ac, val >> 8, val & 0xFF);
mutex_unlock(&ac->mutex);
@@ -664,11 +649,10 @@
struct adxl34x *ac = input_get_drvdata(input);
mutex_lock(&ac->mutex);
- ac->opened = 1;
+ ac->opened = true;
+ __adxl34x_enable(ac);
mutex_unlock(&ac->mutex);
- adxl34x_enable(ac);
-
return 0;
}
@@ -676,58 +660,57 @@
{
struct adxl34x *ac = input_get_drvdata(input);
- adxl34x_disable(ac);
-
mutex_lock(&ac->mutex);
- ac->opened = 0;
+ __adxl34x_disable(ac);
+ ac->opened = false;
mutex_unlock(&ac->mutex);
}
-int adxl34x_probe(struct adxl34x **pac, struct device *dev, int irq,
- int fifo_delay_default, const struct adxl34x_bus_ops *bops)
+struct adxl34x *adxl34x_probe(struct device *dev, int irq,
+ bool fifo_delay_default,
+ const struct adxl34x_bus_ops *bops)
{
struct adxl34x *ac;
struct input_dev *input_dev;
- struct adxl34x_platform_data *pdata;
+ const struct adxl34x_platform_data *pdata;
int err, range, i;
unsigned char revid;
if (!irq) {
dev_err(dev, "no IRQ?\n");
- return -ENODEV;
+ err = -ENODEV;
+ goto err_out;
}
- *pac = ac = kzalloc(sizeof(*ac), GFP_KERNEL);
- if (!ac)
- return -ENOMEM;
+ ac = kzalloc(sizeof(*ac), GFP_KERNEL);
+ input_dev = input_allocate_device();
+ if (!ac || !input_dev) {
+ err = -ENOMEM;
+ goto err_out;
+ }
+
ac->fifo_delay = fifo_delay_default;
pdata = dev->platform_data;
if (!pdata) {
dev_dbg(dev,
"No platfrom data: Using default initialization\n");
- pdata = (struct adxl34x_platform_data *)&adxl34x_default_init;
+ pdata = &adxl34x_default_init;
}
- memcpy(&ac->pdata, pdata, sizeof(*pdata));
+
+ ac->pdata = *pdata;
pdata = &ac->pdata;
- input_dev = input_allocate_device();
- if (!input_dev)
- return -ENOMEM;
-
ac->input = input_dev;
- ac->disabled = 1;
+ ac->disabled = true;
ac->dev = dev;
ac->irq = irq;
- ac->write = bops->write;
- ac->read = bops->read;
- ac->read_block = bops->read_block;
+ ac->bops = bops;
- INIT_WORK(&ac->work, adxl34x_work);
mutex_init(&ac->mutex);
input_dev->name = "ADXL34x accelerometer";
- revid = ac->read(dev, DEVID);
+ revid = ac->bops->read(dev, DEVID);
switch (revid) {
case ID_ADXL345:
@@ -793,7 +776,7 @@
if (pdata->watermark) {
ac->int_mask |= WATERMARK;
if (!FIFO_MODE(pdata->fifo_mode))
- pdata->fifo_mode |= FIFO_STREAM;
+ ac->pdata.fifo_mode |= FIFO_STREAM;
} else {
ac->int_mask |= DATA_READY;
}
@@ -802,12 +785,13 @@
ac->int_mask |= SINGLE_TAP | DOUBLE_TAP;
if (FIFO_MODE(pdata->fifo_mode) == FIFO_BYPASS)
- ac->fifo_delay = 0;
+ ac->fifo_delay = false;
- ac->write(dev, POWER_CTL, 0);
+ ac->bops->write(dev, POWER_CTL, 0);
- err = request_irq(ac->irq, adxl34x_irq,
- IRQF_TRIGGER_HIGH, dev_name(dev), ac);
+ err = request_threaded_irq(ac->irq, NULL, adxl34x_irq,
+ IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
+ dev_name(dev), ac);
if (err) {
dev_err(dev, "irq %d busy?\n", ac->irq);
goto err_free_mem;
@@ -845,14 +829,15 @@
AC_WRITE(ac, FIFO_CTL, FIFO_MODE(pdata->fifo_mode) |
SAMPLES(pdata->watermark));
- if (pdata->use_int2)
+ if (pdata->use_int2) {
/* Map all INTs to INT2 */
AC_WRITE(ac, INT_MAP, ac->int_mask | OVERRUN);
- else
+ } else {
/* Map all INTs to INT1 */
AC_WRITE(ac, INT_MAP, 0);
+ }
- if ((ac->model == 346) && ac->pdata.orientation_enable) {
+ if (ac->model == 346 && ac->pdata.orientation_enable) {
AC_WRITE(ac, ORIENT_CONF,
ORIENT_DEADZONE(ac->pdata.deadzone_angle) |
ORIENT_DIVISOR(ac->pdata.divisor_length));
@@ -860,37 +845,34 @@
ac->orient2d_saved = 1234;
ac->orient3d_saved = 1234;
- if (pdata->orientation_enable & ADXL_EN_ORIENTATION_3D)
- for (i = 0; i < ARRAY_SIZE(pdata->ev_codes_orient_3d); i++)
- __set_bit(pdata->ev_codes_orient_3d[i],
- input_dev->keybit);
+ if (pdata->orientation_enable & ADXL_EN_ORIENTATION_3D)
+ for (i = 0; i < ARRAY_SIZE(pdata->ev_codes_orient_3d); i++)
+ __set_bit(pdata->ev_codes_orient_3d[i],
+ input_dev->keybit);
- if (pdata->orientation_enable & ADXL_EN_ORIENTATION_2D)
- for (i = 0; i < ARRAY_SIZE(pdata->ev_codes_orient_2d); i++)
- __set_bit(pdata->ev_codes_orient_2d[i],
- input_dev->keybit);
-
+ if (pdata->orientation_enable & ADXL_EN_ORIENTATION_2D)
+ for (i = 0; i < ARRAY_SIZE(pdata->ev_codes_orient_2d); i++)
+ __set_bit(pdata->ev_codes_orient_2d[i],
+ input_dev->keybit);
} else {
ac->pdata.orientation_enable = 0;
}
AC_WRITE(ac, INT_ENABLE, ac->int_mask | OVERRUN);
- pdata->power_mode &= (PCTL_AUTO_SLEEP | PCTL_LINK);
+ ac->pdata.power_mode &= (PCTL_AUTO_SLEEP | PCTL_LINK);
- dev_info(dev, "ADXL%d accelerometer, irq %d\n",
- ac->model, ac->irq);
+ return ac;
- return 0;
-
err_remove_attr:
sysfs_remove_group(&dev->kobj, &adxl34x_attr_group);
err_free_irq:
free_irq(ac->irq, ac);
err_free_mem:
input_free_device(input_dev);
-
- return err;
+ kfree(ac);
+ err_out:
+ return ERR_PTR(err);
}
EXPORT_SYMBOL_GPL(adxl34x_probe);
@@ -900,9 +882,9 @@
sysfs_remove_group(&ac->dev->kobj, &adxl34x_attr_group);
free_irq(ac->irq, ac);
input_unregister_device(ac->input);
- dev_dbg(ac->dev, "unregistered accelerometer\n");
kfree(ac);
+ dev_dbg(ac->dev, "unregistered accelerometer\n");
return 0;
}
EXPORT_SYMBOL_GPL(adxl34x_remove);