mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-06 19:08:57 +09:00
rk3288 lcdc: add support BCSH func
This commit is contained in:
@@ -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);
|
||||
u32 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);
|
||||
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){
|
||||
|
||||
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) {
|
||||
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,
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
struct fb_info *fbi = dev_get_drvdata(dev);
|
||||
struct rk_lcdc_driver *dev_drv =
|
||||
(struct rk_lcdc_driver *)fbi->par;
|
||||
int brightness, contrast, sat_con, sin_hue, cos_hue;
|
||||
|
||||
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_hue(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,hue;
|
||||
|
||||
ret = kstrtoint(buf, 0, &hue);
|
||||
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_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)
|
||||
{
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ssize_t set_dsp_bcs(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;
|
||||
|
||||
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),
|
||||
};
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user