Path: blob/master/drivers/input/touchscreen/max11801_ts.c
15111 views
/*1* Driver for MAXI MAX11801 - A Resistive touch screen controller with2* i2c interface3*4* Copyright (C) 2011 Freescale Semiconductor, Inc.5* Author: Zhang Jiejing <[email protected]>6*7* Based on mcs5000_ts.c8*9* This program is free software; you can redistribute it and/or modify10* it under the terms of the GNU General Public License as published by11* the Free Software Foundation; either version 2 of the License.12*/1314/*15* This driver aims to support the series of MAXI touch chips max1180116* through max11803. The main difference between these 4 chips can be17* found in the table below:18* -----------------------------------------------------19* | CHIP | AUTO MODE SUPPORT(FIFO) | INTERFACE |20* |----------------------------------------------------|21* | max11800 | YES | SPI |22* | max11801 | YES | I2C |23* | max11802 | NO | SPI |24* | max11803 | NO | I2C |25* ------------------------------------------------------26*27* Currently, this driver only supports max11801.28*29* Data Sheet:30* http://www.maxim-ic.com/datasheet/index.mvp/id/594331*/3233#include <linux/module.h>34#include <linux/init.h>35#include <linux/i2c.h>36#include <linux/interrupt.h>37#include <linux/input.h>38#include <linux/slab.h>39#include <linux/bitops.h>4041/* Register Address define */42#define GENERNAL_STATUS_REG 0x0043#define GENERNAL_CONF_REG 0x0144#define MESURE_RES_CONF_REG 0x0245#define MESURE_AVER_CONF_REG 0x0346#define ADC_SAMPLE_TIME_CONF_REG 0x0447#define PANEL_SETUPTIME_CONF_REG 0x0548#define DELAY_CONVERSION_CONF_REG 0x0649#define TOUCH_DETECT_PULLUP_CONF_REG 0x0750#define AUTO_MODE_TIME_CONF_REG 0x08 /* only for max11800/max11801 */51#define APERTURE_CONF_REG 0x09 /* only for max11800/max11801 */52#define AUX_MESURE_CONF_REG 0x0a53#define OP_MODE_CONF_REG 0x0b5455/* FIFO is found only in max11800 and max11801 */56#define FIFO_RD_CMD (0x50 << 1)57#define MAX11801_FIFO_INT (1 << 2)58#define MAX11801_FIFO_OVERFLOW (1 << 3)5960#define XY_BUFSIZE 461#define XY_BUF_OFFSET 46263#define MAX11801_MAX_X 0xfff64#define MAX11801_MAX_Y 0xfff6566#define MEASURE_TAG_OFFSET 267#define MEASURE_TAG_MASK (3 << MEASURE_TAG_OFFSET)68#define EVENT_TAG_OFFSET 069#define EVENT_TAG_MASK (3 << EVENT_TAG_OFFSET)70#define MEASURE_X_TAG (0 << MEASURE_TAG_OFFSET)71#define MEASURE_Y_TAG (1 << MEASURE_TAG_OFFSET)7273/* These are the state of touch event state machine */74enum {75EVENT_INIT,76EVENT_MIDDLE,77EVENT_RELEASE,78EVENT_FIFO_END79};8081struct max11801_data {82struct i2c_client *client;83struct input_dev *input_dev;84};8586static u8 read_register(struct i2c_client *client, int addr)87{88/* XXX: The chip ignores LSB of register address */89return i2c_smbus_read_byte_data(client, addr << 1);90}9192static int max11801_write_reg(struct i2c_client *client, int addr, int data)93{94/* XXX: The chip ignores LSB of register address */95return i2c_smbus_write_byte_data(client, addr << 1, data);96}9798static irqreturn_t max11801_ts_interrupt(int irq, void *dev_id)99{100struct max11801_data *data = dev_id;101struct i2c_client *client = data->client;102int status, i, ret;103u8 buf[XY_BUFSIZE];104int x = -1;105int y = -1;106107status = read_register(data->client, GENERNAL_STATUS_REG);108109if (status & (MAX11801_FIFO_INT | MAX11801_FIFO_OVERFLOW)) {110status = read_register(data->client, GENERNAL_STATUS_REG);111112ret = i2c_smbus_read_i2c_block_data(client, FIFO_RD_CMD,113XY_BUFSIZE, buf);114115/*116* We should get 4 bytes buffer that contains X,Y117* and event tag118*/119if (ret < XY_BUFSIZE)120goto out;121122for (i = 0; i < XY_BUFSIZE; i += XY_BUFSIZE / 2) {123if ((buf[i + 1] & MEASURE_TAG_MASK) == MEASURE_X_TAG)124x = (buf[i] << XY_BUF_OFFSET) +125(buf[i + 1] >> XY_BUF_OFFSET);126else if ((buf[i + 1] & MEASURE_TAG_MASK) == MEASURE_Y_TAG)127y = (buf[i] << XY_BUF_OFFSET) +128(buf[i + 1] >> XY_BUF_OFFSET);129}130131if ((buf[1] & EVENT_TAG_MASK) != (buf[3] & EVENT_TAG_MASK))132goto out;133134switch (buf[1] & EVENT_TAG_MASK) {135case EVENT_INIT:136/* fall through */137case EVENT_MIDDLE:138input_report_abs(data->input_dev, ABS_X, x);139input_report_abs(data->input_dev, ABS_Y, y);140input_event(data->input_dev, EV_KEY, BTN_TOUCH, 1);141input_sync(data->input_dev);142break;143144case EVENT_RELEASE:145input_event(data->input_dev, EV_KEY, BTN_TOUCH, 0);146input_sync(data->input_dev);147break;148149case EVENT_FIFO_END:150break;151}152}153out:154return IRQ_HANDLED;155}156157static void __devinit max11801_ts_phy_init(struct max11801_data *data)158{159struct i2c_client *client = data->client;160161/* Average X,Y, take 16 samples, average eight media sample */162max11801_write_reg(client, MESURE_AVER_CONF_REG, 0xff);163/* X,Y panel setup time set to 20us */164max11801_write_reg(client, PANEL_SETUPTIME_CONF_REG, 0x11);165/* Rough pullup time (2uS), Fine pullup time (10us) */166max11801_write_reg(client, TOUCH_DETECT_PULLUP_CONF_REG, 0x10);167/* Auto mode init period = 5ms , scan period = 5ms*/168max11801_write_reg(client, AUTO_MODE_TIME_CONF_REG, 0xaa);169/* Aperture X,Y set to +- 4LSB */170max11801_write_reg(client, APERTURE_CONF_REG, 0x33);171/* Enable Power, enable Automode, enable Aperture, enable Average X,Y */172max11801_write_reg(client, OP_MODE_CONF_REG, 0x36);173}174175static int __devinit max11801_ts_probe(struct i2c_client *client,176const struct i2c_device_id *id)177{178struct max11801_data *data;179struct input_dev *input_dev;180int error;181182data = kzalloc(sizeof(struct max11801_data), GFP_KERNEL);183input_dev = input_allocate_device();184if (!data || !input_dev) {185dev_err(&client->dev, "Failed to allocate memory\n");186error = -ENOMEM;187goto err_free_mem;188}189190data->client = client;191data->input_dev = input_dev;192193input_dev->name = "max11801_ts";194input_dev->id.bustype = BUS_I2C;195input_dev->dev.parent = &client->dev;196197__set_bit(EV_ABS, input_dev->evbit);198__set_bit(EV_KEY, input_dev->evbit);199__set_bit(BTN_TOUCH, input_dev->keybit);200input_set_abs_params(input_dev, ABS_X, 0, MAX11801_MAX_X, 0, 0);201input_set_abs_params(input_dev, ABS_Y, 0, MAX11801_MAX_Y, 0, 0);202input_set_drvdata(input_dev, data);203204max11801_ts_phy_init(data);205206error = request_threaded_irq(client->irq, NULL, max11801_ts_interrupt,207IRQF_TRIGGER_LOW | IRQF_ONESHOT,208"max11801_ts", data);209if (error) {210dev_err(&client->dev, "Failed to register interrupt\n");211goto err_free_mem;212}213214error = input_register_device(data->input_dev);215if (error)216goto err_free_irq;217218i2c_set_clientdata(client, data);219return 0;220221err_free_irq:222free_irq(client->irq, data);223err_free_mem:224input_free_device(input_dev);225kfree(data);226return error;227}228229static __devexit int max11801_ts_remove(struct i2c_client *client)230{231struct max11801_data *data = i2c_get_clientdata(client);232233free_irq(client->irq, data);234input_unregister_device(data->input_dev);235kfree(data);236237return 0;238}239240static const struct i2c_device_id max11801_ts_id[] = {241{"max11801", 0},242{ }243};244MODULE_DEVICE_TABLE(i2c, max11801_ts_id);245246static struct i2c_driver max11801_ts_driver = {247.driver = {248.name = "max11801_ts",249.owner = THIS_MODULE,250},251.id_table = max11801_ts_id,252.probe = max11801_ts_probe,253.remove = __devexit_p(max11801_ts_remove),254};255256static int __init max11801_ts_init(void)257{258return i2c_add_driver(&max11801_ts_driver);259}260261static void __exit max11801_ts_exit(void)262{263i2c_del_driver(&max11801_ts_driver);264}265266module_init(max11801_ts_init);267module_exit(max11801_ts_exit);268269MODULE_AUTHOR("Zhang Jiejing <[email protected]>");270MODULE_DESCRIPTION("Touchscreen driver for MAXI MAX11801 controller");271MODULE_LICENSE("GPL");272273274