tsc2007.c 11.8 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
/*
 * drivers/input/touchscreen/tsc2007.c
 *
 * Copyright (c) 2008 MtekVision Co., Ltd.
 *	Kwangwoo Lee <kwlee@mtekvision.com>
 *
 * Using code from:
 *  - ads7846.c
 *	Copyright (c) 2005 David Brownell
 *	Copyright (c) 2006 Nokia Corporation
 *  - corgi_ts.c
 *	Copyright (C) 2004-2005 Richard Purdie
 *  - omap_ts.[hc], ads7846.h, ts_osk.c
 *	Copyright (C) 2002 MontaVista Software
 *	Copyright (C) 2004 Texas Instruments
 *	Copyright (C) 2005 Dirk Behme
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License version 2 as
 *  published by the Free Software Foundation.
 */

#include <linux/module.h>
#include <linux/slab.h>
#include <linux/input.h>
#include <linux/interrupt.h>
#include <linux/i2c.h>
#include <linux/i2c/tsc2007.h>
29 30 31
#include <linux/of_device.h>
#include <linux/of.h>
#include <linux/of_gpio.h>
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76

#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;
77
	u16			max_rt;
78
	unsigned long		poll_delay;
79
	unsigned long		poll_period;
80 81 82
	int			fuzzx;
	int			fuzzy;
	int			fuzzz;
83

84
	unsigned		gpio;
85 86
	int			irq;

87 88 89
	wait_queue_head_t	wait;
	bool			stopped;

90
	int			(*get_pendown_state)(struct device *);
91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115
	void			(*clear_penirq)(void);
};

static inline int tsc2007_xfer(struct tsc2007 *tsc, u8 cmd)
{
	s32 data;
	u16 val;

	data = i2c_smbus_read_word_data(tsc->client, cmd);
	if (data < 0) {
		dev_err(&tsc->client->dev, "i2c io error: %d\n", data);
		return data;
	}

	/* The protocol and raw data format from i2c interface:
	 * S Addr Wr [A] Comm [A] S Addr Rd [A] [DataLow] A [DataHigh] NA P
	 * Where DataLow has [D11-D4], DataHigh has [D3-D0 << 4 | Dummy 4bit].
	 */
	val = swab16(data) >> 4;

	dev_dbg(&tsc->client->dev, "data: 0x%x, val: 0x%x\n", data, val);

	return val;
}

116
static void tsc2007_read_values(struct tsc2007 *tsc, struct ts_event *tc)
117
{
118 119 120 121 122 123 124 125 126 127 128 129 130
	/* y- still on; turn on only y+ (and ADC) */
	tc->y = tsc2007_xfer(tsc, READ_Y);

	/* turn y- off, x+ on, then leave in lowpower */
	tc->x = tsc2007_xfer(tsc, READ_X);

	/* turn y+ off, x- on; we'll use formula #1 */
	tc->z1 = tsc2007_xfer(tsc, READ_Z1);
	tc->z2 = tsc2007_xfer(tsc, READ_Z2);

	/* Prepare for next touch reading - power down ADC, enable PENIRQ */
	tsc2007_xfer(tsc, PWRDOWN);
}
131

132 133 134
static u32 tsc2007_calculate_pressure(struct tsc2007 *tsc, struct ts_event *tc)
{
	u32 rt = 0;
135 136

	/* range filtering */
137 138
	if (tc->x == MAX_12BIT)
		tc->x = 0;
139

140
	if (likely(tc->x && tc->z1)) {
141
		/* compute touch pressure resistance using equation #1 */
142 143 144 145
		rt = tc->z2 - tc->z1;
		rt *= tc->x;
		rt *= tsc->x_plate_ohms;
		rt /= tc->z1;
146 147 148
		rt = (rt + 2047) >> 12;
	}

149 150 151
	return rt;
}

