// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Driver for Digigram miXart soundcards
 *
 * low level interface with interrupt handling and mail box implementation
 *
 * Copyright (c) 2003 by Digigram <alsa@digigram.com>
 */

#include <linux/interrupt.h>
#include <linux/mutex.h>
#include <linux/pci.h>
#include <linux/io.h>

#include <sound/core.h>
#include "mixart.h"
#include "mixart_hwdep.h"
#include "mixart_core.h"


#define MSG_TIMEOUT_JIFFIES         (400 * HZ) / 1000 /* 400 ms */

#define MSG_DESCRIPTOR_SIZE         0x24
#define MSG_HEADER_SIZE             (MSG_DESCRIPTOR_SIZE + 4)

#define MSG_TYPE_MASK               0x00000003    /* mask for following types */
#define MSG_TYPE_NOTIFY             0             /* embedded -> driver (only notification, do not get_msg() !) */
#define MSG_TYPE_COMMAND            1             /* driver <-> embedded (a command has no answer) */
#define MSG_TYPE_REQUEST            2             /* driver -> embedded (request will get an answer back) */
#define MSG_TYPE_ANSWER             3             /* embedded -> driver */
#define MSG_CANCEL_NOTIFY_MASK      0x80000000    /* this bit is set for a notification that has been canceled */


static int retrieve_msg_frame(struct mixart_mgr *mgr, u32 *msg_frame)
{
	/* read the message frame fifo */
	u32 headptr, tailptr;

	tailptr = readl_be(MIXART_MEM(mgr, MSG_OUTBOUND_POST_TAIL));
	headptr = readl_be(MIXART_MEM(mgr, MSG_OUTBOUND_POST_HEAD));

	if (tailptr == headptr)
		return 0; /* no message posted */

	if (tailptr < MSG_OUTBOUND_POST_STACK)
		return 0; /* error */
	if (tailptr >= MSG_OUTBOUND_POST_STACK + MSG_BOUND_STACK_SIZE)
		return 0; /* error */

	*msg_frame = readl_be(MIXART_MEM(mgr, tailptr));

	/* increment the tail index */
	tailptr += 4;
	if( tailptr >= (MSG_OUTBOUND_POST_STACK+MSG_BOUND_STACK_SIZE) )
		tailptr = MSG_OUTBOUND_POST_STACK;
	writel_be(tailptr, MIXART_MEM(mgr, MSG_OUTBOUND_POST_TAIL));

	return 1;
}

static int get_msg(struct mixart_mgr *mgr, struct mixart_msg *resp,
		   u32 msg_frame_address )
{
	u32  headptr;
	u32  size;
	int  err;
#ifndef __BIG_ENDIAN
	unsigned int i;
#endif

	err = 0;

	/* copy message descriptor from miXart to driver */
	size                =  readl_be(MIXART_MEM(mgr, msg_frame_address));       /* size of descriptor + response */
	resp->message_id    =  readl_be(MIXART_MEM(mgr, msg_frame_address + 4));   /* dwMessageID */
	resp->uid.object_id =  readl_be(MIXART_MEM(mgr, msg_frame_address + 8));   /* uidDest */
	resp->uid.desc      =  readl_be(MIXART_MEM(mgr, msg_frame_address + 12));  /* */

	if( (size < MSG_DESCRIPTOR_SIZE) || (resp->size < (size - MSG_DESCRIPTOR_SIZE))) {
		err = -EINVAL;
		dev_err(&mgr->pci->dev,
			"problem with response size = %d\n", size);
		goto _clean_exit;
	}
	size -= MSG_DESCRIPTOR_SIZE;

	memcpy_fromio(resp->data, MIXART_MEM(mgr, msg_frame_address + MSG_HEADER_SIZE ), size);
	resp->size = size;

	/* swap if necessary */
#ifndef __BIG_ENDIAN
	size /= 4; /* u32 size */
	for(i=0; i < size; i++) {
		((u32*)resp->data)[i] = be32_to_cpu(((__be32*)resp->data)[i]);
	}
#endif

	/*
	 * free message frame address
	 */
	headptr = readl_be(MIXART_MEM(mgr, MSG_OUTBOUND_FREE_HEAD));

	if( (headptr < MSG_OUTBOUND_FREE_STACK) || ( headptr >= (MSG_OUTBOUND_FREE_STACK+MSG_BOUND_STACK_SIZE))) {
		err = -EINVAL;
		goto _clean_exit;
	}

	/* give address back to outbound fifo */
	writel_be(msg_frame_address, MIXART_MEM(mgr, headptr));

	/* increment the outbound free head */
	headptr += 4;
	if( headptr >= (MSG_OUTBOUND_FREE_STACK+MSG_BOUND_STACK_SIZE) )
		headptr = MSG_OUTBOUND_FREE_STACK;

	writel_be(headptr, MIXART_MEM(mgr, MSG_OUTBOUND_FREE_HEAD));

 _clean_exit:
	return err;
}


