/*
 * This file is part of linux driver the digital TV devices equipped with B2C2 FlexcopII(b)/III
 *
 * flexcop-hw-filter.c - pid and mac address filtering and corresponding control functions.
 *
 * see flexcop.c for copyright information.
 */
#include "flexcop.h"

static void flexcop_rcv_data_ctrl(struct flexcop_device *fc, int onoff)
{
	flexcop_set_ibi_value(ctrl_208,Rcv_Data_sig,onoff);

	deb_ts("rcv_data is now: '%s'\n",onoff ? "on" : "off");
}

void flexcop_smc_ctrl(struct flexcop_device *fc, int onoff)
{
	flexcop_set_ibi_value(ctrl_208,SMC_Enable_sig,onoff);
}

void flexcop_null_filter_ctrl(struct flexcop_device *fc, int onoff)
{
	flexcop_set_ibi_value(ctrl_208,Null_filter_sig,onoff);
}

void flexcop_set_mac_filter(struct flexcop_device *fc, u8 mac[6])
{
	flexcop_ibi_value v418,v41c;
	v41c = fc->read_ibi_reg(fc,mac_address_41c);

	v418.mac_address_418.MAC1 = mac[0];
	v418.mac_address_418.MAC2 = mac[1];
	v418.mac_address_418.MAC3 = mac[2];
	v418.mac_address_418.MAC6 = mac[3];
	v41c.mac_address_41c.MAC7 = mac[4];
	v41c.mac_address_41c.MAC8 = mac[5];

	fc->write_ibi_reg(fc,mac_address_418,v418);
	fc->write_ibi_reg(fc,mac_address_41c,v41c);
}

void flexcop_mac_filter_ctrl(struct flexcop_device *fc, int onoff)
{
	flexcop_set_ibi_value(ctrl_208,MAC_filter_Mode_sig,onoff);
}

static void flexcop_pid_group_filter(struct flexcop_device *fc, u16 pid, u16 mask)
{
	/* index_reg_310.extra_index_reg need to 0 or 7 to work */
	flexcop_ibi_value v30c;
	v30c.pid_filter_30c_ext_ind_0_7.Group_PID = pid;
	v30c.pid_filter_30c_ext_ind_0_7.Group_mask = mask;
	fc->write_ibi_reg(fc,pid_filter_30c,v30c);
}

static void flexcop_pid_group_filter_ctrl(struct flexcop_device *fc, int onoff)
{
	flexcop_set_ibi_value(ctrl_208,Mask_filter_sig,onoff);
}

/* this fancy define reduces the code size of the quite similar PID controlling of
 * the first 6 PIDs
 */

#define pid_ctrl(vregname,field,enablefield,trans_field,transval) \
	flexcop_ibi_value vpid = fc->read_ibi_reg(fc, vregname), \
					  v208 = fc->read_ibi_reg(fc, ctrl_208); \
\
	vpid.vregname.field = onoff ? pid : 0x1fff; \
	vpid.vregname.trans_field = transval; \
	v208.ctrl_208.enablefield = onoff; \
\
	fc->write_ibi_reg(fc,vregname,vpid); \
	fc->write_ibi_reg(fc,ctrl_208,v208);

static void flexcop_pid_Stream1_PID_ctrl(struct flexcop_device *fc, u16 pid, int onoff)
{
	pid_ctrl(pid_filter_300,Stream1_PID,Stream1_filter_sig,Stream1_trans,0);
}

static void flexcop_pid_Stream2_PID_ctrl(struct flexcop_device *fc, u16 pid, int onoff)
{
	pid_ctrl(pid_filter_300,Stream2_PID,Stream2_filter_sig,Stream2_trans,0);
}

static void flexcop_pid_PCR_PID_ctrl(struct flexcop_device *fc, u16 pid, int onoff)
{
	pid_ctrl(pid_filter_304,PCR_PID,PCR_filter_sig,PCR_trans,0);
}

static void flexcop_pid_PMT_PID_ctrl(struct flexcop_device *fc, u16 pid, int onoff)
{
	pid_ctrl(pid_filter_304,PMT_PID,PMT_filter_sig,PMT_trans,0);
}

static void flexcop_pid_EMM_PID_ctrl(struct flexcop_device *fc, u16 pid, int onoff)
{
	pid_ctrl(pid_filter_308,EMM_PID,EMM_filter_sig,EMM_trans,0);
}

static void flexcop_pid_ECM_PID_ctrl(struct flexcop_device *fc, u16 pid, int onoff)
{
	pid_ctrl(pid_filter_308,ECM_PID,ECM_filter_sig,ECM_trans,0);
}

