Commit 29ad5b6c authored by Michael Hunold's avatar Michael Hunold Committed by Linus Torvalds

[PATCH] DVB: misc driver updates

- [DVB] av7110: convert MODULE_PARM() to module_param(), replace home-brewn
  waiting stuff in osd code with wait_event_interruptible_timeout()

- [DVB] av7110: put a semaphore around osd calls to make sure they're
  properly serialized, timeout variable in arm_thread() must be int, not
  unsigned long

- [DVB] av7110: add additional OSD window types (patch by Jeremy Jones), new
  ioctl OSD_GET_CAPABILITY/OSD_CAP_MEMSIZE; returns size of OSD memory

- [DVB] av7110: put audio/video initialization into separate function
  init_av7110_av(); call this function after system initialization and after
  arm crash to restore the previous state; thanks to Soeren Sonnenburg
  <bugreports@nn7.de> for this patch.

- [DVB] av7110, budget, ttusb-budget: remove dvb i2c remains, support kernel
  i2c

- [DVB] av7110, budget: use msleep() instead of my_wait(), thanks to Kernel
  Janitors/Nishanth Aravamudan <nacc@us.ibm.com>

- [DVB] av7110, budget: fix videodev has no release callback

- [DVB] av7110: more sparse annotiations

- [DVB] budget: add support for TerraTec Cinergy 1200 DVB-S

- [DVB] budget: fix race condition in irq handler

- [DVB] skystar2, av7110, ttusb-budget, budget: make i2c
  client_(un)register() functions static
