Path: blob/master/drivers/input/touchscreen/tsc2005.c
15109 views
/*1* TSC2005 touchscreen driver2*3* Copyright (C) 2006-2010 Nokia Corporation4*5* Author: Lauri Leukkunen <[email protected]>6* based on TSC2301 driver by Klaus K. Pedersen <[email protected]>7*8* This program is free software; you can redistribute it and/or modify9* it under the terms of the GNU General Public License as published by10* the Free Software Foundation; either version 2 of the License, or11* (at your option) any later version.12*13* This program is distributed in the hope that it will be useful,14* but WITHOUT ANY WARRANTY; without even the implied warranty of15* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the16* GNU General Public License for more details.17*18* You should have received a copy of the GNU General Public License19* along with this program; if not, write to the Free Software20* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA21*22*/2324#include <linux/kernel.h>25#include <linux/module.h>26#include <linux/input.h>27#include <linux/interrupt.h>28#include <linux/delay.h>29#include <linux/pm.h>30#include <linux/spi/spi.h>31#include <linux/spi/tsc2005.h>3233/*34* The touchscreen interface operates as follows:35*36* 1) Pen is pressed against the touchscreen.37* 2) TSC2005 performs AD conversion.38* 3) After the conversion is done TSC2005 drives DAV line down.39* 4) GPIO IRQ is received and tsc2005_irq_thread() is scheduled.40* 5) tsc2005_irq_thread() queues up an spi transfer to fetch the x, y, z1, z241* values.42* 6) tsc2005_irq_thread() reports coordinates to input layer and sets up43* tsc2005_penup_timer() to be called after TSC2005_PENUP_TIME_MS (40ms).44* 7) When the penup timer expires, there have not been touch or DAV interrupts45* during the last 40ms which means the pen has been lifted.46*47* ESD recovery via a hardware reset is done if the TSC2005 doesn't respond48* after a configurable period (in ms) of activity. If esd_timeout is 0, the49* watchdog is disabled.50*/5152/* control byte 1 */53#define TSC2005_CMD 0x8054#define TSC2005_CMD_NORMAL 0x0055#define TSC2005_CMD_STOP 0x0156#define TSC2005_CMD_12BIT 0x045758/* control byte 0 */59#define TSC2005_REG_READ 0x000160#define TSC2005_REG_PND0 0x000261#define TSC2005_REG_X 0x000062#define TSC2005_REG_Y 0x000863#define TSC2005_REG_Z1 0x001064#define TSC2005_REG_Z2 0x001865#define TSC2005_REG_TEMP_HIGH 0x005066#define TSC2005_REG_CFR0 0x006067#define TSC2005_REG_CFR1 0x006868#define TSC2005_REG_CFR2 0x00706970/* configuration register 0 */71#define TSC2005_CFR0_PRECHARGE_276US 0x004072#define TSC2005_CFR0_STABTIME_1MS 0x030073#define TSC2005_CFR0_CLOCK_1MHZ 0x100074#define TSC2005_CFR0_RESOLUTION12 0x200075#define TSC2005_CFR0_PENMODE 0x800076#define TSC2005_CFR0_INITVALUE (TSC2005_CFR0_STABTIME_1MS | \77TSC2005_CFR0_CLOCK_1MHZ | \78TSC2005_CFR0_RESOLUTION12 | \79TSC2005_CFR0_PRECHARGE_276US | \80TSC2005_CFR0_PENMODE)8182/* bits common to both read and write of configuration register 0 */83#define TSC2005_CFR0_RW_MASK 0x3fff8485/* configuration register 1 */86#define TSC2005_CFR1_BATCHDELAY_4MS 0x000387#define TSC2005_CFR1_INITVALUE TSC2005_CFR1_BATCHDELAY_4MS8889/* configuration register 2 */90#define TSC2005_CFR2_MAVE_Z 0x000491#define TSC2005_CFR2_MAVE_Y 0x000892#define TSC2005_CFR2_MAVE_X 0x001093#define TSC2005_CFR2_AVG_7 0x080094#define TSC2005_CFR2_MEDIUM_15 0x300095#define TSC2005_CFR2_INITVALUE (TSC2005_CFR2_MAVE_X | \96TSC2005_CFR2_MAVE_Y | \97TSC2005_CFR2_MAVE_Z | \98TSC2005_CFR2_MEDIUM_15 | \99TSC2005_CFR2_AVG_7)100101#define MAX_12BIT 0xfff102#define TSC2005_SPI_MAX_SPEED_HZ 10000000103#define TSC2005_PENUP_TIME_MS 40104105struct tsc2005_spi_rd {106struct spi_transfer spi_xfer;107u32 spi_tx;108u32 spi_rx;109};110111struct tsc2005 {112struct spi_device *spi;113114struct spi_message spi_read_msg;115struct tsc2005_spi_rd spi_x;116struct tsc2005_spi_rd spi_y;117struct tsc2005_spi_rd spi_z1;118struct tsc2005_spi_rd spi_z2;119120struct input_dev *idev;121char phys[32];122123struct mutex mutex;124125/* raw copy of previous x,y,z */126int in_x;127int in_y;128int in_z1;129int in_z2;130131spinlock_t lock;132struct timer_list penup_timer;133134unsigned int esd_timeout;135struct delayed_work esd_work;136unsigned long last_valid_interrupt;137138unsigned int x_plate_ohm;139140bool opened;141bool suspended;142143bool pen_down;144145void (*set_reset)(bool enable);146};147148static int tsc2005_cmd(struct tsc2005 *ts, u8 cmd)149{150u8 tx = TSC2005_CMD | TSC2005_CMD_12BIT | cmd;151struct spi_transfer xfer = {152.tx_buf = &tx,153.len = 1,154.bits_per_word = 8,155};156struct spi_message msg;157int error;158159spi_message_init(&msg);160spi_message_add_tail(&xfer, &msg);161162error = spi_sync(ts->spi, &msg);163if (error) {164dev_err(&ts->spi->dev, "%s: failed, command: %x, error: %d\n",165__func__, cmd, error);166return error;167}168169return 0;170}171172static int tsc2005_write(struct tsc2005 *ts, u8 reg, u16 value)173{174u32 tx = ((reg | TSC2005_REG_PND0) << 16) | value;175struct spi_transfer xfer = {176.tx_buf = &tx,177.len = 4,178.bits_per_word = 24,179};180struct spi_message msg;181int error;182183spi_message_init(&msg);184spi_message_add_tail(&xfer, &msg);185186error = spi_sync(ts->spi, &msg);187if (error) {188dev_err(&ts->spi->dev,189"%s: failed, register: %x, value: %x, error: %d\n",190__func__, reg, value, error);191return error;192}193194return 0;195}196197static void tsc2005_setup_read(struct tsc2005_spi_rd *rd, u8 reg, bool last)198{199memset(rd, 0, sizeof(*rd));200201rd->spi_tx = (reg | TSC2005_REG_READ) << 16;202rd->spi_xfer.tx_buf = &rd->spi_tx;203rd->spi_xfer.rx_buf = &rd->spi_rx;204rd->spi_xfer.len = 4;205rd->spi_xfer.bits_per_word = 24;206rd->spi_xfer.cs_change = !last;207}208209static int tsc2005_read(struct tsc2005 *ts, u8 reg, u16 *value)210{211struct tsc2005_spi_rd spi_rd;212struct spi_message msg;213int error;214215tsc2005_setup_read(&spi_rd, reg, true);216217spi_message_init(&msg);218spi_message_add_tail(&spi_rd.spi_xfer, &msg);219220error = spi_sync(ts->spi, &msg);221if (error)222return error;223224*value = spi_rd.spi_rx;225return 0;226}227228static void tsc2005_update_pen_state(struct tsc2005 *ts,229int x, int y, int pressure)230{231if (pressure) {232input_report_abs(ts->idev, ABS_X, x);233input_report_abs(ts->idev, ABS_Y, y);234input_report_abs(ts->idev, ABS_PRESSURE, pressure);235if (!ts->pen_down) {236input_report_key(ts->idev, BTN_TOUCH, !!pressure);237ts->pen_down = true;238}239} else {240input_report_abs(ts->idev, ABS_PRESSURE, 0);241if (ts->pen_down) {242input_report_key(ts->idev, BTN_TOUCH, 0);243ts->pen_down = false;244}245}246input_sync(ts->idev);247dev_dbg(&ts->spi->dev, "point(%4d,%4d), pressure (%4d)\n", x, y,248pressure);249}250251static irqreturn_t tsc2005_irq_thread(int irq, void *_ts)252{253struct tsc2005 *ts = _ts;254unsigned long flags;255unsigned int pressure;256u32 x, y;257u32 z1, z2;258int error;259260/* read the coordinates */261error = spi_sync(ts->spi, &ts->spi_read_msg);262if (unlikely(error))263goto out;264265x = ts->spi_x.spi_rx;266y = ts->spi_y.spi_rx;267z1 = ts->spi_z1.spi_rx;268z2 = ts->spi_z2.spi_rx;269270/* validate position */271if (unlikely(x > MAX_12BIT || y > MAX_12BIT))272goto out;273274/* Skip reading if the pressure components are out of range */275if (unlikely(z1 == 0 || z2 > MAX_12BIT || z1 >= z2))276goto out;277278/*279* Skip point if this is a pen down with the exact same values as280* the value before pen-up - that implies SPI fed us stale data281*/282if (!ts->pen_down &&283ts->in_x == x && ts->in_y == y &&284ts->in_z1 == z1 && ts->in_z2 == z2) {285goto out;286}287288/*289* At this point we are happy we have a valid and useful reading.290* Remember it for later comparisons. We may now begin downsampling.291*/292ts->in_x = x;293ts->in_y = y;294ts->in_z1 = z1;295ts->in_z2 = z2;296297/* Compute touch pressure resistance using equation #1 */298pressure = x * (z2 - z1) / z1;299pressure = pressure * ts->x_plate_ohm / 4096;300if (unlikely(pressure > MAX_12BIT))301goto out;302303spin_lock_irqsave(&ts->lock, flags);304305tsc2005_update_pen_state(ts, x, y, pressure);306mod_timer(&ts->penup_timer,307jiffies + msecs_to_jiffies(TSC2005_PENUP_TIME_MS));308309spin_unlock_irqrestore(&ts->lock, flags);310311ts->last_valid_interrupt = jiffies;312out:313return IRQ_HANDLED;314}315316static void tsc2005_penup_timer(unsigned long data)317{318struct tsc2005 *ts = (struct tsc2005 *)data;319unsigned long flags;320321spin_lock_irqsave(&ts->lock, flags);322tsc2005_update_pen_state(ts, 0, 0, 0);323spin_unlock_irqrestore(&ts->lock, flags);324}325326static void tsc2005_start_scan(struct tsc2005 *ts)327{328tsc2005_write(ts, TSC2005_REG_CFR0, TSC2005_CFR0_INITVALUE);329tsc2005_write(ts, TSC2005_REG_CFR1, TSC2005_CFR1_INITVALUE);330tsc2005_write(ts, TSC2005_REG_CFR2, TSC2005_CFR2_INITVALUE);331tsc2005_cmd(ts, TSC2005_CMD_NORMAL);332}333334static void tsc2005_stop_scan(struct tsc2005 *ts)335{336tsc2005_cmd(ts, TSC2005_CMD_STOP);337}338339/* must be called with ts->mutex held */340static void __tsc2005_disable(struct tsc2005 *ts)341{342tsc2005_stop_scan(ts);343344disable_irq(ts->spi->irq);345del_timer_sync(&ts->penup_timer);346347cancel_delayed_work_sync(&ts->esd_work);348349enable_irq(ts->spi->irq);350}351352/* must be called with ts->mutex held */353static void __tsc2005_enable(struct tsc2005 *ts)354{355tsc2005_start_scan(ts);356357if (ts->esd_timeout && ts->set_reset) {358ts->last_valid_interrupt = jiffies;359schedule_delayed_work(&ts->esd_work,360round_jiffies_relative(361msecs_to_jiffies(ts->esd_timeout)));362}363364}365366static ssize_t tsc2005_selftest_show(struct device *dev,367struct device_attribute *attr,368char *buf)369{370struct spi_device *spi = to_spi_device(dev);371struct tsc2005 *ts = spi_get_drvdata(spi);372u16 temp_high;373u16 temp_high_orig;374u16 temp_high_test;375bool success = true;376int error;377378mutex_lock(&ts->mutex);379380/*381* Test TSC2005 communications via temp high register.382*/383__tsc2005_disable(ts);384385error = tsc2005_read(ts, TSC2005_REG_TEMP_HIGH, &temp_high_orig);386if (error) {387dev_warn(dev, "selftest failed: read error %d\n", error);388success = false;389goto out;390}391392temp_high_test = (temp_high_orig - 1) & MAX_12BIT;393394error = tsc2005_write(ts, TSC2005_REG_TEMP_HIGH, temp_high_test);395if (error) {396dev_warn(dev, "selftest failed: write error %d\n", error);397success = false;398goto out;399}400401error = tsc2005_read(ts, TSC2005_REG_TEMP_HIGH, &temp_high);402if (error) {403dev_warn(dev, "selftest failed: read error %d after write\n",404error);405success = false;406goto out;407}408409if (temp_high != temp_high_test) {410dev_warn(dev, "selftest failed: %d != %d\n",411temp_high, temp_high_test);412success = false;413}414415/* hardware reset */416ts->set_reset(false);417usleep_range(100, 500); /* only 10us required */418ts->set_reset(true);419420if (!success)421goto out;422423/* test that the reset really happened */424error = tsc2005_read(ts, TSC2005_REG_TEMP_HIGH, &temp_high);425if (error) {426dev_warn(dev, "selftest failed: read error %d after reset\n",427error);428success = false;429goto out;430}431432if (temp_high != temp_high_orig) {433dev_warn(dev, "selftest failed after reset: %d != %d\n",434temp_high, temp_high_orig);435success = false;436}437438out:439__tsc2005_enable(ts);440mutex_unlock(&ts->mutex);441442return sprintf(buf, "%d\n", success);443}444445static DEVICE_ATTR(selftest, S_IRUGO, tsc2005_selftest_show, NULL);446447static struct attribute *tsc2005_attrs[] = {448&dev_attr_selftest.attr,449NULL450};451452static mode_t tsc2005_attr_is_visible(struct kobject *kobj,453struct attribute *attr, int n)454{455struct device *dev = container_of(kobj, struct device, kobj);456struct spi_device *spi = to_spi_device(dev);457struct tsc2005 *ts = spi_get_drvdata(spi);458mode_t mode = attr->mode;459460if (attr == &dev_attr_selftest.attr) {461if (!ts->set_reset)462mode = 0;463}464465return mode;466}467468static const struct attribute_group tsc2005_attr_group = {469.is_visible = tsc2005_attr_is_visible,470.attrs = tsc2005_attrs,471};472473static void tsc2005_esd_work(struct work_struct *work)474{475struct tsc2005 *ts = container_of(work, struct tsc2005, esd_work.work);476int error;477u16 r;478479if (!mutex_trylock(&ts->mutex)) {480/*481* If the mutex is taken, it means that disable or enable is in482* progress. In that case just reschedule the work. If the work483* is not needed, it will be canceled by disable.484*/485goto reschedule;486}487488if (time_is_after_jiffies(ts->last_valid_interrupt +489msecs_to_jiffies(ts->esd_timeout)))490goto out;491492/* We should be able to read register without disabling interrupts. */493error = tsc2005_read(ts, TSC2005_REG_CFR0, &r);494if (!error &&495!((r ^ TSC2005_CFR0_INITVALUE) & TSC2005_CFR0_RW_MASK)) {496goto out;497}498499/*500* If we could not read our known value from configuration register 0501* then we should reset the controller as if from power-up and start502* scanning again.503*/504dev_info(&ts->spi->dev, "TSC2005 not responding - resetting\n");505506disable_irq(ts->spi->irq);507del_timer_sync(&ts->penup_timer);508509tsc2005_update_pen_state(ts, 0, 0, 0);510511ts->set_reset(false);512usleep_range(100, 500); /* only 10us required */513ts->set_reset(true);514515enable_irq(ts->spi->irq);516tsc2005_start_scan(ts);517518out:519mutex_unlock(&ts->mutex);520reschedule:521/* re-arm the watchdog */522schedule_delayed_work(&ts->esd_work,523round_jiffies_relative(524msecs_to_jiffies(ts->esd_timeout)));525}526527static int tsc2005_open(struct input_dev *input)528{529struct tsc2005 *ts = input_get_drvdata(input);530531mutex_lock(&ts->mutex);532533if (!ts->suspended)534__tsc2005_enable(ts);535536ts->opened = true;537538mutex_unlock(&ts->mutex);539540return 0;541}542543static void tsc2005_close(struct input_dev *input)544{545struct tsc2005 *ts = input_get_drvdata(input);546547mutex_lock(&ts->mutex);548549if (!ts->suspended)550__tsc2005_disable(ts);551552ts->opened = false;553554mutex_unlock(&ts->mutex);555}556557static void __devinit tsc2005_setup_spi_xfer(struct tsc2005 *ts)558{559tsc2005_setup_read(&ts->spi_x, TSC2005_REG_X, false);560tsc2005_setup_read(&ts->spi_y, TSC2005_REG_Y, false);561tsc2005_setup_read(&ts->spi_z1, TSC2005_REG_Z1, false);562tsc2005_setup_read(&ts->spi_z2, TSC2005_REG_Z2, true);563564spi_message_init(&ts->spi_read_msg);565spi_message_add_tail(&ts->spi_x.spi_xfer, &ts->spi_read_msg);566spi_message_add_tail(&ts->spi_y.spi_xfer, &ts->spi_read_msg);567spi_message_add_tail(&ts->spi_z1.spi_xfer, &ts->spi_read_msg);568spi_message_add_tail(&ts->spi_z2.spi_xfer, &ts->spi_read_msg);569}570571static int __devinit tsc2005_probe(struct spi_device *spi)572{573const struct tsc2005_platform_data *pdata = spi->dev.platform_data;574struct tsc2005 *ts;575struct input_dev *input_dev;576unsigned int max_x, max_y, max_p;577unsigned int fudge_x, fudge_y, fudge_p;578int error;579580if (!pdata) {581dev_dbg(&spi->dev, "no platform data\n");582return -ENODEV;583}584585fudge_x = pdata->ts_x_fudge ? : 4;586fudge_y = pdata->ts_y_fudge ? : 8;587fudge_p = pdata->ts_pressure_fudge ? : 2;588max_x = pdata->ts_x_max ? : MAX_12BIT;589max_y = pdata->ts_y_max ? : MAX_12BIT;590max_p = pdata->ts_pressure_max ? : MAX_12BIT;591592if (spi->irq <= 0) {593dev_dbg(&spi->dev, "no irq\n");594return -ENODEV;595}596597spi->mode = SPI_MODE_0;598spi->bits_per_word = 8;599if (!spi->max_speed_hz)600spi->max_speed_hz = TSC2005_SPI_MAX_SPEED_HZ;601602error = spi_setup(spi);603if (error)604return error;605606ts = kzalloc(sizeof(*ts), GFP_KERNEL);607input_dev = input_allocate_device();608if (!ts || !input_dev) {609error = -ENOMEM;610goto err_free_mem;611}612613ts->spi = spi;614ts->idev = input_dev;615616ts->x_plate_ohm = pdata->ts_x_plate_ohm ? : 280;617ts->esd_timeout = pdata->esd_timeout_ms;618ts->set_reset = pdata->set_reset;619620mutex_init(&ts->mutex);621622spin_lock_init(&ts->lock);623setup_timer(&ts->penup_timer, tsc2005_penup_timer, (unsigned long)ts);624625INIT_DELAYED_WORK(&ts->esd_work, tsc2005_esd_work);626627tsc2005_setup_spi_xfer(ts);628629snprintf(ts->phys, sizeof(ts->phys),630"%s/input-ts", dev_name(&spi->dev));631632input_dev->name = "TSC2005 touchscreen";633input_dev->phys = ts->phys;634input_dev->id.bustype = BUS_SPI;635input_dev->dev.parent = &spi->dev;636input_dev->evbit[0] = BIT(EV_ABS) | BIT(EV_KEY);637input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);638639input_set_abs_params(input_dev, ABS_X, 0, max_x, fudge_x, 0);640input_set_abs_params(input_dev, ABS_Y, 0, max_y, fudge_y, 0);641input_set_abs_params(input_dev, ABS_PRESSURE, 0, max_p, fudge_p, 0);642643input_dev->open = tsc2005_open;644input_dev->close = tsc2005_close;645646input_set_drvdata(input_dev, ts);647648/* Ensure the touchscreen is off */649tsc2005_stop_scan(ts);650651error = request_threaded_irq(spi->irq, NULL, tsc2005_irq_thread,652IRQF_TRIGGER_RISING, "tsc2005", ts);653if (error) {654dev_err(&spi->dev, "Failed to request irq, err: %d\n", error);655goto err_free_mem;656}657658spi_set_drvdata(spi, ts);659error = sysfs_create_group(&spi->dev.kobj, &tsc2005_attr_group);660if (error) {661dev_err(&spi->dev,662"Failed to create sysfs attributes, err: %d\n", error);663goto err_clear_drvdata;664}665666error = input_register_device(ts->idev);667if (error) {668dev_err(&spi->dev,669"Failed to register input device, err: %d\n", error);670goto err_remove_sysfs;671}672673irq_set_irq_wake(spi->irq, 1);674return 0;675676err_remove_sysfs:677sysfs_remove_group(&spi->dev.kobj, &tsc2005_attr_group);678err_clear_drvdata:679spi_set_drvdata(spi, NULL);680free_irq(spi->irq, ts);681err_free_mem:682input_free_device(input_dev);683kfree(ts);684return error;685}686687static int __devexit tsc2005_remove(struct spi_device *spi)688{689struct tsc2005 *ts = spi_get_drvdata(spi);690691sysfs_remove_group(&ts->spi->dev.kobj, &tsc2005_attr_group);692693free_irq(ts->spi->irq, ts);694input_unregister_device(ts->idev);695kfree(ts);696697spi_set_drvdata(spi, NULL);698return 0;699}700701#ifdef CONFIG_PM_SLEEP702static int tsc2005_suspend(struct device *dev)703{704struct spi_device *spi = to_spi_device(dev);705struct tsc2005 *ts = spi_get_drvdata(spi);706707mutex_lock(&ts->mutex);708709if (!ts->suspended && ts->opened)710__tsc2005_disable(ts);711712ts->suspended = true;713714mutex_unlock(&ts->mutex);715716return 0;717}718719static int tsc2005_resume(struct device *dev)720{721struct spi_device *spi = to_spi_device(dev);722struct tsc2005 *ts = spi_get_drvdata(spi);723724mutex_lock(&ts->mutex);725726if (ts->suspended && ts->opened)727__tsc2005_enable(ts);728729ts->suspended = false;730731mutex_unlock(&ts->mutex);732733return 0;734}735#endif736737static SIMPLE_DEV_PM_OPS(tsc2005_pm_ops, tsc2005_suspend, tsc2005_resume);738739static struct spi_driver tsc2005_driver = {740.driver = {741.name = "tsc2005",742.owner = THIS_MODULE,743.pm = &tsc2005_pm_ops,744},745.probe = tsc2005_probe,746.remove = __devexit_p(tsc2005_remove),747};748749static int __init tsc2005_init(void)750{751return spi_register_driver(&tsc2005_driver);752}753module_init(tsc2005_init);754755static void __exit tsc2005_exit(void)756{757spi_unregister_driver(&tsc2005_driver);758}759module_exit(tsc2005_exit);760761MODULE_AUTHOR("Lauri Leukkunen <[email protected]>");762MODULE_DESCRIPTION("TSC2005 Touchscreen Driver");763MODULE_LICENSE("GPL");764765766