aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/via
diff options
context:
space:
mode:
authorJonathan Corbet <corbet@lwn.net>2009-12-01 22:29:39 -0500
committerJonathan Corbet <corbet@lwn.net>2010-05-07 19:15:47 -0400
commitf045f77bc0bf238a871b10bea9e425329a8e4abc (patch)
tree085c6651bc6f4d47f4b4659fa4ef4134fe40733f /drivers/video/via
parent4da62e6c6e056d709e5dc04ac7c5e81692cf924f (diff)
viafb: Move core stuff into via-core.c
The first step toward turning viafb into a multifunction driver. This patch creates a new via-core.c file which serves as the main PCI driver; everything else comes below that. Some work has been done to rationalize the i2c drivers in this new scheme. Cc: ScottFang@viatech.com.cn Cc: JosephChan@via.com.tw Cc: Harald Welte <laforge@gnumonks.org> Acked-by: Florian Tobias Schandinat <FlorianSchandinat@gmx.de> Signed-off-by: Jonathan Corbet <corbet@lwn.net>
Diffstat (limited to 'drivers/video/via')
-rw-r--r--drivers/video/via/Makefile2
-rw-r--r--drivers/video/via/dvi.c4
-rw-r--r--drivers/video/via/global.h1
-rw-r--r--drivers/video/via/lcd.c10
-rw-r--r--drivers/video/via/via-core.c116
-rw-r--r--drivers/video/via/via-core.h55
-rw-r--r--drivers/video/via/via_i2c.c74
-rw-r--r--drivers/video/via/via_i2c.h26
-rw-r--r--drivers/video/via/viafbdev.c69
-rw-r--r--drivers/video/via/viafbdev.h17
10 files changed, 242 insertions, 132 deletions
diff --git a/drivers/video/via/Makefile b/drivers/video/via/Makefile
index eeed238ad6a2..aec3f8b24a96 100644
--- a/drivers/video/via/Makefile
+++ b/drivers/video/via/Makefile
@@ -4,4 +4,4 @@
4 4
5obj-$(CONFIG_FB_VIA) += viafb.o 5obj-$(CONFIG_FB_VIA) += viafb.o
6 6
7viafb-y :=viafbdev.o hw.o via_i2c.o dvi.o lcd.o ioctl.o accel.o via_utility.o vt1636.o global.o tblDPASetting.o viamode.o tbl1636.o 7viafb-y :=viafbdev.o hw.o via_i2c.o dvi.o lcd.o ioctl.o accel.o via_utility.o vt1636.o global.o tblDPASetting.o viamode.o tbl1636.o via-core.o
diff --git a/drivers/video/via/dvi.c b/drivers/video/via/dvi.c
index be513701e4e6..e357c4d1cd0f 100644
--- a/drivers/video/via/dvi.c
+++ b/drivers/video/via/dvi.c
@@ -96,7 +96,7 @@ int viafb_tmds_trasmitter_identify(void)
96 viaparinfo->chip_info->tmds_chip_info.tmds_chip_name = VT1632_TMDS; 96 viaparinfo->chip_info->tmds_chip_info.tmds_chip_name = VT1632_TMDS;
97 viaparinfo->chip_info-> 97 viaparinfo->chip_info->
98 tmds_chip_info.tmds_chip_slave_addr = VT1632_TMDS_I2C_ADDR; 98 tmds_chip_info.tmds_chip_slave_addr = VT1632_TMDS_I2C_ADDR;
99 viaparinfo->chip_info->tmds_chip_info.i2c_port = VIA_I2C_ADAP_31; 99 viaparinfo->chip_info->tmds_chip_info.i2c_port = VIA_PORT_31;
100 if (check_tmds_chip(VT1632_DEVICE_ID_REG, VT1632_DEVICE_ID) != FAIL) { 100 if (check_tmds_chip(VT1632_DEVICE_ID_REG, VT1632_DEVICE_ID) != FAIL) {
101 /* 101 /*
102 * Currently only support 12bits,dual edge,add 24bits mode later 102 * Currently only support 12bits,dual edge,add 24bits mode later
@@ -110,7 +110,7 @@ int viafb_tmds_trasmitter_identify(void)
110 viaparinfo->chip_info->tmds_chip_info.i2c_port); 110 viaparinfo->chip_info->tmds_chip_info.i2c_port);
111 return OK; 111 return OK;
112 } else { 112 } else {
113 viaparinfo->chip_info->tmds_chip_info.i2c_port = VIA_I2C_ADAP_2C; 113 viaparinfo->chip_info->tmds_chip_info.i2c_port = VIA_PORT_2C;
114 if (check_tmds_chip(VT1632_DEVICE_ID_REG, VT1632_DEVICE_ID) 114 if (check_tmds_chip(VT1632_DEVICE_ID_REG, VT1632_DEVICE_ID)
115 != FAIL) { 115 != FAIL) {
116 tmds_register_write(0x08, 0x3b); 116 tmds_register_write(0x08, 0x3b);
diff --git a/drivers/video/via/global.h b/drivers/video/via/global.h
index 8d95d5fd1388..be48e73da045 100644
--- a/drivers/video/via/global.h
+++ b/drivers/video/via/global.h
@@ -35,6 +35,7 @@
35 35
36#include "debug.h" 36#include "debug.h"
37 37
38#include "via-core.h"
38#include "viafbdev.h" 39#include "viafbdev.h"
39#include "chip.h" 40#include "chip.h"
40#include "accel.h" 41#include "accel.h"
diff --git a/drivers/video/via/lcd.c b/drivers/video/via/lcd.c
index e19441d9e49f..8ef60c035fa2 100644
--- a/drivers/video/via/lcd.c
+++ b/drivers/video/via/lcd.c
@@ -172,14 +172,14 @@ static bool lvds_identify_integratedlvds(void)
172 172
173int viafb_lvds_trasmitter_identify(void) 173int viafb_lvds_trasmitter_identify(void)
174{ 174{
175 if (viafb_lvds_identify_vt1636(VIA_I2C_ADAP_31)) { 175 if (viafb_lvds_identify_vt1636(VIA_PORT_31)) {
176 viaparinfo->chip_info->lvds_chip_info.i2c_port = VIA_I2C_ADAP_31; 176 viaparinfo->chip_info->lvds_chip_info.i2c_port = VIA_PORT_31;
177 DEBUG_MSG(KERN_INFO 177 DEBUG_MSG(KERN_INFO
178 "Found VIA VT1636 LVDS on port i2c 0x31\n"); 178 "Found VIA VT1636 LVDS on port i2c 0x31\n");
179 } else { 179 } else {
180 if (viafb_lvds_identify_vt1636(VIA_I2C_ADAP_2C)) { 180 if (viafb_lvds_identify_vt1636(VIA_PORT_2C)) {
181 viaparinfo->chip_info->lvds_chip_info.i2c_port = 181 viaparinfo->chip_info->lvds_chip_info.i2c_port =
182 VIA_I2C_ADAP_2C; 182 VIA_PORT_2C;
183 DEBUG_MSG(KERN_INFO 183 DEBUG_MSG(KERN_INFO
184 "Found VIA VT1636 LVDS on port gpio 0x2c\n"); 184 "Found VIA VT1636 LVDS on port gpio 0x2c\n");
185 } 185 }
@@ -419,7 +419,7 @@ static int lvds_register_read(int index)
419{ 419{
420 u8 data; 420 u8 data;
421 421
422 viafb_i2c_readbyte(VIA_I2C_ADAP_2C, 422 viafb_i2c_readbyte(VIA_PORT_2C,
423 (u8) viaparinfo->chip_info->lvds_chip_info.lvds_chip_slave_addr, 423 (u8) viaparinfo->chip_info->lvds_chip_info.lvds_chip_slave_addr,
424 (u8) index, &data); 424 (u8) index, &data);
425 return data; 425 return data;
diff --git a/drivers/video/via/via-core.c b/drivers/video/via/via-core.c
new file mode 100644
index 000000000000..e7201470cf35
--- /dev/null
+++ b/drivers/video/via/via-core.c
@@ -0,0 +1,116 @@
1/*
2 * Copyright 1998-2009 VIA Technologies, Inc. All Rights Reserved.
3 * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
4 * Copyright 2009 Jonathan Corbet <corbet@lwn.net>
5 */
6
7/*
8 * Core code for the Via multifunction framebuffer device.
9 */
10#include <linux/module.h>
11#include <linux/platform_device.h>
12#include "global.h" /* Includes everything under the sun */
13
14/*
15 * The default port config.
16 */
17static struct via_port_cfg adap_configs[] = {
18 [VIA_PORT_26] = { VIA_PORT_I2C, VIA_MODE_OFF, VIASR, 0x26 },
19 [VIA_PORT_31] = { VIA_PORT_I2C, VIA_MODE_I2C, VIASR, 0x31 },
20 [VIA_PORT_25] = { VIA_PORT_GPIO, VIA_MODE_GPIO, VIASR, 0x25 },
21 [VIA_PORT_2C] = { VIA_PORT_GPIO, VIA_MODE_I2C, VIASR, 0x2c },
22 [VIA_PORT_3D] = { VIA_PORT_GPIO, VIA_MODE_GPIO, VIASR, 0x3d },
23 { 0, 0, 0, 0 }
24};
25
26
27static int __devinit via_pci_probe(struct pci_dev *pdev,
28 const struct pci_device_id *ent)
29{
30 int ret;
31
32 ret = pci_enable_device(pdev);
33 if (ret)
34 return ret;
35 /*
36 * Create the I2C busses. Bailing out on failure seems extreme,
37 * but that's what the code did before.
38 */
39 ret = viafb_create_i2c_busses(adap_configs);
40 if (ret)
41 goto out_disable;
42 /*
43 * Set up the framebuffer.
44 */
45 ret = via_fb_pci_probe(pdev, ent);
46 if (ret)
47 goto out_i2c;
48 return 0;
49
50out_i2c:
51 viafb_delete_i2c_busses();
52out_disable:
53 pci_disable_device(pdev);
54 return ret;
55}
56
57static void __devexit via_pci_remove(struct pci_dev *pdev)
58{
59 viafb_delete_i2c_busses();
60 via_fb_pci_remove(pdev);
61 pci_disable_device(pdev);
62}
63
64
65static struct pci_device_id via_pci_table[] __devinitdata = {
66 { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_CLE266_DID),
67 .driver_data = UNICHROME_CLE266 },
68 { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_PM800_DID),
69 .driver_data = UNICHROME_PM800 },
70 { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_K400_DID),
71 .driver_data = UNICHROME_K400 },
72 { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_K800_DID),
73 .driver_data = UNICHROME_K800 },
74 { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_P4M890_DID),
75 .driver_data = UNICHROME_CN700 },
76 { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_K8M890_DID),
77 .driver_data = UNICHROME_K8M890 },
78 { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_CX700_DID),
79 .driver_data = UNICHROME_CX700 },
80 { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_P4M900_DID),
81 .driver_data = UNICHROME_P4M900 },
82 { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_CN750_DID),
83 .driver_data = UNICHROME_CN750 },
84 { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_VX800_DID),
85 .driver_data = UNICHROME_VX800 },
86 { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_VX855_DID),
87 .driver_data = UNICHROME_VX855 },
88 { }
89};
90MODULE_DEVICE_TABLE(pci, via_pci_table);
91
92static struct pci_driver via_driver = {
93 .name = "viafb",
94 .id_table = via_pci_table,
95 .probe = via_pci_probe,
96 .remove = __devexit_p(via_pci_remove),
97};
98
99static int __init via_core_init(void)
100{
101 int ret;
102
103 ret = viafb_init();
104 if (ret)
105 return ret;
106 return pci_register_driver(&via_driver);
107}
108
109static void __exit via_core_exit(void)
110{
111 pci_unregister_driver(&via_driver);
112 viafb_exit();
113}
114
115module_init(via_core_init);
116module_exit(via_core_exit);
diff --git a/drivers/video/via/via-core.h b/drivers/video/via/via-core.h
new file mode 100644
index 000000000000..1c2fb06b77ae
--- /dev/null
+++ b/drivers/video/via/via-core.h
@@ -0,0 +1,55 @@
1/*
2 * Copyright 1998-2009 VIA Technologies, Inc. All Rights Reserved.
3 * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
4 * Copyright 2009 Jonathan Corbet <corbet@lwn.net>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public
8 * License as published by the Free Software Foundation;
9 * either version 2, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
13 * the implied warranty of MERCHANTABILITY or FITNESS FOR
14 * A PARTICULAR PURPOSE.See the GNU General Public License
15 * for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc.,
20 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 */
22
23#ifndef __VIA_CORE_H__
24#define __VIA_CORE_H__
25/*
26 * A description of each known serial I2C/GPIO port.
27 */
28enum via_port_type {
29 VIA_PORT_NONE = 0,
30 VIA_PORT_I2C,
31 VIA_PORT_GPIO,
32};
33
34enum via_port_mode {
35 VIA_MODE_OFF = 0,
36 VIA_MODE_I2C, /* Used as I2C port */
37 VIA_MODE_GPIO, /* Two GPIO ports */
38};
39
40enum viafb_i2c_adap {
41 VIA_PORT_26 = 0,
42 VIA_PORT_31,
43 VIA_PORT_25,
44 VIA_PORT_2C,
45 VIA_PORT_3D,
46};
47#define VIAFB_NUM_PORTS 5
48
49struct via_port_cfg {
50 enum via_port_type type;
51 enum via_port_mode mode;
52 u_int16_t io_port;
53 u_int8_t ioport_index;
54};
55#endif /* __VIA_CORE_H__ */
diff --git a/drivers/video/via/via_i2c.c b/drivers/video/via/via_i2c.c
index b5253e3099f8..478829281562 100644
--- a/drivers/video/via/via_i2c.c
+++ b/drivers/video/via/via_i2c.c
@@ -21,13 +21,18 @@
21 21
22#include "global.h" 22#include "global.h"
23 23
24/*
25 * There can only be one set of these, so there's no point in having
26 * them be dynamically allocated...
27 */
28#define VIAFB_NUM_I2C 5
29static struct via_i2c_stuff via_i2c_par[VIAFB_NUM_I2C];
30
24static void via_i2c_setscl(void *data, int state) 31static void via_i2c_setscl(void *data, int state)
25{ 32{
26 u8 val; 33 u8 val;
27 struct via_i2c_adap_cfg *adap_data = data; 34 struct via_port_cfg *adap_data = data;
28 35
29 DEBUG_MSG(KERN_DEBUG "reading index 0x%02x from IO 0x%x\n",
30 adap_data->ioport_index, adap_data->io_port);
31 val = viafb_read_reg(adap_data->io_port, 36 val = viafb_read_reg(adap_data->io_port,
32 adap_data->ioport_index) & 0xF0; 37 adap_data->ioport_index) & 0xF0;
33 if (state) 38 if (state)
@@ -35,10 +40,10 @@ static void via_i2c_setscl(void *data, int state)
35 else 40 else
36 val &= ~0x20; 41 val &= ~0x20;
37 switch (adap_data->type) { 42 switch (adap_data->type) {
38 case VIA_I2C_I2C: 43 case VIA_PORT_I2C:
39 val |= 0x01; 44 val |= 0x01;
40 break; 45 break;
41 case VIA_I2C_GPIO: 46 case VIA_PORT_GPIO:
42 val |= 0x80; 47 val |= 0x80;
43 break; 48 break;
44 default: 49 default:
@@ -50,7 +55,7 @@ static void via_i2c_setscl(void *data, int state)
50 55
51static int via_i2c_getscl(void *data) 56static int via_i2c_getscl(void *data)
52{ 57{
53 struct via_i2c_adap_cfg *adap_data = data; 58 struct via_port_cfg *adap_data = data;
54 59
55 if (viafb_read_reg(adap_data->io_port, adap_data->ioport_index) & 0x08) 60 if (viafb_read_reg(adap_data->io_port, adap_data->ioport_index) & 0x08)
56 return 1; 61 return 1;
@@ -59,7 +64,7 @@ static int via_i2c_getscl(void *data)
59 64
60static int via_i2c_getsda(void *data) 65static int via_i2c_getsda(void *data)
61{ 66{
62 struct via_i2c_adap_cfg *adap_data = data; 67 struct via_port_cfg *adap_data = data;
63 68
64 if (viafb_read_reg(adap_data->io_port, adap_data->ioport_index) & 0x04) 69 if (viafb_read_reg(adap_data->io_port, adap_data->ioport_index) & 0x04)
65 return 1; 70 return 1;
@@ -69,7 +74,7 @@ static int via_i2c_getsda(void *data)
69static void via_i2c_setsda(void *data, int state) 74static void via_i2c_setsda(void *data, int state)
70{ 75{
71 u8 val; 76 u8 val;
72 struct via_i2c_adap_cfg *adap_data = data; 77 struct via_port_cfg *adap_data = data;
73 78
74 val = viafb_read_reg(adap_data->io_port, 79 val = viafb_read_reg(adap_data->io_port,
75 adap_data->ioport_index) & 0xF0; 80 adap_data->ioport_index) & 0xF0;
@@ -78,10 +83,10 @@ static void via_i2c_setsda(void *data, int state)
78 else 83 else
79 val &= ~0x10; 84 val &= ~0x10;
80 switch (adap_data->type) { 85 switch (adap_data->type) {
81 case VIA_I2C_I2C: 86 case VIA_PORT_I2C:
82 val |= 0x01; 87 val |= 0x01;
83 break; 88 break;
84 case VIA_I2C_GPIO: 89 case VIA_PORT_GPIO:
85 val |= 0x40; 90 val |= 0x40;
86 break; 91 break;
87 default: 92 default:
@@ -103,8 +108,7 @@ int viafb_i2c_readbyte(u8 adap, u8 slave_addr, u8 index, u8 *pdata)
103 mm1[0] = index; 108 mm1[0] = index;
104 msgs[0].len = 1; msgs[1].len = 1; 109 msgs[0].len = 1; msgs[1].len = 1;
105 msgs[0].buf = mm1; msgs[1].buf = pdata; 110 msgs[0].buf = mm1; msgs[1].buf = pdata;
106 return i2c_transfer(&viaparinfo->shared->i2c_stuff[adap].adapter, 111 return i2c_transfer(&via_i2c_par[adap].adapter, msgs, 2);
107 msgs, 2);
108} 112}
109 113
110int viafb_i2c_writebyte(u8 adap, u8 slave_addr, u8 index, u8 data) 114int viafb_i2c_writebyte(u8 adap, u8 slave_addr, u8 index, u8 data)
@@ -116,8 +120,7 @@ int viafb_i2c_writebyte(u8 adap, u8 slave_addr, u8 index, u8 data)
116 msgs.addr = slave_addr / 2; 120 msgs.addr = slave_addr / 2;
117 msgs.len = 2; 121 msgs.len = 2;
118 msgs.buf = msg; 122 msgs.buf = msg;
119 return i2c_transfer(&viaparinfo->shared->i2c_stuff[adap].adapter, 123 return i2c_transfer(&via_i2c_par[adap].adapter, &msgs, 1);
120 &msgs, 1);
121} 124}
122 125
123int viafb_i2c_readbytes(u8 adap, u8 slave_addr, u8 index, u8 *buff, int buff_len) 126int viafb_i2c_readbytes(u8 adap, u8 slave_addr, u8 index, u8 *buff, int buff_len)
@@ -131,13 +134,12 @@ int viafb_i2c_readbytes(u8 adap, u8 slave_addr, u8 index, u8 *buff, int buff_len
131 mm1[0] = index; 134 mm1[0] = index;
132 msgs[0].len = 1; msgs[1].len = buff_len; 135 msgs[0].len = 1; msgs[1].len = buff_len;
133 msgs[0].buf = mm1; msgs[1].buf = buff; 136 msgs[0].buf = mm1; msgs[1].buf = buff;
134 return i2c_transfer(&viaparinfo->shared->i2c_stuff[adap].adapter, 137 return i2c_transfer(&via_i2c_par[adap].adapter, msgs, 2);
135 msgs, 2);
136} 138}
137 139
138static int create_i2c_bus(struct i2c_adapter *adapter, 140static int create_i2c_bus(struct i2c_adapter *adapter,
139 struct i2c_algo_bit_data *algo, 141 struct i2c_algo_bit_data *algo,
140 struct via_i2c_adap_cfg *adap_cfg, 142 struct via_port_cfg *adap_cfg,
141 struct pci_dev *pdev) 143 struct pci_dev *pdev)
142{ 144{
143 DEBUG_MSG(KERN_DEBUG "viafb: creating bus adap=0x%p, algo_bit_data=0x%p, adap_cfg=0x%p\n", adapter, algo, adap_cfg); 145 DEBUG_MSG(KERN_DEBUG "viafb: creating bus adap=0x%p, algo_bit_data=0x%p, adap_cfg=0x%p\n", adapter, algo, adap_cfg);
@@ -170,31 +172,15 @@ static int create_i2c_bus(struct i2c_adapter *adapter,
170 return i2c_bit_add_bus(adapter); 172 return i2c_bit_add_bus(adapter);
171} 173}
172 174
173/* 175int viafb_create_i2c_busses(struct via_port_cfg *configs)
174 * By default, we only activate busses on ports 2c and 31 to avoid
175 * conflicts with other possible users; that default can be changed
176 * below.
177 */
178static struct via_i2c_adap_cfg adap_configs[] = {
179 [VIA_I2C_ADAP_26] = { VIA_I2C_I2C, VIASR, 0x26, 0 },
180 [VIA_I2C_ADAP_31] = { VIA_I2C_I2C, VIASR, 0x31, 1 },
181 [VIA_I2C_ADAP_25] = { VIA_I2C_GPIO, VIASR, 0x25, 0 },
182 [VIA_I2C_ADAP_2C] = { VIA_I2C_GPIO, VIASR, 0x2c, 1 },
183 [VIA_I2C_ADAP_3D] = { VIA_I2C_GPIO, VIASR, 0x3d, 0 },
184 { 0, 0, 0, 0 }
185};
186
187int viafb_create_i2c_busses(struct viafb_par *viapar)
188{ 176{
189 int i, ret; 177 int i, ret;
190 178
191 for (i = 0; i < VIAFB_NUM_I2C; i++) { 179 for (i = 0; i < VIAFB_NUM_PORTS; i++) {
192 struct via_i2c_adap_cfg *adap_cfg = &adap_configs[i]; 180 struct via_port_cfg *adap_cfg = configs++;
193 struct via_i2c_stuff *i2c_stuff = &viapar->shared->i2c_stuff[i]; 181 struct via_i2c_stuff *i2c_stuff = &via_i2c_par[i];
194 182
195 if (adap_cfg->type == 0) 183 if (adap_cfg->type == 0 || adap_cfg->mode != VIA_MODE_I2C)
196 break;
197 if (!adap_cfg->is_active)
198 continue; 184 continue;
199 185
200 ret = create_i2c_bus(&i2c_stuff->adapter, 186 ret = create_i2c_bus(&i2c_stuff->adapter,
@@ -211,14 +197,16 @@ int viafb_create_i2c_busses(struct viafb_par *viapar)
211 return 0; 197 return 0;
212} 198}
213 199
214void viafb_delete_i2c_busses(struct viafb_par *par) 200void viafb_delete_i2c_busses(void)
215{ 201{
216 int i; 202 int i;
217 203
218 for (i = 0; i < ARRAY_SIZE(par->shared->i2c_stuff); i++) { 204 for (i = 0; i < VIAFB_NUM_PORTS; i++) {
219 struct via_i2c_stuff *i2c_stuff = &par->shared->i2c_stuff[i]; 205 struct via_i2c_stuff *i2c_stuff = &via_i2c_par[i];
220 /* only remove those entries in the array that we've 206 /*
221 * actually used (and thus initialized algo_data) */ 207 * Only remove those entries in the array that we've
208 * actually used (and thus initialized algo_data)
209 */
222 if (i2c_stuff->adapter.algo_data == &i2c_stuff->algo) 210 if (i2c_stuff->adapter.algo_data == &i2c_stuff->algo)
223 i2c_del_adapter(&i2c_stuff->adapter); 211 i2c_del_adapter(&i2c_stuff->adapter);
224 } 212 }
diff --git a/drivers/video/via/via_i2c.h b/drivers/video/via/via_i2c.h
index 73d682fcf269..00932914b4ed 100644
--- a/drivers/video/via/via_i2c.h
+++ b/drivers/video/via/via_i2c.h
@@ -24,39 +24,19 @@
24#include <linux/i2c.h> 24#include <linux/i2c.h>
25#include <linux/i2c-algo-bit.h> 25#include <linux/i2c-algo-bit.h>
26 26
27enum via_i2c_type {
28 VIA_I2C_NONE,
29 VIA_I2C_I2C,
30 VIA_I2C_GPIO,
31};
32
33/* private data for each adapter */
34struct via_i2c_adap_cfg {
35 enum via_i2c_type type;
36 u_int16_t io_port;
37 u_int8_t ioport_index;
38 u8 is_active;
39};
40
41struct via_i2c_stuff { 27struct via_i2c_stuff {
42 u16 i2c_port; /* GPIO or I2C port */ 28 u16 i2c_port; /* GPIO or I2C port */
43 struct i2c_adapter adapter; 29 struct i2c_adapter adapter;
44 struct i2c_algo_bit_data algo; 30 struct i2c_algo_bit_data algo;
45}; 31};
46 32
47enum viafb_i2c_adap {
48 VIA_I2C_ADAP_26,
49 VIA_I2C_ADAP_31,
50 VIA_I2C_ADAP_25,
51 VIA_I2C_ADAP_2C,
52 VIA_I2C_ADAP_3D,
53};
54 33
55int viafb_i2c_readbyte(u8 adap, u8 slave_addr, u8 index, u8 *pdata); 34int viafb_i2c_readbyte(u8 adap, u8 slave_addr, u8 index, u8 *pdata);
56int viafb_i2c_writebyte(u8 adap, u8 slave_addr, u8 index, u8 data); 35int viafb_i2c_writebyte(u8 adap, u8 slave_addr, u8 index, u8 data);
57int viafb_i2c_readbytes(u8 adap, u8 slave_addr, u8 index, u8 *buff, int buff_len); 36int viafb_i2c_readbytes(u8 adap, u8 slave_addr, u8 index, u8 *buff, int buff_len);
58 37
59struct viafb_par; 38struct viafb_par;
60int viafb_create_i2c_busses(struct viafb_par *par); 39int viafb_create_i2c_busses(struct via_port_cfg *cfg);
61void viafb_delete_i2c_busses(struct viafb_par *par); 40void viafb_delete_i2c_busses(void);
41struct i2c_adapter *viafb_find_adapter(enum viafb_i2c_adap which);
62#endif /* __VIA_I2C_H__ */ 42#endif /* __VIA_I2C_H__ */
diff --git a/drivers/video/via/viafbdev.c b/drivers/video/via/viafbdev.c
index fa1004997c63..17a874f6ea1c 100644
--- a/drivers/video/via/viafbdev.c
+++ b/drivers/video/via/viafbdev.c
@@ -1731,8 +1731,9 @@ static int parse_mode(const char *str, u32 *xres, u32 *yres)
1731 return 0; 1731 return 0;
1732} 1732}
1733 1733
1734static int __devinit via_pci_probe(struct pci_dev *pdev, 1734
1735 const struct pci_device_id *ent) 1735int __devinit via_fb_pci_probe(struct pci_dev *pdev,
1736 const struct pci_device_id *ent)
1736{ 1737{
1737 u32 default_xres, default_yres; 1738 u32 default_xres, default_yres;
1738 struct VideoModeTable *vmode_entry; 1739 struct VideoModeTable *vmode_entry;
@@ -1764,6 +1765,7 @@ static int __devinit via_pci_probe(struct pci_dev *pdev,
1764 &viaparinfo->shared->lvds_setting_info2; 1765 &viaparinfo->shared->lvds_setting_info2;
1765 viaparinfo->crt_setting_info = &viaparinfo->shared->crt_setting_info; 1766 viaparinfo->crt_setting_info = &viaparinfo->shared->crt_setting_info;
1766 viaparinfo->chip_info = &viaparinfo->shared->chip_info; 1767 viaparinfo->chip_info = &viaparinfo->shared->chip_info;
1768 spin_lock_init(&viaparinfo->reg_lock);
1767 1769
1768 if (viafb_dual_fb) 1770 if (viafb_dual_fb)
1769 viafb_SAMM_ON = 1; 1771 viafb_SAMM_ON = 1;
@@ -1774,26 +1776,21 @@ static int __devinit via_pci_probe(struct pci_dev *pdev,
1774 if (!viafb_SAMM_ON) 1776 if (!viafb_SAMM_ON)
1775 viafb_dual_fb = 0; 1777 viafb_dual_fb = 0;
1776 1778
1777 /* Set up I2C bus stuff */
1778 rc = viafb_create_i2c_busses(viaparinfo);
1779 if (rc)
1780 goto out_fb_release;
1781
1782 viafb_init_chip_info(pdev, ent); 1779 viafb_init_chip_info(pdev, ent);
1783 viaparinfo->fbmem = pci_resource_start(pdev, 0); 1780 viaparinfo->fbmem = pci_resource_start(pdev, 0);
1784 viaparinfo->memsize = viafb_get_fb_size_from_pci(); 1781 viaparinfo->memsize = viafb_get_fb_size_from_pci();
1785 if (viaparinfo->memsize < 0) { 1782 if (viaparinfo->memsize < 0) {
1786 rc = viaparinfo->memsize; 1783 rc = viaparinfo->memsize;
1787 goto out_delete_i2c; 1784 goto out_fb_release;
1788 } 1785 }
1789 viaparinfo->fbmem_free = viaparinfo->memsize; 1786 viaparinfo->fbmem_free = viaparinfo->memsize;
1790 viaparinfo->fbmem_used = 0; 1787 viaparinfo->fbmem_used = 0;
1791 viafbinfo->screen_base = ioremap_nocache(viaparinfo->fbmem, 1788 viafbinfo->screen_base = ioremap_nocache(viaparinfo->fbmem,
1792 viaparinfo->memsize); 1789 viaparinfo->memsize);
1793 if (!viafbinfo->screen_base) { 1790 if (!viafbinfo->screen_base) {
1794 printk(KERN_INFO "ioremap failed\n"); 1791 printk(KERN_ERR "ioremap of fbmem failed\n");
1795 rc = -ENOMEM; 1792 rc = -ENOMEM;
1796 goto out_delete_i2c; 1793 goto out_fb_release;
1797 } 1794 }
1798 1795
1799 viafbinfo->fix.mmio_start = pci_resource_start(pdev, 1); 1796 viafbinfo->fix.mmio_start = pci_resource_start(pdev, 1);
@@ -1963,14 +1960,12 @@ out_fb1_release:
1963 framebuffer_release(viafbinfo1); 1960 framebuffer_release(viafbinfo1);
1964out_unmap_screen: 1961out_unmap_screen:
1965 iounmap(viafbinfo->screen_base); 1962 iounmap(viafbinfo->screen_base);
1966out_delete_i2c:
1967 viafb_delete_i2c_busses(viaparinfo);
1968out_fb_release: 1963out_fb_release:
1969 framebuffer_release(viafbinfo); 1964 framebuffer_release(viafbinfo);
1970 return rc; 1965 return rc;
1971} 1966}
1972 1967
1973static void __devexit via_pci_remove(struct pci_dev *pdev) 1968void __devexit via_fb_pci_remove(struct pci_dev *pdev)
1974{ 1969{
1975 DEBUG_MSG(KERN_INFO "via_pci_remove!\n"); 1970 DEBUG_MSG(KERN_INFO "via_pci_remove!\n");
1976 fb_dealloc_cmap(&viafbinfo->cmap); 1971 fb_dealloc_cmap(&viafbinfo->cmap);
@@ -1980,8 +1975,6 @@ static void __devexit via_pci_remove(struct pci_dev *pdev)
1980 iounmap((void *)viafbinfo->screen_base); 1975 iounmap((void *)viafbinfo->screen_base);
1981 iounmap(viaparinfo->shared->engine_mmio); 1976 iounmap(viaparinfo->shared->engine_mmio);
1982 1977
1983 viafb_delete_i2c_busses(viaparinfo);
1984
1985 framebuffer_release(viafbinfo); 1978 framebuffer_release(viafbinfo);
1986 if (viafb_dual_fb) 1979 if (viafb_dual_fb)
1987 framebuffer_release(viafbinfo1); 1980 framebuffer_release(viafbinfo1);
@@ -2062,41 +2055,10 @@ static int __init viafb_setup(char *options)
2062} 2055}
2063#endif 2056#endif
2064 2057
2065static struct pci_device_id viafb_pci_table[] __devinitdata = { 2058/*
2066 { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_CLE266_DID), 2059 * These are called out of via-core for now.
2067 .driver_data = UNICHROME_CLE266 }, 2060 */
2068 { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_PM800_DID), 2061int __init viafb_init(void)
2069 .driver_data = UNICHROME_PM800 },
2070 { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_K400_DID),
2071 .driver_data = UNICHROME_K400 },
2072 { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_K800_DID),
2073 .driver_data = UNICHROME_K800 },
2074 { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_P4M890_DID),
2075 .driver_data = UNICHROME_CN700 },
2076 { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_K8M890_DID),
2077 .driver_data = UNICHROME_K8M890 },
2078 { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_CX700_DID),
2079 .driver_data = UNICHROME_CX700 },
2080 { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_P4M900_DID),
2081 .driver_data = UNICHROME_P4M900 },
2082 { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_CN750_DID),
2083 .driver_data = UNICHROME_CN750 },
2084 { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_VX800_DID),
2085 .driver_data = UNICHROME_VX800 },
2086 { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_VX855_DID),
2087 .driver_data = UNICHROME_VX855 },
2088 { }
2089};
2090MODULE_DEVICE_TABLE(pci, viafb_pci_table);
2091
2092static struct pci_driver viafb_driver = {
2093 .name = "viafb",
2094 .id_table = viafb_pci_table,
2095 .probe = via_pci_probe,
2096 .remove = __devexit_p(via_pci_remove),
2097};
2098
2099static int __init viafb_init(void)
2100{ 2062{
2101 u32 dummy; 2063 u32 dummy;
2102#ifndef MODULE 2064#ifndef MODULE
@@ -2115,13 +2077,12 @@ static int __init viafb_init(void)
2115 printk(KERN_INFO 2077 printk(KERN_INFO
2116 "VIA Graphics Intergration Chipset framebuffer %d.%d initializing\n", 2078 "VIA Graphics Intergration Chipset framebuffer %d.%d initializing\n",
2117 VERSION_MAJOR, VERSION_MINOR); 2079 VERSION_MAJOR, VERSION_MINOR);
2118 return pci_register_driver(&viafb_driver); 2080 return 0;
2119} 2081}
2120 2082
2121static void __exit viafb_exit(void) 2083void __exit viafb_exit(void)
2122{ 2084{
2123 DEBUG_MSG(KERN_INFO "viafb_exit!\n"); 2085 DEBUG_MSG(KERN_INFO "viafb_exit!\n");
2124 pci_unregister_driver(&viafb_driver);
2125} 2086}
2126 2087
2127static struct fb_ops viafb_ops = { 2088static struct fb_ops viafb_ops = {
@@ -2141,8 +2102,6 @@ static struct fb_ops viafb_ops = {
2141 .fb_sync = viafb_sync, 2102 .fb_sync = viafb_sync,
2142}; 2103};
2143 2104
2144module_init(viafb_init);
2145module_exit(viafb_exit);
2146 2105
2147#ifdef MODULE 2106#ifdef MODULE
2148module_param(viafb_mode, charp, S_IRUSR); 2107module_param(viafb_mode, charp, S_IRUSR);
diff --git a/drivers/video/via/viafbdev.h b/drivers/video/via/viafbdev.h
index 4bc00ec8fb1c..5604f27eb74e 100644
--- a/drivers/video/via/viafbdev.h
+++ b/drivers/video/via/viafbdev.h
@@ -24,6 +24,7 @@
24 24
25#include <linux/proc_fs.h> 25#include <linux/proc_fs.h>
26#include <linux/fb.h> 26#include <linux/fb.h>
27#include <linux/spinlock.h>
27 28
28#include "ioctl.h" 29#include "ioctl.h"
29#include "share.h" 30#include "share.h"
@@ -42,9 +43,6 @@
42struct viafb_shared { 43struct viafb_shared {
43 struct proc_dir_entry *proc_entry; /*viafb proc entry */ 44 struct proc_dir_entry *proc_entry; /*viafb proc entry */
44 45
45 /* I2C stuff */
46 struct via_i2c_stuff i2c_stuff[VIAFB_NUM_I2C];
47
48 /* All the information will be needed to set engine */ 46 /* All the information will be needed to set engine */
49 struct tmds_setting_information tmds_setting_info; 47 struct tmds_setting_information tmds_setting_info;
50 struct crt_setting_information crt_setting_info; 48 struct crt_setting_information crt_setting_info;
@@ -74,6 +72,14 @@ struct viafb_par {
74 72
75 struct viafb_shared *shared; 73 struct viafb_shared *shared;
76 74
75 /*
76 * (jc) I believe one should use locking to protect against
77 * concurrent access to the device ports and registers. Thus,
78 * this lock. Use of it is *far* from universal, though...
79 * someday...
80 */
81 spinlock_t reg_lock;
82
77 /* All the information will be needed to set engine */ 83 /* All the information will be needed to set engine */
78 /* depreciated, use the ones in shared directly */ 84 /* depreciated, use the ones in shared directly */
79 struct tmds_setting_information *tmds_setting_info; 85 struct tmds_setting_information *tmds_setting_info;
@@ -101,4 +107,9 @@ u8 viafb_gpio_i2c_read_lvds(struct lvds_setting_information
101void viafb_gpio_i2c_write_mask_lvds(struct lvds_setting_information 107void viafb_gpio_i2c_write_mask_lvds(struct lvds_setting_information
102 *plvds_setting_info, struct lvds_chip_information 108 *plvds_setting_info, struct lvds_chip_information
103 *plvds_chip_info, struct IODATA io_data); 109 *plvds_chip_info, struct IODATA io_data);
110int via_fb_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent);
111void via_fb_pci_remove(struct pci_dev *pdev);
112/* Temporary */
113int viafb_init(void);
114void viafb_exit(void);
104#endif /* __VIAFBDEV_H__ */ 115#endif /* __VIAFBDEV_H__ */