optimize aw963xx driver

1.add reset node
2.modify enable function
3.fix panic problem

Change-Id: I0e7e1e7185ffa6128239c2e91f61f31f448ded28
Signed-off-by: tin_bingtai.zou_tmp <tinno60@motorola.com>
Reviewed-on: https://gerrit.mot.com/2620252
SME-Granted: SME Approvals Granted
SLTApproved: Slta Waiver
Tested-by: Jira Key
Reviewed-by: <yangyi31@motorola.com>
Reviewed-by: Xiangpo Zhao <zhaoxp3@motorola.com>
Reviewed-by: Yuchang Guo <guoyc1@lenovo.com>
Submit-Approved: Jira Key
This commit is contained in:
tin_bingtai.zou_tmp 2023-05-25 15:42:39 +08:00 • committed by yangyi31
commit f86c48d11b
2 changed files with 116 additions and 59 deletions

View file

@ -2,7 +2,7 @@
#include "aw_sar.h"
#define AW963XX_I2C_NAME "aw963xx_sar"
#define AW963XX_DRIVER_VERSION "v0.1.1.4"
#define AW963XX_DRIVER_VERSION "v0.1.1.14"
static void aw963xx_set_cs_as_irq(struct aw_sar *p_sar, int flag);
static void aw963xx_get_ref_ch_enable(struct aw_sar *p_sar);
@ -233,6 +233,7 @@ static int32_t aw963xx_update_firmware(struct aw_bin *aw_bin, void *load_bin_par
struct i2c_client *i2c = p_sar->i2c;
int32_t ret = 0;
pr_info("%s enter\n",__func__);
if (aw963xx->start_mode == AW963XX_ROM_MODE) {
AWLOGI(p_sar->dev, "no need to update fw.");
return AW_OK;
@ -310,36 +311,39 @@ static void aw963xx_irq_handle_func(uint32_t irq_status, void *data)
int8_t i = 0;
int8_t j = 0;
int32_t ret = 0;
uint32_t curr_status_val = 0;
uint32_t curr_status_val[4] = { 0 };
struct aw_sar *p_sar = (struct aw_sar *)data;
uint32_t ch_th[AW963XX_CHANNEL_NUM_MAX] = { 0 };
AWLOGD(p_sar->dev, "IRQSRC = 0x%x", irq_status);
for (i = 0; i < AW963XX_VALID_TH; i++)
ret = aw_sar_i2c_read(p_sar->i2c, REG_STAT0 + i * (REG_STAT1 - REG_STAT0), &curr_status_val[i]);
for (j = 0; j < AW963XX_CHANNEL_NUM_MAX; j++) {
if (p_sar->channels_arr[j].input == NULL) {
continue;
}
for (i = (AW963XX_VALID_TH - 1); i >= 0; i--) {
ret = aw_sar_i2c_read(p_sar->i2c,
REG_STAT0 + i * (REG_STAT1 - REG_STAT0),
&curr_status_val);
ch_th[j] |= ((curr_status_val >> j) & 0x01) << i;
AWLOGE(p_sar->dev, "ch= %d, th = %d ch_th = 0x%x", j, i, ch_th[j]);
}
AWLOGE(p_sar->dev, "ch = %d last_th=0x%x th = 0x%x", j, p_sar->channels_arr[j].last_channel_info, ch_th[j]);
if (p_sar->channels_arr[j].last_channel_info != ch_th[j]) {
if ((ch_th[j] >> 3 & 0x01) == 1) { //th3
input_report_abs(p_sar->channels_arr[j].input, ABS_DISTANCE, 4);
} else if ((ch_th[j] >> 2 & 0x01) == 1) { //th2
input_report_abs(p_sar->channels_arr[j].input, ABS_DISTANCE, 3);
} else if ((ch_th[j] >> 1 & 0x01) == 1) { //th1
input_report_abs(p_sar->channels_arr[j].input, ABS_DISTANCE, 2);
} else if ((ch_th[j] >> 0 & 0x01) == 1) { //th0
input_report_abs(p_sar->channels_arr[j].input, ABS_DISTANCE, 1);
} else { //far
input_report_abs(p_sar->channels_arr[j].input, ABS_DISTANCE, 0);
continue;
}
input_sync(p_sar->channels_arr[j].input);
p_sar->channels_arr[j].last_channel_info = ch_th[j];
for (i = 0; i < AW963XX_VALID_TH; i++) {
ch_th[j] |= ((curr_status_val[i] >> j) & 0x01) << i;
AWLOGE(p_sar->dev, "ch= %d, th = %d ch_th = 0x%x", j, i, ch_th[j]);
}
AWLOGE(p_sar->dev, "ch = %d last_th=0x%x th = 0x%x", j, p_sar->channels_arr[j].last_channel_info, ch_th[j]);
if (p_sar->channels_arr[j].last_channel_info != ch_th[j]) {
if ((ch_th[j] >> 3 & 0x01) == 1) { //th3
input_report_abs(p_sar->channels_arr[j].input, ABS_DISTANCE, 4);
} else if ((ch_th[j] >> 2 & 0x01) == 1) { //th2
input_report_abs(p_sar->channels_arr[j].input, ABS_DISTANCE, 3);
} else if ((ch_th[j] >> 1 & 0x01) == 1) { //th1
input_report_abs(p_sar->channels_arr[j].input, ABS_DISTANCE, 2);
} else if ((ch_th[j] >> 0 & 0x01) == 1) { //th0
input_report_abs(p_sar->channels_arr[j].input, ABS_DISTANCE, 1);
} else { //far
input_report_abs(p_sar->channels_arr[j].input, ABS_DISTANCE, 0);
}
input_sync(p_sar->channels_arr[j].input);
p_sar->channels_arr[j].last_channel_info = ch_th[j];
}
}
}
@ -357,6 +361,12 @@ static ssize_t aw963xx_operation_mode_get(void *data, char *buf)
else
len += snprintf(buf + len, PAGE_SIZE - len, "operation mode: Unconfirmed\n");
//Note: This code is designed to temporarily place platform interrupts during debugging
if (p_sar->irq_init.host_irq_stat == IRQ_DISABLE) {
enable_irq(p_sar->irq_init.to_irq);
p_sar->irq_init.host_irq_stat = IRQ_ENABLE;
}
return len;
}
@ -961,6 +971,33 @@ static ssize_t cali_show(struct class *class,
static CLASS_ATTR_RO(cali);
static ssize_t
reset_store(struct class *class, struct class_attribute *attr, const char *buf, size_t count)
{
u32 temp = 0;
struct aw963xx *aw963xx = container_of(class, struct aw963xx, capsense_class);
struct aw_sar *p_sar = NULL;
if (aw963xx == NULL)
return 0;
p_sar = aw963xx->p_aw_sar;
if (p_sar == NULL)
return 0;
aw_sar_i2c_read(p_sar->i2c, REG_WST, &temp);
if (!strncmp(buf, "reset", 5) || !strncmp(buf, "1", 1)) {
if (((temp >> 24) & 0x00000003) == 1) {
AWLOGD(p_sar->dev, "temp:0X%x", temp);
aw_sar_i2c_write_bits(p_sar->i2c, REG_SCANCTRL1, ~0xfff, 0xfff);
}
}
return count;
}
static CLASS_ATTR_WO(reset);
static ssize_t mode_show(struct class *class,
struct class_attribute *attr,
char *buf)
@ -1127,51 +1164,6 @@ static ssize_t offset_show(struct class *class,
static CLASS_ATTR_RO(offset);
#ifdef USE_SENSORS_CLASS
static struct aw963xx *g_aw963xx = NULL;
static int capsensor_set_enable(struct sensors_classdev *sensors_cdev, unsigned int enable)
{
uint8_t i = 0;
struct aw963xx *aw963xx = g_aw963xx;
struct aw_sar *p_sar = NULL;
uint8_t set_mode = 0;
if (aw963xx == NULL) {
return 0;
}
p_sar = aw963xx->p_aw_sar;
if (p_sar == NULL) {
return 0;
}
for (i = 0; i < AW963XX_CHANNEL_NUM_MAX; i++) {
if ((p_sar->channels_arr[i].used == AW_FALSE) ||
(p_sar->channels_arr[i].input == NULL)) {
continue;
}
if (enable == 1) {
input_report_abs(p_sar->channels_arr[i].input, ABS_DISTANCE, 0);
input_sync(p_sar->channels_arr[i].input);
aw_sar_i2c_write_bits(p_sar->i2c, REG_SCANCTRL1, ~0xfff, 0xfff);
} else {
input_report_abs(p_sar->channels_arr[i].input, ABS_DISTANCE, -1);
input_sync(p_sar->channels_arr[i].input);
}
AWLOGD(p_sar->dev, "enable cap sensor: %s", sensors_cdev->name);
}
AWLOGD(p_sar->dev, "enable %d", enable);
if (enable == 0x01)
set_mode = AW963XX_ACTIVE_MODE;
else
set_mode = AW963XX_SLEEP_MODE;
aw_sar_mode_set(p_sar, set_mode);
return 0;
}
static const char *g_aw963xx_ch_name[] = {
"Moto CapSense Ch0", "Moto CapSense Ch1", "Moto CapSense Ch2",
"Moto CapSense Ch3", "Moto CapSense Ch4", "Moto CapSensor Ch5",
@ -1180,6 +1172,58 @@ static const char *g_aw963xx_ch_name[] = {
"Moto CapSensor Ch12", "Moto CapSensor Ch13", "Moto CapSensor Ch14"
};
static int32_t g_aw963xx_counter = 0;
static struct aw963xx *g_aw963xx = NULL;
static int capsensor_set_enable(struct sensors_classdev *sensors_cdev, unsigned int enable)
{
uint8_t i = 0;
struct aw963xx *aw963xx = g_aw963xx;
struct aw_sar *p_sar = NULL;
uint8_t set_mode = 0;
pr_info("%s enter\n",__func__);
if (aw963xx == NULL)
return 0;
p_sar = aw963xx->p_aw_sar;
if (p_sar == NULL)
return 0;
AWLOGD(p_sar->dev, "enable %d", enable);
for (i = 0; i < AW963XX_CHANNEL_NUM_MAX; i++) {
if ((p_sar->channels_arr[i].used == AW_FALSE) ||
(p_sar->channels_arr[i].input == NULL))
continue;
if (strcmp(sensors_cdev->name, p_sar->channels_arr[i].name) == 0) {
if (enable == 0x01) {
AWLOGD(p_sar->dev, "enable cap sensor : %s", sensors_cdev->name);
aw_sar_i2c_write_bits(p_sar->i2c, REG_SCANCTRL1, ~0xfff, 0xfff);
set_mode = AW963XX_ACTIVE_MODE;
aw_sar_mode_set(p_sar, set_mode);
input_report_abs(p_sar->channels_arr[i].input, ABS_DISTANCE, 0);
input_sync(p_sar->channels_arr[i].input);
} else if (enable == 0) {
set_mode = AW963XX_SLEEP_MODE;
aw_sar_mode_set(p_sar, set_mode);
input_report_abs(p_sar->channels_arr[i].input, ABS_DISTANCE, -1);
input_sync(p_sar->channels_arr[i].input);
p_sar->channels_arr[i].last_channel_info = -1;
} else {
AWLOGD(p_sar->dev, "unknown enable symbol");
}
break;
}
}
AWLOGD(p_sar->dev, "enable over %d", enable);
return 0;
}
#endif
//moto_customization
@ -1216,6 +1260,12 @@ static int32_t aw_sar_custom_flie_node_create(void *data)
return ret;
}
ret = class_create_file(&aw963xx->capsense_class, &class_attr_reset);
if (ret < 0) {
AWLOGE(p_sar->dev, "Create cali file failed (%d)\n", ret);
return ret;
}
ret = class_create_file(&aw963xx->capsense_class, &class_attr_int_state);
if (ret < 0) {
AWLOGE(p_sar->dev, "Create int_state file failed (%d)\n", ret);
@ -1284,6 +1334,8 @@ static void aw_sar_custom_flie_node_free(void *data)
int i = 0;
#endif
pr_info("%s enter\n",__func__);
if (data == NULL) {
return;
}
@ -1308,6 +1360,7 @@ static void aw_sar_custom_flie_node_free(void *data)
class_remove_file(&aw963xx->capsense_class, &class_attr_mode);
class_remove_file(&aw963xx->capsense_class, &class_attr_int_state);
class_remove_file(&aw963xx->capsense_class, &class_attr_cali);
class_remove_file(&aw963xx->capsense_class, &class_attr_reset);
class_unregister(&aw963xx->capsense_class);
}
@ -1356,6 +1409,8 @@ int32_t aw963xx_init(struct aw_sar *p_sar)
{
struct aw963xx *aw963xx = NULL;
pr_info("%s enter\n",__func__);
if (p_sar == NULL) {
AWLOGE(p_sar->dev, "para is NULL, error!");
return -AW_ERR;
@ -1381,6 +1436,7 @@ void aw963xx_deinit(struct aw_sar *p_sar)
{
struct aw963xx *aw963xx = NULL;
pr_info("%s enter\n",__func__);
if ((p_sar == NULL) || (p_sar->priv_data == NULL)) {
return;
}

View file

@ -2,7 +2,7 @@
#include "aw_sar.h"
#define AW_SAR_I2C_NAME "awinic_sar"
#define AW_SAR_DRIVER_VERSION "v0.1.5.2"
#define AW_SAR_DRIVER_VERSION "v0.1.5.14"
#define USB_POWER_SUPPLY_NAME "usb"
@ -2110,7 +2110,8 @@ static const struct dev_pm_ops aw_sar_pm_ops = {
};
static const struct of_device_id aw_sar_dt_match[] = {
{ .compatible = "awinic,aw_sar" },
{ .compatible = "awinic,aw_sar", },
{},
};
static const struct i2c_device_id aw_sar_i2c_id[] = {