sec_mmi: debug interface enhancements

This commit includes the following enhancements:
1) debug interfaces moved from Samsung specific sysfs path to I2C
   device path
2) write register interface added
3) write register and erase firmware interfaces only available
   in factory mode

Change-Id: I12504e99506c1a1bc76b3c9622814dbeac249438
Signed-off-by: Konstantin Makariev <hcv867@motorola.com>
Reviewed-on: https://gerrit.mot.com/1399692
SME-Granted: SME Approvals Granted
SLTApproved: Slta Waiver
Tested-by: Jira Key
Reviewed-by: Konstantin Makariev <kmakariev@motorola.com>
Submit-Approved: Jira Key
This commit is contained in:
Konstantin Makariev 2019-08-08 13:39:41 -05:00 • committed by Konstantin Makariev
commit d423d7e6bd
3 changed files with 182 additions and 84 deletions

View file

@ -824,6 +824,12 @@ void sec_ts_reinit(struct sec_ts_data *ts);
void sec_ts_sense_on(struct sec_ts_data *ts);
void sec_ts_irq_enable(struct sec_ts_data *ts, bool on);
void sec_ts_lv1_params(u8 cmd, int size);
ssize_t sec_ts_reg_store(struct device *dev,
struct device_attribute *attr, const char *buf, size_t size);
ssize_t sec_ts_regread_show(struct device *dev,
struct device_attribute *attr, char *buf);
#if (1)//!defined(CONFIG_SAMSUNG_PRODUCT_SHIP)
int sec_ts_raw_device_init(struct sec_ts_data *ts);

View file

