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 */