// SPDX-License-Identifier: GPL-2.0-or-later
/*
 *   Generic i2c interface for ALSA
 *
 *   (c) 1998 Gerd Knorr <kraxel@cs.tu-berlin.de>
 *   Modified for the ALSA driver by Jaroslav Kysela <perex@perex.cz>
 */

#include <linux/init.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/string.h>
#include <linux/errno.h>
#include <sound/core.h>
#include <sound/i2c.h>

MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>");
MODULE_DESCRIPTION("Generic i2c interface for ALSA");
MODULE_LICENSE("GPL");

static int snd_i2c_bit_sendbytes(struct snd_i2c_device *device,
				 unsigned char *bytes, int count);
static int snd_i2c_bit_readbytes(struct snd_i2c_device *device,
				 unsigned char *bytes, int count);
static int snd_i2c_bit_probeaddr(struct snd_i2c_bus *bus,
				 unsigned short addr);

static const struct snd_i2c_ops snd_i2c_bit_ops = {
	.sendbytes = snd_i2c_bit_sendbytes,
	.readbytes = snd_i2c_bit_readbytes,
	.probeaddr = snd_i2c_bit_probeaddr,
};

static int snd_i2c_bus_free(struct snd_i2c_bus *bus)
{
	struct snd_i2c_bus *slave;
	struct snd_i2c_device *device;

	if (snd_BUG_ON(!bus))
		return -EINVAL;
	while (!list_empty(&bus->devices)) {
		device = snd_i2c_device(bus->devices.next);
		snd_i2c_device_free(device);
	}
	if (bus->master)
		list_del(&bus->buses);
	else {
		while (!list_empty(&bus->buses)) {
			slave = snd_i2c_slave_bus(bus->buses.next);
			snd_device_free(bus->card, slave);
		}
	}
	if (bus->private_free)
		bus->private_free(bus);
	kfree(bus);
	return 0;
}

static int snd_i2c_bus_dev_free(struct snd_device *device)
{
	struct snd_i2c_bus *bus = device->device_data;
	return snd_i2c_bus_free(bus);
}

int snd_i2c_bus_create(struct snd_card *card, const char *name,
		       struct snd_i2c_bus *master, struct snd_i2c_bus **ri2c)
{
	struct snd_i2c_bus *bus;
	int err;
	static const struct snd_device_ops ops = {
		.dev_free =	snd_i2c_bus_dev_free,
	};

	*ri2c = NULL;
	bus = kzalloc_obj(*bus);
	if (bus == NULL)
		return -ENOMEM;
	mutex_init(&bus->lock_mutex);
	INIT_LIST_HEAD(&bus->devices);
	INIT_LIST_HEAD(&bus->buses);
	bus->card = card;
	bus->ops = &snd_i2c_bit_ops;
	if (master) {
		list_add_tail(&bus->buses, &master->buses);
		bus->master = master;
	}
	strscpy(bus->name, name, sizeof(bus->name));
	err = snd_device_new(card, SNDRV_DEV_BUS, bus, &ops);
	if (err < 0) {
		snd_i2c_bus_free(bus);
		return err;
	}
	*ri2c = bus;
	return 0;
}

EXPORT_SYMBOL(snd_i2c_bus_create);

int snd_i2c_device_create(struct snd_i2c_bus *bus, const char *name,
			  unsigned char addr, struct snd_i2c_device **rdevice)
{
	struct snd_i2c_device *device;

	*rdevice = NULL;
	if (snd_BUG_ON(!bus))
		return -EINVAL;
	device = kzalloc_obj(*device);
	if (device == NULL)
		return -ENOMEM;
	device->addr = addr;
	strscpy(device->name, name, sizeof(device->name));
	list_add_tail(&device->list, &bus->devices);
	device->bus = bus;
	*rdevice = device;
	return 0;
}

EXPORT_SYMBOL(snd_i2c_device_create);

int snd_i2c_device_free(struct snd_i2c_device *device)
{
	if (device->bus)
		list_del(&device->list);
	if (device->private_free)
		device->private_free(device);
	kfree(device);
	return 0;
}

EXPORT_SYMBOL(snd_i2c_device_free);

int snd_i2c_sendbytes(struct snd_i2c_device *device, unsigned char *bytes, int count)
{
	return device->bus->ops->sendbytes(device, bytes, count);
}

EXPORT_SYMBOL(snd_i2c_sendbytes);

int snd_i2c_readbytes(struct snd_i2c_device *device, unsigned char *bytes, int count)
{
	return device->bus->ops->readbytes(device, bytes, count);
}

EXPORT_SYMBOL(snd_i2c_readbytes);

int snd_i2c_probeaddr(struct snd_i2c_bus *bus, unsigned short addr)
{
	return bus->ops->probeaddr(bus, addr);
}

EXPORT_SYMBOL(snd_i2c_probeaddr);

/*
 *  bit-operations
 */

static inline void snd_i2c_bit_hw_start(struct snd_i2c_bus *bus)
{
	if (bus->hw_ops.bit->start)
		bus->hw_ops.bit->start(bus);
}

static inline void snd_i2c_bit_hw_stop(struct snd_i2c_bus *bus)
{
	if (bus->hw_ops.bit->stop)
		bus->hw_ops.bit->stop(bus);
}

static void snd_i2c_bit_direction(struct snd_i2c_bus *bus, int clock, int data)
{
	if (bus->hw_ops.bit->direction)
		bus->hw_ops.bit->direction(bus, clock, data);
}

