247 lines
5.7 KiB
C
Executable file
247 lines
5.7 KiB
C
Executable file
#define pr_fmt(fmt) "[pix_manager]" fmt
|
|
|
|
#include <linux/kernel.h>
|
|
#include <linux/module.h>
|
|
#include <linux/device.h>
|
|
#include <linux/fs.h>
|
|
#include <linux/cdev.h>
|
|
#include <linux/slab.h>
|
|
#include <linux/list.h>
|
|
#include <linux/poll.h>
|
|
#include <linux/bitmap.h>
|
|
#include <linux/proc_fs.h>
|
|
#include <linux/seq_file.h>
|
|
#include <uapi/linux/sched/types.h>
|
|
#include <linux/sched_clock.h>
|
|
#include <linux/log2.h>
|
|
//drv add by situziyin 20230517 start
|
|
#include <drm/drm_panel.h>
|
|
#include <mtk_disp_notify.h>
|
|
//drv add by situziyin 20230517 end
|
|
|
|
struct pixel_data {
|
|
int16_t pixelA;
|
|
int16_t pixelR;
|
|
int16_t pixelG;
|
|
int16_t pixelB;
|
|
} g_pix_param;
|
|
|
|
static int dev_major;
|
|
static struct class *pixel_manager_class;
|
|
static struct notifier_block fb_notifier; //drv add by situziyin 20230517
|
|
|
|
static int pixel_manager_open(struct inode *inode, struct file *filp)
|
|
{
|
|
nonseekable_open(inode, filp);
|
|
return 0;
|
|
}
|
|
|
|
static int pixel_manager_release(struct inode *inode, struct file *filp)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
static int string_is_digital(const char *str)
|
|
{
|
|
int i = 0;
|
|
|
|
if (str == NULL) {
|
|
return -1;
|
|
}
|
|
|
|
while (str[i] != '\0') {
|
|
if (str[i] < '0' || str[i] > '9') {
|
|
return -1;
|
|
}
|
|
i++;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int pixel_atoi(const char *str)
|
|
{
|
|
int i = 0;
|
|
int ret_value = 0;
|
|
|
|
if (str == NULL) {
|
|
return -1;
|
|
}
|
|
|
|
while (str[i] != '\0') {
|
|
ret_value = ret_value * 10 + (str[i] - '0');
|
|
i++;
|
|
}
|
|
|
|
return ret_value;
|
|
}
|
|
|
|
static ssize_t pixel_manager_write(struct file *filp,
|
|
const char __user *buf, size_t count, loff_t *f_pos)
|
|
{
|
|
char rgb_buf[64] = {0};
|
|
char *find_str1 = NULL;
|
|
char *find_str2 = NULL;
|
|
char *find_str3 = NULL;
|
|
char *find_str4 = NULL;
|
|
char tmp_buf[16] = {0};
|
|
|
|
if (copy_from_user(rgb_buf, buf, count))
|
|
return -EFAULT;
|
|
|
|
pr_info("pixel_manager_write:%s\n", rgb_buf);
|
|
find_str1 = strstr(rgb_buf, "A:");
|
|
find_str2 = strstr(rgb_buf, "R:");
|
|
find_str3 = strstr(rgb_buf, "G:");
|
|
find_str4 = strstr(rgb_buf, "B:");
|
|
if (find_str1 != NULL && find_str2 != NULL && find_str2 - find_str1 > 2) {
|
|
strncpy(tmp_buf, find_str1 + 2, find_str2 - find_str1 - 2);
|
|
if (string_is_digital(tmp_buf) == 0) {
|
|
g_pix_param.pixelA = pixel_atoi(tmp_buf);
|
|
}
|
|
}
|
|
|
|
if (find_str2 != NULL && find_str3 != NULL && find_str3 - find_str2 > 2) {
|
|
memset(tmp_buf, 0, sizeof(tmp_buf));
|
|
strncpy(tmp_buf, find_str2 + 2, find_str3 - find_str2 - 2);
|
|
if (string_is_digital(tmp_buf) == 0) {
|
|
g_pix_param.pixelR = pixel_atoi(tmp_buf);
|
|
}
|
|
}
|
|
|
|
if (find_str3 != NULL && find_str4 != NULL && find_str4 - find_str3 > 2) {
|
|
memset(tmp_buf, 0, sizeof(tmp_buf));
|
|
strncpy(tmp_buf, find_str3 + 2, find_str4 - find_str3 - 2);
|
|
if (string_is_digital(tmp_buf) == 0) {
|
|
g_pix_param.pixelG = pixel_atoi(tmp_buf);
|
|
}
|
|
}
|
|
|
|
if (find_str4 != NULL) {
|
|
memset(tmp_buf, 0, sizeof(tmp_buf));
|
|
strcpy(tmp_buf, find_str4 + 2);
|
|
if (string_is_digital(tmp_buf) == 0) {
|
|
g_pix_param.pixelB = pixel_atoi(tmp_buf);
|
|
}
|
|
}
|
|
return count;
|
|
}
|
|
|
|
void get_pix_rgb(int16_t *R, int16_t *G, int16_t *B)
|
|
{
|
|
if (R == NULL || G == NULL || B == NULL) {
|
|
return;
|
|
}
|
|
|
|
if (g_pix_param.pixelR > 255 || g_pix_param.pixelG > 255 || g_pix_param.pixelB > 255) {
|
|
*R = -1;
|
|
*G = -1;
|
|
*B = -1;
|
|
return;
|
|
}
|
|
|
|
*R = g_pix_param.pixelR;
|
|
*G = g_pix_param.pixelG;
|
|
*B = g_pix_param.pixelB;
|
|
pr_info("get_pix_rgb %d:%d:%d\n", *R, *G, *B);
|
|
}
|
|
EXPORT_SYMBOL_GPL(get_pix_rgb);
|
|
|
|
void reset_pix_rgb(void)
|
|
{
|
|
memset(&g_pix_param, -1 , sizeof(g_pix_param));
|
|
}
|
|
EXPORT_SYMBOL_GPL(reset_pix_rgb);
|
|
|
|
//drv add by situziyin 20230517 start
|
|
static int pixel_manager_fb_notifier_cb(struct notifier_block *nb,
|
|
unsigned long action, void *data)
|
|
{
|
|
int disp_blank_powerdown = MTK_DISP_BLANK_POWERDOWN;
|
|
int disp_blank = MTK_DISP_EVENT_BLANK;
|
|
int transition = *(int *)data;
|
|
|
|
if (action == disp_blank) {
|
|
if (transition == disp_blank_powerdown) {
|
|
reset_pix_rgb();
|
|
pr_info("reset pixel\n");
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
//drv add by situziyin 20230517 end
|
|
|
|
static const struct file_operations pixel_manager_fops = {
|
|
.owner = THIS_MODULE,
|
|
.open = pixel_manager_open,
|
|
.release = pixel_manager_release,
|
|
.write = pixel_manager_write
|
|
};
|
|
|
|
static int __init pixel_manager_init(void)
|
|
{
|
|
int ret;
|
|
struct device *dev;
|
|
|
|
dev_major = register_chrdev(0, "pix_manager", &pixel_manager_fops);
|
|
if (dev_major < 0) {
|
|
pr_err("Unable to get major\n");
|
|
ret = dev_major;
|
|
goto err_exit;
|
|
}
|
|
|
|
pixel_manager_class = class_create(THIS_MODULE, "pix_manager");
|
|
if (IS_ERR(pixel_manager_class)) {
|
|
pr_err("Failed to create class\n");
|
|
ret = PTR_ERR(pixel_manager_class);
|
|
goto err_chredev;
|
|
}
|
|
|
|
dev = device_create(pixel_manager_class, NULL, MKDEV(dev_major, 0),
|
|
NULL, "pix_manager");
|
|
if (IS_ERR(dev)) {
|
|
pr_err("Failed to create device\n");
|
|
ret = PTR_ERR(dev);
|
|
goto err_class;
|
|
}
|
|
|
|
//drv add by situziyin 20230517 start
|
|
fb_notifier.notifier_call = pixel_manager_fb_notifier_cb;
|
|
ret = mtk_disp_notifier_register("pix_manager", &fb_notifier);
|
|
if (ret < 0) {
|
|
pr_err("Fail to register FB notifier client\n");
|
|
goto err_device;
|
|
}
|
|
//drv add by situziyin 20230517 end
|
|
|
|
memset(&g_pix_param, -1, sizeof(g_pix_param));
|
|
|
|
return 0;
|
|
|
|
//drv add by situziyin 20230517 start
|
|
err_device:
|
|
device_destroy(pixel_manager_class, MKDEV(dev_major, 0));
|
|
//drv add by situziyin 20230517 end
|
|
err_class:
|
|
class_destroy(pixel_manager_class);
|
|
err_chredev:
|
|
unregister_chrdev(dev_major, "pix_manager");
|
|
err_exit:
|
|
return ret;
|
|
}
|
|
|
|
static void __exit pixel_manager_exit(void)
|
|
{
|
|
mtk_disp_notifier_unregister(&fb_notifier); //drv add by situziyin 20230517
|
|
device_destroy(pixel_manager_class, MKDEV(dev_major, 0));
|
|
class_destroy(pixel_manager_class);
|
|
unregister_chrdev(dev_major, "pix_manager");
|
|
}
|
|
|
|
subsys_initcall(pixel_manager_init);
|
|
module_exit(pixel_manager_exit);
|
|
|
|
MODULE_DESCRIPTION("transfer rgb value");
|
|
MODULE_AUTHOR("Coosea");
|
|
MODULE_LICENSE("GPL v2");
|
|
|