@ -31,6 +31,7 @@
#include <linux/time.h>
#include <linux/vmalloc.h>
#include <linux/uaccess.h>
#include <soc/qcom/mmi_boot_info.h>
#include "sec_ts.h"
#include "sec_mmi.h"
@ -62,6 +63,15 @@ static ssize_t sec_mmi_flashprog_show(struct device *dev,
struct device_attribute *attr, char *buf);
static ssize_t sec_mmi_panel_supplier_show(struct device *dev,
struct device_attribute *attr, char *buf);
static ssize_t sec_mmi_address_store(struct device *dev,
struct device_attribute *attr, const char *buf, size_t size);
static ssize_t sec_mmi_size_store(struct device *dev,
struct device_attribute *attr, const char *buf, size_t size);
static ssize_t sec_mmi_write_store(struct device *dev,
struct device_attribute *attr, const char *buf, size_t size);
static ssize_t sec_mmi_data_show(struct device *dev,
struct device_attribute *attr, char *buf);
static DEVICE_ATTR(forcereflash, (S_IWUSR | S_IWGRP), NULL, sec_mmi_forcereflash_store);
static DEVICE_ATTR(doreflash, (S_IWUSR | S_IWGRP), NULL, sec_mmi_doreflash_store);
@ -73,8 +83,10 @@ static DEVICE_ATTR(buildid, S_IRUGO, sec_mmi_buildid_show, NULL);
static DEVICE_ATTR(flashprog, S_IRUGO, sec_mmi_flashprog_show, NULL);
static DEVICE_ATTR(poweron, S_IRUGO, sec_mmi_poweron_show, NULL);
static DEVICE_ATTR(reset, (S_IWUSR | S_IWGRP), NULL, sec_mmi_reset_store);
static DEVICE_ATTR(erase_all, (S_IWUSR | S_IWGRP), NULL, sec_mmi_erase_store);
static DEVICE_ATTR(panel_supplier, S_IRUGO, sec_mmi_panel_supplier_show, NULL);
static DEVICE_ATTR(address, (S_IWUSR | S_IWGRP), NULL, sec_mmi_address_store);
static DEVICE_ATTR(size, (S_IWUSR | S_IWGRP), NULL, sec_mmi_size_store);
static DEVICE_ATTR(data, S_IRUGO, sec_mmi_data_show, NULL);
static struct attribute *mmi_attributes[] = {
&dev_attr_forcereflash.attr,
@ -87,8 +99,10 @@ static struct attribute *mmi_attributes[] = {
&dev_attr_flashprog.attr,
&dev_attr_poweron.attr,
&dev_attr_reset.attr,
&dev_attr_erase_all.attr,
&dev_attr_panel_supplier.attr,
&dev_attr_address.attr,
&dev_attr_size.attr,
&dev_attr_data.attr,
NULL,
};
@ -96,6 +110,19 @@ static struct attribute_group mmi_attr_group = {
.attrs = mmi_attributes,
};
static DEVICE_ATTR(write, (S_IWUSR | S_IWGRP), NULL, sec_mmi_write_store);
static DEVICE_ATTR(erase_all, (S_IWUSR | S_IWGRP), NULL, sec_mmi_erase_store);
static struct attribute *factory_attributes[] = {
&dev_attr_write.attr,
&dev_attr_erase_all.attr,
NULL,
};
static struct attribute_group factory_attr_group = {
.attrs = factory_attributes,
};
/* Attribute: path (RO) */
static ssize_t path_show(struct device *dev,
struct device_attribute *attr, char *buf)
@ -578,6 +605,11 @@ static ssize_t sec_mmi_erase_store(struct device *dev,
unsigned long value = 0;
int err = 0;
if (ts->power_status == SEC_TS_STATE_POWER_OFF) {
dev_err(DEV_TS, "%s: Power off state\n", __func__);
return -EIO;
}
err = kstrtoul(buf, 10, &value);
if (err < 0) {
dev_err(DEV_TS, "%s: Failed to convert value\n", __func__);
@ -605,6 +637,7 @@ static ssize_t sec_mmi_drv_irq_store(struct device *dev,
struct sec_ts_data *ts = dev_get_drvdata(dev);
unsigned long value = 0;
int err = 0;
err = kstrtoul(buf, 10, &value);
if (err < 0) {
dev_err(DEV_TS, "%s: Failed to convert value\n", __func__);
@ -700,6 +733,119 @@ err_request_fw:
return result;
}
#define MAX_DATA_SZ 1024
static bool factory_mode;
static u8 reg_address;
static int data_size;
static ssize_t sec_mmi_address_store(struct device *dev,
struct device_attribute *attr, const char *buf, size_t size)
{
struct sec_ts_data *ts = dev_get_drvdata(dev);
int error;
long value;
error = kstrtol(buf, 0, &value);
if (error || value > MAX_DATA_SZ)
return -EINVAL;
reg_address = (u8)value;
dev_info(DEV_TS, "%s: read address 0x%02X\n", __func__, reg_address);
return size;
}
static ssize_t sec_mmi_size_store(struct device *dev,
struct device_attribute *attr, const char *buf, size_t size)
{
struct sec_ts_data *ts = dev_get_drvdata(dev);
int error;
long value;
error = kstrtol(buf, 0, &value);
if (error)
return -EINVAL;
data_size = (unsigned int)value;
dev_info(DEV_TS, "%s: read size %u\n", __func__, data_size);
return size;
}
static ssize_t sec_mmi_write_store(struct device *dev,
struct device_attribute *attr, const char *buf, size_t size)
{
struct sec_ts_data *ts = dev_get_drvdata(dev);
char ascii[3] = {0};
char *sptr, *eptr;
size_t data_sz = size;
u8 hex[MAX_DATA_SZ];
int byte, error;
long value;
if (*(buf + size - 1) == '\n')
data_sz--;
if ((data_sz%2 != 0) || (data_sz/2 > MAX_DATA_SZ)) {
dev_err(DEV_TS, "%s: odd input\n", __func__);
return -EINVAL;
}
sptr = (char *)buf;
eptr = (char *)buf + data_sz;
pr_debug("%s: data to write: ", __func__);
for (byte = 0; sptr < eptr; sptr += 2, byte++) {
memcpy(ascii, sptr, 2);
error = kstrtol(ascii, 16, &value);
if (error)
break;
hex[byte] = (u8)value;
pr_cont("0x%02x ", hex[byte]);
}
pr_cont("; total=%d\n", byte);
if (error) {
dev_err(DEV_TS, "%s: input conversion failed\n", __func__);
return -EINVAL;
}
error = sec_ts_reg_store(dev, attr, hex, byte);
if (error != byte) {
dev_err(DEV_TS, "%s: write error\n", __func__);
return -EIO;
}
dev_info(DEV_TS, "%s: written %d bytes to address 0x%02X\n",
__func__, byte, hex[0]);
return size;
}
static ssize_t sec_mmi_data_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct sec_ts_data *ts = dev_get_drvdata(dev);
u8 buffer[MAX_DATA_SZ];
ssize_t length, blen = 0;
int i;
/* init parameters required for sec_ts_regread_show() */
sec_ts_lv1_params(reg_address, data_size);
length = sec_ts_regread_show(dev, attr, buffer);
if (length != data_size)
return sprintf(buf,
"error %zu reading %u bytes from reg addr=0x%02X\n",
length, data_size, reg_address);
dev_info(DEV_TS, "%s: read %u bytes from reg addr=0x%02X\n",
__func__, data_size, reg_address);
for (i = 0; i < length; i++)
blen += scnprintf(buf + blen, PAGE_SIZE - blen, "%02X ", buffer[i]);
blen += scnprintf(buf + blen, PAGE_SIZE - blen, "\n");
return blen;
}
static void sec_mmi_sysfs(struct sec_mmi_data *data, bool enable)
{
struct sec_ts_data *ts = data->ts_ptr;
@ -709,11 +855,22 @@ static void sec_mmi_sysfs(struct sec_mmi_data *data, bool enable)
ret = sysfs_create_group(&data->i2c_client->dev.kobj, &mmi_attr_group);
if (ret < 0) {
input_err(true, DEV_TS,
"%s: Failed to create MMI sysfs attributes\n", __func__);
dev_err(DEV_TS, "%s: Failed to create MMI sysfs attrs\n", __func__);
}
} else
if (strncmp(bi_bootmode(), "mot-factory", strlen("mot-factory")) == 0) {
ret = sysfs_create_group(&data->i2c_client->dev.kobj,
&factory_attr_group);
if (ret < 0)
dev_err(DEV_TS, "%s: Failed to create factory sysfs\n", __func__);
else
factory_mode = true;
}
} else {
sysfs_remove_group(&data->i2c_client->dev.kobj, &mmi_attr_group);
if (factory_mode)
sysfs_remove_group(&data->i2c_client->dev.kobj, &factory_attr_group);
}
}
int sec_mmi_data_init(struct sec_ts_data *ts, bool enable)
@ -726,7 +883,7 @@ int sec_mmi_data_init(struct sec_ts_data *ts, bool enable)
data = ts->mmi_ptr;
if (!data) {
input_err(true, DEV_TS, "%s: MMI data is NULL\n", __func__);
dev_err(DEV_TS, "%s: MMI data is NULL\n", __func__);
return 0;
}
@ -748,18 +905,18 @@ int sec_mmi_data_init(struct sec_ts_data *ts, bool enable)
/* DRM panel status */
panel_ready = dsi_display_is_panel_enable(data->ctrl_dsi,
&probe_status, &pname);
input_info(true, DEV_TS, "%s: drm: probe=%d, enable=%d, panel'%s'\n",
dev_info(DEV_TS, "%s: drm: probe=%d, enable=%d, panel'%s'\n",
__func__, probe_status, panel_ready, pname);
/* check panel binding */
if (data->bound_display && (probe_status == -ENODEV ||
(pname && strncmp(pname, data->bound_display,
strlen(data->bound_display))))) {
input_err(true, DEV_TS, "%s: panel binding failed\n", __func__);
dev_err(DEV_TS, "%s: panel binding failed\n", __func__);
return -ENODEV;
}
if (pname && strstr(pname, "dummy")) {
input_info(true, DEV_TS, "%s: dummy panel; exiting...\n", __func__);
dev_info(DEV_TS, "%s: dummy panel; exiting...\n", __func__);
return -ENODEV;
}
#endif

View file

@ -39,47 +39,29 @@ static int lv1_readsize;
static int lv1_readremain;
static int lv1_readoffset;
static ssize_t sec_ts_reg_store(struct device *dev,
struct device_attribute *attr, const char *buf, size_t size);
static ssize_t sec_ts_regreadsize_store(struct device *dev,
struct device_attribute *attr, const char *buf, size_t size);
static inline ssize_t sec_ts_store_error(struct device *dev,
struct device_attribute *attr, const char *buf, size_t count);
static ssize_t sec_ts_enter_recovery_store(struct device *dev,
struct device_attribute *attr, const char *buf, size_t size);
static ssize_t sec_ts_regread_show(struct device *dev,
struct device_attribute *attr, char *buf);
static ssize_t sec_ts_gesture_status_show(struct device *dev,
struct device_attribute *attr, char *buf);
static inline ssize_t sec_ts_show_error(struct device *dev,
struct device_attribute *attr, char *buf);
static ssize_t sec_ts_address_store(struct device *dev,
struct device_attribute *attr, const char *buf, size_t size);
static ssize_t sec_ts_size_store(struct device *dev,
struct device_attribute *attr, const char *buf, size_t size);
static ssize_t sec_ts_data_show(struct device *dev,
struct device_attribute *attr, char *buf);
static DEVICE_ATTR(sec_ts_reg, (S_IWUSR | S_IWGRP), NULL, sec_ts_reg_store);
static DEVICE_ATTR(sec_ts_regreadsize, (S_IWUSR | S_IWGRP), NULL, sec_ts_regreadsize_store);
static DEVICE_ATTR(sec_ts_enter_recovery, (S_IWUSR | S_IWGRP), NULL, sec_ts_enter_recovery_store);
static DEVICE_ATTR(sec_ts_regread, S_IRUGO, sec_ts_regread_show, NULL);
static DEVICE_ATTR(sec_ts_gesture_status, S_IRUGO, sec_ts_gesture_status_show, NULL);
static DEVICE_ATTR(address, (S_IWUSR | S_IWGRP), NULL, sec_ts_address_store);
static DEVICE_ATTR(size, (S_IWUSR | S_IWGRP), NULL, sec_ts_size_store);
static DEVICE_ATTR(data, S_IRUGO, sec_ts_data_show, NULL);
static struct attribute *cmd_attributes[] = {
&dev_attr_sec_ts_reg.attr,
&dev_attr_sec_ts_regreadsize.attr,
&dev_attr_sec_ts_enter_recovery.attr,
&dev_attr_sec_ts_regread.attr,
&dev_attr_sec_ts_gesture_status.attr,
&dev_attr_address.attr,
&dev_attr_size.attr,
&dev_attr_data.attr,
NULL,
};
@ -88,7 +70,15 @@ static struct attribute_group cmd_attr_group = {
};
/* for debugging--------------------------------------------------------------------------------------*/
static ssize_t sec_ts_reg_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size)
void sec_ts_lv1_params(u8 cmd, int size)
{
lv1cmd = cmd;
lv1_readsize = size;
lv1_readoffset = 0;
lv1_readremain = 0;
}
ssize_t sec_ts_reg_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size)
{
struct sec_ts_data *ts = dev_get_drvdata(dev);
@ -104,7 +94,7 @@ static ssize_t sec_ts_reg_store(struct device *dev, struct device_attribute *att
return size;
}
static ssize_t sec_ts_regread_show(struct device *dev, struct device_attribute *attr, char *buf)
ssize_t sec_ts_regread_show(struct device *dev, struct device_attribute *attr, char *buf)
{
struct sec_ts_data *ts = dev_get_drvdata(dev);
int ret;
@ -192,61 +182,6 @@ static ssize_t sec_ts_regreadsize_store(struct device *dev, struct device_attrib
return size;
}
#define MAX_DATA_SZ 1024
static ssize_t sec_ts_address_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size)
{
struct sec_ts_data *ts = dev_get_drvdata(dev);
int error;
long value;
error = kstrtol(buf, 0, &value);
if (error || value > MAX_DATA_SZ)
return -EINVAL;
lv1cmd = (u8)value;
input_info(true, &ts->client->dev, "%s: read address 0x%02X\n", __func__, lv1cmd);
return size;
}
static ssize_t sec_ts_size_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size)
{
struct sec_ts_data *ts = dev_get_drvdata(dev);
int error;
long value;
error = kstrtol(buf, 0, &value);
if (error)
return -EINVAL;
lv1_readsize = (unsigned int)value;
lv1_readoffset = 0;
lv1_readremain = 0;
input_info(true, &ts->client->dev, "%s: read size %u\n", __func__, lv1_readsize);
return size;
}
static ssize_t sec_ts_data_show(struct device *dev, struct device_attribute *attr, char *buf)
{
struct sec_ts_data *ts = dev_get_drvdata(dev);
u8 buffer[MAX_DATA_SZ];
ssize_t length, blen = 0;
int i;
length = sec_ts_regread_show(dev, attr, buffer);
if (length != lv1_readsize)
return sprintf(buf, "error %zu reading %u bytes from reg addr=0x%02X\n", length, lv1_readsize, lv1cmd);
input_info(true, &ts->client->dev, "%s: %u bytes from reg addr=0x%02X\n", __func__, lv1_readsize, lv1cmd);
for (i = 0; i < length; i++)
blen += scnprintf(buf + blen, PAGE_SIZE - blen, "%02X ", buffer[i]);
blen += scnprintf(buf + blen, PAGE_SIZE - blen, "\n");
return blen;
}
static ssize_t sec_ts_enter_recovery_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size)
{
struct sec_ts_data *ts = dev_get_drvdata(dev);