init scaler core
authorlinjh <linjh@rock-chips.com>
Mon, 30 Sep 2013 06:57:37 +0000 (14:57 +0800)
committerlinjh <linjh@rock-chips.com>
Mon, 30 Sep 2013 06:57:37 +0000 (14:57 +0800)
[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
drivers/misc/Makefile
drivers/misc/scaler/Kconfig [new file with mode: 0755]
drivers/misc/scaler/Makefile [new file with mode: 0644]
drivers/misc/scaler/chips/Kconfig [new file with mode: 0644]
drivers/misc/scaler/chips/Makefile [new file with mode: 0644]
drivers/misc/scaler/chips/tv5735.c [new file with mode: 0644]
drivers/misc/scaler/scaler-core.c [new file with mode: 0644]
drivers/misc/scaler/scaler-core.h [new file with mode: 0644]

index 3034dceb187de6dff10d48df758d1f2f9eac35ad..4e90a6d47c23a74374f1ad1b00bf5a95cc6e35e8 100755 (executable)
@@ -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
index 4614251b5d6fb4d929cf5a29b6a64dd56d89aa93..ff2e22c7a33d40c99db9ca7e6ed4114164d97a2a 100644 (file)
@@ -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 (executable)
index 0000000..4cb0b09
--- /dev/null
@@ -0,0 +1,11 @@
+#
+# all auto modem control drivers configuration\r
+#
+
+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 (file)
index 0000000..a18ce0c
--- /dev/null
@@ -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 (file)
index 0000000..7691e66
--- /dev/null
@@ -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 (file)
index 0000000..4854db3
--- /dev/null
@@ -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 (file)
index 0000000..664e63e
--- /dev/null
@@ -0,0 +1,163 @@
+/*\r
+       Copyright (c) 2010 by Rockchip.\r
+*/\r
+#include <linux/module.h>\r
+#include <linux/input.h>\r
+#include <linux/i2c.h>\r
+#include <linux/delay.h>\r
+#include <linux/kthread.h>\r
+#include <linux/sched.h>\r
+#include <linux/slab.h>\r
+#include <linux/interrupt.h>\r
+#include <linux/irq.h>\r
+#include <linux/cdev.h>\r
+#include <asm/uaccess.h>\r
+#include <linux/version.h>\r
+#include <linux/gpio.h>\r
+#include <linux/io.h>\r
+#include <linux/regulator/consumer.h>\r
+#include <mach/iomux.h>\r
+#include <mach/gpio.h>\r
+#ifdef CONFIG_HAS_EARLYSUSPEND\r
+#include <linux/earlysuspend.h>\r
+#include <linux/wakelock.h>\r
+#endif\r
+#include "../scaler-core.h"\r
+\r
+#define TV_DEV_NAME "trueview"\r
+#define TV_I2C_RATE  (100*1000)\r
+\r
+struct scaler_chip_dev *chip = NULL;\r
+\r
+/***      I2c operate    ***/\r
+static int tv_select_bank(struct i2c_client *client, char bank)\r
+{\r
+       int ret;\r
+       u8 sel_bank = 0xf0;\r
+\r
+       ret = i2c_master_reg8_send(client, sel_bank, &bank, 1, TV_I2C_RATE);\r
+       if (ret != 1)\r
+               printk("%s: write bank = %d failed.\n", __func__, bank);\r
+       return ret;\r
+\r
+}\r
+\r
+static int tv_read_single_data(struct i2c_client *client, char reg)\r
+{\r
+       int ret;\r
+       unsigned char val;\r
+\r
+       ret = i2c_master_reg8_recv(client, reg, &val, 1, TV_I2C_RATE);\r
+       if (ret != 1)\r
+               printk("%s: read reg8 value error:%d\n", __func__, ret);\r
+\r
+       return val;\r
+}\r
+\r
+static int tv_write_single_data(struct i2c_client *client, char reg, char value)\r
+{\r
+       int ret;\r
+       ret = i2c_master_reg8_send(client, reg, &value, 1, TV_I2C_RATE);\r
+       if (ret != 1)\r
+               printk("%s: write reg = %d failed.\n", __func__, reg);\r
+       return ret;\r
+}\r
+\r
+char test[] = "Test";\r
+int read_dev(unsigned short reg, int bytes, void *desc)\r
+{\r
+       int res = -1;\r
+       if (desc) {\r
+               memcpy(desc, test, 5);\r
+               res = 5;\r
+       }\r
+\r
+       return res;\r
+}\r
+\r
+static int parse_cmd(unsigned int cmd, void *arg)\r
+{\r
+       printk("tv5735: parse scaler cmd %u\n",cmd);\r
+       return 0;\r
+}\r
+\r
+//enbale chip to process image\r
+static void start(void) \r
+{\r
+}\r
+\r
+extern char *scaler_input_name[];\r
+static int tv_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id)\r
+{\r
+       struct scaler_platform_data  *pdata = client->dev.platform_data;\r
+\r
+       if (!pdata) {\r
+               printk("%s: client private data not define\n", __func__);\r
+               return -1;\r
+       }else {\r
+               printk("%s: <%s,%d>\n", __func__, scaler_input_name[pdata->default_in], pdata->in_leds_gpio[pdata->default_in]);\r
+       }\r
+\r
+       chip = alloc_scaler_chip();\r
+       if (!chip) {\r
+               printk("%s: alloc scaler chip memory failed.\n", __func__);\r
+               return -1;\r
+       }\r
+       chip->client = client;\r
+       memcpy((void *)chip->name, (void *)client->name, (strlen(client->name) + 1));\r
+       //implement parse cmd function\r
+       init_scaler_chip(chip, pdata);\r
+       chip->parse_cmd = parse_cmd;\r
+       //register\r
+       register_scaler_chip(chip);\r
+\r
+       return 0;\r
+}\r
+\r
+static int tv_i2c_remove(struct i2c_client *client)\r
+{\r
+\r
+       printk("%s: \n", __func__);\r
+       unregister_scaler_chip(chip);\r
+       free_scaler_chip(chip);\r
+       chip = NULL;\r
+       return 0;\r
+}\r
+\r
+\r
+static const struct i2c_device_id tv_i2c_id[] ={\r
+       {"tv5735", 0}, {}\r
+};\r
+MODULE_DEVICE_TABLE(i2c, tv_i2c_id);\r
+\r
+static struct i2c_driver tv_i2c_driver = {\r
+       .id_table = tv_i2c_id,\r
+       .driver = {\r
+               .name = "tv5735"\r
+       },\r
+       .probe = tv_i2c_probe,\r
+       .remove = tv_i2c_remove,\r
+};\r
+\r
+static int __init tv_init(void)\r
+{\r
+       int ret = 0;\r
+       printk("%s: .\n", __func__);\r
+\r
+       ret = i2c_add_driver(&tv_i2c_driver);\r
+       if(ret < 0){\r
+               printk("%s, register i2c device, error\n", __func__);\r
+               return ret;\r
+       }\r
+\r
+       return 0;\r
+}\r
+\r
+static void __exit tv_exit(void)\r
+{\r
+       printk("%s: .\n", __func__);\r
+}\r
+\r
+module_init(tv_init);\r
+module_exit(tv_exit);\r
+\r
diff --git a/drivers/misc/scaler/scaler-core.c b/drivers/misc/scaler/scaler-core.c
new file mode 100644 (file)
index 0000000..7358d0a
--- /dev/null
@@ -0,0 +1,512 @@
+/*
+ *
+ * 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 "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;       //<id only grow>只增不减
+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<id,%d>\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<id,%d>\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 <linjh@rock-chips.com>");
+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 (file)
index 0000000..5052fd1
--- /dev/null
@@ -0,0 +1,167 @@
+#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>
+
+
+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