drivers/misc: remove unused scaler drivers

Change-Id: I9238ec677203a69ff9eecae66bac38f555824276
Signed-off-by: Tao Huang <huangtao@rock-chips.com>
This commit is contained in:
Tao Huang
2018-11-03 13:03:06 +08:00
parent 6c07e13c08
commit 7fe22b566c
11 changed files with 0 additions and 4595 deletions

View File

@@ -1,17 +0,0 @@
# SPDX-License-Identifier: GPL-2.0
#
# all auto modem control drivers configuration
#
menuconfig SCALER_DEVICE
bool "Scaler Device Support"
default n
if SCALER_DEVICE
config SCALER_DEVICE_DDC
bool "Scaler Device Support DDC Read EDID"
default n
source "drivers/misc/scaler/chips/Kconfig"
endif

View File

@@ -1,9 +0,0 @@
# SPDX-License-Identifier: GPL-2.0
#
# Makefile for the display core.
#
obj-$(CONFIG_SCALER_DEVICE) += chips/
obj-$(CONFIG_SCALER_DEVICE) += scaler-core.o
obj-$(CONFIG_SCALER_DEVICE) += scaler-sysfs.o
obj-$(CONFIG_SCALER_DEVICE_DDC) += scaler-edid.o

View File

@@ -1,12 +0,0 @@
# SPDX-License-Identifier: GPL-2.0
#
#config tv5735 support inport type and output type
#
config SCALER_TV5735
bool "Support tv5735 chip"
default n
config SCALER_TEST
bool "test chip"
default n

View File

@@ -1,3 +0,0 @@
# SPDX-License-Identifier: GPL-2.0
obj-$(CONFIG_SCALER_TV5735) += tv5735.o
obj-$(CONFIG_SCALER_TEST) += test.o

View File

@@ -1,143 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
Copyright (c) 2010 by Rockchip.
*/
#include <linux/module.h>
#include <linux/delay.h>
#include <mach/gpio.h>
#include <linux/scaler-core.h>
struct scaler_chip_dev *chip = NULL;
//enbale chip to process image
static void set_cur_inport(void)
{
struct scaler_input_port *iport = NULL;
int ddc_sel_level = -1;
list_for_each_entry(iport, &chip->iports, next) {
if (iport->id == chip->cur_inport_id) {
if (iport->id == 1)
ddc_sel_level = chip->pdata->ddc_sel_level;
else
ddc_sel_level = !chip->pdata->ddc_sel_level;
if (chip->pdata->ddc_sel_gpio > 0)
gpio_direction_output(chip->pdata->ddc_sel_gpio, ddc_sel_level);
gpio_set_value(iport->led_gpio, GPIO_HIGH);
}else {
gpio_set_value(iport->led_gpio, GPIO_LOW);
}
}
}
static int test_parse_cmd(unsigned int cmd, unsigned long arg)
{
printk("test: parse scaler cmd %u\n",cmd);
switch (cmd) {
case SCALER_IOCTL_SET_CUR_INPUT:
set_cur_inport();
break;
default:
break;
}
return 0;
}
static void test_start(void)
{
scaler_switch_default_screen();
}
static int test_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
struct scaler_platform_data *pdata = client->dev.platform_data;
if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
dev_err(&client->adapter->dev, "%s failed ENODEV\n\n", __func__);
return -ENODEV;
}
if (!pdata) {
printk("%s: client private data not define\n", __func__);
return -1;
}
scaler_init_platform(pdata);
chip = alloc_scaler_chip();
if (!chip) {
printk("%s: alloc scaler chip memory failed.\n", __func__);
return -1;
}else {
chip->client = client;
chip->pdata = pdata;
memcpy((void *)chip->name, (void *)client->name, (strlen(client->name) + 1));
}
if (init_scaler_chip(chip, pdata) != 0)
goto err;
//implement parse cmd function
chip->parse_cmd = test_parse_cmd;
chip->start = test_start;
//register
if (register_scaler_chip(chip) != 0)
goto err;
return 0;
err:
free_scaler_chip(chip);
return -1;
}
static int test_i2c_remove(struct i2c_client *client)
{
printk("%s: \n", __func__);
unregister_scaler_chip(chip);
free_scaler_chip(chip);
chip = NULL;
return 0;
}
static const struct i2c_device_id test_i2c_id[] ={
{"aswitch", 0},
{}
};
MODULE_DEVICE_TABLE(i2c, test_i2c_id);
static struct i2c_driver test_i2c_driver = {
.driver = {
.name = "aswitch"
},
.probe = test_i2c_probe,
.remove = test_i2c_remove,
.id_table = test_i2c_id,
};
static int __init test_init(void)
{
int ret = 0;
printk("%s: \n", __func__);
ret = i2c_add_driver(&test_i2c_driver);
if(ret < 0){
printk("%s, register i2c device, error\n", __func__);
return ret;
}
return 0;
}
static void __exit test_exit(void)
{
printk("%s: \n", __func__);
}
module_init(test_init);
module_exit(test_exit);

View File

