From a8d4e9553d050a629a6ab54b948c63df468be486 Mon Sep 17 00:00:00 2001 From: Zhibin Huang Date: Tue, 6 Feb 2024 15:27:09 +0000 Subject: [PATCH 1/5] misc: rk628: unify the node name of interface in dts Type: Fix Redmine ID: N/A Associated modifications: N/A Test: N/A Signed-off-by: Zhibin Huang Change-Id: I59a56b3def8f20121cb9bf53b65fc5ef3bdad6e7 --- drivers/misc/rk628/rk628.c | 30 ++++++++++++++++++++---------- drivers/misc/rk628/rk628_dsi.c | 5 ++++- 2 files changed, 24 insertions(+), 11 deletions(-) diff --git a/drivers/misc/rk628/rk628.c b/drivers/misc/rk628/rk628.c index 4cbba8aa6cda..ac3387c5437c 100644 --- a/drivers/misc/rk628/rk628.c +++ b/drivers/misc/rk628/rk628.c @@ -723,40 +723,50 @@ static int rk628_display_route_info_parse(struct rk628 *rk628) int ret = 0; u32 val; - if (of_property_read_bool(rk628->dev->of_node, "rk628,hdmi-in")) { + if (of_property_read_bool(rk628->dev->of_node, "rk628-hdmi-in") || + of_property_read_bool(rk628->dev->of_node, "rk628,hdmi-in")) { rk628->input_mode = BIT(INPUT_MODE_HDMI); - } else if (of_property_read_bool(rk628->dev->of_node, "rk628,rgb-in")) { + } else if (of_property_read_bool(rk628->dev->of_node, "rk628-rgb-in") || + of_property_read_bool(rk628->dev->of_node, "rk628,rgb-in")) { rk628->input_mode = BIT(INPUT_MODE_RGB); ret = rk628_rgb_parse(rk628, NULL); - } else if (of_property_read_bool(rk628->dev->of_node, "rk628,bt1120-in")) { + } else if (of_property_read_bool(rk628->dev->of_node, "rk628-bt1120-in") || + of_property_read_bool(rk628->dev->of_node, "rk628,bt1120-in")) { rk628->input_mode = BIT(INPUT_MODE_BT1120); ret = rk628_rgb_parse(rk628, NULL); } else { rk628->input_mode = BIT(INPUT_MODE_RGB); } - if ((np = of_get_child_by_name(rk628->dev->of_node, "rk628-gvi"))) { + if ((np = of_get_child_by_name(rk628->dev->of_node, "rk628-gvi-out")) || + (np = of_get_child_by_name(rk628->dev->of_node, "rk628-gvi"))) { rk628->output_mode |= BIT(OUTPUT_MODE_GVI); ret = rk628_gvi_parse(rk628, np); - } else if ((np = of_get_child_by_name(rk628->dev->of_node, "rk628-lvds"))) { + } else if ((np = of_get_child_by_name(rk628->dev->of_node, "rk628-lvds-out")) || + (np = of_get_child_by_name(rk628->dev->of_node, "rk628-lvds"))) { rk628->output_mode |= BIT(OUTPUT_MODE_LVDS); ret = rk628_lvds_parse(rk628, np); - } else if ((np = of_get_child_by_name(rk628->dev->of_node, "rk628-dsi"))) { + } else if ((np = of_get_child_by_name(rk628->dev->of_node, "rk628-dsi-out")) || + (np = of_get_child_by_name(rk628->dev->of_node, "rk628-dsi"))) { rk628->output_mode |= BIT(OUTPUT_MODE_DSI); ret = rk628_dsi_parse(rk628, np); - } else if (of_property_read_bool(rk628->dev->of_node, "rk628,csi-out")) { + } else if (of_property_read_bool(rk628->dev->of_node, "rk628-csi-out") || + of_property_read_bool(rk628->dev->of_node, "rk628,csi-out")) { rk628->output_mode |= BIT(OUTPUT_MODE_CSI); } if (np) of_node_put(np); - if (of_property_read_bool(rk628->dev->of_node, "rk628,hdmi-out")) + if (of_property_read_bool(rk628->dev->of_node, "rk628-hdmi-out") || + of_property_read_bool(rk628->dev->of_node, "rk628,hdmi-out")) rk628->output_mode |= BIT(OUTPUT_MODE_HDMI); - if (of_property_read_bool(rk628->dev->of_node, "rk628-rgb")) { + if (of_property_read_bool(rk628->dev->of_node, "rk628-rgb-out") || + of_property_read_bool(rk628->dev->of_node, "rk628-rgb")) { rk628->output_mode |= BIT(OUTPUT_MODE_RGB); ret = rk628_rgb_parse(rk628, NULL); - } else if (of_property_read_bool(rk628->dev->of_node, "rk628-bt1120")) { + } else if (of_property_read_bool(rk628->dev->of_node, "rk628-bt1120-out") || + of_property_read_bool(rk628->dev->of_node, "rk628-bt1120")) { rk628->output_mode |= BIT(OUTPUT_MODE_BT1120); ret = rk628_rgb_parse(rk628, NULL); } diff --git a/drivers/misc/rk628/rk628_dsi.c b/drivers/misc/rk628/rk628_dsi.c index 9f93bfe35ffe..6a49ed10e783 100644 --- a/drivers/misc/rk628/rk628_dsi.c +++ b/drivers/misc/rk628/rk628_dsi.c @@ -830,7 +830,10 @@ static u32 rk628_dsi_get_lane_rate(const struct rk628_dsi *dsi) u32 max_lane_rate = 1500; u8 bpp, lanes; - dsi_np = of_find_node_by_name(dsi->rk628->dev->of_node, "rk628-dsi"); + dsi_np = of_find_node_by_name(dsi->rk628->dev->of_node, "rk628-dsi-out"); + if (!dsi_np) + dsi_np = of_find_node_by_name(dsi->rk628->dev->of_node, + "rk628-dsi"); if (dsi_np && !of_property_read_u32(dsi_np, "rockchip,lane-mbps", &value)) { lane_rate = value; } else { From 25aeddc5167cc876c5b890699d3dd24b0a09a534 Mon Sep 17 00:00:00 2001 From: Zhibin Huang Date: Tue, 6 Feb 2024 15:29:39 +0000 Subject: [PATCH 2/5] arm64: dts: rockchip: rk3568-evb-rk628: unify the node name of interface in dts Type: N/A Redmine ID: N/A Associated modifications: https://10.10.10.29/c/rk/kernel/+/210058 Test: N/A Signed-off-by: Zhibin Huang Change-Id: I6e11cb752ca57f3a34678cbf44379d3be3b47985 --- .../boot/dts/rockchip/rk3568-evb-rk628-hdmi2dsi-ddr4-v10.dts | 4 ++-- .../dts/rockchip/rk3568-evb-rk628-hdmi2dsi-dual-ddr4-v10.dts | 4 ++-- .../boot/dts/rockchip/rk3568-evb-rk628-hdmi2gvi-ddr4-v10.dts | 4 ++-- .../boot/dts/rockchip/rk3568-evb-rk628-hdmi2lvds-ddr4-v10.dts | 4 ++-- .../dts/rockchip/rk3568-evb-rk628-hdmi2lvds-dual-ddr4-v10.dts | 4 ++-- .../boot/dts/rockchip/rk3568-evb-rk628-rgb2dsi-ddr4-v10.dts | 4 ++-- .../boot/dts/rockchip/rk3568-evb-rk628-rgb2gvi-ddr4-v10.dts | 4 ++-- .../boot/dts/rockchip/rk3568-evb-rk628-rgb2hdmi-ddr4-v10.dts | 4 ++-- .../boot/dts/rockchip/rk3568-evb-rk628-rgb2lvds-ddr4-v10.dts | 4 ++-- .../dts/rockchip/rk3568-evb-rk628-rgb2lvds-dual-ddr4-v10.dts | 4 ++-- 10 files changed, 20 insertions(+), 20 deletions(-) diff --git a/arch/arm64/boot/dts/rockchip/rk3568-evb-rk628-hdmi2dsi-ddr4-v10.dts b/arch/arm64/boot/dts/rockchip/rk3568-evb-rk628-hdmi2dsi-ddr4-v10.dts index 4ecd56149a24..1397d9b3522b 100644 --- a/arch/arm64/boot/dts/rockchip/rk3568-evb-rk628-hdmi2dsi-ddr4-v10.dts +++ b/arch/arm64/boot/dts/rockchip/rk3568-evb-rk628-hdmi2dsi-ddr4-v10.dts @@ -24,8 +24,8 @@ panel-unprepare-delay-ms = <10>; panel-disable-delay-ms = <60>; - rk628,hdmi-in; - rk628-dsi { + rk628-hdmi-in; + rk628-dsi-out { //rockchip,dual-channel; dsi,eotp; dsi,video-mode; diff --git a/arch/arm64/boot/dts/rockchip/rk3568-evb-rk628-hdmi2dsi-dual-ddr4-v10.dts b/arch/arm64/boot/dts/rockchip/rk3568-evb-rk628-hdmi2dsi-dual-ddr4-v10.dts index 0892e5e9ee47..80a73eefe453 100644 --- a/arch/arm64/boot/dts/rockchip/rk3568-evb-rk628-hdmi2dsi-dual-ddr4-v10.dts +++ b/arch/arm64/boot/dts/rockchip/rk3568-evb-rk628-hdmi2dsi-dual-ddr4-v10.dts @@ -22,8 +22,8 @@ panel-disable-delay-ms = <240>; panel-init-delay-ms = <240>; - rk628,hdmi-in; - rk628-dsi { + rk628-hdmi-in; + rk628-dsi-out { rockchip,lane-mbps = <1100>; rockchip,dual-channel; dsi,eotp; diff --git a/arch/arm64/boot/dts/rockchip/rk3568-evb-rk628-hdmi2gvi-ddr4-v10.dts b/arch/arm64/boot/dts/rockchip/rk3568-evb-rk628-hdmi2gvi-ddr4-v10.dts index 93631f254526..42e965bb0aa8 100644 --- a/arch/arm64/boot/dts/rockchip/rk3568-evb-rk628-hdmi2gvi-ddr4-v10.dts +++ b/arch/arm64/boot/dts/rockchip/rk3568-evb-rk628-hdmi2gvi-ddr4-v10.dts @@ -31,8 +31,8 @@ clocks = <&pmucru CLK_WIFI>; clock-names = "soc_24M"; - rk628,hdmi-in; - rk628-gvi { + rk628-hdmi-in; + rk628-gvi-out { /* "rgb666" * "rgb888" * "rgb101010" diff --git a/arch/arm64/boot/dts/rockchip/rk3568-evb-rk628-hdmi2lvds-ddr4-v10.dts b/arch/arm64/boot/dts/rockchip/rk3568-evb-rk628-hdmi2lvds-ddr4-v10.dts index 66f0401fb329..b26fd1b3d910 100644 --- a/arch/arm64/boot/dts/rockchip/rk3568-evb-rk628-hdmi2lvds-ddr4-v10.dts +++ b/arch/arm64/boot/dts/rockchip/rk3568-evb-rk628-hdmi2lvds-ddr4-v10.dts @@ -22,8 +22,8 @@ panel-unprepare-delay-ms = <10>; panel-disable-delay-ms = <60>; - rk628,hdmi-in; - rk628-lvds { + rk628-hdmi-in; + rk628-lvds-out { /* "jeida_18","vesa_24","vesa_18" */ bus-format = "jeida_24"; diff --git a/arch/arm64/boot/dts/rockchip/rk3568-evb-rk628-hdmi2lvds-dual-ddr4-v10.dts b/arch/arm64/boot/dts/rockchip/rk3568-evb-rk628-hdmi2lvds-dual-ddr4-v10.dts index b48bb44cc2bf..faaeddaf437c 100644 --- a/arch/arm64/boot/dts/rockchip/rk3568-evb-rk628-hdmi2lvds-dual-ddr4-v10.dts +++ b/arch/arm64/boot/dts/rockchip/rk3568-evb-rk628-hdmi2lvds-dual-ddr4-v10.dts @@ -25,8 +25,8 @@ panel-unprepare-delay-ms = <10>; panel-disable-delay-ms = <60>; - rk628,hdmi-in; - rk628-lvds { + rk628-hdmi-in; + rk628-lvds-out { /* "jeida_18","vesa_24","vesa_18" */ bus-format = "vesa_24"; diff --git a/arch/arm64/boot/dts/rockchip/rk3568-evb-rk628-rgb2dsi-ddr4-v10.dts b/arch/arm64/boot/dts/rockchip/rk3568-evb-rk628-rgb2dsi-ddr4-v10.dts index 804640323de1..8dd6d3e66cc8 100644 --- a/arch/arm64/boot/dts/rockchip/rk3568-evb-rk628-rgb2dsi-ddr4-v10.dts +++ b/arch/arm64/boot/dts/rockchip/rk3568-evb-rk628-rgb2dsi-ddr4-v10.dts @@ -55,8 +55,8 @@ panel-unprepare-delay-ms = <10>; panel-disable-delay-ms = <60>; - rk628,rgb-in; - rk628-dsi { + rk628-rgb-in; + rk628-dsi-out { //rockchip,dual-channel; dsi,eotp; dsi,video-mode; diff --git a/arch/arm64/boot/dts/rockchip/rk3568-evb-rk628-rgb2gvi-ddr4-v10.dts b/arch/arm64/boot/dts/rockchip/rk3568-evb-rk628-rgb2gvi-ddr4-v10.dts index 9b47d9eda21a..cf252d31c559 100644 --- a/arch/arm64/boot/dts/rockchip/rk3568-evb-rk628-rgb2gvi-ddr4-v10.dts +++ b/arch/arm64/boot/dts/rockchip/rk3568-evb-rk628-rgb2gvi-ddr4-v10.dts @@ -62,8 +62,8 @@ clocks = <&pmucru CLK_WIFI>; clock-names = "soc_24M"; - rk628,rgb-in; - rk628-gvi { + rk628-rgb-in; + rk628-gvi-out { /* "rgb666" * "rgb888" * "rgb101010" diff --git a/arch/arm64/boot/dts/rockchip/rk3568-evb-rk628-rgb2hdmi-ddr4-v10.dts b/arch/arm64/boot/dts/rockchip/rk3568-evb-rk628-rgb2hdmi-ddr4-v10.dts index 83b62f996aff..16d185cb7ad6 100644 --- a/arch/arm64/boot/dts/rockchip/rk3568-evb-rk628-rgb2hdmi-ddr4-v10.dts +++ b/arch/arm64/boot/dts/rockchip/rk3568-evb-rk628-rgb2hdmi-ddr4-v10.dts @@ -23,8 +23,8 @@ pinctrl-names = "default"; pinctrl-0 = <&rk628_reset &refclk_pins>; - rk628,rgb-in; - rk628,hdmi-out; + rk628-rgb-in; + rk628-hdmi-out; status = "okay"; port { diff --git a/arch/arm64/boot/dts/rockchip/rk3568-evb-rk628-rgb2lvds-ddr4-v10.dts b/arch/arm64/boot/dts/rockchip/rk3568-evb-rk628-rgb2lvds-ddr4-v10.dts index 28adb73ce751..01a62e8f8850 100644 --- a/arch/arm64/boot/dts/rockchip/rk3568-evb-rk628-rgb2lvds-ddr4-v10.dts +++ b/arch/arm64/boot/dts/rockchip/rk3568-evb-rk628-rgb2lvds-ddr4-v10.dts @@ -56,8 +56,8 @@ panel-unprepare-delay-ms = <10>; panel-disable-delay-ms = <60>; - rk628,rgb-in; - rk628-lvds { + rk628-rgb-in; + rk628-lvds-out { /* "jeida_18","vesa_24","vesa_18" */ bus-format = "jeida_24"; diff --git a/arch/arm64/boot/dts/rockchip/rk3568-evb-rk628-rgb2lvds-dual-ddr4-v10.dts b/arch/arm64/boot/dts/rockchip/rk3568-evb-rk628-rgb2lvds-dual-ddr4-v10.dts index 65321128ec17..82e344a37036 100644 --- a/arch/arm64/boot/dts/rockchip/rk3568-evb-rk628-rgb2lvds-dual-ddr4-v10.dts +++ b/arch/arm64/boot/dts/rockchip/rk3568-evb-rk628-rgb2lvds-dual-ddr4-v10.dts @@ -57,8 +57,8 @@ panel-unprepare-delay-ms = <10>; panel-disable-delay-ms = <60>; - rk628,rgb-in; - rk628-lvds { + rk628-rgb-in; + rk628-lvds-out { /* "jeida_18","vesa_24","vesa_18" */ bus-format = "vesa_24"; From 379dfa43505725a7f14b237372f42aee460c7786 Mon Sep 17 00:00:00 2001 From: Zhibin Huang Date: Tue, 6 Feb 2024 15:31:28 +0000 Subject: [PATCH 3/5] ARM: dts: rockchip: rk3036-evb1-ddr3-v10: unify the rk628 node name of interface in dts Type: Fix Redmine ID: N/A Associated modifications: https://10.10.10.29/c/rk/kernel/+/210058 Test: N/A Signed-off-by: Zhibin Huang Change-Id: Ic650b9ddda9f9202e430f7459ee86f0b73fac479 --- arch/arm/boot/dts/rk3036-evb1-ddr3-v10.dts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/boot/dts/rk3036-evb1-ddr3-v10.dts b/arch/arm/boot/dts/rk3036-evb1-ddr3-v10.dts index 85a1c67e79fc..7539bd2846b5 100644 --- a/arch/arm/boot/dts/rk3036-evb1-ddr3-v10.dts +++ b/arch/arm/boot/dts/rk3036-evb1-ddr3-v10.dts @@ -226,8 +226,8 @@ reset-gpios = <&gpio0 RK_PA3 GPIO_ACTIVE_LOW>; plugin-det-gpios = <&gpio0 RK_PA0 GPIO_ACTIVE_LOW>; status = "okay"; - rk628,hdmi-in; - rk628-dsi { + rk628-hdmi-in; + rk628-dsi-out { //rockchip,dual-channel; dsi,eotp; dsi,video-mode; From ae97b71b7a2387d1eadd6398e63769dc1b8a4374 Mon Sep 17 00:00:00 2001 From: Zhibin Huang Date: Sun, 4 Feb 2024 07:20:21 +0000 Subject: [PATCH 4/5] misc: rk628: optimize input and output mode information 1. Fixed the issue where the log displays input and output mode information abnormally in some scenarios. 2. The input and output mode information of log and summary are obtained from the same function to facilitate later maintenance. Type: Fix Redmine ID: N/A Associated modifications: N/A Test: dmesg | grep "rk628.*input_mode.*output_mode" cat /sys/kernel/debug/rk628/2-0050/summary Signed-off-by: Zhibin Huang Change-Id: I9c4549d1673417701dc929432b96fa802632e63c --- drivers/misc/rk628/rk628.c | 137 +++++++++++++------------------------ 1 file changed, 49 insertions(+), 88 deletions(-) diff --git a/drivers/misc/rk628/rk628.c b/drivers/misc/rk628/rk628.c index ac3387c5437c..a2781653a3c7 100644 --- a/drivers/misc/rk628/rk628.c +++ b/drivers/misc/rk628/rk628.c @@ -672,49 +672,56 @@ static bool rk628_display_route_check(struct rk628 *rk628) return true; } -static void rk628_final_display_route(struct rk628 *rk628) +static void rk628_current_display_route(struct rk628 *rk628, char *input_s, + int input_s_len, char *output_s, + int output_s_len) { - char *input = NULL; - char *output = NULL; - char buf[20]; + *input_s = '\0'; + *output_s = '\0'; - if (rk628_input_is_hdmi(rk628)) - input = "hdmi"; + if (rk628_input_is_rgb(rk628)) + strlcat(input_s, "RGB", input_s_len); else if (rk628_input_is_bt1120(rk628)) - input = "bt1120"; + strlcat(input_s, "BT1120", input_s_len); + else if (rk628_input_is_hdmi(rk628)) + strlcat(input_s, "HDMI", input_s_len); else - input = "rgb"; + strlcat(input_s, "unknown", input_s_len); + + if (rk628_output_is_rgb(rk628)) + strlcat(output_s, "RGB ", output_s_len); + + if (rk628_output_is_bt1120(rk628)) + strlcat(output_s, "BT1120 ", output_s_len); if (rk628_output_is_gvi(rk628)) - output = "gvi"; - else if (rk628_output_is_lvds(rk628)) - output = "lvds"; - else if (rk628_output_is_dsi(rk628)) - output = "dsi"; - else if (rk628_output_is_csi(rk628)) - output = "csi"; + strlcat(output_s, "GVI ", output_s_len); - if (rk628_output_is_bt1120(rk628)) { - if (output) - sprintf(buf, "%s & %s", output, "bt1120"); - else - output = "bt1120"; - } else if (rk628_output_is_rgb(rk628)) { - if (output) - sprintf(buf, "%s & %s", output, "rgb"); - else - output = "rgb"; - } + if (rk628_output_is_lvds(rk628)) + strncat(output_s, "LVDS ", output_s_len); - if (rk628_output_is_hdmi(rk628)) { - if (output) - sprintf(buf, "%s & %s", output, "hdmi"); - else - output = "hdmi"; - } + if (rk628_output_is_dsi(rk628)) + strlcat(output_s, "DSI ", output_s_len); - dev_info(rk628->dev, "input_mode:%s output_mode:%s\n", input, - hweight32(rk628->output_mode) > 1 ? buf : output); + if (rk628_output_is_csi(rk628)) + strlcat(output_s, "CSI ", output_s_len); + + if (rk628_output_is_hdmi(rk628)) + strlcat(output_s, "HDMI ", output_s_len); + + if (!strlen(output_s)) + strlcat(output_s, "unknown", output_s_len); +} + +static void rk628_show_current_display_route(struct rk628 *rk628) +{ + char input_s[10], output_s[30]; + + rk628_current_display_route(rk628, input_s, sizeof(input_s), + output_s, sizeof(output_s)); + + dev_info(rk628->dev, "input_mode: %s, output_mode: %s\n", input_s, + output_s); } static int rk628_display_route_info_parse(struct rk628 *rk628) @@ -889,25 +896,6 @@ static int rk628_display_timings_get(struct rk628 *rk628) pr_info(args); \ } while (0) -static void rk628_show_input_mode(struct seq_file *s) -{ - struct rk628 *rk628 = s->private; - char input_s[10] = {0}; - - /* show input mode */ - if (rk628_input_is_hdmi(rk628)) - strcpy(input_s, "HDMI"); - else if (rk628_input_is_bt1120(rk628)) - strcpy(input_s, "BT1120"); - else if (rk628_input_is_rgb(rk628)) - strcpy(input_s, "RGB"); - - if (!strlen(input_s)) - strcpy(input_s, "unknown "); - - DEBUG_PRINT("input: %s\n", input_s); -} - static void rk628_show_resolution(struct seq_file *s) { struct rk628 *rk628 = s->private; @@ -1005,38 +993,6 @@ static void rk628_show_input_resolution(struct seq_file *s) rk628_show_resolution(s); } -static void rk628_show_output_mode(struct seq_file *s) -{ - struct rk628 *rk628 = s->private; - char output_s[30] = {0}; - char *p = output_s; - - if (rk628_output_is_gvi(rk628)) - strcpy(p, "GVI "); - else if (rk628_output_is_lvds(rk628)) - strcpy(p, "LVDS "); - else if (rk628_output_is_dsi(rk628)) - strcpy(p, "DSI "); - else if (rk628_output_is_csi(rk628)) - strcpy(p, "CSI "); - p += strlen(p); - - if (rk628_output_is_hdmi(rk628)) { - strcpy(p, "HDMI "); - p += strlen(p); - } - - if (rk628_output_is_rgb(rk628)) - strcpy(p, "RGB "); - else if (rk628_output_is_bt1120(rk628)) - strcpy(p, "BT1120 "); - - if (!strlen(output_s)) - strcpy(p, "unknown "); - - DEBUG_PRINT("output: %s\n", output_s); -} - static void rk628_show_output_resolution(struct seq_file *s) { struct rk628 *rk628 = s->private; @@ -1147,16 +1103,20 @@ static void rk628_show_csc_info(struct seq_file *s) static int rk628_debugfs_dump(struct seq_file *s, void *data) { struct rk628 *rk628 = s->private; + char input_s[10], output_s[30]; u32 val; int sw_hsync_pol, sw_vsync_pol; u32 dsp_frame_v_start, dsp_frame_h_start; + rk628_current_display_route(rk628, input_s, sizeof(input_s), + output_s, sizeof(output_s)); + /* show input info */ - rk628_show_input_mode(s); + DEBUG_PRINT("input: %s\n", input_s); rk628_show_input_resolution(s); /* show output info */ - rk628_show_output_mode(s); + DEBUG_PRINT("output: %s\n", output_s); rk628_show_output_resolution(s); /* show csc info */ @@ -1453,13 +1413,14 @@ rk628_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) if (ret) goto err_clk; + rk628_show_current_display_route(rk628); + if (!rk628_display_route_check(rk628)) { dev_err(dev, "display route check err\n"); ret = -EINVAL; goto err_clk; } - rk628_final_display_route(rk628); rk628_pwr_consumption_init(rk628); #ifdef CONFIG_FB From 5fe35955d774cc30268c13ee4d8b7a5709505269 Mon Sep 17 00:00:00 2001 From: Huang zhibao Date: Mon, 13 Nov 2023 10:56:37 +0800 Subject: [PATCH 5/5] input: rockchip_pwm_remotectl: add pwm v4 support Change-Id: I40d1571c3285165683845df8c48fe45d7fcac01d Signed-off-by: Huang zhibao --- .../input/remotectl/rockchip_pwm_remotectl.c | 443 ++++++++++++++---- .../input/remotectl/rockchip_pwm_remotectl.h | 130 +++-- 2 files changed, 443 insertions(+), 130 deletions(-) diff --git a/drivers/input/remotectl/rockchip_pwm_remotectl.c b/drivers/input/remotectl/rockchip_pwm_remotectl.c index fa3d7650d8ff..606c0857831a 100644 --- a/drivers/input/remotectl/rockchip_pwm_remotectl.c +++ b/drivers/input/remotectl/rockchip_pwm_remotectl.c @@ -1,4 +1,4 @@ -/* SPDX-License-Identifier: GPL-2.0 */ +// SPDX-License-Identifier: GPL-2.0 #include #include @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -19,8 +20,6 @@ #include #include "rockchip_pwm_remotectl.h" - - /* * sys/module/rk_pwm_remotectl/parameters, * modify code_print to change the value @@ -56,8 +55,46 @@ struct rkxx_remotectl_button { struct rkxx_remote_key_table key_table[MAX_NUM_KEYS]; }; +struct rk_remote_pwm_regs { + unsigned long ctrl; + unsigned long version; + unsigned long enable; + unsigned long clk_ctrl; + unsigned long offset; + unsigned long rpt; + unsigned long hpr; + unsigned long lpr; + unsigned long intsts; + unsigned long int_en; + unsigned long pwrmatch_arbiter; + unsigned long pwrmatch_ctrl; + unsigned long pwrmatch_lpre; + unsigned long pwrmatch_hpre; + unsigned long pwrmatch_ld; + unsigned long pwrmatch_hd_zero; + unsigned long pwrmatch_hd_one; + unsigned long pwrmatch_value0; + unsigned long pwrcapture_value; +}; + +struct rk_remote_pwm_funcs { + irqreturn_t (*irq_handler)(int irq, void *data); + void (*int_ctrl)(struct platform_device *pdev, int work_mode); + int (*init_hw)(struct platform_device *pdev); +}; + +struct rk_remote_pwm_data { + struct rk_remote_pwm_regs regs; + struct rk_remote_pwm_funcs funcs; + unsigned int prescaler; + u32 enable_conf; + int pwm_version; + int pwrmactch_key_max; +}; + struct rkxx_remotectl_drvdata { void __iomem *base; + int pwm_version; int state; int nbuttons; int scandata; @@ -81,10 +118,60 @@ struct rkxx_remotectl_drvdata { struct timer_list timer; struct tasklet_struct remote_tasklet; struct wake_lock remotectl_wake_lock; + const struct rk_remote_pwm_data *pwm_data; }; +static irqreturn_t rockchip_pwm_irq(int irq, void *dev_id); +static irqreturn_t rockchip_pwm_irq_v4(int irq, void *dev_id); +static int rk_pwm_remotectl_hw_init(struct platform_device *pdev); +static int rk_pwm_remotectl_hw_init_v4(struct platform_device *pdev); +static void rk_pwm_int_ctrl(struct platform_device *pdev, int work_mode); +static void rk_pwm_int_ctrl_v4(struct platform_device *pdev, int work_mode); + static struct rkxx_remotectl_button *remotectl_button; +struct rk_remote_pwm_data pwm_data_v1 = { + .regs = { + .version = 0x5c, + .ctrl = 0x0c, + }, + .prescaler = 1, + .pwm_version = 1, + .funcs = { + .irq_handler = rockchip_pwm_irq, + .int_ctrl = rk_pwm_int_ctrl, + .init_hw = rk_pwm_remotectl_hw_init, + }, +}; + +struct rk_remote_pwm_data pwm_data_v4 = { + .regs = { + .version = 0x0, + .enable = 0x4, + .clk_ctrl = 0x8, + .ctrl = 0xc, + .hpr = 0x2c, + .lpr = 0x30, + .intsts = 0x70, + .int_en = 0x74, + .pwrmatch_arbiter = 0x100, + .pwrmatch_ctrl = 0x104, + .pwrmatch_lpre = 0x108, + .pwrmatch_hpre = 0x10c, + .pwrmatch_ld = 0x110, + .pwrmatch_hd_zero = 0x114, + .pwrmatch_hd_one = 0x118, + .pwrmatch_value0 = 0x11c, + .pwrcapture_value = 0x15c, + }, + .pwm_version = 4, + .funcs = { + .irq_handler = rockchip_pwm_irq_v4, + .int_ctrl = rk_pwm_int_ctrl_v4, + .init_hw = rk_pwm_remotectl_hw_init_v4, + }, +}; + static int remotectl_keybd_num_lookup(struct rkxx_remotectl_drvdata *ddata) { int i; @@ -100,7 +187,6 @@ static int remotectl_keybd_num_lookup(struct rkxx_remotectl_drvdata *ddata) return 0; } - static int remotectl_keycode_lookup(struct rkxx_remotectl_drvdata *ddata) { int i; @@ -137,7 +223,6 @@ static int rk_remotectl_get_irkeybd_count(struct platform_device *pdev) return boardnum; } - static int rk_remotectl_parse_ir_keys(struct platform_device *pdev) { struct rkxx_remotectl_drvdata *ddata = platform_get_drvdata(pdev); @@ -182,8 +267,6 @@ static int rk_remotectl_parse_ir_keys(struct platform_device *pdev) return 0; } - - static void rk_pwm_remotectl_do_something(unsigned long data) { struct rkxx_remotectl_drvdata *ddata; @@ -359,70 +442,184 @@ static irqreturn_t rockchip_pwm_irq(int irq, void *dev_id) return IRQ_HANDLED; } -static int rk_pwm_pwrkey_wakeup_init(struct platform_device *pdev) +static irqreturn_t rockchip_pwm_irq_v4(int irq, void *dev_id) +{ + struct rkxx_remotectl_drvdata *ddata = dev_id; + int tmp; + int val; + irqreturn_t ret = IRQ_NONE; + + val = readl_relaxed(ddata->base + PWM_REG_INTSTS_V4); + + if (val & CAP_LPR_INT) { + writel_relaxed(CAP_LPR_INT, ddata->base + PWM_REG_INTSTS_V4); + tmp = readl_relaxed(ddata->base + PWM_REG_HPR_V4); + ddata->period = ddata->pwm_freq_nstime * tmp / 1000; + DBG("period = %ld\n", ddata->period); + tasklet_hi_schedule(&ddata->remote_tasklet); + ret = IRQ_HANDLED; + } else if (val & CAP_HPR_INT) { + writel_relaxed(CAP_HPR_INT, ddata->base + PWM_REG_INTSTS_V4); + tmp = readl_relaxed(ddata->base + PWM_REG_LPR_V4); + DBG("lpr = %d\n", tmp); + ret = IRQ_HANDLED; + } + + if (val & PWR_INT) { + writel_relaxed(PWR_INT, ddata->base + PWM_REG_INTSTS_V4); + tmp = readl_relaxed(ddata->base + PWM_REG_CAPTURE_VALUE_V4); + DBG("##### cap_val = 0x%0x\n", tmp); + ddata->pwrkey_wakeup = 1; + ret = IRQ_HANDLED; + } + + if (ddata->state == RMC_PRELOAD) + wake_lock_timeout(&ddata->remotectl_wake_lock, HZ); + + return ret; +} + +static int rk_pwmkey_convert_val(int min, int max, int freq_nstime) +{ + int val, min_temp, max_temp; + + min_temp = min * 1000 / freq_nstime; + max_temp = max * 1000 / freq_nstime; + val = (max_temp & 0xffff) << 16 | (min_temp & 0xffff); + + return val; +} + +static int rockchip_pwm_set_pwrmatch(struct platform_device *pdev) { struct rkxx_remotectl_drvdata *ddata = platform_get_drvdata(pdev); - int val, min_temp, max_temp; unsigned int pwm_id = ddata->remote_pwm_id; int version; - int i, j; - int num = 0; - int ret = -1; int pwr_irq; + int val; + int ret; - ddata->pwm_pwrkey_capture = 0; version = readl_relaxed(ddata->base + RK_PWM_VERSION_ID(pwm_id)); - dev_info(&pdev->dev, "pwm version is 0x%x\n", version & 0xffff0000); + DBG("remote pwm version is 0x%x\n", version); if (((version >> 24) & 0xFF) < 2) { dev_info(&pdev->dev, "pwm version is less v2.0\n"); + ret = -EINVAL; goto end; } pwr_irq = platform_get_irq(pdev, 1); if (pwr_irq < 0) { dev_err(&pdev->dev, "cannot find PWR IRQ\n"); + ret = pwr_irq; goto end; } ret = devm_request_irq(&pdev->dev, pwr_irq, rockchip_pwm_pwrirq, - IRQF_NO_SUSPEND, "rk_pwm_pwr_irq", ddata); + IRQF_NO_SUSPEND, "rk_pwm_pwr_irq", ddata); if (ret) { dev_err(&pdev->dev, "cannot claim PWR_IRQ!!!\n"); goto end; } - val = readl_relaxed(ddata->base + PWM_REG_CTRL); - val = (val & 0xFFFFFFFE) | PWM_DISABLE; - writel_relaxed(val, ddata->base + PWM_REG_CTRL); + val = readl_relaxed(ddata->base + PWM_REG_INT_EN(pwm_id)); + val = (val & 0xFFFFFF7F) | PWM_PWR_INT_ENABLE; + writel_relaxed(val, ddata->base + PWM_REG_INT_EN(pwm_id)); + val = CH3_PWRKEY_ENABLE; + writel_relaxed(val, ddata->base + PWM_REG_PWRMATCH_CTRL(pwm_id)); + + val = readl_relaxed(ddata->base + PWM_REG_CTRL); + val = (val & 0xFFFFFFFE) | PWM_ENABLE; + writel_relaxed(val, ddata->base + PWM_REG_CTRL); + return 0; +end: + return ret; +} + +static int rockchip_pwm_set_pwrmatch_v4(struct rkxx_remotectl_drvdata *pd) +{ + int version; + int channel_id; + int val; + + version = readl_relaxed(pd->base + PWM_REG_VERSION_V4); + DBG("remote pwm version is 0x%x\n", version); + channel_id = (version & CHANNLE_INDEX_MASK) >> CHANNLE_INDEX_SHIFT; + val = BIT(channel_id) << PWRMATCH_READ_LOCK_SHIFT | + BIT(channel_id) << PWRMATCH_GRANT_SHIFT; + writel_relaxed(val, pd->base + PWM_REG_MATCH_ARBITER_V4); + writel_relaxed(PWRKEY_EN(true), + pd->base + PWM_REG_MATCH_CTRL_V4); + + return 0; +} + +static void rockchip_pwrmatch_set_nec_param(struct rkxx_remotectl_drvdata *pd) +{ + unsigned int pwm_id = pd->remote_pwm_id; + void __iomem *reg; + int freq_nstime; + int val; + + freq_nstime = pd->pwm_freq_nstime; //preloader low min:8000us, max:10000us - min_temp = RK_PWM_TIME_PRE_MIN_LOW * 1000 / ddata->pwm_freq_nstime; - max_temp = RK_PWM_TIME_PRE_MAX_LOW * 1000 / ddata->pwm_freq_nstime; - val = (max_temp & 0xffff) << 16 | (min_temp & 0xffff); - writel_relaxed(val, ddata->base + PWM_REG_PWRMATCH_LPRE(pwm_id)); + val = rk_pwmkey_convert_val(RK_PWM_TIME_PRE_MIN_LOW, + RK_PWM_TIME_PRE_MAX_LOW, freq_nstime); + if (pd->pwm_data->pwm_version < 4) + reg = pd->base + PWM_REG_PWRMATCH_LPRE(pwm_id); + else + reg = pd->base + PWM_REG_MATCH_LPRE_V4; + writel_relaxed(val, reg); //preloader higt min:4000us, max:5000us - min_temp = RK_PWM_TIME_PRE_MIN * 1000 / ddata->pwm_freq_nstime; - max_temp = RK_PWM_TIME_PRE_MAX * 1000 / ddata->pwm_freq_nstime; - val = (max_temp & 0xffff) << 16 | (min_temp & 0xffff); - writel_relaxed(val, ddata->base + PWM_REG_PWRMATCH_HPRE(pwm_id)); + val = rk_pwmkey_convert_val(RK_PWM_TIME_PRE_MIN, + RK_PWM_TIME_PRE_MAX, freq_nstime); + if (pd->pwm_data->pwm_version < 4) + reg = pd->base + PWM_REG_PWRMATCH_HPRE(pwm_id); + else + reg = pd->base + PWM_REG_MATCH_HPRE_V4; + writel_relaxed(val, reg); //logic 0/1 low min:480us, max 700us - min_temp = RK_PWM_TIME_BIT_MIN_LOW * 1000 / ddata->pwm_freq_nstime; - max_temp = RK_PWM_TIME_BIT_MAX_LOW * 1000 / ddata->pwm_freq_nstime; - val = (max_temp & 0xffff) << 16 | (min_temp & 0xffff); - writel_relaxed(val, ddata->base + PWM_REG_PWRMATCH_LD(pwm_id)); + val = rk_pwmkey_convert_val(RK_PWM_TIME_BIT_MIN_LOW, + RK_PWM_TIME_BIT_MAX_LOW, freq_nstime); + if (pd->pwm_data->pwm_version < 4) + reg = pd->base + PWM_REG_PWRMATCH_LD(pwm_id); + else + reg = pd->base + PWM_REG_MATCH_LD_V4; + writel_relaxed(val, reg); //logic 0 higt min:480us, max 700us - min_temp = RK_PWM_TIME_BIT0_MIN * 1000 / ddata->pwm_freq_nstime; - max_temp = RK_PWM_TIME_BIT0_MAX * 1000 / ddata->pwm_freq_nstime; - val = (max_temp & 0xffff) << 16 | (min_temp & 0xffff); - writel_relaxed(val, ddata->base + PWM_REG_PWRMATCH_HD_ZERO(pwm_id)); + val = rk_pwmkey_convert_val(RK_PWM_TIME_BIT0_MIN, + RK_PWM_TIME_BIT0_MAX, freq_nstime); + if (pd->pwm_data->pwm_version < 4) + reg = pd->base + PWM_REG_PWRMATCH_HD_ZERO(pwm_id); + else + reg = pd->base + PWM_REG_MATCH_HD_ZERO_V4; + writel_relaxed(val, reg); //logic 1 higt min:1300us, max 2000us - min_temp = RK_PWM_TIME_BIT1_MIN * 1000 / ddata->pwm_freq_nstime; - max_temp = RK_PWM_TIME_BIT1_MAX * 1000 / ddata->pwm_freq_nstime; - val = (max_temp & 0xffff) << 16 | (min_temp & 0xffff); - writel_relaxed(val, ddata->base + PWM_REG_PWRMATCH_HD_ONE(pwm_id)); + val = rk_pwmkey_convert_val(RK_PWM_TIME_BIT1_MIN, + RK_PWM_TIME_BIT1_MAX, freq_nstime); + if (pd->pwm_data->pwm_version < 4) + reg = pd->base + PWM_REG_PWRMATCH_HD_ONE(pwm_id); + else + reg = pd->base + PWM_REG_MATCH_HD_ONE_V4; + writel_relaxed(val, reg); +} - for (j = 0; j < ddata->maxkeybdnum; j++) { +static void rockchip_pwrmatch_set_pwrkey(struct rkxx_remotectl_drvdata *pd) +{ + unsigned int pwm_id = pd->remote_pwm_id; + void __iomem *reg; + int i, j; + int num = 0, num_max; + + if (pd->pwm_data->pwm_version < 4) { + reg = pd->base + PWM_PWRMATCH_VALUE(pwm_id); + num_max = PWM_PWR_KEY_CAPURURE_MAX; + } else { + reg = pd->base + PWM_REG_CAPTURE_VALUE0_V4; + num_max = PWM_PWR_KEY_CAPURURE_MAX_V4; + } + for (j = 0; j < pd->maxkeybdnum; j++) { for (i = 0; i < remotectl_button[j].nbuttons; i++) { int scancode, usercode, pwrkey; @@ -434,71 +631,122 @@ static int rk_pwm_pwrkey_wakeup_init(struct platform_device *pdev) pwrkey = usercode; pwrkey |= (scancode << 24) | ((~scancode & 0xff) << 16); DBG("pwrkey = %x\n", pwrkey); - writel_relaxed(pwrkey, ddata->base - + PWM_PWRMATCH_VALUE(pwm_id) + num * 4); + writel_relaxed(pwrkey, reg + num * 4); num++; - if (num >= PWM_PWR_KEY_CAPURURE_MAX) + if (num >= num_max) break; } } +} - val = readl_relaxed(ddata->base + PWM_REG_INT_EN(pwm_id)); - val = (val & 0xFFFFFF7F) | PWM_PWR_INT_ENABLE; - writel_relaxed(val, ddata->base + PWM_REG_INT_EN(pwm_id)); +static int rk_pwm_pwrkey_wakeup_init(struct platform_device *pdev) +{ + struct rkxx_remotectl_drvdata *ddata = platform_get_drvdata(pdev); + int ret = -1; - val = CH3_PWRKEY_ENABLE; - writel_relaxed(val, ddata->base + PWM_REG_PWRMATCH_CTRL(pwm_id)); - - val = readl_relaxed(ddata->base + PWM_REG_CTRL); - val = (val & 0xFFFFFFFE) | PWM_ENABLE; - writel_relaxed(val, ddata->base + PWM_REG_CTRL); + ddata->pwm_pwrkey_capture = 0; + if (ddata->pwm_data->pwm_version < 4) { + ret = rockchip_pwm_set_pwrmatch(pdev); + if (ret < 0) + goto end; + } else { + rockchip_pwm_set_pwrmatch_v4(ddata); + } + rockchip_pwrmatch_set_nec_param(ddata); + rockchip_pwrmatch_set_pwrkey(ddata); ddata->pwm_pwrkey_capture = 1; end: return ret; } -static void rk_pwm_int_ctrl(void __iomem *pwm_base, uint pwm_id, int ctrl) +static void rk_pwm_int_ctrl(struct platform_device *pdev, int work_mode) { + struct rkxx_remotectl_drvdata *ddata = platform_get_drvdata(pdev); int val; + int pwm_id = ddata->remote_pwm_id; if (pwm_id > 3) return; - val = readl_relaxed(pwm_base + PWM_REG_INT_EN(pwm_id)); - if (ctrl) { + val = readl_relaxed(ddata->base + PWM_REG_INT_EN(pwm_id)); + if (work_mode) { val |= PWM_CH_INT_ENABLE(pwm_id); DBG("pwm int enabled, value is 0x%x\n", val); - writel_relaxed(val, pwm_base + PWM_REG_INT_EN(pwm_id)); + writel_relaxed(val, ddata->base + PWM_REG_INT_EN(pwm_id)); } else { val &= ~PWM_CH_INT_ENABLE(pwm_id); DBG("pwm int disabled, value is 0x%x\n", val); } - writel_relaxed(val, pwm_base + PWM_REG_INT_EN(pwm_id)); + writel_relaxed(val, ddata->base + PWM_REG_INT_EN(pwm_id)); } -static int rk_pwm_remotectl_hw_init(void __iomem *pwm_base, uint pwm_id) +static void rk_pwm_int_ctrl_v4(struct platform_device *pdev, int work_mode) { + struct rkxx_remotectl_drvdata *ddata = platform_get_drvdata(pdev); int val; - if (pwm_id > 3) - return -1; + if (work_mode) { + val = CAP_LPR_INT_EN(true) | CAP_HPR_INT_EN(true) | PWR_INT_EN(false); + writel_relaxed(val, ddata->base + PWM_REG_INT_EN_V4); + } else { + val = CAP_LPR_INT_EN(false) | CAP_HPR_INT_EN(false) | PWR_INT_EN(true); + writel_relaxed(val, ddata->base + PWM_REG_INT_EN_V4); + } +} + +static int rk_pwm_remotectl_hw_init(struct platform_device *pdev) +{ + int val; + struct rkxx_remotectl_drvdata *ddata = platform_get_drvdata(pdev); + //1. disabled pwm - val = readl_relaxed(pwm_base + PWM_REG_CTRL); + val = readl_relaxed(ddata->base + PWM_REG_CTRL); val = (val & 0xFFFFFFFE) | PWM_DISABLE; - writel_relaxed(val, pwm_base + PWM_REG_CTRL); + writel_relaxed(val, ddata->base + PWM_REG_CTRL); + //2. capture mode - val = readl_relaxed(pwm_base + PWM_REG_CTRL); + val = readl_relaxed(ddata->base + PWM_REG_CTRL); val = (val & 0xFFFFFFF9) | PWM_MODE_CAPTURE; - writel_relaxed(val, pwm_base + PWM_REG_CTRL); + writel_relaxed(val, ddata->base + PWM_REG_CTRL); + //set clk div, clk div to 64 - val = readl_relaxed(pwm_base + PWM_REG_CTRL); + val = readl_relaxed(ddata->base + PWM_REG_CTRL); val = (val & 0xFF0001FF) | PWM_DIV64; - writel_relaxed(val, pwm_base + PWM_REG_CTRL); + writel_relaxed(val, ddata->base + PWM_REG_CTRL); + //4. enabled pwm int - rk_pwm_int_ctrl(pwm_base, pwm_id, PWM_INT_ENABLE); + ddata->pwm_data->funcs.int_ctrl(pdev, IR_WORK_MODE); + //5. enabled pwm - val = readl_relaxed(pwm_base + PWM_REG_CTRL); + val = readl_relaxed(ddata->base + PWM_REG_CTRL); val = (val & 0xFFFFFFFE) | PWM_ENABLE; - writel_relaxed(val, pwm_base + PWM_REG_CTRL); + writel_relaxed(val, ddata->base + PWM_REG_CTRL); + + return 0; +} + +static int rk_pwm_remotectl_hw_init_v4(struct platform_device *pdev) +{ + int val; + struct rkxx_remotectl_drvdata *ddata = platform_get_drvdata(pdev); + + //1. disabled pwm + val = PWM_EN(false) | PWM_CLK_EN(false); + writel_relaxed(val, ddata->base + PWM_REG_ENABLE_V4); + + //2. capture mode + val = PWM_MODE(CAPTURE_MODE); + writel_relaxed(val, ddata->base + PWM_REG_CTRL_V4); + + //3. set clk div, clk div to 64 + val = CLK_SCALE(32); + writel_relaxed(val, ddata->base + PWM_REG_CLK_CTRL_V4); + + //4. enabled pwm int + ddata->pwm_data->funcs.int_ctrl(pdev, IR_WORK_MODE); + + //5. enabled pwm + val = PWM_EN(true) | PWM_CLK_EN(true); + writel_relaxed(val, ddata->base + PWM_REG_ENABLE_V4); return 0; } @@ -573,9 +821,18 @@ static inline void rk_pwm_wakeup(struct input_dev *input) input_sync(input); } +static const struct of_device_id rk_pwm_of_match[] = { + { .compatible = "rockchip,remotectl-pwm", .data = &pwm_data_v1}, + { .compatible = "rockchip,remotectl-pwm-v4", .data = &pwm_data_v4}, + { } +}; + +MODULE_DEVICE_TABLE(of, rk_pwm_of_match); + static int rk_pwm_probe(struct platform_device *pdev) { struct rkxx_remotectl_drvdata *ddata; + const struct of_device_id *id; struct device_node *np = pdev->dev.of_node; struct resource *r; struct input_dev *input; @@ -592,20 +849,27 @@ static int rk_pwm_probe(struct platform_device *pdev) int count; pr_err(".. rk pwm remotectl v2.0 init\n"); + id = of_match_device(rk_pwm_of_match, &pdev->dev); + if (!id) + return -EINVAL; + r = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!r) { dev_err(&pdev->dev, "no memory resources defined\n"); return -ENODEV; } + ddata = devm_kzalloc(&pdev->dev, sizeof(struct rkxx_remotectl_drvdata), GFP_KERNEL); if (!ddata) { - dev_err(&pdev->dev, "failed to allocate memory\n"); return -ENOMEM; } + + ddata->pwm_data = id->data; ddata->state = RMC_PRELOAD; ddata->temp_period = 0; ddata->base = devm_ioremap_resource(&pdev->dev, r); + if (IS_ERR(ddata->base)) return PTR_ERR(ddata->base); count = of_property_count_strings(np, "clock-names"); @@ -675,14 +939,17 @@ static int rk_pwm_probe(struct platform_device *pdev) } ddata->irq = irq; ddata->wakeup = 1; - of_property_read_u32(np, "remote_pwm_id", &pwm_id); - pwm_id %= 4; - ddata->remote_pwm_id = pwm_id; - if (pwm_id > 3) { - dev_err(&pdev->dev, "pwm id error\n"); - goto error_pclk; + + if (ddata->pwm_data->pwm_version < 4) { + of_property_read_u32(np, "remote_pwm_id", &pwm_id); + pwm_id %= 4; + ddata->remote_pwm_id = pwm_id; + if (pwm_id > 3) { + dev_err(&pdev->dev, "pwm id error\n"); + goto error_pclk; + } + DBG("remotectl: remote pwm id=0x%x\n", pwm_id); } - DBG("remotectl: remote pwm id=0x%x\n", pwm_id); of_property_read_u32(np, "handle_cpu_id", &cpu_id); ddata->handle_cpu_id = cpu_id; DBG("remotectl: handle cpu id=0x%x\n", cpu_id); @@ -710,29 +977,25 @@ static int rk_pwm_probe(struct platform_device *pdev) cpumask_clear(&cpumask); cpumask_set_cpu(cpu_id, &cpumask); irq_set_affinity_hint(irq, &cpumask); - ret = devm_request_irq(&pdev->dev, irq, rockchip_pwm_irq, + ret = devm_request_irq(&pdev->dev, irq, ddata->pwm_data->funcs.irq_handler, IRQF_NO_SUSPEND, "rk_pwm_irq", ddata); if (ret) { dev_err(&pdev->dev, "cannot claim IRQ %d\n", irq); goto error_irq; } - pwm_freq = clk_get_rate(clk) / 64; ddata->pwm_freq_nstime = 1000000000 / pwm_freq; - rk_pwm_remotectl_hw_init(ddata->base, pwm_id); - + ddata->pwm_data->funcs.init_hw(pdev); ret = rk_pwm_pwrkey_wakeup_init(pdev); if (!ret) { dev_info(&pdev->dev, "Controller support pwrkey capture\n"); goto end; } - ret = rk_pwm_sip_wakeup_init(pdev); if (ret) dev_info(&pdev->dev, "Donot support ATF Wakeup\n"); else dev_info(&pdev->dev, "Support ATF Wakeup\n"); - DBG("rk pwm remotectl init end!\n"); end: return 0; @@ -754,15 +1017,13 @@ static int rk_pwm_remove(struct platform_device *pdev) static int remotectl_suspend(struct device *dev) { int cpu = 0; - int pwm_id; struct cpumask cpumask; struct platform_device *pdev = to_platform_device(dev); struct rkxx_remotectl_drvdata *ddata = platform_get_drvdata(pdev); if (ddata->pwm_pwrkey_capture) { - pwm_id = ddata->remote_pwm_id; ddata->pwrkey_wakeup = 0; - rk_pwm_int_ctrl(ddata->base, pwm_id, PWM_INT_DISABLE); + ddata->pwm_data->funcs.int_ctrl(pdev, IR_SUSPEND_MODE); } cpumask_clear(&cpumask); cpumask_set_cpu(cpu, &cpumask); @@ -770,11 +1031,9 @@ static int remotectl_suspend(struct device *dev) return 0; } - static int remotectl_resume(struct device *dev) { struct cpumask cpumask; - int pwm_id; struct platform_device *pdev = to_platform_device(dev); struct rkxx_remotectl_drvdata *ddata = platform_get_drvdata(pdev); int state; @@ -791,8 +1050,7 @@ static int remotectl_resume(struct device *dev) if (state == REMOTECTL_PWRKEY_WAKEUP) rk_pwm_wakeup(ddata->input); } else if (ddata->pwm_pwrkey_capture) { - pwm_id = ddata->remote_pwm_id; - rk_pwm_int_ctrl(ddata->base, pwm_id, PWM_INT_ENABLE); + ddata->pwm_data->funcs.int_ctrl(pdev, IR_WORK_MODE); if (ddata->pwrkey_wakeup == 0) return 0; ddata->pwrkey_wakeup = 0; @@ -808,13 +1066,6 @@ static const struct dev_pm_ops remotectl_pm_ops = { }; #endif -static const struct of_device_id rk_pwm_of_match[] = { - { .compatible = "rockchip,remotectl-pwm"}, - { } -}; - -MODULE_DEVICE_TABLE(of, rk_pwm_of_match); - static struct platform_driver rk_pwm_driver = { .driver = { .name = "remotectl-pwm", diff --git a/drivers/input/remotectl/rockchip_pwm_remotectl.h b/drivers/input/remotectl/rockchip_pwm_remotectl.h index 5126a3edb5d5..1232e799efb5 100644 --- a/drivers/input/remotectl/rockchip_pwm_remotectl.h +++ b/drivers/input/remotectl/rockchip_pwm_remotectl.h @@ -6,6 +6,7 @@ #define MAX_NUM_KEYS 60 #define PWM_PWR_KEY_CAPURURE_MAX 10 +#define PWM_PWR_KEY_CAPURURE_MAX_V4 16 /* PWM0 registers */ #define PWM_REG_CNTR 0x00 /* Counter Register */ @@ -93,52 +94,109 @@ enum pwm_div { PWM_DIV128 = (0x7 << 12), }; +/* + * regs for pwm v4 + */ +#define PWM_REG_VERSION_V4 0x0 +#define PWM_REG_ENABLE_V4 0x4 +#define PWM_REG_CLK_CTRL_V4 0x8 +#define PWM_REG_CTRL_V4 0xC +#define PWM_REG_HPR_V4 0x2C +#define PWM_REG_LPR_V4 0x30 +#define PWM_REG_INTSTS_V4 0x70 +#define PWM_REG_INT_EN_V4 0x74 +#define PWM_REG_MATCH_ARBITER_V4 0x100 +#define PWM_REG_MATCH_CTRL_V4 0x104 +#define PWM_REG_MATCH_LPRE_V4 0x108 +#define PWM_REG_MATCH_HPRE_V4 0x10C +#define PWM_REG_MATCH_LD_V4 0x110 +#define PWM_REG_MATCH_HD_ZERO_V4 0x114 +#define PWM_REG_MATCH_HD_ONE_V4 0x118 +#define PWM_REG_CAPTURE_VALUE0_V4 0x11C +#define PWM_REG_CAPTURE_VALUE_V4 0x15C + + +#define HIWORD_UPDATE(v, l, h) (((v) << (l)) | (GENMASK(h, l) << 16)) + +/* VERSION_ID */ +#define CHANNLE_INDEX_SHIFT 4 +#define CHANNLE_INDEX_MASK (0xf << CHANNLE_INDEX_SHIFT) + +/* PWM_CTRL */ +#define PWM_MODE(v) HIWORD_UPDATE(v, 0, 1) +#define CAPTURE_MODE 2 +#define CLK_SCALE(v) HIWORD_UPDATE(v, 4, 12) + +/* INTSTS */ +#define CAP_LPR_INTSTS_SHIFT 0 +#define CAP_HPR_INTSTS_SHIFT 1 +#define PWR_INTSTS_SHIFT 5 +#define CAP_LPR_INT BIT(CAP_LPR_INTSTS_SHIFT) +#define CAP_HPR_INT BIT(CAP_HPR_INTSTS_SHIFT) +#define PWR_INT BIT(PWR_INTSTS_SHIFT) + +/* INT_EN */ +#define CAP_LPR_INT_EN(v) HIWORD_UPDATE(v, 0, 0) +#define CAP_HPR_INT_EN(v) HIWORD_UPDATE(v, 1, 1) +#define PWR_INT_EN(v) HIWORD_UPDATE(v, 5, 5) + +/* INT_MASK */ +#define CAP_LPR_INT_MASK(v) HIWORD_UPDATE(v, 0, 0) +#define CAP_HPR_INT_MASK(v) HIWORD_UPDATE(v, 1, 1) +#define PWR_INT_MASK(v) HIWORD_UPDATE(v, 5, 5) + +/* PWRMATCH_ARBITER */ +#define PWRMATCH_GRANT_SHIFT 0 +#define PWRMATCH_READ_LOCK_SHIFT 16 +#define PWRKEY_EN(v) HIWORD_UPDATE(v, 0, 0) +#define PWM_CLK_EN(v) HIWORD_UPDATE(v, 0, 0) +#define PWM_EN(v) HIWORD_UPDATE(v, 1, 1) + + /* NEC Protocol */ -#define RK_PWM_TIME_PRE_MIN 4000 -#define RK_PWM_TIME_PRE_MAX 5000 +#define RK_PWM_TIME_PRE_MIN 4000 +#define RK_PWM_TIME_PRE_MAX 5000 -#define RK_PWM_TIME_PRE_MIN_LOW 8000 -#define RK_PWM_TIME_PRE_MAX_LOW 10000 +#define RK_PWM_TIME_PRE_MIN_LOW 8000 +#define RK_PWM_TIME_PRE_MAX_LOW 10000 -#define RK_PWM_TIME_BIT0_MIN 390 -#define RK_PWM_TIME_BIT0_MAX 730 +#define RK_PWM_TIME_BIT0_MIN 390 +#define RK_PWM_TIME_BIT0_MAX 730 -#define RK_PWM_TIME_BIT1_MIN 1300 -#define RK_PWM_TIME_BIT1_MAX 2000 +#define RK_PWM_TIME_BIT1_MIN 1300 +#define RK_PWM_TIME_BIT1_MAX 2000 -#define RK_PWM_TIME_BIT_MIN_LOW 390 -#define RK_PWM_TIME_BIT_MAX_LOW 730 +#define RK_PWM_TIME_BIT_MIN_LOW 390 +#define RK_PWM_TIME_BIT_MAX_LOW 730 -#define RK_PWM_TIME_RPT_MIN 2000 -#define RK_PWM_TIME_RPT_MAX 2500 +#define RK_PWM_TIME_RPT_MIN 2000 +#define RK_PWM_TIME_RPT_MAX 2500 -#define RK_PWM_TIME_SEQ1_MIN 95000 -#define RK_PWM_TIME_SEQ1_MAX 98000 +#define RK_PWM_TIME_SEQ1_MIN 95000 +#define RK_PWM_TIME_SEQ1_MAX 98000 -#define RK_PWM_TIME_SEQ2_MIN 30000 -#define RK_PWM_TIME_SEQ2_MAX 55000 +#define RK_PWM_TIME_SEQ2_MIN 30000 +#define RK_PWM_TIME_SEQ2_MAX 55000 -#define PWM_REG_INTSTS(n) ((3 - (n)) * 0x10 + 0x10) -#define PWM_REG_INT_EN(n) ((3 - (n)) * 0x10 + 0x14) -#define RK_PWM_VERSION_ID(n) ((3 - (n)) * 0x10 + 0x2c) -#define PWM_REG_PWRMATCH_CTRL(n) ((3 - (n)) * 0x10 + 0x50) -#define PWM_REG_PWRMATCH_LPRE(n) ((3 - (n)) * 0x10 + 0x54) -#define PWM_REG_PWRMATCH_HPRE(n) ((3 - (n)) * 0x10 + 0x58) -#define PWM_REG_PWRMATCH_LD(n) ((3 - (n)) * 0x10 + 0x5C) -#define PWM_REG_PWRMATCH_HD_ZERO(n) ((3 - (n)) * 0x10 + 0x60) -#define PWM_REG_PWRMATCH_HD_ONE(n) ((3 - (n)) * 0x10 + 0x64) -#define PWM_PWRMATCH_VALUE(n) ((3 - (n)) * 0x10 + 0x68) -#define PWM_PWRCAPTURE_VALUE(n) ((3 - (n)) * 0x10 + 0x9c) - -#define PWM_CH_INT(n) BIT(n) -#define PWM_CH_POL(n) BIT(n+8) - -#define PWM_CH_INT_ENABLE(n) BIT(n) -#define PWM_PWR_INT_ENABLE BIT(7) -#define CH3_PWRKEY_ENABLE BIT(3) +#define PWM_REG_INTSTS(n) ((3 - (n)) * 0x10 + 0x10) +#define PWM_REG_INT_EN(n) ((3 - (n)) * 0x10 + 0x14) +#define RK_PWM_VERSION_ID(n) ((3 - (n)) * 0x10 + 0x2c) +#define PWM_REG_PWRMATCH_CTRL(n) ((3 - (n)) * 0x10 + 0x50) +#define PWM_REG_PWRMATCH_LPRE(n) ((3 - (n)) * 0x10 + 0x54) +#define PWM_REG_PWRMATCH_HPRE(n) ((3 - (n)) * 0x10 + 0x58) +#define PWM_REG_PWRMATCH_LD(n) ((3 - (n)) * 0x10 + 0x5C) +#define PWM_REG_PWRMATCH_HD_ZERO(n) ((3 - (n)) * 0x10 + 0x60) +#define PWM_REG_PWRMATCH_HD_ONE(n) ((3 - (n)) * 0x10 + 0x64) +#define PWM_PWRMATCH_VALUE(n) ((3 - (n)) * 0x10 + 0x68) +#define PWM_PWRCAPTURE_VALUE(n) ((3 - (n)) * 0x10 + 0x9c) +#define PWM_CH_INT(n) BIT(n) +#define PWM_CH_POL(n) BIT(n+8) +#define PWM_CH_INT_ENABLE(n) BIT(n) +#define PWM_PWR_INT_ENABLE BIT(7) +#define CH3_PWRKEY_ENABLE BIT(3) typedef enum _RMC_STATE { @@ -149,6 +207,10 @@ typedef enum _RMC_STATE { RMC_SEQUENCE, } eRMC_STATE; +enum { + IR_SUSPEND_MODE = 0, + IR_WORK_MODE +}; struct RKxx_remotectl_platform_data { int nbuttons;