/*
 * Copyright 2009 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, sublicense,
 * 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 above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * 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 NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
 *
 * Authors: Ben Skeggs
 */
#include "aux.h"
#include "pad.h"

static int
nvkm_i2c_aux_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
{
	struct nvkm_i2c_aux *aux = container_of(adap, typeof(*aux), i2c);
	struct i2c_msg *msg = msgs;
	int ret, mcnt = num;

	ret = nvkm_i2c_aux_acquire(aux);
	if (ret)
		return ret;

	while (mcnt--) {
		u8 remaining = msg->len;
		u8 *ptr = msg->buf;

		while (remaining) {
			u8 cnt = (remaining > 16) ? 16 : remaining;
			u8 cmd;

			if (msg->flags & I2C_M_RD)
				cmd = 1;
			else
				cmd = 0;

			if (mcnt || remaining > 16)
				cmd |= 4; /* MOT */

			ret = aux->func->xfer(aux, true, cmd, msg->addr, ptr, &cnt);
			if (ret < 0) {
				nvkm_i2c_aux_release(aux);
				return ret;
			}

			ptr += cnt;
			remaining -= cnt;
		}

		msg++;
	}

	nvkm_i2c_aux_release(aux);
	return num;
}

static u32
nvkm_i2c_aux_i2c_func(struct i2c_adapter *adap)
{
	return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
}

static const struct i2c_algorithm
nvkm_i2c_aux_i2c_algo = {
	.master_xfer = nvkm_i2c_aux_i2c_xfer,
	.functionality = nvkm_i2c_aux_i2c_func
};

void
nvkm_i2c_aux_monitor(struct nvkm_i2c_aux *aux, bool monitor)
{
	struct nvkm_i2c_pad *pad = aux->pad;
	AUX_TRACE(aux, "monitor: %s", monitor ? "yes" : "no");
	if (monitor)
		nvkm_i2c_pad_mode(pad, NVKM_I2C_PAD_AUX);
	else
		nvkm_i2c_pad_mode(pad, NVKM_I2C_PAD_OFF);
}

void
nvkm_i2c_aux_release(struct nvkm_i2c_aux *aux)
{
	struct nvkm_i2c_pad *pad = aux->pad;
	AUX_TRACE(aux, "release");
	nvkm_i2c_pad_release(pad);
	mutex_unlock(&aux->mutex);
}

int
nvkm_i2c_aux_acquire(struct nvkm_i2c_aux *aux)
{
	struct nvkm_i2c_pad *pad = aux->pad;
	int ret;
	AUX_TRACE(aux, "acquire");
	mutex_lock(&aux->mutex);
	ret = nvkm_i2c_pad_acquire(pad, NVKM_I2C_PAD_AUX);
	if (ret)
		mutex_unlock(&aux->mutex);
	return ret;
}

int
nvkm_i2c_aux_xfer(struct nvkm_i2c_aux *aux, bool retry, u8 type,
		  u32 addr, u8 *data, u8 *size)
{
	if (!*size && !aux->func->address_only) {
		AUX_ERR(aux, "address-only transaction dropped");
		return -ENOSYS;
	}
	return aux->func->xfer(aux, retry, type, addr, data, size);
}

int
nvkm_i2c_aux_lnk_ctl(struct nvkm_i2c_aux *aux, int nr, int bw, bool ef)
{
	if (aux->func->lnk_ctl)
		return aux->func->lnk_ctl(aux, nr, bw, ef);
	return -ENODEV;
}

void
nvkm_i2c_aux_del(struct nvkm_i2c_aux **paux)
{
	struct nvkm_i2c_aux *aux = *paux;
	if (aux && !WARN_ON(!aux->func)) {
		AUX_TRACE(aux, "dtor");
		list_del(&aux->head);
		i2c_del_adapter(&aux->i2c);
		kfree(*paux);
		*paux = NULL;
	}
}

int
nvkm_i2c_aux_ctor(const struct nvkm_i2c_aux_func *func,
		  struct nvkm_i2c_pad *pad, int id,
		  struct nvkm_i2c_aux *aux)
{
	struct nvkm_device *device = pad->i2c->subdev.device;

	aux->func = func;
	aux->pad = pad;
	aux->id = id;
	mutex_init(&aux->mutex);
	list_add_tail(&aux->head, &pad->i2c->aux);
	AUX_TRACE(aux, "ctor");

	snprintf(aux->i2c.name, sizeof(aux->i2c.name), "nvkm-%s-aux-%04x",
		 dev_name(device->dev), id);
	aux->i2c.owner = THIS_MODULE;
	aux->i2c.dev.parent = device->dev;
	aux->i2c.algo = &nvkm_i2c_aux_i2c_algo;
	return i2c_add_adapter(&aux->i2c);
}

int
nvkm_i2c_aux_new_(const struct nvkm_i2c_aux_func *func,
		  struct nvkm_i2c_pad *pad, int id,
		  struct nvkm_i2c_aux **paux)
{
	if (!(*paux = kzalloc(sizeof(**paux), GFP_KERNEL)))
		return -ENOMEM;
	return nvkm_i2c_aux_ctor(func, pad, id, *paux);
}
