mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-05 19:31:57 -04:00
Merge tag 'MMI-V1UG35H.75-14' of https://github.com/MotorolaMobilityLLC/motorola-kernel-modules into lineage-22.2
"Fogos push for Android 15" # By Wenge Zhu (6) and others # Via Andrea dos Santos * tag 'MMI-V1UG35H.75-14' of https://github.com/MotorolaMobilityLLC/motorola-kernel-modules: mmi-smbcharger: the battery age value switch to qcom gauge soh mmi_smbcharger_iio: allow to set fuelgauge cycle_count mmi_smbcharger_iio: Get batt cycyle_count from qcom_fg mmi_smbcharger_iio: recharge <=95% mmi_charger: Add state_of_health/first_usage_date/manufacturing_date moto_swap: Reduce force eswap out size of half dlkm: goodix_fod_mmi: fix KE issue dlkm: goodix_fod: support drm panel notification moto_swap: Add reset_bdev to close backing dev for ramboost2.0 avatrn: support touch sensitivity in game mode boston: support touch sensitivity in game mode focaltech: support stowed detection when gesture mode for focal insmod qorvo uwb driver according to mmi_info arm64/dts: update the wlan_antenna driver code for boston usbnet: fix incorrect dev_addr add page fault pages to list head to avoid be swapped out soon input: goodix_berlin: set default touch state to finger mode Report tapping coordinate when report gesture event awinic sar:add KBUILD_OPTIONS dlkm/fps:optimse driver for jiiov fogos: TP: open 1st icnl9916c force up config workaround fix long page fault issue kernel/fogo:fix The device automatically restarts during use cusco: WL2866d bringup [1/4] Support touch mmi class for GT9615 sc760x: Relax wakelock Upgrade gt9615 touch driver version Support factory test mmi_charger: Add heartbeat-factory-interval add sc89890h vindpm_track Revert "(CR) moto_swap: Add SWP_SYNCHRONOUS_IO cmd for ioctl" sc760x_charger: irq-dis-cfg eqe: input touch support game mode Distinguish log print with main touch Add IC type of GT9615 avatrn: add parrot build config for fts charger: add factory charge limit enable voltage Chipone: Fix compatibility with 5.4.0 api fix null pointer at quota_day_store moto_swap: Add SWP_SYNCHRONOUS_IO cmd for ioctl Add charger type uevent eqe: vibrator add haptic rtp support charge: config qg iterm small than FCC Take FPS driver compile error ctwov: Solve iic_driver .remove compatibility issue Conflicts: drivers/input/misc/goodix_fod_mmi/Kbuild drivers/input/touchscreen/focaltech_touch_v3/Kbuild drivers/input/touchscreen/goodix_berlin_mmi/Kbuild drivers/input/touchscreen/touchscreen_mmi/touchscreen_mmi_gesture.c drivers/power/mmi-smbcharger-iio/mmi-smbcharger-iio.c Change-Id: I49de02f202aba2d0a355bd8b86d5a8378e962e61
This commit is contained in:
commit
b487e97532
47 changed files with 1317 additions and 175 deletions
|
|
@ -986,67 +986,6 @@ static int use_gpio_init(struct anc_data *p_data) {
|
|||
return ret_val;
|
||||
}
|
||||
|
||||
static int anc_gpio_init(struct anc_data *p_data) {
|
||||
int ret_val = 0;
|
||||
|
||||
if (p_data == NULL) {
|
||||
ANC_LOGE("p_data is NULL");
|
||||
return -EINVAL;
|
||||
}
|
||||
ANC_LOGD("init gpio");
|
||||
if (p_data->resource_requested) {
|
||||
ANC_LOGW("warning: resource is already requested, return!");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (p_data->vdd_use_gpio) {
|
||||
ret_val = anc_request_named_gpio(p_data, "anc,gpio_pwr", &p_data->pwr_gpio);
|
||||
if (ret_val) {
|
||||
ANC_LOGE("request power gpio failed, ret_val:%d", ret_val);
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
ret_val = gpio_direction_output(p_data->pwr_gpio, 0);
|
||||
if (ret_val) {
|
||||
ANC_LOGE("power gpio direction output failed, ret_val:%d", ret_val);
|
||||
return ret_val;
|
||||
}
|
||||
}
|
||||
|
||||
if (p_data->use_gpio_init == false) {
|
||||
ret_val = use_pinctrl_init(p_data);
|
||||
if (ret_val) {
|
||||
ANC_LOGE("use pinctrl init failed, ret_val:%d", ret_val);
|
||||
return ret_val;
|
||||
}
|
||||
}
|
||||
|
||||
ret_val = use_gpio_init(p_data);
|
||||
if (ret_val) {
|
||||
ANC_LOGE("use gpio init failed, ret_val:%d", ret_val);
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
#ifdef SAMSUNG_PLATFORM
|
||||
/* Init spi clock */
|
||||
ret_val = anc_spi_clk_init(p_data);
|
||||
if (ret_val) {
|
||||
ANC_LOGE("spi init failed, ret_val:%d", ret_val);
|
||||
return ret_val;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (of_property_read_bool(p_data->dev->of_node, "anc,enable-on-boot")) {
|
||||
ANC_LOGD("Enabling hardware");
|
||||
device_power_up(p_data);
|
||||
}
|
||||
|
||||
p_data->resource_requested = true;
|
||||
ANC_LOGD("success");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int anc_gpio_deinit(struct anc_data *p_data) {
|
||||
if (p_data == NULL) {
|
||||
ANC_LOGE("p_data is NULL");
|
||||
|
|
@ -1054,10 +993,6 @@ static int anc_gpio_deinit(struct anc_data *p_data) {
|
|||
}
|
||||
|
||||
ANC_LOGD("deinit gpio");
|
||||
if (!p_data->resource_requested) {
|
||||
ANC_LOGW("warning: resource is already released, return!");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (p_data->vdd_use_gpio) {
|
||||
if (gpio_is_valid(p_data->pwr_gpio)) {
|
||||
|
|
@ -1085,12 +1020,71 @@ static int anc_gpio_deinit(struct anc_data *p_data) {
|
|||
anc_spi_clk_deinit(p_data);
|
||||
#endif
|
||||
|
||||
p_data->resource_requested = false;
|
||||
ANC_LOGD("success");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int anc_gpio_init(struct anc_data *p_data) {
|
||||
int ret_val = 0;
|
||||
|
||||
if (p_data == NULL) {
|
||||
ANC_LOGE("p_data is NULL");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ANC_LOGD("init gpio");
|
||||
if (p_data->vdd_use_gpio) {
|
||||
ret_val = anc_request_named_gpio(p_data, "anc,gpio_pwr", &p_data->pwr_gpio);
|
||||
if (ret_val) {
|
||||
ANC_LOGE("request power gpio failed, ret_val:%d", ret_val);
|
||||
goto ANC_INIT_FAIL;
|
||||
}
|
||||
|
||||
ret_val = gpio_direction_output(p_data->pwr_gpio, 0);
|
||||
if (ret_val) {
|
||||
ANC_LOGE("power gpio direction output failed, ret_val:%d", ret_val);
|
||||
goto ANC_INIT_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
if (p_data->use_gpio_init == false) {
|
||||
ret_val = use_pinctrl_init(p_data);
|
||||
if (ret_val) {
|
||||
ANC_LOGE("use pinctrl init failed, ret_val:%d", ret_val);
|
||||
goto ANC_INIT_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
ret_val = use_gpio_init(p_data);
|
||||
if (ret_val) {
|
||||
ANC_LOGE("use gpio init failed, ret_val:%d", ret_val);
|
||||
goto ANC_INIT_FAIL;
|
||||
}
|
||||
|
||||
#ifdef SAMSUNG_PLATFORM
|
||||
/* Init spi clock */
|
||||
ret_val = anc_spi_clk_init(p_data);
|
||||
if (ret_val) {
|
||||
ANC_LOGE("spi init failed, ret_val:%d", ret_val);
|
||||
goto ANC_INIT_FAIL;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (of_property_read_bool(p_data->dev->of_node, "anc,enable-on-boot")) {
|
||||
ANC_LOGD("Enabling hardware");
|
||||
device_power_up(p_data);
|
||||
}
|
||||
|
||||
ANC_LOGD("success");
|
||||
|
||||
return 0;
|
||||
|
||||
ANC_INIT_FAIL:
|
||||
anc_gpio_deinit(p_data);
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
static int anc_open(struct inode *inode, struct file *filp) {
|
||||
struct anc_data *p_data = NULL;
|
||||
p_data = container_of(inode->i_cdev, struct anc_data, cdev);
|
||||
|
|
@ -1110,10 +1104,18 @@ static int anc_platform_init(struct anc_data *p_data) {
|
|||
ANC_LOGE("p_data is NULL");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (p_data->resource_requested) {
|
||||
ANC_LOGW("warning: resource is already requested, return!");
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret_val = anc_gpio_init(p_data);
|
||||
if (ret_val) {
|
||||
ANC_LOGE("Failed to init gpio, ret_val: %d", ret_val);
|
||||
return ret_val;
|
||||
} else {
|
||||
p_data->resource_requested = true;
|
||||
}
|
||||
|
||||
return ret_val;
|
||||
|
|
@ -1126,10 +1128,18 @@ static int anc_platform_free(struct anc_data *p_data) {
|
|||
ANC_LOGE("p_data is NULL");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!p_data->resource_requested) {
|
||||
ANC_LOGW("warning: resource is already released, return!");
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret_val = anc_gpio_deinit(p_data);
|
||||
if (ret_val) {
|
||||
ANC_LOGE("Failed to deinit gpio");
|
||||
return ret_val;
|
||||
} else {
|
||||
p_data->resource_requested = false;
|
||||
}
|
||||
|
||||
return ret_val;
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
* as published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#include <linux/version.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/gpio.h>
|
||||
|
|
@ -28,6 +29,10 @@
|
|||
#define RESET_HIGH_SLEEP2_MIN_US 5000
|
||||
#define RESET_HIGH_SLEEP2_MAX_US (RESET_HIGH_SLEEP2_MIN_US + 100)
|
||||
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 1, 25))
|
||||
#define devm_gpio_free(a, b) NULL
|
||||
#endif
|
||||
|
||||
struct FPS_data {
|
||||
unsigned int enabled;
|
||||
unsigned int state;
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
#include <linux/version.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/of_gpio.h>
|
||||
|
|
@ -30,6 +31,10 @@
|
|||
#include <linux/platform_device.h>
|
||||
#endif
|
||||
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 1, 25))
|
||||
#define devm_gpio_free(a, b) NULL
|
||||
#endif
|
||||
|
||||
int gf_parse_dts(struct gf_dev *gf_dev)
|
||||
{
|
||||
int rc = 0;
|
||||
|
|
@ -129,7 +134,9 @@ err_pwr:
|
|||
|
||||
void gf_cleanup(struct gf_dev *gf_dev)
|
||||
{
|
||||
#if (LINUX_VERSION_CODE < KERNEL_VERSION(6, 1, 25))
|
||||
struct device *dev = &gf_dev->spi->dev;
|
||||
#endif
|
||||
pr_info("goodix: %s\n", __func__);
|
||||
|
||||
if (gpio_is_valid(gf_dev->irq_gpio)) {
|
||||
|
|
|
|||
|
|
@ -501,6 +501,30 @@ done_freemem:
|
|||
return -1;
|
||||
}
|
||||
|
||||
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(6, 1, 0))
|
||||
static void stmvl53l1_remove(struct i2c_client *client)
|
||||
{
|
||||
struct stmvl53l1_data *data = i2c_get_clientdata(client);
|
||||
struct i2c_data *i2c_data = (struct i2c_data *)data->client_object;
|
||||
|
||||
vl53l1_dbgmsg("Enter\n");
|
||||
mutex_lock(&data->work_mutex);
|
||||
|
||||
stmvl53l1_sysfs_laser(data, false);
|
||||
|
||||
/* main driver cleanup */
|
||||
stmvl53l1_cleanup(data);
|
||||
|
||||
/* release gpios */
|
||||
stmvl53l1_release_gpios(i2c_data);
|
||||
|
||||
mutex_unlock(&data->work_mutex);
|
||||
|
||||
stmvl53l1_put(data->client_object);
|
||||
|
||||
vl53l1_dbgmsg("End\n");
|
||||
}
|
||||
#else
|
||||
static int stmvl53l1_remove(struct i2c_client *client)
|
||||
{
|
||||
struct stmvl53l1_data *data = i2c_get_clientdata(client);
|
||||
|
|
@ -525,6 +549,7 @@ static int stmvl53l1_remove(struct i2c_client *client)
|
|||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
static int stmvl53l1_suspend(struct device *dev)
|
||||
|
|
|
|||
|
|
@ -1788,15 +1788,14 @@ static int fts_sysfs_class(void *_data, bool create)
|
|||
int i, error = 0;
|
||||
static struct class *touchscreen_class;
|
||||
static struct device *ts_class_dev;
|
||||
static int minor;
|
||||
dev_t devno;
|
||||
|
||||
if (create) {
|
||||
minor = input_get_new_minor(data->spi->chip_select,
|
||||
1, false);
|
||||
if (minor < 0)
|
||||
minor = input_get_new_minor(TSDEV_MINOR_BASE,
|
||||
TSDEV_MINOR_MAX, true);
|
||||
pr_info("assigned minor %d\n", minor);
|
||||
error = alloc_chrdev_region(&devno, 0, 1, FTS_CHIP_NAME);
|
||||
if (error) {
|
||||
pr_err("Alloc input devno failed\n");
|
||||
return error;
|
||||
}
|
||||
|
||||
touchscreen_class = class_create(THIS_MODULE, "touchscreen");
|
||||
if (IS_ERR(touchscreen_class)) {
|
||||
|
|
@ -1807,11 +1806,11 @@ static int fts_sysfs_class(void *_data, bool create)
|
|||
|
||||
#ifdef FTS_LAST_TIME_EN
|
||||
ts_class_dev = device_create(touchscreen_class, NULL,
|
||||
MKDEV(INPUT_MAJOR, minor),
|
||||
devno,
|
||||
data, FTS_PRIMARY_NAME);
|
||||
#else
|
||||
ts_class_dev = device_create(touchscreen_class, NULL,
|
||||
MKDEV(INPUT_MAJOR, minor),
|
||||
devno,
|
||||
data, FTS_CHIP_NAME);
|
||||
#endif
|
||||
|
||||
|
|
@ -1845,7 +1844,7 @@ static int fts_sysfs_class(void *_data, bool create)
|
|||
device_destroy:
|
||||
for (--i; i >= 0; --i)
|
||||
device_remove_file(ts_class_dev, &attrs[i]);
|
||||
device_destroy(touchscreen_class, MKDEV(INPUT_MAJOR, minor));
|
||||
device_destroy(touchscreen_class, devno);
|
||||
ts_class_dev = NULL;
|
||||
class_unregister(touchscreen_class);
|
||||
pr_err("error creating touchscreen class\n");
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
DLKM_DIR := motorola/kernel/modules
|
||||
LOCAL_PATH := $(call my-dir)
|
||||
|
||||
ifeq ($(call is-board-platform-in-list,taro kalama), true)
|
||||
ifeq ($(call is-board-platform-in-list,taro kalama parrot), true)
|
||||
|
||||
ifneq ($(FOCALTECH_TOUCH_IC_NAME),)
|
||||
KBUILD_OPTIONS += CONFIG_INPUT_FOCALTECH_V3_MMI_IC_NAME=$(FOCALTECH_TOUCH_IC_NAME)
|
||||
|
|
|
|||
|
|
@ -82,6 +82,8 @@
|
|||
#define FTS_REG_CHIP_ID 0xA3
|
||||
#define FTS_REG_CHIP_ID2 0x9F
|
||||
#define FTS_REG_POWER_MODE 0xA5
|
||||
#define FTS_REG_POWER_MODE_ACTIVE 0
|
||||
#define FTS_REG_POWER_MODE_STANDBY 0x02
|
||||
#define FTS_REG_POWER_MODE_SLEEP 0x03
|
||||
#define FTS_REG_FW_VER 0xA6
|
||||
#define FTS_REG_VENDOR_ID 0xA8
|
||||
|
|
|
|||
|
|
@ -1972,6 +1972,11 @@ static int fts_parse_dt(struct device *dev, struct fts_ts_platform_data *pdata)
|
|||
if (pdata->sample_ctrl)
|
||||
FTS_INFO("support focaltech sample mode");
|
||||
|
||||
pdata->stowed_mode_ctrl = of_property_read_bool(np,
|
||||
"focaltech,stowed-mode-ctrl");
|
||||
if (pdata->stowed_mode_ctrl)
|
||||
FTS_INFO("Support focaltech touch stowed mode");
|
||||
|
||||
|
||||
FTS_FUNC_EXIT();
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -161,6 +161,7 @@ struct fts_ts_platform_data {
|
|||
bool interpolation_ctrl;
|
||||
bool report_rate_ctrl;
|
||||
bool sample_ctrl;
|
||||
bool stowed_mode_ctrl;
|
||||
};
|
||||
|
||||
struct ts_event {
|
||||
|
|
@ -201,6 +202,7 @@ struct fts_mode_info {
|
|||
int sample;
|
||||
int report_rate_mode;
|
||||
int edge_mode[2];
|
||||
int stowed;
|
||||
};
|
||||
struct fts_ts_data {
|
||||
struct i2c_client *client;
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@
|
|||
#include "focaltech_ts_config.h"
|
||||
|
||||
struct focaltech_ic_report_rate_config report_rate_config_info = {
|
||||
#if defined(PRODUCT_BANGKK)
|
||||
#if defined(PRODUCT_BANGKK)|| defined(PRODUCT_AVATRN)
|
||||
.rate_config_count = 2,
|
||||
.refresh_rate_ctrl = 0,
|
||||
.interpolation_ctrl = 1,
|
||||
|
|
|
|||
|
|
@ -71,6 +71,10 @@ static ssize_t fts_sample_store(struct device *dev,
|
|||
struct device_attribute *attr, const char *buf, size_t size);
|
||||
static ssize_t fts_sample_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf);
|
||||
static ssize_t fts_stowed_store(struct device *dev,
|
||||
struct device_attribute *attr, const char *buf, size_t size);
|
||||
static ssize_t fts_stowed_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf);
|
||||
|
||||
|
||||
static DEVICE_ATTR(edge, (S_IRUGO | S_IWUSR | S_IWGRP),
|
||||
|
|
@ -79,6 +83,8 @@ static DEVICE_ATTR(interpolation, (S_IRUGO | S_IWUSR | S_IWGRP),
|
|||
fts_interpolation_show, fts_interpolation_store);
|
||||
static DEVICE_ATTR(sample, (S_IRUGO | S_IWUSR | S_IWGRP),
|
||||
fts_sample_show, fts_sample_store);
|
||||
static DEVICE_ATTR(stowed, (S_IWUSR | S_IWGRP | S_IRUGO),
|
||||
fts_stowed_show, fts_stowed_store);
|
||||
|
||||
#define ADD_ATTR(name) { \
|
||||
if (idx < MAX_ATTRS_ENTRIES) { \
|
||||
|
|
@ -397,6 +403,67 @@ static ssize_t fts_sample_show(struct device *dev,
|
|||
return scnprintf(buf, PAGE_SIZE, "0x%02x", ts_data->set_mode.sample);
|
||||
}
|
||||
|
||||
static ssize_t fts_stowed_store(struct device *dev,
|
||||
struct device_attribute *attr, const char *buf, size_t size)
|
||||
{
|
||||
int ret = 0;
|
||||
unsigned long mode = 0;
|
||||
struct fts_ts_data *ts_data;
|
||||
|
||||
dev = MMI_DEV_TO_TS_DEV(dev);
|
||||
GET_TS_DATA(dev);
|
||||
|
||||
ret = kstrtoul(buf, 0, &mode);
|
||||
if (ret < 0) {
|
||||
FTS_INFO("Failed to convert value.\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
mutex_lock(&ts_data->mode_lock);
|
||||
|
||||
ts_data->get_mode.stowed = mode;
|
||||
if (ts_data->set_mode.stowed == mode) {
|
||||
FTS_DEBUG("The value = %lu is same, so not to write", mode);
|
||||
ret = size;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if ((ts_data->power_disabled == false) && (ts_data->suspended == true)) {
|
||||
if (mode)
|
||||
ret = fts_write_reg(FTS_REG_POWER_MODE, FTS_REG_POWER_MODE_STANDBY);
|
||||
else
|
||||
ret = fts_write_reg(FTS_REG_POWER_MODE, FTS_REG_POWER_MODE_ACTIVE);
|
||||
if (ret < 0) {
|
||||
FTS_ERROR("failed to set report rate, mode = %lu", mode);
|
||||
goto exit;
|
||||
}
|
||||
} else {
|
||||
FTS_INFO("Skip stowed mode setting suspended:%d, power_disabled:%d.\n", ts_data->suspended, ts_data->power_disabled);
|
||||
ret = size;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
ts_data->set_mode.stowed = mode;
|
||||
FTS_INFO("Success to set stowed mode %lu\n", mode);
|
||||
|
||||
ret = size;
|
||||
exit:
|
||||
mutex_unlock(&ts_data->mode_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static ssize_t fts_stowed_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct fts_ts_data *ts_data;
|
||||
|
||||
dev = MMI_DEV_TO_TS_DEV(dev);
|
||||
GET_TS_DATA(dev);
|
||||
|
||||
FTS_INFO("Stowed state = %d.\n", ts_data->set_mode.stowed);
|
||||
return scnprintf(buf, PAGE_SIZE, "0x%02x", ts_data->set_mode.stowed);
|
||||
}
|
||||
|
||||
static int fts_mmi_methods_get_vendor(struct device *dev, void *cdata)
|
||||
{
|
||||
return scnprintf(TO_CHARP(cdata), TS_MMI_MAX_VENDOR_LEN, "%s", "focaltech");
|
||||
|
|
@ -804,6 +871,10 @@ exit:
|
|||
}
|
||||
}
|
||||
|
||||
if (pdata->stowed_mode_ctrl) {
|
||||
ts_data->set_mode.stowed = 0;
|
||||
}
|
||||
|
||||
mutex_unlock(&ts_data->mode_lock);
|
||||
|
||||
FTS_FUNC_EXIT();
|
||||
|
|
@ -833,8 +904,11 @@ static int fts_mmi_pre_suspend(struct device *dev)
|
|||
static int fts_mmi_post_suspend(struct device *dev)
|
||||
{
|
||||
struct fts_ts_data *ts_data;
|
||||
struct fts_ts_platform_data *pdata;
|
||||
int ret = 0;
|
||||
|
||||
GET_TS_DATA(dev);
|
||||
pdata = ts_data->pdata;
|
||||
|
||||
FTS_FUNC_ENTER();
|
||||
|
||||
|
|
@ -848,6 +922,19 @@ static int fts_mmi_post_suspend(struct device *dev)
|
|||
#endif
|
||||
|
||||
ts_data->suspended = true;
|
||||
|
||||
if (pdata->stowed_mode_ctrl && ts_data->get_mode.stowed && (ts_data->power_disabled == false)) {
|
||||
mutex_lock(&ts_data->mode_lock);
|
||||
ret = fts_write_reg(FTS_REG_POWER_MODE, FTS_REG_POWER_MODE_STANDBY);
|
||||
if (ret < 0) {
|
||||
FTS_ERROR("Failed to set stowed mode %d", ts_data->get_mode.stowed);
|
||||
} else {
|
||||
ts_data->set_mode.stowed = ts_data->get_mode.stowed;
|
||||
FTS_INFO("Enable stowed mode %d success.", ts_data->set_mode.stowed);
|
||||
}
|
||||
mutex_unlock(&ts_data->mode_lock);
|
||||
}
|
||||
|
||||
FTS_FUNC_EXIT();
|
||||
|
||||
return 0;
|
||||
|
|
@ -1000,6 +1087,9 @@ static int fts_mmi_extend_attribute_group(struct device *dev, struct attribute_g
|
|||
if (pdata->sample_ctrl)
|
||||
ADD_ATTR(sample);
|
||||
|
||||
if (pdata->stowed_mode_ctrl)
|
||||
ADD_ATTR(stowed);
|
||||
|
||||
if (idx) {
|
||||
ext_attributes[idx] = NULL;
|
||||
*group = &ext_attr_group;
|
||||
|
|
|
|||
|
|
@ -1479,10 +1479,8 @@ static int brl_event_handler(struct goodix_ts_core *cd,
|
|||
ts_event->event_type = EVENT_GESTURE;
|
||||
ts_event->gesture_report_info = pre_buf[2];
|
||||
ts_event->gesture_type = pre_buf[4];
|
||||
#ifdef CONFIG_GTP_FOD
|
||||
memcpy(ts_event->gesture_data, &pre_buf[8],
|
||||
GOODIX_GESTURE_DATA_LEN);
|
||||
#endif
|
||||
} else {
|
||||
ts_info("Unsupported event status");
|
||||
return -EINVAL;
|
||||
|
|
|
|||
|
|
@ -16,7 +16,8 @@ struct goodix_ic_report_rate_config report_rate_config_info = {
|
|||
#if defined(PRODUCT_LI) || defined(PRODUCT_ONELI) || defined(PRODUCT_TUNDRA) \
|
||||
||defined(PRODUCT_EQS) || defined(PRODUCT_RTWO) || defined(PRODUCT_BRONCO) \
|
||||
|| defined(PRODUCT_ZEEKR) || defined(PRODUCT_LYNKCO) || defined(PRODUCT_BANGKK) \
|
||||
|| defined(PRODUCT_CTWO)
|
||||
|| defined(PRODUCT_EQE) || defined(PRODUCT_CTWO) || defined(PRODUCT_BOSTON) \
|
||||
|| defined(PRODUCT_AVATRN)
|
||||
.rate_config_count = 2,
|
||||
.refresh_rate_ctrl = 0,
|
||||
.interpolation_ctrl = 1,
|
||||
|
|
|
|||
|
|
@ -2484,9 +2484,9 @@ static int pen_notifier_callback(struct notifier_block *self,
|
|||
ts_info("Received event(%lu) for pen detection\n", event);
|
||||
|
||||
if (event == PEN_DETECTION_INSERT)
|
||||
cd->gtp_pen_detect_flag = 0x0;
|
||||
cd->gtp_pen_detect_flag = GTP_FINGER_MODE;
|
||||
else if (event == PEN_DETECTION_PULL)
|
||||
cd->gtp_pen_detect_flag = 0x1;
|
||||
cd->gtp_pen_detect_flag = GTP_PEN_MODE;
|
||||
|
||||
mutex_lock_interruptible(&cd->mode_lock);
|
||||
|
||||
|
|
@ -2664,7 +2664,7 @@ static int goodix_ts_probe(struct platform_device *pdev)
|
|||
#endif
|
||||
|
||||
#ifdef GTP_PEN_NOTIFIER
|
||||
core_data->gtp_pen_detect_flag = PEN_DETECTION_INSERT;
|
||||
core_data->gtp_pen_detect_flag = GTP_FINGER_MODE;
|
||||
core_data->pen_notif.notifier_call = pen_notifier_callback;
|
||||
ret = pen_detection_register_client(&core_data->pen_notif);
|
||||
if (ret)
|
||||
|
|
|
|||
|
|
@ -428,9 +428,7 @@ struct goodix_ts_event {
|
|||
u8 gesture_report_info;
|
||||
struct goodix_touch_data touch_data;
|
||||
struct goodix_pen_data pen_data;
|
||||
#ifdef CONFIG_GTP_FOD
|
||||
u8 gesture_data[GOODIX_GESTURE_DATA_LEN];
|
||||
#endif
|
||||
};
|
||||
|
||||
enum goodix_ic_bus_type {
|
||||
|
|
@ -603,6 +601,11 @@ struct goodix_ts_core {
|
|||
#endif
|
||||
};
|
||||
|
||||
#ifdef GTP_PEN_NOTIFIER
|
||||
#define GTP_FINGER_MODE 0
|
||||
#define GTP_PEN_MODE 1
|
||||
#endif
|
||||
|
||||
/* external module structures */
|
||||
enum goodix_ext_priority {
|
||||
EXTMOD_PRIO_RESERVED = 0,
|
||||
|
|
|
|||
|
|
@ -290,6 +290,8 @@ static int gsx_gesture_ist(struct goodix_ts_core *cd,
|
|||
mmi_event.evcode =4;
|
||||
}
|
||||
|
||||
mmi_event.evdata.x = le16_to_cpup((__le16 *)gs_event.gesture_data);
|
||||
mmi_event.evdata.y = le16_to_cpup((__le16 *)(gs_event.gesture_data + 2));
|
||||
/* call class method */
|
||||
ret = cd->imports->report_gesture(&mmi_event);
|
||||
if (!ret)
|
||||
|
|
|
|||
|
|
@ -419,6 +419,8 @@ static int gsx_gesture_ist(struct goodix_ts_core *cd,
|
|||
mmi_event.evcode =1;
|
||||
fod_down = 0;
|
||||
|
||||
mmi_event.evdata.x = le16_to_cpup((__le16 *)gs_event.gesture_data);
|
||||
mmi_event.evdata.y = le16_to_cpup((__le16 *)(gs_event.gesture_data + 2));
|
||||
/* call class method */
|
||||
ret = cd->imports->report_gesture(&mmi_event);
|
||||
if (!ret)
|
||||
|
|
@ -429,6 +431,8 @@ static int gsx_gesture_ist(struct goodix_ts_core *cd,
|
|||
mmi_event.evcode =4;
|
||||
fod_down = 0;
|
||||
|
||||
mmi_event.evdata.x = le16_to_cpup((__le16 *)gs_event.gesture_data);
|
||||
mmi_event.evdata.y = le16_to_cpup((__le16 *)(gs_event.gesture_data + 2));
|
||||
/* call class method */
|
||||
ret = cd->imports->report_gesture(&mmi_event);
|
||||
if (!ret)
|
||||
|
|
|
|||
|
|
@ -1277,8 +1277,8 @@ static int goodix_ts_mmi_post_resume(struct device *dev) {
|
|||
}
|
||||
|
||||
#ifdef GTP_PEN_NOTIFIER
|
||||
if (core_data->gtp_pen_detect_flag) {
|
||||
ret = goodix_ts_send_cmd(core_data, 0x32, 5, 0x1, 0x00);
|
||||
if (core_data->gtp_pen_detect_flag == GTP_PEN_MODE) {
|
||||
ret = goodix_ts_send_cmd(core_data, 0x32, 5, GTP_PEN_MODE, 0x00);
|
||||
if (ret < 0)
|
||||
ts_err("failed to send passive pen mode cmd");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,9 @@ else
|
|||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(DRM_PANEL_EVENT_NOTIFICATIONS),true)
|
||||
KBUILD_OPTIONS += CONFIG_DRM_PANEL_EVENT_NOTIFICATIONS=y
|
||||
endif
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_MODULE := goodix_gt96x_mmi.ko
|
||||
|
|
|
|||
|
|
@ -20,4 +20,13 @@ ifneq ($(filter m y,$(CONFIG_TOUCHSCREEN_GOODIX_BRL_SPI)),)
|
|||
EXTRA_CFLAGS += -DCONFIG_TOUCHSCREEN_GOODIX_BRL_SPI
|
||||
endif
|
||||
|
||||
ifneq ($(filter m y,$(CONFIG_INPUT_TOUCHSCREEN_MMI)),)
|
||||
EXTRA_CFLAGS += -DCONFIG_INPUT_TOUCHSCREEN_MMI
|
||||
goodix_gt96x_mmi-objs += goodix_ts_mmi.o
|
||||
endif
|
||||
|
||||
ifneq ($(filter m y, $(CONFIG_DRM_PANEL_EVENT_NOTIFICATIONS)),)
|
||||
EXTRA_CFLAGS += -DCONFIG_DRM_PANEL_EVENT_NOTIFICATIONS
|
||||
endif
|
||||
|
||||
KBUILD_EXTRA_SYMBOLS += $(CURDIR)/$(KBUILD_EXTMOD)/../touchscreen_mmi/$(GKI_OBJ_MODULE_DIR)/Module.symvers
|
||||
|
|
|
|||
|
|
@ -40,16 +40,20 @@
|
|||
#define ISP_RAM_ADDR_BRA 0x18400
|
||||
#define ISP_RAM_ADDR_BRB 0x57000
|
||||
#define ISP_RAM_ADDR_BRD 0x23800
|
||||
#define ISP_RAM_ADDR_MAR 0x3B800
|
||||
#define HW_REG_CPU_RUN_FROM 0x10000
|
||||
#define FLASH_CMD_REG_BRA 0x10400
|
||||
#define FLASH_CMD_REG_BRB 0x13400
|
||||
#define FLASH_CMD_REG_BRD 0x12400
|
||||
#define FLASH_CMD_REG_MAR 0x10174
|
||||
#define HW_REG_ISP_BUFFER_BRA 0x10410
|
||||
#define HW_REG_ISP_BUFFER_BRB 0x13410
|
||||
#define HW_REG_ISP_BUFFER_BRD 0x12410
|
||||
#define HW_REG_ISP_BUFFER_MAR 0x12400
|
||||
#define CONFIG_DATA_ADDR_BRA 0x3E000
|
||||
#define CONFIG_DATA_ADDR_BRB 0x40000
|
||||
#define CONFIG_DATA_ADDR_BRD 0x3E000
|
||||
#define CONFIG_DATA_ADDR_MAR 0x3F000
|
||||
|
||||
#define HOLD_CPU_REG_W 0x0002
|
||||
#define HOLD_CPU_REG_R 0x2000
|
||||
|
|
@ -131,6 +135,19 @@ struct update_info_t update_brd = {
|
|||
ENABLE_MISCTL_BRD,
|
||||
};
|
||||
|
||||
/* Marseille update info */
|
||||
struct update_info_t update_mar = {
|
||||
FW_HEADER_SIZE,
|
||||
FW_SUBSYS_INFO_OFFSET,
|
||||
ISP_RAM_ADDR_MAR,
|
||||
FLASH_CMD_REG_MAR,
|
||||
HW_REG_ISP_BUFFER_MAR,
|
||||
CONFIG_DATA_ADDR_MAR,
|
||||
MISCTL_REG_BRD,
|
||||
WATCH_DOG_REG_BRD,
|
||||
ENABLE_MISCTL_BRD,
|
||||
};
|
||||
|
||||
enum compare_status {
|
||||
COMPARE_EQUAL = 0,
|
||||
COMPARE_NOCODE,
|
||||
|
|
@ -484,7 +501,8 @@ static int goodix_update_prepare(struct fw_update_ctrl *fwu_ctrl)
|
|||
|
||||
/* enable misctl clock */
|
||||
if (fwu_ctrl->core_data->bus->ic_type == IC_TYPE_BERLIN_D ||
|
||||
fwu_ctrl->core_data->bus->ic_type == IC_TYPE_NOTTINGHAM)
|
||||
fwu_ctrl->core_data->bus->ic_type == IC_TYPE_NOTTINGHAM ||
|
||||
fwu_ctrl->core_data->bus->ic_type == IC_TYPE_MARSEILLE)
|
||||
hw_ops->write(cd, misctl_reg, (u8 *)&enable_misctl_val, 4);
|
||||
else
|
||||
hw_ops->write(cd, misctl_reg, (u8 *)&enable_misctl_val, 1);
|
||||
|
|
@ -1202,6 +1220,8 @@ int goodix_fw_update_init(struct goodix_ts_core *core_data)
|
|||
core_data->update_ctrl.update_info = &update_bra;
|
||||
else if (core_data->bus->ic_type == IC_TYPE_BERLIN_B)
|
||||
core_data->update_ctrl.update_info = &update_brb;
|
||||
else if (core_data->bus->ic_type == IC_TYPE_MARSEILLE)
|
||||
core_data->update_ctrl.update_info = &update_mar;
|
||||
else
|
||||
core_data->update_ctrl.update_info = &update_brd;
|
||||
|
||||
|
|
|
|||
|
|
@ -1585,7 +1585,8 @@ static int brl_get_capacitance_data(struct goodix_ts_core *cd,
|
|||
}
|
||||
|
||||
if (cd->bus->ic_type == IC_TYPE_BERLIN_D ||
|
||||
cd->bus->ic_type == IC_TYPE_NOTTINGHAM)
|
||||
cd->bus->ic_type == IC_TYPE_NOTTINGHAM ||
|
||||
cd->bus->ic_type == IC_TYPE_MARSEILLE)
|
||||
return brld_get_cap_data(cd, info);
|
||||
|
||||
/* disable irq & close esd */
|
||||
|
|
|
|||
|
|
@ -208,6 +208,7 @@ static const struct of_device_id i2c_matchs[] = {
|
|||
{.compatible = "goodix,brl-b",},
|
||||
{.compatible = "goodix,brl-d",},
|
||||
{.compatible = "goodix,nottingham",},
|
||||
{.compatible = "goodix,marseille",},
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, i2c_matchs);
|
||||
|
|
|
|||
|
|
@ -222,6 +222,8 @@ static int goodix_spi_probe(struct spi_device *spi)
|
|||
dev_res->pdev.id = dev_res->id;
|
||||
dev_res->pdev.num_resources = 0;
|
||||
|
||||
spi_set_drvdata(spi, &dev_res->pdev);
|
||||
|
||||
/* register platform device, then the goodix_ts_core
|
||||
* module will probe the touch deivce.
|
||||
*/
|
||||
|
|
@ -245,6 +247,7 @@ static const struct of_device_id spi_matchs[] = {
|
|||
{.compatible = "goodix,brl-b",},
|
||||
{.compatible = "goodix,brl-d",},
|
||||
{.compatible = "goodix,nottingham",},
|
||||
{.compatible = "goodix,marseille",},
|
||||
{},
|
||||
};
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -23,12 +23,15 @@
|
|||
#include <linux/input/mt.h>
|
||||
#define INPUT_TYPE_B_PROTOCOL
|
||||
#endif
|
||||
#include "goodix_ts_mmi.h"
|
||||
|
||||
/* goodix fb test */
|
||||
// #include "../../../video/fbdev/core/fb_firefly.h"
|
||||
|
||||
#define GOODIX_DEFAULT_CFG_NAME "goodix_cfg_group.cfg"
|
||||
struct goodix_device_manager goodix_devices;
|
||||
#define PINCTRL_STATE_ACTIVE "cli_pmx_ts_active"
|
||||
#define PINCTRL_STATE_SUSPEND "cli_pmx_ts_suspend"
|
||||
|
||||
static void goodix_device_manager_init(void)
|
||||
{
|
||||
|
|
@ -886,6 +889,16 @@ static int goodix_parse_dt(struct device_node *node,
|
|||
board_data->pen_enable = of_property_read_bool(node,
|
||||
"goodix,pen-enable");
|
||||
|
||||
/* get ic compatible */
|
||||
r = of_property_read_string(node, "compatible", &name_tmp);
|
||||
if (r) {
|
||||
ts_err("get compatible failed");
|
||||
return r;
|
||||
} else {
|
||||
ts_info("ic_name form dt: %s", name_tmp);
|
||||
strncpy(board_data->ic_name, name_tmp, sizeof(board_data->ic_name));
|
||||
}
|
||||
|
||||
ts_info("[DT]x:%d, y:%d, w:%d, p:%d sleep_enable:%d pen_enable:%d",
|
||||
board_data->panel_max_x, board_data->panel_max_y,
|
||||
board_data->panel_max_w, board_data->panel_max_p,
|
||||
|
|
@ -1156,6 +1169,54 @@ int goodix_ts_power_off(struct goodix_ts_core *cd)
|
|||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* goodix_ts_pinctrl_init - Get pinctrl handler and pinctrl_state
|
||||
* @core_data: pointer to touch core data
|
||||
* return: 0 ok, <0 failed
|
||||
*/
|
||||
static int goodix_ts_pinctrl_init(struct goodix_ts_core *core_data)
|
||||
{
|
||||
int r = 0;
|
||||
|
||||
/* get pinctrl handler from of node */
|
||||
core_data->pinctrl = devm_pinctrl_get(core_data->bus->dev);
|
||||
if (IS_ERR_OR_NULL(core_data->pinctrl)) {
|
||||
ts_info("Failed to get pinctrl handler[need confirm]");
|
||||
core_data->pinctrl = NULL;
|
||||
return -EINVAL;
|
||||
}
|
||||
ts_debug("success get pinctrl");
|
||||
/* active state */
|
||||
core_data->pin_sta_active = pinctrl_lookup_state(core_data->pinctrl,
|
||||
PINCTRL_STATE_ACTIVE);
|
||||
if (IS_ERR_OR_NULL(core_data->pin_sta_active)) {
|
||||
r = PTR_ERR(core_data->pin_sta_active);
|
||||
ts_err("Failed to get pinctrl state:%s, r:%d",
|
||||
PINCTRL_STATE_ACTIVE, r);
|
||||
core_data->pin_sta_active = NULL;
|
||||
goto exit_pinctrl_put;
|
||||
}
|
||||
ts_info("success get avtive pinctrl state");
|
||||
|
||||
/* suspend state */
|
||||
core_data->pin_sta_suspend = pinctrl_lookup_state(core_data->pinctrl,
|
||||
PINCTRL_STATE_SUSPEND);
|
||||
if (IS_ERR_OR_NULL(core_data->pin_sta_suspend)) {
|
||||
r = PTR_ERR(core_data->pin_sta_suspend);
|
||||
ts_err("Failed to get pinctrl state:%s, r:%d",
|
||||
PINCTRL_STATE_SUSPEND, r);
|
||||
core_data->pin_sta_suspend = NULL;
|
||||
goto exit_pinctrl_put;
|
||||
}
|
||||
ts_info("success get suspend pinctrl state");
|
||||
|
||||
return 0;
|
||||
exit_pinctrl_put:
|
||||
devm_pinctrl_put(core_data->pinctrl);
|
||||
core_data->pinctrl = NULL;
|
||||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
* goodix_ts_gpio_setup - Request gpio resources from GPIO subsysten
|
||||
* @core_data: pointer to touch core data
|
||||
|
|
@ -1233,7 +1294,7 @@ static int goodix_ts_input_dev_config(struct goodix_ts_core *core_data)
|
|||
core_data->input_dev = input_dev;
|
||||
input_set_drvdata(input_dev, core_data);
|
||||
|
||||
sprintf(core_data->input_name, "%s.%d", GOODIX_CORE_DRIVER_NAME, dev_id);
|
||||
sprintf(core_data->input_name, "%s_%d", GOODIX_CORE_DRIVER_NAME, dev_id);
|
||||
|
||||
input_dev->name = core_data->input_name;
|
||||
input_dev->id.bustype = core_data->bus->bus_type;
|
||||
|
|
@ -1443,7 +1504,7 @@ int goodix_ts_esd_init(struct goodix_ts_core *cd)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void goodix_ts_release_connects(struct goodix_ts_core *core_data)
|
||||
void goodix_ts_release_connects(struct goodix_ts_core *core_data)
|
||||
{
|
||||
struct input_dev *input_dev = core_data->input_dev;
|
||||
struct input_dev *pen_dev = core_data->pen_dev;
|
||||
|
|
@ -1473,6 +1534,7 @@ static void goodix_ts_release_connects(struct goodix_ts_core *core_data)
|
|||
core_data->hw_ops->after_event_handler(core_data);
|
||||
}
|
||||
|
||||
#ifndef CONFIG_INPUT_TOUCHSCREEN_MMI
|
||||
/**
|
||||
* goodix_ts_suspend - Touchscreen suspend function
|
||||
* Called by PM/FB/EARLYSUSPEN module to put the device to sleep
|
||||
|
|
@ -1552,6 +1614,7 @@ static void goodix_ts_resume_work(struct work_struct *work)
|
|||
container_of(work, struct goodix_ts_core, resume_work);
|
||||
goodix_ts_resume(cd);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if IS_ENABLED(CONFIG_FB)
|
||||
/**
|
||||
|
|
@ -1580,7 +1643,7 @@ int goodix_ts_fb_notifier_callback(struct notifier_block *self,
|
|||
|
||||
return 0;
|
||||
}
|
||||
#elif IS_ENABLED(CONFIG_PM)
|
||||
#elif IS_ENABLED(CONFIG_PM) && !defined(CONFIG_INPUT_TOUCHSCREEN_MMI)
|
||||
/**
|
||||
* goodix_ts_pm_suspend - PM suspend function
|
||||
* Called by kernel during system suspend phrase
|
||||
|
|
@ -1607,6 +1670,29 @@ static const struct dev_pm_ops dev_pm_ops = {
|
|||
.suspend = goodix_ts_pm_suspend,
|
||||
.resume = goodix_ts_pm_resume,
|
||||
};
|
||||
#else
|
||||
/**
|
||||
* goodix_ts_pm_suspend - PM suspend function
|
||||
* Called by kernel during system suspend phrase
|
||||
*/
|
||||
static int goodix_ts_pm_suspend(struct device *dev)
|
||||
{
|
||||
ts_info("system enters into pm_suspend");
|
||||
return 0;
|
||||
}
|
||||
/**
|
||||
* goodix_ts_pm_resume - PM resume function
|
||||
* Called by kernel during system wakeup
|
||||
*/
|
||||
static int goodix_ts_pm_resume(struct device *dev)
|
||||
{
|
||||
ts_info("system resumes from pm_suspend");
|
||||
return 0;
|
||||
}
|
||||
static const struct dev_pm_ops dev_pm_ops = {
|
||||
.suspend = goodix_ts_pm_suspend,
|
||||
.resume = goodix_ts_pm_resume,
|
||||
};
|
||||
#endif
|
||||
|
||||
static void goodix_self_check(struct work_struct *work)
|
||||
|
|
@ -1679,7 +1765,9 @@ int goodix_ts_stage2_init(struct goodix_ts_core *cd)
|
|||
/* inspect init */
|
||||
inspect_module_init(cd);
|
||||
|
||||
#ifndef CONFIG_INPUT_TOUCHSCREEN_MMI
|
||||
INIT_WORK(&cd->resume_work, goodix_ts_resume_work);
|
||||
#endif
|
||||
|
||||
/* Do self check on first boot */
|
||||
INIT_WORK(&cd->self_check_work, goodix_self_check);
|
||||
|
|
@ -1867,6 +1955,24 @@ static int goodix_ts_probe(struct platform_device *pdev)
|
|||
goto err_out;
|
||||
}
|
||||
|
||||
/* Pinctrl handle is optional. */
|
||||
ret = goodix_ts_pinctrl_init(core_data);
|
||||
if (!ret && core_data->pinctrl) {
|
||||
ret = pinctrl_select_state(core_data->pinctrl,
|
||||
core_data->pin_sta_active);
|
||||
if (ret < 0)
|
||||
ts_err("Failed to select active pinstate, r:%d", ret);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_INPUT_TOUCHSCREEN_MMI
|
||||
ts_info("%s:goodix_ts_mmi_dev_register",__func__);
|
||||
ret = goodix_ts_mmi_dev_register(pdev);
|
||||
if (ret) {
|
||||
ts_info("Failed register touchscreen mmi.");
|
||||
goto err_out;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* debug node init */
|
||||
ret = goodix_tools_init(core_data);
|
||||
if (ret) {
|
||||
|
|
@ -1900,6 +2006,11 @@ static int goodix_ts_remove(struct platform_device *pdev)
|
|||
struct goodix_ts_hw_ops *hw_ops = core_data->hw_ops;
|
||||
struct goodix_ts_esd *ts_esd = &core_data->ts_esd;
|
||||
|
||||
#ifdef CONFIG_INPUT_TOUCHSCREEN_MMI
|
||||
ts_info("%s:goodix_ts_mmi_dev_unregister",__func__);
|
||||
goodix_ts_mmi_dev_unregister(pdev);
|
||||
#endif
|
||||
|
||||
goodix_tools_exit(core_data);
|
||||
goodix_fw_update_uninit(core_data);
|
||||
|
||||
|
|
|
|||
|
|
@ -47,9 +47,9 @@
|
|||
#include <linux/fb.h>
|
||||
#endif
|
||||
|
||||
#define GOODIX_CORE_DRIVER_NAME "goodix_ts"
|
||||
#define GOODIX_CORE_DRIVER_NAME "gdx_cli"
|
||||
#define GOODIX_PEN_DRIVER_NAME "goodix_ts,pen"
|
||||
#define GOODIX_DRIVER_VERSION "v1.3.13"
|
||||
#define GOODIX_DRIVER_VERSION "v1.3.15"
|
||||
#define GOODIX_MAX_TOUCH 10
|
||||
#define GOODIX_MAX_KEY 10
|
||||
#define GOODIX_PEN_MAX_PRESSURE 4096
|
||||
|
|
@ -117,7 +117,8 @@ enum IC_TYPE_ID {
|
|||
IC_TYPE_BERLIN_A,
|
||||
IC_TYPE_BERLIN_B,
|
||||
IC_TYPE_BERLIN_D,
|
||||
IC_TYPE_NOTTINGHAM
|
||||
IC_TYPE_NOTTINGHAM,
|
||||
IC_TYPE_MARSEILLE
|
||||
};
|
||||
|
||||
/* SUB-ID
|
||||
|
|
@ -439,6 +440,7 @@ struct goodix_module {
|
|||
* @fw_name: name of the firmware image
|
||||
*/
|
||||
struct goodix_ts_board_data {
|
||||
char ic_name[GOODIX_MAX_STR_LABLE_LEN];
|
||||
char avdd_name[GOODIX_MAX_STR_LABLE_LEN];
|
||||
char iovdd_name[GOODIX_MAX_STR_LABLE_LEN];
|
||||
int reset_gpio;
|
||||
|
|
@ -735,6 +737,9 @@ struct goodix_ts_core {
|
|||
struct goodix_ic_config ic_configs[GOODIX_MAX_CONFIG_GROUP];
|
||||
struct regulator *avdd;
|
||||
struct regulator *iovdd;
|
||||
struct pinctrl *pinctrl;
|
||||
struct pinctrl_state *pin_sta_active;
|
||||
struct pinctrl_state *pin_sta_suspend;
|
||||
u32 gesture_type;
|
||||
|
||||
char input_name[32];
|
||||
|
|
@ -777,12 +782,23 @@ extern int goodix_device_register(struct goodix_device_resource *device);
|
|||
/* log macro */
|
||||
extern bool debug_log_flag;
|
||||
#define ts_info(fmt, arg...) \
|
||||
pr_info("[GTP-INF][%s] "fmt"\n", __func__, ##arg)
|
||||
pr_info("[GDX-CLI-INF][%s] "fmt"\n", __func__, ##arg)
|
||||
#define ts_err(fmt, arg...) \
|
||||
pr_err("[GTP-ERR][%s] "fmt"\n", __func__, ##arg)
|
||||
pr_err("[GDX-CLI-ERR][%s] "fmt"\n", __func__, ##arg)
|
||||
#define ts_debug(fmt, arg...) \
|
||||
{if (debug_log_flag) \
|
||||
pr_info("[GTP-DBG][%s] "fmt"\n", __func__, ##arg);}
|
||||
pr_info("[GDX-CLI-DBG][%s] "fmt"\n", __func__, ##arg);}
|
||||
|
||||
/*
|
||||
* get board data pointer
|
||||
*/
|
||||
static inline struct goodix_ts_board_data *board_data(
|
||||
struct goodix_ts_core *core)
|
||||
{
|
||||
if (!core)
|
||||
return NULL;
|
||||
return &(core->board_data);
|
||||
}
|
||||
|
||||
struct goodix_ts_hw_ops *goodix_get_hw_ops(void);
|
||||
int goodix_get_config_proc(struct goodix_ts_core *cd);
|
||||
|
|
@ -814,4 +830,8 @@ void goodix_ts_esd_off(struct goodix_ts_core *cd);
|
|||
|
||||
int goodix_ts_report_gesture(struct goodix_ts_core *cd, struct goodix_ts_event *event);
|
||||
|
||||
int goodix_ts_power_on(struct goodix_ts_core *cd);
|
||||
int goodix_ts_power_off(struct goodix_ts_core *cd);
|
||||
void goodix_ts_release_connects(struct goodix_ts_core *core_data);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@
|
|||
|
||||
#define DISCARD_FRAMES 3
|
||||
|
||||
#define GOODIX_TEST_FILE_NAME "goodix_test_limits"
|
||||
#define GOODIX_TEST_FILE_NAME "gdx_test_limits"
|
||||
#define MAX_PROC_OUTPUT_SIZE 2 * 1024 * 1024
|
||||
#define MAX_DATA_BUFFER 30000
|
||||
#define MAX_SHORT_NUM 15
|
||||
|
|
@ -112,6 +112,17 @@
|
|||
#define DRV_SEN_SELFCODE_REG_NOT 0x14152
|
||||
#define DIFF_CODE_DATA_REG_NOT 0x14734
|
||||
|
||||
/* marseille */
|
||||
#define MAX_DRV_NUM_MAR 20
|
||||
#define MAX_SEN_NUM_MAR 34
|
||||
#define SHORT_TEST_TIME_REG_MAR 0x138AC
|
||||
#define SHORT_TEST_STATUS_REG_MAR 0x12400
|
||||
#define SHORT_TEST_RESULT_REG_MAR 0x12408
|
||||
#define DRV_DRV_SELFCODE_REG_MAR 0x12448
|
||||
#define SEN_SEN_SELFCODE_REG_MAR 0x127E0
|
||||
#define DRV_SEN_SELFCODE_REG_MAR 0x137D0
|
||||
#define DIFF_CODE_DATA_REG_MAR 0x1383E
|
||||
|
||||
|
||||
#define ABS(val) ((val < 0)? -(val) : val)
|
||||
#define MAX(a, b) ((a > b)? a : b)
|
||||
|
|
@ -144,6 +155,7 @@ enum GTP_MUTUAL_DATA_TYPE {
|
|||
|
||||
static int output_offset;
|
||||
static char *output_buf;
|
||||
static bool auto_test_result;
|
||||
|
||||
/* berlin A drv-sen map */
|
||||
static u8 brl_a_drv_map[] = {
|
||||
|
|
@ -212,6 +224,19 @@ static u8 not_sen_map[] = {
|
|||
28, 29, 30, 31, 32, 33, 34
|
||||
};
|
||||
|
||||
/* marseille drv-sen map */
|
||||
static u8 mar_drv_map[] = {
|
||||
34, 35, 36, 37, 38, 39, 40, 41, 42, 43,
|
||||
44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
|
||||
};
|
||||
|
||||
static u8 mar_sen_map[] = {
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
|
||||
10, 11, 12, 13, 14, 15, 16, 17, 18,
|
||||
19, 20, 21, 22, 23, 24, 25, 26, 27,
|
||||
28, 29, 30, 31, 32, 33
|
||||
};
|
||||
|
||||
typedef struct __attribute__((packed)) {
|
||||
u8 result;
|
||||
u8 drv_drv_num;
|
||||
|
|
@ -322,6 +347,23 @@ struct params_info_t params_not = {
|
|||
0,
|
||||
};
|
||||
|
||||
struct params_info_t params_mar = {
|
||||
MAX_DRV_NUM_MAR,
|
||||
MAX_SEN_NUM_MAR,
|
||||
mar_drv_map,
|
||||
mar_sen_map,
|
||||
SHORT_TEST_TIME_REG_MAR,
|
||||
SHORT_TEST_STATUS_REG_MAR,
|
||||
SHORT_TEST_RESULT_REG_MAR,
|
||||
DRV_DRV_SELFCODE_REG_MAR,
|
||||
SEN_SEN_SELFCODE_REG_MAR,
|
||||
DRV_SEN_SELFCODE_REG_MAR,
|
||||
DIFF_CODE_DATA_REG_MAR,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
};
|
||||
|
||||
struct ts_test_params {
|
||||
bool test_items[MAX_TEST_ITEMS];
|
||||
|
||||
|
|
@ -402,8 +444,10 @@ static int cal_cha_to_cha_res(struct goodix_ts_test *ts_test, int v1, int v2)
|
|||
return (v1 - v2) * 74 / v2 + 20;
|
||||
else if (ts_test->ts->bus->ic_type == IC_TYPE_BERLIN_D)
|
||||
return (v1 / v2 - 1) * 70 + 59;
|
||||
else if (ts_test->ts->bus->ic_type == IC_TYPE_MARSEILLE)
|
||||
return (v1 / v2 - 1) * 14;
|
||||
else
|
||||
return (v1 / v2 - 1) * 55 + 45;
|
||||
return (v1 / v2 - 1) * 55 + 45; // nottingham
|
||||
}
|
||||
|
||||
static int cal_cha_to_avdd_res(struct goodix_ts_test *ts_test, int v1, int v2)
|
||||
|
|
@ -414,8 +458,10 @@ static int cal_cha_to_avdd_res(struct goodix_ts_test *ts_test, int v1, int v2)
|
|||
return 64 * (2 * v2 - 25) * 99 / v1 - 60;
|
||||
else if (ts_test->ts->bus->ic_type == IC_TYPE_BERLIN_D)
|
||||
return 64 * (2 * v2 - 25) * 93 / v1 - 20;
|
||||
else if (ts_test->ts->bus->ic_type == IC_TYPE_MARSEILLE)
|
||||
return 64 * (2 * v2 - 25) * 72 / v1 - 13;
|
||||
else
|
||||
return 64 * (2 * v2 - 25) * 76 / v1 - 15;
|
||||
return 64 * (2 * v2 - 25) * 76 / v1 - 15; // nottingham
|
||||
}
|
||||
|
||||
static int cal_cha_to_gnd_res(struct goodix_ts_test *ts_test, int v)
|
||||
|
|
@ -426,8 +472,10 @@ static int cal_cha_to_gnd_res(struct goodix_ts_test *ts_test, int v)
|
|||
return 150500 / v - 60;
|
||||
else if (ts_test->ts->bus->ic_type == IC_TYPE_BERLIN_D)
|
||||
return 145000 / v - 15;
|
||||
else if (ts_test->ts->bus->ic_type == IC_TYPE_MARSEILLE)
|
||||
return 28800 / v - 13;
|
||||
else
|
||||
return 120000 / v - 16;
|
||||
return 120000 / v - 16; // nottingham
|
||||
}
|
||||
|
||||
static int ts_test_reset(struct goodix_ts_test *ts_test,
|
||||
|
|
@ -659,6 +707,8 @@ static void goodix_init_params(struct goodix_ts_test *ts_test)
|
|||
test_params->params_info = ¶ms_brd;
|
||||
else if (ts_test->ts->bus->ic_type == IC_TYPE_NOTTINGHAM)
|
||||
test_params->params_info = ¶ms_not;
|
||||
else if (ts_test->ts->bus->ic_type == IC_TYPE_MARSEILLE)
|
||||
test_params->params_info = ¶ms_mar;
|
||||
}
|
||||
|
||||
static int goodix_init_testlimits(struct goodix_ts_test *ts_test)
|
||||
|
|
@ -1414,6 +1464,27 @@ static void goodix_shortcircut_test(struct goodix_ts_test *ts_test)
|
|||
return;
|
||||
}
|
||||
|
||||
if (ts_test->ts->bus->ic_type == IC_TYPE_MARSEILLE) {
|
||||
ts_test_read(ts_test, 0x10400, &status, 1);
|
||||
if (status != 0xFD) {
|
||||
ts_err("marseille short status[0x%02x] != 0xFD", status);
|
||||
return;
|
||||
}
|
||||
status = 0;
|
||||
ts_test_write(ts_test, 0x10400, &status, 1);
|
||||
retry = 20;
|
||||
while (retry--) {
|
||||
msleep(20);
|
||||
ts_test_read(ts_test, 0x10400, &status, 1);
|
||||
if (status == 0xAA)
|
||||
break;
|
||||
}
|
||||
if (retry < 0) {
|
||||
ts_err("marseille short status[0x%02x] != 0xAA", status);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
msleep(500); //BerlinB quick check need to delay at least 500ms
|
||||
|
||||
/* get short test time */
|
||||
|
|
@ -1495,7 +1566,8 @@ static int goodix_cap_test_prepare(struct goodix_ts_test *ts_test)
|
|||
|
||||
/* switch rawdata mode */
|
||||
if (ts_test->ts->bus->ic_type == IC_TYPE_BERLIN_D ||
|
||||
ts_test->ts->bus->ic_type == IC_TYPE_NOTTINGHAM) {
|
||||
ts_test->ts->bus->ic_type == IC_TYPE_NOTTINGHAM ||
|
||||
ts_test->ts->bus->ic_type == IC_TYPE_MARSEILLE) {
|
||||
temp_cmd.cmd = 0x90;
|
||||
temp_cmd.data[0] = 0x81;
|
||||
temp_cmd.len = 5;
|
||||
|
|
@ -1532,7 +1604,8 @@ static int goodix_poll_rawdata(struct goodix_ts_test *ts_test, u8 data_type, u8
|
|||
int retry;
|
||||
|
||||
if (ts_test->ts->bus->ic_type == IC_TYPE_BERLIN_D ||
|
||||
ts_test->ts->bus->ic_type == IC_TYPE_NOTTINGHAM)
|
||||
ts_test->ts->bus->ic_type == IC_TYPE_NOTTINGHAM ||
|
||||
ts_test->ts->bus->ic_type == IC_TYPE_MARSEILLE)
|
||||
flag_addr = ts_test->ts->ic_info.misc.frame_data_addr;
|
||||
|
||||
if (data_type == GTP_MUTUAL_RAW) {
|
||||
|
|
@ -1563,7 +1636,8 @@ static int goodix_poll_rawdata(struct goodix_ts_test *ts_test, u8 data_type, u8
|
|||
|
||||
frame_buf = kzalloc(FRAME_DATA_MAX_SIZE, GFP_KERNEL);
|
||||
if (cd->bus->ic_type == IC_TYPE_BERLIN_D ||
|
||||
cd->bus->ic_type == IC_TYPE_NOTTINGHAM) {
|
||||
cd->bus->ic_type == IC_TYPE_NOTTINGHAM ||
|
||||
cd->bus->ic_type == IC_TYPE_MARSEILLE) {
|
||||
ret = ts_test_read(ts_test, flag_addr, frame_buf, FRAME_DATA_MAX_SIZE);
|
||||
if (ret < 0)
|
||||
goto free_exit;
|
||||
|
|
@ -1611,7 +1685,8 @@ static int goodix_cache_rawdata(struct goodix_ts_test *ts_test)
|
|||
u32 flag_addr = ts_test->ts->ic_info.misc.touch_data_addr;
|
||||
|
||||
if (ts_test->ts->bus->ic_type == IC_TYPE_BERLIN_D ||
|
||||
ts_test->ts->bus->ic_type == IC_TYPE_NOTTINGHAM)
|
||||
ts_test->ts->bus->ic_type == IC_TYPE_NOTTINGHAM ||
|
||||
ts_test->ts->bus->ic_type == IC_TYPE_MARSEILLE)
|
||||
flag_addr = ts_test->ts->ic_info.misc.frame_data_addr;
|
||||
|
||||
for (i = 0; i < DISCARD_FRAMES; i++) {
|
||||
|
|
@ -1717,7 +1792,8 @@ static int goodix_cache_noisedata(struct goodix_ts_test *ts_test)
|
|||
u32 flag_addr = ts_test->ts->ic_info.misc.touch_data_addr;
|
||||
|
||||
if (cd->bus->ic_type == IC_TYPE_BERLIN_D ||
|
||||
cd->bus->ic_type == IC_TYPE_NOTTINGHAM) {
|
||||
cd->bus->ic_type == IC_TYPE_NOTTINGHAM ||
|
||||
cd->bus->ic_type == IC_TYPE_MARSEILLE) {
|
||||
flag_addr = ts_test->ts->ic_info.misc.frame_data_addr;
|
||||
temp_cmd.cmd = 0x90;
|
||||
temp_cmd.data[0] = 0x82;
|
||||
|
|
@ -2048,7 +2124,8 @@ static void goodix_check_key_info_test(struct goodix_ts_test *ts_test)
|
|||
//read chip load info for berlin
|
||||
if (cd->bus->ic_type == IC_TYPE_BERLIN_B ||
|
||||
cd->bus->ic_type == IC_TYPE_BERLIN_D ||
|
||||
cd->bus->ic_type == IC_TYPE_NOTTINGHAM) {
|
||||
cd->bus->ic_type == IC_TYPE_NOTTINGHAM ||
|
||||
cd->bus->ic_type == IC_TYPE_MARSEILLE) {
|
||||
if (cd->bus->ic_type == IC_TYPE_BERLIN_B)
|
||||
chip_info_addr = 0x3F300;
|
||||
else
|
||||
|
|
@ -2208,6 +2285,8 @@ static int goodix_save_header(struct goodix_ts_test *ts_test)
|
|||
proc_append_string("<Result>%s</Result>\n", result ? "NG" : "OK");
|
||||
proc_append_string("<DeviceType>GT%s</DeviceType>\n<SensorId>%d</SensorId>\n",
|
||||
ts->fw_version.patch_pid, ts->fw_version.sensor_id);
|
||||
auto_test_result = !result;
|
||||
ts_info("GT%s TP test total result: %d", ts->fw_version.patch_pid, auto_test_result);
|
||||
|
||||
/* save test config */
|
||||
goodix_save_test_config(ts_test);
|
||||
|
|
@ -2220,64 +2299,82 @@ static int goodix_save_header(struct goodix_ts_test *ts_test)
|
|||
if (ts_test->test_params.test_items[GTP_VERSION_TEST]) {
|
||||
if (GTP_TEST_OK == ts_test->test_result[GTP_VERSION_TEST])
|
||||
proc_append_string("<Item name=\"Version Test\" result=\"OK\"/>\n");
|
||||
else
|
||||
proc_append_string("<Item name=\"Version Test\" result=\"NG\"/>\n");
|
||||
else {
|
||||
proc_append_string("<Item name=\"Version Test\" result=\"NG\"/>\n");
|
||||
ts_err("<Item name=\"Version Test\" result=\"NG\"/>\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (ts_test->test_params.test_items[GTP_CHIP_KEY_INFO_TEST]) {
|
||||
if (GTP_TEST_OK == ts_test->test_result[GTP_CHIP_KEY_INFO_TEST])
|
||||
proc_append_string("<Item name=\"Check Chip Key Info\" result=\"OK\"/>\n");
|
||||
else
|
||||
proc_append_string("<Item name=\"Check Chip Key Info\" result=\"NG\"/>\n");
|
||||
else {
|
||||
proc_append_string("<Item name=\"Check Chip Key Info\" result=\"NG\"/>\n");
|
||||
ts_err("<Item name=\"Check Chip Key Info\" result=\"NG\"/>\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (ts_test->test_params.test_items[GTP_CUSTOM_INFO_TEST]) {
|
||||
if (GTP_TEST_OK == ts_test->test_result[GTP_CUSTOM_INFO_TEST])
|
||||
proc_append_string("<Item name=\"Custom Info Test\" result=\"OK\"/>\n");
|
||||
else
|
||||
proc_append_string("<Item name=\"Custom Info Test\" result=\"NG\"/>\n");
|
||||
else {
|
||||
proc_append_string("<Item name=\"Custom Info Test\" result=\"NG\"/>\n");
|
||||
ts_err("<Item name=\"Custom Info Test\" result=\"NG\"/>\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (ts_test->test_params.test_items[GTP_CAP_TEST]) {
|
||||
if (GTP_TEST_OK == ts_test->test_result[GTP_CAP_TEST])
|
||||
proc_append_string("<Item name=\"Rawdata MAX/MIN Test\" result=\"OK\"/>\n");
|
||||
else
|
||||
proc_append_string("<Item name=\"Rawdata MAX/MIN Test\" result=\"NG\"/>\n");
|
||||
else {
|
||||
proc_append_string("<Item name=\"Rawdata MAX/MIN Test\" result=\"NG\"/>\n");
|
||||
ts_err("<Item name=\"Rawdata MAX/MIN Test\" result=\"NG\"/>\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (ts_test->test_params.test_items[GTP_DELTA_TEST]) {
|
||||
if (GTP_TEST_OK == ts_test->test_result[GTP_DELTA_TEST])
|
||||
proc_append_string("<Item name=\"Rawdata Adjcent Deviation Test\" result=\"OK\"/>\n");
|
||||
else
|
||||
proc_append_string("<Item name=\"Rawdata Adjcent Deviation Test\" result=\"NG\"/>\n");
|
||||
else {
|
||||
proc_append_string("<Item name=\"Rawdata Adjcent Deviation Test\" result=\"NG\"/>\n");
|
||||
ts_err("<Item name=\"Rawdata Adjcent Deviation Test\" result=\"NG\"/>\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (ts_test->test_params.test_items[GTP_NOISE_TEST]) {
|
||||
if (GTP_TEST_OK == ts_test->test_result[GTP_NOISE_TEST])
|
||||
proc_append_string("<Item name=\"Diffdata Jitter Test\" result=\"OK\"/>\n");
|
||||
else
|
||||
proc_append_string("<Item name=\"Diffdata Jitter Test\" result=\"NG\"/>\n");
|
||||
else {
|
||||
proc_append_string("<Item name=\"Diffdata Jitter Test\" result=\"NG\"/>\n");
|
||||
ts_err("<Item name=\"Diffdata Jitter Test\" result=\"NG\"/>\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (ts_test->test_params.test_items[GTP_SELFNOISE_TEST]) {
|
||||
if (GTP_TEST_OK == ts_test->test_result[GTP_SELFNOISE_TEST])
|
||||
proc_append_string("<Item name=\"Self Diffdata Jitter Limit Test\" result=\"OK\"/>\n");
|
||||
else
|
||||
proc_append_string("<Item name=\"Self Diffdata Jitter Limit Test\" result=\"NG\"/>\n");
|
||||
else {
|
||||
proc_append_string("<Item name=\"Self Diffdata Jitter Limit Test\" result=\"NG\"/>\n");
|
||||
ts_err("<Item name=\"Self Diffdata Jitter Limit Test\" result=\"NG\"/>\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (ts_test->test_params.test_items[GTP_SELFCAP_TEST]) {
|
||||
if (GTP_TEST_OK == ts_test->test_result[GTP_SELFCAP_TEST])
|
||||
proc_append_string("<Item name=\"Self Rawdata Upper Limit Test\" result=\"OK\"/>\n");
|
||||
else
|
||||
proc_append_string("<Item name=\"Self Rawdata Upper Limit Test\" result=\"NG\"/>\n");
|
||||
else {
|
||||
proc_append_string("<Item name=\"Self Rawdata Upper Limit Test\" result=\"NG\"/>\n");
|
||||
ts_err("<Item name=\"Self Rawdata Upper Limit Test\" result=\"NG\"/>\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (ts_test->test_params.test_items[GTP_SHORT_TEST]) {
|
||||
if (GTP_TEST_OK == ts_test->test_result[GTP_SHORT_TEST])
|
||||
proc_append_string("<Item name=\"Short Test\" result=\"OK\"/>\n");
|
||||
else
|
||||
proc_append_string("<Item name=\"Short Test\" result=\"NG\"/>\n");
|
||||
else {
|
||||
proc_append_string("<Item name=\"Short Test\" result=\"NG\"/>\n");
|
||||
ts_err("<Item name=\"Short Test\" result=\"NG\"/>\n");
|
||||
}
|
||||
}
|
||||
|
||||
proc_append_string("</ItemList>\n");
|
||||
|
|
@ -2748,9 +2845,46 @@ static const struct file_operations auto_test_ops = {
|
|||
};
|
||||
#endif
|
||||
|
||||
static int auto_test_result_proc_show(struct seq_file *file, void *v)
|
||||
{
|
||||
struct goodix_ts_core * core_data = (struct goodix_ts_core *)file->private;
|
||||
if (!core_data) {
|
||||
ts_err("no goodix_ts_core set");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
seq_printf(file, "result=%d\n", auto_test_result);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int auto_test_result_proc_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
return single_open_size(file, auto_test_result_proc_show, PDE_DATA(inode), PAGE_SIZE * 10);
|
||||
}
|
||||
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 6, 0)
|
||||
static const struct file_operations auto_test_result_ops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = auto_test_result_proc_open,
|
||||
.read = seq_read,
|
||||
.llseek = seq_lseek,
|
||||
.release = seq_release,
|
||||
};
|
||||
#else
|
||||
static const struct proc_ops auto_test_result_ops = {
|
||||
.proc_open = auto_test_result_proc_open,
|
||||
.proc_read = seq_read,
|
||||
.proc_lseek = seq_lseek,
|
||||
.proc_release = single_release,
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
int inspect_module_init(struct goodix_ts_core *core_data)
|
||||
{
|
||||
struct proc_dir_entry *proc_entry;
|
||||
struct proc_dir_entry *result_proc_entry;
|
||||
|
||||
proc_entry = proc_create_data("auto_test",
|
||||
0660, core_data->proc_dir_entry, &auto_test_ops, core_data);
|
||||
|
|
@ -2759,6 +2893,13 @@ int inspect_module_init(struct goodix_ts_core *core_data)
|
|||
return -ENODEV;
|
||||
}
|
||||
|
||||
result_proc_entry = proc_create_data("auto_test_result",
|
||||
0660, core_data->proc_dir_entry, &auto_test_result_ops, core_data);
|
||||
if (!result_proc_entry) {
|
||||
ts_err("failed to create auto_test_result proc entry");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
ts_info("inspect module init success");
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
320
drivers/input/touchscreen/goodix_gt96x_mmi/goodix_ts_mmi.c
Normal file
320
drivers/input/touchscreen/goodix_gt96x_mmi/goodix_ts_mmi.c
Normal file
|
|
@ -0,0 +1,320 @@
|
|||
/*
|
||||
* Copyright (C) 2023 Motorola Mobility LLC
|
||||
*
|
||||
* This software is licensed under the terms of the GNU General Public
|
||||
* License version 2, as published by the Free Software Foundation, and
|
||||
* may be copied, distributed, and modified under those terms.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "goodix_ts_mmi.h"
|
||||
#include <linux/delay.h>
|
||||
#include <linux/input/mt.h>
|
||||
|
||||
#define GET_GOODIX_DATA(dev) { \
|
||||
pdev = dev_get_drvdata(dev); \
|
||||
if (!pdev) { \
|
||||
ts_err("Failed to get platform device"); \
|
||||
return -ENODEV; \
|
||||
} \
|
||||
core_data = platform_get_drvdata(pdev); \
|
||||
if (!core_data) { \
|
||||
ts_err("Failed to get driver data"); \
|
||||
return -ENODEV; \
|
||||
} \
|
||||
}
|
||||
|
||||
static int goodix_ts_mmi_methods_get_vendor(struct device *dev, void *cdata) {
|
||||
return scnprintf(TO_CHARP(cdata), TS_MMI_MAX_VENDOR_LEN, "%s", "goodix");
|
||||
}
|
||||
|
||||
static int goodix_ts_mmi_methods_get_productinfo(struct device *dev, void *cdata) {
|
||||
struct platform_device *pdev;
|
||||
struct goodix_ts_core *core_data;
|
||||
struct goodix_ts_board_data *ts_bdata;
|
||||
char* ic_info;
|
||||
|
||||
GET_GOODIX_DATA(dev);
|
||||
|
||||
ts_bdata = board_data(core_data);
|
||||
if (!ts_bdata) {
|
||||
ts_err("Failed to get ts board data");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
ic_info = strstr(ts_bdata->ic_name, ",");
|
||||
ic_info++;
|
||||
|
||||
return scnprintf(TO_CHARP(cdata), TS_MMI_MAX_VENDOR_LEN, "%s", ic_info);
|
||||
}
|
||||
|
||||
#define TOUCH_CFG_VERSION_ADDR 0x10076
|
||||
static int goodix_ts_mmi_methods_get_build_id(struct device *dev, void *cdata) {
|
||||
int ret;
|
||||
struct platform_device *pdev;
|
||||
struct goodix_ts_core *core_data;
|
||||
u32 cfg_id;
|
||||
|
||||
GET_GOODIX_DATA(dev);
|
||||
|
||||
ret = core_data->hw_ops->read(core_data, TOUCH_CFG_VERSION_ADDR,
|
||||
(u8*)&cfg_id, sizeof(cfg_id));
|
||||
if (ret) {
|
||||
ts_info("failed get fw version data, %d", ret);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return snprintf(TO_CHARP(cdata), TS_MMI_MAX_ID_LEN, "%04x", le32_to_cpu(cfg_id));
|
||||
}
|
||||
|
||||
#define TOUCH_FW_VERSION_ADDR 0x1007E
|
||||
/*return firmware version*/
|
||||
static int goodix_ts_mmi_methods_get_config_id(struct device *dev, void *cdata) {
|
||||
int ret;
|
||||
struct platform_device *pdev;
|
||||
struct goodix_ts_core *core_data;
|
||||
u8 fw_id[4] = {0};
|
||||
|
||||
GET_GOODIX_DATA(dev);
|
||||
|
||||
ret = core_data->hw_ops->read(core_data, TOUCH_FW_VERSION_ADDR,
|
||||
fw_id, sizeof(fw_id));
|
||||
if (ret) {
|
||||
ts_info("failed get fw version data, %d", ret);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return snprintf(TO_CHARP(cdata), TS_MMI_MAX_ID_LEN, "%02x%02x%02x%02x",
|
||||
fw_id[0], fw_id[1], fw_id[2], fw_id[3]);
|
||||
}
|
||||
|
||||
static int goodix_ts_mmi_methods_get_bus_type(struct device *dev, void *idata) {
|
||||
struct platform_device *pdev;
|
||||
struct goodix_ts_core *core_data;
|
||||
|
||||
GET_GOODIX_DATA(dev);
|
||||
|
||||
TO_INT(idata) = core_data->bus->bus_type == GOODIX_BUS_TYPE_I2C ?
|
||||
TOUCHSCREEN_MMI_BUS_TYPE_I2C : TOUCHSCREEN_MMI_BUS_TYPE_SPI;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int goodix_ts_mmi_methods_get_irq_status(struct device *dev, void *idata) {
|
||||
struct platform_device *pdev;
|
||||
struct goodix_ts_core *core_data;
|
||||
struct goodix_ts_board_data *ts_bdata;
|
||||
|
||||
GET_GOODIX_DATA(dev);
|
||||
|
||||
ts_bdata = board_data(core_data);
|
||||
if (!ts_bdata) {
|
||||
ts_err("Failed to get ts board data");
|
||||
return -ENODEV;
|
||||
}
|
||||
TO_INT(idata) = gpio_get_value(ts_bdata->irq_gpio);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int goodix_ts_mmi_methods_get_drv_irq(struct device *dev, void *idata) {
|
||||
struct platform_device *pdev;
|
||||
struct goodix_ts_core *core_data;
|
||||
|
||||
GET_GOODIX_DATA(dev);
|
||||
|
||||
TO_INT(idata) = atomic_read(&core_data->irq_enabled);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int goodix_ts_mmi_methods_get_poweron(struct device *dev, void *idata) {
|
||||
struct platform_device *pdev;
|
||||
struct goodix_ts_core *core_data;
|
||||
|
||||
GET_GOODIX_DATA(dev);
|
||||
|
||||
TO_INT(idata) = core_data->power_on;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int goodix_ts_mmi_methods_get_flashprog(struct device *dev, void *idata) {
|
||||
struct platform_device *pdev;
|
||||
struct goodix_ts_core *core_data;
|
||||
|
||||
GET_GOODIX_DATA(dev);
|
||||
|
||||
TO_INT(idata) = core_data->update_ctrl.status;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* reset chip
|
||||
* type:can control software reset and hardware reset,
|
||||
* but GOODIX has no software reset,
|
||||
* so the type parameter is not used here.
|
||||
*/
|
||||
static int goodix_ts_mmi_methods_reset(struct device *dev, int type) {
|
||||
int ret = -ENODEV;
|
||||
struct platform_device *pdev;
|
||||
struct goodix_ts_core *core_data;
|
||||
|
||||
GET_GOODIX_DATA(dev);
|
||||
|
||||
if (core_data->hw_ops->reset)
|
||||
ret = core_data->hw_ops->reset(core_data, GOODIX_NORMAL_RESET_DELAY_MS);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int goodix_ts_mmi_methods_drv_irq(struct device *dev, int state) {
|
||||
int ret = -ENODEV;
|
||||
struct platform_device *pdev;
|
||||
struct goodix_ts_core *core_data;
|
||||
|
||||
GET_GOODIX_DATA(dev);
|
||||
|
||||
if (core_data->hw_ops->irq_enable)
|
||||
ret = core_data->hw_ops->irq_enable(core_data, !(!state));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int goodix_ts_mmi_methods_power(struct device *dev, int on) {
|
||||
struct platform_device *pdev;
|
||||
struct goodix_ts_core *core_data;
|
||||
|
||||
GET_GOODIX_DATA(dev);
|
||||
|
||||
if (on == TS_MMI_POWER_ON)
|
||||
return goodix_ts_power_on(core_data);
|
||||
else if(on == TS_MMI_POWER_OFF)
|
||||
return goodix_ts_power_off(core_data);
|
||||
else {
|
||||
ts_err("Invalid power parameter %d.\n", on);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
static int goodix_ts_mmi_pre_suspend(struct device *dev) {
|
||||
struct platform_device *pdev;
|
||||
struct goodix_ts_core *core_data;
|
||||
|
||||
GET_GOODIX_DATA(dev);
|
||||
|
||||
ts_info("Suspend start");
|
||||
atomic_set(&core_data->suspended, 1);
|
||||
|
||||
/*
|
||||
* notify suspend event, inform the esd protector
|
||||
* and charger detector to turn off the work
|
||||
*/
|
||||
goodix_ts_esd_off(core_data);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int goodix_ts_mmi_panel_state(struct device *dev,
|
||||
enum ts_mmi_pm_mode from, enum ts_mmi_pm_mode to)
|
||||
{
|
||||
struct platform_device *pdev;
|
||||
struct goodix_ts_core *core_data;
|
||||
|
||||
GET_GOODIX_DATA(dev);
|
||||
|
||||
switch (to) {
|
||||
case TS_MMI_PM_GESTURE:
|
||||
break;
|
||||
case TS_MMI_PM_DEEPSLEEP:
|
||||
break;
|
||||
case TS_MMI_PM_ACTIVE:
|
||||
break;
|
||||
default:
|
||||
ts_err("Invalid power state parameter %d.\n", to);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int goodix_ts_mmi_post_suspend(struct device *dev) {
|
||||
struct goodix_ts_core *core_data;
|
||||
struct platform_device *pdev;
|
||||
|
||||
GET_GOODIX_DATA(dev);
|
||||
|
||||
goodix_ts_release_connects(core_data);
|
||||
|
||||
ts_info("Suspend end");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int goodix_ts_mmi_pre_resume(struct device *dev) {
|
||||
struct platform_device *pdev;
|
||||
struct goodix_ts_core *core_data;
|
||||
|
||||
ts_info("Resume start");
|
||||
GET_GOODIX_DATA(dev);
|
||||
|
||||
atomic_set(&core_data->suspended, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int goodix_ts_mmi_post_resume(struct device *dev) {
|
||||
struct platform_device *pdev;
|
||||
struct goodix_ts_core *core_data;
|
||||
|
||||
GET_GOODIX_DATA(dev);
|
||||
|
||||
/* open esd */
|
||||
goodix_ts_esd_on(core_data);
|
||||
ts_info("Resume end");
|
||||
return 0;
|
||||
}
|
||||
static struct ts_mmi_methods goodix_ts_mmi_methods = {
|
||||
.get_vendor = goodix_ts_mmi_methods_get_vendor,
|
||||
.get_productinfo = goodix_ts_mmi_methods_get_productinfo,
|
||||
.get_build_id = goodix_ts_mmi_methods_get_build_id,
|
||||
.get_config_id = goodix_ts_mmi_methods_get_config_id,
|
||||
.get_bus_type = goodix_ts_mmi_methods_get_bus_type,
|
||||
.get_irq_status = goodix_ts_mmi_methods_get_irq_status,
|
||||
.get_drv_irq = goodix_ts_mmi_methods_get_drv_irq,
|
||||
.get_poweron = goodix_ts_mmi_methods_get_poweron,
|
||||
.get_flashprog = goodix_ts_mmi_methods_get_flashprog,
|
||||
/* SET methods */
|
||||
.reset = goodix_ts_mmi_methods_reset,
|
||||
.drv_irq = goodix_ts_mmi_methods_drv_irq,
|
||||
.power = goodix_ts_mmi_methods_power,
|
||||
/* PM callback */
|
||||
.pre_suspend = goodix_ts_mmi_pre_suspend,
|
||||
.panel_state = goodix_ts_mmi_panel_state,
|
||||
.post_suspend = goodix_ts_mmi_post_suspend,
|
||||
.pre_resume = goodix_ts_mmi_pre_resume,
|
||||
.post_resume = goodix_ts_mmi_post_resume,
|
||||
};
|
||||
|
||||
int goodix_ts_mmi_dev_register(struct platform_device *pdev) {
|
||||
int ret;
|
||||
struct goodix_ts_core *core_data;
|
||||
|
||||
core_data = platform_get_drvdata(pdev);
|
||||
if (!core_data) {
|
||||
ts_err("Failed to get driver data");
|
||||
return -ENODEV;
|
||||
}
|
||||
ret = ts_mmi_dev_register(core_data->bus->dev, &goodix_ts_mmi_methods);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "Failed to register ts mmi\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void goodix_ts_mmi_dev_unregister(struct platform_device *pdev) {
|
||||
struct goodix_ts_core *core_data;
|
||||
|
||||
core_data = platform_get_drvdata(pdev);
|
||||
if (!core_data)
|
||||
ts_err("Failed to get driver data");
|
||||
ts_mmi_dev_unregister(core_data->bus->dev);
|
||||
}
|
||||
33
drivers/input/touchscreen/goodix_gt96x_mmi/goodix_ts_mmi.h
Normal file
33
drivers/input/touchscreen/goodix_gt96x_mmi/goodix_ts_mmi.h
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* Copyright (C) 2023 Motorola Mobility LLC
|
||||
*
|
||||
* This software is licensed under the terms of the GNU General Public
|
||||
* License version 2, as published by the Free Software Foundation, and
|
||||
* may be copied, distributed, and modified under those terms.
|
||||
*
|
||||
* 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 __GOODIX_TS_MMI_H__
|
||||
#define __GOODIX_TS_MMI_H__
|
||||
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/touchscreen_mmi.h>
|
||||
#include <linux/mmi_wake_lock.h>
|
||||
#include "goodix_ts_core.h"
|
||||
|
||||
#ifdef CONFIG_INPUT_TOUCHSCREEN_MMI
|
||||
int goodix_ts_mmi_dev_register(struct platform_device *ts_device);
|
||||
void goodix_ts_mmi_dev_unregister(struct platform_device *ts_device);
|
||||
#else
|
||||
static int inline goodix_ts_mmi_dev_register(struct platform_device *ts_device) {
|
||||
return -ENOSYS;
|
||||
}
|
||||
static int inline goodix_ts_mmi_dev_unregister(struct platform_device *ts_device) {
|
||||
return -ENOSYS;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
@ -273,6 +273,11 @@ int goodix_get_ic_type(struct device_node *node,
|
|||
bus_inf->ic_type = IC_TYPE_NOTTINGHAM;
|
||||
return 0;
|
||||
}
|
||||
if (strstr(ic_name, "marseille")) {
|
||||
ts_info("ic type is marseille");
|
||||
bus_inf->ic_type = IC_TYPE_MARSEILLE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
ts_err("unsupported ic type %s", ic_name);
|
||||
return -EINVAL;
|
||||
|
|
|
|||
|
|
@ -414,7 +414,12 @@ int32_t CTP_SPI_READ(struct spi_device *client, uint8_t *buf, uint16_t len)
|
|||
|
||||
while (retries < 5) {
|
||||
ret = spi_read_write(client, buf, len, NVTREAD);
|
||||
if (ret == 0) break;
|
||||
if (ret == 0)
|
||||
break;
|
||||
else if (ret == -ETIMEDOUT) {
|
||||
NVT_ERR("read error, ret = %d\n", ret);
|
||||
break;
|
||||
}
|
||||
retries++;
|
||||
}
|
||||
|
||||
|
|
@ -448,7 +453,13 @@ int32_t CTP_SPI_WRITE(struct spi_device *client, uint8_t *buf, uint16_t len)
|
|||
|
||||
while (retries < 5) {
|
||||
ret = spi_read_write(client, buf, len, NVTWRITE);
|
||||
if (ret == 0) break;
|
||||
if (ret == 0)
|
||||
break;
|
||||
else if (ret == -ETIMEDOUT) {
|
||||
NVT_ERR("write error, ret = %d\n", ret);
|
||||
break;
|
||||
}
|
||||
|
||||
retries++;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -238,8 +238,13 @@ static int ts_mmi_gesture_handler(struct gesture_event_data *gev)
|
|||
{
|
||||
int key_code;
|
||||
struct ts_mmi_dev *touch_cdev = sensor_pdata->touch_cdev;
|
||||
struct ts_mmi_dev_pdata *ppdata = &touch_cdev->pdata;
|
||||
unsigned char mode_type = touch_cdev->gesture_mode_type;
|
||||
|
||||
if (ppdata->resolution_boost) {
|
||||
gev->evdata.x /= ppdata->resolution_boost;
|
||||
gev->evdata.y /= ppdata->resolution_boost;
|
||||
}
|
||||
switch (gev->evcode) {
|
||||
case 1:
|
||||
if (!(mode_type & TS_MMI_GESTURE_SINGLE))
|
||||
|
|
@ -247,7 +252,9 @@ static int ts_mmi_gesture_handler(struct gesture_event_data *gev)
|
|||
|
||||
ts_mmi_single_tap_handler(touch_cdev);
|
||||
key_code = BTN_TRIGGER_HAPPY3;
|
||||
pr_info("%s: single tap\n", __func__);
|
||||
input_report_abs(sensor_pdata->input_sensor_dev, ABS_X, gev->evdata.x);
|
||||
input_report_abs(sensor_pdata->input_sensor_dev, ABS_Y, gev->evdata.y);
|
||||
pr_info("%s: single tap; x=%d, y=%d\n", __func__, gev->evdata.x, gev->evdata.y);
|
||||
break;
|
||||
case 2:
|
||||
if (!(mode_type & TS_MMI_GESTURE_ZERO))
|
||||
|
|
@ -277,7 +284,9 @@ static int ts_mmi_gesture_handler(struct gesture_event_data *gev)
|
|||
return 1;
|
||||
|
||||
key_code = BTN_TRIGGER_HAPPY6;
|
||||
pr_info("%s: double tap\n", __func__);
|
||||
input_report_abs(sensor_pdata->input_sensor_dev, ABS_X, gev->evdata.x);
|
||||
input_report_abs(sensor_pdata->input_sensor_dev, ABS_Y, gev->evdata.y);
|
||||
pr_info("%s: double tap; x=%d, y=%d\n", __func__, gev->evdata.x, gev->evdata.y);
|
||||
touch_cdev->double_tap_pressed = true;
|
||||
sysfs_notify(&DEV_MMI->kobj, NULL, "double_tap_pressed");
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -186,6 +186,9 @@ int ts_mmi_parse_dt(struct ts_mmi_dev *touch_cdev,
|
|||
touch_cdev->clip.xBR, touch_cdev->clip.yBR);
|
||||
}
|
||||
|
||||
if (!of_property_read_u32(of_node, "mmi,resolution_boost", &ppdata->resolution_boost))
|
||||
dev_info(DEV_TS, "%s: resolution_boost = %d\n", __func__, ppdata->resolution_boost);
|
||||
|
||||
chosen = of_find_node_by_name(NULL, "chosen");
|
||||
if (chosen) {
|
||||
struct device_node *child;
|
||||
|
|
|
|||
|
|
@ -294,7 +294,7 @@ static void aw862xx_play_mode(struct aw_haptic *aw_haptic, uint8_t play_mode)
|
|||
case AW_RTP_MODE:
|
||||
aw_info("enter rtp mode");
|
||||
aw_haptic->play_mode = AW_RTP_MODE;
|
||||
aw862xx_set_pwm(aw_haptic, AW_PWM_24K);
|
||||
aw862xx_set_pwm(aw_haptic, AW_PWM_12K);
|
||||
aw862xx_auto_brk_config(aw_haptic, true);
|
||||
haptic_nv_i2c_write_bits(aw_haptic, AW862XX_REG_PLAYCFG3,
|
||||
AW862XX_BIT_PLAYCFG3_PLAY_MODE_MASK,
|
||||
|
|
|
|||
|
|
@ -48,11 +48,57 @@ static char aw_ram_name[][AW_NAME_MAX] = {
|
|||
};
|
||||
|
||||
static char aw_rtp_name[][AW_NAME_MAX] = {
|
||||
{"haptic_nv_rtp_osc_24K_5s.bin"},
|
||||
{"haptic_nv_rtp.bin"},
|
||||
{"haptic_nv_rtp_lighthouse.bin"},
|
||||
{"haptic_nv_rtp_silk.bin"},
|
||||
{"haptic_nv_rtp_autosin.bin"},
|
||||
{"aw862xx_rtp.bin"},
|
||||
{"aw862xx_rtp_Argo_Navis.bin"},
|
||||
{"aw862xx_rtp_Attentive.bin"},
|
||||
{"aw862xx_rtp_Awake.bin"},
|
||||
{"aw862xx_rtp_Bird_Loop.bin"},
|
||||
{"aw862xx_rtp_Brilliant_Times.bin"},
|
||||
{"aw862xx_rtp_Chimey_Phone.bin"},
|
||||
{"aw862xx_rtp_Complex.bin"},
|
||||
{"aw862xx_rtp_Crazy_Dream.bin"},
|
||||
{"aw862xx_rtp_Curve_Ball_Blend.bin"},
|
||||
{"aw862xx_rtp_Digital_Phone.bin"},
|
||||
{"aw862xx_rtp_Electrovision.bin"},
|
||||
{"aw862xx_rtp_Ether_Shake.bin"},
|
||||
{"aw862xx_rtp_Fateful_Words.bin"},
|
||||
{"aw862xx_rtp_Flutey_Phone.bin"},
|
||||
{"aw862xx_rtp_Future_Funk.bin"},
|
||||
{"aw862xx_rtp_Future_Hi_Tech.bin"},
|
||||
{"aw862xx_rtp_Girtab.bin"},
|
||||
{"aw862xx_rtp_Hello.bin"},
|
||||
{"aw862xx_rtp_Hexagon.bin"},
|
||||
{"aw862xx_rtp_Hydra.bin"},
|
||||
{"aw862xx_rtp_Insert_Coin.bin"},
|
||||
{"aw862xx_rtp_Jumping_Dots.bin"},
|
||||
{"aw862xx_rtp_Keys.bin"},
|
||||
{"aw862xx_rtp_Loopy.bin"},
|
||||
{"aw862xx_rtp_Loopy_Lounge.bin"},
|
||||
{"aw862xx_rtp_Modular.bin"},
|
||||
{"aw862xx_rtp_Momentum.bin"},
|
||||
{"aw862xx_rtp_Morning.bin"},
|
||||
{"aw862xx_rtp_Moto.bin"},
|
||||
{"aw862xx_rtp_Natural.bin"},
|
||||
{"aw862xx_rtp_New_Player.bin"},
|
||||
{"aw862xx_rtp_Onward.bin"},
|
||||
{"aw862xx_rtp_Organ_Dub.bin"},
|
||||
{"aw862xx_rtp_Overclocked.bin"},
|
||||
{"aw862xx_rtp_Pegasus.bin"},
|
||||
{"aw862xx_rtp_Pyxis.bin"},
|
||||
{"aw862xx_rtp_Regrade.bin"},
|
||||
{"aw862xx_rtp_Scarabaeus.bin"},
|
||||
{"aw862xx_rtp_Sceptrum.bin"},
|
||||
{"aw862xx_rtp_Simple.bin"},
|
||||
{"aw862xx_rtp_Solarium.bin"},
|
||||
{"aw862xx_rtp_Sparse.bin"},
|
||||
{"aw862xx_rtp_Terrabytes.bin"},
|
||||
{"aw862xx_rtp_Zero_Hour.bin"},
|
||||
{"aw862xx_rtp_Play.bin"},
|
||||
{"aw862xx_rtp_TJINGLE.bin"},
|
||||
{"aw862xx_rtp_Verizon_Airwaves.bin"},
|
||||
{"aw862xx_rtp_City_Lights.bin"},
|
||||
{"aw862xx_rtp_Firefly.bin"},
|
||||
{"aw862xx_rtp_Now_or_Never.bin"},
|
||||
};
|
||||
|
||||
#ifdef AW_TIKTAP
|
||||
|
|
@ -1684,6 +1730,18 @@ static ssize_t seq_store(struct device *dev, struct device_attribute *attr, cons
|
|||
return count;
|
||||
}
|
||||
|
||||
static ssize_t rtp_interface_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ssize_t rtp_interface_store(struct device *dev,
|
||||
struct device_attribute *attr, const char *buf, size_t count)
|
||||
{
|
||||
return count;
|
||||
}
|
||||
|
||||
static ssize_t loop_show(struct device *dev, struct device_attribute *attr, char *buf)
|
||||
{
|
||||
uint8_t i = 0;
|
||||
|
|
@ -2469,6 +2527,7 @@ static DEVICE_ATTR_RW(activate_mode);
|
|||
static DEVICE_ATTR_RW(index);
|
||||
static DEVICE_ATTR_RW(gain);
|
||||
static DEVICE_ATTR_RW(seq);
|
||||
static DEVICE_ATTR_RW(rtp_interface);
|
||||
static DEVICE_ATTR_RW(loop);
|
||||
static DEVICE_ATTR_RW(ram_update);
|
||||
static DEVICE_ATTR_RW(f0);
|
||||
|
|
@ -2501,6 +2560,7 @@ static struct attribute *vibrator_attributes[] = {
|
|||
&dev_attr_index.attr,
|
||||
&dev_attr_gain.attr,
|
||||
&dev_attr_seq.attr,
|
||||
&dev_attr_rtp_interface.attr,
|
||||
&dev_attr_loop.attr,
|
||||
&dev_attr_reg.attr,
|
||||
&dev_attr_ram_update.attr,
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ LOCAL_PATH := $(call my-dir)
|
|||
|
||||
ifeq ($(AW96XX_USB_USE_ONLINE),true)
|
||||
KERNEL_CFLAGS += CONFIG_AW96XX_POWER_SUPPLY_ONLINE=y
|
||||
KBUILD_OPTIONS += CONFIG_AW96XX_POWER_SUPPLY_ONLINE=y
|
||||
endif
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
|
|
|
|||
|
|
@ -621,7 +621,11 @@ static void usb_ether_setup(struct net_device *dev)
|
|||
|
||||
ether_setup(dev);
|
||||
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 1, 25)
|
||||
eth_random_addr((u8 *)dev->dev_addr);
|
||||
#else
|
||||
eth_hw_addr_random(dev);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
|
|
|||
|
|
@ -5490,7 +5490,7 @@ void hybridswap_force_reclaim(struct mem_cgroup *mcg)
|
|||
return;
|
||||
|
||||
mutex_lock(&hybs->swap_lock);
|
||||
require_size = atomic64_read(&hybs->zram_stored_size);
|
||||
require_size = atomic64_read(&hybs->zram_stored_size) / 2;
|
||||
hybs->force_swapout = true;
|
||||
hybridswap_permcg_reclaim(mcg, require_size, &mcg_reclaimed_size);
|
||||
hybs->force_swapout = false;
|
||||
|
|
|
|||
|
|
@ -225,6 +225,7 @@ struct bq2589x {
|
|||
/* enable dynamic adjust vindpm */
|
||||
bool enable_dynamic_adjust_vindpm;
|
||||
int vindpm_flag;
|
||||
bool vindpm_track_flag;
|
||||
|
||||
/*mmi qc3*/
|
||||
bool mmi_qc3_support;
|
||||
|
|
@ -2730,7 +2731,31 @@ static void bq2589x_monitor_workfunc(struct work_struct *work)
|
|||
schedule_delayed_work(&bq->monitor_work, 10 * HZ);
|
||||
}
|
||||
|
||||
|
||||
static void bq2589x_set_vindpm_track(struct bq2589x *bq, bool enable)
|
||||
{
|
||||
u8 val;
|
||||
int ret;
|
||||
|
||||
ret = bq2589x_read_byte(bq, &val, 0x85);
|
||||
if (ret < 0) {
|
||||
bq2589x_write_byte(bq, 0x7D, 0x48);
|
||||
bq2589x_write_byte(bq, 0x7D, 0x54);
|
||||
bq2589x_write_byte(bq, 0x7D, 0x53);
|
||||
bq2589x_write_byte(bq, 0x7D, 0x38);
|
||||
bq2589x_read_byte(bq, &val, 0x85);
|
||||
}
|
||||
dev_info(bq->dev, "%s:0x85_1 = %x\n", __func__,val);
|
||||
if (enable)
|
||||
bq2589x_write_byte(bq, 0x85, val|0x06);
|
||||
else
|
||||
bq2589x_write_byte(bq, 0x85, val & 0xF9);
|
||||
bq2589x_read_byte(bq, &val, 0x85);
|
||||
dev_info(bq->dev, "%s:0x85_2 = %x\n", __func__,val);
|
||||
bq2589x_write_byte(bq, 0x7D, 0x48);
|
||||
bq2589x_write_byte(bq, 0x7D, 0x54);
|
||||
bq2589x_write_byte(bq, 0x7D, 0x53);
|
||||
bq2589x_write_byte(bq, 0x7D, 0x38);
|
||||
}
|
||||
|
||||
static void bq2589x_charger_irq_workfunc(struct work_struct *work)
|
||||
{
|
||||
|
|
@ -2784,12 +2809,21 @@ static void bq2589x_charger_irq_workfunc(struct work_struct *work)
|
|||
bq->cv_tune = 0;
|
||||
bq2589x_set_chargevoltage(bq, bq->final_cv/1000);
|
||||
}
|
||||
if (bq->part_no == SC89890H && bq->vindpm_track_flag) {
|
||||
bq2589x_set_vindpm_track(bq,false);
|
||||
bq->vindpm_track_flag = false;
|
||||
}
|
||||
} else if ((bq->vbus_type != BQ2589X_VBUS_NONE) && (bq->vbus_type != BQ2589X_VBUS_OTG)
|
||||
&& (!(bq->status & BQ2589X_STATUS_PLUGIN) || (reapsd_complete == true))
|
||||
&& state.online) {
|
||||
dev_info(bq->dev, "%s:adapter plugged in\n", __func__);
|
||||
bq->status |= BQ2589X_STATUS_PLUGIN;
|
||||
bq2589x_adapter_in_func(bq);
|
||||
if ((bq->part_no == SC89890H) && (bq->vbus_type == BQ2589X_VBUS_USB_CDP)
|
||||
&& !bq->vindpm_track_flag) {
|
||||
bq2589x_set_vindpm_track(bq,true);
|
||||
bq->vindpm_track_flag = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -526,6 +526,10 @@ struct smb_mmi_charger {
|
|||
bool enable_dcp_ffc;
|
||||
|
||||
bool enable_fcc_large_qg_iterm;
|
||||
|
||||
/*Battery info*/
|
||||
unsigned long manufacturing_date;
|
||||
unsigned long first_usage_date;
|
||||
};
|
||||
|
||||
#define CHGR_FAST_CHARGE_CURRENT_CFG_REG (CHGR_BASE + 0x61)
|
||||
|
|
@ -736,6 +740,7 @@ enum smb_mmi_ext_iio_channels {
|
|||
SMB5_QG_CHARGE_FULL,
|
||||
SMB5_QG_CHARGE_FULL_DESIGN,
|
||||
SMB5_QG_BATT_FULL_CURRENT,
|
||||
SMB5_QG_SOH,
|
||||
};
|
||||
|
||||
static const char * const smb_mmi_ext_iio_chan_name[] = {
|
||||
|
|
@ -759,6 +764,7 @@ static const char * const smb_mmi_ext_iio_chan_name[] = {
|
|||
[SMB5_QG_CHARGE_FULL] = "charge_full",
|
||||
[SMB5_QG_CHARGE_FULL_DESIGN] = "charge_full_design",
|
||||
[SMB5_QG_BATT_FULL_CURRENT] = "batt_full_current",
|
||||
[SMB5_QG_SOH] = "soh",
|
||||
};
|
||||
|
||||
bool is_chan_valid(struct smb_mmi_charger *chip,
|
||||
|
|
@ -3712,7 +3718,11 @@ static void mmi_basic_charge_sm(struct smb_mmi_charger *chip,
|
|||
prm->pres_chrg_step = STEP_FULL;
|
||||
}
|
||||
} else if (prm->pres_chrg_step == STEP_FULL) {
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(6,1,25)
|
||||
if (stat->batt_soc <= 95) {
|
||||
#else
|
||||
if (stat->batt_mv < (max_fv_mv - HYST_STEP_MV * 2)) {
|
||||
#endif
|
||||
prm->chrg_taper_cnt = 0;
|
||||
prm->pres_chrg_step = STEP_NORM;
|
||||
}
|
||||
|
|
@ -4226,29 +4236,40 @@ static void mmi_heartbeat_work(struct work_struct *work)
|
|||
}
|
||||
|
||||
} else if (!chip->factory_mode) {
|
||||
cap_err = 0;
|
||||
rc = smb_mmi_read_iio_chan(chip,
|
||||
SMB5_QG_CHARGE_FULL,
|
||||
&pval.intval);
|
||||
//Get soh from qcom gauge, or soh=age=fcc/fcc_designed
|
||||
rc = smb_mmi_read_iio_chan(chip, SMB5_QG_SOH, &pval.intval);
|
||||
if (rc < 0) {
|
||||
mmi_err(chip, "Couldn't get charge full\n");
|
||||
cap_err = rc;
|
||||
} else
|
||||
main_cap = pval.intval;
|
||||
mmi_err(chip, "Couldn't get qcom battery soh\n");
|
||||
//chip->age = 100;
|
||||
cap_err = 0;
|
||||
rc = smb_mmi_read_iio_chan(chip,
|
||||
SMB5_QG_CHARGE_FULL,
|
||||
&pval.intval);
|
||||
if (rc < 0) {
|
||||
mmi_err(chip, "Couldn't get charge full\n");
|
||||
cap_err = rc;
|
||||
} else
|
||||
main_cap = pval.intval;
|
||||
|
||||
rc = smb_mmi_read_iio_chan(chip,
|
||||
SMB5_QG_CHARGE_FULL_DESIGN,
|
||||
&pval.intval);
|
||||
if (rc < 0) {
|
||||
mmi_err(chip, "Couldn't get charge full design\n");
|
||||
cap_err = rc;
|
||||
} else
|
||||
main_cap_full = pval.intval;
|
||||
rc = smb_mmi_read_iio_chan(chip,
|
||||
SMB5_QG_CHARGE_FULL_DESIGN,
|
||||
&pval.intval);
|
||||
if (rc < 0) {
|
||||
mmi_err(chip, "Couldn't get charge full design\n");
|
||||
cap_err = rc;
|
||||
} else
|
||||
main_cap_full = pval.intval;
|
||||
|
||||
if (cap_err == 0)
|
||||
chip->age = ((main_cap / 10) / (main_cap_full / 1000));
|
||||
if (cap_err == 0)
|
||||
chip->age = ((main_cap / 10) / (main_cap_full / 1000));
|
||||
|
||||
mmi_dbg(chip, "Age %d\n", chip->age);
|
||||
mmi_dbg(chip, "mmi_age %d\n", chip->age);
|
||||
} else {
|
||||
chip->age = pval.intval;
|
||||
mmi_dbg(chip, "get qg soh=%d\n", chip->age);
|
||||
if (chip->cycles < 50)
|
||||
chip->age = 100;
|
||||
}
|
||||
|
||||
/* Fall here for Basic Step and Thermal Charging */
|
||||
mmi_basic_charge_sm(chip, &chg_stat);
|
||||
|
|
@ -4343,7 +4364,6 @@ sch_hb:
|
|||
envp[0] = chrg_rate_string;
|
||||
envp[1] = NULL;
|
||||
}
|
||||
|
||||
if (chip->batt_psy) {
|
||||
smb_mmi_power_supply_changed(chip->batt_psy, envp);
|
||||
} else if (chip->qcom_psy) {
|
||||
|
|
@ -4503,7 +4523,13 @@ static int batt_get_prop(struct power_supply *psy,
|
|||
val->intval = chip->last_reported_soc;
|
||||
break;
|
||||
case POWER_SUPPLY_PROP_CYCLE_COUNT:
|
||||
val->intval = chip->cycles / 100;
|
||||
if (chip->max_main_psy && chip->max_flip_psy)
|
||||
val->intval = chip->cycles / 100;
|
||||
else {
|
||||
rc = power_supply_get_property(chip->qcom_psy, psp, val);
|
||||
if (rc >= 0)
|
||||
chip->cycles = val->intval;
|
||||
}
|
||||
break;
|
||||
case POWER_SUPPLY_PROP_HEALTH:
|
||||
if (chip->max_main_psy && chip->max_flip_psy)
|
||||
|
|
@ -4568,7 +4594,13 @@ static int batt_set_prop(struct power_supply *psy,
|
|||
|
||||
switch (prop) {
|
||||
case POWER_SUPPLY_PROP_CYCLE_COUNT:
|
||||
chip->cycles += val->intval * 100;
|
||||
if (chip->max_main_psy && chip->max_flip_psy) {
|
||||
chip->cycles += val->intval * 100;
|
||||
} else {
|
||||
rc = power_supply_set_property(chip->qcom_psy, prop, val);
|
||||
if (rc < 0)
|
||||
mmi_err(chip, "set cycle_count failed, rc=%d\n", rc);
|
||||
}
|
||||
break;
|
||||
case POWER_SUPPLY_PROP_CURRENT_MAX:
|
||||
if (val->intval < 0) {
|
||||
|
|
@ -4957,9 +4989,100 @@ static ssize_t age_show(struct device *dev,
|
|||
}
|
||||
static DEVICE_ATTR(age, S_IRUGO, age_show, NULL);
|
||||
|
||||
static ssize_t state_of_health_show(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
if (!this_chip) {
|
||||
pr_err("mmi_charger: chip is invalid\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
return scnprintf(buf, CHG_SHOW_MAX_SIZE, "%d\n", this_chip->age);
|
||||
}
|
||||
|
||||
static DEVICE_ATTR(state_of_health, S_IRUGO, state_of_health_show, NULL);
|
||||
|
||||
static ssize_t first_usage_date_show(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
if (!this_chip) {
|
||||
pr_err("mmi_charger: chip is invalid\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
return scnprintf(buf, CHG_SHOW_MAX_SIZE, "%lu\n", this_chip->first_usage_date);
|
||||
}
|
||||
|
||||
static ssize_t first_usage_date_store(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
unsigned long r;
|
||||
unsigned long first_usage_date;
|
||||
|
||||
if (!this_chip) {
|
||||
pr_err("mmi_charger: chip is invalid\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
r = kstrtoul(buf, 0, &first_usage_date);
|
||||
if (r) {
|
||||
mmi_err(this_chip, "Invalid first_usage_date value = %lu\n", first_usage_date);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
this_chip->first_usage_date = first_usage_date;
|
||||
|
||||
return r ? r : count;
|
||||
}
|
||||
|
||||
static DEVICE_ATTR(first_usage_date, 0644, first_usage_date_show, first_usage_date_store);
|
||||
|
||||
static ssize_t manufacturing_date_show(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
if (!this_chip) {
|
||||
pr_err("mmi_charger: chip is invalid\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
return scnprintf(buf, CHG_SHOW_MAX_SIZE, "%lu\n", this_chip->manufacturing_date);
|
||||
}
|
||||
|
||||
static ssize_t manufacturing_date_store(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
unsigned long r;
|
||||
unsigned long manufacturing_date;
|
||||
|
||||
if (!this_chip) {
|
||||
pr_err("mmi_charger: chip is invalid\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
r = kstrtoul(buf, 0, &manufacturing_date);
|
||||
if (r) {
|
||||
mmi_err(this_chip, "Invalid manufacturing_date value = %lu\n", manufacturing_date);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
this_chip->manufacturing_date = manufacturing_date;
|
||||
|
||||
return r ? r : count;
|
||||
}
|
||||
|
||||
static DEVICE_ATTR(manufacturing_date, 0644, manufacturing_date_show, manufacturing_date_store);
|
||||
|
||||
static struct attribute * mmi_g[] = {
|
||||
&dev_attr_charge_rate.attr,
|
||||
&dev_attr_age.attr,
|
||||
&dev_attr_state_of_health.attr,
|
||||
&dev_attr_manufacturing_date.attr,
|
||||
&dev_attr_first_usage_date.attr,
|
||||
NULL,
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@
|
|||
#define BATT_PAIR_ID_MASK ((1 << BATT_PAIR_ID_BITS) - 1)
|
||||
|
||||
#define HEARTBEAT_DELAY_MS 60000
|
||||
#define HEARTBEAT_FACTORY_MS 1000
|
||||
#define HEARTBEAT_FACTORY_MS 5000
|
||||
#define HEARTBEAT_DISCHARGE_MS 100000
|
||||
#define HEARTBEAT_WAKEUP_INTRVAL_NS 70000000000
|
||||
|
||||
|
|
@ -71,6 +71,7 @@ enum {
|
|||
NOTIFY_EVENT_TYPE_LPD_PRESENT,
|
||||
NOTIFY_EVENT_TYPE_VBUS_PRESENT,
|
||||
NOTIFY_EVENT_TYPE_POWER_WATT,
|
||||
NOTIFY_EVENT_TYPE_CHG_REAL_TYPE,
|
||||
};
|
||||
|
||||
static char *charge_rate[] = {
|
||||
|
|
@ -219,6 +220,7 @@ struct mmi_charger_chip {
|
|||
int charge_full_design;
|
||||
int init_cycles;
|
||||
int max_charger_rate;
|
||||
int real_charger_type;
|
||||
bool vbus_present;
|
||||
bool lpd_present;
|
||||
int power_watt;
|
||||
|
|
@ -240,12 +242,14 @@ struct mmi_charger_chip {
|
|||
bool enable_factory_poweroff;
|
||||
bool factory_syspoweroff_wait;
|
||||
bool start_factory_kill_disabled;
|
||||
int upper_limit_en_mv;
|
||||
int upper_limit_capacity;
|
||||
int lower_limit_capacity;
|
||||
|
||||
struct wakeup_source *mmi_hb_wake_source;
|
||||
struct alarm heartbeat_alarm;
|
||||
int heartbeat_interval;
|
||||
int heartbeat_factory_interval;
|
||||
struct notifier_block mmi_reboot;
|
||||
struct notifier_block mmi_psy_notifier;
|
||||
struct delayed_work heartbeat_work;
|
||||
|
|
@ -361,6 +365,8 @@ static ssize_t state_sync_store(struct device *dev,
|
|||
NOTIFY_EVENT_TYPE_VBUS_PRESENT);
|
||||
mmi_notify_charger_event(this_chip,
|
||||
NOTIFY_EVENT_TYPE_POWER_WATT);
|
||||
mmi_notify_charger_event(this_chip,
|
||||
NOTIFY_EVENT_TYPE_CHG_REAL_TYPE);
|
||||
mutex_unlock(&this_chip->charger_lock);
|
||||
cancel_delayed_work(&this_chip->heartbeat_work);
|
||||
schedule_delayed_work(&this_chip->heartbeat_work,
|
||||
|
|
@ -1502,7 +1508,8 @@ static void mmi_update_charger_status(struct mmi_charger_chip *chip,
|
|||
if (chip->enable_charging_limit && chip->factory_version) {
|
||||
charging_limit_modes = status->charging_limit_modes;
|
||||
if ((charging_limit_modes != CHARGING_LIMIT_RUN)
|
||||
&& (batt_info->batt_soc >= chip->upper_limit_capacity))
|
||||
&& (batt_info->batt_soc >= chip->upper_limit_capacity)
|
||||
&& (batt_info->batt_mv >= chip->upper_limit_en_mv))
|
||||
charging_limit_modes = CHARGING_LIMIT_RUN;
|
||||
else if ((charging_limit_modes != CHARGING_LIMIT_OFF)
|
||||
&& (batt_info->batt_soc <= chip->lower_limit_capacity))
|
||||
|
|
@ -1776,6 +1783,11 @@ static void mmi_notify_charger_event(struct mmi_charger_chip *chip, int type)
|
|||
"POWER_SUPPLY_POWER_WATT=%d",
|
||||
chip->power_watt / 1000);
|
||||
break;
|
||||
case NOTIFY_EVENT_TYPE_CHG_REAL_TYPE:
|
||||
scnprintf(event_string, CHG_SHOW_MAX_SIZE,
|
||||
"POWER_SUPPLY_CHARGE_REAL_TYPE=%d",
|
||||
chip->real_charger_type);
|
||||
break;
|
||||
default:
|
||||
mmi_err(chip, "Invalid notify event type %d\n", type);
|
||||
kfree(event_string);
|
||||
|
|
@ -1989,6 +2001,8 @@ static void mmi_update_battery_status(struct mmi_charger_chip *chip)
|
|||
int batt_health = POWER_SUPPLY_HEALTH_UNKNOWN;
|
||||
int charger_rate = MMI_POWER_SUPPLY_CHARGE_RATE_NONE;
|
||||
int max_charger_rate = MMI_POWER_SUPPLY_CHARGE_RATE_NONE;
|
||||
int charger_type = 0;
|
||||
int real_charger_type = 0;
|
||||
struct mmi_charger *charger = NULL;
|
||||
struct mmi_battery_pack *battery = NULL;
|
||||
struct mmi_battery_info *batt_info = NULL;
|
||||
|
|
@ -2027,6 +2041,11 @@ static void mmi_update_battery_status(struct mmi_charger_chip *chip)
|
|||
if (charger->chg_info.chrg_pmax_mw > power_watt)
|
||||
power_watt = charger->chg_info.chrg_pmax_mw;
|
||||
|
||||
/* update charger type */
|
||||
charger_type = charger->chg_info.chrg_type;
|
||||
if (charger_type != 0xFF && real_charger_type < charger_type)
|
||||
real_charger_type = charger_type;
|
||||
|
||||
/* update charging status */
|
||||
if (batt_info->batt_status == POWER_SUPPLY_STATUS_FULL ||
|
||||
battery->status == POWER_SUPPLY_STATUS_FULL ||
|
||||
|
|
@ -2056,6 +2075,7 @@ static void mmi_update_battery_status(struct mmi_charger_chip *chip)
|
|||
battery->cycles,
|
||||
charge_rate[battery->charger_rate]);
|
||||
}
|
||||
|
||||
/* update vbus and liquid present detection status */
|
||||
if (!vbus_present && charger->chg_info.vbus_present)
|
||||
vbus_present = true;
|
||||
|
|
@ -2127,6 +2147,13 @@ static void mmi_update_battery_status(struct mmi_charger_chip *chip)
|
|||
mmi_info(chip, "charger power is %d mW\n", power_watt);
|
||||
}
|
||||
|
||||
if ((chip->real_charger_type) != real_charger_type) {
|
||||
mmi_changed = true;
|
||||
chip->real_charger_type = real_charger_type;
|
||||
mmi_notify_charger_event(chip, NOTIFY_EVENT_TYPE_CHG_REAL_TYPE);
|
||||
mmi_info(chip, "charger real type is %d\n", real_charger_type);
|
||||
}
|
||||
|
||||
list_for_each_entry(battery, &chip->battery_list, list) {
|
||||
if (batt_health == POWER_SUPPLY_HEALTH_UNKNOWN) {
|
||||
batt_health = battery->health;
|
||||
|
|
@ -2254,7 +2281,7 @@ static void mmi_charger_heartbeat_work(struct work_struct *work)
|
|||
chip->suspended = 0;
|
||||
|
||||
if (chip->factory_mode)
|
||||
hb_resch_time = HEARTBEAT_FACTORY_MS;
|
||||
hb_resch_time = chip->heartbeat_factory_interval;
|
||||
else if (chip->max_charger_rate != MMI_POWER_SUPPLY_CHARGE_RATE_NONE
|
||||
&& chip->combo_status != POWER_SUPPLY_STATUS_FULL)
|
||||
hb_resch_time = chip->heartbeat_interval;
|
||||
|
|
@ -2627,10 +2654,12 @@ static int mmi_charger_reboot(struct notifier_block *nb,
|
|||
if (!chip->factory_mode)
|
||||
return NOTIFY_DONE;
|
||||
|
||||
pr_info("Reboot notifier call mmi charger reboot!\n");
|
||||
switch (event) {
|
||||
case SYS_POWER_OFF:
|
||||
factory_kill_disable = true;
|
||||
chip->force_charger_disabled = true;
|
||||
cancel_delayed_work(&chip->heartbeat_work);
|
||||
schedule_delayed_work(&chip->heartbeat_work, msecs_to_jiffies(0));
|
||||
while (chip->max_charger_rate != MMI_POWER_SUPPLY_CHARGE_RATE_NONE &&
|
||||
(shutdown_triggered || chip->factory_syspoweroff_wait) && !chip->empty_vbat_shutdown_triggered) {
|
||||
|
|
@ -2788,6 +2817,11 @@ static int mmi_parse_dt(struct mmi_charger_chip *chip)
|
|||
if (rc)
|
||||
chip->factory_kill_debounce_ms = 0;
|
||||
|
||||
rc = of_property_read_u32(node, "mmi,upper-limit-en-voltage",
|
||||
&chip->upper_limit_en_mv);
|
||||
if (rc)
|
||||
chip->upper_limit_en_mv = 4000;
|
||||
|
||||
rc = of_property_read_u32(node, "mmi,upper-limit-capacity",
|
||||
&chip->upper_limit_capacity);
|
||||
if (rc)
|
||||
|
|
@ -2803,6 +2837,11 @@ static int mmi_parse_dt(struct mmi_charger_chip *chip)
|
|||
if (rc)
|
||||
chip->heartbeat_interval = HEARTBEAT_DELAY_MS;
|
||||
|
||||
rc = of_property_read_u32(node, "mmi,heartbeat-factory-interval",
|
||||
&chip->heartbeat_factory_interval);
|
||||
if (rc)
|
||||
chip->heartbeat_factory_interval = HEARTBEAT_FACTORY_MS;
|
||||
|
||||
rc = of_property_read_u32(node, "mmi,dcp-power-max",
|
||||
&chip->dcp_pmax);
|
||||
if (rc)
|
||||
|
|
@ -3049,6 +3088,7 @@ static void mmi_charger_shutdown(struct platform_device *pdev)
|
|||
{
|
||||
struct mmi_charger_chip *chip = platform_get_drvdata(pdev);
|
||||
|
||||
cancel_delayed_work(&chip->heartbeat_work);
|
||||
mmi_info(chip, "MMI charger shutdown\n");
|
||||
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -232,7 +232,7 @@ static int sc760x_enable_chip(struct sc760x_chip *sc, bool en)
|
|||
|
||||
if (sc->sc760x_enable) {
|
||||
|
||||
if (!sc->irq_enabled) {
|
||||
if (sc->irq && !sc->irq_enabled) {
|
||||
enable_irq_wake(sc->irq);
|
||||
enable_irq(sc->irq);
|
||||
sc->irq_enabled = true;
|
||||
|
|
@ -242,7 +242,7 @@ static int sc760x_enable_chip(struct sc760x_chip *sc, bool en)
|
|||
pr_info("init device failed(%d)\n", ret);
|
||||
}
|
||||
} else {
|
||||
if (sc->irq_enabled) {
|
||||
if (sc->irq && sc->irq_enabled) {
|
||||
disable_irq_wake(sc->irq);
|
||||
disable_irq(sc->irq);
|
||||
sc->irq_enabled = false;
|
||||
|
|
@ -1063,6 +1063,9 @@ static int sc760x_parse_dt(struct sc760x_chip *sc, struct device *dev)
|
|||
sc->init_data.charger_disabled = of_property_read_bool(node,
|
||||
"init-charger-disabled");
|
||||
|
||||
sc->irq_dis_cfg =
|
||||
of_property_read_bool(node, "irq-dis-cfg");
|
||||
|
||||
ret = device_property_read_u32(sc->dev,
|
||||
"iterm-microamp",
|
||||
&sc->init_data.iterm);
|
||||
|
|
@ -1193,6 +1196,12 @@ static int sc760x_register_interrupt(struct sc760x_chip *sc, struct i2c_client *
|
|||
{
|
||||
int ret = 0;
|
||||
|
||||
if (sc->irq_dis_cfg) {
|
||||
sc->irq = 0;
|
||||
dev_err(sc->dev, "irq_dis_cfg is ture\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = devm_request_threaded_irq(sc->dev, client->irq, NULL,
|
||||
sc760x_irq_handler,
|
||||
IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
|
||||
|
|
@ -1202,6 +1211,8 @@ static int sc760x_register_interrupt(struct sc760x_chip *sc, struct i2c_client *
|
|||
return ret;
|
||||
}
|
||||
|
||||
disable_irq_wake(client->irq);
|
||||
disable_irq(client->irq);
|
||||
sc->irq_enabled = false;
|
||||
sc->irq = client->irq;
|
||||
dev_err(sc->dev, "request thread irq success\n");
|
||||
|
|
@ -1421,11 +1432,6 @@ static void charger_detect_work_func(struct work_struct *work)
|
|||
goto err;
|
||||
}
|
||||
|
||||
if (state_changed) {
|
||||
sc760x_dump_reg(sc);
|
||||
power_supply_changed(sc->charger_psy);
|
||||
}
|
||||
return;
|
||||
err:
|
||||
//release wakelock
|
||||
if (state_changed)
|
||||
|
|
@ -2099,9 +2105,13 @@ static int sc760x_suspend(struct device *dev)
|
|||
struct sc760x_chip *sc = dev_get_drvdata(dev);
|
||||
int ret = 0;
|
||||
dev_info(sc->dev, "Suspend successfully!");
|
||||
if (device_may_wakeup(dev))
|
||||
enable_irq_wake(sc->irq);
|
||||
disable_irq(sc->irq);
|
||||
|
||||
if (sc->irq) {
|
||||
if (device_may_wakeup(dev))
|
||||
enable_irq_wake(sc->irq);
|
||||
disable_irq(sc->irq);
|
||||
sc->irq_enabled = false;
|
||||
}
|
||||
ret = sc760x_set_adc_enable(sc, false);
|
||||
if (ret < 0) {
|
||||
dev_err(sc->dev, "%s Failed to disable adc(%d)\n", __func__, ret);
|
||||
|
|
@ -2119,10 +2129,12 @@ static int sc760x_resume(struct device *dev)
|
|||
struct sc760x_chip *sc = dev_get_drvdata(dev);
|
||||
int ret = 0;
|
||||
dev_info(sc->dev, "Resume successfully!");
|
||||
if (device_may_wakeup(dev))
|
||||
disable_irq_wake(sc->irq);
|
||||
enable_irq(sc->irq);
|
||||
|
||||
if (sc->irq) {
|
||||
if (device_may_wakeup(dev))
|
||||
disable_irq_wake(sc->irq);
|
||||
enable_irq(sc->irq);
|
||||
sc->irq_enabled = true;
|
||||
}
|
||||
ret = sc760x_set_lowpower_mode(sc, false);
|
||||
if (ret < 0) {
|
||||
dev_err(sc->dev, "%s Failed to exit lowpower(%d)\n", __func__, ret);
|
||||
|
|
|
|||
|
|
@ -201,6 +201,7 @@ struct sc760x_chip {
|
|||
|
||||
int irq;
|
||||
bool irq_enabled;
|
||||
bool irq_dis_cfg;
|
||||
int role;
|
||||
int sc760x_enable;
|
||||
u32 *thermal_levels;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,15 @@
|
|||
KERNEL_SRC ?= /lib/modules/$(shell uname -r)/build
|
||||
all: modules
|
||||
|
||||
all:
|
||||
$(MAKE) -C $(KERNEL_SRC) M=$(shell pwd) modules $(KBUILD_OPTIONS)
|
||||
modules:
|
||||
$(MAKE) -C $(KERNEL_SRC) M=$(M) modules $(KBUILD_OPTIONS)
|
||||
|
||||
modules_install:
|
||||
$(MAKE) INSTALL_MOD_STRIP=1 -C $(KERNEL_SRC) M=$(shell pwd) modules_install
|
||||
$(MAKE) INSTALL_MOD_STRIP=1 -C $(KERNEL_SRC) M=$(M) modules_install
|
||||
|
||||
%:
|
||||
$(MAKE) -C $(KERNEL_SRC) M=$(M) $@ $(KBUILD_OPTIONS)
|
||||
|
||||
clean:
|
||||
$(MAKE) -C $(KERNEL_SRC) M=$(PWD) clean
|
||||
rm -f *.o *.ko *.mod.c *.mod.o *~ .*.cmd Module.symvers
|
||||
rm -rf .tmp_versions
|
||||
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@
|
|||
#include <linux/ktime.h>
|
||||
#endif
|
||||
|
||||
#include <linux/mmi_device.h>
|
||||
#include <linux/uwb/qmrom.h>
|
||||
#include <linux/uwb/qmrom_spi.h>
|
||||
#include <linux/uwb/qmrom_log.h>
|
||||
|
|
@ -1008,6 +1009,13 @@ static int qm35_probe(struct spi_device *spi)
|
|||
struct clk *uwb_clk;
|
||||
int ret = 0;
|
||||
|
||||
if (spi->dev.of_node && !mmi_device_is_available(spi->dev.of_node)) {
|
||||
pr_err("%s : mmi: device not supported\n", __func__);
|
||||
return -ENODEV;
|
||||
} else {
|
||||
pr_err("%s : supported uwb device found\n", __func__);
|
||||
}
|
||||
|
||||
if (fwname) {
|
||||
qmrom_set_fwname(fwname);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,13 +25,15 @@
|
|||
#include <linux/platform_device.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/pinctrl/consumer.h>
|
||||
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/of_gpio.h>
|
||||
|
||||
#define DRIVER_VERSION "0.0.1"
|
||||
|
||||
struct wlan_antenna_drvdata {
|
||||
struct device *dev;
|
||||
struct pinctrl *pinctrl;
|
||||
int wlan_antenna_gpio;
|
||||
struct pinctrl_state *pstate_active;
|
||||
struct pinctrl_state *pstate_suspend;
|
||||
};
|
||||
|
|
@ -47,7 +49,10 @@ static ssize_t wlan_antenna_en_read(struct device *dev,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
return snprintf(buf, PAGE_SIZE, "wlan_antenna: not support!\n");
|
||||
if (gpio_get_value(data->wlan_antenna_gpio))
|
||||
return snprintf(buf, PAGE_SIZE, "high\n");
|
||||
else
|
||||
return snprintf(buf, PAGE_SIZE, "low\n");
|
||||
}
|
||||
|
||||
static ssize_t wlan_antenna_en_write(struct device *dev,
|
||||
|
|
@ -77,8 +82,6 @@ static ssize_t wlan_antenna_en_write(struct device *dev,
|
|||
|
||||
if(ret) {
|
||||
pr_err("wlan_antenna failed to set pinctrl!\n");
|
||||
} else {
|
||||
pr_info("wlan_antenna success set pinctrl\n");
|
||||
}
|
||||
|
||||
return count;
|
||||
|
|
@ -108,6 +111,13 @@ static int wlan_antenna_probe(struct platform_device *pdev)
|
|||
drvdata->dev = &pdev->dev;
|
||||
platform_set_drvdata(pdev, drvdata);
|
||||
|
||||
drvdata->wlan_antenna_gpio = of_get_named_gpio(dev->of_node, "qcom,wlan_antenna-gpio", 0);
|
||||
ret = gpio_request(drvdata->wlan_antenna_gpio, "wlan_antenna_gpio");
|
||||
if (ret) {
|
||||
pr_err("%s, unable to request gpio %d (%d)\n", __func__, drvdata->wlan_antenna_gpio, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Get pinctrl if target uses pinctrl */
|
||||
drvdata->pinctrl = devm_pinctrl_get(dev);
|
||||
if (IS_ERR_OR_NULL(drvdata->pinctrl)) {
|
||||
|
|
|
|||
|
|
@ -467,6 +467,7 @@ struct ts_mmi_dev_pdata {
|
|||
#ifdef CONFIG_BOARD_USES_DOUBLE_TAP_CTRL
|
||||
int supported_gesture_type;
|
||||
#endif
|
||||
int resolution_boost;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
Loading…
Reference in a new issue