/*
 * Core driver for HTC PASIC3 LED/DS1WM chip.
 *
 * Copyright (C) 2006 Philipp Zabel <philipp.zabel@gmail.com>
 *
 * 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; version 2 of the License.
 */

#include <linux/init.h>
#include <linux/module.h>
#include <linux/platform_device.h>

#include <linux/ds1wm.h>
#include <linux/gpio.h>
#include <linux/io.h>
#include <linux/irq.h>
#include <linux/interrupt.h>
#include <linux/mfd/htc-pasic3.h>

#include <asm/arch/pxa-regs.h>

struct pasic3_data {
	void __iomem *mapping;
	unsigned int bus_shift;
	struct platform_device *ds1wm_pdev;
	struct platform_device *led_pdev;
};

#define REG_ADDR  5
#define REG_DATA  6
#define NUM_REGS  7

#define READ_MODE 0x80

/*
 * write to a secondary register on the PASIC3
 */
void pasic3_write_register(struct device *dev, u32 reg, u8 val)
{
	struct pasic3_data *asic = dev->driver_data;
	int bus_shift = asic->bus_shift;
	void __iomem *addr = asic->mapping + (REG_ADDR << bus_shift);
	void __iomem *data = asic->mapping + (REG_DATA << bus_shift);

	__raw_writeb(~READ_MODE & reg, addr);
	__raw_writeb(val, data);
}
EXPORT_SYMBOL(pasic3_write_register); /* for leds-pasic3 */

/*
 * read from a secondary register on the PASIC3
 */
u8 pasic3_read_register(struct device *dev, u32 reg)
{
	struct pasic3_data *asic = dev->driver_data;
	int bus_shift = asic->bus_shift;
	void __iomem *addr = asic->mapping + (REG_ADDR << bus_shift);
	void __iomem *data = asic->mapping + (REG_DATA << bus_shift);

	__raw_writeb(READ_MODE | reg, addr);
	return __raw_readb(data);
}
EXPORT_SYMBOL(pasic3_read_register); /* for leds-pasic3 */

/*
 * LEDs
 */

static int led_device_add(struct device *pasic3_dev,
				const struct pasic3_leds_machinfo *pdata)
{
	struct pasic3_data *asic = pasic3_dev->driver_data;
	struct platform_device *pdev;
	int ret;

	pdev = platform_device_alloc("pasic3-led", -1);
	if (!pdev) {
		dev_dbg(pasic3_dev, "failed to allocate LED platform device\n");
		return -ENOMEM;
	}

	ret = platform_device_add_data(pdev, pdata,
					sizeof(struct pasic3_leds_machinfo));
	if (ret < 0) {
		dev_dbg(pasic3_dev, "failed to add LED platform data\n");
		goto exit_pdev_put;
	}

	pdev->dev.parent = pasic3_dev;
	ret = platform_device_add(pdev);
	if (ret < 0) {
		dev_dbg(pasic3_dev, "failed to add LED platform device\n");
		goto exit_pdev_put;
	}

	asic->led_pdev = pdev;
	return 0;

exit_pdev_put:
	platform_device_put(pdev);
	return ret;
}

/*
 * DS1WM
 */

static void ds1wm_enable(struct platform_device *pdev)
{
	struct device *dev = pdev->dev.parent;
	int c;

	c = pasic3_read_register(dev, 0x28);
	pasic3_write_register(dev, 0x28, c & 0x7f);

	dev_dbg(dev, "DS1WM OWM_EN low (active) %02x\n", c & 0x7f);
}

static void ds1wm_disable(struct platform_device *pdev)
{
	struct device *dev = pdev->dev.parent;
	int c;

	c = pasic3_read_register(dev, 0x28);
	pasic3_write_register(dev, 0x28, c | 0x80);

	dev_dbg(dev, "DS1WM OWM_EN high (inactive) %02x\n", c | 0x80);
}

