/*
 * Apple Motion Sensor driver (I2C variant)
 *
 * Copyright (C) 2005 Stelian Pop (stelian@popies.net)
 * Copyright (C) 2006 Michael Hanselmann (linux-kernel@hansmi.ch)
 *
 * Clean room implementation based on the reverse engineered Mac OS X driver by
 * Johannes Berg <johannes@sipsolutions.net>, documentation available at
 * http://johannes.sipsolutions.net/PowerBook/Apple_Motion_Sensor_Specification
 *
 * 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.
 */

#include <linux/module.h>
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/delay.h>

#include "ams.h"

/* AMS registers */
#define AMS_COMMAND	0x00	/* command register */
#define AMS_STATUS	0x01	/* status register */
#define AMS_CTRL1	0x02	/* read control 1 (number of values) */
#define AMS_CTRL2	0x03	/* read control 2 (offset?) */
#define AMS_CTRL3	0x04	/* read control 3 (size of each value?) */
#define AMS_DATA1	0x05	/* read data 1 */
#define AMS_DATA2	0x06	/* read data 2 */
#define AMS_DATA3	0x07	/* read data 3 */
#define AMS_DATA4	0x08	/* read data 4 */
#define AMS_DATAX	0x20	/* data X */
#define AMS_DATAY	0x21	/* data Y */
#define AMS_DATAZ	0x22	/* data Z */
#define AMS_FREEFALL	0x24	/* freefall int control */
#define AMS_SHOCK	0x25	/* shock int control */
#define AMS_SENSLOW	0x26	/* sensitivity low limit */
#define AMS_SENSHIGH	0x27	/* sensitivity high limit */
#define AMS_CTRLX	0x28	/* control X */
#define AMS_CTRLY	0x29	/* control Y */
#define AMS_CTRLZ	0x2A	/* control Z */
#define AMS_UNKNOWN1	0x2B	/* unknown 1 */
#define AMS_UNKNOWN2	0x2C	/* unknown 2 */
#define AMS_UNKNOWN3	0x2D	/* unknown 3 */
#define AMS_VENDOR	0x2E	/* vendor */

/* AMS commands - use with the AMS_COMMAND register */
enum ams_i2c_cmd {
	AMS_CMD_NOOP = 0,
	AMS_CMD_VERSION,
	AMS_CMD_READMEM,
	AMS_CMD_WRITEMEM,
	AMS_CMD_ERASEMEM,
	AMS_CMD_READEE,
	AMS_CMD_WRITEEE,
	AMS_CMD_RESET,
	AMS_CMD_START,
};

static int ams_i2c_attach(struct i2c_adapter *adapter);
static int ams_i2c_detach(struct i2c_adapter *adapter);

static struct i2c_driver ams_i2c_driver = {
	.driver = {
		.name   = "ams",
		.owner  = THIS_MODULE,
	},
	.attach_adapter = ams_i2c_attach,
	.detach_adapter = ams_i2c_detach,
};

static s32 ams_i2c_read(u8 reg)
{
	return i2c_smbus_read_byte_data(&ams_info.i2c_client, reg);
}

static int ams_i2c_write(u8 reg, u8 value)
{
	return i2c_smbus_write_byte_data(&ams_info.i2c_client, reg, value);
}

static int ams_i2c_cmd(enum ams_i2c_cmd cmd)
{
	s32 result;
	int remaining = HZ / 20;

	ams_i2c_write(AMS_COMMAND, cmd);
	mdelay(5);

	while (remaining) {
		result = ams_i2c_read(AMS_COMMAND);
		if (result == 0 || result & 0x80)
			return 0;

		remaining = schedule_timeout(remaining);
	}

	return -1;
}

static void ams_i2c_set_irq(enum ams_irq reg, char enable)
{
	if (reg & AMS_IRQ_FREEFALL) {
		u8 val = ams_i2c_read(AMS_CTRLX);
		if (enable)
			val |= 0x80;
		else
			val &= ~0x80;
		ams_i2c_write(AMS_CTRLX, val);
	}

	if (reg & AMS_IRQ_SHOCK) {
		u8 val = ams_i2c_read(AMS_CTRLY);
		if (enable)
			val |= 0x80;
		else
			val &= ~0x80;
		ams_i2c_write(AMS_CTRLY, val);
	}

	if (reg & AMS_IRQ_GLOBAL) {
		u8 val = ams_i2c_read(AMS_CTRLZ);
		if (enable)
			val |= 0x80;
		else
			val &= ~0x80;
		ams_i2c_write(AMS_CTRLZ, val);
	}
}

static void ams_i2c_clear_irq(enum ams_irq reg)
{
	if (reg & AMS_IRQ_FREEFALL)
		ams_i2c_write(AMS_FREEFALL, 0);

	if (reg & AMS_IRQ_SHOCK)
		ams_i2c_write(AMS_SHOCK, 0);
}

static u8 ams_i2c_get_vendor(void)
{
	return ams_i2c_read(AMS_VENDOR);
}

