aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging/tm6000
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging/tm6000')
-rw-r--r--drivers/staging/tm6000/Kconfig4
-rw-r--r--drivers/staging/tm6000/Makefile8
-rw-r--r--drivers/staging/tm6000/tm6000-alsa.c263
-rw-r--r--drivers/staging/tm6000/tm6000-cards.c58
-rw-r--r--drivers/staging/tm6000/tm6000-core.c182
-rw-r--r--drivers/staging/tm6000/tm6000-dvb.c173
-rw-r--r--drivers/staging/tm6000/tm6000-i2c.c25
-rw-r--r--drivers/staging/tm6000/tm6000-input.c364
-rw-r--r--drivers/staging/tm6000/tm6000-stds.c36
-rw-r--r--drivers/staging/tm6000/tm6000-usb-isoc.h5
-rw-r--r--drivers/staging/tm6000/tm6000-video.c335
-rw-r--r--drivers/staging/tm6000/tm6000.h88
12 files changed, 978 insertions, 563 deletions
diff --git a/drivers/staging/tm6000/Kconfig b/drivers/staging/tm6000/Kconfig
index 3657e33e8817..c725356cc346 100644
--- a/drivers/staging/tm6000/Kconfig
+++ b/drivers/staging/tm6000/Kconfig
@@ -26,8 +26,8 @@ config VIDEO_TM6000_ALSA
module will be called tm6000-alsa.
config VIDEO_TM6000_DVB
- bool "DVB Support for tm6000 based TV cards"
- depends on VIDEO_TM6000 && DVB_CORE && EXPERIMENTAL
+ tristate "DVB Support for tm6000 based TV cards"
+ depends on VIDEO_TM6000 && DVB_CORE && USB && EXPERIMENTAL
select DVB_ZL10353
---help---
This adds support for DVB cards based on the tm5600/tm6000 chip.
diff --git a/drivers/staging/tm6000/Makefile b/drivers/staging/tm6000/Makefile
index 93370fccc073..77e06bfd2c46 100644
--- a/drivers/staging/tm6000/Makefile
+++ b/drivers/staging/tm6000/Makefile
@@ -2,14 +2,12 @@ tm6000-objs := tm6000-cards.o \
tm6000-core.o \
tm6000-i2c.o \
tm6000-video.o \
- tm6000-stds.o
-
-ifeq ($(CONFIG_VIDEO_TM6000_DVB),y)
-tm6000-objs += tm6000-dvb.o
-endif
+ tm6000-stds.o \
+ tm6000-input.o
obj-$(CONFIG_VIDEO_TM6000) += tm6000.o
obj-$(CONFIG_VIDEO_TM6000_ALSA) += tm6000-alsa.o
+obj-$(CONFIG_VIDEO_TM6000_DVB) += tm6000-dvb.o
EXTRA_CFLAGS = -Idrivers/media/video
EXTRA_CFLAGS += -Idrivers/media/common/tuners
diff --git a/drivers/staging/tm6000/tm6000-alsa.c b/drivers/staging/tm6000/tm6000-alsa.c
index 273e26ede650..087137d9164d 100644
--- a/drivers/staging/tm6000/tm6000-alsa.c
+++ b/drivers/staging/tm6000/tm6000-alsa.c
@@ -16,6 +16,7 @@
#include <linux/interrupt.h>
#include <linux/usb.h>
#include <linux/slab.h>
+#include <linux/vmalloc.h>
#include <asm/delay.h>
#include <sound/core.h>
@@ -36,34 +37,11 @@
} while (0)
/****************************************************************************
- Data type declarations - Can be moded to a header file later
- ****************************************************************************/
-
-struct snd_tm6000_card {
- struct snd_card *card;
-
- spinlock_t reg_lock;
-
- atomic_t count;
-
- unsigned int period_size;
- unsigned int num_periods;
-
- struct tm6000_core *core;
- struct tm6000_buffer *buf;
-
- int bufsize;
-
- struct snd_pcm_substream *substream;
-};
-
-
-/****************************************************************************
Module global static vars
****************************************************************************/
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
-static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
+
static int enable[SNDRV_CARDS] = {1, [1 ... (SNDRV_CARDS - 1)] = 1};
module_param_array(enable, bool, NULL, 0444);
@@ -100,11 +78,15 @@ static int _tm6000_start_audio_dma(struct snd_tm6000_card *chip)
struct tm6000_core *core = chip->core;
int val;
+ dprintk(1, "Starting audio DMA\n");
+
/* Enables audio */
val = tm6000_get_reg(core, TM6010_REQ07_RCC_ACTIVE_VIDEO_IF, 0x0);
val |= 0x20;
tm6000_set_reg(core, TM6010_REQ07_RCC_ACTIVE_VIDEO_IF, val);
+ tm6000_set_audio_bitrate(core, 48000);
+
tm6000_set_reg(core, TM6010_REQ08_R01_A_INIT, 0x80);
return 0;
@@ -129,19 +111,39 @@ static int _tm6000_stop_audio_dma(struct snd_tm6000_card *chip)
return 0;
}
-static int dsp_buffer_free(struct snd_tm6000_card *chip)
+static void dsp_buffer_free(struct snd_pcm_substream *substream)
{
- BUG_ON(!chip->bufsize);
+ struct snd_tm6000_card *chip = snd_pcm_substream_chip(substream);
dprintk(2, "Freeing buffer\n");
- /* FIXME: Frees buffer */
+ vfree(substream->runtime->dma_area);
+ substream->runtime->dma_area = NULL;
+ substream->runtime->dma_bytes = 0;
+}
- chip->bufsize = 0;
+static int dsp_buffer_alloc(struct snd_pcm_substream *substream, int size)
+{
+ struct snd_tm6000_card *chip = snd_pcm_substream_chip(substream);
+
+ dprintk(2, "Allocating buffer\n");
+
+ if (substream->runtime->dma_area) {
+ if (substream->runtime->dma_bytes > size)
+ return 0;
+ dsp_buffer_free(substream);
+ }
- return 0;
+ substream->runtime->dma_area = vmalloc(size);
+ if (!substream->runtime->dma_area)
+ return -ENOMEM;
+
+ substream->runtime->dma_bytes = size;
+
+ return 0;
}
+
/****************************************************************************
ALSA PCM Interface
****************************************************************************/
@@ -158,16 +160,16 @@ static struct snd_pcm_hardware snd_tm6000_digital_hw = {
SNDRV_PCM_INFO_MMAP_VALID,
.formats = SNDRV_PCM_FMTBIT_S16_LE,
- .rates = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000,
- .rate_min = 44100,
+ .rates = SNDRV_PCM_RATE_48000,
+ .rate_min = 48000,
.rate_max = 48000,
.channels_min = 2,
.channels_max = 2,
- .period_bytes_min = DEFAULT_FIFO_SIZE/4,
- .period_bytes_max = DEFAULT_FIFO_SIZE/4,
+ .period_bytes_min = 62720,
+ .period_bytes_max = 62720,
.periods_min = 1,
.periods_max = 1024,
- .buffer_bytes_max = (1024*1024),
+ .buffer_bytes_max = 62720 * 8,
};
/*
@@ -202,29 +204,64 @@ static int snd_tm6000_close(struct snd_pcm_substream *substream)
return 0;
}
+static int tm6000_fillbuf(struct tm6000_core *core, char *buf, int size)
+{
+ struct snd_tm6000_card *chip = core->adev;
+ struct snd_pcm_substream *substream = chip->substream;
+ struct snd_pcm_runtime *runtime;
+ int period_elapsed = 0;
+ unsigned int stride, buf_pos;
+
+ if (!size || !substream)
+ return -EINVAL;
+
+ runtime = substream->runtime;
+ if (!runtime || !runtime->dma_area)
+ return -EINVAL;
+
+ buf_pos = chip->buf_pos;
+ stride = runtime->frame_bits >> 3;
+
+ dprintk(1, "Copying %d bytes at %p[%d] - buf size=%d x %d\n", size,
+ runtime->dma_area, buf_pos,
+ (unsigned int)runtime->buffer_size, stride);
+
+ if (buf_pos + size >= runtime->buffer_size * stride) {
+ unsigned int cnt = runtime->buffer_size * stride - buf_pos;
+ memcpy(runtime->dma_area + buf_pos, buf, cnt);
+ memcpy(runtime->dma_area, buf + cnt, size - cnt);
+ } else
+ memcpy(runtime->dma_area + buf_pos, buf, size);
+
+ chip->buf_pos += size;
+ if (chip->buf_pos >= runtime->buffer_size * stride)
+ chip->buf_pos -= runtime->buffer_size * stride;
+
+ chip->period_pos += size;
+ if (chip->period_pos >= runtime->period_size) {
+ chip->period_pos -= runtime->period_size;
+ period_elapsed = 1;
+ }
+
+ if (period_elapsed)
+ snd_pcm_period_elapsed(substream);
+
+ return 0;
+}
+
/*
* hw_params callback
*/
static int snd_tm6000_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *hw_params)
{
- struct snd_tm6000_card *chip = snd_pcm_substream_chip(substream);
-
- if (substream->runtime->dma_area) {
- dsp_buffer_free(chip);
- substream->runtime->dma_area = NULL;
- }
-
- chip->period_size = params_period_bytes(hw_params);
- chip->num_periods = params_periods(hw_params);
- chip->bufsize = chip->period_size * params_periods(hw_params);
-
- BUG_ON(!chip->bufsize);
+ int size, rc;
- dprintk(1, "Setting buffer\n");
-
- /* FIXME: Allocate buffer for audio */
+ size = params_period_bytes(hw_params) * params_periods(hw_params);
+ rc = dsp_buffer_alloc(substream, size);
+ if (rc < 0)
+ return rc;
return 0;
}
@@ -234,13 +271,9 @@ static int snd_tm6000_hw_params(struct snd_pcm_substream *substream,
*/
static int snd_tm6000_hw_free(struct snd_pcm_substream *substream)
{
-
struct snd_tm6000_card *chip = snd_pcm_substream_chip(substream);
- if (substream->runtime->dma_area) {
- dsp_buffer_free(chip);
- substream->runtime->dma_area = NULL;
- }
+ _tm6000_stop_audio_dma(chip);
return 0;
}
@@ -250,6 +283,11 @@ static int snd_tm6000_hw_free(struct snd_pcm_substream *substream)
*/
static int snd_tm6000_prepare(struct snd_pcm_substream *substream)
{
+ struct snd_tm6000_card *chip = snd_pcm_substream_chip(substream);
+
+ chip->buf_pos = 0;
+ chip->period_pos = 0;
+
return 0;
}
@@ -287,12 +325,8 @@ static int snd_tm6000_card_trigger(struct snd_pcm_substream *substream, int cmd)
static snd_pcm_uframes_t snd_tm6000_pointer(struct snd_pcm_substream *substream)
{
struct snd_tm6000_card *chip = snd_pcm_substream_chip(substream);
- struct snd_pcm_runtime *runtime = substream->runtime;
- u16 count;
-
- count = atomic_read(&chip->count);
- return runtime->period_size * (count & (runtime->periods-1));
+ return chip->buf_pos;
}
/*
@@ -312,21 +346,6 @@ static struct snd_pcm_ops snd_tm6000_pcm_ops = {
/*
* create a PCM device
*/
-static int __devinit snd_tm6000_pcm(struct snd_tm6000_card *chip,
- int device, char *name)
-{
- int err;
- struct snd_pcm *pcm;
-
- err = snd_pcm_new(chip->card, name, device, 0, 1, &pcm);
- if (err < 0)
- return err;
- pcm->private_data = chip;
- strcpy(pcm->name, name);
- snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_tm6000_pcm_ops);
-
- return 0;
-}
/* FIXME: Control interface - How to control volume/mute? */
@@ -337,27 +356,41 @@ static int __devinit snd_tm6000_pcm(struct snd_tm6000_card *chip,
/*
* Alsa Constructor - Component probe
*/
-
-int tm6000_audio_init(struct tm6000_core *dev, int idx)
+int tm6000_audio_init(struct tm6000_core *dev)
{
- struct snd_card *card;
- struct snd_tm6000_card *chip;
- int rc, len;
- char component[14];
+ struct snd_card *card;
+ struct snd_tm6000_card *chip;
+ int rc;
+ static int devnr;
+ char component[14];
+ struct snd_pcm *pcm;
+
+ if (!dev)
+ return 0;
- if (idx >= SNDRV_CARDS)
+ if (devnr >= SNDRV_CARDS)
return -ENODEV;
- if (!enable[idx])
+ if (!enable[devnr])
return -ENOENT;
- rc = snd_card_create(index[idx], id[idx], THIS_MODULE, 0, &card);
+ rc = snd_card_create(index[devnr], "tm6000", THIS_MODULE, 0, &card);
if (rc < 0) {
- snd_printk(KERN_ERR "cannot create card instance %d\n", idx);
+ snd_printk(KERN_ERR "cannot create card instance %d\n", devnr);
return rc;
}
+ strcpy(card->driver, "tm6000-alsa");
+ strcpy(card->shortname, "TM5600/60x0");
+ sprintf(card->longname, "TM5600/60x0 Audio at bus %d device %d",
+ dev->udev->bus->busnum, dev->udev->devnum);
+
+ sprintf(component, "USB%04x:%04x",
+ le16_to_cpu(dev->udev->descriptor.idVendor),
+ le16_to_cpu(dev->udev->descriptor.idProduct));
+ snd_component_add(card, component);
+ snd_card_set_dev(card, &dev->udev->dev);
- chip = kzalloc(sizeof(*chip), GFP_KERNEL);
+ chip = kzalloc(sizeof(struct snd_tm6000_card), GFP_KERNEL);
if (!chip) {
rc = -ENOMEM;
goto error;
@@ -365,45 +398,24 @@ int tm6000_audio_init(struct tm6000_core *dev, int idx)
chip->core = dev;
chip->card = card;
+ dev->adev = chip;
+ spin_lock_init(&chip->reg_lock);
- strcpy(card->driver, "tm6000-alsa");
- sprintf(component, "USB%04x:%04x",
- le16_to_cpu(dev->udev->descriptor.idVendor),
- le16_to_cpu(dev->udev->descriptor.idProduct));
- snd_component_add(card, component);
-
- if (dev->udev->descriptor.iManufacturer)
- len = usb_string(dev->udev,
- dev->udev->descriptor.iManufacturer,
- card->longname, sizeof(card->longname));
- else
- len = 0;
-
- if (len > 0)
- strlcat(card->longname, " ", sizeof(card->longname));
-
- strlcat(card->longname, card->shortname, sizeof(card->longname));
-
- len = strlcat(card->longname, " at ", sizeof(card->longname));
-
- if (len < sizeof(card->longname))
- usb_make_path(dev->udev, card->longname + len,
- sizeof(card->longname) - len);
-
- strlcat(card->longname,
- dev->udev->speed == USB_SPEED_LOW ? ", low speed" :
- dev->udev->speed == USB_SPEED_FULL ? ", full speed" :
- ", high speed",
- sizeof(card->longname));
-
- rc = snd_tm6000_pcm(chip, 0, "tm6000 Digital");
+ rc = snd_pcm_new(card, "TM6000 Audio", 0, 0, 1, &pcm);
if (rc < 0)
goto error;
+ pcm->info_flags = 0;
+ pcm->private_data = chip;
+ strcpy(pcm->name, "Trident TM5600/60x0");
+
+ snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_tm6000_pcm_ops);
+
rc = snd_card_register(card);
if (rc < 0)
goto error;
+ dprintk(1,"Registered audio driver for %s\n", card->longname);
return 0;
@@ -414,14 +426,31 @@ error:
static int tm6000_audio_fini(struct tm6000_core *dev)
{
+ struct snd_tm6000_card *chip = dev->adev;
+
+ if (!dev)
+ return 0;
+
+ if (!chip)
+ return 0;
+
+ if (!chip->card)
+ return 0;
+
+ snd_card_free(chip->card);
+ chip->card = NULL;
+ kfree(chip);
+ dev->adev = NULL;
+
return 0;
}
struct tm6000_ops audio_ops = {
- .id = TM6000_AUDIO,
+ .type = TM6000_AUDIO,
.name = "TM6000 Audio Extension",
.init = tm6000_audio_init,
.fini = tm6000_audio_fini,
+ .fillbuf = tm6000_fillbuf,
};
static int __init tm6000_alsa_register(void)
diff --git a/drivers/staging/tm6000/tm6000-cards.c b/drivers/staging/tm6000/tm6000-cards.c
index 6a9ae40c7c6d..9d091c34991b 100644
--- a/drivers/staging/tm6000/tm6000-cards.c
+++ b/drivers/staging/tm6000/tm6000-cards.c
@@ -29,6 +29,7 @@
#include <media/tuner.h>
#include <media/tvaudio.h>
#include <media/i2c-addr.h>
+#include <media/rc-map.h>
#include "tm6000.h"
#include "tm6000-regs.h"
@@ -69,6 +70,8 @@ struct tm6000_board {
int demod_addr; /* demodulator address */
struct tm6000_gpio gpio;
+
+ char *ir_codes;
};
struct tm6000_board tm6000_boards[] = {
@@ -276,6 +279,7 @@ struct tm6000_board tm6000_boards[] = {
.dvb_led = TM6010_GPIO_5,
.ir = TM6010_GPIO_0,
},
+ .ir_codes = RC_MAP_NEC_TERRATEC_CINERGY_XS,
},
[TM6010_BOARD_TWINHAN_TU501] = {
.name = "Twinhan TU501(704D1)",
@@ -347,7 +351,7 @@ int tm6000_xc5000_callback(void *ptr, int component, int command, int arg)
}
return (rc);
}
-
+EXPORT_SYMBOL_GPL(tm6000_xc5000_callback);
/* Tuner callback to provide the proper gpio changes needed for xc2028 */
@@ -361,6 +365,8 @@ int tm6000_tuner_callback(void *ptr, int component, int command, int arg)
switch (command) {
case XC2028_RESET_CLK:
+ tm6000_ir_wait(dev, 0);
+
tm6000_set_reg(dev, REQ_04_EN_DISABLE_MCU_INT,
0x02, arg);
msleep(10);
@@ -410,13 +416,14 @@ int tm6000_tuner_callback(void *ptr, int component, int command, int arg)
msleep(130);
break;
}
+
+ tm6000_ir_wait(dev, 1);
break;
case 1:
tm6000_set_reg(dev, REQ_04_EN_DISABLE_MCU_INT,
0x02, 0x01);
msleep(10);
break;
-
case 2:
rc = tm6000_i2c_reset(dev, 100);
break;
@@ -424,6 +431,7 @@ int tm6000_tuner_callback(void *ptr, int component, int command, int arg)
}
return rc;
}
+EXPORT_SYMBOL_GPL(tm6000_tuner_callback);
int tm6000_cards_setup(struct tm6000_core *dev)
{
@@ -635,6 +643,8 @@ static int tm6000_init_dev(struct tm6000_core *dev)
dev->gpio = tm6000_boards[dev->model].gpio;
+ dev->ir_codes = tm6000_boards[dev->model].ir_codes;
+
dev->demod_addr = tm6000_boards[dev->model].demod_addr;
dev->caps = tm6000_boards[dev->model].caps;
@@ -681,31 +691,13 @@ static int tm6000_init_dev(struct tm6000_core *dev)
goto err;
tm6000_add_into_devlist(dev);
-
tm6000_init_extension(dev);
- if (dev->caps.has_dvb) {
- dev->dvb = kzalloc(sizeof(*(dev->dvb)), GFP_KERNEL);
- if (!dev->dvb) {
- rc = -ENOMEM;
- goto err2;
- }
+ tm6000_ir_init(dev);
-#ifdef CONFIG_VIDEO_TM6000_DVB
- rc = tm6000_dvb_register(dev);
- if (rc < 0) {
- kfree(dev->dvb);
- dev->dvb = NULL;
- goto err2;
- }
-#endif
- }
mutex_unlock(&dev->lock);
return 0;
-err2:
- v4l2_device_unregister(&dev->v4l2_dev);
-
err:
mutex_unlock(&dev->lock);
return rc;
@@ -724,7 +716,7 @@ static void get_max_endpoint(struct usb_device *udev,
unsigned int size = tmp & 0x7ff;
if (udev->speed == USB_SPEED_HIGH)
- size = size * hb_mult (tmp);
+ size = size * hb_mult(tmp);
if (size > tm_ep->maxsize) {
tm_ep->endp = curr_e;
@@ -848,6 +840,19 @@ static int tm6000_usb_probe(struct usb_interface *interface,
&dev->isoc_out);
}
break;
+ case USB_ENDPOINT_XFER_INT:
+ if (!dir_out) {
+ get_max_endpoint(usbdev,
+ &interface->altsetting[i],
+ "INT IN", e,
+ &dev->int_in);
+ } else {
+ get_max_endpoint(usbdev,
+ &interface->altsetting[i],
+ "INT OUT", e,
+ &dev->int_out);
+ }
+ break;
}
}
}
@@ -906,12 +911,7 @@ static void tm6000_usb_disconnect(struct usb_interface *interface)
mutex_lock(&dev->lock);
-#ifdef CONFIG_VIDEO_TM6000_DVB
- if (dev->dvb) {
- tm6000_dvb_unregister(dev);
- kfree(dev->dvb);
- }
-#endif
+ tm6000_ir_fini(dev);
if (dev->gpio.power_led) {
switch (dev->model) {
@@ -942,8 +942,8 @@ static void tm6000_usb_disconnect(struct usb_interface *interface)
usb_put_dev(dev->udev);
- tm6000_remove_from_devlist(dev);
tm6000_close_extension(dev);
+ tm6000_remove_from_devlist(dev);
mutex_unlock(&dev->lock);
kfree(dev);
diff --git a/drivers/staging/tm6000/tm6000-core.c b/drivers/staging/tm6000/tm6000-core.c
index c3690e3580da..cded411d8bba 100644
--- a/drivers/staging/tm6000/tm6000-core.c
+++ b/drivers/staging/tm6000/tm6000-core.c
@@ -32,66 +32,64 @@
#define USB_TIMEOUT 5*HZ /* ms */
-int tm6000_read_write_usb (struct tm6000_core *dev, u8 req_type, u8 req,
- u16 value, u16 index, u8 *buf, u16 len)
+int tm6000_read_write_usb(struct tm6000_core *dev, u8 req_type, u8 req,
+ u16 value, u16 index, u8 *buf, u16 len)
{
int ret, i;
unsigned int pipe;
- static int ini=0, last=0, n=0;
- u8 *data=NULL;
+ static int ini = 0, last = 0, n = 0;
+ u8 *data = NULL;
if (len)
data = kzalloc(len, GFP_KERNEL);
if (req_type & USB_DIR_IN)
- pipe=usb_rcvctrlpipe(dev->udev, 0);
+ pipe = usb_rcvctrlpipe(dev->udev, 0);
else {
- pipe=usb_sndctrlpipe(dev->udev, 0);
+ pipe = usb_sndctrlpipe(dev->udev, 0);
memcpy(data, buf, len);
}
if (tm6000_debug & V4L2_DEBUG_I2C) {
if (!ini)
- last=ini=jiffies;
+ last = ini = jiffies;
printk("%06i (dev %p, pipe %08x): ", n, dev->udev, pipe);
- printk( "%s: %06u ms %06u ms %02x %02x %02x %02x %02x %02x %02x %02x ",
- (req_type & USB_DIR_IN)?" IN":"OUT",
+ printk("%s: %06u ms %06u ms %02x %02x %02x %02x %02x %02x %02x %02x ",
+ (req_type & USB_DIR_IN) ? " IN" : "OUT",
jiffies_to_msecs(jiffies-last),
jiffies_to_msecs(jiffies-ini),
- req_type, req,value&0xff,value>>8, index&0xff, index>>8,
- len&0xff, len>>8);
- last=jiffies;
+ req_type, req, value&0xff, value>>8, index&0xff,
+ index>>8, len&0xff, len>>8);
+ last = jiffies;
n++;
- if ( !(req_type & USB_DIR_IN) ) {
+ if (!(req_type & USB_DIR_IN)) {
printk(">>> ");
- for (i=0;i<len;i++) {
- printk(" %02x",buf[i]);
- }
+ for (i = 0; i < len; i++)
+ printk(" %02x", buf[i]);
printk("\n");
}
}
- ret = usb_control_msg(dev->udev, pipe, req, req_type, value, index, data,
- len, USB_TIMEOUT);
+ ret = usb_control_msg(dev->udev, pipe, req, req_type, value, index,
+ data, len, USB_TIMEOUT);
if (req_type & USB_DIR_IN)
memcpy(buf, data, len);
if (tm6000_debug & V4L2_DEBUG_I2C) {
- if (ret<0) {
+ if (ret < 0) {
if (req_type & USB_DIR_IN)
- printk("<<< (len=%d)\n",len);
+ printk("<<< (len=%d)\n", len);
printk("%s: Error #%d\n", __FUNCTION__, ret);
} else if (req_type & USB_DIR_IN) {
printk("<<< ");
- for (i=0;i<len;i++) {
- printk(" %02x",buf[i]);
- }
+ for (i = 0; i < len; i++)
+ printk(" %02x", buf[i]);
printk("\n");
}
}
@@ -103,52 +101,52 @@ int tm6000_read_write_usb (struct tm6000_core *dev, u8 req_type, u8 req,
return ret;
}
-int tm6000_set_reg (struct tm6000_core *dev, u8 req, u16 value, u16 index)
+int tm6000_set_reg(struct tm6000_core *dev, u8 req, u16 value, u16 index)
{
return
- tm6000_read_write_usb (dev, USB_DIR_OUT | USB_TYPE_VENDOR,
- req, value, index, NULL, 0);
+ tm6000_read_write_usb(dev, USB_DIR_OUT | USB_TYPE_VENDOR,
+ req, value, index, NULL, 0);
}
EXPORT_SYMBOL_GPL(tm6000_set_reg);
-int tm6000_get_reg (struct tm6000_core *dev, u8 req, u16 value, u16 index)
+int tm6000_get_reg(struct tm6000_core *dev, u8 req, u16 value, u16 index)
{
int rc;
u8 buf[1];
- rc=tm6000_read_write_usb (dev, USB_DIR_IN | USB_TYPE_VENDOR, req,
- value, index, buf, 1);
+ rc = tm6000_read_write_usb(dev, USB_DIR_IN | USB_TYPE_VENDOR, req,
+ value, index, buf, 1);
- if (rc<0)
+ if (rc < 0)
return rc;
return *buf;
}
EXPORT_SYMBOL_GPL(tm6000_get_reg);
-int tm6000_get_reg16 (struct tm6000_core *dev, u8 req, u16 value, u16 index)
+int tm6000_get_reg16(struct tm6000_core *dev, u8 req, u16 value, u16 index)
{
int rc;
u8 buf[2];
- rc=tm6000_read_write_usb (dev, USB_DIR_IN | USB_TYPE_VENDOR, req,
- value, index, buf, 2);
+ rc = tm6000_read_write_usb(dev, USB_DIR_IN | USB_TYPE_VENDOR, req,
+ value, index, buf, 2);
- if (rc<0)
+ if (rc < 0)
return rc;
return buf[1]|buf[0]<<8;
}
-int tm6000_get_reg32 (struct tm6000_core *dev, u8 req, u16 value, u16 index)
+int tm6000_get_reg32(struct tm6000_core *dev, u8 req, u16 value, u16 index)
{
int rc;
u8 buf[4];
- rc=tm6000_read_write_usb (dev, USB_DIR_IN | USB_TYPE_VENDOR, req,
- value, index, buf, 4);
+ rc = tm6000_read_write_usb(dev, USB_DIR_IN | USB_TYPE_VENDOR, req,
+ value, index, buf, 4);
- if (rc<0)
+ if (rc < 0)
return rc;
return buf[3] | buf[2] << 8 | buf[1] << 16 | buf[0] << 24;
@@ -188,7 +186,7 @@ void tm6000_set_fourcc_format(struct tm6000_core *dev)
}
}
-int tm6000_init_analog_mode (struct tm6000_core *dev)
+int tm6000_init_analog_mode(struct tm6000_core *dev)
{
if (dev->dev_type == TM6010) {
int val;
@@ -294,12 +292,10 @@ int tm6000_init_analog_mode (struct tm6000_core *dev)
/* Enables soft reset */
tm6000_set_reg(dev, TM6010_REQ07_R3F_RESET, 0x01);
- if (dev->scaler) {
+ if (dev->scaler)
tm6000_set_reg(dev, TM6010_REQ07_RC0_ACTIVE_VIDEO_SOURCE, 0x20);
- } else {
- /* Enable Hfilter and disable TS Drop err */
+ else /* Enable Hfilter and disable TS Drop err */
tm6000_set_reg(dev, TM6010_REQ07_RC0_ACTIVE_VIDEO_SOURCE, 0x80);
- }
tm6000_set_reg(dev, TM6010_REQ07_RC3_HSTART1, 0x88);
tm6000_set_reg(dev, TM6010_REQ07_RD8_IR_WAKEUP_SEL, 0x23);
@@ -332,13 +328,13 @@ int tm6000_init_analog_mode (struct tm6000_core *dev)
/*FIXME: Hack!!! */
struct v4l2_frequency f;
mutex_lock(&dev->lock);
- f.frequency=dev->freq;
+ f.frequency = dev->freq;
v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_frequency, &f);
mutex_unlock(&dev->lock);
msleep(100);
- tm6000_set_standard (dev, &dev->norm);
- tm6000_set_audio_bitrate (dev,48000);
+ tm6000_set_standard(dev, &dev->norm);
+ tm6000_set_audio_bitrate(dev, 48000);
/* switch dvb led off */
if (dev->gpio.dvb_led) {
@@ -349,7 +345,7 @@ int tm6000_init_analog_mode (struct tm6000_core *dev)
return 0;
}
-int tm6000_init_digital_mode (struct tm6000_core *dev)
+int tm6000_init_digital_mode(struct tm6000_core *dev)
{
if (dev->dev_type == TM6010) {
int val;
@@ -366,10 +362,8 @@ int tm6000_init_digital_mode (struct tm6000_core *dev)
tm6000_set_reg(dev, TM6010_REQ08_RE2_POWER_DOWN_CTRL1, 0xfc);
tm6000_set_reg(dev, TM6010_REQ08_RE6_POWER_DOWN_CTRL2, 0xff);
tm6000_set_reg(dev, TM6010_REQ08_RF1_AADC_POWER_DOWN, 0xfe);
- tm6000_read_write_usb (dev, 0xc0, 0x0e, 0x00c2, 0x0008, buf, 2);
- printk (KERN_INFO "buf %#x %#x \n", buf[0], buf[1]);
-
-
+ tm6000_read_write_usb(dev, 0xc0, 0x0e, 0x00c2, 0x0008, buf, 2);
+ printk(KERN_INFO"buf %#x %#x\n", buf[0], buf[1]);
} else {
tm6000_set_reg(dev, TM6010_REQ07_RFF_SOFT_RESET, 0x08);
tm6000_set_reg(dev, TM6010_REQ07_RFF_SOFT_RESET, 0x00);
@@ -377,7 +371,7 @@ int tm6000_init_digital_mode (struct tm6000_core *dev)
tm6000_set_reg(dev, TM6010_REQ07_RD8_IR_PULSE_CNT0, 0x08);
tm6000_set_reg(dev, TM6010_REQ07_RE2_OUT_SEL2, 0x0c);
tm6000_set_reg(dev, TM6010_REQ07_RE8_TYPESEL_MOS_I2S, 0xff);
- tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00eb, 0xd8);
+ tm6000_set_reg(dev, REQ_07_SET_GET_AVREG, 0x00eb, 0xd8);
tm6000_set_reg(dev, TM6010_REQ07_RC0_ACTIVE_VIDEO_SOURCE, 0x40);
tm6000_set_reg(dev, TM6010_REQ07_RC1_TRESHOLD, 0xd0);
tm6000_set_reg(dev, TM6010_REQ07_RC3_HSTART1, 0x09);
@@ -388,14 +382,14 @@ int tm6000_init_digital_mode (struct tm6000_core *dev)
tm6000_set_reg(dev, TM6010_REQ07_RE2_OUT_SEL2, 0x0c);
tm6000_set_reg(dev, TM6010_REQ07_RE8_TYPESEL_MOS_I2S, 0xff);
- tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0x00eb, 0x08);
+ tm6000_set_reg(dev, REQ_07_SET_GET_AVREG, 0x00eb, 0x08);
msleep(50);
- tm6000_set_reg (dev, REQ_04_EN_DISABLE_MCU_INT, 0x0020, 0x00);
+ tm6000_set_reg(dev, REQ_04_EN_DISABLE_MCU_INT, 0x0020, 0x00);
msleep(50);
- tm6000_set_reg (dev, REQ_04_EN_DISABLE_MCU_INT, 0x0020, 0x01);
+ tm6000_set_reg(dev, REQ_04_EN_DISABLE_MCU_INT, 0x0020, 0x01);
msleep(50);
- tm6000_set_reg (dev, REQ_04_EN_DISABLE_MCU_INT, 0x0020, 0x00);
+ tm6000_set_reg(dev, REQ_04_EN_DISABLE_MCU_INT, 0x0020, 0x00);
msleep(100);
}
@@ -407,6 +401,7 @@ int tm6000_init_digital_mode (struct tm6000_core *dev)
return 0;
}
+EXPORT_SYMBOL(tm6000_init_digital_mode);
struct reg_init {
u8 req;
@@ -566,9 +561,9 @@ struct reg_init tm6010_init_tab[] = {
{ TM6010_REQ07_RD8_IR_WAKEUP_SEL, 0xff },
};
-int tm6000_init (struct tm6000_core *dev)
+int tm6000_init(struct tm6000_core *dev)
{
- int board, rc=0, i, size;
+ int board, rc = 0, i, size;
struct reg_init *tab;
if (dev->dev_type == TM6010) {
@@ -580,12 +575,12 @@ int tm6000_init (struct tm6000_core *dev)
}
/* Load board's initialization table */
- for (i=0; i< size; i++) {
- rc= tm6000_set_reg (dev, tab[i].req, tab[i].reg, tab[i].val);
- if (rc<0) {
- printk (KERN_ERR "Error %i while setting req %d, "
- "reg %d to value %d\n", rc,
- tab[i].req,tab[i].reg, tab[i].val);
+ for (i = 0; i < size; i++) {
+ rc = tm6000_set_reg(dev, tab[i].req, tab[i].reg, tab[i].val);
+ if (rc < 0) {
+ printk(KERN_ERR "Error %i while setting req %d, "
+ "reg %d to value %d\n", rc,
+ tab[i].req, tab[i].reg, tab[i].val);
return rc;
}
}
@@ -593,12 +588,11 @@ int tm6000_init (struct tm6000_core *dev)
msleep(5); /* Just to be conservative */
/* Check board version - maybe 10Moons specific */
- board=tm6000_get_reg32 (dev, REQ_40_GET_VERSION, 0, 0);
- if (board >=0) {
- printk (KERN_INFO "Board version = 0x%08x\n",board);
- } else {
- printk (KERN_ERR "Error %i while retrieving board version\n",board);
- }
+ board = tm6000_get_reg32(dev, REQ_40_GET_VERSION, 0, 0);
+ if (board >= 0)
+ printk(KERN_INFO "Board version = 0x%08x\n", board);
+ else
+ printk(KERN_ERR "Error %i while retrieving board version\n", board);
rc = tm6000_cards_setup(dev);
@@ -609,23 +603,32 @@ int tm6000_set_audio_bitrate(struct tm6000_core *dev, int bitrate)
{
int val;
- val=tm6000_get_reg (dev, REQ_07_SET_GET_AVREG, 0xeb, 0x0);
-printk("Original value=%d\n",val);
- if (val<0)
+ if (dev->dev_type == TM6010) {
+ val = tm6000_get_reg(dev, TM6010_REQ08_R0A_A_I2S_MOD, 0);
+ if (val < 0)
+ return val;
+ val = (val & 0xf0) | 0x1; /* 48 kHz, not muted */
+ val = tm6000_set_reg(dev, TM6010_REQ08_R0A_A_I2S_MOD, val);
+ if (val < 0)
+ return val;
+ }
+
+ val = tm6000_get_reg(dev, REQ_07_SET_GET_AVREG, 0xeb, 0x0);
+ if (val < 0)
return val;
val &= 0x0f; /* Preserve the audio input control bits */
switch (bitrate) {
case 44100:
- val|=0xd0;
- dev->audio_bitrate=bitrate;
+ val |= 0xd0;
+ dev->audio_bitrate = bitrate;
break;
case 48000:
- val|=0x60;
- dev->audio_bitrate=bitrate;
+ val |= 0x60;
+ dev->audio_bitrate = bitrate;
break;
}
- val=tm6000_set_reg (dev, REQ_07_SET_GET_AVREG, 0xeb, val);
+ val = tm6000_set_reg(dev, REQ_07_SET_GET_AVREG, 0xeb, val);
return val;
}
@@ -659,6 +662,23 @@ void tm6000_add_into_devlist(struct tm6000_core *dev)
static LIST_HEAD(tm6000_extension_devlist);
static DEFINE_MUTEX(tm6000_extension_devlist_lock);
+int tm6000_call_fillbuf(struct tm6000_core *dev, enum tm6000_ops_type type,
+ char *buf, int size)
+{
+ struct tm6000_ops *ops = NULL;
+
+ /* FIXME: tm6000_extension_devlist_lock should be a spinlock */
+
+ if (!list_empty(&tm6000_extension_devlist)) {
+ list_for_each_entry(ops, &tm6000_extension_devlist, next) {
+ if (ops->fillbuf && ops->type == type)
+ ops->fillbuf(dev, buf, size);
+ }
+ }
+
+ return 0;
+}
+
int tm6000_register_extension(struct tm6000_ops *ops)
{
struct tm6000_core *dev = NULL;
@@ -667,10 +687,10 @@ int tm6000_register_extension(struct tm6000_ops *ops)
mutex_lock(&tm6000_extension_devlist_lock);
list_add_tail(&ops->next, &tm6000_extension_devlist);
list_for_each_entry(dev, &tm6000_devlist, devlist) {
- if (dev)
- ops->init(dev);
+ ops->init(dev);
+ printk(KERN_INFO "%s: Initialized (%s) extension\n",
+ dev->name, ops->name);
}
- printk(KERN_INFO "tm6000: Initialized (%s) extension\n", ops->name);
mutex_unlock(&tm6000_extension_devlist_lock);
mutex_unlock(&tm6000_devlist_mutex);
return 0;
diff --git a/drivers/staging/tm6000/tm6000-dvb.c b/drivers/staging/tm6000/tm6000-dvb.c
index 86c1c8b5f25a..f501edccf9c4 100644
--- a/drivers/staging/tm6000/tm6000-dvb.c
+++ b/drivers/staging/tm6000/tm6000-dvb.c
@@ -31,12 +31,25 @@
#include "tuner-xc2028.h"
#include "xc5000.h"
-static void inline print_err_status (struct tm6000_core *dev,
- int packet, int status)
+MODULE_DESCRIPTION("DVB driver extension module for tm5600/6000/6010 based TV cards");
+MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
+MODULE_LICENSE("GPL");
+
+MODULE_SUPPORTED_DEVICE("{{Trident, tm5600},"
+ "{{Trident, tm6000},"
+ "{{Trident, tm6010}");
+
+static int debug;
+
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "enable debug message");
+
+static inline void print_err_status(struct tm6000_core *dev,
+ int packet, int status)
{
char *errmsg = "Unknown";
- switch(status) {
+ switch (status) {
case -ENOENT:
errmsg = "unlinked synchronuously";
break;
@@ -62,7 +75,7 @@ static void inline print_err_status (struct tm6000_core *dev,
errmsg = "Device does not respond";
break;
}
- if (packet<0) {
+ if (packet < 0) {
dprintk(dev, 1, "URB status %d [%s].\n",
status, errmsg);
} else {
@@ -74,19 +87,17 @@ static void inline print_err_status (struct tm6000_core *dev,
static void tm6000_urb_received(struct urb *urb)
{
int ret;
- struct tm6000_core* dev = urb->context;
+ struct tm6000_core *dev = urb->context;
- if(urb->status != 0) {
- print_err_status (dev,0,urb->status);
- }
- else if(urb->actual_length>0){
+ if (urb->status != 0)
+ print_err_status(dev, 0, urb->status);
+ else if (urb->actual_length > 0)
dvb_dmx_swfilter(&dev->dvb->demux, urb->transfer_buffer,
urb->actual_length);
- }
- if(dev->dvb->streams > 0) {
+ if (dev->dvb->streams > 0) {
ret = usb_submit_urb(urb, GFP_ATOMIC);
- if(ret < 0) {
+ if (ret < 0) {
printk(KERN_ERR "tm6000: error %s\n", __FUNCTION__);
kfree(urb->transfer_buffer);
usb_free_urb(urb);
@@ -100,7 +111,7 @@ int tm6000_start_stream(struct tm6000_core *dev)
unsigned int pipe, size;
struct tm6000_dvb *dvb = dev->dvb;
- printk(KERN_INFO "tm6000: got start stream request %s\n",__FUNCTION__);
+ printk(KERN_INFO "tm6000: got start stream request %s\n", __FUNCTION__);
if (dev->mode != TM6000_MODE_DIGITAL) {
tm6000_init_digital_mode(dev);
@@ -108,7 +119,7 @@ int tm6000_start_stream(struct tm6000_core *dev)
}
dvb->bulk_urb = usb_alloc_urb(0, GFP_KERNEL);
- if(dvb->bulk_urb == NULL) {
+ if (dvb->bulk_urb == NULL) {
printk(KERN_ERR "tm6000: couldn't allocate urb\n");
return -ENOMEM;
}
@@ -120,7 +131,7 @@ int tm6000_start_stream(struct tm6000_core *dev)
size = size * 15; /* 512 x 8 or 12 or 15 */
dvb->bulk_urb->transfer_buffer = kzalloc(size, GFP_KERNEL);
- if(dvb->bulk_urb->transfer_buffer == NULL) {
+ if (dvb->bulk_urb->transfer_buffer == NULL) {
usb_free_urb(dvb->bulk_urb);
printk(KERN_ERR "tm6000: couldn't allocate transfer buffer!\n");
return -ENOMEM;
@@ -132,20 +143,20 @@ int tm6000_start_stream(struct tm6000_core *dev)
tm6000_urb_received, dev);
ret = usb_clear_halt(dev->udev, pipe);
- if(ret < 0) {
- printk(KERN_ERR "tm6000: error %i in %s during pipe reset\n",ret,__FUNCTION__);
+ if (ret < 0) {
+ printk(KERN_ERR "tm6000: error %i in %s during pipe reset\n",
+ ret, __FUNCTION__);
return ret;
- }
- else {
+ } else
printk(KERN_ERR "tm6000: pipe resetted\n");
- }
/* mutex_lock(&tm6000_driver.open_close_mutex); */
ret = usb_submit_urb(dvb->bulk_urb, GFP_KERNEL);
/* mutex_unlock(&tm6000_driver.open_close_mutex); */
if (ret) {
- printk(KERN_ERR "tm6000: submit of urb failed (error=%i)\n",ret);
+ printk(KERN_ERR "tm6000: submit of urb failed (error=%i)\n",
+ ret);
kfree(dvb->bulk_urb->transfer_buffer);
usb_free_urb(dvb->bulk_urb);
@@ -159,10 +170,10 @@ void tm6000_stop_stream(struct tm6000_core *dev)
{
struct tm6000_dvb *dvb = dev->dvb;
- if(dvb->bulk_urb) {
- printk (KERN_INFO "urb killing\n");
+ if (dvb->bulk_urb) {
+ printk(KERN_INFO "urb killing\n");
usb_kill_urb(dvb->bulk_urb);
- printk (KERN_INFO "urb buffer free\n");
+ printk(KERN_INFO "urb buffer free\n");
kfree(dvb->bulk_urb->transfer_buffer);
usb_free_urb(dvb->bulk_urb);
dvb->bulk_urb = NULL;
@@ -174,35 +185,34 @@ int tm6000_start_feed(struct dvb_demux_feed *feed)
struct dvb_demux *demux = feed->demux;
struct tm6000_core *dev = demux->priv;
struct tm6000_dvb *dvb = dev->dvb;
- printk(KERN_INFO "tm6000: got start feed request %s\n",__FUNCTION__);
+ printk(KERN_INFO "tm6000: got start feed request %s\n", __FUNCTION__);
mutex_lock(&dvb->mutex);
- if(dvb->streams == 0) {
+ if (dvb->streams == 0) {
dvb->streams = 1;
/* mutex_init(&tm6000_dev->streming_mutex); */
tm6000_start_stream(dev);
- }
- else {
+ } else
++(dvb->streams);
- }
mutex_unlock(&dvb->mutex);
return 0;
}
-int tm6000_stop_feed(struct dvb_demux_feed *feed) {
+int tm6000_stop_feed(struct dvb_demux_feed *feed)
+{
struct dvb_demux *demux = feed->demux;
struct tm6000_core *dev = demux->priv;
struct tm6000_dvb *dvb = dev->dvb;
- printk(KERN_INFO "tm6000: got stop feed request %s\n",__FUNCTION__);
+ printk(KERN_INFO "tm6000: got stop feed request %s\n", __FUNCTION__);
mutex_lock(&dvb->mutex);
- printk (KERN_INFO "stream %#x\n", dvb->streams);
+ printk(KERN_INFO "stream %#x\n", dvb->streams);
--(dvb->streams);
- if(dvb->streams == 0) {
- printk (KERN_INFO "stop stream\n");
+ if (dvb->streams == 0) {
+ printk(KERN_INFO "stop stream\n");
tm6000_stop_stream(dev);
/* mutex_destroy(&tm6000_dev->streaming_mutex); */
}
@@ -216,9 +226,9 @@ int tm6000_dvb_attach_frontend(struct tm6000_core *dev)
{
struct tm6000_dvb *dvb = dev->dvb;
- if(dev->caps.has_zl10353) {
- struct zl10353_config config =
- {.demod_address = dev->demod_addr,
+ if (dev->caps.has_zl10353) {
+ struct zl10353_config config = {
+ .demod_address = dev->demod_addr,
.no_tuner = 1,
.parallel_ts = 1,
.if2 = 45700,
@@ -227,8 +237,7 @@ int tm6000_dvb_attach_frontend(struct tm6000_core *dev)
dvb->frontend = dvb_attach(zl10353_attach, &config,
&dev->i2c_adap);
- }
- else {
+ } else {
printk(KERN_ERR "tm6000: no frontend defined for the device!\n");
return -1;
}
@@ -238,7 +247,7 @@ int tm6000_dvb_attach_frontend(struct tm6000_core *dev)
DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
-int tm6000_dvb_register(struct tm6000_core *dev)
+int register_dvb(struct tm6000_core *dev)
{
int ret = -1;
struct tm6000_dvb *dvb = dev->dvb;
@@ -249,13 +258,13 @@ int tm6000_dvb_register(struct tm6000_core *dev)
/* attach the frontend */
ret = tm6000_dvb_attach_frontend(dev);
- if(ret < 0) {
+ if (ret < 0) {
printk(KERN_ERR "tm6000: couldn't attach the frontend!\n");
goto err;
}
ret = dvb_register_adapter(&dvb->adapter, "Trident TVMaster 6000 DVB-T",
- THIS_MODULE, &dev->udev->dev, adapter_nr);
+ THIS_MODULE, &dev->udev->dev, adapter_nr);
dvb->adapter.priv = dev;
if (dvb->frontend) {
@@ -308,9 +317,8 @@ int tm6000_dvb_register(struct tm6000_core *dev)
break;
}
}
- } else {
+ } else
printk(KERN_ERR "tm6000: no frontend found\n");
- }
dvb->demux.dmx.capabilities = DMX_TS_FILTERING | DMX_SECTION_FILTERING
| DMX_MEMORY_BASED_FILTERING;
@@ -321,7 +329,7 @@ int tm6000_dvb_register(struct tm6000_core *dev)
dvb->demux.stop_feed = tm6000_stop_feed;
dvb->demux.write_to_decoder = NULL;
ret = dvb_dmx_init(&dvb->demux);
- if(ret < 0) {
+ if (ret < 0) {
printk("tm6000: dvb_dmx_init failed (errno = %d)\n", ret);
goto frontend_err;
}
@@ -331,7 +339,7 @@ int tm6000_dvb_register(struct tm6000_core *dev)
dvb->dmxdev.capabilities = 0;
ret = dvb_dmxdev_init(&dvb->dmxdev, &dvb->adapter);
- if(ret < 0) {
+ if (ret < 0) {
printk("tm6000: dvb_dmxdev_init failed (errno = %d)\n", ret);
goto dvb_dmx_err;
}
@@ -341,7 +349,7 @@ int tm6000_dvb_register(struct tm6000_core *dev)
dvb_dmx_err:
dvb_dmx_release(&dvb->demux);
frontend_err:
- if(dvb->frontend) {
+ if (dvb->frontend) {
dvb_frontend_detach(dvb->frontend);
dvb_unregister_frontend(dvb->frontend);
}
@@ -351,11 +359,11 @@ err:
return ret;
}
-void tm6000_dvb_unregister(struct tm6000_core *dev)
+void unregister_dvb(struct tm6000_core *dev)
{
struct tm6000_dvb *dvb = dev->dvb;
- if(dvb->bulk_urb != NULL) {
+ if (dvb->bulk_urb != NULL) {
struct urb *bulk_urb = dvb->bulk_urb;
kfree(bulk_urb->transfer_buffer);
@@ -365,7 +373,7 @@ void tm6000_dvb_unregister(struct tm6000_core *dev)
}
/* mutex_lock(&tm6000_driver.open_close_mutex); */
- if(dvb->frontend) {
+ if (dvb->frontend) {
dvb_frontend_detach(dvb->frontend);
dvb_unregister_frontend(dvb->frontend);
}
@@ -375,5 +383,70 @@ void tm6000_dvb_unregister(struct tm6000_core *dev)
dvb_unregister_adapter(&dvb->adapter);
mutex_destroy(&dvb->mutex);
/* mutex_unlock(&tm6000_driver.open_close_mutex); */
+}
+static int dvb_init(struct tm6000_core *dev)
+{
+ struct tm6000_dvb *dvb;
+ int rc;
+
+ if (!dev)
+ return 0;
+
+ if (!dev->caps.has_dvb)
+ return 0;
+
+ dvb = kzalloc(sizeof(struct tm6000_dvb), GFP_KERNEL);
+ if (!dvb) {
+ printk(KERN_INFO "Cannot allocate memory\n");
+ return -ENOMEM;
+ }
+
+ dev->dvb = dvb;
+
+ rc = register_dvb(dev);
+ if (rc < 0) {
+ kfree(dvb);
+ dev->dvb = NULL;
+ return 0;
+ }
+
+ return 0;
+}
+
+static int dvb_fini(struct tm6000_core *dev)
+{
+ if (!dev)
+ return 0;
+
+ if (!dev->caps.has_dvb)
+ return 0;
+
+ if (dev->dvb) {
+ unregister_dvb(dev);
+ kfree(dev->dvb);
+ dev->dvb = NULL;
+ }
+
+ return 0;
}
+
+static struct tm6000_ops dvb_ops = {
+ .type = TM6000_DVB,
+ .name = "TM6000 dvb Extension",
+ .init = dvb_init,
+ .fini = dvb_fini,
+};
+
+static int __init tm6000_dvb_register(void)
+{
+ return tm6000_register_extension(&dvb_ops);
+}
+
+static void __exit tm6000_dvb_unregister(void)
+{
+ tm6000_unregister_extension(&dvb_ops);
+}
+
+module_init(tm6000_dvb_register);
+module_exit(tm6000_dvb_unregister);
diff --git a/drivers/staging/tm6000/tm6000-i2c.c b/drivers/staging/tm6000/tm6000-i2c.c
index 94ff489a1bbb..79bc67f0311f 100644
--- a/drivers/staging/tm6000/tm6000-i2c.c
+++ b/drivers/staging/tm6000/tm6000-i2c.c
@@ -40,7 +40,7 @@ static unsigned int i2c_debug = 0;
module_param(i2c_debug, int, 0644);
MODULE_PARM_DESC(i2c_debug, "enable debug messages [i2c]");
-#define i2c_dprintk(lvl,fmt, args...) if (i2c_debug>=lvl) do{ \
+#define i2c_dprintk(lvl, fmt, args...) if (i2c_debug >= lvl) do { \
printk(KERN_DEBUG "%s at %s: " fmt, \
dev->name, __FUNCTION__ , ##args); } while (0)
@@ -171,7 +171,7 @@ static int tm6000_i2c_xfer(struct i2c_adapter *i2c_adap,
return 0;
for (i = 0; i < num; i++) {
addr = (msgs[i].addr << 1) & 0xff;
- i2c_dprintk(2,"%s %s addr=0x%x len=%d:",
+ i2c_dprintk(2, "%s %s addr=0x%x len=%d:",
(msgs[i].flags & I2C_M_RD) ? "read" : "write",
i == num - 1 ? "stop" : "nonstop", addr, msgs[i].len);
if (msgs[i].flags & I2C_M_RD) {
@@ -235,7 +235,7 @@ static int tm6000_i2c_xfer(struct i2c_adapter *i2c_adap,
return num;
err:
- i2c_dprintk(2," ERROR: %i\n", rc);
+ i2c_dprintk(2, " ERROR: %i\n", rc);
return rc;
}
@@ -266,11 +266,10 @@ static int tm6000_i2c_eeprom(struct tm6000_core *dev,
if (0 == (i % 16))
printk(KERN_INFO "%s: i2c eeprom %02x:", dev->name, i);
printk(" %02x", eedata[i]);
- if ((eedata[i] >= ' ') && (eedata[i] <= 'z')) {
+ if ((eedata[i] >= ' ') && (eedata[i] <= 'z'))
bytes[i%16] = eedata[i];
- } else {
- bytes[i%16]='.';
- }
+ else
+ bytes[i%16] = '.';
i++;
@@ -305,15 +304,15 @@ static u32 functionality(struct i2c_adapter *adap)
}
#define mass_write(addr, reg, data...) \
- { const static u8 _val[] = data; \
- rc=tm6000_read_write_usb(dev,USB_DIR_OUT | USB_TYPE_VENDOR, \
- REQ_16_SET_GET_I2C_WR1_RDN,(reg<<8)+addr, 0x00, (u8 *) _val, \
+ { static const u8 _val[] = data; \
+ rc = tm6000_read_write_usb(dev, USB_DIR_OUT | USB_TYPE_VENDOR, \
+ REQ_16_SET_GET_I2C_WR1_RDN, (reg<<8)+addr, 0x00, (u8 *) _val, \
ARRAY_SIZE(_val)); \
- if (rc<0) { \
- printk(KERN_ERR "Error on line %d: %d\n",__LINE__,rc); \
+ if (rc < 0) { \
+ printk(KERN_ERR "Error on line %d: %d\n", __LINE__, rc); \
return rc; \
} \
- msleep (10); \
+ msleep(10); \
}
static struct i2c_algorithm tm6000_algo = {
diff --git a/drivers/staging/tm6000/tm6000-input.c b/drivers/staging/tm6000/tm6000-input.c
new file mode 100644
index 000000000000..32f7a0af6938
--- /dev/null
+++ b/drivers/staging/tm6000/tm6000-input.c
@@ -0,0 +1,364 @@
+/*
+ tm6000-input.c - driver for TM5600/TM6000/TM6010 USB video capture devices
+
+ Copyright (C) 2010 Stefan Ringel <stefan.ringel@arcor.de>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation version 2
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+
+#include <linux/input.h>
+#include <linux/usb.h>
+
+#include <media/ir-core.h>
+#include <media/ir-common.h>
+
+#include "tm6000.h"
+#include "tm6000-regs.h"
+
+static unsigned int ir_debug;
+module_param(ir_debug, int, 0644);
+MODULE_PARM_DESC(ir_debug, "enable debug message [IR]");
+
+static unsigned int enable_ir = 1;
+module_param(enable_ir, int, 0644);
+MODULE_PARM_DESC(enable_ir, "enable ir (default is enable");
+
+#undef dprintk
+
+#define dprintk(fmt, arg...) \
+ if (ir_debug) { \
+ printk(KERN_DEBUG "%s/ir: " fmt, ir->name , ## arg); \
+ }
+
+struct tm6000_ir_poll_result {
+ u8 rc_data[4];
+};
+
+struct tm6000_IR {
+ struct tm6000_core *dev;
+ struct ir_input_dev *input;
+ struct ir_input_state ir;
+ char name[32];
+ char phys[32];
+
+ /* poll expernal decoder */
+ int polling;
+ struct delayed_work work;
+ u8 wait:1;
+ struct urb *int_urb;
+ u8 *urb_data;
+ u8 key:1;
+
+ int (*get_key) (struct tm6000_IR *, struct tm6000_ir_poll_result *);
+
+ /* IR device properties */
+ struct ir_dev_props props;
+};
+
+
+void tm6000_ir_wait(struct tm6000_core *dev, u8 state)
+{
+ struct tm6000_IR *ir = dev->ir;
+
+ if (!dev->ir)
+ return;
+
+ if (state)
+ ir->wait = 1;
+ else
+ ir->wait = 0;
+}
+
+
+static int tm6000_ir_config(struct tm6000_IR *ir)
+{
+ struct tm6000_core *dev = ir->dev;
+ u8 buf[10];
+ int rc;
+
+ /* hack */
+ buf[0] = 0xff;
+ buf[1] = 0xff;
+ buf[2] = 0xf2;
+ buf[3] = 0x2b;
+ buf[4] = 0x20;
+ buf[5] = 0x35;
+ buf[6] = 0x60;
+ buf[7] = 0x04;
+ buf[8] = 0xc0;
+ buf[9] = 0x08;
+
+ rc = tm6000_read_write_usb(dev, USB_DIR_OUT | USB_TYPE_VENDOR |
+ USB_RECIP_DEVICE, REQ_00_SET_IR_VALUE, 0, 0, buf, 0x0a);
+ msleep(100);
+
+ if (rc < 0) {
+ printk(KERN_INFO "IR configuration failed");
+ return rc;
+ }
+ return 0;
+}
+
+static void tm6000_ir_urb_received(struct urb *urb)
+{
+ struct tm6000_core *dev = urb->context;
+ struct tm6000_IR *ir = dev->ir;
+ int rc;
+
+ if (urb->status != 0)
+ printk(KERN_INFO "not ready\n");
+ else if (urb->actual_length > 0)
+ memcpy(ir->urb_data, urb->transfer_buffer, urb->actual_length);
+
+ dprintk("data %02x %02x %02x %02x\n", ir->urb_data[0],
+ ir->urb_data[1], ir->urb_data[2], ir->urb_data[3]);
+
+ ir->key = 1;
+
+ rc = usb_submit_urb(urb, GFP_ATOMIC);
+}
+
+static int default_polling_getkey(struct tm6000_IR *ir,
+ struct tm6000_ir_poll_result *poll_result)
+{
+ struct tm6000_core *dev = ir->dev;
+ int rc;
+ u8 buf[2];
+
+ if (ir->wait && !&dev->int_in) {
+ poll_result->rc_data[0] = 0xff;
+ return 0;
+ }
+
+ if (&dev->int_in) {
+ poll_result->rc_data[0] = ir->urb_data[0];
+ poll_result->rc_data[1] = ir->urb_data[1];
+ } else {
+ tm6000_set_reg(dev, REQ_04_EN_DISABLE_MCU_INT, 2, 0);
+ msleep(10);
+ tm6000_set_reg(dev, REQ_04_EN_DISABLE_MCU_INT, 2, 1);
+ msleep(10);
+
+ rc = tm6000_read_write_usb(dev, USB_DIR_IN | USB_TYPE_VENDOR |
+ USB_RECIP_DEVICE, REQ_02_GET_IR_CODE, 0, 0, buf, 1);
+
+ msleep(10);
+
+ dprintk("read data=%02x\n", buf[0]);
+ if (rc < 0)
+ return rc;
+
+ poll_result->rc_data[0] = buf[0];
+ }
+ return 0;
+}
+
+static void tm6000_ir_handle_key(struct tm6000_IR *ir)
+{
+ int result;
+ struct tm6000_ir_poll_result poll_result;
+
+ /* read the registers containing the IR status */
+ result = ir->get_key(ir, &poll_result);
+ if (result < 0) {
+ printk(KERN_INFO "ir->get_key() failed %d\n", result);
+ return;
+ }
+
+ dprintk("ir->get_key result data=%02x %02x\n",
+ poll_result.rc_data[0], poll_result.rc_data[1]);
+
+ if (poll_result.rc_data[0] != 0xff && ir->key == 1) {
+ ir_input_keydown(ir->input->input_dev, &ir->ir,
+ poll_result.rc_data[0] | poll_result.rc_data[1] << 8);
+
+ ir_input_nokey(ir->input->input_dev, &ir->ir);
+ ir->key = 0;
+ }
+ return;
+}
+
+static void tm6000_ir_work(struct work_struct *work)
+{
+ struct tm6000_IR *ir = container_of(work, struct tm6000_IR, work.work);
+
+ tm6000_ir_handle_key(ir);
+ schedule_delayed_work(&ir->work, msecs_to_jiffies(ir->polling));
+}
+
+static int tm6000_ir_start(void *priv)
+{
+ struct tm6000_IR *ir = priv;
+
+ INIT_DELAYED_WORK(&ir->work, tm6000_ir_work);
+ schedule_delayed_work(&ir->work, 0);
+
+ return 0;
+}
+
+static void tm6000_ir_stop(void *priv)
+{
+ struct tm6000_IR *ir = priv;
+
+ cancel_delayed_work_sync(&ir->work);
+}
+
+int tm6000_ir_change_protocol(void *priv, u64 ir_type)
+{
+ struct tm6000_IR *ir = priv;
+
+ ir->get_key = default_polling_getkey;
+
+ tm6000_ir_config(ir);
+ /* TODO */
+ return 0;
+}
+
+int tm6000_ir_init(struct tm6000_core *dev)
+{
+ struct tm6000_IR *ir;
+ struct ir_input_dev *ir_input_dev;
+ int err = -ENOMEM;
+ int pipe, size, rc;
+
+ if (!enable_ir)
+ return -ENODEV;
+
+ if (!dev->caps.has_remote)
+ return 0;
+
+ if (!dev->ir_codes)
+ return 0;
+
+ ir = kzalloc(sizeof(*ir), GFP_KERNEL);
+ ir_input_dev = kzalloc(sizeof(*ir_input_dev), GFP_KERNEL);
+ ir_input_dev->input_dev = input_allocate_device();
+ if (!ir || !ir_input_dev || !ir_input_dev->input_dev)
+ goto err_out_free;
+
+ /* record handles to ourself */
+ ir->dev = dev;
+ dev->ir = ir;
+
+ ir->input = ir_input_dev;
+
+ /* input einrichten */
+ ir->props.allowed_protos = IR_TYPE_RC5 | IR_TYPE_NEC;
+ ir->props.priv = ir;
+ ir->props.change_protocol = tm6000_ir_change_protocol;
+ ir->props.open = tm6000_ir_start;
+ ir->props.close = tm6000_ir_stop;
+ ir->props.driver_type = RC_DRIVER_SCANCODE;
+
+ ir->polling = 50;
+
+ snprintf(ir->name, sizeof(ir->name), "tm5600/60x0 IR (%s)",
+ dev->name);
+
+ usb_make_path(dev->udev, ir->phys, sizeof(ir->phys));
+ strlcat(ir->phys, "/input0", sizeof(ir->phys));
+
+ tm6000_ir_change_protocol(ir, IR_TYPE_UNKNOWN);
+ err = ir_input_init(ir_input_dev->input_dev, &ir->ir, IR_TYPE_OTHER);
+ if (err < 0)
+ goto err_out_free;
+
+ ir_input_dev->input_dev->name = ir->name;
+ ir_input_dev->input_dev->phys = ir->phys;
+ ir_input_dev->input_dev->id.bustype = BUS_USB;
+ ir_input_dev->input_dev->id.version = 1;
+ ir_input_dev->input_dev->id.vendor = le16_to_cpu(dev->udev->descriptor.idVendor);
+ ir_input_dev->input_dev->id.product = le16_to_cpu(dev->udev->descriptor.idProduct);
+
+ ir_input_dev->input_dev->dev.parent = &dev->udev->dev;
+
+ if (&dev->int_in) {
+ dprintk("IR over int\n");
+
+ ir->int_urb = usb_alloc_urb(0, GFP_KERNEL);
+
+ pipe = usb_rcvintpipe(dev->udev,
+ dev->int_in.endp->desc.bEndpointAddress
+ & USB_ENDPOINT_NUMBER_MASK);
+
+ size = usb_maxpacket(dev->udev, pipe, usb_pipeout(pipe));
+ dprintk("IR max size: %d\n", size);
+
+ ir->int_urb->transfer_buffer = kzalloc(size, GFP_KERNEL);
+ if (ir->int_urb->transfer_buffer == NULL) {
+ usb_free_urb(ir->int_urb);
+ goto err_out_stop;
+ }
+ dprintk("int interval: %d\n", dev->int_in.endp->desc.bInterval);
+ usb_fill_int_urb(ir->int_urb, dev->udev, pipe,
+ ir->int_urb->transfer_buffer, size,
+ tm6000_ir_urb_received, dev,
+ dev->int_in.endp->desc.bInterval);
+ rc = usb_submit_urb(ir->int_urb, GFP_KERNEL);
+ if (rc) {
+ kfree(ir->int_urb->transfer_buffer);
+ usb_free_urb(ir->int_urb);
+ err = rc;
+ goto err_out_stop;
+ }
+ ir->urb_data = kzalloc(size, GFP_KERNEL);
+ }
+
+ /* ir register */
+ err = ir_input_register(ir->input->input_dev, dev->ir_codes,
+ &ir->props, "tm6000");
+ if (err)
+ goto err_out_stop;
+
+ return 0;
+
+err_out_stop:
+ dev->ir = NULL;
+err_out_free:
+ kfree(ir_input_dev);
+ kfree(ir);
+ return err;
+}
+
+int tm6000_ir_fini(struct tm6000_core *dev)
+{
+ struct tm6000_IR *ir = dev->ir;
+
+ /* skip detach on non attached board */
+
+ if (!ir)
+ return 0;
+
+ ir_input_unregister(ir->input->input_dev);
+
+ if (ir->int_urb) {
+ usb_kill_urb(ir->int_urb);
+ kfree(ir->int_urb->transfer_buffer);
+ usb_free_urb(ir->int_urb);
+ ir->int_urb = NULL;
+ kfree(ir->urb_data);
+ ir->urb_data = NULL;
+ }
+
+ kfree(ir->input);
+ ir->input = NULL;
+ kfree(ir);
+ dev->ir = NULL;
+
+ return 0;
+}
diff --git a/drivers/staging/tm6000/tm6000-stds.c b/drivers/staging/tm6000/tm6000-stds.c
index b3564f611e5e..6bf4a73b320d 100644
--- a/drivers/staging/tm6000/tm6000-stds.c
+++ b/drivers/staging/tm6000/tm6000-stds.c
@@ -77,7 +77,7 @@ static struct tm6000_std_tv_settings tv_stds[] = {
{TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0e},
{TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f},
{TM6010_REQ07_R03_YC_SEP_CONTROL, 0x00},
- {TM6010_REQ07_R07_OUTPUT_CONTROL, 0x01},
+ {TM6010_REQ07_R07_OUTPUT_CONTROL, 0x31},
{TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x1e},
{TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0x83},
{TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0x0a},
@@ -135,7 +135,7 @@ static struct tm6000_std_tv_settings tv_stds[] = {
{TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0e},
{TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f},
{TM6010_REQ07_R03_YC_SEP_CONTROL, 0x02},
- {TM6010_REQ07_R07_OUTPUT_CONTROL, 0x01},
+ {TM6010_REQ07_R07_OUTPUT_CONTROL, 0x31},
{TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x1e},
{TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0x91},
{TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0x1f},
@@ -193,7 +193,7 @@ static struct tm6000_std_tv_settings tv_stds[] = {
{TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0e},
{TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f},
{TM6010_REQ07_R03_YC_SEP_CONTROL, 0x02},
- {TM6010_REQ07_R07_OUTPUT_CONTROL, 0x01},
+ {TM6010_REQ07_R07_OUTPUT_CONTROL, 0x31},
{TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x25},
{TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0xd5},
{TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0x63},
@@ -251,7 +251,7 @@ static struct tm6000_std_tv_settings tv_stds[] = {
{TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0e},
{TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f},
{TM6010_REQ07_R03_YC_SEP_CONTROL, 0x02},
- {TM6010_REQ07_R07_OUTPUT_CONTROL, 0x01},
+ {TM6010_REQ07_R07_OUTPUT_CONTROL, 0x31},
{TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x24},
{TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0x92},
{TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0xe8},
@@ -308,7 +308,7 @@ static struct tm6000_std_tv_settings tv_stds[] = {
{TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0f},
{TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f},
{TM6010_REQ07_R03_YC_SEP_CONTROL, 0x00},
- {TM6010_REQ07_R07_OUTPUT_CONTROL, 0x01},
+ {TM6010_REQ07_R07_OUTPUT_CONTROL, 0x31},
{TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x1e},
{TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0x8b},
{TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0xa2},
@@ -354,7 +354,7 @@ static struct tm6000_std_settings composite_stds[] = {
{TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0e},
{TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f},
{TM6010_REQ07_R03_YC_SEP_CONTROL, 0x00},
- {TM6010_REQ07_R07_OUTPUT_CONTROL, 0x01},
+ {TM6010_REQ07_R07_OUTPUT_CONTROL, 0x31},
{TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x1e},
{TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0x83},
{TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0x0a},
@@ -396,7 +396,7 @@ static struct tm6000_std_settings composite_stds[] = {
{TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0e},
{TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f},
{TM6010_REQ07_R03_YC_SEP_CONTROL, 0x02},
- {TM6010_REQ07_R07_OUTPUT_CONTROL, 0x01},
+ {TM6010_REQ07_R07_OUTPUT_CONTROL, 0x31},
{TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x1e},
{TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0x91},
{TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0x1f},
@@ -438,7 +438,7 @@ static struct tm6000_std_settings composite_stds[] = {
{TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0e},
{TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f},
{TM6010_REQ07_R03_YC_SEP_CONTROL, 0x02},
- {TM6010_REQ07_R07_OUTPUT_CONTROL, 0x01},
+ {TM6010_REQ07_R07_OUTPUT_CONTROL, 0x31},
{TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x25},
{TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0xd5},
{TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0x63},
@@ -480,7 +480,7 @@ static struct tm6000_std_settings composite_stds[] = {
{TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0e},
{TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f},
{TM6010_REQ07_R03_YC_SEP_CONTROL, 0x02},
- {TM6010_REQ07_R07_OUTPUT_CONTROL, 0x01},
+ {TM6010_REQ07_R07_OUTPUT_CONTROL, 0x31},
{TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x24},
{TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0x92},
{TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0xe8},
@@ -521,7 +521,7 @@ static struct tm6000_std_settings composite_stds[] = {
{TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0f},
{TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f},
{TM6010_REQ07_R03_YC_SEP_CONTROL, 0x00},
- {TM6010_REQ07_R07_OUTPUT_CONTROL, 0x01},
+ {TM6010_REQ07_R07_OUTPUT_CONTROL, 0x31},
{TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x1e},
{TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0x8b},
{TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0xa2},
@@ -567,7 +567,7 @@ static struct tm6000_std_settings svideo_stds[] = {
{TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0e},
{TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f},
{TM6010_REQ07_R03_YC_SEP_CONTROL, 0x04},
- {TM6010_REQ07_R07_OUTPUT_CONTROL, 0x01},
+ {TM6010_REQ07_R07_OUTPUT_CONTROL, 0x31},
{TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x1e},
{TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0x83},
{TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0x0a},
@@ -609,7 +609,7 @@ static struct tm6000_std_settings svideo_stds[] = {
{TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0e},
{TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f},
{TM6010_REQ07_R03_YC_SEP_CONTROL, 0x04},
- {TM6010_REQ07_R07_OUTPUT_CONTROL, 0x01},
+ {TM6010_REQ07_R07_OUTPUT_CONTROL, 0x31},
{TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x1e},
{TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0x91},
{TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0x1f},
@@ -651,7 +651,7 @@ static struct tm6000_std_settings svideo_stds[] = {
{TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0e},
{TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f},
{TM6010_REQ07_R03_YC_SEP_CONTROL, 0x04},
- {TM6010_REQ07_R07_OUTPUT_CONTROL, 0x00},
+ {TM6010_REQ07_R07_OUTPUT_CONTROL, 0x30},
{TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x25},
{TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0xd5},
{TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0x63},
@@ -693,7 +693,7 @@ static struct tm6000_std_settings svideo_stds[] = {
{TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0e},
{TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f},
{TM6010_REQ07_R03_YC_SEP_CONTROL, 0x03},
- {TM6010_REQ07_R07_OUTPUT_CONTROL, 0x01},
+ {TM6010_REQ07_R07_OUTPUT_CONTROL, 0x31},
{TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x24},
{TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0x92},
{TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0xe8},
@@ -734,7 +734,7 @@ static struct tm6000_std_settings svideo_stds[] = {
{TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0f},
{TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f},
{TM6010_REQ07_R03_YC_SEP_CONTROL, 0x03},
- {TM6010_REQ07_R07_OUTPUT_CONTROL, 0x00},
+ {TM6010_REQ07_R07_OUTPUT_CONTROL, 0x30},
{TM6010_REQ07_R17_HLOOP_MAXSTATE, 0x8b},
{TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x1e},
{TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0x8b},
@@ -763,11 +763,11 @@ static struct tm6000_std_settings svideo_stds[] = {
void tm6000_get_std_res(struct tm6000_core *dev)
{
/* Currently, those are the only supported resoltions */
- if (dev->norm & V4L2_STD_525_60) {
+ if (dev->norm & V4L2_STD_525_60)
dev->height = 480;
- } else {
+ else
dev->height = 576;
- }
+
dev->width = 720;
}
diff --git a/drivers/staging/tm6000/tm6000-usb-isoc.h b/drivers/staging/tm6000/tm6000-usb-isoc.h
index 5a5049acd4ec..138716a8f056 100644
--- a/drivers/staging/tm6000/tm6000-usb-isoc.h
+++ b/drivers/staging/tm6000/tm6000-usb-isoc.h
@@ -39,7 +39,7 @@ struct usb_isoc_ctl {
int pos, size, pktsize;
/* Last field: ODD or EVEN? */
- int field;
+ int vfield;
/* Stores incomplete commands */
u32 tmp_buf;
@@ -47,7 +47,4 @@ struct usb_isoc_ctl {
/* Stores already requested buffers */
struct tm6000_buffer *buf;
-
- /* Stores the number of received fields */
- int nfields;
};
diff --git a/drivers/staging/tm6000/tm6000-video.c b/drivers/staging/tm6000/tm6000-video.c
index 56fa371e08c8..ce0a089a0771 100644
--- a/drivers/staging/tm6000/tm6000-video.c
+++ b/drivers/staging/tm6000/tm6000-video.c
@@ -56,6 +56,7 @@ static int video_nr = -1; /* /dev/videoN, -1 for autodetect */
/* Debug level */
int tm6000_debug;
+EXPORT_SYMBOL_GPL(tm6000_debug);
/* supported controls */
static struct v4l2_queryctrl tm6000_qctrl[] = {
@@ -149,8 +150,6 @@ static inline void get_next_buf(struct tm6000_dmaqueue *dma_q,
/* Cleans up buffer - Usefull for testing for frame/URB loss */
outp = videobuf_to_vmalloc(&(*buf)->vb);
-// if (outp)
-// memset(outp, 0, (*buf)->vb.size);
return;
}
@@ -186,236 +185,152 @@ const char *tm6000_msg_type[] = {
/*
* Identify the tm5600/6000 buffer header type and properly handles
*/
-static int copy_packet(struct urb *urb, u32 header, u8 **ptr, u8 *endp,
- u8 *out_p, struct tm6000_buffer **buf)
-{
- struct tm6000_dmaqueue *dma_q = urb->context;
- struct tm6000_core *dev = container_of(dma_q, struct tm6000_core, vidq);
- u8 c;
- unsigned int cmd, cpysize, pktsize, size, field, block, line, pos = 0;
- int rc = 0;
- /* FIXME: move to tm6000-isoc */
- static int last_line = -2, start_line = -2, last_field = -2;
-
- /* FIXME: this is the hardcoded window size
- */
- unsigned int linewidth = (*buf)->vb.width << 1;
-
- if (!dev->isoc_ctl.cmd) {
- c = (header >> 24) & 0xff;
-
- /* split the header fields */
- size = ((header & 0x7e) << 1);
-
- if (size > 0)
- size -= 4;
-
- block = (header >> 7) & 0xf;
- field = (header >> 11) & 0x1;
- line = (header >> 12) & 0x1ff;
- cmd = (header >> 21) & 0x7;
-
- /* Validates header fields */
- if(size > TM6000_URB_MSG_LEN)
- size = TM6000_URB_MSG_LEN;
-
- if (cmd == TM6000_URB_MSG_VIDEO) {
- if ((block+1)*TM6000_URB_MSG_LEN>linewidth)
- cmd = TM6000_URB_MSG_ERR;
-
- /* FIXME: Mounts the image as field0+field1
- * It should, instead, check if the user selected
- * entrelaced or non-entrelaced mode
- */
- pos = ((line << 1) - field - 1) * linewidth +
- block * TM6000_URB_MSG_LEN;
-
- /* Don't allow to write out of the buffer */
- if (pos+TM6000_URB_MSG_LEN > (*buf)->vb.size) {
- dprintk(dev, V4L2_DEBUG_ISOC,
- "ERR: size=%d, num=%d, line=%d, "
- "field=%d\n",
- size, block, line, field);
-
- cmd = TM6000_URB_MSG_ERR;
- }
- } else {
- pos=0;
- }
-
- /* Prints debug info */
- dprintk(dev, V4L2_DEBUG_ISOC, "size=%d, num=%d, "
- " line=%d, field=%d\n",
- size, block, line, field);
-
- if ((last_line!=line)&&(last_line+1!=line) &&
- (cmd != TM6000_URB_MSG_ERR) ) {
- if (cmd != TM6000_URB_MSG_VIDEO) {
- dprintk(dev, V4L2_DEBUG_ISOC, "cmd=%d, "
- "size=%d, num=%d, line=%d, field=%d\n",
- cmd, size, block, line, field);
- }
- if (start_line<0)
- start_line=last_line;
- /* Prints debug info */
- dprintk(dev, V4L2_DEBUG_ISOC, "lines= %d-%d, "
- "field=%d\n",
- start_line, last_line, field);
-
- if ((start_line<6 && last_line>200) &&
- (last_field != field) ) {
-
- dev->isoc_ctl.nfields++;
- if (dev->isoc_ctl.nfields>=2) {
- dev->isoc_ctl.nfields=0;
-
- /* Announces that a new buffer were filled */
- buffer_filled (dev, dma_q, *buf);
- dprintk(dev, V4L2_DEBUG_ISOC,
- "new buffer filled\n");
- get_next_buf (dma_q, buf);
- if (!*buf)
- return rc;
- out_p = videobuf_to_vmalloc(&((*buf)->vb));
- if (!out_p)
- return rc;
-
- pos = dev->isoc_ctl.pos = 0;
- }
- }
-
- start_line=line;
- last_field=field;
- }
- if (cmd == TM6000_URB_MSG_VIDEO)
- last_line = line;
-
- pktsize = TM6000_URB_MSG_LEN;
- } else {
- /* Continue the last copy */
- cmd = dev->isoc_ctl.cmd;
- size= dev->isoc_ctl.size;
- pos = dev->isoc_ctl.pos;
- pktsize = dev->isoc_ctl.pktsize;
- }
-
- cpysize = (endp-(*ptr) > size) ? size : endp - *ptr;
-
- if (cpysize) {
- /* handles each different URB message */
- switch(cmd) {
- case TM6000_URB_MSG_VIDEO:
- /* Fills video buffer */
- memcpy(&out_p[pos], *ptr, cpysize);
- break;
- case TM6000_URB_MSG_PTS:
- break;
- case TM6000_URB_MSG_AUDIO:
- /* Need some code to process audio */
- printk ("%ld: cmd=%s, size=%d\n", jiffies,
- tm6000_msg_type[cmd],size);
- break;
- case TM6000_URB_MSG_VBI:
- break;
- default:
- dprintk (dev, V4L2_DEBUG_ISOC, "cmd=%s, size=%d\n",
- tm6000_msg_type[cmd],size);
- }
- }
- if (cpysize<size) {
- /* End of URB packet, but cmd processing is not
- * complete. Preserve the state for a next packet
- */
- dev->isoc_ctl.pos = pos+cpysize;
- dev->isoc_ctl.size= size-cpysize;
- dev->isoc_ctl.cmd = cmd;
- dev->isoc_ctl.pktsize = pktsize-cpysize;
- (*ptr)+=cpysize;
- } else {
- dev->isoc_ctl.cmd = 0;
- (*ptr)+=pktsize;
- }
-
- return rc;
-}
-
static int copy_streams(u8 *data, unsigned long len,
struct urb *urb)
{
struct tm6000_dmaqueue *dma_q = urb->context;
struct tm6000_core *dev= container_of(dma_q,struct tm6000_core,vidq);
- u8 *ptr=data, *endp=data+len;
+ u8 *ptr=data, *endp=data+len, c;
unsigned long header=0;
int rc=0;
- struct tm6000_buffer *buf;
- char *outp = NULL;
-
- get_next_buf(dma_q, &buf);
- if (buf)
- outp = videobuf_to_vmalloc(&buf->vb);
+ unsigned int cmd, cpysize, pktsize, size, field, block, line, pos = 0;
+ struct tm6000_buffer *vbuf;
+ char *voutp = NULL;
+ unsigned int linewidth;
- if (!outp)
+ /* get video buffer */
+ get_next_buf (dma_q, &vbuf);
+ if (!vbuf)
+ return rc;
+ voutp = videobuf_to_vmalloc(&vbuf->vb);
+ if (!voutp)
return 0;
- for (ptr=data; ptr<endp;) {
+ for (ptr = data; ptr < endp;) {
if (!dev->isoc_ctl.cmd) {
- u8 *p=(u8 *)&dev->isoc_ctl.tmp_buf;
- /* FIXME: This seems very complex
- * It just recovers up to 3 bytes of the header that
- * might be at the previous packet
- */
- if (dev->isoc_ctl.tmp_buf_len) {
- while (dev->isoc_ctl.tmp_buf_len) {
- if ( *(ptr+3-dev->isoc_ctl.tmp_buf_len) == 0x47) {
- break;
- }
- p++;
- dev->isoc_ctl.tmp_buf_len--;
- }
- if (dev->isoc_ctl.tmp_buf_len) {
- memcpy(&header, p,
- dev->isoc_ctl.tmp_buf_len);
- memcpy((u8 *)&header +
+ /* Header */
+ if (dev->isoc_ctl.tmp_buf_len > 0) {
+ /* from last urb or packet */
+ header = dev->isoc_ctl.tmp_buf;
+ if (4 - dev->isoc_ctl.tmp_buf_len > 0) {
+ memcpy ((u8 *)&header +
dev->isoc_ctl.tmp_buf_len,
ptr,
4 - dev->isoc_ctl.tmp_buf_len);
ptr += 4 - dev->isoc_ctl.tmp_buf_len;
- goto HEADER;
}
- }
- /* Seek for sync */
- for (;ptr<endp-3;ptr++) {
- if (*(ptr+3)==0x47)
- break;
+ dev->isoc_ctl.tmp_buf_len = 0;
+ } else {
+ if (ptr + 3 >= endp) {
+ /* have incomplete header */
+ dev->isoc_ctl.tmp_buf_len = endp - ptr;
+ memcpy (&dev->isoc_ctl.tmp_buf, ptr,
+ dev->isoc_ctl.tmp_buf_len);
+ return rc;
+ }
+ /* Seek for sync */
+ for (; ptr < endp - 3; ptr++) {
+ if (*(ptr + 3) == 0x47)
+ break;
+ }
+ /* Get message header */
+ header = *(unsigned long *)ptr;
+ ptr += 4;
}
- if (ptr+3>=endp) {
- dev->isoc_ctl.tmp_buf_len=endp-ptr;
- memcpy (&dev->isoc_ctl.tmp_buf,ptr,
- dev->isoc_ctl.tmp_buf_len);
- dev->isoc_ctl.cmd=0;
- return rc;
+ /* split the header fields */
+ c = (header >> 24) & 0xff;
+ size = ((header & 0x7e) << 1);
+ if (size > 0)
+ size -= 4;
+ block = (header >> 7) & 0xf;
+ field = (header >> 11) & 0x1;
+ line = (header >> 12) & 0x1ff;
+ cmd = (header >> 21) & 0x7;
+ /* Validates haeder fields */
+ if (size > TM6000_URB_MSG_LEN)
+ size = TM6000_URB_MSG_LEN;
+ pktsize = TM6000_URB_MSG_LEN;
+ /* calculate position in buffer
+ * and change the buffer
+ */
+ switch (cmd) {
+ case TM6000_URB_MSG_VIDEO:
+ if ((dev->isoc_ctl.vfield != field) &&
+ (field == 1)) {
+ /* Announces that a new buffer
+ * were filled
+ */
+ buffer_filled (dev, dma_q, vbuf);
+ dprintk (dev, V4L2_DEBUG_ISOC,
+ "new buffer filled\n");
+ get_next_buf (dma_q, &vbuf);
+ if (!vbuf)
+ return rc;
+ voutp = videobuf_to_vmalloc (&vbuf->vb);
+ if (!voutp)
+ return rc;
+ memset(voutp, 0, vbuf->vb.size);
+ }
+ linewidth = vbuf->vb.width << 1;
+ pos = ((line << 1) - field - 1) * linewidth +
+ block * TM6000_URB_MSG_LEN;
+ /* Don't allow to write out of the buffer */
+ if (pos + size > vbuf->vb.size)
+ cmd = TM6000_URB_MSG_ERR;
+ dev->isoc_ctl.vfield = field;
+ break;
+ case TM6000_URB_MSG_VBI:
+ break;
+ case TM6000_URB_MSG_AUDIO:
+ case TM6000_URB_MSG_PTS:
+ size = pktsize; /* Size is always 180 bytes */
+ break;
}
-
- /* Get message header */
- header=*(unsigned long *)ptr;
- ptr+=4;
+ } else {
+ /* Continue the last copy */
+ cmd = dev->isoc_ctl.cmd;
+ size = dev->isoc_ctl.size;
+ pos = dev->isoc_ctl.pos;
+ pktsize = dev->isoc_ctl.pktsize;
}
-HEADER:
- /* Copy or continue last copy */
- rc=copy_packet(urb,header,&ptr,endp,outp,&buf);
- if (rc<0) {
- buf=NULL;
- printk(KERN_ERR "tm6000: buffer underrun at %ld\n",
- jiffies);
- return rc;
+ cpysize = (endp - ptr > size) ? size : endp - ptr;
+ if (cpysize) {
+ /* copy data in different buffers */
+ switch (cmd) {
+ case TM6000_URB_MSG_VIDEO:
+ /* Fills video buffer */
+ if (vbuf)
+ memcpy (&voutp[pos], ptr, cpysize);
+ break;
+ case TM6000_URB_MSG_AUDIO:
+ tm6000_call_fillbuf(dev, TM6000_AUDIO, ptr, cpysize);
+ break;
+ case TM6000_URB_MSG_VBI:
+ /* Need some code to copy vbi buffer */
+ break;
+ case TM6000_URB_MSG_PTS:
+ /* Need some code to copy pts */
+ break;
+ }
+ }
+ if (ptr + pktsize > endp) {
+ /* End of URB packet, but cmd processing is not
+ * complete. Preserve the state for a next packet
+ */
+ dev->isoc_ctl.pos = pos + cpysize;
+ dev->isoc_ctl.size = size - cpysize;
+ dev->isoc_ctl.cmd = cmd;
+ dev->isoc_ctl.pktsize = pktsize - (endp - ptr);
+ ptr += endp - ptr;
+ } else {
+ dev->isoc_ctl.cmd = 0;
+ ptr += pktsize;
}
- if (!buf)
- return 0;
}
-
return 0;
}
+
/*
* Identify the tm5600/6000 buffer header type and properly handles
*/
@@ -510,7 +425,6 @@ static inline int tm6000_isoc_copy(struct urb *urb)
{
struct tm6000_dmaqueue *dma_q = urb->context;
struct tm6000_core *dev= container_of(dma_q,struct tm6000_core,vidq);
- struct tm6000_buffer *buf;
int i, len=0, rc=1, status;
char *p;
@@ -585,7 +499,6 @@ static void tm6000_uninit_isoc(struct tm6000_core *dev)
struct urb *urb;
int i;
- dev->isoc_ctl.nfields = -1;
dev->isoc_ctl.buf = NULL;
for (i = 0; i < dev->isoc_ctl.num_bufs; i++) {
urb=dev->isoc_ctl.urb[i];
@@ -610,8 +523,6 @@ static void tm6000_uninit_isoc(struct tm6000_core *dev)
dev->isoc_ctl.urb=NULL;
dev->isoc_ctl.transfer_buffer=NULL;
dev->isoc_ctl.num_bufs = 0;
-
- dev->isoc_ctl.num_bufs=0;
}
/*
diff --git a/drivers/staging/tm6000/tm6000.h b/drivers/staging/tm6000/tm6000.h
index 7bbaf26dea14..1ec1bff9b294 100644
--- a/drivers/staging/tm6000/tm6000.h
+++ b/drivers/staging/tm6000/tm6000.h
@@ -20,8 +20,8 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-// Use the tm6000-hack, instead of the proper initialization code
-//#define HACK 1
+/* Use the tm6000-hack, instead of the proper initialization code i*/
+/* #define HACK 1 */
#include <linux/videodev2.h>
#include <media/v4l2-common.h>
@@ -98,7 +98,7 @@ enum tm6000_io_method {
};
enum tm6000_mode {
- TM6000_MODE_UNKNOWN=0,
+ TM6000_MODE_UNKNOWN = 0,
TM6000_MODE_ANALOG,
TM6000_MODE_DIGITAL,
};
@@ -128,10 +128,21 @@ struct tm6000_dvb {
struct dvb_frontend *frontend;
struct dmxdev dmxdev;
unsigned int streams;
- struct urb *bulk_urb;
+ struct urb *bulk_urb;
struct mutex mutex;
};
+struct snd_tm6000_card {
+ struct snd_card *card;
+ spinlock_t reg_lock;
+ struct tm6000_core *core;
+ struct snd_pcm_substream *substream;
+
+ /* temporary data for buffer fill processing */
+ unsigned buf_pos;
+ unsigned period_pos;
+};
+
struct tm6000_endpoint {
struct usb_host_endpoint *endp;
__u8 bInterfaceNumber;
@@ -147,7 +158,7 @@ struct tm6000_core {
enum tm6000_devtype dev_type; /* type of device */
v4l2_std_id norm; /* Current norm */
- int width,height; /* Selected resolution */
+ int width, height; /* Selected resolution */
enum tm6000_core_state state;
@@ -160,6 +171,8 @@ struct tm6000_core {
struct tm6000_gpio gpio;
+ char *ir_codes;
+
/* Demodulator configuration */
int demod_addr; /* demodulator address */
@@ -190,6 +203,11 @@ struct tm6000_core {
/* DVB-T support */
struct tm6000_dvb *dvb;
+ /* audio support */
+ struct snd_tm6000_card *adev;
+
+ struct tm6000_IR *ir;
+
/* locks */
struct mutex lock;
@@ -197,6 +215,7 @@ struct tm6000_core {
struct usb_device *udev; /* the usb device */
struct tm6000_endpoint bulk_in, bulk_out, isoc_in, isoc_out;
+ struct tm6000_endpoint int_in, int_out;
/* scaler!=0 if scaler is active*/
int scaler;
@@ -207,14 +226,18 @@ struct tm6000_core {
spinlock_t slock;
};
-#define TM6000_AUDIO 0x10
+enum tm6000_ops_type {
+ TM6000_AUDIO = 0x10,
+ TM6000_DVB = 0x20,
+};
struct tm6000_ops {
struct list_head next;
char *name;
- int id;
+ enum tm6000_ops_type type;
int (*init)(struct tm6000_core *);
int (*fini)(struct tm6000_core *);
+ int (*fillbuf)(struct tm6000_core *, char *buf, int size);
};
struct tm6000_fh {
@@ -222,7 +245,7 @@ struct tm6000_fh {
/* video capture */
struct tm6000_fmt *fmt;
- unsigned int width,height;
+ unsigned int width, height;
struct videobuf_queue vb_vidq;
enum v4l2_buf_type type;
@@ -234,28 +257,24 @@ struct tm6000_fh {
/* In tm6000-cards.c */
-int tm6000_tuner_callback (void *ptr, int component, int command, int arg);
-int tm6000_xc5000_callback (void *ptr, int component, int command, int arg);
+int tm6000_tuner_callback(void *ptr, int component, int command, int arg);
+int tm6000_xc5000_callback(void *ptr, int component, int command, int arg);
int tm6000_cards_setup(struct tm6000_core *dev);
/* In tm6000-core.c */
-int tm6000_read_write_usb (struct tm6000_core *dev, u8 reqtype, u8 req,
+int tm6000_read_write_usb(struct tm6000_core *dev, u8 reqtype, u8 req,
u16 value, u16 index, u8 *buf, u16 len);
-int tm6000_get_reg (struct tm6000_core *dev, u8 req, u16 value, u16 index);
+int tm6000_get_reg(struct tm6000_core *dev, u8 req, u16 value, u16 index);
int tm6000_get_reg16(struct tm6000_core *dev, u8 req, u16 value, u16 index);
int tm6000_get_reg32(struct tm6000_core *dev, u8 req, u16 value, u16 index);
-int tm6000_set_reg (struct tm6000_core *dev, u8 req, u16 value, u16 index);
+int tm6000_set_reg(struct tm6000_core *dev, u8 req, u16 value, u16 index);
int tm6000_i2c_reset(struct tm6000_core *dev, u16 tsleep);
+int tm6000_init(struct tm6000_core *dev);
-int tm6000_init (struct tm6000_core *dev);
-
-int tm6000_init_analog_mode (struct tm6000_core *dev);
-int tm6000_init_digital_mode (struct tm6000_core *dev);
-int tm6000_set_audio_bitrate (struct tm6000_core *dev, int bitrate);
-
-int tm6000_dvb_register(struct tm6000_core *dev);
-void tm6000_dvb_unregister(struct tm6000_core *dev);
+int tm6000_init_analog_mode(struct tm6000_core *dev);
+int tm6000_init_digital_mode(struct tm6000_core *dev);
+int tm6000_set_audio_bitrate(struct tm6000_core *dev, int bitrate);
int tm6000_v4l2_register(struct tm6000_core *dev);
int tm6000_v4l2_unregister(struct tm6000_core *dev);
@@ -268,10 +287,13 @@ int tm6000_register_extension(struct tm6000_ops *ops);
void tm6000_unregister_extension(struct tm6000_ops *ops);
void tm6000_init_extension(struct tm6000_core *dev);
void tm6000_close_extension(struct tm6000_core *dev);
+int tm6000_call_fillbuf(struct tm6000_core *dev, enum tm6000_ops_type type,
+ char *buf, int size);
+
/* In tm6000-stds.c */
void tm6000_get_std_res(struct tm6000_core *dev);
-int tm6000_set_standard (struct tm6000_core *dev, v4l2_std_id *norm);
+int tm6000_set_standard(struct tm6000_core *dev, v4l2_std_id *norm);
/* In tm6000-i2c.c */
int tm6000_i2c_register(struct tm6000_core *dev);
@@ -285,14 +307,14 @@ int tm6000_vidioc_streamon(struct file *file, void *priv,
enum v4l2_buf_type i);
int tm6000_vidioc_streamoff(struct file *file, void *priv,
enum v4l2_buf_type i);
-int tm6000_vidioc_reqbufs (struct file *file, void *priv,
- struct v4l2_requestbuffers *rb);
-int tm6000_vidioc_querybuf (struct file *file, void *priv,
- struct v4l2_buffer *b);
-int tm6000_vidioc_qbuf (struct file *file, void *priv, struct v4l2_buffer *b);
-int tm6000_vidioc_dqbuf (struct file *file, void *priv, struct v4l2_buffer *b);
+int tm6000_vidioc_reqbufs(struct file *file, void *priv,
+ struct v4l2_requestbuffers *rb);
+int tm6000_vidioc_querybuf(struct file *file, void *priv,
+ struct v4l2_buffer *b);
+int tm6000_vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *b);
+int tm6000_vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b);
ssize_t tm6000_v4l2_read(struct file *filp, char __user * buf, size_t count,
- loff_t * f_pos);
+ loff_t *f_pos);
unsigned int tm6000_v4l2_poll(struct file *file,
struct poll_table_struct *wait);
int tm6000_queue_init(struct tm6000_core *dev);
@@ -300,6 +322,10 @@ int tm6000_queue_init(struct tm6000_core *dev);
/* In tm6000-alsa.c */
/*int tm6000_audio_init(struct tm6000_core *dev, int idx);*/
+/* In tm6000-input.c */
+int tm6000_ir_init(struct tm6000_core *dev);
+int tm6000_ir_fini(struct tm6000_core *dev);
+void tm6000_ir_wait(struct tm6000_core *dev, u8 state);
/* Debug stuff */
@@ -307,7 +333,7 @@ extern int tm6000_debug;
#define dprintk(dev, level, fmt, arg...) do {\
if (tm6000_debug & level) \
- printk(KERN_INFO "(%lu) %s %s :"fmt, jiffies, \
+ printk(KERN_INFO "(%lu) %s %s :"fmt, jiffies, \
dev->name, __FUNCTION__ , ##arg); } while (0)
#define V4L2_DEBUG_REG 0x0004
@@ -320,5 +346,3 @@ extern int tm6000_debug;
#define tm6000_err(fmt, arg...) do {\
printk(KERN_ERR "tm6000 %s :"fmt, \
__FUNCTION__ , ##arg); } while (0)
-
-