static void snd_i2c_bit_set(struct snd_i2c_bus *bus, int clock, int data)
{
	bus->hw_ops.bit->setlines(bus, clock, data);
}

#if 0
static int snd_i2c_bit_clock(struct snd_i2c_bus *bus)
{
	if (bus->hw_ops.bit->getclock)
		return bus->hw_ops.bit->getclock(bus);
	return -ENXIO;
}
#endif

static int snd_i2c_bit_data(struct snd_i2c_bus *bus, int ack)
{
	return bus->hw_ops.bit->getdata(bus, ack);
}

static void snd_i2c_bit_start(struct snd_i2c_bus *bus)
{
	snd_i2c_bit_hw_start(bus);
	snd_i2c_bit_direction(bus, 1, 1);	/* SCL - wr, SDA - wr */
	snd_i2c_bit_set(bus, 1, 1);
	snd_i2c_bit_set(bus, 1, 0);
	snd_i2c_bit_set(bus, 0, 0);
}

static void snd_i2c_bit_stop(struct snd_i2c_bus *bus)
{
	snd_i2c_bit_set(bus, 0, 0);
	snd_i2c_bit_set(bus, 1, 0);
	snd_i2c_bit_set(bus, 1, 1);
	snd_i2c_bit_hw_stop(bus);
}

static void snd_i2c_bit_send(struct snd_i2c_bus *bus, int data)
{
	snd_i2c_bit_set(bus, 0, data);
	snd_i2c_bit_set(bus, 1, data);
	snd_i2c_bit_set(bus, 0, data);
}

static int snd_i2c_bit_ack(struct snd_i2c_bus *bus)
{
	int ack;

	snd_i2c_bit_set(bus, 0, 1);
	snd_i2c_bit_set(bus, 1, 1);
	snd_i2c_bit_direction(bus, 1, 0);	/* SCL - wr, SDA - rd */
	ack = snd_i2c_bit_data(bus, 1);
	snd_i2c_bit_direction(bus, 1, 1);	/* SCL - wr, SDA - wr */
	snd_i2c_bit_set(bus, 0, 1);
	return ack ? -EIO : 0;
}

static int snd_i2c_bit_sendbyte(struct snd_i2c_bus *bus, unsigned char data)
{
	int i, err;

	for (i = 7; i >= 0; i--)
		snd_i2c_bit_send(bus, !!(data & (1 << i)));
	err = snd_i2c_bit_ack(bus);
	if (err < 0)
		return err;
	return 0;
}

static int snd_i2c_bit_readbyte(struct snd_i2c_bus *bus, int last)
{
	int i;
	unsigned char data = 0;

	snd_i2c_bit_set(bus, 0, 1);
	snd_i2c_bit_direction(bus, 1, 0);	/* SCL - wr, SDA - rd */
	for (i = 7; i >= 0; i--) {
		snd_i2c_bit_set(bus, 1, 1);
		if (snd_i2c_bit_data(bus, 0))
			data |= (1 << i);
		snd_i2c_bit_set(bus, 0, 1);
	}
	snd_i2c_bit_direction(bus, 1, 1);	/* SCL - wr, SDA - wr */
	snd_i2c_bit_send(bus, !!last);
	return data;
}

static int snd_i2c_bit_sendbytes(struct snd_i2c_device *device,
				 unsigned char *bytes, int count)
{
	struct snd_i2c_bus *bus = device->bus;
	int err, res = 0;

	if (device->flags & SND_I2C_DEVICE_ADDRTEN)
		return -EIO;		/* not yet implemented */
	snd_i2c_bit_start(bus);
	err = snd_i2c_bit_sendbyte(bus, device->addr << 1);
	if (err < 0) {
		snd_i2c_bit_hw_stop(bus);
		return err;
	}
	while (count-- > 0) {
		err = snd_i2c_bit_sendbyte(bus, *bytes++);
		if (err < 0) {
			snd_i2c_bit_hw_stop(bus);
			return err;
		}
		res++;
	}
	snd_i2c_bit_stop(bus);
	return res;
}

static int snd_i2c_bit_readbytes(struct snd_i2c_device *device,
				 unsigned char *bytes, int count)
{
	struct snd_i2c_bus *bus = device->bus;
	int err, res = 0;

	if (device->flags & SND_I2C_DEVICE_ADDRTEN)
		return -EIO;		/* not yet implemented */
	snd_i2c_bit_start(bus);
	err = snd_i2c_bit_sendbyte(bus, (device->addr << 1) | 1);
	if (err < 0) {
		snd_i2c_bit_hw_stop(bus);
		return err;
	}
	while (count-- > 0) {
		err = snd_i2c_bit_readbyte(bus, count == 0);
		if (err < 0) {
			snd_i2c_bit_hw_stop(bus);
			return err;
		}
		*bytes++ = (unsigned char)err;
		res++;
	}
	snd_i2c_bit_stop(bus);
	return res;
}

static int snd_i2c_bit_probeaddr(struct snd_i2c_bus *bus, unsigned short addr)
{
	int err;

	if (addr & 0x8000)	/* 10-bit address */
		return -EIO;	/* not yet implemented */
	if (addr & 0x7f80)	/* invalid address */
		return -EINVAL;
	snd_i2c_bit_start(bus);
	err = snd_i2c_bit_sendbyte(bus, addr << 1);
	snd_i2c_bit_stop(bus);
	return err;
}
