/*
 * Copyright (C) 2015 VanguardiaSur - www.vanguardiasur.com.ar
 *
 * Based on the audio support from the tw6869 driver:
 * Copyright 2015 www.starterkit.ru <info@starterkit.ru>
 *
 * Based on:
 * Driver for Intersil|Techwell TW6869 based DVR cards
 * (c) 2011-12 liran <jli11@intersil.com> [Intersil|Techwell China]
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of version 2 of the GNU General Public License
 * as published by the Free Software Foundation.
 */

#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/kmod.h>
#include <linux/mutex.h>
#include <linux/pci.h>
#include <linux/delay.h>

#include <sound/core.h>
#include <sound/initval.h>
#include <sound/pcm.h>
#include <sound/control.h>
#include "tw686x.h"
#include "tw686x-regs.h"

#define AUDIO_CHANNEL_OFFSET 8

void tw686x_audio_irq(struct tw686x_dev *dev, unsigned long requests,
		      unsigned int pb_status)
{
	unsigned long flags;
	unsigned int ch, pb;

	for_each_set_bit(ch, &requests, max_channels(dev)) {
		struct tw686x_audio_channel *ac = &dev->audio_channels[ch];
		struct tw686x_audio_buf *done = NULL;
		struct tw686x_audio_buf *next = NULL;
		struct tw686x_dma_desc *desc;

		pb = !!(pb_status & BIT(AUDIO_CHANNEL_OFFSET + ch));

		spin_lock_irqsave(&ac->lock, flags);

		/* Sanity check */
		if (!ac->ss || !ac->curr_bufs[0] || !ac->curr_bufs[1]) {
			spin_unlock_irqrestore(&ac->lock, flags);
			continue;
		}

		if (!list_empty(&ac->buf_list)) {
			next = list_first_entry(&ac->buf_list,
					struct tw686x_audio_buf, list);
			list_move_tail(&next->list, &ac->buf_list);
			done = ac->curr_bufs[!pb];
			ac->curr_bufs[pb] = next;
		}
		spin_unlock_irqrestore(&ac->lock, flags);

		if (!done || !next)
			continue;
		/*
		 * Checking for a non-nil dma_desc[pb]->virt buffer is
		 * the same as checking for memcpy DMA mode.
		 */
		desc = &ac->dma_descs[pb];
		if (desc->virt) {
			memcpy(done->virt, desc->virt,
			       dev->period_size);
		} else {
			u32 reg = pb ? ADMA_B_ADDR[ch] : ADMA_P_ADDR[ch];
			reg_write(dev, reg, next->dma);
		}
		ac->ptr = done->dma - ac->buf[0].dma;
		snd_pcm_period_elapsed(ac->ss);
	}
}

static int tw686x_pcm_hw_params(struct snd_pcm_substream *ss,
				struct snd_pcm_hw_params *hw_params)
{
	return snd_pcm_lib_malloc_pages(ss, params_buffer_bytes(hw_params));
}

static int tw686x_pcm_hw_free(struct snd_pcm_substream *ss)
{
	return snd_pcm_lib_free_pages(ss);
}

/*
 * Audio parameters are global and shared among all
 * capture channels. The driver prevents changes to
 * the parameters if any audio channel is capturing.
 */
static const struct snd_pcm_hardware tw686x_capture_hw = {
	.info			= (SNDRV_PCM_INFO_MMAP |
				   SNDRV_PCM_INFO_INTERLEAVED |
				   SNDRV_PCM_INFO_BLOCK_TRANSFER |
				   SNDRV_PCM_INFO_MMAP_VALID),
	.formats		= SNDRV_PCM_FMTBIT_S16_LE,
	.rates			= SNDRV_PCM_RATE_8000_48000,
	.rate_min		= 8000,
	.rate_max		= 48000,
	.channels_min		= 1,
	.channels_max		= 1,
	.buffer_bytes_max	= TW686X_AUDIO_PAGE_MAX * AUDIO_DMA_SIZE_MAX,
	.period_bytes_min	= AUDIO_DMA_SIZE_MIN,
	.period_bytes_max	= AUDIO_DMA_SIZE_MAX,
	.periods_min		= TW686X_AUDIO_PERIODS_MIN,
	.periods_max		= TW686X_AUDIO_PERIODS_MAX,
};