@@ -1,326 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
Copyright (c) 2010 by Rockchip.
*/
#include <linux/module.h>
#include <linux/i2c.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <mach/gpio.h>
#include "tv_setting.h"
#define TV_DEV_NAME "trueview"
#define TV_I2C_RATE (400*1000)
static struct timer_list timer;
static int vga_in_det = 0;
static int vga_offset = 0;
static struct scaler_chip_dev *chip = NULL;
/*** I2c operate ***/
static int tv_select_bank(struct i2c_client *client, char bank)
{
u8 sel_bank = 0xf0;
return i2c_master_reg8_send(client, sel_bank, &bank, 1, TV_I2C_RATE);
}
static int tv_read_single_data(struct i2c_client *client, char reg)
{
int ret;
unsigned char val;
ret = i2c_master_reg8_recv(client, reg, &val, 1, TV_I2C_RATE);
if (ret != 1)
printk("%s: read reg8 value error:%d\n", __func__, ret);
return val;
}
static inline int tv_write_single_data(struct i2c_client *client, char reg, char value)
{
return i2c_master_reg8_send(client, reg, &value, 1, TV_I2C_RATE);
}
static void tv5735_init_reg(unsigned char *regs, int len)
{
int i, ret = -1;
char reg, val;
if (chip == NULL)
return;
for (i = 0; i < len; i += 2) {
reg = regs[i + 0];
val = regs[i + 1];
if (reg == 0xff && val == 0xff)
break;
//ret = i2c_master_reg8_send(chip->client, reg, &val, 1, TV_I2C_RATE);
ret = tv_write_single_data(chip->client, reg, val);
if (ret != 1)
printk("%s: write reg = %d failed.\n", __func__, reg);
}
}
static void set_cur_inport(void)
{
struct scaler_input_port *iport = NULL;
int ddc_sel_level = -1;
list_for_each_entry(iport, &chip->iports, next) {
if (iport->id == chip->cur_inport_id) {
gpio_set_value(iport->led_gpio, GPIO_HIGH);
if (iport->id == 1)
ddc_sel_level = chip->pdata->ddc_sel_level;
else
ddc_sel_level = !chip->pdata->ddc_sel_level;
if (chip->pdata->ddc_sel_gpio > 0)
gpio_direction_output(chip->pdata->ddc_sel_gpio, ddc_sel_level);
if (iport->type == SCALER_IN_RGB) {
if (vga_in_det)
del_timer_sync(&timer);
tv5735_init_reg(regs[iport->type].regs, regs[iport->type].len);
}
if (iport->type == SCALER_IN_VGA) {
tv5735_init_reg(vga2vga_regs[vga_offset].regs, vga2vga_regs[vga_offset].len);
if (vga_in_det)
add_timer(&timer);
}
}else {
gpio_set_value(iport->led_gpio, GPIO_LOW);
}
}
}
static int parse_cmd(unsigned int cmd, unsigned long arg)
{
printk("tv5735: parse scaler cmd %u\n",cmd);
switch (cmd) {
case SCALER_IOCTL_SET_CUR_INPUT:
set_cur_inport();
break;
default:
break;
}
return 0;
}
//enbale chip to process image
static void tv5735_start(void)
{
scaler_switch_default_screen();
set_cur_inport();
//tv5735_init_reg(regs[chip->cur_in_type].regs, regs[chip->cur_in_type].len);
}
static int tv_hardware_is_ok(struct i2c_client *client)
{
unsigned char reg_val= 0;
unsigned chip_id = 0;
if (tv_select_bank(client, 0) == 1) {
reg_val = tv_read_single_data(client, 0x0b);
chip_id = reg_val;
msleep(10);
reg_val = tv_read_single_data(client, 0x0c);
chip_id = (chip_id << 8) | reg_val;
msleep(10);
reg_val = tv_read_single_data(client, 0x0d);
chip_id = (chip_id << 8) | reg_val;
printk("%s: Chip Id %#x\n", client->name, chip_id);
return 0;
}else {
return -1;
}
}
/************pc v\hsync***************/
static void timer_callbak_func(unsigned long arg)
{
int offset = -0, val1 = -1, val2 = -1;
int hsync_cnt = 0, vsync_cnt = 0;
unsigned long vtime, htime;
struct scaler_platform_data *pdata = (struct scaler_platform_data*)arg;
vtime = jiffies + msecs_to_jiffies(200);
val1 = gpio_get_value(pdata->vga_vsync_gpio);
while (time_after(vtime, jiffies)) {
val2 = gpio_get_value(pdata->vga_vsync_gpio);
if (val1 != val2) {
vsync_cnt++;
val1 = val2;
}
}
//printk("vsync cnt = %d\n", vsync_cnt);
htime = jiffies + msecs_to_jiffies(100);
val1 = gpio_get_value(pdata->vga_hsync_gpio);
while (time_after(htime, jiffies)) {
val2 = gpio_get_value(pdata->vga_hsync_gpio);
if (val1 != val2) {
hsync_cnt++;
val1 = val2;
}
}
//printk("hsync cnt = %d\n", hsync_cnt);
//set reg
offset = vga_offset;
if (hsync_cnt > 10500 && hsync_cnt < 11500)
offset = 0;
if (hsync_cnt > 12000 && hsync_cnt < 12700)
offset = 1;
if (hsync_cnt > 9100 && hsync_cnt < 9600)
offset = 2;
if (offset != vga_offset) {
vga_offset = offset;
tv5735_init_reg(vga2vga_regs[offset].regs,
vga2vga_regs[offset].len);
}
mod_timer(&timer, (jiffies + msecs_to_jiffies(100)));
}
static void setup_detect_pcsync_timer(const struct scaler_platform_data *pdata)
{
if (pdata->vga_hsync_gpio > 0) {
if (gpio_request(pdata->vga_hsync_gpio, NULL) != 0) {
printk("%s: request pc hsync detect pin failed\n", __func__);
}else {
if (pdata->vga_vsync_gpio > 0) {
if (gpio_request(pdata->vga_vsync_gpio, NULL) != 0) {
gpio_free(pdata->vga_hsync_gpio);
printk("%s: request pc vsync detect pin failed\n", __func__);
}else {
gpio_direction_input(pdata->vga_hsync_gpio);
gpio_direction_input(pdata->vga_vsync_gpio);
init_timer(&timer);
timer.function = timer_callbak_func;
timer.data = (unsigned long)pdata;
timer.expires = jiffies + msecs_to_jiffies(3000);
vga_in_det = 1;
}//request vsync
}else {//defined vsync
gpio_free(pdata->vga_hsync_gpio);
}
}//request hsync
}//defined hsync
}
/********************pc v\hsync************************/
static int tv_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
int res;
struct scaler_platform_data *pdata = client->dev.platform_data;
if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
res = -ENODEV;
dev_err(&client->adapter->dev, "%s failed %d\n\n", __func__, res);
return -1;
}
if (!pdata) {
printk("%s: client private data not define\n", __func__);
return -1;
}
scaler_init_platform(pdata);
if (tv_hardware_is_ok(client) != 0) {
printk("%s chip hardware not ready\n", client->name);
return -1;
}
//alloc chip memory
chip = alloc_scaler_chip();
if (!chip) {
printk("%s: alloc scaler chip memory failed.\n", __func__);
return -1;
}else {
chip->client = client;
chip->pdata = pdata;
memcpy((void *)chip->name, (void *)client->name, (strlen(client->name) + 1));
}
//init chip
if (init_scaler_chip(chip, pdata) != 0) {
goto err;
}
//implement parse cmd function
chip->parse_cmd = parse_cmd;
chip->start = tv5735_start;
//register chip
if (register_scaler_chip(chip) != 0) {
printk("%s: register scaler chip failed\n", __func__);
goto err;
}
setup_detect_pcsync_timer(pdata);
return 0;
err:
free_scaler_chip(chip);
return -1;
}
static int tv_i2c_remove(struct i2c_client *client)
{
printk("%s: \n", __func__);
unregister_scaler_chip(chip);
free_scaler_chip(chip);
chip = NULL;
return 0;
}
static const struct i2c_device_id tv_i2c_id[] ={
{"tv5735", 0}, {}
};
MODULE_DEVICE_TABLE(i2c, tv_i2c_id);
static struct i2c_driver tv_i2c_driver = {
.id_table = tv_i2c_id,
.driver = {
.name = "tv5735"
},
.probe = tv_i2c_probe,
.remove = tv_i2c_remove,
};
static int __init tv_init(void)
{
int ret = 0;
printk("%s: \n", __func__);
ret = i2c_add_driver(&tv_i2c_driver);
if(ret < 0){
printk("%s, register i2c device, error\n", __func__);
return ret;
}
return 0;
}
static void __exit tv_exit(void)
{
printk("%s: \n", __func__);
}
module_init(tv_init);
module_exit(tv_exit);

