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