blob: 2a0bc42937b2917af6ad11d0f7096ddd1bafc900 [file] [log] [blame]
/**
* touch-info.c - library routines for handling generic touch information
*
* Copyright (c) 2018 smcdef <songmuchun@wingtech.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* 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.
*
* Please see the file Documentation/touch-info.txt for critical information
* about using the touch-info interface.
*/
#ifndef _TOUCH_INFO_H_
#define _TOUCH_INFO_H_
#include <linux/kobject.h>
#include <linux/device.h>
#include <linux/firmware.h>
#include <linux/input.h>
#include <linux/seq_file.h>
/**
* Lock down info format:
* XX XX XX XX XXXX XX XX (8 bytes)
* | | | | | | |
* | | | | | | +----> [7] Reservation byte default = 0
* | | | | | +-------> [6] CG maker
* | | | | +-----------> [4:5] Project ID
* | | | +---------------> [3] HW version
* | | +------------------> [2] CG ink color
* | +---------------------> [1] Display maker
* +------------------------> [0] The maker of Touch Panel and CG lamination
*/
enum {
LOCKDOWN_INFO_PANEL_MAKER_INDEX = 0,
LOCKDOWN_INFO_DISPLAY_MAKER_INDEX,
LOCKDOWN_INFO_PANEL_COLOR_INDEX,
LOCKDOWN_INFO_HW_VERSION_INDEX,
LOCKDOWN_INFO_PROJECT_ID1_INDEX,
LOCKDOWN_INFO_PROJECT_ID2_INDEX,
LOCKDOWN_INFO_CG_MAKER_INDEX,
LOCKDOWN_INFO_RESERVE_INDEX,
/**
* How many bytes to describte lockdown info?
* Now, 8 bytes is enough.
*/
LOCKDOWN_INFO_SIZE,
};
/**
* Gesture report core supported key code.
* You can report gesture key code via tid_report_key().
*/
enum gesture_key {
GS_KEY_SWIPE_LEFT = 0,
GS_KEY_SWIPE_RIGHT,
GS_KEY_SWIPE_UP,
GS_KEY_SWIPE_DOWM,
GS_KEY_DOUBLE_TAP,
GS_KEY_ONECE_TAP,
GS_KEY_LONG_PRESS,
GS_KEY_E,
GS_KEY_C,
GS_KEY_W,
GS_KEY_M,
GS_KEY_O,
GS_KEY_S,
GS_KEY_V,
GS_KEY_Z,
/* do not use the following enumeration */
GS_KEY_END, /* end */
GS_KEY_ENABLE = 31,
};
struct tid_private;
struct proc_dir_entry;
/**
* struct touch_info_dev_operations - The methods of touch_info_dev
* @reset: Reset the IC.
* @get_version: Get the firmware version of the IC.
* @firmware_upgrade: Firmware upgrade.
* @open_short_test: The callback of the open-short test. If open-short
* test success return 1 and fail return 0. Return an error
* number(negative number) if there is an error.
* @get_lockdown_info: Get the lockdown info. The out_values buf size
* is LOCKDOWN_INFO_SIZE.
* @gesture_set_capability: Enable or disable all gesture.
*
* Notice: If success return 0, otherwise return an error
* number(negative number) exclude @open_short_test. You can find all error
* numbers in include/uapi/asm-gerneric/errno-base.h.
*/
struct touch_info_dev_operations {
int (*reset)(struct device *dev);
int (*get_version)(struct device *dev, int *major, int *minor);
int (*firmware_upgrade)(struct device *dev,
const struct firmware *fw, bool force);
#ifdef CONFIG_TOUCHSCREEN_OPEN_SHORT_TEST
int (*open_short_test)(struct device *dev, struct seq_file *seq,
const struct firmware *fw);
#endif
#ifdef CONFIG_TOUCHSCREEN_LOCKDOWN_INFO
/* the out_values buf size is LOCKDOWN_INFO_SIZE */
int (*get_lockdown_info)(struct device *dev, char *out_values);
#endif
#ifdef CONFIG_TOUCHSCREEN_GESTURE
int (*gesture_set_capability)(struct device *dev, bool enable);
#endif
#ifdef CONFIG_FB
int (*resume)(struct device *dev);
int (*suspend)(struct device *dev);
int (*resume_early)(struct device *dev);
int (*suspend_early)(struct device *dev);
#endif
int (*product_selector)(struct device *dev);
/**
* When @targets and @names are both NULL, return the number of targets
* that need to be created.
*/
size_t (*sysfs_create_link_targets)(struct device *dev,
struct kobject **targets,
const char **names);
size_t (*proc_create_link_targets)(struct device *dev,
struct proc_dir_entry **targets,
const char **names);
};
/**
* struct touch_info_dev - The touch information structure
*
* @rst_gpio: The reset gpio num.
* @irq_gpio: The irq gpio num.
* @vendor: The vendor of the touch ic.
* @product: The name of the touch ic.
* @panel_maker: The maker of the touch panel.If you enable
* CONFIG_TOUCHSCREEN_LOCKDOWN_INFO, @panel_maker can set NULL.Because
* we will get maker via @tid_ops->get_lockdown_info().
* @use_dev_path: If your driver has implemented the sysfs file,
* you can set @use_dev_path %true. And also, @reset,
* @get_version and @firmware_upgrade do not need to
* implement. Otherwise set @use_dev_path %false. We will
* help you create those sysfs file.
* @fw_name_use_color: Firmware name should include panel color?
* @ini_name_use_color: Ini(open-short test) name should include panel color?
* @tid_ops: The methods of touch_info_dev.
* @p: Touch core specific data, your driver should not
* touch it.
* @dev Device.
* @panel_color The color of touch panel.
*/
struct touch_info_dev {
int rst_gpio;
int irq_gpio;
const char *vendor;
const char *product;
const char *panel_maker;
bool use_dev_path:1;
bool fw_name_use_color:1;
bool ini_name_use_color:1;
bool open_short_not_use_fw:1;
struct touch_info_dev_operations *tid_ops;
/**
* touch core specific data, your driver should
* not touch it.
*/
struct tid_private *p;
struct device dev;
const char *panel_color;
};
/* Initialize a touch_info_dev structure */
#define TOUCH_INFO_DEV_INIT(name) { \
.rst_gpio = -1, \
.irq_gpio = -1, \
.vendor = NULL, \
.product = NULL, \
.panel_maker = NULL, \
.use_dev_path = false, \
.fw_name_use_color = false, \
.ini_name_use_color = false, \
.open_short_not_use_fw = false, \
.tid_ops = NULL, \
.p = NULL, \
.panel_color = NULL, \
}
/* Define a touch_info_dev varible statically and initialize it */
#define TOUCH_INFO_DEV(name) \
struct touch_info_dev name = TOUCH_INFO_DEV_INIT(name)
#define PROC_ENTRY_FUNCTION(name) \
static int name##_proc_open(struct inode *inode, struct file *file) \
{ \
return single_open(file, name##_proc_show, PDE_DATA(inode)); \
}
#define PROC_ENTRY_COM(name) \
PROC_ENTRY_FUNCTION(name) \
static const struct file_operations name##_fops = { \
.owner = THIS_MODULE, \
.open = name##_proc_open, \
.read = seq_read, \
.llseek = seq_lseek, \
.release = single_release,
#define PROC_ENTRY_END }
#define PROC_ENTRY_RO(name) \
PROC_ENTRY_COM(name) \
PROC_ENTRY_END
#define PROC_ENTRY_RW(name) \
PROC_ENTRY_COM(name) \
.write = name##_proc_write, \
PROC_ENTRY_END
#ifdef CONFIG_TOUCHSCREEN_INFORMATION_INTERFACE
struct touch_info_dev *devm_touch_info_dev_allocate(struct device *dev,
bool alloc_ops);
void devm_touch_info_dev_free(struct device *dev, struct touch_info_dev *tid,
bool free_ops);
int devm_touch_info_dev_register(struct device *dev, const char *name,
struct touch_info_dev *tid);
int touch_info_dev_register(struct device *dev, const char *name,
struct touch_info_dev *tid);
void devm_touch_info_dev_unregister(struct device *dev,
struct touch_info_dev *tid);
void touch_info_dev_unregister(struct touch_info_dev *tid);
int tid_upgrade_firmware_nowait(struct touch_info_dev *tid);
int tid_upgrade_firmware_opt(struct touch_info_dev *tid, bool direct,
bool force);
int tid_hardware_info_get(char *buf, size_t size);
int tid_regulators_enable_opt(struct touch_info_dev *tid, bool enable);
#ifdef CONFIG_TOUCHSCREEN_GESTURE
int tid_report_key(struct touch_info_dev *tid, enum gesture_key key);
bool tid_gesture_is_enabled(struct touch_info_dev *tid);
#else
static inline int tid_report_key(struct touch_info_dev *tid,
enum gesture_key key)
{
return -ENODEV;
}
static inline bool tid_gesture_is_enabled(struct touch_info_dev *tid)
{
return false;
}
#endif /* CONFIG_TOUCHSCREEN_GESTURE */
const char *tid_panel_maker(void);
const char *tid_panel_color(void);
#else
static inline struct touch_info_dev *
devm_touch_info_dev_allocate(struct device *dev, bool alloc_ops)
{
return NULL;
}
static inline int devm_touch_info_dev_register(struct device *dev,
const char *name,
struct touch_info_dev *tid)
{
return -ENODEV;
}
static inline int touch_info_dev_register(struct device *dev,
const char *name,
struct touch_info_dev *tid)
{
return -ENODEV;
}
static inline void devm_touch_info_dev_unregister(struct device *dev,
struct touch_info_dev *tid)
{
}
static inline void touch_info_dev_unregister(struct touch_info_dev *tid)
{
}
static inline int tid_hardware_info_get(char *buf, size_t size)
{
return -ENODEV;
}
static inline int tid_report_key(struct touch_info_dev *tid,
enum gesture_key key)
{
return -ENODEV;
}
static inline int tid_upgrade_firmware_nowait(struct touch_info_dev *tid)
{
return -ENODEV;
}
static inline int tid_upgrade_firmware_opt(struct touch_info_dev *tid,
bool direct, bool force)
{
return -ENODEV;
}
static inline const char *tid_panel_maker(void)
{
return NULL;
}
static inline const char *tid_panel_color(void)
{
return NULL;
}
static inline bool tid_gesture_is_enabled(struct touch_info_dev *tid)
{
return false;
}
static inline void devm_touch_info_dev_free(struct device *dev,
struct touch_info_dev *tid,
bool free_ops)
{
}
static inline int tid_regulators_enable_opt(struct touch_info_dev *tid,
bool enable)
{
return -ENODEV;
}
#endif /* CONFIG_TOUCHSCREEN_INFORMATION_INTERFACE */
static inline int devm_tid_register(struct device *dev,
struct touch_info_dev *tid)
{
return devm_touch_info_dev_register(dev, NULL, tid);
}
static inline void devm_tid_unregister(struct device *dev,
struct touch_info_dev *tid)
{
devm_touch_info_dev_unregister(dev, tid);
}
static inline struct touch_info_dev *devm_tid_allocate(struct device *dev)
{
return devm_touch_info_dev_allocate(dev, false);
}
static inline struct touch_info_dev *
devm_tid_and_ops_allocate(struct device *dev)
{
return devm_touch_info_dev_allocate(dev, true);
}
static inline void devm_tid_free(struct device *dev, struct touch_info_dev *tid)
{
devm_touch_info_dev_free(dev, tid, false);
}
static inline void devm_tid_and_ops_free(struct device *dev,
struct touch_info_dev *tid)
{
devm_touch_info_dev_free(dev, tid, true);
}
static inline int tid_upgrade_firmware(struct touch_info_dev *tid)
{
return tid_upgrade_firmware_opt(tid, false, false);
}
static inline int tid_upgrade_firmware_force(struct touch_info_dev *tid)
{
return tid_upgrade_firmware_opt(tid, false, true);
}
static inline int tid_upgrade_firmware_direct(struct touch_info_dev *tid)
{
return tid_upgrade_firmware_opt(tid, true, false);
}
static inline int tid_upgrade_firmware_direct_force(struct touch_info_dev *tid)
{
return tid_upgrade_firmware_opt(tid, true, true);
}
static inline bool tid_gesture_enabled(void)
{
return tid_gesture_is_enabled(NULL);
}
static inline bool tid_gesture_disabled(void)
{
return !tid_gesture_is_enabled(NULL);
}
static inline bool tid_gesture_enabled_by_tid(struct touch_info_dev *tid)
{
return tid_gesture_is_enabled(tid);
}
static inline bool tid_gesture_disabled_by_tid(struct touch_info_dev *tid)
{
return !tid_gesture_is_enabled(tid);
}
static inline int tid_regulators_enable(struct touch_info_dev *tid)
{
return tid_regulators_enable_opt(tid, true);
}
static inline int tid_regulators_disable(struct touch_info_dev *tid)
{
return tid_regulators_enable_opt(tid, false);
}
#endif /* _TOUCH_INFO_H_ */