File diff suppressed because it is too large Load Diff

View File

@@ -1,567 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
*
* Copyright (C) 2012 Rockchip
*
*---------------------------------
* version 1.0 2012-9-13
*
*/
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/err.h>
#include <linux/delay.h>
#include <linux/sysfs.h>
#include <linux/fs.h>
#include <linux/gpio.h>
#include <linux/version.h>
#include <linux/pm_runtime.h>
#include <asm/uaccess.h>
#include <linux/scaler-core.h>
#define SCALER_CORE_VERSION "v1.0.0"
#define SCALER_CORE_NAME "scaler-core"
#define SCALER_DEV_NAME "scaler-ctrl"
static DEFINE_MUTEX(mutex_chips);
static DEFINE_MUTEX(mutex_ports);
static struct scaler_device *sdev = NULL;
static unsigned short chip_ids = 0; //<id only grow>只增不减
static unsigned int port_ids = 0;
extern int scaler_sysfs_create(struct scaler_device *sdev);
extern int scaler_sysfs_remove(struct scaler_device *sdev);
static const char const *scaler_output_name[] = {
"output type",
"LVDS",
"VGA",
"RGB",
"HDMI",
"DP",
};
const char const *scaler_input_name[] = {
"input tpye",
"VGA",
"RGB",
"HDMI",
"DP",
"DVI",
"YPBPR",
"YCBCR",
"MYDP",
"IDP",
};
static const char const *scaler_func_name[] ={
"This Scaler Function Type Is:",
"convertor",
"switch",
"full function",
};
static void scaler_led_on(int gpio)
{
gpio_set_value(gpio, GPIO_HIGH);
}
static void scaler_led_off(int gpio)
{
gpio_set_value(gpio, GPIO_LOW);
}
static void default_start(void)
{
}
static void default_stop(void)
{
}
static int default_read(unsigned short reg, int bytes, void *desc)
{
return 0;
}
static int default_write(unsigned short reg, int bytes, void *desc)
{
return 0;
}
static int default_parse_cmd(unsigned int cmd, unsigned long arg)
{
return 0;
}
//alloc chip dev memory and init default value
struct scaler_chip_dev *alloc_scaler_chip(void)
{
struct scaler_chip_dev *p = kzalloc(sizeof(struct scaler_chip_dev), GFP_KERNEL);
if (p) {
strcpy(p->name, "unknown");
//init default operation function
p->start = default_start;
p->stop = default_stop;
p->read = default_read;
p->write = default_write;
p->parse_cmd = default_parse_cmd;
//init list head
INIT_LIST_HEAD(&p->next);
INIT_LIST_HEAD(&p->oports);
INIT_LIST_HEAD(&p->iports);
}
return p;
}
int scaler_init_platform(struct scaler_platform_data *pdata)
{
printk("%s: init scaler platform\n", SCALER_CORE_NAME);
if (pdata->init_hw) {
pdata->init_hw();
msleep(5);
}
//power
if (pdata->power_gpio > 0) {
if (!gpio_request(pdata->power_gpio, NULL)) {
if (pdata->power_level != GPIO_HIGH &&
pdata->power_level != GPIO_LOW) {
printk("%s: power pin level use default high\n", SCALER_CORE_NAME);
pdata->power_level = GPIO_HIGH;
}
gpio_direction_output(pdata->power_gpio, pdata->power_level);
}else
printk("%s: request vga power gpio failed\n", SCALER_CORE_NAME);
}else
printk("%s: Don't defined power gpio pin\n", SCALER_CORE_NAME);
//vga 5v en
if (pdata->vga5v_gpio > 0) {
if (!gpio_request(pdata->vga5v_gpio, NULL)) {
if (pdata->vga5v_level != GPIO_HIGH &&
pdata->vga5v_level != GPIO_LOW) {
printk("%s: vga5ven pin level use default high\n", SCALER_CORE_NAME);
pdata->vga5v_level = GPIO_HIGH;
}
gpio_direction_output(pdata->vga5v_gpio, pdata->vga5v_level);
}else
printk("%s: request vga5ven gpio failed\n", SCALER_CORE_NAME);
msleep(10);
}else
printk("%s: Don't defined vga5ven gpio pin\n", SCALER_CORE_NAME);
//ddc select
if (pdata->ddc_sel_gpio > 0) {
if (!gpio_request(pdata->ddc_sel_gpio, NULL)) {
if (pdata->ddc_sel_level != GPIO_HIGH &&
pdata->ddc_sel_level != GPIO_LOW) {
printk("%s: ddc select pin level use default high\n", SCALER_CORE_NAME);
pdata->ddc_sel_level = GPIO_HIGH;
}
gpio_direction_output(pdata->ddc_sel_gpio, pdata->ddc_sel_level);
}else
printk("%s: request ddc select gpio failed\n", SCALER_CORE_NAME);
msleep(10);
}else
printk("%s: Don't defined ddc select gpio pin\n", SCALER_CORE_NAME);
}
int init_scaler_chip(struct scaler_chip_dev *chip, struct scaler_platform_data *pdata)
{
int i;
struct scaler_output_port *oport = NULL;
struct scaler_input_port *iport = NULL;
if (!chip || !pdata) {
printk("%s: chip or pdata is null.\n", SCALER_CORE_NAME);
return -1;
}
//set scaler function type
if (pdata->func_type > SCALER_FUNC_INVALID &&
pdata->func_type < SCALER_FUNC_NUMS) {
chip->func_type = pdata->func_type;
}else {
printk("%s: not defined scaer function type\n", SCALER_CORE_NAME);
chip->func_type = SCALER_FUNC_FULL;
}
printk("%s: %s %s\n", chip->name, scaler_func_name[0], scaler_func_name[chip->func_type]);
//set scaler support input type
for (i = 0; i < pdata->iport_size; i++) {
iport = kzalloc(sizeof(struct scaler_input_port), GFP_KERNEL);
if (!iport) {
printk("%s: kzalloc input port memeory failed.\n", SCALER_CORE_NAME);
return -1;
}else {
iport->max_hres = 1920;
iport->max_vres = 1080;
iport->freq = 60;
//input port id
mutex_lock(&mutex_ports);
iport->id = ++port_ids;
mutex_unlock(&mutex_ports);
//input port type
iport->type = pdata->iports[i].type;
//the first input port is default
if (!chip->cur_inport_id) {
chip->cur_in_type = iport->type;
chip->cur_inport_id = iport->id;
printk("%s: default %s %s\n", chip->name, scaler_input_name[0], scaler_input_name[iport->type]);
}
//init and request input gpio of indicator lamp
if (pdata->iports[i].led_gpio > 0) {
iport->led_gpio = pdata->iports[i].led_gpio;
if (!gpio_request(iport->led_gpio, NULL)) {
gpio_direction_output(iport->led_gpio, GPIO_HIGH);
}else {
printk("%s: request %s<id,%d> gpio failed\n", chip->name,
scaler_input_name[pdata->iports[i].type], iport->id);
}
}
//add input of chip
list_add_tail(&iport->next, &chip->iports);
printk("%s: support %s %s<id,%d> led_gpio %d\n", chip->name, scaler_input_name[0],
scaler_input_name[pdata->iports[i].type], iport->id, iport->led_gpio);
}//if (!iport)
}//for()
//set scaler output type
for (i = 0; i < pdata->oport_size; i++) {
oport = kzalloc(sizeof(struct scaler_output_port), GFP_KERNEL);
if (!oport) {
printk("%s: kzalloc output port memeory failed.\n", SCALER_CORE_NAME);
return -1;
}else {
oport->max_hres = 1920;
oport->max_vres = 1080;
oport->freq = 60;
//output port id
mutex_lock(&mutex_ports);
oport->id = ++port_ids;
mutex_unlock(&mutex_ports);
//output port type
oport->type = pdata->oports[i].type;
//the first output port is default
if (!chip->cur_outport_id) {
chip->cur_out_type = oport->type;
chip->cur_outport_id = oport->id;
printk("%s: default %s %s\n", chip->name, scaler_output_name[0], scaler_output_name[oport->type]);
}
//init and request output gpio of indicator lamp
if (pdata->oports[i].led_gpio > 0) {
oport->led_gpio = pdata->oports[i].led_gpio;
if (!gpio_request(oport->led_gpio, NULL)) {
gpio_direction_output(oport->led_gpio, GPIO_HIGH);
}else {
printk("%s: request %s<id,%d> gpio failed\n", chip->name, scaler_output_name[pdata->oports[i].type], oport->id);
}
}
list_add_tail(&oport->next, &chip->oports);
printk("%s: support %s %s<id,%d> led_gpio %d\n", chip->name, scaler_output_name[0],
scaler_output_name[pdata->oports[i].type], oport->id, oport->led_gpio);
}// if (!oport)
}//for()
return 0;
}
//free scaler chip memory
void free_scaler_chip(struct scaler_chip_dev *chip)
{
struct scaler_output_port *out = NULL;
struct scaler_input_port *in = NULL;
if (chip) {
printk("%s: free %s chip<id:%d> memory resource\n",
SCALER_CORE_NAME, chip->name, chip->id);
list_for_each_entry(out, &chip->oports, next) {
kfree(out);
}
list_for_each_entry(in, &chip->iports, next) {
if (in->led_gpio > 0)
gpio_free(in->led_gpio);
kfree(in);
}
kfree(chip);
}
}
//register chip to scaler core
int register_scaler_chip(struct scaler_chip_dev *chip)
{
int res = -1;
struct scaler_input_port *in;
struct scaler_output_port *out;
if (chip && sdev) {
res = 0;
//start chip to process
chip->start();
//power on input indicator lamp
list_for_each_entry(in, &chip->iports, next){
if (in->id == chip->cur_inport_id)
scaler_led_on(in->led_gpio);
else
scaler_led_off(in->led_gpio);
}
//power on output indicator lamp
list_for_each_entry(out, &chip->oports, next){
if (out->id == chip->cur_outport_id)
scaler_led_on(out->led_gpio);
else
scaler_led_off(out->led_gpio);
}
//add chip to scaler core
mutex_lock(&mutex_chips);
chip->id = ++chip_ids; //chip id only grow
list_add_tail(&chip->next, &sdev->chips);
mutex_unlock(&mutex_chips);
printk("%s: register scaler chip %s<id:%d> success.\n",
SCALER_CORE_NAME, chip->name, chip->id);
}else {
printk("%s: register scaler chip %s<id:%d> failed.\n",
SCALER_CORE_NAME, chip->name, chip->id);
}
return res;
}
//unregister chip to scaler core
int unregister_scaler_chip(struct scaler_chip_dev *chip)
{
int res = -1;
struct scaler_input_port *in;
struct scaler_output_port *out;
if (chip && sdev) {
res = 0;
chip->stop();
//power off input indicator lamp
list_for_each_entry(in, &chip->iports, next){
if (in->id == chip->cur_inport_id)
scaler_led_off(in->led_gpio);
}
//power off output indicator lamp
list_for_each_entry(out, &chip->oports, next){
if (out->id == chip->cur_outport_id)
scaler_led_off(out->led_gpio);
}
//del chip from scaler core
mutex_lock(&mutex_chips);
list_del(&chip->next);
mutex_unlock(&mutex_chips);
printk("%s: unregister scaler chip %s<id:%d> success.\n", __func__, chip->name, chip->id);
}
return res;
}
/*** cdev operate ***/
static int scaler_file_open(struct inode *inode, struct file *filp)
{
return 0;
}
static int scaler_file_close(struct inode *inode, struct file *filp)
{
return 0;
}
static ssize_t scaler_file_read(struct file *filp, char *buf, size_t count, loff_t *f_pos)
{
return 0;
}
static ssize_t scaler_file_write(struct file *filp, const char *buf, size_t count, loff_t *f_pos)
{
return 0;
}
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36)
static long scaler_file_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
#else
static int scaler_file_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)
#endif
{
int iport_id;
struct scaler_chip_dev *chip = NULL;
struct scaler_input_port *iport = NULL;
switch(cmd) {
case 0:
printk("get cur input cmd %#x\n", SCALER_IOCTL_GET_CUR_INPUT);
printk("set cur input cmd %#x\n", SCALER_IOCTL_SET_CUR_INPUT);
break;
case SCALER_IOCTL_SET_CUR_INPUT:
//choose input channel;
copy_from_user(&iport_id, (void *)arg, sizeof(int));
list_for_each_entry(chip, &sdev->chips, next) {
if (chip->cur_inport_id != iport_id) {
list_for_each_entry(iport, &chip->iports, next) {//if iport belong to this chip
if (iport->id == iport_id) {
chip->cur_inport_id = iport_id;
chip->cur_in_type = iport->type;
chip->parse_cmd(cmd, arg);
break;
}
}//list iports
}
}//list chips
break;
case SCALER_IOCTL_GET_CUR_INPUT:
list_for_each_entry(chip, &sdev->chips, next) {
iport_id = chip->cur_inport_id;
}//list chips
copy_to_user((void *)arg, &iport_id, sizeof(int));
printk("current input port id %d\n", iport_id);
break;
default:
//default_parse_cmd(cmd, arg);
break;
}
return 0;
}
struct file_operations scaler_fops = {
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 36)
.unlocked_ioctl =scaler_file_ioctl,
#else
.ioctl =scaler_file_ioctl, //定义所有对scaler操作的cmd
#endif
.read =scaler_file_read,
.write = scaler_file_write,
.open = scaler_file_open,
.release = scaler_file_close,
};
//注册一个scaler的字符设备 供别的设备操作scaler
static int scaler_register_chrdev(void)
{
int ret = 0;
ret = alloc_chrdev_region(&sdev->devno, 0, 1, SCALER_DEV_NAME);
if(ret != 0){
printk("%s, can't allocate chrdev devno.\n", __func__);
return ret;
}else {
printk("%s: Scaler chrdev devno(%d,%d).\n", __func__, MAJOR(sdev->devno), MINOR(sdev->devno));
}
// initialize character device driver
sdev->cdev = cdev_alloc();
if (!sdev->cdev) {
printk("%s: cdev alloc failed.\n", __func__);
goto err1;
}
cdev_init(sdev->cdev, &scaler_fops);
sdev->cdev->owner = THIS_MODULE;
ret = cdev_add(sdev->cdev, sdev->devno, 1);
if(ret < 0){
printk("%s, add character device error, ret %d\n", __func__, ret);
goto err2;
}
sdev->class = class_create(THIS_MODULE, "scaler");
if(!sdev->class){
printk("%s, create class failed\n", __func__);
goto err3;
}
sdev->dev = device_create(sdev->class, NULL, sdev->devno, sdev, SCALER_DEV_NAME);
if (!sdev->dev) {
printk("%s: create device failed\n", __func__);
goto err4;
}
return 0;
err4:
class_destroy(sdev->class);
err3:
cdev_del(sdev->cdev);
err2:
kfree(sdev->cdev);
err1:
unregister_chrdev_region(sdev->devno, 1);
return -1;
}
static void scaler_unregister_chrdev(void)
{
cdev_del(sdev->cdev);
unregister_chrdev_region(sdev->devno, 1);
kfree(sdev->cdev);
device_destroy(sdev->class, sdev->devno);
class_destroy(sdev->class);
}
static int __init rk_scaler_init(void)
{
printk("%s: SCALER CORE VERSION: %s\n", __func__, SCALER_CORE_VERSION);
sdev = kzalloc(sizeof(struct scaler_device), GFP_KERNEL);
if (!sdev) {
printk("%s: malloc scaler devices failed.\n", __func__);
return -1;
}else {
INIT_LIST_HEAD(&sdev->chips);
}
if (scaler_register_chrdev() < 0) {
printk("%s: scaler register chrdev failed.\n", __func__);
goto err1;
}
if (scaler_sysfs_create(sdev) < 0) {
printk("%s: scaler sysfs create faild.\n", __func__);
goto err2;
}
return 0;
err2:
scaler_unregister_chrdev();
err1:
kfree(sdev);
return -1;
}
static void __exit rk_scaler_exit(void)
{
printk("%s\n", __func__);
scaler_sysfs_remove(sdev);
scaler_unregister_chrdev();
kfree(sdev);
}
subsys_initcall(rk_scaler_init);
module_exit(rk_scaler_exit);
MODULE_AUTHOR("linjh <linjh@rock-chips.com>");
MODULE_DESCRIPTION("RK Scaler Device Driver");
MODULE_LICENSE("GPL");

