162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved. 462306a36Sopenharmony_ci * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved. 562306a36Sopenharmony_ci 662306a36Sopenharmony_ci */ 762306a36Sopenharmony_ci 862306a36Sopenharmony_ci#include <linux/via-core.h> 962306a36Sopenharmony_ci#include <linux/via_i2c.h> 1062306a36Sopenharmony_ci#include "global.h" 1162306a36Sopenharmony_ci 1262306a36Sopenharmony_cistatic const struct IODATA common_init_data[] = { 1362306a36Sopenharmony_ci/* Index, Mask, Value */ 1462306a36Sopenharmony_ci /* Set panel power sequence timing */ 1562306a36Sopenharmony_ci {0x10, 0xC0, 0x00}, 1662306a36Sopenharmony_ci /* T1: VDD on - Data on. Each increment is 1 ms. (50ms = 031h) */ 1762306a36Sopenharmony_ci {0x0B, 0xFF, 0x40}, 1862306a36Sopenharmony_ci /* T2: Data on - Backlight on. Each increment is 2 ms. (210ms = 068h) */ 1962306a36Sopenharmony_ci {0x0C, 0xFF, 0x31}, 2062306a36Sopenharmony_ci /* T3: Backlight off -Data off. Each increment is 2 ms. (210ms = 068h)*/ 2162306a36Sopenharmony_ci {0x0D, 0xFF, 0x31}, 2262306a36Sopenharmony_ci /* T4: Data off - VDD off. Each increment is 1 ms. (50ms = 031h) */ 2362306a36Sopenharmony_ci {0x0E, 0xFF, 0x68}, 2462306a36Sopenharmony_ci /* T5: VDD off - VDD on. Each increment is 100 ms. (500ms = 04h) */ 2562306a36Sopenharmony_ci {0x0F, 0xFF, 0x68}, 2662306a36Sopenharmony_ci /* LVDS output power up */ 2762306a36Sopenharmony_ci {0x09, 0xA0, 0xA0}, 2862306a36Sopenharmony_ci /* turn on back light */ 2962306a36Sopenharmony_ci {0x10, 0x33, 0x13} 3062306a36Sopenharmony_ci}; 3162306a36Sopenharmony_ci 3262306a36Sopenharmony_ci/* Index, Mask, Value */ 3362306a36Sopenharmony_cistatic const struct IODATA dual_channel_enable_data = {0x08, 0xF0, 0xE0}; 3462306a36Sopenharmony_cistatic const struct IODATA single_channel_enable_data = {0x08, 0xF0, 0x00}; 3562306a36Sopenharmony_cistatic const struct IODATA dithering_enable_data = {0x0A, 0x70, 0x50}; 3662306a36Sopenharmony_cistatic const struct IODATA dithering_disable_data = {0x0A, 0x70, 0x00}; 3762306a36Sopenharmony_cistatic const struct IODATA vdd_on_data = {0x10, 0x20, 0x20}; 3862306a36Sopenharmony_cistatic const struct IODATA vdd_off_data = {0x10, 0x20, 0x00}; 3962306a36Sopenharmony_ci 4062306a36Sopenharmony_ciu8 viafb_gpio_i2c_read_lvds(struct lvds_setting_information 4162306a36Sopenharmony_ci *plvds_setting_info, struct lvds_chip_information *plvds_chip_info, 4262306a36Sopenharmony_ci u8 index) 4362306a36Sopenharmony_ci{ 4462306a36Sopenharmony_ci u8 data; 4562306a36Sopenharmony_ci 4662306a36Sopenharmony_ci viafb_i2c_readbyte(plvds_chip_info->i2c_port, 4762306a36Sopenharmony_ci plvds_chip_info->lvds_chip_slave_addr, index, &data); 4862306a36Sopenharmony_ci return data; 4962306a36Sopenharmony_ci} 5062306a36Sopenharmony_ci 5162306a36Sopenharmony_civoid viafb_gpio_i2c_write_mask_lvds(struct lvds_setting_information 5262306a36Sopenharmony_ci *plvds_setting_info, struct lvds_chip_information 5362306a36Sopenharmony_ci *plvds_chip_info, struct IODATA io_data) 5462306a36Sopenharmony_ci{ 5562306a36Sopenharmony_ci int index, data; 5662306a36Sopenharmony_ci 5762306a36Sopenharmony_ci index = io_data.Index; 5862306a36Sopenharmony_ci data = viafb_gpio_i2c_read_lvds(plvds_setting_info, plvds_chip_info, 5962306a36Sopenharmony_ci index); 6062306a36Sopenharmony_ci data = (data & (~io_data.Mask)) | io_data.Data; 6162306a36Sopenharmony_ci 6262306a36Sopenharmony_ci viafb_i2c_writebyte(plvds_chip_info->i2c_port, 6362306a36Sopenharmony_ci plvds_chip_info->lvds_chip_slave_addr, index, data); 6462306a36Sopenharmony_ci} 6562306a36Sopenharmony_ci 6662306a36Sopenharmony_civoid viafb_init_lvds_vt1636(struct lvds_setting_information 6762306a36Sopenharmony_ci *plvds_setting_info, struct lvds_chip_information *plvds_chip_info) 6862306a36Sopenharmony_ci{ 6962306a36Sopenharmony_ci int reg_num, i; 7062306a36Sopenharmony_ci 7162306a36Sopenharmony_ci /* Common settings: */ 7262306a36Sopenharmony_ci reg_num = ARRAY_SIZE(common_init_data); 7362306a36Sopenharmony_ci for (i = 0; i < reg_num; i++) 7462306a36Sopenharmony_ci viafb_gpio_i2c_write_mask_lvds(plvds_setting_info, 7562306a36Sopenharmony_ci plvds_chip_info, common_init_data[i]); 7662306a36Sopenharmony_ci 7762306a36Sopenharmony_ci /* Input Data Mode Select */ 7862306a36Sopenharmony_ci if (plvds_setting_info->device_lcd_dualedge) 7962306a36Sopenharmony_ci viafb_gpio_i2c_write_mask_lvds(plvds_setting_info, 8062306a36Sopenharmony_ci plvds_chip_info, dual_channel_enable_data); 8162306a36Sopenharmony_ci else 8262306a36Sopenharmony_ci viafb_gpio_i2c_write_mask_lvds(plvds_setting_info, 8362306a36Sopenharmony_ci plvds_chip_info, single_channel_enable_data); 8462306a36Sopenharmony_ci 8562306a36Sopenharmony_ci if (plvds_setting_info->LCDDithering) 8662306a36Sopenharmony_ci viafb_gpio_i2c_write_mask_lvds(plvds_setting_info, 8762306a36Sopenharmony_ci plvds_chip_info, dithering_enable_data); 8862306a36Sopenharmony_ci else 8962306a36Sopenharmony_ci viafb_gpio_i2c_write_mask_lvds(plvds_setting_info, 9062306a36Sopenharmony_ci plvds_chip_info, dithering_disable_data); 9162306a36Sopenharmony_ci} 9262306a36Sopenharmony_ci 9362306a36Sopenharmony_civoid viafb_enable_lvds_vt1636(struct lvds_setting_information 9462306a36Sopenharmony_ci *plvds_setting_info, 9562306a36Sopenharmony_ci struct lvds_chip_information *plvds_chip_info) 9662306a36Sopenharmony_ci{ 9762306a36Sopenharmony_ci viafb_gpio_i2c_write_mask_lvds(plvds_setting_info, plvds_chip_info, 9862306a36Sopenharmony_ci vdd_on_data); 9962306a36Sopenharmony_ci} 10062306a36Sopenharmony_ci 10162306a36Sopenharmony_civoid viafb_disable_lvds_vt1636(struct lvds_setting_information 10262306a36Sopenharmony_ci *plvds_setting_info, 10362306a36Sopenharmony_ci struct lvds_chip_information *plvds_chip_info) 10462306a36Sopenharmony_ci{ 10562306a36Sopenharmony_ci viafb_gpio_i2c_write_mask_lvds(plvds_setting_info, plvds_chip_info, 10662306a36Sopenharmony_ci vdd_off_data); 10762306a36Sopenharmony_ci} 10862306a36Sopenharmony_ci 10962306a36Sopenharmony_cibool viafb_lvds_identify_vt1636(u8 i2c_adapter) 11062306a36Sopenharmony_ci{ 11162306a36Sopenharmony_ci u8 Buffer[2]; 11262306a36Sopenharmony_ci 11362306a36Sopenharmony_ci DEBUG_MSG(KERN_INFO "viafb_lvds_identify_vt1636.\n"); 11462306a36Sopenharmony_ci 11562306a36Sopenharmony_ci /* Sense VT1636 LVDS Transmiter */ 11662306a36Sopenharmony_ci viaparinfo->chip_info->lvds_chip_info.lvds_chip_slave_addr = 11762306a36Sopenharmony_ci VT1636_LVDS_I2C_ADDR; 11862306a36Sopenharmony_ci 11962306a36Sopenharmony_ci /* Check vendor ID first: */ 12062306a36Sopenharmony_ci if (viafb_i2c_readbyte(i2c_adapter, VT1636_LVDS_I2C_ADDR, 12162306a36Sopenharmony_ci 0x00, &Buffer[0])) 12262306a36Sopenharmony_ci return false; 12362306a36Sopenharmony_ci viafb_i2c_readbyte(i2c_adapter, VT1636_LVDS_I2C_ADDR, 0x01, &Buffer[1]); 12462306a36Sopenharmony_ci 12562306a36Sopenharmony_ci if (!((Buffer[0] == 0x06) && (Buffer[1] == 0x11))) 12662306a36Sopenharmony_ci return false; 12762306a36Sopenharmony_ci 12862306a36Sopenharmony_ci /* Check Chip ID: */ 12962306a36Sopenharmony_ci viafb_i2c_readbyte(i2c_adapter, VT1636_LVDS_I2C_ADDR, 0x02, &Buffer[0]); 13062306a36Sopenharmony_ci viafb_i2c_readbyte(i2c_adapter, VT1636_LVDS_I2C_ADDR, 0x03, &Buffer[1]); 13162306a36Sopenharmony_ci if ((Buffer[0] == 0x45) && (Buffer[1] == 0x33)) { 13262306a36Sopenharmony_ci viaparinfo->chip_info->lvds_chip_info.lvds_chip_name = 13362306a36Sopenharmony_ci VT1636_LVDS; 13462306a36Sopenharmony_ci return true; 13562306a36Sopenharmony_ci } 13662306a36Sopenharmony_ci 13762306a36Sopenharmony_ci return false; 13862306a36Sopenharmony_ci} 13962306a36Sopenharmony_ci 14062306a36Sopenharmony_cistatic int get_clk_range_index(u32 Clk) 14162306a36Sopenharmony_ci{ 14262306a36Sopenharmony_ci if (Clk < DPA_CLK_30M) 14362306a36Sopenharmony_ci return DPA_CLK_RANGE_30M; 14462306a36Sopenharmony_ci else if (Clk < DPA_CLK_50M) 14562306a36Sopenharmony_ci return DPA_CLK_RANGE_30_50M; 14662306a36Sopenharmony_ci else if (Clk < DPA_CLK_70M) 14762306a36Sopenharmony_ci return DPA_CLK_RANGE_50_70M; 14862306a36Sopenharmony_ci else if (Clk < DPA_CLK_100M) 14962306a36Sopenharmony_ci return DPA_CLK_RANGE_70_100M; 15062306a36Sopenharmony_ci else if (Clk < DPA_CLK_150M) 15162306a36Sopenharmony_ci return DPA_CLK_RANGE_100_150M; 15262306a36Sopenharmony_ci else 15362306a36Sopenharmony_ci return DPA_CLK_RANGE_150M; 15462306a36Sopenharmony_ci} 15562306a36Sopenharmony_ci 15662306a36Sopenharmony_cistatic void set_dpa_vt1636(struct lvds_setting_information 15762306a36Sopenharmony_ci *plvds_setting_info, struct lvds_chip_information *plvds_chip_info, 15862306a36Sopenharmony_ci struct VT1636_DPA_SETTING *p_vt1636_dpa_setting) 15962306a36Sopenharmony_ci{ 16062306a36Sopenharmony_ci struct IODATA io_data; 16162306a36Sopenharmony_ci 16262306a36Sopenharmony_ci io_data.Index = 0x09; 16362306a36Sopenharmony_ci io_data.Mask = 0x1F; 16462306a36Sopenharmony_ci io_data.Data = p_vt1636_dpa_setting->CLK_SEL_ST1; 16562306a36Sopenharmony_ci viafb_gpio_i2c_write_mask_lvds(plvds_setting_info, 16662306a36Sopenharmony_ci plvds_chip_info, io_data); 16762306a36Sopenharmony_ci 16862306a36Sopenharmony_ci io_data.Index = 0x08; 16962306a36Sopenharmony_ci io_data.Mask = 0x0F; 17062306a36Sopenharmony_ci io_data.Data = p_vt1636_dpa_setting->CLK_SEL_ST2; 17162306a36Sopenharmony_ci viafb_gpio_i2c_write_mask_lvds(plvds_setting_info, plvds_chip_info, 17262306a36Sopenharmony_ci io_data); 17362306a36Sopenharmony_ci} 17462306a36Sopenharmony_ci 17562306a36Sopenharmony_civoid viafb_vt1636_patch_skew_on_vt3324( 17662306a36Sopenharmony_ci struct lvds_setting_information *plvds_setting_info, 17762306a36Sopenharmony_ci struct lvds_chip_information *plvds_chip_info) 17862306a36Sopenharmony_ci{ 17962306a36Sopenharmony_ci struct VT1636_DPA_SETTING dpa = {0x00, 0x00}, dpa_16x12 = {0x0B, 0x03}, 18062306a36Sopenharmony_ci *pdpa; 18162306a36Sopenharmony_ci int index; 18262306a36Sopenharmony_ci 18362306a36Sopenharmony_ci DEBUG_MSG(KERN_INFO "viafb_vt1636_patch_skew_on_vt3324.\n"); 18462306a36Sopenharmony_ci 18562306a36Sopenharmony_ci /* Graphics DPA settings: */ 18662306a36Sopenharmony_ci index = get_clk_range_index(plvds_setting_info->vclk); 18762306a36Sopenharmony_ci viafb_set_dpa_gfx(plvds_chip_info->output_interface, 18862306a36Sopenharmony_ci &GFX_DPA_SETTING_TBL_VT3324[index]); 18962306a36Sopenharmony_ci 19062306a36Sopenharmony_ci /* LVDS Transmitter DPA settings: */ 19162306a36Sopenharmony_ci if (plvds_setting_info->lcd_panel_hres == 1600 && 19262306a36Sopenharmony_ci plvds_setting_info->lcd_panel_vres == 1200) 19362306a36Sopenharmony_ci pdpa = &dpa_16x12; 19462306a36Sopenharmony_ci else 19562306a36Sopenharmony_ci pdpa = &dpa; 19662306a36Sopenharmony_ci 19762306a36Sopenharmony_ci set_dpa_vt1636(plvds_setting_info, plvds_chip_info, pdpa); 19862306a36Sopenharmony_ci} 19962306a36Sopenharmony_ci 20062306a36Sopenharmony_civoid viafb_vt1636_patch_skew_on_vt3327( 20162306a36Sopenharmony_ci struct lvds_setting_information *plvds_setting_info, 20262306a36Sopenharmony_ci struct lvds_chip_information *plvds_chip_info) 20362306a36Sopenharmony_ci{ 20462306a36Sopenharmony_ci struct VT1636_DPA_SETTING dpa = {0x00, 0x00}; 20562306a36Sopenharmony_ci int index; 20662306a36Sopenharmony_ci 20762306a36Sopenharmony_ci DEBUG_MSG(KERN_INFO "viafb_vt1636_patch_skew_on_vt3327.\n"); 20862306a36Sopenharmony_ci 20962306a36Sopenharmony_ci /* Graphics DPA settings: */ 21062306a36Sopenharmony_ci index = get_clk_range_index(plvds_setting_info->vclk); 21162306a36Sopenharmony_ci viafb_set_dpa_gfx(plvds_chip_info->output_interface, 21262306a36Sopenharmony_ci &GFX_DPA_SETTING_TBL_VT3327[index]); 21362306a36Sopenharmony_ci 21462306a36Sopenharmony_ci /* LVDS Transmitter DPA settings: */ 21562306a36Sopenharmony_ci set_dpa_vt1636(plvds_setting_info, plvds_chip_info, &dpa); 21662306a36Sopenharmony_ci} 21762306a36Sopenharmony_ci 21862306a36Sopenharmony_civoid viafb_vt1636_patch_skew_on_vt3364( 21962306a36Sopenharmony_ci struct lvds_setting_information *plvds_setting_info, 22062306a36Sopenharmony_ci struct lvds_chip_information *plvds_chip_info) 22162306a36Sopenharmony_ci{ 22262306a36Sopenharmony_ci int index; 22362306a36Sopenharmony_ci 22462306a36Sopenharmony_ci DEBUG_MSG(KERN_INFO "viafb_vt1636_patch_skew_on_vt3364.\n"); 22562306a36Sopenharmony_ci 22662306a36Sopenharmony_ci /* Graphics DPA settings: */ 22762306a36Sopenharmony_ci index = get_clk_range_index(plvds_setting_info->vclk); 22862306a36Sopenharmony_ci viafb_set_dpa_gfx(plvds_chip_info->output_interface, 22962306a36Sopenharmony_ci &GFX_DPA_SETTING_TBL_VT3364[index]); 23062306a36Sopenharmony_ci} 231