aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video
diff options
context:
space:
mode:
authorRussell King <rmk+kernel@arm.linux.org.uk>2010-08-02 04:57:07 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2011-02-11 05:16:05 -0500
commitb7ca01a9b20e3fdd11745227905e9ad8a99e0123 (patch)
tree6d4157e1253e074343044566092bb3de3c950234 /drivers/video
parent052a7f5c496b7d2966edea0f576ec39f41703992 (diff)
VIDEO: cyberpro: add support for video capture I2C
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'drivers/video')
-rw-r--r--drivers/video/Kconfig9
-rw-r--r--drivers/video/cyber2000fb.c122
-rw-r--r--drivers/video/cyber2000fb.h1
3 files changed, 118 insertions, 14 deletions
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index e0c7edf6c82b..b20f0f81dc01 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -448,6 +448,15 @@ config FB_CYBER2000_DDC
448 Say Y here if you want DDC support for your CyberPro graphics 448 Say Y here if you want DDC support for your CyberPro graphics
449 card. This is only I2C bus support, driver does not use EDID. 449 card. This is only I2C bus support, driver does not use EDID.
450 450
451config FB_CYBER2000_I2C
452 bool "CyberPro 2000/2010/5000 I2C support"
453 depends on FB_CYBER2000 && I2C && ARCH_NETWINDER
454 select I2C_ALGOBIT
455 help
456 Enable support for the I2C video decoder interface on the
457 Integraphics CyberPro 20x0 and 5000 VGA chips. This is used
458 on the Netwinder machines for the SAA7111 video capture.
459
451config FB_APOLLO 460config FB_APOLLO
452 bool 461 bool
453 depends on (FB = y) && APOLLO 462 depends on (FB = y) && APOLLO
diff --git a/drivers/video/cyber2000fb.c b/drivers/video/cyber2000fb.c
index eeccdb8f4848..27cb3b23c3da 100644
--- a/drivers/video/cyber2000fb.c
+++ b/drivers/video/cyber2000fb.c
@@ -47,7 +47,6 @@
47#include <linux/pci.h> 47#include <linux/pci.h>
48#include <linux/init.h> 48#include <linux/init.h>
49#include <linux/io.h> 49#include <linux/io.h>
50
51#include <linux/i2c.h> 50#include <linux/i2c.h>
52#include <linux/i2c-algo-bit.h> 51#include <linux/i2c-algo-bit.h>
53 52
@@ -99,6 +98,11 @@ struct cfb_info {
99 struct i2c_adapter ddc_adapter; 98 struct i2c_adapter ddc_adapter;
100 struct i2c_algo_bit_data ddc_algo; 99 struct i2c_algo_bit_data ddc_algo;
101#endif 100#endif
101
102#ifdef CONFIG_FB_CYBER2000_I2C
103 struct i2c_adapter i2c_adapter;
104 struct i2c_algo_bit_data i2c_algo;
105#endif
102}; 106};
103 107
104static char *default_font = "Acorn8x8"; 108static char *default_font = "Acorn8x8";
@@ -1131,6 +1135,11 @@ int cyber2000fb_attach(struct cyberpro_info *info, int idx)
1131{ 1135{
1132 if (int_cfb_info != NULL) { 1136 if (int_cfb_info != NULL) {
1133 info->dev = int_cfb_info->dev; 1137 info->dev = int_cfb_info->dev;
1138#ifdef CONFIG_FB_CYBER2000_I2C
1139 info->i2c = &int_cfb_info->i2c_adapter;
1140#else
1141 info->i2c = NULL;
1142#endif
1134 info->regs = int_cfb_info->regs; 1143 info->regs = int_cfb_info->regs;
1135 info->fb = int_cfb_info->fb.screen_base; 1144 info->fb = int_cfb_info->fb.screen_base;
1136 info->fb_size = int_cfb_info->fb.fix.smem_len; 1145 info->fb_size = int_cfb_info->fb.fix.smem_len;
@@ -1251,6 +1260,86 @@ static int __devinit cyber2000fb_setup_ddc_bus(struct cfb_info *cfb)
1251} 1260}
1252#endif /* CONFIG_FB_CYBER2000_DDC */ 1261#endif /* CONFIG_FB_CYBER2000_DDC */
1253 1262
1263#ifdef CONFIG_FB_CYBER2000_I2C
1264static void cyber2000fb_i2c_setsda(void *data, int state)
1265{
1266 struct cfb_info *cfb = data;
1267 unsigned int latch2;
1268
1269 spin_lock(&cfb->reg_b0_lock);
1270 latch2 = cyber2000_grphr(EXT_LATCH2, cfb);
1271 latch2 &= EXT_LATCH2_I2C_CLKEN;
1272 if (state)
1273 latch2 |= EXT_LATCH2_I2C_DATEN;
1274 cyber2000_grphw(EXT_LATCH2, latch2, cfb);
1275 spin_unlock(&cfb->reg_b0_lock);
1276}
1277
1278static void cyber2000fb_i2c_setscl(void *data, int state)
1279{
1280 struct cfb_info *cfb = data;
1281 unsigned int latch2;
1282
1283 spin_lock(&cfb->reg_b0_lock);
1284 latch2 = cyber2000_grphr(EXT_LATCH2, cfb);
1285 latch2 &= EXT_LATCH2_I2C_DATEN;
1286 if (state)
1287 latch2 |= EXT_LATCH2_I2C_CLKEN;
1288 cyber2000_grphw(EXT_LATCH2, latch2, cfb);
1289 spin_unlock(&cfb->reg_b0_lock);
1290}
1291
1292static int cyber2000fb_i2c_getsda(void *data)
1293{
1294 struct cfb_info *cfb = data;
1295 int ret;
1296
1297 spin_lock(&cfb->reg_b0_lock);
1298 ret = !!(cyber2000_grphr(EXT_LATCH2, cfb) & EXT_LATCH2_I2C_DAT);
1299 spin_unlock(&cfb->reg_b0_lock);
1300
1301 return ret;
1302}
1303
1304static int cyber2000fb_i2c_getscl(void *data)
1305{
1306 struct cfb_info *cfb = data;
1307 int ret;
1308
1309 spin_lock(&cfb->reg_b0_lock);
1310 ret = !!(cyber2000_grphr(EXT_LATCH2, cfb) & EXT_LATCH2_I2C_CLK);
1311 spin_unlock(&cfb->reg_b0_lock);
1312
1313 return ret;
1314}
1315
1316static int __devinit cyber2000fb_i2c_register(struct cfb_info *cfb)
1317{
1318 strlcpy(cfb->i2c_adapter.name, cfb->fb.fix.id,
1319 sizeof(cfb->i2c_adapter.name));
1320 cfb->i2c_adapter.owner = THIS_MODULE;
1321 cfb->i2c_adapter.algo_data = &cfb->i2c_algo;
1322 cfb->i2c_adapter.dev.parent = &cfb->dev->dev;
1323 cfb->i2c_algo.setsda = cyber2000fb_i2c_setsda;
1324 cfb->i2c_algo.setscl = cyber2000fb_i2c_setscl;
1325 cfb->i2c_algo.getsda = cyber2000fb_i2c_getsda;
1326 cfb->i2c_algo.getscl = cyber2000fb_i2c_getscl;
1327 cfb->i2c_algo.udelay = 5;
1328 cfb->i2c_algo.timeout = msecs_to_jiffies(100);
1329 cfb->i2c_algo.data = cfb;
1330
1331 return i2c_bit_add_bus(&cfb->i2c_adapter);
1332}
1333
1334static void cyber2000fb_i2c_unregister(struct cfb_info *cfb)
1335{
1336 i2c_del_adapter(&cfb->i2c_adapter);
1337}
1338#else
1339#define cyber2000fb_i2c_register(cfb) (0)
1340#define cyber2000fb_i2c_unregister(cfb) do { } while (0)
1341#endif
1342
1254/* 1343/*
1255 * These parameters give 1344 * These parameters give
1256 * 640x480, hsync 31.5kHz, vsync 60Hz 1345 * 640x480, hsync 31.5kHz, vsync 60Hz
@@ -1520,7 +1609,14 @@ static int __devinit cyberpro_common_probe(struct cfb_info *cfb)
1520 1609
1521 if (cfb->dev) 1610 if (cfb->dev)
1522 cfb->fb.device = &cfb->dev->dev; 1611 cfb->fb.device = &cfb->dev->dev;
1612
1613 err = cyber2000fb_i2c_register(cfb);
1614 if (err)
1615 goto failed;
1616
1523 err = register_framebuffer(&cfb->fb); 1617 err = register_framebuffer(&cfb->fb);
1618 if (err)
1619 cyber2000fb_i2c_unregister(cfb);
1524 1620
1525failed: 1621failed:
1526#ifdef CONFIG_FB_CYBER2000_DDC 1622#ifdef CONFIG_FB_CYBER2000_DDC
@@ -1530,6 +1626,16 @@ failed:
1530 return err; 1626 return err;
1531} 1627}
1532 1628
1629static void __devexit cyberpro_common_remove(struct cfb_info *cfb)
1630{
1631 unregister_framebuffer(&cfb->fb);
1632#ifdef CONFIG_FB_CYBER2000_DDC
1633 if (cfb->ddc_registered)
1634 i2c_del_adapter(&cfb->ddc_adapter);
1635#endif
1636 cyber2000fb_i2c_unregister(cfb);
1637}
1638
1533static void cyberpro_common_resume(struct cfb_info *cfb) 1639static void cyberpro_common_resume(struct cfb_info *cfb)
1534{ 1640{
1535 cyberpro_init_hw(cfb); 1641 cyberpro_init_hw(cfb);
@@ -1769,19 +1875,7 @@ static void __devexit cyberpro_pci_remove(struct pci_dev *dev)
1769 struct cfb_info *cfb = pci_get_drvdata(dev); 1875 struct cfb_info *cfb = pci_get_drvdata(dev);
1770 1876
1771 if (cfb) { 1877 if (cfb) {
1772 /* 1878 cyberpro_common_remove(cfb);
1773 * If unregister_framebuffer fails, then
1774 * we will be leaving hooks that could cause
1775 * oopsen laying around.
1776 */
1777 if (unregister_framebuffer(&cfb->fb))
1778 printk(KERN_WARNING "%s: danger Will Robinson, "
1779 "danger danger! Oopsen imminent!\n",
1780 cfb->fb.fix.id);
1781#ifdef CONFIG_FB_CYBER2000_DDC
1782 if (cfb->ddc_registered)
1783 i2c_del_adapter(&cfb->ddc_adapter);
1784#endif
1785 iounmap(cfb->region); 1879 iounmap(cfb->region);
1786 cyberpro_free_fb_info(cfb); 1880 cyberpro_free_fb_info(cfb);
1787 1881
diff --git a/drivers/video/cyber2000fb.h b/drivers/video/cyber2000fb.h
index de4fc43e51c1..814cce5acf12 100644
--- a/drivers/video/cyber2000fb.h
+++ b/drivers/video/cyber2000fb.h
@@ -465,6 +465,7 @@ struct cfb_info;
465 465
466struct cyberpro_info { 466struct cyberpro_info {
467 struct pci_dev *dev; 467 struct pci_dev *dev;
468 struct i2c_adapter *i2c;
468 unsigned char __iomem *regs; 469 unsigned char __iomem *regs;
469 char __iomem *fb; 470 char __iomem *fb;
470 char dev_name[32]; 471 char dev_name[32];