View File

@@ -1,479 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0 */
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/fb.h>
#include <mach/gpio.h>
#include <mach/iomux.h>
//#include <linux/rk_screen.h>
#include <linux/rk_fb.h>
#include "../../video/edid.h"
#define DDC_ADDR 0x50 //read 0xa0 write 0xa1
#define DDC_I2C_RATE 100*1000
#define DEFAULT_MODE 3
#undef SDEBUG
#ifdef SDEBUG
#define SPRINTK(fmt, args...) printk(fmt,## args)
#else
#define SPRINTK(fmt, args...)
#endif
static struct scaler_ddc_dev
{
unsigned char *edid;
struct i2c_client *client;
struct fb_monspecs specs;
struct list_head modelist;
struct fb_videomode *mode;
}*ddev = NULL;
static const struct fb_videomode default_modedb[] = {
//name refresh xres yres pixclock h_bp h_fp v_bp v_fp h_pw v_pw polariry PorI flag(used for vic)
#if defined(CONFIG_CLK_RK30_BOX)
{ "1024x768p@60Hz", 60, 1024, 768, KHZ2PICOS(65000), 160, 24, 29, 3, 136, 6, 0, 0, 0 },
{ "1280x720p@60Hz", 60, 1280, 720, KHZ2PICOS(74250), 220, 110, 20, 5, 40, 5, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 0 },
{ "1280x1024p@60Hz", 60, 1280, 1024, KHZ2PICOS(108000), 248, 48, 38, 1, 112, 3, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 0 },
{ "1366x768p@60Hz", 60, 1366, 768, KHZ2PICOS(85500), 213, 70, 24, 3, 143, 3, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 0 },
{ "1440x900p@60Hz", 60, 1440, 900, KHZ2PICOS(106500), 232, 80, 25, 3, 152, 6, FB_SYNC_VERT_HIGH_ACT, 0, 0 },
{ "1680x1050p@60Hz", 60, 1680, 1050, KHZ2PICOS(146250), 280, 104, 30, 3, 176, 6, FB_SYNC_VERT_HIGH_ACT, 0, 0 },
{ "1920x1080p@60Hz", 60, 1920, 1080, KHZ2PICOS(148500), 148, 88, 36, 4, 44, 5, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 0 },
#else
//{ "640x480p@60Hz", 60, 640, 480, KHZ2PICOS(25175), 48, 16, 33, 10, 96, 2, 0, 0, 1 },
{ "720x480p@60Hz", 60, 720, 480, KHZ2PICOS(27000), 60, 16, 30, 9, 62, 6, 0, 0, 2 },
{ "720x576p@50Hz", 50, 720, 576, KHZ2PICOS(27000), 68, 12, 39, 5, 64, 5, 0, 0, 17 },
{ "1280x720p@50Hz", 50, 1280, 720, KHZ2PICOS(74250), 220, 440, 20, 5, 40, 5, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 19 },
{ "1280x720p@60Hz", 60, 1280, 720, KHZ2PICOS(74250), 220, 110, 20, 5, 40, 5, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 4 },
{ "1920x1080p@50Hz", 50, 1920, 1080, KHZ2PICOS(148500), 148, 528, 36, 4, 44, 5, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 31 },
{ "1920x1080p@60Hz", 60, 1920, 1080, KHZ2PICOS(148500), 148, 88, 36, 4, 44, 5, FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 0, 16 },
#endif
};
static int scaler_mode2screen(const struct fb_videomode *modedb, struct rk29fb_screen *screen)
{
if(modedb == NULL || screen == NULL)
return -1;
memset(screen, 0, sizeof(struct rk29fb_screen));
/* screen type & face */
screen->type = SCREEN_RGB;
screen->face = OUT_P888;
//screen->lvds_format = LVDS_8BIT_1; //lvds data format
/* Screen size */
screen->x_res = modedb->xres;
screen->y_res = modedb->yres;
/* Timing */
screen->pixclock = PICOS2KHZ(modedb->pixclock);
screen->pixclock /= 250;
screen->pixclock *= 250;
screen->pixclock *= 1000;
printk(" pixclock is %d\n", screen->pixclock);
screen->lcdc_aclk = 300000000;
screen->left_margin = modedb->left_margin ;
screen->right_margin = modedb->right_margin;
screen->hsync_len = modedb->hsync_len;
screen->upper_margin = modedb->upper_margin ;
screen->lower_margin = modedb->lower_margin;
screen->vsync_len = modedb->vsync_len;
/* Pin polarity */
if(FB_SYNC_HOR_HIGH_ACT & modedb->sync)
screen->pin_hsync = 1;
else
screen->pin_hsync = 0;
if(FB_SYNC_VERT_HIGH_ACT & modedb->sync)
screen->pin_vsync = 1;
else
screen->pin_vsync = 0;
screen->pin_den = 0;
screen->pin_dclk = 1;
/* Swap rule */
screen->swap_rb = 0;
screen->swap_rg = 0;
screen->swap_gb = 0;
screen->swap_delta = 0;
screen->swap_dumy = 0;
/* Operation function*/
screen->init = NULL;
screen->standby = NULL;
return 0;
}
void set_vga_lcd_info(struct rk29fb_screen *screen, struct rk29lcd_info *lcd_info)
{
scaler_mode2screen(&default_modedb[DEFAULT_MODE], screen);
}
static int scaler_edid_read(char *buf, int len)
{
int rc;
if (ddev == NULL || ddev->client == NULL)
return -ENODEV;
if (buf == NULL)
return -ENOMEM;
// Check ddc i2c communication is available or not.
rc = i2c_master_reg8_recv(ddev->client, 0, buf, 6, DDC_I2C_RATE);
if(rc == 6) {
/************DEBUG*************/
SPRINTK("EDID HEAD: ");
for (rc = 0; rc < 6; rc++)
SPRINTK(" %#X", buf[rc]);
SPRINTK("\n");
/************DEBUG*************/
memset(buf, 0, len);
// Read EDID.
rc = i2c_master_reg8_recv(ddev->client, 0, buf, len, DDC_I2C_RATE);
if(rc == len)
return 0;
}
printk("unable to read EDID block.\n");
return -EIO;
}
/*
*read edid of monitor and parse it
*/
static int scaler_parse_vga_edid(void)
{
int i ;
struct fb_monspecs *specs = NULL;
if (ddev == NULL) {
return -ENODEV;
}else {
specs = &ddev->specs;
//free old edid
if (ddev->edid) {
kfree(ddev->edid);
ddev->edid = NULL;
}
ddev->edid = kzalloc(EDID_LENGTH, GFP_KERNEL);
if (!ddev->edid)
return -ENOMEM;
//read edid
if (!scaler_edid_read(ddev->edid, EDID_LENGTH)) {
//free old fb_monspecs
if(specs->modedb)
kfree(specs->modedb);
memset(specs, 0, sizeof(struct fb_monspecs));
//parse edid to fb_monspecs
fb_edid_to_monspecs(ddev->edid, specs);
/********** DEBUG ***********/
SPRINTK("========================================\n");
SPRINTK("Display Information (EDID)\n");
SPRINTK("========================================\n");
SPRINTK(" EDID Version %d.%d\n", (int) specs->version, (int) specs->revision);
SPRINTK(" Serial Number: %s\n", specs->serial_no);
SPRINTK(" ASCII Block: %s\n", specs->ascii);
SPRINTK(" Monitor Name: %s\n", specs->monitor);
SPRINTK(" Display Characteristics:\n");
for (i = 0; i < specs->modedb_len; i++)
SPRINTK(" %4d x %4d @%d [clk: %ldKHZ]\n", specs->modedb[i].xres, specs->modedb[i].yres,
specs->modedb[i].refresh, PICOS2KHZ(specs->modedb[i].pixclock));
SPRINTK("========================================\n");
/********** DEBUG ***********/
}else {
return -EIO;
}
}
printk("scaler-ddc: read and parse vga edid success.\n");
return 0;
}
static void scaler_set_default_modelist(void)
{
int i;
struct fb_videomode *mode = NULL;
struct list_head *modelist = &ddev->modelist;
fb_destroy_modelist(modelist);
for(i = 0; i < ARRAY_SIZE(default_modedb); i++)
{
mode = (struct fb_videomode *)&default_modedb[i];
fb_add_videomode(mode, modelist);
}
}
/*
* Check mode 1920x1080p@60Hz is in modedb or not.
* If exist, set it as output moe.
* If not exist, try mode 1280x720p@60Hz.
* If both mode not exist, try 720x480p@60Hz.
*/
static int scaler_check_mode(struct fb_videomode *mode)
{
struct fb_monspecs *specs = NULL;
struct list_head *modelist = NULL;
struct fb_videomode *tmp_mode = NULL;
unsigned int pixclock;
int i;
if (ddev == NULL)
return -ENODEV;
specs = &ddev->specs;
modelist = &ddev->modelist;
fb_destroy_modelist(modelist);
if (mode) {
for(i = 0; i < ARRAY_SIZE(default_modedb); i++) {
tmp_mode = (struct fb_videomode *)&default_modedb[i];
pixclock = PICOS2KHZ(tmp_mode->pixclock);
pixclock /= 250;
pixclock *= 250;
pixclock *= 1000;
if( (pixclock <= specs->dclkmax) &&
(tmp_mode->xres <= mode->xres) && (tmp_mode->yres <= mode->yres) &&
(tmp_mode->refresh <= specs->vfmax) && (tmp_mode->refresh >= specs->vfmin)
) {
fb_add_videomode(tmp_mode, modelist);
}
}
}
return 0;
}
/*
* Find monitor prefered video mode. If not find,
* @specs init info of monitor
*/
struct fb_videomode *scaler_find_max_mode(void)
{
struct fb_videomode *mode = NULL/*, *nearest_mode = NULL*/;
struct fb_monspecs *specs = NULL;
int i, pixclock;
if (ddev == NULL)
return NULL;
specs = &ddev->specs;
if(specs->modedb_len) {
/* Get max resolution timing */
mode = &specs->modedb[0];
for (i = 0; i < specs->modedb_len; i++) {
if(specs->modedb[i].xres > mode->xres)
mode = &specs->modedb[i];
else if( (specs->modedb[i].xres == mode->xres) && (specs->modedb[i].yres > mode->yres) )
mode = &specs->modedb[i];
}
// For some monitor, the max pixclock read from EDID is smaller
// than the clock of max resolution mode supported. We fix it.
pixclock = PICOS2KHZ(mode->pixclock);
pixclock /= 250;
pixclock *= 250;
pixclock *= 1000;
if(pixclock == 148250000)
pixclock = 148500000;
if(pixclock > specs->dclkmax)
specs->dclkmax = pixclock;
printk("scaler-ddc: max mode %dx%d@%d[pixclock-%ld KHZ]\n", mode->xres, mode->yres,
mode->refresh, PICOS2KHZ(mode->pixclock));
}
return mode;
}
static struct fb_videomode *scaler_find_best_mode(void)
{
int res = -1;
struct fb_videomode *mode = NULL, *best = NULL;
res = scaler_parse_vga_edid();
if (res == 0) {
mode = scaler_find_max_mode();
if (mode) {
scaler_check_mode(mode);
best = (struct fb_videomode *)fb_find_nearest_mode(mode, &ddev->modelist);
}
} else {
printk("scaler-ddc: read and parse edid failed errno:%d.\n", res);
}
return best;
}
int scaler_switch_screen(struct fb_videomode *mode)
{
struct rk29fb_screen screen;
if (mode) {
scaler_mode2screen(mode, &screen);
#ifdef CONFIG_ARCH_RK29
return FB_Switch_Screen(&screen, 1);
#else
return rk_fb_switch_screen(&screen, 1, 0);
#endif
}
printk("scaler-ddc: fb_videomode is null\n");
return -1;
}
int scaler_switch_default_screen(void)
{
int res;
struct fb_videomode *mode = NULL;
if (ddev == NULL) {
printk("scaler-ddc: No DDC Dev.\n");
return -ENODEV;
}
mode = scaler_find_best_mode();
if (mode) {
printk("scaler-ddc: best mode %dx%d@%d[pixclock-%ld KHZ]\n", mode->xres, mode->yres,
mode->refresh, PICOS2KHZ(mode->pixclock));
ddev->mode = mode;
res = scaler_switch_screen(mode);
}else {
res = -1;
printk("scaler-ddc: Don't find best mode\n");
}
return res;
}
EXPORT_SYMBOL(scaler_switch_default_screen);
struct fb_videomode *scaler_get_cmode(void)
{
struct fb_videomode *mode = NULL;
if (ddev != NULL)
mode = ddev->mode;
return mode;
}
EXPORT_SYMBOL(scaler_get_cmode);
static int scaler_ddc_probe(struct i2c_client *client,const struct i2c_device_id *id)
{
if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
return -ENODEV;
ddev = kzalloc(sizeof(struct scaler_ddc_dev), GFP_KERNEL);
if (ddev == NULL)
return -ENOMEM;
INIT_LIST_HEAD(&ddev->modelist);
ddev->client = client;
ddev->mode = &default_modedb[DEFAULT_MODE];
scaler_set_default_modelist();
printk("%s: success.\n", __func__);
return 0;
}
static int __devexit scaler_ddc_remove(struct i2c_client *client)
{
if(ddev->edid)
kfree(ddev->edid);
if (ddev->specs.modedb)
kfree(ddev->specs.modedb);
kfree(ddev);
return 0;
}
static const struct i2c_device_id scaler_ddc_id[] = {
{ "scaler_ddc", 0 },
{ }
};
static struct i2c_driver scaler_ddc_driver = {
.driver = {
.name = "scaler_ddc",
.owner = THIS_MODULE,
},
.probe = scaler_ddc_probe,
.remove = scaler_ddc_remove,
.id_table = scaler_ddc_id,
};
static int __init scaler_ddc_init(void)
{
return i2c_add_driver(&scaler_ddc_driver);
}
static void __exit scaler_ddc_exit(void)
{
i2c_del_driver(&scaler_ddc_driver);
}
subsys_initcall(scaler_ddc_init);
module_exit(scaler_ddc_exit);
/************SYSFS DEBUG ***********/
void scaler_ddc_is_ok(void)
{
int rc = -1;
char buf[8];
if (ddev != NULL) {
rc = i2c_master_reg8_recv(ddev->client, 0, buf, 8, DDC_I2C_RATE);
if(rc == 8) {
if (buf[0] == 0x00 && buf[1] == 0xff && buf[2] == 0xff && buf[3] == 0xff &&
buf[4] == 0xff && buf[5] == 0xff && buf[6] == 0xff && buf[7] == 0x00)
printk("scaler-ddc: is ok\n");
else
printk("scaler-ddc: io error");
}else
printk("scaler-ddc: i2c error\n");
}else
printk("scaler-ddc: unknown error\n");
}
void scaler_current_mode(void)
{
if (ddev != NULL && ddev->mode != NULL)
printk("scaler-ddc: cmode %dx%d@%d\n", ddev->mode->xres, ddev->mode->yres,
ddev->mode->refresh);
else
printk("scaler-ddc: unknown mode\n");
}
void scaler_test_read_vga_edid(void)
{
int i = 0, res;
struct fb_monspecs *specs = NULL;
res = scaler_parse_vga_edid();
if (res == 0) {
specs = &ddev->specs;
printk("========================================\n");
printk("Display Information (EDID)\n");
printk("========================================\n");
printk(" EDID Version %d.%d\n", (int) specs->version, (int) specs->revision);
printk(" Serial Number: %s\n", specs->serial_no);
printk(" ASCII Block: %s\n", specs->ascii);
printk(" Monitor Name: %s\n", specs->monitor);
printk(" Display Characteristics:\n");
for (i = 0; i < specs->modedb_len; i++)
printk(" %4d x %4d @%d [clk: %ldKHZ]\n", specs->modedb[i].xres, specs->modedb[i].yres,
specs->modedb[i].refresh, PICOS2KHZ(specs->modedb[i].pixclock));
printk("========================================\n");
}else{
printk("scaler-ddc: read and parse failed errno %d\n", res);
}
}

