support pmk8350 gpio3 as stylus clk.

TP:
  Support Pmk8350 gpio3 as the stylus clock for Rogue PVT, and the
output frequency is 19.2Mhz.

Change-Id: I5dae054b6170b921b7afee1853b7de7995531705
Reviewed-on: https://gerrit.mot.com/2111742
SLTApproved: Slta Waiver
SME-Granted: SME Approvals Granted
Tested-by: Jira Key
Reviewed-by: Jianqi Yang <yangj@motorola.com>
Submit-Approved: Jira Key
This commit is contained in:
litong20 2021-11-17 12:52:53 +08:00 • committed by litong
commit ce40bdb1a9
3 changed files with 151 additions and 20 deletions

View file

@ -1087,8 +1087,15 @@ static int goodix_parse_dt(struct device_node *node,
board_data->stylus_mode_ctrl = of_property_read_bool(node,
"goodix,stylus_mode-ctrl");
if (board_data->stylus_mode_ctrl)
if (board_data->stylus_mode_ctrl) {
ts_info("support goodix stylus mode");
/* get stylus clock name */
r = of_property_read_string(node, "goodix,stylus-clk-source", &name_tmp);
if (!r) {
ts_info("stylus clk source from source %s", name_tmp);
strncpy(board_data->stylus_clk_src, name_tmp, sizeof(board_data->stylus_clk_src));
}
}
board_data->sensitivity_ctrl = of_property_read_bool(node,
"goodix,sensitivity-ctrl");
@ -1377,6 +1384,61 @@ int goodix_ts_power_off(struct goodix_ts_core *cd)
return ret;
}
/**
* goodix_ts_stylus_clk_init - Config stylus clock
* return:0 ok, <0 failed
*/
static int goodix_ts_stylus_clk_init(struct goodix_ts_core *core_data)
{
int ret = 0;
struct goodix_ts_board_data *ts_bdata = board_data(core_data);
struct goodix_bus_interface *bus_interface = core_data->bus;
if (!ts_bdata->stylus_mode_ctrl) {
ts_err("stylus not support!");
return -EINVAL;
}
if (!strcmp(ts_bdata->stylus_clk_src, STYLUS_CLK_SRC_PMIC)) {
if (of_get_property(bus_interface->dev->of_node, "clocks", NULL)) {
core_data->stylus_clk = devm_clk_get(bus_interface->dev, "stylus_clk");
if (IS_ERR_OR_NULL(core_data->stylus_clk)) {
ts_err("failed to get stylus clk\n");
return -EINVAL;
}
}
} else if (!strcmp(ts_bdata->stylus_clk_src, STYLUS_CLK_SRC_GPIO)){
if (IS_ERR_OR_NULL(core_data->pinctrl)) {
ts_info("Failed to get pinctrl handler[need confirm]");
core_data->pinctrl = NULL;
return -EINVAL;
}
core_data->stylus_clk_active = pinctrl_lookup_state(core_data->pinctrl,
PINCTRL_STYLUS_CLK_ACTIVE);
if (IS_ERR_OR_NULL(core_data->stylus_clk_active)) {
ret = PTR_ERR(core_data->stylus_clk_active);
ts_err("Failed to get state clk pinctrl state:%s, ret:%d",
PINCTRL_STYLUS_CLK_ACTIVE, ret);
core_data->stylus_clk_active = NULL;
return ret;
}
ts_info("success get stylus clk pinctrl active state");
core_data->stylus_clk_suspend = pinctrl_lookup_state(core_data->pinctrl,
PINCTRL_STYLUS_CLK_SUSPEND);
if (IS_ERR_OR_NULL(core_data->stylus_clk_suspend)) {
ret = PTR_ERR(core_data->stylus_clk_suspend);
ts_err("Failed to get state clk pinctrl state:%s, ret:%d",
PINCTRL_STYLUS_CLK_SUSPEND, ret);
core_data->stylus_clk_suspend = NULL;
return ret;
}
ts_info("success get stylus clk pinctrl suspend state");
} else {
ts_err("The stylus clock source is invalid");
return -EINVAL;
}
return ret;
}
/**
* goodix_ts_pinctrl_init - Get pinctrl handler and pinctrl_state
@ -2235,14 +2297,6 @@ static int goodix_ts_probe(struct platform_device *pdev)
ts_err("failed parse device info form dts, %d", ret);
return -EINVAL;
}
if (of_get_property(bus_interface->dev->of_node, "clocks", NULL)) {
core_data->stylus_clk = devm_clk_get(bus_interface->dev, "stylus_clk");
if (IS_ERR_OR_NULL(core_data->stylus_clk)) {
ts_err("failed to get stylus clk\n");
}
}
} else {
ts_err("no valid device tree node found");
return -ENODEV;
@ -2288,6 +2342,11 @@ static int goodix_ts_probe(struct platform_device *pdev)
ts_err("Failed to select active pinstate, r:%d", ret);
}
/* get stylus clock*/
ret = goodix_ts_stylus_clk_init(core_data);
if (ret)
ts_err("failed get goodix stylus clock");
/* confirm it's goodix touch dev or not */
ret = core_data->hw_ops->dev_confirm(core_data);
if (ret) {

View file

@ -46,6 +46,11 @@
#define TS_DEFAULT_FIRMWARE "goodix_firmware.bin"
#define TS_DEFAULT_CFG_BIN "goodix_cfg_group.bin"
#define PINCTRL_STYLUS_CLK_ACTIVE "stylus_clk_active"
#define PINCTRL_STYLUS_CLK_SUSPEND "stylus_clk_suspend"
#define STYLUS_CLK_SRC_GPIO "stylus_clk_gpio"
#define STYLUS_CLK_SRC_PMIC "stylus_clk_pmic"
enum CORD_PROB_STA {
CORE_MODULE_UNPROBED = 0,
CORE_MODULE_PROB_SUCCESS = 1,
@ -269,6 +274,7 @@ struct goodix_ts_board_data {
bool pen_enable;
char fw_name[GOODIX_MAX_STR_LABLE_LEN];
char cfg_bin_name[GOODIX_MAX_STR_LABLE_LEN];
char stylus_clk_src[GOODIX_MAX_STR_LABLE_LEN]; /*stylus clock source*/
bool sensitivity_ctrl;
bool stylus_mode_ctrl;
@ -468,6 +474,8 @@ struct goodix_ts_core {
struct pinctrl *pinctrl;
struct pinctrl_state *pin_sta_active;
struct pinctrl_state *pin_sta_suspend;
struct pinctrl_state *stylus_clk_active;
struct pinctrl_state *stylus_clk_suspend;
int power_on;
int irq;

View file

@ -189,27 +189,85 @@ static ssize_t goodix_ts_sensitivity_store(struct device *dev,
return ret;
}
static int goodix_clock_enable(struct goodix_ts_core *core_data, bool mode) {
int ret = 0;
struct goodix_ts_board_data *ts_bdata;
ts_bdata = board_data(core_data);
if (!ts_bdata) {
ts_err("Failed to get ts board data");
return -ENODEV;
}
if (mode) {
if (!strcmp(ts_bdata->stylus_clk_src, STYLUS_CLK_SRC_PMIC)) {
if (IS_ERR_OR_NULL(core_data->stylus_clk)) {
ts_err("failed to get stylus clk\n");
return -EINVAL;
}
ret = clk_prepare_enable(core_data->stylus_clk);
if (ret) {
ts_err("failed to enable stylus clk\n");
return ret;
}
} else if (!strcmp(ts_bdata->stylus_clk_src, STYLUS_CLK_SRC_GPIO)){
if (IS_ERR_OR_NULL(core_data->stylus_clk_active)) {
ts_err("Failed to get state clk pinctrl state:%s",
PINCTRL_STYLUS_CLK_ACTIVE);
core_data->stylus_clk_active = NULL;
return -EINVAL;
}
ret = pinctrl_select_state(core_data->pinctrl,
core_data->stylus_clk_active);
if (ret < 0) {
ts_err("Failed to select active stylus clk state, ret:%d", ret);
return ret;
}
} else {
ts_err("stylus clock source is invalid");
return -EINVAL;
}
ts_info("success to enable stylus clk\n");
} else {
if (!strcmp(ts_bdata->stylus_clk_src, STYLUS_CLK_SRC_PMIC)) {
if (IS_ERR_OR_NULL(core_data->stylus_clk)) {
ts_err("failed to get stylus clk\n");
return -EINVAL;
}
clk_disable_unprepare(core_data->stylus_clk);
} else if (!strcmp(ts_bdata->stylus_clk_src, STYLUS_CLK_SRC_GPIO)){
if (IS_ERR_OR_NULL(core_data->stylus_clk_suspend)) {
ts_err("Failed to get state clk pinctrl state:%s",
PINCTRL_STYLUS_CLK_SUSPEND);
core_data->stylus_clk_suspend = NULL;
return -EINVAL;
}
ret = pinctrl_select_state(core_data->pinctrl,
core_data->stylus_clk_suspend);
if (ret < 0) {
ts_err("Failed to select stylus clk suspend state, ret:%d", ret);
return ret;
}
} else {
ts_err("stylus clock source is invalid");
return -EINVAL;
}
ts_info("success to disable stylus clk\n");
}
return ret;
}
static int goodix_stylus_mode(struct goodix_ts_core *core_data, int mode) {
int ret = 0;
if (IS_ERR_OR_NULL(core_data->stylus_clk)) {
ts_err("failed to get stylus clk\n");
return -EINVAL;
}
if (mode) {
ret = clk_prepare_enable(core_data->stylus_clk);
if (ret) {
ts_err("failed to enable stylus clk\n");
return ret;
}
ts_info("success to open stylus clk\n");
goodix_clock_enable(core_data, mode);
ret = goodix_ts_send_cmd(core_data, STYLUS_MODE_SWITCH_CMD, 5, mode, 0x00);
msleep(20);
} else {
ret = goodix_ts_send_cmd(core_data, STYLUS_MODE_SWITCH_CMD, 5, mode, 0x00);
msleep(20);
clk_disable_unprepare(core_data->stylus_clk);
ts_info("success to close stylus clk\n");
goodix_clock_enable(core_data, mode);
}
return ret;
@ -239,6 +297,12 @@ static ssize_t goodix_ts_stylus_mode_store(struct device *dev,
return size;
}
if (core_data->power_on == 0) {
core_data->stylus_mode = mode;
ts_debug("The touch is in sleep state, restore the value when resume\n");
return size;
}
ret = goodix_stylus_mode(core_data, mode);
if (ret) {
return ret;