/*
 * i2c-amd756-s4882.c - i2c-amd756 extras for the Tyan S4882 motherboard
 *
 * Copyright (C) 2004, 2008 Jean Delvare <jdelvare@suse.de>
 *
 * 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.
 */
 
/*
 * We select the channels by sending commands to the Philips
 * PCA9556 chip at I2C address 0x18. The main adapter is used for
 * the non-multiplexed part of the bus, and 4 virtual adapters
 * are defined for the multiplexed addresses: 0x50-0x53 (memory
 * module EEPROM) located on channels 1-4, and 0x4c (LM63)
 * located on multiplexed channels 0 and 5-7. We define one
 * virtual adapter per CPU, which corresponds to two multiplexed
 * channels:
 *   CPU0: virtual adapter 1, channels 1 and 0
 *   CPU1: virtual adapter 2, channels 2 and 5
 *   CPU2: virtual adapter 3, channels 3 and 6
 *   CPU3: virtual adapter 4, channels 4 and 7
 */

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/init.h>
#include <linux/i2c.h>
#include <linux/mutex.h>

extern struct i2c_adapter amd756_smbus;

static struct i2c_adapter *s4882_adapter;
static struct i2c_algorithm *s4882_algo;

/* Wrapper access functions for multiplexed SMBus */
static DEFINE_MUTEX(amd756_lock);

static s32 amd756_access_virt0(struct i2c_adapter * adap, u16 addr,
			       unsigned short flags, char read_write,
			       u8 command, int size,
			       union i2c_smbus_data * data)
{
	int error;

	/* We exclude the multiplexed addresses */
	if (addr == 0x4c || (addr & 0xfc) == 0x50 || (addr & 0xfc) == 0x30
	 || addr == 0x18)
		return -ENXIO;

	mutex_lock(&amd756_lock);

	error = amd756_smbus.algo->smbus_xfer(adap, addr, flags, read_write,
					      command, size, data);

	mutex_unlock(&amd756_lock);

	return error;
}

/* We remember the last used channels combination so as to only switch
   channels when it is really needed. This greatly reduces the SMBus
   overhead, but also assumes that nobody will be writing to the PCA9556
   in our back. */
static u8 last_channels;

static inline s32 amd756_access_channel(struct i2c_adapter * adap, u16 addr,
					unsigned short flags, char read_write,
					u8 command, int size,
					union i2c_smbus_data * data,
					u8 channels)
{
	int error;

	/* We exclude the non-multiplexed addresses */
	if (addr != 0x4c && (addr & 0xfc) != 0x50 && (addr & 0xfc) != 0x30)
		return -ENXIO;

	mutex_lock(&amd756_lock);

	if (last_channels != channels) {
		union i2c_smbus_data mplxdata;
		mplxdata.byte = channels;

		error = amd756_smbus.algo->smbus_xfer(adap, 0x18, 0,
						      I2C_SMBUS_WRITE, 0x01,
						      I2C_SMBUS_BYTE_DATA,
						      &mplxdata);
		if (error)
			goto UNLOCK;
		last_channels = channels;
	}
	error = amd756_smbus.algo->smbus_xfer(adap, addr, flags, read_write,
					      command, size, data);

UNLOCK:
	mutex_unlock(&amd756_lock);
	return error;
}

static s32 amd756_access_virt1(struct i2c_adapter * adap, u16 addr,
			       unsigned short flags, char read_write,
			       u8 command, int size,
			       union i2c_smbus_data * data)
{
	/* CPU0: channels 1 and 0 enabled */
	return amd756_access_channel(adap, addr, flags, read_write, command,
				     size, data, 0x03);
}

static s32 amd756_access_virt2(struct i2c_adapter * adap, u16 addr,
			       unsigned short flags, char read_write,
			       u8 command, int size,
			       union i2c_smbus_data * data)
{
	/* CPU1: channels 2 and 5 enabled */
	return amd756_access_channel(adap, addr, flags, read_write, command,
				     size, data, 0x24);
}

static s32 amd756_access_virt3(struct i2c_adapter * adap, u16 addr,
			       unsigned short flags, char read_write,
			       u8 command, int size,
			       union i2c_smbus_data * data)
{
	/* CPU2: channels 3 and 6 enabled */
	return amd756_access_channel(adap, addr, flags, read_write, command,
				     size, data, 0x48);
}

