diff options
author | Michael Hunold <devnull@localhost> | 2002-12-17 14:58:23 +0000 |
---|---|---|
committer | Michael Hunold <devnull@localhost> | 2002-12-17 14:58:23 +0000 |
commit | e6e1f4acdf9a3437a50147206b12c0fdef4e6a90 (patch) | |
tree | b0615d3a6f43e3d2368a432e6d3edf6dfaa3a4e8 /linux/drivers/media | |
parent | 1f0cdfa2a5aba72c3c69340a21ff9e8e9afd3fe1 (diff) | |
download | mediapointer-dvb-s2-e6e1f4acdf9a3437a50147206b12c0fdef4e6a90.tar.gz mediapointer-dvb-s2-e6e1f4acdf9a3437a50147206b12c0fdef4e6a90.tar.bz2 |
Remove old saa7146 driver core used for the av7110.
Diffstat (limited to 'linux/drivers/media')
-rw-r--r-- | linux/drivers/media/dvb/av7110/saa7146.c | 1662 | ||||
-rw-r--r-- | linux/drivers/media/dvb/av7110/saa7146_core.c | 967 | ||||
-rw-r--r-- | linux/drivers/media/dvb/av7110/saa7146_core.h | 111 | ||||
-rw-r--r-- | linux/drivers/media/dvb/av7110/saa7146_defs.h | 382 | ||||
-rw-r--r-- | linux/drivers/media/dvb/av7110/saa7146_v4l.c | 501 | ||||
-rw-r--r-- | linux/drivers/media/dvb/av7110/saa7146_v4l.h | 32 |
6 files changed, 0 insertions, 3655 deletions
diff --git a/linux/drivers/media/dvb/av7110/saa7146.c b/linux/drivers/media/dvb/av7110/saa7146.c deleted file mode 100644 index 93fa074ad..000000000 --- a/linux/drivers/media/dvb/av7110/saa7146.c +++ /dev/null @@ -1,1662 +0,0 @@ -/* - the api- and os-independet parts of the saa7146 device driver - - Copyright (C) 1998,1999 Michael Hunold <michael@mihu.de> - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include "saa7146_defs.h" - -#define TRUNC(val,max) ((val) < (max) ? (val) : (max)) - -#ifdef __COMPILE_SAA7146__ - -struct saa7146_modes_constants - modes_constants[] = { - { V_OFFSET_PAL, V_FIELD_PAL, V_ACTIVE_LINES_PAL, - H_OFFSET_PAL, H_PIXELS_PAL, H_PIXELS_PAL+1, - V_ACTIVE_LINES_PAL, 1024 }, /* PAL values */ - { V_OFFSET_NTSC, V_FIELD_NTSC, V_ACTIVE_LINES_NTSC, - H_OFFSET_NTSC, H_PIXELS_NTSC, H_PIXELS_NTSC+1, - V_ACTIVE_LINES_NTSC, 1024 }, /* NTSC values */ - { 0,0,0,0,0,0,0,0 }, /* secam values */ - { 0,288,576, - 0,188*4,188*4+1, - 288,188*4 } /* TS values */ -}; - -/* ----------------------------------------------------------------------------------------- - helper functions for the calculation of the horizontal- and vertical scaling registers, - clip-format-register etc ... - these functions take pointers to the (most-likely read-out original-values) and manipulate - them according to the requested new scaling parameters. - ----------------------------------------------------------------------------------------- */ - -/* hps_coeff used for CXY and CXUV; scale 1/1 -> scale 1/64 */ -struct { - u16 hps_coeff; - u16 weight_sum; -} hps_h_coeff_tab [] = { - {0x00, 2}, {0x02, 4}, {0x00, 4}, {0x06, 8}, {0x02, 8}, - {0x08, 8}, {0x00, 8}, {0x1E, 16}, {0x0E, 8}, {0x26, 8}, - {0x06, 8}, {0x42, 8}, {0x02, 8}, {0x80, 8}, {0x00, 8}, - {0xFE, 16}, {0xFE, 8}, {0x7E, 8}, {0x7E, 8}, {0x3E, 8}, - {0x3E, 8}, {0x1E, 8}, {0x1E, 8}, {0x0E, 8}, {0x0E, 8}, - {0x06, 8}, {0x06, 8}, {0x02, 8}, {0x02, 8}, {0x00, 8}, - {0x00, 8}, {0xFE, 16}, {0xFE, 8}, {0xFE, 8}, {0xFE, 8}, - {0xFE, 8}, {0xFE, 8}, {0xFE, 8}, {0xFE, 8}, {0xFE, 8}, - {0xFE, 8}, {0xFE, 8}, {0xFE, 8}, {0xFE, 8}, {0xFE, 8}, - {0xFE, 8}, {0xFE, 8}, {0xFE, 8}, {0xFE, 8}, {0x7E, 8}, - {0x7E, 8}, {0x3E, 8}, {0x3E, 8}, {0x1E, 8}, {0x1E, 8}, - {0x0E, 8}, {0x0E, 8}, {0x06, 8}, {0x06, 8}, {0x02, 8}, - {0x02, 8}, {0x00, 8}, {0x00, 8}, {0xFE, 16} -}; - -/* table of attenuation values for horizontal scaling */ -u8 h_attenuation[] = { 1, 2, 4, 8, 2, 4, 8, 16, 0}; - -int calculate_h_scale_registers(struct saa7146* saa, u32 in_x, u32 out_x, int flip_lr, u32* hps_ctrl, u32* hps_v_gain, u32* hps_h_prescale, u32* hps_h_scale) -{ - /* horizontal prescaler */ - u32 dcgx = 0, xpsc = 0, xacm = 0, cxy = 0, cxuv = 0; - /* horizontal scaler */ - u32 xim = 0, xp = 0, xsci =0; - /* vertical scale & gain */ - u32 pfuv = 0; - /* helper variables */ - u32 h_atten = 0, i = 0; - - if ( 0 == out_x ) { - printk("saa7146: ==> calculate_h_scale_registers: invalid value (=0).\n"); - return -EINVAL; - } - - /* mask out vanity-bit */ - *hps_ctrl &= ~MASK_29; - - /* calculate prescale-(xspc)-value: [n .. 1/2) : 1 - [1/2 .. 1/3) : 2 - [1/3 .. 1/4) : 3 - ... */ - if (in_x > out_x) { - xpsc = in_x / out_x; - } else { - /* zooming */ - xpsc = 1; - } - - /* if flip_lr-bit is set, number of pixels after horizontal prescaling must be < 384 */ - if ( 0 != flip_lr ) { - /* set vanity bit */ - *hps_ctrl |= MASK_29; - - while (in_x / xpsc >= 384 ) - xpsc++; - } - /* if zooming is wanted, number of pixels after horizontal prescaling must be < 768 */ - else { - while ( in_x / xpsc >= 768 ) - xpsc++; - } - - /* maximum prescale is 64 (p.69) */ - if ( xpsc > 64 ) - xpsc = 64; - - /* keep xacm clear*/ - xacm = 0; - - /* set horizontal filter parameters (CXY = CXUV) */ - cxy = hps_h_coeff_tab[TRUNC(xpsc - 1, 63)].hps_coeff; - cxuv = cxy; - - /* calculate and set horizontal fine scale (xsci) */ - - /* bypass the horizontal scaler ? */ - if ( (in_x == out_x) && ( 1 == xpsc ) ) - xsci = 0x400; - else - xsci = ( (1024 * in_x) / (out_x * xpsc) ) + xpsc; - - /* set start phase for horizontal fine scale (xp) to 0 */ - xp = 0; - - /* set xim, if we bypass the horizontal scaler */ - if ( 0x400 == xsci ) - xim = 1; - else - xim = 0; - - /* if the prescaler is bypassed, enable horizontal accumulation mode (xacm) - and clear dcgx */ - if( 1 == xpsc ) { - xacm = 1; - dcgx = 0; - } else { - xacm = 0; - /* get best match in the table of attenuations for horizontal scaling */ - h_atten = hps_h_coeff_tab[TRUNC(xpsc - 1, 63)].weight_sum; - - for (i = 0; h_attenuation[i] != 0; i++) { - if (h_attenuation[i] >= h_atten) - break; - } - - dcgx = i; - } - - /* the horizontal scaling increment controls the UV filter to reduce the bandwith to - improve the display quality, so set it ... */ - if ( xsci == 0x400) - pfuv = 0x00; - else if ( xsci < 0x600) - pfuv = 0x01; - else if ( xsci < 0x680) - pfuv = 0x11; - else if ( xsci < 0x700) - pfuv = 0x22; - else - pfuv = 0x33; - - - *hps_v_gain &= MASK_W0|MASK_B2; - *hps_v_gain |= (pfuv << 24); - - *hps_h_scale &= ~(MASK_W1 | 0xf000); - *hps_h_scale |= (xim << 31) | (xp << 24) | (xsci << 12); - - *hps_h_prescale |= (dcgx << 27) | ((xpsc-1) << 18) | (xacm << 17) | (cxy << 8) | (cxuv << 0); - - return 0; -} - -struct { - u16 hps_coeff; - u16 weight_sum; -} hps_v_coeff_tab [] = { - {0x0100, 2}, {0x0102, 4}, {0x0300, 4}, {0x0106, 8}, - {0x0502, 8}, {0x0708, 8}, {0x0F00, 8}, {0x011E, 16}, - {0x110E, 16}, {0x1926, 16}, {0x3906, 16}, {0x3D42, 16}, - {0x7D02, 16}, {0x7F80, 16}, {0xFF00, 16}, {0x01FE, 32}, - {0x01FE, 32}, {0x817E, 32}, {0x817E, 32}, {0xC13E, 32}, - {0xC13E, 32}, {0xE11E, 32}, {0xE11E, 32}, {0xF10E, 32}, - {0xF10E, 32}, {0xF906, 32}, {0xF906, 32}, {0xFD02, 32}, - {0xFD02, 32}, {0xFF00, 32}, {0xFF00, 32}, {0x01FE, 64}, - {0x01FE, 64}, {0x01FE, 64}, {0x01FE, 64}, {0x01FE, 64}, - {0x01FE, 64}, {0x01FE, 64}, {0x01FE, 64}, {0x01FE, 64}, - {0x01FE, 64}, {0x01FE, 64}, {0x01FE, 64}, {0x01FE, 64}, - {0x01FE, 64}, {0x01FE, 64}, {0x01FE, 64}, {0x01FE, 64}, - {0x01FE, 64}, {0x817E, 64}, {0x817E, 64}, {0xC13E, 64}, - {0xC13E, 64}, {0xE11E, 64}, {0xE11E, 64}, {0xF10E, 64}, - {0xF10E, 64}, {0xF906, 64}, {0xF906, 64}, {0xFD02, 64}, - {0xFD02, 64}, {0xFF00, 64}, {0xFF00, 64}, {0x01FE, 128} -}; - -/* table of attenuation values for vertical scaling */ -u16 v_attenuation[] = { 2, 4, 8, 16, 32, 64, 128, 256, 0}; - -int calculate_v_scale_registers(struct saa7146* saa, u32 in_y, u32 out_y, u32* hps_v_scale, u32* hps_v_gain) -{ - u32 yacm = 0, ysci = 0, yacl = 0, ypo = 0, ype = 0; /* vertical scaling */ - u32 dcgy = 0, cya_cyb = 0; /* vertical scale & gain */ - - u32 v_atten = 0, i = 0; /* helper variables */ - - /* error, if vertical zooming */ - if ( in_y < out_y ) { - printk("saa7146: ==> calculate_v_scale_registers: we cannot do vertical zooming.\n"); - return -EINVAL; - } - - /* linear phase interpolation may be used if scaling is between 1 and 1/2 - or scaling is between 1/2 and 1/4 (if interlace is set; see below) */ - if( ((2*out_y) >= in_y) || (((4*out_y) >= in_y) && saa->interlace != 0)) { - - /* convention: if scaling is between 1/2 and 1/4 we only use - the even lines, the odd lines get discarded (see function move_to) - if interlace is set */ - if( saa->interlace != 0 && (out_y*4) >= in_y && (out_y*2) <= in_y) - out_y *= 2; - - yacm = 0; - yacl = 0; - cya_cyb = 0x00ff; - - /* calculate scaling increment */ - if ( in_y > out_y ) - ysci = ((1024 * in_y) / (out_y + 1)) - 1024; - else - ysci = 0; - - dcgy = 0; - - /* calculate ype and ypo */ - if (saa->interlace !=0) { - - /* Special case for interlaced input */ - - /* See Philips SAA7146A Product Spec (page 75): */ - /* "For interlaced input, ype and ypo is defiend as */ - /* YPeven= 3/2 x YPodd (line 1 = odd)" */ - /* */ - /* It looks like the spec is wrong! */ - /* The ad hoc values below works fine for a target */ - /* window height of 480 (vertical scale = 1/1) NTSC. */ - /* PLI: December 27, 2000. */ - ypo=64; - ype=0; - } else { - ype = ysci / 16; - ypo = ype + (ysci / 64); - } - } - else { - yacm = 1; - - /* calculate scaling increment */ - ysci = (((10 * 1024 * (in_y - out_y - 1)) / in_y) + 9) / 10; - - /* calculate ype and ypo */ - ypo = ype = ((ysci + 15) / 16); - - /* the sequence length interval (yacl) has to be set according - to the prescale value, e.g. [n .. 1/2) : 0 - [1/2 .. 1/3) : 1 - [1/3 .. 1/4) : 2 - ... */ - if ( ysci < 512) { - yacl = 0; - } - else { - yacl = ( ysci / (1024 - ysci) ); - } - - /* get filter coefficients for cya, cyb from table hps_v_coeff_tab */ - cya_cyb = hps_v_coeff_tab[TRUNC(yacl, 63)].hps_coeff; - - /* get best match in the table of attenuations for vertical scaling */ - v_atten = hps_v_coeff_tab[TRUNC(yacl, 63)].weight_sum; - - for (i = 0; v_attenuation[i] != 0; i++) { - if (v_attenuation[i] >= v_atten) - break; - } - - dcgy = i; - } - - /* ypo and ype swapped in spec ? */ - *hps_v_scale |= (yacm << 31) | (ysci << 21) | (yacl << 15) | (ypo << 8 ) | (ype << 1); - - *hps_v_gain &= ~(MASK_W0|MASK_B2); - *hps_v_gain |= (dcgy << 16) | (cya_cyb << 0); - - return 0; -} - -void calculate_hxo_hyo_and_sources(struct saa7146* saa, int port_sel, int sync_sel, u32* hps_h_scale, u32* hps_ctrl) -{ - u32 hyo = 0, hxo = 0; - - hyo = modes_constants[saa->mode].v_offset; - hxo = modes_constants[saa->mode].h_offset; - - *hps_h_scale &= ~(MASK_B0 | 0xf00); - *hps_ctrl &= ~(MASK_W0 | MASK_B2 | MASK_30 | MASK_31 | MASK_28); - - *hps_h_scale |= (hxo << 0); - *hps_ctrl |= (hyo << 12); - - *hps_ctrl |= ( port_sel == 0 ? 0x0 : MASK_30); - *hps_ctrl |= ( sync_sel == 0 ? 0x0 : MASK_28); -} - -void calculate_output_format_register(struct saa7146* saa, u16 palette, u32* clip_format) -{ - /* clear out the necessary bits */ - *clip_format &= 0x0000ffff; - /* set these bits new */ - *clip_format |= (( ((palette&0xf00)>>8) << 30) | ((palette&0x00f) << 24) | (((palette&0x0f0)>>4) << 16)); -} - -void calculate_bcs_ctrl_register(struct saa7146 *saa, u32 brightness, u32 contrast, u32 colour, u32 *bcs_ctrl) -{ - *bcs_ctrl = ((brightness << 24) | (contrast << 16) | (colour << 0)); -} - - -int calculate_video_dma1_grab(struct saa7146* saa, int frame, struct saa7146_video_dma* vdma1) -{ - int depth = 0; - - switch(saa->grab_format[frame]) { - case YUV422_COMPOSED: - case RGB15_COMPOSED: - case RGB16_COMPOSED: - depth = 2; - break; - case RGB24_COMPOSED: - depth = 3; - break; - default: - depth = 4; - break; - } - - vdma1->pitch = saa->grab_width[frame]*depth*2; - vdma1->base_even = 0; - vdma1->base_odd = vdma1->base_even + (vdma1->pitch/2); - vdma1->prot_addr = (saa->grab_width[frame]*saa->grab_height[frame]*depth)-1; - vdma1->num_line_byte = ((modes_constants[saa->mode].v_field<<16) + modes_constants[saa->mode].h_pixels); - vdma1->base_page = virt_to_bus(saa->page_table[frame]) | ME1; - - /* convention: if scaling is between 1/2 and 1/4 we only use - the even lines, the odd lines get discarded (see vertical scaling) */ - if( saa->interlace != 0 && saa->grab_height[frame]*4 >= modes_constants[saa->mode].v_calc && saa->grab_height[frame]*2 <= modes_constants[saa->mode].v_calc) { - vdma1->base_odd = vdma1->prot_addr; - vdma1->pitch /= 2; - } - - return 0; -} - -/* ---------------------------------------------*/ -/* position of overlay-window */ -/* ---------------------------------------------*/ - -/* calculate the new memory offsets for a desired position */ -int move_to(struct saa7146* saa, int w_x, int w_y, int w_height, int b_width, int b_depth, int b_bpl, u32 base, int td_flip) -{ - struct saa7146_video_dma vdma1; - - if( w_y < 0 || w_height <= 0 || b_depth <= 0 || b_bpl <= 0 || base == 0 ) { - printk("saa7146: ==> calculate_video_dma1_overlay: illegal values: y: %d h: %d d: %d b: %d base: %d\n",w_y ,w_height,b_depth,b_bpl,base); - return -EINVAL; - } - - /* calculate memory offsets for picture, look if we shall top-down-flip */ - vdma1.pitch = 2*b_bpl; - if ( 0 == td_flip ) { - vdma1.prot_addr = (u32)base + ((w_height+w_y+1)*b_width*(b_depth/4)); - vdma1.base_even = (u32)base + (w_y * (vdma1.pitch/2)) + (w_x * (b_depth / 8)); - vdma1.base_odd = vdma1.base_even + (vdma1.pitch / 2); - } - else { - vdma1.prot_addr = (u32)base + (w_y * (vdma1.pitch/2)); - vdma1.base_even = (u32)base + ((w_y+w_height) * (vdma1.pitch/2)) + (w_x * (b_depth / 8)); - vdma1.base_odd = vdma1.base_even + (vdma1.pitch / 2); - vdma1.pitch *= -1; - } - - /* convention: if scaling is between 1/2 and 1/4 we only use - the even lines, the odd lines get discarded (see vertical scaling) */ - if( saa->interlace != 0 && w_height*4 >= modes_constants[saa->mode].v_calc && w_height*2 <= modes_constants[saa->mode].v_calc) { - vdma1.base_odd = vdma1.prot_addr; - vdma1.pitch /= 2; - } - - vdma1.base_page = 0; - vdma1.num_line_byte = (modes_constants[saa->mode].v_field<<16)+modes_constants[saa->mode].h_pixels; - - saa7146_write(saa->mem, BASE_EVEN1, vdma1.base_even); - saa7146_write(saa->mem, BASE_ODD1, vdma1.base_odd); - saa7146_write(saa->mem, PROT_ADDR1, vdma1.prot_addr); - saa7146_write(saa->mem, BASE_PAGE1, vdma1.base_page); - saa7146_write(saa->mem, PITCH1, vdma1.pitch); - saa7146_write(saa->mem, NUM_LINE_BYTE1, vdma1.num_line_byte); - - /* update the video dma 1 registers */ - saa7146_write(saa->mem, MC2, (MASK_02 | MASK_18)); - - return 0; - -} - -/* ---------------------------------------------*/ -/* size of window (overlay) */ -/* ---------------------------------------------*/ - -int set_window(struct saa7146* saa, int width, int height, int flip_lr, int port_sel, int sync_sel) -{ - u32 hps_v_scale = 0, hps_v_gain = 0, hps_ctrl = 0, hps_h_prescale = 0, hps_h_scale = 0; - - /* set vertical scale according to selected mode: 0 = PAL, 1 = NTSC */ - hps_v_scale = 0; /* all bits get set by the function-call */ - hps_v_gain = 0; /* fixme: saa7146_read(saa->mem, HPS_V_GAIN);*/ - calculate_v_scale_registers(saa, modes_constants[saa->mode].v_calc, height, &hps_v_scale, &hps_v_gain); - - /* set horizontal scale according to selected mode: 0 = PAL, 1 = NTSC */ - hps_ctrl = 0; - hps_h_prescale = 0; /* all bits get set in the function */ - hps_h_scale = 0; - calculate_h_scale_registers(saa, modes_constants[saa->mode].h_calc, width, 0, &hps_ctrl, &hps_v_gain, &hps_h_prescale, &hps_h_scale); - - /* set hyo and hxo */ - calculate_hxo_hyo_and_sources(saa, port_sel, sync_sel, &hps_h_scale, &hps_ctrl); - - /* write out new register contents */ - saa7146_write(saa->mem, HPS_V_SCALE, hps_v_scale); - saa7146_write(saa->mem, HPS_V_GAIN, hps_v_gain); - saa7146_write(saa->mem, HPS_CTRL, hps_ctrl); - saa7146_write(saa->mem, HPS_H_PRESCALE,hps_h_prescale); - saa7146_write(saa->mem, HPS_H_SCALE, hps_h_scale); - - /* upload shadow-ram registers */ - saa7146_write( saa->mem, MC2, (MASK_05 | MASK_06 | MASK_21 | MASK_22) ); - -/* - printk("w:%d,h:%d\n",width,height); -*/ - return 0; - -} - -void set_output_format(struct saa7146* saa, u16 palette) -{ - u32 clip_format = saa7146_read(saa->mem, CLIP_FORMAT_CTRL); - - dprintk("saa7146: ==> set_output_format: pal:0x%03x\n",palette); - - /* call helper function */ - calculate_output_format_register(saa,palette,&clip_format); - dprintk("saa7146: ==> set_output_format: 0x%08x\n",clip_format); - - /* update the hps registers */ - saa7146_write(saa->mem, CLIP_FORMAT_CTRL, clip_format); - saa7146_write(saa->mem, MC2, (MASK_05 | MASK_21)); -} - -void set_picture_prop(struct saa7146 *saa, u32 brightness, u32 contrast, u32 colour) -{ - u32 bcs_ctrl = 0; - - calculate_bcs_ctrl_register(saa, brightness, contrast, colour, &bcs_ctrl); - saa7146_write(saa->mem, BCS_CTRL, bcs_ctrl); - - /* update the bcs register */ - saa7146_write(saa->mem, MC2, (MASK_06 | MASK_22)); -} - -/* ---------------------------------------------*/ -/* overlay enable/disable */ -/* ---------------------------------------------*/ - -/* enable(1) / disable(0) video */ -void video_setmode(struct saa7146* saa, int v) -{ - hprintk("saa7146: ==> video_setmode; m:%d\n",v); - - /* disable ? */ - if(v==0) { - /* disable video dma1 */ - saa7146_write(saa->mem, MC1, MASK_22); - } else {/* or enable ? */ - /* fixme: enable video */ - saa7146_write(saa->mem, MC1, (MASK_06 | MASK_22)); - } -} - -/* ----------------------------------------------------- - common grabbing-functions. if you have some simple - saa7146-based frame-grabber you can most likely call - these. they do all the revision-dependend stuff and - do rps/irq-based grabbing for you. - -----------------------------------------------------*/ - -/* this function initializes the rps for the next grab for any "old" - saa7146s (= revision 0). it assumes that the rps is *not* running - when it gets called. */ -int init_rps0_rev0(struct saa7146* saa, int frame, int irq_call) -{ - struct saa7146_video_dma vdma1; - u32 hps_v_scale = 0, hps_v_gain = 0, hps_ctrl = 0, hps_h_prescale = 0, hps_h_scale = 0; - u32 clip_format = 0; /* this can be 0, since we don't do clipping */ - u32 bcs_ctrl = 0; - - int count = 0; - -/* these static values are used to remember the last "programming" of the rps. - if the height, width and format of the grab has not changed (which is very likely - when some streaming capture is done) the reprogramming overhead can be minimized */ -static int last_height = 0; -static int last_width = 0; -static int last_format = 0; -static int last_port = 0; -static int last_frame = -1; - - /* write the address of the rps-program */ - saa7146_write(saa->mem, RPS_ADDR0, virt_to_bus(&saa->rps0[ 0])); - - /* let's check if we can re-use something of the last grabbing process */ - if ( saa->grab_height[frame] != last_height - || saa->grab_width[frame] != last_width - || saa->grab_port[frame] != last_port - || saa->grab_format[frame] != last_format ) { - - /* nope, we have to start from the beginning */ - calculate_video_dma1_grab(saa, frame, &vdma1); - calculate_v_scale_registers(saa, modes_constants[saa->mode].v_calc, saa->grab_height[frame], &hps_v_scale, &hps_v_gain); - calculate_h_scale_registers(saa, modes_constants[saa->mode].h_calc, saa->grab_width[frame], 0, &hps_ctrl, &hps_v_gain, &hps_h_prescale, &hps_h_scale); - calculate_hxo_hyo_and_sources(saa, saa->grab_port[frame], saa->grab_port[frame], &hps_h_scale, &hps_ctrl); - calculate_output_format_register(saa,saa->grab_format[frame],&clip_format); - calculate_bcs_ctrl_register(saa, 0x80, 0x40, 0x40, &bcs_ctrl); - - count = 0; - - saa->rps0[ count++ ] = cpu_to_le32(CMD_WR_REG_MASK | (MC1/4)); /* turn off video-dma1 and dma2 (clipping)*/ - saa->rps0[ count++ ] = cpu_to_le32(MASK_06 | MASK_22 | MASK_05 | MASK_21); /* => mask */ - saa->rps0[ count++ ] = cpu_to_le32(MASK_22 | MASK_21); /* => values */ - - saa->rps0[ count++ ] = cpu_to_le32(CMD_PAUSE | ( saa->grab_port[frame] == 0 ? MASK_12 : MASK_14)); /* wait for o_fid_a/b */ - saa->rps0[ count++ ] = cpu_to_le32(CMD_PAUSE | ( saa->grab_port[frame] == 0 ? MASK_11 : MASK_13)); /* wait for e_fid_a/b */ - - saa->rps0[ count++ ] = cpu_to_le32(CMD_WR_REG | (6 << 8) | HPS_CTRL/4); /* upload hps-registers for next grab */ - saa->rps0[ count++ ] = cpu_to_le32(hps_ctrl); - saa->rps0[ count++ ] = cpu_to_le32(hps_v_scale); - saa->rps0[ count++ ] = cpu_to_le32(hps_v_gain); - saa->rps0[ count++ ] = cpu_to_le32(hps_h_prescale); - saa->rps0[ count++ ] = cpu_to_le32(hps_h_scale); - saa->rps0[ count++ ] = cpu_to_le32(bcs_ctrl); - - saa->rps0[ count++ ] = cpu_to_le32(CMD_WR_REG | (1 << 8) | CLIP_FORMAT_CTRL/4);/* upload hps-registers for next grab */ - saa->rps0[ count++ ] = cpu_to_le32(clip_format); - - saa->rps0[ count++ ] = cpu_to_le32(CMD_UPLOAD | MASK_05 | MASK_06); /* upload hps1/2 */ - - /* upload video-dma1 registers for next grab */ - saa->rps0[ count++ ] = cpu_to_le32(CMD_WR_REG | (6 << 8) | BASE_ODD1/4); - saa->rps0[ count++ ] = cpu_to_le32(vdma1.base_odd); - saa->rps0[ count++ ] = cpu_to_le32(vdma1.base_even); - saa->rps0[ count++ ] = cpu_to_le32(vdma1.prot_addr); - saa->rps0[ count++ ] = cpu_to_le32(vdma1.pitch); - saa->rps0[ count++ ] = cpu_to_le32(vdma1.base_page); - saa->rps0[ count++ ] = cpu_to_le32(vdma1.num_line_byte); - - saa->rps0[ count++ ] = cpu_to_le32(CMD_UPLOAD | MASK_02); /* upload video-dma1 */ - - saa->rps0[ count++ ] = cpu_to_le32(CMD_WR_REG_MASK | (MC1/4)); /* turn on video-dma1 */ - saa->rps0[ count++ ] = cpu_to_le32(MASK_06 | MASK_22); /* => mask */ - saa->rps0[ count++ ] = cpu_to_le32(MASK_06 | MASK_22); /* => values */ - - saa->rps0[ count++ ] = cpu_to_le32(CMD_WR_REG | (1 << 8) | (MC2/4)); /* Write MC2 */ - saa->rps0[ count++ ] = cpu_to_le32((1 << (27+frame)) | (1 << (11+frame))); - - saa->rps0[ count++ ] = cpu_to_le32(CMD_PAUSE | ( saa->grab_port[frame] == 0 ? MASK_12 : MASK_14)); /* wait for o_fid_a/b */ - saa->rps0[ count++ ] = cpu_to_le32(CMD_PAUSE | ( saa->grab_port[frame] == 0 ? MASK_11 : MASK_13)); /* wait for e_fid_a/b */ - - saa->rps0[ count++ ] = cpu_to_le32(CMD_WR_REG_MASK | (MC1/4)); /* turn off video-dma1 */ - saa->rps0[ count++ ] = cpu_to_le32(MASK_06 | MASK_22); /* => mask */ - saa->rps0[ count++ ] = cpu_to_le32(MASK_22); /* => values */ - - saa->rps0[ count++ ] = cpu_to_le32(CMD_INTERRUPT); /* generate interrupt */ - saa->rps0[ count++ ] = cpu_to_le32(CMD_STOP); /* stop processing */ - } else { - - /* the height, width, ... have not changed. check if the user wants to grab to - another *buffer* */ - if( frame != last_frame ) { - - /* ok, we want to grab to another buffer, but with the same programming. - it is sufficient to adjust the video_dma1-registers and the rps-signal stuff. */ - saa->rps0[ 20 ] = cpu_to_le32(virt_to_bus(saa->page_table[frame]) | ME1); - saa->rps0[ 27 ] = cpu_to_le32((1 << (27+frame)) | (1 << (11+frame))); - - } - } - - /* if we are called from within the irq-handler, the hps is at the beginning of a - new frame. the rps does not need to wait the new frame, and so we tweak the - starting address a little bit and so we can directly start grabbing again. - note: for large video-sizes and slow computers this can cause jaggy pictures - because the whole process is not in sync. perhaps one should be able to - disable this. (please remember that this whole stuff only belongs to - "old" saa7146s (= revision 0), newer saa7146s don´t have any hardware-bugs - and capture works fine. (see below) */ - if( 1 == irq_call ) { - saa7146_write(saa->mem, RPS_ADDR0, virt_to_bus(&saa->rps0[15])); - } - - /* turn on rps */ - saa7146_write(saa->mem, MC1, (MASK_12 | MASK_28)); - - /* store the values for the last grab */ - last_height = saa->grab_height[frame]; - last_width = saa->grab_width[frame]; - last_format = saa->grab_format[frame]; - last_port = saa->grab_port[frame]; - last_frame = frame; - - return 0; -} - -int init_rps0_rev1(struct saa7146* saa, int frame) { - -static int old_width[SAA7146_MAX_BUF]; /* pixel width of grabs */ -static int old_height[SAA7146_MAX_BUF]; /* pixel height of grabs */ -static int old_format[SAA7146_MAX_BUF]; /* video format of grabs */ -static int old_port[SAA7146_MAX_BUF]; /* video port for grab */ - -static int buf_stat[SAA7146_MAX_BUF]; - - struct saa7146_video_dma vdma1; - u32 hps_v_scale = 0, hps_v_gain = 0, hps_ctrl = 0, hps_h_prescale = 0, hps_h_scale = 0; - u32 clip_format = 0; /* this can be 0, since we don't do clipping */ - u32 bcs_ctrl = 0; - - int i = 0, count = 0; - - /* check if something has changed since the last grab for this buffer */ - if ( saa->grab_height[frame] == old_height[frame] - && saa->grab_width[frame] == old_width[frame] - && saa->grab_port[frame] == old_port[frame] - && saa->grab_format[frame] == old_format[frame] ) { - - /* nope, nothing to be done here */ - return 0; - } - - /* re-program the rps0 completely */ - - /* indicate that the user has requested re-programming of the 'frame'-buffer */ - buf_stat[frame] = 1; - - /* turn off rps */ - saa7146_write(saa->mem, MC1, MASK_28); - - - /* write beginning of rps-program */ - count = 0; - saa->rps0[ count++ ] = cpu_to_le32(CMD_PAUSE | MASK_12); /* wait for o_fid_a */ - saa->rps0[ count++ ] = cpu_to_le32(CMD_PAUSE | MASK_11); /* wait for e_fid_a */ - for(i = 0; i < saa->buffers; i++) { - saa->rps0[ count++ ] = cpu_to_le32(CMD_JUMP | (1 << (21+i))); /* check signal x, jump if set */ - saa->rps0[ count++ ] = cpu_to_le32(virt_to_bus(&saa->rps0[40*(i+1)])); - } - saa->rps0[ count++ ] = cpu_to_le32(CMD_PAUSE | MASK_12); /* wait for o_fid_a */ - saa->rps0[ count++ ] = cpu_to_le32(CMD_PAUSE | MASK_11); /* wait for e_fid_a */ - saa->rps0[ count++ ] = cpu_to_le32(CMD_JUMP); /* jump to the beginning */ - saa->rps0[ count++ ] = cpu_to_le32(virt_to_bus(&saa->rps0[2])); - - for(i = 0; i < saa->buffers; i++) { - - /* we only re-program the i-th buffer if the user had set some values for it earlier. - otherwise the calculation-functions may fail. */ - if( buf_stat[i] == 0) - continue; - - count = 40*(i+1); - - calculate_video_dma1_grab(saa, i, &vdma1); - calculate_v_scale_registers(saa, modes_constants[saa->mode].v_calc, saa->grab_height[i], &hps_v_scale, &hps_v_gain); - calculate_h_scale_registers(saa, modes_constants[saa->mode].h_calc, saa->grab_width[i], 0, &hps_ctrl, &hps_v_gain, &hps_h_prescale, &hps_h_scale); - calculate_hxo_hyo_and_sources(saa, saa->grab_port[i], saa->grab_port[i], &hps_h_scale, &hps_ctrl); - calculate_output_format_register(saa,saa->grab_format[i],&clip_format); - calculate_bcs_ctrl_register(saa, 0x80, 0x40, 0x40, &bcs_ctrl); - - saa->rps0[ count++ ] = cpu_to_le32(CMD_WR_REG | (6 << 8) | HPS_CTRL/4); /* upload hps-registers for next grab */ - saa->rps0[ count++ ] = cpu_to_le32(hps_ctrl); - saa->rps0[ count++ ] = cpu_to_le32(hps_v_scale); - saa->rps0[ count++ ] = cpu_to_le32(hps_v_gain); - saa->rps0[ count++ ] = cpu_to_le32(hps_h_prescale); - saa->rps0[ count++ ] = cpu_to_le32(hps_h_scale); - saa->rps0[ count++ ] = cpu_to_le32(bcs_ctrl); - - saa->rps0[ count++ ] = cpu_to_le32(CMD_WR_REG | (1 << 8) | CLIP_FORMAT_CTRL/4);/* upload hps-registers for next grab */ - saa->rps0[ count++ ] = cpu_to_le32(clip_format); - - saa->rps0[ count++ ] = cpu_to_le32(CMD_UPLOAD | MASK_05 | MASK_06); /* upload hps1/2 */ - - saa->rps0[ count++ ] = cpu_to_le32(CMD_WR_REG | (6 << 8) | BASE_ODD1/4); /* upload video-dma1 registers for next grab */ - saa->rps0[ count++ ] = cpu_to_le32(vdma1.base_odd); - saa->rps0[ count++ ] = cpu_to_le32(vdma1.base_even); - saa->rps0[ count++ ] = cpu_to_le32(vdma1.prot_addr); - saa->rps0[ count++ ] = cpu_to_le32(vdma1.pitch); - saa->rps0[ count++ ] = cpu_to_le32(vdma1.base_page); - saa->rps0[ count++ ] = cpu_to_le32(vdma1.num_line_byte); - - saa->rps0[ count++ ] = cpu_to_le32(CMD_UPLOAD | MASK_02); /* upload video-dma1 */ - - saa->rps0[ count++ ] = cpu_to_le32(CMD_WR_REG_MASK | (MC1/4)); /* turn on video-dma1 */ - saa->rps0[ count++ ] = cpu_to_le32(MASK_06 | MASK_22); /* => mask */ - saa->rps0[ count++ ] = cpu_to_le32(MASK_06 | MASK_22); /* => values */ - - saa->rps0[ count++ ] = cpu_to_le32(CMD_PAUSE | ( saa->grab_port[i] == 0 ? MASK_12 : MASK_14)); /* wait for o_fid_a/b */ - saa->rps0[ count++ ] = cpu_to_le32(CMD_PAUSE | ( saa->grab_port[i] == 0 ? MASK_11 : MASK_13)); /* wait for e_fid_a/b */ - - saa->rps0[ count++ ] = cpu_to_le32(CMD_WR_REG_MASK | (MC1/4)); /* turn off video-dma1 and dma2 (clipping)*/ - saa->rps0[ count++ ] = cpu_to_le32(MASK_06 | MASK_22 | MASK_05 | MASK_21); /* => mask */ - saa->rps0[ count++ ] = cpu_to_le32(MASK_22 | MASK_21); /* => values */ - - saa->rps0[ count++ ] = cpu_to_le32(CMD_WR_REG | (1 << 8) | (MC2/4)); /* Write MC2 */ - saa->rps0[ count++ ] = cpu_to_le32((1 << (27+i))); - saa->rps0[ count++ ] = cpu_to_le32(CMD_INTERRUPT); /* generate interrupt */ - - saa->rps0[ count++ ] = cpu_to_le32(CMD_JUMP); /* jump to the beginning */ - saa->rps0[ count++ ] = cpu_to_le32(virt_to_bus(&saa->rps0[2])); - - old_height[frame] = saa->grab_height[frame]; - old_width[frame] = saa->grab_width[frame]; - old_port[frame] = saa->grab_port[frame]; - old_format[frame] = saa->grab_format[frame]; - } - - /* write the address of the rps-program */ - saa7146_write(saa->mem, RPS_ADDR0, virt_to_bus(&saa->rps0[ 0])); - /* turn on rps again */ - saa7146_write(saa->mem, MC1, (MASK_12 | MASK_28)); - - return 0; -} - -/* this funtion is called whenever a new grab is requested. if possible (that - means: if the rps is not running) it re-programs the rps, otherwise it relys on - the irq-handler to do that */ -int set_up_grabbing(struct saa7146* saa, int frame) -{ - u32 mc1 = 0; - - if( 0 == saa->revision ) { - - /* check if the rps is currently in use */ - mc1 = saa7146_read(saa->mem, MC1); - - /* the rps is not running ... */ - if( 0 == ( mc1 & MASK_12) ) { - - /* we can completly re-program the rps now */ - dprintk("saa7146_v4l.o: ==> set_up_grabbing: start new rps.\n"); - init_rps0_rev0(saa,frame,0); - } else { - - /* the rps is running. in this case, the irq-handler is responsible for - re-programming the rps and nothing can be done right now */ - dprintk("saa7146_v4l.o: ==> set_up_grabbing: no new rps started.\n"); - } - } else { - /* check if something has changed, reprogram if necessary */ - init_rps0_rev1(saa,frame); - /* set rps-signal-bit to start grabbing */ - saa7146_write(saa->mem, MC2, (1 << (27+frame)) | (1 << (11+frame))); - } - - return 0; -} - - -void saa7146_std_grab_irq_callback_rps0(struct saa7146* saa, u32 isr, void* data) -{ - u32 mc2 = 0; - int i = 0; - - hprintk("saa7146_v4l.o: ==> saa7146_v4l_irq_callback_rps0\n"); - - /* check for revision: old revision */ - if( 0 == saa->revision ) { - - /* look what buffer has been grabbed, set the ´done´-flag and clear the signal */ - mc2 = saa7146_read(saa->mem, MC2); - for( i = 0; i < saa->buffers; i++ ) { - - if ((0 != (mc2 & (1 << (11+i)))) && (GBUFFER_GRABBING == saa->frame_stat[i])) { - saa->frame_stat[i] = GBUFFER_DONE; - saa7146_write(saa->mem, MC2, (1<<(27+i))); - } - } - - /* look if there is another buffer we can grab to */ - for( i = 0; i < saa->buffers; i++ ) { - if ( GBUFFER_GRABBING == saa->frame_stat[i] ) - break; - } - - /* yes, then set up the rps again */ - if( saa->buffers != i) { - init_rps0_rev0(saa,i,1); - } - } else { - /* new revisions */ - - /* look what buffer has been grabbed, set the ´done´-flag */ - mc2 = saa7146_read(saa->mem, MC2); - for( i = 0; i < saa->buffers; i++ ) { - - if ((0 == (mc2 & (1 << (11+i)))) && (GBUFFER_GRABBING == saa->frame_stat[i])) { - saa->frame_stat[i] = GBUFFER_DONE; - } - } - - } - /* notify any pending process */ - wake_up_interruptible(&saa->rps0_wq); - return; -} - -/* ---------------------------------------------*/ -/* mask-clipping */ -/* ---------------------------------------------*/ -int calculate_clipping_registers_mask(struct saa7146* saa, u32 width, u32 height, struct saa7146_video_dma* vdma2, u32* clip_format, u32* arbtr_ctrl) -{ - u32 clip_addr = 0, clip_pitch = 0; - - dprintk("saa7146: ==> calculate_clipping_registers_mask\n"); - - /* adjust arbitration control register */ - *arbtr_ctrl &= 0xffff00ff; - *arbtr_ctrl |= 0x00001000; - - clip_addr = virt_to_bus(saa->clipping); - clip_pitch = ((width+31)/32)*4; - - vdma2->base_even = clip_addr; - vdma2->base_page = 0x04; /* enable read - operation */ - vdma2->prot_addr = clip_addr + (clip_pitch*height); - - /* convention: if scaling is between 1/2 and 1/4 we only use - the even lines, the odd lines get discarded (see vertical scaling) */ - if( saa->interlace != 0 && height*4 >= modes_constants[saa->mode].v_calc && height*2 <= modes_constants[saa->mode].v_calc) { - vdma2->base_odd = vdma2->prot_addr; - vdma2->pitch = clip_pitch; - vdma2->num_line_byte = (((height)-1) << 16) | (clip_pitch-1); - } else { - vdma2->base_odd = clip_addr+clip_pitch; - vdma2->pitch = clip_pitch*2; - vdma2->num_line_byte = (((height/2)-1) << 16) | (clip_pitch-1); - } - - *clip_format &= 0xfffffff7; - - return 0; -} - -/* helper functions for emulate rect-clipping via mask-clipping. - note: these are extremely inefficient, but for clipping with less than 16 - windows rect-clipping should be done anyway... -*/ - -/* clear one pixel of the clipping memory at position (x,y) */ -void set_pixel(s32 x, s32 y, s32 window_width, u32* mem) { - - u32 mem_per_row = 0; - u32 adr = 0; - u32 shift = 0; - u32 bit = 0; - - mem_per_row = (window_width + 31 )/ 32 ; - adr = y * mem_per_row + (x / 32); - shift = 31 - (x % 32); - bit = (1 << shift); - - mem[adr] |= bit; -} - -/* clear a box out of the clipping memory, beginning at (x,y) with "width" and "height" */ -void set_box(s32 x, s32 y, s32 width, s32 height, s32 window_width, s32 window_height, u32* mem) -{ - s32 ty = 0; - s32 tx = 0; - - /* the video_clip-struct may contain negative values to indicate that a window - doesn't lay completly over the video window. Thus, we correct the values */ - - if( width < 0) { - x += width; width = -width; - } - if( height < 0) { - y += height; height = -height; - } - - if( x < 0) { - width += x; x = 0; - } - if( y < 0) { - height += y; y = 0; - } - - if( width <= 0 || height <= 0) { - printk("saa7146: ==> set_box: sanity error!\n"); - return; - } - - if(x + width > window_width) - width -= (x + width) - window_width; - if(y + height > window_height) - height -= (y + height) - window_height; - - /* Now, set a '1' in the memory, where no video picture should appear */ - for(ty = y; ty < y+height; ty++) { - for(tx = x; tx < x+width; tx++) { - set_pixel(tx, ty, window_width, mem); - } - } -} - -int emulate_rect_clipping(struct saa7146 *saa, u16 clipcount, int x[], int y[], int w[], int h[], u32 w_width, u32 w_height) -{ - int i = 0; - - /* clear out clipping mem */ - memset(saa->clipping, 0x0, CLIPPING_MEM_SIZE*sizeof(u32)); - - /* go through list of clipping-windows, clear out rectangular-regions in the clipping memory */ - for(i = 0; i < clipcount; i++) { - set_box(x[i], y[i], w[i], h[i], w_width, w_height, saa->clipping); - } - - return 0; -} - -/* ---------------------------------------------*/ -/* rectangle-clipping */ -/* ---------------------------------------------*/ - -#define MIN(x,y) ( ((x) < (y)) ? (x) : (y) ) -#define MAX(x,y) ( ((x) > (y)) ? (x) : (y) ) - -/* simple double-sort algorithm with duplicate elimination */ -int sort_and_eliminate(u32* values, int* count) -{ - int low = 0, high = 0, top = 0, temp = 0; - int cur = 0, next = 0; - - /* sanity checks */ - if( (0 > *count) || (NULL == values) ) { - printk("saa7146: ==> sort_and_eliminate: internal error #1\n"); - return -EINVAL; - } - - /* bubble sort the first ´count´ items of the array ´values´ */ - for( top = *count; top > 0; top--) { - for( low = 0, high = 1; high < top; low++, high++) { - if( values[low] > values[high] ) { - temp = values[low]; - values[low] = values[high]; - values[high] = temp; - } - } - } - - /* remove duplicate items */ - for( cur = 0, next = 1; next < *count; next++) { - if( values[cur] != values[next]) - values[++cur] = values[next]; - } - - *count = cur + 1; - - return 0; -} - -int calculate_clipping_registers_rect(struct saa7146 *saa, int clipcount, int x[], int y[], int w[], int h[], u32 width, u32 height, struct saa7146_video_dma* vdma2, u32* clip_format, u32* arbtr_ctrl) -{ - u32 line_list[32]; - u32 pixel_list[32]; - u32 numdwords = 0; - - int i = 0, j = 0; - int l = 0, r = 0, t = 0, b = 0; - int cnt_line = 0, cnt_pixel = 0; - - dprintk("saa7146: ==> calculate_clipping_registers_clip\n"); - - /* clear out memory */ - memset(&line_list[0], 0x00, sizeof(u32)*32); - memset(&pixel_list[0], 0x00, sizeof(u32)*32); - memset(saa->clipping, 0x00, sizeof(u32)*CLIPPING_MEM_SIZE); - - /* fill the line and pixel-lists */ - for(i = 0; i < clipcount; i++) { - - /* calculate values for l(eft), r(ight), t(op), b(ottom) */ - l = x[i]; - r = x[i]+w[i]; - t = y[i]; - b = y[i]+h[i]; - - /* insert left/right coordinates */ - pixel_list[ 2*i ] = MIN(l, width); - pixel_list[(2*i)+1] = MIN(r, width); - /* insert top/bottom coordinates */ - line_list[ 2*i ] = MIN(t, height); - line_list[(2*i)+1] = MIN(b, height); - } - - /* sort and eliminate lists */ - cnt_line = cnt_pixel = 2*clipcount; - sort_and_eliminate( &pixel_list[0], &cnt_pixel ); - sort_and_eliminate( &line_list[0], &cnt_line ); - - /* calculate the number of used u32s */ - numdwords = MAX( (cnt_line+1), (cnt_pixel+1))*2; - numdwords = MAX(4, numdwords); - numdwords = MIN(64, numdwords); - - /* fill up cliptable */ - for(i = 0; i < cnt_pixel; i++) { - saa->clipping[2*i] |= (pixel_list[i] << 16); - } - for(i = 0; i < cnt_line; i++) { - saa->clipping[(2*i)+1] |= (line_list[i] << 16); - } - - /* fill up cliptable with the display infos */ - for(j = 0; j < clipcount; j++) { - - for(i = 0; i < cnt_pixel; i++) { - - if( x[j] < 0) - x[j] = 0; - - if( pixel_list[i] < (x[j] + w[j])) { - - if ( pixel_list[i] >= x[j] ) { - saa->clipping[2*i] |= (1 << j); - } - } - } - for(i = 0; i < cnt_line; i++) { - - if( y[j] < 0) - y[j] = 0; - - if( line_list[i] < (y[j] + h[j]) ) { - - if( line_list[i] >= y[j] ) { - saa->clipping[(2*i)+1] |= (1 << j); - } - } - } - } - - /* adjust arbitration control register */ - *arbtr_ctrl &= 0xffff00ff; - *arbtr_ctrl |= 0x00001c00; - - vdma2->base_even = virt_to_bus(saa->clipping); - vdma2->base_odd = virt_to_bus(saa->clipping); - vdma2->prot_addr = virt_to_bus(saa->clipping)+((sizeof(u32))*(numdwords)); - vdma2->base_page = 0x04; - vdma2->pitch = 0x00; - vdma2->num_line_byte = (0 << 16 | (sizeof(u32))*(numdwords-1) ); - - /* set clipping-mode. please note again, that for sizes below 1/2, we only use the - even-field. because of this, we have to specify ´recinterl´ correctly (specs, p. 97)*/ - *clip_format &= 0xfffffff7; - - if( saa->interlace != 0 && height*4 >= modes_constants[saa->mode].v_calc && height*2 <= modes_constants[saa->mode].v_calc) { - *clip_format |= 0x00000000; - } else { - *clip_format |= 0x00000008; - } - return 0; -} - - -/* ---------------------------------------------*/ -/* main function for clipping */ -/* ---------------------------------------------*/ -/* arguments: - type = see ´saa7146.h´ - width = width of the video-window - height = height of the video-window - *mask = pointer to mask memory (only needed for mask-clipping) - *clips = pointer to clip-window-list (only needed for rect-clipping) - clipcount = # of clip-windows (only needed for rect-clipping) -*/ -int clip_windows(struct saa7146* saa, u32 type, u32 width, u32 height, u32* mask, u16 clipcount, int x[], int y[], int w[], int h[]) -{ - struct saa7146_video_dma vdma2; - - u32 clip_format = saa7146_read(saa->mem, CLIP_FORMAT_CTRL); - u32 arbtr_ctrl = saa7146_read(saa->mem, PCI_BT_V1); - - hprintk("saa7146: ==> clip_windows\n"); - - /* some sanity checks first */ - if ( width <= 0 || height <= 0 ) { - printk("saa7146: ==> clip_windows: sanity error #1!\n"); - return -EINVAL; - } - - /* check if anything to do here, disable clipping if == 0 */ - if( clipcount == 0 ) { - - /* mask out relevant bits (=lower word)*/ - clip_format &= MASK_W1; - - /* upload clipping-registers*/ - saa7146_write(saa->mem, CLIP_FORMAT_CTRL,clip_format); - saa7146_write(saa->mem, MC2, (MASK_05 | MASK_21)); - - /* disable video dma2 */ - saa7146_write(saa->mem, MC1, (MASK_21)); - - return 0; - } - - switch(type) { - - case SAA7146_CLIPPING_MASK_INVERTED: - case SAA7146_CLIPPING_MASK: - { - printk("mask\n"); - /* sanity check */ - if( NULL == mask ) { - printk("saa7146: ==> clip_windows: sanity error #1!\n"); - return -EINVAL; - } - - /* copy the clipping mask to structure */ - memmove(saa->clipping, mask, CLIPPING_MEM_SIZE*sizeof(u32)); - /* set clipping registers */ - calculate_clipping_registers_mask(saa,width,height,&vdma2,&clip_format,&arbtr_ctrl); - - break; - } - - case SAA7146_CLIPPING_RECT_INVERTED: - case SAA7146_CLIPPING_RECT: - { - /* see if we have anything to do */ - if ( 0 == clipcount ) { - return 0; - } - - /* sanity check */ - if( NULL == x || NULL == y || NULL == w || NULL == h ) { - printk("saa7146: ==> clip_windows: sanity error #2!\n"); - return -EINVAL; - } - - /* rectangle clipping can only handle 16 overlay windows; if we - have more, we have do emulate the whole thing with mask-clipping */ - if (1) { //clipcount > > 16 ) { - //printk("emulate\n"); - emulate_rect_clipping(saa, clipcount, x,y,w,h, width, height); - calculate_clipping_registers_mask(saa,width,height,&vdma2,&clip_format,&arbtr_ctrl); - if( SAA7146_CLIPPING_RECT == type ) - type = SAA7146_CLIPPING_MASK; - else - type = SAA7146_CLIPPING_MASK_INVERTED; - - } - else { - calculate_clipping_registers_rect(saa,clipcount,x,y,w,h,width,height,&vdma2,&clip_format,&arbtr_ctrl); - } - - break; - } - - default: - { - printk("saa7146: ==> clip_windows: internal error #1!\n"); - return -EINVAL; - } - - } - - /* set clipping format */ - clip_format &= 0xffff0008; - clip_format |= (type << 4); - - saa7146_write(saa->mem, BASE_EVEN2, vdma2.base_even); - saa7146_write(saa->mem, BASE_ODD2, vdma2.base_odd); - saa7146_write(saa->mem, PROT_ADDR2, vdma2.prot_addr); - saa7146_write(saa->mem, BASE_PAGE2, vdma2.base_page); - saa7146_write(saa->mem, PITCH2, vdma2.pitch); - saa7146_write(saa->mem, NUM_LINE_BYTE2, vdma2.num_line_byte); - - saa7146_write(saa->mem, CLIP_FORMAT_CTRL,clip_format); - saa7146_write(saa->mem, PCI_BT_V1, arbtr_ctrl); - - /* upload clip_control-register, clipping-registers, enable video dma2 */ - saa7146_write(saa->mem, MC2, (MASK_05 | MASK_21 | MASK_03 | MASK_19)); - saa7146_write(saa->mem, MC1, (MASK_05 | MASK_21)); -/* - printk("ARBTR_CTRL: 0x%08x\n",saa7146_read(saa->mem, PCI_BT_V1)); - printk("CLIP_FORMAT: 0x%08x\n",saa7146_read(saa->mem, CLIP_FORMAT_CTRL)); - printk("BASE_ODD1: 0x%08x\n",saa7146_read(saa->mem, BASE_ODD1)); - printk("BASE_EVEN1: 0x%08x\n",saa7146_read(saa->mem, BASE_EVEN1)); - printk("PROT_ADDR1: 0x%08x\n",saa7146_read(saa->mem, PROT_ADDR1)); - printk("PITCH1: 0x%08x\n",saa7146_read(saa->mem, PITCH1)); - printk("BASE_PAGE1: 0x%08x\n",saa7146_read(saa->mem, BASE_PAGE1)); - printk("NUM_LINE_BYTE1: 0x%08x\n",saa7146_read(saa->mem, NUM_LINE_BYTE1)); - printk("BASE_ODD2: 0x%08x\n",saa7146_read(saa->mem, BASE_ODD2)); - printk("BASE_EVEN2: 0x%08x\n",saa7146_read(saa->mem, BASE_EVEN2)); - printk("PROT_ADDR2: 0x%08x\n",saa7146_read(saa->mem, PROT_ADDR2)); - printk("PITCH2: 0x%08x\n",saa7146_read(saa->mem, PITCH2)); - printk("BASE_PAGE2: 0x%08x\n",saa7146_read(saa->mem, BASE_PAGE2)); - printk("NUM_LINE_BYTE2: 0x%08x\n",saa7146_read(saa->mem, NUM_LINE_BYTE2)); -*/ - return 0; - -} -#endif - -#ifdef __COMPILE_SAA7146_I2C__ - -/* ---------------------------------------------*/ -/* i2c-helper functions */ -/* ---------------------------------------------*/ - -/* this functions gets the status from the saa7146 at address 'addr' - and returns it */ -u32 i2c_status_check(struct saa7146* saa) -{ - u32 iicsta = 0; - - iicsta = saa7146_read(saa->mem, I2C_STATUS ); - hprintk("saa7146: ==> i2c_status_check:0x%08x\n",iicsta); - - return iicsta; -} - -/* this function should be called after an i2c-command has been written. - if we are debugging, it checks, if the busy flags rises and falls correctly - and reports a timeout (-1) or the error-bits set like in described in the specs, - p.123, table 110 */ -int i2c_busy_rise_and_fall(struct saa7146* saa, int timeout) -{ - int i = 0; - u32 status = 0; - - hprintk("saa7146: ==> i2c_busy_rise_and_fall\n"); - - /* wait until busy-flag rises */ - for (i = 5; i > 0; i--) { - - hprintk("saa7146: i2c_busy_rise_and_fall; rise wait %d\n",i); - - status = i2c_status_check(saa); - - /* check busy flag */ - if ( 0 != (status & SAA7146_I2C_BUSY)) - break; - - /* see if anything can be done while we're waiting */ - cond_resched (); - mdelay(1); - } - - /* we don't check the i-value, since it does not matter - if we missed the rise of the busy flag or the fall or - whatever. we just have to wait some undefined time - after an i2c-command has been written out */ - - /* wait until busy-flag is inactive or error is reported */ - for (i = timeout; i > 0; i--) { - - hprintk("saa7146: i2c_busy_rise_and_fall; fall wait %d\n",i); - - status = i2c_status_check(saa); - - /* check busy flag */ - if ( 0 == (status & SAA7146_I2C_BUSY)) - break; - - /* check error flag */ - if ( 0 != (status & SAA7146_I2C_ERR)) - break; - - /* see if anything can be done while we're waiting */ - cond_resched (); - - mdelay(1); - } - - /* did a timeout occur ? */ - if ( 0 == i ) { - hprintk("saa7146: i2c_busy_rise_and_fall: timeout #2\n"); - return -1; - } - - /* report every error pending */ - switch( status & 0xfc ) { - - case SAA7146_I2C_SPERR: - hprintk("saa7146: i2c_busy_rise_and_fall: error due to invalid start/stop condition\n"); - break; - - case SAA7146_I2C_APERR: - hprintk("saa7146: i2c_busy_rise_and_fall: error in address phase\n"); - break; - - case SAA7146_I2C_DTERR: - hprintk("saa7146: i2c_busy_rise_and_fall: error in data transmission\n"); - break; - - case SAA7146_I2C_DRERR: - hprintk("saa7146: i2c_busy_rise_and_fall: error when receiving data\n"); - break; - - case SAA7146_I2C_AL: - hprintk("saa7146: i2c_busy_rise_and_fall: error because arbitration lost\n"); - break; - } - - return status; - -} - -/* this functions resets the saa7146 at address 'addr' - and returns 0 if everything was fine, otherwise -1 */ -int i2c_reset(struct saa7146* saa) -{ - u32 status = 0; - - hprintk("saa7146: ==> i2c_reset\n"); - - status = i2c_status_check(saa); - - /* clear data-byte for sure */ - saa7146_write(saa->mem, I2C_TRANSFER, 0x00); - - /* check if any operation is still in progress */ - if ( 0 != ( status & SAA7146_I2C_BUSY) ) { - - /* Yes, kill ongoing operation */ - hprintk("saa7146: i2c_reset: busy_state detected\n"); - - /* set ABORT-OPERATION-bit */ - saa7146_write(saa->mem, I2C_STATUS, ( SAA7146_I2C_BBR | MASK_07)); - saa7146_write(saa->mem, MC2, (MASK_00 | MASK_16)); - mdelay( SAA7146_I2C_DELAY ); - - /* clear all error-bits pending; this is needed because p.123, note 1 */ - saa7146_write(saa->mem, I2C_STATUS, SAA7146_I2C_BBR ); - saa7146_write(saa->mem, MC2, (MASK_00 | MASK_16)); - mdelay( SAA7146_I2C_DELAY ); - } - - /* check if any other error is still present */ - if ( SAA7146_I2C_BBR != (status = i2c_status_check(saa)) ) { - - /* yes, try to kick it */ - hprintk("saa7146: i2c_reset: error_state detected, status:0x%08x\n",status); - - /* clear all error-bits pending */ - saa7146_write(saa->mem, I2C_STATUS, SAA7146_I2C_BBR ); - saa7146_write(saa->mem, MC2, (MASK_00 | MASK_16)); - mdelay( SAA7146_I2C_DELAY ); - /* the data sheet says it might be necessary to clear the status - twice after an abort */ - saa7146_write(saa->mem, I2C_STATUS, SAA7146_I2C_BBR ); - saa7146_write(saa->mem, MC2, (MASK_00 | MASK_16)); - } - - /* if any error is still present, a fatal error has occured ... */ - if ( SAA7146_I2C_BBR != (status = i2c_status_check(saa)) ) { - hprintk("saa7146: i2c_reset: fatal error, status:0x%08x\n",status); - return -EIO; - } - - return 0; -} - -/* this functions writes out the data-bytes at 'data' to the saa7146 - at address 'addr' regarding the 'timeout' and 'retries' values; - it returns 0 if ok, -1 if the transfer failed, -2 if the transfer - failed badly (e.g. address error) */ -int i2c_write_out(struct saa7146* saa, u32* data, int timeout) -{ - int status = 0; - - hprintk("saa7146: ==> writeout: 0x%08x (before) (to:%d)\n",*data,timeout); - - /* write out i2c-command */ - saa7146_write(saa->mem, I2C_TRANSFER, *data); - saa7146_write(saa->mem, I2C_STATUS, SAA7146_I2C_BBR); - saa7146_write(saa->mem, MC2, (MASK_00 | MASK_16)); - - /* after writing out an i2c-command we have to wait for a while; - because we do not know, how long we have to wait, we simply look - what the busy-flag is doing, before doing something else */ - - /* reason: while fiddling around with the i2c-routines, I noticed - that after writing out an i2c-command, one may not read out the - status immediately after that. you *must* wait some time, before - even the busy-flag gets set */ - - status = i2c_busy_rise_and_fall(saa,timeout); - - if ( -1 == status ) { - hprintk("saa7146: i2c_write_out; timeout\n"); - return -ETIMEDOUT; - } - - /* we only handle address-errors here */ - if ( 0 != (status & SAA7146_I2C_APERR)) { - hprintk("saa7146: i2c_write_out; error in address phase\n"); - return -EREMOTEIO; - } - - /* check for some other mysterious error; we don't handle this here */ - if ( 0 != ( status & 0xff)) { - hprintk("saa7146: i2c_write_out: some error has occured\n"); - return -EIO; - } - - /* read back data, just in case we were reading ... */ - *data = saa7146_read(saa->mem, I2C_TRANSFER); - - hprintk("saa7146: writeout: 0x%08x (after)\n",*data); - - return 0; -} - -int clean_up(const struct i2c_msg *m, int num, u32 *op) -{ - u16 i, j; - u16 op_count = 0; - - /* loop through all messages */ - for(i = 0; i < num; i++) { - op_count++; - /* loop throgh all bytes of message i */ - for(j = 0; j < m[i].len; j++) { - /* write back all bytes that could have been read */ - m[i].buf[j] = (op[op_count/3] >> ((3-(op_count%3))*8)); - op_count++; - } - } - - return 0; -} - -int prepare(const struct i2c_msg *m, int num, u32 *op) -{ - u16 h1, h2; - u16 i, j, addr; - u16 mem = 0, op_count = 0; - -//for (i=0; i<num; i++) { printk ("\n%02x (%s): ", m[i].addr, m[i].flags & I2C_M_RD ? "R" : "W"); for (j=0; j<m[i].len; j++) { m[i].buf[j] &= 0xff; printk (" %02x ", (u8) m[i].buf[j]); } } printk ("\n"); - /* determine size of needed memory */ - for(i = 0; i < num; i++) - mem += m[i].len + 1; - - /* we need one u32 for three bytes to be send plus - one byte to address the device */ - mem = 1 + ((mem-1) / 3); - - if ( mem > I2C_MEM_SIZE ) { - hprintk("saa7146: prepare: i2c-message to big\n"); - return -1; - } - - /* be careful: clear out the i2c-mem first */ - memset(op,0,sizeof(u32)*mem); - - for(i = 0; i < num; i++) { - /* insert the address of the i2c-slave. - * note: we get 7-bit-i2c-addresses, - * so we have to perform a translation - */ - addr = (m[i].addr << 1) | ((m[i].flags & I2C_M_RD) ? 1 : 0); - h1 = op_count/3; h2 = op_count%3; - op[h1] |= ((u8)addr << ((3-h2)*8)); - op[h1] |= (SAA7146_I2C_START << ((3-h2)*2)); - op_count++; - /* loop through all bytes of message i */ - for(j = 0; j < m[i].len; j++) { - /* insert the data bytes */ - h1 = op_count/3; h2 = op_count%3; - op[h1] |= ((u8)m[i].buf[j] << ((3-h2)*8)); - op[h1] |= (SAA7146_I2C_CONT << ((3-h2)*2)); - op_count++; - } - } - - /* have a look at the last byte inserted: - * if it was: ...CONT change it to ...STOP - */ - h1 = (op_count-1)/3; h2 = (op_count-1)%3; - if ( SAA7146_I2C_CONT == (0x3 & ((op[h1]) >> ((3-h2)*2))) ) { - op[h1] &= ~(0x2 << ((3-h2)*2)); - op[h1] |= (SAA7146_I2C_STOP << ((3-h2)*2)); - } - - return mem; -} -#endif - - -#ifdef __COMPILE_SAA7146_DEBI__ - -/* functions for accessing the debi-port. note: we currently don't support - * page-table-transfers. - */ - -#define MY_DEBI_TIMEOUT_MS 5 - -int debi_transfer(struct saa7146* saa, struct saa7146_debi_transfer* dt) -{ - u32 debi_config = 0, debi_command = 0, debi_page = 0, debi_ad = 0; - u32 timeout = MY_DEBI_TIMEOUT_MS; - - /* sanity checks */ - if(dt->direction > 1 || dt->timeout > 15 || dt->swap > 3 || dt->slave16 > 2 || dt->intel > 1 || dt->increment > 1 || dt->tien > 1 ) - return -EINVAL; - - debi_page = 0; - /* keep bits 31,30,28 clear */ - debi_config = (dt->timeout << 22) | (dt->swap << 20) | (dt->slave16 << 19) | (dt->increment << 18) | (dt->intel << 17) | (dt->tien << 16); - debi_command = (dt->num_bytes << 17) | (dt->direction << 16) | (dt->address << 0); - debi_ad = dt->mem; - - saa7146_write(saa->mem, DEBI_PAGE, debi_page); - saa7146_write(saa->mem, DEBI_CONFIG, debi_config); - saa7146_write(saa->mem, DEBI_COMMAND, debi_command); - saa7146_write(saa->mem, DEBI_AD, debi_ad); - - /* upload debi-registers */ - saa7146_write(saa->mem, MC2, (MASK_01|MASK_17)); - - /* wait for DEBI upload to complete */ - while (! (saa7146_read(saa->mem, MC2) & 0x2)); - - while( --timeout ) { - /* check, if DEBI still active */ - u32 psr = saa7146_read(saa->mem, PSR); - if (0 != (psr & SPCI_DEBI_S)) { - /* check, if error occured */ -/* if ( 0 != (saa7146_read(saa->mem, SSR) & (MASK_23|MASK_22))) { */ - if ( 0 != (saa7146_read(saa->mem, SSR) & (MASK_22))) { - /* clear error status and indicate error */ - saa7146_write(saa->mem, ISR, SPCI_DEBI_E); - return -1; - } - } - else { - /* Clear status bit */ - saa7146_write(saa->mem, ISR, SPCI_DEBI_S); - break; - } - /* I don´t know how we should actually wait for the debi to have finished. - we simply wait 1ms here and then check in a loop for max. MY_DEBI_TIMEOUT_MS */ - mdelay(1); - } - - /* check for timeout */ - if( 0 == timeout ) { - return -1; - } - - /* read back data if we did immediate read-transfer */ - if(dt->num_bytes <= 4 && dt->direction == 1) { - dt->mem = saa7146_read(saa->mem, DEBI_AD); - switch(dt->num_bytes) { - case 1: - dt->mem &= 0x000000ff; - break; - case 2: - dt->mem &= 0x0000ffff; - break; - case 3: - dt->mem &= 0x00ffffff; - break; - } - } - - return 0; -} -#endif - -#ifdef __COMPILE_SAA7146_STUFF__ -/* ---------------------------------------------*/ -/* helper-function: set gpio-pins */ -/* ---------------------------------------------*/ -void gpio_set(struct saa7146* saa, u8 pin, u8 data) -{ - u32 value = 0; - - /* sanity check */ - if(pin > 3) - return; - - /* read old register contents */ - value = saa7146_read(saa->mem, GPIO_CTRL ); - - value &= ~(0xff << (8*pin)); - value |= (data << (8*pin)); - - saa7146_write(saa->mem, GPIO_CTRL, value); -} - -void select_input(struct saa7146* saa, int p) -{ - u32 hps_ctrl = 0; - - /* sanity check */ - if( p < 0 || p > 1 ) - return; - - /* read old state */ - hps_ctrl = saa7146_read(saa->mem, HPS_CTRL); - - /* mask out relevant bits */ - hps_ctrl &= ~( MASK_31 | MASK_30 | MASK_28 ); - - /* set bits for input b */ - if( 1 == p ) { - hps_ctrl |= ( (1 << 30) | (1 << 28) ); - } - - /* write back & upload register */ - saa7146_write(saa->mem, HPS_CTRL, hps_ctrl); - saa7146_write(saa->mem, MC2, (MASK_05 | MASK_21)); -} - -#endif - diff --git a/linux/drivers/media/dvb/av7110/saa7146_core.c b/linux/drivers/media/dvb/av7110/saa7146_core.c deleted file mode 100644 index 97fd00a9c..000000000 --- a/linux/drivers/media/dvb/av7110/saa7146_core.c +++ /dev/null @@ -1,967 +0,0 @@ -/* - saa7146_core.c - core-functions + i2c driver for the saa7146 by - Philips Semiconductors. - - Copyright (C) 1998,1999 Michael Hunold <michael@mihu.de> - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - - -#include <linux/module.h> /* for module-version */ -#include <linux/delay.h> /* for delay-stuff */ -#include <linux/slab.h> /* for kmalloc/kfree */ -#include <linux/pci.h> /* for pci-config-stuff, vendor ids etc. */ -#include <linux/wrapper.h> /* for mem_map_reserve */ -#include <linux/init.h> -#include <asm/io.h> /* for accessing the pci-device */ -#include <linux/vmalloc.h> -#include <linux/mm.h> - -#include "saa7146_defs.h" -#include "saa7146_core.h" -#include "saa7146_v4l.h" -#include "av7110.h" -#include "compat.h" -#include "dvb_i2c.h" - -/* insmod parameter: here you can specify the number of video-buffers - to be allocated. for simple capturing 2 buffers (double-buffering) - should suffice. but if you plan to do 25fps grabbing, you should - set this to 4(=maximum), in order to be able to catch up from - temporarily delays */ -static int buffers = 2; - -/* insmod parameter: some programs (e.g. ´vic´) do not allow to - specify the used video-mode, so you have to tell this to the - modules by hand, 0 = PAL, 1 = NTSC */ -static int mode = 0; - -/* debug levels: 0 -- no debugging outputs - 1 -- prints out entering (and exiting if useful) of functions - 2 -- prints out very, very detailed informations of what is going on - 3 -- both of the above */ -int saa7146_debug = 0; /* insmod parameter */ - -#define dprintk if (saa7146_debug & 1) printk -#define hprintk if (saa7146_debug & 2) printk - -/* ---------------------------------------------*/ -/* memory functions - taken from bttv.c */ -/* ---------------------------------------------*/ - -static inline unsigned long kvirt_to_pa(unsigned long adr) -{ - unsigned long kva; - - kva = (unsigned long) page_address(vmalloc_to_page((void *)adr)); - kva |= adr & (PAGE_SIZE-1); /* restore the offset */ - - return __pa(kva); -} - - -static LIST_HEAD(saa7146_list); - -static int saa7146_extension_count = 0; -static struct saa7146_extension* saa7146_ext[SAA7146_MAX_EXTENSIONS]; - -#define SAA7146_I2C_TIMEOUT 100 /* in ms */ -#define SAA7146_I2C_RETRIES 6 - -static u32 SAA7146_I2C_BBR = SAA7146_I2C_BUS_BIT_RATE_3200; - -#define __COMPILE_SAA7146_I2C__ -#define __COMPILE_SAA7146_DEBI__ -#include "saa7146.c" -#undef __COMPILE_SAA7146_I2C__ - -/* ---------------------------------------------*/ -/* memory functions designed for saa7146 */ -/* ---------------------------------------------*/ - -/* rvmalloc allocates the memory and builds up - the page-tables for ´quant´-number of buffers */ -static void* rvmalloc(int quant, u32* pt[]) -{ - void* mem; - - unsigned long adr = 0; - unsigned long count = 0; - - u32* ptp = 0; - int i = 0, j = 0; - - dprintk(KERN_ERR "saa7146: rvmalloc called, quant:%d\n",quant); - - if(!quant) - return NULL; - - /* get grabbing memory */ - mem = vmalloc_32(quant*GRABBING_MEM_SIZE); - - if(!mem) - return NULL; - - dprintk(KERN_ERR "saa7146: alloc page tables\n"); - - /* alloc one page for a page-table for ´quant´ buffers */ - for(i = 0; i < quant; i++) { - pt[i] = (u32*)kmalloc(PAGE_SIZE,GFP_KERNEL); - - /* error: memory could not be allocated */ - if(!pt[i]) { - dprintk(KERN_ERR "saa7146: failed, free tables\n"); - for(j = (i-1); j >= 0; j--) - kfree(pt[j]); - dprintk(KERN_ERR "saa7146: free buffer memory\n"); - vfree(mem); - dprintk(KERN_ERR "saa7146: return 0 address for buffer\n"); - return NULL; - } - memset(pt[i], 0x00, PAGE_SIZE); - } - - dprintk(KERN_ERR "saa7146: clear RAM\n"); - - /* clear the ram out, no junk to the user - note: 0x7f gives a nice grey field - in RGB and YUV as well */ - memset(mem, 0x7f, quant*GRABBING_MEM_SIZE); - - dprintk(KERN_ERR "saa7146: build page tables\n"); - adr = (unsigned long)mem; - /* walk through the grabbing-memory and build up the page-tables */ - for(i = 0; i < quant; i++) { - - for (count=0; count<GRABBING_MEM_SIZE; count+=PAGE_SIZE) - mem_map_reserve(virt_to_page(__va(kvirt_to_pa(adr+count)))); - /* separate loop for SAA MMU, PAGE_SIZE can be !=4096 */ - ptp = pt[i]; - for (count=0; count<GRABBING_MEM_SIZE; count+=4096, adr+=4096) - *(ptp++) = cpu_to_le32(kvirt_to_pa(adr)); - } - dprintk(KERN_ERR "saa7146: page tables built\n"); - return mem; -} - -static void rvfree(void* mem, int quant, u32* pt[]) -{ - unsigned long adr, page; - unsigned long size = 0; - - int i = 0; - - dprintk(KERN_ERR "saa7146: rvfree called\n"); - - if (!quant) - return; - - if (mem) { - adr = (unsigned long)mem; - size = quant * GRABBING_MEM_SIZE; - - while (size > 0) { - page = kvirt_to_pa(adr); - mem_map_unreserve(virt_to_page(__va(page))); - adr += PAGE_SIZE; - size -= PAGE_SIZE; - } - - /* release the grabbing memory */ - vfree(mem); - } - /* free the page tables */ - for(i = 0; i < quant; i++) { - kfree(pt[i]); - } -} - - -/* ---------------------------------------------*/ -/* i2c-functions */ -/* ---------------------------------------------*/ - -static -int do_master_xfer (struct dvb_i2c_bus *i2c, const struct i2c_msg *msgs, int num) -{ - struct saa7146 *a = i2c->data; - int count; - int i = 0; - - dprintk(KERN_ERR "saa7146_core.o: master_xfer called, num:%d\n",num); - - /* prepare the message(s), get number of u32s to transfer */ - count = prepare(msgs, num, a->i2c); - - if (count < 0) { - hprintk(KERN_ERR "saa7146_core.o: could not prepare i2c-message\n"); - return -EIO; - } - - /* reset the i2c-device if necessary */ - if (i2c_reset(a) < 0) { - hprintk(KERN_ERR "saa7146_core.o: could not reset i2c-bus\n"); - return -EIO; - } - - for(i = 0; i < count; i++) { - /* see how many u32 have to be transferred; - * if there is only 1, - * we do not start the whole rps1-engine... - */ - - /* if address-error occured, don't retry */ - if (i2c_write_out(a, &a->i2c[i], SAA7146_I2C_TIMEOUT) < 0) { - hprintk (KERN_ERR "saa7146_core.o: " - "i2c error in address phase\n"); - return -EREMOTEIO; - } - } - - /* if any things had to be read, get the results */ - if (clean_up(msgs, num, a->i2c) < 0) { - hprintk(KERN_ERR "saa7146_core.o: i2c cleanup failed!\n"); - return -EIO; - } - - /* return the number of delivered messages */ - return num; -} - - - -static -int master_xfer (struct dvb_i2c_bus *i2c, const struct i2c_msg *msgs, int num) -{ - struct saa7146 *saa = i2c->data; - int retries = SAA7146_I2C_RETRIES; - int ret; - - if (down_interruptible (&saa->i2c_sem)) - return -ERESTARTSYS; - - do { - ret = do_master_xfer (i2c, msgs, num); - } while (ret != num && retries--); - - up (&saa->i2c_sem); - - return ret; -} - - -/* registering functions to load algorithms at runtime */ -int i2c_saa7146_add_bus (struct saa7146 *saa) -{ - init_MUTEX(&saa->i2c_sem); - - /* enable i2c-port pins */ - saa7146_write (saa->mem, MC1, (MASK_08 | MASK_24)); - - sprintf(saa->name, "saa7146(%d)", saa->dvb_adapter->num); - - saa->i2c_bus = dvb_register_i2c_bus (master_xfer, saa, - saa->dvb_adapter, 0); - if (!saa->i2c_bus) - return -ENOMEM; - - return 0; -} - - -void i2c_saa7146_del_bus (struct saa7146 *saa) -{ - dvb_unregister_i2c_bus (master_xfer, - saa->i2c_bus->adapter, saa->i2c_bus->id); - - dvb_unregister_adapter (saa->dvb_adapter); -} - -/* ---------------------------------------------*/ -/* debug-helper function: dump-registers */ -/* ---------------------------------------------*/ - -void dump_registers(unsigned char* mem) { - - u16 j = 0; - - for( j = 0x0; j < 0x1fe; j+=0x4 ) { - printk("0x%03x: 0x%08x\n",j,saa7146_read(mem,j)); - } - -} - -/* -----------------------------------------------------*/ -/* dispatcher-function for handling external commands */ -/* -----------------------------------------------------*/ - -static int saa7146_core_command (struct dvb_i2c_bus *i2c, unsigned int cmd, void *arg) -{ - int i = 0, result = -ENOIOCTLCMD; - struct saa7146* saa = i2c->data; - - dprintk("saa7146_core.o: ==> saa7146_core_command\n"); - - if( NULL == saa) - return -EINVAL; - - /* first let the extensions handle the command */ - for (i = 0; i < SAA7146_MAX_EXTENSIONS; i++) { - if (NULL != saa7146_ext[i]) { - if( -ENOIOCTLCMD != (result = saa7146_ext[i]->command(saa, saa->data[i], cmd, arg))) { - break; - } - } - } - - /* if command has not been handled by an extension, handle it now */ - if( result == -ENOIOCTLCMD ) { - - switch(cmd) { - case SAA7146_DUMP_REGISTERS: - { - dump_registers(saa->mem); - break; - } - case SAA7146_SET_DD1: - { - u32 *i = arg; - - dprintk(KERN_ERR "saa7146_core.o: SAA7146_SET_DD1 to 0x%08x\n",*i); - - /* set dd1 port register */ - saa7146_write(saa->mem, DD1_INIT, *i); - - /* write out init-values */ - saa7146_write(saa->mem,MC2, (MASK_09 | MASK_10 | MASK_26 | MASK_26)); - - break; - } - case SAA7146_DO_MMAP: - { - struct vm_area_struct *vma = arg; - unsigned long size = vma->vm_end - vma->vm_start; - unsigned long start = vma->vm_start; - unsigned long page,pos; - - dprintk(KERN_ERR "saa7146_core.o: SAA7146_DO_MMAP.\n"); - - if (size > saa->buffers * GRABBING_MEM_SIZE) - return -EINVAL; - - if ( NULL == saa->grabbing ) - return -EINVAL; - - pos=(unsigned long)saa->grabbing; - - while (size > 0) - { - page = kvirt_to_pa(pos); - if (remap_page_range(vma, start, page, - PAGE_SIZE, PAGE_SHARED)) - return -EAGAIN; - start += PAGE_SIZE; - pos += PAGE_SIZE; - size -= PAGE_SIZE; - } - - break; - } - case SAA7146_DEBI_TRANSFER: { - - struct saa7146_debi_transfer *dt = arg; - - dprintk("saa7146_core.o: SAA7146_DEBI_TRANSFER\n"); - dprintk("saa7146_core.o: timeout:%d, swap:%d, slave16:%d, increment:%d, intel:%d, tien:%d\n", dt->timeout, dt->swap, dt->slave16, dt->increment, dt->intel, dt->tien); - dprintk("saa7146_core.o: address:0x%04x, num_bytes:%d, direction:%d, mem:0x%08x\n",dt->address,dt->address,dt->direction,dt->mem); - - debi_transfer(saa, dt); - break; - } - - default: { - return -ENOIOCTLCMD; - } - } - } - - return 0; -} - -/* -----------------------------------------------------*/ -/* dispatcher-function for handling irq-events */ -/* -----------------------------------------------------*/ - -/* irq-handler function */ -static void saa7146_irq(int irq, void *dev_id, struct pt_regs * regs) -{ - struct saa7146 *saa = (struct saa7146 *)dev_id; - u32 isr = 0; - int i; - int count = 0; - - /* process all interrupts */ - while (1) { - - /* read out the primary status register */ - isr = saa7146_read(saa->mem, ISR); - /* clear all IRQs */ - saa7146_write(saa->mem, ISR, isr); - - /* is anything to do? */ - if ( 0 == isr ) - return; - - dprintk("%s: irq-call: isr:0x%08x\n",saa->name,isr); - - /* first let the extensions handle the interrupt */ - for (i = 0; i < SAA7146_MAX_EXTENSIONS; i++) - if (saa7146_ext[i] && - (isr&saa7146_ext[i]->handles_irqs)) { - saa7146_ext[i]->irq_handler(saa, isr, saa->data[i]); - //saa7146_write(saa->mem, ISR, saa7146_ext[i]->handles_irqs); - } - - //printk(KERN_ERR "%s: unhandled interrupt: 0x%08x\n", saa->name, isr); - - /* see if we are in a hard interrupt loop */ - ++count; - if (count > 10) - printk (KERN_WARNING "%s: irq loop %d\n", saa->name, count); - if (count > 20) { - saa7146_write(saa->mem, IER, 0x00000000); - printk(KERN_ERR "%s: IRQ lockup, cleared int mask\n", saa->name); - break; - } - } -} - -/* ----------------------------------------------------- - functions for finding any saa7146s in the system, - inserting/removing module for kernel, etc. - -----------------------------------------------------*/ - -int configure_saa7146 (struct saa7146 *saa) -{ - u32 rev = 0; - int result = 0; - - hprintk("saa7146_core.o: ==> configure_saa7146\n"); - - /* check module-parameters for sanity */ - - /* check if wanted number of video-buffers is valid, otherwise fix it */ - //if (buffers < 2) - // buffers = 2; - - if ( buffers > SAA7146_MAX_BUF ) - buffers = SAA7146_MAX_BUF; - - /* check if mode is supported */ - switch( mode ) { - /* 0 = pal, 1 = ntsc */ - case 0: - case 1: - { - break; - } - /* default to pal */ - default: - { - mode = 0; - break; - } - } - - /* get chip-revision; this is needed to enable bug-fixes */ - if( 0 > pci_read_config_dword(saa->device, 0x08, &rev)) { - printk (KERN_ERR - "saa7146_core.o: cannot read from pci-device!\n"); - return -1; - } - - saa->revision = (rev & 0xf); - - /* remap the memory from virtual to physical adress */ - saa->mem = ioremap ((saa->device->resource[0].start) - &PCI_BASE_ADDRESS_MEM_MASK, 0x1000); - - if ( !saa->mem ) { - printk(KERN_ERR "saa7146_core.o: cannot map pci-address!\n"); - return -EFAULT; - } - - /* get clipping memory */ - saa->clipping = (u32*) kmalloc (CLIPPING_MEM_SIZE*sizeof(u32),GFP_KERNEL); - - if ( !saa->clipping ) { - printk(KERN_ERR "saa7146_core.o: not enough kernel-memory for clipping!\n"); - return -ENOMEM; - } - - memset(saa->clipping, 0x0, CLIPPING_MEM_SIZE*sizeof(u32)); - - /* get i2c memory */ - saa->i2c = (u32*) kmalloc (I2C_MEM_SIZE*sizeof(u32),GFP_KERNEL); /*64*/ - - if ( !saa->i2c ) { - printk(KERN_ERR "saa7146_core.o: not enough kernel-memory for i2c!\n"); - kfree(saa->clipping); - return -ENOMEM; - } - - memset(saa->i2c, 0x0, I2C_MEM_SIZE*sizeof(u32)); - - /* get grabbing memory */ - saa->grabbing = (u32*) rvmalloc (buffers, &saa->page_table[0]); - - if ( !saa->grabbing ) { - printk(KERN_ERR "saa7146_core.o: not enough kernel-memory for grabbing_mem!\n"); - kfree(saa->i2c); - kfree(saa->clipping); - return -ENOMEM; - } - - /* get rps0 memory */ - saa->rps0 = (u32*) kmalloc (RPS_MEM_SIZE*sizeof(u32),GFP_KERNEL); - - if ( !saa->rps0 ) { - printk(KERN_ERR "saa7146_core.o: not enough kernel-memory for rps0_mem!\n"); - kfree(saa->i2c); - kfree(saa->clipping); - rvfree(saa->grabbing, buffers, &saa->page_table[0]); - return -ENOMEM; - } - - memset(saa->rps0, 0x0, RPS_MEM_SIZE*sizeof(u32)); - - /* get rps1 memory */ - saa->rps1 = (u32*) kmalloc (RPS_MEM_SIZE*sizeof(u32),GFP_KERNEL); - if ( !saa->rps1 ) { - printk(KERN_ERR "saa7146_core.o: not enough kernel-memory for rps1_mem!\n"); - kfree(saa->rps0); - kfree(saa->i2c); - kfree(saa->clipping); - rvfree(saa->grabbing, buffers, &saa->page_table[0]); - return -1; - } - - memset(saa->rps1, 0x0, RPS_MEM_SIZE*sizeof(u32)); - - /* get debi memory (32kB) */ - saa->debi = (u32*) kmalloc (8192*sizeof(u32),GFP_KERNEL); - - if ( !saa->debi ) { - printk(KERN_ERR "saa7146_core.o: not enough kernel-memory for debi_mem!\n"); - kfree(saa->rps1); - kfree(saa->rps0); - kfree(saa->i2c); - kfree(saa->clipping); - rvfree(saa->grabbing, buffers, &saa->page_table[0]); - return -1; - } - - memset(saa->debi, 0x0, 8192*sizeof(u32)); - - - /* clear out memory for grabbing information */ - memset(&saa->grab_width[0], 0x0, sizeof(int)*SAA7146_MAX_BUF); - memset(&saa->grab_height[0], 0x0, sizeof(int)*SAA7146_MAX_BUF); - memset(&saa->grab_format[0], 0x0, sizeof(int)*SAA7146_MAX_BUF); - memset(&saa->grab_port[0], 0x0, sizeof(int)*SAA7146_MAX_BUF); - - /* init the frame-status array */ - memset(&saa->frame_stat[0], GBUFFER_UNUSED, sizeof(int)*SAA7146_MAX_BUF); - - /* clear out all wait queues */ - init_waitqueue_head(&saa->rps0_wq); - init_waitqueue_head(&saa->rps1_wq); - - - /* request an interrupt for the saa7146 */ - result = request_irq (saa->device->irq, saa7146_irq, - SA_SHIRQ | SA_INTERRUPT, saa->name, (void *) saa); - - switch(result) { - case -EINVAL: - { - printk(KERN_ERR "saa7146_core.o: Bad irq number or handler\n"); - return -EINVAL; - } - case -EBUSY: - { - printk(KERN_ERR "saa7146_core.o: IRQ %d busy, change your PnP config in BIOS\n", saa->device->irq); - return -EBUSY; - } - case 0: - { - break; - } - default: - { - return result; - } - } - - /* print status message */ - dprintk("saa7146_core.o: %s: bus:%d, rev:%d, mem:0x%08x.\n", saa->name, saa->device->bus->number, saa->revision, (unsigned int) saa->mem); - - /* enable bus-mastering */ - pci_set_master( saa->device ); - - /* disable everything on the saa7146, perform a software-reset */ - saa7146_write(saa->mem, MC1, 0xbfff0000); - mdelay(2); -#if 0 - { - int j; - - /* clear all registers */ - for( j = 0x0; j < 0xfc; j+=0x4 ) { - saa7146_write(saa->mem,j, 0x0000000); - } - for( j = 0x104; j < 0x1fc; j+=0x4 ) { - saa7146_write(saa->mem,j, 0x0000000); - } - } -#endif - /* clear out any rps-signals pending */ - saa7146_write(saa->mem, MC2, 0xf8000000); - - /* enable video-port-pins*/ - saa7146_write(saa->mem,MC1, (MASK_10 | MASK_26)); - - /* disable all interrupt-conditions, only enable RPS interrupts */ - saa7146_write(saa->mem, ISR, 0xffffffff); - saa7146_write(saa->mem, IER, (MASK_27 | MASK_28)); -/* - printk("main: 0x114: 0x%08x\n",saa7146_read(saa->mem, 0x114)); - printk("main: 0x0e4: 0x%08x\n",saa7146_read(saa->mem, 0x0e4)); - printk("PSR: 0x%08x\n",saa7146_read(saa->mem, PSR)); - printk("SSR: 0x%08x\n",saa7146_read(saa->mem, SSR)); - printk("IER: 0x%08x\n",saa7146_read(saa->mem, IER)); - printk("ISR: 0x%08x\n",saa7146_read(saa->mem, ISR)); -*/ - - saa7146_write(saa->mem,PCI_BT_V1, 0x1c00101f); - saa7146_write(saa->mem,BCS_CTRL, 0x80400040); - - /* set dd1 stream a & b */ - saa7146_write(saa->mem, DD1_STREAM_B, 0x00000000); - saa7146_write(saa->mem, DD1_INIT, 0x02000000); - saa7146_write(saa->mem, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26)); - - saa7146_write(saa->mem, MC2, 0x077c077c); - - /* the Siemens DVB needs this if you want to have the i2c chips - get recognized before the main driver is loaded - */ - saa7146_write(saa->mem, GPIO_CTRL, 0x500000); - - saa->command = &saa7146_core_command; - saa->buffers = buffers; - saa->mode = mode; - saa->interlace = 1; - - i2c_saa7146_add_bus (saa); - - saa7146_write(saa->mem, GPIO_CTRL, 0x000000); - return 0; -} - - -void saa7146_foreach (void (*callback) (struct saa7146* saa, void *data), - void *data) -{ - struct list_head *entry; - - list_for_each (entry, &saa7146_list) { - struct saa7146* saa; - - saa = list_entry (entry, struct saa7146, list_head); - callback (saa, data); - } -} - - -static -void saa7146_attach_extension (struct saa7146* saa, void *data) -{ - int ext_id = (int) data; - saa7146_ext[ext_id]->attach (saa, &saa->data[ext_id]); -} - - -static -void saa7146_detach_extension (struct saa7146* saa, void *data) -{ - int ext_id = (int) data; - saa7146_ext[ext_id]->detach (saa, &saa->data[ext_id]); -} - - -int saa7146_add_extension(struct saa7146_extension* ext) -{ - int ext_id = 0; - - for (ext_id = 0; ext_id < SAA7146_MAX_EXTENSIONS; ext_id++) { - if (NULL == saa7146_ext[ext_id]) - break; - if (SAA7146_MAX_EXTENSIONS == ext_id) { - printk(KERN_WARNING "saa7146.o: attach_extension(%s) - " - "enlarge SAA7146_MAX_EXTENSIONS.\n",ext->name); - return -ENOMEM; - } - } - - saa7146_ext[ext_id] = ext; - saa7146_extension_count++; - - if (ext->attach) - saa7146_foreach (saa7146_attach_extension, (void*) ext_id); - - return 0; -} - - -int saa7146_del_extension(struct saa7146_extension* ext) -{ - int ext_id = 0; - - for (ext_id = 0; ext_id < SAA7146_MAX_EXTENSIONS; ext_id++) - if (ext == saa7146_ext[ext_id]) - break; - - if (SAA7146_MAX_EXTENSIONS == ext_id) { - printk("%s: detach_extension extension [%s] not found.\n", - __FUNCTION__, ext->name); - return -ENODEV; - } - - if (ext->detach) - saa7146_foreach (saa7146_detach_extension, (void*) ext_id); - - saa7146_ext[ext_id] = NULL; - saa7146_extension_count--; - - return 0; -} - - -static -void remove_saa7146(struct saa7146 *saa) -{ - i2c_saa7146_del_bus (saa); - - /* shut down all dma transfers */ - saa7146_write(saa->mem, MC1, 0xbfff0000); - - dprintk("free irqs\n"); - /* disable alle irqs, release irq-routine */ - saa7146_write(saa->mem, IER, 0x00); - saa7146_write(saa->mem, ISR, 0xffffffff); - free_irq(saa->device->irq, (void *)saa); - dprintk("unmap memory\n"); - /* unmap the memory, if necessary */ - if (saa->mem) - iounmap((unsigned char *)((unsigned int)saa->mem)); - - dprintk("release grabbing memory\n"); - /* release grabbing memory */ - if(saa->grabbing) - rvfree(saa->grabbing, buffers, &saa->page_table[0]); - - dprintk("release other memory\n"); - /* release clipping, i2c, rps0 memory */ - kfree(saa->clipping); - kfree(saa->i2c); - kfree(saa->rps0); - kfree(saa->rps1); - kfree(saa->debi); -} - - -static int saa7146_suspend(struct pci_dev *pdev, u32 state) -{ - printk("saa7146_suspend()\n"); - saa7146_core_command(((struct saa7146 *) pdev->driver_data)->i2c_bus, - SAA7146_SUSPEND, 0); - return 0; -} - -static int -saa7146_resume(struct pci_dev *pdev) -{ - printk("saa7146_resume()\n"); - saa7146_core_command(((struct saa7146 *) pdev->driver_data)->i2c_bus, - SAA7146_RESUME, 0); - return 0; -} - - -struct card_info { - int type; - char *name; -}; - - -static -int __devinit saa7146_init_one (struct pci_dev *pdev, - const struct pci_device_id *ent) -{ - struct dvb_adapter *adap; - struct saa7146 *saa; - int card_type; - struct card_info *cinfo= (struct card_info *) ent->driver_data; - - dprintk("saa7146_init_one()\n"); - - card_type = cinfo->type; - dvb_register_adapter(&adap, cinfo->name); - - if (!(saa = kmalloc (sizeof (struct saa7146), GFP_KERNEL))) { - printk ("%s: out of memory!\n", __FUNCTION__); - return -ENOMEM; - } - - memset (saa, 0, sizeof (struct saa7146)); - - saa->device = pdev; - saa->device->driver_data = saa; - saa->card_type = card_type; - saa->dvb_adapter = adap; - - pci_enable_device (saa->device); - - configure_saa7146 (saa); - - list_add_tail (&saa->list_head, &saa7146_list); - - return 0; -} - -static -void __devexit saa7146_remove_one (struct pci_dev *pdev) -{ - struct saa7146 *saa = pdev->driver_data; - - dprintk("saa7146_remove_one()\n"); - - list_del (&saa->list_head); - pci_disable_device(pdev); - remove_saa7146 (saa); -} - - -static struct card_info fs_1_5 = { DVB_CARD_TT_SIEMENS, "Siemens cable card PCI rev1.5" }; -static struct card_info fs_1_3 = { DVB_CARD_TT_SIEMENS, "Siemens/Technotrend/Hauppauge PCI rev1.3" }; -static struct card_info ttbs = { DVB_CARD_TT_BUDGET, "TT-Budget/WinTV-NOVA-S PCI" }; -static struct card_info ttbc = { DVB_CARD_TT_BUDGET, "TT-Budget/WinTV-NOVA-C PCI" }; -static struct card_info ttbt = { DVB_CARD_TT_BUDGET, "TT-Budget/WinTV-NOVA-T PCI" }; -static struct card_info ttbci = { DVB_CARD_TT_BUDGET_CI, "TT-Budget/WinTV-NOVA-CI PCI" }; -static struct card_info satel = { DVB_CARD_TT_BUDGET, "SATELCO Multimedia PCI"}; -static struct card_info unkwn0 = { DVB_CARD_TT_SIEMENS, "Technotrend/Hauppauge PCI rev?(unknown0)?"}; -static struct card_info unkwn1 = { DVB_CARD_TT_SIEMENS, "Technotrend/Hauppauge PCI rev?(unknown1)" }; -static struct card_info unkwn2 = { DVB_CARD_TT_SIEMENS, "Technotrend/Hauppauge PCI rev?(unknown2)" }; -static struct card_info tt_1_6 = { DVB_CARD_TT_SIEMENS, "Technotrend/Hauppauge PCI rev1.3 or 1.6" }; -static struct card_info tt_2_1 = { DVB_CARD_TT_SIEMENS, "Technotrend/Hauppauge PCI rev2.1 or 2.2" }; -static struct card_info tt_t = { DVB_CARD_TT_SIEMENS, "Technotrend/Hauppauge PCI DVB-T" }; -static struct card_info knc1 = { DVB_CARD_KNC1, "KNC1 DVB-S" }; - -#define PHILIPS_SAA7146 PCI_VENDOR_ID_PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7146 -#define CARD_INFO driver_data: (unsigned long) & - -static struct pci_device_id saa7146_pci_tbl[] __devinitdata = { - { PHILIPS_SAA7146, 0x110a, 0xffff, CARD_INFO fs_1_5 }, - { PHILIPS_SAA7146, 0x110a, 0x0000, CARD_INFO fs_1_5 }, - { PHILIPS_SAA7146, 0x13c2, 0x1003, CARD_INFO ttbs }, - { PHILIPS_SAA7146, 0x13c2, 0x1004, CARD_INFO ttbc }, - { PHILIPS_SAA7146, 0x13c2, 0x1005, CARD_INFO ttbt }, - { PHILIPS_SAA7146, 0x13c2, 0x100c, CARD_INFO ttbci }, - { PHILIPS_SAA7146, 0x13c2, 0x1013, CARD_INFO satel }, - { PHILIPS_SAA7146, 0x13c2, 0x0000, CARD_INFO fs_1_3 }, - { PHILIPS_SAA7146, 0x13c2, 0x1002, CARD_INFO unkwn0 }, - { PHILIPS_SAA7146, 0x13c2, 0x0001, CARD_INFO tt_1_6 }, - { PHILIPS_SAA7146, 0x13c2, 0x0002, CARD_INFO tt_2_1 }, - { PHILIPS_SAA7146, 0x13c2, 0x0003, CARD_INFO tt_2_1 }, - { PHILIPS_SAA7146, 0x13c2, 0x0004, CARD_INFO tt_2_1 }, - { PHILIPS_SAA7146, 0x13c2, 0x0006, CARD_INFO tt_1_6 }, - { PHILIPS_SAA7146, 0x13c2, 0x0008, CARD_INFO tt_t }, - { PHILIPS_SAA7146, 0xffc2, 0x0000, CARD_INFO unkwn1 }, - { PHILIPS_SAA7146, 0x00a1, 0x00a1, CARD_INFO unkwn2 }, - { PHILIPS_SAA7146, 0x1131, 0x4f56, CARD_INFO knc1 }, - { PHILIPS_SAA7146, 0x1131, 0x4f56, CARD_INFO knc1 }, - { 0,}, -}; - -MODULE_DEVICE_TABLE(pci, saa7146_pci_tbl); - -static struct pci_driver saa7146_driver = { - .name = "saa7146", - .id_table = saa7146_pci_tbl, - .probe = saa7146_init_one, - .remove = __devexit_p(saa7146_remove_one), - .suspend = saa7146_suspend, - .resume = saa7146_resume, -}; - - -static -int __init saa7146_init_module(void) -{ - int err; - - dprintk("saa7146_init_module\n"); - - if ((err = pci_module_init(&saa7146_driver))) - return err; - - if ((err = saa7146_v4l_init ())) - return err; - - if ((err = av7110_init ())) - return err; - - if ((err = av7110_ir_init ())) - return err; - - return 0; -} - -static -void __exit saa7146_cleanup_module(void) -{ - av7110_ir_exit (); - av7110_exit (); - saa7146_v4l_exit (); - pci_unregister_driver(&saa7146_driver); -} - -module_init(saa7146_init_module); -module_exit(saa7146_cleanup_module); - -MODULE_AUTHOR("Michael Hunold <michael@mihu.de>, " - "Christian Theiss <mistert@rz.fh-augsburg.de>, " - "Ralph Metzler <rjkm@convergence.de>, " - "Marcus Metzler <mocm@convergence.de>, " - "Holger Waechtler <holger@convergence.de> and others"); - -MODULE_DESCRIPTION("driver for saa7146/av7110 based DVB PCI cards"); -MODULE_LICENSE("GPL"); -MODULE_PARM(mode,"i"); -MODULE_PARM(saa7146_debug,"i"); -MODULE_PARM(buffers,"i"); - diff --git a/linux/drivers/media/dvb/av7110/saa7146_core.h b/linux/drivers/media/dvb/av7110/saa7146_core.h deleted file mode 100644 index 40d5ab0ff..000000000 --- a/linux/drivers/media/dvb/av7110/saa7146_core.h +++ /dev/null @@ -1,111 +0,0 @@ -#ifndef __SAA7146_CORE__ -#define __SAA7146_CORE__ - -#include <asm/io.h> -#include <asm/semaphore.h> - -#include "dvbdev.h" - - -/* maximum number of capture frames we support */ -#define SAA7146_MAX_BUF 5 -/* maximum number of extensions we support */ -#define SAA7146_MAX_EXTENSIONS 4 - -/* stuff for writing to saa7146 */ -#define saa7146_write(mem,adr,dat) writel((dat),(mem+(adr))) -#define saa7146_read(mem,adr) readl(mem+(adr)) - - -#define DVB_CARD_TT_SIEMENS 0 -#define DVB_CARD_TT_BUDGET 1 -#define DVB_CARD_TT_BUDGET_CI 2 -#define DVB_CARD_KNC1 3 - - -/* this struct contains some constants needed for horizontal and vertical scaling. - currently we only support PAL (mode=0)and NTSC (mode=1). */ - -struct saa7146 { - - char name[32]; /* give it a nice name */ - - struct list_head list_head; - struct pci_dev *device; - int card_type; - - struct dvb_adapter *dvb_adapter; - struct dvb_i2c_bus *i2c_bus; - struct semaphore i2c_sem; - - void* data[SAA7146_MAX_EXTENSIONS]; /* data hooks for extensions */ - - int (*command) (struct dvb_i2c_bus *i, unsigned int cmd, void *arg); - - unsigned char* mem; /* pointer to mapped IO memory */ - int revision; /* chip revision; needed for bug-workarounds*/ - - int interlace; - int mode; - - u32* i2c; /* i2c memory */ - u32* grabbing; /* grabbing memory */ - u32* clipping; /* clipping memory for mask or rectangle clipping*/ - u32* rps0; /* memory for rps0-program */ - u32* rps1; /* memory for rps1-program */ - u32* debi; /* memory for debi-transfers */ - - int buffers; /* number of grabbing-buffers */ - - u32* page_table[SAA7146_MAX_BUF]; /* page_tables for buffers*/ - int frame_stat[SAA7146_MAX_BUF]; /* status of grabbing buffers */ - - int grab_width[SAA7146_MAX_BUF]; /* pixel width of grabs */ - int grab_height[SAA7146_MAX_BUF]; /* pixel height of grabs */ - int grab_format[SAA7146_MAX_BUF]; /* video format of grabs */ - int grab_port[SAA7146_MAX_BUF]; /* video port for grab */ - - wait_queue_head_t rps0_wq; /* rps0 interrupt queue (=> capture) */ - wait_queue_head_t rps1_wq; /* rps1 interrupt queue (=> i2c, ...) */ -}; - -#define SAA7146_IRQ_RPS0 -#define SAA7146_IRQ_RPS1 - -struct saa7146_extension { - char name[32]; - u32 handles_irqs; - - void (*irq_handler)(struct saa7146*, u32, void*); - - int (*command)(struct saa7146*, void*, unsigned int cmd, void *arg); - - int (*attach)(struct saa7146*, void**); - int (*detach)(struct saa7146*, void**); - - void (*inc_use)(struct saa7146*); - void (*dec_use)(struct saa7146*); -}; - -extern int saa7146_add_extension(struct saa7146_extension* ext); -extern int saa7146_del_extension(struct saa7146_extension* ext); - - -/* external grabbing states */ -#define GBUFFER_UNUSED 0x000 -#define GBUFFER_GRABBING 0x001 -#define GBUFFER_DONE 0x002 - -#define SAA7146_CORE_BASE 200 - -#define SAA7146_DO_MMAP _IOW('d', (SAA7146_CORE_BASE+11), struct vm_area_struct *) -#define SAA7146_SET_DD1 _IOW('d', (SAA7146_CORE_BASE+12), u32) -#define SAA7146_DUMP_REGISTERS _IOW('d', (SAA7146_CORE_BASE+13), u32) -#define SAA7146_DEBI_TRANSFER _IOW('d', (SAA7146_CORE_BASE+14), struct saa7146_debi_transfer) - - -#define SAA7146_SUSPEND _IOW('d', (SAA7146_CORE_BASE+32), u32) -#define SAA7146_RESUME _IOW('d', (SAA7146_CORE_BASE+33), u32) - -#endif - diff --git a/linux/drivers/media/dvb/av7110/saa7146_defs.h b/linux/drivers/media/dvb/av7110/saa7146_defs.h deleted file mode 100644 index db19ee302..000000000 --- a/linux/drivers/media/dvb/av7110/saa7146_defs.h +++ /dev/null @@ -1,382 +0,0 @@ -#ifndef __INCLUDED_SAA7146__ -#define __INCLUDED_SAA7146__ - -struct saa7146_video_dma { - u32 base_odd; - u32 base_even; - u32 prot_addr; - u32 pitch; - u32 base_page; - u32 num_line_byte; -}; - -struct saa7146_debi_transfer { - - u8 timeout; /* have a look at the specs for reasonable values, p.110 ff */ - u8 swap; - u8 slave16; - u8 increment; /* only for block transfers */ - u8 intel; - u8 tien; - - u16 address; - u16 num_bytes; - u8 direction; - u32 mem; /* either a "pointer" (actually the physical address) of the debi-memory (block-transfer, use virt_to_bus to supply it) or 4 bytes (as one u32-value) for immediate transfer */ -}; - -struct saa7146_modes_constants { - u8 v_offset; - u16 v_field; - u16 v_calc; - - u8 h_offset; - u16 h_pixels; - u16 h_calc; - - u16 v_max_out; - u16 h_max_out; -}; - -struct saa7146_mmap_struct -{ - const char *adr; - unsigned long size; -}; - -#define SAA7146_PAL 0 -#define SAA7146_NTSC 1 -#define SAA7146_SECAM 2 - -#define SAA7146_HPS_SOURCE_PORT_A 0x00 -#define SAA7146_HPS_SOURCE_PORT_B 0x01 -#define SAA7146_HPS_SOURCE_YPB_CPA 0x02 -#define SAA7146_HPS_SOURCE_YPA_CPB 0x03 - -#define SAA7146_HPS_SYNC_PORT_A 0x00 -#define SAA7146_HPS_SYNC_PORT_B 0x01 - - -/* Number of vertical active lines */ -#define V_ACTIVE_LINES_PAL 576 -#define V_ACTIVE_LINES_NTSC 480 -#define V_ACTIVE_LINES_SECAM 576 - -/* Number of lines in a field for HPS to process */ -#define V_FIELD_PAL 288 -#define V_FIELD_NTSC 240 -#define V_FIELD_SECAM 288 - -/* Number of lines of vertical offset before processing */ -#define V_OFFSET_NTSC 0x10 /* PLI */ -#define V_OFFSET_PAL 0x15 -#define V_OFFSET_SECAM 0x14 - -/* Number of horizontal pixels to process */ -#define H_PIXELS_NTSC 708 -#define H_PIXELS_PAL 720 -#define H_PIXELS_SECAM 720 - -/* Horizontal offset of processing window */ -#define H_OFFSET_NTSC 0x40 /* PLI Try 0x3f and find all red colors turning into blue !!?? */ -#define H_OFFSET_PAL 0x3a -#define H_OFFSET_SECAM 0x14 - -/* some memory-sizes */ -#define GRABBING_MEM_SIZE 0x240000 /* 1024 * 576 * 4*/ -#define CLIPPING_MEM_SIZE 20000 /* 1024 * 625 / 32 */ -#define I2C_MEM_SIZE 0x000800 /* 2048 */ -#define RPS_MEM_SIZE 0x000800 /* 2048 */ - -/************************************************************************/ -/* UNSORTED */ -/************************************************************************/ - -#define ME1 0x0000000800 -#define PV1 0x0000000008 - -/************************************************************************/ -/* CLIPPING */ -/************************************************************************/ - -/* some defines for the various clipping-modes */ -#define SAA7146_CLIPPING_RECT 0x4 -#define SAA7146_CLIPPING_RECT_INVERTED 0x5 -#define SAA7146_CLIPPING_MASK 0x6 -#define SAA7146_CLIPPING_MASK_INVERTED 0x7 - -/************************************************************************/ -/* RPS */ -/************************************************************************/ - -#define CMD_NOP 0x00000000 /* No operation */ -#define CMD_CLR_EVENT 0x00000000 /* Clear event */ -#define CMD_SET_EVENT 0x10000000 /* Set signal event */ -#define CMD_PAUSE 0x20000000 /* Pause */ -#define CMD_CHECK_LATE 0x30000000 /* Check late */ -#define CMD_UPLOAD 0x40000000 /* Upload */ -#define CMD_STOP 0x50000000 /* Stop */ -#define CMD_INTERRUPT 0x60000000 /* Interrupt */ -#define CMD_JUMP 0x80000000 /* Jump */ -#define CMD_WR_REG 0x90000000 /* Write (load) register */ -#define CMD_RD_REG 0xa0000000 /* Read (store) register */ -#define CMD_WR_REG_MASK 0xc0000000 /* Write register with mask */ - -/************************************************************************/ -/* OUTPUT FORMATS */ -/************************************************************************/ - -/* output formats; each entry holds three types of information */ -/* composed is used in the sense of "not-planar" */ - -#define RGB15_COMPOSED 0x213 -/* this means: yuv2rgb-conversation-mode=2, dither=yes(=1), format-mode = 3 */ -#define RGB16_COMPOSED 0x210 -#define RGB24_COMPOSED 0x201 -#define RGB32_COMPOSED 0x202 - -#define YUV411_COMPOSED 0x003 -/* this means: yuv2rgb-conversation-mode=0, dither=no(=0), format-mode = 3 */ -#define YUV422_COMPOSED 0x000 -#define YUV411_DECOMPOSED 0x00b -#define YUV422_DECOMPOSED 0x009 -#define YUV420_DECOMPOSED 0x00a - -/************************************************************************/ -/* MISC */ -/************************************************************************/ - -/* Bit mask constants */ -#define MASK_00 0x00000001 /* Mask value for bit 0 */ -#define MASK_01 0x00000002 /* Mask value for bit 1 */ -#define MASK_02 0x00000004 /* Mask value for bit 2 */ -#define MASK_03 0x00000008 /* Mask value for bit 3 */ -#define MASK_04 0x00000010 /* Mask value for bit 4 */ -#define MASK_05 0x00000020 /* Mask value for bit 5 */ -#define MASK_06 0x00000040 /* Mask value for bit 6 */ -#define MASK_07 0x00000080 /* Mask value for bit 7 */ -#define MASK_08 0x00000100 /* Mask value for bit 8 */ -#define MASK_09 0x00000200 /* Mask value for bit 9 */ -#define MASK_10 0x00000400 /* Mask value for bit 10 */ -#define MASK_11 0x00000800 /* Mask value for bit 11 */ -#define MASK_12 0x00001000 /* Mask value for bit 12 */ -#define MASK_13 0x00002000 /* Mask value for bit 13 */ -#define MASK_14 0x00004000 /* Mask value for bit 14 */ -#define MASK_15 0x00008000 /* Mask value for bit 15 */ -#define MASK_16 0x00010000 /* Mask value for bit 16 */ -#define MASK_17 0x00020000 /* Mask value for bit 17 */ -#define MASK_18 0x00040000 /* Mask value for bit 18 */ -#define MASK_19 0x00080000 /* Mask value for bit 19 */ -#define MASK_20 0x00100000 /* Mask value for bit 20 */ -#define MASK_21 0x00200000 /* Mask value for bit 21 */ -#define MASK_22 0x00400000 /* Mask value for bit 22 */ -#define MASK_23 0x00800000 /* Mask value for bit 23 */ -#define MASK_24 0x01000000 /* Mask value for bit 24 */ -#define MASK_25 0x02000000 /* Mask value for bit 25 */ -#define MASK_26 0x04000000 /* Mask value for bit 26 */ -#define MASK_27 0x08000000 /* Mask value for bit 27 */ -#define MASK_28 0x10000000 /* Mask value for bit 28 */ -#define MASK_29 0x20000000 /* Mask value for bit 29 */ -#define MASK_30 0x40000000 /* Mask value for bit 30 */ -#define MASK_31 0x80000000 /* Mask value for bit 31 */ - -#define MASK_B0 0x000000ff /* Mask value for byte 0 */ -#define MASK_B1 0x0000ff00 /* Mask value for byte 1 */ -#define MASK_B2 0x00ff0000 /* Mask value for byte 2 */ -#define MASK_B3 0xff000000 /* Mask value for byte 3 */ - -#define MASK_W0 0x0000ffff /* Mask value for word 0 */ -#define MASK_W1 0xffff0000 /* Mask value for word 1 */ - -#define MASK_PA 0xfffffffc /* Mask value for physical address */ -#define MASK_PR 0xfffffffe /* Mask value for protection register */ -#define MASK_ER 0xffffffff /* Mask value for the entire register */ - -#define MASK_NONE 0x00000000 /* No mask */ - -/************************************************************************/ -/* REGISTERS */ -/************************************************************************/ - -#define BASE_ODD1 0x00 /* Video DMA 1 registers */ -#define BASE_EVEN1 0x04 -#define PROT_ADDR1 0x08 -#define PITCH1 0x0C -#define BASE_PAGE1 0x10 /* Video DMA 1 base page */ -#define NUM_LINE_BYTE1 0x14 - -#define BASE_ODD2 0x18 /* Video DMA 2 registers */ -#define BASE_EVEN2 0x1C -#define PROT_ADDR2 0x20 -#define PITCH2 0x24 -#define BASE_PAGE2 0x28 /* Video DMA 2 base page */ -#define NUM_LINE_BYTE2 0x2C - -#define BASE_ODD3 0x30 /* Video DMA 3 registers */ -#define BASE_EVEN3 0x34 -#define PROT_ADDR3 0x38 -#define PITCH3 0x3C -#define BASE_PAGE3 0x40 /* Video DMA 3 base page */ -#define NUM_LINE_BYTE3 0x44 - -#define PCI_BT_V1 0x48 /* Video/FIFO 1 */ -#define PCI_BT_V2 0x49 /* Video/FIFO 2 */ -#define PCI_BT_V3 0x4A /* Video/FIFO 3 */ -#define PCI_BT_DEBI 0x4B /* DEBI */ -#define PCI_BT_A 0x4C /* Audio */ - -#define DD1_INIT 0x50 /* Init setting of DD1 interface */ - -#define DD1_STREAM_B 0x54 /* DD1 B video data stream handling */ -#define DD1_STREAM_A 0x56 /* DD1 A video data stream handling */ - -#define BRS_CTRL 0x58 /* BRS control register */ -#define HPS_CTRL 0x5C /* HPS control register */ -#define HPS_V_SCALE 0x60 /* HPS vertical scale */ -#define HPS_V_GAIN 0x64 /* HPS vertical ACL and gain */ -#define HPS_H_PRESCALE 0x68 /* HPS horizontal prescale */ -#define HPS_H_SCALE 0x6C /* HPS horizontal scale */ -#define BCS_CTRL 0x70 /* BCS control */ -#define CHROMA_KEY_RANGE 0x74 -#define CLIP_FORMAT_CTRL 0x78 /* HPS outputs formats & clipping */ - -#define DEBI_CONFIG 0x7C -#define DEBI_COMMAND 0x80 -#define DEBI_PAGE 0x84 -#define DEBI_AD 0x88 - -#define I2C_TRANSFER 0x8C -#define I2C_STATUS 0x90 - -#define BASE_A1_IN 0x94 /* Audio 1 input DMA */ -#define PROT_A1_IN 0x98 -#define PAGE_A1_IN 0x9C - -#define BASE_A1_OUT 0xA0 /* Audio 1 output DMA */ -#define PROT_A1_OUT 0xA4 -#define PAGE_A1_OUT 0xA8 - -#define BASE_A2_IN 0xAC /* Audio 2 input DMA */ -#define PROT_A2_IN 0xB0 -#define PAGE_A2_IN 0xB4 - -#define BASE_A2_OUT 0xB8 /* Audio 2 output DMA */ -#define PROT_A2_OUT 0xBC -#define PAGE_A2_OUT 0xC0 - -#define RPS_PAGE0 0xC4 /* RPS task 0 page register */ -#define RPS_PAGE1 0xC8 /* RPS task 1 page register */ - -#define RPS_THRESH0 0xCC /* HBI threshold for task 0 */ -#define RPS_THRESH1 0xD0 /* HBI threshold for task 1 */ - -#define RPS_TOV0 0xD4 /* RPS timeout for task 0 */ -#define RPS_TOV1 0xD8 /* RPS timeout for task 1 */ - -#define IER 0xDC /* Interrupt enable register */ - -#define GPIO_CTRL 0xE0 /* GPIO 0-3 register */ - -#define EC1SSR 0xE4 /* Event cnt set 1 source select */ -#define EC2SSR 0xE8 /* Event cnt set 2 source select */ -#define ECT1R 0xEC /* Event cnt set 1 thresholds */ -#define ECT2R 0xF0 /* Event cnt set 2 thresholds */ - -#define ACON1 0xF4 -#define ACON2 0xF8 - -#define MC1 0xFC /* Main control register 1 */ -#define MC2 0x100 /* Main control register 2 */ - -#define RPS_ADDR0 0x104 /* RPS task 0 address register */ -#define RPS_ADDR1 0x108 /* RPS task 1 address register */ - -#define ISR 0x10C /* Interrupt status register */ -#define PSR 0x110 /* Primary status register */ -#define SSR 0x114 /* Secondary status register */ - -#define EC1R 0x118 /* Event counter set 1 register */ -#define EC2R 0x11C /* Event counter set 2 register */ - -#define PCI_VDP1 0x120 /* Video DMA pointer of FIFO 1 */ -#define PCI_VDP2 0x124 /* Video DMA pointer of FIFO 2 */ -#define PCI_VDP3 0x128 /* Video DMA pointer of FIFO 3 */ -#define PCI_ADP1 0x12C /* Audio DMA pointer of audio out 1 */ -#define PCI_ADP2 0x130 /* Audio DMA pointer of audio in 1 */ -#define PCI_ADP3 0x134 /* Audio DMA pointer of audio out 2 */ -#define PCI_ADP4 0x138 /* Audio DMA pointer of audio in 2 */ -#define PCI_DMA_DDP 0x13C /* DEBI DMA pointer */ - -#define LEVEL_REP 0x140, -#define A_TIME_SLOT1 0x180, /* from 180 - 1BC */ -#define A_TIME_SLOT2 0x1C0, /* from 1C0 - 1FC */ - -/************************************************************************/ -/* ISR-MASKS */ -/************************************************************************/ - -#define SPCI_PPEF 0x80000000 /* PCI parity error */ -#define SPCI_PABO 0x40000000 /* PCI access error (target or master abort) */ -#define SPCI_PPED 0x20000000 /* PCI parity error on 'real time data' */ -#define SPCI_RPS_I1 0x10000000 /* Interrupt issued by RPS1 */ -#define SPCI_RPS_I0 0x08000000 /* Interrupt issued by RPS0 */ -#define SPCI_RPS_LATE1 0x04000000 /* RPS task 1 is late */ -#define SPCI_RPS_LATE0 0x02000000 /* RPS task 0 is late */ -#define SPCI_RPS_E1 0x01000000 /* RPS error from task 1 */ -#define SPCI_RPS_E0 0x00800000 /* RPS error from task 0 */ -#define SPCI_RPS_TO1 0x00400000 /* RPS timeout task 1 */ -#define SPCI_RPS_TO0 0x00200000 /* RPS timeout task 0 */ -#define SPCI_UPLD 0x00100000 /* RPS in upload */ -#define SPCI_DEBI_S 0x00080000 /* DEBI status */ -#define SPCI_DEBI_E 0x00040000 /* DEBI error */ -#define SPCI_IIC_S 0x00020000 /* I2C status */ -#define SPCI_IIC_E 0x00010000 /* I2C error */ -#define SPCI_A2_IN 0x00008000 /* Audio 2 input DMA protection / limit */ -#define SPCI_A2_OUT 0x00004000 /* Audio 2 output DMA protection / limit */ -#define SPCI_A1_IN 0x00002000 /* Audio 1 input DMA protection / limit */ -#define SPCI_A1_OUT 0x00001000 /* Audio 1 output DMA protection / limit */ -#define SPCI_AFOU 0x00000800 /* Audio FIFO over- / underflow */ -#define SPCI_V_PE 0x00000400 /* Video protection address */ -#define SPCI_VFOU 0x00000200 /* Video FIFO over- / underflow */ -#define SPCI_FIDA 0x00000100 /* Field ID video port A */ -#define SPCI_FIDB 0x00000080 /* Field ID video port B */ -#define SPCI_PIN3 0x00000040 /* GPIO pin 3 */ -#define SPCI_PIN2 0x00000020 /* GPIO pin 2 */ -#define SPCI_PIN1 0x00000010 /* GPIO pin 1 */ -#define SPCI_PIN0 0x00000008 /* GPIO pin 0 */ -#define SPCI_ECS 0x00000004 /* Event counter 1, 2, 4, 5 */ -#define SPCI_EC3S 0x00000002 /* Event counter 3 */ -#define SPCI_EC0S 0x00000001 /* Event counter 0 */ - -/************************************************************************/ -/* I2C */ -/************************************************************************/ - -/* time we wait after certain i2c-operations */ -#define SAA7146_I2C_DELAY 10 - -#define SAA7146_I2C_ABORT (1<<7) -#define SAA7146_I2C_SPERR (1<<6) -#define SAA7146_I2C_APERR (1<<5) -#define SAA7146_I2C_DTERR (1<<4) -#define SAA7146_I2C_DRERR (1<<3) -#define SAA7146_I2C_AL (1<<2) -#define SAA7146_I2C_ERR (1<<1) -#define SAA7146_I2C_BUSY (1<<0) - -#define SAA7146_I2C_START (0x3) -#define SAA7146_I2C_CONT (0x2) -#define SAA7146_I2C_STOP (0x1) -#define SAA7146_I2C_NOP (0x0) - -#define SAA7146_I2C_BUS_BIT_RATE_6400 (0x500) -#define SAA7146_I2C_BUS_BIT_RATE_3200 (0x100) -#define SAA7146_I2C_BUS_BIT_RATE_480 (0x400) -#define SAA7146_I2C_BUS_BIT_RATE_320 (0x600) -#define SAA7146_I2C_BUS_BIT_RATE_240 (0x700) -#define SAA7146_I2C_BUS_BIT_RATE_120 (0x000) -#define SAA7146_I2C_BUS_BIT_RATE_80 (0x200) -#define SAA7146_I2C_BUS_BIT_RATE_60 (0x300) - - -#endif diff --git a/linux/drivers/media/dvb/av7110/saa7146_v4l.c b/linux/drivers/media/dvb/av7110/saa7146_v4l.c deleted file mode 100644 index 9a159f83a..000000000 --- a/linux/drivers/media/dvb/av7110/saa7146_v4l.c +++ /dev/null @@ -1,501 +0,0 @@ -/* - video4linux-parts of the saa7146 device driver - - Copyright (C) 1998,1999 Michael Hunold <michael@mihu.de> - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include <linux/module.h> /* for module-version */ -#include <linux/string.h> -#include <linux/slab.h> /* for kmalloc/kfree */ -#include <linux/delay.h> /* for delay-stuff */ -#include <asm/uaccess.h> /* for copy_to/from_user */ -#include <linux/wrapper.h> /* for mem_map_reserve */ -#include <linux/vmalloc.h> -#include <linux/videodev.h> - -#include "saa7146_defs.h" -#include "saa7146_core.h" -#include "saa7146_v4l.h" - - -static int saa7146_v4l_debug = 0; - -#define dprintk if (saa7146_v4l_debug) printk -#define hprintk if (saa7146_v4l_debug >= 2) printk -#define gprintk if (saa7146_v4l_debug >= 3) printk - -#define __COMPILE_SAA7146__ -#include "saa7146.c" - -/* transform video4linux-cliplist to plain arrays -- we assume that the arrays - are big enough -- if not: your fault! */ -int saa7146_v4lclip2plain(struct video_clip *clips, u16 clipcount, int x[], int y[], int width[], int height[]) -{ - int i = 0; - struct video_clip* vc = NULL; - - dprintk("saa7146_v4l.o: ==> saa7146_v4lclip2plain, cc:%d\n",clipcount); - - /* anything to do here? */ - if( 0 == clipcount ) - return 0; - - /* copy to kernel-space */ - vc = vmalloc(sizeof(struct video_clip)*(clipcount)); - if( NULL == vc ) { - printk("saa7146_v4l.o: ==> v4lclip2saa7146_v4l.o: no memory #2!\n"); - return -ENOMEM; - } - if(copy_from_user(vc,clips,sizeof(struct video_clip)*clipcount)) { - printk("saa7146_v4l.o: ==> v4lclip2saa7146_v4l.o: could not copy from user-space!\n"); - return -EFAULT; - } - - /* copy the clip-list to the arrays - note: the video_clip-struct may contain negative values to indicate that a window - doesn't lay completly over the video window. Thus, we correct the values right here */ - for(i = 0; i < clipcount; i++) { - - if( vc[i].width < 0) { - vc[i].x += vc[i].width; vc[i].width = -vc[i].width; - } - if( vc[i].height < 0) { - vc[i].y += vc[i].height; vc[i].height = -vc[i].height; - } - - if( vc[i].x < 0) { - vc[i].width += vc[i].x; vc[i].x = 0; - } - if( vc[i].y < 0) { - vc[i].height += vc[i].y; vc[i].y = 0; - } - - if(vc[i].width <= 0 || vc[i].height <= 0) { - vfree(vc); - return -EINVAL; - } - - x[i] = vc[i].x; - y[i] = vc[i].y; - width[i] = vc[i].width; - height[i] = vc[i].height; - } - - /* free memory used for temporary clips */ - vfree(vc); - - return 0; -} - -struct saa7146_v4l_struct { - struct video_buffer buffer; - struct video_mbuf mbuf; - struct video_window window; - struct video_picture picture; -}; - -static int saa7146_v4l_command(struct saa7146* saa, void *p, unsigned int cmd, void *arg) -{ - struct saa7146_v4l_struct* data = (struct saa7146_v4l_struct*)p; - - hprintk("saa7146_v4l.o: ==> saa7146_v4l_command\n"); - - if( NULL == saa) - return -EINVAL; - - switch(cmd) { - case SAA7146_V4L_GPICT: - { - struct video_picture *p = arg; - - hprintk(KERN_ERR "saa7146_v4l.o: SAA7146_V4L_GPICT\n"); - - memcpy(p, &data->picture, sizeof(struct video_picture)); - - } - break; - - case SAA7146_V4L_SPICT: - { - struct video_picture *p = arg; - - hprintk(KERN_ERR "saa7146_v4l.o: SAA7146_V4L_SPICT\n"); - - memcpy(&data->picture, p, sizeof(struct video_picture)); - set_picture_prop(saa, (u32)(data->picture.brightness>>8),(u32)(data->picture.contrast>>9),(u32)(data->picture.colour>>9)); - - } - break; - - case SAA7146_V4L_SWIN: - { - struct video_window *vw = arg; - int *x = NULL, *y = NULL, *w = NULL, *h = NULL; - - u32 palette = 0; - - hprintk(KERN_ERR "saa7146_v4l.o: SAA7146_V4L_SWIN\n"); - - video_setmode(saa, 0); - saa7146_write(saa->mem, MC1, (MASK_21)); - - set_window(saa, vw->width, vw->height,0,0,0); - //saa->port, saa->sync); - if (move_to(saa, vw->x, vw->y, vw->height, data->buffer.width, - data->buffer.depth, data->buffer.bytesperline, - (u32)data->buffer.base, 0)<0) - return -1; - - switch( data->picture.palette ) { - - case VIDEO_PALETTE_RGB555: - palette = RGB15_COMPOSED; - break; - - case VIDEO_PALETTE_RGB24: - palette = RGB24_COMPOSED; - break; - - case VIDEO_PALETTE_RGB32: - palette = RGB32_COMPOSED; - break; - - case VIDEO_PALETTE_UYVY: - palette = YUV422_COMPOSED; - break; - - case VIDEO_PALETTE_YUV422P: - palette = YUV422_DECOMPOSED; - break; - - case VIDEO_PALETTE_YUV420P: - palette = YUV420_DECOMPOSED; - break; - - case VIDEO_PALETTE_YUV411P: - palette = YUV411_DECOMPOSED; - break; - - default: - /*case VIDEO_PALETTE_RGB565:*/ - palette = RGB16_COMPOSED; - break; - } - - set_output_format(saa, palette); - - if (vw->flags==VIDEO_CLIP_BITMAP) { - clip_windows(saa, SAA7146_CLIPPING_MASK, vw->width, vw->height, - (u32 *) vw->clips, 1, 0, 0, 0, 0); - } else { - - - /* this is tricky, but helps us saving kmalloc/kfree-calls - and boring if/else-constructs ... */ - x = (int*)kmalloc(sizeof(int)*vw->clipcount*4,GFP_KERNEL); - if( NULL == x ) { - hprintk(KERN_ERR "saa7146_v4l.o: SAA7146_V4L_SWIN: out of kernel-memory.\n"); - return -ENOMEM; - } - y = x+(1*vw->clipcount); - w = x+(2*vw->clipcount); - h = x+(3*vw->clipcount); - - /* transform clipping-windows */ - if (0 != saa7146_v4lclip2plain(vw->clips, vw->clipcount,x,y,w,h)) - break; - clip_windows(saa, SAA7146_CLIPPING_RECT, vw->width, vw->height, - NULL, vw->clipcount, x, y, w, h); - kfree(x); - - memcpy(&data->window, arg, sizeof(struct video_window)); - } - video_setmode(saa, 1); - break; - } - - case SAA7146_V4L_CCAPTURE: - { - int* i = arg; - - hprintk(KERN_ERR "saa7146_v4l.o: SAA7146_V4L_CCAPTURE\n"); - - if ( 0 == *i ) { - video_setmode(saa, 0); - } - else { - video_setmode(saa, 1); - } - - break; - } - - case SAA7146_V4L_GFBUF: - { - struct video_buffer *b = arg; - - hprintk(KERN_ERR "saa7146_v4l.o: SAA7146_V4L_GFBUF\n"); - - memcpy(b, &data->buffer, sizeof(struct video_buffer)); - - break; - } - - case SAA7146_V4L_SFBUF: - { - struct video_buffer *b = arg; - - memcpy(&data->buffer, b, sizeof(struct video_buffer)); - hprintk(KERN_ERR "saa7146_v4l.o: SAA7146_V4L_SFBUF: b:0x%08x, h:%d, w:%d, d:%d\n", (u32)data->buffer.base, data->buffer.height, data->buffer.width, data->buffer.depth); - - break; - } - - - case SAA7146_V4L_CSYNC: - { - int i = *((int*)arg); - - int count = 0, k = 0; - unsigned char* grabbfr; - unsigned char y, uv; - - /* sanity checks */ - if ( i >= saa->buffers || i < 0) { - gprintk("saa7146_v4l.o: SAA7146_V4L_CSYNC, invalid buffer %d\n",i); - return -EINVAL; - } - - /* get the state */ - switch ( saa->frame_stat[i] ) { - case GBUFFER_UNUSED: - { - /* there was no grab to this buffer */ - gprintk(KERN_ERR "saa7146_v4l.o: SAA7146_V4L_CSYNC, invalid frame (fr:%d)\n",i); - return -EINVAL; - } - case GBUFFER_GRABBING: - { - /* wait to be woken up by the irq-handler */ - interruptible_sleep_on(&saa->rps0_wq); - break; - } - case GBUFFER_DONE: - { - gprintk(KERN_ERR "saa7146_v4l.o: SAA7146_V4L_CSYNC, frame done! (fr:%d)\n",i); - break; - } - } - - /* all saa7146´s below chip-revision 3 are not capable of - doing byte-swaps with video-dma1. for rgb-grabbing this - does not matter, but yuv422-grabbing has the wrong - byte-order, so we have to swap in software */ - if ( ( saa->revision<3) && - (saa->grab_format[i] == YUV422_COMPOSED)) { - /* swap UYVY to YUYV */ - count = saa->grab_height[i]*saa->grab_width[i]*2; - grabbfr = ((unsigned char*)(saa->grabbing))+i*GRABBING_MEM_SIZE; - for (k=0; k<count; k=k+2) { - y = grabbfr[k+1]; - uv = grabbfr[k]; - grabbfr[k] = y; - grabbfr[k+1] = uv; - } - } - - /* set corresponding buffer to ´unused´ */ - saa->frame_stat[i] = GBUFFER_UNUSED; - - break; - } - case SAA7146_V4L_CMCAPTURE: - { - struct video_mmap *vm = arg; - - gprintk(KERN_ERR "saa7146_v4l.o: SAA7146_V4L_CMCAPTURE, trying buffer:%d\n", vm->frame); - - /* check status for wanted frame */ - if ( GBUFFER_GRABBING == saa->frame_stat[vm->frame] ) { - gprintk("saa7146_v4l.o: frame #%d still grabbing!\n",vm->frame); - return -EBUSY; - } - - /* do necessary transformations from the videodev-structure to our own format. */ - - /* sanity checks */ - if ( vm->width <= 0 || vm->height <= 0 ) { - gprintk("saa7146_v4l.o: set_up_grabbing, invalid dimension for wanted buffer %d\n",vm->frame); - return -EINVAL; - } - - /* set corresponding buffer to ´grabbing´ */ - saa->frame_stat[vm->frame] = GBUFFER_GRABBING; - - /* copy grabbing informtaion for the buffer */ - saa->grab_height[vm->frame] = vm->height; - saa->grab_width[vm->frame] = vm->width; - /* fixme: setting of grabbing port ?!*/ - saa->grab_port[vm->frame] = 0; - - switch( vm->format ) { - - case VIDEO_PALETTE_RGB555: - saa->grab_format[vm->frame] = RGB15_COMPOSED; - break; - - case VIDEO_PALETTE_RGB24: - saa->grab_format[vm->frame] = RGB24_COMPOSED; - break; - - case VIDEO_PALETTE_RGB32: - saa->grab_format[vm->frame] = RGB32_COMPOSED; - break; - - case VIDEO_PALETTE_YUV420P: - return -EINVAL; - - case VIDEO_PALETTE_YUV422: - saa->grab_format[vm->frame] = YUV422_COMPOSED; - break; - - case VIDEO_PALETTE_YUV422P: - saa->grab_format[vm->frame] = YUV422_DECOMPOSED; - break; - - case VIDEO_PALETTE_YUV411P: - saa->grab_format[vm->frame] = YUV411_DECOMPOSED; - break; - - default: - /*case VIDEO_PALETTE_RGB565:*/ - saa->grab_format[vm->frame] = RGB16_COMPOSED; - break; - } - - set_up_grabbing(saa,vm->frame); - break; - } - case SAA7146_V4L_GMBUF: - { - struct video_mbuf *m = arg; - int i = 0; - - m->size = saa->buffers * GRABBING_MEM_SIZE; - m->frames = saa->buffers; - - for(i = 0; i < saa->buffers; i++) - m->offsets[i]=(i*GRABBING_MEM_SIZE); - - gprintk(KERN_ERR "saa7146_v4l.o: SAA7146_V4L_GMBUF, providing %d buffers.\n", saa->buffers); - - break; - } - - default: - return -ENOIOCTLCMD; - } - - return 0; -} - -int saa7146_v4l_attach(struct saa7146* adap, void** p) -{ - struct saa7146_v4l_struct* data; - - hprintk("saa7146_v4l.o: ==> saa7146_v4l_inc_use_attach\n"); - - if (!(data = kmalloc(sizeof(struct saa7146_v4l_struct), GFP_KERNEL))) { - printk (KERN_ERR "%s: out of memory!\n", __FUNCTION__); - return -ENOMEM; - } - *(struct saa7146_v4l_struct**)p = data; - - memset(&data->buffer, 0x0, sizeof(struct video_buffer)); - memset(&data->mbuf, 0x0, sizeof(struct video_mbuf)); - memset(&data->window, 0x0, sizeof(struct video_window)); - memset(&data->picture,0x0, sizeof(struct video_picture)); - - data->picture.brightness = 32768; - data->picture.contrast = 32768; - data->picture.colour = 32768; /* saturation */ - data->picture.depth = 16; - data->picture.palette = VIDEO_PALETTE_RGB565; - - return 0; -} - - -void saa7146_v4l_inc_use(struct saa7146* adap) -{ - MOD_INC_USE_COUNT; -} - - -int saa7146_v4l_detach(struct saa7146* adap, void** p) -{ - struct saa7146_v4l_struct** data = (struct saa7146_v4l_struct**)p; - - kfree(*data); - *data = NULL; - - return 0; -} - - -void saa7146_v4l_dec_use(struct saa7146* adap) -{ - MOD_DEC_USE_COUNT; -} - - -static struct saa7146_extension saa7146_v4l_extension = { - "v4l extension\0", - MASK_27, /* handles rps0 irqs */ - saa7146_std_grab_irq_callback_rps0, - saa7146_v4l_command, - saa7146_v4l_attach, - saa7146_v4l_detach, - saa7146_v4l_inc_use, - saa7146_v4l_dec_use -}; - - -int saa7146_v4l_init (void) -{ - int res = 0; - - if((res = saa7146_add_extension(&saa7146_v4l_extension))) { - printk("saa7146_v4l.o: extension registration failed, module not inserted.\n"); - return res; - } - - return 0; -} - - -void saa7146_v4l_exit (void) -{ - int res = 0; - if ((res = saa7146_del_extension(&saa7146_v4l_extension))) { - printk("saa7146_v4l.o: extension deregistration failed, module not removed.\n"); - } -} - -MODULE_PARM(saa7146_v4l_debug, "i"); -MODULE_PARM_DESC(saa7146_v4l_debug, "set saa7146_v4l.c in debug mode"); - diff --git a/linux/drivers/media/dvb/av7110/saa7146_v4l.h b/linux/drivers/media/dvb/av7110/saa7146_v4l.h deleted file mode 100644 index b9236252e..000000000 --- a/linux/drivers/media/dvb/av7110/saa7146_v4l.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef __INCLUDED_SAA7146_V4L_V4L__ -#define __INCLUDED_SAA7146_V4L_V4L__ - -/************************************************************************/ -/* ADDRESSING */ -/************************************************************************/ - -#define SAA7146_V4L_BASE 100 - -#define SAA7146_V4L_GPICT _IOW('d', (SAA7146_V4L_BASE+ 1), struct video_picture) -#define SAA7146_V4L_SPICT _IOW('d', (SAA7146_V4L_BASE+ 2), struct video_picture) - -#define SAA7146_V4L_GFBUF _IOW('d', (SAA7146_V4L_BASE+ 3), struct video_buffer) -#define SAA7146_V4L_SFBUF _IOW('d', (SAA7146_V4L_BASE+ 4), struct video_buffer) - -#define SAA7146_V4L_GMBUF _IOW('d', (SAA7146_V4L_BASE+ 5), struct video_mbuf) - -#define SAA7146_V4L_SWIN _IOW('d', (SAA7146_V4L_BASE+ 6), struct video_window) - -#define SAA7146_V4L_CCAPTURE _IOW('d', (SAA7146_V4L_BASE+ 7), int) - -#define SAA7146_V4L_CMCAPTURE _IOW('d', (SAA7146_V4L_BASE+ 8), struct video_mmap) -#define SAA7146_V4L_CSYNC _IOW('d', (SAA7146_V4L_BASE+ 9), int) -#define SAA7146_V4L_CGSTATUS _IOW('d', (SAA7146_V4L_BASE+10), int) - -#define SAA7146_V4L_TSCAPTURE _IOW('d', (SAA7146_V4L_BASE+11), int) - -extern int saa7146_v4l_init (void); -extern void saa7146_v4l_exit (void); - -#endif - |