#include <linux/clk.h>
#include <linux/uaccess.h>
-//#include <mach/board.h>
-//#include <mach/io.h>
#include <linux/of_gpio.h>
-//#include <mach/iomux.h>
-#include <linux/rk_fb.h>
+#include <linux/rk_fb.h>
#if defined(CONFIG_DEBUG_FS)
#include <linux/fs.h>
#include "rk616_hdmi.h"
#include "rk616_hdmi_hw.h"
-extern void hdmi_register_display_sysfs(struct hdmi *hdmi, struct device *parent);
-extern void hdmi_unregister_display_sysfs(struct hdmi *hdmi);
-
-struct hdmi *hdmi = NULL;
+static struct rk_hdmi_device *hdmi_dev;
#if defined(CONFIG_DEBUG_FS)
static int rk616_hdmi_reg_show(struct seq_file *s, void *v)
{
int i = 0;
u32 val = 0;
- seq_printf(s, "\n>>>rk616_ctl reg");
- for (i = 0; i < 16; i++) {
+
+ seq_puts(s, "\n>>>rk616_ctl reg");
+ for (i = 0; i < 16; i++)
seq_printf(s, " %2x", i);
- }
- seq_printf(s, "\n-----------------------------------------------------------------");
-
- for(i=0; i<= PHY_PRE_DIV_RATIO; i++) {
- hdmi_readl(i, &val);
- if(i%16==0)
- seq_printf(s,"\n>>>rk616_ctl %2x:", i);
- seq_printf(s," %02x",val);
+
+ seq_puts(s,
+ "\n-----------------------------------------------------------------");
+
+ for (i = 0; i <= PHY_PRE_DIV_RATIO; i++) {
+ hdmi_readl(hdmi_dev, i, &val);
+ if (i % 16 == 0)
+ seq_printf(s, "\n>>>rk616_ctl %2x:", i);
+ seq_printf(s, " %02x", val);
}
- seq_printf(s, "\n-----------------------------------------------------------------\n");
-
+ seq_puts(s,
+ "\n-----------------------------------------------------------------\n");
+
return 0;
}
-static ssize_t rk616_hdmi_reg_write (struct file *file, const char __user *buf, size_t count, loff_t *ppos)
-{
+static ssize_t rk616_hdmi_reg_write(struct file *file, const char __user *buf,
+ size_t count, loff_t *ppos)
+{
u32 reg;
u32 val;
char kbuf[25];
+ struct hdmi *hdmi_drv = &hdmi_dev->driver;
+
if (copy_from_user(kbuf, buf, count))
return -EFAULT;
sscanf(kbuf, "%x%x", ®, &val);
- if ((reg < 0) || (reg > 0xed)) {
- dev_info(hdmi->dev, "it is no hdmi reg\n");
- return count;
- }
- dev_info(hdmi->dev, "/**********rk616 reg config******/");
- dev_info(hdmi->dev, "\n reg=%x val=%x\n", reg, val);
- hdmi_writel(reg, val);
+ if ((reg < 0) || (reg > 0xed)) {
+ dev_info(hdmi_drv->dev, "it is no hdmi reg\n");
+ return count;
+ }
+ dev_info(hdmi_drv->dev, "/**********rk616 reg config******/");
+ dev_info(hdmi_drv->dev, "\n reg=%x val=%x\n", reg, val);
+ hdmi_writel(hdmi_dev, reg, val);
return count;
}
static int rk616_hdmi_reg_open(struct inode *inode, struct file *file)
{
- struct mfd_rk616 *rk616 = inode->i_private;
- return single_open(file,rk616_hdmi_reg_show,rk616);
+ struct mfd_rk616 *rk616_drv = inode->i_private;
+
+ return single_open(file, rk616_hdmi_reg_show, rk616_drv);
}
static const struct file_operations rk616_hdmi_reg_fops = {
- .owner = THIS_MODULE,
- .open = rk616_hdmi_reg_open,
- .read = seq_read,
- .write = rk616_hdmi_reg_write,
- .llseek = seq_lseek,
- .release = single_release,
+ .owner = THIS_MODULE,
+ .open = rk616_hdmi_reg_open,
+ .read = seq_read,
+ .write = rk616_hdmi_reg_write,
+ .llseek = seq_lseek,
+ .release = single_release,
};
#endif
+#if defined(CONFIG_ARCH_RK3026)
+static int rk616_hdmi_clk_enable(struct rk_hdmi_device *hdmi_dev)
+{
+ if (!hdmi_dev->clk_on) {
+ clk_prepare_enable(hdmi_dev->hclk);
+ spin_lock(&hdmi_dev->reg_lock);
+ hdmi_dev->clk_on = 1;
+ spin_unlock(&hdmi_dev->reg_lock);
+ }
+
+ return 0;
+}
+
+static int rk616_hdmi_clk_disable(struct rk_hdmi_device *hdmi_dev)
+{
+ if (!hdmi_dev->clk_on) {
+ spin_lock(&hdmi_dev->reg_lock);
+ hdmi_dev->clk_on = 0;
+ spin_unlock(&hdmi_dev->reg_lock);
+ clk_disable_unprepare(hdmi_dev->hclk);
+ }
+
+ return 0;
+}
+
+#endif
+
int rk616_hdmi_register_hdcp_callbacks(void (*hdcp_cb)(void),
- void (*hdcp_irq_cb)(int status),
- int (*hdcp_power_on_cb)(void),
- void (*hdcp_power_off_cb)(void))
+ void (*hdcp_irq_cb)(int status),
+ int (*hdcp_power_on_cb)(void),
+ void (*hdcp_power_off_cb)(void))
{
- if(hdmi == NULL)
+ struct hdmi *hdmi_drv = &hdmi_dev->driver;
+
+ if (hdmi_drv == NULL)
return HDMI_ERROR_FALSE;
- hdmi->hdcp_cb = hdcp_cb;
- hdmi->hdcp_irq_cb = hdcp_irq_cb;
- hdmi->hdcp_power_on_cb = hdcp_power_on_cb;
- hdmi->hdcp_power_off_cb = hdcp_power_off_cb;
+ hdmi_drv->hdcp_cb = hdcp_cb;
+ hdmi_drv->hdcp_irq_cb = hdcp_irq_cb;
+ hdmi_drv->hdcp_power_on_cb = hdcp_power_on_cb;
+ hdmi_drv->hdcp_power_off_cb = hdcp_power_off_cb;
return HDMI_ERROR_SUCESS;
}
-#ifdef CONFIG_HAS_EARLYSUSPEND
-static void hdmi_early_suspend(struct early_suspend *h)
+static void rk616_hdmi_early_suspend(void)
{
- hdmi_dbg(hdmi->dev, "hdmi enter early suspend pwr %d state %d\n", hdmi->pwr_mode, hdmi->state);
+ struct hdmi *hdmi_drv = &hdmi_dev->driver;
- flush_delayed_work(&hdmi->delay_work);
- mutex_lock(&hdmi->enable_mutex);
- hdmi->suspend = 1;
- if(!hdmi->enable) {
- mutex_unlock(&hdmi->enable_mutex);
+ hdmi_dbg(hdmi_drv->dev, "hdmi enter early suspend pwr %d state %d\n",
+ hdmi_drv->pwr_mode, hdmi_drv->state);
+
+ flush_delayed_work(&hdmi_drv->delay_work);
+ mutex_lock(&hdmi_drv->enable_mutex);
+ hdmi_drv->suspend = 1;
+ if (!hdmi_drv->enable) {
+ mutex_unlock(&hdmi_drv->enable_mutex);
return;
}
- if (hdmi->irq)
- disable_irq(hdmi->irq);
+ if (hdmi_drv->irq)
+ disable_irq(hdmi_drv->irq);
- mutex_unlock(&hdmi->enable_mutex);
- hdmi->command = HDMI_CONFIG_ENABLE;
- init_completion(&hdmi->complete);
- hdmi->wait = 1;
- queue_delayed_work(hdmi->workqueue, &hdmi->delay_work, 0);
- wait_for_completion_interruptible_timeout(&hdmi->complete,
- msecs_to_jiffies(5000));
- flush_delayed_work(&hdmi->delay_work);
+ mutex_unlock(&hdmi_drv->enable_mutex);
+ hdmi_drv->command = HDMI_CONFIG_ENABLE;
+ init_completion(&hdmi_drv->complete);
+ hdmi_drv->wait = 1;
+ queue_delayed_work(hdmi_drv->workqueue, &hdmi_drv->delay_work, 0);
+ wait_for_completion_interruptible_timeout(&hdmi_drv->complete,
+ msecs_to_jiffies(5000));
+ flush_delayed_work(&hdmi_drv->delay_work);
- return;
}
-static void hdmi_early_resume(struct early_suspend *h)
+static void rk616_hdmi_early_resume(void)
{
- struct rk616_hdmi *rk616_hdmi;
+ struct hdmi *hdmi_drv = &hdmi_dev->driver;
+ struct mfd_rk616 *rk616_drv = hdmi_dev->rk616_drv;
- rk616_hdmi = container_of(hdmi, struct rk616_hdmi, g_hdmi);
- hdmi_dbg(hdmi->dev, "hdmi exit early resume\n");
+ hdmi_dbg(hdmi_drv->dev, "hdmi exit early resume\n");
- mutex_lock(&hdmi->enable_mutex);
+ mutex_lock(&hdmi_drv->enable_mutex);
- hdmi->suspend = 0;
- rk616_hdmi_initial(hdmi);
- if(hdmi->enable && hdmi->irq) {
- enable_irq(hdmi->irq);
- // hdmi_irq();
- rk616_hdmi_work(hdmi);
+ hdmi_drv->suspend = 0;
+ rk616_hdmi_initial(hdmi_drv);
+ if (hdmi_drv->enable && hdmi_drv->irq) {
+ enable_irq(hdmi_drv->irq);
+ rk616_hdmi_work(hdmi_drv);
}
- if (rk616_hdmi->rk616_drv && !gpio_is_valid(rk616_hdmi->rk616_drv->pdata->hdmi_irq))
- queue_delayed_work(hdmi->workqueue, &rk616_hdmi->rk616_delay_work, 100);
- queue_delayed_work(hdmi->workqueue, &hdmi->delay_work, msecs_to_jiffies(10));
- mutex_unlock(&hdmi->enable_mutex);
- return;
+ if (rk616_drv && !gpio_is_valid(rk616_drv->pdata->hdmi_irq))
+ queue_delayed_work(hdmi_drv->workqueue,
+ &hdmi_dev->rk616_delay_work,
+ msecs_to_jiffies(100));
+
+ queue_delayed_work(hdmi_drv->workqueue, &hdmi_drv->delay_work,
+ msecs_to_jiffies(10));
+ mutex_unlock(&hdmi_drv->enable_mutex);
}
-#endif
-static void rk616_delay_work_func(struct work_struct *work)
+
+static int rk616_hdmi_fb_event_notify(struct notifier_block *self,
+ unsigned long action, void *data)
{
- struct rk616_hdmi *rk616_hdmi;
+ struct fb_event *event = data;
+ int blank_mode = *((int *)event->data);
+
+ if (action == FB_EARLY_EVENT_BLANK) {
+ switch (blank_mode) {
+ case FB_BLANK_UNBLANK:
+ break;
+ default:
+ rk616_hdmi_early_suspend();
+ break;
+ }
+ } else if (action == FB_EVENT_BLANK) {
+ switch (blank_mode) {
+ case FB_BLANK_UNBLANK:
+ rk616_hdmi_early_resume();
+ break;
+ default:
+ break;
+ }
+ }
- rk616_hdmi = container_of(hdmi, struct rk616_hdmi, g_hdmi);
+ return NOTIFY_OK;
+}
- if(hdmi->suspend == 0) {
- if(hdmi->enable == 1) {
- //hdmi_irq();
- rk616_hdmi_work(hdmi);
- }
+static struct notifier_block rk616_hdmi_fb_notifier = {
+ .notifier_call = rk616_hdmi_fb_event_notify,
+};
+
+
+static void rk616_delay_work_func(struct work_struct *work)
+{
+ struct hdmi *hdmi_drv = &hdmi_dev->driver;
+ struct mfd_rk616 *rk616_drv = hdmi_dev->rk616_drv;
+
+ if (hdmi_drv->suspend == 0) {
+ if (hdmi_drv->enable == 1)
+ rk616_hdmi_work(hdmi_drv);
- if (rk616_hdmi->rk616_drv && !gpio_is_valid(rk616_hdmi->rk616_drv->pdata->hdmi_irq)) {
- queue_delayed_work(hdmi->workqueue, &rk616_hdmi->rk616_delay_work, 100);
- }
+ if (rk616_drv && !gpio_is_valid(rk616_drv->pdata->hdmi_irq))
+ queue_delayed_work(hdmi_drv->workqueue,
+ &hdmi_dev->rk616_delay_work,
+ msecs_to_jiffies(100));
}
}
static void __maybe_unused rk616_irq_work_func(struct work_struct *work)
{
- if((hdmi->suspend == 0) && (hdmi->enable == 1)) {
- rk616_hdmi_work(hdmi);
- }
- dev_info(hdmi->dev, "func: %s, enable_irq\n", __func__);
- enable_irq(hdmi->irq);
+ struct hdmi *hdmi_drv = &hdmi_dev->driver;
+
+ if ((hdmi_drv->suspend == 0) && (hdmi_drv->enable == 1))
+ rk616_hdmi_work(hdmi_drv);
+
+ dev_info(hdmi_drv->dev, "func: %s, enable_irq\n", __func__);
+ enable_irq(hdmi_drv->irq);
}
static irqreturn_t rk616_hdmi_irq(int irq, void *dev_id)
{
- struct work_struct *rk616_irq_work_struct;
- struct rk616_hdmi *rk616_hdmi;
-
- rk616_hdmi = container_of(hdmi, struct rk616_hdmi, g_hdmi);
- if(rk616_hdmi->rk616_drv) {
- rk616_irq_work_struct = dev_id;
- disable_irq_nosync(hdmi->irq);
- queue_work(hdmi->workqueue, rk616_irq_work_struct);
- } else {
- /* 3028a hdmi */
- if((hdmi->suspend == 0) && (hdmi->enable == 1)) {
- printk(KERN_INFO "line = %d, rk616_hdmi_irq irq triggered.\n", __LINE__);
- rk616_hdmi_work(hdmi);
- }
- }
- return IRQ_HANDLED;
+ struct work_struct *rk616_irq_work_struct;
+ struct hdmi *hdmi_drv = &hdmi_dev->driver;
+ struct mfd_rk616 *rk616_drv = hdmi_dev->rk616_drv;
+
+ if (rk616_drv) {
+ rk616_irq_work_struct = dev_id;
+ disable_irq_nosync(hdmi_drv->irq);
+ queue_work(hdmi_drv->workqueue, rk616_irq_work_struct);
+ } else {
+ /* 3028a hdmi */
+ if ((hdmi_drv->suspend == 0) && (hdmi_drv->enable == 1)) {
+ hdmi_dbg(hdmi_drv->dev,
+ "line = %d, rk616_hdmi_irq irq triggered.\n",
+ __LINE__);
+ rk616_hdmi_work(hdmi_drv);
+ }
+ }
+ return IRQ_HANDLED;
+}
+
+static int rk616_hdmi_drv_init(struct hdmi *hdmi_drv)
+{
+ int ret = 0;
+ int lcdc_id = 0;
+ struct rk_screen screen;
+
+ rk_fb_get_prmry_screen(&screen);
+
+ /* hdmi is extend as default,TODO modify if hdmi is primary */
+ lcdc_id = (screen.lcdc_id == 0) ? 1 : 0;
+ /* lcdc source select */
+ /* wait to modify!!
+#if defined(CONFIG_ARCH_RK3026)
+ grf_writel(HDMI_SEL_LCDC(lcdc_id), RK3036_GRF_SOC_CON6);
+#endif
+ */
+ if (lcdc_id == 0)
+ hdmi_drv->lcdc = rk_get_lcdc_drv("lcdc0");
+ else
+ hdmi_drv->lcdc = rk_get_lcdc_drv("lcdc1");
+ if (IS_ERR(hdmi_drv->lcdc)) {
+ dev_err(hdmi_drv->dev,
+ "can not connect to video source lcdc\n");
+ ret = -ENXIO;
+ return ret;
+ }
+
+ hdmi_drv->xscale = 100;
+ hdmi_drv->yscale = 100;
+
+ spin_lock_init(&hdmi_drv->irq_lock);
+ mutex_init(&hdmi_drv->enable_mutex);
+ hdmi_sys_init(hdmi_drv);
+ ret = rk616_hdmi_initial(hdmi_drv);
+
+ return ret;
}
static int rk616_hdmi_probe(struct platform_device *pdev)
{
int ret;
- struct rk616_hdmi *rk616_hdmi;
- struct resource __maybe_unused *mem;
- struct resource __maybe_unused *res;
- struct device_node *np = pdev->dev.of_node;
-
- rk616_hdmi = devm_kzalloc(&pdev->dev, sizeof(*rk616_hdmi), GFP_KERNEL);
- if(!rk616_hdmi)
- {
+ struct rk_hdmi_device *hdmi_dev;
+ struct hdmi *hdmi_drv;
+ struct resource __maybe_unused *mem;
+ struct resource __maybe_unused *res;
+
+ hdmi_dev = devm_kzalloc(&pdev->dev, sizeof(struct rk_hdmi_device),
+ GFP_KERNEL);
+ if (!hdmi_dev) {
dev_err(&pdev->dev, ">>rk616_hdmi kmalloc fail!");
return -ENOMEM;
}
- hdmi = &rk616_hdmi->g_hdmi;
+
+ hdmi_drv = &hdmi_dev->driver;
+ hdmi_drv->dev = &pdev->dev;
+ platform_set_drvdata(pdev, hdmi_dev);
+ spin_lock_init(&hdmi_dev->reg_lock);
#ifdef CONFIG_ARCH_RK3026
- rk616_hdmi->rk616_drv = NULL;
+ hdmi_dev->rk616_drv = NULL;
#else
- rk616_hdmi->rk616_drv = dev_get_drvdata(pdev->dev.parent);
- if(!(rk616_hdmi->rk616_drv))
- {
- dev_err(&pdev->dev,"null mfd device rk616!\n");
- return -ENODEV;
+ hdmi_dev->rk616_drv = dev_get_drvdata(pdev->dev.parent);
+ if (!(hdmi_dev->rk616_drv)) {
+ dev_err(hdmi_drv->dev, "null mfd device rk616!\n");
+ goto err0;
}
-
#endif
- hdmi->dev = &pdev->dev;
- platform_set_drvdata(pdev, hdmi);
-
- if(HDMI_SOURCE_DEFAULT == HDMI_SOURCE_LCDC0)
- hdmi->lcdc = rk_get_lcdc_drv("lcdc0");
- else
- hdmi->lcdc = rk_get_lcdc_drv("lcdc1");
- if(hdmi->lcdc == NULL)
- {
- dev_err(hdmi->dev, "can not connect to video source lcdc\n");
- ret = -ENXIO;
+ if (rk616_hdmi_drv_init(hdmi_drv))
goto err0;
- }
- hdmi->xscale = 100;
- hdmi->yscale = 100;
-
-
- hdmi_sys_init(hdmi);
-
- hdmi->workqueue = create_singlethread_workqueue("hdmi");
- INIT_DELAYED_WORK(&(hdmi->delay_work), hdmi_work);
-
-#ifdef CONFIG_HAS_EARLYSUSPEND
- hdmi->early_suspend.suspend = hdmi_early_suspend;
- hdmi->early_suspend.resume = hdmi_early_resume;
- hdmi->early_suspend.level = EARLY_SUSPEND_LEVEL_DISABLE_FB - 10;
- register_early_suspend(&hdmi->early_suspend);
-#endif
#ifdef CONFIG_SWITCH
- hdmi->switch_hdmi.name="hdmi";
- switch_dev_register(&(hdmi->switch_hdmi));
+ hdmi_drv->switch_hdmi.name = "hdmi";
+ switch_dev_register(&(hdmi_drv->switch_hdmi));
#endif
+ hdmi_register_display_sysfs(hdmi_drv, NULL);
+ fb_register_client(&rk616_hdmi_fb_notifier);
- spin_lock_init(&hdmi->irq_lock);
- mutex_init(&hdmi->enable_mutex);
+ hdmi_drv->workqueue = create_singlethread_workqueue("hdmi");
+ INIT_DELAYED_WORK(&(hdmi_drv->delay_work), hdmi_work);
+ INIT_DELAYED_WORK(&hdmi_dev->rk616_delay_work, rk616_delay_work_func);
- INIT_DELAYED_WORK(&rk616_hdmi->rk616_delay_work, rk616_delay_work_func);
+#ifdef CONFIG_ARCH_RK3026
+ /* enable clk */
+ hdmi_dev->hclk = devm_clk_get(hdmi_drv->dev, "pclk_hdmi");
+ if (IS_ERR(hdmi_dev->hclk)) {
+ dev_err(hdmi_drv->dev, "Unable to get hdmi hclk\n");
+ ret = -ENXIO;
+ goto err1;
+ }
+ rk616_hdmi_clk_enable(); /* enable clk may move to irq func */
+
+ /* request and remap iomem */
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ dev_err(hdmi_dev->dev, "Unable to get register resource\n");
+ ret = -ENXIO;
+ goto err2;
+ }
+ hdmi_dev->regbase_phy = res->start;
+ hdmi_dev->regsize_phy = resource_size(res);
+ hdmi_dev->regbase = devm_ioremap_resource(hdmi_drv->dev, res);
+ if (IS_ERR(hdmi_dev->regbase)) {
+ ret = PTR_ERR(hdmi_dev->regbase);
+ dev_err(hdmi_drv->dev, "cannot ioremap registers,err=%d\n",
+ ret);
+ goto err2;
+ }
/* get the IRQ */
- // if(rk616->pdata->hdmi_irq != INVALID_GPIO)
-
-#ifdef CONFIG_ARCH_RK3026
- hdmi->hclk = clk_get(NULL,"pclk_hdmi");
- if(IS_ERR(hdmi->hclk)) {
- dev_err(hdmi->dev, "Unable to get hdmi hclk\n");
- ret = -ENXIO;
- goto err0;
- }
- clk_enable(hdmi->hclk);
-
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!res) {
- dev_err(hdmi->dev, "Unable to get register resource\n");
- ret = -ENXIO;
- goto err0;
- }
- hdmi->regbase_phy = res->start;
- hdmi->regsize_phy = (res->end - res->start) + 1;
- mem = request_mem_region(res->start, (res->end - res->start) + 1, pdev->name);
- if (!mem) {
- dev_err(hdmi->dev, "failed to request mem region for hdmi\n");
- ret = -ENOENT;
- goto err0;
- }
-
- dev_info(hdmi->dev, "res->start = 0x%x\n,res->end = 0x%x\n", res->start, res->end);
- hdmi->regbase = (int)ioremap(res->start, (res->end - res->start) + 1);
- if (!hdmi->regbase) {
- dev_err(hdmi->dev, "cannot ioremap registers\n");
- ret = -ENXIO;
- goto err1;
- }
-
- // rk30_mux_api_set(GPIO0A7_I2C3_SDA_HDMI_DDCSDA_NAME, GPIO0A_HDMI_DDCSDA);
- // rk30_mux_api_set(GPIO0A6_I2C3_SCL_HDMI_DDCSCL_NAME, GPIO0A_HDMI_DDCSCL);
- // rk30_mux_api_set(GPIO0B7_HDMI_HOTPLUGIN_NAME, GPIO0B_HDMI_HOTPLUGIN);
- iomux_set(HDMI_DDCSDA);
- iomux_set(HDMI_DDCSCL);
- iomux_set(HDMI_HOTPLUGIN);
-
- ret = rk616_hdmi_initial(hdmi);
- /* get the IRQ */
- hdmi->irq = platform_get_irq(pdev, 0);
- if(hdmi->irq <= 0) {
- dev_err(hdmi->dev, "failed to get hdmi irq resource (%d).\n", hdmi->irq);
- hdmi->irq = 0;
- } else {
- /* request the IRQ */
- ret = request_irq(hdmi->irq, rk616_hdmi_irq, 0, dev_name(&pdev->dev), hdmi);
- if (ret) {
- dev_err(hdmi->dev, "hdmi request_irq failed (%d).\n", ret);
- goto err1;
- }
- }
+ hdmi_drv->irq = platform_get_irq(pdev, 0);
+ if (hdmi_drv->irq <= 0) {
+ dev_err(hdmi->dev, "failed to get hdmi irq resource (%d).\n",
+ hdmi->irq);
+ hdmi_drv->irq = 0;
+ } else {
+ /* request the IRQ */
+ ret = devm_request_irq(hdmi_drv->dev, hdmi_drv->irq,
+ rk616_hdmi_irq, 0,
+ dev_name(hdmi_drv->dev), hdmi_drv);
+ if (ret) {
+ dev_err(hdmi_drv->dev, "hdmi request_irq failed (%d)\n",
+ ret);
+ goto err2;
+ }
+ }
#else
- ret = rk616_hdmi_initial(hdmi);
- if(gpio_is_valid(rk616_hdmi->rk616_drv->pdata->hdmi_irq)) {
- INIT_WORK(&rk616_hdmi->rk616_irq_work_struct, rk616_irq_work_func);
- ret = gpio_request(rk616_hdmi->rk616_drv->pdata->hdmi_irq,"rk616_hdmi_irq");
- if(ret < 0) {
- dev_err(hdmi->dev,"request gpio for rk616 hdmi irq fail\n");
- }
- gpio_direction_input(rk616_hdmi->rk616_drv->pdata->hdmi_irq);
- hdmi->irq = gpio_to_irq(rk616_hdmi->rk616_drv->pdata->hdmi_irq);
- if(hdmi->irq <= 0) {
- dev_err(hdmi->dev, "failed to get hdmi irq resource (%d).\n", hdmi->irq);
- ret = -ENXIO;
- goto err1;
- }
-
- /* request the IRQ */
- ret = request_irq(hdmi->irq, rk616_hdmi_irq, IRQF_TRIGGER_LOW, dev_name(&pdev->dev), &rk616_hdmi->rk616_irq_work_struct);
- if (ret) {
- dev_err(hdmi->dev, "hdmi request_irq failed (%d).\n", ret);
- goto err1;
- }
- } else {
- /* use roll polling method */
- hdmi->irq = 0;
- }
+ if (gpio_is_valid(hdmi_dev->rk616_drv->pdata->hdmi_irq)) {
+ INIT_WORK(&hdmi_dev->rk616_irq_work_struct,
+ rk616_irq_work_func);
+ ret = gpio_request(hdmi_dev->rk616_drv->pdata->hdmi_irq,
+ "rk616_hdmi_irq");
+ if (ret < 0) {
+ dev_err(hdmi_drv->dev,
+ "request gpio for rk616 hdmi irq fail\n");
+ }
+ gpio_direction_input(hdmi_dev->rk616_drv->pdata->hdmi_irq);
+ hdmi_drv->irq =
+ gpio_to_irq(hdmi_dev->rk616_drv->pdata->hdmi_irq);
+ if (hdmi_drv->irq <= 0) {
+ dev_err(hdmi_drv->dev,
+ "failed to get hdmi irq resource (%d).\n",
+ hdmi_drv->irq);
+ ret = -ENXIO;
+ goto err1;
+ }
+
+ /* request the IRQ */
+ ret = devm_request_irq(hdmi_drv->dev, hdmi_drv->irq,
+ rk616_hdmi_irq, IRQF_TRIGGER_LOW,
+ dev_name(&pdev->dev),
+ &hdmi_dev->rk616_irq_work_struct);
+ if (ret) {
+ dev_err(hdmi_drv->dev, "hdmi request_irq failed (%d)\n",
+ ret);
+ goto err1;
+ }
+ } else {
+ /* use roll polling method */
+ hdmi_drv->irq = 0;
+ }
#endif
- hdmi_register_display_sysfs(hdmi, NULL);
#if defined(CONFIG_DEBUG_FS)
- if(rk616_hdmi->rk616_drv && rk616_hdmi->rk616_drv->debugfs_dir) {
- debugfs_create_file("hdmi", S_IRUSR, rk616_hdmi->rk616_drv->debugfs_dir, rk616_hdmi->rk616_drv, &rk616_hdmi_reg_fops);
+ if (hdmi_dev->rk616_drv && hdmi_dev->rk616_drv->debugfs_dir) {
+ debugfs_create_file("hdmi", S_IRUSR,
+ hdmi_dev->rk616_drv->debugfs_dir,
+ hdmi_dev->rk616_drv, &rk616_hdmi_reg_fops);
} else {
- rk616_hdmi->debugfs_dir = debugfs_create_dir("rk616", NULL);
- if (IS_ERR(rk616_hdmi->debugfs_dir)) {
- dev_err(hdmi->dev,"failed to create debugfs dir for rk616!\n");
- } else {
- debugfs_create_file("hdmi", S_IRUSR, rk616_hdmi->debugfs_dir, rk616_hdmi, &rk616_hdmi_reg_fops);
- }
- }
+ hdmi_dev->debugfs_dir = debugfs_create_dir("rk616", NULL);
+ if (IS_ERR(hdmi_dev->debugfs_dir)) {
+ dev_err(hdmi_drv->dev,
+ "failed to create debugfs dir for rk616!\n");
+ } else {
+ debugfs_create_file("hdmi", S_IRUSR,
+ hdmi_dev->debugfs_dir, hdmi_drv,
+ &rk616_hdmi_reg_fops);
+ }
+ }
#endif
- // rk616_delay_work_func(NULL);
- queue_delayed_work(hdmi->workqueue, &rk616_hdmi->rk616_delay_work, msecs_to_jiffies(0));
- dev_info(hdmi->dev, "rk616 hdmi probe success.\n");
+
+ queue_delayed_work(hdmi_drv->workqueue, &hdmi_dev->rk616_delay_work,
+ msecs_to_jiffies(0));
+ dev_info(hdmi_drv->dev, "rk616 hdmi probe success.\n");
return 0;
+
+#if defined(CONFIG_ARCH_RK3026)
+err2:
+ rk616_hdmi_clk_disable(hdmi_dev);
+#endif
+
err1:
+ fb_unregister_client(&rk616_hdmi_fb_notifier);
+ hdmi_unregister_display_sysfs(hdmi_drv);
#ifdef CONFIG_SWITCH
- switch_dev_unregister(&(hdmi->switch_hdmi));
-#endif
- hdmi_unregister_display_sysfs(hdmi);
-#ifdef CONFIG_HAS_EARLYSUSPEND
- unregister_early_suspend(&hdmi->early_suspend);
+ switch_dev_unregister(&(hdmi_drv->switch_hdmi));
#endif
+
err0:
- hdmi_dbg(hdmi->dev, "rk616 hdmi probe error.\n");
- kfree(hdmi);
- hdmi = NULL;
+ hdmi_dbg(hdmi_drv->dev, "rk616 hdmi probe error.\n");
+ kfree(hdmi_dev);
+ hdmi_dev = NULL;
return ret;
}
static int rk616_hdmi_remove(struct platform_device *pdev)
{
- if(hdmi) {
- mutex_lock(&hdmi->enable_mutex);
- if(!hdmi->suspend && hdmi->enable && hdmi->irq)
- disable_irq(hdmi->irq);
- mutex_unlock(&hdmi->enable_mutex);
- if (hdmi->irq) {
- free_irq(hdmi->irq, NULL);
- }
- flush_workqueue(hdmi->workqueue);
- destroy_workqueue(hdmi->workqueue);
+ struct rk_hdmi_device *hdmi_dev = platform_get_drvdata(pdev);
+ struct hdmi *hdmi_drv = NULL;
+
+ if (hdmi_dev) {
+ hdmi_drv = &hdmi_dev->driver;
+ mutex_lock(&hdmi_drv->enable_mutex);
+ if (!hdmi_drv->suspend && hdmi_drv->enable && hdmi_drv->irq)
+ disable_irq(hdmi_drv->irq);
+ mutex_unlock(&hdmi_drv->enable_mutex);
+ if (hdmi_drv->irq)
+ free_irq(hdmi_drv->irq, NULL);
+
+ flush_workqueue(hdmi_drv->workqueue);
+ destroy_workqueue(hdmi_drv->workqueue);
#ifdef CONFIG_SWITCH
- switch_dev_unregister(&(hdmi->switch_hdmi));
+ switch_dev_unregister(&(hdmi_drv->switch_hdmi));
#endif
- hdmi_unregister_display_sysfs(hdmi);
+ hdmi_unregister_display_sysfs(hdmi_drv);
#ifdef CONFIG_HAS_EARLYSUSPEND
- unregister_early_suspend(&hdmi->early_suspend);
+ unregister_early_suspend(&hdmi_drv->early_suspend);
#endif
- fb_destroy_modelist(&hdmi->edid.modelist);
- if(hdmi->edid.audio)
- kfree(hdmi->edid.audio);
- if(hdmi->edid.specs)
- {
- if(hdmi->edid.specs->modedb)
- kfree(hdmi->edid.specs->modedb);
- kfree(hdmi->edid.specs);
+ fb_destroy_modelist(&hdmi_drv->edid.modelist);
+ if (hdmi_drv->edid.audio)
+ kfree(hdmi_drv->edid.audio);
+ if (hdmi_drv->edid.specs) {
+ if (hdmi_drv->edid.specs->modedb)
+ kfree(hdmi_drv->edid.specs->modedb);
+ kfree(hdmi_drv->edid.specs);
}
- kfree(hdmi);
- hdmi = NULL;
+
+ hdmi_dbg(hdmi_drv->dev, "rk616 hdmi removed.\n");
+ kfree(hdmi_dev);
+ hdmi_dev = NULL;
}
- hdmi_dbg(hdmi->dev, "rk616 hdmi removed.\n");
+
return 0;
}
static void rk616_hdmi_shutdown(struct platform_device *pdev)
{
- if(hdmi) {
+ struct hdmi *hdmi_drv;
+
+ if (hdmi_dev) {
+ hdmi_drv = &hdmi_dev->driver;
#ifdef CONFIG_HAS_EARLYSUSPEND
- unregister_early_suspend(&hdmi->early_suspend);
-#endif
- flush_delayed_work(&hdmi->delay_work);
- mutex_lock(&hdmi->enable_mutex);
- hdmi->suspend = 1;
- if(!hdmi->enable) {
- mutex_unlock(&hdmi->enable_mutex);
- return;
- }
- if (hdmi->irq)
- disable_irq(hdmi->irq);
- mutex_unlock(&hdmi->enable_mutex);
- }
- hdmi_dbg(hdmi->dev, "rk616 hdmi shut down.\n");
+ unregister_early_suspend(&hdmi_drv->early_suspend);
+#endif
+ flush_delayed_work(&hdmi_drv->delay_work);
+ mutex_lock(&hdmi_drv->enable_mutex);
+ hdmi_drv->suspend = 1;
+ if (!hdmi_drv->enable) {
+ mutex_unlock(&hdmi_drv->enable_mutex);
+ return;
+ }
+ if (hdmi_drv->irq)
+ disable_irq(hdmi_drv->irq);
+ mutex_unlock(&hdmi_drv->enable_mutex);
+ }
+ hdmi_dbg(hdmi_drv->dev, "rk616 hdmi shut down.\n");
}
#if defined(CONFIG_OF)
#endif
static struct platform_driver rk616_hdmi_driver = {
- .probe = rk616_hdmi_probe,
- .remove = rk616_hdmi_remove,
- .driver = {
+ .probe = rk616_hdmi_probe,
+ .remove = rk616_hdmi_remove,
+ .driver = {
#ifdef CONFIG_ARCH_RK3026
- .name = "rk3026-hdmi",
+ .name = "rk3026-hdmi",
#else
- .name = "rk616-hdmi",
+ .name = "rk616-hdmi",
#endif
- .owner = THIS_MODULE,
- .of_match_table = of_match_ptr(rk616_hdmi_of_match),
- },
- .shutdown = rk616_hdmi_shutdown,
+ .owner = THIS_MODULE,
+ .of_match_table = of_match_ptr(rk616_hdmi_of_match),
+ },
+ .shutdown = rk616_hdmi_shutdown,
};
static int __init rk616_hdmi_init(void)
platform_driver_unregister(&rk616_hdmi_driver);
}
-
-//fs_initcall(rk616_hdmi_init);
late_initcall(rk616_hdmi_init);
module_exit(rk616_hdmi_exit);
#include "../../rk_hdmi.h"
#include <linux/mfd/rk616.h>
-#if defined(CONFIG_HDMI_SOURCE_LCDC1)
-#define HDMI_SOURCE_DEFAULT HDMI_SOURCE_LCDC1
-#else
-#define HDMI_SOURCE_DEFAULT HDMI_SOURCE_LCDC0
-#endif
-enum{
+enum {
INPUT_IIS,
INPUT_SPDIF
};
extern void rk616_hdmi_control_output(struct hdmi *hdmi, int enable);
extern int rk616_hdmi_register_hdcp_callbacks(void (*hdcp_cb)(void),
- void (*hdcp_irq_cb)(int status),
- int (*hdcp_power_on_cb)(void),
- void (*hdcp_power_off_cb)(void));
+ void (*hdcp_irq_cb)(int status),
+ int (*hdcp_power_on_cb)(void),
+ void (*hdcp_power_off_cb)(void));
-struct rk616_hdmi {
- struct hdmi g_hdmi;
- //struct early_suspend early_suspend; //TODO Daisen
- struct delayed_work rk616_delay_work;
- struct work_struct rk616_irq_work_struct;
- struct mfd_rk616 *rk616_drv;
- struct dentry *debugfs_dir;
+struct rk_hdmi_device {
+ int clk_on;
+ spinlock_t reg_lock;
+ struct hdmi driver;
+ void __iomem *regbase;
+ int regbase_phy;
+ int regsize_phy;
+ struct clk *pd;
+ struct clk *hclk; /* HDMI AHP clk */
+ struct delayed_work rk616_delay_work;
+ struct work_struct rk616_irq_work_struct;
+ struct mfd_rk616 *rk616_drv;
+ struct dentry *debugfs_dir;
};
-#endif /* __RK30_HDMI_H__ */
+#endif /* __RK616_HDMI_H__ */
#include <linux/delay.h>
-#include <asm/io.h>
-//#include <mach/io.h>
+#include <linux/io.h>
#include <linux/interrupt.h>
#include <linux/of_irq.h>
#include "rk616_hdmi.h"
#include "rk616_hdmi_hw.h"
-//#include <mach/gpio.h>
-
-// static char edid_result = 0;
#ifndef CONFIG_ARCH_RK3026
-static int rk616_set_polarity(struct mfd_rk616 * rk616, int vic)
+static int rk616_set_polarity(struct mfd_rk616 *rk616_drv, int vic)
{
- u32 val;
- int ret;
- u32 hdmi_polarity_mask = (3<<14);
-
- switch(vic)
- {
-
- case HDMI_1920x1080p_60Hz:
- case HDMI_1920x1080p_50Hz:
- case HDMI_1920x1080i_60Hz:
- case HDMI_1920x1080i_50Hz:
- case HDMI_1280x720p_60Hz:
- case HDMI_1280x720p_50Hz:
- val = 0xc000;
- ret = rk616->write_dev_bits(rk616, CRU_CFGMISC_CON, hdmi_polarity_mask, &val);
- break;
-
- case HDMI_720x576p_50Hz_4_3:
- case HDMI_720x576p_50Hz_16_9:
- case HDMI_720x480p_60Hz_4_3:
- case HDMI_720x480p_60Hz_16_9:
- val = 0x0;
- ret = rk616->write_dev_bits(rk616, CRU_CFGMISC_CON, hdmi_polarity_mask, &val);
- break;
- default:
- val = 0x0;
- ret = rk616->write_dev_bits(rk616, CRU_CFGMISC_CON, hdmi_polarity_mask, &val);
- break;
- }
- return ret;
+ u32 val;
+ int ret;
+ u32 hdmi_polarity_mask = (3 << 14);
+
+ switch (vic) {
+
+ case HDMI_1920x1080p_60Hz:
+ case HDMI_1920x1080p_50Hz:
+ case HDMI_1920x1080i_60Hz:
+ case HDMI_1920x1080i_50Hz:
+ case HDMI_1280x720p_60Hz:
+ case HDMI_1280x720p_50Hz:
+ val = 0xc000;
+ ret = rk616_drv->write_dev_bits(rk616_drv, CRU_CFGMISC_CON,
+ hdmi_polarity_mask, &val);
+ break;
+
+ case HDMI_720x576p_50Hz_4_3:
+ case HDMI_720x576p_50Hz_16_9:
+ case HDMI_720x480p_60Hz_4_3:
+ case HDMI_720x480p_60Hz_16_9:
+ val = 0x0;
+ ret = rk616_drv->write_dev_bits(rk616_drv, CRU_CFGMISC_CON,
+ hdmi_polarity_mask, &val);
+ break;
+ default:
+ val = 0x0;
+ ret = rk616_drv->write_dev_bits(rk616_drv, CRU_CFGMISC_CON,
+ hdmi_polarity_mask, &val);
+ break;
+ }
+ return ret;
}
-static int rk616_hdmi_set_vif(struct hdmi *hdmi, struct rk_screen *screen, bool connect)
+static int rk616_hdmi_set_vif(struct hdmi *hdmi_drv, struct rk_screen *screen,
+ bool connect)
{
- struct rk616_hdmi *rk616_hdmi;
- rk616_hdmi = container_of(hdmi, struct rk616_hdmi, g_hdmi);
+ struct rk_hdmi_device *hdmi_dev = container_of(hdmi_drv,
+ struct rk_hdmi_device,
+ driver);
+ struct mfd_rk616 *rk616_drv = hdmi_dev->rk616_drv;
- if (connect)
- rk616_set_polarity(rk616_hdmi->rk616_drv, hdmi->vic);
+ if (connect)
+ rk616_set_polarity(rk616_drv, hdmi_drv->vic);
- rk616_set_vif(rk616_hdmi->rk616_drv,screen,connect);
+ rk616_set_vif(rk616_drv, screen, connect);
return 0;
}
-static int rk616_hdmi_init_pol_set(struct mfd_rk616 * rk616,int pol)
+static int rk616_hdmi_init_pol_set(struct mfd_rk616 *rk616_drv, int pol)
{
u32 val;
int ret;
- int int_pol_mask = (1 << 5);
+ int int_pol_mask = (1 << 5);
- if (pol)
- val = 0x0;
- else
- val = 0x20;
- ret = rk616->write_dev_bits(rk616, CRU_CFGMISC_CON, int_pol_mask, &val);
+ if (pol)
+ val = 0x0;
+ else
+ val = 0x20;
+ ret = rk616_drv->write_dev_bits(rk616_drv, CRU_CFGMISC_CON,
+ int_pol_mask, &val);
return 0;
}
msleep(1);
}
-
-static void rk616_hdmi_av_mute(bool enable)
+static void rk616_hdmi_av_mute(struct hdmi *hdmi_drv, bool enable)
{
- hdmi_writel(AV_MUTE, v_AUDIO_MUTE(enable) | v_VIDEO_MUTE(enable));
-}
+ struct rk_hdmi_device *hdmi_dev = container_of(hdmi_drv,
+ struct rk_hdmi_device,
+ driver);
-static void rk616_hdmi_sys_power_up(void)
-{
- hdmi_msk_reg(SYS_CTRL,m_POWER, v_PWR_ON);
+ hdmi_writel(hdmi_dev, AV_MUTE,
+ v_AUDIO_MUTE(enable) | v_VIDEO_MUTE(enable));
}
-static void rk616_hdmi_sys_power_down(void)
+
+static void rk616_hdmi_sys_power(struct hdmi *hdmi_drv, bool enable)
{
- hdmi_msk_reg(SYS_CTRL,m_POWER, v_PWR_OFF);
-}
+ struct rk_hdmi_device *hdmi_dev = container_of(hdmi_drv,
+ struct rk_hdmi_device,
+ driver);
+ if (enable)
+ hdmi_msk_reg(hdmi_dev, SYS_CTRL, m_POWER, v_PWR_ON);
+ else
+ hdmi_msk_reg(hdmi_dev, SYS_CTRL, m_POWER, v_PWR_OFF);
+}
-static void rk616_hdmi_set_pwr_mode(struct hdmi *hdmi, int mode)
+static void rk616_hdmi_set_pwr_mode(struct hdmi *hdmi_drv, int mode)
{
- if(hdmi->pwr_mode == mode)
- return;
- hdmi_dbg(hdmi->dev,"%s change pwr_mode %d --> %d\n",__FUNCTION__,hdmi->pwr_mode,mode);
- switch(mode){
- case NORMAL:
- hdmi_dbg(hdmi->dev,"%s change pwr_mode NORMALpwr_mode = %d, mode = %d\n",__FUNCTION__,hdmi->pwr_mode,mode);
- rk616_hdmi_sys_power_down();
- if (!(hdmi->set_vif) && (hdmi->vic == HDMI_1920x1080p_60Hz || hdmi->vic == HDMI_1920x1080p_50Hz)) {
- /* 3026 and 1080p */
- hdmi_writel(PHY_DRIVER,0xcc);
- hdmi_writel(PHY_PRE_EMPHASIS,0x4f);
- } else {
- hdmi_writel(PHY_DRIVER,0xaa);
- hdmi_writel(PHY_PRE_EMPHASIS,0x0f);
- }
- hdmi_writel(PHY_SYS_CTL,0x2d);
- hdmi_writel(PHY_SYS_CTL,0x2c);
- hdmi_writel(PHY_SYS_CTL,0x28);
- hdmi_writel(PHY_SYS_CTL,0x20);
- hdmi_writel(PHY_CHG_PWR,0x0f);
- hdmi_writel(0xce, 0x00);
- hdmi_writel(0xce, 0x01);
- rk616_hdmi_av_mute(1);
- rk616_hdmi_sys_power_up();
+ struct rk_hdmi_device *hdmi_dev = container_of(hdmi_drv,
+ struct rk_hdmi_device,
+ driver);
+
+ if (hdmi_drv->pwr_mode == mode)
+ return;
+
+ hdmi_dbg(hdmi_drv->dev, "%s change pwr_mode %d --> %d\n", __func__,
+ hdmi_drv->pwr_mode, mode);
+
+ switch (mode) {
+ case NORMAL:
+ hdmi_dbg(hdmi_drv->dev,
+ "%s change pwr_mode NORMAL pwr_mode = %d, mode = %d\n",
+ __func__, hdmi->pwr_mode, mode);
+ rk616_hdmi_sys_power(hdmi_drv, false);
+ if (!(hdmi_drv->set_vif)
+ && (hdmi_drv->vic == HDMI_1920x1080p_60Hz
+ || hdmi_drv->vic == HDMI_1920x1080p_50Hz)) {
+ /* 3026 and 1080p */
+ hdmi_writel(hdmi_dev, PHY_DRIVER, 0xcc);
+ hdmi_writel(hdmi_dev, PHY_PRE_EMPHASIS, 0x4f);
+ } else {
+ hdmi_writel(hdmi_dev, PHY_DRIVER, 0x99);
+ hdmi_writel(hdmi_dev, PHY_PRE_EMPHASIS, 0x0f);
+ }
+
+ hdmi_writel(hdmi_dev, PHY_SYS_CTL, 0x2d);
+ hdmi_writel(hdmi_dev, PHY_SYS_CTL, 0x2c);
+ hdmi_writel(hdmi_dev, PHY_SYS_CTL, 0x28);
+ hdmi_writel(hdmi_dev, PHY_SYS_CTL, 0x20);
+ hdmi_writel(hdmi_dev, PHY_CHG_PWR, 0x0f);
+ hdmi_writel(hdmi_dev, 0xce, 0x00);
+ hdmi_writel(hdmi_dev, 0xce, 0x01);
+ rk616_hdmi_av_mute(hdmi_drv, 1);
+ rk616_hdmi_sys_power(hdmi_drv, true);
break;
case LOWER_PWR:
- hdmi_dbg(hdmi->dev,"%s change pwr_mode LOWER_PWR pwr_mode = %d, mode = %d\n",__FUNCTION__,hdmi->pwr_mode,mode);
- rk616_hdmi_av_mute(0);
- rk616_hdmi_sys_power_down();
- hdmi_writel(PHY_DRIVER,0x00);
- hdmi_writel(PHY_PRE_EMPHASIS,0x00);
- hdmi_writel(PHY_CHG_PWR,0x00);
- hdmi_writel(PHY_SYS_CTL,0x2f);
+ hdmi_dbg(hdmi_drv->dev,
+ "%s change pwr_mode LOWER_PWR pwr_mode = %d, mode = %d\n",
+ __func__, hdmi->pwr_mode, mode);
+ rk616_hdmi_av_mute(hdmi_drv, 0);
+ rk616_hdmi_sys_power(hdmi_drv, false);
+ hdmi_writel(hdmi_dev, PHY_DRIVER, 0x00);
+ hdmi_writel(hdmi_dev, PHY_PRE_EMPHASIS, 0x00);
+ hdmi_writel(hdmi_dev, PHY_CHG_PWR, 0x00);
+ hdmi_writel(hdmi_dev, PHY_SYS_CTL, 0x2f);
break;
default:
- hdmi_dbg(hdmi->dev,"unkown rk616 hdmi pwr mode %d\n",mode);
- }
- hdmi->pwr_mode = mode;
-}
+ hdmi_dbg(hdmi_drv->dev, "unkown rk616 hdmi pwr mode %d\n",
+ mode);
+ }
+ hdmi_drv->pwr_mode = mode;
+}
-int rk616_hdmi_detect_hotplug(struct hdmi *hdmi)
+int rk616_hdmi_detect_hotplug(struct hdmi *hdmi_drv)
{
int value = 0;
-#if 0
- hdmi_readl(INTERRUPT_STATUS1,&value);
- if(value){
- hdmi_writel(INTERRUPT_STATUS1, value);
- }
-#endif
- hdmi_readl(HDMI_STATUS,&value);
-
- hdmi_dbg(hdmi->dev, "[%s] value %02x\n", __FUNCTION__, value);
+ struct rk_hdmi_device *hdmi_dev = container_of(hdmi_drv,
+ struct rk_hdmi_device,
+ driver);
+
+ hdmi_dbg(hdmi_drv->dev, "[%s] value %02x\n", __func__, value);
+ hdmi_readl(hdmi_dev, HDMI_STATUS, &value);
value &= m_HOTPLUG;
- if(value == m_HOTPLUG)
+ if (value == m_HOTPLUG)
return HDMI_HPD_ACTIVED;
- else if(value)
+ else if (value)
return HDMI_HPD_INSERT;
else
return HDMI_HPD_REMOVED;
}
-
-int rk616_hdmi_read_edid(struct hdmi *hdmi, int block, u8 * buf)
+int rk616_hdmi_read_edid(struct hdmi *hdmi_drv, int block, u8 *buf)
{
- u32 c = 0;
- u8 Segment = 0;
- u8 Offset = 0;
-
- int ret = -1;
- int i, j;
- int ddc_bus_freq;
- int trytime;
- int checksum = 0;
-
- if(block%2)
- Offset = HDMI_EDID_BLOCK_SIZE;
-
- if(block/2)
- Segment = 1;
-
- ddc_bus_freq = (HDMI_SYS_FREG_CLK>>2)/HDMI_SCL_RATE;
- hdmi_writel(DDC_BUS_FREQ_L, ddc_bus_freq & 0xFF);
- hdmi_writel(DDC_BUS_FREQ_H, (ddc_bus_freq >> 8) & 0xFF);
-
- hdmi_dbg(hdmi->dev, "EDID DATA (Segment = %d Block = %d Offset = %d):\n", (int) Segment, (int) block, (int) Offset);
- disable_irq(hdmi->irq);
-
- //enable edid interrupt
- hdmi_writel(INTERRUPT_MASK1, m_INT_HOTPLUG | m_INT_EDID_READY);
-
- for (trytime = 0; trytime < 10; trytime++) {
- c=0x04;
- hdmi_writel(INTERRUPT_STATUS1, c);
-
- //set edid fifo first addr
- c = 0x00;
- hdmi_writel(EDID_FIFO_OFFSET, c);
-
- //set edid word address 00/80
- c = Offset;
- hdmi_writel(EDID_WORD_ADDR, c);
-
- //set edid segment pointer
- c = Segment;
- hdmi_writel(EDID_SEGMENT_POINTER, c);
-
- for (i = 0; i < 10; i++) {
- //wait edid interrupt
- msleep(10);
- c=0x00;
- hdmi_readl(INTERRUPT_STATUS1, &c);
-
- if (c & 0x04) {
- break;
- }
-
- }
-
- if (c & 0x04) {
- for(j = 0; j < HDMI_EDID_BLOCK_SIZE; j++){
- c = 0;
- hdmi_readl(0x50, &c);
- buf[j] = c;
- checksum += c;
+ u32 c = 0;
+ u8 segment = 0;
+ u8 offset = 0;
+ int ret = -1;
+ int i, j;
+ int ddc_bus_freq;
+ int trytime;
+ int checksum = 0;
+ struct rk_hdmi_device *hdmi_dev = container_of(hdmi_drv,
+ struct rk_hdmi_device,
+ driver);
+
+ if (block % 2)
+ offset = HDMI_EDID_BLOCK_SIZE;
+
+ if (block / 2)
+ segment = 1;
+
+ ddc_bus_freq = (HDMI_SYS_FREG_CLK >> 2) / HDMI_SCL_RATE;
+ hdmi_writel(hdmi_dev, DDC_BUS_FREQ_L, ddc_bus_freq & 0xFF);
+ hdmi_writel(hdmi_dev, DDC_BUS_FREQ_H, (ddc_bus_freq >> 8) & 0xFF);
+
+ hdmi_dbg(hdmi_drv->dev,
+ "EDID DATA (Segment = %d Block = %d Offset = %d):\n",
+ (int)segment, (int)block, (int)offset);
+ disable_irq(hdmi_drv->irq);
+
+ /* Enable edid interrupt */
+ hdmi_writel(hdmi_dev, INTERRUPT_MASK1,
+ m_INT_HOTPLUG | m_INT_EDID_READY);
+
+ for (trytime = 0; trytime < 10; trytime++) {
+ hdmi_writel(hdmi_dev, INTERRUPT_STATUS1, 0x04);
+
+ /* Set edid fifo first addr */
+ hdmi_writel(hdmi_dev, EDID_FIFO_OFFSET, 0x00);
+
+ /* Set edid word address 0x00/0x80 */
+ hdmi_writel(hdmi_dev, EDID_WORD_ADDR, offset);
+
+ /* Set edid segment pointer */
+ hdmi_writel(hdmi_dev, EDID_SEGMENT_POINTER, segment);
+
+ for (i = 0; i < 10; i++) {
+ /* Wait edid interrupt */
+ msleep(10);
+ c = 0x00;
+ hdmi_readl(hdmi_dev, INTERRUPT_STATUS1, &c);
+
+ if (c & m_INT_EDID_READY)
+ break;
+ }
+
+ if (c & m_INT_EDID_READY) {
+ for (j = 0; j < HDMI_EDID_BLOCK_SIZE; j++) {
+ c = 0;
+ hdmi_readl(hdmi_dev, 0x50, &c);
+ buf[j] = c;
+ checksum += c;
#ifdef HDMI_DEBUG
- if(j%16==0)
- printk("\n>>>0x%02x: ", j);
+ if (j % 16 == 0)
+ dev_info(hdmi_drv->dev, "\n>>>0x%02x: ",
+ j);
- printk("0x%02x ",c);
+ dev_info(hdmi_drv->dev, "0x%02x ", c);
#endif
- }
-
- //clear EDID interrupt reg
- c=0x04;
- hdmi_writel(INTERRUPT_STATUS1, c);
-
- // printk("checksum = 0x%x\n", checksum);
- if ((checksum &= 0xff) == 0) {
- ret = 0;
- hdmi_dbg(hdmi->dev, "[%s] edid read sucess\n", __FUNCTION__);
- break;
- }
- }
- }
-
- hdmi_writel(INTERRUPT_MASK1, m_INT_HOTPLUG);
- enable_irq(hdmi->irq);
-
- return ret;
+ }
+
+ /* clear EDID interrupt reg */
+ hdmi_writel(hdmi_dev, INTERRUPT_STATUS1,
+ m_INT_EDID_READY);
+
+ if ((checksum & 0xff) == 0) {
+ ret = 0;
+ hdmi_dbg(hdmi_drv->dev,
+ "[%s] edid read sucess\n", __func__);
+ break;
+ }
+ }
+ }
+
+ hdmi_writel(hdmi_dev, INTERRUPT_MASK1, m_INT_HOTPLUG);
+ enable_irq(hdmi_drv->irq);
+
+ return ret;
}
-static void rk616_hdmi_config_avi(unsigned char vic, unsigned char output_color)
+static void rk616_hdmi_config_avi(struct hdmi *hdmi_drv,
+ unsigned char vic, unsigned char output_color)
{
int i;
char info[SIZE_AVI_INFOFRAME];
-
+ struct rk_hdmi_device *hdmi_dev = container_of(hdmi_drv,
+ struct rk_hdmi_device,
+ driver);
+
memset(info, 0, SIZE_AVI_INFOFRAME);
- hdmi_writel(CONTROL_PACKET_BUF_INDEX, INFOFRAME_AVI);
+ hdmi_writel(hdmi_dev, CONTROL_PACKET_BUF_INDEX, INFOFRAME_AVI);
info[0] = 0x82;
info[1] = 0x02;
- info[2] = 0x0D;
+ info[2] = 0x0D;
info[3] = info[0] + info[1] + info[2];
info[4] = (AVI_COLOR_MODE_RGB << 5);
- info[5] = (AVI_COLORIMETRY_NO_DATA << 6) | (AVI_CODED_FRAME_ASPECT_NO_DATA << 4) | ACTIVE_ASPECT_RATE_SAME_AS_CODED_FRAME;
+ info[5] =
+ (AVI_COLORIMETRY_NO_DATA << 6) | (AVI_CODED_FRAME_ASPECT_NO_DATA <<
+ 4) |
+ ACTIVE_ASPECT_RATE_SAME_AS_CODED_FRAME;
info[6] = 0;
info[7] = vic;
info[8] = 0;
- // Calculate AVI InfoFrame ChecKsum
+ /* Calculate AVI InfoFrame ChecKsum */
for (i = 4; i < SIZE_AVI_INFOFRAME; i++)
- {
- info[3] += info[i];
- }
+ info[3] += info[i];
+
info[3] = 0x100 - info[3];
-
- for(i = 0; i < SIZE_AVI_INFOFRAME; i++)
- hdmi_writel(CONTROL_PACKET_ADDR + i, info[i]);
-}
+ for (i = 0; i < SIZE_AVI_INFOFRAME; i++)
+ hdmi_writel(hdmi_dev, CONTROL_PACKET_ADDR + i, info[i]);
+}
-static int rk616_hdmi_config_video(struct hdmi *hdmi, struct hdmi_video_para *vpara)
+static int rk616_hdmi_config_video(struct hdmi *hdmi_drv,
+ struct hdmi_video_para *vpara)
{
int value;
struct fb_videomode *mode;
- struct rk616_hdmi *rk616_hdmi;
+ struct rk_hdmi_device *hdmi_dev = container_of(hdmi_drv,
+ struct rk_hdmi_device,
+ driver);
- hdmi_dbg(hdmi->dev, "[%s]\n", __FUNCTION__);
- rk616_hdmi = container_of(hdmi, struct rk616_hdmi, g_hdmi);
+ hdmi_dbg(hdmi_drv->dev, "[%s]\n", __func__);
- if(vpara == NULL) {
- hdmi_err(hdmi->dev, "[%s] input parameter error\n", __FUNCTION__);
+ if (vpara == NULL) {
+ hdmi_err(hdmi_drv->dev, "[%s] input parameter error\n",
+ __func__);
return -1;
}
- if(hdmi->pwr_mode == LOWER_PWR) {
- rk616_hdmi_set_pwr_mode(hdmi, NORMAL);
- }
+ /* Output RGB as default */
+ vpara->output_color = VIDEO_OUTPUT_RGB444;
+ if (hdmi_drv->pwr_mode == LOWER_PWR)
+ rk616_hdmi_set_pwr_mode(hdmi_drv, NORMAL);
+ /* Disable video and audio output */
+ hdmi_writel(hdmi_dev, AV_MUTE, v_AUDIO_MUTE(1) | v_VIDEO_MUTE(1));
- vpara->output_color = VIDEO_OUTPUT_RGB444;
- if(hdmi->hdcp_power_off_cb)
- hdmi->hdcp_power_off_cb();
- // Diable video and audio output
- hdmi_writel(AV_MUTE, v_AUDIO_MUTE(1) | v_VIDEO_MUTE(1));
-
- // Input video mode is SDR RGB24bit, Data enable signal from external
- hdmi_writel(VIDEO_CONTRL1, v_VIDEO_INPUT_FORMAT(VIDEO_INPUT_SDR_RGB444) | v_DE_EXTERNAL);
- hdmi_writel(VIDEO_CONTRL2, v_VIDEO_INPUT_BITS(VIDEO_INPUT_8BITS) | v_VIDEO_OUTPUT_FORMAT(vpara->output_color & 0xFF));
-
- // Set HDMI Mode
- hdmi_writel(HDCP_CTRL, v_HDMI_DVI(vpara->output_mode));
-
- // Enable or disalbe color space convert
- if(vpara->input_color != vpara->output_color) {
+ /* Input video mode is SDR RGB24bit, Data enable signal from external */
+ hdmi_writel(hdmi_dev, VIDEO_CONTRL1,
+ v_VIDEO_INPUT_FORMAT(VIDEO_INPUT_SDR_RGB444) |
+ v_DE_EXTERNAL);
+ hdmi_writel(hdmi_dev, VIDEO_CONTRL2,
+ v_VIDEO_INPUT_BITS(VIDEO_INPUT_8BITS) |
+ v_VIDEO_OUTPUT_FORMAT(vpara->output_color & 0xFF));
+
+ /* Set HDMI Mode */
+ hdmi_writel(hdmi_dev, HDCP_CTRL, v_HDMI_DVI(vpara->output_mode));
+
+ /* Enable or disalbe color space convert */
+ if (vpara->input_color != vpara->output_color)
value = v_SOF_DISABLE | v_CSC_ENABLE;
- }
else
value = v_SOF_DISABLE;
- hdmi_writel(VIDEO_CONTRL3, value);
+ hdmi_writel(hdmi_dev, VIDEO_CONTRL3, value);
- // Set ext video
+ /* Set ext video timing */
#if 1
- hdmi_writel(VIDEO_TIMING_CTL, 0);
+ hdmi_writel(hdmi_dev, VIDEO_TIMING_CTL, 0);
mode = (struct fb_videomode *)hdmi_vic_to_videomode(vpara->vic);
- if(mode == NULL)
- {
- hdmi_err(hdmi->dev, "[%s] not found vic %d\n", __FUNCTION__, vpara->vic);
+ if (mode == NULL) {
+ hdmi_err(hdmi_drv->dev, "[%s] not found vic %d\n", __func__,
+ vpara->vic);
return -ENOENT;
}
- hdmi->tmdsclk = mode->pixclock;
+ hdmi_drv->tmdsclk = mode->pixclock;
#else
value = v_EXTERANL_VIDEO(1) | v_INETLACE(mode->vmode);
- if(mode->sync & FB_SYNC_HOR_HIGH_ACT)
+ if (mode->sync & FB_SYNC_HOR_HIGH_ACT)
value |= v_HSYNC_POLARITY(1);
- if(mode->sync & FB_SYNC_VERT_HIGH_ACT)
+ if (mode->sync & FB_SYNC_VERT_HIGH_ACT)
value |= v_VSYNC_POLARITY(1);
- hdmi_writel(VIDEO_TIMING_CTL, value);
-
- value = mode->left_margin + mode->xres + mode->right_margin + mode->hsync_len;
- hdmi_writel(VIDEO_EXT_HTOTAL_L, value & 0xFF);
- hdmi_writel(VIDEO_EXT_HTOTAL_H, (value >> 8) & 0xFF);
-
+ hdmi_writel(hdmi_dev, VIDEO_TIMING_CTL, value);
+
+ value = mode->left_margin + mode->xres + mode->right_margin +
+ mode->hsync_len;
+ hdmi_writel(hdmi_dev, VIDEO_EXT_HTOTAL_L, value & 0xFF);
+ hdmi_writel(hdmi_dev, VIDEO_EXT_HTOTAL_H, (value >> 8) & 0xFF);
+
value = mode->left_margin + mode->right_margin + mode->hsync_len;
- hdmi_writel(VIDEO_EXT_HBLANK_L, value & 0xFF);
- hdmi_writel(VIDEO_EXT_HBLANK_H, (value >> 8) & 0xFF);
-
+ hdmi_writel(hdmi_dev, VIDEO_EXT_HBLANK_L, value & 0xFF);
+ hdmi_writel(hdmi_dev, VIDEO_EXT_HBLANK_H, (value >> 8) & 0xFF);
+
value = mode->left_margin + mode->hsync_len;
- hdmi_writel(VIDEO_EXT_HDELAY_L, value & 0xFF);
- hdmi_writel(VIDEO_EXT_HDELAY_H, (value >> 8) & 0xFF);
-
+ hdmi_writel(hdmi_dev, VIDEO_EXT_HDELAY_L, value & 0xFF);
+ hdmi_writel(hdmi_dev, VIDEO_EXT_HDELAY_H, (value >> 8) & 0xFF);
+
value = mode->hsync_len;
- hdmi_writel(VIDEO_EXT_HDURATION_L, value & 0xFF);
- hdmi_writel(VIDEO_EXT_HDURATION_H, (value >> 8) & 0xFF);
-
- value = mode->upper_margin + mode->yres + mode->lower_margin + mode->vsync_len;
- hdmi_writel(VIDEO_EXT_VTOTAL_L, value & 0xFF);
- hdmi_writel(VIDEO_EXT_VTOTAL_H, (value >> 8) & 0xFF);
-
+ hdmi_writel(hdmi_dev, VIDEO_EXT_HDURATION_L, value & 0xFF);
+ hdmi_writel(hdmi_dev, VIDEO_EXT_HDURATION_H, (value >> 8) & 0xFF);
+
+ value = mode->upper_margin + mode->yres + mode->lower_margin +
+ mode->vsync_len;
+ hdmi_writel(hdmi_dev, VIDEO_EXT_VTOTAL_L, value & 0xFF);
+ hdmi_writel(hdmi_dev, VIDEO_EXT_VTOTAL_H, (value >> 8) & 0xFF);
+
value = mode->upper_margin + mode->vsync_len + mode->lower_margin;
- hdmi_writel(VIDEO_EXT_VBLANK, value & 0xFF);
+ hdmi_writel(hdmi_dev, VIDEO_EXT_VBLANK, value & 0xFF);
- if(vpara->vic == HDMI_720x480p_60Hz_4_3 || vpara->vic == HDMI_720x480p_60Hz_16_9)
+ if (vpara->vic == HDMI_720x480p_60Hz_4_3
+ || vpara->vic == HDMI_720x480p_60Hz_16_9)
value = 42;
else
value = mode->upper_margin + mode->vsync_len;
- hdmi_writel(VIDEO_EXT_VDELAY, value & 0xFF);
-
+ hdmi_writel(hdmi_dev, VIDEO_EXT_VDELAY, value & 0xFF);
+
value = mode->vsync_len;
- hdmi_writel(VIDEO_EXT_VDURATION, value & 0xFF);
+ hdmi_writel(hdmi_dev, VIDEO_EXT_VDURATION, value & 0xFF);
#endif
- if(vpara->output_mode == OUTPUT_HDMI) {
- rk616_hdmi_config_avi(vpara->vic, vpara->output_color);
- hdmi_dbg(hdmi->dev, "[%s] sucess output HDMI.\n", __FUNCTION__);
+ if (vpara->output_mode == OUTPUT_HDMI) {
+ rk616_hdmi_config_avi(hdmi_drv, vpara->vic,
+ vpara->output_color);
+ hdmi_dbg(hdmi->dev, "[%s] sucess output HDMI.\n", __func__);
+ } else {
+ hdmi_dbg(hdmi->dev, "[%s] sucess output DVI.\n", __func__);
}
- else {
- hdmi_dbg(hdmi->dev, "[%s] sucess output DVI.\n", __FUNCTION__);
+
+ if (hdmi_drv->set_vif) {
+ hdmi_writel(hdmi_dev, PHY_PRE_DIV_RATIO, 0x0f);
+ hdmi_writel(hdmi_dev, PHY_FEEDBACK_DIV_RATIO_LOW, 0x96);
+ } else { /* rk3028a */
+ hdmi_writel(hdmi_dev, PHY_PRE_DIV_RATIO, 0x1e);
+ hdmi_writel(hdmi_dev, PHY_FEEDBACK_DIV_RATIO_LOW, 0x2c);
+ hdmi_writel(hdmi_dev, PHY_FEEDBACK_DIV_RATIO_HIGH, 0x01);
}
-
- // if(rk616_hdmi->rk616_drv) {
- if (hdmi->set_vif) {
- hdmi_writel(0xed, 0x0f);
- hdmi_writel(0xe7, 0x96);
- } else { // rk3028a
- hdmi_writel(0xed, 0x1e);
- hdmi_writel(0xe7, 0x2c);
- hdmi_writel(0xe8, 0x01);
- }
return 0;
}
-static void rk616_hdmi_config_aai(void)
+static void rk616_hdmi_config_aai(struct hdmi *hdmi_drv)
{
int i;
char info[SIZE_AUDIO_INFOFRAME];
-
+ struct rk_hdmi_device *hdmi_dev = container_of(hdmi_drv,
+ struct rk_hdmi_device,
+ driver);
+
memset(info, 0, SIZE_AUDIO_INFOFRAME);
-
+
info[0] = 0x84;
info[1] = 0x01;
info[2] = 0x0A;
-
- info[3] = info[0] + info[1] + info[2];
+
+ info[3] = info[0] + info[1] + info[2];
for (i = 4; i < SIZE_AUDIO_INFOFRAME; i++)
- info[3] += info[i];
-
+ info[3] += info[i];
+
info[3] = 0x100 - info[3];
-
- hdmi_writel(CONTROL_PACKET_BUF_INDEX, INFOFRAME_AAI);
- for(i = 0; i < SIZE_AUDIO_INFOFRAME; i++)
- hdmi_writel(CONTROL_PACKET_ADDR + i, info[i]);
+
+ hdmi_writel(hdmi_dev, CONTROL_PACKET_BUF_INDEX, INFOFRAME_AAI);
+ for (i = 0; i < SIZE_AUDIO_INFOFRAME; i++)
+ hdmi_writel(hdmi_dev, CONTROL_PACKET_ADDR + i, info[i]);
}
-static int rk616_hdmi_config_audio(struct hdmi *hdmi, struct hdmi_audio *audio)
+static int rk616_hdmi_config_audio(struct hdmi *hdmi_drv,
+ struct hdmi_audio *audio)
{
int rate, N, channel, mclk_fs;
-
- if(audio->channel < 3)
+ struct rk_hdmi_device *hdmi_dev = container_of(hdmi_drv,
+ struct rk_hdmi_device,
+ driver);
+
+ if (audio->channel < 3)
channel = I2S_CHANNEL_1_2;
- else if(audio->channel < 5)
+ else if (audio->channel < 5)
channel = I2S_CHANNEL_3_4;
- else if(audio->channel < 7)
+ else if (audio->channel < 7)
channel = I2S_CHANNEL_5_6;
else
channel = I2S_CHANNEL_7_8;
-
- switch(audio->rate)
- {
- case HDMI_AUDIO_FS_32000:
- rate = AUDIO_32K;
- N = N_32K;
- mclk_fs = MCLK_384FS;
- break;
- case HDMI_AUDIO_FS_44100:
- rate = AUDIO_441K;
- N = N_441K;
- mclk_fs = MCLK_256FS;
- break;
- case HDMI_AUDIO_FS_48000:
- rate = AUDIO_48K;
- N = N_48K;
- mclk_fs = MCLK_256FS;
- break;
- case HDMI_AUDIO_FS_88200:
- rate = AUDIO_882K;
- N = N_882K;
- mclk_fs = MCLK_128FS;
- break;
- case HDMI_AUDIO_FS_96000:
- rate = AUDIO_96K;
- N = N_96K;
- mclk_fs = MCLK_128FS;
- break;
- case HDMI_AUDIO_FS_176400:
- rate = AUDIO_1764K;
- N = N_1764K;
- mclk_fs = MCLK_128FS;
- break;
- case HDMI_AUDIO_FS_192000:
- rate = AUDIO_192K;
- N = N_192K;
- mclk_fs = MCLK_128FS;
- break;
- default:
- dev_err(hdmi->dev, "[%s] not support such sample rate %d\n", __FUNCTION__, audio->rate);
- return -ENOENT;
+
+ switch (audio->rate) {
+ case HDMI_AUDIO_FS_32000:
+ rate = AUDIO_32K;
+ N = N_32K;
+ mclk_fs = MCLK_384FS;
+ break;
+ case HDMI_AUDIO_FS_44100:
+ rate = AUDIO_441K;
+ N = N_441K;
+ mclk_fs = MCLK_256FS;
+ break;
+ case HDMI_AUDIO_FS_48000:
+ rate = AUDIO_48K;
+ N = N_48K;
+ mclk_fs = MCLK_256FS;
+ break;
+ case HDMI_AUDIO_FS_88200:
+ rate = AUDIO_882K;
+ N = N_882K;
+ mclk_fs = MCLK_128FS;
+ break;
+ case HDMI_AUDIO_FS_96000:
+ rate = AUDIO_96K;
+ N = N_96K;
+ mclk_fs = MCLK_128FS;
+ break;
+ case HDMI_AUDIO_FS_176400:
+ rate = AUDIO_1764K;
+ N = N_1764K;
+ mclk_fs = MCLK_128FS;
+ break;
+ case HDMI_AUDIO_FS_192000:
+ rate = AUDIO_192K;
+ N = N_192K;
+ mclk_fs = MCLK_128FS;
+ break;
+ default:
+ dev_err(hdmi_drv->dev, "[%s] not support such sample rate %d\n",
+ __func__, audio->rate);
+ return -ENOENT;
}
- //set_audio source I2S
- if(HDMI_CODEC_SOURCE_SELECT == INPUT_IIS){
- hdmi_writel(AUDIO_CTRL1, 0x00);
- hdmi_writel(AUDIO_SAMPLE_RATE, rate);
- hdmi_writel(AUDIO_I2S_MODE, v_I2S_MODE(I2S_STANDARD) | v_I2S_CHANNEL(channel) );
- hdmi_writel(AUDIO_I2S_MAP, 0x00);
- hdmi_writel(AUDIO_I2S_SWAPS_SPDIF, 0); // no swap
- }else{
- hdmi_writel(AUDIO_CTRL1, 0x08);
- hdmi_writel(AUDIO_I2S_SWAPS_SPDIF, 0); // no swap
+ /* set_audio source I2S */
+ if (HDMI_CODEC_SOURCE_SELECT == INPUT_IIS) {
+ hdmi_writel(hdmi_dev, AUDIO_CTRL1, 0x00);
+ hdmi_writel(hdmi_dev, AUDIO_SAMPLE_RATE, rate);
+ hdmi_writel(hdmi_dev, AUDIO_I2S_MODE,
+ v_I2S_MODE(I2S_STANDARD) | v_I2S_CHANNEL(channel));
+ hdmi_writel(hdmi_dev, AUDIO_I2S_MAP, 0x00);
+ /* no swap */
+ hdmi_writel(hdmi_dev, AUDIO_I2S_SWAPS_SPDIF, 0);
+ } else {
+ hdmi_writel(hdmi_dev, AUDIO_CTRL1, 0x08);
+ /* no swap */
+ hdmi_writel(hdmi_dev, AUDIO_I2S_SWAPS_SPDIF, 0);
}
-
- //Set N value
- hdmi_writel(AUDIO_N_H, (N >> 16) & 0x0F);
- hdmi_writel(AUDIO_N_M, (N >> 8) & 0xFF);
- hdmi_writel(AUDIO_N_L, N & 0xFF);
- rk616_hdmi_config_aai();
-
- return 0;
+
+ /* Set N value */
+ hdmi_writel(hdmi_dev, AUDIO_N_H, (N >> 16) & 0x0F);
+ hdmi_writel(hdmi_dev, AUDIO_N_M, (N >> 8) & 0xFF);
+ hdmi_writel(hdmi_dev, AUDIO_N_L, N & 0xFF);
+ rk616_hdmi_config_aai(hdmi_drv);
+
+ return 0;
}
-void rk616_hdmi_control_output(struct hdmi *hdmi, int enable)
+void rk616_hdmi_control_output(struct hdmi *hdmi_drv, int enable)
{
int mutestatus = 0;
-
- if(enable) {
- if(hdmi->pwr_mode == LOWER_PWR)
- rk616_hdmi_set_pwr_mode(hdmi, NORMAL);
- hdmi_readl(AV_MUTE,&mutestatus);
- if(mutestatus && (m_AUDIO_MUTE | m_VIDEO_BLACK)) {
- hdmi_writel(AV_MUTE, v_AUDIO_MUTE(0) | v_VIDEO_MUTE(0));
+ struct rk_hdmi_device *hdmi_dev = container_of(hdmi_drv,
+ struct rk_hdmi_device,
+ driver);
+
+ if (enable) {
+ if (hdmi_drv->pwr_mode == LOWER_PWR)
+ rk616_hdmi_set_pwr_mode(hdmi_drv, NORMAL);
+ hdmi_readl(hdmi_dev, AV_MUTE, &mutestatus);
+ if (mutestatus && (m_AUDIO_MUTE | m_VIDEO_BLACK)) {
+ hdmi_writel(hdmi_dev, AV_MUTE,
+ v_AUDIO_MUTE(0) | v_VIDEO_MUTE(0));
}
- rk616_hdmi_sys_power_up();
- rk616_hdmi_sys_power_down();
- rk616_hdmi_sys_power_up();
- hdmi_writel(0xce, 0x00);
+ rk616_hdmi_sys_power(hdmi_drv, true);
+ rk616_hdmi_sys_power(hdmi_drv, false);
+ rk616_hdmi_sys_power(hdmi_drv, true);
+ hdmi_writel(hdmi_dev, 0xce, 0x00);
delay100us();
- hdmi_writel(0xce, 0x01);
- }
- else {
- hdmi_writel(AV_MUTE, v_AUDIO_MUTE(1) | v_VIDEO_MUTE(1));
+ hdmi_writel(hdmi_dev, 0xce, 0x01);
+ } else {
+ hdmi_writel(hdmi_dev, AV_MUTE,
+ v_AUDIO_MUTE(1) | v_VIDEO_MUTE(1));
}
}
-int rk616_hdmi_removed(struct hdmi *hdmi)
+int rk616_hdmi_removed(struct hdmi *hdmi_drv)
{
- dev_printk(KERN_INFO , hdmi->dev , "Removed.\n");
- rk616_hdmi_set_pwr_mode(hdmi, LOWER_PWR);
+ dev_info(hdmi_drv->dev, "Removed.\n");
+ if (hdmi_drv->hdcp_power_off_cb)
+ hdmi_drv->hdcp_power_off_cb();
+ rk616_hdmi_set_pwr_mode(hdmi_drv, LOWER_PWR);
return HDMI_ERROR_SUCESS;
}
-
-void rk616_hdmi_work(struct hdmi *hdmi)
-{
+void rk616_hdmi_work(struct hdmi *hdmi_drv)
+{
u32 interrupt = 0;
- // int value = 0;
-
-
- hdmi_readl(INTERRUPT_STATUS1,&interrupt);
- if(interrupt){
- hdmi_writel(INTERRUPT_STATUS1, interrupt);
- }
+ struct rk_hdmi_device *hdmi_dev = container_of(hdmi_drv,
+ struct rk_hdmi_device,
+ driver);
- if(interrupt & m_HOTPLUG){
- if(hdmi->state == HDMI_SLEEP)
- hdmi->state = WAIT_HOTPLUG;
- //if(hdmi->pwr_mode == LOWER_PWR)
- // rk616_hdmi_set_pwr_mode(NORMAL);
+ hdmi_readl(hdmi_dev, INTERRUPT_STATUS1, &interrupt);
+ if (interrupt)
+ hdmi_writel(hdmi_dev, INTERRUPT_STATUS1, interrupt);
- queue_delayed_work(hdmi->workqueue, &hdmi->delay_work, msecs_to_jiffies(40));
+ if (interrupt & m_HOTPLUG) {
+ if (hdmi_drv->state == HDMI_SLEEP)
+ hdmi_drv->state = WAIT_HOTPLUG;
- }
+ queue_delayed_work(hdmi_drv->workqueue, &hdmi_drv->delay_work,
+ msecs_to_jiffies(40));
-#if 0
- if(hdmi->state == HDMI_SLEEP) {
-// hdmi_dbg(hdmi->dev, "hdmi return to sleep mode\n");
- rk616_hdmi_set_pwr_mode(hdmi, LOWER_PWR);
}
-#endif
-#if 0
- if(hdmi->hdcp_irq_cb)
- hdmi->hdcp_irq_cb(interrupt2);
-#endif
+
+ if (hdmi_drv->hdcp_irq_cb)
+ hdmi_drv->hdcp_irq_cb(0);
}
-static void rk616_hdmi_reset(struct hdmi *hdmi)
+static void rk616_hdmi_reset(struct hdmi *hdmi_drv)
{
u32 val = 0;
u32 msk = 0;
-
- hdmi_msk_reg(SYS_CTRL,m_RST_DIGITAL,v_NOT_RST_DIGITAL);
+ struct rk_hdmi_device *hdmi_dev = container_of(hdmi_drv,
+ struct rk_hdmi_device,
+ driver);
+
+ hdmi_msk_reg(hdmi_dev, SYS_CTRL, m_RST_DIGITAL, v_NOT_RST_DIGITAL);
delay100us();
- hdmi_msk_reg(SYS_CTRL,m_RST_ANALOG,v_NOT_RST_ANALOG);
+ hdmi_msk_reg(hdmi_dev, SYS_CTRL, m_RST_ANALOG, v_NOT_RST_ANALOG);
delay100us();
msk = m_REG_CLK_INV | m_REG_CLK_SOURCE | m_POWER | m_INT_POL;
- val = v_REG_CLK_INV | v_REG_CLK_SOURCE_SYS | v_PWR_ON |v_INT_POL_HIGH;
- hdmi_msk_reg(SYS_CTRL,msk,val);
- hdmi_writel(INTERRUPT_MASK1,m_INT_HOTPLUG);
- rk616_hdmi_set_pwr_mode(hdmi, LOWER_PWR);
+ val = v_REG_CLK_INV | v_REG_CLK_SOURCE_SYS | v_PWR_ON | v_INT_POL_HIGH;
+ hdmi_msk_reg(hdmi_dev, SYS_CTRL, msk, val);
+ hdmi_writel(hdmi_dev, INTERRUPT_MASK1, m_INT_HOTPLUG);
+ rk616_hdmi_set_pwr_mode(hdmi_drv, LOWER_PWR);
}
-int rk616_hdmi_initial(struct hdmi *hdmi)
+int rk616_hdmi_initial(struct hdmi *hdmi_drv)
{
int rc = HDMI_ERROR_SUCESS;
- struct rk616_hdmi *rk616_hdmi;
- rk616_hdmi = container_of(hdmi, struct rk616_hdmi, g_hdmi);
+#ifndef CONFIG_ARCH_RK3026
+ struct rk_hdmi_device *hdmi_dev = container_of(hdmi_drv,
+ struct rk_hdmi_device,
+ driver);
+ struct mfd_rk616 *rk616_drv = hdmi_dev->rk616_drv;
+#endif
- hdmi->pwr_mode = NORMAL;
- hdmi->remove = rk616_hdmi_removed ;
- hdmi->control_output = rk616_hdmi_control_output;
- hdmi->config_video = rk616_hdmi_config_video;
- hdmi->config_audio = rk616_hdmi_config_audio;
- hdmi->detect_hotplug = rk616_hdmi_detect_hotplug;
- hdmi->read_edid = rk616_hdmi_read_edid;
+ hdmi_drv->pwr_mode = NORMAL;
+ hdmi_drv->remove = rk616_hdmi_removed;
+ hdmi_drv->control_output = rk616_hdmi_control_output;
+ hdmi_drv->config_video = rk616_hdmi_config_video;
+ hdmi_drv->config_audio = rk616_hdmi_config_audio;
+ hdmi_drv->detect_hotplug = rk616_hdmi_detect_hotplug;
+ hdmi_drv->read_edid = rk616_hdmi_read_edid;
#ifdef CONFIG_ARCH_RK3026
- rk3028_hdmi_reset_pclk();
- rk616_hdmi_reset(hdmi);
+ rk3028_hdmi_reset_pclk();
+ rk616_hdmi_reset(hdmi_drv);
#else
- hdmi->set_vif = rk616_hdmi_set_vif;
- rk616_hdmi_reset(hdmi);
- rk616_hdmi_init_pol_set(rk616_hdmi->rk616_drv, 0);
+ hdmi_drv->set_vif = rk616_hdmi_set_vif;
+ rk616_hdmi_reset(hdmi_drv);
+ rk616_hdmi_init_pol_set(rk616_drv, 0);
#endif
-
- if(hdmi->hdcp_power_on_cb)
- rc = hdmi->hdcp_power_on_cb();
+
+ if (hdmi_drv->hdcp_power_on_cb)
+ rc = hdmi_drv->hdcp_power_on_cb();
return rc;
}
#define _RK616_HDMI_HW_H
#define RK616_HDMI_BASE 0x400
-enum PWR_MODE{
- NORMAL,
- LOWER_PWR,
+enum PWR_MODE {
+ NORMAL,
+ LOWER_PWR,
};
enum {
- OUTPUT_DVI = 0,
- OUTPUT_HDMI
- };
-
+ OUTPUT_DVI = 0,
+ OUTPUT_HDMI
+};
#ifdef RK616_USE_MCLK_12M
#define HDMI_SYS_FREG_CLK 12000000
#endif
#define HDMI_SCL_RATE (100*1000)
-#define DDC_BUS_FREQ_L 0x4b
-#define DDC_BUS_FREQ_H 0x4c
-
+#define DDC_BUS_FREQ_L 0x4b
+#define DDC_BUS_FREQ_H 0x4c
#define SYS_CTRL 0x00
-#define m_RST_ANALOG (1<<6)
-#define v_RST_ANALOG (0<<6)
-#define v_NOT_RST_ANALOG (1<<6)
-
-#define m_RST_DIGITAL (1<<5)
-#define v_RST_DIGITAL (0<<5)
-#define v_NOT_RST_DIGITAL (1<<5)
-
-#define m_REG_CLK_INV (1<<4)
-#define v_REG_CLK_NOT_INV (0<<4)
-#define v_REG_CLK_INV (1<<4)
-#define m_VCLK_INV (1<<3)
-#define v_VCLK_NOT_INV (0<<3)
-#define v_VCLK_INV (1<<3)
-#define m_REG_CLK_SOURCE (1<<2)
-#define v_REG_CLK_SOURCE_TMDS (0<<2)
-#define v_REG_CLK_SOURCE_SYS (1<<2)
-#define m_POWER (1<<1)
-#define v_PWR_ON (0<<1)
-#define v_PWR_OFF (1<<1)
-#define m_INT_POL (1<<0)
-#define v_INT_POL_HIGH 1
-#define v_INT_POL_LOW 0
-
-
-#define VIDEO_CONTRL1 0x01
- #define m_VIDEO_INPUT_FORMAT (7 << 1)
- #define m_DE_SOURCE (1 << 0)
- enum {
- VIDEO_INPUT_SDR_RGB444 = 0,
- VIDEO_INPUT_DDR_RGB444 = 5,
- VIDEO_INPUT_DDR_YCBCR422 = 6
- };
- #define v_VIDEO_INPUT_FORMAT(n) (n << 1)
- #define v_DE_EXTERNAL 1
- #define v_DE_INTERANL 0
-
-#define VIDEO_CONTRL2 0x02
- #define m_VIDEO_OUTPUT_FORMAT (3 << 6)
- #define m_VIDEO_INPUT_BITS (3 << 4)
- #define v_VIDEO_OUTPUT_FORMAT(n)(n << 6)
- #define v_VIDEO_INPUT_BITS(n) (n << 4)
- enum{
- VIDEO_INPUT_12BITS = 0,
- VIDEO_INPUT_10BITS,
- VIDEO_INPUT_8BITS
- };
-#define VIDEO_CONTRL3 0x04
- #define m_SOF (1 << 3)
- #define m_CSC (1 << 0)
- #define v_SOF_ENABLE (0 << 3)
- #define v_SOF_DISABLE (1 << 3)
- #define v_CSC_ENABLE 1
- #define v_CSC_DISABLE 0
-
-#define AV_MUTE 0x05
- #define m_AVMUTE_CLEAR (1 << 7)
- #define m_AVMUTE_ENABLE (1 << 6)
- #define m_AUDIO_MUTE (1 << 1)
- #define m_VIDEO_BLACK (1 << 0)
- #define v_AUDIO_MUTE(n) (n << 1)
- #define v_VIDEO_MUTE(n) (n << 0)
-
-#define VIDEO_TIMING_CTL 0x08
- #define v_HSYNC_POLARITY(n) (n << 3)
- #define v_VSYNC_POLARITY(n) (n << 2)
- #define v_INETLACE(n) (n << 1)
- #define v_EXTERANL_VIDEO(n) (n << 0)
-
-#define VIDEO_EXT_HTOTAL_L 0x09
-#define VIDEO_EXT_HTOTAL_H 0x0a
-#define VIDEO_EXT_HBLANK_L 0x0b
-#define VIDEO_EXT_HBLANK_H 0x0c
-#define VIDEO_EXT_HDELAY_L 0x0d
-#define VIDEO_EXT_HDELAY_H 0x0e
+#define m_RST_ANALOG (1 << 6)
+#define v_RST_ANALOG (0 << 6)
+#define v_NOT_RST_ANALOG (1 << 6)
+
+#define m_RST_DIGITAL (1 << 5)
+#define v_RST_DIGITAL (0 << 5)
+#define v_NOT_RST_DIGITAL (1 << 5)
+
+#define m_REG_CLK_INV (1 << 4)
+#define v_REG_CLK_NOT_INV (0 << 4)
+#define v_REG_CLK_INV (1 << 4)
+#define m_VCLK_INV (1 << 3)
+#define v_VCLK_NOT_INV (0 << 3)
+#define v_VCLK_INV (1 << 3)
+#define m_REG_CLK_SOURCE (1 << 2)
+#define v_REG_CLK_SOURCE_TMDS (0 << 2)
+#define v_REG_CLK_SOURCE_SYS (1 << 2)
+#define m_POWER (1 << 1)
+#define v_PWR_ON (0 << 1)
+#define v_PWR_OFF (1 << 1)
+#define m_INT_POL (1 << 0)
+#define v_INT_POL_HIGH 1
+#define v_INT_POL_LOW 0
+
+#define VIDEO_CONTRL1 0x01
+#define m_VIDEO_INPUT_FORMAT (7 << 1)
+#define m_DE_SOURCE (1 << 0)
+enum {
+ VIDEO_INPUT_SDR_RGB444 = 0,
+ VIDEO_INPUT_DDR_RGB444 = 5,
+ VIDEO_INPUT_DDR_YCBCR422 = 6
+};
+#define v_VIDEO_INPUT_FORMAT(n) (n << 1)
+#define v_DE_EXTERNAL 1
+#define v_DE_INTERANL 0
+
+#define VIDEO_CONTRL2 0x02
+#define m_VIDEO_OUTPUT_FORMAT (3 << 6)
+#define m_VIDEO_INPUT_BITS (3 << 4)
+#define v_VIDEO_OUTPUT_FORMAT(n)(n << 6)
+#define v_VIDEO_INPUT_BITS(n) (n << 4)
+enum {
+ VIDEO_INPUT_12BITS = 0,
+ VIDEO_INPUT_10BITS,
+ VIDEO_INPUT_8BITS
+};
+#define VIDEO_CONTRL3 0x04
+#define m_SOF (1 << 3)
+#define m_CSC (1 << 0)
+#define v_SOF_ENABLE (0 << 3)
+#define v_SOF_DISABLE (1 << 3)
+#define v_CSC_ENABLE 1
+#define v_CSC_DISABLE 0
+
+#define AV_MUTE 0x05
+#define m_AVMUTE_CLEAR (1 << 7)
+#define m_AVMUTE_ENABLE (1 << 6)
+#define m_AUDIO_MUTE (1 << 1)
+#define m_VIDEO_BLACK (1 << 0)
+#define v_AUDIO_MUTE(n) (n << 1)
+#define v_VIDEO_MUTE(n) (n << 0)
+
+#define VIDEO_TIMING_CTL 0x08
+#define v_HSYNC_POLARITY(n) (n << 3)
+#define v_VSYNC_POLARITY(n) (n << 2)
+#define v_INETLACE(n) (n << 1)
+#define v_EXTERANL_VIDEO(n) (n << 0)
+
+#define VIDEO_EXT_HTOTAL_L 0x09
+#define VIDEO_EXT_HTOTAL_H 0x0a
+#define VIDEO_EXT_HBLANK_L 0x0b
+#define VIDEO_EXT_HBLANK_H 0x0c
+#define VIDEO_EXT_HDELAY_L 0x0d
+#define VIDEO_EXT_HDELAY_H 0x0e
#define VIDEO_EXT_HDURATION_L 0x0f
#define VIDEO_EXT_HDURATION_H 0x10
-#define VIDEO_EXT_VTOTAL_L 0x11
-#define VIDEO_EXT_VTOTAL_H 0x12
-#define VIDEO_EXT_VBLANK 0x13
-#define VIDEO_EXT_VDELAY 0x14
-#define VIDEO_EXT_VDURATION 0x15
-
-#define AUDIO_CTRL1 0x35
- enum {
- CTS_SOURCE_INTERNAL = 0,
- CTS_SOURCE_EXTERNAL
- };
- #define v_CTS_SOURCE(n) (n << 7)
- enum {
- DOWNSAMPLE_DISABLE = 0,
- DOWNSAMPLE_1_2,
- DOWNSAMPLE_1_4
- };
- #define v_DOWN_SAMPLE(n) (n << 5)
- enum {
- AUDIO_SOURCE_IIS = 0,
- AUDIO_SOURCE_SPDIF
- };
- #define v_AUDIO_SOURCE(n) (n << 3)
- #define v_MCLK_ENABLE(n) (n << 2)
- enum {
- MCLK_128FS = 0,
- MCLK_256FS,
- MCLK_384FS,
- MCLK_512FS
- };
- #define v_MCLK_RATIO(n) (n)
-
-#define AUDIO_SAMPLE_RATE 0x37
- enum {
- AUDIO_32K = 0x3,
- AUDIO_441K = 0x0,
- AUDIO_48K = 0x2,
- AUDIO_882K = 0x8,
- AUDIO_96K = 0xa,
- AUDIO_1764K = 0xc,
- AUDIO_192K = 0xe,
- };
-
-#define AUDIO_I2S_MODE 0x38
- enum {
- I2S_CHANNEL_1_2 = 1,
- I2S_CHANNEL_3_4 = 3,
- I2S_CHANNEL_5_6 = 7,
- I2S_CHANNEL_7_8 = 0xf
- };
- #define v_I2S_CHANNEL(n) ((n) << 2)
- enum {
- I2S_STANDARD = 0,
- I2S_LEFT_JUSTIFIED,
- I2S_RIGHT_JUSTIFIED
- };
- #define v_I2S_MODE(n) (n)
-
-#define AUDIO_I2S_MAP 0x39
+#define VIDEO_EXT_VTOTAL_L 0x11
+#define VIDEO_EXT_VTOTAL_H 0x12
+#define VIDEO_EXT_VBLANK 0x13
+#define VIDEO_EXT_VDELAY 0x14
+#define VIDEO_EXT_VDURATION 0x15
+
+#define AUDIO_CTRL1 0x35
+enum {
+ CTS_SOURCE_INTERNAL = 0,
+ CTS_SOURCE_EXTERNAL
+};
+#define v_CTS_SOURCE(n) (n << 7)
+enum {
+ DOWNSAMPLE_DISABLE = 0,
+ DOWNSAMPLE_1_2,
+ DOWNSAMPLE_1_4
+};
+#define v_DOWN_SAMPLE(n) (n << 5)
+enum {
+ AUDIO_SOURCE_IIS = 0,
+ AUDIO_SOURCE_SPDIF
+};
+#define v_AUDIO_SOURCE(n) (n << 3)
+#define v_MCLK_ENABLE(n) (n << 2)
+enum {
+ MCLK_128FS = 0,
+ MCLK_256FS,
+ MCLK_384FS,
+ MCLK_512FS
+};
+#define v_MCLK_RATIO(n) (n)
+
+#define AUDIO_SAMPLE_RATE 0x37
+enum {
+ AUDIO_32K = 0x3,
+ AUDIO_441K = 0x0,
+ AUDIO_48K = 0x2,
+ AUDIO_882K = 0x8,
+ AUDIO_96K = 0xa,
+ AUDIO_1764K = 0xc,
+ AUDIO_192K = 0xe,
+};
+
+#define AUDIO_I2S_MODE 0x38
+enum {
+ I2S_CHANNEL_1_2 = 1,
+ I2S_CHANNEL_3_4 = 3,
+ I2S_CHANNEL_5_6 = 7,
+ I2S_CHANNEL_7_8 = 0xf
+};
+#define v_I2S_CHANNEL(n) ((n) << 2)
+enum {
+ I2S_STANDARD = 0,
+ I2S_LEFT_JUSTIFIED,
+ I2S_RIGHT_JUSTIFIED
+};
+#define v_I2S_MODE(n) (n)
+
+#define AUDIO_I2S_MAP 0x39
#define AUDIO_I2S_SWAPS_SPDIF 0x3a
- #define v_SPIDF_FREQ(n) (n)
+#define v_SPIDF_FREQ(n) (n)
-#define N_32K 0x1000
-#define N_441K 0x1880
-#define N_882K 0x3100
-#define N_1764K 0x6200
-#define N_48K 0x1800
+#define N_32K 0x1000
+#define N_441K 0x1880
+#define N_882K 0x3100
+#define N_1764K 0x6200
+#define N_48K 0x1800
#define N_96K 0x3000
-#define N_192K 0x6000
+#define N_192K 0x6000
-#define AUDIO_N_H 0x3f
-#define AUDIO_N_M 0x40
-#define AUDIO_N_L 0x41
+#define AUDIO_N_H 0x3f
+#define AUDIO_N_M 0x40
+#define AUDIO_N_L 0x41
-#define AUDIO_CTS_H 0x45
-#define AUDIO_CTS_M 0x46
-#define AUDIO_CTS_L 0x47
+#define AUDIO_CTS_H 0x45
+#define AUDIO_CTS_M 0x46
+#define AUDIO_CTS_L 0x47
+#define DDC_CLK_L 0x4b
+#define DDC_CLK_H 0x4c
-#define DDC_CLK_L 0x4b
-#define DDC_CLK_H 0x4c
-
-#define EDID_SEGMENT_POINTER 0x4d
+#define EDID_SEGMENT_POINTER 0x4d
#define EDID_WORD_ADDR 0x4e
#define EDID_FIFO_OFFSET 0x4f
#define EDID_FIFO_ADDR 0x50
INFOFRAME_AVI = 0x06,
INFOFRAME_AAI = 0x08
};
-#define CONTROL_PACKET_ADDR 0xa0
-
+#define CONTROL_PACKET_ADDR 0xa0
-#define SIZE_AVI_INFOFRAME 0x11 // 14 bytes
-#define SIZE_AUDIO_INFOFRAME 0x0F // 15 bytes
+#define SIZE_AVI_INFOFRAME 0x11 /* 14 bytes */
+#define SIZE_AUDIO_INFOFRAME 0x0F /* 15 bytes */
enum {
AVI_COLOR_MODE_RGB = 0,
AVI_COLOR_MODE_YCBCR422,
ACTIVE_ASPECT_RATE_14_9
};
-#define HDCP_CTRL 0x52
- #define m_HDMI_DVI (1 << 1)
- #define v_HDMI_DVI(n) (n << 1)
+#define HDCP_CTRL 0x52
+#define m_HDMI_DVI (1 << 1)
+#define v_HDMI_DVI(n) (n << 1)
#define INTERRUPT_MASK1 0xc0
#define INTERRUPT_STATUS1 0xc1
- #define m_INT_HOTPLUG (1 << 7)
- #define m_INT_ACTIVE_VSYNC (1 << 5)
- #define m_INT_EDID_READY (1 << 2)
-
+#define m_INT_HOTPLUG (1 << 7)
+#define m_INT_ACTIVE_VSYNC (1 << 5)
+#define m_INT_EDID_READY (1 << 2)
+
#define INTERRUPT_MASK2 0xc2
#define INTERRUPT_STATUS2 0xc3
- #define m_INT_HDCP_ERR (1 << 7)
- #define m_INT_BKSV_FLAG (1 << 6)
- #define m_INT_HDCP_OK (1 << 4)
-
-#define HDMI_STATUS 0xc8
- #define m_HOTPLUG (1 << 7)
- #define m_DDC_SDA (1 << 5)
- #define m_DDC_SDC (1 << 4)
-
-#define PHY_SYNC 0xce //sync phy parameter
-#define PHY_SYS_CTL 0xe0
- #define m_TMDS_CLK_SOURCE (1<<5)
- #define v_TMDS_FROM_PLL (0<<5)
- #define v_TMDS_FROM_GEN (1<<5)
- #define m_PHASE_CLK (1<<4)
- #define v_DEFAULT_PHASE (0<<4)
- #define v_SYNC_PHASE (1<<4)
- #define m_TMDS_CURRENT_PWR (1<<3)
- #define v_TURN_ON_CURRENT (0<<3)
- #define v_CAT_OFF_CURRENT (1<<3)
- #define m_BANDGAP_PWR (1<<2)
- #define v_BANDGAP_PWR_UP (0<<2)
- #define v_BANDGAP_PWR_DOWN (1<<2)
- #define m_PLL_PWR (1<<1)
- #define v_PLL_PWR_UP (0<<1)
- #define v_PLL_PWR_DOWN (1<<1)
- #define m_TMDS_CHG_PWR (1<<0)
- #define v_TMDS_CHG_PWR_UP (0<<0)
- #define v_TMDS_CHG_PWR_DOWN (1<<0)
-
-#define PHY_CHG_PWR 0xe1
- #define v_CLK_CHG_PWR(n) ((n&1)<<3)
- #define v_DATA_CHG_PWR(n) ((n&7)<<0)
-
-#define PHY_DRIVER 0xe2
- #define v_CLK_MAIN_DRIVER(n) (n << 4)
- #define v_DATA_MAIN_DRIVER(n) (n << 0)
-
+#define m_INT_HDCP_ERR (1 << 7)
+#define m_INT_BKSV_FLAG (1 << 6)
+#define m_INT_HDCP_OK (1 << 4)
+
+#define HDMI_STATUS 0xc8
+#define m_HOTPLUG (1 << 7)
+#define m_DDC_SDA (1 << 5)
+#define m_DDC_SDC (1 << 4)
+
+#define HDMI_COLORBAR 0xc9
+
+#define PHY_SYNC 0xce /* sync phy parameter */
+#define PHY_SYS_CTL 0xe0
+#define m_TMDS_CLK_SOURCE (1 << 5)
+#define v_TMDS_FROM_PLL (0 << 5)
+#define v_TMDS_FROM_GEN (1 << 5)
+#define m_PHASE_CLK (1 << 4)
+#define v_DEFAULT_PHASE (0 << 4)
+#define v_SYNC_PHASE (1 << 4)
+#define m_TMDS_CURRENT_PWR (1 << 3)
+#define v_TURN_ON_CURRENT (0 << 3)
+#define v_CAT_OFF_CURRENT (1 << 3)
+#define m_BANDGAP_PWR (1 << 2)
+#define v_BANDGAP_PWR_UP (0 << 2)
+#define v_BANDGAP_PWR_DOWN (1 << 2)
+#define m_PLL_PWR (1 << 1)
+#define v_PLL_PWR_UP (0 << 1)
+#define v_PLL_PWR_DOWN (1 << 1)
+#define m_TMDS_CHG_PWR (1 << 0)
+#define v_TMDS_CHG_PWR_UP (0 << 0)
+#define v_TMDS_CHG_PWR_DOWN (1 << 0)
+
+#define PHY_CHG_PWR 0xe1
+#define v_CLK_CHG_PWR(n) ((n & 1) << 3)
+#define v_DATA_CHG_PWR(n) ((n & 7) << 0)
+
+#define PHY_DRIVER 0xe2
+#define v_CLK_MAIN_DRIVER(n) (n << 4)
+#define v_DATA_MAIN_DRIVER(n) (n << 0)
+
#define PHY_PRE_EMPHASIS 0xe3
- #define v_PRE_EMPHASIS(n) ((n&7)<<4)
- #define v_CLK_PRE_DRIVER(n) ((n&3)<<2)
- #define v_DATA_PRE_DRIVER(n) ((n&3)<<0)
-
+#define v_PRE_EMPHASIS(n) ((n & 7) << 4)
+#define v_CLK_PRE_DRIVER(n) ((n & 3) << 2)
+#define v_DATA_PRE_DRIVER(n) ((n & 3) << 0)
+
#define PHY_FEEDBACK_DIV_RATIO_LOW 0xe7
- #define v_FEEDBACK_DIV_LOW(n) (n&0xff)
-#define PHY_FEEDBACK_DIV_RATIO_HIGH 0xe8
- #define v_FEEDBACK_DIV_HIGH(n) (n&1)
+#define v_FEEDBACK_DIV_LOW(n) (n & 0xff)
+#define PHY_FEEDBACK_DIV_RATIO_HIGH 0xe8
+#define v_FEEDBACK_DIV_HIGH(n) (n & 1)
-#define PHY_PRE_DIV_RATIO 0xed
- #define v_PRE_DIV_RATIO(n) (n&1f)
+#define PHY_PRE_DIV_RATIO 0xed
+#define v_PRE_DIV_RATIO(n) (n & 0x1f)
-extern struct hdmi *hdmi;
#ifndef CONFIG_ARCH_RK3026
-static inline int hdmi_readl(u16 offset, u32 *val)
+static inline int hdmi_readl(struct rk_hdmi_device *hdmi_dev,
+ u16 offset, u32 *val)
{
- int ret;
- struct rk616_hdmi *rk616_hdmi;
- rk616_hdmi = container_of(hdmi, struct rk616_hdmi, g_hdmi);
+ int ret;
+ struct mfd_rk616 *rk616_drv = hdmi_dev->rk616_drv;
- ret = rk616_hdmi->rk616_drv->read_dev(rk616_hdmi->rk616_drv, (RK616_HDMI_BASE + ((offset)<<2)), val);
- return ret;
+ ret = rk616_drv->read_dev(rk616_drv,
+ (RK616_HDMI_BASE + ((offset) << 2)), val);
+ return ret;
}
-static inline int hdmi_writel(u16 offset, u32 val)
+static inline int hdmi_writel(struct rk_hdmi_device *hdmi_dev,
+ u16 offset, u32 val)
{
- int ret;
- struct rk616_hdmi *rk616_hdmi;
- rk616_hdmi = container_of(hdmi, struct rk616_hdmi, g_hdmi);
+ int ret;
+ struct mfd_rk616 *rk616_drv = hdmi_dev->rk616_drv;
- ret = rk616_hdmi->rk616_drv->write_dev(rk616_hdmi->rk616_drv, (RK616_HDMI_BASE + ((offset)<<2)), &val);
- return ret;
+ ret = rk616_drv->write_dev(rk616_drv,
+ (RK616_HDMI_BASE + ((offset) << 2)), &val);
+ return ret;
}
-static inline int hdmi_msk_reg(u16 offset, u32 msk, u32 val)
+static inline int hdmi_msk_reg(struct rk_hdmi_device *hdmi_dev, u16 offset,
+ u32 msk, u32 val)
{
- int ret;
- struct rk616_hdmi *rk616_hdmi;
- rk616_hdmi = container_of(hdmi, struct rk616_hdmi, g_hdmi);
+ int ret;
+ struct mfd_rk616 *rk616_drv = hdmi_dev->rk616_drv;
- ret = rk616_hdmi->rk616_drv->write_dev_bits(rk616_hdmi->rk616_drv, (RK616_HDMI_BASE + ((offset)<<2)), msk, &val);
- return ret;
+ ret = rk616_drv->write_dev_bits(rk616_drv,
+ (RK616_HDMI_BASE + ((offset) << 2)),
+ msk, &val);
+ return ret;
}
#else
-static inline int hdmi_readl(u16 offset, u32 *val)
+static inline int hdmi_readl(struct rk_hdmi_device *hdmi_dev, u16 offset,
+ u32 *val)
{
- int ret = 0;
- *val = readl_relaxed(hdmi->regbase + (offset) * 0x04);
- return ret;
+ int ret = 0;
+
+ *val = readl_relaxed(hdmi_dev->regbase + (offset) * 0x04);
+ return ret;
}
-static inline int hdmi_writel(u16 offset, u32 val)
+static inline int hdmi_writel(struct rk_hdmi_device *hdmi_dev, u16 offset,
+ u32 val)
{
- int ret = 0;
- writel_relaxed(val, hdmi->regbase + (offset) * 0x04);
- return ret;
+ int ret = 0;
+
+ writel_relaxed(val, hdmi_dev->regbase + (offset) * 0x04);
+ return ret;
}
-static inline int hdmi_msk_reg(u16 offset, u32 msk, u32 val)
+static inline int hdmi_msk_reg(struct rk_hdmi_device *hdmi_dev, u16 offset,
+ u32 msk, u32 val)
{
- int ret = 0;
- u32 temp;
- temp = readl_relaxed(hdmi->regbase + (offset) * 0x04) & (0xFF - (msk));
- writel_relaxed(temp | ( (val) & (msk) ), hdmi->regbase + (offset) * 0x04);
- return ret;
+ int ret = 0;
+ u32 temp;
+
+ temp = readl_relaxed(hdmi->regbase + (offset) * 0x04) & (0xFF - (msk));
+ writel_relaxed(temp | ((val) & (msk)), hdmi->regbase + (offset) * 0x04);
+ return ret;
}
+
static inline void rk3028_hdmi_reset_pclk(void)
{
- writel_relaxed(0x00010001,RK2928_CRU_BASE+ 0x128);
- msleep(100);
- writel_relaxed(0x00010000, RK2928_CRU_BASE + 0x128);
+ writel_relaxed(0x00010001, RK2928_CRU_BASE + 0x128);
+ msleep(100);
+ writel_relaxed(0x00010000, RK2928_CRU_BASE + 0x128);
}
#endif
extern int rk616_hdmi_initial(struct hdmi *hdmi);
extern void rk616_hdmi_work(struct hdmi *hdmi);
-
#endif