static int tw686x_pcm_open(struct snd_pcm_substream *ss)
{
	struct tw686x_dev *dev = snd_pcm_substream_chip(ss);
	struct tw686x_audio_channel *ac = &dev->audio_channels[ss->number];
	struct snd_pcm_runtime *rt = ss->runtime;
	int err;

	ac->ss = ss;
	rt->hw = tw686x_capture_hw;

	err = snd_pcm_hw_constraint_integer(rt, SNDRV_PCM_HW_PARAM_PERIODS);
	if (err < 0)
		return err;

	return 0;
}

static int tw686x_pcm_close(struct snd_pcm_substream *ss)
{
	struct tw686x_dev *dev = snd_pcm_substream_chip(ss);
	struct tw686x_audio_channel *ac = &dev->audio_channels[ss->number];

	ac->ss = NULL;
	return 0;
}

static int tw686x_pcm_prepare(struct snd_pcm_substream *ss)
{
	struct tw686x_dev *dev = snd_pcm_substream_chip(ss);
	struct tw686x_audio_channel *ac = &dev->audio_channels[ss->number];
	struct snd_pcm_runtime *rt = ss->runtime;
	unsigned int period_size = snd_pcm_lib_period_bytes(ss);
	struct tw686x_audio_buf *p_buf, *b_buf;
	unsigned long flags;
	int i;

	spin_lock_irqsave(&dev->lock, flags);
	/*
	 * Given the audio parameters are global (i.e. shared across
	 * DMA channels), we need to check new params are allowed.
	 */
	if (((dev->audio_rate != rt->rate) ||
	     (dev->period_size != period_size)) && dev->audio_enabled)
		goto err_audio_busy;

	tw686x_disable_channel(dev, AUDIO_CHANNEL_OFFSET + ac->ch);
	spin_unlock_irqrestore(&dev->lock, flags);

	if (dev->audio_rate != rt->rate) {
		u32 reg;

		dev->audio_rate = rt->rate;
		reg = ((125000000 / rt->rate) << 16) +
		       ((125000000 % rt->rate) << 16) / rt->rate;

		reg_write(dev, AUDIO_CONTROL2, reg);
	}

	if (dev->period_size != period_size) {
		u32 reg;

		dev->period_size = period_size;
		reg = reg_read(dev, AUDIO_CONTROL1);
		reg &= ~(AUDIO_DMA_SIZE_MASK << AUDIO_DMA_SIZE_SHIFT);
		reg |= period_size << AUDIO_DMA_SIZE_SHIFT;

		reg_write(dev, AUDIO_CONTROL1, reg);
	}

	if (rt->periods < TW686X_AUDIO_PERIODS_MIN ||
	    rt->periods > TW686X_AUDIO_PERIODS_MAX)
		return -EINVAL;

	spin_lock_irqsave(&ac->lock, flags);
	INIT_LIST_HEAD(&ac->buf_list);

	for (i = 0; i < rt->periods; i++) {
		ac->buf[i].dma = rt->dma_addr + period_size * i;
		ac->buf[i].virt = rt->dma_area + period_size * i;
		INIT_LIST_HEAD(&ac->buf[i].list);
		list_add_tail(&ac->buf[i].list, &ac->buf_list);
	}

	p_buf =	list_first_entry(&ac->buf_list, struct tw686x_audio_buf, list);
	list_move_tail(&p_buf->list, &ac->buf_list);

	b_buf =	list_first_entry(&ac->buf_list, struct tw686x_audio_buf, list);
	list_move_tail(&b_buf->list, &ac->buf_list);

	ac->curr_bufs[0] = p_buf;
	ac->curr_bufs[1] = b_buf;
	ac->ptr = 0;

	if (dev->dma_mode != TW686X_DMA_MODE_MEMCPY) {
		reg_write(dev, ADMA_P_ADDR[ac->ch], p_buf->dma);
		reg_write(dev, ADMA_B_ADDR[ac->ch], b_buf->dma);
	}

	spin_unlock_irqrestore(&ac->lock, flags);

	return 0;

err_audio_busy:
	spin_unlock_irqrestore(&dev->lock, flags);
	return -EBUSY;
}

