Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

tdfxfb: move I2C functionality into the tdfxfb

The I2C functionality provided by the i2c-voodoo3 driver is moved into the
tdfxfb (frame buffer driver for Voodoo3 cards). This way there is no
conflict between the i2c driver and the fb driver.

The tdfxfb does not make use from the DDC functionality yet but provides
all the functionality of the i2c-voodoo3 driver.

Signed-off-by: Krzysztof Helt <krzysztof.h1@wp.pl>
Acked-by: Jean Delvare <khali@linux-fr.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Krzysztof Helt and committed by
Linus Torvalds
feff3880 8f9b1528

+234 -1
+9
drivers/video/Kconfig
··· 1550 1550 select FB_CFB_IMAGEBLIT 1551 1551 select FB_CFB_FILLRECT 1552 1552 select FB_CFB_COPYAREA 1553 + select FB_MODE_HELPERS 1553 1554 help 1554 1555 This driver supports graphics boards with the 3Dfx Banshee, 1555 1556 Voodoo3 or VSA-100 (aka Voodoo4/5) chips. Say Y if you have ··· 1565 1564 ---help--- 1566 1565 This will compile the 3Dfx Banshee/Voodoo3/VSA-100 frame buffer 1567 1566 device driver with acceleration functions. 1567 + 1568 + config FB_3DFX_I2C 1569 + bool "Enable DDC/I2C support" 1570 + depends on FB_3DFX && EXPERIMENTAL 1571 + select FB_DDC 1572 + default y 1573 + help 1574 + Say Y here if you want DDC/I2C support for your 3dfx Voodoo3. 1568 1575 1569 1576 config FB_VOODOO1 1570 1577 tristate "3Dfx Voodoo Graphics (sst1) support"
+199 -1
drivers/video/tdfxfb.c
··· 10 10 * Created : Thu Sep 23 18:17:43 1999, hmallat 11 11 * Last modified: Tue Nov 2 21:19:47 1999, hmallat 12 12 * 13 + * I2C part copied from the i2c-voodoo3.c driver by: 14 + * Frodo Looijaard <frodol@dds.nl>, 15 + * Philip Edelbrock <phil@netroedge.com>, 16 + * Ralph Metzler <rjkm@thp.uni-koeln.de>, and 17 + * Mark D. Studebaker <mdsxyz123@yahoo.com> 18 + * 13 19 * Lots of the information here comes from the Daryll Strauss' Banshee 14 20 * patches to the XF86 server, and the rest comes from the 3dfx 15 21 * Banshee specification. I'm very much indebted to Daryll for his ··· 1173 1167 #endif 1174 1168 }; 1175 1169 1170 + #ifdef CONFIG_FB_3DFX_I2C 1171 + /* The voo GPIO registers don't have individual masks for each bit 1172 + so we always have to read before writing. */ 1173 + 1174 + static void tdfxfb_i2c_setscl(void *data, int val) 1175 + { 1176 + struct tdfxfb_i2c_chan *chan = data; 1177 + struct tdfx_par *par = chan->par; 1178 + unsigned int r; 1179 + 1180 + r = tdfx_inl(par, VIDSERPARPORT); 1181 + if (val) 1182 + r |= I2C_SCL_OUT; 1183 + else 1184 + r &= ~I2C_SCL_OUT; 1185 + tdfx_outl(par, VIDSERPARPORT, r); 1186 + tdfx_inl(par, VIDSERPARPORT); /* flush posted write */ 1187 + } 1188 + 1189 + static void tdfxfb_i2c_setsda(void *data, int val) 1190 + { 1191 + struct tdfxfb_i2c_chan *chan = data; 1192 + struct tdfx_par *par = chan->par; 1193 + unsigned int r; 1194 + 1195 + r = tdfx_inl(par, VIDSERPARPORT); 1196 + if (val) 1197 + r |= I2C_SDA_OUT; 1198 + else 1199 + r &= ~I2C_SDA_OUT; 1200 + tdfx_outl(par, VIDSERPARPORT, r); 1201 + tdfx_inl(par, VIDSERPARPORT); /* flush posted write */ 1202 + } 1203 + 1204 + /* The GPIO pins are open drain, so the pins always remain outputs. 1205 + We rely on the i2c-algo-bit routines to set the pins high before 1206 + reading the input from other chips. */ 1207 + 1208 + static int tdfxfb_i2c_getscl(void *data) 1209 + { 1210 + struct tdfxfb_i2c_chan *chan = data; 1211 + struct tdfx_par *par = chan->par; 1212 + 1213 + return (0 != (tdfx_inl(par, VIDSERPARPORT) & I2C_SCL_IN)); 1214 + } 1215 + 1216 + static int tdfxfb_i2c_getsda(void *data) 1217 + { 1218 + struct tdfxfb_i2c_chan *chan = data; 1219 + struct tdfx_par *par = chan->par; 1220 + 1221 + return (0 != (tdfx_inl(par, VIDSERPARPORT) & I2C_SDA_IN)); 1222 + } 1223 + 1224 + static void tdfxfb_ddc_setscl(void *data, int val) 1225 + { 1226 + struct tdfxfb_i2c_chan *chan = data; 1227 + struct tdfx_par *par = chan->par; 1228 + unsigned int r; 1229 + 1230 + r = tdfx_inl(par, VIDSERPARPORT); 1231 + if (val) 1232 + r |= DDC_SCL_OUT; 1233 + else 1234 + r &= ~DDC_SCL_OUT; 1235 + tdfx_outl(par, VIDSERPARPORT, r); 1236 + tdfx_inl(par, VIDSERPARPORT); /* flush posted write */ 1237 + } 1238 + 1239 + static void tdfxfb_ddc_setsda(void *data, int val) 1240 + { 1241 + struct tdfxfb_i2c_chan *chan = data; 1242 + struct tdfx_par *par = chan->par; 1243 + unsigned int r; 1244 + 1245 + r = tdfx_inl(par, VIDSERPARPORT); 1246 + if (val) 1247 + r |= DDC_SDA_OUT; 1248 + else 1249 + r &= ~DDC_SDA_OUT; 1250 + tdfx_outl(par, VIDSERPARPORT, r); 1251 + tdfx_inl(par, VIDSERPARPORT); /* flush posted write */ 1252 + } 1253 + 1254 + static int tdfxfb_ddc_getscl(void *data) 1255 + { 1256 + struct tdfxfb_i2c_chan *chan = data; 1257 + struct tdfx_par *par = chan->par; 1258 + 1259 + return (0 != (tdfx_inl(par, VIDSERPARPORT) & DDC_SCL_IN)); 1260 + } 1261 + 1262 + static int tdfxfb_ddc_getsda(void *data) 1263 + { 1264 + struct tdfxfb_i2c_chan *chan = data; 1265 + struct tdfx_par *par = chan->par; 1266 + 1267 + return (0 != (tdfx_inl(par, VIDSERPARPORT) & DDC_SDA_IN)); 1268 + } 1269 + 1270 + static int __devinit tdfxfb_setup_ddc_bus(struct tdfxfb_i2c_chan *chan, 1271 + const char *name, struct device *dev) 1272 + { 1273 + int rc; 1274 + 1275 + strlcpy(chan->adapter.name, name, sizeof(chan->adapter.name)); 1276 + chan->adapter.owner = THIS_MODULE; 1277 + chan->adapter.class = I2C_CLASS_DDC; 1278 + chan->adapter.algo_data = &chan->algo; 1279 + chan->adapter.dev.parent = dev; 1280 + chan->algo.setsda = tdfxfb_ddc_setsda; 1281 + chan->algo.setscl = tdfxfb_ddc_setscl; 1282 + chan->algo.getsda = tdfxfb_ddc_getsda; 1283 + chan->algo.getscl = tdfxfb_ddc_getscl; 1284 + chan->algo.udelay = 10; 1285 + chan->algo.timeout = msecs_to_jiffies(500); 1286 + chan->algo.data = chan; 1287 + 1288 + i2c_set_adapdata(&chan->adapter, chan); 1289 + 1290 + rc = i2c_bit_add_bus(&chan->adapter); 1291 + if (rc == 0) 1292 + DPRINTK("I2C bus %s registered.\n", name); 1293 + else 1294 + chan->par = NULL; 1295 + 1296 + return rc; 1297 + } 1298 + 1299 + static int __devinit tdfxfb_setup_i2c_bus(struct tdfxfb_i2c_chan *chan, 1300 + const char *name, struct device *dev) 1301 + { 1302 + int rc; 1303 + 1304 + strlcpy(chan->adapter.name, name, sizeof(chan->adapter.name)); 1305 + chan->adapter.owner = THIS_MODULE; 1306 + chan->adapter.class = I2C_CLASS_TV_ANALOG; 1307 + chan->adapter.algo_data = &chan->algo; 1308 + chan->adapter.dev.parent = dev; 1309 + chan->algo.setsda = tdfxfb_i2c_setsda; 1310 + chan->algo.setscl = tdfxfb_i2c_setscl; 1311 + chan->algo.getsda = tdfxfb_i2c_getsda; 1312 + chan->algo.getscl = tdfxfb_i2c_getscl; 1313 + chan->algo.udelay = 10; 1314 + chan->algo.timeout = msecs_to_jiffies(500); 1315 + chan->algo.data = chan; 1316 + 1317 + i2c_set_adapdata(&chan->adapter, chan); 1318 + 1319 + rc = i2c_bit_add_bus(&chan->adapter); 1320 + if (rc == 0) 1321 + DPRINTK("I2C bus %s registered.\n", name); 1322 + else 1323 + chan->par = NULL; 1324 + 1325 + return rc; 1326 + } 1327 + 1328 + static void __devinit tdfxfb_create_i2c_busses(struct fb_info *info) 1329 + { 1330 + struct tdfx_par *par = info->par; 1331 + 1332 + tdfx_outl(par, VIDINFORMAT, 0x8160); 1333 + tdfx_outl(par, VIDSERPARPORT, 0xcffc0020); 1334 + 1335 + par->chan[0].par = par; 1336 + par->chan[1].par = par; 1337 + 1338 + tdfxfb_setup_ddc_bus(&par->chan[0], "Voodoo3-DDC", info->dev); 1339 + tdfxfb_setup_i2c_bus(&par->chan[1], "Voodoo3-I2C", info->dev); 1340 + } 1341 + 1342 + static void tdfxfb_delete_i2c_busses(struct tdfx_par *par) 1343 + { 1344 + if (par->chan[0].par) 1345 + i2c_del_adapter(&par->chan[0].adapter); 1346 + par->chan[0].par = NULL; 1347 + 1348 + if (par->chan[1].par) 1349 + i2c_del_adapter(&par->chan[1].adapter); 1350 + par->chan[1].par = NULL; 1351 + } 1352 + #endif /* CONFIG_FB_3DFX_I2C */ 1353 + 1176 1354 /** 1177 1355 * tdfxfb_probe - Device Initializiation 1178 1356 * ··· 1474 1284 if (hwcursor) 1475 1285 info->fix.smem_len = (info->fix.smem_len - 1024) & 1476 1286 (PAGE_MASK << 1); 1477 - 1287 + #ifdef CONFIG_FB_3DFX_I2C 1288 + tdfxfb_create_i2c_busses(info); 1289 + #endif 1478 1290 if (!mode_option) 1479 1291 mode_option = "640x480@60"; 1480 1292 ··· 1507 1315 return 0; 1508 1316 1509 1317 out_err_iobase: 1318 + #ifdef CONFIG_FB_3DFX_I2C 1319 + tdfxfb_delete_i2c_busses(default_par); 1320 + #endif 1510 1321 if (default_par->mtrr_handle >= 0) 1511 1322 mtrr_del(default_par->mtrr_handle, info->fix.smem_start, 1512 1323 info->fix.smem_len); ··· 1574 1379 struct tdfx_par *par = info->par; 1575 1380 1576 1381 unregister_framebuffer(info); 1382 + #ifdef CONFIG_FB_3DFX_I2C 1383 + tdfxfb_delete_i2c_busses(par); 1384 + #endif 1577 1385 if (par->mtrr_handle >= 0) 1578 1386 mtrr_del(par->mtrr_handle, info->fix.smem_start, 1579 1387 info->fix.smem_len);
+26
include/video/tdfx.h
··· 1 1 #ifndef _TDFX_H 2 2 #define _TDFX_H 3 3 4 + #include <linux/i2c.h> 5 + #include <linux/i2c-algo-bit.h> 6 + 4 7 /* membase0 register offsets */ 5 8 #define STATUS 0x00 6 9 #define PCIINIT0 0x04 ··· 126 123 #define VIDCFG_PIXFMT_SHIFT 18 127 124 #define DACMODE_2X BIT(0) 128 125 126 + /* I2C bit locations in the VIDSERPARPORT register */ 127 + #define DDC_ENAB 0x00040000 128 + #define DDC_SCL_OUT 0x00080000 129 + #define DDC_SDA_OUT 0x00100000 130 + #define DDC_SCL_IN 0x00200000 131 + #define DDC_SDA_IN 0x00400000 132 + #define I2C_ENAB 0x00800000 133 + #define I2C_SCL_OUT 0x01000000 134 + #define I2C_SDA_OUT 0x02000000 135 + #define I2C_SCL_IN 0x04000000 136 + #define I2C_SDA_IN 0x08000000 137 + 129 138 /* VGA rubbish, need to change this for multihead support */ 130 139 #define MISC_W 0x3c2 131 140 #define MISC_R 0x3cc ··· 183 168 unsigned long miscinit0; 184 169 }; 185 170 171 + struct tdfx_par; 172 + 173 + struct tdfxfb_i2c_chan { 174 + struct tdfx_par *par; 175 + struct i2c_adapter adapter; 176 + struct i2c_algo_bit_data algo; 177 + }; 178 + 186 179 struct tdfx_par { 187 180 u32 max_pixclock; 188 181 u32 palette[16]; 189 182 void __iomem *regbase_virt; 190 183 unsigned long iobase; 191 184 int mtrr_handle; 185 + #ifdef CONFIG_FB_3DFX_I2C 186 + struct tdfxfb_i2c_chan chan[2]; 187 + #endif 192 188 }; 193 189 194 190 #endif /* __KERNEL__ */