/*
 * 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(struct work_struct *private_);

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


/*
 * 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(struct work_struct *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);

