<commit_before>/*
 * budget-ci.c: driver for the SAA7146 based Budget DVB cards
 *
 * Compiled from various sources by <NAME> <<EMAIL>>
 *
 *     msp430 IR support contributed by <NAME> <<EMAIL>>
 *     partially based on the Siemens DVB driver by Ralph+<NAME>
 *
 * CI interface support (c) 2004 <NAME> <<EMAIL>>
 *
 * 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.
 * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
 *
 *
 * the project's page is at http://www.linuxtv.org/ 
 */

#include <linux/module.h>
#include <linux/errno.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/spinlock.h>
#include <media/rc-core.h>

#include "budget.h"

#include "dvb_ca_en50221.h"
#include "stv0299.h"
#include "stv0297.h"
#include "tda1004x.h"
#include "stb0899_drv.h"
#include "stb0899_reg.h"
#include "stb0899_cfg.h"
#include "stb6100.h"
#include "stb6100_cfg.h"
#include "lnbp21.h"
#include "bsbe1.h"
#include "bsru6.h"
#include "tda1002x.h"
#include "tda827x.h"

#define MODULE_NAME "budget_ci"

/*
 * Regarding DEBIADDR_IR:
 * Some CI modules hang if random addresses are read.
 * Using address 0x4000 for the IR read means that we
 * use the same address as for CI version, which should
 * be a safe default.
 */
#define DEBIADDR_IR		0x4000
#define DEBIADDR_CICONTROL	0x0000
#define DEBIADDR_CIVERSION	0x4000
#define DEBIADDR_IO		0x1000
#define DEBIADDR_ATTR		0x3000

#define CICONTROL_RESET		0x01
#define CICONTROL_ENABLETS	0x02
#define CICONTROL_CAMDETECT	0x08

#define DEBICICTL		0x00420000
#define DEBICICAM		0x02420000

#define SLOTSTATUS_NONE		1
#define SLOTSTATUS_PRESENT	2
#define SLOTSTATUS_RESET	4
#define SLOTSTATUS_READY	8
#define SLOTSTATUS_OCCUPIED	(SLOTSTATUS_PRESENT|SLOTSTATUS_RESET|SLOTSTATUS_READY)

/* RC5 device wildcard */
#define IR_DEVICE_ANY		255

static int rc5_device = -1;
module_param(rc5_device, int, 0644);
MODULE_PARM_DESC(rc5_device, "only IR commands to given RC5 device (device = 0 - 31, any device = 255, default: autodetect)");

static int ir_debug;
module_param(ir_debug, int, 0644);
MODULE_PARM_DESC(ir_debug, "enable debugging information for IR decoding");

DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);

struct budget_ci_ir {
	struct rc_dev *dev;
	struct tasklet_struct msp430_irq_tasklet;
	char name[72]; /* 40 + 32 for (struct saa7146_dev).name */
	char phys[32];
	int rc5_device;
	u32 ir_key;
	bool have_command;
};

struct budget_ci {
	struct budget budget;
	struct tasklet_struct ciintf_irq_tasklet;
	int slot_status;
	int ci_irq;
	struct dvb_ca_en50221 ca;
	struct budget_ci_ir ir;
	u8 tuner_pll_address; /* used for philips_tdm1316l configs */
};

static void msp430_ir_interrupt(unsigned long data)
{
	struct budget_ci *budget_ci = (struct budget_ci *) data;
	struct rc_dev *dev = budget_ci->ir.dev;
	u32 command = ttpci_budget_debiread(&budget_ci->budget, DEBINOSWAP, DEBIADDR_IR, 2, 1, 0) >> 8;

	/*
	 * The msp430 chip can generate two different bytes, command and device
	 *
	 * type1: X1CCCCCC, C = command bits (0 - 63)
	 * type2: X0TDDDDD, D = device bits (0 - 31), T = RC5 toggle bit
	 *
	 * Each signal from the remote control can generate one or more command
	 * bytes and one or more device bytes. For the repeated bytes, the
	 * highest bit (X) is set. The first command byte is always generated
	 * before the first device byte. Other than that, no specific order
	 * seems to apply. To make life interesting, bytes can also be lost.
	 *
	 * Only when we have a command and device byte, a keypress is
	 * generated.
	 */

	if (ir_debug)
		printk("budget_ci: received byte 0x%02x\n", command);

	/* Remove repeat bit, we use every command */
	command = command & 0x7f;

	/* Is this a RC5 command byte? */
	if (command & 0x40) {
		budget_ci->ir.have_command = true;
		budget_ci->ir.ir_key = command & 0x3f;
		return;
	}

	/* It's a RC5 device byte */
	if (!budget_ci->ir.have_command)
		return;
	budget_ci->ir.have_command = false;

	/* FIXME: We should generate complete scancodes with device info */
	if (budget_ci->ir.rc5_device != IR_DEVICE_ANY &&
	    budget_ci->ir.rc5_device != (command & 0x1f))
		return;

	rc_keydown(dev, budget_ci->ir.ir_key, (command & 0x20) ? 1 : 0);
}

