mirror of
https://github.com/armbian/linux.git
synced 2026-01-06 10:13:00 -08:00
rk2928 rk610 rk616 lvds:indepent from screen config file
This commit is contained in:
@@ -4,20 +4,23 @@
|
||||
#include <linux/device.h>
|
||||
#include <linux/delay.h>
|
||||
#include <asm/gpio.h>
|
||||
#include <linux/mfd/core.h>
|
||||
#include <linux/mfd/rk610_core.h>
|
||||
#include <linux/clk.h>
|
||||
#include <mach/iomux.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#if defined(CONFIG_ARCH_RK3066B)
|
||||
#define RK610_RESET_PIN RK30_PIN2_PC5
|
||||
#elif defined(CONFIG_ARCH_RK30)
|
||||
#define RK610_RESET_PIN RK30_PIN0_PC6
|
||||
#else
|
||||
#define RK610_RESET_PIN RK29_PIN6_PC1
|
||||
#if defined(CONFIG_DEBUG_FS)
|
||||
#include <linux/fs.h>
|
||||
#include <linux/debugfs.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/uaccess.h>
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Debug
|
||||
*/
|
||||
@@ -28,11 +31,15 @@
|
||||
#endif
|
||||
|
||||
static struct i2c_client *rk610_control_client = NULL;
|
||||
#ifdef CONFIG_RK610_LVDS
|
||||
extern int rk610_lcd_init(struct rk610_core_info *rk610_core_info);
|
||||
#else
|
||||
int rk610_lcd_init(struct rk610_core_info *rk610_core_info){}
|
||||
#endif
|
||||
|
||||
|
||||
static struct mfd_cell rk610_devs[] = {
|
||||
{
|
||||
.name = "rk610-lcd",
|
||||
.id = 0,
|
||||
},
|
||||
};
|
||||
|
||||
int rk610_control_send_byte(const char reg, const char data)
|
||||
{
|
||||
int ret;
|
||||
@@ -157,7 +164,7 @@ void rk610_control_init_codec(void)
|
||||
DBG("[%s] RK610_CONTROL_REG_CLOCK_CON1 is %x\n", __FUNCTION__, data);
|
||||
}
|
||||
#endif
|
||||
#ifdef RK610_DEBUG
|
||||
|
||||
static int rk610_read_p0_reg(struct i2c_client *client, char reg, char *val)
|
||||
{
|
||||
return i2c_master_reg8_recv(client, reg, val, 1, 100*1000) > 0? 0: -EINVAL;
|
||||
@@ -167,43 +174,58 @@ static int rk610_write_p0_reg(struct i2c_client *client, char reg, char *val)
|
||||
{
|
||||
return i2c_master_reg8_send(client, reg, val, 1, 100*1000) > 0? 0: -EINVAL;
|
||||
}
|
||||
static ssize_t rk610_show_reg_attrs(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
|
||||
|
||||
#if defined(CONFIG_DEBUG_FS)
|
||||
static int rk610_reg_show(struct seq_file *s, void *v)
|
||||
{
|
||||
|
||||
int i,size=0;
|
||||
char val;
|
||||
struct i2c_client *client=rk610_control_client;
|
||||
|
||||
for(i=0;i<256;i++)
|
||||
char reg = 0;
|
||||
u8 val = 0;
|
||||
struct rk610_core_info *core_info = s->private;
|
||||
if(!core_info)
|
||||
{
|
||||
rk610_read_p0_reg(client, i, &val);
|
||||
if(i%16==0)
|
||||
size += sprintf(buf+size,"\n>>>rk610_ctl %x:",i);
|
||||
size += sprintf(buf+size," %2x",val);
|
||||
dev_err(core_info->dev,"no mfd rk610!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return size;
|
||||
for(reg=C_PLL_CON0;reg<= I2C_CON;reg++)
|
||||
{
|
||||
rk610_read_p0_reg(core_info->client, reg, &val);
|
||||
if(reg%8==0)
|
||||
seq_printf(s,"\n0x%02x:",reg);
|
||||
seq_printf(s," %02x",val);
|
||||
}
|
||||
seq_printf(s,"\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
static ssize_t rk610_store_reg_attrs(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
const char *buf, size_t size)
|
||||
|
||||
static ssize_t rk610_reg_write (struct file *file, const char __user *buf, size_t count, loff_t *ppos)
|
||||
{
|
||||
struct rk610_core_info *core_info = file->f_path.dentry->d_inode->i_private;
|
||||
u32 reg,val;
|
||||
|
||||
char kbuf[25];
|
||||
if (copy_from_user(kbuf, buf, count))
|
||||
return -EFAULT;
|
||||
sscanf(kbuf, "%x%x", ®,&val);
|
||||
rk610_write_p0_reg(core_info->client, reg, (u8*)&val);
|
||||
return count;
|
||||
}
|
||||
|
||||
static int rk610_reg_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
struct i2c_client *client=NULL;
|
||||
static char val=0,reg=0;
|
||||
client = rk610_control_client;
|
||||
DBG("/**********rk610 reg config******/");
|
||||
|
||||
sscanf(buf, "%x%x", &val,®);
|
||||
DBG("reg=%x val=%x\n",reg,val);
|
||||
rk610_write_p0_reg(client, reg, &val);
|
||||
DBG("val=%x\n",val);
|
||||
return size;
|
||||
struct rk610_core_info *core_info = inode->i_private;
|
||||
return single_open(file,rk610_reg_show,core_info);
|
||||
}
|
||||
|
||||
static struct device_attribute rk610_attrs[] = {
|
||||
__ATTR(reg_ctl, 0777,rk610_show_reg_attrs,rk610_store_reg_attrs),
|
||||
static const struct file_operations rk610_reg_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = rk610_reg_open,
|
||||
.read = seq_read,
|
||||
.write = rk610_reg_write,
|
||||
.llseek = seq_lseek,
|
||||
.release = single_release,
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -248,14 +270,25 @@ static int rk610_control_probe(struct i2c_client *client,
|
||||
}
|
||||
|
||||
rk610_control_client = client;
|
||||
msleep(100);
|
||||
if(core_info->pdata->rk610_power_on_init)
|
||||
core_info->pdata->rk610_power_on_init();
|
||||
core_info->client = client;
|
||||
rk610_lcd_init(core_info);
|
||||
#ifdef RK610_DEBUG
|
||||
device_create_file(&(client->dev), &rk610_attrs[0]);
|
||||
core_info->dev = &client->dev;
|
||||
i2c_set_clientdata(client,core_info);
|
||||
ret = mfd_add_devices(&client->dev, -1,
|
||||
rk610_devs, ARRAY_SIZE(rk610_devs),
|
||||
NULL,0);
|
||||
|
||||
#if defined(CONFIG_DEBUG_FS)
|
||||
core_info->debugfs_dir = debugfs_create_dir("rk610", NULL);
|
||||
if (IS_ERR(core_info->debugfs_dir))
|
||||
{
|
||||
dev_err(&client->dev,"failed to create debugfs dir for rk610!\n");
|
||||
}
|
||||
else
|
||||
debugfs_create_file("core", S_IRUSR,core_info->debugfs_dir,core_info,&rk610_reg_fops);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -281,7 +314,6 @@ static struct i2c_driver rk610_control_driver = {
|
||||
|
||||
static int __init rk610_control_init(void)
|
||||
{
|
||||
DBG("[%s] start\n", __FUNCTION__);
|
||||
return i2c_add_driver(&rk610_control_driver);
|
||||
}
|
||||
|
||||
@@ -291,7 +323,6 @@ static void __exit rk610_control_exit(void)
|
||||
}
|
||||
|
||||
subsys_initcall_sync(rk610_control_init);
|
||||
//module_init(rk610_control_init);
|
||||
module_exit(rk610_control_exit);
|
||||
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ static void rk_output_lvds(rk_screen *screen)
|
||||
{
|
||||
LVDSWrReg(m_PDN_CBG(1)|m_PD_PLL(0)|m_PDN(1)|m_OEN(0) \
|
||||
|m_DS(DS_10PF)|m_MSBSEL(DATA_D0_MSB) \
|
||||
|m_OUT_FORMAT(screen->hw_format) \
|
||||
|m_OUT_FORMAT(screen->lvds_format) \
|
||||
|m_LCDC_SEL(screen->lcdc_id));
|
||||
|
||||
printk("%s>>connect to lcdc output interface%d\n",__func__,screen->lcdc_id);
|
||||
@@ -19,7 +19,7 @@ static void rk_output_lvttl(rk_screen *screen)
|
||||
{
|
||||
LVDSWrReg(m_PDN_CBG(0)|m_PD_PLL(1)|m_PDN(0)|m_OEN(1) \
|
||||
|m_DS(DS_10PF)|m_MSBSEL(DATA_D0_MSB) \
|
||||
|m_OUT_FORMAT(screen->hw_format) \
|
||||
|m_OUT_FORMAT(screen->lvds_format) \
|
||||
|m_LCDC_SEL(screen->lcdc_id));
|
||||
printk("%s>>connect to lcdc output interface%d\n",__func__,screen->lcdc_id);
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -39,7 +39,7 @@ static int rk616_lvds_cfg(struct mfd_rk616 *rk616,rk_screen *screen)
|
||||
val = 0;
|
||||
val &= ~(LVDS_CH0TTL_EN | LVDS_CH1TTL_EN | LVDS_PLL_PWR_DN);
|
||||
val = (LVDS_DCLK_INV)|(LVDS_CH1_PWR_EN) |(LVDS_CH0_PWR_EN) | LVDS_HBP_ODD(odd) |
|
||||
(LVDS_CBG_PWR_EN) | (LVDS_CH_SEL) | (LVDS_OUT_FORMAT(screen->hw_format)) |
|
||||
(LVDS_CBG_PWR_EN) | (LVDS_CH_SEL) | (LVDS_OUT_FORMAT(screen->lvds_format)) |
|
||||
(LVDS_CH0TTL_EN << 16) | (LVDS_CH1TTL_EN << 16) |(LVDS_CH1_PWR_EN << 16) |
|
||||
(LVDS_CH0_PWR_EN << 16) | (LVDS_CBG_PWR_EN << 16) | (LVDS_CH_SEL << 16) |
|
||||
(LVDS_OUT_FORMAT_MASK) | (LVDS_DCLK_INV << 16) | (LVDS_PLL_PWR_DN << 16) |
|
||||
@@ -52,7 +52,7 @@ static int rk616_lvds_cfg(struct mfd_rk616 *rk616,rk_screen *screen)
|
||||
{
|
||||
val = 0;
|
||||
val &= ~(LVDS_CH0TTL_EN | LVDS_CH1TTL_EN | LVDS_CH1_PWR_EN | LVDS_PLL_PWR_DN | LVDS_CH_SEL); //use channel 0
|
||||
val |= (LVDS_CH0_PWR_EN) |(LVDS_CBG_PWR_EN) | (LVDS_OUT_FORMAT(screen->hw_format)) |
|
||||
val |= (LVDS_CH0_PWR_EN) |(LVDS_CBG_PWR_EN) | (LVDS_OUT_FORMAT(screen->lvds_format)) |
|
||||
(LVDS_CH0TTL_EN << 16) | (LVDS_CH1TTL_EN << 16) |(LVDS_CH0_PWR_EN << 16) |
|
||||
(LVDS_DCLK_INV ) | (LVDS_CH0TTL_EN << 16) | (LVDS_CH1TTL_EN << 16) |(LVDS_CH0_PWR_EN << 16) |
|
||||
(LVDS_CBG_PWR_EN << 16)|(LVDS_CH_SEL << 16) | (LVDS_PLL_PWR_DN << 16)|
|
||||
@@ -104,7 +104,7 @@ static int rk616_dither_cfg(struct mfd_rk616 *rk616,rk_screen *screen,bool enabl
|
||||
|
||||
|
||||
|
||||
int rk610_lcd_scaler_set_param(rk_screen *screen,bool enable )//enable:0 bypass 1: scale
|
||||
int rk616_scaler_set_param(rk_screen *screen,bool enable )//enable:0 bypass 1: scale
|
||||
{
|
||||
int ret;
|
||||
struct mfd_rk616 *rk616 = g_lvds->rk616;
|
||||
@@ -113,7 +113,7 @@ int rk610_lcd_scaler_set_param(rk_screen *screen,bool enable )//enable:0 bypass
|
||||
printk(KERN_ERR "%s:mfd rk616 is null!\n",__func__);
|
||||
return -1;
|
||||
}
|
||||
g_lvds->screen = screen;
|
||||
|
||||
ret = rk616_display_router_cfg(rk616,screen,enable);
|
||||
|
||||
ret = rk616_dither_cfg(rk616,screen,enable);
|
||||
@@ -122,6 +122,16 @@ int rk610_lcd_scaler_set_param(rk_screen *screen,bool enable )//enable:0 bypass
|
||||
}
|
||||
|
||||
|
||||
static int rk616_lvds_init_cfg(struct mfd_rk616 *rk616,rk_screen *screen)
|
||||
{
|
||||
int ret ;
|
||||
ret = rk616_display_router_cfg(rk616,screen,0);
|
||||
|
||||
ret = rk616_dither_cfg(rk616,screen,0);
|
||||
ret = rk616_lvds_cfg(rk616,screen);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_HAS_EARLYSUSPEND)
|
||||
static void rk616_lvds_early_suspend(struct early_suspend *h)
|
||||
@@ -155,7 +165,7 @@ static int rk616_lvds_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct rk616_lvds *lvds = NULL;
|
||||
struct mfd_rk616 *rk616 = NULL;
|
||||
|
||||
rk_screen *screen = NULL;
|
||||
lvds = kzalloc(sizeof(struct rk616_lvds),GFP_KERNEL);
|
||||
if(!lvds)
|
||||
{
|
||||
@@ -171,8 +181,19 @@ static int rk616_lvds_probe(struct platform_device *pdev)
|
||||
}
|
||||
else
|
||||
g_lvds = lvds;
|
||||
lvds->rk616 = rk616;
|
||||
|
||||
lvds->rk616 = rk616;
|
||||
|
||||
screen = rk_fb_get_prmry_screen();
|
||||
if(!screen)
|
||||
{
|
||||
dev_err(&pdev->dev,"the fb prmry screen is null!\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
lvds->screen = screen;
|
||||
#if defined(CONFIG_ONE_LCDC_DUAL_OUTPUT_INF)
|
||||
screen->sscreen_set = rk616_scaler_set_param;
|
||||
#endif
|
||||
rk616_lvds_init_cfg(rk616,screen);
|
||||
#ifdef CONFIG_HAS_EARLYSUSPEND
|
||||
lvds->early_suspend.suspend = rk616_lvds_early_suspend;
|
||||
lvds->early_suspend.resume = rk616_lvds_late_resume;
|
||||
@@ -213,8 +234,7 @@ static int __init rk616_lvds_init(void)
|
||||
{
|
||||
return platform_driver_register(&rk616_lvds_driver);
|
||||
}
|
||||
subsys_initcall_sync(rk616_lvds_init);
|
||||
|
||||
fs_initcall(rk616_lvds_init);
|
||||
static void __exit rk616_lvds_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&rk616_lvds_driver);
|
||||
|
||||
@@ -141,7 +141,9 @@ struct rk610_ctl_platform_data {
|
||||
};
|
||||
struct rk610_core_info{
|
||||
struct i2c_client *client;
|
||||
struct device *dev;
|
||||
struct rk610_ctl_platform_data *pdata;
|
||||
struct dentry *debugfs_dir;
|
||||
void *lcd_pdata;
|
||||
};
|
||||
|
||||
|
||||
@@ -109,7 +109,7 @@ struct rk29lcd_info {
|
||||
typedef struct rk29fb_screen {
|
||||
/* screen type & hardware connect format & out face */
|
||||
u16 type;
|
||||
u16 hw_format; //lvds data format
|
||||
u16 lvds_format; //lvds data format
|
||||
u16 face;
|
||||
u8 lcdc_id; //which output interface the screeen connect to
|
||||
u8 screen_id; //screen number
|
||||
|
||||
Reference in New Issue
Block a user