提交 11e18475 编写于 作者: F Florian Tobias Schandinat

Merge branch 'viafb-next' of git://github.com/schandinat/linux-2.6 into fbdev-next

......@@ -6,4 +6,7 @@ obj-$(CONFIG_FB_VIA) += viafb.o
viafb-y :=viafbdev.o hw.o via_i2c.o dvi.o lcd.o ioctl.o accel.o \
via_utility.o vt1636.o global.o tblDPASetting.o viamode.o \
via-core.o via-gpio.o via_modesetting.o via_clock.o
via-core.o via-gpio.o via_modesetting.o via_clock.o \
via_aux.o via_aux_edid.o via_aux_vt1636.o via_aux_vt1632.o \
via_aux_vt1631.o via_aux_vt1625.o via_aux_vt1622.o via_aux_vt1621.o \
via_aux_sii164.o via_aux_ch7301.o
......@@ -146,9 +146,6 @@ struct tmds_setting_information {
struct lvds_setting_information {
int iga_path;
int h_active;
int v_active;
int bpp;
int lcd_panel_hres;
int lcd_panel_vres;
int display_method;
......
......@@ -172,10 +172,11 @@ static int tmds_register_read_bytes(int index, u8 *buff, int buff_len)
}
/* DVI Set Mode */
void viafb_dvi_set_mode(const struct fb_var_screeninfo *var, int iga)
void viafb_dvi_set_mode(const struct fb_var_screeninfo *var,
u16 cxres, u16 cyres, int iga)
{
struct fb_var_screeninfo dvi_var = *var;
struct crt_mode_table *rb_mode;
const struct fb_videomode *rb_mode;
int maxPixelClock;
maxPixelClock = viaparinfo->shared->tmds_setting_info.max_pixel_clock;
......@@ -185,7 +186,7 @@ void viafb_dvi_set_mode(const struct fb_var_screeninfo *var, int iga)
viafb_fill_var_timing_info(&dvi_var, rb_mode);
}
viafb_fill_crtc_timing(&dvi_var, iga);
viafb_fill_crtc_timing(&dvi_var, cxres, cyres, iga);
}
/* Sense DVI Connector */
......
......@@ -59,6 +59,7 @@ void viafb_dvi_enable(void);
bool __devinit viafb_tmds_trasmitter_identify(void);
void __devinit viafb_init_dvi_size(struct tmds_chip_information *tmds_chip,
struct tmds_setting_information *tmds_setting);
void viafb_dvi_set_mode(const struct fb_var_screeninfo *var, int iga);
void viafb_dvi_set_mode(const struct fb_var_screeninfo *var,
u16 cxres, u16 cyres, int iga);
#endif /* __DVI_H__ */
......@@ -1467,28 +1467,32 @@ void viafb_set_vclock(u32 clk, int set_iga)
via_write_misc_reg_mask(0x0C, 0x0C); /* select external clock */
}
static struct display_timing var_to_timing(const struct fb_var_screeninfo *var)
struct display_timing var_to_timing(const struct fb_var_screeninfo *var,
u16 cxres, u16 cyres)
{
struct display_timing timing;
u16 dx = (var->xres - cxres) / 2, dy = (var->yres - cyres) / 2;
timing.hor_addr = var->xres;
timing.hor_sync_start = timing.hor_addr + var->right_margin;
timing.hor_addr = cxres;
timing.hor_sync_start = timing.hor_addr + var->right_margin + dx;
timing.hor_sync_end = timing.hor_sync_start + var->hsync_len;
timing.hor_total = timing.hor_sync_end + var->left_margin;
timing.hor_blank_start = timing.hor_addr;
timing.hor_blank_end = timing.hor_total;
timing.ver_addr = var->yres;
timing.ver_sync_start = timing.ver_addr + var->lower_margin;
timing.hor_total = timing.hor_sync_end + var->left_margin + dx;
timing.hor_blank_start = timing.hor_addr + dx;
timing.hor_blank_end = timing.hor_total - dx;
timing.ver_addr = cyres;
timing.ver_sync_start = timing.ver_addr + var->lower_margin + dy;
timing.ver_sync_end = timing.ver_sync_start + var->vsync_len;
timing.ver_total = timing.ver_sync_end + var->upper_margin;
timing.ver_blank_start = timing.ver_addr;
timing.ver_blank_end = timing.ver_total;
timing.ver_total = timing.ver_sync_end + var->upper_margin + dy;
timing.ver_blank_start = timing.ver_addr + dy;
timing.ver_blank_end = timing.ver_total - dy;
return timing;
}
void viafb_fill_crtc_timing(const struct fb_var_screeninfo *var, int iga)
void viafb_fill_crtc_timing(const struct fb_var_screeninfo *var,
u16 cxres, u16 cyres, int iga)
{
struct display_timing crt_reg = var_to_timing(var);
struct display_timing crt_reg = var_to_timing(var,
cxres ? cxres : var->xres, cyres ? cyres : var->yres);
if (iga == IGA1)
via_set_primary_timing(&crt_reg);
......@@ -1526,13 +1530,6 @@ void viafb_update_device_setting(int hres, int vres, int bpp, int flag)
if (flag == 0) {
viaparinfo->tmds_setting_info->h_active = hres;
viaparinfo->tmds_setting_info->v_active = vres;
viaparinfo->lvds_setting_info->h_active = hres;
viaparinfo->lvds_setting_info->v_active = vres;
viaparinfo->lvds_setting_info->bpp = bpp;
viaparinfo->lvds_setting_info2->h_active = hres;
viaparinfo->lvds_setting_info2->v_active = vres;
viaparinfo->lvds_setting_info2->bpp = bpp;
} else {
if (viaparinfo->tmds_setting_info->iga_path == IGA2) {
......@@ -1540,16 +1537,6 @@ void viafb_update_device_setting(int hres, int vres, int bpp, int flag)
viaparinfo->tmds_setting_info->v_active = vres;
}
if (viaparinfo->lvds_setting_info->iga_path == IGA2) {
viaparinfo->lvds_setting_info->h_active = hres;
viaparinfo->lvds_setting_info->v_active = vres;
viaparinfo->lvds_setting_info->bpp = bpp;
}
if (IGA2 == viaparinfo->lvds_setting_info2->iga_path) {
viaparinfo->lvds_setting_info2->h_active = hres;
viaparinfo->lvds_setting_info2->v_active = vres;
viaparinfo->lvds_setting_info2->bpp = bpp;
}
}
}
......@@ -1758,13 +1745,13 @@ static void set_display_channel(void)
}
}
static u8 get_sync(struct fb_info *info)
static u8 get_sync(struct fb_var_screeninfo *var)
{
u8 polarity = 0;
if (!(info->var.sync & FB_SYNC_HOR_HIGH_ACT))
if (!(var->sync & FB_SYNC_HOR_HIGH_ACT))
polarity |= VIA_HSYNC_NEGATIVE;
if (!(info->var.sync & FB_SYNC_VERT_HIGH_ACT))
if (!(var->sync & FB_SYNC_VERT_HIGH_ACT))
polarity |= VIA_VSYNC_NEGATIVE;
return polarity;
}
......@@ -1844,9 +1831,9 @@ static void hw_init(void)
load_fix_bit_crtc_reg();
}
int viafb_setmode(int video_bpp, int video_bpp1)
int viafb_setmode(void)
{
int j;
int j, cxres = 0, cyres = 0;
int port;
u32 devices = viaparinfo->shared->iga1_devices
| viaparinfo->shared->iga2_devices;
......@@ -1895,6 +1882,8 @@ int viafb_setmode(int video_bpp, int video_bpp1)
} else if (viafb_SAMM_ON) {
viafb_fill_var_timing_info(&var2, viafb_get_best_mode(
viafb_second_xres, viafb_second_yres, viafb_refresh1));
cxres = viafbinfo->var.xres;
cyres = viafbinfo->var.yres;
var2.bits_per_pixel = viafbinfo->var.bits_per_pixel;
}
......@@ -1902,9 +1891,9 @@ int viafb_setmode(int video_bpp, int video_bpp1)
if (viafb_CRT_ON) {
if (viaparinfo->shared->iga2_devices & VIA_CRT
&& viafb_SAMM_ON)
viafb_fill_crtc_timing(&var2, IGA2);
viafb_fill_crtc_timing(&var2, cxres, cyres, IGA2);
else
viafb_fill_crtc_timing(&viafbinfo->var,
viafb_fill_crtc_timing(&viafbinfo->var, 0, 0,
(viaparinfo->shared->iga1_devices & VIA_CRT)
? IGA1 : IGA2);
......@@ -1922,17 +1911,17 @@ int viafb_setmode(int video_bpp, int video_bpp1)
if (viafb_DVI_ON) {
if (viaparinfo->shared->tmds_setting_info.iga_path == IGA2
&& viafb_SAMM_ON)
viafb_dvi_set_mode(&var2, IGA2);
viafb_dvi_set_mode(&var2, cxres, cyres, IGA2);
else
viafb_dvi_set_mode(&viafbinfo->var,
viafb_dvi_set_mode(&viafbinfo->var, 0, 0,
viaparinfo->tmds_setting_info->iga_path);
}
if (viafb_LCD_ON) {
if (viafb_SAMM_ON &&
(viaparinfo->lvds_setting_info->iga_path == IGA2)) {
viaparinfo->lvds_setting_info->bpp = video_bpp1;
viafb_lcd_set_mode(viaparinfo->lvds_setting_info,
viafb_lcd_set_mode(&var2, cxres, cyres,
viaparinfo->lvds_setting_info,
&viaparinfo->chip_info->lvds_chip_info);
} else {
/* IGA1 doesn't have LCD scaling, so set it center. */
......@@ -1940,16 +1929,16 @@ int viafb_setmode(int video_bpp, int video_bpp1)
viaparinfo->lvds_setting_info->display_method =
LCD_CENTERING;
}
viaparinfo->lvds_setting_info->bpp = video_bpp;
viafb_lcd_set_mode(viaparinfo->lvds_setting_info,
viafb_lcd_set_mode(&viafbinfo->var, 0, 0,
viaparinfo->lvds_setting_info,
&viaparinfo->chip_info->lvds_chip_info);
}
}
if (viafb_LCD2_ON) {
if (viafb_SAMM_ON &&
(viaparinfo->lvds_setting_info2->iga_path == IGA2)) {
viaparinfo->lvds_setting_info2->bpp = video_bpp1;
viafb_lcd_set_mode(viaparinfo->lvds_setting_info2,
viafb_lcd_set_mode(&var2, cxres, cyres,
viaparinfo->lvds_setting_info2,
&viaparinfo->chip_info->lvds_chip_info2);
} else {
/* IGA1 doesn't have LCD scaling, so set it center. */
......@@ -1957,8 +1946,8 @@ int viafb_setmode(int video_bpp, int video_bpp1)
viaparinfo->lvds_setting_info2->display_method =
LCD_CENTERING;
}
viaparinfo->lvds_setting_info2->bpp = video_bpp;
viafb_lcd_set_mode(viaparinfo->lvds_setting_info2,
viafb_lcd_set_mode(&viafbinfo->var, 0, 0,
viaparinfo->lvds_setting_info2,
&viaparinfo->chip_info->lvds_chip_info2);
}
}
......@@ -1971,7 +1960,7 @@ int viafb_setmode(int video_bpp, int video_bpp1)
if (!viafb_hotplug) {
viafb_hotplug_Xres = viafbinfo->var.xres;
viafb_hotplug_Yres = viafbinfo->var.yres;
viafb_hotplug_bpp = video_bpp;
viafb_hotplug_bpp = viafbinfo->var.bits_per_pixel;
viafb_hotplug_refresh = viafb_refresh;
if (viafb_DVI_ON)
......@@ -1980,13 +1969,13 @@ int viafb_setmode(int video_bpp, int video_bpp1)
viafb_DeviceStatus = CRT_Device;
}
device_on();
if (!viafb_dual_fb)
via_set_sync_polarity(devices, get_sync(viafbinfo));
if (!viafb_SAMM_ON)
via_set_sync_polarity(devices, get_sync(&viafbinfo->var));
else {
via_set_sync_polarity(viaparinfo->shared->iga1_devices,
get_sync(viafbinfo));
get_sync(&viafbinfo->var));
via_set_sync_polarity(viaparinfo->shared->iga2_devices,
get_sync(viafbinfo1));
get_sync(&var2));
}
clock.set_engine_pll_state(VIA_STATE_ON);
......@@ -2023,20 +2012,20 @@ int viafb_setmode(int video_bpp, int video_bpp1)
int viafb_get_refresh(int hres, int vres, u32 long_refresh)
{
struct crt_mode_table *best;
const struct fb_videomode *best;
best = viafb_get_best_mode(hres, vres, long_refresh);
if (!best)
return 60;
if (abs(best->refresh_rate - long_refresh) > 3) {
if (abs(best->refresh - long_refresh) > 3) {
if (hres == 1200 && vres == 900)
return 49; /* OLPC DCON only supports 50 Hz */
else
return 60;
}
return best->refresh_rate;
return best->refresh;
}
static void device_off(void)
......@@ -2129,26 +2118,17 @@ void viafb_set_dpa_gfx(int output_interface, struct GFX_DPA_SETTING\
}
}
/*According var's xres, yres fill var's other timing information*/
void viafb_fill_var_timing_info(struct fb_var_screeninfo *var,
struct crt_mode_table *mode)
const struct fb_videomode *mode)
{
struct display_timing crt_reg;
crt_reg = mode->crtc;
var->pixclock = 1000000000 / (crt_reg.hor_total * crt_reg.ver_total)
* 1000 / mode->refresh_rate;
var->left_margin =
crt_reg.hor_total - (crt_reg.hor_sync_start + crt_reg.hor_sync_end);
var->right_margin = crt_reg.hor_sync_start - crt_reg.hor_addr;
var->hsync_len = crt_reg.hor_sync_end;
var->upper_margin =
crt_reg.ver_total - (crt_reg.ver_sync_start + crt_reg.ver_sync_end);
var->lower_margin = crt_reg.ver_sync_start - crt_reg.ver_addr;
var->vsync_len = crt_reg.ver_sync_end;
var->sync = 0;
if (mode->h_sync_polarity == POSITIVE)
var->sync |= FB_SYNC_HOR_HIGH_ACT;
if (mode->v_sync_polarity == POSITIVE)
var->sync |= FB_SYNC_VERT_HIGH_ACT;
var->pixclock = mode->pixclock;
var->xres = mode->xres;
var->yres = mode->yres;
var->left_margin = mode->left_margin;
var->right_margin = mode->right_margin;
var->hsync_len = mode->hsync_len;
var->upper_margin = mode->upper_margin;
var->lower_margin = mode->lower_margin;
var->vsync_len = mode->vsync_len;
var->sync = mode->sync;
}
......@@ -637,7 +637,10 @@ extern int viafb_LCD_ON;
extern int viafb_DVI_ON;
extern int viafb_hotplug;
void viafb_fill_crtc_timing(const struct fb_var_screeninfo *var, int iga);
struct display_timing var_to_timing(const struct fb_var_screeninfo *var,
u16 cxres, u16 cyres);
void viafb_fill_crtc_timing(const struct fb_var_screeninfo *var,
u16 cxres, u16 cyres, int iga);
void viafb_set_vclock(u32 CLK, int set_iga);
void viafb_load_reg(int timing_value, int viafb_load_reg_num,
struct io_register *reg,
......@@ -657,9 +660,9 @@ void viafb_load_FIFO_reg(int set_iga, int hor_active, int ver_active);
void viafb_set_dpa_gfx(int output_interface, struct GFX_DPA_SETTING\
*p_gfx_dpa_setting);
int viafb_setmode(int video_bpp, int video_bpp1);
int viafb_setmode(void);
void viafb_fill_var_timing_info(struct fb_var_screeninfo *var,
struct crt_mode_table *mode);
const struct fb_videomode *mode);
void __devinit viafb_init_chip_info(int chip_type);
void __devinit viafb_init_dac(int set_iga);
int viafb_get_refresh(int hres, int vres, u32 float_refresh);
......
......@@ -53,10 +53,6 @@ static void __devinit fp_id_to_vindex(int panel_id);
static int lvds_register_read(int index);
static void load_lcd_scaling(int set_hres, int set_vres, int panel_hres,
int panel_vres);
static void via_pitch_alignment_patch_lcd(
struct lvds_setting_information *plvds_setting_info,
struct lvds_chip_information
*plvds_chip_info);
static void lcd_patch_skew_dvp0(struct lvds_setting_information
*plvds_setting_info,
struct lvds_chip_information *plvds_chip_info);
......@@ -79,9 +75,6 @@ static void check_diport_of_integrated_lvds(
struct lvds_chip_information *plvds_chip_info,
struct lvds_setting_information
*plvds_setting_info);
static struct display_timing lcd_centering_timging(struct display_timing
mode_crt_reg,
struct display_timing panel_crt_reg);
static inline bool check_lvds_chip(int device_id_subaddr, int device_id)
{
......@@ -454,20 +447,17 @@ static void load_lcd_scaling(int set_hres, int set_vres, int panel_hres,
}
}
static void via_pitch_alignment_patch_lcd(
struct lvds_setting_information *plvds_setting_info,
struct lvds_chip_information
*plvds_chip_info)
static void via_pitch_alignment_patch_lcd(int iga_path, int hres, int bpp)
{
unsigned char cr13, cr35, cr65, cr66, cr67;
unsigned long dwScreenPitch = 0;
unsigned long dwPitch;
dwPitch = plvds_setting_info->h_active * (plvds_setting_info->bpp >> 3);
dwPitch = hres * (bpp >> 3);
if (dwPitch & 0x1F) {
dwScreenPitch = ((dwPitch + 31) & ~31) >> 3;
if (plvds_setting_info->iga_path == IGA2) {
if (plvds_setting_info->bpp > 8) {
if (iga_path == IGA2) {
if (bpp > 8) {
cr66 = (unsigned char)(dwScreenPitch & 0xFF);
viafb_write_reg(CR66, VIACR, cr66);
cr67 = viafb_read_reg(VIACR, CR67) & 0xFC;
......@@ -485,7 +475,7 @@ static void via_pitch_alignment_patch_lcd(
cr65 += 2;
viafb_write_reg(CR65, VIACR, cr65);
} else {
if (plvds_setting_info->bpp > 8) {
if (bpp > 8) {
cr13 = (unsigned char)(dwScreenPitch & 0xFF);
viafb_write_reg(CR13, VIACR, cr13);
cr35 = viafb_read_reg(VIACR, CR35) & 0x1F;
......@@ -548,49 +538,45 @@ static void lcd_patch_skew(struct lvds_setting_information
}
/* LCD Set Mode */
void viafb_lcd_set_mode(struct lvds_setting_information *plvds_setting_info,
void viafb_lcd_set_mode(const struct fb_var_screeninfo *var, u16 cxres,
u16 cyres, struct lvds_setting_information *plvds_setting_info,
struct lvds_chip_information *plvds_chip_info)
{
int set_iga = plvds_setting_info->iga_path;
int mode_bpp = plvds_setting_info->bpp;
int set_hres = plvds_setting_info->h_active;
int set_vres = plvds_setting_info->v_active;
int mode_bpp = var->bits_per_pixel;
int set_hres = cxres ? cxres : var->xres;
int set_vres = cyres ? cyres : var->yres;
int panel_hres = plvds_setting_info->lcd_panel_hres;
int panel_vres = plvds_setting_info->lcd_panel_vres;
u32 clock;
struct display_timing mode_crt_reg, panel_crt_reg, timing;
struct crt_mode_table *mode_crt_table, *panel_crt_table;
struct display_timing timing;
struct fb_var_screeninfo panel_var;
const struct fb_videomode *mode_crt_table, *panel_crt_table;
DEBUG_MSG(KERN_INFO "viafb_lcd_set_mode!!\n");
/* Get mode table */
mode_crt_table = viafb_get_best_mode(set_hres, set_vres, 60);
mode_crt_reg = mode_crt_table->crtc;
/* Get panel table Pointer */
panel_crt_table = viafb_get_best_mode(panel_hres, panel_vres, 60);
panel_crt_reg = panel_crt_table->crtc;
viafb_fill_var_timing_info(&panel_var, panel_crt_table);
DEBUG_MSG(KERN_INFO "bellow viafb_lcd_set_mode!!\n");
if (VT1636_LVDS == plvds_chip_info->lvds_chip_name)
viafb_init_lvds_vt1636(plvds_setting_info, plvds_chip_info);
clock = panel_crt_reg.hor_total * panel_crt_reg.ver_total
* panel_crt_table->refresh_rate;
clock = PICOS2KHZ(panel_crt_table->pixclock) * 1000;
plvds_setting_info->vclk = clock;
if (set_iga == IGA2 && (set_hres < panel_hres || set_vres < panel_vres)
&& plvds_setting_info->display_method == LCD_EXPANDSION) {
timing = panel_crt_reg;
timing = var_to_timing(&panel_var, panel_hres, panel_vres);
load_lcd_scaling(set_hres, set_vres, panel_hres, panel_vres);
} else {
timing = lcd_centering_timging(mode_crt_reg, panel_crt_reg);
timing = var_to_timing(&panel_var, set_hres, set_vres);
if (set_iga == IGA2)
/* disable scaling */
via_write_reg_mask(VIACR, 0x79, 0x00,
BIT0 + BIT1 + BIT2);
}
timing.hor_blank_end += timing.hor_blank_start;
timing.hor_sync_end += timing.hor_sync_start;
timing.ver_blank_end += timing.ver_blank_start;
timing.ver_sync_end += timing.ver_sync_start;
if (set_iga == IGA1)
via_set_primary_timing(&timing);
else if (set_iga == IGA2)
......@@ -613,7 +599,8 @@ void viafb_lcd_set_mode(struct lvds_setting_information *plvds_setting_info,
viafb_write_reg_mask(CR6A, VIACR, 0x01, BIT0);
/* Patch for non 32bit alignment mode */
via_pitch_alignment_patch_lcd(plvds_setting_info, plvds_chip_info);
via_pitch_alignment_patch_lcd(plvds_setting_info->iga_path, set_hres,
var->bits_per_pixel);
}
static void integrated_lvds_disable(struct lvds_setting_information
......@@ -973,37 +960,6 @@ void __devinit viafb_init_lvds_output_interface(struct lvds_chip_information
}
}
static struct display_timing lcd_centering_timging(struct display_timing
mode_crt_reg,
struct display_timing panel_crt_reg)
{
struct display_timing crt_reg;
crt_reg.hor_total = panel_crt_reg.hor_total;
crt_reg.hor_addr = mode_crt_reg.hor_addr;
crt_reg.hor_blank_start =
(panel_crt_reg.hor_addr - mode_crt_reg.hor_addr) / 2 +
crt_reg.hor_addr;
crt_reg.hor_blank_end = panel_crt_reg.hor_blank_end;
crt_reg.hor_sync_start =
(panel_crt_reg.hor_sync_start -
panel_crt_reg.hor_blank_start) + crt_reg.hor_blank_start;
crt_reg.hor_sync_end = panel_crt_reg.hor_sync_end;
crt_reg.ver_total = panel_crt_reg.ver_total;
crt_reg.ver_addr = mode_crt_reg.ver_addr;
crt_reg.ver_blank_start =
(panel_crt_reg.ver_addr - mode_crt_reg.ver_addr) / 2 +
crt_reg.ver_addr;
crt_reg.ver_blank_end = panel_crt_reg.ver_blank_end;
crt_reg.ver_sync_start =
(panel_crt_reg.ver_sync_start -
panel_crt_reg.ver_blank_start) + crt_reg.ver_blank_start;
crt_reg.ver_sync_end = panel_crt_reg.ver_sync_end;
return crt_reg;
}
bool viafb_lcd_get_mobile_state(bool *mobile)
{
unsigned char __iomem *romptr, *tableptr, *biosptr;
......
......@@ -76,7 +76,8 @@ void __devinit viafb_init_lvds_output_interface(struct lvds_chip_information
*plvds_chip_info,
struct lvds_setting_information
*plvds_setting_info);
void viafb_lcd_set_mode(struct lvds_setting_information *plvds_setting_info,
void viafb_lcd_set_mode(const struct fb_var_screeninfo *var, u16 cxres,
u16 cyres, struct lvds_setting_information *plvds_setting_info,
struct lvds_chip_information *plvds_chip_info);
bool __devinit viafb_lvds_trasmitter_identify(void);
void viafb_init_lvds_output_interface(struct lvds_chip_information
......
......@@ -283,337 +283,6 @@
#define HW_LAYOUT_LCD1_LCD2 0x04
#define HW_LAYOUT_LCD_EXTERNAL_LCD2 0x10
/* Definition Refresh Rate */
#define REFRESH_49 49
#define REFRESH_50 50
#define REFRESH_60 60
#define REFRESH_75 75
#define REFRESH_85 85
#define REFRESH_100 100
#define REFRESH_120 120
/* Definition Sync Polarity*/
#define NEGATIVE 1
#define POSITIVE 0
/*480x640@60 Sync Polarity (GTF)
*/
#define M480X640_R60_HSP NEGATIVE
#define M480X640_R60_VSP POSITIVE
/*640x480@60 Sync Polarity (VESA Mode)
*/
#define M640X480_R60_HSP NEGATIVE
#define M640X480_R60_VSP NEGATIVE
/*640x480@75 Sync Polarity (VESA Mode)
*/
#define M640X480_R75_HSP NEGATIVE
#define M640X480_R75_VSP NEGATIVE
/*640x480@85 Sync Polarity (VESA Mode)
*/
#define M640X480_R85_HSP NEGATIVE
#define M640X480_R85_VSP NEGATIVE
/*640x480@100 Sync Polarity (GTF Mode)
*/
#define M640X480_R100_HSP NEGATIVE
#define M640X480_R100_VSP POSITIVE
/*640x480@120 Sync Polarity (GTF Mode)
*/
#define M640X480_R120_HSP NEGATIVE
#define M640X480_R120_VSP POSITIVE
/*720x480@60 Sync Polarity (GTF Mode)
*/
#define M720X480_R60_HSP NEGATIVE
#define M720X480_R60_VSP POSITIVE
/*720x576@60 Sync Polarity (GTF Mode)
*/
#define M720X576_R60_HSP NEGATIVE
#define M720X576_R60_VSP POSITIVE
/*800x600@60 Sync Polarity (VESA Mode)
*/
#define M800X600_R60_HSP POSITIVE
#define M800X600_R60_VSP POSITIVE
/*800x600@75 Sync Polarity (VESA Mode)
*/
#define M800X600_R75_HSP POSITIVE
#define M800X600_R75_VSP POSITIVE
/*800x600@85 Sync Polarity (VESA Mode)
*/
#define M800X600_R85_HSP POSITIVE
#define M800X600_R85_VSP POSITIVE
/*800x600@100 Sync Polarity (GTF Mode)
*/
#define M800X600_R100_HSP NEGATIVE
#define M800X600_R100_VSP POSITIVE
/*800x600@120 Sync Polarity (GTF Mode)
*/
#define M800X600_R120_HSP NEGATIVE
#define M800X600_R120_VSP POSITIVE
/*800x480@60 Sync Polarity (CVT Mode)
*/
#define M800X480_R60_HSP NEGATIVE
#define M800X480_R60_VSP POSITIVE
/*848x480@60 Sync Polarity (CVT Mode)
*/
#define M848X480_R60_HSP NEGATIVE
#define M848X480_R60_VSP POSITIVE
/*852x480@60 Sync Polarity (GTF Mode)
*/
#define M852X480_R60_HSP NEGATIVE
#define M852X480_R60_VSP POSITIVE
/*1024x512@60 Sync Polarity (GTF Mode)
*/
#define M1024X512_R60_HSP NEGATIVE
#define M1024X512_R60_VSP POSITIVE
/*1024x600@60 Sync Polarity (GTF Mode)
*/
#define M1024X600_R60_HSP NEGATIVE
#define M1024X600_R60_VSP POSITIVE
/*1024x768@60 Sync Polarity (VESA Mode)
*/
#define M1024X768_R60_HSP NEGATIVE
#define M1024X768_R60_VSP NEGATIVE
/*1024x768@75 Sync Polarity (VESA Mode)
*/
#define M1024X768_R75_HSP POSITIVE
#define M1024X768_R75_VSP POSITIVE
/*1024x768@85 Sync Polarity (VESA Mode)
*/
#define M1024X768_R85_HSP POSITIVE
#define M1024X768_R85_VSP POSITIVE
/*1024x768@100 Sync Polarity (GTF Mode)
*/
#define M1024X768_R100_HSP NEGATIVE
#define M1024X768_R100_VSP POSITIVE
/*1152x864@75 Sync Polarity (VESA Mode)
*/
#define M1152X864_R75_HSP POSITIVE
#define M1152X864_R75_VSP POSITIVE
/*1280x720@60 Sync Polarity (GTF Mode)
*/
#define M1280X720_R60_HSP NEGATIVE
#define M1280X720_R60_VSP POSITIVE
/* 1280x768@50 Sync Polarity (GTF Mode) */
#define M1280X768_R50_HSP NEGATIVE
#define M1280X768_R50_VSP POSITIVE
/*1280x768@60 Sync Polarity (GTF Mode)
*/
#define M1280X768_R60_HSP NEGATIVE
#define M1280X768_R60_VSP POSITIVE
/*1280x800@60 Sync Polarity (CVT Mode)
*/
#define M1280X800_R60_HSP NEGATIVE
#define M1280X800_R60_VSP POSITIVE
/*1280x960@60 Sync Polarity (VESA Mode)
*/
#define M1280X960_R60_HSP POSITIVE
#define M1280X960_R60_VSP POSITIVE
/*1280x1024@60 Sync Polarity (VESA Mode)
*/
#define M1280X1024_R60_HSP POSITIVE
#define M1280X1024_R60_VSP POSITIVE
/* 1360x768@60 Sync Polarity (CVT Mode) */
#define M1360X768_R60_HSP POSITIVE
#define M1360X768_R60_VSP POSITIVE
/* 1360x768@60 Sync Polarity (CVT Reduce Blanking Mode) */
#define M1360X768_RB_R60_HSP POSITIVE
#define M1360X768_RB_R60_VSP NEGATIVE
/* 1368x768@50 Sync Polarity (GTF Mode) */
#define M1368X768_R50_HSP NEGATIVE
#define M1368X768_R50_VSP POSITIVE
/* 1368x768@60 Sync Polarity (VESA Mode) */
#define M1368X768_R60_HSP NEGATIVE
#define M1368X768_R60_VSP POSITIVE
/*1280x1024@75 Sync Polarity (VESA Mode)
*/
#define M1280X1024_R75_HSP POSITIVE
#define M1280X1024_R75_VSP POSITIVE
/*1280x1024@85 Sync Polarity (VESA Mode)
*/
#define M1280X1024_R85_HSP POSITIVE
#define M1280X1024_R85_VSP POSITIVE
/*1440x1050@60 Sync Polarity (GTF Mode)
*/
#define M1440X1050_R60_HSP NEGATIVE
#define M1440X1050_R60_VSP POSITIVE
/*1600x1200@60 Sync Polarity (VESA Mode)
*/
#define M1600X1200_R60_HSP POSITIVE
#define M1600X1200_R60_VSP POSITIVE
/*1600x1200@75 Sync Polarity (VESA Mode)
*/
#define M1600X1200_R75_HSP POSITIVE
#define M1600X1200_R75_VSP POSITIVE
/* 1680x1050@60 Sync Polarity (CVT Mode) */
#define M1680x1050_R60_HSP NEGATIVE
#define M1680x1050_R60_VSP NEGATIVE
/* 1680x1050@60 Sync Polarity (CVT Reduce Blanking Mode) */
#define M1680x1050_RB_R60_HSP POSITIVE
#define M1680x1050_RB_R60_VSP NEGATIVE
/* 1680x1050@75 Sync Polarity (CVT Mode) */
#define M1680x1050_R75_HSP NEGATIVE
#define M1680x1050_R75_VSP POSITIVE
/*1920x1080@60 Sync Polarity (CVT Mode)
*/
#define M1920X1080_R60_HSP NEGATIVE
#define M1920X1080_R60_VSP POSITIVE
/* 1920x1080@60 Sync Polarity (CVT Reduce Blanking Mode) */
#define M1920X1080_RB_R60_HSP POSITIVE
#define M1920X1080_RB_R60_VSP NEGATIVE
/*1920x1440@60 Sync Polarity (VESA Mode)
*/
#define M1920X1440_R60_HSP NEGATIVE
#define M1920X1440_R60_VSP POSITIVE
/*1920x1440@75 Sync Polarity (VESA Mode)
*/
#define M1920X1440_R75_HSP NEGATIVE
#define M1920X1440_R75_VSP POSITIVE
#if 0
/* 1400x1050@60 Sync Polarity (VESA Mode) */
#define M1400X1050_R60_HSP NEGATIVE
#define M1400X1050_R60_VSP NEGATIVE
#endif
/* 1400x1050@60 Sync Polarity (CVT Mode) */
#define M1400X1050_R60_HSP NEGATIVE
#define M1400X1050_R60_VSP POSITIVE
/* 1400x1050@60 Sync Polarity (CVT Reduce Blanking Mode) */
#define M1400X1050_RB_R60_HSP POSITIVE
#define M1400X1050_RB_R60_VSP NEGATIVE
/* 1400x1050@75 Sync Polarity (CVT Mode) */
#define M1400X1050_R75_HSP NEGATIVE
#define M1400X1050_R75_VSP POSITIVE
/* 960x600@60 Sync Polarity (CVT Mode) */
#define M960X600_R60_HSP NEGATIVE
#define M960X600_R60_VSP POSITIVE
/* 1000x600@60 Sync Polarity (GTF Mode) */
#define M1000X600_R60_HSP NEGATIVE
#define M1000X600_R60_VSP POSITIVE
/* 1024x576@60 Sync Polarity (GTF Mode) */
#define M1024X576_R60_HSP NEGATIVE
#define M1024X576_R60_VSP POSITIVE
/*1024x600@60 Sync Polarity (GTF Mode)*/
#define M1024X600_R60_HSP NEGATIVE
#define M1024X600_R60_VSP POSITIVE
/* 1088x612@60 Sync Polarity (CVT Mode) */
#define M1088X612_R60_HSP NEGATIVE
#define M1088X612_R60_VSP POSITIVE
/* 1152x720@60 Sync Polarity (CVT Mode) */
#define M1152X720_R60_HSP NEGATIVE
#define M1152X720_R60_VSP POSITIVE
/* 1200x720@60 Sync Polarity (GTF Mode) */
#define M1200X720_R60_HSP NEGATIVE
#define M1200X720_R60_VSP POSITIVE
/* 1200x900@60 Sync Polarity (DCON) */
#define M1200X900_R60_HSP POSITIVE
#define M1200X900_R60_VSP POSITIVE
/* 1280x600@60 Sync Polarity (GTF Mode) */
#define M1280x600_R60_HSP NEGATIVE
#define M1280x600_R60_VSP POSITIVE
/* 1280x720@50 Sync Polarity (GTF Mode) */
#define M1280X720_R50_HSP NEGATIVE
#define M1280X720_R50_VSP POSITIVE
/* 1440x900@60 Sync Polarity (CVT Mode) */
#define M1440X900_R60_HSP NEGATIVE
#define M1440X900_R60_VSP POSITIVE
/* 1440x900@75 Sync Polarity (CVT Mode) */
#define M1440X900_R75_HSP NEGATIVE
#define M1440X900_R75_VSP POSITIVE
/* 1440x900@60 Sync Polarity (CVT Reduce Blanking Mode) */
#define M1440X900_RB_R60_HSP POSITIVE
#define M1440X900_RB_R60_VSP NEGATIVE
/* 1600x900@60 Sync Polarity (CVT Mode) */
#define M1600X900_R60_HSP NEGATIVE
#define M1600X900_R60_VSP POSITIVE
/* 1600x900@60 Sync Polarity (CVT Reduce Blanking Mode) */
#define M1600X900_RB_R60_HSP POSITIVE
#define M1600X900_RB_R60_VSP NEGATIVE
/* 1600x1024@60 Sync Polarity (GTF Mode) */
#define M1600X1024_R60_HSP NEGATIVE
#define M1600X1024_R60_VSP POSITIVE
/* 1792x1344@60 Sync Polarity (DMT Mode) */
#define M1792x1344_R60_HSP NEGATIVE
#define M1792x1344_R60_VSP POSITIVE
/* 1856x1392@60 Sync Polarity (DMT Mode) */
#define M1856x1392_R60_HSP NEGATIVE
#define M1856x1392_R60_VSP POSITIVE
/* 1920x1200@60 Sync Polarity (CVT Mode) */
#define M1920X1200_R60_HSP NEGATIVE
#define M1920X1200_R60_VSP POSITIVE
/* 1920x1200@60 Sync Polarity (CVT Reduce Blanking Mode) */
#define M1920X1200_RB_R60_HSP POSITIVE
#define M1920X1200_RB_R60_VSP NEGATIVE
/* 2048x1536@60 Sync Polarity (CVT Mode) */
#define M2048x1536_R60_HSP NEGATIVE
#define M2048x1536_R60_VSP POSITIVE
/* Definition CRTC Timing Index */
#define H_TOTAL_INDEX 0
#define H_ADDR_INDEX 1
......
/*
* Copyright 2011 Florian Tobias Schandinat <FlorianSchandinat@gmx.de>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public
* License as published by the Free Software Foundation;
* either version 2, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
* the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE.See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc.,
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/*
* infrastructure for devices connected via I2C
*/
#include <linux/slab.h>
#include "via_aux.h"
struct via_aux_bus *via_aux_probe(struct i2c_adapter *adap)
{
struct via_aux_bus *bus;
if (!adap)
return NULL;
bus = kmalloc(sizeof(*bus), GFP_KERNEL);
if (!bus)
return NULL;
bus->adap = adap;
INIT_LIST_HEAD(&bus->drivers);
via_aux_edid_probe(bus);
via_aux_vt1636_probe(bus);
via_aux_vt1632_probe(bus);
via_aux_vt1631_probe(bus);
via_aux_vt1625_probe(bus);
via_aux_vt1622_probe(bus);
via_aux_vt1621_probe(bus);
via_aux_sii164_probe(bus);
via_aux_ch7301_probe(bus);
return bus;
}
void via_aux_free(struct via_aux_bus *bus)
{
struct via_aux_drv *pos, *n;
if (!bus)
return;
list_for_each_entry_safe(pos, n, &bus->drivers, chain) {
if (pos->cleanup)
pos->cleanup(pos);
list_del(&pos->chain);
kfree(pos->data);
kfree(pos);
}
kfree(bus);
}
const struct fb_videomode *via_aux_get_preferred_mode(struct via_aux_bus *bus)
{
struct via_aux_drv *pos;
const struct fb_videomode *mode = NULL;
if (!bus)
return NULL;
list_for_each_entry(pos, &bus->drivers, chain) {
if (pos->get_preferred_mode)
mode = pos->get_preferred_mode(pos);
}
return mode;
}
/*
* Copyright 2011 Florian Tobias Schandinat <FlorianSchandinat@gmx.de>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public
* License as published by the Free Software Foundation;
* either version 2, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
* the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE.See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc.,
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/*
* infrastructure for devices connected via I2C
*/
#ifndef __VIA_AUX_H__
#define __VIA_AUX_H__
#include <linux/list.h>
#include <linux/i2c.h>
#include <linux/fb.h>
struct via_aux_bus {
struct i2c_adapter *adap; /* the I2C device to access the bus */
struct list_head drivers; /* drivers for devices on this bus */
};
struct via_aux_drv {
struct list_head chain; /* chain to support multiple drivers */
struct via_aux_bus *bus; /* the I2C bus used */
u8 addr; /* the I2C slave address */
const char *name; /* human readable name of the driver */
void *data; /* private data of this driver */
void (*cleanup)(struct via_aux_drv *drv);
const struct fb_videomode* (*get_preferred_mode)
(struct via_aux_drv *drv);
};
struct via_aux_bus *via_aux_probe(struct i2c_adapter *adap);
void via_aux_free(struct via_aux_bus *bus);
const struct fb_videomode *via_aux_get_preferred_mode(struct via_aux_bus *bus);
static inline bool via_aux_add(struct via_aux_drv *drv)
{
struct via_aux_drv *data = kmalloc(sizeof(*data), GFP_KERNEL);
if (!data)
return false;
*data = *drv;
list_add_tail(&data->chain, &data->bus->drivers);
return true;
}
static inline bool via_aux_read(struct via_aux_drv *drv, u8 start, u8 *buf,
u8 len)
{
struct i2c_msg msg[2] = {
{.addr = drv->addr, .flags = 0, .len = 1, .buf = &start},
{.addr = drv->addr, .flags = I2C_M_RD, .len = len, .buf = buf} };
return i2c_transfer(drv->bus->adap, msg, 2) == 2;
}
/* probe functions of existing drivers - should only be called in via_aux.c */
void via_aux_ch7301_probe(struct via_aux_bus *bus);
void via_aux_edid_probe(struct via_aux_bus *bus);
void via_aux_sii164_probe(struct via_aux_bus *bus);
void via_aux_vt1636_probe(struct via_aux_bus *bus);
void via_aux_vt1632_probe(struct via_aux_bus *bus);
void via_aux_vt1631_probe(struct via_aux_bus *bus);
void via_aux_vt1625_probe(struct via_aux_bus *bus);
void via_aux_vt1622_probe(struct via_aux_bus *bus);
void via_aux_vt1621_probe(struct via_aux_bus *bus);
#endif /* __VIA_AUX_H__ */
/*
* Copyright 2011 Florian Tobias Schandinat <FlorianSchandinat@gmx.de>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public
* License as published by the Free Software Foundation;
* either version 2, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
* the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE.See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc.,
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/*
* driver for Chrontel CH7301 DVI Transmitter
*/
#include <linux/slab.h>
#include "via_aux.h"
static const char *name = "CH7301 DVI Transmitter";
static void probe(struct via_aux_bus *bus, u8 addr)
{
struct via_aux_drv drv = {
.bus = bus,
.addr = addr,
.name = name};
u8 tmp;
if (!via_aux_read(&drv, 0x4B, &tmp, 1) || tmp != 0x17)
return;
printk(KERN_INFO "viafb: Found %s at address 0x%x\n", name, addr);
via_aux_add(&drv);
}
void via_aux_ch7301_probe(struct via_aux_bus *bus)
{
probe(bus, 0x75);
probe(bus, 0x76);
}
/*
* Copyright 2011 Florian Tobias Schandinat <FlorianSchandinat@gmx.de>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public
* License as published by the Free Software Foundation;
* either version 2, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
* the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE.See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc.,
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/*
* generic EDID driver
*/
#include <linux/slab.h>
#include <linux/fb.h>
#include "via_aux.h"
#include "../edid.h"
static const char *name = "EDID";
static void query_edid(struct via_aux_drv *drv)
{
struct fb_monspecs *spec = drv->data;
unsigned char edid[EDID_LENGTH];
bool valid = false;
if (spec) {
fb_destroy_modedb(spec->modedb);
} else {
spec = kmalloc(sizeof(*spec), GFP_KERNEL);
if (!spec)
return;
}
spec->version = spec->revision = 0;
if (via_aux_read(drv, 0x00, edid, EDID_LENGTH)) {
fb_edid_to_monspecs(edid, spec);
valid = spec->version || spec->revision;
}
if (!valid) {
kfree(spec);
spec = NULL;
} else
printk(KERN_DEBUG "EDID: %s %s\n", spec->manufacturer, spec->monitor);
drv->data = spec;
}
static const struct fb_videomode *get_preferred_mode(struct via_aux_drv *drv)
{
struct fb_monspecs *spec = drv->data;
int i;
if (!spec || !spec->modedb || !(spec->misc & FB_MISC_1ST_DETAIL))
return NULL;
for (i = 0; i < spec->modedb_len; i++) {
if (spec->modedb[i].flag & FB_MODE_IS_FIRST &&
spec->modedb[i].flag & FB_MODE_IS_DETAILED)
return &spec->modedb[i];
}
return NULL;
}
static void cleanup(struct via_aux_drv *drv)
{
struct fb_monspecs *spec = drv->data;
if (spec)
fb_destroy_modedb(spec->modedb);
}
void via_aux_edid_probe(struct via_aux_bus *bus)
{
struct via_aux_drv drv = {
.bus = bus,
.addr = 0x50,
.name = name,
.cleanup = cleanup,
.get_preferred_mode = get_preferred_mode};
query_edid(&drv);
/* as EDID devices can be connected/disconnected just add the driver */
via_aux_add(&drv);
}
/*
* Copyright 2011 Florian Tobias Schandinat <FlorianSchandinat@gmx.de>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public
* License as published by the Free Software Foundation;
* either version 2, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
* the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE.See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc.,
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/*
* driver for Silicon Image SiI 164 PanelLink Transmitter
*/
#include <linux/slab.h>
#include "via_aux.h"
static const char *name = "SiI 164 PanelLink Transmitter";
static void probe(struct via_aux_bus *bus, u8 addr)
{
struct via_aux_drv drv = {
.bus = bus,
.addr = addr,
.name = name};
/* check vendor id and device id */
const u8 id[] = {0x01, 0x00, 0x06, 0x00}, len = ARRAY_SIZE(id);
u8 tmp[len];
if (!via_aux_read(&drv, 0x00, tmp, len) || memcmp(id, tmp, len))
return;
printk(KERN_INFO "viafb: Found %s at address 0x%x\n", name, addr);
via_aux_add(&drv);
}
void via_aux_sii164_probe(struct via_aux_bus *bus)
{
u8 i;
for (i = 0x38; i <= 0x3F; i++)
probe(bus, i);
}
/*
* Copyright 2011 Florian Tobias Schandinat <FlorianSchandinat@gmx.de>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public
* License as published by the Free Software Foundation;
* either version 2, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
* the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE.See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc.,
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/*
* driver for VIA VT1621(M) TV Encoder
*/
#include <linux/slab.h>
#include "via_aux.h"
static const char *name = "VT1621(M) TV Encoder";
void via_aux_vt1621_probe(struct via_aux_bus *bus)
{
struct via_aux_drv drv = {
.bus = bus,
.addr = 0x20,
.name = name};
u8 tmp;
if (!via_aux_read(&drv, 0x1B, &tmp, 1) || tmp != 0x02)
return;
printk(KERN_INFO "viafb: Found %s\n", name);
via_aux_add(&drv);
}
/*
* Copyright 2011 Florian Tobias Schandinat <FlorianSchandinat@gmx.de>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public
* License as published by the Free Software Foundation;
* either version 2, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
* the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE.See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc.,
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/*
* driver for VIA VT1622(M) Digital TV Encoder
*/
#include <linux/slab.h>
#include "via_aux.h"
static const char *name = "VT1622(M) Digital TV Encoder";
static void probe(struct via_aux_bus *bus, u8 addr)
{
struct via_aux_drv drv = {
.bus = bus,
.addr = addr,
.name = name};
u8 tmp;
if (!via_aux_read(&drv, 0x1B, &tmp, 1) || tmp != 0x03)
return;
printk(KERN_INFO "viafb: Found %s at address 0x%x\n", name, addr);
via_aux_add(&drv);
}
void via_aux_vt1622_probe(struct via_aux_bus *bus)
{
probe(bus, 0x20);
probe(bus, 0x21);
}
/*
* Copyright 2011 Florian Tobias Schandinat <FlorianSchandinat@gmx.de>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public
* License as published by the Free Software Foundation;
* either version 2, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
* the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE.See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc.,
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/*
* driver for VIA VT1625(M) HDTV Encoder
*/
#include <linux/slab.h>
#include "via_aux.h"
static const char *name = "VT1625(M) HDTV Encoder";
static void probe(struct via_aux_bus *bus, u8 addr)
{
struct via_aux_drv drv = {
.bus = bus,
.addr = addr,
.name = name};
u8 tmp;
if (!via_aux_read(&drv, 0x1B, &tmp, 1) || tmp != 0x50)
return;
printk(KERN_INFO "viafb: Found %s at address 0x%x\n", name, addr);
via_aux_add(&drv);
}
void via_aux_vt1625_probe(struct via_aux_bus *bus)
{
probe(bus, 0x20);
probe(bus, 0x21);
}
/*
* Copyright 2011 Florian Tobias Schandinat <FlorianSchandinat@gmx.de>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public
* License as published by the Free Software Foundation;
* either version 2, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
* the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE.See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc.,
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/*
* driver for VIA VT1631 LVDS Transmitter
*/
#include <linux/slab.h>
#include "via_aux.h"
static const char *name = "VT1631 LVDS Transmitter";
void via_aux_vt1631_probe(struct via_aux_bus *bus)
{
struct via_aux_drv drv = {
.bus = bus,
.addr = 0x38,
.name = name};
/* check vendor id and device id */
const u8 id[] = {0x06, 0x11, 0x91, 0x31}, len = ARRAY_SIZE(id);
u8 tmp[len];
if (!via_aux_read(&drv, 0x00, tmp, len) || memcmp(id, tmp, len))
return;
printk(KERN_INFO "viafb: Found %s\n", name);
via_aux_add(&drv);
}
/*
* Copyright 2011 Florian Tobias Schandinat <FlorianSchandinat@gmx.de>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public
* License as published by the Free Software Foundation;
* either version 2, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
* the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE.See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc.,
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/*
* driver for VIA VT1632 DVI Transmitter
*/
#include <linux/slab.h>
#include "via_aux.h"
static const char *name = "VT1632 DVI Transmitter";
static void probe(struct via_aux_bus *bus, u8 addr)
{
struct via_aux_drv drv = {
.bus = bus,
.addr = addr,
.name = name};
/* check vendor id and device id */
const u8 id[] = {0x06, 0x11, 0x92, 0x31}, len = ARRAY_SIZE(id);
u8 tmp[len];
if (!via_aux_read(&drv, 0x00, tmp, len) || memcmp(id, tmp, len))
return;
printk(KERN_INFO "viafb: Found %s at address 0x%x\n", name, addr);
via_aux_add(&drv);
}
void via_aux_vt1632_probe(struct via_aux_bus *bus)
{
u8 i;
for (i = 0x08; i <= 0x0F; i++)
probe(bus, i);
}
/*
* Copyright 2011 Florian Tobias Schandinat <FlorianSchandinat@gmx.de>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public
* License as published by the Free Software Foundation;
* either version 2, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
* the implied warranty of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE.See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc.,
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/*
* driver for VIA VT1636 LVDS Transmitter
*/
#include <linux/slab.h>
#include "via_aux.h"
static const char *name = "VT1636 LVDS Transmitter";
void via_aux_vt1636_probe(struct via_aux_bus *bus)
{
struct via_aux_drv drv = {
.bus = bus,
.addr = 0x40,
.name = name};
/* check vendor id and device id */
const u8 id[] = {0x06, 0x11, 0x45, 0x33}, len = ARRAY_SIZE(id);
u8 tmp[len];
if (!via_aux_read(&drv, 0x00, tmp, len) || memcmp(id, tmp, len))
return;
printk(KERN_INFO "viafb: Found %s\n", name);
via_aux_add(&drv);
}
......@@ -51,7 +51,7 @@ static void via_i2c_setscl(void *data, int state)
val |= 0x01;
break;
case VIA_PORT_GPIO:
val |= 0x80;
val |= 0x82;
break;
default:
printk(KERN_ERR "viafb_i2c: specify wrong i2c type.\n");
......@@ -67,6 +67,9 @@ static int via_i2c_getscl(void *data)
int ret = 0;
spin_lock_irqsave(&i2c_vdev->reg_lock, flags);
if (adap_data->type == VIA_PORT_GPIO)
via_write_reg_mask(adap_data->io_port, adap_data->ioport_index,
0, 0x80);
if (via_read_reg(adap_data->io_port, adap_data->ioport_index) & 0x08)
ret = 1;
spin_unlock_irqrestore(&i2c_vdev->reg_lock, flags);
......@@ -80,6 +83,9 @@ static int via_i2c_getsda(void *data)
int ret = 0;
spin_lock_irqsave(&i2c_vdev->reg_lock, flags);
if (adap_data->type == VIA_PORT_GPIO)
via_write_reg_mask(adap_data->io_port, adap_data->ioport_index,
0, 0x40);
if (via_read_reg(adap_data->io_port, adap_data->ioport_index) & 0x04)
ret = 1;
spin_unlock_irqrestore(&i2c_vdev->reg_lock, flags);
......@@ -103,7 +109,7 @@ static void via_i2c_setsda(void *data, int state)
val |= 0x01;
break;
case VIA_PORT_GPIO:
val |= 0x40;
val |= 0x42;
break;
default:
printk(KERN_ERR "viafb_i2c: specify wrong i2c type.\n");
......
......@@ -24,6 +24,7 @@
#include <linux/slab.h>
#include <linux/stat.h>
#include <linux/via-core.h>
#include <linux/via_i2c.h>
#include <asm/olpc.h>
#define _MASTER_FILE
......@@ -286,26 +287,22 @@ static int viafb_set_par(struct fb_info *info)
viafb_second_yres, viafb_bpp1, 1);
}
refresh = viafb_get_refresh(info->var.xres, info->var.yres,
get_var_refresh(&info->var));
if (viafb_get_best_mode(viafbinfo->var.xres, viafbinfo->var.yres,
refresh)) {
if (viafb_dual_fb && viapar->iga_path == IGA2) {
viafb_bpp1 = info->var.bits_per_pixel;
viafb_refresh1 = refresh;
} else {
viafb_bpp = info->var.bits_per_pixel;
viafb_refresh = refresh;
}
if (info->var.accel_flags & FB_ACCELF_TEXT)
info->flags &= ~FBINFO_HWACCEL_DISABLED;
else
info->flags |= FBINFO_HWACCEL_DISABLED;
viafb_setmode(info->var.bits_per_pixel, viafb_bpp1);
viafb_pan_display(&info->var, info);
refresh = get_var_refresh(&info->var);
if (viafb_dual_fb && viapar->iga_path == IGA2) {
viafb_bpp1 = info->var.bits_per_pixel;
viafb_refresh1 = refresh;
} else {
viafb_bpp = info->var.bits_per_pixel;
viafb_refresh = refresh;
}
if (info->var.accel_flags & FB_ACCELF_TEXT)
info->flags &= ~FBINFO_HWACCEL_DISABLED;
else
info->flags |= FBINFO_HWACCEL_DISABLED;
viafb_setmode();
viafb_pan_display(&info->var, info);
return 0;
}
......@@ -1670,12 +1667,23 @@ static void viafb_remove_proc(struct viafb_shared *shared)
}
#undef IS_VT1636
static int parse_mode(const char *str, u32 *xres, u32 *yres)
static int parse_mode(const char *str, u32 devices, u32 *xres, u32 *yres)
{
const struct fb_videomode *mode = NULL;
char *ptr;
if (!str) {
if (machine_is_olpc()) {
if (devices == VIA_CRT)
mode = via_aux_get_preferred_mode(
viaparinfo->shared->i2c_26);
else if (devices == VIA_DVP1)
mode = via_aux_get_preferred_mode(
viaparinfo->shared->i2c_31);
if (mode) {
*xres = mode->xres;
*yres = mode->yres;
} else if (machine_is_olpc()) {
*xres = 1200;
*yres = 900;
} else {
......@@ -1729,6 +1737,31 @@ static struct viafb_pm_hooks viafb_fb_pm_hooks = {
#endif
static void __devinit i2c_bus_probe(struct viafb_shared *shared)
{
/* should be always CRT */
printk(KERN_INFO "viafb: Probing I2C bus 0x26\n");
shared->i2c_26 = via_aux_probe(viafb_find_i2c_adapter(VIA_PORT_26));
/* seems to be usually DVP1 */
printk(KERN_INFO "viafb: Probing I2C bus 0x31\n");
shared->i2c_31 = via_aux_probe(viafb_find_i2c_adapter(VIA_PORT_31));
/* FIXME: what is this? */
if (!machine_is_olpc()) {
printk(KERN_INFO "viafb: Probing I2C bus 0x2C\n");
shared->i2c_2C = via_aux_probe(viafb_find_i2c_adapter(VIA_PORT_2C));
}
printk(KERN_INFO "viafb: Finished I2C bus probing");
}
static void i2c_bus_free(struct viafb_shared *shared)
{
via_aux_free(shared->i2c_26);
via_aux_free(shared->i2c_31);
via_aux_free(shared->i2c_2C);
}
int __devinit via_fb_pci_probe(struct viafb_dev *vdev)
{
......@@ -1762,6 +1795,7 @@ int __devinit via_fb_pci_probe(struct viafb_dev *vdev)
&viaparinfo->shared->lvds_setting_info2;
viaparinfo->chip_info = &viaparinfo->shared->chip_info;
i2c_bus_probe(viaparinfo->shared);
if (viafb_dual_fb)
viafb_SAMM_ON = 1;
parse_lcd_port();
......@@ -1804,10 +1838,11 @@ int __devinit via_fb_pci_probe(struct viafb_dev *vdev)
viafb_second_size * 1024 * 1024;
}
parse_mode(viafb_mode, &default_xres, &default_yres);
parse_mode(viafb_mode, viaparinfo->shared->iga1_devices,
&default_xres, &default_yres);
if (viafb_SAMM_ON == 1)
parse_mode(viafb_mode1, &viafb_second_xres,
&viafb_second_yres);
parse_mode(viafb_mode1, viaparinfo->shared->iga2_devices,
&viafb_second_xres, &viafb_second_yres);
default_var.xres = default_xres;
default_var.yres = default_yres;
......@@ -1915,6 +1950,7 @@ int __devinit via_fb_pci_probe(struct viafb_dev *vdev)
if (viafbinfo1)
framebuffer_release(viafbinfo1);
out_fb_release:
i2c_bus_free(viaparinfo->shared);
framebuffer_release(viafbinfo);
return rc;
}
......@@ -1927,6 +1963,7 @@ void __devexit via_fb_pci_remove(struct pci_dev *pdev)
if (viafb_dual_fb)
unregister_framebuffer(viafbinfo1);
viafb_remove_proc(viaparinfo->shared);
i2c_bus_free(viaparinfo->shared);
framebuffer_release(viafbinfo);
if (viafb_dual_fb)
framebuffer_release(viafbinfo1);
......@@ -2033,9 +2070,9 @@ int __init viafb_init(void)
if (r < 0)
return r;
#endif
if (parse_mode(viafb_mode, &dummy_x, &dummy_y)
if (parse_mode(viafb_mode, 0, &dummy_x, &dummy_y)
|| !viafb_get_best_mode(dummy_x, dummy_y, viafb_refresh)
|| parse_mode(viafb_mode1, &dummy_x, &dummy_y)
|| parse_mode(viafb_mode1, 0, &dummy_x, &dummy_y)
|| !viafb_get_best_mode(dummy_x, dummy_y, viafb_refresh1)
|| viafb_bpp < 0 || viafb_bpp > 32
|| viafb_bpp1 < 0 || viafb_bpp1 > 32
......
......@@ -26,6 +26,7 @@
#include <linux/fb.h>
#include <linux/spinlock.h>
#include "via_aux.h"
#include "ioctl.h"
#include "share.h"
#include "chip.h"
......@@ -48,6 +49,11 @@ struct viafb_shared {
struct proc_dir_entry *iga2_proc_entry;
struct viafb_dev *vdev; /* Global dev info */
/* I2C busses that may have auxiliary devices */
struct via_aux_bus *i2c_26;
struct via_aux_bus *i2c_31;
struct via_aux_bus *i2c_2C;
/* All the information will be needed to set engine */
struct tmds_setting_information tmds_setting_info;
struct lvds_setting_information lvds_setting_info;
......
此差异已折叠。
......@@ -31,11 +31,6 @@ struct VPITTable {
unsigned char AR[StdAR];
};
struct VideoModeTable {
struct crt_mode_table *crtc;
int mode_array;
};
struct patch_table {
int table_length;
struct io_reg *io_reg_table;
......@@ -60,7 +55,9 @@ extern struct io_reg PM1024x768[];
extern struct patch_table res_patch_table[];
extern struct VPITTable VPIT;
struct crt_mode_table *viafb_get_best_mode(int hres, int vres, int refresh);
struct crt_mode_table *viafb_get_best_rb_mode(int hres, int vres, int refresh);
const struct fb_videomode *viafb_get_best_mode(int hres, int vres,
int refresh);
const struct fb_videomode *viafb_get_best_rb_mode(int hres, int vres,
int refresh);
#endif /* __VIAMODE_H__ */
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册