/*
* Elan I2C/SMBus Touchpad driver
*
* Copyright (c) 2013 ELAN Microelectronics Corp.
*
* Author: 林政維 (Duson Lin) <dusonlin@emc.com.tw>
* Version: 1.5.6
*
* Based on cyapa driver:
* copyright (c) 2011-2012 Cypress Semiconductor, Inc.
* copyright (c) 2011-2012 Google, Inc.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published
* by the Free Software Foundation.
*
* Trademarks are the property of their respective owners.
*/
#include <linux/acpi.h>
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/firmware.h>
#include <linux/i2c.h>
#include <linux/init.h>
#include <linux/input/mt.h>
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/input.h>
#include <linux/uaccess.h>
#include <linux/jiffies.h>
#include <linux/completion.h>
#include <linux/of.h>
#include <linux/regulator/consumer.h>
#include <asm/unaligned.h>
#include "elan_i2c.h"
#define DRIVER_NAME "elan_i2c"
#define ELAN_DRIVER_VERSION "1.5.6"
#define ETP_PRESSURE_OFFSET 25
#define ETP_MAX_PRESSURE 255
#define ETP_FWIDTH_REDUCE 90
#define ETP_FINGER_WIDTH 15
#define ETP_RETRY_COUNT 3
#define ETP_MAX_FINGERS 5
#define ETP_FINGER_DATA_LEN 5
#define ETP_REPORT_ID 0x5D
#define ETP_REPORT_ID_OFFSET 2
#define ETP_TOUCH_INFO_OFFSET 3
#define ETP_FINGER_DATA_OFFSET 4
#define ETP_MAX_REPORT_LEN 34
/* The main device structure */
struct elan_tp_data {
struct i2c_client *client;
struct input_dev *input;
struct regulator *vcc;
const struct elan_transport_ops *ops;
/* for fw update */
struct completion fw_completion;
bool in_fw_update;
struct mutex sysfs_mutex;
unsigned int max_x;
unsigned int max_y;
unsigned int width_x;
unsigned int width_y;
unsigned int x_res;
unsigned int y_res;
u8 product_id;
u8 fw_version;
u8 sm_version;
u8 iap_version;
u16 fw_checksum;
u8 mode;
bool irq_wake;
u8 min_baseline;
u8 max_baseline;
bool baseline_ready;
};
static int elan_enable_power(struct elan_tp_data *data)
{
int repeat = ETP_RETRY_COUNT;
int error;
error = regulator_enable(data->vcc);
if (error) {
dev_err(&data->client->dev,
"Failed to enable regulator: %d\n", error);
return error;
}
do {
error = data->ops->power_control(data->client, true);
if (error >= 0)
return 0;
msleep(30);
} while (--repeat > 0);
return error;
}
static int elan_disable_power(struct elan_tp_data *data)
{
int repeat = ETP_RETRY_COUNT;
int error;
do {
error = data->ops->power_control(data->client, false);
if (!error) {
error = regulator_disable(data->vcc);
if (error) {
dev_err(&data->client->dev,
"Failed to disable regulator: %d\n",
error);
/* Attempt to power the chip back up */
data->ops->power_control(data->client, true);
break;
}
return 0;
}
msleep(30);
} while (--repeat > 0);
return error;
}
static int elan_sleep(struct elan_tp_data *data)
{
int repeat = ETP_RETRY_COUNT;
int error;
do {
error = data->ops->sleep_control(data->client, true);
if (!error)
return 0;
msleep(30);
} while (--repeat > 0);
return<