From ce2ae02a277e4e7ab71316b87d0f0ae4e66bd2b7 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 23 Oct 2008 10:20:27 -0200 Subject: radio-si470x: add support for kworld usb radio From: Alexey Klimov This patch add support for new device named KWorld USB FM Radio SnapMusic Mobile 700 (FM700). And changes few lines in comments. Signed-off-by: Alexey Klimov Acked-By: Tobias Lorenz Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/radio/radio-si470x.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/linux/drivers/media/radio/radio-si470x.c b/linux/drivers/media/radio/radio-si470x.c index e332b3de5..921deeb89 100644 --- a/linux/drivers/media/radio/radio-si470x.c +++ b/linux/drivers/media/radio/radio-si470x.c @@ -4,6 +4,7 @@ * Driver for USB radios for the Silicon Labs Si470x FM Radio Receivers: * - Silicon Labs USB FM Radio Reference Design * - ADS/Tech FM Radio Receiver (formerly Instant FM Music) (RDX-155-EF) + * - KWorld USB FM Radio SnapMusic Mobile 700 (FM700) * * Copyright (c) 2008 Tobias Lorenz * @@ -105,6 +106,9 @@ * - afc indication * - more safety checks, let si470x_get_freq return errno * - vidioc behavior corrected according to v4l2 spec + * 2008-10-20 Alexey Klimov + * - add support for KWorld USB FM Radio FM700 + * - blacklisted KWorld radio in hid-core.c and hid-ids.h * * ToDo: * - add firmware download/update support @@ -146,6 +150,8 @@ static struct usb_device_id si470x_usb_driver_id_table[] = { { USB_DEVICE_AND_INTERFACE_INFO(0x10c4, 0x818a, USB_CLASS_HID, 0, 0) }, /* ADS/Tech FM Radio Receiver (formerly Instant FM Music) */ { USB_DEVICE_AND_INTERFACE_INFO(0x06e1, 0xa155, USB_CLASS_HID, 0, 0) }, + /* KWorld USB FM Radio SnapMusic Mobile 700 (FM700) */ + { USB_DEVICE_AND_INTERFACE_INFO(0x1b80, 0xd700, USB_CLASS_HID, 0, 0) }, /* Terminating entry */ { } }; -- cgit v1.2.3 From de797c21fdcc4d220dd797b792ad3b290f7cec94 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 23 Oct 2008 10:53:56 -0200 Subject: ibmcam: Fix a regression caused by a482f327ff56bc3cf53176a7eb736cea47291a1d From: Mauro Carvalho Chehab As reported by David Ellingsworth: > I'm not sure if it matters or not, but the ibmcam driver in the > Mauro's linux-2.6 git tree in the for_linus branch is currently > broken. uvd is equal to NULL during most of ibmcam_probe. Due to that, an OOPS is generated at dev_info. This patch replaces uvd->dev->dev to dev->dev inside this routine. Signed-off-by: Mauro Carvalho Chehab Reviewed-by: David Ellingsworth --- linux/drivers/media/video/usbvideo/ibmcam.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/linux/drivers/media/video/usbvideo/ibmcam.c b/linux/drivers/media/video/usbvideo/ibmcam.c index d202feac0..1119bcf58 100644 --- a/linux/drivers/media/video/usbvideo/ibmcam.c +++ b/linux/drivers/media/video/usbvideo/ibmcam.c @@ -3695,7 +3695,7 @@ static int ibmcam_probe(struct usb_interface *intf, const struct usb_device_id * unsigned char video_ep = 0; if (debug >= 1) - dev_info(&uvd->dev->dev, "ibmcam_probe(%p,%u.)\n", intf, ifnum); + dev_info(&dev->dev, "ibmcam_probe(%p,%u.)\n", intf, ifnum); /* We don't handle multi-config cameras */ if (dev->descriptor.bNumConfigurations != 1) @@ -3746,7 +3746,7 @@ static int ibmcam_probe(struct usb_interface *intf, const struct usb_device_id * brand = "IBM PC Camera"; /* a.k.a. Xirlink C-It */ break; } - dev_info(&uvd->dev->dev, + dev_info(&dev->dev, "%s USB camera found (model %d, rev. 0x%04x)\n", brand, model, le16_to_cpu(dev->descriptor.bcdDevice)); } while (0); @@ -3754,7 +3754,7 @@ static int ibmcam_probe(struct usb_interface *intf, const struct usb_device_id * /* Validate found interface: must have one ISO endpoint */ nas = intf->num_altsetting; if (debug > 0) - dev_info(&uvd->dev->dev, "Number of alternate settings=%d.\n", + dev_info(&dev->dev, "Number of alternate settings=%d.\n", nas); if (nas < 2) { err("Too few alternate settings for this camera!"); @@ -3799,7 +3799,7 @@ static int ibmcam_probe(struct usb_interface *intf, const struct usb_device_id * actInterface = i; maxPS = le16_to_cpu(endpoint->wMaxPacketSize); if (debug > 0) - dev_info(&uvd->dev->dev, + dev_info(&dev->dev, "Active setting=%d. " "maxPS=%d.\n", i, maxPS); } else @@ -3840,7 +3840,7 @@ static int ibmcam_probe(struct usb_interface *intf, const struct usb_device_id * RESTRICT_TO_RANGE(framerate, 0, 5); break; default: - dev_info(&uvd->dev->dev, "IBM camera: using 320x240\n"); + dev_info(&dev->dev, "IBM camera: using 320x240\n"); size = SIZE_320x240; /* No break here */ case SIZE_320x240: @@ -3869,7 +3869,7 @@ static int ibmcam_probe(struct usb_interface *intf, const struct usb_device_id * canvasY = 120; break; default: - dev_info(&uvd->dev->dev, "IBM NetCamera: using 176x144\n"); + dev_info(&dev->dev, "IBM NetCamera: using 176x144\n"); size = SIZE_176x144; /* No break here */ case SIZE_176x144: -- cgit v1.2.3 From 29ac7c213e31ba795fc416ad8b584eae712e11c4 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 23 Oct 2008 10:55:22 -0200 Subject: Add some missing compat32 ioctls From: Gregor Jasny This patch adds the missing compat ioctls that are needed to operate Skype in combination with libv4l and a MJPEG only camera. If you think it's trivial enough please submit it to -stable, too. Signed-off-by: Gregor Jasny Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/compat_ioctl32.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/linux/drivers/media/video/compat_ioctl32.c b/linux/drivers/media/video/compat_ioctl32.c index a37f3a64e..2b36744c0 100644 --- a/linux/drivers/media/video/compat_ioctl32.c +++ b/linux/drivers/media/video/compat_ioctl32.c @@ -932,6 +932,7 @@ long v4l_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg) case VIDIOC_STREAMON32: case VIDIOC_STREAMOFF32: case VIDIOC_G_PARM: + case VIDIOC_S_PARM: case VIDIOC_G_STD: case VIDIOC_S_STD: case VIDIOC_G_TUNER: @@ -950,6 +951,8 @@ long v4l_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg) case VIDIOC_S_INPUT32: case VIDIOC_TRY_FMT32: case VIDIOC_S_HW_FREQ_SEEK: + case VIDIOC_ENUM_FRAMESIZES: + case VIDIOC_ENUM_FRAMEINTERVALS: ret = do_video_ioctl(file, cmd, arg); break; -- cgit v1.2.3 From 33b3d5674be358c590d4608cbf57101fbfa25632 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 18 Oct 2008 07:41:52 +0000 Subject: V4L/DVB: remove unused #include From: Huang Weiyi The file(s) below do not use LINUX_VERSION_CODE nor KERNEL_VERSION. drivers/media/dvb/dm1105/dm1105.c drivers/media/dvb/dvb-usb/dw2102.c This patch removes the said #include . Signed-off-by: Huang Weiyi Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/dm1105/dm1105.c | 1 - linux/drivers/media/dvb/dvb-usb/dw2102.c | 1 - 2 files changed, 2 deletions(-) diff --git a/linux/drivers/media/dvb/dm1105/dm1105.c b/linux/drivers/media/dvb/dm1105/dm1105.c index d9d1e0a12..19daa752f 100644 --- a/linux/drivers/media/dvb/dm1105/dm1105.c +++ b/linux/drivers/media/dvb/dm1105/dm1105.c @@ -19,7 +19,6 @@ * */ -#include #include #include #include diff --git a/linux/drivers/media/dvb/dvb-usb/dw2102.c b/linux/drivers/media/dvb/dvb-usb/dw2102.c index 6286fbbe7..c9431713d 100644 --- a/linux/drivers/media/dvb/dvb-usb/dw2102.c +++ b/linux/drivers/media/dvb/dvb-usb/dw2102.c @@ -9,7 +9,6 @@ * * see Documentation/dvb/README.dvb-usb for more information */ -#include #include "dw2102.h" #include "si21xx.h" #include "stv0299.h" -- cgit v1.2.3 From ec60228e845ea89c0f4e3e5b2a0d7f3ce832f182 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 24 Oct 2008 08:44:03 -0200 Subject: Fix compilation with RHEL 5.2 kernel From: Mauro Carvalho Chehab RHEL 5 already declares bool. Still, there are some warnings that probably indicate that something else needs to be done for the code to work with RHEL5. Priority: normal Signed-off-by: Mauro Carvalho Chehab --- v4l/compat.h | 2 ++ v4l/scripts/make_config_compat.pl | 20 ++++++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/v4l/compat.h b/v4l/compat.h index f3dfceafe..7325e15c4 100644 --- a/v4l/compat.h +++ b/v4l/compat.h @@ -55,7 +55,9 @@ #define DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d)) #define PCIAGP_FAIL 0 #define vmalloc_32_user(a) vmalloc_32(a) +#endif +#ifdef NEED_BOOL_TYPE /* bool type and enum-based definition of true and false was added in 2.6.19 */ typedef int bool; #define true 1 diff --git a/v4l/scripts/make_config_compat.pl b/v4l/scripts/make_config_compat.pl index e538c925b..bd34e7193 100755 --- a/v4l/scripts/make_config_compat.pl +++ b/v4l/scripts/make_config_compat.pl @@ -83,12 +83,32 @@ sub check_snd_ctl_boolean_mono_info() close INNET; } +sub check_bool() +{ + my $file = "$kdir/include/linux/types.h"; + my $old_syntax = 1; + + open INDEP, "<$file" or die "File not found: $file"; + while () { + if (m/^\s*typedef.*bool;/) { + $old_syntax = 0; + last; + } + } + + if ($old_syntax) { + $out.= "\n#define NEED_BOOL_TYPE 1\n"; + } + close INDEP; +} + sub check_other_dependencies() { check_spin_lock(); check_sound_driver_h(); check_snd_ctl_boolean_mono_info(); check_snd_pcm_rate_to_rate_bit(); + check_bool(); } # Do the basic rules -- cgit v1.2.3 From 1b6595818b457badf50f6aff79f832360eb499de Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 17 Oct 2008 23:19:29 +0000 Subject: de-BKL cafe_ccic.c From: Jonathan Corbet Remove lock_kernel() call from cafe_ccic.c Commit d56dc61265d2527a63ab5b0f03199a43cd89ca36 added lock_kernel() calls to cafe_ccic.c. But that driver was written with proper locking and does not need the BKL, so take it back out. Signed-off-by: Jonathan Corbet Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/cafe_ccic.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/linux/drivers/media/video/cafe_ccic.c b/linux/drivers/media/video/cafe_ccic.c index 6aba16f85..1184b9186 100644 --- a/linux/drivers/media/video/cafe_ccic.c +++ b/linux/drivers/media/video/cafe_ccic.c @@ -1483,12 +1483,9 @@ static int cafe_v4l_open(struct inode *inode, struct file *filp) { struct cafe_camera *cam; - lock_kernel(); cam = cafe_find_dev(iminor(inode)); - if (cam == NULL) { - unlock_kernel(); + if (cam == NULL) return -ENODEV; - } filp->private_data = cam; mutex_lock(&cam->s_mutex); @@ -1500,7 +1497,6 @@ static int cafe_v4l_open(struct inode *inode, struct file *filp) } (cam->users)++; mutex_unlock(&cam->s_mutex); - unlock_kernel(); return 0; } -- cgit v1.2.3 From d0ef773c94431fc5e1f8fa033914ddf75a74e472 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 20 Oct 2008 13:57:02 -0700 Subject: [PATCH] saa7134: fix resource map sanity check conflict From: Suresh Siddha Impact: driver could possibly stomp on resources outside of its scope {mchehab@redhat.com: I got two versions of the same patch (identical, except for whitespacing). One authored by Andy Burns and another authored by Suresh Siddha. Due to that, I'm applying the one that has less CodingStyle errors. I'm also adding both comments and the SOB's for both patches, since they are both interesting} Suresh Siddha commented: Alexey Fisher reported: > resource map sanity check conflict: 0xcfeff800 0xcff007ff 0xcfe00000 > 0xcfefffff PCI Bus 0000:01 BAR base is located in the middle of the 4K page and the hardcoded size argument makes the request span two pages causing the conflict. Fix the hard coded size argument in ioremap(). Andy Burns commented: I have already sent this patch on the linux-dvb list, but it didn't get much attention, so re-sending direct, I hope you all don't mind. While attempting to run mythtv in a xen domU, I encountered problems loading the driver for my saa7134 card, with an error from ioremap(). This error was due to the driver allocating an incorrectly sized mmio area, which was trapped by xen's permission checks, but this would go un-noticed on a kernel without xen. My card has a 1K sized mmio area, I've had information that other cards have 2K areas, perhaps others have different sizes, yet the driver always attempts to map 4K. I realise that the granularity of mapping is the page size, which typically would be 4K, but unless the card's base address happens to fall on a 4K boundary (mine does not) then the base+4K will end up spanning two pages, and this is when the error occurs under xen. My patch uses the pci_resource_len macro to determine the size required for the user's particular card, instead of the hardcoded 4K value. I've tested with a couple of printk() inside ioremap() that the start address and size do get rounded to the closest page boundary. With this patch I am able to successfully load the saa7134 driver and run mythtv under xen with my card, subject to correct pollirq settings in case of shared IRQ, I am still seeing occasional DMA panics, which I think are related to swiotlb handling by dom0/domU, usually the panic occurs when changing mux, once tuned to a mux, 12 hour continuous recordings are possible without errors. Reported-by: Alexey Fisher Signed-off-by: Suresh Siddha Signed-off-by: Andy Burns Tested-by: Alexey Fisher Signed-off-by: Ingo Molnar Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/saa7134/saa7134-core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/linux/drivers/media/video/saa7134/saa7134-core.c b/linux/drivers/media/video/saa7134/saa7134-core.c index 1d1fdce21..2e9a015e9 100644 --- a/linux/drivers/media/video/saa7134/saa7134-core.c +++ b/linux/drivers/media/video/saa7134/saa7134-core.c @@ -1002,7 +1002,8 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev, dev->name,(unsigned long long)pci_resource_start(pci_dev,0)); goto fail1; } - dev->lmmio = ioremap(pci_resource_start(pci_dev,0), 0x1000); + dev->lmmio = ioremap(pci_resource_start(pci_dev, 0), + pci_resource_len(pci_dev, 0)); dev->bmmio = (__u8 __iomem *)dev->lmmio; if (NULL == dev->lmmio) { err = -EIO; -- cgit v1.2.3 From 8ea0539ab4ca8942b9bd89e943666e4bfb2d2463 Mon Sep 17 00:00:00 2001 From: Thierry MERLE Date: Thu, 23 Oct 2008 22:49:49 +0200 Subject: CinergyT2: fix Kconfig typo From: Thierry MERLE config\tDVB_USB_CINERGY_T2 causes the make_kconfig.pl to forget to enable by default the compilation of cinergyT2 module. Priority: normal Signed-off-by: Thierry MERLE --- linux/drivers/media/dvb/dvb-usb/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linux/drivers/media/dvb/dvb-usb/Kconfig b/linux/drivers/media/dvb/dvb-usb/Kconfig index 47488a97a..62b68c291 100644 --- a/linux/drivers/media/dvb/dvb-usb/Kconfig +++ b/linux/drivers/media/dvb/dvb-usb/Kconfig @@ -261,7 +261,7 @@ config DVB_USB_DW2102 Say Y here to support the DvbWorld DVB-S/S2 USB2.0 receivers and the TeVii S650. -config DVB_USB_CINERGY_T2 +config DVB_USB_CINERGY_T2 tristate "Terratec CinergyT2/qanu USB 2.0 DVB-T receiver" depends on DVB_USB help -- cgit v1.2.3 From 9ac1186d1b2315e2d06b234777d6af07e9170396 Mon Sep 17 00:00:00 2001 From: Thierry MERLE Date: Thu, 23 Oct 2008 23:18:30 +0200 Subject: CinergyT2: on v4l-dvb update, remove the old cinergyT2 driver if present From: Thierry MERLE If a user installs the new CinergyT2 driver, on an kernel on which the old driver is present, the make install procedure does not remove the old driver if present. Just adding an entry in v4l/obsolete.txt does the trick for the user. Priority: normal Signed-off-by: Thierry MERLE --- v4l/obsolete.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/v4l/obsolete.txt b/v4l/obsolete.txt index e720a48b8..b495f6d96 100644 --- a/v4l/obsolete.txt +++ b/v4l/obsolete.txt @@ -4,6 +4,9 @@ video/video-buf # This file were replaced by videobuf-dvb video/video-buf-dvb +#This driver has been reworked and moved to dvb-usb +dvb/cinergyT2/cinergyT2 + # Those drivers were moved to common/tuners dvb/frontends/mt2060 dvb/frontends/mt2131 -- cgit v1.2.3 From 79a20149988e1583787adf53c222a141f510dabf Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 24 Oct 2008 13:47:07 +0000 Subject: cx88-dvb: Fix Oops in case i2c bus failed to register From: Matthias Schwarzott There already is an report at kernel bugzilla about this issue: http://bugzilla.kernel.org/show_bug.cgi?id=9455 When enabling extra checks for the i2c-bus of cx88 based cards by loading i2c_algo_bit with bit_test=1 this may trigger an oops when loading cx88_dvb. This is caused by the extra check code that detects that the sda-line is stuck high and thus does not register the i2c-bus. cx88-dvb however does not check if the i2c-bus is valid and just uses core->i2c_adap to attach dvb frontend modules. This leads to an oops at the first call to i2c_transfer: $ modprobe i2c_algo_bit bit_test=1 $ modprobe cx8802 cx88/2: cx2388x MPEG-TS Driver Manager version 0.0.6 loaded cx88[0]: quirk: PCIPCI_NATOMA -- set TBFX cx88[0]: subsystem: 0070:9202, board: Hauppauge Nova-S-Plus DVB-S [card=37,autodetected], frontend(s): 1 cx88[0]: TV tuner type 4, Radio tuner type -1 cx88[0]: SDA stuck high! cx88[0]: i2c register FAILED input: cx88 IR (Hauppauge Nova-S-Plus as /class/input/input5 cx88[0]/2: cx2388x 8802 Driver Manager cx88-mpeg driver manager 0000:00:10.2: enabling device (0154 -> 0156) cx88-mpeg driver manager 0000:00:10.2: PCI INT A -> Link[LNKD] -> GSI 9 (level, low) -> IRQ 9 cx88[0]/2: found at 0000:00:10.2, rev: 5, irq: 9, latency: 64, mmio: 0xfb000000 cx8802_probe() allocating 1 frontend(s) cx88/2: cx2388x dvb driver version 0.0.6 loaded cx88/2: registering cx8802 driver, type: dvb access: shared cx88[0]/2: subsystem: 0070:9202, board: Hauppauge Nova-S-Plus DVB-S [card=37] cx88[0]/2: cx2388x based DVB/ATSC card BUG: unable to handle kernel NULL pointer dereference at 00000000 IP: [] :i2c_core:i2c_transfer+0x1f/0x80 *pde = 00000000 Modules linked in: cx88_dvb(+) cx8802 cx88xx ir_common i2c_algo_bit tveeprom videobuf_dvb btcx_risc mga drm ipv6 fscpos eeprom nfsd exportfs stv0299 b2c2_flexcop_pci b2c2_flexcop cx24123 s5h1420 ves1x93 dvb_ttpci dvb_core saa7146_vv saa7146 videobuf_dma_sg videobuf_core videodev v4l1_compat ttpci_eeprom lirc_serial lirc_dev usbhid rtc uhci_hcd 8139too i2c_piix4 i2c_core usbcore evdev Pid: 4249, comm: modprobe Not tainted (2.6.27-gentoo #3) EIP: 0060:[] EFLAGS: 00010296 CPU: 0 EIP is at i2c_transfer+0x1f/0x80 [i2c_core] EAX: 00000000 EBX: ffffffa1 ECX: 00000002 EDX: d6c71e3c ESI: d80cd050 EDI: d8093c00 EBP: d6c71e20 ESP: d6c71e0c DS: 007b ES: 007b FS: 0000 GS: 0033 SS: 0068 Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/cx88/cx88-dvb.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/linux/drivers/media/video/cx88/cx88-dvb.c b/linux/drivers/media/video/cx88/cx88-dvb.c index 898ce5ea8..ed2fc02c8 100644 --- a/linux/drivers/media/video/cx88/cx88-dvb.c +++ b/linux/drivers/media/video/cx88/cx88-dvb.c @@ -605,6 +605,11 @@ static int dvb_register(struct cx8802_dev *dev) struct videobuf_dvb_frontend *fe0, *fe1 = NULL; int mfe_shared = 0; /* bus not shared by default */ + if (0 != core->i2c_rc) { + printk(KERN_ERR "%s/2: no i2c-bus available, cannot attach dvb drivers\n", core->name); + goto frontend_detach; + } + /* Get the first frontend */ fe0 = videobuf_dvb_get_frontend(&dev->frontends, 1); if (!fe0) -- cgit v1.2.3 From 6b5f5ff6db5bdccf525c24c356d71bedfba91417 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 23 Oct 2008 17:11:19 +0200 Subject: Dynamic DVB minor allocation From: Andreas Oberritter This is a multi-part message in MIME format. Implement dynamic minor allocation for DVB, to allow more than four devices of the same type per adapter, based on drivers/usb/core/file.c. Add a new config option, DVB_DYNAMIC_MINORS, to make use of this feature, which defaults to no for backwards compatibility. Signed-off-by: Andreas Oberritter Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/Kconfig | 13 +++++++ linux/drivers/media/dvb/dvb-core/dvbdev.c | 61 ++++++++++++++++++++----------- linux/drivers/media/dvb/dvb-core/dvbdev.h | 1 + 3 files changed, 54 insertions(+), 21 deletions(-) diff --git a/linux/drivers/media/dvb/Kconfig b/linux/drivers/media/dvb/Kconfig index 0bcd85257..40ebde53b 100644 --- a/linux/drivers/media/dvb/Kconfig +++ b/linux/drivers/media/dvb/Kconfig @@ -2,6 +2,19 @@ # DVB device configuration # +config DVB_DYNAMIC_MINORS + bool "Dynamic DVB minor allocation" + depends on DVB_CORE + default n + help + If you say Y here, the DVB subsystem will use dynamic minor + allocation for any device that uses the DVB major number. + This means that you can have more than 4 of a single type + of device (like demuxes and frontends) per adapter, but udev + will be required to manage the device nodes. + + If you are unsure about this, say N here. + menuconfig DVB_CAPTURE_DRIVERS bool "DVB/ATSC adapters" depends on DVB_CORE diff --git a/linux/drivers/media/dvb/dvb-core/dvbdev.c b/linux/drivers/media/dvb/dvb-core/dvbdev.c index c2e824710..a35286f1a 100644 --- a/linux/drivers/media/dvb/dvb-core/dvbdev.c +++ b/linux/drivers/media/dvb/dvb-core/dvbdev.c @@ -51,33 +51,27 @@ static const char * const dnames[] = { "net", "osd" }; +#ifdef CONFIG_DVB_DYNAMIC_MINORS +#define MAX_DVB_MINORS 256 +#define DVB_MAX_IDS MAX_DVB_MINORS +#else #define DVB_MAX_IDS 4 #define nums2minor(num,type,id) ((num << 6) | (id << 4) | type) #define MAX_DVB_MINORS (DVB_MAX_ADAPTERS*64) +#endif static struct class *dvb_class; -static struct dvb_device* dvbdev_find_device (int minor) -{ - struct dvb_adapter *adap; - - list_for_each_entry(adap, &dvb_adapter_list, list_head) { - struct dvb_device *dev; - list_for_each_entry(dev, &adap->device_list, list_head) - if (nums2minor(adap->num, dev->type, dev->id) == minor) - return dev; - } - - return NULL; -} - +static struct dvb_device *dvb_minors[MAX_DVB_MINORS]; +static DECLARE_RWSEM(minor_rwsem); static int dvb_device_open(struct inode *inode, struct file *file) { struct dvb_device *dvbdev; lock_kernel(); - dvbdev = dvbdev_find_device (iminor(inode)); + down_read(&minor_rwsem); + dvbdev = dvb_minors[iminor(inode)]; if (dvbdev && dvbdev->fops) { int err = 0; @@ -97,9 +91,11 @@ static int dvb_device_open(struct inode *inode, struct file *file) file->f_op = fops_get(old_fops); } fops_put(old_fops); + up_read(&minor_rwsem); unlock_kernel(); return err; } + up_read(&minor_rwsem); unlock_kernel(); return -ENODEV; } @@ -201,6 +197,7 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev, #else struct class_device *clsdev; #endif + int minor; int id; mutex_lock(&dvbdev_register_lock); @@ -240,6 +237,26 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev, list_add_tail (&dvbdev->list_head, &adap->device_list); + down_write(&minor_rwsem); +#ifdef CONFIG_DVB_DYNAMIC_MINORS + for (minor = 0; minor < MAX_DVB_MINORS; minor++) + if (dvb_minors[minor] == NULL) + break; + + if (minor == MAX_DVB_MINORS) { + kfree(dvbdevfops); + kfree(dvbdev); + mutex_unlock(&dvbdev_register_lock); + return -EINVAL; + } +#else + minor = nums2minor(adap->num, type, id); +#endif + + dvbdev->minor = minor; + dvb_minors[minor] = dvbdev; + up_write(&minor_rwsem); + mutex_unlock(&dvbdev_register_lock); #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 27) @@ -248,11 +265,11 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev, NULL, "dvb%d.%s%d", adap->num, dnames[type], id); #elif LINUX_VERSION_CODE == KERNEL_VERSION(2, 6, 27) clsdev = device_create_drvdata(dvb_class, adap->device, - MKDEV(DVB_MAJOR, nums2minor(adap->num, type, id)), + MKDEV(DVB_MAJOR, minor), NULL, "dvb%d.%s%d", adap->num, dnames[type], id); #else clsdev = device_create(dvb_class, adap->device, - MKDEV(DVB_MAJOR, nums2minor(adap->num, type, id)), + MKDEV(DVB_MAJOR, minor), "dvb%d.%s%d", adap->num, dnames[type], id); #endif if (IS_ERR(clsdev)) { @@ -262,8 +279,7 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev, } dprintk(KERN_DEBUG "DVB: register adapter%d/%s%d @ minor: %i (0x%02x)\n", - adap->num, dnames[type], id, nums2minor(adap->num, type, id), - nums2minor(adap->num, type, id)); + adap->num, dnames[type], id, minor, minor); return 0; } @@ -275,8 +291,11 @@ void dvb_unregister_device(struct dvb_device *dvbdev) if (!dvbdev) return; - device_destroy(dvb_class, MKDEV(DVB_MAJOR, nums2minor(dvbdev->adapter->num, - dvbdev->type, dvbdev->id))); + down_write(&minor_rwsem); + dvb_minors[dvbdev->minor] = NULL; + up_write(&minor_rwsem); + + device_destroy(dvb_class, MKDEV(DVB_MAJOR, dvbdev->minor)); list_del (&dvbdev->list_head); kfree (dvbdev->fops); diff --git a/linux/drivers/media/dvb/dvb-core/dvbdev.h b/linux/drivers/media/dvb/dvb-core/dvbdev.h index 574e336ba..dca49cf96 100644 --- a/linux/drivers/media/dvb/dvb-core/dvbdev.h +++ b/linux/drivers/media/dvb/dvb-core/dvbdev.h @@ -74,6 +74,7 @@ struct dvb_device { struct file_operations *fops; struct dvb_adapter *adapter; int type; + int minor; u32 id; /* in theory, 'users' can vanish now, -- cgit v1.2.3 From a3051cccbd1392da4014779977273ee72ac0de5e Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 24 Oct 2008 13:15:08 -0200 Subject: zl10353: add new register configuration for zl10353/especially 6mhz taiwan. From: Markus Rechberger Priority: normal Signed-off-by: Markus Rechberger Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/frontends/zl10353.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/linux/drivers/media/dvb/frontends/zl10353.c b/linux/drivers/media/dvb/frontends/zl10353.c index 11160a3ee..2e449a457 100644 --- a/linux/drivers/media/dvb/frontends/zl10353.c +++ b/linux/drivers/media/dvb/frontends/zl10353.c @@ -225,15 +225,18 @@ static int zl10353_set_parameters(struct dvb_frontend *fe, /* These are extrapolated from the 7 and 8MHz values */ zl10353_single_write(fe, MCLK_RATIO, 0x97); zl10353_single_write(fe, 0x64, 0x34); + zl10353_single_write(fe, 0xcc, 0xdd); break; case BANDWIDTH_7_MHZ: zl10353_single_write(fe, MCLK_RATIO, 0x86); zl10353_single_write(fe, 0x64, 0x35); + zl10353_single_write(fe, 0xcc, 0x73); break; case BANDWIDTH_8_MHZ: default: zl10353_single_write(fe, MCLK_RATIO, 0x75); zl10353_single_write(fe, 0x64, 0x36); + zl10353_single_write(fe, 0xcc, 0x73); } zl10353_calc_nominal_rate(fe, op->bandwidth, &nominal_rate); -- cgit v1.2.3 From dfad04b41675b7df9a5bab9638af9f32e340c4d0 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 24 Oct 2008 13:19:14 -0200 Subject: tvp5150: add support to enable raw vbi From: Markus Rechberger Priority: normal Signed-off-by: Markus Rechberger [mchehab@redhat.com: Fix bad whitespaces] Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/tvp5150.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/linux/drivers/media/video/tvp5150.c b/linux/drivers/media/video/tvp5150.c index 28c5c6761..ac8205d87 100644 --- a/linux/drivers/media/video/tvp5150.c +++ b/linux/drivers/media/video/tvp5150.c @@ -935,6 +935,21 @@ static int tvp5150_command(struct i2c_client *c, int i; fmt = arg; + /* raw vbi */ + if (fmt->type == V4L2_BUF_TYPE_VBI_CAPTURE) { + /* this is for capturing 36 raw vbi lines + if there's a way to cut off the beginning 2 vbi lines + with the tvp5150 then the vbi line count could be lowered + to 17 lines/field again, although I couldn't find a register + which could do that cropping */ + if (fmt->fmt.vbi.sample_format == V4L2_PIX_FMT_GREY) + tvp5150_write(c, TVP5150_LUMA_PROC_CTL_1, 0x70); + if (fmt->fmt.vbi.count[0] == 18 && fmt->fmt.vbi.count[1] == 18) { + tvp5150_write(c, TVP5150_VERT_BLANKING_START, 0x00); + tvp5150_write(c, TVP5150_VERT_BLANKING_STOP, 0x01); + } + break; + } if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) return -EINVAL; svbi = &fmt->fmt.sliced; -- cgit v1.2.3 From 5ae93fa2a3fc12c8d5e4c3f22917f4185b3feadd Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 23 Oct 2008 00:07:42 +0000 Subject: adding sharp s921 ISDB-T driver From: Markus Rechberger s921_module.c: wrapper for the dvb frontend interface s921_core.c: core s921 1seg ISDB-T driver, everything is set to auto as much as possible in order to not require certain parameters which currently cannot be passed to the ISDB-T chip. ISDB-T support can be tested using dvbscan, dvbstream/snoop and mplayer Tested 1seg H264/aac stream with this driver using a custom linux ISDB-T player Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/empia/sharp/Makefile | 3 + linux/drivers/media/video/empia/sharp/s921_core.c | 586 +++++++++++++++++++++ linux/drivers/media/video/empia/sharp/s921_core.h | 114 ++++ .../drivers/media/video/empia/sharp/s921_module.c | 254 +++++++++ .../drivers/media/video/empia/sharp/s921_module.h | 49 ++ 5 files changed, 1006 insertions(+) create mode 100644 linux/drivers/media/video/empia/sharp/Makefile create mode 100644 linux/drivers/media/video/empia/sharp/s921_core.c create mode 100644 linux/drivers/media/video/empia/sharp/s921_core.h create mode 100644 linux/drivers/media/video/empia/sharp/s921_module.c create mode 100644 linux/drivers/media/video/empia/sharp/s921_module.h diff --git a/linux/drivers/media/video/empia/sharp/Makefile b/linux/drivers/media/video/empia/sharp/Makefile new file mode 100644 index 000000000..510561130 --- /dev/null +++ b/linux/drivers/media/video/empia/sharp/Makefile @@ -0,0 +1,3 @@ +s921-objs := s921_module.o s921_core.o + +obj-m += s921.o diff --git a/linux/drivers/media/video/empia/sharp/s921_core.c b/linux/drivers/media/video/empia/sharp/s921_core.c new file mode 100644 index 000000000..1a7271700 --- /dev/null +++ b/linux/drivers/media/video/empia/sharp/s921_core.c @@ -0,0 +1,586 @@ +/* + * Driver for Sharp s921 driver + * + * Copyright (C) 2008 Markus Rechberger + * + */ + + +#include +#include +#include "s921_core.h" + +static int s921_isdb_init(struct s921_isdb_t *dev); +static int s921_isdb_set_parameters(struct s921_isdb_t *dev, struct s921_isdb_t_transmission_mode_params *params); +static int s921_isdb_tune(struct s921_isdb_t *dev, struct s921_isdb_t_tune_params *params); +static int s921_isdb_get_status(struct s921_isdb_t *dev, void *data); + +static u8 init_table[]={ 0x01, 0x40, 0x02, 0x00, 0x03, 0x40, 0x04, 0x01, + 0x05, 0x00, 0x06, 0x00, 0x07, 0x00, 0x08, 0x00, + 0x09, 0x00, 0x0a, 0x00, 0x0b, 0x5a, 0x0c, 0x00, + 0x0d, 0x00, 0x0f, 0x00, 0x13, 0x1b, 0x14, 0x80, + 0x15, 0x40, 0x17, 0x70, 0x18, 0x01, 0x19, 0x12, + 0x1a, 0x01, 0x1b, 0x12, 0x1c, 0xa0, 0x1d, 0x00, + 0x1e, 0x0a, 0x1f, 0x08, 0x20, 0x40, 0x21, 0xff, + 0x22, 0x4c, 0x23, 0x4e, 0x24, 0x4c, 0x25, 0x00, + 0x26, 0x00, 0x27, 0xf4, 0x28, 0x60, 0x29, 0x88, + 0x2a, 0x40, 0x2b, 0x40, 0x2c, 0xff, 0x2d, 0x00, + 0x2e, 0xff, 0x2f, 0x00, 0x30, 0x20, 0x31, 0x06, + 0x32, 0x0c, 0x34, 0x0f, 0x37, 0xfe, 0x38, 0x00, + 0x39, 0x63, 0x3a, 0x10, 0x3b, 0x10, 0x47, 0x00, + 0x49, 0xe5, 0x4b, 0x00, 0x50, 0xc0, 0x52, 0x20, + 0x54, 0x5a, 0x55, 0x5b, 0x56, 0x40, 0x57, 0x70, + 0x5c, 0x50, 0x5d, 0x00, 0x62, 0x17, 0x63, 0x2f, + 0x64, 0x6f, 0x68, 0x00, 0x69, 0x89, 0x6a, 0x00, + 0x6b, 0x00, 0x6c, 0x00, 0x6d, 0x00, 0x6e, 0x00, + 0x70, 0x00, 0x71, 0x00, 0x75, 0x00, 0x76, 0x30, + 0x77, 0x01, 0xaf, 0x00, 0xb0, 0xa0, 0xb2, 0x3d, + 0xb3, 0x25, 0xb4, 0x8b, 0xb5, 0x4b, 0xb6, 0x3f, + 0xb7, 0xff, 0xb8, 0xff, 0xb9, 0xfc, 0xba, 0x00, + 0xbb, 0x00, 0xbc, 0x00, 0xd0, 0x30, 0xe4, 0x84, + 0xf0, 0x48, 0xf1, 0x19, 0xf2, 0x5a, 0xf3, 0x8e, + 0xf4, 0x2d, 0xf5, 0x07, 0xf6, 0x5a, 0xf7, 0xba, + 0xf8, 0xd7 }; + +static u8 c_table[]={ 0x58, 0x8a, 0x7b, 0x59, 0x8c, 0x7b, 0x5a, 0x8e, 0x5b, + 0x5b, 0x90, 0x5b, 0x5c, 0x92, 0x5b, 0x5d, 0x94, 0x5b, + 0x5e, 0x96, 0x5b, 0x5f, 0x98, 0x3b, 0x60, 0x9a, 0x3b, + 0x61, 0x9c, 0x3b, 0x62, 0x9e, 0x3b, 0x63, 0xa0, 0x3b, + 0x64, 0xa2, 0x1b, 0x65, 0xa4, 0x1b, 0x66, 0xa6, 0x1b, + 0x67, 0xa8, 0x1b, 0x68, 0xaa, 0x1b, 0x69, 0xac, 0x1b, + 0x6a, 0xae, 0x1b, 0x6b, 0xb0, 0x1b, 0x6c, 0xb2, 0x1b, + 0x6d, 0xb4, 0xfb, 0x6e, 0xb6, 0xfb, 0x6f, 0xb8, 0xfb, + 0x70, 0xba, 0xfb, 0x71, 0xbc, 0xdb, 0x72, 0xbe, 0xdb, + 0x73, 0xc0, 0xdb, 0x74, 0xc2, 0xdb, 0x75, 0xc4, 0xdb, + 0x76, 0xc6, 0xdb, 0x77, 0xc8, 0xbb, 0x78, 0xca, 0xbb, + 0x79, 0xcc, 0xbb, 0x7a, 0xce, 0xbb, 0x7b, 0xd0, 0xbb, + 0x7c, 0xd2, 0xbb, 0x7d, 0xd4, 0xbb, 0x7e, 0xd6, 0xbb, + 0x7f, 0xd8, 0xbb, 0x80, 0xda, 0x9b, 0x81, 0xdc, 0x9b, + 0x82, 0xde, 0x9b, 0x83, 0xe0, 0x9b, 0x84, 0xe2, 0x9b, + 0x85, 0xe4, 0x9b, 0x86, 0xe6, 0x9b, 0x87, 0xe8, 0x9b, + 0x88, 0xea, 0x9b, 0x89, 0xec, 0x9b }; + +int s921_isdb_cmd(struct s921_isdb_t *dev, u32 cmd, void *data) { + switch(cmd) { + case ISDB_T_CMD_INIT: + s921_isdb_init(dev); + break; + case ISDB_T_CMD_SET_PARAM: + s921_isdb_set_parameters(dev, data); + break; + case ISDB_T_CMD_TUNE: + s921_isdb_tune(dev, data); + break; + case ISDB_T_CMD_GET_STATUS: + s921_isdb_get_status(dev, data); + break; + default: + printk("unhandled command\n"); + return -EINVAL; + } + return 0; +} + +static int s921_isdb_init(struct s921_isdb_t *dev) { + unsigned int i; + unsigned int ret; + printk("isdb_init\n"); + for (i = 0; i < sizeof(init_table); i+=2) { + ret = dev->i2c_write(dev->priv_dev, init_table[i], init_table[i+1]); + if (ret != 0) { + printk("i2c write failed\n"); + return ret; + } + } + return 0; +} + +static int s921_isdb_set_parameters(struct s921_isdb_t *dev, struct s921_isdb_t_transmission_mode_params *params) { + + int ret; + /* auto is sufficient for now, lateron this should be reflected in an extra interface */ + +#if 0 + u8 mod_b2 = 0; + u8 mod_b3 = 0; + u8 mod_b4 = 0; + u8 mod_b5 = 0; + u8 mod_b6 = 0; + u8 mod_b7 = 0; + u8 mod_b8 = 0; + /* LAYER A Setup */ + + switch (params->layer_a_carrier_modulation) { + case ISDB_T_LA_CM_DQPSK: + mod_b3 |= 0<<5; + break; + case ISDB_T_LA_CM_QPSK: + mod_b3 |= 1<<5; + break; + case ISDB_T_LA_CM_16QAM: + mod_b3 |= 2<<5; + break; + case ISDB_T_LA_CM_64QAM: + mod_b3 |= 3<<5; + break; + case ISDB_T_LA_CM_NOLAYER: + mod_b3 |= 7<<5; + break; + default: + printk("invalid carrier modulation\n"); + return -EINVAL; + } + + switch(params->layer_a_code_rate) { + case ISDB_T_LA_CR_1_2: + mod_b3 |= 0<<2; + break; + case ISDB_T_LA_CR_2_3: + mod_b3 |= 1<<2; + break; + case ISDB_T_LA_CR_3_4: + mod_b3 |= 2<<2; + break; + case ISDB_T_LA_CR_5_6: + mod_b3 |= 3<<2; + break; + case ISDB_T_LA_CR_7_8: + mod_b3 |= 4<<2; + break; + default: + printk("invalid coderate\n"); + return -EINVAL; + } + + switch (params->layer_a_mode) { + case ISDB_T_LA_MODE_1: + switch(params->layer_a_time_interleave) { + case ISDB_T_LA_TI_0: + mod_b3 |= 0; + mod_b4 |= 0; + break; + case ISDB_T_LA_TI_4: + mod_b3 |= 1; + mod_b4 |= 0; + break; + case ISDB_T_LA_TI_8: + mod_b3 |= 2; + mod_b4 |= 0; + break; + case ISDB_T_LA_TI_16: + mod_b3 |= 3; + mod_b4 |= 0; + break; + case ISDB_T_LA_TI_32: + mod_b3 |= 0; + mod_b4 |= 1<<7; + break; + default: + printk("invalid layer a time interleave\n"); + return -EINVAL; + } + break; + case ISDB_T_LA_MODE_2: + switch(params->layer_a_time_interleave) { + case ISDB_T_LA_TI_0: + mod_b3 |= 0; + mod_b4 |= 0; + break; + case ISDB_T_LA_TI_2: + mod_b3 |= 1; + mod_b4 |= 0; + break; + case ISDB_T_LA_TI_4: + mod_b3 |= 2; + mod_b4 |= 0; + break; + case ISDB_T_LA_TI_8: + mod_b3 |= 3; + mod_b4 |= 0; + break; + case ISDB_T_LA_TI_16: + mod_b3 |= 0; + mod_b4 |= 1<<7; + break; + default: + + printk("invalid layer a time interleave\n"); + return -EINVAL; + } + break; + case ISDB_T_LA_MODE_3: + switch(params->layer_a_time_interleave) { + case ISDB_T_LA_TI_0: + mod_b3 |= 0; + mod_b4 |= 0; + break; + case ISDB_T_LA_TI_1: + mod_b3 |= 1; + mod_b4 |= 0; + break; + case ISDB_T_LA_TI_2: + mod_b3 |= 2; + mod_b4 |= 0; + break; + case ISDB_T_LA_TI_4: + mod_b3 |= 3; + mod_b4 |= 0; + break; + case ISDB_T_LA_TI_8: + mod_b3 |= 0; + mod_b4 |= 1<<7; + break; + default: + printk("invalid layer a time interleave\n"); + return -EINVAL; + } + break; + default: + printk("invalid layer mode\n"); + return -EINVAL; + } + + + /* LAYER B Setup */ + switch (params->layer_b_carrier_modulation) { + case ISDB_T_LB_CM_DQPSK: + mod_b4 |= 0; + break; + case ISDB_T_LB_CM_QPSK: + mod_b4 |= 1; + break; + case ISDB_T_LB_CM_16QAM: + mod_b4 |= 2; + break; + case ISDB_T_LB_CM_64QAM: + mod_b4 |= 3; + break; + case ISDB_T_LB_CM_NOLAYER: + mod_b4 |= 7; + break; + default: + return -EINVAL; + } + + switch(params->layer_b_code_rate) { + case ISDB_T_LB_CR_1_2: + mod_b5 |= 0<<5; + break; + case ISDB_T_LB_CR_2_3: + mod_b5 |= 1<<5; + break; + case ISDB_T_LB_CR_3_4: + mod_b5 |= 2<<5; + break; + case ISDB_T_LB_CR_5_6: + mod_b5 |= 3<<5; + break; + case ISDB_T_LB_CR_7_8: + mod_b5 |= 4<<5; + break; + case ISDB_T_LB_CR_NOLAYER: + mod_b5 |= 7<<5; + break; + default: + return -EINVAL; + } + + switch (params->layer_b_mode) { + case ISDB_T_LB_MODE_1: + switch(params->layer_b_time_interleave) { + case ISDB_T_LB_TI_0: + mod_b5 |= 0; + break; + case ISDB_T_LB_TI_4: + mod_b5 |= 1<<2; + break; + case ISDB_T_LB_TI_8: + mod_b5 |= 2<<2; + break; + case ISDB_T_LB_TI_16: + mod_b5 |= 3<<2; + break; + case ISDB_T_LB_TI_32: + mod_b5 |= 4<<2; + break; + default: + return -EINVAL; + } + break; + case ISDB_T_LB_MODE_2: + switch(params->layer_b_time_interleave) { + case ISDB_T_LB_TI_0: + mod_b5 |= 0; + break; + case ISDB_T_LB_TI_2: + mod_b5 |= 1<<2; + break; + case ISDB_T_LB_TI_4: + mod_b5 |= 2<<2; + break; + case ISDB_T_LB_TI_8: + mod_b5 |= 3<<2; + break; + case ISDB_T_LB_TI_16: + mod_b5 |= 4<<2; + break; + default: + return -EINVAL; + } + break; + case ISDB_T_LB_MODE_3: + switch(params->layer_b_time_interleave) { + case ISDB_T_LB_TI_0: + mod_b5 |= 0; + break; + case ISDB_T_LB_TI_1: + mod_b5 |= 1<<2; + break; + case ISDB_T_LB_TI_2: + mod_b5 |= 2<<2; + break; + case ISDB_T_LB_TI_4: + mod_b5 |= 3<<2; + break; + case ISDB_T_LB_TI_8: + mod_b5 |= 4<<2; + break; + default: + return -EINVAL; + } + break; + default: + return -EINVAL; + } + + /* LAYER C Setup */ + switch (params->layer_c_carrier_modulation) { + case ISDB_T_LC_CM_DQPSK: + mod_b5 |= 0<<3; + break; + case ISDB_T_LC_CM_QPSK: + mod_b5 |= 1<<3; + break; + case ISDB_T_LC_CM_16QAM: + mod_b5 |= 2<<3; + break; + case ISDB_T_LC_CM_64QAM: + mod_b5 |= 3<<3; + break; + case ISDB_T_LC_CM_NOLAYER: + mod_b5 |= 7<<3; + break; + default: + return -EINVAL; + } + + switch(params->layer_c_code_rate) { + case ISDB_T_LC_CR_1_2: + mod_b5 |= 0<<0; + break; + case ISDB_T_LC_CR_2_3: + mod_b5 |= 1<<0; + break; + case ISDB_T_LC_CR_3_4: + mod_b5 |= 2<<0; + break; + case ISDB_T_LC_CR_5_6: + mod_b5 |= 3<<0; + break; + case ISDB_T_LC_CR_7_8: + mod_b5 |= 4<<0; + break; + default: + return -EINVAL; + } + + switch (params->layer_c_mode) { + case ISDB_T_LC_MODE_1: + switch(params->layer_c_time_interleave) { + case ISDB_T_LC_TI_0: + mod_b7 |= 0<<5; + break; + case ISDB_T_LC_TI_4: + mod_b7 |= 1<<5; + break; + case ISDB_T_LC_TI_8: + mod_b7 |= 2<<5; + break; + case ISDB_T_LC_TI_16: + mod_b7 |= 3<<5; + break; + case ISDB_T_LC_TI_32: + mod_b7 |= 4<<5; + break; + default: + return -EINVAL; + } + break; + case ISDB_T_LC_MODE_2: + switch(params->layer_c_time_interleave) { + case ISDB_T_LC_TI_0: + mod_b7 |= 0<<5; + break; + case ISDB_T_LC_TI_2: + mod_b7 |= 1<<5; + break; + case ISDB_T_LC_TI_4: + mod_b7 |= 2<<5; + break; + case ISDB_T_LC_TI_8: + mod_b7 |= 3<<5; + break; + case ISDB_T_LC_TI_16: + mod_b7 |= 4<<5; + break; + default: + return -EINVAL; + } + break; + case ISDB_T_LC_MODE_3: + switch(params->layer_c_time_interleave) { + case ISDB_T_LC_TI_0: + mod_b7 |= 0<<5; + break; + case ISDB_T_LC_TI_1: + mod_b7 |= 1<<5; + break; + case ISDB_T_LC_TI_2: + mod_b7 |= 2<<5; + break; + case ISDB_T_LC_TI_4: + mod_b7 |= 3<<5; + break; + case ISDB_T_LC_TI_8: + mod_b7 |= 4<<5; + break; + default: + return -EINVAL; + } + break; + default: + return -EINVAL; + } +#endif + + + ret = dev->i2c_write(dev->priv_dev, 0xb0, 0xa0); //mod_b2); + ret = dev->i2c_write(dev->priv_dev, 0xb2, 0x3d); //mod_b2); + + if (ret < 0) + return -EINVAL; + + ret = dev->i2c_write(dev->priv_dev, 0xb3, 0x25); //mod_b3); + if (ret < 0) + return -EINVAL; + + ret = dev->i2c_write(dev->priv_dev, 0xb4, 0x8b); //mod_b4); + if (ret < 0) + return -EINVAL; + + ret = dev->i2c_write(dev->priv_dev, 0xb5, 0x4b); //mod_b5); + if (ret < 0) + return -EINVAL; + + ret = dev->i2c_write(dev->priv_dev, 0xb6, 0x3f); //mod_b6); + if (ret < 0) + return -EINVAL; + + ret = dev->i2c_write(dev->priv_dev, 0xb7, 0x3f); //mod_b7); + if (ret < 0) + return -EINVAL; + + return E_OK; +} + +static int s921_isdb_tune(struct s921_isdb_t *dev, struct s921_isdb_t_tune_params *params) { + + int ret; + int index; + + index = (params->frequency - 473143000)/6000000; + + if (index > 48) { + return -EINVAL; + } + + dev->i2c_write(dev->priv_dev, 0x47, 0x60); + + ret = dev->i2c_write(dev->priv_dev, 0x68, 0x00); + if (ret < 0) + return -EINVAL; + + ret = dev->i2c_write(dev->priv_dev, 0x69, 0x89); + if (ret < 0) + return -EINVAL; + + ret = dev->i2c_write(dev->priv_dev, 0xf0, 0x48); + if (ret < 0) + return -EINVAL; + + ret = dev->i2c_write(dev->priv_dev, 0xf1, 0x19); + if (ret < 0) + return -EINVAL; + + ret = dev->i2c_write(dev->priv_dev, 0xf2, c_table[index*3]); + if (ret < 0) + return -EINVAL; + + ret = dev->i2c_write(dev->priv_dev, 0xf3, c_table[index*3+1]); + if (ret < 0) + return -EINVAL; + + ret = dev->i2c_write(dev->priv_dev, 0xf4, c_table[index*3+2]); + if (ret < 0) + return -EINVAL; + + ret = dev->i2c_write(dev->priv_dev, 0xf5, 0xae); + if (ret < 0) + return -EINVAL; + + ret = dev->i2c_write(dev->priv_dev, 0xf6, 0xb7); + if (ret < 0) + return -EINVAL; + + ret = dev->i2c_write(dev->priv_dev, 0xf7, 0xba); + if (ret < 0) + return -EINVAL; + + ret = dev->i2c_write(dev->priv_dev, 0xf8, 0xd7); + if (ret < 0) + return -EINVAL; + + ret = dev->i2c_write(dev->priv_dev, 0x68, 0x0a); + if (ret < 0) + return -EINVAL; + + ret = dev->i2c_write(dev->priv_dev, 0x69, 0x09); + if (ret < 0) + return -EINVAL; + + dev->i2c_write(dev->priv_dev, 0x01, 0x40); + return 0; +} + +static int s921_isdb_get_status(struct s921_isdb_t *dev, void *data) { + unsigned int *ret = (unsigned int*)data; + u8 ifagc_dt; + u8 rfagc_dt; + + mdelay(10); + ifagc_dt = dev->i2c_read(dev->priv_dev, 0x81); + rfagc_dt = dev->i2c_read(dev->priv_dev, 0x82); +#if 0 + *ret = dev->i2c_read(dev->priv_dev, 0x82); + printk("status 83: %02x\n", *ret); + *ret = dev->i2c_read(dev->priv_dev, 0x80); + mdelay(10); + *ret = dev->i2c_read(dev->priv_dev, 0x80); + mdelay(10); + *ret = dev->i2c_read(dev->priv_dev, 0x80); +#endif + if (rfagc_dt == 0x40) { + *ret = 1; + } + return 0; +} diff --git a/linux/drivers/media/video/empia/sharp/s921_core.h b/linux/drivers/media/video/empia/sharp/s921_core.h new file mode 100644 index 000000000..ae39a2a52 --- /dev/null +++ b/linux/drivers/media/video/empia/sharp/s921_core.h @@ -0,0 +1,114 @@ +#ifndef _S921_CORE_H +#define _S921_CORE_H +//#define u8 unsigned int +//#define u32 unsigned int + + + +//#define EINVAL -1 +#define E_OK 0 + +struct s921_isdb_t { + void *priv_dev; + int (*i2c_write)(void *dev, u8 reg, u8 val); + int (*i2c_read)(void *dev, u8 reg); +}; + +#define ISDB_T_CMD_INIT 0 +#define ISDB_T_CMD_SET_PARAM 1 +#define ISDB_T_CMD_TUNE 2 +#define ISDB_T_CMD_GET_STATUS 3 + +struct s921_isdb_t_tune_params { + u32 frequency; +}; + +struct s921_isdb_t_status { +}; + +struct s921_isdb_t_transmission_mode_params { + u8 mode; + u8 layer_a_mode; +#define ISDB_T_LA_MODE_1 0 +#define ISDB_T_LA_MODE_2 1 +#define ISDB_T_LA_MODE_3 2 + u8 layer_a_carrier_modulation; +#define ISDB_T_LA_CM_DQPSK 0 +#define ISDB_T_LA_CM_QPSK 1 +#define ISDB_T_LA_CM_16QAM 2 +#define ISDB_T_LA_CM_64QAM 3 +#define ISDB_T_LA_CM_NOLAYER 4 + u8 layer_a_code_rate; +#define ISDB_T_LA_CR_1_2 0 +#define ISDB_T_LA_CR_2_3 1 +#define ISDB_T_LA_CR_3_4 2 +#define ISDB_T_LA_CR_5_6 4 +#define ISDB_T_LA_CR_7_8 8 +#define ISDB_T_LA_CR_NOLAYER 16 + u8 layer_a_time_interleave; +#define ISDB_T_LA_TI_0 0 +#define ISDB_T_LA_TI_1 1 +#define ISDB_T_LA_TI_2 2 +#define ISDB_T_LA_TI_4 4 +#define ISDB_T_LA_TI_8 8 +#define ISDB_T_LA_TI_16 16 +#define ISDB_T_LA_TI_32 32 + u8 layer_a_nseg; + + u8 layer_b_mode; +#define ISDB_T_LB_MODE_1 0 +#define ISDB_T_LB_MODE_2 1 +#define ISDB_T_LB_MODE_3 2 + u8 layer_b_carrier_modulation; +#define ISDB_T_LB_CM_DQPSK 0 +#define ISDB_T_LB_CM_QPSK 1 +#define ISDB_T_LB_CM_16QAM 2 +#define ISDB_T_LB_CM_64QAM 3 +#define ISDB_T_LB_CM_NOLAYER 4 + u8 layer_b_code_rate; +#define ISDB_T_LB_CR_1_2 0 +#define ISDB_T_LB_CR_2_3 1 +#define ISDB_T_LB_CR_3_4 2 +#define ISDB_T_LB_CR_5_6 4 +#define ISDB_T_LB_CR_7_8 8 +#define ISDB_T_LB_CR_NOLAYER 16 + u8 layer_b_time_interleave; +#define ISDB_T_LB_TI_0 0 +#define ISDB_T_LB_TI_1 1 +#define ISDB_T_LB_TI_2 2 +#define ISDB_T_LB_TI_4 4 +#define ISDB_T_LB_TI_8 8 +#define ISDB_T_LB_TI_16 16 +#define ISDB_T_LB_TI_32 32 + u8 layer_b_nseg; + + u8 layer_c_mode; +#define ISDB_T_LC_MODE_1 0 +#define ISDB_T_LC_MODE_2 1 +#define ISDB_T_LC_MODE_3 2 + u8 layer_c_carrier_modulation; +#define ISDB_T_LC_CM_DQPSK 0 +#define ISDB_T_LC_CM_QPSK 1 +#define ISDB_T_LC_CM_16QAM 2 +#define ISDB_T_LC_CM_64QAM 3 +#define ISDB_T_LC_CM_NOLAYER 4 + u8 layer_c_code_rate; +#define ISDB_T_LC_CR_1_2 0 +#define ISDB_T_LC_CR_2_3 1 +#define ISDB_T_LC_CR_3_4 2 +#define ISDB_T_LC_CR_5_6 4 +#define ISDB_T_LC_CR_7_8 8 +#define ISDB_T_LC_CR_NOLAYER 16 + u8 layer_c_time_interleave; +#define ISDB_T_LC_TI_0 0 +#define ISDB_T_LC_TI_1 1 +#define ISDB_T_LC_TI_2 2 +#define ISDB_T_LC_TI_4 4 +#define ISDB_T_LC_TI_8 8 +#define ISDB_T_LC_TI_16 16 +#define ISDB_T_LC_TI_32 32 + u8 layer_c_nseg; +}; + +int s921_isdb_cmd(struct s921_isdb_t *dev, u32 cmd, void *data); +#endif diff --git a/linux/drivers/media/video/empia/sharp/s921_module.c b/linux/drivers/media/video/empia/sharp/s921_module.c new file mode 100644 index 000000000..d78ebafe8 --- /dev/null +++ b/linux/drivers/media/video/empia/sharp/s921_module.c @@ -0,0 +1,254 @@ +/* + * Driver for Sharp s921 driver + * + * Copyright (C) 2008 Markus Rechberger + * + * All rights reserved. + * + */ + +#include +#include +#include +#include "dvb_frontend.h" +#include "s921_module.h" +#include "s921_core.h" + +static unsigned int debug = 0; +module_param(debug, int, 0644); +MODULE_PARM_DESC(debug,"s921 debugging (default off)"); + +#define dprintk(fmt, args...) if (debug) do {\ + printk("s921 debug: " fmt, ##args); } while (0) + +struct s921_state +{ + struct dvb_frontend frontend; + fe_modulation_t current_modulation; + __u32 snr; + __u32 current_frequency; + __u8 addr; + struct s921_isdb_t dev; + struct i2c_adapter *i2c; +}; + +static int s921_set_parameters(struct dvb_frontend *fe, struct dvb_frontend_parameters *param) { + struct s921_state *state = (struct s921_state *)fe->demodulator_priv; + struct s921_isdb_t_transmission_mode_params params; + struct s921_isdb_t_tune_params tune_params; + + tune_params.frequency = param->frequency; +#if 0 + struct dvb_ofdm_parameters *op = ¶m->u.ofdm; + + switch (op->bandwidth) { + case BANDWIDTH_6_MHZ: + case BANDWIDTH_7_MHZ: + case BANDWIDTH_8_MHZ: + default: + break; + } + + switch (op->code_rate_HP) { + case FEC_2_3: + case FEC_3_4: + case FEC_5_6: + case FEC_7_8: + case FEC_1_2: + case FEC_AUTO: + break; + default: + break; + } + + switch(op->code_rate_LP) { + case FEC_2_3: + case FEC_3_4: + case FEC_5_6: + case FEC_7_8: + case FEC_1_2: + case FEC_AUTO: + case FEC_NONE: + default: + break; + } + + switch (op->constellation) { + case QPSK: + case QAM_AUTO: + case QAM_16: + default: + break; + } + + switch (op->guard_interval) { + case GUARD_INTERVAL_1_32: + case GUARD_INTERVAL_AUTO: + case GUARD_INTERVAL_1_16: + case GUARD_INTERVAL_1_8: + case GUARD_INTERVAL_1_4: + default: + break; + } + + switch (op->hierarchy_information) { + case HIERARCHY_AUTO: + case HIERARCHY_NONE: + case HIERARCHY_1: + case HIERARCHY_2: + case HIERARCHY_4: + default: + break; + } + +#endif + s921_isdb_cmd(&state->dev, ISDB_T_CMD_SET_PARAM, ¶ms); + s921_isdb_cmd(&state->dev, ISDB_T_CMD_TUNE, &tune_params); + mdelay(100); + return 0; +} + +static int s921_init(struct dvb_frontend *fe) { + printk("s921 init\n"); + return 0; +} + +static int s921_sleep(struct dvb_frontend *fe) { + printk("s921 sleep\n"); + return 0; +} + +static int s921_read_status(struct dvb_frontend *fe, fe_status_t *status) +{ + struct s921_state *state = (struct s921_state *)fe->demodulator_priv; + unsigned int ret; + mdelay(5); + s921_isdb_cmd(&state->dev, ISDB_T_CMD_GET_STATUS, &ret); + *status = 0; + + printk("status: %02x\n", ret); + if (ret == 1) { + *status |= FE_HAS_CARRIER; + *status |= FE_HAS_VITERBI; + *status |= FE_HAS_LOCK; + *status |= FE_HAS_SYNC; + *status |= FE_HAS_SIGNAL; + } + + return 0; +} + +static int s921_read_ber(struct dvb_frontend *fe, __u32 *ber) +{ + dprintk("read ber\n"); + return 0; +} + +static int s921_read_snr(struct dvb_frontend *fe, __u16 *snr) +{ + dprintk("read snr\n"); + return 0; +} + +static int s921_read_ucblocks(struct dvb_frontend *fe, __u32 *ucblocks) +{ + dprintk("read ucblocks\n"); + return 0; +} + +static void s921_release(struct dvb_frontend *fe) +{ + struct s921_state *state = (struct s921_state *)fe->demodulator_priv; + kfree(state); +} + +static struct dvb_frontend_ops demod_s921={ + .info = { + .name = "SHARP S921", + .type = FE_OFDM, + .frequency_min = 473143000, + .frequency_max = 767143000, + .frequency_stepsize = 6000000, + .frequency_tolerance = 0, + .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | + FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | + FE_CAN_FEC_AUTO | + FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO | + FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO | + FE_CAN_HIERARCHY_AUTO | FE_CAN_RECOVER | + FE_CAN_MUTE_TS + }, + .init = s921_init, + .sleep = s921_sleep, + .set_frontend = s921_set_parameters, + .read_snr = s921_read_snr, + .read_ber = s921_read_ber, + .read_status = s921_read_status, + .read_ucblocks = s921_read_ucblocks, + .release = s921_release, +}; + +static int s921_write(void *dev, u8 reg, u8 val) { + struct s921_state *state = dev; + char buf[2]={reg,val}; + int err; + struct i2c_msg i2cmsgs = { + .addr = state->addr, + .flags = 0, + .len = 2, + .buf = buf + }; + + if((err = i2c_transfer(state->i2c, &i2cmsgs, 1))<0) { + printk("%s i2c_transfer error %d\n", __FUNCTION__, err); + if (err < 0) + return err; + else + return -EREMOTEIO; + } + + return 0; +} + +static int s921_read(void *dev, u8 reg) { + struct s921_state *state = dev; + u8 b1; + int ret; + struct i2c_msg msg[2] = { { .addr = state->addr, + .flags = 0, + .buf = ®, .len = 1 }, + { .addr = state->addr, + .flags = I2C_M_RD, + .buf = &b1, .len = 1 } }; + + ret = i2c_transfer(state->i2c, msg, 2); + if (ret != 2) + return ret; + return b1; +} + +struct dvb_frontend* s921_attach(const struct s921_config *config, + struct i2c_adapter *i2c) +{ + + struct s921_state *state; + state = kzalloc(sizeof(struct s921_state), GFP_KERNEL); + memset(state, 0x0, sizeof(struct s921_state)); + + state->addr = config->i2c_address; + state->i2c = i2c; + state->dev.i2c_write = &s921_write; + state->dev.i2c_read = &s921_read; + state->dev.priv_dev = state; + + s921_isdb_cmd(&state->dev, ISDB_T_CMD_INIT, NULL); + + memcpy(&state->frontend.ops, &demod_s921, sizeof(struct dvb_frontend_ops)); + state->frontend.demodulator_priv = state; + return &state->frontend; +} + +EXPORT_SYMBOL_GPL(s921_attach); +MODULE_AUTHOR("Markus Rechberger "); +MODULE_DESCRIPTION("Sharp S921 ISDB-T 1Seg"); +MODULE_LICENSE("GPL"); diff --git a/linux/drivers/media/video/empia/sharp/s921_module.h b/linux/drivers/media/video/empia/sharp/s921_module.h new file mode 100644 index 000000000..78660424b --- /dev/null +++ b/linux/drivers/media/video/empia/sharp/s921_module.h @@ -0,0 +1,49 @@ +/* + * Driver for DVB-T s921 demodulator + * + * Copyright (C) 2008 Markus Rechberger + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.= + */ + +#ifndef S921_MODULE_H +#define S921_MODULE_H + +#include +#include "s921_core.h" + +int s921_isdb_init(struct s921_isdb_t *dev); +int s921_isdb_cmd(struct s921_isdb_t *dev, u32 cmd, void *data); + +struct s921_config +{ + /* demodulator's I2C address */ + u8 i2c_address; +}; + +#if defined(CONFIG_DVB_S921) || (defined(CONFIG_DVB_S921_MODULE) && defined(MODULE)) +extern struct dvb_frontend* s921_attach(const struct s921_config *config, + struct i2c_adapter *i2c); +#else +static inline struct dvb_frontend* s921_attach(const struct s921_config *config, + struct i2c_adapter *i2c) +{ + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); + return NULL; +} +#endif /* CONFIG_DVB_S921 */ + +#endif /* S921_H */ -- cgit v1.2.3 From c61629aabee98f55e9f6fd2d2e8e65758ab4fcec Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 23 Oct 2008 00:08:47 +0000 Subject: adding lgdt3304 based driver From: Markus Rechberger lgdt3304.c: frontend driver for the lgdt3304 chip, this driver is not compatible with the lgdt330x. Signed-off-by: Markus Rechberger Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/empia/lgdt3304/Makefile | 7 + .../drivers/media/video/empia/lgdt3304/lgdt3304.c | 398 +++++++++++++++++++++ .../drivers/media/video/empia/lgdt3304/lgdt3304.h | 45 +++ 3 files changed, 450 insertions(+) create mode 100644 linux/drivers/media/video/empia/lgdt3304/Makefile create mode 100644 linux/drivers/media/video/empia/lgdt3304/lgdt3304.c create mode 100644 linux/drivers/media/video/empia/lgdt3304/lgdt3304.h diff --git a/linux/drivers/media/video/empia/lgdt3304/Makefile b/linux/drivers/media/video/empia/lgdt3304/Makefile new file mode 100644 index 000000000..4d261a762 --- /dev/null +++ b/linux/drivers/media/video/empia/lgdt3304/Makefile @@ -0,0 +1,7 @@ +lgdt3304-demod-objs := lgdt3304.o + +obj-m += lgdt3304-demod.o + +EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core +EXTRA_CFLAGS += -Idrivers/media/dvb/frontends +EXTRA_CFLAGS += -DCONFIG_DVB_LGDT3304 diff --git a/linux/drivers/media/video/empia/lgdt3304/lgdt3304.c b/linux/drivers/media/video/empia/lgdt3304/lgdt3304.c new file mode 100644 index 000000000..1e8867b15 --- /dev/null +++ b/linux/drivers/media/video/empia/lgdt3304/lgdt3304.c @@ -0,0 +1,398 @@ +/* + * Driver for LG ATSC lgdt3304 driver + * + * Copyright (C) 2008 Markus Rechberger + * + */ + +#include +#include +#include +#include "dvb_frontend.h" +#include "lgdt3304.h" + +static unsigned int debug = 0; +module_param(debug, int, 0644); +MODULE_PARM_DESC(debug,"lgdt3304 debugging (default off)"); + +#define dprintk(fmt, args...) if (debug) do {\ + printk("lgdt3304 debug: " fmt, ##args); } while (0) + +struct lgdt3304_state +{ + struct dvb_frontend frontend; + fe_modulation_t current_modulation; + __u32 snr; + __u32 current_frequency; + __u8 addr; + struct i2c_adapter *i2c; +}; + +static int i2c_write_demod_bytes (struct dvb_frontend *fe, __u8 *buf, int len) +{ + struct lgdt3304_state *state = fe->demodulator_priv; + struct i2c_msg i2cmsgs = { + .addr = state->addr, + .flags = 0, + .len = 3, + .buf = buf + }; + int i; + int err; + + for (i=0; ii2c, &i2cmsgs, 1))<0) { + printk("%s i2c_transfer error %d\n", __FUNCTION__, err); + if (err < 0) + return err; + else + return -EREMOTEIO; + } + i2cmsgs.buf += 3; + } + return 0; +} + +static int lgdt3304_i2c_read_reg(struct dvb_frontend *fe, unsigned int reg) +{ + struct lgdt3304_state *state = fe->demodulator_priv; + struct i2c_msg i2cmsgs[2]; + int ret; + __u8 buf; + + __u8 regbuf[2] = { reg>>8, reg&0xff }; + + i2cmsgs[0].addr = state->addr; + i2cmsgs[0].flags = 0; + i2cmsgs[0].len = 2; + i2cmsgs[0].buf = regbuf; + + i2cmsgs[1].addr = state->addr; + i2cmsgs[1].flags = I2C_M_RD; + i2cmsgs[1].len = 1; + i2cmsgs[1].buf = &buf; + + if((ret = i2c_transfer(state->i2c, i2cmsgs, 2))<0) { + printk("%s i2c_transfer error %d\n", __FUNCTION__, ret); + return ret; + } + + return buf; +} + +static int lgdt3304_i2c_write_reg(struct dvb_frontend *fe, int reg, int val) +{ + struct lgdt3304_state *state = fe->demodulator_priv; + char buffer[3] = { reg>>8, reg&0xff, val }; + int ret; + + struct i2c_msg i2cmsgs = { + .addr = state->addr, + .flags = 0, + .len = 3, + .buf=buffer + }; + ret = i2c_transfer(state->i2c, &i2cmsgs, 1); + if (ret != 1) { + printk("%s i2c_transfer error %d\n", __FUNCTION__, ret); + return ret; + } + + return 0; +} + + +static int lgdt3304_soft_Reset(struct dvb_frontend *fe) +{ + lgdt3304_i2c_write_reg(fe, 0x0002, 0x9a); + lgdt3304_i2c_write_reg(fe, 0x0002, 0x9b); + mdelay(200); + return 0; +} + +static int lgdt3304_set_parameters(struct dvb_frontend *fe, struct dvb_frontend_parameters *param) { + int err = 0; + + static __u8 lgdt3304_vsb8_data[] = { + /* 16bit , 8bit */ + /* regs , val */ + 0x00, 0x00, 0x02, + 0x00, 0x00, 0x13, + 0x00, 0x0d, 0x02, + 0x00, 0x0e, 0x02, + 0x00, 0x12, 0x32, + 0x00, 0x13, 0xc4, + 0x01, 0x12, 0x17, + 0x01, 0x13, 0x15, + 0x01, 0x14, 0x18, + 0x01, 0x15, 0xff, + 0x01, 0x16, 0x2c, + 0x02, 0x14, 0x67, + 0x02, 0x24, 0x8d, + 0x04, 0x27, 0x12, + 0x04, 0x28, 0x4f, + 0x03, 0x08, 0x80, + 0x03, 0x09, 0x00, + 0x03, 0x0d, 0x00, + 0x03, 0x0e, 0x1c, + 0x03, 0x14, 0xe1, + 0x05, 0x0e, 0x5b, + }; + + /* not yet tested .. */ + static __u8 lgdt3304_qam64_data[] = { + /* 16bit , 8bit */ + /* regs , val */ + 0x00, 0x00, 0x18, + 0x00, 0x0d, 0x02, + //0x00, 0x0e, 0x02, + 0x00, 0x12, 0x2a, + 0x00, 0x13, 0x00, + 0x03, 0x14, 0xe3, + 0x03, 0x0e, 0x1c, + 0x03, 0x08, 0x66, + 0x03, 0x09, 0x66, + 0x03, 0x0a, 0x08, + 0x03, 0x0b, 0x9b, + 0x05, 0x0e, 0x5b, + }; + +#if 0 + /* not yet tested */ + static __u8 lgdt3304_qam256_data[] = { + /* 16bit , 8bit */ + /* regs , val */ + 0x00, 0x00, 0x19, + 0x00, 0x12, 0x2a, + 0x00, 0x13, 0x80, + 0x00, 0x0d, 0x02, + 0x03, 0x14, 0xe3, + + 0x03, 0x0e, 0x1c, + 0x03, 0x08, 0x66, + 0x03, 0x09, 0x66, + 0x03, 0x0a, 0x08, + 0x03, 0x0b, 0x9b, + 0x03, 0x0d, 0x14, + 0x05, 0x0e, 0x5b, + }; +#endif + + /* tested with KWorld a340 */ + static __u8 lgdt3304_qam256_data[] = { + /* 16bit , 8bit */ + /* regs , val */ + 0x00, 0x00, 0x01, //0x19, + 0x00, 0x12, 0x2a, + 0x00, 0x13, 0x80, + 0x00, 0x0d, 0x02, + 0x03, 0x14, 0xe3, + + 0x03, 0x0e, 0x1c, + 0x03, 0x08, 0x66, + 0x03, 0x09, 0x66, + 0x03, 0x0a, 0x08, + 0x03, 0x0b, 0x9b, + + 0x03, 0x0d, 0x14, + //0x05, 0x0e, 0x5b, + 0x01, 0x06, 0x4a, + 0x01, 0x07, 0x3d, + 0x01, 0x08, 0x70, + 0x01, 0x09, 0xa3, + + 0x05, 0x04, 0xfd, + + 0x00, 0x0d, 0x82, + + 0x05, 0x0e, 0x5b, + + 0x05, 0x0e, 0x5b, + + 0x00, 0x02, 0x9a, + + 0x00, 0x02, 0x9b, + + 0x00, 0x00, 0x01, + 0x00, 0x12, 0x2a, + 0x00, 0x13, 0x80, + 0x00, 0x0d, 0x02, + 0x03, 0x14, 0xe3, + + 0x03, 0x0e, 0x1c, + 0x03, 0x08, 0x66, + 0x03, 0x09, 0x66, + 0x03, 0x0a, 0x08, + 0x03, 0x0b, 0x9b, + + 0x03, 0x0d, 0x14, + 0x01, 0x06, 0x4a, + 0x01, 0x07, 0x3d, + 0x01, 0x08, 0x70, + 0x01, 0x09, 0xa3, + + 0x05, 0x04, 0xfd, + + 0x00, 0x0d, 0x82, + + 0x05, 0x0e, 0x5b, + }; + + struct lgdt3304_state *state = fe->demodulator_priv; + if (state->current_modulation != param->u.vsb.modulation) { + switch(param->u.vsb.modulation) { + case VSB_8: + err = i2c_write_demod_bytes(fe, lgdt3304_vsb8_data, + sizeof(lgdt3304_vsb8_data)); + break; + case QAM_64: + err = i2c_write_demod_bytes(fe, lgdt3304_qam64_data, + sizeof(lgdt3304_qam64_data)); + break; + case QAM_256: + err = i2c_write_demod_bytes(fe, lgdt3304_qam256_data, + sizeof(lgdt3304_qam256_data)); + break; + default: + break; + } + + if (err) { + printk("%s error setting modulation\n", __FUNCTION__); + } else { + state->current_modulation = param->u.vsb.modulation; + } + } + state->current_frequency = param->frequency; + + lgdt3304_soft_Reset(fe); + + + if (fe->ops.tuner_ops.set_params) + fe->ops.tuner_ops.set_params(fe, param); + + return 0; +} + +static int lgdt3304_init(struct dvb_frontend *fe) { + return 0; +} + +static int lgdt3304_sleep(struct dvb_frontend *fe) { + return 0; +} + + +static int lgdt3304_read_status(struct dvb_frontend *fe, fe_status_t *status) +{ + struct lgdt3304_state *state = fe->demodulator_priv; + int r011d; + int qam_lck; + + *status = 0; + dprintk("lgdt read status\n"); + + r011d = lgdt3304_i2c_read_reg(fe, 0x011d); + + dprintk("%02x\n", r011d); + + switch(state->current_modulation) { + case VSB_8: + if (r011d & 0x80) { + dprintk("VSB Locked\n"); + *status |= FE_HAS_CARRIER; + *status |= FE_HAS_LOCK; + *status |= FE_HAS_SYNC; + *status |= FE_HAS_SIGNAL; + } + break; + case QAM_64: + case QAM_256: + qam_lck = r011d & 0x7; + switch(qam_lck) { + case 0x0: dprintk("Unlock\n"); + break; + case 0x4: dprintk("1st Lock in acquisition state\n"); + break; + case 0x6: dprintk("2nd Lock in acquisition state\n"); + break; + case 0x7: dprintk("Final Lock in good reception state\n"); + *status |= FE_HAS_CARRIER; + *status |= FE_HAS_LOCK; + *status |= FE_HAS_SYNC; + *status |= FE_HAS_SIGNAL; + break; + } + break; + default: + printk("%s unhandled modulation\n", __FUNCTION__); + } + + + return 0; +} + +static int lgdt3304_read_ber(struct dvb_frontend *fe, __u32 *ber) +{ + dprintk("read ber\n"); + return 0; +} + +static int lgdt3304_read_snr(struct dvb_frontend *fe, __u16 *snr) +{ + dprintk("read snr\n"); + return 0; +} + +static int lgdt3304_read_ucblocks(struct dvb_frontend *fe, __u32 *ucblocks) +{ + dprintk("read ucblocks\n"); + return 0; +} + +static void lgdt3304_release(struct dvb_frontend *fe) +{ + struct lgdt3304_state *state = (struct lgdt3304_state *)fe->demodulator_priv; + kfree(state); +} + +static struct dvb_frontend_ops demod_lgdt3304={ + .info = { + .name = "LG 3304", + .type = FE_ATSC, + .frequency_min = 54000000, + .frequency_max = 858000000, + .frequency_stepsize = 62500, + .symbol_rate_min = 5056941, + .symbol_rate_max = 10762000, + .caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB + }, + .init = lgdt3304_init, + .sleep = lgdt3304_sleep, + .set_frontend = lgdt3304_set_parameters, + .read_snr = lgdt3304_read_snr, + .read_ber = lgdt3304_read_ber, + .read_status = lgdt3304_read_status, + .read_ucblocks = lgdt3304_read_ucblocks, + .release = lgdt3304_release, +}; + +struct dvb_frontend* lgdt3304_attach(const struct lgdt3304_config *config, + struct i2c_adapter *i2c) +{ + + struct lgdt3304_state *state; + state = kzalloc(sizeof(struct lgdt3304_state), GFP_KERNEL); + memset(state, 0x0, sizeof(struct lgdt3304_state)); + state->addr = config->i2c_address; + state->i2c = i2c; + + memcpy(&state->frontend.ops, &demod_lgdt3304, sizeof(struct dvb_frontend_ops)); + state->frontend.demodulator_priv = state; + return &state->frontend; +} + +EXPORT_SYMBOL_GPL(lgdt3304_attach); +MODULE_AUTHOR("Markus Rechberger "); +MODULE_DESCRIPTION("LGE LGDT3304 DVB-T demodulator driver"); +MODULE_LICENSE("GPL"); diff --git a/linux/drivers/media/video/empia/lgdt3304/lgdt3304.h b/linux/drivers/media/video/empia/lgdt3304/lgdt3304.h new file mode 100644 index 000000000..fc409fe59 --- /dev/null +++ b/linux/drivers/media/video/empia/lgdt3304/lgdt3304.h @@ -0,0 +1,45 @@ +/* + * Driver for DVB-T lgdt3304 demodulator + * + * Copyright (C) 2008 Markus Rechberger + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.= + */ + +#ifndef LGDT3304_H +#define LGDT3304_H + +#include + +struct lgdt3304_config +{ + /* demodulator's I2C address */ + u8 i2c_address; +}; + +#if defined(CONFIG_DVB_LGDT3304) || (defined(CONFIG_DVB_LGDT3304_MODULE) && defined(MODULE)) +extern struct dvb_frontend* lgdt3304_attach(const struct lgdt3304_config *config, + struct i2c_adapter *i2c); +#else +static inline struct dvb_frontend* lgdt3304_attach(const struct lgdt3304_config *config, + struct i2c_adapter *i2c) +{ + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); + return NULL; +} +#endif /* CONFIG_DVB_LGDT */ + +#endif /* LGDT3304_H */ -- cgit v1.2.3 From 2245652cac401039c92068767ae978b4c922897b Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 24 Oct 2008 14:44:38 -0200 Subject: Move S921 driver to the proper place and allow it to compile From: Mauro Carvalho Chehab Priority: normal Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/frontends/Kconfig | 11 + linux/drivers/media/dvb/frontends/Makefile | 3 + linux/drivers/media/dvb/frontends/s921_core.c | 587 +++++++++++++++++++++ linux/drivers/media/dvb/frontends/s921_core.h | 114 ++++ linux/drivers/media/dvb/frontends/s921_module.c | 254 +++++++++ linux/drivers/media/dvb/frontends/s921_module.h | 49 ++ linux/drivers/media/video/empia/sharp/Makefile | 3 - linux/drivers/media/video/empia/sharp/s921_core.c | 586 -------------------- linux/drivers/media/video/empia/sharp/s921_core.h | 114 ---- .../drivers/media/video/empia/sharp/s921_module.c | 254 --------- .../drivers/media/video/empia/sharp/s921_module.h | 49 -- 11 files changed, 1018 insertions(+), 1006 deletions(-) create mode 100644 linux/drivers/media/dvb/frontends/s921_core.c create mode 100644 linux/drivers/media/dvb/frontends/s921_core.h create mode 100644 linux/drivers/media/dvb/frontends/s921_module.c create mode 100644 linux/drivers/media/dvb/frontends/s921_module.h delete mode 100644 linux/drivers/media/video/empia/sharp/Makefile delete mode 100644 linux/drivers/media/video/empia/sharp/s921_core.c delete mode 100644 linux/drivers/media/video/empia/sharp/s921_core.h delete mode 100644 linux/drivers/media/video/empia/sharp/s921_module.c delete mode 100644 linux/drivers/media/video/empia/sharp/s921_module.h diff --git a/linux/drivers/media/dvb/frontends/Kconfig b/linux/drivers/media/dvb/frontends/Kconfig index 96b93e21a..8da1e8166 100644 --- a/linux/drivers/media/dvb/frontends/Kconfig +++ b/linux/drivers/media/dvb/frontends/Kconfig @@ -369,6 +369,17 @@ config DVB_S5H1411 An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want to support this frontend. +comment "ISDB-T (terrestrial) frontends" + depends on DVB_CORE + +config DVB_S921 + tristate "Sharp S921 tuner" + depends on DVB_CORE && I2C + default m if DVB_FE_CUSTOMISE + help + AN ISDB-T DQPSK, QPSK, 16QAM and 64QAM 1seg tuner module. + Say Y when you want to support this frontend. + comment "Digital terrestrial only tuners/PLL" depends on DVB_CORE diff --git a/linux/drivers/media/dvb/frontends/Makefile b/linux/drivers/media/dvb/frontends/Makefile index aba79f4a6..11a5407ec 100644 --- a/linux/drivers/media/dvb/frontends/Makefile +++ b/linux/drivers/media/dvb/frontends/Makefile @@ -5,6 +5,8 @@ EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/ EXTRA_CFLAGS += -Idrivers/media/common/tuners/ +s921-objs := s921_module.o s921_core.o + obj-$(CONFIG_DVB_PLL) += dvb-pll.o obj-$(CONFIG_DVB_STV0299) += stv0299.o obj-$(CONFIG_DVB_SP8870) += sp8870.o @@ -55,3 +57,4 @@ obj-$(CONFIG_DVB_CX24116) += cx24116.o obj-$(CONFIG_DVB_SI21XX) += si21xx.o obj-$(CONFIG_DVB_STV0288) += stv0288.o obj-$(CONFIG_DVB_STB6000) += stb6000.o +obj-$(CONFIG_DVB_S921) += s921.o diff --git a/linux/drivers/media/dvb/frontends/s921_core.c b/linux/drivers/media/dvb/frontends/s921_core.c new file mode 100644 index 000000000..5b9e6040e --- /dev/null +++ b/linux/drivers/media/dvb/frontends/s921_core.c @@ -0,0 +1,587 @@ +/* + * Driver for Sharp s921 driver + * + * Copyright (C) 2008 Markus Rechberger + * + */ + + +#include +#include +#include +#include "s921_core.h" + +static int s921_isdb_init(struct s921_isdb_t *dev); +static int s921_isdb_set_parameters(struct s921_isdb_t *dev, struct s921_isdb_t_transmission_mode_params *params); +static int s921_isdb_tune(struct s921_isdb_t *dev, struct s921_isdb_t_tune_params *params); +static int s921_isdb_get_status(struct s921_isdb_t *dev, void *data); + +static u8 init_table[]={ 0x01, 0x40, 0x02, 0x00, 0x03, 0x40, 0x04, 0x01, + 0x05, 0x00, 0x06, 0x00, 0x07, 0x00, 0x08, 0x00, + 0x09, 0x00, 0x0a, 0x00, 0x0b, 0x5a, 0x0c, 0x00, + 0x0d, 0x00, 0x0f, 0x00, 0x13, 0x1b, 0x14, 0x80, + 0x15, 0x40, 0x17, 0x70, 0x18, 0x01, 0x19, 0x12, + 0x1a, 0x01, 0x1b, 0x12, 0x1c, 0xa0, 0x1d, 0x00, + 0x1e, 0x0a, 0x1f, 0x08, 0x20, 0x40, 0x21, 0xff, + 0x22, 0x4c, 0x23, 0x4e, 0x24, 0x4c, 0x25, 0x00, + 0x26, 0x00, 0x27, 0xf4, 0x28, 0x60, 0x29, 0x88, + 0x2a, 0x40, 0x2b, 0x40, 0x2c, 0xff, 0x2d, 0x00, + 0x2e, 0xff, 0x2f, 0x00, 0x30, 0x20, 0x31, 0x06, + 0x32, 0x0c, 0x34, 0x0f, 0x37, 0xfe, 0x38, 0x00, + 0x39, 0x63, 0x3a, 0x10, 0x3b, 0x10, 0x47, 0x00, + 0x49, 0xe5, 0x4b, 0x00, 0x50, 0xc0, 0x52, 0x20, + 0x54, 0x5a, 0x55, 0x5b, 0x56, 0x40, 0x57, 0x70, + 0x5c, 0x50, 0x5d, 0x00, 0x62, 0x17, 0x63, 0x2f, + 0x64, 0x6f, 0x68, 0x00, 0x69, 0x89, 0x6a, 0x00, + 0x6b, 0x00, 0x6c, 0x00, 0x6d, 0x00, 0x6e, 0x00, + 0x70, 0x00, 0x71, 0x00, 0x75, 0x00, 0x76, 0x30, + 0x77, 0x01, 0xaf, 0x00, 0xb0, 0xa0, 0xb2, 0x3d, + 0xb3, 0x25, 0xb4, 0x8b, 0xb5, 0x4b, 0xb6, 0x3f, + 0xb7, 0xff, 0xb8, 0xff, 0xb9, 0xfc, 0xba, 0x00, + 0xbb, 0x00, 0xbc, 0x00, 0xd0, 0x30, 0xe4, 0x84, + 0xf0, 0x48, 0xf1, 0x19, 0xf2, 0x5a, 0xf3, 0x8e, + 0xf4, 0x2d, 0xf5, 0x07, 0xf6, 0x5a, 0xf7, 0xba, + 0xf8, 0xd7 }; + +static u8 c_table[]={ 0x58, 0x8a, 0x7b, 0x59, 0x8c, 0x7b, 0x5a, 0x8e, 0x5b, + 0x5b, 0x90, 0x5b, 0x5c, 0x92, 0x5b, 0x5d, 0x94, 0x5b, + 0x5e, 0x96, 0x5b, 0x5f, 0x98, 0x3b, 0x60, 0x9a, 0x3b, + 0x61, 0x9c, 0x3b, 0x62, 0x9e, 0x3b, 0x63, 0xa0, 0x3b, + 0x64, 0xa2, 0x1b, 0x65, 0xa4, 0x1b, 0x66, 0xa6, 0x1b, + 0x67, 0xa8, 0x1b, 0x68, 0xaa, 0x1b, 0x69, 0xac, 0x1b, + 0x6a, 0xae, 0x1b, 0x6b, 0xb0, 0x1b, 0x6c, 0xb2, 0x1b, + 0x6d, 0xb4, 0xfb, 0x6e, 0xb6, 0xfb, 0x6f, 0xb8, 0xfb, + 0x70, 0xba, 0xfb, 0x71, 0xbc, 0xdb, 0x72, 0xbe, 0xdb, + 0x73, 0xc0, 0xdb, 0x74, 0xc2, 0xdb, 0x75, 0xc4, 0xdb, + 0x76, 0xc6, 0xdb, 0x77, 0xc8, 0xbb, 0x78, 0xca, 0xbb, + 0x79, 0xcc, 0xbb, 0x7a, 0xce, 0xbb, 0x7b, 0xd0, 0xbb, + 0x7c, 0xd2, 0xbb, 0x7d, 0xd4, 0xbb, 0x7e, 0xd6, 0xbb, + 0x7f, 0xd8, 0xbb, 0x80, 0xda, 0x9b, 0x81, 0xdc, 0x9b, + 0x82, 0xde, 0x9b, 0x83, 0xe0, 0x9b, 0x84, 0xe2, 0x9b, + 0x85, 0xe4, 0x9b, 0x86, 0xe6, 0x9b, 0x87, 0xe8, 0x9b, + 0x88, 0xea, 0x9b, 0x89, 0xec, 0x9b }; + +int s921_isdb_cmd(struct s921_isdb_t *dev, u32 cmd, void *data) { + switch(cmd) { + case ISDB_T_CMD_INIT: + s921_isdb_init(dev); + break; + case ISDB_T_CMD_SET_PARAM: + s921_isdb_set_parameters(dev, data); + break; + case ISDB_T_CMD_TUNE: + s921_isdb_tune(dev, data); + break; + case ISDB_T_CMD_GET_STATUS: + s921_isdb_get_status(dev, data); + break; + default: + printk("unhandled command\n"); + return -EINVAL; + } + return 0; +} + +static int s921_isdb_init(struct s921_isdb_t *dev) { + unsigned int i; + unsigned int ret; + printk("isdb_init\n"); + for (i = 0; i < sizeof(init_table); i+=2) { + ret = dev->i2c_write(dev->priv_dev, init_table[i], init_table[i+1]); + if (ret != 0) { + printk("i2c write failed\n"); + return ret; + } + } + return 0; +} + +static int s921_isdb_set_parameters(struct s921_isdb_t *dev, struct s921_isdb_t_transmission_mode_params *params) { + + int ret; + /* auto is sufficient for now, lateron this should be reflected in an extra interface */ + +#if 0 + u8 mod_b2 = 0; + u8 mod_b3 = 0; + u8 mod_b4 = 0; + u8 mod_b5 = 0; + u8 mod_b6 = 0; + u8 mod_b7 = 0; + u8 mod_b8 = 0; + /* LAYER A Setup */ + + switch (params->layer_a_carrier_modulation) { + case ISDB_T_LA_CM_DQPSK: + mod_b3 |= 0<<5; + break; + case ISDB_T_LA_CM_QPSK: + mod_b3 |= 1<<5; + break; + case ISDB_T_LA_CM_16QAM: + mod_b3 |= 2<<5; + break; + case ISDB_T_LA_CM_64QAM: + mod_b3 |= 3<<5; + break; + case ISDB_T_LA_CM_NOLAYER: + mod_b3 |= 7<<5; + break; + default: + printk("invalid carrier modulation\n"); + return -EINVAL; + } + + switch(params->layer_a_code_rate) { + case ISDB_T_LA_CR_1_2: + mod_b3 |= 0<<2; + break; + case ISDB_T_LA_CR_2_3: + mod_b3 |= 1<<2; + break; + case ISDB_T_LA_CR_3_4: + mod_b3 |= 2<<2; + break; + case ISDB_T_LA_CR_5_6: + mod_b3 |= 3<<2; + break; + case ISDB_T_LA_CR_7_8: + mod_b3 |= 4<<2; + break; + default: + printk("invalid coderate\n"); + return -EINVAL; + } + + switch (params->layer_a_mode) { + case ISDB_T_LA_MODE_1: + switch(params->layer_a_time_interleave) { + case ISDB_T_LA_TI_0: + mod_b3 |= 0; + mod_b4 |= 0; + break; + case ISDB_T_LA_TI_4: + mod_b3 |= 1; + mod_b4 |= 0; + break; + case ISDB_T_LA_TI_8: + mod_b3 |= 2; + mod_b4 |= 0; + break; + case ISDB_T_LA_TI_16: + mod_b3 |= 3; + mod_b4 |= 0; + break; + case ISDB_T_LA_TI_32: + mod_b3 |= 0; + mod_b4 |= 1<<7; + break; + default: + printk("invalid layer a time interleave\n"); + return -EINVAL; + } + break; + case ISDB_T_LA_MODE_2: + switch(params->layer_a_time_interleave) { + case ISDB_T_LA_TI_0: + mod_b3 |= 0; + mod_b4 |= 0; + break; + case ISDB_T_LA_TI_2: + mod_b3 |= 1; + mod_b4 |= 0; + break; + case ISDB_T_LA_TI_4: + mod_b3 |= 2; + mod_b4 |= 0; + break; + case ISDB_T_LA_TI_8: + mod_b3 |= 3; + mod_b4 |= 0; + break; + case ISDB_T_LA_TI_16: + mod_b3 |= 0; + mod_b4 |= 1<<7; + break; + default: + + printk("invalid layer a time interleave\n"); + return -EINVAL; + } + break; + case ISDB_T_LA_MODE_3: + switch(params->layer_a_time_interleave) { + case ISDB_T_LA_TI_0: + mod_b3 |= 0; + mod_b4 |= 0; + break; + case ISDB_T_LA_TI_1: + mod_b3 |= 1; + mod_b4 |= 0; + break; + case ISDB_T_LA_TI_2: + mod_b3 |= 2; + mod_b4 |= 0; + break; + case ISDB_T_LA_TI_4: + mod_b3 |= 3; + mod_b4 |= 0; + break; + case ISDB_T_LA_TI_8: + mod_b3 |= 0; + mod_b4 |= 1<<7; + break; + default: + printk("invalid layer a time interleave\n"); + return -EINVAL; + } + break; + default: + printk("invalid layer mode\n"); + return -EINVAL; + } + + + /* LAYER B Setup */ + switch (params->layer_b_carrier_modulation) { + case ISDB_T_LB_CM_DQPSK: + mod_b4 |= 0; + break; + case ISDB_T_LB_CM_QPSK: + mod_b4 |= 1; + break; + case ISDB_T_LB_CM_16QAM: + mod_b4 |= 2; + break; + case ISDB_T_LB_CM_64QAM: + mod_b4 |= 3; + break; + case ISDB_T_LB_CM_NOLAYER: + mod_b4 |= 7; + break; + default: + return -EINVAL; + } + + switch(params->layer_b_code_rate) { + case ISDB_T_LB_CR_1_2: + mod_b5 |= 0<<5; + break; + case ISDB_T_LB_CR_2_3: + mod_b5 |= 1<<5; + break; + case ISDB_T_LB_CR_3_4: + mod_b5 |= 2<<5; + break; + case ISDB_T_LB_CR_5_6: + mod_b5 |= 3<<5; + break; + case ISDB_T_LB_CR_7_8: + mod_b5 |= 4<<5; + break; + case ISDB_T_LB_CR_NOLAYER: + mod_b5 |= 7<<5; + break; + default: + return -EINVAL; + } + + switch (params->layer_b_mode) { + case ISDB_T_LB_MODE_1: + switch(params->layer_b_time_interleave) { + case ISDB_T_LB_TI_0: + mod_b5 |= 0; + break; + case ISDB_T_LB_TI_4: + mod_b5 |= 1<<2; + break; + case ISDB_T_LB_TI_8: + mod_b5 |= 2<<2; + break; + case ISDB_T_LB_TI_16: + mod_b5 |= 3<<2; + break; + case ISDB_T_LB_TI_32: + mod_b5 |= 4<<2; + break; + default: + return -EINVAL; + } + break; + case ISDB_T_LB_MODE_2: + switch(params->layer_b_time_interleave) { + case ISDB_T_LB_TI_0: + mod_b5 |= 0; + break; + case ISDB_T_LB_TI_2: + mod_b5 |= 1<<2; + break; + case ISDB_T_LB_TI_4: + mod_b5 |= 2<<2; + break; + case ISDB_T_LB_TI_8: + mod_b5 |= 3<<2; + break; + case ISDB_T_LB_TI_16: + mod_b5 |= 4<<2; + break; + default: + return -EINVAL; + } + break; + case ISDB_T_LB_MODE_3: + switch(params->layer_b_time_interleave) { + case ISDB_T_LB_TI_0: + mod_b5 |= 0; + break; + case ISDB_T_LB_TI_1: + mod_b5 |= 1<<2; + break; + case ISDB_T_LB_TI_2: + mod_b5 |= 2<<2; + break; + case ISDB_T_LB_TI_4: + mod_b5 |= 3<<2; + break; + case ISDB_T_LB_TI_8: + mod_b5 |= 4<<2; + break; + default: + return -EINVAL; + } + break; + default: + return -EINVAL; + } + + /* LAYER C Setup */ + switch (params->layer_c_carrier_modulation) { + case ISDB_T_LC_CM_DQPSK: + mod_b5 |= 0<<3; + break; + case ISDB_T_LC_CM_QPSK: + mod_b5 |= 1<<3; + break; + case ISDB_T_LC_CM_16QAM: + mod_b5 |= 2<<3; + break; + case ISDB_T_LC_CM_64QAM: + mod_b5 |= 3<<3; + break; + case ISDB_T_LC_CM_NOLAYER: + mod_b5 |= 7<<3; + break; + default: + return -EINVAL; + } + + switch(params->layer_c_code_rate) { + case ISDB_T_LC_CR_1_2: + mod_b5 |= 0<<0; + break; + case ISDB_T_LC_CR_2_3: + mod_b5 |= 1<<0; + break; + case ISDB_T_LC_CR_3_4: + mod_b5 |= 2<<0; + break; + case ISDB_T_LC_CR_5_6: + mod_b5 |= 3<<0; + break; + case ISDB_T_LC_CR_7_8: + mod_b5 |= 4<<0; + break; + default: + return -EINVAL; + } + + switch (params->layer_c_mode) { + case ISDB_T_LC_MODE_1: + switch(params->layer_c_time_interleave) { + case ISDB_T_LC_TI_0: + mod_b7 |= 0<<5; + break; + case ISDB_T_LC_TI_4: + mod_b7 |= 1<<5; + break; + case ISDB_T_LC_TI_8: + mod_b7 |= 2<<5; + break; + case ISDB_T_LC_TI_16: + mod_b7 |= 3<<5; + break; + case ISDB_T_LC_TI_32: + mod_b7 |= 4<<5; + break; + default: + return -EINVAL; + } + break; + case ISDB_T_LC_MODE_2: + switch(params->layer_c_time_interleave) { + case ISDB_T_LC_TI_0: + mod_b7 |= 0<<5; + break; + case ISDB_T_LC_TI_2: + mod_b7 |= 1<<5; + break; + case ISDB_T_LC_TI_4: + mod_b7 |= 2<<5; + break; + case ISDB_T_LC_TI_8: + mod_b7 |= 3<<5; + break; + case ISDB_T_LC_TI_16: + mod_b7 |= 4<<5; + break; + default: + return -EINVAL; + } + break; + case ISDB_T_LC_MODE_3: + switch(params->layer_c_time_interleave) { + case ISDB_T_LC_TI_0: + mod_b7 |= 0<<5; + break; + case ISDB_T_LC_TI_1: + mod_b7 |= 1<<5; + break; + case ISDB_T_LC_TI_2: + mod_b7 |= 2<<5; + break; + case ISDB_T_LC_TI_4: + mod_b7 |= 3<<5; + break; + case ISDB_T_LC_TI_8: + mod_b7 |= 4<<5; + break; + default: + return -EINVAL; + } + break; + default: + return -EINVAL; + } +#endif + + + ret = dev->i2c_write(dev->priv_dev, 0xb0, 0xa0); //mod_b2); + ret = dev->i2c_write(dev->priv_dev, 0xb2, 0x3d); //mod_b2); + + if (ret < 0) + return -EINVAL; + + ret = dev->i2c_write(dev->priv_dev, 0xb3, 0x25); //mod_b3); + if (ret < 0) + return -EINVAL; + + ret = dev->i2c_write(dev->priv_dev, 0xb4, 0x8b); //mod_b4); + if (ret < 0) + return -EINVAL; + + ret = dev->i2c_write(dev->priv_dev, 0xb5, 0x4b); //mod_b5); + if (ret < 0) + return -EINVAL; + + ret = dev->i2c_write(dev->priv_dev, 0xb6, 0x3f); //mod_b6); + if (ret < 0) + return -EINVAL; + + ret = dev->i2c_write(dev->priv_dev, 0xb7, 0x3f); //mod_b7); + if (ret < 0) + return -EINVAL; + + return E_OK; +} + +static int s921_isdb_tune(struct s921_isdb_t *dev, struct s921_isdb_t_tune_params *params) { + + int ret; + int index; + + index = (params->frequency - 473143000)/6000000; + + if (index > 48) { + return -EINVAL; + } + + dev->i2c_write(dev->priv_dev, 0x47, 0x60); + + ret = dev->i2c_write(dev->priv_dev, 0x68, 0x00); + if (ret < 0) + return -EINVAL; + + ret = dev->i2c_write(dev->priv_dev, 0x69, 0x89); + if (ret < 0) + return -EINVAL; + + ret = dev->i2c_write(dev->priv_dev, 0xf0, 0x48); + if (ret < 0) + return -EINVAL; + + ret = dev->i2c_write(dev->priv_dev, 0xf1, 0x19); + if (ret < 0) + return -EINVAL; + + ret = dev->i2c_write(dev->priv_dev, 0xf2, c_table[index*3]); + if (ret < 0) + return -EINVAL; + + ret = dev->i2c_write(dev->priv_dev, 0xf3, c_table[index*3+1]); + if (ret < 0) + return -EINVAL; + + ret = dev->i2c_write(dev->priv_dev, 0xf4, c_table[index*3+2]); + if (ret < 0) + return -EINVAL; + + ret = dev->i2c_write(dev->priv_dev, 0xf5, 0xae); + if (ret < 0) + return -EINVAL; + + ret = dev->i2c_write(dev->priv_dev, 0xf6, 0xb7); + if (ret < 0) + return -EINVAL; + + ret = dev->i2c_write(dev->priv_dev, 0xf7, 0xba); + if (ret < 0) + return -EINVAL; + + ret = dev->i2c_write(dev->priv_dev, 0xf8, 0xd7); + if (ret < 0) + return -EINVAL; + + ret = dev->i2c_write(dev->priv_dev, 0x68, 0x0a); + if (ret < 0) + return -EINVAL; + + ret = dev->i2c_write(dev->priv_dev, 0x69, 0x09); + if (ret < 0) + return -EINVAL; + + dev->i2c_write(dev->priv_dev, 0x01, 0x40); + return 0; +} + +static int s921_isdb_get_status(struct s921_isdb_t *dev, void *data) { + unsigned int *ret = (unsigned int*)data; + u8 ifagc_dt; + u8 rfagc_dt; + + mdelay(10); + ifagc_dt = dev->i2c_read(dev->priv_dev, 0x81); + rfagc_dt = dev->i2c_read(dev->priv_dev, 0x82); +#if 0 + *ret = dev->i2c_read(dev->priv_dev, 0x82); + printk("status 83: %02x\n", *ret); + *ret = dev->i2c_read(dev->priv_dev, 0x80); + mdelay(10); + *ret = dev->i2c_read(dev->priv_dev, 0x80); + mdelay(10); + *ret = dev->i2c_read(dev->priv_dev, 0x80); +#endif + if (rfagc_dt == 0x40) { + *ret = 1; + } + return 0; +} diff --git a/linux/drivers/media/dvb/frontends/s921_core.h b/linux/drivers/media/dvb/frontends/s921_core.h new file mode 100644 index 000000000..de2f10a44 --- /dev/null +++ b/linux/drivers/media/dvb/frontends/s921_core.h @@ -0,0 +1,114 @@ +#ifndef _S921_CORE_H +#define _S921_CORE_H +//#define u8 unsigned int +//#define u32 unsigned int + + + +//#define EINVAL -1 +#define E_OK 0 + +struct s921_isdb_t { + void *priv_dev; + int (*i2c_write)(void *dev, u8 reg, u8 val); + int (*i2c_read)(void *dev, u8 reg); +}; + +#define ISDB_T_CMD_INIT 0 +#define ISDB_T_CMD_SET_PARAM 1 +#define ISDB_T_CMD_TUNE 2 +#define ISDB_T_CMD_GET_STATUS 3 + +struct s921_isdb_t_tune_params { + u32 frequency; +}; + +struct s921_isdb_t_status { +}; + +struct s921_isdb_t_transmission_mode_params { + u8 mode; + u8 layer_a_mode; +#define ISDB_T_LA_MODE_1 0 +#define ISDB_T_LA_MODE_2 1 +#define ISDB_T_LA_MODE_3 2 + u8 layer_a_carrier_modulation; +#define ISDB_T_LA_CM_DQPSK 0 +#define ISDB_T_LA_CM_QPSK 1 +#define ISDB_T_LA_CM_16QAM 2 +#define ISDB_T_LA_CM_64QAM 3 +#define ISDB_T_LA_CM_NOLAYER 4 + u8 layer_a_code_rate; +#define ISDB_T_LA_CR_1_2 0 +#define ISDB_T_LA_CR_2_3 1 +#define ISDB_T_LA_CR_3_4 2 +#define ISDB_T_LA_CR_5_6 4 +#define ISDB_T_LA_CR_7_8 8 +#define ISDB_T_LA_CR_NOLAYER 16 + u8 layer_a_time_interleave; +#define ISDB_T_LA_TI_0 0 +#define ISDB_T_LA_TI_1 1 +#define ISDB_T_LA_TI_2 2 +#define ISDB_T_LA_TI_4 4 +#define ISDB_T_LA_TI_8 8 +#define ISDB_T_LA_TI_16 16 +#define ISDB_T_LA_TI_32 32 + u8 layer_a_nseg; + + u8 layer_b_mode; +#define ISDB_T_LB_MODE_1 0 +#define ISDB_T_LB_MODE_2 1 +#define ISDB_T_LB_MODE_3 2 + u8 layer_b_carrier_modulation; +#define ISDB_T_LB_CM_DQPSK 0 +#define ISDB_T_LB_CM_QPSK 1 +#define ISDB_T_LB_CM_16QAM 2 +#define ISDB_T_LB_CM_64QAM 3 +#define ISDB_T_LB_CM_NOLAYER 4 + u8 layer_b_code_rate; +#define ISDB_T_LB_CR_1_2 0 +#define ISDB_T_LB_CR_2_3 1 +#define ISDB_T_LB_CR_3_4 2 +#define ISDB_T_LB_CR_5_6 4 +#define ISDB_T_LB_CR_7_8 8 +#define ISDB_T_LB_CR_NOLAYER 16 + u8 layer_b_time_interleave; +#define ISDB_T_LB_TI_0 0 +#define ISDB_T_LB_TI_1 1 +#define ISDB_T_LB_TI_2 2 +#define ISDB_T_LB_TI_4 4 +#define ISDB_T_LB_TI_8 8 +#define ISDB_T_LB_TI_16 16 +#define ISDB_T_LB_TI_32 32 + u8 layer_b_nseg; + + u8 layer_c_mode; +#define ISDB_T_LC_MODE_1 0 +#define ISDB_T_LC_MODE_2 1 +#define ISDB_T_LC_MODE_3 2 + u8 layer_c_carrier_modulation; +#define ISDB_T_LC_CM_DQPSK 0 +#define ISDB_T_LC_CM_QPSK 1 +#define ISDB_T_LC_CM_16QAM 2 +#define ISDB_T_LC_CM_64QAM 3 +#define ISDB_T_LC_CM_NOLAYER 4 + u8 layer_c_code_rate; +#define ISDB_T_LC_CR_1_2 0 +#define ISDB_T_LC_CR_2_3 1 +#define ISDB_T_LC_CR_3_4 2 +#define ISDB_T_LC_CR_5_6 4 +#define ISDB_T_LC_CR_7_8 8 +#define ISDB_T_LC_CR_NOLAYER 16 + u8 layer_c_time_interleave; +#define ISDB_T_LC_TI_0 0 +#define ISDB_T_LC_TI_1 1 +#define ISDB_T_LC_TI_2 2 +#define ISDB_T_LC_TI_4 4 +#define ISDB_T_LC_TI_8 8 +#define ISDB_T_LC_TI_16 16 +#define ISDB_T_LC_TI_32 32 + u8 layer_c_nseg; +}; + +int s921_isdb_cmd(struct s921_isdb_t *dev, u32 cmd, void *data); +#endif diff --git a/linux/drivers/media/dvb/frontends/s921_module.c b/linux/drivers/media/dvb/frontends/s921_module.c new file mode 100644 index 000000000..6018ec505 --- /dev/null +++ b/linux/drivers/media/dvb/frontends/s921_module.c @@ -0,0 +1,254 @@ +/* + * Driver for Sharp s921 driver + * + * Copyright (C) 2008 Markus Rechberger + * + * All rights reserved. + * + */ + +#include +#include +#include +#include "dvb_frontend.h" +#include "s921_module.h" +#include "s921_core.h" + +static unsigned int debug = 0; +module_param(debug, int, 0644); +MODULE_PARM_DESC(debug,"s921 debugging (default off)"); + +#define dprintk(fmt, args...) if (debug) do {\ + printk("s921 debug: " fmt, ##args); } while (0) + +struct s921_state +{ + struct dvb_frontend frontend; + fe_modulation_t current_modulation; + __u32 snr; + __u32 current_frequency; + __u8 addr; + struct s921_isdb_t dev; + struct i2c_adapter *i2c; +}; + +static int s921_set_parameters(struct dvb_frontend *fe, struct dvb_frontend_parameters *param) { + struct s921_state *state = (struct s921_state *)fe->demodulator_priv; + struct s921_isdb_t_transmission_mode_params params; + struct s921_isdb_t_tune_params tune_params; + + tune_params.frequency = param->frequency; +#if 0 + struct dvb_ofdm_parameters *op = ¶m->u.ofdm; + + switch (op->bandwidth) { + case BANDWIDTH_6_MHZ: + case BANDWIDTH_7_MHZ: + case BANDWIDTH_8_MHZ: + default: + break; + } + + switch (op->code_rate_HP) { + case FEC_2_3: + case FEC_3_4: + case FEC_5_6: + case FEC_7_8: + case FEC_1_2: + case FEC_AUTO: + break; + default: + break; + } + + switch(op->code_rate_LP) { + case FEC_2_3: + case FEC_3_4: + case FEC_5_6: + case FEC_7_8: + case FEC_1_2: + case FEC_AUTO: + case FEC_NONE: + default: + break; + } + + switch (op->constellation) { + case QPSK: + case QAM_AUTO: + case QAM_16: + default: + break; + } + + switch (op->guard_interval) { + case GUARD_INTERVAL_1_32: + case GUARD_INTERVAL_AUTO: + case GUARD_INTERVAL_1_16: + case GUARD_INTERVAL_1_8: + case GUARD_INTERVAL_1_4: + default: + break; + } + + switch (op->hierarchy_information) { + case HIERARCHY_AUTO: + case HIERARCHY_NONE: + case HIERARCHY_1: + case HIERARCHY_2: + case HIERARCHY_4: + default: + break; + } + +#endif + s921_isdb_cmd(&state->dev, ISDB_T_CMD_SET_PARAM, ¶ms); + s921_isdb_cmd(&state->dev, ISDB_T_CMD_TUNE, &tune_params); + mdelay(100); + return 0; +} + +static int s921_init(struct dvb_frontend *fe) { + printk("s921 init\n"); + return 0; +} + +static int s921_sleep(struct dvb_frontend *fe) { + printk("s921 sleep\n"); + return 0; +} + +static int s921_read_status(struct dvb_frontend *fe, fe_status_t *status) +{ + struct s921_state *state = (struct s921_state *)fe->demodulator_priv; + unsigned int ret; + mdelay(5); + s921_isdb_cmd(&state->dev, ISDB_T_CMD_GET_STATUS, &ret); + *status = 0; + + printk("status: %02x\n", ret); + if (ret == 1) { + *status |= FE_HAS_CARRIER; + *status |= FE_HAS_VITERBI; + *status |= FE_HAS_LOCK; + *status |= FE_HAS_SYNC; + *status |= FE_HAS_SIGNAL; + } + + return 0; +} + +static int s921_read_ber(struct dvb_frontend *fe, __u32 *ber) +{ + dprintk("read ber\n"); + return 0; +} + +static int s921_read_snr(struct dvb_frontend *fe, __u16 *snr) +{ + dprintk("read snr\n"); + return 0; +} + +static int s921_read_ucblocks(struct dvb_frontend *fe, __u32 *ucblocks) +{ + dprintk("read ucblocks\n"); + return 0; +} + +static void s921_release(struct dvb_frontend *fe) +{ + struct s921_state *state = (struct s921_state *)fe->demodulator_priv; + kfree(state); +} + +static struct dvb_frontend_ops demod_s921={ + .info = { + .name = "SHARP S921", + .type = FE_OFDM, + .frequency_min = 473143000, + .frequency_max = 767143000, + .frequency_stepsize = 6000000, + .frequency_tolerance = 0, + .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | + FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | + FE_CAN_FEC_AUTO | + FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO | + FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO | + FE_CAN_HIERARCHY_AUTO | FE_CAN_RECOVER | + FE_CAN_MUTE_TS + }, + .init = s921_init, + .sleep = s921_sleep, + .set_frontend = s921_set_parameters, + .read_snr = s921_read_snr, + .read_ber = s921_read_ber, + .read_status = s921_read_status, + .read_ucblocks = s921_read_ucblocks, + .release = s921_release, +}; + +static int s921_write(void *dev, u8 reg, u8 val) { + struct s921_state *state = dev; + char buf[2]={reg,val}; + int err; + struct i2c_msg i2cmsgs = { + .addr = state->addr, + .flags = 0, + .len = 2, + .buf = buf + }; + + if((err = i2c_transfer(state->i2c, &i2cmsgs, 1))<0) { + printk("%s i2c_transfer error %d\n", __FUNCTION__, err); + if (err < 0) + return err; + else + return -EREMOTEIO; + } + + return 0; +} + +static int s921_read(void *dev, u8 reg) { + struct s921_state *state = dev; + u8 b1; + int ret; + struct i2c_msg msg[2] = { { .addr = state->addr, + .flags = 0, + .buf = ®, .len = 1 }, + { .addr = state->addr, + .flags = I2C_M_RD, + .buf = &b1, .len = 1 } }; + + ret = i2c_transfer(state->i2c, msg, 2); + if (ret != 2) + return ret; + return b1; +} + +struct dvb_frontend* s921_attach(const struct s921_config *config, + struct i2c_adapter *i2c) +{ + + struct s921_state *state; + state = kzalloc(sizeof(struct s921_state), GFP_KERNEL); + memset(state, 0x0, sizeof(struct s921_state)); + + state->addr = config->i2c_address; + state->i2c = i2c; + state->dev.i2c_write = &s921_write; + state->dev.i2c_read = &s921_read; + state->dev.priv_dev = state; + + s921_isdb_cmd(&state->dev, ISDB_T_CMD_INIT, NULL); + + memcpy(&state->frontend.ops, &demod_s921, sizeof(struct dvb_frontend_ops)); + state->frontend.demodulator_priv = state; + return &state->frontend; +} + +EXPORT_SYMBOL_GPL(s921_attach); +MODULE_AUTHOR("Markus Rechberger "); +MODULE_DESCRIPTION("Sharp S921 ISDB-T 1Seg"); +MODULE_LICENSE("GPL"); diff --git a/linux/drivers/media/dvb/frontends/s921_module.h b/linux/drivers/media/dvb/frontends/s921_module.h new file mode 100644 index 000000000..78660424b --- /dev/null +++ b/linux/drivers/media/dvb/frontends/s921_module.h @@ -0,0 +1,49 @@ +/* + * Driver for DVB-T s921 demodulator + * + * Copyright (C) 2008 Markus Rechberger + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.= + */ + +#ifndef S921_MODULE_H +#define S921_MODULE_H + +#include +#include "s921_core.h" + +int s921_isdb_init(struct s921_isdb_t *dev); +int s921_isdb_cmd(struct s921_isdb_t *dev, u32 cmd, void *data); + +struct s921_config +{ + /* demodulator's I2C address */ + u8 i2c_address; +}; + +#if defined(CONFIG_DVB_S921) || (defined(CONFIG_DVB_S921_MODULE) && defined(MODULE)) +extern struct dvb_frontend* s921_attach(const struct s921_config *config, + struct i2c_adapter *i2c); +#else +static inline struct dvb_frontend* s921_attach(const struct s921_config *config, + struct i2c_adapter *i2c) +{ + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); + return NULL; +} +#endif /* CONFIG_DVB_S921 */ + +#endif /* S921_H */ diff --git a/linux/drivers/media/video/empia/sharp/Makefile b/linux/drivers/media/video/empia/sharp/Makefile deleted file mode 100644 index 510561130..000000000 --- a/linux/drivers/media/video/empia/sharp/Makefile +++ /dev/null @@ -1,3 +0,0 @@ -s921-objs := s921_module.o s921_core.o - -obj-m += s921.o diff --git a/linux/drivers/media/video/empia/sharp/s921_core.c b/linux/drivers/media/video/empia/sharp/s921_core.c deleted file mode 100644 index 1a7271700..000000000 --- a/linux/drivers/media/video/empia/sharp/s921_core.c +++ /dev/null @@ -1,586 +0,0 @@ -/* - * Driver for Sharp s921 driver - * - * Copyright (C) 2008 Markus Rechberger - * - */ - - -#include -#include -#include "s921_core.h" - -static int s921_isdb_init(struct s921_isdb_t *dev); -static int s921_isdb_set_parameters(struct s921_isdb_t *dev, struct s921_isdb_t_transmission_mode_params *params); -static int s921_isdb_tune(struct s921_isdb_t *dev, struct s921_isdb_t_tune_params *params); -static int s921_isdb_get_status(struct s921_isdb_t *dev, void *data); - -static u8 init_table[]={ 0x01, 0x40, 0x02, 0x00, 0x03, 0x40, 0x04, 0x01, - 0x05, 0x00, 0x06, 0x00, 0x07, 0x00, 0x08, 0x00, - 0x09, 0x00, 0x0a, 0x00, 0x0b, 0x5a, 0x0c, 0x00, - 0x0d, 0x00, 0x0f, 0x00, 0x13, 0x1b, 0x14, 0x80, - 0x15, 0x40, 0x17, 0x70, 0x18, 0x01, 0x19, 0x12, - 0x1a, 0x01, 0x1b, 0x12, 0x1c, 0xa0, 0x1d, 0x00, - 0x1e, 0x0a, 0x1f, 0x08, 0x20, 0x40, 0x21, 0xff, - 0x22, 0x4c, 0x23, 0x4e, 0x24, 0x4c, 0x25, 0x00, - 0x26, 0x00, 0x27, 0xf4, 0x28, 0x60, 0x29, 0x88, - 0x2a, 0x40, 0x2b, 0x40, 0x2c, 0xff, 0x2d, 0x00, - 0x2e, 0xff, 0x2f, 0x00, 0x30, 0x20, 0x31, 0x06, - 0x32, 0x0c, 0x34, 0x0f, 0x37, 0xfe, 0x38, 0x00, - 0x39, 0x63, 0x3a, 0x10, 0x3b, 0x10, 0x47, 0x00, - 0x49, 0xe5, 0x4b, 0x00, 0x50, 0xc0, 0x52, 0x20, - 0x54, 0x5a, 0x55, 0x5b, 0x56, 0x40, 0x57, 0x70, - 0x5c, 0x50, 0x5d, 0x00, 0x62, 0x17, 0x63, 0x2f, - 0x64, 0x6f, 0x68, 0x00, 0x69, 0x89, 0x6a, 0x00, - 0x6b, 0x00, 0x6c, 0x00, 0x6d, 0x00, 0x6e, 0x00, - 0x70, 0x00, 0x71, 0x00, 0x75, 0x00, 0x76, 0x30, - 0x77, 0x01, 0xaf, 0x00, 0xb0, 0xa0, 0xb2, 0x3d, - 0xb3, 0x25, 0xb4, 0x8b, 0xb5, 0x4b, 0xb6, 0x3f, - 0xb7, 0xff, 0xb8, 0xff, 0xb9, 0xfc, 0xba, 0x00, - 0xbb, 0x00, 0xbc, 0x00, 0xd0, 0x30, 0xe4, 0x84, - 0xf0, 0x48, 0xf1, 0x19, 0xf2, 0x5a, 0xf3, 0x8e, - 0xf4, 0x2d, 0xf5, 0x07, 0xf6, 0x5a, 0xf7, 0xba, - 0xf8, 0xd7 }; - -static u8 c_table[]={ 0x58, 0x8a, 0x7b, 0x59, 0x8c, 0x7b, 0x5a, 0x8e, 0x5b, - 0x5b, 0x90, 0x5b, 0x5c, 0x92, 0x5b, 0x5d, 0x94, 0x5b, - 0x5e, 0x96, 0x5b, 0x5f, 0x98, 0x3b, 0x60, 0x9a, 0x3b, - 0x61, 0x9c, 0x3b, 0x62, 0x9e, 0x3b, 0x63, 0xa0, 0x3b, - 0x64, 0xa2, 0x1b, 0x65, 0xa4, 0x1b, 0x66, 0xa6, 0x1b, - 0x67, 0xa8, 0x1b, 0x68, 0xaa, 0x1b, 0x69, 0xac, 0x1b, - 0x6a, 0xae, 0x1b, 0x6b, 0xb0, 0x1b, 0x6c, 0xb2, 0x1b, - 0x6d, 0xb4, 0xfb, 0x6e, 0xb6, 0xfb, 0x6f, 0xb8, 0xfb, - 0x70, 0xba, 0xfb, 0x71, 0xbc, 0xdb, 0x72, 0xbe, 0xdb, - 0x73, 0xc0, 0xdb, 0x74, 0xc2, 0xdb, 0x75, 0xc4, 0xdb, - 0x76, 0xc6, 0xdb, 0x77, 0xc8, 0xbb, 0x78, 0xca, 0xbb, - 0x79, 0xcc, 0xbb, 0x7a, 0xce, 0xbb, 0x7b, 0xd0, 0xbb, - 0x7c, 0xd2, 0xbb, 0x7d, 0xd4, 0xbb, 0x7e, 0xd6, 0xbb, - 0x7f, 0xd8, 0xbb, 0x80, 0xda, 0x9b, 0x81, 0xdc, 0x9b, - 0x82, 0xde, 0x9b, 0x83, 0xe0, 0x9b, 0x84, 0xe2, 0x9b, - 0x85, 0xe4, 0x9b, 0x86, 0xe6, 0x9b, 0x87, 0xe8, 0x9b, - 0x88, 0xea, 0x9b, 0x89, 0xec, 0x9b }; - -int s921_isdb_cmd(struct s921_isdb_t *dev, u32 cmd, void *data) { - switch(cmd) { - case ISDB_T_CMD_INIT: - s921_isdb_init(dev); - break; - case ISDB_T_CMD_SET_PARAM: - s921_isdb_set_parameters(dev, data); - break; - case ISDB_T_CMD_TUNE: - s921_isdb_tune(dev, data); - break; - case ISDB_T_CMD_GET_STATUS: - s921_isdb_get_status(dev, data); - break; - default: - printk("unhandled command\n"); - return -EINVAL; - } - return 0; -} - -static int s921_isdb_init(struct s921_isdb_t *dev) { - unsigned int i; - unsigned int ret; - printk("isdb_init\n"); - for (i = 0; i < sizeof(init_table); i+=2) { - ret = dev->i2c_write(dev->priv_dev, init_table[i], init_table[i+1]); - if (ret != 0) { - printk("i2c write failed\n"); - return ret; - } - } - return 0; -} - -static int s921_isdb_set_parameters(struct s921_isdb_t *dev, struct s921_isdb_t_transmission_mode_params *params) { - - int ret; - /* auto is sufficient for now, lateron this should be reflected in an extra interface */ - -#if 0 - u8 mod_b2 = 0; - u8 mod_b3 = 0; - u8 mod_b4 = 0; - u8 mod_b5 = 0; - u8 mod_b6 = 0; - u8 mod_b7 = 0; - u8 mod_b8 = 0; - /* LAYER A Setup */ - - switch (params->layer_a_carrier_modulation) { - case ISDB_T_LA_CM_DQPSK: - mod_b3 |= 0<<5; - break; - case ISDB_T_LA_CM_QPSK: - mod_b3 |= 1<<5; - break; - case ISDB_T_LA_CM_16QAM: - mod_b3 |= 2<<5; - break; - case ISDB_T_LA_CM_64QAM: - mod_b3 |= 3<<5; - break; - case ISDB_T_LA_CM_NOLAYER: - mod_b3 |= 7<<5; - break; - default: - printk("invalid carrier modulation\n"); - return -EINVAL; - } - - switch(params->layer_a_code_rate) { - case ISDB_T_LA_CR_1_2: - mod_b3 |= 0<<2; - break; - case ISDB_T_LA_CR_2_3: - mod_b3 |= 1<<2; - break; - case ISDB_T_LA_CR_3_4: - mod_b3 |= 2<<2; - break; - case ISDB_T_LA_CR_5_6: - mod_b3 |= 3<<2; - break; - case ISDB_T_LA_CR_7_8: - mod_b3 |= 4<<2; - break; - default: - printk("invalid coderate\n"); - return -EINVAL; - } - - switch (params->layer_a_mode) { - case ISDB_T_LA_MODE_1: - switch(params->layer_a_time_interleave) { - case ISDB_T_LA_TI_0: - mod_b3 |= 0; - mod_b4 |= 0; - break; - case ISDB_T_LA_TI_4: - mod_b3 |= 1; - mod_b4 |= 0; - break; - case ISDB_T_LA_TI_8: - mod_b3 |= 2; - mod_b4 |= 0; - break; - case ISDB_T_LA_TI_16: - mod_b3 |= 3; - mod_b4 |= 0; - break; - case ISDB_T_LA_TI_32: - mod_b3 |= 0; - mod_b4 |= 1<<7; - break; - default: - printk("invalid layer a time interleave\n"); - return -EINVAL; - } - break; - case ISDB_T_LA_MODE_2: - switch(params->layer_a_time_interleave) { - case ISDB_T_LA_TI_0: - mod_b3 |= 0; - mod_b4 |= 0; - break; - case ISDB_T_LA_TI_2: - mod_b3 |= 1; - mod_b4 |= 0; - break; - case ISDB_T_LA_TI_4: - mod_b3 |= 2; - mod_b4 |= 0; - break; - case ISDB_T_LA_TI_8: - mod_b3 |= 3; - mod_b4 |= 0; - break; - case ISDB_T_LA_TI_16: - mod_b3 |= 0; - mod_b4 |= 1<<7; - break; - default: - - printk("invalid layer a time interleave\n"); - return -EINVAL; - } - break; - case ISDB_T_LA_MODE_3: - switch(params->layer_a_time_interleave) { - case ISDB_T_LA_TI_0: - mod_b3 |= 0; - mod_b4 |= 0; - break; - case ISDB_T_LA_TI_1: - mod_b3 |= 1; - mod_b4 |= 0; - break; - case ISDB_T_LA_TI_2: - mod_b3 |= 2; - mod_b4 |= 0; - break; - case ISDB_T_LA_TI_4: - mod_b3 |= 3; - mod_b4 |= 0; - break; - case ISDB_T_LA_TI_8: - mod_b3 |= 0; - mod_b4 |= 1<<7; - break; - default: - printk("invalid layer a time interleave\n"); - return -EINVAL; - } - break; - default: - printk("invalid layer mode\n"); - return -EINVAL; - } - - - /* LAYER B Setup */ - switch (params->layer_b_carrier_modulation) { - case ISDB_T_LB_CM_DQPSK: - mod_b4 |= 0; - break; - case ISDB_T_LB_CM_QPSK: - mod_b4 |= 1; - break; - case ISDB_T_LB_CM_16QAM: - mod_b4 |= 2; - break; - case ISDB_T_LB_CM_64QAM: - mod_b4 |= 3; - break; - case ISDB_T_LB_CM_NOLAYER: - mod_b4 |= 7; - break; - default: - return -EINVAL; - } - - switch(params->layer_b_code_rate) { - case ISDB_T_LB_CR_1_2: - mod_b5 |= 0<<5; - break; - case ISDB_T_LB_CR_2_3: - mod_b5 |= 1<<5; - break; - case ISDB_T_LB_CR_3_4: - mod_b5 |= 2<<5; - break; - case ISDB_T_LB_CR_5_6: - mod_b5 |= 3<<5; - break; - case ISDB_T_LB_CR_7_8: - mod_b5 |= 4<<5; - break; - case ISDB_T_LB_CR_NOLAYER: - mod_b5 |= 7<<5; - break; - default: - return -EINVAL; - } - - switch (params->layer_b_mode) { - case ISDB_T_LB_MODE_1: - switch(params->layer_b_time_interleave) { - case ISDB_T_LB_TI_0: - mod_b5 |= 0; - break; - case ISDB_T_LB_TI_4: - mod_b5 |= 1<<2; - break; - case ISDB_T_LB_TI_8: - mod_b5 |= 2<<2; - break; - case ISDB_T_LB_TI_16: - mod_b5 |= 3<<2; - break; - case ISDB_T_LB_TI_32: - mod_b5 |= 4<<2; - break; - default: - return -EINVAL; - } - break; - case ISDB_T_LB_MODE_2: - switch(params->layer_b_time_interleave) { - case ISDB_T_LB_TI_0: - mod_b5 |= 0; - break; - case ISDB_T_LB_TI_2: - mod_b5 |= 1<<2; - break; - case ISDB_T_LB_TI_4: - mod_b5 |= 2<<2; - break; - case ISDB_T_LB_TI_8: - mod_b5 |= 3<<2; - break; - case ISDB_T_LB_TI_16: - mod_b5 |= 4<<2; - break; - default: - return -EINVAL; - } - break; - case ISDB_T_LB_MODE_3: - switch(params->layer_b_time_interleave) { - case ISDB_T_LB_TI_0: - mod_b5 |= 0; - break; - case ISDB_T_LB_TI_1: - mod_b5 |= 1<<2; - break; - case ISDB_T_LB_TI_2: - mod_b5 |= 2<<2; - break; - case ISDB_T_LB_TI_4: - mod_b5 |= 3<<2; - break; - case ISDB_T_LB_TI_8: - mod_b5 |= 4<<2; - break; - default: - return -EINVAL; - } - break; - default: - return -EINVAL; - } - - /* LAYER C Setup */ - switch (params->layer_c_carrier_modulation) { - case ISDB_T_LC_CM_DQPSK: - mod_b5 |= 0<<3; - break; - case ISDB_T_LC_CM_QPSK: - mod_b5 |= 1<<3; - break; - case ISDB_T_LC_CM_16QAM: - mod_b5 |= 2<<3; - break; - case ISDB_T_LC_CM_64QAM: - mod_b5 |= 3<<3; - break; - case ISDB_T_LC_CM_NOLAYER: - mod_b5 |= 7<<3; - break; - default: - return -EINVAL; - } - - switch(params->layer_c_code_rate) { - case ISDB_T_LC_CR_1_2: - mod_b5 |= 0<<0; - break; - case ISDB_T_LC_CR_2_3: - mod_b5 |= 1<<0; - break; - case ISDB_T_LC_CR_3_4: - mod_b5 |= 2<<0; - break; - case ISDB_T_LC_CR_5_6: - mod_b5 |= 3<<0; - break; - case ISDB_T_LC_CR_7_8: - mod_b5 |= 4<<0; - break; - default: - return -EINVAL; - } - - switch (params->layer_c_mode) { - case ISDB_T_LC_MODE_1: - switch(params->layer_c_time_interleave) { - case ISDB_T_LC_TI_0: - mod_b7 |= 0<<5; - break; - case ISDB_T_LC_TI_4: - mod_b7 |= 1<<5; - break; - case ISDB_T_LC_TI_8: - mod_b7 |= 2<<5; - break; - case ISDB_T_LC_TI_16: - mod_b7 |= 3<<5; - break; - case ISDB_T_LC_TI_32: - mod_b7 |= 4<<5; - break; - default: - return -EINVAL; - } - break; - case ISDB_T_LC_MODE_2: - switch(params->layer_c_time_interleave) { - case ISDB_T_LC_TI_0: - mod_b7 |= 0<<5; - break; - case ISDB_T_LC_TI_2: - mod_b7 |= 1<<5; - break; - case ISDB_T_LC_TI_4: - mod_b7 |= 2<<5; - break; - case ISDB_T_LC_TI_8: - mod_b7 |= 3<<5; - break; - case ISDB_T_LC_TI_16: - mod_b7 |= 4<<5; - break; - default: - return -EINVAL; - } - break; - case ISDB_T_LC_MODE_3: - switch(params->layer_c_time_interleave) { - case ISDB_T_LC_TI_0: - mod_b7 |= 0<<5; - break; - case ISDB_T_LC_TI_1: - mod_b7 |= 1<<5; - break; - case ISDB_T_LC_TI_2: - mod_b7 |= 2<<5; - break; - case ISDB_T_LC_TI_4: - mod_b7 |= 3<<5; - break; - case ISDB_T_LC_TI_8: - mod_b7 |= 4<<5; - break; - default: - return -EINVAL; - } - break; - default: - return -EINVAL; - } -#endif - - - ret = dev->i2c_write(dev->priv_dev, 0xb0, 0xa0); //mod_b2); - ret = dev->i2c_write(dev->priv_dev, 0xb2, 0x3d); //mod_b2); - - if (ret < 0) - return -EINVAL; - - ret = dev->i2c_write(dev->priv_dev, 0xb3, 0x25); //mod_b3); - if (ret < 0) - return -EINVAL; - - ret = dev->i2c_write(dev->priv_dev, 0xb4, 0x8b); //mod_b4); - if (ret < 0) - return -EINVAL; - - ret = dev->i2c_write(dev->priv_dev, 0xb5, 0x4b); //mod_b5); - if (ret < 0) - return -EINVAL; - - ret = dev->i2c_write(dev->priv_dev, 0xb6, 0x3f); //mod_b6); - if (ret < 0) - return -EINVAL; - - ret = dev->i2c_write(dev->priv_dev, 0xb7, 0x3f); //mod_b7); - if (ret < 0) - return -EINVAL; - - return E_OK; -} - -static int s921_isdb_tune(struct s921_isdb_t *dev, struct s921_isdb_t_tune_params *params) { - - int ret; - int index; - - index = (params->frequency - 473143000)/6000000; - - if (index > 48) { - return -EINVAL; - } - - dev->i2c_write(dev->priv_dev, 0x47, 0x60); - - ret = dev->i2c_write(dev->priv_dev, 0x68, 0x00); - if (ret < 0) - return -EINVAL; - - ret = dev->i2c_write(dev->priv_dev, 0x69, 0x89); - if (ret < 0) - return -EINVAL; - - ret = dev->i2c_write(dev->priv_dev, 0xf0, 0x48); - if (ret < 0) - return -EINVAL; - - ret = dev->i2c_write(dev->priv_dev, 0xf1, 0x19); - if (ret < 0) - return -EINVAL; - - ret = dev->i2c_write(dev->priv_dev, 0xf2, c_table[index*3]); - if (ret < 0) - return -EINVAL; - - ret = dev->i2c_write(dev->priv_dev, 0xf3, c_table[index*3+1]); - if (ret < 0) - return -EINVAL; - - ret = dev->i2c_write(dev->priv_dev, 0xf4, c_table[index*3+2]); - if (ret < 0) - return -EINVAL; - - ret = dev->i2c_write(dev->priv_dev, 0xf5, 0xae); - if (ret < 0) - return -EINVAL; - - ret = dev->i2c_write(dev->priv_dev, 0xf6, 0xb7); - if (ret < 0) - return -EINVAL; - - ret = dev->i2c_write(dev->priv_dev, 0xf7, 0xba); - if (ret < 0) - return -EINVAL; - - ret = dev->i2c_write(dev->priv_dev, 0xf8, 0xd7); - if (ret < 0) - return -EINVAL; - - ret = dev->i2c_write(dev->priv_dev, 0x68, 0x0a); - if (ret < 0) - return -EINVAL; - - ret = dev->i2c_write(dev->priv_dev, 0x69, 0x09); - if (ret < 0) - return -EINVAL; - - dev->i2c_write(dev->priv_dev, 0x01, 0x40); - return 0; -} - -static int s921_isdb_get_status(struct s921_isdb_t *dev, void *data) { - unsigned int *ret = (unsigned int*)data; - u8 ifagc_dt; - u8 rfagc_dt; - - mdelay(10); - ifagc_dt = dev->i2c_read(dev->priv_dev, 0x81); - rfagc_dt = dev->i2c_read(dev->priv_dev, 0x82); -#if 0 - *ret = dev->i2c_read(dev->priv_dev, 0x82); - printk("status 83: %02x\n", *ret); - *ret = dev->i2c_read(dev->priv_dev, 0x80); - mdelay(10); - *ret = dev->i2c_read(dev->priv_dev, 0x80); - mdelay(10); - *ret = dev->i2c_read(dev->priv_dev, 0x80); -#endif - if (rfagc_dt == 0x40) { - *ret = 1; - } - return 0; -} diff --git a/linux/drivers/media/video/empia/sharp/s921_core.h b/linux/drivers/media/video/empia/sharp/s921_core.h deleted file mode 100644 index ae39a2a52..000000000 --- a/linux/drivers/media/video/empia/sharp/s921_core.h +++ /dev/null @@ -1,114 +0,0 @@ -#ifndef _S921_CORE_H -#define _S921_CORE_H -//#define u8 unsigned int -//#define u32 unsigned int - - - -//#define EINVAL -1 -#define E_OK 0 - -struct s921_isdb_t { - void *priv_dev; - int (*i2c_write)(void *dev, u8 reg, u8 val); - int (*i2c_read)(void *dev, u8 reg); -}; - -#define ISDB_T_CMD_INIT 0 -#define ISDB_T_CMD_SET_PARAM 1 -#define ISDB_T_CMD_TUNE 2 -#define ISDB_T_CMD_GET_STATUS 3 - -struct s921_isdb_t_tune_params { - u32 frequency; -}; - -struct s921_isdb_t_status { -}; - -struct s921_isdb_t_transmission_mode_params { - u8 mode; - u8 layer_a_mode; -#define ISDB_T_LA_MODE_1 0 -#define ISDB_T_LA_MODE_2 1 -#define ISDB_T_LA_MODE_3 2 - u8 layer_a_carrier_modulation; -#define ISDB_T_LA_CM_DQPSK 0 -#define ISDB_T_LA_CM_QPSK 1 -#define ISDB_T_LA_CM_16QAM 2 -#define ISDB_T_LA_CM_64QAM 3 -#define ISDB_T_LA_CM_NOLAYER 4 - u8 layer_a_code_rate; -#define ISDB_T_LA_CR_1_2 0 -#define ISDB_T_LA_CR_2_3 1 -#define ISDB_T_LA_CR_3_4 2 -#define ISDB_T_LA_CR_5_6 4 -#define ISDB_T_LA_CR_7_8 8 -#define ISDB_T_LA_CR_NOLAYER 16 - u8 layer_a_time_interleave; -#define ISDB_T_LA_TI_0 0 -#define ISDB_T_LA_TI_1 1 -#define ISDB_T_LA_TI_2 2 -#define ISDB_T_LA_TI_4 4 -#define ISDB_T_LA_TI_8 8 -#define ISDB_T_LA_TI_16 16 -#define ISDB_T_LA_TI_32 32 - u8 layer_a_nseg; - - u8 layer_b_mode; -#define ISDB_T_LB_MODE_1 0 -#define ISDB_T_LB_MODE_2 1 -#define ISDB_T_LB_MODE_3 2 - u8 layer_b_carrier_modulation; -#define ISDB_T_LB_CM_DQPSK 0 -#define ISDB_T_LB_CM_QPSK 1 -#define ISDB_T_LB_CM_16QAM 2 -#define ISDB_T_LB_CM_64QAM 3 -#define ISDB_T_LB_CM_NOLAYER 4 - u8 layer_b_code_rate; -#define ISDB_T_LB_CR_1_2 0 -#define ISDB_T_LB_CR_2_3 1 -#define ISDB_T_LB_CR_3_4 2 -#define ISDB_T_LB_CR_5_6 4 -#define ISDB_T_LB_CR_7_8 8 -#define ISDB_T_LB_CR_NOLAYER 16 - u8 layer_b_time_interleave; -#define ISDB_T_LB_TI_0 0 -#define ISDB_T_LB_TI_1 1 -#define ISDB_T_LB_TI_2 2 -#define ISDB_T_LB_TI_4 4 -#define ISDB_T_LB_TI_8 8 -#define ISDB_T_LB_TI_16 16 -#define ISDB_T_LB_TI_32 32 - u8 layer_b_nseg; - - u8 layer_c_mode; -#define ISDB_T_LC_MODE_1 0 -#define ISDB_T_LC_MODE_2 1 -#define ISDB_T_LC_MODE_3 2 - u8 layer_c_carrier_modulation; -#define ISDB_T_LC_CM_DQPSK 0 -#define ISDB_T_LC_CM_QPSK 1 -#define ISDB_T_LC_CM_16QAM 2 -#define ISDB_T_LC_CM_64QAM 3 -#define ISDB_T_LC_CM_NOLAYER 4 - u8 layer_c_code_rate; -#define ISDB_T_LC_CR_1_2 0 -#define ISDB_T_LC_CR_2_3 1 -#define ISDB_T_LC_CR_3_4 2 -#define ISDB_T_LC_CR_5_6 4 -#define ISDB_T_LC_CR_7_8 8 -#define ISDB_T_LC_CR_NOLAYER 16 - u8 layer_c_time_interleave; -#define ISDB_T_LC_TI_0 0 -#define ISDB_T_LC_TI_1 1 -#define ISDB_T_LC_TI_2 2 -#define ISDB_T_LC_TI_4 4 -#define ISDB_T_LC_TI_8 8 -#define ISDB_T_LC_TI_16 16 -#define ISDB_T_LC_TI_32 32 - u8 layer_c_nseg; -}; - -int s921_isdb_cmd(struct s921_isdb_t *dev, u32 cmd, void *data); -#endif diff --git a/linux/drivers/media/video/empia/sharp/s921_module.c b/linux/drivers/media/video/empia/sharp/s921_module.c deleted file mode 100644 index d78ebafe8..000000000 --- a/linux/drivers/media/video/empia/sharp/s921_module.c +++ /dev/null @@ -1,254 +0,0 @@ -/* - * Driver for Sharp s921 driver - * - * Copyright (C) 2008 Markus Rechberger - * - * All rights reserved. - * - */ - -#include -#include -#include -#include "dvb_frontend.h" -#include "s921_module.h" -#include "s921_core.h" - -static unsigned int debug = 0; -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug,"s921 debugging (default off)"); - -#define dprintk(fmt, args...) if (debug) do {\ - printk("s921 debug: " fmt, ##args); } while (0) - -struct s921_state -{ - struct dvb_frontend frontend; - fe_modulation_t current_modulation; - __u32 snr; - __u32 current_frequency; - __u8 addr; - struct s921_isdb_t dev; - struct i2c_adapter *i2c; -}; - -static int s921_set_parameters(struct dvb_frontend *fe, struct dvb_frontend_parameters *param) { - struct s921_state *state = (struct s921_state *)fe->demodulator_priv; - struct s921_isdb_t_transmission_mode_params params; - struct s921_isdb_t_tune_params tune_params; - - tune_params.frequency = param->frequency; -#if 0 - struct dvb_ofdm_parameters *op = ¶m->u.ofdm; - - switch (op->bandwidth) { - case BANDWIDTH_6_MHZ: - case BANDWIDTH_7_MHZ: - case BANDWIDTH_8_MHZ: - default: - break; - } - - switch (op->code_rate_HP) { - case FEC_2_3: - case FEC_3_4: - case FEC_5_6: - case FEC_7_8: - case FEC_1_2: - case FEC_AUTO: - break; - default: - break; - } - - switch(op->code_rate_LP) { - case FEC_2_3: - case FEC_3_4: - case FEC_5_6: - case FEC_7_8: - case FEC_1_2: - case FEC_AUTO: - case FEC_NONE: - default: - break; - } - - switch (op->constellation) { - case QPSK: - case QAM_AUTO: - case QAM_16: - default: - break; - } - - switch (op->guard_interval) { - case GUARD_INTERVAL_1_32: - case GUARD_INTERVAL_AUTO: - case GUARD_INTERVAL_1_16: - case GUARD_INTERVAL_1_8: - case GUARD_INTERVAL_1_4: - default: - break; - } - - switch (op->hierarchy_information) { - case HIERARCHY_AUTO: - case HIERARCHY_NONE: - case HIERARCHY_1: - case HIERARCHY_2: - case HIERARCHY_4: - default: - break; - } - -#endif - s921_isdb_cmd(&state->dev, ISDB_T_CMD_SET_PARAM, ¶ms); - s921_isdb_cmd(&state->dev, ISDB_T_CMD_TUNE, &tune_params); - mdelay(100); - return 0; -} - -static int s921_init(struct dvb_frontend *fe) { - printk("s921 init\n"); - return 0; -} - -static int s921_sleep(struct dvb_frontend *fe) { - printk("s921 sleep\n"); - return 0; -} - -static int s921_read_status(struct dvb_frontend *fe, fe_status_t *status) -{ - struct s921_state *state = (struct s921_state *)fe->demodulator_priv; - unsigned int ret; - mdelay(5); - s921_isdb_cmd(&state->dev, ISDB_T_CMD_GET_STATUS, &ret); - *status = 0; - - printk("status: %02x\n", ret); - if (ret == 1) { - *status |= FE_HAS_CARRIER; - *status |= FE_HAS_VITERBI; - *status |= FE_HAS_LOCK; - *status |= FE_HAS_SYNC; - *status |= FE_HAS_SIGNAL; - } - - return 0; -} - -static int s921_read_ber(struct dvb_frontend *fe, __u32 *ber) -{ - dprintk("read ber\n"); - return 0; -} - -static int s921_read_snr(struct dvb_frontend *fe, __u16 *snr) -{ - dprintk("read snr\n"); - return 0; -} - -static int s921_read_ucblocks(struct dvb_frontend *fe, __u32 *ucblocks) -{ - dprintk("read ucblocks\n"); - return 0; -} - -static void s921_release(struct dvb_frontend *fe) -{ - struct s921_state *state = (struct s921_state *)fe->demodulator_priv; - kfree(state); -} - -static struct dvb_frontend_ops demod_s921={ - .info = { - .name = "SHARP S921", - .type = FE_OFDM, - .frequency_min = 473143000, - .frequency_max = 767143000, - .frequency_stepsize = 6000000, - .frequency_tolerance = 0, - .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | - FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | - FE_CAN_FEC_AUTO | - FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO | - FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO | - FE_CAN_HIERARCHY_AUTO | FE_CAN_RECOVER | - FE_CAN_MUTE_TS - }, - .init = s921_init, - .sleep = s921_sleep, - .set_frontend = s921_set_parameters, - .read_snr = s921_read_snr, - .read_ber = s921_read_ber, - .read_status = s921_read_status, - .read_ucblocks = s921_read_ucblocks, - .release = s921_release, -}; - -static int s921_write(void *dev, u8 reg, u8 val) { - struct s921_state *state = dev; - char buf[2]={reg,val}; - int err; - struct i2c_msg i2cmsgs = { - .addr = state->addr, - .flags = 0, - .len = 2, - .buf = buf - }; - - if((err = i2c_transfer(state->i2c, &i2cmsgs, 1))<0) { - printk("%s i2c_transfer error %d\n", __FUNCTION__, err); - if (err < 0) - return err; - else - return -EREMOTEIO; - } - - return 0; -} - -static int s921_read(void *dev, u8 reg) { - struct s921_state *state = dev; - u8 b1; - int ret; - struct i2c_msg msg[2] = { { .addr = state->addr, - .flags = 0, - .buf = ®, .len = 1 }, - { .addr = state->addr, - .flags = I2C_M_RD, - .buf = &b1, .len = 1 } }; - - ret = i2c_transfer(state->i2c, msg, 2); - if (ret != 2) - return ret; - return b1; -} - -struct dvb_frontend* s921_attach(const struct s921_config *config, - struct i2c_adapter *i2c) -{ - - struct s921_state *state; - state = kzalloc(sizeof(struct s921_state), GFP_KERNEL); - memset(state, 0x0, sizeof(struct s921_state)); - - state->addr = config->i2c_address; - state->i2c = i2c; - state->dev.i2c_write = &s921_write; - state->dev.i2c_read = &s921_read; - state->dev.priv_dev = state; - - s921_isdb_cmd(&state->dev, ISDB_T_CMD_INIT, NULL); - - memcpy(&state->frontend.ops, &demod_s921, sizeof(struct dvb_frontend_ops)); - state->frontend.demodulator_priv = state; - return &state->frontend; -} - -EXPORT_SYMBOL_GPL(s921_attach); -MODULE_AUTHOR("Markus Rechberger "); -MODULE_DESCRIPTION("Sharp S921 ISDB-T 1Seg"); -MODULE_LICENSE("GPL"); diff --git a/linux/drivers/media/video/empia/sharp/s921_module.h b/linux/drivers/media/video/empia/sharp/s921_module.h deleted file mode 100644 index 78660424b..000000000 --- a/linux/drivers/media/video/empia/sharp/s921_module.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Driver for DVB-T s921 demodulator - * - * Copyright (C) 2008 Markus Rechberger - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.= - */ - -#ifndef S921_MODULE_H -#define S921_MODULE_H - -#include -#include "s921_core.h" - -int s921_isdb_init(struct s921_isdb_t *dev); -int s921_isdb_cmd(struct s921_isdb_t *dev, u32 cmd, void *data); - -struct s921_config -{ - /* demodulator's I2C address */ - u8 i2c_address; -}; - -#if defined(CONFIG_DVB_S921) || (defined(CONFIG_DVB_S921_MODULE) && defined(MODULE)) -extern struct dvb_frontend* s921_attach(const struct s921_config *config, - struct i2c_adapter *i2c); -#else -static inline struct dvb_frontend* s921_attach(const struct s921_config *config, - struct i2c_adapter *i2c) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} -#endif /* CONFIG_DVB_S921 */ - -#endif /* S921_H */ -- cgit v1.2.3 From 2919f67f6614355388ad72644b0a305ec1c86234 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 24 Oct 2008 16:06:17 -0200 Subject: Move lgdt3304 driver to the proper place and allow it to compile From: Mauro Carvalho Chehab Priority: normal Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/frontends/Kconfig | 8 + linux/drivers/media/dvb/frontends/Makefile | 2 + linux/drivers/media/dvb/frontends/lgdt3304.c | 398 +++++++++++++++++++++ linux/drivers/media/dvb/frontends/lgdt3304.h | 45 +++ linux/drivers/media/video/empia/lgdt3304/Makefile | 7 - .../drivers/media/video/empia/lgdt3304/lgdt3304.c | 398 --------------------- .../drivers/media/video/empia/lgdt3304/lgdt3304.h | 45 --- 7 files changed, 453 insertions(+), 450 deletions(-) create mode 100644 linux/drivers/media/dvb/frontends/lgdt3304.c create mode 100644 linux/drivers/media/dvb/frontends/lgdt3304.h delete mode 100644 linux/drivers/media/video/empia/lgdt3304/Makefile delete mode 100644 linux/drivers/media/video/empia/lgdt3304/lgdt3304.c delete mode 100644 linux/drivers/media/video/empia/lgdt3304/lgdt3304.h diff --git a/linux/drivers/media/dvb/frontends/Kconfig b/linux/drivers/media/dvb/frontends/Kconfig index 8da1e8166..69eb1f8eb 100644 --- a/linux/drivers/media/dvb/frontends/Kconfig +++ b/linux/drivers/media/dvb/frontends/Kconfig @@ -345,6 +345,14 @@ config DVB_LGDT330X An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want to support this frontend. +config DVB_LGDT3304 + tristate "LG Electronics LGDT3304" + depends on DVB_CORE && I2C + default m if DVB_FE_CUSTOMISE + help + An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want + to support this frontend. + config DVB_S5H1409 tristate "Samsung S5H1409 based" depends on DVB_CORE && I2C diff --git a/linux/drivers/media/dvb/frontends/Makefile b/linux/drivers/media/dvb/frontends/Makefile index 11a5407ec..651c9e889 100644 --- a/linux/drivers/media/dvb/frontends/Makefile +++ b/linux/drivers/media/dvb/frontends/Makefile @@ -37,6 +37,7 @@ obj-$(CONFIG_DVB_OR51132) += or51132.o obj-$(CONFIG_DVB_BCM3510) += bcm3510.o obj-$(CONFIG_DVB_S5H1420) += s5h1420.o obj-$(CONFIG_DVB_LGDT330X) += lgdt330x.o +obj-$(CONFIG_DVB_LGDT3304) += lgdt3304.o obj-$(CONFIG_DVB_CX24123) += cx24123.o obj-$(CONFIG_DVB_LNBP21) += lnbp21.o obj-$(CONFIG_DVB_ISL6405) += isl6405.o @@ -58,3 +59,4 @@ obj-$(CONFIG_DVB_SI21XX) += si21xx.o obj-$(CONFIG_DVB_STV0288) += stv0288.o obj-$(CONFIG_DVB_STB6000) += stb6000.o obj-$(CONFIG_DVB_S921) += s921.o + diff --git a/linux/drivers/media/dvb/frontends/lgdt3304.c b/linux/drivers/media/dvb/frontends/lgdt3304.c new file mode 100644 index 000000000..724811744 --- /dev/null +++ b/linux/drivers/media/dvb/frontends/lgdt3304.c @@ -0,0 +1,398 @@ +/* + * Driver for LG ATSC lgdt3304 driver + * + * Copyright (C) 2008 Markus Rechberger + * + */ + +#include +#include +#include +#include "dvb_frontend.h" +#include "lgdt3304.h" + +static unsigned int debug = 0; +module_param(debug, int, 0644); +MODULE_PARM_DESC(debug,"lgdt3304 debugging (default off)"); + +#define dprintk(fmt, args...) if (debug) do {\ + printk("lgdt3304 debug: " fmt, ##args); } while (0) + +struct lgdt3304_state +{ + struct dvb_frontend frontend; + fe_modulation_t current_modulation; + __u32 snr; + __u32 current_frequency; + __u8 addr; + struct i2c_adapter *i2c; +}; + +static int i2c_write_demod_bytes (struct dvb_frontend *fe, __u8 *buf, int len) +{ + struct lgdt3304_state *state = fe->demodulator_priv; + struct i2c_msg i2cmsgs = { + .addr = state->addr, + .flags = 0, + .len = 3, + .buf = buf + }; + int i; + int err; + + for (i=0; ii2c, &i2cmsgs, 1))<0) { + printk("%s i2c_transfer error %d\n", __FUNCTION__, err); + if (err < 0) + return err; + else + return -EREMOTEIO; + } + i2cmsgs.buf += 3; + } + return 0; +} + +static int lgdt3304_i2c_read_reg(struct dvb_frontend *fe, unsigned int reg) +{ + struct lgdt3304_state *state = fe->demodulator_priv; + struct i2c_msg i2cmsgs[2]; + int ret; + __u8 buf; + + __u8 regbuf[2] = { reg>>8, reg&0xff }; + + i2cmsgs[0].addr = state->addr; + i2cmsgs[0].flags = 0; + i2cmsgs[0].len = 2; + i2cmsgs[0].buf = regbuf; + + i2cmsgs[1].addr = state->addr; + i2cmsgs[1].flags = I2C_M_RD; + i2cmsgs[1].len = 1; + i2cmsgs[1].buf = &buf; + + if((ret = i2c_transfer(state->i2c, i2cmsgs, 2))<0) { + printk("%s i2c_transfer error %d\n", __FUNCTION__, ret); + return ret; + } + + return buf; +} + +static int lgdt3304_i2c_write_reg(struct dvb_frontend *fe, int reg, int val) +{ + struct lgdt3304_state *state = fe->demodulator_priv; + char buffer[3] = { reg>>8, reg&0xff, val }; + int ret; + + struct i2c_msg i2cmsgs = { + .addr = state->addr, + .flags = 0, + .len = 3, + .buf=buffer + }; + ret = i2c_transfer(state->i2c, &i2cmsgs, 1); + if (ret != 1) { + printk("%s i2c_transfer error %d\n", __FUNCTION__, ret); + return ret; + } + + return 0; +} + + +static int lgdt3304_soft_Reset(struct dvb_frontend *fe) +{ + lgdt3304_i2c_write_reg(fe, 0x0002, 0x9a); + lgdt3304_i2c_write_reg(fe, 0x0002, 0x9b); + mdelay(200); + return 0; +} + +static int lgdt3304_set_parameters(struct dvb_frontend *fe, struct dvb_frontend_parameters *param) { + int err = 0; + + static __u8 lgdt3304_vsb8_data[] = { + /* 16bit , 8bit */ + /* regs , val */ + 0x00, 0x00, 0x02, + 0x00, 0x00, 0x13, + 0x00, 0x0d, 0x02, + 0x00, 0x0e, 0x02, + 0x00, 0x12, 0x32, + 0x00, 0x13, 0xc4, + 0x01, 0x12, 0x17, + 0x01, 0x13, 0x15, + 0x01, 0x14, 0x18, + 0x01, 0x15, 0xff, + 0x01, 0x16, 0x2c, + 0x02, 0x14, 0x67, + 0x02, 0x24, 0x8d, + 0x04, 0x27, 0x12, + 0x04, 0x28, 0x4f, + 0x03, 0x08, 0x80, + 0x03, 0x09, 0x00, + 0x03, 0x0d, 0x00, + 0x03, 0x0e, 0x1c, + 0x03, 0x14, 0xe1, + 0x05, 0x0e, 0x5b, + }; + + /* not yet tested .. */ + static __u8 lgdt3304_qam64_data[] = { + /* 16bit , 8bit */ + /* regs , val */ + 0x00, 0x00, 0x18, + 0x00, 0x0d, 0x02, + //0x00, 0x0e, 0x02, + 0x00, 0x12, 0x2a, + 0x00, 0x13, 0x00, + 0x03, 0x14, 0xe3, + 0x03, 0x0e, 0x1c, + 0x03, 0x08, 0x66, + 0x03, 0x09, 0x66, + 0x03, 0x0a, 0x08, + 0x03, 0x0b, 0x9b, + 0x05, 0x0e, 0x5b, + }; + +#if 0 + /* not yet tested */ + static __u8 lgdt3304_qam256_data[] = { + /* 16bit , 8bit */ + /* regs , val */ + 0x00, 0x00, 0x19, + 0x00, 0x12, 0x2a, + 0x00, 0x13, 0x80, + 0x00, 0x0d, 0x02, + 0x03, 0x14, 0xe3, + + 0x03, 0x0e, 0x1c, + 0x03, 0x08, 0x66, + 0x03, 0x09, 0x66, + 0x03, 0x0a, 0x08, + 0x03, 0x0b, 0x9b, + 0x03, 0x0d, 0x14, + 0x05, 0x0e, 0x5b, + }; +#endif + + /* tested with KWorld a340 */ + static __u8 lgdt3304_qam256_data[] = { + /* 16bit , 8bit */ + /* regs , val */ + 0x00, 0x00, 0x01, //0x19, + 0x00, 0x12, 0x2a, + 0x00, 0x13, 0x80, + 0x00, 0x0d, 0x02, + 0x03, 0x14, 0xe3, + + 0x03, 0x0e, 0x1c, + 0x03, 0x08, 0x66, + 0x03, 0x09, 0x66, + 0x03, 0x0a, 0x08, + 0x03, 0x0b, 0x9b, + + 0x03, 0x0d, 0x14, + //0x05, 0x0e, 0x5b, + 0x01, 0x06, 0x4a, + 0x01, 0x07, 0x3d, + 0x01, 0x08, 0x70, + 0x01, 0x09, 0xa3, + + 0x05, 0x04, 0xfd, + + 0x00, 0x0d, 0x82, + + 0x05, 0x0e, 0x5b, + + 0x05, 0x0e, 0x5b, + + 0x00, 0x02, 0x9a, + + 0x00, 0x02, 0x9b, + + 0x00, 0x00, 0x01, + 0x00, 0x12, 0x2a, + 0x00, 0x13, 0x80, + 0x00, 0x0d, 0x02, + 0x03, 0x14, 0xe3, + + 0x03, 0x0e, 0x1c, + 0x03, 0x08, 0x66, + 0x03, 0x09, 0x66, + 0x03, 0x0a, 0x08, + 0x03, 0x0b, 0x9b, + + 0x03, 0x0d, 0x14, + 0x01, 0x06, 0x4a, + 0x01, 0x07, 0x3d, + 0x01, 0x08, 0x70, + 0x01, 0x09, 0xa3, + + 0x05, 0x04, 0xfd, + + 0x00, 0x0d, 0x82, + + 0x05, 0x0e, 0x5b, + }; + + struct lgdt3304_state *state = fe->demodulator_priv; + if (state->current_modulation != param->u.vsb.modulation) { + switch(param->u.vsb.modulation) { + case VSB_8: + err = i2c_write_demod_bytes(fe, lgdt3304_vsb8_data, + sizeof(lgdt3304_vsb8_data)); + break; + case QAM_64: + err = i2c_write_demod_bytes(fe, lgdt3304_qam64_data, + sizeof(lgdt3304_qam64_data)); + break; + case QAM_256: + err = i2c_write_demod_bytes(fe, lgdt3304_qam256_data, + sizeof(lgdt3304_qam256_data)); + break; + default: + break; + } + + if (err) { + printk("%s error setting modulation\n", __FUNCTION__); + } else { + state->current_modulation = param->u.vsb.modulation; + } + } + state->current_frequency = param->frequency; + + lgdt3304_soft_Reset(fe); + + + if (fe->ops.tuner_ops.set_params) + fe->ops.tuner_ops.set_params(fe, param); + + return 0; +} + +static int lgdt3304_init(struct dvb_frontend *fe) { + return 0; +} + +static int lgdt3304_sleep(struct dvb_frontend *fe) { + return 0; +} + + +static int lgdt3304_read_status(struct dvb_frontend *fe, fe_status_t *status) +{ + struct lgdt3304_state *state = fe->demodulator_priv; + int r011d; + int qam_lck; + + *status = 0; + dprintk("lgdt read status\n"); + + r011d = lgdt3304_i2c_read_reg(fe, 0x011d); + + dprintk("%02x\n", r011d); + + switch(state->current_modulation) { + case VSB_8: + if (r011d & 0x80) { + dprintk("VSB Locked\n"); + *status |= FE_HAS_CARRIER; + *status |= FE_HAS_LOCK; + *status |= FE_HAS_SYNC; + *status |= FE_HAS_SIGNAL; + } + break; + case QAM_64: + case QAM_256: + qam_lck = r011d & 0x7; + switch(qam_lck) { + case 0x0: dprintk("Unlock\n"); + break; + case 0x4: dprintk("1st Lock in acquisition state\n"); + break; + case 0x6: dprintk("2nd Lock in acquisition state\n"); + break; + case 0x7: dprintk("Final Lock in good reception state\n"); + *status |= FE_HAS_CARRIER; + *status |= FE_HAS_LOCK; + *status |= FE_HAS_SYNC; + *status |= FE_HAS_SIGNAL; + break; + } + break; + default: + printk("%s unhandled modulation\n", __FUNCTION__); + } + + + return 0; +} + +static int lgdt3304_read_ber(struct dvb_frontend *fe, __u32 *ber) +{ + dprintk("read ber\n"); + return 0; +} + +static int lgdt3304_read_snr(struct dvb_frontend *fe, __u16 *snr) +{ + dprintk("read snr\n"); + return 0; +} + +static int lgdt3304_read_ucblocks(struct dvb_frontend *fe, __u32 *ucblocks) +{ + dprintk("read ucblocks\n"); + return 0; +} + +static void lgdt3304_release(struct dvb_frontend *fe) +{ + struct lgdt3304_state *state = (struct lgdt3304_state *)fe->demodulator_priv; + kfree(state); +} + +static struct dvb_frontend_ops demod_lgdt3304={ + .info = { + .name = "LG 3304", + .type = FE_ATSC, + .frequency_min = 54000000, + .frequency_max = 858000000, + .frequency_stepsize = 62500, + .symbol_rate_min = 5056941, + .symbol_rate_max = 10762000, + .caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB + }, + .init = lgdt3304_init, + .sleep = lgdt3304_sleep, + .set_frontend = lgdt3304_set_parameters, + .read_snr = lgdt3304_read_snr, + .read_ber = lgdt3304_read_ber, + .read_status = lgdt3304_read_status, + .read_ucblocks = lgdt3304_read_ucblocks, + .release = lgdt3304_release, +}; + +struct dvb_frontend* lgdt3304_attach(const struct lgdt3304_config *config, + struct i2c_adapter *i2c) +{ + + struct lgdt3304_state *state; + state = kzalloc(sizeof(struct lgdt3304_state), GFP_KERNEL); + memset(state, 0x0, sizeof(struct lgdt3304_state)); + state->addr = config->i2c_address; + state->i2c = i2c; + + memcpy(&state->frontend.ops, &demod_lgdt3304, sizeof(struct dvb_frontend_ops)); + state->frontend.demodulator_priv = state; + return &state->frontend; +} + +EXPORT_SYMBOL_GPL(lgdt3304_attach); +MODULE_AUTHOR("Markus Rechberger "); +MODULE_DESCRIPTION("LGE LGDT3304 DVB-T demodulator driver"); +MODULE_LICENSE("GPL"); diff --git a/linux/drivers/media/dvb/frontends/lgdt3304.h b/linux/drivers/media/dvb/frontends/lgdt3304.h new file mode 100644 index 000000000..fc409fe59 --- /dev/null +++ b/linux/drivers/media/dvb/frontends/lgdt3304.h @@ -0,0 +1,45 @@ +/* + * Driver for DVB-T lgdt3304 demodulator + * + * Copyright (C) 2008 Markus Rechberger + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.= + */ + +#ifndef LGDT3304_H +#define LGDT3304_H + +#include + +struct lgdt3304_config +{ + /* demodulator's I2C address */ + u8 i2c_address; +}; + +#if defined(CONFIG_DVB_LGDT3304) || (defined(CONFIG_DVB_LGDT3304_MODULE) && defined(MODULE)) +extern struct dvb_frontend* lgdt3304_attach(const struct lgdt3304_config *config, + struct i2c_adapter *i2c); +#else +static inline struct dvb_frontend* lgdt3304_attach(const struct lgdt3304_config *config, + struct i2c_adapter *i2c) +{ + printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); + return NULL; +} +#endif /* CONFIG_DVB_LGDT */ + +#endif /* LGDT3304_H */ diff --git a/linux/drivers/media/video/empia/lgdt3304/Makefile b/linux/drivers/media/video/empia/lgdt3304/Makefile deleted file mode 100644 index 4d261a762..000000000 --- a/linux/drivers/media/video/empia/lgdt3304/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -lgdt3304-demod-objs := lgdt3304.o - -obj-m += lgdt3304-demod.o - -EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core -EXTRA_CFLAGS += -Idrivers/media/dvb/frontends -EXTRA_CFLAGS += -DCONFIG_DVB_LGDT3304 diff --git a/linux/drivers/media/video/empia/lgdt3304/lgdt3304.c b/linux/drivers/media/video/empia/lgdt3304/lgdt3304.c deleted file mode 100644 index 1e8867b15..000000000 --- a/linux/drivers/media/video/empia/lgdt3304/lgdt3304.c +++ /dev/null @@ -1,398 +0,0 @@ -/* - * Driver for LG ATSC lgdt3304 driver - * - * Copyright (C) 2008 Markus Rechberger - * - */ - -#include -#include -#include -#include "dvb_frontend.h" -#include "lgdt3304.h" - -static unsigned int debug = 0; -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug,"lgdt3304 debugging (default off)"); - -#define dprintk(fmt, args...) if (debug) do {\ - printk("lgdt3304 debug: " fmt, ##args); } while (0) - -struct lgdt3304_state -{ - struct dvb_frontend frontend; - fe_modulation_t current_modulation; - __u32 snr; - __u32 current_frequency; - __u8 addr; - struct i2c_adapter *i2c; -}; - -static int i2c_write_demod_bytes (struct dvb_frontend *fe, __u8 *buf, int len) -{ - struct lgdt3304_state *state = fe->demodulator_priv; - struct i2c_msg i2cmsgs = { - .addr = state->addr, - .flags = 0, - .len = 3, - .buf = buf - }; - int i; - int err; - - for (i=0; ii2c, &i2cmsgs, 1))<0) { - printk("%s i2c_transfer error %d\n", __FUNCTION__, err); - if (err < 0) - return err; - else - return -EREMOTEIO; - } - i2cmsgs.buf += 3; - } - return 0; -} - -static int lgdt3304_i2c_read_reg(struct dvb_frontend *fe, unsigned int reg) -{ - struct lgdt3304_state *state = fe->demodulator_priv; - struct i2c_msg i2cmsgs[2]; - int ret; - __u8 buf; - - __u8 regbuf[2] = { reg>>8, reg&0xff }; - - i2cmsgs[0].addr = state->addr; - i2cmsgs[0].flags = 0; - i2cmsgs[0].len = 2; - i2cmsgs[0].buf = regbuf; - - i2cmsgs[1].addr = state->addr; - i2cmsgs[1].flags = I2C_M_RD; - i2cmsgs[1].len = 1; - i2cmsgs[1].buf = &buf; - - if((ret = i2c_transfer(state->i2c, i2cmsgs, 2))<0) { - printk("%s i2c_transfer error %d\n", __FUNCTION__, ret); - return ret; - } - - return buf; -} - -static int lgdt3304_i2c_write_reg(struct dvb_frontend *fe, int reg, int val) -{ - struct lgdt3304_state *state = fe->demodulator_priv; - char buffer[3] = { reg>>8, reg&0xff, val }; - int ret; - - struct i2c_msg i2cmsgs = { - .addr = state->addr, - .flags = 0, - .len = 3, - .buf=buffer - }; - ret = i2c_transfer(state->i2c, &i2cmsgs, 1); - if (ret != 1) { - printk("%s i2c_transfer error %d\n", __FUNCTION__, ret); - return ret; - } - - return 0; -} - - -static int lgdt3304_soft_Reset(struct dvb_frontend *fe) -{ - lgdt3304_i2c_write_reg(fe, 0x0002, 0x9a); - lgdt3304_i2c_write_reg(fe, 0x0002, 0x9b); - mdelay(200); - return 0; -} - -static int lgdt3304_set_parameters(struct dvb_frontend *fe, struct dvb_frontend_parameters *param) { - int err = 0; - - static __u8 lgdt3304_vsb8_data[] = { - /* 16bit , 8bit */ - /* regs , val */ - 0x00, 0x00, 0x02, - 0x00, 0x00, 0x13, - 0x00, 0x0d, 0x02, - 0x00, 0x0e, 0x02, - 0x00, 0x12, 0x32, - 0x00, 0x13, 0xc4, - 0x01, 0x12, 0x17, - 0x01, 0x13, 0x15, - 0x01, 0x14, 0x18, - 0x01, 0x15, 0xff, - 0x01, 0x16, 0x2c, - 0x02, 0x14, 0x67, - 0x02, 0x24, 0x8d, - 0x04, 0x27, 0x12, - 0x04, 0x28, 0x4f, - 0x03, 0x08, 0x80, - 0x03, 0x09, 0x00, - 0x03, 0x0d, 0x00, - 0x03, 0x0e, 0x1c, - 0x03, 0x14, 0xe1, - 0x05, 0x0e, 0x5b, - }; - - /* not yet tested .. */ - static __u8 lgdt3304_qam64_data[] = { - /* 16bit , 8bit */ - /* regs , val */ - 0x00, 0x00, 0x18, - 0x00, 0x0d, 0x02, - //0x00, 0x0e, 0x02, - 0x00, 0x12, 0x2a, - 0x00, 0x13, 0x00, - 0x03, 0x14, 0xe3, - 0x03, 0x0e, 0x1c, - 0x03, 0x08, 0x66, - 0x03, 0x09, 0x66, - 0x03, 0x0a, 0x08, - 0x03, 0x0b, 0x9b, - 0x05, 0x0e, 0x5b, - }; - -#if 0 - /* not yet tested */ - static __u8 lgdt3304_qam256_data[] = { - /* 16bit , 8bit */ - /* regs , val */ - 0x00, 0x00, 0x19, - 0x00, 0x12, 0x2a, - 0x00, 0x13, 0x80, - 0x00, 0x0d, 0x02, - 0x03, 0x14, 0xe3, - - 0x03, 0x0e, 0x1c, - 0x03, 0x08, 0x66, - 0x03, 0x09, 0x66, - 0x03, 0x0a, 0x08, - 0x03, 0x0b, 0x9b, - 0x03, 0x0d, 0x14, - 0x05, 0x0e, 0x5b, - }; -#endif - - /* tested with KWorld a340 */ - static __u8 lgdt3304_qam256_data[] = { - /* 16bit , 8bit */ - /* regs , val */ - 0x00, 0x00, 0x01, //0x19, - 0x00, 0x12, 0x2a, - 0x00, 0x13, 0x80, - 0x00, 0x0d, 0x02, - 0x03, 0x14, 0xe3, - - 0x03, 0x0e, 0x1c, - 0x03, 0x08, 0x66, - 0x03, 0x09, 0x66, - 0x03, 0x0a, 0x08, - 0x03, 0x0b, 0x9b, - - 0x03, 0x0d, 0x14, - //0x05, 0x0e, 0x5b, - 0x01, 0x06, 0x4a, - 0x01, 0x07, 0x3d, - 0x01, 0x08, 0x70, - 0x01, 0x09, 0xa3, - - 0x05, 0x04, 0xfd, - - 0x00, 0x0d, 0x82, - - 0x05, 0x0e, 0x5b, - - 0x05, 0x0e, 0x5b, - - 0x00, 0x02, 0x9a, - - 0x00, 0x02, 0x9b, - - 0x00, 0x00, 0x01, - 0x00, 0x12, 0x2a, - 0x00, 0x13, 0x80, - 0x00, 0x0d, 0x02, - 0x03, 0x14, 0xe3, - - 0x03, 0x0e, 0x1c, - 0x03, 0x08, 0x66, - 0x03, 0x09, 0x66, - 0x03, 0x0a, 0x08, - 0x03, 0x0b, 0x9b, - - 0x03, 0x0d, 0x14, - 0x01, 0x06, 0x4a, - 0x01, 0x07, 0x3d, - 0x01, 0x08, 0x70, - 0x01, 0x09, 0xa3, - - 0x05, 0x04, 0xfd, - - 0x00, 0x0d, 0x82, - - 0x05, 0x0e, 0x5b, - }; - - struct lgdt3304_state *state = fe->demodulator_priv; - if (state->current_modulation != param->u.vsb.modulation) { - switch(param->u.vsb.modulation) { - case VSB_8: - err = i2c_write_demod_bytes(fe, lgdt3304_vsb8_data, - sizeof(lgdt3304_vsb8_data)); - break; - case QAM_64: - err = i2c_write_demod_bytes(fe, lgdt3304_qam64_data, - sizeof(lgdt3304_qam64_data)); - break; - case QAM_256: - err = i2c_write_demod_bytes(fe, lgdt3304_qam256_data, - sizeof(lgdt3304_qam256_data)); - break; - default: - break; - } - - if (err) { - printk("%s error setting modulation\n", __FUNCTION__); - } else { - state->current_modulation = param->u.vsb.modulation; - } - } - state->current_frequency = param->frequency; - - lgdt3304_soft_Reset(fe); - - - if (fe->ops.tuner_ops.set_params) - fe->ops.tuner_ops.set_params(fe, param); - - return 0; -} - -static int lgdt3304_init(struct dvb_frontend *fe) { - return 0; -} - -static int lgdt3304_sleep(struct dvb_frontend *fe) { - return 0; -} - - -static int lgdt3304_read_status(struct dvb_frontend *fe, fe_status_t *status) -{ - struct lgdt3304_state *state = fe->demodulator_priv; - int r011d; - int qam_lck; - - *status = 0; - dprintk("lgdt read status\n"); - - r011d = lgdt3304_i2c_read_reg(fe, 0x011d); - - dprintk("%02x\n", r011d); - - switch(state->current_modulation) { - case VSB_8: - if (r011d & 0x80) { - dprintk("VSB Locked\n"); - *status |= FE_HAS_CARRIER; - *status |= FE_HAS_LOCK; - *status |= FE_HAS_SYNC; - *status |= FE_HAS_SIGNAL; - } - break; - case QAM_64: - case QAM_256: - qam_lck = r011d & 0x7; - switch(qam_lck) { - case 0x0: dprintk("Unlock\n"); - break; - case 0x4: dprintk("1st Lock in acquisition state\n"); - break; - case 0x6: dprintk("2nd Lock in acquisition state\n"); - break; - case 0x7: dprintk("Final Lock in good reception state\n"); - *status |= FE_HAS_CARRIER; - *status |= FE_HAS_LOCK; - *status |= FE_HAS_SYNC; - *status |= FE_HAS_SIGNAL; - break; - } - break; - default: - printk("%s unhandled modulation\n", __FUNCTION__); - } - - - return 0; -} - -static int lgdt3304_read_ber(struct dvb_frontend *fe, __u32 *ber) -{ - dprintk("read ber\n"); - return 0; -} - -static int lgdt3304_read_snr(struct dvb_frontend *fe, __u16 *snr) -{ - dprintk("read snr\n"); - return 0; -} - -static int lgdt3304_read_ucblocks(struct dvb_frontend *fe, __u32 *ucblocks) -{ - dprintk("read ucblocks\n"); - return 0; -} - -static void lgdt3304_release(struct dvb_frontend *fe) -{ - struct lgdt3304_state *state = (struct lgdt3304_state *)fe->demodulator_priv; - kfree(state); -} - -static struct dvb_frontend_ops demod_lgdt3304={ - .info = { - .name = "LG 3304", - .type = FE_ATSC, - .frequency_min = 54000000, - .frequency_max = 858000000, - .frequency_stepsize = 62500, - .symbol_rate_min = 5056941, - .symbol_rate_max = 10762000, - .caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB - }, - .init = lgdt3304_init, - .sleep = lgdt3304_sleep, - .set_frontend = lgdt3304_set_parameters, - .read_snr = lgdt3304_read_snr, - .read_ber = lgdt3304_read_ber, - .read_status = lgdt3304_read_status, - .read_ucblocks = lgdt3304_read_ucblocks, - .release = lgdt3304_release, -}; - -struct dvb_frontend* lgdt3304_attach(const struct lgdt3304_config *config, - struct i2c_adapter *i2c) -{ - - struct lgdt3304_state *state; - state = kzalloc(sizeof(struct lgdt3304_state), GFP_KERNEL); - memset(state, 0x0, sizeof(struct lgdt3304_state)); - state->addr = config->i2c_address; - state->i2c = i2c; - - memcpy(&state->frontend.ops, &demod_lgdt3304, sizeof(struct dvb_frontend_ops)); - state->frontend.demodulator_priv = state; - return &state->frontend; -} - -EXPORT_SYMBOL_GPL(lgdt3304_attach); -MODULE_AUTHOR("Markus Rechberger "); -MODULE_DESCRIPTION("LGE LGDT3304 DVB-T demodulator driver"); -MODULE_LICENSE("GPL"); diff --git a/linux/drivers/media/video/empia/lgdt3304/lgdt3304.h b/linux/drivers/media/video/empia/lgdt3304/lgdt3304.h deleted file mode 100644 index fc409fe59..000000000 --- a/linux/drivers/media/video/empia/lgdt3304/lgdt3304.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Driver for DVB-T lgdt3304 demodulator - * - * Copyright (C) 2008 Markus Rechberger - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.= - */ - -#ifndef LGDT3304_H -#define LGDT3304_H - -#include - -struct lgdt3304_config -{ - /* demodulator's I2C address */ - u8 i2c_address; -}; - -#if defined(CONFIG_DVB_LGDT3304) || (defined(CONFIG_DVB_LGDT3304_MODULE) && defined(MODULE)) -extern struct dvb_frontend* lgdt3304_attach(const struct lgdt3304_config *config, - struct i2c_adapter *i2c); -#else -static inline struct dvb_frontend* lgdt3304_attach(const struct lgdt3304_config *config, - struct i2c_adapter *i2c) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return NULL; -} -#endif /* CONFIG_DVB_LGDT */ - -#endif /* LGDT3304_H */ -- cgit v1.2.3 From 103b617eb24dcf2f7327af653375e417197c046c Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 25 Oct 2008 00:07:57 -0200 Subject: VBI fix for cx88 cards From: Rafael Diniz The attached patch fix VBI support cx88 card. I'm running a capture for hours, getting the closed caption from it[1], and it's working perfect - the output is the same of a bttv card. Please apply this patch as soon as possible. [1] - using zvbi-ntsc-cc of zvbi project. Signed-off-by: Rafael Diniz Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/cx88/cx88-video.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/linux/drivers/media/video/cx88/cx88-video.c b/linux/drivers/media/video/cx88/cx88-video.c index 6250bc8bd..40136a431 100644 --- a/linux/drivers/media/video/cx88/cx88-video.c +++ b/linux/drivers/media/video/cx88/cx88-video.c @@ -1453,8 +1453,12 @@ static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i) struct cx8800_fh *fh = priv; struct cx8800_dev *dev = fh->dev; - if (unlikely(fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)) + /* We should remember that this driver also supports teletext, */ + /* so we have to test if the v4l2_buf_type is VBI capture data. */ + if (unlikely((fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) && + (fh->type != V4L2_BUF_TYPE_VBI_CAPTURE))) return -EINVAL; + if (unlikely(i != fh->type)) return -EINVAL; @@ -1469,8 +1473,10 @@ static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i) struct cx8800_dev *dev = fh->dev; int err, res; - if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + if ((fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) && + (fh->type != V4L2_BUF_TYPE_VBI_CAPTURE)) return -EINVAL; + if (i != fh->type) return -EINVAL; -- cgit v1.2.3 From aac51a768ccbeb3ad7fc2ed795b3c376ee7934d2 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 22 Oct 2008 21:02:09 +0000 Subject: Documentation update for cx88 From: Rafael Diniz Attached is a patch that updates the cx88 documentation to add the fact the closed caption works for at least NTSC capture. ps: I also updated the wiki at: http://www.linuxtv.org/v4lwiki/index.php/Text_capture#cx88_devices Signed-off-by: Rafael Diniz Signed-off-by: Mauro Carvalho Chehab --- linux/Documentation/video4linux/README.cx88 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/linux/Documentation/video4linux/README.cx88 b/linux/Documentation/video4linux/README.cx88 index 06a33a4f5..166d5960b 100644 --- a/linux/Documentation/video4linux/README.cx88 +++ b/linux/Documentation/video4linux/README.cx88 @@ -27,8 +27,8 @@ audio sound card) should be possible, but there is no code yet ... vbi - - some code present. Doesn't crash any more, but also doesn't - work yet ... + - Code present. Works for NTSC closed caption. PAL and other + TV norms may or may not work. how to add support for new cards -- cgit v1.2.3 From 9a7a51209584be9da3ae6f0628885b4fb4f137ae Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 25 Oct 2008 00:13:57 -0200 Subject: Update README.cx88 with the current status From: Mauro Carvalho Chehab README.cx88 were outdated since a long time. Update it with the current status. Priority: normal Signed-off-by: Mauro Carvalho Chehab CC: Rafael Diniz --- linux/Documentation/video4linux/README.cx88 | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/linux/Documentation/video4linux/README.cx88 b/linux/Documentation/video4linux/README.cx88 index 166d5960b..35fae23f8 100644 --- a/linux/Documentation/video4linux/README.cx88 +++ b/linux/Documentation/video4linux/README.cx88 @@ -1,4 +1,3 @@ - cx8800 release notes ==================== @@ -10,21 +9,20 @@ current status video - Basically works. - - Some minor image quality glitches. - - For now only capture, overlay support isn't completed yet. + - For now, only capture and read(). Overlay isn't supported. audio - The chip specs for the on-chip TV sound decoder are next to useless :-/ - Neverless the builtin TV sound decoder starts working now, - at least for PAL-BG. Other TV norms need other code ... + at least for some standards. FOR ANY REPORTS ON THIS PLEASE MENTION THE TV NORM YOU ARE USING. - Most tuner chips do provide mono sound, which may or may not be useable depending on the board design. With the Hauppauge cards it works, so there is mono sound available as fallback. - audio data dma (i.e. recording without loopback cable to the - sound card) should be possible, but there is no code yet ... + sound card) is supported via cx88-alsa. vbi - Code present. Works for NTSC closed caption. PAL and other -- cgit v1.2.3 From b12831a462e695841ace55e08ac956e6724ab496 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 24 Oct 2008 20:45:34 +0000 Subject: compat code: Fix compile failure of av7110.c on Kernel 2.6.27 From: Matthias Schwarzott av7110.c does not compile against a 2.6.27 kernel, as the inclusion of linux/byteorder/swabb.h is now conditional with But the byteorder changes in kernel took place after Kernel 2.6.27, so the compat code needs to look like this: Signed-off-by: Matthias Schwarzott Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/dvb/ttpci/av7110.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linux/drivers/media/dvb/ttpci/av7110.c b/linux/drivers/media/dvb/ttpci/av7110.c index 2ef9f030f..b99057a68 100644 --- a/linux/drivers/media/dvb/ttpci/av7110.c +++ b/linux/drivers/media/dvb/ttpci/av7110.c @@ -52,7 +52,7 @@ #include #include #include -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 27) +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 28) #include #endif -- cgit v1.2.3 From 122f8ca9fc2a1fb872708d4135f09d68585e7f0c Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Fri, 24 Oct 2008 18:08:28 +0000 Subject: Minor fixes to the saa7110 driver From: Jean Delvare * Apparently the author of the saa7110 driver was confused by the number of outputs returned by DECODER_GET_CAPABILITIES. Of course a decoder chip has no analog ouputs, but it must have at least one digital output. * Fix an off-by-one error when checking the input value of DECODER_SET_INPUT. Signed-off-by: Jean Delvare Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/saa7110.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/linux/drivers/media/video/saa7110.c b/linux/drivers/media/video/saa7110.c index 15eb8bd7a..b7afe3124 100644 --- a/linux/drivers/media/video/saa7110.c +++ b/linux/drivers/media/video/saa7110.c @@ -48,7 +48,7 @@ module_param(debug, int, 0); MODULE_PARM_DESC(debug, "Debug level (0-1)"); #define SAA7110_MAX_INPUT 9 /* 6 CVBS, 3 SVHS */ -#define SAA7110_MAX_OUTPUT 0 /* its a decoder only */ +#define SAA7110_MAX_OUTPUT 1 /* 1 YUV */ #define SAA7110_NR_REG 0x35 @@ -328,7 +328,7 @@ saa7110_command (struct i2c_client *client, case DECODER_SET_INPUT: v = *(int *) arg; - if (v < 0 || v > SAA7110_MAX_INPUT) { + if (v < 0 || v >= SAA7110_MAX_INPUT) { v4l_dbg(1, debug, client, "input=%d not available\n", v); return -EINVAL; } -- cgit v1.2.3 From 3c1b08410ee59c3b4f2ce840babb09c5a3beebd2 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 25 Oct 2008 01:21:57 -0200 Subject: Improve make install to work properly with a distro that use non-standard dir for V4L/DVB modules From: Mauro Carvalho Chehab One distro stores kernel/drivers/media files on non-standard dirs. I can't see any logical rule for, once having the kernel original dir position, determine were the kernel driver were placed on that distro. For example, they put xc5000.ko driver inside /media/au0828, while the expected place would be something like /media/common/tuners. So, this patch do some tricks, when "make rminstall" or "make install" is called: 1) detect if it is such distro; 2) if so, it will run something like: find /media -name -exec rm '{}' \; where is the official V4L/DVB name for the compiled modules, and is the distro non-standard dir. This should remove the new V4L/DVB .ko modules that are located at the non-standard dir or inside one of its sub-directories. NOTICE: If there are other V4L/DVB drivers there that (1) aren't inside V4L/DVB tree; (2) weren't selected to compile; then those drivers will likely stop working. This patch doesn't affect the other distros. Priority: normal Signed-off-by: Mauro Carvalho Chehab --- v4l/scripts/make_makefile.pl | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/v4l/scripts/make_makefile.pl b/v4l/scripts/make_makefile.pl index 82821b43b..ac1b6cac0 100755 --- a/v4l/scripts/make_makefile.pl +++ b/v4l/scripts/make_makefile.pl @@ -157,6 +157,33 @@ sub removeobsolete() } } +# +# Special hack for Ubuntu with their backport mess +# +sub removeubuntu() +{ + my $dest = "/lib/modules/\$(KERNELRELEASE)/ubuntu/media"; + my $filelist; + + while ( my ($dir, $files) = each(%instdir) ) { + $filelist .= join(' ', keys %$files); + } + while ( my ($dir, $files) = each(%obsolete) ) { + $filelist .= join(' ', keys %$files); + } + $filelist =~ s/\s+$//; + + print OUT "\t\@if [ -d $dest ]; then "; + print OUT "printf \"\\nHmm... distro kernel with a non-standard place for module backports detected.\\n"; + print OUT "Please always prefer to use vanilla upstream kernel with V4L/DVB\\n"; + print OUT "I'll try to remove old/obsolete LUM files from $dest:\\n\"; "; + print OUT "files='", $filelist, "'; "; + + print OUT "for i in \$\$files;do find \"$dest\" \-name \"\$\$i\" \-exec echo \'{}\' \';\' ;"; + print OUT " find \"$dest\" \-name \"\$\$i\" \-exec rm \'{}\' \';\' ;"; + print OUT " done;"; + print OUT " fi\n"; +} getobsolete(); @@ -169,6 +196,7 @@ print OUT "\t\@echo \"Stripping debug info from files\"\n"; print OUT "\t\@strip --strip-debug \$(inst-m)\n\n"; removeobsolete(); +removeubuntu(); print OUT "\t\@echo \"Installing kernel modules under \$(DESTDIR)\$(KDIR26)/:\"\n"; @@ -191,8 +219,8 @@ print OUT "\t/sbin/depmod -a \$(KERNELRELEASE) \$(if \$(DESTDIR),-b \$(DESTDIR)) print OUT "media-rminstall::\n"; removeobsolete(); +removeubuntu(); -print OUT "\t\@echo -e \"\\nRemoving old \$(DEST) files\\n\"\n"; while ( my ($dir, $files) = each(%instdir) ) { print OUT "\t\@echo -e \"\\nRemoving old \$(KDIR26)/$dir files:\"\n"; print OUT "\t\@files='", join(' ', keys %$files), "'; "; -- cgit v1.2.3 From f46b85426d01f8ce77fd9a4a036cc0345ae1c4be Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 25 Oct 2008 01:34:37 -0200 Subject: A small improvement at a comment added on the latest patch From: Mauro Carvalho Chehab Priority: normal Signed-off-by: Mauro Carvalho Chehab --- v4l/scripts/make_makefile.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/v4l/scripts/make_makefile.pl b/v4l/scripts/make_makefile.pl index ac1b6cac0..ce6f00516 100755 --- a/v4l/scripts/make_makefile.pl +++ b/v4l/scripts/make_makefile.pl @@ -158,7 +158,7 @@ sub removeobsolete() } # -# Special hack for Ubuntu with their backport mess +# Special hack for Ubuntu with their non-standard dir # sub removeubuntu() { -- cgit v1.2.3