/*
 * Support for the Extra GPIOs on the Sharp SL-C1000 (Akita)
 * (uses a 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.
 *
 */

#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/module.h>
#include <linux/i2c.h>
#include <linux/slab.h>
#include <linux/workqueue.h>
#include <asm/arch/akita.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, I2C_CLIENT_END };

/* I2C Magic */
I2C_CLIENT_INSMOD;

static int max7310_write(struct i2c_client *client, int address, int data);
static struct i2c_client max7310_template;
static void akita_ioexp_work(void *private_);

static struct device *akita_ioexp_device;
static unsigned char ioexp_output_value = AKITA_IOEXP_IO_OUT;
DECLARE_WORK(akita_ioexp, akita_ioexp_work, NULL);


/*
 * MAX7310 Access
 */
static 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;
}

static int max7310_set_ouputs(struct device *dev, int outputs)
{
	struct i2c_client *client = to_i2c_client(dev);

	return max7310_write(client, MAX7310_OUTPUT, outputs);
}

/*
 * 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_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;
	}

	max7310_config(&new_client->dev, AKITA_IOEXP_IO_DIR, 0);
	akita_ioexp_device = &new_client->dev;
	schedule_work(&akita_ioexp);

	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;

	akita_ioexp_device = NULL;

	if ((err = i2c_detach_client(client)))
		return err;

	kfree(client);
	return 0;
}

static struct i2c_driver max7310_i2c_driver = {
	.driver = {
		.name	= "akita-max7310",
	},
	.id		= I2C_DRIVERID_AKITAIOEXP,
	.attach_adapter	= max7310_attach_adapter,
	.detach_client	= max7310_detach_client,
};

static struct i2c_client max7310_template = {
	name:   "akita-max7310",
	driver: &max7310_i2c_driver,
};

void akita_set_ioexp(struct device *dev, unsigned char bit)
{
	ioexp_output_value |= bit;

	if (akita_ioexp_device)
		schedule_work(&akita_ioexp);
	return;
}

void akita_reset_ioexp(struct device *dev, unsigned char bit)
{
	ioexp_output_value &= ~bit;

	if (akita_ioexp_device)
		schedule_work(&akita_ioexp);
	return;
}

EXPORT_SYMBOL(akita_set_ioexp);
EXPORT_SYMBOL(akita_reset_ioexp);

static void akita_ioexp_work(void *private_)
{
	if (akita_ioexp_device)
		max7310_set_ouputs(akita_ioexp_device, ioexp_output_value);
}


#ifdef CONFIG_PM
static int akita_ioexp_suspend(struct platform_device *pdev, pm_message_t state)
{
	flush_scheduled_work();
	return 0;
}

static int akita_ioexp_resume(struct platform_device *pdev)
{
	schedule_work(&akita_ioexp);
	return 0;
}
#else
#define akita_ioexp_suspend NULL
#define akita_ioexp_resume NULL
#endif

static int __init akita_ioexp_probe(struct platform_device *pdev)
{
	return i2c_add_driver(&max7310_i2c_driver);
}

static int akita_ioexp_remove(struct platform_device *pdev)
{
	i2c_del_driver(&max7310_i2c_driver);
	return 0;
}

static struct platform_driver akita_ioexp_driver = {
	.probe		= akita_ioexp_probe,
	.remove		= akita_ioexp_remove,
	.suspend	= akita_ioexp_suspend,
	.resume		= akita_ioexp_resume,
	.driver		= {
		.name	= "akita-ioexp",
	},
};

static int __init akita_ioexp_init(void)
{
	return platform_driver_register(&akita_ioexp_driver);
}

static void __exit akita_ioexp_exit(void)
{
	platform_driver_unregister(&akita_ioexp_driver);
}

MODULE_AUTHOR("Richard Purdie <rpurdie@openedhand.com>");
MODULE_DESCRIPTION("Akita IO-Expander driver");
MODULE_LICENSE("GPL");

fs_initcall(akita_ioexp_init);
module_exit(akita_ioexp_exit);

