vt1636.c 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  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. static const struct IODATA common_init_data[] = {
  22. /* Index, Mask, Value */
  23. /* Set panel power sequence timing */
  24. {0x10, 0xC0, 0x00},
  25. /* T1: VDD on - Data on. Each increment is 1 ms. (50ms = 031h) */
  26. {0x0B, 0xFF, 0x40},
  27. /* T2: Data on - Backlight on. Each increment is 2 ms. (210ms = 068h) */
  28. {0x0C, 0xFF, 0x31},
  29. /* T3: Backlight off -Data off. Each increment is 2 ms. (210ms = 068h)*/
  30. {0x0D, 0xFF, 0x31},
  31. /* T4: Data off - VDD off. Each increment is 1 ms. (50ms = 031h) */
  32. {0x0E, 0xFF, 0x68},
  33. /* T5: VDD off - VDD on. Each increment is 100 ms. (500ms = 04h) */
  34. {0x0F, 0xFF, 0x68},
  35. /* LVDS output power up */
  36. {0x09, 0xA0, 0xA0},
  37. /* turn on back light */
  38. {0x10, 0x33, 0x13}
  39. };
  40. /* Index, Mask, Value */
  41. static const struct IODATA dual_channel_enable_data = {0x08, 0xF0, 0xE0};
  42. static const struct IODATA single_channel_enable_data = {0x08, 0xF0, 0x00};
  43. static const struct IODATA dithering_enable_data = {0x0A, 0x70, 0x50};
  44. static const struct IODATA dithering_disable_data = {0x0A, 0x70, 0x00};
  45. static const struct IODATA vdd_on_data = {0x10, 0x20, 0x20};
  46. static const struct IODATA vdd_off_data = {0x10, 0x20, 0x00};
  47. u8 viafb_gpio_i2c_read_lvds(struct lvds_setting_information
  48. *plvds_setting_info, struct lvds_chip_information *plvds_chip_info,
  49. u8 index)
  50. {
  51. u8 data;
  52. viafb_i2c_readbyte(plvds_chip_info->i2c_port,
  53. plvds_chip_info->lvds_chip_slave_addr, index, &data);
  54. return data;
  55. }
  56. void viafb_gpio_i2c_write_mask_lvds(struct lvds_setting_information
  57. *plvds_setting_info, struct lvds_chip_information
  58. *plvds_chip_info, struct IODATA io_data)
  59. {
  60. int index, data;
  61. index = io_data.Index;
  62. data = viafb_gpio_i2c_read_lvds(plvds_setting_info, plvds_chip_info,
  63. index);
  64. data = (data & (~io_data.Mask)) | io_data.Data;
  65. viafb_i2c_writebyte(plvds_chip_info->i2c_port,
  66. plvds_chip_info->lvds_chip_slave_addr, index, data);
  67. }
  68. void viafb_init_lvds_vt1636(struct lvds_setting_information
  69. *plvds_setting_info, struct lvds_chip_information *plvds_chip_info)
  70. {
  71. int reg_num, i;
  72. /* Common settings: */
  73. reg_num = ARRAY_SIZE(common_init_data);
  74. for (i = 0; i < reg_num; i++)
  75. viafb_gpio_i2c_write_mask_lvds(plvds_setting_info,
  76. plvds_chip_info, common_init_data[i]);
  77. /* Input Data Mode Select */
  78. if (plvds_setting_info->device_lcd_dualedge)
  79. viafb_gpio_i2c_write_mask_lvds(plvds_setting_info,
  80. plvds_chip_info, dual_channel_enable_data);
  81. else
  82. viafb_gpio_i2c_write_mask_lvds(plvds_setting_info,
  83. plvds_chip_info, single_channel_enable_data);
  84. if (plvds_setting_info->LCDDithering)
  85. viafb_gpio_i2c_write_mask_lvds(plvds_setting_info,
  86. plvds_chip_info, dithering_enable_data);
  87. else
  88. viafb_gpio_i2c_write_mask_lvds(plvds_setting_info,
  89. plvds_chip_info, dithering_disable_data);
  90. }
  91. void viafb_enable_lvds_vt1636(struct lvds_setting_information
  92. *plvds_setting_info,
  93. struct lvds_chip_information *plvds_chip_info)
  94. {
  95. viafb_gpio_i2c_write_mask_lvds(plvds_setting_info, plvds_chip_info,
  96. vdd_on_data);
  97. }
  98. void viafb_disable_lvds_vt1636(struct lvds_setting_information
  99. *plvds_setting_info,
  100. struct lvds_chip_information *plvds_chip_info)
  101. {
  102. viafb_gpio_i2c_write_mask_lvds(plvds_setting_info, plvds_chip_info,
  103. vdd_off_data);
  104. }
  105. bool viafb_lvds_identify_vt1636(u8 i2c_adapter)
  106. {
  107. u8 Buffer[2];
  108. DEBUG_MSG(KERN_INFO "viafb_lvds_identify_vt1636.\n");
  109. /* Sense VT1636 LVDS Transmiter */
  110. viaparinfo->chip_info->lvds_chip_info.lvds_chip_slave_addr =
  111. VT1636_LVDS_I2C_ADDR;
  112. /* Check vendor ID first: */
  113. if (viafb_i2c_readbyte(i2c_adapter, VT1636_LVDS_I2C_ADDR,
  114. 0x00, &Buffer[0]))
  115. return false;
  116. viafb_i2c_readbyte(i2c_adapter, VT1636_LVDS_I2C_ADDR, 0x01, &Buffer[1]);
  117. if (!((Buffer[0] == 0x06) && (Buffer[1] == 0x11)))
  118. return false;
  119. /* Check Chip ID: */
  120. viafb_i2c_readbyte(i2c_adapter, VT1636_LVDS_I2C_ADDR, 0x02, &Buffer[0]);
  121. viafb_i2c_readbyte(i2c_adapter, VT1636_LVDS_I2C_ADDR, 0x03, &Buffer[1]);
  122. if ((Buffer[0] == 0x45) && (Buffer[1] == 0x33)) {
  123. viaparinfo->chip_info->lvds_chip_info.lvds_chip_name =
  124. VT1636_LVDS;
  125. return true;
  126. }
  127. return false;
  128. }
  129. static int get_clk_range_index(u32 Clk)
  130. {
  131. if (Clk < DPA_CLK_30M)
  132. return DPA_CLK_RANGE_30M;
  133. else if (Clk < DPA_CLK_50M)
  134. return DPA_CLK_RANGE_30_50M;
  135. else if (Clk < DPA_CLK_70M)
  136. return DPA_CLK_RANGE_50_70M;
  137. else if (Clk < DPA_CLK_100M)
  138. return DPA_CLK_RANGE_70_100M;
  139. else if (Clk < DPA_CLK_150M)
  140. return DPA_CLK_RANGE_100_150M;
  141. else
  142. return DPA_CLK_RANGE_150M;
  143. }
  144. static int get_lvds_dpa_setting_index(int panel_size_id,
  145. struct VT1636_DPA_SETTING *p_vt1636_dpasetting_tbl,
  146. int tbl_size)
  147. {
  148. int i;
  149. for (i = 0; i < tbl_size; i++) {
  150. if (panel_size_id == p_vt1636_dpasetting_tbl->PanelSizeID)
  151. return i;
  152. p_vt1636_dpasetting_tbl++;
  153. }
  154. return 0;
  155. }
  156. static void set_dpa_vt1636(struct lvds_setting_information
  157. *plvds_setting_info, struct lvds_chip_information *plvds_chip_info,
  158. struct VT1636_DPA_SETTING *p_vt1636_dpa_setting)
  159. {
  160. struct IODATA io_data;
  161. io_data.Index = 0x09;
  162. io_data.Mask = 0x1F;
  163. io_data.Data = p_vt1636_dpa_setting->CLK_SEL_ST1;
  164. viafb_gpio_i2c_write_mask_lvds(plvds_setting_info,
  165. plvds_chip_info, io_data);
  166. io_data.Index = 0x08;
  167. io_data.Mask = 0x0F;
  168. io_data.Data = p_vt1636_dpa_setting->CLK_SEL_ST2;
  169. viafb_gpio_i2c_write_mask_lvds(plvds_setting_info, plvds_chip_info,
  170. io_data);
  171. }
  172. void viafb_vt1636_patch_skew_on_vt3324(
  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_vt3324.\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_VT3324[index]);
  182. /* LVDS Transmitter DPA settings: */
  183. size = ARRAY_SIZE(VT1636_DPA_SETTING_TBL_VT3324);
  184. index =
  185. get_lvds_dpa_setting_index(plvds_setting_info->lcd_panel_id,
  186. VT1636_DPA_SETTING_TBL_VT3324, size);
  187. set_dpa_vt1636(plvds_setting_info, plvds_chip_info,
  188. &VT1636_DPA_SETTING_TBL_VT3324[index]);
  189. }
  190. void viafb_vt1636_patch_skew_on_vt3327(
  191. struct lvds_setting_information *plvds_setting_info,
  192. struct lvds_chip_information *plvds_chip_info)
  193. {
  194. int index, size;
  195. DEBUG_MSG(KERN_INFO "viafb_vt1636_patch_skew_on_vt3327.\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_VT3327[index]);
  200. /* LVDS Transmitter DPA settings: */
  201. size = ARRAY_SIZE(VT1636_DPA_SETTING_TBL_VT3327);
  202. index =
  203. get_lvds_dpa_setting_index(plvds_setting_info->lcd_panel_id,
  204. VT1636_DPA_SETTING_TBL_VT3327, size);
  205. set_dpa_vt1636(plvds_setting_info, plvds_chip_info,
  206. &VT1636_DPA_SETTING_TBL_VT3327[index]);
  207. }
  208. void viafb_vt1636_patch_skew_on_vt3364(
  209. struct lvds_setting_information *plvds_setting_info,
  210. struct lvds_chip_information *plvds_chip_info)
  211. {
  212. int index;
  213. DEBUG_MSG(KERN_INFO "viafb_vt1636_patch_skew_on_vt3364.\n");
  214. /* Graphics DPA settings: */
  215. index = get_clk_range_index(plvds_setting_info->vclk);
  216. viafb_set_dpa_gfx(plvds_chip_info->output_interface,
  217. &GFX_DPA_SETTING_TBL_VT3364[index]);
  218. }