From 3a6621bed8952b6e475394558b0115b0d5084a27 Mon Sep 17 00:00:00 2001 From: Feng Zhang Date: Mon, 26 Jun 2023 18:34:26 +0800 Subject: [PATCH 1/5] drm/bridge: dw-mipi-dsi: Enable hsclk when sending lp cmds Signed-off-by: Feng Zhang --- drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c index a680731ce4d950..c7222618e83f84 100644 --- a/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c +++ b/drivers/gpu/drm/bridge/synopsys/dw-mipi-dsi.c @@ -402,7 +402,7 @@ static void dw_mipi_message_config(struct dw_mipi_dsi *dsi, ctrl = dsi_read(dsi, DSI_LPCLK_CTRL); if (lpm) { val |= ENABLE_LOW_POWER_CMD; - ctrl &= ~PHY_TXREQUESTCLKHS; + ctrl |= PHY_TXREQUESTCLKHS; } else { val &= ~ENABLE_LOW_POWER_CMD; ctrl |= PHY_TXREQUESTCLKHS; From fbcb7996523c67dc90b06d36ccbb360c3968db60 Mon Sep 17 00:00:00 2001 From: Feng Zhang Date: Wed, 28 Jun 2023 11:30:02 +0800 Subject: [PATCH 2/5] driver: misc: add rockpi_mcu driver Signed-off-by: Feng Zhang --- drivers/misc/Kconfig | 7 ++ drivers/misc/Makefile | 1 + drivers/misc/rockpi_mcu.c | 247 ++++++++++++++++++++++++++++++++++++++ drivers/misc/rockpi_mcu.h | 14 +++ 4 files changed, 269 insertions(+) create mode 100644 drivers/misc/rockpi_mcu.c create mode 100644 drivers/misc/rockpi_mcu.h diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index 276c7c4fef1587..427665526e7dc7 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -496,6 +496,13 @@ config HISI_HIKEY_USB switching between the dual-role USB-C port and the USB-A host ports using only one USB controller. +config ROCKPI_MCU + tristate "rockpi mcu" + default n + depends on I2C + help + Control the power of touch screen for rockpi board. + source "drivers/misc/c2port/Kconfig" source "drivers/misc/eeprom/Kconfig" source "drivers/misc/cb710/Kconfig" diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index b296e760fd4747..c6d044c477fa88 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile @@ -61,3 +61,4 @@ obj-$(CONFIG_UACCE) += uacce/ obj-$(CONFIG_XILINX_SDFEC) += xilinx_sdfec.o obj-$(CONFIG_HISI_HIKEY_USB) += hisi_hikey_usb.o obj-$(CONFIG_UID_SYS_STATS) += uid_sys_stats.o +obj-$(CONFIG_ROCKPI_MCU) += rockpi_mcu.o diff --git a/drivers/misc/rockpi_mcu.c b/drivers/misc/rockpi_mcu.c new file mode 100644 index 00000000000000..c660ba06cd725f --- /dev/null +++ b/drivers/misc/rockpi_mcu.c @@ -0,0 +1,247 @@ +/* + * + * Rockpi board Touchscreen MCU driver. + * + * Copyright (c) 2016 ASUSTek Computer Inc. + * Copyright (c) 2012-2014, The Linux Foundation. All rights reserved. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include "rockpi_mcu.h" + +static struct rockpi_mcu_data *g_mcu_data; +static int connected = 0; + +static int is_hex(char num) +{ + //0-9, a-f, A-F + if ((47 < num && num < 58) || (64 < num && num < 71) || (96 < num && num < 103)) + return 1; + return 0; +} + +static int string_to_byte(const char *source, unsigned char *destination, int size) +{ + int i = 0, counter = 0; + char c[3] = {0}; + unsigned char bytes; + + if (size%2 == 1) + return -EINVAL; + + for(i = 0; i < size; i++){ + if(!is_hex(source[i])) { + return -EINVAL; + } + if(0 == i%2){ + c[0] = source[i]; + c[1] = source[i+1]; + sscanf(c, "%hhx", &bytes); + destination[counter] = bytes; + counter++; + } + } + return 0; +} + +static int send_cmds(struct i2c_client *client, const char *buf) +{ + int ret, size = strlen(buf); + //unsigned char byte_cmd[size/2]; + + unsigned char byte_cmd[10]; + + if ((size%2) != 0) { + LOG_ERR("size should be even\n"); + return -EINVAL; + } + + LOG_INFO("%s\n", buf); + + string_to_byte(buf, byte_cmd, size); + + ret = i2c_master_send(client, byte_cmd, size/2); + if (ret <= 0) { + //LOG_ERR("send command failed, ret = %d\n", ret); + printk("send command failed, ret = %d\n", ret); + return ret!=0 ? ret : -ECOMM; + } + msleep(20); + return 0; +} + +static int recv_cmds(struct i2c_client *client, char *buf, int size) +{ + int ret; + + ret = i2c_master_recv(client, buf, size); + if (ret <= 0) { + LOG_ERR("receive commands failed, %d\n", ret); + return ret!=0 ? ret : -ECOMM; + } + msleep(20); + return 0; +} + +static int init_cmd_check(struct rockpi_mcu_data *mcu_data) +{ + int ret; + char recv_buf[1] = {0}; + + ret = send_cmds(mcu_data->client, "80"); + if (ret < 0) + goto error; + + recv_cmds(mcu_data->client, recv_buf, 1); + if (ret < 0) + goto error; + + LOG_INFO("recv_cmds: 0x%X\n", recv_buf[0]); + if (recv_buf[0] != 0xDE && recv_buf[0] != 0xC3) { + LOG_ERR("read wrong info\n"); + ret = -EINVAL; + goto error; + + } + return 0; + +error: + return ret; +} + +int rockpi_mcu_screen_power_up(void) +{ + int res = 0; + if (!connected) + return -ENODEV; + + LOG_INFO("\n"); + + res = send_cmds(g_mcu_data->client, "8500"); + if(res < 0) + printk("send 8500 failed\n"); + msleep(800); + res = send_cmds(g_mcu_data->client, "8501"); + if(res < 0) + printk("send 8501 failed\n"); + msleep(800); + res = send_cmds(g_mcu_data->client, "8104"); + if(res < 0) + printk("send 8104 failed\n"); + + return 0; +} +EXPORT_SYMBOL_GPL(rockpi_mcu_screen_power_up); + +int rockpi_mcu_set_bright(int bright) +{ + unsigned char cmd[2]; + int ret; + + if (!connected) + return -ENODEV; + + if (bright > 0xff || bright < 0) + return -EINVAL; + + LOG_INFO("bright = 0x%x\n", bright); + + cmd[0] = 0x86; + cmd[1] = bright; + + ret = i2c_master_send(g_mcu_data->client, cmd, 2); + if (ret <= 0) { + LOG_ERR("send command failed, ret = %d\n", ret); + return ret != 0 ? ret : -ECOMM; + } + + return 0; +} +EXPORT_SYMBOL_GPL(rockpi_mcu_set_bright); + +int rockpi_mcu_is_connected(void) +{ + return connected; +} +EXPORT_SYMBOL_GPL(rockpi_mcu_is_connected); + +static int rockpi_mcu_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct rockpi_mcu_data *mcu_data; + int ret; + + LOG_INFO("address = 0x%x\n", client->addr); + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { + LOG_ERR("I2C check functionality failed\n"); + return -ENODEV; + } + + mcu_data = kzalloc(sizeof(struct rockpi_mcu_data), GFP_KERNEL); + if (mcu_data == NULL) { + LOG_ERR("no memory for device\n"); + return -ENOMEM; + } + + mcu_data->client = client; + i2c_set_clientdata(client, mcu_data); + g_mcu_data = mcu_data; + + ret = init_cmd_check(mcu_data); + if (ret < 0) { + LOG_ERR("init_cmd_check failed, %d\n", ret); + if (ret == -ENXIO) + ret = -EPROBE_DEFER; + goto error; + } + connected = 1; + + return 0; + +error: + kfree(mcu_data); + return ret; +} + +static int rockpi_mcu_remove(struct i2c_client *client) +{ + struct rockpi_mcu_data *mcu_data = i2c_get_clientdata(client); + connected = 0; + kfree(mcu_data); + return 0; +} + +static const struct i2c_device_id rockpi_mcu_id[] = { + {"rockpi_mcu", 0}, + {}, +}; + +static struct i2c_driver rockpi_mcu_driver = { + .driver = { + .name = "rockpi_mcu", + }, + .probe = rockpi_mcu_probe, + .remove = rockpi_mcu_remove, + .id_table = rockpi_mcu_id, +}; +module_i2c_driver(rockpi_mcu_driver); + +MODULE_DESCRIPTION("rockpi Board TouchScreen MCU driver"); +MODULE_LICENSE("GPL v2"); \ No newline at end of file diff --git a/drivers/misc/rockpi_mcu.h b/drivers/misc/rockpi_mcu.h new file mode 100644 index 00000000000000..6eb27bcdc54aaa --- /dev/null +++ b/drivers/misc/rockpi_mcu.h @@ -0,0 +1,14 @@ +#ifndef _ROCKPI_MCU_H_ +#define _ROCKPI_MCU_H_ + +#define LOG_INFO(fmt,arg...) pr_info("rockpi-mcu: %s: "fmt, __func__, ##arg); +#define LOG_ERR(fmt,arg...) pr_err("rockpi-mcu: %s: "fmt, __func__, ##arg); + +#define MAX_I2C_LEN 255 + +struct rockpi_mcu_data { + struct device *dev; + struct i2c_client *client; +}; + +#endif \ No newline at end of file From 1faa191bbbe696c11a95609d8b1d9a357faedff6 Mon Sep 17 00:00:00 2001 From: Feng Zhang Date: Mon, 26 Jun 2023 20:32:44 +0800 Subject: [PATCH 3/5] drm/panel: add RaspberryPi 7inch touchscreen driver Signed-off-by: Feng Zhang --- drivers/gpu/drm/panel/Kconfig | 10 + drivers/gpu/drm/panel/Makefile | 1 + .../gpu/drm/panel/panel-raspits-tc358762.c | 613 ++++++++++++++++++ 3 files changed, 624 insertions(+) create mode 100644 drivers/gpu/drm/panel/panel-raspits-tc358762.c diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig index 2794dd34726f52..d221a63d1eca13 100644 --- a/drivers/gpu/drm/panel/Kconfig +++ b/drivers/gpu/drm/panel/Kconfig @@ -285,6 +285,16 @@ config DRM_PANEL_RASPBERRYPI_TOUCHSCREEN Pi 7" Touchscreen. To compile this driver as a module, choose M here. +config DRM_PANEL_RASPITS_TC358762 + tristate "Raspberry Pi 7-inch touchscreen tc358762 panel" + depends on OF && I2C + depends on BACKLIGHT_CLASS_DEVICE + select VIDEOMODE_HELPERS + help + Say Y here if you want to enable support for Raspberry Pi + touchscreen tc358762 panel. + To compile this driver as a module, choose M here. + config DRM_PANEL_RAYDIUM_RM67191 tristate "Raydium RM67191 FHD 1080x1920 DSI video mode panel" depends on OF diff --git a/drivers/gpu/drm/panel/Makefile b/drivers/gpu/drm/panel/Makefile index d99b1eaf92c2bf..88a92760cd5b04 100644 --- a/drivers/gpu/drm/panel/Makefile +++ b/drivers/gpu/drm/panel/Makefile @@ -27,6 +27,7 @@ obj-$(CONFIG_DRM_PANEL_ORISETECH_OTM8009A) += panel-orisetech-otm8009a.o obj-$(CONFIG_DRM_PANEL_OSD_OSD101T2587_53TS) += panel-osd-osd101t2587-53ts.o obj-$(CONFIG_DRM_PANEL_PANASONIC_VVX10F034N00) += panel-panasonic-vvx10f034n00.o obj-$(CONFIG_DRM_PANEL_RASPBERRYPI_TOUCHSCREEN) += panel-raspberrypi-touchscreen.o +obj-$(CONFIG_DRM_PANEL_RASPITS_TC358762) += panel-raspits-tc358762.o obj-$(CONFIG_DRM_PANEL_RAYDIUM_RM67191) += panel-raydium-rm67191.o obj-$(CONFIG_DRM_PANEL_RAYDIUM_RM68200) += panel-raydium-rm68200.o obj-$(CONFIG_DRM_PANEL_RONBO_RB070D30) += panel-ronbo-rb070d30.o diff --git a/drivers/gpu/drm/panel/panel-raspits-tc358762.c b/drivers/gpu/drm/panel/panel-raspits-tc358762.c new file mode 100644 index 00000000000000..3fa1e283776b88 --- /dev/null +++ b/drivers/gpu/drm/panel/panel-raspits-tc358762.c @@ -0,0 +1,613 @@ +/* + * Copyright (C) 2013, NVIDIA Corporation. All rights reserved. + * Copyright (c) 2022 Radxa Computer Co., Ltd. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sub license, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include