add Raspits Pi 7-inch touchscreen panel support

This commit is contained in:
itlhd
2024-11-05 11:01:19 +08:00
committed by Igor
parent e4e453ec15
commit a8903865c0
7 changed files with 960 additions and 0 deletions

View File

@@ -451,6 +451,14 @@ config DRM_PANEL_RASPBERRYPI_TOUCHSCREEN
Pi 7" Touchscreen. To compile this driver as a module,
choose M here.
config DRM_PANEL_RASPITS_TC358762
tristate "Raspits Pi 7-inch touchscreen panel"
depends on DRM_MIPI_DSI
help
Say Y here if you want to enable support for the Raspits
Pi 7" Touchscreen. 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

View File

@@ -44,6 +44,7 @@ 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_RADXA_DISPLAY_8HD) += panel-radxa-display-8hd.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

File diff suppressed because it is too large Load Diff

View File

@@ -13,6 +13,12 @@ config RK803
help
Driver for RK803 which is used for driving porjector and IR flood LED.
config CONFIG_ROCKPI_MCU
tristate "ROCKPI_MCU"
depends on I2C
help
Driver for ROCKPI_MCU which is used for 7 Touchscreen.
source "drivers/misc/rockchip/Kconfig"
config LT7911D_FB_NOTIFIER

View File

@@ -5,6 +5,7 @@
obj-y += rk628/
obj-$(CONFIG_RK803) += rk803.o
obj-y += rockpi_mcu.o
obj-y += rockchip/
obj-$(CONFIG_LT7911D_FB_NOTIFIER) += lt7911d-fb-notifier.o
obj-$(CONFIG_IBM_ASM) += ibmasm/

246
drivers/misc/rockpi_mcu.c Executable file
View File

@@ -0,0 +1,246 @@
/*
*
* 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 <linux/module.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/i2c.h>
#include <linux/errno.h>
#include <linux/module.h>
#include <linux/workqueue.h>
#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 void rockpi_mcu_remove(struct i2c_client *client)
{
struct rockpi_mcu_data *mcu_data = i2c_get_clientdata(client);
connected = 0;
kfree(mcu_data);
}
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");

14
drivers/misc/rockpi_mcu.h Executable file
View File

@@ -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