0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/via-core.h>
0009 #include <linux/via_i2c.h>
0010 #include "global.h"
0011
0012 static const struct IODATA common_init_data[] = {
0013
0014
0015 {0x10, 0xC0, 0x00},
0016
0017 {0x0B, 0xFF, 0x40},
0018
0019 {0x0C, 0xFF, 0x31},
0020
0021 {0x0D, 0xFF, 0x31},
0022
0023 {0x0E, 0xFF, 0x68},
0024
0025 {0x0F, 0xFF, 0x68},
0026
0027 {0x09, 0xA0, 0xA0},
0028
0029 {0x10, 0x33, 0x13}
0030 };
0031
0032
0033 static const struct IODATA dual_channel_enable_data = {0x08, 0xF0, 0xE0};
0034 static const struct IODATA single_channel_enable_data = {0x08, 0xF0, 0x00};
0035 static const struct IODATA dithering_enable_data = {0x0A, 0x70, 0x50};
0036 static const struct IODATA dithering_disable_data = {0x0A, 0x70, 0x00};
0037 static const struct IODATA vdd_on_data = {0x10, 0x20, 0x20};
0038 static const struct IODATA vdd_off_data = {0x10, 0x20, 0x00};
0039
0040 u8 viafb_gpio_i2c_read_lvds(struct lvds_setting_information
0041 *plvds_setting_info, struct lvds_chip_information *plvds_chip_info,
0042 u8 index)
0043 {
0044 u8 data;
0045
0046 viafb_i2c_readbyte(plvds_chip_info->i2c_port,
0047 plvds_chip_info->lvds_chip_slave_addr, index, &data);
0048 return data;
0049 }
0050
0051 void viafb_gpio_i2c_write_mask_lvds(struct lvds_setting_information
0052 *plvds_setting_info, struct lvds_chip_information
0053 *plvds_chip_info, struct IODATA io_data)
0054 {
0055 int index, data;
0056
0057 index = io_data.Index;
0058 data = viafb_gpio_i2c_read_lvds(plvds_setting_info, plvds_chip_info,
0059 index);
0060 data = (data & (~io_data.Mask)) | io_data.Data;
0061
0062 viafb_i2c_writebyte(plvds_chip_info->i2c_port,
0063 plvds_chip_info->lvds_chip_slave_addr, index, data);
0064 }
0065
0066 void viafb_init_lvds_vt1636(struct lvds_setting_information
0067 *plvds_setting_info, struct lvds_chip_information *plvds_chip_info)
0068 {
0069 int reg_num, i;
0070
0071
0072 reg_num = ARRAY_SIZE(common_init_data);
0073 for (i = 0; i < reg_num; i++)
0074 viafb_gpio_i2c_write_mask_lvds(plvds_setting_info,
0075 plvds_chip_info, common_init_data[i]);
0076
0077
0078 if (plvds_setting_info->device_lcd_dualedge)
0079 viafb_gpio_i2c_write_mask_lvds(plvds_setting_info,
0080 plvds_chip_info, dual_channel_enable_data);
0081 else
0082 viafb_gpio_i2c_write_mask_lvds(plvds_setting_info,
0083 plvds_chip_info, single_channel_enable_data);
0084
0085 if (plvds_setting_info->LCDDithering)
0086 viafb_gpio_i2c_write_mask_lvds(plvds_setting_info,
0087 plvds_chip_info, dithering_enable_data);
0088 else
0089 viafb_gpio_i2c_write_mask_lvds(plvds_setting_info,
0090 plvds_chip_info, dithering_disable_data);
0091 }
0092
0093 void viafb_enable_lvds_vt1636(struct lvds_setting_information
0094 *plvds_setting_info,
0095 struct lvds_chip_information *plvds_chip_info)
0096 {
0097 viafb_gpio_i2c_write_mask_lvds(plvds_setting_info, plvds_chip_info,
0098 vdd_on_data);
0099 }
0100
0101 void viafb_disable_lvds_vt1636(struct lvds_setting_information
0102 *plvds_setting_info,
0103 struct lvds_chip_information *plvds_chip_info)
0104 {
0105 viafb_gpio_i2c_write_mask_lvds(plvds_setting_info, plvds_chip_info,
0106 vdd_off_data);
0107 }
0108
0109 bool viafb_lvds_identify_vt1636(u8 i2c_adapter)
0110 {
0111 u8 Buffer[2];
0112
0113 DEBUG_MSG(KERN_INFO "viafb_lvds_identify_vt1636.\n");
0114
0115
0116 viaparinfo->chip_info->lvds_chip_info.lvds_chip_slave_addr =
0117 VT1636_LVDS_I2C_ADDR;
0118
0119
0120 if (viafb_i2c_readbyte(i2c_adapter, VT1636_LVDS_I2C_ADDR,
0121 0x00, &Buffer[0]))
0122 return false;
0123 viafb_i2c_readbyte(i2c_adapter, VT1636_LVDS_I2C_ADDR, 0x01, &Buffer[1]);
0124
0125 if (!((Buffer[0] == 0x06) && (Buffer[1] == 0x11)))
0126 return false;
0127
0128
0129 viafb_i2c_readbyte(i2c_adapter, VT1636_LVDS_I2C_ADDR, 0x02, &Buffer[0]);
0130 viafb_i2c_readbyte(i2c_adapter, VT1636_LVDS_I2C_ADDR, 0x03, &Buffer[1]);
0131 if ((Buffer[0] == 0x45) && (Buffer[1] == 0x33)) {
0132 viaparinfo->chip_info->lvds_chip_info.lvds_chip_name =
0133 VT1636_LVDS;
0134 return true;
0135 }
0136
0137 return false;
0138 }
0139
0140 static int get_clk_range_index(u32 Clk)
0141 {
0142 if (Clk < DPA_CLK_30M)
0143 return DPA_CLK_RANGE_30M;
0144 else if (Clk < DPA_CLK_50M)
0145 return DPA_CLK_RANGE_30_50M;
0146 else if (Clk < DPA_CLK_70M)
0147 return DPA_CLK_RANGE_50_70M;
0148 else if (Clk < DPA_CLK_100M)
0149 return DPA_CLK_RANGE_70_100M;
0150 else if (Clk < DPA_CLK_150M)
0151 return DPA_CLK_RANGE_100_150M;
0152 else
0153 return DPA_CLK_RANGE_150M;
0154 }
0155
0156 static void set_dpa_vt1636(struct lvds_setting_information
0157 *plvds_setting_info, struct lvds_chip_information *plvds_chip_info,
0158 struct VT1636_DPA_SETTING *p_vt1636_dpa_setting)
0159 {
0160 struct IODATA io_data;
0161
0162 io_data.Index = 0x09;
0163 io_data.Mask = 0x1F;
0164 io_data.Data = p_vt1636_dpa_setting->CLK_SEL_ST1;
0165 viafb_gpio_i2c_write_mask_lvds(plvds_setting_info,
0166 plvds_chip_info, io_data);
0167
0168 io_data.Index = 0x08;
0169 io_data.Mask = 0x0F;
0170 io_data.Data = p_vt1636_dpa_setting->CLK_SEL_ST2;
0171 viafb_gpio_i2c_write_mask_lvds(plvds_setting_info, plvds_chip_info,
0172 io_data);
0173 }
0174
0175 void viafb_vt1636_patch_skew_on_vt3324(
0176 struct lvds_setting_information *plvds_setting_info,
0177 struct lvds_chip_information *plvds_chip_info)
0178 {
0179 struct VT1636_DPA_SETTING dpa = {0x00, 0x00}, dpa_16x12 = {0x0B, 0x03},
0180 *pdpa;
0181 int index;
0182
0183 DEBUG_MSG(KERN_INFO "viafb_vt1636_patch_skew_on_vt3324.\n");
0184
0185
0186 index = get_clk_range_index(plvds_setting_info->vclk);
0187 viafb_set_dpa_gfx(plvds_chip_info->output_interface,
0188 &GFX_DPA_SETTING_TBL_VT3324[index]);
0189
0190
0191 if (plvds_setting_info->lcd_panel_hres == 1600 &&
0192 plvds_setting_info->lcd_panel_vres == 1200)
0193 pdpa = &dpa_16x12;
0194 else
0195 pdpa = &dpa;
0196
0197 set_dpa_vt1636(plvds_setting_info, plvds_chip_info, pdpa);
0198 }
0199
0200 void viafb_vt1636_patch_skew_on_vt3327(
0201 struct lvds_setting_information *plvds_setting_info,
0202 struct lvds_chip_information *plvds_chip_info)
0203 {
0204 struct VT1636_DPA_SETTING dpa = {0x00, 0x00};
0205 int index;
0206
0207 DEBUG_MSG(KERN_INFO "viafb_vt1636_patch_skew_on_vt3327.\n");
0208
0209
0210 index = get_clk_range_index(plvds_setting_info->vclk);
0211 viafb_set_dpa_gfx(plvds_chip_info->output_interface,
0212 &GFX_DPA_SETTING_TBL_VT3327[index]);
0213
0214
0215 set_dpa_vt1636(plvds_setting_info, plvds_chip_info, &dpa);
0216 }
0217
0218 void viafb_vt1636_patch_skew_on_vt3364(
0219 struct lvds_setting_information *plvds_setting_info,
0220 struct lvds_chip_information *plvds_chip_info)
0221 {
0222 int index;
0223
0224 DEBUG_MSG(KERN_INFO "viafb_vt1636_patch_skew_on_vt3364.\n");
0225
0226
0227 index = get_clk_range_index(plvds_setting_info->vclk);
0228 viafb_set_dpa_gfx(plvds_chip_info->output_interface,
0229 &GFX_DPA_SETTING_TBL_VT3364[index]);
0230 }