static int msp430_ir_init(struct budget_ci *budget_ci)
{
	struct saa7146_dev *saa = budget_ci->budget.dev;
	struct rc_dev *dev;
	int error;

	dev = rc_allocate_device();
	if (!dev) {
		printk(KERN_ERR "budget_ci: IR interface initialisation failed\n");
		return -ENOMEM;
	}

	snprintf(budget_ci->ir.name, sizeof(budget_ci->ir.name),
		 "Budget-CI dvb ir receiver %s", saa->name);
	snprintf(budget_ci->ir.phys, sizeof(budget_ci->ir.phys),
		 "pci-%s/ir0", pci_name(saa->pci));

	dev->driver_name = MODULE_NAME;
	dev->input_name = budget_ci->ir.name;
	dev->input_phys = budget_ci->ir.phys;
	dev->input_id.bustype = BUS_PCI;
	dev->input_id.version = 1;
	if (saa->pci->subsystem_vendor) {
		dev->input_id.vendor = saa->pci->subsystem_vendor;
		dev->input_id.product = saa->pci->subsystem_device;
	} else {
		dev->input_id.vendor = saa->pci->vendor;
		dev->input_id.product = saa->pci->device;
	}
	dev->dev.parent = &saa->pci->dev;

	if (rc5_device < 0)
		budget_ci->ir.rc5_device = IR_DEVICE_ANY;
	else
		budget_ci->ir.rc5_device = rc5_device;

	/* Select keymap and address */
	switch (budget_ci->budget.dev->pci->subsystem_device) {
	case 0x100c:
	case 0x100f:
	case 0x1011:
	case 0x1012:
		/* The hauppauge keymap is a superset of these remotes */
		dev->map_name = RC_MAP_HAUPPAUGE_NEW;

		if (rc5_device < 0)
			budget_ci->ir.rc5_device = 0x1f;
		break;
	case 0x1010:<commit_msg>[media] DVB: Set scanmask for Budget/SAA7146 cards<commit_after>/*
 * budget-ci.c: driver for the SAA7146 based Budget DVB cards
 *
 * Compiled from various sources by <NAME> <<EMAIL>>
 *
 *     msp430 IR support contributed by <NAME> <<EMAIL>>
 *     partially based on the Siemens DVB driver by Ralph+<NAME>
 *
 * CI interface support (c) 2004 <NAME> <<EMAIL>>
 *
 * 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.
 * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
 *
 *
 * the project's page is at http://www.linuxtv.org/ 
 */

#include <linux/module.h>
#include <linux/errno.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/spinlock.h>
#include <media/rc-core.h>

#include "budget.h"

#include "dvb_ca_en50221.h"
#include "stv0299.h"
#include "stv0297.h"
#include "tda1004x.h"
#include "stb0899_drv.h"
#include "stb0899_reg.h"
#include "stb0899_cfg.h"
#include "stb6100.h"
#include "stb6100_cfg.h"
#include "lnbp21.h"
#include "bsbe1.h"
#include "bsru6.h"
#include "tda1002x.h"
#include "tda827x.h"

#define MODULE_NAME "budget_ci"

/*
 * Regarding DEBIADDR_IR:
 * Some CI modules hang if random addresses are read.
 * Using address 0x4000 for the IR read means that we
 * use the same address as for CI version, which should
 * be a safe default.
 */
#define DEBIADDR_IR		0x4000
#define DEBIADDR_CICONTROL	0x0000
#define DEBIADDR_CIVERSION	0x4000
#define DEBIADDR_IO		0x1000
#define DEBIADDR_ATTR		0x3000

#define CICONTROL_RESET		0x01
#define CICONTROL_ENABLETS	0x02
#define CICONTROL_CAMDETECT	0x08

#define DEBICICTL		0x00420000
#define DEBICICAM		0x02420000

#define SLOTSTATUS_NONE		1
#define SLOTSTATUS_PRESENT	2
#define SLOTSTATUS_RESET	4
#define SLOTSTATUS_READY	8
#define SLOTSTATUS_OCCUPIED	(SLOTSTATUS_PRESENT|SLOTSTATUS_RESET|SLOTSTATUS_READY)

/* RC5 device wildcard */
#define IR_DEVICE_ANY		255

static int rc5_device = -1;
module_param(rc5_device, int, 0644);
MODULE_PARM_DESC(rc5_device, "only IR commands to given RC5 device (device = 0 - 31, any device = 255, default: autodetect)");

static int ir_debug;
module_param(ir_debug, int, 0644);
MODULE_PARM_DESC(ir_debug, "enable debugging information for IR decoding");

DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);

struct budget_ci_ir {
	struct rc_dev *dev;
	struct tasklet_struct msp430_irq_tasklet;
	char name[72]; /* 40 + 32 for (struct saa7146_dev).name */
	char phys[32];
	int rc5_device;
	u32 ir_key;
	bool have_command;
};

struct budget_ci {
	struct budget budget;
	struct tasklet_struct ciintf_irq_tasklet;
	int slot_status;
	int ci_irq;
	struct dvb_ca_en50221 ca;
	struct budget_ci_ir ir;
	u8 tuner_pll_address; /* used for philips_tdm1316l configs */
};

static void msp430_ir_interrupt(unsigned long data)
{
	struct budget_ci *budget_ci = (struct budget_ci *) data;
	struct rc_dev *dev = budget_ci->ir.dev;
	u32 command = ttpci_budget_debiread(&budget_ci->budget, DEBINOSWAP, DEBIADDR_IR, 2, 1, 0) >> 8;

	/*
	 * The msp430 chip can generate two different bytes, command and device
	 *
	 * type1: X1CCCCCC, C = command bits (0 - 63)
	 * type2: X0TDDDDD, D = device bits (0 - 31), T = RC5 toggle bit
	 *
	 * Each signal from the remote control can generate one or more command
	 * bytes and one or more device bytes. For the repeated bytes, the
	 * highest bit (X) is set. The first command byte is always generated
	 * before the first device byte. Other than that, no specific order
	 * seems to apply. To make life interesting, bytes can also be lost.
	 *
	 * Only when we have a command and device byte, a keypress is
	 * generated.
	 */

	if (ir_debug)
		printk("budget_ci: received byte 0x%02x\n", command);

	/* Remove repeat bit, we use every command */
	command = command & 0x7f;

	/* Is this a RC5 command byte? */
	if (command & 0x40) {
		budget_ci->ir.have_command = true;
		budget_ci->ir.ir_key = command & 0x3f;
		return;
	}

	/* It's a RC5 device byte */
	if (!budget_ci->ir.have_command)
		return;
	budget_ci->ir.have_command = false;

	/* FIXME: We should generate complete scancodes with device info */
	if (budget_ci->ir.rc5_device != IR_DEVICE_ANY &&
	    budget_ci->ir.rc5_device != (command & 0x1f))
		return;

	rc_keydown(dev, budget_ci->ir.ir_key, (command & 0x20) ? 1 : 0);
}

static int msp430_ir_init(struct budget_ci *budget_ci)
{
	struct saa7146_dev *saa = budget_ci->budget.dev;
	struct rc_dev *dev;
	int error;

	dev = rc_allocate_device();
	if (!dev) {
		printk(KERN_ERR "budget_ci: IR interface initialisation failed\n");
		return -ENOMEM;
	}

	snprintf(budget_ci->ir.name, sizeof(budget_ci->ir.name),
		 "Budget-CI dvb ir receiver %s", saa->name);
	snprintf(budget_ci->ir.phys, sizeof(budget_ci->ir.phys),
		 "pci-%s/ir0", pci_name(saa->pci));

	dev->driver_name = MODULE_NAME;
	dev->input_name = budget_ci->ir.name;
	dev->input_phys = budget_ci->ir.phys;
	dev->input_id.bustype = BUS_PCI;
	dev->input_id.version = 1;
	dev->scanmask = 0xff;
	if (saa->pci->subsystem_vendor) {
		dev->input_id.vendor = saa->pci->subsystem_vendor;
		dev->input_id.product = saa->pci->subsystem_device;
	} else {
		dev->input_id.vendor = saa->pci->vendor;
		dev->input_id.product = saa->pci->device;
	}
	dev->dev.parent = &saa->pci->dev;

	if (rc5_device < 0)
		budget_ci->ir.rc5_device = IR_DEVICE_ANY;
	else
		budget_ci->ir.rc5_device = rc5_device;

	/* Select keymap and address */
	switch (budget_ci->budget.dev->pci->subsystem_device) {
	case 0x100c:
	case 0x100f:
	case 0x1011:
	case 0x1012:
		/* The hauppauge keymap is a superset of these remotes */
		dev->map_name = RC_MAP_HAUPPAUGE_NEW;

		if (rc5_device < 0)
			budget_ci->ir.rc5_device = 0x1f;
		break;
	case 0x1010:
{'fraction_non_alphanumeric': 0.1092275707660323, 'fraction_numerical': 0.04389892851431313, 'mean_word_length': 4.248426353336131, 'pattern_counts': {'":': 0, '<': 39, '<?xml version=': 0, '>': 134, 'https://': 0, 'lorem ipsum': 0, 'www.': 4, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4314225', 'n_tokens_mistral': 5073, 'n_tokens_neox': 4633, 'n_words': 1349}