rk3288 lcdc: add support BCSH func
authorhjc <hjc@rock-chips.com>
Tue, 27 May 2014 08:03:59 +0000 (16:03 +0800)
committerhjc <hjc@rock-chips.com>
Tue, 27 May 2014 08:15:47 +0000 (16:15 +0800)
drivers/video/rockchip/lcdc/rk3288_lcdc.c
drivers/video/rockchip/rkfb_sysfs.c
include/linux/rk_fb.h

index d9dc627a0b969b733c6f62d59115e5204d90df91..dd72111ecfc3a3e52a498de51f0bcd0f858e569c 100755 (executable)
@@ -3166,56 +3166,53 @@ static int rk3288_lcdc_set_dsp_cabc(struct rk_lcdc_driver *dev_drv,int mode)
        return 0;
 }
 /*
-       Sin0=*0.000???????? Cos0=*1.000
-       Sin5=*0.087???????C  Cos5=*0.996
-       Sin10=*0.174                     Cos10=*0.985
-       Sin15=*0.259 ???????CCos15=*0.966
-       Sin20=*0.342????????Cos20=*0.940
-       Sin25=*0.422????????Cos25=*0.906
-       Sin30=*0.500????????Cos30=*0.866
+       a:[-30~0]:
+           sin_hue = sin(a)*256 +0x100;
+           cos_hue = cos(a)*256;
+       a:[0~30]
+           sin_hue = sin(a)*256;
+           cos_hue = cos(a)*256;
 */
