/*
 * Copyright (C) 2009 ST-Ericsson
 *
 * Author: Srinidhi KASAGAR <srinidhi.kasagar@stericsson.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.
 *
 * AB4500 is a companion power management chip used with U8500.
 * On this platform, this is interfaced with SSP0 controller
 * which is a ARM primecell pl022.
 *
 * At the moment the module just exports read/write features.
 * Interrupt management to be added - TODO.
 */
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/spi/spi.h>
#include <linux/mfd/ab4500.h>

/* just required if probe fails, we need to
 * unregister the device
 */
static struct spi_driver ab4500_driver;

/*
 * This funtion writes to any AB4500 registers using
 * SPI protocol &  before it writes it packs the data
 * in the below 24 bit frame format
 *
 *	 *|------------------------------------|
 *	 *| 23|22...18|17.......10|9|8|7......0|
 *	 *| r/w  bank       adr          data  |
 *	 * ------------------------------------
 *
 * This function shouldn't be called from interrupt
 * context
 */
int ab4500_write(struct ab4500 *ab4500, unsigned char block,
		unsigned long addr, unsigned char data)
{
	struct spi_transfer xfer;
	struct spi_message	msg;
	int err;
	unsigned long spi_data =
		block << 18 | addr << 10 | data;

	mutex_lock(&ab4500->lock);
	ab4500->tx_buf[0] = spi_data;
	ab4500->rx_buf[0] = 0;

	xfer.tx_buf	= ab4500->tx_buf;
	xfer.rx_buf 	= NULL;
	xfer.len	= sizeof(unsigned long);

	spi_message_init(&msg);
	spi_message_add_tail(&xfer, &msg);

	err = spi_sync(ab4500->spi, &msg);
	mutex_unlock(&ab4500->lock);

	return err;
}
EXPORT_SYMBOL(ab4500_write);

int ab4500_read(struct ab4500 *ab4500, unsigned char block,
		unsigned long addr)
{
	struct spi_transfer xfer;
	struct spi_message	msg;
	unsigned long spi_data =
		1 << 23 | block << 18 | addr << 10;

	mutex_lock(&ab4500->lock);
	ab4500->tx_buf[0] = spi_data;
	ab4500->rx_buf[0] = 0;

	xfer.tx_buf	= ab4500->tx_buf;
	xfer.rx_buf 	= ab4500->rx_buf;
	xfer.len	= sizeof(unsigned long);

	spi_message_init(&msg);
	spi_message_add_tail(&xfer, &msg);

	spi_sync(ab4500->spi, &msg);
	mutex_unlock(&ab4500->lock);

	return  ab4500->rx_buf[0];
}
EXPORT_SYMBOL(ab4500_read);

/* ref: ab3100 core */
#define AB4500_DEVICE(devname, devid)				\
static struct platform_device ab4500_##devname##_device = {	\
	.name	= devid,					\
	.id	= -1,						\
}

/* list of childern devices of ab4500 - all are
 * not populated here - TODO
 */
AB4500_DEVICE(charger, "ab4500-charger");
AB4500_DEVICE(audio, "ab4500-audio");
AB4500_DEVICE(usb, "ab4500-usb");
AB4500_DEVICE(tvout, "ab4500-tvout");
AB4500_DEVICE(sim, "ab4500-sim");
AB4500_DEVICE(gpadc, "ab4500-gpadc");
AB4500_DEVICE(clkmgt, "ab4500-clkmgt");
AB4500_DEVICE(misc, "ab4500-misc");

static struct platform_device *ab4500_platform_devs[] = {
	&ab4500_charger_device,
	&ab4500_audio_device,
	&ab4500_usb_device,
	&ab4500_tvout_device,
	&ab4500_sim_device,
	&ab4500_gpadc_device,
	&ab4500_clkmgt_device,
	&ab4500_misc_device,
};

static int __init ab4500_probe(struct spi_device *spi)
{
	struct ab4500	*ab4500;
	unsigned char revision;
	int err = 0;
	int i;

	ab4500 = kzalloc(sizeof *ab4500, GFP_KERNEL);
	if (!ab4500) {
		dev_err(&spi->dev, "could not allocate AB4500\n");
		err = -ENOMEM;
		goto not_detect;
	}

	ab4500->spi = spi;
	spi_set_drvdata(spi, ab4500);

	mutex_init(&ab4500->lock);

	/* read the revision register */
	revision = ab4500_read(ab4500, AB4500_MISC, AB4500_REV_REG);

	/* revision id 0x0 is for early drop, 0x10 is for cut1.0 */
	if (revision == 0x0 || revision == 0x10)
		dev_info(&spi->dev, "Detected chip: %s, revision = %x\n",
			ab4500_driver.driver.name, revision);
	else	{
		dev_err(&spi->dev, "unknown chip: 0x%x\n", revision);
		goto not_detect;
	}

	for (i = 0; i < ARRAY_SIZE(ab4500_platform_devs); i++)	{
		ab4500_platform_devs[i]->dev.parent =
			&spi->dev;
		platform_set_drvdata(ab4500_platform_devs[i], ab4500);
	}

	/* register the ab4500 platform devices */
	platform_add_devices(ab4500_platform_devs,
			ARRAY_SIZE(ab4500_platform_devs));

	return err;

 not_detect:
	spi_unregister_driver(&ab4500_driver);
	kfree(ab4500);
	return err;
}

static int __devexit ab4500_remove(struct spi_device *spi)
{
	struct ab4500 *ab4500 =
		spi_get_drvdata(spi);

	kfree(ab4500);

	return 0;
}

static struct spi_driver ab4500_driver = {
	.driver = {
		.name = "ab4500",
		.owner = THIS_MODULE,
	},
	.probe = ab4500_probe,
	.remove = __devexit_p(ab4500_remove)
};

static int __devinit ab4500_init(void)
{
	return spi_register_driver(&ab4500_driver);
}

static void __exit ab4500_exit(void)
{
	spi_unregister_driver(&ab4500_driver);
}

subsys_initcall(ab4500_init);
module_exit(ab4500_exit);

MODULE_AUTHOR("Srinidhi KASAGAR <srinidhi.kasagar@stericsson.com");
MODULE_DESCRIPTION("AB4500 core driver");
MODULE_LICENSE("GPL");