static int tw686x_pcm_trigger(struct snd_pcm_substream *ss, int cmd)
{
	struct tw686x_dev *dev = snd_pcm_substream_chip(ss);
	struct tw686x_audio_channel *ac = &dev->audio_channels[ss->number];
	unsigned long flags;
	int err = 0;

	switch (cmd) {
	case SNDRV_PCM_TRIGGER_START:
		if (ac->curr_bufs[0] && ac->curr_bufs[1]) {
			spin_lock_irqsave(&dev->lock, flags);
			dev->audio_enabled = 1;
			tw686x_enable_channel(dev,
				AUDIO_CHANNEL_OFFSET + ac->ch);
			spin_unlock_irqrestore(&dev->lock, flags);

			mod_timer(&dev->dma_delay_timer,
				  jiffies + msecs_to_jiffies(100));
		} else {
			err = -EIO;
		}
		break;
	case SNDRV_PCM_TRIGGER_STOP:
		spin_lock_irqsave(&dev->lock, flags);
		dev->audio_enabled = 0;
		tw686x_disable_channel(dev, AUDIO_CHANNEL_OFFSET + ac->ch);
		spin_unlock_irqrestore(&dev->lock, flags);

		spin_lock_irqsave(&ac->lock, flags);
		ac->curr_bufs[0] = NULL;
		ac->curr_bufs[1] = NULL;
		spin_unlock_irqrestore(&ac->lock, flags);
		break;
	default:
		err = -EINVAL;
	}
	return err;
}

static snd_pcm_uframes_t tw686x_pcm_pointer(struct snd_pcm_substream *ss)
{
	struct tw686x_dev *dev = snd_pcm_substream_chip(ss);
	struct tw686x_audio_channel *ac = &dev->audio_channels[ss->number];

	return bytes_to_frames(ss->runtime, ac->ptr);
}

static const struct snd_pcm_ops tw686x_pcm_ops = {
	.open = tw686x_pcm_open,
	.close = tw686x_pcm_close,
	.ioctl = snd_pcm_lib_ioctl,
	.hw_params = tw686x_pcm_hw_params,
	.hw_free = tw686x_pcm_hw_free,
	.prepare = tw686x_pcm_prepare,
	.trigger = tw686x_pcm_trigger,
	.pointer = tw686x_pcm_pointer,
};

static int tw686x_snd_pcm_init(struct tw686x_dev *dev)
{
	struct snd_card *card = dev->snd_card;
	struct snd_pcm *pcm;
	struct snd_pcm_substream *ss;
	unsigned int i;
	int err;

	err = snd_pcm_new(card, card->driver, 0, 0, max_channels(dev), &pcm);
	if (err < 0)
		return err;

	snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &tw686x_pcm_ops);
	snd_pcm_chip(pcm) = dev;
	pcm->info_flags = 0;
	strlcpy(pcm->name, "tw686x PCM", sizeof(pcm->name));

	for (i = 0, ss = pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream;
	     ss; ss = ss->next, i++)
		snprintf(ss->name, sizeof(ss->name), "vch%u audio", i);

	return snd_pcm_lib_preallocate_pages_for_all(pcm,
				SNDRV_DMA_TYPE_DEV,
				snd_dma_pci_data(dev->pci_dev),
				TW686X_AUDIO_PAGE_MAX * AUDIO_DMA_SIZE_MAX,
				TW686X_AUDIO_PAGE_MAX * AUDIO_DMA_SIZE_MAX);
}

static void tw686x_audio_dma_free(struct tw686x_dev *dev,
				  struct tw686x_audio_channel *ac)
{
	int pb;