View File

@@ -1,126 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0 */
#include <linux/device.h>
#include <linux/init.h>
#include <linux/scaler-core.h>
#include <linux/slab.h>
#include <asm/uaccess.h>
extern void scaler_test_read_vga_edid(void);
extern void scaler_ddc_is_ok(void);
extern void scaler_current_mode(void);
extern const char const *scaler_input_name[];
static ssize_t scaler_chips_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct scaler_chip_dev *chip = NULL;
struct scaler_device *sdev = dev_get_drvdata(dev);
list_for_each_entry(chip, &sdev->chips, next) {
printk("name: %s<id: %d>\n", chip->name, chip->id);
}
return 0;
}
static DEVICE_ATTR(chips, 0664, scaler_chips_show, NULL);
static ssize_t scaler_iport_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
int iports = 0;
struct scaler_chip_dev *chip = NULL;
struct scaler_input_port *in = NULL;
struct scaler_device *sdev = dev_get_drvdata(dev);
list_for_each_entry(chip, &sdev->chips, next) {
list_for_each_entry(in, &chip->iports, next) {
iports++;
printk("id = %d type = %s gpio = %d\n", in->id,
scaler_input_name[in->type], in->led_gpio);
}
}
return sprintf(buf, "%d\n", iports);
}
static DEVICE_ATTR(iports, 0664, scaler_iport_show, NULL);
static ssize_t scaler_cur_iport_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct scaler_chip_dev *chip = NULL;
//struct scaler_input_port *in = NULL;
struct scaler_device *sdev = dev_get_drvdata(dev);
list_for_each_entry(chip, &sdev->chips, next) {
printk("id = %d type = %s\n", chip->cur_inport_id,
scaler_input_name[chip->cur_in_type]);
}
return 0;
}
static DEVICE_ATTR(cur_iport, 0664, scaler_cur_iport_show, NULL);
static ssize_t scaler_cmode_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
scaler_current_mode();
return 0;
}
static DEVICE_ATTR(current_mode, 0664, scaler_cmode_show, NULL);
static ssize_t scaler_edid_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
scaler_test_read_vga_edid();
return 0;
}
static DEVICE_ATTR(edid, 0664, scaler_edid_show, NULL);
static ssize_t scaler_ddc_status_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
scaler_ddc_is_ok();
return 0;
}
static DEVICE_ATTR(ddc_status, 0664, scaler_ddc_status_show, NULL);
static struct attribute *scaler_attributes[] = {
&dev_attr_chips.attr,
&dev_attr_iports.attr,
&dev_attr_cur_iport.attr,
&dev_attr_current_mode.attr,
&dev_attr_edid.attr,
&dev_attr_ddc_status.attr,
NULL
};
static mode_t scaler_attr_is_visible(struct kobject *kobj,
struct attribute *attr, int n)
{
mode_t mode = attr->mode;
return mode;
}
static const struct attribute_group scaler_attr_group = {
.is_visible = scaler_attr_is_visible,
.attrs = scaler_attributes,
};
int scaler_sysfs_create(struct scaler_device *sdev)
{
int err;
err = sysfs_create_group(&sdev->dev->kobj, &scaler_attr_group);
return err;
}
int scaler_sysfs_remove(struct scaler_device *sdev)
{
sysfs_remove_group(&sdev->dev->kobj, &scaler_attr_group);
return 0;
}

