Linux-2.6.12-rc2

Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.

Let it rip!
diff --git a/sound/oss/dmasound/tas_common.c b/sound/oss/dmasound/tas_common.c
new file mode 100644
index 0000000..d36a1fe
--- /dev/null
+++ b/sound/oss/dmasound/tas_common.c
@@ -0,0 +1,214 @@
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/proc_fs.h>
+#include <linux/ioport.h>
+#include <linux/sysctl.h>
+#include <linux/types.h>
+#include <linux/i2c.h>
+#include <linux/init.h>
+#include <linux/soundcard.h>
+#include <asm/uaccess.h>
+#include <asm/errno.h>
+#include <asm/io.h>
+#include <asm/prom.h>
+
+#include "tas_common.h"
+
+#define CALL0(proc)								\
+	do {									\
+		struct tas_data_t *self;					\
+		if (!tas_client || driver_hooks == NULL)			\
+			return -1;						\
+		self = dev_get_drvdata(&tas_client->dev);			\
+		if (driver_hooks->proc)						\
+			return driver_hooks->proc(self);			\
+		else								\
+			return -EINVAL;						\
+	} while (0)
+
+#define CALL(proc,arg...)							\
+	do {									\
+		struct tas_data_t *self;					\
+		if (!tas_client || driver_hooks == NULL)			\
+			return -1;						\
+		self = dev_get_drvdata(&tas_client->dev);			\
+		if (driver_hooks->proc)						\
+			return driver_hooks->proc(self, ## arg);		\
+		else								\
+			return -EINVAL;						\
+	} while (0)
+
+
+static u8 tas_i2c_address = 0x34;
+static struct i2c_client *tas_client;
+static struct device_node* tas_node;
+
+static int tas_attach_adapter(struct i2c_adapter *);
+static int tas_detach_client(struct i2c_client *);
+
+struct i2c_driver tas_driver = {
+	.owner		= THIS_MODULE,
+	.name		= "tas",
+	.flags		= I2C_DF_NOTIFY,
+	.attach_adapter	= tas_attach_adapter,
+	.detach_client	= tas_detach_client,
+};
+
+struct tas_driver_hooks_t *driver_hooks;
+
+int
+tas_register_driver(struct tas_driver_hooks_t *hooks)
+{
+	driver_hooks = hooks;
+	return 0;
+}
+
+int
+tas_get_mixer_level(int mixer, uint *level)
+{
+	CALL(get_mixer_level,mixer,level);
+}
+
+int
+tas_set_mixer_level(int mixer,uint level)
+{
+	CALL(set_mixer_level,mixer,level);
+}
+
+int
+tas_enter_sleep(void)
+{
+	CALL0(enter_sleep);
+}
+
+int
+tas_leave_sleep(void)
+{
+	CALL0(leave_sleep);
+}
+
+int
+tas_supported_mixers(void)
+{
+	CALL0(supported_mixers);
+}
+
+int
+tas_mixer_is_stereo(int mixer)
+{
+	CALL(mixer_is_stereo,mixer);
+}
+
+int
+tas_stereo_mixers(void)
+{
+	CALL0(stereo_mixers);
+}
+
+int
+tas_output_device_change(int device_id,int layout_id,int speaker_id)
+{
+	CALL(output_device_change,device_id,layout_id,speaker_id);
+}
+
+int
+tas_device_ioctl(u_int cmd, u_long arg)
+{
+	CALL(device_ioctl,cmd,arg);
+}
+
+int
+tas_post_init(void)
+{
+	CALL0(post_init);
+}
+
+static int
+tas_detect_client(struct i2c_adapter *adapter, int address)
+{
+	static const char *client_name = "tas Digital Equalizer";
+	struct i2c_client *new_client;
+	int rc = -ENODEV;
+
+	if (!driver_hooks) {
+		printk(KERN_ERR "tas_detect_client called with no hooks !\n");
+		return -ENODEV;
+	}
+	
+	new_client = kmalloc(sizeof(*new_client), GFP_KERNEL);
+	if (!new_client)
+		return -ENOMEM;
+	memset(new_client, 0, sizeof(*new_client));
+
+	new_client->addr = address;
+	new_client->adapter = adapter;
+	new_client->driver = &tas_driver;
+	strlcpy(new_client->name, client_name, DEVICE_NAME_SIZE);
+
+        if (driver_hooks->init(new_client))
+		goto bail;
+
+	/* Tell the i2c layer a new client has arrived */
+	if (i2c_attach_client(new_client)) {
+		driver_hooks->uninit(dev_get_drvdata(&new_client->dev));
+		goto bail;
+	}
+
+	tas_client = new_client;
+	return 0;
+ bail:
+	tas_client = NULL;
+	kfree(new_client);
+	return rc;
+}
+
+static int
+tas_attach_adapter(struct i2c_adapter *adapter)
+{
+	if (!strncmp(adapter->name, "mac-io", 6))
+		return tas_detect_client(adapter, tas_i2c_address);
+	return 0;
+}
+
+static int
+tas_detach_client(struct i2c_client *client)
+{
+	if (client == tas_client) {
+		driver_hooks->uninit(dev_get_drvdata(&client->dev));
+
+		i2c_detach_client(client);
+		kfree(client);
+	}
+	return 0;
+}
+
+void
+tas_cleanup(void)
+{
+	i2c_del_driver(&tas_driver);
+}
+
+int __init
+tas_init(int driver_id, const char *driver_name)
+{
+	u32* paddr;
+
+	printk(KERN_INFO "tas driver [%s])\n", driver_name);
+
+#ifndef CONFIG_I2C_KEYWEST
+	request_module("i2c-keywest");
+#endif
+	tas_node = find_devices("deq");
+	if (tas_node == NULL)
+		return -ENODEV;
+	paddr = (u32 *)get_property(tas_node, "i2c-address", NULL);
+	if (paddr) {
+		tas_i2c_address = (*paddr) >> 1;
+		printk(KERN_INFO "using i2c address: 0x%x from device-tree\n",
+				tas_i2c_address);
+	} else    
+		printk(KERN_INFO "using i2c address: 0x%x (default)\n",
+				tas_i2c_address);
+
+	return i2c_add_driver(&tas_driver);
+}