Index: linux-2.6.13/drivers/i2c/chips/max7310.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-2.6.13/drivers/i2c/chips/max7310.c	2005-10-29 18:45:26.000000000 +0100
@@ -0,0 +1,202 @@
+/* 
+ * max7310.c  --  Maxim MAX7310 8 Port IO Expander
+ *
+ * Copyright 2005 Openedhand Ltd.
+ *
+ * Author: Richard Purdie <richard@openedhand.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#define I2C_DRIVERID_MAX7310 0xdafe
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+
+/* MAX7310 Regiser Map */
+#define MAX7310_INPUT    0x00
+#define MAX7310_OUTPUT   0x01
+#define MAX7310_POLINV   0x02
+#define MAX7310_IODIR    0x03 /* 1 = Input, 0 = Output */
+#define MAX7310_TIMEOUT  0x04
+
+/* Addresses to scan */
+static unsigned short normal_i2c[] = { 
+	0x18,
+//	0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,  
+//	0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 
+//	0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 
+//	0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 
+//	0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 
+//	0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 
+//	0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
+	I2C_CLIENT_END 
+};
+
+/* I2C Magic */
+I2C_CLIENT_INSMOD;
+
+static int max7310_write(struct i2c_client *client, int address, int data);
+static int max7310_read(struct i2c_client *client, int address);
+static struct i2c_client max7310_template;
+
+/* 
+ * Public Interface
+ */
+int max7310_config(struct device *dev, int iomode, int polarity)
+{
+	int ret;
+	struct i2c_client *client = to_i2c_client(dev);
+
+	ret = max7310_write(client, MAX7310_POLINV, polarity); 
+	if (ret < 0)
+		return ret;
+	ret = max7310_write(client, MAX7310_IODIR, iomode); 
+	return ret;
+}
+
+int max7310_set_ouputs(struct device *dev, int outputs)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+
+	return max7310_write(client, MAX7310_OUTPUT, outputs); 
+}
+
+int max7310_read_inputs(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+
+	return max7310_read(client, MAX7310_INPUT); 
+}
+
+EXPORT_SYMBOL(max7310_config);
+EXPORT_SYMBOL(max7310_set_ouputs);
+EXPORT_SYMBOL(max7310_read_inputs);
+
+
+/* 
+ * Sysfs Functions 
+ */
+static ssize_t show_gpio(struct device *dev, struct device_attribute *attr, char *buf)
+{
+	return sprintf(buf, "0x%02x\n", max7310_read_inputs(dev));
+}
+
+static ssize_t set_gpio(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
+{
+	unsigned long val = simple_strtoul(buf, NULL, 16);
+
+	if (val > 0xff)
+		return -EINVAL;
+
+	max7310_set_ouputs(dev, val);
+
+	return count;
+}
+
+static DEVICE_ATTR(gpio, S_IWUSR | S_IRUGO, show_gpio, set_gpio);
+
+
+/*
+ * I2C Functions
+ */
+static int max7310_write(struct i2c_client *client, int address, int value)
+{
+	u8 data[2];
+
+	data[0] = address & 0xff;
+	data[1] = value & 0xff;
+
+	if (i2c_master_send(client, data, 2) == 2)
+		return 0;
+	return -1;
+}
+
+static int max7310_read(struct i2c_client *client, int address)
+{
+	u8 data[1];
+
+	data[0] = address & 0xff;
+
+	if (i2c_master_recv(client, data, 1) == 1) {
+		return data[0];
+	}
+	return -1;
+}
+
+static int max7310_detect(struct i2c_adapter *adapter, int address, int kind)
+{
+	struct i2c_client *new_client;
+	int err;
+
+	if (!(new_client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL)))
+		return -ENOMEM;
+
+	max7310_template.adapter = adapter;
+	max7310_template.addr = address;
+	
+	memcpy(new_client, &max7310_template, sizeof(struct i2c_client));
+
+	if ((err = i2c_attach_client(new_client))) {
+		kfree(new_client);
+		return err;
+	}
+	
+	/* Register sysfs hooks */
+	device_create_file(&new_client->dev, &dev_attr_gpio);
+	return 0;
+}
+
+static int max7310_attach_adapter(struct i2c_adapter *adapter)
+{
+	return i2c_probe(adapter, &addr_data, max7310_detect);
+}
+
+static int max7310_detach_client(struct i2c_client *client)
+{
+	int err;
+
+	device_remove_file(&client->dev, &dev_attr_gpio);
+
+	if ((err = i2c_detach_client(client)))
+		return err;
+
+	kfree(client);
+	return 0;
+}
+
+static struct i2c_driver max7310_i2c_driver = {
+	.owner		= THIS_MODULE,
+	.name		= "max7310",
+	.id		= I2C_DRIVERID_MAX7310,
+	.flags		= I2C_DF_NOTIFY,
+	.attach_adapter	= max7310_attach_adapter,
+	.detach_client	= max7310_detach_client,
+};
+
+static struct i2c_client max7310_template = {
+	name:   "max7310",
+	flags:  I2C_CLIENT_ALLOW_USE,
+	driver: &max7310_i2c_driver,
+};
+
+static int __init max7310_init(void)
+{
+	return i2c_add_driver(&max7310_i2c_driver);
+}
+
+static void __exit max7310_exit(void)
+{
+	i2c_del_driver(&max7310_i2c_driver);
+}
+
+MODULE_AUTHOR("Richard Purdie <rpurdie@openedhand.com>");
+MODULE_DESCRIPTION("MAX7310 driver");
+MODULE_LICENSE("GPL");
+
+module_init(max7310_init);
+module_exit(max7310_exit);
Index: linux-2.6.13/drivers/i2c/chips/Kconfig
===================================================================
--- linux-2.6.13.orig/drivers/i2c/chips/Kconfig	2005-10-28 11:33:51.000000000 +0100
+++ linux-2.6.13/drivers/i2c/chips/Kconfig	2005-10-28 11:34:19.000000000 +0100
@@ -126,4 +126,17 @@
 	  This driver can also be built as a module.  If so, the module
 	  will be called max6875.
 
+config MAX7310
+	tristate "Maxim MAX7310 8 Port IO Exander"
+	depends on I2C && EXPERIMENTAL
+	help
+	  If you say yes here you get support for the Maxim MAX7310
+	  8 Port IO Exander. 
+
+	  This chip is found in certain devices such as the Sharp Zaurus
+	  SL-C1000 (Akita).
+	  
+	  This driver can also be built as a module.  If so, the module
+	  will be called max7310.
+
 endmenu
Index: linux-2.6.13/drivers/i2c/chips/Makefile
===================================================================
--- linux-2.6.13.orig/drivers/i2c/chips/Makefile	2005-08-29 00:41:01.000000000 +0100
+++ linux-2.6.13/drivers/i2c/chips/Makefile	2005-10-28 11:34:19.000000000 +0100
@@ -12,6 +12,7 @@
 obj-$(CONFIG_SENSORS_PCF8591)	+= pcf8591.o
 obj-$(CONFIG_SENSORS_RTC8564)	+= rtc8564.o
 obj-$(CONFIG_ISP1301_OMAP)	+= isp1301_omap.o
+obj-$(CONFIG_MAX7310)		+= max7310.o
 obj-$(CONFIG_TPS65010)		+= tps65010.o
 
 ifeq ($(CONFIG_I2C_DEBUG_CHIP),y)