static void ams_i2c_get_xyz(s8 *x, s8 *y, s8 *z)
{
	*x = ams_i2c_read(AMS_DATAX);
	*y = ams_i2c_read(AMS_DATAY);
	*z = ams_i2c_read(AMS_DATAZ);
}

static int ams_i2c_attach(struct i2c_adapter *adapter)
{
	unsigned long bus;
	int vmaj, vmin;
	int result;

	/* There can be only one */
	if (unlikely(ams_info.has_device))
		return -ENODEV;

	if (strncmp(adapter->name, "uni-n", 5))
		return -ENODEV;

	bus = simple_strtoul(adapter->name + 6, NULL, 10);
	if (bus != ams_info.i2c_bus)
		return -ENODEV;

	ams_info.i2c_client.addr = ams_info.i2c_address;
	ams_info.i2c_client.adapter = adapter;
	ams_info.i2c_client.driver = &ams_i2c_driver;
	strcpy(ams_info.i2c_client.name, "Apple Motion Sensor");

	if (ams_i2c_cmd(AMS_CMD_RESET)) {
		printk(KERN_INFO "ams: Failed to reset the device\n");
		return -ENODEV;
	}

	if (ams_i2c_cmd(AMS_CMD_START)) {
		printk(KERN_INFO "ams: Failed to start the device\n");
		return -ENODEV;
	}

	/* get version/vendor information */
	ams_i2c_write(AMS_CTRL1, 0x02);
	ams_i2c_write(AMS_CTRL2, 0x85);
	ams_i2c_write(AMS_CTRL3, 0x01);

	ams_i2c_cmd(AMS_CMD_READMEM);

	vmaj = ams_i2c_read(AMS_DATA1);
	vmin = ams_i2c_read(AMS_DATA2);
	if (vmaj != 1 || vmin != 52) {
		printk(KERN_INFO "ams: Incorrect device version (%d.%d)\n",
			vmaj, vmin);
		return -ENODEV;
	}

	ams_i2c_cmd(AMS_CMD_VERSION);

	vmaj = ams_i2c_read(AMS_DATA1);
	vmin = ams_i2c_read(AMS_DATA2);
	if (vmaj != 0 || vmin != 1) {
		printk(KERN_INFO "ams: Incorrect firmware version (%d.%d)\n",
			vmaj, vmin);
		return -ENODEV;
	}

	/* Disable interrupts */
	ams_i2c_set_irq(AMS_IRQ_ALL, 0);

	result = ams_sensor_attach();
	if (result < 0)
		return result;

	/* Set default values */
	ams_i2c_write(AMS_SENSLOW, 0x15);
	ams_i2c_write(AMS_SENSHIGH, 0x60);
	ams_i2c_write(AMS_CTRLX, 0x08);
	ams_i2c_write(AMS_CTRLY, 0x0F);
	ams_i2c_write(AMS_CTRLZ, 0x4F);
	ams_i2c_write(AMS_UNKNOWN1, 0x14);

	/* Clear interrupts */
	ams_i2c_clear_irq(AMS_IRQ_ALL);

	ams_info.has_device = 1;

	/* Enable interrupts */
	ams_i2c_set_irq(AMS_IRQ_ALL, 1);

	printk(KERN_INFO "ams: Found I2C based motion sensor\n");

	return 0;
}

static int ams_i2c_detach(struct i2c_adapter *adapter)
{
	if (ams_info.has_device) {
		/* Disable interrupts */
		ams_i2c_set_irq(AMS_IRQ_ALL, 0);

		/* Clear interrupts */
		ams_i2c_clear_irq(AMS_IRQ_ALL);

		printk(KERN_INFO "ams: Unloading\n");

		ams_info.has_device = 0;
	}

	return 0;
}

static void ams_i2c_exit(void)
{
	i2c_del_driver(&ams_i2c_driver);
}

int __init ams_i2c_init(struct device_node *np)
{
	char *tmp_bus;
	int result;
	const u32 *prop;

	mutex_lock(&ams_info.lock);

	/* Set implementation stuff */
	ams_info.of_node = np;
	ams_info.exit = ams_i2c_exit;
	ams_info.get_vendor = ams_i2c_get_vendor;
	ams_info.get_xyz = ams_i2c_get_xyz;
	ams_info.clear_irq = ams_i2c_clear_irq;
	ams_info.bustype = BUS_I2C;

	/* look for bus either using "reg" or by path */
	prop = get_property(ams_info.of_node, "reg", NULL);
	if (!prop) {
		result = -ENODEV;

		goto exit;
	}

	tmp_bus = strstr(ams_info.of_node->full_name, "/i2c-bus@");
	if (tmp_bus)
		ams_info.i2c_bus = *(tmp_bus + 9) - '0';
	else
		ams_info.i2c_bus = ((*prop) >> 8) & 0x0f;
	ams_info.i2c_address = ((*prop) & 0xff) >> 1;

	result = i2c_add_driver(&ams_i2c_driver);

exit:
	mutex_unlock(&ams_info.lock);

	return result;
}