/*
 * send a message to miXart. return: the msg_frame used for this message
 */
/* call with mgr->msg_lock held! */
static int send_msg( struct mixart_mgr *mgr,
		     struct mixart_msg *msg,
		     int max_answersize,
		     int mark_pending,
		     u32 *msg_event)
{
	u32 headptr, tailptr;
	u32 msg_frame_address;
	int i;

	if (snd_BUG_ON(msg->size % 4))
		return -EINVAL;

	/* get message frame address */
	tailptr = readl_be(MIXART_MEM(mgr, MSG_INBOUND_FREE_TAIL));
	headptr = readl_be(MIXART_MEM(mgr, MSG_INBOUND_FREE_HEAD));

	if (tailptr == headptr) {
		dev_err(&mgr->pci->dev, "error: no message frame available\n");
		return -EBUSY;
	}

	if( (tailptr < MSG_INBOUND_FREE_STACK) || (tailptr >= (MSG_INBOUND_FREE_STACK+MSG_BOUND_STACK_SIZE))) {
		return -EINVAL;
	}

	msg_frame_address = readl_be(MIXART_MEM(mgr, tailptr));
	writel(0, MIXART_MEM(mgr, tailptr)); /* set address to zero on this fifo position */

	/* increment the inbound free tail */
	tailptr += 4;
	if( tailptr >= (MSG_INBOUND_FREE_STACK+MSG_BOUND_STACK_SIZE) )
		tailptr = MSG_INBOUND_FREE_STACK;

	writel_be(tailptr, MIXART_MEM(mgr, MSG_INBOUND_FREE_TAIL));

	/* TODO : use memcpy_toio() with intermediate buffer to copy the message */

	/* copy message descriptor to card memory */
	writel_be( msg->size + MSG_DESCRIPTOR_SIZE,      MIXART_MEM(mgr, msg_frame_address) );      /* size of descriptor + request */
	writel_be( msg->message_id ,                     MIXART_MEM(mgr, msg_frame_address + 4) );  /* dwMessageID */
	writel_be( msg->uid.object_id,                   MIXART_MEM(mgr, msg_frame_address + 8) );  /* uidDest */
	writel_be( msg->uid.desc,                        MIXART_MEM(mgr, msg_frame_address + 12) ); /* */
	writel_be( MSG_DESCRIPTOR_SIZE,                  MIXART_MEM(mgr, msg_frame_address + 16) ); /* SizeHeader */
	writel_be( MSG_DESCRIPTOR_SIZE,                  MIXART_MEM(mgr, msg_frame_address + 20) ); /* OffsetDLL_T16 */
	writel_be( msg->size,                            MIXART_MEM(mgr, msg_frame_address + 24) ); /* SizeDLL_T16 */
	writel_be( MSG_DESCRIPTOR_SIZE,                  MIXART_MEM(mgr, msg_frame_address + 28) ); /* OffsetDLL_DRV */
	writel_be( 0,                                    MIXART_MEM(mgr, msg_frame_address + 32) ); /* SizeDLL_DRV */
	writel_be( MSG_DESCRIPTOR_SIZE + max_answersize, MIXART_MEM(mgr, msg_frame_address + 36) ); /* dwExpectedAnswerSize */

	/* copy message data to card memory */
	for( i=0; i < msg->size; i+=4 ) {
		writel_be( *(u32*)(msg->data + i), MIXART_MEM(mgr, MSG_HEADER_SIZE + msg_frame_address + i)  );
	}

	if( mark_pending ) {
		if( *msg_event ) {
			/* the pending event is the notification we wait for ! */
			mgr->pending_event = *msg_event;
		}
		else {
			/* the pending event is the answer we wait for (same address than the request)! */
			mgr->pending_event = msg_frame_address;

			/* copy address back to caller */
			*msg_event = msg_frame_address;
		}
	}

	/* mark the frame as a request (will have an answer) */
	msg_frame_address |= MSG_TYPE_REQUEST;

	/* post the frame */
	headptr = readl_be(MIXART_MEM(mgr, MSG_INBOUND_POST_HEAD));

	if( (headptr < MSG_INBOUND_POST_STACK) || (headptr >= (MSG_INBOUND_POST_STACK+MSG_BOUND_STACK_SIZE))) {
		return -EINVAL;
	}

	writel_be(msg_frame_address, MIXART_MEM(mgr, headptr));

	/* increment the inbound post head */
	headptr += 4;
	if( headptr >= (MSG_INBOUND_POST_STACK+MSG_BOUND_STACK_SIZE) )
		headptr = MSG_INBOUND_POST_STACK;

	writel_be(headptr, MIXART_MEM(mgr, MSG_INBOUND_POST_HEAD));

	return 0;
}


