summaryrefslogtreecommitdiff
path: root/drivers/staging
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@redhat.com>2010-07-04 16:33:26 -0300
committerMauro Carvalho Chehab <mchehab@redhat.com>2010-07-04 16:33:26 -0300
commit8d81eecb8fe7098d43ae33fcdeb7acdc9ae91108 (patch)
treebf120fe66bcdce07d8ea108852e15299edf94d7e /drivers/staging
parent011906dc794530a0f2a86dd5a6e4caff19200a3d (diff)
parent6e5e76fad4b3f29772446c6a95c18d1b674c9fd2 (diff)
Merge branch 'staging/tm6000' into staging/all
* staging/tm6000: (29 commits) tm6000: Partially revert some copybuf logic tm6000: Be sure that the new buffer is empty tm6000: Fix copybuf continue logic Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com> tm6000: audio packet has always 180 bytes tm6000: Improve set bitrate routines used by alsa tm6000-alsa: Implement a routine to store data received from URB tm6000-alsa: Fix several bugs at the driver initialization code tm6000: avoid unknown symbol tm6000_debug tm6000: Add a callback code for buffer fill tm6000: Use an emum for extension type tm6000-alsa: rework audio buffer allocation/deallocation tm6000: Avoid OOPS when loading tm6000-alsa module tm6000: Fix compilation breakages V4L/DVB: Staging: tm6000: Fix coding style issues V4L/DVB: tm6000: move dvb into a separate kern module V4L/DVB: tm6000: rewrite init and fini V4L/DVB: tm6000: Fix Video decoder initialization V4L/DVB: tm6000: rewrite copy_streams V4L/DVB: tm6000: add DVB support for tuner xc5000 V4L/DVB: tm6000: set variable dev_mode in function tm6000_start_stream ...
Diffstat (limited to 'drivers/staging')
-rw-r--r--drivers/staging/tm6000/Kconfig4
-rw-r--r--drivers/staging/tm6000/Makefile5
-rw-r--r--drivers/staging/tm6000/tm6000-alsa.c263
-rw-r--r--drivers/staging/tm6000/tm6000-cards.c34
-rw-r--r--drivers/staging/tm6000/tm6000-core.c188
-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-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.h79
11 files changed, 584 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..4129c185da53 100644
--- a/drivers/staging/tm6000/Makefile
+++ b/drivers/staging/tm6000/Makefile
@@ -4,12 +4,9 @@ tm6000-objs := tm6000-cards.o \
tm6000-video.o \
tm6000-stds.o
-ifeq ($(CONFIG_VIDEO_TM6000_DVB),y)
-tm6000-objs += tm6000-dvb.o
-endif
-
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 ce081cd44ad4..aa3857737560 100644
--- a/drivers/staging/tm6000/tm6000-alsa.c
+++ b/drivers/staging/tm6000/tm6000-alsa.c
@@ -15,6 +15,7 @@
#include <linux/device.h>
#include <linux/interrupt.h>
#include <linux/usb.h>
+#include <linux/vmalloc.h>
#include <asm/delay.h>
#include <sound/core.h>
@@ -35,34 +36,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);
@@ -99,11 +77,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;
@@ -128,19 +110,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
****************************************************************************/
@@ -157,16 +159,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,
};
/*
@@ -201,29 +203,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;
}
@@ -233,13 +270,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;
}
@@ -249,6 +282,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;
}
@@ -286,12 +324,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;
}
/*
@@ -311,21 +345,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? */
@@ -336,27 +355,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;
@@ -364,45 +397,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;
@@ -413,14 +425,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 cedd9044022f..50756e5604a4 100644
--- a/drivers/staging/tm6000/tm6000-cards.c
+++ b/drivers/staging/tm6000/tm6000-cards.c
@@ -346,7 +346,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 */
@@ -423,6 +423,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)
{
@@ -680,31 +681,11 @@ 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;
- }
-
-#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;
@@ -723,7 +704,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;
@@ -905,13 +886,6 @@ 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
-
if (dev->gpio.power_led) {
switch (dev->model) {
case TM6010_BOARD_HAUPPAUGE_900H:
@@ -941,8 +915,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 27f3f551b545..9f60ad5e6f0a 100644
--- a/drivers/staging/tm6000/tm6000-core.c
+++ b/drivers/staging/tm6000/tm6000-core.c
@@ -31,66 +31,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");
}
}
@@ -102,52 +100,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;
@@ -187,7 +185,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;
@@ -293,12 +291,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);
@@ -331,13 +327,19 @@ 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) {
+ tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
+ dev->gpio.dvb_led, 0x01);
+ }
/* switch dvb led off */
if (dev->gpio.dvb_led) {
@@ -348,7 +350,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;
@@ -365,10 +367,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);
@@ -376,7 +376,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);
@@ -387,14 +387,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);
}
@@ -406,6 +406,7 @@ int tm6000_init_digital_mode (struct tm6000_core *dev)
return 0;
}
+EXPORT_SYMBOL(tm6000_init_digital_mode);
struct reg_init {
u8 req;
@@ -565,9 +566,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) {
@@ -579,12 +580,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;
}
}
@@ -592,12 +593,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);
@@ -608,23 +608,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;
}
@@ -658,6 +667,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;
@@ -666,10 +692,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 261e66acbe46..ff9cc6d50c3d 100644
--- a/drivers/staging/tm6000/tm6000-dvb.c
+++ b/drivers/staging/tm6000/tm6000-dvb.c
@@ -30,12 +30,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;
@@ -61,7 +74,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 {
@@ -73,19 +86,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);
@@ -99,7 +110,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);
@@ -107,7 +118,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;
}
@@ -119,7 +130,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;
@@ -131,20 +142,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);
@@ -158,10 +169,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;
@@ -173,35 +184,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); */
}
@@ -215,9 +225,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,
@@ -226,8 +236,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;
}
@@ -237,7 +246,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;
@@ -248,13 +257,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) {
@@ -307,9 +316,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;
@@ -320,7 +328,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;
}
@@ -330,7 +338,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;
}
@@ -340,7 +348,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);
}
@@ -350,11 +358,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);
@@ -364,7 +372,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);
}
@@ -374,5 +382,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-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..89862a49520d 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;
@@ -190,6 +201,9 @@ struct tm6000_core {
/* DVB-T support */
struct tm6000_dvb *dvb;
+ /* audio support */
+ struct snd_tm6000_card *adev;
+
/* locks */
struct mutex lock;
@@ -207,14 +221,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 +240,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 +252,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 +282,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 +302,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);
@@ -307,7 +324,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 +337,3 @@ extern int tm6000_debug;
#define tm6000_err(fmt, arg...) do {\
printk(KERN_ERR "tm6000 %s :"fmt, \
__FUNCTION__ , ##arg); } while (0)
-
-