	for (pb = 0; pb < 2; pb++) {
		if (!ac->dma_descs[pb].virt)
			continue;
		pci_free_consistent(dev->pci_dev, ac->dma_descs[pb].size,
				    ac->dma_descs[pb].virt,
				    ac->dma_descs[pb].phys);
		ac->dma_descs[pb].virt = NULL;
	}
}

static int tw686x_audio_dma_alloc(struct tw686x_dev *dev,
				  struct tw686x_audio_channel *ac)
{
	int pb;

	/*
	 * In the memcpy DMA mode we allocate a consistent buffer
	 * and use it for the DMA capture. Otherwise, DMA
	 * acts on the ALSA buffers as received in pcm_prepare.
	 */
	if (dev->dma_mode != TW686X_DMA_MODE_MEMCPY)
		return 0;

	for (pb = 0; pb < 2; pb++) {
		u32 reg = pb ? ADMA_B_ADDR[ac->ch] : ADMA_P_ADDR[ac->ch];
		void *virt;

		virt = pci_alloc_consistent(dev->pci_dev, AUDIO_DMA_SIZE_MAX,
					    &ac->dma_descs[pb].phys);
		if (!virt) {
			dev_err(&dev->pci_dev->dev,
				"dma%d: unable to allocate audio DMA %s-buffer\n",
				ac->ch, pb ? "B" : "P");
			return -ENOMEM;
		}
		ac->dma_descs[pb].virt = virt;
		ac->dma_descs[pb].size = AUDIO_DMA_SIZE_MAX;
		reg_write(dev, reg, ac->dma_descs[pb].phys);
	}
	return 0;
}

void tw686x_audio_free(struct tw686x_dev *dev)
{
	unsigned long flags;
	u32 dma_ch_mask;
	u32 dma_cmd;

	spin_lock_irqsave(&dev->lock, flags);
	dma_cmd = reg_read(dev, DMA_CMD);
	dma_ch_mask = reg_read(dev, DMA_CHANNEL_ENABLE);
	reg_write(dev, DMA_CMD, dma_cmd & ~0xff00);
	reg_write(dev, DMA_CHANNEL_ENABLE, dma_ch_mask & ~0xff00);
	spin_unlock_irqrestore(&dev->lock, flags);

	if (!dev->snd_card)
		return;
	snd_card_free(dev->snd_card);
	dev->snd_card = NULL;
}

int tw686x_audio_init(struct tw686x_dev *dev)
{
	struct pci_dev *pci_dev = dev->pci_dev;
	struct snd_card *card;
	int err, ch;

	/* Enable external audio */
	reg_write(dev, AUDIO_CONTROL1, BIT(0));

	err = snd_card_new(&pci_dev->dev, SNDRV_DEFAULT_IDX1,
			   SNDRV_DEFAULT_STR1,
			   THIS_MODULE, 0, &card);
	if (err < 0)
		return err;

	dev->snd_card = card;
	strlcpy(card->driver, "tw686x", sizeof(card->driver));
	strlcpy(card->shortname, "tw686x", sizeof(card->shortname));
	strlcpy(card->longname, pci_name(pci_dev), sizeof(card->longname));
	snd_card_set_dev(card, &pci_dev->dev);

	for (ch = 0; ch < max_channels(dev); ch++) {
		struct tw686x_audio_channel *ac;

		ac = &dev->audio_channels[ch];
		spin_lock_init(&ac->lock);
		ac->dev = dev;
		ac->ch = ch;

		err = tw686x_audio_dma_alloc(dev, ac);
		if (err < 0)
			goto err_cleanup;
	}

	err = tw686x_snd_pcm_init(dev);
	if (err < 0)
		goto err_cleanup;

	err = snd_card_register(card);
	if (!err)
		return 0;

err_cleanup:
	for (ch = 0; ch < max_channels(dev); ch++) {
		if (!dev->audio_channels[ch].dev)
			continue;
		tw686x_audio_dma_free(dev, &dev->audio_channels[ch]);
	}
	snd_card_free(card);
	dev->snd_card = NULL;
	return err;
}