View File

@@ -1,172 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __SCALER_CORE_H__
#define __SCALER_CORE_H__
#include <linux/platform_device.h>
#include <linux/i2c.h>
#include <linux/cdev.h>
#include <linux/file.h>
#include <linux/list.h>
#include <linux/fb.h>
struct scaler_platform_data;
struct display_edid {
char *data;
char *ext_data;
};
enum scaler_output_type {
SCALER_OUT_INVALID = 0,
SCALER_OUT_LVDS,
SCALER_OUT_VGA,
SCALER_OUT_RGB,
SCALER_OUT_HDMI,
SCALER_OUT_DP,
SCALER_OUT_NUMS,
};
enum scaler_input_type {
SCALER_IN_INVALID = 0,
SCALER_IN_VGA,
SCALER_IN_RGB,
SCALER_IN_HDMI,
SCALER_IN_DP,
SCALER_IN_DVI,
SCALER_IN_YPBPR,
SCALER_IN_YCBCR,
SCALER_IN_MYDP,
SCALER_IN_IDP,
SCALER_IN_NUMS,
};
enum scaler_bus_type {
SCALER_BUS_TYPE_INVALID = 0,
SCALER_BUS_TYPE_UART,
SCALER_BUS_TYPE_I2C,
SCALER_BUS_TYPE_SPI,
SCALER_BUS_TYPE_NUMS,
};
/*
* the function of scaler, for example convertor or switch
*/
enum scaler_function_type {
SCALER_FUNC_INVALID = 0,
SCALER_FUNC_CONVERTOR, //转换器
SCALER_FUNC_SWITCH, //切换开关多选一输出
SCALER_FUNC_FULL, //全功能
SCALER_FUNC_NUMS,
};
struct scaler_output_port {
int id;
int max_hres;
int max_vres;
int freq;
int led_gpio; //working led
enum scaler_output_type type;
struct list_head next;
};
struct scaler_input_port {
int id;
int max_hres;
int max_vres;
int freq; //HZ
int led_gpio; //working led
enum scaler_input_type type;
struct list_head next;
};
struct scaler_chip_dev {
char id;
char name[I2C_NAME_SIZE];
struct i2c_client *client;
struct scaler_platform_data *pdata;
enum scaler_function_type func_type;
struct list_head iports;
struct list_head oports;
enum scaler_input_type cur_in_type;
enum scaler_output_type cur_out_type;
int cur_inport_id;
int cur_outport_id;
//enable chip to process image
void (*start)(void);
//disable chip to process image
void (*stop)(void);
void (*reset)(char active);
void (*suspend)(void);
void (*resume)(void);
//
int (*read)(unsigned short reg, int bytes, void *dest);
int (*write)(unsigned short reg, int bytes, void *src);
int (*parse_cmd)(unsigned int cmd, unsigned long arg);
int (*update_firmware)(void *data);
//scaler chip dev list
struct list_head next;
};
struct scaler_platform_data {
int int_gpio;
int reset_gpio;
int status_gpio; //check chip if work on lower power mode or normal mode.
int power_gpio;
int power_level;
int vga5v_gpio;
int vga5v_level;
int ddc_sel_gpio;
int ddc_sel_level; //ddc dev default select by defined the first input port in iports
int vga_hsync_gpio; //detect vga-in v\hsync clk by gpio
int vga_vsync_gpio;
char *firmware;
//function type
enum scaler_function_type func_type;
//config in and out
struct scaler_input_port *iports;
struct scaler_output_port *oports;
int iport_size;
int oport_size;
int (*init_hw)(void);
int (*exit_hw)(void);
};
struct scaler_device {
struct class *class;
struct device *dev;
struct cdev *cdev;
dev_t devno;
struct display_edid edid;
struct list_head chips;
};
//scaler core
int scaler_init_platform(struct scaler_platform_data *pdata);
struct scaler_chip_dev *alloc_scaler_chip(void);
//free chip memory and port memory
void free_scaler_chip(struct scaler_chip_dev *chip);
int init_scaler_chip(struct scaler_chip_dev *chip, struct scaler_platform_data *pdata);
int register_scaler_chip(struct scaler_chip_dev *chip);
int unregister_scaler_chip(struct scaler_chip_dev *chip);
//edid
int scaler_switch_default_screen(void);
struct fb_videmode *scaler_get_cmode(void);
//fs ioctl
#define SCALER_IOCTL_MAGIC 'a'
#define SCALER_IOCTL_POWER _IOW(SCALER_IOCTL_MAGIC, 0x00, char)
#define SCALER_IOCTL_GET_CUR_INPUT _IOR(SCALER_IOCTL_MAGIC, 0x01, int)
#define SCALER_IOCTL_SET_CUR_INPUT _IOW(SCALER_IOCTL_MAGIC, 0x02, int)
#endif