Signed-off-by: default avatarMichael Hunold <hunold@linuxtv.org>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 7cd893fd
...@@ -2236,7 +2236,7 @@ static int flexcop_diseqc_ioctl(struct dvb_frontend *fe, unsigned int cmd, void ...@@ -2236,7 +2236,7 @@ static int flexcop_diseqc_ioctl(struct dvb_frontend *fe, unsigned int cmd, void
} }
int client_register(struct i2c_client *client) static int client_register(struct i2c_client *client)
{ {
struct adapter *adapter = (struct adapter*)i2c_get_adapdata(client->adapter); struct adapter *adapter = (struct adapter*)i2c_get_adapdata(client->adapter);
...@@ -2247,7 +2247,7 @@ int client_register(struct i2c_client *client) ...@@ -2247,7 +2247,7 @@ int client_register(struct i2c_client *client)
return 0; return 0;
} }
int client_unregister(struct i2c_client *client) static int client_unregister(struct i2c_client *client)
{ {
struct adapter *adapter = (struct adapter*)i2c_get_adapdata(client->adapter); struct adapter *adapter = (struct adapter*)i2c_get_adapdata(client->adapter);
......
...@@ -41,6 +41,7 @@ ...@@ -41,6 +41,7 @@
#include <linux/smp_lock.h> #include <linux/smp_lock.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/moduleparam.h>
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/types.h> #include <linux/types.h>
#include <linux/fcntl.h> #include <linux/fcntl.h>
...@@ -50,18 +51,14 @@ ...@@ -50,18 +51,14 @@
#include <linux/vmalloc.h> #include <linux/vmalloc.h>
#include <linux/firmware.h> #include <linux/firmware.h>
#include <linux/crc32.h> #include <linux/crc32.h>
#include <linux/i2c.h>
#include <asm/system.h> #include <asm/system.h>
#include <asm/semaphore.h> #include <asm/semaphore.h>
#include <linux/dvb/frontend.h> #include <linux/dvb/frontend.h>
#include "dvb_i2c.h"
#include "dvb_frontend.h" #include "dvb_frontend.h"
#include "dvb_functions.h"
#define DEBUG_VARIABLE av7110_debug
#include "ttpci-eeprom.h" #include "ttpci-eeprom.h"
#include "av7110.h" #include "av7110.h"
...@@ -70,26 +67,93 @@ ...@@ -70,26 +67,93 @@
#include "av7110_ca.h" #include "av7110_ca.h"
#include "av7110_ipack.h" #include "av7110_ipack.h"
static int av7110_debug;
static void restart_feeds(struct av7110 *av7110);
int av7110_debug = 0;
static int vidmode=CVBS_RGB_OUT; static int vidmode=CVBS_RGB_OUT;
static int pids_off; static int pids_off;
static int adac=DVB_ADAC_TI; static int adac=DVB_ADAC_TI;
static int hw_sections = 0; static int hw_sections;
static int rgb_on = 0; static int rgb_on;
static int volume = 255;
module_param_named(debug, av7110_debug, int, 0644);
MODULE_PARM_DESC(av7110_debug, "Turn on/off debugging (default:off).");
module_param(vidmode, int, 0444);
MODULE_PARM_DESC(vidmode,"analog video out: 0 off, 1 CVBS+RGB (default), 2 CVBS+YC, 3 YC");
module_param(pids_off, int, 0444);
MODULE_PARM_DESC(pids_off,"clear video/audio/PCR PID filters when demux is closed");
module_param(adac, int, 0444);
MODULE_PARM_DESC(adac,"audio DAC type: 0 TI, 1 CRYSTAL, 2 MSP (use if autodetection fails)");
module_param(hw_sections, int, 0444);
MODULE_PARM_DESC(hw_sections, "0 use software section filter, 1 use hardware");
module_param(rgb_on, int, 0444);
MODULE_PARM_DESC(rgb_on, "For Siemens DVB-C cards only: Enable RGB control"
" signal on SCART pin 16 to switch SCART video mode from CVBS to RGB");
module_param(volume, int, 0444);
MODULE_PARM_DESC(volume, "initial volume: default 255 (range 0-255)");
static void restart_feeds(struct av7110 *av7110);
int av7110_num = 0; int av7110_num = 0;
static void init_av7110_av(struct av7110 *av7110)
{
struct saa7146_dev *dev=av7110->dev;
/* set internal volume control to maximum */
av7110->adac_type = DVB_ADAC_TI;
av7110_set_volume(av7110, av7110->mixer.volume_left, av7110->mixer.volume_right);
av7710_set_video_mode(av7110, vidmode);
/* handle different card types */
/* remaining inits according to card and frontend type */
av7110->has_analog_tuner = 0;
av7110->current_input = 0;
if (i2c_writereg(av7110, 0x20, 0x00, 0x00) == 1) {
printk ("av7110(%d): Crystal audio DAC detected\n",
av7110->dvb_adapter->num);
av7110->adac_type = DVB_ADAC_CRYSTAL;
i2c_writereg(av7110, 0x20, 0x01, 0xd2);
i2c_writereg(av7110, 0x20, 0x02, 0x49);
i2c_writereg(av7110, 0x20, 0x03, 0x00);
i2c_writereg(av7110, 0x20, 0x04, 0x00);
/**
* some special handling for the Siemens DVB-C cards...
*/
} else if (0 == av7110_init_analog_module(av7110)) {
/* done. */
}
else if (dev->pci->subsystem_vendor == 0x110a) {
printk("av7110(%d): DVB-C w/o analog module detected\n",
av7110->dvb_adapter->num);
av7110->adac_type = DVB_ADAC_NONE;
}
else {
av7110->adac_type = adac;
printk("av7110(%d): adac type set to %d\n",
av7110->dvb_adapter->num, av7110->adac_type);
}
if (av7110->adac_type == DVB_ADAC_NONE || av7110->adac_type == DVB_ADAC_MSP) {
// switch DVB SCART on
av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, MainSwitch, 1, 0);
av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, ADSwitch, 1, 1);
if (rgb_on)
saa7146_setgpio(dev, 1, SAA7146_GPIO_OUTHI); // RGB on, SCART pin 16
//saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO); // SCARTpin 8
}
av7110_set_volume(av7110, av7110->mixer.volume_left, av7110->mixer.volume_right);
av7110_setup_irc_config(av7110, 0);
}
static void recover_arm(struct av7110 *av7110) static void recover_arm(struct av7110 *av7110)
{ {
DEB_EE(("av7110: %p\n",av7110)); DEB_EE(("av7110: %p\n",av7110));
av7110_bootarm(av7110); av7110_bootarm(av7110);
dvb_delay(100); msleep(100);
restart_feeds(av7110); restart_feeds(av7110);
av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, SetIR, 1, av7110->ir_config); av7110_fw_cmd(av7110, COMTYPE_PIDFILTER, SetIR, 1, av7110->ir_config);
} }
...@@ -106,12 +170,16 @@ static void arm_error(struct av7110 *av7110) ...@@ -106,12 +170,16 @@ static void arm_error(struct av7110 *av7110)
static int arm_thread(void *data) static int arm_thread(void *data)
{ {
struct av7110 *av7110 = data; struct av7110 *av7110 = data;
unsigned long timeout;
u16 newloops = 0; u16 newloops = 0;
int timeout;
DEB_EE(("av7110: %p\n",av7110)); DEB_EE(("av7110: %p\n",av7110));
dvb_kernel_thread_setup ("arm_mon"); lock_kernel ();
daemonize ("arm_mon");
sigfillset (&current->blocked);
unlock_kernel ();
av7110->arm_thread = current; av7110->arm_thread = current;
while (1) { while (1) {
...@@ -135,6 +203,9 @@ static int arm_thread(void *data) ...@@ -135,6 +203,9 @@ static int arm_thread(void *data)
av7110->dvb_adapter->num); av7110->dvb_adapter->num);
arm_error(av7110); arm_error(av7110);
av7710_set_video_mode(av7110, vidmode);
init_av7110_av(av7110);
if (down_interruptible(&av7110->dcomlock)) if (down_interruptible(&av7110->dcomlock))
break; break;
...@@ -638,6 +709,8 @@ static int dvb_osd_ioctl(struct inode *inode, struct file *file, ...@@ -638,6 +709,8 @@ static int dvb_osd_ioctl(struct inode *inode, struct file *file,
if (cmd == OSD_SEND_CMD) if (cmd == OSD_SEND_CMD)
return av7110_osd_cmd(av7110, (osd_cmd_t *) parg); return av7110_osd_cmd(av7110, (osd_cmd_t *) parg);
if (cmd == OSD_GET_CAPABILITY)
return av7110_osd_capability(av7110, (osd_cap_t *) parg);
return -EINVAL; return -EINVAL;
} }
...@@ -1203,19 +1276,17 @@ static void dvb_unregister(struct av7110 *av7110) ...@@ -1203,19 +1276,17 @@ static void dvb_unregister(struct av7110 *av7110)
int i2c_writereg(struct av7110 *av7110, u8 id, u8 reg, u8 val) int i2c_writereg(struct av7110 *av7110, u8 id, u8 reg, u8 val)
{ {
u8 msg[2] = { reg, val }; u8 msg[2] = { reg, val };
struct dvb_i2c_bus *i2c = av7110->i2c_bus;
struct i2c_msg msgs; struct i2c_msg msgs;
msgs.flags = 0; msgs.flags = 0;
msgs.addr = id / 2; msgs.addr = id / 2;
msgs.len = 2; msgs.len = 2;
msgs.buf = msg; msgs.buf = msg;
return i2c->xfer(i2c, &msgs, 1); return i2c_transfer(&av7110->i2c_adap, &msgs, 1);
} }
u8 i2c_readreg(struct av7110 *av7110, u8 id, u8 reg) u8 i2c_readreg(struct av7110 *av7110, u8 id, u8 reg)
{ {
struct dvb_i2c_bus *i2c = av7110->i2c_bus;
u8 mm1[] = {0x00}; u8 mm1[] = {0x00};
u8 mm2[] = {0x00}; u8 mm2[] = {0x00};
struct i2c_msg msgs[2]; struct i2c_msg msgs[2];
...@@ -1226,17 +1297,11 @@ u8 i2c_readreg(struct av7110 *av7110, u8 id, u8 reg) ...@@ -1226,17 +1297,11 @@ u8 i2c_readreg(struct av7110 *av7110, u8 id, u8 reg)
mm1[0] = reg; mm1[0] = reg;
msgs[0].len = 1; msgs[1].len = 1; msgs[0].len = 1; msgs[1].len = 1;
msgs[0].buf = mm1; msgs[1].buf = mm2; msgs[0].buf = mm1; msgs[1].buf = mm2;
i2c->xfer(i2c, msgs, 2); i2c_transfer(&av7110->i2c_adap, msgs, 2);
return mm2[0]; return mm2[0];
} }
static int master_xfer(struct dvb_i2c_bus *i2c, const struct i2c_msg msgs[], int num)
{
struct saa7146_dev *dev = i2c->data;
return saa7146_i2c_transfer(dev, msgs, num, 6);
}
/**************************************************************************** /****************************************************************************
* INITIALIZATION * INITIALIZATION
****************************************************************************/ ****************************************************************************/
...@@ -1310,27 +1375,66 @@ static int get_firmware(struct av7110* av7110) ...@@ -1310,27 +1375,66 @@ static int get_firmware(struct av7110* av7110)
/* request the av7110 firmware, this will block until someone uploads it */ /* request the av7110 firmware, this will block until someone uploads it */
ret = request_firmware(&fw, "dvb-ttpci-01.fw", &av7110->dev->pci->dev); ret = request_firmware(&fw, "dvb-ttpci-01.fw", &av7110->dev->pci->dev);
if (ret) { if (ret) {
printk("dvb-ttpci: cannot request firmware!\n"); if (ret == -ENOENT) {
printk(KERN_ERR "dvb-ttpci: could not load firmware,"
" file not found: dvb-ttpci-01.fw\n");
printk(KERN_ERR "dvb-ttpci: usually this should be in"
" /usr/lib/hotplug/firmware\n");
printk(KERN_ERR "dvb-ttpci: and can be downloaded here"
" http://www.linuxtv.org/download/dvb/firmware/\n");
} else
printk(KERN_ERR "dvb-ttpci: cannot request firmware"
" (error %i)\n", ret);
return -EINVAL; return -EINVAL;
} }
if (fw->size <= 200000) { if (fw->size <= 200000) {
printk("dvb-ttpci: this firmware is way too small.\n"); printk("dvb-ttpci: this firmware is way too small.\n");
release_firmware(fw);
return -EINVAL; return -EINVAL;
} }
/* check if the firmware is available */ /* check if the firmware is available */
av7110->bin_fw = (unsigned char*) vmalloc(fw->size); av7110->bin_fw = (unsigned char*) vmalloc(fw->size);
if (NULL == av7110->bin_fw) { if (NULL == av7110->bin_fw) {
DEB_D(("out of memory\n")); DEB_D(("out of memory\n"));
release_firmware(fw);
return -ENOMEM; return -ENOMEM;
} }
memcpy(av7110->bin_fw, fw->data, fw->size); memcpy(av7110->bin_fw, fw->data, fw->size);
av7110->size_fw = fw->size; av7110->size_fw = fw->size;
if ((ret = check_firmware(av7110))) if ((ret = check_firmware(av7110)))
vfree(av7110->bin_fw); vfree(av7110->bin_fw);
release_firmware(fw);
return ret; return ret;
} }
#endif #endif
static int client_register(struct i2c_client *client)
{
struct saa7146_dev *dev = (struct saa7146_dev*)i2c_get_adapdata(client->adapter);
struct av7110 *av7110 = (struct av7110*)dev->ext_priv;
/* fixme: check for "type" (ie. frontend type) */
if (client->driver->command)
return client->driver->command(client, FE_REGISTER, av7110->dvb_adapter);
return 0;
}
static int client_unregister(struct i2c_client *client)
{
struct saa7146_dev *dev = (struct saa7146_dev*)i2c_get_adapdata(client->adapter);
struct av7110 *av7110 = (struct av7110*)dev->ext_priv;
/* fixme: check for "type" (ie. frontend type) */
if (client->driver->command)
return client->driver->command(client, FE_UNREGISTER, av7110->dvb_adapter);
return 0;
}
static int av7110_attach(struct saa7146_dev* dev, struct saa7146_pci_extension_data *pci_ext) static int av7110_attach(struct saa7146_dev* dev, struct saa7146_pci_extension_data *pci_ext)
{ {
struct av7110 *av7110 = NULL; struct av7110 *av7110 = NULL;
...@@ -1361,18 +1465,26 @@ static int av7110_attach(struct saa7146_dev* dev, struct saa7146_pci_extension_d ...@@ -1361,18 +1465,26 @@ static int av7110_attach(struct saa7146_dev* dev, struct saa7146_pci_extension_d
get recognized before the main driver is fully loaded */ get recognized before the main driver is fully loaded */
saa7146_write(dev, GPIO_CTRL, 0x500000); saa7146_write(dev, GPIO_CTRL, 0x500000);
saa7146_i2c_adapter_prepare(dev, NULL, 0, SAA7146_I2C_BUS_BIT_RATE_120); /* 275 kHz */ av7110->i2c_adap = (struct i2c_adapter) {
.client_register = client_register,
.client_unregister = client_unregister,
#ifdef I2C_ADAP_CLASS_TV_DIGITAL
.class = I2C_ADAP_CLASS_TV_DIGITAL,
#else
.class = I2C_CLASS_TV_DIGITAL,
#endif
};
strlcpy(av7110->i2c_adap.name, pci_ext->ext_priv, sizeof(av7110->i2c_adap.name));
av7110->i2c_bus = dvb_register_i2c_bus (master_xfer, dev, saa7146_i2c_adapter_prepare(dev, &av7110->i2c_adap, SAA7146_I2C_BUS_BIT_RATE_120); /* 275 kHz */
av7110->dvb_adapter, 0);
if (!av7110->i2c_bus) { if (i2c_add_adapter(&av7110->i2c_adap) < 0) {
dvb_unregister_adapter (av7110->dvb_adapter); dvb_unregister_adapter (av7110->dvb_adapter);
kfree(av7110); kfree(av7110);
return -ENOMEM; return -ENOMEM;
} }
ttpci_eeprom_parse_mac(av7110->i2c_bus); ttpci_eeprom_parse_mac(&av7110->i2c_adap, av7110->dvb_adapter->proposed_mac);
saa7146_write(dev, PCI_BT_V1, 0x1c00101f); saa7146_write(dev, PCI_BT_V1, 0x1c00101f);
saa7146_write(dev, BCS_CTRL, 0x80400040); saa7146_write(dev, BCS_CTRL, 0x80400040);
...@@ -1399,6 +1511,7 @@ static int av7110_attach(struct saa7146_dev* dev, struct saa7146_pci_extension_d ...@@ -1399,6 +1511,7 @@ static int av7110_attach(struct saa7146_dev* dev, struct saa7146_pci_extension_d
/* default OSD window */ /* default OSD window */
av7110->osdwin=1; av7110->osdwin=1;
sema_init(&av7110->osd_sema, 1);
/* ARM "watchdog" */ /* ARM "watchdog" */
init_waitqueue_head(&av7110->arm_wait); init_waitqueue_head(&av7110->arm_wait);
...@@ -1443,54 +1556,12 @@ static int av7110_attach(struct saa7146_dev* dev, struct saa7146_pci_extension_d ...@@ -1443,54 +1556,12 @@ static int av7110_attach(struct saa7146_dev* dev, struct saa7146_pci_extension_d
goto err2; goto err2;
} }
/* set internal volume control to maximum */ /* set initial volume in mixer struct */
av7110->adac_type = DVB_ADAC_TI; av7110->mixer.volume_left = volume;
av7110_set_volume(av7110, 0xff, 0xff); av7110->mixer.volume_right = volume;
av7710_set_video_mode(av7110, vidmode);
/* handle different card types */
/* remaining inits according to card and frontend type */
av7110->has_analog_tuner = 0;
av7110->current_input = 0;
if (i2c_writereg(av7110, 0x20, 0x00, 0x00)==1) {
printk ("av7110(%d): Crystal audio DAC detected\n",
av7110->dvb_adapter->num);
av7110->adac_type = DVB_ADAC_CRYSTAL;
i2c_writereg(av7110, 0x20, 0x01, 0xd2);
i2c_writereg(av7110, 0x20, 0x02, 0x49);
i2c_writereg(av7110, 0x20, 0x03, 0x00);
i2c_writereg(av7110, 0x20, 0x04, 0x00);
/**
* some special handling for the Siemens DVB-C cards...
*/
} else if (0 == av7110_init_analog_module(av7110)) {
/* done. */
}
else if (dev->pci->subsystem_vendor == 0x110a) {
printk("av7110(%d): DVB-C w/o analog module detected\n",
av7110->dvb_adapter->num);
av7110->adac_type = DVB_ADAC_NONE;
}
else {
av7110->adac_type = adac;
printk("av7110(%d): adac type set to %d\n",
av7110->dvb_adapter->num, av7110->adac_type);
}
if (av7110->adac_type == DVB_ADAC_NONE || av7110->adac_type == DVB_ADAC_MSP) {
// switch DVB SCART on
av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, MainSwitch, 1, 0);
av7110_fw_cmd(av7110, COMTYPE_AUDIODAC, ADSwitch, 1, 1);
if (rgb_on)
saa7146_setgpio(dev, 1, SAA7146_GPIO_OUTHI); // RGB on, SCART pin 16
//saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO); // SCARTpin 8
}
av7110_set_volume(av7110, 0xff, 0xff); init_av7110_av(av7110);
av7110_setup_irc_config (av7110, 0);
av7110_register(av7110); av7110_register(av7110);
/* special case DVB-C: these cards have an analog tuner /* special case DVB-C: these cards have an analog tuner
...@@ -1510,13 +1581,12 @@ static int av7110_attach(struct saa7146_dev* dev, struct saa7146_pci_extension_d ...@@ -1510,13 +1581,12 @@ static int av7110_attach(struct saa7146_dev* dev, struct saa7146_pci_extension_d
av7110->arm_rmmod = 1; av7110->arm_rmmod = 1;
wake_up_interruptible(&av7110->arm_wait); wake_up_interruptible(&av7110->arm_wait);
while (av7110->arm_thread) while (av7110->arm_thread)
dvb_delay(1); msleep(1);
err2: err2:
av7110_ca_exit(av7110); av7110_ca_exit(av7110);
av7110_av_exit(av7110); av7110_av_exit(av7110);
err: err:
dvb_unregister_i2c_bus (master_xfer,av7110->i2c_bus->adapter, i2c_del_adapter(&av7110->i2c_adap);
av7110->i2c_bus->id);
dvb_unregister_adapter (av7110->dvb_adapter); dvb_unregister_adapter (av7110->dvb_adapter);
...@@ -1546,7 +1616,7 @@ static int av7110_detach (struct saa7146_dev* saa) ...@@ -1546,7 +1616,7 @@ static int av7110_detach (struct saa7146_dev* saa)
wake_up_interruptible(&av7110->arm_wait); wake_up_interruptible(&av7110->arm_wait);
while (av7110->arm_thread) while (av7110->arm_thread)
dvb_delay(1); msleep(1);
dvb_unregister(av7110); dvb_unregister(av7110);
...@@ -1563,7 +1633,8 @@ static int av7110_detach (struct saa7146_dev* saa) ...@@ -1563,7 +1633,8 @@ static int av7110_detach (struct saa7146_dev* saa)
pci_free_consistent(saa->pci, 8192, av7110->debi_virt, pci_free_consistent(saa->pci, 8192, av7110->debi_virt,
av7110->debi_bus); av7110->debi_bus);
dvb_unregister_i2c_bus (master_xfer,av7110->i2c_bus->adapter, av7110->i2c_bus->id); i2c_del_adapter(&av7110->i2c_adap);
dvb_unregister_adapter (av7110->dvb_adapter); dvb_unregister_adapter (av7110->dvb_adapter);
av7110_num--; av7110_num--;
...@@ -1602,7 +1673,7 @@ static struct saa7146_pci_extension_data x_var = { \ ...@@ -1602,7 +1673,7 @@ static struct saa7146_pci_extension_data x_var = { \
MAKE_AV7110_INFO(fs_1_5, "Siemens cable card PCI rev1.5"); MAKE_AV7110_INFO(fs_1_5, "Siemens cable card PCI rev1.5");
MAKE_AV7110_INFO(fs_1_3, "Siemens/Technotrend/Hauppauge PCI rev1.3"); MAKE_AV7110_INFO(fs_1_3, "Siemens/Technotrend/Hauppauge PCI rev1.3");
MAKE_AV7110_INFO(tt_1_6, "Technotrend/Hauppauge PCI rev1.3 or 1.6"); MAKE_AV7110_INFO(tt_1_6, "Technotrend/Hauppauge PCI rev1.3 or 1.6");
MAKE_AV7110_INFO(tt_2_1, "Technotrend/Hauppauge PCI rev2.1"); MAKE_AV7110_INFO(tt_2_1, "Technotrend/Hauppauge PCI rev2.1 or 2.2");
MAKE_AV7110_INFO(tt_t, "Technotrend/Hauppauge PCI DVB-T"); MAKE_AV7110_INFO(tt_t, "Technotrend/Hauppauge PCI DVB-T");
MAKE_AV7110_INFO(unkwn0, "Technotrend/Hauppauge PCI rev?(unknown0)?"); MAKE_AV7110_INFO(unkwn0, "Technotrend/Hauppauge PCI rev?(unknown0)?");
MAKE_AV7110_INFO(unkwn1, "Technotrend/Hauppauge PCI rev?(unknown1)?"); MAKE_AV7110_INFO(unkwn1, "Technotrend/Hauppauge PCI rev?(unknown1)?");
...@@ -1684,15 +1755,3 @@ MODULE_DESCRIPTION("driver for the SAA7146 based AV110 PCI DVB cards by " ...@@ -1684,15 +1755,3 @@ MODULE_DESCRIPTION("driver for the SAA7146 based AV110 PCI DVB cards by "
MODULE_AUTHOR("Ralph Metzler, Marcus Metzler, others"); MODULE_AUTHOR("Ralph Metzler, Marcus Metzler, others");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
MODULE_PARM(av7110_debug,"i");
MODULE_PARM(vidmode,"i");
MODULE_PARM_DESC(vidmode,"analog video out: 0 off, 1 CVBS+RGB (default), 2 CVBS+YC, 3 YC");
MODULE_PARM(pids_off,"i");
MODULE_PARM_DESC(pids_off,"clear video/audio/PCR PID filters when demux is closed");
MODULE_PARM(adac,"i");
MODULE_PARM_DESC(adac,"audio DAC type: 0 TI, 1 CRYSTAL, 2 MSP (use if autodetection fails)");
MODULE_PARM(hw_sections, "i");
MODULE_PARM_DESC(hw_sections, "0 use software section filter, 1 use hardware");
MODULE_PARM(rgb_on, "i");
MODULE_PARM_DESC(rgb_on, "For Siemens DVB-C cards only: Enable RGB control"
" signal on SCART pin 16 to switch SCART video mode from CVBS to RGB");
...@@ -4,13 +4,12 @@ ...@@ -4,13 +4,12 @@
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/socket.h> #include <linux/socket.h>
#include <linux/netdevice.h> #include <linux/netdevice.h>
#include <linux/i2c.h>
#ifdef CONFIG_DEVFS_FS #ifdef CONFIG_DEVFS_FS
#include <linux/devfs_fs_kernel.h> #include <linux/devfs_fs_kernel.h>
#endif #endif
#include <media/saa7146_vv.h>
#include <linux/dvb/video.h> #include <linux/dvb/video.h>
#include <linux/dvb/audio.h> #include <linux/dvb/audio.h>
#include <linux/dvb/dmx.h> #include <linux/dvb/dmx.h>
...@@ -26,6 +25,7 @@ ...@@ -26,6 +25,7 @@
#include "dvb_net.h" #include "dvb_net.h"
#include "dvb_ringbuffer.h" #include "dvb_ringbuffer.h"
#include <media/saa7146_vv.h>
#define MAXFILT 32 #define MAXFILT 32
...@@ -60,12 +60,13 @@ struct av7110 { ...@@ -60,12 +60,13 @@ struct av7110 {
struct dvb_device dvb_dev; struct dvb_device dvb_dev;
struct dvb_net dvb_net; struct dvb_net dvb_net;
struct video_device v4l_dev; struct video_device *v4l_dev;
struct video_device vbi_dev; struct video_device *vbi_dev;
struct saa7146_dev *dev; struct saa7146_dev *dev;
struct dvb_i2c_bus *i2c_bus; struct i2c_adapter i2c_adap;
char *card_name; char *card_name;
/* support for analog module of dvb-c */ /* support for analog module of dvb-c */
...@@ -127,7 +128,7 @@ struct av7110 { ...@@ -127,7 +128,7 @@ struct av7110 {
int osdwin; /* currently active window */ int osdwin; /* currently active window */
u16 osdbpp[8]; u16 osdbpp[8];
struct semaphore osd_sema;
/* CA */ /* CA */
...@@ -187,6 +188,7 @@ struct av7110 { ...@@ -187,6 +188,7 @@ struct av7110 {
struct dvb_ringbuffer ci_rbuffer; struct dvb_ringbuffer ci_rbuffer;
struct dvb_ringbuffer ci_wbuffer; struct dvb_ringbuffer ci_wbuffer;
struct audio_mixer mixer;
struct dvb_adapter *dvb_adapter; struct dvb_adapter *dvb_adapter;
struct dvb_device *video_dev; struct dvb_device *video_dev;
......
...@@ -37,14 +37,10 @@ ...@@ -37,14 +37,10 @@
#include <linux/smp_lock.h> #include <linux/smp_lock.h>
#include <linux/fs.h> #include <linux/fs.h>
#define DEBUG_VARIABLE av7110_debug
extern int av7110_debug;
#include "av7110.h" #include "av7110.h"
#include "av7110_hw.h" #include "av7110_hw.h"
#include "av7110_av.h" #include "av7110_av.h"
#include "av7110_ipack.h" #include "av7110_ipack.h"
#include "dvb_functions.h"
/* MPEG-2 (ISO 13818 / H.222.0) stream types */ /* MPEG-2 (ISO 13818 / H.222.0) stream types */
#define PROG_STREAM_MAP 0xBC #define PROG_STREAM_MAP 0xBC
...@@ -292,6 +288,9 @@ int av7110_set_volume(struct av7110 *av7110, int volleft, int volright) ...@@ -292,6 +288,9 @@ int av7110_set_volume(struct av7110 *av7110, int volleft, int volright)
DEB_EE(("av7110: %p\n", av7110)); DEB_EE(("av7110: %p\n", av7110));
av7110->mixer.volume_left = volleft;
av7110->mixer.volume_right = volright;
switch (av7110->adac_type) { switch (av7110->adac_type) {
case DVB_ADAC_TI: case DVB_ADAC_TI:
volleft = (volleft * 256) / 1036; volleft = (volleft * 256) / 1036;
......
...@@ -38,13 +38,8 @@ ...@@ -38,13 +38,8 @@
#include <linux/byteorder/swabb.h> #include <linux/byteorder/swabb.h>
#include <linux/smp_lock.h> #include <linux/smp_lock.h>
#define DEBUG_VARIABLE av7110_debug
extern int av7110_debug;
#include "dvb_i2c.h"
#include "av7110.h" #include "av7110.h"
#include "av7110_hw.h" #include "av7110_hw.h"
#include "dvb_functions.h"
void CI_handle(struct av7110 *av7110, u8 *data, u16 len) void CI_handle(struct av7110 *av7110, u8 *data, u16 len)
......
...@@ -38,12 +38,8 @@ ...@@ -38,12 +38,8 @@
#include <linux/smp_lock.h> #include <linux/smp_lock.h>
#include <linux/fs.h> #include <linux/fs.h>
#define DEBUG_VARIABLE av7110_debug
extern int av7110_debug;
#include "av7110.h" #include "av7110.h"
#include "av7110_hw.h" #include "av7110_hw.h"
#include "dvb_functions.h"
/**************************************************************************** /****************************************************************************
* DEBI functions * DEBI functions
...@@ -106,7 +102,7 @@ void av7110_reset_arm(struct av7110 *av7110) ...@@ -106,7 +102,7 @@ void av7110_reset_arm(struct av7110 *av7110)
saa7146_write(av7110->dev, ISR, (MASK_19 | MASK_03)); saa7146_write(av7110->dev, ISR, (MASK_19 | MASK_03));
saa7146_setgpio(av7110->dev, RESET_LINE, SAA7146_GPIO_OUTHI); saa7146_setgpio(av7110->dev, RESET_LINE, SAA7146_GPIO_OUTHI);
dvb_delay(30); /* the firmware needs some time to initialize */ msleep(30); /* the firmware needs some time to initialize */
ARM_ResetMailBox(av7110); ARM_ResetMailBox(av7110);
...@@ -268,7 +264,7 @@ int av7110_bootarm(struct av7110 *av7110) ...@@ -268,7 +264,7 @@ int av7110_bootarm(struct av7110 *av7110)
return -1; return -1;
} }
saa7146_setgpio(dev, RESET_LINE, SAA7146_GPIO_OUTHI); saa7146_setgpio(dev, RESET_LINE, SAA7146_GPIO_OUTHI);
dvb_delay(30); /* the firmware needs some time to initialize */ msleep(30); /* the firmware needs some time to initialize */
//ARM_ClearIrq(av7110); //ARM_ClearIrq(av7110);
ARM_ResetMailBox(av7110); ARM_ResetMailBox(av7110);
...@@ -302,7 +298,7 @@ int __av7110_send_fw_cmd(struct av7110 *av7110, u16* buf, int length) ...@@ -302,7 +298,7 @@ int __av7110_send_fw_cmd(struct av7110 *av7110, u16* buf, int length)
start = jiffies; start = jiffies;
while (rdebi(av7110, DEBINOSWAP, COMMAND, 0, 2 )) { while (rdebi(av7110, DEBINOSWAP, COMMAND, 0, 2 )) {
dvb_delay(1); msleep(1);
if (time_after(jiffies, start + ARM_WAIT_FREE)) { if (time_after(jiffies, start + ARM_WAIT_FREE)) {
printk(KERN_ERR "%s: timeout waiting for COMMAND idle\n", __FUNCTION__); printk(KERN_ERR "%s: timeout waiting for COMMAND idle\n", __FUNCTION__);
return -1; return -1;
...@@ -312,7 +308,7 @@ int __av7110_send_fw_cmd(struct av7110 *av7110, u16* buf, int length) ...@@ -312,7 +308,7 @@ int __av7110_send_fw_cmd(struct av7110 *av7110, u16* buf, int length)
#ifndef _NOHANDSHAKE #ifndef _NOHANDSHAKE
start = jiffies; start = jiffies;
while (rdebi(av7110, DEBINOSWAP, HANDSHAKE_REG, 0, 2 )) { while (rdebi(av7110, DEBINOSWAP, HANDSHAKE_REG, 0, 2 )) {
dvb_delay(1); msleep(1);
if (time_after(jiffies, start + ARM_WAIT_SHAKE)) { if (time_after(jiffies, start + ARM_WAIT_SHAKE)) {
printk(KERN_ERR "%s: timeout waiting for HANDSHAKE_REG\n", __FUNCTION__); printk(KERN_ERR "%s: timeout waiting for HANDSHAKE_REG\n", __FUNCTION__);
return -1; return -1;
...@@ -322,7 +318,7 @@ int __av7110_send_fw_cmd(struct av7110 *av7110, u16* buf, int length) ...@@ -322,7 +318,7 @@ int __av7110_send_fw_cmd(struct av7110 *av7110, u16* buf, int length)
start = jiffies; start = jiffies;
while (rdebi(av7110, DEBINOSWAP, MSGSTATE, 0, 2) & OSDQFull) { while (rdebi(av7110, DEBINOSWAP, MSGSTATE, 0, 2) & OSDQFull) {
dvb_delay(1); msleep(1);
if (time_after(jiffies, start + ARM_WAIT_OSD)) { if (time_after(jiffies, start + ARM_WAIT_OSD)) {
printk(KERN_ERR "%s: timeout waiting for !OSDQFull\n", __FUNCTION__); printk(KERN_ERR "%s: timeout waiting for !OSDQFull\n", __FUNCTION__);
return -1; return -1;
...@@ -341,7 +337,7 @@ int __av7110_send_fw_cmd(struct av7110 *av7110, u16* buf, int length) ...@@ -341,7 +337,7 @@ int __av7110_send_fw_cmd(struct av7110 *av7110, u16* buf, int length)
#ifdef COM_DEBUG #ifdef COM_DEBUG
start = jiffies; start = jiffies;
while (rdebi(av7110, DEBINOSWAP, COMMAND, 0, 2 )) { while (rdebi(av7110, DEBINOSWAP, COMMAND, 0, 2 )) {
dvb_delay(1); msleep(1);
if (time_after(jiffies, start + ARM_WAIT_FREE)) { if (time_after(jiffies, start + ARM_WAIT_FREE)) {
printk(KERN_ERR "%s: timeout waiting for COMMAND to complete\n", printk(KERN_ERR "%s: timeout waiting for COMMAND to complete\n",
__FUNCTION__); __FUNCTION__);
...@@ -458,7 +454,7 @@ int av7110_fw_request(struct av7110 *av7110, u16 *request_buf, ...@@ -458,7 +454,7 @@ int av7110_fw_request(struct av7110 *av7110, u16 *request_buf,
start = jiffies; start = jiffies;
while (rdebi(av7110, DEBINOSWAP, COMMAND, 0, 2)) { while (rdebi(av7110, DEBINOSWAP, COMMAND, 0, 2)) {
#ifdef _NOHANDSHAKE #ifdef _NOHANDSHAKE
dvb_delay(1); msleep(1);
#endif #endif
if (time_after(jiffies, start + ARM_WAIT_FREE)) { if (time_after(jiffies, start + ARM_WAIT_FREE)) {
printk("%s: timeout waiting for COMMAND to complete\n", __FUNCTION__); printk("%s: timeout waiting for COMMAND to complete\n", __FUNCTION__);
...@@ -470,7 +466,7 @@ int av7110_fw_request(struct av7110 *av7110, u16 *request_buf, ...@@ -470,7 +466,7 @@ int av7110_fw_request(struct av7110 *av7110, u16 *request_buf,
#ifndef _NOHANDSHAKE #ifndef _NOHANDSHAKE
start = jiffies; start = jiffies;
while (rdebi(av7110, DEBINOSWAP, HANDSHAKE_REG, 0, 2 )) { while (rdebi(av7110, DEBINOSWAP, HANDSHAKE_REG, 0, 2 )) {
dvb_delay(1); msleep(1);
if (time_after(jiffies, start + ARM_WAIT_SHAKE)) { if (time_after(jiffies, start + ARM_WAIT_SHAKE)) {
printk(KERN_ERR "%s: timeout waiting for HANDSHAKE_REG\n", __FUNCTION__); printk(KERN_ERR "%s: timeout waiting for HANDSHAKE_REG\n", __FUNCTION__);
up(&av7110->dcomlock); up(&av7110->dcomlock);
...@@ -630,7 +626,7 @@ static int FlushText(struct av7110 *av7110) ...@@ -630,7 +626,7 @@ static int FlushText(struct av7110 *av7110)
return -ERESTARTSYS; return -ERESTARTSYS;
start = jiffies; start = jiffies;
while (rdebi(av7110, DEBINOSWAP, BUFF1_BASE, 0, 2)) { while (rdebi(av7110, DEBINOSWAP, BUFF1_BASE, 0, 2)) {
dvb_delay(1); msleep(1);
if (time_after(jiffies, start + ARM_WAIT_OSD)) { if (time_after(jiffies, start + ARM_WAIT_OSD)) {
printk(KERN_ERR "%s: timeout waiting for BUFF1_BASE == 0\n", printk(KERN_ERR "%s: timeout waiting for BUFF1_BASE == 0\n",
__FUNCTION__); __FUNCTION__);
...@@ -654,7 +650,7 @@ static int WriteText(struct av7110 *av7110, u8 win, u16 x, u16 y, u8* buf) ...@@ -654,7 +650,7 @@ static int WriteText(struct av7110 *av7110, u8 win, u16 x, u16 y, u8* buf)
start = jiffies; start = jiffies;
while (rdebi(av7110, DEBINOSWAP, BUFF1_BASE, 0, 2)) { while (rdebi(av7110, DEBINOSWAP, BUFF1_BASE, 0, 2)) {
dvb_delay(1); msleep(1);
if (time_after(jiffies, start + ARM_WAIT_OSD)) { if (time_after(jiffies, start + ARM_WAIT_OSD)) {
printk(KERN_ERR "%s: timeout waiting for BUFF1_BASE == 0\n", printk(KERN_ERR "%s: timeout waiting for BUFF1_BASE == 0\n",
__FUNCTION__); __FUNCTION__);
...@@ -665,7 +661,7 @@ static int WriteText(struct av7110 *av7110, u8 win, u16 x, u16 y, u8* buf) ...@@ -665,7 +661,7 @@ static int WriteText(struct av7110 *av7110, u8 win, u16 x, u16 y, u8* buf)
#ifndef _NOHANDSHAKE #ifndef _NOHANDSHAKE
start = jiffies; start = jiffies;
while (rdebi(av7110, DEBINOSWAP, HANDSHAKE_REG, 0, 2)) { while (rdebi(av7110, DEBINOSWAP, HANDSHAKE_REG, 0, 2)) {
dvb_delay(1); msleep(1);
if (time_after(jiffies, start + ARM_WAIT_SHAKE)) { if (time_after(jiffies, start + ARM_WAIT_SHAKE)) {
printk(KERN_ERR "%s: timeout waiting for HANDSHAKE_REG\n", printk(KERN_ERR "%s: timeout waiting for HANDSHAKE_REG\n",
__FUNCTION__); __FUNCTION__);
...@@ -721,7 +717,7 @@ static inline int DestroyOSDWindow(struct av7110 *av7110, u8 windownr) ...@@ -721,7 +717,7 @@ static inline int DestroyOSDWindow(struct av7110 *av7110, u8 windownr)
} }
static inline int CreateOSDWindow(struct av7110 *av7110, u8 windownr, static inline int CreateOSDWindow(struct av7110 *av7110, u8 windownr,
enum av7110_window_display_type disptype, osd_raw_window_t disptype,
u16 width, u16 height) u16 width, u16 height)
{ {
return av7110_fw_cmd(av7110, COMTYPE_OSD, WCreate, 4, return av7110_fw_cmd(av7110, COMTYPE_OSD, WCreate, 4,
...@@ -732,8 +728,8 @@ static inline int CreateOSDWindow(struct av7110 *av7110, u8 windownr, ...@@ -732,8 +728,8 @@ static inline int CreateOSDWindow(struct av7110 *av7110, u8 windownr,
static enum av7110_osd_palette_type bpp2pal[8] = { static enum av7110_osd_palette_type bpp2pal[8] = {
Pal1Bit, Pal2Bit, 0, Pal4Bit, 0, 0, 0, Pal8Bit Pal1Bit, Pal2Bit, 0, Pal4Bit, 0, 0, 0, Pal8Bit
}; };
static enum av7110_window_display_type bpp2bit[8] = { static osd_raw_window_t bpp2bit[8] = {
BITMAP1, BITMAP2, 0, BITMAP4, 0, 0, 0, BITMAP8 OSD_BITMAP1, OSD_BITMAP2, 0, OSD_BITMAP4, 0, 0, 0, OSD_BITMAP8
}; };
static inline int LoadBitmap(struct av7110 *av7110, u16 format, static inline int LoadBitmap(struct av7110 *av7110, u16 format,
...@@ -743,32 +739,26 @@ static inline int LoadBitmap(struct av7110 *av7110, u16 format, ...@@ -743,32 +739,26 @@ static inline int LoadBitmap(struct av7110 *av7110, u16 format,
int i; int i;
int d, delta; int d, delta;
u8 c; u8 c;
DECLARE_WAITQUEUE(wait, current); int ret;
DEB_EE(("av7110: %p\n", av7110)); DEB_EE(("av7110: %p\n", av7110));
if (av7110->bmp_state == BMP_LOADING) { ret = wait_event_interruptible_timeout(av7110->bmpq, av7110->bmp_state != BMP_LOADING, HZ);
add_wait_queue(&av7110->bmpq, &wait); if (ret == -ERESTARTSYS || ret == 0) {
while (1) { printk("dvb-ttpci: warning: timeout waiting in %s()\n", __FUNCTION__);
set_current_state(TASK_INTERRUPTIBLE); av7110->bmp_state = BMP_NONE;
if (av7110->bmp_state != BMP_LOADING
|| signal_pending(current))
break;
schedule();
}
set_current_state(TASK_RUNNING);
remove_wait_queue(&av7110->bmpq, &wait);
}
if (av7110->bmp_state == BMP_LOADING)
return -1; return -1;
}
BUG_ON (av7110->bmp_state == BMP_LOADING);
av7110->bmp_state = BMP_LOADING; av7110->bmp_state = BMP_LOADING;
if (format == BITMAP8) { if (format == OSD_BITMAP8) {
bpp=8; delta = 1; bpp=8; delta = 1;
} else if (format == BITMAP4) { } else if (format == OSD_BITMAP4) {
bpp=4; delta = 2; bpp=4; delta = 2;
} else if (format == BITMAP2) { } else if (format == OSD_BITMAP2) {
bpp=2; delta = 4; bpp=2; delta = 4;
} else if (format == BITMAP1) { } else if (format == OSD_BITMAP1) {
bpp=1; delta = 8; bpp=1; delta = 8;
} else { } else {
av7110->bmp_state = BMP_NONE; av7110->bmp_state = BMP_NONE;
...@@ -786,7 +776,7 @@ static inline int LoadBitmap(struct av7110 *av7110, u16 format, ...@@ -786,7 +776,7 @@ static inline int LoadBitmap(struct av7110 *av7110, u16 format,
return -1; return -1;
} }
} }
if (format != BITMAP8) { if (format != OSD_BITMAP8) {
for (i = 0; i < dx * dy / delta; i++) { for (i = 0; i < dx * dy / delta; i++) {
c = ((u8 *)av7110->bmpbuf)[1024 + i * delta + delta - 1]; c = ((u8 *)av7110->bmpbuf)[1024 + i * delta + delta - 1];
for (d = delta - 2; d >= 0; d--) { for (d = delta - 2; d >= 0; d--) {
...@@ -802,27 +792,22 @@ static inline int LoadBitmap(struct av7110 *av7110, u16 format, ...@@ -802,27 +792,22 @@ static inline int LoadBitmap(struct av7110 *av7110, u16 format,
static int BlitBitmap(struct av7110 *av7110, u16 win, u16 x, u16 y, u16 trans) static int BlitBitmap(struct av7110 *av7110, u16 win, u16 x, u16 y, u16 trans)
{ {
DECLARE_WAITQUEUE(wait, current); int ret;
DEB_EE(("av7110: %p\n", av7110)); DEB_EE(("av7110: %p\n", av7110));
if (av7110->bmp_state == BMP_NONE) BUG_ON (av7110->bmp_state == BMP_NONE);
ret = wait_event_interruptible_timeout(av7110->bmpq, av7110->bmp_state != BMP_LOADING, HZ);
if (ret == -ERESTARTSYS || ret == 0) {
printk("dvb-ttpci: warning: timeout waiting in %s()\n", __FUNCTION__);
av7110->bmp_state = BMP_NONE;
return -1; return -1;
if (av7110->bmp_state == BMP_LOADING) {
add_wait_queue(&av7110->bmpq, &wait);
while (1) {
set_current_state(TASK_INTERRUPTIBLE);
if (av7110->bmp_state != BMP_LOADING
|| signal_pending(current))
break;
schedule();
} }
set_current_state(TASK_RUNNING);
remove_wait_queue(&av7110->bmpq, &wait); BUG_ON (av7110->bmp_state != BMP_LOADED);
}
if (av7110->bmp_state == BMP_LOADED)
return av7110_fw_cmd(av7110, COMTYPE_OSD, BlitBmp, 4, win, x, y, trans); return av7110_fw_cmd(av7110, COMTYPE_OSD, BlitBmp, 4, win, x, y, trans);
return -1;
} }
static inline int ReleaseBitmap(struct av7110 *av7110) static inline int ReleaseBitmap(struct av7110 *av7110)
...@@ -865,18 +850,22 @@ static void OSDSetColor(struct av7110 *av7110, u8 color, u8 r, u8 g, u8 b, u8 bl ...@@ -865,18 +850,22 @@ static void OSDSetColor(struct av7110 *av7110, u8 color, u8 r, u8 g, u8 b, u8 bl
color, ((blend >> 4) & 0x0f)); color, ((blend >> 4) & 0x0f));
} }
static int OSDSetPalette(struct av7110 *av7110, u32 *colors, u8 first, u8 last) static int OSDSetPalette(struct av7110 *av7110, u32 __user * colors, u8 first, u8 last)
{ {
int i; int i;
int length = last - first + 1; int length = last - first + 1;
if (length * 4 > DATA_BUFF3_SIZE) if (length * 4 > DATA_BUFF3_SIZE)
return -1; return -EINVAL;
for (i = 0; i < length; i++) { for (i = 0; i < length; i++) {
u32 blend = (colors[i] & 0xF0000000) >> 4; u32 color, blend, yuv;
u32 yuv = blend ? RGB2YUV(colors[i] & 0xFF, (colors[i] >> 8) & 0xFF,
(colors[i] >> 16) & 0xFF) | blend : 0; if (get_user(color, colors + i))
return -EFAULT;
blend = (color & 0xF0000000) >> 4;
yuv = blend ? RGB2YUV(color & 0xFF, (color >> 8) & 0xFF,
(color >> 16) & 0xFF) | blend : 0;
yuv = ((yuv & 0xFFFF0000) >> 16) | ((yuv & 0x0000FFFF) << 16); yuv = ((yuv & 0xFFFF0000) >> 16) | ((yuv & 0x0000FFFF) << 16);
wdebi(av7110, DEBINOSWAP, DATA_BUFF3_BASE + i * 4, yuv, 4); wdebi(av7110, DEBINOSWAP, DATA_BUFF3_BASE + i * 4, yuv, 4);
} }
...@@ -922,10 +911,19 @@ static int OSDSetBlock(struct av7110 *av7110, int x0, int y0, ...@@ -922,10 +911,19 @@ static int OSDSetBlock(struct av7110 *av7110, int x0, int y0,
int av7110_osd_cmd(struct av7110 *av7110, osd_cmd_t *dc) int av7110_osd_cmd(struct av7110 *av7110, osd_cmd_t *dc)
{ {
int ret;
ret = down_interruptible(&av7110->osd_sema);
if (ret)
return -ERESTARTSYS;
/* stupid, but OSD functions don't provide a return code anyway */
ret = 0;
switch (dc->cmd) { switch (dc->cmd) {
case OSD_Close: case OSD_Close:
DestroyOSDWindow(av7110, av7110->osdwin); DestroyOSDWindow(av7110, av7110->osdwin);
return 0; goto out;
case OSD_Open: case OSD_Open:
av7110->osdbpp[av7110->osdwin] = (dc->color - 1) & 7; av7110->osdbpp[av7110->osdwin] = (dc->color - 1) & 7;
CreateOSDWindow(av7110, av7110->osdwin, CreateOSDWindow(av7110, av7110->osdwin,
...@@ -935,90 +933,84 @@ int av7110_osd_cmd(struct av7110 *av7110, osd_cmd_t *dc) ...@@ -935,90 +933,84 @@ int av7110_osd_cmd(struct av7110 *av7110, osd_cmd_t *dc)
MoveWindowAbs(av7110, av7110->osdwin, dc->x0, dc->y0); MoveWindowAbs(av7110, av7110->osdwin, dc->x0, dc->y0);
SetColorBlend(av7110, av7110->osdwin); SetColorBlend(av7110, av7110->osdwin);
} }
return 0; goto out;
case OSD_Show: case OSD_Show:
MoveWindowRel(av7110, av7110->osdwin, 0, 0); MoveWindowRel(av7110, av7110->osdwin, 0, 0);
return 0; goto out;
case OSD_Hide: case OSD_Hide:
HideWindow(av7110, av7110->osdwin); HideWindow(av7110, av7110->osdwin);
return 0; goto out;
case OSD_Clear: case OSD_Clear:
DrawBlock(av7110, av7110->osdwin, 0, 0, 720, 576, 0); DrawBlock(av7110, av7110->osdwin, 0, 0, 720, 576, 0);
return 0; goto out;
case OSD_Fill: case OSD_Fill:
DrawBlock(av7110, av7110->osdwin, 0, 0, 720, 576, dc->color); DrawBlock(av7110, av7110->osdwin, 0, 0, 720, 576, dc->color);
return 0; goto out;
case OSD_SetColor: case OSD_SetColor:
OSDSetColor(av7110, dc->color, dc->x0, dc->y0, dc->x1, dc->y1); OSDSetColor(av7110, dc->color, dc->x0, dc->y0, dc->x1, dc->y1);
return 0; goto out;
case OSD_SetPalette: case OSD_SetPalette:
{ {
int len = dc->x0-dc->color+1; if (FW_VERSION(av7110->arm_app) >= 0x2618) {
void *buf; ret = OSDSetPalette(av7110, (u32 *)dc->data, dc->color, dc->x0);
if (len <= 0) goto out;
return 0; } else {
int i, len = dc->x0-dc->color+1;
buf = kmalloc(len * 4, GFP_KERNEL); u8 *colors = (u8 *)dc->data;
if (!buf) u8 r, g, b, blend;
return -ENOMEM;
for (i = 0; i<len; i++) {
if (copy_from_user(buf, dc->data, len * 4)) { if (get_user(r, colors + i * 4) ||
kfree(buf); get_user(g, colors + i * 4 + 1) ||
return -EFAULT; get_user(b, colors + i * 4 + 2) ||
get_user(blend, colors + i * 4 + 3)) {
ret = -EFAULT;
goto out;
} }
OSDSetColor(av7110, dc->color + i, r, g, b, blend);
if (FW_VERSION(av7110->arm_app) >= 0x2618)
OSDSetPalette(av7110, buf, dc->color, dc->x0);
else {
int i;
u8 *colors = buf;
for (i = 0; i<len; i++)
OSDSetColor(av7110, dc->color + i,
colors[i * 4], colors[i * 4 + 1],
colors[i * 4 + 2], colors[i * 4 + 3]);
} }
kfree(buf); }
return 0; ret = 0;
goto out;
} }
case OSD_SetTrans: case OSD_SetTrans:
return 0; goto out;
case OSD_SetPixel: case OSD_SetPixel:
DrawLine(av7110, av7110->osdwin, DrawLine(av7110, av7110->osdwin,
dc->x0, dc->y0, 0, 0, dc->color); dc->x0, dc->y0, 0, 0, dc->color);
return 0; goto out;
case OSD_GetPixel: case OSD_GetPixel:
return 0; goto out;
case OSD_SetRow: case OSD_SetRow:
dc->y1 = dc->y0; dc->y1 = dc->y0;
/* fall through */ /* fall through */
case OSD_SetBlock: case OSD_SetBlock:
OSDSetBlock(av7110, dc->x0, dc->y0, dc->x1, dc->y1, dc->color, dc->data); OSDSetBlock(av7110, dc->x0, dc->y0, dc->x1, dc->y1, dc->color, dc->data);
return 0; goto out;
case OSD_FillRow: case OSD_FillRow:
DrawBlock(av7110, av7110->osdwin, dc->x0, dc->y0, DrawBlock(av7110, av7110->osdwin, dc->x0, dc->y0,
dc->x1-dc->x0+1, dc->y1, dc->color); dc->x1-dc->x0+1, dc->y1, dc->color);
return 0; goto out;
case OSD_FillBlock: case OSD_FillBlock:
DrawBlock(av7110, av7110->osdwin, dc->x0, dc->y0, DrawBlock(av7110, av7110->osdwin, dc->x0, dc->y0,
dc->x1 - dc->x0 + 1, dc->y1 - dc->y0 + 1, dc->color); dc->x1 - dc->x0 + 1, dc->y1 - dc->y0 + 1, dc->color);
return 0; goto out;
case OSD_Line: case OSD_Line:
DrawLine(av7110, av7110->osdwin, DrawLine(av7110, av7110->osdwin,
dc->x0, dc->y0, dc->x1 - dc->x0, dc->y1 - dc->y0, dc->color); dc->x0, dc->y0, dc->x1 - dc->x0, dc->y1 - dc->y0, dc->color);
return 0; goto out;
case OSD_Query: case OSD_Query:
return 0; goto out;
case OSD_Test: case OSD_Test:
return 0; goto out;
case OSD_Text: case OSD_Text:
{ {
char textbuf[240]; char textbuf[240];
if (strncpy_from_user(textbuf, dc->data, 240) < 0) if (strncpy_from_user(textbuf, dc->data, 240) < 0) {
return -EFAULT; ret = -EFAULT;
goto out;
}
textbuf[239] = 0; textbuf[239] = 0;
if (dc->x1 > 3) if (dc->x1 > 3)
dc->x1 = 3; dc->x1 = 3;
...@@ -1026,16 +1018,55 @@ int av7110_osd_cmd(struct av7110 *av7110, osd_cmd_t *dc) ...@@ -1026,16 +1018,55 @@ int av7110_osd_cmd(struct av7110 *av7110, osd_cmd_t *dc)
(u16) (dc->color & 0xffff), (u16) (dc->color >> 16)); (u16) (dc->color & 0xffff), (u16) (dc->color >> 16));
FlushText(av7110); FlushText(av7110);
WriteText(av7110, av7110->osdwin, dc->x0, dc->y0, textbuf); WriteText(av7110, av7110->osdwin, dc->x0, dc->y0, textbuf);
return 0; goto out;
} }
case OSD_SetWindow: case OSD_SetWindow:
if (dc->x0 < 1 || dc->x0 > 7) if (dc->x0 < 1 || dc->x0 > 7) {
return -EINVAL; ret = -EINVAL;
goto out;
}
av7110->osdwin = dc->x0; av7110->osdwin = dc->x0;
return 0; goto out;
case OSD_MoveWindow: case OSD_MoveWindow:
MoveWindowAbs(av7110, av7110->osdwin, dc->x0, dc->y0); MoveWindowAbs(av7110, av7110->osdwin, dc->x0, dc->y0);
SetColorBlend(av7110, av7110->osdwin); SetColorBlend(av7110, av7110->osdwin);
goto out;
case OSD_OpenRaw:
if (dc->color < OSD_BITMAP1 || dc->color > OSD_CURSOR) {
ret = -EINVAL;
goto out;
}
if (dc->color >= OSD_BITMAP1 && dc->color <= OSD_BITMAP8HR) {
av7110->osdbpp[av7110->osdwin] = (1 << (dc->color & 3)) - 1;
}
else {
av7110->osdbpp[av7110->osdwin] = 0;
}
CreateOSDWindow(av7110, av7110->osdwin, (osd_raw_window_t)dc->color,
dc->x1 - dc->x0 + 1, dc->y1 - dc->y0 + 1);
if (!dc->data) {
MoveWindowAbs(av7110, av7110->osdwin, dc->x0, dc->y0);
SetColorBlend(av7110, av7110->osdwin);
}
goto out;
default:
ret = -EINVAL;
goto out;
}
out:
up(&av7110->osd_sema);
return ret;
}
int av7110_osd_capability(struct av7110 *av7110, osd_cap_t *cap)
{
switch (cap->cmd) {
case OSD_CAP_MEMSIZE:
if (FW_4M_SDRAM(av7110->arm_app))
cap->val = 1000000;
else
cap->val = 92000;
return 0; return 0;
default: default:
return -EINVAL; return -EINVAL;
......
...@@ -39,29 +39,6 @@ enum av7110_osd_palette_type ...@@ -39,29 +39,6 @@ enum av7110_osd_palette_type
Pal8Bit = 256 /* 256 colors for 16 bit palette */ Pal8Bit = 256 /* 256 colors for 16 bit palette */
}; };
enum av7110_window_display_type {
BITMAP1, /* 1 bit bitmap */
BITMAP2, /* 2 bit bitmap */
BITMAP4, /* 4 bit bitmap */
BITMAP8, /* 8 bit bitmap */
BITMAP1HR, /* 1 Bit bitmap half resolution */
BITMAP2HR, /* 2 bit bitmap half resolution */
BITMAP4HR, /* 4 bit bitmap half resolution */
BITMAP8HR, /* 8 bit bitmap half resolution */
YCRCB422, /* 4:2:2 YCRCB Graphic Display */
YCRCB444, /* 4:4:4 YCRCB Graphic Display */
YCRCB444HR, /* 4:4:4 YCRCB graphic half resolution */
VIDEOTSIZE, /* True Size Normal MPEG Video Display */
VIDEOHSIZE, /* MPEG Video Display Half Resolution */
VIDEOQSIZE, /* MPEG Video Display Quarter Resolution */
VIDEODSIZE, /* MPEG Video Display Double Resolution */
VIDEOTHSIZE, /* True Size MPEG Video Display Half Resolution */
VIDEOTQSIZE, /* True Size MPEG Video Display Quarter Resolution*/
VIDEOTDSIZE, /* True Size MPEG Video Display Double Resolution */
VIDEONSIZE, /* Full Size MPEG Video Display */
CURSOR /* Cursor */
};
/* switch defines */ /* switch defines */
#define SB_GPIO 3 #define SB_GPIO 3
#define SB_OFF SAA7146_GPIO_OUTLO /* SlowBlank off (TV-Mode) */ #define SB_OFF SAA7146_GPIO_OUTLO /* SlowBlank off (TV-Mode) */
...@@ -388,6 +365,7 @@ extern void av7110_reset_arm(struct av7110 *av7110); ...@@ -388,6 +365,7 @@ extern void av7110_reset_arm(struct av7110 *av7110);
extern int av7110_bootarm(struct av7110 *av7110); extern int av7110_bootarm(struct av7110 *av7110);
extern int av7110_firmversion(struct av7110 *av7110); extern int av7110_firmversion(struct av7110 *av7110);
#define FW_CI_LL_SUPPORT(arm_app) ((arm_app) & 0x80000000) #define FW_CI_LL_SUPPORT(arm_app) ((arm_app) & 0x80000000)
#define FW_4M_SDRAM(arm_app) ((arm_app) & 0x40000000)
#define FW_VERSION(arm_app) ((arm_app) & 0x0000FFFF) #define FW_VERSION(arm_app) ((arm_app) & 0x0000FFFF)
extern int av7110_fw_cmd(struct av7110 *av7110, int type, int com, int num, ...); extern int av7110_fw_cmd(struct av7110 *av7110, int type, int com, int num, ...);
...@@ -495,7 +473,7 @@ static int inline vidcom(struct av7110 *av7110, u32 com, u32 arg) ...@@ -495,7 +473,7 @@ static int inline vidcom(struct av7110 *av7110, u32 com, u32 arg)
static int inline audcom(struct av7110 *av7110, u32 com) static int inline audcom(struct av7110 *av7110, u32 com)
{ {
return av7110_fw_cmd(av7110, COMTYPE_MISC, AV7110_FW_AUDIO_COMMAND, 4, return av7110_fw_cmd(av7110, COMTYPE_MISC, AV7110_FW_AUDIO_COMMAND, 2,
(com>>16), (com&0xffff)); (com>>16), (com&0xffff));
} }
...@@ -510,6 +488,7 @@ extern int av7110_diseqc_send(struct av7110 *av7110, int len, u8 *msg, unsigned ...@@ -510,6 +488,7 @@ extern int av7110_diseqc_send(struct av7110 *av7110, int len, u8 *msg, unsigned
#ifdef CONFIG_DVB_AV7110_OSD #ifdef CONFIG_DVB_AV7110_OSD
extern int av7110_osd_cmd(struct av7110 *av7110, osd_cmd_t *dc); extern int av7110_osd_cmd(struct av7110 *av7110, osd_cmd_t *dc);
extern int av7110_osd_capability(struct av7110 *av7110, osd_cap_t *cap);
#endif /* CONFIG_DVB_AV7110_OSD */ #endif /* CONFIG_DVB_AV7110_OSD */
......
#include <linux/types.h> #include <linux/types.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/input.h> #include <linux/input.h>
#include <linux/proc_fs.h> #include <linux/proc_fs.h>
#include <asm/bitops.h> #include <asm/bitops.h>
#include "av7110.h" #include "av7110.h"
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
#include "input_fake.h"
#endif
#define UP_TIMEOUT (HZ/4) #define UP_TIMEOUT (HZ/4)
static int av7110_ir_debug = 0; static int av7110_ir_debug;
#define dprintk(x...) do { if (av7110_ir_debug) printk (x); } while (0) module_param_named(debug_ir, av7110_ir_debug, int, 0644);
MODULE_PARM_DESC(av7110_ir_debug, "Turn on/off IR debugging (default:off).");
#define dprintk(x...) do { if (av7110_ir_debug) printk (x); } while (0)
static struct input_dev input_dev; static struct input_dev input_dev;
...@@ -205,6 +203,7 @@ int __init av7110_ir_init (void) ...@@ -205,6 +203,7 @@ int __init av7110_ir_init (void)
void __exit av7110_ir_exit (void) void __exit av7110_ir_exit (void)
{ {
del_timer_sync(&keyup_timer);
remove_proc_entry ("av7110_ir", NULL); remove_proc_entry ("av7110_ir", NULL);
av7110_unregister_irc_handler (av7110_emit_key); av7110_unregister_irc_handler (av7110_emit_key);
input_unregister_device(&input_dev); input_unregister_device(&input_dev);
...@@ -213,6 +212,3 @@ void __exit av7110_ir_exit (void) ...@@ -213,6 +212,3 @@ void __exit av7110_ir_exit (void)
//MODULE_AUTHOR("Holger Waechtler <holger@convergence.de>"); //MODULE_AUTHOR("Holger Waechtler <holger@convergence.de>");
//MODULE_LICENSE("GPL"); //MODULE_LICENSE("GPL");
MODULE_PARM(av7110_ir_debug,"i");
MODULE_PARM_DESC(av7110_ir_debug, "enable AV7110 IR receiver debug messages");
...@@ -35,23 +35,16 @@ ...@@ -35,23 +35,16 @@
#include <linux/byteorder/swabb.h> #include <linux/byteorder/swabb.h>
#include <linux/smp_lock.h> #include <linux/smp_lock.h>
#define DEBUG_VARIABLE av7110_debug
extern int av7110_debug;
#include "dvb_i2c.h"
#include "av7110.h" #include "av7110.h"
#include "av7110_hw.h" #include "av7110_hw.h"
#include "av7110_av.h" #include "av7110_av.h"
#include "dvb_functions.h"
int msp_writereg(struct av7110 *av7110, u8 dev, u16 reg, u16 val) int msp_writereg(struct av7110 *av7110, u8 dev, u16 reg, u16 val)
{ {
u8 msg[5] = { dev, reg >> 8, reg & 0xff, val >> 8 , val & 0xff }; u8 msg[5] = { dev, reg >> 8, reg & 0xff, val >> 8 , val & 0xff };
struct dvb_i2c_bus *i2c = av7110->i2c_bus;
struct i2c_msg msgs = { .flags = 0, .addr = 0x40, .len = 5, .buf = msg }; struct i2c_msg msgs = { .flags = 0, .addr = 0x40, .len = 5, .buf = msg };
if (i2c->xfer(i2c, &msgs, 1) != 1) { if (i2c_transfer(&av7110->i2c_adap, &msgs, 1) != 1) {
printk("av7110(%d): %s(%u = %u) failed\n", printk("av7110(%d): %s(%u = %u) failed\n",
av7110->dvb_adapter->num, __FUNCTION__, reg, val); av7110->dvb_adapter->num, __FUNCTION__, reg, val);
return -EIO; return -EIO;
...@@ -63,13 +56,12 @@ int msp_readreg(struct av7110 *av7110, u8 dev, u16 reg, u16 *val) ...@@ -63,13 +56,12 @@ int msp_readreg(struct av7110 *av7110, u8 dev, u16 reg, u16 *val)
{ {
u8 msg1[3] = { dev, reg >> 8, reg & 0xff }; u8 msg1[3] = { dev, reg >> 8, reg & 0xff };
u8 msg2[2]; u8 msg2[2];
struct dvb_i2c_bus *i2c = av7110->i2c_bus;
struct i2c_msg msgs[2] = { struct i2c_msg msgs[2] = {
{ .flags = 0, .addr = 0x40, .len = 3, .buf = msg1 }, { .flags = 0, .addr = 0x40, .len = 3, .buf = msg1 },
{ .flags = I2C_M_RD, .addr = 0x40, .len = 2, .buf = msg2 } { .flags = I2C_M_RD, .addr = 0x40, .len = 2, .buf = msg2 }
}; };
if (i2c->xfer(i2c, msgs, 2) != 2) { if (i2c_transfer(&av7110->i2c_adap, &msgs[0], 2) != 2) {
printk("av7110(%d): %s(%u) failed\n", printk("av7110(%d): %s(%u) failed\n",
av7110->dvb_adapter->num, __FUNCTION__, reg); av7110->dvb_adapter->num, __FUNCTION__, reg);
return -EIO; return -EIO;
...@@ -517,7 +509,7 @@ int av7110_init_analog_module(struct av7110 *av7110) ...@@ -517,7 +509,7 @@ int av7110_init_analog_module(struct av7110 *av7110)
printk("av7110(%d): DVB-C analog module detected, initializing MSP3400\n", printk("av7110(%d): DVB-C analog module detected, initializing MSP3400\n",
av7110->dvb_adapter->num); av7110->dvb_adapter->num);
av7110->adac_type = DVB_ADAC_MSP; av7110->adac_type = DVB_ADAC_MSP;
dvb_delay(100); // the probing above resets the msp... msleep(100); // the probing above resets the msp...
msp_readreg(av7110, MSP_RD_DSP, 0x001e, &version1); msp_readreg(av7110, MSP_RD_DSP, 0x001e, &version1);
msp_readreg(av7110, MSP_RD_DSP, 0x001f, &version2); msp_readreg(av7110, MSP_RD_DSP, 0x001f, &version2);
printk("av7110(%d): MSP3400 version 0x%04x 0x%04x\n", printk("av7110(%d): MSP3400 version 0x%04x 0x%04x\n",
......
...@@ -30,14 +30,12 @@ ...@@ -30,14 +30,12 @@
* the project's page is at http://www.linuxtv.org/dvb/ * the project's page is at http://www.linuxtv.org/dvb/
*/ */
#include <media/saa7146_vv.h>
#include "budget.h" #include "budget.h"
#include "dvb_functions.h" #include <media/saa7146_vv.h>
struct budget_av { struct budget_av {
struct budget budget; struct budget budget;
struct video_device vd; struct video_device *vd;
int cur_input; int cur_input;
int has_saa7113; int has_saa7113;
}; };
...@@ -47,7 +45,7 @@ struct budget_av { ...@@ -47,7 +45,7 @@ struct budget_av {
****************************************************************************/ ****************************************************************************/
static u8 i2c_readreg (struct dvb_i2c_bus *i2c, u8 id, u8 reg) static u8 i2c_readreg (struct i2c_adapter *i2c, u8 id, u8 reg)
{ {
u8 mm1[] = {0x00}; u8 mm1[] = {0x00};
u8 mm2[] = {0x00}; u8 mm2[] = {0x00};
...@@ -60,12 +58,12 @@ static u8 i2c_readreg (struct dvb_i2c_bus *i2c, u8 id, u8 reg) ...@@ -60,12 +58,12 @@ static u8 i2c_readreg (struct dvb_i2c_bus *i2c, u8 id, u8 reg)
msgs[0].len = 1; msgs[1].len = 1; msgs[0].len = 1; msgs[1].len = 1;
msgs[0].buf = mm1; msgs[1].buf = mm2; msgs[0].buf = mm1; msgs[1].buf = mm2;
i2c->xfer(i2c, msgs, 2); i2c_transfer(i2c, msgs, 2);
return mm2[0]; return mm2[0];
} }
static int i2c_readregs(struct dvb_i2c_bus *i2c, u8 id, u8 reg, u8 *buf, u8 len) static int i2c_readregs(struct i2c_adapter *i2c, u8 id, u8 reg, u8 *buf, u8 len)
{ {
u8 mm1[] = { reg }; u8 mm1[] = { reg };
struct i2c_msg msgs[2] = { struct i2c_msg msgs[2] = {
...@@ -73,13 +71,14 @@ static int i2c_readregs(struct dvb_i2c_bus *i2c, u8 id, u8 reg, u8 *buf, u8 len) ...@@ -73,13 +71,14 @@ static int i2c_readregs(struct dvb_i2c_bus *i2c, u8 id, u8 reg, u8 *buf, u8 len)
{ .addr = id/2, .flags = I2C_M_RD, .buf = buf, .len = len } { .addr = id/2, .flags = I2C_M_RD, .buf = buf, .len = len }
}; };
if (i2c->xfer(i2c, msgs, 2) != 2) if (i2c_transfer(i2c, msgs, 2) != 2)
return -EIO; return -EIO;
return 0; return 0;
} }
static int i2c_writereg (struct dvb_i2c_bus *i2c, u8 id, u8 reg, u8 val) static int i2c_writereg (struct i2c_adapter *i2c, u8 id, u8 reg, u8 val)
{ {
u8 msg[2]={ reg, val }; u8 msg[2]={ reg, val };
struct i2c_msg msgs; struct i2c_msg msgs;
...@@ -88,7 +87,7 @@ static int i2c_writereg (struct dvb_i2c_bus *i2c, u8 id, u8 reg, u8 val) ...@@ -88,7 +87,7 @@ static int i2c_writereg (struct dvb_i2c_bus *i2c, u8 id, u8 reg, u8 val)
msgs.addr=id/2; msgs.addr=id/2;
msgs.len=2; msgs.len=2;
msgs.buf=msg; msgs.buf=msg;
return i2c->xfer (i2c, &msgs, 1); return i2c_transfer(i2c, &msgs, 1);
} }
...@@ -127,7 +126,7 @@ static int saa7113_init (struct budget_av *budget_av) ...@@ -127,7 +126,7 @@ static int saa7113_init (struct budget_av *budget_av)
struct budget *budget = &budget_av->budget; struct budget *budget = &budget_av->budget;
const u8 *data = saa7113_tab; const u8 *data = saa7113_tab;
if (i2c_writereg (budget->i2c_bus, 0x4a, 0x01, 0x08) != 1) { if (i2c_writereg (&budget->i2c_adap, 0x4a, 0x01, 0x08) != 1) {
DEB_D(("saa7113: not found on KNC card\n")); DEB_D(("saa7113: not found on KNC card\n"));
return -ENODEV; return -ENODEV;
} }
...@@ -135,12 +134,12 @@ static int saa7113_init (struct budget_av *budget_av) ...@@ -135,12 +134,12 @@ static int saa7113_init (struct budget_av *budget_av)
INFO(("saa7113: detected and initializing\n")); INFO(("saa7113: detected and initializing\n"));
while (*data != 0xff) { while (*data != 0xff) {
i2c_writereg(budget->i2c_bus, 0x4a, *data, *(data+1)); i2c_writereg(&budget->i2c_adap, 0x4a, *data, *(data+1));
data += 2; data += 2;
} }
DEB_D(("saa7113: status=%02x\n", DEB_D(("saa7113: status=%02x\n",
i2c_readreg(budget->i2c_bus, 0x4a, 0x1f))); i2c_readreg(&budget->i2c_adap, 0x4a, 0x1f)));
return 0; return 0;
} }
...@@ -154,11 +153,11 @@ static int saa7113_setinput (struct budget_av *budget_av, int input) ...@@ -154,11 +153,11 @@ static int saa7113_setinput (struct budget_av *budget_av, int input)
return -ENODEV; return -ENODEV;
if (input == 1) { if (input == 1) {
i2c_writereg(budget->i2c_bus, 0x4a, 0x02, 0xc7); i2c_writereg(&budget->i2c_adap, 0x4a, 0x02, 0xc7);
i2c_writereg(budget->i2c_bus, 0x4a, 0x09, 0x80); i2c_writereg(&budget->i2c_adap, 0x4a, 0x09, 0x80);
} else if (input == 0) { } else if (input == 0) {
i2c_writereg(budget->i2c_bus, 0x4a, 0x02, 0xc0); i2c_writereg(&budget->i2c_adap, 0x4a, 0x02, 0xc0);
i2c_writereg(budget->i2c_bus, 0x4a, 0x09, 0x00); i2c_writereg(&budget->i2c_adap, 0x4a, 0x09, 0x00);
} else } else
return -EINVAL; return -EINVAL;
...@@ -177,7 +176,7 @@ static int budget_av_detach (struct saa7146_dev *dev) ...@@ -177,7 +176,7 @@ static int budget_av_detach (struct saa7146_dev *dev)
if ( 1 == budget_av->has_saa7113 ) { if ( 1 == budget_av->has_saa7113 ) {
saa7146_setgpio(dev, 0, SAA7146_GPIO_OUTLO); saa7146_setgpio(dev, 0, SAA7146_GPIO_OUTLO);
dvb_delay(200); msleep(200);
saa7146_unregister_device (&budget_av->vd, dev); saa7146_unregister_device (&budget_av->vd, dev);
} }
...@@ -201,7 +200,7 @@ static int budget_av_attach (struct saa7146_dev* dev, ...@@ -201,7 +200,7 @@ static int budget_av_attach (struct saa7146_dev* dev,
DEB_EE(("dev: %p\n",dev)); DEB_EE(("dev: %p\n",dev));
if (bi->type != BUDGET_KNC1) { if (bi->type != BUDGET_KNC1 && bi->type != BUDGET_CIN1200) {
return -ENODEV; return -ENODEV;
} }
...@@ -210,13 +209,13 @@ static int budget_av_attach (struct saa7146_dev* dev, ...@@ -210,13 +209,13 @@ static int budget_av_attach (struct saa7146_dev* dev,
memset(budget_av, 0, sizeof(struct budget_av)); memset(budget_av, 0, sizeof(struct budget_av));
dev->ext_priv = budget_av;
if ((err = ttpci_budget_init(&budget_av->budget, dev, info))) { if ((err = ttpci_budget_init(&budget_av->budget, dev, info))) {
kfree(budget_av); kfree(budget_av);
return err; return err;
} }
dev->ext_priv = budget_av;
/* knc1 initialization */ /* knc1 initialization */
saa7146_write(dev, DD1_STREAM_B, 0x04000000); saa7146_write(dev, DD1_STREAM_B, 0x04000000);
saa7146_write(dev, DD1_INIT, 0x07000600); saa7146_write(dev, DD1_INIT, 0x07000600);
...@@ -225,7 +224,7 @@ static int budget_av_attach (struct saa7146_dev* dev, ...@@ -225,7 +224,7 @@ static int budget_av_attach (struct saa7146_dev* dev,
//test_knc_ci(av7110); //test_knc_ci(av7110);
saa7146_setgpio(dev, 0, SAA7146_GPIO_OUTHI); saa7146_setgpio(dev, 0, SAA7146_GPIO_OUTHI);
dvb_delay(500); msleep(500);
if ( 0 == saa7113_init(budget_av) ) { if ( 0 == saa7113_init(budget_av) ) {
budget_av->has_saa7113 = 1; budget_av->has_saa7113 = 1;
...@@ -259,7 +258,7 @@ static int budget_av_attach (struct saa7146_dev* dev, ...@@ -259,7 +258,7 @@ static int budget_av_attach (struct saa7146_dev* dev,
saa7146_write(dev, PCI_BT_V1, 0x1c00101f); saa7146_write(dev, PCI_BT_V1, 0x1c00101f);
mac = budget_av->budget.dvb_adapter->proposed_mac; mac = budget_av->budget.dvb_adapter->proposed_mac;
if (i2c_readregs(budget_av->budget.i2c_bus, 0xa0, 0x30, mac, 6)) { if (i2c_readregs(&budget_av->budget.i2c_adap, 0xa0, 0x30, mac, 6)) {
printk("KNC1-%d: Could not read MAC from KNC1 card\n", printk("KNC1-%d: Could not read MAC from KNC1 card\n",
budget_av->budget.dvb_adapter->num); budget_av->budget.dvb_adapter->num);
memset(mac, 0, 6); memset(mac, 0, 6);
...@@ -361,9 +360,11 @@ static struct saa7146_extension budget_extension; ...@@ -361,9 +360,11 @@ static struct saa7146_extension budget_extension;
MAKE_BUDGET_INFO(knc1, "KNC1 DVB-S", BUDGET_KNC1); MAKE_BUDGET_INFO(knc1, "KNC1 DVB-S", BUDGET_KNC1);
MAKE_BUDGET_INFO(cin1200, "TerraTec Cinergy 1200 DVB-S", BUDGET_CIN1200);
static struct pci_device_id pci_tbl [] = { static struct pci_device_id pci_tbl [] = {
MAKE_EXTENSION_PCI(knc1, 0x1131, 0x4f56), MAKE_EXTENSION_PCI(knc1, 0x1131, 0x4f56),
MAKE_EXTENSION_PCI(cin1200, 0x153b, 0x1154),
{ {
.vendor = 0, .vendor = 0,
} }
......
...@@ -38,13 +38,8 @@ ...@@ -38,13 +38,8 @@
#include <linux/input.h> #include <linux/input.h>
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include "dvb_functions.h"
#include "dvb_ca_en50221.h" #include "dvb_ca_en50221.h"
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
#include "input_fake.h"
#endif
#define DEBIADDR_IR 0x1234 #define DEBIADDR_IR 0x1234
#define DEBIADDR_CICONTROL 0x0000 #define DEBIADDR_CICONTROL 0x0000
#define DEBIADDR_CIVERSION 0x4000 #define DEBIADDR_CIVERSION 0x4000
...@@ -79,14 +74,15 @@ static u32 budget_debiread (struct budget_ci* budget_ci, u32 config, int addr, i ...@@ -79,14 +74,15 @@ static u32 budget_debiread (struct budget_ci* budget_ci, u32 config, int addr, i
{ {
struct saa7146_dev *saa = budget_ci->budget.dev; struct saa7146_dev *saa = budget_ci->budget.dev;
u32 result = 0; u32 result = 0;
unsigned long flags;
if (count > 4 || count <= 0) if (count > 4 || count <= 0)
return 0; return 0;
spin_lock(&budget_ci->debilock); spin_lock_irqsave(&budget_ci->debilock, flags);
if (saa7146_wait_for_debi_done(saa) < 0) { if (saa7146_wait_for_debi_done(saa) < 0) {
spin_unlock(&budget_ci->debilock); spin_unlock_irqrestore(&budget_ci->debilock, flags);
return 0; return 0;
} }
...@@ -101,21 +97,22 @@ static u32 budget_debiread (struct budget_ci* budget_ci, u32 config, int addr, i ...@@ -101,21 +97,22 @@ static u32 budget_debiread (struct budget_ci* budget_ci, u32 config, int addr, i
result = saa7146_read(saa, 0x88); result = saa7146_read(saa, 0x88);
result &= (0xffffffffUL >> ((4 - count) * 8)); result &= (0xffffffffUL >> ((4 - count) * 8));
spin_unlock(&budget_ci->debilock); spin_unlock_irqrestore(&budget_ci->debilock, flags);
return result; return result;
} }
static u8 budget_debiwrite (struct budget_ci* budget_ci, u32 config, int addr, int count, u32 value) static u8 budget_debiwrite (struct budget_ci* budget_ci, u32 config, int addr, int count, u32 value)
{ {
struct saa7146_dev *saa = budget_ci->budget.dev; struct saa7146_dev *saa = budget_ci->budget.dev;
unsigned long flags;
if (count > 4 || count <= 0) if (count > 4 || count <= 0)
return 0; return 0;
spin_lock(&budget_ci->debilock); spin_lock_irqsave(&budget_ci->debilock, flags);
if (saa7146_wait_for_debi_done(saa) < 0) { if (saa7146_wait_for_debi_done(saa) < 0) {
spin_unlock(&budget_ci->debilock); spin_unlock_irqrestore(&budget_ci->debilock, flags);
return 0; return 0;
} }
...@@ -128,7 +125,7 @@ static u8 budget_debiwrite (struct budget_ci* budget_ci, u32 config, int addr, i ...@@ -128,7 +125,7 @@ static u8 budget_debiwrite (struct budget_ci* budget_ci, u32 config, int addr, i
saa7146_wait_for_debi_done(saa); saa7146_wait_for_debi_done(saa);
spin_unlock(&budget_ci->debilock); spin_unlock_irqrestore(&budget_ci->debilock, flags);
return 0; return 0;
} }
...@@ -326,7 +323,7 @@ static int ciintf_slot_reset(struct dvb_ca_en50221* ca, int slot) { ...@@ -326,7 +323,7 @@ static int ciintf_slot_reset(struct dvb_ca_en50221* ca, int slot) {
saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQHI); saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQHI);
budget_ci->slot_status = SLOTSTATUS_RESET; budget_ci->slot_status = SLOTSTATUS_RESET;
budget_debiwrite(budget_ci, DEBICICTL, DEBIADDR_CICONTROL, 1, 0); budget_debiwrite(budget_ci, DEBICICTL, DEBIADDR_CICONTROL, 1, 0);
dvb_delay(1); msleep(1);
budget_debiwrite(budget_ci, DEBICICTL, DEBIADDR_CICONTROL, 1, CICONTROL_RESET); budget_debiwrite(budget_ci, DEBICICTL, DEBIADDR_CICONTROL, 1, CICONTROL_RESET);
saa7146_setgpio(saa, 1, SAA7146_GPIO_OUTHI); saa7146_setgpio(saa, 1, SAA7146_GPIO_OUTHI);
...@@ -372,14 +369,13 @@ static void ciintf_interrupt (unsigned long data) ...@@ -372,14 +369,13 @@ static void ciintf_interrupt (unsigned long data)
// ensure we don't get spurious IRQs during initialisation // ensure we don't get spurious IRQs during initialisation
if (!budget_ci->budget.ci_present) return; if (!budget_ci->budget.ci_present) return;
// read the CAM status
flags = budget_debiread(budget_ci, DEBICICTL, DEBIADDR_CICONTROL, 1); flags = budget_debiread(budget_ci, DEBICICTL, DEBIADDR_CICONTROL, 1);
if (flags & CICONTROL_CAMDETECT) {
// always set the GPIO mode back to "normal", in case the card is // GPIO should be set to trigger on falling edge if a CAM is present
// yanked at an inopportune moment
saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQLO); saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQLO);
if (flags & CICONTROL_CAMDETECT) {
if (budget_ci->slot_status & SLOTSTATUS_NONE) { if (budget_ci->slot_status & SLOTSTATUS_NONE) {
// CAM insertion IRQ // CAM insertion IRQ
budget_ci->slot_status = SLOTSTATUS_PRESENT; budget_ci->slot_status = SLOTSTATUS_PRESENT;
...@@ -395,7 +391,15 @@ static void ciintf_interrupt (unsigned long data) ...@@ -395,7 +391,15 @@ static void ciintf_interrupt (unsigned long data)
dvb_ca_en50221_frda_irq(&budget_ci->ca, 0); dvb_ca_en50221_frda_irq(&budget_ci->ca, 0);
} }
} else { } else {
// trigger on rising edge if a CAM is not present - when a CAM is inserted, we
// only want to get the IRQ when it sets READY. If we trigger on the falling edge,
// the CAM might not actually be ready yet.
saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQHI);
// generate a CAM removal IRQ if we haven't already
if (budget_ci->slot_status & SLOTSTATUS_OCCUPIED) { if (budget_ci->slot_status & SLOTSTATUS_OCCUPIED) {
// CAM removal IRQ
budget_ci->slot_status = SLOTSTATUS_NONE; budget_ci->slot_status = SLOTSTATUS_NONE;
dvb_ca_en50221_camchange_irq(&budget_ci->ca, 0, DVB_CA_EN50221_CAMCHANGE_REMOVED); dvb_ca_en50221_camchange_irq(&budget_ci->ca, 0, DVB_CA_EN50221_CAMCHANGE_REMOVED);
} }
...@@ -446,7 +450,11 @@ static int ciintf_init(struct budget_ci* budget_ci) ...@@ -446,7 +450,11 @@ static int ciintf_init(struct budget_ci* budget_ci)
// Setup CI slot IRQ // Setup CI slot IRQ
tasklet_init (&budget_ci->ciintf_irq_tasklet, ciintf_interrupt, (unsigned long) budget_ci); tasklet_init (&budget_ci->ciintf_irq_tasklet, ciintf_interrupt, (unsigned long) budget_ci);
if (budget_ci->slot_status != SLOTSTATUS_NONE) {
saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQLO); saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQLO);
} else {
saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQHI);
}
saa7146_write(saa, IER, saa7146_read(saa, IER) | MASK_03); saa7146_write(saa, IER, saa7146_read(saa, IER) | MASK_03);
budget_debiwrite(budget_ci, DEBICICTL, DEBIADDR_CICONTROL, 1, CICONTROL_RESET); budget_debiwrite(budget_ci, DEBICICTL, DEBIADDR_CICONTROL, 1, CICONTROL_RESET);
...@@ -475,7 +483,7 @@ static void ciintf_deinit(struct budget_ci* budget_ci) ...@@ -475,7 +483,7 @@ static void ciintf_deinit(struct budget_ci* budget_ci)
saa7146_setgpio(saa, 0, SAA7146_GPIO_INPUT); saa7146_setgpio(saa, 0, SAA7146_GPIO_INPUT);
tasklet_kill(&budget_ci->ciintf_irq_tasklet); tasklet_kill(&budget_ci->ciintf_irq_tasklet);
budget_debiwrite(budget_ci, DEBICICTL, DEBIADDR_CICONTROL, 1, 0); budget_debiwrite(budget_ci, DEBICICTL, DEBIADDR_CICONTROL, 1, 0);
dvb_delay(1); msleep(1);
budget_debiwrite(budget_ci, DEBICICTL, DEBIADDR_CICONTROL, 1, CICONTROL_RESET); budget_debiwrite(budget_ci, DEBICICTL, DEBIADDR_CICONTROL, 1, CICONTROL_RESET);
// disable TS data stream to CI interface // disable TS data stream to CI interface
...@@ -520,20 +528,19 @@ static int budget_ci_attach (struct saa7146_dev* dev, ...@@ -520,20 +528,19 @@ static int budget_ci_attach (struct saa7146_dev* dev,
spin_lock_init(&budget_ci->debilock); spin_lock_init(&budget_ci->debilock);
budget_ci->budget.ci_present = 0; budget_ci->budget.ci_present = 0;
dev->ext_priv = budget_ci;
if ((err = ttpci_budget_init (&budget_ci->budget, dev, info))) { if ((err = ttpci_budget_init (&budget_ci->budget, dev, info))) {
kfree (budget_ci); kfree (budget_ci);
return err; return err;
} }
dev->ext_priv = budget_ci;
tasklet_init (&budget_ci->msp430_irq_tasklet, msp430_ir_interrupt, tasklet_init (&budget_ci->msp430_irq_tasklet, msp430_ir_interrupt,
(unsigned long) budget_ci); (unsigned long) budget_ci);
msp430_ir_init (budget_ci); msp430_ir_init (budget_ci);
// UNCOMMENT TO TEST CI INTERFACE ciintf_init(budget_ci);
// ciintf_init(budget_ci);
return 0; return 0;
} }
......
...@@ -34,10 +34,15 @@ ...@@ -34,10 +34,15 @@
* the project's page is at http://www.linuxtv.org/dvb/ * the project's page is at http://www.linuxtv.org/dvb/
*/ */
#include <linux/moduleparam.h>
#include "budget.h" #include "budget.h"
#include "ttpci-eeprom.h" #include "ttpci-eeprom.h"
int budget_debug = 0; int budget_debug;
module_param_named(debug, budget_debug, int, 0644);
MODULE_PARM_DESC(budget_debug, "Turn on/off budget debugging (default:off).");
/**************************************************************************** /****************************************************************************
* TT budget / WinTV Nova * TT budget / WinTV Nova
...@@ -258,13 +263,26 @@ static void budget_unregister(struct budget *budget) ...@@ -258,13 +263,26 @@ static void budget_unregister(struct budget *budget)
dvb_dmx_release(&budget->demux); dvb_dmx_release(&budget->demux);
} }
/* fixme: can this be unified among all saa7146 based dvb cards? */
static int master_xfer (struct dvb_i2c_bus *i2c, const struct i2c_msg msgs[], int num) static int client_register(struct i2c_client *client)
{ {
struct saa7146_dev *dev = i2c->data; struct saa7146_dev *dev = (struct saa7146_dev*)i2c_get_adapdata(client->adapter);
return saa7146_i2c_transfer(dev, msgs, num, 6); struct budget *budget = (struct budget*)dev->ext_priv;
if (client->driver->command)
return client->driver->command(client, FE_REGISTER, budget->dvb_adapter);
return 0;
} }
static int client_unregister(struct i2c_client *client)
{
struct saa7146_dev *dev = (struct saa7146_dev*)i2c_get_adapdata(client->adapter);
struct budget *budget = (struct budget*)dev->ext_priv;
if (client->driver->command)
return client->driver->command(client, FE_UNREGISTER, budget->dvb_adapter);
return 0;
}
int ttpci_budget_init (struct budget *budget, int ttpci_budget_init (struct budget *budget,
struct saa7146_dev* dev, struct saa7146_dev* dev,
...@@ -301,17 +319,27 @@ int ttpci_budget_init (struct budget *budget, ...@@ -301,17 +319,27 @@ int ttpci_budget_init (struct budget *budget,
if (bi->type != BUDGET_FS_ACTIVY) if (bi->type != BUDGET_FS_ACTIVY)
saa7146_write(dev, GPIO_CTRL, 0x500000); /* GPIO 3 = 1 */ saa7146_write(dev, GPIO_CTRL, 0x500000); /* GPIO 3 = 1 */
saa7146_i2c_adapter_prepare(dev, NULL, 0, SAA7146_I2C_BUS_BIT_RATE_120); budget->i2c_adap = (struct i2c_adapter) {
.client_register = client_register,
.client_unregister = client_unregister,
#ifdef I2C_ADAP_CLASS_TV_DIGITAL
.class = I2C_ADAP_CLASS_TV_DIGITAL,
#else
.class = I2C_CLASS_TV_DIGITAL,
#endif
};
strlcpy(budget->i2c_adap.name, budget->card->name, sizeof(budget->i2c_adap.name));
budget->i2c_bus = dvb_register_i2c_bus (master_xfer, dev, saa7146_i2c_adapter_prepare(dev, &budget->i2c_adap, SAA7146_I2C_BUS_BIT_RATE_120);
budget->dvb_adapter, 0); strcpy(budget->i2c_adap.name, budget->card->name);
if (!budget->i2c_bus) { if (i2c_add_adapter(&budget->i2c_adap) < 0) {
dvb_unregister_adapter (budget->dvb_adapter); dvb_unregister_adapter (budget->dvb_adapter);
return -ENOMEM; return -ENOMEM;
} }
ttpci_eeprom_parse_mac(budget->i2c_bus); ttpci_eeprom_parse_mac(&budget->i2c_adap, budget->dvb_adapter->proposed_mac);
if( NULL == (budget->grabbing = saa7146_vmalloc_build_pgtable(dev->pci,length,&budget->pt))) { if( NULL == (budget->grabbing = saa7146_vmalloc_build_pgtable(dev->pci,length,&budget->pt))) {
ret = -ENOMEM; ret = -ENOMEM;
...@@ -334,12 +362,11 @@ int ttpci_budget_init (struct budget *budget, ...@@ -334,12 +362,11 @@ int ttpci_budget_init (struct budget *budget,
return 0; return 0;
} }
err: err:
i2c_del_adapter(&budget->i2c_adap);
if (budget->grabbing) if (budget->grabbing)
vfree(budget->grabbing); vfree(budget->grabbing);
dvb_unregister_i2c_bus (master_xfer,budget->i2c_bus->adapter,
budget->i2c_bus->id);
dvb_unregister_adapter (budget->dvb_adapter); dvb_unregister_adapter (budget->dvb_adapter);
return ret; return ret;
...@@ -354,8 +381,7 @@ int ttpci_budget_deinit (struct budget *budget) ...@@ -354,8 +381,7 @@ int ttpci_budget_deinit (struct budget *budget)
budget_unregister (budget); budget_unregister (budget);
dvb_unregister_i2c_bus (master_xfer, budget->i2c_bus->adapter, i2c_del_adapter(&budget->i2c_adap);
budget->i2c_bus->id);
dvb_unregister_adapter (budget->dvb_adapter); dvb_unregister_adapter (budget->dvb_adapter);
...@@ -402,7 +428,5 @@ EXPORT_SYMBOL_GPL(ttpci_budget_irq10_handler); ...@@ -402,7 +428,5 @@ EXPORT_SYMBOL_GPL(ttpci_budget_irq10_handler);
EXPORT_SYMBOL_GPL(ttpci_budget_set_video_port); EXPORT_SYMBOL_GPL(ttpci_budget_set_video_port);
EXPORT_SYMBOL_GPL(budget_debug); EXPORT_SYMBOL_GPL(budget_debug);
MODULE_PARM(budget_debug,"i");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
...@@ -35,7 +35,6 @@ ...@@ -35,7 +35,6 @@
*/ */
#include "budget.h" #include "budget.h"
#include "dvb_functions.h"
static void Set22K (struct budget *budget, int state) static void Set22K (struct budget *budget, int state)
{ {
...@@ -100,7 +99,7 @@ static int SendDiSEqCMsg (struct budget *budget, int len, u8 *msg, unsigned long ...@@ -100,7 +99,7 @@ static int SendDiSEqCMsg (struct budget *budget, int len, u8 *msg, unsigned long
udelay(12500); udelay(12500);
saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO); saa7146_setgpio(dev, 3, SAA7146_GPIO_OUTLO);
} }
dvb_delay(20); msleep(20);
} }
return 0; return 0;
...@@ -202,6 +201,8 @@ static int budget_attach (struct saa7146_dev* dev, struct saa7146_pci_extension_ ...@@ -202,6 +201,8 @@ static int budget_attach (struct saa7146_dev* dev, struct saa7146_pci_extension_
DEB_EE(("dev:%p, info:%p, budget:%p\n",dev,info,budget)); DEB_EE(("dev:%p, info:%p, budget:%p\n",dev,info,budget));
dev->ext_priv = budget;
if ((err = ttpci_budget_init (budget, dev, info))) { if ((err = ttpci_budget_init (budget, dev, info))) {
printk("==> failed\n"); printk("==> failed\n");
kfree (budget); kfree (budget);
...@@ -215,8 +216,6 @@ static int budget_attach (struct saa7146_dev* dev, struct saa7146_pci_extension_ ...@@ -215,8 +216,6 @@ static int budget_attach (struct saa7146_dev* dev, struct saa7146_pci_extension_
dvb_add_frontend_ioctls (budget->dvb_adapter, dvb_add_frontend_ioctls (budget->dvb_adapter,
budget_diseqc_ioctl, NULL, budget); budget_diseqc_ioctl, NULL, budget);
dev->ext_priv = budget;
return 0; return 0;
} }
......
#ifndef __BUDGET_DVB__ #ifndef __BUDGET_DVB__
#define __BUDGET_DVB__ #define __BUDGET_DVB__
#include <media/saa7146.h>
#include "dvb_i2c.h"
#include "dvb_frontend.h" #include "dvb_frontend.h"
#include "dvbdev.h" #include "dvbdev.h"
#include "demux.h" #include "demux.h"
...@@ -12,6 +9,8 @@ ...@@ -12,6 +9,8 @@
#include "dvb_filter.h" #include "dvb_filter.h"
#include "dvb_net.h" #include "dvb_net.h"
#include <media/saa7146.h>
extern int budget_debug; extern int budget_debug;
struct budget_info { struct budget_info {
...@@ -28,7 +27,7 @@ struct budget { ...@@ -28,7 +27,7 @@ struct budget {
struct saa7146_dev *dev; struct saa7146_dev *dev;
struct dvb_i2c_bus *i2c_bus; struct i2c_adapter i2c_adap;
struct budget_info *card; struct budget_info *card;
unsigned char *grabbing; unsigned char *grabbing;
...@@ -79,6 +78,7 @@ static struct saa7146_pci_extension_data x_var = { \ ...@@ -79,6 +78,7 @@ static struct saa7146_pci_extension_data x_var = { \
#define BUDGET_KNC1 2 #define BUDGET_KNC1 2
#define BUDGET_PATCH 3 #define BUDGET_PATCH 3
#define BUDGET_FS_ACTIVY 4 #define BUDGET_FS_ACTIVY 4
#define BUDGET_CIN1200 5
#define BUDGET_VIDEO_PORTA 0 #define BUDGET_VIDEO_PORTA 0
#define BUDGET_VIDEO_PORTB 1 #define BUDGET_VIDEO_PORTB 1
......
...@@ -35,9 +35,8 @@ ...@@ -35,9 +35,8 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/string.h> #include <linux/string.h>
#include <linux/i2c.h>
#include "dvb_i2c.h"
#include "dvb_functions.h"
#if 1 #if 1
#define dprintk(x...) do { printk(x); } while (0) #define dprintk(x...) do { printk(x); } while (0)
...@@ -85,7 +84,7 @@ static int getmac_tt(u8 * decodedMAC, u8 * encodedMAC) ...@@ -85,7 +84,7 @@ static int getmac_tt(u8 * decodedMAC, u8 * encodedMAC)
return 0; return 0;
} }
static int ttpci_eeprom_read_encodedMAC(struct dvb_i2c_bus *i2c, u8 * encodedMAC) static int ttpci_eeprom_read_encodedMAC(struct i2c_adapter *adapter, u8 * encodedMAC)
{ {
int ret; int ret;
u8 b0[] = { 0xcc }; u8 b0[] = { 0xcc };
...@@ -97,7 +96,7 @@ static int ttpci_eeprom_read_encodedMAC(struct dvb_i2c_bus *i2c, u8 * encodedMAC ...@@ -97,7 +96,7 @@ static int ttpci_eeprom_read_encodedMAC(struct dvb_i2c_bus *i2c, u8 * encodedMAC
/* dprintk("%s\n", __FUNCTION__); */ /* dprintk("%s\n", __FUNCTION__); */
ret = i2c->xfer(i2c, msg, 2); ret = i2c_transfer(adapter, msg, 2);
if (ret != 2) /* Assume EEPROM isn't there */ if (ret != 2) /* Assume EEPROM isn't there */
return (-ENODEV); return (-ENODEV);
...@@ -106,36 +105,34 @@ static int ttpci_eeprom_read_encodedMAC(struct dvb_i2c_bus *i2c, u8 * encodedMAC ...@@ -106,36 +105,34 @@ static int ttpci_eeprom_read_encodedMAC(struct dvb_i2c_bus *i2c, u8 * encodedMAC
} }
int ttpci_eeprom_parse_mac(struct dvb_i2c_bus *i2c) int ttpci_eeprom_parse_mac(struct i2c_adapter *adapter, u8 *proposed_mac)
{ {
int ret, i; int ret, i;
u8 encodedMAC[20]; u8 encodedMAC[20];
u8 decodedMAC[6]; u8 decodedMAC[6];
ret = ttpci_eeprom_read_encodedMAC(i2c, encodedMAC); ret = ttpci_eeprom_read_encodedMAC(adapter, encodedMAC);
if (ret != 0) { /* Will only be -ENODEV */ if (ret != 0) { /* Will only be -ENODEV */
dprintk("Couldn't read from EEPROM: not there?\n"); dprintk("Couldn't read from EEPROM: not there?\n");
memset(i2c->adapter->proposed_mac, 0, 6); memset(proposed_mac, 0, 6);
return ret; return ret;
} }
ret = getmac_tt(decodedMAC, encodedMAC); ret = getmac_tt(decodedMAC, encodedMAC);
if( ret != 0 ) { if( ret != 0 ) {
dprintk("%s adapter %i failed MAC signature check\n", dprintk("adapter failed MAC signature check\n");
i2c->adapter->name, i2c->adapter->num);
dprintk("encoded MAC from EEPROM was " ); dprintk("encoded MAC from EEPROM was " );
for(i=0; i<19; i++) { for(i=0; i<19; i++) {
dprintk( "%.2x:", encodedMAC[i]); dprintk( "%.2x:", encodedMAC[i]);
} }
dprintk("%.2x\n", encodedMAC[19]); dprintk("%.2x\n", encodedMAC[19]);
memset(i2c->adapter->proposed_mac, 0, 6); memset(proposed_mac, 0, 6);
return ret; return ret;
} }
memcpy(i2c->adapter->proposed_mac, decodedMAC, 6); memcpy(proposed_mac, decodedMAC, 6);
dprintk("%s adapter %i has MAC addr = %.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n", dprintk("adapter has MAC addr = %.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n",
i2c->adapter->name, i2c->adapter->num,
decodedMAC[0], decodedMAC[1], decodedMAC[2], decodedMAC[0], decodedMAC[1], decodedMAC[2],
decodedMAC[3], decodedMAC[4], decodedMAC[5]); decodedMAC[3], decodedMAC[4], decodedMAC[5]);
return 0; return 0;
......
...@@ -25,8 +25,9 @@ ...@@ -25,8 +25,9 @@
#ifndef __TTPCI_EEPROM_H__ #ifndef __TTPCI_EEPROM_H__
#define __TTPCI_EEPROM_H__ #define __TTPCI_EEPROM_H__
#include "dvb_i2c.h" #include <linux/types.h>
#include <linux/i2c.h>
extern int ttpci_eeprom_parse_mac(struct dvb_i2c_bus *i2c); extern int ttpci_eeprom_parse_mac(struct i2c_adapter *adapter, u8 *propsed_mac);
#endif #endif
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/wait.h> #include <linux/wait.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/usb.h> #include <linux/usb.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/time.h> #include <linux/time.h>
...@@ -28,8 +29,6 @@ ...@@ -28,8 +29,6 @@
#include <linux/dvb/dmx.h> #include <linux/dvb/dmx.h>
#include <linux/pci.h> #include <linux/pci.h>
#include "dvb_functions.h"
/* /*
TTUSB_HWSECTIONS: TTUSB_HWSECTIONS:
the DSP supports filtering in hardware, however, since the "muxstream" the DSP supports filtering in hardware, however, since the "muxstream"
...@@ -49,7 +48,10 @@ ...@@ -49,7 +48,10 @@
this unless the device doesn't load at all. > 2 for bandwidth statistics. this unless the device doesn't load at all. > 2 for bandwidth statistics.
*/ */
static int debug = 0; static int debug;
module_param(debug, int, 0644);
MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
#define dprintk(x...) do { if (debug) printk(KERN_DEBUG x); } while (0) #define dprintk(x...) do { if (debug) printk(KERN_DEBUG x); } while (0)
...@@ -80,6 +82,8 @@ struct ttusb { ...@@ -80,6 +82,8 @@ struct ttusb {
struct dvb_adapter *adapter; struct dvb_adapter *adapter;
struct usb_device *dev; struct usb_device *dev;
struct i2c_adapter i2c_adap;
int disconnecting; int disconnecting;
int iso_streaming; int iso_streaming;
...@@ -242,10 +246,9 @@ static int ttusb_i2c_msg(struct ttusb *ttusb, ...@@ -242,10 +246,9 @@ static int ttusb_i2c_msg(struct ttusb *ttusb,
return rcv_len; return rcv_len;
} }
static int ttusb_i2c_xfer(struct dvb_i2c_bus *i2c, const struct i2c_msg msg[], static int master_xfer(struct i2c_adapter* adapter, struct i2c_msg msg[], int num)
int num)
{ {
struct ttusb *ttusb = i2c->data; struct ttusb *ttusb = i2c_get_adapdata(adapter);
int i = 0; int i = 0;
int inc; int inc;
...@@ -514,7 +517,7 @@ static int ttusb_set_tone(struct ttusb *ttusb, fe_sec_tone_mode_t tone) ...@@ -514,7 +517,7 @@ static int ttusb_set_tone(struct ttusb *ttusb, fe_sec_tone_mode_t tone)
static int ttusb_lnb_ioctl(struct dvb_frontend *fe, unsigned int cmd, void *arg) static int ttusb_lnb_ioctl(struct dvb_frontend *fe, unsigned int cmd, void *arg)
{ {
struct ttusb *ttusb = fe->i2c->data; struct ttusb *ttusb = fe->before_after_data;
switch (cmd) { switch (cmd) {
case FE_SET_VOLTAGE: case FE_SET_VOLTAGE:
...@@ -787,7 +790,7 @@ static void ttusb_iso_irq(struct urb *urb, struct pt_regs *ptregs) ...@@ -787,7 +790,7 @@ static void ttusb_iso_irq(struct urb *urb, struct pt_regs *ptregs)
ttusb_process_frame(ttusb, data, len); ttusb_process_frame(ttusb, data, len);
} }
} }
usb_submit_urb(urb, GFP_KERNEL); usb_submit_urb(urb, GFP_ATOMIC);
} }
static void ttusb_free_iso_urbs(struct ttusb *ttusb) static void ttusb_free_iso_urbs(struct ttusb *ttusb)
...@@ -822,7 +825,7 @@ static int ttusb_alloc_iso_urbs(struct ttusb *ttusb) ...@@ -822,7 +825,7 @@ static int ttusb_alloc_iso_urbs(struct ttusb *ttusb)
if (! if (!
(urb = (urb =
usb_alloc_urb(FRAMES_PER_ISO_BUF, GFP_KERNEL))) { usb_alloc_urb(FRAMES_PER_ISO_BUF, GFP_ATOMIC))) {
ttusb_free_iso_urbs(ttusb); ttusb_free_iso_urbs(ttusb);
return -ENOMEM; return -ENOMEM;
} }
...@@ -880,7 +883,7 @@ static int ttusb_start_iso_xfer(struct ttusb *ttusb) ...@@ -880,7 +883,7 @@ static int ttusb_start_iso_xfer(struct ttusb *ttusb)
} }
for (i = 0; i < ISO_BUF_COUNT; i++) { for (i = 0; i < ISO_BUF_COUNT; i++) {
if ((err = usb_submit_urb(ttusb->iso_urb[i], GFP_KERNEL))) { if ((err = usb_submit_urb(ttusb->iso_urb[i], GFP_ATOMIC))) {
ttusb_stop_iso_xfer(ttusb); ttusb_stop_iso_xfer(ttusb);
printk printk
("%s: failed urb submission (%i: err = %i)!\n", ("%s: failed urb submission (%i: err = %i)!\n",
...@@ -1068,6 +1071,38 @@ static struct file_operations stc_fops = { ...@@ -1068,6 +1071,38 @@ static struct file_operations stc_fops = {
}; };
#endif #endif
u32 functionality(struct i2c_adapter *adapter)
{
return I2C_FUNC_I2C;
}
static struct i2c_algorithm ttusb_dec_algo = {
.name = "ttusb dec i2c algorithm",
.id = I2C_ALGO_BIT,
.master_xfer = master_xfer,
.functionality = functionality,
};
static int client_register(struct i2c_client *client)
{
struct ttusb *ttusb = (struct ttusb*)i2c_get_adapdata(client->adapter);
if (client->driver->command)
return client->driver->command(client, FE_REGISTER, ttusb->adapter);
return 0;
}
static int client_unregister(struct i2c_client *client)
{
struct ttusb *ttusb = (struct ttusb*)i2c_get_adapdata(client->adapter);
if (client->driver->command)
return client->driver->command(client, FE_UNREGISTER, ttusb->adapter);
return 0;
}
static int ttusb_probe(struct usb_interface *intf, const struct usb_device_id *id) static int ttusb_probe(struct usb_interface *intf, const struct usb_device_id *id)
{ {
struct usb_device *udev; struct usb_device *udev;
...@@ -1078,17 +1113,6 @@ static int ttusb_probe(struct usb_interface *intf, const struct usb_device_id *i ...@@ -1078,17 +1113,6 @@ static int ttusb_probe(struct usb_interface *intf, const struct usb_device_id *i
udev = interface_to_usbdev(intf); udev = interface_to_usbdev(intf);
/* Device has already been reset; its configuration was chosen.
* If this fault happens, use a hotplug script to choose the
* right configuration (write bConfigurationValue in sysfs).
*/
if (udev->actconfig->desc.bConfigurationValue != 1) {
dev_err(&intf->dev, "device config is #%d, need #1\n",
udev->actconfig->desc.bConfigurationValue);
return -ENODEV;
}
if (intf->altsetting->desc.bInterfaceNumber != 1) return -ENODEV; if (intf->altsetting->desc.bInterfaceNumber != 1) return -ENODEV;
if (!(ttusb = kmalloc(sizeof(struct ttusb), GFP_KERNEL))) if (!(ttusb = kmalloc(sizeof(struct ttusb), GFP_KERNEL)))
...@@ -1117,7 +1141,29 @@ static int ttusb_probe(struct usb_interface *intf, const struct usb_device_id *i ...@@ -1117,7 +1141,29 @@ static int ttusb_probe(struct usb_interface *intf, const struct usb_device_id *i
dvb_register_adapter(&ttusb->adapter, "Technotrend/Hauppauge Nova-USB", THIS_MODULE); dvb_register_adapter(&ttusb->adapter, "Technotrend/Hauppauge Nova-USB", THIS_MODULE);
dvb_register_i2c_bus(ttusb_i2c_xfer, ttusb, ttusb->adapter, 0); /* i2c */
memset(&ttusb->i2c_adap, 0, sizeof(struct i2c_adapter));
strcpy(ttusb->i2c_adap.name, "TTUSB DEC");
i2c_set_adapdata(&ttusb->i2c_adap, ttusb);
#ifdef I2C_ADAP_CLASS_TV_DIGITAL
ttusb->i2c_adap.class = I2C_ADAP_CLASS_TV_DIGITAL;
#else
ttusb->i2c_adap.class = I2C_CLASS_TV_DIGITAL;
#endif
ttusb->i2c_adap.algo = &ttusb_dec_algo;
ttusb->i2c_adap.algo_data = NULL;
ttusb->i2c_adap.id = I2C_ALGO_BIT;
ttusb->i2c_adap.client_register = client_register;
ttusb->i2c_adap.client_unregister = client_unregister;
result = i2c_add_adapter(&ttusb->i2c_adap);
if (result) {
dvb_unregister_adapter (ttusb->adapter);
return result;
}
dvb_add_frontend_ioctls(ttusb->adapter, ttusb_lnb_ioctl, NULL, dvb_add_frontend_ioctls(ttusb->adapter, ttusb_lnb_ioctl, NULL,
ttusb); ttusb);
...@@ -1137,9 +1183,10 @@ static int ttusb_probe(struct usb_interface *intf, const struct usb_device_id *i ...@@ -1137,9 +1183,10 @@ static int ttusb_probe(struct usb_interface *intf, const struct usb_device_id *i
ttusb->dvb_demux.write_to_decoder = NULL; ttusb->dvb_demux.write_to_decoder = NULL;
if ((result = dvb_dmx_init(&ttusb->dvb_demux)) < 0) { if ((result = dvb_dmx_init(&ttusb->dvb_demux)) < 0) {
printk("ttusb_dvb: dvb_dmx_init failed (errno = %d)\n", printk("ttusb_dvb: dvb_dmx_init failed (errno = %d)\n", result);
result); i2c_del_adapter(&ttusb->i2c_adap);
goto err; dvb_unregister_adapter (ttusb->adapter);
return -ENODEV;
} }
//FIXME dmxdev (nur WAS?) //FIXME dmxdev (nur WAS?)
ttusb->dmxdev.filternum = ttusb->dvb_demux.filternum; ttusb->dmxdev.filternum = ttusb->dvb_demux.filternum;
...@@ -1150,15 +1197,20 @@ static int ttusb_probe(struct usb_interface *intf, const struct usb_device_id *i ...@@ -1150,15 +1197,20 @@ static int ttusb_probe(struct usb_interface *intf, const struct usb_device_id *i
printk("ttusb_dvb: dvb_dmxdev_init failed (errno = %d)\n", printk("ttusb_dvb: dvb_dmxdev_init failed (errno = %d)\n",
result); result);
dvb_dmx_release(&ttusb->dvb_demux); dvb_dmx_release(&ttusb->dvb_demux);
goto err; i2c_del_adapter(&ttusb->i2c_adap);
dvb_unregister_adapter (ttusb->adapter);
return -ENODEV;
} }
if (dvb_net_init if (dvb_net_init(ttusb->adapter, &ttusb->dvbnet, &ttusb->dvb_demux.dmx)) {
(ttusb->adapter, &ttusb->dvbnet, &ttusb->dvb_demux.dmx)) {
printk("ttusb_dvb: dvb_net_init failed!\n"); printk("ttusb_dvb: dvb_net_init failed!\n");
dvb_dmxdev_release(&ttusb->dmxdev);
dvb_dmx_release(&ttusb->dvb_demux);
i2c_del_adapter(&ttusb->i2c_adap);
dvb_unregister_adapter (ttusb->adapter);
return -ENODEV;
} }
err:
#if 0 #if 0
ttusb->stc_devfs_handle = ttusb->stc_devfs_handle =
devfs_register(ttusb->adapter->devfs_handle, TTUSB_BUDGET_NAME, devfs_register(ttusb->adapter->devfs_handle, TTUSB_BUDGET_NAME,
...@@ -1187,7 +1239,7 @@ static void ttusb_disconnect(struct usb_interface *intf) ...@@ -1187,7 +1239,7 @@ static void ttusb_disconnect(struct usb_interface *intf)
dvb_dmxdev_release(&ttusb->dmxdev); dvb_dmxdev_release(&ttusb->dmxdev);
dvb_dmx_release(&ttusb->dvb_demux); dvb_dmx_release(&ttusb->dvb_demux);
dvb_unregister_i2c_bus(ttusb_i2c_xfer, ttusb->adapter, 0); i2c_del_adapter(&ttusb->i2c_adap);
dvb_unregister_adapter(ttusb->adapter); dvb_unregister_adapter(ttusb->adapter);
ttusb_free_iso_urbs(ttusb); ttusb_free_iso_urbs(ttusb);
...@@ -1234,9 +1286,6 @@ static void __exit ttusb_exit(void) ...@@ -1234,9 +1286,6 @@ static void __exit ttusb_exit(void)
module_init(ttusb_init); module_init(ttusb_init);
module_exit(ttusb_exit); module_exit(ttusb_exit);
MODULE_PARM(debug, "i");
MODULE_PARM_DESC(debug, "Debug or not");
MODULE_AUTHOR("Holger Waechtler <holger@convergence.de>"); MODULE_AUTHOR("Holger Waechtler <holger@convergence.de>");
MODULE_DESCRIPTION("TTUSB DVB Driver"); MODULE_DESCRIPTION("TTUSB DVB Driver");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
...@@ -22,10 +22,12 @@ ...@@ -22,10 +22,12 @@
#include <asm/semaphore.h> #include <asm/semaphore.h>
#include <linux/list.h> #include <linux/list.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/pci.h> #include <linux/pci.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include <linux/usb.h> #include <linux/usb.h>
#include <linux/version.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/firmware.h> #include <linux/firmware.h>
#if defined(CONFIG_CRC32) || defined(CONFIG_CRC32_MODULE) #if defined(CONFIG_CRC32) || defined(CONFIG_CRC32_MODULE)
...@@ -37,13 +39,17 @@ ...@@ -37,13 +39,17 @@
#include "dmxdev.h" #include "dmxdev.h"
#include "dvb_demux.h" #include "dvb_demux.h"
#include "dvb_i2c.h"
#include "dvb_filter.h" #include "dvb_filter.h"
#include "dvb_frontend.h" #include "dvb_frontend.h"
#include "dvb_net.h" #include "dvb_net.h"
static int debug = 0; static int debug;
static int output_pva = 0; static int output_pva;
module_param(debug, int, 0644);
MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
module_param(output_pva, int, 0444);
MODULE_PARM_DESC(output_pva, "Output PVA from dvr device (default:off)");
#define dprintk if (debug) printk #define dprintk if (debug) printk
...@@ -95,7 +101,6 @@ struct ttusb_dec { ...@@ -95,7 +101,6 @@ struct ttusb_dec {
struct dmxdev dmxdev; struct dmxdev dmxdev;
struct dvb_demux demux; struct dvb_demux demux;
struct dmx_frontend frontend; struct dmx_frontend frontend;
struct dvb_i2c_bus i2c_bus;
struct dvb_net dvb_net; struct dvb_net dvb_net;
struct dvb_frontend_info *frontend_info; struct dvb_frontend_info *frontend_info;
int (*frontend_ioctl) (struct dvb_frontend *, unsigned int, void *); int (*frontend_ioctl) (struct dvb_frontend *, unsigned int, void *);
...@@ -1100,7 +1105,7 @@ static int ttusb_dec_alloc_iso_urbs(struct ttusb_dec *dec) ...@@ -1100,7 +1105,7 @@ static int ttusb_dec_alloc_iso_urbs(struct ttusb_dec *dec)
&dec->iso_dma_handle); &dec->iso_dma_handle);
memset(dec->iso_buffer, 0, memset(dec->iso_buffer, 0,
sizeof(ISO_FRAME_SIZE * (FRAMES_PER_ISO_BUF * ISO_BUF_COUNT))); ISO_FRAME_SIZE * (FRAMES_PER_ISO_BUF * ISO_BUF_COUNT));
for (i = 0; i < ISO_BUF_COUNT; i++) { for (i = 0; i < ISO_BUF_COUNT; i++) {
struct urb *urb; struct urb *urb;
...@@ -1600,7 +1605,7 @@ static int ttusb_dec_3000s_frontend_ioctl(struct dvb_frontend *fe, ...@@ -1600,7 +1605,7 @@ static int ttusb_dec_3000s_frontend_ioctl(struct dvb_frontend *fe,
p->u.qam.symbol_rate); p->u.qam.symbol_rate);
dprintk(" inversion->%d\n", p->inversion); dprintk(" inversion->%d\n", p->inversion);
freq = htonl(p->frequency * 1000 + freq = htonl(p->frequency +
(dec->hi_band ? LOF_HI : LOF_LO)); (dec->hi_band ? LOF_HI : LOF_LO));
memcpy(&b[4], &freq, sizeof(u32)); memcpy(&b[4], &freq, sizeof(u32));
sym_rate = htonl(p->u.qam.symbol_rate); sym_rate = htonl(p->u.qam.symbol_rate);
...@@ -1628,9 +1633,18 @@ static int ttusb_dec_3000s_frontend_ioctl(struct dvb_frontend *fe, ...@@ -1628,9 +1633,18 @@ static int ttusb_dec_3000s_frontend_ioctl(struct dvb_frontend *fe,
dprintk("%s: FE_INIT\n", __FUNCTION__); dprintk("%s: FE_INIT\n", __FUNCTION__);
break; break;
case FE_DISEQC_SEND_MASTER_CMD: case FE_DISEQC_SEND_MASTER_CMD: {
u8 b[] = { 0x00, 0xff, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00 };
struct dvb_diseqc_master_cmd *cmd = arg;
memcpy(&b[4], cmd->msg, cmd->msg_len);
dprintk("%s: FE_DISEQC_SEND_MASTER_CMD\n", __FUNCTION__); dprintk("%s: FE_DISEQC_SEND_MASTER_CMD\n", __FUNCTION__);
ttusb_dec_send_command(dec, 0x72,
sizeof(b) - (6 - cmd->msg_len), b,
NULL, NULL);
break; break;
}
case FE_DISEQC_SEND_BURST: case FE_DISEQC_SEND_BURST:
dprintk("%s: FE_DISEQC_SEND_BURST\n", __FUNCTION__); dprintk("%s: FE_DISEQC_SEND_BURST\n", __FUNCTION__);
...@@ -1669,15 +1683,13 @@ static int ttusb_dec_3000s_frontend_ioctl(struct dvb_frontend *fe, ...@@ -1669,15 +1683,13 @@ static int ttusb_dec_3000s_frontend_ioctl(struct dvb_frontend *fe,
static void ttusb_dec_init_frontend(struct ttusb_dec *dec) static void ttusb_dec_init_frontend(struct ttusb_dec *dec)
{ {
dec->i2c_bus.adapter = dec->adapter; int ret;
ret = dvb_register_frontend(dec->frontend_ioctl, dec->adapter, dec, dec->frontend_info, THIS_MODULE);
dvb_register_frontend(dec->frontend_ioctl, &dec->i2c_bus, (void *)dec,
dec->frontend_info);
} }
static void ttusb_dec_exit_frontend(struct ttusb_dec *dec) static void ttusb_dec_exit_frontend(struct ttusb_dec *dec)
{ {
dvb_unregister_frontend(dec->frontend_ioctl, &dec->i2c_bus); dvb_unregister_frontend_new(dec->frontend_ioctl, dec->adapter);
} }
static void ttusb_dec_init_filters(struct ttusb_dec *dec) static void ttusb_dec_init_filters(struct ttusb_dec *dec)
...@@ -1840,7 +1852,3 @@ MODULE_DESCRIPTION(DRIVER_NAME); ...@@ -1840,7 +1852,3 @@ MODULE_DESCRIPTION(DRIVER_NAME);
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
MODULE_DEVICE_TABLE(usb, ttusb_dec_table); MODULE_DEVICE_TABLE(usb, ttusb_dec_table);
MODULE_PARM(debug, "i");
MODULE_PARM_DESC(debug, "Debug level");
MODULE_PARM(output_pva, "i");
MODULE_PARM_DESC(output_pva, "Output PVA from dvr device");
...@@ -94,6 +94,7 @@ typedef enum { ...@@ -94,6 +94,7 @@ typedef enum {
OSD_Text, // (x0,y0,size,color,text) OSD_Text, // (x0,y0,size,color,text)
OSD_SetWindow, // (x0) set window with number 0<x0<8 as current OSD_SetWindow, // (x0) set window with number 0<x0<8 as current
OSD_MoveWindow, // move current window to (x0, y0) OSD_MoveWindow, // move current window to (x0, y0)
OSD_OpenRaw, // Open other types of OSD windows
} OSD_Command; } OSD_Command;
typedef struct osd_cmd_s { typedef struct osd_cmd_s {
...@@ -106,8 +107,39 @@ typedef struct osd_cmd_s { ...@@ -106,8 +107,39 @@ typedef struct osd_cmd_s {
void __user *data; void __user *data;
} osd_cmd_t; } osd_cmd_t;
/* OSD_OpenRaw: set 'color' to desired window type */
typedef enum {
OSD_BITMAP1, /* 1 bit bitmap */
OSD_BITMAP2, /* 2 bit bitmap */
OSD_BITMAP4, /* 4 bit bitmap */
OSD_BITMAP8, /* 8 bit bitmap */
OSD_BITMAP1HR, /* 1 Bit bitmap half resolution */
OSD_BITMAP2HR, /* 2 bit bitmap half resolution */
OSD_BITMAP4HR, /* 4 bit bitmap half resolution */
OSD_BITMAP8HR, /* 8 bit bitmap half resolution */
OSD_YCRCB422, /* 4:2:2 YCRCB Graphic Display */
OSD_YCRCB444, /* 4:4:4 YCRCB Graphic Display */
OSD_YCRCB444HR, /* 4:4:4 YCRCB graphic half resolution */
OSD_VIDEOTSIZE, /* True Size Normal MPEG Video Display */
OSD_VIDEOHSIZE, /* MPEG Video Display Half Resolution */
OSD_VIDEOQSIZE, /* MPEG Video Display Quarter Resolution */
OSD_VIDEODSIZE, /* MPEG Video Display Double Resolution */
OSD_VIDEOTHSIZE, /* True Size MPEG Video Display Half Resolution */
OSD_VIDEOTQSIZE, /* True Size MPEG Video Display Quarter Resolution*/
OSD_VIDEOTDSIZE, /* True Size MPEG Video Display Double Resolution */
OSD_VIDEONSIZE, /* Full Size MPEG Video Display */
OSD_CURSOR /* Cursor */
} osd_raw_window_t;
typedef struct osd_cap_s {
int cmd;
#define OSD_CAP_MEMSIZE 1 /* memory size */
long val;
} osd_cap_t;
#define OSD_SEND_CMD _IOW('o', 160, osd_cmd_t) #define OSD_SEND_CMD _IOW('o', 160, osd_cmd_t)
#define OSD_GET_CAPABILITY _IOR('o', 161, osd_cap_t)
#endif #endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment