input: touchscreen: synaptics_3200: Add Synaptics 3200 driver

HTC kernel version: evitaul-jb-crc-3.4.10-ec474a3

Change-Id: I4acac53e40e4b47f249f631e7b92d9dfe7cb9e79
diff --git a/include/linux/rmi.h b/include/linux/rmi.h
new file mode 100644
index 0000000..b84b10f
--- /dev/null
+++ b/include/linux/rmi.h
@@ -0,0 +1,424 @@
+/*
+ * Copyright (c) 2011 Synaptics Incorporated
+ * Copyright (c) 2011 Unixphere
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef _RMI_H
+#define _RMI_H
+#include <linux/kernel.h>
+#include <linux/lockdep.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/device.h>
+#include <linux/cdev.h>
+#include <linux/mutex.h>
+#include <linux/stat.h>
+#include <linux/wait.h>
+#include <linux/list.h>
+#include <linux/interrupt.h>
+
+#ifdef CONFIG_HAS_EARLYSUSPEND
+#include <linux/earlysuspend.h>
+#endif
+
+
+#define RMI_RO_ATTR S_IRUGO
+#define RMI_RW_ATTR (S_IRUGO | S_IWUGO)
+#define RMI_WO_ATTR S_IWUGO
+
+#define PDT_START_SCAN_LOCATION 0x00e9
+
+enum rmi_irq_polarity {
+	RMI_IRQ_ACTIVE_LOW = 0,
+	RMI_IRQ_ACTIVE_HIGH = 1
+};
+
+struct rmi_f11_2d_axis_alignment {
+	bool swap_axes;
+	bool flip_x;
+	bool flip_y;
+	int clip_X_low;
+	int clip_Y_low;
+	int clip_X_high;
+	int clip_Y_high;
+	int offset_X;
+	int offset_Y;
+	int rel_report_enabled;
+};
+
+union rmi_f11_2d_ctrl0 {
+	struct {
+		u8 reporting_mode:3;
+		u8 abs_pos_filt:1;
+		u8 rel_pos_filt:1;
+		u8 rel_ballistics:1;
+		u8 dribble:1;
+		u8 report_beyond_clip:1;
+	};
+	u8 reg;
+};
+
+union rmi_f11_2d_ctrl1 {
+	struct {
+		u8 palm_detect_thres:4;
+		u8 motion_sensitivity:2;
+		u8 man_track_en:1;
+		u8 man_tracked_finger:1;
+	};
+	u8 reg;
+};
+
+union rmi_f11_2d_ctrl2__3 {
+	struct {
+		u8 delta_x_threshold:8;
+		u8 delta_y_threshold:8;
+	};
+	u8 regs[2];
+};
+
+union rmi_f11_2d_ctrl4 {
+	struct {
+		u8 velocity:8;
+	};
+	u8 reg;
+};
+
+union rmi_f11_2d_ctrl5 {
+	struct {
+		u8 acceleration:8;
+	};
+	u8 reg;
+};
+
+union rmi_f11_2d_ctrl6__7 {
+	struct {
+		u16 sensor_max_x_pos:12;
+	};
+	u8 regs[2];
+};
+
+union rmi_f11_2d_ctrl8__9 {
+	struct {
+		u16 sensor_max_y_pos:12;
+	};
+	u8 regs[2];
+};
+
+union rmi_f11_2d_ctrl10 {
+	struct {
+		u8 single_tap_int_enable:1;
+		u8 tap_n_hold_int_enable:1;
+		u8 double_tap_int_enable:1;
+		u8 early_tap_int_enable:1;
+		u8 flick_int_enable:1;
+		u8 press_int_enable:1;
+		u8 pinch_int_enable:1;
+	};
+	u8 reg;
+};
+
+union rmi_f11_2d_ctrl11 {
+	struct {
+		u8 palm_detect_int_enable:1;
+		u8 rotate_int_enable:1;
+		u8 touch_shape_int_enable:1;
+		u8 scroll_zone_int_enable:1;
+		u8 multi_finger_scroll_int_enable:1;
+	};
+	u8 reg;
+};
+
+union rmi_f11_2d_ctrl12 {
+	struct {
+		u8 sensor_map:7;
+		u8 xy_sel:1;
+	};
+	u8 reg;
+};
+
+union rmi_f11_2d_ctrl14 {
+	struct {
+		u8 sens_adjustment:5;
+		u8 hyst_adjustment:3;
+	};
+	u8 reg;
+};
+
+struct  rmi_f11_2d_ctrl {
+	union rmi_f11_2d_ctrl0		*ctrl0;
+	union rmi_f11_2d_ctrl1		*ctrl1;
+	union rmi_f11_2d_ctrl2__3	*ctrl2__3;
+	union rmi_f11_2d_ctrl4		*ctrl4;
+	union rmi_f11_2d_ctrl5		*ctrl5;
+	union rmi_f11_2d_ctrl6__7	*ctrl6__7;
+	union rmi_f11_2d_ctrl8__9	*ctrl8__9;
+	union rmi_f11_2d_ctrl10		*ctrl10;
+	union rmi_f11_2d_ctrl11		*ctrl11;
+	union rmi_f11_2d_ctrl12		*ctrl12;
+	u8				ctrl12_size;
+	union rmi_f11_2d_ctrl14		*ctrl14;
+	u8				*ctrl15;
+	u8				*ctrl16;
+	u8				*ctrl17;
+	u8				*ctrl18;
+	u8				*ctrl19;
+};
+
+struct rmi_f19_button_map {
+	unsigned char nbuttons;
+	unsigned char *map;
+};
+
+struct rmi_device_platform_data_spi {
+	int block_delay_us;
+	int split_read_block_delay_us;
+	int byte_delay_us;
+	int split_read_byte_delay_us;
+	int pre_delay_us;
+	int post_delay_us;
+
+	void *cs_assert_data;
+	int (*cs_assert) (const void *cs_assert_data, const bool assert);
+};
+
+struct rmi_device_platform_data {
+	char *driver_name;
+
+	int irq_no;
+	int irq;
+	enum rmi_irq_polarity irq_polarity;
+	int (*gpio_config)(void);
+
+	struct rmi_device_platform_data_spi spi_v2;
+
+	
+	struct rmi_f11_2d_ctrl *f11_ctrl;
+	struct rmi_f11_2d_axis_alignment axis_align;
+	struct rmi_f19_button_map *button_map;
+
+#ifdef	CONFIG_PM
+	void *pm_data;
+	int (*pre_suspend) (const void *pm_data);
+	int (*post_resume) (const void *pm_data);
+#endif
+};
+
+struct rmi_function_descriptor {
+	u16 query_base_addr;
+	u16 command_base_addr;
+	u16 control_base_addr;
+	u16 data_base_addr;
+	u8 interrupt_source_count;
+	u8 function_number;
+	u8 function_version;
+};
+
+struct rmi_function_container;
+struct rmi_device;
+
+struct rmi_function_handler {
+	int func;
+	int (*init)(struct rmi_function_container *fc);
+	int (*attention)(struct rmi_function_container *fc, u8 *irq_bits);
+#ifdef CONFIG_PM
+	int (*suspend)(struct rmi_function_container *fc);
+	int (*resume)(struct rmi_function_container *fc);
+#endif
+	void (*remove)(struct rmi_function_container *fc);
+};
+
+struct rmi_function_device {
+	struct device dev;
+};
+
+struct rmi_function_container {
+	struct list_head list;
+
+	struct rmi_function_descriptor fd;
+	struct rmi_device *rmi_dev;
+	struct rmi_function_handler *fh;
+	struct device dev;
+
+	int num_of_irqs;
+	int irq_pos;
+	u8 *irq_mask;
+
+	void *data;
+};
+#define to_rmi_function_container(d) \
+		container_of(d, struct rmi_function_container, dev);
+#define to_rmi_function_device(d) \
+		container_of(d, struct rmi_function_device, dev);
+
+
+
+#define RMI_CHAR_DEV_TMPBUF_SZ 128
+#define RMI_REG_ADDR_PAGE_SELECT 0xFF
+
+struct rmi_char_dev {
+	
+	struct mutex mutex_file_op;
+	
+	struct cdev main_dev;
+
+	
+	
+
+	
+	
+	struct rmi_phys_device *phys;
+	
+	int ref_count;
+};
+
+int rmi_char_dev_register(void);
+void rmi_char_dev_unregister(struct rmi_phys_device *phys);
+
+
+
+
+struct rmi_driver {
+	struct device_driver driver;
+
+	int (*probe)(struct rmi_device *rmi_dev);
+	int (*remove)(struct rmi_device *rmi_dev);
+	void (*shutdown)(struct rmi_device *rmi_dev);
+	int (*irq_handler)(struct rmi_device *rmi_dev, int irq);
+	void (*fh_add)(struct rmi_device *rmi_dev,
+		       struct rmi_function_handler *fh);
+	void (*fh_remove)(struct rmi_device *rmi_dev,
+			  struct rmi_function_handler *fh);
+	u8* (*get_func_irq_mask)(struct rmi_device *rmi_dev,
+			    struct rmi_function_container *fc);
+	int (*store_irq_mask)(struct rmi_device *rmi_dev, u8* new_interupts);
+	int (*restore_irq_mask)(struct rmi_device *rmi_dev);
+	void *data;
+};
+#define to_rmi_driver(d) \
+	container_of(d, struct rmi_driver, driver);
+
+struct rmi_phys_info {
+	char *proto;
+	long tx_count;
+	long tx_bytes;
+	long tx_errs;
+	long rx_count;
+	long rx_bytes;
+	long rx_errs;
+	long attn_count;
+	long attn;
+};
+
+struct rmi_phys_device {
+	struct device *dev;
+	struct rmi_device *rmi_dev;
+
+	int (*write)(struct rmi_phys_device *phys, u16 addr, u8 data);
+	int (*write_block)(struct rmi_phys_device *phys, u16 addr, u8 *buf,
+			   int len);
+	int (*read)(struct rmi_phys_device *phys, u16 addr, u8 *buf);
+	int (*read_block)(struct rmi_phys_device *phys, u16 addr, u8 *buf,
+			  int len);
+
+	int (*enable_device) (struct rmi_phys_device *phys);
+	void (*disable_device) (struct rmi_phys_device *phys);
+
+	void *data;
+
+	struct rmi_phys_info info;
+
+	
+	struct rmi_char_dev *char_dev;
+	struct class *rmi_char_device_class;
+};
+
+struct rmi_device {
+	struct device dev;
+
+	struct rmi_driver *driver;
+	struct rmi_phys_device *phys;
+
+#ifdef CONFIG_HAS_EARLYSUSPEND
+	struct early_suspend early_suspend_handler;
+#endif
+};
+#define to_rmi_device(d) container_of(d, struct rmi_device, dev);
+#define to_rmi_platform_data(d) ((d)->phys->dev->platform_data);
+
+int i2c_rmi_read(uint16_t addr, uint8_t *data, uint16_t length);
+int i2c_rmi_write(uint16_t addr, uint8_t *data, uint16_t length);
+
+static inline void rmi_set_driverdata(struct rmi_device *d, void *data)
+{
+	dev_set_drvdata(&d->dev, data);
+}
+
+static inline void *rmi_get_driverdata(struct rmi_device *d)
+{
+	return dev_get_drvdata(&d->dev);
+}
+
+static inline int rmi_read(struct rmi_device *d, u16 addr, u8 *buf)
+{
+	return d->phys->read(d->phys, addr, buf);
+}
+
+static inline int rmi_read_block(struct rmi_device *d, u16 addr, u8 *buf,
+				 int len)
+{
+	return d->phys->read_block(d->phys, addr, buf, len);
+}
+
+static inline int rmi_write(struct rmi_device *d, u16 addr, u8 data)
+{
+	return d->phys->write(d->phys, addr, data);
+}
+
+static inline int rmi_write_block(struct rmi_device *d, u16 addr, u8 *buf,
+				  int len)
+{
+	return d->phys->write_block(d->phys, addr, buf, len);
+}
+
+int rmi_register_driver(struct rmi_driver *driver);
+
+void rmi_unregister_driver(struct rmi_driver *driver);
+
+int rmi_register_phys_device(struct rmi_phys_device *phys);
+
+void rmi_unregister_phys_device(struct rmi_phys_device *phys);
+
+int rmi_register_function_driver(struct rmi_function_handler *fh);
+
+void rmi_unregister_function_driver(struct rmi_function_handler *fh);
+
+struct rmi_function_handler *rmi_get_function_handler(int id);
+
+ssize_t rmi_store_error(struct device *dev,
+			struct device_attribute *attr,
+			const char *buf, size_t count);
+
+ssize_t rmi_show_error(struct device *dev,
+		       struct device_attribute *attr,
+		       char *buf);
+
+void u8_set_bit(u8 *target, int pos);
+void u8_clear_bit(u8 *target, int pos);
+bool u8_is_set(u8 *target, int pos);
+bool u8_is_any_set(u8 *target, int size);
+void u8_or(u8 *dest, u8* target1, u8* target2, int size);
+void u8_and(u8 *dest, u8* target1, u8* target2, int size);
+#endif
diff --git a/include/linux/synaptics_i2c_rmi.h b/include/linux/synaptics_i2c_rmi.h
index 5539cc5..e66d982 100644
--- a/include/linux/synaptics_i2c_rmi.h
+++ b/include/linux/synaptics_i2c_rmi.h
@@ -18,6 +18,38 @@
 #define _LINUX_SYNAPTICS_I2C_RMI_H
 
 #define SYNAPTICS_I2C_RMI_NAME "synaptics-rmi-ts"
+#define SYNAPTICS_T1007_NAME "synaptics-t1007"
+#define SYNAPTICS_T1021_NAME "synaptics-t1021"
+#define SYNAPTICS_3K_NAME "synaptics-3k"
+#define SYNAPTICS_3K_INCELL_NAME "synaptics-3k-incell"
+#define SYNAPTICS_3200_NAME "synaptics-3200"
+#define SYNAPTICS_FW_3_2_PACKRAT 1115999
+#define SYNAPTICS_FW_NOCAL_PACKRAT 1293981
+
+
+#define SYN_CONFIG_SIZE 32 * 16
+#define SYN_MAX_PAGE 4
+#define SYN_BL_PAGE 1
+#define SYN_F01DATA_BASEADDR 0x0013
+#define SYN_PROCESS_ERR -1
+
+#define SYN_AND_REPORT_TYPE_A		0
+#define	SYN_AND_REPORT_TYPE_B		1
+#define SYN_AND_REPORT_TYPE_HTC		2
+
+#define TAP_DX_OUTER		0
+#define TAP_DY_OUTER		1
+#define TAP_TIMEOUT		2
+#define TAP_DX_INTER		3
+#define TAP_DY_INTER		4
+
+#define CUS_REG_SIZE		4
+#define CUS_REG_BASE		0
+#define CUS_BALLISTICS_CTRL	1
+#define CUS_LAND_CTRL		2
+#define CUS_LIFT_CTRL		3
+
+#define SENSOR_ID_CHECKING_EN	1 << 16
 
 enum {
 	SYNAPTICS_FLIP_X = 1UL << 0,
@@ -26,11 +58,37 @@
 	SYNAPTICS_SNAP_TO_INACTIVE_EDGE = 1UL << 3,
 };
 
+enum {
+	FINGER_1_REPORT = 1 << 0,
+	FINGER_2_REPORT = 1 << 1,
+};
+
+#ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_3K
+struct synaptics_virtual_key {
+	int index;
+	int keycode;
+	int x_range_min;
+	int x_range_max;
+	int y_range_min;
+	int y_range_max;
+};
+#endif
+
 struct synaptics_i2c_rmi_platform_data {
 	uint32_t version;	/* Use this entry for panels with */
 				/* (major << 8 | minor) version or above. */
 				/* If non-zero another array entry follows */
 	int (*power)(int on);	/* Only valid in first array entry */
