Path: blob/master/drivers/input/mouse/synaptics_i2c.c
15109 views
/*1* Synaptics touchpad with I2C interface2*3* Copyright (C) 2009 Compulab, Ltd.4* Mike Rapoport <[email protected]>5* Igor Grinberg <[email protected]>6*7* This file is subject to the terms and conditions of the GNU General Public8* License. See the file COPYING in the main directory of this archive for9* more details.10*/1112#include <linux/module.h>13#include <linux/i2c.h>14#include <linux/irq.h>15#include <linux/interrupt.h>16#include <linux/input.h>17#include <linux/delay.h>18#include <linux/workqueue.h>19#include <linux/slab.h>20#include <linux/pm.h>2122#define DRIVER_NAME "synaptics_i2c"23/* maximum product id is 15 characters */24#define PRODUCT_ID_LENGTH 1525#define REGISTER_LENGTH 82627/*28* after soft reset, we should wait for 1 ms29* before the device becomes operational30*/31#define SOFT_RESET_DELAY_MS 332/* and after hard reset, we should wait for max 500ms */33#define HARD_RESET_DELAY_MS 5003435/* Registers by SMBus address */36#define PAGE_SEL_REG 0xff37#define DEVICE_STATUS_REG 0x093839/* Registers by RMI address */40#define DEV_CONTROL_REG 0x000041#define INTERRUPT_EN_REG 0x000142#define ERR_STAT_REG 0x000243#define INT_REQ_STAT_REG 0x000344#define DEV_COMMAND_REG 0x00044546#define RMI_PROT_VER_REG 0x020047#define MANUFACT_ID_REG 0x020148#define PHYS_INT_VER_REG 0x020249#define PROD_PROPERTY_REG 0x020350#define INFO_QUERY_REG0 0x020451#define INFO_QUERY_REG1 (INFO_QUERY_REG0 + 1)52#define INFO_QUERY_REG2 (INFO_QUERY_REG0 + 2)53#define INFO_QUERY_REG3 (INFO_QUERY_REG0 + 3)5455#define PRODUCT_ID_REG0 0x021056#define PRODUCT_ID_REG1 (PRODUCT_ID_REG0 + 1)57#define PRODUCT_ID_REG2 (PRODUCT_ID_REG0 + 2)58#define PRODUCT_ID_REG3 (PRODUCT_ID_REG0 + 3)59#define PRODUCT_ID_REG4 (PRODUCT_ID_REG0 + 4)60#define PRODUCT_ID_REG5 (PRODUCT_ID_REG0 + 5)61#define PRODUCT_ID_REG6 (PRODUCT_ID_REG0 + 6)62#define PRODUCT_ID_REG7 (PRODUCT_ID_REG0 + 7)63#define PRODUCT_ID_REG8 (PRODUCT_ID_REG0 + 8)64#define PRODUCT_ID_REG9 (PRODUCT_ID_REG0 + 9)65#define PRODUCT_ID_REG10 (PRODUCT_ID_REG0 + 10)66#define PRODUCT_ID_REG11 (PRODUCT_ID_REG0 + 11)67#define PRODUCT_ID_REG12 (PRODUCT_ID_REG0 + 12)68#define PRODUCT_ID_REG13 (PRODUCT_ID_REG0 + 13)69#define PRODUCT_ID_REG14 (PRODUCT_ID_REG0 + 14)70#define PRODUCT_ID_REG15 (PRODUCT_ID_REG0 + 15)7172#define DATA_REG0 0x040073#define ABS_PRESSURE_REG 0x040174#define ABS_MSB_X_REG 0x040275#define ABS_LSB_X_REG (ABS_MSB_X_REG + 1)76#define ABS_MSB_Y_REG 0x040477#define ABS_LSB_Y_REG (ABS_MSB_Y_REG + 1)78#define REL_X_REG 0x040679#define REL_Y_REG 0x04078081#define DEV_QUERY_REG0 0x100082#define DEV_QUERY_REG1 (DEV_QUERY_REG0 + 1)83#define DEV_QUERY_REG2 (DEV_QUERY_REG0 + 2)84#define DEV_QUERY_REG3 (DEV_QUERY_REG0 + 3)85#define DEV_QUERY_REG4 (DEV_QUERY_REG0 + 4)86#define DEV_QUERY_REG5 (DEV_QUERY_REG0 + 5)87#define DEV_QUERY_REG6 (DEV_QUERY_REG0 + 6)88#define DEV_QUERY_REG7 (DEV_QUERY_REG0 + 7)89#define DEV_QUERY_REG8 (DEV_QUERY_REG0 + 8)9091#define GENERAL_2D_CONTROL_REG 0x104192#define SENSOR_SENSITIVITY_REG 0x104493#define SENS_MAX_POS_MSB_REG 0x104694#define SENS_MAX_POS_LSB_REG (SENS_MAX_POS_UPPER_REG + 1)9596/* Register bits */97/* Device Control Register Bits */98#define REPORT_RATE_1ST_BIT 699100/* Interrupt Enable Register Bits (INTERRUPT_EN_REG) */101#define F10_ABS_INT_ENA 0102#define F10_REL_INT_ENA 1103#define F20_INT_ENA 2104105/* Interrupt Request Register Bits (INT_REQ_STAT_REG | DEVICE_STATUS_REG) */106#define F10_ABS_INT_REQ 0107#define F10_REL_INT_REQ 1108#define F20_INT_REQ 2109/* Device Status Register Bits (DEVICE_STATUS_REG) */110#define STAT_CONFIGURED 6111#define STAT_ERROR 7112113/* Device Command Register Bits (DEV_COMMAND_REG) */114#define RESET_COMMAND 0x01115#define REZERO_COMMAND 0x02116117/* Data Register 0 Bits (DATA_REG0) */118#define GESTURE 3119120/* Device Query Registers Bits */121/* DEV_QUERY_REG3 */122#define HAS_PALM_DETECT 1123#define HAS_MULTI_FING 2124#define HAS_SCROLLER 4125#define HAS_2D_SCROLL 5126127/* General 2D Control Register Bits (GENERAL_2D_CONTROL_REG) */128#define NO_DECELERATION 1129#define REDUCE_REPORTING 3130#define NO_FILTER 5131132/* Function Masks */133/* Device Control Register Masks (DEV_CONTROL_REG) */134#define REPORT_RATE_MSK 0xc0135#define SLEEP_MODE_MSK 0x07136137/* Device Sleep Modes */138#define FULL_AWAKE 0x0139#define NORMAL_OP 0x1140#define LOW_PWR_OP 0x2141#define VERY_LOW_PWR_OP 0x3142#define SENS_SLEEP 0x4143#define SLEEP_MOD 0x5144#define DEEP_SLEEP 0x6145#define HIBERNATE 0x7146147/* Interrupt Register Mask */148/* (INT_REQ_STAT_REG | DEVICE_STATUS_REG | INTERRUPT_EN_REG) */149#define INT_ENA_REQ_MSK 0x07150#define INT_ENA_ABS_MSK 0x01151#define INT_ENA_REL_MSK 0x02152#define INT_ENA_F20_MSK 0x04153154/* Device Status Register Masks (DEVICE_STATUS_REG) */155#define CONFIGURED_MSK 0x40156#define ERROR_MSK 0x80157158/* Data Register 0 Masks */159#define FINGER_WIDTH_MSK 0xf0160#define GESTURE_MSK 0x08161#define SENSOR_STATUS_MSK 0x07162163/*164* MSB Position Register Masks165* ABS_MSB_X_REG | ABS_MSB_Y_REG | SENS_MAX_POS_MSB_REG |166* DEV_QUERY_REG3 | DEV_QUERY_REG5167*/168#define MSB_POSITION_MSK 0x1f169170/* Device Query Registers Masks */171172/* DEV_QUERY_REG2 */173#define NUM_EXTRA_POS_MSK 0x07174175/* When in IRQ mode read the device every THREAD_IRQ_SLEEP_SECS */176#define THREAD_IRQ_SLEEP_SECS 2177#define THREAD_IRQ_SLEEP_MSECS (THREAD_IRQ_SLEEP_SECS * MSEC_PER_SEC)178179/*180* When in Polling mode and no data received for NO_DATA_THRES msecs181* reduce the polling rate to NO_DATA_SLEEP_MSECS182*/183#define NO_DATA_THRES (MSEC_PER_SEC)184#define NO_DATA_SLEEP_MSECS (MSEC_PER_SEC / 4)185186/* Control touchpad's No Deceleration option */187static int no_decel = 1;188module_param(no_decel, bool, 0644);189MODULE_PARM_DESC(no_decel, "No Deceleration. Default = 1 (on)");190191/* Control touchpad's Reduced Reporting option */192static int reduce_report;193module_param(reduce_report, bool, 0644);194MODULE_PARM_DESC(reduce_report, "Reduced Reporting. Default = 0 (off)");195196/* Control touchpad's No Filter option */197static int no_filter;198module_param(no_filter, bool, 0644);199MODULE_PARM_DESC(no_filter, "No Filter. Default = 0 (off)");200201/*202* touchpad Attention line is Active Low and Open Drain,203* therefore should be connected to pulled up line204* and the irq configuration should be set to Falling Edge Trigger205*/206/* Control IRQ / Polling option */207static bool polling_req;208module_param(polling_req, bool, 0444);209MODULE_PARM_DESC(polling_req, "Request Polling. Default = 0 (use irq)");210211/* Control Polling Rate */212static int scan_rate = 80;213module_param(scan_rate, int, 0644);214MODULE_PARM_DESC(scan_rate, "Polling rate in times/sec. Default = 80");215216/* The main device structure */217struct synaptics_i2c {218struct i2c_client *client;219struct input_dev *input;220struct delayed_work dwork;221spinlock_t lock;222int no_data_count;223int no_decel_param;224int reduce_report_param;225int no_filter_param;226int scan_rate_param;227int scan_ms;228};229230static inline void set_scan_rate(struct synaptics_i2c *touch, int scan_rate)231{232touch->scan_ms = MSEC_PER_SEC / scan_rate;233touch->scan_rate_param = scan_rate;234}235236/*237* Driver's initial design makes no race condition possible on i2c bus,238* so there is no need in any locking.239* Keep it in mind, while playing with the code.240*/241static s32 synaptics_i2c_reg_get(struct i2c_client *client, u16 reg)242{243int ret;244245ret = i2c_smbus_write_byte_data(client, PAGE_SEL_REG, reg >> 8);246if (ret == 0)247ret = i2c_smbus_read_byte_data(client, reg & 0xff);248249return ret;250}251252static s32 synaptics_i2c_reg_set(struct i2c_client *client, u16 reg, u8 val)253{254int ret;255256ret = i2c_smbus_write_byte_data(client, PAGE_SEL_REG, reg >> 8);257if (ret == 0)258ret = i2c_smbus_write_byte_data(client, reg & 0xff, val);259260return ret;261}262263static s32 synaptics_i2c_word_get(struct i2c_client *client, u16 reg)264{265int ret;266267ret = i2c_smbus_write_byte_data(client, PAGE_SEL_REG, reg >> 8);268if (ret == 0)269ret = i2c_smbus_read_word_data(client, reg & 0xff);270271return ret;272}273274static int synaptics_i2c_config(struct i2c_client *client)275{276int ret, control;277u8 int_en;278279/* set Report Rate to Device Highest (>=80) and Sleep to normal */280ret = synaptics_i2c_reg_set(client, DEV_CONTROL_REG, 0xc1);281if (ret)282return ret;283284/* set Interrupt Disable to Func20 / Enable to Func10) */285int_en = (polling_req) ? 0 : INT_ENA_ABS_MSK | INT_ENA_REL_MSK;286ret = synaptics_i2c_reg_set(client, INTERRUPT_EN_REG, int_en);287if (ret)288return ret;289290control = synaptics_i2c_reg_get(client, GENERAL_2D_CONTROL_REG);291/* No Deceleration */292control |= no_decel ? 1 << NO_DECELERATION : 0;293/* Reduced Reporting */294control |= reduce_report ? 1 << REDUCE_REPORTING : 0;295/* No Filter */296control |= no_filter ? 1 << NO_FILTER : 0;297ret = synaptics_i2c_reg_set(client, GENERAL_2D_CONTROL_REG, control);298if (ret)299return ret;300301return 0;302}303304static int synaptics_i2c_reset_config(struct i2c_client *client)305{306int ret;307308/* Reset the Touchpad */309ret = synaptics_i2c_reg_set(client, DEV_COMMAND_REG, RESET_COMMAND);310if (ret) {311dev_err(&client->dev, "Unable to reset device\n");312} else {313msleep(SOFT_RESET_DELAY_MS);314ret = synaptics_i2c_config(client);315if (ret)316dev_err(&client->dev, "Unable to config device\n");317}318319return ret;320}321322static int synaptics_i2c_check_error(struct i2c_client *client)323{324int status, ret = 0;325326status = i2c_smbus_read_byte_data(client, DEVICE_STATUS_REG) &327(CONFIGURED_MSK | ERROR_MSK);328329if (status != CONFIGURED_MSK)330ret = synaptics_i2c_reset_config(client);331332return ret;333}334335static bool synaptics_i2c_get_input(struct synaptics_i2c *touch)336{337struct input_dev *input = touch->input;338int xy_delta, gesture;339s32 data;340s8 x_delta, y_delta;341342/* Deal with spontanious resets and errors */343if (synaptics_i2c_check_error(touch->client))344return 0;345346/* Get Gesture Bit */347data = synaptics_i2c_reg_get(touch->client, DATA_REG0);348gesture = (data >> GESTURE) & 0x1;349350/*351* Get Relative axes. we have to get them in one shot,352* so we get 2 bytes starting from REL_X_REG.353*/354xy_delta = synaptics_i2c_word_get(touch->client, REL_X_REG) & 0xffff;355356/* Separate X from Y */357x_delta = xy_delta & 0xff;358y_delta = (xy_delta >> REGISTER_LENGTH) & 0xff;359360/* Report the button event */361input_report_key(input, BTN_LEFT, gesture);362363/* Report the deltas */364input_report_rel(input, REL_X, x_delta);365input_report_rel(input, REL_Y, -y_delta);366input_sync(input);367368return xy_delta || gesture;369}370371static void synaptics_i2c_reschedule_work(struct synaptics_i2c *touch,372unsigned long delay)373{374unsigned long flags;375376spin_lock_irqsave(&touch->lock, flags);377378/*379* If work is already scheduled then subsequent schedules will not380* change the scheduled time that's why we have to cancel it first.381*/382__cancel_delayed_work(&touch->dwork);383schedule_delayed_work(&touch->dwork, delay);384385spin_unlock_irqrestore(&touch->lock, flags);386}387388static irqreturn_t synaptics_i2c_irq(int irq, void *dev_id)389{390struct synaptics_i2c *touch = dev_id;391392synaptics_i2c_reschedule_work(touch, 0);393394return IRQ_HANDLED;395}396397static void synaptics_i2c_check_params(struct synaptics_i2c *touch)398{399bool reset = false;400401if (scan_rate != touch->scan_rate_param)402set_scan_rate(touch, scan_rate);403404if (no_decel != touch->no_decel_param) {405touch->no_decel_param = no_decel;406reset = true;407}408409if (no_filter != touch->no_filter_param) {410touch->no_filter_param = no_filter;411reset = true;412}413414if (reduce_report != touch->reduce_report_param) {415touch->reduce_report_param = reduce_report;416reset = true;417}418419if (reset)420synaptics_i2c_reset_config(touch->client);421}422423/* Control the Device polling rate / Work Handler sleep time */424static unsigned long synaptics_i2c_adjust_delay(struct synaptics_i2c *touch,425bool have_data)426{427unsigned long delay, nodata_count_thres;428429if (polling_req) {430delay = touch->scan_ms;431if (have_data) {432touch->no_data_count = 0;433} else {434nodata_count_thres = NO_DATA_THRES / touch->scan_ms;435if (touch->no_data_count < nodata_count_thres)436touch->no_data_count++;437else438delay = NO_DATA_SLEEP_MSECS;439}440return msecs_to_jiffies(delay);441} else {442delay = msecs_to_jiffies(THREAD_IRQ_SLEEP_MSECS);443return round_jiffies_relative(delay);444}445}446447/* Work Handler */448static void synaptics_i2c_work_handler(struct work_struct *work)449{450bool have_data;451struct synaptics_i2c *touch =452container_of(work, struct synaptics_i2c, dwork.work);453unsigned long delay;454455synaptics_i2c_check_params(touch);456457have_data = synaptics_i2c_get_input(touch);458delay = synaptics_i2c_adjust_delay(touch, have_data);459460/*461* While interrupt driven, there is no real need to poll the device.462* But touchpads are very sensitive, so there could be errors463* related to physical environment and the attention line isn't464* necessarily asserted. In such case we can lose the touchpad.465* We poll the device once in THREAD_IRQ_SLEEP_SECS and466* if error is detected, we try to reset and reconfigure the touchpad.467*/468synaptics_i2c_reschedule_work(touch, delay);469}470471static int synaptics_i2c_open(struct input_dev *input)472{473struct synaptics_i2c *touch = input_get_drvdata(input);474int ret;475476ret = synaptics_i2c_reset_config(touch->client);477if (ret)478return ret;479480if (polling_req)481synaptics_i2c_reschedule_work(touch,482msecs_to_jiffies(NO_DATA_SLEEP_MSECS));483484return 0;485}486487static void synaptics_i2c_close(struct input_dev *input)488{489struct synaptics_i2c *touch = input_get_drvdata(input);490491if (!polling_req)492synaptics_i2c_reg_set(touch->client, INTERRUPT_EN_REG, 0);493494cancel_delayed_work_sync(&touch->dwork);495496/* Save some power */497synaptics_i2c_reg_set(touch->client, DEV_CONTROL_REG, DEEP_SLEEP);498}499500static void synaptics_i2c_set_input_params(struct synaptics_i2c *touch)501{502struct input_dev *input = touch->input;503504input->name = touch->client->name;505input->phys = touch->client->adapter->name;506input->id.bustype = BUS_I2C;507input->id.version = synaptics_i2c_word_get(touch->client,508INFO_QUERY_REG0);509input->dev.parent = &touch->client->dev;510input->open = synaptics_i2c_open;511input->close = synaptics_i2c_close;512input_set_drvdata(input, touch);513514/* Register the device as mouse */515__set_bit(EV_REL, input->evbit);516__set_bit(REL_X, input->relbit);517__set_bit(REL_Y, input->relbit);518519/* Register device's buttons and keys */520__set_bit(EV_KEY, input->evbit);521__set_bit(BTN_LEFT, input->keybit);522}523524static struct synaptics_i2c *synaptics_i2c_touch_create(struct i2c_client *client)525{526struct synaptics_i2c *touch;527528touch = kzalloc(sizeof(struct synaptics_i2c), GFP_KERNEL);529if (!touch)530return NULL;531532touch->client = client;533touch->no_decel_param = no_decel;534touch->scan_rate_param = scan_rate;535set_scan_rate(touch, scan_rate);536INIT_DELAYED_WORK(&touch->dwork, synaptics_i2c_work_handler);537spin_lock_init(&touch->lock);538539return touch;540}541542static int __devinit synaptics_i2c_probe(struct i2c_client *client,543const struct i2c_device_id *dev_id)544{545int ret;546struct synaptics_i2c *touch;547548touch = synaptics_i2c_touch_create(client);549if (!touch)550return -ENOMEM;551552ret = synaptics_i2c_reset_config(client);553if (ret)554goto err_mem_free;555556if (client->irq < 1)557polling_req = true;558559touch->input = input_allocate_device();560if (!touch->input) {561ret = -ENOMEM;562goto err_mem_free;563}564565synaptics_i2c_set_input_params(touch);566567if (!polling_req) {568dev_dbg(&touch->client->dev,569"Requesting IRQ: %d\n", touch->client->irq);570571ret = request_irq(touch->client->irq, synaptics_i2c_irq,572IRQF_DISABLED|IRQ_TYPE_EDGE_FALLING,573DRIVER_NAME, touch);574if (ret) {575dev_warn(&touch->client->dev,576"IRQ request failed: %d, "577"falling back to polling\n", ret);578polling_req = true;579synaptics_i2c_reg_set(touch->client,580INTERRUPT_EN_REG, 0);581}582}583584if (polling_req)585dev_dbg(&touch->client->dev,586"Using polling at rate: %d times/sec\n", scan_rate);587588/* Register the device in input subsystem */589ret = input_register_device(touch->input);590if (ret) {591dev_err(&client->dev,592"Input device register failed: %d\n", ret);593goto err_input_free;594}595596i2c_set_clientdata(client, touch);597598return 0;599600err_input_free:601input_free_device(touch->input);602err_mem_free:603kfree(touch);604605return ret;606}607608static int __devexit synaptics_i2c_remove(struct i2c_client *client)609{610struct synaptics_i2c *touch = i2c_get_clientdata(client);611612if (!polling_req)613free_irq(client->irq, touch);614615input_unregister_device(touch->input);616kfree(touch);617618return 0;619}620621#ifdef CONFIG_PM622static int synaptics_i2c_suspend(struct device *dev)623{624struct i2c_client *client = to_i2c_client(dev);625struct synaptics_i2c *touch = i2c_get_clientdata(client);626627cancel_delayed_work_sync(&touch->dwork);628629/* Save some power */630synaptics_i2c_reg_set(touch->client, DEV_CONTROL_REG, DEEP_SLEEP);631632return 0;633}634635static int synaptics_i2c_resume(struct device *dev)636{637int ret;638struct i2c_client *client = to_i2c_client(dev);639struct synaptics_i2c *touch = i2c_get_clientdata(client);640641ret = synaptics_i2c_reset_config(client);642if (ret)643return ret;644645synaptics_i2c_reschedule_work(touch,646msecs_to_jiffies(NO_DATA_SLEEP_MSECS));647648return 0;649}650#endif651652static SIMPLE_DEV_PM_OPS(synaptics_i2c_pm, synaptics_i2c_suspend,653synaptics_i2c_resume);654655static const struct i2c_device_id synaptics_i2c_id_table[] = {656{ "synaptics_i2c", 0 },657{ },658};659MODULE_DEVICE_TABLE(i2c, synaptics_i2c_id_table);660661static struct i2c_driver synaptics_i2c_driver = {662.driver = {663.name = DRIVER_NAME,664.owner = THIS_MODULE,665.pm = &synaptics_i2c_pm,666},667668.probe = synaptics_i2c_probe,669.remove = __devexit_p(synaptics_i2c_remove),670671.id_table = synaptics_i2c_id_table,672};673674static int __init synaptics_i2c_init(void)675{676return i2c_add_driver(&synaptics_i2c_driver);677}678679static void __exit synaptics_i2c_exit(void)680{681i2c_del_driver(&synaptics_i2c_driver);682}683684module_init(synaptics_i2c_init);685module_exit(synaptics_i2c_exit);686687MODULE_DESCRIPTION("Synaptics I2C touchpad driver");688MODULE_AUTHOR("Mike Rapoport, Igor Grinberg, Compulab");689MODULE_LICENSE("GPL");690691692693