Merge branch 'for-2.6.31' of git://git.kernel.org/pub/scm/linux/kernel/git/bart/ide-2.6
[linux-2.6] / drivers / video / via / via_utility.c
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 "global.h"
23
24 void viafb_get_device_support_state(u32 *support_state)
25 {
26         *support_state = CRT_Device;
27
28         if (viaparinfo->chip_info->tmds_chip_info.tmds_chip_name == VT1632_TMDS)
29                 *support_state |= DVI_Device;
30
31         if (viaparinfo->chip_info->lvds_chip_info.lvds_chip_name == VT1631_LVDS)
32                 *support_state |= LCD_Device;
33 }
34
35 void viafb_get_device_connect_state(u32 *connect_state)
36 {
37         bool mobile = false;
38
39         *connect_state = CRT_Device;
40
41         if (viafb_dvi_sense())
42                 *connect_state |= DVI_Device;
43
44         viafb_lcd_get_mobile_state(&mobile);
45         if (mobile)
46                 *connect_state |= LCD_Device;
47 }
48
49 bool viafb_lcd_get_support_expand_state(u32 xres, u32 yres)
50 {
51         unsigned int support_state = 0;
52
53         switch (viafb_lcd_panel_id) {
54         case LCD_PANEL_ID0_640X480:
55                 if ((xres < 640) && (yres < 480))
56                         support_state = true;
57                 break;
58
59         case LCD_PANEL_ID1_800X600:
60                 if ((xres < 800) && (yres < 600))
61                         support_state = true;
62                 break;
63
64         case LCD_PANEL_ID2_1024X768:
65                 if ((xres < 1024) && (yres < 768))
66                         support_state = true;
67                 break;
68
69         case LCD_PANEL_ID3_1280X768:
70                 if ((xres < 1280) && (yres < 768))
71                         support_state = true;
72                 break;
73
74         case LCD_PANEL_ID4_1280X1024:
75                 if ((xres < 1280) && (yres < 1024))
76                         support_state = true;
77                 break;
78
79         case LCD_PANEL_ID5_1400X1050:
80                 if ((xres < 1400) && (yres < 1050))
81                         support_state = true;
82                 break;
83
84         case LCD_PANEL_ID6_1600X1200:
85                 if ((xres < 1600) && (yres < 1200))
86                         support_state = true;
87                 break;
88
89         case LCD_PANEL_ID7_1366X768:
90                 if ((xres < 1366) && (yres < 768))
91                         support_state = true;
92                 break;
93
94         case LCD_PANEL_ID8_1024X600:
95                 if ((xres < 1024) && (yres < 600))
96                         support_state = true;
97                 break;
98
99         case LCD_PANEL_ID9_1280X800:
100                 if ((xres < 1280) && (yres < 800))
101                         support_state = true;
102                 break;
103
104         case LCD_PANEL_IDA_800X480:
105                 if ((xres < 800) && (yres < 480))
106                         support_state = true;
107                 break;
108
109         case LCD_PANEL_IDB_1360X768:
110                 if ((xres < 1360) && (yres < 768))
111                         support_state = true;
112                 break;
113
114         case LCD_PANEL_IDC_480X640:
115                 if ((xres < 480) && (yres < 640))
116                         support_state = true;
117                 break;
118
119         default:
120                 support_state = false;
121                 break;
122         }
123
124         return support_state;
125 }
126
127 /*====================================================================*/
128 /*                      Gamma Function Implementation*/
129 /*====================================================================*/
130
131 void viafb_set_gamma_table(int bpp, unsigned int *gamma_table)
132 {
133         int i, sr1a;
134         int active_device_amount = 0;
135         int device_status = viafb_DeviceStatus;
136
137         for (i = 0; i < sizeof(viafb_DeviceStatus) * 8; i++) {
138                 if (device_status & 1)
139                         active_device_amount++;
140                 device_status >>= 1;
141         }
142
143         /* 8 bpp mode can't adjust gamma */
144         if (bpp == 8)
145                 return ;
146
147         /* Enable Gamma */
148         switch (viaparinfo->chip_info->gfx_chip_name) {
149         case UNICHROME_CLE266:
150         case UNICHROME_K400:
151                 viafb_write_reg_mask(SR16, VIASR, 0x80, BIT7);
152                 break;
153
154         case UNICHROME_K800:
155         case UNICHROME_PM800:
156         case UNICHROME_CN700:
157         case UNICHROME_CX700:
158         case UNICHROME_K8M890:
159         case UNICHROME_P4M890:
160         case UNICHROME_P4M900:
161                 viafb_write_reg_mask(CR33, VIACR, 0x80, BIT7);
162                 break;
163         }
164         sr1a = (unsigned int)viafb_read_reg(VIASR, SR1A);
165         viafb_write_reg_mask(SR1A, VIASR, 0x0, BIT0);
166
167         /* Fill IGA1 Gamma Table */
168         outb(0, LUT_INDEX_WRITE);
169         for (i = 0; i < 256; i++) {
170                 outb(gamma_table[i] >> 16, LUT_DATA);
171                 outb(gamma_table[i] >> 8 & 0xFF, LUT_DATA);
172                 outb(gamma_table[i] & 0xFF, LUT_DATA);
173         }
174
175         /* If adjust Gamma value in SAMM, fill IGA1,
176            IGA2 Gamma table simultanous. */
177         /* Switch to IGA2 Gamma Table */
178         if ((active_device_amount > 1) &&
179                 !((viaparinfo->chip_info->gfx_chip_name ==
180                 UNICHROME_CLE266) &&
181                 (viaparinfo->chip_info->gfx_chip_revision < 15))) {
182                 viafb_write_reg_mask(SR1A, VIASR, 0x01, BIT0);
183                 viafb_write_reg_mask(CR6A, VIACR, 0x02, BIT1);
184
185                 /* Fill IGA2 Gamma Table */
186                 outb(0, LUT_INDEX_WRITE);
187                 for (i = 0; i < 256; i++) {
188                         outb(gamma_table[i] >> 16, LUT_DATA);
189                         outb(gamma_table[i] >> 8 & 0xFF, LUT_DATA);
190                         outb(gamma_table[i] & 0xFF, LUT_DATA);
191                 }
192         }
193         viafb_write_reg(SR1A, VIASR, sr1a);
194 }
195
196 void viafb_get_gamma_table(unsigned int *gamma_table)
197 {
198         unsigned char color_r, color_g, color_b;
199         unsigned char sr1a = 0;
200         int i;
201
202         /* Enable Gamma */
203         switch (viaparinfo->chip_info->gfx_chip_name) {
204         case UNICHROME_CLE266:
205         case UNICHROME_K400:
206                 viafb_write_reg_mask(SR16, VIASR, 0x80, BIT7);
207                 break;
208
209         case UNICHROME_K800:
210         case UNICHROME_PM800:
211         case UNICHROME_CN700:
212         case UNICHROME_CX700:
213         case UNICHROME_K8M890:
214         case UNICHROME_P4M890:
215         case UNICHROME_P4M900:
216                 viafb_write_reg_mask(CR33, VIACR, 0x80, BIT7);
217                 break;
218         }
219         sr1a = viafb_read_reg(VIASR, SR1A);
220         viafb_write_reg_mask(SR1A, VIASR, 0x0, BIT0);
221
222         /* Reading gamma table to get color value */
223         outb(0, LUT_INDEX_READ);
224         for (i = 0; i < 256; i++) {
225                 color_r = inb(LUT_DATA);
226                 color_g = inb(LUT_DATA);
227                 color_b = inb(LUT_DATA);
228                 gamma_table[i] =
229                     ((((u32) color_r) << 16) |
230                      (((u16) color_g) << 8)) | color_b;
231         }
232         viafb_write_reg(SR1A, VIASR, sr1a);
233 }
234
235 void viafb_get_gamma_support_state(int bpp, unsigned int *support_state)
236 {
237         if (bpp == 8)
238                 *support_state = None_Device;
239         else
240                 *support_state = CRT_Device | DVI_Device | LCD_Device;
241 }
242
243 int viafb_input_parameter_converter(int parameter_value)
244 {
245         int result;
246
247         if (parameter_value >= 1 && parameter_value <= 9)
248                 result = 1 << (parameter_value - 1);
249         else
250                 result = 1;
251
252         return result;
253 }