vt1636.c 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306
  1. /*
  2. * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
  3. * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
  4. * This program is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU General Public
  6. * License as published by the Free Software Foundation;
  7. * either version 2, or (at your option) any later version.
  8. * This program is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
  10. * the implied warranty of MERCHANTABILITY or FITNESS FOR
  11. * A PARTICULAR PURPOSE.See the GNU General Public License
  12. * for more details.
  13. * You should have received a copy of the GNU General Public License
  14. * along with this program; if not, write to the Free Software
  15. * Foundation, Inc.,
  16. * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  17. */
  18. #include "global.h"
  19. u8 viafb_gpio_i2c_read_lvds(struct lvds_setting_information
  20. *plvds_setting_info, struct lvds_chip_information *plvds_chip_info,
  21. u8 index)
  22. {
  23. u8 data;
  24. viaparinfo->shared->i2c_stuff.i2c_port = plvds_chip_info->i2c_port;
  25. viafb_i2c_readbyte(plvds_chip_info->lvds_chip_slave_addr, index, &data);
  26. return data;
  27. }
  28. void viafb_gpio_i2c_write_mask_lvds(struct lvds_setting_information
  29. *plvds_setting_info, struct lvds_chip_information
  30. *plvds_chip_info, struct IODATA io_data)
  31. {
  32. int index, data;
  33. viaparinfo->shared->i2c_stuff.i2c_port = plvds_chip_info->i2c_port;
  34. index = io_data.Index;
  35. data = viafb_gpio_i2c_read_lvds(plvds_setting_info, plvds_chip_info,
  36. index);
  37. data = (data & (~io_data.Mask)) | io_data.Data;
  38. viafb_i2c_writebyte(plvds_chip_info->lvds_chip_slave_addr, index, data);
  39. }
  40. void viafb_init_lvds_vt1636(struct lvds_setting_information
  41. *plvds_setting_info, struct lvds_chip_information *plvds_chip_info)
  42. {
  43. int reg_num, i;
  44. /* Common settings: */
  45. reg_num = ARRAY_SIZE(COMMON_INIT_TBL_VT1636);
  46. for (i = 0; i < reg_num; i++) {
  47. viafb_gpio_i2c_write_mask_lvds(plvds_setting_info,
  48. plvds_chip_info,
  49. COMMON_INIT_TBL_VT1636[i]);
  50. }
  51. /* Input Data Mode Select */
  52. if (plvds_setting_info->device_lcd_dualedge) {
  53. viafb_gpio_i2c_write_mask_lvds(plvds_setting_info,
  54. plvds_chip_info,
  55. DUAL_CHANNEL_ENABLE_TBL_VT1636[0]);
  56. } else {
  57. viafb_gpio_i2c_write_mask_lvds(plvds_setting_info,
  58. plvds_chip_info,
  59. SINGLE_CHANNEL_ENABLE_TBL_VT1636[0]);
  60. }
  61. if (plvds_setting_info->LCDDithering) {
  62. viafb_gpio_i2c_write_mask_lvds(plvds_setting_info,
  63. plvds_chip_info,
  64. DITHERING_ENABLE_TBL_VT1636[0]);
  65. } else {
  66. viafb_gpio_i2c_write_mask_lvds(plvds_setting_info,
  67. plvds_chip_info,
  68. DITHERING_DISABLE_TBL_VT1636[0]);
  69. }
  70. }
  71. void viafb_enable_lvds_vt1636(struct lvds_setting_information
  72. *plvds_setting_info,
  73. struct lvds_chip_information *plvds_chip_info)
  74. {
  75. viafb_gpio_i2c_write_mask_lvds(plvds_setting_info, plvds_chip_info,
  76. VDD_ON_TBL_VT1636[0]);
  77. /* Pad on: */
  78. switch (plvds_chip_info->output_interface) {
  79. case INTERFACE_DVP0:
  80. {
  81. viafb_write_reg_mask(SR1E, VIASR, 0xC0, 0xC0);
  82. break;
  83. }
  84. case INTERFACE_DVP1:
  85. {
  86. viafb_write_reg_mask(SR1E, VIASR, 0x30, 0x30);
  87. break;
  88. }
  89. case INTERFACE_DFP_LOW:
  90. {
  91. viafb_write_reg_mask(SR2A, VIASR, 0x03, 0x03);
  92. break;
  93. }
  94. case INTERFACE_DFP_HIGH:
  95. {
  96. viafb_write_reg_mask(SR2A, VIASR, 0x03, 0x0C);
  97. break;
  98. }
  99. }
  100. }
  101. void viafb_disable_lvds_vt1636(struct lvds_setting_information
  102. *plvds_setting_info,
  103. struct lvds_chip_information *plvds_chip_info)
  104. {
  105. viafb_gpio_i2c_write_mask_lvds(plvds_setting_info, plvds_chip_info,
  106. VDD_OFF_TBL_VT1636[0]);
  107. /* Pad off: */
  108. switch (plvds_chip_info->output_interface) {
  109. case INTERFACE_DVP0:
  110. {
  111. viafb_write_reg_mask(SR1E, VIASR, 0x00, 0xC0);
  112. break;
  113. }
  114. case INTERFACE_DVP1:
  115. {
  116. viafb_write_reg_mask(SR1E, VIASR, 0x00, 0x30);
  117. break;
  118. }
  119. case INTERFACE_DFP_LOW:
  120. {
  121. viafb_write_reg_mask(SR2A, VIASR, 0x00, 0x03);
  122. break;
  123. }
  124. case INTERFACE_DFP_HIGH:
  125. {
  126. viafb_write_reg_mask(SR2A, VIASR, 0x00, 0x0C);
  127. break;
  128. }
  129. }
  130. }
  131. bool viafb_lvds_identify_vt1636(void)
  132. {
  133. u8 Buffer[2];
  134. DEBUG_MSG(KERN_INFO "viafb_lvds_identify_vt1636.\n");
  135. /* Sense VT1636 LVDS Transmiter */
  136. viaparinfo->chip_info->lvds_chip_info.lvds_chip_slave_addr =
  137. VT1636_LVDS_I2C_ADDR;
  138. /* Check vendor ID first: */
  139. viafb_i2c_readbyte((u8) viaparinfo->chip_info->lvds_chip_info.
  140. lvds_chip_slave_addr,
  141. 0x00, &Buffer[0]);
  142. viafb_i2c_readbyte((u8) viaparinfo->chip_info->lvds_chip_info.
  143. lvds_chip_slave_addr,
  144. 0x01, &Buffer[1]);
  145. if (!((Buffer[0] == 0x06) && (Buffer[1] == 0x11)))
  146. return false;
  147. /* Check Chip ID: */
  148. viafb_i2c_readbyte((u8) viaparinfo->chip_info->lvds_chip_info.
  149. lvds_chip_slave_addr,
  150. 0x02, &Buffer[0]);
  151. viafb_i2c_readbyte((u8) viaparinfo->chip_info->lvds_chip_info.
  152. lvds_chip_slave_addr,
  153. 0x03, &Buffer[1]);
  154. if ((Buffer[0] == 0x45) && (Buffer[1] == 0x33)) {
  155. viaparinfo->chip_info->lvds_chip_info.lvds_chip_name =
  156. VT1636_LVDS;
  157. return true;
  158. }
  159. return false;
  160. }
  161. static int get_clk_range_index(u32 Clk)
  162. {
  163. if (Clk < DPA_CLK_30M)
  164. return DPA_CLK_RANGE_30M;
  165. else if (Clk < DPA_CLK_50M)
  166. return DPA_CLK_RANGE_30_50M;
  167. else if (Clk < DPA_CLK_70M)
  168. return DPA_CLK_RANGE_50_70M;
  169. else if (Clk < DPA_CLK_100M)
  170. return DPA_CLK_RANGE_70_100M;
  171. else if (Clk < DPA_CLK_150M)
  172. return DPA_CLK_RANGE_100_150M;
  173. else
  174. return DPA_CLK_RANGE_150M;
  175. }
  176. static int get_lvds_dpa_setting_index(int panel_size_id,
  177. struct VT1636_DPA_SETTING *p_vt1636_dpasetting_tbl,
  178. int tbl_size)
  179. {
  180. int i;
  181. for (i = 0; i < tbl_size; i++) {
  182. if (panel_size_id == p_vt1636_dpasetting_tbl->PanelSizeID)
  183. return i;
  184. p_vt1636_dpasetting_tbl++;
  185. }
  186. return 0;
  187. }
  188. static void set_dpa_vt1636(struct lvds_setting_information
  189. *plvds_setting_info, struct lvds_chip_information *plvds_chip_info,
  190. struct VT1636_DPA_SETTING *p_vt1636_dpa_setting)
  191. {
  192. struct IODATA io_data;
  193. io_data.Index = 0x09;
  194. io_data.Mask = 0x1F;
  195. io_data.Data = p_vt1636_dpa_setting->CLK_SEL_ST1;
  196. viafb_gpio_i2c_write_mask_lvds(plvds_setting_info,
  197. plvds_chip_info, io_data);
  198. io_data.Index = 0x08;
  199. io_data.Mask = 0x0F;
  200. io_data.Data = p_vt1636_dpa_setting->CLK_SEL_ST2;
  201. viafb_gpio_i2c_write_mask_lvds(plvds_setting_info, plvds_chip_info,
  202. io_data);
  203. }
  204. void viafb_vt1636_patch_skew_on_vt3324(
  205. struct lvds_setting_information *plvds_setting_info,
  206. struct lvds_chip_information *plvds_chip_info)
  207. {
  208. int index, size;
  209. DEBUG_MSG(KERN_INFO "viafb_vt1636_patch_skew_on_vt3324.\n");
  210. /* Graphics DPA settings: */
  211. index = get_clk_range_index(plvds_setting_info->vclk);
  212. viafb_set_dpa_gfx(plvds_chip_info->output_interface,
  213. &GFX_DPA_SETTING_TBL_VT3324[index]);
  214. /* LVDS Transmitter DPA settings: */
  215. size = ARRAY_SIZE(VT1636_DPA_SETTING_TBL_VT3324);
  216. index =
  217. get_lvds_dpa_setting_index(plvds_setting_info->lcd_panel_id,
  218. VT1636_DPA_SETTING_TBL_VT3324, size);
  219. set_dpa_vt1636(plvds_setting_info, plvds_chip_info,
  220. &VT1636_DPA_SETTING_TBL_VT3324[index]);
  221. }
  222. void viafb_vt1636_patch_skew_on_vt3327(
  223. struct lvds_setting_information *plvds_setting_info,
  224. struct lvds_chip_information *plvds_chip_info)
  225. {
  226. int index, size;
  227. DEBUG_MSG(KERN_INFO "viafb_vt1636_patch_skew_on_vt3327.\n");
  228. /* Graphics DPA settings: */
  229. index = get_clk_range_index(plvds_setting_info->vclk);
  230. viafb_set_dpa_gfx(plvds_chip_info->output_interface,
  231. &GFX_DPA_SETTING_TBL_VT3327[index]);
  232. /* LVDS Transmitter DPA settings: */
  233. size = ARRAY_SIZE(VT1636_DPA_SETTING_TBL_VT3327);
  234. index =
  235. get_lvds_dpa_setting_index(plvds_setting_info->lcd_panel_id,
  236. VT1636_DPA_SETTING_TBL_VT3327, size);
  237. set_dpa_vt1636(plvds_setting_info, plvds_chip_info,
  238. &VT1636_DPA_SETTING_TBL_VT3327[index]);
  239. }
  240. void viafb_vt1636_patch_skew_on_vt3364(
  241. struct lvds_setting_information *plvds_setting_info,
  242. struct lvds_chip_information *plvds_chip_info)
  243. {
  244. int index;
  245. DEBUG_MSG(KERN_INFO "viafb_vt1636_patch_skew_on_vt3364.\n");
  246. /* Graphics DPA settings: */
  247. index = get_clk_range_index(plvds_setting_info->vclk);
  248. viafb_set_dpa_gfx(plvds_chip_info->output_interface,
  249. &GFX_DPA_SETTING_TBL_VT3364[index]);
  250. }