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);
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",
.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,
}
-
-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;
__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),
};
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;
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);