/*
 * 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_probe(struct i2c_client *client,
			 const struct i2c_device_id *id);
static int ams_i2c_remove(struct i2c_client *client);

static const struct i2c_device_id ams_id[] = {
	{ "MAC,accelerometer_1", 0 },
	{ }
};
MODULE_DEVICE_TABLE(i2c, ams_id);

static struct i2c_driver ams_i2c_driver = {
	.driver = {
		.name   = "ams",
	},
	.probe          = ams_i2c_probe,
	.remove         = ams_i2c_remove,
	.id_table       = ams_id,
};

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 count = 3;

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

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

		schedule_timeout_uninterruptible(HZ / 20);
	}

	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_probe(struct i2c_client *client,
			 const struct i2c_device_id *id)
{
	int vmaj, vmin;
	int result;

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

	ams_info.i2c_client = client;

	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_remove(struct i2c_client *client)
{
	if (ams_info.has_device) {
		ams_sensor_detach();

		/* 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)
{
	int result;

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

	result = i2c_add_driver(&ams_i2c_driver);

	return result;
}
