vt1636.c 8.0 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 "via-core.h"
  19. #include "via_i2c.h"
  20. #include "global.h"
  21. u8 viafb_gpio_i2c_read_lvds(struct lvds_setting_information
  22. *plvds_setting_info, struct lvds_chip_information *plvds_chip_info,
  23. u8 index)
  24. {
  25. u8 data;
  26. viafb_i2c_readbyte(plvds_chip_info->i2c_port,
  27. plvds_chip_info->lvds_chip_slave_addr, index, &data);
  28. return data;
  29. }
  30. void viafb_gpio_i2c_write_mask_lvds(struct lvds_setting_information
  31. *plvds_setting_info, struct lvds_chip_information
  32. *plvds_chip_info, struct IODATA io_data)
  33. {
  34. int index, data;
  35. index = io_data.Index;
  36. data = viafb_gpio_i2c_read_lvds(plvds_setting_info, plvds_chip_info,
  37. index);
  38. data = (data & (~io_data.Mask)) | io_data.Data;
  39. viafb_i2c_writebyte(plvds_chip_info->i2c_port,
  40. plvds_chip_info->lvds_chip_slave_addr, index, data);
  41. }
  42. void viafb_init_lvds_vt1636(struct lvds_setting_information
  43. *plvds_setting_info, struct lvds_chip_information *plvds_chip_info)
  44. {
  45. int reg_num, i;
  46. /* Common settings: */
  47. reg_num = ARRAY_SIZE(COMMON_INIT_TBL_VT1636);
  48. for (i = 0; i < reg_num; i++) {
  49. viafb_gpio_i2c_write_mask_lvds(plvds_setting_info,
  50. plvds_chip_info,
  51. COMMON_INIT_TBL_VT1636[i]);
  52. }
  53. /* Input Data Mode Select */
  54. if (plvds_setting_info->device_lcd_dualedge) {
  55. viafb_gpio_i2c_write_mask_lvds(plvds_setting_info,
  56. plvds_chip_info,
  57. DUAL_CHANNEL_ENABLE_TBL_VT1636[0]);
  58. } else {
  59. viafb_gpio_i2c_write_mask_lvds(plvds_setting_info,
  60. plvds_chip_info,
  61. SINGLE_CHANNEL_ENABLE_TBL_VT1636[0]);
  62. }
  63. if (plvds_setting_info->LCDDithering) {
  64. viafb_gpio_i2c_write_mask_lvds(plvds_setting_info,
  65. plvds_chip_info,
  66. DITHERING_ENABLE_TBL_VT1636[0]);
  67. } else {
  68. viafb_gpio_i2c_write_mask_lvds(plvds_setting_info,
  69. plvds_chip_info,
  70. DITHERING_DISABLE_TBL_VT1636[0]);
  71. }
  72. }
  73. void viafb_enable_lvds_vt1636(struct lvds_setting_information
  74. *plvds_setting_info,
  75. struct lvds_chip_information *plvds_chip_info)
  76. {
  77. viafb_gpio_i2c_write_mask_lvds(plvds_setting_info, plvds_chip_info,
  78. VDD_ON_TBL_VT1636[0]);
  79. /* Pad on: */
  80. switch (plvds_chip_info->output_interface) {
  81. case INTERFACE_DVP0:
  82. {
  83. viafb_write_reg_mask(SR1E, VIASR, 0xC0, 0xC0);
  84. break;
  85. }
  86. case INTERFACE_DVP1:
  87. {
  88. viafb_write_reg_mask(SR1E, VIASR, 0x30, 0x30);
  89. break;
  90. }
  91. case INTERFACE_DFP_LOW:
  92. {
  93. viafb_write_reg_mask(SR2A, VIASR, 0x03, 0x03);
  94. break;
  95. }
  96. case INTERFACE_DFP_HIGH:
  97. {
  98. viafb_write_reg_mask(SR2A, VIASR, 0x03, 0x0C);
  99. break;
  100. }
  101. }
  102. }
  103. void viafb_disable_lvds_vt1636(struct lvds_setting_information
  104. *plvds_setting_info,
  105. struct lvds_chip_information *plvds_chip_info)
  106. {
  107. viafb_gpio_i2c_write_mask_lvds(plvds_setting_info, plvds_chip_info,
  108. VDD_OFF_TBL_VT1636[0]);
  109. /* Pad off: */
  110. switch (plvds_chip_info->output_interface) {
  111. case INTERFACE_DVP0:
  112. {
  113. viafb_write_reg_mask(SR1E, VIASR, 0x00, 0xC0);
  114. break;
  115. }
  116. case INTERFACE_DVP1:
  117. {
  118. viafb_write_reg_mask(SR1E, VIASR, 0x00, 0x30);
  119. break;
  120. }
  121. case INTERFACE_DFP_LOW:
  122. {
  123. viafb_write_reg_mask(SR2A, VIASR, 0x00, 0x03);
  124. break;
  125. }
  126. case INTERFACE_DFP_HIGH:
  127. {
  128. viafb_write_reg_mask(SR2A, VIASR, 0x00, 0x0C);
  129. break;
  130. }
  131. }
  132. }
  133. bool viafb_lvds_identify_vt1636(u8 i2c_adapter)
  134. {
  135. u8 Buffer[2];
  136. DEBUG_MSG(KERN_INFO "viafb_lvds_identify_vt1636.\n");
  137. /* Sense VT1636 LVDS Transmiter */
  138. viaparinfo->chip_info->lvds_chip_info.lvds_chip_slave_addr =
  139. VT1636_LVDS_I2C_ADDR;
  140. /* Check vendor ID first: */
  141. viafb_i2c_readbyte(i2c_adapter,
  142. (u8) viaparinfo->chip_info->lvds_chip_info.lvds_chip_slave_addr,
  143. 0x00, &Buffer[0]);
  144. viafb_i2c_readbyte(i2c_adapter,
  145. (u8) viaparinfo->chip_info->lvds_chip_info.lvds_chip_slave_addr,
  146. 0x01, &Buffer[1]);
  147. if (!((Buffer[0] == 0x06) && (Buffer[1] == 0x11)))
  148. return false;
  149. /* Check Chip ID: */
  150. viafb_i2c_readbyte(i2c_adapter,
  151. (u8) viaparinfo->chip_info->lvds_chip_info.lvds_chip_slave_addr,
  152. 0x02, &Buffer[0]);
  153. viafb_i2c_readbyte(i2c_adapter,
  154. (u8) viaparinfo->chip_info->lvds_chip_info.lvds_chip_slave_addr,
  155. 0x03, &Buffer[1]);
  156. if ((Buffer[0] == 0x45) && (Buffer[1] == 0x33)) {
  157. viaparinfo->chip_info->lvds_chip_info.lvds_chip_name =
  158. VT1636_LVDS;
  159. return true;
  160. }
  161. return false;
  162. }
  163. static int get_clk_range_index(u32 Clk)
  164. {
  165. if (Clk < DPA_CLK_30M)
  166. return DPA_CLK_RANGE_30M;
  167. else if (Clk < DPA_CLK_50M)
  168. return DPA_CLK_RANGE_30_50M;
  169. else if (Clk < DPA_CLK_70M)
  170. return DPA_CLK_RANGE_50_70M;
  171. else if (Clk < DPA_CLK_100M)
  172. return DPA_CLK_RANGE_70_100M;
  173. else if (Clk < DPA_CLK_150M)
  174. return DPA_CLK_RANGE_100_150M;
  175. else
  176. return DPA_CLK_RANGE_150M;
  177. }
  178. static int get_lvds_dpa_setting_index(int panel_size_id,
  179. struct VT1636_DPA_SETTING *p_vt1636_dpasetting_tbl,
  180. int tbl_size)
  181. {
  182. int i;
  183. for (i = 0; i < tbl_size; i++) {
  184. if (panel_size_id == p_vt1636_dpasetting_tbl->PanelSizeID)
  185. return i;
  186. p_vt1636_dpasetting_tbl++;
  187. }
  188. return 0;
  189. }
  190. static void set_dpa_vt1636(struct lvds_setting_information
  191. *plvds_setting_info, struct lvds_chip_information *plvds_chip_info,
  192. struct VT1636_DPA_SETTING *p_vt1636_dpa_setting)
  193. {
  194. struct IODATA io_data;
  195. io_data.Index = 0x09;
  196. io_data.Mask = 0x1F;
  197. io_data.Data = p_vt1636_dpa_setting->CLK_SEL_ST1;
  198. viafb_gpio_i2c_write_mask_lvds(plvds_setting_info,
  199. plvds_chip_info, io_data);
  200. io_data.Index = 0x08;
  201. io_data.Mask = 0x0F;
  202. io_data.Data = p_vt1636_dpa_setting->CLK_SEL_ST2;
  203. viafb_gpio_i2c_write_mask_lvds(plvds_setting_info, plvds_chip_info,
  204. io_data);
  205. }
  206. void viafb_vt1636_patch_skew_on_vt3324(
  207. struct lvds_setting_information *plvds_setting_info,
  208. struct lvds_chip_information *plvds_chip_info)
  209. {
  210. int index, size;
  211. DEBUG_MSG(KERN_INFO "viafb_vt1636_patch_skew_on_vt3324.\n");
  212. /* Graphics DPA settings: */
  213. index = get_clk_range_index(plvds_setting_info->vclk);
  214. viafb_set_dpa_gfx(plvds_chip_info->output_interface,
  215. &GFX_DPA_SETTING_TBL_VT3324[index]);
  216. /* LVDS Transmitter DPA settings: */
  217. size = ARRAY_SIZE(VT1636_DPA_SETTING_TBL_VT3324);
  218. index =
  219. get_lvds_dpa_setting_index(plvds_setting_info->lcd_panel_id,
  220. VT1636_DPA_SETTING_TBL_VT3324, size);
  221. set_dpa_vt1636(plvds_setting_info, plvds_chip_info,
  222. &VT1636_DPA_SETTING_TBL_VT3324[index]);
  223. }
  224. void viafb_vt1636_patch_skew_on_vt3327(
  225. struct lvds_setting_information *plvds_setting_info,
  226. struct lvds_chip_information *plvds_chip_info)
  227. {
  228. int index, size;
  229. DEBUG_MSG(KERN_INFO "viafb_vt1636_patch_skew_on_vt3327.\n");
  230. /* Graphics DPA settings: */
  231. index = get_clk_range_index(plvds_setting_info->vclk);
  232. viafb_set_dpa_gfx(plvds_chip_info->output_interface,
  233. &GFX_DPA_SETTING_TBL_VT3327[index]);
  234. /* LVDS Transmitter DPA settings: */
  235. size = ARRAY_SIZE(VT1636_DPA_SETTING_TBL_VT3327);
  236. index =
  237. get_lvds_dpa_setting_index(plvds_setting_info->lcd_panel_id,
  238. VT1636_DPA_SETTING_TBL_VT3327, size);
  239. set_dpa_vt1636(plvds_setting_info, plvds_chip_info,
  240. &VT1636_DPA_SETTING_TBL_VT3327[index]);
  241. }
  242. void viafb_vt1636_patch_skew_on_vt3364(
  243. struct lvds_setting_information *plvds_setting_info,
  244. struct lvds_chip_information *plvds_chip_info)
  245. {
  246. int index;
  247. DEBUG_MSG(KERN_INFO "viafb_vt1636_patch_skew_on_vt3364.\n");
  248. /* Graphics DPA settings: */
  249. index = get_clk_range_index(plvds_setting_info->vclk);
  250. viafb_set_dpa_gfx(plvds_chip_info->output_interface,
  251. &GFX_DPA_SETTING_TBL_VT3364[index]);
  252. }