static s32 amd756_access_virt4(struct i2c_adapter * adap, u16 addr,
			       unsigned short flags, char read_write,
			       u8 command, int size,
			       union i2c_smbus_data * data)
{
	/* CPU3: channels 4 and 7 enabled */
	return amd756_access_channel(adap, addr, flags, read_write, command,
				     size, data, 0x90);
}

static int __init amd756_s4882_init(void)
{
	int i, error;
	union i2c_smbus_data ioconfig;

	if (!amd756_smbus.dev.parent)
		return -ENODEV;

	/* Configure the PCA9556 multiplexer */
	ioconfig.byte = 0x00; /* All I/O to output mode */
	error = i2c_smbus_xfer(&amd756_smbus, 0x18, 0, I2C_SMBUS_WRITE, 0x03,
			       I2C_SMBUS_BYTE_DATA, &ioconfig);
	if (error) {
		dev_err(&amd756_smbus.dev, "PCA9556 configuration failed\n");
		error = -EIO;
		goto ERROR0;
	}

	/* Unregister physical bus */
	i2c_del_adapter(&amd756_smbus);

	printk(KERN_INFO "Enabling SMBus multiplexing for Tyan S4882\n");
	/* Define the 5 virtual adapters and algorithms structures */
	if (!(s4882_adapter = kzalloc(5 * sizeof(struct i2c_adapter),
				      GFP_KERNEL))) {
		error = -ENOMEM;
		goto ERROR1;
	}
	if (!(s4882_algo = kzalloc(5 * sizeof(struct i2c_algorithm),
				   GFP_KERNEL))) {
		error = -ENOMEM;
		goto ERROR2;
	}

	/* Fill in the new structures */
	s4882_algo[0] = *(amd756_smbus.algo);
	s4882_algo[0].smbus_xfer = amd756_access_virt0;
	s4882_adapter[0] = amd756_smbus;
	s4882_adapter[0].algo = s4882_algo;
	s4882_adapter[0].dev.parent = amd756_smbus.dev.parent;
	for (i = 1; i < 5; i++) {
		s4882_algo[i] = *(amd756_smbus.algo);
		s4882_adapter[i] = amd756_smbus;
		snprintf(s4882_adapter[i].name, sizeof(s4882_adapter[i].name),
			 "SMBus 8111 adapter (CPU%d)", i-1);
		s4882_adapter[i].algo = s4882_algo+i;
		s4882_adapter[i].dev.parent = amd756_smbus.dev.parent;
	}
	s4882_algo[1].smbus_xfer = amd756_access_virt1;
	s4882_algo[2].smbus_xfer = amd756_access_virt2;
	s4882_algo[3].smbus_xfer = amd756_access_virt3;
	s4882_algo[4].smbus_xfer = amd756_access_virt4;

	/* Register virtual adapters */
	for (i = 0; i < 5; i++) {
		error = i2c_add_adapter(s4882_adapter+i);
		if (error) {
			printk(KERN_ERR "i2c-amd756-s4882: "
			       "Virtual adapter %d registration "
			       "failed, module not inserted\n", i);
			for (i--; i >= 0; i--)
				i2c_del_adapter(s4882_adapter+i);
			goto ERROR3;
		}
	}

	return 0;

ERROR3:
	kfree(s4882_algo);
	s4882_algo = NULL;
ERROR2:
	kfree(s4882_adapter);
	s4882_adapter = NULL;
ERROR1:
	/* Restore physical bus */
	i2c_add_adapter(&amd756_smbus);
ERROR0:
	return error;
}

static void __exit amd756_s4882_exit(void)
{
	if (s4882_adapter) {
		int i;

		for (i = 0; i < 5; i++)
			i2c_del_adapter(s4882_adapter+i);
		kfree(s4882_adapter);
		s4882_adapter = NULL;
	}
	kfree(s4882_algo);
	s4882_algo = NULL;

	/* Restore physical bus */
	if (i2c_add_adapter(&amd756_smbus))
		printk(KERN_ERR "i2c-amd756-s4882: "
		       "Physical bus restoration failed\n");
}

MODULE_AUTHOR("Jean Delvare <jdelvare@suse.de>");
MODULE_DESCRIPTION("S4882 SMBus multiplexing");
MODULE_LICENSE("GPL");

module_init(amd756_s4882_init);
module_exit(amd756_s4882_exit);
