/*
 * Copyright 2012 Red Hat Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sub license, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
 * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
 * USE OR OTHER DEALINGS IN THE SOFTWARE.
 *
 * The above copyright notice and this permission notice (including the
 * next paragraph) shall be included in all copies or substantial portions
 * of the Software.
 *
 */
/*
 * Authors: Dave Airlie <airlied@redhat.com>
 */
#include <linux/export.h>
#include <linux/i2c.h>
#include <linux/i2c-algo-bit.h>
#include <drm/drmP.h>

#include "mgag200_drv.h"

static int mga_i2c_read_gpio(struct mga_device *mdev)
{
	WREG8(DAC_INDEX, MGA1064_GEN_IO_DATA);
	return RREG8(DAC_DATA);
}

static void mga_i2c_set_gpio(struct mga_device *mdev, int mask, int val)
{
	int tmp;

	WREG8(DAC_INDEX, MGA1064_GEN_IO_CTL);
	tmp = (RREG8(DAC_DATA) & mask) | val;
	WREG_DAC(MGA1064_GEN_IO_CTL, tmp);
	WREG_DAC(MGA1064_GEN_IO_DATA, 0);
}

static inline void mga_i2c_set(struct mga_device *mdev, int mask, int state)
{
	if (state)
		state = 0;
	else
		state = mask;
	mga_i2c_set_gpio(mdev, ~mask, state);
}

static void mga_gpio_setsda(void *data, int state)
{
	struct mga_i2c_chan *i2c = data;
	struct mga_device *mdev = i2c->dev->dev_private;
	mga_i2c_set(mdev, i2c->data, state);
}

static void mga_gpio_setscl(void *data, int state)
{
	struct mga_i2c_chan *i2c = data;
	struct mga_device *mdev = i2c->dev->dev_private;
	mga_i2c_set(mdev, i2c->clock, state);
}

static int mga_gpio_getsda(void *data)
{
	struct mga_i2c_chan *i2c = data;
	struct mga_device *mdev = i2c->dev->dev_private;
	return (mga_i2c_read_gpio(mdev) & i2c->data) ? 1 : 0;
}

static int mga_gpio_getscl(void *data)
{
	struct mga_i2c_chan *i2c = data;
	struct mga_device *mdev = i2c->dev->dev_private;
	return (mga_i2c_read_gpio(mdev) & i2c->clock) ? 1 : 0;
}

struct mga_i2c_chan *mgag200_i2c_create(struct drm_device *dev)
{
	struct mga_device *mdev = dev->dev_private;
	struct mga_i2c_chan *i2c;
	int ret;
	int data, clock;

	WREG_DAC(MGA1064_GEN_IO_CTL2, 1);
	WREG_DAC(MGA1064_GEN_IO_DATA, 0xff);
	WREG_DAC(MGA1064_GEN_IO_CTL, 0);

	switch (mdev->type) {
	case G200_SE_A:
	case G200_SE_B:
	case G200_EV:
	case G200_WB:
		data = 1;
		clock = 2;
		break;
	case G200_EH:
	case G200_ER:
		data = 2;
		clock = 1;
		break;
	default:
		data = 2;
		clock = 8;
		break;
	}

	i2c = kzalloc(sizeof(struct mga_i2c_chan), GFP_KERNEL);
	if (!i2c)
		return NULL;

	i2c->data = data;
	i2c->clock = clock;
	i2c->adapter.owner = THIS_MODULE;
	i2c->adapter.class = I2C_CLASS_DDC;
	i2c->adapter.dev.parent = &dev->pdev->dev;
	i2c->dev = dev;
	i2c_set_adapdata(&i2c->adapter, i2c);
	snprintf(i2c->adapter.name, sizeof(i2c->adapter.name), "mga i2c");

	i2c->adapter.algo_data = &i2c->bit;

	i2c->bit.udelay = 10;
	i2c->bit.timeout = 2;
	i2c->bit.data = i2c;
	i2c->bit.setsda		= mga_gpio_setsda;
	i2c->bit.setscl		= mga_gpio_setscl;
	i2c->bit.getsda		= mga_gpio_getsda;
	i2c->bit.getscl		= mga_gpio_getscl;

	ret = i2c_bit_add_bus(&i2c->adapter);
	if (ret) {
		kfree(i2c);
		i2c = NULL;
	}
	return i2c;
}

void mgag200_i2c_destroy(struct mga_i2c_chan *i2c)
{
	if (!i2c)
		return;
	i2c_del_adapter(&i2c->adapter);
	kfree(i2c);
}

