mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-10 14:19:09 -04:00
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:
parent
a23570c75d
commit
ce40bdb1a9
3 changed files with 151 additions and 20 deletions
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Reference in a new issue