static struct ds1wm_platform_data ds1wm_pdata = {
	.bus_shift = 2,
	.enable    = ds1wm_enable,
	.disable   = ds1wm_disable,
};

static int ds1wm_device_add(struct device *pasic3_dev, int bus_shift)
{
	struct pasic3_data *asic = pasic3_dev->driver_data;
	struct platform_device *pdev;
	int ret;

	pdev = platform_device_alloc("ds1wm", -1);
	if (!pdev) {
		dev_dbg(pasic3_dev, "failed to allocate DS1WM platform device\n");
		return -ENOMEM;
	}

	ret = platform_device_add_resources(pdev, pdev->resource,
						pdev->num_resources);
	if (ret < 0) {
		dev_dbg(pasic3_dev, "failed to add DS1WM resources\n");
		goto exit_pdev_put;
	}

	ds1wm_pdata.bus_shift = asic->bus_shift;
	ret = platform_device_add_data(pdev, &ds1wm_pdata,
					sizeof(struct ds1wm_platform_data));
	if (ret < 0) {
		dev_dbg(pasic3_dev, "failed to add DS1WM platform data\n");
		goto exit_pdev_put;
	}

	pdev->dev.parent = pasic3_dev;
	ret = platform_device_add(pdev);
	if (ret < 0) {
		dev_dbg(pasic3_dev, "failed to add DS1WM platform device\n");
		goto exit_pdev_put;
	}

	asic->ds1wm_pdev = pdev;
	return 0;

exit_pdev_put:
	platform_device_put(pdev);
	return ret;
}

static int __init pasic3_probe(struct platform_device *pdev)
{
	struct pasic3_platform_data *pdata = pdev->dev.platform_data;
	struct device *dev = &pdev->dev;
	struct pasic3_data *asic;
	struct resource *r;
	int ret;

	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!r)
		return -ENXIO;

	if (!request_mem_region(r->start, r->end - r->start + 1, "pasic3"))
		return -EBUSY;

	asic = kzalloc(sizeof(struct pasic3_data), GFP_KERNEL);
	if (!asic)
		return -ENOMEM;

	platform_set_drvdata(pdev, asic);

	if (pdata && pdata->bus_shift)
		asic->bus_shift = pdata->bus_shift;
	else
		asic->bus_shift = 2;

	asic->mapping = ioremap(r->start, r->end - r->start + 1);
	if (!asic->mapping) {
		dev_err(dev, "couldn't ioremap PASIC3\n");
		kfree(asic);
		return -ENOMEM;
	}

	ret = ds1wm_device_add(dev, asic->bus_shift);
	if (ret < 0)
		dev_warn(dev, "failed to register DS1WM\n");

	if (pdata->led_pdata) {
		ret = led_device_add(dev, pdata->led_pdata);
		if (ret < 0)
			dev_warn(dev, "failed to register LED device\n");
	}

	return 0;
}

static int pasic3_remove(struct platform_device *pdev)
{
	struct pasic3_data *asic = platform_get_drvdata(pdev);
	struct resource *r;

	if (asic->led_pdev)
		platform_device_unregister(asic->led_pdev);
	if (asic->ds1wm_pdev)
		platform_device_unregister(asic->ds1wm_pdev);

	iounmap(asic->mapping);
	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	release_mem_region(r->start, r->end - r->start + 1);
	kfree(asic);
	return 0;
}

static struct platform_driver pasic3_driver = {
	.driver		= {
		.name	= "pasic3",
	},
	.remove		= pasic3_remove,
};

static int __init pasic3_base_init(void)
{
	return platform_driver_probe(&pasic3_driver, pasic3_probe);
}

static void __exit pasic3_base_exit(void)
{
	platform_driver_unregister(&pasic3_driver);
}

module_init(pasic3_base_init);
module_exit(pasic3_base_exit);

MODULE_AUTHOR("Philipp Zabel <philipp.zabel@gmail.com>");
MODULE_DESCRIPTION("Core driver for HTC PASIC3");
MODULE_LICENSE("GPL");
