aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video
diff options
context:
space:
mode:
authorHarald Welte <laforge@gnumonks.org>2009-05-22 12:35:39 -0400
committerJonathan Corbet <corbet@lwn.net>2010-04-27 15:01:45 -0400
commit277d32a36cba0b42c9c6836ff07f9b978566e95c (patch)
tree7161c2ddeb6064a42ba4babe3678a0493ecf6365 /drivers/video
parentc205d932530719d2a6ddb9152650e5bbe80c9400 (diff)
viafb: rework the I2C support in the VIA framebuffer driver
This patch changes the way how the various I2C busses are used internally inside the viafb driver: Previosuly, only a single i2c_adapter was created, even though two different hardware I2C busses are accessed: A structure member in a global variable was modified to indicate the bus to be used. Now, all existing hardware busses are registered with the i2c core, and the viafb_i2c_{read,write}byte[s]() function take the adapter number as function call parameter, rather than referring to the global structure member. [jc: even more painful merge with mainline changes ->2.6.34] [jc: painful merge with OLPC changes] Cc: Florian Tobias Schandinat <FlorianSchandinat@gmx.de> Cc: ScottFang@viatech.com.cn Cc: JosephChan@via.com.tw Signed-off-by: Harald Welte <HaraldWelte@viatech.com> Signed-off-by: Jonathan Corbet <corbet@lwn.net>
Diffstat (limited to 'drivers/video')
-rw-r--r--drivers/video/via/dvi.c35
-rw-r--r--drivers/video/via/lcd.c19
-rw-r--r--drivers/video/via/via_i2c.c171
-rw-r--r--drivers/video/via/via_i2c.h43
-rw-r--r--drivers/video/via/viafbdev.c6
-rw-r--r--drivers/video/via/viafbdev.h4
-rw-r--r--drivers/video/via/vt1636.c36
-rw-r--r--drivers/video/via/vt1636.h2
8 files changed, 182 insertions, 134 deletions
diff --git a/drivers/video/via/dvi.c b/drivers/video/via/dvi.c
index abe59b8c7a05..be513701e4e6 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 = I2CPORTINDEX; 99 viaparinfo->chip_info->tmds_chip_info.i2c_port = VIA_I2C_ADAP_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 = GPIOPORTINDEX; 113 viaparinfo->chip_info->tmds_chip_info.i2c_port = VIA_I2C_ADAP_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);
@@ -160,32 +160,26 @@ int viafb_tmds_trasmitter_identify(void)
160 160
161static void tmds_register_write(int index, u8 data) 161static void tmds_register_write(int index, u8 data)
162{ 162{
163 viaparinfo->shared->i2c_stuff.i2c_port = 163 viafb_i2c_writebyte(viaparinfo->chip_info->tmds_chip_info.i2c_port,
164 viaparinfo->chip_info->tmds_chip_info.i2c_port; 164 viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr,
165 165 index, data);
166 viafb_i2c_writebyte(viaparinfo->chip_info->tmds_chip_info.
167 tmds_chip_slave_addr, index,
168 data);
169} 166}
170 167
171static int tmds_register_read(int index) 168static int tmds_register_read(int index)
172{ 169{
173 u8 data; 170 u8 data;
174 171
175 viaparinfo->shared->i2c_stuff.i2c_port = 172 viafb_i2c_readbyte(viaparinfo->chip_info->tmds_chip_info.i2c_port,
176 viaparinfo->chip_info->tmds_chip_info.i2c_port; 173 (u8) viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr,
177 viafb_i2c_readbyte((u8) viaparinfo->chip_info-> 174 (u8) index, &data);
178 tmds_chip_info.tmds_chip_slave_addr,
179 (u8) index, &data);
180 return data; 175 return data;
181} 176}
182 177
183static int tmds_register_read_bytes(int index, u8 *buff, int buff_len) 178static int tmds_register_read_bytes(int index, u8 *buff, int buff_len)
184{ 179{
185 viaparinfo->shared->i2c_stuff.i2c_port = 180 viafb_i2c_readbytes(viaparinfo->chip_info->tmds_chip_info.i2c_port,
186 viaparinfo->chip_info->tmds_chip_info.i2c_port; 181 (u8) viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr,
187 viafb_i2c_readbytes((u8) viaparinfo->chip_info->tmds_chip_info. 182 (u8) index, buff, buff_len);
188 tmds_chip_slave_addr, (u8) index, buff, buff_len);
189 return 0; 183 return 0;
190} 184}
191 185
@@ -541,9 +535,10 @@ void viafb_dvi_enable(void)
541 else 535 else
542 data = 0x37; 536 data = 0x37;
543 viafb_i2c_writebyte(viaparinfo->chip_info-> 537 viafb_i2c_writebyte(viaparinfo->chip_info->
544 tmds_chip_info. 538 tmds_chip_info.i2c_port,
545 tmds_chip_slave_addr, 539 viaparinfo->chip_info->
546 0x08, data); 540 tmds_chip_info.tmds_chip_slave_addr,
541 0x08, data);
547 } 542 }
548 } 543 }
549 } 544 }
diff --git a/drivers/video/via/lcd.c b/drivers/video/via/lcd.c
index 09020f0b2d2a..e19441d9e49f 100644
--- a/drivers/video/via/lcd.c
+++ b/drivers/video/via/lcd.c
@@ -172,18 +172,16 @@ static bool lvds_identify_integratedlvds(void)
172 172
173int viafb_lvds_trasmitter_identify(void) 173int viafb_lvds_trasmitter_identify(void)
174{ 174{
175 viaparinfo->shared->i2c_stuff.i2c_port = I2CPORTINDEX; 175 if (viafb_lvds_identify_vt1636(VIA_I2C_ADAP_31)) {
176 if (viafb_lvds_identify_vt1636()) { 176 viaparinfo->chip_info->lvds_chip_info.i2c_port = VIA_I2C_ADAP_31;
177 viaparinfo->chip_info->lvds_chip_info.i2c_port = I2CPORTINDEX;
178 DEBUG_MSG(KERN_INFO 177 DEBUG_MSG(KERN_INFO
179 "Found VIA VT1636 LVDS on port i2c 0x31 \n"); 178 "Found VIA VT1636 LVDS on port i2c 0x31\n");
180 } else { 179 } else {
181 viaparinfo->shared->i2c_stuff.i2c_port = GPIOPORTINDEX; 180 if (viafb_lvds_identify_vt1636(VIA_I2C_ADAP_2C)) {
182 if (viafb_lvds_identify_vt1636()) {
183 viaparinfo->chip_info->lvds_chip_info.i2c_port = 181 viaparinfo->chip_info->lvds_chip_info.i2c_port =
184 GPIOPORTINDEX; 182 VIA_I2C_ADAP_2C;
185 DEBUG_MSG(KERN_INFO 183 DEBUG_MSG(KERN_INFO
186 "Found VIA VT1636 LVDS on port gpio 0x2c \n"); 184 "Found VIA VT1636 LVDS on port gpio 0x2c\n");
187 } 185 }
188 } 186 }
189 187
@@ -421,9 +419,8 @@ static int lvds_register_read(int index)
421{ 419{
422 u8 data; 420 u8 data;
423 421
424 viaparinfo->shared->i2c_stuff.i2c_port = GPIOPORTINDEX; 422 viafb_i2c_readbyte(VIA_I2C_ADAP_2C,
425 viafb_i2c_readbyte((u8) viaparinfo->chip_info-> 423 (u8) viaparinfo->chip_info->lvds_chip_info.lvds_chip_slave_addr,
426 lvds_chip_info.lvds_chip_slave_addr,
427 (u8) index, &data); 424 (u8) index, &data);
428 return data; 425 return data;
429} 426}
diff --git a/drivers/video/via/via_i2c.c b/drivers/video/via/via_i2c.c
index 15543e968248..8f8e0bf0cf91 100644
--- a/drivers/video/via/via_i2c.c
+++ b/drivers/video/via/via_i2c.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved. 2 * Copyright 1998-2009 VIA Technologies, Inc. All Rights Reserved.
3 * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved. 3 * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
4 4
5 * This program is free software; you can redistribute it and/or 5 * This program is free software; you can redistribute it and/or
@@ -24,40 +24,44 @@
24static void via_i2c_setscl(void *data, int state) 24static void via_i2c_setscl(void *data, int state)
25{ 25{
26 u8 val; 26 u8 val;
27 struct via_i2c_stuff *via_i2c_chan = (struct via_i2c_stuff *)data; 27 struct via_i2c_adap_cfg *adap_data = data;
28 28
29 val = viafb_read_reg(VIASR, via_i2c_chan->i2c_port) & 0xF0; 29 printk(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,
32 adap_data->ioport_index) & 0xF0;
30 if (state) 33 if (state)
31 val |= 0x20; 34 val |= 0x20;
32 else 35 else
33 val &= ~0x20; 36 val &= ~0x20;
34 switch (via_i2c_chan->i2c_port) { 37 switch (adap_data->type) {
35 case I2CPORTINDEX: 38 case VIA_I2C_I2C:
36 val |= 0x01; 39 val |= 0x01;
37 break; 40 break;
38 case GPIOPORTINDEX: 41 case VIA_I2C_GPIO:
39 val |= 0x80; 42 val |= 0x80;
40 break; 43 break;
41 default: 44 default:
42 DEBUG_MSG("via_i2c: specify wrong i2c port.\n"); 45 DEBUG_MSG("viafb_i2c: specify wrong i2c type.\n");
43 } 46 }
44 viafb_write_reg(via_i2c_chan->i2c_port, VIASR, val); 47 viafb_write_reg(adap_data->ioport_index,
48 adap_data->io_port, val);
45} 49}
46 50
47static int via_i2c_getscl(void *data) 51static int via_i2c_getscl(void *data)
48{ 52{
49 struct via_i2c_stuff *via_i2c_chan = (struct via_i2c_stuff *)data; 53 struct via_i2c_adap_cfg *adap_data = data;
50 54
51 if (viafb_read_reg(VIASR, via_i2c_chan->i2c_port) & 0x08) 55 if (viafb_read_reg(adap_data->io_port, adap_data->ioport_index) & 0x08)
52 return 1; 56 return 1;
53 return 0; 57 return 0;
54} 58}
55 59
56static int via_i2c_getsda(void *data) 60static int via_i2c_getsda(void *data)
57{ 61{
58 struct via_i2c_stuff *via_i2c_chan = (struct via_i2c_stuff *)data; 62 struct via_i2c_adap_cfg *adap_data = data;
59 63
60 if (viafb_read_reg(VIASR, via_i2c_chan->i2c_port) & 0x04) 64 if (viafb_read_reg(adap_data->io_port, adap_data->ioport_index) & 0x04)
61 return 1; 65 return 1;
62 return 0; 66 return 0;
63} 67}
@@ -65,27 +69,29 @@ static int via_i2c_getsda(void *data)
65static void via_i2c_setsda(void *data, int state) 69static void via_i2c_setsda(void *data, int state)
66{ 70{
67 u8 val; 71 u8 val;
68 struct via_i2c_stuff *via_i2c_chan = (struct via_i2c_stuff *)data; 72 struct via_i2c_adap_cfg *adap_data = data;
69 73
70 val = viafb_read_reg(VIASR, via_i2c_chan->i2c_port) & 0xF0; 74 val = viafb_read_reg(adap_data->io_port,
75 adap_data->ioport_index) & 0xF0;
71 if (state) 76 if (state)
72 val |= 0x10; 77 val |= 0x10;
73 else 78 else
74 val &= ~0x10; 79 val &= ~0x10;
75 switch (via_i2c_chan->i2c_port) { 80 switch (adap_data->type) {
76 case I2CPORTINDEX: 81 case VIA_I2C_I2C:
77 val |= 0x01; 82 val |= 0x01;
78 break; 83 break;
79 case GPIOPORTINDEX: 84 case VIA_I2C_GPIO:
80 val |= 0x40; 85 val |= 0x40;
81 break; 86 break;
82 default: 87 default:
83 DEBUG_MSG("via_i2c: specify wrong i2c port.\n"); 88 DEBUG_MSG("viafb_i2c: specify wrong i2c type.\n");
84 } 89 }
85 viafb_write_reg(via_i2c_chan->i2c_port, VIASR, val); 90 viafb_write_reg(adap_data->ioport_index,
91 adap_data->io_port, val);
86} 92}
87 93
88int viafb_i2c_readbyte(u8 slave_addr, u8 index, u8 *pdata) 94int viafb_i2c_readbyte(u8 adap, u8 slave_addr, u8 index, u8 *pdata)
89{ 95{
90 u8 mm1[] = {0x00}; 96 u8 mm1[] = {0x00};
91 struct i2c_msg msgs[2]; 97 struct i2c_msg msgs[2];
@@ -97,12 +103,11 @@ int viafb_i2c_readbyte(u8 slave_addr, u8 index, u8 *pdata)
97 mm1[0] = index; 103 mm1[0] = index;
98 msgs[0].len = 1; msgs[1].len = 1; 104 msgs[0].len = 1; msgs[1].len = 1;
99 msgs[0].buf = mm1; msgs[1].buf = pdata; 105 msgs[0].buf = mm1; msgs[1].buf = pdata;
100 i2c_transfer(&viaparinfo->shared->i2c_stuff.adapter, msgs, 2); 106 return i2c_transfer(&viaparinfo->shared->i2c_stuff[adap].adapter,
101 107 msgs, 2);
102 return 0;
103} 108}
104 109
105int viafb_i2c_writebyte(u8 slave_addr, u8 index, u8 data) 110int viafb_i2c_writebyte(u8 adap, u8 slave_addr, u8 index, u8 data)
106{ 111{
107 u8 msg[2] = { index, data }; 112 u8 msg[2] = { index, data };
108 struct i2c_msg msgs; 113 struct i2c_msg msgs;
@@ -111,10 +116,11 @@ int viafb_i2c_writebyte(u8 slave_addr, u8 index, u8 data)
111 msgs.addr = slave_addr / 2; 116 msgs.addr = slave_addr / 2;
112 msgs.len = 2; 117 msgs.len = 2;
113 msgs.buf = msg; 118 msgs.buf = msg;
114 return i2c_transfer(&viaparinfo->shared->i2c_stuff.adapter, &msgs, 1); 119 return i2c_transfer(&viaparinfo->shared->i2c_stuff[adap].adapter,
120 &msgs, 1);
115} 121}
116 122
117int viafb_i2c_readbytes(u8 slave_addr, u8 index, u8 *buff, int buff_len) 123int viafb_i2c_readbytes(u8 adap, u8 slave_addr, u8 index, u8 *buff, int buff_len)
118{ 124{
119 u8 mm1[] = {0x00}; 125 u8 mm1[] = {0x00};
120 struct i2c_msg msgs[2]; 126 struct i2c_msg msgs[2];
@@ -125,53 +131,88 @@ int viafb_i2c_readbytes(u8 slave_addr, u8 index, u8 *buff, int buff_len)
125 mm1[0] = index; 131 mm1[0] = index;
126 msgs[0].len = 1; msgs[1].len = buff_len; 132 msgs[0].len = 1; msgs[1].len = buff_len;
127 msgs[0].buf = mm1; msgs[1].buf = buff; 133 msgs[0].buf = mm1; msgs[1].buf = buff;
128 i2c_transfer(&viaparinfo->shared->i2c_stuff.adapter, msgs, 2); 134 return i2c_transfer(&viaparinfo->shared->i2c_stuff[adap].adapter,
129 return 0; 135 msgs, 2);
130} 136}
131 137
132int viafb_create_i2c_bus(void *viapar) 138static int create_i2c_bus(struct i2c_adapter *adapter,
139 struct i2c_algo_bit_data *algo,
140 struct via_i2c_adap_cfg *adap_cfg,
141 struct pci_dev *pdev)
133{ 142{
134 int ret; 143 printk(KERN_DEBUG "viafb: creating bus adap=0x%p, algo_bit_data=0x%p, adap_cfg=0x%p\n", adapter, algo, adap_cfg);
135 struct via_i2c_stuff *i2c_stuff = 144
136 &((struct viafb_par *)viapar)->shared->i2c_stuff; 145 algo->setsda = via_i2c_setsda;
137 146 algo->setscl = via_i2c_setscl;
138 strcpy(i2c_stuff->adapter.name, "via_i2c"); 147 algo->getsda = via_i2c_getsda;
139 i2c_stuff->i2c_port = 0x0; 148 algo->getscl = via_i2c_getscl;
140 i2c_stuff->adapter.owner = THIS_MODULE; 149 algo->udelay = 40;
141 i2c_stuff->adapter.id = 0x01FFFF; 150 algo->timeout = 20;
142 i2c_stuff->adapter.class = 0; 151 algo->data = adap_cfg;
143 i2c_stuff->adapter.algo_data = &i2c_stuff->algo; 152
144 i2c_stuff->adapter.dev.parent = NULL; 153 sprintf(adapter->name, "viafb i2c io_port idx 0x%02x",
145 i2c_stuff->algo.setsda = via_i2c_setsda; 154 adap_cfg->ioport_index);
146 i2c_stuff->algo.setscl = via_i2c_setscl; 155 adapter->owner = THIS_MODULE;
147 i2c_stuff->algo.getsda = via_i2c_getsda; 156 adapter->id = 0x01FFFF;
148 i2c_stuff->algo.getscl = via_i2c_getscl; 157 adapter->class = I2C_CLASS_DDC;
149 i2c_stuff->algo.udelay = 40; 158 adapter->algo_data = algo;
150 i2c_stuff->algo.timeout = 20; 159 if (pdev)
151 i2c_stuff->algo.data = i2c_stuff; 160 adapter->dev.parent = &pdev->dev;
152 161 else
153 i2c_set_adapdata(&i2c_stuff->adapter, i2c_stuff); 162 adapter->dev.parent = NULL;
163 /* i2c_set_adapdata(adapter, adap_cfg); */
154 164
155 /* Raise SCL and SDA */ 165 /* Raise SCL and SDA */
156 i2c_stuff->i2c_port = I2CPORTINDEX; 166 via_i2c_setsda(adap_cfg, 1);
157 via_i2c_setsda(i2c_stuff, 1); 167 via_i2c_setscl(adap_cfg, 1);
158 via_i2c_setscl(i2c_stuff, 1);
159
160 i2c_stuff->i2c_port = GPIOPORTINDEX;
161 via_i2c_setsda(i2c_stuff, 1);
162 via_i2c_setscl(i2c_stuff, 1);
163 udelay(20); 168 udelay(20);
164 169
165 ret = i2c_bit_add_bus(&i2c_stuff->adapter); 170 return i2c_bit_add_bus(adapter);
166 if (ret == 0) 171}
167 DEBUG_MSG("I2C bus %s registered.\n", i2c_stuff->adapter.name); 172
168 else 173static struct via_i2c_adap_cfg adap_configs[] = {
169 DEBUG_MSG("Failed to register I2C bus %s.\n", 174 [VIA_I2C_ADAP_26] = { VIA_I2C_I2C, VIASR, 0x26 },
170 i2c_stuff->adapter.name); 175 [VIA_I2C_ADAP_31] = { VIA_I2C_I2C, VIASR, 0x31 },
171 return ret; 176 [VIA_I2C_ADAP_25] = { VIA_I2C_GPIO, VIASR, 0x25 },
177 [VIA_I2C_ADAP_2C] = { VIA_I2C_GPIO, VIASR, 0x2c },
178 [VIA_I2C_ADAP_3D] = { VIA_I2C_GPIO, VIASR, 0x3d },
179 { 0, 0, 0 }
180};
181
182int viafb_create_i2c_busses(struct viafb_par *viapar)
183{
184 int i, ret;
185
186 for (i = 0; i < VIAFB_NUM_I2C; i++) {
187 struct via_i2c_adap_cfg *adap_cfg = &adap_configs[i];
188 struct via_i2c_stuff *i2c_stuff = &viapar->shared->i2c_stuff[i];
189
190 if (adap_cfg->type == 0)
191 break;
192
193 ret = create_i2c_bus(&i2c_stuff->adapter,
194 &i2c_stuff->algo, adap_cfg,
195 NULL); /* FIXME: PCIDEV */
196 if (ret < 0) {
197 printk(KERN_ERR "viafb: cannot create i2c bus %u:%d\n",
198 i, ret);
199 /* FIXME: properly release previous busses */
200 return ret;
201 }
202 }
203
204 return 0;
172} 205}
173 206
174void viafb_delete_i2c_buss(void *par) 207void viafb_delete_i2c_busses(struct viafb_par *par)
175{ 208{
176 i2c_del_adapter(&((struct viafb_par *)par)->shared->i2c_stuff.adapter); 209 int i;
210
211 for (i = 0; i < ARRAY_SIZE(par->shared->i2c_stuff); i++) {
212 struct via_i2c_stuff *i2c_stuff = &par->shared->i2c_stuff[i];
213 /* only remove those entries in the array that we've
214 * actually used (and thus initialized algo_data) */
215 if (i2c_stuff->adapter.algo_data == &i2c_stuff->algo)
216 i2c_del_adapter(&i2c_stuff->adapter);
217 }
177} 218}
diff --git a/drivers/video/via/via_i2c.h b/drivers/video/via/via_i2c.h
index 3a13242a3152..00ed97886842 100644
--- a/drivers/video/via/via_i2c.h
+++ b/drivers/video/via/via_i2c.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved. 2 * Copyright 1998-2009 VIA Technologies, Inc. All Rights Reserved.
3 * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved. 3 * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
4 4
5 * This program is free software; you can redistribute it and/or 5 * This program is free software; you can redistribute it and/or
@@ -24,23 +24,38 @@
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};
39
27struct via_i2c_stuff { 40struct via_i2c_stuff {
28 u16 i2c_port; /* GPIO or I2C port */ 41 u16 i2c_port; /* GPIO or I2C port */
29 struct i2c_adapter adapter; 42 struct i2c_adapter adapter;
30 struct i2c_algo_bit_data algo; 43 struct i2c_algo_bit_data algo;
31}; 44};
32 45
33#define I2CPORT 0x3c4 46enum viafb_i2c_adap {
34#define I2CPORTINDEX 0x31 47 VIA_I2C_ADAP_26,
35#define GPIOPORT 0x3C4 48 VIA_I2C_ADAP_31,
36#define GPIOPORTINDEX 0x2C 49 VIA_I2C_ADAP_25,
37#define I2C_BUS 1 50 VIA_I2C_ADAP_2C,
38#define GPIO_BUS 2 51 VIA_I2C_ADAP_3D,
39#define DELAYPORT 0x3C3 52};
40 53
41int viafb_i2c_readbyte(u8 slave_addr, u8 index, u8 *pdata); 54int viafb_i2c_readbyte(u8 adap, u8 slave_addr, u8 index, u8 *pdata);
42int viafb_i2c_writebyte(u8 slave_addr, u8 index, u8 data); 55int viafb_i2c_writebyte(u8 adap, u8 slave_addr, u8 index, u8 data);
43int viafb_i2c_readbytes(u8 slave_addr, u8 index, u8 *buff, int buff_len); 56int viafb_i2c_readbytes(u8 adap, u8 slave_addr, u8 index, u8 *buff, int buff_len);
44int viafb_create_i2c_bus(void *par); 57
45void viafb_delete_i2c_buss(void *par); 58struct viafb_par;
59int viafb_create_i2c_busses(struct viafb_par *par);
60void viafb_delete_i2c_busses(struct viafb_par *par);
46#endif /* __VIA_I2C_H__ */ 61#endif /* __VIA_I2C_H__ */
diff --git a/drivers/video/via/viafbdev.c b/drivers/video/via/viafbdev.c
index 8955ab4caac8..fa1004997c63 100644
--- a/drivers/video/via/viafbdev.c
+++ b/drivers/video/via/viafbdev.c
@@ -1775,7 +1775,7 @@ static int __devinit via_pci_probe(struct pci_dev *pdev,
1775 viafb_dual_fb = 0; 1775 viafb_dual_fb = 0;
1776 1776
1777 /* Set up I2C bus stuff */ 1777 /* Set up I2C bus stuff */
1778 rc = viafb_create_i2c_bus(viaparinfo); 1778 rc = viafb_create_i2c_busses(viaparinfo);
1779 if (rc) 1779 if (rc)
1780 goto out_fb_release; 1780 goto out_fb_release;
1781 1781
@@ -1964,7 +1964,7 @@ out_fb1_release:
1964out_unmap_screen: 1964out_unmap_screen:
1965 iounmap(viafbinfo->screen_base); 1965 iounmap(viafbinfo->screen_base);
1966out_delete_i2c: 1966out_delete_i2c:
1967 viafb_delete_i2c_buss(viaparinfo); 1967 viafb_delete_i2c_busses(viaparinfo);
1968out_fb_release: 1968out_fb_release:
1969 framebuffer_release(viafbinfo); 1969 framebuffer_release(viafbinfo);
1970 return rc; 1970 return rc;
@@ -1980,7 +1980,7 @@ static void __devexit via_pci_remove(struct pci_dev *pdev)
1980 iounmap((void *)viafbinfo->screen_base); 1980 iounmap((void *)viafbinfo->screen_base);
1981 iounmap(viaparinfo->shared->engine_mmio); 1981 iounmap(viaparinfo->shared->engine_mmio);
1982 1982
1983 viafb_delete_i2c_buss(viaparinfo); 1983 viafb_delete_i2c_busses(viaparinfo);
1984 1984
1985 framebuffer_release(viafbinfo); 1985 framebuffer_release(viafbinfo);
1986 if (viafb_dual_fb) 1986 if (viafb_dual_fb)
diff --git a/drivers/video/via/viafbdev.h b/drivers/video/via/viafbdev.h
index 61b5953cd159..4bc00ec8fb1c 100644
--- a/drivers/video/via/viafbdev.h
+++ b/drivers/video/via/viafbdev.h
@@ -37,11 +37,13 @@
37#define VERSION_OS 0 /* 0: for 32 bits OS, 1: for 64 bits OS */ 37#define VERSION_OS 0 /* 0: for 32 bits OS, 1: for 64 bits OS */
38#define VERSION_MINOR 4 38#define VERSION_MINOR 4
39 39
40#define VIAFB_NUM_I2C 5
41
40struct viafb_shared { 42struct viafb_shared {
41 struct proc_dir_entry *proc_entry; /*viafb proc entry */ 43 struct proc_dir_entry *proc_entry; /*viafb proc entry */
42 44
43 /* I2C stuff */ 45 /* I2C stuff */
44 struct via_i2c_stuff i2c_stuff; 46 struct via_i2c_stuff i2c_stuff[VIAFB_NUM_I2C];
45 47
46 /* All the information will be needed to set engine */ 48 /* All the information will be needed to set engine */
47 struct tmds_setting_information tmds_setting_info; 49 struct tmds_setting_information tmds_setting_info;
diff --git a/drivers/video/via/vt1636.c b/drivers/video/via/vt1636.c
index a6b37494e79a..4589c6e73c5d 100644
--- a/drivers/video/via/vt1636.c
+++ b/drivers/video/via/vt1636.c
@@ -27,9 +27,8 @@ u8 viafb_gpio_i2c_read_lvds(struct lvds_setting_information
27{ 27{
28 u8 data; 28 u8 data;
29 29
30 viaparinfo->shared->i2c_stuff.i2c_port = plvds_chip_info->i2c_port; 30 viafb_i2c_readbyte(plvds_chip_info->i2c_port,
31 viafb_i2c_readbyte(plvds_chip_info->lvds_chip_slave_addr, index, &data); 31 plvds_chip_info->lvds_chip_slave_addr, index, &data);
32
33 return data; 32 return data;
34} 33}
35 34
@@ -39,14 +38,13 @@ void viafb_gpio_i2c_write_mask_lvds(struct lvds_setting_information
39{ 38{
40 int index, data; 39 int index, data;
41 40
42 viaparinfo->shared->i2c_stuff.i2c_port = plvds_chip_info->i2c_port;
43
44 index = io_data.Index; 41 index = io_data.Index;
45 data = viafb_gpio_i2c_read_lvds(plvds_setting_info, plvds_chip_info, 42 data = viafb_gpio_i2c_read_lvds(plvds_setting_info, plvds_chip_info,
46 index); 43 index);
47 data = (data & (~io_data.Mask)) | io_data.Data; 44 data = (data & (~io_data.Mask)) | io_data.Data;
48 45
49 viafb_i2c_writebyte(plvds_chip_info->lvds_chip_slave_addr, index, data); 46 viafb_i2c_writebyte(plvds_chip_info->i2c_port,
47 plvds_chip_info->lvds_chip_slave_addr, index, data);
50} 48}
51 49
52void viafb_init_lvds_vt1636(struct lvds_setting_information 50void viafb_init_lvds_vt1636(struct lvds_setting_information
@@ -159,7 +157,7 @@ void viafb_disable_lvds_vt1636(struct lvds_setting_information
159 } 157 }
160} 158}
161 159
162bool viafb_lvds_identify_vt1636(void) 160bool viafb_lvds_identify_vt1636(u8 i2c_adapter)
163{ 161{
164 u8 Buffer[2]; 162 u8 Buffer[2];
165 163
@@ -170,23 +168,23 @@ bool viafb_lvds_identify_vt1636(void)
170 VT1636_LVDS_I2C_ADDR; 168 VT1636_LVDS_I2C_ADDR;
171 169
172 /* Check vendor ID first: */ 170 /* Check vendor ID first: */
173 viafb_i2c_readbyte((u8) viaparinfo->chip_info->lvds_chip_info. 171 viafb_i2c_readbyte(i2c_adapter,
174 lvds_chip_slave_addr, 172 (u8) viaparinfo->chip_info->lvds_chip_info.lvds_chip_slave_addr,
175 0x00, &Buffer[0]); 173 0x00, &Buffer[0]);
176 viafb_i2c_readbyte((u8) viaparinfo->chip_info->lvds_chip_info. 174 viafb_i2c_readbyte(i2c_adapter,
177 lvds_chip_slave_addr, 175 (u8) viaparinfo->chip_info->lvds_chip_info.lvds_chip_slave_addr,
178 0x01, &Buffer[1]); 176 0x01, &Buffer[1]);
179 177
180 if (!((Buffer[0] == 0x06) && (Buffer[1] == 0x11))) 178 if (!((Buffer[0] == 0x06) && (Buffer[1] == 0x11)))
181 return false; 179 return false;
182 180
183 /* Check Chip ID: */ 181 /* Check Chip ID: */
184 viafb_i2c_readbyte((u8) viaparinfo->chip_info->lvds_chip_info. 182 viafb_i2c_readbyte(i2c_adapter,
185 lvds_chip_slave_addr, 183 (u8) viaparinfo->chip_info->lvds_chip_info.lvds_chip_slave_addr,
186 0x02, &Buffer[0]); 184 0x02, &Buffer[0]);
187 viafb_i2c_readbyte((u8) viaparinfo->chip_info->lvds_chip_info. 185 viafb_i2c_readbyte(i2c_adapter,
188 lvds_chip_slave_addr, 186 (u8) viaparinfo->chip_info->lvds_chip_info.lvds_chip_slave_addr,
189 0x03, &Buffer[1]); 187 0x03, &Buffer[1]);
190 if ((Buffer[0] == 0x45) && (Buffer[1] == 0x33)) { 188 if ((Buffer[0] == 0x45) && (Buffer[1] == 0x33)) {
191 viaparinfo->chip_info->lvds_chip_info.lvds_chip_name = 189 viaparinfo->chip_info->lvds_chip_info.lvds_chip_name =
192 VT1636_LVDS; 190 VT1636_LVDS;
diff --git a/drivers/video/via/vt1636.h b/drivers/video/via/vt1636.h
index 2a150c58c7ed..4c1314e57468 100644
--- a/drivers/video/via/vt1636.h
+++ b/drivers/video/via/vt1636.h
@@ -22,7 +22,7 @@
22#ifndef _VT1636_H_ 22#ifndef _VT1636_H_
23#define _VT1636_H_ 23#define _VT1636_H_
24#include "chip.h" 24#include "chip.h"
25bool viafb_lvds_identify_vt1636(void); 25bool viafb_lvds_identify_vt1636(u8 i2c_adapter);
26void viafb_init_lvds_vt1636(struct lvds_setting_information 26void viafb_init_lvds_vt1636(struct lvds_setting_information
27 *plvds_setting_info, struct lvds_chip_information *plvds_chip_info); 27 *plvds_setting_info, struct lvds_chip_information *plvds_chip_info);
28void viafb_enable_lvds_vt1636(struct lvds_setting_information 28void viafb_enable_lvds_vt1636(struct lvds_setting_information