/*
 * Copyright 2011 Analog Devices Inc.
 *
 * Licensed under the GPL-2.
 *
 */

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/delay.h>

#include <asm/gptimers.h>
#include <asm/portmux.h>

#include <linux/iio/iio.h>
#include <linux/iio/trigger.h>

#include "iio-trig-bfin-timer.h"

struct bfin_timer {
	unsigned short id, bit;
	unsigned long irqbit;
	int irq;
	int pin;
};

/*
 * this covers all hardware timer configurations on
 * all Blackfin derivatives out there today
 */

static struct bfin_timer iio_bfin_timer_code[MAX_BLACKFIN_GPTIMERS] = {
	{TIMER0_id,  TIMER0bit,  TIMER_STATUS_TIMIL0,  IRQ_TIMER0, P_TMR0},
	{TIMER1_id,  TIMER1bit,  TIMER_STATUS_TIMIL1,  IRQ_TIMER1, P_TMR1},
	{TIMER2_id,  TIMER2bit,  TIMER_STATUS_TIMIL2,  IRQ_TIMER2, P_TMR2},
#if (MAX_BLACKFIN_GPTIMERS > 3)
	{TIMER3_id,  TIMER3bit,  TIMER_STATUS_TIMIL3,  IRQ_TIMER3, P_TMR3},
	{TIMER4_id,  TIMER4bit,  TIMER_STATUS_TIMIL4,  IRQ_TIMER4, P_TMR4},
	{TIMER5_id,  TIMER5bit,  TIMER_STATUS_TIMIL5,  IRQ_TIMER5, P_TMR5},
	{TIMER6_id,  TIMER6bit,  TIMER_STATUS_TIMIL6,  IRQ_TIMER6, P_TMR6},
	{TIMER7_id,  TIMER7bit,  TIMER_STATUS_TIMIL7,  IRQ_TIMER7, P_TMR7},
#endif
#if (MAX_BLACKFIN_GPTIMERS > 8)
	{TIMER8_id,  TIMER8bit,  TIMER_STATUS_TIMIL8,  IRQ_TIMER8, P_TMR8},
	{TIMER9_id,  TIMER9bit,  TIMER_STATUS_TIMIL9,  IRQ_TIMER9, P_TMR9},
	{TIMER10_id, TIMER10bit, TIMER_STATUS_TIMIL10, IRQ_TIMER10, P_TMR10},
#if (MAX_BLACKFIN_GPTIMERS > 11)
	{TIMER11_id, TIMER11bit, TIMER_STATUS_TIMIL11, IRQ_TIMER11, P_TMR11},
#endif
#endif
};

struct bfin_tmr_state {
	struct iio_trigger *trig;
	struct bfin_timer *t;
	unsigned timer_num;
	bool output_enable;
	unsigned int duty;
	int irq;
};

static int iio_bfin_tmr_set_state(struct iio_trigger *trig, bool state)
{
	struct bfin_tmr_state *st = iio_trigger_get_drvdata(trig);

	if (get_gptimer_period(st->t->id) == 0)
		return -EINVAL;

	if (state)
		enable_gptimers(st->t->bit);
	else
		disable_gptimers(st->t->bit);

	return 0;
}

static ssize_t iio_bfin_tmr_frequency_store(struct device *dev,
					    struct device_attribute *attr,
					    const char *buf, size_t count)
{
	struct iio_trigger *trig = to_iio_trigger(dev);
	struct bfin_tmr_state *st = iio_trigger_get_drvdata(trig);
	unsigned int val;
	bool enabled;
	int ret;

	ret = kstrtouint(buf, 10, &val);
	if (ret)
		return ret;

	if (val > 100000)
		return -EINVAL;

	enabled = get_enabled_gptimers() & st->t->bit;

	if (enabled)
		disable_gptimers(st->t->bit);

	if (!val)
		return count;

	val = get_sclk() / val;
	if (val <= 4 || val <= st->duty)
		return -EINVAL;

	set_gptimer_period(st->t->id, val);
	set_gptimer_pwidth(st->t->id, val - st->duty);

	if (enabled)
		enable_gptimers(st->t->bit);

	return count;
}

static ssize_t iio_bfin_tmr_frequency_show(struct device *dev,
					   struct device_attribute *attr,
					   char *buf)
{
	struct iio_trigger *trig = to_iio_trigger(dev);
	struct bfin_tmr_state *st = iio_trigger_get_drvdata(trig);
	unsigned int period = get_gptimer_period(st->t->id);
	unsigned long val;

	if (!period)
		val = 0;
	else
		val = get_sclk() / get_gptimer_period(st->t->id);

	return sprintf(buf, "%lu\n", val);
}

static DEVICE_ATTR(frequency, S_IRUGO | S_IWUSR, iio_bfin_tmr_frequency_show,
		   iio_bfin_tmr_frequency_store);

