From 7f27ae3765c0e562e32809abddb8be4860a4593a Mon Sep 17 00:00:00 2001 From: linjh Date: Mon, 30 Sep 2013 14:57:37 +0800 Subject: [PATCH] init scaler core [reference files] drivers/misc/Kconfig drivers/misc/Makefile drivers/misc/scaler/Kconfig drivers/misc/scaler/Makefile drivers/misc/scaler/chips/Kconfig drivers/misc/scaler/chips/Makefile drivers/misc/scaler/chips/tv5735.c drivers/misc/scaler/scaler-core.c drivers/misc/scaler/scaler-core.h --- drivers/misc/Kconfig | 1 + drivers/misc/Makefile | 1 + drivers/misc/scaler/Kconfig | 11 + drivers/misc/scaler/Makefile | 6 + drivers/misc/scaler/chips/Kconfig | 7 + drivers/misc/scaler/chips/Makefile | 1 + drivers/misc/scaler/chips/tv5735.c | 163 +++++++++ drivers/misc/scaler/scaler-core.c | 512 +++++++++++++++++++++++++++++ drivers/misc/scaler/scaler-core.h | 167 ++++++++++ 9 files changed, 869 insertions(+) create mode 100755 drivers/misc/scaler/Kconfig create mode 100644 drivers/misc/scaler/Makefile create mode 100644 drivers/misc/scaler/chips/Kconfig create mode 100644 drivers/misc/scaler/chips/Makefile create mode 100644 drivers/misc/scaler/chips/tv5735.c create mode 100644 drivers/misc/scaler/scaler-core.c create mode 100644 drivers/misc/scaler/scaler-core.h diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index 3034dceb187d..4e90a6d47c23 100755 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -576,4 +576,5 @@ source "drivers/misc/carma/Kconfig" source "drivers/misc/bp/Kconfig" source "drivers/misc/rk2928_callpad_misc/Kconfig" source "drivers/misc/3g_module/Kconfig" +source "drivers/misc/scaler/Kconfig" endif # MISC_DEVICES diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index 4614251b5d6f..ff2e22c7a33d 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile @@ -63,3 +63,4 @@ obj-$(CONFIG_RK29_SC8800) += sc8800.o obj-y += rk2928_callpad_misc/ obj-$(CONFIG_MODEM_SOUND) += modem_sound.o obj-$(CONFIG_TCC_BT_DEV) += tcc_bt_dev.o +obj-$(CONFIG_SCALER_DEVICE) += scaler/ diff --git a/drivers/misc/scaler/Kconfig b/drivers/misc/scaler/Kconfig new file mode 100755 index 000000000000..4cb0b09bf58a --- /dev/null +++ b/drivers/misc/scaler/Kconfig @@ -0,0 +1,11 @@ +# +# all auto modem control drivers configuration +# + +menuconfig SCALER_DEVICE + bool "Scaler Device Support" + default n + +if SCALER_DEVICE +source "drivers/misc/scaler/chips/Kconfig" +endif diff --git a/drivers/misc/scaler/Makefile b/drivers/misc/scaler/Makefile new file mode 100644 index 000000000000..a18ce0cf606b --- /dev/null +++ b/drivers/misc/scaler/Makefile @@ -0,0 +1,6 @@ +# +# Makefile for the display core. +# + +obj-$(CONFIG_SCALER_DEVICE) += chips/ +obj-$(CONFIG_SCALER_DEVICE) += scaler-core.o diff --git a/drivers/misc/scaler/chips/Kconfig b/drivers/misc/scaler/chips/Kconfig new file mode 100644 index 000000000000..7691e667b5b4 --- /dev/null +++ b/drivers/misc/scaler/chips/Kconfig @@ -0,0 +1,7 @@ +# +#config tv5735 support inport type and output type +# + +config SCALER_TV5735 + bool "Support tv5735 chip" + default n diff --git a/drivers/misc/scaler/chips/Makefile b/drivers/misc/scaler/chips/Makefile new file mode 100644 index 000000000000..4854db33e5a3 --- /dev/null +++ b/drivers/misc/scaler/chips/Makefile @@ -0,0 +1 @@ +obj-$(CONFIG_SCALER_TV5735) += tv5735.o diff --git a/drivers/misc/scaler/chips/tv5735.c b/drivers/misc/scaler/chips/tv5735.c new file mode 100644 index 000000000000..664e63e7ca95 --- /dev/null +++ b/drivers/misc/scaler/chips/tv5735.c @@ -0,0 +1,163 @@ +/* + Copyright (c) 2010 by Rockchip. +*/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef CONFIG_HAS_EARLYSUSPEND +#include +#include +#endif +#include "../scaler-core.h" + +#define TV_DEV_NAME "trueview" +#define TV_I2C_RATE (100*1000) + +struct scaler_chip_dev *chip = NULL; + +/*** I2c operate ***/ +static int tv_select_bank(struct i2c_client *client, char bank) +{ + int ret; + u8 sel_bank = 0xf0; + + ret = i2c_master_reg8_send(client, sel_bank, &bank, 1, TV_I2C_RATE); + if (ret != 1) + printk("%s: write bank = %d failed.\n", __func__, bank); + return ret; + +} + +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 int tv_write_single_data(struct i2c_client *client, char reg, char value) +{ + int ret; + ret = i2c_master_reg8_send(client, reg, &value, 1, TV_I2C_RATE); + if (ret != 1) + printk("%s: write reg = %d failed.\n", __func__, reg); + return ret; +} + +char test[] = "Test"; +int read_dev(unsigned short reg, int bytes, void *desc) +{ + int res = -1; + if (desc) { + memcpy(desc, test, 5); + res = 5; + } + + return res; +} + +static int parse_cmd(unsigned int cmd, void *arg) +{ + printk("tv5735: parse scaler cmd %u\n",cmd); + return 0; +} + +//enbale chip to process image +static void start(void) +{ +} + +extern char *scaler_input_name[]; +static int tv_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) +{ + struct scaler_platform_data *pdata = client->dev.platform_data; + + if (!pdata) { + printk("%s: client private data not define\n", __func__); + return -1; + }else { + printk("%s: <%s,%d>\n", __func__, scaler_input_name[pdata->default_in], pdata->in_leds_gpio[pdata->default_in]); + } + + chip = alloc_scaler_chip(); + if (!chip) { + printk("%s: alloc scaler chip memory failed.\n", __func__); + return -1; + } + chip->client = client; + memcpy((void *)chip->name, (void *)client->name, (strlen(client->name) + 1)); + //implement parse cmd function + init_scaler_chip(chip, pdata); + chip->parse_cmd = parse_cmd; + //register + register_scaler_chip(chip); + + return 0; +} + +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); + diff --git a/drivers/misc/scaler/scaler-core.c b/drivers/misc/scaler/scaler-core.c new file mode 100644 index 000000000000..7358d0ac3fe2 --- /dev/null +++ b/drivers/misc/scaler/scaler-core.c @@ -0,0 +1,512 @@ +/* + * + * Copyright (C) 2012 Rockchip + * + *--------------------------------- + * version 1.0 2012-9-13 + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "scaler-core.h" + +#define SCALER_CORE_VERSION "v1.0.0" +#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; //只增不减 +static unsigned int port_ids = 0; + +static const char const *scaler_output_name[] = { + "output type", + "LVDS", + "VGA", + "RGB", + "HDMI", + "DP", +}; + +const char const *scaler_input_name[] = { + "input tpye", + "VGA", + "RGB", + "DVI", + "YPBPR", + "YCBCR", + "DP", + "HDMI", + "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 int default_read(unsigned short reg, int bytes, void *desc) +{ + printk("Don't init read register func\n"); + return 0; +} + +static int default_write(unsigned short reg, int bytes, void *desc) +{ + printk("Don't init write register func\n"); + return 0; +} + +static int default_parse_cmd(unsigned int cmd, void *arg) +{ + struct scaler_chip_dev *chip = NULL; + printk("Don't init parse_scaler_cmd funct\n"); + + list_for_each_entry(chip, &sdev->chips, next) { + chip->parse_cmd(cmd, 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->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 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", __func__); + 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", __func__); + 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", __func__); + 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]; + + //init and request input gpio of indicator lamp + if (pdata->in_leds_gpio[pdata->iports[i]] > 0) { + iport->led_gpio = pdata->in_leds_gpio[pdata->iports[i]]; + if (gpio_request(iport->led_gpio, scaler_input_name[pdata->iports[i]])) { + gpio_direction_output(iport->led_gpio, GPIO_HIGH); + } + } + + //add input of chip + list_add(&iport->next, &chip->iports); + printk("%s: support %s %s\n", chip->name, scaler_input_name[0], scaler_input_name[pdata->iports[i]], iport->id); + } + } + + //default input type + if (pdata->default_in > SCALER_IN_INVALID && + pdata->default_in < SCALER_IN_NUMS) { + chip->cur_in_type = pdata->default_in; + }else { + chip->cur_in_type = SCALER_IN_VGA; + } + printk("%s: default %s %s\n", chip->name, scaler_input_name[0], scaler_input_name[pdata->default_in]); + + //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", __func__); + 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]; + + //init and request output gpio of indicator lamp + if (pdata->out_leds_gpio[pdata->oports[i]] > 0) { + oport->led_gpio = pdata->out_leds_gpio[pdata->iports[i]]; + if (gpio_request(oport->led_gpio, scaler_output_name[pdata->oports[i]])) { + gpio_direction_output(oport->led_gpio, GPIO_HIGH); + } + } + + list_add(&oport->next, &chip->oports); + printk("%s: support %s %s\n", chip->name, scaler_output_name[0], scaler_output_name[pdata->oports[i]], oport->id); + } + } + + //default output type + if (pdata->default_out > SCALER_OUT_INVALID && + pdata->default_out < SCALER_OUT_NUMS) { + chip->cur_out_type = pdata->default_out; + }else { + chip->cur_out_type = SCALER_OUT_VGA; + } + printk("%s: default %s %s\n", chip->name, scaler_output_name[0], scaler_output_name[pdata->default_out]); + + 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) { + + 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 + if (chip->start) + chip->start(); + + //power on input indicator lamp + list_for_each_entry(in, &chip->iports, next){ + if (in->type == chip->cur_in_type) + scaler_led_on(in->led_gpio); + scaler_led_off(in->led_gpio); + } + + //power on output indicator lamp + list_for_each_entry(out, &chip->oports, next){ + if (out->type == chip->cur_out_type) + scaler_led_on(out->led_gpio); + 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(&chip->next, &sdev->chips); + mutex_unlock(&mutex_chips); + printk("%s: register scaler chip %s success.\n", __func__, chip->name); + } + + 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; + + if (chip->stop) + chip->stop(); + + //power off input indicator lamp + list_for_each_entry(in, &chip->iports, next){ + if (in->type == chip->cur_in_type) + scaler_led_off(in->led_gpio); + } + + //power off output indicator lamp + list_for_each_entry(out, &chip->oports, next){ + if (out->type == chip->cur_out_type) + 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 success.\n", __func__, chip->name); + } + + 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 +{ + switch(cmd) { + case 0: + break; + case 1: + //choose input channel; + break; + default: + printk("%s: Don't register scaler chip!\n", __func__); + break; + } + + default_parse_cmd(cmd, NULL); + + 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){ + 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__); + return -1; + } + 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); + return ret; + } + + sdev->class = class_create(THIS_MODULE, SCALER_DEV_NAME); + if(IS_ERR(sdev->class)){ + printk("%s, create class, error\n", __func__); + return ret; + } + device_create(sdev->class, NULL, sdev->devno, NULL, SCALER_DEV_NAME); + + return 0; +} +#if 0 +static int scaler_register_i2c(struct scaler_platform_data *pdata) +{ + int res = 0; + struct i2c_board_info scaler_i2c_info; + printk("%s\n", __func__); + + if (pdata->i2c_channel < 0 || pdata->i2c_channel > 4) { + printk("%s: i2c channel %d bound [0,3]", __func__, pdata->i2c_channel); + return 1; + } + + strcpy(scaler_i2c_info.type, pdata->name); + scaler_i2c_info.addr = pdata->i2c_addr; + + res = i2c_register_board_info(pdata->i2c_channel, &scaler_i2c_info, 1); + if (res < 0) { + printk("%s: i2c register board info failed.\n", __func__); + return -1; + } + + + return res; +} + +static int rk_scaler_probe(struct platform_device *pdev) +{ + int res = 0; + struct scaler_platform_data *pdata; + + printk("%s\n", __func__); + pdata = pdev->dev.platform_data; + if (!pdata) { + printk("%s: Don't Defined Platform Data.\n", __func__); + return -1; + } + + sdev = kzalloc(sizeof(struct scaler_device), GFP_KERNEL); + if (!sdev) { + printk("%s: malloc scaler devices failed.\n", __func__); + return -1; + }else { + //sdev->pdata = pdata; + INIT_LIST_HEAD(&sdev->chips); + } + + scaler_register_chrdev(); + + //if (pdata->init_hw) + // pdata->init_hw(); + //else + // scaler_init_hw(); + + //res = scaler_register_i2c(pdata); + if (res < 0) + return -1; + + return res; +} + +static int rk_scaler_remove(struct platform_device *pdev) +{ + printk("%s\n", __func__); + kfree(sdev); + return 0; +} + +static struct platform_driver rk_scaler_driver = { + .probe = rk_scaler_probe, + .remove = rk_scaler_remove, + .driver = { + .name = "rk-scaler", + .owner = THIS_MODULE, + } +}; +#endif + +static int __init rk_scaler_init(void) +{ + //printk("%s\n", __func__); + //return platform_driver_register(&rk_scaler_driver); + int res = 0; + + 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); + } + + res = scaler_register_chrdev(); + + return res; +} + +static void __exit rk_scaler_exit(void) +{ + //platform_driver_unregister(&rk_scaler_driver); + kfree(sdev); +} + +subsys_initcall(rk_scaler_init); +module_exit(rk_scaler_exit); + +MODULE_AUTHOR("linjh "); +MODULE_DESCRIPTION("RK Scaler Device Driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/misc/scaler/scaler-core.h b/drivers/misc/scaler/scaler-core.h new file mode 100644 index 000000000000..5052fd1db772 --- /dev/null +++ b/drivers/misc/scaler/scaler-core.h @@ -0,0 +1,167 @@ +#ifndef __SCALER_CORE_H__ +#define __SCALER_CORE_H__ +#include +#include +#include +#include +#include + + +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_DVI, + SCALER_IN_YPBPR, + SCALER_IN_YCBCR, + SCALER_IN_DP, + SCALER_IN_HDMI, + 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; + unsigned 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 + unsigned 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; + + enum scaler_function_type func_type; + + int int_gpio; + int reset_gpio; + int power_gpio; + int status_gpio; + int reg_size; //8bit = 1, 16bit = 2, 24bit = 3,32bit = 4. + + struct list_head oports; //config all support output type by make menuconfig + struct list_head iports; //config all support input type by make menuconfig + enum scaler_input_type cur_in_type; + enum scaler_output_type cur_out_type; + + //init hardware(gpio etc.) + int (*init_hw)(void); + int (*exit_hw)(void); + + //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, void *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 power_gpio; + int status_gpio; //check chip if work on lower power mode or normal mode. + //config input indicator lamp + unsigned in_leds_gpio[SCALER_IN_NUMS]; + //config output indicator lamp + unsigned out_leds_gpio[SCALER_OUT_NUMS]; + + char *firmware; + //function type + enum scaler_function_type func_type; + + //config in and out + enum scaler_input_type *iports; + enum scaler_output_type *oports; + int iport_size; + int oport_size; + enum scaler_input_type default_in; + enum scaler_output_type default_out; + + int (*init_hw)(void); + int (*exit_hw)(void); +}; + +struct scaler_device { + struct class *class; + dev_t devno; + struct cdev *cdev; + + struct display_edid edid; + + struct list_head chips; +}; + +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); + +#define SCALER_IOCTL_MAGIC 's' +#define SCALER_IOCTL_POWER _IOW(SCALER_IOCTL_MAGIC, 0x00, char) +#define SCALER_IOCTL_GET_CUR_INPUT _IOR(SCALER_IOCTL_MAGIC, 0x01, int port_id) +#define SCALER_IOCTL_SET_CUR_INPUT _IOW(SCALER_IOCTL_MAGIC, 0x02, int port_id) + +#endif -- 2.34.1