int snd_mixart_send_msg(struct mixart_mgr *mgr, struct mixart_msg *request, int max_resp_size, void *resp_data)
{
	struct mixart_msg resp;
	u32 msg_frame = 0; /* set to 0, so it's no notification to wait for, but the answer */
	int err;
	wait_queue_entry_t wait;
	long timeout;

	init_waitqueue_entry(&wait, current);

	mutex_lock(&mgr->msg_lock);
	/* send the message */
	err = send_msg(mgr, request, max_resp_size, 1, &msg_frame);  /* send and mark the answer pending */
	if (err) {
		mutex_unlock(&mgr->msg_lock);
		return err;
	}

	set_current_state(TASK_UNINTERRUPTIBLE);
	add_wait_queue(&mgr->msg_sleep, &wait);
	mutex_unlock(&mgr->msg_lock);
	timeout = schedule_timeout(MSG_TIMEOUT_JIFFIES);
	remove_wait_queue(&mgr->msg_sleep, &wait);

	if (! timeout) {
		/* error - no ack */
		dev_err(&mgr->pci->dev,
			"error: no response on msg %x\n", msg_frame);
		return -EIO;
	}

	/* retrieve the answer into the same struct mixart_msg */
	resp.message_id = 0;
	resp.uid = (struct mixart_uid){0,0};
	resp.data = resp_data;
	resp.size = max_resp_size;

	mutex_lock(&mgr->msg_lock);
	err = get_msg(mgr, &resp, msg_frame);
	mutex_unlock(&mgr->msg_lock);

	if( request->message_id != resp.message_id )
		dev_err(&mgr->pci->dev, "RESPONSE ERROR!\n");

	return err;
}


int snd_mixart_send_msg_wait_notif(struct mixart_mgr *mgr,
				   struct mixart_msg *request, u32 notif_event)
{
	int err;
	wait_queue_entry_t wait;
	long timeout;

	if (snd_BUG_ON(!notif_event))
		return -EINVAL;
	if (snd_BUG_ON((notif_event & MSG_TYPE_MASK) != MSG_TYPE_NOTIFY))
		return -EINVAL;
	if (snd_BUG_ON(notif_event & MSG_CANCEL_NOTIFY_MASK))
		return -EINVAL;

	init_waitqueue_entry(&wait, current);