static struct attribute *iio_bfin_tmr_trigger_attrs[] = {
	&dev_attr_frequency.attr,
	NULL,
};

static const struct attribute_group iio_bfin_tmr_trigger_attr_group = {
	.attrs = iio_bfin_tmr_trigger_attrs,
};

static const struct attribute_group *iio_bfin_tmr_trigger_attr_groups[] = {
	&iio_bfin_tmr_trigger_attr_group,
	NULL
};

static irqreturn_t iio_bfin_tmr_trigger_isr(int irq, void *devid)
{
	struct bfin_tmr_state *st = devid;

	clear_gptimer_intr(st->t->id);
	iio_trigger_poll(st->trig);

	return IRQ_HANDLED;
}

static int iio_bfin_tmr_get_number(int irq)
{
	int i;

	for (i = 0; i < MAX_BLACKFIN_GPTIMERS; i++)
		if (iio_bfin_timer_code[i].irq == irq)
			return i;

	return -ENODEV;
}

static const struct iio_trigger_ops iio_bfin_tmr_trigger_ops = {
	.owner = THIS_MODULE,
	.set_trigger_state = iio_bfin_tmr_set_state,
};

static int iio_bfin_tmr_trigger_probe(struct platform_device *pdev)
{
	struct iio_bfin_timer_trigger_pdata *pdata = pdev->dev.platform_data;
	struct bfin_tmr_state *st;
	unsigned int config;
	int ret;

	st = devm_kzalloc(&pdev->dev, sizeof(*st), GFP_KERNEL);
	if (!st)
		return -ENOMEM;

	st->irq = platform_get_irq(pdev, 0);
	if (!st->irq) {
		dev_err(&pdev->dev, "No IRQs specified");
		return -ENODEV;
	}

	ret = iio_bfin_tmr_get_number(st->irq);
	if (ret < 0)
		return ret;

	st->timer_num = ret;
	st->t = &iio_bfin_timer_code[st->timer_num];

	st->trig = iio_trigger_alloc("bfintmr%d", st->timer_num);
	if (!st->trig)
		return -ENOMEM;

	st->trig->ops = &iio_bfin_tmr_trigger_ops;
	st->trig->dev.groups = iio_bfin_tmr_trigger_attr_groups;
	iio_trigger_set_drvdata(st->trig, st);
	ret = iio_trigger_register(st->trig);
	if (ret)
		goto out;

	ret = request_irq(st->irq, iio_bfin_tmr_trigger_isr,
			  0, st->trig->name, st);
	if (ret) {
		dev_err(&pdev->dev,
			"request IRQ-%d failed", st->irq);
		goto out1;
	}

	config = PWM_OUT | PERIOD_CNT | IRQ_ENA;

	if (pdata && pdata->output_enable) {
		unsigned long long val;

		st->output_enable = true;

		ret = peripheral_request(st->t->pin, st->trig->name);
		if (ret)
			goto out_free_irq;

		val = (unsigned long long)get_sclk() * pdata->duty_ns;
		do_div(val, NSEC_PER_SEC);
		st->duty = val;

		/**
		 * The interrupt will be generated at the end of the period,
		 * since we want the interrupt to be generated at end of the
		 * pulse we invert both polarity and duty cycle, so that the
		 * pulse will be generated directly before the interrupt.
		 */
		if (pdata->active_low)
			config |= PULSE_HI;
	} else {
		st->duty = 1;
		config |= OUT_DIS;
	}

	set_gptimer_config(st->t->id, config);

	dev_info(&pdev->dev, "iio trigger Blackfin TMR%d, IRQ-%d",
		 st->timer_num, st->irq);
	platform_set_drvdata(pdev, st);

	return 0;
out_free_irq:
	free_irq(st->irq, st);
out1:
	iio_trigger_unregister(st->trig);
out:
	iio_trigger_put(st->trig);
	return ret;
}

static int iio_bfin_tmr_trigger_remove(struct platform_device *pdev)
{
	struct bfin_tmr_state *st = platform_get_drvdata(pdev);

	disable_gptimers(st->t->bit);
	if (st->output_enable)
		peripheral_free(st->t->pin);
	free_irq(st->irq, st);
	iio_trigger_unregister(st->trig);
	iio_trigger_put(st->trig);

	return 0;
}

static struct platform_driver iio_bfin_tmr_trigger_driver = {
	.driver = {
		.name = "iio_bfin_tmr_trigger",
	},
	.probe = iio_bfin_tmr_trigger_probe,
	.remove = iio_bfin_tmr_trigger_remove,
};

module_platform_driver(iio_bfin_tmr_trigger_driver);

MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
MODULE_DESCRIPTION("Blackfin system timer based trigger for the iio subsystem");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS("platform:iio-trig-bfin-timer");
