vt1636.c 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  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 <linux/via-core.h>
  19. #include <linux/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. }
  80. void viafb_disable_lvds_vt1636(struct lvds_setting_information
  81. *plvds_setting_info,
  82. struct lvds_chip_information *plvds_chip_info)
  83. {
  84. viafb_gpio_i2c_write_mask_lvds(plvds_setting_info, plvds_chip_info,
  85. VDD_OFF_TBL_VT1636[0]);
  86. }
  87. bool viafb_lvds_identify_vt1636(u8 i2c_adapter)
  88. {
  89. u8 Buffer[2];
  90. DEBUG_MSG(KERN_INFO "viafb_lvds_identify_vt1636.\n");
  91. /* Sense VT1636 LVDS Transmiter */
  92. viaparinfo->chip_info->lvds_chip_info.lvds_chip_slave_addr =
  93. VT1636_LVDS_I2C_ADDR;
  94. /* Check vendor ID first: */
  95. if (viafb_i2c_readbyte(i2c_adapter, VT1636_LVDS_I2C_ADDR,
  96. 0x00, &Buffer[0]))
  97. return false;
  98. viafb_i2c_readbyte(i2c_adapter, VT1636_LVDS_I2C_ADDR, 0x01, &Buffer[1]);
  99. if (!((Buffer[0] == 0x06) && (Buffer[1] == 0x11)))
  100. return false;
  101. /* Check Chip ID: */
  102. viafb_i2c_readbyte(i2c_adapter, VT1636_LVDS_I2C_ADDR, 0x02, &Buffer[0]);
  103. viafb_i2c_readbyte(i2c_adapter, VT1636_LVDS_I2C_ADDR, 0x03, &Buffer[1]);
  104. if ((Buffer[0] == 0x45) && (Buffer[1] == 0x33)) {
  105. viaparinfo->chip_info->lvds_chip_info.lvds_chip_name =
  106. VT1636_LVDS;
  107. return true;
  108. }
  109. return false;
  110. }
  111. static int get_clk_range_index(u32 Clk)
  112. {
  113. if (Clk < DPA_CLK_30M)
  114. return DPA_CLK_RANGE_30M;
  115. else if (Clk < DPA_CLK_50M)
  116. return DPA_CLK_RANGE_30_50M;
  117. else if (Clk < DPA_CLK_70M)
  118. return DPA_CLK_RANGE_50_70M;
  119. else if (Clk < DPA_CLK_100M)
  120. return DPA_CLK_RANGE_70_100M;
  121. else if (Clk < DPA_CLK_150M)
  122. return DPA_CLK_RANGE_100_150M;
  123. else
  124. return DPA_CLK_RANGE_150M;
  125. }
  126. static int get_lvds_dpa_setting_index(int panel_size_id,
  127. struct VT1636_DPA_SETTING *p_vt1636_dpasetting_tbl,
  128. int tbl_size)
  129. {
  130. int i;
  131. for (i = 0; i < tbl_size; i++) {
  132. if (panel_size_id == p_vt1636_dpasetting_tbl->PanelSizeID)
  133. return i;
  134. p_vt1636_dpasetting_tbl++;
  135. }
  136. return 0;
  137. }
  138. static void set_dpa_vt1636(struct lvds_setting_information
  139. *plvds_setting_info, struct lvds_chip_information *plvds_chip_info,
  140. struct VT1636_DPA_SETTING *p_vt1636_dpa_setting)
  141. {
  142. struct IODATA io_data;
  143. io_data.Index = 0x09;
  144. io_data.Mask = 0x1F;
  145. io_data.Data = p_vt1636_dpa_setting->CLK_SEL_ST1;
  146. viafb_gpio_i2c_write_mask_lvds(plvds_setting_info,
  147. plvds_chip_info, io_data);
  148. io_data.Index = 0x08;
  149. io_data.Mask = 0x0F;
  150. io_data.Data = p_vt1636_dpa_setting->CLK_SEL_ST2;
  151. viafb_gpio_i2c_write_mask_lvds(plvds_setting_info, plvds_chip_info,
  152. io_data);
  153. }
  154. void viafb_vt1636_patch_skew_on_vt3324(
  155. struct lvds_setting_information *plvds_setting_info,
  156. struct lvds_chip_information *plvds_chip_info)
  157. {
  158. int index, size;
  159. DEBUG_MSG(KERN_INFO "viafb_vt1636_patch_skew_on_vt3324.\n");
  160. /* Graphics DPA settings: */
  161. index = get_clk_range_index(plvds_setting_info->vclk);
  162. viafb_set_dpa_gfx(plvds_chip_info->output_interface,
  163. &GFX_DPA_SETTING_TBL_VT3324[index]);
  164. /* LVDS Transmitter DPA settings: */
  165. size = ARRAY_SIZE(VT1636_DPA_SETTING_TBL_VT3324);
  166. index =
  167. get_lvds_dpa_setting_index(plvds_setting_info->lcd_panel_id,
  168. VT1636_DPA_SETTING_TBL_VT3324, size);
  169. set_dpa_vt1636(plvds_setting_info, plvds_chip_info,
  170. &VT1636_DPA_SETTING_TBL_VT3324[index]);
  171. }
  172. void viafb_vt1636_patch_skew_on_vt3327(
  173. struct lvds_setting_information *plvds_setting_info,
  174. struct lvds_chip_information *plvds_chip_info)
  175. {
  176. int index, size;
  177. DEBUG_MSG(KERN_INFO "viafb_vt1636_patch_skew_on_vt3327.\n");
  178. /* Graphics DPA settings: */
  179. index = get_clk_range_index(plvds_setting_info->vclk);
  180. viafb_set_dpa_gfx(plvds_chip_info->output_interface,
  181. &GFX_DPA_SETTING_TBL_VT3327[index]);
  182. /* LVDS Transmitter DPA settings: */
  183. size = ARRAY_SIZE(VT1636_DPA_SETTING_TBL_VT3327);
  184. index =
  185. get_lvds_dpa_setting_index(plvds_setting_info->lcd_panel_id,
  186. VT1636_DPA_SETTING_TBL_VT3327, size);
  187. set_dpa_vt1636(plvds_setting_info, plvds_chip_info,
  188. &VT1636_DPA_SETTING_TBL_VT3327[index]);
  189. }
  190. void viafb_vt1636_patch_skew_on_vt3364(
  191. struct lvds_setting_information *plvds_setting_info,
  192. struct lvds_chip_information *plvds_chip_info)
  193. {
  194. int index;
  195. DEBUG_MSG(KERN_INFO "viafb_vt1636_patch_skew_on_vt3364.\n");
  196. /* Graphics DPA settings: */
  197. index = get_clk_range_index(plvds_setting_info->vclk);
  198. viafb_set_dpa_gfx(plvds_chip_info->output_interface,
  199. &GFX_DPA_SETTING_TBL_VT3364[index]);
  200. }