	mutex_lock(&mgr->msg_lock);
	/* send the message */
	err = send_msg(mgr, request, MSG_DEFAULT_SIZE, 1, &notif_event);  /* send and mark the notification event pending */
	if(err) {
		mutex_unlock(&mgr->msg_lock);
		return err;
	}

	set_current_state(TASK_UNINTERRUPTIBLE);
	add_wait_queue(&mgr->msg_sleep, &wait);
	mutex_unlock(&mgr->msg_lock);
	timeout = schedule_timeout(MSG_TIMEOUT_JIFFIES);
	remove_wait_queue(&mgr->msg_sleep, &wait);

	if (! timeout) {
		/* error - no ack */
		dev_err(&mgr->pci->dev,
			"error: notification %x not received\n", notif_event);
		return -EIO;
	}

	return 0;
}


int snd_mixart_send_msg_nonblock(struct mixart_mgr *mgr, struct mixart_msg *request)
{
	u32 message_frame;
	int err;

	/* just send the message (do not mark it as a pending one) */
	mutex_lock(&mgr->msg_lock);
	err = send_msg(mgr, request, MSG_DEFAULT_SIZE, 0, &message_frame);
	mutex_unlock(&mgr->msg_lock);

	/* the answer will be handled by snd_struct mixart_msgasklet()  */
	atomic_inc(&mgr->msg_processed);

	return err;
}


/* common buffer of interrupt to send/receive messages */
static u32 mixart_msg_data[MSG_DEFAULT_SIZE / 4];


static void snd_mixart_process_msg(struct mixart_mgr *mgr)
{
	struct mixart_msg resp;
	u32 msg, addr, type;
	int err;

	while (mgr->msg_fifo_readptr != mgr->msg_fifo_writeptr) {
		msg = mgr->msg_fifo[mgr->msg_fifo_readptr];
		mgr->msg_fifo_readptr++;
		mgr->msg_fifo_readptr %= MSG_FIFO_SIZE;

		/* process the message ... */
		addr = msg & ~MSG_TYPE_MASK;
		type = msg & MSG_TYPE_MASK;

		switch (type) {
		case MSG_TYPE_ANSWER:
			/* answer to a message on that we did not wait for (send_msg_nonblock) */
			resp.message_id = 0;
			resp.data = mixart_msg_data;
			resp.size = sizeof(mixart_msg_data);
			err = get_msg(mgr, &resp, addr);
			if( err < 0 ) {
				dev_err(&mgr->pci->dev,
					"error(%d) reading mf %x\n",
					err, msg);
				break;
			}

			switch(resp.message_id) {
			case MSG_STREAM_START_INPUT_STAGE_PACKET:
			case MSG_STREAM_START_OUTPUT_STAGE_PACKET:
			case MSG_STREAM_STOP_INPUT_STAGE_PACKET:
			case MSG_STREAM_STOP_OUTPUT_STAGE_PACKET:
				if(mixart_msg_data[0])
					dev_err(&mgr->pci->dev,
						"error MSG_STREAM_ST***_***PUT_STAGE_PACKET status=%x\n",
						mixart_msg_data[0]);
				break;
			default:
				dev_dbg(&mgr->pci->dev,
					"received mf(%x) : msg_id(%x) uid(%x, %x) size(%zd)\n",
					   msg, resp.message_id, resp.uid.object_id, resp.uid.desc, resp.size);
				break;
			}
			break;
 		case MSG_TYPE_NOTIFY:
			/* msg contains no address ! do not get_msg() ! */
		case MSG_TYPE_COMMAND:
			/* get_msg() necessary */
		default:
			dev_err(&mgr->pci->dev,
				"doesn't know what to do with message %x\n",
				msg);
		} /* switch type */

		/* decrement counter */
		atomic_dec(&mgr->msg_processed);

	} /* while there is a msg in fifo */
}


