From: hjc Date: Tue, 27 May 2014 08:03:59 +0000 (+0800) Subject: rk3288 lcdc: add support BCSH func X-Git-Tag: firefly_0821_release~5222 X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=af1283a6fdce4b9f47a06952da76ee6a47adcf04;p=firefly-linux-kernel-4.4.55.git rk3288 lcdc: add support BCSH func --- diff --git a/drivers/video/rockchip/lcdc/rk3288_lcdc.c b/drivers/video/rockchip/lcdc/rk3288_lcdc.c index d9dc627a0b96..dd72111ecfc3 100755 --- a/drivers/video/rockchip/lcdc/rk3288_lcdc.c +++ b/drivers/video/rockchip/lcdc/rk3288_lcdc.c @@ -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, diff --git a/drivers/video/rockchip/rkfb_sysfs.c b/drivers/video/rockchip/rkfb_sysfs.c index 47d10fc89030..49ffe6394bf9 100755 --- a/drivers/video/rockchip/rkfb_sysfs.c +++ b/drivers/video/rockchip/rkfb_sysfs.c @@ -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), }; diff --git a/include/linux/rk_fb.h b/include/linux/rk_fb.h index 45cd481daadf..3693a222d3e7 100755 --- a/include/linux/rk_fb.h +++ b/include/linux/rk_fb.h @@ -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);