[2.6][0/14] DVB subsystem update
Subsystems (2)
PATCH 1/1 [2.6][0/14] DVB subsystem update
Hi there,
here comes a patchset consisting of 14 patches bringing the in-kernel DVB subsystem in sync with the LinuxTV.org CVS driver.
The most important changes include:
- remove non-linux compatibility stuff
- remove home-brewn dvb-i2c stuff, use kernel-i2c instead
- convert home-brewn bttv i2c access drivers to real bttv sub-drivers
- add new driver for mobile USB Budget DVB-T devices by DiBcom
- add new drivers for Zarlink DVB-T MT352 frontend, Conexant 22702 DVB OFDM frontend and DVB-T demodulator DiBcom 3000-MB frontend
- plus lots of other changes, explained in the top of each patch.
Please apply. Thanks!
Regards.
Michael Hunold.
PATCH 1/1 [2.6][1/14] update saa7146 driver
- [DVB] uses msleep() instead of my_wait(), thanks to Kernel Janitors/Nishanth Aravamudan <[email protected]>
- [DVB] fix videodev has no release callback
- [DVB] use PAGE_SIZE for pagetables, not home-brewn SAA7146_PGTABLE_SIZE
- [DVB] use cpu_to_le32() at various places for endianess independency
- [DVB] turn some error checks into BUG()s
- [DVB] make saa7146_i2c_adapter_prepare() support an adapter class
- [DVB] add support for V4L2_PIX_FMT_RGB32 pixelformat
- [DVB] replace generic saa7146 i2c name by card specific name, suggested by Uli Luckas <[email protected]>
drivers/media/common/saa7146_core.c +4 -10
@@ -133,8 +133,6 @@/********************************************************************************/ /* common page table functions */ -#define SAA7146_PGTABLE_SIZE 4096 -char *saa7146_vmalloc_build_pgtable (struct pci_dev *pci,long length,struct saa7146_pgtable *pt) {int pages = (length+PAGE_SIZE -1 )/PAGE_SIZE ;
@@ -182,11 +180,11 @@u32 *cpu;dma_addr_t dma_addr; - cpu =pci_alloc_consistent (pci,SAA7146_PGTABLE_SIZE , &dma_addr); + cpu =pci_alloc_consistent (pci,PAGE_SIZE , &dma_addr);if (NULL == cpu) {return -ENOMEM ; } - pt->size =SAA7146_PGTABLE_SIZE ; + pt->size =PAGE_SIZE ; pt->cpu = cpu; pt->dma = dma_addr;
@@ -201,11 +199,7 @@int i,p;BUG_ON (0 == sglen); - -if (list->offset >PAGE_SIZE ) { -DEB_D (("offset > PAGE_SIZE. this should not happen." )); -return -EINVAL ; - } +BUG_ON (list->offset >PAGE_SIZE );/* if we have a user buffer, the first page may not be aligned to a page boundary. */
@@ -217,7 +211,7 @@printk("i:%d, adr:0x%08x, len:%d, offset:%d\n", i,sg_dma_address(list), sg_dma_len(list), list->offset); */ for (p =0 ; p *4096 < list->length; p++, ptr++) { - *ptr =sg_dma_address (list) + p *4096 ; + *ptr =cpu_to_le32 (sg_dma_address (list) + p *4096 ); nr_pages++; } }
drivers/media/common/saa7146_fops.c +29 -25
108 lines not on this page · raw message
drivers/media/common/saa7146_hlp.c +9 -8
@@ -413,10 +413,10 @@/* fill up cliptable */ for (i =0 ; i < cnt_pixel; i++) { - clipping[2 *i] |= (pixel_list[i] <<16 ); + clipping[2 *i] |=cpu_to_le32 (pixel_list[i] <<16 ); }for (i =0 ; i < cnt_line; i++) { - clipping[(2 *i)+1 ] |= (line_list[i] <<16 ); + clipping[(2 *i)+1 ] |=cpu_to_le32 (line_list[i] <<16 ); }/* fill up cliptable with the display infos */
@@ -430,7 +430,7 @@if ( pixel_list[i] < (x[j] + w[j])) {if ( pixel_list[i] >= x[j] ) { - clipping[2 *i] |= (1 << j); + clipping[2 *i] |=cpu_to_le32 (1 << j); } } }
@@ -442,7 +442,7 @@if ( line_list[i] < (y[j] + h[j]) ) {if ( line_list[i] >= y[j] ) { - clipping[(2 *i)+1 ] |= (1 << j); + clipping[(2 *i)+1 ] |=cpu_to_le32 (1 << j); } } }
@@ -560,9 +560,10 @@ }/* calculate the new memory offsets for a desired position */ -static void saa7146_set_position (struct saa7146_dev *dev,int w_x,int w_y,int w_height,enum v4l2_field field) +static void saa7146_set_position (struct saa7146_dev *dev,int w_x,int w_y,int w_height,enum v4l2_field field,u32 pixelformat) {struct saa7146_vv *vv = dev->vv_data; +struct saa7146_format *sfmt =format_by_fourcc (dev, pixelformat);int b_depth = vv->ov_fmt->depth;int b_bpl = vv->ov_fb.fmt.bytesperline;
@@ -601,7 +602,7 @@ vdma1.pitch *=-1 ; } - vdma1.base_page =0 ; + vdma1.base_page = sfmt->swap; vdma1.num_line_byte = (vv->standard->v_field<<16 )+vv->standard->h_pixels;saa7146_write_out_dma (dev,1 , &vdma1);
@@ -657,7 +658,7 @@struct saa7146_vv *vv = dev->vv_data;saa7146_set_window (dev, fh->ov.win.w.width, fh->ov.win.w.height, fh->ov.win.field); -saa7146_set_position (dev, fh->ov.win.w.left, fh->ov.win.w.top, fh->ov.win.w.height, fh->ov.win.field); +saa7146_set_position (dev, fh->ov.win.w.left, fh->ov.win.w.top, fh->ov.win.w.height, fh->ov.win.field, vv->ov_fmt->pixelformat);saa7146_set_output_format (dev, vv->ov_fmt->trans);saa7146_set_clipping_rect (fh);
@@ -727,7 +729,7 @@ vdma1.pitch = (width*depth*2 )/8 ; } vdma1.num_line_byte = ((vv->standard->v_field<<16 ) + vv->standard->h_pixels); - vdma1.base_page = buf->pt[0 ].dma |ME1 ; + vdma1.base_page = buf->pt[0 ].dma |ME1 | sfmt->swap;if (0 != vv->vflip ) { vdma1.prot_addr = buf->pt[0 ].offset;
drivers/media/common/saa7146_i2c.c +9 -18
@@ -1,13 +1,6 @@#include <linux/version.h> #include <media/saa7146_vv.h> -/* helper function */ -static void my_wait (struct saa7146_dev *dev,long ms) -{ -set_current_state (TASK_INTERRUPTIBLE ); -schedule_timeout ((((ms+10 )/10 )*HZ )/1000 ); -} -u32 saa7146_i2c_func (struct i2c_adapter *adapter) {//fm DEB_I2C(("'%s'.\n", adapter->name));
@@ -136,12 +129,12 @@/* set "ABORT-OPERATION"-bit (bit 7)*/ saa7146_write (dev,I2C_STATUS , (dev->i2c_bitrate |MASK_07 ));saa7146_write (dev,MC2 , (MASK_00 |MASK_16 )); -my_wait (dev,SAA7146_I2C_DELAY ); +msleep (SAA7146_I2C_DELAY );/* clear all error-bits pending; this is needed because p.123, note 1 */ saa7146_write (dev,I2C_STATUS , dev->i2c_bitrate);saa7146_write (dev,MC2 , (MASK_00 |MASK_16 )); -my_wait (dev,SAA7146_I2C_DELAY ); +msleep (SAA7146_I2C_DELAY ); }/* check if any error is (still) present. (this can be necessary because p.123, note 1) */
@@ -155,18 +148,18 @@after serious protocol errors caused by e.g. the SAA7740 */ saa7146_write (dev,I2C_STATUS , (dev->i2c_bitrate |MASK_07 ));saa7146_write (dev,MC2 , (MASK_00 |MASK_16 )); -my_wait (dev,SAA7146_I2C_DELAY ); +msleep (SAA7146_I2C_DELAY );/* clear all error-bits pending */ saa7146_write (dev,I2C_STATUS , dev->i2c_bitrate);saa7146_write (dev,MC2 , (MASK_00 |MASK_16 )); -my_wait (dev,SAA7146_I2C_DELAY ); +msleep (SAA7146_I2C_DELAY );/* the data sheet says it might be necessary to clear the status twice after an abort */ saa7146_write (dev,I2C_STATUS , dev->i2c_bitrate);saa7146_write (dev,MC2 , (MASK_00 |MASK_16 )); -my_wait (dev,SAA7146_I2C_DELAY ); +msleep (SAA7146_I2C_DELAY ); }/* if any error is still present, a fatal error has occured ... */
@@ -243,7 +236,7 @@if ((++trial <20 ) && short_delay)udelay (10 );else -my_wait (dev,1 ); +msleep (1 ); } }
@@ -345,7 +338,7 @@ }/* delay a bit before retrying */ -my_wait (dev,10 ); +msleep (10 ); }while (err != num && retries--);
@@ -400,7 +393,7 @@ .functionality = saa7146_i2c_func, }; -int saa7146_i2c_adapter_prepare (struct saa7146_dev *dev,struct i2c_adapter *i2c_adapter,unsigned int class,u32 bitrate) +int saa7146_i2c_adapter_prepare (struct saa7146_dev *dev,struct i2c_adapter *i2c_adapter,u32 bitrate) {DEB_EE (("bitrate: 0x%08x\n" ,bitrate));
@@ -411,13 +404,11 @@saa7146_i2c_reset (dev);if (NULL != i2c_adapter ) { -memset (i2c_adapter,0 ,sizeof (struct i2c_adapter )); -strcpy (i2c_adapter->name, dev->name);#if (LINUX_VERSION_CODE <KERNEL_VERSION (2 ,5 ,0 )) i2c_adapter->data = dev;#else +BUG_ON (!i2c_adapter->class);i2c_set_adapdata (i2c_adapter,dev); - i2c_adapter->class = class;#endif i2c_adapter->algo = &saa7146_algo; i2c_adapter->algo_data =NULL ;
drivers/media/common/saa7146_video.c +8 -1
@@ -38,6 +38,13 @@ .depth = 32, .flags = 0, }, { + .name = "RGB-32 (R-G-B)", + .pixelformat = V4L2_PIX_FMT_RGB32, + .trans = RGB32_COMPOSED, + .depth = 32, + .flags = 0, + .swap = 0x2, + }, { .name = "Greyscale-8", .pixelformat = V4L2_PIX_FMT_GREY, .trans = Y8,
@@ -634,7 +641,7 @@/* walk all pages, copy all page addresses to ptr1 */ for (i =0 ; i < length; i++, list++) {for (p =0 ; p *4096 < list->length; p++, ptr1++) { - *ptr1 =sg_dma_address (list) - list->offset; + *ptr1 =cpu_to_le32 (sg_dma_address (list) - list->offset); } }/*
include/media/saa7146.h +1 -1
@@ -154,7 +166,7 @@ };/* from saa7146_i2c.c */ -int saa7146_i2c_adapter_prepare (struct saa7146_dev *dev,struct i2c_adapter *i2c_adapter,unsigned int class,u32 bitrate); +int saa7146_i2c_adapter_prepare (struct saa7146_dev *dev,struct i2c_adapter *i2c_adapter,u32 bitrate);int saa7146_i2c_transfer (struct saa7146_dev *saa,const struct i2c_msg msgs[],int num,int retries);/* from saa7146_core.c */
include/media/saa7146_vv.h +3 -2
@@ -35,6 +35,7 @@u32 trans;u8 depth;u8 flags; +u8 swap; };struct saa7146_standard
@@ -188,8 +189,8 @@ };/* from saa7146_fops.c */ -int saa7146_register_device (struct video_device *vid,struct saa7146_dev * dev,char *name,int type); -int saa7146_unregister_device (struct video_device *vid,struct saa7146_dev * dev); +int saa7146_register_device (struct video_device **vid,struct saa7146_dev * dev,char *name,int type); +int saa7146_unregister_device (struct video_device **vid,struct saa7146_dev * dev);void saa7146_buffer_finish (struct saa7146_dev *dev,struct saa7146_dmaqueue *q,int state);void saa7146_buffer_next (struct saa7146_dev *dev,struct saa7146_dmaqueue *q,int vbi);int saa7146_buffer_queue (struct saa7146_dev *dev,struct saa7146_dmaqueue *q,struct saa7146_buf *buf);
Re: [PATCH][2.6][2/14] documentation update
- [DVB] add udev.txt which describes how to use dvb and udev/sysfs
- [DVB] add Visionplus VisionDTV USB-Ter DVB-T adapter documentation
- [DVB] update TT USB DEC documentation
- [DVB] update various Kconfig entries
#diff -uraNwB xx-linux-2.6.8.1/Documentation/dvb/cards.txt linux-2.6.8.1-patched/Documentation/dvb/cards.txt
Documentation/dvb/cards.txt +1 -1
@@ -49,7 +49,7 @@ - "budget" cards (i.e. without hardware MPEG decoder): - Technotrend Budget / Hauppauge WinTV-Nova PCI Cards - SATELCO Multimedia PCI - - KNC1 DVB-S + - KNC1 DVB-S, Typhoon DVB-S, Terratec Cinergy 1200 DVB-S (no CI support) - Typhoon DVB-S budget - Fujitsu-Siemens Activy DVB-S budget card
Documentation/dvb/contributors.txt +2 -0
@@ -69,6 +69,8 @@ Kenneth Aafl�y <[email protected]> for adding support for Typhoon DVB-S budget card +Ernst Peinlich <[email protected]> + for tuning/DiSEqC support for the DEC 3000-s (If you think you should be in this list, but you are not, drop a line to the DVB mailing list)
Documentation/dvb/firmware.txt +68 -28
144 lines not on this page · raw message
Documentation/dvb/readme.txt +7 -0
@@ -41,4 +41,11 @@ various bt8xx based "budget" DVB cards (Nebula, Pinnacle PCTV, Twinhan DST) +"vp7041.txt" +contains detailed informations about the +Visionplus VisionDTV USB-Ter DVB-T adapter. + +"udev.txt" +how to get DVB and udev up and running. + Good luck and have fun!
Documentation/dvb/ttusb-dec.txt +4 -5
@@ -6,6 +6,8 @@ Supported: DEC2000-t + DEC2450-t + DEC3000-s Linux Kernels 2.4 and 2.6 Video Streaming Audio Streaming
@@ -13,14 +15,11 @@ Channel Zapping Hotplug firmware loader under 2.6 kernels -In Progress: - DEC2540-t - DEC3000-s - To Do: Tuner status information DVB network interface Streaming video PC->DEC + Conax support for 2450-t Getting the Firmware --------------------
@@ -57,7 +56,7 @@ Hotplug Firmware Loading for 2.6 kernels ---------------------------------------- For 2.6 kernels the firmware is loaded at the point that the driver module is -loaded. See Documentation/dvb/firmware.txt for more information. +loaded. See linux/Documentation/dvb/firmware.txt for more information. mv STB_PC_T.bin /usr/lib/hotplug/firmware/dvb-ttusb-dec-2000t.fw mv STB_PC_X.bin /usr/lib/hotplug/firmware/dvb-ttusb-dec-2540t.fw
Documentation/dvb/udev.txt +46 -0
46 lines not on this page · raw message
Documentation/dvb/avermedia.txt +3 -23
@@ -6,7 +6,6 @@ Assumptions and Introduction The Avermedia DVB-T Getting the card going - Getting the Firmware Receiving DVB-T in Australia Known Limitations Further Update
@@ -149,28 +148,9 @@ to start accessing the card with utilities such as scan, tzap, dvbstream etc. - The current version of the frontend module sp887x.o, contains - no firmware drivers?, so the first time you open it with a DVB - utility the driver will try to download some initial firmware - to the card. You will need to download this firmware from the - web, or copy it from an installation of the Windows drivers - that probably came with your card, before you can use it. - - The default Linux filesystem location for this firmware is - /usr/lib/hotplug/firmware/sc_main.mc . - _________________________________________________________ - -Getting the Firmware - - As the firmware for the card is no longer contained within the - driver, it is necessary to extract it from the windows - drivers. - - The Windows drivers for the Avermedia DVB-T can be obtained - from: http://babyurl.com/H3U970 and you can get an application - to extract the firmware from: - http://www.kyz.uklinux.net/cabextract.php. - _________________________________________________________ + The frontend module sp887x.o, requires an external firmware. + Please use the command "get_dvb_firmware sp887x" to download + it. Then copy it to /usr/lib/hotplug/firmware. Receiving DVB-T in Australia
Documentation/dvb/cards.txt +6 -0
@@ -38,6 +38,7 @@ Comtech DVBT-6k07 (SP5730 PLL) (NxtWave Communications NXT6000 demodulator) - sp887x : Microtune 7202D + - dib3000mb : DiBcom 3000-MB Frontend DVB-S/C/T: - dst : TwinHan DST Frontend
@@ -66,4 +67,9 @@ - Nova USB - DEC 2000-T, 3000-S, 2540-T +o DiBcom DVB-T USB based devices: + - Twinhan VisionPlus VisionDTV USB-Ter DVB-T Device + - KWorld V-Stream XPERT DTV - DVB-T USB + - HAMA DVB-T USB device + o Experimental support for the analog module of the Siemens DVB-C PCI card
Documentation/dvb/firmware.txt +28 -68
144 lines not on this page · raw message
Documentation/dvb/get_dvb_firmware +339 -0
339 lines not on this page · raw message
Documentation/dvb/README.dibusb +152 -0
152 lines not on this page · raw message
Documentation/dvb/readme.txt +3 -3
@@ -28,9 +28,9 @@ "faq.txt" contains frequently asked questions and their answers. -"firmware.txt" -contains informations for required external firmware -files and where to get them. +"get_dvb_firmware" +script to download and extract firmware for those devices +that require it. "ttusb-dec.txt" contains detailed informations about the
Documentation/dvb/ttusb-dec.txt +6 -25
@@ -23,34 +23,17 @@ Getting the Firmware -------------------- -The firmware can be found in the software update zip files on this page: -http://www.hauppauge.de/sw_dec.htm - -The firmwares are named as follows: -DEC2000-t: STB_PC_T.bin -DEC2540-t: STB_PC_X.bin -DEC3000-s: STB_PC_S.bin - -Note that firmwares since version 2.16 beta2 for the DEC2000-t give the device -the USB ID of the DEC3000-s. The driver copes with this. - -Instructions follow for retrieving version 2.16 of the firmware: - -wget http://hauppauge.lightpath.net/de/dec216.exe -unzip -j dec216.exe software/OEM/STB/App/Boot/STB_PC_T.bin -unzip -j dec216.exe software/OEM/STB/App/Boot/STB_PC_X.bin -unzip -j dec216.exe software/OEM/STB/App/Boot/STB_PC_S.bin +To download the firmware, use the following commands: +"get_dvb_firmware dec2000t" +"get_dvb_firmware dec2540t" +"get_dvb_firmware dec3000s" Compilation Notes for 2.4 kernels --------------------------------- For 2.4 kernels the firmware for the DECs is compiled into the driver itself. -The firmwares are expected to be in the build-2.4 directory at compilation -time. -mv STB_PC_T.bin build-2.4/dvb-ttusb-dec-2000t.fw -mv STB_PC_X.bin build-2.4/dvb-ttusb-dec-2540t.fw -mv STB_PC_S.bin build-2.4/dvb-ttusb-dec-3000s.fw +Copy the three files downloaded above into the build-2.4 directory. Hotplug Firmware Loading for 2.6 kernels
@@ -58,6 +41,4 @@ For 2.6 kernels the firmware is loaded at the point that the driver module is loaded. See linux/Documentation/dvb/firmware.txt for more information. -mv STB_PC_T.bin /usr/lib/hotplug/firmware/dvb-ttusb-dec-2000t.fw -mv STB_PC_X.bin /usr/lib/hotplug/firmware/dvb-ttusb-dec-2540t.fw -mv STB_PC_S.bin /usr/lib/hotplug/firmware/dvb-ttusb-dec-3000s.fw +Copy the three files downloaded above into the /usr/lib/hotplug/firmware directory.
drivers/media/dvb/Kconfig +2 -10
@@ -12,20 +12,11 @@ own a DVB adapter and want to use it or if you compile Linux for a digital SetTopBox. - API specs and user tools are available from - <http://www.linuxtv.org/>. + API specs and user tools are available from <http://www.linuxtv.org/>. Please report problems regarding this driver to the LinuxDVB mailing list. - You might want add the following lines to your /etc/modules.conf: - - alias char-major-250 dvb - alias dvb dvb-ttpci - below dvb-ttpci alps_bsru6 alps_bsrv2 \ - grundig_29504-401 grundig_29504-491 \ - ves1820 - If unsure say N. source "drivers/media/dvb/dvb-core/Kconfig"
@@ -40,6 +31,7 @@ depends on DVB_CORE && USB source "drivers/media/dvb/ttusb-budget/Kconfig" source "drivers/media/dvb/ttusb-dec/Kconfig" +source "drivers/media/dvb/dibusb/Kconfig" comment "Supported FlexCopII (B2C2) Adapters" depends on DVB_CORE && PCI
drivers/media/dvb/ttusb-dec/Kconfig +5 -3
@@ -12,8 +12,10 @@ only compressed MPEG data over the USB bus, so you need an external software decoder to watch TV on your computer. - The DEC devices require firmware in order to boot into a mode in - which they are slaves to the PC. See - <file:Documentation/dvb/ttusb-dec.txt> for details. + This driver needs external firmware. Please use the commands + "<kerneldir>/Documentation/dvb/get_dvb_firmware dec2000t", + "<kerneldir>/Documentation/dvb/get_dvb_firmware dec2540t", + "<kerneldir>/Documentation/dvb/get_dvb_firmware dec3000s", + download/extract them, and then copy them to /usr/lib/hotplug/firmware. Say Y if you own such a device and want to use it.
drivers/media/dvb/ttpci/Kconfig +7 -1
@@ -11,11 +11,16 @@ This driver only supports the fullfeatured cards with onboard MPEG2 decoder. + This driver needs an external firmware. Please use the script + "<kerneldir>/Documentation/dvb/get_dvb_firmware av7110" to + download/extract it, and then copy it to /usr/lib/hotplug/firmware. + Say Y if you own such a card and want to use it. config DVB_AV7110_FIRMWARE bool "Compile AV7110 firmware into the driver" depends on DVB_AV7110 && !STANDALONE + default y if DVB_AV7110=y help The AV7110 firmware is normally loaded by the firmware hotplug manager. If you want to compile the firmware into the driver you need to say
@@ -33,6 +38,7 @@ config DVB_AV7110_OSD bool "AV7110 OSD support" depends on DVB_AV7110 + default y if DVB_AV7110=y || DVB_AV7110=m help The AV7110 firmware provides some code to generate an OnScreenDisplay on the video output. This is kind of nonstandard and not guaranteed to
@@ -91,7 +97,7 @@ config DVB_BUDGET_PATCH tristate "AV7110 cards with Budget Patch" - depends on DVB_BUDGET + depends on DVB_CORE && DVB_BUDGET select DVB_AV7110 help Support for Budget Patch (full TS) modification on
Re: [PATCH][2.6][3/14] dvb-bt8xx and skystar2 driver update
- [DVB] convert drivers from dvb-i2c to kernel-i2c
- [DVB] convert MODULE_PARM() to module_param()
- [DVB] convert dvb_delay() to mdelay()
- [DVB] dvb-bt8xx: convert home-brewn bttv i2c access to a real bttv sub-driver
drivers/media/dvb/b2c2/skystar2.c +76 -20
@@ -30,14 +30,16 @@* along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#include <linux/module.h> +#include <linux/moduleparam.h> #include <linux/delay.h> #include <linux/pci.h> #include <linux/init.h> +#include <linux/version.h> #include <asm/io.h> -#include "dvb_i2c.h" #include "dvb_frontend.h" #include <linux/dvb/frontend.h>
@@ -49,12 +51,17 @@#include "demux.h" #include "dvb_net.h" -#include "dvb_functions.h" -static int debug =0 ; +static int debug; +static int enable_hw_filters =2 ; + +module_param (debug, int,0644 ); +MODULE_PARM_DESC (debug,"Set debugging level (0 = default, 1 = most messages, 2 = all messages)." ); +module_param (enable_hw_filters, int,0444 ); +MODULE_PARM_DESC (enable_hw_filters,"enable hardware filters: supported values: 0 (none), 1, 2" ); + #define dprintk(x...) do { if (debug>=1) printk(x); } while (0) #define ddprintk(x...) do { if (debug>=2) printk(x); } while (0) -static int enable_hw_filters =2 ;#define SIZE_OF_BUF_DMA1 0x3ac00#define SIZE_OF_BUF_DMA2 0x758
@@ -89,7 +96,7 @@struct dmxdev dmxdev;struct dmx_frontend hw_frontend;struct dmx_frontend mem_frontend; -struct dvb_i2c_bus *i2c_bus; +struct i2c_adapter i2c_adap;struct dvb_net dvbnet;struct semaphore i2c_sem;
@@ -277,9 +284,9 @@return buf - start; } -static int master_xfer (struct dvb_i2c_bus *i2c,const struct i2c_msg *msgs,int num) +static int master_xfer (struct i2c_adapter * adapter,struct i2c_msg msgs[],int num) { -struct adapter *tmp = i2c->data; +struct adapter *tmp =i2c_get_adapdata (adapter);int i, ret =0 ;if (down_interruptible (&tmp->i2c_sem))
@@ -291,10 +298,10 @@ddprintk ("message %d: flags=0x%x, addr=0x%x, buf=0x%x, len=%d \n" , i, msgs[i].flags, msgs[i].addr, msgs[i].buf[0 ], msgs[i].len); -/* allow only the mt312 and stv0299 frontends to access the bus */ -if ((msgs[i].addr !=0x0e ) && (msgs[i].addr !=0x68 ) && (msgs[i].addr !=0x61 )) { +/* allow only the mt312, mt352 and stv0299 frontends to access the bus */ +if ((msgs[i].addr !=0x0e ) && (msgs[i].addr !=0x68 ) && + (msgs[i].addr !=0x61 ) && (msgs[i].addr !=0x0f )) {up (&tmp->i2c_sem); -return -EREMOTEIO ; } }
@@ -2122,7 +2128,7 @@udelay (12500 );set_tuner_tone (adapter,0 ); } -dvb_delay (20 ); +msleep (20 ); }return 0 ;
@@ -2228,6 +2235,44 @@return 0 ; } + +int client_register (struct i2c_client *client) +{ +struct adapter *adapter = (struct adapter *)i2c_get_adapdata (client->adapter); + +dprintk ("client_register\n" ); + +if (client->driver->command) +return client->driver->command (client,FE_REGISTER , adapter->dvb_adapter); +return 0 ; +} + +int client_unregister (struct i2c_client *client) +{ +struct adapter *adapter = (struct adapter *)i2c_get_adapdata (client->adapter); + +dprintk ("client_unregister\n" ); + +if (client->driver->command) +return client->driver->command (client,FE_UNREGISTER , adapter->dvb_adapter); +return 0 ; +} + +u32 flexcop_i2c_func (struct i2c_adapter *adapter) +{ +printk ("flexcop_i2c_func\n" ); + +return I2C_FUNC_I2C ; +} + +static struct i2c_algorithm flexcop_algo = { + .name ="flexcop i2c algorithm" , + .id =I2C_ALGO_BIT , + .master_xfer = master_xfer, + .functionality = flexcop_i2c_func, +}; + +static int skystar2_probe (struct pci_dev *pdev,const struct pci_device_id *ent) {struct adapter *adapter;
@@ -2258,10 +2303,27 @@init_MUTEX (&adapter->i2c_sem); - adapter->i2c_bus =dvb_register_i2c_bus (master_xfer, adapter, adapter->dvb_adapter,0 ); -if (!adapter->i2c_bus) +memset (&adapter->i2c_adap,0 ,sizeof (struct i2c_adapter )); +strcpy (adapter->i2c_adap.name,"Technisat SkyStar2 driver" ); + +i2c_set_adapdata (&adapter->i2c_adap, adapter); + +#ifdef I2C_ADAP_CLASS_TV_DIGITAL + adapter->i2c_adap.class =I2C_ADAP_CLASS_TV_DIGITAL ; +#else + adapter->i2c_adap.class =I2C_CLASS_TV_DIGITAL ; +#endif + adapter->i2c_adap.algo = &flexcop_algo; + adapter->i2c_adap.algo_data =NULL ; + adapter->i2c_adap.id =I2C_ALGO_BIT ; + adapter->i2c_adap.client_register = client_register; + adapter->i2c_adap.client_unregister = client_unregister; + +if (i2c_add_adapter (&adapter->i2c_adap) <0 ) { +dvb_unregister_adapter (adapter->dvb_adapter);return -ENOMEM ; + }dvb_add_frontend_ioctls (adapter->dvb_adapter, flexcop_diseqc_ioctl,NULL , adapter);
@@ -2327,8 +2389,7 @@if (adapter->dvb_adapter !=NULL ) {dvb_remove_frontend_ioctls (adapter->dvb_adapter, flexcop_diseqc_ioctl,NULL ); -if (adapter->i2c_bus !=NULL ) -dvb_unregister_i2c_bus (master_xfer, adapter->i2c_bus->adapter, adapter->i2c_bus->id); +i2c_del_adapter (&adapter->i2c_adap);dvb_unregister_adapter (adapter->dvb_adapter); }
@@ -2364,10 +2425,5 @@module_init (skystar2_init);module_exit (skystar2_cleanup); -MODULE_PARM (debug,"i" ); -MODULE_PARM_DESC (debug,"enable verbose debug messages: supported values: 1 and 2" ); -MODULE_PARM (enable_hw_filters,"i" ); -MODULE_PARM_DESC (enable_hw_filters,"enable hardware filters: supported values: 0 (none), 1, 2" ); -MODULE_DESCRIPTION ("Technisat SkyStar2 DVB PCI Driver" );MODULE_LICENSE ("GPL" );
drivers/media/dvb/bt8xx/bt878.c +15 -17
@@ -27,8 +27,8 @@* */ -#include <linux/version.h> #include <linux/module.h> +#include <linux/moduleparam.h> #include <linux/kernel.h> #include <linux/pci.h> #include <asm/io.h>
@@ -46,20 +46,19 @@#include "bt878.h" #include "dst-bt878.h" -#include "dvb_functions.h" /**************************************/ /* Miscellaneous utility definitions */ /**************************************/ -unsigned int bt878_verbose =1 ; -unsigned int bt878_debug =0 ; -MODULE_PARM (bt878_verbose,"i" ); +static unsigned int bt878_verbose =1 ; +static unsigned int bt878_debug; + +module_param_named (verbose, bt878_verbose, int,0444 );MODULE_PARM_DESC (bt878_verbose,"verbose startup messages, default is 1 (yes)" ); -MODULE_PARM (bt878_debug,"i" ); -MODULE_PARM_DESC (bt878_debug,"debug messages, default is 0 (no)" ); -MODULE_LICENSE ("GPL" ); +module_param_named (debug, bt878_debug, int,0644 ); +MODULE_PARM_DESC (bt878_debug,"Turn on/off debugging (default:off)." );int bt878_num;struct bt878 bt878[BT878_MAX ];
@@ -339,10 +338,6 @@return IRQ_HANDLED ; } -extern int bttv_gpio_enable (unsigned int card,unsigned long mask,unsigned long data); -extern int bttv_read_gpio (unsigned int card,unsigned long *data); -extern int bttv_write_gpio (unsigned int card,unsigned long mask,unsigned long data); -int bt878_device_control (struct bt878 *bt,unsigned int cmd,union dst_gpio_packet *mp) {
@@ -386,20 +381,20 @@EXPORT_SYMBOL (bt878_device_control); -struct bt878 *bt878_find_by_dvb_adap (struct dvb_adapter *adap) +struct bt878 *bt878_find_by_i2c_adap (struct i2c_adapter *adapter) {unsigned int card_nr; -printk ("bt878 find by dvb adap: checking \"%s\"\n" ,adap->name); +printk ("bt878 find by dvb adap: checking \"%s\"\n" ,adapter->name);for (card_nr =0 ; card_nr < bt878_num; card_nr++) { -if (bt878[card_nr].adap_ptr == adap) +if (bt878[card_nr].adapter == adapter)return &bt878[card_nr]; } -printk ("bt878 find by dvb adap: NOT found \"%s\"\n" ,adap->name); +printk ("bt878 find by dvb adap: NOT found \"%s\"\n" ,adapter->name);return NULL ; } -EXPORT_SYMBOL (bt878_find_by_dvb_adap); +EXPORT_SYMBOL (bt878_find_by_i2c_adap);/***********************/ /* PCI device handling */
@@ -607,6 +602,9 @@module_init (bt878_init_module);module_exit (bt878_cleanup_module); + +MODULE_LICENSE ("GPL" ); +/* * Local variables: * c-basic-offset: 8
drivers/media/dvb/bt8xx/bt878.h +2 -1
@@ -26,6 +26,7 @@#include <linux/sched.h> #include <linux/spinlock.h> #include "bt848.h" +#include "bttv.h" #define BT878_VERSION_CODE 0x000000
@@ -94,7 +95,7 @@struct semaphore gpio_lock;unsigned int nr;unsigned int bttv_nr; -struct dvb_adapter *adap_ptr; +struct i2c_adapter *adapter;struct pci_dev *dev;unsigned int id;unsigned int TS_Size;
drivers/media/dvb/bt8xx/dvb-bt8xx.c +130 -283
538 lines not on this page · raw message
drivers/media/dvb/bt8xx/dvb-bt8xx.h +1 -1
@@ -25,9 +25,9 @@#include <linux/i2c.h> #include "dvbdev.h" #include "dvb_net.h" +#include "bttv.h" struct dvb_bt8xx_card { -struct list_head list;u8 active;char card_name[32 ];
drivers/media/dvb/bt8xx/Kconfig +5 -2
@@ -1,13 +1,16 @@ config DVB_BT8XX - tristate "Nebula/Pinnacle PCTV PCI cards" + tristate "Nebula/Pinnacle PCTV/Twinhan PCI cards" depends on DVB_CORE && PCI && VIDEO_BT848 help Support for PCI cards based on the Bt8xx PCI bridge. Examples are - the Nebula cards, the Pinnacle PCTV cards, and Twinhan DST cards. + the Nebula cards, the Pinnacle PCTV cards and Twinhan DST cards. Since these cards have no MPEG decoder onboard, they transmit only compressed MPEG data over the PCI bus, so you need an external software decoder to watch TV on your computer. + If you have a Twinhan card, don't forget to select + "Twinhan DST based DVB-S/-T frontend". + Say Y if you own such a device and want to use it.
drivers/media/dvb/frontends/dst-bt878.h +2 -3
@@ -32,7 +32,6 @@struct bt878 ; -int -bt878_device_control (struct bt878 *bt,unsigned int cmd,union dst_gpio_packet *mp); +int bt878_device_control (struct bt878 *bt,unsigned int cmd,union dst_gpio_packet *mp); -struct bt878 *bt878_find_by_dvb_adap (struct dvb_adapter *adap); +struct bt878 *bt878_find_by_i2c_adap (struct i2c_adapter *adap);
Re: [PATCH][2.6][4/14] dvb core update
- [DVB] remove non-linux compatibility stuff from dvb_functions. rest in peace.
- [DVB] remove home-brewn dvb-i2c stuff. rest in peace.
- [DVB] convert MODULE_PARM() to module_param()
- [DVB] convert dvb_delay() to mdelay()
- [DVB] convert C++ comments to C comments
- [DVB] dvb_ca_en50221: fix for matrix CAMs from Sjoerd Simons, use c99 initializers, Fix for aston CAM read timeout problems, Moved CAM CTRL IF reset to a better place, better debugging with multiple cards (Sjoerd Simons)
- [DVB] dvb-frontend: patch by Wolfgang Fritz: suppress spurious events during tuning, Do not allow write (and related) ioctls when frontend is opened RDONLY, Properly lock the frontend module on open/close, patch by Christopher Pascoe: remove bogus up(fe->sem) on fe thread exit, patch by Christopher Pascoe: remove bogus up(fe->sem) on fe thread exit
- [DVB] dvb-demux: using spin_lock instead of spin_lock_irq caused a race condition between irq/tasklet and user space task
- [DVB] dvb-core: add sysfs/udev support using "class_simple", prevent Oops when PES filter is set with invalid pes_type, protect feed_list with spin_locks
drivers/media/dvb/dvb-core/dmxdev.c +5 -3
@@ -25,6 +25,7 @@#include <linux/slab.h> #include <linux/vmalloc.h> #include <linux/module.h> +#include <linux/moduleparam.h> #include <linux/sched.h> #include <linux/poll.h> #include <linux/ioctl.h>
@@ -33,10 +34,11 @@#include <asm/system.h> #include "dmxdev.h" -#include "dvb_functions.h" -MODULE_PARM (debug,"i" ); -static int debug =0 ; +static int debug; + +module_param (debug, int,0644 ); +MODULE_PARM_DESC (debug,"Turn on/off debugging (default:off)." );#define dprintk if (debug) printk
drivers/media/dvb/dvb-core/dvb_ca_en50221.c +74 -65
341 lines not on this page · raw message
drivers/media/dvb/dvb-core/dvb_ca_en50221.h +3 -0
@@ -42,6 +42,9 @@/* Structure describing a CA interface */ struct dvb_ca_en50221 { +/* NOTE: the read_*, write_* and poll_slot_status functions must use locks as +* they may be called from several threads at once */ +/* functions for accessing attribute memory on the CAM */ int (*read_attribute_mem)(struct dvb_ca_en50221 * ca,int slot,int address);int (*write_attribute_mem)(struct dvb_ca_en50221 * ca,int slot,int address,u8 value);
drivers/media/dvb/dvb-core/dvb_demux.c +9 -4
@@ -31,7 +31,6 @@#include <asm/uaccess.h> #include "dvb_demux.h" -#include "dvb_functions.h" #define NOBUFS /*
@@ -570,24 +570,30 @@static void dvb_demux_feed_add (struct dvb_demux_feed *feed) { +spin_lock (&feed->demux->lock);if (dvb_demux_feed_find (feed)) {printk (KERN_ERR "%s: feed already in list (type=%x state=%x pid=%x)\n" , __FUNCTION__, feed->type, feed->state, feed->pid); -return ; + goto out; }list_add (&feed->list_head, &feed->demux->feed_list); +out: +spin_unlock (&feed->demux->lock); }static void dvb_demux_feed_del (struct dvb_demux_feed *feed) { +spin_lock (&feed->demux->lock);if (!(dvb_demux_feed_find (feed))) {printk (KERN_ERR "%s: feed not in list (type=%x state=%x pid=%x)\n" , __FUNCTION__, feed->type, feed->state, feed->pid); -return ; + goto out; }list_del (&feed->list_head); +out: +spin_unlock (&feed->demux->lock); } static int dmx_ts_feed_set (struct dmx_ts_feed* ts_feed, u16 pid, int ts_type,
@@ -789,7 +795,7 @@ feed->pid =0xffff ; -if (feed->ts_type &TS_DECODER ) +if (feed->ts_type &TS_DECODER && feed->pes_type <DMX_TS_PES_OTHER ) demux->pesfilter[feed->pes_type] =NULL ;up (&demux->mutex);
drivers/media/dvb/dvb-core/dvbdev.c +93 -11
169 lines not on this page · raw message
drivers/media/dvb/dvb-core/dvbdev.h +11 -0
@@ -28,6 +28,7 @@#include <linux/fs.h> #include <linux/list.h> #include <linux/devfs_fs_kernel.h> +#include <linux/smp_lock.h> #define DVB_MAJOR 212
@@ -92,5 +90,15 @@extern int dvb_generic_release (struct inode *inode,struct file *file);extern int dvb_generic_ioctl (struct inode *inode,struct file *file,unsigned int cmd,unsigned long arg); + +/* we don't mess with video_usercopy() any more, +we simply define out own dvb_usercopy(), which will hopefully become +generic_usercopy() someday... */ + +extern int dvb_usercopy (struct inode *inode,struct file *file, +unsigned int cmd,unsigned long arg, +int (*func)(struct inode *inode,struct file *file, +unsigned int cmd,void *arg)); +#endif /* #ifndef _DVBDEV_H_ */
drivers/media/dvb/dvb-core/dvb_frontend.c +142 -120
592 lines not on this page · raw message
drivers/media/dvb/dvb-core/dvb_frontend.h +26 -9
@@ -31,14 +34,29 @@#include <linux/i2c.h> #include <linux/module.h> #include <linux/errno.h> +#include <linux/delay.h> #include <linux/dvb/frontend.h> -#include "dvb_i2c.h" #include "dvbdev.h" - - +/* FIXME: Move to i2c-id.h */ +#define I2C_DRIVERID_DVBFE_ALPS_TDLB7 I2C_DRIVERID_EXP2 +#define I2C_DRIVERID_DVBFE_ALPS_TDMB7 I2C_DRIVERID_EXP2 +#define I2C_DRIVERID_DVBFE_AT76C651 I2C_DRIVERID_EXP2 +#define I2C_DRIVERID_DVBFE_CX24110 I2C_DRIVERID_EXP2 +#define I2C_DRIVERID_DVBFE_DST I2C_DRIVERID_EXP2 +#define I2C_DRIVERID_DVBFE_DUMMY I2C_DRIVERID_EXP2 +#define I2C_DRIVERID_DVBFE_L64781 I2C_DRIVERID_EXP2 +#define I2C_DRIVERID_DVBFE_MT312 I2C_DRIVERID_EXP2 +#define I2C_DRIVERID_DVBFE_MT352 I2C_DRIVERID_EXP2 +#define I2C_DRIVERID_DVBFE_NXT6000 I2C_DRIVERID_EXP2 +#define I2C_DRIVERID_DVBFE_SP887X I2C_DRIVERID_EXP2 +#define I2C_DRIVERID_DVBFE_STV0299 I2C_DRIVERID_EXP2 +#define I2C_DRIVERID_DVBFE_TDA1004X I2C_DRIVERID_EXP2 +#define I2C_DRIVERID_DVBFE_TDA8083 I2C_DRIVERID_EXP2 +#define I2C_DRIVERID_DVBFE_VES1820 I2C_DRIVERID_EXP2 +#define I2C_DRIVERID_DVBFE_VES1X93 I2C_DRIVERID_EXP2/** * when before_ioctl is registered and returns value 0, ioctl and after_ioctl
@@ -50,7 +68,7 @@int (*ioctl) (struct dvb_frontend *frontend,unsigned int cmd,void *arg);int (*after_ioctl) (struct dvb_frontend *frontend,unsigned int cmd,void *arg);void (*notifier_callback) (fe_status_t s,void *data); -struct dvb_i2c_bus *i2c; +struct dvb_adapter *dvb_adapter;void *before_after_data;/* can be used by hardware module... */ void *notifier_data;/* can be used by hardware module... */ void *data;/* can be used by hardware module... */
@@ -75,19 +93,21 @@#define FE_SLEEP _IO('v', 80)#define FE_INIT _IO('v', 81)#define FE_GET_TUNE_SETTINGS _IOWR('v', 83, struct dvb_frontend_tune_settings) - +#define FE_REGISTER _IO ('v', 84) +#define FE_UNREGISTER _IO ('v', 85)extern int dvb_register_frontend (int (*ioctl) (struct dvb_frontend *frontend,unsigned int cmd,void *arg), -struct dvb_i2c_bus *i2c, +struct dvb_adapter *dvb_adapter,void *data, -struct dvb_frontend_info *info); +struct dvb_frontend_info *info, +struct module *module);extern int -dvb_unregister_frontend (int (*ioctl) (struct dvb_frontend *frontend, +dvb_unregister_frontend_new (int (*ioctl) (struct dvb_frontend *frontend,unsigned int cmd,void *arg), -struct dvb_i2c_bus *i2c); +struct dvb_adapter *dvb_adapter);/**
drivers/media/dvb/dvb-core/dvb_ksyms.c +1 -6
@@ -24,17 +24,12 @@EXPORT_SYMBOL (dvbdmx_disconnect_frontend);EXPORT_SYMBOL (dvb_register_frontend); -EXPORT_SYMBOL (dvb_unregister_frontend); +EXPORT_SYMBOL (dvb_unregister_frontend_new);EXPORT_SYMBOL (dvb_add_frontend_ioctls);EXPORT_SYMBOL (dvb_remove_frontend_ioctls);EXPORT_SYMBOL (dvb_add_frontend_notifier);EXPORT_SYMBOL (dvb_remove_frontend_notifier); -EXPORT_SYMBOL (dvb_register_i2c_bus); -EXPORT_SYMBOL (dvb_unregister_i2c_bus); -EXPORT_SYMBOL (dvb_register_i2c_device); -EXPORT_SYMBOL (dvb_unregister_i2c_device); -EXPORT_SYMBOL (dvb_net_init);EXPORT_SYMBOL (dvb_net_release);
drivers/media/dvb/dvb-core/Makefile +2 -2
@@ -3,7 +3,7 @@ # dvb-core-objs = dvbdev.o dmxdev.o dvb_demux.o dvb_filter.o \ - dvb_ca_en50221.o dvb_functions.o dvb_frontend.o \ - dvb_i2c.o dvb_net.o dvb_ksyms.o dvb_ringbuffer.o + dvb_ca_en50221.o dvb_frontend.o \ + dvb_net.o dvb_ksyms.o dvb_ringbuffer.o obj-$(CONFIG_DVB_CORE) += dvb-core.o
drivers/media/dvb/dvb-core/dvb_functions.c +0 -89
89 lines not on this page · raw message
drivers/media/dvb/dvb-core/dvb_functions.h +0 -50
50 lines not on this page · raw message
drivers/media/dvb/dvb-core/dvb_i2c.c +0 -290
290 lines not on this page · raw message
drivers/media/dvb/dvb-core/dvb_i2c.h +0 -63
63 lines not on this page · raw message
include/linux/dvb/frontend.h +4 -1
@@ -32,7 +32,8 @@typedef enum fe_type {FE_QPSK ,FE_QAM , -FE_OFDM +FE_OFDM , +FE_ATSC }fe_type_t ;
@@ -59,6 +60,8 @@FE_CAN_BANDWIDTH_AUTO =0x40000 ,FE_CAN_GUARD_INTERVAL_AUTO =0x80000 ,FE_CAN_HIERARCHY_AUTO =0x100000 , +FE_CAN_8VSB =0x200000 , +FE_CAN_16VSB =0x400000 ,FE_NEEDS_BENDING =0x20000000 ,// frontend requires frequency bending FE_CAN_RECOVER =0x40000000 ,// frontend can recover from a cable unplug automatically FE_CAN_MUTE_TS =0x80000000 // frontend can stop spurious TS data output
drivers/media/dvb/dvb-core/dvb_ca_en50221.c +20 -25
142 lines not on this page · raw message
drivers/media/dvb/dvb-core/dvb_demux.c +4 -4
@@ -569,7 +570,7 @@static void dvb_demux_feed_add (struct dvb_demux_feed *feed) { -spin_lock (&feed->demux->lock); +spin_lock_irq (&feed->demux->lock);if (dvb_demux_feed_find (feed)) {printk (KERN_ERR "%s: feed already in list (type=%x state=%x pid=%x)\n" , __FUNCTION__, feed->type, feed->state, feed->pid);
@@ -578,12 +579,12 @@list_add (&feed->list_head, &feed->demux->feed_list); out: -spin_unlock (&feed->demux->lock); +spin_unlock_irq (&feed->demux->lock); }static void dvb_demux_feed_del (struct dvb_demux_feed *feed) { -spin_lock (&feed->demux->lock); +spin_lock_irq (&feed->demux->lock);if (!(dvb_demux_feed_find (feed))) {printk (KERN_ERR "%s: feed not in list (type=%x state=%x pid=%x)\n" , __FUNCTION__, feed->type, feed->state, feed->pid);
@@ -592,7 +593,7 @@list_del (&feed->list_head); out: -spin_unlock (&feed->demux->lock); +spin_unlock_irq (&feed->demux->lock); } static int dmx_ts_feed_set (struct dmx_ts_feed* ts_feed, u16 pid, int ts_type,
drivers/media/dvb/dvb-core/dvb_net.c +0 -2
@@ -40,8 +40,6 @@#include "dvb_demux.h" #include "dvb_net.h" -#include "dvb_functions.h" -static inline __u32 iov_crc32 (__u32 c,struct kvec *iov,unsigned int cnt ) {
Re: [PATCH][2.6][5/14] convert frontend drivers to kernel i2c 1/3
- [DVB] stv0299, tda1004x, ves1820, ves1x93: convert from dvb-i2c to kernel-i2c, MODULE_PARM() to module_param(), dvb_delay() to mdelay()
- [DVB] tda1004x: move from home-brewn firmware loading to firmware_class
- [DVB] stv0299: support Cinergy1200, patch by Uli Luckas
drivers/media/dvb/frontends/stv0299.c +169 -91
@@ -48,21 +48,28 @@#include <linux/init.h> #include <linux/kernel.h> #include <linux/module.h> +#include <linux/moduleparam.h> #include <linux/string.h> #include <linux/slab.h> #include <asm/div64.h> #include "dvb_frontend.h" -#include "dvb_functions.h" -#if 0 -#define dprintk(x...) printk(x) -#else -#define dprintk(x...) -#endif +#define FRONTEND_NAME "dvbfe_stv0299" -static int stv0299_status =0 ; -static int disable_typhoon =0 ; +#define dprintk(args...) \ + do { \ + if (debug) printk(KERN_DEBUG FRONTEND_NAME ": " args); \ + } while (0) + +static int debug; +static int stv0299_status; + +module_param (debug, int,0644 ); +MODULE_PARM_DESC (debug,"Turn on/off frontend debugging (default:off)." ); +module_param (stv0299_status, int,0444 ); +MODULE_PARM_DESC (stv0299_status,"Which status value to support " +"(0 == BER (default), 1 == UCBLOCKS)" );#define STATUS_BER 0#define STATUS_UCBLOCKS 1
@@ -77,6 +84,7 @@#define SAMSUNG_TBMU24112IMB 4#define PHILIPS_SU1278_TSA_TT 5 // SU1278 with TSA5059 synth and TechnoTrend settings#define PHILIPS_SU1278_TSA_TY 6 // SU1278 with TUA5059 synth and Typhoon wiring +#define PHILIPS_SU1278_TSA_CI 7 // SU1278 with TUA5059 synth and TerraTec Cinergy wiring/* Master Clock = 88 MHz */ #define M_CLK (88000000UL)
@@ -108,6 +116,8 @@u32 tuner_frequency;u32 symbol_rate;fe_code_rate_t fec_inner; +struct i2c_adapter *i2c; +struct dvb_adapter *dvb; };
@@ -264,26 +274,26 @@0x34 ,0x13 }; -static int stv0299_set_FEC (struct dvb_i2c_bus *i2c,fe_code_rate_t fec); -static int stv0299_set_symbolrate (struct dvb_i2c_bus *i2c,u32 srate,int tuner_type); +static int stv0299_set_FEC (struct i2c_adapter *i2c,fe_code_rate_t fec); +static int stv0299_set_symbolrate (struct i2c_adapter *i2c,u32 srate,int tuner_type); -static int stv0299_writereg (struct dvb_i2c_bus *i2c,u8 reg,u8 data) +static int stv0299_writereg (struct i2c_adapter *i2c,u8 reg,u8 data) {int ret;u8 buf [] = { reg, data };struct i2c_msg msg = { .addr =0x68 , .flags =0 , .buf = buf, .len =2 }; - ret = i2c->xfer (i2c, &msg,1 ); + ret =i2c_transfer (i2c, &msg,1 );if (ret !=1 )dprintk ("%s: writereg error (reg == 0x%02x, val == 0x%02x, " "ret == %i)\n" , __FUNCTION__, reg, data, ret); -return (ret !=1 ) ?-1 :0 ; +return (ret !=1 ) ? -EREMOTEIO :0 ; } -static u8 stv0299_readreg (struct dvb_i2c_bus *i2c,u8 reg) +static u8 stv0299_readreg (struct i2c_adapter *i2c,u8 reg) {int ret;u8 b0 [] = { reg };
@@ -291,7 +301,7 @@struct i2c_msg msg [] = { { .addr =0x68 , .flags =0 , .buf = b0, .len =1 }, { .addr =0x68 , .flags =I2C_M_RD , .buf = b1, .len =1 } }; - ret = i2c->xfer (i2c, msg,2 ); + ret =i2c_transfer (i2c, msg,2 );if (ret !=2 ) dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n",
@@ -301,13 +311,13 @@ } -static int stv0299_readregs (struct dvb_i2c_bus *i2c,u8 reg1,u8 *b,u8 len) +static int stv0299_readregs (struct i2c_adapter *i2c,u8 reg1,u8 *b,u8 len) {int ret;struct i2c_msg msg [] = { { .addr =0x68 , .flags =0 , .buf = ®1, .len =1 }, { .addr =0x68 , .flags =I2C_M_RD , .buf = b, .len = len } }; - ret = i2c->xfer (i2c, msg,2 ); + ret =i2c_transfer (i2c, msg,2 );if (ret !=2 )dprintk ("%s: readreg error (ret == %i)\n" , __FUNCTION__, ret);
@@ -316,7 +326,7 @@ } -static int pll_write (struct dvb_i2c_bus *i2c,u8 addr,u8 *data,int len) +static int pll_write (struct i2c_adapter *i2c,u8 addr,u8 *data,int len) {int ret;struct i2c_msg msg = { addr: addr, .flags =0 , .buf = data, .len = len };
@@ -324,7 +334,7 @@stv0299_writereg (i2c,0x05 ,0xb5 );/* enable i2c repeater on stv0299 */ - ret = i2c->xfer (i2c, &msg,1 ); + ret =i2c_transfer (i2c, &msg,1 );stv0299_writereg (i2c,0x05 ,0x35 );/* disable i2c repeater on stv0299 */
@@ -335,7 +345,7 @@ } -static int sl1935_set_tv_freq (struct dvb_i2c_bus *i2c,u32 freq,int ftype) +static int sl1935_set_tv_freq (struct i2c_adapter *i2c,u32 freq,int ftype) {u8 buf[4 ];u32 div;
@@ -358,7 +368,7 @@* set up the downconverter frequency divisor for a * reference clock comparision frequency of 125 kHz. */ -static int tsa5059_set_tv_freq (struct dvb_i2c_bus *i2c,u32 freq,int ftype,int srate) +static int tsa5059_set_tv_freq (struct i2c_adapter *i2c,u32 freq,int ftype,int srate) {u8 addr;u32 div;
@@ -389,7 +399,8 @@case PHILIPS_SU1278_TSA :case PHILIPS_SU1278_TSA_TT :case PHILIPS_SU1278_TSA_TY : -if (ftype ==PHILIPS_SU1278_TSA_TY ) +case PHILIPS_SU1278_TSA_CI : +if (ftype ==PHILIPS_SU1278_TSA_TY || ftype ==PHILIPS_SU1278_TSA_CI ) addr =0x61 ;else addr =0x60 ;
@@ -421,7 +432,7 @@#define MIN2 (a,b) ((a) < (b) ? (a) : (b))#define MIN3 (a,b,c) MIN2(MIN2(a,b),c) -static int tua6100_set_tv_freq (struct dvb_i2c_bus *i2c,u32 freq, +static int tua6100_set_tv_freq (struct i2c_adapter *i2c,u32 freq,int ftype,int srate) {u8 reg0 [2 ] = {0x00 ,0x00 };
@@ -542,7 +553,7 @@ } -static int pll_set_tv_freq (struct dvb_i2c_bus *i2c,u32 freq,int ftype,int srate) +static int pll_set_tv_freq (struct i2c_adapter *i2c,u32 freq,int ftype,int srate) {switch (ftype) {case SAMSUNG_TBMU24112IMB :
@@ -560,7 +571,7 @@ }#if 0 -static int tsa5059_read_status (struct dvb_i2c_bus *i2c) +static int tsa5059_read_status (struct i2c_adapter *i2c) {int ret;u8 rpt1 [] = {0x05 ,0xb5 };
@@ -571,7 +582,7 @@dprintk ("%s\n" , __FUNCTION__); - ret = i2c->xfer (i2c, msg,2 ); + ret =i2c_transfer (i2c, msg,2 );if (ret !=2 )dprintk ("%s: readreg error (ret == %i)\n" , __FUNCTION__, ret);
@@ -581,7 +592,7 @@#endif -static int stv0299_init (struct dvb_i2c_bus *i2c,int ftype) +static int stv0299_init (struct i2c_adapter *i2c,int ftype) {int i;
@@ -614,7 +625,7 @@stv0299_writereg (i2c, init_tab[i], init_tab[i+1 ]);/* AGC1 reference register setup */ -if (ftype ==PHILIPS_SU1278_TSA || ftype ==PHILIPS_SU1278_TSA_TY ) +if (ftype ==PHILIPS_SU1278_TSA || ftype ==PHILIPS_SU1278_TSA_TY || ftype ==PHILIPS_SU1278_TSA_CI )stv0299_writereg (i2c,0x0f ,0x92 );/* Iagc = Inverse, m1 = 18 */ else if (ftype ==PHILIPS_SU1278_TUA )stv0299_writereg (i2c,0x0f ,0x94 );/* Iagc = Inverse, m1 = 20 */
@@ -637,7 +648,7 @@ } -static int stv0299_set_FEC (struct dvb_i2c_bus *i2c,fe_code_rate_t fec) +static int stv0299_set_FEC (struct i2c_adapter *i2c,fe_code_rate_t fec) {dprintk ("%s\n" , __FUNCTION__);
@@ -681,7 +692,7 @@ } -static fe_code_rate_t stv0299_get_fec (struct dvb_i2c_bus *i2c) +static fe_code_rate_t stv0299_get_fec (struct i2c_adapter *i2c) {static fe_code_rate_t fec_tab [] = {FEC_2_3 ,FEC_3_4 ,FEC_5_6 ,FEC_7_8 ,FEC_1_2 };
@@ -699,7 +710,7 @@ } -static int stv0299_wait_diseqc_fifo (struct dvb_i2c_bus *i2c,int timeout) +static int stv0299_wait_diseqc_fifo (struct i2c_adapter *i2c,int timeout) {unsigned long start = jiffies;
@@ -710,14 +721,14 @@dprintk ("%s: timeout!!\n" , __FUNCTION__);return -ETIMEDOUT ; } -dvb_delay (10 ); +msleep (10 ); };return 0 ; } -static int stv0299_wait_diseqc_idle (struct dvb_i2c_bus *i2c,int timeout) +static int stv0299_wait_diseqc_idle (struct i2c_adapter *i2c,int timeout) {unsigned long start = jiffies;
@@ -728,14 +739,14 @@dprintk ("%s: timeout!!\n" , __FUNCTION__);return -ETIMEDOUT ; } -dvb_delay (10 ); +msleep (10 ); };return 0 ; } -static int stv0299_send_diseqc_msg (struct dvb_i2c_bus *i2c, +static int stv0299_send_diseqc_msg (struct i2c_adapter *i2c,struct dvb_diseqc_master_cmd *m) {u8 val;
@@ -766,7 +777,7 @@ } -static int stv0299_send_diseqc_burst (struct dvb_i2c_bus *i2c,fe_sec_mini_cmd_t burst) +static int stv0299_send_diseqc_burst (struct i2c_adapter *i2c,fe_sec_mini_cmd_t burst) {u8 val;
@@ -793,7 +804,7 @@ } -static int stv0299_set_tone (struct dvb_i2c_bus *i2c,fe_sec_tone_mode_t tone) +static int stv0299_set_tone (struct i2c_adapter *i2c,fe_sec_tone_mode_t tone) {u8 val;
@@ -826,7 +837,7 @@ } -static int stv0299_set_voltage (struct dvb_i2c_bus *i2c,fe_sec_voltage_t voltage, +static int stv0299_set_voltage (struct i2c_adapter *i2c,fe_sec_voltage_t voltage,int tuner_type) {u8 reg0x08;
@@ -849,11 +860,18 @@return stv0299_writereg (i2c,0x08 ,0x00 );/* LNB power off! */ } +if (tuner_type ==PHILIPS_SU1278_TSA_CI ) + { +stv0299_writereg (i2c,0x08 , reg0x08 &0xBF );// switch LNB power on OP2/LOCK pin off + } +else + {stv0299_writereg (i2c,0x08 , reg0x08 |0x40 ); + }switch (voltage) {case SEC_VOLTAGE_13 : -if (tuner_type ==PHILIPS_SU1278_TSA_TY ) +if (tuner_type ==PHILIPS_SU1278_TSA_TY || tuner_type ==PHILIPS_SU1278_TSA_CI )return stv0299_writereg (i2c,0x0c , reg0x0c |0x10 );else return stv0299_writereg (i2c,0x0c , reg0x0c |0x40 );
@@ -867,7 +885,7 @@ } -static int stv0299_set_symbolrate (struct dvb_i2c_bus *i2c,u32 srate,int tuner_type) +static int stv0299_set_symbolrate (struct i2c_adapter *i2c,u32 srate,int tuner_type) {u64 big = srate;u32 ratio;
@@ -918,6 +937,7 @@break ;case PHILIPS_SU1278_TSA_TY : +case PHILIPS_SU1278_TSA_CI :case PHILIPS_SU1278_TSA : aclk =0xb5 ;if (srate <2000000 ) bclk =0x86 ;
@@ -958,7 +978,7 @@ } -static int stv0299_get_symbolrate (struct dvb_i2c_bus *i2c,int tuner_type) +static int stv0299_get_symbolrate (struct i2c_adapter *i2c,int tuner_type) {u32 Mclk =M_CLK /4096L ;u32 srate;
@@ -995,8 +1014,8 @@static int uni0299_ioctl (struct dvb_frontend *fe,unsigned int cmd,void *arg) { -struct dvb_i2c_bus *i2c = fe->i2c;struct stv0299_state *state = (struct stv0299_state *) fe->data; +struct i2c_adapter *i2c = state->i2c;dprintk ("%s\n" , __FUNCTION__);
@@ -1248,9 +1267,9 @@return 0 ; } -static long probe_tuner (struct dvb_i2c_bus *i2c) +static long probe_tuner (struct i2c_adapter *adapter) { -struct dvb_adapter * adapter = (struct dvb_adapter *) i2c->adapter; +struct i2c_adapter *i2c = adapter;/* superfluous */ /* read the status register of TSA5059 */ u8 rpt[] = {0x05 ,0xb5 };
@@ -1269,45 +1288,45 @@stv0299_writereg (i2c,0x03 ,0x00 ); -printk ("%s: try to attach to %s\n" , __FUNCTION__, adapter->name); - -if (strcmp (adapter->name,"Technisat SkyStar2 driver" ) ==0 ) - { -printk ("%s: setup for tuner Samsung TBMU24112IMB\n" , __FILE__); +printk ("stv0299: try to attach to %s\n" , adapter->name); +if (!strcmp (adapter->name,"Technisat SkyStar2 driver" )) { +printk ("stv0299: setup for tuner Samsung TBMU24112IMB\n" );return SAMSUNG_TBMU24112IMB ; } -if ((ret = i2c->xfer (i2c, msg1,2 )) ==2 ) { +if ((ret =i2c_transfer (i2c, msg1,2 )) ==2 ) {if (strcmp (adapter->name,"TT-Budget/WinTV-NOVA-CI PCI" ) ==0 ) {// technotrend cards require non-datasheet settings -printk ("%s: setup for tuner SU1278 (TSA5059 synth) on" -" TechnoTrend hardware\n" , __FILE__); +printk ("stv0299: setup for tuner SU1278 (TSA5059 synth) on TechnoTrend hardware\n" );return PHILIPS_SU1278_TSA_TT ; }else {// fall back to datasheet-recommended settings -printk ("%s: setup for tuner SU1278 (TSA5059 synth)\n" , - __FILE__); +printk ("stv0299: setup for tuner SU1278 (TSA5059 synth)\n" );return PHILIPS_SU1278_TSA ; } } -if ((ret = i2c->xfer (i2c, msg2,2 )) ==2 ) { -if (strcmp (adapter->name,"KNC1 DVB-S" ) ==0 && - !disable_typhoon ) +if ((ret =i2c_transfer (i2c, msg2,2 )) ==2 ) { +if (strcmp (adapter->name,"KNC1 DVB-S" ) ==0 ) {// Typhoon cards have unusual wiring. -printk ("%s: setup for tuner SU1278 (TSA5059 synth) on" -" Typhoon hardware\n" , __FILE__); +printk ("stv0299: setup for tuner SU1278 (TSA5059 synth) on Typhoon hardware\n" );return PHILIPS_SU1278_TSA_TY ; } +else if (strcmp (adapter->name,"TerraTec Cinergy 1200 DVB-S" ) ==0 ) + { +// Cinergy cards have unusual wiring. +printk ("%s: setup for tuner SU1278 (TSA5059 synth) on" +" TerraTec hardware\n" , __FILE__); +return PHILIPS_SU1278_TSA_CI ; + }//else if ((stat[0] & 0x3f) == 0) { else if (0 ) { -printk ("%s: setup for tuner TDQF-S001F\n" , __FILE__); +printk ("stv0299: setup for tuner TDQF-S001F\n" );return LG_TDQF_S001F ; }else { -printk ("%s: setup for tuner BSRU6, TDQB-S00x\n" , - __FILE__); +printk ("stv0299: setup for tuner BSRU6, TDQB-S00x\n" );return ALPS_BSRU6 ; } }
@@ -1317,29 +1336,29 @@*/ stv0299_writereg (i2c,0x02 ,0x00 ); -if ((ret = i2c->xfer (i2c, msg3,2 )) ==2 ) { -printk ("%s: setup for tuner Philips SU1278 (TUA6100 synth)\n" , - __FILE__); +if ((ret =i2c_transfer (i2c, msg3,2 )) ==2 ) { +printk ("stv0299: setup for tuner Philips SU1278 (TUA6100 synth)\n" );return PHILIPS_SU1278_TUA ; } -printk ("%s: unknown PLL synthesizer (ret == %i), " -"please report to <[email protected]>!!\n" , - __FILE__, ret); +printk ("stv0299: unknown PLL synthesizer (ret == %i), please report to <[email protected]>!!\n" , ret);return UNKNOWN_FRONTEND ; } +static struct i2c_client client_template; -static int uni0299_attach (struct dvb_i2c_bus *i2c,void **data) +static int attach_adapter (struct i2c_adapter *adapter) { +struct i2c_client *client;struct stv0299_state * state;int tuner_type; +int ret;u8 id; -stv0299_writereg (i2c,0x02 ,0x34 );/* standby off */ -dvb_delay (200 ); - id =stv0299_readreg (i2c,0x00 ); +stv0299_writereg (adapter,0x02 ,0x34 );/* standby off */ +msleep (200 ); + id =stv0299_readreg (adapter,0x00 );dprintk ("%s: id == 0x%02x\n" , __FUNCTION__, id);
@@ -1348,53 +1367,112 @@if (id !=0xa1 && id !=0x80 )return -ENODEV ; -if ((tuner_type =probe_tuner (i2c)) <0 ) +if ((tuner_type =probe_tuner (adapter)) <0 )return -ENODEV ;if ((state =kmalloc (sizeof (struct stv0299_state ),GFP_KERNEL )) ==NULL ) {return -ENOMEM ; } - *data = state; +if (NULL == (client =kmalloc (sizeof (struct i2c_client ),GFP_KERNEL ))) { +kfree (state); +return -ENOMEM ; + } + state->tuner_type = tuner_type; state->tuner_frequency =0 ; state->initialised =0 ; -return dvb_register_frontend (uni0299_ioctl, i2c, (void *) state, - &uni0299_info); + state->i2c = adapter; + +memcpy (client, &client_template,sizeof (struct i2c_client )); + client->adapter = adapter; + client->addr = (0x68 >>1 ); +i2c_set_clientdata (client, (void *)state); + + ret =i2c_attach_client (client); +if (ret) { +kfree (client); +kfree (state); +return -EFAULT ; + } + +BUG_ON (!state->dvb); + + ret =dvb_register_frontend (uni0299_ioctl, state->dvb, state, + &uni0299_info,THIS_MODULE ); +if (ret) { +i2c_detach_client (client); +kfree (client); +kfree (state); +return -EFAULT ; } +return 0 ; +} -static void uni0299_detach (struct dvb_i2c_bus *i2c,void *data) +static int detach_client (struct i2c_client *client) { +struct stv0299_state *state = (struct stv0299_state *)i2c_get_clientdata (client); + +dvb_unregister_frontend_new (uni0299_ioctl, state->dvb); +i2c_detach_client (client); +kfree (client); +kfree (state); +return 0 ; +} + +static int command (struct i2c_client *client,unsigned int cmd,void *arg) +{ +struct stv0299_state *data = (struct stv0299_state *)i2c_get_clientdata (client);dprintk ("%s\n" , __FUNCTION__); -kfree (data); -dvb_unregister_frontend (uni0299_ioctl, i2c); + +switch (cmd) { +case FE_REGISTER : { + data->dvb = (struct dvb_adapter *)arg; +break ; + } +case FE_UNREGISTER : { + data->dvb =NULL ; +break ; + } +default : +return -EOPNOTSUPP ; + } +return 0 ; } +static struct i2c_driver driver = { + .owner =THIS_MODULE , + .name =FRONTEND_NAME , + .id =I2C_DRIVERID_DVBFE_STV0299 , + .flags =I2C_DF_NOTIFY , + .attach_adapter = attach_adapter, + .detach_client = detach_client, + .command = command, +}; + +static struct i2c_client client_template = { + .name =FRONTEND_NAME , + .flags =I2C_CLIENT_ALLOW_USE , + .driver = &driver, +};static int __init init_uni0299 (void ) { -dprintk ("%s\n" , __FUNCTION__); -return dvb_register_i2c_device (NULL , uni0299_attach, uni0299_detach); +return i2c_add_driver (&driver); } - static void __exit exit_uni0299 (void) { -dprintk ("%s\n" , __FUNCTION__); - -dvb_unregister_i2c_device (uni0299_attach); +if (i2c_del_driver (&driver)) +printk ("stv0299: driver deregistration failed\n" ); }module_init (init_uni0299);module_exit (exit_uni0299);MODULE_DESCRIPTION ("Universal STV0299/TSA5059/SL1935 DVB Frontend driver" ); -MODULE_AUTHOR ("Ralph Metzler, Holger Waechtler, Peter Schildmann, Felix Domke, Andreas Oberritter, Andrew de Quincey" ); +MODULE_AUTHOR ("Ralph Metzler, Holger Waechtler, Peter Schildmann, Felix Domke, " +"Andreas Oberritter, Andrew de Quincey, Kenneth Aafl�y" );MODULE_LICENSE ("GPL" ); -MODULE_PARM (stv0299_status,"i" ); -MODULE_PARM_DESC (stv0299_status,"Which status value to support (0: BER, 1: UCBLOCKS)" ); - -MODULE_PARM (disable_typhoon,"i" ); -MODULE_PARM_DESC (disable_typhoon,"Disable support for Philips SU1278 on Typhoon hardware." );
drivers/media/dvb/frontends/tda1004x.c +344 -271
1,010 lines not on this page · raw message
drivers/media/dvb/frontends/ves1820.c +255 -204
731 lines not on this page · raw message
drivers/media/dvb/frontends/ves1x93.c +105 -32
296 lines not on this page · raw message
Re: [PATCH][2.6][6/14] convert frontend drivers to kernel i2c 2/3
- [DVB] alps_tdlb7, alps_tdmb7, at76c651, cx24110, dst: convert from dvb-i2c to kernel-i2c, MODULE_PARM() to module_param(), dvb_delay() to mdelay()
- [DVB] alps_tdlb7: move from home-brewn firmware loading to firmware_class
- [DVB] dst: use sysfs attributes for type and flags for per-card parameters
drivers/media/dvb/frontends/alps_tdlb7.c +168 -141
@@ -20,33 +20,38 @@*/ -/* -This driver needs a copy of the firmware file 'Sc_main.mc' from the Haupauge -windows driver in the '/usr/lib/DVB/driver/frontends' directory. -You can also pass the complete file name with the module parameter 'firmware_file'. +This driver needs a copy of the firmware file from the Technotrend +Windoze driver. + +This page is worth a look: +http://www.heise.de/ct/ftp/projekte/vdr/firmware.shtml + Copy 'Sc_main.mc' to '/usr/lib/hotplug/firmware/dvb-fe-tdlb7-2.16.fw'. */ +#define SP887X_DEFAULT_FIRMWARE "dvb-fe-tdlb7-2.16.fw" -#include <linux/module.h> #include <linux/init.h> -#include <linux/vmalloc.h> -#include <linux/fs.h> -#include <linux/unistd.h> +#include <linux/module.h> +#include <linux/moduleparam.h> +#include <linux/device.h> +#include <linux/firmware.h> #include <linux/delay.h> -#include <linux/syscalls.h> #include "dvb_frontend.h" -#include "dvb_functions.h" -#ifndef CONFIG_ALPS_TDLB7_FIRMWARE_LOCATION -#define CONFIG_ALPS_TDLB7_FIRMWARE_LOCATION "/usr/lib/DVB/driver/frontends/Sc_main.mc" -#endif +#define FRONTEND_NAME "dvbfe_alps_tdlb7" + +#define dprintk(args...) \ + do { \ + if (debug) printk(KERN_DEBUG FRONTEND_NAME ": " args); \ + } while (0) + +static int debug; -static char * firmware_file =CONFIG_ALPS_TDLB7_FIRMWARE_LOCATION ; -static int debug =0 ; +module_param (debug, int,0644 ); +MODULE_PARM_DESC (debug,"Turn on/off frontend debugging (default:off)." ); -#define dprintk if (debug) printk/* firmware size for sp8870 */ #define SP8870_FIRMWARE_SIZE 16382
@@ -54,9 +59,6 @@/* starting point for firmware in file 'Sc_main.mc' */ #define SP8870_FIRMWARE_OFFSET 0x0A - -static int errno; -static struct dvb_frontend_info tdlb7_info = { .name ="Alps TDLB7" , .type =FE_OFDM ,
@@ -71,14 +73,18 @@ FE_CAN_HIERARCHY_AUTO | FE_CAN_RECOVER }; +struct tdlb7_state { +struct i2c_adapter *i2c; +struct dvb_adapter *dvb; +}; -static int sp8870_writereg (struct dvb_i2c_bus *i2c,u16 reg,u16 data) +static int sp8870_writereg (struct i2c_adapter *i2c,u16 reg,u16 data) {u8 buf [] = { reg >>8 , reg &0xff , data >>8 , data &0xff };struct i2c_msg msg = { .addr =0x71 , .flags =0 , .buf = buf, .len =4 };int err; -if ((err = i2c->xfer (i2c, &msg,1 )) !=1 ) { +if ((err =i2c_transfer (i2c, &msg,1 )) !=1 ) {dprintk ("%s: writereg error (err == %i, reg == 0x%02x, data == 0x%02x)\n" , __FUNCTION__, err, reg, data);return -EREMOTEIO ; }
@@ -86,8 +92,7 @@return 0 ; } - -static u16 sp8870_readreg (struct dvb_i2c_bus *i2c,u16 reg) +static u16 sp8870_readreg (struct i2c_adapter *i2c,u16 reg) {int ret;u8 b0 [] = { reg >>8 , reg &0xff };
@@ -95,7 +100,7 @@struct i2c_msg msg [] = { { .addr =0x71 , .flags =0 , .buf = b0, .len =2 }, { .addr =0x71 , .flags =I2C_M_RD , .buf = b1, .len =2 } }; - ret = i2c->xfer (i2c, msg,2 ); + ret =i2c_transfer (i2c, msg,2 );if (ret !=2 ) {dprintk ("%s: readreg error (ret == %i)\n" , __FUNCTION__, ret);
@@ -105,22 +110,26 @@return (b1[0 ] <<8 | b1[1 ]); } - -static int sp5659_write (struct dvb_i2c_bus *i2c,u8 data [4 ]) +static int sp5659_write (struct i2c_adapter *i2c,u8 data [4 ]) {int ret; -struct i2c_msg msg = { .addr =0x60 , .flags =0 , .buf = data, .len =4 }; - ret = i2c->xfer (i2c, &msg,1 ); +u8 buf_open [] = {0x206 >>8 ,0x206 &0xff ,0x001 >>8 ,0x001 &0xff }; +u8 buf_close [] = {0x206 >>8 ,0x206 &0xff ,0x000 >>8 ,0x000 &0xff }; + +struct i2c_msg msg[3 ] = { {.addr =0x71 , .flags =0 , .buf = buf_open, .len =4 }, + {.addr =0x60 , .flags =0 , .buf = data, .len =4 }, + {.addr =0x71 , .flags =0 , .buf = buf_close, .len =4 } }; -if (ret !=1 ) + ret =i2c_transfer (i2c, &msg[0 ],3 ); + +if (ret !=3 )printk ("%s: i/o error (ret == %i)\n" , __FUNCTION__, ret); -return (ret !=1 ) ?-1 :0 ; +return (ret !=3 ) ? -EREMOTEIO :0 ; } - -static void sp5659_set_tv_freq (struct dvb_i2c_bus *i2c,u32 freq) +static void sp5659_set_tv_freq (struct i2c_adapter *i2c,u32 freq) {u32 div = (freq +36200000 ) /166666 ;u8 buf [4 ];
@@ -137,65 +146,23 @@ buf[3 ] = pwr <<6 ;/* open i2c gate for PLL message transmission... */ -sp8870_writereg (i2c,0x206 ,0x001 );sp5659_write (i2c, buf); -sp8870_writereg (i2c,0x206 ,0x000 ); } - -static int sp8870_read_firmware_file (const char *fn,char **fp) -{ -int fd; -loff_t filesize; -char *dp; - - fd =sys_open (fn,0 ,0 ); -if (fd ==-1 ) { -printk ("%s: unable to open '%s'.\n" , __FUNCTION__, fn); -return -EIO ; - } - - filesize =sys_lseek (fd,0L ,2 ); -if (filesize <=0 || filesize <SP8870_FIRMWARE_OFFSET +SP8870_FIRMWARE_SIZE ) { -printk ("%s: firmware filesize to small '%s'\n" , __FUNCTION__, fn); -sys_close (fd); -return -EIO ; - } - - *fp= dp =vmalloc (SP8870_FIRMWARE_SIZE ); -if (dp ==NULL ) { -printk ("%s: out of memory loading '%s'.\n" , __FUNCTION__, fn); -sys_close (fd); -return -EIO ; - } - -sys_lseek (fd,SP8870_FIRMWARE_OFFSET ,0 ); -if (sys_read (fd, dp,SP8870_FIRMWARE_SIZE ) !=SP8870_FIRMWARE_SIZE ) { -printk ("%s: failed to read '%s'.\n" ,__FUNCTION__, fn); -vfree (dp); -sys_close (fd); -return -EIO ; - } - -sys_close (fd); - *fp = dp; - -return 0 ; -} - - -static int sp8870_firmware_upload (struct dvb_i2c_bus *i2c) +static int sp8870_firmware_upload (struct i2c_adapter *i2c,const struct firmware *fw) {struct i2c_msg msg; -char *fw_buf =NULL ; +char *fw_buf = fw->data;int fw_pos;u8 tx_buf[255 ];int tx_len;int err =0 ; -mm_segment_t fs =get_fs ();dprintk ("%s: ...\n" , __FUNCTION__); +if (fw->size <SP8870_FIRMWARE_SIZE +SP8870_FIRMWARE_OFFSET ) +return -EINVAL ; +// system controller stop sp8870_writereg (i2c,0x0F00 ,0x0000 );
@@ -205,19 +172,10 @@// instruction RAM MWR sp8870_writereg (i2c,0x8F0A , ((SP8870_FIRMWARE_SIZE /2 ) >>16 )); -// reading firmware file to buffer -set_fs (get_ds ()); - err =sp8870_read_firmware_file (firmware_file, (char **) &fw_buf); -set_fs (fs); -if (err !=0 ) { -printk ("%s: reading firmware file failed!\n" , __FUNCTION__); -return err; - } -// do firmware upload - fw_pos =0 ; -while (fw_pos <SP8870_FIRMWARE_SIZE ){ - tx_len = (fw_pos <=SP8870_FIRMWARE_SIZE -252 ) ?252 :SP8870_FIRMWARE_SIZE - fw_pos; + fw_pos =SP8870_FIRMWARE_OFFSET ; +while (fw_pos <SP8870_FIRMWARE_SIZE +SP8870_FIRMWARE_OFFSET ){ + tx_len = (fw_pos <=SP8870_FIRMWARE_SIZE +SP8870_FIRMWARE_OFFSET -252 ) ?252 :SP8870_FIRMWARE_SIZE +SP8870_FIRMWARE_OFFSET - fw_pos;// write register 0xCF0A tx_buf[0 ] =0xCF ; tx_buf[1 ] =0x0A ;
@@ -226,23 +184,19 @@ msg.flags=0 ; msg.buf = tx_buf; msg.len = tx_len +2 ; -if ((err = i2c->xfer (i2c, &msg,1 )) !=1 ) { +if ((err =i2c_transfer (i2c, &msg,1 )) !=1 ) {printk ("%s: firmware upload failed!\n" , __FUNCTION__);printk ("%s: i2c error (err == %i)\n" , __FUNCTION__, err); -vfree (fw_buf);return err; } fw_pos += tx_len; } -vfree (fw_buf); -dprintk ("%s: done!\n" , __FUNCTION__);return 0 ; }; - -static void sp8870_microcontroller_stop (struct dvb_i2c_bus *i2c) +static void sp8870_microcontroller_stop (struct i2c_adapter *i2c) {sp8870_writereg (i2c,0x0F08 ,0x000 );sp8870_writereg (i2c,0x0F09 ,0x000 );
@@ -251,8 +205,7 @@sp8870_writereg (i2c,0x0F00 ,0x000 ); } - -static void sp8870_microcontroller_start (struct dvb_i2c_bus *i2c) +static void sp8870_microcontroller_start (struct i2c_adapter *i2c) {sp8870_writereg (i2c,0x0F08 ,0x000 );sp8870_writereg (i2c,0x0F09 ,0x000 );
@@ -264,8 +217,7 @@sp8870_readreg (i2c,0x0D01 ); } - -static int sp8870_init (struct dvb_i2c_bus *i2c) +static int sp8870_init (struct i2c_adapter *i2c) {dprintk ("%s\n" , __FUNCTION__);
@@ -291,8 +243,7 @@return 0 ; } - -static int sp8870_read_status (struct dvb_i2c_bus *i2c,fe_status_t * fe_status) +static int sp8870_read_status (struct i2c_adapter *i2c,fe_status_t * fe_status) {int status;int signal;
@@ -317,8 +268,7 @@return 0 ; } - -static int sp8870_read_ber (struct dvb_i2c_bus *i2c,u32 * ber) +static int sp8870_read_ber (struct i2c_adapter *i2c,u32 * ber) {int ret;u32 tmp;
@@ -345,8 +295,7 @@return 0 ; } - -static int sp8870_read_signal_strength (struct dvb_i2c_bus *i2c,u16 * signal) +static int sp8870_read_signal_strength (struct i2c_adapter *i2c,u16 * signal) {int ret;u16 tmp;
@@ -371,15 +320,13 @@return 0 ; } - -static int sp8870_read_snr (struct dvb_i2c_bus *i2c,u32 * snr) +static int sp8870_read_snr (struct i2c_adapter *i2c,u32 * snr) { *snr=0 ;return -EOPNOTSUPP ; } - -static int sp8870_read_uncorrected_blocks (struct dvb_i2c_bus *i2c,u32 * ublocks) +static int sp8870_read_uncorrected_blocks (struct i2c_adapter *i2c,u32 * ublocks) {int ret;
@@ -397,8 +344,7 @@return 0 ; } - -static int sp8870_read_data_valid_signal (struct dvb_i2c_bus *i2c) +static int sp8870_read_data_valid_signal (struct i2c_adapter *i2c) {return (sp8870_readreg (i2c,0x0D02 ) >0 ); }
@@ -476,8 +421,7 @@return 0 ; } - -static int sp8870_set_frontend_parameters (struct dvb_i2c_bus *i2c, +static int sp8870_set_frontend_parameters (struct i2c_adapter *i2c,struct dvb_frontend_parameters *p) {int err;
@@ -540,7 +483,7 @@// only for debugging: counter for channel switches static int switches =0 ; -static int sp8870_set_frontend (struct dvb_i2c_bus *i2c,struct dvb_frontend_parameters *p) +static int sp8870_set_frontend (struct i2c_adapter *i2c,struct dvb_frontend_parameters *p) {/* The firmware of the sp8870 sometimes locks up after setting frontend parameters.
@@ -595,15 +538,13 @@return 0 ; } - -static int sp8870_sleep (struct dvb_i2c_bus *i2c) +static int sp8870_sleep (struct i2c_adapter *i2c) {// tristate TS output and disable interface pins return sp8870_writereg (i2c,0xC18 ,0x000 ); } - -static int sp8870_wake_up (struct dvb_i2c_bus *i2c) +static int sp8870_wake_up (struct i2c_adapter *i2c) {// enable TS output and interface pins return sp8870_writereg (i2c,0xC18 ,0x00D );
@@ -609,10 +550,10 @@return sp8870_writereg (i2c,0xC18 ,0x00D ); } -static int tdlb7_ioctl (struct dvb_frontend *fe,unsigned int cmd,void *arg) { -struct dvb_i2c_bus *i2c = fe->i2c; +struct tdlb7_state *state = (struct tdlb7_state *) fe->data; +struct i2c_adapter *i2c = state->i2c;switch (cmd) {case FE_GET_INFO :
@@ -667,9 +608,15 @@return 0 ; } +static struct i2c_client client_template; -static int tdlb7_attach (struct dvb_i2c_bus *i2c,void **data) +static int attach_adapter (struct i2c_adapter *adapter) { +struct i2c_client *client; +struct tdlb7_state *state; +const struct firmware *fw; +int ret; +u8 b0 [] = {0x02 ,0x00 };u8 b1 [] = {0 ,0 };struct i2c_msg msg [] = { { .addr =0x71 , .flags =0 , .buf = b0, .len =2 },
@@ -677,48 +624,126 @@dprintk ("%s\n" , __FUNCTION__); -if (i2c->xfer (i2c, msg,2 ) !=2 ) +if (NULL == (client =kmalloc (sizeof (struct i2c_client ),GFP_KERNEL ))) { +return -ENOMEM ; + } + +if (NULL == (state =kmalloc (sizeof (struct tdlb7_state ),GFP_KERNEL ))) { +kfree (client); +return -ENOMEM ; + } + state->i2c = adapter; + +if (i2c_transfer (adapter, msg,2 ) !=2 ) { +kfree (state); +kfree (client);return -ENODEV ; + } -sp8870_firmware_upload (i2c); +memcpy (client, &client_template,sizeof (struct i2c_client )); + client->adapter = adapter; +i2c_set_clientdata (client, (void *)state); -return dvb_register_frontend (tdlb7_ioctl, i2c,NULL , &tdlb7_info); + ret =i2c_attach_client (client); +if (ret) { +kfree (client); +kfree (state); +return ret; } +/* request the firmware, this will block until someone uploads it */ +printk ("tdlb7: waiting for firmware upload...\n" ); + ret =request_firmware (&fw,SP887X_DEFAULT_FIRMWARE , &client->dev); +if (ret) { +printk ("tdlb7: no firmware upload (timeout or file not found?)\n" ); + goto out; + } -static void tdlb7_detach (struct dvb_i2c_bus *i2c,void *data) -{ -dprintk ("%s\n" , __FUNCTION__); + ret =sp8870_firmware_upload (adapter, fw); +if (ret) { +printk ("tdlb7: writing firmware to device failed\n" ); +release_firmware (fw); + goto out; + } -dvb_unregister_frontend (tdlb7_ioctl, i2c); + ret =dvb_register_frontend (tdlb7_ioctl, state->dvb, state, + &tdlb7_info,THIS_MODULE ); +if (ret) { +printk ("tdlb7: registering frontend to dvb-core failed.\n" ); +release_firmware (fw); + goto out; } +return 0 ; +out: +i2c_detach_client (client); +kfree (client); +kfree (state); +return ret; +} -static int __init init_tdlb7 (void ) +static int detach_client (struct i2c_client *client) { +struct tdlb7_state *state = (struct tdlb7_state *)i2c_get_clientdata (client); +dprintk ("%s\n" , __FUNCTION__); -return dvb_register_i2c_device (THIS_MODULE , tdlb7_attach, tdlb7_detach); +dvb_unregister_frontend_new (tdlb7_ioctl, state->dvb); +i2c_detach_client (client); +BUG_ON (state->dvb); +kfree (client); +kfree (state); +return 0 ; } - -static void __exit exit_tdlb7 (void) +static int command (struct i2c_client *client,unsigned int cmd,void *arg) { +struct tdlb7_state *state = (struct tdlb7_state *)i2c_get_clientdata (client); +dprintk ("%s\n" , __FUNCTION__); -dvb_unregister_i2c_device (tdlb7_attach); +switch (cmd) { +case FE_REGISTER : + state->dvb = (struct dvb_adapter *)arg; +break ; +case FE_UNREGISTER : + state->dvb =NULL ; +break ; +default : +return -EOPNOTSUPP ; + } +return 0 ; } +static struct i2c_driver driver = { + .owner =THIS_MODULE , + .name =FRONTEND_NAME , + .id =I2C_DRIVERID_DVBFE_ALPS_TDLB7 , + .flags =I2C_DF_NOTIFY , + .attach_adapter = attach_adapter, + .detach_client = detach_client, + .command = command, +}; -module_init (init_tdlb7); -module_exit (exit_tdlb7); +static struct i2c_client client_template = { + .name =FRONTEND_NAME , + .flags =I2C_CLIENT_ALLOW_USE , + .driver = &driver, +}; +static int __init init_tdlb7 (void ) +{ +return i2c_add_driver (&driver); +} -MODULE_PARM (debug,"i" ); -MODULE_PARM_DESC (debug,"enable verbose debug messages" ); +static void __exit exit_tdlb7(void) +{ +if (i2c_del_driver (&driver)) +printk ("tdlb7: driver deregistration failed\n" ); +} -MODULE_PARM (firmware_file,"s" ); -MODULE_PARM_DESC (firmware_file,"where to find the firmware file" ); +module_init (init_tdlb7); +module_exit (exit_tdlb7);MODULE_DESCRIPTION ("TDLB7 DVB-T Frontend" );MODULE_AUTHOR ("Juergen Peitz" );
drivers/media/dvb/frontends/alps_tdmb7.c +115 -38
287 lines not on this page · raw message
drivers/media/dvb/frontends/at76c651.c +220 -179
678 lines not on this page · raw message
drivers/media/dvb/frontends/cx24110.c +130 -38
321 lines not on this page · raw message
drivers/media/dvb/frontends/dst.c +215 -142
608 lines not on this page · raw message
Re: [PATCH][2.6][7/14] convert frontend drivers to kernel i2c 3/3
- [DVB] dvb_dummy_fe, grundig_29504-401, grundig_29504-491, mt312: convert from dvb-i2c to kernel-i2c, MODULE_PARM() to module_param(), dvb_delay() to mdelay()
- [DVB] update frontend Kconfig
drivers/media/dvb/frontends/dvb_dummy_fe.c +75 -13
@@ -20,12 +20,16 @@*/ #include <linux/module.h> +#include <linux/moduleparam.h> #include <linux/init.h> #include "dvb_frontend.h" -static int sct =0 ; +#define FRONTEND_NAME "dvbfe_dummy" +static int frontend_type; +module_param (frontend_type, int,0444 ); +MODULE_PARM_DESC (frontend_type,"0 == DVB-S, 1 == DVB-C, 2 == DVB-T" );/* depending on module parameter sct deliver different infos */
@@ -87,8 +91,7 @@struct dvb_frontend_info *frontend_info (void ) { -switch (sct) - { +switch (frontend_type) {case 2 :return &dvb_t_dummyfe_info;case 1 :
@@ -168,30 +171,89 @@return 0 ; } +static struct i2c_client client_template; -static int dvbdummyfe_attach (struct dvb_i2c_bus *i2c,void **data) +static int dvbdummyfe_attach_adapter (struct i2c_adapter *adapter) { -return dvb_register_frontend (dvbdummyfe_ioctl, i2c,NULL ,frontend_info ()); +struct dvb_adapter *dvb; +struct i2c_client *client; +int ret; + +if ((client =kmalloc (sizeof (struct i2c_client ),GFP_KERNEL )) ==NULL ) +return -ENOMEM ; + +memcpy (client, &client_template,sizeof (struct i2c_client )); + client->adapter = adapter; + +if ((ret =i2c_attach_client (client))) { +kfree (client); +return ret; } + dvb =i2c_get_clientdata (client); +BUG_ON (!dvb); -static void dvbdummyfe_detach (struct dvb_i2c_bus *i2c,void *data) +if ((ret =dvb_register_frontend (dvbdummyfe_ioctl, dvb,NULL , +frontend_info (),THIS_MODULE ))) { +kfree (client); +return ret; + } + +return 0 ; +} + + +static int dvbdummyfe_detach_client (struct i2c_client *client) { -dvb_unregister_frontend (dvbdummyfe_ioctl, i2c); +struct dvb_adapter *dvb =i2c_get_clientdata (client); + +dvb_unregister_frontend_new (dvbdummyfe_ioctl, dvb); +i2c_detach_client (client); +kfree (client); +return 0 ; } +static int dvbdummyfe_command (struct i2c_client *client, +unsigned int cmd,void *arg) +{ +switch (cmd) { +case FE_REGISTER : +i2c_set_clientdata (client, arg); +break ; +case FE_UNREGISTER : +break ; +default : +return -EOPNOTSUPP ; + } + +return 0 ; +} + +static struct i2c_driver driver = { + .owner =THIS_MODULE , + .name =FRONTEND_NAME , + .id =I2C_DRIVERID_DVBFE_DUMMY , + .flags =I2C_DF_NOTIFY , + .attach_adapter = dvbdummyfe_attach_adapter, + .detach_client = dvbdummyfe_detach_client, + .command = dvbdummyfe_command, +}; + +static struct i2c_client client_template = { + .name =FRONTEND_NAME , + .flags =I2C_CLIENT_ALLOW_USE , + .driver = &driver, +};static int __init init_dvbdummyfe (void ) { -return dvb_register_i2c_device (THIS_MODULE , - dvbdummyfe_attach, - dvbdummyfe_detach); +return i2c_add_driver (&driver); } - static void __exit exit_dvbdummyfe (void) { -dvb_unregister_i2c_device (dvbdummyfe_attach); +if (i2c_del_driver (&driver)) +printk (KERN_ERR "dummyfe: driver deregistration failed.\n" ); }
@@ -202,4 +263,4 @@MODULE_DESCRIPTION ("DVB DUMMY Frontend" );MODULE_AUTHOR ("Emard" );MODULE_LICENSE ("GPL" ); -MODULE_PARM (sct,"i" ); +
drivers/media/dvb/frontends/grundig_29504-401.c +154 -69
400 lines not on this page · raw message
drivers/media/dvb/frontends/grundig_29504-491.c +132 -40
332 lines not on this page · raw message
drivers/media/dvb/frontends/Kconfig +75 -88
256 lines not on this page · raw message
drivers/media/dvb/frontends/mt312.c +163 -81
547 lines not on this page · raw message
Re: [PATCH][2.6][8/14] some more frontend drivers to converted to kernel i2c
- [DVB] nxt6000, sp887x: convert from dvb-i2c to kernel-i2c, MODULE_PARM() to module_param(), dvb_delay() to mdelay()
- [DVB] sp887x: move from home-brewn firmware loading to firmware_class
drivers/media/dvb/frontends/nxt6000.c +124 -114
@@ -36,11 +34,11 @@#include "dvb_frontend.h" #include "nxt6000.h" -static int debug =0 ; -MODULE_DESCRIPTION ("NxtWave NXT6000 DVB demodulator driver" );MODULE_AUTHOR ("Florian Schirmer" );MODULE_LICENSE ("GPL" ); + +static int debug =0 ;MODULE_PARM (debug,"i" );static struct dvb_frontend_info nxt6000_info = {
@@ -68,20 +65,21 @@u8 tuner_addr;u8 tuner_type;u8 clock_inversion; +struct i2c_adapter *i2c; +struct dvb_adapter *dvb; };#define TUNER_TYPE_ALP510 0#define TUNER_TYPE_SP5659 1#define TUNER_TYPE_SP5730 2 -#define FE2NXT (fe) ((struct nxt6000_config *)((fe)->data)) +// #define FE2NXT(fe) ((struct nxt6000_config *)((fe)->data)) #define FREQ2DIV (freq) ((freq + 36166667) / 166667)#define dprintk if (debug) printk -static int nxt6000_write (struct dvb_i2c_bus *i2c,u8 addr,u8 reg,u8 data) +static int nxt6000_write (struct i2c_adapter *i2c,u8 addr,u8 reg,u8 data) { -u8 buf[] = {reg, data};struct i2c_msg msg = {.addr = addr >>1 , .flags =0 , .buf = buf, .len =2 };int ret;
@@ -86,7 +84,7 @@struct i2c_msg msg = {.addr = addr >>1 , .flags =0 , .buf = buf, .len =2 };int ret; -if ((ret = i2c->xfer (i2c, &msg,1 )) !=1 ) +if ((ret =i2c_transfer (i2c, &msg,1 )) !=1 )dprintk ("nxt6000: nxt6000_write error (.addr = 0x%02X, reg: 0x%02X, data: 0x%02X, ret: %d)\n" , addr, reg, data, ret);return (ret !=1 ) ? -EFAULT :0 ;
@@ -90,21 +88,15 @@dprintk ("nxt6000: nxt6000_write error (.addr = 0x%02X, reg: 0x%02X, data: 0x%02X, ret: %d)\n" , addr, reg, data, ret);return (ret !=1 ) ? -EFAULT :0 ; - } -static u8 nxt6000_writereg (struct dvb_frontend *fe,u8 reg,u8 data) +static u8 nxt6000_writereg (struct nxt6000_config *nxt,u8 reg,u8 data) { - -struct nxt6000_config *nxt =FE2NXT (fe); - -return nxt6000_write (fe->i2c, nxt->demod_addr, reg, data); - +return nxt6000_write (nxt->i2c, nxt->demod_addr, reg, data); } -static u8 nxt6000_read (struct dvb_i2c_bus *i2c,u8 addr,u8 reg) +static u8 nxt6000_read (struct i2c_adapter *i2c,u8 addr,u8 reg) { -int ret;u8 b0[] = {reg};u8 b1[] = {0 };
@@ -113,7 +105,7 @@ {.addr = addr >> 1,.flags = I2C_M_RD,.buf = b1,.len = 1} }; - ret = i2c->xfer (i2c, msgs,2 ); + ret =i2c_transfer (i2c, msgs,2 );if (ret !=2 )dprintk ("nxt6000: nxt6000_read error (.addr = 0x%02X, reg: 0x%02X, ret: %d)\n" , addr, reg, ret);
@@ -119,33 +111,28 @@dprintk ("nxt6000: nxt6000_read error (.addr = 0x%02X, reg: 0x%02X, ret: %d)\n" , addr, reg, ret);return b1[0 ]; - } -static u8 nxt6000_readreg (struct dvb_frontend *fe,u8 reg) +static u8 nxt6000_readreg (struct nxt6000_config *nxt,u8 reg) { - -struct nxt6000_config *nxt =FE2NXT (fe); - -return nxt6000_read (fe->i2c, nxt->demod_addr, reg); +return nxt6000_read (nxt->i2c, nxt->demod_addr, reg); } -static int pll_test (struct dvb_i2c_bus *i2c,u8 demod_addr,u8 tuner_addr) +static int pll_test (struct i2c_adapter *i2c,u8 demod_addr,u8 tuner_addr) {u8 buf [1 ];struct i2c_msg msg = {.addr = tuner_addr >>1 ,.flags =I2C_M_RD ,.buf = buf,.len =1 };int ret;nxt6000_write (i2c, demod_addr,ENABLE_TUNER_IIC ,0x01 );/* open i2c bus switch */ - ret = i2c->xfer (i2c, &msg,1 ); + ret =i2c_transfer (i2c, &msg,1 );nxt6000_write (i2c, demod_addr,ENABLE_TUNER_IIC ,0x00 );/* close i2c bus switch */ return (ret !=1 ) ? -EFAULT :0 ; } -static int pll_write (struct dvb_i2c_bus *i2c,u8 demod_addr,u8 tuner_addr,u8 *buf,u8 len) +static int pll_write (struct i2c_adapter *i2c,u8 demod_addr,u8 tuner_addr,u8 * buf,u8 len) { -struct i2c_msg msg = {.addr = tuner_addr >>1 , .flags =0 , .buf = buf, .len = len};int ret;
@@ -150,7 +137,7 @@int ret;nxt6000_write (i2c, demod_addr,ENABLE_TUNER_IIC ,0x01 );/* open i2c bus switch */ - ret = i2c->xfer (i2c, &msg,1 ); + ret =i2c_transfer (i2c, &msg,1 );nxt6000_write (i2c, demod_addr,ENABLE_TUNER_IIC ,0x00 );/* close i2c bus switch */ if (ret !=1 )
@@ -157,14 +144,11 @@dprintk ("nxt6000: pll_write error %d\n" , ret);return (ret !=1 ) ? -EFAULT :0 ; - } -static int sp5659_set_tv_freq (struct dvb_frontend *fe,u32 freq) +static int sp5659_set_tv_freq (struct nxt6000_config *nxt,u32 freq) { -u8 buf[4 ]; -struct nxt6000_config *nxt =FE2NXT (fe); buf[0 ] = (FREQ2DIV (freq) >>8 ) &0x7F ; buf[1 ] =FREQ2DIV (freq) &0xFF ;
@@ -179,15 +163,12 @@else return -EINVAL ; -return pll_write (fe->i2c, nxt->demod_addr, nxt->tuner_addr, buf,4 ); - +return pll_write (nxt->i2c, nxt->demod_addr, nxt->tuner_addr, buf,4 ); } -static int alp510_set_tv_freq (struct dvb_frontend *fe,u32 freq) +static int alp510_set_tv_freq (struct nxt6000_config *nxt,u32 freq) { -u8 buf[4 ]; -struct nxt6000_config *nxt =FE2NXT (fe); buf[0 ] = (FREQ2DIV (freq) >>8 ) &0x7F ; buf[1 ] =FREQ2DIV (freq) &0xFF ;
@@ -217,15 +198,12 @@return -EINVAL ;#endif -return pll_write (fe->i2c, nxt->demod_addr, nxt->tuner_addr, buf,4 ); - +return pll_write (nxt->i2c, nxt->demod_addr, nxt->tuner_addr, buf,4 ); } -static int sp5730_set_tv_freq (struct dvb_frontend *fe,u32 freq) +static int sp5730_set_tv_freq (struct nxt6000_config *nxt,u32 freq) { -u8 buf[4 ]; -struct nxt6000_config *nxt =FE2NXT (fe); buf[0 ] = (FREQ2DIV (freq) >>8 ) &0x7F ; buf[1 ] =FREQ2DIV (freq) &0xFF ;
@@ -250,13 +228,11 @@else return -EINVAL ; -return pll_write (fe->i2c, nxt->demod_addr, nxt->tuner_addr, buf,4 ); - +return pll_write (nxt->i2c, nxt->demod_addr, nxt->tuner_addr, buf,4 ); } -static void nxt6000_reset (struct dvb_frontend *fe) +static void nxt6000_reset (struct nxt6000_config *fe) { -u8 val; val =nxt6000_readreg (fe,OFDM_COR_CTL );
@@ -263,12 +239,10 @@nxt6000_writereg (fe,OFDM_COR_CTL , val & ~COREACT );nxt6000_writereg (fe,OFDM_COR_CTL , val |COREACT ); - } -static int nxt6000_set_bandwidth (struct dvb_frontend *fe,fe_bandwidth_t bandwidth) +static int nxt6000_set_bandwidth (struct nxt6000_config *fe,fe_bandwidth_t bandwidth) { -u16 nominal_rate;int result;
@@ -302,12 +268,10 @@return result;return nxt6000_writereg (fe,OFDM_TRL_NOMINALRATE_2 , (nominal_rate >>8 ) &0xFF ); - } -static int nxt6000_set_guard_interval (struct dvb_frontend *fe,fe_guard_interval_t guard_interval) +static int nxt6000_set_guard_interval (struct nxt6000_config *fe,fe_guard_interval_t guard_interval) { -switch (guard_interval) {case GUARD_INTERVAL_1_32 :
@@ -328,16 +288,12 @@return nxt6000_writereg (fe,OFDM_COR_MODEGUARD ,0x03 | (nxt6000_readreg (fe,OFDM_COR_MODEGUARD ) & ~0x03 ));default : -return -EINVAL ; - } - } -static int nxt6000_set_inversion (struct dvb_frontend *fe,fe_spectral_inversion_t inversion) +static int nxt6000_set_inversion (struct nxt6000_config *fe,fe_spectral_inversion_t inversion) { -switch (inversion) {case INVERSION_OFF :
@@ -353,12 +306,10 @@return -EINVAL ; } - } -static int nxt6000_set_transmission_mode (struct dvb_frontend *fe,fe_transmit_mode_t transmission_mode) +static int nxt6000_set_transmission_mode (struct nxt6000_config *fe,fe_transmit_mode_t transmission_mode) { -int result;switch (transmission_mode) {
@@ -383,14 +331,10 @@return -EINVAL ; } - } -static void nxt6000_setup (struct dvb_frontend *fe) +static void nxt6000_setup (struct nxt6000_config *fe) { - -struct nxt6000_config *nxt =FE2NXT (fe); -nxt6000_writereg (fe,RS_COR_SYNC_PARAM ,SYNC_PARAM );nxt6000_writereg (fe,BER_CTRL ,/*(1 << 2) |*/ (0x01 <<1 ) |0x01 );nxt6000_writereg (fe,VIT_COR_CTL ,VIT_COR_RESYNC );
@@ -409,7 +353,7 @@nxt6000_writereg (fe,EN_DMD_RACQ , (1 <<7 ) | (3 <<4 ) |2 );nxt6000_writereg (fe,DIAG_CONFIG ,TB_SET ); -if (nxt->clock_inversion) +if (fe->clock_inversion)nxt6000_writereg (fe,SUB_DIAG_MODE_SEL ,CLKINVERSION );else nxt6000_writereg (fe,SUB_DIAG_MODE_SEL ,0 );
@@ -415,10 +359,9 @@nxt6000_writereg (fe,SUB_DIAG_MODE_SEL ,0 );nxt6000_writereg (fe,TS_FORMAT ,0 ); - } -static void nxt6000_dump_status (struct dvb_frontend *fe) +static void nxt6000_dump_status (struct nxt6000_config *fe) {u8 val;
@@ -673,13 +567,12 @@ val =nxt6000_readreg (fe,RF_AGC_STATUS );printk (" RF AGC LOCK: %d," , (val >>4 ) &0x01 ); -printk ("\n" ); - } -static int nxt6000_ioctl (struct dvb_frontend *fe,unsigned int cmd,void *arg) +static int nxt6000_ioctl (struct dvb_frontend *f,unsigned int cmd,void *arg) { +struct nxt6000_config *fe = (struct nxt6000_config *) f->data;switch (cmd) {
@@ -769,17 +659,14 @@case FE_SET_FRONTEND : { -struct nxt6000_config *nxt =FE2NXT (fe);struct dvb_frontend_parameters *param = (struct dvb_frontend_parameters *)arg;int result; -switch (nxt->tuner_type) { +switch (fe->tuner_type) {case TUNER_TYPE_ALP510 : -if ((result =alp510_set_tv_freq (fe, param->frequency)) <0 )return result; -break ;case TUNER_TYPE_SP5659 :
@@ -826,42 +705,41 @@static u8 demod_addr_tbl[] = {0x14 ,0x18 ,0x24 ,0x28 }; -static int nxt6000_attach (struct dvb_i2c_bus *i2c,void **data) +static struct i2c_client client_template; + +static int attach_adapter (struct i2c_adapter *adapter) { +struct i2c_client *client; +struct nxt6000_config *nxt;u8 addr_nr; -u8 fe_count =0 ; -struct nxt6000_config *pnxt; - -dprintk ("nxt6000: attach\n" ); +int ret; - pnxt =kmalloc (sizeof (demod_addr_tbl)*sizeof (struct nxt6000_config ),GFP_KERNEL ); -if (NULL == pnxt) { -dprintk ("nxt6000: no memory for private data.\n" ); +if ((nxt =kmalloc (sizeof (struct nxt6000_config ),GFP_KERNEL )) ==NULL )return -ENOMEM ; - } - *data = pnxt; + +memset (nxt,0 ,sizeof (*nxt)); + nxt->i2c = adapter;for (addr_nr =0 ; addr_nr <sizeof (demod_addr_tbl); addr_nr++) { -struct nxt6000_config *nxt = &pnxt[addr_nr]; -if (nxt6000_read (i2c, demod_addr_tbl[addr_nr],OFDM_MSC_REV ) !=NXT6000ASICDEVICE ) +if (nxt6000_read (adapter, demod_addr_tbl[addr_nr],OFDM_MSC_REV ) !=NXT6000ASICDEVICE )continue ; -if (pll_test (i2c, demod_addr_tbl[addr_nr],0xC0 ) ==0 ) { +if (pll_test (adapter, demod_addr_tbl[addr_nr],0xC0 ) ==0 ) { nxt->tuner_addr =0xC0 ; nxt->tuner_type =TUNER_TYPE_ALP510 ; nxt->clock_inversion =1 ;dprintk ("nxt6000: detected TI ALP510 tuner at 0x%02X\n" , nxt->tuner_addr); - }else if (pll_test (i2c, demod_addr_tbl[addr_nr],0xC2 ) ==0 ) { + }else if (pll_test (adapter, demod_addr_tbl[addr_nr],0xC2 ) ==0 ) { nxt->tuner_addr =0xC2 ; nxt->tuner_type =TUNER_TYPE_SP5659 ; nxt->clock_inversion =0 ;dprintk ("nxt6000: detected MITEL SP5659 tuner at 0x%02X\n" , nxt->tuner_addr); - }else if (pll_test (i2c, demod_addr_tbl[addr_nr],0xC0 ) ==0 ) { + }else if (pll_test (adapter, demod_addr_tbl[addr_nr],0xC0 ) ==0 ) { nxt->tuner_addr =0xC0 ; nxt->tuner_type =TUNER_TYPE_SP5730 ; nxt->clock_inversion =0 ;
@@ -872,48 +750,99 @@printk ("nxt6000: unable to detect tuner\n" );continue ; } - - nxt->demod_addr = demod_addr_tbl[addr_nr]; - -dprintk ("nxt6000: attached at %d:%d\n" , i2c->adapter->num, i2c->id); - -dvb_register_frontend (nxt6000_ioctl, i2c, (void *)nxt, &nxt6000_info); - - fe_count++; } -if (fe_count ==0 ) { -kfree (pnxt); +if (addr_nr ==sizeof (demod_addr_tbl)) { +kfree (nxt);return -ENODEV ; } -return 0 ; + nxt->demod_addr = demod_addr_tbl[addr_nr]; + +if (NULL == (client =kmalloc (sizeof (struct i2c_client ),GFP_KERNEL ))) { +kfree (nxt); +return -ENOMEM ; } -static void nxt6000_detach (struct dvb_i2c_bus *i2c,void *data) -{ -struct nxt6000_config *pnxt = (struct nxt6000_config *)data; -dprintk ("nxt6000: detach\n" ); -dvb_unregister_frontend (nxt6000_ioctl, i2c); -kfree (pnxt); +memcpy (client, &client_template,sizeof (struct i2c_client )); + client->adapter = adapter; + client->addr = demod_addr_tbl[addr_nr]; +i2c_set_clientdata (client, (void *) nxt); + + ret =i2c_attach_client (client); +if (ret) + goto out; + +BUG_ON (!nxt->dvb); + + ret =dvb_register_frontend (nxt6000_ioctl, nxt->dvb, nxt, &nxt6000_info,THIS_MODULE ); +if (ret) { +i2c_detach_client (client); + goto out; + } + + ret =0 ; +out: +kfree (client); +kfree (nxt); +return ret; +} + +static int detach_client (struct i2c_client *client) +{ +struct nxt6000_config *state = (struct nxt6000_config *)i2c_get_clientdata (client); +dvb_unregister_frontend_new (nxt6000_ioctl, state->dvb); +i2c_detach_client (client); +BUG_ON (state->dvb); +kfree (client); +kfree (state); +return 0 ; } -static __init int nxt6000_init (void ) +static int command (struct i2c_client *client,unsigned int cmd,void *arg) { +struct nxt6000_config *state = (struct nxt6000_config *)i2c_get_clientdata (client); -dprintk ("nxt6000: init\n" ); +switch (cmd) { +case FE_REGISTER :{ + state->dvb = (struct dvb_adapter *) arg; +break ; + } +case FE_UNREGISTER :{ + state->dvb =NULL ; +break ; + } +default : +return -EOPNOTSUPP ; + } +return 0 ; +} -return dvb_register_i2c_device (THIS_MODULE , nxt6000_attach, nxt6000_detach); +static struct i2c_driver driver = { + .owner =THIS_MODULE , + .name ="nxt6000" , + .id =I2C_DRIVERID_DVBFE_NXT6000 , + .flags =I2C_DF_NOTIFY , + .attach_adapter = attach_adapter, + .detach_client = detach_client, + .command = command, +}; +static struct i2c_client client_template = { +I2C_DEVNAME ("nxt6000" ), + .flags =I2C_CLIENT_ALLOW_USE , + .driver = &driver, +}; + +static __init int nxt6000_init (void ) +{ +return i2c_add_driver (&driver); } static __exit void nxt6000_exit(void) { - -dprintk ("nxt6000: cleanup\n" ); - -dvb_unregister_i2c_device (nxt6000_attach); - +if (i2c_del_driver (&driver)) +printk ("nxt6000: driver deregistration failed\n" ); }module_init (nxt6000_init);
drivers/media/dvb/frontends/sp887x.c +163 -147
508 lines not on this page · raw message
Re: [PATCH][2.6][9/14] add new frontend drivers 1/2
- [DVB] add new driver for Zarlink DVB-T MT352 frontend
- [DVB] add new driver for Conexant 22702 DVB OFDM frontend
drivers/media/dvb/frontends/Makefile +2 -0
@@ -18,3 +18,5 @@ obj-$(CONFIG_DVB_TDA1004X) += tda1004x.o obj-$(CONFIG_DVB_SP887X) += sp887x.o obj-$(CONFIG_DVB_NXT6000) += nxt6000.o +obj-$(CONFIG_DVB_MT352) += mt352.o +
drivers/media/dvb/frontends/mt352.c +901 -0
901 lines not on this page · raw message
drivers/media/dvb/frontends/mt352.h +177 -0
177 lines not on this page · raw message
drivers/media/dvb/frontends/cx22702.c +900 -0
900 lines not on this page · raw message
Re: [PATCH][2.6][10/14] add new frontend drivers 2/2
- [DVB] add new driver for mobile DVB-T demodulator DiBcom 3000-MB
- [DVB] add new drivers to Makefile
drivers/media/dvb/frontends/dib3000mb.c +857 -0
@@ -0,0 +1,857 @@ +/* +* Frontend driver for mobile DVB-T demodulator DiBcom 3000-MB +* DiBcom (http://www.dibcom.fr/) +* +* Copyright (C) 2004 Patrick Boettcher ([email protected]) +* +* based on GPL code from DibCom, which has +* +* Copyright (C) 2004 Amaury Demol for DiBcom ([email protected]) +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License as +* published by the Free Software Foundation, version 2. +* +* Acknowledgements +* +* Amaury Demol ([email protected]) from DiBcom for providing specs and driver +* sources, on which this driver (and the dvb-dibusb) are based. +* +* see Documentation/dvb/README.dibusb for more information +* +*/ + +#include <linux/config.h> +#include <linux/kernel.h> +#include <linux/version.h> +#include <linux/module.h> +#include <linux/moduleparam.h> +#include <linux/init.h> +#include <linux/delay.h> + +#include "dvb_frontend.h" + +#include "dib3000mb.h" + +/* debug */ + +#ifdef CONFIG_DVB_DIBCOM_DEBUG +#define dprintk_new(level,args...) \ + do { if ((debug & level)) { printk(args); } } while (0) + +static int debug; +module_param (debug, int,0x644 ); +MODULE_PARM_DESC (debug,"set debugging level (1=info,2=xfer,4=alotmore (|-able))." ); +#else +#define dprintk_new(args...) +#endif + +#define deb_info(args...) dprintk_new(0x01,args) +#define deb_xfer(args...) dprintk_new(0x02,args) +#define deb_alot(args...) dprintk_new(0x04,args) + +/* Version information */ +#define DRIVER_VERSION "0.1" +#define DRIVER_DESC "DiBcom 3000-MB DVB-T frontend" +#define DRIVER_AUTHOR "Patrick Boettcher, [email protected]" + +struct dib3000mb_state { +struct i2c_client *i2c; +struct dvb_adapter *dvb; +u16 manufactor_id; +u16 device_id; +}; + +static struct dvb_frontend_info dib3000mb_info = { + .name ="DiBcom 3000-MB DVB-T frontend" , + .type =FE_OFDM , + .frequency_min =44250000 , + .frequency_max =867250000 , + .frequency_stepsize =62500 , + .caps =FE_CAN_INVERSION_AUTO | +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 , +}; + + +#define rd (reg) dib3000mb_read_reg(state->i2c,reg) +#define wr (reg,val) if (dib3000mb_write_reg(state->i2c,reg,val)) \ + { err("while sending 0x%04x to 0x%04x.",val,reg); return -EREMOTEIO; } +#define wr_foreach (a,v) { int i; \ + deb_alot("sizeof: %d %d\n",sizeof(a),sizeof(v));\ + for (i=0; i < sizeof(a)/sizeof(u16); i++) \ + wr(a[i],v[i]); \ +} + +static u16 dib3000mb_read_reg (struct i2c_client *i2c,u16 reg) +{ +u8 wb[] = { ((reg >>8 ) |0x80 ) &0xff , reg &0xff }; +u8 rb[2 ]; +struct i2c_msg msg[] = { + { .addr = i2c->addr, .flags =0 , .buf = wb, .len =2 }, + { .addr = i2c->addr, .flags =I2C_M_RD , .buf = rb, .len =2 }, + }; +deb_alot ("reading from i2c bus (reg: %d)\n" ,reg); + +if (i2c_transfer (i2c->adapter,msg,2 ) !=2 ) +deb_alot ("i2c read error\n" ); + +return (rb[0 ] <<8 ) | rb[1 ]; +} + +static int dib3000mb_write_reg (struct i2c_client *i2c,u16 reg,u16 val) +{ +u8 b[] = { + (reg >>8 ) &0xff , reg &0xff , + (val >>8 ) &0xff , val &0xff , + }; +struct i2c_msg msg[] = { { .addr = i2c->addr, .flags =0 , .buf = b, .len =4 } }; +deb_alot ("writing to i2c bus (reg: %d, val: %d)\n" ,reg,val); + +return i2c_transfer (i2c->adapter,msg,1 ) !=1 ? -EREMOTEIO :0 ; +} + +static int dib3000mb_tuner_thomson_cable_eu (struct dib3000mb_state *state, +u32 freq) +{ +u32 tfreq = (freq +36125000 ) /62500 ; +unsigned int addr; +int vu,p0,p1,p2; + +if (freq >403250000 ) + vu =1 , p2 =1 , p1 =0 , p0 =1 ; +else if (freq >115750000 ) + vu =0 , p2 =1 , p1 =1 , p0 =0 ; +else if (freq >44250000 ) + vu =0 , p2 =0 , p1 =1 , p0 =1 ; +else +return -EINVAL ; +/* TODO better solution for i2c->addr handling */ + addr = state->i2c->addr; + state->i2c->addr =DIB3000MB_TUNER_ADDR_DEFAULT ; +wr (tfreq &0x7fff ,(0x8e <<8 ) + ((vu <<7 ) | (p2 <<2 ) | (p1 <<1 ) | p0) ); + state->i2c->addr = addr; + +return 0 ; +} + +static int dib3000mb_get_frontend (struct dib3000mb_state *state, +struct dvb_frontend_parameters *fep) +{ +struct dvb_ofdm_parameters *ofdm = &fep->u.ofdm; +fe_code_rate_t *cr; +u16 tps_val; +int inv_test1,inv_test2; +u32 dds_val, threshold =0x800000 ; + +if (!rd (DIB3000MB_REG_TPS_LOCK )) +return -EINVAL ; + + dds_val = ((rd (DIB3000MB_REG_DDS_VALUE_MSB ) &0xff ) <<16 ) +rd (DIB3000MB_REG_DDS_VALUE_LSB ); +if (dds_val & threshold) + inv_test1 =0 ; +else if (dds_val == threshold) + inv_test1 =1 ; +else + inv_test1 =2 ; + + dds_val = ((rd (DIB3000MB_REG_DDS_FREQ_MSB ) &0xff ) <<16 ) +rd (DIB3000MB_REG_DDS_FREQ_LSB ); +if (dds_val & threshold) + inv_test2 =0 ; +else if (dds_val == threshold) + inv_test2 =1 ; +else + inv_test2 =2 ; + + fep->inversion = + ((inv_test2 ==2 ) && (inv_test1==1 || inv_test1==0 )) + || + ((inv_test2 ==0 ) && (inv_test1==1 || inv_test1==2 )); + +deb_info ("inversion %d %d, %d\n" ,inv_test2,inv_test1, fep->inversion); + +switch ((tps_val =rd (DIB3000MB_REG_TPS_QAM ))) { +case DIB3000MB_QAM_QPSK : +deb_info ("QPSK " ); + ofdm->constellation =QPSK ; +break ; +case DIB3000MB_QAM_QAM16 : +deb_info ("QAM16 " ); + ofdm->constellation =QAM_16 ; +break ; +case DIB3000MB_QAM_QAM64 : +deb_info ("QAM64 " ); + ofdm->constellation =QAM_64 ; +break ; +default : +err ("Unexpected constellation returned by TPS (%d)" ,tps_val); +break ; + } +deb_info ("TPS: %d\n" ,tps_val); + +if (rd (DIB3000MB_REG_TPS_HRCH )) { +deb_info ("HRCH ON\n" ); + tps_val =rd (DIB3000MB_REG_TPS_CODE_RATE_LP ); + cr = &ofdm->code_rate_LP; + ofdm->code_rate_HP =FEC_NONE ; + +switch ((tps_val =rd (DIB3000MB_REG_TPS_VIT_ALPHA ))) { +case DIB3000MB_VIT_ALPHA_OFF : +deb_info ("HIERARCHY_NONE " ); + ofdm->hierarchy_information =HIERARCHY_NONE ; +break ; +case DIB3000MB_VIT_ALPHA_1 : +deb_info ("HIERARCHY_1 " ); + ofdm->hierarchy_information =HIERARCHY_1 ; +break ; +case DIB3000MB_VIT_ALPHA_2 : +deb_info ("HIERARCHY_2 " ); + ofdm->hierarchy_information =HIERARCHY_2 ; +break ; +case DIB3000MB_VIT_ALPHA_4 : +deb_info ("HIERARCHY_4 " ); + ofdm->hierarchy_information =HIERARCHY_4 ; +break ; +default : +err ("Unexpected ALPHA value returned by TPS (%d)" ,tps_val); + } +deb_info ("TPS: %d\n" ,tps_val); + }else { +deb_info ("HRCH OFF\n" ); + tps_val =rd (DIB3000MB_REG_TPS_CODE_RATE_HP ); + cr = &ofdm->code_rate_HP; + ofdm->code_rate_LP =FEC_NONE ; + ofdm->hierarchy_information =HIERARCHY_NONE ; + } + +switch (tps_val) { +case DIB3000MB_FEC_1_2 : +deb_info ("FEC_1_2 " ); + *cr =FEC_1_2 ; +break ; +case DIB3000MB_FEC_2_3 : +deb_info ("FEC_2_3 " ); + *cr =FEC_2_3 ; +break ; +case DIB3000MB_FEC_3_4 : +deb_info ("FEC_3_4 " ); + *cr =FEC_3_4 ; +break ; +case DIB3000MB_FEC_5_6 : +deb_info ("FEC_5_6 " ); + *cr =FEC_4_5 ; +break ; +case DIB3000MB_FEC_7_8 : +deb_info ("FEC_7_8 " ); + *cr =FEC_7_8 ; +break ; +default : +err ("Unexpected FEC returned by TPS (%d)" ,tps_val); +break ; + } +deb_info ("TPS: %d\n" ,tps_val); + +switch ((tps_val =rd (DIB3000MB_REG_TPS_GUARD_TIME ))) { +case DIB3000MB_GUARD_TIME_1_32 : +deb_info ("GUARD_INTERVAL_1_32 " ); + ofdm->guard_interval =GUARD_INTERVAL_1_32 ; +break ; +case DIB3000MB_GUARD_TIME_1_16 : +deb_info ("GUARD_INTERVAL_1_16 " ); + ofdm->guard_interval =GUARD_INTERVAL_1_16 ; +break ; +case DIB3000MB_GUARD_TIME_1_8 : +deb_info ("GUARD_INTERVAL_1_8 " ); + ofdm->guard_interval =GUARD_INTERVAL_1_8 ; +break ; +case DIB3000MB_GUARD_TIME_1_4 : +deb_info ("GUARD_INTERVAL_1_4 " ); + ofdm->guard_interval =GUARD_INTERVAL_1_4 ; +break ; +default : +err ("Unexpected Guard Time returned by TPS (%d)" ,tps_val); +break ; + } +deb_info ("TPS: %d\n" ,tps_val); + +switch ((tps_val =rd (DIB3000MB_REG_TPS_FFT ))) { +case DIB3000MB_FFT_2K : +deb_info ("TRANSMISSION_MODE_2K " ); + ofdm->transmission_mode =TRANSMISSION_MODE_2K ; +break ; +case DIB3000MB_FFT_8K : +deb_info ("TRANSMISSION_MODE_8K " ); + ofdm->transmission_mode =TRANSMISSION_MODE_8K ; +break ; +default : +err ("unexpected transmission mode return by TPS (%d)" ,tps_val); + } +deb_info ("TPS: %d\n" ,tps_val); +return 0 ; +} + +static int dib3000mb_set_frontend (struct dib3000mb_state *state, +struct dvb_frontend_parameters *fep,int tuner); + +static int dib3000mb_fe_read_search_status (struct dib3000mb_state *state) +{ +u16 irq; +struct dvb_frontend_parameters fep; + + irq =rd (DIB3000MB_REG_AS_IRQ_PENDING ); + +if (irq &0x02 ) { +if (rd (DIB3000MB_REG_LOCK2_VALUE ) &0x01 ) { +if (dib3000mb_get_frontend (state,&fep) ==0 ) { +deb_info ("reading tuning data from frontend succeeded.\n" ); +return dib3000mb_set_frontend (state,&fep,0 ) ==0 ; + }else { +deb_info ("reading tuning data failed -> tuning failed.\n" ); +return 0 ; + } + }else { +deb_info ("AS IRQ was pending, but LOCK2 was not & 0x01.\n" ); +return 0 ; + } + }else if (irq &0x01 ) { +deb_info ("Autosearch failed.\n" ); +return 0 ; + } + +return -1 ; +} + +static int dib3000mb_set_frontend (struct dib3000mb_state *state, +struct dvb_frontend_parameters *fep,int tuner) +{ +struct dvb_ofdm_parameters *ofdm = &fep->u.ofdm; +fe_code_rate_t fe_cr; +int search_state,seq; + +if (tuner) { +wr (DIB3000MB_REG_TUNER , +DIB3000MB_ACTIVATE_TUNER_XFER (DIB3000MB_TUNER_ADDR_DEFAULT ) ); +dib3000mb_tuner_thomson_cable_eu (state,fep->frequency); + +/* wait for tuner */ +msleep (1 ); +wr (DIB3000MB_REG_TUNER , +DIB3000MB_DEACTIVATE_TUNER_XFER (DIB3000MB_TUNER_ADDR_DEFAULT ) ); + +switch (ofdm->bandwidth) { +case BANDWIDTH_8_MHZ : +case BANDWIDTH_AUTO : +wr_foreach (dib3000mb_reg_timing_freq,dib3000mb_timing_freq[2 ]); +wr_foreach (dib3000mb_reg_bandwidth,dib3000mb_bandwidth_8mhz); +break ; +case BANDWIDTH_7_MHZ : +wr_foreach (dib3000mb_reg_timing_freq,dib3000mb_timing_freq[1 ]); +wr_foreach (dib3000mb_reg_bandwidth,dib3000mb_bandwidth_7mhz); +break ; +case BANDWIDTH_6_MHZ : +wr_foreach (dib3000mb_reg_timing_freq,dib3000mb_timing_freq[0 ]); +wr_foreach (dib3000mb_reg_bandwidth,dib3000mb_bandwidth_6mhz); +break ; +default : +err ("unkown bandwidth value." ); +return -EINVAL ; +break ; + } + } +wr (DIB3000MB_REG_LOCK1_MASK ,DIB3000MB_LOCK1_SEARCH_4 ); + +switch (ofdm->transmission_mode) { +case TRANSMISSION_MODE_2K : +wr (DIB3000MB_REG_FFT ,DIB3000MB_FFT_2K ); +break ; +case TRANSMISSION_MODE_8K : +wr (DIB3000MB_REG_FFT ,DIB3000MB_FFT_8K ); +break ; +case TRANSMISSION_MODE_AUTO : +wr (DIB3000MB_REG_FFT ,DIB3000MB_FFT_AUTO ); +break ; +default : +return -EINVAL ; + } + +switch (ofdm->guard_interval) { +case GUARD_INTERVAL_1_32 : +wr (DIB3000MB_REG_GUARD_TIME ,DIB3000MB_GUARD_TIME_1_32 ); +break ; +case GUARD_INTERVAL_1_16 : +wr (DIB3000MB_REG_GUARD_TIME ,DIB3000MB_GUARD_TIME_1_16 ); +break ; +case GUARD_INTERVAL_1_8 : +wr (DIB3000MB_REG_GUARD_TIME ,DIB3000MB_GUARD_TIME_1_8 ); +break ; +case GUARD_INTERVAL_1_4 : +wr (DIB3000MB_REG_GUARD_TIME ,DIB3000MB_GUARD_TIME_1_4 ); +break ; +case GUARD_INTERVAL_AUTO : +wr (DIB3000MB_REG_GUARD_TIME ,DIB3000MB_GUARD_TIME_AUTO ); +break ; +default : +return -EINVAL ; + } + +switch (fep->inversion) { +case INVERSION_OFF : +wr (DIB3000MB_REG_DDS_INV ,DIB3000MB_DDS_INV_OFF ); +break ; +case INVERSION_AUTO : +case INVERSION_ON : +wr (DIB3000MB_REG_DDS_INV ,DIB3000MB_DDS_INV_ON ); +break ; +default : +return -EINVAL ; + } + +switch (ofdm->constellation) { +case QPSK : +wr (DIB3000MB_REG_QAM ,DIB3000MB_QAM_QPSK ); +break ; +case QAM_16 : +wr (DIB3000MB_REG_QAM ,DIB3000MB_QAM_QAM16 ); +break ; +case QAM_64 : +wr (DIB3000MB_REG_QAM ,DIB3000MB_QAM_QAM64 ); +break ; +case QAM_AUTO : +break ; +default : +return -EINVAL ; + } + +switch (ofdm->hierarchy_information) { +case HIERARCHY_NONE : +case HIERARCHY_1 : +wr (DIB3000MB_REG_VIT_ALPHA ,DIB3000MB_VIT_ALPHA_1 ); +break ; +case HIERARCHY_2 : +wr (DIB3000MB_REG_VIT_ALPHA ,DIB3000MB_VIT_ALPHA_2 ); +break ; +case HIERARCHY_4 : +wr (DIB3000MB_REG_VIT_ALPHA ,DIB3000MB_VIT_ALPHA_4 ); +break ; +case HIERARCHY_AUTO : +wr (DIB3000MB_REG_VIT_ALPHA ,DIB3000MB_VIT_ALPHA_AUTO ); +break ; +default : +return -EINVAL ; + } + +if (ofdm->hierarchy_information ==HIERARCHY_NONE ) { +wr (DIB3000MB_REG_VIT_HRCH ,DIB3000MB_VIT_HRCH_OFF ); +wr (DIB3000MB_REG_VIT_HP ,DIB3000MB_VIT_HP ); + fe_cr = ofdm->code_rate_HP; + }else { +wr (DIB3000MB_REG_VIT_HRCH ,DIB3000MB_VIT_HRCH_ON ); +wr (DIB3000MB_REG_VIT_HP ,DIB3000MB_VIT_LP ); + fe_cr = ofdm->code_rate_LP; + } + +switch (fe_cr) { +case FEC_1_2 : +wr (DIB3000MB_REG_VIT_CODE_RATE ,DIB3000MB_FEC_1_2 ); +break ; +case FEC_2_3 : +wr (DIB3000MB_REG_VIT_CODE_RATE ,DIB3000MB_FEC_2_3 ); +break ; +case FEC_3_4 : +wr (DIB3000MB_REG_VIT_CODE_RATE ,DIB3000MB_FEC_3_4 ); +break ; +case FEC_5_6 : +wr (DIB3000MB_REG_VIT_CODE_RATE ,DIB3000MB_FEC_5_6 ); +break ; +case FEC_7_8 : +wr (DIB3000MB_REG_VIT_CODE_RATE ,DIB3000MB_FEC_7_8 ); +break ; +case FEC_NONE : +case FEC_AUTO : +break ; +default : +return -EINVAL ; + } + + seq = dib3000mb_seq + [ofdm->transmission_mode ==TRANSMISSION_MODE_AUTO ] + [ofdm->guard_interval ==GUARD_INTERVAL_AUTO ] + [fep->inversion ==INVERSION_AUTO ]; + +deb_info ("seq? %d\n" ,seq); + +wr (DIB3000MB_REG_SEQ ,seq); + +wr (DIB3000MB_REG_ISI ,seq ?DIB3000MB_ISI_INHIBIT :DIB3000MB_ISI_ACTIVATE ); + +if (ofdm->transmission_mode ==TRANSMISSION_MODE_2K ) { +if (ofdm->guard_interval ==GUARD_INTERVAL_1_8 ) { +wr (DIB3000MB_REG_SYNC_IMPROVEMENT ,DIB3000MB_SYNC_IMPROVE_2K_1_8 ); + }else { +wr (DIB3000MB_REG_SYNC_IMPROVEMENT ,DIB3000MB_SYNC_IMPROVE_DEFAULT ); + } + +wr (DIB3000MB_REG_UNK_121 ,DIB3000MB_UNK_121_2K ); + }else { +wr (DIB3000MB_REG_UNK_121 ,DIB3000MB_UNK_121_DEFAULT ); + } + +wr (DIB3000MB_REG_MOBILE_ALGO ,DIB3000MB_MOBILE_ALGO_OFF ); +wr (DIB3000MB_REG_MOBILE_MODE_QAM ,DIB3000MB_MOBILE_MODE_QAM_OFF ); +wr (DIB3000MB_REG_MOBILE_MODE ,DIB3000MB_MOBILE_MODE_OFF ); + +wr_foreach (dib3000mb_reg_agc_bandwidth,dib3000mb_agc_bandwidth_high); + +wr (DIB3000MB_REG_ISI ,DIB3000MB_ISI_ACTIVATE ); + +wr (DIB3000MB_REG_RESTART ,DIB3000MB_RESTART_AGC +DIB3000MB_RESTART_CTRL ); +wr (DIB3000MB_REG_RESTART ,DIB3000MB_RESTART_OFF ); + +/* wait for AGC lock */ +msleep (70 ); + +wr_foreach (dib3000mb_reg_agc_bandwidth,dib3000mb_agc_bandwidth_low); + +/* something has to be auto searched */ +if (ofdm->constellation ==QAM_AUTO || + ofdm->hierarchy_information ==HIERARCHY_AUTO || + fe_cr ==FEC_AUTO || + fep->inversion ==INVERSION_AUTO ) { + +deb_info ("autosearch enabled.\n" ); + +wr (DIB3000MB_REG_ISI ,DIB3000MB_ISI_INHIBIT ); + +wr (DIB3000MB_REG_RESTART ,DIB3000MB_RESTART_AUTO_SEARCH ); +wr (DIB3000MB_REG_RESTART ,DIB3000MB_RESTART_OFF ); + +while ((search_state =dib3000mb_fe_read_search_status (state)) <0 ); + +return search_state ?0 : -EINVAL ; + }else { +wr (DIB3000MB_REG_RESTART ,DIB3000MB_RESTART_CTRL ); +wr (DIB3000MB_REG_RESTART ,DIB3000MB_RESTART_OFF ); +msleep (70 ); + } +return 0 ; +} + + +static int dib3000mb_fe_init (struct dib3000mb_state *state,int mobile_mode) +{ +wr (DIB3000MB_REG_POWER_CONTROL ,DIB3000MB_POWER_UP ); + +wr (DIB3000MB_REG_RESTART ,DIB3000MB_RESTART_AGC ); + +wr (DIB3000MB_REG_RESET_DEVICE ,DIB3000MB_RESET_DEVICE ); +wr (DIB3000MB_REG_RESET_DEVICE ,DIB3000MB_RESET_DEVICE_RST ); + +wr (DIB3000MB_REG_CLOCK ,DIB3000MB_CLOCK_DEFAULT ); + +wr (DIB3000MB_REG_ELECT_OUT_MODE ,DIB3000MB_ELECT_OUT_MODE_ON ); + +wr (DIB3000MB_REG_QAM ,DIB3000MB_QAM_RESERVED ); +wr (DIB3000MB_REG_VIT_ALPHA ,DIB3000MB_VIT_ALPHA_AUTO ); + +wr (DIB3000MB_REG_DDS_FREQ_MSB ,DIB3000MB_DDS_FREQ_MSB ); +wr (DIB3000MB_REG_DDS_FREQ_LSB ,DIB3000MB_DDS_FREQ_LSB ); + +wr_foreach (dib3000mb_reg_timing_freq,dib3000mb_timing_freq[2 ]); + +wr_foreach (dib3000mb_reg_impulse_noise, + dib3000mb_impulse_noise_values[DIB3000MB_IMPNOISE_OFF ]); + +wr_foreach (dib3000mb_reg_agc_gain,dib3000mb_default_agc_gain); + +wr (DIB3000MB_REG_PHASE_NOISE ,DIB3000MB_PHASE_NOISE_DEFAULT ); + +wr_foreach (dib3000mb_reg_phase_noise, dib3000mb_default_noise_phase); + +wr_foreach (dib3000mb_reg_lock_duration,dib3000mb_default_lock_duration); + +wr_foreach (dib3000mb_reg_agc_bandwidth,dib3000mb_agc_bandwidth_low); + +wr (DIB3000MB_REG_LOCK0_MASK ,DIB3000MB_LOCK0_DEFAULT ); +wr (DIB3000MB_REG_LOCK1_MASK ,DIB3000MB_LOCK1_SEARCH_4 ); +wr (DIB3000MB_REG_LOCK2_MASK ,DIB3000MB_LOCK2_DEFAULT ); +wr (DIB3000MB_REG_SEQ ,dib3000mb_seq[1 ][1 ][1 ]); + +wr_foreach (dib3000mb_reg_bandwidth,dib3000mb_bandwidth_8mhz); + +wr (DIB3000MB_REG_UNK_68 ,DIB3000MB_UNK_68 ); +wr (DIB3000MB_REG_UNK_69 ,DIB3000MB_UNK_69 ); +wr (DIB3000MB_REG_UNK_71 ,DIB3000MB_UNK_71 ); +wr (DIB3000MB_REG_UNK_77 ,DIB3000MB_UNK_77 ); +wr (DIB3000MB_REG_UNK_78 ,DIB3000MB_UNK_78 ); +wr (DIB3000MB_REG_ISI ,DIB3000MB_ISI_INHIBIT ); +wr (DIB3000MB_REG_UNK_92 ,DIB3000MB_UNK_92 ); +wr (DIB3000MB_REG_UNK_96 ,DIB3000MB_UNK_96 ); +wr (DIB3000MB_REG_UNK_97 ,DIB3000MB_UNK_97 ); +wr (DIB3000MB_REG_UNK_106 ,DIB3000MB_UNK_106 ); +wr (DIB3000MB_REG_UNK_107 ,DIB3000MB_UNK_107 ); +wr (DIB3000MB_REG_UNK_108 ,DIB3000MB_UNK_108 ); +wr (DIB3000MB_REG_UNK_122 ,DIB3000MB_UNK_122 ); +wr (DIB3000MB_REG_MOBILE_MODE_QAM ,DIB3000MB_MOBILE_MODE_QAM_OFF ); +wr (DIB3000MB_REG_VIT_CODE_RATE ,DIB3000MB_FEC_1_2 ); +wr (DIB3000MB_REG_VIT_HP ,DIB3000MB_VIT_HP ); +wr (DIB3000MB_REG_BERLEN ,DIB3000MB_BERLEN_DEFAULT ); + +wr_foreach (dib3000mb_reg_filter_coeffs,dib3000mb_filter_coeffs); + +wr (DIB3000MB_REG_MOBILE_ALGO ,DIB3000MB_MOBILE_ALGO_ON ); +wr (DIB3000MB_REG_MULTI_DEMOD_MSB ,DIB3000MB_MULTI_DEMOD_MSB ); +wr (DIB3000MB_REG_MULTI_DEMOD_LSB ,DIB3000MB_MULTI_DEMOD_LSB ); + +wr (DIB3000MB_REG_OUTPUT_MODE ,DIB3000MB_OUTPUT_MODE_SLAVE ); + +wr (DIB3000MB_REG_FIFO_142 ,DIB3000MB_FIFO_142 ); +wr (DIB3000MB_REG_MPEG2_OUT_MODE ,DIB3000MB_MPEG2_OUT_MODE_188 ); +wr (DIB3000MB_REG_FIFO_144 ,DIB3000MB_FIFO_144 ); +wr (DIB3000MB_REG_FIFO ,DIB3000MB_FIFO_INHIBIT ); +wr (DIB3000MB_REG_FIFO_146 ,DIB3000MB_FIFO_146 ); +wr (DIB3000MB_REG_FIFO_147 ,DIB3000MB_FIFO_147 ); + +wr (DIB3000MB_REG_DATA_IN_DIVERSITY ,DIB3000MB_DATA_DIVERSITY_IN_OFF ); +return 0 ; +} + +static int dib3000mb_read_status (struct dib3000mb_state *state,fe_status_t *stat) +{ + *stat =0 ; + *stat |=rd (DIB3000MB_REG_AGC_LOCK ) ?FE_HAS_SIGNAL :0 ; + *stat |=rd (DIB3000MB_REG_CARRIER_LOCK ) ?FE_HAS_CARRIER :0 ; + *stat |=rd (DIB3000MB_REG_VIT_LCK ) ?FE_HAS_VITERBI :0 ; + *stat |=rd (DIB3000MB_REG_TS_SYNC_LOCK ) ?FE_HAS_SYNC :0 ; + *stat |= *stat ?FE_HAS_LOCK :0 ; + +deb_info ("actual status is %2x\n" ,*stat); + +deb_info ("autoval: tps: %d, qam: %d, hrch: %d, alpha: %d, hp: %d, lp: %d, guard: %d, fft: %d cell: %d\n" , +rd (DIB3000MB_REG_TPS_LOCK ), +rd (DIB3000MB_REG_TPS_QAM ), +rd (DIB3000MB_REG_TPS_HRCH ), +rd (DIB3000MB_REG_TPS_VIT_ALPHA ), +rd (DIB3000MB_REG_TPS_CODE_RATE_HP ), +rd (DIB3000MB_REG_TPS_CODE_RATE_LP ), +rd (DIB3000MB_REG_TPS_GUARD_TIME ), +rd (DIB3000MB_REG_TPS_FFT ), +rd (DIB3000MB_REG_TPS_CELL_ID )); + +//*stat = FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK; +return 0 ; +} + +static int dib3000mb_read_ber (struct dib3000mb_state *state,u32 *ber) +{ + *ber = + (((rd (DIB3000MB_REG_BER_MSB ) <<16 ) &0x1f ) |rd (DIB3000MB_REG_BER_LSB ) ) / +100000000 ; +return 0 ; +} + +static int dib3000mb_signal_strength (struct dib3000mb_state *state,u16 *strength) +{ +// *stength = DIB3000MB_REG_SIGNAL_POWER +return 0 ; +} + +static int dib3000mb_sleep (struct dib3000mb_state *state) +{ +wr (DIB3000MB_REG_POWER_CONTROL ,DIB3000MB_POWER_DOWN ); +return 0 ; +} + +static int dib3000mb_ioctl (struct dvb_frontend *fe,unsigned int cmd,void *arg) +{ +struct dib3000mb_state *state = fe->data; +int ret =0 ; +switch (cmd) { +case FE_GET_INFO : +deb_info ("FE_GET_INFO\n" ); +memcpy (arg, &dib3000mb_info,sizeof (struct dvb_frontend_info )); +break ; + +case FE_READ_STATUS : +deb_info ("FE_READ_STATUS\n" ); + ret =dib3000mb_read_status (state,(fe_status_t *)arg); +break ; + +case FE_READ_BER : +deb_info ("FE_READ_BER\n" ); + ret =dib3000mb_read_ber (state,(u32 *)arg); +break ; + +case FE_READ_SIGNAL_STRENGTH : +deb_info ("FE_READ_SIG_STRENGTH\n" ); + ret =dib3000mb_signal_strength (state,(u16 *) arg); +break ; + +case FE_READ_SNR : +deb_info ("FE_READ_SNR\n" ); +break ; + +case FE_READ_UNCORRECTED_BLOCKS : +deb_info ("FE_READ_UNCORRECTED_BLOCKS\n" ); +break ; + +case FE_SET_FRONTEND : +deb_info ("FE_SET_FRONTEND\n" ); + ret =dib3000mb_set_frontend (state,(struct dvb_frontend_parameters *) arg,1 ); +break ; + +case FE_GET_FRONTEND : +deb_info ("FE_GET_FRONTEND\n" ); + ret =dib3000mb_get_frontend (state,(struct dvb_frontend_parameters *) arg); +break ; + +case FE_SLEEP : +deb_info ("FE_SLEEP\n" ); + ret =dib3000mb_sleep (state); +break ; + +case FE_INIT : +deb_info ("FE_INIT\n" ); + ret =dib3000mb_fe_init (state,0 ); +break ; + +case FE_SET_TONE : +case FE_SET_VOLTAGE : +default : + ret = -EOPNOTSUPP ; +break ; + } +return 0 ; +} + +static struct i2c_client client_template; + +static int dib3000mb_attach_adapter (struct i2c_adapter *adapter) +{ +struct i2c_client *client; +struct dib3000mb_state *state; +int ret = -ENOMEM ; + +deb_info ("i2c probe with adapter '%s'.\n" ,adapter->name); + +if ((state =kmalloc (sizeof (struct dib3000mb_state ),GFP_KERNEL )) ==NULL ) +return -ENOMEM ; + + +if ((client =kmalloc (sizeof (struct i2c_client ),GFP_KERNEL )) ==NULL ) + goto i2c_kmalloc_err; + +memcpy (client, &client_template,sizeof (struct i2c_client )); + + client->adapter = adapter; + client->addr =0x10 ; + state->i2c = client; + +i2c_set_clientdata (client,state); + + state->manufactor_id =dib3000mb_read_reg (client,DIB3000MB_REG_MANUFACTOR_ID ); + state->device_id =dib3000mb_read_reg (client,DIB3000MB_REG_DEVICE_ID ); +if (state->manufactor_id ==0x01b3 && state->device_id ==0x3000 ) +info ("found a DiBCom (0x%04x) 3000-MB DVB-T frontend (ver: %x)." , + state->manufactor_id, state->device_id); +else { +err ("did not found a DiBCom 3000-MB." ); + ret = -ENODEV ; + goto probe_err; + } + +if ((ret =i2c_attach_client (client))) + goto i2c_attach_err; + +if (state->dvb ==NULL ) + goto i2c_attach_err; + +if ((ret =dvb_register_frontend (dib3000mb_ioctl, state->dvb, state, + &dib3000mb_info,THIS_MODULE ))) + goto dvb_fe_err; + + + goto success; +dvb_fe_err: +i2c_detach_client (client); +i2c_attach_err: +probe_err: +kfree (client); +i2c_kmalloc_err: +kfree (state); +return ret; +success: +return 0 ; +} + + +static int dib3000mb_detach_client (struct i2c_client *client) +{ +struct dib3000mb_state *state =i2c_get_clientdata (client); + +deb_info ("i2c detach\n" ); + +dvb_unregister_frontend (dib3000mb_ioctl, state->dvb); +i2c_detach_client (client); +kfree (client); +kfree (state); + +return 0 ; +} + +static int dib3000mb_command (struct i2c_client *client, +unsigned int cmd,void *arg) +{ +struct dib3000mb_state *state =i2c_get_clientdata (client); +deb_info ("i2c command.\n" ); +switch (cmd) { +case FE_REGISTER : + state->dvb = arg; +break ; +case FE_UNREGISTER : + state->dvb =NULL ; +break ; +default : +return -EOPNOTSUPP ; + } + +return 0 ; +} + +static struct i2c_driver driver = { + .owner =THIS_MODULE , + .name ="dib3000mb" , + .id =I2C_DRIVERID_DVBFE_DIB3000MB , + .flags =I2C_DF_NOTIFY , + .attach_adapter = dib3000mb_attach_adapter, + .detach_client = dib3000mb_detach_client, + .command = dib3000mb_command, +}; + +static struct i2c_client client_template = { + .name ="dib3000mb" , + .flags =I2C_CLIENT_ALLOW_USE , + .driver = &driver, +}; + +/* module stuff */ +static int __init dib3000mb_init (void ) +{ +deb_info ("debugging level: %d\n" ,debug); +return i2c_add_driver (&driver); +} + +static void __exit dib3000mb_exit(void) +{ +i2c_del_driver (&driver); +} + +module_init (dib3000mb_init); +module_exit (dib3000mb_exit); + +MODULE_AUTHOR (DRIVER_AUTHOR ); +MODULE_DESCRIPTION (DRIVER_DESC ); +MODULE_LICENSE ("GPL" );
drivers/media/dvb/frontends/dib3000mb.h +657 -0
657 lines not on this page · raw message
drivers/media/dvb/frontends/Makefile +2 -0
@@ -12,6 +12,7 @@ obj-$(CONFIG_DVB_CX24110) += cx24110.o obj-$(CONFIG_DVB_GRUNDIG_29504_491) += grundig_29504-491.o obj-$(CONFIG_DVB_GRUNDIG_29504_401) += grundig_29504-401.o +obj-$(CONFIG_DVB_DIB3000MB) += dib3000mb.o obj-$(CONFIG_DVB_MT312) += mt312.o obj-$(CONFIG_DVB_VES1820) += ves1820.o obj-$(CONFIG_DVB_VES1X93) += ves1x93.o
@@ -19,4 +20,5 @@ obj-$(CONFIG_DVB_SP887X) += sp887x.o obj-$(CONFIG_DVB_NXT6000) += nxt6000.o obj-$(CONFIG_DVB_MT352) += mt352.o +obj-$(CONFIG_DVB_CX22702) += cx22702.o
Re: [PATCH][2.6][11/14] new DVB driver
- [DVB] new driver for mobile USB Budget DVB-T devices, thanks to Patrick Boettcher
drivers/media/dvb/dibusb/dvb-dibusb.c +719 -0
@@ -0,0 +1,719 @@ +/* +* Driver for mobile USB Budget DVB-T devices based on reference +* design made by DiBcom (http://www.dibcom.fr/) +* +* dvb-dibusb.c +* +* Copyright (C) 2004 Patrick Boettcher ([email protected]) +* +* based on GPL code from DiBcom, which has +* +* Copyright (C) 2004 Amaury Demol for DiBcom ([email protected]) +* +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License as +* published by the Free Software Foundation, version 2. +* +* Acknowledgements +* +* Amaury Demol ([email protected]) from DiBcom for providing specs and driver +* sources, on which this driver (and the dib3000mb frontend) are based. +* +* TODO +* - probing for i2c addresses, it is possible, that they have been changed +* by the vendor +* +* see Documentation/dvb/README.dibusb for more information +*/ + +#include <linux/config.h> +#include <linux/kernel.h> +#include <linux/usb.h> +#include <linux/firmware.h> +#include <linux/version.h> +#include <linux/moduleparam.h> +#include <linux/pci.h> + +#include "dmxdev.h" +#include "dvb_demux.h" +#include "dvb_filter.h" +#include "dvb_net.h" +#include "dvb_frontend.h" + +#include "dvb-dibusb.h" + +/* debug */ + +#ifdef CONFIG_DVB_DIBCOM_DEBUG +#define dprintk_new(level,args...) \ + do { if ((debug & level)) { printk(args); } } while (0) + +#define debug_dump (b,l) if (debug) {\ + int i; deb_xfer("%s: %d > ",__FUNCTION__,l); \ + for (i = 0; i < l; i++) deb_xfer("%02x ", b[i]); \ + deb_xfer("\n");\ +} + +static int debug; +module_param (debug, int,0x644 ); +MODULE_PARM_DESC (debug,"set debugging level (1=info,2=xfer,4=alotmore (|-able))." ); +#else +#define dprintk_new(args...) +#define debug_dump (b,l) +#endif + +#define deb_info(args...) dprintk_new(0x01,args) +#define deb_xfer(args...) dprintk_new(0x02,args) +#define deb_alot(args...) dprintk_new(0x04,args) + +/* Version information */ +#define DRIVER_VERSION "0.0" +#define DRIVER_DESC "DiBcom based USB Budget DVB-T device" +#define DRIVER_AUTHOR "Patrick Boettcher, [email protected]" + +/* USB Driver stuff */ + +/* table of devices that work with this driver */ +static struct usb_device_id dibusb_table [] = { + {USB_DEVICE (USB_TWINHAN_VENDOR_ID ,USB_VP7041_PRODUCT_PREFW_ID ) }, + {USB_DEVICE (USB_TWINHAN_VENDOR_ID ,USB_VP7041_PRODUCT_ID ) }, + {USB_DEVICE (USB_IMC_NETWORKS_VENDOR_ID ,USB_VP7041_PRODUCT_PREFW_ID ) }, + {USB_DEVICE (USB_IMC_NETWORKS_VENDOR_ID ,USB_VP7041_PRODUCT_ID ) }, + {USB_DEVICE (USB_KWORLD_VENDOR_ID ,USB_VSTREAM_PRODUCT_PREFW_ID ) }, + {USB_DEVICE (USB_KWORLD_VENDOR_ID ,USB_VSTREAM_PRODUCT_ID ) }, + {USB_DEVICE (USB_DIBCOM_VENDOR_ID ,USB_DIBCOM_PRODUCT_PREFW_ID ) }, + {USB_DEVICE (USB_DIBCOM_VENDOR_ID ,USB_DIBCOM_PRODUCT_ID ) }, + {USB_DEVICE (USB_ULTIMA_ELECTRONIC_ID ,USB_ULTIMA_ELEC_PROD_PREFW_ID ) }, + {USB_DEVICE (USB_ULTIMA_ELECTRONIC_ID ,USB_ULTIMA_ELEC_PROD_ID ) }, + { }/* Terminating entry */ +}; + +MODULE_DEVICE_TABLE (usb, dibusb_table); + +static int dibusb_readwrite_usb (struct usb_dibusb *dib, +u8 *wbuf,u16 wlen,u8 *rbuf,u16 rlen) +{ +int actlen,ret = -ENOMEM ; + +if (wbuf ==NULL || wlen ==0 ) +return -EINVAL ; + +/* if (dib->disconnecting) +return -EINVAL;*/ + +if ((ret =down_interruptible (&dib->usb_sem))) +return ret; + +debug_dump (wbuf,wlen); + + ret =usb_bulk_msg (dib->udev,COMMAND_PIPE , + wbuf,wlen,&actlen,DIBUSB_I2C_TIMEOUT ); + +if (ret) +err ("bulk message failed: %d (%d/%d)" ,ret,wlen,actlen); +else + ret = actlen != wlen ?-1 :0 ; + +/* an answer is expected */ +if (!ret && rbuf && rlen) { + ret =usb_bulk_msg (dib->udev,RESULT_PIPE ,rbuf,rlen, + &actlen,DIBUSB_I2C_TIMEOUT ); + +if (ret) +err ("recv bulk message failed: %d" ,ret); +else { +deb_alot ("rlen: %d\n" ,rlen); +debug_dump (rbuf,actlen); + } + } + +up (&dib->usb_sem); +return ret; +} + +static int dibusb_write_usb (struct usb_dibusb *dib,u8 *buf,u16 len) +{ +return dibusb_readwrite_usb (dib,buf,len,NULL ,0 ); +} + +static int dibusb_i2c_msg (struct usb_dibusb *dib,u8 addr, +u8 *wbuf,u16 wlen,u8 *rbuf,u16 rlen) +{ +u8 sndbuf[wlen+4 ];/* lead(1) devaddr,direction(1) addr(2) data(wlen) (len(2) (when reading)) */ +/* write only ? */ +int wo = (rbuf ==NULL || rlen ==0 ), + len =2 + wlen + (wo ?0 :2 ); + +deb_alot ("wo: %d, wlen: %d, len: %d\n" ,wo,wlen,len); + + sndbuf[0 ] = wo ?DIBUSB_REQ_I2C_WRITE :DIBUSB_REQ_I2C_READ ; + sndbuf[1 ] = (addr &0xfe ) | (wo ?0 :1 ); + +memcpy (&sndbuf[2 ],wbuf,wlen); + +if (!wo) { + sndbuf[wlen+2 ] = (rlen >>8 ) &0xff ; + sndbuf[wlen+3 ] = rlen &0xff ; + } + +return dibusb_readwrite_usb (dib,sndbuf,len,rbuf,rlen); +} + +/* +* DVB stuff +*/ + +static struct dibusb_pid *dibusb_get_free_pid (struct usb_dibusb *dib) +{ +int i; +unsigned long flags; +struct dibusb_pid *dpid =NULL ; + +spin_lock_irqsave (&dib->pid_list_lock,flags); +for (i=0 ; i <DIBUSB_MAX_PIDS ; i++) +if (!dib->pid_list[i].active) { + dpid = dib->pid_list + i; + dpid->active =1 ; +break ; + } +spin_unlock_irqrestore (&dib->pid_list_lock,flags); +return dpid; +} + +static int dibusb_start_xfer (struct usb_dibusb *dib) +{ +u8 b[4 ] = { + (DIB3000MB_REG_FIFO >>8 ) &0xff , + (DIB3000MB_REG_FIFO ) &0xff , + (DIB3000MB_FIFO_ACTIVATE >>8 ) &0xff , + (DIB3000MB_FIFO_ACTIVATE ) &0xff + }; +return dibusb_i2c_msg (dib,DIBUSB_DEMOD_I2C_ADDR_DEFAULT ,b,4 ,NULL ,0 ); +} + +static int dibusb_stop_xfer (struct usb_dibusb *dib) +{ +u8 b[4 ] = { + (DIB3000MB_REG_FIFO >>8 ) &0xff , + (DIB3000MB_REG_FIFO ) &0xff , + (DIB3000MB_FIFO_INHIBIT >>8 ) &0xff , + (DIB3000MB_FIFO_INHIBIT ) &0xff + }; +return dibusb_i2c_msg (dib,DIBUSB_DEMOD_I2C_ADDR_DEFAULT ,b,4 ,NULL ,0 ); +} + +static int dibusb_set_pid (struct dibusb_pid *dpid) +{ +u16 pid = dpid->pid | (dpid->active ?DIB3000MB_ACTIVATE_FILTERING :0 ); +u8 b[4 ] = { + (dpid->reg >>8 ) &0xff , + (dpid->reg) &0xff , + (pid >>8 ) &0xff , + (pid) &0xff + }; + +return dibusb_i2c_msg (dpid->dib,DIBUSB_DEMOD_I2C_ADDR_DEFAULT ,b,4 ,NULL ,0 ); +} + +static void dibusb_urb_complete (struct urb *urb,struct pt_regs *ptregs) +{ +struct usb_dibusb *dib = urb->context; + +if (!dib->streaming) +return ; + +if (urb->status ==0 ) { +deb_info ("URB return len: %d\n" ,urb->actual_length); +if (urb->actual_length %188 ) +deb_info ("TS Packets: %d, %d\n" , urb->actual_length/188 ,urb->actual_length %188 ); +dvb_dmx_swfilter_packets (&dib->demux, (u8 *) urb->transfer_buffer,urb->actual_length/188 ); + } + +if (dib->streaming) +usb_submit_urb (urb,GFP_KERNEL ); +} + + +static int dibusb_start_feed (struct dvb_demux_feed *dvbdmxfeed) +{ +// struct dvb_demux *dvbdmx = dvbdmxfeed->demux; +struct usb_dibusb *dib = dvbdmxfeed->demux->priv; +struct dibusb_pid *dpid; +int ret =0 ; + +deb_info ("pid: 0x%04x, feedtype: %d\n" , dvbdmxfeed->pid,dvbdmxfeed->type); + +if ((dpid =dibusb_get_free_pid (dib)) ==NULL ) { +err ("no free pid in list." ); +return -ENODEV ; + } + dvbdmxfeed->priv = dpid; + dpid->pid = dvbdmxfeed->pid; + +dibusb_set_pid (dpid); + +if (0 == dib->feed_count++) { +usb_fill_bulk_urb ( dib->buf_urb, dib->udev,DATA_PIPE , + dib->buffer,8192 , dibusb_urb_complete, dib); + dib->buf_urb->transfer_flags =0 ; + dib->buf_urb->timeout =0 ; + +if ((ret =usb_submit_urb (dib->buf_urb,GFP_KERNEL ))) { +dibusb_stop_xfer (dib); +err ("could not submit buffer urb." ); +return ret; + } + +if ((ret =dibusb_start_xfer (dib))) +return ret; + + dib->streaming =1 ; + } +return 0 ; +} + +static int dibusb_stop_feed (struct dvb_demux_feed *dvbdmxfeed) +{ +struct usb_dibusb *dib = dvbdmxfeed->demux->priv; +struct dibusb_pid *dpid = (struct dibusb_pid *) dvbdmxfeed->priv; + +deb_info ("stopfeed pid: 0x%04x, feedtype: %d" ,dvbdmxfeed->pid, dvbdmxfeed->type); + +if (dpid ==NULL ) +err ("channel in dmxfeed->priv was NULL" ); +else { + dpid->active =0 ; + dpid->pid =0 ; +dibusb_set_pid (dpid); + } + +if (--dib->feed_count ==0 ) { + dib->streaming =0 ; +usb_unlink_urb (dib->buf_urb); +dibusb_stop_xfer (dib); + } +return 0 ; +} + +/* +* firmware transfers +*/ + +/* +* do not use this, just a workaround for a bug, +* which will never occur :). +*/ +static int dibusb_interrupt_read_loop (struct usb_dibusb *dib) +{ +u8 b[1 ] = {DIBUSB_REQ_INTR_READ }; +return dibusb_write_usb (dib,b,1 ); +} + +/* +* TODO: a tasklet should run with a delay of 1/10 second +* and fill an appropriate event device ? +*/ +static int dibusb_read_remote_control (struct usb_dibusb *dib) +{ +u8 b[1 ] = {DIBUSB_REQ_POLL_REMOTE }, rb[5 ]; +int ret; +if ((ret =dibusb_readwrite_usb (dib,b,1 ,rb,5 ))) +return ret; + +return 0 ; +} + +/* +* ioctl for the firmware +*/ +static int dibusb_ioctl_cmd (struct usb_dibusb *dib,u8 cmd,u8 *param,int plen) +{ +u8 b[34 ]; +int size = plen >32 ?32 : plen; + b[0 ] =DIBUSB_REQ_SET_IOCTL ; + b[1 ] = cmd; +memcpy (&b[2 ],param,size); + +return dibusb_write_usb (dib,b,2 +size); +} + +/* +* ioctl for power control +*/ +static int dibusb_hw_sleep (struct usb_dibusb *dib) +{ +u8 b[1 ] = {DIBUSB_IOCTL_POWER_SLEEP }; +return dibusb_ioctl_cmd (dib,DIBUSB_IOCTL_CMD_POWER_MODE , b,1 ); +} + +static int dibusb_hw_wakeup (struct usb_dibusb *dib) +{ +u8 b[1 ] = {DIBUSB_IOCTL_POWER_WAKEUP }; +return dibusb_ioctl_cmd (dib,DIBUSB_IOCTL_CMD_POWER_MODE , b,1 ); +} + +/* +* I2C +*/ +static int dibusb_i2c_xfer (struct i2c_adapter *adap,struct i2c_msg msg[],int num) +{ +struct usb_dibusb *dib =i2c_get_adapdata (adap); +int i; + +if (down_interruptible (&dib->i2c_sem) <0 ) +return -EAGAIN ; + +for (i =0 ; i < num; i++) { +/* write/read request */ +if (i+1 < num && (msg[i+1 ].flags &I2C_M_RD )) { +if (dibusb_i2c_msg (dib, msg[i].addr, msg[i].buf,msg[i].len, + msg[i+1 ].buf,msg[i+1 ].len) <0 ) +break ; + i++; + }else +if (dibusb_i2c_msg (dib, msg[i].addr, msg[i].buf,msg[i].len,NULL ,0 ) <0 ) +break ; + } + +up (&dib->i2c_sem); +return i; +} + +static u32 dibusb_i2c_func (struct i2c_adapter *adapter) +{ +return I2C_FUNC_I2C ; +} + +static int dibusb_i2c_client_register (struct i2c_client *i2c) +{ +struct usb_dibusb *dib =i2c_get_adapdata (i2c->adapter); +if (i2c->driver->command) +return i2c->driver->command (i2c,FE_REGISTER ,dib->adapter); +return 0 ; +} + +static int dibusb_i2c_client_unregister (struct i2c_client *i2c) +{ +struct usb_dibusb *dib =i2c_get_adapdata (i2c->adapter); +if (i2c->driver->command) +return i2c->driver->command (i2c,FE_UNREGISTER ,dib->adapter); +return 0 ; +} + +static struct i2c_algorithm dibusb_algo = { + .name ="DiBcom USB i2c algorithm" , + .id =I2C_ALGO_BIT , + .master_xfer = dibusb_i2c_xfer, + .functionality = dibusb_i2c_func, +}; + +static int dibusb_dvb_init(struct usb_dibusb *dib) +{ + int ret; + +#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,4) + if ((ret = dvb_register_adapter(&dib->adapter, DRIVER_DESC)) < 0) { +#else + if ((ret = dvb_register_adapter(&dib->adapter, DRIVER_DESC , + THIS_MODULE)) < 0) { +#endif + deb_info("dvb_register_adapter failed: error %d", ret); + goto err; + } + + strncpy(dib->i2c_adap.name,dib->dibdev->name,I2C_NAME_SIZE); +#ifdef I2C_ADAP_CLASS_TV_DIGITAL + dib->i2c_adap.class = I2C_ADAP_CLASS_TV_DIGITAL, +#else + dib->i2c_adap.class = I2C_CLASS_TV_DIGITAL, +#endif + dib->i2c_adap.algo = &dibusb_algo; + dib->i2c_adap.algo_data = NULL; + dib->i2c_adap.id = I2C_ALGO_BIT; + dib->i2c_adap.client_register = dibusb_i2c_client_register, + dib->i2c_adap.client_unregister = dibusb_i2c_client_unregister, + + i2c_set_adapdata(&dib->i2c_adap, dib); + + if ((i2c_add_adapter(&dib->i2c_adap) < 0)) { + err("could not add i2c adapter"); + goto err_i2c; + } + + dib->demux.dmx.capabilities = DMX_TS_FILTERING | DMX_SECTION_FILTERING; + + dib->demux.priv = (void *)dib; + dib->demux.filternum = DIBUSB_MAX_PIDS; + dib->demux.feednum = DIBUSB_MAX_PIDS; + dib->demux.start_feed = dibusb_start_feed; + dib->demux.stop_feed = dibusb_stop_feed; + dib->demux.write_to_decoder = NULL; + if ((ret = dvb_dmx_init(&dib->demux)) < 0) { + err("dvb_dmx_init failed: error %d",ret); + goto err_dmx; + } + + dib->dmxdev.filternum = dib->demux.filternum; + dib->dmxdev.demux = &dib->demux.dmx; + dib->dmxdev.capabilities = 0; + if ((ret = dvb_dmxdev_init(&dib->dmxdev, dib->adapter)) < 0) { + err("dvb_dmxdev_init failed: error %d",ret); + goto err_dmx_dev; + } + + dvb_net_init(dib->adapter, &dib->dvb_net, &dib->demux.dmx); + + goto success; +err_dmx_dev: + dvb_dmx_release(&dib->demux); +err_dmx: + i2c_del_adapter(&dib->i2c_adap); +err_i2c: + dvb_unregister_adapter(dib->adapter); +err: + return ret; +success: + return 0; +} + +static int dibusb_dvb_exit(struct usb_dibusb *dib) +{ + deb_info("unregistering DVB part\n"); + dvb_net_release(&dib->dvb_net); + dib->demux.dmx.close(&dib->demux.dmx); + dvb_dmxdev_release(&dib->dmxdev); + dvb_dmx_release(&dib->demux); + i2c_del_adapter(&dib->i2c_adap); + dvb_unregister_adapter(dib->adapter); + + return 0; +} + +static int dibusb_exit(struct usb_dibusb *dib) +{ + usb_free_urb(dib->buf_urb); + pci_free_consistent(NULL,8192,dib->buffer,dib->dma_handle); + return 0; +} + +static int dibusb_init(struct usb_dibusb *dib) +{ + int ret,i; + sema_init(&dib->usb_sem, 1); + sema_init(&dib->i2c_sem, 1); + + /* + * when reloading the driver w/o replugging the device + * a timeout occures, this helps + */ + usb_clear_halt(dib->udev,COMMAND_PIPE); + usb_clear_halt(dib->udev,RESULT_PIPE); + usb_clear_halt(dib->udev,DATA_PIPE); + + /* dibusb_reset_cpu(dib); */ + + dib->buffer = pci_alloc_consistent(NULL,8192, &dib->dma_handle); + memset(dib->buffer,0,8192); + if (!(dib->buf_urb = usb_alloc_urb(0,GFP_KERNEL))) { + dibusb_exit(dib); + return -ENOMEM; + } + + for (i=0; i < DIBUSB_MAX_PIDS; i++) { + dib->pid_list[i].reg = i+DIB3000MB_REG_FIRST_PID; + dib->pid_list[i].pid = 0; + dib->pid_list[i].active = 0; + dib->pid_list[i].dib = dib; + } + + dib->streaming = 0; + dib->feed_count = 0; + + if ((ret = dibusb_dvb_init(dib))) { + dibusb_exit(dib); + return ret; + } + return 0; +} + +/* + * load a firmware packet to the device + */ +static int dibusb_writemem(struct usb_device *udev,u16 addr,u8 *data, u8 len) +{ + return usb_control_msg(udev, usb_sndctrlpipe(udev,0), + 0xa0, USB_TYPE_VENDOR, addr, 0x00, data, len, 5*HZ); +} + +static int dibusb_loadfirmware(struct usb_device *udev, + struct dibusb_device *dibdev) +{ + const struct firmware *fw = NULL; + u16 addr; + u8 *b,*p; + int ret = 0,i; + + for (i = 0; i < sizeof(valid_firmware_filenames)/sizeof(const char*); i++) { + if ((ret = request_firmware(&fw, valid_firmware_filenames[i], &udev->dev)) == 0) { + info("using firmware file (%s).",valid_firmware_filenames[i]); + break; + } + deb_info("tried to find '%s' firmware - unsuccessful. (%d)\n", + valid_firmware_filenames[i],ret); + } + + if (fw == NULL) { + err("did not find a valid firmware file. " + "Please see linux/Documentation/dvb/ for more details on firmware-problems."); + return -EINVAL; + } + p = kmalloc(fw->size,GFP_KERNEL); + if (p != NULL) { + u8 reset; + /* + * you cannot use the fw->data as buffer for + * usb_control_msg, a new buffer has to be + * created + */ + memcpy(p,fw->data,fw->size); + + /* stop the CPU */ + reset = 1; + if ((ret = dibusb_writemem(udev,DIBUSB_CPU_CSREG,&reset,1)) != 1) + err("could not stop the USB controller CPU."); + for(i = 0; p[i+3] == 0 && i < fw->size; ) { + b = (u8 *) &p[i]; + addr = *((u16 *) &b[1]); + + ret = dibusb_writemem(udev,addr,&b[4],b[0]); + + if (ret != b[0]) { + err("error while transferring firmware " + "(transferred size: %d, block size: %d)", + ret,b[1]); + ret = -EINVAL; + break; + } + i += 5 + b[0]; + } + /* restart the CPU */ + reset = 0; + if ((ret = dibusb_writemem(udev,DIBUSB_CPU_CSREG,&reset,1)) != 1) + err("could not restart the USB controller CPU."); + + kfree(p); + ret = 0; + } else { + ret = -ENOMEM; + } + release_firmware(fw); + + return ret; +} + +/* + * USB + */ +static int dibusb_probe(struct usb_interface *intf, + const struct usb_device_id *id) +{ + struct usb_device *udev = interface_to_usbdev(intf); + struct usb_dibusb *dib = NULL; + struct dibusb_device *dibdev = NULL; + + int ret = -ENOMEM,i,cold=0; + + for (i = 0; i < DIBUSB_SUPPORTED_DEVICES; i++) + if (dibusb_devices[i].cold_product_id == udev->descriptor.idProduct || + dibusb_devices[i].warm_product_id == udev->descriptor.idProduct) { + dibdev = &dibusb_devices[i]; + + cold = dibdev->cold_product_id == udev->descriptor.idProduct; + + if (cold) + info("found a '%s' in cold state, will try to load a firmware",dibdev->name); + else + info("found a '%s' in warm state.",dibdev->name); + } + + if (dibdev == NULL) { + err("something went very wrong, " + "unknown product ID: %.4x",udev->descriptor.idProduct); + return -ENODEV; + } + + if (cold) + ret = dibusb_loadfirmware(udev,dibdev); + else { + dib = kmalloc(sizeof(struct usb_dibusb),GFP_KERNEL); + if (dib == NULL) { + err("no memory"); + return ret; + } + memset(dib,0,sizeof(struct usb_dibusb)); + + dib->udev = udev; + dib->dibdev = dibdev; + + usb_set_intfdata(intf, dib); + + ret = dibusb_init(dib); + } + + if (ret == 0) + info("%s successfully initialized and connected.",dibdev->name); + else + info("%s error while loading driver (%d)",dibdev->name,ret); + return ret; +} + +static void dibusb_disconnect(struct usb_interface *intf) +{ + struct usb_dibusb *dib = usb_get_intfdata(intf); + const char *name = DRIVER_DESC; + + usb_set_intfdata(intf,NULL); + if (dib != NULL) { + name = dib->dibdev->name; + dibusb_dvb_exit(dib); + dibusb_exit(dib); + kfree(dib); + } + info("%s successfully deinitialized and disconnected.",name); + +} + +/* usb specific object needed to register this driver with the usb subsystem */ +static struct usb_driver dibusb_driver = { + .owner = THIS_MODULE, + .name = "dvb_dibusb", + .probe = dibusb_probe, + .disconnect = dibusb_disconnect, + .id_table = dibusb_table, +}; + +/* module stuff */ +static int __init usb_dibusb_init(void) +{ + int result; + if ((result = usb_register(&dibusb_driver))) { + err("usb_register failed. Error number %d",result); + return result; + } + + return 0; +} + +static void __exit usb_dibusb_exit(void) +{ + /* deregister this driver from the USB subsystem */ + usb_deregister(&dibusb_driver); +} + +module_init (usb_dibusb_init); +module_exit (usb_dibusb_exit); + +MODULE_AUTHOR(DRIVER_AUTHOR); +MODULE_DESCRIPTION(DRIVER_DESC); +MODULE_LICENSE("GPL");
drivers/media/dvb/dibusb/dvb-dibusb.h +175 -0
175 lines not on this page · raw message
drivers/media/dvb/dibusb/Kconfig +31 -0
@@ -0,0 +1,31 @@ +config DVB_DIBUSB + tristate "Twinhan/KWorld/Hama/Artec USB DVB-T devices" + depends on DVB_CORE && USB + select FW_LOADER + help + Support for USB 1.1 DVB-T devices based on a reference design made by + DiBcom (http://www.dibcom.fr). + + Devices supported by this driver: + + Twinhan VisionPlus VisionDTV USB-Ter (VP7041) + KWorld V-Stream XPERT DTV - DVB-T USB + Hama DVB-T USB-Box + DiBcom reference device (non-public) + Ultima Electronic/Artec T1 USB TVBOX + + The VP7041 seems to be identical to "CTS Portable" (Chinese + Television System). + + These devices can be understood as budget ones, they "only" deliver + the MPEG data. + + Currently all known copies of the DiBcom reference design have the DiBcom 3000MB + frontend onboard. Please enable and load this one manually in order to use this + device. + + A firmware is needed to use the device. See Documentation/dvb/README.dibusb + details. + + Say Y if you own such a device and want to use it. You should build it as + a module.
drivers/media/dvb/dibusb/Makefile +3 -0
@@ -0,0 +1,3 @@ +obj-$(CONFIG_DVB_DIBUSB) += dvb-dibusb.o + +EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/
drivers/media/dvb/Makefile +1 -2
@@ -2,5 +2,4 @@ # Makefile for the kernel multimedia device drivers. # -obj-y := dvb-core/ frontends/ ttpci/ ttusb-dec/ ttusb-budget/ b2c2/ bt8xx/ - +obj-y := dvb-core/ frontends/ ttpci/ ttusb-dec/ ttusb-budget/ b2c2/ bt8xx/ dibusb/
drivers/media/dvb/frontends/Kconfig +36 -10
76 lines not on this page · raw message
Re: [PATCH][2.6][12/14] misc. driver updates
- [DVB] av7110: convert MODULE_PARM() to module_param(), replace home-brewn waiting stuff in osd code with wait_event_interruptible_timeout()
- [DVB] av7110: put a semaphore around osd calls to make sure they're properly serialized, timeout variable in arm_thread() must be int, not unsigned long
- [DVB] av7110: add additional OSD window types (patch by Jeremy Jones), new ioctl OSD_GET_CAPABILITY/OSD_CAP_MEMSIZE; returns size of OSD memory
- [DVB] av7110: put audio/video initialization into separate function init_av7110_av(); call this function after system initialization and after arm crash to restore the previous state; thanks to Soeren Sonnenburg <[email protected]> for this patch.
- [DVB] av7110, budget, ttusb-budget: remove dvb i2c remains, support kernel i2c
- [DVB] av7110, budget: use msleep() instead of my_wait(), thanks to Kernel Janitors/Nishanth Aravamudan <[email protected]>
- [DVB] av7110, budget: fix videodev has no release callback
- [DVB] av7110: more sparse annotiations
- [DVB] budget: add support for TerraTec Cinergy 1200 DVB-S
- [DVB] budget: fix race condition in irq handler
- [DVB] skystar2, av7110, ttusb-budget, budget: make i2c client_(un)register() functions static
drivers/media/dvb/ttpci/av7110_av.c +3 -4
@@ -37,14 +37,10 @@#include <linux/smp_lock.h> #include <linux/fs.h> -#define DEBUG_VARIABLE av7110_debug -extern int av7110_debug; -#include "av7110.h" #include "av7110_hw.h" #include "av7110_av.h" #include "av7110_ipack.h" -#include "dvb_functions.h" /* MPEG-2 (ISO 13818 / H.222.0) stream types */ #define PROG_STREAM_MAP 0xBC
@@ -292,6 +286,9 @@DEB_EE (("av7110: %p\n" , av7110)); + av7110->mixer.volume_left = volleft; + av7110->mixer.volume_right = volright; +switch (av7110->adac_type) {case DVB_ADAC_TI : volleft = (volleft *256 ) /1036 ;
drivers/media/dvb/ttpci/av7110.c +153 -95
421 lines not on this page · raw message
drivers/media/dvb/ttpci/av7110_ca.c +0 -5
@@ -38,13 +38,8 @@#include <linux/byteorder/swabb.h> #include <linux/smp_lock.h> -#define DEBUG_VARIABLE av7110_debug -extern int av7110_debug; - -#include "dvb_i2c.h" #include "av7110.h" #include "av7110_hw.h" -#include "dvb_functions.h" void CI_handle (struct av7110 *av7110,u8 *data,u16 len)
drivers/media/dvb/ttpci/av7110.h +8 -6
@@ -4,13 +4,12 @@#include <linux/interrupt.h> #include <linux/socket.h> #include <linux/netdevice.h> +#include <linux/i2c.h> #ifdef CONFIG_DEVFS_FS #include <linux/devfs_fs_kernel.h> #endif -#include <media/saa7146_vv.h> -#include <linux/dvb/video.h> #include <linux/dvb/audio.h> #include <linux/dvb/dmx.h>
@@ -26,6 +25,7 @@#include "dvb_net.h" #include "dvb_ringbuffer.h" +#include <media/saa7146_vv.h> #define MAXFILT 32
@@ -60,12 +60,13 @@struct dvb_device dvb_dev;struct dvb_net dvb_net; -struct video_device v4l_dev; -struct video_device vbi_dev; +struct video_device *v4l_dev; +struct video_device *vbi_dev;struct saa7146_dev *dev; -struct dvb_i2c_bus *i2c_bus; +struct i2c_adapter i2c_adap; +char *card_name;/* support for analog module of dvb-c */
@@ -127,7 +128,7 @@int osdwin;/* currently active window */ u16 osdbpp[8 ]; - +struct semaphore osd_sema;/* CA */
@@ -187,6 +188,7 @@struct dvb_ringbuffer ci_rbuffer;struct dvb_ringbuffer ci_wbuffer; +struct audio_mixer mixer;struct dvb_adapter *dvb_adapter;struct dvb_device *video_dev;
drivers/media/dvb/ttpci/av7110_hw.c +137 -106
441 lines not on this page · raw message
drivers/media/dvb/ttpci/av7110_hw.h +3 -24
@@ -39,29 +39,6 @@ Pal8Bit = 256 /* 256 colors for 16 bit palette */ }; -enum av7110_window_display_type { -BITMAP1 ,/* 1 bit bitmap */ -BITMAP2 ,/* 2 bit bitmap */ -BITMAP4 ,/* 4 bit bitmap */ -BITMAP8 ,/* 8 bit bitmap */ -BITMAP1HR ,/* 1 Bit bitmap half resolution */ -BITMAP2HR ,/* 2 bit bitmap half resolution */ -BITMAP4HR ,/* 4 bit bitmap half resolution */ -BITMAP8HR ,/* 8 bit bitmap half resolution */ -YCRCB422 ,/* 4:2:2 YCRCB Graphic Display */ -YCRCB444 ,/* 4:4:4 YCRCB Graphic Display */ -YCRCB444HR ,/* 4:4:4 YCRCB graphic half resolution */ -VIDEOTSIZE ,/* True Size Normal MPEG Video Display */ -VIDEOHSIZE ,/* MPEG Video Display Half Resolution */ -VIDEOQSIZE ,/* MPEG Video Display Quarter Resolution */ -VIDEODSIZE ,/* MPEG Video Display Double Resolution */ -VIDEOTHSIZE ,/* True Size MPEG Video Display Half Resolution */ -VIDEOTQSIZE ,/* True Size MPEG Video Display Quarter Resolution*/ -VIDEOTDSIZE ,/* True Size MPEG Video Display Double Resolution */ -VIDEONSIZE ,/* Full Size MPEG Video Display */ -CURSOR /* Cursor */ -}; -/* switch defines */ #define SB_GPIO 3#define SB_OFF SAA7146_GPIO_OUTLO/* SlowBlank off (TV-Mode) */
@@ -388,6 +365,7 @@extern int av7110_bootarm (struct av7110 *av7110);extern int av7110_firmversion (struct av7110 *av7110);#define FW_CI_LL_SUPPORT (arm_app) ((arm_app) & 0x80000000) +#define FW_4M_SDRAM (arm_app) ((arm_app) & 0x40000000)#define FW_VERSION (arm_app) ((arm_app) & 0x0000FFFF)extern int av7110_fw_cmd (struct av7110 *av7110,int type,int com,int num, ...);
@@ -495,7 +473,7 @@static int inline audcom (struct av7110 *av7110,u32 com) { -return av7110_fw_cmd (av7110,COMTYPE_MISC ,AV7110_FW_AUDIO_COMMAND ,4 , +return av7110_fw_cmd (av7110,COMTYPE_MISC ,AV7110_FW_AUDIO_COMMAND ,2 , (com>>16 ), (com&0xffff )); }
@@ -510,6 +488,7 @@#ifdef CONFIG_DVB_AV7110_OSD extern int av7110_osd_cmd (struct av7110 *av7110,osd_cmd_t *dc); +extern int av7110_osd_capability (struct av7110 *av7110,osd_cap_t *cap);#endif /* CONFIG_DVB_AV7110_OSD */
drivers/media/dvb/ttpci/av7110_ir.c +6 -10
@@ -1,23 +1,21 @@#include <linux/types.h> #include <linux/init.h> #include <linux/module.h> +#include <linux/moduleparam.h> #include <linux/input.h> #include <linux/proc_fs.h> #include <asm/bitops.h> #include "av7110.h" -#if (LINUX_VERSION_CODE <KERNEL_VERSION (2 ,5 ,0 )) -#include "input_fake.h" -#endif - -#define UP_TIMEOUT (HZ/4) -static int av7110_ir_debug =0 ; +static int av7110_ir_debug; -#define dprintk(x...) do { if (av7110_ir_debug) printk (x); } while (0) +module_param_named (debug_ir, av7110_ir_debug, int,0644 ); +MODULE_PARM_DESC (av7110_ir_debug,"Turn on/off IR debugging (default:off)." ); +#define dprintk(x...) do { if (av7110_ir_debug) printk (x); } while (0)static struct input_dev input_dev;
@@ -205,6 +198,7 @@ void __exit av7110_ir_exit (void) { +del_timer_sync (&keyup_timer);remove_proc_entry ("av7110_ir" ,NULL );av7110_unregister_irc_handler (av7110_emit_key);input_unregister_device (&input_dev);
@@ -213,6 +207,3 @@//MODULE_AUTHOR("Holger Waechtler <[email protected]>"); //MODULE_LICENSE("GPL"); -MODULE_PARM (av7110_ir_debug,"i" ); -MODULE_PARM_DESC (av7110_ir_debug,"enable AV7110 IR receiver debug messages" ); -
drivers/media/dvb/ttpci/av7110_v4l.c +3 -11
@@ -35,23 +35,16 @@#include <linux/byteorder/swabb.h> #include <linux/smp_lock.h> -#define DEBUG_VARIABLE av7110_debug -extern int av7110_debug; - -#include "dvb_i2c.h" #include "av7110.h" #include "av7110_hw.h" #include "av7110_av.h" -#include "dvb_functions.h" -int msp_writereg (struct av7110 *av7110,u8 dev,u16 reg,u16 val) {u8 msg[5 ] = { dev, reg >>8 , reg &0xff , val >>8 , val &0xff }; -struct dvb_i2c_bus *i2c = av7110->i2c_bus;struct i2c_msg msgs = { .flags =0 , .addr =0x40 , .len =5 , .buf = msg }; -if (i2c->xfer (i2c, &msgs,1 ) !=1 ) { +if (i2c_transfer (&av7110->i2c_adap, &msgs,1 ) !=1 ) {printk ("av7110(%d): %s(%u = %u) failed\n" , av7110->dvb_adapter->num, __FUNCTION__, reg, val);return -EIO ;
@@ -63,13 +56,12 @@ {u8 msg1[3 ] = { dev, reg >>8 , reg &0xff };u8 msg2[2 ]; -struct dvb_i2c_bus *i2c = av7110->i2c_bus;struct i2c_msg msgs[2 ] = { { .flags =0 , .addr =0x40 , .len =3 , .buf = msg1 }, { .flags =I2C_M_RD , .addr =0x40 , .len =2 , .buf = msg2 } }; -if (i2c->xfer (i2c, msgs,2 ) !=2 ) { +if (i2c_transfer (&av7110->i2c_adap, &msgs[0 ],2 ) !=2 ) {printk ("av7110(%d): %s(%u) failed\n" , av7110->dvb_adapter->num, __FUNCTION__, reg);return -EIO ;
@@ -517,7 +507,7 @@printk ("av7110(%d): DVB-C analog module detected, initializing MSP3400\n" , av7110->dvb_adapter->num); av7110->adac_type =DVB_ADAC_MSP ; -dvb_delay (100 );// the probing above resets the msp... +msleep (100 );// the probing above resets the msp... msp_readreg (av7110,MSP_RD_DSP ,0x001e , &version1);msp_readreg (av7110,MSP_RD_DSP ,0x001f , &version2); printk("av7110(%d): MSP3400 version 0x%04x 0x%04x\n",
drivers/media/dvb/ttpci/budget-av.c +24 -23
159 lines not on this page · raw message
drivers/media/dvb/ttpci/budget.c +3 -4
@@ -35,7 +35,6 @@*/ #include "budget.h" -#include "dvb_functions.h" static void Set22K (struct budget *budget,int state) {
@@ -100,7 +99,7 @@udelay (12500 );saa7146_setgpio (dev,3 ,SAA7146_GPIO_OUTLO ); } -dvb_delay (20 ); +msleep (20 ); }return 0 ;
@@ -202,6 +201,8 @@DEB_EE (("dev:%p, info:%p, budget:%p\n" ,dev,info,budget)); + dev->ext_priv = budget; +if ((err =ttpci_budget_init (budget, dev, info))) {printk ("==> failed\n" );kfree (budget);
@@ -215,8 +216,6 @@dvb_add_frontend_ioctls (budget->dvb_adapter, budget_diseqc_ioctl,NULL , budget); - dev->ext_priv = budget; -return 0 ; }
drivers/media/dvb/ttpci/budget-ci.c +20 -15
@@ -38,13 +38,8 @@#include <linux/input.h> #include <linux/spinlock.h> -#include "dvb_functions.h" #include "dvb_ca_en50221.h" -#if (LINUX_VERSION_CODE <KERNEL_VERSION (2 ,5 ,0 )) -#include "input_fake.h" -#endif -#define DEBIADDR_IR 0x1234#define DEBIADDR_CICONTROL 0x0000#define DEBIADDR_CIVERSION 0x4000
@@ -326,7 +321,7 @@saa7146_setgpio (saa,0 ,SAA7146_GPIO_IRQHI ); budget_ci->slot_status =SLOTSTATUS_RESET ;budget_debiwrite (budget_ci,DEBICICTL ,DEBIADDR_CICONTROL ,1 ,0 ); -dvb_delay (1 ); +msleep (1 );budget_debiwrite (budget_ci,DEBICICTL ,DEBIADDR_CICONTROL ,1 ,CICONTROL_RESET );saa7146_setgpio (saa,1 ,SAA7146_GPIO_OUTHI );
@@ -372,14 +367,13 @@// ensure we don't get spurious IRQs during initialisation if (!budget_ci->budget.ci_present)return ; +// read the CAM status flags =budget_debiread (budget_ci,DEBICICTL ,DEBIADDR_CICONTROL ,1 ); +if (flags &CICONTROL_CAMDETECT ) { -// always set the GPIO mode back to "normal", in case the card is -// yanked at an inopportune moment +// GPIO should be set to trigger on falling edge if a CAM is present saa7146_setgpio (saa,0 ,SAA7146_GPIO_IRQLO ); -if (flags &CICONTROL_CAMDETECT ) { -if (budget_ci->slot_status &SLOTSTATUS_NONE ) {// CAM insertion IRQ budget_ci->slot_status =SLOTSTATUS_PRESENT ;
@@ -395,7 +389,15 @@dvb_ca_en50221_frda_irq (&budget_ci->ca,0 ); } }else { + +// trigger on rising edge if a CAM is not present - when a CAM is inserted, we +// only want to get the IRQ when it sets READY. If we trigger on the falling edge, +// the CAM might not actually be ready yet. +saa7146_setgpio (saa,0 ,SAA7146_GPIO_IRQHI ); + +// generate a CAM removal IRQ if we haven't already if (budget_ci->slot_status &SLOTSTATUS_OCCUPIED ) { +// CAM removal IRQ budget_ci->slot_status =SLOTSTATUS_NONE ;dvb_ca_en50221_camchange_irq (&budget_ci->ca,0 ,DVB_CA_EN50221_CAMCHANGE_REMOVED ); }
@@ -446,7 +448,11 @@// Setup CI slot IRQ tasklet_init (&budget_ci->ciintf_irq_tasklet, ciintf_interrupt, (unsigned long ) budget_ci); +if (budget_ci->slot_status !=SLOTSTATUS_NONE ) {saa7146_setgpio (saa,0 ,SAA7146_GPIO_IRQLO ); + }else { +saa7146_setgpio (saa,0 ,SAA7146_GPIO_IRQHI ); + }saa7146_write (saa,IER ,saa7146_read (saa,IER ) |MASK_03 );budget_debiwrite (budget_ci,DEBICICTL ,DEBIADDR_CICONTROL ,1 ,CICONTROL_RESET );
@@ -475,7 +481,7 @@saa7146_setgpio (saa,0 ,SAA7146_GPIO_INPUT );tasklet_kill (&budget_ci->ciintf_irq_tasklet);budget_debiwrite (budget_ci,DEBICICTL ,DEBIADDR_CICONTROL ,1 ,0 ); -dvb_delay (1 ); +msleep (1 );budget_debiwrite (budget_ci,DEBICICTL ,DEBIADDR_CICONTROL ,1 ,CICONTROL_RESET );// disable TS data stream to CI interface
@@ -520,20 +526,19 @@spin_lock_init (&budget_ci->debilock); budget_ci->budget.ci_present =0 ; + dev->ext_priv = budget_ci; +if ((err =ttpci_budget_init (&budget_ci->budget, dev, info))) {kfree (budget_ci);return err; } - dev->ext_priv = budget_ci; -tasklet_init (&budget_ci->msp430_irq_tasklet, msp430_ir_interrupt, (unsigned long ) budget_ci);msp430_ir_init (budget_ci); -// UNCOMMENT TO TEST CI INTERFACE -// ciintf_init(budget_ci); +ciintf_init (budget_ci);return 0 ; }
drivers/media/dvb/ttpci/budget-core.c +41 -17
108 lines not on this page · raw message
drivers/media/dvb/ttpci/budget.h +4 -4
@@ -1,9 +1,6 @@#ifndef __BUDGET_DVB__#define __BUDGET_DVB__ -#include <media/saa7146.h> - -#include "dvb_i2c.h" #include "dvb_frontend.h" #include "dvbdev.h" #include "demux.h"
@@ -12,6 +9,8 @@#include "dvb_filter.h" #include "dvb_net.h" +#include <media/saa7146.h> +extern int budget_debug;struct budget_info {
@@ -28,7 +27,7 @@struct saa7146_dev *dev; -struct dvb_i2c_bus *i2c_bus; +struct i2c_adapter i2c_adap;struct budget_info *card;unsigned char *grabbing;
@@ -79,6 +78,7 @@#define BUDGET_KNC1 2#define BUDGET_PATCH 3#define BUDGET_FS_ACTIVY 4 +#define BUDGET_CIN1200 5#define BUDGET_VIDEO_PORTA 0#define BUDGET_VIDEO_PORTB 1
drivers/media/dvb/ttpci/ttpci-eeprom.c +10 -13
@@ -35,9 +35,8 @@#include <linux/init.h> #include <linux/module.h> #include <linux/string.h> +#include <linux/i2c.h> -#include "dvb_i2c.h" -#include "dvb_functions.h" #if 1 #define dprintk(x...) do { printk(x); } while (0)
@@ -85,7 +84,7 @@return 0 ; } -static int ttpci_eeprom_read_encodedMAC (struct dvb_i2c_bus *i2c,u8 * encodedMAC) +static int ttpci_eeprom_read_encodedMAC (struct i2c_adapter *adapter,u8 * encodedMAC) {int ret;u8 b0[] = {0xcc };
@@ -97,7 +96,7 @@/* dprintk("%s\n", __FUNCTION__); */ - ret = i2c->xfer (i2c, msg,2 ); + ret =i2c_transfer (adapter, msg,2 );if (ret !=2 )/* Assume EEPROM isn't there */ return (-ENODEV );
@@ -106,36 +105,34 @@ } -int ttpci_eeprom_parse_mac (struct dvb_i2c_bus *i2c) +int ttpci_eeprom_parse_mac (struct i2c_adapter *adapter,u8 *proposed_mac) {int ret, i;u8 encodedMAC[20 ];u8 decodedMAC[6 ]; - ret =ttpci_eeprom_read_encodedMAC (i2c, encodedMAC); + ret =ttpci_eeprom_read_encodedMAC (adapter, encodedMAC);if (ret !=0 ) {/* Will only be -ENODEV */ dprintk ("Couldn't read from EEPROM: not there?\n" ); -memset (i2c->adapter->proposed_mac,0 ,6 ); +memset (proposed_mac,0 ,6 );return ret; } ret =getmac_tt (decodedMAC, encodedMAC);if ( ret !=0 ) { -dprintk ("%s adapter %i failed MAC signature check\n" , - i2c->adapter->name, i2c->adapter->num); +dprintk ("adapter failed MAC signature check\n" );dprintk ("encoded MAC from EEPROM was " );for (i=0 ; i<19 ; i++) {dprintk ("%.2x:" , encodedMAC[i]); }dprintk ("%.2x\n" , encodedMAC[19 ]); -memset (i2c->adapter->proposed_mac,0 ,6 ); +memset (proposed_mac,0 ,6 );return ret; } -memcpy (i2c->adapter->proposed_mac, decodedMAC,6 ); -dprintk ("%s adapter %i has MAC addr = %.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n" , - i2c->adapter->name, i2c->adapter->num, +memcpy (proposed_mac, decodedMAC,6 ); +dprintk ("adapter has MAC addr = %.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n" , decodedMAC[0 ], decodedMAC[1 ], decodedMAC[2 ], decodedMAC[3 ], decodedMAC[4 ], decodedMAC[5 ]);return 0 ;
drivers/media/dvb/ttpci/ttpci-eeprom.h +3 -2
@@ -25,8 +25,9 @@#ifndef __TTPCI_EEPROM_H__#define __TTPCI_EEPROM_H__ -#include "dvb_i2c.h" +#include <linux/types.h> +#include <linux/i2c.h> -extern int ttpci_eeprom_parse_mac (struct dvb_i2c_bus *i2c); +extern int ttpci_eeprom_parse_mac (struct i2c_adapter *adapter,u8 *propsed_mac);#endif
drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c +82 -33
217 lines not on this page · raw message
drivers/media/dvb/ttusb-dec/ttusb_dec.c +24 -16
@@ -22,10 +22,12 @@#include <asm/semaphore.h> #include <linux/list.h> #include <linux/module.h> +#include <linux/moduleparam.h> #include <linux/pci.h> #include <linux/slab.h> #include <linux/spinlock.h> #include <linux/usb.h> +#include <linux/version.h> #include <linux/interrupt.h> #include <linux/firmware.h> #if defined(CONFIG_CRC32 ) || defined(CONFIG_CRC32_MODULE )
@@ -37,13 +39,17 @@#include "dmxdev.h" #include "dvb_demux.h" -#include "dvb_i2c.h" #include "dvb_filter.h" #include "dvb_frontend.h" #include "dvb_net.h" -static int debug =0 ; -static int output_pva =0 ; +static int debug; +static int output_pva; + +module_param (debug, int,0644 ); +MODULE_PARM_DESC (debug,"Turn on/off debugging (default:off)." ); +module_param (output_pva, int,0444 ); +MODULE_PARM_DESC (output_pva,"Output PVA from dvr device (default:off)" );#define dprintk if (debug) printk
@@ -95,7 +101,6 @@struct dmxdev dmxdev;struct dvb_demux demux;struct dmx_frontend frontend; -struct dvb_i2c_bus i2c_bus;struct dvb_net dvb_net;struct dvb_frontend_info *frontend_info;int (*frontend_ioctl) (struct dvb_frontend *,unsigned int ,void *);
@@ -1100,7 +1104,7 @@ &dec->iso_dma_handle);memset (dec->iso_buffer,0 , -sizeof (ISO_FRAME_SIZE * (FRAMES_PER_ISO_BUF *ISO_BUF_COUNT ))); +ISO_FRAME_SIZE * (FRAMES_PER_ISO_BUF *ISO_BUF_COUNT ));for (i =0 ; i <ISO_BUF_COUNT ; i++) {struct urb *urb;
@@ -1600,7 +1603,7 @@ p->u.qam.symbol_rate);dprintk (" inversion->%d\n" , p->inversion); - freq =htonl (p->frequency *1000 + + freq =htonl (p->frequency + (dec->hi_band ?LOF_HI :LOF_LO ));memcpy (&b[4 ], &freq,sizeof (u32)); sym_rate =htonl (p->u.qam.symbol_rate);
@@ -1628,9 +1631,18 @@dprintk ("%s: FE_INIT\n" , __FUNCTION__);break ; -case FE_DISEQC_SEND_MASTER_CMD : +case FE_DISEQC_SEND_MASTER_CMD : { +u8 b[] = {0x00 ,0xff ,0x00 ,0x00 , +0x00 ,0x00 ,0x00 ,0x00 , +0x00 ,0x00 }; +struct dvb_diseqc_master_cmd *cmd = arg; +memcpy (&b[4 ], cmd->msg, cmd->msg_len);dprintk ("%s: FE_DISEQC_SEND_MASTER_CMD\n" , __FUNCTION__); +ttusb_dec_send_command (dec,0x72 , +sizeof (b) - (6 - cmd->msg_len), b, +NULL ,NULL );break ; + }case FE_DISEQC_SEND_BURST :dprintk ("%s: FE_DISEQC_SEND_BURST\n" , __FUNCTION__);
@@ -1669,15 +1680,13 @@static void ttusb_dec_init_frontend (struct ttusb_dec *dec) { - dec->i2c_bus.adapter = dec->adapter; - -dvb_register_frontend (dec->frontend_ioctl, &dec->i2c_bus, (void *)dec, - dec->frontend_info); +int ret; + ret =dvb_register_frontend (dec->frontend_ioctl, dec->adapter, dec, dec->frontend_info,THIS_MODULE ); }static void ttusb_dec_exit_frontend (struct ttusb_dec *dec) { -dvb_unregister_frontend (dec->frontend_ioctl, &dec->i2c_bus); +dvb_unregister_frontend_new (dec->frontend_ioctl, dec->adapter); }static void ttusb_dec_init_filters (struct ttusb_dec *dec)
@@ -1840,7 +1849,3 @@MODULE_LICENSE ("GPL" );MODULE_DEVICE_TABLE (usb, ttusb_dec_table); -MODULE_PARM (debug,"i" ); -MODULE_PARM_DESC (debug,"Debug level" ); -MODULE_PARM (output_pva,"i" ); -MODULE_PARM_DESC (output_pva,"Output PVA from dvr device" );
include/linux/dvb/osd.h +32 -0
@@ -94,6 +94,7 @@ OSD_Text,// (x0,y0,size,color,text) OSD_SetWindow,// (x0) set window with number 0<x0<8 as current OSD_MoveWindow,// move current window to (x0, y0) + OSD_OpenRaw,// Open other types of OSD windows } OSD_Command; typedef struct osd_cmd_s {
@@ -106,8 +107,39 @@ void __user *data; } osd_cmd_t; +/* OSD_OpenRaw: set 'color' to desired window type */ +typedef enum { +OSD_BITMAP1 ,/* 1 bit bitmap */ +OSD_BITMAP2 ,/* 2 bit bitmap */ +OSD_BITMAP4 ,/* 4 bit bitmap */ +OSD_BITMAP8 ,/* 8 bit bitmap */ +OSD_BITMAP1HR ,/* 1 Bit bitmap half resolution */ +OSD_BITMAP2HR ,/* 2 bit bitmap half resolution */ +OSD_BITMAP4HR ,/* 4 bit bitmap half resolution */ +OSD_BITMAP8HR ,/* 8 bit bitmap half resolution */ +OSD_YCRCB422 ,/* 4:2:2 YCRCB Graphic Display */ +OSD_YCRCB444 ,/* 4:4:4 YCRCB Graphic Display */ +OSD_YCRCB444HR ,/* 4:4:4 YCRCB graphic half resolution */ +OSD_VIDEOTSIZE ,/* True Size Normal MPEG Video Display */ +OSD_VIDEOHSIZE ,/* MPEG Video Display Half Resolution */ +OSD_VIDEOQSIZE ,/* MPEG Video Display Quarter Resolution */ +OSD_VIDEODSIZE ,/* MPEG Video Display Double Resolution */ +OSD_VIDEOTHSIZE ,/* True Size MPEG Video Display Half Resolution */ +OSD_VIDEOTQSIZE ,/* True Size MPEG Video Display Quarter Resolution*/ +OSD_VIDEOTDSIZE ,/* True Size MPEG Video Display Double Resolution */ +OSD_VIDEONSIZE ,/* Full Size MPEG Video Display */ +OSD_CURSOR /* Cursor */ +}osd_raw_window_t ; + +typedef struct osd_cap_s { +int cmd; +#define OSD_CAP_MEMSIZE 1/* memory size */ +long val; +}osd_cap_t ; +#define OSD_SEND_CMD _IOW('o', 160, osd_cmd_t) +#define OSD_GET_CAPABILITY _IOR('o', 161, osd_cap_t)#endif
drivers/media/dvb/b2c2/skystar2.c +2 -2
@@ -2236,7 +2236,7 @@ } -int client_register (struct i2c_client *client) +static int client_register (struct i2c_client *client) {struct adapter *adapter = (struct adapter *)i2c_get_adapdata (client->adapter);
@@ -2247,7 +2247,7 @@return 0 ; } -int client_unregister (struct i2c_client *client) +static int client_unregister (struct i2c_client *client) {struct adapter *adapter = (struct adapter *)i2c_get_adapdata (client->adapter);
drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c +2 -2
@@ -1083,7 +1083,7 @@ .functionality = functionality, }; -int client_register (struct i2c_client *client) +static int client_register (struct i2c_client *client) {struct ttusb *ttusb = (struct ttusb *)i2c_get_adapdata (client->adapter);
@@ -1093,7 +1093,7 @@return 0 ; } -int client_unregister (struct i2c_client *client) +static int client_unregister (struct i2c_client *client) {struct ttusb *ttusb = (struct ttusb *)i2c_get_adapdata (client->adapter);
drivers/media/dvb/ttpci/budget-core.c +2 -2
@@ -264,7 +264,7 @@ }/* fixme: can this be unified among all saa7146 based dvb cards? */ -int client_register (struct i2c_client *client) +static int client_register (struct i2c_client *client) {struct saa7146_dev *dev = (struct saa7146_dev *)i2c_get_adapdata (client->adapter);struct budget *budget = (struct budget *)dev->ext_priv;
@@ -274,7 +274,7 @@return 0 ; } -int client_unregister (struct i2c_client *client) +static int client_unregister (struct i2c_client *client) {struct saa7146_dev *dev = (struct saa7146_dev *)i2c_get_adapdata (client->adapter);struct budget *budget = (struct budget *)dev->ext_priv;
drivers/media/dvb/ttpci/av7110.c +3 -2
@@ -1412,7 +1411,8 @@ }#endif -int client_register (struct i2c_client *client) + +static int client_register (struct i2c_client *client) {struct saa7146_dev *dev = (struct saa7146_dev *)i2c_get_adapdata (client->adapter);struct av7110 *av7110 = (struct av7110 *)dev->ext_priv;
@@ -1423,7 +1423,7 @@return 0 ; } -int client_unregister (struct i2c_client *client) +static int client_unregister (struct i2c_client *client) {struct saa7146_dev *dev = (struct saa7146_dev *)i2c_get_adapdata (client->adapter);struct av7110 *av7110 = (struct av7110 *)dev->ext_priv;
drivers/media/dvb/ttpci/budget-ci.c +8 -6
@@ -74,14 +74,15 @@ {struct saa7146_dev *saa = budget_ci->budget.dev;u32 result =0 ; +unsigned long flags;if (count >4 || count <=0 )return 0 ; -spin_lock (&budget_ci->debilock); +spin_lock_irqsave (&budget_ci->debilock, flags);if (saa7146_wait_for_debi_done (saa) <0 ) { -spin_unlock (&budget_ci->debilock); +spin_unlock_irqrestore (&budget_ci->debilock, flags);return 0 ; }
@@ -96,21 +97,22 @@ result =saa7146_read (saa,0x88 ); result &= (0xffffffffUL >> ((4 - count) *8 )); -spin_unlock (&budget_ci->debilock); +spin_unlock_irqrestore (&budget_ci->debilock, flags);return result; }static u8 budget_debiwrite (struct budget_ci * budget_ci,u32 config,int addr,int count,u32 value) {struct saa7146_dev *saa = budget_ci->budget.dev; +unsigned long flags;if (count >4 || count <=0 )return 0 ; -spin_lock (&budget_ci->debilock); +spin_lock_irqsave (&budget_ci->debilock, flags);if (saa7146_wait_for_debi_done (saa) <0 ) { -spin_unlock (&budget_ci->debilock); +spin_unlock_irqrestore (&budget_ci->debilock, flags);return 0 ; }
@@ -123,7 +125,7 @@saa7146_wait_for_debi_done (saa); -spin_unlock (&budget_ci->debilock); +spin_unlock_irqrestore (&budget_ci->debilock, flags);return 0 ; }
Re: [PATCH][2.6][13/14] dvb frontend updates
- [DVB] all: replace dvb_unregister_frontend_new() with dvb_unregister_frontend()
- [DVB] sp887x: fix firmware download, patch by Jose Alberto Reguero
- [DVB] tda1004x: add firmware loading via firmware_class()
- [DVB] dvb_frontend: without hierachical coding, code_rate_LP is irrelevant, so we tolerate the otherwise invalid FEC_NONE setting
- [DVB] ves1x93: fixed dropouts on older DVB cards, fix tuning issues (Andreas Share / Gregoire Favre),
drivers/media/dvb/dvb-core/dvb_ksyms.c +1 -1
@@ -24,7 +24,7 @@EXPORT_SYMBOL (dvbdmx_disconnect_frontend);EXPORT_SYMBOL (dvb_register_frontend); -EXPORT_SYMBOL (dvb_unregister_frontend_new); +EXPORT_SYMBOL (dvb_unregister_frontend);EXPORT_SYMBOL (dvb_add_frontend_ioctls);EXPORT_SYMBOL (dvb_remove_frontend_ioctls);EXPORT_SYMBOL (dvb_add_frontend_notifier);
drivers/media/dvb/frontends/alps_tdlb7.c +4 -9
@@ -19,15 +19,10 @@Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* -This driver needs a copy of the firmware file from the Technotrend -Windoze driver. - -This page is worth a look: -http://www.heise.de/ct/ftp/projekte/vdr/firmware.shtml -- Copy 'Sc_main.mc' to '/usr/lib/hotplug/firmware/dvb-fe-tdlb7-2.16.fw'. +* This driver needs external firmware. Please use the command +* "<kerneldir>/Documentation/dvb/get_dvb_firmware alps_tdlb7" to +* download/extract it, and then copy it to /usr/lib/hotplug/firmware. */ #define SP887X_DEFAULT_FIRMWARE "dvb-fe-tdlb7-2.16.fw"
@@ -690,7 +683,7 @@dprintk ("%s\n" , __FUNCTION__); -dvb_unregister_frontend_new (tdlb7_ioctl, state->dvb); +dvb_unregister_frontend (tdlb7_ioctl, state->dvb);i2c_detach_client (client);BUG_ON (state->dvb);kfree (client);
drivers/media/dvb/frontends/alps_tdmb7.c +1 -1
@@ -470,7 +467,7 @@dprintk ("%s\n" , __FUNCTION__); -dvb_unregister_frontend_new (tdmb7_ioctl, state->dvb); +dvb_unregister_frontend (tdmb7_ioctl, state->dvb);i2c_detach_client (client);BUG_ON (state->dvb);kfree (client);
drivers/media/dvb/frontends/at76c651.c +1 -1
@@ -514,7 +508,7 @@ {struct at76c651_state *state =i2c_get_clientdata (client); -dvb_unregister_frontend_new (at76c651_ioctl, state->dvb); +dvb_unregister_frontend (at76c651_ioctl, state->dvb);i2c_detach_client (client);BUG_ON (state->dvb);kfree (client);
drivers/media/dvb/frontends/cx24110.c +1 -1
@@ -708,7 +708,7 @@ {struct cx24110_state *state =i2c_get_clientdata (client); -dvb_unregister_frontend_new (cx24110_ioctl, state->dvb); +dvb_unregister_frontend (cx24110_ioctl, state->dvb);i2c_detach_client (client);BUG_ON (state->dvb);kfree (client);
drivers/media/dvb/frontends/dst.c +1 -1
@@ -1193,7 +1190,7 @@ {struct dst_data *state = (struct dst_data *)i2c_get_clientdata (client); -dvb_unregister_frontend_new (dst_ioctl, state->dvb); +dvb_unregister_frontend (dst_ioctl, state->dvb);device_remove_file (&client->dev, &dev_attr_client_type);device_remove_file (&client->dev, &dev_attr_client_flags);
drivers/media/dvb/frontends/dvb_dummy_fe.c +1 -1
@@ -207,7 +207,7 @@ {struct dvb_adapter *dvb =i2c_get_clientdata (client); -dvb_unregister_frontend_new (dvbdummyfe_ioctl, dvb); +dvb_unregister_frontend (dvbdummyfe_ioctl, dvb);i2c_detach_client (client);kfree (client);return 0 ;
drivers/media/dvb/frontends/grundig_29504-401.c +1 -1
@@ -684,7 +684,7 @@ {struct l64781_state *state =i2c_get_clientdata (client); -dvb_unregister_frontend_new (l64781_ioctl, state->dvb); +dvb_unregister_frontend (l64781_ioctl, state->dvb);i2c_detach_client (client);BUG_ON (state->dvb);kfree (client);
drivers/media/dvb/frontends/grundig_29504-491.c +1 -1
@@ -492,7 +490,7 @@ {struct tda8083_state *state =i2c_get_clientdata (client); -dvb_unregister_frontend_new (tda8083_ioctl, state->dvb); +dvb_unregister_frontend (tda8083_ioctl, state->dvb);i2c_detach_client (client);BUG_ON (state->dvb);kfree (client);
drivers/media/dvb/frontends/mt312.c +1 -1
@@ -845,7 +845,7 @@dprintk ("%s\n" , __FUNCTION__); -dvb_unregister_frontend_new (mt312_ioctl, state->dvb); +dvb_unregister_frontend (mt312_ioctl, state->dvb);i2c_detach_client (client);BUG_ON (state->dvb);kfree (client);
drivers/media/dvb/frontends/mt352.c +1 -1
@@ -840,7 +840,7 @@ {struct mt352_state *state =i2c_get_clientdata (client); -dvb_unregister_frontend_new (mt352_ioctl, state->dvb); +dvb_unregister_frontend (mt352_ioctl, state->dvb);i2c_detach_client (client);BUG_ON (state->dvb);kfree (client);
drivers/media/dvb/frontends/nxt6000.c +1 -1
@@ -872,7 +791,7 @@static int detach_client (struct i2c_client *client) {struct nxt6000_config *state = (struct nxt6000_config *)i2c_get_clientdata (client); -dvb_unregister_frontend_new (nxt6000_ioctl, state->dvb); +dvb_unregister_frontend (nxt6000_ioctl, state->dvb);i2c_detach_client (client);BUG_ON (state->dvb);kfree (client);
drivers/media/dvb/frontends/sp887x.c +6 -13
@@ -3,16 +3,9 @@*/ /* -This driver needs a copy of the Avermedia firmware. The version tested -is part of the Avermedia DVB-T 1.3.26.3 Application. If the software is -installed in Windoze the file will be in the /Program Files/AVerTV DVB-T/ -directory and is called sc_main.mc. Alternatively it can "extracted" from -the install cab files. -- Copy this file to '/usr/lib/hotplug/firmware/dvb-fe-sp887x.fw'. -- With this version of the file the first 10 bytes are discarded and the -next 0x4000 loaded. This may change in future versions. +* This driver needs external firmware. Please use the command +* "<kerneldir>/Documentation/dvb/get_dvb_firmware sp887x" to +* download/extract it, and then copy it to /usr/lib/hotplug/firmware. */ #define SP887X_DEFAULT_FIRMWARE "dvb-fe-sp887x.fw"
@@ -202,8 +195,8 @@int c =BLOCKSIZE ;int err; -if (i+c > fw_size) - c = fw_size - i; +if (i+c >FW_SIZE ) + c =FW_SIZE - i;/* bit 0x8000 in address is set to enable 13bit mode */ /* bit 0x4000 enables multibyte read/write transfers */
@@ -650,7 +641,7 @@dprintk ("%s\n" , __FUNCTION__); -dvb_unregister_frontend_new (sp887x_ioctl, state->dvb); +dvb_unregister_frontend (sp887x_ioctl, state->dvb);i2c_detach_client (client);BUG_ON (state->dvb);kfree (client);
drivers/media/dvb/frontends/stv0299.c +1 -1
@@ -1414,7 +1414,7 @@ {struct stv0299_state *state = (struct stv0299_state *)i2c_get_clientdata (client); -dvb_unregister_frontend_new (uni0299_ioctl, state->dvb); +dvb_unregister_frontend (uni0299_ioctl, state->dvb);i2c_detach_client (client);kfree (client);kfree (state);
drivers/media/dvb/frontends/tda1004x.c +32 -79
198 lines not on this page · raw message
drivers/media/dvb/dvb-core/dvb_frontend.c +8 -1
@@ -762,6 +763,13 @@ fe->parameters.inversion =INVERSION_AUTO ; fetunesettings.parameters.inversion =INVERSION_AUTO ; } +if (fe->info->type ==FE_OFDM ) { +/* without hierachical coding code_rate_LP is irrelevant, +* so we tolerate the otherwise invalid FEC_NONE setting */ +if (fe->parameters.u.ofdm.hierarchy_information ==HIERARCHY_NONE && + fe->parameters.u.ofdm.code_rate_LP ==FEC_NONE ) + fe->parameters.u.ofdm.code_rate_LP =FEC_AUTO ; + }/* get frontend-specific tuning settings */ if (dvb_frontend_internal_ioctl(&fe->frontend, FE_GET_TUNE_SETTINGS,
@@ -1180,7 +1186,7 @@return 0 ; } -int dvb_unregister_frontend_new (int (*ioctl) (struct dvb_frontend *frontend, +int dvb_unregister_frontend (int (*ioctl) (struct dvb_frontend *frontend,unsigned int cmd,void *arg),struct dvb_adapter *dvb_adapter) {
drivers/media/dvb/dvb-core/dvb_frontend.h +3 -1
@@ -42,6 +45,8 @@#define I2C_DRIVERID_DVBFE_ALPS_TDMB7 I2C_DRIVERID_EXP2#define I2C_DRIVERID_DVBFE_AT76C651 I2C_DRIVERID_EXP2#define I2C_DRIVERID_DVBFE_CX24110 I2C_DRIVERID_EXP2 +#define I2C_DRIVERID_DVBFE_CX22702 I2C_DRIVERID_EXP2 +#define I2C_DRIVERID_DVBFE_DIB3000MB I2C_DRIVERID_EXP2#define I2C_DRIVERID_DVBFE_DST I2C_DRIVERID_EXP2#define I2C_DRIVERID_DVBFE_DUMMY I2C_DRIVERID_EXP2#define I2C_DRIVERID_DVBFE_L64781 I2C_DRIVERID_EXP2
@@ -102,7 +107,7 @@ struct module *module);extern int -dvb_unregister_frontend_new (int (*ioctl) (struct dvb_frontend *frontend, +dvb_unregister_frontend (int (*ioctl) (struct dvb_frontend *frontend,unsigned int cmd,void *arg),struct dvb_adapter *dvb_adapter);
drivers/media/dvb/frontends/ves1820.c +1 -1
@@ -578,7 +575,7 @@static int detach_client (struct i2c_client *client) {struct ves1820_state *state = (struct ves1820_state *)i2c_get_clientdata (client); -dvb_unregister_frontend_new (ves1820_ioctl, state->dvb); +dvb_unregister_frontend (ves1820_ioctl, state->dvb);device_remove_file (&client->dev, &dev_attr_client_name);i2c_detach_client (client);BUG_ON (state->dvb);
drivers/media/dvb/frontends/ves1x93.c +41 -37
141 lines not on this page · raw message
drivers/media/dvb/ttusb-dec/ttusb_dec.c +1 -1
@@ -1689,7 +1686,7 @@static void ttusb_dec_exit_frontend (struct ttusb_dec *dec) { -dvb_unregister_frontend_new (dec->frontend_ioctl, dec->adapter); +dvb_unregister_frontend (dec->frontend_ioctl, dec->adapter); }static void ttusb_dec_init_filters (struct ttusb_dec *dec)
Re: [PATCH][2.6][14/14] follow saa7146 changes in other drivers
- [V4L] mxb, dpc7146, hexium_orion, hexium_gemini: follow latest changes in saa7146 driver
drivers/media/video/dpc7146.c +7 -3
@@ -79,8 +79,8 @@struct dpc { -struct video_device video_dev; -struct video_device vbi_dev; +struct video_device *video_dev; +struct video_device *vbi_dev;struct i2c_adapter i2c_adapter;struct i2c_client *saa7111a;
@@ -106,7 +106,11 @@video port pins should be enabled here ?! */ saa7146_write (dev,MC1 , (MASK_08 |MASK_24 |MASK_10 |MASK_26 )); -saa7146_i2c_adapter_prepare (dev, &dpc->i2c_adapter,I2C_CLASS_TV_ANALOG ,SAA7146_I2C_BUS_BIT_RATE_480 ); + dpc->i2c_adapter = (struct i2c_adapter ) { + .class =I2C_CLASS_TV_ANALOG , + .name ="dpc7146" , + }; +saa7146_i2c_adapter_prepare (dev, &dpc->i2c_adapter,SAA7146_I2C_BUS_BIT_RATE_480 );if (i2c_add_adapter (&dpc->i2c_adapter) <0 ) {DEB_S (("cannot register i2c-device. skipping.\n" ));kfree (dpc);
drivers/media/video/hexium_gemini.c +7 -2
@@ -78,7 +78,8 @@struct hexium {int type; -struct video_device video_dev; + +struct video_device *video_dev;struct i2c_adapter i2c_adapter;int cur_input;/* current input */
@@ -250,7 +251,11 @@/* enable i2c-port pins */ saa7146_write (dev,MC1 , (MASK_08 |MASK_24 |MASK_10 |MASK_26 )); -saa7146_i2c_adapter_prepare (dev, &hexium->i2c_adapter,I2C_CLASS_TV_ANALOG ,SAA7146_I2C_BUS_BIT_RATE_480 ); + hexium->i2c_adapter = (struct i2c_adapter ) { + .class =I2C_CLASS_TV_ANALOG , + .name ="hexium gemini" , + }; +saa7146_i2c_adapter_prepare (dev, &hexium->i2c_adapter,SAA7146_I2C_BUS_BIT_RATE_480 );if (i2c_add_adapter (&hexium->i2c_adapter) <0 ) {DEB_S (("cannot register i2c-device. skipping.\n" ));kfree (hexium);
drivers/media/video/hexium_orion.c +7 -2
@@ -68,8 +68,9 @@struct hexium {int type; -struct video_device video_dev; +struct video_device *video_dev;struct i2c_adapter i2c_adapter; +int cur_input;/* current input */ };
@@ -237,7 +238,11 @@saa7146_write (dev,DD1_STREAM_B ,0x00000000 );saa7146_write (dev,MC2 , (MASK_09 |MASK_25 |MASK_10 |MASK_26 )); -saa7146_i2c_adapter_prepare (dev, &hexium->i2c_adapter,I2C_CLASS_TV_ANALOG ,SAA7146_I2C_BUS_BIT_RATE_480 ); + hexium->i2c_adapter = (struct i2c_adapter ) { + .class =I2C_CLASS_TV_ANALOG , + .name ="hexium orion" , + }; +saa7146_i2c_adapter_prepare (dev, &hexium->i2c_adapter,SAA7146_I2C_BUS_BIT_RATE_480 );if (i2c_add_adapter (&hexium->i2c_adapter) <0 ) {DEB_S (("cannot register i2c-device. skipping.\n" ));kfree (hexium);
drivers/media/video/mxb.c +8 -3
@@ -128,8 +128,8 @@struct mxb { -struct video_device video_dev; -struct video_device vbi_dev; +struct video_device *video_dev; +struct video_device *vbi_dev;struct i2c_adapter i2c_adapter;
@@ -183,7 +183,12 @@ }memset (mxb,0x0 ,sizeof (struct mxb )); -saa7146_i2c_adapter_prepare (dev, &mxb->i2c_adapter,I2C_CLASS_TV_ANALOG ,SAA7146_I2C_BUS_BIT_RATE_480 ); + mxb->i2c_adapter = (struct i2c_adapter ) { + .class =I2C_CLASS_TV_ANALOG , + .name ="mxb" , + }; + +saa7146_i2c_adapter_prepare (dev, &mxb->i2c_adapter,SAA7146_I2C_BUS_BIT_RATE_480 );if (i2c_add_adapter (&mxb->i2c_adapter) <0 ) {DEB_S (("cannot register i2c-device. skipping.\n" ));kfree (mxb);
Re: [PATCH][2.6][4/14] dvb core update
In reply to Michael HunoldOn Fri, 17 Sep 2004, Michael Hunold wrote:
FYI '//' are now (since 1998) 'C' comments as well as 'C++'
Cheers,
Dick Johnson
Penguin : Linux version 2.4.26 on an i686 machine (5570.56 BogoMips).
Note 96.31% of all statistics are fiction.
Re: [PATCH][2.6][4/14] dvb core update
In reply to Jesper JuhlQuoted 3 lines · Jesper Juhl
Besides, didn't C99 make C++ style comments valid for C code as well? Does CodingStyle have any oppinion on this?
We've allowed C++ comments for a longish time as far as I can tell. They are very common, all over the tree according to a quick grep. Admittedly they are more common in certain driver setups than in "general code", but I don't think there is really any reason (other than maintainer preferences) to convert one into the other.
Linus
Re: [PATCH][2.6][4/14] dvb core update
In reply to Michael HunoldQuoted 8 lines · Michael Hunold
Date: Fri, 17 Sep 2004 16:27:45 +0200
From: Michael Hunold <[email protected]>
To: Linus Torvalds <[email protected]>
Cc: Linux Kernel Mailing List <[email protected]>,
Andrew Morton <[email protected]>
Subject: Re: [PATCH][2.6][4/14] dvb core update
[...]
Quoted 1 line
- [DVB] convert C++ comments to C comments
It seems you missed a few, and the patch adds a few itself :
Quoted 2 lines
drivers/media/dvb/dvb-core/dvb_ca_en50221.c +0
-0@@ -662,19 +670,9 @@// sanity check
[...]
Quoted 1 line
drivers/media/dvb/dvb-core/dvb_ca_en50221.c +1
-0+// no need to poll if the CAM supports IRQs
[...]
Quoted 1 line
drivers/media/dvb/dvb-core/dvb_ca_en50221.c +1
-0+// poll mode
[...]
include/linux/dvb/frontend.h line 67
Quoted 3 lines
include/linux/dvb/frontend.h +0
-0FE_NEEDS_BENDING =0x20000000 ,// frontend requires frequency bending FE_CAN_RECOVER =0x40000000 ,// frontend can recover from a cable unplug automatically FE_CAN_MUTE_TS =0x80000000 // frontend can stop spurious TS data output
And I'll bet there are probably more if I could be bothered to check the actual files.
Besides, didn't C99 make C++ style comments valid for C code as well? Does CodingStyle have any oppinion on this?
--
Jesper Juhl <[email protected]>
Re: [PATCH][2.6][4/14] dvb core update
Quoted 2 lines · Jesper Juhl
And I'll bet there are probably more if I could be bothered to check the actual files.
Lots of drivers use C++^WBCPL comments (C++ just borrowed them)
Quoted 1 line
Besides, didn't C99 make C++ style comments valid for C code as well?
Yes and this leads to such fun as
x = 4 //**/
-1;
if(x == 3)
printf("New C compiler\n");Quoted 3 lines · Michael Hunold
here comes a patchset consisting of 14 patches bringing the in-kernel DVB subsystem in sync with the LinuxTV.org CVS driver.
I'm getting lots of rejects from these. At the fifth patch I gave up. The rejects appear to be against stock 2.6.9-rc2.
Please regenerate these patches and double-check that they apply to latest -linus tree. Or against next -mm if they are dependent upon Gerd's patches:
v4l-msp3400-cleanup.patch
v4l-tuner-update.patch
v4l-bttv-update.patch
v4l-dvb-cx88-driver-update.patch
Re: [PATCH][2.6][12.1/14] DVB: add kernel message classifiers
In reply to Michael HunoldHello Michael!
Quoted 4 lines · Michael Hunold
- [DVB] av7110: convert
MODULE_PARM()tomodule_param(), replace home-brewn waiting stuff in osd code withwait_event_interruptible_timeout()
- [DVB] av7110, budget: usemsleep()instead ofmy_wait(), thanks to Kernel Janitors/Nishanth Aravamudan <[email protected]>Signed-off-by Michael Hunold <[email protected]>
Could you please apply the following patch on top, which adds kernel message classifiers to printk()-calls in av7110_av.c
If you don't to apply the whole patch, please at least remove those two printk() calls in av7110_ioctl() line 267 and 270, because on my Siemens DVB-C 1.6 they are printed every second and fill up syslog! (BTW: Stereo detection never worked for me)
drivers/media/dvb/ttpci/av7110_v4l.c renamed from drivers/media/dvb/ttpci/av7110_v4l.c~ +12 -12
@@ -51,7 +51,7 @@ int msp_writereg(struct av7110 *av7110,struct i2c_msg msgs = { .flags =0 , .addr =0x40 , .len =5 , .buf = msg };if (i2c_transfer (&av7110->i2c_adap, &msgs,1 ) !=1 ) { -printk ("av7110(%d): %s(%u = %u) failed\n" , +printk (KERN_ERR "av7110(%d): %s(%u = %u) failed\n" , av7110->dvb_adapter->num, __FUNCTION__, reg, val);return -EIO ; }
@@ -68,7 +68,7 @@ int msp_readreg(struct av7110 *av7110, u };if (i2c_transfer (&av7110->i2c_adap, &msgs[0 ],2 ) !=2 ) { -printk ("av7110(%d): %s(%u) failed\n" , +printk (KERN_ERR "av7110(%d): %s(%u) failed\n" , av7110->dvb_adapter->num, __FUNCTION__, reg);return -EIO ; }
@@ -194,7 +194,7 @@ int av7110_dvb_c_switch(struct saa7146_f source =SAA7146_HPS_SOURCE_PORT_B ; sync =SAA7146_HPS_SYNC_PORT_B ;memcpy (standard, analog_standard,sizeof (struct saa7146_standard ) *2 ); -printk ("av7110: switching to analog TV\n" ); +printk (KERN_INFO "av7110: switching to analog TV\n" );msp_writereg (av7110,MSP_WR_DSP ,0x0008 ,0x0000 );// loudspeaker source msp_writereg (av7110,MSP_WR_DSP ,0x0009 ,0x0000 );// headphone source msp_writereg (av7110,MSP_WR_DSP ,0x000a ,0x0000 );// SCART 1 source
@@ -207,7 +207,7 @@ int av7110_dvb_c_switch(struct saa7146_f source =SAA7146_HPS_SOURCE_PORT_A ; sync =SAA7146_HPS_SYNC_PORT_A ;memcpy (standard, dvb_standard,sizeof (struct saa7146_standard ) *2 ); -printk ("av7110: switching DVB mode\n" ); +printk (KERN_INFO "av7110: switching DVB mode\n" );msp_writereg (av7110,MSP_WR_DSP ,0x0008 ,0x0220 );// loudspeaker source msp_writereg (av7110,MSP_WR_DSP ,0x0009 ,0x0220 );// headphone source msp_writereg (av7110,MSP_WR_DSP ,0x000a ,0x0220 );// SCART 1 source
@@ -218,10 +218,10 @@ int av7110_dvb_c_switch(struct saa7146_f/* hmm, this does not do anything!? */ if (av7110_fw_cmd (av7110,COMTYPE_AUDIODAC , ADSwitch,1 , adswitch)) -printk ("ADSwitch error\n" ); +printk (KERN_ERROR "ADSwitch error\n" );if (ves1820_writereg (dev,0x0f , band)) -printk ("setting band in demodulator failed.\n" ); +printk (KERN_ERROR "setting band in demodulator failed.\n" );saa7146_set_hps_source_and_sync (dev, source, sync);if (vv->ov_suspend !=NULL ) {
@@ -264,10 +264,10 @@ int av7110_ioctl(struct saa7146_fh *fh,// FIXME: standard / stereo detection is still broken msp_readreg (av7110,MSP_RD_DEM ,0x007e , &stereo_det); -printk ("VIDIOC_G_TUNER: msp3400 TV standard detection: 0x%04x\n" , stereo_det); +printk (KERN_DEBUG "VIDIOC_G_TUNER: msp3400 TV standard detection: 0x%04x\n" , stereo_det);msp_readreg (av7110,MSP_RD_DSP ,0x0018 , &stereo_det); -printk ("VIDIOC_G_TUNER: msp3400 stereo detection: 0x%04x\n" , stereo_det); +printk (KERN_DEBUG "VIDIOC_G_TUNER: msp3400 stereo detection: 0x%04x\n" , stereo_det); stereo = (s8)(stereo_det >>8 );if (stereo >0x10 ) {/* stereo */
@@ -418,7 +418,7 @@ printk("VIDIOC_G_TUNER: msp3400 TV standbreak ; }default : -printk ("no such ioctl\n" ); +printk (KERN_ERR "no such ioctl\n" );return -ENOIOCTLCMD ; }return 0 ;
@@ -512,13 +512,13 @@ int av7110_init_analog_module(struct av7 || i2c_writereg(av7110, 0x80, 0x0, 0) != 1)return -ENODEV ; -printk ("av7110(%d): DVB-C analog module detected, initializing MSP3400\n" , +printk (KERN_INFO "av7110(%d): DVB-C analog module detected, initializing MSP3400\n" , av7110->dvb_adapter->num); av7110->adac_type =DVB_ADAC_MSP ;msleep (100 );// the probing above resets the msp... msp_readreg (av7110,MSP_RD_DSP ,0x001e , &version1);msp_readreg (av7110,MSP_RD_DSP ,0x001f , &version2); -printk ("av7110(%d): MSP3400 version 0x%04x 0x%04x\n" , +printk (KERN_INFO "av7110(%d): MSP3400 version 0x%04x 0x%04x\n" , av7110->dvb_adapter->num, version1, version2);msp_writereg (av7110,MSP_WR_DSP ,0x0013 ,0x0c00 );msp_writereg (av7110,MSP_WR_DSP ,0x0000 ,0x7f00 );// loudspeaker + headphone
@@ -537,7 +537,7 @@ int av7110_init_analog_module(struct av7/* init the saa7113 */ while (*i !=0xff ) {if (i2c_writereg (av7110,0x48 , i[0 ], i[1 ]) !=1 ) { -printk ("av7110(%d): saa7113 initialization failed" , +printk (KERN_ERR "av7110(%d): saa7113 initialization failed" , av7110->dvb_adapter->num);break ; }
Signature · 3 lines
/ / (_)__ __ ____ __ Philipp Hahn / /__/ / _ \/ // /\ \/ / /____/_/_//_/\_,_/ /_/\_\ [email protected]
Hi,
Quoted 2 lines · Andrew Morton
I'm getting lots of rejects from these. At the fifth patch I gave up. The rejects appear to be against stock 2.6.9-rc2.
The patchset was against 2.6.8(.1), the rejects come from the janitor cleanups for msleep() in the saa7146 driver and from the sys_read()/errno mess in the frontend drivers, which loaded the firmware directly.
Quoted 3 lines
Please regenerate these patches and double-check that they apply to latest -linus tree. Or against next -mm if they are dependent upon Gerd's patches:
I'll send you a new patchset against 2.6.9-rc2-mm1 in private right now.
The patches have been adopted or re-generated to fit against your
latest tree, so I don't post them in public any more.
CU
Michael.
Re: [PATCH][2.6][12.1/14] DVB: add kernel message classifiers
In reply to Philipp Matthias HahnHi,
Quoted 7 lines
Could you please apply the following patch on top, which adds kernel message classifiers to printk()-calls in
av7110_av.cIf you don't to apply the whole patch, please at least remove those two
printk()calls inav7110_ioctl()line 267 and 270, because on my Siemens DVB-C 1.6 they are printed every second and fill up syslog! (BTW: Stereo detection never worked for me)
I've taken the time and reworked the debug message logic in the av7110 driver. It depended on the saa7146 driver and used horrible macros anyway, so I converted them alltogether.
I'll try to get this into 2.6.9 as well.
CU
Michael.