vt1636.c 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300
  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. if (viafb_i2c_readbyte(i2c_adapter, VT1636_LVDS_I2C_ADDR,
  142. 0x00, &Buffer[0]))
  143. return false;
  144. viafb_i2c_readbyte(i2c_adapter, VT1636_LVDS_I2C_ADDR, 0x01, &Buffer[1]);
  145. if (!((Buffer[0] == 0x06) && (Buffer[1] == 0x11)))
  146. return false;
  147. /* Check Chip ID: */
  148. viafb_i2c_readbyte(i2c_adapter, VT1636_LVDS_I2C_ADDR, 0x02, &Buffer[0]);
  149. viafb_i2c_readbyte(i2c_adapter, VT1636_LVDS_I2C_ADDR, 0x03, &Buffer[1]);
  150. if ((Buffer[0] == 0x45) && (Buffer[1] == 0x33)) {
  151. viaparinfo->chip_info->lvds_chip_info.lvds_chip_name =
  152. VT1636_LVDS;
  153. return true;
  154. }
  155. return false;
  156. }
  157. static int get_clk_range_index(u32 Clk)
  158. {
  159. if (Clk < DPA_CLK_30M)
  160. return DPA_CLK_RANGE_30M;
  161. else if (Clk < DPA_CLK_50M)
  162. return DPA_CLK_RANGE_30_50M;
  163. else if (Clk < DPA_CLK_70M)
  164. return DPA_CLK_RANGE_50_70M;
  165. else if (Clk < DPA_CLK_100M)
  166. return DPA_CLK_RANGE_70_100M;
  167. else if (Clk < DPA_CLK_150M)
  168. return DPA_CLK_RANGE_100_150M;
  169. else
  170. return DPA_CLK_RANGE_150M;
  171. }
  172. static int get_lvds_dpa_setting_index(int panel_size_id,
  173. struct VT1636_DPA_SETTING *p_vt1636_dpasetting_tbl,
  174. int tbl_size)
  175. {
  176. int i;
  177. for (i = 0; i < tbl_size; i++) {
  178. if (panel_size_id == p_vt1636_dpasetting_tbl->PanelSizeID)
  179. return i;
  180. p_vt1636_dpasetting_tbl++;
  181. }
  182. return 0;
  183. }
  184. static void set_dpa_vt1636(struct lvds_setting_information
  185. *plvds_setting_info, struct lvds_chip_information *plvds_chip_info,
  186. struct VT1636_DPA_SETTING *p_vt1636_dpa_setting)
  187. {
  188. struct IODATA io_data;
  189. io_data.Index = 0x09;
  190. io_data.Mask = 0x1F;
  191. io_data.Data = p_vt1636_dpa_setting->CLK_SEL_ST1;
  192. viafb_gpio_i2c_write_mask_lvds(plvds_setting_info,
  193. plvds_chip_info, io_data);
  194. io_data.Index = 0x08;
  195. io_data.Mask = 0x0F;
  196. io_data.Data = p_vt1636_dpa_setting->CLK_SEL_ST2;
  197. viafb_gpio_i2c_write_mask_lvds(plvds_setting_info, plvds_chip_info,
  198. io_data);
  199. }
  200. void viafb_vt1636_patch_skew_on_vt3324(
  201. struct lvds_setting_information *plvds_setting_info,
  202. struct lvds_chip_information *plvds_chip_info)
  203. {
  204. int index, size;
  205. DEBUG_MSG(KERN_INFO "viafb_vt1636_patch_skew_on_vt3324.\n");
  206. /* Graphics DPA settings: */
  207. index = get_clk_range_index(plvds_setting_info->vclk);
  208. viafb_set_dpa_gfx(plvds_chip_info->output_interface,
  209. &GFX_DPA_SETTING_TBL_VT3324[index]);
  210. /* LVDS Transmitter DPA settings: */
  211. size = ARRAY_SIZE(VT1636_DPA_SETTING_TBL_VT3324);
  212. index =
  213. get_lvds_dpa_setting_index(plvds_setting_info->lcd_panel_id,
  214. VT1636_DPA_SETTING_TBL_VT3324, size);
  215. set_dpa_vt1636(plvds_setting_info, plvds_chip_info,
  216. &VT1636_DPA_SETTING_TBL_VT3324[index]);
  217. }
  218. void viafb_vt1636_patch_skew_on_vt3327(
  219. struct lvds_setting_information *plvds_setting_info,
  220. struct lvds_chip_information *plvds_chip_info)
  221. {
  222. int index, size;
  223. DEBUG_MSG(KERN_INFO "viafb_vt1636_patch_skew_on_vt3327.\n");
  224. /* Graphics DPA settings: */
  225. index = get_clk_range_index(plvds_setting_info->vclk);
  226. viafb_set_dpa_gfx(plvds_chip_info->output_interface,
  227. &GFX_DPA_SETTING_TBL_VT3327[index]);
  228. /* LVDS Transmitter DPA settings: */
  229. size = ARRAY_SIZE(VT1636_DPA_SETTING_TBL_VT3327);
  230. index =
  231. get_lvds_dpa_setting_index(plvds_setting_info->lcd_panel_id,
  232. VT1636_DPA_SETTING_TBL_VT3327, size);
  233. set_dpa_vt1636(plvds_setting_info, plvds_chip_info,
  234. &VT1636_DPA_SETTING_TBL_VT3327[index]);
  235. }
  236. void viafb_vt1636_patch_skew_on_vt3364(
  237. struct lvds_setting_information *plvds_setting_info,
  238. struct lvds_chip_information *plvds_chip_info)
  239. {
  240. int index;
  241. DEBUG_MSG(KERN_INFO "viafb_vt1636_patch_skew_on_vt3364.\n");
  242. /* Graphics DPA settings: */
  243. index = get_clk_range_index(plvds_setting_info->vclk);
  244. viafb_set_dpa_gfx(plvds_chip_info->output_interface,
  245. &GFX_DPA_SETTING_TBL_VT3364[index]);
  246. }