diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-10-31 15:42:54 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-10-31 15:42:54 -0700 |
commit | 1eb63378354ac37b7e27d256bbf84684751bac32 (patch) | |
tree | 0775591a2dced778d1ba0bd8a946831e424d02d7 /drivers/staging | |
parent | 1a4ceab195e66bce9c1638fdded6d92988100ba4 (diff) | |
parent | bac2dacd5fb9ddad093d7a2dc5ab44e764874821 (diff) |
Merge branch 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media
* 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media: (348 commits)
[media] pctv452e: Remove bogus code
[media] adv7175: Make use of media bus pixel codes
[media] media: vb2: fix incorrect return value
[media] em28xx: implement VIDIOC_ENUM_FRAMESIZES
[media] cx23885: Stop the risc video fifo before reconfiguring it
[media] cx23885: Avoid incorrect error handling and reporting
[media] cx23885: Avoid stopping the risc engine during buffer timeout
[media] cx23885: Removed a spurious function cx23885_set_scale()
[media] cx23885: v4l2 api compliance, set the audioset field correctly
[media] cx23885: hook the audio selection functions into the main driver
[media] cx23885: add generic functions for dealing with audio input selection
[media] cx23885: fixes related to maximum number of inputs and range checking
[media] cx23885: Initial support for the MPX-885 mini-card
[media] cx25840: Ensure AUDIO6 and AUDIO7 trigger line-in baseband use
[media] cx23885: Enable audio line in support from the back panel
[media] cx23885: Allow the audio mux config to be specified on a per input basis
[media] cx25840: Enable support for non-tuner LR1/LR2 audio inputs
[media] cx23885: Name an internal i2c part and declare a bitfield by name
[media] cx23885: Ensure VBI buffers timeout quickly - bugfix for vbi hangs during streaming
[media] cx23885: remove channel dump diagnostics when a vbi buffer times out
...
Fix up trivial conflicts in drivers/misc/altera-stapl/altera.c (header
file rename vs add)
Diffstat (limited to 'drivers/staging')
28 files changed, 2 insertions, 11666 deletions
diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index a32961305723..d132c27dfb3f 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -34,8 +34,6 @@ source "drivers/staging/go7007/Kconfig" source "drivers/staging/cx25821/Kconfig" -source "drivers/staging/tm6000/Kconfig" - source "drivers/staging/cxd2099/Kconfig" source "drivers/staging/usbip/Kconfig" @@ -142,8 +140,6 @@ source "drivers/staging/ste_rmi4/Kconfig" source "drivers/staging/gma500/Kconfig" -source "drivers/staging/altera-stapl/Kconfig" - source "drivers/staging/mei/Kconfig" source "drivers/staging/nvec/Kconfig" diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index d7a5a04d0a2f..936b7c22e18e 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -8,7 +8,6 @@ obj-$(CONFIG_ET131X) += et131x/ obj-$(CONFIG_SLICOSS) += slicoss/ obj-$(CONFIG_VIDEO_GO7007) += go7007/ obj-$(CONFIG_VIDEO_CX25821) += cx25821/ -obj-$(CONFIG_VIDEO_TM6000) += tm6000/ obj-$(CONFIG_DVB_CXD2099) += cxd2099/ obj-$(CONFIG_LIRC_STAGING) += lirc/ obj-$(CONFIG_USBIP_CORE) += usbip/ @@ -59,7 +58,6 @@ obj-$(CONFIG_BCM_WIMAX) += bcm/ obj-$(CONFIG_FT1000) += ft1000/ obj-$(CONFIG_SND_INTEL_SST) += intel_sst/ obj-$(CONFIG_SPEAKUP) += speakup/ -obj-$(CONFIG_ALTERA_STAPL) +=altera-stapl/ obj-$(CONFIG_TOUCHSCREEN_CLEARPAD_TM1217) += cptm1217/ obj-$(CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4) += ste_rmi4/ obj-$(CONFIG_DRM_PSB) += gma500/ diff --git a/drivers/staging/altera-stapl/Kconfig b/drivers/staging/altera-stapl/Kconfig deleted file mode 100644 index b6537321ed72..000000000000 --- a/drivers/staging/altera-stapl/Kconfig +++ /dev/null @@ -1,6 +0,0 @@ -config ALTERA_STAPL - tristate "Altera FPGA firmware download module" - depends on I2C - default n - help - An Altera FPGA module. Say Y when you want to support this tool. diff --git a/drivers/staging/altera-stapl/Makefile b/drivers/staging/altera-stapl/Makefile deleted file mode 100644 index ddeede3c4b96..000000000000 --- a/drivers/staging/altera-stapl/Makefile +++ /dev/null @@ -1,3 +0,0 @@ -altera-stapl-y := altera-lpt.o altera-jtag.o altera-comp.o altera.o - -obj-$(CONFIG_ALTERA_STAPL) += altera-stapl.o diff --git a/drivers/staging/altera-stapl/altera-comp.c b/drivers/staging/altera-stapl/altera-comp.c deleted file mode 100644 index 49b103bedaaf..000000000000 --- a/drivers/staging/altera-stapl/altera-comp.c +++ /dev/null @@ -1,142 +0,0 @@ -/* - * altera-comp.c - * - * altera FPGA driver - * - * Copyright (C) Altera Corporation 1998-2001 - * Copyright (C) 2010 NetUP Inc. - * Copyright (C) 2010 Igor M. Liplianin <liplianin@netup.ru> - * - * 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/kernel.h> -#include "altera-exprt.h" - -#define SHORT_BITS 16 -#define CHAR_BITS 8 -#define DATA_BLOB_LENGTH 3 -#define MATCH_DATA_LENGTH 8192 -#define ALTERA_REQUEST_SIZE 1024 -#define ALTERA_BUFFER_SIZE (MATCH_DATA_LENGTH + ALTERA_REQUEST_SIZE) - -static u32 altera_bits_req(u32 n) -{ - u32 result = SHORT_BITS; - - if (n == 0) - result = 1; - else { - /* Look for the highest non-zero bit position */ - while ((n & (1 << (SHORT_BITS - 1))) == 0) { - n <<= 1; - --result; - } - } - - return result; -} - -static u32 altera_read_packed(u8 *buffer, u32 bits, u32 *bits_avail, - u32 *in_index) -{ - u32 result = 0; - u32 shift = 0; - u32 databyte = 0; - - while (bits > 0) { - databyte = buffer[*in_index]; - result |= (((databyte >> (CHAR_BITS - *bits_avail)) - & (0xff >> (CHAR_BITS - *bits_avail))) << shift); - - if (bits <= *bits_avail) { - result &= (0xffff >> (SHORT_BITS - (bits + shift))); - *bits_avail -= bits; - bits = 0; - } else { - ++(*in_index); - shift += *bits_avail; - bits -= *bits_avail; - *bits_avail = CHAR_BITS; - } - } - - return result; -} - -u32 altera_shrink(u8 *in, u32 in_length, u8 *out, u32 out_length, s32 version) -{ - u32 i, j, data_length = 0L; - u32 offset, length; - u32 match_data_length = MATCH_DATA_LENGTH; - u32 bits_avail = CHAR_BITS; - u32 in_index = 0L; - - if (version > 0) - --match_data_length; - - for (i = 0; i < out_length; ++i) - out[i] = 0; - - /* Read number of bytes in data. */ - for (i = 0; i < sizeof(in_length); ++i) { - data_length = data_length | ( - altera_read_packed(in, - CHAR_BITS, - &bits_avail, - &in_index) << (i * CHAR_BITS)); - } - - if (data_length > out_length) { - data_length = 0L; - return data_length; - } - - i = 0; - while (i < data_length) { - /* A 0 bit indicates literal data. */ - if (altera_read_packed(in, 1, &bits_avail, - &in_index) == 0) { - for (j = 0; j < DATA_BLOB_LENGTH; ++j) { - if (i < data_length) { - out[i] = (u8)altera_read_packed(in, - CHAR_BITS, - &bits_avail, - &in_index); - i++; - } - } - } else { - /* A 1 bit indicates offset/length to follow. */ - offset = altera_read_packed(in, altera_bits_req((s16) - (i > match_data_length ? - match_data_length : i)), - &bits_avail, - &in_index); - length = altera_read_packed(in, CHAR_BITS, - &bits_avail, - &in_index); - for (j = 0; j < length; ++j) { - if (i < data_length) { - out[i] = out[i - offset]; - i++; - } - } - } - } - - return data_length; -} diff --git a/drivers/staging/altera-stapl/altera-exprt.h b/drivers/staging/altera-stapl/altera-exprt.h deleted file mode 100644 index 39c38d84a670..000000000000 --- a/drivers/staging/altera-stapl/altera-exprt.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * altera-exprt.h - * - * altera FPGA driver - * - * Copyright (C) Altera Corporation 1998-2001 - * Copyright (C) 2010 NetUP Inc. - * Copyright (C) 2010 Igor M. Liplianin <liplianin@netup.ru> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef ALTERA_EXPRT_H -#define ALTERA_EXPRT_H - - -u32 altera_shrink(u8 *in, u32 in_length, u8 *out, u32 out_length, s32 version); -int netup_jtag_io_lpt(void *device, int tms, int tdi, int read_tdo); - -#endif /* ALTERA_EXPRT_H */ diff --git a/drivers/staging/altera-stapl/altera-jtag.c b/drivers/staging/altera-stapl/altera-jtag.c deleted file mode 100644 index 8b1620b1b2d0..000000000000 --- a/drivers/staging/altera-stapl/altera-jtag.c +++ /dev/null @@ -1,1021 +0,0 @@ -/* - * altera-jtag.c - * - * altera FPGA driver - * - * Copyright (C) Altera Corporation 1998-2001 - * Copyright (C) 2010 NetUP Inc. - * Copyright (C) 2010 Igor M. Liplianin <liplianin@netup.ru> - * - * 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/delay.h> -#include <linux/firmware.h> -#include <linux/slab.h> -#include "altera.h" -#include "altera-exprt.h" -#include "altera-jtag.h" - -#define alt_jtag_io(a, b, c)\ - astate->config->jtag_io(astate->config->dev, a, b, c); - -#define alt_malloc(a) kzalloc(a, GFP_KERNEL); - -/* - * This structure shows, for each JTAG state, which state is reached after - * a single TCK clock cycle with TMS high or TMS low, respectively. This - * describes all possible state transitions in the JTAG state machine. - */ -struct altera_jtag_machine { - enum altera_jtag_state tms_high; - enum altera_jtag_state tms_low; -}; - -static const struct altera_jtag_machine altera_transitions[] = { - /* RESET */ { RESET, IDLE }, - /* IDLE */ { DRSELECT, IDLE }, - /* DRSELECT */ { IRSELECT, DRCAPTURE }, - /* DRCAPTURE */ { DREXIT1, DRSHIFT }, - /* DRSHIFT */ { DREXIT1, DRSHIFT }, - /* DREXIT1 */ { DRUPDATE, DRPAUSE }, - /* DRPAUSE */ { DREXIT2, DRPAUSE }, - /* DREXIT2 */ { DRUPDATE, DRSHIFT }, - /* DRUPDATE */ { DRSELECT, IDLE }, - /* IRSELECT */ { RESET, IRCAPTURE }, - /* IRCAPTURE */ { IREXIT1, IRSHIFT }, - /* IRSHIFT */ { IREXIT1, IRSHIFT }, - /* IREXIT1 */ { IRUPDATE, IRPAUSE }, - /* IRPAUSE */ { IREXIT2, IRPAUSE }, - /* IREXIT2 */ { IRUPDATE, IRSHIFT }, - /* IRUPDATE */ { DRSELECT, IDLE } -}; - -/* - * This table contains the TMS value to be used to take the NEXT STEP on - * the path to the desired state. The array index is the current state, - * and the bit position is the desired endstate. To find out which state - * is used as the intermediate state, look up the TMS value in the - * altera_transitions[] table. - */ -static const u16 altera_jtag_path_map[16] = { - /* RST RTI SDRS CDR SDR E1DR PDR E2DR */ - 0x0001, 0xFFFD, 0xFE01, 0xFFE7, 0xFFEF, 0xFF0F, 0xFFBF, 0xFFFF, - /* UDR SIRS CIR SIR E1IR PIR E2IR UIR */ - 0xFEFD, 0x0001, 0xF3FF, 0xF7FF, 0x87FF, 0xDFFF, 0xFFFF, 0x7FFD -}; - -/* Flag bits for alt_jtag_io() function */ -#define TMS_HIGH 1 -#define TMS_LOW 0 -#define TDI_HIGH 1 -#define TDI_LOW 0 -#define READ_TDO 1 -#define IGNORE_TDO 0 - -int altera_jinit(struct altera_state *astate) -{ - struct altera_jtag *js = &astate->js; - - /* initial JTAG state is unknown */ - js->jtag_state = ILLEGAL_JTAG_STATE; - - /* initialize to default state */ - js->drstop_state = IDLE; - js->irstop_state = IDLE; - js->dr_pre = 0; - js->dr_post = 0; - js->ir_pre = 0; - js->ir_post = 0; - js->dr_length = 0; - js->ir_length = 0; - - js->dr_pre_data = NULL; - js->dr_post_data = NULL; - js->ir_pre_data = NULL; - js->ir_post_data = NULL; - js->dr_buffer = NULL; - js->ir_buffer = NULL; - - return 0; -} - -int altera_set_drstop(struct altera_jtag *js, enum altera_jtag_state state) -{ - js->drstop_state = state; - - return 0; -} - -int altera_set_irstop(struct altera_jtag *js, enum altera_jtag_state state) -{ - js->irstop_state = state; - - return 0; -} - -int altera_set_dr_pre(struct altera_jtag *js, - u32 count, u32 start_index, - u8 *preamble_data) -{ - int status = 0; - u32 i; - u32 j; - - if (count > js->dr_pre) { - kfree(js->dr_pre_data); - js->dr_pre_data = (u8 *)alt_malloc((count + 7) >> 3); - if (js->dr_pre_data == NULL) - status = -ENOMEM; - else - js->dr_pre = count; - } else - js->dr_pre = count; - - if (status == 0) { - for (i = 0; i < count; ++i) { - j = i + start_index; - - if (preamble_data == NULL) - js->dr_pre_data[i >> 3] |= (1 << (i & 7)); - else { - if (preamble_data[j >> 3] & (1 << (j & 7))) - js->dr_pre_data[i >> 3] |= - (1 << (i & 7)); - else - js->dr_pre_data[i >> 3] &= - ~(u32)(1 << (i & 7)); - - } - } - } - - return status; -} - -int altera_set_ir_pre(struct altera_jtag *js, u32 count, u32 start_index, - u8 *preamble_data) -{ - int status = 0; - u32 i; - u32 j; - - if (count > js->ir_pre) { - kfree(js->ir_pre_data); - js->ir_pre_data = (u8 *)alt_malloc((count + 7) >> 3); - if (js->ir_pre_data == NULL) - status = -ENOMEM; - else - js->ir_pre = count; - - } else - js->ir_pre = count; - - if (status == 0) { - for (i = 0; i < count; ++i) { - j = i + start_index; - if (preamble_data == NULL) - js->ir_pre_data[i >> 3] |= (1 << (i & 7)); - else { - if (preamble_data[j >> 3] & (1 << (j & 7))) - js->ir_pre_data[i >> 3] |= - (1 << (i & 7)); - else - js->ir_pre_data[i >> 3] &= - ~(u32)(1 << (i & 7)); - - } - } - } - - return status; -} - -int altera_set_dr_post(struct altera_jtag *js, u32 count, u32 start_index, - u8 *postamble_data) -{ - int status = 0; - u32 i; - u32 j; - - if (count > js->dr_post) { - kfree(js->dr_post_data); - js->dr_post_data = (u8 *)alt_malloc((count + 7) >> 3); - - if (js->dr_post_data == NULL) - status = -ENOMEM; - else - js->dr_post = count; - - } else - js->dr_post = count; - - if (status == 0) { - for (i = 0; i < count; ++i) { - j = i + start_index; - - if (postamble_data == NULL) - js->dr_post_data[i >> 3] |= (1 << (i & 7)); - else { - if (postamble_data[j >> 3] & (1 << (j & 7))) - js->dr_post_data[i >> 3] |= - (1 << (i & 7)); - else - js->dr_post_data[i >> 3] &= - ~(u32)(1 << (i & 7)); - - } - } - } - - return status; -} - -int altera_set_ir_post(struct altera_jtag *js, u32 count, u32 start_index, - u8 *postamble_data) -{ - int status = 0; - u32 i; - u32 j; - - if (count > js->ir_post) { - kfree(js->ir_post_data); - js->ir_post_data = (u8 *)alt_malloc((count + 7) >> 3); - if (js->ir_post_data == NULL) - status = -ENOMEM; - else - js->ir_post = count; - - } else - js->ir_post = count; - - if (status != 0) - return status; - - for (i = 0; i < count; ++i) { - j = i + start_index; - - if (postamble_data == NULL) - js->ir_post_data[i >> 3] |= (1 << (i & 7)); - else { - if (postamble_data[j >> 3] & (1 << (j & 7))) - js->ir_post_data[i >> 3] |= (1 << (i & 7)); - else - js->ir_post_data[i >> 3] &= - ~(u32)(1 << (i & 7)); - - } - } - - return status; -} - -static void altera_jreset_idle(struct altera_state *astate) -{ - struct altera_jtag *js = &astate->js; - int i; - /* Go to Test Logic Reset (no matter what the starting state may be) */ - for (i = 0; i < 5; ++i) - alt_jtag_io(TMS_HIGH, TDI_LOW, IGNORE_TDO); - - /* Now step to Run Test / Idle */ - alt_jtag_io(TMS_LOW, TDI_LOW, IGNORE_TDO); - js->jtag_state = IDLE; -} - -int altera_goto_jstate(struct altera_state *astate, - enum altera_jtag_state state) -{ - struct altera_jtag *js = &astate->js; - int tms; - int count = 0; - int status = 0; - - if (js->jtag_state == ILLEGAL_JTAG_STATE) - /* initialize JTAG chain to known state */ - altera_jreset_idle(astate); - - if (js->jtag_state == state) { - /* - * We are already in the desired state. - * If it is a stable state, loop here. - * Otherwise do nothing (no clock cycles). - */ - if ((state == IDLE) || (state == DRSHIFT) || - (state == DRPAUSE) || (state == IRSHIFT) || - (state == IRPAUSE)) { - alt_jtag_io(TMS_LOW, TDI_LOW, IGNORE_TDO); - } else if (state == RESET) - alt_jtag_io(TMS_HIGH, TDI_LOW, IGNORE_TDO); - - } else { - while ((js->jtag_state != state) && (count < 9)) { - /* Get TMS value to take a step toward desired state */ - tms = (altera_jtag_path_map[js->jtag_state] & - (1 << state)) - ? TMS_HIGH : TMS_LOW; - - /* Take a step */ - alt_jtag_io(tms, TDI_LOW, IGNORE_TDO); - - if (tms) - js->jtag_state = - altera_transitions[js->jtag_state].tms_high; - else - js->jtag_state = - altera_transitions[js->jtag_state].tms_low; - - ++count; - } - } - - if (js->jtag_state != state) - status = -EREMOTEIO; - - return status; -} - -int altera_wait_cycles(struct altera_state *astate, - s32 cycles, - enum altera_jtag_state wait_state) -{ - struct altera_jtag *js = &astate->js; - int tms; - s32 count; - int status = 0; - - if (js->jtag_state != wait_state) - status = altera_goto_jstate(astate, wait_state); - - if (status == 0) { - /* - * Set TMS high to loop in RESET state - * Set TMS low to loop in any other stable state - */ - tms = (wait_state == RESET) ? TMS_HIGH : TMS_LOW; - - for (count = 0L; count < cycles; count++) - alt_jtag_io(tms, TDI_LOW, IGNORE_TDO); - - } - - return status; -} - -int altera_wait_msecs(struct altera_state *astate, - s32 microseconds, enum altera_jtag_state wait_state) -/* - * Causes JTAG hardware to sit in the specified stable - * state for the specified duration of real time. If - * no JTAG operations have been performed yet, then only - * a delay is performed. This permits the WAIT USECS - * statement to be used in VECTOR programs without causing - * any JTAG operations. - * Returns 0 for success, else appropriate error code. - */ -{ - struct altera_jtag *js = &astate->js; - int status = 0; - - if ((js->jtag_state != ILLEGAL_JTAG_STATE) && - (js->jtag_state != wait_state)) - status = altera_goto_jstate(astate, wait_state); - - if (status == 0) - /* Wait for specified time interval */ - udelay(microseconds); - - return status; -} - -static void altera_concatenate_data(u8 *buffer, - u8 *preamble_data, - u32 preamble_count, - u8 *target_data, - u32 start_index, - u32 target_count, - u8 *postamble_data, - u32 postamble_count) -/* - * Copies preamble data, target data, and postamble data - * into one buffer for IR or DR scans. - */ -{ - u32 i, j, k; - - for (i = 0L; i < preamble_count; ++i) { - if (preamble_data[i >> 3L] & (1L << (i & 7L))) - buffer[i >> 3L] |= (1L << (i & 7L)); - else - buffer[i >> 3L] &= ~(u32)(1L << (i & 7L)); - - } - - j = start_index; - k = preamble_count + target_count; - for (; i < k; ++i, ++j) { - if (target_data[j >> 3L] & (1L << (j & 7L))) - buffer[i >> 3L] |= (1L << (i & 7L)); - else - buffer[i >> 3L] &= ~(u32)(1L << (i & 7L)); - - } - - j = 0L; - k = preamble_count + target_count + postamble_count; - for (; i < k; ++i, ++j) { - if (postamble_data[j >> 3L] & (1L << (j & 7L))) - buffer[i >> 3L] |= (1L << (i & 7L)); - else - buffer[i >> 3L] &= ~(u32)(1L << (i & 7L)); - - } -} - -static int alt_jtag_drscan(struct altera_state *astate, - int start_state, - int count, - u8 *tdi, - u8 *tdo) -{ - int i = 0; - int tdo_bit = 0; - int status = 1; - - /* First go to DRSHIFT state */ - switch (start_state) { - case 0: /* IDLE */ - alt_jtag_io(1, 0, 0); /* DRSELECT */ - alt_jtag_io(0, 0, 0); /* DRCAPTURE */ - alt_jtag_io(0, 0, 0); /* DRSHIFT */ - break; - - case 1: /* DRPAUSE */ - alt_jtag_io(1, 0, 0); /* DREXIT2 */ - alt_jtag_io(1, 0, 0); /* DRUPDATE */ - alt_jtag_io(1, 0, 0); /* DRSELECT */ - alt_jtag_io(0, 0, 0); /* DRCAPTURE */ - alt_jtag_io(0, 0, 0); /* DRSHIFT */ - break; - - case 2: /* IRPAUSE */ - alt_jtag_io(1, 0, 0); /* IREXIT2 */ - alt_jtag_io(1, 0, 0); /* IRUPDATE */ - alt_jtag_io(1, 0, 0); /* DRSELECT */ - alt_jtag_io(0, 0, 0); /* DRCAPTURE */ - alt_jtag_io(0, 0, 0); /* DRSHIFT */ - break; - - default: - status = 0; - } - - if (status) { - /* loop in the SHIFT-DR state */ - for (i = 0; i < count; i++) { - tdo_bit = alt_jtag_io( - (i == count - 1), - tdi[i >> 3] & (1 << (i & 7)), - (tdo != NULL)); - - if (tdo != NULL) { - if (tdo_bit) - tdo[i >> 3] |= (1 << (i & 7)); - else - tdo[i >> 3] &= ~(u32)(1 << (i & 7)); - - } - } - - alt_jtag_io(0, 0, 0); /* DRPAUSE */ - } - - return status; -} - -static int alt_jtag_irscan(struct altera_state *astate, - int start_state, - int count, - u8 *tdi, - u8 *tdo) -{ - int i = 0; - int tdo_bit = 0; - int status = 1; - - /* First go to IRSHIFT state */ - switch (start_state) { - case 0: /* IDLE */ - alt_jtag_io(1, 0, 0); /* DRSELECT */ - alt_jtag_io(1, 0, 0); /* IRSELECT */ - alt_jtag_io(0, 0, 0); /* IRCAPTURE */ - alt_jtag_io(0, 0, 0); /* IRSHIFT */ - break; - - case 1: /* DRPAUSE */ - alt_jtag_io(1, 0, 0); /* DREXIT2 */ - alt_jtag_io(1, 0, 0); /* DRUPDATE */ - alt_jtag_io(1, 0, 0); /* DRSELECT */ - alt_jtag_io(1, 0, 0); /* IRSELECT */ - alt_jtag_io(0, 0, 0); /* IRCAPTURE */ - alt_jtag_io(0, 0, 0); /* IRSHIFT */ - break; - - case 2: /* IRPAUSE */ - alt_jtag_io(1, 0, 0); /* IREXIT2 */ - alt_jtag_io(1, 0, 0); /* IRUPDATE */ - alt_jtag_io(1, 0, 0); /* DRSELECT */ - alt_jtag_io(1, 0, 0); /* IRSELECT */ - alt_jtag_io(0, 0, 0); /* IRCAPTURE */ - alt_jtag_io(0, 0, 0); /* IRSHIFT */ - break; - - default: - status = 0; - } - - if (status) { - /* loop in the SHIFT-IR state */ - for (i = 0; i < count; i++) { - tdo_bit = alt_jtag_io( - (i == count - 1), - tdi[i >> 3] & (1 << (i & 7)), - (tdo != NULL)); - if (tdo != NULL) { - if (tdo_bit) - tdo[i >> 3] |= (1 << (i & 7)); - else - tdo[i >> 3] &= ~(u32)(1 << (i & 7)); - - } - } - - alt_jtag_io(0, 0, 0); /* IRPAUSE */ - } - - return status; -} - -static void altera_extract_target_data(u8 *buffer, - u8 *target_data, - u32 start_index, - u32 preamble_count, - u32 target_count) -/* - * Copies target data from scan buffer, filtering out - * preamble and postamble data. - */ -{ - u32 i; - u32 j; - u32 k; - - j = preamble_count; - k = start_index + target_count; - for (i = start_index; i < k; ++i, ++j) { - if (buffer[j >> 3] & (1 << (j & 7))) - target_data[i >> 3] |= (1 << (i & 7)); - else - target_data[i >> 3] &= ~(u32)(1 << (i & 7)); - - } -} - -int altera_irscan(struct altera_state *astate, - u32 count, - u8 *tdi_data, - u32 start_index) -/* Shifts data into instruction register */ -{ - struct altera_jtag *js = &astate->js; - int start_code = 0; - u32 alloc_chars = 0; - u32 shift_count = js->ir_pre + count + js->ir_post; - int status = 0; - enum altera_jtag_state start_state = ILLEGAL_JTAG_STATE; - - switch (js->jtag_state) { - case ILLEGAL_JTAG_STATE: - case RESET: - case IDLE: - start_code = 0; - start_state = IDLE; - break; - - case DRSELECT: - case DRCAPTURE: - case DRSHIFT: - case DREXIT1: - case DRPAUSE: - case DREXIT2: - case DRUPDATE: - start_code = 1; - start_state = DRPAUSE; - break; - - case IRSELECT: - case IRCAPTURE: - case IRSHIFT: - case IREXIT1: - case IRPAUSE: - case IREXIT2: - case IRUPDATE: - start_code = 2; - start_state = IRPAUSE; - break; - - default: - status = -EREMOTEIO; - break; - } - - if (status == 0) - if (js->jtag_state != start_state) - status = altera_goto_jstate(astate, start_state); - - if (status == 0) { - if (shift_count > js->ir_length) { - alloc_chars = (shift_count + 7) >> 3; - kfree(js->ir_buffer); - js->ir_buffer = (u8 *)alt_malloc(alloc_chars); - if (js->ir_buffer == NULL) - status = -ENOMEM; - else - js->ir_length = alloc_chars * 8; - - } - } - - if (status == 0) { - /* - * Copy preamble data, IR data, - * and postamble data into a buffer - */ - altera_concatenate_data(js->ir_buffer, - js->ir_pre_data, - js->ir_pre, - tdi_data, - start_index, - count, - js->ir_post_data, - js->ir_post); - /* Do the IRSCAN */ - alt_jtag_irscan(astate, - start_code, - shift_count, - js->ir_buffer, - NULL); - - /* alt_jtag_irscan() always ends in IRPAUSE state */ - js->jtag_state = IRPAUSE; - } - - if (status == 0) - if (js->irstop_state != IRPAUSE) - status = altera_goto_jstate(astate, js->irstop_state); - - - return status; -} - -int altera_swap_ir(struct altera_state *astate, - u32 count, - u8 *in_data, - u32 in_index, - u8 *out_data, - u32 out_index) -/* Shifts data into instruction register, capturing output data */ -{ - struct altera_jtag *js = &astate->js; - int start_code = 0; - u32 alloc_chars = 0; - u32 shift_count = js->ir_pre + count + js->ir_post; - int status = 0; - enum altera_jtag_state start_state = ILLEGAL_JTAG_STATE; - - switch (js->jtag_state) { - case ILLEGAL_JTAG_STATE: - case RESET: - case IDLE: - start_code = 0; - start_state = IDLE; - break; - - case DRSELECT: - case DRCAPTURE: - case DRSHIFT: - case DREXIT1: - case DRPAUSE: - case DREXIT2: - case DRUPDATE: - start_code = 1; - start_state = DRPAUSE; - break; - - case IRSELECT: - case IRCAPTURE: - case IRSHIFT: - case IREXIT1: - case IRPAUSE: - case IREXIT2: - case IRUPDATE: - start_code = 2; - start_state = IRPAUSE; - break; - - default: - status = -EREMOTEIO; - break; - } - - if (status == 0) - if (js->jtag_state != start_state) - status = altera_goto_jstate(astate, start_state); - - if (status == 0) { - if (shift_count > js->ir_length) { - alloc_chars = (shift_count + 7) >> 3; - kfree(js->ir_buffer); - js->ir_buffer = (u8 *)alt_malloc(alloc_chars); - if (js->ir_buffer == NULL) - status = -ENOMEM; - else - js->ir_length = alloc_chars * 8; - - } - } - - if (status == 0) { - /* - * Copy preamble data, IR data, - * and postamble data into a buffer - */ - altera_concatenate_data(js->ir_buffer, - js->ir_pre_data, - js->ir_pre, - in_data, - in_index, - count, - js->ir_post_data, - js->ir_post); - - /* Do the IRSCAN */ - alt_jtag_irscan(astate, - start_code, - shift_count, - js->ir_buffer, - js->ir_buffer); - - /* alt_jtag_irscan() always ends in IRPAUSE state */ - js->jtag_state = IRPAUSE; - } - - if (status == 0) - if (js->irstop_state != IRPAUSE) - status = altera_goto_jstate(astate, js->irstop_state); - - - if (status == 0) - /* Now extract the returned data from the buffer */ - altera_extract_target_data(js->ir_buffer, - out_data, out_index, - js->ir_pre, count); - - return status; -} - -int altera_drscan(struct altera_state *astate, - u32 count, - u8 *tdi_data, - u32 start_index) -/* Shifts data into data register (ignoring output data) */ -{ - struct altera_jtag *js = &astate->js; - int start_code = 0; - u32 alloc_chars = 0; - u32 shift_count = js->dr_pre + count + js->dr_post; - int status = 0; - enum altera_jtag_state start_state = ILLEGAL_JTAG_STATE; - - switch (js->jtag_state) { - case ILLEGAL_JTAG_STATE: - case RESET: - case IDLE: - start_code = 0; - start_state = IDLE; - break; - - case DRSELECT: - case DRCAPTURE: - case DRSHIFT: - case DREXIT1: - case DRPAUSE: - case DREXIT2: - case DRUPDATE: - start_code = 1; - start_state = DRPAUSE; - break; - - case IRSELECT: - case IRCAPTURE: - case IRSHIFT: - case IREXIT1: - case IRPAUSE: - case IREXIT2: - case IRUPDATE: - start_code = 2; - start_state = IRPAUSE; - break; - - default: - status = -EREMOTEIO; - break; - } - - if (status == 0) - if (js->jtag_state != start_state) - status = altera_goto_jstate(astate, start_state); - - if (status == 0) { - if (shift_count > js->dr_length) { - alloc_chars = (shift_count + 7) >> 3; - kfree(js->dr_buffer); - js->dr_buffer = (u8 *)alt_malloc(alloc_chars); - if (js->dr_buffer == NULL) - status = -ENOMEM; - else - js->dr_length = alloc_chars * 8; - - } - } - - if (status == 0) { - /* - * Copy preamble data, DR data, - * and postamble data into a buffer - */ - altera_concatenate_data(js->dr_buffer, - js->dr_pre_data, - js->dr_pre, - tdi_data, - start_index, - count, - js->dr_post_data, - js->dr_post); - /* Do the DRSCAN */ - alt_jtag_drscan(astate, start_code, shift_count, - js->dr_buffer, NULL); - /* alt_jtag_drscan() always ends in DRPAUSE state */ - js->jtag_state = DRPAUSE; - } - - if (status == 0) - if (js->drstop_state != DRPAUSE) - status = altera_goto_jstate(astate, js->drstop_state); - - return status; -} - -int altera_swap_dr(struct altera_state *astate, u32 count, - u8 *in_data, u32 in_index, - u8 *out_data, u32 out_index) -/* Shifts data into data register, capturing output data */ -{ - struct altera_jtag *js = &astate->js; - int start_code = 0; - u32 alloc_chars = 0; - u32 shift_count = js->dr_pre + count + js->dr_post; - int status = 0; - enum altera_jtag_state start_state = ILLEGAL_JTAG_STATE; - - switch (js->jtag_state) { - case ILLEGAL_JTAG_STATE: - case RESET: - case IDLE: - start_code = 0; - start_state = IDLE; - break; - - case DRSELECT: - case DRCAPTURE: - case DRSHIFT: - case DREXIT1: - case DRPAUSE: - case DREXIT2: - case DRUPDATE: - start_code = 1; - start_state = DRPAUSE; - break; - - case IRSELECT: - case IRCAPTURE: - case IRSHIFT: - case IREXIT1: - case IRPAUSE: - case IREXIT2: - case IRUPDATE: - start_code = 2; - start_state = IRPAUSE; - break; - - default: - status = -EREMOTEIO; - break; - } - - if (status == 0) - if (js->jtag_state != start_state) - status = altera_goto_jstate(astate, start_state); - - if (status == 0) { - if (shift_count > js->dr_length) { - alloc_chars = (shift_count + 7) >> 3; - kfree(js->dr_buffer); - js->dr_buffer = (u8 *)alt_malloc(alloc_chars); - - if (js->dr_buffer == NULL) - status = -ENOMEM; - else - js->dr_length = alloc_chars * 8; - - } - } - - if (status == 0) { - /* - * Copy preamble data, DR data, - * and postamble data into a buffer - */ - altera_concatenate_data(js->dr_buffer, - js->dr_pre_data, - js->dr_pre, - in_data, - in_index, - count, - js->dr_post_data, - js->dr_post); - - /* Do the DRSCAN */ - alt_jtag_drscan(astate, - start_code, - shift_count, - js->dr_buffer, - js->dr_buffer); - - /* alt_jtag_drscan() always ends in DRPAUSE state */ - js->jtag_state = DRPAUSE; - } - - if (status == 0) - if (js->drstop_state != DRPAUSE) - status = altera_goto_jstate(astate, js->drstop_state); - - if (status == 0) - /* Now extract the returned data from the buffer */ - altera_extract_target_data(js->dr_buffer, - out_data, - out_index, - js->dr_pre, - count); - - return status; -} - -void altera_free_buffers(struct altera_state *astate) -{ - struct altera_jtag *js = &astate->js; - /* If the JTAG interface was used, reset it to TLR */ - if (js->jtag_state != ILLEGAL_JTAG_STATE) - altera_jreset_idle(astate); - - kfree(js->dr_pre_data); - js->dr_pre_data = NULL; - - kfree(js->dr_post_data); - js->dr_post_data = NULL; - - kfree(js->dr_buffer); - js->dr_buffer = NULL; - - kfree(js->ir_pre_data); - js->ir_pre_data = NULL; - - kfree(js->ir_post_data); - js->ir_post_data = NULL; - - kfree(js->ir_buffer); - js->ir_buffer = NULL; -} diff --git a/drivers/staging/altera-stapl/altera-jtag.h b/drivers/staging/altera-stapl/altera-jtag.h deleted file mode 100644 index 2f97e36a2fbc..000000000000 --- a/drivers/staging/altera-stapl/altera-jtag.h +++ /dev/null @@ -1,113 +0,0 @@ -/* - * altera-jtag.h - * - * altera FPGA driver - * - * Copyright (C) Altera Corporation 1998-2001 - * Copyright (C) 2010 NetUP Inc. - * Copyright (C) 2010 Igor M. Liplianin <liplianin@netup.ru> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef ALTERA_JTAG_H -#define ALTERA_JTAG_H - -/* Function Prototypes */ -enum altera_jtag_state { - ILLEGAL_JTAG_STATE = -1, - RESET = 0, - IDLE = 1, - DRSELECT = 2, - DRCAPTURE = 3, - DRSHIFT = 4, - DREXIT1 = 5, - DRPAUSE = 6, - DREXIT2 = 7, - DRUPDATE = 8, - IRSELECT = 9, - IRCAPTURE = 10, - IRSHIFT = 11, - IREXIT1 = 12, - IRPAUSE = 13, - IREXIT2 = 14, - IRUPDATE = 15 - -}; - -struct altera_jtag { - /* Global variable to store the current JTAG state */ - enum altera_jtag_state jtag_state; - - /* Store current stop-state for DR and IR scan commands */ - enum altera_jtag_state drstop_state; - enum altera_jtag_state irstop_state; - - /* Store current padding values */ - u32 dr_pre; - u32 dr_post; - u32 ir_pre; - u32 ir_post; - u32 dr_length; - u32 ir_length; - u8 *dr_pre_data; - u8 *dr_post_data; - u8 *ir_pre_data; - u8 *ir_post_data; - u8 *dr_buffer; - u8 *ir_buffer; -}; - -#define ALTERA_STACK_SIZE 128 -#define ALTERA_MESSAGE_LENGTH 1024 - -struct altera_state { - struct altera_config *config; - struct altera_jtag js; - char msg_buff[ALTERA_MESSAGE_LENGTH + 1]; - long stack[ALTERA_STACK_SIZE]; -}; - -int altera_jinit(struct altera_state *astate); -int altera_set_drstop(struct altera_jtag *js, enum altera_jtag_state state); -int altera_set_irstop(struct altera_jtag *js, enum altera_jtag_state state); -int altera_set_dr_pre(struct altera_jtag *js, u32 count, u32 start_index, - u8 *preamble_data); -int altera_set_ir_pre(struct altera_jtag *js, u32 count, u32 start_index, - u8 *preamble_data); -int altera_set_dr_post(struct altera_jtag *js, u32 count, u32 start_index, - u8 *postamble_data); -int altera_set_ir_post(struct altera_jtag *js, u32 count, u32 start_index, - u8 *postamble_data); -int altera_goto_jstate(struct altera_state *astate, - enum altera_jtag_state state); -int altera_wait_cycles(struct altera_state *astate, s32 cycles, - enum altera_jtag_state wait_state); -int altera_wait_msecs(struct altera_state *astate, s32 microseconds, - enum altera_jtag_state wait_state); -int altera_irscan(struct altera_state *astate, u32 count, - u8 *tdi_data, u32 start_index); -int altera_swap_ir(struct altera_state *astate, - u32 count, u8 *in_data, - u32 in_index, u8 *out_data, - u32 out_index); -int altera_drscan(struct altera_state *astate, u32 count, - u8 *tdi_data, u32 start_index); -int altera_swap_dr(struct altera_state *astate, u32 count, - u8 *in_data, u32 in_index, - u8 *out_data, u32 out_index); -void altera_free_buffers(struct altera_state *astate); -#endif /* ALTERA_JTAG_H */ diff --git a/drivers/staging/altera-stapl/altera-lpt.c b/drivers/staging/altera-stapl/altera-lpt.c deleted file mode 100644 index 91456a03612d..000000000000 --- a/drivers/staging/altera-stapl/altera-lpt.c +++ /dev/null @@ -1,70 +0,0 @@ -/* - * altera-lpt.c - * - * altera FPGA driver - * - * Copyright (C) Altera Corporation 1998-2001 - * Copyright (C) 2010 NetUP Inc. - * Copyright (C) 2010 Abylay Ospan <aospan@netup.ru> - * - * 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/io.h> -#include <linux/kernel.h> -#include "altera-exprt.h" - -static int lpt_hardware_initialized; - -static void byteblaster_write(int port, int data) -{ - outb((u8)data, (u16)(port + 0x378)); -}; - -static int byteblaster_read(int port) -{ - int data = 0; - data = inb((u16)(port + 0x378)); - return data & 0xff; -}; - -int netup_jtag_io_lpt(void *device, int tms, int tdi, int read_tdo) -{ - int data = 0; - int tdo = 0; - int initial_lpt_ctrl = 0; - - if (!lpt_hardware_initialized) { - initial_lpt_ctrl = byteblaster_read(2); - byteblaster_write(2, (initial_lpt_ctrl | 0x02) & 0xdf); - lpt_hardware_initialized = 1; - } - - data = ((tdi ? 0x40 : 0) | (tms ? 0x02 : 0)); - - byteblaster_write(0, data); - - if (read_tdo) { - tdo = byteblaster_read(1); - tdo = ((tdo & 0x80) ? 0 : 1); - } - - byteblaster_write(0, data | 0x01); - - byteblaster_write(0, data); - - return tdo; -} diff --git a/drivers/staging/altera-stapl/altera.c b/drivers/staging/altera-stapl/altera.c deleted file mode 100644 index c2eff6a82db1..000000000000 --- a/drivers/staging/altera-stapl/altera.c +++ /dev/null @@ -1,2537 +0,0 @@ -/* - * altera.c - * - * altera FPGA driver - * - * Copyright (C) Altera Corporation 1998-2001 - * Copyright (C) 2010,2011 NetUP Inc. - * Copyright (C) 2010,2011 Igor M. Liplianin <liplianin@netup.ru> - * - * 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 <asm/unaligned.h> -#include <linux/ctype.h> -#include <linux/string.h> -#include <linux/firmware.h> -#include <linux/slab.h> -#include <linux/module.h> -#include "altera.h" -#include "altera-exprt.h" -#include "altera-jtag.h" - -static int debug = 1; -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "enable debugging information"); - -MODULE_DESCRIPTION("altera FPGA kernel module"); -MODULE_AUTHOR("Igor M. Liplianin <liplianin@netup.ru>"); -MODULE_LICENSE("GPL"); - -#define dprintk(args...) \ - if (debug) { \ - printk(KERN_DEBUG args); \ - } - -enum altera_fpga_opcode { - OP_NOP = 0, - OP_DUP, - OP_SWP, - OP_ADD, - OP_SUB, - OP_MULT, - OP_DIV, - OP_MOD, - OP_SHL, - OP_SHR, - OP_NOT, - OP_AND, - OP_OR, - OP_XOR, - OP_INV, - OP_GT, - OP_LT, - OP_RET, - OP_CMPS, - OP_PINT, - OP_PRNT, - OP_DSS, - OP_DSSC, - OP_ISS, - OP_ISSC, - OP_DPR = 0x1c, - OP_DPRL, - OP_DPO, - OP_DPOL, - OP_IPR, - OP_IPRL, - OP_IPO, - OP_IPOL, - OP_PCHR, - OP_EXIT, - OP_EQU, - OP_POPT, - OP_ABS = 0x2c, - OP_BCH0, - OP_PSH0 = 0x2f, - OP_PSHL = 0x40, - OP_PSHV, - OP_JMP, - OP_CALL, - OP_NEXT, - OP_PSTR, - OP_SINT = 0x47, - OP_ST, - OP_ISTP, - OP_DSTP, - OP_SWPN, - OP_DUPN, - OP_POPV, - OP_POPE, - OP_POPA, - OP_JMPZ, - OP_DS, - OP_IS, - OP_DPRA, - OP_DPOA, - OP_IPRA, - OP_IPOA, - OP_EXPT, - OP_PSHE, - OP_PSHA, - OP_DYNA, - OP_EXPV = 0x5c, - OP_COPY = 0x80, - OP_REVA, - OP_DSC, - OP_ISC, - OP_WAIT, - OP_VS, - OP_CMPA = 0xc0, - OP_VSC, -}; - -struct altera_procinfo { - char *name; - u8 attrs; - struct altera_procinfo *next; -}; - -/* This function checks if enough parameters are available on the stack. */ -static int altera_check_stack(int stack_ptr, int count, int *status) -{ - if (stack_ptr < count) { - *status = -EOVERFLOW; - return 0; - } - - return 1; -} - -static void altera_export_int(char *key, s32 value) -{ - dprintk("Export: key = \"%s\", value = %d\n", key, value); -} - -#define HEX_LINE_CHARS 72 -#define HEX_LINE_BITS (HEX_LINE_CHARS * 4) - -static void altera_export_bool_array(char *key, u8 *data, s32 count) -{ - char string[HEX_LINE_CHARS + 1]; - s32 i, offset; - u32 size, line, lines, linebits, value, j, k; - - if (count > HEX_LINE_BITS) { - dprintk("Export: key = \"%s\", %d bits, value = HEX\n", - key, count); - lines = (count + (HEX_LINE_BITS - 1)) / HEX_LINE_BITS; - - for (line = 0; line < lines; ++line) { - if (line < (lines - 1)) { - linebits = HEX_LINE_BITS; - size = HEX_LINE_CHARS; - offset = count - ((line + 1) * HEX_LINE_BITS); - } else { - linebits = - count - ((lines - 1) * HEX_LINE_BITS); - size = (linebits + 3) / 4; - offset = 0L; - } - - string[size] = '\0'; - j = size - 1; - value = 0; - - for (k = 0; k < linebits; ++k) { - i = k + offset; - if (data[i >> 3] & (1 << (i & 7))) - value |= (1 << (i & 3)); - if ((i & 3) == 3) { - sprintf(&string[j], "%1x", value); - value = 0; - --j; - } - } - if ((k & 3) > 0) - sprintf(&string[j], "%1x", value); - - dprintk("%s\n", string); - } - - } else { - size = (count + 3) / 4; - string[size] = '\0'; - j = size - 1; - value = 0; - - for (i = 0; i < count; ++i) { - if (data[i >> 3] & (1 << (i & 7))) - value |= (1 << (i & 3)); - if ((i & 3) == 3) { - sprintf(&string[j], "%1x", value); - value = 0; - --j; - } - } - if ((i & 3) > 0) - sprintf(&string[j], "%1x", value); - - dprintk("Export: key = \"%s\", %d bits, value = HEX %s\n", - key, count, string); - } -} - -static int altera_execute(struct altera_state *astate, - u8 *p, - s32 program_size, - s32 *error_address, - int *exit_code, - int *format_version) -{ - struct altera_config *aconf = astate->config; - char *msg_buff = astate->msg_buff; - long *stack = astate->stack; - int status = 0; - u32 first_word = 0L; - u32 action_table = 0L; - u32 proc_table = 0L; - u32 str_table = 0L; - u32 sym_table = 0L; - u32 data_sect = 0L; - u32 code_sect = 0L; - u32 debug_sect = 0L; - u32 action_count = 0L; - u32 proc_count = 0L; - u32 sym_count = 0L; - long *vars = NULL; - s32 *var_size = NULL; - char *attrs = NULL; - u8 *proc_attributes = NULL; - u32 pc; - u32 opcode_address; - u32 args[3]; - u32 opcode; - u32 name_id; - u8 charbuf[4]; - long long_tmp; - u32 variable_id; - u8 *charptr_tmp; - u8 *charptr_tmp2; - long *longptr_tmp; - int version = 0; - int delta = 0; - int stack_ptr = 0; - u32 arg_count; - int done = 0; - int bad_opcode = 0; - u32 count; - u32 index; - u32 index2; - s32 long_count; - s32 long_idx; - s32 long_idx2; - u32 i; - u32 j; - u32 uncomp_size; - u32 offset; - u32 value; - int current_proc = 0; - int reverse; - - char *name; - - dprintk("%s\n", __func__); - - /* Read header information */ - if (program_size > 52L) { - first_word = get_unaligned_be32(&p[0]); - version = (first_word & 1L); - *format_version = version + 1; - delta = version * 8; - - action_table = get_unaligned_be32(&p[4]); - proc_table = get_unaligned_be32(&p[8]); - str_table = get_unaligned_be32(&p[4 + delta]); - sym_table = get_unaligned_be32(&p[16 + delta]); - data_sect = get_unaligned_be32(&p[20 + delta]); - code_sect = get_unaligned_be32(&p[24 + delta]); - debug_sect = get_unaligned_be32(&p[28 + delta]); - action_count = get_unaligned_be32(&p[40 + delta]); - proc_count = get_unaligned_be32(&p[44 + delta]); - sym_count = get_unaligned_be32(&p[48 + (2 * delta)]); - } - - if ((first_word != 0x4A414D00L) && (first_word != 0x4A414D01L)) { - done = 1; - status = -EIO; - goto exit_done; - } - - if (sym_count <= 0) - goto exit_done; - - vars = kzalloc(sym_count * sizeof(long), GFP_KERNEL); - - if (vars == NULL) - status = -ENOMEM; - - if (status == 0) { - var_size = kzalloc(sym_count * sizeof(s32), GFP_KERNEL); - - if (var_size == NULL) - status = -ENOMEM; - } - - if (status == 0) { - attrs = kzalloc(sym_count, GFP_KERNEL); - - if (attrs == NULL) - status = -ENOMEM; - } - - if ((status == 0) && (version > 0)) { - proc_attributes = kzalloc(proc_count, GFP_KERNEL); - - if (proc_attributes == NULL) - status = -ENOMEM; - } - - if (status != 0) - goto exit_done; - - delta = version * 2; - - for (i = 0; i < sym_count; ++i) { - offset = (sym_table + ((11 + delta) * i)); - - value = get_unaligned_be32(&p[offset + 3 + delta]); - - attrs[i] = p[offset]; - - /* - * use bit 7 of attribute byte to indicate that - * this buffer was dynamically allocated - * and should be freed later - */ - attrs[i] &= 0x7f; - - var_size[i] = get_unaligned_be32(&p[offset + 7 + delta]); - - /* - * Attribute bits: - * bit 0: 0 = read-only, 1 = read-write - * bit 1: 0 = not compressed, 1 = compressed - * bit 2: 0 = not initialized, 1 = initialized - * bit 3: 0 = scalar, 1 = array - * bit 4: 0 = Boolean, 1 = integer - * bit 5: 0 = declared variable, - * 1 = compiler created temporary variable - */ - - if ((attrs[i] & 0x0c) == 0x04) - /* initialized scalar variable */ - vars[i] = value; - else if ((attrs[i] & 0x1e) == 0x0e) { - /* initialized compressed Boolean array */ - uncomp_size = get_unaligned_le32(&p[data_sect + value]); - - /* allocate a buffer for the uncompressed data */ - vars[i] = (long)kzalloc(uncomp_size, GFP_KERNEL); - if (vars[i] == 0L) - status = -ENOMEM; - else { - /* set flag so buffer will be freed later */ - attrs[i] |= 0x80; - - /* uncompress the data */ - if (altera_shrink(&p[data_sect + value], - var_size[i], - (u8 *)vars[i], - uncomp_size, - version) != uncomp_size) - /* decompression failed */ - status = -EIO; - else - var_size[i] = uncomp_size * 8L; - - } - } else if ((attrs[i] & 0x1e) == 0x0c) { - /* initialized Boolean array */ - vars[i] = value + data_sect + (long)p; - } else if ((attrs[i] & 0x1c) == 0x1c) { - /* initialized integer array */ - vars[i] = value + data_sect; - } else if ((attrs[i] & 0x0c) == 0x08) { - /* uninitialized array */ - - /* flag attrs so that memory is freed */ - attrs[i] |= 0x80; - - if (var_size[i] > 0) { - u32 size; - - if (attrs[i] & 0x10) - /* integer array */ - size = (var_size[i] * sizeof(s32)); - else - /* Boolean array */ - size = ((var_size[i] + 7L) / 8L); - - vars[i] = (long)kzalloc(size, GFP_KERNEL); - - if (vars[i] == 0) { - status = -ENOMEM; - } else { - /* zero out memory */ - for (j = 0; j < size; ++j) - ((u8 *)(vars[i]))[j] = 0; - - } - } else - vars[i] = 0; - - } else - vars[i] = 0; - - } - -exit_done: - if (status != 0) - done = 1; - - altera_jinit(astate); - - pc = code_sect; - msg_buff[0] = '\0'; - - /* - * For JBC version 2, we will execute the procedures corresponding to - * the selected ACTION - */ - if (version > 0) { - if (aconf->action == NULL) { - status = -EINVAL; - done = 1; - } else { - int action_found = 0; - for (i = 0; (i < action_count) && !action_found; ++i) { - name_id = get_unaligned_be32(&p[action_table + - (12 * i)]); - - name = &p[str_table + name_id]; - - if (strnicmp(aconf->action, name, strlen(name)) == 0) { - action_found = 1; - current_proc = - get_unaligned_be32(&p[action_table + - (12 * i) + 8]); - } - } - - if (!action_found) { - status = -EINVAL; - done = 1; - } - } - - if (status == 0) { - int first_time = 1; - i = current_proc; - while ((i != 0) || first_time) { - first_time = 0; - /* check procedure attribute byte */ - proc_attributes[i] = - (p[proc_table + - (13 * i) + 8] & - 0x03); - - /* - * BIT0 - OPTIONAL - * BIT1 - RECOMMENDED - * BIT6 - FORCED OFF - * BIT7 - FORCED ON - */ - - i = get_unaligned_be32(&p[proc_table + - (13 * i) + 4]); - } - - /* - * Set current_proc to the first procedure - * to be executed - */ - i = current_proc; - while ((i != 0) && - ((proc_attributes[i] == 1) || - ((proc_attributes[i] & 0xc0) == 0x40))) { - i = get_unaligned_be32(&p[proc_table + - (13 * i) + 4]); - } - - if ((i != 0) || ((i == 0) && (current_proc == 0) && - ((proc_attributes[0] != 1) && - ((proc_attributes[0] & 0xc0) != 0x40)))) { - current_proc = i; - pc = code_sect + - get_unaligned_be32(&p[proc_table + - (13 * i) + 9]); - if ((pc < code_sect) || (pc >= debug_sect)) - status = -ERANGE; - } else - /* there are no procedures to execute! */ - done = 1; - - } - } - - msg_buff[0] = '\0'; - - while (!done) { - opcode = (p[pc] & 0xff); - opcode_address = pc; - ++pc; - - if (debug > 1) - printk("opcode: %02x\n", opcode); - - arg_count = (opcode >> 6) & 3; - for (i = 0; i < arg_count; ++i) { - args[i] = get_unaligned_be32(&p[pc]); - pc += 4; - } - - switch (opcode) { - case OP_NOP: - break; - case OP_DUP: - if (altera_check_stack(stack_ptr, 1, &status)) { - stack[stack_ptr] = stack[stack_ptr - 1]; - ++stack_ptr; - } - break; - case OP_SWP: - if (altera_check_stack(stack_ptr, 2, &status)) { - long_tmp = stack[stack_ptr - 2]; - stack[stack_ptr - 2] = stack[stack_ptr - 1]; - stack[stack_ptr - 1] = long_tmp; - } - break; - case OP_ADD: - if (altera_check_stack(stack_ptr, 2, &status)) { - --stack_ptr; - stack[stack_ptr - 1] += stack[stack_ptr]; - } - break; - case OP_SUB: - if (altera_check_stack(stack_ptr, 2, &status)) { - --stack_ptr; - stack[stack_ptr - 1] -= stack[stack_ptr]; - } - break; - case OP_MULT: - if (altera_check_stack(stack_ptr, 2, &status)) { - --stack_ptr; - stack[stack_ptr - 1] *= stack[stack_ptr]; - } - break; - case OP_DIV: - if (altera_check_stack(stack_ptr, 2, &status)) { - --stack_ptr; - stack[stack_ptr - 1] /= stack[stack_ptr]; - } - break; - case OP_MOD: - if (altera_check_stack(stack_ptr, 2, &status)) { - --stack_ptr; - stack[stack_ptr - 1] %= stack[stack_ptr]; - } - break; - case OP_SHL: - if (altera_check_stack(stack_ptr, 2, &status)) { - --stack_ptr; - stack[stack_ptr - 1] <<= stack[stack_ptr]; - } - break; - case OP_SHR: - if (altera_check_stack(stack_ptr, 2, &status)) { - --stack_ptr; - stack[stack_ptr - 1] >>= stack[stack_ptr]; - } - break; - case OP_NOT: - if (altera_check_stack(stack_ptr, 1, &status)) - stack[stack_ptr - 1] ^= (-1L); - - break; - case OP_AND: - if (altera_check_stack(stack_ptr, 2, &status)) { - --stack_ptr; - stack[stack_ptr - 1] &= stack[stack_ptr]; - } - break; - case OP_OR: - if (altera_check_stack(stack_ptr, 2, &status)) { - --stack_ptr; - stack[stack_ptr - 1] |= stack[stack_ptr]; - } - break; - case OP_XOR: - if (altera_check_stack(stack_ptr, 2, &status)) { - --stack_ptr; - stack[stack_ptr - 1] ^= stack[stack_ptr]; - } - break; - case OP_INV: - if (!altera_check_stack(stack_ptr, 1, &status)) - break; - stack[stack_ptr - 1] = stack[stack_ptr - 1] ? 0L : 1L; - break; - case OP_GT: - if (!altera_check_stack(stack_ptr, 2, &status)) - break; - --stack_ptr; - stack[stack_ptr - 1] = - (stack[stack_ptr - 1] > stack[stack_ptr]) ? - 1L : 0L; - - break; - case OP_LT: - if (!altera_check_stack(stack_ptr, 2, &status)) - break; - --stack_ptr; - stack[stack_ptr - 1] = - (stack[stack_ptr - 1] < stack[stack_ptr]) ? - 1L : 0L; - - break; - case OP_RET: - if ((version > 0) && (stack_ptr == 0)) { - /* - * We completed one of the main procedures - * of an ACTION. - * Find the next procedure - * to be executed and jump to it. - * If there are no more procedures, then EXIT. - */ - i = get_unaligned_be32(&p[proc_table + - (13 * current_proc) + 4]); - while ((i != 0) && - ((proc_attributes[i] == 1) || - ((proc_attributes[i] & 0xc0) == 0x40))) - i = get_unaligned_be32(&p[proc_table + - (13 * i) + 4]); - - if (i == 0) { - /* no procedures to execute! */ - done = 1; - *exit_code = 0; /* success */ - } else { - current_proc = i; - pc = code_sect + get_unaligned_be32( - &p[proc_table + - (13 * i) + 9]); - if ((pc < code_sect) || - (pc >= debug_sect)) - status = -ERANGE; - } - - } else - if (altera_check_stack(stack_ptr, 1, &status)) { - pc = stack[--stack_ptr] + code_sect; - if ((pc <= code_sect) || - (pc >= debug_sect)) - status = -ERANGE; - - } - - break; - case OP_CMPS: - /* - * Array short compare - * ...stack 0 is source 1 value - * ...stack 1 is source 2 value - * ...stack 2 is mask value - * ...stack 3 is count - */ - if (altera_check_stack(stack_ptr, 4, &status)) { - s32 a = stack[--stack_ptr]; - s32 b = stack[--stack_ptr]; - long_tmp = stack[--stack_ptr]; - count = stack[stack_ptr - 1]; - - if ((count < 1) || (count > 32)) - status = -ERANGE; - else { - long_tmp &= ((-1L) >> (32 - count)); - - stack[stack_ptr - 1] = - ((a & long_tmp) == (b & long_tmp)) - ? 1L : 0L; - } - } - break; - case OP_PINT: - /* - * PRINT add integer - * ...stack 0 is integer value - */ - if (!altera_check_stack(stack_ptr, 1, &status)) - break; - sprintf(&msg_buff[strlen(msg_buff)], - "%ld", stack[--stack_ptr]); - break; - case OP_PRNT: - /* PRINT finish */ - if (debug) - printk(msg_buff, "\n"); - - msg_buff[0] = '\0'; - break; - case OP_DSS: - /* - * DRSCAN short - * ...stack 0 is scan data - * ...stack 1 is count - */ - if (!altera_check_stack(stack_ptr, 2, &status)) - break; - long_tmp = stack[--stack_ptr]; - count = stack[--stack_ptr]; - put_unaligned_le32(long_tmp, &charbuf[0]); - status = altera_drscan(astate, count, charbuf, 0); - break; - case OP_DSSC: - /* - * DRSCAN short with capture - * ...stack 0 is scan data - * ...stack 1 is count - */ - if (!altera_check_stack(stack_ptr, 2, &status)) - break; - long_tmp = stack[--stack_ptr]; - count = stack[stack_ptr - 1]; - put_unaligned_le32(long_tmp, &charbuf[0]); - status = altera_swap_dr(astate, count, charbuf, - 0, charbuf, 0); - stack[stack_ptr - 1] = get_unaligned_le32(&charbuf[0]); - break; - case OP_ISS: - /* - * IRSCAN short - * ...stack 0 is scan data - * ...stack 1 is count - */ - if (!altera_check_stack(stack_ptr, 2, &status)) - break; - long_tmp = stack[--stack_ptr]; - count = stack[--stack_ptr]; - put_unaligned_le32(long_tmp, &charbuf[0]); - status = altera_irscan(astate, count, charbuf, 0); - break; - case OP_ISSC: - /* - * IRSCAN short with capture - * ...stack 0 is scan data - * ...stack 1 is count - */ - if (!altera_check_stack(stack_ptr, 2, &status)) - break; - long_tmp = stack[--stack_ptr]; - count = stack[stack_ptr - 1]; - put_unaligned_le32(long_tmp, &charbuf[0]); - status = altera_swap_ir(astate, count, charbuf, - 0, charbuf, 0); - stack[stack_ptr - 1] = get_unaligned_le32(&charbuf[0]); - break; - case OP_DPR: - if (!altera_check_stack(stack_ptr, 1, &status)) - break; - count = stack[--stack_ptr]; - status = altera_set_dr_pre(&astate->js, count, 0, NULL); - break; - case OP_DPRL: - /* - * DRPRE with literal data - * ...stack 0 is count - * ...stack 1 is literal data - */ - if (!altera_check_stack(stack_ptr, 2, &status)) - break; - count = stack[--stack_ptr]; - long_tmp = stack[--stack_ptr]; - put_unaligned_le32(long_tmp, &charbuf[0]); - status = altera_set_dr_pre(&astate->js, count, 0, - charbuf); - break; - case OP_DPO: - /* - * DRPOST - * ...stack 0 is count - */ - if (altera_check_stack(stack_ptr, 1, &status)) { - count = stack[--stack_ptr]; - status = altera_set_dr_post(&astate->js, count, - 0, NULL); - } - break; - case OP_DPOL: - /* - * DRPOST with literal data - * ...stack 0 is count - * ...stack 1 is literal data - */ - if (!altera_check_stack(stack_ptr, 2, &status)) - break; - count = stack[--stack_ptr]; - long_tmp = stack[--stack_ptr]; - put_unaligned_le32(long_tmp, &charbuf[0]); - status = altera_set_dr_post(&astate->js, count, 0, - charbuf); - break; - case OP_IPR: - if (altera_check_stack(stack_ptr, 1, &status)) { - count = stack[--stack_ptr]; - status = altera_set_ir_pre(&astate->js, count, - 0, NULL); - } - break; - case OP_IPRL: - /* - * IRPRE with literal data - * ...stack 0 is count - * ...stack 1 is literal data - */ - if (altera_check_stack(stack_ptr, 2, &status)) { - count = stack[--stack_ptr]; - long_tmp = stack[--stack_ptr]; - put_unaligned_le32(long_tmp, &charbuf[0]); - status = altera_set_ir_pre(&astate->js, count, - 0, charbuf); - } - break; - case OP_IPO: - /* - * IRPOST - * ...stack 0 is count - */ - if (altera_check_stack(stack_ptr, 1, &status)) { - count = stack[--stack_ptr]; - status = altera_set_ir_post(&astate->js, count, - 0, NULL); - } - break; - case OP_IPOL: - /* - * IRPOST with literal data - * ...stack 0 is count - * ...stack 1 is literal data - */ - if (!altera_check_stack(stack_ptr, 2, &status)) - break; - count = stack[--stack_ptr]; - long_tmp = stack[--stack_ptr]; - put_unaligned_le32(long_tmp, &charbuf[0]); - status = altera_set_ir_post(&astate->js, count, 0, - charbuf); - break; - case OP_PCHR: - if (altera_check_stack(stack_ptr, 1, &status)) { - u8 ch; - count = strlen(msg_buff); - ch = (char) stack[--stack_ptr]; - if ((ch < 1) || (ch > 127)) { - /* - * character code out of range - * instead of flagging an error, - * force the value to 127 - */ - ch = 127; - } - msg_buff[count] = ch; - msg_buff[count + 1] = '\0'; - } - break; - case OP_EXIT: - if (altera_check_stack(stack_ptr, 1, &status)) - *exit_code = stack[--stack_ptr]; - - done = 1; - break; - case OP_EQU: - if (!altera_check_stack(stack_ptr, 2, &status)) - break; - --stack_ptr; - stack[stack_ptr - 1] = - (stack[stack_ptr - 1] == stack[stack_ptr]) ? - 1L : 0L; - break; - case OP_POPT: - if (altera_check_stack(stack_ptr, 1, &status)) - --stack_ptr; - - break; - case OP_ABS: - if (!altera_check_stack(stack_ptr, 1, &status)) - break; - if (stack[stack_ptr - 1] < 0) - stack[stack_ptr - 1] = 0 - stack[stack_ptr - 1]; - - break; - case OP_BCH0: - /* - * Batch operation 0 - * SWP - * SWPN 7 - * SWP - * SWPN 6 - * DUPN 8 - * SWPN 2 - * SWP - * DUPN 6 - * DUPN 6 - */ - - /* SWP */ - if (altera_check_stack(stack_ptr, 2, &status)) { - long_tmp = stack[stack_ptr - 2]; - stack[stack_ptr - 2] = stack[stack_ptr - 1]; - stack[stack_ptr - 1] = long_tmp; - } - - /* SWPN 7 */ - index = 7 + 1; - if (altera_check_stack(stack_ptr, index, &status)) { - long_tmp = stack[stack_ptr - index]; - stack[stack_ptr - index] = stack[stack_ptr - 1]; - stack[stack_ptr - 1] = long_tmp; - } - - /* SWP */ - if (altera_check_stack(stack_ptr, 2, &status)) { - long_tmp = stack[stack_ptr - 2]; - stack[stack_ptr - 2] = stack[stack_ptr - 1]; - stack[stack_ptr - 1] = long_tmp; - } - - /* SWPN 6 */ - index = 6 + 1; - if (altera_check_stack(stack_ptr, index, &status)) { - long_tmp = stack[stack_ptr - index]; - stack[stack_ptr - index] = stack[stack_ptr - 1]; - stack[stack_ptr - 1] = long_tmp; - } - - /* DUPN 8 */ - index = 8 + 1; - if (altera_check_stack(stack_ptr, index, &status)) { - stack[stack_ptr] = stack[stack_ptr - index]; - ++stack_ptr; - } - - /* SWPN 2 */ - index = 2 + 1; - if (altera_check_stack(stack_ptr, index, &status)) { - long_tmp = stack[stack_ptr - index]; - stack[stack_ptr - index] = stack[stack_ptr - 1]; - stack[stack_ptr - 1] = long_tmp; - } - - /* SWP */ - if (altera_check_stack(stack_ptr, 2, &status)) { - long_tmp = stack[stack_ptr - 2]; - stack[stack_ptr - 2] = stack[stack_ptr - 1]; - stack[stack_ptr - 1] = long_tmp; - } - - /* DUPN 6 */ - index = 6 + 1; - if (altera_check_stack(stack_ptr, index, &status)) { - stack[stack_ptr] = stack[stack_ptr - index]; - ++stack_ptr; - } - - /* DUPN 6 */ - index = 6 + 1; - if (altera_check_stack(stack_ptr, index, &status)) { - stack[stack_ptr] = stack[stack_ptr - index]; - ++stack_ptr; - } - break; - case OP_PSH0: - stack[stack_ptr++] = 0; - break; - case OP_PSHL: - stack[stack_ptr++] = (s32) args[0]; - break; - case OP_PSHV: - stack[stack_ptr++] = vars[args[0]]; - break; - case OP_JMP: - pc = args[0] + code_sect; - if ((pc < code_sect) || (pc >= debug_sect)) - status = -ERANGE; - break; - case OP_CALL: - stack[stack_ptr++] = pc; - pc = args[0] + code_sect; - if ((pc < code_sect) || (pc >= debug_sect)) - status = -ERANGE; - break; - case OP_NEXT: - /* - * Process FOR / NEXT loop - * ...argument 0 is variable ID - * ...stack 0 is step value - * ...stack 1 is end value - * ...stack 2 is top address - */ - if (altera_check_stack(stack_ptr, 3, &status)) { - s32 step = stack[stack_ptr - 1]; - s32 end = stack[stack_ptr - 2]; - s32 top = stack[stack_ptr - 3]; - s32 iterator = vars[args[0]]; - int break_out = 0; - - if (step < 0) { - if (iterator <= end) - break_out = 1; - } else if (iterator >= end) - break_out = 1; - - if (break_out) { - stack_ptr -= 3; - } else { - vars[args[0]] = iterator + step; - pc = top + code_sect; - if ((pc < code_sect) || - (pc >= debug_sect)) - status = -ERANGE; - } - } - break; - case OP_PSTR: - /* - * PRINT add string - * ...argument 0 is string ID - */ - count = strlen(msg_buff); - strlcpy(&msg_buff[count], - &p[str_table + args[0]], - ALTERA_MESSAGE_LENGTH - count); - break; - case OP_SINT: - /* - * STATE intermediate state - * ...argument 0 is state code - */ - status = altera_goto_jstate(astate, args[0]); - break; - case OP_ST: - /* - * STATE final state - * ...argument 0 is state code - */ - status = altera_goto_jstate(astate, args[0]); - break; - case OP_ISTP: - /* - * IRSTOP state - * ...argument 0 is state code - */ - status = altera_set_irstop(&astate->js, args[0]); - break; - case OP_DSTP: - /* - * DRSTOP state - * ...argument 0 is state code - */ - status = altera_set_drstop(&astate->js, args[0]); - break; - - case OP_SWPN: - /* - * Exchange top with Nth stack value - * ...argument 0 is 0-based stack entry - * to swap with top element - */ - index = (args[0]) + 1; - if (altera_check_stack(stack_ptr, index, &status)) { - long_tmp = stack[stack_ptr - index]; - stack[stack_ptr - index] = stack[stack_ptr - 1]; - stack[stack_ptr - 1] = long_tmp; - } - break; - case OP_DUPN: - /* - * Duplicate Nth stack value - * ...argument 0 is 0-based stack entry to duplicate - */ - index = (args[0]) + 1; - if (altera_check_stack(stack_ptr, index, &status)) { - stack[stack_ptr] = stack[stack_ptr - index]; - ++stack_ptr; - } - break; - case OP_POPV: - /* - * Pop stack into scalar variable - * ...argument 0 is variable ID - * ...stack 0 is value - */ - if (altera_check_stack(stack_ptr, 1, &status)) - vars[args[0]] = stack[--stack_ptr]; - - break; - case OP_POPE: - /* - * Pop stack into integer array element - * ...argument 0 is variable ID - * ...stack 0 is array index - * ...stack 1 is value - */ - if (!altera_check_stack(stack_ptr, 2, &status)) - break; - variable_id = args[0]; - - /* - * If variable is read-only, - * convert to writable array - */ - if ((version > 0) && - ((attrs[variable_id] & 0x9c) == 0x1c)) { - /* Allocate a writable buffer for this array */ - count = var_size[variable_id]; - long_tmp = vars[variable_id]; - longptr_tmp = kzalloc(count * sizeof(long), - GFP_KERNEL); - vars[variable_id] = (long)longptr_tmp; - - if (vars[variable_id] == 0) { - status = -ENOMEM; - break; - } - - /* copy previous contents into buffer */ - for (i = 0; i < count; ++i) { - longptr_tmp[i] = - get_unaligned_be32(&p[long_tmp]); - long_tmp += sizeof(long); - } - - /* - * set bit 7 - buffer was - * dynamically allocated - */ - attrs[variable_id] |= 0x80; - - /* clear bit 2 - variable is writable */ - attrs[variable_id] &= ~0x04; - attrs[variable_id] |= 0x01; - - } - - /* check that variable is a writable integer array */ - if ((attrs[variable_id] & 0x1c) != 0x18) - status = -ERANGE; - else { - longptr_tmp = (long *)vars[variable_id]; - - /* pop the array index */ - index = stack[--stack_ptr]; - - /* pop the value and store it into the array */ - longptr_tmp[index] = stack[--stack_ptr]; - } - - break; - case OP_POPA: - /* - * Pop stack into Boolean array - * ...argument 0 is variable ID - * ...stack 0 is count - * ...stack 1 is array index - * ...stack 2 is value - */ - if (!altera_check_stack(stack_ptr, 3, &status)) - break; - variable_id = args[0]; - - /* - * If variable is read-only, - * convert to writable array - */ - if ((version > 0) && - ((attrs[variable_id] & 0x9c) == 0x0c)) { - /* Allocate a writable buffer for this array */ - long_tmp = - (var_size[variable_id] + 7L) >> 3L; - charptr_tmp2 = (u8 *)vars[variable_id]; - charptr_tmp = - kzalloc(long_tmp, GFP_KERNEL); - vars[variable_id] = (long)charptr_tmp; - - if (vars[variable_id] == 0) { - status = -ENOMEM; - break; - } - - /* zero the buffer */ - for (long_idx = 0L; - long_idx < long_tmp; - ++long_idx) { - charptr_tmp[long_idx] = 0; - } - - /* copy previous contents into buffer */ - for (long_idx = 0L; - long_idx < var_size[variable_id]; - ++long_idx) { - long_idx2 = long_idx; - - if (charptr_tmp2[long_idx2 >> 3] & - (1 << (long_idx2 & 7))) { - charptr_tmp[long_idx >> 3] |= - (1 << (long_idx & 7)); - } - } - - /* - * set bit 7 - buffer was - * dynamically allocated - */ - attrs[variable_id] |= 0x80; - - /* clear bit 2 - variable is writable */ - attrs[variable_id] &= ~0x04; - attrs[variable_id] |= 0x01; - - } - - /* - * check that variable is - * a writable Boolean array - */ - if ((attrs[variable_id] & 0x1c) != 0x08) { - status = -ERANGE; - break; - } - - charptr_tmp = (u8 *)vars[variable_id]; - - /* pop the count (number of bits to copy) */ - long_count = stack[--stack_ptr]; - - /* pop the array index */ - long_idx = stack[--stack_ptr]; - - reverse = 0; - - if (version > 0) { - /* - * stack 0 = array right index - * stack 1 = array left index - */ - - if (long_idx > long_count) { - reverse = 1; - long_tmp = long_count; - long_count = 1 + long_idx - - long_count; - long_idx = long_tmp; - - /* reverse POPA is not supported */ - status = -ERANGE; - break; - } else - long_count = 1 + long_count - - long_idx; - - } - - /* pop the data */ - long_tmp = stack[--stack_ptr]; - - if (long_count < 1) { - status = -ERANGE; - break; - } - - for (i = 0; i < long_count; ++i) { - if (long_tmp & (1L << (s32) i)) - charptr_tmp[long_idx >> 3L] |= - (1L << (long_idx & 7L)); - else - charptr_tmp[long_idx >> 3L] &= - ~(1L << (long_idx & 7L)); - - ++long_idx; - } - - break; - case OP_JMPZ: - /* - * Pop stack and branch if zero - * ...argument 0 is address - * ...stack 0 is condition value - */ - if (altera_check_stack(stack_ptr, 1, &status)) { - if (stack[--stack_ptr] == 0) { - pc = args[0] + code_sect; - if ((pc < code_sect) || - (pc >= debug_sect)) - status = -ERANGE; - } - } - break; - case OP_DS: - case OP_IS: - /* - * DRSCAN - * IRSCAN - * ...argument 0 is scan data variable ID - * ...stack 0 is array index - * ...stack 1 is count - */ - if (!altera_check_stack(stack_ptr, 2, &status)) - break; - long_idx = stack[--stack_ptr]; - long_count = stack[--stack_ptr]; - reverse = 0; - if (version > 0) { - /* - * stack 0 = array right index - * stack 1 = array left index - * stack 2 = count - */ - long_tmp = long_count; - long_count = stack[--stack_ptr]; - - if (long_idx > long_tmp) { - reverse = 1; - long_idx = long_tmp; - } - } - - charptr_tmp = (u8 *)vars[args[0]]; - - if (reverse) { - /* - * allocate a buffer - * and reverse the data order - */ - charptr_tmp2 = charptr_tmp; - charptr_tmp = kzalloc((long_count >> 3) + 1, - GFP_KERNEL); - if (charptr_tmp == NULL) { - status = -ENOMEM; - break; - } - - long_tmp = long_idx + long_count - 1; - long_idx2 = 0; - while (long_idx2 < long_count) { - if (charptr_tmp2[long_tmp >> 3] & - (1 << (long_tmp & 7))) - charptr_tmp[long_idx2 >> 3] |= - (1 << (long_idx2 & 7)); - else - charptr_tmp[long_idx2 >> 3] &= - ~(1 << (long_idx2 & 7)); - - --long_tmp; - ++long_idx2; - } - } - - if (opcode == 0x51) /* DS */ - status = altera_drscan(astate, long_count, - charptr_tmp, long_idx); - else /* IS */ - status = altera_irscan(astate, long_count, - charptr_tmp, long_idx); - - if (reverse) - kfree(charptr_tmp); - - break; - case OP_DPRA: - /* - * DRPRE with array data - * ...argument 0 is variable ID - * ...stack 0 is array index - * ...stack 1 is count - */ - if (!altera_check_stack(stack_ptr, 2, &status)) - break; - index = stack[--stack_ptr]; - count = stack[--stack_ptr]; - - if (version > 0) - /* - * stack 0 = array right index - * stack 1 = array left index - */ - count = 1 + count - index; - - charptr_tmp = (u8 *)vars[args[0]]; - status = altera_set_dr_pre(&astate->js, count, index, - charptr_tmp); - break; - case OP_DPOA: - /* - * DRPOST with array data - * ...argument 0 is variable ID - * ...stack 0 is array index - * ...stack 1 is count - */ - if (!altera_check_stack(stack_ptr, 2, &status)) - break; - index = stack[--stack_ptr]; - count = stack[--stack_ptr]; - - if (version > 0) - /* - * stack 0 = array right index - * stack 1 = array left index - */ - count = 1 + count - index; - - charptr_tmp = (u8 *)vars[args[0]]; - status = altera_set_dr_post(&astate->js, count, index, - charptr_tmp); - break; - case OP_IPRA: - /* - * IRPRE with array data - * ...argument 0 is variable ID - * ...stack 0 is array index - * ...stack 1 is count - */ - if (!altera_check_stack(stack_ptr, 2, &status)) - break; - index = stack[--stack_ptr]; - count = stack[--stack_ptr]; - - if (version > 0) - /* - * stack 0 = array right index - * stack 1 = array left index - */ - count = 1 + count - index; - - charptr_tmp = (u8 *)vars[args[0]]; - status = altera_set_ir_pre(&astate->js, count, index, - charptr_tmp); - - break; - case OP_IPOA: - /* - * IRPOST with array data - * ...argument 0 is variable ID - * ...stack 0 is array index - * ...stack 1 is count - */ - if (!altera_check_stack(stack_ptr, 2, &status)) - break; - index = stack[--stack_ptr]; - count = stack[--stack_ptr]; - - if (version > 0) - /* - * stack 0 = array right index - * stack 1 = array left index - */ - count = 1 + count - index; - - charptr_tmp = (u8 *)vars[args[0]]; - status = altera_set_ir_post(&astate->js, count, index, - charptr_tmp); - - break; - case OP_EXPT: - /* - * EXPORT - * ...argument 0 is string ID - * ...stack 0 is integer expression - */ - if (altera_check_stack(stack_ptr, 1, &status)) { - name = &p[str_table + args[0]]; - long_tmp = stack[--stack_ptr]; - altera_export_int(name, long_tmp); - } - break; - case OP_PSHE: - /* - * Push integer array element - * ...argument 0 is variable ID - * ...stack 0 is array index - */ - if (!altera_check_stack(stack_ptr, 1, &status)) - break; - variable_id = args[0]; - index = stack[stack_ptr - 1]; - - /* check variable type */ - if ((attrs[variable_id] & 0x1f) == 0x19) { - /* writable integer array */ - longptr_tmp = (long *)vars[variable_id]; - stack[stack_ptr - 1] = longptr_tmp[index]; - } else if ((attrs[variable_id] & 0x1f) == 0x1c) { - /* read-only integer array */ - long_tmp = vars[variable_id] + - (index * sizeof(long)); - stack[stack_ptr - 1] = - get_unaligned_be32(&p[long_tmp]); - } else - status = -ERANGE; - - break; - case OP_PSHA: - /* - * Push Boolean array - * ...argument 0 is variable ID - * ...stack 0 is count - * ...stack 1 is array index - */ - if (!altera_check_stack(stack_ptr, 2, &status)) - break; - variable_id = args[0]; - - /* check that variable is a Boolean array */ - if ((attrs[variable_id] & 0x18) != 0x08) { - status = -ERANGE; - break; - } - - charptr_tmp = (u8 *)vars[variable_id]; - - /* pop the count (number of bits to copy) */ - count = stack[--stack_ptr]; - - /* pop the array index */ - index = stack[stack_ptr - 1]; - - if (version > 0) - /* - * stack 0 = array right index - * stack 1 = array left index - */ - count = 1 + count - index; - - if ((count < 1) || (count > 32)) { - status = -ERANGE; - break; - } - - long_tmp = 0L; - - for (i = 0; i < count; ++i) - if (charptr_tmp[(i + index) >> 3] & - (1 << ((i + index) & 7))) - long_tmp |= (1L << i); - - stack[stack_ptr - 1] = long_tmp; - - break; - case OP_DYNA: - /* - * Dynamically change size of array - * ...argument 0 is variable ID - * ...stack 0 is new size - */ - if (!altera_check_stack(stack_ptr, 1, &status)) - break; - variable_id = args[0]; - long_tmp = stack[--stack_ptr]; - - if (long_tmp > var_size[variable_id]) { - var_size[variable_id] = long_tmp; - - if (attrs[variable_id] & 0x10) - /* allocate integer array */ - long_tmp *= sizeof(long); - else - /* allocate Boolean array */ - long_tmp = (long_tmp + 7) >> 3; - - /* - * If the buffer was previously allocated, - * free it - */ - if (attrs[variable_id] & 0x80) { - kfree((void *)vars[variable_id]); - vars[variable_id] = 0; - } - - /* - * Allocate a new buffer - * of the requested size - */ - vars[variable_id] = (long) - kzalloc(long_tmp, GFP_KERNEL); - - if (vars[variable_id] == 0) { - status = -ENOMEM; - break; - } - - /* - * Set the attribute bit to indicate that - * this buffer was dynamically allocated and - * should be freed later - */ - attrs[variable_id] |= 0x80; - - /* zero out memory */ - count = ((var_size[variable_id] + 7L) / - 8L); - charptr_tmp = (u8 *)(vars[variable_id]); - for (index = 0; index < count; ++index) - charptr_tmp[index] = 0; - - } - - break; - case OP_EXPV: - /* - * Export Boolean array - * ...argument 0 is string ID - * ...stack 0 is variable ID - * ...stack 1 is array right index - * ...stack 2 is array left index - */ - if (!altera_check_stack(stack_ptr, 3, &status)) - break; - if (version == 0) { - /* EXPV is not supported in JBC 1.0 */ - bad_opcode = 1; - break; - } - name = &p[str_table + args[0]]; - variable_id = stack[--stack_ptr]; - long_idx = stack[--stack_ptr];/* right indx */ - long_idx2 = stack[--stack_ptr];/* left indx */ - - if (long_idx > long_idx2) { - /* reverse indices not supported */ - status = -ERANGE; - break; - } - - long_count = 1 + long_idx2 - long_idx; - - charptr_tmp = (u8 *)vars[variable_id]; - charptr_tmp2 = NULL; - - if ((long_idx & 7L) != 0) { - s32 k = long_idx; - charptr_tmp2 = - kzalloc(((long_count + 7L) / 8L), - GFP_KERNEL); - if (charptr_tmp2 == NULL) { - status = -ENOMEM; - break; - } - - for (i = 0; i < long_count; ++i) { - if (charptr_tmp[k >> 3] & - (1 << (k & 7))) - charptr_tmp2[i >> 3] |= - (1 << (i & 7)); - else - charptr_tmp2[i >> 3] &= - ~(1 << (i & 7)); - - ++k; - } - charptr_tmp = charptr_tmp2; - - } else if (long_idx != 0) - charptr_tmp = &charptr_tmp[long_idx >> 3]; - - altera_export_bool_array(name, charptr_tmp, - long_count); - - /* free allocated buffer */ - if ((long_idx & 7L) != 0) - kfree(charptr_tmp2); - - break; - case OP_COPY: { - /* - * Array copy - * ...argument 0 is dest ID - * ...argument 1 is source ID - * ...stack 0 is count - * ...stack 1 is dest index - * ...stack 2 is source index - */ - s32 copy_count; - s32 copy_index; - s32 copy_index2; - s32 destleft; - s32 src_count; - s32 dest_count; - int src_reverse = 0; - int dest_reverse = 0; - - if (!altera_check_stack(stack_ptr, 3, &status)) - break; - - copy_count = stack[--stack_ptr]; - copy_index = stack[--stack_ptr]; - copy_index2 = stack[--stack_ptr]; - reverse = 0; - - if (version > 0) { - /* - * stack 0 = source right index - * stack 1 = source left index - * stack 2 = destination right index - * stack 3 = destination left index - */ - destleft = stack[--stack_ptr]; - - if (copy_count > copy_index) { - src_reverse = 1; - reverse = 1; - src_count = 1 + copy_count - copy_index; - /* copy_index = source start index */ - } else { - src_count = 1 + copy_index - copy_count; - /* source start index */ - copy_index = copy_count; - } - - if (copy_index2 > destleft) { - dest_reverse = 1; - reverse = !reverse; - dest_count = 1 + copy_index2 - destleft; - /* destination start index */ - copy_index2 = destleft; - } else - dest_count = 1 + destleft - copy_index2; - - copy_count = (src_count < dest_count) ? - src_count : dest_count; - - if ((src_reverse || dest_reverse) && - (src_count != dest_count)) - /* - * If either the source or destination - * is reversed, we can't tolerate - * a length mismatch, because we - * "left justify" arrays when copying. - * This won't work correctly - * with reversed arrays. - */ - status = -ERANGE; - - } - - count = copy_count; - index = copy_index; - index2 = copy_index2; - - /* - * If destination is a read-only array, - * allocate a buffer and convert it to a writable array - */ - variable_id = args[1]; - if ((version > 0) && - ((attrs[variable_id] & 0x9c) == 0x0c)) { - /* Allocate a writable buffer for this array */ - long_tmp = - (var_size[variable_id] + 7L) >> 3L; - charptr_tmp2 = (u8 *)vars[variable_id]; - charptr_tmp = - kzalloc(long_tmp, GFP_KERNEL); - vars[variable_id] = (long)charptr_tmp; - - if (vars[variable_id] == 0) { - status = -ENOMEM; - break; - } - - /* zero the buffer */ - for (long_idx = 0L; long_idx < long_tmp; - ++long_idx) - charptr_tmp[long_idx] = 0; - - /* copy previous contents into buffer */ - for (long_idx = 0L; - long_idx < var_size[variable_id]; - ++long_idx) { - long_idx2 = long_idx; - - if (charptr_tmp2[long_idx2 >> 3] & - (1 << (long_idx2 & 7))) - charptr_tmp[long_idx >> 3] |= - (1 << (long_idx & 7)); - - } - - /* - set bit 7 - buffer was dynamically allocated */ - attrs[variable_id] |= 0x80; - - /* clear bit 2 - variable is writable */ - attrs[variable_id] &= ~0x04; - attrs[variable_id] |= 0x01; - } - - charptr_tmp = (u8 *)vars[args[1]]; - charptr_tmp2 = (u8 *)vars[args[0]]; - - /* check if destination is a writable Boolean array */ - if ((attrs[args[1]] & 0x1c) != 0x08) { - status = -ERANGE; - break; - } - - if (count < 1) { - status = -ERANGE; - break; - } - - if (reverse) - index2 += (count - 1); - - for (i = 0; i < count; ++i) { - if (charptr_tmp2[index >> 3] & - (1 << (index & 7))) - charptr_tmp[index2 >> 3] |= - (1 << (index2 & 7)); - else - charptr_tmp[index2 >> 3] &= - ~(1 << (index2 & 7)); - - ++index; - if (reverse) - --index2; - else - ++index2; - } - - break; - } - case OP_DSC: - case OP_ISC: { - /* - * DRSCAN with capture - * IRSCAN with capture - * ...argument 0 is scan data variable ID - * ...argument 1 is capture variable ID - * ...stack 0 is capture index - * ...stack 1 is scan data index - * ...stack 2 is count - */ - s32 scan_right, scan_left; - s32 capture_count = 0; - s32 scan_count = 0; - s32 capture_index; - s32 scan_index; - - if (!altera_check_stack(stack_ptr, 3, &status)) - break; - - capture_index = stack[--stack_ptr]; - scan_index = stack[--stack_ptr]; - - if (version > 0) { - /* - * stack 0 = capture right index - * stack 1 = capture left index - * stack 2 = scan right index - * stack 3 = scan left index - * stack 4 = count - */ - scan_right = stack[--stack_ptr]; - scan_left = stack[--stack_ptr]; - capture_count = 1 + scan_index - capture_index; - scan_count = 1 + scan_left - scan_right; - scan_index = scan_right; - } - - long_count = stack[--stack_ptr]; - /* - * If capture array is read-only, allocate a buffer - * and convert it to a writable array - */ - variable_id = args[1]; - if ((version > 0) && - ((attrs[variable_id] & 0x9c) == 0x0c)) { - /* Allocate a writable buffer for this array */ - long_tmp = - (var_size[variable_id] + 7L) >> 3L; - charptr_tmp2 = (u8 *)vars[variable_id]; - charptr_tmp = - kzalloc(long_tmp, GFP_KERNEL); - vars[variable_id] = (long)charptr_tmp; - - if (vars[variable_id] == 0) { - status = -ENOMEM; - break; - } - - /* zero the buffer */ - for (long_idx = 0L; long_idx < long_tmp; - ++long_idx) - charptr_tmp[long_idx] = 0; - - /* copy previous contents into buffer */ - for (long_idx = 0L; - long_idx < var_size[variable_id]; - ++long_idx) { - long_idx2 = long_idx; - - if (charptr_tmp2[long_idx2 >> 3] & - (1 << (long_idx2 & 7))) - charptr_tmp[long_idx >> 3] |= - (1 << (long_idx & 7)); - - } - - /* - * set bit 7 - buffer was - * dynamically allocated - */ - attrs[variable_id] |= 0x80; - - /* clear bit 2 - variable is writable */ - attrs[variable_id] &= ~0x04; - attrs[variable_id] |= 0x01; - - } - - charptr_tmp = (u8 *)vars[args[0]]; - charptr_tmp2 = (u8 *)vars[args[1]]; - - if ((version > 0) && - ((long_count > capture_count) || - (long_count > scan_count))) { - status = -ERANGE; - break; - } - - /* - * check that capture array - * is a writable Boolean array - */ - if ((attrs[args[1]] & 0x1c) != 0x08) { - status = -ERANGE; - break; - } - - if (status == 0) { - if (opcode == 0x82) /* DSC */ - status = altera_swap_dr(astate, - long_count, - charptr_tmp, - scan_index, - charptr_tmp2, - capture_index); - else /* ISC */ - status = altera_swap_ir(astate, - long_count, - charptr_tmp, - scan_index, - charptr_tmp2, - capture_index); - - } - - break; - } - case OP_WAIT: - /* - * WAIT - * ...argument 0 is wait state - * ...argument 1 is end state - * ...stack 0 is cycles - * ...stack 1 is microseconds - */ - if (!altera_check_stack(stack_ptr, 2, &status)) - break; - long_tmp = stack[--stack_ptr]; - - if (long_tmp != 0L) - status = altera_wait_cycles(astate, long_tmp, - args[0]); - - long_tmp = stack[--stack_ptr]; - - if ((status == 0) && (long_tmp != 0L)) - status = altera_wait_msecs(astate, - long_tmp, - args[0]); - - if ((status == 0) && (args[1] != args[0])) - status = altera_goto_jstate(astate, - args[1]); - - if (version > 0) { - --stack_ptr; /* throw away MAX cycles */ - --stack_ptr; /* throw away MAX microseconds */ - } - break; - case OP_CMPA: { - /* - * Array compare - * ...argument 0 is source 1 ID - * ...argument 1 is source 2 ID - * ...argument 2 is mask ID - * ...stack 0 is source 1 index - * ...stack 1 is source 2 index - * ...stack 2 is mask index - * ...stack 3 is count - */ - s32 a, b; - u8 *source1 = (u8 *)vars[args[0]]; - u8 *source2 = (u8 *)vars[args[1]]; - u8 *mask = (u8 *)vars[args[2]]; - u32 index1; - u32 index2; - u32 mask_index; - - if (!altera_check_stack(stack_ptr, 4, &status)) - break; - - index1 = stack[--stack_ptr]; - index2 = stack[--stack_ptr]; - mask_index = stack[--stack_ptr]; - long_count = stack[--stack_ptr]; - - if (version > 0) { - /* - * stack 0 = source 1 right index - * stack 1 = source 1 left index - * stack 2 = source 2 right index - * stack 3 = source 2 left index - * stack 4 = mask right index - * stack 5 = mask left index - */ - s32 mask_right = stack[--stack_ptr]; - s32 mask_left = stack[--stack_ptr]; - /* source 1 count */ - a = 1 + index2 - index1; - /* source 2 count */ - b = 1 + long_count - mask_index; - a = (a < b) ? a : b; - /* mask count */ - b = 1 + mask_left - mask_right; - a = (a < b) ? a : b; - /* source 2 start index */ - index2 = mask_index; - /* mask start index */ - mask_index = mask_right; - long_count = a; - } - - long_tmp = 1L; - - if (long_count < 1) - status = -ERANGE; - else { - count = long_count; - - for (i = 0; i < count; ++i) { - if (mask[mask_index >> 3] & - (1 << (mask_index & 7))) { - a = source1[index1 >> 3] & - (1 << (index1 & 7)) - ? 1 : 0; - b = source2[index2 >> 3] & - (1 << (index2 & 7)) - ? 1 : 0; - - if (a != b) /* failure */ - long_tmp = 0L; - } - ++index1; - ++index2; - ++mask_index; - } - } - - stack[stack_ptr++] = long_tmp; - - break; - } - default: - /* Unrecognized opcode -- ERROR! */ - bad_opcode = 1; - break; - } - - if (bad_opcode) - status = -ENOSYS; - - if ((stack_ptr < 0) || (stack_ptr >= ALTERA_STACK_SIZE)) - status = -EOVERFLOW; - - if (status != 0) { - done = 1; - *error_address = (s32)(opcode_address - code_sect); - } - } - - altera_free_buffers(astate); - - /* Free all dynamically allocated arrays */ - if ((attrs != NULL) && (vars != NULL)) - for (i = 0; i < sym_count; ++i) - if (attrs[i] & 0x80) - kfree((void *)vars[i]); - - kfree(vars); - kfree(var_size); - kfree(attrs); - kfree(proc_attributes); - - return status; -} - -static int altera_get_note(u8 *p, s32 program_size, - s32 *offset, char *key, char *value, int length) -/* - * Gets key and value of NOTE fields in the JBC file. - * Can be called in two modes: if offset pointer is NULL, - * then the function searches for note fields which match - * the key string provided. If offset is not NULL, then - * the function finds the next note field of any key, - * starting at the offset specified by the offset pointer. - * Returns 0 for success, else appropriate error code - */ -{ - int status = -ENODATA; - u32 note_strings = 0L; - u32 note_table = 0L; - u32 note_count = 0L; - u32 first_word = 0L; - int version = 0; - int delta = 0; - char *key_ptr; - char *value_ptr; - int i; - - /* Read header information */ - if (program_size > 52L) { - first_word = get_unaligned_be32(&p[0]); - version = (first_word & 1L); - delta = version * 8; - - note_strings = get_unaligned_be32(&p[8 + delta]); - note_table = get_unaligned_be32(&p[12 + delta]); - note_count = get_unaligned_be32(&p[44 + (2 * delta)]); - } - - if ((first_word != 0x4A414D00L) && (first_word != 0x4A414D01L)) - return -EIO; - - if (note_count <= 0L) - return status; - - if (offset == NULL) { - /* - * We will search for the first note with a specific key, - * and return only the value - */ - for (i = 0; (i < note_count) && - (status != 0); ++i) { - key_ptr = &p[note_strings + - get_unaligned_be32( - &p[note_table + (8 * i)])]; - if ((strnicmp(key, key_ptr, strlen(key_ptr)) == 0) && - (key != NULL)) { - status = 0; - - value_ptr = &p[note_strings + - get_unaligned_be32( - &p[note_table + (8 * i) + 4])]; - - if (value != NULL) - strlcpy(value, value_ptr, length); - - } - } - } else { - /* - * We will search for the next note, regardless of the key, - * and return both the value and the key - */ - - i = *offset; - - if ((i >= 0) && (i < note_count)) { - status = 0; - - if (key != NULL) - strlcpy(key, &p[note_strings + - get_unaligned_be32( - &p[note_table + (8 * i)])], - length); - - if (value != NULL) - strlcpy(value, &p[note_strings + - get_unaligned_be32( - &p[note_table + (8 * i) + 4])], - length); - - *offset = i + 1; - } - } - - return status; -} - -static int altera_check_crc(u8 *p, s32 program_size) -{ - int status = 0; - u16 local_expected = 0, - local_actual = 0, - shift_reg = 0xffff; - int bit, feedback; - u8 databyte; - u32 i; - u32 crc_section = 0L; - u32 first_word = 0L; - int version = 0; - int delta = 0; - - if (program_size > 52L) { - first_word = get_unaligned_be32(&p[0]); - version = (first_word & 1L); - delta = version * 8; - - crc_section = get_unaligned_be32(&p[32 + delta]); - } - - if ((first_word != 0x4A414D00L) && (first_word != 0x4A414D01L)) - status = -EIO; - - if (crc_section >= program_size) - status = -EIO; - - if (status == 0) { - local_expected = (u16)get_unaligned_be16(&p[crc_section]); - - for (i = 0; i < crc_section; ++i) { - databyte = p[i]; - for (bit = 0; bit < 8; bit++) { - feedback = (databyte ^ shift_reg) & 0x01; - shift_reg >>= 1; - if (feedback) - shift_reg ^= 0x8408; - - databyte >>= 1; - } - } - - local_actual = (u16)~shift_reg; - - if (local_expected != local_actual) - status = -EILSEQ; - - } - - if (debug || status) { - switch (status) { - case 0: - printk(KERN_INFO "%s: CRC matched: %04x\n", __func__, - local_actual); - break; - case -EILSEQ: - printk(KERN_ERR "%s: CRC mismatch: expected %04x, " - "actual %04x\n", __func__, local_expected, - local_actual); - break; - case -ENODATA: - printk(KERN_ERR "%s: expected CRC not found, " - "actual CRC = %04x\n", __func__, - local_actual); - break; - case -EIO: - printk(KERN_ERR "%s: error: format isn't " - "recognized.\n", __func__); - break; - default: - printk(KERN_ERR "%s: CRC function returned error " - "code %d\n", __func__, status); - break; - } - } - - return status; -} - -static int altera_get_file_info(u8 *p, - s32 program_size, - int *format_version, - int *action_count, - int *procedure_count) -{ - int status = -EIO; - u32 first_word = 0; - int version = 0; - - if (program_size <= 52L) - return status; - - first_word = get_unaligned_be32(&p[0]); - - if ((first_word == 0x4A414D00L) || (first_word == 0x4A414D01L)) { - status = 0; - - version = (first_word & 1L); - *format_version = version + 1; - - if (version > 0) { - *action_count = get_unaligned_be32(&p[48]); - *procedure_count = get_unaligned_be32(&p[52]); - } - } - - return status; -} - -static int altera_get_act_info(u8 *p, - s32 program_size, - int index, - char **name, - char **description, - struct altera_procinfo **proc_list) -{ - int status = -EIO; - struct altera_procinfo *procptr = NULL; - struct altera_procinfo *tmpptr = NULL; - u32 first_word = 0L; - u32 action_table = 0L; - u32 proc_table = 0L; - u32 str_table = 0L; - u32 note_strings = 0L; - u32 action_count = 0L; - u32 proc_count = 0L; - u32 act_name_id = 0L; - u32 act_desc_id = 0L; - u32 act_proc_id = 0L; - u32 act_proc_name = 0L; - u8 act_proc_attribute = 0; - - if (program_size <= 52L) - return status; - /* Read header information */ - first_word = get_unaligned_be32(&p[0]); - - if (first_word != 0x4A414D01L) - return status; - - action_table = get_unaligned_be32(&p[4]); - proc_table = get_unaligned_be32(&p[8]); - str_table = get_unaligned_be32(&p[12]); - note_strings = get_unaligned_be32(&p[16]); - action_count = get_unaligned_be32(&p[48]); - proc_count = get_unaligned_be32(&p[52]); - - if (index >= action_count) - return status; - - act_name_id = get_unaligned_be32(&p[action_table + (12 * index)]); - act_desc_id = get_unaligned_be32(&p[action_table + (12 * index) + 4]); - act_proc_id = get_unaligned_be32(&p[action_table + (12 * index) + 8]); - - *name = &p[str_table + act_name_id]; - - if (act_desc_id < (note_strings - str_table)) - *description = &p[str_table + act_desc_id]; - - do { - act_proc_name = get_unaligned_be32( - &p[proc_table + (13 * act_proc_id)]); - act_proc_attribute = - (p[proc_table + (13 * act_proc_id) + 8] & 0x03); - - procptr = - kzalloc(sizeof(struct altera_procinfo), - GFP_KERNEL); - - if (procptr == NULL) - status = -ENOMEM; - else { - procptr->name = &p[str_table + act_proc_name]; - procptr->attrs = act_proc_attribute; - procptr->next = NULL; - - /* add record to end of linked list */ - if (*proc_list == NULL) - *proc_list = procptr; - else { - tmpptr = *proc_list; - while (tmpptr->next != NULL) - tmpptr = tmpptr->next; - tmpptr->next = procptr; - } - } - - act_proc_id = get_unaligned_be32( - &p[proc_table + (13 * act_proc_id) + 4]); - } while ((act_proc_id != 0) && (act_proc_id < proc_count)); - - return status; -} - -int altera_init(struct altera_config *config, const struct firmware *fw) -{ - struct altera_state *astate = NULL; - struct altera_procinfo *proc_list = NULL; - struct altera_procinfo *procptr = NULL; - char *key = NULL; - char *value = NULL; - char *action_name = NULL; - char *description = NULL; - int exec_result = 0; - int exit_code = 0; - int format_version = 0; - int action_count = 0; - int procedure_count = 0; - int index = 0; - s32 offset = 0L; - s32 error_address = 0L; - int retval = 0; - - key = kzalloc(33, GFP_KERNEL); - if (!key) { - retval = -ENOMEM; - goto out; - } - value = kzalloc(257, GFP_KERNEL); - if (!value) { - retval = -ENOMEM; - goto free_key; - } - astate = kzalloc(sizeof(struct altera_state), GFP_KERNEL); - if (!astate) { - retval = -ENOMEM; - goto free_value; - } - - astate->config = config; - if (!astate->config->jtag_io) { - dprintk(KERN_INFO "%s: using byteblaster!\n", __func__); - astate->config->jtag_io = netup_jtag_io_lpt; - } - - altera_check_crc((u8 *)fw->data, fw->size); - - if (debug) { - altera_get_file_info((u8 *)fw->data, fw->size, &format_version, - &action_count, &procedure_count); - printk(KERN_INFO "%s: File format is %s ByteCode format\n", - __func__, (format_version == 2) ? "Jam STAPL" : - "pre-standardized Jam 1.1"); - while (altera_get_note((u8 *)fw->data, fw->size, - &offset, key, value, 256) == 0) - printk(KERN_INFO "%s: NOTE \"%s\" = \"%s\"\n", - __func__, key, value); - } - - if (debug && (format_version == 2) && (action_count > 0)) { - printk(KERN_INFO "%s: Actions available:\n", __func__); - for (index = 0; index < action_count; ++index) { - altera_get_act_info((u8 *)fw->data, fw->size, - index, &action_name, - &description, - &proc_list); - - if (description == NULL) - printk(KERN_INFO "%s: %s\n", - __func__, - action_name); - else - printk(KERN_INFO "%s: %s \"%s\"\n", - __func__, - action_name, - description); - - procptr = proc_list; - while (procptr != NULL) { - if (procptr->attrs != 0) - printk(KERN_INFO "%s: %s (%s)\n", - __func__, - procptr->name, - (procptr->attrs == 1) ? - "optional" : "recommended"); - - proc_list = procptr->next; - kfree(procptr); - procptr = proc_list; - } - } - - printk(KERN_INFO "\n"); - } - - exec_result = altera_execute(astate, (u8 *)fw->data, fw->size, - &error_address, &exit_code, &format_version); - - if (exit_code) - exec_result = -EREMOTEIO; - - if ((format_version == 2) && (exec_result == -EINVAL)) { - if (astate->config->action == NULL) - printk(KERN_ERR "%s: error: no action specified for " - "Jam STAPL file.\nprogram terminated.\n", - __func__); - else - printk(KERN_ERR "%s: error: action \"%s\"" - " is not supported " - "for this Jam STAPL file.\n" - "Program terminated.\n", __func__, - astate->config->action); - - } else if (exec_result) - printk(KERN_ERR "%s: error %d\n", __func__, exec_result); - - kfree(astate); -free_value: - kfree(value); -free_key: - kfree(key); -out: - return retval; -} -EXPORT_SYMBOL(altera_init); diff --git a/drivers/staging/altera-stapl/altera.h b/drivers/staging/altera-stapl/altera.h deleted file mode 100644 index 94c0c6181daf..000000000000 --- a/drivers/staging/altera-stapl/altera.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * altera.h - * - * altera FPGA driver - * - * Copyright (C) Altera Corporation 1998-2001 - * Copyright (C) 2010 NetUP Inc. - * Copyright (C) 2010 Igor M. Liplianin <liplianin@netup.ru> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef _ALTERA_H_ -#define _ALTERA_H_ - -struct altera_config { - void *dev; - u8 *action; - int (*jtag_io) (void *dev, int tms, int tdi, int tdo); -}; - -#if defined(CONFIG_ALTERA_STAPL) || \ - (defined(CONFIG_ALTERA_STAPL_MODULE) && defined(MODULE)) - -extern int altera_init(struct altera_config *config, const struct firmware *fw); -#else - -static inline int altera_init(struct altera_config *config, - const struct firmware *fw) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return 0; -} -#endif /* CONFIG_ALTERA_STAPL */ - -#endif /* _ALTERA_H_ */ diff --git a/drivers/staging/dt3155v4l/dt3155v4l.c b/drivers/staging/dt3155v4l/dt3155v4l.c index 5b212dc725e1..04e93c49f03a 100644 --- a/drivers/staging/dt3155v4l/dt3155v4l.c +++ b/drivers/staging/dt3155v4l/dt3155v4l.c @@ -193,7 +193,7 @@ dt3155_start_acq(struct dt3155_priv *pd) struct vb2_buffer *vb = pd->curr_buf; dma_addr_t dma_addr; - dma_addr = vb2_dma_contig_plane_paddr(vb, 0); + dma_addr = vb2_dma_contig_plane_dma_addr(vb, 0); iowrite32(dma_addr, pd->regs + EVEN_DMA_START); iowrite32(dma_addr + img_width, pd->regs + ODD_DMA_START); iowrite32(img_width, pd->regs + EVEN_DMA_STRIDE); @@ -357,7 +357,7 @@ dt3155_irq_handler_even(int irq, void *dev_id) ivb = list_first_entry(&ipd->dmaq, typeof(*ivb), done_entry); list_del(&ivb->done_entry); ipd->curr_buf = ivb; - dma_addr = vb2_dma_contig_plane_paddr(ivb, 0); + dma_addr = vb2_dma_contig_plane_dma_addr(ivb, 0); iowrite32(dma_addr, ipd->regs + EVEN_DMA_START); iowrite32(dma_addr + img_width, ipd->regs + ODD_DMA_START); iowrite32(img_width, ipd->regs + EVEN_DMA_STRIDE); diff --git a/drivers/staging/tm6000/CARDLIST b/drivers/staging/tm6000/CARDLIST deleted file mode 100644 index b5edce487997..000000000000 --- a/drivers/staging/tm6000/CARDLIST +++ /dev/null @@ -1,16 +0,0 @@ - 1 -> Generic tm5600 board (tm5600) [6000:0001] - 2 -> Generic tm6000 board (tm6000) [6000:0001] - 3 -> Generic tm6010 board (tm6010) [6000:0002] - 4 -> 10Moons UT821 (tm5600) [6000:0001] - 5 -> 10Moons UT330 (tm5600) - 6 -> ADSTech Dual TV (tm6000) [06e1:f332] - 7 -> FreeCom and similar (tm6000) [14aa:0620] - 8 -> ADSTech Mini Dual TV (tm6000) [06e1:b339] - 9 -> Hauppauge WinTV HVR-900H/USB2 Stick (tm6010) [2040:6600,2040:6601,2040:6610,2040:6611] - 10 -> Beholder Wander (tm6010) [6000:dec0] - 11 -> Beholder Voyager (tm6010) [6000:dec1] - 12 -> TerraTec Cinergy Hybrid XE/Cinergy Hybrid Stick (tm6010) [0ccd:0086,0ccd:00a5] - 13 -> TwinHan TU501 (tm6010) [13d3:3240,13d3:3241,13d3:3243,13d3:3264] - 14 -> Beholder Wander Lite (tm6010) [6000:dec2] - 15 -> Beholder Voyager Lite (tm6010) [6000:dec3] - diff --git a/drivers/staging/tm6000/Kconfig b/drivers/staging/tm6000/Kconfig deleted file mode 100644 index 114eec8a630a..000000000000 --- a/drivers/staging/tm6000/Kconfig +++ /dev/null @@ -1,33 +0,0 @@ -config VIDEO_TM6000 - tristate "TV Master TM5600/6000/6010 driver" - depends on VIDEO_DEV && I2C && INPUT && RC_CORE && USB && EXPERIMENTAL - select VIDEO_TUNER - select MEDIA_TUNER_XC2028 - select MEDIA_TUNER_XC5000 - select VIDEOBUF_VMALLOC - help - Support for TM5600/TM6000/TM6010 USB Device - - Since these cards have no MPEG decoder onboard, they transmit - only compressed MPEG data over the usb bus, so you need - an external software decoder to watch TV on your computer. - - Say Y if you own such a device and want to use it. - -config VIDEO_TM6000_ALSA - tristate "TV Master TM5600/6000/6010 audio support" - depends on VIDEO_TM6000 && SND && EXPERIMENTAL - select SND_PCM - ---help--- - This is a video4linux driver for direct (DMA) audio for - TM5600/TM6000/TM6010 USB Devices. - - To compile this driver as a module, choose M here: the - module will be called tm6000-alsa. - -config VIDEO_TM6000_DVB - tristate "DVB Support for tm6000 based TV cards" - depends on VIDEO_TM6000 && DVB_CORE && USB && EXPERIMENTAL - select DVB_ZL10353 - ---help--- - This adds support for DVB cards based on the tm5600/tm6000 chip. diff --git a/drivers/staging/tm6000/Makefile b/drivers/staging/tm6000/Makefile deleted file mode 100644 index 395515b4a888..000000000000 --- a/drivers/staging/tm6000/Makefile +++ /dev/null @@ -1,15 +0,0 @@ -tm6000-y := tm6000-cards.o \ - tm6000-core.o \ - tm6000-i2c.o \ - tm6000-video.o \ - tm6000-stds.o \ - tm6000-input.o - -obj-$(CONFIG_VIDEO_TM6000) += tm6000.o -obj-$(CONFIG_VIDEO_TM6000_ALSA) += tm6000-alsa.o -obj-$(CONFIG_VIDEO_TM6000_DVB) += tm6000-dvb.o - -ccflags-y := -Idrivers/media/video -ccflags-y += -Idrivers/media/common/tuners -ccflags-y += -Idrivers/media/dvb/dvb-core -ccflags-y += -Idrivers/media/dvb/frontends diff --git a/drivers/staging/tm6000/README b/drivers/staging/tm6000/README deleted file mode 100644 index c340ebc2ee9f..000000000000 --- a/drivers/staging/tm6000/README +++ /dev/null @@ -1,22 +0,0 @@ -Todo: - - Fix the loss of some blocks when receiving the video URB's - - Add a lock at tm6000_read_write_usb() to prevent two simultaneous access to the - URB control transfers - - Properly add the locks at tm6000-video - - Add audio support - - Add vbi support - - Add IR support - - Do several cleanups - - I think that frame1/frame0 are inverted. This causes a funny effect at the image. - the fix is trivial, but require some tests - - My tm6010 devices sometimes insist on stop working. I need to turn them off, removing - from my machine and wait for a while for it to work again. I'm starting to think that - it is an overheat issue - is there a workaround that we could do? - - Sometimes, tm6010 doesn't read eeprom at the proper time (hardware bug). So, the device - got miss-detected as a "generic" tm6000. This can be really bad if the tuner is the - Low Power one, as it may result on loading the high power firmware, that could damage - the device. Maybe we may read eeprom to double check, when the device is marked as "generic" - - Coding Style fixes - - sparse cleanups - -Please send patches to linux-media@vger.kernel.org diff --git a/drivers/staging/tm6000/TODO b/drivers/staging/tm6000/TODO deleted file mode 100644 index 135d0ea3ad70..000000000000 --- a/drivers/staging/tm6000/TODO +++ /dev/null @@ -1,8 +0,0 @@ -There a few things to do before putting this driver in production: - - IR NEC with tm5600/6000 TV cards - - IR RC5 with tm5600/6000/6010 TV cards - - CodingStyle; - - Fix audio; - - Fix some panic/OOPS conditions. - -Please send patches to linux-media@vger.kernel.org diff --git a/drivers/staging/tm6000/tm6000-alsa.c b/drivers/staging/tm6000/tm6000-alsa.c deleted file mode 100644 index bd5fa89af07c..000000000000 --- a/drivers/staging/tm6000/tm6000-alsa.c +++ /dev/null @@ -1,512 +0,0 @@ -/* - * - * Support for audio capture for tm5600/6000/6010 - * (c) 2007-2008 Mauro Carvalho Chehab <mchehab@redhat.com> - * - * Based on cx88-alsa.c - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include <linux/module.h> -#include <linux/init.h> -#include <linux/device.h> -#include <linux/interrupt.h> -#include <linux/usb.h> -#include <linux/slab.h> -#include <linux/vmalloc.h> - -#include <linux/delay.h> -#include <sound/core.h> -#include <sound/pcm.h> -#include <sound/pcm_params.h> -#include <sound/control.h> -#include <sound/initval.h> - - -#include "tm6000.h" -#include "tm6000-regs.h" - -#undef dprintk - -#define dprintk(level, fmt, arg...) do { \ - if (debug >= level) \ - printk(KERN_INFO "%s/1: " fmt, chip->core->name , ## arg); \ - } while (0) - -/**************************************************************************** - Module global static vars - ****************************************************************************/ - -static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ - -static int enable[SNDRV_CARDS] = {1, [1 ... (SNDRV_CARDS - 1)] = 1}; - -module_param_array(enable, bool, NULL, 0444); -MODULE_PARM_DESC(enable, "Enable tm6000x soundcard. default enabled."); - -module_param_array(index, int, NULL, 0444); -MODULE_PARM_DESC(index, "Index value for tm6000x capture interface(s)."); - - -/**************************************************************************** - Module macros - ****************************************************************************/ - -MODULE_DESCRIPTION("ALSA driver module for tm5600/tm6000/tm6010 based TV cards"); -MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>"); -MODULE_LICENSE("GPL"); -MODULE_SUPPORTED_DEVICE("{{Trident,tm5600}," - "{{Trident,tm6000}," - "{{Trident,tm6010}"); -static unsigned int debug; -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "enable debug messages"); - -/**************************************************************************** - Module specific funtions - ****************************************************************************/ - -/* - * BOARD Specific: Sets audio DMA - */ - -static int _tm6000_start_audio_dma(struct snd_tm6000_card *chip) -{ - struct tm6000_core *core = chip->core; - - dprintk(1, "Starting audio DMA\n"); - - /* Enables audio */ - tm6000_set_reg_mask(core, TM6010_REQ07_RCC_ACTIVE_VIDEO_IF, 0x40, 0x40); - - tm6000_set_audio_bitrate(core, 48000); - - return 0; -} - -/* - * BOARD Specific: Resets audio DMA - */ -static int _tm6000_stop_audio_dma(struct snd_tm6000_card *chip) -{ - struct tm6000_core *core = chip->core; - - dprintk(1, "Stopping audio DMA\n"); - - /* Disables audio */ - tm6000_set_reg_mask(core, TM6010_REQ07_RCC_ACTIVE_VIDEO_IF, 0x00, 0x40); - - return 0; -} - -static void dsp_buffer_free(struct snd_pcm_substream *substream) -{ - struct snd_tm6000_card *chip = snd_pcm_substream_chip(substream); - - dprintk(2, "Freeing buffer\n"); - - vfree(substream->runtime->dma_area); - substream->runtime->dma_area = NULL; - substream->runtime->dma_bytes = 0; -} - -static int dsp_buffer_alloc(struct snd_pcm_substream *substream, int size) -{ - struct snd_tm6000_card *chip = snd_pcm_substream_chip(substream); - - dprintk(2, "Allocating buffer\n"); - - if (substream->runtime->dma_area) { - if (substream->runtime->dma_bytes > size) - return 0; - - dsp_buffer_free(substream); - } - - substream->runtime->dma_area = vmalloc(size); - if (!substream->runtime->dma_area) - return -ENOMEM; - - substream->runtime->dma_bytes = size; - - return 0; -} - - -/**************************************************************************** - ALSA PCM Interface - ****************************************************************************/ - -/* - * Digital hardware definition - */ -#define DEFAULT_FIFO_SIZE 4096 - -static struct snd_pcm_hardware snd_tm6000_digital_hw = { - .info = SNDRV_PCM_INFO_MMAP | - SNDRV_PCM_INFO_INTERLEAVED | - SNDRV_PCM_INFO_BLOCK_TRANSFER | - SNDRV_PCM_INFO_MMAP_VALID, - .formats = SNDRV_PCM_FMTBIT_S16_LE, - - .rates = SNDRV_PCM_RATE_CONTINUOUS, - .rate_min = 48000, - .rate_max = 48000, - .channels_min = 2, - .channels_max = 2, - .period_bytes_min = 64, - .period_bytes_max = 12544, - .periods_min = 1, - .periods_max = 98, - .buffer_bytes_max = 62720 * 8, -}; - -/* - * audio pcm capture open callback - */ -static int snd_tm6000_pcm_open(struct snd_pcm_substream *substream) -{ - struct snd_tm6000_card *chip = snd_pcm_substream_chip(substream); - struct snd_pcm_runtime *runtime = substream->runtime; - int err; - - err = snd_pcm_hw_constraint_pow2(runtime, 0, - SNDRV_PCM_HW_PARAM_PERIODS); - if (err < 0) - goto _error; - - chip->substream = substream; - - runtime->hw = snd_tm6000_digital_hw; - - return 0; -_error: - dprintk(1, "Error opening PCM!\n"); - return err; -} - -/* - * audio close callback - */ -static int snd_tm6000_close(struct snd_pcm_substream *substream) -{ - struct snd_tm6000_card *chip = snd_pcm_substream_chip(substream); - struct tm6000_core *core = chip->core; - - if (atomic_read(&core->stream_started) > 0) { - atomic_set(&core->stream_started, 0); - schedule_work(&core->wq_trigger); - } - - return 0; -} - -static int tm6000_fillbuf(struct tm6000_core *core, char *buf, int size) -{ - struct snd_tm6000_card *chip = core->adev; - struct snd_pcm_substream *substream = chip->substream; - struct snd_pcm_runtime *runtime; - int period_elapsed = 0; - unsigned int stride, buf_pos; - int length; - - if (atomic_read(&core->stream_started) == 0) - return 0; - - if (!size || !substream) { - dprintk(1, "substream was NULL\n"); - return -EINVAL; - } - - runtime = substream->runtime; - if (!runtime || !runtime->dma_area) { - dprintk(1, "runtime was NULL\n"); - return -EINVAL; - } - - buf_pos = chip->buf_pos; - stride = runtime->frame_bits >> 3; - - if (stride == 0) { - dprintk(1, "stride is zero\n"); - return -EINVAL; - } - - length = size / stride; - if (length == 0) { - dprintk(1, "%s: length was zero\n", __func__); - return -EINVAL; - } - - dprintk(1, "Copying %d bytes at %p[%d] - buf size=%d x %d\n", size, - runtime->dma_area, buf_pos, - (unsigned int)runtime->buffer_size, stride); - - if (buf_pos + length >= runtime->buffer_size) { - unsigned int cnt = runtime->buffer_size - buf_pos; - memcpy(runtime->dma_area + buf_pos * stride, buf, cnt * stride); - memcpy(runtime->dma_area, buf + cnt * stride, - length * stride - cnt * stride); - } else - memcpy(runtime->dma_area + buf_pos * stride, buf, - length * stride); - - snd_pcm_stream_lock(substream); - - chip->buf_pos += length; - if (chip->buf_pos >= runtime->buffer_size) - chip->buf_pos -= runtime->buffer_size; - - chip->period_pos += length; - if (chip->period_pos >= runtime->period_size) { - chip->period_pos -= runtime->period_size; - period_elapsed = 1; - } - - snd_pcm_stream_unlock(substream); - - if (period_elapsed) - snd_pcm_period_elapsed(substream); - - return 0; -} - -/* - * hw_params callback - */ -static int snd_tm6000_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *hw_params) -{ - int size, rc; - - size = params_period_bytes(hw_params) * params_periods(hw_params); - - rc = dsp_buffer_alloc(substream, size); - if (rc < 0) - return rc; - - return 0; -} - -/* - * hw free callback - */ -static int snd_tm6000_hw_free(struct snd_pcm_substream *substream) -{ - struct snd_tm6000_card *chip = snd_pcm_substream_chip(substream); - struct tm6000_core *core = chip->core; - - if (atomic_read(&core->stream_started) > 0) { - atomic_set(&core->stream_started, 0); - schedule_work(&core->wq_trigger); - } - - return 0; -} - -/* - * prepare callback - */ -static int snd_tm6000_prepare(struct snd_pcm_substream *substream) -{ - struct snd_tm6000_card *chip = snd_pcm_substream_chip(substream); - - chip->buf_pos = 0; - chip->period_pos = 0; - - return 0; -} - - -/* - * trigger callback - */ -static void audio_trigger(struct work_struct *work) -{ - struct tm6000_core *core = container_of(work, struct tm6000_core, - wq_trigger); - struct snd_tm6000_card *chip = core->adev; - - if (atomic_read(&core->stream_started)) { - dprintk(1, "starting capture"); - _tm6000_start_audio_dma(chip); - } else { - dprintk(1, "stopping capture"); - _tm6000_stop_audio_dma(chip); - } -} - -static int snd_tm6000_card_trigger(struct snd_pcm_substream *substream, int cmd) -{ - struct snd_tm6000_card *chip = snd_pcm_substream_chip(substream); - struct tm6000_core *core = chip->core; - int err = 0; - - switch (cmd) { - case SNDRV_PCM_TRIGGER_START: - atomic_set(&core->stream_started, 1); - break; - case SNDRV_PCM_TRIGGER_STOP: - atomic_set(&core->stream_started, 0); - break; - default: - err = -EINVAL; - break; - } - schedule_work(&core->wq_trigger); - - return err; -} -/* - * pointer callback - */ -static snd_pcm_uframes_t snd_tm6000_pointer(struct snd_pcm_substream *substream) -{ - struct snd_tm6000_card *chip = snd_pcm_substream_chip(substream); - - return chip->buf_pos; -} - -/* - * operators - */ -static struct snd_pcm_ops snd_tm6000_pcm_ops = { - .open = snd_tm6000_pcm_open, - .close = snd_tm6000_close, - .ioctl = snd_pcm_lib_ioctl, - .hw_params = snd_tm6000_hw_params, - .hw_free = snd_tm6000_hw_free, - .prepare = snd_tm6000_prepare, - .trigger = snd_tm6000_card_trigger, - .pointer = snd_tm6000_pointer, -}; - -/* - * create a PCM device - */ - -/* FIXME: Control interface - How to control volume/mute? */ - -/**************************************************************************** - Basic Flow for Sound Devices - ****************************************************************************/ - -/* - * Alsa Constructor - Component probe - */ -int tm6000_audio_init(struct tm6000_core *dev) -{ - struct snd_card *card; - struct snd_tm6000_card *chip; - int rc; - static int devnr; - char component[14]; - struct snd_pcm *pcm; - - if (!dev) - return 0; - - if (devnr >= SNDRV_CARDS) - return -ENODEV; - - if (!enable[devnr]) - return -ENOENT; - - rc = snd_card_create(index[devnr], "tm6000", THIS_MODULE, 0, &card); - if (rc < 0) { - snd_printk(KERN_ERR "cannot create card instance %d\n", devnr); - return rc; - } - strcpy(card->driver, "tm6000-alsa"); - strcpy(card->shortname, "TM5600/60x0"); - sprintf(card->longname, "TM5600/60x0 Audio at bus %d device %d", - dev->udev->bus->busnum, dev->udev->devnum); - - sprintf(component, "USB%04x:%04x", - le16_to_cpu(dev->udev->descriptor.idVendor), - le16_to_cpu(dev->udev->descriptor.idProduct)); - snd_component_add(card, component); - snd_card_set_dev(card, &dev->udev->dev); - - chip = kzalloc(sizeof(struct snd_tm6000_card), GFP_KERNEL); - if (!chip) { - rc = -ENOMEM; - goto error; - } - - chip->core = dev; - chip->card = card; - dev->adev = chip; - spin_lock_init(&chip->reg_lock); - - rc = snd_pcm_new(card, "TM6000 Audio", 0, 0, 1, &pcm); - if (rc < 0) - goto error_chip; - - pcm->info_flags = 0; - pcm->private_data = chip; - strcpy(pcm->name, "Trident TM5600/60x0"); - - snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_tm6000_pcm_ops); - - INIT_WORK(&dev->wq_trigger, audio_trigger); - rc = snd_card_register(card); - if (rc < 0) - goto error_chip; - - dprintk(1, "Registered audio driver for %s\n", card->longname); - - return 0; - -error_chip: - kfree(chip); - dev->adev = NULL; -error: - snd_card_free(card); - return rc; -} - -static int tm6000_audio_fini(struct tm6000_core *dev) -{ - struct snd_tm6000_card *chip = dev->adev; - - if (!dev) - return 0; - - if (!chip) - return 0; - - if (!chip->card) - return 0; - - snd_card_free(chip->card); - chip->card = NULL; - kfree(chip); - dev->adev = NULL; - - return 0; -} - -struct tm6000_ops audio_ops = { - .type = TM6000_AUDIO, - .name = "TM6000 Audio Extension", - .init = tm6000_audio_init, - .fini = tm6000_audio_fini, - .fillbuf = tm6000_fillbuf, -}; - -static int __init tm6000_alsa_register(void) -{ - return tm6000_register_extension(&audio_ops); -} - -static void __exit tm6000_alsa_unregister(void) -{ - tm6000_unregister_extension(&audio_ops); -} - -module_init(tm6000_alsa_register); -module_exit(tm6000_alsa_unregister); diff --git a/drivers/staging/tm6000/tm6000-cards.c b/drivers/staging/tm6000/tm6000-cards.c deleted file mode 100644 index 9227db5d8955..000000000000 --- a/drivers/staging/tm6000/tm6000-cards.c +++ /dev/null @@ -1,1382 +0,0 @@ -/* - * tm6000-cards.c - driver for TM5600/TM6000/TM6010 USB video capture devices - * - * Copyright (C) 2006-2007 Mauro Carvalho Chehab <mchehab@infradead.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation version 2 - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include <linux/init.h> -#include <linux/module.h> -#include <linux/pci.h> -#include <linux/delay.h> -#include <linux/i2c.h> -#include <linux/usb.h> -#include <linux/slab.h> -#include <media/v4l2-common.h> -#include <media/tuner.h> -#include <media/tvaudio.h> -#include <media/i2c-addr.h> -#include <media/rc-map.h> - -#include "tm6000.h" -#include "tm6000-regs.h" -#include "tuner-xc2028.h" -#include "xc5000.h" - -#define TM6000_BOARD_UNKNOWN 0 -#define TM5600_BOARD_GENERIC 1 -#define TM6000_BOARD_GENERIC 2 -#define TM6010_BOARD_GENERIC 3 -#define TM5600_BOARD_10MOONS_UT821 4 -#define TM5600_BOARD_10MOONS_UT330 5 -#define TM6000_BOARD_ADSTECH_DUAL_TV 6 -#define TM6000_BOARD_FREECOM_AND_SIMILAR 7 -#define TM6000_BOARD_ADSTECH_MINI_DUAL_TV 8 -#define TM6010_BOARD_HAUPPAUGE_900H 9 -#define TM6010_BOARD_BEHOLD_WANDER 10 -#define TM6010_BOARD_BEHOLD_VOYAGER 11 -#define TM6010_BOARD_TERRATEC_CINERGY_HYBRID_XE 12 -#define TM6010_BOARD_TWINHAN_TU501 13 -#define TM6010_BOARD_BEHOLD_WANDER_LITE 14 -#define TM6010_BOARD_BEHOLD_VOYAGER_LITE 15 -#define TM5600_BOARD_TERRATEC_GRABSTER 16 - -#define is_generic(model) ((model == TM6000_BOARD_UNKNOWN) || \ - (model == TM5600_BOARD_GENERIC) || \ - (model == TM6000_BOARD_GENERIC) || \ - (model == TM6010_BOARD_GENERIC)) - -#define TM6000_MAXBOARDS 16 -static unsigned int card[] = {[0 ... (TM6000_MAXBOARDS - 1)] = UNSET }; - -module_param_array(card, int, NULL, 0444); - -static unsigned long tm6000_devused; - - -struct tm6000_board { - char *name; - char eename[16]; /* EEPROM name */ - unsigned eename_size; /* size of EEPROM name */ - unsigned eename_pos; /* Position where it appears at ROM */ - - struct tm6000_capabilities caps; - - enum tm6000_devtype type; /* variant of the chipset */ - int tuner_type; /* type of the tuner */ - int tuner_addr; /* tuner address */ - int demod_addr; /* demodulator address */ - - struct tm6000_gpio gpio; - - struct tm6000_input vinput[3]; - struct tm6000_input rinput; - - char *ir_codes; -}; - -struct tm6000_board tm6000_boards[] = { - [TM6000_BOARD_UNKNOWN] = { - .name = "Unknown tm6000 video grabber", - .caps = { - .has_tuner = 1, - .has_eeprom = 1, - }, - .gpio = { - .tuner_reset = TM6000_GPIO_1, - }, - .vinput = { { - .type = TM6000_INPUT_TV, - .vmux = TM6000_VMUX_VIDEO_B, - .amux = TM6000_AMUX_ADC1, - }, { - .type = TM6000_INPUT_COMPOSITE1, - .vmux = TM6000_VMUX_VIDEO_A, - .amux = TM6000_AMUX_ADC2, - }, { - .type = TM6000_INPUT_SVIDEO, - .vmux = TM6000_VMUX_VIDEO_AB, - .amux = TM6000_AMUX_ADC2, - }, - }, - }, - [TM5600_BOARD_GENERIC] = { - .name = "Generic tm5600 board", - .type = TM5600, - .tuner_type = TUNER_XC2028, - .tuner_addr = 0xc2 >> 1, - .caps = { - .has_tuner = 1, - .has_eeprom = 1, - }, - .gpio = { - .tuner_reset = TM6000_GPIO_1, - }, - .vinput = { { - .type = TM6000_INPUT_TV, - .vmux = TM6000_VMUX_VIDEO_B, - .amux = TM6000_AMUX_ADC1, - }, { - .type = TM6000_INPUT_COMPOSITE1, - .vmux = TM6000_VMUX_VIDEO_A, - .amux = TM6000_AMUX_ADC2, - }, { - .type = TM6000_INPUT_SVIDEO, - .vmux = TM6000_VMUX_VIDEO_AB, - .amux = TM6000_AMUX_ADC2, - }, - }, - }, - [TM6000_BOARD_GENERIC] = { - .name = "Generic tm6000 board", - .tuner_type = TUNER_XC2028, - .tuner_addr = 0xc2 >> 1, - .caps = { - .has_tuner = 1, - .has_eeprom = 1, - }, - .gpio = { - .tuner_reset = TM6000_GPIO_1, - }, - .vinput = { { - .type = TM6000_INPUT_TV, - .vmux = TM6000_VMUX_VIDEO_B, - .amux = TM6000_AMUX_ADC1, - }, { - .type = TM6000_INPUT_COMPOSITE1, - .vmux = TM6000_VMUX_VIDEO_A, - .amux = TM6000_AMUX_ADC2, - }, { - .type = TM6000_INPUT_SVIDEO, - .vmux = TM6000_VMUX_VIDEO_AB, - .amux = TM6000_AMUX_ADC2, - }, - }, - }, - [TM6010_BOARD_GENERIC] = { - .name = "Generic tm6010 board", - .type = TM6010, - .tuner_type = TUNER_XC2028, - .tuner_addr = 0xc2 >> 1, - .demod_addr = 0x1e >> 1, - .caps = { - .has_tuner = 1, - .has_dvb = 1, - .has_zl10353 = 1, - .has_eeprom = 1, - .has_remote = 1, - }, - .gpio = { - .tuner_reset = TM6010_GPIO_2, - .tuner_on = TM6010_GPIO_3, - .demod_reset = TM6010_GPIO_1, - .demod_on = TM6010_GPIO_4, - .power_led = TM6010_GPIO_7, - .dvb_led = TM6010_GPIO_5, - .ir = TM6010_GPIO_0, - }, - .vinput = { { - .type = TM6000_INPUT_TV, - .vmux = TM6000_VMUX_VIDEO_B, - .amux = TM6000_AMUX_SIF1, - }, { - .type = TM6000_INPUT_COMPOSITE1, - .vmux = TM6000_VMUX_VIDEO_A, - .amux = TM6000_AMUX_ADC2, - }, { - .type = TM6000_INPUT_SVIDEO, - .vmux = TM6000_VMUX_VIDEO_AB, - .amux = TM6000_AMUX_ADC2, - }, - }, - }, - [TM5600_BOARD_10MOONS_UT821] = { - .name = "10Moons UT 821", - .tuner_type = TUNER_XC2028, - .eename = { '1', '0', 'M', 'O', 'O', 'N', 'S', '5', '6', '0', '0', 0xff, 0x45, 0x5b}, - .eename_size = 14, - .eename_pos = 0x14, - .type = TM5600, - .tuner_addr = 0xc2 >> 1, - .caps = { - .has_tuner = 1, - .has_eeprom = 1, - }, - .gpio = { - .tuner_reset = TM6000_GPIO_1, - }, - .vinput = { { - .type = TM6000_INPUT_TV, - .vmux = TM6000_VMUX_VIDEO_B, - .amux = TM6000_AMUX_ADC1, - }, { - .type = TM6000_INPUT_COMPOSITE1, - .vmux = TM6000_VMUX_VIDEO_A, - .amux = TM6000_AMUX_ADC2, - }, { - .type = TM6000_INPUT_SVIDEO, - .vmux = TM6000_VMUX_VIDEO_AB, - .amux = TM6000_AMUX_ADC2, - }, - }, - }, - [TM5600_BOARD_10MOONS_UT330] = { - .name = "10Moons UT 330", - .tuner_type = TUNER_PHILIPS_FQ1216AME_MK4, - .tuner_addr = 0xc8 >> 1, - .caps = { - .has_tuner = 1, - .has_dvb = 0, - .has_zl10353 = 0, - .has_eeprom = 1, - }, - .vinput = { { - .type = TM6000_INPUT_TV, - .vmux = TM6000_VMUX_VIDEO_B, - .amux = TM6000_AMUX_ADC1, - }, { - .type = TM6000_INPUT_COMPOSITE1, - .vmux = TM6000_VMUX_VIDEO_A, - .amux = TM6000_AMUX_ADC2, - }, { - .type = TM6000_INPUT_SVIDEO, - .vmux = TM6000_VMUX_VIDEO_AB, - .amux = TM6000_AMUX_ADC2, - }, - }, - }, - [TM6000_BOARD_ADSTECH_DUAL_TV] = { - .name = "ADSTECH Dual TV USB", - .tuner_type = TUNER_XC2028, - .tuner_addr = 0xc8 >> 1, - .caps = { - .has_tuner = 1, - .has_tda9874 = 1, - .has_dvb = 1, - .has_zl10353 = 1, - .has_eeprom = 1, - }, - .vinput = { { - .type = TM6000_INPUT_TV, - .vmux = TM6000_VMUX_VIDEO_B, - .amux = TM6000_AMUX_ADC1, - }, { - .type = TM6000_INPUT_COMPOSITE1, - .vmux = TM6000_VMUX_VIDEO_A, - .amux = TM6000_AMUX_ADC2, - }, { - .type = TM6000_INPUT_SVIDEO, - .vmux = TM6000_VMUX_VIDEO_AB, - .amux = TM6000_AMUX_ADC2, - }, - }, - }, - [TM6000_BOARD_FREECOM_AND_SIMILAR] = { - .name = "Freecom Hybrid Stick / Moka DVB-T Receiver Dual", - .tuner_type = TUNER_XC2028, /* has a XC3028 */ - .tuner_addr = 0xc2 >> 1, - .demod_addr = 0x1e >> 1, - .caps = { - .has_tuner = 1, - .has_dvb = 1, - .has_zl10353 = 1, - .has_eeprom = 0, - .has_remote = 1, - }, - .gpio = { - .tuner_reset = TM6000_GPIO_4, - }, - .vinput = { { - .type = TM6000_INPUT_TV, - .vmux = TM6000_VMUX_VIDEO_B, - .amux = TM6000_AMUX_ADC1, - }, { - .type = TM6000_INPUT_COMPOSITE1, - .vmux = TM6000_VMUX_VIDEO_A, - .amux = TM6000_AMUX_ADC2, - }, { - .type = TM6000_INPUT_SVIDEO, - .vmux = TM6000_VMUX_VIDEO_AB, - .amux = TM6000_AMUX_ADC2, - }, - }, - }, - [TM6000_BOARD_ADSTECH_MINI_DUAL_TV] = { - .name = "ADSTECH Mini Dual TV USB", - .tuner_type = TUNER_XC2028, /* has a XC3028 */ - .tuner_addr = 0xc8 >> 1, - .demod_addr = 0x1e >> 1, - .caps = { - .has_tuner = 1, - .has_dvb = 1, - .has_zl10353 = 1, - .has_eeprom = 0, - }, - .gpio = { - .tuner_reset = TM6000_GPIO_4, - }, - .vinput = { { - .type = TM6000_INPUT_TV, - .vmux = TM6000_VMUX_VIDEO_B, - .amux = TM6000_AMUX_ADC1, - }, { - .type = TM6000_INPUT_COMPOSITE1, - .vmux = TM6000_VMUX_VIDEO_A, - .amux = TM6000_AMUX_ADC2, - }, { - .type = TM6000_INPUT_SVIDEO, - .vmux = TM6000_VMUX_VIDEO_AB, - .amux = TM6000_AMUX_ADC2, - }, - }, - }, - [TM6010_BOARD_HAUPPAUGE_900H] = { - .name = "Hauppauge WinTV HVR-900H / WinTV USB2-Stick", - .eename = { 'H', 0, 'V', 0, 'R', 0, '9', 0, '0', 0, '0', 0, 'H', 0 }, - .eename_size = 14, - .eename_pos = 0x42, - .tuner_type = TUNER_XC2028, /* has a XC3028 */ - .tuner_addr = 0xc2 >> 1, - .demod_addr = 0x1e >> 1, - .type = TM6010, - .caps = { - .has_tuner = 1, - .has_dvb = 1, - .has_zl10353 = 1, - .has_eeprom = 1, - .has_remote = 1, - }, - .gpio = { - .tuner_reset = TM6010_GPIO_2, - .tuner_on = TM6010_GPIO_3, - .demod_reset = TM6010_GPIO_1, - .demod_on = TM6010_GPIO_4, - .power_led = TM6010_GPIO_7, - .dvb_led = TM6010_GPIO_5, - .ir = TM6010_GPIO_0, - }, - .vinput = { { - .type = TM6000_INPUT_TV, - .vmux = TM6000_VMUX_VIDEO_B, - .amux = TM6000_AMUX_SIF1, - }, { - .type = TM6000_INPUT_COMPOSITE1, - .vmux = TM6000_VMUX_VIDEO_A, - .amux = TM6000_AMUX_ADC2, - }, { - .type = TM6000_INPUT_SVIDEO, - .vmux = TM6000_VMUX_VIDEO_AB, - .amux = TM6000_AMUX_ADC2, - }, - }, - }, - [TM6010_BOARD_BEHOLD_WANDER] = { - .name = "Beholder Wander DVB-T/TV/FM USB2.0", - .tuner_type = TUNER_XC5000, - .tuner_addr = 0xc2 >> 1, - .demod_addr = 0x1e >> 1, - .type = TM6010, - .caps = { - .has_tuner = 1, - .has_dvb = 1, - .has_zl10353 = 1, - .has_eeprom = 1, - .has_remote = 1, - .has_radio = 1. - }, - .gpio = { - .tuner_reset = TM6010_GPIO_0, - .demod_reset = TM6010_GPIO_1, - .power_led = TM6010_GPIO_6, - }, - .vinput = { { - .type = TM6000_INPUT_TV, - .vmux = TM6000_VMUX_VIDEO_B, - .amux = TM6000_AMUX_SIF1, - }, { - .type = TM6000_INPUT_COMPOSITE1, - .vmux = TM6000_VMUX_VIDEO_A, - .amux = TM6000_AMUX_ADC2, - }, { - .type = TM6000_INPUT_SVIDEO, - .vmux = TM6000_VMUX_VIDEO_AB, - .amux = TM6000_AMUX_ADC2, - }, - }, - .rinput = { - .type = TM6000_INPUT_RADIO, - .amux = TM6000_AMUX_ADC1, - }, - }, - [TM6010_BOARD_BEHOLD_VOYAGER] = { - .name = "Beholder Voyager TV/FM USB2.0", - .tuner_type = TUNER_XC5000, - .tuner_addr = 0xc2 >> 1, - .type = TM6010, - .caps = { - .has_tuner = 1, - .has_dvb = 0, - .has_zl10353 = 0, - .has_eeprom = 1, - .has_remote = 1, - .has_radio = 1, - }, - .gpio = { - .tuner_reset = TM6010_GPIO_0, - .power_led = TM6010_GPIO_6, - }, - .vinput = { { - .type = TM6000_INPUT_TV, - .vmux = TM6000_VMUX_VIDEO_B, - .amux = TM6000_AMUX_SIF1, - }, { - .type = TM6000_INPUT_COMPOSITE1, - .vmux = TM6000_VMUX_VIDEO_A, - .amux = TM6000_AMUX_ADC2, - }, { - .type = TM6000_INPUT_SVIDEO, - .vmux = TM6000_VMUX_VIDEO_AB, - .amux = TM6000_AMUX_ADC2, - }, - }, - .rinput = { - .type = TM6000_INPUT_RADIO, - .amux = TM6000_AMUX_ADC1, - }, - }, - [TM6010_BOARD_TERRATEC_CINERGY_HYBRID_XE] = { - .name = "Terratec Cinergy Hybrid XE / Cinergy Hybrid-Stick", - .tuner_type = TUNER_XC2028, /* has a XC3028 */ - .tuner_addr = 0xc2 >> 1, - .demod_addr = 0x1e >> 1, - .type = TM6010, - .caps = { - .has_tuner = 1, - .has_dvb = 1, - .has_zl10353 = 1, - .has_eeprom = 1, - .has_remote = 1, - }, - .gpio = { - .tuner_reset = TM6010_GPIO_2, - .tuner_on = TM6010_GPIO_3, - .demod_reset = TM6010_GPIO_1, - .demod_on = TM6010_GPIO_4, - .power_led = TM6010_GPIO_7, - .dvb_led = TM6010_GPIO_5, - .ir = TM6010_GPIO_0, - }, - .ir_codes = RC_MAP_NEC_TERRATEC_CINERGY_XS, - .vinput = { { - .type = TM6000_INPUT_TV, - .vmux = TM6000_VMUX_VIDEO_B, - .amux = TM6000_AMUX_SIF1, - }, { - .type = TM6000_INPUT_COMPOSITE1, - .vmux = TM6000_VMUX_VIDEO_A, - .amux = TM6000_AMUX_ADC2, - }, { - .type = TM6000_INPUT_SVIDEO, - .vmux = TM6000_VMUX_VIDEO_AB, - .amux = TM6000_AMUX_ADC2, - }, - }, - }, - [TM5600_BOARD_TERRATEC_GRABSTER] = { - .name = "Terratec Grabster AV 150/250 MX", - .type = TM5600, - .tuner_type = TUNER_ABSENT, - .vinput = { { - .type = TM6000_INPUT_TV, - .vmux = TM6000_VMUX_VIDEO_B, - .amux = TM6000_AMUX_ADC1, - }, { - .type = TM6000_INPUT_COMPOSITE1, - .vmux = TM6000_VMUX_VIDEO_A, - .amux = TM6000_AMUX_ADC2, - }, { - .type = TM6000_INPUT_SVIDEO, - .vmux = TM6000_VMUX_VIDEO_AB, - .amux = TM6000_AMUX_ADC2, - }, - }, - }, - [TM6010_BOARD_TWINHAN_TU501] = { - .name = "Twinhan TU501(704D1)", - .tuner_type = TUNER_XC2028, /* has a XC3028 */ - .tuner_addr = 0xc2 >> 1, - .demod_addr = 0x1e >> 1, - .type = TM6010, - .caps = { - .has_tuner = 1, - .has_dvb = 1, - .has_zl10353 = 1, - .has_eeprom = 1, - .has_remote = 1, - }, - .gpio = { - .tuner_reset = TM6010_GPIO_2, - .tuner_on = TM6010_GPIO_3, - .demod_reset = TM6010_GPIO_1, - .demod_on = TM6010_GPIO_4, - .power_led = TM6010_GPIO_7, - .dvb_led = TM6010_GPIO_5, - .ir = TM6010_GPIO_0, - }, - .vinput = { { - .type = TM6000_INPUT_TV, - .vmux = TM6000_VMUX_VIDEO_B, - .amux = TM6000_AMUX_SIF1, - }, { - .type = TM6000_INPUT_COMPOSITE1, - .vmux = TM6000_VMUX_VIDEO_A, - .amux = TM6000_AMUX_ADC2, - }, { - .type = TM6000_INPUT_SVIDEO, - .vmux = TM6000_VMUX_VIDEO_AB, - .amux = TM6000_AMUX_ADC2, - }, - }, - }, - [TM6010_BOARD_BEHOLD_WANDER_LITE] = { - .name = "Beholder Wander Lite DVB-T/TV/FM USB2.0", - .tuner_type = TUNER_XC5000, - .tuner_addr = 0xc2 >> 1, - .demod_addr = 0x1e >> 1, - .type = TM6010, - .caps = { - .has_tuner = 1, - .has_dvb = 1, - .has_zl10353 = 1, - .has_eeprom = 1, - .has_remote = 0, - .has_radio = 1, - }, - .gpio = { - .tuner_reset = TM6010_GPIO_0, - .demod_reset = TM6010_GPIO_1, - .power_led = TM6010_GPIO_6, - }, - .vinput = { { - .type = TM6000_INPUT_TV, - .vmux = TM6000_VMUX_VIDEO_B, - .amux = TM6000_AMUX_SIF1, - }, - }, - .rinput = { - .type = TM6000_INPUT_RADIO, - .amux = TM6000_AMUX_ADC1, - }, - }, - [TM6010_BOARD_BEHOLD_VOYAGER_LITE] = { - .name = "Beholder Voyager Lite TV/FM USB2.0", - .tuner_type = TUNER_XC5000, - .tuner_addr = 0xc2 >> 1, - .type = TM6010, - .caps = { - .has_tuner = 1, - .has_dvb = 0, - .has_zl10353 = 0, - .has_eeprom = 1, - .has_remote = 0, - .has_radio = 1, - }, - .gpio = { - .tuner_reset = TM6010_GPIO_0, - .power_led = TM6010_GPIO_6, - }, - .vinput = { { - .type = TM6000_INPUT_TV, - .vmux = TM6000_VMUX_VIDEO_B, - .amux = TM6000_AMUX_SIF1, - }, - }, - .rinput = { - .type = TM6000_INPUT_RADIO, - .amux = TM6000_AMUX_ADC1, - }, - }, -}; - -/* table of devices that work with this driver */ -struct usb_device_id tm6000_id_table[] = { - { USB_DEVICE(0x6000, 0x0001), .driver_info = TM5600_BOARD_GENERIC }, - { USB_DEVICE(0x6000, 0x0002), .driver_info = TM6010_BOARD_GENERIC }, - { USB_DEVICE(0x06e1, 0xf332), .driver_info = TM6000_BOARD_ADSTECH_DUAL_TV }, - { USB_DEVICE(0x14aa, 0x0620), .driver_info = TM6000_BOARD_FREECOM_AND_SIMILAR }, - { USB_DEVICE(0x06e1, 0xb339), .driver_info = TM6000_BOARD_ADSTECH_MINI_DUAL_TV }, - { USB_DEVICE(0x2040, 0x6600), .driver_info = TM6010_BOARD_HAUPPAUGE_900H }, - { USB_DEVICE(0x2040, 0x6601), .driver_info = TM6010_BOARD_HAUPPAUGE_900H }, - { USB_DEVICE(0x2040, 0x6610), .driver_info = TM6010_BOARD_HAUPPAUGE_900H }, - { USB_DEVICE(0x2040, 0x6611), .driver_info = TM6010_BOARD_HAUPPAUGE_900H }, - { USB_DEVICE(0x6000, 0xdec0), .driver_info = TM6010_BOARD_BEHOLD_WANDER }, - { USB_DEVICE(0x6000, 0xdec1), .driver_info = TM6010_BOARD_BEHOLD_VOYAGER }, - { USB_DEVICE(0x0ccd, 0x0086), .driver_info = TM6010_BOARD_TERRATEC_CINERGY_HYBRID_XE }, - { USB_DEVICE(0x0ccd, 0x00A5), .driver_info = TM6010_BOARD_TERRATEC_CINERGY_HYBRID_XE }, - { USB_DEVICE(0x0ccd, 0x0079), .driver_info = TM5600_BOARD_TERRATEC_GRABSTER }, - { USB_DEVICE(0x13d3, 0x3240), .driver_info = TM6010_BOARD_TWINHAN_TU501 }, - { USB_DEVICE(0x13d3, 0x3241), .driver_info = TM6010_BOARD_TWINHAN_TU501 }, - { USB_DEVICE(0x13d3, 0x3243), .driver_info = TM6010_BOARD_TWINHAN_TU501 }, - { USB_DEVICE(0x13d3, 0x3264), .driver_info = TM6010_BOARD_TWINHAN_TU501 }, - { USB_DEVICE(0x6000, 0xdec2), .driver_info = TM6010_BOARD_BEHOLD_WANDER_LITE }, - { USB_DEVICE(0x6000, 0xdec3), .driver_info = TM6010_BOARD_BEHOLD_VOYAGER_LITE }, - { }, -}; - -/* Control power led for show some activity */ -void tm6000_flash_led(struct tm6000_core *dev, u8 state) -{ - /* Power LED unconfigured */ - if (!dev->gpio.power_led) - return; - - /* ON Power LED */ - if (state) { - switch (dev->model) { - case TM6010_BOARD_HAUPPAUGE_900H: - case TM6010_BOARD_TERRATEC_CINERGY_HYBRID_XE: - case TM6010_BOARD_TWINHAN_TU501: - tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, - dev->gpio.power_led, 0x00); - break; - case TM6010_BOARD_BEHOLD_WANDER: - case TM6010_BOARD_BEHOLD_VOYAGER: - case TM6010_BOARD_BEHOLD_WANDER_LITE: - case TM6010_BOARD_BEHOLD_VOYAGER_LITE: - tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, - dev->gpio.power_led, 0x01); - break; - } - } - /* OFF Power LED */ - else { - switch (dev->model) { - case TM6010_BOARD_HAUPPAUGE_900H: - case TM6010_BOARD_TERRATEC_CINERGY_HYBRID_XE: - case TM6010_BOARD_TWINHAN_TU501: - tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, - dev->gpio.power_led, 0x01); - break; - case TM6010_BOARD_BEHOLD_WANDER: - case TM6010_BOARD_BEHOLD_VOYAGER: - case TM6010_BOARD_BEHOLD_WANDER_LITE: - case TM6010_BOARD_BEHOLD_VOYAGER_LITE: - tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, - dev->gpio.power_led, 0x00); - break; - } - } -} - -/* Tuner callback to provide the proper gpio changes needed for xc5000 */ -int tm6000_xc5000_callback(void *ptr, int component, int command, int arg) -{ - int rc = 0; - struct tm6000_core *dev = ptr; - - if (dev->tuner_type != TUNER_XC5000) - return 0; - - switch (command) { - case XC5000_TUNER_RESET: - tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, - dev->gpio.tuner_reset, 0x01); - msleep(15); - tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, - dev->gpio.tuner_reset, 0x00); - msleep(15); - tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, - dev->gpio.tuner_reset, 0x01); - break; - } - return rc; -} -EXPORT_SYMBOL_GPL(tm6000_xc5000_callback); - -/* Tuner callback to provide the proper gpio changes needed for xc2028 */ - -int tm6000_tuner_callback(void *ptr, int component, int command, int arg) -{ - int rc = 0; - struct tm6000_core *dev = ptr; - - if (dev->tuner_type != TUNER_XC2028) - return 0; - - switch (command) { - case XC2028_RESET_CLK: - tm6000_ir_wait(dev, 0); - - tm6000_set_reg(dev, REQ_04_EN_DISABLE_MCU_INT, - 0x02, arg); - msleep(10); - rc = tm6000_i2c_reset(dev, 10); - break; - case XC2028_TUNER_RESET: - /* Reset codes during load firmware */ - switch (arg) { - case 0: - /* newer tuner can faster reset */ - switch (dev->model) { - case TM5600_BOARD_10MOONS_UT821: - tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, - dev->gpio.tuner_reset, 0x01); - tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, - 0x300, 0x01); - msleep(10); - tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, - dev->gpio.tuner_reset, 0x00); - tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, - 0x300, 0x00); - msleep(10); - tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, - dev->gpio.tuner_reset, 0x01); - tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, - 0x300, 0x01); - break; - case TM6010_BOARD_HAUPPAUGE_900H: - case TM6010_BOARD_TERRATEC_CINERGY_HYBRID_XE: - case TM6010_BOARD_TWINHAN_TU501: - tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, - dev->gpio.tuner_reset, 0x01); - msleep(60); - tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, - dev->gpio.tuner_reset, 0x00); - msleep(75); - tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, - dev->gpio.tuner_reset, 0x01); - msleep(60); - break; - default: - tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, - dev->gpio.tuner_reset, 0x00); - msleep(130); - tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, - dev->gpio.tuner_reset, 0x01); - msleep(130); - break; - } - - tm6000_ir_wait(dev, 1); - break; - case 1: - tm6000_set_reg(dev, REQ_04_EN_DISABLE_MCU_INT, - 0x02, 0x01); - msleep(10); - break; - case 2: - rc = tm6000_i2c_reset(dev, 100); - break; - } - } - return rc; -} -EXPORT_SYMBOL_GPL(tm6000_tuner_callback); - -int tm6000_cards_setup(struct tm6000_core *dev) -{ - int i, rc; - - /* - * Board-specific initialization sequence. Handles all GPIO - * initialization sequences that are board-specific. - * Up to now, all found devices use GPIO1 and GPIO4 at the same way. - * Probably, they're all based on some reference device. Due to that, - * there's a common routine at the end to handle those GPIO's. Devices - * that use different pinups or init sequences can just return at - * the board-specific session. - */ - switch (dev->model) { - case TM6010_BOARD_HAUPPAUGE_900H: - case TM6010_BOARD_TERRATEC_CINERGY_HYBRID_XE: - case TM6010_BOARD_TWINHAN_TU501: - case TM6010_BOARD_GENERIC: - /* Turn xceive 3028 on */ - tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, dev->gpio.tuner_on, 0x01); - msleep(15); - /* Turn zarlink zl10353 on */ - tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, dev->gpio.demod_on, 0x00); - msleep(15); - /* Reset zarlink zl10353 */ - tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, dev->gpio.demod_reset, 0x00); - msleep(50); - tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, dev->gpio.demod_reset, 0x01); - msleep(15); - /* Turn zarlink zl10353 off */ - tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, dev->gpio.demod_on, 0x01); - msleep(15); - /* ir ? */ - tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, dev->gpio.ir, 0x01); - msleep(15); - /* Power led on (blue) */ - tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, dev->gpio.power_led, 0x00); - msleep(15); - /* DVB led off (orange) */ - tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, dev->gpio.dvb_led, 0x01); - msleep(15); - /* Turn zarlink zl10353 on */ - tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, dev->gpio.demod_on, 0x00); - msleep(15); - break; - case TM6010_BOARD_BEHOLD_WANDER: - case TM6010_BOARD_BEHOLD_WANDER_LITE: - /* Power led on (blue) */ - tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, dev->gpio.power_led, 0x01); - msleep(15); - /* Reset zarlink zl10353 */ - tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, dev->gpio.demod_reset, 0x00); - msleep(50); - tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, dev->gpio.demod_reset, 0x01); - msleep(15); - break; - case TM6010_BOARD_BEHOLD_VOYAGER: - case TM6010_BOARD_BEHOLD_VOYAGER_LITE: - /* Power led on (blue) */ - tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, dev->gpio.power_led, 0x01); - msleep(15); - break; - default: - break; - } - - /* - * Default initialization. Most of the devices seem to use GPIO1 - * and GPIO4.on the same way, so, this handles the common sequence - * used by most devices. - * If a device uses a different sequence or different GPIO pins for - * reset, just add the code at the board-specific part - */ - - if (dev->gpio.tuner_reset) { - for (i = 0; i < 2; i++) { - rc = tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, - dev->gpio.tuner_reset, 0x00); - if (rc < 0) { - printk(KERN_ERR "Error %i doing tuner reset\n", rc); - return rc; - } - - msleep(10); /* Just to be conservative */ - rc = tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, - dev->gpio.tuner_reset, 0x01); - if (rc < 0) { - printk(KERN_ERR "Error %i doing tuner reset\n", rc); - return rc; - } - } - } else { - printk(KERN_ERR "Tuner reset is not configured\n"); - return -1; - } - - msleep(50); - - return 0; -}; - -static void tm6000_config_tuner(struct tm6000_core *dev) -{ - struct tuner_setup tun_setup; - - /* Load tuner module */ - v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap, - "tuner", dev->tuner_addr, NULL); - - memset(&tun_setup, 0, sizeof(tun_setup)); - tun_setup.type = dev->tuner_type; - tun_setup.addr = dev->tuner_addr; - - tun_setup.mode_mask = 0; - if (dev->caps.has_tuner) - tun_setup.mode_mask |= (T_ANALOG_TV | T_RADIO); - - switch (dev->tuner_type) { - case TUNER_XC2028: - tun_setup.tuner_callback = tm6000_tuner_callback; - break; - case TUNER_XC5000: - tun_setup.tuner_callback = tm6000_xc5000_callback; - break; - } - - v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_type_addr, &tun_setup); - - switch (dev->tuner_type) { - case TUNER_XC2028: { - struct v4l2_priv_tun_config xc2028_cfg; - struct xc2028_ctrl ctl; - - memset(&xc2028_cfg, 0, sizeof(xc2028_cfg)); - memset(&ctl, 0, sizeof(ctl)); - - ctl.demod = XC3028_FE_ZARLINK456; - - xc2028_cfg.tuner = TUNER_XC2028; - xc2028_cfg.priv = &ctl; - - switch (dev->model) { - case TM6010_BOARD_HAUPPAUGE_900H: - case TM6010_BOARD_TERRATEC_CINERGY_HYBRID_XE: - case TM6010_BOARD_TWINHAN_TU501: - ctl.fname = "xc3028L-v36.fw"; - break; - default: - if (dev->dev_type == TM6010) - ctl.fname = "xc3028-v27.fw"; - else - ctl.fname = "xc3028-v24.fw"; - } - - printk(KERN_INFO "Setting firmware parameters for xc2028\n"); - v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_config, - &xc2028_cfg); - - } - break; - case TUNER_XC5000: - { - struct v4l2_priv_tun_config xc5000_cfg; - struct xc5000_config ctl = { - .i2c_address = dev->tuner_addr, - .if_khz = 4570, - .radio_input = XC5000_RADIO_FM1_MONO, - }; - - xc5000_cfg.tuner = TUNER_XC5000; - xc5000_cfg.priv = &ctl; - - v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_config, - &xc5000_cfg); - } - break; - default: - printk(KERN_INFO "Unknown tuner type. Tuner is not configured.\n"); - break; - } -} - -static int fill_board_specific_data(struct tm6000_core *dev) -{ - int rc; - - dev->dev_type = tm6000_boards[dev->model].type; - dev->tuner_type = tm6000_boards[dev->model].tuner_type; - dev->tuner_addr = tm6000_boards[dev->model].tuner_addr; - - dev->gpio = tm6000_boards[dev->model].gpio; - - dev->ir_codes = tm6000_boards[dev->model].ir_codes; - - dev->demod_addr = tm6000_boards[dev->model].demod_addr; - - dev->caps = tm6000_boards[dev->model].caps; - - dev->vinput[0] = tm6000_boards[dev->model].vinput[0]; - dev->vinput[1] = tm6000_boards[dev->model].vinput[1]; - dev->vinput[2] = tm6000_boards[dev->model].vinput[2]; - dev->rinput = tm6000_boards[dev->model].rinput; - - /* initialize hardware */ - rc = tm6000_init(dev); - if (rc < 0) - return rc; - - return v4l2_device_register(&dev->udev->dev, &dev->v4l2_dev); -} - - -static void use_alternative_detection_method(struct tm6000_core *dev) -{ - int i, model = -1; - - if (!dev->eedata_size) - return; - - for (i = 0; i < ARRAY_SIZE(tm6000_boards); i++) { - if (!tm6000_boards[i].eename_size) - continue; - if (dev->eedata_size < tm6000_boards[i].eename_pos + - tm6000_boards[i].eename_size) - continue; - - if (!memcmp(&dev->eedata[tm6000_boards[i].eename_pos], - tm6000_boards[i].eename, - tm6000_boards[i].eename_size)) { - model = i; - break; - } - } - if (model < 0) { - printk(KERN_INFO "Device has eeprom but is currently unknown\n"); - return; - } - - dev->model = model; - - printk(KERN_INFO "Device identified via eeprom as %s (type = %d)\n", - tm6000_boards[model].name, model); -} - -static int tm6000_init_dev(struct tm6000_core *dev) -{ - struct v4l2_frequency f; - int rc = 0; - - mutex_init(&dev->lock); - mutex_lock(&dev->lock); - - if (!is_generic(dev->model)) { - rc = fill_board_specific_data(dev); - if (rc < 0) - goto err; - - /* register i2c bus */ - rc = tm6000_i2c_register(dev); - if (rc < 0) - goto err; - } else { - /* register i2c bus */ - rc = tm6000_i2c_register(dev); - if (rc < 0) - goto err; - - use_alternative_detection_method(dev); - - rc = fill_board_specific_data(dev); - if (rc < 0) - goto err; - } - - /* Default values for STD and resolutions */ - dev->width = 720; - dev->height = 480; - dev->norm = V4L2_STD_PAL_M; - - /* Configure tuner */ - tm6000_config_tuner(dev); - - /* Set video standard */ - v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_std, dev->norm); - - /* Set tuner frequency - also loads firmware on xc2028/xc3028 */ - f.tuner = 0; - f.type = V4L2_TUNER_ANALOG_TV; - f.frequency = 3092; /* 193.25 MHz */ - dev->freq = f.frequency; - v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_frequency, &f); - - if (dev->caps.has_tda9874) - v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap, - "tvaudio", I2C_ADDR_TDA9874, NULL); - - /* register and initialize V4L2 */ - rc = tm6000_v4l2_register(dev); - if (rc < 0) - goto err; - - tm6000_add_into_devlist(dev); - tm6000_init_extension(dev); - - tm6000_ir_init(dev); - - mutex_unlock(&dev->lock); - return 0; - -err: - mutex_unlock(&dev->lock); - return rc; -} - -/* high bandwidth multiplier, as encoded in highspeed endpoint descriptors */ -#define hb_mult(wMaxPacketSize) (1 + (((wMaxPacketSize) >> 11) & 0x03)) - -static void get_max_endpoint(struct usb_device *udev, - struct usb_host_interface *alt, - char *msgtype, - struct usb_host_endpoint *curr_e, - struct tm6000_endpoint *tm_ep) -{ - u16 tmp = le16_to_cpu(curr_e->desc.wMaxPacketSize); - unsigned int size = tmp & 0x7ff; - - if (udev->speed == USB_SPEED_HIGH) - size = size * hb_mult(tmp); - - if (size > tm_ep->maxsize) { - tm_ep->endp = curr_e; - tm_ep->maxsize = size; - tm_ep->bInterfaceNumber = alt->desc.bInterfaceNumber; - tm_ep->bAlternateSetting = alt->desc.bAlternateSetting; - - printk(KERN_INFO "tm6000: %s endpoint: 0x%02x (max size=%u bytes)\n", - msgtype, curr_e->desc.bEndpointAddress, - size); - } -} - -/* - * tm6000_usb_probe() - * checks for supported devices - */ -static int tm6000_usb_probe(struct usb_interface *interface, - const struct usb_device_id *id) -{ - struct usb_device *usbdev; - struct tm6000_core *dev = NULL; - int i, rc = 0; - int nr = 0; - char *speed; - - usbdev = usb_get_dev(interface_to_usbdev(interface)); - - /* Selects the proper interface */ - rc = usb_set_interface(usbdev, 0, 1); - if (rc < 0) - goto err; - - /* Check to see next free device and mark as used */ - nr = find_first_zero_bit(&tm6000_devused, TM6000_MAXBOARDS); - if (nr >= TM6000_MAXBOARDS) { - printk(KERN_ERR "tm6000: Supports only %i tm60xx boards.\n", TM6000_MAXBOARDS); - usb_put_dev(usbdev); - return -ENOMEM; - } - - /* Create and initialize dev struct */ - dev = kzalloc(sizeof(*dev), GFP_KERNEL); - if (dev == NULL) { - printk(KERN_ERR "tm6000" ": out of memory!\n"); - usb_put_dev(usbdev); - return -ENOMEM; - } - spin_lock_init(&dev->slock); - - /* Increment usage count */ - tm6000_devused |= 1<<nr; - snprintf(dev->name, 29, "tm6000 #%d", nr); - - dev->model = id->driver_info; - if ((card[nr] >= 0) && (card[nr] < ARRAY_SIZE(tm6000_boards))) - dev->model = card[nr]; - - dev->udev = usbdev; - dev->devno = nr; - - switch (usbdev->speed) { - case USB_SPEED_LOW: - speed = "1.5"; - break; - case USB_SPEED_UNKNOWN: - case USB_SPEED_FULL: - speed = "12"; - break; - case USB_SPEED_HIGH: - speed = "480"; - break; - default: - speed = "unknown"; - } - - - - /* Get endpoints */ - for (i = 0; i < interface->num_altsetting; i++) { - int ep; - - for (ep = 0; ep < interface->altsetting[i].desc.bNumEndpoints; ep++) { - struct usb_host_endpoint *e; - int dir_out; - - e = &interface->altsetting[i].endpoint[ep]; - - dir_out = ((e->desc.bEndpointAddress & - USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT); - - printk(KERN_INFO "tm6000: alt %d, interface %i, class %i\n", - i, - interface->altsetting[i].desc.bInterfaceNumber, - interface->altsetting[i].desc.bInterfaceClass); - - switch (e->desc.bmAttributes) { - case USB_ENDPOINT_XFER_BULK: - if (!dir_out) { - get_max_endpoint(usbdev, - &interface->altsetting[i], - "Bulk IN", e, - &dev->bulk_in); - } else { - get_max_endpoint(usbdev, - &interface->altsetting[i], - "Bulk OUT", e, - &dev->bulk_out); - } - break; - case USB_ENDPOINT_XFER_ISOC: - if (!dir_out) { - get_max_endpoint(usbdev, - &interface->altsetting[i], - "ISOC IN", e, - &dev->isoc_in); - } else { - get_max_endpoint(usbdev, - &interface->altsetting[i], - "ISOC OUT", e, - &dev->isoc_out); - } - break; - case USB_ENDPOINT_XFER_INT: - if (!dir_out) { - get_max_endpoint(usbdev, - &interface->altsetting[i], - "INT IN", e, - &dev->int_in); - } else { - get_max_endpoint(usbdev, - &interface->altsetting[i], - "INT OUT", e, - &dev->int_out); - } - break; - } - } - } - - - printk(KERN_INFO "tm6000: New video device @ %s Mbps (%04x:%04x, ifnum %d)\n", - speed, - le16_to_cpu(dev->udev->descriptor.idVendor), - le16_to_cpu(dev->udev->descriptor.idProduct), - interface->altsetting->desc.bInterfaceNumber); - -/* check if the the device has the iso in endpoint at the correct place */ - if (!dev->isoc_in.endp) { - printk(KERN_ERR "tm6000: probing error: no IN ISOC endpoint!\n"); - rc = -ENODEV; - - goto err; - } - - /* save our data pointer in this interface device */ - usb_set_intfdata(interface, dev); - - printk(KERN_INFO "tm6000: Found %s\n", tm6000_boards[dev->model].name); - - rc = tm6000_init_dev(dev); - - if (rc < 0) - goto err; - - return 0; - -err: - printk(KERN_ERR "tm6000: Error %d while registering\n", rc); - - tm6000_devused &= ~(1<<nr); - usb_put_dev(usbdev); - - kfree(dev); - return rc; -} - -/* - * tm6000_usb_disconnect() - * called when the device gets diconencted - * video device will be unregistered on v4l2_close in case it is still open - */ -static void tm6000_usb_disconnect(struct usb_interface *interface) -{ - struct tm6000_core *dev = usb_get_intfdata(interface); - usb_set_intfdata(interface, NULL); - - if (!dev) - return; - - printk(KERN_INFO "tm6000: disconnecting %s\n", dev->name); - - tm6000_ir_fini(dev); - - if (dev->gpio.power_led) { - switch (dev->model) { - case TM6010_BOARD_HAUPPAUGE_900H: - case TM6010_BOARD_TERRATEC_CINERGY_HYBRID_XE: - case TM6010_BOARD_TWINHAN_TU501: - /* Power led off */ - tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, - dev->gpio.power_led, 0x01); - msleep(15); - break; - case TM6010_BOARD_BEHOLD_WANDER: - case TM6010_BOARD_BEHOLD_VOYAGER: - case TM6010_BOARD_BEHOLD_WANDER_LITE: - case TM6010_BOARD_BEHOLD_VOYAGER_LITE: - /* Power led off */ - tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, - dev->gpio.power_led, 0x00); - msleep(15); - break; - } - } - tm6000_v4l2_unregister(dev); - - tm6000_i2c_unregister(dev); - - v4l2_device_unregister(&dev->v4l2_dev); - - dev->state |= DEV_DISCONNECTED; - - usb_put_dev(dev->udev); - - tm6000_close_extension(dev); - tm6000_remove_from_devlist(dev); - - kfree(dev); -} - -static struct usb_driver tm6000_usb_driver = { - .name = "tm6000", - .probe = tm6000_usb_probe, - .disconnect = tm6000_usb_disconnect, - .id_table = tm6000_id_table, -}; - -static int __init tm6000_module_init(void) -{ - int result; - - printk(KERN_INFO "tm6000" " v4l2 driver version %d.%d.%d loaded\n", - (TM6000_VERSION >> 16) & 0xff, - (TM6000_VERSION >> 8) & 0xff, TM6000_VERSION & 0xff); - - /* register this driver with the USB subsystem */ - result = usb_register(&tm6000_usb_driver); - if (result) - printk(KERN_ERR "tm6000" - " usb_register failed. Error number %d.\n", result); - - return result; -} - -static void __exit tm6000_module_exit(void) -{ - /* deregister at USB subsystem */ - usb_deregister(&tm6000_usb_driver); -} - -module_init(tm6000_module_init); -module_exit(tm6000_module_exit); - -MODULE_DESCRIPTION("Trident TVMaster TM5600/TM6000/TM6010 USB2 adapter"); -MODULE_AUTHOR("Mauro Carvalho Chehab"); -MODULE_LICENSE("GPL"); diff --git a/drivers/staging/tm6000/tm6000-core.c b/drivers/staging/tm6000/tm6000-core.c deleted file mode 100644 index d7eb2e23cdbd..000000000000 --- a/drivers/staging/tm6000/tm6000-core.c +++ /dev/null @@ -1,909 +0,0 @@ -/* - * tm6000-core.c - driver for TM5600/TM6000/TM6010 USB video capture devices - * - * Copyright (C) 2006-2007 Mauro Carvalho Chehab <mchehab@infradead.org> - * - * Copyright (C) 2007 Michel Ludwig <michel.ludwig@gmail.com> - * - DVB-T support - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation version 2 - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include <linux/module.h> -#include <linux/kernel.h> -#include <linux/slab.h> -#include <linux/usb.h> -#include <linux/i2c.h> -#include "tm6000.h" -#include "tm6000-regs.h" -#include <media/v4l2-common.h> -#include <media/tuner.h> - -#define USB_TIMEOUT (5 * HZ) /* ms */ - -int tm6000_read_write_usb(struct tm6000_core *dev, u8 req_type, u8 req, - u16 value, u16 index, u8 *buf, u16 len) -{ - int ret, i; - unsigned int pipe; - u8 *data = NULL; - - if (len) - data = kzalloc(len, GFP_KERNEL); - - - if (req_type & USB_DIR_IN) - pipe = usb_rcvctrlpipe(dev->udev, 0); - else { - pipe = usb_sndctrlpipe(dev->udev, 0); - memcpy(data, buf, len); - } - - if (tm6000_debug & V4L2_DEBUG_I2C) { - printk("(dev %p, pipe %08x): ", dev->udev, pipe); - - printk("%s: %02x %02x %02x %02x %02x %02x %02x %02x ", - (req_type & USB_DIR_IN) ? " IN" : "OUT", - req_type, req, value&0xff, value>>8, index&0xff, - index>>8, len&0xff, len>>8); - - if (!(req_type & USB_DIR_IN)) { - printk(">>> "); - for (i = 0; i < len; i++) - printk(" %02x", buf[i]); - printk("\n"); - } - } - - ret = usb_control_msg(dev->udev, pipe, req, req_type, value, index, - data, len, USB_TIMEOUT); - - if (req_type & USB_DIR_IN) - memcpy(buf, data, len); - - if (tm6000_debug & V4L2_DEBUG_I2C) { - if (ret < 0) { - if (req_type & USB_DIR_IN) - printk("<<< (len=%d)\n", len); - - printk("%s: Error #%d\n", __FUNCTION__, ret); - } else if (req_type & USB_DIR_IN) { - printk("<<< "); - for (i = 0; i < len; i++) - printk(" %02x", buf[i]); - printk("\n"); - } - } - - kfree(data); - - msleep(5); - - return ret; -} - -int tm6000_set_reg(struct tm6000_core *dev, u8 req, u16 value, u16 index) -{ - return - tm6000_read_write_usb(dev, USB_DIR_OUT | USB_TYPE_VENDOR, - req, value, index, NULL, 0); -} -EXPORT_SYMBOL_GPL(tm6000_set_reg); - -int tm6000_get_reg(struct tm6000_core *dev, u8 req, u16 value, u16 index) -{ - int rc; - u8 buf[1]; - - rc = tm6000_read_write_usb(dev, USB_DIR_IN | USB_TYPE_VENDOR, req, - value, index, buf, 1); - - if (rc < 0) - return rc; - - return *buf; -} -EXPORT_SYMBOL_GPL(tm6000_get_reg); - -int tm6000_set_reg_mask(struct tm6000_core *dev, u8 req, u16 value, - u16 index, u16 mask) -{ - int rc; - u8 buf[1]; - u8 new_index; - - rc = tm6000_read_write_usb(dev, USB_DIR_IN | USB_TYPE_VENDOR, req, - value, index, buf, 1); - - if (rc < 0) - return rc; - - new_index = (buf[0] & ~mask) | (index & mask); - - if (new_index == index) - return 0; - - return tm6000_read_write_usb(dev, USB_DIR_OUT | USB_TYPE_VENDOR, - req, value, new_index, NULL, 0); -} -EXPORT_SYMBOL_GPL(tm6000_set_reg_mask); - -int tm6000_get_reg16(struct tm6000_core *dev, u8 req, u16 value, u16 index) -{ - int rc; - u8 buf[2]; - - rc = tm6000_read_write_usb(dev, USB_DIR_IN | USB_TYPE_VENDOR, req, - value, index, buf, 2); - - if (rc < 0) - return rc; - - return buf[1]|buf[0]<<8; -} - -int tm6000_get_reg32(struct tm6000_core *dev, u8 req, u16 value, u16 index) -{ - int rc; - u8 buf[4]; - - rc = tm6000_read_write_usb(dev, USB_DIR_IN | USB_TYPE_VENDOR, req, - value, index, buf, 4); - - if (rc < 0) - return rc; - - return buf[3] | buf[2] << 8 | buf[1] << 16 | buf[0] << 24; -} - -int tm6000_i2c_reset(struct tm6000_core *dev, u16 tsleep) -{ - int rc; - - rc = tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, TM6000_GPIO_CLK, 0); - if (rc < 0) - return rc; - - msleep(tsleep); - - rc = tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, TM6000_GPIO_CLK, 1); - msleep(tsleep); - - return rc; -} - -void tm6000_set_fourcc_format(struct tm6000_core *dev) -{ - if (dev->dev_type == TM6010) { - int val; - - val = tm6000_get_reg(dev, TM6010_REQ07_RCC_ACTIVE_VIDEO_IF, 0) & 0xfc; - if (dev->fourcc == V4L2_PIX_FMT_UYVY) - tm6000_set_reg(dev, TM6010_REQ07_RCC_ACTIVE_VIDEO_IF, val); - else - tm6000_set_reg(dev, TM6010_REQ07_RCC_ACTIVE_VIDEO_IF, val | 1); - } else { - if (dev->fourcc == V4L2_PIX_FMT_UYVY) - tm6000_set_reg(dev, TM6010_REQ07_RC1_TRESHOLD, 0xd0); - else - tm6000_set_reg(dev, TM6010_REQ07_RC1_TRESHOLD, 0x90); - } -} - -static void tm6000_set_vbi(struct tm6000_core *dev) -{ - /* - * FIXME: - * VBI lines and start/end are different between 60Hz and 50Hz - * So, it is very likely that we need to change the config to - * something that takes it into account, doing something different - * if (dev->norm & V4L2_STD_525_60) - */ - - if (dev->dev_type == TM6010) { - tm6000_set_reg(dev, TM6010_REQ07_R3F_RESET, 0x01); - tm6000_set_reg(dev, TM6010_REQ07_R41_TELETEXT_VBI_CODE1, 0x27); - tm6000_set_reg(dev, TM6010_REQ07_R42_VBI_DATA_HIGH_LEVEL, 0x55); - tm6000_set_reg(dev, TM6010_REQ07_R43_VBI_DATA_TYPE_LINE7, 0x66); - tm6000_set_reg(dev, TM6010_REQ07_R44_VBI_DATA_TYPE_LINE8, 0x66); - tm6000_set_reg(dev, TM6010_REQ07_R45_VBI_DATA_TYPE_LINE9, 0x66); - tm6000_set_reg(dev, - TM6010_REQ07_R46_VBI_DATA_TYPE_LINE10, 0x66); - tm6000_set_reg(dev, - TM6010_REQ07_R47_VBI_DATA_TYPE_LINE11, 0x66); - tm6000_set_reg(dev, - TM6010_REQ07_R48_VBI_DATA_TYPE_LINE12, 0x66); - tm6000_set_reg(dev, - TM6010_REQ07_R49_VBI_DATA_TYPE_LINE13, 0x66); - tm6000_set_reg(dev, - TM6010_REQ07_R4A_VBI_DATA_TYPE_LINE14, 0x66); - tm6000_set_reg(dev, - TM6010_REQ07_R4B_VBI_DATA_TYPE_LINE15, 0x66); - tm6000_set_reg(dev, - TM6010_REQ07_R4C_VBI_DATA_TYPE_LINE16, 0x66); - tm6000_set_reg(dev, - TM6010_REQ07_R4D_VBI_DATA_TYPE_LINE17, 0x66); - tm6000_set_reg(dev, - TM6010_REQ07_R4E_VBI_DATA_TYPE_LINE18, 0x66); - tm6000_set_reg(dev, - TM6010_REQ07_R4F_VBI_DATA_TYPE_LINE19, 0x66); - tm6000_set_reg(dev, - TM6010_REQ07_R50_VBI_DATA_TYPE_LINE20, 0x66); - tm6000_set_reg(dev, - TM6010_REQ07_R51_VBI_DATA_TYPE_LINE21, 0x66); - tm6000_set_reg(dev, - TM6010_REQ07_R52_VBI_DATA_TYPE_LINE22, 0x66); - tm6000_set_reg(dev, - TM6010_REQ07_R53_VBI_DATA_TYPE_LINE23, 0x00); - tm6000_set_reg(dev, - TM6010_REQ07_R54_VBI_DATA_TYPE_RLINES, 0x00); - tm6000_set_reg(dev, - TM6010_REQ07_R55_VBI_LOOP_FILTER_GAIN, 0x01); - tm6000_set_reg(dev, - TM6010_REQ07_R56_VBI_LOOP_FILTER_I_GAIN, 0x00); - tm6000_set_reg(dev, - TM6010_REQ07_R57_VBI_LOOP_FILTER_P_GAIN, 0x02); - tm6000_set_reg(dev, TM6010_REQ07_R58_VBI_CAPTION_DTO1, 0x35); - tm6000_set_reg(dev, TM6010_REQ07_R59_VBI_CAPTION_DTO0, 0xa0); - tm6000_set_reg(dev, TM6010_REQ07_R5A_VBI_TELETEXT_DTO1, 0x11); - tm6000_set_reg(dev, TM6010_REQ07_R5B_VBI_TELETEXT_DTO0, 0x4c); - tm6000_set_reg(dev, TM6010_REQ07_R40_TELETEXT_VBI_CODE0, 0x01); - tm6000_set_reg(dev, TM6010_REQ07_R3F_RESET, 0x00); - } -} - -int tm6000_init_analog_mode(struct tm6000_core *dev) -{ - struct v4l2_frequency f; - - if (dev->dev_type == TM6010) { - /* Enable video and audio */ - tm6000_set_reg_mask(dev, TM6010_REQ07_RCC_ACTIVE_VIDEO_IF, - 0x60, 0x60); - /* Disable TS input */ - tm6000_set_reg_mask(dev, TM6010_REQ07_RC0_ACTIVE_VIDEO_SOURCE, - 0x00, 0x40); - } else { - /* Enables soft reset */ - tm6000_set_reg(dev, TM6010_REQ07_R3F_RESET, 0x01); - - if (dev->scaler) - /* Disable Hfilter and Enable TS Drop err */ - tm6000_set_reg(dev, TM6010_REQ07_RC0_ACTIVE_VIDEO_SOURCE, 0x20); - else /* Enable Hfilter and disable TS Drop err */ - tm6000_set_reg(dev, TM6010_REQ07_RC0_ACTIVE_VIDEO_SOURCE, 0x80); - - tm6000_set_reg(dev, TM6010_REQ07_RC3_HSTART1, 0x88); - tm6000_set_reg(dev, TM6000_REQ07_RDA_CLK_SEL, 0x23); - tm6000_set_reg(dev, TM6010_REQ07_RD1_ADDR_FOR_REQ1, 0xc0); - tm6000_set_reg(dev, TM6010_REQ07_RD2_ADDR_FOR_REQ2, 0xd8); - tm6000_set_reg(dev, TM6010_REQ07_RD6_ENDP_REQ1_REQ2, 0x06); - tm6000_set_reg(dev, TM6000_REQ07_RDF_PWDOWN_ACLK, 0x1f); - - /* AP Software reset */ - tm6000_set_reg(dev, TM6010_REQ07_RFF_SOFT_RESET, 0x08); - tm6000_set_reg(dev, TM6010_REQ07_RFF_SOFT_RESET, 0x00); - - tm6000_set_fourcc_format(dev); - - /* Disables soft reset */ - tm6000_set_reg(dev, TM6010_REQ07_R3F_RESET, 0x00); - } - msleep(20); - - /* Tuner firmware can now be loaded */ - - /* - * FIXME: This is a hack! xc3028 "sleeps" when no channel is detected - * for more than a few seconds. Not sure why, as this behavior does - * not happen on other devices with xc3028. So, I suspect that it - * is yet another bug at tm6000. After start sleeping, decoding - * doesn't start automatically. Instead, it requires some - * I2C commands to wake it up. As we want to have image at the - * beginning, we needed to add this hack. The better would be to - * discover some way to make tm6000 to wake up without this hack. - */ - f.frequency = dev->freq; - v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_frequency, &f); - - msleep(100); - tm6000_set_standard(dev); - tm6000_set_vbi(dev); - tm6000_set_audio_bitrate(dev, 48000); - - /* switch dvb led off */ - if (dev->gpio.dvb_led) { - tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, - dev->gpio.dvb_led, 0x01); - } - - return 0; -} - -int tm6000_init_digital_mode(struct tm6000_core *dev) -{ - if (dev->dev_type == TM6010) { - /* Disable video and audio */ - tm6000_set_reg_mask(dev, TM6010_REQ07_RCC_ACTIVE_VIDEO_IF, - 0x00, 0x60); - /* Enable TS input */ - tm6000_set_reg_mask(dev, TM6010_REQ07_RC0_ACTIVE_VIDEO_SOURCE, - 0x40, 0x40); - /* all power down, but not the digital data port */ - tm6000_set_reg(dev, TM6010_REQ07_RFE_POWER_DOWN, 0x28); - tm6000_set_reg(dev, TM6010_REQ08_RE2_POWER_DOWN_CTRL1, 0xfc); - tm6000_set_reg(dev, TM6010_REQ08_RE6_POWER_DOWN_CTRL2, 0xff); - } else { - tm6000_set_reg(dev, TM6010_REQ07_RFF_SOFT_RESET, 0x08); - tm6000_set_reg(dev, TM6010_REQ07_RFF_SOFT_RESET, 0x00); - tm6000_set_reg(dev, TM6010_REQ07_R3F_RESET, 0x01); - tm6000_set_reg(dev, TM6000_REQ07_RDF_PWDOWN_ACLK, 0x08); - tm6000_set_reg(dev, TM6000_REQ07_RE2_VADC_STATUS_CTL, 0x0c); - tm6000_set_reg(dev, TM6000_REQ07_RE8_VADC_PWDOWN_CTL, 0xff); - tm6000_set_reg(dev, TM6000_REQ07_REB_VADC_AADC_MODE, 0xd8); - tm6000_set_reg(dev, TM6010_REQ07_RC0_ACTIVE_VIDEO_SOURCE, 0x40); - tm6000_set_reg(dev, TM6010_REQ07_RC1_TRESHOLD, 0xd0); - tm6000_set_reg(dev, TM6010_REQ07_RC3_HSTART1, 0x09); - tm6000_set_reg(dev, TM6000_REQ07_RDA_CLK_SEL, 0x37); - tm6000_set_reg(dev, TM6010_REQ07_RD1_ADDR_FOR_REQ1, 0xd8); - tm6000_set_reg(dev, TM6010_REQ07_RD2_ADDR_FOR_REQ2, 0xc0); - tm6000_set_reg(dev, TM6010_REQ07_RD6_ENDP_REQ1_REQ2, 0x60); - - tm6000_set_reg(dev, TM6000_REQ07_RE2_VADC_STATUS_CTL, 0x0c); - tm6000_set_reg(dev, TM6000_REQ07_RE8_VADC_PWDOWN_CTL, 0xff); - tm6000_set_reg(dev, TM6000_REQ07_REB_VADC_AADC_MODE, 0x08); - msleep(50); - - tm6000_set_reg(dev, REQ_04_EN_DISABLE_MCU_INT, 0x0020, 0x00); - msleep(50); - tm6000_set_reg(dev, REQ_04_EN_DISABLE_MCU_INT, 0x0020, 0x01); - msleep(50); - tm6000_set_reg(dev, REQ_04_EN_DISABLE_MCU_INT, 0x0020, 0x00); - msleep(100); - } - - /* switch dvb led on */ - if (dev->gpio.dvb_led) { - tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, - dev->gpio.dvb_led, 0x00); - } - - return 0; -} -EXPORT_SYMBOL(tm6000_init_digital_mode); - -struct reg_init { - u8 req; - u8 reg; - u8 val; -}; - -/* The meaning of those initializations are unknown */ -struct reg_init tm6000_init_tab[] = { - /* REG VALUE */ - { TM6000_REQ07_RDF_PWDOWN_ACLK, 0x1f }, - { TM6010_REQ07_RFF_SOFT_RESET, 0x08 }, - { TM6010_REQ07_RFF_SOFT_RESET, 0x00 }, - { TM6010_REQ07_RD5_POWERSAVE, 0x4f }, - { TM6000_REQ07_RDA_CLK_SEL, 0x23 }, - { TM6000_REQ07_RDB_OUT_SEL, 0x08 }, - { TM6000_REQ07_RE2_VADC_STATUS_CTL, 0x00 }, - { TM6000_REQ07_RE3_VADC_INP_LPF_SEL1, 0x10 }, - { TM6000_REQ07_RE5_VADC_INP_LPF_SEL2, 0x00 }, - { TM6000_REQ07_RE8_VADC_PWDOWN_CTL, 0x00 }, - { TM6000_REQ07_REB_VADC_AADC_MODE, 0x64 }, /* 48000 bits/sample, external input */ - { TM6000_REQ07_REE_VADC_CTRL_SEL_CONTROL, 0xc2 }, - - { TM6010_REQ07_R3F_RESET, 0x01 }, /* Start of soft reset */ - { TM6010_REQ07_R00_VIDEO_CONTROL0, 0x00 }, - { TM6010_REQ07_R01_VIDEO_CONTROL1, 0x07 }, - { TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f }, - { TM6010_REQ07_R03_YC_SEP_CONTROL, 0x00 }, - { TM6010_REQ07_R05_NOISE_THRESHOLD, 0x64 }, - { TM6010_REQ07_R07_OUTPUT_CONTROL, 0x01 }, - { TM6010_REQ07_R08_LUMA_CONTRAST_ADJ, 0x82 }, - { TM6010_REQ07_R09_LUMA_BRIGHTNESS_ADJ, 0x36 }, - { TM6010_REQ07_R0A_CHROMA_SATURATION_ADJ, 0x50 }, - { TM6010_REQ07_R0C_CHROMA_AGC_CONTROL, 0x6a }, - { TM6010_REQ07_R11_AGC_PEAK_CONTROL, 0xc9 }, - { TM6010_REQ07_R12_AGC_GATE_STARTH, 0x07 }, - { TM6010_REQ07_R13_AGC_GATE_STARTL, 0x3b }, - { TM6010_REQ07_R14_AGC_GATE_WIDTH, 0x47 }, - { TM6010_REQ07_R15_AGC_BP_DELAY, 0x6f }, - { TM6010_REQ07_R17_HLOOP_MAXSTATE, 0xcd }, - { TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x1e }, - { TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0x8b }, - { TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0xa2 }, - { TM6010_REQ07_R1B_CHROMA_DTO_INCREMENT0, 0xe9 }, - { TM6010_REQ07_R1C_HSYNC_DTO_INCREMENT3, 0x1c }, - { TM6010_REQ07_R1D_HSYNC_DTO_INCREMENT2, 0xcc }, - { TM6010_REQ07_R1E_HSYNC_DTO_INCREMENT1, 0xcc }, - { TM6010_REQ07_R1F_HSYNC_DTO_INCREMENT0, 0xcd }, - { TM6010_REQ07_R20_HSYNC_RISING_EDGE_TIME, 0x3c }, - { TM6010_REQ07_R21_HSYNC_PHASE_OFFSET, 0x3c }, - { TM6010_REQ07_R2D_CHROMA_BURST_END, 0x48 }, - { TM6010_REQ07_R2E_ACTIVE_VIDEO_HSTART, 0x88 }, - { TM6010_REQ07_R30_ACTIVE_VIDEO_VSTART, 0x22 }, - { TM6010_REQ07_R31_ACTIVE_VIDEO_VHIGHT, 0x61 }, - { TM6010_REQ07_R32_VSYNC_HLOCK_MIN, 0x74 }, - { TM6010_REQ07_R33_VSYNC_HLOCK_MAX, 0x1c }, - { TM6010_REQ07_R34_VSYNC_AGC_MIN, 0x74 }, - { TM6010_REQ07_R35_VSYNC_AGC_MAX, 0x1c }, - { TM6010_REQ07_R36_VSYNC_VBI_MIN, 0x7a }, - { TM6010_REQ07_R37_VSYNC_VBI_MAX, 0x26 }, - { TM6010_REQ07_R38_VSYNC_THRESHOLD, 0x40 }, - { TM6010_REQ07_R39_VSYNC_TIME_CONSTANT, 0x0a }, - { TM6010_REQ07_R42_VBI_DATA_HIGH_LEVEL, 0x55 }, - { TM6010_REQ07_R51_VBI_DATA_TYPE_LINE21, 0x11 }, - { TM6010_REQ07_R55_VBI_LOOP_FILTER_GAIN, 0x01 }, - { TM6010_REQ07_R57_VBI_LOOP_FILTER_P_GAIN, 0x02 }, - { TM6010_REQ07_R58_VBI_CAPTION_DTO1, 0x35 }, - { TM6010_REQ07_R59_VBI_CAPTION_DTO0, 0xa0 }, - { TM6010_REQ07_R80_COMB_FILTER_TRESHOLD, 0x15 }, - { TM6010_REQ07_R82_COMB_FILTER_CONFIG, 0x42 }, - { TM6010_REQ07_RC1_TRESHOLD, 0xd0 }, - { TM6010_REQ07_RC3_HSTART1, 0x88 }, - { TM6010_REQ07_R3F_RESET, 0x00 }, /* End of the soft reset */ - { TM6010_REQ05_R18_IMASK7, 0x00 }, -}; - -struct reg_init tm6010_init_tab[] = { - { TM6010_REQ07_RC0_ACTIVE_VIDEO_SOURCE, 0x00 }, - { TM6010_REQ07_RC4_HSTART0, 0xa0 }, - { TM6010_REQ07_RC6_HEND0, 0x40 }, - { TM6010_REQ07_RCA_VEND0, 0x31 }, - { TM6010_REQ07_RCC_ACTIVE_VIDEO_IF, 0xe1 }, - { TM6010_REQ07_RE0_DVIDEO_SOURCE, 0x03 }, - { TM6010_REQ07_RFE_POWER_DOWN, 0x7f }, - - { TM6010_REQ08_RE2_POWER_DOWN_CTRL1, 0xf0 }, - { TM6010_REQ08_RE3_ADC_IN1_SEL, 0xf4 }, - { TM6010_REQ08_RE4_ADC_IN2_SEL, 0xf8 }, - { TM6010_REQ08_RE6_POWER_DOWN_CTRL2, 0x00 }, - { TM6010_REQ08_REA_BUFF_DRV_CTRL, 0xf2 }, - { TM6010_REQ08_REB_SIF_GAIN_CTRL, 0xf0 }, - { TM6010_REQ08_REC_REVERSE_YC_CTRL, 0xc2 }, - { TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG, 0x60 }, - { TM6010_REQ08_RF1_AADC_POWER_DOWN, 0xfc }, - - { TM6010_REQ07_R3F_RESET, 0x01 }, - { TM6010_REQ07_R00_VIDEO_CONTROL0, 0x00 }, - { TM6010_REQ07_R01_VIDEO_CONTROL1, 0x07 }, - { TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f }, - { TM6010_REQ07_R03_YC_SEP_CONTROL, 0x00 }, - { TM6010_REQ07_R05_NOISE_THRESHOLD, 0x64 }, - { TM6010_REQ07_R07_OUTPUT_CONTROL, 0x01 }, - { TM6010_REQ07_R08_LUMA_CONTRAST_ADJ, 0x82 }, - { TM6010_REQ07_R09_LUMA_BRIGHTNESS_ADJ, 0x36 }, - { TM6010_REQ07_R0A_CHROMA_SATURATION_ADJ, 0x50 }, - { TM6010_REQ07_R0C_CHROMA_AGC_CONTROL, 0x6a }, - { TM6010_REQ07_R11_AGC_PEAK_CONTROL, 0xc9 }, - { TM6010_REQ07_R12_AGC_GATE_STARTH, 0x07 }, - { TM6010_REQ07_R13_AGC_GATE_STARTL, 0x3b }, - { TM6010_REQ07_R14_AGC_GATE_WIDTH, 0x47 }, - { TM6010_REQ07_R15_AGC_BP_DELAY, 0x6f }, - { TM6010_REQ07_R17_HLOOP_MAXSTATE, 0xcd }, - { TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x1e }, - { TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0x8b }, - { TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0xa2 }, - { TM6010_REQ07_R1B_CHROMA_DTO_INCREMENT0, 0xe9 }, - { TM6010_REQ07_R1C_HSYNC_DTO_INCREMENT3, 0x1c }, - { TM6010_REQ07_R1D_HSYNC_DTO_INCREMENT2, 0xcc }, - { TM6010_REQ07_R1E_HSYNC_DTO_INCREMENT1, 0xcc }, - { TM6010_REQ07_R1F_HSYNC_DTO_INCREMENT0, 0xcd }, - { TM6010_REQ07_R20_HSYNC_RISING_EDGE_TIME, 0x3c }, - { TM6010_REQ07_R21_HSYNC_PHASE_OFFSET, 0x3c }, - { TM6010_REQ07_R2D_CHROMA_BURST_END, 0x48 }, - { TM6010_REQ07_R2E_ACTIVE_VIDEO_HSTART, 0x88 }, - { TM6010_REQ07_R30_ACTIVE_VIDEO_VSTART, 0x22 }, - { TM6010_REQ07_R31_ACTIVE_VIDEO_VHIGHT, 0x61 }, - { TM6010_REQ07_R32_VSYNC_HLOCK_MIN, 0x74 }, - { TM6010_REQ07_R33_VSYNC_HLOCK_MAX, 0x1c }, - { TM6010_REQ07_R34_VSYNC_AGC_MIN, 0x74 }, - { TM6010_REQ07_R35_VSYNC_AGC_MAX, 0x1c }, - { TM6010_REQ07_R36_VSYNC_VBI_MIN, 0x7a }, - { TM6010_REQ07_R37_VSYNC_VBI_MAX, 0x26 }, - { TM6010_REQ07_R38_VSYNC_THRESHOLD, 0x40 }, - { TM6010_REQ07_R39_VSYNC_TIME_CONSTANT, 0x0a }, - { TM6010_REQ07_R42_VBI_DATA_HIGH_LEVEL, 0x55 }, - { TM6010_REQ07_R51_VBI_DATA_TYPE_LINE21, 0x11 }, - { TM6010_REQ07_R55_VBI_LOOP_FILTER_GAIN, 0x01 }, - { TM6010_REQ07_R57_VBI_LOOP_FILTER_P_GAIN, 0x02 }, - { TM6010_REQ07_R58_VBI_CAPTION_DTO1, 0x35 }, - { TM6010_REQ07_R59_VBI_CAPTION_DTO0, 0xa0 }, - { TM6010_REQ07_R80_COMB_FILTER_TRESHOLD, 0x15 }, - { TM6010_REQ07_R82_COMB_FILTER_CONFIG, 0x42 }, - { TM6010_REQ07_RC1_TRESHOLD, 0xd0 }, - { TM6010_REQ07_RC3_HSTART1, 0x88 }, - { TM6010_REQ07_R3F_RESET, 0x00 }, - - { TM6010_REQ05_R18_IMASK7, 0x00 }, - - { TM6010_REQ07_RD8_IR_LEADER1, 0xaa }, - { TM6010_REQ07_RD8_IR_LEADER0, 0x30 }, - { TM6010_REQ07_RD8_IR_PULSE_CNT1, 0x20 }, - { TM6010_REQ07_RD8_IR_PULSE_CNT0, 0xd0 }, - { REQ_04_EN_DISABLE_MCU_INT, 0x02, 0x00 }, - { TM6010_REQ07_RD8_IR, 0x2f }, - - /* set remote wakeup key:any key wakeup */ - { TM6010_REQ07_RE5_REMOTE_WAKEUP, 0xfe }, - { TM6010_REQ07_RD8_IR_WAKEUP_SEL, 0xff }, -}; - -int tm6000_init(struct tm6000_core *dev) -{ - int board, rc = 0, i, size; - struct reg_init *tab; - - /* Check board revision */ - board = tm6000_get_reg32(dev, REQ_40_GET_VERSION, 0, 0); - if (board >= 0) { - switch (board & 0xff) { - case 0xf3: - printk(KERN_INFO "Found tm6000\n"); - if (dev->dev_type != TM6000) - dev->dev_type = TM6000; - break; - case 0xf4: - printk(KERN_INFO "Found tm6010\n"); - if (dev->dev_type != TM6010) - dev->dev_type = TM6010; - break; - default: - printk(KERN_INFO "Unknown board version = 0x%08x\n", board); - } - } else - printk(KERN_ERR "Error %i while retrieving board version\n", board); - - if (dev->dev_type == TM6010) { - tab = tm6010_init_tab; - size = ARRAY_SIZE(tm6010_init_tab); - } else { - tab = tm6000_init_tab; - size = ARRAY_SIZE(tm6000_init_tab); - } - - /* Load board's initialization table */ - for (i = 0; i < size; i++) { - rc = tm6000_set_reg(dev, tab[i].req, tab[i].reg, tab[i].val); - if (rc < 0) { - printk(KERN_ERR "Error %i while setting req %d, " - "reg %d to value %d\n", rc, - tab[i].req, tab[i].reg, tab[i].val); - return rc; - } - } - - msleep(5); /* Just to be conservative */ - - rc = tm6000_cards_setup(dev); - - return rc; -} - -int tm6000_set_audio_bitrate(struct tm6000_core *dev, int bitrate) -{ - int val = 0; - u8 areg_f0 = 0x60; /* ADC MCLK = 250 Fs */ - u8 areg_0a = 0x91; /* SIF 48KHz */ - - switch (bitrate) { - case 48000: - areg_f0 = 0x60; /* ADC MCLK = 250 Fs */ - areg_0a = 0x91; /* SIF 48KHz */ - dev->audio_bitrate = bitrate; - break; - case 32000: - areg_f0 = 0x00; /* ADC MCLK = 375 Fs */ - areg_0a = 0x90; /* SIF 32KHz */ - dev->audio_bitrate = bitrate; - break; - default: - return -EINVAL; - } - - - /* enable I2S, if we use sif or external I2S device */ - if (dev->dev_type == TM6010) { - val = tm6000_set_reg(dev, TM6010_REQ08_R0A_A_I2S_MOD, areg_0a); - if (val < 0) - return val; - - val = tm6000_set_reg_mask(dev, TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG, - areg_f0, 0xf0); - if (val < 0) - return val; - } else { - val = tm6000_set_reg_mask(dev, TM6000_REQ07_REB_VADC_AADC_MODE, - areg_f0, 0xf0); - if (val < 0) - return val; - } - return 0; -} -EXPORT_SYMBOL_GPL(tm6000_set_audio_bitrate); - -int tm6000_set_audio_rinput(struct tm6000_core *dev) -{ - if (dev->dev_type == TM6010) { - /* Audio crossbar setting, default SIF1 */ - u8 areg_f0; - - switch (dev->rinput.amux) { - case TM6000_AMUX_SIF1: - case TM6000_AMUX_SIF2: - areg_f0 = 0x03; - break; - case TM6000_AMUX_ADC1: - areg_f0 = 0x00; - break; - case TM6000_AMUX_ADC2: - areg_f0 = 0x08; - break; - case TM6000_AMUX_I2S: - areg_f0 = 0x04; - break; - default: - printk(KERN_INFO "%s: audio input dosn't support\n", - dev->name); - return 0; - break; - } - /* Set audio input crossbar */ - tm6000_set_reg_mask(dev, TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG, - areg_f0, 0x0f); - } else { - u8 areg_eb; - /* Audio setting, default LINE1 */ - switch (dev->rinput.amux) { - case TM6000_AMUX_ADC1: - areg_eb = 0x00; - break; - case TM6000_AMUX_ADC2: - areg_eb = 0x04; - break; - default: - printk(KERN_INFO "%s: audio input dosn't support\n", - dev->name); - return 0; - break; - } - /* Set audio input */ - tm6000_set_reg_mask(dev, TM6000_REQ07_REB_VADC_AADC_MODE, - areg_eb, 0x0f); - } - return 0; -} - -void tm6010_set_mute_sif(struct tm6000_core *dev, u8 mute) -{ - u8 mute_reg = 0; - - if (mute) - mute_reg = 0x08; - - tm6000_set_reg_mask(dev, TM6010_REQ08_R0A_A_I2S_MOD, mute_reg, 0x08); -} - -void tm6010_set_mute_adc(struct tm6000_core *dev, u8 mute) -{ - u8 mute_reg = 0; - - if (mute) - mute_reg = 0x20; - - if (dev->dev_type == TM6010) { - tm6000_set_reg_mask(dev, TM6010_REQ08_RF2_LEFT_CHANNEL_VOL, - mute_reg, 0x20); - tm6000_set_reg_mask(dev, TM6010_REQ08_RF3_RIGHT_CHANNEL_VOL, - mute_reg, 0x20); - } else { - tm6000_set_reg_mask(dev, TM6000_REQ07_REC_VADC_AADC_LVOL, - mute_reg, 0x20); - tm6000_set_reg_mask(dev, TM6000_REQ07_RED_VADC_AADC_RVOL, - mute_reg, 0x20); - } -} - -int tm6000_tvaudio_set_mute(struct tm6000_core *dev, u8 mute) -{ - enum tm6000_mux mux; - - if (dev->radio) - mux = dev->rinput.amux; - else - mux = dev->vinput[dev->input].amux; - - switch (mux) { - case TM6000_AMUX_SIF1: - case TM6000_AMUX_SIF2: - if (dev->dev_type == TM6010) - tm6010_set_mute_sif(dev, mute); - else { - printk(KERN_INFO "ERROR: TM5600 and TM6000 don't has" - " SIF audio inputs. Please check the %s" - " configuration.\n", dev->name); - return -EINVAL; - } - break; - case TM6000_AMUX_ADC1: - case TM6000_AMUX_ADC2: - tm6010_set_mute_adc(dev, mute); - break; - default: - return -EINVAL; - break; - } - return 0; -} - -void tm6010_set_volume_sif(struct tm6000_core *dev, int vol) -{ - u8 vol_reg; - - vol_reg = vol & 0x0F; - - if (vol < 0) - vol_reg |= 0x40; - - tm6000_set_reg(dev, TM6010_REQ08_R07_A_LEFT_VOL, vol_reg); - tm6000_set_reg(dev, TM6010_REQ08_R08_A_RIGHT_VOL, vol_reg); -} - -void tm6010_set_volume_adc(struct tm6000_core *dev, int vol) -{ - u8 vol_reg; - - vol_reg = (vol + 0x10) & 0x1f; - - if (dev->dev_type == TM6010) { - tm6000_set_reg(dev, TM6010_REQ08_RF2_LEFT_CHANNEL_VOL, vol_reg); - tm6000_set_reg(dev, TM6010_REQ08_RF3_RIGHT_CHANNEL_VOL, vol_reg); - } else { - tm6000_set_reg(dev, TM6000_REQ07_REC_VADC_AADC_LVOL, vol_reg); - tm6000_set_reg(dev, TM6000_REQ07_RED_VADC_AADC_RVOL, vol_reg); - } -} - -void tm6000_set_volume(struct tm6000_core *dev, int vol) -{ - enum tm6000_mux mux; - - if (dev->radio) { - mux = dev->rinput.amux; - vol += 8; /* Offset to 0 dB */ - } else - mux = dev->vinput[dev->input].amux; - - switch (mux) { - case TM6000_AMUX_SIF1: - case TM6000_AMUX_SIF2: - if (dev->dev_type == TM6010) - tm6010_set_volume_sif(dev, vol); - else - printk(KERN_INFO "ERROR: TM5600 and TM6000 don't has" - " SIF audio inputs. Please check the %s" - " configuration.\n", dev->name); - break; - case TM6000_AMUX_ADC1: - case TM6000_AMUX_ADC2: - tm6010_set_volume_adc(dev, vol); - break; - default: - break; - } -} - -static LIST_HEAD(tm6000_devlist); -static DEFINE_MUTEX(tm6000_devlist_mutex); - -/* - * tm6000_realease_resource() - */ - -void tm6000_remove_from_devlist(struct tm6000_core *dev) -{ - mutex_lock(&tm6000_devlist_mutex); - list_del(&dev->devlist); - mutex_unlock(&tm6000_devlist_mutex); -}; - -void tm6000_add_into_devlist(struct tm6000_core *dev) -{ - mutex_lock(&tm6000_devlist_mutex); - list_add_tail(&dev->devlist, &tm6000_devlist); - mutex_unlock(&tm6000_devlist_mutex); -}; - -/* - * Extension interface - */ - -static LIST_HEAD(tm6000_extension_devlist); - -int tm6000_call_fillbuf(struct tm6000_core *dev, enum tm6000_ops_type type, - char *buf, int size) -{ - struct tm6000_ops *ops = NULL; - - /* FIXME: tm6000_extension_devlist_lock should be a spinlock */ - - if (!list_empty(&tm6000_extension_devlist)) { - list_for_each_entry(ops, &tm6000_extension_devlist, next) { - if (ops->fillbuf && ops->type == type) - ops->fillbuf(dev, buf, size); - } - } - - return 0; -} - -int tm6000_register_extension(struct tm6000_ops *ops) -{ - struct tm6000_core *dev = NULL; - - mutex_lock(&tm6000_devlist_mutex); - list_add_tail(&ops->next, &tm6000_extension_devlist); - list_for_each_entry(dev, &tm6000_devlist, devlist) { - ops->init(dev); - printk(KERN_INFO "%s: Initialized (%s) extension\n", - dev->name, ops->name); - } - mutex_unlock(&tm6000_devlist_mutex); - return 0; -} -EXPORT_SYMBOL(tm6000_register_extension); - -void tm6000_unregister_extension(struct tm6000_ops *ops) -{ - struct tm6000_core *dev = NULL; - - mutex_lock(&tm6000_devlist_mutex); - list_for_each_entry(dev, &tm6000_devlist, devlist) - ops->fini(dev); - - printk(KERN_INFO "tm6000: Remove (%s) extension\n", ops->name); - list_del(&ops->next); - mutex_unlock(&tm6000_devlist_mutex); -} -EXPORT_SYMBOL(tm6000_unregister_extension); - -void tm6000_init_extension(struct tm6000_core *dev) -{ - struct tm6000_ops *ops = NULL; - - mutex_lock(&tm6000_devlist_mutex); - if (!list_empty(&tm6000_extension_devlist)) { - list_for_each_entry(ops, &tm6000_extension_devlist, next) { - if (ops->init) - ops->init(dev); - } - } - mutex_unlock(&tm6000_devlist_mutex); -} - -void tm6000_close_extension(struct tm6000_core *dev) -{ - struct tm6000_ops *ops = NULL; - - mutex_lock(&tm6000_devlist_mutex); - if (!list_empty(&tm6000_extension_devlist)) { - list_for_each_entry(ops, &tm6000_extension_devlist, next) { - if (ops->fini) - ops->fini(dev); - } - } - mutex_unlock(&tm6000_devlist_mutex); -} diff --git a/drivers/staging/tm6000/tm6000-dvb.c b/drivers/staging/tm6000/tm6000-dvb.c deleted file mode 100644 index 0e0dfce05821..000000000000 --- a/drivers/staging/tm6000/tm6000-dvb.c +++ /dev/null @@ -1,452 +0,0 @@ -/* - * tm6000-dvb.c - dvb-t support for TM5600/TM6000/TM6010 USB video capture devices - * - * Copyright (C) 2007 Michel Ludwig <michel.ludwig@gmail.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation version 2 - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include <linux/kernel.h> -#include <linux/slab.h> -#include <linux/usb.h> - -#include "tm6000.h" -#include "tm6000-regs.h" - -#include "zl10353.h" - -#include <media/tuner.h> - -#include "tuner-xc2028.h" -#include "xc5000.h" - -MODULE_DESCRIPTION("DVB driver extension module for tm5600/6000/6010 based TV cards"); -MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>"); -MODULE_LICENSE("GPL"); - -MODULE_SUPPORTED_DEVICE("{{Trident, tm5600}," - "{{Trident, tm6000}," - "{{Trident, tm6010}"); - -static int debug; - -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "enable debug message"); - -static inline void print_err_status(struct tm6000_core *dev, - int packet, int status) -{ - char *errmsg = "Unknown"; - - switch (status) { - case -ENOENT: - errmsg = "unlinked synchronuously"; - break; - case -ECONNRESET: - errmsg = "unlinked asynchronuously"; - break; - case -ENOSR: - errmsg = "Buffer error (overrun)"; - break; - case -EPIPE: - errmsg = "Stalled (device not responding)"; - break; - case -EOVERFLOW: - errmsg = "Babble (bad cable?)"; - break; - case -EPROTO: - errmsg = "Bit-stuff error (bad cable?)"; - break; - case -EILSEQ: - errmsg = "CRC/Timeout (could be anything)"; - break; - case -ETIME: - errmsg = "Device does not respond"; - break; - } - if (packet < 0) { - dprintk(dev, 1, "URB status %d [%s].\n", - status, errmsg); - } else { - dprintk(dev, 1, "URB packet %d, status %d [%s].\n", - packet, status, errmsg); - } -} - -static void tm6000_urb_received(struct urb *urb) -{ - int ret; - struct tm6000_core *dev = urb->context; - - if (urb->status != 0) - print_err_status(dev, 0, urb->status); - else if (urb->actual_length > 0) - dvb_dmx_swfilter(&dev->dvb->demux, urb->transfer_buffer, - urb->actual_length); - - if (dev->dvb->streams > 0) { - ret = usb_submit_urb(urb, GFP_ATOMIC); - if (ret < 0) { - printk(KERN_ERR "tm6000: error %s\n", __func__); - kfree(urb->transfer_buffer); - usb_free_urb(urb); - } - } -} - -int tm6000_start_stream(struct tm6000_core *dev) -{ - int ret; - unsigned int pipe, size; - struct tm6000_dvb *dvb = dev->dvb; - - printk(KERN_INFO "tm6000: got start stream request %s\n", __func__); - - if (dev->mode != TM6000_MODE_DIGITAL) { - tm6000_init_digital_mode(dev); - dev->mode = TM6000_MODE_DIGITAL; - } - - dvb->bulk_urb = usb_alloc_urb(0, GFP_KERNEL); - if (dvb->bulk_urb == NULL) { - printk(KERN_ERR "tm6000: couldn't allocate urb\n"); - return -ENOMEM; - } - - pipe = usb_rcvbulkpipe(dev->udev, dev->bulk_in.endp->desc.bEndpointAddress - & USB_ENDPOINT_NUMBER_MASK); - - size = usb_maxpacket(dev->udev, pipe, usb_pipeout(pipe)); - size = size * 15; /* 512 x 8 or 12 or 15 */ - - dvb->bulk_urb->transfer_buffer = kzalloc(size, GFP_KERNEL); - if (dvb->bulk_urb->transfer_buffer == NULL) { - usb_free_urb(dvb->bulk_urb); - printk(KERN_ERR "tm6000: couldn't allocate transfer buffer!\n"); - return -ENOMEM; - } - - usb_fill_bulk_urb(dvb->bulk_urb, dev->udev, pipe, - dvb->bulk_urb->transfer_buffer, - size, - tm6000_urb_received, dev); - - ret = usb_clear_halt(dev->udev, pipe); - if (ret < 0) { - printk(KERN_ERR "tm6000: error %i in %s during pipe reset\n", - ret, __func__); - return ret; - } else - printk(KERN_ERR "tm6000: pipe resetted\n"); - -/* mutex_lock(&tm6000_driver.open_close_mutex); */ - ret = usb_submit_urb(dvb->bulk_urb, GFP_KERNEL); - -/* mutex_unlock(&tm6000_driver.open_close_mutex); */ - if (ret) { - printk(KERN_ERR "tm6000: submit of urb failed (error=%i)\n", - ret); - - kfree(dvb->bulk_urb->transfer_buffer); - usb_free_urb(dvb->bulk_urb); - return ret; - } - - return 0; -} - -void tm6000_stop_stream(struct tm6000_core *dev) -{ - struct tm6000_dvb *dvb = dev->dvb; - - if (dvb->bulk_urb) { - printk(KERN_INFO "urb killing\n"); - usb_kill_urb(dvb->bulk_urb); - printk(KERN_INFO "urb buffer free\n"); - kfree(dvb->bulk_urb->transfer_buffer); - usb_free_urb(dvb->bulk_urb); - dvb->bulk_urb = NULL; - } -} - -int tm6000_start_feed(struct dvb_demux_feed *feed) -{ - struct dvb_demux *demux = feed->demux; - struct tm6000_core *dev = demux->priv; - struct tm6000_dvb *dvb = dev->dvb; - printk(KERN_INFO "tm6000: got start feed request %s\n", __func__); - - mutex_lock(&dvb->mutex); - if (dvb->streams == 0) { - dvb->streams = 1; -/* mutex_init(&tm6000_dev->streming_mutex); */ - tm6000_start_stream(dev); - } else - ++(dvb->streams); - mutex_unlock(&dvb->mutex); - - return 0; -} - -int tm6000_stop_feed(struct dvb_demux_feed *feed) -{ - struct dvb_demux *demux = feed->demux; - struct tm6000_core *dev = demux->priv; - struct tm6000_dvb *dvb = dev->dvb; - - printk(KERN_INFO "tm6000: got stop feed request %s\n", __func__); - - mutex_lock(&dvb->mutex); - - printk(KERN_INFO "stream %#x\n", dvb->streams); - --(dvb->streams); - if (dvb->streams == 0) { - printk(KERN_INFO "stop stream\n"); - tm6000_stop_stream(dev); -/* mutex_destroy(&tm6000_dev->streaming_mutex); */ - } - mutex_unlock(&dvb->mutex); -/* mutex_destroy(&tm6000_dev->streaming_mutex); */ - - return 0; -} - -int tm6000_dvb_attach_frontend(struct tm6000_core *dev) -{ - struct tm6000_dvb *dvb = dev->dvb; - - if (dev->caps.has_zl10353) { - struct zl10353_config config = { - .demod_address = dev->demod_addr, - .no_tuner = 1, - .parallel_ts = 1, - .if2 = 45700, - .disable_i2c_gate_ctrl = 1, - }; - - dvb->frontend = dvb_attach(zl10353_attach, &config, - &dev->i2c_adap); - } else { - printk(KERN_ERR "tm6000: no frontend defined for the device!\n"); - return -1; - } - - return (!dvb->frontend) ? -1 : 0; -} - -DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); - -int register_dvb(struct tm6000_core *dev) -{ - int ret = -1; - struct tm6000_dvb *dvb = dev->dvb; - - mutex_init(&dvb->mutex); - - dvb->streams = 0; - - /* attach the frontend */ - ret = tm6000_dvb_attach_frontend(dev); - if (ret < 0) { - printk(KERN_ERR "tm6000: couldn't attach the frontend!\n"); - goto err; - } - - ret = dvb_register_adapter(&dvb->adapter, "Trident TVMaster 6000 DVB-T", - THIS_MODULE, &dev->udev->dev, adapter_nr); - dvb->adapter.priv = dev; - - if (dvb->frontend) { - switch (dev->tuner_type) { - case TUNER_XC2028: { - struct xc2028_config cfg = { - .i2c_adap = &dev->i2c_adap, - .i2c_addr = dev->tuner_addr, - }; - - dvb->frontend->callback = tm6000_tuner_callback; - ret = dvb_register_frontend(&dvb->adapter, dvb->frontend); - if (ret < 0) { - printk(KERN_ERR - "tm6000: couldn't register frontend\n"); - goto adapter_err; - } - - if (!dvb_attach(xc2028_attach, dvb->frontend, &cfg)) { - printk(KERN_ERR "tm6000: couldn't register " - "frontend (xc3028)\n"); - ret = -EINVAL; - goto frontend_err; - } - printk(KERN_INFO "tm6000: XC2028/3028 asked to be " - "attached to frontend!\n"); - break; - } - case TUNER_XC5000: { - struct xc5000_config cfg = { - .i2c_address = dev->tuner_addr, - }; - - dvb->frontend->callback = tm6000_xc5000_callback; - ret = dvb_register_frontend(&dvb->adapter, dvb->frontend); - if (ret < 0) { - printk(KERN_ERR - "tm6000: couldn't register frontend\n"); - goto adapter_err; - } - - if (!dvb_attach(xc5000_attach, dvb->frontend, &dev->i2c_adap, &cfg)) { - printk(KERN_ERR "tm6000: couldn't register " - "frontend (xc5000)\n"); - ret = -EINVAL; - goto frontend_err; - } - printk(KERN_INFO "tm6000: XC5000 asked to be " - "attached to frontend!\n"); - break; - } - } - } else - printk(KERN_ERR "tm6000: no frontend found\n"); - - dvb->demux.dmx.capabilities = DMX_TS_FILTERING | DMX_SECTION_FILTERING - | DMX_MEMORY_BASED_FILTERING; - dvb->demux.priv = dev; - dvb->demux.filternum = 8; - dvb->demux.feednum = 8; - dvb->demux.start_feed = tm6000_start_feed; - dvb->demux.stop_feed = tm6000_stop_feed; - dvb->demux.write_to_decoder = NULL; - ret = dvb_dmx_init(&dvb->demux); - if (ret < 0) { - printk("tm6000: dvb_dmx_init failed (errno = %d)\n", ret); - goto frontend_err; - } - - dvb->dmxdev.filternum = dev->dvb->demux.filternum; - dvb->dmxdev.demux = &dev->dvb->demux.dmx; - dvb->dmxdev.capabilities = 0; - - ret = dvb_dmxdev_init(&dvb->dmxdev, &dvb->adapter); - if (ret < 0) { - printk("tm6000: dvb_dmxdev_init failed (errno = %d)\n", ret); - goto dvb_dmx_err; - } - - return 0; - -dvb_dmx_err: - dvb_dmx_release(&dvb->demux); -frontend_err: - if (dvb->frontend) { - dvb_frontend_detach(dvb->frontend); - dvb_unregister_frontend(dvb->frontend); - } -adapter_err: - dvb_unregister_adapter(&dvb->adapter); -err: - return ret; -} - -void unregister_dvb(struct tm6000_core *dev) -{ - struct tm6000_dvb *dvb = dev->dvb; - - if (dvb->bulk_urb != NULL) { - struct urb *bulk_urb = dvb->bulk_urb; - - kfree(bulk_urb->transfer_buffer); - bulk_urb->transfer_buffer = NULL; - usb_unlink_urb(bulk_urb); - usb_free_urb(bulk_urb); - } - -/* mutex_lock(&tm6000_driver.open_close_mutex); */ - if (dvb->frontend) { - dvb_frontend_detach(dvb->frontend); - dvb_unregister_frontend(dvb->frontend); - } - - dvb_dmxdev_release(&dvb->dmxdev); - dvb_dmx_release(&dvb->demux); - dvb_unregister_adapter(&dvb->adapter); - mutex_destroy(&dvb->mutex); -/* mutex_unlock(&tm6000_driver.open_close_mutex); */ -} - -static int dvb_init(struct tm6000_core *dev) -{ - struct tm6000_dvb *dvb; - int rc; - - if (!dev) - return 0; - - if (!dev->caps.has_dvb) - return 0; - - dvb = kzalloc(sizeof(struct tm6000_dvb), GFP_KERNEL); - if (!dvb) { - printk(KERN_INFO "Cannot allocate memory\n"); - return -ENOMEM; - } - - dev->dvb = dvb; - - rc = register_dvb(dev); - if (rc < 0) { - kfree(dvb); - dev->dvb = NULL; - return 0; - } - - return 0; -} - -static int dvb_fini(struct tm6000_core *dev) -{ - if (!dev) - return 0; - - if (!dev->caps.has_dvb) - return 0; - - if (dev->dvb) { - unregister_dvb(dev); - kfree(dev->dvb); - dev->dvb = NULL; - } - - return 0; -} - -static struct tm6000_ops dvb_ops = { - .type = TM6000_DVB, - .name = "TM6000 dvb Extension", - .init = dvb_init, - .fini = dvb_fini, -}; - -static int __init tm6000_dvb_register(void) -{ - return tm6000_register_extension(&dvb_ops); -} - -static void __exit tm6000_dvb_unregister(void) -{ - tm6000_unregister_extension(&dvb_ops); -} - -module_init(tm6000_dvb_register); -module_exit(tm6000_dvb_unregister); diff --git a/drivers/staging/tm6000/tm6000-i2c.c b/drivers/staging/tm6000/tm6000-i2c.c deleted file mode 100644 index 5a651ea5f60a..000000000000 --- a/drivers/staging/tm6000/tm6000-i2c.c +++ /dev/null @@ -1,345 +0,0 @@ -/* - * tm6000-i2c.c - driver for TM5600/TM6000/TM6010 USB video capture devices - * - * Copyright (C) 2006-2007 Mauro Carvalho Chehab <mchehab@infradead.org> - * - * Copyright (C) 2007 Michel Ludwig <michel.ludwig@gmail.com> - * - Fix SMBus Read Byte command - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation version 2 - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include <linux/module.h> -#include <linux/kernel.h> -#include <linux/usb.h> -#include <linux/i2c.h> - -#include "tm6000.h" -#include "tm6000-regs.h" -#include <media/v4l2-common.h> -#include <media/tuner.h> -#include "tuner-xc2028.h" - - -/* ----------------------------------------------------------- */ - -static unsigned int i2c_debug; -module_param(i2c_debug, int, 0644); -MODULE_PARM_DESC(i2c_debug, "enable debug messages [i2c]"); - -#define i2c_dprintk(lvl, fmt, args...) if (i2c_debug >= lvl) do { \ - printk(KERN_DEBUG "%s at %s: " fmt, \ - dev->name, __func__, ##args); } while (0) - -static int tm6000_i2c_send_regs(struct tm6000_core *dev, unsigned char addr, - __u8 reg, char *buf, int len) -{ - int rc; - unsigned int tsleep; - unsigned int i2c_packet_limit = 16; - - if (dev->dev_type == TM6010) - i2c_packet_limit = 64; - - if (!buf) - return -1; - - if (len < 1 || len > i2c_packet_limit) { - printk(KERN_ERR "Incorrect length of i2c packet = %d, limit set to %d\n", - len, i2c_packet_limit); - return -1; - } - - /* capture mutex */ - rc = tm6000_read_write_usb(dev, USB_DIR_OUT | USB_TYPE_VENDOR | - USB_RECIP_DEVICE, REQ_16_SET_GET_I2C_WR1_RDN, - addr | reg << 8, 0, buf, len); - - if (rc < 0) { - /* release mutex */ - return rc; - } - - /* Calculate delay time, 14000us for 64 bytes */ - tsleep = ((len * 200) + 200 + 1000) / 1000; - msleep(tsleep); - - /* release mutex */ - return rc; -} - -/* Generic read - doesn't work fine with 16bit registers */ -static int tm6000_i2c_recv_regs(struct tm6000_core *dev, unsigned char addr, - __u8 reg, char *buf, int len) -{ - int rc; - u8 b[2]; - unsigned int i2c_packet_limit = 16; - - if (dev->dev_type == TM6010) - i2c_packet_limit = 64; - - if (!buf) - return -1; - - if (len < 1 || len > i2c_packet_limit) { - printk(KERN_ERR "Incorrect length of i2c packet = %d, limit set to %d\n", - len, i2c_packet_limit); - return -1; - } - - /* capture mutex */ - if ((dev->caps.has_zl10353) && (dev->demod_addr << 1 == addr) && (reg % 2 == 0)) { - /* - * Workaround an I2C bug when reading from zl10353 - */ - reg -= 1; - len += 1; - - rc = tm6000_read_write_usb(dev, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - REQ_16_SET_GET_I2C_WR1_RDN, addr | reg << 8, 0, b, len); - - *buf = b[1]; - } else { - rc = tm6000_read_write_usb(dev, USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - REQ_16_SET_GET_I2C_WR1_RDN, addr | reg << 8, 0, buf, len); - } - - /* release mutex */ - return rc; -} - -/* - * read from a 16bit register - * for example xc2028, xc3028 or xc3028L - */ -static int tm6000_i2c_recv_regs16(struct tm6000_core *dev, unsigned char addr, - __u16 reg, char *buf, int len) -{ - int rc; - unsigned char ureg; - - if (!buf || len != 2) - return -1; - - /* capture mutex */ - if (dev->dev_type == TM6010) { - ureg = reg & 0xFF; - rc = tm6000_read_write_usb(dev, USB_DIR_OUT | USB_TYPE_VENDOR | - USB_RECIP_DEVICE, REQ_16_SET_GET_I2C_WR1_RDN, - addr | (reg & 0xFF00), 0, &ureg, 1); - - if (rc < 0) { - /* release mutex */ - return rc; - } - - msleep(1400 / 1000); - rc = tm6000_read_write_usb(dev, USB_DIR_IN | USB_TYPE_VENDOR | - USB_RECIP_DEVICE, REQ_35_AFTEK_TUNER_READ, - reg, 0, buf, len); - } else { - rc = tm6000_read_write_usb(dev, USB_DIR_IN | USB_TYPE_VENDOR | - USB_RECIP_DEVICE, REQ_14_SET_GET_I2C_WR2_RDN, - addr, reg, buf, len); - } - - /* release mutex */ - return rc; -} - -static int tm6000_i2c_xfer(struct i2c_adapter *i2c_adap, - struct i2c_msg msgs[], int num) -{ - struct tm6000_core *dev = i2c_adap->algo_data; - int addr, rc, i, byte; - - if (num <= 0) - return 0; - for (i = 0; i < num; i++) { - addr = (msgs[i].addr << 1) & 0xff; - i2c_dprintk(2, "%s %s addr=0x%x len=%d:", - (msgs[i].flags & I2C_M_RD) ? "read" : "write", - i == num - 1 ? "stop" : "nonstop", addr, msgs[i].len); - if (msgs[i].flags & I2C_M_RD) { - /* read request without preceding register selection */ - /* - * The TM6000 only supports a read transaction - * immediately after a 1 or 2 byte write to select - * a register. We cannot fulfil this request. - */ - i2c_dprintk(2, " read without preceding write not" - " supported"); - rc = -EOPNOTSUPP; - goto err; - } else if (i + 1 < num && msgs[i].len <= 2 && - (msgs[i + 1].flags & I2C_M_RD) && - msgs[i].addr == msgs[i + 1].addr) { - /* 1 or 2 byte write followed by a read */ - if (i2c_debug >= 2) - for (byte = 0; byte < msgs[i].len; byte++) - printk(" %02x", msgs[i].buf[byte]); - i2c_dprintk(2, "; joined to read %s len=%d:", - i == num - 2 ? "stop" : "nonstop", - msgs[i + 1].len); - - if (msgs[i].len == 2) { - rc = tm6000_i2c_recv_regs16(dev, addr, - msgs[i].buf[0] << 8 | msgs[i].buf[1], - msgs[i + 1].buf, msgs[i + 1].len); - } else { - rc = tm6000_i2c_recv_regs(dev, addr, msgs[i].buf[0], - msgs[i + 1].buf, msgs[i + 1].len); - } - - i++; - - if (addr == dev->tuner_addr << 1) { - tm6000_set_reg(dev, REQ_50_SET_START, 0, 0); - tm6000_set_reg(dev, REQ_51_SET_STOP, 0, 0); - } - if (i2c_debug >= 2) - for (byte = 0; byte < msgs[i].len; byte++) - printk(" %02x", msgs[i].buf[byte]); - } else { - /* write bytes */ - if (i2c_debug >= 2) - for (byte = 0; byte < msgs[i].len; byte++) - printk(" %02x", msgs[i].buf[byte]); - rc = tm6000_i2c_send_regs(dev, addr, msgs[i].buf[0], - msgs[i].buf + 1, msgs[i].len - 1); - - if (addr == dev->tuner_addr << 1) { - tm6000_set_reg(dev, REQ_50_SET_START, 0, 0); - tm6000_set_reg(dev, REQ_51_SET_STOP, 0, 0); - } - } - if (i2c_debug >= 2) - printk("\n"); - if (rc < 0) - goto err; - } - - return num; -err: - i2c_dprintk(2, " ERROR: %i\n", rc); - return rc; -} - -static int tm6000_i2c_eeprom(struct tm6000_core *dev) -{ - int i, rc; - unsigned char *p = dev->eedata; - unsigned char bytes[17]; - - dev->i2c_client.addr = 0xa0 >> 1; - dev->eedata_size = 0; - - bytes[16] = '\0'; - for (i = 0; i < sizeof(dev->eedata); ) { - *p = i; - rc = tm6000_i2c_recv_regs(dev, 0xa0, i, p, 1); - if (rc < 1) { - if (p == dev->eedata) - goto noeeprom; - else { - printk(KERN_WARNING - "%s: i2c eeprom read error (err=%d)\n", - dev->name, rc); - } - return -EINVAL; - } - dev->eedata_size++; - p++; - if (0 == (i % 16)) - printk(KERN_INFO "%s: i2c eeprom %02x:", dev->name, i); - printk(" %02x", dev->eedata[i]); - if ((dev->eedata[i] >= ' ') && (dev->eedata[i] <= 'z')) - bytes[i%16] = dev->eedata[i]; - else - bytes[i%16] = '.'; - - i++; - - if (0 == (i % 16)) { - bytes[16] = '\0'; - printk(" %s\n", bytes); - } - } - if (0 != (i%16)) { - bytes[i%16] = '\0'; - for (i %= 16; i < 16; i++) - printk(" "); - printk(" %s\n", bytes); - } - - return 0; - -noeeprom: - printk(KERN_INFO "%s: Huh, no eeprom present (err=%d)?\n", - dev->name, rc); - return -EINVAL; -} - -/* ----------------------------------------------------------- */ - -/* - * functionality() - */ -static u32 functionality(struct i2c_adapter *adap) -{ - return I2C_FUNC_SMBUS_EMUL; -} - -static const struct i2c_algorithm tm6000_algo = { - .master_xfer = tm6000_i2c_xfer, - .functionality = functionality, -}; - -/* ----------------------------------------------------------- */ - -/* - * tm6000_i2c_register() - * register i2c bus - */ -int tm6000_i2c_register(struct tm6000_core *dev) -{ - int rc; - - dev->i2c_adap.owner = THIS_MODULE; - dev->i2c_adap.algo = &tm6000_algo; - dev->i2c_adap.dev.parent = &dev->udev->dev; - strlcpy(dev->i2c_adap.name, dev->name, sizeof(dev->i2c_adap.name)); - dev->i2c_adap.algo_data = dev; - i2c_set_adapdata(&dev->i2c_adap, &dev->v4l2_dev); - rc = i2c_add_adapter(&dev->i2c_adap); - if (rc) - return rc; - - dev->i2c_client.adapter = &dev->i2c_adap; - strlcpy(dev->i2c_client.name, "tm6000 internal", I2C_NAME_SIZE); - tm6000_i2c_eeprom(dev); - - return 0; -} - -/* - * tm6000_i2c_unregister() - * unregister i2c_bus - */ -int tm6000_i2c_unregister(struct tm6000_core *dev) -{ - i2c_del_adapter(&dev->i2c_adap); - return 0; -} diff --git a/drivers/staging/tm6000/tm6000-input.c b/drivers/staging/tm6000/tm6000-input.c deleted file mode 100644 index 70a2c5f557c1..000000000000 --- a/drivers/staging/tm6000/tm6000-input.c +++ /dev/null @@ -1,459 +0,0 @@ -/* - * tm6000-input.c - driver for TM5600/TM6000/TM6010 USB video capture devices - * - * Copyright (C) 2010 Stefan Ringel <stefan.ringel@arcor.de> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation version 2 - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include <linux/module.h> -#include <linux/init.h> -#include <linux/delay.h> - -#include <linux/input.h> -#include <linux/usb.h> - -#include <media/rc-core.h> - -#include "tm6000.h" -#include "tm6000-regs.h" - -static unsigned int ir_debug; -module_param(ir_debug, int, 0644); -MODULE_PARM_DESC(ir_debug, "enable debug message [IR]"); - -static unsigned int enable_ir = 1; -module_param(enable_ir, int, 0644); -MODULE_PARM_DESC(enable_ir, "enable ir (default is enable)"); - -/* number of 50ms for ON-OFF-ON power led */ -/* show IR activity */ -#define PWLED_OFF 2 - -#undef dprintk - -#define dprintk(fmt, arg...) \ - if (ir_debug) { \ - printk(KERN_DEBUG "%s/ir: " fmt, ir->name , ## arg); \ - } - -struct tm6000_ir_poll_result { - u16 rc_data; -}; - -struct tm6000_IR { - struct tm6000_core *dev; - struct rc_dev *rc; - char name[32]; - char phys[32]; - - /* poll expernal decoder */ - int polling; - struct delayed_work work; - u8 wait:1; - u8 key:1; - u8 pwled:1; - u8 pwledcnt; - u16 key_addr; - struct urb *int_urb; - u8 *urb_data; - - int (*get_key) (struct tm6000_IR *, struct tm6000_ir_poll_result *); - - /* IR device properties */ - u64 rc_type; -}; - - -void tm6000_ir_wait(struct tm6000_core *dev, u8 state) -{ - struct tm6000_IR *ir = dev->ir; - - if (!dev->ir) - return; - - if (state) - ir->wait = 1; - else - ir->wait = 0; -} - - -static int tm6000_ir_config(struct tm6000_IR *ir) -{ - struct tm6000_core *dev = ir->dev; - u8 buf[10]; - int rc; - - switch (ir->rc_type) { - case RC_TYPE_NEC: - /* Setup IR decoder for NEC standard 12MHz system clock */ - /* IR_LEADER_CNT = 0.9ms */ - tm6000_set_reg(dev, TM6010_REQ07_RD8_IR_LEADER1, 0xaa); - tm6000_set_reg(dev, TM6010_REQ07_RD8_IR_LEADER0, 0x30); - /* IR_PULSE_CNT = 0.7ms */ - tm6000_set_reg(dev, TM6010_REQ07_RD8_IR_PULSE_CNT1, 0x20); - tm6000_set_reg(dev, TM6010_REQ07_RD8_IR_PULSE_CNT0, 0xd0); - /* Remote WAKEUP = enable */ - tm6000_set_reg(dev, TM6010_REQ07_RE5_REMOTE_WAKEUP, 0xfe); - /* IR_WKUP_SEL = Low byte in decoded IR data */ - tm6000_set_reg(dev, TM6010_REQ07_RD8_IR_WAKEUP_SEL, 0xff); - /* IR_WKU_ADD code */ - tm6000_set_reg(dev, TM6010_REQ07_RD8_IR_WAKEUP_ADD, 0xff); - tm6000_flash_led(dev, 0); - msleep(100); - tm6000_flash_led(dev, 1); - break; - default: - /* hack */ - buf[0] = 0xff; - buf[1] = 0xff; - buf[2] = 0xf2; - buf[3] = 0x2b; - buf[4] = 0x20; - buf[5] = 0x35; - buf[6] = 0x60; - buf[7] = 0x04; - buf[8] = 0xc0; - buf[9] = 0x08; - - rc = tm6000_read_write_usb(dev, USB_DIR_OUT | USB_TYPE_VENDOR | - USB_RECIP_DEVICE, REQ_00_SET_IR_VALUE, 0, 0, buf, 0x0a); - msleep(100); - - if (rc < 0) { - printk(KERN_INFO "IR configuration failed"); - return rc; - } - break; - } - - return 0; -} - -static void tm6000_ir_urb_received(struct urb *urb) -{ - struct tm6000_core *dev = urb->context; - struct tm6000_IR *ir = dev->ir; - int rc; - - if (urb->status != 0) - printk(KERN_INFO "not ready\n"); - else if (urb->actual_length > 0) { - memcpy(ir->urb_data, urb->transfer_buffer, urb->actual_length); - - dprintk("data %02x %02x %02x %02x\n", ir->urb_data[0], - ir->urb_data[1], ir->urb_data[2], ir->urb_data[3]); - - ir->key = 1; - } - - rc = usb_submit_urb(urb, GFP_ATOMIC); -} - -static int default_polling_getkey(struct tm6000_IR *ir, - struct tm6000_ir_poll_result *poll_result) -{ - struct tm6000_core *dev = ir->dev; - int rc; - u8 buf[2]; - - if (ir->wait && !&dev->int_in) - return 0; - - if (&dev->int_in) { - switch (ir->rc_type) { - case RC_TYPE_RC5: - poll_result->rc_data = ir->urb_data[0]; - break; - case RC_TYPE_NEC: - if (ir->urb_data[1] == ((ir->key_addr >> 8) & 0xff)) { - poll_result->rc_data = ir->urb_data[0] - | ir->urb_data[1] << 8; - } - break; - default: - poll_result->rc_data = ir->urb_data[0] - | ir->urb_data[1] << 8; - break; - } - } else { - tm6000_set_reg(dev, REQ_04_EN_DISABLE_MCU_INT, 2, 0); - msleep(10); - tm6000_set_reg(dev, REQ_04_EN_DISABLE_MCU_INT, 2, 1); - msleep(10); - - if (ir->rc_type == RC_TYPE_RC5) { - rc = tm6000_read_write_usb(dev, USB_DIR_IN | - USB_TYPE_VENDOR | USB_RECIP_DEVICE, - REQ_02_GET_IR_CODE, 0, 0, buf, 1); - - msleep(10); - - dprintk("read data=%02x\n", buf[0]); - if (rc < 0) - return rc; - - poll_result->rc_data = buf[0]; - } else { - rc = tm6000_read_write_usb(dev, USB_DIR_IN | - USB_TYPE_VENDOR | USB_RECIP_DEVICE, - REQ_02_GET_IR_CODE, 0, 0, buf, 2); - - msleep(10); - - dprintk("read data=%04x\n", buf[0] | buf[1] << 8); - if (rc < 0) - return rc; - - poll_result->rc_data = buf[0] | buf[1] << 8; - } - if ((poll_result->rc_data & 0x00ff) != 0xff) - ir->key = 1; - } - return 0; -} - -static void tm6000_ir_handle_key(struct tm6000_IR *ir) -{ - struct tm6000_core *dev = ir->dev; - int result; - struct tm6000_ir_poll_result poll_result; - - /* read the registers containing the IR status */ - result = ir->get_key(ir, &poll_result); - if (result < 0) { - printk(KERN_INFO "ir->get_key() failed %d\n", result); - return; - } - - dprintk("ir->get_key result data=%04x\n", poll_result.rc_data); - - if (ir->pwled) { - if (ir->pwledcnt >= PWLED_OFF) { - ir->pwled = 0; - ir->pwledcnt = 0; - tm6000_flash_led(dev, 1); - } else - ir->pwledcnt += 1; - } - - if (ir->key) { - rc_keydown(ir->rc, poll_result.rc_data, 0); - ir->key = 0; - ir->pwled = 1; - ir->pwledcnt = 0; - tm6000_flash_led(dev, 0); - } - return; -} - -static void tm6000_ir_work(struct work_struct *work) -{ - struct tm6000_IR *ir = container_of(work, struct tm6000_IR, work.work); - - tm6000_ir_handle_key(ir); - schedule_delayed_work(&ir->work, msecs_to_jiffies(ir->polling)); -} - -static int tm6000_ir_start(struct rc_dev *rc) -{ - struct tm6000_IR *ir = rc->priv; - - INIT_DELAYED_WORK(&ir->work, tm6000_ir_work); - schedule_delayed_work(&ir->work, 0); - - return 0; -} - -static void tm6000_ir_stop(struct rc_dev *rc) -{ - struct tm6000_IR *ir = rc->priv; - - cancel_delayed_work_sync(&ir->work); -} - -int tm6000_ir_change_protocol(struct rc_dev *rc, u64 rc_type) -{ - struct tm6000_IR *ir = rc->priv; - - if (!ir) - return 0; - - if ((rc->rc_map.scan) && (rc_type == RC_TYPE_NEC)) - ir->key_addr = ((rc->rc_map.scan[0].scancode >> 8) & 0xffff); - - ir->get_key = default_polling_getkey; - ir->rc_type = rc_type; - - tm6000_ir_config(ir); - /* TODO */ - return 0; -} - -int tm6000_ir_int_start(struct tm6000_core *dev) -{ - struct tm6000_IR *ir = dev->ir; - int pipe, size; - int err = -ENOMEM; - - - if (!ir) - return -ENODEV; - - ir->int_urb = usb_alloc_urb(0, GFP_KERNEL); - if (!ir->int_urb) - return -ENOMEM; - - pipe = usb_rcvintpipe(dev->udev, - dev->int_in.endp->desc.bEndpointAddress - & USB_ENDPOINT_NUMBER_MASK); - - size = usb_maxpacket(dev->udev, pipe, usb_pipeout(pipe)); - dprintk("IR max size: %d\n", size); - - ir->int_urb->transfer_buffer = kzalloc(size, GFP_KERNEL); - if (ir->int_urb->transfer_buffer == NULL) { - usb_free_urb(ir->int_urb); - return err; - } - dprintk("int interval: %d\n", dev->int_in.endp->desc.bInterval); - usb_fill_int_urb(ir->int_urb, dev->udev, pipe, - ir->int_urb->transfer_buffer, size, - tm6000_ir_urb_received, dev, - dev->int_in.endp->desc.bInterval); - err = usb_submit_urb(ir->int_urb, GFP_KERNEL); - if (err) { - kfree(ir->int_urb->transfer_buffer); - usb_free_urb(ir->int_urb); - return err; - } - ir->urb_data = kzalloc(size, GFP_KERNEL); - - return 0; -} - -void tm6000_ir_int_stop(struct tm6000_core *dev) -{ - struct tm6000_IR *ir = dev->ir; - - if (!ir) - return; - - usb_kill_urb(ir->int_urb); - kfree(ir->int_urb->transfer_buffer); - usb_free_urb(ir->int_urb); - ir->int_urb = NULL; - kfree(ir->urb_data); - ir->urb_data = NULL; -} - -int tm6000_ir_init(struct tm6000_core *dev) -{ - struct tm6000_IR *ir; - struct rc_dev *rc; - int err = -ENOMEM; - - if (!enable_ir) - return -ENODEV; - - if (!dev->caps.has_remote) - return 0; - - if (!dev->ir_codes) - return 0; - - ir = kzalloc(sizeof(*ir), GFP_KERNEL); - rc = rc_allocate_device(); - if (!ir || !rc) - goto out; - - /* record handles to ourself */ - ir->dev = dev; - dev->ir = ir; - ir->rc = rc; - - /* input einrichten */ - rc->allowed_protos = RC_TYPE_RC5 | RC_TYPE_NEC; - rc->priv = ir; - rc->change_protocol = tm6000_ir_change_protocol; - rc->open = tm6000_ir_start; - rc->close = tm6000_ir_stop; - rc->driver_type = RC_DRIVER_SCANCODE; - - ir->polling = 50; - ir->pwled = 0; - ir->pwledcnt = 0; - - - snprintf(ir->name, sizeof(ir->name), "tm5600/60x0 IR (%s)", - dev->name); - - usb_make_path(dev->udev, ir->phys, sizeof(ir->phys)); - strlcat(ir->phys, "/input0", sizeof(ir->phys)); - - tm6000_ir_change_protocol(rc, RC_TYPE_UNKNOWN); - - rc->input_name = ir->name; - rc->input_phys = ir->phys; - rc->input_id.bustype = BUS_USB; - rc->input_id.version = 1; - rc->input_id.vendor = le16_to_cpu(dev->udev->descriptor.idVendor); - rc->input_id.product = le16_to_cpu(dev->udev->descriptor.idProduct); - rc->map_name = dev->ir_codes; - rc->driver_name = "tm6000"; - rc->dev.parent = &dev->udev->dev; - - if (&dev->int_in) { - dprintk("IR over int\n"); - - err = tm6000_ir_int_start(dev); - - if (err) - goto out; - } - - /* ir register */ - err = rc_register_device(rc); - if (err) - goto out; - - return 0; - -out: - dev->ir = NULL; - rc_free_device(rc); - kfree(ir); - return err; -} - -int tm6000_ir_fini(struct tm6000_core *dev) -{ - struct tm6000_IR *ir = dev->ir; - - /* skip detach on non attached board */ - - if (!ir) - return 0; - - rc_unregister_device(ir->rc); - - if (ir->int_urb) - tm6000_ir_int_stop(dev); - - kfree(ir); - dev->ir = NULL; - - return 0; -} diff --git a/drivers/staging/tm6000/tm6000-regs.h b/drivers/staging/tm6000/tm6000-regs.h deleted file mode 100644 index 5375a8347374..000000000000 --- a/drivers/staging/tm6000/tm6000-regs.h +++ /dev/null @@ -1,598 +0,0 @@ -/* - * tm6000-regs.h - driver for TM5600/TM6000/TM6010 USB video capture devices - * - * Copyright (C) 2006-2007 Mauro Carvalho Chehab <mchehab@infradead.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation version 2 - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -/* - * Define TV Master TM5600/TM6000/TM6010 Request codes - */ -#define REQ_00_SET_IR_VALUE 0 -#define REQ_01_SET_WAKEUP_IRCODE 1 -#define REQ_02_GET_IR_CODE 2 -#define REQ_03_SET_GET_MCU_PIN 3 -#define REQ_04_EN_DISABLE_MCU_INT 4 -#define REQ_05_SET_GET_USBREG 5 - /* Write: RegNum, Value, 0 */ - /* Read : RegNum, Value, 1, RegStatus */ -#define REQ_06_SET_GET_USBREG_BIT 6 -#define REQ_07_SET_GET_AVREG 7 - /* Write: RegNum, Value, 0 */ - /* Read : RegNum, Value, 1, RegStatus */ -#define REQ_08_SET_GET_AVREG_BIT 8 -#define REQ_09_SET_GET_TUNER_FQ 9 -#define REQ_10_SET_TUNER_SYSTEM 10 -#define REQ_11_SET_EEPROM_ADDR 11 -#define REQ_12_SET_GET_EEPROMBYTE 12 -#define REQ_13_GET_EEPROM_SEQREAD 13 -#define REQ_14_SET_GET_I2C_WR2_RDN 14 -#define REQ_15_SET_GET_I2CBYTE 15 - /* Write: Subaddr, Slave Addr, value, 0 */ - /* Read : Subaddr, Slave Addr, value, 1 */ -#define REQ_16_SET_GET_I2C_WR1_RDN 16 - /* Subaddr, Slave Addr, 0, length */ -#define REQ_17_SET_GET_I2CFP 17 - /* Write: Slave Addr, register, value */ - /* Read : Slave Addr, register, 2, data */ -#define REQ_20_DATA_TRANSFER 20 -#define REQ_30_I2C_WRITE 30 -#define REQ_31_I2C_READ 31 -#define REQ_35_AFTEK_TUNER_READ 35 -#define REQ_40_GET_VERSION 40 -#define REQ_50_SET_START 50 -#define REQ_51_SET_STOP 51 -#define REQ_52_TRANSMIT_DATA 52 -#define REQ_53_SPI_INITIAL 53 -#define REQ_54_SPI_SETSTART 54 -#define REQ_55_SPI_INOUTDATA 55 -#define REQ_56_SPI_SETSTOP 56 - -/* - * Define TV Master TM5600/TM6000/TM6010 GPIO lines - */ - -#define TM6000_GPIO_CLK 0x101 -#define TM6000_GPIO_DATA 0x100 - -#define TM6000_GPIO_1 0x102 -#define TM6000_GPIO_2 0x103 -#define TM6000_GPIO_3 0x104 -#define TM6000_GPIO_4 0x300 -#define TM6000_GPIO_5 0x301 -#define TM6000_GPIO_6 0x304 -#define TM6000_GPIO_7 0x305 - -/* tm6010 defines GPIO with different values */ -#define TM6010_GPIO_0 0x0102 -#define TM6010_GPIO_1 0x0103 -#define TM6010_GPIO_2 0x0104 -#define TM6010_GPIO_3 0x0105 -#define TM6010_GPIO_4 0x0106 -#define TM6010_GPIO_5 0x0107 -#define TM6010_GPIO_6 0x0300 -#define TM6010_GPIO_7 0x0301 -#define TM6010_GPIO_9 0x0305 -/* - * Define TV Master TM5600/TM6000/TM6010 URB message codes and length - */ - -enum { - TM6000_URB_MSG_VIDEO=1, - TM6000_URB_MSG_AUDIO, - TM6000_URB_MSG_VBI, - TM6000_URB_MSG_PTS, - TM6000_URB_MSG_ERR, -}; - -/* Define specific TM6000 Video decoder registers */ -#define TM6000_REQ07_RD8_TEST_SEL 0x07, 0xd8 -#define TM6000_REQ07_RD9_A_SIM_SEL 0x07, 0xd9 -#define TM6000_REQ07_RDA_CLK_SEL 0x07, 0xda -#define TM6000_REQ07_RDB_OUT_SEL 0x07, 0xdb -#define TM6000_REQ07_RDC_NSEL_I2S 0x07, 0xdc -#define TM6000_REQ07_RDD_GPIO2_MDRV 0x07, 0xdd -#define TM6000_REQ07_RDE_GPIO1_MDRV 0x07, 0xde -#define TM6000_REQ07_RDF_PWDOWN_ACLK 0x07, 0xdf -#define TM6000_REQ07_RE0_VADC_REF_CTL 0x07, 0xe0 -#define TM6000_REQ07_RE1_VADC_DACLIMP 0x07, 0xe1 -#define TM6000_REQ07_RE2_VADC_STATUS_CTL 0x07, 0xe2 -#define TM6000_REQ07_RE3_VADC_INP_LPF_SEL1 0x07, 0xe3 -#define TM6000_REQ07_RE4_VADC_TARGET1 0x07, 0xe4 -#define TM6000_REQ07_RE5_VADC_INP_LPF_SEL2 0x07, 0xe5 -#define TM6000_REQ07_RE6_VADC_TARGET2 0x07, 0xe6 -#define TM6000_REQ07_RE7_VADC_AGAIN_CTL 0x07, 0xe7 -#define TM6000_REQ07_RE8_VADC_PWDOWN_CTL 0x07, 0xe8 -#define TM6000_REQ07_RE9_VADC_INPUT_CTL1 0x07, 0xe9 -#define TM6000_REQ07_REA_VADC_INPUT_CTL2 0x07, 0xea -#define TM6000_REQ07_REB_VADC_AADC_MODE 0x07, 0xeb -#define TM6000_REQ07_REC_VADC_AADC_LVOL 0x07, 0xec -#define TM6000_REQ07_RED_VADC_AADC_RVOL 0x07, 0xed -#define TM6000_REQ07_REE_VADC_CTRL_SEL_CONTROL 0x07, 0xee -#define TM6000_REQ07_REF_VADC_GAIN_MAP_CTL 0x07, 0xef -#define TM6000_REQ07_RFD_BIST_ERR_VST_LOW 0x07, 0xfd -#define TM6000_REQ07_RFE_BIST_ERR_VST_HIGH 0x07, 0xfe - -/* Define TM6000/TM6010 Video decoder registers */ -#define TM6010_REQ07_R00_VIDEO_CONTROL0 0x07, 0x00 -#define TM6010_REQ07_R01_VIDEO_CONTROL1 0x07, 0x01 -#define TM6010_REQ07_R02_VIDEO_CONTROL2 0x07, 0x02 -#define TM6010_REQ07_R03_YC_SEP_CONTROL 0x07, 0x03 -#define TM6010_REQ07_R04_LUMA_HAGC_CONTROL 0x07, 0x04 -#define TM6010_REQ07_R05_NOISE_THRESHOLD 0x07, 0x05 -#define TM6010_REQ07_R06_AGC_GATE_THRESHOLD 0x07, 0x06 -#define TM6010_REQ07_R07_OUTPUT_CONTROL 0x07, 0x07 -#define TM6010_REQ07_R08_LUMA_CONTRAST_ADJ 0x07, 0x08 -#define TM6010_REQ07_R09_LUMA_BRIGHTNESS_ADJ 0x07, 0x09 -#define TM6010_REQ07_R0A_CHROMA_SATURATION_ADJ 0x07, 0x0a -#define TM6010_REQ07_R0B_CHROMA_HUE_PHASE_ADJ 0x07, 0x0b -#define TM6010_REQ07_R0C_CHROMA_AGC_CONTROL 0x07, 0x0c -#define TM6010_REQ07_R0D_CHROMA_KILL_LEVEL 0x07, 0x0d -#define TM6010_REQ07_R0F_CHROMA_AUTO_POSITION 0x07, 0x0f -#define TM6010_REQ07_R10_AGC_PEAK_NOMINAL 0x07, 0x10 -#define TM6010_REQ07_R11_AGC_PEAK_CONTROL 0x07, 0x11 -#define TM6010_REQ07_R12_AGC_GATE_STARTH 0x07, 0x12 -#define TM6010_REQ07_R13_AGC_GATE_STARTL 0x07, 0x13 -#define TM6010_REQ07_R14_AGC_GATE_WIDTH 0x07, 0x14 -#define TM6010_REQ07_R15_AGC_BP_DELAY 0x07, 0x15 -#define TM6010_REQ07_R16_LOCK_COUNT 0x07, 0x16 -#define TM6010_REQ07_R17_HLOOP_MAXSTATE 0x07, 0x17 -#define TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3 0x07, 0x18 -#define TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2 0x07, 0x19 -#define TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1 0x07, 0x1a -#define TM6010_REQ07_R1B_CHROMA_DTO_INCREMENT0 0x07, 0x1b -#define TM6010_REQ07_R1C_HSYNC_DTO_INCREMENT3 0x07, 0x1c -#define TM6010_REQ07_R1D_HSYNC_DTO_INCREMENT2 0x07, 0x1d -#define TM6010_REQ07_R1E_HSYNC_DTO_INCREMENT1 0x07, 0x1e -#define TM6010_REQ07_R1F_HSYNC_DTO_INCREMENT0 0x07, 0x1f -#define TM6010_REQ07_R20_HSYNC_RISING_EDGE_TIME 0x07, 0x20 -#define TM6010_REQ07_R21_HSYNC_PHASE_OFFSET 0x07, 0x21 -#define TM6010_REQ07_R22_HSYNC_PLL_START_TIME 0x07, 0x22 -#define TM6010_REQ07_R23_HSYNC_PLL_END_TIME 0x07, 0x23 -#define TM6010_REQ07_R24_HSYNC_TIP_START_TIME 0x07, 0x24 -#define TM6010_REQ07_R25_HSYNC_TIP_END_TIME 0x07, 0x25 -#define TM6010_REQ07_R26_HSYNC_RISING_EDGE_START 0x07, 0x26 -#define TM6010_REQ07_R27_HSYNC_RISING_EDGE_END 0x07, 0x27 -#define TM6010_REQ07_R28_BACKPORCH_START 0x07, 0x28 -#define TM6010_REQ07_R29_BACKPORCH_END 0x07, 0x29 -#define TM6010_REQ07_R2A_HSYNC_FILTER_START 0x07, 0x2a -#define TM6010_REQ07_R2B_HSYNC_FILTER_END 0x07, 0x2b -#define TM6010_REQ07_R2C_CHROMA_BURST_START 0x07, 0x2c -#define TM6010_REQ07_R2D_CHROMA_BURST_END 0x07, 0x2d -#define TM6010_REQ07_R2E_ACTIVE_VIDEO_HSTART 0x07, 0x2e -#define TM6010_REQ07_R2F_ACTIVE_VIDEO_HWIDTH 0x07, 0x2f -#define TM6010_REQ07_R30_ACTIVE_VIDEO_VSTART 0x07, 0x30 -#define TM6010_REQ07_R31_ACTIVE_VIDEO_VHIGHT 0x07, 0x31 -#define TM6010_REQ07_R32_VSYNC_HLOCK_MIN 0x07, 0x32 -#define TM6010_REQ07_R33_VSYNC_HLOCK_MAX 0x07, 0x33 -#define TM6010_REQ07_R34_VSYNC_AGC_MIN 0x07, 0x34 -#define TM6010_REQ07_R35_VSYNC_AGC_MAX 0x07, 0x35 -#define TM6010_REQ07_R36_VSYNC_VBI_MIN 0x07, 0x36 -#define TM6010_REQ07_R37_VSYNC_VBI_MAX 0x07, 0x37 -#define TM6010_REQ07_R38_VSYNC_THRESHOLD 0x07, 0x38 -#define TM6010_REQ07_R39_VSYNC_TIME_CONSTANT 0x07, 0x39 -#define TM6010_REQ07_R3A_STATUS1 0x07, 0x3a -#define TM6010_REQ07_R3B_STATUS2 0x07, 0x3b -#define TM6010_REQ07_R3C_STATUS3 0x07, 0x3c -#define TM6010_REQ07_R3F_RESET 0x07, 0x3f -#define TM6010_REQ07_R40_TELETEXT_VBI_CODE0 0x07, 0x40 -#define TM6010_REQ07_R41_TELETEXT_VBI_CODE1 0x07, 0x41 -#define TM6010_REQ07_R42_VBI_DATA_HIGH_LEVEL 0x07, 0x42 -#define TM6010_REQ07_R43_VBI_DATA_TYPE_LINE7 0x07, 0x43 -#define TM6010_REQ07_R44_VBI_DATA_TYPE_LINE8 0x07, 0x44 -#define TM6010_REQ07_R45_VBI_DATA_TYPE_LINE9 0x07, 0x45 -#define TM6010_REQ07_R46_VBI_DATA_TYPE_LINE10 0x07, 0x46 -#define TM6010_REQ07_R47_VBI_DATA_TYPE_LINE11 0x07, 0x47 -#define TM6010_REQ07_R48_VBI_DATA_TYPE_LINE12 0x07, 0x48 -#define TM6010_REQ07_R49_VBI_DATA_TYPE_LINE13 0x07, 0x49 -#define TM6010_REQ07_R4A_VBI_DATA_TYPE_LINE14 0x07, 0x4a -#define TM6010_REQ07_R4B_VBI_DATA_TYPE_LINE15 0x07, 0x4b -#define TM6010_REQ07_R4C_VBI_DATA_TYPE_LINE16 0x07, 0x4c -#define TM6010_REQ07_R4D_VBI_DATA_TYPE_LINE17 0x07, 0x4d -#define TM6010_REQ07_R4E_VBI_DATA_TYPE_LINE18 0x07, 0x4e -#define TM6010_REQ07_R4F_VBI_DATA_TYPE_LINE19 0x07, 0x4f -#define TM6010_REQ07_R50_VBI_DATA_TYPE_LINE20 0x07, 0x50 -#define TM6010_REQ07_R51_VBI_DATA_TYPE_LINE21 0x07, 0x51 -#define TM6010_REQ07_R52_VBI_DATA_TYPE_LINE22 0x07, 0x52 -#define TM6010_REQ07_R53_VBI_DATA_TYPE_LINE23 0x07, 0x53 -#define TM6010_REQ07_R54_VBI_DATA_TYPE_RLINES 0x07, 0x54 -#define TM6010_REQ07_R55_VBI_LOOP_FILTER_GAIN 0x07, 0x55 -#define TM6010_REQ07_R56_VBI_LOOP_FILTER_I_GAIN 0x07, 0x56 -#define TM6010_REQ07_R57_VBI_LOOP_FILTER_P_GAIN 0x07, 0x57 -#define TM6010_REQ07_R58_VBI_CAPTION_DTO1 0x07, 0x58 -#define TM6010_REQ07_R59_VBI_CAPTION_DTO0 0x07, 0x59 -#define TM6010_REQ07_R5A_VBI_TELETEXT_DTO1 0x07, 0x5a -#define TM6010_REQ07_R5B_VBI_TELETEXT_DTO0 0x07, 0x5b -#define TM6010_REQ07_R5C_VBI_WSS625_DTO1 0x07, 0x5c -#define TM6010_REQ07_R5D_VBI_WSS625_DTO0 0x07, 0x5d -#define TM6010_REQ07_R5E_VBI_CAPTION_FRAME_START 0x07, 0x5e -#define TM6010_REQ07_R5F_VBI_WSS625_FRAME_START 0x07, 0x5f -#define TM6010_REQ07_R60_TELETEXT_FRAME_START 0x07, 0x60 -#define TM6010_REQ07_R61_VBI_CCDATA1 0x07, 0x61 -#define TM6010_REQ07_R62_VBI_CCDATA2 0x07, 0x62 -#define TM6010_REQ07_R63_VBI_WSS625_DATA1 0x07, 0x63 -#define TM6010_REQ07_R64_VBI_WSS625_DATA2 0x07, 0x64 -#define TM6010_REQ07_R65_VBI_DATA_STATUS 0x07, 0x65 -#define TM6010_REQ07_R66_VBI_CAPTION_START 0x07, 0x66 -#define TM6010_REQ07_R67_VBI_WSS625_START 0x07, 0x67 -#define TM6010_REQ07_R68_VBI_TELETEXT_START 0x07, 0x68 -#define TM6010_REQ07_R70_HSYNC_DTO_INC_STATUS3 0x07, 0x70 -#define TM6010_REQ07_R71_HSYNC_DTO_INC_STATUS2 0x07, 0x71 -#define TM6010_REQ07_R72_HSYNC_DTO_INC_STATUS1 0x07, 0x72 -#define TM6010_REQ07_R73_HSYNC_DTO_INC_STATUS0 0x07, 0x73 -#define TM6010_REQ07_R74_CHROMA_DTO_INC_STATUS3 0x07, 0x74 -#define TM6010_REQ07_R75_CHROMA_DTO_INC_STATUS2 0x07, 0x75 -#define TM6010_REQ07_R76_CHROMA_DTO_INC_STATUS1 0x07, 0x76 -#define TM6010_REQ07_R77_CHROMA_DTO_INC_STATUS0 0x07, 0x77 -#define TM6010_REQ07_R78_AGC_AGAIN_STATUS 0x07, 0x78 -#define TM6010_REQ07_R79_AGC_DGAIN_STATUS 0x07, 0x79 -#define TM6010_REQ07_R7A_CHROMA_MAG_STATUS 0x07, 0x7a -#define TM6010_REQ07_R7B_CHROMA_GAIN_STATUS1 0x07, 0x7b -#define TM6010_REQ07_R7C_CHROMA_GAIN_STATUS0 0x07, 0x7c -#define TM6010_REQ07_R7D_CORDIC_FREQ_STATUS 0x07, 0x7d -#define TM6010_REQ07_R7F_STATUS_NOISE 0x07, 0x7f -#define TM6010_REQ07_R80_COMB_FILTER_TRESHOLD 0x07, 0x80 -#define TM6010_REQ07_R82_COMB_FILTER_CONFIG 0x07, 0x82 -#define TM6010_REQ07_R83_CHROMA_LOCK_CONFIG 0x07, 0x83 -#define TM6010_REQ07_R84_NOISE_NTSC_C 0x07, 0x84 -#define TM6010_REQ07_R85_NOISE_PAL_C 0x07, 0x85 -#define TM6010_REQ07_R86_NOISE_PHASE_C 0x07, 0x86 -#define TM6010_REQ07_R87_NOISE_PHASE_Y 0x07, 0x87 -#define TM6010_REQ07_R8A_CHROMA_LOOPFILTER_STATE 0x07, 0x8a -#define TM6010_REQ07_R8B_CHROMA_HRESAMPLER 0x07, 0x8b -#define TM6010_REQ07_R8D_CPUMP_DELAY_ADJ 0x07, 0x8d -#define TM6010_REQ07_R8E_CPUMP_ADJ 0x07, 0x8e -#define TM6010_REQ07_R8F_CPUMP_DELAY 0x07, 0x8f - -/* Define TM6000/TM6010 Miscellaneous registers */ -#define TM6010_REQ07_RC0_ACTIVE_VIDEO_SOURCE 0x07, 0xc0 -#define TM6010_REQ07_RC1_TRESHOLD 0x07, 0xc1 -#define TM6010_REQ07_RC2_HSYNC_WIDTH 0x07, 0xc2 -#define TM6010_REQ07_RC3_HSTART1 0x07, 0xc3 -#define TM6010_REQ07_RC4_HSTART0 0x07, 0xc4 -#define TM6010_REQ07_RC5_HEND1 0x07, 0xc5 -#define TM6010_REQ07_RC6_HEND0 0x07, 0xc6 -#define TM6010_REQ07_RC7_VSTART1 0x07, 0xc7 -#define TM6010_REQ07_RC8_VSTART0 0x07, 0xc8 -#define TM6010_REQ07_RC9_VEND1 0x07, 0xc9 -#define TM6010_REQ07_RCA_VEND0 0x07, 0xca -#define TM6010_REQ07_RCB_DELAY 0x07, 0xcb -/* ONLY for TM6010 */ -#define TM6010_REQ07_RCC_ACTIVE_VIDEO_IF 0x07, 0xcc -#define TM6010_REQ07_RD0_USB_PERIPHERY_CONTROL 0x07, 0xd0 -#define TM6010_REQ07_RD1_ADDR_FOR_REQ1 0x07, 0xd1 -#define TM6010_REQ07_RD2_ADDR_FOR_REQ2 0x07, 0xd2 -#define TM6010_REQ07_RD3_ADDR_FOR_REQ3 0x07, 0xd3 -#define TM6010_REQ07_RD4_ADDR_FOR_REQ4 0x07, 0xd4 -#define TM6010_REQ07_RD5_POWERSAVE 0x07, 0xd5 -#define TM6010_REQ07_RD6_ENDP_REQ1_REQ2 0x07, 0xd6 -#define TM6010_REQ07_RD7_ENDP_REQ3_REQ4 0x07, 0xd7 -/* ONLY for TM6010 */ -#define TM6010_REQ07_RD8_IR 0x07, 0xd8 -/* ONLY for TM6010 */ -#define TM6010_REQ07_RD8_IR_BSIZE 0x07, 0xd9 -/* ONLY for TM6010 */ -#define TM6010_REQ07_RD8_IR_WAKEUP_SEL 0x07, 0xda -/* ONLY for TM6010 */ -#define TM6010_REQ07_RD8_IR_WAKEUP_ADD 0x07, 0xdb -/* ONLY for TM6010 */ -#define TM6010_REQ07_RD8_IR_LEADER1 0x07, 0xdc -/* ONLY for TM6010 */ -#define TM6010_REQ07_RD8_IR_LEADER0 0x07, 0xdd -/* ONLY for TM6010 */ -#define TM6010_REQ07_RD8_IR_PULSE_CNT1 0x07, 0xde -/* ONLY for TM6010 */ -#define TM6010_REQ07_RD8_IR_PULSE_CNT0 0x07, 0xdf -/* ONLY for TM6010 */ -#define TM6010_REQ07_RE0_DVIDEO_SOURCE 0x07, 0xe0 -/* ONLY for TM6010 */ -#define TM6010_REQ07_RE0_DVIDEO_SOURCE_IF 0x07, 0xe1 -/* ONLY for TM6010 */ -#define TM6010_REQ07_RE2_OUT_SEL2 0x07, 0xe2 -/* ONLY for TM6010 */ -#define TM6010_REQ07_RE3_OUT_SEL1 0x07, 0xe3 -/* ONLY for TM6010 */ -#define TM6010_REQ07_RE4_OUT_SEL0 0x07, 0xe4 -/* ONLY for TM6010 */ -#define TM6010_REQ07_RE5_REMOTE_WAKEUP 0x07, 0xe5 -/* ONLY for TM6010 */ -#define TM6010_REQ07_RE7_PUB_GPIO 0x07, 0xe7 -/* ONLY for TM6010 */ -#define TM6010_REQ07_RE8_TYPESEL_MOS_I2S 0x07, 0xe8 -/* ONLY for TM6010 */ -#define TM6010_REQ07_RE9_TYPESEL_MOS_TS 0x07, 0xe9 -/* ONLY for TM6010 */ -#define TM6010_REQ07_REA_TYPESEL_MOS_CCIR 0x07, 0xea -/* ONLY for TM6010 */ -#define TM6010_REQ07_RF0_BIST_CRC_RESULT0 0x07, 0xf0 -/* ONLY for TM6010 */ -#define TM6010_REQ07_RF1_BIST_CRC_RESULT1 0x07, 0xf1 -/* ONLY for TM6010 */ -#define TM6010_REQ07_RF2_BIST_CRC_RESULT2 0x07, 0xf2 -/* ONLY for TM6010 */ -#define TM6010_REQ07_RF3_BIST_CRC_RESULT3 0x07, 0xf3 -/* ONLY for TM6010 */ -#define TM6010_REQ07_RF4_BIST_ERR_VST2 0x07, 0xf4 -/* ONLY for TM6010 */ -#define TM6010_REQ07_RF5_BIST_ERR_VST1 0x07, 0xf5 -/* ONLY for TM6010 */ -#define TM6010_REQ07_RF6_BIST_ERR_VST0 0x07, 0xf6 -/* ONLY for TM6010 */ -#define TM6010_REQ07_RF7_BIST 0x07, 0xf7 -/* ONLY for TM6010 */ -#define TM6010_REQ07_RFE_POWER_DOWN 0x07, 0xfe -#define TM6010_REQ07_RFF_SOFT_RESET 0x07, 0xff - -/* Define TM6000/TM6010 USB registers */ -#define TM6010_REQ05_R00_MAIN_CTRL 0x05, 0x00 -#define TM6010_REQ05_R01_DEVADDR 0x05, 0x01 -#define TM6010_REQ05_R02_TEST 0x05, 0x02 -#define TM6010_REQ05_R04_SOFN0 0x05, 0x04 -#define TM6010_REQ05_R05_SOFN1 0x05, 0x05 -#define TM6010_REQ05_R06_SOFTM0 0x05, 0x06 -#define TM6010_REQ05_R07_SOFTM1 0x05, 0x07 -#define TM6010_REQ05_R08_PHY_TEST 0x05, 0x08 -#define TM6010_REQ05_R09_VCTL 0x05, 0x09 -#define TM6010_REQ05_R0A_VSTA 0x05, 0x0a -#define TM6010_REQ05_R0B_CX_CFG 0x05, 0x0b -#define TM6010_REQ05_R0C_ENDP0_REG0 0x05, 0x0c -#define TM6010_REQ05_R10_GMASK 0x05, 0x10 -#define TM6010_REQ05_R11_IMASK0 0x05, 0x11 -#define TM6010_REQ05_R12_IMASK1 0x05, 0x12 -#define TM6010_REQ05_R13_IMASK2 0x05, 0x13 -#define TM6010_REQ05_R14_IMASK3 0x05, 0x14 -#define TM6010_REQ05_R15_IMASK4 0x05, 0x15 -#define TM6010_REQ05_R16_IMASK5 0x05, 0x16 -#define TM6010_REQ05_R17_IMASK6 0x05, 0x17 -#define TM6010_REQ05_R18_IMASK7 0x05, 0x18 -#define TM6010_REQ05_R19_ZEROP0 0x05, 0x19 -#define TM6010_REQ05_R1A_ZEROP1 0x05, 0x1a -#define TM6010_REQ05_R1C_FIFO_EMP0 0x05, 0x1c -#define TM6010_REQ05_R1D_FIFO_EMP1 0x05, 0x1d -#define TM6010_REQ05_R20_IRQ_GROUP 0x05, 0x20 -#define TM6010_REQ05_R21_IRQ_SOURCE0 0x05, 0x21 -#define TM6010_REQ05_R22_IRQ_SOURCE1 0x05, 0x22 -#define TM6010_REQ05_R23_IRQ_SOURCE2 0x05, 0x23 -#define TM6010_REQ05_R24_IRQ_SOURCE3 0x05, 0x24 -#define TM6010_REQ05_R25_IRQ_SOURCE4 0x05, 0x25 -#define TM6010_REQ05_R26_IRQ_SOURCE5 0x05, 0x26 -#define TM6010_REQ05_R27_IRQ_SOURCE6 0x05, 0x27 -#define TM6010_REQ05_R28_IRQ_SOURCE7 0x05, 0x28 -#define TM6010_REQ05_R29_SEQ_ERR0 0x05, 0x29 -#define TM6010_REQ05_R2A_SEQ_ERR1 0x05, 0x2a -#define TM6010_REQ05_R2B_SEQ_ABORT0 0x05, 0x2b -#define TM6010_REQ05_R2C_SEQ_ABORT1 0x05, 0x2c -#define TM6010_REQ05_R2D_TX_ZERO0 0x05, 0x2d -#define TM6010_REQ05_R2E_TX_ZERO1 0x05, 0x2e -#define TM6010_REQ05_R2F_IDLE_CNT 0x05, 0x2f -#define TM6010_REQ05_R30_FNO_P1 0x05, 0x30 -#define TM6010_REQ05_R31_FNO_P2 0x05, 0x31 -#define TM6010_REQ05_R32_FNO_P3 0x05, 0x32 -#define TM6010_REQ05_R33_FNO_P4 0x05, 0x33 -#define TM6010_REQ05_R34_FNO_P5 0x05, 0x34 -#define TM6010_REQ05_R35_FNO_P6 0x05, 0x35 -#define TM6010_REQ05_R36_FNO_P7 0x05, 0x36 -#define TM6010_REQ05_R37_FNO_P8 0x05, 0x37 -#define TM6010_REQ05_R38_FNO_P9 0x05, 0x38 -#define TM6010_REQ05_R30_FNO_P10 0x05, 0x39 -#define TM6010_REQ05_R30_FNO_P11 0x05, 0x3a -#define TM6010_REQ05_R30_FNO_P12 0x05, 0x3b -#define TM6010_REQ05_R30_FNO_P13 0x05, 0x3c -#define TM6010_REQ05_R30_FNO_P14 0x05, 0x3d -#define TM6010_REQ05_R30_FNO_P15 0x05, 0x3e -#define TM6010_REQ05_R40_IN_MAXPS_LOW1 0x05, 0x40 -#define TM6010_REQ05_R41_IN_MAXPS_HIGH1 0x05, 0x41 -#define TM6010_REQ05_R42_IN_MAXPS_LOW2 0x05, 0x42 -#define TM6010_REQ05_R43_IN_MAXPS_HIGH2 0x05, 0x43 -#define TM6010_REQ05_R44_IN_MAXPS_LOW3 0x05, 0x44 -#define TM6010_REQ05_R45_IN_MAXPS_HIGH3 0x05, 0x45 -#define TM6010_REQ05_R46_IN_MAXPS_LOW4 0x05, 0x46 -#define TM6010_REQ05_R47_IN_MAXPS_HIGH4 0x05, 0x47 -#define TM6010_REQ05_R48_IN_MAXPS_LOW5 0x05, 0x48 -#define TM6010_REQ05_R49_IN_MAXPS_HIGH5 0x05, 0x49 -#define TM6010_REQ05_R4A_IN_MAXPS_LOW6 0x05, 0x4a -#define TM6010_REQ05_R4B_IN_MAXPS_HIGH6 0x05, 0x4b -#define TM6010_REQ05_R4C_IN_MAXPS_LOW7 0x05, 0x4c -#define TM6010_REQ05_R4D_IN_MAXPS_HIGH7 0x05, 0x4d -#define TM6010_REQ05_R4E_IN_MAXPS_LOW8 0x05, 0x4e -#define TM6010_REQ05_R4F_IN_MAXPS_HIGH8 0x05, 0x4f -#define TM6010_REQ05_R50_IN_MAXPS_LOW9 0x05, 0x50 -#define TM6010_REQ05_R51_IN_MAXPS_HIGH9 0x05, 0x51 -#define TM6010_REQ05_R40_IN_MAXPS_LOW10 0x05, 0x52 -#define TM6010_REQ05_R41_IN_MAXPS_HIGH10 0x05, 0x53 -#define TM6010_REQ05_R40_IN_MAXPS_LOW11 0x05, 0x54 -#define TM6010_REQ05_R41_IN_MAXPS_HIGH11 0x05, 0x55 -#define TM6010_REQ05_R40_IN_MAXPS_LOW12 0x05, 0x56 -#define TM6010_REQ05_R41_IN_MAXPS_HIGH12 0x05, 0x57 -#define TM6010_REQ05_R40_IN_MAXPS_LOW13 0x05, 0x58 -#define TM6010_REQ05_R41_IN_MAXPS_HIGH13 0x05, 0x59 -#define TM6010_REQ05_R40_IN_MAXPS_LOW14 0x05, 0x5a -#define TM6010_REQ05_R41_IN_MAXPS_HIGH14 0x05, 0x5b -#define TM6010_REQ05_R40_IN_MAXPS_LOW15 0x05, 0x5c -#define TM6010_REQ05_R41_IN_MAXPS_HIGH15 0x05, 0x5d -#define TM6010_REQ05_R60_OUT_MAXPS_LOW1 0x05, 0x60 -#define TM6010_REQ05_R61_OUT_MAXPS_HIGH1 0x05, 0x61 -#define TM6010_REQ05_R62_OUT_MAXPS_LOW2 0x05, 0x62 -#define TM6010_REQ05_R63_OUT_MAXPS_HIGH2 0x05, 0x63 -#define TM6010_REQ05_R64_OUT_MAXPS_LOW3 0x05, 0x64 -#define TM6010_REQ05_R65_OUT_MAXPS_HIGH3 0x05, 0x65 -#define TM6010_REQ05_R66_OUT_MAXPS_LOW4 0x05, 0x66 -#define TM6010_REQ05_R67_OUT_MAXPS_HIGH4 0x05, 0x67 -#define TM6010_REQ05_R68_OUT_MAXPS_LOW5 0x05, 0x68 -#define TM6010_REQ05_R69_OUT_MAXPS_HIGH5 0x05, 0x69 -#define TM6010_REQ05_R6A_OUT_MAXPS_LOW6 0x05, 0x6a -#define TM6010_REQ05_R6B_OUT_MAXPS_HIGH6 0x05, 0x6b -#define TM6010_REQ05_R6C_OUT_MAXPS_LOW7 0x05, 0x6c -#define TM6010_REQ05_R6D_OUT_MAXPS_HIGH7 0x05, 0x6d -#define TM6010_REQ05_R6E_OUT_MAXPS_LOW8 0x05, 0x6e -#define TM6010_REQ05_R6F_OUT_MAXPS_HIGH8 0x05, 0x6f -#define TM6010_REQ05_R70_OUT_MAXPS_LOW9 0x05, 0x70 -#define TM6010_REQ05_R71_OUT_MAXPS_HIGH9 0x05, 0x71 -#define TM6010_REQ05_R60_OUT_MAXPS_LOW10 0x05, 0x72 -#define TM6010_REQ05_R61_OUT_MAXPS_HIGH10 0x05, 0x73 -#define TM6010_REQ05_R60_OUT_MAXPS_LOW11 0x05, 0x74 -#define TM6010_REQ05_R61_OUT_MAXPS_HIGH11 0x05, 0x75 -#define TM6010_REQ05_R60_OUT_MAXPS_LOW12 0x05, 0x76 -#define TM6010_REQ05_R61_OUT_MAXPS_HIGH12 0x05, 0x77 -#define TM6010_REQ05_R60_OUT_MAXPS_LOW13 0x05, 0x78 -#define TM6010_REQ05_R61_OUT_MAXPS_HIGH13 0x05, 0x79 -#define TM6010_REQ05_R60_OUT_MAXPS_LOW14 0x05, 0x7a -#define TM6010_REQ05_R61_OUT_MAXPS_HIGH14 0x05, 0x7b -#define TM6010_REQ05_R60_OUT_MAXPS_LOW15 0x05, 0x7c -#define TM6010_REQ05_R61_OUT_MAXPS_HIGH15 0x05, 0x7d -#define TM6010_REQ05_R80_FIFO0 0x05, 0x80 -#define TM6010_REQ05_R81_FIFO1 0x05, 0x81 -#define TM6010_REQ05_R82_FIFO2 0x05, 0x82 -#define TM6010_REQ05_R83_FIFO3 0x05, 0x83 -#define TM6010_REQ05_R84_FIFO4 0x05, 0x84 -#define TM6010_REQ05_R85_FIFO5 0x05, 0x85 -#define TM6010_REQ05_R86_FIFO6 0x05, 0x86 -#define TM6010_REQ05_R87_FIFO7 0x05, 0x87 -#define TM6010_REQ05_R88_FIFO8 0x05, 0x88 -#define TM6010_REQ05_R89_FIFO9 0x05, 0x89 -#define TM6010_REQ05_R81_FIFO10 0x05, 0x8a -#define TM6010_REQ05_R81_FIFO11 0x05, 0x8b -#define TM6010_REQ05_R81_FIFO12 0x05, 0x8c -#define TM6010_REQ05_R81_FIFO13 0x05, 0x8d -#define TM6010_REQ05_R81_FIFO14 0x05, 0x8e -#define TM6010_REQ05_R81_FIFO15 0x05, 0x8f -#define TM6010_REQ05_R90_CFG_FIFO0 0x05, 0x90 -#define TM6010_REQ05_R91_CFG_FIFO1 0x05, 0x91 -#define TM6010_REQ05_R92_CFG_FIFO2 0x05, 0x92 -#define TM6010_REQ05_R93_CFG_FIFO3 0x05, 0x93 -#define TM6010_REQ05_R94_CFG_FIFO4 0x05, 0x94 -#define TM6010_REQ05_R95_CFG_FIFO5 0x05, 0x95 -#define TM6010_REQ05_R96_CFG_FIFO6 0x05, 0x96 -#define TM6010_REQ05_R97_CFG_FIFO7 0x05, 0x97 -#define TM6010_REQ05_R98_CFG_FIFO8 0x05, 0x98 -#define TM6010_REQ05_R99_CFG_FIFO9 0x05, 0x99 -#define TM6010_REQ05_R91_CFG_FIFO10 0x05, 0x9a -#define TM6010_REQ05_R91_CFG_FIFO11 0x05, 0x9b -#define TM6010_REQ05_R91_CFG_FIFO12 0x05, 0x9c -#define TM6010_REQ05_R91_CFG_FIFO13 0x05, 0x9d -#define TM6010_REQ05_R91_CFG_FIFO14 0x05, 0x9e -#define TM6010_REQ05_R91_CFG_FIFO15 0x05, 0x9f -#define TM6010_REQ05_RA0_CTL_FIFO0 0x05, 0xa0 -#define TM6010_REQ05_RA1_CTL_FIFO1 0x05, 0xa1 -#define TM6010_REQ05_RA2_CTL_FIFO2 0x05, 0xa2 -#define TM6010_REQ05_RA3_CTL_FIFO3 0x05, 0xa3 -#define TM6010_REQ05_RA4_CTL_FIFO4 0x05, 0xa4 -#define TM6010_REQ05_RA5_CTL_FIFO5 0x05, 0xa5 -#define TM6010_REQ05_RA6_CTL_FIFO6 0x05, 0xa6 -#define TM6010_REQ05_RA7_CTL_FIFO7 0x05, 0xa7 -#define TM6010_REQ05_RA8_CTL_FIFO8 0x05, 0xa8 -#define TM6010_REQ05_RA9_CTL_FIFO9 0x05, 0xa9 -#define TM6010_REQ05_RA1_CTL_FIFO10 0x05, 0xaa -#define TM6010_REQ05_RA1_CTL_FIFO11 0x05, 0xab -#define TM6010_REQ05_RA1_CTL_FIFO12 0x05, 0xac -#define TM6010_REQ05_RA1_CTL_FIFO13 0x05, 0xad -#define TM6010_REQ05_RA1_CTL_FIFO14 0x05, 0xae -#define TM6010_REQ05_RA1_CTL_FIFO15 0x05, 0xaf -#define TM6010_REQ05_RB0_BC_LOW_FIFO0 0x05, 0xb0 -#define TM6010_REQ05_RB1_BC_LOW_FIFO1 0x05, 0xb1 -#define TM6010_REQ05_RB2_BC_LOW_FIFO2 0x05, 0xb2 -#define TM6010_REQ05_RB3_BC_LOW_FIFO3 0x05, 0xb3 -#define TM6010_REQ05_RB4_BC_LOW_FIFO4 0x05, 0xb4 -#define TM6010_REQ05_RB5_BC_LOW_FIFO5 0x05, 0xb5 -#define TM6010_REQ05_RB6_BC_LOW_FIFO6 0x05, 0xb6 -#define TM6010_REQ05_RB7_BC_LOW_FIFO7 0x05, 0xb7 -#define TM6010_REQ05_RB8_BC_LOW_FIFO8 0x05, 0xb8 -#define TM6010_REQ05_RB9_BC_LOW_FIFO9 0x05, 0xb9 -#define TM6010_REQ05_RB1_BC_LOW_FIFO10 0x05, 0xba -#define TM6010_REQ05_RB1_BC_LOW_FIFO11 0x05, 0xbb -#define TM6010_REQ05_RB1_BC_LOW_FIFO12 0x05, 0xbc -#define TM6010_REQ05_RB1_BC_LOW_FIFO13 0x05, 0xbd -#define TM6010_REQ05_RB1_BC_LOW_FIFO14 0x05, 0xbe -#define TM6010_REQ05_RB1_BC_LOW_FIFO15 0x05, 0xbf -#define TM6010_REQ05_RC0_DATA_FIFO0 0x05, 0xc0 -#define TM6010_REQ05_RC4_DATA_FIFO1 0x05, 0xc4 -#define TM6010_REQ05_RC8_DATA_FIFO2 0x05, 0xc8 -#define TM6010_REQ05_RCC_DATA_FIFO3 0x05, 0xcc -#define TM6010_REQ05_RD0_DATA_FIFO4 0x05, 0xd0 -#define TM6010_REQ05_RD4_DATA_FIFO5 0x05, 0xd4 -#define TM6010_REQ05_RD8_DATA_FIFO6 0x05, 0xd8 -#define TM6010_REQ05_RDC_DATA_FIFO7 0x05, 0xdc -#define TM6010_REQ05_RE0_DATA_FIFO8 0x05, 0xe0 -#define TM6010_REQ05_RE4_DATA_FIFO9 0x05, 0xe4 -#define TM6010_REQ05_RC4_DATA_FIFO10 0x05, 0xe8 -#define TM6010_REQ05_RC4_DATA_FIFO11 0x05, 0xec -#define TM6010_REQ05_RC4_DATA_FIFO12 0x05, 0xf0 -#define TM6010_REQ05_RC4_DATA_FIFO13 0x05, 0xf4 -#define TM6010_REQ05_RC4_DATA_FIFO14 0x05, 0xf8 -#define TM6010_REQ05_RC4_DATA_FIFO15 0x05, 0xfc - -/* Define TM6010 Audio decoder registers */ -/* This core available only in TM6010 */ -#define TM6010_REQ08_R00_A_VERSION 0x08, 0x00 -#define TM6010_REQ08_R01_A_INIT 0x08, 0x01 -#define TM6010_REQ08_R02_A_FIX_GAIN_CTRL 0x08, 0x02 -#define TM6010_REQ08_R03_A_AUTO_GAIN_CTRL 0x08, 0x03 -#define TM6010_REQ08_R04_A_SIF_AMP_CTRL 0x08, 0x04 -#define TM6010_REQ08_R05_A_STANDARD_MOD 0x08, 0x05 -#define TM6010_REQ08_R06_A_SOUND_MOD 0x08, 0x06 -#define TM6010_REQ08_R07_A_LEFT_VOL 0x08, 0x07 -#define TM6010_REQ08_R08_A_RIGHT_VOL 0x08, 0x08 -#define TM6010_REQ08_R09_A_MAIN_VOL 0x08, 0x09 -#define TM6010_REQ08_R0A_A_I2S_MOD 0x08, 0x0a -#define TM6010_REQ08_R0B_A_ASD_THRES1 0x08, 0x0b -#define TM6010_REQ08_R0C_A_ASD_THRES2 0x08, 0x0c -#define TM6010_REQ08_R0D_A_AMD_THRES 0x08, 0x0d -#define TM6010_REQ08_R0E_A_MONO_THRES1 0x08, 0x0e -#define TM6010_REQ08_R0F_A_MONO_THRES2 0x08, 0x0f -#define TM6010_REQ08_R10_A_MUTE_THRES1 0x08, 0x10 -#define TM6010_REQ08_R11_A_MUTE_THRES2 0x08, 0x11 -#define TM6010_REQ08_R12_A_AGC_U 0x08, 0x12 -#define TM6010_REQ08_R13_A_AGC_ERR_T 0x08, 0x13 -#define TM6010_REQ08_R14_A_AGC_GAIN_INIT 0x08, 0x14 -#define TM6010_REQ08_R15_A_AGC_STEP_THR 0x08, 0x15 -#define TM6010_REQ08_R16_A_AGC_GAIN_MAX 0x08, 0x16 -#define TM6010_REQ08_R17_A_AGC_GAIN_MIN 0x08, 0x17 -#define TM6010_REQ08_R18_A_TR_CTRL 0x08, 0x18 -#define TM6010_REQ08_R19_A_FH_2FH_GAIN 0x08, 0x19 -#define TM6010_REQ08_R1A_A_NICAM_SER_MAX 0x08, 0x1a -#define TM6010_REQ08_R1B_A_NICAM_SER_MIN 0x08, 0x1b -#define TM6010_REQ08_R1E_A_GAIN_DEEMPH_OUT 0x08, 0x1e -#define TM6010_REQ08_R1F_A_TEST_INTF_SEL 0x08, 0x1f -#define TM6010_REQ08_R20_A_TEST_PIN_SEL 0x08, 0x20 -#define TM6010_REQ08_R21_A_AGC_ERR 0x08, 0x21 -#define TM6010_REQ08_R22_A_AGC_GAIN 0x08, 0x22 -#define TM6010_REQ08_R23_A_NICAM_INFO 0x08, 0x23 -#define TM6010_REQ08_R24_A_SER 0x08, 0x24 -#define TM6010_REQ08_R25_A_C1_AMP 0x08, 0x25 -#define TM6010_REQ08_R26_A_C2_AMP 0x08, 0x26 -#define TM6010_REQ08_R27_A_NOISE_AMP 0x08, 0x27 -#define TM6010_REQ08_R28_A_AUDIO_MODE_RES 0x08, 0x28 - -/* Define TM6010 Video ADC registers */ -#define TM6010_REQ08_RE0_ADC_REF 0x08, 0xe0 -#define TM6010_REQ08_RE1_DAC_CLMP 0x08, 0xe1 -#define TM6010_REQ08_RE2_POWER_DOWN_CTRL1 0x08, 0xe2 -#define TM6010_REQ08_RE3_ADC_IN1_SEL 0x08, 0xe3 -#define TM6010_REQ08_RE4_ADC_IN2_SEL 0x08, 0xe4 -#define TM6010_REQ08_RE5_GAIN_PARAM 0x08, 0xe5 -#define TM6010_REQ08_RE6_POWER_DOWN_CTRL2 0x08, 0xe6 -#define TM6010_REQ08_RE7_REG_GAIN_Y 0x08, 0xe7 -#define TM6010_REQ08_RE8_REG_GAIN_C 0x08, 0xe8 -#define TM6010_REQ08_RE9_BIAS_CTRL 0x08, 0xe9 -#define TM6010_REQ08_REA_BUFF_DRV_CTRL 0x08, 0xea -#define TM6010_REQ08_REB_SIF_GAIN_CTRL 0x08, 0xeb -#define TM6010_REQ08_REC_REVERSE_YC_CTRL 0x08, 0xec -#define TM6010_REQ08_RED_GAIN_SEL 0x08, 0xed - -/* Define TM6010 Audio ADC registers */ -#define TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG 0x08, 0xf0 -#define TM6010_REQ08_RF1_AADC_POWER_DOWN 0x08, 0xf1 -#define TM6010_REQ08_RF2_LEFT_CHANNEL_VOL 0x08, 0xf2 -#define TM6010_REQ08_RF3_RIGHT_CHANNEL_VOL 0x08, 0xf3 diff --git a/drivers/staging/tm6000/tm6000-stds.c b/drivers/staging/tm6000/tm6000-stds.c deleted file mode 100644 index 8b29d732ddcb..000000000000 --- a/drivers/staging/tm6000/tm6000-stds.c +++ /dev/null @@ -1,679 +0,0 @@ -/* - * tm6000-stds.c - driver for TM5600/TM6000/TM6010 USB video capture devices - * - * Copyright (C) 2007 Mauro Carvalho Chehab <mchehab@redhat.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation version 2 - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include <linux/module.h> -#include <linux/kernel.h> -#include "tm6000.h" -#include "tm6000-regs.h" - -static unsigned int tm6010_a_mode = 0; -module_param(tm6010_a_mode, int, 0644); -MODULE_PARM_DESC(tm6010_a_mode, "set tm6010 sif audio mode"); - -struct tm6000_reg_settings { - unsigned char req; - unsigned char reg; - unsigned char value; -}; - - -struct tm6000_std_settings { - v4l2_std_id id; - struct tm6000_reg_settings common[27]; -}; - -static struct tm6000_std_settings composite_stds[] = { - { - .id = V4L2_STD_PAL_M, - .common = { - {TM6010_REQ07_R3F_RESET, 0x01}, - {TM6010_REQ07_R00_VIDEO_CONTROL0, 0x04}, - {TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0e}, - {TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f}, - {TM6010_REQ07_R03_YC_SEP_CONTROL, 0x00}, - {TM6010_REQ07_R07_OUTPUT_CONTROL, 0x31}, - {TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x1e}, - {TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0x83}, - {TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0x0a}, - {TM6010_REQ07_R1B_CHROMA_DTO_INCREMENT0, 0xe0}, - {TM6010_REQ07_R1C_HSYNC_DTO_INCREMENT3, 0x1c}, - {TM6010_REQ07_R1D_HSYNC_DTO_INCREMENT2, 0xcc}, - {TM6010_REQ07_R1E_HSYNC_DTO_INCREMENT1, 0xcc}, - {TM6010_REQ07_R1F_HSYNC_DTO_INCREMENT0, 0xcd}, - {TM6010_REQ07_R2E_ACTIVE_VIDEO_HSTART, 0x88}, - {TM6010_REQ07_R30_ACTIVE_VIDEO_VSTART, 0x20}, - {TM6010_REQ07_R31_ACTIVE_VIDEO_VHIGHT, 0x61}, - {TM6010_REQ07_R33_VSYNC_HLOCK_MAX, 0x0c}, - {TM6010_REQ07_R35_VSYNC_AGC_MAX, 0x1c}, - {TM6010_REQ07_R82_COMB_FILTER_CONFIG, 0x52}, - {TM6010_REQ07_R83_CHROMA_LOCK_CONFIG, 0x6F}, - - {TM6010_REQ07_R04_LUMA_HAGC_CONTROL, 0xdc}, - {TM6010_REQ07_R0D_CHROMA_KILL_LEVEL, 0x07}, - {TM6010_REQ07_R3F_RESET, 0x00}, - {0, 0, 0}, - }, - }, { - .id = V4L2_STD_PAL_Nc, - .common = { - {TM6010_REQ07_R3F_RESET, 0x01}, - {TM6010_REQ07_R00_VIDEO_CONTROL0, 0x36}, - {TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0e}, - {TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f}, - {TM6010_REQ07_R03_YC_SEP_CONTROL, 0x02}, - {TM6010_REQ07_R07_OUTPUT_CONTROL, 0x31}, - {TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x1e}, - {TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0x91}, - {TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0x1f}, - {TM6010_REQ07_R1B_CHROMA_DTO_INCREMENT0, 0x0c}, - {TM6010_REQ07_R1C_HSYNC_DTO_INCREMENT3, 0x1c}, - {TM6010_REQ07_R1D_HSYNC_DTO_INCREMENT2, 0xcc}, - {TM6010_REQ07_R1E_HSYNC_DTO_INCREMENT1, 0xcc}, - {TM6010_REQ07_R1F_HSYNC_DTO_INCREMENT0, 0xcd}, - {TM6010_REQ07_R2E_ACTIVE_VIDEO_HSTART, 0x8c}, - {TM6010_REQ07_R30_ACTIVE_VIDEO_VSTART, 0x2c}, - {TM6010_REQ07_R31_ACTIVE_VIDEO_VHIGHT, 0xc1}, - {TM6010_REQ07_R33_VSYNC_HLOCK_MAX, 0x0c}, - {TM6010_REQ07_R35_VSYNC_AGC_MAX, 0x1c}, - {TM6010_REQ07_R82_COMB_FILTER_CONFIG, 0x52}, - {TM6010_REQ07_R83_CHROMA_LOCK_CONFIG, 0x6F}, - - {TM6010_REQ07_R04_LUMA_HAGC_CONTROL, 0xdc}, - {TM6010_REQ07_R0D_CHROMA_KILL_LEVEL, 0x07}, - {TM6010_REQ07_R3F_RESET, 0x00}, - {0, 0, 0}, - }, - }, { - .id = V4L2_STD_PAL, - .common = { - {TM6010_REQ07_R3F_RESET, 0x01}, - {TM6010_REQ07_R00_VIDEO_CONTROL0, 0x32}, - {TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0e}, - {TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f}, - {TM6010_REQ07_R03_YC_SEP_CONTROL, 0x02}, - {TM6010_REQ07_R07_OUTPUT_CONTROL, 0x31}, - {TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x25}, - {TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0xd5}, - {TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0x63}, - {TM6010_REQ07_R1B_CHROMA_DTO_INCREMENT0, 0x50}, - {TM6010_REQ07_R1C_HSYNC_DTO_INCREMENT3, 0x1c}, - {TM6010_REQ07_R1D_HSYNC_DTO_INCREMENT2, 0xcc}, - {TM6010_REQ07_R1E_HSYNC_DTO_INCREMENT1, 0xcc}, - {TM6010_REQ07_R1F_HSYNC_DTO_INCREMENT0, 0xcd}, - {TM6010_REQ07_R2E_ACTIVE_VIDEO_HSTART, 0x8c}, - {TM6010_REQ07_R30_ACTIVE_VIDEO_VSTART, 0x2c}, - {TM6010_REQ07_R31_ACTIVE_VIDEO_VHIGHT, 0xc1}, - {TM6010_REQ07_R33_VSYNC_HLOCK_MAX, 0x0c}, - {TM6010_REQ07_R35_VSYNC_AGC_MAX, 0x1c}, - {TM6010_REQ07_R82_COMB_FILTER_CONFIG, 0x52}, - {TM6010_REQ07_R83_CHROMA_LOCK_CONFIG, 0x6F}, - - {TM6010_REQ07_R04_LUMA_HAGC_CONTROL, 0xdc}, - {TM6010_REQ07_R0D_CHROMA_KILL_LEVEL, 0x07}, - {TM6010_REQ07_R3F_RESET, 0x00}, - {0, 0, 0}, - }, - }, { - .id = V4L2_STD_SECAM, - .common = { - {TM6010_REQ07_R3F_RESET, 0x01}, - {TM6010_REQ07_R00_VIDEO_CONTROL0, 0x38}, - {TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0e}, - {TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f}, - {TM6010_REQ07_R03_YC_SEP_CONTROL, 0x02}, - {TM6010_REQ07_R07_OUTPUT_CONTROL, 0x31}, - {TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x24}, - {TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0x92}, - {TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0xe8}, - {TM6010_REQ07_R1B_CHROMA_DTO_INCREMENT0, 0xed}, - {TM6010_REQ07_R1C_HSYNC_DTO_INCREMENT3, 0x1c}, - {TM6010_REQ07_R1D_HSYNC_DTO_INCREMENT2, 0xcc}, - {TM6010_REQ07_R1E_HSYNC_DTO_INCREMENT1, 0xcc}, - {TM6010_REQ07_R1F_HSYNC_DTO_INCREMENT0, 0xcd}, - {TM6010_REQ07_R2E_ACTIVE_VIDEO_HSTART, 0x8c}, - {TM6010_REQ07_R30_ACTIVE_VIDEO_VSTART, 0x2c}, - {TM6010_REQ07_R31_ACTIVE_VIDEO_VHIGHT, 0xc1}, - {TM6010_REQ07_R33_VSYNC_HLOCK_MAX, 0x2c}, - {TM6010_REQ07_R35_VSYNC_AGC_MAX, 0x18}, - {TM6010_REQ07_R82_COMB_FILTER_CONFIG, 0x42}, - {TM6010_REQ07_R83_CHROMA_LOCK_CONFIG, 0xFF}, - - {TM6010_REQ07_R0D_CHROMA_KILL_LEVEL, 0x07}, - {TM6010_REQ07_R3F_RESET, 0x00}, - {0, 0, 0}, - }, - }, { - .id = V4L2_STD_NTSC, - .common = { - {TM6010_REQ07_R3F_RESET, 0x01}, - {TM6010_REQ07_R00_VIDEO_CONTROL0, 0x00}, - {TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0f}, - {TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f}, - {TM6010_REQ07_R03_YC_SEP_CONTROL, 0x00}, - {TM6010_REQ07_R07_OUTPUT_CONTROL, 0x31}, - {TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x1e}, - {TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0x8b}, - {TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0xa2}, - {TM6010_REQ07_R1B_CHROMA_DTO_INCREMENT0, 0xe9}, - {TM6010_REQ07_R1C_HSYNC_DTO_INCREMENT3, 0x1c}, - {TM6010_REQ07_R1D_HSYNC_DTO_INCREMENT2, 0xcc}, - {TM6010_REQ07_R1E_HSYNC_DTO_INCREMENT1, 0xcc}, - {TM6010_REQ07_R1F_HSYNC_DTO_INCREMENT0, 0xcd}, - {TM6010_REQ07_R2E_ACTIVE_VIDEO_HSTART, 0x88}, - {TM6010_REQ07_R30_ACTIVE_VIDEO_VSTART, 0x22}, - {TM6010_REQ07_R31_ACTIVE_VIDEO_VHIGHT, 0x61}, - {TM6010_REQ07_R33_VSYNC_HLOCK_MAX, 0x1c}, - {TM6010_REQ07_R35_VSYNC_AGC_MAX, 0x1c}, - {TM6010_REQ07_R82_COMB_FILTER_CONFIG, 0x42}, - {TM6010_REQ07_R83_CHROMA_LOCK_CONFIG, 0x6F}, - - {TM6010_REQ07_R04_LUMA_HAGC_CONTROL, 0xdd}, - {TM6010_REQ07_R0D_CHROMA_KILL_LEVEL, 0x07}, - {TM6010_REQ07_R3F_RESET, 0x00}, - {0, 0, 0}, - }, - }, -}; - -static struct tm6000_std_settings svideo_stds[] = { - { - .id = V4L2_STD_PAL_M, - .common = { - {TM6010_REQ07_R3F_RESET, 0x01}, - {TM6010_REQ07_R00_VIDEO_CONTROL0, 0x05}, - {TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0e}, - {TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f}, - {TM6010_REQ07_R03_YC_SEP_CONTROL, 0x04}, - {TM6010_REQ07_R07_OUTPUT_CONTROL, 0x31}, - {TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x1e}, - {TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0x83}, - {TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0x0a}, - {TM6010_REQ07_R1B_CHROMA_DTO_INCREMENT0, 0xe0}, - {TM6010_REQ07_R1C_HSYNC_DTO_INCREMENT3, 0x1c}, - {TM6010_REQ07_R1D_HSYNC_DTO_INCREMENT2, 0xcc}, - {TM6010_REQ07_R1E_HSYNC_DTO_INCREMENT1, 0xcc}, - {TM6010_REQ07_R1F_HSYNC_DTO_INCREMENT0, 0xcd}, - {TM6010_REQ07_R2E_ACTIVE_VIDEO_HSTART, 0x88}, - {TM6010_REQ07_R30_ACTIVE_VIDEO_VSTART, 0x22}, - {TM6010_REQ07_R31_ACTIVE_VIDEO_VHIGHT, 0x61}, - {TM6010_REQ07_R33_VSYNC_HLOCK_MAX, 0x0c}, - {TM6010_REQ07_R35_VSYNC_AGC_MAX, 0x1c}, - {TM6010_REQ07_R82_COMB_FILTER_CONFIG, 0x52}, - {TM6010_REQ07_R83_CHROMA_LOCK_CONFIG, 0x6F}, - - {TM6010_REQ07_R04_LUMA_HAGC_CONTROL, 0xdc}, - {TM6010_REQ07_R0D_CHROMA_KILL_LEVEL, 0x07}, - {TM6010_REQ07_R3F_RESET, 0x00}, - {0, 0, 0}, - }, - }, { - .id = V4L2_STD_PAL_Nc, - .common = { - {TM6010_REQ07_R3F_RESET, 0x01}, - {TM6010_REQ07_R00_VIDEO_CONTROL0, 0x37}, - {TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0e}, - {TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f}, - {TM6010_REQ07_R03_YC_SEP_CONTROL, 0x04}, - {TM6010_REQ07_R07_OUTPUT_CONTROL, 0x31}, - {TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x1e}, - {TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0x91}, - {TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0x1f}, - {TM6010_REQ07_R1B_CHROMA_DTO_INCREMENT0, 0x0c}, - {TM6010_REQ07_R1C_HSYNC_DTO_INCREMENT3, 0x1c}, - {TM6010_REQ07_R1D_HSYNC_DTO_INCREMENT2, 0xcc}, - {TM6010_REQ07_R1E_HSYNC_DTO_INCREMENT1, 0xcc}, - {TM6010_REQ07_R1F_HSYNC_DTO_INCREMENT0, 0xcd}, - {TM6010_REQ07_R2E_ACTIVE_VIDEO_HSTART, 0x88}, - {TM6010_REQ07_R30_ACTIVE_VIDEO_VSTART, 0x22}, - {TM6010_REQ07_R31_ACTIVE_VIDEO_VHIGHT, 0xc1}, - {TM6010_REQ07_R33_VSYNC_HLOCK_MAX, 0x0c}, - {TM6010_REQ07_R35_VSYNC_AGC_MAX, 0x1c}, - {TM6010_REQ07_R82_COMB_FILTER_CONFIG, 0x52}, - {TM6010_REQ07_R83_CHROMA_LOCK_CONFIG, 0x6F}, - - {TM6010_REQ07_R04_LUMA_HAGC_CONTROL, 0xdc}, - {TM6010_REQ07_R0D_CHROMA_KILL_LEVEL, 0x07}, - {TM6010_REQ07_R3F_RESET, 0x00}, - {0, 0, 0}, - }, - }, { - .id = V4L2_STD_PAL, - .common = { - {TM6010_REQ07_R3F_RESET, 0x01}, - {TM6010_REQ07_R00_VIDEO_CONTROL0, 0x33}, - {TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0e}, - {TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f}, - {TM6010_REQ07_R03_YC_SEP_CONTROL, 0x04}, - {TM6010_REQ07_R07_OUTPUT_CONTROL, 0x30}, - {TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x25}, - {TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0xd5}, - {TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0x63}, - {TM6010_REQ07_R1B_CHROMA_DTO_INCREMENT0, 0x50}, - {TM6010_REQ07_R1C_HSYNC_DTO_INCREMENT3, 0x1c}, - {TM6010_REQ07_R1D_HSYNC_DTO_INCREMENT2, 0xcc}, - {TM6010_REQ07_R1E_HSYNC_DTO_INCREMENT1, 0xcc}, - {TM6010_REQ07_R1F_HSYNC_DTO_INCREMENT0, 0xcd}, - {TM6010_REQ07_R2E_ACTIVE_VIDEO_HSTART, 0x8c}, - {TM6010_REQ07_R30_ACTIVE_VIDEO_VSTART, 0x2a}, - {TM6010_REQ07_R31_ACTIVE_VIDEO_VHIGHT, 0xc1}, - {TM6010_REQ07_R33_VSYNC_HLOCK_MAX, 0x0c}, - {TM6010_REQ07_R35_VSYNC_AGC_MAX, 0x1c}, - {TM6010_REQ07_R82_COMB_FILTER_CONFIG, 0x52}, - {TM6010_REQ07_R83_CHROMA_LOCK_CONFIG, 0x6F}, - - {TM6010_REQ07_R04_LUMA_HAGC_CONTROL, 0xdc}, - {TM6010_REQ07_R0D_CHROMA_KILL_LEVEL, 0x07}, - {TM6010_REQ07_R3F_RESET, 0x00}, - {0, 0, 0}, - }, - }, { - .id = V4L2_STD_SECAM, - .common = { - {TM6010_REQ07_R3F_RESET, 0x01}, - {TM6010_REQ07_R00_VIDEO_CONTROL0, 0x39}, - {TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0e}, - {TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f}, - {TM6010_REQ07_R03_YC_SEP_CONTROL, 0x03}, - {TM6010_REQ07_R07_OUTPUT_CONTROL, 0x31}, - {TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x24}, - {TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0x92}, - {TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0xe8}, - {TM6010_REQ07_R1B_CHROMA_DTO_INCREMENT0, 0xed}, - {TM6010_REQ07_R1C_HSYNC_DTO_INCREMENT3, 0x1c}, - {TM6010_REQ07_R1D_HSYNC_DTO_INCREMENT2, 0xcc}, - {TM6010_REQ07_R1E_HSYNC_DTO_INCREMENT1, 0xcc}, - {TM6010_REQ07_R1F_HSYNC_DTO_INCREMENT0, 0xcd}, - {TM6010_REQ07_R2E_ACTIVE_VIDEO_HSTART, 0x8c}, - {TM6010_REQ07_R30_ACTIVE_VIDEO_VSTART, 0x2a}, - {TM6010_REQ07_R31_ACTIVE_VIDEO_VHIGHT, 0xc1}, - {TM6010_REQ07_R33_VSYNC_HLOCK_MAX, 0x2c}, - {TM6010_REQ07_R35_VSYNC_AGC_MAX, 0x18}, - {TM6010_REQ07_R82_COMB_FILTER_CONFIG, 0x42}, - {TM6010_REQ07_R83_CHROMA_LOCK_CONFIG, 0xFF}, - - {TM6010_REQ07_R0D_CHROMA_KILL_LEVEL, 0x07}, - {TM6010_REQ07_R3F_RESET, 0x00}, - {0, 0, 0}, - }, - }, { - .id = V4L2_STD_NTSC, - .common = { - {TM6010_REQ07_R3F_RESET, 0x01}, - {TM6010_REQ07_R00_VIDEO_CONTROL0, 0x01}, - {TM6010_REQ07_R01_VIDEO_CONTROL1, 0x0f}, - {TM6010_REQ07_R02_VIDEO_CONTROL2, 0x5f}, - {TM6010_REQ07_R03_YC_SEP_CONTROL, 0x03}, - {TM6010_REQ07_R07_OUTPUT_CONTROL, 0x30}, - {TM6010_REQ07_R17_HLOOP_MAXSTATE, 0x8b}, - {TM6010_REQ07_R18_CHROMA_DTO_INCREMENT3, 0x1e}, - {TM6010_REQ07_R19_CHROMA_DTO_INCREMENT2, 0x8b}, - {TM6010_REQ07_R1A_CHROMA_DTO_INCREMENT1, 0xa2}, - {TM6010_REQ07_R1B_CHROMA_DTO_INCREMENT0, 0xe9}, - {TM6010_REQ07_R1C_HSYNC_DTO_INCREMENT3, 0x1c}, - {TM6010_REQ07_R1D_HSYNC_DTO_INCREMENT2, 0xcc}, - {TM6010_REQ07_R1E_HSYNC_DTO_INCREMENT1, 0xcc}, - {TM6010_REQ07_R1F_HSYNC_DTO_INCREMENT0, 0xcd}, - {TM6010_REQ07_R2E_ACTIVE_VIDEO_HSTART, 0x88}, - {TM6010_REQ07_R30_ACTIVE_VIDEO_VSTART, 0x22}, - {TM6010_REQ07_R31_ACTIVE_VIDEO_VHIGHT, 0x61}, - {TM6010_REQ07_R33_VSYNC_HLOCK_MAX, 0x1c}, - {TM6010_REQ07_R35_VSYNC_AGC_MAX, 0x1c}, - {TM6010_REQ07_R82_COMB_FILTER_CONFIG, 0x42}, - {TM6010_REQ07_R83_CHROMA_LOCK_CONFIG, 0x6F}, - - {TM6010_REQ07_R04_LUMA_HAGC_CONTROL, 0xdd}, - {TM6010_REQ07_R0D_CHROMA_KILL_LEVEL, 0x07}, - {TM6010_REQ07_R3F_RESET, 0x00}, - {0, 0, 0}, - }, - }, -}; - - -static int tm6000_set_audio_std(struct tm6000_core *dev) -{ - uint8_t areg_02 = 0x04; /* GC1 Fixed gain 0dB */ - uint8_t areg_05 = 0x01; /* Auto 4.5 = M Japan, Auto 6.5 = DK */ - uint8_t areg_06 = 0x02; /* Auto de-emphasis, mannual channel mode */ - uint8_t nicam_flag = 0; /* No NICAM */ - - if (dev->radio) { - tm6000_set_reg(dev, TM6010_REQ08_R01_A_INIT, 0x00); - tm6000_set_reg(dev, TM6010_REQ08_R02_A_FIX_GAIN_CTRL, 0x04); - tm6000_set_reg(dev, TM6010_REQ08_R03_A_AUTO_GAIN_CTRL, 0x00); - tm6000_set_reg(dev, TM6010_REQ08_R04_A_SIF_AMP_CTRL, 0x80); - tm6000_set_reg(dev, TM6010_REQ08_R05_A_STANDARD_MOD, 0x0c); - /* set mono or stereo */ - if (dev->amode == V4L2_TUNER_MODE_MONO) - tm6000_set_reg(dev, TM6010_REQ08_R06_A_SOUND_MOD, 0x00); - else if (dev->amode == V4L2_TUNER_MODE_STEREO) - tm6000_set_reg(dev, TM6010_REQ08_R06_A_SOUND_MOD, 0x02); - tm6000_set_reg(dev, TM6010_REQ08_R09_A_MAIN_VOL, 0x18); - tm6000_set_reg(dev, TM6010_REQ08_R0C_A_ASD_THRES2, 0x0a); - tm6000_set_reg(dev, TM6010_REQ08_R0D_A_AMD_THRES, 0x40); - tm6000_set_reg(dev, TM6010_REQ08_RF1_AADC_POWER_DOWN, 0xfe); - tm6000_set_reg(dev, TM6010_REQ08_R1E_A_GAIN_DEEMPH_OUT, 0x13); - tm6000_set_reg(dev, TM6010_REQ08_R01_A_INIT, 0x80); - return 0; - } - - switch (tm6010_a_mode) { - /* auto */ - case 0: - switch (dev->norm) { - case V4L2_STD_NTSC_M_KR: - areg_05 |= 0x00; - break; - case V4L2_STD_NTSC_M_JP: - areg_05 |= 0x40; - break; - case V4L2_STD_NTSC_M: - case V4L2_STD_PAL_M: - case V4L2_STD_PAL_N: - areg_05 |= 0x20; - break; - case V4L2_STD_PAL_Nc: - areg_05 |= 0x60; - break; - case V4L2_STD_SECAM_L: - areg_05 |= 0x00; - break; - case V4L2_STD_DK: - areg_05 |= 0x10; - break; - } - break; - /* A2 */ - case 1: - switch (dev->norm) { - case V4L2_STD_B: - case V4L2_STD_GH: - areg_05 = 0x05; - break; - case V4L2_STD_DK: - areg_05 = 0x09; - break; - } - break; - /* NICAM */ - case 2: - switch (dev->norm) { - case V4L2_STD_B: - case V4L2_STD_GH: - areg_05 = 0x07; - break; - case V4L2_STD_DK: - areg_05 = 0x06; - break; - case V4L2_STD_PAL_I: - areg_05 = 0x08; - break; - case V4L2_STD_SECAM_L: - areg_05 = 0x0a; - areg_02 = 0x02; - break; - } - nicam_flag = 1; - break; - /* other */ - case 3: - switch (dev->norm) { - /* DK3_A2 */ - case V4L2_STD_DK: - areg_05 = 0x0b; - break; - /* Korea */ - case V4L2_STD_NTSC_M_KR: - areg_05 = 0x04; - break; - /* EIAJ */ - case V4L2_STD_NTSC_M_JP: - areg_05 = 0x03; - break; - default: - areg_05 = 0x02; - break; - } - break; - } - - tm6000_set_reg(dev, TM6010_REQ08_R01_A_INIT, 0x00); - tm6000_set_reg(dev, TM6010_REQ08_R02_A_FIX_GAIN_CTRL, areg_02); - tm6000_set_reg(dev, TM6010_REQ08_R03_A_AUTO_GAIN_CTRL, 0x00); - tm6000_set_reg(dev, TM6010_REQ08_R04_A_SIF_AMP_CTRL, 0xa0); - tm6000_set_reg(dev, TM6010_REQ08_R05_A_STANDARD_MOD, areg_05); - tm6000_set_reg(dev, TM6010_REQ08_R06_A_SOUND_MOD, areg_06); - tm6000_set_reg(dev, TM6010_REQ08_R07_A_LEFT_VOL, 0x00); - tm6000_set_reg(dev, TM6010_REQ08_R08_A_RIGHT_VOL, 0x00); - tm6000_set_reg(dev, TM6010_REQ08_R09_A_MAIN_VOL, 0x08); - tm6000_set_reg(dev, TM6010_REQ08_R0A_A_I2S_MOD, 0x91); - tm6000_set_reg(dev, TM6010_REQ08_R0B_A_ASD_THRES1, 0x20); - tm6000_set_reg(dev, TM6010_REQ08_R0C_A_ASD_THRES2, 0x12); - tm6000_set_reg(dev, TM6010_REQ08_R0D_A_AMD_THRES, 0x20); - tm6000_set_reg(dev, TM6010_REQ08_R0E_A_MONO_THRES1, 0xf0); - tm6000_set_reg(dev, TM6010_REQ08_R0F_A_MONO_THRES2, 0x80); - tm6000_set_reg(dev, TM6010_REQ08_R10_A_MUTE_THRES1, 0xc0); - tm6000_set_reg(dev, TM6010_REQ08_R11_A_MUTE_THRES2, 0x80); - tm6000_set_reg(dev, TM6010_REQ08_R12_A_AGC_U, 0x12); - tm6000_set_reg(dev, TM6010_REQ08_R13_A_AGC_ERR_T, 0xfe); - tm6000_set_reg(dev, TM6010_REQ08_R14_A_AGC_GAIN_INIT, 0x20); - tm6000_set_reg(dev, TM6010_REQ08_R15_A_AGC_STEP_THR, 0x14); - tm6000_set_reg(dev, TM6010_REQ08_R16_A_AGC_GAIN_MAX, 0xfe); - tm6000_set_reg(dev, TM6010_REQ08_R17_A_AGC_GAIN_MIN, 0x01); - tm6000_set_reg(dev, TM6010_REQ08_R18_A_TR_CTRL, 0xa0); - tm6000_set_reg(dev, TM6010_REQ08_R19_A_FH_2FH_GAIN, 0x32); - tm6000_set_reg(dev, TM6010_REQ08_R1A_A_NICAM_SER_MAX, 0x64); - tm6000_set_reg(dev, TM6010_REQ08_R1B_A_NICAM_SER_MIN, 0x20); - tm6000_set_reg(dev, REQ_08_SET_GET_AVREG_BIT, 0x1c, 0x00); - tm6000_set_reg(dev, REQ_08_SET_GET_AVREG_BIT, 0x1d, 0x00); - tm6000_set_reg(dev, TM6010_REQ08_R1E_A_GAIN_DEEMPH_OUT, 0x13); - tm6000_set_reg(dev, TM6010_REQ08_R1F_A_TEST_INTF_SEL, 0x00); - tm6000_set_reg(dev, TM6010_REQ08_R20_A_TEST_PIN_SEL, 0x00); - tm6000_set_reg(dev, TM6010_REQ08_R01_A_INIT, 0x80); - - return 0; -} - -void tm6000_get_std_res(struct tm6000_core *dev) -{ - /* Currently, those are the only supported resoltions */ - if (dev->norm & V4L2_STD_525_60) - dev->height = 480; - else - dev->height = 576; - - dev->width = 720; -} - -static int tm6000_load_std(struct tm6000_core *dev, - struct tm6000_reg_settings *set, int max_size) -{ - int i, rc; - - /* Load board's initialization table */ - for (i = 0; max_size; i++) { - if (!set[i].req) - return 0; - - rc = tm6000_set_reg(dev, set[i].req, set[i].reg, set[i].value); - if (rc < 0) { - printk(KERN_ERR "Error %i while setting " - "req %d, reg %d to value %d\n", - rc, set[i].req, set[i].reg, set[i].value); - return rc; - } - } - - return 0; -} - -int tm6000_set_standard(struct tm6000_core *dev) -{ - int i, rc = 0; - u8 reg_07_fe = 0x8a; - u8 reg_08_f1 = 0xfc; - u8 reg_08_e2 = 0xf0; - u8 reg_08_e6 = 0x0f; - - tm6000_get_std_res(dev); - - if (dev->radio) { - /* todo */ - } - - if (dev->dev_type == TM6010) { - switch (dev->vinput[dev->input].vmux) { - case TM6000_VMUX_VIDEO_A: - tm6000_set_reg(dev, TM6010_REQ08_RE3_ADC_IN1_SEL, 0xf4); - tm6000_set_reg(dev, TM6010_REQ08_REA_BUFF_DRV_CTRL, 0xf1); - tm6000_set_reg(dev, TM6010_REQ08_REB_SIF_GAIN_CTRL, 0xe0); - tm6000_set_reg(dev, TM6010_REQ08_REC_REVERSE_YC_CTRL, 0xc2); - tm6000_set_reg(dev, TM6010_REQ08_RED_GAIN_SEL, 0xe8); - reg_07_fe |= 0x01; - break; - case TM6000_VMUX_VIDEO_B: - tm6000_set_reg(dev, TM6010_REQ08_RE3_ADC_IN1_SEL, 0xf8); - tm6000_set_reg(dev, TM6010_REQ08_REA_BUFF_DRV_CTRL, 0xf1); - tm6000_set_reg(dev, TM6010_REQ08_REB_SIF_GAIN_CTRL, 0xe0); - tm6000_set_reg(dev, TM6010_REQ08_REC_REVERSE_YC_CTRL, 0xc2); - tm6000_set_reg(dev, TM6010_REQ08_RED_GAIN_SEL, 0xe8); - reg_07_fe |= 0x01; - break; - case TM6000_VMUX_VIDEO_AB: - tm6000_set_reg(dev, TM6010_REQ08_RE3_ADC_IN1_SEL, 0xfc); - tm6000_set_reg(dev, TM6010_REQ08_RE4_ADC_IN2_SEL, 0xf8); - reg_08_e6 = 0x00; - tm6000_set_reg(dev, TM6010_REQ08_REA_BUFF_DRV_CTRL, 0xf2); - tm6000_set_reg(dev, TM6010_REQ08_REB_SIF_GAIN_CTRL, 0xf0); - tm6000_set_reg(dev, TM6010_REQ08_REC_REVERSE_YC_CTRL, 0xc2); - tm6000_set_reg(dev, TM6010_REQ08_RED_GAIN_SEL, 0xe0); - break; - default: - break; - } - switch (dev->vinput[dev->input].amux) { - case TM6000_AMUX_ADC1: - tm6000_set_reg_mask(dev, TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG, - 0x00, 0x0f); - break; - case TM6000_AMUX_ADC2: - tm6000_set_reg_mask(dev, TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG, - 0x08, 0x0f); - break; - case TM6000_AMUX_SIF1: - reg_08_e2 |= 0x02; - reg_08_e6 = 0x08; - reg_07_fe |= 0x40; - reg_08_f1 |= 0x02; - tm6000_set_reg(dev, TM6010_REQ08_RE4_ADC_IN2_SEL, 0xf3); - tm6000_set_reg_mask(dev, TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG, - 0x02, 0x0f); - break; - case TM6000_AMUX_SIF2: - reg_08_e2 |= 0x02; - reg_08_e6 = 0x08; - reg_07_fe |= 0x40; - reg_08_f1 |= 0x02; - tm6000_set_reg(dev, TM6010_REQ08_RE4_ADC_IN2_SEL, 0xf7); - tm6000_set_reg_mask(dev, TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG, - 0x02, 0x0f); - break; - default: - break; - } - tm6000_set_reg(dev, TM6010_REQ08_RE2_POWER_DOWN_CTRL1, reg_08_e2); - tm6000_set_reg(dev, TM6010_REQ08_RE6_POWER_DOWN_CTRL2, reg_08_e6); - tm6000_set_reg(dev, TM6010_REQ08_RF1_AADC_POWER_DOWN, reg_08_f1); - tm6000_set_reg(dev, TM6010_REQ07_RFE_POWER_DOWN, reg_07_fe); - } else { - switch (dev->vinput[dev->input].vmux) { - case TM6000_VMUX_VIDEO_A: - tm6000_set_reg(dev, TM6000_REQ07_RE3_VADC_INP_LPF_SEL1, 0x10); - tm6000_set_reg(dev, TM6000_REQ07_RE5_VADC_INP_LPF_SEL2, 0x00); - tm6000_set_reg(dev, TM6000_REQ07_RE8_VADC_PWDOWN_CTL, 0x0f); - tm6000_set_reg(dev, - REQ_03_SET_GET_MCU_PIN, dev->vinput[dev->input].v_gpio, 0); - break; - case TM6000_VMUX_VIDEO_B: - tm6000_set_reg(dev, TM6000_REQ07_RE3_VADC_INP_LPF_SEL1, 0x00); - tm6000_set_reg(dev, TM6000_REQ07_RE5_VADC_INP_LPF_SEL2, 0x00); - tm6000_set_reg(dev, TM6000_REQ07_RE8_VADC_PWDOWN_CTL, 0x0f); - tm6000_set_reg(dev, - REQ_03_SET_GET_MCU_PIN, dev->vinput[dev->input].v_gpio, 0); - break; - case TM6000_VMUX_VIDEO_AB: - tm6000_set_reg(dev, TM6000_REQ07_RE3_VADC_INP_LPF_SEL1, 0x10); - tm6000_set_reg(dev, TM6000_REQ07_RE5_VADC_INP_LPF_SEL2, 0x10); - tm6000_set_reg(dev, TM6000_REQ07_RE8_VADC_PWDOWN_CTL, 0x00); - tm6000_set_reg(dev, - REQ_03_SET_GET_MCU_PIN, dev->vinput[dev->input].v_gpio, 1); - break; - default: - break; - } - switch (dev->vinput[dev->input].amux) { - case TM6000_AMUX_ADC1: - tm6000_set_reg_mask(dev, - TM6000_REQ07_REB_VADC_AADC_MODE, 0x00, 0x0f); - break; - case TM6000_AMUX_ADC2: - tm6000_set_reg_mask(dev, - TM6000_REQ07_REB_VADC_AADC_MODE, 0x04, 0x0f); - break; - default: - break; - } - } - if (dev->vinput[dev->input].type == TM6000_INPUT_SVIDEO) { - for (i = 0; i < ARRAY_SIZE(svideo_stds); i++) { - if (dev->norm & svideo_stds[i].id) { - rc = tm6000_load_std(dev, svideo_stds[i].common, - sizeof(svideo_stds[i]. - common)); - goto ret; - } - } - return -EINVAL; - } else { - for (i = 0; i < ARRAY_SIZE(composite_stds); i++) { - if (dev->norm & composite_stds[i].id) { - rc = tm6000_load_std(dev, - composite_stds[i].common, - sizeof(composite_stds[i]. - common)); - goto ret; - } - } - return -EINVAL; - } - -ret: - if (rc < 0) - return rc; - - if ((dev->dev_type == TM6010) && - ((dev->vinput[dev->input].amux == TM6000_AMUX_SIF1) || - (dev->vinput[dev->input].amux == TM6000_AMUX_SIF2))) - tm6000_set_audio_std(dev); - - msleep(40); - - - return 0; -} diff --git a/drivers/staging/tm6000/tm6000-usb-isoc.h b/drivers/staging/tm6000/tm6000-usb-isoc.h deleted file mode 100644 index 084c2a8904a3..000000000000 --- a/drivers/staging/tm6000/tm6000-usb-isoc.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * tm6000-buf.c - driver for TM5600/TM6000/TM6010 USB video capture devices - * - * Copyright (C) 2006-2007 Mauro Carvalho Chehab <mchehab@infradead.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation version 2 - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include <linux/videodev2.h> - -#define TM6000_URB_MSG_LEN 180 - -struct usb_isoc_ctl { - /* max packet size of isoc transaction */ - int max_pkt_size; - - /* number of allocated urbs */ - int num_bufs; - - /* urb for isoc transfers */ - struct urb **urb; - - /* transfer buffers for isoc transfer */ - char **transfer_buffer; - - /* Last buffer command and region */ - u8 cmd; - int pos, size, pktsize; - - /* Last field: ODD or EVEN? */ - int vfield, field; - - /* Stores incomplete commands */ - u32 tmp_buf; - int tmp_buf_len; - - /* Stores already requested buffers */ - struct tm6000_buffer *buf; -}; diff --git a/drivers/staging/tm6000/tm6000-video.c b/drivers/staging/tm6000/tm6000-video.c deleted file mode 100644 index 8d8b939915d8..000000000000 --- a/drivers/staging/tm6000/tm6000-video.c +++ /dev/null @@ -1,1809 +0,0 @@ -/* - * tm6000-video.c - driver for TM5600/TM6000/TM6010 USB video capture devices - * - * Copyright (C) 2006-2007 Mauro Carvalho Chehab <mchehab@infradead.org> - * - * Copyright (C) 2007 Michel Ludwig <michel.ludwig@gmail.com> - * - Fixed module load/unload - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation version 2 - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ -#include <linux/module.h> -#include <linux/delay.h> -#include <linux/errno.h> -#include <linux/fs.h> -#include <linux/kernel.h> -#include <linux/slab.h> -#include <linux/mm.h> -#include <linux/ioport.h> -#include <linux/init.h> -#include <linux/sched.h> -#include <linux/random.h> -#include <linux/usb.h> -#include <linux/videodev2.h> -#include <media/v4l2-ioctl.h> -#include <media/tuner.h> -#include <linux/interrupt.h> -#include <linux/kthread.h> -#include <linux/highmem.h> -#include <linux/freezer.h> - -#include "tm6000-regs.h" -#include "tm6000.h" - -#define BUFFER_TIMEOUT msecs_to_jiffies(2000) /* 2 seconds */ - -/* Limits minimum and default number of buffers */ -#define TM6000_MIN_BUF 4 -#define TM6000_DEF_BUF 8 - -#define TM6000_MAX_ISO_PACKETS 46 /* Max number of ISO packets */ - -/* Declare static vars that will be used as parameters */ -static unsigned int vid_limit = 16; /* Video memory limit, in Mb */ -static int video_nr = -1; /* /dev/videoN, -1 for autodetect */ -static int radio_nr = -1; /* /dev/radioN, -1 for autodetect */ - -/* Debug level */ -int tm6000_debug; -EXPORT_SYMBOL_GPL(tm6000_debug); - -static const struct v4l2_queryctrl no_ctrl = { - .name = "42", - .flags = V4L2_CTRL_FLAG_DISABLED, -}; - -/* supported controls */ -static struct v4l2_queryctrl tm6000_qctrl[] = { - { - .id = V4L2_CID_BRIGHTNESS, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Brightness", - .minimum = 0, - .maximum = 255, - .step = 1, - .default_value = 54, - .flags = 0, - }, { - .id = V4L2_CID_CONTRAST, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Contrast", - .minimum = 0, - .maximum = 255, - .step = 0x1, - .default_value = 119, - .flags = 0, - }, { - .id = V4L2_CID_SATURATION, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Saturation", - .minimum = 0, - .maximum = 255, - .step = 0x1, - .default_value = 112, - .flags = 0, - }, { - .id = V4L2_CID_HUE, - .type = V4L2_CTRL_TYPE_INTEGER, - .name = "Hue", - .minimum = -128, - .maximum = 127, - .step = 0x1, - .default_value = 0, - .flags = 0, - }, - /* --- audio --- */ - { - .id = V4L2_CID_AUDIO_MUTE, - .name = "Mute", - .minimum = 0, - .maximum = 1, - .type = V4L2_CTRL_TYPE_BOOLEAN, - }, { - .id = V4L2_CID_AUDIO_VOLUME, - .name = "Volume", - .minimum = -15, - .maximum = 15, - .step = 1, - .default_value = 0, - .type = V4L2_CTRL_TYPE_INTEGER, - } -}; - -static const unsigned int CTRLS = ARRAY_SIZE(tm6000_qctrl); -static int qctl_regs[ARRAY_SIZE(tm6000_qctrl)]; - -static struct tm6000_fmt format[] = { - { - .name = "4:2:2, packed, YVY2", - .fourcc = V4L2_PIX_FMT_YUYV, - .depth = 16, - }, { - .name = "4:2:2, packed, UYVY", - .fourcc = V4L2_PIX_FMT_UYVY, - .depth = 16, - }, { - .name = "A/V + VBI mux packet", - .fourcc = V4L2_PIX_FMT_TM6000, - .depth = 16, - } -}; - -static const struct v4l2_queryctrl *ctrl_by_id(unsigned int id) -{ - unsigned int i; - - for (i = 0; i < CTRLS; i++) - if (tm6000_qctrl[i].id == id) - return tm6000_qctrl+i; - return NULL; -} - -/* ------------------------------------------------------------------ - * DMA and thread functions - * ------------------------------------------------------------------ - */ - -#define norm_maxw(a) 720 -#define norm_maxh(a) 576 - -#define norm_minw(a) norm_maxw(a) -#define norm_minh(a) norm_maxh(a) - -/* - * video-buf generic routine to get the next available buffer - */ -static inline void get_next_buf(struct tm6000_dmaqueue *dma_q, - struct tm6000_buffer **buf) -{ - struct tm6000_core *dev = container_of(dma_q, struct tm6000_core, vidq); - char *outp; - - if (list_empty(&dma_q->active)) { - dprintk(dev, V4L2_DEBUG_QUEUE, "No active queue to serve\n"); - *buf = NULL; - return; - } - - *buf = list_entry(dma_q->active.next, - struct tm6000_buffer, vb.queue); - - /* Cleans up buffer - Useful for testing for frame/URB loss */ - outp = videobuf_to_vmalloc(&(*buf)->vb); - - return; -} - -/* - * Announces that a buffer were filled and request the next - */ -static inline void buffer_filled(struct tm6000_core *dev, - struct tm6000_dmaqueue *dma_q, - struct tm6000_buffer *buf) -{ - /* Advice that buffer was filled */ - dprintk(dev, V4L2_DEBUG_ISOC, "[%p/%d] wakeup\n", buf, buf->vb.i); - buf->vb.state = VIDEOBUF_DONE; - buf->vb.field_count++; - do_gettimeofday(&buf->vb.ts); - - list_del(&buf->vb.queue); - wake_up(&buf->vb.done); -} - -const char *tm6000_msg_type[] = { - "unknown(0)", /* 0 */ - "video", /* 1 */ - "audio", /* 2 */ - "vbi", /* 3 */ - "pts", /* 4 */ - "err", /* 5 */ - "unknown(6)", /* 6 */ - "unknown(7)", /* 7 */ -}; - -/* - * Identify the tm5600/6000 buffer header type and properly handles - */ -static int copy_streams(u8 *data, unsigned long len, - struct urb *urb) -{ - struct tm6000_dmaqueue *dma_q = urb->context; - struct tm6000_core *dev = container_of(dma_q, struct tm6000_core, vidq); - u8 *ptr = data, *endp = data+len, c; - unsigned long header = 0; - int rc = 0; - unsigned int cmd, cpysize, pktsize, size, field, block, line, pos = 0; - struct tm6000_buffer *vbuf = NULL; - char *voutp = NULL; - unsigned int linewidth; - - if (!dev->radio) { - /* get video buffer */ - get_next_buf(dma_q, &vbuf); - - if (!vbuf) - return rc; - voutp = videobuf_to_vmalloc(&vbuf->vb); - - if (!voutp) - return 0; - } - - for (ptr = data; ptr < endp;) { - if (!dev->isoc_ctl.cmd) { - /* Header */ - if (dev->isoc_ctl.tmp_buf_len > 0) { - /* from last urb or packet */ - header = dev->isoc_ctl.tmp_buf; - if (4 - dev->isoc_ctl.tmp_buf_len > 0) { - memcpy((u8 *)&header + - dev->isoc_ctl.tmp_buf_len, - ptr, - 4 - dev->isoc_ctl.tmp_buf_len); - ptr += 4 - dev->isoc_ctl.tmp_buf_len; - } - dev->isoc_ctl.tmp_buf_len = 0; - } else { - if (ptr + 3 >= endp) { - /* have incomplete header */ - dev->isoc_ctl.tmp_buf_len = endp - ptr; - memcpy(&dev->isoc_ctl.tmp_buf, ptr, - dev->isoc_ctl.tmp_buf_len); - return rc; - } - /* Seek for sync */ - for (; ptr < endp - 3; ptr++) { - if (*(ptr + 3) == 0x47) - break; - } - /* Get message header */ - header = *(unsigned long *)ptr; - ptr += 4; - } - - /* split the header fields */ - c = (header >> 24) & 0xff; - size = ((header & 0x7e) << 1); - if (size > 0) - size -= 4; - block = (header >> 7) & 0xf; - field = (header >> 11) & 0x1; - line = (header >> 12) & 0x1ff; - cmd = (header >> 21) & 0x7; - /* Validates haeder fields */ - if (size > TM6000_URB_MSG_LEN) - size = TM6000_URB_MSG_LEN; - pktsize = TM6000_URB_MSG_LEN; - /* calculate position in buffer - * and change the buffer - */ - switch (cmd) { - case TM6000_URB_MSG_VIDEO: - if (!dev->radio) { - if ((dev->isoc_ctl.vfield != field) && - (field == 1)) { - /* Announces that a new buffer - * were filled - */ - buffer_filled(dev, dma_q, vbuf); - dprintk(dev, V4L2_DEBUG_ISOC, - "new buffer filled\n"); - get_next_buf(dma_q, &vbuf); - if (!vbuf) - return rc; - voutp = videobuf_to_vmalloc(&vbuf->vb); - if (!voutp) - return rc; - memset(voutp, 0, vbuf->vb.size); - } - linewidth = vbuf->vb.width << 1; - pos = ((line << 1) - field - 1) * - linewidth + block * TM6000_URB_MSG_LEN; - /* Don't allow to write out of the buffer */ - if (pos + size > vbuf->vb.size) - cmd = TM6000_URB_MSG_ERR; - dev->isoc_ctl.vfield = field; - } - break; - case TM6000_URB_MSG_VBI: - break; - case TM6000_URB_MSG_AUDIO: - case TM6000_URB_MSG_PTS: - size = pktsize; /* Size is always 180 bytes */ - break; - } - } else { - /* Continue the last copy */ - cmd = dev->isoc_ctl.cmd; - size = dev->isoc_ctl.size; - pos = dev->isoc_ctl.pos; - pktsize = dev->isoc_ctl.pktsize; - field = dev->isoc_ctl.field; - } - cpysize = (endp - ptr > size) ? size : endp - ptr; - if (cpysize) { - /* copy data in different buffers */ - switch (cmd) { - case TM6000_URB_MSG_VIDEO: - /* Fills video buffer */ - if (vbuf) - memcpy(&voutp[pos], ptr, cpysize); - break; - case TM6000_URB_MSG_AUDIO: { - int i; - for (i = 0; i < cpysize; i += 2) - swab16s((u16 *)(ptr + i)); - - tm6000_call_fillbuf(dev, TM6000_AUDIO, ptr, cpysize); - break; - } - case TM6000_URB_MSG_VBI: - /* Need some code to copy vbi buffer */ - break; - case TM6000_URB_MSG_PTS: { - /* Need some code to copy pts */ - u32 pts; - pts = *(u32 *)ptr; - dprintk(dev, V4L2_DEBUG_ISOC, "field %d, PTS %x", - field, pts); - break; - } - } - } - if (ptr + pktsize > endp) { - /* End of URB packet, but cmd processing is not - * complete. Preserve the state for a next packet - */ - dev->isoc_ctl.pos = pos + cpysize; - dev->isoc_ctl.size = size - cpysize; - dev->isoc_ctl.cmd = cmd; - dev->isoc_ctl.field = field; - dev->isoc_ctl.pktsize = pktsize - (endp - ptr); - ptr += endp - ptr; - } else { - dev->isoc_ctl.cmd = 0; - ptr += pktsize; - } - } - return 0; -} - -/* - * Identify the tm5600/6000 buffer header type and properly handles - */ -static int copy_multiplexed(u8 *ptr, unsigned long len, - struct urb *urb) -{ - struct tm6000_dmaqueue *dma_q = urb->context; - struct tm6000_core *dev = container_of(dma_q, struct tm6000_core, vidq); - unsigned int pos = dev->isoc_ctl.pos, cpysize; - int rc = 1; - struct tm6000_buffer *buf; - char *outp = NULL; - - get_next_buf(dma_q, &buf); - if (buf) - outp = videobuf_to_vmalloc(&buf->vb); - - if (!outp) - return 0; - - while (len > 0) { - cpysize = min(len, buf->vb.size-pos); - memcpy(&outp[pos], ptr, cpysize); - pos += cpysize; - ptr += cpysize; - len -= cpysize; - if (pos >= buf->vb.size) { - pos = 0; - /* Announces that a new buffer were filled */ - buffer_filled(dev, dma_q, buf); - dprintk(dev, V4L2_DEBUG_ISOC, "new buffer filled\n"); - get_next_buf(dma_q, &buf); - if (!buf) - break; - outp = videobuf_to_vmalloc(&(buf->vb)); - if (!outp) - return rc; - pos = 0; - } - } - - dev->isoc_ctl.pos = pos; - return rc; -} - -static inline void print_err_status(struct tm6000_core *dev, - int packet, int status) -{ - char *errmsg = "Unknown"; - - switch (status) { - case -ENOENT: - errmsg = "unlinked synchronuously"; - break; - case -ECONNRESET: - errmsg = "unlinked asynchronuously"; - break; - case -ENOSR: - errmsg = "Buffer error (overrun)"; - break; - case -EPIPE: - errmsg = "Stalled (device not responding)"; - break; - case -EOVERFLOW: - errmsg = "Babble (bad cable?)"; - break; - case -EPROTO: - errmsg = "Bit-stuff error (bad cable?)"; - break; - case -EILSEQ: - errmsg = "CRC/Timeout (could be anything)"; - break; - case -ETIME: - errmsg = "Device does not respond"; - break; - } - if (packet < 0) { - dprintk(dev, V4L2_DEBUG_QUEUE, "URB status %d [%s].\n", - status, errmsg); - } else { - dprintk(dev, V4L2_DEBUG_QUEUE, "URB packet %d, status %d [%s].\n", - packet, status, errmsg); - } -} - - -/* - * Controls the isoc copy of each urb packet - */ -static inline int tm6000_isoc_copy(struct urb *urb) -{ - struct tm6000_dmaqueue *dma_q = urb->context; - struct tm6000_core *dev = container_of(dma_q, struct tm6000_core, vidq); - int i, len = 0, rc = 1, status; - char *p; - - if (urb->status < 0) { - print_err_status(dev, -1, urb->status); - return 0; - } - - for (i = 0; i < urb->number_of_packets; i++) { - status = urb->iso_frame_desc[i].status; - - if (status < 0) { - print_err_status(dev, i, status); - continue; - } - - len = urb->iso_frame_desc[i].actual_length; - - if (len > 0) { - p = urb->transfer_buffer + urb->iso_frame_desc[i].offset; - if (!urb->iso_frame_desc[i].status) { - if ((dev->fourcc) == V4L2_PIX_FMT_TM6000) { - rc = copy_multiplexed(p, len, urb); - if (rc <= 0) - return rc; - } else { - copy_streams(p, len, urb); - } - } - } - } - return rc; -} - -/* ------------------------------------------------------------------ - * URB control - * ------------------------------------------------------------------ - */ - -/* - * IRQ callback, called by URB callback - */ -static void tm6000_irq_callback(struct urb *urb) -{ - struct tm6000_dmaqueue *dma_q = urb->context; - struct tm6000_core *dev = container_of(dma_q, struct tm6000_core, vidq); - int i; - - if (!dev) - return; - - spin_lock(&dev->slock); - tm6000_isoc_copy(urb); - spin_unlock(&dev->slock); - - /* Reset urb buffers */ - for (i = 0; i < urb->number_of_packets; i++) { - urb->iso_frame_desc[i].status = 0; - urb->iso_frame_desc[i].actual_length = 0; - } - - urb->status = usb_submit_urb(urb, GFP_ATOMIC); - if (urb->status) - tm6000_err("urb resubmit failed (error=%i)\n", - urb->status); -} - -/* - * Stop and Deallocate URBs - */ -static void tm6000_uninit_isoc(struct tm6000_core *dev) -{ - struct urb *urb; - int i; - - dev->isoc_ctl.buf = NULL; - for (i = 0; i < dev->isoc_ctl.num_bufs; i++) { - urb = dev->isoc_ctl.urb[i]; - if (urb) { - usb_kill_urb(urb); - usb_unlink_urb(urb); - if (dev->isoc_ctl.transfer_buffer[i]) { - usb_free_coherent(dev->udev, - urb->transfer_buffer_length, - dev->isoc_ctl.transfer_buffer[i], - urb->transfer_dma); - } - usb_free_urb(urb); - dev->isoc_ctl.urb[i] = NULL; - } - dev->isoc_ctl.transfer_buffer[i] = NULL; - } - - kfree(dev->isoc_ctl.urb); - kfree(dev->isoc_ctl.transfer_buffer); - - dev->isoc_ctl.urb = NULL; - dev->isoc_ctl.transfer_buffer = NULL; - dev->isoc_ctl.num_bufs = 0; -} - -/* - * Allocate URBs and start IRQ - */ -static int tm6000_prepare_isoc(struct tm6000_core *dev) -{ - struct tm6000_dmaqueue *dma_q = &dev->vidq; - int i, j, sb_size, pipe, size, max_packets, num_bufs = 8; - struct urb *urb; - - /* De-allocates all pending stuff */ - tm6000_uninit_isoc(dev); - /* Stop interrupt USB pipe */ - tm6000_ir_int_stop(dev); - - usb_set_interface(dev->udev, - dev->isoc_in.bInterfaceNumber, - dev->isoc_in.bAlternateSetting); - - /* Start interrupt USB pipe */ - tm6000_ir_int_start(dev); - - pipe = usb_rcvisocpipe(dev->udev, - dev->isoc_in.endp->desc.bEndpointAddress & - USB_ENDPOINT_NUMBER_MASK); - - size = usb_maxpacket(dev->udev, pipe, usb_pipeout(pipe)); - - if (size > dev->isoc_in.maxsize) - size = dev->isoc_in.maxsize; - - dev->isoc_ctl.max_pkt_size = size; - - max_packets = TM6000_MAX_ISO_PACKETS; - sb_size = max_packets * size; - - dev->isoc_ctl.num_bufs = num_bufs; - - dev->isoc_ctl.urb = kmalloc(sizeof(void *)*num_bufs, GFP_KERNEL); - if (!dev->isoc_ctl.urb) { - tm6000_err("cannot alloc memory for usb buffers\n"); - return -ENOMEM; - } - - dev->isoc_ctl.transfer_buffer = kmalloc(sizeof(void *)*num_bufs, - GFP_KERNEL); - if (!dev->isoc_ctl.transfer_buffer) { - tm6000_err("cannot allocate memory for usbtransfer\n"); - kfree(dev->isoc_ctl.urb); - return -ENOMEM; - } - - dprintk(dev, V4L2_DEBUG_QUEUE, "Allocating %d x %d packets" - " (%d bytes) of %d bytes each to handle %u size\n", - max_packets, num_bufs, sb_size, - dev->isoc_in.maxsize, size); - - /* allocate urbs and transfer buffers */ - for (i = 0; i < dev->isoc_ctl.num_bufs; i++) { - urb = usb_alloc_urb(max_packets, GFP_KERNEL); - if (!urb) { - tm6000_err("cannot alloc isoc_ctl.urb %i\n", i); - tm6000_uninit_isoc(dev); - usb_free_urb(urb); - return -ENOMEM; - } - dev->isoc_ctl.urb[i] = urb; - - dev->isoc_ctl.transfer_buffer[i] = usb_alloc_coherent(dev->udev, - sb_size, GFP_KERNEL, &urb->transfer_dma); - if (!dev->isoc_ctl.transfer_buffer[i]) { - tm6000_err("unable to allocate %i bytes for transfer" - " buffer %i%s\n", - sb_size, i, - in_interrupt() ? " while in int" : ""); - tm6000_uninit_isoc(dev); - return -ENOMEM; - } - memset(dev->isoc_ctl.transfer_buffer[i], 0, sb_size); - - usb_fill_bulk_urb(urb, dev->udev, pipe, - dev->isoc_ctl.transfer_buffer[i], sb_size, - tm6000_irq_callback, dma_q); - urb->interval = dev->isoc_in.endp->desc.bInterval; - urb->number_of_packets = max_packets; - urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP; - - for (j = 0; j < max_packets; j++) { - urb->iso_frame_desc[j].offset = size * j; - urb->iso_frame_desc[j].length = size; - } - } - - return 0; -} - -static int tm6000_start_thread(struct tm6000_core *dev) -{ - struct tm6000_dmaqueue *dma_q = &dev->vidq; - int i; - - dma_q->frame = 0; - dma_q->ini_jiffies = jiffies; - - init_waitqueue_head(&dma_q->wq); - - /* submit urbs and enables IRQ */ - for (i = 0; i < dev->isoc_ctl.num_bufs; i++) { - int rc = usb_submit_urb(dev->isoc_ctl.urb[i], GFP_ATOMIC); - if (rc) { - tm6000_err("submit of urb %i failed (error=%i)\n", i, - rc); - tm6000_uninit_isoc(dev); - return rc; - } - } - - return 0; -} - -/* ------------------------------------------------------------------ - * Videobuf operations - * ------------------------------------------------------------------ - */ - -static int -buffer_setup(struct videobuf_queue *vq, unsigned int *count, unsigned int *size) -{ - struct tm6000_fh *fh = vq->priv_data; - - *size = fh->fmt->depth * fh->width * fh->height >> 3; - if (0 == *count) - *count = TM6000_DEF_BUF; - - if (*count < TM6000_MIN_BUF) - *count = TM6000_MIN_BUF; - - while (*size * *count > vid_limit * 1024 * 1024) - (*count)--; - - return 0; -} - -static void free_buffer(struct videobuf_queue *vq, struct tm6000_buffer *buf) -{ - struct tm6000_fh *fh = vq->priv_data; - struct tm6000_core *dev = fh->dev; - unsigned long flags; - - if (in_interrupt()) - BUG(); - - /* We used to wait for the buffer to finish here, but this didn't work - because, as we were keeping the state as VIDEOBUF_QUEUED, - videobuf_queue_cancel marked it as finished for us. - (Also, it could wedge forever if the hardware was misconfigured.) - - This should be safe; by the time we get here, the buffer isn't - queued anymore. If we ever start marking the buffers as - VIDEOBUF_ACTIVE, it won't be, though. - */ - spin_lock_irqsave(&dev->slock, flags); - if (dev->isoc_ctl.buf == buf) - dev->isoc_ctl.buf = NULL; - spin_unlock_irqrestore(&dev->slock, flags); - - videobuf_vmalloc_free(&buf->vb); - buf->vb.state = VIDEOBUF_NEEDS_INIT; -} - -static int -buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb, - enum v4l2_field field) -{ - struct tm6000_fh *fh = vq->priv_data; - struct tm6000_buffer *buf = container_of(vb, struct tm6000_buffer, vb); - struct tm6000_core *dev = fh->dev; - int rc = 0, urb_init = 0; - - BUG_ON(NULL == fh->fmt); - - - /* FIXME: It assumes depth=2 */ - /* The only currently supported format is 16 bits/pixel */ - buf->vb.size = fh->fmt->depth*fh->width*fh->height >> 3; - if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size) - return -EINVAL; - - if (buf->fmt != fh->fmt || - buf->vb.width != fh->width || - buf->vb.height != fh->height || - buf->vb.field != field) { - buf->fmt = fh->fmt; - buf->vb.width = fh->width; - buf->vb.height = fh->height; - buf->vb.field = field; - buf->vb.state = VIDEOBUF_NEEDS_INIT; - } - - if (VIDEOBUF_NEEDS_INIT == buf->vb.state) { - rc = videobuf_iolock(vq, &buf->vb, NULL); - if (rc != 0) - goto fail; - urb_init = 1; - } - - if (!dev->isoc_ctl.num_bufs) - urb_init = 1; - - if (urb_init) { - rc = tm6000_prepare_isoc(dev); - if (rc < 0) - goto fail; - - rc = tm6000_start_thread(dev); - if (rc < 0) - goto fail; - - } - - buf->vb.state = VIDEOBUF_PREPARED; - return 0; - -fail: - free_buffer(vq, buf); - return rc; -} - -static void -buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb) -{ - struct tm6000_buffer *buf = container_of(vb, struct tm6000_buffer, vb); - struct tm6000_fh *fh = vq->priv_data; - struct tm6000_core *dev = fh->dev; - struct tm6000_dmaqueue *vidq = &dev->vidq; - - buf->vb.state = VIDEOBUF_QUEUED; - list_add_tail(&buf->vb.queue, &vidq->active); -} - -static void buffer_release(struct videobuf_queue *vq, struct videobuf_buffer *vb) -{ - struct tm6000_buffer *buf = container_of(vb, struct tm6000_buffer, vb); - - free_buffer(vq, buf); -} - -static struct videobuf_queue_ops tm6000_video_qops = { - .buf_setup = buffer_setup, - .buf_prepare = buffer_prepare, - .buf_queue = buffer_queue, - .buf_release = buffer_release, -}; - -/* ------------------------------------------------------------------ - * IOCTL handling - * ------------------------------------------------------------------ - */ - -static bool is_res_read(struct tm6000_core *dev, struct tm6000_fh *fh) -{ - /* Is the current fh handling it? if so, that's OK */ - if (dev->resources == fh && dev->is_res_read) - return true; - - return false; -} - -static bool is_res_streaming(struct tm6000_core *dev, struct tm6000_fh *fh) -{ - /* Is the current fh handling it? if so, that's OK */ - if (dev->resources == fh) - return true; - - return false; -} - -static bool res_get(struct tm6000_core *dev, struct tm6000_fh *fh, - bool is_res_read) -{ - /* Is the current fh handling it? if so, that's OK */ - if (dev->resources == fh && dev->is_res_read == is_res_read) - return true; - - /* is it free? */ - if (dev->resources) - return false; - - /* grab it */ - dev->resources = fh; - dev->is_res_read = is_res_read; - dprintk(dev, V4L2_DEBUG_RES_LOCK, "res: get\n"); - return true; -} - -static void res_free(struct tm6000_core *dev, struct tm6000_fh *fh) -{ - /* Is the current fh handling it? if so, that's OK */ - if (dev->resources != fh) - return; - - dev->resources = NULL; - dprintk(dev, V4L2_DEBUG_RES_LOCK, "res: put\n"); -} - -/* ------------------------------------------------------------------ - * IOCTL vidioc handling - * ------------------------------------------------------------------ - */ -static int vidioc_querycap(struct file *file, void *priv, - struct v4l2_capability *cap) -{ - struct tm6000_core *dev = ((struct tm6000_fh *)priv)->dev; - - strlcpy(cap->driver, "tm6000", sizeof(cap->driver)); - strlcpy(cap->card, "Trident TVMaster TM5600/6000/6010", sizeof(cap->card)); - cap->version = TM6000_VERSION; - cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | - V4L2_CAP_STREAMING | - V4L2_CAP_AUDIO | - V4L2_CAP_READWRITE; - - if (dev->tuner_type != TUNER_ABSENT) - cap->capabilities |= V4L2_CAP_TUNER; - - return 0; -} - -static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv, - struct v4l2_fmtdesc *f) -{ - if (unlikely(f->index >= ARRAY_SIZE(format))) - return -EINVAL; - - strlcpy(f->description, format[f->index].name, sizeof(f->description)); - f->pixelformat = format[f->index].fourcc; - return 0; -} - -static int vidioc_g_fmt_vid_cap(struct file *file, void *priv, - struct v4l2_format *f) -{ - struct tm6000_fh *fh = priv; - - f->fmt.pix.width = fh->width; - f->fmt.pix.height = fh->height; - f->fmt.pix.field = fh->vb_vidq.field; - f->fmt.pix.pixelformat = fh->fmt->fourcc; - f->fmt.pix.bytesperline = - (f->fmt.pix.width * fh->fmt->depth) >> 3; - f->fmt.pix.sizeimage = - f->fmt.pix.height * f->fmt.pix.bytesperline; - - return 0; -} - -static struct tm6000_fmt *format_by_fourcc(unsigned int fourcc) -{ - unsigned int i; - - for (i = 0; i < ARRAY_SIZE(format); i++) - if (format[i].fourcc == fourcc) - return format+i; - return NULL; -} - -static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, - struct v4l2_format *f) -{ - struct tm6000_core *dev = ((struct tm6000_fh *)priv)->dev; - struct tm6000_fmt *fmt; - enum v4l2_field field; - - fmt = format_by_fourcc(f->fmt.pix.pixelformat); - if (NULL == fmt) { - dprintk(dev, V4L2_DEBUG_IOCTL_ARG, "Fourcc format (0x%08x)" - " invalid.\n", f->fmt.pix.pixelformat); - return -EINVAL; - } - - field = f->fmt.pix.field; - - if (field == V4L2_FIELD_ANY) - field = V4L2_FIELD_SEQ_TB; - else if (V4L2_FIELD_INTERLACED != field) { - dprintk(dev, V4L2_DEBUG_IOCTL_ARG, "Field type invalid.\n"); - return -EINVAL; - } - - tm6000_get_std_res(dev); - - f->fmt.pix.width = dev->width; - f->fmt.pix.height = dev->height; - - f->fmt.pix.width &= ~0x01; - - f->fmt.pix.field = field; - - f->fmt.pix.bytesperline = - (f->fmt.pix.width * fmt->depth) >> 3; - f->fmt.pix.sizeimage = - f->fmt.pix.height * f->fmt.pix.bytesperline; - - return 0; -} - -/*FIXME: This seems to be generic enough to be at videodev2 */ -static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, - struct v4l2_format *f) -{ - struct tm6000_fh *fh = priv; - struct tm6000_core *dev = fh->dev; - int ret = vidioc_try_fmt_vid_cap(file, fh, f); - if (ret < 0) - return ret; - - fh->fmt = format_by_fourcc(f->fmt.pix.pixelformat); - fh->width = f->fmt.pix.width; - fh->height = f->fmt.pix.height; - fh->vb_vidq.field = f->fmt.pix.field; - fh->type = f->type; - - dev->fourcc = f->fmt.pix.pixelformat; - - tm6000_set_fourcc_format(dev); - - return 0; -} - -static int vidioc_reqbufs(struct file *file, void *priv, - struct v4l2_requestbuffers *p) -{ - struct tm6000_fh *fh = priv; - - return videobuf_reqbufs(&fh->vb_vidq, p); -} - -static int vidioc_querybuf(struct file *file, void *priv, - struct v4l2_buffer *p) -{ - struct tm6000_fh *fh = priv; - - return videobuf_querybuf(&fh->vb_vidq, p); -} - -static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *p) -{ - struct tm6000_fh *fh = priv; - - return videobuf_qbuf(&fh->vb_vidq, p); -} - -static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p) -{ - struct tm6000_fh *fh = priv; - - return videobuf_dqbuf(&fh->vb_vidq, p, - file->f_flags & O_NONBLOCK); -} - -static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i) -{ - struct tm6000_fh *fh = priv; - struct tm6000_core *dev = fh->dev; - - if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) - return -EINVAL; - if (i != fh->type) - return -EINVAL; - - if (!res_get(dev, fh, false)) - return -EBUSY; - return videobuf_streamon(&fh->vb_vidq); -} - -static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i) -{ - struct tm6000_fh *fh = priv; - struct tm6000_core *dev = fh->dev; - - if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) - return -EINVAL; - if (i != fh->type) - return -EINVAL; - - videobuf_streamoff(&fh->vb_vidq); - res_free(dev, fh); - - return 0; -} - -static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *norm) -{ - int rc = 0; - struct tm6000_fh *fh = priv; - struct tm6000_core *dev = fh->dev; - - dev->norm = *norm; - rc = tm6000_init_analog_mode(dev); - - fh->width = dev->width; - fh->height = dev->height; - - if (rc < 0) - return rc; - - v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_std, dev->norm); - - return 0; -} - -static const char *iname[] = { - [TM6000_INPUT_TV] = "Television", - [TM6000_INPUT_COMPOSITE1] = "Composite 1", - [TM6000_INPUT_COMPOSITE2] = "Composite 2", - [TM6000_INPUT_SVIDEO] = "S-Video", -}; - -static int vidioc_enum_input(struct file *file, void *priv, - struct v4l2_input *i) -{ - struct tm6000_fh *fh = priv; - struct tm6000_core *dev = fh->dev; - unsigned int n; - - n = i->index; - if (n >= 3) - return -EINVAL; - - if (!dev->vinput[n].type) - return -EINVAL; - - i->index = n; - - if (dev->vinput[n].type == TM6000_INPUT_TV) - i->type = V4L2_INPUT_TYPE_TUNER; - else - i->type = V4L2_INPUT_TYPE_CAMERA; - - strcpy(i->name, iname[dev->vinput[n].type]); - - i->std = TM6000_STD; - - return 0; -} - -static int vidioc_g_input(struct file *file, void *priv, unsigned int *i) -{ - struct tm6000_fh *fh = priv; - struct tm6000_core *dev = fh->dev; - - *i = dev->input; - - return 0; -} - -static int vidioc_s_input(struct file *file, void *priv, unsigned int i) -{ - struct tm6000_fh *fh = priv; - struct tm6000_core *dev = fh->dev; - int rc = 0; - - if (i >= 3) - return -EINVAL; - if (!dev->vinput[i].type) - return -EINVAL; - - dev->input = i; - - rc = vidioc_s_std(file, priv, &dev->vfd->current_norm); - - return rc; -} - -/* --- controls ---------------------------------------------- */ -static int vidioc_queryctrl(struct file *file, void *priv, - struct v4l2_queryctrl *qc) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(tm6000_qctrl); i++) - if (qc->id && qc->id == tm6000_qctrl[i].id) { - memcpy(qc, &(tm6000_qctrl[i]), - sizeof(*qc)); - return 0; - } - - return -EINVAL; -} - -static int vidioc_g_ctrl(struct file *file, void *priv, - struct v4l2_control *ctrl) -{ - struct tm6000_fh *fh = priv; - struct tm6000_core *dev = fh->dev; - int val; - - /* FIXME: Probably, those won't work! Maybe we need shadow regs */ - switch (ctrl->id) { - case V4L2_CID_CONTRAST: - val = tm6000_get_reg(dev, TM6010_REQ07_R08_LUMA_CONTRAST_ADJ, 0); - break; - case V4L2_CID_BRIGHTNESS: - val = tm6000_get_reg(dev, TM6010_REQ07_R09_LUMA_BRIGHTNESS_ADJ, 0); - return 0; - case V4L2_CID_SATURATION: - val = tm6000_get_reg(dev, TM6010_REQ07_R0A_CHROMA_SATURATION_ADJ, 0); - return 0; - case V4L2_CID_HUE: - val = tm6000_get_reg(dev, TM6010_REQ07_R0B_CHROMA_HUE_PHASE_ADJ, 0); - return 0; - case V4L2_CID_AUDIO_MUTE: - val = dev->ctl_mute; - return 0; - case V4L2_CID_AUDIO_VOLUME: - val = dev->ctl_volume; - return 0; - default: - return -EINVAL; - } - - if (val < 0) - return val; - - ctrl->value = val; - - return 0; -} -static int vidioc_s_ctrl(struct file *file, void *priv, - struct v4l2_control *ctrl) -{ - struct tm6000_fh *fh = priv; - struct tm6000_core *dev = fh->dev; - u8 val = ctrl->value; - - switch (ctrl->id) { - case V4L2_CID_CONTRAST: - tm6000_set_reg(dev, TM6010_REQ07_R08_LUMA_CONTRAST_ADJ, val); - return 0; - case V4L2_CID_BRIGHTNESS: - tm6000_set_reg(dev, TM6010_REQ07_R09_LUMA_BRIGHTNESS_ADJ, val); - return 0; - case V4L2_CID_SATURATION: - tm6000_set_reg(dev, TM6010_REQ07_R0A_CHROMA_SATURATION_ADJ, val); - return 0; - case V4L2_CID_HUE: - tm6000_set_reg(dev, TM6010_REQ07_R0B_CHROMA_HUE_PHASE_ADJ, val); - return 0; - case V4L2_CID_AUDIO_MUTE: - dev->ctl_mute = val; - tm6000_tvaudio_set_mute(dev, val); - return 0; - case V4L2_CID_AUDIO_VOLUME: - dev->ctl_volume = val; - tm6000_set_volume(dev, val); - return 0; - } - return -EINVAL; -} - -static int vidioc_g_tuner(struct file *file, void *priv, - struct v4l2_tuner *t) -{ - struct tm6000_fh *fh = priv; - struct tm6000_core *dev = fh->dev; - - if (unlikely(UNSET == dev->tuner_type)) - return -EINVAL; - if (0 != t->index) - return -EINVAL; - - strcpy(t->name, "Television"); - t->type = V4L2_TUNER_ANALOG_TV; - t->capability = V4L2_TUNER_CAP_NORM; - t->rangehigh = 0xffffffffUL; - t->rxsubchans = V4L2_TUNER_SUB_STEREO; - - v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, g_tuner, t); - - t->audmode = dev->amode; - - return 0; -} - -static int vidioc_s_tuner(struct file *file, void *priv, - struct v4l2_tuner *t) -{ - struct tm6000_fh *fh = priv; - struct tm6000_core *dev = fh->dev; - - if (UNSET == dev->tuner_type) - return -EINVAL; - if (0 != t->index) - return -EINVAL; - - dev->amode = t->audmode; - dprintk(dev, 3, "audio mode: %x\n", t->audmode); - - v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_tuner, t); - - return 0; -} - -static int vidioc_g_frequency(struct file *file, void *priv, - struct v4l2_frequency *f) -{ - struct tm6000_fh *fh = priv; - struct tm6000_core *dev = fh->dev; - - if (unlikely(UNSET == dev->tuner_type)) - return -EINVAL; - - f->type = fh->radio ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; - f->frequency = dev->freq; - - v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, g_frequency, f); - - return 0; -} - -static int vidioc_s_frequency(struct file *file, void *priv, - struct v4l2_frequency *f) -{ - struct tm6000_fh *fh = priv; - struct tm6000_core *dev = fh->dev; - - if (unlikely(UNSET == dev->tuner_type)) - return -EINVAL; - if (unlikely(f->tuner != 0)) - return -EINVAL; - if (0 == fh->radio && V4L2_TUNER_ANALOG_TV != f->type) - return -EINVAL; - if (1 == fh->radio && V4L2_TUNER_RADIO != f->type) - return -EINVAL; - - dev->freq = f->frequency; - v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_frequency, f); - - return 0; -} - -static int radio_querycap(struct file *file, void *priv, - struct v4l2_capability *cap) -{ - struct tm6000_fh *fh = file->private_data; - struct tm6000_core *dev = fh->dev; - - strcpy(cap->driver, "tm6000"); - strlcpy(cap->card, dev->name, sizeof(dev->name)); - sprintf(cap->bus_info, "USB%04x:%04x", - le16_to_cpu(dev->udev->descriptor.idVendor), - le16_to_cpu(dev->udev->descriptor.idProduct)); - cap->version = dev->dev_type; - cap->capabilities = V4L2_CAP_TUNER | - V4L2_CAP_AUDIO | - V4L2_CAP_RADIO | - V4L2_CAP_READWRITE | - V4L2_CAP_STREAMING; - - return 0; -} - -static int radio_g_tuner(struct file *file, void *priv, - struct v4l2_tuner *t) -{ - struct tm6000_fh *fh = file->private_data; - struct tm6000_core *dev = fh->dev; - - if (0 != t->index) - return -EINVAL; - - memset(t, 0, sizeof(*t)); - strcpy(t->name, "Radio"); - t->type = V4L2_TUNER_RADIO; - t->rxsubchans = V4L2_TUNER_SUB_STEREO; - - v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, g_tuner, t); - - return 0; -} - -static int radio_s_tuner(struct file *file, void *priv, - struct v4l2_tuner *t) -{ - struct tm6000_fh *fh = file->private_data; - struct tm6000_core *dev = fh->dev; - - if (0 != t->index) - return -EINVAL; - - v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_tuner, t); - - return 0; -} - -static int radio_enum_input(struct file *file, void *priv, - struct v4l2_input *i) -{ - struct tm6000_fh *fh = priv; - struct tm6000_core *dev = fh->dev; - - if (i->index != 0) - return -EINVAL; - - if (!dev->rinput.type) - return -EINVAL; - - strcpy(i->name, "Radio"); - i->type = V4L2_INPUT_TYPE_TUNER; - - return 0; -} - -static int radio_g_input(struct file *filp, void *priv, unsigned int *i) -{ - struct tm6000_fh *fh = priv; - struct tm6000_core *dev = fh->dev; - - if (dev->input != 5) - return -EINVAL; - - *i = dev->input - 5; - - return 0; -} - -static int radio_g_audio(struct file *file, void *priv, - struct v4l2_audio *a) -{ - memset(a, 0, sizeof(*a)); - strcpy(a->name, "Radio"); - return 0; -} - -static int radio_s_audio(struct file *file, void *priv, - struct v4l2_audio *a) -{ - return 0; -} - -static int radio_s_input(struct file *filp, void *priv, unsigned int i) -{ - struct tm6000_fh *fh = priv; - struct tm6000_core *dev = fh->dev; - - if (i) - return -EINVAL; - - if (!dev->rinput.type) - return -EINVAL; - - dev->input = i + 5; - - return 0; -} - -static int radio_s_std(struct file *file, void *fh, v4l2_std_id *norm) -{ - return 0; -} - -static int radio_queryctrl(struct file *file, void *priv, - struct v4l2_queryctrl *c) -{ - const struct v4l2_queryctrl *ctrl; - - if (c->id < V4L2_CID_BASE || - c->id >= V4L2_CID_LASTP1) - return -EINVAL; - if (c->id == V4L2_CID_AUDIO_MUTE) { - ctrl = ctrl_by_id(c->id); - *c = *ctrl; - } else - *c = no_ctrl; - - return 0; -} - -/* ------------------------------------------------------------------ - File operations for the device - ------------------------------------------------------------------*/ - -static int tm6000_open(struct file *file) -{ - struct video_device *vdev = video_devdata(file); - struct tm6000_core *dev = video_drvdata(file); - struct tm6000_fh *fh; - enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - int i, rc; - int radio = 0; - - printk(KERN_INFO "tm6000: open called (dev=%s)\n", - video_device_node_name(vdev)); - - dprintk(dev, V4L2_DEBUG_OPEN, "tm6000: open called (dev=%s)\n", - video_device_node_name(vdev)); - - switch (vdev->vfl_type) { - case VFL_TYPE_GRABBER: - type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - break; - case VFL_TYPE_VBI: - type = V4L2_BUF_TYPE_VBI_CAPTURE; - break; - case VFL_TYPE_RADIO: - radio = 1; - break; - } - - /* If more than one user, mutex should be added */ - dev->users++; - - dprintk(dev, V4L2_DEBUG_OPEN, "open dev=%s type=%s users=%d\n", - video_device_node_name(vdev), v4l2_type_names[type], - dev->users); - - /* allocate + initialize per filehandle data */ - fh = kzalloc(sizeof(*fh), GFP_KERNEL); - if (NULL == fh) { - dev->users--; - return -ENOMEM; - } - - file->private_data = fh; - fh->dev = dev; - fh->radio = radio; - dev->radio = radio; - fh->type = type; - dev->fourcc = format[0].fourcc; - - fh->fmt = format_by_fourcc(dev->fourcc); - - tm6000_get_std_res(dev); - - fh->width = dev->width; - fh->height = dev->height; - - dprintk(dev, V4L2_DEBUG_OPEN, "Open: fh=0x%08lx, dev=0x%08lx, " - "dev->vidq=0x%08lx\n", - (unsigned long)fh, (unsigned long)dev, (unsigned long)&dev->vidq); - dprintk(dev, V4L2_DEBUG_OPEN, "Open: list_empty " - "queued=%d\n", list_empty(&dev->vidq.queued)); - dprintk(dev, V4L2_DEBUG_OPEN, "Open: list_empty " - "active=%d\n", list_empty(&dev->vidq.active)); - - /* initialize hardware on analog mode */ - rc = tm6000_init_analog_mode(dev); - if (rc < 0) - return rc; - - if (dev->mode != TM6000_MODE_ANALOG) { - /* Put all controls at a sane state */ - for (i = 0; i < ARRAY_SIZE(tm6000_qctrl); i++) - qctl_regs[i] = tm6000_qctrl[i].default_value; - - dev->mode = TM6000_MODE_ANALOG; - } - - videobuf_queue_vmalloc_init(&fh->vb_vidq, &tm6000_video_qops, - NULL, &dev->slock, - fh->type, - V4L2_FIELD_INTERLACED, - sizeof(struct tm6000_buffer), fh, &dev->lock); - - if (fh->radio) { - dprintk(dev, V4L2_DEBUG_OPEN, "video_open: setting radio device\n"); - dev->input = 5; - tm6000_set_audio_rinput(dev); - v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_radio); - tm6000_prepare_isoc(dev); - tm6000_start_thread(dev); - } - - return 0; -} - -static ssize_t -tm6000_read(struct file *file, char __user *data, size_t count, loff_t *pos) -{ - struct tm6000_fh *fh = file->private_data; - - if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { - if (!res_get(fh->dev, fh, true)) - return -EBUSY; - - return videobuf_read_stream(&fh->vb_vidq, data, count, pos, 0, - file->f_flags & O_NONBLOCK); - } - return 0; -} - -static unsigned int -tm6000_poll(struct file *file, struct poll_table_struct *wait) -{ - struct tm6000_fh *fh = file->private_data; - struct tm6000_buffer *buf; - - if (V4L2_BUF_TYPE_VIDEO_CAPTURE != fh->type) - return POLLERR; - - if (!!is_res_streaming(fh->dev, fh)) - return POLLERR; - - if (!is_res_read(fh->dev, fh)) { - /* streaming capture */ - if (list_empty(&fh->vb_vidq.stream)) - return POLLERR; - buf = list_entry(fh->vb_vidq.stream.next, struct tm6000_buffer, vb.stream); - } else { - /* read() capture */ - return videobuf_poll_stream(file, &fh->vb_vidq, - wait); - } - poll_wait(file, &buf->vb.done, wait); - if (buf->vb.state == VIDEOBUF_DONE || - buf->vb.state == VIDEOBUF_ERROR) - return POLLIN | POLLRDNORM; - return 0; -} - -static int tm6000_release(struct file *file) -{ - struct tm6000_fh *fh = file->private_data; - struct tm6000_core *dev = fh->dev; - struct video_device *vdev = video_devdata(file); - - dprintk(dev, V4L2_DEBUG_OPEN, "tm6000: close called (dev=%s, users=%d)\n", - video_device_node_name(vdev), dev->users); - - dev->users--; - - res_free(dev, fh); - if (!dev->users) { - tm6000_uninit_isoc(dev); - videobuf_mmap_free(&fh->vb_vidq); - } - - kfree(fh); - - return 0; -} - -static int tm6000_mmap(struct file *file, struct vm_area_struct * vma) -{ - struct tm6000_fh *fh = file->private_data; - int ret; - - ret = videobuf_mmap_mapper(&fh->vb_vidq, vma); - - return ret; -} - -static struct v4l2_file_operations tm6000_fops = { - .owner = THIS_MODULE, - .open = tm6000_open, - .release = tm6000_release, - .unlocked_ioctl = video_ioctl2, /* V4L2 ioctl handler */ - .read = tm6000_read, - .poll = tm6000_poll, - .mmap = tm6000_mmap, -}; - -static const struct v4l2_ioctl_ops video_ioctl_ops = { - .vidioc_querycap = vidioc_querycap, - .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap, - .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap, - .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap, - .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap, - .vidioc_s_std = vidioc_s_std, - .vidioc_enum_input = vidioc_enum_input, - .vidioc_g_input = vidioc_g_input, - .vidioc_s_input = vidioc_s_input, - .vidioc_queryctrl = vidioc_queryctrl, - .vidioc_g_ctrl = vidioc_g_ctrl, - .vidioc_s_ctrl = vidioc_s_ctrl, - .vidioc_g_tuner = vidioc_g_tuner, - .vidioc_s_tuner = vidioc_s_tuner, - .vidioc_g_frequency = vidioc_g_frequency, - .vidioc_s_frequency = vidioc_s_frequency, - .vidioc_streamon = vidioc_streamon, - .vidioc_streamoff = vidioc_streamoff, - .vidioc_reqbufs = vidioc_reqbufs, - .vidioc_querybuf = vidioc_querybuf, - .vidioc_qbuf = vidioc_qbuf, - .vidioc_dqbuf = vidioc_dqbuf, -}; - -static struct video_device tm6000_template = { - .name = "tm6000", - .fops = &tm6000_fops, - .ioctl_ops = &video_ioctl_ops, - .release = video_device_release, - .tvnorms = TM6000_STD, - .current_norm = V4L2_STD_NTSC_M, -}; - -static const struct v4l2_file_operations radio_fops = { - .owner = THIS_MODULE, - .open = tm6000_open, - .release = tm6000_release, - .unlocked_ioctl = video_ioctl2, -}; - -static const struct v4l2_ioctl_ops radio_ioctl_ops = { - .vidioc_querycap = radio_querycap, - .vidioc_g_tuner = radio_g_tuner, - .vidioc_enum_input = radio_enum_input, - .vidioc_g_audio = radio_g_audio, - .vidioc_s_tuner = radio_s_tuner, - .vidioc_s_audio = radio_s_audio, - .vidioc_s_input = radio_s_input, - .vidioc_s_std = radio_s_std, - .vidioc_queryctrl = radio_queryctrl, - .vidioc_g_input = radio_g_input, - .vidioc_g_ctrl = vidioc_g_ctrl, - .vidioc_s_ctrl = vidioc_s_ctrl, - .vidioc_g_frequency = vidioc_g_frequency, - .vidioc_s_frequency = vidioc_s_frequency, -}; - -struct video_device tm6000_radio_template = { - .name = "tm6000", - .fops = &radio_fops, - .ioctl_ops = &radio_ioctl_ops, -}; - -/* ----------------------------------------------------------------- - * Initialization and module stuff - * ------------------------------------------------------------------ - */ - -static struct video_device *vdev_init(struct tm6000_core *dev, - const struct video_device - *template, const char *type_name) -{ - struct video_device *vfd; - - vfd = video_device_alloc(); - if (NULL == vfd) - return NULL; - - *vfd = *template; - vfd->v4l2_dev = &dev->v4l2_dev; - vfd->release = video_device_release; - vfd->debug = tm6000_debug; - vfd->lock = &dev->lock; - - snprintf(vfd->name, sizeof(vfd->name), "%s %s", dev->name, type_name); - - video_set_drvdata(vfd, dev); - return vfd; -} - -int tm6000_v4l2_register(struct tm6000_core *dev) -{ - int ret = -1; - - dev->vfd = vdev_init(dev, &tm6000_template, "video"); - - if (!dev->vfd) { - printk(KERN_INFO "%s: can't register video device\n", - dev->name); - return -ENOMEM; - } - - /* init video dma queues */ - INIT_LIST_HEAD(&dev->vidq.active); - INIT_LIST_HEAD(&dev->vidq.queued); - - ret = video_register_device(dev->vfd, VFL_TYPE_GRABBER, video_nr); - - if (ret < 0) { - printk(KERN_INFO "%s: can't register video device\n", - dev->name); - return ret; - } - - printk(KERN_INFO "%s: registered device %s\n", - dev->name, video_device_node_name(dev->vfd)); - - if (dev->caps.has_radio) { - dev->radio_dev = vdev_init(dev, &tm6000_radio_template, - "radio"); - if (!dev->radio_dev) { - printk(KERN_INFO "%s: can't register radio device\n", - dev->name); - return ret; /* FIXME release resource */ - } - - ret = video_register_device(dev->radio_dev, VFL_TYPE_RADIO, - radio_nr); - if (ret < 0) { - printk(KERN_INFO "%s: can't register radio device\n", - dev->name); - return ret; /* FIXME release resource */ - } - - printk(KERN_INFO "%s: registered device %s\n", - dev->name, video_device_node_name(dev->radio_dev)); - } - - printk(KERN_INFO "Trident TVMaster TM5600/TM6000/TM6010 USB2 board (Load status: %d)\n", ret); - return ret; -} - -int tm6000_v4l2_unregister(struct tm6000_core *dev) -{ - video_unregister_device(dev->vfd); - - if (dev->radio_dev) { - if (video_is_registered(dev->radio_dev)) - video_unregister_device(dev->radio_dev); - else - video_device_release(dev->radio_dev); - dev->radio_dev = NULL; - } - - return 0; -} - -int tm6000_v4l2_exit(void) -{ - return 0; -} - -module_param(video_nr, int, 0); -MODULE_PARM_DESC(video_nr, "Allow changing video device number"); - -module_param_named(debug, tm6000_debug, int, 0444); -MODULE_PARM_DESC(debug, "activates debug info"); - -module_param(vid_limit, int, 0644); -MODULE_PARM_DESC(vid_limit, "capture memory limit in megabytes"); - diff --git a/drivers/staging/tm6000/tm6000.h b/drivers/staging/tm6000/tm6000.h deleted file mode 100644 index c56da628dbef..000000000000 --- a/drivers/staging/tm6000/tm6000.h +++ /dev/null @@ -1,395 +0,0 @@ -/* - * tm6000.h - driver for TM5600/TM6000/TM6010 USB video capture devices - * - * Copyright (C) 2006-2007 Mauro Carvalho Chehab <mchehab@infradead.org> - * - * Copyright (C) 2007 Michel Ludwig <michel.ludwig@gmail.com> - * - DVB-T support - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation version 2 - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -/* Use the tm6000-hack, instead of the proper initialization code i*/ -/* #define HACK 1 */ - -#include <linux/videodev2.h> -#include <media/v4l2-common.h> -#include <media/videobuf-vmalloc.h> -#include "tm6000-usb-isoc.h" -#include <linux/i2c.h> -#include <linux/mutex.h> -#include <media/v4l2-device.h> -#include <linux/version.h> -#include <linux/dvb/frontend.h> -#include "dvb_demux.h" -#include "dvb_frontend.h" -#include "dmxdev.h" - -#define TM6000_VERSION KERNEL_VERSION(0, 0, 2) - -/* Inputs */ -enum tm6000_itype { - TM6000_INPUT_TV = 1, - TM6000_INPUT_COMPOSITE1, - TM6000_INPUT_COMPOSITE2, - TM6000_INPUT_SVIDEO, - TM6000_INPUT_DVB, - TM6000_INPUT_RADIO, -}; - -enum tm6000_mux { - TM6000_VMUX_VIDEO_A = 1, - TM6000_VMUX_VIDEO_B, - TM6000_VMUX_VIDEO_AB, - TM6000_AMUX_ADC1, - TM6000_AMUX_ADC2, - TM6000_AMUX_SIF1, - TM6000_AMUX_SIF2, - TM6000_AMUX_I2S, -}; - -enum tm6000_devtype { - TM6000 = 0, - TM5600, - TM6010, -}; - -struct tm6000_input { - enum tm6000_itype type; - enum tm6000_mux vmux; - enum tm6000_mux amux; - unsigned int v_gpio; - unsigned int a_gpio; -}; - -/* ------------------------------------------------------------------ - * Basic structures - * ------------------------------------------------------------------ - */ - -struct tm6000_fmt { - char *name; - u32 fourcc; /* v4l2 format id */ - int depth; -}; - -/* buffer for one video frame */ -struct tm6000_buffer { - /* common v4l buffer stuff -- must be first */ - struct videobuf_buffer vb; - - struct tm6000_fmt *fmt; -}; - -struct tm6000_dmaqueue { - struct list_head active; - struct list_head queued; - - /* thread for generating video stream*/ - struct task_struct *kthread; - wait_queue_head_t wq; - /* Counters to control fps rate */ - int frame; - int ini_jiffies; -}; - -/* device states */ -enum tm6000_core_state { - DEV_INITIALIZED = 0x01, - DEV_DISCONNECTED = 0x02, - DEV_MISCONFIGURED = 0x04, -}; - -/* io methods */ -enum tm6000_io_method { - IO_NONE, - IO_READ, - IO_MMAP, -}; - -enum tm6000_mode { - TM6000_MODE_UNKNOWN = 0, - TM6000_MODE_ANALOG, - TM6000_MODE_DIGITAL, -}; - -struct tm6000_gpio { - int tuner_reset; - int tuner_on; - int demod_reset; - int demod_on; - int power_led; - int dvb_led; - int ir; -}; - -struct tm6000_capabilities { - unsigned int has_tuner:1; - unsigned int has_tda9874:1; - unsigned int has_dvb:1; - unsigned int has_zl10353:1; - unsigned int has_eeprom:1; - unsigned int has_remote:1; - unsigned int has_radio:1; -}; - -struct tm6000_dvb { - struct dvb_adapter adapter; - struct dvb_demux demux; - struct dvb_frontend *frontend; - struct dmxdev dmxdev; - unsigned int streams; - struct urb *bulk_urb; - struct mutex mutex; -}; - -struct snd_tm6000_card { - struct snd_card *card; - spinlock_t reg_lock; - struct tm6000_core *core; - struct snd_pcm_substream *substream; - - /* temporary data for buffer fill processing */ - unsigned buf_pos; - unsigned period_pos; -}; - -struct tm6000_endpoint { - struct usb_host_endpoint *endp; - __u8 bInterfaceNumber; - __u8 bAlternateSetting; - unsigned maxsize; -}; - -struct tm6000_core { - /* generic device properties */ - char name[30]; /* name (including minor) of the device */ - int model; /* index in the device_data struct */ - int devno; /* marks the number of this device */ - enum tm6000_devtype dev_type; /* type of device */ - unsigned char eedata[256]; /* Eeprom data */ - unsigned eedata_size; /* Size of the eeprom info */ - - v4l2_std_id norm; /* Current norm */ - int width, height; /* Selected resolution */ - - enum tm6000_core_state state; - - /* Device Capabilities*/ - struct tm6000_capabilities caps; - - /* Tuner configuration */ - int tuner_type; /* type of the tuner */ - int tuner_addr; /* tuner address */ - - struct tm6000_gpio gpio; - - char *ir_codes; - - __u8 radio; - - /* Demodulator configuration */ - int demod_addr; /* demodulator address */ - - int audio_bitrate; - /* i2c i/o */ - struct i2c_adapter i2c_adap; - struct i2c_client i2c_client; - - - /* extension */ - struct list_head devlist; - - /* video for linux */ - int users; - - /* various device info */ - struct tm6000_fh *resources; /* Points to fh that is streaming */ - bool is_res_read; - - struct video_device *vfd; - struct video_device *radio_dev; - struct tm6000_dmaqueue vidq; - struct v4l2_device v4l2_dev; - - int input; - struct tm6000_input vinput[3]; /* video input */ - struct tm6000_input rinput; /* radio input */ - - int freq; - unsigned int fourcc; - - enum tm6000_mode mode; - - int ctl_mute; /* audio */ - int ctl_volume; - int amode; - - /* DVB-T support */ - struct tm6000_dvb *dvb; - - /* audio support */ - struct snd_tm6000_card *adev; - struct work_struct wq_trigger; /* Trigger to start/stop audio for alsa module */ - atomic_t stream_started; /* stream should be running if true */ - - struct tm6000_IR *ir; - - /* locks */ - struct mutex lock; - - /* usb transfer */ - struct usb_device *udev; /* the usb device */ - - struct tm6000_endpoint bulk_in, bulk_out, isoc_in, isoc_out; - struct tm6000_endpoint int_in, int_out; - - /* scaler!=0 if scaler is active*/ - int scaler; - - /* Isoc control struct */ - struct usb_isoc_ctl isoc_ctl; - - spinlock_t slock; -}; - -enum tm6000_ops_type { - TM6000_AUDIO = 0x10, - TM6000_DVB = 0x20, -}; - -struct tm6000_ops { - struct list_head next; - char *name; - enum tm6000_ops_type type; - int (*init)(struct tm6000_core *); - int (*fini)(struct tm6000_core *); - int (*fillbuf)(struct tm6000_core *, char *buf, int size); -}; - -struct tm6000_fh { - struct tm6000_core *dev; - unsigned int radio; - - /* video capture */ - struct tm6000_fmt *fmt; - unsigned int width, height; - struct videobuf_queue vb_vidq; - - enum v4l2_buf_type type; -}; - -#define TM6000_STD (V4L2_STD_PAL|V4L2_STD_PAL_N|V4L2_STD_PAL_Nc| \ - V4L2_STD_PAL_M|V4L2_STD_PAL_60|V4L2_STD_NTSC_M| \ - V4L2_STD_NTSC_M_JP|V4L2_STD_SECAM) - -/* In tm6000-cards.c */ - -int tm6000_tuner_callback(void *ptr, int component, int command, int arg); -int tm6000_xc5000_callback(void *ptr, int component, int command, int arg); -int tm6000_cards_setup(struct tm6000_core *dev); -void tm6000_flash_led(struct tm6000_core *dev, u8 state); - -/* In tm6000-core.c */ - -int tm6000_read_write_usb(struct tm6000_core *dev, u8 reqtype, u8 req, - u16 value, u16 index, u8 *buf, u16 len); -int tm6000_get_reg(struct tm6000_core *dev, u8 req, u16 value, u16 index); -int tm6000_get_reg16(struct tm6000_core *dev, u8 req, u16 value, u16 index); -int tm6000_get_reg32(struct tm6000_core *dev, u8 req, u16 value, u16 index); -int tm6000_set_reg(struct tm6000_core *dev, u8 req, u16 value, u16 index); -int tm6000_set_reg_mask(struct tm6000_core *dev, u8 req, u16 value, - u16 index, u16 mask); -int tm6000_i2c_reset(struct tm6000_core *dev, u16 tsleep); -int tm6000_init(struct tm6000_core *dev); - -int tm6000_init_analog_mode(struct tm6000_core *dev); -int tm6000_init_digital_mode(struct tm6000_core *dev); -int tm6000_set_audio_bitrate(struct tm6000_core *dev, int bitrate); -int tm6000_set_audio_rinput(struct tm6000_core *dev); -int tm6000_tvaudio_set_mute(struct tm6000_core *dev, u8 mute); -void tm6000_set_volume(struct tm6000_core *dev, int vol); - -int tm6000_v4l2_register(struct tm6000_core *dev); -int tm6000_v4l2_unregister(struct tm6000_core *dev); -int tm6000_v4l2_exit(void); -void tm6000_set_fourcc_format(struct tm6000_core *dev); - -void tm6000_remove_from_devlist(struct tm6000_core *dev); -void tm6000_add_into_devlist(struct tm6000_core *dev); -int tm6000_register_extension(struct tm6000_ops *ops); -void tm6000_unregister_extension(struct tm6000_ops *ops); -void tm6000_init_extension(struct tm6000_core *dev); -void tm6000_close_extension(struct tm6000_core *dev); -int tm6000_call_fillbuf(struct tm6000_core *dev, enum tm6000_ops_type type, - char *buf, int size); - - -/* In tm6000-stds.c */ -void tm6000_get_std_res(struct tm6000_core *dev); -int tm6000_set_standard(struct tm6000_core *dev); - -/* In tm6000-i2c.c */ -int tm6000_i2c_register(struct tm6000_core *dev); -int tm6000_i2c_unregister(struct tm6000_core *dev); - -/* In tm6000-queue.c */ - -int tm6000_v4l2_mmap(struct file *filp, struct vm_area_struct *vma); - -int tm6000_vidioc_streamon(struct file *file, void *priv, - enum v4l2_buf_type i); -int tm6000_vidioc_streamoff(struct file *file, void *priv, - enum v4l2_buf_type i); -int tm6000_vidioc_reqbufs(struct file *file, void *priv, - struct v4l2_requestbuffers *rb); -int tm6000_vidioc_querybuf(struct file *file, void *priv, - struct v4l2_buffer *b); -int tm6000_vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *b); -int tm6000_vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b); -ssize_t tm6000_v4l2_read(struct file *filp, char __user * buf, size_t count, - loff_t *f_pos); -unsigned int tm6000_v4l2_poll(struct file *file, - struct poll_table_struct *wait); -int tm6000_queue_init(struct tm6000_core *dev); - -/* In tm6000-alsa.c */ -/*int tm6000_audio_init(struct tm6000_core *dev, int idx);*/ - -/* In tm6000-input.c */ -int tm6000_ir_init(struct tm6000_core *dev); -int tm6000_ir_fini(struct tm6000_core *dev); -void tm6000_ir_wait(struct tm6000_core *dev, u8 state); -int tm6000_ir_int_start(struct tm6000_core *dev); -void tm6000_ir_int_stop(struct tm6000_core *dev); - -/* Debug stuff */ - -extern int tm6000_debug; - -#define dprintk(dev, level, fmt, arg...) do {\ - if (tm6000_debug & level) \ - printk(KERN_INFO "(%lu) %s %s :"fmt, jiffies, \ - dev->name, __FUNCTION__ , ##arg); } while (0) - -#define V4L2_DEBUG_REG 0x0004 -#define V4L2_DEBUG_I2C 0x0008 -#define V4L2_DEBUG_QUEUE 0x0010 -#define V4L2_DEBUG_ISOC 0x0020 -#define V4L2_DEBUG_RES_LOCK 0x0040 /* Resource locking */ -#define V4L2_DEBUG_OPEN 0x0080 /* video open/close debug */ - -#define tm6000_err(fmt, arg...) do {\ - printk(KERN_ERR "tm6000 %s :"fmt, \ - __FUNCTION__ , ##arg); } while (0) |