138e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim/* 238e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim * mcs5000_ts.c - Touchscreen driver for MELFAS MCS-5000 controller 338e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim * 438e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim * Copyright (C) 2009 Samsung Electronics Co.Ltd 538e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim * Author: Joonyoung Shim <jy0922.shim@samsung.com> 638e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim * 738e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim * Based on wm97xx-core.c 838e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim * 938e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim * This program is free software; you can redistribute it and/or modify it 1038e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim * under the terms of the GNU General Public License as published by the 1138e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim * Free Software Foundation; either version 2 of the License, or (at your 1238e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim * option) any later version. 1338e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim * 1438e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim */ 1538e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim 1638e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim#include <linux/module.h> 1738e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim#include <linux/init.h> 1838e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim#include <linux/i2c.h> 19312e8e8a9e2471b0ada7366497fffb3ff1a40e2cJoonyoung Shim#include <linux/i2c/mcs.h> 2038e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim#include <linux/interrupt.h> 2138e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim#include <linux/input.h> 2238e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim#include <linux/irq.h> 235a0e3ad6af8660be21ca98a971cd00f331318c05Tejun Heo#include <linux/slab.h> 2438e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim 2538e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim/* Registers */ 2638e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim#define MCS5000_TS_STATUS 0x00 2738e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim#define STATUS_OFFSET 0 2838e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim#define STATUS_NO (0 << STATUS_OFFSET) 2938e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim#define STATUS_INIT (1 << STATUS_OFFSET) 3038e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim#define STATUS_SENSING (2 << STATUS_OFFSET) 3138e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim#define STATUS_COORD (3 << STATUS_OFFSET) 3238e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim#define STATUS_GESTURE (4 << STATUS_OFFSET) 3338e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim#define ERROR_OFFSET 4 3438e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim#define ERROR_NO (0 << ERROR_OFFSET) 3538e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim#define ERROR_POWER_ON_RESET (1 << ERROR_OFFSET) 3638e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim#define ERROR_INT_RESET (2 << ERROR_OFFSET) 3738e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim#define ERROR_EXT_RESET (3 << ERROR_OFFSET) 3838e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim#define ERROR_INVALID_REG_ADDRESS (8 << ERROR_OFFSET) 3938e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim#define ERROR_INVALID_REG_VALUE (9 << ERROR_OFFSET) 4038e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim 4138e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim#define MCS5000_TS_OP_MODE 0x01 4238e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim#define RESET_OFFSET 0 4338e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim#define RESET_NO (0 << RESET_OFFSET) 4438e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim#define RESET_EXT_SOFT (1 << RESET_OFFSET) 4538e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim#define OP_MODE_OFFSET 1 4638e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim#define OP_MODE_SLEEP (0 << OP_MODE_OFFSET) 4738e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim#define OP_MODE_ACTIVE (1 << OP_MODE_OFFSET) 4838e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim#define GESTURE_OFFSET 4 4938e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim#define GESTURE_DISABLE (0 << GESTURE_OFFSET) 5038e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim#define GESTURE_ENABLE (1 << GESTURE_OFFSET) 5138e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim#define PROXIMITY_OFFSET 5 5238e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim#define PROXIMITY_DISABLE (0 << PROXIMITY_OFFSET) 5338e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim#define PROXIMITY_ENABLE (1 << PROXIMITY_OFFSET) 5438e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim#define SCAN_MODE_OFFSET 6 5538e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim#define SCAN_MODE_INTERRUPT (0 << SCAN_MODE_OFFSET) 5638e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim#define SCAN_MODE_POLLING (1 << SCAN_MODE_OFFSET) 5738e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim#define REPORT_RATE_OFFSET 7 5838e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim#define REPORT_RATE_40 (0 << REPORT_RATE_OFFSET) 5938e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim#define REPORT_RATE_80 (1 << REPORT_RATE_OFFSET) 6038e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim 6138e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim#define MCS5000_TS_SENS_CTL 0x02 6238e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim#define MCS5000_TS_FILTER_CTL 0x03 6338e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim#define PRI_FILTER_OFFSET 0 6438e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim#define SEC_FILTER_OFFSET 4 6538e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim 6638e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim#define MCS5000_TS_X_SIZE_UPPER 0x08 6738e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim#define MCS5000_TS_X_SIZE_LOWER 0x09 6838e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim#define MCS5000_TS_Y_SIZE_UPPER 0x0A 6938e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim#define MCS5000_TS_Y_SIZE_LOWER 0x0B 7038e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim 7138e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim#define MCS5000_TS_INPUT_INFO 0x10 7238e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim#define INPUT_TYPE_OFFSET 0 7338e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim#define INPUT_TYPE_NONTOUCH (0 << INPUT_TYPE_OFFSET) 7438e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim#define INPUT_TYPE_SINGLE (1 << INPUT_TYPE_OFFSET) 7538e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim#define INPUT_TYPE_DUAL (2 << INPUT_TYPE_OFFSET) 7638e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim#define INPUT_TYPE_PALM (3 << INPUT_TYPE_OFFSET) 7738e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim#define INPUT_TYPE_PROXIMITY (7 << INPUT_TYPE_OFFSET) 7838e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim#define GESTURE_CODE_OFFSET 3 7938e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim#define GESTURE_CODE_NO (0 << GESTURE_CODE_OFFSET) 8038e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim 8138e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim#define MCS5000_TS_X_POS_UPPER 0x11 8238e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim#define MCS5000_TS_X_POS_LOWER 0x12 8338e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim#define MCS5000_TS_Y_POS_UPPER 0x13 8438e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim#define MCS5000_TS_Y_POS_LOWER 0x14 8538e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim#define MCS5000_TS_Z_POS 0x15 8638e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim#define MCS5000_TS_WIDTH 0x16 8738e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim#define MCS5000_TS_GESTURE_VAL 0x17 8838e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim#define MCS5000_TS_MODULE_REV 0x20 8938e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim#define MCS5000_TS_FIRMWARE_VER 0x21 9038e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim 9138e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim/* Touchscreen absolute values */ 9238e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim#define MCS5000_MAX_XC 0x3ff 9338e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim#define MCS5000_MAX_YC 0x3ff 9438e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim 9538e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shimenum mcs5000_ts_read_offset { 9638e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim READ_INPUT_INFO, 9738e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim READ_X_POS_UPPER, 9838e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim READ_X_POS_LOWER, 9938e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim READ_Y_POS_UPPER, 10038e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim READ_Y_POS_LOWER, 10138e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim READ_BLOCK_SIZE, 10238e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim}; 10338e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim 10438e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim/* Each client has this additional data */ 10538e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shimstruct mcs5000_ts_data { 10638e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim struct i2c_client *client; 10738e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim struct input_dev *input_dev; 108312e8e8a9e2471b0ada7366497fffb3ff1a40e2cJoonyoung Shim const struct mcs_platform_data *platform_data; 10938e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim}; 11038e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim 11138e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shimstatic irqreturn_t mcs5000_ts_interrupt(int irq, void *dev_id) 11238e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim{ 11338e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim struct mcs5000_ts_data *data = dev_id; 11438e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim struct i2c_client *client = data->client; 11538e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim u8 buffer[READ_BLOCK_SIZE]; 11638e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim int err; 11738e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim int x; 11838e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim int y; 11938e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim 12038e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim err = i2c_smbus_read_i2c_block_data(client, MCS5000_TS_INPUT_INFO, 12138e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim READ_BLOCK_SIZE, buffer); 12238e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim if (err < 0) { 12338e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim dev_err(&client->dev, "%s, err[%d]\n", __func__, err); 12438e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim goto out; 12538e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim } 12638e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim 12738e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim switch (buffer[READ_INPUT_INFO]) { 12838e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim case INPUT_TYPE_NONTOUCH: 12938e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim input_report_key(data->input_dev, BTN_TOUCH, 0); 13038e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim input_sync(data->input_dev); 13138e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim break; 13238e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim 13338e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim case INPUT_TYPE_SINGLE: 13438e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim x = (buffer[READ_X_POS_UPPER] << 8) | buffer[READ_X_POS_LOWER]; 13538e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim y = (buffer[READ_Y_POS_UPPER] << 8) | buffer[READ_Y_POS_LOWER]; 13638e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim 13738e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim input_report_key(data->input_dev, BTN_TOUCH, 1); 13838e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim input_report_abs(data->input_dev, ABS_X, x); 13938e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim input_report_abs(data->input_dev, ABS_Y, y); 14038e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim input_sync(data->input_dev); 14138e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim break; 14238e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim 14338e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim case INPUT_TYPE_DUAL: 14438e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim /* TODO */ 14538e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim break; 14638e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim 14738e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim case INPUT_TYPE_PALM: 14838e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim /* TODO */ 14938e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim break; 15038e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim 15138e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim case INPUT_TYPE_PROXIMITY: 15238e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim /* TODO */ 15338e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim break; 15438e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim 15538e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim default: 15638e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim dev_err(&client->dev, "Unknown ts input type %d\n", 15738e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim buffer[READ_INPUT_INFO]); 15838e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim break; 15938e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim } 16038e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim 16138e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim out: 16238e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim return IRQ_HANDLED; 16338e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim} 16438e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim 16538e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shimstatic void mcs5000_ts_phys_init(struct mcs5000_ts_data *data) 16638e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim{ 167312e8e8a9e2471b0ada7366497fffb3ff1a40e2cJoonyoung Shim const struct mcs_platform_data *platform_data = 16838e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim data->platform_data; 16938e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim struct i2c_client *client = data->client; 17038e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim 17138e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim /* Touch reset & sleep mode */ 17238e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim i2c_smbus_write_byte_data(client, MCS5000_TS_OP_MODE, 17338e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim RESET_EXT_SOFT | OP_MODE_SLEEP); 17438e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim 17538e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim /* Touch size */ 17638e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim i2c_smbus_write_byte_data(client, MCS5000_TS_X_SIZE_UPPER, 17738e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim platform_data->x_size >> 8); 17838e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim i2c_smbus_write_byte_data(client, MCS5000_TS_X_SIZE_LOWER, 17938e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim platform_data->x_size & 0xff); 18038e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim i2c_smbus_write_byte_data(client, MCS5000_TS_Y_SIZE_UPPER, 18138e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim platform_data->y_size >> 8); 18238e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim i2c_smbus_write_byte_data(client, MCS5000_TS_Y_SIZE_LOWER, 18338e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim platform_data->y_size & 0xff); 18438e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim 18538e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim /* Touch active mode & 80 report rate */ 18638e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim i2c_smbus_write_byte_data(data->client, MCS5000_TS_OP_MODE, 18738e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim OP_MODE_ACTIVE | REPORT_RATE_80); 18838e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim} 18938e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim 19038e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shimstatic int __devinit mcs5000_ts_probe(struct i2c_client *client, 19138e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim const struct i2c_device_id *id) 19238e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim{ 19338e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim struct mcs5000_ts_data *data; 19438e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim struct input_dev *input_dev; 19538e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim int ret; 19638e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim 19738e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim if (!client->dev.platform_data) 19838e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim return -EINVAL; 19938e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim 20038e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim data = kzalloc(sizeof(struct mcs5000_ts_data), GFP_KERNEL); 20138e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim input_dev = input_allocate_device(); 20238e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim if (!data || !input_dev) { 20338e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim dev_err(&client->dev, "Failed to allocate memory\n"); 20438e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim ret = -ENOMEM; 20538e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim goto err_free_mem; 20638e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim } 20738e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim 20838e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim data->client = client; 20938e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim data->input_dev = input_dev; 21038e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim data->platform_data = client->dev.platform_data; 21138e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim 21238e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim input_dev->name = "MELPAS MCS-5000 Touchscreen"; 21338e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim input_dev->id.bustype = BUS_I2C; 21438e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim input_dev->dev.parent = &client->dev; 21538e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim 21638e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim __set_bit(EV_ABS, input_dev->evbit); 21738e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim __set_bit(EV_KEY, input_dev->evbit); 21838e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim __set_bit(BTN_TOUCH, input_dev->keybit); 21938e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim input_set_abs_params(input_dev, ABS_X, 0, MCS5000_MAX_XC, 0, 0); 22038e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim input_set_abs_params(input_dev, ABS_Y, 0, MCS5000_MAX_YC, 0, 0); 22138e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim 22238e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim input_set_drvdata(input_dev, data); 22338e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim 22438e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim if (data->platform_data->cfg_pin) 22538e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim data->platform_data->cfg_pin(); 22638e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim 22738e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim ret = request_threaded_irq(client->irq, NULL, mcs5000_ts_interrupt, 22838e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim IRQF_TRIGGER_LOW | IRQF_ONESHOT, "mcs5000_ts", data); 22938e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim 23038e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim if (ret < 0) { 23138e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim dev_err(&client->dev, "Failed to register interrupt\n"); 23238e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim goto err_free_mem; 23338e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim } 23438e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim 23538e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim ret = input_register_device(data->input_dev); 23638e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim if (ret < 0) 23738e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim goto err_free_irq; 23838e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim 23938e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim mcs5000_ts_phys_init(data); 24038e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim i2c_set_clientdata(client, data); 24138e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim 24238e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim return 0; 24338e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim 24438e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shimerr_free_irq: 24538e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim free_irq(client->irq, data); 24638e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shimerr_free_mem: 24738e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim input_free_device(input_dev); 24838e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim kfree(data); 24938e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim return ret; 25038e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim} 25138e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim 25238e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shimstatic int __devexit mcs5000_ts_remove(struct i2c_client *client) 25338e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim{ 25438e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim struct mcs5000_ts_data *data = i2c_get_clientdata(client); 25538e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim 25638e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim free_irq(client->irq, data); 25738e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim input_unregister_device(data->input_dev); 25838e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim kfree(data); 25938e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim 26038e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim return 0; 26138e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim} 26238e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim 26338e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim#ifdef CONFIG_PM 26492b672e217ddf87e4181454f8200f0f06139cdbcMark Brownstatic int mcs5000_ts_suspend(struct device *dev) 26538e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim{ 26692b672e217ddf87e4181454f8200f0f06139cdbcMark Brown struct i2c_client *client = to_i2c_client(dev); 26792b672e217ddf87e4181454f8200f0f06139cdbcMark Brown 26838e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim /* Touch sleep mode */ 26938e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim i2c_smbus_write_byte_data(client, MCS5000_TS_OP_MODE, OP_MODE_SLEEP); 27038e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim 27138e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim return 0; 27238e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim} 27338e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim 27492b672e217ddf87e4181454f8200f0f06139cdbcMark Brownstatic int mcs5000_ts_resume(struct device *dev) 27538e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim{ 27692b672e217ddf87e4181454f8200f0f06139cdbcMark Brown struct i2c_client *client = to_i2c_client(dev); 27738e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim struct mcs5000_ts_data *data = i2c_get_clientdata(client); 27838e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim 27938e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim mcs5000_ts_phys_init(data); 28038e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim 28138e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim return 0; 28238e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim} 28392b672e217ddf87e4181454f8200f0f06139cdbcMark Brown 28492b672e217ddf87e4181454f8200f0f06139cdbcMark Brownstatic SIMPLE_DEV_PM_OPS(mcs5000_ts_pm, mcs5000_ts_suspend, mcs5000_ts_resume); 28538e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim#endif 28638e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim 28738e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shimstatic const struct i2c_device_id mcs5000_ts_id[] = { 28838e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim { "mcs5000_ts", 0 }, 28938e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim { } 29038e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim}; 29138e783b38148531c0840ac130b97eb8158f84b48Joonyoung ShimMODULE_DEVICE_TABLE(i2c, mcs5000_ts_id); 29238e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim 29338e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shimstatic struct i2c_driver mcs5000_ts_driver = { 29438e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim .probe = mcs5000_ts_probe, 29538e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim .remove = __devexit_p(mcs5000_ts_remove), 29638e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim .driver = { 29738e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim .name = "mcs5000_ts", 29892b672e217ddf87e4181454f8200f0f06139cdbcMark Brown#ifdef CONFIG_PM 29992b672e217ddf87e4181454f8200f0f06139cdbcMark Brown .pm = &mcs5000_ts_pm, 30092b672e217ddf87e4181454f8200f0f06139cdbcMark Brown#endif 30138e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim }, 30238e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim .id_table = mcs5000_ts_id, 30338e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim}; 30438e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim 3051b92c1cf6b638e7cbe9fdaac3f6efb8874f5cc02Axel Linmodule_i2c_driver(mcs5000_ts_driver); 30638e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim 30738e783b38148531c0840ac130b97eb8158f84b48Joonyoung Shim/* Module information */ 30838e783b38148531c0840ac130b97eb8158f84b48Joonyoung ShimMODULE_AUTHOR("Joonyoung Shim <jy0922.shim@samsung.com>"); 30938e783b38148531c0840ac130b97eb8158f84b48Joonyoung ShimMODULE_DESCRIPTION("Touchscreen driver for MELFAS MCS-5000 controller"); 31038e783b38148531c0840ac130b97eb8158f84b48Joonyoung ShimMODULE_LICENSE("GPL"); 311