/*****************************************************************************
*
* File Name: cst0xx_core.c
*
* Version: V1.0
*
*****************************************************************************/
/*****************************************************************************
* Included header files
*****************************************************************************/
#include "cust_gpio_usage.h"
#include <cust_eint.h>
#include <linux/interrupt.h>
#include <linux/i2c.h>
#include <linux/sched.h>
#include <linux/kthread.h>
#include <linux/wait.h>
#include <linux/time.h>
#include <linux/delay.h>
#include <linux/input.h>
#include <linux/input/mt.h>
#include <linux/dma-mapping.h>
#include <mach/mt_pm_ldo.h>
#include <mach/mt_typedefs.h>
#include <mach/mt_boot.h>
//#include <linux/sched/prio.h>
#include <linux/rtpm_prio.h>
#ifdef CONFIG_HAS_EARLYSUSPEND
#include <linux/earlysuspend.h>
#endif
#include <linux/wakelock.h>
#include "cst0xx_core.h"
#include "cst0xx_ex_fun.h"
//#include "tpd.h"
/*****************************************************************************
* Private constant and macro definitions using #define
*****************************************************************************/
#define HYN_DRIVER_NAME "hyn_ts"
#define HYN_I2C_SLAVE_ADDR 0x15//0x2A 0x70 0x15 0x38
#define I2C_EXTENSION_FOCAL 1
#define CTP_NAME "hyn_ts"
/*****************************************************************************
* Static variables
*****************************************************************************/
struct i2c_client *hyn_i2c_client;
struct input_dev *hyn_input_dev;
struct task_struct *thread_tpd;
static DECLARE_WAIT_QUEUE_HEAD(waiter);
static int tpd_flag;
#if HYN_DEBUG_EN
int g_show_log = 1;
#else
int g_show_log = 0;
#endif
#if 0
unsigned int tpd_rst_gpio_number = 0;
static unsigned int tpd_int_gpio_number = 1;
static unsigned int hyn_touch_irq = 0;
static unsigned int f_hyn_irq_disable = 0;
static spinlock_t irq_lock;
#endif
//taikoto add 20180129
u8 *g_dma_buff_va = NULL;
dma_addr_t g_dma_buff_pa = 0;
u8 *tpd_i2c_dma_va = NULL;
dma_addr_t tpd_i2c_dma_pa = 0;
static void msg_dma_alloct(void) {
if (NULL == g_dma_buff_va) {
tpd->dev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
g_dma_buff_va = (u8 *)dma_alloc_coherent(&tpd->dev->dev, 128, &g_dma_buff_pa, GFP_KERNEL);
}
if(!g_dma_buff_va) {
HYN_DEBUG("[HYNITRON][DMA] Allocate DMA I2C Buffer failed!\n");
}
}
static void msg_dma_release(void) {
if(g_dma_buff_va) {
dma_free_coherent(NULL, 128, g_dma_buff_va, g_dma_buff_pa);
g_dma_buff_va = NULL;
g_dma_buff_pa = 0;
HYN_DEBUG("[HYNITRON][DMA] Allocate DMA I2C Buffer release!\n");
}
}
static DEFINE_MUTEX(i2c_access);
static DEFINE_MUTEX(i2c_rw_access);
//taikoto add end
#if TPD_HAVE_BUTTON
static int tpd_keys_local[TPD_KEY_COUNT] = TPD_KEYS;
static int tpd_keys_dim_local[TPD_KEY_COUNT][4] = TPD_KEYS_DIM;
#endif
#if (defined(CONFIG_TPD_HAVE_CALIBRATION) && !defined(CONFIG_TPD_CUSTOM_CALIBRATION))
static int tpd_def_calmat_local_normal[8] = TPD_CALIBRATION_MATRIX_ROTATION_NORMAL;
static int tpd_def_calmat_local_factory[8] = TPD_CALIBRATION_MATRIX_ROTATION_FACTORY;
#endif
/*****************************************************************************
* Static function prototypes
*****************************************************************************/
static int tpd_probe(struct i2c_client *client, const struct i2c_device_id *id);
static int tpd_i2c_detect(struct i2c_client *client, struct i2c_board_info *info);
static int tpd_remove(struct i2c_client *client);
static void tpd_resume(struct device *h);
static void tpd_suspend(struct device *h);
static void hyn_release_all_finger(void);
/*****************************************************************************
* Focaltech ts i2c driver configuration
*****************************************************************************/
static const struct i2c_device_id hyn_tpd_id[] = {{HYN_DRIVER_NAME, 0}, {} };
static struct i2c_board_info __initdata hyn_i2c_tpd={ I2C_BOARD_INFO(HYN_DRIVER_NAME, (0x2A>>1))};
#if 0
static const struct of_device_id hyn_dt_match[] =
{
{.compatible = "mediatek,cap_touch"},
{},
};
MODULE_DEVICE_TABLE(of, hyn_dt_match);
#endif
static struct i2c_driver tpd_i2c_driver =
{
.driver = {
.name = HYN_DRIVER_NAME,
//.of_match_table = of_match_ptr(hyn_dt_match),
},
.probe = tpd_probe,
.remove = tpd_remove,
.id_table = hyn_tpd_id,
.driver.name = HYN_DRIVER_NAME,
.detect = tpd_i2c_detect,
};
#if 0
static int of_get_hyn_platform_data(struct device *dev)
{
const struct of_device_id *match;
HYN_FUNC_ENTER();
if (dev->of_node) {
match = of_match_device(of_match_ptr(hyn_dt_match), dev);
if (!match) {
HYN_ERROR("[HYNITRON]: No device match found\n");
return -ENODEV;
}
}
HYN_FUNC_EXIT();
return 0;
}
#endif
#if 0
/*****************************************************************************
* Name: hyn_reset_proc
* Brief: Execute reset operation
* Input: hdelayms - delay time unit:ms
* Output:
* Return: 0 - Get correct Device ID
*****************************************************************************/
int hyn_reset_proc(int hdelayms)
{
tpd_gpio_output(tpd_rst_gpio_number, 0);
msleep(20);
tpd_gpio_output(tpd_rst_gpio_number, 1);
if (hdelayms){
msleep(hdelayms);
}
return 0;
}
#endif
int hyn_reset_proc(int hdelayms)
{
mt_set_gpio_mode(GPIO_CTP_RST_PIN, GPIO_CTP_RST_PIN_M_GPIO);
mt_set_gpio_dir(GPIO_CTP_RST_PIN, GPIO_DIR_OUT);
mt_set_gpio_out(GPIO_CTP_RST_PIN, GPIO_OUT_ZERO);
msleep(20);
mt_set_gpio_mode(GPIO_CTP_RST_PIN, GPIO_CTP_RST_PIN_M_GPIO);
mt_set_gpio_dir(GPIO_CTP_RST_PIN, GPIO_DIR_OUT);
mt_set_gpio_out(GPIO_CTP_RST_PIN, GPIO_OUT_ONE);
if (hdelayms){
msleep(hdelayms);
}
return 0;
}
#if 0
/*****************************************************************************
* Name: hyn_irq_disable
* Brief: disable irq
* Input:
* sync: 1 - call disable_irq(); Can't used in interrup handler
* 0 - call disable_irq_nosync(); Usually used in interrup handler
* Output:
* Return:
*****************************************************************************/
void hyn_irq_disable(void)
{
unsigned long irqflags;
spin_lock_irqsave(&irq_lock, irqflags);
if (!f_hyn_irq_disable)
{
disable_irq(hyn_touch_irq);
f_hyn_irq_disable = 1;
}
spin_unlock_irqrestore(&irq_lock, irqflags);
}
/*****************************************************************************
* Name: hyn_irq_enable
* Brief: enable irq
* Input:
* Output:
* Return:
*****************************************************************************/
void hyn_irq_enable(void)
{
unsigned long irqflags = 0;
spin_lock_irqsave(&irq_lock, irqflags);
if (f_hyn_irq_disable)
{
enable_irq(hyn_touch_irq);
f_hyn_irq_disable = 0;
}
spin_unlock_irqrestore(&irq_lock, irqflags);
}
#endif
#if 1
/*****************************************************************************
* Reprot related
*****************************************************************************/
/*****************************************************************************
* Name: hyn_release_all_finger
* Brief:
* Input:
* Output:
* Return:
*****************************************************************************/
static void hyn_release_all_finger(void)
{
#if HYN_MT_PROTOCOL_B_EN
unsigned int fin
评论1