/*
 * MEN 16z188 Analog to Digial Converter
 *
 * Copyright (C) 2014 MEN Mikroelektronik GmbH (www.men.de)
 * Author: Johannes Thumshirn <johannes.thumshirn@men.de>
 *
 * 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; version 2 of the License.
 */

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/mcb.h>
#include <linux/io.h>
#include <linux/iio/iio.h>

#define Z188_ADC_MAX_CHAN	8
#define Z188_ADC_GAIN		0x0700000
#define Z188_MODE_VOLTAGE	BIT(27)
#define Z188_CFG_AUTO		0x1
#define Z188_CTRL_REG		0x40

#define ADC_DATA(x) (((x) >> 2) & 0x7ffffc)
#define ADC_OVR(x) ((x) & 0x1)

struct z188_adc {
	struct resource *mem;
	void __iomem *base;
};

#define Z188_ADC_CHANNEL(idx) {					\
		.type = IIO_VOLTAGE,				\
		.indexed = 1,					\
		.channel = (idx),				\
		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),   \
}

static const struct iio_chan_spec z188_adc_iio_channels[] = {
	Z188_ADC_CHANNEL(0),
	Z188_ADC_CHANNEL(1),
	Z188_ADC_CHANNEL(2),
	Z188_ADC_CHANNEL(3),
	Z188_ADC_CHANNEL(4),
	Z188_ADC_CHANNEL(5),
	Z188_ADC_CHANNEL(6),
	Z188_ADC_CHANNEL(7),
};

static int z188_iio_read_raw(struct iio_dev *iio_dev,
			struct iio_chan_spec const *chan,
			int *val,
			int *val2,
			long info)
{
	struct z188_adc *adc = iio_priv(iio_dev);
	int ret;
	u16 tmp;

	switch (info) {
	case IIO_CHAN_INFO_RAW:
		tmp = readw(adc->base + chan->channel * 4);

		if (ADC_OVR(tmp)) {
			dev_info(&iio_dev->dev,
				"Oversampling error on ADC channel %d\n",
				chan->channel);
			return -EIO;
		}
		*val = ADC_DATA(tmp);
		ret = IIO_VAL_INT;
		break;
	default:
		ret = -EINVAL;
		break;
	}

	return ret;
}

static const struct iio_info z188_adc_info = {
	.read_raw = &z188_iio_read_raw,
	.driver_module = THIS_MODULE,
};

static void men_z188_config_channels(void __iomem *addr)
{
	int i;
	u32 cfg;
	u32 ctl;

	ctl = readl(addr + Z188_CTRL_REG);
	ctl |= Z188_CFG_AUTO;
	writel(ctl, addr + Z188_CTRL_REG);

	for (i = 0; i < Z188_ADC_MAX_CHAN; i++) {
		cfg = readl(addr + i);
		cfg &= ~Z188_ADC_GAIN;
		cfg |= Z188_MODE_VOLTAGE;
		writel(cfg, addr + i);
	}
}

static int men_z188_probe(struct mcb_device *dev,
			const struct mcb_device_id *id)
{
	struct z188_adc *adc;
	struct iio_dev *indio_dev;
	struct resource *mem;
	int ret;

	indio_dev = devm_iio_device_alloc(&dev->dev, sizeof(struct z188_adc));
	if (!indio_dev)
		return -ENOMEM;

	adc = iio_priv(indio_dev);
	indio_dev->name = "z188-adc";
	indio_dev->dev.parent = &dev->dev;
	indio_dev->info = &z188_adc_info;
	indio_dev->modes = INDIO_DIRECT_MODE;
	indio_dev->channels = z188_adc_iio_channels;
	indio_dev->num_channels = ARRAY_SIZE(z188_adc_iio_channels);

	mem = mcb_request_mem(dev, "z188-adc");
	if (IS_ERR(mem))
		return PTR_ERR(mem);

	adc->base = ioremap(mem->start, resource_size(mem));
	if (adc->base == NULL)
		goto err;

	men_z188_config_channels(adc->base);

	adc->mem = mem;
	mcb_set_drvdata(dev, indio_dev);

	ret = iio_device_register(indio_dev);
	if (ret)
		goto err_unmap;

	return 0;

err_unmap:
	iounmap(adc->base);
err:
	mcb_release_mem(mem);
	return -ENXIO;
}

static void men_z188_remove(struct mcb_device *dev)
{
	struct iio_dev *indio_dev  = mcb_get_drvdata(dev);
	struct z188_adc *adc = iio_priv(indio_dev);

	iio_device_unregister(indio_dev);
	iounmap(adc->base);
	mcb_release_mem(adc->mem);
}

static const struct mcb_device_id men_z188_ids[] = {
	{ .device = 0xbc },
	{ }
};
MODULE_DEVICE_TABLE(mcb, men_z188_ids);

static struct mcb_driver men_z188_driver = {
	.driver = {
		.name = "z188-adc",
		.owner = THIS_MODULE,
	},
	.probe = men_z188_probe,
	.remove = men_z188_remove,
	.id_table = men_z188_ids,
};
module_mcb_driver(men_z188_driver);

MODULE_AUTHOR("Johannes Thumshirn <johannes.thumshirn@men.de>");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("IIO ADC driver for MEN 16z188 ADC Core");
MODULE_ALIAS("mcb:16z188");
