/*
|
* Allwinner SoCs tv driver.
|
*
|
* Copyright (C) 2016 Allwinner.
|
*
|
* This file is licensed under the terms of the GNU General Public
|
* License version 2. This program is licensed "as is" without any
|
* warranty of any kind, whether express or implied.
|
*/
|
|
#include "tv_ac200.h"
|
#include "tv_ac200_lowlevel.h"
|
|
static s32 aw1683_wr_reg(u16 addr, u16 val)
|
{
|
return acx00_reg_write(tv_priv.acx00, addr, val);
|
}
|
|
static s32 aw1683_rd_reg(u16 addr, u16 *val)
|
{
|
*val = acx00_reg_read(tv_priv.acx00, addr);
|
return 0;
|
}
|
|
|
s32 aw1683_tve_init(const u16 *p_dac_cali)
|
{
|
u16 data;
|
|
if (p_dac_cali == NULL)
|
return -1;
|
|
/* clk for tve */
|
aw1683_wr_reg(0x001a, 0x0003);
|
aw1683_wr_reg(0x0040, 0x0702);
|
aw1683_wr_reg(0x000c, 0x4e01);
|
aw1683_wr_reg(0x000c, 0xce01);
|
aw1683_wr_reg(0x0018, 0x0001);
|
aw1683_wr_reg(0x0018, 0x000f);
|
|
/* sid for tve */
|
if (*p_dac_cali == 0)
|
aw1683_rd_reg(0x8002, &data);
|
else
|
data = *p_dac_cali;
|
if (data == 0)
|
aw1683_wr_reg(0x4306, 0x28f);
|
else if (data < 0x3f5 && data > 0)
|
aw1683_wr_reg(0x4306, data + 10);
|
else
|
aw1683_wr_reg(0x4306, data);
|
|
/* tve anto check */
|
aw1683_wr_reg(0x4008, 0x12a0);
|
aw1683_wr_reg(0x400a, 0x4300);
|
aw1683_wr_reg(0x40f4, 0x0230);
|
aw1683_wr_reg(0x40f8, 0x0064);
|
aw1683_wr_reg(0x40fa, 0x0c80);
|
aw1683_wr_reg(0x4040, 0x0002);
|
aw1683_wr_reg(0x4030, 0x0001);
|
|
return 0;
|
}
|
|
s32 aw1683_tve_plug_status(void)
|
{
|
u16 data;
|
|
aw1683_rd_reg(0x4038, &data);
|
return (data & 0x3);
|
}
|
|
s32 aw1683_tve_set_mode(u32 mode)
|
{
|
u32 inter = 0;
|
u32 ccir = 1;
|
u32 m = (mode == 11) ? 1:0;
|
u32 c = ccir ? 2:3;
|
u32 i = inter;
|
u32 x = tv_video_timing[m].x_res;
|
u32 y = tv_video_timing[m].y_res/(i+1);
|
u32 hbp = (tv_video_timing[m].hor_back_porch
|
+tv_video_timing[m].hor_sync_time) * c;
|
u32 vbp = (tv_video_timing[m].ver_back_porch
|
+tv_video_timing[m].ver_sync_time);
|
u32 syuv = ccir ? 0:1;
|
/* u32 resync_pixels = 0x7b*c; */
|
|
aw1683_wr_reg(0x5000, syuv);
|
aw1683_wr_reg(0x5008, hbp-1);
|
aw1683_wr_reg(0x500a, x*c-1);
|
aw1683_wr_reg(0x500c, vbp-1);
|
aw1683_wr_reg(0x500e, y-1);
|
aw1683_wr_reg(0x5016, vbp-1+i);
|
aw1683_wr_reg(0x5010, 0x0000);
|
aw1683_wr_reg(0x5012, 0x0004);
|
|
if (mode == 14) {
|
aw1683_wr_reg(0x4002, 0x8000);
|
aw1683_wr_reg(0x4004, 0x0000);
|
aw1683_wr_reg(0x4006, 0x0707);
|
/* aw1683_wr_reg(0x4008, 0x0001); */
|
aw1683_wr_reg(0x400a, 0x4300);
|
aw1683_wr_reg(0x400c, 0x1400);
|
aw1683_wr_reg(0x400e, 0x3000);
|
aw1683_wr_reg(0x4010, 0x7c1f);
|
aw1683_wr_reg(0x4012, 0x21f0);
|
aw1683_wr_reg(0x4014, 0x0020);
|
aw1683_wr_reg(0x4016, 0x0076);
|
aw1683_wr_reg(0x4018, 0x0016);
|
aw1683_wr_reg(0x401a, 0x0000);
|
aw1683_wr_reg(0x401c, 0x020d);
|
aw1683_wr_reg(0x401e, 0x0016);
|
aw1683_wr_reg(0x4020, 0x011a);
|
aw1683_wr_reg(0x4022, 0x00f0);
|
aw1683_wr_reg(0x4100, 0x0001);
|
aw1683_wr_reg(0x4102, 0x0000);
|
aw1683_wr_reg(0x4104, 0x0000);
|
aw1683_wr_reg(0x4106, 0x0000);
|
aw1683_wr_reg(0x4108, 0x0002);
|
aw1683_wr_reg(0x410a, 0x0000);
|
aw1683_wr_reg(0x410c, 0x004f);
|
aw1683_wr_reg(0x410e, 0x0000);
|
aw1683_wr_reg(0x4110, 0x0000);
|
aw1683_wr_reg(0x4112, 0x0000);
|
aw1683_wr_reg(0x4114, 0x447e);
|
aw1683_wr_reg(0x4116, 0x0016);
|
aw1683_wr_reg(0x4118, 0xa0a0);
|
aw1683_wr_reg(0x411a, 0x0000);
|
aw1683_wr_reg(0x411c, 0x00f0);
|
aw1683_wr_reg(0x411e, 0x0010);
|
aw1683_wr_reg(0x4120, 0x0320);
|
aw1683_wr_reg(0x4122, 0x01e8);
|
aw1683_wr_reg(0x4124, 0x05a0);
|
aw1683_wr_reg(0x4126, 0x0000);
|
aw1683_wr_reg(0x4128, 0x0000);
|
aw1683_wr_reg(0x412a, 0x0001);
|
aw1683_wr_reg(0x412c, 0x0101);
|
aw1683_wr_reg(0x412e, 0x0000);
|
/* aw1683_wr_reg(0x4130, 0x0000); */
|
/* aw1683_wr_reg(0x4132, 0x3016); */
|
aw1683_wr_reg(0x4134, 0x0000);
|
aw1683_wr_reg(0x4136, 0x0000);
|
aw1683_wr_reg(0x4138, 0x0000);
|
aw1683_wr_reg(0x413a, 0x0000);
|
aw1683_wr_reg(0x413c, 0x0000);
|
aw1683_wr_reg(0x413e, 0x0000);
|
aw1683_wr_reg(0x5014, 0x0100);
|
aw1683_wr_reg(0x4130, 0x0000);
|
aw1683_wr_reg(0x4132, 0x2004); /* 2004 */
|
aw1683_wr_reg(0x4000, 0x0300);
|
} else {
|
aw1683_wr_reg(0x4002, 0x8000);
|
aw1683_wr_reg(0x4004, 0x0001);
|
aw1683_wr_reg(0x4006, 0x0707);
|
/* aw1683_wr_reg(0x4008, 0x0001); */
|
aw1683_wr_reg(0x400a, 0x4300);
|
aw1683_wr_reg(0x400c, 0x1400);
|
aw1683_wr_reg(0x400e, 0x3000);
|
aw1683_wr_reg(0x4010, 0x8acb);
|
aw1683_wr_reg(0x4012, 0x2a09);
|
aw1683_wr_reg(0x4014, 0x0018);
|
aw1683_wr_reg(0x4016, 0x008a);
|
aw1683_wr_reg(0x4018, 0x0016);
|
aw1683_wr_reg(0x401a, 0x0000);
|
aw1683_wr_reg(0x401c, 0x0271);
|
aw1683_wr_reg(0x401e, 0x0016);
|
aw1683_wr_reg(0x4020, 0x00fc);
|
aw1683_wr_reg(0x4022, 0x00fc);
|
aw1683_wr_reg(0x4100, 0x0000);
|
aw1683_wr_reg(0x4102, 0x0000);
|
aw1683_wr_reg(0x4104, 0x0001);
|
aw1683_wr_reg(0x4106, 0x0000);
|
aw1683_wr_reg(0x4108, 0x0005);
|
aw1683_wr_reg(0x410a, 0x0000);
|
aw1683_wr_reg(0x410c, 0x2929);
|
aw1683_wr_reg(0x410e, 0x0000);
|
aw1683_wr_reg(0x4110, 0x0000);
|
aw1683_wr_reg(0x4112, 0x0000);
|
aw1683_wr_reg(0x4114, 0x447e);
|
aw1683_wr_reg(0x4116, 0x0016);
|
aw1683_wr_reg(0x4118, 0xabab);
|
aw1683_wr_reg(0x411a, 0x0000);
|
aw1683_wr_reg(0x411c, 0x00fc);
|
aw1683_wr_reg(0x411e, 0x0010);
|
aw1683_wr_reg(0x4120, 0x0320);
|
aw1683_wr_reg(0x4122, 0x01e8);
|
aw1683_wr_reg(0x4124, 0x05a0);
|
aw1683_wr_reg(0x4126, 0x0000);
|
aw1683_wr_reg(0x4128, 0x0000);
|
aw1683_wr_reg(0x412a, 0x0001);
|
aw1683_wr_reg(0x412c, 0x0101);
|
aw1683_wr_reg(0x412e, 0x0000);
|
/* aw1683_wr_reg(0x4130, 0x0380); */
|
/* aw1683_wr_reg(0x4132, 0x3009); */
|
aw1683_wr_reg(0x4134, 0x0000);
|
aw1683_wr_reg(0x4136, 0x0000);
|
aw1683_wr_reg(0x4138, 0x0000);
|
aw1683_wr_reg(0x413a, 0x0000);
|
aw1683_wr_reg(0x413c, 0x0000);
|
aw1683_wr_reg(0x413e, 0x0000);
|
aw1683_wr_reg(0x43a0, 0x0001);
|
aw1683_wr_reg(0x43a2, 0x0003);
|
aw1683_wr_reg(0x5014, 0x2149);
|
aw1683_wr_reg(0x4130, 0x0380);
|
aw1683_wr_reg(0x4132, 0x2009); /* 2004 */
|
aw1683_wr_reg(0x4000, 0x0300);
|
}
|
|
/* aw1683_wr_bits(0x4000,0x0,0x1); */
|
/* aw1683_wr_reg(0x4000,0x0301); */
|
|
return 0;
|
}
|
|
s32 aw1683_tve_open(void)
|
{
|
u16 data;
|
|
aw1683_wr_reg(0x4008, 0x02a1);
|
aw1683_wr_reg(0x4000, 0x0301);
|
aw1683_rd_reg(0x4008, &data);
|
if (data != 0x02a1)
|
return -1;
|
aw1683_rd_reg(0x4000, &data);
|
if (data != 0x0301)
|
return -1;
|
|
return 0;
|
}
|
|
s32 aw1683_tve_close(void)
|
{
|
aw1683_wr_reg(0x4000, 0x0300);
|
aw1683_wr_reg(0x4008, 0x02a0);
|
|
return 0;
|
}
|
|
#if 0
|
s32 aw1683_tve(void)
|
{
|
s32 mode = 1;
|
s32 inter = 0;
|
s32 ccir = 1;
|
|
aw1673_video_rgb(mode, inter, ccir);
|
aw1683_tve_init();
|
aw1683_tve_set_mode(mode);
|
aw1683_tve_open();
|
|
while (1) {
|
aw1683_tve_close();
|
mode = 0;
|
aw1673_video_rgb(mode, inter, ccir);
|
aw1683_tve_set_mode(mode);
|
aw1683_tve_open();
|
|
aw1683_tve_close();
|
mode = 1;
|
aw1673_video_rgb(mode, inter, ccir);
|
aw1683_tve_set_mode(mode);
|
aw1683_tve_open();
|
}
|
|
return RET_OK;
|
}
|
#endif
|
|
s32 aw1683_enable_chip(void)
|
{
|
aw1683_wr_reg(0x0002, 0x0001);
|
return 0;
|
}
|