293 lines
9.5 KiB
C
293 lines
9.5 KiB
C
|
/*
|
||
|
* Synaptics RMI4 touchscreen driver
|
||
|
*
|
||
|
* Copyright (C) 2012 Synaptics Incorporated
|
||
|
*
|
||
|
* Copyright (C) 2012 Alexandra Chin <alexandra.chin@tw.synaptics.com>
|
||
|
* Copyright (C) 2012 Scott Lin <scott.lin@tw.synaptics.com>
|
||
|
* Copyright (c) 2013, The Linux Foundation. All rights reserved.
|
||
|
*
|
||
|
* 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.
|
||
|
*/
|
||
|
|
||
|
#ifndef _SYNAPTICS_DSX_RMI4_H_
|
||
|
#define _SYNAPTICS_DSX_RMI4_H_
|
||
|
|
||
|
#define SYNAPTICS_DS4 (1 << 0)
|
||
|
#define SYNAPTICS_DS5 (1 << 1)
|
||
|
#define SYNAPTICS_DSX_DRIVER_PRODUCT SYNAPTICS_DS4
|
||
|
#define SYNAPTICS_DSX_DRIVER_VERSION 0x1005
|
||
|
|
||
|
#include <linux/version.h>
|
||
|
|
||
|
#ifdef CONFIG_FB
|
||
|
#include <linux/notifier.h>
|
||
|
#include <linux/fb.h>
|
||
|
#elif defined CONFIG_HAS_EARLYSUSPEND
|
||
|
#include <linux/earlysuspend.h>
|
||
|
#endif
|
||
|
|
||
|
#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_F1A (0x1a)
|
||
|
#define SYNAPTICS_RMI4_F34 (0x34)
|
||
|
#define SYNAPTICS_RMI4_F54 (0x54)
|
||
|
#define SYNAPTICS_RMI4_F55 (0x55)
|
||
|
|
||
|
#define SYNAPTICS_RMI4_PRODUCT_INFO_SIZE 2
|
||
|
#define SYNAPTICS_RMI4_DATE_CODE_SIZE 3
|
||
|
#define SYNAPTICS_RMI4_PRODUCT_ID_SIZE 10
|
||
|
#define SYNAPTICS_RMI4_BUILD_ID_SIZE 3
|
||
|
|
||
|
#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
|
||
|
|
||
|
/*
|
||
|
* 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[SYNAPTICS_RMI4_PRODUCT_INFO_SIZE];
|
||
|
unsigned char date_code[SYNAPTICS_RMI4_DATE_CODE_SIZE];
|
||
|
unsigned short tester_id;
|
||
|
unsigned short serial_number;
|
||
|
unsigned char product_id_string[SYNAPTICS_RMI4_PRODUCT_ID_SIZE + 1];
|
||
|
unsigned char build_id[SYNAPTICS_RMI4_BUILD_ID_SIZE];
|
||
|
unsigned char config_id[3];
|
||
|
struct list_head support_fn_list;
|
||
|
};
|
||
|
|
||
|
/*
|
||
|
* 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
|
||
|
* @flip_x: set to TRUE if desired to flip direction on x-axis
|
||
|
* @flip_y: set to TRUE if desired to flip direction on y-axis
|
||
|
* @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_rmi4_platform_data *board;
|
||
|
struct synaptics_rmi4_device_info rmi4_mod_info;
|
||
|
struct regulator *vdd;
|
||
|
struct regulator *vcc_i2c;
|
||
|
struct mutex rmi4_io_ctrl_mutex;
|
||
|
struct delayed_work det_work;
|
||
|
struct workqueue_struct *det_workqueue;
|
||
|
#ifdef CONFIG_HAS_EARLYSUSPEND
|
||
|
struct early_suspend early_suspend;
|
||
|
#endif
|
||
|
const char *fw_image_name;
|
||
|
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 num_of_fingers;
|
||
|
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;
|
||
|
bool flip_x;
|
||
|
bool flip_y;
|
||
|
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);
|
||
|
#ifdef CONFIG_FB
|
||
|
struct notifier_block fb_notif;
|
||
|
#else
|
||
|
#ifdef CONFIG_HAS_EARLYSUSPEND
|
||
|
struct early_suspend early_suspend;
|
||
|
#endif
|
||
|
#endif
|
||
|
};
|
||
|
|
||
|
enum exp_fn {
|
||
|
RMI_DEV = 0,
|
||
|
RMI_F34,
|
||
|
RMI_F54,
|
||
|
RMI_FW_UPDATER,
|
||
|
RMI_LAST,
|
||
|
};
|
||
|
|
||
|
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 synaptics_rmi4_data *rmi4_data),
|
||
|
void (*func_remove)(struct synaptics_rmi4_data *rmi4_data),
|
||
|
void (*func_attn)(struct synaptics_rmi4_data *rmi4_data,
|
||
|
unsigned char intr_mask));
|
||
|
|
||
|
static inline ssize_t synaptics_rmi4_show_error(struct device *dev,
|
||
|
struct device_attribute *attr, char *buf)
|
||
|
{
|
||
|
dev_warn(dev, "%s Attempted to read from write-only attribute %s\n",
|
||
|
__func__, attr->attr.name);
|
||
|
return -EPERM;
|
||
|
}
|
||
|
|
||
|
static inline ssize_t synaptics_rmi4_store_error(struct device *dev,
|
||
|
struct device_attribute *attr, const char *buf, size_t count)
|
||
|
{
|
||
|
dev_warn(dev, "%s Attempted to write to read-only attribute %s\n",
|
||
|
__func__, attr->attr.name);
|
||
|
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
|