static void flexcop_pid_control(struct flexcop_device *fc, int index, u16 pid,int onoff)
{
	if (pid == 0x2000)
		return;

	deb_ts("setting pid: %5d %04x at index %d '%s'\n",pid,pid,index,onoff ? "on" : "off");

	/* We could use bit magic here to reduce source code size.
	 * I decided against it, but to use the real register names */
	switch (index) {
		case 0: flexcop_pid_Stream1_PID_ctrl(fc,pid,onoff); break;
		case 1: flexcop_pid_Stream2_PID_ctrl(fc,pid,onoff); break;
		case 2: flexcop_pid_PCR_PID_ctrl(fc,pid,onoff); break;
		case 3: flexcop_pid_PMT_PID_ctrl(fc,pid,onoff); break;
		case 4: flexcop_pid_EMM_PID_ctrl(fc,pid,onoff); break;
		case 5:	flexcop_pid_ECM_PID_ctrl(fc,pid,onoff); break;
		default:
			if (fc->has_32_hw_pid_filter && index < 38) {
				flexcop_ibi_value vpid,vid;

				/* set the index */
				vid = fc->read_ibi_reg(fc,index_reg_310);
				vid.index_reg_310.index_reg = index - 6;
				fc->write_ibi_reg(fc,index_reg_310, vid);

				vpid = fc->read_ibi_reg(fc,pid_n_reg_314);
				vpid.pid_n_reg_314.PID = onoff ? pid : 0x1fff;
				vpid.pid_n_reg_314.PID_enable_bit = onoff;
				fc->write_ibi_reg(fc,pid_n_reg_314, vpid);
			}
			break;
	}
}

static int flexcop_toggle_fullts_streaming(struct flexcop_device *fc,int onoff)
{
	if (fc->fullts_streaming_state != onoff) {
		deb_ts("%s full TS transfer\n",onoff ? "enabling" : "disabling");
		flexcop_pid_group_filter(fc, 0, 0x1fe0 * (!onoff));
		flexcop_pid_group_filter_ctrl(fc,onoff);
		fc->fullts_streaming_state = onoff;
	}
	return 0;
}

int flexcop_pid_feed_control(struct flexcop_device *fc, struct dvb_demux_feed *dvbdmxfeed, int onoff)
{
	int max_pid_filter = 6 + fc->has_32_hw_pid_filter*32;

	fc->feedcount += onoff ? 1 : -1; /* the number of PIDs/Feed currently requested */
	if (dvbdmxfeed->index >= max_pid_filter)
		fc->extra_feedcount += onoff ? 1 : -1;

	/* toggle complete-TS-streaming when:
	 * - pid_filtering is not enabled and it is the first or last feed requested
	 * - pid_filtering is enabled,
	 *   - but the number of requested feeds is exceeded
	 *   - or the requested pid is 0x2000 */

	if (!fc->pid_filtering && fc->feedcount == onoff)
		flexcop_toggle_fullts_streaming(fc,onoff);

	if (fc->pid_filtering) {
		flexcop_pid_control(fc,dvbdmxfeed->index,dvbdmxfeed->pid,onoff);

		if (fc->extra_feedcount > 0)
			flexcop_toggle_fullts_streaming(fc,1);
		else if (dvbdmxfeed->pid == 0x2000)
			flexcop_toggle_fullts_streaming(fc,onoff);
		else
			flexcop_toggle_fullts_streaming(fc,0);
	}

	/* if it was the first or last feed request change the stream-status */
	if (fc->feedcount == onoff) {
		flexcop_rcv_data_ctrl(fc,onoff);
		if (fc->stream_control) /* device specific stream control */
			fc->stream_control(fc,onoff);

		/* feeding stopped -> reset the flexcop filter*/
		if (onoff == 0) {
			flexcop_reset_block_300(fc);
			flexcop_hw_filter_init(fc);
		}
	}

	return 0;
}

void flexcop_hw_filter_init(struct flexcop_device *fc)
{
	int i;
	flexcop_ibi_value v;
	for (i = 0; i < 6 + 32*fc->has_32_hw_pid_filter; i++)
		flexcop_pid_control(fc,i,0x1fff,0);

	flexcop_pid_group_filter(fc, 0, 0x1fe0);
	flexcop_pid_group_filter_ctrl(fc,0);

	v = fc->read_ibi_reg(fc,pid_filter_308);
	v.pid_filter_308.EMM_filter_4 = 1;
	v.pid_filter_308.EMM_filter_6 = 0;
	fc->write_ibi_reg(fc,pid_filter_308,v);

	flexcop_null_filter_ctrl(fc, 1);
}
