/*
* Copyright (C) 2017 Amlogic, Inc. All rights reserved.
*
* 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; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* Description:
*/
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/delay.h>
#include <linux/device.h>

#include "aml_pcmcia.h"
#include "aml_ci.h"

static int aml_pcmcia_debug = 1;

module_param_named(pcmcia_debug, aml_pcmcia_debug, int, 0644);
MODULE_PARM_DESC(pcmcia_debug, "enable verbose debug messages");

#define pr_dbg(args...)\
	do {\
		if (aml_pcmcia_debug)\
			printk(args);\
	} while (0)
#define pr_error(fmt, args...) printk("PCMCIA: " fmt, ## args)


static int pcmcia_plugin(struct aml_pcmcia *pc)
{
	if (pc->slot_state == MODULE_XTRACTED) {
		pr_dbg(" CAM Plugged IN: Adapter(%d) Slot(0)\n", 0);
		udelay(50);
		aml_pcmcia_reset(pc);
		/*wait unplug*/
		pc->init_irq(pc, IRQF_TRIGGER_RISING);
		udelay(500);
		pc->slot_state = MODULE_INSERTED;
	} else {
		pr_error("repeat into pcmcia insert \r\n");
		aml_pcmcia_reset(pc);
	}
	udelay(100);
	pc->pcmcia_plugin(pc, 1);

	return 0;
}

static int pcmcia_unplug(struct aml_pcmcia *pc)
{
	if (pc->slot_state == MODULE_INSERTED) {
		pr_dbg(" CAM Unplugged: Adapter(%d) Slot(0)\n", 0);
		/*udelay(50);*/
		/*aml_pcmcia_reset(pc);*/
		/*wait plugin*/
		pc->init_irq(pc, IRQF_TRIGGER_FALLING);
		udelay(500);
		pc->slot_state = MODULE_XTRACTED;
	}
	udelay(100);
	pc->pcmcia_plugin(pc, 0);

	return 0;
}

static irqreturn_t pcmcia_irq_handler(int irq, void *dev_id)
{
	struct aml_pcmcia *pc = (struct aml_pcmcia *)dev_id;
	pr_dbg("pcmcia_irq_handler--into--\r\n");
	disable_irq_nosync(pc->irq);
	schedule_work(&pc->pcmcia_work);
	enable_irq(pc->irq);
	return IRQ_HANDLED;
}

static void aml_pcmcia_work(struct work_struct *work)
{
	int cd1, cd2;
	struct aml_pcmcia *pc = container_of(
		work, struct aml_pcmcia, pcmcia_work);

	cd1 = pc->get_cd1(pc);
	cd2 = pc->get_cd2(pc);

	if (cd1 != cd2)
		pr_error("CAM card not inerted.\n");
	else {
		if (!cd1) {
			pr_error("Adapter(%d) Slot(0): CAM Plugin\n", 0);
			pcmcia_plugin(pc);
		} else {
			pr_error("Adapter(%d) Slot(0): CAM Unplug\n", 0);
			pcmcia_unplug(pc);
		}
	}
}

static void aml_pcmcia_detect_cam(struct aml_pcmcia *pc)
{
	int cd1, cd2;

	if (pc == NULL) {
		return;
	}
	cd1 = pc->get_cd1(pc);
	cd2 = pc->get_cd2(pc);

	if (cd1 != cd2)
		pr_error("CAM card not inerted. check end\n");
	else {
		if (!cd1) {
			pr_error("Adapter(%d) Slot(0): CAM Plugin\n", 0);
			pcmcia_plugin(pc);
		} else {
			pr_error("Adapter(%d) Slot(0): CAM Unplug\n", 0);
			pcmcia_unplug(pc);
		}
	}
}
static struct aml_pcmcia *pc_cur;

