/**
*
* Synaptics Register Mapped Interface (RMI4) I2C Physical Layer Driver.
* Copyright (c) 2007-2010, Synaptics Incorporated
*
* Author: Js HA <js.ha@stericsson.com> for ST-Ericsson
* Author: Naveen Kumar G <naveen.gaddipati@stericsson.com> for ST-Ericsson
* Copyright 2010 (c) ST-Ericsson AB
*/
/*
* This file is licensed under the GPL2 license.
*
*#############################################################################
* GPL
*
* 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.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
*#############################################################################
*/
#include <linux/input.h>
#include <linux/slab.h>
#include <linux/i2c.h>
#include <linux/interrupt.h>
#include <linux/regulator/consumer.h>
#include <linux/module.h>
#include <linux/input/mt.h>
#include "synaptics_i2c_rmi4.h"
/* TODO: for multiple device support will need a per-device mutex */
#define DRIVER_NAME "synaptics_rmi4_i2c"
#define MAX_ERROR_REPORT 6
#define MAX_TOUCH_MAJOR 15
#define MAX_RETRY_COUNT 5
#define STD_QUERY_LEN 21
#define PAGE_LEN 2
#define DATA_BUF_LEN 32
#define BUF_LEN 37
#define QUERY_LEN 9
#define DATA_LEN 12
#define HAS_TAP 0x01
#define HAS_PALMDETECT 0x01
#define HAS_ROTATE 0x02
#define HAS_TAPANDHOLD 0x02
#define HAS_DOUBLETAP 0x04
#define HAS_EARLYTAP 0x08
#define HAS_RELEASE 0x08
#define HAS_FLICK 0x10
#define HAS_PRESS 0x20
#define HAS_PINCH 0x40
#define MASK_16BIT 0xFFFF
#define MASK_8BIT 0xFF
#define MASK_7BIT 0x7F
#define MASK_5BIT 0x1F
#define MASK_4BIT 0x0F
#define MASK_3BIT 0x07
#define MASK_2BIT 0x03
#define TOUCHPAD_CTRL_INTR 0x8
#define PDT_START_SCAN_LOCATION (0x00E9)
#define PDT_END_SCAN_LOCATION (0x000A)
#define PDT_ENTRY_SIZE (0x0006)
#define SYNAPTICS_RMI4_TOUCHPAD_FUNC_NUM (0x11)
#define SYNAPTICS_RMI4_DEVICE_CONTROL_FUNC_NUM (0x01)
/**
* struct synaptics_rmi4_fn_desc - contains the function descriptor information
* @query_base_addr: base address for query
* @cmd_base_addr: base address for command
* @ctrl_base_addr: base address for control
* @data_base_addr: base address for data
* @intr_src_count: count for the interrupt source
* @fn_number: function number
*
* This structure is used to gives the function descriptor information
* of the particular functionality.
*/
struct synaptics_rmi4_fn_desc {
unsigned char query_base_addr;
unsigned char cmd_base_addr;
unsigned char ctrl_base_addr;
unsigned char data_base_addr;
unsigned char intr_src_count;
unsigned char fn_number;
};
/**
* struct synaptics_rmi4_fn - contains the function information
* @fn_number: function number
* @num_of_data_sources: number of data sources
* @num_of_data_points: number of fingers touched
* @size_of_data_register_block: data register block size
* @index_to_intr_reg: index for interrupt register
* @intr_mask: interrupt mask value
* @fn_desc: variable for function descriptor structure
* @link: linked list for function descriptors
*
* This structure gives information about the number of data sources and
* the number of data registers associated with the function.
*/
struct synaptics_rmi4_fn {
unsigned char fn_number;
unsigned char num_of_data_sources;
unsigned char num_of_data_points;
unsigned char size_of_data_register_block;
unsigned char index_to_intr_reg;
unsigned char intr_mask;
struct synaptics_rmi4_fn_desc fn_desc;
struct list_head link;
};
/**
* struct synaptics_rmi4_device_info - contains the rmi4 device information
* @version_major: protocol major version number
* @version_minor: protocol minor version number
* @manufacturer_id: manufacturer identification byte
* @product_props: product properties information
* @product_info: product info array
* @date_code: device manufacture date
* @tester_id: tester id array
* @serial_number: serial number for that device
* @product_id_string: product id for the device
* @support_fn_list: linked list for device information
*
* This structure gives information about the number of data sources and
* the number of data registers associated with the function.
*/
struct synaptics_rmi4_device_info {
unsigned int version_major;
unsigned int version_minor;
unsigned char manufacturer_id;
unsigned char product_props;
unsigned char product_info[2];
unsigned char date_code[3];
unsigned short tester_id;
unsigned short serial_number;
unsigned char product_id_string[11];
struct list_head support_fn_list;
};
/**
* struct synaptics_rmi4_data - contains the rmi4 device data
* @rmi4_mod_info: structure variable for rmi4 device info
* @input_dev: pointer for input device
* @i2c_client: pointer for i2c client
* @board: constant pointer for touch platform data
* @fn_list_mutex: mutex for function list
* @rmi4_page_mutex: mutex for rmi4 page
* @current_page: variable for integer
* @number_of_interrupt_register: interrupt registers count
* @fn01_ctrl_base_addr: control base address for fn01
* @fn01_query_base_addr: query base address for fn01
* @fn01_data_base_addr: data base address for fn01
* @sensor_max_x: sensor maximum x value
* @sensor_max_y: sensor maximum y value
* @regulator: pointer to the regulator structure
* @wait: wait queue structure variable
* @touch_stopped: flag to stop the thread function
* @fingers_supported: maximum supported fingers
*
* This structure gives the device data information.
*/
struct synaptics_rmi4_data {
struct synaptics_rmi4_device_info rmi4_mod_info;
struct input_dev *input_dev;
struct i2c_client *i2c_client;
const struct synaptics_rmi4_platform_data *board;
struct mutex fn_list_mutex;
struct mutex rmi4_page_mutex;
int current_page;
unsigned int number_of_interrupt_register;
unsigned short fn01_ctrl_base_addr;
unsigned short fn01_query_base_addr;
unsigned short fn01_data_base_addr;
int sensor_max_x;
int sensor_max_y;
struct regulator *regulator;
wait_queue_head_t wait;
bool touch_stopped;
unsigned char fingers_supported;
};
/**
* synaptics_rmi4_set_page() - sets the page
* @pdata: pointer to synaptics_rmi4_data structure
* @address: set the address of the page
*
* This function is used to set the page and returns integer.
*/
static int synaptics_rmi4_set_page(struct synaptics_rmi4_data *pdata,
unsigned int address)
{
unsigned char txbuf[PAGE_LEN];
int retval;
unsigned int page;
struct i2c_client *i2c = pdata->i2c_client;
page = ((address >> 8) & MASK_8BIT);
if (page != pdata->current_page) {
txbuf[0] = MASK_8BIT;
txbuf[1] = page;
retval = i2c_master_send(i2c, txbuf, PAGE_LEN);
if (retval != PAGE_LEN)
dev_err(&i2c->dev, "%s:failed:%d\n", __func__, retval);
else
pdata->current_page = page;
} else
retval = PAGE_LEN;
return retval;
}
/**
* synaptics_rmi4_i2c_block_read() - read the block of data
* @pdata: pointer to synaptics_rmi4_data structure
* @address: read the block of data from this offset
* @valp: pointer to a buffer containing the data to be read
* @size: number of bytes to read
*
* This function is to read the block of data and returns integer.
*/
static int synaptics_rmi4_i2c_block_read(struct synaptics_rmi4_data *pdata,
unsigned short address,
unsigned char *valp, int size)
{
int retval = 0;
int retry_count = 0;
int index;
struct i2c_client *i2c = pdata->i2c_client;
mutex_lock(&(pdata->rmi4_page_mutex));
retval = synaptics_rmi4_set_page(pdata, address);
if (retval != PAGE_LEN)
goto exit;
index = address & MASK_8BIT;
retry:
retval = i2c_smbus_read_i2c_block_data(i2c, index, size, valp);
if (retval != size) {
if (++retry_count == MAX_RETRY_COUNT)
dev_err(&i2c->dev,