152
static bool tsc2007_is_pen_down(struct tsc2007 *ts)
153
{
154 155
	/*
	 * NOTE: We can't rely on the pressure to determine the pen down
156 157 158 159
	 * state, even though this controller has a pressure sensor.
	 * The pressure value can fluctuate for quite a while after
	 * lifting the pen and in some cases may not even settle at the
	 * expected value.
160 161
	 *
	 * The only safe way to check for the pen up condition is in the
162 163
	 * work function by reading the pen signal state (it's a GPIO
	 * and IRQ). Unfortunately such callback is not always available,
164 165
	 * in that case we assume that the pen is down and expect caller
	 * to fall back on the pressure reading.
166
	 */
167

168 169
	if (!ts->get_pendown_state)
		return true;
170

171
	return ts->get_pendown_state(&ts->client->dev);
172
}
173

174 175 176 177 178 179
static irqreturn_t tsc2007_soft_irq(int irq, void *handle)
{
	struct tsc2007 *ts = handle;
	struct input_dev *input = ts->input;
	struct ts_event tc;
	u32 rt;
180

181 182 183 184
	while (!ts->stopped && tsc2007_is_pen_down(ts)) {

		/* pen is down, continue with the measurement */
		tsc2007_read_values(ts, &tc);
185

186
		rt = tsc2007_calculate_pressure(ts, &tc);
187

188
		if (!rt && !ts->get_pendown_state) {
189 190 191 192 193 194 195 196 197 198 199 200
			/*
			 * If pressure reported is 0 and we don't have
			 * callback to check pendown state, we have to
			 * assume that pen was lifted up.
			 */
			break;
		}

		if (rt <= ts->max_rt) {
			dev_dbg(&ts->client->dev,
				"DOWN point(%4d,%4d), pressure (%4u)\n",
				tc.x, tc.y, rt);
201 202

			input_report_key(input, BTN_TOUCH, 1);
203 204 205 206 207 208 209 210 211 212 213 214 215
			input_report_abs(input, ABS_X, tc.x);
			input_report_abs(input, ABS_Y, tc.y);
			input_report_abs(input, ABS_PRESSURE, rt);

			input_sync(input);

		} else {
			/*
			 * Sample found inconsistent by debouncing or pressure is
			 * beyond the maximum. Don't report it to user space,
			 * repeat at least once more the measurement.
			 */
			dev_dbg(&ts->client->dev, "ignored pressure %d\n", rt);
216 217
		}

218 219 220
		wait_event_timeout(ts->wait, ts->stopped,
				   msecs_to_jiffies(ts->poll_period));
	}
221

222
	dev_dbg(&ts->client->dev, "UP\n");
223

224 225 226
	input_report_key(input, BTN_TOUCH, 0);
	input_report_abs(input, ABS_PRESSURE, 0);
	input_sync(input);
227

228 229
	if (ts->clear_penirq)
		ts->clear_penirq();
230

231
	return IRQ_HANDLED;
232 233
}

234
static irqreturn_t tsc2007_hard_irq(int irq, void *handle)
235 236 237
{
	struct tsc2007 *ts = handle;

238
	if (tsc2007_is_pen_down(ts))
239
		return IRQ_WAKE_THREAD;
240 241 242 243 244 245 246

	if (ts->clear_penirq)
		ts->clear_penirq();

	return IRQ_HANDLED;
}

247
static void tsc2007_stop(struct tsc2007 *ts)
248
{
249 250 251
	ts->stopped = true;
	mb();
	wake_up(&ts->wait);
252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280

	disable_irq(ts->irq);
}

static int tsc2007_open(struct input_dev *input_dev)
{
	struct tsc2007 *ts = input_get_drvdata(input_dev);
	int err;

	ts->stopped = false;
	mb();

	enable_irq(ts->irq);

	/* Prepare for touch readings - power down ADC and enable PENIRQ */
	err = tsc2007_xfer(ts, PWRDOWN);
	if (err < 0) {
		tsc2007_stop(ts);
		return err;
	}

	return 0;
}

static void tsc2007_close(struct input_dev *input_dev)
{
	struct tsc2007 *ts = input_get_drvdata(input_dev);

	tsc2007_stop(ts);
281 282
}