+#ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_3K
+	struct synaptics_virtual_key *virtual_key;
+	uint8_t virtual_key_num;
+	struct kobject *vk_obj;
+	struct kobj_attribute *vk2Use;
+	uint8_t sensitivity;
+	uint8_t finger_support;
+	uint32_t gap_area;
+	uint32_t key_area;
+#endif
 	uint32_t flags;
 	unsigned long irqflags;
 	uint32_t inactive_left; /* 0x10000 = screen width */
@@ -47,9 +105,80 @@
 	uint32_t snap_bottom_off; /* 0x10000 = screen height */
 	uint32_t fuzz_x; /* 0x10000 = screen width */
 	uint32_t fuzz_y; /* 0x10000 = screen height */
+#ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_3K
+	int abs_x_min;
+	int abs_x_max;
+	int abs_y_min;
+	int abs_y_max;
+#endif
 	int fuzz_p;
 	int fuzz_w;
+#ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_3K
+	uint32_t display_width;
+	uint32_t display_height;
+#endif
 	int8_t sensitivity_adjust;
+#ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_3K
+	uint32_t dup_threshold;
+	uint32_t margin_inactive_pixel[4];
+	uint16_t filter_level[4];
+	uint8_t reduce_report_level[5];
+	uint8_t noise_information;
+	uint8_t jumpfq_enable;
+	uint8_t cable_support;
+	uint8_t config[SYN_CONFIG_SIZE];
+	int gpio_irq;
+	int gpio_reset;
+	uint8_t default_config;
+	uint8_t report_type;
+	uint8_t large_obj_check;
+	uint16_t tw_pin_mask;
+	uint32_t sensor_id;
+	uint32_t packrat_number;
+	uint8_t support_htc_event;
+	uint8_t mfg_flag;
+	uint8_t customer_register[CUS_REG_SIZE];
+	uint8_t segmentation_bef_unlock;
+	uint8_t threshold_bef_unlock;
+	uint16_t saturation_bef_unlock;
+	uint8_t i2c_err_handler_en;
+	uint8_t energy_ratio_relaxation;
+	uint8_t multitouch_calibration;
+	uint8_t psensor_detection;
+	uint8_t PixelTouchThreshold_bef_unlock;
+#endif
 };
 
+#ifdef CONFIG_TOUCHSCREEN_SYNAPTICS_3K
+struct page_description {
+	uint8_t addr;
+	uint8_t value;
+};
+
+struct syn_finger_data {
+	int x;
+	int y;
+	int w;
+	int z;
+};
+
+struct function_t {
+	uint8_t function_type;
+	uint8_t interrupt_source;
+	uint16_t data_base;
+	uint16_t control_base;
+	uint16_t command_base;
+	uint16_t query_base;
+};
+enum {
+	QUERY_BASE,
+	COMMAND_BASE,
+	CONTROL_BASE,
+	DATA_BASE,
+	INTR_SOURCE,
+	FUNCTION
+};
+
+extern uint8_t getPowerKeyState(void);
+#endif /* CONFIG_TOUCHSCREEN_SYNAPTICS_3K */
 #endif /* _LINUX_SYNAPTICS_I2C_RMI_H */