-static int rk3288_lcdc_set_hue(struct rk_lcdc_driver *dev_drv,int hue)
+static int rk3288_lcdc_get_bcsh_hue(struct rk_lcdc_driver *dev_drv,bcsh_hue_mode mode)
 {
 
        struct lcdc_device *lcdc_dev =
            container_of(dev_drv, struct lcdc_device, driver);
-       int sin_hue_val,cos_hue_val;
-       u32 mask, val;
-
-       int sin_hue[7]={0,22, 44, 66, 87, 108, 128};
-       int cos_hue[7]={256,254,252,247,240,231,221};
-
-       if((hue > 0)&&(hue <= 30)){
-               /*sin_hue_val = (int)sin_hue[hue] * 256;
-                  cos_hue_val = (int)cos_hue[hue] * 256;*/
-               hue /= 5;
-               sin_hue_val = sin_hue[hue];
-               cos_hue_val = cos_hue[hue];
-       }else if((hue > 30)&&(hue <= 60)){
-               hue -= 30;
-               hue /= 5;
-               /*sin_hue_val = (int)sin_hue[hue] * 256 + 0x100;
-                  cos_hue_val = (int)cos_hue[hue] * 256 + 0x100;*/
-               sin_hue_val = sin_hue[hue] + 0x100;
-               cos_hue_val = cos_hue[hue] + 0x100;
-       }else{
-               dev_warn(lcdc_dev->dev,"hue=%d should be [0:60]\n",hue);
-       }
-               
-       spin_lock(&lcdc_dev->reg_lock); 
-       if(lcdc_dev->clk_on){
+       u32 val;
                        
-               mask = m_BCSH_OUT_MODE;
-               val = v_BCSH_OUT_MODE(3);       
-               lcdc_msk_reg(lcdc_dev, BCSH_BCS, mask, val);
+       spin_lock(&lcdc_dev->reg_lock);
+       if (lcdc_dev->clk_on) {
+               val = lcdc_readl(lcdc_dev, BCSH_H);
+               switch(mode){
+               case H_SIN:
+                       val &= m_BCSH_SIN_HUE;
+                       break;
+               case H_COS:
+                       val &= m_BCSH_COS_HUE;
+                       val >>= 16;
+                       break;
+               default:
+                       break;
+               }
+       }
+       spin_unlock(&lcdc_dev->reg_lock);
 
+       return val;
+}
+
+
+static int rk3288_lcdc_set_bcsh_hue(struct rk_lcdc_driver *dev_drv,int sin_hue, int cos_hue)
+{
+
+       struct lcdc_device *lcdc_dev =
+           container_of(dev_drv, struct lcdc_device, driver);
+       u32 mask, val;
+
+       spin_lock(&lcdc_dev->reg_lock);
+       if (lcdc_dev->clk_on) {
                mask = m_BCSH_SIN_HUE | m_BCSH_COS_HUE;
-               val = v_BCSH_SIN_HUE(sin_hue_val) | v_BCSH_COS_HUE(cos_hue_val);
+               val = v_BCSH_SIN_HUE(sin_hue) | v_BCSH_COS_HUE(cos_hue);
                lcdc_msk_reg(lcdc_dev, BCSH_H, mask, val);
-
-               mask = m_BCSH_EN;
-               val = v_BCSH_EN(1);
-               lcdc_msk_reg(lcdc_dev, BCSH_COLOR_BAR, mask, val);
                lcdc_cfg_done(lcdc_dev);
        }       
        spin_unlock(&lcdc_dev->reg_lock);
@@ -3223,30 +3220,101 @@ static int rk3288_lcdc_set_hue(struct rk_lcdc_driver *dev_drv,int hue)
        return 0;
 }
 
-static int rk3288_lcdc_set_bcsh_bcs(struct rk_lcdc_driver *dev_drv,int bri,int con,int sat)
+static int rk3288_lcdc_set_bcsh_bcs(struct rk_lcdc_driver *dev_drv,bcsh_bcs_mode mode,int value)
 {
        struct lcdc_device *lcdc_dev =
            container_of(dev_drv, struct lcdc_device, driver);
        u32 mask, val;
        
        spin_lock(&lcdc_dev->reg_lock);
-       if(lcdc_dev->clk_on){
-               mask = m_BCSH_OUT_MODE | m_BCSH_BRIGHTNESS |
-                       m_BCSH_CONTRAST | m_BCSH_SAT_CON;
-               val = v_BCSH_OUT_MODE(3) | v_BCSH_BRIGHTNESS(bri) |
-                       v_BCSH_CONTRAST(con) | v_BCSH_SAT_CON(sat);
+       if(lcdc_dev->clk_on) {
+               switch (mode) {
+               case BRIGHTNESS:
+               /*from 0 to 255,typical is 128*/
+                       if (value < 0x80)
+                               value += 0x80;
+                       else if (value >= 0x80)
+                               value = value - 0x80;
+                       mask =  m_BCSH_BRIGHTNESS;
+                       val = v_BCSH_BRIGHTNESS(value);
+                       break;
+               case CONTRAST:
+               /*from 0 to 510,typical is 256*/
+                       mask =  m_BCSH_CONTRAST;
+                       val =  v_BCSH_CONTRAST(value);
+                       break;
+               case SAT_CON:
+               /*from 0 to 1015,typical is 256*/
+                       mask = m_BCSH_SAT_CON;
+                       val = v_BCSH_SAT_CON(value);
+                       break;
+               default:
+                       break;
+               }
                lcdc_msk_reg(lcdc_dev, BCSH_BCS, mask, val);
+               lcdc_cfg_done(lcdc_dev);
+       }
+       spin_unlock(&lcdc_dev->reg_lock);
+       return val;
+}
 
-               mask = m_BCSH_EN;
-               val = v_BCSH_EN(1);
-               lcdc_msk_reg(lcdc_dev, BCSH_COLOR_BAR, mask, val);
+static int rk3288_lcdc_get_bcsh_bcs(struct rk_lcdc_driver *dev_drv,bcsh_bcs_mode mode)
+{
+       struct lcdc_device *lcdc_dev =
+           container_of(dev_drv, struct lcdc_device, driver);
+       u32 val;
+
+       spin_lock(&lcdc_dev->reg_lock);
+       if(lcdc_dev->clk_on) {
+               val = lcdc_readl(lcdc_dev, BCSH_BCS);
+               switch (mode) {
+               case BRIGHTNESS:
+                       val &= m_BCSH_BRIGHTNESS;
+                       if(val > 0x80)
+                               val -= 0x80;
+                       else
+                               val += 0x80;
+                       break;
+               case CONTRAST:
+                       val &= m_BCSH_CONTRAST;
+                       val >>= 8;
+                       break;
+               case SAT_CON:
+                       val &= m_BCSH_SAT_CON;
+                       val >>= 20;
+                       break;
+               default:
+                       break;
+               }
+       }
+       spin_unlock(&lcdc_dev->reg_lock);
+       return val;
+}
+
+
+static int rk3288_lcdc_open_bcsh(struct rk_lcdc_driver *dev_drv, bool open)
+{
+       struct lcdc_device *lcdc_dev =
+           container_of(dev_drv, struct lcdc_device, driver);
+       u32 mask, val;
+
+       spin_lock(&lcdc_dev->reg_lock);
+       if (lcdc_dev->clk_on) {
+               if (open) {
+                       lcdc_writel(lcdc_dev,BCSH_COLOR_BAR,0x1);
+                       lcdc_writel(lcdc_dev,BCSH_BCS,0xd0010000);
+                       lcdc_writel(lcdc_dev,BCSH_H,0x01000000);
+               } else {
+                       mask = m_BCSH_EN;
+                       val = v_BCSH_EN(0);
+                       lcdc_msk_reg(lcdc_dev, BCSH_COLOR_BAR, mask, val);
+               }
                lcdc_cfg_done(lcdc_dev);
        }
        spin_unlock(&lcdc_dev->reg_lock);
        return 0;
 }
 
-
 static struct rk_lcdc_win lcdc_win[] = {
        [0] = {
               .name = "win0",
@@ -3295,8 +3363,11 @@ static struct rk_lcdc_drv_ops lcdc_drv_ops = {
        .dpi_status             = rk3288_lcdc_dpi_status,
        .get_dsp_addr           = rk3288_lcdc_get_dsp_addr,
        .set_dsp_cabc           = rk3288_lcdc_set_dsp_cabc,
-       .set_dsp_hue            = rk3288_lcdc_set_hue,
+       .set_dsp_bcsh_hue       = rk3288_lcdc_set_bcsh_hue,
        .set_dsp_bcsh_bcs       = rk3288_lcdc_set_bcsh_bcs,
+       .get_dsp_bcsh_hue       = rk3288_lcdc_get_bcsh_hue,
+       .get_dsp_bcsh_bcs       = rk3288_lcdc_get_bcsh_bcs,
+       .open_bcsh              = rk3288_lcdc_open_bcsh,
        .dump_reg               = rk3288_lcdc_reg_dump,
        .cfg_done               = rk3288_lcdc_config_done,
        .set_irq_to_cpu         = rk3288_lcdc_set_irq_to_cpu,
index 47d10fc89030d316814512b5d235bf45f9a39654..49ffe6394bf975e2017b3fe1b3371f2ff7939e69 100755 (executable)
@@ -318,53 +318,68 @@ static ssize_t set_dsp_cabc(struct device *dev, struct device_attribute *attr,
 
        
 }
-
-static ssize_t show_hue(struct device *dev,
+static ssize_t show_dsp_bcsh(struct device *dev,
                            struct device_attribute *attr, char *buf)
 {
-
-       return 0;
-}
-
-static ssize_t set_hue(struct device *dev, struct device_attribute *attr,
-                          const char *buf, size_t count)
-{
        struct fb_info *fbi = dev_get_drvdata(dev);
        struct rk_lcdc_driver *dev_drv =
            (struct rk_lcdc_driver *)fbi->par;
-       int ret,hue;
-       
-       ret = kstrtoint(buf, 0, &hue);
-       if (ret)
-               return ret;
+       int brightness, contrast, sat_con, sin_hue, cos_hue;
 
-       ret = dev_drv->ops->set_dsp_hue(dev_drv, hue);
-       if(ret < 0)
-               return ret;
-       
-       return count;
-}
-
-static ssize_t show_dsp_bcs(struct device *dev,
-                           struct device_attribute *attr, char *buf)
-{
+       brightness = dev_drv->ops->get_dsp_bcsh_bcs(dev_drv, BRIGHTNESS);
+       contrast = dev_drv->ops->get_dsp_bcsh_bcs(dev_drv, CONTRAST);
+       sat_con = dev_drv->ops->get_dsp_bcsh_bcs(dev_drv, SAT_CON);
+       sin_hue = dev_drv->ops->get_dsp_bcsh_hue(dev_drv,H_SIN);
+       cos_hue = dev_drv->ops->get_dsp_bcsh_hue(dev_drv,H_COS);
 
+       snprintf(buf, PAGE_SIZE, "brightness:%4d,contrast:%4d,sat_con:%4d,"
+                                "sin_hue:%4d,cos_hue:%4d\n",
+                                brightness, contrast,sat_con,sin_hue,cos_hue);
        return 0;
 }
 
-static ssize_t set_dsp_bcs(struct device *dev, struct device_attribute *attr,
+static ssize_t set_dsp_bcsh(struct device *dev, struct device_attribute *attr,
                           const char *buf, size_t count)
 {
        struct fb_info *fbi = dev_get_drvdata(dev);
        struct rk_lcdc_driver *dev_drv =
            (struct rk_lcdc_driver *)fbi->par;
-       int ret,bri,con,sat;
-       
-       ret = kstrtoint(buf, 0, &bri);
-       if (ret)
-               return ret;
+       int brightness, contrast, sat_con, hue, ret, open, sin_hue, cos_hue;
+       if (!strncmp(buf, "open", 4)) {
+               ret = dev_drv->ops->open_bcsh(dev_drv, 1);
+       } else if (!strncmp(buf, "close", 5)) {
+               ret = dev_drv->ops->open_bcsh(dev_drv, 0);
+       } else if (!strncmp(buf, "brightness", 10)) {
+               sscanf(buf, "brightness %d", &brightness);
+               if (unlikely(brightness > 255)) {
+                       dev_err(fbi->dev,"brightness should be [0:255],now=%d\n\n",brightness);
+                       brightness = 255;
+               }
+               ret = dev_drv->ops->set_dsp_bcsh_bcs(dev_drv, BRIGHTNESS,brightness);
+       } else if (!strncmp(buf, "contrast", 8)) {
+               sscanf(buf, "contrast %d", &contrast);
+               if (unlikely(contrast > 510)) {
+                       dev_err(fbi->dev,"contrast should be [0:510],now=%d\n",contrast);
+                       contrast = 510;
+               }
+               ret = dev_drv->ops->set_dsp_bcsh_bcs(dev_drv, CONTRAST,contrast);
+       } else if (!strncmp(buf, "sat_con", 7)) {
+               sscanf(buf, "sat_con %d", &sat_con);
+               if (unlikely(sat_con > 1015)) {
+                       dev_err(fbi->dev,"sat_con should be [0:1015],now=%d\n",sat_con);
+                       sat_con = 1015;
+               }
+               ret = dev_drv->ops->set_dsp_bcsh_bcs(dev_drv, SAT_CON,sat_con);
+       } else if (!strncmp(buf, "hue", 3)) {
+               sscanf(buf, "hue %d %d", &sin_hue,&cos_hue);
+               if (unlikely(sin_hue > 511 || cos_hue > 511)) {
+                       dev_err(fbi->dev,"sin_hue=%d,cos_hue=%d\n",sin_hue,cos_hue);
+               }
+               ret = dev_drv->ops->set_dsp_bcsh_hue(dev_drv,sin_hue,cos_hue);
+       } else {
+               printk("format error\n");
+       }
 
-       ret = dev_drv->ops->set_dsp_bcsh_bcs(dev_drv, bri,con,sat);
        if(ret < 0)
                return ret;
        
@@ -459,8 +474,7 @@ static struct device_attribute rkfb_attrs[] = {
        __ATTR(map, S_IRUGO | S_IWUSR, show_fb_win_map, set_fb_win_map),
        __ATTR(dsp_lut, S_IRUGO | S_IWUSR, show_dsp_lut, set_dsp_lut),
        __ATTR(cabc, S_IRUGO | S_IWUSR, show_dsp_cabc, set_dsp_cabc),
-       __ATTR(hue, S_IRUGO | S_IWUSR, show_hue, set_hue),
-       __ATTR(bcs, S_IRUGO | S_IWUSR, show_dsp_bcs, set_dsp_bcs),
+       __ATTR(bcsh, S_IRUGO | S_IWUSR, show_dsp_bcsh, set_dsp_bcsh),
        __ATTR(scale, S_IRUGO | S_IWUSR, show_scale, set_scale),
 };
 
index 45cd481daadf2f6791f8d13bfd23953c841e9481..3693a222d3e7d5bf2742e739296ab4f60533ac14 100755 (executable)
@@ -223,6 +223,17 @@ enum
     SCALE_DOWN = 0x2
 };
 
+typedef enum {
+       BRIGHTNESS      = 0x0,
+       CONTRAST        = 0x1,
+       SAT_CON         = 0x2
+} bcsh_bcs_mode;
+
+typedef enum {
+       H_SIN           = 0x0,
+       H_COS           = 0x1
+} bcsh_hue_mode;
+
 
 struct rk_fb_rgb {
        struct fb_bitfield red;
@@ -396,8 +407,11 @@ struct rk_lcdc_drv_ops {
        int (*dpi_status) (struct rk_lcdc_driver * dev_drv);
        int (*get_dsp_addr)(struct rk_lcdc_driver * dev_drv,unsigned int *dsp_addr);
        int (*set_dsp_cabc) (struct rk_lcdc_driver * dev_drv, int mode);
-       int (*set_dsp_hue) (struct rk_lcdc_driver *dev_drv,int hue);
-       int (*set_dsp_bcsh_bcs)(struct rk_lcdc_driver *dev_drv,int bri,int con,int sat);
+       int (*set_dsp_bcsh_hue) (struct rk_lcdc_driver *dev_drv,int sin_hue, int cos_hue);
+       int (*set_dsp_bcsh_bcs)(struct rk_lcdc_driver *dev_drv,bcsh_bcs_mode mode,int value);
+       int (*get_dsp_bcsh_hue) (struct rk_lcdc_driver *dev_drv,bcsh_hue_mode mode);
+       int (*get_dsp_bcsh_bcs)(struct rk_lcdc_driver *dev_drv,bcsh_bcs_mode mode);
+       int (*open_bcsh)(struct rk_lcdc_driver *dev_drv, bool open);
        int (*dump_reg) (struct rk_lcdc_driver * dev_drv);
        int (*mmu_en) (struct rk_lcdc_driver * dev_drv);
        int (*cfg_done) (struct rk_lcdc_driver * dev_drv);