diff options
Diffstat (limited to 'drivers/media/video/cx18')
45 files changed, 0 insertions, 11741 deletions
diff --git a/drivers/media/video/cx18/Kconfig b/drivers/media/video/cx18/Kconfig deleted file mode 100644 index 8940b5387de..00000000000 --- a/drivers/media/video/cx18/Kconfig +++ /dev/null @@ -1,21 +0,0 @@ -config VIDEO_CX18 - tristate "Conexant cx23418 MPEG encoder support" - depends on VIDEO_V4L2 && DVB_CORE && PCI && I2C && EXPERIMENTAL - depends on INPUT # due to VIDEO_IR - select I2C_ALGOBIT - select VIDEO_IR - select VIDEO_TUNER - select VIDEO_TVEEPROM - select VIDEO_CX2341X - select VIDEO_CS5345 - select DVB_S5H1409 if !DVB_FE_CUSTOMISE - select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMIZE - ---help--- - This is a video4linux driver for Conexant cx23418 based - PCI combo video recorder devices. - - This is used in devices such as the Hauppauge HVR-1600 - cards. - - To compile this driver as a module, choose M here: the - module will be called cx18. diff --git a/drivers/media/video/cx18/Makefile b/drivers/media/video/cx18/Makefile deleted file mode 100644 index f7bf0edf93f..00000000000 --- a/drivers/media/video/cx18/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -cx18-objs := cx18-driver.o cx18-cards.o cx18-i2c.o cx18-firmware.o cx18-gpio.o \ - cx18-queue.o cx18-streams.o cx18-fileops.o cx18-ioctl.o cx18-controls.o \ - cx18-mailbox.o cx18-vbi.o cx18-audio.o cx18-video.o cx18-irq.o \ - cx18-av-core.o cx18-av-audio.o cx18-av-firmware.o cx18-av-vbi.o cx18-scb.o \ - cx18-dvb.o cx18-io.o - -obj-$(CONFIG_VIDEO_CX18) += cx18.o - -EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core -EXTRA_CFLAGS += -Idrivers/media/dvb/frontends -EXTRA_CFLAGS += -Idrivers/media/common/tuners diff --git a/drivers/media/video/cx18/cx18-audio.c b/drivers/media/video/cx18/cx18-audio.c deleted file mode 100644 index 57beddf0af4..00000000000 --- a/drivers/media/video/cx18/cx18-audio.c +++ /dev/null @@ -1,87 +0,0 @@ -/* - * cx18 audio-related functions - * - * Derived from ivtv-audio.c - * - * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> - * - * 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., 59 Temple Place, Suite 330, Boston, MA - * 02111-1307 USA - */ - -#include "cx18-driver.h" -#include "cx18-io.h" -#include "cx18-i2c.h" -#include "cx18-cards.h" -#include "cx18-audio.h" - -#define CX18_AUDIO_ENABLE 0xc72014 - -/* Selects the audio input and output according to the current - settings. */ -int cx18_audio_set_io(struct cx18 *cx) -{ - struct v4l2_routing route; - u32 audio_input; - u32 val; - int mux_input; - int err; - - /* Determine which input to use */ - if (test_bit(CX18_F_I_RADIO_USER, &cx->i_flags)) { - audio_input = cx->card->radio_input.audio_input; - mux_input = cx->card->radio_input.muxer_input; - } else { - audio_input = - cx->card->audio_inputs[cx->audio_input].audio_input; - mux_input = - cx->card->audio_inputs[cx->audio_input].muxer_input; - } - - /* handle muxer chips */ - route.input = mux_input; - route.output = 0; - cx18_i2c_hw(cx, cx->card->hw_muxer, VIDIOC_INT_S_AUDIO_ROUTING, &route); - - route.input = audio_input; - err = cx18_i2c_hw(cx, cx->card->hw_audio_ctrl, - VIDIOC_INT_S_AUDIO_ROUTING, &route); - if (err) - return err; - - val = cx18_read_reg(cx, CX18_AUDIO_ENABLE) & ~0x30; - val |= (audio_input > CX18_AV_AUDIO_SERIAL2) ? 0x20 : - (audio_input << 4); - cx18_write_reg(cx, val | 0xb00, CX18_AUDIO_ENABLE); - cx18_vapi(cx, CX18_APU_RESETAI, 1, 0); - return 0; -} - -void cx18_audio_set_route(struct cx18 *cx, struct v4l2_routing *route) -{ - cx18_i2c_hw(cx, cx->card->hw_audio_ctrl, - VIDIOC_INT_S_AUDIO_ROUTING, route); -} - -void cx18_audio_set_audio_clock_freq(struct cx18 *cx, u8 freq) -{ - static u32 freqs[3] = { 44100, 48000, 32000 }; - - /* The audio clock of the digitizer must match the codec sample - rate otherwise you get some very strange effects. */ - if (freq > 2) - return; - cx18_call_i2c_clients(cx, VIDIOC_INT_AUDIO_CLOCK_FREQ, &freqs[freq]); -} diff --git a/drivers/media/video/cx18/cx18-audio.h b/drivers/media/video/cx18/cx18-audio.h deleted file mode 100644 index cb569a69379..00000000000 --- a/drivers/media/video/cx18/cx18-audio.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * cx18 audio-related functions - * - * Derived from ivtv-audio.c - * - * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> - * - * 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., 59 Temple Place, Suite 330, Boston, MA - * 02111-1307 USA - */ - -int cx18_audio_set_io(struct cx18 *cx); -void cx18_audio_set_route(struct cx18 *cx, struct v4l2_routing *route); -void cx18_audio_set_audio_clock_freq(struct cx18 *cx, u8 freq); diff --git a/drivers/media/video/cx18/cx18-av-audio.c b/drivers/media/video/cx18/cx18-av-audio.c deleted file mode 100644 index a2f0ad57043..00000000000 --- a/drivers/media/video/cx18/cx18-av-audio.c +++ /dev/null @@ -1,545 +0,0 @@ -/* - * cx18 ADEC audio functions - * - * Derived from cx25840-audio.c - * - * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> - * Copyright (C) 2008 Andy Walls <awalls@radix.net> - * - * 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., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -#include "cx18-driver.h" - -static int set_audclk_freq(struct cx18 *cx, u32 freq) -{ - struct cx18_av_state *state = &cx->av_state; - - if (freq != 32000 && freq != 44100 && freq != 48000) - return -EINVAL; - - /* - * The PLL parameters are based on the external crystal frequency that - * would ideally be: - * - * NTSC Color subcarrier freq * 8 = - * 4.5 MHz/286 * 455/2 * 8 = 28.63636363... MHz - * - * The accidents of history and rationale that explain from where this - * combination of magic numbers originate can be found in: - * - * [1] Abrahams, I. C., "Choice of Chrominance Subcarrier Frequency in - * the NTSC Standards", Proceedings of the I-R-E, January 1954, pp 79-80 - * - * [2] Abrahams, I. C., "The 'Frequency Interleaving' Principle in the - * NTSC Standards", Proceedings of the I-R-E, January 1954, pp 81-83 - * - * As Mike Bradley has rightly pointed out, it's not the exact crystal - * frequency that matters, only that all parts of the driver and - * firmware are using the same value (close to the ideal value). - * - * Since I have a strong suspicion that, if the firmware ever assumes a - * crystal value at all, it will assume 28.636360 MHz, the crystal - * freq used in calculations in this driver will be: - * - * xtal_freq = 28.636360 MHz - * - * an error of less than 0.13 ppm which is way, way better than any off - * the shelf crystal will have for accuracy anyway. - * - * Below I aim to run the PLLs' VCOs near 400 MHz to minimze error. - * - * Many thanks to Jeff Campbell and Mike Bradley for their extensive - * investigation, experimentation, testing, and suggested solutions of - * of audio/video sync problems with SVideo and CVBS captures. - */ - - if (state->aud_input > CX18_AV_AUDIO_SERIAL2) { - switch (freq) { - case 32000: - /* - * VID_PLL Integer = 0x0f, VID_PLL Post Divider = 0x04 - * AUX_PLL Integer = 0x0d, AUX PLL Post Divider = 0x20 - */ - cx18_av_write4(cx, 0x108, 0x200d040f); - - /* VID_PLL Fraction = 0x2be2fe */ - /* xtal * 0xf.15f17f0/4 = 108 MHz: 432 MHz pre-postdiv*/ - cx18_av_write4(cx, 0x10c, 0x002be2fe); - - /* AUX_PLL Fraction = 0x176740c */ - /* xtal * 0xd.bb3a060/0x20 = 32000 * 384: 393 MHz p-pd*/ - cx18_av_write4(cx, 0x110, 0x0176740c); - - /* src3/4/6_ctl */ - /* 0x1.f77f = (4 * xtal/8*2/455) / 32000 */ - cx18_av_write4(cx, 0x900, 0x0801f77f); - cx18_av_write4(cx, 0x904, 0x0801f77f); - cx18_av_write4(cx, 0x90c, 0x0801f77f); - - /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x20 */ - cx18_av_write(cx, 0x127, 0x60); - - /* AUD_COUNT = 0x2fff = 8 samples * 4 * 384 - 1 */ - cx18_av_write4(cx, 0x12c, 0x11202fff); - - /* - * EN_AV_LOCK = 0 - * VID_COUNT = 0x0d2ef8 = 107999.000 * 8 = - * ((8 samples/32,000) * (13,500,000 * 8) * 4 - 1) * 8 - */ - cx18_av_write4(cx, 0x128, 0xa00d2ef8); - break; - - case 44100: - /* - * VID_PLL Integer = 0x0f, VID_PLL Post Divider = 0x04 - * AUX_PLL Integer = 0x0e, AUX PLL Post Divider = 0x18 - */ - cx18_av_write4(cx, 0x108, 0x180e040f); - - /* VID_PLL Fraction = 0x2be2fe */ - /* xtal * 0xf.15f17f0/4 = 108 MHz: 432 MHz pre-postdiv*/ - cx18_av_write4(cx, 0x10c, 0x002be2fe); - - /* AUX_PLL Fraction = 0x062a1f2 */ - /* xtal * 0xe.3150f90/0x18 = 44100 * 384: 406 MHz p-pd*/ - cx18_av_write4(cx, 0x110, 0x0062a1f2); - - /* src3/4/6_ctl */ - /* 0x1.6d59 = (4 * xtal/8*2/455) / 44100 */ - cx18_av_write4(cx, 0x900, 0x08016d59); - cx18_av_write4(cx, 0x904, 0x08016d59); - cx18_av_write4(cx, 0x90c, 0x08016d59); - - /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x18 */ - cx18_av_write(cx, 0x127, 0x58); - - /* AUD_COUNT = 0x92ff = 49 samples * 2 * 384 - 1 */ - cx18_av_write4(cx, 0x12c, 0x112092ff); - - /* - * EN_AV_LOCK = 0 - * VID_COUNT = 0x1d4bf8 = 239999.000 * 8 = - * ((49 samples/44,100) * (13,500,000 * 8) * 2 - 1) * 8 - */ - cx18_av_write4(cx, 0x128, 0xa01d4bf8); - break; - - case 48000: - /* - * VID_PLL Integer = 0x0f, VID_PLL Post Divider = 0x04 - * AUX_PLL Integer = 0x0e, AUX PLL Post Divider = 0x16 - */ - cx18_av_write4(cx, 0x108, 0x160e040f); - - /* VID_PLL Fraction = 0x2be2fe */ - /* xtal * 0xf.15f17f0/4 = 108 MHz: 432 MHz pre-postdiv*/ - cx18_av_write4(cx, 0x10c, 0x002be2fe); - - /* AUX_PLL Fraction = 0x05227ad */ - /* xtal * 0xe.2913d68/0x16 = 48000 * 384: 406 MHz p-pd*/ - cx18_av_write4(cx, 0x110, 0x005227ad); - - /* src3/4/6_ctl */ - /* 0x1.4faa = (4 * xtal/8*2/455) / 48000 */ - cx18_av_write4(cx, 0x900, 0x08014faa); - cx18_av_write4(cx, 0x904, 0x08014faa); - cx18_av_write4(cx, 0x90c, 0x08014faa); - - /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x16 */ - cx18_av_write(cx, 0x127, 0x56); - - /* AUD_COUNT = 0x5fff = 4 samples * 16 * 384 - 1 */ - cx18_av_write4(cx, 0x12c, 0x11205fff); - - /* - * EN_AV_LOCK = 0 - * VID_COUNT = 0x1193f8 = 143999.000 * 8 = - * ((4 samples/48,000) * (13,500,000 * 8) * 16 - 1) * 8 - */ - cx18_av_write4(cx, 0x128, 0xa01193f8); - break; - } - } else { - switch (freq) { - case 32000: - /* - * VID_PLL Integer = 0x0f, VID_PLL Post Divider = 0x04 - * AUX_PLL Integer = 0x0d, AUX PLL Post Divider = 0x30 - */ - cx18_av_write4(cx, 0x108, 0x300d040f); - - /* VID_PLL Fraction = 0x2be2fe */ - /* xtal * 0xf.15f17f0/4 = 108 MHz: 432 MHz pre-postdiv*/ - cx18_av_write4(cx, 0x10c, 0x002be2fe); - - /* AUX_PLL Fraction = 0x176740c */ - /* xtal * 0xd.bb3a060/0x30 = 32000 * 256: 393 MHz p-pd*/ - cx18_av_write4(cx, 0x110, 0x0176740c); - - /* src1_ctl */ - /* 0x1.0000 = 32000/32000 */ - cx18_av_write4(cx, 0x8f8, 0x08010000); - - /* src3/4/6_ctl */ - /* 0x2.0000 = 2 * (32000/32000) */ - cx18_av_write4(cx, 0x900, 0x08020000); - cx18_av_write4(cx, 0x904, 0x08020000); - cx18_av_write4(cx, 0x90c, 0x08020000); - - /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x30 */ - cx18_av_write(cx, 0x127, 0x70); - - /* AUD_COUNT = 0x1fff = 8 samples * 4 * 256 - 1 */ - cx18_av_write4(cx, 0x12c, 0x11201fff); - - /* - * EN_AV_LOCK = 0 - * VID_COUNT = 0x0d2ef8 = 107999.000 * 8 = - * ((8 samples/32,000) * (13,500,000 * 8) * 4 - 1) * 8 - */ - cx18_av_write4(cx, 0x128, 0xa00d2ef8); - break; - - case 44100: - /* - * VID_PLL Integer = 0x0f, VID_PLL Post Divider = 0x04 - * AUX_PLL Integer = 0x0e, AUX PLL Post Divider = 0x24 - */ - cx18_av_write4(cx, 0x108, 0x240e040f); - - /* VID_PLL Fraction = 0x2be2fe */ - /* xtal * 0xf.15f17f0/4 = 108 MHz: 432 MHz pre-postdiv*/ - cx18_av_write4(cx, 0x10c, 0x002be2fe); - - /* AUX_PLL Fraction = 0x062a1f2 */ - /* xtal * 0xe.3150f90/0x24 = 44100 * 256: 406 MHz p-pd*/ - cx18_av_write4(cx, 0x110, 0x0062a1f2); - - /* src1_ctl */ - /* 0x1.60cd = 44100/32000 */ - cx18_av_write4(cx, 0x8f8, 0x080160cd); - - /* src3/4/6_ctl */ - /* 0x1.7385 = 2 * (32000/44100) */ - cx18_av_write4(cx, 0x900, 0x08017385); - cx18_av_write4(cx, 0x904, 0x08017385); - cx18_av_write4(cx, 0x90c, 0x08017385); - - /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x24 */ - cx18_av_write(cx, 0x127, 0x64); - - /* AUD_COUNT = 0x61ff = 49 samples * 2 * 256 - 1 */ - cx18_av_write4(cx, 0x12c, 0x112061ff); - - /* - * EN_AV_LOCK = 0 - * VID_COUNT = 0x1d4bf8 = 239999.000 * 8 = - * ((49 samples/44,100) * (13,500,000 * 8) * 2 - 1) * 8 - */ - cx18_av_write4(cx, 0x128, 0xa01d4bf8); - break; - - case 48000: - /* - * VID_PLL Integer = 0x0f, VID_PLL Post Divider = 0x04 - * AUX_PLL Integer = 0x0d, AUX PLL Post Divider = 0x20 - */ - cx18_av_write4(cx, 0x108, 0x200d040f); - - /* VID_PLL Fraction = 0x2be2fe */ - /* xtal * 0xf.15f17f0/4 = 108 MHz: 432 MHz pre-postdiv*/ - cx18_av_write4(cx, 0x10c, 0x002be2fe); - - /* AUX_PLL Fraction = 0x176740c */ - /* xtal * 0xd.bb3a060/0x20 = 48000 * 256: 393 MHz p-pd*/ - cx18_av_write4(cx, 0x110, 0x0176740c); - - /* src1_ctl */ - /* 0x1.8000 = 48000/32000 */ - cx18_av_write4(cx, 0x8f8, 0x08018000); - - /* src3/4/6_ctl */ - /* 0x1.5555 = 2 * (32000/48000) */ - cx18_av_write4(cx, 0x900, 0x08015555); - cx18_av_write4(cx, 0x904, 0x08015555); - cx18_av_write4(cx, 0x90c, 0x08015555); - - /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x20 */ - cx18_av_write(cx, 0x127, 0x60); - - /* AUD_COUNT = 0x3fff = 4 samples * 16 * 256 - 1 */ - cx18_av_write4(cx, 0x12c, 0x11203fff); - - /* - * EN_AV_LOCK = 0 - * VID_COUNT = 0x1193f8 = 143999.000 * 8 = - * ((4 samples/48,000) * (13,500,000 * 8) * 16 - 1) * 8 - */ - cx18_av_write4(cx, 0x128, 0xa01193f8); - break; - } - } - - state->audclk_freq = freq; - - return 0; -} - -void cx18_av_audio_set_path(struct cx18 *cx) -{ - struct cx18_av_state *state = &cx->av_state; - u8 v; - - /* stop microcontroller */ - v = cx18_av_read(cx, 0x803) & ~0x10; - cx18_av_write_expect(cx, 0x803, v, v, 0x1f); - - /* assert soft reset */ - v = cx18_av_read(cx, 0x810) | 0x01; - cx18_av_write_expect(cx, 0x810, v, v, 0x0f); - - /* Mute everything to prevent the PFFT! */ - cx18_av_write(cx, 0x8d3, 0x1f); - - if (state->aud_input <= CX18_AV_AUDIO_SERIAL2) { - /* Set Path1 to Serial Audio Input */ - cx18_av_write4(cx, 0x8d0, 0x01011012); - - /* The microcontroller should not be started for the - * non-tuner inputs: autodetection is specific for - * TV audio. */ - } else { - /* Set Path1 to Analog Demod Main Channel */ - cx18_av_write4(cx, 0x8d0, 0x1f063870); - } - - set_audclk_freq(cx, state->audclk_freq); - - /* deassert soft reset */ - v = cx18_av_read(cx, 0x810) & ~0x01; - cx18_av_write_expect(cx, 0x810, v, v, 0x0f); - - if (state->aud_input > CX18_AV_AUDIO_SERIAL2) { - /* When the microcontroller detects the - * audio format, it will unmute the lines */ - v = cx18_av_read(cx, 0x803) | 0x10; - cx18_av_write_expect(cx, 0x803, v, v, 0x1f); - } -} - -static int get_volume(struct cx18 *cx) -{ - /* Volume runs +18dB to -96dB in 1/2dB steps - * change to fit the msp3400 -114dB to +12dB range */ - - /* check PATH1_VOLUME */ - int vol = 228 - cx18_av_read(cx, 0x8d4); - vol = (vol / 2) + 23; - return vol << 9; -} - -static void set_volume(struct cx18 *cx, int volume) -{ - /* First convert the volume to msp3400 values (0-127) */ - int vol = volume >> 9; - /* now scale it up to cx18_av values - * -114dB to -96dB maps to 0 - * this should be 19, but in my testing that was 4dB too loud */ - if (vol <= 23) - vol = 0; - else - vol -= 23; - - /* PATH1_VOLUME */ - cx18_av_write(cx, 0x8d4, 228 - (vol * 2)); -} - -static int get_bass(struct cx18 *cx) -{ - /* bass is 49 steps +12dB to -12dB */ - - /* check PATH1_EQ_BASS_VOL */ - int bass = cx18_av_read(cx, 0x8d9) & 0x3f; - bass = (((48 - bass) * 0xffff) + 47) / 48; - return bass; -} - -static void set_bass(struct cx18 *cx, int bass) -{ - /* PATH1_EQ_BASS_VOL */ - cx18_av_and_or(cx, 0x8d9, ~0x3f, 48 - (bass * 48 / 0xffff)); -} - -static int get_treble(struct cx18 *cx) -{ - /* treble is 49 steps +12dB to -12dB */ - - /* check PATH1_EQ_TREBLE_VOL */ - int treble = cx18_av_read(cx, 0x8db) & 0x3f; - treble = (((48 - treble) * 0xffff) + 47) / 48; - return treble; -} - -static void set_treble(struct cx18 *cx, int treble) -{ - /* PATH1_EQ_TREBLE_VOL */ - cx18_av_and_or(cx, 0x8db, ~0x3f, 48 - (treble * 48 / 0xffff)); -} - -static int get_balance(struct cx18 *cx) -{ - /* balance is 7 bit, 0 to -96dB */ - - /* check PATH1_BAL_LEVEL */ - int balance = cx18_av_read(cx, 0x8d5) & 0x7f; - /* check PATH1_BAL_LEFT */ - if ((cx18_av_read(cx, 0x8d5) & 0x80) == 0) - balance = 0x80 - balance; - else - balance = 0x80 + balance; - return balance << 8; -} - -static void set_balance(struct cx18 *cx, int balance) -{ - int bal = balance >> 8; - if (bal > 0x80) { - /* PATH1_BAL_LEFT */ - cx18_av_and_or(cx, 0x8d5, 0x7f, 0x80); - /* PATH1_BAL_LEVEL */ - cx18_av_and_or(cx, 0x8d5, ~0x7f, bal & 0x7f); - } else { - /* PATH1_BAL_LEFT */ - cx18_av_and_or(cx, 0x8d5, 0x7f, 0x00); - /* PATH1_BAL_LEVEL */ - cx18_av_and_or(cx, 0x8d5, ~0x7f, 0x80 - bal); - } -} - -static int get_mute(struct cx18 *cx) -{ - /* check SRC1_MUTE_EN */ - return cx18_av_read(cx, 0x8d3) & 0x2 ? 1 : 0; -} - -static void set_mute(struct cx18 *cx, int mute) -{ - struct cx18_av_state *state = &cx->av_state; - u8 v; - - if (state->aud_input > CX18_AV_AUDIO_SERIAL2) { - /* Must turn off microcontroller in order to mute sound. - * Not sure if this is the best method, but it does work. - * If the microcontroller is running, then it will undo any - * changes to the mute register. */ - v = cx18_av_read(cx, 0x803); - if (mute) { - /* disable microcontroller */ - v &= ~0x10; - cx18_av_write_expect(cx, 0x803, v, v, 0x1f); - cx18_av_write(cx, 0x8d3, 0x1f); - } else { - /* enable microcontroller */ - v |= 0x10; - cx18_av_write_expect(cx, 0x803, v, v, 0x1f); - } - } else { - /* SRC1_MUTE_EN */ - cx18_av_and_or(cx, 0x8d3, ~0x2, mute ? 0x02 : 0x00); - } -} - -int cx18_av_audio(struct cx18 *cx, unsigned int cmd, void *arg) -{ - struct cx18_av_state *state = &cx->av_state; - struct v4l2_control *ctrl = arg; - int retval; - - switch (cmd) { - case VIDIOC_INT_AUDIO_CLOCK_FREQ: - { - u8 v; - if (state->aud_input > CX18_AV_AUDIO_SERIAL2) { - v = cx18_av_read(cx, 0x803) & ~0x10; - cx18_av_write_expect(cx, 0x803, v, v, 0x1f); - cx18_av_write(cx, 0x8d3, 0x1f); - } - v = cx18_av_read(cx, 0x810) | 0x1; - cx18_av_write_expect(cx, 0x810, v, v, 0x0f); - - retval = set_audclk_freq(cx, *(u32 *)arg); - - v = cx18_av_read(cx, 0x810) & ~0x1; - cx18_av_write_expect(cx, 0x810, v, v, 0x0f); - if (state->aud_input > CX18_AV_AUDIO_SERIAL2) { - v = cx18_av_read(cx, 0x803) | 0x10; - cx18_av_write_expect(cx, 0x803, v, v, 0x1f); - } - return retval; - } - - case VIDIOC_G_CTRL: - switch (ctrl->id) { - case V4L2_CID_AUDIO_VOLUME: - ctrl->value = get_volume(cx); - break; - case V4L2_CID_AUDIO_BASS: - ctrl->value = get_bass(cx); - break; - case V4L2_CID_AUDIO_TREBLE: - ctrl->value = get_treble(cx); - break; - case V4L2_CID_AUDIO_BALANCE: - ctrl->value = get_balance(cx); - break; - case V4L2_CID_AUDIO_MUTE: - ctrl->value = get_mute(cx); - break; - default: - return -EINVAL; - } - break; - - case VIDIOC_S_CTRL: - switch (ctrl->id) { - case V4L2_CID_AUDIO_VOLUME: - set_volume(cx, ctrl->value); - break; - case V4L2_CID_AUDIO_BASS: - set_bass(cx, ctrl->value); - break; - case V4L2_CID_AUDIO_TREBLE: - set_treble(cx, ctrl->value); - break; - case V4L2_CID_AUDIO_BALANCE: - set_balance(cx, ctrl->value); - break; - case V4L2_CID_AUDIO_MUTE: - set_mute(cx, ctrl->value); - break; - default: - return -EINVAL; - } - break; - - default: - return -EINVAL; - } - - return 0; -} diff --git a/drivers/media/video/cx18/cx18-av-core.c b/drivers/media/video/cx18/cx18-av-core.c deleted file mode 100644 index 0b1c84b4ddd..00000000000 --- a/drivers/media/video/cx18/cx18-av-core.c +++ /dev/null @@ -1,1079 +0,0 @@ -/* - * cx18 ADEC audio functions - * - * Derived from cx25840-core.c - * - * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> - * Copyright (C) 2008 Andy Walls <awalls@radix.net> - * - * 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., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -#include "cx18-driver.h" -#include "cx18-io.h" - -int cx18_av_write(struct cx18 *cx, u16 addr, u8 value) -{ - u32 reg = 0xc40000 + (addr & ~3); - u32 mask = 0xff; - int shift = (addr & 3) * 8; - u32 x = cx18_read_reg(cx, reg); - - x = (x & ~(mask << shift)) | ((u32)value << shift); - cx18_write_reg(cx, x, reg); - return 0; -} - -int cx18_av_write_expect(struct cx18 *cx, u16 addr, u8 value, u8 eval, u8 mask) -{ - u32 reg = 0xc40000 + (addr & ~3); - int shift = (addr & 3) * 8; - u32 x = cx18_read_reg(cx, reg); - - x = (x & ~((u32)0xff << shift)) | ((u32)value << shift); - cx18_write_reg_expect(cx, x, reg, - ((u32)eval << shift), ((u32)mask << shift)); - return 0; -} - -int cx18_av_write4(struct cx18 *cx, u16 addr, u32 value) -{ - cx18_write_reg(cx, value, 0xc40000 + addr); - return 0; -} - -int -cx18_av_write4_expect(struct cx18 *cx, u16 addr, u32 value, u32 eval, u32 mask) -{ - cx18_write_reg_expect(cx, value, 0xc40000 + addr, eval, mask); - return 0; -} - -int cx18_av_write4_noretry(struct cx18 *cx, u16 addr, u32 value) -{ - cx18_write_reg_noretry(cx, value, 0xc40000 + addr); - return 0; -} - -u8 cx18_av_read(struct cx18 *cx, u16 addr) -{ - u32 x = cx18_read_reg(cx, 0xc40000 + (addr & ~3)); - int shift = (addr & 3) * 8; - - return (x >> shift) & 0xff; -} - -u32 cx18_av_read4(struct cx18 *cx, u16 addr) -{ - return cx18_read_reg(cx, 0xc40000 + addr); -} - -int cx18_av_and_or(struct cx18 *cx, u16 addr, unsigned and_mask, - u8 or_value) -{ - return cx18_av_write(cx, addr, - (cx18_av_read(cx, addr) & and_mask) | - or_value); -} - -int cx18_av_and_or4(struct cx18 *cx, u16 addr, u32 and_mask, - u32 or_value) -{ - return cx18_av_write4(cx, addr, - (cx18_av_read4(cx, addr) & and_mask) | - or_value); -} - -/* ----------------------------------------------------------------------- */ - -static int set_input(struct cx18 *cx, enum cx18_av_video_input vid_input, - enum cx18_av_audio_input aud_input); -static void log_audio_status(struct cx18 *cx); -static void log_video_status(struct cx18 *cx); - -/* ----------------------------------------------------------------------- */ - -static void cx18_av_initialize(struct cx18 *cx) -{ - struct cx18_av_state *state = &cx->av_state; - u32 v; - - cx18_av_loadfw(cx); - /* Stop 8051 code execution */ - cx18_av_write4_expect(cx, CXADEC_DL_CTL, 0x03000000, - 0x03000000, 0x13000000); - - /* initallize the PLL by toggling sleep bit */ - v = cx18_av_read4(cx, CXADEC_HOST_REG1); - /* enable sleep mode - register appears to be read only... */ - cx18_av_write4_expect(cx, CXADEC_HOST_REG1, v | 1, v, 0xfffe); - /* disable sleep mode */ - cx18_av_write4_expect(cx, CXADEC_HOST_REG1, v & 0xfffe, - v & 0xfffe, 0xffff); - - /* initialize DLLs */ - v = cx18_av_read4(cx, CXADEC_DLL1_DIAG_CTRL) & 0xE1FFFEFF; - /* disable FLD */ - cx18_av_write4(cx, CXADEC_DLL1_DIAG_CTRL, v); - /* enable FLD */ - cx18_av_write4(cx, CXADEC_DLL1_DIAG_CTRL, v | 0x10000100); - - v = cx18_av_read4(cx, CXADEC_DLL2_DIAG_CTRL) & 0xE1FFFEFF; - /* disable FLD */ - cx18_av_write4(cx, CXADEC_DLL2_DIAG_CTRL, v); - /* enable FLD */ - cx18_av_write4(cx, CXADEC_DLL2_DIAG_CTRL, v | 0x06000100); - - /* set analog bias currents. Set Vreg to 1.20V. */ - cx18_av_write4(cx, CXADEC_AFE_DIAG_CTRL1, 0x000A1802); - - v = cx18_av_read4(cx, CXADEC_AFE_DIAG_CTRL3) | 1; - /* enable TUNE_FIL_RST */ - cx18_av_write4_expect(cx, CXADEC_AFE_DIAG_CTRL3, v, v, 0x03009F0F); - /* disable TUNE_FIL_RST */ - cx18_av_write4_expect(cx, CXADEC_AFE_DIAG_CTRL3, - v & 0xFFFFFFFE, v & 0xFFFFFFFE, 0x03009F0F); - - /* enable 656 output */ - cx18_av_and_or4(cx, CXADEC_PIN_CTRL1, ~0, 0x040C00); - - /* video output drive strength */ - cx18_av_and_or4(cx, CXADEC_PIN_CTRL2, ~0, 0x2); - - /* reset video */ - cx18_av_write4(cx, CXADEC_SOFT_RST_CTRL, 0x8000); - cx18_av_write4(cx, CXADEC_SOFT_RST_CTRL, 0); - - /* set video to auto-detect */ - /* Clear bits 11-12 to enable slow locking mode. Set autodetect mode */ - /* set the comb notch = 1 */ - cx18_av_and_or4(cx, CXADEC_MODE_CTRL, 0xFFF7E7F0, 0x02040800); - - /* Enable wtw_en in CRUSH_CTRL (Set bit 22) */ - /* Enable maj_sel in CRUSH_CTRL (Set bit 20) */ - cx18_av_and_or4(cx, CXADEC_CRUSH_CTRL, ~0, 0x00500000); - - /* Set VGA_TRACK_RANGE to 0x20 */ - cx18_av_and_or4(cx, CXADEC_DFE_CTRL2, 0xFFFF00FF, 0x00002000); - - /* Enable VBI capture */ - cx18_av_write4(cx, CXADEC_OUT_CTRL1, 0x4010253F); - /* cx18_av_write4(cx, CXADEC_OUT_CTRL1, 0x4010253E); */ - - /* Set the video input. - The setting in MODE_CTRL gets lost when we do the above setup */ - /* EncSetSignalStd(dwDevNum, pEnc->dwSigStd); */ - /* EncSetVideoInput(dwDevNum, pEnc->VidIndSelection); */ - - v = cx18_av_read4(cx, CXADEC_AFE_CTRL); - v &= 0xFFFBFFFF; /* turn OFF bit 18 for droop_comp_ch1 */ - v &= 0xFFFF7FFF; /* turn OFF bit 9 for clamp_sel_ch1 */ - v &= 0xFFFFFFFE; /* turn OFF bit 0 for 12db_ch1 */ - /* v |= 0x00000001;*/ /* turn ON bit 0 for 12db_ch1 */ - cx18_av_write4(cx, CXADEC_AFE_CTRL, v); - -/* if(dwEnable && dw3DCombAvailable) { */ -/* CxDevWrReg(CXADEC_SRC_COMB_CFG, 0x7728021F); */ -/* } else { */ -/* CxDevWrReg(CXADEC_SRC_COMB_CFG, 0x6628021F); */ -/* } */ - cx18_av_write4(cx, CXADEC_SRC_COMB_CFG, 0x6628021F); - state->default_volume = 228 - cx18_av_read(cx, 0x8d4); - state->default_volume = ((state->default_volume / 2) + 23) << 9; -} - -/* ----------------------------------------------------------------------- */ - -void cx18_av_std_setup(struct cx18 *cx) -{ - struct cx18_av_state *state = &cx->av_state; - v4l2_std_id std = state->std; - int hblank, hactive, burst, vblank, vactive, sc; - int vblank656, src_decimation; - int luma_lpf, uv_lpf, comb; - u32 pll_int, pll_frac, pll_post; - - /* datasheet startup, step 8d */ - if (std & ~V4L2_STD_NTSC) - cx18_av_write(cx, 0x49f, 0x11); - else - cx18_av_write(cx, 0x49f, 0x14); - - if (std & V4L2_STD_625_50) { - hblank = 132; - hactive = 720; - burst = 93; - vblank = 36; - vactive = 580; - vblank656 = 40; - src_decimation = 0x21f; - - luma_lpf = 2; - if (std & V4L2_STD_PAL) { - uv_lpf = 1; - comb = 0x20; - sc = 688739; - } else if (std == V4L2_STD_PAL_Nc) { - uv_lpf = 1; - comb = 0x20; - sc = 556453; - } else { /* SECAM */ - uv_lpf = 0; - comb = 0; - sc = 672351; - } - } else { - hactive = 720; - hblank = 122; - vactive = 487; - luma_lpf = 1; - uv_lpf = 1; - vblank = 26; - vblank656 = 26; - - src_decimation = 0x21f; - if (std == V4L2_STD_PAL_60) { - burst = 0x5b; - luma_lpf = 2; - comb = 0x20; - sc = 688739; - } else if (std == V4L2_STD_PAL_M) { - burst = 0x61; - comb = 0x20; - sc = 555452; - } else { - burst = 0x5b; - comb = 0x66; - sc = 556063; - } - } - - /* DEBUG: Displays configured PLL frequency */ - pll_int = cx18_av_read(cx, 0x108); - pll_frac = cx18_av_read4(cx, 0x10c) & 0x1ffffff; - pll_post = cx18_av_read(cx, 0x109); - CX18_DEBUG_INFO("PLL regs = int: %u, frac: %u, post: %u\n", - pll_int, pll_frac, pll_post); - - if (pll_post) { - int fin, fsc, pll; - - pll = (28636360L * ((((u64)pll_int) << 25) + pll_frac)) >> 25; - pll /= pll_post; - CX18_DEBUG_INFO("PLL = %d.%06d MHz\n", - pll / 1000000, pll % 1000000); - CX18_DEBUG_INFO("PLL/8 = %d.%06d MHz\n", - pll / 8000000, (pll / 8) % 1000000); - - fin = ((u64)src_decimation * pll) >> 12; - CX18_DEBUG_INFO("ADC Sampling freq = %d.%06d MHz\n", - fin / 1000000, fin % 1000000); - - fsc = (((u64)sc) * pll) >> 24L; - CX18_DEBUG_INFO("Chroma sub-carrier freq = %d.%06d MHz\n", - fsc / 1000000, fsc % 1000000); - - CX18_DEBUG_INFO("hblank %i, hactive %i, " - "vblank %i , vactive %i, vblank656 %i, src_dec %i," - "burst 0x%02x, luma_lpf %i, uv_lpf %i, comb 0x%02x," - " sc 0x%06x\n", - hblank, hactive, vblank, vactive, vblank656, - src_decimation, burst, luma_lpf, uv_lpf, comb, sc); - } - - /* Sets horizontal blanking delay and active lines */ - cx18_av_write(cx, 0x470, hblank); - cx18_av_write(cx, 0x471, 0xff & (((hblank >> 8) & 0x3) | - (hactive << 4))); - cx18_av_write(cx, 0x472, hactive >> 4); - - /* Sets burst gate delay */ - cx18_av_write(cx, 0x473, burst); - - /* Sets vertical blanking delay and active duration */ - cx18_av_write(cx, 0x474, vblank); - cx18_av_write(cx, 0x475, 0xff & (((vblank >> 8) & 0x3) | - (vactive << 4))); - cx18_av_write(cx, 0x476, vactive >> 4); - cx18_av_write(cx, 0x477, vblank656); - - /* Sets src decimation rate */ - cx18_av_write(cx, 0x478, 0xff & src_decimation); - cx18_av_write(cx, 0x479, 0xff & (src_decimation >> 8)); - - /* Sets Luma and UV Low pass filters */ - cx18_av_write(cx, 0x47a, luma_lpf << 6 | ((uv_lpf << 4) & 0x30)); - - /* Enables comb filters */ - cx18_av_write(cx, 0x47b, comb); - - /* Sets SC Step*/ - cx18_av_write(cx, 0x47c, sc); - cx18_av_write(cx, 0x47d, 0xff & sc >> 8); - cx18_av_write(cx, 0x47e, 0xff & sc >> 16); - - /* Sets VBI parameters */ - if (std & V4L2_STD_625_50) { - cx18_av_write(cx, 0x47f, 0x01); - state->vbi_line_offset = 5; - } else { - cx18_av_write(cx, 0x47f, 0x00); - state->vbi_line_offset = 8; - } -} - -/* ----------------------------------------------------------------------- */ - -static void input_change(struct cx18 *cx) -{ - struct cx18_av_state *state = &cx->av_state; - v4l2_std_id std = state->std; - u8 v; - - /* Follow step 8c and 8d of section 3.16 in the cx18_av datasheet */ - cx18_av_write(cx, 0x49f, (std & V4L2_STD_NTSC) ? 0x14 : 0x11); - cx18_av_and_or(cx, 0x401, ~0x60, 0); - cx18_av_and_or(cx, 0x401, ~0x60, 0x60); - - if (std & V4L2_STD_525_60) { - if (std == V4L2_STD_NTSC_M_JP) { - /* Japan uses EIAJ audio standard */ - cx18_av_write_expect(cx, 0x808, 0xf7, 0xf7, 0xff); - cx18_av_write_expect(cx, 0x80b, 0x02, 0x02, 0x3f); - } else if (std == V4L2_STD_NTSC_M_KR) { - /* South Korea uses A2 audio standard */ - cx18_av_write_expect(cx, 0x808, 0xf8, 0xf8, 0xff); - cx18_av_write_expect(cx, 0x80b, 0x03, 0x03, 0x3f); - } else { - /* Others use the BTSC audio standard */ - cx18_av_write_expect(cx, 0x808, 0xf6, 0xf6, 0xff); - cx18_av_write_expect(cx, 0x80b, 0x01, 0x01, 0x3f); - } - } else if (std & V4L2_STD_PAL) { - /* Follow tuner change procedure for PAL */ - cx18_av_write_expect(cx, 0x808, 0xff, 0xff, 0xff); - cx18_av_write_expect(cx, 0x80b, 0x03, 0x03, 0x3f); - } else if (std & V4L2_STD_SECAM) { - /* Select autodetect for SECAM */ - cx18_av_write_expect(cx, 0x808, 0xff, 0xff, 0xff); - cx18_av_write_expect(cx, 0x80b, 0x03, 0x03, 0x3f); - } - - v = cx18_av_read(cx, 0x803); - if (v & 0x10) { - /* restart audio decoder microcontroller */ - v &= ~0x10; - cx18_av_write_expect(cx, 0x803, v, v, 0x1f); - v |= 0x10; - cx18_av_write_expect(cx, 0x803, v, v, 0x1f); - } -} - -static int set_input(struct cx18 *cx, enum cx18_av_video_input vid_input, - enum cx18_av_audio_input aud_input) -{ - struct cx18_av_state *state = &cx->av_state; - u8 is_composite = (vid_input >= CX18_AV_COMPOSITE1 && - vid_input <= CX18_AV_COMPOSITE8); - u8 reg; - u8 v; - - CX18_DEBUG_INFO("decoder set video input %d, audio input %d\n", - vid_input, aud_input); - - if (is_composite) { - reg = 0xf0 + (vid_input - CX18_AV_COMPOSITE1); - } else { - int luma = vid_input & 0xf0; - int chroma = vid_input & 0xf00; - - if ((vid_input & ~0xff0) || - luma < CX18_AV_SVIDEO_LUMA1 || - luma > CX18_AV_SVIDEO_LUMA8 || - chroma < CX18_AV_SVIDEO_CHROMA4 || - chroma > CX18_AV_SVIDEO_CHROMA8) { - CX18_ERR("0x%04x is not a valid video input!\n", - vid_input); - return -EINVAL; - } - reg = 0xf0 + ((luma - CX18_AV_SVIDEO_LUMA1) >> 4); - if (chroma >= CX18_AV_SVIDEO_CHROMA7) { - reg &= 0x3f; - reg |= (chroma - CX18_AV_SVIDEO_CHROMA7) >> 2; - } else { - reg &= 0xcf; - reg |= (chroma - CX18_AV_SVIDEO_CHROMA4) >> 4; - } - } - - switch (aud_input) { - case CX18_AV_AUDIO_SERIAL1: - case CX18_AV_AUDIO_SERIAL2: - /* do nothing, use serial audio input */ - break; - case CX18_AV_AUDIO4: reg &= ~0x30; break; - case CX18_AV_AUDIO5: reg &= ~0x30; reg |= 0x10; break; - case CX18_AV_AUDIO6: reg &= ~0x30; reg |= 0x20; break; - case CX18_AV_AUDIO7: reg &= ~0xc0; break; - case CX18_AV_AUDIO8: reg &= ~0xc0; reg |= 0x40; break; - - default: - CX18_ERR("0x%04x is not a valid audio input!\n", aud_input); - return -EINVAL; - } - - cx18_av_write_expect(cx, 0x103, reg, reg, 0xf7); - /* Set INPUT_MODE to Composite (0) or S-Video (1) */ - cx18_av_and_or(cx, 0x401, ~0x6, is_composite ? 0 : 0x02); - - /* Set CH_SEL_ADC2 to 1 if input comes from CH3 */ - v = cx18_av_read(cx, 0x102); - if (reg & 0x80) - v &= ~0x2; - else - v |= 0x2; - /* Set DUAL_MODE_ADC2 to 1 if input comes from both CH2 and CH3 */ - if ((reg & 0xc0) != 0xc0 && (reg & 0x30) != 0x30) - v |= 0x4; - else - v &= ~0x4; - cx18_av_write_expect(cx, 0x102, v, v, 0x17); - - /*cx18_av_and_or4(cx, 0x104, ~0x001b4180, 0x00004180);*/ - - state->vid_input = vid_input; - state->aud_input = aud_input; - cx18_av_audio_set_path(cx); - input_change(cx); - return 0; -} - -/* ----------------------------------------------------------------------- */ - -static int set_v4lstd(struct cx18 *cx) -{ - struct cx18_av_state *state = &cx->av_state; - u8 fmt = 0; /* zero is autodetect */ - u8 pal_m = 0; - - /* First tests should be against specific std */ - if (state->std == V4L2_STD_NTSC_M_JP) { - fmt = 0x2; - } else if (state->std == V4L2_STD_NTSC_443) { - fmt = 0x3; - } else if (state->std == V4L2_STD_PAL_M) { - pal_m = 1; - fmt = 0x5; - } else if (state->std == V4L2_STD_PAL_N) { - fmt = 0x6; - } else if (state->std == V4L2_STD_PAL_Nc) { - fmt = 0x7; - } else if (state->std == V4L2_STD_PAL_60) { - fmt = 0x8; - } else { - /* Then, test against generic ones */ - if (state->std & V4L2_STD_NTSC) - fmt = 0x1; - else if (state->std & V4L2_STD_PAL) - fmt = 0x4; - else if (state->std & V4L2_STD_SECAM) - fmt = 0xc; - } - - CX18_DEBUG_INFO("changing video std to fmt %i\n", fmt); - - /* Follow step 9 of section 3.16 in the cx18_av datasheet. - Without this PAL may display a vertical ghosting effect. - This happens for example with the Yuan MPC622. */ - if (fmt >= 4 && fmt < 8) { - /* Set format to NTSC-M */ - cx18_av_and_or(cx, 0x400, ~0xf, 1); - /* Turn off LCOMB */ - cx18_av_and_or(cx, 0x47b, ~6, 0); - } - cx18_av_and_or(cx, 0x400, ~0x2f, fmt | 0x20); - cx18_av_and_or(cx, 0x403, ~0x3, pal_m); - cx18_av_std_setup(cx); - input_change(cx); - return 0; -} - -/* ----------------------------------------------------------------------- */ - -static int set_v4lctrl(struct cx18 *cx, struct v4l2_control *ctrl) -{ - switch (ctrl->id) { - case V4L2_CID_BRIGHTNESS: - if (ctrl->value < 0 || ctrl->value > 255) { - CX18_ERR("invalid brightness setting %d\n", - ctrl->value); - return -ERANGE; - } - - cx18_av_write(cx, 0x414, ctrl->value - 128); - break; - - case V4L2_CID_CONTRAST: - if (ctrl->value < 0 || ctrl->value > 127) { - CX18_ERR("invalid contrast setting %d\n", - ctrl->value); - return -ERANGE; - } - - cx18_av_write(cx, 0x415, ctrl->value << 1); - break; - - case V4L2_CID_SATURATION: - if (ctrl->value < 0 || ctrl->value > 127) { - CX18_ERR("invalid saturation setting %d\n", - ctrl->value); - return -ERANGE; - } - - cx18_av_write(cx, 0x420, ctrl->value << 1); - cx18_av_write(cx, 0x421, ctrl->value << 1); - break; - - case V4L2_CID_HUE: - if (ctrl->value < -127 || ctrl->value > 127) { - CX18_ERR("invalid hue setting %d\n", ctrl->value); - return -ERANGE; - } - - cx18_av_write(cx, 0x422, ctrl->value); - break; - - case V4L2_CID_AUDIO_VOLUME: - case V4L2_CID_AUDIO_BASS: - case V4L2_CID_AUDIO_TREBLE: - case V4L2_CID_AUDIO_BALANCE: - case V4L2_CID_AUDIO_MUTE: - return cx18_av_audio(cx, VIDIOC_S_CTRL, ctrl); - - default: - return -EINVAL; - } - - return 0; -} - -static int get_v4lctrl(struct cx18 *cx, struct v4l2_control *ctrl) -{ - switch (ctrl->id) { - case V4L2_CID_BRIGHTNESS: - ctrl->value = (s8)cx18_av_read(cx, 0x414) + 128; - break; - case V4L2_CID_CONTRAST: - ctrl->value = cx18_av_read(cx, 0x415) >> 1; - break; - case V4L2_CID_SATURATION: - ctrl->value = cx18_av_read(cx, 0x420) >> 1; - break; - case V4L2_CID_HUE: - ctrl->value = (s8)cx18_av_read(cx, 0x422); - break; - case V4L2_CID_AUDIO_VOLUME: - case V4L2_CID_AUDIO_BASS: - case V4L2_CID_AUDIO_TREBLE: - case V4L2_CID_AUDIO_BALANCE: - case V4L2_CID_AUDIO_MUTE: - return cx18_av_audio(cx, VIDIOC_G_CTRL, ctrl); - default: - return -EINVAL; - } - - return 0; -} - -/* ----------------------------------------------------------------------- */ - -static int get_v4lfmt(struct cx18 *cx, struct v4l2_format *fmt) -{ - switch (fmt->type) { - case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: - return cx18_av_vbi(cx, VIDIOC_G_FMT, fmt); - default: - return -EINVAL; - } - - return 0; -} - -static int set_v4lfmt(struct cx18 *cx, struct v4l2_format *fmt) -{ - struct cx18_av_state *state = &cx->av_state; - struct v4l2_pix_format *pix; - int HSC, VSC, Vsrc, Hsrc, filter, Vlines; - int is_50Hz = !(state->std & V4L2_STD_525_60); - - switch (fmt->type) { - case V4L2_BUF_TYPE_VIDEO_CAPTURE: - pix = &(fmt->fmt.pix); - - Vsrc = (cx18_av_read(cx, 0x476) & 0x3f) << 4; - Vsrc |= (cx18_av_read(cx, 0x475) & 0xf0) >> 4; - - Hsrc = (cx18_av_read(cx, 0x472) & 0x3f) << 4; - Hsrc |= (cx18_av_read(cx, 0x471) & 0xf0) >> 4; - - Vlines = pix->height + (is_50Hz ? 4 : 7); - - if ((pix->width * 16 < Hsrc) || (Hsrc < pix->width) || - (Vlines * 8 < Vsrc) || (Vsrc < Vlines)) { - CX18_ERR("%dx%d is not a valid size!\n", - pix->width, pix->height); - return -ERANGE; - } - - HSC = (Hsrc * (1 << 20)) / pix->width - (1 << 20); - VSC = (1 << 16) - (Vsrc * (1 << 9) / Vlines - (1 << 9)); - VSC &= 0x1fff; - - if (pix->width >= 385) - filter = 0; - else if (pix->width > 192) - filter = 1; - else if (pix->width > 96) - filter = 2; - else - filter = 3; - - CX18_DEBUG_INFO("decoder set size %dx%d -> scale %ux%u\n", - pix->width, pix->height, HSC, VSC); - - /* HSCALE=HSC */ - cx18_av_write(cx, 0x418, HSC & 0xff); - cx18_av_write(cx, 0x419, (HSC >> 8) & 0xff); - cx18_av_write(cx, 0x41a, HSC >> 16); - /* VSCALE=VSC */ - cx18_av_write(cx, 0x41c, VSC & 0xff); - cx18_av_write(cx, 0x41d, VSC >> 8); - /* VS_INTRLACE=1 VFILT=filter */ - cx18_av_write(cx, 0x41e, 0x8 | filter); - break; - - case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: - return cx18_av_vbi(cx, VIDIOC_S_FMT, fmt); - - case V4L2_BUF_TYPE_VBI_CAPTURE: - return cx18_av_vbi(cx, VIDIOC_S_FMT, fmt); - - default: - return -EINVAL; - } - - return 0; -} - -/* ----------------------------------------------------------------------- */ - -int cx18_av_cmd(struct cx18 *cx, unsigned int cmd, void *arg) -{ - struct cx18_av_state *state = &cx->av_state; - struct v4l2_tuner *vt = arg; - struct v4l2_routing *route = arg; - - /* ignore these commands */ - switch (cmd) { - case TUNER_SET_TYPE_ADDR: - return 0; - } - - if (!state->is_initialized) { - CX18_DEBUG_INFO("cmd %08x triggered fw load\n", cmd); - /* initialize on first use */ - state->is_initialized = 1; - cx18_av_initialize(cx); - } - - switch (cmd) { - case VIDIOC_INT_DECODE_VBI_LINE: - return cx18_av_vbi(cx, cmd, arg); - - case VIDIOC_INT_AUDIO_CLOCK_FREQ: - return cx18_av_audio(cx, cmd, arg); - - case VIDIOC_STREAMON: - CX18_DEBUG_INFO("enable output\n"); - cx18_av_write(cx, 0x115, 0x8c); - cx18_av_write(cx, 0x116, 0x07); - break; - - case VIDIOC_STREAMOFF: - CX18_DEBUG_INFO("disable output\n"); - cx18_av_write(cx, 0x115, 0x00); - cx18_av_write(cx, 0x116, 0x00); - break; - - case VIDIOC_LOG_STATUS: - log_video_status(cx); - log_audio_status(cx); - break; - - case VIDIOC_G_CTRL: - return get_v4lctrl(cx, (struct v4l2_control *)arg); - - case VIDIOC_S_CTRL: - return set_v4lctrl(cx, (struct v4l2_control *)arg); - - case VIDIOC_QUERYCTRL: - { - struct v4l2_queryctrl *qc = arg; - - switch (qc->id) { - case V4L2_CID_BRIGHTNESS: - case V4L2_CID_CONTRAST: - case V4L2_CID_SATURATION: - case V4L2_CID_HUE: - return v4l2_ctrl_query_fill_std(qc); - default: - break; - } - - switch (qc->id) { - case V4L2_CID_AUDIO_VOLUME: - return v4l2_ctrl_query_fill(qc, 0, 65535, - 65535 / 100, state->default_volume); - case V4L2_CID_AUDIO_MUTE: - case V4L2_CID_AUDIO_BALANCE: - case V4L2_CID_AUDIO_BASS: - case V4L2_CID_AUDIO_TREBLE: - return v4l2_ctrl_query_fill_std(qc); - default: - return -EINVAL; - } - return -EINVAL; - } - - case VIDIOC_G_STD: - *(v4l2_std_id *)arg = state->std; - break; - - case VIDIOC_S_STD: - if (state->radio == 0 && state->std == *(v4l2_std_id *)arg) - return 0; - state->radio = 0; - state->std = *(v4l2_std_id *)arg; - return set_v4lstd(cx); - - case AUDC_SET_RADIO: - state->radio = 1; - break; - - case VIDIOC_INT_G_VIDEO_ROUTING: - route->input = state->vid_input; - route->output = 0; - break; - - case VIDIOC_INT_S_VIDEO_ROUTING: - return set_input(cx, route->input, state->aud_input); - - case VIDIOC_INT_G_AUDIO_ROUTING: - route->input = state->aud_input; - route->output = 0; - break; - - case VIDIOC_INT_S_AUDIO_ROUTING: - return set_input(cx, state->vid_input, route->input); - - case VIDIOC_S_FREQUENCY: - input_change(cx); - break; - - case VIDIOC_G_TUNER: - { - u8 vpres = cx18_av_read(cx, 0x40e) & 0x20; - u8 mode; - int val = 0; - - if (state->radio) - break; - - vt->signal = vpres ? 0xffff : 0x0; - - vt->capability |= - V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_LANG1 | - V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP; - - mode = cx18_av_read(cx, 0x804); - - /* get rxsubchans and audmode */ - if ((mode & 0xf) == 1) - val |= V4L2_TUNER_SUB_STEREO; - else - val |= V4L2_TUNER_SUB_MONO; - - if (mode == 2 || mode == 4) - val = V4L2_TUNER_SUB_LANG1 | V4L2_TUNER_SUB_LANG2; - - if (mode & 0x10) - val |= V4L2_TUNER_SUB_SAP; - - vt->rxsubchans = val; - vt->audmode = state->audmode; - break; - } - - case VIDIOC_S_TUNER: - { - u8 v; - - if (state->radio) - break; - - v = cx18_av_read(cx, 0x809); - v &= ~0xf; - - switch (vt->audmode) { - case V4L2_TUNER_MODE_MONO: - /* mono -> mono - stereo -> mono - bilingual -> lang1 */ - break; - case V4L2_TUNER_MODE_STEREO: - case V4L2_TUNER_MODE_LANG1: - /* mono -> mono - stereo -> stereo - bilingual -> lang1 */ - v |= 0x4; - break; - case V4L2_TUNER_MODE_LANG1_LANG2: - /* mono -> mono - stereo -> stereo - bilingual -> lang1/lang2 */ - v |= 0x7; - break; - case V4L2_TUNER_MODE_LANG2: - /* mono -> mono - stereo -> stereo - bilingual -> lang2 */ - v |= 0x1; - break; - default: - return -EINVAL; - } - cx18_av_write_expect(cx, 0x809, v, v, 0xff); - state->audmode = vt->audmode; - break; - } - - case VIDIOC_G_FMT: - return get_v4lfmt(cx, (struct v4l2_format *)arg); - - case VIDIOC_S_FMT: - return set_v4lfmt(cx, (struct v4l2_format *)arg); - - case VIDIOC_INT_RESET: - cx18_av_initialize(cx); - break; - - default: - return -EINVAL; - } - - return 0; -} - -/* ----------------------------------------------------------------------- */ - -/* ----------------------------------------------------------------------- */ - -static void log_video_status(struct cx18 *cx) -{ - static const char *const fmt_strs[] = { - "0x0", - "NTSC-M", "NTSC-J", "NTSC-4.43", - "PAL-BDGHI", "PAL-M", "PAL-N", "PAL-Nc", "PAL-60", - "0x9", "0xA", "0xB", - "SECAM", - "0xD", "0xE", "0xF" - }; - - struct cx18_av_state *state = &cx->av_state; - u8 vidfmt_sel = cx18_av_read(cx, 0x400) & 0xf; - u8 gen_stat1 = cx18_av_read(cx, 0x40d); - u8 gen_stat2 = cx18_av_read(cx, 0x40e); - int vid_input = state->vid_input; - - CX18_INFO("Video signal: %spresent\n", - (gen_stat2 & 0x20) ? "" : "not "); - CX18_INFO("Detected format: %s\n", - fmt_strs[gen_stat1 & 0xf]); - - CX18_INFO("Specified standard: %s\n", - vidfmt_sel ? fmt_strs[vidfmt_sel] : "automatic detection"); - - if (vid_input >= CX18_AV_COMPOSITE1 && - vid_input <= CX18_AV_COMPOSITE8) { - CX18_INFO("Specified video input: Composite %d\n", - vid_input - CX18_AV_COMPOSITE1 + 1); - } else { - CX18_INFO("Specified video input: S-Video (Luma In%d, Chroma In%d)\n", - (vid_input & 0xf0) >> 4, (vid_input & 0xf00) >> 8); - } - - CX18_INFO("Specified audioclock freq: %d Hz\n", state->audclk_freq); -} - -/* ----------------------------------------------------------------------- */ - -static void log_audio_status(struct cx18 *cx) -{ - struct cx18_av_state *state = &cx->av_state; - u8 download_ctl = cx18_av_read(cx, 0x803); - u8 mod_det_stat0 = cx18_av_read(cx, 0x804); - u8 mod_det_stat1 = cx18_av_read(cx, 0x805); - u8 audio_config = cx18_av_read(cx, 0x808); - u8 pref_mode = cx18_av_read(cx, 0x809); - u8 afc0 = cx18_av_read(cx, 0x80b); - u8 mute_ctl = cx18_av_read(cx, 0x8d3); - int aud_input = state->aud_input; - char *p; - - switch (mod_det_stat0) { - case 0x00: p = "mono"; break; - case 0x01: p = "stereo"; break; - case 0x02: p = "dual"; break; - case 0x04: p = "tri"; break; - case 0x10: p = "mono with SAP"; break; - case 0x11: p = "stereo with SAP"; break; - case 0x12: p = "dual with SAP"; break; - case 0x14: p = "tri with SAP"; break; - case 0xfe: p = "forced mode"; break; - default: p = "not defined"; break; - } - CX18_INFO("Detected audio mode: %s\n", p); - - switch (mod_det_stat1) { - case 0x00: p = "not defined"; break; - case 0x01: p = "EIAJ"; break; - case 0x02: p = "A2-M"; break; - case 0x03: p = "A2-BG"; break; - case 0x04: p = "A2-DK1"; break; - case 0x05: p = "A2-DK2"; break; - case 0x06: p = "A2-DK3"; break; - case 0x07: p = "A1 (6.0 MHz FM Mono)"; break; - case 0x08: p = "AM-L"; break; - case 0x09: p = "NICAM-BG"; break; - case 0x0a: p = "NICAM-DK"; break; - case 0x0b: p = "NICAM-I"; break; - case 0x0c: p = "NICAM-L"; break; - case 0x0d: p = "BTSC/EIAJ/A2-M Mono (4.5 MHz FMMono)"; break; - case 0x0e: p = "IF FM Radio"; break; - case 0x0f: p = "BTSC"; break; - case 0x10: p = "detected chrominance"; break; - case 0xfd: p = "unknown audio standard"; break; - case 0xfe: p = "forced audio standard"; break; - case 0xff: p = "no detected audio standard"; break; - default: p = "not defined"; break; - } - CX18_INFO("Detected audio standard: %s\n", p); - CX18_INFO("Audio muted: %s\n", - (mute_ctl & 0x2) ? "yes" : "no"); - CX18_INFO("Audio microcontroller: %s\n", - (download_ctl & 0x10) ? "running" : "stopped"); - - switch (audio_config >> 4) { - case 0x00: p = "undefined"; break; - case 0x01: p = "BTSC"; break; - case 0x02: p = "EIAJ"; break; - case 0x03: p = "A2-M"; break; - case 0x04: p = "A2-BG"; break; - case 0x05: p = "A2-DK1"; break; - case 0x06: p = "A2-DK2"; break; - case 0x07: p = "A2-DK3"; break; - case 0x08: p = "A1 (6.0 MHz FM Mono)"; break; - case 0x09: p = "AM-L"; break; - case 0x0a: p = "NICAM-BG"; break; - case 0x0b: p = "NICAM-DK"; break; - case 0x0c: p = "NICAM-I"; break; - case 0x0d: p = "NICAM-L"; break; - case 0x0e: p = "FM radio"; break; - case 0x0f: p = "automatic detection"; break; - default: p = "undefined"; break; - } - CX18_INFO("Configured audio standard: %s\n", p); - - if ((audio_config >> 4) < 0xF) { - switch (audio_config & 0xF) { - case 0x00: p = "MONO1 (LANGUAGE A/Mono L+R channel for BTSC, EIAJ, A2)"; break; - case 0x01: p = "MONO2 (LANGUAGE B)"; break; - case 0x02: p = "MONO3 (STEREO forced MONO)"; break; - case 0x03: p = "MONO4 (NICAM ANALOG-Language C/Analog Fallback)"; break; - case 0x04: p = "STEREO"; break; - case 0x05: p = "DUAL1 (AC)"; break; - case 0x06: p = "DUAL2 (BC)"; break; - case 0x07: p = "DUAL3 (AB)"; break; - default: p = "undefined"; - } - CX18_INFO("Configured audio mode: %s\n", p); - } else { - switch (audio_config & 0xF) { - case 0x00: p = "BG"; break; - case 0x01: p = "DK1"; break; - case 0x02: p = "DK2"; break; - case 0x03: p = "DK3"; break; - case 0x04: p = "I"; break; - case 0x05: p = "L"; break; - case 0x06: p = "BTSC"; break; - case 0x07: p = "EIAJ"; break; - case 0x08: p = "A2-M"; break; - case 0x09: p = "FM Radio (4.5 MHz)"; break; - case 0x0a: p = "FM Radio (5.5 MHz)"; break; - case 0x0b: p = "S-Video"; break; - case 0x0f: p = "automatic standard and mode detection"; break; - default: p = "undefined"; break; - } - CX18_INFO("Configured audio system: %s\n", p); - } - - if (aud_input) - CX18_INFO("Specified audio input: Tuner (In%d)\n", - aud_input); - else - CX18_INFO("Specified audio input: External\n"); - - switch (pref_mode & 0xf) { - case 0: p = "mono/language A"; break; - case 1: p = "language B"; break; - case 2: p = "language C"; break; - case 3: p = "analog fallback"; break; - case 4: p = "stereo"; break; - case 5: p = "language AC"; break; - case 6: p = "language BC"; break; - case 7: p = "language AB"; break; - default: p = "undefined"; break; - } - CX18_INFO("Preferred audio mode: %s\n", p); - - if ((audio_config & 0xf) == 0xf) { - switch ((afc0 >> 3) & 0x1) { - case 0: p = "system DK"; break; - case 1: p = "system L"; break; - } - CX18_INFO("Selected 65 MHz format: %s\n", p); - - switch (afc0 & 0x7) { - case 0: p = "Chroma"; break; - case 1: p = "BTSC"; break; - case 2: p = "EIAJ"; break; - case 3: p = "A2-M"; break; - case 4: p = "autodetect"; break; - default: p = "undefined"; break; - } - CX18_INFO("Selected 45 MHz format: %s\n", p); - } -} diff --git a/drivers/media/video/cx18/cx18-av-core.h b/drivers/media/video/cx18/cx18-av-core.h deleted file mode 100644 index cf68a603909..00000000000 --- a/drivers/media/video/cx18/cx18-av-core.h +++ /dev/null @@ -1,329 +0,0 @@ -/* - * cx18 ADEC header - * - * Derived from cx25840-core.h - * - * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> - * Copyright (C) 2008 Andy Walls <awalls@radix.net> - * - * 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., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -#ifndef _CX18_AV_CORE_H_ -#define _CX18_AV_CORE_H_ - -struct cx18; - -enum cx18_av_video_input { - /* Composite video inputs In1-In8 */ - CX18_AV_COMPOSITE1 = 1, - CX18_AV_COMPOSITE2, - CX18_AV_COMPOSITE3, - CX18_AV_COMPOSITE4, - CX18_AV_COMPOSITE5, - CX18_AV_COMPOSITE6, - CX18_AV_COMPOSITE7, - CX18_AV_COMPOSITE8, - - /* S-Video inputs consist of one luma input (In1-In8) ORed with one - chroma input (In5-In8) */ - CX18_AV_SVIDEO_LUMA1 = 0x10, - CX18_AV_SVIDEO_LUMA2 = 0x20, - CX18_AV_SVIDEO_LUMA3 = 0x30, - CX18_AV_SVIDEO_LUMA4 = 0x40, - CX18_AV_SVIDEO_LUMA5 = 0x50, - CX18_AV_SVIDEO_LUMA6 = 0x60, - CX18_AV_SVIDEO_LUMA7 = 0x70, - CX18_AV_SVIDEO_LUMA8 = 0x80, - CX18_AV_SVIDEO_CHROMA4 = 0x400, - CX18_AV_SVIDEO_CHROMA5 = 0x500, - CX18_AV_SVIDEO_CHROMA6 = 0x600, - CX18_AV_SVIDEO_CHROMA7 = 0x700, - CX18_AV_SVIDEO_CHROMA8 = 0x800, - - /* S-Video aliases for common luma/chroma combinations */ - CX18_AV_SVIDEO1 = 0x510, - CX18_AV_SVIDEO2 = 0x620, - CX18_AV_SVIDEO3 = 0x730, - CX18_AV_SVIDEO4 = 0x840, -}; - -enum cx18_av_audio_input { - /* Audio inputs: serial or In4-In8 */ - CX18_AV_AUDIO_SERIAL1, - CX18_AV_AUDIO_SERIAL2, - CX18_AV_AUDIO4 = 4, - CX18_AV_AUDIO5, - CX18_AV_AUDIO6, - CX18_AV_AUDIO7, - CX18_AV_AUDIO8, -}; - -struct cx18_av_state { - int radio; - v4l2_std_id std; - enum cx18_av_video_input vid_input; - enum cx18_av_audio_input aud_input; - u32 audclk_freq; - int audmode; - int vbi_line_offset; - int default_volume; - u32 id; - u32 rev; - int is_initialized; -}; - - -/* Registers */ -#define CXADEC_CHIP_TYPE_TIGER 0x837 -#define CXADEC_CHIP_TYPE_MAKO 0x843 - -#define CXADEC_HOST_REG1 0x000 -#define CXADEC_HOST_REG2 0x001 - -#define CXADEC_CHIP_CTRL 0x100 -#define CXADEC_AFE_CTRL 0x104 -#define CXADEC_PLL_CTRL1 0x108 -#define CXADEC_VID_PLL_FRAC 0x10C -#define CXADEC_AUX_PLL_FRAC 0x110 -#define CXADEC_PIN_CTRL1 0x114 -#define CXADEC_PIN_CTRL2 0x118 -#define CXADEC_PIN_CFG1 0x11C -#define CXADEC_PIN_CFG2 0x120 - -#define CXADEC_PIN_CFG3 0x124 -#define CXADEC_I2S_MCLK 0x127 - -#define CXADEC_AUD_LOCK1 0x128 -#define CXADEC_AUD_LOCK2 0x12C -#define CXADEC_POWER_CTRL 0x130 -#define CXADEC_AFE_DIAG_CTRL1 0x134 -#define CXADEC_AFE_DIAG_CTRL2 0x138 -#define CXADEC_AFE_DIAG_CTRL3 0x13C -#define CXADEC_PLL_DIAG_CTRL 0x140 -#define CXADEC_TEST_CTRL1 0x144 -#define CXADEC_TEST_CTRL2 0x148 -#define CXADEC_BIST_STAT 0x14C -#define CXADEC_DLL1_DIAG_CTRL 0x158 -#define CXADEC_DLL2_DIAG_CTRL 0x15C - -/* IR registers */ -#define CXADEC_IR_CTRL_REG 0x200 -#define CXADEC_IR_TXCLK_REG 0x204 -#define CXADEC_IR_RXCLK_REG 0x208 -#define CXADEC_IR_CDUTY_REG 0x20C -#define CXADEC_IR_STAT_REG 0x210 -#define CXADEC_IR_IRQEN_REG 0x214 -#define CXADEC_IR_FILTER_REG 0x218 -#define CXADEC_IR_FIFO_REG 0x21C - -/* Video Registers */ -#define CXADEC_MODE_CTRL 0x400 -#define CXADEC_OUT_CTRL1 0x404 -#define CXADEC_OUT_CTRL2 0x408 -#define CXADEC_GEN_STAT 0x40C -#define CXADEC_INT_STAT_MASK 0x410 -#define CXADEC_LUMA_CTRL 0x414 - -#define CXADEC_BRIGHTNESS_CTRL_BYTE 0x414 -#define CXADEC_CONTRAST_CTRL_BYTE 0x415 -#define CXADEC_LUMA_CTRL_BYTE_3 0x416 - -#define CXADEC_HSCALE_CTRL 0x418 -#define CXADEC_VSCALE_CTRL 0x41C - -#define CXADEC_CHROMA_CTRL 0x420 - -#define CXADEC_USAT_CTRL_BYTE 0x420 -#define CXADEC_VSAT_CTRL_BYTE 0x421 -#define CXADEC_HUE_CTRL_BYTE 0x422 - -#define CXADEC_VBI_LINE_CTRL1 0x424 -#define CXADEC_VBI_LINE_CTRL2 0x428 -#define CXADEC_VBI_LINE_CTRL3 0x42C -#define CXADEC_VBI_LINE_CTRL4 0x430 -#define CXADEC_VBI_LINE_CTRL5 0x434 -#define CXADEC_VBI_FC_CFG 0x438 -#define CXADEC_VBI_MISC_CFG1 0x43C -#define CXADEC_VBI_MISC_CFG2 0x440 -#define CXADEC_VBI_PAY1 0x444 -#define CXADEC_VBI_PAY2 0x448 -#define CXADEC_VBI_CUST1_CFG1 0x44C -#define CXADEC_VBI_CUST1_CFG2 0x450 -#define CXADEC_VBI_CUST1_CFG3 0x454 -#define CXADEC_VBI_CUST2_CFG1 0x458 -#define CXADEC_VBI_CUST2_CFG2 0x45C -#define CXADEC_VBI_CUST2_CFG3 0x460 -#define CXADEC_VBI_CUST3_CFG1 0x464 -#define CXADEC_VBI_CUST3_CFG2 0x468 -#define CXADEC_VBI_CUST3_CFG3 0x46C -#define CXADEC_HORIZ_TIM_CTRL 0x470 -#define CXADEC_VERT_TIM_CTRL 0x474 -#define CXADEC_SRC_COMB_CFG 0x478 -#define CXADEC_CHROMA_VBIOFF_CFG 0x47C -#define CXADEC_FIELD_COUNT 0x480 -#define CXADEC_MISC_TIM_CTRL 0x484 -#define CXADEC_DFE_CTRL1 0x488 -#define CXADEC_DFE_CTRL2 0x48C -#define CXADEC_DFE_CTRL3 0x490 -#define CXADEC_PLL_CTRL2 0x494 -#define CXADEC_HTL_CTRL 0x498 -#define CXADEC_COMB_CTRL 0x49C -#define CXADEC_CRUSH_CTRL 0x4A0 -#define CXADEC_SOFT_RST_CTRL 0x4A4 -#define CXADEC_MV_DT_CTRL2 0x4A8 -#define CXADEC_MV_DT_CTRL3 0x4AC -#define CXADEC_MISC_DIAG_CTRL 0x4B8 - -#define CXADEC_DL_CTL 0x800 -#define CXADEC_DL_CTL_ADDRESS_LOW 0x800 /* Byte 1 in DL_CTL */ -#define CXADEC_DL_CTL_ADDRESS_HIGH 0x801 /* Byte 2 in DL_CTL */ -#define CXADEC_DL_CTL_DATA 0x802 /* Byte 3 in DL_CTL */ -#define CXADEC_DL_CTL_CONTROL 0x803 /* Byte 4 in DL_CTL */ - -#define CXADEC_STD_DET_STATUS 0x804 - -#define CXADEC_STD_DET_CTL 0x808 -#define CXADEC_STD_DET_CTL_AUD_CTL 0x808 /* Byte 1 in STD_DET_CTL */ -#define CXADEC_STD_DET_CTL_PREF_MODE 0x809 /* Byte 2 in STD_DET_CTL */ - -#define CXADEC_DW8051_INT 0x80C -#define CXADEC_GENERAL_CTL 0x810 -#define CXADEC_AAGC_CTL 0x814 -#define CXADEC_IF_SRC_CTL 0x818 -#define CXADEC_ANLOG_DEMOD_CTL 0x81C -#define CXADEC_ROT_FREQ_CTL 0x820 -#define CXADEC_FM1_CTL 0x824 -#define CXADEC_PDF_CTL 0x828 -#define CXADEC_DFT1_CTL1 0x82C -#define CXADEC_DFT1_CTL2 0x830 -#define CXADEC_DFT_STATUS 0x834 -#define CXADEC_DFT2_CTL1 0x838 -#define CXADEC_DFT2_CTL2 0x83C -#define CXADEC_DFT2_STATUS 0x840 -#define CXADEC_DFT3_CTL1 0x844 -#define CXADEC_DFT3_CTL2 0x848 -#define CXADEC_DFT3_STATUS 0x84C -#define CXADEC_DFT4_CTL1 0x850 -#define CXADEC_DFT4_CTL2 0x854 -#define CXADEC_DFT4_STATUS 0x858 -#define CXADEC_AM_MTS_DET 0x85C -#define CXADEC_ANALOG_MUX_CTL 0x860 -#define CXADEC_DIG_PLL_CTL1 0x864 -#define CXADEC_DIG_PLL_CTL2 0x868 -#define CXADEC_DIG_PLL_CTL3 0x86C -#define CXADEC_DIG_PLL_CTL4 0x870 -#define CXADEC_DIG_PLL_CTL5 0x874 -#define CXADEC_DEEMPH_GAIN_CTL 0x878 -#define CXADEC_DEEMPH_COEF1 0x87C -#define CXADEC_DEEMPH_COEF2 0x880 -#define CXADEC_DBX1_CTL1 0x884 -#define CXADEC_DBX1_CTL2 0x888 -#define CXADEC_DBX1_STATUS 0x88C -#define CXADEC_DBX2_CTL1 0x890 -#define CXADEC_DBX2_CTL2 0x894 -#define CXADEC_DBX2_STATUS 0x898 -#define CXADEC_AM_FM_DIFF 0x89C - -/* NICAM registers go here */ -#define CXADEC_NICAM_STATUS 0x8C8 -#define CXADEC_DEMATRIX_CTL 0x8CC - -#define CXADEC_PATH1_CTL1 0x8D0 -#define CXADEC_PATH1_VOL_CTL 0x8D4 -#define CXADEC_PATH1_EQ_CTL 0x8D8 -#define CXADEC_PATH1_SC_CTL 0x8DC - -#define CXADEC_PATH2_CTL1 0x8E0 -#define CXADEC_PATH2_VOL_CTL 0x8E4 -#define CXADEC_PATH2_EQ_CTL 0x8E8 -#define CXADEC_PATH2_SC_CTL 0x8EC - -#define CXADEC_SRC_CTL 0x8F0 -#define CXADEC_SRC_LF_COEF 0x8F4 -#define CXADEC_SRC1_CTL 0x8F8 -#define CXADEC_SRC2_CTL 0x8FC -#define CXADEC_SRC3_CTL 0x900 -#define CXADEC_SRC4_CTL 0x904 -#define CXADEC_SRC5_CTL 0x908 -#define CXADEC_SRC6_CTL 0x90C - -#define CXADEC_BASEBAND_OUT_SEL 0x910 -#define CXADEC_I2S_IN_CTL 0x914 -#define CXADEC_I2S_OUT_CTL 0x918 -#define CXADEC_AC97_CTL 0x91C -#define CXADEC_QAM_PDF 0x920 -#define CXADEC_QAM_CONST_DEC 0x924 -#define CXADEC_QAM_ROTATOR_FREQ 0x948 - -/* Bit defintions / settings used in Mako Audio */ -#define CXADEC_PREF_MODE_MONO_LANGA 0 -#define CXADEC_PREF_MODE_MONO_LANGB 1 -#define CXADEC_PREF_MODE_MONO_LANGC 2 -#define CXADEC_PREF_MODE_FALLBACK 3 -#define CXADEC_PREF_MODE_STEREO 4 -#define CXADEC_PREF_MODE_DUAL_LANG_AC 5 -#define CXADEC_PREF_MODE_DUAL_LANG_BC 6 -#define CXADEC_PREF_MODE_DUAL_LANG_AB 7 - - -#define CXADEC_DETECT_STEREO 1 -#define CXADEC_DETECT_DUAL 2 -#define CXADEC_DETECT_TRI 4 -#define CXADEC_DETECT_SAP 0x10 -#define CXADEC_DETECT_NO_SIGNAL 0xFF - -#define CXADEC_SELECT_AUDIO_STANDARD_BG 0xF0 /* NICAM BG and A2 BG */ -#define CXADEC_SELECT_AUDIO_STANDARD_DK1 0xF1 /* NICAM DK and A2 DK */ -#define CXADEC_SELECT_AUDIO_STANDARD_DK2 0xF2 -#define CXADEC_SELECT_AUDIO_STANDARD_DK3 0xF3 -#define CXADEC_SELECT_AUDIO_STANDARD_I 0xF4 /* NICAM I and A1 */ -#define CXADEC_SELECT_AUDIO_STANDARD_L 0xF5 /* NICAM L and System L AM */ -#define CXADEC_SELECT_AUDIO_STANDARD_BTSC 0xF6 -#define CXADEC_SELECT_AUDIO_STANDARD_EIAJ 0xF7 -#define CXADEC_SELECT_AUDIO_STANDARD_A2_M 0xF8 /* A2 M */ -#define CXADEC_SELECT_AUDIO_STANDARD_FM 0xF9 /* FM radio */ -#define CXADEC_SELECT_AUDIO_STANDARD_AUTO 0xFF /* Auto detect */ - -/* ----------------------------------------------------------------------- */ -/* cx18_av-core.c */ -int cx18_av_write(struct cx18 *cx, u16 addr, u8 value); -int cx18_av_write4(struct cx18 *cx, u16 addr, u32 value); -int cx18_av_write4_noretry(struct cx18 *cx, u16 addr, u32 value); -int cx18_av_write_expect(struct cx18 *cx, u16 addr, u8 value, u8 eval, u8 mask); -int cx18_av_write4_expect(struct cx18 *cx, u16 addr, u32 value, u32 eval, - u32 mask); -u8 cx18_av_read(struct cx18 *cx, u16 addr); -u32 cx18_av_read4(struct cx18 *cx, u16 addr); -int cx18_av_and_or(struct cx18 *cx, u16 addr, unsigned mask, u8 value); -int cx18_av_and_or4(struct cx18 *cx, u16 addr, u32 mask, u32 value); -int cx18_av_cmd(struct cx18 *cx, unsigned int cmd, void *arg); -void cx18_av_std_setup(struct cx18 *cx); - -/* ----------------------------------------------------------------------- */ -/* cx18_av-firmware.c */ -int cx18_av_loadfw(struct cx18 *cx); - -/* ----------------------------------------------------------------------- */ -/* cx18_av-audio.c */ -int cx18_av_audio(struct cx18 *cx, unsigned int cmd, void *arg); -void cx18_av_audio_set_path(struct cx18 *cx); - -/* ----------------------------------------------------------------------- */ -/* cx18_av-vbi.c */ -int cx18_av_vbi(struct cx18 *cx, unsigned int cmd, void *arg); - -#endif diff --git a/drivers/media/video/cx18/cx18-av-firmware.c b/drivers/media/video/cx18/cx18-av-firmware.c deleted file mode 100644 index c64fd0a05a9..00000000000 --- a/drivers/media/video/cx18/cx18-av-firmware.c +++ /dev/null @@ -1,147 +0,0 @@ -/* - * cx18 ADEC firmware functions - * - * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> - * Copyright (C) 2008 Andy Walls <awalls@radix.net> - * - * 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., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - -#include "cx18-driver.h" -#include "cx18-io.h" -#include <linux/firmware.h> - -#define CX18_AUDIO_ENABLE 0xc72014 -#define FWFILE "v4l-cx23418-dig.fw" - -int cx18_av_loadfw(struct cx18 *cx) -{ - const struct firmware *fw = NULL; - u32 size; - u32 v; - const u8 *ptr; - int i; - int retries1 = 0; - - if (request_firmware(&fw, FWFILE, &cx->dev->dev) != 0) { - CX18_ERR("unable to open firmware %s\n", FWFILE); - return -EINVAL; - } - - /* The firmware load often has byte errors, so allow for several - retries, both at byte level and at the firmware load level. */ - while (retries1 < 5) { - cx18_av_write4_expect(cx, CXADEC_CHIP_CTRL, 0x00010000, - 0x00008430, 0xffffffff); /* cx25843 */ - cx18_av_write_expect(cx, CXADEC_STD_DET_CTL, 0xf6, 0xf6, 0xff); - - /* Reset the Mako core, Register is alias of CXADEC_CHIP_CTRL */ - cx18_av_write4_expect(cx, 0x8100, 0x00010000, - 0x00008430, 0xffffffff); /* cx25843 */ - - /* Put the 8051 in reset and enable firmware upload */ - cx18_av_write4_noretry(cx, CXADEC_DL_CTL, 0x0F000000); - - ptr = fw->data; - size = fw->size; - - for (i = 0; i < size; i++) { - u32 dl_control = 0x0F000000 | i | ((u32)ptr[i] << 16); - u32 value = 0; - int retries2; - int unrec_err = 0; - - for (retries2 = 0; retries2 < CX18_MAX_MMIO_WR_RETRIES; - retries2++) { - cx18_av_write4_noretry(cx, CXADEC_DL_CTL, - dl_control); - udelay(10); - value = cx18_av_read4(cx, CXADEC_DL_CTL); - if (value == dl_control) - break; - /* Check if we can correct the byte by changing - the address. We can only write the lower - address byte of the address. */ - if ((value & 0x3F00) != (dl_control & 0x3F00)) { - unrec_err = 1; - break; - } - } - if (unrec_err || retries2 >= CX18_MAX_MMIO_WR_RETRIES) - break; - } - if (i == size) - break; - retries1++; - } - if (retries1 >= 5) { - CX18_ERR("unable to load firmware %s\n", FWFILE); - release_firmware(fw); - return -EIO; - } - - cx18_av_write4_expect(cx, CXADEC_DL_CTL, - 0x13000000 | fw->size, 0x13000000, 0x13000000); - - /* Output to the 416 */ - cx18_av_and_or4(cx, CXADEC_PIN_CTRL1, ~0, 0x78000); - - /* Audio input control 1 set to Sony mode */ - /* Audio output input 2 is 0 for slave operation input */ - /* 0xC4000914[5]: 0 = left sample on WS=0, 1 = left sample on WS=1 */ - /* 0xC4000914[7]: 0 = Philips mode, 1 = Sony mode (1st SCK rising edge - after WS transition for first bit of audio word. */ - cx18_av_write4(cx, CXADEC_I2S_IN_CTL, 0x000000A0); - - /* Audio output control 1 is set to Sony mode */ - /* Audio output control 2 is set to 1 for master mode */ - /* 0xC4000918[5]: 0 = left sample on WS=0, 1 = left sample on WS=1 */ - /* 0xC4000918[7]: 0 = Philips mode, 1 = Sony mode (1st SCK rising edge - after WS transition for first bit of audio word. */ - /* 0xC4000918[8]: 0 = slave operation, 1 = master (SCK_OUT and WS_OUT - are generated) */ - cx18_av_write4(cx, CXADEC_I2S_OUT_CTL, 0x000001A0); - - /* set alt I2s master clock to /16 and enable alt divider i2s - passthrough */ - cx18_av_write4(cx, CXADEC_PIN_CFG3, 0x5000B687); - - cx18_av_write4_expect(cx, CXADEC_STD_DET_CTL, 0x000000F6, 0x000000F6, - 0x3F00FFFF); - /* CxDevWrReg(CXADEC_STD_DET_CTL, 0x000000FF); */ - - /* Set bit 0 in register 0x9CC to signify that this is MiniMe. */ - /* Register 0x09CC is defined by the Merlin firmware, and doesn't - have a name in the spec. */ - cx18_av_write4(cx, 0x09CC, 1); - - v = cx18_read_reg(cx, CX18_AUDIO_ENABLE); - /* If bit 11 is 1, clear bit 10 */ - if (v & 0x800) - cx18_write_reg(cx, v & 0xFFFFFBFF, CX18_AUDIO_ENABLE); - - /* Enable WW auto audio standard detection */ - v = cx18_av_read4(cx, CXADEC_STD_DET_CTL); - v |= 0xFF; /* Auto by default */ - v |= 0x400; /* Stereo by default */ - v |= 0x14000000; - cx18_av_write4_expect(cx, CXADEC_STD_DET_CTL, v, v, 0x3F00FFFF); - - release_firmware(fw); - - CX18_INFO("loaded %s firmware (%d bytes)\n", FWFILE, size); - return 0; -} diff --git a/drivers/media/video/cx18/cx18-av-vbi.c b/drivers/media/video/cx18/cx18-av-vbi.c deleted file mode 100644 index 1527ea4f6b0..00000000000 --- a/drivers/media/video/cx18/cx18-av-vbi.c +++ /dev/null @@ -1,270 +0,0 @@ -/* - * cx18 ADEC VBI functions - * - * Derived from cx25840-vbi.c - * - * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> - * - * 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., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA. - */ - - -#include "cx18-driver.h" - -static int odd_parity(u8 c) -{ - c ^= (c >> 4); - c ^= (c >> 2); - c ^= (c >> 1); - - return c & 1; -} - -static int decode_vps(u8 *dst, u8 *p) -{ - static const u8 biphase_tbl[] = { - 0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4, - 0xb0, 0x38, 0x30, 0xb0, 0xf0, 0x78, 0x70, 0xf0, - 0xd2, 0x5a, 0x52, 0xd2, 0x96, 0x1e, 0x16, 0x96, - 0x92, 0x1a, 0x12, 0x92, 0xd2, 0x5a, 0x52, 0xd2, - 0xd0, 0x58, 0x50, 0xd0, 0x94, 0x1c, 0x14, 0x94, - 0x90, 0x18, 0x10, 0x90, 0xd0, 0x58, 0x50, 0xd0, - 0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4, - 0xb0, 0x38, 0x30, 0xb0, 0xf0, 0x78, 0x70, 0xf0, - 0xe1, 0x69, 0x61, 0xe1, 0xa5, 0x2d, 0x25, 0xa5, - 0xa1, 0x29, 0x21, 0xa1, 0xe1, 0x69, 0x61, 0xe1, - 0xc3, 0x4b, 0x43, 0xc3, 0x87, 0x0f, 0x07, 0x87, - 0x83, 0x0b, 0x03, 0x83, 0xc3, 0x4b, 0x43, 0xc3, - 0xc1, 0x49, 0x41, 0xc1, 0x85, 0x0d, 0x05, 0x85, - 0x81, 0x09, 0x01, 0x81, 0xc1, 0x49, 0x41, 0xc1, - 0xe1, 0x69, 0x61, 0xe1, 0xa5, 0x2d, 0x25, 0xa5, - 0xa1, 0x29, 0x21, 0xa1, 0xe1, 0x69, 0x61, 0xe1, - 0xe0, 0x68, 0x60, 0xe0, 0xa4, 0x2c, 0x24, 0xa4, - 0xa0, 0x28, 0x20, 0xa0, 0xe0, 0x68, 0x60, 0xe0, - 0xc2, 0x4a, 0x42, 0xc2, 0x86, 0x0e, 0x06, 0x86, - 0x82, 0x0a, 0x02, 0x82, 0xc2, 0x4a, 0x42, 0xc2, - 0xc0, 0x48, 0x40, 0xc0, 0x84, 0x0c, 0x04, 0x84, - 0x80, 0x08, 0x00, 0x80, 0xc0, 0x48, 0x40, 0xc0, - 0xe0, 0x68, 0x60, 0xe0, 0xa4, 0x2c, 0x24, 0xa4, - 0xa0, 0x28, 0x20, 0xa0, 0xe0, 0x68, 0x60, 0xe0, - 0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4, - 0xb0, 0x38, 0x30, 0xb0, 0xf0, 0x78, 0x70, 0xf0, - 0xd2, 0x5a, 0x52, 0xd2, 0x96, 0x1e, 0x16, 0x96, - 0x92, 0x1a, 0x12, 0x92, 0xd2, 0x5a, 0x52, 0xd2, - 0xd0, 0x58, 0x50, 0xd0, 0x94, 0x1c, 0x14, 0x94, - 0x90, 0x18, 0x10, 0x90, 0xd0, 0x58, 0x50, 0xd0, - 0xf0, 0x78, 0x70, 0xf0, 0xb4, 0x3c, 0x34, 0xb4, - 0xb0, 0x38, 0x30, 0xb0, 0xf0, 0x78, 0x70, 0xf0, - }; - - u8 c, err = 0; - int i; - - for (i = 0; i < 2 * 13; i += 2) { - err |= biphase_tbl[p[i]] | biphase_tbl[p[i + 1]]; - c = (biphase_tbl[p[i + 1]] & 0xf) | - ((biphase_tbl[p[i]] & 0xf) << 4); - dst[i / 2] = c; - } - - return err & 0xf0; -} - -int cx18_av_vbi(struct cx18 *cx, unsigned int cmd, void *arg) -{ - struct cx18_av_state *state = &cx->av_state; - struct v4l2_format *fmt; - struct v4l2_sliced_vbi_format *svbi; - - switch (cmd) { - case VIDIOC_G_FMT: - { - static u16 lcr2vbi[] = { - 0, V4L2_SLICED_TELETEXT_B, 0, /* 1 */ - 0, V4L2_SLICED_WSS_625, 0, /* 4 */ - V4L2_SLICED_CAPTION_525, /* 6 */ - 0, 0, V4L2_SLICED_VPS, 0, 0, /* 9 */ - 0, 0, 0, 0 - }; - int is_pal = !(state->std & V4L2_STD_525_60); - int i; - - fmt = arg; - if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) - return -EINVAL; - svbi = &fmt->fmt.sliced; - memset(svbi, 0, sizeof(*svbi)); - /* we're done if raw VBI is active */ - if ((cx18_av_read(cx, 0x404) & 0x10) == 0) - break; - - if (is_pal) { - for (i = 7; i <= 23; i++) { - u8 v = cx18_av_read(cx, 0x424 + i - 7); - - svbi->service_lines[0][i] = lcr2vbi[v >> 4]; - svbi->service_lines[1][i] = lcr2vbi[v & 0xf]; - svbi->service_set |= svbi->service_lines[0][i] | - svbi->service_lines[1][i]; - } - } else { - for (i = 10; i <= 21; i++) { - u8 v = cx18_av_read(cx, 0x424 + i - 10); - - svbi->service_lines[0][i] = lcr2vbi[v >> 4]; - svbi->service_lines[1][i] = lcr2vbi[v & 0xf]; - svbi->service_set |= svbi->service_lines[0][i] | - svbi->service_lines[1][i]; - } - } - break; - } - - case VIDIOC_S_FMT: - { - int is_pal = !(state->std & V4L2_STD_525_60); - int vbi_offset = is_pal ? 1 : 0; - int i, x; - u8 lcr[24]; - - fmt = arg; - if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE && - fmt->type != V4L2_BUF_TYPE_VBI_CAPTURE) - return -EINVAL; - svbi = &fmt->fmt.sliced; - if (fmt->type == V4L2_BUF_TYPE_VBI_CAPTURE) { - /* raw VBI */ - memset(svbi, 0, sizeof(*svbi)); - - /* Setup standard */ - cx18_av_std_setup(cx); - - /* VBI Offset */ - cx18_av_write(cx, 0x47f, vbi_offset); - cx18_av_write(cx, 0x404, 0x2e); - break; - } - - for (x = 0; x <= 23; x++) - lcr[x] = 0x00; - - /* Setup standard */ - cx18_av_std_setup(cx); - - /* Sliced VBI */ - cx18_av_write(cx, 0x404, 0x32); /* Ancillary data */ - cx18_av_write(cx, 0x406, 0x13); - cx18_av_write(cx, 0x47f, vbi_offset); - - if (is_pal) { - for (i = 0; i <= 6; i++) - svbi->service_lines[0][i] = - svbi->service_lines[1][i] = 0; - } else { - for (i = 0; i <= 9; i++) - svbi->service_lines[0][i] = - svbi->service_lines[1][i] = 0; - - for (i = 22; i <= 23; i++) - svbi->service_lines[0][i] = - svbi->service_lines[1][i] = 0; - } - - for (i = 7; i <= 23; i++) { - for (x = 0; x <= 1; x++) { - switch (svbi->service_lines[1-x][i]) { - case V4L2_SLICED_TELETEXT_B: - lcr[i] |= 1 << (4 * x); - break; - case V4L2_SLICED_WSS_625: - lcr[i] |= 4 << (4 * x); - break; - case V4L2_SLICED_CAPTION_525: - lcr[i] |= 6 << (4 * x); - break; - case V4L2_SLICED_VPS: - lcr[i] |= 9 << (4 * x); - break; - } - } - } - - if (is_pal) { - for (x = 1, i = 0x424; i <= 0x434; i++, x++) - cx18_av_write(cx, i, lcr[6 + x]); - } else { - for (x = 1, i = 0x424; i <= 0x430; i++, x++) - cx18_av_write(cx, i, lcr[9 + x]); - for (i = 0x431; i <= 0x434; i++) - cx18_av_write(cx, i, 0); - } - - cx18_av_write(cx, 0x43c, 0x16); - cx18_av_write(cx, 0x474, is_pal ? 0x2a : 0x22); - break; - } - - case VIDIOC_INT_DECODE_VBI_LINE: - { - struct v4l2_decode_vbi_line *vbi = arg; - u8 *p = vbi->p; - int id1, id2, l, err = 0; - - if (p[0] || p[1] != 0xff || p[2] != 0xff || - (p[3] != 0x55 && p[3] != 0x91)) { - vbi->line = vbi->type = 0; - break; - } - - p += 4; - id1 = p[-1]; - id2 = p[0] & 0xf; - l = p[2] & 0x3f; - l += state->vbi_line_offset; - p += 4; - - switch (id2) { - case 1: - id2 = V4L2_SLICED_TELETEXT_B; - break; - case 4: - id2 = V4L2_SLICED_WSS_625; - break; - case 6: - id2 = V4L2_SLICED_CAPTION_525; - err = !odd_parity(p[0]) || !odd_parity(p[1]); - break; - case 9: - id2 = V4L2_SLICED_VPS; - if (decode_vps(p, p) != 0) - err = 1; - break; - default: - id2 = 0; - err = 1; - break; - } - - vbi->type = err ? 0 : id2; - vbi->line = err ? 0 : l; - vbi->is_second_field = err ? 0 : (id1 == 0x55); - vbi->p = p; - break; - } - } - - return 0; -} diff --git a/drivers/media/video/cx18/cx18-cards.c b/drivers/media/video/cx18/cx18-cards.c deleted file mode 100644 index e274043657d..00000000000 --- a/drivers/media/video/cx18/cx18-cards.c +++ /dev/null @@ -1,455 +0,0 @@ -/* - * cx18 functions to query card hardware - * - * Derived from ivtv-cards.c - * - * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> - * Copyright (C) 2008 Andy Walls <awalls@radix.net> - * - * 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., 59 Temple Place, Suite 330, Boston, MA - * 02111-1307 USA - */ - -#include "cx18-driver.h" -#include "cx18-cards.h" -#include "cx18-av-core.h" -#include "cx18-i2c.h" -#include <media/cs5345.h> - -#define V4L2_STD_PAL_SECAM (V4L2_STD_PAL|V4L2_STD_SECAM) - -/********************** card configuration *******************************/ - -/* usual i2c tuner addresses to probe */ -static struct cx18_card_tuner_i2c cx18_i2c_std = { - .radio = { I2C_CLIENT_END }, - .demod = { 0x43, I2C_CLIENT_END }, - .tv = { 0x61, 0x60, I2C_CLIENT_END }, -}; - -/* Please add new PCI IDs to: http://pci-ids.ucw.cz/iii - This keeps the PCI ID database up to date. Note that the entries - must be added under vendor 0x4444 (Conexant) as subsystem IDs. - New vendor IDs should still be added to the vendor ID list. */ - -/* Hauppauge HVR-1600 cards */ - -/* Note: for Hauppauge cards the tveeprom information is used instead - of PCI IDs */ -static const struct cx18_card cx18_card_hvr1600_esmt = { - .type = CX18_CARD_HVR_1600_ESMT, - .name = "Hauppauge HVR-1600", - .comment = "Raw VBI supported; Sliced VBI is not yet supported\n", - .v4l2_capabilities = CX18_CAP_ENCODER, - .hw_audio_ctrl = CX18_HW_CX23418, - .hw_muxer = CX18_HW_CS5345, - .hw_all = CX18_HW_TVEEPROM | CX18_HW_TUNER | - CX18_HW_CS5345 | CX18_HW_DVB, - .video_inputs = { - { CX18_CARD_INPUT_VID_TUNER, 0, CX18_AV_COMPOSITE7 }, - { CX18_CARD_INPUT_SVIDEO1, 1, CX18_AV_SVIDEO1 }, - { CX18_CARD_INPUT_COMPOSITE1, 1, CX18_AV_COMPOSITE3 }, - { CX18_CARD_INPUT_SVIDEO2, 2, CX18_AV_SVIDEO2 }, - { CX18_CARD_INPUT_COMPOSITE2, 2, CX18_AV_COMPOSITE4 }, - }, - .audio_inputs = { - { CX18_CARD_INPUT_AUD_TUNER, - CX18_AV_AUDIO8, CS5345_IN_1 | CS5345_MCLK_1_5 }, - { CX18_CARD_INPUT_LINE_IN1, - CX18_AV_AUDIO_SERIAL1, CS5345_IN_2 }, - { CX18_CARD_INPUT_LINE_IN2, - CX18_AV_AUDIO_SERIAL1, CS5345_IN_3 }, - }, - .radio_input = { CX18_CARD_INPUT_AUD_TUNER, - CX18_AV_AUDIO_SERIAL1, CS5345_IN_4 }, - .ddr = { - /* ESMT M13S128324A-5B memory */ - .chip_config = 0x003, - .refresh = 0x30c, - .timing1 = 0x44220e82, - .timing2 = 0x08, - .tune_lane = 0, - .initial_emrs = 0, - }, - .gpio_init.initial_value = 0x3001, - .gpio_init.direction = 0x3001, - .gpio_i2c_slave_reset = { - .active_lo_mask = 0x3001, - .msecs_asserted = 10, - .msecs_recovery = 40, - .ir_reset_mask = 0x0001, - }, - .i2c = &cx18_i2c_std, -}; - -static const struct cx18_card cx18_card_hvr1600_samsung = { - .type = CX18_CARD_HVR_1600_SAMSUNG, - .name = "Hauppauge HVR-1600 (Preproduction)", - .comment = "Raw VBI supported; Sliced VBI is not yet supported\n", - .v4l2_capabilities = CX18_CAP_ENCODER, - .hw_audio_ctrl = CX18_HW_CX23418, - .hw_muxer = CX18_HW_CS5345, - .hw_all = CX18_HW_TVEEPROM | CX18_HW_TUNER | - CX18_HW_CS5345 | CX18_HW_DVB, - .video_inputs = { - { CX18_CARD_INPUT_VID_TUNER, 0, CX18_AV_COMPOSITE7 }, - { CX18_CARD_INPUT_SVIDEO1, 1, CX18_AV_SVIDEO1 }, - { CX18_CARD_INPUT_COMPOSITE1, 1, CX18_AV_COMPOSITE3 }, - { CX18_CARD_INPUT_SVIDEO2, 2, CX18_AV_SVIDEO2 }, - { CX18_CARD_INPUT_COMPOSITE2, 2, CX18_AV_COMPOSITE4 }, - }, - .audio_inputs = { - { CX18_CARD_INPUT_AUD_TUNER, - CX18_AV_AUDIO8, CS5345_IN_1 | CS5345_MCLK_1_5 }, - { CX18_CARD_INPUT_LINE_IN1, - CX18_AV_AUDIO_SERIAL1, CS5345_IN_2 }, - { CX18_CARD_INPUT_LINE_IN2, - CX18_AV_AUDIO_SERIAL1, CS5345_IN_3 }, - }, - .radio_input = { CX18_CARD_INPUT_AUD_TUNER, - CX18_AV_AUDIO_SERIAL1, CS5345_IN_4 }, - .ddr = { - /* Samsung K4D263238G-VC33 memory */ - .chip_config = 0x003, - .refresh = 0x30c, - .timing1 = 0x23230b73, - .timing2 = 0x08, - .tune_lane = 0, - .initial_emrs = 2, - }, - .gpio_init.initial_value = 0x3001, - .gpio_init.direction = 0x3001, - .gpio_i2c_slave_reset = { - .active_lo_mask = 0x3001, - .msecs_asserted = 10, - .msecs_recovery = 40, - .ir_reset_mask = 0x0001, - }, - .i2c = &cx18_i2c_std, -}; - -/* ------------------------------------------------------------------------- */ - -/* Compro VideoMate H900: note that this card is analog only! */ - -static const struct cx18_card_pci_info cx18_pci_h900[] = { - { PCI_DEVICE_ID_CX23418, CX18_PCI_ID_COMPRO, 0xe100 }, - { 0, 0, 0 } -}; - -static const struct cx18_card cx18_card_h900 = { - .type = CX18_CARD_COMPRO_H900, - .name = "Compro VideoMate H900", - .comment = "Raw VBI supported; Sliced VBI is not yet supported\n", - .v4l2_capabilities = CX18_CAP_ENCODER, - .hw_audio_ctrl = CX18_HW_CX23418, - .hw_all = CX18_HW_TUNER, - .video_inputs = { - { CX18_CARD_INPUT_VID_TUNER, 0, CX18_AV_COMPOSITE2 }, - { CX18_CARD_INPUT_SVIDEO1, 1, - CX18_AV_SVIDEO_LUMA3 | CX18_AV_SVIDEO_CHROMA4 }, - { CX18_CARD_INPUT_COMPOSITE1, 1, CX18_AV_COMPOSITE1 }, - }, - .audio_inputs = { - { CX18_CARD_INPUT_AUD_TUNER, - CX18_AV_AUDIO5, 0 }, - { CX18_CARD_INPUT_LINE_IN1, - CX18_AV_AUDIO_SERIAL1, 0 }, - }, - .radio_input = { CX18_CARD_INPUT_AUD_TUNER, - CX18_AV_AUDIO_SERIAL1, 0 }, - .tuners = { - { .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 }, - }, - .ddr = { - /* EtronTech EM6A9160TS-5G memory */ - .chip_config = 0x50003, - .refresh = 0x753, - .timing1 = 0x24330e84, - .timing2 = 0x1f, - .tune_lane = 0, - .initial_emrs = 0, - }, - .xceive_pin = 15, - .pci_list = cx18_pci_h900, - .i2c = &cx18_i2c_std, -}; - -/* ------------------------------------------------------------------------- */ - -/* Yuan MPC718: not working at the moment! */ - -static const struct cx18_card_pci_info cx18_pci_mpc718[] = { - { PCI_DEVICE_ID_CX23418, CX18_PCI_ID_YUAN, 0x0718 }, - { 0, 0, 0 } -}; - -static const struct cx18_card cx18_card_mpc718 = { - .type = CX18_CARD_YUAN_MPC718, - .name = "Yuan MPC718", - .comment = "Analog video capture works; some audio line in may not.\n", - .v4l2_capabilities = CX18_CAP_ENCODER, - .hw_audio_ctrl = CX18_HW_CX23418, - .hw_all = CX18_HW_TUNER, - .video_inputs = { - { CX18_CARD_INPUT_VID_TUNER, 0, CX18_AV_COMPOSITE2 }, - { CX18_CARD_INPUT_SVIDEO1, 1, - CX18_AV_SVIDEO_LUMA3 | CX18_AV_SVIDEO_CHROMA4 }, - { CX18_CARD_INPUT_COMPOSITE1, 1, CX18_AV_COMPOSITE1 }, - { CX18_CARD_INPUT_SVIDEO2, 2, - CX18_AV_SVIDEO_LUMA7 | CX18_AV_SVIDEO_CHROMA8 }, - { CX18_CARD_INPUT_COMPOSITE2, 2, CX18_AV_COMPOSITE6 }, - { CX18_CARD_INPUT_COMPOSITE3, 2, CX18_AV_COMPOSITE3 }, - }, - .audio_inputs = { - { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO5, 0 }, - { CX18_CARD_INPUT_LINE_IN1, CX18_AV_AUDIO_SERIAL1, 0 }, - { CX18_CARD_INPUT_LINE_IN2, CX18_AV_AUDIO_SERIAL1, 0 }, - }, - .radio_input = { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO_SERIAL1, 0 }, - .tuners = { - /* XC3028 tuner */ - { .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 }, - }, - .ddr = { - /* Probably Samsung K4D263238G-VC33 memory */ - .chip_config = 0x003, - .refresh = 0x30c, - .timing1 = 0x23230b73, - .timing2 = 0x08, - .tune_lane = 0, - .initial_emrs = 2, - }, - .xceive_pin = 0, - .pci_list = cx18_pci_mpc718, - .i2c = &cx18_i2c_std, -}; - -/* ------------------------------------------------------------------------- */ - -/* Conexant Raptor PAL/SECAM: note that this card is analog only! */ - -static const struct cx18_card_pci_info cx18_pci_cnxt_raptor_pal[] = { - { PCI_DEVICE_ID_CX23418, CX18_PCI_ID_CONEXANT, 0x0009 }, - { 0, 0, 0 } -}; - -static const struct cx18_card cx18_card_cnxt_raptor_pal = { - .type = CX18_CARD_CNXT_RAPTOR_PAL, - .name = "Conexant Raptor PAL/SECAM", - .comment = "Raw VBI supported; Sliced VBI is not yet supported\n", - .v4l2_capabilities = CX18_CAP_ENCODER, - .hw_audio_ctrl = CX18_HW_CX23418, - .hw_muxer = CX18_HW_GPIO, - .hw_all = CX18_HW_TUNER | CX18_HW_GPIO, - .video_inputs = { - { CX18_CARD_INPUT_VID_TUNER, 0, CX18_AV_COMPOSITE2 }, - { CX18_CARD_INPUT_SVIDEO1, 1, - CX18_AV_SVIDEO_LUMA3 | CX18_AV_SVIDEO_CHROMA4 }, - { CX18_CARD_INPUT_COMPOSITE1, 1, CX18_AV_COMPOSITE1 }, - { CX18_CARD_INPUT_SVIDEO2, 2, - CX18_AV_SVIDEO_LUMA7 | CX18_AV_SVIDEO_CHROMA8 }, - { CX18_CARD_INPUT_COMPOSITE2, 2, CX18_AV_COMPOSITE6 }, - }, - .audio_inputs = { - { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO5, 0 }, - { CX18_CARD_INPUT_LINE_IN1, CX18_AV_AUDIO_SERIAL1, 1 }, - { CX18_CARD_INPUT_LINE_IN2, CX18_AV_AUDIO_SERIAL2, 1 }, - }, - .tuners = { - { .std = V4L2_STD_PAL_SECAM, .tuner = TUNER_PHILIPS_FM1216ME_MK3 }, - }, - .radio_input = { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO_SERIAL1, 2 }, - .ddr = { - /* MT 46V16M16 memory */ - .chip_config = 0x50306, - .refresh = 0x753, - .timing1 = 0x33220953, - .timing2 = 0x09, - .tune_lane = 0, - .initial_emrs = 0, - }, - .gpio_init.initial_value = 0x1002, - .gpio_init.direction = 0xf002, - .gpio_audio_input = { .mask = 0xf002, - .tuner = 0x1002, /* LED D1 Tuner AF */ - .linein = 0x2000, /* LED D2 Line In 1 */ - .radio = 0x4002 }, /* LED D3 Tuner AF */ - .pci_list = cx18_pci_cnxt_raptor_pal, - .i2c = &cx18_i2c_std, -}; - -/* ------------------------------------------------------------------------- */ - -/* Toshiba Qosmio laptop internal DVB-T/Analog Hybrid Tuner */ - -static const struct cx18_card_pci_info cx18_pci_toshiba_qosmio_dvbt[] = { - { PCI_DEVICE_ID_CX23418, CX18_PCI_ID_TOSHIBA, 0x0110 }, - { 0, 0, 0 } -}; - -static const struct cx18_card cx18_card_toshiba_qosmio_dvbt = { - .type = CX18_CARD_TOSHIBA_QOSMIO_DVBT, - .name = "Toshiba Qosmio DVB-T/Analog", - .comment = "Experimenters and photos needed for device to work well.\n" - "\tTo help, mail the ivtv-devel list (www.ivtvdriver.org).\n", - .v4l2_capabilities = CX18_CAP_ENCODER, - .hw_audio_ctrl = CX18_HW_CX23418, - .hw_all = CX18_HW_TUNER, - .video_inputs = { - { CX18_CARD_INPUT_VID_TUNER, 0, CX18_AV_COMPOSITE6 }, - { CX18_CARD_INPUT_SVIDEO1, 1, - CX18_AV_SVIDEO_LUMA3 | CX18_AV_SVIDEO_CHROMA4 }, - { CX18_CARD_INPUT_COMPOSITE1, 1, CX18_AV_COMPOSITE1 }, - }, - .audio_inputs = { - { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO5, 0 }, - { CX18_CARD_INPUT_LINE_IN1, CX18_AV_AUDIO_SERIAL1, 1 }, - }, - .tuners = { - { .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 }, - }, - .ddr = { - .chip_config = 0x202, - .refresh = 0x3bb, - .timing1 = 0x33320a63, - .timing2 = 0x0a, - .tune_lane = 0, - .initial_emrs = 0x42, - }, - .xceive_pin = 15, - .pci_list = cx18_pci_toshiba_qosmio_dvbt, - .i2c = &cx18_i2c_std, -}; - -/* ------------------------------------------------------------------------- */ - -/* Leadtek WinFast PVR2100 */ - -static const struct cx18_card_pci_info cx18_pci_leadtek_pvr2100[] = { - { PCI_DEVICE_ID_CX23418, CX18_PCI_ID_LEADTEK, 0x6f27 }, - { 0, 0, 0 } -}; - -static const struct cx18_card cx18_card_leadtek_pvr2100 = { - .type = CX18_CARD_LEADTEK_PVR2100, - .name = "Leadtek WinFast PVR2100", - .comment = "Experimenters and photos needed for device to work well.\n" - "\tTo help, mail the ivtv-devel list (www.ivtvdriver.org).\n", - .v4l2_capabilities = CX18_CAP_ENCODER, - .hw_audio_ctrl = CX18_HW_CX23418, - .hw_muxer = CX18_HW_GPIO, - .hw_all = CX18_HW_TUNER | CX18_HW_GPIO, - .video_inputs = { - { CX18_CARD_INPUT_VID_TUNER, 0, CX18_AV_COMPOSITE2 }, - { CX18_CARD_INPUT_SVIDEO1, 1, - CX18_AV_SVIDEO_LUMA3 | CX18_AV_SVIDEO_CHROMA4 }, - { CX18_CARD_INPUT_COMPOSITE1, 1, CX18_AV_COMPOSITE7 }, - }, - .audio_inputs = { - { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO5, 0 }, - { CX18_CARD_INPUT_LINE_IN1, CX18_AV_AUDIO_SERIAL1, 1 }, - }, - .tuners = { - /* XC3028 tuner */ - { .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 }, - }, - .radio_input = { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO5, 2 }, - .ddr = { - /* - * Pointer to proper DDR config values provided by - * Terry Wu <terrywu at leadtek.com.tw> - */ - .chip_config = 0x303, - .refresh = 0x3bb, - .timing1 = 0x24220e83, - .timing2 = 0x1f, - .tune_lane = 0, - .initial_emrs = 0x2, - }, - .gpio_init.initial_value = 0x6, - .gpio_init.direction = 0x7, - .gpio_audio_input = { .mask = 0x7, - .tuner = 0x6, .linein = 0x2, .radio = 0x2 }, - .xceive_pin = 15, - .pci_list = cx18_pci_leadtek_pvr2100, - .i2c = &cx18_i2c_std, -}; - -/* ------------------------------------------------------------------------- */ - -static const struct cx18_card *cx18_card_list[] = { - &cx18_card_hvr1600_esmt, - &cx18_card_hvr1600_samsung, - &cx18_card_h900, - &cx18_card_mpc718, - &cx18_card_cnxt_raptor_pal, - &cx18_card_toshiba_qosmio_dvbt, - &cx18_card_leadtek_pvr2100, -}; - -const struct cx18_card *cx18_get_card(u16 index) -{ - if (index >= ARRAY_SIZE(cx18_card_list)) - return NULL; - return cx18_card_list[index]; -} - -int cx18_get_input(struct cx18 *cx, u16 index, struct v4l2_input *input) -{ - const struct cx18_card_video_input *card_input = - cx->card->video_inputs + index; - static const char * const input_strs[] = { - "Tuner 1", - "S-Video 1", - "S-Video 2", - "Composite 1", - "Composite 2", - "Composite 3" - }; - - memset(input, 0, sizeof(*input)); - if (index >= cx->nof_inputs) - return -EINVAL; - input->index = index; - strlcpy(input->name, input_strs[card_input->video_type - 1], - sizeof(input->name)); - input->type = (card_input->video_type == CX18_CARD_INPUT_VID_TUNER ? - V4L2_INPUT_TYPE_TUNER : V4L2_INPUT_TYPE_CAMERA); - input->audioset = (1 << cx->nof_audio_inputs) - 1; - input->std = (input->type == V4L2_INPUT_TYPE_TUNER) ? - cx->tuner_std : V4L2_STD_ALL; - return 0; -} - -int cx18_get_audio_input(struct cx18 *cx, u16 index, struct v4l2_audio *audio) -{ - const struct cx18_card_audio_input *aud_input = - cx->card->audio_inputs + index; - static const char * const input_strs[] = { - "Tuner 1", - "Line In 1", - "Line In 2" - }; - - memset(audio, 0, sizeof(*audio)); - if (index >= cx->nof_audio_inputs) - return -EINVAL; - strlcpy(audio->name, input_strs[aud_input->audio_type - 1], - sizeof(audio->name)); - audio->index = index; - audio->capability = V4L2_AUDCAP_STEREO; - return 0; -} diff --git a/drivers/media/video/cx18/cx18-cards.h b/drivers/media/video/cx18/cx18-cards.h deleted file mode 100644 index 6fa7bcb42dd..00000000000 --- a/drivers/media/video/cx18/cx18-cards.h +++ /dev/null @@ -1,150 +0,0 @@ -/* - * cx18 functions to query card hardware - * - * Derived from ivtv-cards.c - * - * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> - * Copyright (C) 2008 Andy Walls <awalls@radix.net> - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -/* hardware flags */ -#define CX18_HW_TUNER (1 << 0) -#define CX18_HW_TVEEPROM (1 << 1) -#define CX18_HW_CS5345 (1 << 2) -#define CX18_HW_GPIO (1 << 3) -#define CX18_HW_CX23418 (1 << 4) -#define CX18_HW_DVB (1 << 5) - -/* video inputs */ -#define CX18_CARD_INPUT_VID_TUNER 1 -#define CX18_CARD_INPUT_SVIDEO1 2 -#define CX18_CARD_INPUT_SVIDEO2 3 -#define CX18_CARD_INPUT_COMPOSITE1 4 -#define CX18_CARD_INPUT_COMPOSITE2 5 -#define CX18_CARD_INPUT_COMPOSITE3 6 - -/* audio inputs */ -#define CX18_CARD_INPUT_AUD_TUNER 1 -#define CX18_CARD_INPUT_LINE_IN1 2 -#define CX18_CARD_INPUT_LINE_IN2 3 - -#define CX18_CARD_MAX_VIDEO_INPUTS 6 -#define CX18_CARD_MAX_AUDIO_INPUTS 3 -#define CX18_CARD_MAX_TUNERS 2 - -/* V4L2 capability aliases */ -#define CX18_CAP_ENCODER (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_TUNER | \ - V4L2_CAP_AUDIO | V4L2_CAP_READWRITE | \ - V4L2_CAP_VBI_CAPTURE) -/* | V4L2_CAP_SLICED_VBI_CAPTURE) not yet */ - -struct cx18_card_video_input { - u8 video_type; /* video input type */ - u8 audio_index; /* index in cx18_card_audio_input array */ - u16 video_input; /* hardware video input */ -}; - -struct cx18_card_audio_input { - u8 audio_type; /* audio input type */ - u32 audio_input; /* hardware audio input */ - u16 muxer_input; /* hardware muxer input for boards with a - multiplexer chip */ -}; - -struct cx18_card_pci_info { - u16 device; - u16 subsystem_vendor; - u16 subsystem_device; -}; - -/* GPIO definitions */ - -/* The mask is the set of bits used by the operation */ - -struct cx18_gpio_init { /* set initial GPIO DIR and OUT values */ - u32 direction; /* DIR setting. Leave to 0 if no init is needed */ - u32 initial_value; -}; - -struct cx18_gpio_i2c_slave_reset { - u32 active_lo_mask; /* GPIO outputs that reset i2c chips when low */ - u32 active_hi_mask; /* GPIO outputs that reset i2c chips when high */ - int msecs_asserted; /* time period reset must remain asserted */ - int msecs_recovery; /* time after deassert for chips to be ready */ - u32 ir_reset_mask; /* GPIO to reset the Zilog Z8F0811 IR contoller */ -}; - -struct cx18_gpio_audio_input { /* select tuner/line in input */ - u32 mask; /* leave to 0 if not supported */ - u32 tuner; - u32 linein; - u32 radio; -}; - -struct cx18_card_tuner { - v4l2_std_id std; /* standard for which the tuner is suitable */ - int tuner; /* tuner ID (from tuner.h) */ -}; - -struct cx18_card_tuner_i2c { - unsigned short radio[2];/* radio tuner i2c address to probe */ - unsigned short demod[2];/* demodulator i2c address to probe */ - unsigned short tv[4]; /* tv tuner i2c addresses to probe */ -}; - -struct cx18_ddr { /* DDR config data */ - u32 chip_config; - u32 refresh; - u32 timing1; - u32 timing2; - u32 tune_lane; - u32 initial_emrs; -}; - -/* for card information/parameters */ -struct cx18_card { - int type; - char *name; - char *comment; - u32 v4l2_capabilities; - u32 hw_audio_ctrl; /* hardware used for the V4L2 controls (only - 1 dev allowed) */ - u32 hw_muxer; /* hardware used to multiplex audio input */ - u32 hw_all; /* all hardware used by the board */ - struct cx18_card_video_input video_inputs[CX18_CARD_MAX_VIDEO_INPUTS]; - struct cx18_card_audio_input audio_inputs[CX18_CARD_MAX_AUDIO_INPUTS]; - struct cx18_card_audio_input radio_input; - - /* GPIO card-specific settings */ - u8 xceive_pin; /* XCeive tuner GPIO reset pin */ - struct cx18_gpio_init gpio_init; - struct cx18_gpio_i2c_slave_reset gpio_i2c_slave_reset; - struct cx18_gpio_audio_input gpio_audio_input; - - struct cx18_card_tuner tuners[CX18_CARD_MAX_TUNERS]; - struct cx18_card_tuner_i2c *i2c; - - struct cx18_ddr ddr; - - /* list of device and subsystem vendor/devices that - correspond to this card type. */ - const struct cx18_card_pci_info *pci_list; -}; - -int cx18_get_input(struct cx18 *cx, u16 index, struct v4l2_input *input); -int cx18_get_audio_input(struct cx18 *cx, u16 index, struct v4l2_audio *input); -const struct cx18_card *cx18_get_card(u16 index); diff --git a/drivers/media/video/cx18/cx18-controls.c b/drivers/media/video/cx18/cx18-controls.c deleted file mode 100644 index 17edf305d64..00000000000 --- a/drivers/media/video/cx18/cx18-controls.c +++ /dev/null @@ -1,317 +0,0 @@ -/* - * cx18 ioctl control functions - * - * Derived from ivtv-controls.c - * - * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> - * - * 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., 59 Temple Place, Suite 330, Boston, MA - * 02111-1307 USA - */ - -#include "cx18-driver.h" -#include "cx18-av-core.h" -#include "cx18-cards.h" -#include "cx18-ioctl.h" -#include "cx18-audio.h" -#include "cx18-i2c.h" -#include "cx18-mailbox.h" -#include "cx18-controls.h" - -static const u32 user_ctrls[] = { - V4L2_CID_USER_CLASS, - V4L2_CID_BRIGHTNESS, - V4L2_CID_CONTRAST, - V4L2_CID_SATURATION, - V4L2_CID_HUE, - V4L2_CID_AUDIO_VOLUME, - V4L2_CID_AUDIO_BALANCE, - V4L2_CID_AUDIO_BASS, - V4L2_CID_AUDIO_TREBLE, - V4L2_CID_AUDIO_MUTE, - V4L2_CID_AUDIO_LOUDNESS, - 0 -}; - -static const u32 *ctrl_classes[] = { - user_ctrls, - cx2341x_mpeg_ctrls, - NULL -}; - -int cx18_queryctrl(struct file *file, void *fh, struct v4l2_queryctrl *qctrl) -{ - struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; - const char *name; - - qctrl->id = v4l2_ctrl_next(ctrl_classes, qctrl->id); - if (qctrl->id == 0) - return -EINVAL; - - switch (qctrl->id) { - /* Standard V4L2 controls */ - case V4L2_CID_BRIGHTNESS: - case V4L2_CID_HUE: - case V4L2_CID_SATURATION: - case V4L2_CID_CONTRAST: - if (cx18_av_cmd(cx, VIDIOC_QUERYCTRL, qctrl)) - qctrl->flags |= V4L2_CTRL_FLAG_DISABLED; - return 0; - - case V4L2_CID_AUDIO_VOLUME: - case V4L2_CID_AUDIO_MUTE: - case V4L2_CID_AUDIO_BALANCE: - case V4L2_CID_AUDIO_BASS: - case V4L2_CID_AUDIO_TREBLE: - case V4L2_CID_AUDIO_LOUDNESS: - if (cx18_i2c_hw(cx, cx->card->hw_audio_ctrl, VIDIOC_QUERYCTRL, qctrl)) - qctrl->flags |= V4L2_CTRL_FLAG_DISABLED; - return 0; - - default: - if (cx2341x_ctrl_query(&cx->params, qctrl)) - qctrl->flags |= V4L2_CTRL_FLAG_DISABLED; - return 0; - } - strncpy(qctrl->name, name, sizeof(qctrl->name) - 1); - qctrl->name[sizeof(qctrl->name) - 1] = 0; - return 0; -} - -int cx18_querymenu(struct file *file, void *fh, struct v4l2_querymenu *qmenu) -{ - struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; - struct v4l2_queryctrl qctrl; - - qctrl.id = qmenu->id; - cx18_queryctrl(file, fh, &qctrl); - return v4l2_ctrl_query_menu(qmenu, &qctrl, - cx2341x_ctrl_get_menu(&cx->params, qmenu->id)); -} - -static int cx18_try_ctrl(struct file *file, void *fh, - struct v4l2_ext_control *vctrl) -{ - struct v4l2_queryctrl qctrl; - const char **menu_items = NULL; - int err; - - qctrl.id = vctrl->id; - err = cx18_queryctrl(file, fh, &qctrl); - if (err) - return err; - if (qctrl.type == V4L2_CTRL_TYPE_MENU) - menu_items = v4l2_ctrl_get_menu(qctrl.id); - return v4l2_ctrl_check(vctrl, &qctrl, menu_items); -} - -static int cx18_s_ctrl(struct cx18 *cx, struct v4l2_control *vctrl) -{ - switch (vctrl->id) { - /* Standard V4L2 controls */ - case V4L2_CID_BRIGHTNESS: - case V4L2_CID_HUE: - case V4L2_CID_SATURATION: - case V4L2_CID_CONTRAST: - return cx18_av_cmd(cx, VIDIOC_S_CTRL, vctrl); - - case V4L2_CID_AUDIO_VOLUME: - case V4L2_CID_AUDIO_MUTE: - case V4L2_CID_AUDIO_BALANCE: - case V4L2_CID_AUDIO_BASS: - case V4L2_CID_AUDIO_TREBLE: - case V4L2_CID_AUDIO_LOUDNESS: - return cx18_i2c_hw(cx, cx->card->hw_audio_ctrl, VIDIOC_S_CTRL, vctrl); - - default: - CX18_DEBUG_IOCTL("invalid control 0x%x\n", vctrl->id); - return -EINVAL; - } - return 0; -} - -static int cx18_g_ctrl(struct cx18 *cx, struct v4l2_control *vctrl) -{ - switch (vctrl->id) { - /* Standard V4L2 controls */ - case V4L2_CID_BRIGHTNESS: - case V4L2_CID_HUE: - case V4L2_CID_SATURATION: - case V4L2_CID_CONTRAST: - return cx18_av_cmd(cx, VIDIOC_G_CTRL, vctrl); - - case V4L2_CID_AUDIO_VOLUME: - case V4L2_CID_AUDIO_MUTE: - case V4L2_CID_AUDIO_BALANCE: - case V4L2_CID_AUDIO_BASS: - case V4L2_CID_AUDIO_TREBLE: - case V4L2_CID_AUDIO_LOUDNESS: - return cx18_i2c_hw(cx, cx->card->hw_audio_ctrl, VIDIOC_G_CTRL, vctrl); - default: - CX18_DEBUG_IOCTL("invalid control 0x%x\n", vctrl->id); - return -EINVAL; - } - return 0; -} - -static int cx18_setup_vbi_fmt(struct cx18 *cx, enum v4l2_mpeg_stream_vbi_fmt fmt) -{ - if (!(cx->v4l2_cap & V4L2_CAP_SLICED_VBI_CAPTURE)) - return -EINVAL; - if (atomic_read(&cx->ana_capturing) > 0) - return -EBUSY; - - /* First try to allocate sliced VBI buffers if needed. */ - if (fmt && cx->vbi.sliced_mpeg_data[0] == NULL) { - int i; - - for (i = 0; i < CX18_VBI_FRAMES; i++) { - /* Yuck, hardcoded. Needs to be a define */ - cx->vbi.sliced_mpeg_data[i] = kmalloc(2049, GFP_KERNEL); - if (cx->vbi.sliced_mpeg_data[i] == NULL) { - while (--i >= 0) { - kfree(cx->vbi.sliced_mpeg_data[i]); - cx->vbi.sliced_mpeg_data[i] = NULL; - } - return -ENOMEM; - } - } - } - - cx->vbi.insert_mpeg = fmt; - - if (cx->vbi.insert_mpeg == 0) - return 0; - /* Need sliced data for mpeg insertion */ - if (cx18_get_service_set(cx->vbi.sliced_in) == 0) { - if (cx->is_60hz) - cx->vbi.sliced_in->service_set = V4L2_SLICED_CAPTION_525; - else - cx->vbi.sliced_in->service_set = V4L2_SLICED_WSS_625; - cx18_expand_service_set(cx->vbi.sliced_in, cx->is_50hz); - } - return 0; -} - -int cx18_g_ext_ctrls(struct file *file, void *fh, struct v4l2_ext_controls *c) -{ - struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; - struct v4l2_control ctrl; - - if (c->ctrl_class == V4L2_CTRL_CLASS_USER) { - int i; - int err = 0; - - for (i = 0; i < c->count; i++) { - ctrl.id = c->controls[i].id; - ctrl.value = c->controls[i].value; - err = cx18_g_ctrl(cx, &ctrl); - c->controls[i].value = ctrl.value; - if (err) { - c->error_idx = i; - break; - } - } - return err; - } - if (c->ctrl_class == V4L2_CTRL_CLASS_MPEG) - return cx2341x_ext_ctrls(&cx->params, 0, c, VIDIOC_G_EXT_CTRLS); - return -EINVAL; -} - -int cx18_s_ext_ctrls(struct file *file, void *fh, struct v4l2_ext_controls *c) -{ - struct cx18_open_id *id = fh; - struct cx18 *cx = id->cx; - int ret; - struct v4l2_control ctrl; - - ret = v4l2_prio_check(&cx->prio, &id->prio); - if (ret) - return ret; - - if (c->ctrl_class == V4L2_CTRL_CLASS_USER) { - int i; - int err = 0; - - for (i = 0; i < c->count; i++) { - ctrl.id = c->controls[i].id; - ctrl.value = c->controls[i].value; - err = cx18_s_ctrl(cx, &ctrl); - c->controls[i].value = ctrl.value; - if (err) { - c->error_idx = i; - break; - } - } - return err; - } - if (c->ctrl_class == V4L2_CTRL_CLASS_MPEG) { - struct cx18_api_func_private priv; - struct cx2341x_mpeg_params p = cx->params; - int err = cx2341x_ext_ctrls(&p, atomic_read(&cx->ana_capturing), - c, VIDIOC_S_EXT_CTRLS); - - if (err) - return err; - - if (p.video_encoding != cx->params.video_encoding) { - int is_mpeg1 = p.video_encoding == - V4L2_MPEG_VIDEO_ENCODING_MPEG_1; - struct v4l2_format fmt; - - /* fix videodecoder resolution */ - fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - fmt.fmt.pix.width = cx->params.width - / (is_mpeg1 ? 2 : 1); - fmt.fmt.pix.height = cx->params.height; - cx18_av_cmd(cx, VIDIOC_S_FMT, &fmt); - } - priv.cx = cx; - priv.s = &cx->streams[id->type]; - err = cx2341x_update(&priv, cx18_api_func, &cx->params, &p); - if (!err && cx->params.stream_vbi_fmt != p.stream_vbi_fmt) - err = cx18_setup_vbi_fmt(cx, p.stream_vbi_fmt); - cx->params = p; - cx->dualwatch_stereo_mode = p.audio_properties & 0x0300; - cx18_audio_set_audio_clock_freq(cx, p.audio_properties & 0x03); - return err; - } - return -EINVAL; -} - -int cx18_try_ext_ctrls(struct file *file, void *fh, struct v4l2_ext_controls *c) -{ - struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; - - if (c->ctrl_class == V4L2_CTRL_CLASS_USER) { - int i; - int err = 0; - - for (i = 0; i < c->count; i++) { - err = cx18_try_ctrl(file, fh, &c->controls[i]); - if (err) { - c->error_idx = i; - break; - } - } - return err; - } - if (c->ctrl_class == V4L2_CTRL_CLASS_MPEG) - return cx2341x_ext_ctrls(&cx->params, - atomic_read(&cx->ana_capturing), - c, VIDIOC_TRY_EXT_CTRLS); - return -EINVAL; -} diff --git a/drivers/media/video/cx18/cx18-controls.h b/drivers/media/video/cx18/cx18-controls.h deleted file mode 100644 index e46323700b8..00000000000 --- a/drivers/media/video/cx18/cx18-controls.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * cx18 ioctl control functions - * - * Derived from ivtv-controls.h - * - * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> - - * 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., 59 Temple Place, Suite 330, Boston, MA - * 02111-1307 USA - */ - -int cx18_queryctrl(struct file *file, void *fh, struct v4l2_queryctrl *a); -int cx18_g_ext_ctrls(struct file *file, void *fh, struct v4l2_ext_controls *a); -int cx18_s_ext_ctrls(struct file *file, void *fh, struct v4l2_ext_controls *a); -int cx18_try_ext_ctrls(struct file *file, void *fh, - struct v4l2_ext_controls *a); -int cx18_querymenu(struct file *file, void *fh, struct v4l2_querymenu *a); diff --git a/drivers/media/video/cx18/cx18-driver.c b/drivers/media/video/cx18/cx18-driver.c deleted file mode 100644 index f50cf2167ad..00000000000 --- a/drivers/media/video/cx18/cx18-driver.c +++ /dev/null @@ -1,1178 +0,0 @@ -/* - * cx18 driver initialization and card probing - * - * Derived from ivtv-driver.c - * - * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> - * Copyright (C) 2008 Andy Walls <awalls@radix.net> - * - * 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., 59 Temple Place, Suite 330, Boston, MA - * 02111-1307 USA - */ - -#include "cx18-driver.h" -#include "cx18-io.h" -#include "cx18-version.h" -#include "cx18-cards.h" -#include "cx18-i2c.h" -#include "cx18-irq.h" -#include "cx18-gpio.h" -#include "cx18-firmware.h" -#include "cx18-streams.h" -#include "cx18-av-core.h" -#include "cx18-scb.h" -#include "cx18-mailbox.h" -#include "cx18-ioctl.h" -#include "tuner-xc2028.h" - -#include <media/tveeprom.h> - - -/* var to keep track of the number of array elements in use */ -int cx18_cards_active; - -/* If you have already X v4l cards, then set this to X. This way - the device numbers stay matched. Example: you have a WinTV card - without radio and a Compro H900 with. Normally this would give a - video1 device together with a radio0 device for the Compro. By - setting this to 1 you ensure that radio0 is now also radio1. */ -int cx18_first_minor; - -/* Master variable for all cx18 info */ -struct cx18 *cx18_cards[CX18_MAX_CARDS]; - -/* Protects cx18_cards_active */ -DEFINE_SPINLOCK(cx18_cards_lock); - -/* add your revision and whatnot here */ -static struct pci_device_id cx18_pci_tbl[] __devinitdata = { - {PCI_VENDOR_ID_CX, PCI_DEVICE_ID_CX23418, - PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - {0,} -}; - -MODULE_DEVICE_TABLE(pci, cx18_pci_tbl); - -/* Parameter declarations */ -static int cardtype[CX18_MAX_CARDS]; -static int tuner[CX18_MAX_CARDS] = { -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1 }; -static int radio[CX18_MAX_CARDS] = { -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1 }; -static unsigned cardtype_c = 1; -static unsigned tuner_c = 1; -static unsigned radio_c = 1; -static char pal[] = "--"; -static char secam[] = "--"; -static char ntsc[] = "-"; - -/* Buffers */ -static int enc_ts_buffers = CX18_DEFAULT_ENC_TS_BUFFERS; -static int enc_mpg_buffers = CX18_DEFAULT_ENC_MPG_BUFFERS; -static int enc_idx_buffers = CX18_DEFAULT_ENC_IDX_BUFFERS; -static int enc_yuv_buffers = CX18_DEFAULT_ENC_YUV_BUFFERS; -static int enc_vbi_buffers = CX18_DEFAULT_ENC_VBI_BUFFERS; -static int enc_pcm_buffers = CX18_DEFAULT_ENC_PCM_BUFFERS; - -static int enc_ts_bufsize = CX18_DEFAULT_ENC_TS_BUFSIZE; -static int enc_mpg_bufsize = CX18_DEFAULT_ENC_MPG_BUFSIZE; -static int enc_idx_bufsize = CX18_DEFAULT_ENC_IDX_BUFSIZE; -static int enc_yuv_bufsize = CX18_DEFAULT_ENC_YUV_BUFSIZE; -/* VBI bufsize based on standards supported by card tuner for now */ -static int enc_pcm_bufsize = CX18_DEFAULT_ENC_PCM_BUFSIZE; - -static int enc_ts_bufs = -1; -static int enc_mpg_bufs = -1; -static int enc_idx_bufs = -1; -static int enc_yuv_bufs = -1; -static int enc_vbi_bufs = -1; -static int enc_pcm_bufs = -1; - - -static int cx18_pci_latency = 1; - -static int mmio_ndelay; -static int retry_mmio = 1; - -int cx18_debug; - -module_param_array(tuner, int, &tuner_c, 0644); -module_param_array(radio, bool, &radio_c, 0644); -module_param_array(cardtype, int, &cardtype_c, 0644); -module_param_string(pal, pal, sizeof(pal), 0644); -module_param_string(secam, secam, sizeof(secam), 0644); -module_param_string(ntsc, ntsc, sizeof(ntsc), 0644); -module_param_named(debug, cx18_debug, int, 0644); -module_param(mmio_ndelay, int, 0644); -module_param(retry_mmio, int, 0644); -module_param(cx18_pci_latency, int, 0644); -module_param(cx18_first_minor, int, 0644); - -module_param(enc_ts_buffers, int, 0644); -module_param(enc_mpg_buffers, int, 0644); -module_param(enc_idx_buffers, int, 0644); -module_param(enc_yuv_buffers, int, 0644); -module_param(enc_vbi_buffers, int, 0644); -module_param(enc_pcm_buffers, int, 0644); - -module_param(enc_ts_bufsize, int, 0644); -module_param(enc_mpg_bufsize, int, 0644); -module_param(enc_idx_bufsize, int, 0644); -module_param(enc_yuv_bufsize, int, 0644); -/* VBI bufsize based on standards supported by card tuner for now */ -module_param(enc_pcm_bufsize, int, 0644); - -module_param(enc_ts_bufs, int, 0644); -module_param(enc_mpg_bufs, int, 0644); -module_param(enc_idx_bufs, int, 0644); -module_param(enc_yuv_bufs, int, 0644); -module_param(enc_vbi_bufs, int, 0644); -module_param(enc_pcm_bufs, int, 0644); - -MODULE_PARM_DESC(tuner, "Tuner type selection,\n" - "\t\t\tsee tuner.h for values"); -MODULE_PARM_DESC(radio, - "Enable or disable the radio. Use only if autodetection\n" - "\t\t\tfails. 0 = disable, 1 = enable"); -MODULE_PARM_DESC(cardtype, - "Only use this option if your card is not detected properly.\n" - "\t\tSpecify card type:\n" - "\t\t\t 1 = Hauppauge HVR 1600 (ESMT memory)\n" - "\t\t\t 2 = Hauppauge HVR 1600 (Samsung memory)\n" - "\t\t\t 3 = Compro VideoMate H900\n" - "\t\t\t 4 = Yuan MPC718\n" - "\t\t\t 5 = Conexant Raptor PAL/SECAM\n" - "\t\t\t 6 = Toshiba Qosmio DVB-T/Analog\n" - "\t\t\t 7 = Leadtek WinFast PVR2100\n" - "\t\t\t 0 = Autodetect (default)\n" - "\t\t\t-1 = Ignore this card\n\t\t"); -MODULE_PARM_DESC(pal, "Set PAL standard: B, G, H, D, K, I, M, N, Nc, 60"); -MODULE_PARM_DESC(secam, "Set SECAM standard: B, G, H, D, K, L, LC"); -MODULE_PARM_DESC(ntsc, "Set NTSC standard: M, J, K"); -MODULE_PARM_DESC(debug, - "Debug level (bitmask). Default: 0\n" - "\t\t\t 1/0x0001: warning\n" - "\t\t\t 2/0x0002: info\n" - "\t\t\t 4/0x0004: mailbox\n" - "\t\t\t 8/0x0008: dma\n" - "\t\t\t 16/0x0010: ioctl\n" - "\t\t\t 32/0x0020: file\n" - "\t\t\t 64/0x0040: i2c\n" - "\t\t\t128/0x0080: irq\n" - "\t\t\t256/0x0100: high volume\n"); -MODULE_PARM_DESC(cx18_pci_latency, - "Change the PCI latency to 64 if lower: 0 = No, 1 = Yes,\n" - "\t\t\tDefault: Yes"); -MODULE_PARM_DESC(retry_mmio, - "(Deprecated) MMIO writes are now always checked and retried\n" - "\t\t\tEffectively: 1 [Yes]"); -MODULE_PARM_DESC(mmio_ndelay, - "(Deprecated) MMIO accesses are now never purposely delayed\n" - "\t\t\tEffectively: 0 ns"); -MODULE_PARM_DESC(enc_ts_buffers, - "Encoder TS buffer memory (MB). (enc_ts_bufs can override)\n" - "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_TS_BUFFERS)); -MODULE_PARM_DESC(enc_ts_bufsize, - "Size of an encoder TS buffer (kB)\n" - "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_TS_BUFSIZE)); -MODULE_PARM_DESC(enc_ts_bufs, - "Number of encoder TS buffers\n" - "\t\t\tDefault is computed from other enc_ts_* parameters"); -MODULE_PARM_DESC(enc_mpg_buffers, - "Encoder MPG buffer memory (MB). (enc_mpg_bufs can override)\n" - "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_MPG_BUFFERS)); -MODULE_PARM_DESC(enc_mpg_bufsize, - "Size of an encoder MPG buffer (kB)\n" - "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_MPG_BUFSIZE)); -MODULE_PARM_DESC(enc_mpg_bufs, - "Number of encoder MPG buffers\n" - "\t\t\tDefault is computed from other enc_mpg_* parameters"); -MODULE_PARM_DESC(enc_idx_buffers, - "Encoder IDX buffer memory (MB). (enc_idx_bufs can override)\n" - "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_IDX_BUFFERS)); -MODULE_PARM_DESC(enc_idx_bufsize, - "Size of an encoder IDX buffer (kB)\n" - "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_IDX_BUFSIZE)); -MODULE_PARM_DESC(enc_idx_bufs, - "Number of encoder IDX buffers\n" - "\t\t\tDefault is computed from other enc_idx_* parameters"); -MODULE_PARM_DESC(enc_yuv_buffers, - "Encoder YUV buffer memory (MB). (enc_yuv_bufs can override)\n" - "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_YUV_BUFFERS)); -MODULE_PARM_DESC(enc_yuv_bufsize, - "Size of an encoder YUV buffer (kB)\n" - "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_YUV_BUFSIZE)); -MODULE_PARM_DESC(enc_yuv_bufs, - "Number of encoder YUV buffers\n" - "\t\t\tDefault is computed from other enc_yuv_* parameters"); -MODULE_PARM_DESC(enc_vbi_buffers, - "Encoder VBI buffer memory (MB). (enc_vbi_bufs can override)\n" - "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_VBI_BUFFERS)); -MODULE_PARM_DESC(enc_vbi_bufs, - "Number of encoder VBI buffers\n" - "\t\t\tDefault is computed from enc_vbi_buffers & tuner std"); -MODULE_PARM_DESC(enc_pcm_buffers, - "Encoder PCM buffer memory (MB). (enc_pcm_bufs can override)\n" - "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_PCM_BUFFERS)); -MODULE_PARM_DESC(enc_pcm_bufsize, - "Size of an encoder PCM buffer (kB)\n" - "\t\t\tDefault: " __stringify(CX18_DEFAULT_ENC_PCM_BUFSIZE)); -MODULE_PARM_DESC(enc_pcm_bufs, - "Number of encoder PCM buffers\n" - "\t\t\tDefault is computed from other enc_pcm_* parameters"); - -MODULE_PARM_DESC(cx18_first_minor, "Set kernel number assigned to first card"); - -MODULE_AUTHOR("Hans Verkuil"); -MODULE_DESCRIPTION("CX23418 driver"); -MODULE_SUPPORTED_DEVICE("CX23418 MPEG2 encoder"); -MODULE_LICENSE("GPL"); - -MODULE_VERSION(CX18_VERSION); - -/* Generic utility functions */ -int cx18_msleep_timeout(unsigned int msecs, int intr) -{ - long int timeout = msecs_to_jiffies(msecs); - int sig; - - do { - set_current_state(intr ? TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE); - timeout = schedule_timeout(timeout); - sig = intr ? signal_pending(current) : 0; - } while (!sig && timeout); - return sig; -} - -/* Release ioremapped memory */ -static void cx18_iounmap(struct cx18 *cx) -{ - if (cx == NULL) - return; - - /* Release io memory */ - if (cx->enc_mem != NULL) { - CX18_DEBUG_INFO("releasing enc_mem\n"); - iounmap(cx->enc_mem); - cx->enc_mem = NULL; - } -} - -/* Hauppauge card? get values from tveeprom */ -void cx18_read_eeprom(struct cx18 *cx, struct tveeprom *tv) -{ - u8 eedata[256]; - - cx->i2c_client[0].addr = 0xA0 >> 1; - tveeprom_read(&cx->i2c_client[0], eedata, sizeof(eedata)); - tveeprom_hauppauge_analog(&cx->i2c_client[0], tv, eedata); -} - -static void cx18_process_eeprom(struct cx18 *cx) -{ - struct tveeprom tv; - - cx18_read_eeprom(cx, &tv); - - /* Many thanks to Steven Toth from Hauppauge for providing the - model numbers */ - /* Note: the Samsung memory models cannot be reliably determined - from the model number. Use the cardtype module option if you - have one of these preproduction models. */ - switch (tv.model) { - case 74000 ... 74999: - cx->card = cx18_get_card(CX18_CARD_HVR_1600_ESMT); - break; - case 0: - CX18_ERR("Invalid EEPROM\n"); - return; - default: - CX18_ERR("Unknown model %d, defaulting to HVR-1600\n", tv.model); - cx->card = cx18_get_card(CX18_CARD_HVR_1600_ESMT); - break; - } - - cx->v4l2_cap = cx->card->v4l2_capabilities; - cx->card_name = cx->card->name; - cx->card_i2c = cx->card->i2c; - - CX18_INFO("Autodetected %s\n", cx->card_name); - - if (tv.tuner_type == TUNER_ABSENT) - CX18_ERR("tveeprom cannot autodetect tuner!"); - - if (cx->options.tuner == -1) - cx->options.tuner = tv.tuner_type; - if (cx->options.radio == -1) - cx->options.radio = (tv.has_radio != 0); - - if (cx->std != 0) - /* user specified tuner standard */ - return; - - /* autodetect tuner standard */ - if (tv.tuner_formats & V4L2_STD_PAL) { - CX18_DEBUG_INFO("PAL tuner detected\n"); - cx->std |= V4L2_STD_PAL_BG | V4L2_STD_PAL_H; - } else if (tv.tuner_formats & V4L2_STD_NTSC) { - CX18_DEBUG_INFO("NTSC tuner detected\n"); - cx->std |= V4L2_STD_NTSC_M; - } else if (tv.tuner_formats & V4L2_STD_SECAM) { - CX18_DEBUG_INFO("SECAM tuner detected\n"); - cx->std |= V4L2_STD_SECAM_L; - } else { - CX18_INFO("No tuner detected, default to NTSC-M\n"); - cx->std |= V4L2_STD_NTSC_M; - } -} - -static v4l2_std_id cx18_parse_std(struct cx18 *cx) -{ - switch (pal[0]) { - case '6': - return V4L2_STD_PAL_60; - case 'b': - case 'B': - case 'g': - case 'G': - return V4L2_STD_PAL_BG; - case 'h': - case 'H': - return V4L2_STD_PAL_H; - case 'n': - case 'N': - if (pal[1] == 'c' || pal[1] == 'C') - return V4L2_STD_PAL_Nc; - return V4L2_STD_PAL_N; - case 'i': - case 'I': - return V4L2_STD_PAL_I; - case 'd': - case 'D': - case 'k': - case 'K': - return V4L2_STD_PAL_DK; - case 'M': - case 'm': - return V4L2_STD_PAL_M; - case '-': - break; - default: - CX18_WARN("pal= argument not recognised\n"); - return 0; - } - - switch (secam[0]) { - case 'b': - case 'B': - case 'g': - case 'G': - case 'h': - case 'H': - return V4L2_STD_SECAM_B | V4L2_STD_SECAM_G | V4L2_STD_SECAM_H; - case 'd': - case 'D': - case 'k': - case 'K': - return V4L2_STD_SECAM_DK; - case 'l': - case 'L': - if (secam[1] == 'C' || secam[1] == 'c') - return V4L2_STD_SECAM_LC; - return V4L2_STD_SECAM_L; - case '-': - break; - default: - CX18_WARN("secam= argument not recognised\n"); - return 0; - } - - switch (ntsc[0]) { - case 'm': - case 'M': - return V4L2_STD_NTSC_M; - case 'j': - case 'J': - return V4L2_STD_NTSC_M_JP; - case 'k': - case 'K': - return V4L2_STD_NTSC_M_KR; - case '-': - break; - default: - CX18_WARN("ntsc= argument not recognised\n"); - return 0; - } - - /* no match found */ - return 0; -} - -static void cx18_process_options(struct cx18 *cx) -{ - int i, j; - - cx->options.megabytes[CX18_ENC_STREAM_TYPE_TS] = enc_ts_buffers; - cx->options.megabytes[CX18_ENC_STREAM_TYPE_MPG] = enc_mpg_buffers; - cx->options.megabytes[CX18_ENC_STREAM_TYPE_IDX] = enc_idx_buffers; - cx->options.megabytes[CX18_ENC_STREAM_TYPE_YUV] = enc_yuv_buffers; - cx->options.megabytes[CX18_ENC_STREAM_TYPE_VBI] = enc_vbi_buffers; - cx->options.megabytes[CX18_ENC_STREAM_TYPE_PCM] = enc_pcm_buffers; - cx->options.megabytes[CX18_ENC_STREAM_TYPE_RAD] = 0; /* control only */ - - cx->stream_buffers[CX18_ENC_STREAM_TYPE_TS] = enc_ts_bufs; - cx->stream_buffers[CX18_ENC_STREAM_TYPE_MPG] = enc_mpg_bufs; - cx->stream_buffers[CX18_ENC_STREAM_TYPE_IDX] = enc_idx_bufs; - cx->stream_buffers[CX18_ENC_STREAM_TYPE_YUV] = enc_yuv_bufs; - cx->stream_buffers[CX18_ENC_STREAM_TYPE_VBI] = enc_vbi_bufs; - cx->stream_buffers[CX18_ENC_STREAM_TYPE_PCM] = enc_pcm_bufs; - cx->stream_buffers[CX18_ENC_STREAM_TYPE_RAD] = 0; /* control, no data */ - - cx->stream_buf_size[CX18_ENC_STREAM_TYPE_TS] = enc_ts_bufsize; - cx->stream_buf_size[CX18_ENC_STREAM_TYPE_MPG] = enc_mpg_bufsize; - cx->stream_buf_size[CX18_ENC_STREAM_TYPE_IDX] = enc_idx_bufsize; - cx->stream_buf_size[CX18_ENC_STREAM_TYPE_YUV] = enc_yuv_bufsize; - cx->stream_buf_size[CX18_ENC_STREAM_TYPE_VBI] = 0; /* computed later */ - cx->stream_buf_size[CX18_ENC_STREAM_TYPE_PCM] = enc_pcm_bufsize; - cx->stream_buf_size[CX18_ENC_STREAM_TYPE_RAD] = 0; /* control no data */ - - /* Except for VBI ensure stream_buffers & stream_buf_size are valid */ - for (i = 0; i < CX18_MAX_STREAMS; i++) { - /* User said to use 0 buffers */ - if (cx->stream_buffers[i] == 0) { - cx->options.megabytes[i] = 0; - cx->stream_buf_size[i] = 0; - continue; - } - /* User said to use 0 MB total */ - if (cx->options.megabytes[i] <= 0) { - cx->options.megabytes[i] = 0; - cx->stream_buffers[i] = 0; - cx->stream_buf_size[i] = 0; - continue; - } - /* VBI is computed later or user said buffer has size 0 */ - if (cx->stream_buf_size[i] <= 0) { - if (i != CX18_ENC_STREAM_TYPE_VBI) { - cx->options.megabytes[i] = 0; - cx->stream_buffers[i] = 0; - cx->stream_buf_size[i] = 0; - } - continue; - } - if (cx->stream_buffers[i] < 0) { - cx->stream_buffers[i] = cx->options.megabytes[i] * 1024 - / cx->stream_buf_size[i]; - } else { - /* N.B. This might round down to 0 */ - cx->options.megabytes[i] = - cx->stream_buffers[i] * cx->stream_buf_size[i] / 1024; - } - cx->stream_buf_size[i] *= 1024; /* convert from kB to bytes */ - } - - cx->options.cardtype = cardtype[cx->num]; - cx->options.tuner = tuner[cx->num]; - cx->options.radio = radio[cx->num]; - - cx->std = cx18_parse_std(cx); - if (cx->options.cardtype == -1) { - CX18_INFO("Ignore card\n"); - return; - } - cx->card = cx18_get_card(cx->options.cardtype - 1); - if (cx->card) - CX18_INFO("User specified %s card\n", cx->card->name); - else if (cx->options.cardtype != 0) - CX18_ERR("Unknown user specified type, trying to autodetect card\n"); - if (cx->card == NULL) { - if (cx->dev->subsystem_vendor == CX18_PCI_ID_HAUPPAUGE) { - cx->card = cx18_get_card(CX18_CARD_HVR_1600_ESMT); - CX18_INFO("Autodetected Hauppauge card\n"); - } - } - if (cx->card == NULL) { - for (i = 0; (cx->card = cx18_get_card(i)); i++) { - if (cx->card->pci_list == NULL) - continue; - for (j = 0; cx->card->pci_list[j].device; j++) { - if (cx->dev->device != - cx->card->pci_list[j].device) - continue; - if (cx->dev->subsystem_vendor != - cx->card->pci_list[j].subsystem_vendor) - continue; - if (cx->dev->subsystem_device != - cx->card->pci_list[j].subsystem_device) - continue; - CX18_INFO("Autodetected %s card\n", cx->card->name); - goto done; - } - } - } -done: - - if (cx->card == NULL) { - cx->card = cx18_get_card(CX18_CARD_HVR_1600_ESMT); - CX18_ERR("Unknown card: vendor/device: [%04x:%04x]\n", - cx->dev->vendor, cx->dev->device); - CX18_ERR(" subsystem vendor/device: [%04x:%04x]\n", - cx->dev->subsystem_vendor, cx->dev->subsystem_device); - CX18_ERR("Defaulting to %s card\n", cx->card->name); - CX18_ERR("Please mail the vendor/device and subsystem vendor/device IDs and what kind of\n"); - CX18_ERR("card you have to the ivtv-devel mailinglist (www.ivtvdriver.org)\n"); - CX18_ERR("Prefix your subject line with [UNKNOWN CX18 CARD].\n"); - } - cx->v4l2_cap = cx->card->v4l2_capabilities; - cx->card_name = cx->card->name; - cx->card_i2c = cx->card->i2c; -} - -/* Precondition: the cx18 structure has been memset to 0. Only - the dev and num fields have been filled in. - No assumptions on the card type may be made here (see cx18_init_struct2 - for that). - */ -static int __devinit cx18_init_struct1(struct cx18 *cx) -{ - int i; - - cx->base_addr = pci_resource_start(cx->dev, 0); - - mutex_init(&cx->serialize_lock); - mutex_init(&cx->i2c_bus_lock[0]); - mutex_init(&cx->i2c_bus_lock[1]); - mutex_init(&cx->gpio_lock); - mutex_init(&cx->epu2apu_mb_lock); - mutex_init(&cx->epu2cpu_mb_lock); - - spin_lock_init(&cx->lock); - - cx->work_queue = create_singlethread_workqueue(cx->name); - if (cx->work_queue == NULL) { - CX18_ERR("Unable to create work hander thread\n"); - return -ENOMEM; - } - - for (i = 0; i < CX18_MAX_EPU_WORK_ORDERS; i++) { - cx->epu_work_order[i].cx = cx; - cx->epu_work_order[i].str = cx->epu_debug_str; - INIT_WORK(&cx->epu_work_order[i].work, cx18_epu_work_handler); - } - - /* start counting open_id at 1 */ - cx->open_id = 1; - - /* Initial settings */ - cx2341x_fill_defaults(&cx->params); - cx->temporal_strength = cx->params.video_temporal_filter; - cx->spatial_strength = cx->params.video_spatial_filter; - cx->filter_mode = cx->params.video_spatial_filter_mode | - (cx->params.video_temporal_filter_mode << 1) | - (cx->params.video_median_filter_type << 2); - cx->params.port = CX2341X_PORT_MEMORY; - cx->params.capabilities = CX2341X_CAP_HAS_TS; - init_waitqueue_head(&cx->cap_w); - init_waitqueue_head(&cx->mb_apu_waitq); - init_waitqueue_head(&cx->mb_cpu_waitq); - init_waitqueue_head(&cx->dma_waitq); - - /* VBI */ - cx->vbi.in.type = V4L2_BUF_TYPE_VBI_CAPTURE; - cx->vbi.sliced_in = &cx->vbi.in.fmt.sliced; - - /* - * The VBI line sizes depend on the pixel clock and the horiz rate - * - * (1/Fh)*(2*Fp) = Samples/line - * = 4 bytes EAV + Anc data in hblank + 4 bytes SAV + active samples - * - * Sliced VBI is sent as ancillary data during horizontal blanking - * Raw VBI is sent as active video samples during vertcal blanking - * - * We use a BT.656 pxiel clock of 13.5 MHz and a BT.656 active line - * length of 720 pixels @ 4:2:2 sampling. Thus... - * - * For systems that use a 15.734 kHz horizontal rate, such as - * NTSC-M, PAL-M, PAL-60, and other 60 Hz/525 line systems, we have: - * - * (1/15.734 kHz) * 2 * 13.5 MHz = 1716 samples/line = - * 4 bytes SAV + 268 bytes anc data + 4 bytes SAV + 1440 active samples - * - * For systems that use a 15.625 kHz horizontal rate, such as - * PAL-B/G/H, PAL-I, SECAM-L and other 50 Hz/625 line systems, we have: - * - * (1/15.625 kHz) * 2 * 13.5 MHz = 1728 samples/line = - * 4 bytes SAV + 280 bytes anc data + 4 bytes SAV + 1440 active samples - * - */ - - /* FIXME: init these based on tuner std & modify when std changes */ - /* CX18-AV-Core number of VBI samples output per horizontal line */ - cx->vbi.raw_decoder_line_size = 1444; /* 4 byte SAV + 2 * 720 */ - cx->vbi.sliced_decoder_line_size = 272; /* 60 Hz: 268+4, 50 Hz: 280+4 */ - - /* CX18-AV-Core VBI samples/line possibly rounded up */ - cx->vbi.raw_size = 1444; /* Real max size is 1444 */ - cx->vbi.sliced_size = 284; /* Real max size is 284 */ - - /* - * CX18-AV-Core SAV/EAV RP codes in VIP 1.x mode - * Task Field VerticalBlank HorizontalBlank 0 0 0 0 - */ - cx->vbi.raw_decoder_sav_odd_field = 0x20; /* V */ - cx->vbi.raw_decoder_sav_even_field = 0x60; /* FV */ - cx->vbi.sliced_decoder_sav_odd_field = 0xB0; /* T VH - actually EAV */ - cx->vbi.sliced_decoder_sav_even_field = 0xF0; /* TFVH - actually EAV */ - return 0; -} - -/* Second initialization part. Here the card type has been - autodetected. */ -static void __devinit cx18_init_struct2(struct cx18 *cx) -{ - int i; - - for (i = 0; i < CX18_CARD_MAX_VIDEO_INPUTS; i++) - if (cx->card->video_inputs[i].video_type == 0) - break; - cx->nof_inputs = i; - for (i = 0; i < CX18_CARD_MAX_AUDIO_INPUTS; i++) - if (cx->card->audio_inputs[i].audio_type == 0) - break; - cx->nof_audio_inputs = i; - - /* Find tuner input */ - for (i = 0; i < cx->nof_inputs; i++) { - if (cx->card->video_inputs[i].video_type == - CX18_CARD_INPUT_VID_TUNER) - break; - } - if (i == cx->nof_inputs) - i = 0; - cx->active_input = i; - cx->audio_input = cx->card->video_inputs[i].audio_index; - cx->av_state.vid_input = CX18_AV_COMPOSITE7; - cx->av_state.aud_input = CX18_AV_AUDIO8; - cx->av_state.audclk_freq = 48000; - cx->av_state.audmode = V4L2_TUNER_MODE_LANG1; - /* FIXME - 8 is NTSC value, investigate */ - cx->av_state.vbi_line_offset = 8; -} - -static int cx18_setup_pci(struct cx18 *cx, struct pci_dev *dev, - const struct pci_device_id *pci_id) -{ - u16 cmd; - unsigned char pci_latency; - - CX18_DEBUG_INFO("Enabling pci device\n"); - - if (pci_enable_device(dev)) { - CX18_ERR("Can't enable device %d!\n", cx->num); - return -EIO; - } - if (pci_set_dma_mask(dev, 0xffffffff)) { - CX18_ERR("No suitable DMA available on card %d.\n", cx->num); - return -EIO; - } - if (!request_mem_region(cx->base_addr, CX18_MEM_SIZE, "cx18 encoder")) { - CX18_ERR("Cannot request encoder memory region on card %d.\n", cx->num); - return -EIO; - } - - /* Enable bus mastering and memory mapped IO for the CX23418 */ - pci_read_config_word(dev, PCI_COMMAND, &cmd); - cmd |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER; - pci_write_config_word(dev, PCI_COMMAND, cmd); - - pci_read_config_byte(dev, PCI_CLASS_REVISION, &cx->card_rev); - pci_read_config_byte(dev, PCI_LATENCY_TIMER, &pci_latency); - - if (pci_latency < 64 && cx18_pci_latency) { - CX18_INFO("Unreasonably low latency timer, " - "setting to 64 (was %d)\n", pci_latency); - pci_write_config_byte(dev, PCI_LATENCY_TIMER, 64); - pci_read_config_byte(dev, PCI_LATENCY_TIMER, &pci_latency); - } - - CX18_DEBUG_INFO("cx%d (rev %d) at %02x:%02x.%x, " - "irq: %d, latency: %d, memory: 0x%lx\n", - cx->dev->device, cx->card_rev, dev->bus->number, - PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn), - cx->dev->irq, pci_latency, (unsigned long)cx->base_addr); - - return 0; -} - -#ifdef MODULE -static u32 cx18_request_module(struct cx18 *cx, u32 hw, - const char *name, u32 id) -{ - if ((hw & id) == 0) - return hw; - if (request_module(name) != 0) { - CX18_ERR("Failed to load module %s\n", name); - return hw & ~id; - } - CX18_DEBUG_INFO("Loaded module %s\n", name); - return hw; -} -#endif - -static void cx18_load_and_init_modules(struct cx18 *cx) -{ - u32 hw = cx->card->hw_all; - int i; - -#ifdef MODULE - /* load modules */ -#ifdef CONFIG_MEDIA_TUNER_MODULE - hw = cx18_request_module(cx, hw, "tuner", CX18_HW_TUNER); -#endif -#ifdef CONFIG_VIDEO_CS5345_MODULE - hw = cx18_request_module(cx, hw, "cs5345", CX18_HW_CS5345); -#endif -#endif - - /* check which i2c devices are actually found */ - for (i = 0; i < 32; i++) { - u32 device = 1 << i; - - if (!(device & hw)) - continue; - if (device == CX18_HW_GPIO || device == CX18_HW_TVEEPROM || - device == CX18_HW_CX23418 || device == CX18_HW_DVB) { - /* These 'devices' do not use i2c probing */ - cx->hw_flags |= device; - continue; - } - cx18_i2c_register(cx, i); - if (cx18_i2c_hw_addr(cx, device) > 0) - cx->hw_flags |= device; - } - - hw = cx->hw_flags; -} - -static int __devinit cx18_probe(struct pci_dev *dev, - const struct pci_device_id *pci_id) -{ - int retval = 0; - int i; - int vbi_buf_size; - u32 devtype; - struct cx18 *cx; - - spin_lock(&cx18_cards_lock); - - /* Make sure we've got a place for this card */ - if (cx18_cards_active == CX18_MAX_CARDS) { - printk(KERN_ERR "cx18: Maximum number of cards detected (%d).\n", - cx18_cards_active); - spin_unlock(&cx18_cards_lock); - return -ENOMEM; - } - - cx = kzalloc(sizeof(struct cx18), GFP_ATOMIC); - if (!cx) { - spin_unlock(&cx18_cards_lock); - return -ENOMEM; - } - cx18_cards[cx18_cards_active] = cx; - cx->dev = dev; - cx->num = cx18_cards_active++; - snprintf(cx->name, sizeof(cx->name), "cx18-%d", cx->num); - CX18_INFO("Initializing card #%d\n", cx->num); - - spin_unlock(&cx18_cards_lock); - - cx18_process_options(cx); - if (cx->options.cardtype == -1) { - retval = -ENODEV; - goto err; - } - if (cx18_init_struct1(cx)) { - retval = -ENOMEM; - goto err; - } - - CX18_DEBUG_INFO("base addr: 0x%08x\n", cx->base_addr); - - /* PCI Device Setup */ - retval = cx18_setup_pci(cx, dev, pci_id); - if (retval != 0) - goto free_workqueue; - - /* save cx in the pci struct for later use */ - pci_set_drvdata(dev, cx); - - /* map io memory */ - CX18_DEBUG_INFO("attempting ioremap at 0x%08x len 0x%08x\n", - cx->base_addr + CX18_MEM_OFFSET, CX18_MEM_SIZE); - cx->enc_mem = ioremap_nocache(cx->base_addr + CX18_MEM_OFFSET, - CX18_MEM_SIZE); - if (!cx->enc_mem) { - CX18_ERR("ioremap failed, perhaps increasing __VMALLOC_RESERVE in page.h\n"); - CX18_ERR("or disabling CONFIG_HIGHMEM4G into the kernel would help\n"); - retval = -ENOMEM; - goto free_mem; - } - cx->reg_mem = cx->enc_mem + CX18_REG_OFFSET; - devtype = cx18_read_reg(cx, 0xC72028); - switch (devtype & 0xff000000) { - case 0xff000000: - CX18_INFO("cx23418 revision %08x (A)\n", devtype); - break; - case 0x01000000: - CX18_INFO("cx23418 revision %08x (B)\n", devtype); - break; - default: - CX18_INFO("cx23418 revision %08x (Unknown)\n", devtype); - break; - } - - cx18_init_power(cx, 1); - cx18_init_memory(cx); - - cx->scb = (struct cx18_scb __iomem *)(cx->enc_mem + SCB_OFFSET); - cx18_init_scb(cx); - - cx18_gpio_init(cx); - - /* active i2c */ - CX18_DEBUG_INFO("activating i2c...\n"); - retval = init_cx18_i2c(cx); - if (retval) { - CX18_ERR("Could not initialize i2c\n"); - goto free_map; - } - - CX18_DEBUG_INFO("Active card count: %d.\n", cx18_cards_active); - - if (cx->card->hw_all & CX18_HW_TVEEPROM) { - /* Based on the model number the cardtype may be changed. - The PCI IDs are not always reliable. */ - cx18_process_eeprom(cx); - } - if (cx->card->comment) - CX18_INFO("%s", cx->card->comment); - if (cx->card->v4l2_capabilities == 0) { - retval = -ENODEV; - goto free_i2c; - } - cx18_init_memory(cx); - cx18_init_scb(cx); - - /* Register IRQ */ - retval = request_irq(cx->dev->irq, cx18_irq_handler, - IRQF_SHARED | IRQF_DISABLED, cx->name, (void *)cx); - if (retval) { - CX18_ERR("Failed to register irq %d\n", retval); - goto free_i2c; - } - - if (cx->std == 0) - cx->std = V4L2_STD_NTSC_M; - - if (cx->options.tuner == -1) { - for (i = 0; i < CX18_CARD_MAX_TUNERS; i++) { - if ((cx->std & cx->card->tuners[i].std) == 0) - continue; - cx->options.tuner = cx->card->tuners[i].tuner; - break; - } - } - /* if no tuner was found, then pick the first tuner in the card list */ - if (cx->options.tuner == -1 && cx->card->tuners[0].std) { - cx->std = cx->card->tuners[0].std; - if (cx->std & V4L2_STD_PAL) - cx->std = V4L2_STD_PAL_BG | V4L2_STD_PAL_H; - else if (cx->std & V4L2_STD_NTSC) - cx->std = V4L2_STD_NTSC_M; - else if (cx->std & V4L2_STD_SECAM) - cx->std = V4L2_STD_SECAM_L; - cx->options.tuner = cx->card->tuners[0].tuner; - } - if (cx->options.radio == -1) - cx->options.radio = (cx->card->radio_input.audio_type != 0); - - /* The card is now fully identified, continue with card-specific - initialization. */ - cx18_init_struct2(cx); - - cx18_load_and_init_modules(cx); - - if (cx->std & V4L2_STD_525_60) { - cx->is_60hz = 1; - cx->is_out_60hz = 1; - } else { - cx->is_50hz = 1; - cx->is_out_50hz = 1; - } - cx->params.video_gop_size = cx->is_60hz ? 15 : 12; - - /* - * FIXME: setting the buffer size based on the tuner standard is - * suboptimal, as the CVBS and SVideo inputs could use a different std - * and the buffer could end up being too small in that case. - */ - vbi_buf_size = cx->vbi.raw_size * (cx->is_60hz ? 24 : 36) / 2; - cx->stream_buf_size[CX18_ENC_STREAM_TYPE_VBI] = vbi_buf_size; - - if (cx->stream_buffers[CX18_ENC_STREAM_TYPE_VBI] < 0) - cx->stream_buffers[CX18_ENC_STREAM_TYPE_VBI] = - cx->options.megabytes[CX18_ENC_STREAM_TYPE_VBI] * 1024 * 1024 - / vbi_buf_size; - else - cx->options.megabytes[CX18_ENC_STREAM_TYPE_VBI] = - cx->stream_buffers[CX18_ENC_STREAM_TYPE_VBI] * vbi_buf_size - / (1024 * 1024); - - if (cx->options.radio > 0) - cx->v4l2_cap |= V4L2_CAP_RADIO; - - if (cx->options.tuner > -1) { - struct tuner_setup setup; - - setup.addr = ADDR_UNSET; - setup.type = cx->options.tuner; - setup.mode_mask = T_ANALOG_TV; /* matches TV tuners */ - setup.tuner_callback = (setup.type == TUNER_XC2028) ? - cx18_reset_tuner_gpio : NULL; - cx18_call_i2c_clients(cx, TUNER_SET_TYPE_ADDR, &setup); - if (setup.type == TUNER_XC2028) { - static struct xc2028_ctrl ctrl = { - .fname = XC2028_DEFAULT_FIRMWARE, - .max_len = 64, - }; - struct v4l2_priv_tun_config cfg = { - .tuner = cx->options.tuner, - .priv = &ctrl, - }; - cx18_call_i2c_clients(cx, TUNER_SET_CONFIG, &cfg); - } - } - - /* The tuner is fixed to the standard. The other inputs (e.g. S-Video) - are not. */ - cx->tuner_std = cx->std; - - retval = cx18_streams_setup(cx); - if (retval) { - CX18_ERR("Error %d setting up streams\n", retval); - goto free_irq; - } - retval = cx18_streams_register(cx); - if (retval) { - CX18_ERR("Error %d registering devices\n", retval); - goto free_streams; - } - - CX18_INFO("Initialized card #%d: %s\n", cx->num, cx->card_name); - - return 0; - -free_streams: - cx18_streams_cleanup(cx, 1); -free_irq: - free_irq(cx->dev->irq, (void *)cx); -free_i2c: - exit_cx18_i2c(cx); -free_map: - cx18_iounmap(cx); -free_mem: - release_mem_region(cx->base_addr, CX18_MEM_SIZE); -free_workqueue: - destroy_workqueue(cx->work_queue); -err: - if (retval == 0) - retval = -ENODEV; - CX18_ERR("Error %d on initialization\n", retval); - - i = cx->num; - spin_lock(&cx18_cards_lock); - kfree(cx18_cards[i]); - cx18_cards[i] = NULL; - spin_unlock(&cx18_cards_lock); - return retval; -} - -int cx18_init_on_first_open(struct cx18 *cx) -{ - int video_input; - int fw_retry_count = 3; - struct v4l2_frequency vf; - struct cx18_open_id fh; - - fh.cx = cx; - - if (test_bit(CX18_F_I_FAILED, &cx->i_flags)) - return -ENXIO; - - if (test_and_set_bit(CX18_F_I_INITED, &cx->i_flags)) - return 0; - - while (--fw_retry_count > 0) { - /* load firmware */ - if (cx18_firmware_init(cx) == 0) - break; - if (fw_retry_count > 1) - CX18_WARN("Retry loading firmware\n"); - } - - if (fw_retry_count == 0) { - set_bit(CX18_F_I_FAILED, &cx->i_flags); - return -ENXIO; - } - set_bit(CX18_F_I_LOADED_FW, &cx->i_flags); - - /* Init the firmware twice to work around a silicon bug - * transport related. */ - - fw_retry_count = 3; - while (--fw_retry_count > 0) { - /* load firmware */ - if (cx18_firmware_init(cx) == 0) - break; - if (fw_retry_count > 1) - CX18_WARN("Retry loading firmware\n"); - } - - if (fw_retry_count == 0) { - set_bit(CX18_F_I_FAILED, &cx->i_flags); - return -ENXIO; - } - - vf.tuner = 0; - vf.type = V4L2_TUNER_ANALOG_TV; - vf.frequency = 6400; /* the tuner 'baseline' frequency */ - - /* Set initial frequency. For PAL/SECAM broadcasts no - 'default' channel exists AFAIK. */ - if (cx->std == V4L2_STD_NTSC_M_JP) - vf.frequency = 1460; /* ch. 1 91250*16/1000 */ - else if (cx->std & V4L2_STD_NTSC_M) - vf.frequency = 1076; /* ch. 4 67250*16/1000 */ - - video_input = cx->active_input; - cx->active_input++; /* Force update of input */ - cx18_s_input(NULL, &fh, video_input); - - /* Let the VIDIOC_S_STD ioctl do all the work, keeps the code - in one place. */ - cx->std++; /* Force full standard initialization */ - cx18_s_std(NULL, &fh, &cx->tuner_std); - cx18_s_frequency(NULL, &fh, &vf); - return 0; -} - -static void cx18_cancel_epu_work_orders(struct cx18 *cx) -{ - int i; - for (i = 0; i < CX18_MAX_EPU_WORK_ORDERS; i++) - cancel_work_sync(&cx->epu_work_order[i].work); -} - -static void cx18_remove(struct pci_dev *pci_dev) -{ - struct cx18 *cx = pci_get_drvdata(pci_dev); - - CX18_DEBUG_INFO("Removing Card #%d\n", cx->num); - - /* Stop all captures */ - CX18_DEBUG_INFO("Stopping all streams\n"); - if (atomic_read(&cx->tot_capturing) > 0) - cx18_stop_all_captures(cx); - - /* Interrupts */ - cx18_sw1_irq_disable(cx, IRQ_CPU_TO_EPU | IRQ_APU_TO_EPU); - cx18_sw2_irq_disable(cx, IRQ_CPU_TO_EPU_ACK | IRQ_APU_TO_EPU_ACK); - - cx18_halt_firmware(cx); - - cx18_cancel_epu_work_orders(cx); - - destroy_workqueue(cx->work_queue); - - cx18_streams_cleanup(cx, 1); - - exit_cx18_i2c(cx); - - free_irq(cx->dev->irq, (void *)cx); - - cx18_iounmap(cx); - - release_mem_region(cx->base_addr, CX18_MEM_SIZE); - - pci_disable_device(cx->dev); - - CX18_INFO("Removed %s, card #%d\n", cx->card_name, cx->num); -} - -/* define a pci_driver for card detection */ -static struct pci_driver cx18_pci_driver = { - .name = "cx18", - .id_table = cx18_pci_tbl, - .probe = cx18_probe, - .remove = cx18_remove, -}; - -static int module_start(void) -{ - printk(KERN_INFO "cx18: Start initialization, version %s\n", CX18_VERSION); - - memset(cx18_cards, 0, sizeof(cx18_cards)); - - /* Validate parameters */ - if (cx18_first_minor < 0 || cx18_first_minor >= CX18_MAX_CARDS) { - printk(KERN_ERR "cx18: Exiting, cx18_first_minor must be between 0 and %d\n", - CX18_MAX_CARDS - 1); - return -1; - } - - if (cx18_debug < 0 || cx18_debug > 511) { - cx18_debug = 0; - printk(KERN_INFO "cx18: Debug value must be >= 0 and <= 511!\n"); - } - - if (pci_register_driver(&cx18_pci_driver)) { - printk(KERN_ERR "cx18: Error detecting PCI card\n"); - return -ENODEV; - } - printk(KERN_INFO "cx18: End initialization\n"); - return 0; -} - -static void module_cleanup(void) -{ - int i; - - pci_unregister_driver(&cx18_pci_driver); - - for (i = 0; i < cx18_cards_active; i++) { - if (cx18_cards[i] == NULL) - continue; - kfree(cx18_cards[i]); - } - -} - -module_init(module_start); -module_exit(module_cleanup); diff --git a/drivers/media/video/cx18/cx18-driver.h b/drivers/media/video/cx18/cx18-driver.h deleted file mode 100644 index 0d2edebc39b..00000000000 --- a/drivers/media/video/cx18/cx18-driver.h +++ /dev/null @@ -1,514 +0,0 @@ -/* - * cx18 driver internal defines and structures - * - * Derived from ivtv-driver.h - * - * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> - * Copyright (C) 2008 Andy Walls <awalls@radix.net> - * - * 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., 59 Temple Place, Suite 330, Boston, MA - * 02111-1307 USA - */ - -#ifndef CX18_DRIVER_H -#define CX18_DRIVER_H - -#include <linux/version.h> -#include <linux/module.h> -#include <linux/moduleparam.h> -#include <linux/init.h> -#include <linux/delay.h> -#include <linux/sched.h> -#include <linux/fs.h> -#include <linux/pci.h> -#include <linux/interrupt.h> -#include <linux/spinlock.h> -#include <linux/i2c.h> -#include <linux/i2c-algo-bit.h> -#include <linux/list.h> -#include <linux/unistd.h> -#include <linux/pagemap.h> -#include <linux/workqueue.h> -#include <linux/mutex.h> -#include <asm/byteorder.h> - -#include <linux/dvb/video.h> -#include <linux/dvb/audio.h> -#include <media/v4l2-common.h> -#include <media/v4l2-ioctl.h> -#include <media/tuner.h> -#include "cx18-mailbox.h" -#include "cx18-av-core.h" -#include "cx23418.h" - -/* DVB */ -#include "demux.h" -#include "dmxdev.h" -#include "dvb_demux.h" -#include "dvb_frontend.h" -#include "dvb_net.h" -#include "dvbdev.h" - -#ifndef CONFIG_PCI -# error "This driver requires kernel PCI support." -#endif - -#define CX18_MEM_OFFSET 0x00000000 -#define CX18_MEM_SIZE 0x04000000 -#define CX18_REG_OFFSET 0x02000000 - -/* Maximum cx18 driver instances. */ -#define CX18_MAX_CARDS 32 - -/* Supported cards */ -#define CX18_CARD_HVR_1600_ESMT 0 /* Hauppauge HVR 1600 (ESMT memory) */ -#define CX18_CARD_HVR_1600_SAMSUNG 1 /* Hauppauge HVR 1600 (Samsung memory) */ -#define CX18_CARD_COMPRO_H900 2 /* Compro VideoMate H900 */ -#define CX18_CARD_YUAN_MPC718 3 /* Yuan MPC718 */ -#define CX18_CARD_CNXT_RAPTOR_PAL 4 /* Conexant Raptor PAL */ -#define CX18_CARD_TOSHIBA_QOSMIO_DVBT 5 /* Toshiba Qosmio Interal DVB-T/Analog*/ -#define CX18_CARD_LEADTEK_PVR2100 6 /* Leadtek WinFast PVR2100 */ -#define CX18_CARD_LAST 6 - -#define CX18_ENC_STREAM_TYPE_MPG 0 -#define CX18_ENC_STREAM_TYPE_TS 1 -#define CX18_ENC_STREAM_TYPE_YUV 2 -#define CX18_ENC_STREAM_TYPE_VBI 3 -#define CX18_ENC_STREAM_TYPE_PCM 4 -#define CX18_ENC_STREAM_TYPE_IDX 5 -#define CX18_ENC_STREAM_TYPE_RAD 6 -#define CX18_MAX_STREAMS 7 - -/* system vendor and device IDs */ -#define PCI_VENDOR_ID_CX 0x14f1 -#define PCI_DEVICE_ID_CX23418 0x5b7a - -/* subsystem vendor ID */ -#define CX18_PCI_ID_HAUPPAUGE 0x0070 -#define CX18_PCI_ID_COMPRO 0x185b -#define CX18_PCI_ID_YUAN 0x12ab -#define CX18_PCI_ID_CONEXANT 0x14f1 -#define CX18_PCI_ID_TOSHIBA 0x1179 -#define CX18_PCI_ID_LEADTEK 0x107D - -/* ======================================================================== */ -/* ========================== START USER SETTABLE DMA VARIABLES =========== */ -/* ======================================================================== */ - -/* DMA Buffers, Default size in MB allocated */ -#define CX18_DEFAULT_ENC_TS_BUFFERS 1 -#define CX18_DEFAULT_ENC_MPG_BUFFERS 2 -#define CX18_DEFAULT_ENC_IDX_BUFFERS 1 -#define CX18_DEFAULT_ENC_YUV_BUFFERS 2 -#define CX18_DEFAULT_ENC_VBI_BUFFERS 1 -#define CX18_DEFAULT_ENC_PCM_BUFFERS 1 - -/* Maximum firmware DMA buffers per stream */ -#define CX18_MAX_FW_MDLS_PER_STREAM 63 - -/* DMA buffer, default size in kB allocated */ -#define CX18_DEFAULT_ENC_TS_BUFSIZE 32 -#define CX18_DEFAULT_ENC_MPG_BUFSIZE 32 -#define CX18_DEFAULT_ENC_IDX_BUFSIZE 32 -#define CX18_DEFAULT_ENC_YUV_BUFSIZE 128 -/* Default VBI bufsize based on standards supported by card tuner for now */ -#define CX18_DEFAULT_ENC_PCM_BUFSIZE 4 - -/* i2c stuff */ -#define I2C_CLIENTS_MAX 16 - -/* debugging */ - -/* Flag to turn on high volume debugging */ -#define CX18_DBGFLG_WARN (1 << 0) -#define CX18_DBGFLG_INFO (1 << 1) -#define CX18_DBGFLG_API (1 << 2) -#define CX18_DBGFLG_DMA (1 << 3) -#define CX18_DBGFLG_IOCTL (1 << 4) -#define CX18_DBGFLG_FILE (1 << 5) -#define CX18_DBGFLG_I2C (1 << 6) -#define CX18_DBGFLG_IRQ (1 << 7) -/* Flag to turn on high volume debugging */ -#define CX18_DBGFLG_HIGHVOL (1 << 8) - -/* NOTE: extra space before comma in 'cx->num , ## args' is required for - gcc-2.95, otherwise it won't compile. */ -#define CX18_DEBUG(x, type, fmt, args...) \ - do { \ - if ((x) & cx18_debug) \ - printk(KERN_INFO "cx18-%d " type ": " fmt, cx->num , ## args); \ - } while (0) -#define CX18_DEBUG_WARN(fmt, args...) CX18_DEBUG(CX18_DBGFLG_WARN, "warning", fmt , ## args) -#define CX18_DEBUG_INFO(fmt, args...) CX18_DEBUG(CX18_DBGFLG_INFO, "info", fmt , ## args) -#define CX18_DEBUG_API(fmt, args...) CX18_DEBUG(CX18_DBGFLG_API, "api", fmt , ## args) -#define CX18_DEBUG_DMA(fmt, args...) CX18_DEBUG(CX18_DBGFLG_DMA, "dma", fmt , ## args) -#define CX18_DEBUG_IOCTL(fmt, args...) CX18_DEBUG(CX18_DBGFLG_IOCTL, "ioctl", fmt , ## args) -#define CX18_DEBUG_FILE(fmt, args...) CX18_DEBUG(CX18_DBGFLG_FILE, "file", fmt , ## args) -#define CX18_DEBUG_I2C(fmt, args...) CX18_DEBUG(CX18_DBGFLG_I2C, "i2c", fmt , ## args) -#define CX18_DEBUG_IRQ(fmt, args...) CX18_DEBUG(CX18_DBGFLG_IRQ, "irq", fmt , ## args) - -#define CX18_DEBUG_HIGH_VOL(x, type, fmt, args...) \ - do { \ - if (((x) & cx18_debug) && (cx18_debug & CX18_DBGFLG_HIGHVOL)) \ - printk(KERN_INFO "cx18%d " type ": " fmt, cx->num , ## args); \ - } while (0) -#define CX18_DEBUG_HI_WARN(fmt, args...) CX18_DEBUG_HIGH_VOL(CX18_DBGFLG_WARN, "warning", fmt , ## args) -#define CX18_DEBUG_HI_INFO(fmt, args...) CX18_DEBUG_HIGH_VOL(CX18_DBGFLG_INFO, "info", fmt , ## args) -#define CX18_DEBUG_HI_API(fmt, args...) CX18_DEBUG_HIGH_VOL(CX18_DBGFLG_API, "api", fmt , ## args) -#define CX18_DEBUG_HI_DMA(fmt, args...) CX18_DEBUG_HIGH_VOL(CX18_DBGFLG_DMA, "dma", fmt , ## args) -#define CX18_DEBUG_HI_IOCTL(fmt, args...) CX18_DEBUG_HIGH_VOL(CX18_DBGFLG_IOCTL, "ioctl", fmt , ## args) -#define CX18_DEBUG_HI_FILE(fmt, args...) CX18_DEBUG_HIGH_VOL(CX18_DBGFLG_FILE, "file", fmt , ## args) -#define CX18_DEBUG_HI_I2C(fmt, args...) CX18_DEBUG_HIGH_VOL(CX18_DBGFLG_I2C, "i2c", fmt , ## args) -#define CX18_DEBUG_HI_IRQ(fmt, args...) CX18_DEBUG_HIGH_VOL(CX18_DBGFLG_IRQ, "irq", fmt , ## args) - -/* Standard kernel messages */ -#define CX18_ERR(fmt, args...) printk(KERN_ERR "cx18-%d: " fmt, cx->num , ## args) -#define CX18_WARN(fmt, args...) printk(KERN_WARNING "cx18-%d: " fmt, cx->num , ## args) -#define CX18_INFO(fmt, args...) printk(KERN_INFO "cx18-%d: " fmt, cx->num , ## args) - -/* Values for CX18_API_DEC_PLAYBACK_SPEED mpeg_frame_type_mask parameter: */ -#define MPEG_FRAME_TYPE_IFRAME 1 -#define MPEG_FRAME_TYPE_IFRAME_PFRAME 3 -#define MPEG_FRAME_TYPE_ALL 7 - -#define CX18_MAX_PGM_INDEX (400) - -extern int cx18_debug; - - -struct cx18_options { - int megabytes[CX18_MAX_STREAMS]; /* Size in megabytes of each stream */ - int cardtype; /* force card type on load */ - int tuner; /* set tuner on load */ - int radio; /* enable/disable radio */ -}; - -/* per-buffer bit flags */ -#define CX18_F_B_NEED_BUF_SWAP 0 /* this buffer should be byte swapped */ - -/* per-stream, s_flags */ -#define CX18_F_S_CLAIMED 3 /* this stream is claimed */ -#define CX18_F_S_STREAMING 4 /* the fw is decoding/encoding this stream */ -#define CX18_F_S_INTERNAL_USE 5 /* this stream is used internally (sliced VBI processing) */ -#define CX18_F_S_STREAMOFF 7 /* signal end of stream EOS */ -#define CX18_F_S_APPL_IO 8 /* this stream is used read/written by an application */ - -/* per-cx18, i_flags */ -#define CX18_F_I_LOADED_FW 0 /* Loaded firmware 1st time */ -#define CX18_F_I_EOS 4 /* End of encoder stream */ -#define CX18_F_I_RADIO_USER 5 /* radio tuner is selected */ -#define CX18_F_I_ENC_PAUSED 13 /* the encoder is paused */ -#define CX18_F_I_INITED 21 /* set after first open */ -#define CX18_F_I_FAILED 22 /* set if first open failed */ - -/* These are the VBI types as they appear in the embedded VBI private packets. */ -#define CX18_SLICED_TYPE_TELETEXT_B (1) -#define CX18_SLICED_TYPE_CAPTION_525 (4) -#define CX18_SLICED_TYPE_WSS_625 (5) -#define CX18_SLICED_TYPE_VPS (7) - -struct cx18_buffer { - struct list_head list; - dma_addr_t dma_handle; - u32 id; - unsigned long b_flags; - unsigned skipped; - char *buf; - - u32 bytesused; - u32 readpos; -}; - -struct cx18_queue { - struct list_head list; - atomic_t buffers; - u32 bytesused; -}; - -struct cx18_dvb { - struct dmx_frontend hw_frontend; - struct dmx_frontend mem_frontend; - struct dmxdev dmxdev; - struct dvb_adapter dvb_adapter; - struct dvb_demux demux; - struct dvb_frontend *fe; - struct dvb_net dvbnet; - int enabled; - int feeding; - struct mutex feedlock; -}; - -struct cx18; /* forward reference */ -struct cx18_scb; /* forward reference */ - - -#define CX18_MAX_MDL_ACKS 2 -#define CX18_MAX_EPU_WORK_ORDERS (CX18_MAX_FW_MDLS_PER_STREAM + 7) -/* CPU_DE_RELEASE_MDL can burst CX18_MAX_FW_MDLS_PER_STREAM orders in a group */ - -#define CX18_F_EWO_MB_STALE_UPON_RECEIPT 0x1 -#define CX18_F_EWO_MB_STALE_WHILE_PROC 0x2 -#define CX18_F_EWO_MB_STALE \ - (CX18_F_EWO_MB_STALE_UPON_RECEIPT | CX18_F_EWO_MB_STALE_WHILE_PROC) - -struct cx18_epu_work_order { - struct work_struct work; - atomic_t pending; - struct cx18 *cx; - unsigned long flags; - int rpu; - struct cx18_mailbox mb; - struct cx18_mdl_ack mdl_ack[CX18_MAX_MDL_ACKS]; - char *str; -}; - -#define CX18_INVALID_TASK_HANDLE 0xffffffff - -struct cx18_stream { - /* These first four fields are always set, even if the stream - is not actually created. */ - struct video_device *v4l2dev; /* NULL when stream not created */ - struct cx18 *cx; /* for ease of use */ - const char *name; /* name of the stream */ - int type; /* stream type */ - u32 handle; /* task handle */ - unsigned mdl_offset; - - u32 id; - struct mutex qlock; /* locks access to the queues */ - unsigned long s_flags; /* status flags, see above */ - int dma; /* can be PCI_DMA_TODEVICE, - PCI_DMA_FROMDEVICE or - PCI_DMA_NONE */ - u64 dma_pts; - wait_queue_head_t waitq; - - /* Buffer Stats */ - u32 buffers; - u32 buf_size; - - /* Buffer Queues */ - struct cx18_queue q_free; /* free buffers */ - struct cx18_queue q_busy; /* busy buffers - in use by firmware */ - struct cx18_queue q_full; /* full buffers - data for user apps */ - - /* DVB / Digital Transport */ - struct cx18_dvb dvb; -}; - -struct cx18_open_id { - u32 open_id; - int type; - enum v4l2_priority prio; - struct cx18 *cx; -}; - -/* forward declaration of struct defined in cx18-cards.h */ -struct cx18_card; - - -#define CX18_VBI_FRAMES 32 - -/* VBI data */ -struct vbi_info { - u32 enc_size; - u32 frame; - u8 cc_data_odd[256]; - u8 cc_data_even[256]; - int cc_pos; - u8 cc_no_update; - u8 vps[5]; - u8 vps_found; - int wss; - u8 wss_found; - u8 wss_no_update; - u32 raw_decoder_line_size; - u8 raw_decoder_sav_odd_field; - u8 raw_decoder_sav_even_field; - u32 sliced_decoder_line_size; - u8 sliced_decoder_sav_odd_field; - u8 sliced_decoder_sav_even_field; - struct v4l2_format in; - /* convenience pointer to sliced struct in vbi_in union */ - struct v4l2_sliced_vbi_format *sliced_in; - u32 service_set_in; - int insert_mpeg; - - /* Buffer for the maximum of 2 * 18 * packet_size sliced VBI lines. - One for /dev/vbi0 and one for /dev/vbi8 */ - struct v4l2_sliced_vbi_data sliced_data[36]; - - /* Buffer for VBI data inserted into MPEG stream. - The first byte is a dummy byte that's never used. - The next 16 bytes contain the MPEG header for the VBI data, - the remainder is the actual VBI data. - The max size accepted by the MPEG VBI reinsertion turns out - to be 1552 bytes, which happens to be 4 + (1 + 42) * (2 * 18) bytes, - where 4 is a four byte header, 42 is the max sliced VBI payload, 1 is - a single line header byte and 2 * 18 is the number of VBI lines per frame. - - However, it seems that the data must be 1K aligned, so we have to - pad the data until the 1 or 2 K boundary. - - This pointer array will allocate 2049 bytes to store each VBI frame. */ - u8 *sliced_mpeg_data[CX18_VBI_FRAMES]; - u32 sliced_mpeg_size[CX18_VBI_FRAMES]; - struct cx18_buffer sliced_mpeg_buf; - u32 inserted_frame; - - u32 start[2], count; - u32 raw_size; - u32 sliced_size; -}; - -/* Per cx23418, per I2C bus private algo callback data */ -struct cx18_i2c_algo_callback_data { - struct cx18 *cx; - int bus_index; /* 0 or 1 for the cx23418's 1st or 2nd I2C bus */ -}; - -#define CX18_MAX_MMIO_WR_RETRIES 10 - -/* Struct to hold info about cx18 cards */ -struct cx18 { - int num; /* board number, -1 during init! */ - char name[8]; /* board name for printk and interrupts (e.g. 'cx180') */ - struct pci_dev *dev; /* PCI device */ - const struct cx18_card *card; /* card information */ - const char *card_name; /* full name of the card */ - const struct cx18_card_tuner_i2c *card_i2c; /* i2c addresses to probe for tuner */ - u8 is_50hz; - u8 is_60hz; - u8 is_out_50hz; - u8 is_out_60hz; - u8 nof_inputs; /* number of video inputs */ - u8 nof_audio_inputs; /* number of audio inputs */ - u16 buffer_id; /* buffer ID counter */ - u32 v4l2_cap; /* V4L2 capabilities of card */ - u32 hw_flags; /* Hardware description of the board */ - unsigned mdl_offset; - struct cx18_scb __iomem *scb; /* pointer to SCB */ - struct mutex epu2apu_mb_lock; /* protect driver to chip mailbox in SCB*/ - struct mutex epu2cpu_mb_lock; /* protect driver to chip mailbox in SCB*/ - - struct cx18_av_state av_state; - - /* codec settings */ - struct cx2341x_mpeg_params params; - u32 filter_mode; - u32 temporal_strength; - u32 spatial_strength; - - /* dualwatch */ - unsigned long dualwatch_jiffies; - u16 dualwatch_stereo_mode; - - /* Digitizer type */ - int digitizer; /* 0x00EF = saa7114 0x00FO = saa7115 0x0106 = mic */ - - struct mutex serialize_lock; /* mutex used to serialize open/close/start/stop/ioctl operations */ - struct cx18_options options; /* User options */ - int stream_buffers[CX18_MAX_STREAMS]; /* # of buffers for each stream */ - int stream_buf_size[CX18_MAX_STREAMS]; /* Stream buffer size */ - struct cx18_stream streams[CX18_MAX_STREAMS]; /* Stream data */ - unsigned long i_flags; /* global cx18 flags */ - atomic_t ana_capturing; /* count number of active analog capture streams */ - atomic_t tot_capturing; /* total count number of active capture streams */ - spinlock_t lock; /* lock access to this struct */ - int search_pack_header; - - int open_id; /* incremented each time an open occurs, used as - unique ID. Starts at 1, so 0 can be used as - uninitialized value in the stream->id. */ - - u32 base_addr; - struct v4l2_prio_state prio; - - u8 card_rev; - void __iomem *enc_mem, *reg_mem; - - struct vbi_info vbi; - - u32 pgm_info_offset; - u32 pgm_info_num; - u32 pgm_info_write_idx; - u32 pgm_info_read_idx; - struct v4l2_enc_idx_entry pgm_info[CX18_MAX_PGM_INDEX]; - - u64 mpg_data_received; - u64 vbi_data_inserted; - - wait_queue_head_t mb_apu_waitq; - wait_queue_head_t mb_cpu_waitq; - wait_queue_head_t cap_w; - /* when the current DMA is finished this queue is woken up */ - wait_queue_head_t dma_waitq; - - u32 sw1_irq_mask; - u32 sw2_irq_mask; - u32 hw2_irq_mask; - - struct workqueue_struct *work_queue; - struct cx18_epu_work_order epu_work_order[CX18_MAX_EPU_WORK_ORDERS]; - char epu_debug_str[256]; /* CX18_EPU_DEBUG is rare: use shared space */ - - /* i2c */ - struct i2c_adapter i2c_adap[2]; - struct i2c_algo_bit_data i2c_algo[2]; - struct cx18_i2c_algo_callback_data i2c_algo_cb_data[2]; - struct i2c_client i2c_client[2]; - struct mutex i2c_bus_lock[2]; - struct i2c_client *i2c_clients[I2C_CLIENTS_MAX]; - - /* gpio */ - u32 gpio_dir; - u32 gpio_val; - struct mutex gpio_lock; - - /* v4l2 and User settings */ - - /* codec settings */ - u32 audio_input; - u32 active_input; - u32 active_output; - v4l2_std_id std; - v4l2_std_id tuner_std; /* The norm of the tuner (fixed) */ -}; - -/* Globals */ -extern struct cx18 *cx18_cards[]; -extern int cx18_cards_active; -extern int cx18_first_minor; -extern spinlock_t cx18_cards_lock; - -/*==============Prototypes==================*/ - -/* Return non-zero if a signal is pending */ -int cx18_msleep_timeout(unsigned int msecs, int intr); - -/* Read Hauppauge eeprom */ -struct tveeprom; /* forward reference */ -void cx18_read_eeprom(struct cx18 *cx, struct tveeprom *tv); - -/* First-open initialization: load firmware, etc. */ -int cx18_init_on_first_open(struct cx18 *cx); - -/* Test if the current VBI mode is raw (1) or sliced (0) */ -static inline int cx18_raw_vbi(const struct cx18 *cx) -{ - return cx->vbi.in.type == V4L2_BUF_TYPE_VBI_CAPTURE; -} - -#endif /* CX18_DRIVER_H */ diff --git a/drivers/media/video/cx18/cx18-dvb.c b/drivers/media/video/cx18/cx18-dvb.c deleted file mode 100644 index bd5e6f3fd4d..00000000000 --- a/drivers/media/video/cx18/cx18-dvb.c +++ /dev/null @@ -1,310 +0,0 @@ -/* - * cx18 functions for DVB support - * - * Copyright (c) 2008 Steven Toth <stoth@linuxtv.org> - * Copyright (C) 2008 Andy Walls <awalls@radix.net> - * - * 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 "cx18-version.h" -#include "cx18-dvb.h" -#include "cx18-io.h" -#include "cx18-streams.h" -#include "cx18-cards.h" -#include "s5h1409.h" -#include "mxl5005s.h" - -DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); - -#define CX18_REG_DMUX_NUM_PORT_0_CONTROL 0xd5a000 - -static struct mxl5005s_config hauppauge_hvr1600_tuner = { - .i2c_address = 0xC6 >> 1, - .if_freq = IF_FREQ_5380000HZ, - .xtal_freq = CRYSTAL_FREQ_16000000HZ, - .agc_mode = MXL_SINGLE_AGC, - .tracking_filter = MXL_TF_C_H, - .rssi_enable = MXL_RSSI_ENABLE, - .cap_select = MXL_CAP_SEL_ENABLE, - .div_out = MXL_DIV_OUT_4, - .clock_out = MXL_CLOCK_OUT_DISABLE, - .output_load = MXL5005S_IF_OUTPUT_LOAD_200_OHM, - .top = MXL5005S_TOP_25P2, - .mod_mode = MXL_DIGITAL_MODE, - .if_mode = MXL_ZERO_IF, - .AgcMasterByte = 0x00, -}; - -static struct s5h1409_config hauppauge_hvr1600_config = { - .demod_address = 0x32 >> 1, - .output_mode = S5H1409_SERIAL_OUTPUT, - .gpio = S5H1409_GPIO_ON, - .qam_if = 44000, - .inversion = S5H1409_INVERSION_OFF, - .status_mode = S5H1409_DEMODLOCKING, - .mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK - -}; - -static int dvb_register(struct cx18_stream *stream); - -/* Kernel DVB framework calls this when the feed needs to start. - * The CX18 framework should enable the transport DMA handling - * and queue processing. - */ -static int cx18_dvb_start_feed(struct dvb_demux_feed *feed) -{ - struct dvb_demux *demux = feed->demux; - struct cx18_stream *stream = (struct cx18_stream *) demux->priv; - struct cx18 *cx = stream->cx; - int ret; - u32 v; - - CX18_DEBUG_INFO("Start feed: pid = 0x%x index = %d\n", - feed->pid, feed->index); - - mutex_lock(&cx->serialize_lock); - ret = cx18_init_on_first_open(cx); - mutex_unlock(&cx->serialize_lock); - if (ret) { - CX18_ERR("Failed to initialize firmware starting DVB feed\n"); - return ret; - } - ret = -EINVAL; - - switch (cx->card->type) { - case CX18_CARD_HVR_1600_ESMT: - case CX18_CARD_HVR_1600_SAMSUNG: - v = cx18_read_reg(cx, CX18_REG_DMUX_NUM_PORT_0_CONTROL); - v |= 0x00400000; /* Serial Mode */ - v |= 0x00002000; /* Data Length - Byte */ - v |= 0x00010000; /* Error - Polarity */ - v |= 0x00020000; /* Error - Passthru */ - v |= 0x000c0000; /* Error - Ignore */ - cx18_write_reg(cx, v, CX18_REG_DMUX_NUM_PORT_0_CONTROL); - break; - - default: - /* Assumption - Parallel transport - Signalling - * undefined or default. - */ - break; - } - - if (!demux->dmx.frontend) - return -EINVAL; - - if (!stream) - return -EINVAL; - - mutex_lock(&stream->dvb.feedlock); - if (stream->dvb.feeding++ == 0) { - CX18_DEBUG_INFO("Starting Transport DMA\n"); - set_bit(CX18_F_S_STREAMING, &stream->s_flags); - ret = cx18_start_v4l2_encode_stream(stream); - if (ret < 0) { - CX18_DEBUG_INFO("Failed to start Transport DMA\n"); - stream->dvb.feeding--; - if (stream->dvb.feeding == 0) - clear_bit(CX18_F_S_STREAMING, &stream->s_flags); - } - } else - ret = 0; - mutex_unlock(&stream->dvb.feedlock); - - return ret; -} - -/* Kernel DVB framework calls this when the feed needs to stop. */ -static int cx18_dvb_stop_feed(struct dvb_demux_feed *feed) -{ - struct dvb_demux *demux = feed->demux; - struct cx18_stream *stream = (struct cx18_stream *)demux->priv; - struct cx18 *cx = stream->cx; - int ret = -EINVAL; - - CX18_DEBUG_INFO("Stop feed: pid = 0x%x index = %d\n", - feed->pid, feed->index); - - if (stream) { - mutex_lock(&stream->dvb.feedlock); - if (--stream->dvb.feeding == 0) { - CX18_DEBUG_INFO("Stopping Transport DMA\n"); - ret = cx18_stop_v4l2_encode_stream(stream, 0); - } else - ret = 0; - mutex_unlock(&stream->dvb.feedlock); - } - - return ret; -} - -int cx18_dvb_register(struct cx18_stream *stream) -{ - struct cx18 *cx = stream->cx; - struct cx18_dvb *dvb = &stream->dvb; - struct dvb_adapter *dvb_adapter; - struct dvb_demux *dvbdemux; - struct dmx_demux *dmx; - int ret; - - if (!dvb) - return -EINVAL; - - ret = dvb_register_adapter(&dvb->dvb_adapter, - CX18_DRIVER_NAME, - THIS_MODULE, &cx->dev->dev, adapter_nr); - if (ret < 0) - goto err_out; - - dvb_adapter = &dvb->dvb_adapter; - - dvbdemux = &dvb->demux; - - dvbdemux->priv = (void *)stream; - - dvbdemux->filternum = 256; - dvbdemux->feednum = 256; - dvbdemux->start_feed = cx18_dvb_start_feed; - dvbdemux->stop_feed = cx18_dvb_stop_feed; - dvbdemux->dmx.capabilities = (DMX_TS_FILTERING | - DMX_SECTION_FILTERING | DMX_MEMORY_BASED_FILTERING); - ret = dvb_dmx_init(dvbdemux); - if (ret < 0) - goto err_dvb_unregister_adapter; - - dmx = &dvbdemux->dmx; - - dvb->hw_frontend.source = DMX_FRONTEND_0; - dvb->mem_frontend.source = DMX_MEMORY_FE; - dvb->dmxdev.filternum = 256; - dvb->dmxdev.demux = dmx; - - ret = dvb_dmxdev_init(&dvb->dmxdev, dvb_adapter); - if (ret < 0) - goto err_dvb_dmx_release; - - ret = dmx->add_frontend(dmx, &dvb->hw_frontend); - if (ret < 0) - goto err_dvb_dmxdev_release; - - ret = dmx->add_frontend(dmx, &dvb->mem_frontend); - if (ret < 0) - goto err_remove_hw_frontend; - - ret = dmx->connect_frontend(dmx, &dvb->hw_frontend); - if (ret < 0) - goto err_remove_mem_frontend; - - ret = dvb_register(stream); - if (ret < 0) - goto err_disconnect_frontend; - - dvb_net_init(dvb_adapter, &dvb->dvbnet, dmx); - - CX18_INFO("DVB Frontend registered\n"); - CX18_INFO("Registered DVB adapter%d for %s (%d x %d kB)\n", - stream->dvb.dvb_adapter.num, stream->name, - stream->buffers, stream->buf_size/1024); - - mutex_init(&dvb->feedlock); - dvb->enabled = 1; - return ret; - -err_disconnect_frontend: - dmx->disconnect_frontend(dmx); -err_remove_mem_frontend: - dmx->remove_frontend(dmx, &dvb->mem_frontend); -err_remove_hw_frontend: - dmx->remove_frontend(dmx, &dvb->hw_frontend); -err_dvb_dmxdev_release: - dvb_dmxdev_release(&dvb->dmxdev); -err_dvb_dmx_release: - dvb_dmx_release(dvbdemux); -err_dvb_unregister_adapter: - dvb_unregister_adapter(dvb_adapter); -err_out: - return ret; -} - -void cx18_dvb_unregister(struct cx18_stream *stream) -{ - struct cx18 *cx = stream->cx; - struct cx18_dvb *dvb = &stream->dvb; - struct dvb_adapter *dvb_adapter; - struct dvb_demux *dvbdemux; - struct dmx_demux *dmx; - - CX18_INFO("unregister DVB\n"); - - dvb_adapter = &dvb->dvb_adapter; - dvbdemux = &dvb->demux; - dmx = &dvbdemux->dmx; - - dmx->close(dmx); - dvb_net_release(&dvb->dvbnet); - dmx->remove_frontend(dmx, &dvb->mem_frontend); - dmx->remove_frontend(dmx, &dvb->hw_frontend); - dvb_dmxdev_release(&dvb->dmxdev); - dvb_dmx_release(dvbdemux); - dvb_unregister_frontend(dvb->fe); - dvb_frontend_detach(dvb->fe); - dvb_unregister_adapter(dvb_adapter); -} - -/* All the DVB attach calls go here, this function get's modified - * for each new card. No other function in this file needs - * to change. - */ -static int dvb_register(struct cx18_stream *stream) -{ - struct cx18_dvb *dvb = &stream->dvb; - struct cx18 *cx = stream->cx; - int ret = 0; - - switch (cx->card->type) { - case CX18_CARD_HVR_1600_ESMT: - case CX18_CARD_HVR_1600_SAMSUNG: - dvb->fe = dvb_attach(s5h1409_attach, - &hauppauge_hvr1600_config, - &cx->i2c_adap[0]); - if (dvb->fe != NULL) { - dvb_attach(mxl5005s_attach, dvb->fe, - &cx->i2c_adap[0], - &hauppauge_hvr1600_tuner); - ret = 0; - } - break; - default: - /* No Digital Tv Support */ - break; - } - - if (dvb->fe == NULL) { - CX18_ERR("frontend initialization failed\n"); - return -1; - } - - ret = dvb_register_frontend(&dvb->dvb_adapter, dvb->fe); - if (ret < 0) { - if (dvb->fe->ops.release) - dvb->fe->ops.release(dvb->fe); - return ret; - } - - return ret; -} diff --git a/drivers/media/video/cx18/cx18-dvb.h b/drivers/media/video/cx18/cx18-dvb.h deleted file mode 100644 index bf8d8f6f545..00000000000 --- a/drivers/media/video/cx18/cx18-dvb.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * cx18 functions for DVB support - * - * Copyright (c) 2008 Steven Toth <stoth@linuxtv.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; 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 "cx18-driver.h" - -int cx18_dvb_register(struct cx18_stream *stream); -void cx18_dvb_unregister(struct cx18_stream *stream); diff --git a/drivers/media/video/cx18/cx18-fileops.c b/drivers/media/video/cx18/cx18-fileops.c deleted file mode 100644 index 055f6e004b2..00000000000 --- a/drivers/media/video/cx18/cx18-fileops.c +++ /dev/null @@ -1,721 +0,0 @@ -/* - * cx18 file operation functions - * - * Derived from ivtv-fileops.c - * - * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> - * Copyright (C) 2008 Andy Walls <awalls@radix.net> - * - * 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., 59 Temple Place, Suite 330, Boston, MA - * 02111-1307 USA - */ - -#include "cx18-driver.h" -#include "cx18-fileops.h" -#include "cx18-i2c.h" -#include "cx18-queue.h" -#include "cx18-vbi.h" -#include "cx18-audio.h" -#include "cx18-mailbox.h" -#include "cx18-scb.h" -#include "cx18-streams.h" -#include "cx18-controls.h" -#include "cx18-ioctl.h" -#include "cx18-cards.h" - -/* This function tries to claim the stream for a specific file descriptor. - If no one else is using this stream then the stream is claimed and - associated VBI streams are also automatically claimed. - Possible error returns: -EBUSY if someone else has claimed - the stream or 0 on success. */ -static int cx18_claim_stream(struct cx18_open_id *id, int type) -{ - struct cx18 *cx = id->cx; - struct cx18_stream *s = &cx->streams[type]; - struct cx18_stream *s_vbi; - int vbi_type; - - if (test_and_set_bit(CX18_F_S_CLAIMED, &s->s_flags)) { - /* someone already claimed this stream */ - if (s->id == id->open_id) { - /* yes, this file descriptor did. So that's OK. */ - return 0; - } - if (s->id == -1 && type == CX18_ENC_STREAM_TYPE_VBI) { - /* VBI is handled already internally, now also assign - the file descriptor to this stream for external - reading of the stream. */ - s->id = id->open_id; - CX18_DEBUG_INFO("Start Read VBI\n"); - return 0; - } - /* someone else is using this stream already */ - CX18_DEBUG_INFO("Stream %d is busy\n", type); - return -EBUSY; - } - s->id = id->open_id; - - /* CX18_ENC_STREAM_TYPE_MPG needs to claim CX18_ENC_STREAM_TYPE_VBI - (provided VBI insertion is on and sliced VBI is selected), for all - other streams we're done */ - if (type == CX18_ENC_STREAM_TYPE_MPG && - cx->vbi.insert_mpeg && !cx18_raw_vbi(cx)) { - vbi_type = CX18_ENC_STREAM_TYPE_VBI; - } else { - return 0; - } - s_vbi = &cx->streams[vbi_type]; - - set_bit(CX18_F_S_CLAIMED, &s_vbi->s_flags); - - /* mark that it is used internally */ - set_bit(CX18_F_S_INTERNAL_USE, &s_vbi->s_flags); - return 0; -} - -/* This function releases a previously claimed stream. It will take into - account associated VBI streams. */ -static void cx18_release_stream(struct cx18_stream *s) -{ - struct cx18 *cx = s->cx; - struct cx18_stream *s_vbi; - - s->id = -1; - if (s->type == CX18_ENC_STREAM_TYPE_VBI && - test_bit(CX18_F_S_INTERNAL_USE, &s->s_flags)) { - /* this stream is still in use internally */ - return; - } - if (!test_and_clear_bit(CX18_F_S_CLAIMED, &s->s_flags)) { - CX18_DEBUG_WARN("Release stream %s not in use!\n", s->name); - return; - } - - cx18_flush_queues(s); - - /* CX18_ENC_STREAM_TYPE_MPG needs to release CX18_ENC_STREAM_TYPE_VBI, - for all other streams we're done */ - if (s->type == CX18_ENC_STREAM_TYPE_MPG) - s_vbi = &cx->streams[CX18_ENC_STREAM_TYPE_VBI]; - else - return; - - /* clear internal use flag */ - if (!test_and_clear_bit(CX18_F_S_INTERNAL_USE, &s_vbi->s_flags)) { - /* was already cleared */ - return; - } - if (s_vbi->id != -1) { - /* VBI stream still claimed by a file descriptor */ - return; - } - clear_bit(CX18_F_S_CLAIMED, &s_vbi->s_flags); - cx18_flush_queues(s_vbi); -} - -static void cx18_dualwatch(struct cx18 *cx) -{ - struct v4l2_tuner vt; - u16 new_bitmap; - u16 new_stereo_mode; - const u16 stereo_mask = 0x0300; - const u16 dual = 0x0200; - u32 h; - - new_stereo_mode = cx->params.audio_properties & stereo_mask; - memset(&vt, 0, sizeof(vt)); - cx18_call_i2c_clients(cx, VIDIOC_G_TUNER, &vt); - if (vt.audmode == V4L2_TUNER_MODE_LANG1_LANG2 && - (vt.rxsubchans & V4L2_TUNER_SUB_LANG2)) - new_stereo_mode = dual; - - if (new_stereo_mode == cx->dualwatch_stereo_mode) - return; - - new_bitmap = new_stereo_mode - | (cx->params.audio_properties & ~stereo_mask); - - CX18_DEBUG_INFO("dualwatch: change stereo flag from 0x%x to 0x%x. " - "new audio_bitmask=0x%ux\n", - cx->dualwatch_stereo_mode, new_stereo_mode, new_bitmap); - - h = cx18_find_handle(cx); - if (h == CX18_INVALID_TASK_HANDLE) { - CX18_DEBUG_INFO("dualwatch: can't find valid task handle\n"); - return; - } - - if (cx18_vapi(cx, - CX18_CPU_SET_AUDIO_PARAMETERS, 2, h, new_bitmap) == 0) { - cx->dualwatch_stereo_mode = new_stereo_mode; - return; - } - CX18_DEBUG_INFO("dualwatch: changing stereo flag failed\n"); -} - - -static struct cx18_buffer *cx18_get_buffer(struct cx18_stream *s, int non_block, int *err) -{ - struct cx18 *cx = s->cx; - struct cx18_stream *s_vbi = &cx->streams[CX18_ENC_STREAM_TYPE_VBI]; - struct cx18_buffer *buf; - DEFINE_WAIT(wait); - - *err = 0; - while (1) { - if (s->type == CX18_ENC_STREAM_TYPE_MPG) { - - if (time_after(jiffies, cx->dualwatch_jiffies + msecs_to_jiffies(1000))) { - cx->dualwatch_jiffies = jiffies; - cx18_dualwatch(cx); - } - if (test_bit(CX18_F_S_INTERNAL_USE, &s_vbi->s_flags) && - !test_bit(CX18_F_S_APPL_IO, &s_vbi->s_flags)) { - while ((buf = cx18_dequeue(s_vbi, &s_vbi->q_full))) { - /* byteswap and process VBI data */ - cx18_process_vbi_data(cx, buf, - s_vbi->dma_pts, - s_vbi->type); - cx18_stream_put_buf_fw(s_vbi, buf); - } - } - buf = &cx->vbi.sliced_mpeg_buf; - if (buf->readpos != buf->bytesused) - return buf; - } - - /* do we have new data? */ - buf = cx18_dequeue(s, &s->q_full); - if (buf) { - if (!test_and_clear_bit(CX18_F_B_NEED_BUF_SWAP, - &buf->b_flags)) - return buf; - if (s->type == CX18_ENC_STREAM_TYPE_MPG) - /* byteswap MPG data */ - cx18_buf_swap(buf); - else { - /* byteswap and process VBI data */ - cx18_process_vbi_data(cx, buf, - s->dma_pts, s->type); - } - return buf; - } - - /* return if end of stream */ - if (!test_bit(CX18_F_S_STREAMING, &s->s_flags)) { - CX18_DEBUG_INFO("EOS %s\n", s->name); - return NULL; - } - - /* return if file was opened with O_NONBLOCK */ - if (non_block) { - *err = -EAGAIN; - return NULL; - } - - /* wait for more data to arrive */ - prepare_to_wait(&s->waitq, &wait, TASK_INTERRUPTIBLE); - /* New buffers might have become available before we were added - to the waitqueue */ - if (!atomic_read(&s->q_full.buffers)) - schedule(); - finish_wait(&s->waitq, &wait); - if (signal_pending(current)) { - /* return if a signal was received */ - CX18_DEBUG_INFO("User stopped %s\n", s->name); - *err = -EINTR; - return NULL; - } - } -} - -static void cx18_setup_sliced_vbi_buf(struct cx18 *cx) -{ - int idx = cx->vbi.inserted_frame % CX18_VBI_FRAMES; - - cx->vbi.sliced_mpeg_buf.buf = cx->vbi.sliced_mpeg_data[idx]; - cx->vbi.sliced_mpeg_buf.bytesused = cx->vbi.sliced_mpeg_size[idx]; - cx->vbi.sliced_mpeg_buf.readpos = 0; -} - -static size_t cx18_copy_buf_to_user(struct cx18_stream *s, - struct cx18_buffer *buf, char __user *ubuf, size_t ucount) -{ - struct cx18 *cx = s->cx; - size_t len = buf->bytesused - buf->readpos; - - if (len > ucount) - len = ucount; - if (cx->vbi.insert_mpeg && s->type == CX18_ENC_STREAM_TYPE_MPG && - !cx18_raw_vbi(cx) && buf != &cx->vbi.sliced_mpeg_buf) { - const char *start = buf->buf + buf->readpos; - const char *p = start + 1; - const u8 *q; - u8 ch = cx->search_pack_header ? 0xba : 0xe0; - int stuffing, i; - - while (start + len > p) { - q = memchr(p, 0, start + len - p); - if (q == NULL) - break; - p = q + 1; - if ((char *)q + 15 >= buf->buf + buf->bytesused || - q[1] != 0 || q[2] != 1 || q[3] != ch) - continue; - if (!cx->search_pack_header) { - if ((q[6] & 0xc0) != 0x80) - continue; - if (((q[7] & 0xc0) == 0x80 && - (q[9] & 0xf0) == 0x20) || - ((q[7] & 0xc0) == 0xc0 && - (q[9] & 0xf0) == 0x30)) { - ch = 0xba; - cx->search_pack_header = 1; - p = q + 9; - } - continue; - } - stuffing = q[13] & 7; - /* all stuffing bytes must be 0xff */ - for (i = 0; i < stuffing; i++) - if (q[14 + i] != 0xff) - break; - if (i == stuffing && - (q[4] & 0xc4) == 0x44 && - (q[12] & 3) == 3 && - q[14 + stuffing] == 0 && - q[15 + stuffing] == 0 && - q[16 + stuffing] == 1) { - cx->search_pack_header = 0; - len = (char *)q - start; - cx18_setup_sliced_vbi_buf(cx); - break; - } - } - } - if (copy_to_user(ubuf, (u8 *)buf->buf + buf->readpos, len)) { - CX18_DEBUG_WARN("copy %zd bytes to user failed for %s\n", - len, s->name); - return -EFAULT; - } - buf->readpos += len; - if (s->type == CX18_ENC_STREAM_TYPE_MPG && - buf != &cx->vbi.sliced_mpeg_buf) - cx->mpg_data_received += len; - return len; -} - -static ssize_t cx18_read(struct cx18_stream *s, char __user *ubuf, - size_t tot_count, int non_block) -{ - struct cx18 *cx = s->cx; - size_t tot_written = 0; - int single_frame = 0; - - if (atomic_read(&cx->ana_capturing) == 0 && s->id == -1) { - /* shouldn't happen */ - CX18_DEBUG_WARN("Stream %s not initialized before read\n", - s->name); - return -EIO; - } - - /* Each VBI buffer is one frame, the v4l2 API says that for VBI the - frames should arrive one-by-one, so make sure we never output more - than one VBI frame at a time */ - if (s->type == CX18_ENC_STREAM_TYPE_VBI && !cx18_raw_vbi(cx)) - single_frame = 1; - - for (;;) { - struct cx18_buffer *buf; - int rc; - - buf = cx18_get_buffer(s, non_block, &rc); - /* if there is no data available... */ - if (buf == NULL) { - /* if we got data, then return that regardless */ - if (tot_written) - break; - /* EOS condition */ - if (rc == 0) { - clear_bit(CX18_F_S_STREAMOFF, &s->s_flags); - clear_bit(CX18_F_S_APPL_IO, &s->s_flags); - cx18_release_stream(s); - } - /* set errno */ - return rc; - } - - rc = cx18_copy_buf_to_user(s, buf, ubuf + tot_written, - tot_count - tot_written); - - if (buf != &cx->vbi.sliced_mpeg_buf) { - if (buf->readpos == buf->bytesused) - cx18_stream_put_buf_fw(s, buf); - else - cx18_push(s, buf, &s->q_full); - } else if (buf->readpos == buf->bytesused) { - int idx = cx->vbi.inserted_frame % CX18_VBI_FRAMES; - - cx->vbi.sliced_mpeg_size[idx] = 0; - cx->vbi.inserted_frame++; - cx->vbi_data_inserted += buf->bytesused; - } - if (rc < 0) - return rc; - tot_written += rc; - - if (tot_written == tot_count || single_frame) - break; - } - return tot_written; -} - -static ssize_t cx18_read_pos(struct cx18_stream *s, char __user *ubuf, - size_t count, loff_t *pos, int non_block) -{ - ssize_t rc = count ? cx18_read(s, ubuf, count, non_block) : 0; - struct cx18 *cx = s->cx; - - CX18_DEBUG_HI_FILE("read %zd from %s, got %zd\n", count, s->name, rc); - if (rc > 0) - pos += rc; - return rc; -} - -int cx18_start_capture(struct cx18_open_id *id) -{ - struct cx18 *cx = id->cx; - struct cx18_stream *s = &cx->streams[id->type]; - struct cx18_stream *s_vbi; - - if (s->type == CX18_ENC_STREAM_TYPE_RAD) { - /* you cannot read from these stream types. */ - return -EPERM; - } - - /* Try to claim this stream. */ - if (cx18_claim_stream(id, s->type)) - return -EBUSY; - - /* If capture is already in progress, then we also have to - do nothing extra. */ - if (test_bit(CX18_F_S_STREAMOFF, &s->s_flags) || - test_and_set_bit(CX18_F_S_STREAMING, &s->s_flags)) { - set_bit(CX18_F_S_APPL_IO, &s->s_flags); - return 0; - } - - /* Start VBI capture if required */ - s_vbi = &cx->streams[CX18_ENC_STREAM_TYPE_VBI]; - if (s->type == CX18_ENC_STREAM_TYPE_MPG && - test_bit(CX18_F_S_INTERNAL_USE, &s_vbi->s_flags) && - !test_and_set_bit(CX18_F_S_STREAMING, &s_vbi->s_flags)) { - /* Note: the CX18_ENC_STREAM_TYPE_VBI is claimed - automatically when the MPG stream is claimed. - We only need to start the VBI capturing. */ - if (cx18_start_v4l2_encode_stream(s_vbi)) { - CX18_DEBUG_WARN("VBI capture start failed\n"); - - /* Failure, clean up and return an error */ - clear_bit(CX18_F_S_STREAMING, &s_vbi->s_flags); - clear_bit(CX18_F_S_STREAMING, &s->s_flags); - /* also releases the associated VBI stream */ - cx18_release_stream(s); - return -EIO; - } - CX18_DEBUG_INFO("VBI insertion started\n"); - } - - /* Tell the card to start capturing */ - if (!cx18_start_v4l2_encode_stream(s)) { - /* We're done */ - set_bit(CX18_F_S_APPL_IO, &s->s_flags); - /* Resume a possibly paused encoder */ - if (test_and_clear_bit(CX18_F_I_ENC_PAUSED, &cx->i_flags)) - cx18_vapi(cx, CX18_CPU_CAPTURE_PAUSE, 1, s->handle); - return 0; - } - - /* failure, clean up */ - CX18_DEBUG_WARN("Failed to start capturing for stream %s\n", s->name); - - /* Note: the CX18_ENC_STREAM_TYPE_VBI is released - automatically when the MPG stream is released. - We only need to stop the VBI capturing. */ - if (s->type == CX18_ENC_STREAM_TYPE_MPG && - test_bit(CX18_F_S_STREAMING, &s_vbi->s_flags)) { - cx18_stop_v4l2_encode_stream(s_vbi, 0); - clear_bit(CX18_F_S_STREAMING, &s_vbi->s_flags); - } - clear_bit(CX18_F_S_STREAMING, &s->s_flags); - cx18_release_stream(s); - return -EIO; -} - -ssize_t cx18_v4l2_read(struct file *filp, char __user *buf, size_t count, - loff_t *pos) -{ - struct cx18_open_id *id = filp->private_data; - struct cx18 *cx = id->cx; - struct cx18_stream *s = &cx->streams[id->type]; - int rc; - - CX18_DEBUG_HI_FILE("read %zd bytes from %s\n", count, s->name); - - mutex_lock(&cx->serialize_lock); - rc = cx18_start_capture(id); - mutex_unlock(&cx->serialize_lock); - if (rc) - return rc; - return cx18_read_pos(s, buf, count, pos, filp->f_flags & O_NONBLOCK); -} - -unsigned int cx18_v4l2_enc_poll(struct file *filp, poll_table *wait) -{ - struct cx18_open_id *id = filp->private_data; - struct cx18 *cx = id->cx; - struct cx18_stream *s = &cx->streams[id->type]; - int eof = test_bit(CX18_F_S_STREAMOFF, &s->s_flags); - - /* Start a capture if there is none */ - if (!eof && !test_bit(CX18_F_S_STREAMING, &s->s_flags)) { - int rc; - - mutex_lock(&cx->serialize_lock); - rc = cx18_start_capture(id); - mutex_unlock(&cx->serialize_lock); - if (rc) { - CX18_DEBUG_INFO("Could not start capture for %s (%d)\n", - s->name, rc); - return POLLERR; - } - CX18_DEBUG_FILE("Encoder poll started capture\n"); - } - - /* add stream's waitq to the poll list */ - CX18_DEBUG_HI_FILE("Encoder poll\n"); - poll_wait(filp, &s->waitq, wait); - - if (atomic_read(&s->q_full.buffers)) - return POLLIN | POLLRDNORM; - if (eof) - return POLLHUP; - return 0; -} - -void cx18_stop_capture(struct cx18_open_id *id, int gop_end) -{ - struct cx18 *cx = id->cx; - struct cx18_stream *s = &cx->streams[id->type]; - - CX18_DEBUG_IOCTL("close() of %s\n", s->name); - - /* 'Unclaim' this stream */ - - /* Stop capturing */ - if (test_bit(CX18_F_S_STREAMING, &s->s_flags)) { - struct cx18_stream *s_vbi = - &cx->streams[CX18_ENC_STREAM_TYPE_VBI]; - - CX18_DEBUG_INFO("close stopping capture\n"); - /* Special case: a running VBI capture for VBI insertion - in the mpeg stream. Need to stop that too. */ - if (id->type == CX18_ENC_STREAM_TYPE_MPG && - test_bit(CX18_F_S_STREAMING, &s_vbi->s_flags) && - !test_bit(CX18_F_S_APPL_IO, &s_vbi->s_flags)) { - CX18_DEBUG_INFO("close stopping embedded VBI capture\n"); - cx18_stop_v4l2_encode_stream(s_vbi, 0); - } - if (id->type == CX18_ENC_STREAM_TYPE_VBI && - test_bit(CX18_F_S_INTERNAL_USE, &s->s_flags)) - /* Also used internally, don't stop capturing */ - s->id = -1; - else - cx18_stop_v4l2_encode_stream(s, gop_end); - } - if (!gop_end) { - clear_bit(CX18_F_S_APPL_IO, &s->s_flags); - clear_bit(CX18_F_S_STREAMOFF, &s->s_flags); - cx18_release_stream(s); - } -} - -int cx18_v4l2_close(struct file *filp) -{ - struct cx18_open_id *id = filp->private_data; - struct cx18 *cx = id->cx; - struct cx18_stream *s = &cx->streams[id->type]; - - CX18_DEBUG_IOCTL("close() of %s\n", s->name); - - v4l2_prio_close(&cx->prio, &id->prio); - - /* Easy case first: this stream was never claimed by us */ - if (s->id != id->open_id) { - kfree(id); - return 0; - } - - /* 'Unclaim' this stream */ - - /* Stop radio */ - mutex_lock(&cx->serialize_lock); - if (id->type == CX18_ENC_STREAM_TYPE_RAD) { - /* Closing radio device, return to TV mode */ - cx18_mute(cx); - /* Mark that the radio is no longer in use */ - clear_bit(CX18_F_I_RADIO_USER, &cx->i_flags); - /* Switch tuner to TV */ - cx18_call_i2c_clients(cx, VIDIOC_S_STD, &cx->std); - /* Select correct audio input (i.e. TV tuner or Line in) */ - cx18_audio_set_io(cx); - if (atomic_read(&cx->ana_capturing) > 0) { - /* Undo video mute */ - cx18_vapi(cx, CX18_CPU_SET_VIDEO_MUTE, 2, s->handle, - cx->params.video_mute | - (cx->params.video_mute_yuv << 8)); - } - /* Done! Unmute and continue. */ - cx18_unmute(cx); - cx18_release_stream(s); - } else { - cx18_stop_capture(id, 0); - } - kfree(id); - mutex_unlock(&cx->serialize_lock); - return 0; -} - -static int cx18_serialized_open(struct cx18_stream *s, struct file *filp) -{ - struct cx18 *cx = s->cx; - struct cx18_open_id *item; - - CX18_DEBUG_FILE("open %s\n", s->name); - - /* Allocate memory */ - item = kmalloc(sizeof(struct cx18_open_id), GFP_KERNEL); - if (NULL == item) { - CX18_DEBUG_WARN("nomem on v4l2 open\n"); - return -ENOMEM; - } - item->cx = cx; - item->type = s->type; - v4l2_prio_open(&cx->prio, &item->prio); - - item->open_id = cx->open_id++; - filp->private_data = item; - - if (item->type == CX18_ENC_STREAM_TYPE_RAD) { - /* Try to claim this stream */ - if (cx18_claim_stream(item, item->type)) { - /* No, it's already in use */ - kfree(item); - return -EBUSY; - } - - if (!test_bit(CX18_F_I_RADIO_USER, &cx->i_flags)) { - if (atomic_read(&cx->ana_capturing) > 0) { - /* switching to radio while capture is - in progress is not polite */ - cx18_release_stream(s); - kfree(item); - return -EBUSY; - } - } - - /* Mark that the radio is being used. */ - set_bit(CX18_F_I_RADIO_USER, &cx->i_flags); - /* We have the radio */ - cx18_mute(cx); - /* Switch tuner to radio */ - cx18_call_i2c_clients(cx, AUDC_SET_RADIO, NULL); - /* Select the correct audio input (i.e. radio tuner) */ - cx18_audio_set_io(cx); - /* Done! Unmute and continue. */ - cx18_unmute(cx); - } - return 0; -} - -int cx18_v4l2_open(struct file *filp) -{ - int res, x, y = 0; - struct cx18 *cx = NULL; - struct cx18_stream *s = NULL; - int minor = video_devdata(filp)->minor; - - /* Find which card this open was on */ - spin_lock(&cx18_cards_lock); - for (x = 0; cx == NULL && x < cx18_cards_active; x++) { - /* find out which stream this open was on */ - for (y = 0; y < CX18_MAX_STREAMS; y++) { - if (cx18_cards[x] == NULL) - continue; - s = &cx18_cards[x]->streams[y]; - if (s->v4l2dev && s->v4l2dev->minor == minor) { - cx = cx18_cards[x]; - break; - } - } - } - spin_unlock(&cx18_cards_lock); - - if (cx == NULL) { - /* Couldn't find a device registered - on that minor, shouldn't happen! */ - printk(KERN_WARNING "No cx18 device found on minor %d\n", - minor); - return -ENXIO; - } - - mutex_lock(&cx->serialize_lock); - if (cx18_init_on_first_open(cx)) { - CX18_ERR("Failed to initialize on minor %d\n", minor); - mutex_unlock(&cx->serialize_lock); - return -ENXIO; - } - res = cx18_serialized_open(s, filp); - mutex_unlock(&cx->serialize_lock); - return res; -} - -void cx18_mute(struct cx18 *cx) -{ - u32 h; - if (atomic_read(&cx->ana_capturing)) { - h = cx18_find_handle(cx); - if (h != CX18_INVALID_TASK_HANDLE) - cx18_vapi(cx, CX18_CPU_SET_AUDIO_MUTE, 2, h, 1); - else - CX18_ERR("Can't find valid task handle for mute\n"); - } - CX18_DEBUG_INFO("Mute\n"); -} - -void cx18_unmute(struct cx18 *cx) -{ - u32 h; - if (atomic_read(&cx->ana_capturing)) { - h = cx18_find_handle(cx); - if (h != CX18_INVALID_TASK_HANDLE) { - cx18_msleep_timeout(100, 0); - cx18_vapi(cx, CX18_CPU_SET_MISC_PARAMETERS, 2, h, 12); - cx18_vapi(cx, CX18_CPU_SET_AUDIO_MUTE, 2, h, 0); - } else - CX18_ERR("Can't find valid task handle for unmute\n"); - } - CX18_DEBUG_INFO("Unmute\n"); -} diff --git a/drivers/media/video/cx18/cx18-fileops.h b/drivers/media/video/cx18/cx18-fileops.h deleted file mode 100644 index 92e2d5dab93..00000000000 --- a/drivers/media/video/cx18/cx18-fileops.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * cx18 file operation functions - * - * Derived from ivtv-fileops.h - * - * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> - * - * 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., 59 Temple Place, Suite 330, Boston, MA - * 02111-1307 USA - */ - -/* Testing/Debugging */ -int cx18_v4l2_open(struct file *filp); -ssize_t cx18_v4l2_read(struct file *filp, char __user *buf, size_t count, - loff_t *pos); -ssize_t cx18_v4l2_write(struct file *filp, const char __user *buf, size_t count, - loff_t *pos); -int cx18_v4l2_close(struct file *filp); -unsigned int cx18_v4l2_enc_poll(struct file *filp, poll_table *wait); -int cx18_start_capture(struct cx18_open_id *id); -void cx18_stop_capture(struct cx18_open_id *id, int gop_end); -void cx18_mute(struct cx18 *cx); -void cx18_unmute(struct cx18 *cx); - diff --git a/drivers/media/video/cx18/cx18-firmware.c b/drivers/media/video/cx18/cx18-firmware.c deleted file mode 100644 index 1fa95da1575..00000000000 --- a/drivers/media/video/cx18/cx18-firmware.c +++ /dev/null @@ -1,466 +0,0 @@ -/* - * cx18 firmware functions - * - * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> - * Copyright (C) 2008 Andy Walls <awalls@radix.net> - * - * 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., 59 Temple Place, Suite 330, Boston, MA - * 02111-1307 USA - */ - -#include "cx18-driver.h" -#include "cx18-io.h" -#include "cx18-scb.h" -#include "cx18-irq.h" -#include "cx18-firmware.h" -#include "cx18-cards.h" -#include "cx18-av-core.h" -#include <linux/firmware.h> - -#define CX18_PROC_SOFT_RESET 0xc70010 -#define CX18_DDR_SOFT_RESET 0xc70014 -#define CX18_CLOCK_SELECT1 0xc71000 -#define CX18_CLOCK_SELECT2 0xc71004 -#define CX18_HALF_CLOCK_SELECT1 0xc71008 -#define CX18_HALF_CLOCK_SELECT2 0xc7100C -#define CX18_CLOCK_POLARITY1 0xc71010 -#define CX18_CLOCK_POLARITY2 0xc71014 -#define CX18_ADD_DELAY_ENABLE1 0xc71018 -#define CX18_ADD_DELAY_ENABLE2 0xc7101C -#define CX18_CLOCK_ENABLE1 0xc71020 -#define CX18_CLOCK_ENABLE2 0xc71024 - -#define CX18_REG_BUS_TIMEOUT_EN 0xc72024 - -#define CX18_FAST_CLOCK_PLL_INT 0xc78000 -#define CX18_FAST_CLOCK_PLL_FRAC 0xc78004 -#define CX18_FAST_CLOCK_PLL_POST 0xc78008 -#define CX18_FAST_CLOCK_PLL_PRESCALE 0xc7800C -#define CX18_FAST_CLOCK_PLL_ADJUST_BANDWIDTH 0xc78010 - -#define CX18_SLOW_CLOCK_PLL_INT 0xc78014 -#define CX18_SLOW_CLOCK_PLL_FRAC 0xc78018 -#define CX18_SLOW_CLOCK_PLL_POST 0xc7801C -#define CX18_MPEG_CLOCK_PLL_INT 0xc78040 -#define CX18_MPEG_CLOCK_PLL_FRAC 0xc78044 -#define CX18_MPEG_CLOCK_PLL_POST 0xc78048 -#define CX18_PLL_POWER_DOWN 0xc78088 -#define CX18_SW1_INT_STATUS 0xc73104 -#define CX18_SW1_INT_ENABLE_PCI 0xc7311C -#define CX18_SW2_INT_SET 0xc73140 -#define CX18_SW2_INT_STATUS 0xc73144 -#define CX18_ADEC_CONTROL 0xc78120 - -#define CX18_DDR_REQUEST_ENABLE 0xc80000 -#define CX18_DDR_CHIP_CONFIG 0xc80004 -#define CX18_DDR_REFRESH 0xc80008 -#define CX18_DDR_TIMING1 0xc8000C -#define CX18_DDR_TIMING2 0xc80010 -#define CX18_DDR_POWER_REG 0xc8001C - -#define CX18_DDR_TUNE_LANE 0xc80048 -#define CX18_DDR_INITIAL_EMRS 0xc80054 -#define CX18_DDR_MB_PER_ROW_7 0xc8009C -#define CX18_DDR_BASE_63_ADDR 0xc804FC - -#define CX18_WMB_CLIENT02 0xc90108 -#define CX18_WMB_CLIENT05 0xc90114 -#define CX18_WMB_CLIENT06 0xc90118 -#define CX18_WMB_CLIENT07 0xc9011C -#define CX18_WMB_CLIENT08 0xc90120 -#define CX18_WMB_CLIENT09 0xc90124 -#define CX18_WMB_CLIENT10 0xc90128 -#define CX18_WMB_CLIENT11 0xc9012C -#define CX18_WMB_CLIENT12 0xc90130 -#define CX18_WMB_CLIENT13 0xc90134 -#define CX18_WMB_CLIENT14 0xc90138 - -#define CX18_DSP0_INTERRUPT_MASK 0xd0004C - -#define APU_ROM_SYNC1 0x6D676553 /* "mgeS" */ -#define APU_ROM_SYNC2 0x72646548 /* "rdeH" */ - -struct cx18_apu_rom_seghdr { - u32 sync1; - u32 sync2; - u32 addr; - u32 size; -}; - -static int load_cpu_fw_direct(const char *fn, u8 __iomem *mem, struct cx18 *cx) -{ - const struct firmware *fw = NULL; - int i, j; - unsigned size; - u32 __iomem *dst = (u32 __iomem *)mem; - const u32 *src; - - if (request_firmware(&fw, fn, &cx->dev->dev)) { - CX18_ERR("Unable to open firmware %s\n", fn); - CX18_ERR("Did you put the firmware in the hotplug firmware directory?\n"); - return -ENOMEM; - } - - src = (const u32 *)fw->data; - - for (i = 0; i < fw->size; i += 4096) { - cx18_setup_page(cx, i); - for (j = i; j < fw->size && j < i + 4096; j += 4) { - /* no need for endianness conversion on the ppc */ - cx18_raw_writel(cx, *src, dst); - if (cx18_raw_readl(cx, dst) != *src) { - CX18_ERR("Mismatch at offset %x\n", i); - release_firmware(fw); - cx18_setup_page(cx, 0); - return -EIO; - } - dst++; - src++; - } - } - if (!test_bit(CX18_F_I_LOADED_FW, &cx->i_flags)) - CX18_INFO("loaded %s firmware (%zd bytes)\n", fn, fw->size); - size = fw->size; - release_firmware(fw); - cx18_setup_page(cx, SCB_OFFSET); - return size; -} - -static int load_apu_fw_direct(const char *fn, u8 __iomem *dst, struct cx18 *cx, - u32 *entry_addr) -{ - const struct firmware *fw = NULL; - int i, j; - unsigned size; - const u32 *src; - struct cx18_apu_rom_seghdr seghdr; - const u8 *vers; - u32 offset = 0; - u32 apu_version = 0; - int sz; - - if (request_firmware(&fw, fn, &cx->dev->dev)) { - CX18_ERR("unable to open firmware %s\n", fn); - CX18_ERR("did you put the firmware in the hotplug firmware directory?\n"); - cx18_setup_page(cx, 0); - return -ENOMEM; - } - - *entry_addr = 0; - src = (const u32 *)fw->data; - vers = fw->data + sizeof(seghdr); - sz = fw->size; - - apu_version = (vers[0] << 24) | (vers[4] << 16) | vers[32]; - while (offset + sizeof(seghdr) < fw->size) { - /* TODO: byteswapping */ - memcpy(&seghdr, src + offset / 4, sizeof(seghdr)); - offset += sizeof(seghdr); - if (seghdr.sync1 != APU_ROM_SYNC1 || - seghdr.sync2 != APU_ROM_SYNC2) { - offset += seghdr.size; - continue; - } - CX18_DEBUG_INFO("load segment %x-%x\n", seghdr.addr, - seghdr.addr + seghdr.size - 1); - if (*entry_addr == 0) - *entry_addr = seghdr.addr; - if (offset + seghdr.size > sz) - break; - for (i = 0; i < seghdr.size; i += 4096) { - cx18_setup_page(cx, seghdr.addr + i); - for (j = i; j < seghdr.size && j < i + 4096; j += 4) { - /* no need for endianness conversion on the ppc */ - cx18_raw_writel(cx, src[(offset + j) / 4], - dst + seghdr.addr + j); - if (cx18_raw_readl(cx, dst + seghdr.addr + j) - != src[(offset + j) / 4]) { - CX18_ERR("Mismatch at offset %x\n", - offset + j); - release_firmware(fw); - cx18_setup_page(cx, 0); - return -EIO; - } - } - } - offset += seghdr.size; - } - if (!test_bit(CX18_F_I_LOADED_FW, &cx->i_flags)) - CX18_INFO("loaded %s firmware V%08x (%zd bytes)\n", - fn, apu_version, fw->size); - size = fw->size; - release_firmware(fw); - cx18_setup_page(cx, 0); - return size; -} - -void cx18_halt_firmware(struct cx18 *cx) -{ - CX18_DEBUG_INFO("Preparing for firmware halt.\n"); - cx18_write_reg_expect(cx, 0x000F000F, CX18_PROC_SOFT_RESET, - 0x0000000F, 0x000F000F); - cx18_write_reg_expect(cx, 0x00020002, CX18_ADEC_CONTROL, - 0x00000002, 0x00020002); -} - -void cx18_init_power(struct cx18 *cx, int lowpwr) -{ - /* power-down Spare and AOM PLLs */ - /* power-up fast, slow and mpeg PLLs */ - cx18_write_reg(cx, 0x00000008, CX18_PLL_POWER_DOWN); - - /* ADEC out of sleep */ - cx18_write_reg_expect(cx, 0x00020000, CX18_ADEC_CONTROL, - 0x00000000, 0x00020002); - - /* - * The PLL parameters are based on the external crystal frequency that - * would ideally be: - * - * NTSC Color subcarrier freq * 8 = - * 4.5 MHz/286 * 455/2 * 8 = 28.63636363... MHz - * - * The accidents of history and rationale that explain from where this - * combination of magic numbers originate can be found in: - * - * [1] Abrahams, I. C., "Choice of Chrominance Subcarrier Frequency in - * the NTSC Standards", Proceedings of the I-R-E, January 1954, pp 79-80 - * - * [2] Abrahams, I. C., "The 'Frequency Interleaving' Principle in the - * NTSC Standards", Proceedings of the I-R-E, January 1954, pp 81-83 - * - * As Mike Bradley has rightly pointed out, it's not the exact crystal - * frequency that matters, only that all parts of the driver and - * firmware are using the same value (close to the ideal value). - * - * Since I have a strong suspicion that, if the firmware ever assumes a - * crystal value at all, it will assume 28.636360 MHz, the crystal - * freq used in calculations in this driver will be: - * - * xtal_freq = 28.636360 MHz - * - * an error of less than 0.13 ppm which is way, way better than any off - * the shelf crystal will have for accuracy anyway. - * - * Below I aim to run the PLLs' VCOs near 400 MHz to minimze errors. - * - * Many thanks to Jeff Campbell and Mike Bradley for their extensive - * investigation, experimentation, testing, and suggested solutions of - * of audio/video sync problems with SVideo and CVBS captures. - */ - - /* the fast clock is at 200/245 MHz */ - /* 1 * xtal_freq * 0x0d.f7df9b8 / 2 = 200 MHz: 400 MHz pre post-divide*/ - /* 1 * xtal_freq * 0x11.1c71eb8 / 2 = 245 MHz: 490 MHz pre post-divide*/ - cx18_write_reg(cx, lowpwr ? 0xD : 0x11, CX18_FAST_CLOCK_PLL_INT); - cx18_write_reg(cx, lowpwr ? 0x1EFBF37 : 0x038E3D7, - CX18_FAST_CLOCK_PLL_FRAC); - - cx18_write_reg(cx, 2, CX18_FAST_CLOCK_PLL_POST); - cx18_write_reg(cx, 1, CX18_FAST_CLOCK_PLL_PRESCALE); - cx18_write_reg(cx, 4, CX18_FAST_CLOCK_PLL_ADJUST_BANDWIDTH); - - /* set slow clock to 125/120 MHz */ - /* xtal_freq * 0x0d.1861a20 / 3 = 125 MHz: 375 MHz before post-divide */ - /* xtal_freq * 0x0c.92493f8 / 3 = 120 MHz: 360 MHz before post-divide */ - cx18_write_reg(cx, lowpwr ? 0xD : 0xC, CX18_SLOW_CLOCK_PLL_INT); - cx18_write_reg(cx, lowpwr ? 0x30C344 : 0x124927F, - CX18_SLOW_CLOCK_PLL_FRAC); - cx18_write_reg(cx, 3, CX18_SLOW_CLOCK_PLL_POST); - - /* mpeg clock pll 54MHz */ - /* xtal_freq * 0xf.15f17f0 / 8 = 54 MHz: 432 MHz before post-divide */ - cx18_write_reg(cx, 0xF, CX18_MPEG_CLOCK_PLL_INT); - cx18_write_reg(cx, 0x2BE2FE, CX18_MPEG_CLOCK_PLL_FRAC); - cx18_write_reg(cx, 8, CX18_MPEG_CLOCK_PLL_POST); - - /* - * VDCLK Integer = 0x0f, Post Divider = 0x04 - * AIMCLK Integer = 0x0e, Post Divider = 0x16 - */ - cx18_av_write4(cx, CXADEC_PLL_CTRL1, 0x160e040f); - - /* VDCLK Fraction = 0x2be2fe */ - /* xtal * 0xf.15f17f0/4 = 108 MHz: 432 MHz before post divide */ - cx18_av_write4(cx, CXADEC_VID_PLL_FRAC, 0x002be2fe); - - /* AIMCLK Fraction = 0x05227ad */ - /* xtal * 0xe.2913d68/0x16 = 48000 * 384: 406 MHz before post-divide */ - cx18_av_write4(cx, CXADEC_AUX_PLL_FRAC, 0x005227ad); - - /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x16 */ - cx18_av_write(cx, CXADEC_I2S_MCLK, 0x56); - - /* Defaults */ - /* APU = SC or SC/2 = 125/62.5 */ - /* EPU = SC = 125 */ - /* DDR = FC = 180 */ - /* ENC = SC = 125 */ - /* AI1 = SC = 125 */ - /* VIM2 = disabled */ - /* PCI = FC/2 = 90 */ - /* AI2 = disabled */ - /* DEMUX = disabled */ - /* AO = SC/2 = 62.5 */ - /* SER = 54MHz */ - /* VFC = disabled */ - /* USB = disabled */ - - if (lowpwr) { - cx18_write_reg_expect(cx, 0xFFFF0020, CX18_CLOCK_SELECT1, - 0x00000020, 0xFFFFFFFF); - cx18_write_reg_expect(cx, 0xFFFF0004, CX18_CLOCK_SELECT2, - 0x00000004, 0xFFFFFFFF); - } else { - /* This doesn't explicitly set every clock select */ - cx18_write_reg_expect(cx, 0x00060004, CX18_CLOCK_SELECT1, - 0x00000004, 0x00060006); - cx18_write_reg_expect(cx, 0x00060006, CX18_CLOCK_SELECT2, - 0x00000006, 0x00060006); - } - - cx18_write_reg_expect(cx, 0xFFFF0002, CX18_HALF_CLOCK_SELECT1, - 0x00000002, 0xFFFFFFFF); - cx18_write_reg_expect(cx, 0xFFFF0104, CX18_HALF_CLOCK_SELECT2, - 0x00000104, 0xFFFFFFFF); - cx18_write_reg_expect(cx, 0xFFFF9026, CX18_CLOCK_ENABLE1, - 0x00009026, 0xFFFFFFFF); - cx18_write_reg_expect(cx, 0xFFFF3105, CX18_CLOCK_ENABLE2, - 0x00003105, 0xFFFFFFFF); -} - -void cx18_init_memory(struct cx18 *cx) -{ - cx18_msleep_timeout(10, 0); - cx18_write_reg_expect(cx, 0x00010000, CX18_DDR_SOFT_RESET, - 0x00000000, 0x00010001); - cx18_msleep_timeout(10, 0); - - cx18_write_reg(cx, cx->card->ddr.chip_config, CX18_DDR_CHIP_CONFIG); - - cx18_msleep_timeout(10, 0); - - cx18_write_reg(cx, cx->card->ddr.refresh, CX18_DDR_REFRESH); - cx18_write_reg(cx, cx->card->ddr.timing1, CX18_DDR_TIMING1); - cx18_write_reg(cx, cx->card->ddr.timing2, CX18_DDR_TIMING2); - - cx18_msleep_timeout(10, 0); - - /* Initialize DQS pad time */ - cx18_write_reg(cx, cx->card->ddr.tune_lane, CX18_DDR_TUNE_LANE); - cx18_write_reg(cx, cx->card->ddr.initial_emrs, CX18_DDR_INITIAL_EMRS); - - cx18_msleep_timeout(10, 0); - - cx18_write_reg_expect(cx, 0x00020000, CX18_DDR_SOFT_RESET, - 0x00000000, 0x00020002); - cx18_msleep_timeout(10, 0); - - /* use power-down mode when idle */ - cx18_write_reg(cx, 0x00000010, CX18_DDR_POWER_REG); - - cx18_write_reg_expect(cx, 0x00010001, CX18_REG_BUS_TIMEOUT_EN, - 0x00000001, 0x00010001); - - cx18_write_reg(cx, 0x48, CX18_DDR_MB_PER_ROW_7); - cx18_write_reg(cx, 0xE0000, CX18_DDR_BASE_63_ADDR); - - cx18_write_reg(cx, 0x00000101, CX18_WMB_CLIENT02); /* AO */ - cx18_write_reg(cx, 0x00000101, CX18_WMB_CLIENT09); /* AI2 */ - cx18_write_reg(cx, 0x00000101, CX18_WMB_CLIENT05); /* VIM1 */ - cx18_write_reg(cx, 0x00000101, CX18_WMB_CLIENT06); /* AI1 */ - cx18_write_reg(cx, 0x00000101, CX18_WMB_CLIENT07); /* 3D comb */ - cx18_write_reg(cx, 0x00000101, CX18_WMB_CLIENT10); /* ME */ - cx18_write_reg(cx, 0x00000101, CX18_WMB_CLIENT12); /* ENC */ - cx18_write_reg(cx, 0x00000101, CX18_WMB_CLIENT13); /* PK */ - cx18_write_reg(cx, 0x00000101, CX18_WMB_CLIENT11); /* RC */ - cx18_write_reg(cx, 0x00000101, CX18_WMB_CLIENT14); /* AVO */ -} - -int cx18_firmware_init(struct cx18 *cx) -{ - u32 fw_entry_addr; - int sz, retries; - u32 api_args[MAX_MB_ARGUMENTS]; - - /* Allow chip to control CLKRUN */ - cx18_write_reg(cx, 0x5, CX18_DSP0_INTERRUPT_MASK); - - /* Stop the firmware */ - cx18_write_reg_expect(cx, 0x000F000F, CX18_PROC_SOFT_RESET, - 0x0000000F, 0x000F000F); - - cx18_msleep_timeout(1, 0); - - /* If the CPU is still running */ - if ((cx18_read_reg(cx, CX18_PROC_SOFT_RESET) & 8) == 0) { - CX18_ERR("%s: couldn't stop CPU to load firmware\n", __func__); - return -EIO; - } - - cx18_sw1_irq_enable(cx, IRQ_CPU_TO_EPU | IRQ_APU_TO_EPU); - cx18_sw2_irq_enable(cx, IRQ_CPU_TO_EPU_ACK | IRQ_APU_TO_EPU_ACK); - - sz = load_cpu_fw_direct("v4l-cx23418-cpu.fw", cx->enc_mem, cx); - if (sz <= 0) - return sz; - - /* The SCB & IPC area *must* be correct before starting the firmwares */ - cx18_init_scb(cx); - - fw_entry_addr = 0; - sz = load_apu_fw_direct("v4l-cx23418-apu.fw", cx->enc_mem, cx, - &fw_entry_addr); - if (sz <= 0) - return sz; - - /* Start the CPU. The CPU will take care of the APU for us. */ - cx18_write_reg_expect(cx, 0x00080000, CX18_PROC_SOFT_RESET, - 0x00000000, 0x00080008); - - /* Wait up to 500 ms for the APU to come out of reset */ - for (retries = 0; - retries < 50 && (cx18_read_reg(cx, CX18_PROC_SOFT_RESET) & 1) == 1; - retries++) - cx18_msleep_timeout(10, 0); - - cx18_msleep_timeout(200, 0); - - if (retries == 50 && - (cx18_read_reg(cx, CX18_PROC_SOFT_RESET) & 1) == 1) { - CX18_ERR("Could not start the CPU\n"); - return -EIO; - } - - /* - * The CPU had once before set up to receive an interrupt for it's - * outgoing IRQ_CPU_TO_EPU_ACK to us. If it ever does this, we get an - * interrupt when it sends us an ack, but by the time we process it, - * that flag in the SW2 status register has been cleared by the CPU - * firmware. We'll prevent that not so useful condition from happening - * by clearing the CPU's interrupt enables for Ack IRQ's we want to - * process. - */ - cx18_sw2_irq_disable_cpu(cx, IRQ_CPU_TO_EPU_ACK | IRQ_APU_TO_EPU_ACK); - - /* Try a benign command to see if the CPU is alive and well */ - sz = cx18_vapi_result(cx, api_args, CX18_CPU_DEBUG_PEEK32, 1, 0); - if (sz < 0) - return sz; - - /* initialize GPIO */ - cx18_write_reg_expect(cx, 0x14001400, 0xc78110, 0x00001400, 0x14001400); - return 0; -} diff --git a/drivers/media/video/cx18/cx18-firmware.h b/drivers/media/video/cx18/cx18-firmware.h deleted file mode 100644 index 38d4c05e849..00000000000 --- a/drivers/media/video/cx18/cx18-firmware.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * cx18 firmware functions - * - * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> - * - * 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., 59 Temple Place, Suite 330, Boston, MA - * 02111-1307 USA - */ - -int cx18_firmware_init(struct cx18 *cx); -void cx18_halt_firmware(struct cx18 *cx); -void cx18_init_memory(struct cx18 *cx); -void cx18_init_power(struct cx18 *cx, int lowpwr); diff --git a/drivers/media/video/cx18/cx18-gpio.c b/drivers/media/video/cx18/cx18-gpio.c deleted file mode 100644 index 1a99329f33c..00000000000 --- a/drivers/media/video/cx18/cx18-gpio.c +++ /dev/null @@ -1,218 +0,0 @@ -/* - * cx18 gpio functions - * - * Derived from ivtv-gpio.c - * - * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> - * Copyright (C) 2008 Andy Walls <awalls@radix.net> - * - * 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., 59 Temple Place, Suite 330, Boston, MA - * 02111-1307 USA - */ - -#include "cx18-driver.h" -#include "cx18-io.h" -#include "cx18-cards.h" -#include "cx18-gpio.h" -#include "tuner-xc2028.h" - -/********************* GPIO stuffs *********************/ - -/* GPIO registers */ -#define CX18_REG_GPIO_IN 0xc72010 -#define CX18_REG_GPIO_OUT1 0xc78100 -#define CX18_REG_GPIO_DIR1 0xc78108 -#define CX18_REG_GPIO_OUT2 0xc78104 -#define CX18_REG_GPIO_DIR2 0xc7810c - -/* - * HVR-1600 GPIO pins, courtesy of Hauppauge: - * - * gpio0: zilog ir process reset pin - * gpio1: zilog programming pin (you should never use this) - * gpio12: cx24227 reset pin - * gpio13: cs5345 reset pin -*/ - -static void gpio_write(struct cx18 *cx) -{ - u32 dir_lo = cx->gpio_dir & 0xffff; - u32 val_lo = cx->gpio_val & 0xffff; - u32 dir_hi = cx->gpio_dir >> 16; - u32 val_hi = cx->gpio_val >> 16; - - cx18_write_reg_expect(cx, dir_lo << 16, - CX18_REG_GPIO_DIR1, ~dir_lo, dir_lo); - cx18_write_reg_expect(cx, (dir_lo << 16) | val_lo, - CX18_REG_GPIO_OUT1, val_lo, dir_lo); - cx18_write_reg_expect(cx, dir_hi << 16, - CX18_REG_GPIO_DIR2, ~dir_hi, dir_hi); - cx18_write_reg_expect(cx, (dir_hi << 16) | val_hi, - CX18_REG_GPIO_OUT2, val_hi, dir_hi); -} - -void cx18_reset_i2c_slaves_gpio(struct cx18 *cx) -{ - const struct cx18_gpio_i2c_slave_reset *p; - - p = &cx->card->gpio_i2c_slave_reset; - - if ((p->active_lo_mask | p->active_hi_mask) == 0) - return; - - /* Assuming that the masks are a subset of the bits in gpio_dir */ - - /* Assert */ - mutex_lock(&cx->gpio_lock); - cx->gpio_val = - (cx->gpio_val | p->active_hi_mask) & ~(p->active_lo_mask); - gpio_write(cx); - schedule_timeout_uninterruptible(msecs_to_jiffies(p->msecs_asserted)); - - /* Deassert */ - cx->gpio_val = - (cx->gpio_val | p->active_lo_mask) & ~(p->active_hi_mask); - gpio_write(cx); - schedule_timeout_uninterruptible(msecs_to_jiffies(p->msecs_recovery)); - mutex_unlock(&cx->gpio_lock); -} - -void cx18_reset_ir_gpio(void *data) -{ - struct cx18 *cx = ((struct cx18_i2c_algo_callback_data *)data)->cx; - const struct cx18_gpio_i2c_slave_reset *p; - - p = &cx->card->gpio_i2c_slave_reset; - - if (p->ir_reset_mask == 0) - return; - - CX18_DEBUG_INFO("Resetting IR microcontroller\n"); - - /* - Assert timing for the Z8F0811 on HVR-1600 boards: - 1. Assert RESET for min of 4 clock cycles at 18.432 MHz to initiate - 2. Reset then takes 66 WDT cycles at 10 kHz + 16 xtal clock cycles - (6,601,085 nanoseconds ~= 7 milliseconds) - 3. DBG pin must be high before chip exits reset for normal operation. - DBG is open drain and hopefully pulled high since we don't - normally drive it (GPIO 1?) for the HVR-1600 - 4. Z8F0811 won't exit reset until RESET is deasserted - */ - mutex_lock(&cx->gpio_lock); - cx->gpio_val = cx->gpio_val & ~p->ir_reset_mask; - gpio_write(cx); - mutex_unlock(&cx->gpio_lock); - schedule_timeout_uninterruptible(msecs_to_jiffies(p->msecs_asserted)); - - /* - Zilog comes out of reset, loads reset vector address and executes - from there. Required recovery delay unknown. - */ - mutex_lock(&cx->gpio_lock); - cx->gpio_val = cx->gpio_val | p->ir_reset_mask; - gpio_write(cx); - mutex_unlock(&cx->gpio_lock); - schedule_timeout_uninterruptible(msecs_to_jiffies(p->msecs_recovery)); -} -EXPORT_SYMBOL(cx18_reset_ir_gpio); -/* This symbol is exported for use by an infrared module for the IR-blaster */ - -void cx18_gpio_init(struct cx18 *cx) -{ - mutex_lock(&cx->gpio_lock); - cx->gpio_dir = cx->card->gpio_init.direction; - cx->gpio_val = cx->card->gpio_init.initial_value; - - if (cx->card->tuners[0].tuner == TUNER_XC2028) { - cx->gpio_dir |= 1 << cx->card->xceive_pin; - cx->gpio_val |= 1 << cx->card->xceive_pin; - } - - if (cx->gpio_dir == 0) { - mutex_unlock(&cx->gpio_lock); - return; - } - - CX18_DEBUG_INFO("GPIO initial dir: %08x/%08x out: %08x/%08x\n", - cx18_read_reg(cx, CX18_REG_GPIO_DIR1), - cx18_read_reg(cx, CX18_REG_GPIO_DIR2), - cx18_read_reg(cx, CX18_REG_GPIO_OUT1), - cx18_read_reg(cx, CX18_REG_GPIO_OUT2)); - - gpio_write(cx); - mutex_unlock(&cx->gpio_lock); -} - -/* Xceive tuner reset function */ -int cx18_reset_tuner_gpio(void *dev, int component, int cmd, int value) -{ - struct i2c_algo_bit_data *algo = dev; - struct cx18_i2c_algo_callback_data *cb_data = algo->data; - struct cx18 *cx = cb_data->cx; - - if (cmd != XC2028_TUNER_RESET) - return 0; - CX18_DEBUG_INFO("Resetting tuner\n"); - - mutex_lock(&cx->gpio_lock); - cx->gpio_val &= ~(1 << cx->card->xceive_pin); - gpio_write(cx); - mutex_unlock(&cx->gpio_lock); - schedule_timeout_interruptible(msecs_to_jiffies(1)); - - mutex_lock(&cx->gpio_lock); - cx->gpio_val |= 1 << cx->card->xceive_pin; - gpio_write(cx); - mutex_unlock(&cx->gpio_lock); - schedule_timeout_interruptible(msecs_to_jiffies(1)); - return 0; -} - -int cx18_gpio(struct cx18 *cx, unsigned int command, void *arg) -{ - struct v4l2_routing *route = arg; - u32 mask, data; - - switch (command) { - case VIDIOC_INT_S_AUDIO_ROUTING: - if (route->input > 2) - return -EINVAL; - mask = cx->card->gpio_audio_input.mask; - switch (route->input) { - case 0: - data = cx->card->gpio_audio_input.tuner; - break; - case 1: - data = cx->card->gpio_audio_input.linein; - break; - case 2: - default: - data = cx->card->gpio_audio_input.radio; - break; - } - break; - - default: - return -EINVAL; - } - if (mask) { - mutex_lock(&cx->gpio_lock); - cx->gpio_val = (cx->gpio_val & ~mask) | (data & mask); - gpio_write(cx); - mutex_unlock(&cx->gpio_lock); - } - return 0; -} diff --git a/drivers/media/video/cx18/cx18-gpio.h b/drivers/media/video/cx18/cx18-gpio.h deleted file mode 100644 index 39ffccc19d8..00000000000 --- a/drivers/media/video/cx18/cx18-gpio.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * cx18 gpio functions - * - * Derived from ivtv-gpio.h - * - * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> - * Copyright (C) 2008 Andy Walls <awalls@radix.net> - * - * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -void cx18_gpio_init(struct cx18 *cx); -void cx18_reset_i2c_slaves_gpio(struct cx18 *cx); -void cx18_reset_ir_gpio(void *data); -int cx18_reset_tuner_gpio(void *dev, int component, int cmd, int value); -int cx18_gpio(struct cx18 *cx, unsigned int command, void *arg); diff --git a/drivers/media/video/cx18/cx18-i2c.c b/drivers/media/video/cx18/cx18-i2c.c deleted file mode 100644 index 83e1c633312..00000000000 --- a/drivers/media/video/cx18/cx18-i2c.c +++ /dev/null @@ -1,432 +0,0 @@ -/* - * cx18 I2C functions - * - * Derived from ivtv-i2c.c - * - * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> - * Copyright (C) 2008 Andy Walls <awalls@radix.net> - * - * 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., 59 Temple Place, Suite 330, Boston, MA - * 02111-1307 USA - */ - -#include "cx18-driver.h" -#include "cx18-io.h" -#include "cx18-cards.h" -#include "cx18-gpio.h" -#include "cx18-av-core.h" -#include "cx18-i2c.h" -#include "cx18-irq.h" - -#define CX18_REG_I2C_1_WR 0xf15000 -#define CX18_REG_I2C_1_RD 0xf15008 -#define CX18_REG_I2C_2_WR 0xf25100 -#define CX18_REG_I2C_2_RD 0xf25108 - -#define SETSCL_BIT 0x0001 -#define SETSDL_BIT 0x0002 -#define GETSCL_BIT 0x0004 -#define GETSDL_BIT 0x0008 - -#define CX18_CS5345_I2C_ADDR 0x4c - -/* This array should match the CX18_HW_ defines */ -static const u8 hw_driverids[] = { - I2C_DRIVERID_TUNER, - I2C_DRIVERID_TVEEPROM, - I2C_DRIVERID_CS5345, - 0, /* CX18_HW_GPIO dummy driver ID */ - 0 /* CX18_HW_CX23418 dummy driver ID */ -}; - -/* This array should match the CX18_HW_ defines */ -static const u8 hw_addrs[] = { - 0, - 0, - CX18_CS5345_I2C_ADDR, - 0, /* CX18_HW_GPIO dummy driver ID */ - 0, /* CX18_HW_CX23418 dummy driver ID */ -}; - -/* This array should match the CX18_HW_ defines */ -/* This might well become a card-specific array */ -static const u8 hw_bus[] = { - 0, - 0, - 0, - 0, /* CX18_HW_GPIO dummy driver ID */ - 0, /* CX18_HW_CX23418 dummy driver ID */ -}; - -/* This array should match the CX18_HW_ defines */ -static const char * const hw_devicenames[] = { - "tuner", - "tveeprom", - "cs5345", - "gpio", - "cx23418", -}; - -int cx18_i2c_register(struct cx18 *cx, unsigned idx) -{ - struct i2c_board_info info; - struct i2c_client *c; - u8 id, bus; - int i; - - CX18_DEBUG_I2C("i2c client register\n"); - if (idx >= ARRAY_SIZE(hw_driverids) || hw_driverids[idx] == 0) - return -1; - id = hw_driverids[idx]; - bus = hw_bus[idx]; - memset(&info, 0, sizeof(info)); - strlcpy(info.type, hw_devicenames[idx], sizeof(info.type)); - info.addr = hw_addrs[idx]; - for (i = 0; i < I2C_CLIENTS_MAX; i++) - if (cx->i2c_clients[i] == NULL) - break; - - if (i == I2C_CLIENTS_MAX) { - CX18_ERR("insufficient room for new I2C client!\n"); - return -ENOMEM; - } - - if (id != I2C_DRIVERID_TUNER) { - c = i2c_new_device(&cx->i2c_adap[bus], &info); - if (c->driver == NULL) - i2c_unregister_device(c); - else - cx->i2c_clients[i] = c; - return cx->i2c_clients[i] ? 0 : -ENODEV; - } - - /* special tuner handling */ - c = i2c_new_probed_device(&cx->i2c_adap[1], &info, cx->card_i2c->radio); - if (c && c->driver == NULL) - i2c_unregister_device(c); - else if (c) - cx->i2c_clients[i++] = c; - c = i2c_new_probed_device(&cx->i2c_adap[1], &info, cx->card_i2c->demod); - if (c && c->driver == NULL) - i2c_unregister_device(c); - else if (c) - cx->i2c_clients[i++] = c; - c = i2c_new_probed_device(&cx->i2c_adap[1], &info, cx->card_i2c->tv); - if (c && c->driver == NULL) - i2c_unregister_device(c); - else if (c) - cx->i2c_clients[i++] = c; - return 0; -} - -static int attach_inform(struct i2c_client *client) -{ - return 0; -} - -static int detach_inform(struct i2c_client *client) -{ - int i; - struct cx18 *cx = (struct cx18 *)i2c_get_adapdata(client->adapter); - - CX18_DEBUG_I2C("i2c client detach\n"); - for (i = 0; i < I2C_CLIENTS_MAX; i++) { - if (cx->i2c_clients[i] == client) { - cx->i2c_clients[i] = NULL; - break; - } - } - CX18_DEBUG_I2C("i2c detach [client=%s,%s]\n", - client->name, (i < I2C_CLIENTS_MAX) ? "ok" : "failed"); - - return 0; -} - -static void cx18_setscl(void *data, int state) -{ - struct cx18 *cx = ((struct cx18_i2c_algo_callback_data *)data)->cx; - int bus_index = ((struct cx18_i2c_algo_callback_data *)data)->bus_index; - u32 addr = bus_index ? CX18_REG_I2C_2_WR : CX18_REG_I2C_1_WR; - u32 r = cx18_read_reg(cx, addr); - - if (state) - cx18_write_reg(cx, r | SETSCL_BIT, addr); - else - cx18_write_reg(cx, r & ~SETSCL_BIT, addr); -} - -static void cx18_setsda(void *data, int state) -{ - struct cx18 *cx = ((struct cx18_i2c_algo_callback_data *)data)->cx; - int bus_index = ((struct cx18_i2c_algo_callback_data *)data)->bus_index; - u32 addr = bus_index ? CX18_REG_I2C_2_WR : CX18_REG_I2C_1_WR; - u32 r = cx18_read_reg(cx, addr); - - if (state) - cx18_write_reg(cx, r | SETSDL_BIT, addr); - else - cx18_write_reg(cx, r & ~SETSDL_BIT, addr); -} - -static int cx18_getscl(void *data) -{ - struct cx18 *cx = ((struct cx18_i2c_algo_callback_data *)data)->cx; - int bus_index = ((struct cx18_i2c_algo_callback_data *)data)->bus_index; - u32 addr = bus_index ? CX18_REG_I2C_2_RD : CX18_REG_I2C_1_RD; - - return cx18_read_reg(cx, addr) & GETSCL_BIT; -} - -static int cx18_getsda(void *data) -{ - struct cx18 *cx = ((struct cx18_i2c_algo_callback_data *)data)->cx; - int bus_index = ((struct cx18_i2c_algo_callback_data *)data)->bus_index; - u32 addr = bus_index ? CX18_REG_I2C_2_RD : CX18_REG_I2C_1_RD; - - return cx18_read_reg(cx, addr) & GETSDL_BIT; -} - -/* template for i2c-bit-algo */ -static struct i2c_adapter cx18_i2c_adap_template = { - .name = "cx18 i2c driver", - .id = I2C_HW_B_CX2341X, - .algo = NULL, /* set by i2c-algo-bit */ - .algo_data = NULL, /* filled from template */ - .client_register = attach_inform, - .client_unregister = detach_inform, - .owner = THIS_MODULE, -}; - -#define CX18_SCL_PERIOD (10) /* usecs. 10 usec is period for a 100 KHz clock */ -#define CX18_ALGO_BIT_TIMEOUT (2) /* seconds */ - -static struct i2c_algo_bit_data cx18_i2c_algo_template = { - .setsda = cx18_setsda, - .setscl = cx18_setscl, - .getsda = cx18_getsda, - .getscl = cx18_getscl, - .udelay = CX18_SCL_PERIOD/2, /* 1/2 clock period in usec*/ - .timeout = CX18_ALGO_BIT_TIMEOUT*HZ /* jiffies */ -}; - -static struct i2c_client cx18_i2c_client_template = { - .name = "cx18 internal", -}; - -int cx18_call_i2c_client(struct cx18 *cx, int addr, unsigned cmd, void *arg) -{ - struct i2c_client *client; - int retval; - int i; - - CX18_DEBUG_I2C("call_i2c_client addr=%02x\n", addr); - for (i = 0; i < I2C_CLIENTS_MAX; i++) { - client = cx->i2c_clients[i]; - if (client == NULL || client->driver == NULL || - client->driver->command == NULL) - continue; - if (addr == client->addr) { - retval = client->driver->command(client, cmd, arg); - return retval; - } - } - if (cmd != VIDIOC_DBG_G_CHIP_IDENT) - CX18_ERR("i2c addr 0x%02x not found for cmd 0x%x!\n", - addr, cmd); - return -ENODEV; -} - -/* Find the i2c device based on the driver ID and return - its i2c address or -ENODEV if no matching device was found. */ -static int cx18_i2c_id_addr(struct cx18 *cx, u32 id) -{ - struct i2c_client *client; - int retval = -ENODEV; - int i; - - for (i = 0; i < I2C_CLIENTS_MAX; i++) { - client = cx->i2c_clients[i]; - if (client == NULL || client->driver == NULL) - continue; - if (id == client->driver->id) { - retval = client->addr; - break; - } - } - return retval; -} - -/* Find the i2c device name matching the CX18_HW_ flag */ -static const char *cx18_i2c_hw_name(u32 hw) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(hw_driverids); i++) - if (1 << i == hw) - return hw_devicenames[i]; - return "unknown device"; -} - -/* Find the i2c device matching the CX18_HW_ flag and return - its i2c address or -ENODEV if no matching device was found. */ -int cx18_i2c_hw_addr(struct cx18 *cx, u32 hw) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(hw_driverids); i++) - if (1 << i == hw) - return cx18_i2c_id_addr(cx, hw_driverids[i]); - return -ENODEV; -} - -/* Calls i2c device based on CX18_HW_ flag. If hw == 0, then do nothing. - If hw == CX18_HW_GPIO then call the gpio handler. */ -int cx18_i2c_hw(struct cx18 *cx, u32 hw, unsigned int cmd, void *arg) -{ - int addr; - - if (hw == 0) - return 0; - - if (hw == CX18_HW_GPIO) - return cx18_gpio(cx, cmd, arg); - - if (hw == CX18_HW_CX23418) - return cx18_av_cmd(cx, cmd, arg); - - addr = cx18_i2c_hw_addr(cx, hw); - if (addr < 0) { - CX18_ERR("i2c hardware 0x%08x (%s) not found for cmd 0x%x!\n", - hw, cx18_i2c_hw_name(hw), cmd); - return addr; - } - return cx18_call_i2c_client(cx, addr, cmd, arg); -} - -/* broadcast cmd for all I2C clients and for the gpio subsystem */ -void cx18_call_i2c_clients(struct cx18 *cx, unsigned int cmd, void *arg) -{ - if (cx->i2c_adap[0].algo == NULL || cx->i2c_adap[1].algo == NULL) { - CX18_ERR("adapter is not set\n"); - return; - } - cx18_av_cmd(cx, cmd, arg); - i2c_clients_command(&cx->i2c_adap[0], cmd, arg); - i2c_clients_command(&cx->i2c_adap[1], cmd, arg); - if (cx->hw_flags & CX18_HW_GPIO) - cx18_gpio(cx, cmd, arg); -} - -/* init + register i2c algo-bit adapter */ -int init_cx18_i2c(struct cx18 *cx) -{ - int i; - CX18_DEBUG_I2C("i2c init\n"); - - /* Sanity checks for the I2C hardware arrays. They must be the - * same size and GPIO/CX23418 must be the last entries. - */ - if (ARRAY_SIZE(hw_driverids) != ARRAY_SIZE(hw_addrs) || - ARRAY_SIZE(hw_devicenames) != ARRAY_SIZE(hw_addrs) || - CX18_HW_GPIO != (1 << (ARRAY_SIZE(hw_addrs) - 2)) || - CX18_HW_CX23418 != (1 << (ARRAY_SIZE(hw_addrs) - 1)) || - hw_driverids[ARRAY_SIZE(hw_addrs) - 1]) { - CX18_ERR("Mismatched I2C hardware arrays\n"); - return -ENODEV; - } - - for (i = 0; i < 2; i++) { - memcpy(&cx->i2c_adap[i], &cx18_i2c_adap_template, - sizeof(struct i2c_adapter)); - memcpy(&cx->i2c_algo[i], &cx18_i2c_algo_template, - sizeof(struct i2c_algo_bit_data)); - cx->i2c_algo_cb_data[i].cx = cx; - cx->i2c_algo_cb_data[i].bus_index = i; - cx->i2c_algo[i].data = &cx->i2c_algo_cb_data[i]; - cx->i2c_adap[i].algo_data = &cx->i2c_algo[i]; - - sprintf(cx->i2c_adap[i].name + strlen(cx->i2c_adap[i].name), - " #%d-%d", cx->num, i); - i2c_set_adapdata(&cx->i2c_adap[i], cx); - - memcpy(&cx->i2c_client[i], &cx18_i2c_client_template, - sizeof(struct i2c_client)); - sprintf(cx->i2c_client[i].name + - strlen(cx->i2c_client[i].name), "%d", i); - cx->i2c_client[i].adapter = &cx->i2c_adap[i]; - cx->i2c_adap[i].dev.parent = &cx->dev->dev; - } - - if (cx18_read_reg(cx, CX18_REG_I2C_2_WR) != 0x0003c02f) { - /* Reset/Unreset I2C hardware block */ - /* Clock select 220MHz */ - cx18_write_reg_expect(cx, 0x10000000, 0xc71004, - 0x00000000, 0x10001000); - /* Clock Enable */ - cx18_write_reg_expect(cx, 0x10001000, 0xc71024, - 0x00001000, 0x10001000); - } - /* courtesy of Steven Toth <stoth@hauppauge.com> */ - cx18_write_reg_expect(cx, 0x00c00000, 0xc7001c, 0x00000000, 0x00c000c0); - mdelay(10); - cx18_write_reg_expect(cx, 0x00c000c0, 0xc7001c, 0x000000c0, 0x00c000c0); - mdelay(10); - cx18_write_reg_expect(cx, 0x00c00000, 0xc7001c, 0x00000000, 0x00c000c0); - mdelay(10); - - /* Set to edge-triggered intrs. */ - cx18_write_reg(cx, 0x00c00000, 0xc730c8); - /* Clear any stale intrs */ - cx18_write_reg_expect(cx, HW2_I2C1_INT|HW2_I2C2_INT, HW2_INT_CLR_STATUS, - ~(HW2_I2C1_INT|HW2_I2C2_INT), HW2_I2C1_INT|HW2_I2C2_INT); - - /* Hw I2C1 Clock Freq ~100kHz */ - cx18_write_reg(cx, 0x00021c0f & ~4, CX18_REG_I2C_1_WR); - cx18_setscl(&cx->i2c_algo_cb_data[0], 1); - cx18_setsda(&cx->i2c_algo_cb_data[0], 1); - - /* Hw I2C2 Clock Freq ~100kHz */ - cx18_write_reg(cx, 0x00021c0f & ~4, CX18_REG_I2C_2_WR); - cx18_setscl(&cx->i2c_algo_cb_data[1], 1); - cx18_setsda(&cx->i2c_algo_cb_data[1], 1); - - cx18_reset_i2c_slaves_gpio(cx); - - return i2c_bit_add_bus(&cx->i2c_adap[0]) || - i2c_bit_add_bus(&cx->i2c_adap[1]); -} - -void exit_cx18_i2c(struct cx18 *cx) -{ - int i; - CX18_DEBUG_I2C("i2c exit\n"); - cx18_write_reg(cx, cx18_read_reg(cx, CX18_REG_I2C_1_WR) | 4, - CX18_REG_I2C_1_WR); - cx18_write_reg(cx, cx18_read_reg(cx, CX18_REG_I2C_2_WR) | 4, - CX18_REG_I2C_2_WR); - - for (i = 0; i < 2; i++) { - i2c_del_adapter(&cx->i2c_adap[i]); - } -} - -/* - Hauppauge HVR1600 should have: - 32 cx24227 - 98 unknown - a0 eeprom - c2 tuner - e? zilog ir - */ diff --git a/drivers/media/video/cx18/cx18-i2c.h b/drivers/media/video/cx18/cx18-i2c.h deleted file mode 100644 index 4869739013b..00000000000 --- a/drivers/media/video/cx18/cx18-i2c.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * cx18 I2C functions - * - * Derived from ivtv-i2c.h - * - * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> - * - * 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., 59 Temple Place, Suite 330, Boston, MA - * 02111-1307 USA - */ - -int cx18_i2c_hw_addr(struct cx18 *cx, u32 hw); -int cx18_i2c_hw(struct cx18 *cx, u32 hw, unsigned int cmd, void *arg); -int cx18_call_i2c_client(struct cx18 *cx, int addr, unsigned cmd, void *arg); -void cx18_call_i2c_clients(struct cx18 *cx, unsigned int cmd, void *arg); -int cx18_i2c_register(struct cx18 *cx, unsigned idx); - -/* init + register i2c algo-bit adapter */ -int init_cx18_i2c(struct cx18 *cx); -void exit_cx18_i2c(struct cx18 *cx); diff --git a/drivers/media/video/cx18/cx18-io.c b/drivers/media/video/cx18/cx18-io.c deleted file mode 100644 index ec5b3d7bcc6..00000000000 --- a/drivers/media/video/cx18/cx18-io.c +++ /dev/null @@ -1,97 +0,0 @@ -/* - * cx18 driver PCI memory mapped IO access routines - * - * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> - * Copyright (C) 2008 Andy Walls <awalls@radix.net> - * - * 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., 59 Temple Place, Suite 330, Boston, MA - * 02111-1307 USA - */ - -#include "cx18-driver.h" -#include "cx18-io.h" -#include "cx18-irq.h" - -void cx18_memset_io(struct cx18 *cx, void __iomem *addr, int val, size_t count) -{ - u8 __iomem *dst = addr; - u16 val2 = val | (val << 8); - u32 val4 = val2 | (val2 << 16); - - /* Align writes on the CX23418's addresses */ - if ((count > 0) && ((unsigned long)dst & 1)) { - cx18_writeb(cx, (u8) val, dst); - count--; - dst++; - } - if ((count > 1) && ((unsigned long)dst & 2)) { - cx18_writew(cx, val2, dst); - count -= 2; - dst += 2; - } - while (count > 3) { - cx18_writel(cx, val4, dst); - count -= 4; - dst += 4; - } - if (count > 1) { - cx18_writew(cx, val2, dst); - count -= 2; - dst += 2; - } - if (count > 0) - cx18_writeb(cx, (u8) val, dst); -} - -void cx18_sw1_irq_enable(struct cx18 *cx, u32 val) -{ - cx18_write_reg_expect(cx, val, SW1_INT_STATUS, ~val, val); - cx->sw1_irq_mask = cx18_read_reg(cx, SW1_INT_ENABLE_PCI) | val; - cx18_write_reg(cx, cx->sw1_irq_mask, SW1_INT_ENABLE_PCI); -} - -void cx18_sw1_irq_disable(struct cx18 *cx, u32 val) -{ - cx->sw1_irq_mask = cx18_read_reg(cx, SW1_INT_ENABLE_PCI) & ~val; - cx18_write_reg(cx, cx->sw1_irq_mask, SW1_INT_ENABLE_PCI); -} - -void cx18_sw2_irq_enable(struct cx18 *cx, u32 val) -{ - cx18_write_reg_expect(cx, val, SW2_INT_STATUS, ~val, val); - cx->sw2_irq_mask = cx18_read_reg(cx, SW2_INT_ENABLE_PCI) | val; - cx18_write_reg(cx, cx->sw2_irq_mask, SW2_INT_ENABLE_PCI); -} - -void cx18_sw2_irq_disable(struct cx18 *cx, u32 val) -{ - cx->sw2_irq_mask = cx18_read_reg(cx, SW2_INT_ENABLE_PCI) & ~val; - cx18_write_reg(cx, cx->sw2_irq_mask, SW2_INT_ENABLE_PCI); -} - -void cx18_sw2_irq_disable_cpu(struct cx18 *cx, u32 val) -{ - u32 r; - r = cx18_read_reg(cx, SW2_INT_ENABLE_CPU); - cx18_write_reg(cx, r & ~val, SW2_INT_ENABLE_CPU); -} - -void cx18_setup_page(struct cx18 *cx, u32 addr) -{ - u32 val; - val = cx18_read_reg(cx, 0xD000F8); - val = (val & ~0x1f00) | ((addr >> 17) & 0x1f00); - cx18_write_reg(cx, val, 0xD000F8); -} diff --git a/drivers/media/video/cx18/cx18-io.h b/drivers/media/video/cx18/cx18-io.h deleted file mode 100644 index 2635b3a8cc9..00000000000 --- a/drivers/media/video/cx18/cx18-io.h +++ /dev/null @@ -1,191 +0,0 @@ -/* - * cx18 driver PCI memory mapped IO access routines - * - * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> - * Copyright (C) 2008 Andy Walls <awalls@radix.net> - * - * 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., 59 Temple Place, Suite 330, Boston, MA - * 02111-1307 USA - */ - -#ifndef CX18_IO_H -#define CX18_IO_H - -#include "cx18-driver.h" - -/* - * Readback and retry of MMIO access for reliability: - * The concept was suggested by Steve Toth <stoth@linuxtv.org>. - * The implmentation is the fault of Andy Walls <awalls@radix.net>. - * - * *write* functions are implied to retry the mmio unless suffixed with _noretry - * *read* functions never retry the mmio (it never helps to do so) - */ - -/* Non byteswapping memory mapped IO */ -static inline u32 cx18_raw_readl(struct cx18 *cx, const void __iomem *addr) -{ - return __raw_readl(addr); -} - -static inline -void cx18_raw_writel_noretry(struct cx18 *cx, u32 val, void __iomem *addr) -{ - __raw_writel(val, addr); -} - -static inline void cx18_raw_writel(struct cx18 *cx, u32 val, void __iomem *addr) -{ - int i; - for (i = 0; i < CX18_MAX_MMIO_WR_RETRIES; i++) { - cx18_raw_writel_noretry(cx, val, addr); - if (val == cx18_raw_readl(cx, addr)) - break; - } -} - -/* Normal memory mapped IO */ -static inline u32 cx18_readl(struct cx18 *cx, const void __iomem *addr) -{ - return readl(addr); -} - -static inline -void cx18_writel_noretry(struct cx18 *cx, u32 val, void __iomem *addr) -{ - writel(val, addr); -} - -static inline void cx18_writel(struct cx18 *cx, u32 val, void __iomem *addr) -{ - int i; - for (i = 0; i < CX18_MAX_MMIO_WR_RETRIES; i++) { - cx18_writel_noretry(cx, val, addr); - if (val == cx18_readl(cx, addr)) - break; - } -} - -static inline -void cx18_writel_expect(struct cx18 *cx, u32 val, void __iomem *addr, - u32 eval, u32 mask) -{ - int i; - u32 r; - eval &= mask; - for (i = 0; i < CX18_MAX_MMIO_WR_RETRIES; i++) { - cx18_writel_noretry(cx, val, addr); - r = cx18_readl(cx, addr); - if (r == 0xffffffff && eval != 0xffffffff) - continue; - if (eval == (r & mask)) - break; - } -} - -static inline u16 cx18_readw(struct cx18 *cx, const void __iomem *addr) -{ - return readw(addr); -} - -static inline -void cx18_writew_noretry(struct cx18 *cx, u16 val, void __iomem *addr) -{ - writew(val, addr); -} - -static inline void cx18_writew(struct cx18 *cx, u16 val, void __iomem *addr) -{ - int i; - for (i = 0; i < CX18_MAX_MMIO_WR_RETRIES; i++) { - cx18_writew_noretry(cx, val, addr); - if (val == cx18_readw(cx, addr)) - break; - } -} - -static inline u8 cx18_readb(struct cx18 *cx, const void __iomem *addr) -{ - return readb(addr); -} - -static inline -void cx18_writeb_noretry(struct cx18 *cx, u8 val, void __iomem *addr) -{ - writeb(val, addr); -} - -static inline void cx18_writeb(struct cx18 *cx, u8 val, void __iomem *addr) -{ - int i; - for (i = 0; i < CX18_MAX_MMIO_WR_RETRIES; i++) { - cx18_writeb_noretry(cx, val, addr); - if (val == cx18_readb(cx, addr)) - break; - } -} - -static inline -void cx18_memcpy_fromio(struct cx18 *cx, void *to, - const void __iomem *from, unsigned int len) -{ - memcpy_fromio(to, from, len); -} - -void cx18_memset_io(struct cx18 *cx, void __iomem *addr, int val, size_t count); - - -/* Access "register" region of CX23418 memory mapped I/O */ -static inline void cx18_write_reg_noretry(struct cx18 *cx, u32 val, u32 reg) -{ - cx18_writel_noretry(cx, val, cx->reg_mem + reg); -} - -static inline void cx18_write_reg(struct cx18 *cx, u32 val, u32 reg) -{ - cx18_writel(cx, val, cx->reg_mem + reg); -} - -static inline void cx18_write_reg_expect(struct cx18 *cx, u32 val, u32 reg, - u32 eval, u32 mask) -{ - cx18_writel_expect(cx, val, cx->reg_mem + reg, eval, mask); -} - -static inline u32 cx18_read_reg(struct cx18 *cx, u32 reg) -{ - return cx18_readl(cx, cx->reg_mem + reg); -} - - -/* Access "encoder memory" region of CX23418 memory mapped I/O */ -static inline void cx18_write_enc(struct cx18 *cx, u32 val, u32 addr) -{ - cx18_writel(cx, val, cx->enc_mem + addr); -} - -static inline u32 cx18_read_enc(struct cx18 *cx, u32 addr) -{ - return cx18_readl(cx, cx->enc_mem + addr); -} - -void cx18_sw1_irq_enable(struct cx18 *cx, u32 val); -void cx18_sw1_irq_disable(struct cx18 *cx, u32 val); -void cx18_sw2_irq_enable(struct cx18 *cx, u32 val); -void cx18_sw2_irq_disable(struct cx18 *cx, u32 val); -void cx18_sw2_irq_disable_cpu(struct cx18 *cx, u32 val); -void cx18_setup_page(struct cx18 *cx, u32 addr); - -#endif /* CX18_IO_H */ diff --git a/drivers/media/video/cx18/cx18-ioctl.c b/drivers/media/video/cx18/cx18-ioctl.c deleted file mode 100644 index 7086aaba77d..00000000000 --- a/drivers/media/video/cx18/cx18-ioctl.c +++ /dev/null @@ -1,843 +0,0 @@ -/* - * cx18 ioctl system call - * - * Derived from ivtv-ioctl.c - * - * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> - * Copyright (C) 2008 Andy Walls <awalls@radix.net> - * - * 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., 59 Temple Place, Suite 330, Boston, MA - * 02111-1307 USA - */ - -#include "cx18-driver.h" -#include "cx18-io.h" -#include "cx18-version.h" -#include "cx18-mailbox.h" -#include "cx18-i2c.h" -#include "cx18-queue.h" -#include "cx18-fileops.h" -#include "cx18-vbi.h" -#include "cx18-audio.h" -#include "cx18-video.h" -#include "cx18-streams.h" -#include "cx18-ioctl.h" -#include "cx18-gpio.h" -#include "cx18-controls.h" -#include "cx18-cards.h" -#include "cx18-av-core.h" -#include <media/tveeprom.h> -#include <media/v4l2-chip-ident.h> -#include <linux/i2c-id.h> - -u16 cx18_service2vbi(int type) -{ - switch (type) { - case V4L2_SLICED_TELETEXT_B: - return CX18_SLICED_TYPE_TELETEXT_B; - case V4L2_SLICED_CAPTION_525: - return CX18_SLICED_TYPE_CAPTION_525; - case V4L2_SLICED_WSS_625: - return CX18_SLICED_TYPE_WSS_625; - case V4L2_SLICED_VPS: - return CX18_SLICED_TYPE_VPS; - default: - return 0; - } -} - -static int valid_service_line(int field, int line, int is_pal) -{ - return (is_pal && line >= 6 && (line != 23 || field == 0)) || - (!is_pal && line >= 10 && line < 22); -} - -static u16 select_service_from_set(int field, int line, u16 set, int is_pal) -{ - u16 valid_set = (is_pal ? V4L2_SLICED_VBI_625 : V4L2_SLICED_VBI_525); - int i; - - set = set & valid_set; - if (set == 0 || !valid_service_line(field, line, is_pal)) - return 0; - if (!is_pal) { - if (line == 21 && (set & V4L2_SLICED_CAPTION_525)) - return V4L2_SLICED_CAPTION_525; - } else { - if (line == 16 && field == 0 && (set & V4L2_SLICED_VPS)) - return V4L2_SLICED_VPS; - if (line == 23 && field == 0 && (set & V4L2_SLICED_WSS_625)) - return V4L2_SLICED_WSS_625; - if (line == 23) - return 0; - } - for (i = 0; i < 32; i++) { - if ((1 << i) & set) - return 1 << i; - } - return 0; -} - -void cx18_expand_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal) -{ - u16 set = fmt->service_set; - int f, l; - - fmt->service_set = 0; - for (f = 0; f < 2; f++) { - for (l = 0; l < 24; l++) - fmt->service_lines[f][l] = select_service_from_set(f, l, set, is_pal); - } -} - - -u16 cx18_get_service_set(struct v4l2_sliced_vbi_format *fmt) -{ - int f, l; - u16 set = 0; - - for (f = 0; f < 2; f++) { - for (l = 0; l < 24; l++) - set |= fmt->service_lines[f][l]; - } - return set; -} - -static int cx18_g_fmt_vid_cap(struct file *file, void *fh, - struct v4l2_format *fmt) -{ - struct cx18_open_id *id = fh; - struct cx18 *cx = id->cx; - struct v4l2_pix_format *pixfmt = &fmt->fmt.pix; - - pixfmt->width = cx->params.width; - pixfmt->height = cx->params.height; - pixfmt->colorspace = V4L2_COLORSPACE_SMPTE170M; - pixfmt->field = V4L2_FIELD_INTERLACED; - pixfmt->priv = 0; - if (id->type == CX18_ENC_STREAM_TYPE_YUV) { - pixfmt->pixelformat = V4L2_PIX_FMT_HM12; - /* YUV size is (Y=(h*w) + UV=(h*(w/2))) */ - pixfmt->sizeimage = - pixfmt->height * pixfmt->width + - pixfmt->height * (pixfmt->width / 2); - pixfmt->bytesperline = 720; - } else { - pixfmt->pixelformat = V4L2_PIX_FMT_MPEG; - pixfmt->sizeimage = 128 * 1024; - pixfmt->bytesperline = 0; - } - return 0; -} - -static int cx18_g_fmt_vbi_cap(struct file *file, void *fh, - struct v4l2_format *fmt) -{ - struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; - struct v4l2_vbi_format *vbifmt = &fmt->fmt.vbi; - - vbifmt->sampling_rate = 27000000; - vbifmt->offset = 248; - vbifmt->samples_per_line = cx->vbi.raw_decoder_line_size - 4; - vbifmt->sample_format = V4L2_PIX_FMT_GREY; - vbifmt->start[0] = cx->vbi.start[0]; - vbifmt->start[1] = cx->vbi.start[1]; - vbifmt->count[0] = vbifmt->count[1] = cx->vbi.count; - vbifmt->flags = 0; - vbifmt->reserved[0] = 0; - vbifmt->reserved[1] = 0; - return 0; -} - -static int cx18_g_fmt_sliced_vbi_cap(struct file *file, void *fh, - struct v4l2_format *fmt) -{ - return -EINVAL; -} - -static int cx18_try_fmt_vid_cap(struct file *file, void *fh, - struct v4l2_format *fmt) -{ - struct cx18_open_id *id = fh; - struct cx18 *cx = id->cx; - int w = fmt->fmt.pix.width; - int h = fmt->fmt.pix.height; - - w = min(w, 720); - w = max(w, 1); - h = min(h, cx->is_50hz ? 576 : 480); - h = max(h, 2); - cx18_g_fmt_vid_cap(file, fh, fmt); - fmt->fmt.pix.width = w; - fmt->fmt.pix.height = h; - return 0; -} - -static int cx18_try_fmt_vbi_cap(struct file *file, void *fh, - struct v4l2_format *fmt) -{ - return cx18_g_fmt_vbi_cap(file, fh, fmt); -} - -static int cx18_try_fmt_sliced_vbi_cap(struct file *file, void *fh, - struct v4l2_format *fmt) -{ - return -EINVAL; -} - -static int cx18_s_fmt_vid_cap(struct file *file, void *fh, - struct v4l2_format *fmt) -{ - struct cx18_open_id *id = fh; - struct cx18 *cx = id->cx; - int ret; - int w, h; - - ret = v4l2_prio_check(&cx->prio, &id->prio); - if (ret) - return ret; - - ret = cx18_try_fmt_vid_cap(file, fh, fmt); - if (ret) - return ret; - w = fmt->fmt.pix.width; - h = fmt->fmt.pix.height; - - if (cx->params.width == w && cx->params.height == h) - return 0; - - if (atomic_read(&cx->ana_capturing) > 0) - return -EBUSY; - - cx->params.width = w; - cx->params.height = h; - cx18_av_cmd(cx, VIDIOC_S_FMT, fmt); - return cx18_g_fmt_vid_cap(file, fh, fmt); -} - -static int cx18_s_fmt_vbi_cap(struct file *file, void *fh, - struct v4l2_format *fmt) -{ - struct cx18_open_id *id = fh; - struct cx18 *cx = id->cx; - int ret; - - ret = v4l2_prio_check(&cx->prio, &id->prio); - if (ret) - return ret; - - if (!cx18_raw_vbi(cx) && atomic_read(&cx->ana_capturing) > 0) - return -EBUSY; - - cx->vbi.sliced_in->service_set = 0; - cx->vbi.in.type = V4L2_BUF_TYPE_VBI_CAPTURE; - cx18_av_cmd(cx, VIDIOC_S_FMT, fmt); - return cx18_g_fmt_vbi_cap(file, fh, fmt); -} - -static int cx18_s_fmt_sliced_vbi_cap(struct file *file, void *fh, - struct v4l2_format *fmt) -{ - return -EINVAL; -} - -static int cx18_g_chip_ident(struct file *file, void *fh, - struct v4l2_dbg_chip_ident *chip) -{ - struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; - - chip->ident = V4L2_IDENT_NONE; - chip->revision = 0; - if (v4l2_chip_match_host(&chip->match)) { - chip->ident = V4L2_IDENT_CX23418; - return 0; - } - cx18_call_i2c_clients(cx, VIDIOC_DBG_G_CHIP_IDENT, chip); - return 0; -} - -#ifdef CONFIG_VIDEO_ADV_DEBUG -static int cx18_cxc(struct cx18 *cx, unsigned int cmd, void *arg) -{ - struct v4l2_dbg_register *regs = arg; - unsigned long flags; - - if (!capable(CAP_SYS_ADMIN)) - return -EPERM; - if (regs->reg >= CX18_MEM_OFFSET + CX18_MEM_SIZE) - return -EINVAL; - - spin_lock_irqsave(&cx18_cards_lock, flags); - regs->size = 4; - if (cmd == VIDIOC_DBG_G_REGISTER) - regs->val = cx18_read_enc(cx, regs->reg); - else - cx18_write_enc(cx, regs->val, regs->reg); - spin_unlock_irqrestore(&cx18_cards_lock, flags); - return 0; -} - -static int cx18_g_register(struct file *file, void *fh, - struct v4l2_dbg_register *reg) -{ - struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; - - if (v4l2_chip_match_host(®->match)) - return cx18_cxc(cx, VIDIOC_DBG_G_REGISTER, reg); - cx18_call_i2c_clients(cx, VIDIOC_DBG_G_REGISTER, reg); - return 0; -} - -static int cx18_s_register(struct file *file, void *fh, - struct v4l2_dbg_register *reg) -{ - struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; - - if (v4l2_chip_match_host(®->match)) - return cx18_cxc(cx, VIDIOC_DBG_S_REGISTER, reg); - cx18_call_i2c_clients(cx, VIDIOC_DBG_S_REGISTER, reg); - return 0; -} -#endif - -static int cx18_g_priority(struct file *file, void *fh, enum v4l2_priority *p) -{ - struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; - - *p = v4l2_prio_max(&cx->prio); - return 0; -} - -static int cx18_s_priority(struct file *file, void *fh, enum v4l2_priority prio) -{ - struct cx18_open_id *id = fh; - struct cx18 *cx = id->cx; - - return v4l2_prio_change(&cx->prio, &id->prio, prio); -} - -static int cx18_querycap(struct file *file, void *fh, - struct v4l2_capability *vcap) -{ - struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; - - strlcpy(vcap->driver, CX18_DRIVER_NAME, sizeof(vcap->driver)); - strlcpy(vcap->card, cx->card_name, sizeof(vcap->card)); - snprintf(vcap->bus_info, sizeof(vcap->bus_info), "PCI:%s", pci_name(cx->dev)); - vcap->version = CX18_DRIVER_VERSION; /* version */ - vcap->capabilities = cx->v4l2_cap; /* capabilities */ - return 0; -} - -static int cx18_enumaudio(struct file *file, void *fh, struct v4l2_audio *vin) -{ - struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; - - return cx18_get_audio_input(cx, vin->index, vin); -} - -static int cx18_g_audio(struct file *file, void *fh, struct v4l2_audio *vin) -{ - struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; - - vin->index = cx->audio_input; - return cx18_get_audio_input(cx, vin->index, vin); -} - -static int cx18_s_audio(struct file *file, void *fh, struct v4l2_audio *vout) -{ - struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; - - if (vout->index >= cx->nof_audio_inputs) - return -EINVAL; - cx->audio_input = vout->index; - cx18_audio_set_io(cx); - return 0; -} - -static int cx18_enum_input(struct file *file, void *fh, struct v4l2_input *vin) -{ - struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; - - /* set it to defaults from our table */ - return cx18_get_input(cx, vin->index, vin); -} - -static int cx18_cropcap(struct file *file, void *fh, - struct v4l2_cropcap *cropcap) -{ - struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; - - if (cropcap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) - return -EINVAL; - cropcap->bounds.top = cropcap->bounds.left = 0; - cropcap->bounds.width = 720; - cropcap->bounds.height = cx->is_50hz ? 576 : 480; - cropcap->pixelaspect.numerator = cx->is_50hz ? 59 : 10; - cropcap->pixelaspect.denominator = cx->is_50hz ? 54 : 11; - cropcap->defrect = cropcap->bounds; - return 0; -} - -static int cx18_s_crop(struct file *file, void *fh, struct v4l2_crop *crop) -{ - struct cx18_open_id *id = fh; - struct cx18 *cx = id->cx; - int ret; - - ret = v4l2_prio_check(&cx->prio, &id->prio); - if (ret) - return ret; - - if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) - return -EINVAL; - return cx18_av_cmd(cx, VIDIOC_S_CROP, crop); -} - -static int cx18_g_crop(struct file *file, void *fh, struct v4l2_crop *crop) -{ - struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; - - if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) - return -EINVAL; - return cx18_av_cmd(cx, VIDIOC_G_CROP, crop); -} - -static int cx18_enum_fmt_vid_cap(struct file *file, void *fh, - struct v4l2_fmtdesc *fmt) -{ - static struct v4l2_fmtdesc formats[] = { - { 0, V4L2_BUF_TYPE_VIDEO_CAPTURE, 0, - "HM12 (YUV 4:1:1)", V4L2_PIX_FMT_HM12, { 0, 0, 0, 0 } - }, - { 1, V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FMT_FLAG_COMPRESSED, - "MPEG", V4L2_PIX_FMT_MPEG, { 0, 0, 0, 0 } - } - }; - - if (fmt->index > 1) - return -EINVAL; - *fmt = formats[fmt->index]; - return 0; -} - -static int cx18_g_input(struct file *file, void *fh, unsigned int *i) -{ - struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; - - *i = cx->active_input; - return 0; -} - -int cx18_s_input(struct file *file, void *fh, unsigned int inp) -{ - struct cx18_open_id *id = fh; - struct cx18 *cx = id->cx; - int ret; - - ret = v4l2_prio_check(&cx->prio, &id->prio); - if (ret) - return ret; - - if (inp < 0 || inp >= cx->nof_inputs) - return -EINVAL; - - if (inp == cx->active_input) { - CX18_DEBUG_INFO("Input unchanged\n"); - return 0; - } - - CX18_DEBUG_INFO("Changing input from %d to %d\n", - cx->active_input, inp); - - cx->active_input = inp; - /* Set the audio input to whatever is appropriate for the input type. */ - cx->audio_input = cx->card->video_inputs[inp].audio_index; - - /* prevent others from messing with the streams until - we're finished changing inputs. */ - cx18_mute(cx); - cx18_video_set_io(cx); - cx18_audio_set_io(cx); - cx18_unmute(cx); - return 0; -} - -static int cx18_g_frequency(struct file *file, void *fh, - struct v4l2_frequency *vf) -{ - struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; - - if (vf->tuner != 0) - return -EINVAL; - - cx18_call_i2c_clients(cx, VIDIOC_G_FREQUENCY, vf); - return 0; -} - -int cx18_s_frequency(struct file *file, void *fh, struct v4l2_frequency *vf) -{ - struct cx18_open_id *id = fh; - struct cx18 *cx = id->cx; - int ret; - - ret = v4l2_prio_check(&cx->prio, &id->prio); - if (ret) - return ret; - - if (vf->tuner != 0) - return -EINVAL; - - cx18_mute(cx); - CX18_DEBUG_INFO("v4l2 ioctl: set frequency %d\n", vf->frequency); - cx18_call_i2c_clients(cx, VIDIOC_S_FREQUENCY, vf); - cx18_unmute(cx); - return 0; -} - -static int cx18_g_std(struct file *file, void *fh, v4l2_std_id *std) -{ - struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; - - *std = cx->std; - return 0; -} - -int cx18_s_std(struct file *file, void *fh, v4l2_std_id *std) -{ - struct cx18_open_id *id = fh; - struct cx18 *cx = id->cx; - int ret; - - ret = v4l2_prio_check(&cx->prio, &id->prio); - if (ret) - return ret; - - if ((*std & V4L2_STD_ALL) == 0) - return -EINVAL; - - if (*std == cx->std) - return 0; - - if (test_bit(CX18_F_I_RADIO_USER, &cx->i_flags) || - atomic_read(&cx->ana_capturing) > 0) { - /* Switching standard would turn off the radio or mess - with already running streams, prevent that by - returning EBUSY. */ - return -EBUSY; - } - - cx->std = *std; - cx->is_60hz = (*std & V4L2_STD_525_60) ? 1 : 0; - cx->params.is_50hz = cx->is_50hz = !cx->is_60hz; - cx->params.width = 720; - cx->params.height = cx->is_50hz ? 576 : 480; - cx->vbi.count = cx->is_50hz ? 18 : 12; - cx->vbi.start[0] = cx->is_50hz ? 6 : 10; - cx->vbi.start[1] = cx->is_50hz ? 318 : 273; - cx->vbi.sliced_decoder_line_size = cx->is_60hz ? 272 : 284; - CX18_DEBUG_INFO("Switching standard to %llx.\n", - (unsigned long long) cx->std); - - /* Tuner */ - cx18_call_i2c_clients(cx, VIDIOC_S_STD, &cx->std); - return 0; -} - -static int cx18_s_tuner(struct file *file, void *fh, struct v4l2_tuner *vt) -{ - struct cx18_open_id *id = fh; - struct cx18 *cx = id->cx; - int ret; - - ret = v4l2_prio_check(&cx->prio, &id->prio); - if (ret) - return ret; - - if (vt->index != 0) - return -EINVAL; - - /* Setting tuner can only set audio mode */ - cx18_call_i2c_clients(cx, VIDIOC_S_TUNER, vt); - - return 0; -} - -static int cx18_g_tuner(struct file *file, void *fh, struct v4l2_tuner *vt) -{ - struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; - - if (vt->index != 0) - return -EINVAL; - - cx18_call_i2c_clients(cx, VIDIOC_G_TUNER, vt); - - if (test_bit(CX18_F_I_RADIO_USER, &cx->i_flags)) { - strlcpy(vt->name, "cx18 Radio Tuner", sizeof(vt->name)); - vt->type = V4L2_TUNER_RADIO; - } else { - strlcpy(vt->name, "cx18 TV Tuner", sizeof(vt->name)); - vt->type = V4L2_TUNER_ANALOG_TV; - } - - return 0; -} - -static int cx18_g_sliced_vbi_cap(struct file *file, void *fh, - struct v4l2_sliced_vbi_cap *cap) -{ - return -EINVAL; -} - -static int cx18_g_enc_index(struct file *file, void *fh, - struct v4l2_enc_idx *idx) -{ - return -EINVAL; -} - -static int cx18_encoder_cmd(struct file *file, void *fh, - struct v4l2_encoder_cmd *enc) -{ - struct cx18_open_id *id = fh; - struct cx18 *cx = id->cx; - u32 h; - - switch (enc->cmd) { - case V4L2_ENC_CMD_START: - CX18_DEBUG_IOCTL("V4L2_ENC_CMD_START\n"); - enc->flags = 0; - return cx18_start_capture(id); - - case V4L2_ENC_CMD_STOP: - CX18_DEBUG_IOCTL("V4L2_ENC_CMD_STOP\n"); - enc->flags &= V4L2_ENC_CMD_STOP_AT_GOP_END; - cx18_stop_capture(id, - enc->flags & V4L2_ENC_CMD_STOP_AT_GOP_END); - break; - - case V4L2_ENC_CMD_PAUSE: - CX18_DEBUG_IOCTL("V4L2_ENC_CMD_PAUSE\n"); - enc->flags = 0; - if (!atomic_read(&cx->ana_capturing)) - return -EPERM; - if (test_and_set_bit(CX18_F_I_ENC_PAUSED, &cx->i_flags)) - return 0; - h = cx18_find_handle(cx); - if (h == CX18_INVALID_TASK_HANDLE) { - CX18_ERR("Can't find valid task handle for " - "V4L2_ENC_CMD_PAUSE\n"); - return -EBADFD; - } - cx18_mute(cx); - cx18_vapi(cx, CX18_CPU_CAPTURE_PAUSE, 1, h); - break; - - case V4L2_ENC_CMD_RESUME: - CX18_DEBUG_IOCTL("V4L2_ENC_CMD_RESUME\n"); - enc->flags = 0; - if (!atomic_read(&cx->ana_capturing)) - return -EPERM; - if (!test_and_clear_bit(CX18_F_I_ENC_PAUSED, &cx->i_flags)) - return 0; - h = cx18_find_handle(cx); - if (h == CX18_INVALID_TASK_HANDLE) { - CX18_ERR("Can't find valid task handle for " - "V4L2_ENC_CMD_RESUME\n"); - return -EBADFD; - } - cx18_vapi(cx, CX18_CPU_CAPTURE_RESUME, 1, h); - cx18_unmute(cx); - break; - - default: - CX18_DEBUG_IOCTL("Unknown cmd %d\n", enc->cmd); - return -EINVAL; - } - return 0; -} - -static int cx18_try_encoder_cmd(struct file *file, void *fh, - struct v4l2_encoder_cmd *enc) -{ - struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; - - switch (enc->cmd) { - case V4L2_ENC_CMD_START: - CX18_DEBUG_IOCTL("V4L2_ENC_CMD_START\n"); - enc->flags = 0; - break; - - case V4L2_ENC_CMD_STOP: - CX18_DEBUG_IOCTL("V4L2_ENC_CMD_STOP\n"); - enc->flags &= V4L2_ENC_CMD_STOP_AT_GOP_END; - break; - - case V4L2_ENC_CMD_PAUSE: - CX18_DEBUG_IOCTL("V4L2_ENC_CMD_PAUSE\n"); - enc->flags = 0; - break; - - case V4L2_ENC_CMD_RESUME: - CX18_DEBUG_IOCTL("V4L2_ENC_CMD_RESUME\n"); - enc->flags = 0; - break; - - default: - CX18_DEBUG_IOCTL("Unknown cmd %d\n", enc->cmd); - return -EINVAL; - } - return 0; -} - -static int cx18_log_status(struct file *file, void *fh) -{ - struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; - struct v4l2_input vidin; - struct v4l2_audio audin; - int i; - - CX18_INFO("================= START STATUS CARD #%d =================\n", cx->num); - if (cx->hw_flags & CX18_HW_TVEEPROM) { - struct tveeprom tv; - - cx18_read_eeprom(cx, &tv); - } - cx18_call_i2c_clients(cx, VIDIOC_LOG_STATUS, NULL); - cx18_get_input(cx, cx->active_input, &vidin); - cx18_get_audio_input(cx, cx->audio_input, &audin); - CX18_INFO("Video Input: %s\n", vidin.name); - CX18_INFO("Audio Input: %s\n", audin.name); - mutex_lock(&cx->gpio_lock); - CX18_INFO("GPIO: direction 0x%08x, value 0x%08x\n", - cx->gpio_dir, cx->gpio_val); - mutex_unlock(&cx->gpio_lock); - CX18_INFO("Tuner: %s\n", - test_bit(CX18_F_I_RADIO_USER, &cx->i_flags) ? "Radio" : "TV"); - cx2341x_log_status(&cx->params, cx->name); - CX18_INFO("Status flags: 0x%08lx\n", cx->i_flags); - for (i = 0; i < CX18_MAX_STREAMS; i++) { - struct cx18_stream *s = &cx->streams[i]; - - if (s->v4l2dev == NULL || s->buffers == 0) - continue; - CX18_INFO("Stream %s: status 0x%04lx, %d%% of %d KiB (%d buffers) in use\n", - s->name, s->s_flags, - atomic_read(&s->q_full.buffers) * 100 / s->buffers, - (s->buffers * s->buf_size) / 1024, s->buffers); - } - CX18_INFO("Read MPEG/VBI: %lld/%lld bytes\n", - (long long)cx->mpg_data_received, - (long long)cx->vbi_data_inserted); - CX18_INFO("================== END STATUS CARD #%d ==================\n", cx->num); - return 0; -} - -static long cx18_default(struct file *file, void *fh, int cmd, void *arg) -{ - struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; - - switch (cmd) { - case VIDIOC_INT_S_AUDIO_ROUTING: { - struct v4l2_routing *route = arg; - - CX18_DEBUG_IOCTL("VIDIOC_INT_S_AUDIO_ROUTING(%d, %d)\n", - route->input, route->output); - cx18_audio_set_route(cx, route); - break; - } - - case VIDIOC_INT_RESET: { - u32 val = *(u32 *)arg; - - if ((val == 0) || (val & 0x01)) - cx18_reset_ir_gpio(&cx->i2c_algo_cb_data[0]); - break; - } - - default: - return -EINVAL; - } - return 0; -} - -long cx18_v4l2_ioctl(struct file *filp, unsigned int cmd, - unsigned long arg) -{ - struct video_device *vfd = video_devdata(filp); - struct cx18_open_id *id = (struct cx18_open_id *)filp->private_data; - struct cx18 *cx = id->cx; - long res; - - mutex_lock(&cx->serialize_lock); - - if (cx18_debug & CX18_DBGFLG_IOCTL) - vfd->debug = V4L2_DEBUG_IOCTL | V4L2_DEBUG_IOCTL_ARG; - res = video_ioctl2(filp, cmd, arg); - vfd->debug = 0; - mutex_unlock(&cx->serialize_lock); - return res; -} - -static const struct v4l2_ioctl_ops cx18_ioctl_ops = { - .vidioc_querycap = cx18_querycap, - .vidioc_g_priority = cx18_g_priority, - .vidioc_s_priority = cx18_s_priority, - .vidioc_s_audio = cx18_s_audio, - .vidioc_g_audio = cx18_g_audio, - .vidioc_enumaudio = cx18_enumaudio, - .vidioc_enum_input = cx18_enum_input, - .vidioc_cropcap = cx18_cropcap, - .vidioc_s_crop = cx18_s_crop, - .vidioc_g_crop = cx18_g_crop, - .vidioc_g_input = cx18_g_input, - .vidioc_s_input = cx18_s_input, - .vidioc_g_frequency = cx18_g_frequency, - .vidioc_s_frequency = cx18_s_frequency, - .vidioc_s_tuner = cx18_s_tuner, - .vidioc_g_tuner = cx18_g_tuner, - .vidioc_g_enc_index = cx18_g_enc_index, - .vidioc_g_std = cx18_g_std, - .vidioc_s_std = cx18_s_std, - .vidioc_log_status = cx18_log_status, - .vidioc_enum_fmt_vid_cap = cx18_enum_fmt_vid_cap, - .vidioc_encoder_cmd = cx18_encoder_cmd, - .vidioc_try_encoder_cmd = cx18_try_encoder_cmd, - .vidioc_g_fmt_vid_cap = cx18_g_fmt_vid_cap, - .vidioc_g_fmt_vbi_cap = cx18_g_fmt_vbi_cap, - .vidioc_g_fmt_sliced_vbi_cap = cx18_g_fmt_sliced_vbi_cap, - .vidioc_s_fmt_vid_cap = cx18_s_fmt_vid_cap, - .vidioc_s_fmt_vbi_cap = cx18_s_fmt_vbi_cap, - .vidioc_s_fmt_sliced_vbi_cap = cx18_s_fmt_sliced_vbi_cap, - .vidioc_try_fmt_vid_cap = cx18_try_fmt_vid_cap, - .vidioc_try_fmt_vbi_cap = cx18_try_fmt_vbi_cap, - .vidioc_try_fmt_sliced_vbi_cap = cx18_try_fmt_sliced_vbi_cap, - .vidioc_g_sliced_vbi_cap = cx18_g_sliced_vbi_cap, - .vidioc_g_chip_ident = cx18_g_chip_ident, -#ifdef CONFIG_VIDEO_ADV_DEBUG - .vidioc_g_register = cx18_g_register, - .vidioc_s_register = cx18_s_register, -#endif - .vidioc_default = cx18_default, - .vidioc_queryctrl = cx18_queryctrl, - .vidioc_querymenu = cx18_querymenu, - .vidioc_g_ext_ctrls = cx18_g_ext_ctrls, - .vidioc_s_ext_ctrls = cx18_s_ext_ctrls, - .vidioc_try_ext_ctrls = cx18_try_ext_ctrls, -}; - -void cx18_set_funcs(struct video_device *vdev) -{ - vdev->ioctl_ops = &cx18_ioctl_ops; -} diff --git a/drivers/media/video/cx18/cx18-ioctl.h b/drivers/media/video/cx18/cx18-ioctl.h deleted file mode 100644 index e2ca0d15211..00000000000 --- a/drivers/media/video/cx18/cx18-ioctl.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * cx18 ioctl system call - * - * Derived from ivtv-ioctl.h - * - * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> - * Copyright (C) 2008 Andy Walls <awalls@radix.net> - * - * 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., 59 Temple Place, Suite 330, Boston, MA - * 02111-1307 USA - */ - -u16 cx18_service2vbi(int type); -void cx18_expand_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal); -u16 cx18_get_service_set(struct v4l2_sliced_vbi_format *fmt); -void cx18_set_funcs(struct video_device *vdev); -int cx18_s_std(struct file *file, void *fh, v4l2_std_id *std); -int cx18_s_frequency(struct file *file, void *fh, struct v4l2_frequency *vf); -int cx18_s_input(struct file *file, void *fh, unsigned int inp); -long cx18_v4l2_ioctl(struct file *filp, unsigned int cmd, - unsigned long arg); diff --git a/drivers/media/video/cx18/cx18-irq.c b/drivers/media/video/cx18/cx18-irq.c deleted file mode 100644 index af2f504eda2..00000000000 --- a/drivers/media/video/cx18/cx18-irq.c +++ /dev/null @@ -1,81 +0,0 @@ -/* - * cx18 interrupt handling - * - * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> - * Copyright (C) 2008 Andy Walls <awalls@radix.net> - * - * 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., 59 Temple Place, Suite 330, Boston, MA - * 02111-1307 USA - */ - -#include "cx18-driver.h" -#include "cx18-io.h" -#include "cx18-irq.h" -#include "cx18-mailbox.h" -#include "cx18-scb.h" - -static void xpu_ack(struct cx18 *cx, u32 sw2) -{ - if (sw2 & IRQ_CPU_TO_EPU_ACK) - wake_up(&cx->mb_cpu_waitq); - if (sw2 & IRQ_APU_TO_EPU_ACK) - wake_up(&cx->mb_apu_waitq); -} - -static void epu_cmd(struct cx18 *cx, u32 sw1) -{ - if (sw1 & IRQ_CPU_TO_EPU) - cx18_api_epu_cmd_irq(cx, CPU); - if (sw1 & IRQ_APU_TO_EPU) - cx18_api_epu_cmd_irq(cx, APU); -} - -irqreturn_t cx18_irq_handler(int irq, void *dev_id) -{ - struct cx18 *cx = (struct cx18 *)dev_id; - u32 sw1, sw2, hw2; - - sw1 = cx18_read_reg(cx, SW1_INT_STATUS) & cx->sw1_irq_mask; - sw2 = cx18_read_reg(cx, SW2_INT_STATUS) & cx->sw2_irq_mask; - hw2 = cx18_read_reg(cx, HW2_INT_CLR_STATUS) & cx->hw2_irq_mask; - - if (sw1) - cx18_write_reg_expect(cx, sw1, SW1_INT_STATUS, ~sw1, sw1); - if (sw2) - cx18_write_reg_expect(cx, sw2, SW2_INT_STATUS, ~sw2, sw2); - if (hw2) - cx18_write_reg_expect(cx, hw2, HW2_INT_CLR_STATUS, ~hw2, hw2); - - if (sw1 || sw2 || hw2) - CX18_DEBUG_HI_IRQ("received interrupts " - "SW1: %x SW2: %x HW2: %x\n", sw1, sw2, hw2); - - /* - * SW1 responses have to happen first. The sending XPU times out the - * incoming mailboxes on us rather rapidly. - */ - if (sw1) - epu_cmd(cx, sw1); - - /* To do: interrupt-based I2C handling - if (hw2 & (HW2_I2C1_INT|HW2_I2C2_INT)) { - } - */ - - if (sw2) - xpu_ack(cx, sw2); - - return (sw1 || sw2 || hw2) ? IRQ_HANDLED : IRQ_NONE; -} diff --git a/drivers/media/video/cx18/cx18-irq.h b/drivers/media/video/cx18/cx18-irq.h deleted file mode 100644 index 91f0b5278ef..00000000000 --- a/drivers/media/video/cx18/cx18-irq.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * cx18 interrupt handling - * - * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> - * Copyright (C) 2008 Andy Walls <awalls@radix.net> - * - * 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., 59 Temple Place, Suite 330, Boston, MA - * 02111-1307 USA - */ - -#define HW2_I2C1_INT (1 << 22) -#define HW2_I2C2_INT (1 << 23) -#define HW2_INT_CLR_STATUS 0xc730c4 -#define HW2_INT_MASK5_PCI 0xc730e4 -#define SW1_INT_SET 0xc73100 -#define SW1_INT_STATUS 0xc73104 -#define SW1_INT_ENABLE_PCI 0xc7311c -#define SW2_INT_SET 0xc73140 -#define SW2_INT_STATUS 0xc73144 -#define SW2_INT_ENABLE_CPU 0xc73158 -#define SW2_INT_ENABLE_PCI 0xc7315c - -irqreturn_t cx18_irq_handler(int irq, void *dev_id); diff --git a/drivers/media/video/cx18/cx18-mailbox.c b/drivers/media/video/cx18/cx18-mailbox.c deleted file mode 100644 index de5e723fdf4..00000000000 --- a/drivers/media/video/cx18/cx18-mailbox.c +++ /dev/null @@ -1,703 +0,0 @@ -/* - * cx18 mailbox functions - * - * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> - * Copyright (C) 2008 Andy Walls <awalls@radix.net> - * - * 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., 59 Temple Place, Suite 330, Boston, MA - * 02111-1307 USA - */ - -#include <stdarg.h> - -#include "cx18-driver.h" -#include "cx18-io.h" -#include "cx18-scb.h" -#include "cx18-irq.h" -#include "cx18-mailbox.h" -#include "cx18-queue.h" -#include "cx18-streams.h" - -static const char *rpu_str[] = { "APU", "CPU", "EPU", "HPU" }; - -#define API_FAST (1 << 2) /* Short timeout */ -#define API_SLOW (1 << 3) /* Additional 300ms timeout */ - -struct cx18_api_info { - u32 cmd; - u8 flags; /* Flags, see above */ - u8 rpu; /* Processing unit */ - const char *name; /* The name of the command */ -}; - -#define API_ENTRY(rpu, x, f) { (x), (f), (rpu), #x } - -static const struct cx18_api_info api_info[] = { - /* MPEG encoder API */ - API_ENTRY(CPU, CX18_CPU_SET_CHANNEL_TYPE, 0), - API_ENTRY(CPU, CX18_EPU_DEBUG, 0), - API_ENTRY(CPU, CX18_CREATE_TASK, 0), - API_ENTRY(CPU, CX18_DESTROY_TASK, 0), - API_ENTRY(CPU, CX18_CPU_CAPTURE_START, API_SLOW), - API_ENTRY(CPU, CX18_CPU_CAPTURE_STOP, API_SLOW), - API_ENTRY(CPU, CX18_CPU_CAPTURE_PAUSE, 0), - API_ENTRY(CPU, CX18_CPU_CAPTURE_RESUME, 0), - API_ENTRY(CPU, CX18_CPU_SET_CHANNEL_TYPE, 0), - API_ENTRY(CPU, CX18_CPU_SET_STREAM_OUTPUT_TYPE, 0), - API_ENTRY(CPU, CX18_CPU_SET_VIDEO_IN, 0), - API_ENTRY(CPU, CX18_CPU_SET_VIDEO_RATE, 0), - API_ENTRY(CPU, CX18_CPU_SET_VIDEO_RESOLUTION, 0), - API_ENTRY(CPU, CX18_CPU_SET_FILTER_PARAM, 0), - API_ENTRY(CPU, CX18_CPU_SET_SPATIAL_FILTER_TYPE, 0), - API_ENTRY(CPU, CX18_CPU_SET_MEDIAN_CORING, 0), - API_ENTRY(CPU, CX18_CPU_SET_INDEXTABLE, 0), - API_ENTRY(CPU, CX18_CPU_SET_AUDIO_PARAMETERS, 0), - API_ENTRY(CPU, CX18_CPU_SET_VIDEO_MUTE, 0), - API_ENTRY(CPU, CX18_CPU_SET_AUDIO_MUTE, 0), - API_ENTRY(CPU, CX18_CPU_SET_MISC_PARAMETERS, 0), - API_ENTRY(CPU, CX18_CPU_SET_RAW_VBI_PARAM, API_SLOW), - API_ENTRY(CPU, CX18_CPU_SET_CAPTURE_LINE_NO, 0), - API_ENTRY(CPU, CX18_CPU_SET_COPYRIGHT, 0), - API_ENTRY(CPU, CX18_CPU_SET_AUDIO_PID, 0), - API_ENTRY(CPU, CX18_CPU_SET_VIDEO_PID, 0), - API_ENTRY(CPU, CX18_CPU_SET_VER_CROP_LINE, 0), - API_ENTRY(CPU, CX18_CPU_SET_GOP_STRUCTURE, 0), - API_ENTRY(CPU, CX18_CPU_SET_SCENE_CHANGE_DETECTION, 0), - API_ENTRY(CPU, CX18_CPU_SET_ASPECT_RATIO, 0), - API_ENTRY(CPU, CX18_CPU_SET_SKIP_INPUT_FRAME, 0), - API_ENTRY(CPU, CX18_CPU_SET_SLICED_VBI_PARAM, 0), - API_ENTRY(CPU, CX18_CPU_SET_USERDATA_PLACE_HOLDER, 0), - API_ENTRY(CPU, CX18_CPU_GET_ENC_PTS, 0), - API_ENTRY(CPU, CX18_CPU_DE_SET_MDL_ACK, 0), - API_ENTRY(CPU, CX18_CPU_DE_SET_MDL, API_FAST), - API_ENTRY(CPU, CX18_CPU_DE_RELEASE_MDL, API_SLOW), - API_ENTRY(APU, CX18_APU_RESETAI, 0), - API_ENTRY(CPU, CX18_CPU_DEBUG_PEEK32, 0), - API_ENTRY(0, 0, 0), -}; - -static const struct cx18_api_info *find_api_info(u32 cmd) -{ - int i; - - for (i = 0; api_info[i].cmd; i++) - if (api_info[i].cmd == cmd) - return &api_info[i]; - return NULL; -} - -static void dump_mb(struct cx18 *cx, struct cx18_mailbox *mb, char *name) -{ - char argstr[MAX_MB_ARGUMENTS*11+1]; - char *p; - int i; - - if (!(cx18_debug & CX18_DBGFLG_API)) - return; - - for (i = 0, p = argstr; i < MAX_MB_ARGUMENTS; i++, p += 11) { - /* kernel snprintf() appends '\0' always */ - snprintf(p, 12, " %#010x", mb->args[i]); - } - CX18_DEBUG_API("%s: req %#010x ack %#010x cmd %#010x err %#010x args%s" - "\n", name, mb->request, mb->ack, mb->cmd, mb->error, argstr); -} - - -/* - * Functions that run in a work_queue work handling context - */ - -static void epu_dma_done(struct cx18 *cx, struct cx18_epu_work_order *order) -{ - u32 handle, mdl_ack_count, id; - struct cx18_mailbox *mb; - struct cx18_mdl_ack *mdl_ack; - struct cx18_stream *s; - struct cx18_buffer *buf; - int i; - - mb = &order->mb; - handle = mb->args[0]; - s = cx18_handle_to_stream(cx, handle); - - if (s == NULL) { - CX18_WARN("Got DMA done notification for unknown/inactive" - " handle %d, %s mailbox seq no %d\n", handle, - (order->flags & CX18_F_EWO_MB_STALE_UPON_RECEIPT) ? - "stale" : "good", mb->request); - return; - } - - mdl_ack_count = mb->args[2]; - mdl_ack = order->mdl_ack; - for (i = 0; i < mdl_ack_count; i++, mdl_ack++) { - id = mdl_ack->id; - /* - * Simple integrity check for processing a stale (and possibly - * inconsistent mailbox): make sure the buffer id is in the - * valid range for the stream. - * - * We go through the trouble of dealing with stale mailboxes - * because most of the time, the mailbox data is still valid and - * unchanged (and in practice the firmware ping-pongs the - * two mdl_ack buffers so mdl_acks are not stale). - * - * There are occasions when we get a half changed mailbox, - * which this check catches for a handle & id mismatch. If the - * handle and id do correspond, the worst case is that we - * completely lost the old buffer, but pick up the new buffer - * early (but the new mdl_ack is guaranteed to be good in this - * case as the firmware wouldn't point us to a new mdl_ack until - * it's filled in). - * - * cx18_queue_get buf() will detect the lost buffers - * and send them back to q_free for fw rotation eventually. - */ - if ((order->flags & CX18_F_EWO_MB_STALE_UPON_RECEIPT) && - !(id >= s->mdl_offset && - id < (s->mdl_offset + s->buffers))) { - CX18_WARN("Fell behind! Ignoring stale mailbox with " - " inconsistent data. Lost buffer for mailbox " - "seq no %d\n", mb->request); - break; - } - buf = cx18_queue_get_buf(s, id, mdl_ack->data_used); - - CX18_DEBUG_HI_DMA("DMA DONE for %s (buffer %d)\n", s->name, id); - if (buf == NULL) { - CX18_WARN("Could not find buf %d for stream %s\n", - id, s->name); - /* Put as many buffers as possible back into fw use */ - cx18_stream_load_fw_queue(s); - continue; - } - - if (s->type == CX18_ENC_STREAM_TYPE_TS && s->dvb.enabled) { - CX18_DEBUG_HI_DMA("TS recv bytesused = %d\n", - buf->bytesused); - dvb_dmx_swfilter(&s->dvb.demux, buf->buf, - buf->bytesused); - } - /* Put as many buffers as possible back into fw use */ - cx18_stream_load_fw_queue(s); - /* Put back TS buffer, since it was removed from all queues */ - if (s->type == CX18_ENC_STREAM_TYPE_TS) - cx18_stream_put_buf_fw(s, buf); - } - wake_up(&cx->dma_waitq); - if (s->id != -1) - wake_up(&s->waitq); -} - -static void epu_debug(struct cx18 *cx, struct cx18_epu_work_order *order) -{ - char *p; - char *str = order->str; - - CX18_DEBUG_INFO("%x %s\n", order->mb.args[0], str); - p = strchr(str, '.'); - if (!test_bit(CX18_F_I_LOADED_FW, &cx->i_flags) && p && p > str) - CX18_INFO("FW version: %s\n", p - 1); -} - -static void epu_cmd(struct cx18 *cx, struct cx18_epu_work_order *order) -{ - switch (order->rpu) { - case CPU: - { - switch (order->mb.cmd) { - case CX18_EPU_DMA_DONE: - epu_dma_done(cx, order); - break; - case CX18_EPU_DEBUG: - epu_debug(cx, order); - break; - default: - CX18_WARN("Unknown CPU to EPU mailbox command %#0x\n", - order->mb.cmd); - break; - } - break; - } - case APU: - CX18_WARN("Unknown APU to EPU mailbox command %#0x\n", - order->mb.cmd); - break; - default: - break; - } -} - -static -void free_epu_work_order(struct cx18 *cx, struct cx18_epu_work_order *order) -{ - atomic_set(&order->pending, 0); -} - -void cx18_epu_work_handler(struct work_struct *work) -{ - struct cx18_epu_work_order *order = - container_of(work, struct cx18_epu_work_order, work); - struct cx18 *cx = order->cx; - epu_cmd(cx, order); - free_epu_work_order(cx, order); -} - - -/* - * Functions that run in an interrupt handling context - */ - -static void mb_ack_irq(struct cx18 *cx, struct cx18_epu_work_order *order) -{ - struct cx18_mailbox __iomem *ack_mb; - u32 ack_irq, req; - - switch (order->rpu) { - case APU: - ack_irq = IRQ_EPU_TO_APU_ACK; - ack_mb = &cx->scb->apu2epu_mb; - break; - case CPU: - ack_irq = IRQ_EPU_TO_CPU_ACK; - ack_mb = &cx->scb->cpu2epu_mb; - break; - default: - CX18_WARN("Unhandled RPU (%d) for command %x ack\n", - order->rpu, order->mb.cmd); - return; - } - - req = order->mb.request; - /* Don't ack if the RPU has gotten impatient and timed us out */ - if (req != cx18_readl(cx, &ack_mb->request) || - req == cx18_readl(cx, &ack_mb->ack)) { - CX18_DEBUG_WARN("Possibly falling behind: %s self-ack'ed our " - "incoming %s to EPU mailbox (sequence no. %u) " - "while processing\n", - rpu_str[order->rpu], rpu_str[order->rpu], req); - order->flags |= CX18_F_EWO_MB_STALE_WHILE_PROC; - return; - } - cx18_writel(cx, req, &ack_mb->ack); - cx18_write_reg_expect(cx, ack_irq, SW2_INT_SET, ack_irq, ack_irq); - return; -} - -static int epu_dma_done_irq(struct cx18 *cx, struct cx18_epu_work_order *order) -{ - u32 handle, mdl_ack_offset, mdl_ack_count; - struct cx18_mailbox *mb; - - mb = &order->mb; - handle = mb->args[0]; - mdl_ack_offset = mb->args[1]; - mdl_ack_count = mb->args[2]; - - if (handle == CX18_INVALID_TASK_HANDLE || - mdl_ack_count == 0 || mdl_ack_count > CX18_MAX_MDL_ACKS) { - if ((order->flags & CX18_F_EWO_MB_STALE) == 0) - mb_ack_irq(cx, order); - return -1; - } - - cx18_memcpy_fromio(cx, order->mdl_ack, cx->enc_mem + mdl_ack_offset, - sizeof(struct cx18_mdl_ack) * mdl_ack_count); - - if ((order->flags & CX18_F_EWO_MB_STALE) == 0) - mb_ack_irq(cx, order); - return 1; -} - -static -int epu_debug_irq(struct cx18 *cx, struct cx18_epu_work_order *order) -{ - u32 str_offset; - char *str = order->str; - - str[0] = '\0'; - str_offset = order->mb.args[1]; - if (str_offset) { - cx18_setup_page(cx, str_offset); - cx18_memcpy_fromio(cx, str, cx->enc_mem + str_offset, 252); - str[252] = '\0'; - cx18_setup_page(cx, SCB_OFFSET); - } - - if ((order->flags & CX18_F_EWO_MB_STALE) == 0) - mb_ack_irq(cx, order); - - return str_offset ? 1 : 0; -} - -static inline -int epu_cmd_irq(struct cx18 *cx, struct cx18_epu_work_order *order) -{ - int ret = -1; - - switch (order->rpu) { - case CPU: - { - switch (order->mb.cmd) { - case CX18_EPU_DMA_DONE: - ret = epu_dma_done_irq(cx, order); - break; - case CX18_EPU_DEBUG: - ret = epu_debug_irq(cx, order); - break; - default: - CX18_WARN("Unknown CPU to EPU mailbox command %#0x\n", - order->mb.cmd); - break; - } - break; - } - case APU: - CX18_WARN("Unknown APU to EPU mailbox command %#0x\n", - order->mb.cmd); - break; - default: - break; - } - return ret; -} - -static inline -struct cx18_epu_work_order *alloc_epu_work_order_irq(struct cx18 *cx) -{ - int i; - struct cx18_epu_work_order *order = NULL; - - for (i = 0; i < CX18_MAX_EPU_WORK_ORDERS; i++) { - /* - * We only need "pending" atomic to inspect its contents, - * and need not do a check and set because: - * 1. Any work handler thread only clears "pending" and only - * on one, particular work order at a time, per handler thread. - * 2. "pending" is only set here, and we're serialized because - * we're called in an IRQ handler context. - */ - if (atomic_read(&cx->epu_work_order[i].pending) == 0) { - order = &cx->epu_work_order[i]; - atomic_set(&order->pending, 1); - break; - } - } - return order; -} - -void cx18_api_epu_cmd_irq(struct cx18 *cx, int rpu) -{ - struct cx18_mailbox __iomem *mb; - struct cx18_mailbox *order_mb; - struct cx18_epu_work_order *order; - int submit; - - switch (rpu) { - case CPU: - mb = &cx->scb->cpu2epu_mb; - break; - case APU: - mb = &cx->scb->apu2epu_mb; - break; - default: - return; - } - - order = alloc_epu_work_order_irq(cx); - if (order == NULL) { - CX18_WARN("Unable to find blank work order form to schedule " - "incoming mailbox command processing\n"); - return; - } - - order->flags = 0; - order->rpu = rpu; - order_mb = &order->mb; - - /* mb->cmd and mb->args[0] through mb->args[2] */ - cx18_memcpy_fromio(cx, &order_mb->cmd, &mb->cmd, 4 * sizeof(u32)); - /* mb->request and mb->ack. N.B. we want to read mb->ack last */ - cx18_memcpy_fromio(cx, &order_mb->request, &mb->request, - 2 * sizeof(u32)); - - if (order_mb->request == order_mb->ack) { - CX18_DEBUG_WARN("Possibly falling behind: %s self-ack'ed our " - "incoming %s to EPU mailbox (sequence no. %u)" - "\n", - rpu_str[rpu], rpu_str[rpu], order_mb->request); - dump_mb(cx, order_mb, "incoming"); - order->flags = CX18_F_EWO_MB_STALE_UPON_RECEIPT; - } - - /* - * Individual EPU command processing is responsible for ack-ing - * a non-stale mailbox as soon as possible - */ - submit = epu_cmd_irq(cx, order); - if (submit > 0) { - queue_work(cx->work_queue, &order->work); - } -} - - -/* - * Functions called from a non-interrupt, non work_queue context - */ - -static int cx18_api_call(struct cx18 *cx, u32 cmd, int args, u32 data[]) -{ - const struct cx18_api_info *info = find_api_info(cmd); - u32 state, irq, req, ack, err; - struct cx18_mailbox __iomem *mb; - u32 __iomem *xpu_state; - wait_queue_head_t *waitq; - struct mutex *mb_lock; - long int timeout, ret; - int i; - - if (info == NULL) { - CX18_WARN("unknown cmd %x\n", cmd); - return -EINVAL; - } - - if (cmd == CX18_CPU_DE_SET_MDL) - CX18_DEBUG_HI_API("%s\n", info->name); - else - CX18_DEBUG_API("%s\n", info->name); - - switch (info->rpu) { - case APU: - waitq = &cx->mb_apu_waitq; - mb_lock = &cx->epu2apu_mb_lock; - irq = IRQ_EPU_TO_APU; - mb = &cx->scb->epu2apu_mb; - xpu_state = &cx->scb->apu_state; - break; - case CPU: - waitq = &cx->mb_cpu_waitq; - mb_lock = &cx->epu2cpu_mb_lock; - irq = IRQ_EPU_TO_CPU; - mb = &cx->scb->epu2cpu_mb; - xpu_state = &cx->scb->cpu_state; - break; - default: - CX18_WARN("Unknown RPU (%d) for API call\n", info->rpu); - return -EINVAL; - } - - mutex_lock(mb_lock); - /* - * Wait for an in-use mailbox to complete - * - * If the XPU is responding with Ack's, the mailbox shouldn't be in - * a busy state, since we serialize access to it on our end. - * - * If the wait for ack after sending a previous command was interrupted - * by a signal, we may get here and find a busy mailbox. After waiting, - * mark it "not busy" from our end, if the XPU hasn't ack'ed it still. - */ - state = cx18_readl(cx, xpu_state); - req = cx18_readl(cx, &mb->request); - timeout = msecs_to_jiffies(10); - ret = wait_event_timeout(*waitq, - (ack = cx18_readl(cx, &mb->ack)) == req, - timeout); - if (req != ack) { - /* waited long enough, make the mbox "not busy" from our end */ - cx18_writel(cx, req, &mb->ack); - CX18_ERR("mbox was found stuck busy when setting up for %s; " - "clearing busy and trying to proceed\n", info->name); - } else if (ret != timeout) - CX18_DEBUG_API("waited %u msecs for busy mbox to be acked\n", - jiffies_to_msecs(timeout-ret)); - - /* Build the outgoing mailbox */ - req = ((req & 0xfffffffe) == 0xfffffffe) ? 1 : req + 1; - - cx18_writel(cx, cmd, &mb->cmd); - for (i = 0; i < args; i++) - cx18_writel(cx, data[i], &mb->args[i]); - cx18_writel(cx, 0, &mb->error); - cx18_writel(cx, req, &mb->request); - cx18_writel(cx, req - 1, &mb->ack); /* ensure ack & req are distinct */ - - /* - * Notify the XPU and wait for it to send an Ack back - */ - timeout = msecs_to_jiffies((info->flags & API_FAST) ? 10 : 20); - - CX18_DEBUG_HI_IRQ("sending interrupt SW1: %x to send %s\n", - irq, info->name); - cx18_write_reg_expect(cx, irq, SW1_INT_SET, irq, irq); - - ret = wait_event_timeout( - *waitq, - cx18_readl(cx, &mb->ack) == cx18_readl(cx, &mb->request), - timeout); - - if (ret == 0) { - /* Timed out */ - mutex_unlock(mb_lock); - CX18_DEBUG_WARN("sending %s timed out waiting %d msecs for RPU " - "acknowledgement\n", - info->name, jiffies_to_msecs(timeout)); - return -EINVAL; - } - - if (ret != timeout) - CX18_DEBUG_HI_API("waited %u msecs for %s to be acked\n", - jiffies_to_msecs(timeout-ret), info->name); - - /* Collect data returned by the XPU */ - for (i = 0; i < MAX_MB_ARGUMENTS; i++) - data[i] = cx18_readl(cx, &mb->args[i]); - err = cx18_readl(cx, &mb->error); - mutex_unlock(mb_lock); - - /* - * Wait for XPU to perform extra actions for the caller in some cases. - * e.g. CX18_CPU_DE_RELEASE_MDL will cause the CPU to send all buffers - * back in a burst shortly thereafter - */ - if (info->flags & API_SLOW) - cx18_msleep_timeout(300, 0); - - if (err) - CX18_DEBUG_API("mailbox error %08x for command %s\n", err, - info->name); - return err ? -EIO : 0; -} - -int cx18_api(struct cx18 *cx, u32 cmd, int args, u32 data[]) -{ - return cx18_api_call(cx, cmd, args, data); -} - -static int cx18_set_filter_param(struct cx18_stream *s) -{ - struct cx18 *cx = s->cx; - u32 mode; - int ret; - - mode = (cx->filter_mode & 1) ? 2 : (cx->spatial_strength ? 1 : 0); - ret = cx18_vapi(cx, CX18_CPU_SET_FILTER_PARAM, 4, - s->handle, 1, mode, cx->spatial_strength); - mode = (cx->filter_mode & 2) ? 2 : (cx->temporal_strength ? 1 : 0); - ret = ret ? ret : cx18_vapi(cx, CX18_CPU_SET_FILTER_PARAM, 4, - s->handle, 0, mode, cx->temporal_strength); - ret = ret ? ret : cx18_vapi(cx, CX18_CPU_SET_FILTER_PARAM, 4, - s->handle, 2, cx->filter_mode >> 2, 0); - return ret; -} - -int cx18_api_func(void *priv, u32 cmd, int in, int out, - u32 data[CX2341X_MBOX_MAX_DATA]) -{ - struct cx18_api_func_private *api_priv = priv; - struct cx18 *cx = api_priv->cx; - struct cx18_stream *s = api_priv->s; - - switch (cmd) { - case CX2341X_ENC_SET_OUTPUT_PORT: - return 0; - case CX2341X_ENC_SET_FRAME_RATE: - return cx18_vapi(cx, CX18_CPU_SET_VIDEO_IN, 6, - s->handle, 0, 0, 0, 0, data[0]); - case CX2341X_ENC_SET_FRAME_SIZE: - return cx18_vapi(cx, CX18_CPU_SET_VIDEO_RESOLUTION, 3, - s->handle, data[1], data[0]); - case CX2341X_ENC_SET_STREAM_TYPE: - return cx18_vapi(cx, CX18_CPU_SET_STREAM_OUTPUT_TYPE, 2, - s->handle, data[0]); - case CX2341X_ENC_SET_ASPECT_RATIO: - return cx18_vapi(cx, CX18_CPU_SET_ASPECT_RATIO, 2, - s->handle, data[0]); - - case CX2341X_ENC_SET_GOP_PROPERTIES: - return cx18_vapi(cx, CX18_CPU_SET_GOP_STRUCTURE, 3, - s->handle, data[0], data[1]); - case CX2341X_ENC_SET_GOP_CLOSURE: - return 0; - case CX2341X_ENC_SET_AUDIO_PROPERTIES: - return cx18_vapi(cx, CX18_CPU_SET_AUDIO_PARAMETERS, 2, - s->handle, data[0]); - case CX2341X_ENC_MUTE_AUDIO: - return cx18_vapi(cx, CX18_CPU_SET_AUDIO_MUTE, 2, - s->handle, data[0]); - case CX2341X_ENC_SET_BIT_RATE: - return cx18_vapi(cx, CX18_CPU_SET_VIDEO_RATE, 5, - s->handle, data[0], data[1], data[2], data[3]); - case CX2341X_ENC_MUTE_VIDEO: - return cx18_vapi(cx, CX18_CPU_SET_VIDEO_MUTE, 2, - s->handle, data[0]); - case CX2341X_ENC_SET_FRAME_DROP_RATE: - return cx18_vapi(cx, CX18_CPU_SET_SKIP_INPUT_FRAME, 2, - s->handle, data[0]); - case CX2341X_ENC_MISC: - return cx18_vapi(cx, CX18_CPU_SET_MISC_PARAMETERS, 4, - s->handle, data[0], data[1], data[2]); - case CX2341X_ENC_SET_DNR_FILTER_MODE: - cx->filter_mode = (data[0] & 3) | (data[1] << 2); - return cx18_set_filter_param(s); - case CX2341X_ENC_SET_DNR_FILTER_PROPS: - cx->spatial_strength = data[0]; - cx->temporal_strength = data[1]; - return cx18_set_filter_param(s); - case CX2341X_ENC_SET_SPATIAL_FILTER_TYPE: - return cx18_vapi(cx, CX18_CPU_SET_SPATIAL_FILTER_TYPE, 3, - s->handle, data[0], data[1]); - case CX2341X_ENC_SET_CORING_LEVELS: - return cx18_vapi(cx, CX18_CPU_SET_MEDIAN_CORING, 5, - s->handle, data[0], data[1], data[2], data[3]); - } - CX18_WARN("Unknown cmd %x\n", cmd); - return 0; -} - -int cx18_vapi_result(struct cx18 *cx, u32 data[MAX_MB_ARGUMENTS], - u32 cmd, int args, ...) -{ - va_list ap; - int i; - - va_start(ap, args); - for (i = 0; i < args; i++) - data[i] = va_arg(ap, u32); - va_end(ap); - return cx18_api(cx, cmd, args, data); -} - -int cx18_vapi(struct cx18 *cx, u32 cmd, int args, ...) -{ - u32 data[MAX_MB_ARGUMENTS]; - va_list ap; - int i; - - if (cx == NULL) { - CX18_ERR("cx == NULL (cmd=%x)\n", cmd); - return 0; - } - if (args > MAX_MB_ARGUMENTS) { - CX18_ERR("args too big (cmd=%x)\n", cmd); - args = MAX_MB_ARGUMENTS; - } - va_start(ap, args); - for (i = 0; i < args; i++) - data[i] = va_arg(ap, u32); - va_end(ap); - return cx18_api(cx, cmd, args, data); -} diff --git a/drivers/media/video/cx18/cx18-mailbox.h b/drivers/media/video/cx18/cx18-mailbox.h deleted file mode 100644 index ce2b6686aa0..00000000000 --- a/drivers/media/video/cx18/cx18-mailbox.h +++ /dev/null @@ -1,100 +0,0 @@ -/* - * cx18 mailbox functions - * - * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> - * Copyright (C) 2008 Andy Walls <awalls@radix.net> - * - * 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., 59 Temple Place, Suite 330, Boston, MA - * 02111-1307 USA - */ - -#ifndef _CX18_MAILBOX_H_ -#define _CX18_MAILBOX_H_ - -/* mailbox max args */ -#define MAX_MB_ARGUMENTS 6 -/* compatibility, should be same as the define in cx2341x.h */ -#define CX2341X_MBOX_MAX_DATA 16 - -#define MB_RESERVED_HANDLE_0 0 -#define MB_RESERVED_HANDLE_1 0xFFFFFFFF - -#define APU 0 -#define CPU 1 -#define EPU 2 -#define HPU 3 - -struct cx18; - -/* - * This structure is used by CPU to provide completed buffers information - * Its structure is dictrated by the layout of the SCB, required by the - * firmware, but its defintion needs to be here, instead of in cx18-scb.h, - * for mailbox work order scheduling - */ -struct cx18_mdl_ack { - u32 id; /* ID of a completed MDL */ - u32 data_used; /* Total data filled in the MDL for buffer 'id' */ -}; - -/* The cx18_mailbox struct is the mailbox structure which is used for passing - messages between processors */ -struct cx18_mailbox { - /* The sender sets a handle in 'request' after he fills the command. The - 'request' should be different than 'ack'. The sender, also, generates - an interrupt on XPU2YPU_irq where XPU is the sender and YPU is the - receiver. */ - u32 request; - /* The receiver detects a new command when 'req' is different than 'ack'. - He sets 'ack' to the same value as 'req' to clear the command. He, also, - generates an interrupt on YPU2XPU_irq where XPU is the sender and YPU - is the receiver. */ - u32 ack; - u32 reserved[6]; - /* 'cmd' identifies the command. The list of these commands are in - cx23418.h */ - u32 cmd; - /* Each command can have up to 6 arguments */ - u32 args[MAX_MB_ARGUMENTS]; - /* The return code can be one of the codes in the file cx23418.h. If the - command is completed successfuly, the error will be ERR_SYS_SUCCESS. - If it is pending, the code is ERR_SYS_PENDING. If it failed, the error - code would indicate the task from which the error originated and will - be one of the errors in cx23418.h. In that case, the following - applies ((error & 0xff) != 0). - If the command is pending, the return will be passed in a MB from the - receiver to the sender. 'req' will be returned in args[0] */ - u32 error; -}; - -struct cx18_stream; - -struct cx18_api_func_private { - struct cx18 *cx; - struct cx18_stream *s; -}; - -int cx18_api(struct cx18 *cx, u32 cmd, int args, u32 data[]); -int cx18_vapi_result(struct cx18 *cx, u32 data[MAX_MB_ARGUMENTS], u32 cmd, - int args, ...); -int cx18_vapi(struct cx18 *cx, u32 cmd, int args, ...); -int cx18_api_func(void *priv, u32 cmd, int in, int out, - u32 data[CX2341X_MBOX_MAX_DATA]); - -void cx18_api_epu_cmd_irq(struct cx18 *cx, int rpu); - -void cx18_epu_work_handler(struct work_struct *work); - -#endif diff --git a/drivers/media/video/cx18/cx18-queue.c b/drivers/media/video/cx18/cx18-queue.c deleted file mode 100644 index 8d9441e88c4..00000000000 --- a/drivers/media/video/cx18/cx18-queue.c +++ /dev/null @@ -1,235 +0,0 @@ -/* - * cx18 buffer queues - * - * Derived from ivtv-queue.c - * - * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> - * Copyright (C) 2008 Andy Walls <awalls@radix.net> - * - * 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., 59 Temple Place, Suite 330, Boston, MA - * 02111-1307 USA - */ - -#include "cx18-driver.h" -#include "cx18-streams.h" -#include "cx18-queue.h" -#include "cx18-scb.h" - -void cx18_buf_swap(struct cx18_buffer *buf) -{ - int i; - - for (i = 0; i < buf->bytesused; i += 4) - swab32s((u32 *)(buf->buf + i)); -} - -void cx18_queue_init(struct cx18_queue *q) -{ - INIT_LIST_HEAD(&q->list); - atomic_set(&q->buffers, 0); - q->bytesused = 0; -} - -struct cx18_queue *_cx18_enqueue(struct cx18_stream *s, struct cx18_buffer *buf, - struct cx18_queue *q, int to_front) -{ - /* clear the buffer if it is not to be enqueued to the full queue */ - if (q != &s->q_full) { - buf->bytesused = 0; - buf->readpos = 0; - buf->b_flags = 0; - buf->skipped = 0; - } - - mutex_lock(&s->qlock); - - /* q_busy is restricted to a max buffer count imposed by firmware */ - if (q == &s->q_busy && - atomic_read(&q->buffers) >= CX18_MAX_FW_MDLS_PER_STREAM) - q = &s->q_free; - - if (to_front) - list_add(&buf->list, &q->list); /* LIFO */ - else - list_add_tail(&buf->list, &q->list); /* FIFO */ - q->bytesused += buf->bytesused - buf->readpos; - atomic_inc(&q->buffers); - - mutex_unlock(&s->qlock); - return q; -} - -struct cx18_buffer *cx18_dequeue(struct cx18_stream *s, struct cx18_queue *q) -{ - struct cx18_buffer *buf = NULL; - - mutex_lock(&s->qlock); - if (!list_empty(&q->list)) { - buf = list_first_entry(&q->list, struct cx18_buffer, list); - list_del_init(&buf->list); - q->bytesused -= buf->bytesused - buf->readpos; - buf->skipped = 0; - atomic_dec(&q->buffers); - } - mutex_unlock(&s->qlock); - return buf; -} - -struct cx18_buffer *cx18_queue_get_buf(struct cx18_stream *s, u32 id, - u32 bytesused) -{ - struct cx18 *cx = s->cx; - struct cx18_buffer *buf; - struct cx18_buffer *tmp; - struct cx18_buffer *ret = NULL; - - mutex_lock(&s->qlock); - list_for_each_entry_safe(buf, tmp, &s->q_busy.list, list) { - if (buf->id != id) { - buf->skipped++; - if (buf->skipped >= atomic_read(&s->q_busy.buffers)-1) { - /* buffer must have fallen out of rotation */ - CX18_WARN("Skipped %s, buffer %d, %d " - "times - it must have dropped out of " - "rotation\n", s->name, buf->id, - buf->skipped); - /* move it to q_free */ - list_move_tail(&buf->list, &s->q_free.list); - buf->bytesused = buf->readpos = buf->b_flags = - buf->skipped = 0; - atomic_dec(&s->q_busy.buffers); - atomic_inc(&s->q_free.buffers); - } - continue; - } - - buf->bytesused = bytesused; - /* Sync the buffer before we release the qlock */ - cx18_buf_sync_for_cpu(s, buf); - if (s->type == CX18_ENC_STREAM_TYPE_TS) { - /* - * TS doesn't use q_full. As we pull the buffer off of - * the queue here, the caller will have to put it back. - */ - list_del_init(&buf->list); - } else { - /* Move buffer from q_busy to q_full */ - list_move_tail(&buf->list, &s->q_full.list); - set_bit(CX18_F_B_NEED_BUF_SWAP, &buf->b_flags); - s->q_full.bytesused += buf->bytesused; - atomic_inc(&s->q_full.buffers); - } - atomic_dec(&s->q_busy.buffers); - - ret = buf; - break; - } - mutex_unlock(&s->qlock); - return ret; -} - -/* Move all buffers of a queue to q_free, while flushing the buffers */ -static void cx18_queue_flush(struct cx18_stream *s, struct cx18_queue *q) -{ - struct cx18_buffer *buf; - - if (q == &s->q_free) - return; - - mutex_lock(&s->qlock); - while (!list_empty(&q->list)) { - buf = list_first_entry(&q->list, struct cx18_buffer, list); - list_move_tail(&buf->list, &s->q_free.list); - buf->bytesused = buf->readpos = buf->b_flags = buf->skipped = 0; - atomic_inc(&s->q_free.buffers); - } - cx18_queue_init(q); - mutex_unlock(&s->qlock); -} - -void cx18_flush_queues(struct cx18_stream *s) -{ - cx18_queue_flush(s, &s->q_busy); - cx18_queue_flush(s, &s->q_full); -} - -int cx18_stream_alloc(struct cx18_stream *s) -{ - struct cx18 *cx = s->cx; - int i; - - if (s->buffers == 0) - return 0; - - CX18_DEBUG_INFO("Allocate %s stream: %d x %d buffers (%dkB total)\n", - s->name, s->buffers, s->buf_size, - s->buffers * s->buf_size / 1024); - - if (((char __iomem *)&cx->scb->cpu_mdl[cx->mdl_offset + s->buffers] - - (char __iomem *)cx->scb) > SCB_RESERVED_SIZE) { - unsigned bufsz = (((char __iomem *)cx->scb) + SCB_RESERVED_SIZE - - ((char __iomem *)cx->scb->cpu_mdl)); - - CX18_ERR("Too many buffers, cannot fit in SCB area\n"); - CX18_ERR("Max buffers = %zd\n", - bufsz / sizeof(struct cx18_mdl)); - return -ENOMEM; - } - - s->mdl_offset = cx->mdl_offset; - - /* allocate stream buffers. Initially all buffers are in q_free. */ - for (i = 0; i < s->buffers; i++) { - struct cx18_buffer *buf = kzalloc(sizeof(struct cx18_buffer), - GFP_KERNEL|__GFP_NOWARN); - - if (buf == NULL) - break; - buf->buf = kmalloc(s->buf_size, GFP_KERNEL|__GFP_NOWARN); - if (buf->buf == NULL) { - kfree(buf); - break; - } - buf->id = cx->buffer_id++; - INIT_LIST_HEAD(&buf->list); - buf->dma_handle = pci_map_single(s->cx->dev, - buf->buf, s->buf_size, s->dma); - cx18_buf_sync_for_cpu(s, buf); - cx18_enqueue(s, buf, &s->q_free); - } - if (i == s->buffers) { - cx->mdl_offset += s->buffers; - return 0; - } - CX18_ERR("Couldn't allocate buffers for %s stream\n", s->name); - cx18_stream_free(s); - return -ENOMEM; -} - -void cx18_stream_free(struct cx18_stream *s) -{ - struct cx18_buffer *buf; - - /* move all buffers to q_free */ - cx18_flush_queues(s); - - /* empty q_free */ - while ((buf = cx18_dequeue(s, &s->q_free))) { - pci_unmap_single(s->cx->dev, buf->dma_handle, - s->buf_size, s->dma); - kfree(buf->buf); - kfree(buf); - } -} diff --git a/drivers/media/video/cx18/cx18-queue.h b/drivers/media/video/cx18/cx18-queue.h deleted file mode 100644 index 456cec3bc28..00000000000 --- a/drivers/media/video/cx18/cx18-queue.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - * cx18 buffer queues - * - * Derived from ivtv-queue.h - * - * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> - * Copyright (C) 2008 Andy Walls <awalls@radix.net> - * - * 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., 59 Temple Place, Suite 330, Boston, MA - * 02111-1307 USA - */ - -#define CX18_DMA_UNMAPPED ((u32) -1) - -/* cx18_buffer utility functions */ - -static inline void cx18_buf_sync_for_cpu(struct cx18_stream *s, - struct cx18_buffer *buf) -{ - pci_dma_sync_single_for_cpu(s->cx->dev, buf->dma_handle, - s->buf_size, s->dma); -} - -static inline void cx18_buf_sync_for_device(struct cx18_stream *s, - struct cx18_buffer *buf) -{ - pci_dma_sync_single_for_device(s->cx->dev, buf->dma_handle, - s->buf_size, s->dma); -} - -void cx18_buf_swap(struct cx18_buffer *buf); - -/* cx18_queue utility functions */ -struct cx18_queue *_cx18_enqueue(struct cx18_stream *s, struct cx18_buffer *buf, - struct cx18_queue *q, int to_front); - -static inline -struct cx18_queue *cx18_enqueue(struct cx18_stream *s, struct cx18_buffer *buf, - struct cx18_queue *q) -{ - return _cx18_enqueue(s, buf, q, 0); /* FIFO */ -} - -static inline -struct cx18_queue *cx18_push(struct cx18_stream *s, struct cx18_buffer *buf, - struct cx18_queue *q) -{ - return _cx18_enqueue(s, buf, q, 1); /* LIFO */ -} - -void cx18_queue_init(struct cx18_queue *q); -struct cx18_buffer *cx18_dequeue(struct cx18_stream *s, struct cx18_queue *q); -struct cx18_buffer *cx18_queue_get_buf(struct cx18_stream *s, u32 id, - u32 bytesused); -void cx18_flush_queues(struct cx18_stream *s); - -/* cx18_stream utility functions */ -int cx18_stream_alloc(struct cx18_stream *s); -void cx18_stream_free(struct cx18_stream *s); diff --git a/drivers/media/video/cx18/cx18-scb.c b/drivers/media/video/cx18/cx18-scb.c deleted file mode 100644 index 34b4d03c55c..00000000000 --- a/drivers/media/video/cx18/cx18-scb.c +++ /dev/null @@ -1,122 +0,0 @@ -/* - * cx18 System Control Block initialization - * - * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> - * Copyright (C) 2008 Andy Walls <awalls@radix.net> - * - * 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., 59 Temple Place, Suite 330, Boston, MA - * 02111-1307 USA - */ - -#include "cx18-driver.h" -#include "cx18-io.h" -#include "cx18-scb.h" - -void cx18_init_scb(struct cx18 *cx) -{ - cx18_setup_page(cx, SCB_OFFSET); - cx18_memset_io(cx, cx->scb, 0, 0x10000); - - cx18_writel(cx, IRQ_APU_TO_CPU, &cx->scb->apu2cpu_irq); - cx18_writel(cx, IRQ_CPU_TO_APU_ACK, &cx->scb->cpu2apu_irq_ack); - cx18_writel(cx, IRQ_HPU_TO_CPU, &cx->scb->hpu2cpu_irq); - cx18_writel(cx, IRQ_CPU_TO_HPU_ACK, &cx->scb->cpu2hpu_irq_ack); - cx18_writel(cx, IRQ_PPU_TO_CPU, &cx->scb->ppu2cpu_irq); - cx18_writel(cx, IRQ_CPU_TO_PPU_ACK, &cx->scb->cpu2ppu_irq_ack); - cx18_writel(cx, IRQ_EPU_TO_CPU, &cx->scb->epu2cpu_irq); - cx18_writel(cx, IRQ_CPU_TO_EPU_ACK, &cx->scb->cpu2epu_irq_ack); - - cx18_writel(cx, IRQ_CPU_TO_APU, &cx->scb->cpu2apu_irq); - cx18_writel(cx, IRQ_APU_TO_CPU_ACK, &cx->scb->apu2cpu_irq_ack); - cx18_writel(cx, IRQ_HPU_TO_APU, &cx->scb->hpu2apu_irq); - cx18_writel(cx, IRQ_APU_TO_HPU_ACK, &cx->scb->apu2hpu_irq_ack); - cx18_writel(cx, IRQ_PPU_TO_APU, &cx->scb->ppu2apu_irq); - cx18_writel(cx, IRQ_APU_TO_PPU_ACK, &cx->scb->apu2ppu_irq_ack); - cx18_writel(cx, IRQ_EPU_TO_APU, &cx->scb->epu2apu_irq); - cx18_writel(cx, IRQ_APU_TO_EPU_ACK, &cx->scb->apu2epu_irq_ack); - - cx18_writel(cx, IRQ_CPU_TO_HPU, &cx->scb->cpu2hpu_irq); - cx18_writel(cx, IRQ_HPU_TO_CPU_ACK, &cx->scb->hpu2cpu_irq_ack); - cx18_writel(cx, IRQ_APU_TO_HPU, &cx->scb->apu2hpu_irq); - cx18_writel(cx, IRQ_HPU_TO_APU_ACK, &cx->scb->hpu2apu_irq_ack); - cx18_writel(cx, IRQ_PPU_TO_HPU, &cx->scb->ppu2hpu_irq); - cx18_writel(cx, IRQ_HPU_TO_PPU_ACK, &cx->scb->hpu2ppu_irq_ack); - cx18_writel(cx, IRQ_EPU_TO_HPU, &cx->scb->epu2hpu_irq); - cx18_writel(cx, IRQ_HPU_TO_EPU_ACK, &cx->scb->hpu2epu_irq_ack); - - cx18_writel(cx, IRQ_CPU_TO_PPU, &cx->scb->cpu2ppu_irq); - cx18_writel(cx, IRQ_PPU_TO_CPU_ACK, &cx->scb->ppu2cpu_irq_ack); - cx18_writel(cx, IRQ_APU_TO_PPU, &cx->scb->apu2ppu_irq); - cx18_writel(cx, IRQ_PPU_TO_APU_ACK, &cx->scb->ppu2apu_irq_ack); - cx18_writel(cx, IRQ_HPU_TO_PPU, &cx->scb->hpu2ppu_irq); - cx18_writel(cx, IRQ_PPU_TO_HPU_ACK, &cx->scb->ppu2hpu_irq_ack); - cx18_writel(cx, IRQ_EPU_TO_PPU, &cx->scb->epu2ppu_irq); - cx18_writel(cx, IRQ_PPU_TO_EPU_ACK, &cx->scb->ppu2epu_irq_ack); - - cx18_writel(cx, IRQ_CPU_TO_EPU, &cx->scb->cpu2epu_irq); - cx18_writel(cx, IRQ_EPU_TO_CPU_ACK, &cx->scb->epu2cpu_irq_ack); - cx18_writel(cx, IRQ_APU_TO_EPU, &cx->scb->apu2epu_irq); - cx18_writel(cx, IRQ_EPU_TO_APU_ACK, &cx->scb->epu2apu_irq_ack); - cx18_writel(cx, IRQ_HPU_TO_EPU, &cx->scb->hpu2epu_irq); - cx18_writel(cx, IRQ_EPU_TO_HPU_ACK, &cx->scb->epu2hpu_irq_ack); - cx18_writel(cx, IRQ_PPU_TO_EPU, &cx->scb->ppu2epu_irq); - cx18_writel(cx, IRQ_EPU_TO_PPU_ACK, &cx->scb->epu2ppu_irq_ack); - - cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, apu2cpu_mb), - &cx->scb->apu2cpu_mb_offset); - cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, hpu2cpu_mb), - &cx->scb->hpu2cpu_mb_offset); - cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, ppu2cpu_mb), - &cx->scb->ppu2cpu_mb_offset); - cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, epu2cpu_mb), - &cx->scb->epu2cpu_mb_offset); - cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, cpu2apu_mb), - &cx->scb->cpu2apu_mb_offset); - cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, hpu2apu_mb), - &cx->scb->hpu2apu_mb_offset); - cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, ppu2apu_mb), - &cx->scb->ppu2apu_mb_offset); - cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, epu2apu_mb), - &cx->scb->epu2apu_mb_offset); - cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, cpu2hpu_mb), - &cx->scb->cpu2hpu_mb_offset); - cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, apu2hpu_mb), - &cx->scb->apu2hpu_mb_offset); - cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, ppu2hpu_mb), - &cx->scb->ppu2hpu_mb_offset); - cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, epu2hpu_mb), - &cx->scb->epu2hpu_mb_offset); - cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, cpu2ppu_mb), - &cx->scb->cpu2ppu_mb_offset); - cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, apu2ppu_mb), - &cx->scb->apu2ppu_mb_offset); - cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, hpu2ppu_mb), - &cx->scb->hpu2ppu_mb_offset); - cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, epu2ppu_mb), - &cx->scb->epu2ppu_mb_offset); - cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, cpu2epu_mb), - &cx->scb->cpu2epu_mb_offset); - cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, apu2epu_mb), - &cx->scb->apu2epu_mb_offset); - cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, hpu2epu_mb), - &cx->scb->hpu2epu_mb_offset); - cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, ppu2epu_mb), - &cx->scb->ppu2epu_mb_offset); - - cx18_writel(cx, SCB_OFFSET + offsetof(struct cx18_scb, cpu_state), - &cx->scb->ipc_offset); - - cx18_writel(cx, 1, &cx->scb->epu_state); -} diff --git a/drivers/media/video/cx18/cx18-scb.h b/drivers/media/video/cx18/cx18-scb.h deleted file mode 100644 index 1dc1c431f5a..00000000000 --- a/drivers/media/video/cx18/cx18-scb.h +++ /dev/null @@ -1,280 +0,0 @@ -/* - * cx18 System Control Block initialization - * - * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> - * Copyright (C) 2008 Andy Walls <awalls@radix.net> - * - * 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., 59 Temple Place, Suite 330, Boston, MA - * 02111-1307 USA - */ - -#ifndef CX18_SCB_H -#define CX18_SCB_H - -#include "cx18-mailbox.h" - -/* NOTE: All ACK interrupts are in the SW2 register. All non-ACK interrupts - are in the SW1 register. */ - -#define IRQ_APU_TO_CPU 0x00000001 -#define IRQ_CPU_TO_APU_ACK 0x00000001 -#define IRQ_HPU_TO_CPU 0x00000002 -#define IRQ_CPU_TO_HPU_ACK 0x00000002 -#define IRQ_PPU_TO_CPU 0x00000004 -#define IRQ_CPU_TO_PPU_ACK 0x00000004 -#define IRQ_EPU_TO_CPU 0x00000008 -#define IRQ_CPU_TO_EPU_ACK 0x00000008 - -#define IRQ_CPU_TO_APU 0x00000010 -#define IRQ_APU_TO_CPU_ACK 0x00000010 -#define IRQ_HPU_TO_APU 0x00000020 -#define IRQ_APU_TO_HPU_ACK 0x00000020 -#define IRQ_PPU_TO_APU 0x00000040 -#define IRQ_APU_TO_PPU_ACK 0x00000040 -#define IRQ_EPU_TO_APU 0x00000080 -#define IRQ_APU_TO_EPU_ACK 0x00000080 - -#define IRQ_CPU_TO_HPU 0x00000100 -#define IRQ_HPU_TO_CPU_ACK 0x00000100 -#define IRQ_APU_TO_HPU 0x00000200 -#define IRQ_HPU_TO_APU_ACK 0x00000200 -#define IRQ_PPU_TO_HPU 0x00000400 -#define IRQ_HPU_TO_PPU_ACK 0x00000400 -#define IRQ_EPU_TO_HPU 0x00000800 -#define IRQ_HPU_TO_EPU_ACK 0x00000800 - -#define IRQ_CPU_TO_PPU 0x00001000 -#define IRQ_PPU_TO_CPU_ACK 0x00001000 -#define IRQ_APU_TO_PPU 0x00002000 -#define IRQ_PPU_TO_APU_ACK 0x00002000 -#define IRQ_HPU_TO_PPU 0x00004000 -#define IRQ_PPU_TO_HPU_ACK 0x00004000 -#define IRQ_EPU_TO_PPU 0x00008000 -#define IRQ_PPU_TO_EPU_ACK 0x00008000 - -#define IRQ_CPU_TO_EPU 0x00010000 -#define IRQ_EPU_TO_CPU_ACK 0x00010000 -#define IRQ_APU_TO_EPU 0x00020000 -#define IRQ_EPU_TO_APU_ACK 0x00020000 -#define IRQ_HPU_TO_EPU 0x00040000 -#define IRQ_EPU_TO_HPU_ACK 0x00040000 -#define IRQ_PPU_TO_EPU 0x00080000 -#define IRQ_EPU_TO_PPU_ACK 0x00080000 - -#define SCB_OFFSET 0xDC0000 - -/* If Firmware uses fixed memory map, it shall not allocate the area - between SCB_OFFSET and SCB_OFFSET+SCB_RESERVED_SIZE-1 inclusive */ -#define SCB_RESERVED_SIZE 0x10000 - - -/* This structure is used by EPU to provide memory descriptors in its memory */ -struct cx18_mdl { - u32 paddr; /* Physical address of a buffer segment */ - u32 length; /* Length of the buffer segment */ -}; - -struct cx18_scb { - /* These fields form the System Control Block which is used at boot time - for localizing the IPC data as well as the code positions for all - processors. The offsets are from the start of this struct. */ - - /* Offset where to find the Inter-Processor Communication data */ - u32 ipc_offset; - u32 reserved01[7]; - /* Offset where to find the start of the CPU code */ - u32 cpu_code_offset; - u32 reserved02[3]; - /* Offset where to find the start of the APU code */ - u32 apu_code_offset; - u32 reserved03[3]; - /* Offset where to find the start of the HPU code */ - u32 hpu_code_offset; - u32 reserved04[3]; - /* Offset where to find the start of the PPU code */ - u32 ppu_code_offset; - u32 reserved05[3]; - - /* These fields form Inter-Processor Communication data which is used - by all processors to locate the information needed for communicating - with other processors */ - - /* Fields for CPU: */ - - /* bit 0: 1/0 processor ready/not ready. Set other bits to 0. */ - u32 cpu_state; - u32 reserved1[7]; - /* Offset to the mailbox used for sending commands from APU to CPU */ - u32 apu2cpu_mb_offset; - /* Value to write to register SW1 register set (0xC7003100) after the - command is ready */ - u32 apu2cpu_irq; - /* Value to write to register SW2 register set (0xC7003140) after the - command is cleared */ - u32 cpu2apu_irq_ack; - u32 reserved2[13]; - - u32 hpu2cpu_mb_offset; - u32 hpu2cpu_irq; - u32 cpu2hpu_irq_ack; - u32 reserved3[13]; - - u32 ppu2cpu_mb_offset; - u32 ppu2cpu_irq; - u32 cpu2ppu_irq_ack; - u32 reserved4[13]; - - u32 epu2cpu_mb_offset; - u32 epu2cpu_irq; - u32 cpu2epu_irq_ack; - u32 reserved5[13]; - u32 reserved6[8]; - - /* Fields for APU: */ - - u32 apu_state; - u32 reserved11[7]; - u32 cpu2apu_mb_offset; - u32 cpu2apu_irq; - u32 apu2cpu_irq_ack; - u32 reserved12[13]; - - u32 hpu2apu_mb_offset; - u32 hpu2apu_irq; - u32 apu2hpu_irq_ack; - u32 reserved13[13]; - - u32 ppu2apu_mb_offset; - u32 ppu2apu_irq; - u32 apu2ppu_irq_ack; - u32 reserved14[13]; - - u32 epu2apu_mb_offset; - u32 epu2apu_irq; - u32 apu2epu_irq_ack; - u32 reserved15[13]; - u32 reserved16[8]; - - /* Fields for HPU: */ - - u32 hpu_state; - u32 reserved21[7]; - u32 cpu2hpu_mb_offset; - u32 cpu2hpu_irq; - u32 hpu2cpu_irq_ack; - u32 reserved22[13]; - - u32 apu2hpu_mb_offset; - u32 apu2hpu_irq; - u32 hpu2apu_irq_ack; - u32 reserved23[13]; - - u32 ppu2hpu_mb_offset; - u32 ppu2hpu_irq; - u32 hpu2ppu_irq_ack; - u32 reserved24[13]; - - u32 epu2hpu_mb_offset; - u32 epu2hpu_irq; - u32 hpu2epu_irq_ack; - u32 reserved25[13]; - u32 reserved26[8]; - - /* Fields for PPU: */ - - u32 ppu_state; - u32 reserved31[7]; - u32 cpu2ppu_mb_offset; - u32 cpu2ppu_irq; - u32 ppu2cpu_irq_ack; - u32 reserved32[13]; - - u32 apu2ppu_mb_offset; - u32 apu2ppu_irq; - u32 ppu2apu_irq_ack; - u32 reserved33[13]; - - u32 hpu2ppu_mb_offset; - u32 hpu2ppu_irq; - u32 ppu2hpu_irq_ack; - u32 reserved34[13]; - - u32 epu2ppu_mb_offset; - u32 epu2ppu_irq; - u32 ppu2epu_irq_ack; - u32 reserved35[13]; - u32 reserved36[8]; - - /* Fields for EPU: */ - - u32 epu_state; - u32 reserved41[7]; - u32 cpu2epu_mb_offset; - u32 cpu2epu_irq; - u32 epu2cpu_irq_ack; - u32 reserved42[13]; - - u32 apu2epu_mb_offset; - u32 apu2epu_irq; - u32 epu2apu_irq_ack; - u32 reserved43[13]; - - u32 hpu2epu_mb_offset; - u32 hpu2epu_irq; - u32 epu2hpu_irq_ack; - u32 reserved44[13]; - - u32 ppu2epu_mb_offset; - u32 ppu2epu_irq; - u32 epu2ppu_irq_ack; - u32 reserved45[13]; - u32 reserved46[8]; - - u32 semaphores[8]; /* Semaphores */ - - u32 reserved50[32]; /* Reserved for future use */ - - struct cx18_mailbox apu2cpu_mb; - struct cx18_mailbox hpu2cpu_mb; - struct cx18_mailbox ppu2cpu_mb; - struct cx18_mailbox epu2cpu_mb; - - struct cx18_mailbox cpu2apu_mb; - struct cx18_mailbox hpu2apu_mb; - struct cx18_mailbox ppu2apu_mb; - struct cx18_mailbox epu2apu_mb; - - struct cx18_mailbox cpu2hpu_mb; - struct cx18_mailbox apu2hpu_mb; - struct cx18_mailbox ppu2hpu_mb; - struct cx18_mailbox epu2hpu_mb; - - struct cx18_mailbox cpu2ppu_mb; - struct cx18_mailbox apu2ppu_mb; - struct cx18_mailbox hpu2ppu_mb; - struct cx18_mailbox epu2ppu_mb; - - struct cx18_mailbox cpu2epu_mb; - struct cx18_mailbox apu2epu_mb; - struct cx18_mailbox hpu2epu_mb; - struct cx18_mailbox ppu2epu_mb; - - struct cx18_mdl_ack cpu_mdl_ack[CX18_MAX_STREAMS][CX18_MAX_MDL_ACKS]; - struct cx18_mdl cpu_mdl[1]; -}; - -void cx18_init_scb(struct cx18 *cx); - -#endif diff --git a/drivers/media/video/cx18/cx18-streams.c b/drivers/media/video/cx18/cx18-streams.c deleted file mode 100644 index 89c1ec94f33..00000000000 --- a/drivers/media/video/cx18/cx18-streams.c +++ /dev/null @@ -1,654 +0,0 @@ -/* - * cx18 init/start/stop/exit stream functions - * - * Derived from ivtv-streams.c - * - * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> - * Copyright (C) 2008 Andy Walls <awalls@radix.net> - * - * 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., 59 Temple Place, Suite 330, Boston, MA - * 02111-1307 USA - */ - -#include "cx18-driver.h" -#include "cx18-io.h" -#include "cx18-fileops.h" -#include "cx18-mailbox.h" -#include "cx18-i2c.h" -#include "cx18-queue.h" -#include "cx18-ioctl.h" -#include "cx18-streams.h" -#include "cx18-cards.h" -#include "cx18-scb.h" -#include "cx18-av-core.h" -#include "cx18-dvb.h" - -#define CX18_DSP0_INTERRUPT_MASK 0xd0004C - -static struct v4l2_file_operations cx18_v4l2_enc_fops = { - .owner = THIS_MODULE, - .read = cx18_v4l2_read, - .open = cx18_v4l2_open, - /* FIXME change to video_ioctl2 if serialization lock can be removed */ - .ioctl = cx18_v4l2_ioctl, - .release = cx18_v4l2_close, - .poll = cx18_v4l2_enc_poll, -}; - -/* offset from 0 to register ts v4l2 minors on */ -#define CX18_V4L2_ENC_TS_OFFSET 16 -/* offset from 0 to register pcm v4l2 minors on */ -#define CX18_V4L2_ENC_PCM_OFFSET 24 -/* offset from 0 to register yuv v4l2 minors on */ -#define CX18_V4L2_ENC_YUV_OFFSET 32 - -static struct { - const char *name; - int vfl_type; - int num_offset; - int dma; - enum v4l2_buf_type buf_type; -} cx18_stream_info[] = { - { /* CX18_ENC_STREAM_TYPE_MPG */ - "encoder MPEG", - VFL_TYPE_GRABBER, 0, - PCI_DMA_FROMDEVICE, V4L2_BUF_TYPE_VIDEO_CAPTURE, - }, - { /* CX18_ENC_STREAM_TYPE_TS */ - "TS", - VFL_TYPE_GRABBER, -1, - PCI_DMA_FROMDEVICE, V4L2_BUF_TYPE_VIDEO_CAPTURE, - }, - { /* CX18_ENC_STREAM_TYPE_YUV */ - "encoder YUV", - VFL_TYPE_GRABBER, CX18_V4L2_ENC_YUV_OFFSET, - PCI_DMA_FROMDEVICE, V4L2_BUF_TYPE_VIDEO_CAPTURE, - }, - { /* CX18_ENC_STREAM_TYPE_VBI */ - "encoder VBI", - VFL_TYPE_VBI, 0, - PCI_DMA_FROMDEVICE, V4L2_BUF_TYPE_VBI_CAPTURE, - }, - { /* CX18_ENC_STREAM_TYPE_PCM */ - "encoder PCM audio", - VFL_TYPE_GRABBER, CX18_V4L2_ENC_PCM_OFFSET, - PCI_DMA_FROMDEVICE, V4L2_BUF_TYPE_PRIVATE, - }, - { /* CX18_ENC_STREAM_TYPE_IDX */ - "encoder IDX", - VFL_TYPE_GRABBER, -1, - PCI_DMA_FROMDEVICE, V4L2_BUF_TYPE_VIDEO_CAPTURE, - }, - { /* CX18_ENC_STREAM_TYPE_RAD */ - "encoder radio", - VFL_TYPE_RADIO, 0, - PCI_DMA_NONE, V4L2_BUF_TYPE_PRIVATE, - }, -}; - -static void cx18_stream_init(struct cx18 *cx, int type) -{ - struct cx18_stream *s = &cx->streams[type]; - struct video_device *dev = s->v4l2dev; - - /* we need to keep v4l2dev, so restore it afterwards */ - memset(s, 0, sizeof(*s)); - s->v4l2dev = dev; - - /* initialize cx18_stream fields */ - s->cx = cx; - s->type = type; - s->name = cx18_stream_info[type].name; - s->handle = CX18_INVALID_TASK_HANDLE; - - s->dma = cx18_stream_info[type].dma; - s->buffers = cx->stream_buffers[type]; - s->buf_size = cx->stream_buf_size[type]; - - mutex_init(&s->qlock); - init_waitqueue_head(&s->waitq); - s->id = -1; - cx18_queue_init(&s->q_free); - cx18_queue_init(&s->q_busy); - cx18_queue_init(&s->q_full); -} - -static int cx18_prep_dev(struct cx18 *cx, int type) -{ - struct cx18_stream *s = &cx->streams[type]; - u32 cap = cx->v4l2_cap; - int num_offset = cx18_stream_info[type].num_offset; - int num = cx->num + cx18_first_minor + num_offset; - - /* These four fields are always initialized. If v4l2dev == NULL, then - this stream is not in use. In that case no other fields but these - four can be used. */ - s->v4l2dev = NULL; - s->cx = cx; - s->type = type; - s->name = cx18_stream_info[type].name; - - /* Check whether the radio is supported */ - if (type == CX18_ENC_STREAM_TYPE_RAD && !(cap & V4L2_CAP_RADIO)) - return 0; - - /* Check whether VBI is supported */ - if (type == CX18_ENC_STREAM_TYPE_VBI && - !(cap & (V4L2_CAP_VBI_CAPTURE | V4L2_CAP_SLICED_VBI_CAPTURE))) - return 0; - - /* User explicitly selected 0 buffers for these streams, so don't - create them. */ - if (cx18_stream_info[type].dma != PCI_DMA_NONE && - cx->stream_buffers[type] == 0) { - CX18_INFO("Disabled %s device\n", cx18_stream_info[type].name); - return 0; - } - - cx18_stream_init(cx, type); - - if (num_offset == -1) - return 0; - - /* allocate and initialize the v4l2 video device structure */ - s->v4l2dev = video_device_alloc(); - if (s->v4l2dev == NULL) { - CX18_ERR("Couldn't allocate v4l2 video_device for %s\n", - s->name); - return -ENOMEM; - } - - snprintf(s->v4l2dev->name, sizeof(s->v4l2dev->name), "cx18-%d", - cx->num); - - s->v4l2dev->num = num; - s->v4l2dev->parent = &cx->dev->dev; - s->v4l2dev->fops = &cx18_v4l2_enc_fops; - s->v4l2dev->release = video_device_release; - s->v4l2dev->tvnorms = V4L2_STD_ALL; - cx18_set_funcs(s->v4l2dev); - return 0; -} - -/* Initialize v4l2 variables and register v4l2 devices */ -int cx18_streams_setup(struct cx18 *cx) -{ - int type, ret; - - /* Setup V4L2 Devices */ - for (type = 0; type < CX18_MAX_STREAMS; type++) { - /* Prepare device */ - ret = cx18_prep_dev(cx, type); - if (ret < 0) - break; - - /* Allocate Stream */ - ret = cx18_stream_alloc(&cx->streams[type]); - if (ret < 0) - break; - } - if (type == CX18_MAX_STREAMS) - return 0; - - /* One or more streams could not be initialized. Clean 'em all up. */ - cx18_streams_cleanup(cx, 0); - return ret; -} - -static int cx18_reg_dev(struct cx18 *cx, int type) -{ - struct cx18_stream *s = &cx->streams[type]; - int vfl_type = cx18_stream_info[type].vfl_type; - int num, ret; - - /* TODO: Shouldn't this be a VFL_TYPE_TRANSPORT or something? - * We need a VFL_TYPE_TS defined. - */ - if (strcmp("TS", s->name) == 0) { - /* just return if no DVB is supported */ - if ((cx->card->hw_all & CX18_HW_DVB) == 0) - return 0; - ret = cx18_dvb_register(s); - if (ret < 0) { - CX18_ERR("DVB failed to register\n"); - return ret; - } - } - - if (s->v4l2dev == NULL) - return 0; - - num = s->v4l2dev->num; - /* card number + user defined offset + device offset */ - if (type != CX18_ENC_STREAM_TYPE_MPG) { - struct cx18_stream *s_mpg = &cx->streams[CX18_ENC_STREAM_TYPE_MPG]; - - if (s_mpg->v4l2dev) - num = s_mpg->v4l2dev->num + cx18_stream_info[type].num_offset; - } - - /* Register device. First try the desired minor, then any free one. */ - ret = video_register_device(s->v4l2dev, vfl_type, num); - if (ret < 0) { - CX18_ERR("Couldn't register v4l2 device for %s kernel number %d\n", - s->name, num); - video_device_release(s->v4l2dev); - s->v4l2dev = NULL; - return ret; - } - num = s->v4l2dev->num; - - switch (vfl_type) { - case VFL_TYPE_GRABBER: - CX18_INFO("Registered device video%d for %s (%d x %d kB)\n", - num, s->name, cx->stream_buffers[type], - cx->stream_buf_size[type]/1024); - break; - - case VFL_TYPE_RADIO: - CX18_INFO("Registered device radio%d for %s\n", - num, s->name); - break; - - case VFL_TYPE_VBI: - if (cx->stream_buffers[type]) - CX18_INFO("Registered device vbi%d for %s " - "(%d x %d bytes)\n", - num, s->name, cx->stream_buffers[type], - cx->stream_buf_size[type]); - else - CX18_INFO("Registered device vbi%d for %s\n", - num, s->name); - break; - } - - return 0; -} - -/* Register v4l2 devices */ -int cx18_streams_register(struct cx18 *cx) -{ - int type; - int err; - int ret = 0; - - /* Register V4L2 devices */ - for (type = 0; type < CX18_MAX_STREAMS; type++) { - err = cx18_reg_dev(cx, type); - if (err && ret == 0) - ret = err; - } - - if (ret == 0) - return 0; - - /* One or more streams could not be initialized. Clean 'em all up. */ - cx18_streams_cleanup(cx, 1); - return ret; -} - -/* Unregister v4l2 devices */ -void cx18_streams_cleanup(struct cx18 *cx, int unregister) -{ - struct video_device *vdev; - int type; - - /* Teardown all streams */ - for (type = 0; type < CX18_MAX_STREAMS; type++) { - if (cx->streams[type].dvb.enabled) { - cx18_dvb_unregister(&cx->streams[type]); - cx->streams[type].dvb.enabled = false; - } - - vdev = cx->streams[type].v4l2dev; - - cx->streams[type].v4l2dev = NULL; - if (vdev == NULL) - continue; - - cx18_stream_free(&cx->streams[type]); - - /* Unregister or release device */ - if (unregister) - video_unregister_device(vdev); - else - video_device_release(vdev); - } -} - -static void cx18_vbi_setup(struct cx18_stream *s) -{ - struct cx18 *cx = s->cx; - int raw = cx18_raw_vbi(cx); - u32 data[CX2341X_MBOX_MAX_DATA]; - int lines; - - if (cx->is_60hz) { - cx->vbi.count = 12; - cx->vbi.start[0] = 10; - cx->vbi.start[1] = 273; - } else { /* PAL/SECAM */ - cx->vbi.count = 18; - cx->vbi.start[0] = 6; - cx->vbi.start[1] = 318; - } - - /* setup VBI registers */ - cx18_av_cmd(cx, VIDIOC_S_FMT, &cx->vbi.in); - - /* determine number of lines and total number of VBI bytes. - A raw line takes 1444 bytes: 4 byte SAV code + 2 * 720 - A sliced line takes 51 bytes: 4 byte frame header, 4 byte internal - header, 42 data bytes + checksum (to be confirmed) */ - if (raw) { - lines = cx->vbi.count * 2; - } else { - lines = cx->is_60hz ? 24 : 38; - if (cx->is_60hz) - lines += 2; - } - - cx->vbi.enc_size = lines * - (raw ? cx->vbi.raw_size : cx->vbi.sliced_size); - - data[0] = s->handle; - /* Lines per field */ - data[1] = (lines / 2) | ((lines / 2) << 16); - /* bytes per line */ - data[2] = (raw ? cx->vbi.raw_decoder_line_size - : cx->vbi.sliced_decoder_line_size); - /* Every X number of frames a VBI interrupt arrives - (frames as in 25 or 30 fps) */ - data[3] = 1; - /* Setup VBI for the cx25840 digitizer */ - if (raw) { - data[4] = 0x20602060; - data[5] = 0x307090d0; - } else { - data[4] = 0xB0F0B0F0; - data[5] = 0xA0E0A0E0; - } - - CX18_DEBUG_INFO("Setup VBI h: %d lines %x bpl %d fr %d %x %x\n", - data[0], data[1], data[2], data[3], data[4], data[5]); - - if (s->type == CX18_ENC_STREAM_TYPE_VBI) - cx18_api(cx, CX18_CPU_SET_RAW_VBI_PARAM, 6, data); -} - -struct cx18_queue *cx18_stream_put_buf_fw(struct cx18_stream *s, - struct cx18_buffer *buf) -{ - struct cx18 *cx = s->cx; - struct cx18_queue *q; - - /* Don't give it to the firmware, if we're not running a capture */ - if (s->handle == CX18_INVALID_TASK_HANDLE || - !test_bit(CX18_F_S_STREAMING, &s->s_flags)) - return cx18_enqueue(s, buf, &s->q_free); - - q = cx18_enqueue(s, buf, &s->q_busy); - if (q != &s->q_busy) - return q; /* The firmware has the max buffers it can handle */ - - cx18_buf_sync_for_device(s, buf); - cx18_vapi(cx, CX18_CPU_DE_SET_MDL, 5, s->handle, - (void __iomem *) &cx->scb->cpu_mdl[buf->id] - cx->enc_mem, - 1, buf->id, s->buf_size); - return q; -} - -void cx18_stream_load_fw_queue(struct cx18_stream *s) -{ - struct cx18_queue *q; - struct cx18_buffer *buf; - - if (atomic_read(&s->q_free.buffers) == 0 || - atomic_read(&s->q_busy.buffers) >= CX18_MAX_FW_MDLS_PER_STREAM) - return; - - /* Move from q_free to q_busy notifying the firmware, until the limit */ - do { - buf = cx18_dequeue(s, &s->q_free); - if (buf == NULL) - break; - q = cx18_stream_put_buf_fw(s, buf); - } while (atomic_read(&s->q_busy.buffers) < CX18_MAX_FW_MDLS_PER_STREAM - && q == &s->q_busy); -} - -int cx18_start_v4l2_encode_stream(struct cx18_stream *s) -{ - u32 data[MAX_MB_ARGUMENTS]; - struct cx18 *cx = s->cx; - struct cx18_buffer *buf; - int ts = 0; - int captype = 0; - - if (s->v4l2dev == NULL && s->dvb.enabled == 0) - return -EINVAL; - - CX18_DEBUG_INFO("Start encoder stream %s\n", s->name); - - switch (s->type) { - case CX18_ENC_STREAM_TYPE_MPG: - captype = CAPTURE_CHANNEL_TYPE_MPEG; - cx->mpg_data_received = cx->vbi_data_inserted = 0; - cx->dualwatch_jiffies = jiffies; - cx->dualwatch_stereo_mode = cx->params.audio_properties & 0x300; - cx->search_pack_header = 0; - break; - - case CX18_ENC_STREAM_TYPE_TS: - captype = CAPTURE_CHANNEL_TYPE_TS; - ts = 1; - break; - case CX18_ENC_STREAM_TYPE_YUV: - captype = CAPTURE_CHANNEL_TYPE_YUV; - break; - case CX18_ENC_STREAM_TYPE_PCM: - captype = CAPTURE_CHANNEL_TYPE_PCM; - break; - case CX18_ENC_STREAM_TYPE_VBI: - captype = cx18_raw_vbi(cx) ? - CAPTURE_CHANNEL_TYPE_VBI : CAPTURE_CHANNEL_TYPE_SLICED_VBI; - cx->vbi.frame = 0; - cx->vbi.inserted_frame = 0; - memset(cx->vbi.sliced_mpeg_size, - 0, sizeof(cx->vbi.sliced_mpeg_size)); - break; - default: - return -EINVAL; - } - - /* mute/unmute video */ - cx18_vapi(cx, CX18_CPU_SET_VIDEO_MUTE, 2, - s->handle, !!test_bit(CX18_F_I_RADIO_USER, &cx->i_flags)); - - /* Clear Streamoff flags in case left from last capture */ - clear_bit(CX18_F_S_STREAMOFF, &s->s_flags); - - cx18_vapi_result(cx, data, CX18_CREATE_TASK, 1, CPU_CMD_MASK_CAPTURE); - s->handle = data[0]; - cx18_vapi(cx, CX18_CPU_SET_CHANNEL_TYPE, 2, s->handle, captype); - - if (atomic_read(&cx->ana_capturing) == 0 && !ts) { - struct cx18_api_func_private priv; - - /* Stuff from Windows, we don't know what it is */ - cx18_vapi(cx, CX18_CPU_SET_VER_CROP_LINE, 2, s->handle, 0); - cx18_vapi(cx, CX18_CPU_SET_MISC_PARAMETERS, 3, s->handle, 3, 1); - cx18_vapi(cx, CX18_CPU_SET_MISC_PARAMETERS, 3, s->handle, 8, 0); - cx18_vapi(cx, CX18_CPU_SET_MISC_PARAMETERS, 3, s->handle, 4, 1); - cx18_vapi(cx, CX18_CPU_SET_MISC_PARAMETERS, 2, s->handle, 12); - - cx18_vapi(cx, CX18_CPU_SET_CAPTURE_LINE_NO, 3, - s->handle, cx->digitizer, cx->digitizer); - - /* Setup VBI */ - if (cx->v4l2_cap & V4L2_CAP_VBI_CAPTURE) - cx18_vbi_setup(s); - - /* assign program index info. - Mask 7: select I/P/B, Num_req: 400 max */ - cx18_vapi_result(cx, data, CX18_CPU_SET_INDEXTABLE, 1, 0); - - /* Setup API for Stream */ - priv.cx = cx; - priv.s = s; - cx2341x_update(&priv, cx18_api_func, NULL, &cx->params); - } - - if (atomic_read(&cx->tot_capturing) == 0) { - clear_bit(CX18_F_I_EOS, &cx->i_flags); - cx18_write_reg(cx, 7, CX18_DSP0_INTERRUPT_MASK); - } - - cx18_vapi(cx, CX18_CPU_DE_SET_MDL_ACK, 3, s->handle, - (void __iomem *)&cx->scb->cpu_mdl_ack[s->type][0] - cx->enc_mem, - (void __iomem *)&cx->scb->cpu_mdl_ack[s->type][1] - cx->enc_mem); - - /* Init all the cpu_mdls for this stream */ - cx18_flush_queues(s); - mutex_lock(&s->qlock); - list_for_each_entry(buf, &s->q_free.list, list) { - cx18_writel(cx, buf->dma_handle, - &cx->scb->cpu_mdl[buf->id].paddr); - cx18_writel(cx, s->buf_size, &cx->scb->cpu_mdl[buf->id].length); - } - mutex_unlock(&s->qlock); - cx18_stream_load_fw_queue(s); - - /* begin_capture */ - if (cx18_vapi(cx, CX18_CPU_CAPTURE_START, 1, s->handle)) { - CX18_DEBUG_WARN("Error starting capture!\n"); - /* Ensure we're really not capturing before releasing MDLs */ - if (s->type == CX18_ENC_STREAM_TYPE_MPG) - cx18_vapi(cx, CX18_CPU_CAPTURE_STOP, 2, s->handle, 1); - else - cx18_vapi(cx, CX18_CPU_CAPTURE_STOP, 1, s->handle); - clear_bit(CX18_F_S_STREAMING, &s->s_flags); - /* FIXME - CX18_F_S_STREAMOFF as well? */ - cx18_vapi(cx, CX18_CPU_DE_RELEASE_MDL, 1, s->handle); - cx18_vapi(cx, CX18_DESTROY_TASK, 1, s->handle); - s->handle = CX18_INVALID_TASK_HANDLE; - if (atomic_read(&cx->tot_capturing) == 0) { - set_bit(CX18_F_I_EOS, &cx->i_flags); - cx18_write_reg(cx, 5, CX18_DSP0_INTERRUPT_MASK); - } - return -EINVAL; - } - - /* you're live! sit back and await interrupts :) */ - if (!ts) - atomic_inc(&cx->ana_capturing); - atomic_inc(&cx->tot_capturing); - return 0; -} - -void cx18_stop_all_captures(struct cx18 *cx) -{ - int i; - - for (i = CX18_MAX_STREAMS - 1; i >= 0; i--) { - struct cx18_stream *s = &cx->streams[i]; - - if (s->v4l2dev == NULL && s->dvb.enabled == 0) - continue; - if (test_bit(CX18_F_S_STREAMING, &s->s_flags)) - cx18_stop_v4l2_encode_stream(s, 0); - } -} - -int cx18_stop_v4l2_encode_stream(struct cx18_stream *s, int gop_end) -{ - struct cx18 *cx = s->cx; - unsigned long then; - - if (s->v4l2dev == NULL && s->dvb.enabled == 0) - return -EINVAL; - - /* This function assumes that you are allowed to stop the capture - and that we are actually capturing */ - - CX18_DEBUG_INFO("Stop Capture\n"); - - if (atomic_read(&cx->tot_capturing) == 0) - return 0; - - if (s->type == CX18_ENC_STREAM_TYPE_MPG) - cx18_vapi(cx, CX18_CPU_CAPTURE_STOP, 2, s->handle, !gop_end); - else - cx18_vapi(cx, CX18_CPU_CAPTURE_STOP, 1, s->handle); - - then = jiffies; - - if (s->type == CX18_ENC_STREAM_TYPE_MPG && gop_end) { - CX18_INFO("ignoring gop_end: not (yet?) supported by the firmware\n"); - } - - if (s->type != CX18_ENC_STREAM_TYPE_TS) - atomic_dec(&cx->ana_capturing); - atomic_dec(&cx->tot_capturing); - - /* Clear capture and no-read bits */ - clear_bit(CX18_F_S_STREAMING, &s->s_flags); - - /* Tell the CX23418 it can't use our buffers anymore */ - cx18_vapi(cx, CX18_CPU_DE_RELEASE_MDL, 1, s->handle); - - cx18_vapi(cx, CX18_DESTROY_TASK, 1, s->handle); - s->handle = CX18_INVALID_TASK_HANDLE; - - if (atomic_read(&cx->tot_capturing) > 0) - return 0; - - cx18_write_reg(cx, 5, CX18_DSP0_INTERRUPT_MASK); - wake_up(&s->waitq); - - return 0; -} - -u32 cx18_find_handle(struct cx18 *cx) -{ - int i; - - /* find first available handle to be used for global settings */ - for (i = 0; i < CX18_MAX_STREAMS; i++) { - struct cx18_stream *s = &cx->streams[i]; - - if (s->v4l2dev && (s->handle != CX18_INVALID_TASK_HANDLE)) - return s->handle; - } - return CX18_INVALID_TASK_HANDLE; -} - -struct cx18_stream *cx18_handle_to_stream(struct cx18 *cx, u32 handle) -{ - int i; - struct cx18_stream *s; - - if (handle == CX18_INVALID_TASK_HANDLE) - return NULL; - - for (i = 0; i < CX18_MAX_STREAMS; i++) { - s = &cx->streams[i]; - if (s->handle != handle) - continue; - if (s->v4l2dev || s->dvb.enabled) - return s; - } - return NULL; -} diff --git a/drivers/media/video/cx18/cx18-streams.h b/drivers/media/video/cx18/cx18-streams.h deleted file mode 100644 index 420e0a17294..00000000000 --- a/drivers/media/video/cx18/cx18-streams.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * cx18 init/start/stop/exit stream functions - * - * Derived from ivtv-streams.h - * - * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> - * Copyright (C) 2008 Andy Walls <awalls@radix.net> - * - * 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., 59 Temple Place, Suite 330, Boston, MA - * 02111-1307 USA - */ - -u32 cx18_find_handle(struct cx18 *cx); -struct cx18_stream *cx18_handle_to_stream(struct cx18 *cx, u32 handle); -int cx18_streams_setup(struct cx18 *cx); -int cx18_streams_register(struct cx18 *cx); -void cx18_streams_cleanup(struct cx18 *cx, int unregister); - -/* Capture related */ -void cx18_stream_load_fw_queue(struct cx18_stream *s); -struct cx18_queue *cx18_stream_put_buf_fw(struct cx18_stream *s, - struct cx18_buffer *buf); -int cx18_start_v4l2_encode_stream(struct cx18_stream *s); -int cx18_stop_v4l2_encode_stream(struct cx18_stream *s, int gop_end); - -void cx18_stop_all_captures(struct cx18 *cx); diff --git a/drivers/media/video/cx18/cx18-vbi.c b/drivers/media/video/cx18/cx18-vbi.c deleted file mode 100644 index fb595bd548e..00000000000 --- a/drivers/media/video/cx18/cx18-vbi.c +++ /dev/null @@ -1,211 +0,0 @@ -/* - * cx18 Vertical Blank Interval support functions - * - * Derived from ivtv-vbi.c - * - * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> - * - * 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., 59 Temple Place, Suite 330, Boston, MA - * 02111-1307 USA - */ - -#include "cx18-driver.h" -#include "cx18-vbi.h" -#include "cx18-ioctl.h" -#include "cx18-queue.h" -#include "cx18-av-core.h" - -static void copy_vbi_data(struct cx18 *cx, int lines, u32 pts_stamp) -{ - int line = 0; - int i; - u32 linemask[2] = { 0, 0 }; - unsigned short size; - static const u8 mpeg_hdr_data[] = { - 0x00, 0x00, 0x01, 0xba, 0x44, 0x00, 0x0c, 0x66, - 0x24, 0x01, 0x01, 0xd1, 0xd3, 0xfa, 0xff, 0xff, - 0x00, 0x00, 0x01, 0xbd, 0x00, 0x1a, 0x84, 0x80, - 0x07, 0x21, 0x00, 0x5d, 0x63, 0xa7, 0xff, 0xff - }; - const int sd = sizeof(mpeg_hdr_data); /* start of vbi data */ - int idx = cx->vbi.frame % CX18_VBI_FRAMES; - u8 *dst = &cx->vbi.sliced_mpeg_data[idx][0]; - - for (i = 0; i < lines; i++) { - struct v4l2_sliced_vbi_data *sdata = cx->vbi.sliced_data + i; - int f, l; - - if (sdata->id == 0) - continue; - - l = sdata->line - 6; - f = sdata->field; - if (f) - l += 18; - if (l < 32) - linemask[0] |= (1 << l); - else - linemask[1] |= (1 << (l - 32)); - dst[sd + 12 + line * 43] = cx18_service2vbi(sdata->id); - memcpy(dst + sd + 12 + line * 43 + 1, sdata->data, 42); - line++; - } - memcpy(dst, mpeg_hdr_data, sizeof(mpeg_hdr_data)); - if (line == 36) { - /* All lines are used, so there is no space for the linemask - (the max size of the VBI data is 36 * 43 + 4 bytes). - So in this case we use the magic number 'ITV0'. */ - memcpy(dst + sd, "ITV0", 4); - memcpy(dst + sd + 4, dst + sd + 12, line * 43); - size = 4 + ((43 * line + 3) & ~3); - } else { - memcpy(dst + sd, "cx0", 4); - memcpy(dst + sd + 4, &linemask[0], 8); - size = 12 + ((43 * line + 3) & ~3); - } - dst[4+16] = (size + 10) >> 8; - dst[5+16] = (size + 10) & 0xff; - dst[9+16] = 0x21 | ((pts_stamp >> 29) & 0x6); - dst[10+16] = (pts_stamp >> 22) & 0xff; - dst[11+16] = 1 | ((pts_stamp >> 14) & 0xff); - dst[12+16] = (pts_stamp >> 7) & 0xff; - dst[13+16] = 1 | ((pts_stamp & 0x7f) << 1); - cx->vbi.sliced_mpeg_size[idx] = sd + size; -} - -/* Compress raw VBI format, removes leading SAV codes and surplus space - after the field. - Returns new compressed size. */ -static u32 compress_raw_buf(struct cx18 *cx, u8 *buf, u32 size) -{ - u32 line_size = cx->vbi.raw_decoder_line_size; - u32 lines = cx->vbi.count; - u8 sav1 = cx->vbi.raw_decoder_sav_odd_field; - u8 sav2 = cx->vbi.raw_decoder_sav_even_field; - u8 *q = buf; - u8 *p; - int i; - - for (i = 0; i < lines; i++) { - p = buf + i * line_size; - - /* Look for SAV code */ - if (p[0] != 0xff || p[1] || p[2] || - (p[3] != sav1 && p[3] != sav2)) - break; - memcpy(q, p + 4, line_size - 4); - q += line_size - 4; - } - return lines * (line_size - 4); -} - - -/* Compressed VBI format, all found sliced blocks put next to one another - Returns new compressed size */ -static u32 compress_sliced_buf(struct cx18 *cx, u32 line, u8 *buf, - u32 size, u8 sav) -{ - u32 line_size = cx->vbi.sliced_decoder_line_size; - struct v4l2_decode_vbi_line vbi; - int i; - - /* find the first valid line */ - for (i = 0; i < size; i++, buf++) { - if (buf[0] == 0xff && !buf[1] && !buf[2] && buf[3] == sav) - break; - } - - size -= i; - if (size < line_size) - return line; - for (i = 0; i < size / line_size; i++) { - u8 *p = buf + i * line_size; - - /* Look for SAV code */ - if (p[0] != 0xff || p[1] || p[2] || p[3] != sav) - continue; - vbi.p = p + 4; - cx18_av_cmd(cx, VIDIOC_INT_DECODE_VBI_LINE, &vbi); - if (vbi.type) { - cx->vbi.sliced_data[line].id = vbi.type; - cx->vbi.sliced_data[line].field = vbi.is_second_field; - cx->vbi.sliced_data[line].line = vbi.line; - memcpy(cx->vbi.sliced_data[line].data, vbi.p, 42); - line++; - } - } - return line; -} - -void cx18_process_vbi_data(struct cx18 *cx, struct cx18_buffer *buf, - u64 pts_stamp, int streamtype) -{ - u8 *p = (u8 *) buf->buf; - u32 size = buf->bytesused; - int lines; - - if (streamtype != CX18_ENC_STREAM_TYPE_VBI) - return; - - /* Raw VBI data */ - if (cx18_raw_vbi(cx)) { - u8 type; - - cx18_buf_swap(buf); - - /* Skip 12 bytes of header that gets stuffed in */ - size -= 12; - memcpy(p, &buf->buf[12], size); - type = p[3]; - - size = buf->bytesused = compress_raw_buf(cx, p, size); - - /* second field of the frame? */ - if (type == cx->vbi.raw_decoder_sav_even_field) { - /* Dirty hack needed for backwards - compatibility of old VBI software. */ - p += size - 4; - memcpy(p, &cx->vbi.frame, 4); - cx->vbi.frame++; - } - return; - } - - /* Sliced VBI data with data insertion */ - cx18_buf_swap(buf); - - /* first field */ - lines = compress_sliced_buf(cx, 0, p, size / 2, - cx->vbi.sliced_decoder_sav_odd_field); - /* second field */ - /* experimentation shows that the second half does not always - begin at the exact address. So start a bit earlier - (hence 32). */ - lines = compress_sliced_buf(cx, lines, p + size / 2 - 32, - size / 2 + 32, cx->vbi.sliced_decoder_sav_even_field); - /* always return at least one empty line */ - if (lines == 0) { - cx->vbi.sliced_data[0].id = 0; - cx->vbi.sliced_data[0].line = 0; - cx->vbi.sliced_data[0].field = 0; - lines = 1; - } - buf->bytesused = size = lines * sizeof(cx->vbi.sliced_data[0]); - memcpy(p, &cx->vbi.sliced_data[0], size); - - if (cx->vbi.insert_mpeg) - copy_vbi_data(cx, lines, pts_stamp); - cx->vbi.frame++; -} diff --git a/drivers/media/video/cx18/cx18-vbi.h b/drivers/media/video/cx18/cx18-vbi.h deleted file mode 100644 index c56ff7d28f2..00000000000 --- a/drivers/media/video/cx18/cx18-vbi.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * cx18 Vertical Blank Interval support functions - * - * Derived from ivtv-vbi.h - * - * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> - * - * 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., 59 Temple Place, Suite 330, Boston, MA - * 02111-1307 USA - */ - -void cx18_process_vbi_data(struct cx18 *cx, struct cx18_buffer *buf, - u64 pts_stamp, int streamtype); -int cx18_used_line(struct cx18 *cx, int line, int field); diff --git a/drivers/media/video/cx18/cx18-version.h b/drivers/media/video/cx18/cx18-version.h deleted file mode 100644 index 84c0ff13b60..00000000000 --- a/drivers/media/video/cx18/cx18-version.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * cx18 driver version information - * - * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> - * - * 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., 59 Temple Place, Suite 330, Boston, MA - * 02111-1307 USA - */ - -#ifndef CX18_VERSION_H -#define CX18_VERSION_H - -#define CX18_DRIVER_NAME "cx18" -#define CX18_DRIVER_VERSION_MAJOR 1 -#define CX18_DRIVER_VERSION_MINOR 0 -#define CX18_DRIVER_VERSION_PATCHLEVEL 4 - -#define CX18_VERSION __stringify(CX18_DRIVER_VERSION_MAJOR) "." __stringify(CX18_DRIVER_VERSION_MINOR) "." __stringify(CX18_DRIVER_VERSION_PATCHLEVEL) -#define CX18_DRIVER_VERSION KERNEL_VERSION(CX18_DRIVER_VERSION_MAJOR, \ - CX18_DRIVER_VERSION_MINOR, CX18_DRIVER_VERSION_PATCHLEVEL) - -#endif diff --git a/drivers/media/video/cx18/cx18-video.c b/drivers/media/video/cx18/cx18-video.c deleted file mode 100644 index 2e5c4193933..00000000000 --- a/drivers/media/video/cx18/cx18-video.c +++ /dev/null @@ -1,45 +0,0 @@ -/* - * cx18 video interface functions - * - * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> - * - * 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., 59 Temple Place, Suite 330, Boston, MA - * 02111-1307 USA - */ - -#include "cx18-driver.h" -#include "cx18-video.h" -#include "cx18-av-core.h" -#include "cx18-cards.h" - -void cx18_video_set_io(struct cx18 *cx) -{ - struct v4l2_routing route; - int inp = cx->active_input; - u32 type; - - route.input = cx->card->video_inputs[inp].video_input; - route.output = 0; - cx18_av_cmd(cx, VIDIOC_INT_S_VIDEO_ROUTING, &route); - - type = cx->card->video_inputs[inp].video_type; - - if (type == CX18_CARD_INPUT_VID_TUNER) - route.input = 0; /* Tuner */ - else if (type < CX18_CARD_INPUT_COMPOSITE1) - route.input = 2; /* S-Video */ - else - route.input = 1; /* Composite */ -} diff --git a/drivers/media/video/cx18/cx18-video.h b/drivers/media/video/cx18/cx18-video.h deleted file mode 100644 index 529006a06e5..00000000000 --- a/drivers/media/video/cx18/cx18-video.h +++ /dev/null @@ -1,22 +0,0 @@ -/* - * cx18 video interface functions - * - * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> - * - * 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., 59 Temple Place, Suite 330, Boston, MA - * 02111-1307 USA - */ - -void cx18_video_set_io(struct cx18 *cx); diff --git a/drivers/media/video/cx18/cx23418.h b/drivers/media/video/cx18/cx23418.h deleted file mode 100644 index 601f3a2ab74..00000000000 --- a/drivers/media/video/cx18/cx23418.h +++ /dev/null @@ -1,469 +0,0 @@ -/* - * cx18 header containing common defines. - * - * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> - * - * 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., 59 Temple Place, Suite 330, Boston, MA - * 02111-1307 USA - */ - -#ifndef CX23418_H -#define CX23418_H - -#include <media/cx2341x.h> - -#define MGR_CMD_MASK 0x40000000 -/* The MSB of the command code indicates that this is the completion of a - command */ -#define MGR_CMD_MASK_ACK (MGR_CMD_MASK | 0x80000000) - -/* Description: This command creates a new instance of a certain task - IN[0] - Task ID. This is one of the XPU_CMD_MASK_YYY where XPU is - the processor on which the task YYY will be created - OUT[0] - Task handle. This handle is passed along with commands to - dispatch to the right instance of the task - ReturnCode - One of the ERR_SYS_... */ -#define CX18_CREATE_TASK (MGR_CMD_MASK | 0x0001) - -/* Description: This command destroys an instance of a task - IN[0] - Task handle. Hanlde of the task to destroy - ReturnCode - One of the ERR_SYS_... */ -#define CX18_DESTROY_TASK (MGR_CMD_MASK | 0x0002) - -/* All commands for CPU have the following mask set */ -#define CPU_CMD_MASK 0x20000000 -#define CPU_CMD_MASK_DEBUG (CPU_CMD_MASK | 0x00000000) -#define CPU_CMD_MASK_ACK (CPU_CMD_MASK | 0x80000000) -#define CPU_CMD_MASK_CAPTURE (CPU_CMD_MASK | 0x00020000) -#define CPU_CMD_MASK_TS (CPU_CMD_MASK | 0x00040000) - -#define EPU_CMD_MASK 0x02000000 -#define EPU_CMD_MASK_DEBUG (EPU_CMD_MASK | 0x000000) -#define EPU_CMD_MASK_DE (EPU_CMD_MASK | 0x040000) - -#define APU_CMD_MASK 0x10000000 -#define APU_CMD_MASK_ACK (APU_CMD_MASK | 0x80000000) - -#define CX18_APU_RESETAI (APU_CMD_MASK | 0x05) - -/* Description: This command indicates that a Memory Descriptor List has been - filled with the requested channel type - IN[0] - Task handle. Handle of the task - IN[1] - Offset of the MDL_ACK from the beginning of the local DDR. - IN[2] - Number of CNXT_MDL_ACK structures in the array pointed to by IN[1] - ReturnCode - One of the ERR_DE_... */ -#define CX18_EPU_DMA_DONE (EPU_CMD_MASK_DE | 0x0001) - -/* Something interesting happened - IN[0] - A value to log - IN[1] - An offset of a string in the MiniMe memory; - 0/zero/NULL means "I have nothing to say" */ -#define CX18_EPU_DEBUG (EPU_CMD_MASK_DEBUG | 0x0003) - -/* Reads memory/registers (32-bit) - IN[0] - Address - OUT[1] - Value */ -#define CX18_CPU_DEBUG_PEEK32 (CPU_CMD_MASK_DEBUG | 0x0003) - -/* Description: This command starts streaming with the set channel type - IN[0] - Task handle. Handle of the task to start - ReturnCode - One of the ERR_CAPTURE_... */ -#define CX18_CPU_CAPTURE_START (CPU_CMD_MASK_CAPTURE | 0x0002) - -/* Description: This command stops streaming with the set channel type - IN[0] - Task handle. Handle of the task to stop - IN[1] - 0 = stop at end of GOP, 1 = stop at end of frame (MPEG only) - ReturnCode - One of the ERR_CAPTURE_... */ -#define CX18_CPU_CAPTURE_STOP (CPU_CMD_MASK_CAPTURE | 0x0003) - -/* Description: This command pauses streaming with the set channel type - IN[0] - Task handle. Handle of the task to pause - ReturnCode - One of the ERR_CAPTURE_... */ -#define CX18_CPU_CAPTURE_PAUSE (CPU_CMD_MASK_CAPTURE | 0x0007) - -/* Description: This command resumes streaming with the set channel type - IN[0] - Task handle. Handle of the task to resume - ReturnCode - One of the ERR_CAPTURE_... */ -#define CX18_CPU_CAPTURE_RESUME (CPU_CMD_MASK_CAPTURE | 0x0008) - -#define CAPTURE_CHANNEL_TYPE_NONE 0 -#define CAPTURE_CHANNEL_TYPE_MPEG 1 -#define CAPTURE_CHANNEL_TYPE_INDEX 2 -#define CAPTURE_CHANNEL_TYPE_YUV 3 -#define CAPTURE_CHANNEL_TYPE_PCM 4 -#define CAPTURE_CHANNEL_TYPE_VBI 5 -#define CAPTURE_CHANNEL_TYPE_SLICED_VBI 6 -#define CAPTURE_CHANNEL_TYPE_TS 7 -#define CAPTURE_CHANNEL_TYPE_MAX 15 - -/* Description: This command sets the channel type. This can only be done - when stopped. - IN[0] - Task handle. Handle of the task to start - IN[1] - Channel Type. See Below. - ReturnCode - One of the ERR_CAPTURE_... */ -#define CX18_CPU_SET_CHANNEL_TYPE (CPU_CMD_MASK_CAPTURE + 1) - -/* Description: Set stream output type - IN[0] - task handle. Handle of the task to start - IN[1] - type - ReturnCode - One of the ERR_CAPTURE_... */ -#define CX18_CPU_SET_STREAM_OUTPUT_TYPE (CPU_CMD_MASK_CAPTURE | 0x0012) - -/* Description: Set video input resolution and frame rate - IN[0] - task handle - IN[1] - reserved - IN[2] - reserved - IN[3] - reserved - IN[4] - reserved - IN[5] - frame rate, 0 - 29.97f/s, 1 - 25f/s - ReturnCode - One of the ERR_CAPTURE_... */ -#define CX18_CPU_SET_VIDEO_IN (CPU_CMD_MASK_CAPTURE | 0x0004) - -/* Description: Set video frame rate - IN[0] - task handle. Handle of the task to start - IN[1] - video bit rate mode - IN[2] - video average rate - IN[3] - video peak rate - IN[4] - system mux rate - ReturnCode - One of the ERR_CAPTURE_... */ -#define CX18_CPU_SET_VIDEO_RATE (CPU_CMD_MASK_CAPTURE | 0x0005) - -/* Description: Set video output resolution - IN[0] - task handle - IN[1] - horizontal size - IN[2] - vertical size - ReturnCode - One of the ERR_CAPTURE_... */ -#define CX18_CPU_SET_VIDEO_RESOLUTION (CPU_CMD_MASK_CAPTURE | 0x0006) - -/* Description: This command set filter parameters - IN[0] - Task handle. Handle of the task - IN[1] - type, 0 - temporal, 1 - spatial, 2 - median - IN[2] - mode, temporal/spatial: 0 - disable, 1 - static, 2 - dynamic - median: 0 = disable, 1 = horizontal, 2 = vertical, - 3 = horizontal/vertical, 4 = diagonal - IN[3] - strength, temporal 0 - 31, spatial 0 - 15 - ReturnCode - One of the ERR_CAPTURE_... */ -#define CX18_CPU_SET_FILTER_PARAM (CPU_CMD_MASK_CAPTURE | 0x0009) - -/* Description: This command set spatial filter type - IN[0] - Task handle. - IN[1] - luma type: 0 = disable, 1 = 1D horizontal only, 2 = 1D vertical only, - 3 = 2D H/V separable, 4 = 2D symmetric non-separable - IN[2] - chroma type: 0 - diable, 1 = 1D horizontal - ReturnCode - One of the ERR_CAPTURE_... */ -#define CX18_CPU_SET_SPATIAL_FILTER_TYPE (CPU_CMD_MASK_CAPTURE | 0x000C) - -/* Description: This command set coring levels for median filter - IN[0] - Task handle. - IN[1] - luma_high - IN[2] - luma_low - IN[3] - chroma_high - IN[4] - chroma_low - ReturnCode - One of the ERR_CAPTURE_... */ -#define CX18_CPU_SET_MEDIAN_CORING (CPU_CMD_MASK_CAPTURE | 0x000E) - -/* Description: This command set the picture type mask for index file - IN[0] - 0 = disable index file output - 1 = output I picture - 2 = P picture - 4 = B picture - other = illegal */ -#define CX18_CPU_SET_INDEXTABLE (CPU_CMD_MASK_CAPTURE | 0x0010) - -/* Description: Set audio parameters - IN[0] - task handle. Handle of the task to start - IN[1] - audio parameter - ReturnCode - One of the ERR_CAPTURE_... */ -#define CX18_CPU_SET_AUDIO_PARAMETERS (CPU_CMD_MASK_CAPTURE | 0x0011) - -/* Description: Set video mute - IN[0] - task handle. Handle of the task to start - IN[1] - bit31-24: muteYvalue - bit23-16: muteUvalue - bit15-8: muteVvalue - bit0: 1:mute, 0: unmute - ReturnCode - One of the ERR_CAPTURE_... */ -#define CX18_CPU_SET_VIDEO_MUTE (CPU_CMD_MASK_CAPTURE | 0x0013) - -/* Description: Set audio mute - IN[0] - task handle. Handle of the task to start - IN[1] - mute/unmute - ReturnCode - One of the ERR_CAPTURE_... */ -#define CX18_CPU_SET_AUDIO_MUTE (CPU_CMD_MASK_CAPTURE | 0x0014) - -/* Description: Set stream output type - IN[0] - task handle. Handle of the task to start - IN[1] - subType - SET_INITIAL_SCR 1 - SET_QUALITY_MODE 2 - SET_VIM_PROTECT_MODE 3 - SET_PTS_CORRECTION 4 - SET_USB_FLUSH_MODE 5 - SET_MERAQPAR_ENABLE 6 - SET_NAV_PACK_INSERTION 7 - SET_SCENE_CHANGE_ENABLE 8 - IN[2] - parameter 1 - IN[3] - parameter 2 - ReturnCode - One of the ERR_CAPTURE_... */ -#define CX18_CPU_SET_MISC_PARAMETERS (CPU_CMD_MASK_CAPTURE | 0x0015) - -/* Description: Set raw VBI parameters - IN[0] - Task handle - IN[1] - No. of input lines per field: - bit[15:0]: field 1, - bit[31:16]: field 2 - IN[2] - No. of input bytes per line - IN[3] - No. of output frames per transfer - IN[4] - start code - IN[5] - stop code - ReturnCode */ -#define CX18_CPU_SET_RAW_VBI_PARAM (CPU_CMD_MASK_CAPTURE | 0x0016) - -/* Description: Set capture line No. - IN[0] - task handle. Handle of the task to start - IN[1] - height1 - IN[2] - height2 - ReturnCode - One of the ERR_CAPTURE_... */ -#define CX18_CPU_SET_CAPTURE_LINE_NO (CPU_CMD_MASK_CAPTURE | 0x0017) - -/* Description: Set copyright - IN[0] - task handle. Handle of the task to start - IN[1] - copyright - ReturnCode - One of the ERR_CAPTURE_... */ -#define CX18_CPU_SET_COPYRIGHT (CPU_CMD_MASK_CAPTURE | 0x0018) - -/* Description: Set audio PID - IN[0] - task handle. Handle of the task to start - IN[1] - PID - ReturnCode - One of the ERR_CAPTURE_... */ -#define CX18_CPU_SET_AUDIO_PID (CPU_CMD_MASK_CAPTURE | 0x0019) - -/* Description: Set video PID - IN[0] - task handle. Handle of the task to start - IN[1] - PID - ReturnCode - One of the ERR_CAPTURE_... */ -#define CX18_CPU_SET_VIDEO_PID (CPU_CMD_MASK_CAPTURE | 0x001A) - -/* Description: Set Vertical Crop Line - IN[0] - task handle. Handle of the task to start - IN[1] - Line - ReturnCode - One of the ERR_CAPTURE_... */ -#define CX18_CPU_SET_VER_CROP_LINE (CPU_CMD_MASK_CAPTURE | 0x001B) - -/* Description: Set COP structure - IN[0] - task handle. Handle of the task to start - IN[1] - M - IN[2] - N - ReturnCode - One of the ERR_CAPTURE_... */ -#define CX18_CPU_SET_GOP_STRUCTURE (CPU_CMD_MASK_CAPTURE | 0x001C) - -/* Description: Set Scene Change Detection - IN[0] - task handle. Handle of the task to start - IN[1] - scene change - ReturnCode - One of the ERR_CAPTURE_... */ -#define CX18_CPU_SET_SCENE_CHANGE_DETECTION (CPU_CMD_MASK_CAPTURE | 0x001D) - -/* Description: Set Aspect Ratio - IN[0] - task handle. Handle of the task to start - IN[1] - AspectRatio - ReturnCode - One of the ERR_CAPTURE_... */ -#define CX18_CPU_SET_ASPECT_RATIO (CPU_CMD_MASK_CAPTURE | 0x001E) - -/* Description: Set Skip Input Frame - IN[0] - task handle. Handle of the task to start - IN[1] - skip input frames - ReturnCode - One of the ERR_CAPTURE_... */ -#define CX18_CPU_SET_SKIP_INPUT_FRAME (CPU_CMD_MASK_CAPTURE | 0x001F) - -/* Description: Set sliced VBI parameters - - Note This API will only apply to MPEG and Sliced VBI Channels - IN[0] - Task handle - IN[1] - output type, 0 - CC, 1 - Moji, 2 - Teletext - IN[2] - start / stop line - bit[15:0] start line number - bit[31:16] stop line number - IN[3] - number of output frames per interrupt - IN[4] - VBI insertion mode - bit 0: output user data, 1 - enable - bit 1: output private stream, 1 - enable - bit 2: mux option, 0 - in GOP, 1 - in picture - bit[7:0] private stream ID - IN[5] - insertion period while mux option is in picture - ReturnCode - VBI data offset */ -#define CX18_CPU_SET_SLICED_VBI_PARAM (CPU_CMD_MASK_CAPTURE | 0x0020) - -/* Description: Set the user data place holder - IN[0] - type of data (0 for user) - IN[1] - Stuffing period - IN[2] - ID data size in word (less than 10) - IN[3] - Pointer to ID buffer */ -#define CX18_CPU_SET_USERDATA_PLACE_HOLDER (CPU_CMD_MASK_CAPTURE | 0x0021) - - -/* Description: - In[0] Task Handle - return parameter: - Out[0] Reserved - Out[1] Video PTS bit[32:2] of last output video frame. - Out[2] Video PTS bit[ 1:0] of last output video frame. - Out[3] Hardware Video PTS counter bit[31:0], - these bits get incremented on every 90kHz clock tick. - Out[4] Hardware Video PTS counter bit32, - these bits get incremented on every 90kHz clock tick. - ReturnCode */ -#define CX18_CPU_GET_ENC_PTS (CPU_CMD_MASK_CAPTURE | 0x0022) - -/* Below is the list of commands related to the data exchange */ -#define CPU_CMD_MASK_DE (CPU_CMD_MASK | 0x040000) - -/* Description: This command provides the physical base address of the local - DDR as viewed by EPU - IN[0] - Physical offset where EPU has the local DDR mapped - ReturnCode - One of the ERR_DE_... */ -#define CPU_CMD_DE_SetBase (CPU_CMD_MASK_DE | 0x0001) - -/* Description: This command provides the offsets in the device memory where - the 2 cx18_mdl_ack blocks reside - IN[0] - Task handle. Handle of the task to start - IN[1] - Offset of the first cx18_mdl_ack from the beginning of the - local DDR. - IN[2] - Offset of the second cx18_mdl_ack from the beginning of the - local DDR. - ReturnCode - One of the ERR_DE_... */ -#define CX18_CPU_DE_SET_MDL_ACK (CPU_CMD_MASK_DE | 0x0002) - -/* Description: This command provides the offset to a Memory Descriptor List - IN[0] - Task handle. Handle of the task to start - IN[1] - Offset of the MDL from the beginning of the local DDR. - IN[2] - Number of cx18_mdl structures in the array pointed to by IN[1] - IN[3] - Buffer ID - IN[4] - Total buffer length - ReturnCode - One of the ERR_DE_... */ -#define CX18_CPU_DE_SET_MDL (CPU_CMD_MASK_DE | 0x0005) - -/* Description: This command requests return of all current Memory - Descriptor Lists to the driver - IN[0] - Task handle. Handle of the task to start - ReturnCode - One of the ERR_DE_... */ -#define CX18_CPU_DE_RELEASE_MDL (CPU_CMD_MASK_DE | 0x0006) - -/* Description: This command signals the cpu that the dat buffer has been - consumed and ready for re-use. - IN[0] - Task handle. Handle of the task - IN[1] - Offset of the data block from the beginning of the local DDR. - IN[2] - Number of bytes in the data block - ReturnCode - One of the ERR_DE_... */ -/* #define CX18_CPU_DE_RELEASE_BUFFER (CPU_CMD_MASK_DE | 0x0007) */ - -/* No Error / Success */ -#define CNXT_OK 0x000000 - -/* Received unknown command */ -#define CXERR_UNK_CMD 0x000001 - -/* First parameter in the command is invalid */ -#define CXERR_INVALID_PARAM1 0x000002 - -/* Second parameter in the command is invalid */ -#define CXERR_INVALID_PARAM2 0x000003 - -/* Device interface is not open/found */ -#define CXERR_DEV_NOT_FOUND 0x000004 - -/* Requested function is not implemented/available */ -#define CXERR_NOTSUPPORTED 0x000005 - -/* Invalid pointer is provided */ -#define CXERR_BADPTR 0x000006 - -/* Unable to allocate memory */ -#define CXERR_NOMEM 0x000007 - -/* Object/Link not found */ -#define CXERR_LINK 0x000008 - -/* Device busy, command cannot be executed */ -#define CXERR_BUSY 0x000009 - -/* File/device/handle is not open. */ -#define CXERR_NOT_OPEN 0x00000A - -/* Value is out of range */ -#define CXERR_OUTOFRANGE 0x00000B - -/* Buffer overflow */ -#define CXERR_OVERFLOW 0x00000C - -/* Version mismatch */ -#define CXERR_BADVER 0x00000D - -/* Operation timed out */ -#define CXERR_TIMEOUT 0x00000E - -/* Operation aborted */ -#define CXERR_ABORT 0x00000F - -/* Specified I2C device not found for read/write */ -#define CXERR_I2CDEV_NOTFOUND 0x000010 - -/* Error in I2C data xfer (but I2C device is present) */ -#define CXERR_I2CDEV_XFERERR 0x000011 - -/* Chanel changing component not ready */ -#define CXERR_CHANNELNOTREADY 0x000012 - -/* PPU (Presensation/Decoder) mail box is corrupted */ -#define CXERR_PPU_MB_CORRUPT 0x000013 - -/* CPU (Capture/Encoder) mail box is corrupted */ -#define CXERR_CPU_MB_CORRUPT 0x000014 - -/* APU (Audio) mail box is corrupted */ -#define CXERR_APU_MB_CORRUPT 0x000015 - -/* Unable to open file for reading */ -#define CXERR_FILE_OPEN_READ 0x000016 - -/* Unable to open file for writing */ -#define CXERR_FILE_OPEN_WRITE 0x000017 - -/* Unable to find the I2C section specified */ -#define CXERR_I2C_BADSECTION 0x000018 - -/* Error in I2C data xfer (but I2C device is present) */ -#define CXERR_I2CDEV_DATALOW 0x000019 - -/* Error in I2C data xfer (but I2C device is present) */ -#define CXERR_I2CDEV_CLOCKLOW 0x00001A - -/* No Interrupt received from HW (for I2C access) */ -#define CXERR_NO_HW_I2C_INTR 0x00001B - -/* RPU is not ready to accept commands! */ -#define CXERR_RPU_NOT_READY 0x00001C - -/* RPU is not ready to accept commands! */ -#define CXERR_RPU_NO_ACK 0x00001D - -/* The are no buffers ready. Try again soon! */ -#define CXERR_NODATA_AGAIN 0x00001E - -/* The stream is stopping. Function not alllowed now! */ -#define CXERR_STOPPING_STATUS 0x00001F - -/* Trying to access hardware when the power is turned OFF */ -#define CXERR_DEVPOWER_OFF 0x000020 - -#endif /* CX23418_H */ |