irqreturn_t snd_mixart_interrupt(int irq, void *dev_id)
{
	struct mixart_mgr *mgr = dev_id;
	u32 it_reg;

	it_reg = readl_le(MIXART_REG(mgr, MIXART_PCI_OMISR_OFFSET));
	if( !(it_reg & MIXART_OIDI) ) {
		/* this device did not cause the interrupt */
		return IRQ_NONE;
	}

	/* mask all interrupts */
	writel_le(MIXART_HOST_ALL_INTERRUPT_MASKED, MIXART_REG(mgr, MIXART_PCI_OMIMR_OFFSET));

	/* outdoorbell register clear */
	it_reg = readl(MIXART_REG(mgr, MIXART_PCI_ODBR_OFFSET));
	writel(it_reg, MIXART_REG(mgr, MIXART_PCI_ODBR_OFFSET));

	/* clear interrupt */
	writel_le( MIXART_OIDI, MIXART_REG(mgr, MIXART_PCI_OMISR_OFFSET) );

	return IRQ_WAKE_THREAD;
}

irqreturn_t snd_mixart_threaded_irq(int irq, void *dev_id)
{
	struct mixart_mgr *mgr = dev_id;
	int err;
	struct mixart_msg resp;
	u32 msg;

	mutex_lock(&mgr->lock);
	/* process interrupt */
	while (retrieve_msg_frame(mgr, &msg)) {

		switch (msg & MSG_TYPE_MASK) {
		case MSG_TYPE_COMMAND:
			resp.message_id = 0;
			resp.data = mixart_msg_data;
			resp.size = sizeof(mixart_msg_data);
			err = get_msg(mgr, &resp, msg & ~MSG_TYPE_MASK);
			if( err < 0 ) {
				dev_err(&mgr->pci->dev,
					"interrupt: error(%d) reading mf %x\n",
					err, msg);
				break;
			}

			if(resp.message_id == MSG_SERVICES_TIMER_NOTIFY) {
				int i;
				struct mixart_timer_notify *notify;
				notify = (struct mixart_timer_notify *)mixart_msg_data;

				BUILD_BUG_ON(sizeof(notify) > sizeof(mixart_msg_data));
				if (snd_BUG_ON(notify->stream_count > ARRAY_SIZE(notify->streams)))
					break;
				for(i=0; i<notify->stream_count; i++) {

					u32 buffer_id = notify->streams[i].buffer_id;
					unsigned int chip_number =  (buffer_id & MIXART_NOTIFY_CARD_MASK) >> MIXART_NOTIFY_CARD_OFFSET; /* card0 to 3 */
					unsigned int pcm_number  =  (buffer_id & MIXART_NOTIFY_PCM_MASK ) >> MIXART_NOTIFY_PCM_OFFSET;  /* pcm0 to 3  */
					unsigned int sub_number  =   buffer_id & MIXART_NOTIFY_SUBS_MASK;             /* 0 to MIXART_PLAYBACK_STREAMS */
					unsigned int is_capture  = ((buffer_id & MIXART_NOTIFY_CAPT_MASK) != 0);      /* playback == 0 / capture == 1 */

					struct snd_mixart *chip  = mgr->chip[chip_number];
					struct mixart_stream *stream;

					if ((chip_number >= mgr->num_cards) || (pcm_number >= MIXART_PCM_TOTAL) || (sub_number >= MIXART_PLAYBACK_STREAMS)) {
						dev_err(&mgr->pci->dev,
							"error MSG_SERVICES_TIMER_NOTIFY buffer_id (%x) pos(%d)\n",
							   buffer_id, notify->streams[i].sample_pos_low_part);
						break;
					}

					if (is_capture)
						stream = &chip->capture_stream[pcm_number];
					else
						stream = &chip->playback_stream[pcm_number][sub_number];

					if (stream->substream && (stream->status == MIXART_STREAM_STATUS_RUNNING)) {
						struct snd_pcm_runtime *runtime = stream->substream->runtime;
						int elapsed = 0;
						u64 sample_count = ((u64)notify->streams[i].sample_pos_high_part) << 32;
						sample_count |= notify->streams[i].sample_pos_low_part;

						while (1) {
							u64 new_elapse_pos = stream->abs_period_elapsed +  runtime->period_size;

							if (new_elapse_pos > sample_count) {
								break; /* while */
							}
							else {
								elapsed = 1;
								stream->buf_periods++;
								if (stream->buf_periods >= runtime->periods)
									stream->buf_periods = 0;

								stream->abs_period_elapsed = new_elapse_pos;
							}
						}
						stream->buf_period_frag = (u32)( sample_count - stream->abs_period_elapsed );

						if(elapsed) {
							mutex_unlock(&mgr->lock);
							snd_pcm_period_elapsed(stream->substream);
							mutex_lock(&mgr->lock);
						}
					}
				}
				break;
			}
			if(resp.message_id == MSG_SERVICES_REPORT_TRACES) {
				if(resp.size > 1) {
#ifndef __BIG_ENDIAN
					/* Traces are text: the swapped msg_data has to be swapped back ! */
					int i;
					for(i=0; i<(resp.size/4); i++) {
						((__be32*)mixart_msg_data)[i] = cpu_to_be32((mixart_msg_data)[i]);
					}
#endif
					((char*)mixart_msg_data)[resp.size - 1] = 0;
					dev_dbg(&mgr->pci->dev,
						"MIXART TRACE : %s\n",
						(char *)mixart_msg_data);
				}
				break;
			}

			dev_dbg(&mgr->pci->dev, "command %x not handled\n",
				resp.message_id);
			break;

		case MSG_TYPE_NOTIFY:
			if(msg & MSG_CANCEL_NOTIFY_MASK) {
				msg &= ~MSG_CANCEL_NOTIFY_MASK;
				dev_err(&mgr->pci->dev,
					"canceled notification %x !\n", msg);
			}
			fallthrough;
		case MSG_TYPE_ANSWER:
			/* answer or notification to a message we are waiting for*/
			mutex_lock(&mgr->msg_lock);
			if( (msg & ~MSG_TYPE_MASK) == mgr->pending_event ) {
				wake_up(&mgr->msg_sleep);
				mgr->pending_event = 0;
			}
			/* answer to a message we did't want to wait for */
			else {
				mgr->msg_fifo[mgr->msg_fifo_writeptr] = msg;
				mgr->msg_fifo_writeptr++;
				mgr->msg_fifo_writeptr %= MSG_FIFO_SIZE;
				snd_mixart_process_msg(mgr);
			}
			mutex_unlock(&mgr->msg_lock);
			break;
		case MSG_TYPE_REQUEST:
		default:
			dev_dbg(&mgr->pci->dev,
				"interrupt received request %x\n", msg);
			/* TODO : are there things to do here ? */
			break;
		} /* switch on msg type */
	} /* while there are msgs */

	/* allow interrupt again */
	writel_le( MIXART_ALLOW_OUTBOUND_DOORBELL, MIXART_REG( mgr, MIXART_PCI_OMIMR_OFFSET));

	mutex_unlock(&mgr->lock);

	return IRQ_HANDLED;
}


void snd_mixart_init_mailbox(struct mixart_mgr *mgr)
{
	writel( 0, MIXART_MEM( mgr, MSG_HOST_RSC_PROTECTION ) );
	writel( 0, MIXART_MEM( mgr, MSG_AGENT_RSC_PROTECTION ) );

	/* allow outbound messagebox to generate interrupts */
	if(mgr->irq >= 0) {
		writel_le( MIXART_ALLOW_OUTBOUND_DOORBELL, MIXART_REG( mgr, MIXART_PCI_OMIMR_OFFSET));
	}
	return;
}

void snd_mixart_exit_mailbox(struct mixart_mgr *mgr)
{
	/* no more interrupts on outbound messagebox */
	writel_le( MIXART_HOST_ALL_INTERRUPT_MASKED, MIXART_REG( mgr, MIXART_PCI_OMIMR_OFFSET));
	return;
}

void snd_mixart_reset_board(struct mixart_mgr *mgr)
{
	/* reset miXart */
	writel_be( 1, MIXART_REG(mgr, MIXART_BA1_BRUTAL_RESET_OFFSET) );
	return;
}