283 284
#ifdef CONFIG_OF
static int tsc2007_get_pendown_state_gpio(struct device *dev)
285
{
286 287 288 289 290 291 292 293 294 295 296
	struct i2c_client *client = to_i2c_client(dev);
	struct tsc2007 *ts = i2c_get_clientdata(client);

	return !gpio_get_value(ts->gpio);
}

static int tsc2007_probe_dt(struct i2c_client *client, struct tsc2007 *ts)
{
	struct device_node *np = client->dev.of_node;
	u32 val32;
	u64 val64;
297

298 299
	if (!np) {
		dev_err(&client->dev, "missing device tree data\n");
300 301 302
		return -EINVAL;
	}

303 304 305 306
	if (!of_property_read_u32(np, "ti,max-rt", &val32))
		ts->max_rt = val32;
	else
		ts->max_rt = MAX_12BIT;
307

308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326
	if (!of_property_read_u32(np, "ti,fuzzx", &val32))
		ts->fuzzx = val32;

	if (!of_property_read_u32(np, "ti,fuzzy", &val32))
		ts->fuzzy = val32;

	if (!of_property_read_u32(np, "ti,fuzzz", &val32))
		ts->fuzzz = val32;

	if (!of_property_read_u64(np, "ti,poll-period", &val64))
		ts->poll_period = val64;
	else
		ts->poll_period = 1;

	if (!of_property_read_u32(np, "ti,x-plate-ohms", &val32)) {
		ts->x_plate_ohms = val32;
	} else {
		dev_err(&client->dev, "missing ti,x-plate-ohms devicetree property.");
		return -EINVAL;
327 328
	}

329 330 331 332 333 334 335
	ts->gpio = of_get_gpio(np, 0);
	if (gpio_is_valid(ts->gpio))
		ts->get_pendown_state = tsc2007_get_pendown_state_gpio;
	else
		dev_warn(&client->dev,
			 "GPIO not specified in DT (of_get_gpio returned %d)\n",
			 ts->gpio);
336

337 338 339 340 341 342 343 344 345 346 347 348 349 350
	return 0;
}
#else
static int tsc2007_probe_dt(struct i2c_client *client, struct tsc2007 *ts)
{
	dev_err(&client->dev, "platform data is required!\n");
	return -EINVAL;
}
#endif

static int tsc2007_probe_pdev(struct i2c_client *client, struct tsc2007 *ts,
			      const struct tsc2007_platform_data *pdata,
			      const struct i2c_device_id *id)
{
351 352
	ts->model             = pdata->model;
	ts->x_plate_ohms      = pdata->x_plate_ohms;
353
	ts->max_rt            = pdata->max_rt ? : MAX_12BIT;
354
	ts->poll_delay        = pdata->poll_delay ? : 1;
355
	ts->poll_period       = pdata->poll_period ? : 1;
356 357
	ts->get_pendown_state = pdata->get_pendown_state;
	ts->clear_penirq      = pdata->clear_penirq;
358 359 360
	ts->fuzzx             = pdata->fuzzx;
	ts->fuzzy             = pdata->fuzzy;
	ts->fuzzz             = pdata->fuzzz;
361

362 363
	if (pdata->x_plate_ohms == 0) {
		dev_err(&client->dev, "x_plate_ohms is not set up in platform data");
364
		return -EINVAL;
365 366
	}

367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405
	return 0;
}

