[PATCH lm_sensors2 CVS code] - i2c-prosavage driver
henk
henk at god.dyndns.org
Sat Jun 14 15:52:10 CEST 2003
Added i2c-prosavage bus driver to todays lm_sensors2 CVS code, an updated
./mkpatch/mkpatch.pl and ./kernel/busses/Module.mk is included.
..
/* 18-05-2003 - created
* 16-06-2003 - adapted for lm_sensors2
*
* This driver interfaces to the I2C bus of the VIA north bridge embedded
* ProSavage4/8 devices. Usefull for gaining access to the TV Encoder
chips.
..
Please include this in the CVS tree..
Have fun,
Henk Vergonet
--
-------------- next part --------------
diff -U 3 -N -r -x sensors.h -x Entries lm_sensors2/kernel/busses/Module.mk lm_sensors2-p1/kernel/busses/Module.mk
--- lm_sensors2/kernel/busses/Module.mk 2003-06-14 15:24:08.000000000 +0200
+++ lm_sensors2-p1/kernel/busses/Module.mk 2003-06-14 13:55:22.000000000 +0200
@@ -90,6 +90,9 @@
ifneq ($(shell if grep -q '^CONFIG_I2C_VOODOO3=y' $(LINUX)/.config; then echo 1; fi),1)
KERNELBUSSESTARGETS += $(MODULE_DIR)/i2c-voodoo3.o
endif
+ifneq ($(shell if grep -q '^CONFIG_I2C_PROSAVAGE=y' $(LINUX)/.config; then echo 1; fi),1)
+KERNELBUSSESTARGETS += $(MODULE_DIR)/i2c-prosavage.o
+endif
# Include all dependency files
INCLUDEFILES += $(KERNELBUSSESTARGETS:.o=.d)
diff -U 3 -N -r -x sensors.h -x Entries lm_sensors2/kernel/busses/i2c-prosavage.c lm_sensors2-p1/kernel/busses/i2c-prosavage.c
--- lm_sensors2/kernel/busses/i2c-prosavage.c 1970-01-01 01:00:00.000000000 +0100
+++ lm_sensors2-p1/kernel/busses/i2c-prosavage.c 2003-06-14 15:07:23.000000000 +0200
@@ -0,0 +1,333 @@
+/*
+ * kernel/busses/i2c-prosavage.c
+ *
+ * i2c bus driver for S3/VIA 8365/8375 graphics processor.
+ * Copyright (c) 2003 Henk Vergonet <henk at god.dyndns.org>
+ * Based on code written by:
+ * Frodo Looijaard <frodol at dds.nl>,
+ * Philip Edelbrock <phil at netroedge.com>,
+ * Ralph Metzler <rjkm at thp.uni-koeln.de>, and
+ * Mark D. Studebaker <mdsxyz123 at yahoo.com>
+ * Simon Vogl
+ * and others
+ *
+ * Please read the lm_sensors documentation for details on use.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+/* 18-05-2003 - created
+ * 16-06-2003 - adapted for lm_sensors2
+ *
+ * This driver interfaces to the I2C bus of the VIA north bridge embedded
+ * ProSavage4/8 devices. Usefull for gaining access to the TV Encoder chips.
+ *
+ * Graphics cores:
+ * S3/VIA KM266/VT8375 aka ProSavage8
+ * S3/VIA KM133/VT8365 aka Savage4
+ *
+ * Two serial busses are implemented:
+ * SERIAL1 - I2C serial communications interface
+ * SERIAL2 - DDC2 monitor communications interface
+ *
+ * Tested on a FX41 mainboard, see http://www.shuttle.com
+ *
+ *
+ * TODO:
+ * - Robust initialisation code of video registers.
+ * Get rid of the hardcoded the video IO base addresses.
+ * (Additional documentation needed :(
+ */
+
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/i2c.h>
+#include <linux/i2c-algo-bit.h>
+
+#include <asm/io.h>
+
+#include "version.h"
+
+
+/*
+ * driver configuration
+ */
+#define DRIVER_ID "i2c-prosavage"
+#define DRIVER_VERSION "20030616"
+
+
+/*
+ * i2c configuration
+ */
+#ifndef I2C_HW_B_S3VIA
+#define I2C_HW_B_S3VIA 0x18 /* S3VIA ProSavage adapter */
+#endif
+
+/* delays */
+#define CYCLE_DELAY 10
+#define TIMEOUT (HZ / 2)
+
+
+/*
+ * S3/VIA 8365/8375 registers
+ */
+#ifndef PCI_VENDOR_ID_S3
+#define PCI_VENDOR_ID_S3 0x5333
+#endif
+#ifndef PCI_DEVICE_ID_S3_SAVAGE4
+#define PCI_DEVICE_ID_S3_SAVAGE4 0x8a25
+#endif
+#ifndef PCI_DEVICE_ID_S3_PROSAVAGE8
+#define PCI_DEVICE_ID_S3_PROSAVAGE8 0x8d04
+#endif
+
+/* FIXME determine from chip config */
+#define VGA_IOBASE0 0x3c0
+#define VGA_IOBASE1 0x3d0
+
+#define IOREG_SERIAL1 0xa0 /* I2C serial communications interface */
+#define MMREG_SERIAL1 0xff20
+#define IOREG_SERIAL2 0xb1 /* DDC2 monitor communications interface */
+
+
+/* based on vt8365 documentation */
+#define I2C_ENAB 0x00000010
+#define I2C_SCL_OUT 0x00000001
+#define I2C_SDA_OUT 0x00000002
+#define I2C_SCL_IN 0x00000004
+#define I2C_SDA_IN 0x00000008
+
+
+/*
+ * Manipulate the extended video registers
+ */
+static inline unsigned int getCR0(unsigned int cr)
+{
+ outb_p((unsigned char)cr, VGA_IOBASE0 + 4);
+ return inb_p(VGA_IOBASE0 + 5);
+}
+
+static inline void setCR0(unsigned int cr, unsigned int val)
+{
+ outb_p((unsigned char)cr, VGA_IOBASE0 + 4);
+ outb_p((unsigned char)val, VGA_IOBASE0 + 5);
+}
+
+static inline unsigned int getCR1(unsigned int cr)
+{
+ outb_p((unsigned char)cr, VGA_IOBASE1 + 4);
+ return inb_p(VGA_IOBASE1 + 5);
+}
+
+static inline void setCR1(unsigned int cr, unsigned int val)
+{
+ outb_p((unsigned char)cr, VGA_IOBASE1 + 4);
+ outb_p((unsigned char)val, VGA_IOBASE1 + 5);
+}
+
+
+/*
+ * Serial bus line handling
+ *
+ * serial communications register as parameter in private data
+ */
+static void bit_s3via_setscl(void *cr, int val)
+{
+ unsigned int r;
+ r = getCR1((unsigned int)cr);
+ r |= I2C_ENAB;
+ if(val) r |= I2C_SCL_OUT;
+ else r &= ~I2C_SCL_OUT;
+ setCR1((unsigned int)cr, r);
+}
+
+static void bit_s3via_setsda(void *cr, int val)
+{
+ unsigned int r;
+ r = getCR1((unsigned int)cr);
+ r |= I2C_ENAB; /* Enable DDC */
+ if(val) r |= I2C_SDA_OUT;
+ else r &= ~I2C_SDA_OUT;
+ setCR1((unsigned int)cr, r);
+}
+
+static int bit_s3via_getscl(void *cr)
+{
+ return (0 != (getCR1((unsigned int)cr) & I2C_SCL_IN));
+}
+
+static int bit_s3via_getsda(void *cr)
+{
+ return (0 != (getCR1((unsigned int)cr) & I2C_SDA_IN));
+}
+
+
+/*
+ * WARNING these i2c_algo_bit_data struct's are shared between adapters
+ * if more than 1 video card is used. The bit-algo driver must not modify
+ * or manipulate its contents.
+ */
+static struct i2c_algo_bit_data algo_serial1 = {
+ .data = (void *)IOREG_SERIAL1,
+ .setsda = bit_s3via_setsda,
+ .setscl = bit_s3via_setscl,
+ .getsda = bit_s3via_getsda,
+ .getscl = bit_s3via_getscl,
+ .udelay = CYCLE_DELAY,
+ .mdelay = CYCLE_DELAY,
+ .timeout = TIMEOUT
+};
+
+static struct i2c_algo_bit_data algo_serial2 = {
+ .data = (void *)IOREG_SERIAL2,
+ .setsda = bit_s3via_setsda,
+ .setscl = bit_s3via_setscl,
+ .getsda = bit_s3via_getsda,
+ .getscl = bit_s3via_getscl,
+ .udelay = CYCLE_DELAY,
+ .mdelay = CYCLE_DELAY,
+ .timeout = TIMEOUT
+};
+
+static const struct i2c_adapter bus_template_i2c = {
+ .owner = THIS_MODULE,
+ .name = "ProSavage I2C bus",
+ .id = I2C_HW_B_S3VIA,
+ .algo_data = &algo_serial1,
+};
+
+static const struct i2c_adapter bus_template_ddc2 = {
+ .owner = THIS_MODULE,
+ .name = "ProSavage DDC2 bus",
+ .id = I2C_HW_B_S3VIA,
+ .algo_data = &algo_serial2,
+};
+
+#define MAX_BUSSES 2
+static int i2c_bus_cnt = 0;
+static struct i2c_adapter i2c_bus[MAX_BUSSES];
+
+
+/*
+ * adapter initialisation
+ */
+static int i2c_register_bus(struct pci_dev *dev, const struct i2c_adapter *conf)
+{
+ int ret;
+
+ if(i2c_bus_cnt > MAX_BUSSES) return -ENOSPC;
+
+ memcpy(&i2c_bus[i2c_bus_cnt], conf, sizeof(i2c_bus[i2c_bus_cnt]));
+
+ /* add a xref to the bus number */
+ snprintf(i2c_bus[i2c_bus_cnt].name, sizeof(i2c_bus[i2c_bus_cnt].name),
+ "%s at %02x:%02x.%x", conf->name,
+ dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
+
+ ret = i2c_bit_add_bus(&i2c_bus[i2c_bus_cnt]);
+ if(ret) return ret;
+
+ i2c_bus_cnt++;
+ return 0;
+}
+
+
+/*
+ * Detect chip and initialize it
+ */
+static int __devinit prosavage_probe(struct pci_dev *dev, const struct pci_device_id *id)
+{
+ int ret = 0;
+
+ /* general initialisation */
+ /* Unlock Extended IO Space */
+// setCR0(0x10, 1); // is this needed ?
+
+ /* Enable MMIO */
+// val = getCR0(0x1a);
+// setCR0(0x1a, val | 0x68);
+
+// setCR1(0x6a, 0);
+// setCR1(0x6b, 0);
+// setCR1(0x6c, 0);
+
+ ret = i2c_register_bus(dev, &bus_template_i2c);
+ if(ret) return ret;
+
+ ret = i2c_register_bus(dev, &bus_template_ddc2);
+ return ret;
+}
+
+static void __devexit prosavage_remove(struct pci_dev *dev)
+{
+ int ret;
+ while(i2c_bus_cnt > 0) {
+ i2c_bus_cnt--;
+ ret = i2c_bit_del_bus(&i2c_bus[i2c_bus_cnt]);
+ if(ret)
+ printk(DRIVER_ID ": %s not removed\n", i2c_bus[i2c_bus_cnt].name);
+ }
+}
+
+
+/*
+ * Data for PCI driver interface
+ *
+ * This data only exists for exporting the supported
+ * PCI ids via MODULE_DEVICE_TABLE.
+ */
+static struct pci_device_id prosavage_pci_tbl[] __devinitdata = {
+ {
+ .vendor = PCI_VENDOR_ID_S3,
+ .device = PCI_DEVICE_ID_S3_SAVAGE4,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ },{
+ .vendor = PCI_VENDOR_ID_S3,
+ .device = PCI_DEVICE_ID_S3_PROSAVAGE8,
+ .subvendor = PCI_ANY_ID,
+ .subdevice = PCI_ANY_ID,
+ },{ 0, }
+};
+
+static struct pci_driver prosavage_driver = {
+ .name = "s3via smbus",
+ .id_table = prosavage_pci_tbl,
+ .probe = prosavage_probe,
+ .remove = __devexit_p(prosavage_remove),
+};
+
+static int __init prosavage_init(void)
+{
+ i2c_bus_cnt = 0;
+ printk(DRIVER_ID ": version %s LM(%s)\n", DRIVER_VERSION, LM_VERSION);
+ return pci_module_init(&prosavage_driver);
+}
+
+static void __exit prosavage_exit(void)
+{
+ pci_unregister_driver(&prosavage_driver);
+}
+
+MODULE_DEVICE_TABLE(pci, prosavage_pci_tbl);
+MODULE_AUTHOR("Henk Vergonet");
+MODULE_DESCRIPTION("ProSavage VIA 8365/8375 I2C/SMBus driver");
+MODULE_LICENSE("GPL");
+
+module_init (prosavage_init);
+module_exit (prosavage_exit);
+
diff -U 3 -N -r -x sensors.h -x Entries lm_sensors2/mkpatch/mkpatch.pl lm_sensors2-p1/mkpatch/mkpatch.pl
--- lm_sensors2/mkpatch/mkpatch.pl 2003-06-14 15:24:20.000000000 +0200
+++ lm_sensors2-p1/mkpatch/mkpatch.pl 2003-06-14 14:05:21.000000000 +0200
@@ -235,6 +235,15 @@
built as a module which can be inserted and removed while the kernel
is running.
+S3VIA ProSavage
+CONFIG_I2C_PROSAVAGE
+ If you say yes to this option, support will be included for the
+ S3VIA ProSavage I2C and DDC interfaces. The I2C busses on the these
+ chips are generally used only for video devices.
+ This can also be
+ built as a module which can be inserted and removed while the kernel
+ is running.
+
DEC Tsunami 21272
CONFIG_I2C_TSUNAMI
If you say yes to this option, support will be included for the DEC
@@ -857,6 +866,7 @@
dep_tristate ' VIA Technologies, Inc. VT82C586B' CONFIG_I2C_VIA $CONFIG_I2C_ALGOBIT
dep_tristate ' VIA Technologies, Inc. VT596A/B, 686A/B, 8231, 8233, 8233A, 8235' CONFIG_I2C_VIAPRO $CONFIG_I2C
dep_tristate ' Voodoo3 I2C interface' CONFIG_I2C_VOODOO3 $CONFIG_I2C_ALGOBIT
+ dep_tristate ' ProSavage I2C/DDC interface' CONFIG_I2C_PROSAVAGE $CONFIG_I2C_ALGOBIT
dep_tristate ' Pseudo ISA adapter (for some hardware sensors)' CONFIG_I2C_ISA $CONFIG_I2C
fi
@@ -1258,6 +1268,7 @@
obj-$(CONFIG_I2C_VIA) += i2c-via.o
obj-$(CONFIG_I2C_VIAPRO) += i2c-viapro.o
obj-$(CONFIG_I2C_VOODOO3) += i2c-voodoo3.o
+obj-$(CONFIG_I2C_PROSAVAGE) += i2c-prosavage.o
export-objs += dmi_scan.o
EOF
} else {
@@ -1398,6 +1409,14 @@
endif
endif
+ifeq ($(CONFIG_I2C_PROSAVAGE),y)
+ L_OBJS += i2c-prosavage.o
+else
+ ifeq ($(CONFIG_I2C_PROSAVAGE),m)
+ M_OBJS += i2c-prosavage.o
+ endif
+endif
+
EOF
}
}
@@ -1486,6 +1505,9 @@
#ifdef CONFIG_I2C_VOODOO3
extern int i2c_voodoo3_init(void);
#endif
+#ifdef CONFIG_I2C_PROSAVAGE
+ extern int i2c_prosavage_init(void);
+#endif
EOF
} elsif ($patch_nr == 2) {
print OUTPUT << 'EOF';
@@ -1537,6 +1559,9 @@
#ifdef CONFIG_I2C_VOODOO3
i2c_voodoo3_init();
#endif
+#ifdef CONFIG_I2C_PROSAVAGE
+ i2c_prosavage_init();
+#endif
#ifdef CONFIG_I2C_ISA
i2c_isa_init();
#endif
More information about the lm-sensors
mailing list