vt1636.c 7.4 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. 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 void set_dpa_vt1636(struct lvds_setting_information
  145. *plvds_setting_info, struct lvds_chip_information *plvds_chip_info,
  146. struct VT1636_DPA_SETTING *p_vt1636_dpa_setting)
  147. {
  148. struct IODATA io_data;
  149. io_data.Index = 0x09;
  150. io_data.Mask = 0x1F;
  151. io_data.Data = p_vt1636_dpa_setting->CLK_SEL_ST1;
  152. viafb_gpio_i2c_write_mask_lvds(plvds_setting_info,
  153. plvds_chip_info, io_data);
  154. io_data.Index = 0x08;
  155. io_data.Mask = 0x0F;
  156. io_data.Data = p_vt1636_dpa_setting->CLK_SEL_ST2;
  157. viafb_gpio_i2c_write_mask_lvds(plvds_setting_info, plvds_chip_info,
  158. io_data);
  159. }
  160. void viafb_vt1636_patch_skew_on_vt3324(
  161. struct lvds_setting_information *plvds_setting_info,
  162. struct lvds_chip_information *plvds_chip_info)
  163. {
  164. struct VT1636_DPA_SETTING dpa = {0x00, 0x00}, dpa_16x12 = {0x0B, 0x03},
  165. *pdpa;
  166. int index;
  167. DEBUG_MSG(KERN_INFO "viafb_vt1636_patch_skew_on_vt3324.\n");
  168. /* Graphics DPA settings: */
  169. index = get_clk_range_index(plvds_setting_info->vclk);
  170. viafb_set_dpa_gfx(plvds_chip_info->output_interface,
  171. &GFX_DPA_SETTING_TBL_VT3324[index]);
  172. /* LVDS Transmitter DPA settings: */
  173. if (plvds_setting_info->lcd_panel_hres == 1600 &&
  174. plvds_setting_info->lcd_panel_vres == 1200)
  175. pdpa = &dpa_16x12;
  176. else
  177. pdpa = &dpa;
  178. set_dpa_vt1636(plvds_setting_info, plvds_chip_info, pdpa);
  179. }
  180. void viafb_vt1636_patch_skew_on_vt3327(
  181. struct lvds_setting_information *plvds_setting_info,
  182. struct lvds_chip_information *plvds_chip_info)
  183. {
  184. struct VT1636_DPA_SETTING dpa = {0x00, 0x00};
  185. int index;
  186. DEBUG_MSG(KERN_INFO "viafb_vt1636_patch_skew_on_vt3327.\n");
  187. /* Graphics DPA settings: */
  188. index = get_clk_range_index(plvds_setting_info->vclk);
  189. viafb_set_dpa_gfx(plvds_chip_info->output_interface,
  190. &GFX_DPA_SETTING_TBL_VT3327[index]);
  191. /* LVDS Transmitter DPA settings: */
  192. set_dpa_vt1636(plvds_setting_info, plvds_chip_info, &dpa);
  193. }
  194. void viafb_vt1636_patch_skew_on_vt3364(
  195. struct lvds_setting_information *plvds_setting_info,
  196. struct lvds_chip_information *plvds_chip_info)
  197. {
  198. int index;
  199. DEBUG_MSG(KERN_INFO "viafb_vt1636_patch_skew_on_vt3364.\n");
  200. /* Graphics DPA settings: */
  201. index = get_clk_range_index(plvds_setting_info->vclk);
  202. viafb_set_dpa_gfx(plvds_chip_info->output_interface,
  203. &GFX_DPA_SETTING_TBL_VT3364[index]);
  204. }