static int tsc2007_probe(struct i2c_client *client,
			 const struct i2c_device_id *id)
{
	const struct tsc2007_platform_data *pdata = dev_get_platdata(&client->dev);
	struct tsc2007 *ts;
	struct input_dev *input_dev;
	int err;

	if (!i2c_check_functionality(client->adapter,
				     I2C_FUNC_SMBUS_READ_WORD_DATA))
		return -EIO;

	ts = devm_kzalloc(&client->dev, sizeof(struct tsc2007), GFP_KERNEL);
	if (!ts)
		return -ENOMEM;

	if (pdata)
		err = tsc2007_probe_pdev(client, ts, pdata, id);
	else
		err = tsc2007_probe_dt(client, ts);
	if (err)
		return err;

	input_dev = input_allocate_device();
	if (!input_dev) {
		err = -ENOMEM;
		goto err_free_input;
	};

	i2c_set_clientdata(client, ts);

	ts->client = client;
	ts->irq = client->irq;
	ts->input = input_dev;
	init_waitqueue_head(&ts->wait);

406 407
	snprintf(ts->phys, sizeof(ts->phys),
		 "%s/input0", dev_name(&client->dev));
408 409 410 411 412

	input_dev->name = "TSC2007 Touchscreen";
	input_dev->phys = ts->phys;
	input_dev->id.bustype = BUS_I2C;

413 414 415 416 417
	input_dev->open = tsc2007_open;
	input_dev->close = tsc2007_close;

	input_set_drvdata(input_dev, ts);

418 419 420
	input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
	input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);

421 422
	input_set_abs_params(input_dev, ABS_X, 0, MAX_12BIT, ts->fuzzx, 0);
	input_set_abs_params(input_dev, ABS_Y, 0, MAX_12BIT, ts->fuzzy, 0);
423
	input_set_abs_params(input_dev, ABS_PRESSURE, 0, MAX_12BIT,
424
			     ts->fuzzz, 0);
425

426
	if (pdata && pdata->init_platform_hw)
427
		pdata->init_platform_hw();
428

429 430
	err = request_threaded_irq(ts->irq, tsc2007_hard_irq, tsc2007_soft_irq,
				   IRQF_ONESHOT, client->dev.driver->name, ts);
431 432
	if (err < 0) {
		dev_err(&client->dev, "irq %d busy?\n", ts->irq);
433
		goto err_free_input;
434 435
	}

436
	tsc2007_stop(ts);
437

438 439 440 441 442 443 444
	err = input_register_device(input_dev);
	if (err)
		goto err_free_irq;

	return 0;

 err_free_irq:
445
	free_irq(ts->irq, ts);
446
	if (pdata && pdata->exit_platform_hw)
447
		pdata->exit_platform_hw();
448
 err_free_input:
449 450 451 452
	input_free_device(input_dev);
	return err;
}

B
Bill Pemberton 已提交
453
static int tsc2007_remove(struct i2c_client *client)
454
{
455 456
	const struct tsc2007_platform_data *pdata = dev_get_platdata(&client->dev);
	struct tsc2007 *ts = i2c_get_clientdata(client);
457

458
	free_irq(ts->irq, ts);
459

460
	if (pdata && pdata->exit_platform_hw)
461
		pdata->exit_platform_hw();
462 463 464 465 466 467 468

	input_unregister_device(ts->input);
	kfree(ts);

	return 0;
}

469
static const struct i2c_device_id tsc2007_idtable[] = {
470 471 472 473 474 475
	{ "tsc2007", 0 },
	{ }
};

MODULE_DEVICE_TABLE(i2c, tsc2007_idtable);

476 477 478 479 480 481 482 483
#ifdef CONFIG_OF
static const struct of_device_id tsc2007_of_match[] = {
	{ .compatible = "ti,tsc2007" },
	{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, tsc2007_of_match);
#endif

484 485 486
static struct i2c_driver tsc2007_driver = {
	.driver = {
		.owner	= THIS_MODULE,
487 488
		.name	= "tsc2007",
		.of_match_table = of_match_ptr(tsc2007_of_match),
489 490 491
	},
	.id_table	= tsc2007_idtable,
	.probe		= tsc2007_probe,
B
Bill Pemberton 已提交
492
	.remove		= tsc2007_remove,
493 494
};

495
module_i2c_driver(tsc2007_driver);
496 497 498 499

MODULE_AUTHOR("Kwangwoo Lee <kwlee@mtekvision.com>");
MODULE_DESCRIPTION("TSC2007 TouchScreen Driver");
MODULE_LICENSE("GPL");