Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
vt1636.c
Go to the documentation of this file.
1 /*
2  * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
3  * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
4 
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public
7  * License as published by the Free Software Foundation;
8  * either version 2, or (at your option) any later version.
9 
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
12  * the implied warranty of MERCHANTABILITY or FITNESS FOR
13  * A PARTICULAR PURPOSE.See the GNU General Public License
14  * for more details.
15 
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc.,
19  * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20  */
21 
22 #include <linux/via-core.h>
23 #include <linux/via_i2c.h>
24 #include "global.h"
25 
26 static const struct IODATA common_init_data[] = {
27 /* Index, Mask, Value */
28  /* Set panel power sequence timing */
29  {0x10, 0xC0, 0x00},
30  /* T1: VDD on - Data on. Each increment is 1 ms. (50ms = 031h) */
31  {0x0B, 0xFF, 0x40},
32  /* T2: Data on - Backlight on. Each increment is 2 ms. (210ms = 068h) */
33  {0x0C, 0xFF, 0x31},
34  /* T3: Backlight off -Data off. Each increment is 2 ms. (210ms = 068h)*/
35  {0x0D, 0xFF, 0x31},
36  /* T4: Data off - VDD off. Each increment is 1 ms. (50ms = 031h) */
37  {0x0E, 0xFF, 0x68},
38  /* T5: VDD off - VDD on. Each increment is 100 ms. (500ms = 04h) */
39  {0x0F, 0xFF, 0x68},
40  /* LVDS output power up */
41  {0x09, 0xA0, 0xA0},
42  /* turn on back light */
43  {0x10, 0x33, 0x13}
44 };
45 
46 /* Index, Mask, Value */
47 static const struct IODATA dual_channel_enable_data = {0x08, 0xF0, 0xE0};
48 static const struct IODATA single_channel_enable_data = {0x08, 0xF0, 0x00};
49 static const struct IODATA dithering_enable_data = {0x0A, 0x70, 0x50};
50 static const struct IODATA dithering_disable_data = {0x0A, 0x70, 0x00};
51 static const struct IODATA vdd_on_data = {0x10, 0x20, 0x20};
52 static const struct IODATA vdd_off_data = {0x10, 0x20, 0x00};
53 
55  *plvds_setting_info, struct lvds_chip_information *plvds_chip_info,
56  u8 index)
57 {
58  u8 data;
59 
60  viafb_i2c_readbyte(plvds_chip_info->i2c_port,
61  plvds_chip_info->lvds_chip_slave_addr, index, &data);
62  return data;
63 }
64 
66  *plvds_setting_info, struct lvds_chip_information
67  *plvds_chip_info, struct IODATA io_data)
68 {
69  int index, data;
70 
71  index = io_data.Index;
72  data = viafb_gpio_i2c_read_lvds(plvds_setting_info, plvds_chip_info,
73  index);
74  data = (data & (~io_data.Mask)) | io_data.Data;
75 
76  viafb_i2c_writebyte(plvds_chip_info->i2c_port,
77  plvds_chip_info->lvds_chip_slave_addr, index, data);
78 }
79 
81  *plvds_setting_info, struct lvds_chip_information *plvds_chip_info)
82 {
83  int reg_num, i;
84 
85  /* Common settings: */
86  reg_num = ARRAY_SIZE(common_init_data);
87  for (i = 0; i < reg_num; i++)
88  viafb_gpio_i2c_write_mask_lvds(plvds_setting_info,
89  plvds_chip_info, common_init_data[i]);
90 
91  /* Input Data Mode Select */
92  if (plvds_setting_info->device_lcd_dualedge)
93  viafb_gpio_i2c_write_mask_lvds(plvds_setting_info,
94  plvds_chip_info, dual_channel_enable_data);
95  else
96  viafb_gpio_i2c_write_mask_lvds(plvds_setting_info,
97  plvds_chip_info, single_channel_enable_data);
98 
99  if (plvds_setting_info->LCDDithering)
100  viafb_gpio_i2c_write_mask_lvds(plvds_setting_info,
101  plvds_chip_info, dithering_enable_data);
102  else
103  viafb_gpio_i2c_write_mask_lvds(plvds_setting_info,
104  plvds_chip_info, dithering_disable_data);
105 }
106 
108  *plvds_setting_info,
109  struct lvds_chip_information *plvds_chip_info)
110 {
111  viafb_gpio_i2c_write_mask_lvds(plvds_setting_info, plvds_chip_info,
112  vdd_on_data);
113 }
114 
116  *plvds_setting_info,
117  struct lvds_chip_information *plvds_chip_info)
118 {
119  viafb_gpio_i2c_write_mask_lvds(plvds_setting_info, plvds_chip_info,
120  vdd_off_data);
121 }
122 
124 {
125  u8 Buffer[2];
126 
127  DEBUG_MSG(KERN_INFO "viafb_lvds_identify_vt1636.\n");
128 
129  /* Sense VT1636 LVDS Transmiter */
130  viaparinfo->chip_info->lvds_chip_info.lvds_chip_slave_addr =
132 
133  /* Check vendor ID first: */
134  if (viafb_i2c_readbyte(i2c_adapter, VT1636_LVDS_I2C_ADDR,
135  0x00, &Buffer[0]))
136  return false;
137  viafb_i2c_readbyte(i2c_adapter, VT1636_LVDS_I2C_ADDR, 0x01, &Buffer[1]);
138 
139  if (!((Buffer[0] == 0x06) && (Buffer[1] == 0x11)))
140  return false;
141 
142  /* Check Chip ID: */
143  viafb_i2c_readbyte(i2c_adapter, VT1636_LVDS_I2C_ADDR, 0x02, &Buffer[0]);
144  viafb_i2c_readbyte(i2c_adapter, VT1636_LVDS_I2C_ADDR, 0x03, &Buffer[1]);
145  if ((Buffer[0] == 0x45) && (Buffer[1] == 0x33)) {
146  viaparinfo->chip_info->lvds_chip_info.lvds_chip_name =
147  VT1636_LVDS;
148  return true;
149  }
150 
151  return false;
152 }
153 
154 static int get_clk_range_index(u32 Clk)
155 {
156  if (Clk < DPA_CLK_30M)
157  return DPA_CLK_RANGE_30M;
158  else if (Clk < DPA_CLK_50M)
159  return DPA_CLK_RANGE_30_50M;
160  else if (Clk < DPA_CLK_70M)
161  return DPA_CLK_RANGE_50_70M;
162  else if (Clk < DPA_CLK_100M)
163  return DPA_CLK_RANGE_70_100M;
164  else if (Clk < DPA_CLK_150M)
165  return DPA_CLK_RANGE_100_150M;
166  else
167  return DPA_CLK_RANGE_150M;
168 }
169 
170 static void set_dpa_vt1636(struct lvds_setting_information
171  *plvds_setting_info, struct lvds_chip_information *plvds_chip_info,
172  struct VT1636_DPA_SETTING *p_vt1636_dpa_setting)
173 {
174  struct IODATA io_data;
175 
176  io_data.Index = 0x09;
177  io_data.Mask = 0x1F;
178  io_data.Data = p_vt1636_dpa_setting->CLK_SEL_ST1;
179  viafb_gpio_i2c_write_mask_lvds(plvds_setting_info,
180  plvds_chip_info, io_data);
181 
182  io_data.Index = 0x08;
183  io_data.Mask = 0x0F;
184  io_data.Data = p_vt1636_dpa_setting->CLK_SEL_ST2;
185  viafb_gpio_i2c_write_mask_lvds(plvds_setting_info, plvds_chip_info,
186  io_data);
187 }
188 
190  struct lvds_setting_information *plvds_setting_info,
191  struct lvds_chip_information *plvds_chip_info)
192 {
193  struct VT1636_DPA_SETTING dpa = {0x00, 0x00}, dpa_16x12 = {0x0B, 0x03},
194  *pdpa;
195  int index;
196 
197  DEBUG_MSG(KERN_INFO "viafb_vt1636_patch_skew_on_vt3324.\n");
198 
199  /* Graphics DPA settings: */
200  index = get_clk_range_index(plvds_setting_info->vclk);
201  viafb_set_dpa_gfx(plvds_chip_info->output_interface,
203 
204  /* LVDS Transmitter DPA settings: */
205  if (plvds_setting_info->lcd_panel_hres == 1600 &&
206  plvds_setting_info->lcd_panel_vres == 1200)
207  pdpa = &dpa_16x12;
208  else
209  pdpa = &dpa;
210 
211  set_dpa_vt1636(plvds_setting_info, plvds_chip_info, pdpa);
212 }
213 
215  struct lvds_setting_information *plvds_setting_info,
216  struct lvds_chip_information *plvds_chip_info)
217 {
218  struct VT1636_DPA_SETTING dpa = {0x00, 0x00};
219  int index;
220 
221  DEBUG_MSG(KERN_INFO "viafb_vt1636_patch_skew_on_vt3327.\n");
222 
223  /* Graphics DPA settings: */
224  index = get_clk_range_index(plvds_setting_info->vclk);
225  viafb_set_dpa_gfx(plvds_chip_info->output_interface,
227 
228  /* LVDS Transmitter DPA settings: */
229  set_dpa_vt1636(plvds_setting_info, plvds_chip_info, &dpa);
230 }
231 
233  struct lvds_setting_information *plvds_setting_info,
234  struct lvds_chip_information *plvds_chip_info)
235 {
236  int index;
237 
238  DEBUG_MSG(KERN_INFO "viafb_vt1636_patch_skew_on_vt3364.\n");
239 
240  /* Graphics DPA settings: */
241  index = get_clk_range_index(plvds_setting_info->vclk);
242  viafb_set_dpa_gfx(plvds_chip_info->output_interface,
244 }