From: Krzysztof Halasa <khc@pm.waw.pl>
To: Jeff Garzik <jeff@garzik.org>
Cc: <linux-kernel@vger.kernel.org>
Subject: [PATCH] Cirrus Logic framebuffer I2C support
Date: Tue, 04 Jul 2006 21:23:28 +0200 [thread overview]
Message-ID: <m3mzbpdvin.fsf@defiant.localdomain> (raw)
Hi,
The attached patch adds I2C support to Cirrus Logic framebuffer driver.
Only "I2C adapter" is supported, it's not used for DDC purposes.
Tested with an old Intel R440LX machine against ST M24512 I2C EEPROM
connected to VGA DDC signals.
Currently works with "Alpine" chips only (CL-GD543x and 544x).
I've done it for my tests but don't know why should I keep it private.
Signed-off-by: Krzysztof Halasa <khc@pm.waw.pl>
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 4587087..b50825d 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -133,6 +133,12 @@ config FB_CIRRUS
Say N unless you have such a graphics board or plan to get one
before you next recompile the kernel.
+config FB_CIRRUS_I2C
+ bool " Enable I2C adapter driver"
+ depends on FB_CIRRUS
+ help
+ This enables I2C support for Cirrus Logic boards.
+
config FB_PM2
tristate "Permedia2 support"
depends on FB && ((AMIGA && BROKEN) || PCI)
diff --git a/drivers/video/cirrusfb.c b/drivers/video/cirrusfb.c
index 1103010..b72e3de 100644
--- a/drivers/video/cirrusfb.c
+++ b/drivers/video/cirrusfb.c
@@ -48,6 +48,8 @@ #include <linux/delay.h>
#include <linux/fb.h>
#include <linux/init.h>
#include <linux/selection.h>
+#include <linux/i2c.h>
+#include <linux/i2c-algo-bit.h>
#include <asm/pgtable.h>
#ifdef CONFIG_ZORRO
@@ -406,7 +408,11 @@ struct cirrusfb_info {
u32 pseudo_palette[16];
struct { u8 red, green, blue, pad; } palette[256];
-
+#ifdef CONFIG_FB_CIRRUS_I2C
+ int i2c_used;
+ struct i2c_adapter alpine_ops;
+ struct i2c_algo_bit_data bit_alpine_data;
+#endif
#ifdef CONFIG_ZORRO
struct zorro_dev *zdev;
#endif
@@ -2298,6 +2304,38 @@ static int cirrusfb_set_fbinfo(struct ci
return 0;
}
+#ifdef CONFIG_FB_CIRRUS_I2C
+static void alpine_setsda(void *ptr, int state)
+{
+ struct cirrusfb_info *cinfo = ptr;
+ u8 reg = vga_rseq(cinfo->regbase, 0x08) & ~2;
+ if (state)
+ reg |= 2;
+ vga_wseq(cinfo->regbase, 0x08, reg);
+}
+
+static void alpine_setscl(void *ptr, int state)
+{
+ struct cirrusfb_info *cinfo = ptr;
+ u8 reg = vga_rseq(cinfo->regbase, 0x08) & ~1;
+ if (state)
+ reg |= 1;
+ vga_wseq(cinfo->regbase, 0x08, reg);
+}
+
+static int alpine_getsda(void *ptr)
+{
+ struct cirrusfb_info *cinfo = ptr;
+ return !!(vga_rseq(cinfo->regbase, 0x08) & 0x80);
+}
+
+static int alpine_getscl(void *ptr)
+{
+ struct cirrusfb_info *cinfo = ptr;
+ return !!(vga_rseq(cinfo->regbase, 0x08) & 0x04);
+}
+#endif
+
static int cirrusfb_register(struct cirrusfb_info *cinfo)
{
struct fb_info *info;
@@ -2337,6 +2375,33 @@ static int cirrusfb_register(struct cirr
goto err_dealloc_cmap;
}
+#ifdef CONFIG_FB_CIRRUS_I2C
+ cinfo->i2c_used = 0;
+ if (cinfo->btype == BT_ALPINE || cinfo->btype == BT_PICASSO4) {
+ vga_wseq(cinfo->regbase, 0x08, 0x41); /* DDC mode: SCL */
+ vga_wseq(cinfo->regbase, 0x08, 0x43); /* DDC mode: SCL + SDA */
+ cinfo->bit_alpine_data.setsda = alpine_setsda;
+ cinfo->bit_alpine_data.setscl = alpine_setscl;
+ cinfo->bit_alpine_data.getsda = alpine_getsda;
+ cinfo->bit_alpine_data.getscl = alpine_getscl;
+ cinfo->bit_alpine_data.udelay = 5;
+ cinfo->bit_alpine_data.mdelay = 1;
+ cinfo->bit_alpine_data.timeout = HZ;
+ cinfo->bit_alpine_data.data = cinfo;
+ cinfo->alpine_ops.owner = THIS_MODULE;
+ cinfo->alpine_ops.id = I2C_HW_B_LP;
+ cinfo->alpine_ops.algo_data = &cinfo->bit_alpine_data;
+ strlcpy(cinfo->alpine_ops.name,
+ "Cirrus Logic Alpine DDC I2C adapter", I2C_NAME_SIZE);
+ if (!(err = i2c_bit_add_bus(&cinfo->alpine_ops))) {
+ printk(KERN_DEBUG "Initialized Alpine I2C adapter\n");
+ cinfo->i2c_used = 1;
+ } else
+ printk(KERN_WARNING "Unable to initialize Alpine I2C"
+ "adapter (result = %i)\n", err);
+ }
+#endif
+
DPRINTK ("EXIT, returning 0\n");
return 0;
@@ -2352,6 +2417,10 @@ static void __devexit cirrusfb_cleanup (
struct cirrusfb_info *cinfo = info->par;
DPRINTK ("ENTER\n");
+#ifdef CONFIG_FB_CIRRUS_I2C
+ if (cinfo->i2c_used)
+ i2c_bit_del_bus(&cinfo->alpine_ops);
+#endif
switch_monitor (cinfo, 0);
unregister_framebuffer (info);
reply other threads:[~2006-07-04 19:23 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=m3mzbpdvin.fsf@defiant.localdomain \
--to=khc@pm.waw.pl \
--cc=jeff@garzik.org \
--cc=linux-kernel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®