int aml_pcmcia_init(struct aml_pcmcia *pc)
{
	int err = 0;
	unsigned long mode;
	pr_dbg("aml_pcmcia_init start pc->irq=%d\r\n", pc->irq);
	pc->rst(pc, AML_L);
	/*power on*/
	pc->pwr(pc, AML_PWR_OPEN);/*hi is open power*/
	/*assuming cam unpluged, config the INT to waiting-for-plugin mode*/
	pc->init_irq(pc, IRQF_TRIGGER_LOW);

	INIT_WORK(&pc->pcmcia_work, aml_pcmcia_work);

	mode = IRQF_ONESHOT;
	if (pc->io_device_type == AML_DVB_IO_TYPE_SPI_T312) {
		mode = mode | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING;
	}

	err = request_irq(pc->irq,
	pcmcia_irq_handler,
	mode, "aml-pcmcia", pc);
	if (err != 0) {
		pr_error("ERROR: IRQ registration failed ! <%d>", err);
		return -ENODEV;
	}

	pc_cur = pc;
	pr_dbg("aml_pcmcia_init ok\r\n");
	if (pc->io_device_type == AML_DVB_IO_TYPE_SPI_T312) {
		//mcu start very fast,so she can detect cam before soc init end.
		//so we need add detect cam fun for first time.
		aml_pcmcia_detect_cam(pc);
	}
	return 0;
}
EXPORT_SYMBOL(aml_pcmcia_init);

int aml_pcmcia_exit(struct aml_pcmcia *pc)
{
	free_irq(pc->irq, pc);
	return 0;
}
EXPORT_SYMBOL(aml_pcmcia_exit);

int aml_pcmcia_reset(struct aml_pcmcia *pc)
{
		pr_dbg("CAM RESET-->\n");
		/* viaccess neotion cam need delay 2000 and 3000 */
		/* smit cam need delay 1000 and 1500 */
		/* need change delay according cam vendor */
		pc->rst(pc, AML_H);/*HI is reset*/
		mdelay(1000);
		pc->rst(pc, AML_L);/*defaule LOW*/
		pr_dbg("CAM RESET--\n");
		mdelay(1500);
		pr_dbg("CAM RESET--end\n");
	return 0;
}
EXPORT_SYMBOL(aml_pcmcia_reset);


#if 0
static ssize_t aml_pcmcia_test_cmd(struct class *class,
struct class_attribute *attr, const char *buf, size_t size)
{
	pr_dbg("pcmcia cmd: %s\n", buf);
	if (pc_cur) {
		if (memcmp(buf, "reset", 5) == 0)
			aml_pcmcia_reset(pc_cur);
		else if (memcmp(buf, "on", 2) == 0)
			pc_cur->pwr(pc_cur, AML_PWR_OPEN);
		else if (memcmp(buf, "off", 3) == 0)
			pc_cur->pwr(pc_cur, AML_PWR_CLOSE);
		else if (memcmp(buf, "poll", 4) == 0)
			schedule_work(&pc_cur->pcmcia_work);
		else if (memcmp(buf, "intr", 4) == 0)
			pc_cur->init_irq(pc_cur, IRQF_TRIGGER_RISING);
		else if (memcmp(buf, "intf", 4) == 0)
			pc_cur->init_irq(pc_cur, IRQF_TRIGGER_FALLING);
	}
	return size;
}

static struct class_attribute aml_pcmcia_class_attrs[] = {
	__ATTR(cmd,  S_IRUGO | S_IWUSR, NULL, aml_pcmcia_test_cmd),
	__ATTR_NULL
};

static struct class aml_pcmcia_class = {
	.name = "aml_pcmcia_test",
	.class_attrs = aml_pcmcia_class_attrs,
};

static int __init aml_pcmcia_mod_init(void)
{
	pr_dbg("Amlogic PCMCIA Init\n");

	class_register(&aml_pcmcia_class);

	return 0;
}

static void __exit aml_pcmcia_mod_exit(void)
{
	pr_dbg("Amlogic PCMCIA Exit\n");

	class_unregister(&aml_pcmcia_class);
}



module_init(aml_pcmcia_mod_init);
module_exit(aml_pcmcia_mod_exit);

MODULE_LICENSE("GPL");
#endif
