|
@@ -27,70 +27,10 @@
|
|
#include <linux/i2c.h>
|
|
#include <linux/i2c.h>
|
|
#include <linux/i2c/tsc2007.h>
|
|
#include <linux/i2c/tsc2007.h>
|
|
#include <linux/of_device.h>
|
|
#include <linux/of_device.h>
|
|
-#include <linux/of.h>
|
|
|
|
#include <linux/of_gpio.h>
|
|
#include <linux/of_gpio.h>
|
|
|
|
+#include "tsc2007.h"
|
|
|
|
|
|
-#define TSC2007_MEASURE_TEMP0 (0x0 << 4)
|
|
|
|
-#define TSC2007_MEASURE_AUX (0x2 << 4)
|
|
|
|
-#define TSC2007_MEASURE_TEMP1 (0x4 << 4)
|
|
|
|
-#define TSC2007_ACTIVATE_XN (0x8 << 4)
|
|
|
|
-#define TSC2007_ACTIVATE_YN (0x9 << 4)
|
|
|
|
-#define TSC2007_ACTIVATE_YP_XN (0xa << 4)
|
|
|
|
-#define TSC2007_SETUP (0xb << 4)
|
|
|
|
-#define TSC2007_MEASURE_X (0xc << 4)
|
|
|
|
-#define TSC2007_MEASURE_Y (0xd << 4)
|
|
|
|
-#define TSC2007_MEASURE_Z1 (0xe << 4)
|
|
|
|
-#define TSC2007_MEASURE_Z2 (0xf << 4)
|
|
|
|
-
|
|
|
|
-#define TSC2007_POWER_OFF_IRQ_EN (0x0 << 2)
|
|
|
|
-#define TSC2007_ADC_ON_IRQ_DIS0 (0x1 << 2)
|
|
|
|
-#define TSC2007_ADC_OFF_IRQ_EN (0x2 << 2)
|
|
|
|
-#define TSC2007_ADC_ON_IRQ_DIS1 (0x3 << 2)
|
|
|
|
-
|
|
|
|
-#define TSC2007_12BIT (0x0 << 1)
|
|
|
|
-#define TSC2007_8BIT (0x1 << 1)
|
|
|
|
-
|
|
|
|
-#define MAX_12BIT ((1 << 12) - 1)
|
|
|
|
-
|
|
|
|
-#define ADC_ON_12BIT (TSC2007_12BIT | TSC2007_ADC_ON_IRQ_DIS0)
|
|
|
|
-
|
|
|
|
-#define READ_Y (ADC_ON_12BIT | TSC2007_MEASURE_Y)
|
|
|
|
-#define READ_Z1 (ADC_ON_12BIT | TSC2007_MEASURE_Z1)
|
|
|
|
-#define READ_Z2 (ADC_ON_12BIT | TSC2007_MEASURE_Z2)
|
|
|
|
-#define READ_X (ADC_ON_12BIT | TSC2007_MEASURE_X)
|
|
|
|
-#define PWRDOWN (TSC2007_12BIT | TSC2007_POWER_OFF_IRQ_EN)
|
|
|
|
-
|
|
|
|
-struct ts_event {
|
|
|
|
- u16 x;
|
|
|
|
- u16 y;
|
|
|
|
- u16 z1, z2;
|
|
|
|
-};
|
|
|
|
-
|
|
|
|
-struct tsc2007 {
|
|
|
|
- struct input_dev *input;
|
|
|
|
- char phys[32];
|
|
|
|
-
|
|
|
|
- struct i2c_client *client;
|
|
|
|
-
|
|
|
|
- u16 model;
|
|
|
|
- u16 x_plate_ohms;
|
|
|
|
- u16 max_rt;
|
|
|
|
- unsigned long poll_period; /* in jiffies */
|
|
|
|
- int fuzzx;
|
|
|
|
- int fuzzy;
|
|
|
|
- int fuzzz;
|
|
|
|
-
|
|
|
|
- unsigned gpio;
|
|
|
|
- int irq;
|
|
|
|
-
|
|
|
|
- wait_queue_head_t wait;
|
|
|
|
- bool stopped;
|
|
|
|
-
|
|
|
|
- int (*get_pendown_state)(struct device *);
|
|
|
|
- void (*clear_penirq)(void);
|
|
|
|
-};
|
|
|
|
-
|
|
|
|
-static inline int tsc2007_xfer(struct tsc2007 *tsc, u8 cmd)
|
|
|
|
|
|
+int tsc2007_xfer(struct tsc2007 *tsc, u8 cmd)
|
|
{
|
|
{
|
|
s32 data;
|
|
s32 data;
|
|
u16 val;
|
|
u16 val;
|
|
@@ -128,7 +68,7 @@ static void tsc2007_read_values(struct tsc2007 *tsc, struct ts_event *tc)
|
|
tsc2007_xfer(tsc, PWRDOWN);
|
|
tsc2007_xfer(tsc, PWRDOWN);
|
|
}
|
|
}
|
|
|
|
|
|
-static u32 tsc2007_calculate_pressure(struct tsc2007 *tsc, struct ts_event *tc)
|
|
|
|
|
|
+u32 tsc2007_calculate_pressure(struct tsc2007 *tsc, struct ts_event *tc)
|
|
{
|
|
{
|
|
u32 rt = 0;
|
|
u32 rt = 0;
|
|
|
|
|
|
@@ -148,7 +88,7 @@ static u32 tsc2007_calculate_pressure(struct tsc2007 *tsc, struct ts_event *tc)
|
|
return rt;
|
|
return rt;
|
|
}
|
|
}
|
|
|
|
|
|
-static bool tsc2007_is_pen_down(struct tsc2007 *ts)
|
|
|
|
|
|
+bool tsc2007_is_pen_down(struct tsc2007 *ts)
|
|
{
|
|
{
|
|
/*
|
|
/*
|
|
* NOTE: We can't rely on the pressure to determine the pen down
|
|
* NOTE: We can't rely on the pressure to determine the pen down
|
|
@@ -180,7 +120,10 @@ static irqreturn_t tsc2007_soft_irq(int irq, void *handle)
|
|
while (!ts->stopped && tsc2007_is_pen_down(ts)) {
|
|
while (!ts->stopped && tsc2007_is_pen_down(ts)) {
|
|
|
|
|
|
/* pen is down, continue with the measurement */
|
|
/* pen is down, continue with the measurement */
|
|
|
|
+
|
|
|
|
+ mutex_lock(&ts->mlock);
|
|
tsc2007_read_values(ts, &tc);
|
|
tsc2007_read_values(ts, &tc);
|
|
|
|
+ mutex_unlock(&ts->mlock);
|
|
|
|
|
|
rt = tsc2007_calculate_pressure(ts, &tc);
|
|
rt = tsc2007_calculate_pressure(ts, &tc);
|
|
|
|
|
|
@@ -375,7 +318,8 @@ static void tsc2007_call_exit_platform_hw(void *data)
|
|
static int tsc2007_probe(struct i2c_client *client,
|
|
static int tsc2007_probe(struct i2c_client *client,
|
|
const struct i2c_device_id *id)
|
|
const struct i2c_device_id *id)
|
|
{
|
|
{
|
|
- const struct tsc2007_platform_data *pdata = dev_get_platdata(&client->dev);
|
|
|
|
|
|
+ const struct tsc2007_platform_data *pdata =
|
|
|
|
+ dev_get_platdata(&client->dev);
|
|
struct tsc2007 *ts;
|
|
struct tsc2007 *ts;
|
|
struct input_dev *input_dev;
|
|
struct input_dev *input_dev;
|
|
int err;
|
|
int err;
|
|
@@ -404,7 +348,9 @@ static int tsc2007_probe(struct i2c_client *client,
|
|
ts->client = client;
|
|
ts->client = client;
|
|
ts->irq = client->irq;
|
|
ts->irq = client->irq;
|
|
ts->input = input_dev;
|
|
ts->input = input_dev;
|
|
|
|
+
|
|
init_waitqueue_head(&ts->wait);
|
|
init_waitqueue_head(&ts->wait);
|
|
|
|
+ mutex_init(&ts->mlock);
|
|
|
|
|
|
snprintf(ts->phys, sizeof(ts->phys),
|
|
snprintf(ts->phys, sizeof(ts->phys),
|
|
"%s/input0", dev_name(&client->dev));
|
|
"%s/input0", dev_name(&client->dev));
|
|
@@ -460,7 +406,7 @@ static int tsc2007_probe(struct i2c_client *client,
|
|
if (err < 0) {
|
|
if (err < 0) {
|
|
dev_err(&client->dev,
|
|
dev_err(&client->dev,
|
|
"Failed to setup chip: %d\n", err);
|
|
"Failed to setup chip: %d\n", err);
|
|
- return err; /* usually, chip does not respond */
|
|
|
|
|
|
+ return err; /* chip does not respond */
|
|
}
|
|
}
|
|
|
|
|
|
err = input_register_device(input_dev);
|
|
err = input_register_device(input_dev);
|
|
@@ -470,6 +416,13 @@ static int tsc2007_probe(struct i2c_client *client,
|
|
return err;
|
|
return err;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ err = tsc2007_iio_configure(ts);
|
|
|
|
+ if (err) {
|
|
|
|
+ dev_err(&client->dev,
|
|
|
|
+ "Failed to register with IIO: %d\n", err);
|
|
|
|
+ return err;
|
|
|
|
+ }
|
|
|
|
+
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|