/* * Synaptics DSX touchscreen driver * * Copyright (C) 2012 Synaptics Incorporated * * Copyright (C) 2012 Alexandra Chin * Copyright (C) 2012 Scott Lin * Copyright (C) 2010 Js HA * Copyright (C) 2010 Naveen Kumar G * * 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 _SYNAPTICS_DSX_RMI4_H_ #define _SYNAPTICS_DSX_RMI4_H_ #define SYNAPTICS_RMI4_DRIVER_VERSION "1.0" #define PROXIMITY 0 #define PDT_PROPS (0X00EF) #define PDT_START (0x00E9) #define PDT_END (0x000A) #define PDT_ENTRY_SIZE (0x0006) #define PAGES_TO_SERVICE (10) #define PAGE_SELECT_LEN (2) #define SYNAPTICS_RMI4_F01 (0x01) #define SYNAPTICS_RMI4_F11 (0x11) #define SYNAPTICS_RMI4_F12 (0x12) #define SYNAPTICS_RMI4_F1A (0x1a) #define SYNAPTICS_RMI4_F34 (0x34) #define SYNAPTICS_RMI4_F51 (0x51) #define SYNAPTICS_RMI4_F54 (0x54) #define SYNAPTICS_RMI4_PRODUCT_INFO_SIZE 2 #define SYNAPTICS_RMI4_PRODUCT_ID_LENGTH 10 #define MAX_NUMBER_OF_FINGERS 10 #define MAX_NUMBER_OF_BUTTONS 4 #define MAX_INTR_REGISTERS 4 #define MASK_16BIT 0xFFFF #define MASK_8BIT 0xFF #define MASK_7BIT 0x7F #define MASK_6BIT 0x3F #define MASK_5BIT 0x1F #define MASK_4BIT 0x0F #define MASK_3BIT 0x07 #define MASK_2BIT 0x03 #define MASK_1BIT 0x01 #define NO_0D_WHILE_2D 1 #define RPT_OBJ_TYPE (1 << 0) #define RPT_X_LSB (1 << 1) #define RPT_X_MSB (1 << 2) #define RPT_Y_LSB (1 << 3) #define RPT_Y_MSB (1 << 4) #define RPT_Z (1 << 5) #define RPT_WX (1 << 6) #define RPT_WY (1 << 7) #define F12_RPT_DEFAULT (RPT_OBJ_TYPE | RPT_X_LSB | RPT_Y_LSB | RPT_Y_MSB) #define F12_RPT (F12_RPT_DEFAULT | RPT_WX | RPT_WY) #if PROXIMITY #define HOVER_Z_MAX 255 #define FINGER_HOVER (1 << 0) #define AIR_SWIPE (1 << 1) #define LARGE_OBJ (1 << 2) #define HOVER_PINCH (1 << 3) #define NO_PROXIMITY_ON_TOUCH (1 << 5) #define PROXIMITY_ENABLE (FINGER_HOVER | NO_PROXIMITY_ON_TOUCH) #endif #define EXP_FN_DET_INTERVAL 1000 /* ms */ #define POLLING_PERIOD 1 /* ms */ #define SYN_I2C_RETRY_TIMES 10 #define MAX_TOUCH_MAJOR 15 #define F01_STD_QUERY_LEN 21 #define F11_STD_QUERY_LEN 9 #define F11_STD_CTRL_LEN 10 #define F11_STD_DATA_LEN 12 #define NORMAL_OPERATION (0 << 0) #define SENSOR_SLEEP (1 << 0) #define NO_SLEEP_OFF (0 << 3) #define NO_SLEEP_ON (1 << 3) enum exp_fn { RMI_DEV = 0, RMI_F34, RMI_F54, RMI_FW_UPDATER, RMI_LAST, }; struct synaptics_rmi4_f12_query_5 { union { struct { unsigned char size_of_query6; struct { unsigned char ctrl0_is_present:1; unsigned char ctrl1_is_present:1; unsigned char ctrl2_is_present:1; unsigned char ctrl3_is_present:1; unsigned char ctrl4_is_present:1; unsigned char ctrl5_is_present:1; unsigned char ctrl6_is_present:1; unsigned char ctrl7_is_present:1; } __packed; struct { unsigned char ctrl8_is_present:1; unsigned char ctrl9_is_present:1; unsigned char ctrl10_is_present:1; unsigned char ctrl11_is_present:1; unsigned char ctrl12_is_present:1; unsigned char ctrl13_is_present:1; unsigned char ctrl14_is_present:1; unsigned char ctrl15_is_present:1; } __packed; struct { unsigned char ctrl16_is_present:1; unsigned char ctrl17_is_present:1; unsigned char ctrl18_is_present:1; unsigned char ctrl19_is_present:1; unsigned char ctrl20_is_present:1; unsigned char ctrl21_is_present:1; unsigned char ctrl22_is_present:1; unsigned char ctrl23_is_present:1; } __packed; }; unsigned char data[4]; }; }; struct synaptics_rmi4_f12_query_8 { union { struct { unsigned char size_of_query9; struct { unsigned char data0_is_present:1; unsigned char data1_is_present:1; unsigned char data2_is_present:1; unsigned char data3_is_present:1; unsigned char data4_is_present:1; unsigned char data5_is_present:1; unsigned char data6_is_present:1; unsigned char data7_is_present:1; } __packed; }; unsigned char data[2]; }; }; struct synaptics_rmi4_f12_ctrl_8 { union { struct { unsigned char max_x_coord_lsb; unsigned char max_x_coord_msb; unsigned char max_y_coord_lsb; unsigned char max_y_coord_msb; unsigned char rx_pitch_lsb; unsigned char rx_pitch_msb; unsigned char tx_pitch_lsb; unsigned char tx_pitch_msb; unsigned char low_rx_clip; unsigned char high_rx_clip; unsigned char low_tx_clip; unsigned char high_tx_clip; unsigned char num_of_rx; unsigned char num_of_tx; }; unsigned char data[14]; }; }; struct synaptics_rmi4_f12_ctrl_23 { union { struct { unsigned char obj_type_enable; unsigned char max_reported_objects; }; unsigned char data[2]; }; }; struct synaptics_rmi4_f12_finger_data { union { struct { unsigned char object_type_and_status; unsigned char x_lsb; unsigned char x_msb; unsigned char y_lsb; unsigned char y_msb; unsigned char z; unsigned char wx; unsigned char wy; }; unsigned char data[8]; }; }; struct synaptics_rmi4_f1a_query { union { struct { unsigned char max_button_count:3; unsigned char reserved:5; unsigned char has_general_control:1; unsigned char has_interrupt_enable:1; unsigned char has_multibutton_select:1; unsigned char has_tx_rx_map:1; unsigned char has_perbutton_threshold:1; unsigned char has_release_threshold:1; unsigned char has_strongestbtn_hysteresis:1; unsigned char has_filter_strength:1; } __packed; unsigned char data[2]; }; }; struct synaptics_rmi4_f1a_control_0 { union { struct { unsigned char multibutton_report:2; unsigned char filter_mode:2; unsigned char reserved:4; } __packed; unsigned char data[1]; }; }; struct synaptics_rmi4_f1a_control_3_4 { unsigned char transmitterbutton; unsigned char receiverbutton; }; struct synaptics_rmi4_f1a_control { struct synaptics_rmi4_f1a_control_0 general_control; unsigned char *button_int_enable; unsigned char *multi_button; struct synaptics_rmi4_f1a_control_3_4 *electrode_map; unsigned char *button_threshold; unsigned char button_release_threshold; unsigned char strongest_button_hysteresis; unsigned char filter_strength; }; struct synaptics_rmi4_f1a_handle { int button_bitmask_size; unsigned char button_count; unsigned char valid_button_count; unsigned char *button_data_buffer; unsigned char *button_map; struct synaptics_rmi4_f1a_query button_query; struct synaptics_rmi4_f1a_control button_control; }; #if PROXIMITY struct synaptics_rmi4_f51_query { union { struct { unsigned char query_register_count; unsigned char data_register_count; unsigned char control_register_count; unsigned char command_register_count; }; unsigned char data[4]; }; }; struct synaptics_rmi4_f51_data { union { struct { unsigned char finger_hover_det:1; unsigned char air_swipe_det:1; unsigned char large_obj_det:1; unsigned char f1a_data0_b3:1; unsigned char hover_pinch_det:1; unsigned char f1a_data0_b5__7:3; unsigned char hover_finger_x_4__11; unsigned char hover_finger_y_4__11; unsigned char hover_finger_xy_0__3; unsigned char hover_finger_z; unsigned char f1a_data2_b0__6:7; unsigned char hover_pinch_dir:1; unsigned char air_swipe_dir_0:1; unsigned char air_swipe_dir_1:1; unsigned char f1a_data3_b2__5:4; unsigned char large_obj_act:2; } __packed; unsigned char data[7]; }; }; struct synaptics_rmi4_f51_handle { unsigned short proximity_enables_addr; struct synaptics_rmi4_data *rmi4_data; }; #endif struct synaptics_rmi4_exp_fn { enum exp_fn fn_type; bool inserted; int (*func_init)(struct i2c_client *client); void (*func_remove)(struct i2c_client *client); void (*func_attn)(struct i2c_client *client, unsigned char intr_mask); struct list_head link; }; /* * struct synaptics_rmi4_fn_desc - function descriptor fields in PDT * @query_base_addr: base address for query registers * @cmd_base_addr: base address for command registers * @ctrl_base_addr: base address for control registers * @data_base_addr: base address for data registers * @intr_src_count: number of interrupt sources * @fn_number: function number */ 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; }; /* * synaptics_rmi4_fn_full_addr - full 16-bit base addresses * @query_base: 16-bit base address for query registers * @cmd_base: 16-bit base address for data registers * @ctrl_base: 16-bit base address for command registers * @data_base: 16-bit base address for control registers */ struct synaptics_rmi4_fn_full_addr { unsigned short query_base; unsigned short cmd_base; unsigned short ctrl_base; unsigned short data_base; }; /* * struct synaptics_rmi4_fn - function handler data structure * @fn_number: function number * @num_of_data_sources: number of data sources * @num_of_data_points: maximum number of fingers supported * @size_of_data_register_block: data register block size * @data1_offset: offset to data1 register from data base address * @intr_reg_num: index to associated interrupt register * @intr_mask: interrupt mask * @full_addr: full 16-bit base addresses of function registers * @link: linked list for function handlers * @data_size: size of private data * @data: pointer to private data */ 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 data1_offset; unsigned char intr_reg_num; unsigned char intr_mask; struct synaptics_rmi4_fn_full_addr full_addr; struct list_head link; int data_size; void *data; }; /* * struct synaptics_rmi4_device_info - device information * @version_major: rmi protocol major version number * @version_minor: rmi protocol minor version number * @manufacturer_id: manufacturer id * @product_props: product properties information * @product_info: product info array * @date_code: device manufacture date * @tester_id: tester id array * @serial_number: device serial number * @product_id_string: device product id * @support_fn_list: linked list for function handlers */ 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_f01_device_status { union { struct { unsigned char status_code:4; unsigned char reserved:2; unsigned char flash_prog:1; unsigned char unconfigured:1; } __packed; unsigned char data[1]; }; }; /* * struct synaptics_rmi4_data - rmi4 device instance data * @i2c_client: pointer to associated i2c client * @input_dev: pointer to associated input device * @board: constant pointer to platform data * @rmi4_mod_info: device information * @regulator: pointer to associated regulator * @rmi4_io_ctrl_mutex: mutex for i2c i/o control * @det_work: work thread instance for expansion function detection * @det_workqueue: pointer to work queue for work thread instance * @early_suspend: instance to support early suspend power management * @current_page: current page in sensor to acess * @button_0d_enabled: flag for 0d button support * @full_pm_cycle: flag for full power management cycle in early suspend stage * @num_of_intr_regs: number of interrupt registers * @f01_query_base_addr: query base address for f01 * @f01_cmd_base_addr: command base address for f01 * @f01_ctrl_base_addr: control base address for f01 * @f01_data_base_addr: data base address for f01 * @irq: attention interrupt * @sensor_max_x: sensor maximum x value * @sensor_max_y: sensor maximum y value * @irq_enabled: flag for indicating interrupt enable status * @touch_stopped: flag to stop interrupt thread processing * @fingers_on_2d: flag to indicate presence of fingers in 2d area * @sensor_sleep: flag to indicate sleep state of sensor * @wait: wait queue for touch data polling in interrupt thread * @i2c_read: pointer to i2c read function * @i2c_write: pointer to i2c write function * @irq_enable: pointer to irq enable function */ struct synaptics_rmi4_data { struct i2c_client *i2c_client; struct input_dev *input_dev; const struct synaptics_dsx_platform_data *board; struct synaptics_rmi4_device_info rmi4_mod_info; struct regulator *regulator; struct mutex rmi4_io_ctrl_mutex; // struct delayed_work det_work; struct work_struct work; struct workqueue_struct *det_workqueue; struct workqueue_struct *workqueue; //struct early_suspend early_suspend; unsigned char current_page; unsigned char button_0d_enabled; unsigned char full_pm_cycle; unsigned char num_of_rx; unsigned char num_of_tx; unsigned char intr_mask[MAX_INTR_REGISTERS]; unsigned short num_of_intr_regs; unsigned short f01_query_base_addr; unsigned short f01_cmd_base_addr; unsigned short f01_ctrl_base_addr; unsigned short f01_data_base_addr; int irq; int sensor_max_x; int sensor_max_y; bool irq_enabled; bool touch_stopped; bool fingers_on_2d; bool sensor_sleep; wait_queue_head_t wait; int (*i2c_read)(struct synaptics_rmi4_data *pdata, unsigned short addr, unsigned char *data, unsigned short length); int (*i2c_write)(struct synaptics_rmi4_data *pdata, unsigned short addr, unsigned char *data, unsigned short length); int (*irq_enable)(struct synaptics_rmi4_data *rmi4_data, bool enable); int (*reset_device)(struct synaptics_rmi4_data *rmi4_data); }; struct synaptics_rmi4_exp_fn_ptr { int (*read)(struct synaptics_rmi4_data *rmi4_data, unsigned short addr, unsigned char *data, unsigned short length); int (*write)(struct synaptics_rmi4_data *rmi4_data, unsigned short addr, unsigned char *data, unsigned short length); int (*enable)(struct synaptics_rmi4_data *rmi4_data, bool enable); }; void synaptics_rmi4_new_function(enum exp_fn fn_type, bool insert, int (*func_init)(struct i2c_client *client), void (*func_remove)(struct i2c_client *client), void (*func_attn)(struct i2c_client *client, unsigned char intr_mask)); static inline ssize_t synaptics_rmi4_show_error(struct device *dev, struct device_attribute *attr, char *buf) { #if 0 dev_warn(dev, "%s Attempted to read from write-only attribute %s\n", __func__, attr->attr.name); #endif return -EPERM; } static inline ssize_t synaptics_rmi4_store_error(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { #if 0 dev_warn(dev, "%s Attempted to write to read-only attribute %s\n", __func__, attr->attr.name); #endif return -EPERM; } static inline void batohs(unsigned short *dest, unsigned char *src) { *dest = src[1] * 0x100 + src[0]; } static inline void hstoba(unsigned char *dest, unsigned short src) { dest[0] = src % 0x100; dest[1] = src / 0x100; } #endif