diff options
author | Mauro Carvalho Chehab <mchehab@redhat.com> | 2012-08-14 12:13:30 -0300 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2012-08-15 16:36:22 -0300 |
commit | b285192a43f0432d82c2c10974204e78af0da596 (patch) | |
tree | 618aa87e760c9c949eca9e4df6ae0eeffa11dcfc /drivers/media/video/cx23885 | |
parent | 68de959f773a1d49096835c411390bceff5d1549 (diff) | |
download | linux-3.10-b285192a43f0432d82c2c10974204e78af0da596.tar.gz linux-3.10-b285192a43f0432d82c2c10974204e78af0da596.tar.bz2 linux-3.10-b285192a43f0432d82c2c10974204e78af0da596.zip |
[media] rename most media/video pci drivers to media/pci
Rename all PCI drivers with their own directory under
drivers/media/video into drivers/media/pci and update the
building system.
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/cx23885')
32 files changed, 0 insertions, 15531 deletions
diff --git a/drivers/media/video/cx23885/Kconfig b/drivers/media/video/cx23885/Kconfig deleted file mode 100644 index b391e9bda87..00000000000 --- a/drivers/media/video/cx23885/Kconfig +++ /dev/null @@ -1,46 +0,0 @@ -config VIDEO_CX23885 - tristate "Conexant cx23885 (2388x successor) support" - depends on DVB_CORE && VIDEO_DEV && PCI && I2C && INPUT && SND - select SND_PCM - select I2C_ALGOBIT - select VIDEO_BTCX - select VIDEO_TUNER - select VIDEO_TVEEPROM - depends on RC_CORE - select VIDEOBUF_DVB - select VIDEOBUF_DMA_SG - select VIDEO_CX25840 - select VIDEO_CX2341X - select DVB_DIB7000P if !DVB_FE_CUSTOMISE - select DVB_S5H1409 if !DVB_FE_CUSTOMISE - select DVB_S5H1411 if !DVB_FE_CUSTOMISE - select DVB_LGDT330X if !DVB_FE_CUSTOMISE - select DVB_ZL10353 if !DVB_FE_CUSTOMISE - select DVB_TDA10048 if !DVB_FE_CUSTOMISE - select DVB_LNBP21 if !DVB_FE_CUSTOMISE - select DVB_STV6110 if !DVB_FE_CUSTOMISE - select DVB_CX24116 if !DVB_FE_CUSTOMISE - select DVB_STV0900 if !DVB_FE_CUSTOMISE - select DVB_DS3000 if !DVB_FE_CUSTOMISE - select DVB_STV0367 if !DVB_FE_CUSTOMISE - select MEDIA_TUNER_MT2131 if !MEDIA_TUNER_CUSTOMISE - select MEDIA_TUNER_XC2028 if !MEDIA_TUNER_CUSTOMISE - select MEDIA_TUNER_TDA8290 if !MEDIA_TUNER_CUSTOMISE - select MEDIA_TUNER_TDA18271 if !MEDIA_TUNER_CUSTOMISE - select MEDIA_TUNER_XC5000 if !MEDIA_TUNER_CUSTOMISE - ---help--- - This is a video4linux driver for Conexant 23885 based - TV cards. - - To compile this driver as a module, choose M here: the - module will be called cx23885 - -config MEDIA_ALTERA_CI - tristate "Altera FPGA based CI module" - depends on VIDEO_CX23885 && DVB_CORE - select ALTERA_STAPL - ---help--- - An Altera FPGA CI module for NetUP Dual DVB-T/C RF CI card. - - To compile this driver as a module, choose M here: the - module will be called altera-ci diff --git a/drivers/media/video/cx23885/Makefile b/drivers/media/video/cx23885/Makefile deleted file mode 100644 index f92cc4c14f0..00000000000 --- a/drivers/media/video/cx23885/Makefile +++ /dev/null @@ -1,15 +0,0 @@ -cx23885-objs := cx23885-cards.o cx23885-video.o cx23885-vbi.o \ - cx23885-core.o cx23885-i2c.o cx23885-dvb.o cx23885-417.o \ - cx23885-ioctl.o cx23885-ir.o cx23885-av.o cx23885-input.o \ - cx23888-ir.o netup-init.o cimax2.o netup-eeprom.o \ - cx23885-f300.o cx23885-alsa.o - -obj-$(CONFIG_VIDEO_CX23885) += cx23885.o -obj-$(CONFIG_MEDIA_ALTERA_CI) += altera-ci.o - -ccflags-y += -Idrivers/media/video -ccflags-y += -Idrivers/media/tuners -ccflags-y += -Idrivers/media/dvb-core -ccflags-y += -Idrivers/media/dvb-frontends - -ccflags-y += $(extra-cflags-y) $(extra-cflags-m) diff --git a/drivers/media/video/cx23885/altera-ci.c b/drivers/media/video/cx23885/altera-ci.c deleted file mode 100644 index 1fa8927f0d3..00000000000 --- a/drivers/media/video/cx23885/altera-ci.c +++ /dev/null @@ -1,837 +0,0 @@ -/* - * altera-ci.c - * - * CI driver in conjunction with NetUp Dual DVB-T/C RF CI card - * - * Copyright (C) 2010,2011 NetUP Inc. - * Copyright (C) 2010,2011 Igor M. Liplianin <liplianin@netup.ru> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -/* - * currently cx23885 GPIO's used. - * GPIO-0 ~INT in - * GPIO-1 TMS out - * GPIO-2 ~reset chips out - * GPIO-3 to GPIO-10 data/addr for CA in/out - * GPIO-11 ~CS out - * GPIO-12 AD_RG out - * GPIO-13 ~WR out - * GPIO-14 ~RD out - * GPIO-15 ~RDY in - * GPIO-16 TCK out - * GPIO-17 TDO in - * GPIO-18 TDI out - */ -/* - * Bit definitions for MC417_RWD and MC417_OEN registers - * bits 31-16 - * +-----------+ - * | Reserved | - * +-----------+ - * bit 15 bit 14 bit 13 bit 12 bit 11 bit 10 bit 9 bit 8 - * +-------+-------+-------+-------+-------+-------+-------+-------+ - * | TDI | TDO | TCK | RDY# | #RD | #WR | AD_RG | #CS | - * +-------+-------+-------+-------+-------+-------+-------+-------+ - * bit 7 bit 6 bit 5 bit 4 bit 3 bit 2 bit 1 bit 0 - * +-------+-------+-------+-------+-------+-------+-------+-------+ - * | DATA7| DATA6| DATA5| DATA4| DATA3| DATA2| DATA1| DATA0| - * +-------+-------+-------+-------+-------+-------+-------+-------+ - */ -#include <media/videobuf-dma-sg.h> -#include <media/videobuf-dvb.h> -#include "altera-ci.h" -#include "dvb_ca_en50221.h" - -/* FPGA regs */ -#define NETUP_CI_INT_CTRL 0x00 -#define NETUP_CI_BUSCTRL2 0x01 -#define NETUP_CI_ADDR0 0x04 -#define NETUP_CI_ADDR1 0x05 -#define NETUP_CI_DATA 0x06 -#define NETUP_CI_BUSCTRL 0x07 -#define NETUP_CI_PID_ADDR0 0x08 -#define NETUP_CI_PID_ADDR1 0x09 -#define NETUP_CI_PID_DATA 0x0a -#define NETUP_CI_TSA_DIV 0x0c -#define NETUP_CI_TSB_DIV 0x0d -#define NETUP_CI_REVISION 0x0f - -/* const for ci op */ -#define NETUP_CI_FLG_CTL 1 -#define NETUP_CI_FLG_RD 1 -#define NETUP_CI_FLG_AD 1 - -static unsigned int ci_dbg; -module_param(ci_dbg, int, 0644); -MODULE_PARM_DESC(ci_dbg, "Enable CI debugging"); - -static unsigned int pid_dbg; -module_param(pid_dbg, int, 0644); -MODULE_PARM_DESC(pid_dbg, "Enable PID filtering debugging"); - -MODULE_DESCRIPTION("altera FPGA CI module"); -MODULE_AUTHOR("Igor M. Liplianin <liplianin@netup.ru>"); -MODULE_LICENSE("GPL"); - -#define ci_dbg_print(args...) \ - do { \ - if (ci_dbg) \ - printk(KERN_DEBUG args); \ - } while (0) - -#define pid_dbg_print(args...) \ - do { \ - if (pid_dbg) \ - printk(KERN_DEBUG args); \ - } while (0) - -struct altera_ci_state; -struct netup_hw_pid_filter; - -struct fpga_internal { - void *dev; - struct mutex fpga_mutex;/* two CI's on the same fpga */ - struct netup_hw_pid_filter *pid_filt[2]; - struct altera_ci_state *state[2]; - struct work_struct work; - int (*fpga_rw) (void *dev, int flag, int data, int rw); - int cis_used; - int filts_used; - int strt_wrk; -}; - -/* stores all private variables for communication with CI */ -struct altera_ci_state { - struct fpga_internal *internal; - struct dvb_ca_en50221 ca; - int status; - int nr; -}; - -/* stores all private variables for hardware pid filtering */ -struct netup_hw_pid_filter { - struct fpga_internal *internal; - struct dvb_demux *demux; - /* save old functions */ - int (*start_feed)(struct dvb_demux_feed *feed); - int (*stop_feed)(struct dvb_demux_feed *feed); - - int status; - int nr; -}; - -/* internal params node */ -struct fpga_inode { - /* pointer for internal params, one for each pair of CI's */ - struct fpga_internal *internal; - struct fpga_inode *next_inode; -}; - -/* first internal params */ -static struct fpga_inode *fpga_first_inode; - -/* find chip by dev */ -static struct fpga_inode *find_inode(void *dev) -{ - struct fpga_inode *temp_chip = fpga_first_inode; - - if (temp_chip == NULL) - return temp_chip; - - /* - Search for the last fpga CI chip or - find it by dev */ - while ((temp_chip != NULL) && - (temp_chip->internal->dev != dev)) - temp_chip = temp_chip->next_inode; - - return temp_chip; -} -/* check demux */ -static struct fpga_internal *check_filter(struct fpga_internal *temp_int, - void *demux_dev, int filt_nr) -{ - if (temp_int == NULL) - return NULL; - - if ((temp_int->pid_filt[filt_nr]) == NULL) - return NULL; - - if (temp_int->pid_filt[filt_nr]->demux == demux_dev) - return temp_int; - - return NULL; -} - -/* find chip by demux */ -static struct fpga_inode *find_dinode(void *demux_dev) -{ - struct fpga_inode *temp_chip = fpga_first_inode; - struct fpga_internal *temp_int; - - /* - * Search of the last fpga CI chip or - * find it by demux - */ - while (temp_chip != NULL) { - if (temp_chip->internal != NULL) { - temp_int = temp_chip->internal; - if (check_filter(temp_int, demux_dev, 0)) - break; - if (check_filter(temp_int, demux_dev, 1)) - break; - } - - temp_chip = temp_chip->next_inode; - } - - return temp_chip; -} - -/* deallocating chip */ -static void remove_inode(struct fpga_internal *internal) -{ - struct fpga_inode *prev_node = fpga_first_inode; - struct fpga_inode *del_node = find_inode(internal->dev); - - if (del_node != NULL) { - if (del_node == fpga_first_inode) { - fpga_first_inode = del_node->next_inode; - } else { - while (prev_node->next_inode != del_node) - prev_node = prev_node->next_inode; - - if (del_node->next_inode == NULL) - prev_node->next_inode = NULL; - else - prev_node->next_inode = - prev_node->next_inode->next_inode; - } - - kfree(del_node); - } -} - -/* allocating new chip */ -static struct fpga_inode *append_internal(struct fpga_internal *internal) -{ - struct fpga_inode *new_node = fpga_first_inode; - - if (new_node == NULL) { - new_node = kmalloc(sizeof(struct fpga_inode), GFP_KERNEL); - fpga_first_inode = new_node; - } else { - while (new_node->next_inode != NULL) - new_node = new_node->next_inode; - - new_node->next_inode = - kmalloc(sizeof(struct fpga_inode), GFP_KERNEL); - if (new_node->next_inode != NULL) - new_node = new_node->next_inode; - else - new_node = NULL; - } - - if (new_node != NULL) { - new_node->internal = internal; - new_node->next_inode = NULL; - } - - return new_node; -} - -static int netup_fpga_op_rw(struct fpga_internal *inter, int addr, - u8 val, u8 read) -{ - inter->fpga_rw(inter->dev, NETUP_CI_FLG_AD, addr, 0); - return inter->fpga_rw(inter->dev, 0, val, read); -} - -/* flag - mem/io, read - read/write */ -int altera_ci_op_cam(struct dvb_ca_en50221 *en50221, int slot, - u8 flag, u8 read, int addr, u8 val) -{ - - struct altera_ci_state *state = en50221->data; - struct fpga_internal *inter = state->internal; - - u8 store; - int mem = 0; - - if (0 != slot) - return -EINVAL; - - mutex_lock(&inter->fpga_mutex); - - netup_fpga_op_rw(inter, NETUP_CI_ADDR0, ((addr << 1) & 0xfe), 0); - netup_fpga_op_rw(inter, NETUP_CI_ADDR1, ((addr >> 7) & 0x7f), 0); - store = netup_fpga_op_rw(inter, NETUP_CI_BUSCTRL, 0, NETUP_CI_FLG_RD); - - store &= 0x0f; - store |= ((state->nr << 7) | (flag << 6)); - - netup_fpga_op_rw(inter, NETUP_CI_BUSCTRL, store, 0); - mem = netup_fpga_op_rw(inter, NETUP_CI_DATA, val, read); - - mutex_unlock(&inter->fpga_mutex); - - ci_dbg_print("%s: %s: addr=[0x%02x], %s=%x\n", __func__, - (read) ? "read" : "write", addr, - (flag == NETUP_CI_FLG_CTL) ? "ctl" : "mem", - (read) ? mem : val); - - return mem; -} - -int altera_ci_read_attribute_mem(struct dvb_ca_en50221 *en50221, - int slot, int addr) -{ - return altera_ci_op_cam(en50221, slot, 0, NETUP_CI_FLG_RD, addr, 0); -} - -int altera_ci_write_attribute_mem(struct dvb_ca_en50221 *en50221, - int slot, int addr, u8 data) -{ - return altera_ci_op_cam(en50221, slot, 0, 0, addr, data); -} - -int altera_ci_read_cam_ctl(struct dvb_ca_en50221 *en50221, int slot, u8 addr) -{ - return altera_ci_op_cam(en50221, slot, NETUP_CI_FLG_CTL, - NETUP_CI_FLG_RD, addr, 0); -} - -int altera_ci_write_cam_ctl(struct dvb_ca_en50221 *en50221, int slot, - u8 addr, u8 data) -{ - return altera_ci_op_cam(en50221, slot, NETUP_CI_FLG_CTL, 0, addr, data); -} - -int altera_ci_slot_reset(struct dvb_ca_en50221 *en50221, int slot) -{ - struct altera_ci_state *state = en50221->data; - struct fpga_internal *inter = state->internal; - /* reasonable timeout for CI reset is 10 seconds */ - unsigned long t_out = jiffies + msecs_to_jiffies(9999); - int ret; - - ci_dbg_print("%s\n", __func__); - - if (0 != slot) - return -EINVAL; - - mutex_lock(&inter->fpga_mutex); - - ret = netup_fpga_op_rw(inter, NETUP_CI_BUSCTRL, 0, NETUP_CI_FLG_RD); - netup_fpga_op_rw(inter, NETUP_CI_BUSCTRL, - (ret & 0xcf) | (1 << (5 - state->nr)), 0); - - mutex_unlock(&inter->fpga_mutex); - - for (;;) { - mdelay(50); - - mutex_lock(&inter->fpga_mutex); - - ret = netup_fpga_op_rw(inter, NETUP_CI_BUSCTRL, - 0, NETUP_CI_FLG_RD); - mutex_unlock(&inter->fpga_mutex); - - if ((ret & (1 << (5 - state->nr))) == 0) - break; - if (time_after(jiffies, t_out)) - break; - } - - - ci_dbg_print("%s: %d msecs\n", __func__, - jiffies_to_msecs(jiffies + msecs_to_jiffies(9999) - t_out)); - - return 0; -} - -int altera_ci_slot_shutdown(struct dvb_ca_en50221 *en50221, int slot) -{ - /* not implemented */ - return 0; -} - -int altera_ci_slot_ts_ctl(struct dvb_ca_en50221 *en50221, int slot) -{ - struct altera_ci_state *state = en50221->data; - struct fpga_internal *inter = state->internal; - int ret; - - ci_dbg_print("%s\n", __func__); - - if (0 != slot) - return -EINVAL; - - mutex_lock(&inter->fpga_mutex); - - ret = netup_fpga_op_rw(inter, NETUP_CI_BUSCTRL, 0, NETUP_CI_FLG_RD); - netup_fpga_op_rw(inter, NETUP_CI_BUSCTRL, - (ret & 0x0f) | (1 << (3 - state->nr)), 0); - - mutex_unlock(&inter->fpga_mutex); - - return 0; -} - -/* work handler */ -static void netup_read_ci_status(struct work_struct *work) -{ - struct fpga_internal *inter = - container_of(work, struct fpga_internal, work); - int ret; - - ci_dbg_print("%s\n", __func__); - - mutex_lock(&inter->fpga_mutex); - /* ack' irq */ - ret = netup_fpga_op_rw(inter, NETUP_CI_INT_CTRL, 0, NETUP_CI_FLG_RD); - ret = netup_fpga_op_rw(inter, NETUP_CI_BUSCTRL, 0, NETUP_CI_FLG_RD); - - mutex_unlock(&inter->fpga_mutex); - - if (inter->state[1] != NULL) { - inter->state[1]->status = - ((ret & 1) == 0 ? - DVB_CA_EN50221_POLL_CAM_PRESENT | - DVB_CA_EN50221_POLL_CAM_READY : 0); - ci_dbg_print("%s: setting CI[1] status = 0x%x\n", - __func__, inter->state[1]->status); - }; - - if (inter->state[0] != NULL) { - inter->state[0]->status = - ((ret & 2) == 0 ? - DVB_CA_EN50221_POLL_CAM_PRESENT | - DVB_CA_EN50221_POLL_CAM_READY : 0); - ci_dbg_print("%s: setting CI[0] status = 0x%x\n", - __func__, inter->state[0]->status); - }; -} - -/* CI irq handler */ -int altera_ci_irq(void *dev) -{ - struct fpga_inode *temp_int = NULL; - struct fpga_internal *inter = NULL; - - ci_dbg_print("%s\n", __func__); - - if (dev != NULL) { - temp_int = find_inode(dev); - if (temp_int != NULL) { - inter = temp_int->internal; - schedule_work(&inter->work); - } - } - - return 1; -} -EXPORT_SYMBOL(altera_ci_irq); - -int altera_poll_ci_slot_status(struct dvb_ca_en50221 *en50221, int slot, - int open) -{ - struct altera_ci_state *state = en50221->data; - - if (0 != slot) - return -EINVAL; - - return state->status; -} - -void altera_hw_filt_release(void *main_dev, int filt_nr) -{ - struct fpga_inode *temp_int = find_inode(main_dev); - struct netup_hw_pid_filter *pid_filt = NULL; - - ci_dbg_print("%s\n", __func__); - - if (temp_int != NULL) { - pid_filt = temp_int->internal->pid_filt[filt_nr - 1]; - /* stored old feed controls */ - pid_filt->demux->start_feed = pid_filt->start_feed; - pid_filt->demux->stop_feed = pid_filt->stop_feed; - - if (((--(temp_int->internal->filts_used)) <= 0) && - ((temp_int->internal->cis_used) <= 0)) { - - ci_dbg_print("%s: Actually removing\n", __func__); - - remove_inode(temp_int->internal); - kfree(pid_filt->internal); - } - - kfree(pid_filt); - - } - -} -EXPORT_SYMBOL(altera_hw_filt_release); - -void altera_ci_release(void *dev, int ci_nr) -{ - struct fpga_inode *temp_int = find_inode(dev); - struct altera_ci_state *state = NULL; - - ci_dbg_print("%s\n", __func__); - - if (temp_int != NULL) { - state = temp_int->internal->state[ci_nr - 1]; - altera_hw_filt_release(dev, ci_nr); - - - if (((temp_int->internal->filts_used) <= 0) && - ((--(temp_int->internal->cis_used)) <= 0)) { - - ci_dbg_print("%s: Actually removing\n", __func__); - - remove_inode(temp_int->internal); - kfree(state->internal); - } - - if (state != NULL) { - if (state->ca.data != NULL) - dvb_ca_en50221_release(&state->ca); - - kfree(state); - } - } - -} -EXPORT_SYMBOL(altera_ci_release); - -static void altera_pid_control(struct netup_hw_pid_filter *pid_filt, - u16 pid, int onoff) -{ - struct fpga_internal *inter = pid_filt->internal; - u8 store = 0; - - /* pid 0-0x1f always enabled, don't touch them */ - if ((pid == 0x2000) || (pid < 0x20)) - return; - - mutex_lock(&inter->fpga_mutex); - - netup_fpga_op_rw(inter, NETUP_CI_PID_ADDR0, (pid >> 3) & 0xff, 0); - netup_fpga_op_rw(inter, NETUP_CI_PID_ADDR1, - ((pid >> 11) & 0x03) | (pid_filt->nr << 2), 0); - - store = netup_fpga_op_rw(inter, NETUP_CI_PID_DATA, 0, NETUP_CI_FLG_RD); - - if (onoff)/* 0 - on, 1 - off */ - store |= (1 << (pid & 7)); - else - store &= ~(1 << (pid & 7)); - - netup_fpga_op_rw(inter, NETUP_CI_PID_DATA, store, 0); - - mutex_unlock(&inter->fpga_mutex); - - pid_dbg_print("%s: (%d) set pid: %5d 0x%04x '%s'\n", __func__, - pid_filt->nr, pid, pid, onoff ? "off" : "on"); -} - -static void altera_toggle_fullts_streaming(struct netup_hw_pid_filter *pid_filt, - int filt_nr, int onoff) -{ - struct fpga_internal *inter = pid_filt->internal; - u8 store = 0; - int i; - - pid_dbg_print("%s: pid_filt->nr[%d] now %s\n", __func__, pid_filt->nr, - onoff ? "off" : "on"); - - if (onoff)/* 0 - on, 1 - off */ - store = 0xff;/* ignore pid */ - else - store = 0;/* enable pid */ - - mutex_lock(&inter->fpga_mutex); - - for (i = 0; i < 1024; i++) { - netup_fpga_op_rw(inter, NETUP_CI_PID_ADDR0, i & 0xff, 0); - - netup_fpga_op_rw(inter, NETUP_CI_PID_ADDR1, - ((i >> 8) & 0x03) | (pid_filt->nr << 2), 0); - /* pid 0-0x1f always enabled */ - netup_fpga_op_rw(inter, NETUP_CI_PID_DATA, - (i > 3 ? store : 0), 0); - } - - mutex_unlock(&inter->fpga_mutex); -} - -int altera_pid_feed_control(void *demux_dev, int filt_nr, - struct dvb_demux_feed *feed, int onoff) -{ - struct fpga_inode *temp_int = find_dinode(demux_dev); - struct fpga_internal *inter = temp_int->internal; - struct netup_hw_pid_filter *pid_filt = inter->pid_filt[filt_nr - 1]; - - altera_pid_control(pid_filt, feed->pid, onoff ? 0 : 1); - /* call old feed proc's */ - if (onoff) - pid_filt->start_feed(feed); - else - pid_filt->stop_feed(feed); - - if (feed->pid == 0x2000) - altera_toggle_fullts_streaming(pid_filt, filt_nr, - onoff ? 0 : 1); - - return 0; -} -EXPORT_SYMBOL(altera_pid_feed_control); - -int altera_ci_start_feed(struct dvb_demux_feed *feed, int num) -{ - altera_pid_feed_control(feed->demux, num, feed, 1); - - return 0; -} - -int altera_ci_stop_feed(struct dvb_demux_feed *feed, int num) -{ - altera_pid_feed_control(feed->demux, num, feed, 0); - - return 0; -} - -int altera_ci_start_feed_1(struct dvb_demux_feed *feed) -{ - return altera_ci_start_feed(feed, 1); -} - -int altera_ci_stop_feed_1(struct dvb_demux_feed *feed) -{ - return altera_ci_stop_feed(feed, 1); -} - -int altera_ci_start_feed_2(struct dvb_demux_feed *feed) -{ - return altera_ci_start_feed(feed, 2); -} - -int altera_ci_stop_feed_2(struct dvb_demux_feed *feed) -{ - return altera_ci_stop_feed(feed, 2); -} - -int altera_hw_filt_init(struct altera_ci_config *config, int hw_filt_nr) -{ - struct netup_hw_pid_filter *pid_filt = NULL; - struct fpga_inode *temp_int = find_inode(config->dev); - struct fpga_internal *inter = NULL; - int ret = 0; - - pid_filt = kzalloc(sizeof(struct netup_hw_pid_filter), GFP_KERNEL); - - ci_dbg_print("%s\n", __func__); - - if (!pid_filt) { - ret = -ENOMEM; - goto err; - } - - if (temp_int != NULL) { - inter = temp_int->internal; - (inter->filts_used)++; - ci_dbg_print("%s: Find Internal Structure!\n", __func__); - } else { - inter = kzalloc(sizeof(struct fpga_internal), GFP_KERNEL); - if (!inter) { - ret = -ENOMEM; - goto err; - } - - temp_int = append_internal(inter); - inter->filts_used = 1; - inter->dev = config->dev; - inter->fpga_rw = config->fpga_rw; - mutex_init(&inter->fpga_mutex); - inter->strt_wrk = 1; - ci_dbg_print("%s: Create New Internal Structure!\n", __func__); - } - - ci_dbg_print("%s: setting hw pid filter = %p for ci = %d\n", __func__, - pid_filt, hw_filt_nr - 1); - inter->pid_filt[hw_filt_nr - 1] = pid_filt; - pid_filt->demux = config->demux; - pid_filt->internal = inter; - pid_filt->nr = hw_filt_nr - 1; - /* store old feed controls */ - pid_filt->start_feed = config->demux->start_feed; - pid_filt->stop_feed = config->demux->stop_feed; - /* replace with new feed controls */ - if (hw_filt_nr == 1) { - pid_filt->demux->start_feed = altera_ci_start_feed_1; - pid_filt->demux->stop_feed = altera_ci_stop_feed_1; - } else if (hw_filt_nr == 2) { - pid_filt->demux->start_feed = altera_ci_start_feed_2; - pid_filt->demux->stop_feed = altera_ci_stop_feed_2; - } - - altera_toggle_fullts_streaming(pid_filt, 0, 1); - - return 0; -err: - ci_dbg_print("%s: Can't init hardware filter: Error %d\n", - __func__, ret); - - kfree(pid_filt); - - return ret; -} -EXPORT_SYMBOL(altera_hw_filt_init); - -int altera_ci_init(struct altera_ci_config *config, int ci_nr) -{ - struct altera_ci_state *state; - struct fpga_inode *temp_int = find_inode(config->dev); - struct fpga_internal *inter = NULL; - int ret = 0; - u8 store = 0; - - state = kzalloc(sizeof(struct altera_ci_state), GFP_KERNEL); - - ci_dbg_print("%s\n", __func__); - - if (!state) { - ret = -ENOMEM; - goto err; - } - - if (temp_int != NULL) { - inter = temp_int->internal; - (inter->cis_used)++; - ci_dbg_print("%s: Find Internal Structure!\n", __func__); - } else { - inter = kzalloc(sizeof(struct fpga_internal), GFP_KERNEL); - if (!inter) { - ret = -ENOMEM; - goto err; - } - - temp_int = append_internal(inter); - inter->cis_used = 1; - inter->dev = config->dev; - inter->fpga_rw = config->fpga_rw; - mutex_init(&inter->fpga_mutex); - inter->strt_wrk = 1; - ci_dbg_print("%s: Create New Internal Structure!\n", __func__); - } - - ci_dbg_print("%s: setting state = %p for ci = %d\n", __func__, - state, ci_nr - 1); - inter->state[ci_nr - 1] = state; - state->internal = inter; - state->nr = ci_nr - 1; - - state->ca.owner = THIS_MODULE; - state->ca.read_attribute_mem = altera_ci_read_attribute_mem; - state->ca.write_attribute_mem = altera_ci_write_attribute_mem; - state->ca.read_cam_control = altera_ci_read_cam_ctl; - state->ca.write_cam_control = altera_ci_write_cam_ctl; - state->ca.slot_reset = altera_ci_slot_reset; - state->ca.slot_shutdown = altera_ci_slot_shutdown; - state->ca.slot_ts_enable = altera_ci_slot_ts_ctl; - state->ca.poll_slot_status = altera_poll_ci_slot_status; - state->ca.data = state; - - ret = dvb_ca_en50221_init(config->adapter, - &state->ca, - /* flags */ 0, - /* n_slots */ 1); - if (0 != ret) - goto err; - - altera_hw_filt_init(config, ci_nr); - - if (inter->strt_wrk) { - INIT_WORK(&inter->work, netup_read_ci_status); - inter->strt_wrk = 0; - } - - ci_dbg_print("%s: CI initialized!\n", __func__); - - mutex_lock(&inter->fpga_mutex); - - /* Enable div */ - netup_fpga_op_rw(inter, NETUP_CI_TSA_DIV, 0x0, 0); - netup_fpga_op_rw(inter, NETUP_CI_TSB_DIV, 0x0, 0); - - /* enable TS out */ - store = netup_fpga_op_rw(inter, NETUP_CI_BUSCTRL2, 0, NETUP_CI_FLG_RD); - store |= (3 << 4); - netup_fpga_op_rw(inter, NETUP_CI_BUSCTRL2, store, 0); - - ret = netup_fpga_op_rw(inter, NETUP_CI_REVISION, 0, NETUP_CI_FLG_RD); - /* enable irq */ - netup_fpga_op_rw(inter, NETUP_CI_INT_CTRL, 0x44, 0); - - mutex_unlock(&inter->fpga_mutex); - - ci_dbg_print("%s: NetUP CI Revision = 0x%x\n", __func__, ret); - - schedule_work(&inter->work); - - return 0; -err: - ci_dbg_print("%s: Cannot initialize CI: Error %d.\n", __func__, ret); - - kfree(state); - - return ret; -} -EXPORT_SYMBOL(altera_ci_init); - -int altera_ci_tuner_reset(void *dev, int ci_nr) -{ - struct fpga_inode *temp_int = find_inode(dev); - struct fpga_internal *inter = NULL; - u8 store; - - ci_dbg_print("%s\n", __func__); - - if (temp_int == NULL) - return -1; - - if (temp_int->internal == NULL) - return -1; - - inter = temp_int->internal; - - mutex_lock(&inter->fpga_mutex); - - store = netup_fpga_op_rw(inter, NETUP_CI_BUSCTRL2, 0, NETUP_CI_FLG_RD); - store &= ~(4 << (2 - ci_nr)); - netup_fpga_op_rw(inter, NETUP_CI_BUSCTRL2, store, 0); - msleep(100); - store |= (4 << (2 - ci_nr)); - netup_fpga_op_rw(inter, NETUP_CI_BUSCTRL2, store, 0); - - mutex_unlock(&inter->fpga_mutex); - - return 0; -} -EXPORT_SYMBOL(altera_ci_tuner_reset); diff --git a/drivers/media/video/cx23885/altera-ci.h b/drivers/media/video/cx23885/altera-ci.h deleted file mode 100644 index 70e4fd69ad9..00000000000 --- a/drivers/media/video/cx23885/altera-ci.h +++ /dev/null @@ -1,100 +0,0 @@ -/* - * altera-ci.c - * - * CI driver in conjunction with NetUp Dual DVB-T/C RF CI card - * - * Copyright (C) 2010 NetUP Inc. - * Copyright (C) 2010 Igor M. Liplianin <liplianin@netup.ru> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ -#ifndef __ALTERA_CI_H -#define __ALTERA_CI_H - -#define ALT_DATA 0x000000ff -#define ALT_TDI 0x00008000 -#define ALT_TDO 0x00004000 -#define ALT_TCK 0x00002000 -#define ALT_RDY 0x00001000 -#define ALT_RD 0x00000800 -#define ALT_WR 0x00000400 -#define ALT_AD_RG 0x00000200 -#define ALT_CS 0x00000100 - -struct altera_ci_config { - void *dev;/* main dev, for example cx23885_dev */ - void *adapter;/* for CI to connect to */ - struct dvb_demux *demux;/* for hardware PID filter to connect to */ - int (*fpga_rw) (void *dev, int ad_rg, int val, int rw); -}; - -#if defined(CONFIG_MEDIA_ALTERA_CI) || (defined(CONFIG_MEDIA_ALTERA_CI_MODULE) \ - && defined(MODULE)) - -extern int altera_ci_init(struct altera_ci_config *config, int ci_nr); -extern void altera_ci_release(void *dev, int ci_nr); -extern int altera_ci_irq(void *dev); -extern int altera_ci_tuner_reset(void *dev, int ci_nr); - -#else - -static inline int altera_ci_init(struct altera_ci_config *config, int ci_nr) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return 0; -} - -static inline void altera_ci_release(void *dev, int ci_nr) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); -} - -static inline int altera_ci_irq(void *dev) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return 0; -} - -static inline int altera_ci_tuner_reset(void *dev, int ci_nr) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return 0; -} - -#endif -#if 0 -static inline int altera_hw_filt_init(struct altera_ci_config *config, - int hw_filt_nr) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return 0; -} - -static inline void altera_hw_filt_release(void *dev, int filt_nr) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); -} - -static inline int altera_pid_feed_control(void *dev, int filt_nr, - struct dvb_demux_feed *dvbdmxfeed, int onoff) -{ - printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); - return 0; -} - -#endif /* CONFIG_MEDIA_ALTERA_CI */ - -#endif /* __ALTERA_CI_H */ diff --git a/drivers/media/video/cx23885/cimax2.c b/drivers/media/video/cx23885/cimax2.c deleted file mode 100644 index c9f15d6dec4..00000000000 --- a/drivers/media/video/cx23885/cimax2.c +++ /dev/null @@ -1,536 +0,0 @@ -/* - * cimax2.c - * - * CIMax2(R) SP2 driver in conjunction with NetUp Dual DVB-S2 CI card - * - * Copyright (C) 2009 NetUP Inc. - * Copyright (C) 2009 Igor M. Liplianin <liplianin@netup.ru> - * Copyright (C) 2009 Abylay Ospan <aospan@netup.ru> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include "cx23885.h" -#include "dvb_ca_en50221.h" -/**** Bit definitions for MC417_RWD and MC417_OEN registers *** - bits 31-16 -+-----------+ -| Reserved | -+-----------+ - bit 15 bit 14 bit 13 bit 12 bit 11 bit 10 bit 9 bit 8 -+-------+-------+-------+-------+-------+-------+-------+-------+ -| WR# | RD# | | ACK# | ADHI | ADLO | CS1# | CS0# | -+-------+-------+-------+-------+-------+-------+-------+-------+ - bit 7 bit 6 bit 5 bit 4 bit 3 bit 2 bit 1 bit 0 -+-------+-------+-------+-------+-------+-------+-------+-------+ -| DATA7| DATA6| DATA5| DATA4| DATA3| DATA2| DATA1| DATA0| -+-------+-------+-------+-------+-------+-------+-------+-------+ -***/ -/* MC417 */ -#define NETUP_DATA 0x000000ff -#define NETUP_WR 0x00008000 -#define NETUP_RD 0x00004000 -#define NETUP_ACK 0x00001000 -#define NETUP_ADHI 0x00000800 -#define NETUP_ADLO 0x00000400 -#define NETUP_CS1 0x00000200 -#define NETUP_CS0 0x00000100 -#define NETUP_EN_ALL 0x00001000 -#define NETUP_CTRL_OFF (NETUP_CS1 | NETUP_CS0 | NETUP_WR | NETUP_RD) -#define NETUP_CI_CTL 0x04 -#define NETUP_CI_RD 1 - -#define NETUP_IRQ_DETAM 0x1 -#define NETUP_IRQ_IRQAM 0x4 - -static unsigned int ci_dbg; -module_param(ci_dbg, int, 0644); -MODULE_PARM_DESC(ci_dbg, "Enable CI debugging"); - -static unsigned int ci_irq_enable; -module_param(ci_irq_enable, int, 0644); -MODULE_PARM_DESC(ci_irq_enable, "Enable IRQ from CAM"); - -#define ci_dbg_print(args...) \ - do { \ - if (ci_dbg) \ - printk(KERN_DEBUG args); \ - } while (0) - -#define ci_irq_flags() (ci_irq_enable ? NETUP_IRQ_IRQAM : 0) - -/* stores all private variables for communication with CI */ -struct netup_ci_state { - struct dvb_ca_en50221 ca; - struct mutex ca_mutex; - struct i2c_adapter *i2c_adap; - u8 ci_i2c_addr; - int status; - struct work_struct work; - void *priv; - u8 current_irq_mode; - int current_ci_flag; - unsigned long next_status_checked_time; -}; - - -int netup_read_i2c(struct i2c_adapter *i2c_adap, u8 addr, u8 reg, - u8 *buf, int len) -{ - int ret; - struct i2c_msg msg[] = { - { - .addr = addr, - .flags = 0, - .buf = ®, - .len = 1 - }, { - .addr = addr, - .flags = I2C_M_RD, - .buf = buf, - .len = len - } - }; - - ret = i2c_transfer(i2c_adap, msg, 2); - - if (ret != 2) { - ci_dbg_print("%s: i2c read error, Reg = 0x%02x, Status = %d\n", - __func__, reg, ret); - - return -1; - } - - ci_dbg_print("%s: i2c read Addr=0x%04x, Reg = 0x%02x, data = %02x\n", - __func__, addr, reg, buf[0]); - - return 0; -} - -int netup_write_i2c(struct i2c_adapter *i2c_adap, u8 addr, u8 reg, - u8 *buf, int len) -{ - int ret; - u8 buffer[len + 1]; - - struct i2c_msg msg = { - .addr = addr, - .flags = 0, - .buf = &buffer[0], - .len = len + 1 - }; - - buffer[0] = reg; - memcpy(&buffer[1], buf, len); - - ret = i2c_transfer(i2c_adap, &msg, 1); - - if (ret != 1) { - ci_dbg_print("%s: i2c write error, Reg=[0x%02x], Status=%d\n", - __func__, reg, ret); - return -1; - } - - return 0; -} - -int netup_ci_get_mem(struct cx23885_dev *dev) -{ - int mem; - unsigned long timeout = jiffies + msecs_to_jiffies(1); - - for (;;) { - mem = cx_read(MC417_RWD); - if ((mem & NETUP_ACK) == 0) - break; - if (time_after(jiffies, timeout)) - break; - udelay(1); - } - - cx_set(MC417_RWD, NETUP_CTRL_OFF); - - return mem & 0xff; -} - -int netup_ci_op_cam(struct dvb_ca_en50221 *en50221, int slot, - u8 flag, u8 read, int addr, u8 data) -{ - struct netup_ci_state *state = en50221->data; - struct cx23885_tsport *port = state->priv; - struct cx23885_dev *dev = port->dev; - - u8 store; - int mem; - int ret; - - if (0 != slot) - return -EINVAL; - - if (state->current_ci_flag != flag) { - ret = netup_read_i2c(state->i2c_adap, state->ci_i2c_addr, - 0, &store, 1); - if (ret != 0) - return ret; - - store &= ~0x0c; - store |= flag; - - ret = netup_write_i2c(state->i2c_adap, state->ci_i2c_addr, - 0, &store, 1); - if (ret != 0) - return ret; - }; - state->current_ci_flag = flag; - - mutex_lock(&dev->gpio_lock); - - /* write addr */ - cx_write(MC417_OEN, NETUP_EN_ALL); - cx_write(MC417_RWD, NETUP_CTRL_OFF | - NETUP_ADLO | (0xff & addr)); - cx_clear(MC417_RWD, NETUP_ADLO); - cx_write(MC417_RWD, NETUP_CTRL_OFF | - NETUP_ADHI | (0xff & (addr >> 8))); - cx_clear(MC417_RWD, NETUP_ADHI); - - if (read) { /* data in */ - cx_write(MC417_OEN, NETUP_EN_ALL | NETUP_DATA); - } else /* data out */ - cx_write(MC417_RWD, NETUP_CTRL_OFF | data); - - /* choose chip */ - cx_clear(MC417_RWD, - (state->ci_i2c_addr == 0x40) ? NETUP_CS0 : NETUP_CS1); - /* read/write */ - cx_clear(MC417_RWD, (read) ? NETUP_RD : NETUP_WR); - mem = netup_ci_get_mem(dev); - - mutex_unlock(&dev->gpio_lock); - - if (!read) - if (mem < 0) - return -EREMOTEIO; - - ci_dbg_print("%s: %s: chipaddr=[0x%x] addr=[0x%02x], %s=%x\n", __func__, - (read) ? "read" : "write", state->ci_i2c_addr, addr, - (flag == NETUP_CI_CTL) ? "ctl" : "mem", - (read) ? mem : data); - - if (read) - return mem; - - return 0; -} - -int netup_ci_read_attribute_mem(struct dvb_ca_en50221 *en50221, - int slot, int addr) -{ - return netup_ci_op_cam(en50221, slot, 0, NETUP_CI_RD, addr, 0); -} - -int netup_ci_write_attribute_mem(struct dvb_ca_en50221 *en50221, - int slot, int addr, u8 data) -{ - return netup_ci_op_cam(en50221, slot, 0, 0, addr, data); -} - -int netup_ci_read_cam_ctl(struct dvb_ca_en50221 *en50221, int slot, u8 addr) -{ - return netup_ci_op_cam(en50221, slot, NETUP_CI_CTL, - NETUP_CI_RD, addr, 0); -} - -int netup_ci_write_cam_ctl(struct dvb_ca_en50221 *en50221, int slot, - u8 addr, u8 data) -{ - return netup_ci_op_cam(en50221, slot, NETUP_CI_CTL, 0, addr, data); -} - -int netup_ci_slot_reset(struct dvb_ca_en50221 *en50221, int slot) -{ - struct netup_ci_state *state = en50221->data; - u8 buf = 0x80; - int ret; - - if (0 != slot) - return -EINVAL; - - udelay(500); - ret = netup_write_i2c(state->i2c_adap, state->ci_i2c_addr, - 0, &buf, 1); - - if (ret != 0) - return ret; - - udelay(500); - - buf = 0x00; - ret = netup_write_i2c(state->i2c_adap, state->ci_i2c_addr, - 0, &buf, 1); - - msleep(1000); - dvb_ca_en50221_camready_irq(&state->ca, 0); - - return 0; - -} - -int netup_ci_slot_shutdown(struct dvb_ca_en50221 *en50221, int slot) -{ - /* not implemented */ - return 0; -} - -int netup_ci_set_irq(struct dvb_ca_en50221 *en50221, u8 irq_mode) -{ - struct netup_ci_state *state = en50221->data; - int ret; - - if (irq_mode == state->current_irq_mode) - return 0; - - ci_dbg_print("%s: chipaddr=[0x%x] setting ci IRQ to [0x%x] \n", - __func__, state->ci_i2c_addr, irq_mode); - ret = netup_write_i2c(state->i2c_adap, state->ci_i2c_addr, - 0x1b, &irq_mode, 1); - - if (ret != 0) - return ret; - - state->current_irq_mode = irq_mode; - - return 0; -} - -int netup_ci_slot_ts_ctl(struct dvb_ca_en50221 *en50221, int slot) -{ - struct netup_ci_state *state = en50221->data; - u8 buf; - - if (0 != slot) - return -EINVAL; - - netup_read_i2c(state->i2c_adap, state->ci_i2c_addr, - 0, &buf, 1); - buf |= 0x60; - - return netup_write_i2c(state->i2c_adap, state->ci_i2c_addr, - 0, &buf, 1); -} - -/* work handler */ -static void netup_read_ci_status(struct work_struct *work) -{ - struct netup_ci_state *state = - container_of(work, struct netup_ci_state, work); - u8 buf[33]; - int ret; - - /* CAM module IRQ processing. fast operation */ - dvb_ca_en50221_frda_irq(&state->ca, 0); - - /* CAM module INSERT/REMOVE processing. slow operation because of i2c - * transfers */ - if (time_after(jiffies, state->next_status_checked_time) - || !state->status) { - ret = netup_read_i2c(state->i2c_adap, state->ci_i2c_addr, - 0, &buf[0], 33); - - state->next_status_checked_time = jiffies - + msecs_to_jiffies(1000); - - if (ret != 0) - return; - - ci_dbg_print("%s: Slot Status Addr=[0x%04x], " - "Reg=[0x%02x], data=%02x, " - "TS config = %02x\n", __func__, - state->ci_i2c_addr, 0, buf[0], - buf[0]); - - - if (buf[0] & 1) - state->status = DVB_CA_EN50221_POLL_CAM_PRESENT | - DVB_CA_EN50221_POLL_CAM_READY; - else - state->status = 0; - } -} - -/* CI irq handler */ -int netup_ci_slot_status(struct cx23885_dev *dev, u32 pci_status) -{ - struct cx23885_tsport *port = NULL; - struct netup_ci_state *state = NULL; - - ci_dbg_print("%s:\n", __func__); - - if (0 == (pci_status & (PCI_MSK_GPIO0 | PCI_MSK_GPIO1))) - return 0; - - if (pci_status & PCI_MSK_GPIO0) { - port = &dev->ts1; - state = port->port_priv; - schedule_work(&state->work); - ci_dbg_print("%s: Wakeup CI0\n", __func__); - } - - if (pci_status & PCI_MSK_GPIO1) { - port = &dev->ts2; - state = port->port_priv; - schedule_work(&state->work); - ci_dbg_print("%s: Wakeup CI1\n", __func__); - } - - return 1; -} - -int netup_poll_ci_slot_status(struct dvb_ca_en50221 *en50221, int slot, int open) -{ - struct netup_ci_state *state = en50221->data; - - if (0 != slot) - return -EINVAL; - - netup_ci_set_irq(en50221, open ? (NETUP_IRQ_DETAM | ci_irq_flags()) - : NETUP_IRQ_DETAM); - - return state->status; -} - -int netup_ci_init(struct cx23885_tsport *port) -{ - struct netup_ci_state *state; - u8 cimax_init[34] = { - 0x00, /* module A control*/ - 0x00, /* auto select mask high A */ - 0x00, /* auto select mask low A */ - 0x00, /* auto select pattern high A */ - 0x00, /* auto select pattern low A */ - 0x44, /* memory access time A */ - 0x00, /* invert input A */ - 0x00, /* RFU */ - 0x00, /* RFU */ - 0x00, /* module B control*/ - 0x00, /* auto select mask high B */ - 0x00, /* auto select mask low B */ - 0x00, /* auto select pattern high B */ - 0x00, /* auto select pattern low B */ - 0x44, /* memory access time B */ - 0x00, /* invert input B */ - 0x00, /* RFU */ - 0x00, /* RFU */ - 0x00, /* auto select mask high Ext */ - 0x00, /* auto select mask low Ext */ - 0x00, /* auto select pattern high Ext */ - 0x00, /* auto select pattern low Ext */ - 0x00, /* RFU */ - 0x02, /* destination - module A */ - 0x01, /* power on (use it like store place) */ - 0x00, /* RFU */ - 0x00, /* int status read only */ - ci_irq_flags() | NETUP_IRQ_DETAM, /* DETAM, IRQAM unmasked */ - 0x05, /* EXTINT=active-high, INT=push-pull */ - 0x00, /* USCG1 */ - 0x04, /* ack active low */ - 0x00, /* LOCK = 0 */ - 0x33, /* serial mode, rising in, rising out, MSB first*/ - 0x31, /* synchronization */ - }; - int ret; - - ci_dbg_print("%s\n", __func__); - state = kzalloc(sizeof(struct netup_ci_state), GFP_KERNEL); - if (!state) { - ci_dbg_print("%s: Unable create CI structure!\n", __func__); - ret = -ENOMEM; - goto err; - } - - port->port_priv = state; - - switch (port->nr) { - case 1: - state->ci_i2c_addr = 0x40; - break; - case 2: - state->ci_i2c_addr = 0x41; - break; - } - - state->i2c_adap = &port->dev->i2c_bus[0].i2c_adap; - state->ca.owner = THIS_MODULE; - state->ca.read_attribute_mem = netup_ci_read_attribute_mem; - state->ca.write_attribute_mem = netup_ci_write_attribute_mem; - state->ca.read_cam_control = netup_ci_read_cam_ctl; - state->ca.write_cam_control = netup_ci_write_cam_ctl; - state->ca.slot_reset = netup_ci_slot_reset; - state->ca.slot_shutdown = netup_ci_slot_shutdown; - state->ca.slot_ts_enable = netup_ci_slot_ts_ctl; - state->ca.poll_slot_status = netup_poll_ci_slot_status; - state->ca.data = state; - state->priv = port; - state->current_irq_mode = ci_irq_flags() | NETUP_IRQ_DETAM; - - ret = netup_write_i2c(state->i2c_adap, state->ci_i2c_addr, - 0, &cimax_init[0], 34); - /* lock registers */ - ret |= netup_write_i2c(state->i2c_adap, state->ci_i2c_addr, - 0x1f, &cimax_init[0x18], 1); - /* power on slots */ - ret |= netup_write_i2c(state->i2c_adap, state->ci_i2c_addr, - 0x18, &cimax_init[0x18], 1); - - if (0 != ret) - goto err; - - ret = dvb_ca_en50221_init(&port->frontends.adapter, - &state->ca, - /* flags */ 0, - /* n_slots */ 1); - if (0 != ret) - goto err; - - INIT_WORK(&state->work, netup_read_ci_status); - schedule_work(&state->work); - - ci_dbg_print("%s: CI initialized!\n", __func__); - - return 0; -err: - ci_dbg_print("%s: Cannot initialize CI: Error %d.\n", __func__, ret); - kfree(state); - return ret; -} - -void netup_ci_exit(struct cx23885_tsport *port) -{ - struct netup_ci_state *state; - - if (NULL == port) - return; - - state = (struct netup_ci_state *)port->port_priv; - if (NULL == state) - return; - - if (NULL == state->ca.data) - return; - - dvb_ca_en50221_release(&state->ca); - kfree(state); -} diff --git a/drivers/media/video/cx23885/cimax2.h b/drivers/media/video/cx23885/cimax2.h deleted file mode 100644 index 518744a4c8a..00000000000 --- a/drivers/media/video/cx23885/cimax2.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * cimax2.h - * - * CIMax(R) SP2 driver in conjunction with NetUp Dual DVB-S2 CI card - * - * Copyright (C) 2009 NetUP Inc. - * Copyright (C) 2009 Igor M. Liplianin <liplianin@netup.ru> - * Copyright (C) 2009 Abylay Ospan <aospan@netup.ru> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef CIMAX2_H -#define CIMAX2_H -#include "dvb_ca_en50221.h" - -extern int netup_ci_read_attribute_mem(struct dvb_ca_en50221 *en50221, - int slot, int addr); -extern int netup_ci_write_attribute_mem(struct dvb_ca_en50221 *en50221, - int slot, int addr, u8 data); -extern int netup_ci_read_cam_ctl(struct dvb_ca_en50221 *en50221, - int slot, u8 addr); -extern int netup_ci_write_cam_ctl(struct dvb_ca_en50221 *en50221, - int slot, u8 addr, u8 data); -extern int netup_ci_slot_reset(struct dvb_ca_en50221 *en50221, int slot); -extern int netup_ci_slot_shutdown(struct dvb_ca_en50221 *en50221, int slot); -extern int netup_ci_slot_ts_ctl(struct dvb_ca_en50221 *en50221, int slot); -extern int netup_ci_slot_status(struct cx23885_dev *dev, u32 pci_status); -extern int netup_poll_ci_slot_status(struct dvb_ca_en50221 *en50221, - int slot, int open); -extern int netup_ci_init(struct cx23885_tsport *port); -extern void netup_ci_exit(struct cx23885_tsport *port); - -#endif diff --git a/drivers/media/video/cx23885/cx23885-417.c b/drivers/media/video/cx23885/cx23885-417.c deleted file mode 100644 index 5d5052d0253..00000000000 --- a/drivers/media/video/cx23885/cx23885-417.c +++ /dev/null @@ -1,1790 +0,0 @@ -/* - * - * Support for a cx23417 mpeg encoder via cx23885 host port. - * - * (c) 2004 Jelle Foks <jelle@foks.us> - * (c) 2004 Gerd Knorr <kraxel@bytesex.org> - * (c) 2008 Steven Toth <stoth@linuxtv.org> - * - CX23885/7/8 support - * - * Includes parts from the ivtv driver <http://sourceforge.net/projects/ivtv/> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include <linux/module.h> -#include <linux/moduleparam.h> -#include <linux/init.h> -#include <linux/fs.h> -#include <linux/delay.h> -#include <linux/device.h> -#include <linux/firmware.h> -#include <linux/slab.h> -#include <media/v4l2-common.h> -#include <media/v4l2-ioctl.h> -#include <media/cx2341x.h> - -#include "cx23885.h" -#include "cx23885-ioctl.h" - -#define CX23885_FIRM_IMAGE_SIZE 376836 -#define CX23885_FIRM_IMAGE_NAME "v4l-cx23885-enc.fw" - -static unsigned int mpegbufs = 32; -module_param(mpegbufs, int, 0644); -MODULE_PARM_DESC(mpegbufs, "number of mpeg buffers, range 2-32"); -static unsigned int mpeglines = 32; -module_param(mpeglines, int, 0644); -MODULE_PARM_DESC(mpeglines, "number of lines in an MPEG buffer, range 2-32"); -static unsigned int mpeglinesize = 512; -module_param(mpeglinesize, int, 0644); -MODULE_PARM_DESC(mpeglinesize, - "number of bytes in each line of an MPEG buffer, range 512-1024"); - -static unsigned int v4l_debug; -module_param(v4l_debug, int, 0644); -MODULE_PARM_DESC(v4l_debug, "enable V4L debug messages"); - -#define dprintk(level, fmt, arg...)\ - do { if (v4l_debug >= level) \ - printk(KERN_DEBUG "%s: " fmt, \ - (dev) ? dev->name : "cx23885[?]", ## arg); \ - } while (0) - -static struct cx23885_tvnorm cx23885_tvnorms[] = { - { - .name = "NTSC-M", - .id = V4L2_STD_NTSC_M, - }, { - .name = "NTSC-JP", - .id = V4L2_STD_NTSC_M_JP, - }, { - .name = "PAL-BG", - .id = V4L2_STD_PAL_BG, - }, { - .name = "PAL-DK", - .id = V4L2_STD_PAL_DK, - }, { - .name = "PAL-I", - .id = V4L2_STD_PAL_I, - }, { - .name = "PAL-M", - .id = V4L2_STD_PAL_M, - }, { - .name = "PAL-N", - .id = V4L2_STD_PAL_N, - }, { - .name = "PAL-Nc", - .id = V4L2_STD_PAL_Nc, - }, { - .name = "PAL-60", - .id = V4L2_STD_PAL_60, - }, { - .name = "SECAM-L", - .id = V4L2_STD_SECAM_L, - }, { - .name = "SECAM-DK", - .id = V4L2_STD_SECAM_DK, - } -}; - -/* ------------------------------------------------------------------ */ -enum cx23885_capture_type { - CX23885_MPEG_CAPTURE, - CX23885_RAW_CAPTURE, - CX23885_RAW_PASSTHRU_CAPTURE -}; -enum cx23885_capture_bits { - CX23885_RAW_BITS_NONE = 0x00, - CX23885_RAW_BITS_YUV_CAPTURE = 0x01, - CX23885_RAW_BITS_PCM_CAPTURE = 0x02, - CX23885_RAW_BITS_VBI_CAPTURE = 0x04, - CX23885_RAW_BITS_PASSTHRU_CAPTURE = 0x08, - CX23885_RAW_BITS_TO_HOST_CAPTURE = 0x10 -}; -enum cx23885_capture_end { - CX23885_END_AT_GOP, /* stop at the end of gop, generate irq */ - CX23885_END_NOW, /* stop immediately, no irq */ -}; -enum cx23885_framerate { - CX23885_FRAMERATE_NTSC_30, /* NTSC: 30fps */ - CX23885_FRAMERATE_PAL_25 /* PAL: 25fps */ -}; -enum cx23885_stream_port { - CX23885_OUTPUT_PORT_MEMORY, - CX23885_OUTPUT_PORT_STREAMING, - CX23885_OUTPUT_PORT_SERIAL -}; -enum cx23885_data_xfer_status { - CX23885_MORE_BUFFERS_FOLLOW, - CX23885_LAST_BUFFER, -}; -enum cx23885_picture_mask { - CX23885_PICTURE_MASK_NONE, - CX23885_PICTURE_MASK_I_FRAMES, - CX23885_PICTURE_MASK_I_P_FRAMES = 0x3, - CX23885_PICTURE_MASK_ALL_FRAMES = 0x7, -}; -enum cx23885_vbi_mode_bits { - CX23885_VBI_BITS_SLICED, - CX23885_VBI_BITS_RAW, -}; -enum cx23885_vbi_insertion_bits { - CX23885_VBI_BITS_INSERT_IN_XTENSION_USR_DATA, - CX23885_VBI_BITS_INSERT_IN_PRIVATE_PACKETS = 0x1 << 1, - CX23885_VBI_BITS_SEPARATE_STREAM = 0x2 << 1, - CX23885_VBI_BITS_SEPARATE_STREAM_USR_DATA = 0x4 << 1, - CX23885_VBI_BITS_SEPARATE_STREAM_PRV_DATA = 0x5 << 1, -}; -enum cx23885_dma_unit { - CX23885_DMA_BYTES, - CX23885_DMA_FRAMES, -}; -enum cx23885_dma_transfer_status_bits { - CX23885_DMA_TRANSFER_BITS_DONE = 0x01, - CX23885_DMA_TRANSFER_BITS_ERROR = 0x04, - CX23885_DMA_TRANSFER_BITS_LL_ERROR = 0x10, -}; -enum cx23885_pause { - CX23885_PAUSE_ENCODING, - CX23885_RESUME_ENCODING, -}; -enum cx23885_copyright { - CX23885_COPYRIGHT_OFF, - CX23885_COPYRIGHT_ON, -}; -enum cx23885_notification_type { - CX23885_NOTIFICATION_REFRESH, -}; -enum cx23885_notification_status { - CX23885_NOTIFICATION_OFF, - CX23885_NOTIFICATION_ON, -}; -enum cx23885_notification_mailbox { - CX23885_NOTIFICATION_NO_MAILBOX = -1, -}; -enum cx23885_field1_lines { - CX23885_FIELD1_SAA7114 = 0x00EF, /* 239 */ - CX23885_FIELD1_SAA7115 = 0x00F0, /* 240 */ - CX23885_FIELD1_MICRONAS = 0x0105, /* 261 */ -}; -enum cx23885_field2_lines { - CX23885_FIELD2_SAA7114 = 0x00EF, /* 239 */ - CX23885_FIELD2_SAA7115 = 0x00F0, /* 240 */ - CX23885_FIELD2_MICRONAS = 0x0106, /* 262 */ -}; -enum cx23885_custom_data_type { - CX23885_CUSTOM_EXTENSION_USR_DATA, - CX23885_CUSTOM_PRIVATE_PACKET, -}; -enum cx23885_mute { - CX23885_UNMUTE, - CX23885_MUTE, -}; -enum cx23885_mute_video_mask { - CX23885_MUTE_VIDEO_V_MASK = 0x0000FF00, - CX23885_MUTE_VIDEO_U_MASK = 0x00FF0000, - CX23885_MUTE_VIDEO_Y_MASK = 0xFF000000, -}; -enum cx23885_mute_video_shift { - CX23885_MUTE_VIDEO_V_SHIFT = 8, - CX23885_MUTE_VIDEO_U_SHIFT = 16, - CX23885_MUTE_VIDEO_Y_SHIFT = 24, -}; - -/* defines below are from ivtv-driver.h */ -#define IVTV_CMD_HW_BLOCKS_RST 0xFFFFFFFF - -/* Firmware API commands */ -#define IVTV_API_STD_TIMEOUT 500 - -/* Registers */ -/* IVTV_REG_OFFSET */ -#define IVTV_REG_ENC_SDRAM_REFRESH (0x07F8) -#define IVTV_REG_ENC_SDRAM_PRECHARGE (0x07FC) -#define IVTV_REG_SPU (0x9050) -#define IVTV_REG_HW_BLOCKS (0x9054) -#define IVTV_REG_VPU (0x9058) -#define IVTV_REG_APU (0xA064) - -/**** Bit definitions for MC417_RWD and MC417_OEN registers *** - bits 31-16 -+-----------+ -| Reserved | -+-----------+ - bit 15 bit 14 bit 13 bit 12 bit 11 bit 10 bit 9 bit 8 -+-------+-------+-------+-------+-------+-------+-------+-------+ -| MIWR# | MIRD# | MICS# |MIRDY# |MIADDR3|MIADDR2|MIADDR1|MIADDR0| -+-------+-------+-------+-------+-------+-------+-------+-------+ - bit 7 bit 6 bit 5 bit 4 bit 3 bit 2 bit 1 bit 0 -+-------+-------+-------+-------+-------+-------+-------+-------+ -|MIDATA7|MIDATA6|MIDATA5|MIDATA4|MIDATA3|MIDATA2|MIDATA1|MIDATA0| -+-------+-------+-------+-------+-------+-------+-------+-------+ -***/ -#define MC417_MIWR 0x8000 -#define MC417_MIRD 0x4000 -#define MC417_MICS 0x2000 -#define MC417_MIRDY 0x1000 -#define MC417_MIADDR 0x0F00 -#define MC417_MIDATA 0x00FF - -/* MIADDR* nibble definitions */ -#define MCI_MEMORY_DATA_BYTE0 0x000 -#define MCI_MEMORY_DATA_BYTE1 0x100 -#define MCI_MEMORY_DATA_BYTE2 0x200 -#define MCI_MEMORY_DATA_BYTE3 0x300 -#define MCI_MEMORY_ADDRESS_BYTE2 0x400 -#define MCI_MEMORY_ADDRESS_BYTE1 0x500 -#define MCI_MEMORY_ADDRESS_BYTE0 0x600 -#define MCI_REGISTER_DATA_BYTE0 0x800 -#define MCI_REGISTER_DATA_BYTE1 0x900 -#define MCI_REGISTER_DATA_BYTE2 0xA00 -#define MCI_REGISTER_DATA_BYTE3 0xB00 -#define MCI_REGISTER_ADDRESS_BYTE0 0xC00 -#define MCI_REGISTER_ADDRESS_BYTE1 0xD00 -#define MCI_REGISTER_MODE 0xE00 - -/* Read and write modes */ -#define MCI_MODE_REGISTER_READ 0 -#define MCI_MODE_REGISTER_WRITE 1 -#define MCI_MODE_MEMORY_READ 0 -#define MCI_MODE_MEMORY_WRITE 0x40 - -/*** Bit definitions for MC417_CTL register **** - bits 31-6 bits 5-4 bit 3 bits 2-1 Bit 0 -+--------+-------------+--------+--------------+------------+ -|Reserved|MC417_SPD_CTL|Reserved|MC417_GPIO_SEL|UART_GPIO_EN| -+--------+-------------+--------+--------------+------------+ -***/ -#define MC417_SPD_CTL(x) (((x) << 4) & 0x00000030) -#define MC417_GPIO_SEL(x) (((x) << 1) & 0x00000006) -#define MC417_UART_GPIO_EN 0x00000001 - -/* Values for speed control */ -#define MC417_SPD_CTL_SLOW 0x1 -#define MC417_SPD_CTL_MEDIUM 0x0 -#define MC417_SPD_CTL_FAST 0x3 /* b'1x, but we use b'11 */ - -/* Values for GPIO select */ -#define MC417_GPIO_SEL_GPIO3 0x3 -#define MC417_GPIO_SEL_GPIO2 0x2 -#define MC417_GPIO_SEL_GPIO1 0x1 -#define MC417_GPIO_SEL_GPIO0 0x0 - -void cx23885_mc417_init(struct cx23885_dev *dev) -{ - u32 regval; - - dprintk(2, "%s()\n", __func__); - - /* Configure MC417_CTL register to defaults. */ - regval = MC417_SPD_CTL(MC417_SPD_CTL_FAST) | - MC417_GPIO_SEL(MC417_GPIO_SEL_GPIO3) | - MC417_UART_GPIO_EN; - cx_write(MC417_CTL, regval); - - /* Configure MC417_OEN to defaults. */ - regval = MC417_MIRDY; - cx_write(MC417_OEN, regval); - - /* Configure MC417_RWD to defaults. */ - regval = MC417_MIWR | MC417_MIRD | MC417_MICS; - cx_write(MC417_RWD, regval); -} - -static int mc417_wait_ready(struct cx23885_dev *dev) -{ - u32 mi_ready; - unsigned long timeout = jiffies + msecs_to_jiffies(1); - - for (;;) { - mi_ready = cx_read(MC417_RWD) & MC417_MIRDY; - if (mi_ready != 0) - return 0; - if (time_after(jiffies, timeout)) - return -1; - udelay(1); - } -} - -int mc417_register_write(struct cx23885_dev *dev, u16 address, u32 value) -{ - u32 regval; - - /* Enable MC417 GPIO outputs except for MC417_MIRDY, - * which is an input. - */ - cx_write(MC417_OEN, MC417_MIRDY); - - /* Write data byte 0 */ - regval = MC417_MIRD | MC417_MIRDY | MCI_REGISTER_DATA_BYTE0 | - (value & 0x000000FF); - cx_write(MC417_RWD, regval); - - /* Transition CS/WR to effect write transaction across bus. */ - regval |= MC417_MICS | MC417_MIWR; - cx_write(MC417_RWD, regval); - - /* Write data byte 1 */ - regval = MC417_MIRD | MC417_MIRDY | MCI_REGISTER_DATA_BYTE1 | - ((value >> 8) & 0x000000FF); - cx_write(MC417_RWD, regval); - regval |= MC417_MICS | MC417_MIWR; - cx_write(MC417_RWD, regval); - - /* Write data byte 2 */ - regval = MC417_MIRD | MC417_MIRDY | MCI_REGISTER_DATA_BYTE2 | - ((value >> 16) & 0x000000FF); - cx_write(MC417_RWD, regval); - regval |= MC417_MICS | MC417_MIWR; - cx_write(MC417_RWD, regval); - - /* Write data byte 3 */ - regval = MC417_MIRD | MC417_MIRDY | MCI_REGISTER_DATA_BYTE3 | - ((value >> 24) & 0x000000FF); - cx_write(MC417_RWD, regval); - regval |= MC417_MICS | MC417_MIWR; - cx_write(MC417_RWD, regval); - - /* Write address byte 0 */ - regval = MC417_MIRD | MC417_MIRDY | MCI_REGISTER_ADDRESS_BYTE0 | - (address & 0xFF); - cx_write(MC417_RWD, regval); - regval |= MC417_MICS | MC417_MIWR; - cx_write(MC417_RWD, regval); - - /* Write address byte 1 */ - regval = MC417_MIRD | MC417_MIRDY | MCI_REGISTER_ADDRESS_BYTE1 | - ((address >> 8) & 0xFF); - cx_write(MC417_RWD, regval); - regval |= MC417_MICS | MC417_MIWR; - cx_write(MC417_RWD, regval); - - /* Indicate that this is a write. */ - regval = MC417_MIRD | MC417_MIRDY | MCI_REGISTER_MODE | - MCI_MODE_REGISTER_WRITE; - cx_write(MC417_RWD, regval); - regval |= MC417_MICS | MC417_MIWR; - cx_write(MC417_RWD, regval); - - /* Wait for the trans to complete (MC417_MIRDY asserted). */ - return mc417_wait_ready(dev); -} - -int mc417_register_read(struct cx23885_dev *dev, u16 address, u32 *value) -{ - int retval; - u32 regval; - u32 tempval; - u32 dataval; - - /* Enable MC417 GPIO outputs except for MC417_MIRDY, - * which is an input. - */ - cx_write(MC417_OEN, MC417_MIRDY); - - /* Write address byte 0 */ - regval = MC417_MIRD | MC417_MIRDY | MCI_REGISTER_ADDRESS_BYTE0 | - ((address & 0x00FF)); - cx_write(MC417_RWD, regval); - regval |= MC417_MICS | MC417_MIWR; - cx_write(MC417_RWD, regval); - - /* Write address byte 1 */ - regval = MC417_MIRD | MC417_MIRDY | MCI_REGISTER_ADDRESS_BYTE1 | - ((address >> 8) & 0xFF); - cx_write(MC417_RWD, regval); - regval |= MC417_MICS | MC417_MIWR; - cx_write(MC417_RWD, regval); - - /* Indicate that this is a register read. */ - regval = MC417_MIRD | MC417_MIRDY | MCI_REGISTER_MODE | - MCI_MODE_REGISTER_READ; - cx_write(MC417_RWD, regval); - regval |= MC417_MICS | MC417_MIWR; - cx_write(MC417_RWD, regval); - - /* Wait for the trans to complete (MC417_MIRDY asserted). */ - retval = mc417_wait_ready(dev); - - /* switch the DAT0-7 GPIO[10:3] to input mode */ - cx_write(MC417_OEN, MC417_MIRDY | MC417_MIDATA); - - /* Read data byte 0 */ - regval = MC417_MIRD | MC417_MIRDY | MCI_REGISTER_DATA_BYTE0; - cx_write(MC417_RWD, regval); - - /* Transition RD to effect read transaction across bus. - * Transtion 0x5000 -> 0x9000 correct (RD/RDY -> WR/RDY)? - * Should it be 0x9000 -> 0xF000 (also why is RDY being set, its - * input only...) - */ - regval = MC417_MIWR | MC417_MIRDY | MCI_REGISTER_DATA_BYTE0; - cx_write(MC417_RWD, regval); - - /* Collect byte */ - tempval = cx_read(MC417_RWD); - dataval = tempval & 0x000000FF; - - /* Bring CS and RD high. */ - regval = MC417_MIWR | MC417_MIRD | MC417_MICS | MC417_MIRDY; - cx_write(MC417_RWD, regval); - - /* Read data byte 1 */ - regval = MC417_MIRD | MC417_MIRDY | MCI_REGISTER_DATA_BYTE1; - cx_write(MC417_RWD, regval); - regval = MC417_MIWR | MC417_MIRDY | MCI_REGISTER_DATA_BYTE1; - cx_write(MC417_RWD, regval); - tempval = cx_read(MC417_RWD); - dataval |= ((tempval & 0x000000FF) << 8); - regval = MC417_MIWR | MC417_MIRD | MC417_MICS | MC417_MIRDY; - cx_write(MC417_RWD, regval); - - /* Read data byte 2 */ - regval = MC417_MIRD | MC417_MIRDY | MCI_REGISTER_DATA_BYTE2; - cx_write(MC417_RWD, regval); - regval = MC417_MIWR | MC417_MIRDY | MCI_REGISTER_DATA_BYTE2; - cx_write(MC417_RWD, regval); - tempval = cx_read(MC417_RWD); - dataval |= ((tempval & 0x000000FF) << 16); - regval = MC417_MIWR | MC417_MIRD | MC417_MICS | MC417_MIRDY; - cx_write(MC417_RWD, regval); - - /* Read data byte 3 */ - regval = MC417_MIRD | MC417_MIRDY | MCI_REGISTER_DATA_BYTE3; - cx_write(MC417_RWD, regval); - regval = MC417_MIWR | MC417_MIRDY | MCI_REGISTER_DATA_BYTE3; - cx_write(MC417_RWD, regval); - tempval = cx_read(MC417_RWD); - dataval |= ((tempval & 0x000000FF) << 24); - regval = MC417_MIWR | MC417_MIRD | MC417_MICS | MC417_MIRDY; - cx_write(MC417_RWD, regval); - - *value = dataval; - - return retval; -} - -int mc417_memory_write(struct cx23885_dev *dev, u32 address, u32 value) -{ - u32 regval; - - /* Enable MC417 GPIO outputs except for MC417_MIRDY, - * which is an input. - */ - cx_write(MC417_OEN, MC417_MIRDY); - - /* Write data byte 0 */ - regval = MC417_MIRD | MC417_MIRDY | MCI_MEMORY_DATA_BYTE0 | - (value & 0x000000FF); - cx_write(MC417_RWD, regval); - - /* Transition CS/WR to effect write transaction across bus. */ - regval |= MC417_MICS | MC417_MIWR; - cx_write(MC417_RWD, regval); - - /* Write data byte 1 */ - regval = MC417_MIRD | MC417_MIRDY | MCI_MEMORY_DATA_BYTE1 | - ((value >> 8) & 0x000000FF); - cx_write(MC417_RWD, regval); - regval |= MC417_MICS | MC417_MIWR; - cx_write(MC417_RWD, regval); - - /* Write data byte 2 */ - regval = MC417_MIRD | MC417_MIRDY | MCI_MEMORY_DATA_BYTE2 | - ((value >> 16) & 0x000000FF); - cx_write(MC417_RWD, regval); - regval |= MC417_MICS | MC417_MIWR; - cx_write(MC417_RWD, regval); - - /* Write data byte 3 */ - regval = MC417_MIRD | MC417_MIRDY | MCI_MEMORY_DATA_BYTE3 | - ((value >> 24) & 0x000000FF); - cx_write(MC417_RWD, regval); - regval |= MC417_MICS | MC417_MIWR; - cx_write(MC417_RWD, regval); - - /* Write address byte 2 */ - regval = MC417_MIRD | MC417_MIRDY | MCI_MEMORY_ADDRESS_BYTE2 | - MCI_MODE_MEMORY_WRITE | ((address >> 16) & 0x3F); - cx_write(MC417_RWD, regval); - regval |= MC417_MICS | MC417_MIWR; - cx_write(MC417_RWD, regval); - - /* Write address byte 1 */ - regval = MC417_MIRD | MC417_MIRDY | MCI_MEMORY_ADDRESS_BYTE1 | - ((address >> 8) & 0xFF); - cx_write(MC417_RWD, regval); - regval |= MC417_MICS | MC417_MIWR; - cx_write(MC417_RWD, regval); - - /* Write address byte 0 */ - regval = MC417_MIRD | MC417_MIRDY | MCI_MEMORY_ADDRESS_BYTE0 | - (address & 0xFF); - cx_write(MC417_RWD, regval); - regval |= MC417_MICS | MC417_MIWR; - cx_write(MC417_RWD, regval); - - /* Wait for the trans to complete (MC417_MIRDY asserted). */ - return mc417_wait_ready(dev); -} - -int mc417_memory_read(struct cx23885_dev *dev, u32 address, u32 *value) -{ - int retval; - u32 regval; - u32 tempval; - u32 dataval; - - /* Enable MC417 GPIO outputs except for MC417_MIRDY, - * which is an input. - */ - cx_write(MC417_OEN, MC417_MIRDY); - - /* Write address byte 2 */ - regval = MC417_MIRD | MC417_MIRDY | MCI_MEMORY_ADDRESS_BYTE2 | - MCI_MODE_MEMORY_READ | ((address >> 16) & 0x3F); - cx_write(MC417_RWD, regval); - regval |= MC417_MICS | MC417_MIWR; - cx_write(MC417_RWD, regval); - - /* Write address byte 1 */ - regval = MC417_MIRD | MC417_MIRDY | MCI_MEMORY_ADDRESS_BYTE1 | - ((address >> 8) & 0xFF); - cx_write(MC417_RWD, regval); - regval |= MC417_MICS | MC417_MIWR; - cx_write(MC417_RWD, regval); - - /* Write address byte 0 */ - regval = MC417_MIRD | MC417_MIRDY | MCI_MEMORY_ADDRESS_BYTE0 | - (address & 0xFF); - cx_write(MC417_RWD, regval); - regval |= MC417_MICS | MC417_MIWR; - cx_write(MC417_RWD, regval); - - /* Wait for the trans to complete (MC417_MIRDY asserted). */ - retval = mc417_wait_ready(dev); - - /* switch the DAT0-7 GPIO[10:3] to input mode */ - cx_write(MC417_OEN, MC417_MIRDY | MC417_MIDATA); - - /* Read data byte 3 */ - regval = MC417_MIRD | MC417_MIRDY | MCI_MEMORY_DATA_BYTE3; - cx_write(MC417_RWD, regval); - - /* Transition RD to effect read transaction across bus. */ - regval = MC417_MIWR | MC417_MIRDY | MCI_MEMORY_DATA_BYTE3; - cx_write(MC417_RWD, regval); - - /* Collect byte */ - tempval = cx_read(MC417_RWD); - dataval = ((tempval & 0x000000FF) << 24); - - /* Bring CS and RD high. */ - regval = MC417_MIWR | MC417_MIRD | MC417_MICS | MC417_MIRDY; - cx_write(MC417_RWD, regval); - - /* Read data byte 2 */ - regval = MC417_MIRD | MC417_MIRDY | MCI_MEMORY_DATA_BYTE2; - cx_write(MC417_RWD, regval); - regval = MC417_MIWR | MC417_MIRDY | MCI_MEMORY_DATA_BYTE2; - cx_write(MC417_RWD, regval); - tempval = cx_read(MC417_RWD); - dataval |= ((tempval & 0x000000FF) << 16); - regval = MC417_MIWR | MC417_MIRD | MC417_MICS | MC417_MIRDY; - cx_write(MC417_RWD, regval); - - /* Read data byte 1 */ - regval = MC417_MIRD | MC417_MIRDY | MCI_MEMORY_DATA_BYTE1; - cx_write(MC417_RWD, regval); - regval = MC417_MIWR | MC417_MIRDY | MCI_MEMORY_DATA_BYTE1; - cx_write(MC417_RWD, regval); - tempval = cx_read(MC417_RWD); - dataval |= ((tempval & 0x000000FF) << 8); - regval = MC417_MIWR | MC417_MIRD | MC417_MICS | MC417_MIRDY; - cx_write(MC417_RWD, regval); - - /* Read data byte 0 */ - regval = MC417_MIRD | MC417_MIRDY | MCI_MEMORY_DATA_BYTE0; - cx_write(MC417_RWD, regval); - regval = MC417_MIWR | MC417_MIRDY | MCI_MEMORY_DATA_BYTE0; - cx_write(MC417_RWD, regval); - tempval = cx_read(MC417_RWD); - dataval |= (tempval & 0x000000FF); - regval = MC417_MIWR | MC417_MIRD | MC417_MICS | MC417_MIRDY; - cx_write(MC417_RWD, regval); - - *value = dataval; - - return retval; -} - -void mc417_gpio_set(struct cx23885_dev *dev, u32 mask) -{ - u32 val; - - /* Set the gpio value */ - mc417_register_read(dev, 0x900C, &val); - val |= (mask & 0x000ffff); - mc417_register_write(dev, 0x900C, val); -} - -void mc417_gpio_clear(struct cx23885_dev *dev, u32 mask) -{ - u32 val; - - /* Clear the gpio value */ - mc417_register_read(dev, 0x900C, &val); - val &= ~(mask & 0x0000ffff); - mc417_register_write(dev, 0x900C, val); -} - -void mc417_gpio_enable(struct cx23885_dev *dev, u32 mask, int asoutput) -{ - u32 val; - - /* Enable GPIO direction bits */ - mc417_register_read(dev, 0x9020, &val); - if (asoutput) - val |= (mask & 0x0000ffff); - else - val &= ~(mask & 0x0000ffff); - - mc417_register_write(dev, 0x9020, val); -} -/* ------------------------------------------------------------------ */ - -/* MPEG encoder API */ -static char *cmd_to_str(int cmd) -{ - switch (cmd) { - case CX2341X_ENC_PING_FW: - return "PING_FW"; - case CX2341X_ENC_START_CAPTURE: - return "START_CAPTURE"; - case CX2341X_ENC_STOP_CAPTURE: - return "STOP_CAPTURE"; - case CX2341X_ENC_SET_AUDIO_ID: - return "SET_AUDIO_ID"; - case CX2341X_ENC_SET_VIDEO_ID: - return "SET_VIDEO_ID"; - case CX2341X_ENC_SET_PCR_ID: - return "SET_PCR_ID"; - case CX2341X_ENC_SET_FRAME_RATE: - return "SET_FRAME_RATE"; - case CX2341X_ENC_SET_FRAME_SIZE: - return "SET_FRAME_SIZE"; - case CX2341X_ENC_SET_BIT_RATE: - return "SET_BIT_RATE"; - case CX2341X_ENC_SET_GOP_PROPERTIES: - return "SET_GOP_PROPERTIES"; - case CX2341X_ENC_SET_ASPECT_RATIO: - return "SET_ASPECT_RATIO"; - case CX2341X_ENC_SET_DNR_FILTER_MODE: - return "SET_DNR_FILTER_MODE"; - case CX2341X_ENC_SET_DNR_FILTER_PROPS: - return "SET_DNR_FILTER_PROPS"; - case CX2341X_ENC_SET_CORING_LEVELS: - return "SET_CORING_LEVELS"; - case CX2341X_ENC_SET_SPATIAL_FILTER_TYPE: - return "SET_SPATIAL_FILTER_TYPE"; - case CX2341X_ENC_SET_VBI_LINE: - return "SET_VBI_LINE"; - case CX2341X_ENC_SET_STREAM_TYPE: - return "SET_STREAM_TYPE"; - case CX2341X_ENC_SET_OUTPUT_PORT: - return "SET_OUTPUT_PORT"; - case CX2341X_ENC_SET_AUDIO_PROPERTIES: - return "SET_AUDIO_PROPERTIES"; - case CX2341X_ENC_HALT_FW: - return "HALT_FW"; - case CX2341X_ENC_GET_VERSION: - return "GET_VERSION"; - case CX2341X_ENC_SET_GOP_CLOSURE: - return "SET_GOP_CLOSURE"; - case CX2341X_ENC_GET_SEQ_END: - return "GET_SEQ_END"; - case CX2341X_ENC_SET_PGM_INDEX_INFO: - return "SET_PGM_INDEX_INFO"; - case CX2341X_ENC_SET_VBI_CONFIG: - return "SET_VBI_CONFIG"; - case CX2341X_ENC_SET_DMA_BLOCK_SIZE: - return "SET_DMA_BLOCK_SIZE"; - case CX2341X_ENC_GET_PREV_DMA_INFO_MB_10: - return "GET_PREV_DMA_INFO_MB_10"; - case CX2341X_ENC_GET_PREV_DMA_INFO_MB_9: - return "GET_PREV_DMA_INFO_MB_9"; - case CX2341X_ENC_SCHED_DMA_TO_HOST: - return "SCHED_DMA_TO_HOST"; - case CX2341X_ENC_INITIALIZE_INPUT: - return "INITIALIZE_INPUT"; - case CX2341X_ENC_SET_FRAME_DROP_RATE: - return "SET_FRAME_DROP_RATE"; - case CX2341X_ENC_PAUSE_ENCODER: - return "PAUSE_ENCODER"; - case CX2341X_ENC_REFRESH_INPUT: - return "REFRESH_INPUT"; - case CX2341X_ENC_SET_COPYRIGHT: - return "SET_COPYRIGHT"; - case CX2341X_ENC_SET_EVENT_NOTIFICATION: - return "SET_EVENT_NOTIFICATION"; - case CX2341X_ENC_SET_NUM_VSYNC_LINES: - return "SET_NUM_VSYNC_LINES"; - case CX2341X_ENC_SET_PLACEHOLDER: - return "SET_PLACEHOLDER"; - case CX2341X_ENC_MUTE_VIDEO: - return "MUTE_VIDEO"; - case CX2341X_ENC_MUTE_AUDIO: - return "MUTE_AUDIO"; - case CX2341X_ENC_MISC: - return "MISC"; - default: - return "UNKNOWN"; - } -} - -static int cx23885_mbox_func(void *priv, - u32 command, - int in, - int out, - u32 data[CX2341X_MBOX_MAX_DATA]) -{ - struct cx23885_dev *dev = priv; - unsigned long timeout; - u32 value, flag, retval = 0; - int i; - - dprintk(3, "%s: command(0x%X) = %s\n", __func__, command, - cmd_to_str(command)); - - /* this may not be 100% safe if we can't read any memory location - without side effects */ - mc417_memory_read(dev, dev->cx23417_mailbox - 4, &value); - if (value != 0x12345678) { - printk(KERN_ERR - "Firmware and/or mailbox pointer not initialized " - "or corrupted, signature = 0x%x, cmd = %s\n", value, - cmd_to_str(command)); - return -1; - } - - /* This read looks at 32 bits, but flag is only 8 bits. - * Seems we also bail if CMD or TIMEOUT bytes are set??? - */ - mc417_memory_read(dev, dev->cx23417_mailbox, &flag); - if (flag) { - printk(KERN_ERR "ERROR: Mailbox appears to be in use " - "(%x), cmd = %s\n", flag, cmd_to_str(command)); - return -1; - } - - flag |= 1; /* tell 'em we're working on it */ - mc417_memory_write(dev, dev->cx23417_mailbox, flag); - - /* write command + args + fill remaining with zeros */ - /* command code */ - mc417_memory_write(dev, dev->cx23417_mailbox + 1, command); - mc417_memory_write(dev, dev->cx23417_mailbox + 3, - IVTV_API_STD_TIMEOUT); /* timeout */ - for (i = 0; i < in; i++) { - mc417_memory_write(dev, dev->cx23417_mailbox + 4 + i, data[i]); - dprintk(3, "API Input %d = %d\n", i, data[i]); - } - for (; i < CX2341X_MBOX_MAX_DATA; i++) - mc417_memory_write(dev, dev->cx23417_mailbox + 4 + i, 0); - - flag |= 3; /* tell 'em we're done writing */ - mc417_memory_write(dev, dev->cx23417_mailbox, flag); - - /* wait for firmware to handle the API command */ - timeout = jiffies + msecs_to_jiffies(10); - for (;;) { - mc417_memory_read(dev, dev->cx23417_mailbox, &flag); - if (0 != (flag & 4)) - break; - if (time_after(jiffies, timeout)) { - printk(KERN_ERR "ERROR: API Mailbox timeout\n"); - return -1; - } - udelay(10); - } - - /* read output values */ - for (i = 0; i < out; i++) { - mc417_memory_read(dev, dev->cx23417_mailbox + 4 + i, data + i); - dprintk(3, "API Output %d = %d\n", i, data[i]); - } - - mc417_memory_read(dev, dev->cx23417_mailbox + 2, &retval); - dprintk(3, "API result = %d\n", retval); - - flag = 0; - mc417_memory_write(dev, dev->cx23417_mailbox, flag); - - return retval; -} - -/* We don't need to call the API often, so using just one - * mailbox will probably suffice - */ -static int cx23885_api_cmd(struct cx23885_dev *dev, - u32 command, - u32 inputcnt, - u32 outputcnt, - ...) -{ - u32 data[CX2341X_MBOX_MAX_DATA]; - va_list vargs; - int i, err; - - dprintk(3, "%s() cmds = 0x%08x\n", __func__, command); - - va_start(vargs, outputcnt); - for (i = 0; i < inputcnt; i++) - data[i] = va_arg(vargs, int); - - err = cx23885_mbox_func(dev, command, inputcnt, outputcnt, data); - for (i = 0; i < outputcnt; i++) { - int *vptr = va_arg(vargs, int *); - *vptr = data[i]; - } - va_end(vargs); - - return err; -} - -static int cx23885_find_mailbox(struct cx23885_dev *dev) -{ - u32 signature[4] = { - 0x12345678, 0x34567812, 0x56781234, 0x78123456 - }; - int signaturecnt = 0; - u32 value; - int i; - - dprintk(2, "%s()\n", __func__); - - for (i = 0; i < CX23885_FIRM_IMAGE_SIZE; i++) { - mc417_memory_read(dev, i, &value); - if (value == signature[signaturecnt]) - signaturecnt++; - else - signaturecnt = 0; - if (4 == signaturecnt) { - dprintk(1, "Mailbox signature found at 0x%x\n", i+1); - return i+1; - } - } - printk(KERN_ERR "Mailbox signature values not found!\n"); - return -1; -} - -static int cx23885_load_firmware(struct cx23885_dev *dev) -{ - static const unsigned char magic[8] = { - 0xa7, 0x0d, 0x00, 0x00, 0x66, 0xbb, 0x55, 0xaa - }; - const struct firmware *firmware; - int i, retval = 0; - u32 value = 0; - u32 gpio_output = 0; - u32 gpio_value; - u32 checksum = 0; - u32 *dataptr; - - dprintk(2, "%s()\n", __func__); - - /* Save GPIO settings before reset of APU */ - retval |= mc417_memory_read(dev, 0x9020, &gpio_output); - retval |= mc417_memory_read(dev, 0x900C, &gpio_value); - - retval = mc417_register_write(dev, - IVTV_REG_VPU, 0xFFFFFFED); - retval |= mc417_register_write(dev, - IVTV_REG_HW_BLOCKS, IVTV_CMD_HW_BLOCKS_RST); - retval |= mc417_register_write(dev, - IVTV_REG_ENC_SDRAM_REFRESH, 0x80000800); - retval |= mc417_register_write(dev, - IVTV_REG_ENC_SDRAM_PRECHARGE, 0x1A); - retval |= mc417_register_write(dev, - IVTV_REG_APU, 0); - - if (retval != 0) { - printk(KERN_ERR "%s: Error with mc417_register_write\n", - __func__); - return -1; - } - - retval = request_firmware(&firmware, CX23885_FIRM_IMAGE_NAME, - &dev->pci->dev); - - if (retval != 0) { - printk(KERN_ERR - "ERROR: Hotplug firmware request failed (%s).\n", - CX23885_FIRM_IMAGE_NAME); - printk(KERN_ERR "Please fix your hotplug setup, the board will " - "not work without firmware loaded!\n"); - return -1; - } - - if (firmware->size != CX23885_FIRM_IMAGE_SIZE) { - printk(KERN_ERR "ERROR: Firmware size mismatch " - "(have %zd, expected %d)\n", - firmware->size, CX23885_FIRM_IMAGE_SIZE); - release_firmware(firmware); - return -1; - } - - if (0 != memcmp(firmware->data, magic, 8)) { - printk(KERN_ERR - "ERROR: Firmware magic mismatch, wrong file?\n"); - release_firmware(firmware); - return -1; - } - - /* transfer to the chip */ - dprintk(2, "Loading firmware ...\n"); - dataptr = (u32 *)firmware->data; - for (i = 0; i < (firmware->size >> 2); i++) { - value = *dataptr; - checksum += ~value; - if (mc417_memory_write(dev, i, value) != 0) { - printk(KERN_ERR "ERROR: Loading firmware failed!\n"); - release_firmware(firmware); - return -1; - } - dataptr++; - } - - /* read back to verify with the checksum */ - dprintk(1, "Verifying firmware ...\n"); - for (i--; i >= 0; i--) { - if (mc417_memory_read(dev, i, &value) != 0) { - printk(KERN_ERR "ERROR: Reading firmware failed!\n"); - release_firmware(firmware); - return -1; - } - checksum -= ~value; - } - if (checksum) { - printk(KERN_ERR - "ERROR: Firmware load failed (checksum mismatch).\n"); - release_firmware(firmware); - return -1; - } - release_firmware(firmware); - dprintk(1, "Firmware upload successful.\n"); - - retval |= mc417_register_write(dev, IVTV_REG_HW_BLOCKS, - IVTV_CMD_HW_BLOCKS_RST); - - /* F/W power up disturbs the GPIOs, restore state */ - retval |= mc417_register_write(dev, 0x9020, gpio_output); - retval |= mc417_register_write(dev, 0x900C, gpio_value); - - retval |= mc417_register_read(dev, IVTV_REG_VPU, &value); - retval |= mc417_register_write(dev, IVTV_REG_VPU, value & 0xFFFFFFE8); - - /* Hardcoded GPIO's here */ - retval |= mc417_register_write(dev, 0x9020, 0x4000); - retval |= mc417_register_write(dev, 0x900C, 0x4000); - - mc417_register_read(dev, 0x9020, &gpio_output); - mc417_register_read(dev, 0x900C, &gpio_value); - - if (retval < 0) - printk(KERN_ERR "%s: Error with mc417_register_write\n", - __func__); - return 0; -} - -void cx23885_417_check_encoder(struct cx23885_dev *dev) -{ - u32 status, seq; - - status = seq = 0; - cx23885_api_cmd(dev, CX2341X_ENC_GET_SEQ_END, 0, 2, &status, &seq); - dprintk(1, "%s() status = %d, seq = %d\n", __func__, status, seq); -} - -static void cx23885_codec_settings(struct cx23885_dev *dev) -{ - dprintk(1, "%s()\n", __func__); - - /* Dynamically change the height based on video standard */ - if (dev->encodernorm.id & V4L2_STD_525_60) - dev->ts1.height = 480; - else - dev->ts1.height = 576; - - /* assign frame size */ - cx23885_api_cmd(dev, CX2341X_ENC_SET_FRAME_SIZE, 2, 0, - dev->ts1.height, dev->ts1.width); - - dev->mpeg_params.width = dev->ts1.width; - dev->mpeg_params.height = dev->ts1.height; - dev->mpeg_params.is_50hz = - (dev->encodernorm.id & V4L2_STD_625_50) != 0; - - cx2341x_update(dev, cx23885_mbox_func, NULL, &dev->mpeg_params); - - cx23885_api_cmd(dev, CX2341X_ENC_MISC, 2, 0, 3, 1); - cx23885_api_cmd(dev, CX2341X_ENC_MISC, 2, 0, 4, 1); -} - -static int cx23885_initialize_codec(struct cx23885_dev *dev, int startencoder) -{ - int version; - int retval; - u32 i, data[7]; - - dprintk(1, "%s()\n", __func__); - - retval = cx23885_api_cmd(dev, CX2341X_ENC_PING_FW, 0, 0); /* ping */ - if (retval < 0) { - dprintk(2, "%s() PING OK\n", __func__); - retval = cx23885_load_firmware(dev); - if (retval < 0) { - printk(KERN_ERR "%s() f/w load failed\n", __func__); - return retval; - } - retval = cx23885_find_mailbox(dev); - if (retval < 0) { - printk(KERN_ERR "%s() mailbox < 0, error\n", - __func__); - return -1; - } - dev->cx23417_mailbox = retval; - retval = cx23885_api_cmd(dev, CX2341X_ENC_PING_FW, 0, 0); - if (retval < 0) { - printk(KERN_ERR - "ERROR: cx23417 firmware ping failed!\n"); - return -1; - } - retval = cx23885_api_cmd(dev, CX2341X_ENC_GET_VERSION, 0, 1, - &version); - if (retval < 0) { - printk(KERN_ERR "ERROR: cx23417 firmware get encoder :" - "version failed!\n"); - return -1; - } - dprintk(1, "cx23417 firmware version is 0x%08x\n", version); - msleep(200); - } - - cx23885_codec_settings(dev); - msleep(60); - - cx23885_api_cmd(dev, CX2341X_ENC_SET_NUM_VSYNC_LINES, 2, 0, - CX23885_FIELD1_SAA7115, CX23885_FIELD2_SAA7115); - cx23885_api_cmd(dev, CX2341X_ENC_SET_PLACEHOLDER, 12, 0, - CX23885_CUSTOM_EXTENSION_USR_DATA, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0); - - /* Setup to capture VBI */ - data[0] = 0x0001BD00; - data[1] = 1; /* frames per interrupt */ - data[2] = 4; /* total bufs */ - data[3] = 0x91559155; /* start codes */ - data[4] = 0x206080C0; /* stop codes */ - data[5] = 6; /* lines */ - data[6] = 64; /* BPL */ - - cx23885_api_cmd(dev, CX2341X_ENC_SET_VBI_CONFIG, 7, 0, data[0], data[1], - data[2], data[3], data[4], data[5], data[6]); - - for (i = 2; i <= 24; i++) { - int valid; - - valid = ((i >= 19) && (i <= 21)); - cx23885_api_cmd(dev, CX2341X_ENC_SET_VBI_LINE, 5, 0, i, - valid, 0 , 0, 0); - cx23885_api_cmd(dev, CX2341X_ENC_SET_VBI_LINE, 5, 0, - i | 0x80000000, valid, 0, 0, 0); - } - - cx23885_api_cmd(dev, CX2341X_ENC_MUTE_AUDIO, 1, 0, CX23885_UNMUTE); - msleep(60); - - /* initialize the video input */ - cx23885_api_cmd(dev, CX2341X_ENC_INITIALIZE_INPUT, 0, 0); - msleep(60); - - /* Enable VIP style pixel invalidation so we work with scaled mode */ - mc417_memory_write(dev, 2120, 0x00000080); - - /* start capturing to the host interface */ - if (startencoder) { - cx23885_api_cmd(dev, CX2341X_ENC_START_CAPTURE, 2, 0, - CX23885_MPEG_CAPTURE, CX23885_RAW_BITS_NONE); - msleep(10); - } - - return 0; -} - -/* ------------------------------------------------------------------ */ - -static int bb_buf_setup(struct videobuf_queue *q, - unsigned int *count, unsigned int *size) -{ - struct cx23885_fh *fh = q->priv_data; - - fh->dev->ts1.ts_packet_size = mpeglinesize; - fh->dev->ts1.ts_packet_count = mpeglines; - - *size = fh->dev->ts1.ts_packet_size * fh->dev->ts1.ts_packet_count; - *count = mpegbufs; - - return 0; -} - -static int bb_buf_prepare(struct videobuf_queue *q, - struct videobuf_buffer *vb, enum v4l2_field field) -{ - struct cx23885_fh *fh = q->priv_data; - return cx23885_buf_prepare(q, &fh->dev->ts1, - (struct cx23885_buffer *)vb, - field); -} - -static void bb_buf_queue(struct videobuf_queue *q, - struct videobuf_buffer *vb) -{ - struct cx23885_fh *fh = q->priv_data; - cx23885_buf_queue(&fh->dev->ts1, (struct cx23885_buffer *)vb); -} - -static void bb_buf_release(struct videobuf_queue *q, - struct videobuf_buffer *vb) -{ - cx23885_free_buffer(q, (struct cx23885_buffer *)vb); -} - -static struct videobuf_queue_ops cx23885_qops = { - .buf_setup = bb_buf_setup, - .buf_prepare = bb_buf_prepare, - .buf_queue = bb_buf_queue, - .buf_release = bb_buf_release, -}; - -/* ------------------------------------------------------------------ */ - -static const u32 *ctrl_classes[] = { - cx2341x_mpeg_ctrls, - NULL -}; - -static int cx23885_queryctrl(struct cx23885_dev *dev, - struct v4l2_queryctrl *qctrl) -{ - qctrl->id = v4l2_ctrl_next(ctrl_classes, qctrl->id); - if (qctrl->id == 0) - return -EINVAL; - - /* MPEG V4L2 controls */ - if (cx2341x_ctrl_query(&dev->mpeg_params, qctrl)) - qctrl->flags |= V4L2_CTRL_FLAG_DISABLED; - - return 0; -} - -static int cx23885_querymenu(struct cx23885_dev *dev, - struct v4l2_querymenu *qmenu) -{ - struct v4l2_queryctrl qctrl; - - qctrl.id = qmenu->id; - cx23885_queryctrl(dev, &qctrl); - return v4l2_ctrl_query_menu(qmenu, &qctrl, - cx2341x_ctrl_get_menu(&dev->mpeg_params, qmenu->id)); -} - -static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *id) -{ - struct cx23885_fh *fh = file->private_data; - struct cx23885_dev *dev = fh->dev; - - call_all(dev, core, g_std, id); - - return 0; -} - -static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *id) -{ - struct cx23885_fh *fh = file->private_data; - struct cx23885_dev *dev = fh->dev; - unsigned int i; - - for (i = 0; i < ARRAY_SIZE(cx23885_tvnorms); i++) - if (*id & cx23885_tvnorms[i].id) - break; - if (i == ARRAY_SIZE(cx23885_tvnorms)) - return -EINVAL; - dev->encodernorm = cx23885_tvnorms[i]; - - /* Have the drier core notify the subdevices */ - mutex_lock(&dev->lock); - cx23885_set_tvnorm(dev, *id); - mutex_unlock(&dev->lock); - - return 0; -} - -static int vidioc_enum_input(struct file *file, void *priv, - struct v4l2_input *i) -{ - struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev; - dprintk(1, "%s()\n", __func__); - return cx23885_enum_input(dev, i); -} - -static int vidioc_g_input(struct file *file, void *priv, unsigned int *i) -{ - return cx23885_get_input(file, priv, i); -} - -static int vidioc_s_input(struct file *file, void *priv, unsigned int i) -{ - return cx23885_set_input(file, priv, i); -} - -static int vidioc_g_tuner(struct file *file, void *priv, - struct v4l2_tuner *t) -{ - struct cx23885_fh *fh = file->private_data; - struct cx23885_dev *dev = fh->dev; - - if (UNSET == dev->tuner_type) - return -EINVAL; - if (0 != t->index) - return -EINVAL; - strcpy(t->name, "Television"); - call_all(dev, tuner, g_tuner, t); - - dprintk(1, "VIDIOC_G_TUNER: tuner type %d\n", t->type); - - return 0; -} - -static int vidioc_s_tuner(struct file *file, void *priv, - struct v4l2_tuner *t) -{ - struct cx23885_fh *fh = file->private_data; - struct cx23885_dev *dev = fh->dev; - - if (UNSET == dev->tuner_type) - return -EINVAL; - - /* Update the A/V core */ - call_all(dev, tuner, s_tuner, t); - - return 0; -} - -static int vidioc_g_frequency(struct file *file, void *priv, - struct v4l2_frequency *f) -{ - struct cx23885_fh *fh = file->private_data; - struct cx23885_dev *dev = fh->dev; - - if (UNSET == dev->tuner_type) - return -EINVAL; - f->type = V4L2_TUNER_ANALOG_TV; - f->frequency = dev->freq; - - call_all(dev, tuner, g_frequency, f); - - return 0; -} - -static int vidioc_s_frequency(struct file *file, void *priv, - struct v4l2_frequency *f) -{ - return cx23885_set_frequency(file, priv, f); -} - -static int vidioc_g_ctrl(struct file *file, void *priv, - struct v4l2_control *ctl) -{ - struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev; - - return cx23885_get_control(dev, ctl); -} - -static int vidioc_s_ctrl(struct file *file, void *priv, - struct v4l2_control *ctl) -{ - struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev; - - return cx23885_set_control(dev, ctl); -} - -static int vidioc_querycap(struct file *file, void *priv, - struct v4l2_capability *cap) -{ - struct cx23885_fh *fh = file->private_data; - struct cx23885_dev *dev = fh->dev; - struct cx23885_tsport *tsport = &dev->ts1; - - strlcpy(cap->driver, dev->name, sizeof(cap->driver)); - strlcpy(cap->card, cx23885_boards[tsport->dev->board].name, - sizeof(cap->card)); - sprintf(cap->bus_info, "PCI:%s", pci_name(dev->pci)); - cap->capabilities = - V4L2_CAP_VIDEO_CAPTURE | - V4L2_CAP_READWRITE | - V4L2_CAP_STREAMING | - 0; - if (UNSET != dev->tuner_type) - cap->capabilities |= V4L2_CAP_TUNER; - - return 0; -} - -static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv, - struct v4l2_fmtdesc *f) -{ - if (f->index != 0) - return -EINVAL; - - strlcpy(f->description, "MPEG", sizeof(f->description)); - f->pixelformat = V4L2_PIX_FMT_MPEG; - - return 0; -} - -static int vidioc_g_fmt_vid_cap(struct file *file, void *priv, - struct v4l2_format *f) -{ - struct cx23885_fh *fh = file->private_data; - struct cx23885_dev *dev = fh->dev; - - f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; - f->fmt.pix.bytesperline = 0; - f->fmt.pix.sizeimage = - dev->ts1.ts_packet_size * dev->ts1.ts_packet_count; - f->fmt.pix.colorspace = 0; - f->fmt.pix.width = dev->ts1.width; - f->fmt.pix.height = dev->ts1.height; - f->fmt.pix.field = fh->mpegq.field; - dprintk(1, "VIDIOC_G_FMT: w: %d, h: %d, f: %d\n", - dev->ts1.width, dev->ts1.height, fh->mpegq.field); - return 0; -} - -static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, - struct v4l2_format *f) -{ - struct cx23885_fh *fh = file->private_data; - struct cx23885_dev *dev = fh->dev; - - f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; - f->fmt.pix.bytesperline = 0; - f->fmt.pix.sizeimage = - dev->ts1.ts_packet_size * dev->ts1.ts_packet_count; - f->fmt.pix.colorspace = 0; - dprintk(1, "VIDIOC_TRY_FMT: w: %d, h: %d, f: %d\n", - dev->ts1.width, dev->ts1.height, fh->mpegq.field); - return 0; -} - -static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, - struct v4l2_format *f) -{ - struct cx23885_fh *fh = file->private_data; - struct cx23885_dev *dev = fh->dev; - - f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; - f->fmt.pix.bytesperline = 0; - f->fmt.pix.sizeimage = - dev->ts1.ts_packet_size * dev->ts1.ts_packet_count; - f->fmt.pix.colorspace = 0; - dprintk(1, "VIDIOC_S_FMT: w: %d, h: %d, f: %d\n", - f->fmt.pix.width, f->fmt.pix.height, f->fmt.pix.field); - return 0; -} - -static int vidioc_reqbufs(struct file *file, void *priv, - struct v4l2_requestbuffers *p) -{ - struct cx23885_fh *fh = file->private_data; - - return videobuf_reqbufs(&fh->mpegq, p); -} - -static int vidioc_querybuf(struct file *file, void *priv, - struct v4l2_buffer *p) -{ - struct cx23885_fh *fh = file->private_data; - - return videobuf_querybuf(&fh->mpegq, p); -} - -static int vidioc_qbuf(struct file *file, void *priv, - struct v4l2_buffer *p) -{ - struct cx23885_fh *fh = file->private_data; - - return videobuf_qbuf(&fh->mpegq, p); -} - -static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b) -{ - struct cx23885_fh *fh = priv; - - return videobuf_dqbuf(&fh->mpegq, b, file->f_flags & O_NONBLOCK); -} - - -static int vidioc_streamon(struct file *file, void *priv, - enum v4l2_buf_type i) -{ - struct cx23885_fh *fh = file->private_data; - - return videobuf_streamon(&fh->mpegq); -} - -static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i) -{ - struct cx23885_fh *fh = file->private_data; - - return videobuf_streamoff(&fh->mpegq); -} - -static int vidioc_g_ext_ctrls(struct file *file, void *priv, - struct v4l2_ext_controls *f) -{ - struct cx23885_fh *fh = priv; - struct cx23885_dev *dev = fh->dev; - - if (f->ctrl_class != V4L2_CTRL_CLASS_MPEG) - return -EINVAL; - return cx2341x_ext_ctrls(&dev->mpeg_params, 0, f, VIDIOC_G_EXT_CTRLS); -} - -static int vidioc_s_ext_ctrls(struct file *file, void *priv, - struct v4l2_ext_controls *f) -{ - struct cx23885_fh *fh = priv; - struct cx23885_dev *dev = fh->dev; - struct cx2341x_mpeg_params p; - int err; - - if (f->ctrl_class != V4L2_CTRL_CLASS_MPEG) - return -EINVAL; - - p = dev->mpeg_params; - err = cx2341x_ext_ctrls(&p, 0, f, VIDIOC_S_EXT_CTRLS); - - if (err == 0) { - err = cx2341x_update(dev, cx23885_mbox_func, - &dev->mpeg_params, &p); - dev->mpeg_params = p; - } - return err; -} - -static int vidioc_try_ext_ctrls(struct file *file, void *priv, - struct v4l2_ext_controls *f) -{ - struct cx23885_fh *fh = priv; - struct cx23885_dev *dev = fh->dev; - struct cx2341x_mpeg_params p; - int err; - - if (f->ctrl_class != V4L2_CTRL_CLASS_MPEG) - return -EINVAL; - - p = dev->mpeg_params; - err = cx2341x_ext_ctrls(&p, 0, f, VIDIOC_TRY_EXT_CTRLS); - return err; -} - -static int vidioc_log_status(struct file *file, void *priv) -{ - struct cx23885_fh *fh = priv; - struct cx23885_dev *dev = fh->dev; - char name[32 + 2]; - - snprintf(name, sizeof(name), "%s/2", dev->name); - printk(KERN_INFO - "%s/2: ============ START LOG STATUS ============\n", - dev->name); - call_all(dev, core, log_status); - cx2341x_log_status(&dev->mpeg_params, name); - printk(KERN_INFO - "%s/2: ============= END LOG STATUS =============\n", - dev->name); - return 0; -} - -static int vidioc_querymenu(struct file *file, void *priv, - struct v4l2_querymenu *a) -{ - struct cx23885_fh *fh = priv; - struct cx23885_dev *dev = fh->dev; - - return cx23885_querymenu(dev, a); -} - -static int vidioc_queryctrl(struct file *file, void *priv, - struct v4l2_queryctrl *c) -{ - struct cx23885_fh *fh = priv; - struct cx23885_dev *dev = fh->dev; - - return cx23885_queryctrl(dev, c); -} - -static int mpeg_open(struct file *file) -{ - struct cx23885_dev *dev = video_drvdata(file); - struct cx23885_fh *fh; - - dprintk(2, "%s()\n", __func__); - - /* allocate + initialize per filehandle data */ - fh = kzalloc(sizeof(*fh), GFP_KERNEL); - if (!fh) - return -ENOMEM; - - file->private_data = fh; - fh->dev = dev; - - videobuf_queue_sg_init(&fh->mpegq, &cx23885_qops, - &dev->pci->dev, &dev->ts1.slock, - V4L2_BUF_TYPE_VIDEO_CAPTURE, - V4L2_FIELD_INTERLACED, - sizeof(struct cx23885_buffer), - fh, NULL); - return 0; -} - -static int mpeg_release(struct file *file) -{ - struct cx23885_fh *fh = file->private_data; - struct cx23885_dev *dev = fh->dev; - - dprintk(2, "%s()\n", __func__); - - /* FIXME: Review this crap */ - /* Shut device down on last close */ - if (atomic_cmpxchg(&fh->v4l_reading, 1, 0) == 1) { - if (atomic_dec_return(&dev->v4l_reader_count) == 0) { - /* stop mpeg capture */ - cx23885_api_cmd(fh->dev, CX2341X_ENC_STOP_CAPTURE, 3, 0, - CX23885_END_NOW, CX23885_MPEG_CAPTURE, - CX23885_RAW_BITS_NONE); - - msleep(500); - cx23885_417_check_encoder(dev); - - cx23885_cancel_buffers(&fh->dev->ts1); - } - } - - if (fh->mpegq.streaming) - videobuf_streamoff(&fh->mpegq); - if (fh->mpegq.reading) - videobuf_read_stop(&fh->mpegq); - - videobuf_mmap_free(&fh->mpegq); - file->private_data = NULL; - kfree(fh); - - return 0; -} - -static ssize_t mpeg_read(struct file *file, char __user *data, - size_t count, loff_t *ppos) -{ - struct cx23885_fh *fh = file->private_data; - struct cx23885_dev *dev = fh->dev; - - dprintk(2, "%s()\n", __func__); - - /* Deal w/ A/V decoder * and mpeg encoder sync issues. */ - /* Start mpeg encoder on first read. */ - if (atomic_cmpxchg(&fh->v4l_reading, 0, 1) == 0) { - if (atomic_inc_return(&dev->v4l_reader_count) == 1) { - if (cx23885_initialize_codec(dev, 1) < 0) - return -EINVAL; - } - } - - return videobuf_read_stream(&fh->mpegq, data, count, ppos, 0, - file->f_flags & O_NONBLOCK); -} - -static unsigned int mpeg_poll(struct file *file, - struct poll_table_struct *wait) -{ - struct cx23885_fh *fh = file->private_data; - struct cx23885_dev *dev = fh->dev; - - dprintk(2, "%s\n", __func__); - - return videobuf_poll_stream(file, &fh->mpegq, wait); -} - -static int mpeg_mmap(struct file *file, struct vm_area_struct *vma) -{ - struct cx23885_fh *fh = file->private_data; - struct cx23885_dev *dev = fh->dev; - - dprintk(2, "%s()\n", __func__); - - return videobuf_mmap_mapper(&fh->mpegq, vma); -} - -static struct v4l2_file_operations mpeg_fops = { - .owner = THIS_MODULE, - .open = mpeg_open, - .release = mpeg_release, - .read = mpeg_read, - .poll = mpeg_poll, - .mmap = mpeg_mmap, - .ioctl = video_ioctl2, -}; - -static const struct v4l2_ioctl_ops mpeg_ioctl_ops = { - .vidioc_querystd = vidioc_g_std, - .vidioc_g_std = vidioc_g_std, - .vidioc_s_std = vidioc_s_std, - .vidioc_enum_input = vidioc_enum_input, - .vidioc_g_input = vidioc_g_input, - .vidioc_s_input = vidioc_s_input, - .vidioc_g_tuner = vidioc_g_tuner, - .vidioc_s_tuner = vidioc_s_tuner, - .vidioc_g_frequency = vidioc_g_frequency, - .vidioc_s_frequency = vidioc_s_frequency, - .vidioc_s_ctrl = vidioc_s_ctrl, - .vidioc_g_ctrl = vidioc_g_ctrl, - .vidioc_querycap = vidioc_querycap, - .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap, - .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap, - .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap, - .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap, - .vidioc_reqbufs = vidioc_reqbufs, - .vidioc_querybuf = vidioc_querybuf, - .vidioc_qbuf = vidioc_qbuf, - .vidioc_dqbuf = vidioc_dqbuf, - .vidioc_streamon = vidioc_streamon, - .vidioc_streamoff = vidioc_streamoff, - .vidioc_g_ext_ctrls = vidioc_g_ext_ctrls, - .vidioc_s_ext_ctrls = vidioc_s_ext_ctrls, - .vidioc_try_ext_ctrls = vidioc_try_ext_ctrls, - .vidioc_log_status = vidioc_log_status, - .vidioc_querymenu = vidioc_querymenu, - .vidioc_queryctrl = vidioc_queryctrl, - .vidioc_g_chip_ident = cx23885_g_chip_ident, -#ifdef CONFIG_VIDEO_ADV_DEBUG - .vidioc_g_register = cx23885_g_register, - .vidioc_s_register = cx23885_s_register, -#endif -}; - -static struct video_device cx23885_mpeg_template = { - .name = "cx23885", - .fops = &mpeg_fops, - .ioctl_ops = &mpeg_ioctl_ops, - .tvnorms = CX23885_NORMS, - .current_norm = V4L2_STD_NTSC_M, -}; - -void cx23885_417_unregister(struct cx23885_dev *dev) -{ - dprintk(1, "%s()\n", __func__); - - if (dev->v4l_device) { - if (video_is_registered(dev->v4l_device)) - video_unregister_device(dev->v4l_device); - else - video_device_release(dev->v4l_device); - dev->v4l_device = NULL; - } -} - -static struct video_device *cx23885_video_dev_alloc( - struct cx23885_tsport *tsport, - struct pci_dev *pci, - struct video_device *template, - char *type) -{ - struct video_device *vfd; - struct cx23885_dev *dev = tsport->dev; - - dprintk(1, "%s()\n", __func__); - - vfd = video_device_alloc(); - if (NULL == vfd) - return NULL; - *vfd = *template; - snprintf(vfd->name, sizeof(vfd->name), "%s (%s)", - cx23885_boards[tsport->dev->board].name, type); - vfd->parent = &pci->dev; - vfd->release = video_device_release; - return vfd; -} - -int cx23885_417_register(struct cx23885_dev *dev) -{ - /* FIXME: Port1 hardcoded here */ - int err = -ENODEV; - struct cx23885_tsport *tsport = &dev->ts1; - - dprintk(1, "%s()\n", __func__); - - if (cx23885_boards[dev->board].portb != CX23885_MPEG_ENCODER) - return err; - - /* Set default TV standard */ - dev->encodernorm = cx23885_tvnorms[0]; - - if (dev->encodernorm.id & V4L2_STD_525_60) - tsport->height = 480; - else - tsport->height = 576; - - tsport->width = 720; - cx2341x_fill_defaults(&dev->mpeg_params); - - dev->mpeg_params.port = CX2341X_PORT_SERIAL; - - /* Allocate and initialize V4L video device */ - dev->v4l_device = cx23885_video_dev_alloc(tsport, - dev->pci, &cx23885_mpeg_template, "mpeg"); - video_set_drvdata(dev->v4l_device, dev); - err = video_register_device(dev->v4l_device, - VFL_TYPE_GRABBER, -1); - if (err < 0) { - printk(KERN_INFO "%s: can't register mpeg device\n", dev->name); - return err; - } - - printk(KERN_INFO "%s: registered device %s [mpeg]\n", - dev->name, video_device_node_name(dev->v4l_device)); - - /* ST: Configure the encoder paramaters, but don't begin - * encoding, this resolves an issue where the first time the - * encoder is started video can be choppy. - */ - cx23885_initialize_codec(dev, 0); - - return 0; -} - -MODULE_FIRMWARE(CX23885_FIRM_IMAGE_NAME); diff --git a/drivers/media/video/cx23885/cx23885-alsa.c b/drivers/media/video/cx23885/cx23885-alsa.c deleted file mode 100644 index 795169237e7..00000000000 --- a/drivers/media/video/cx23885/cx23885-alsa.c +++ /dev/null @@ -1,535 +0,0 @@ -/* - * - * Support for CX23885 analog audio capture - * - * (c) 2008 Mijhail Moreyra <mijhail.moreyra@gmail.com> - * Adapted from cx88-alsa.c - * (c) 2009 Steven Toth <stoth@kernellabs.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include <linux/module.h> -#include <linux/init.h> -#include <linux/device.h> -#include <linux/interrupt.h> -#include <linux/vmalloc.h> -#include <linux/dma-mapping.h> -#include <linux/pci.h> - -#include <asm/delay.h> - -#include <sound/core.h> -#include <sound/pcm.h> -#include <sound/pcm_params.h> -#include <sound/control.h> -#include <sound/initval.h> - -#include <sound/tlv.h> - - -#include "cx23885.h" -#include "cx23885-reg.h" - -#define AUDIO_SRAM_CHANNEL SRAM_CH07 - -#define dprintk(level, fmt, arg...) if (audio_debug >= level) \ - printk(KERN_INFO "%s: " fmt, chip->dev->name , ## arg) - -#define dprintk_core(level, fmt, arg...) if (audio_debug >= level) \ - printk(KERN_DEBUG "%s: " fmt, chip->dev->name , ## arg) - -/**************************************************************************** - Module global static vars - ****************************************************************************/ - -static unsigned int disable_analog_audio; -module_param(disable_analog_audio, int, 0644); -MODULE_PARM_DESC(disable_analog_audio, "disable analog audio ALSA driver"); - -static unsigned int audio_debug; -module_param(audio_debug, int, 0644); -MODULE_PARM_DESC(audio_debug, "enable debug messages [analog audio]"); - -/**************************************************************************** - Board specific funtions - ****************************************************************************/ - -/* Constants taken from cx88-reg.h */ -#define AUD_INT_DN_RISCI1 (1 << 0) -#define AUD_INT_UP_RISCI1 (1 << 1) -#define AUD_INT_RDS_DN_RISCI1 (1 << 2) -#define AUD_INT_DN_RISCI2 (1 << 4) /* yes, 3 is skipped */ -#define AUD_INT_UP_RISCI2 (1 << 5) -#define AUD_INT_RDS_DN_RISCI2 (1 << 6) -#define AUD_INT_DN_SYNC (1 << 12) -#define AUD_INT_UP_SYNC (1 << 13) -#define AUD_INT_RDS_DN_SYNC (1 << 14) -#define AUD_INT_OPC_ERR (1 << 16) -#define AUD_INT_BER_IRQ (1 << 20) -#define AUD_INT_MCHG_IRQ (1 << 21) -#define GP_COUNT_CONTROL_RESET 0x3 - -/* - * BOARD Specific: Sets audio DMA - */ - -static int cx23885_start_audio_dma(struct cx23885_audio_dev *chip) -{ - struct cx23885_audio_buffer *buf = chip->buf; - struct cx23885_dev *dev = chip->dev; - struct sram_channel *audio_ch = - &dev->sram_channels[AUDIO_SRAM_CHANNEL]; - - dprintk(1, "%s()\n", __func__); - - /* Make sure RISC/FIFO are off before changing FIFO/RISC settings */ - cx_clear(AUD_INT_DMA_CTL, 0x11); - - /* setup fifo + format - out channel */ - cx23885_sram_channel_setup(chip->dev, audio_ch, buf->bpl, - buf->risc.dma); - - /* sets bpl size */ - cx_write(AUD_INT_A_LNGTH, buf->bpl); - - /* This is required to get good audio (1 seems to be ok) */ - cx_write(AUD_INT_A_MODE, 1); - - /* reset counter */ - cx_write(AUD_INT_A_GPCNT_CTL, GP_COUNT_CONTROL_RESET); - atomic_set(&chip->count, 0); - - dprintk(1, "Start audio DMA, %d B/line, %d lines/FIFO, %d periods, %d " - "byte buffer\n", buf->bpl, cx_read(audio_ch->cmds_start+12)>>1, - chip->num_periods, buf->bpl * chip->num_periods); - - /* Enables corresponding bits at AUD_INT_STAT */ - cx_write(AUDIO_INT_INT_MSK, AUD_INT_OPC_ERR | AUD_INT_DN_SYNC | - AUD_INT_DN_RISCI1); - - /* Clean any pending interrupt bits already set */ - cx_write(AUDIO_INT_INT_STAT, ~0); - - /* enable audio irqs */ - cx_set(PCI_INT_MSK, chip->dev->pci_irqmask | PCI_MSK_AUD_INT); - - /* start dma */ - cx_set(DEV_CNTRL2, (1<<5)); /* Enables Risc Processor */ - cx_set(AUD_INT_DMA_CTL, 0x11); /* audio downstream FIFO and - RISC enable */ - if (audio_debug) - cx23885_sram_channel_dump(chip->dev, audio_ch); - - return 0; -} - -/* - * BOARD Specific: Resets audio DMA - */ -static int cx23885_stop_audio_dma(struct cx23885_audio_dev *chip) -{ - struct cx23885_dev *dev = chip->dev; - dprintk(1, "Stopping audio DMA\n"); - - /* stop dma */ - cx_clear(AUD_INT_DMA_CTL, 0x11); - - /* disable irqs */ - cx_clear(PCI_INT_MSK, PCI_MSK_AUD_INT); - cx_clear(AUDIO_INT_INT_MSK, AUD_INT_OPC_ERR | AUD_INT_DN_SYNC | - AUD_INT_DN_RISCI1); - - if (audio_debug) - cx23885_sram_channel_dump(chip->dev, - &dev->sram_channels[AUDIO_SRAM_CHANNEL]); - - return 0; -} - -/* - * BOARD Specific: Handles audio IRQ - */ -int cx23885_audio_irq(struct cx23885_dev *dev, u32 status, u32 mask) -{ - struct cx23885_audio_dev *chip = dev->audio_dev; - - if (0 == (status & mask)) - return 0; - - cx_write(AUDIO_INT_INT_STAT, status); - - /* risc op code error */ - if (status & AUD_INT_OPC_ERR) { - printk(KERN_WARNING "%s/1: Audio risc op code error\n", - dev->name); - cx_clear(AUD_INT_DMA_CTL, 0x11); - cx23885_sram_channel_dump(dev, - &dev->sram_channels[AUDIO_SRAM_CHANNEL]); - } - if (status & AUD_INT_DN_SYNC) { - dprintk(1, "Downstream sync error\n"); - cx_write(AUD_INT_A_GPCNT_CTL, GP_COUNT_CONTROL_RESET); - return 1; - } - /* risc1 downstream */ - if (status & AUD_INT_DN_RISCI1) { - atomic_set(&chip->count, cx_read(AUD_INT_A_GPCNT)); - snd_pcm_period_elapsed(chip->substream); - } - /* FIXME: Any other status should deserve a special handling? */ - - return 1; -} - -static int dsp_buffer_free(struct cx23885_audio_dev *chip) -{ - BUG_ON(!chip->dma_size); - - dprintk(2, "Freeing buffer\n"); - videobuf_dma_unmap(&chip->pci->dev, chip->dma_risc); - videobuf_dma_free(chip->dma_risc); - btcx_riscmem_free(chip->pci, &chip->buf->risc); - kfree(chip->buf); - - chip->dma_risc = NULL; - chip->dma_size = 0; - - return 0; -} - -/**************************************************************************** - ALSA PCM Interface - ****************************************************************************/ - -/* - * Digital hardware definition - */ -#define DEFAULT_FIFO_SIZE 4096 - -static struct snd_pcm_hardware snd_cx23885_digital_hw = { - .info = SNDRV_PCM_INFO_MMAP | - SNDRV_PCM_INFO_INTERLEAVED | - SNDRV_PCM_INFO_BLOCK_TRANSFER | - SNDRV_PCM_INFO_MMAP_VALID, - .formats = SNDRV_PCM_FMTBIT_S16_LE, - - .rates = SNDRV_PCM_RATE_48000, - .rate_min = 48000, - .rate_max = 48000, - .channels_min = 2, - .channels_max = 2, - /* Analog audio output will be full of clicks and pops if there - are not exactly four lines in the SRAM FIFO buffer. */ - .period_bytes_min = DEFAULT_FIFO_SIZE/4, - .period_bytes_max = DEFAULT_FIFO_SIZE/4, - .periods_min = 1, - .periods_max = 1024, - .buffer_bytes_max = (1024*1024), -}; - -/* - * audio pcm capture open callback - */ -static int snd_cx23885_pcm_open(struct snd_pcm_substream *substream) -{ - struct cx23885_audio_dev *chip = snd_pcm_substream_chip(substream); - struct snd_pcm_runtime *runtime = substream->runtime; - int err; - - if (!chip) { - printk(KERN_ERR "BUG: cx23885 can't find device struct." - " Can't proceed with open\n"); - return -ENODEV; - } - - err = snd_pcm_hw_constraint_pow2(runtime, 0, - SNDRV_PCM_HW_PARAM_PERIODS); - if (err < 0) - goto _error; - - chip->substream = substream; - - runtime->hw = snd_cx23885_digital_hw; - - if (chip->dev->sram_channels[AUDIO_SRAM_CHANNEL].fifo_size != - DEFAULT_FIFO_SIZE) { - unsigned int bpl = chip->dev-> - sram_channels[AUDIO_SRAM_CHANNEL].fifo_size / 4; - bpl &= ~7; /* must be multiple of 8 */ - runtime->hw.period_bytes_min = bpl; - runtime->hw.period_bytes_max = bpl; - } - - return 0; -_error: - dprintk(1, "Error opening PCM!\n"); - return err; -} - -/* - * audio close callback - */ -static int snd_cx23885_close(struct snd_pcm_substream *substream) -{ - return 0; -} - -/* - * hw_params callback - */ -static int snd_cx23885_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *hw_params) -{ - struct cx23885_audio_dev *chip = snd_pcm_substream_chip(substream); - struct videobuf_dmabuf *dma; - - struct cx23885_audio_buffer *buf; - int ret; - - if (substream->runtime->dma_area) { - dsp_buffer_free(chip); - substream->runtime->dma_area = NULL; - } - - chip->period_size = params_period_bytes(hw_params); - chip->num_periods = params_periods(hw_params); - chip->dma_size = chip->period_size * params_periods(hw_params); - - BUG_ON(!chip->dma_size); - BUG_ON(chip->num_periods & (chip->num_periods-1)); - - buf = kzalloc(sizeof(*buf), GFP_KERNEL); - if (NULL == buf) - return -ENOMEM; - - buf->bpl = chip->period_size; - - dma = &buf->dma; - videobuf_dma_init(dma); - ret = videobuf_dma_init_kernel(dma, PCI_DMA_FROMDEVICE, - (PAGE_ALIGN(chip->dma_size) >> PAGE_SHIFT)); - if (ret < 0) - goto error; - - ret = videobuf_dma_map(&chip->pci->dev, dma); - if (ret < 0) - goto error; - - ret = cx23885_risc_databuffer(chip->pci, &buf->risc, dma->sglist, - chip->period_size, chip->num_periods, 1); - if (ret < 0) - goto error; - - /* Loop back to start of program */ - buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP|RISC_IRQ1|RISC_CNT_INC); - buf->risc.jmp[1] = cpu_to_le32(buf->risc.dma); - buf->risc.jmp[2] = cpu_to_le32(0); /* bits 63-32 */ - - chip->buf = buf; - chip->dma_risc = dma; - - substream->runtime->dma_area = chip->dma_risc->vaddr; - substream->runtime->dma_bytes = chip->dma_size; - substream->runtime->dma_addr = 0; - - return 0; - -error: - kfree(buf); - return ret; -} - -/* - * hw free callback - */ -static int snd_cx23885_hw_free(struct snd_pcm_substream *substream) -{ - - struct cx23885_audio_dev *chip = snd_pcm_substream_chip(substream); - - if (substream->runtime->dma_area) { - dsp_buffer_free(chip); - substream->runtime->dma_area = NULL; - } - - return 0; -} - -/* - * prepare callback - */ -static int snd_cx23885_prepare(struct snd_pcm_substream *substream) -{ - return 0; -} - -/* - * trigger callback - */ -static int snd_cx23885_card_trigger(struct snd_pcm_substream *substream, - int cmd) -{ - struct cx23885_audio_dev *chip = snd_pcm_substream_chip(substream); - int err; - - /* Local interrupts are already disabled by ALSA */ - spin_lock(&chip->lock); - - switch (cmd) { - case SNDRV_PCM_TRIGGER_START: - err = cx23885_start_audio_dma(chip); - break; - case SNDRV_PCM_TRIGGER_STOP: - err = cx23885_stop_audio_dma(chip); - break; - default: - err = -EINVAL; - break; - } - - spin_unlock(&chip->lock); - - return err; -} - -/* - * pointer callback - */ -static snd_pcm_uframes_t snd_cx23885_pointer( - struct snd_pcm_substream *substream) -{ - struct cx23885_audio_dev *chip = snd_pcm_substream_chip(substream); - struct snd_pcm_runtime *runtime = substream->runtime; - u16 count; - - count = atomic_read(&chip->count); - - return runtime->period_size * (count & (runtime->periods-1)); -} - -/* - * page callback (needed for mmap) - */ -static struct page *snd_cx23885_page(struct snd_pcm_substream *substream, - unsigned long offset) -{ - void *pageptr = substream->runtime->dma_area + offset; - return vmalloc_to_page(pageptr); -} - -/* - * operators - */ -static struct snd_pcm_ops snd_cx23885_pcm_ops = { - .open = snd_cx23885_pcm_open, - .close = snd_cx23885_close, - .ioctl = snd_pcm_lib_ioctl, - .hw_params = snd_cx23885_hw_params, - .hw_free = snd_cx23885_hw_free, - .prepare = snd_cx23885_prepare, - .trigger = snd_cx23885_card_trigger, - .pointer = snd_cx23885_pointer, - .page = snd_cx23885_page, -}; - -/* - * create a PCM device - */ -static int snd_cx23885_pcm(struct cx23885_audio_dev *chip, int device, - char *name) -{ - int err; - struct snd_pcm *pcm; - - err = snd_pcm_new(chip->card, name, device, 0, 1, &pcm); - if (err < 0) - return err; - pcm->private_data = chip; - strcpy(pcm->name, name); - snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_cx23885_pcm_ops); - - return 0; -} - -/**************************************************************************** - Basic Flow for Sound Devices - ****************************************************************************/ - -/* - * Alsa Constructor - Component probe - */ - -struct cx23885_audio_dev *cx23885_audio_register(struct cx23885_dev *dev) -{ - struct snd_card *card; - struct cx23885_audio_dev *chip; - int err; - - if (disable_analog_audio) - return NULL; - - if (dev->sram_channels[AUDIO_SRAM_CHANNEL].cmds_start == 0) { - printk(KERN_WARNING "%s(): Missing SRAM channel configuration " - "for analog TV Audio\n", __func__); - return NULL; - } - - err = snd_card_create(SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1, - THIS_MODULE, sizeof(struct cx23885_audio_dev), &card); - if (err < 0) - goto error; - - chip = (struct cx23885_audio_dev *) card->private_data; - chip->dev = dev; - chip->pci = dev->pci; - chip->card = card; - spin_lock_init(&chip->lock); - - snd_card_set_dev(card, &dev->pci->dev); - - err = snd_cx23885_pcm(chip, 0, "CX23885 Digital"); - if (err < 0) - goto error; - - strcpy(card->driver, "CX23885"); - sprintf(card->shortname, "Conexant CX23885"); - sprintf(card->longname, "%s at %s", card->shortname, dev->name); - - err = snd_card_register(card); - if (err < 0) - goto error; - - dprintk(0, "registered ALSA audio device\n"); - - return chip; - -error: - snd_card_free(card); - printk(KERN_ERR "%s(): Failed to register analog " - "audio adapter\n", __func__); - - return NULL; -} - -/* - * ALSA destructor - */ -void cx23885_audio_unregister(struct cx23885_dev *dev) -{ - struct cx23885_audio_dev *chip = dev->audio_dev; - - snd_card_free(chip->card); -} diff --git a/drivers/media/video/cx23885/cx23885-av.c b/drivers/media/video/cx23885/cx23885-av.c deleted file mode 100644 index 134ebddd860..00000000000 --- a/drivers/media/video/cx23885/cx23885-av.c +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Driver for the Conexant CX23885/7/8 PCIe bridge - * - * AV device support routines - non-input, non-vl42_subdev routines - * - * Copyright (C) 2010 Andy Walls <awalls@md.metrocast.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 "cx23885.h" - -void cx23885_av_work_handler(struct work_struct *work) -{ - struct cx23885_dev *dev = - container_of(work, struct cx23885_dev, cx25840_work); - bool handled; - - v4l2_subdev_call(dev->sd_cx25840, core, interrupt_service_routine, - PCI_MSK_AV_CORE, &handled); - cx23885_irq_enable(dev, PCI_MSK_AV_CORE); -} diff --git a/drivers/media/video/cx23885/cx23885-av.h b/drivers/media/video/cx23885/cx23885-av.h deleted file mode 100644 index d2915c3e53a..00000000000 --- a/drivers/media/video/cx23885/cx23885-av.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Driver for the Conexant CX23885/7/8 PCIe bridge - * - * AV device support routines - non-input, non-vl42_subdev routines - * - * Copyright (C) 2010 Andy Walls <awalls@md.metrocast.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 _CX23885_AV_H_ -#define _CX23885_AV_H_ -void cx23885_av_work_handler(struct work_struct *work); -#endif diff --git a/drivers/media/video/cx23885/cx23885-cards.c b/drivers/media/video/cx23885/cx23885-cards.c deleted file mode 100644 index d365e9a8efc..00000000000 --- a/drivers/media/video/cx23885/cx23885-cards.c +++ /dev/null @@ -1,1684 +0,0 @@ -/* - * Driver for the Conexant CX23885 PCIe bridge - * - * Copyright (c) 2006 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 <linux/init.h> -#include <linux/module.h> -#include <linux/pci.h> -#include <linux/delay.h> -#include <media/cx25840.h> -#include <linux/firmware.h> -#include <misc/altera.h> - -#include "cx23885.h" -#include "tuner-xc2028.h" -#include "netup-eeprom.h" -#include "netup-init.h" -#include "altera-ci.h" -#include "xc4000.h" -#include "xc5000.h" -#include "cx23888-ir.h" - -static unsigned int netup_card_rev = 1; -module_param(netup_card_rev, int, 0644); -MODULE_PARM_DESC(netup_card_rev, - "NetUP Dual DVB-T/C CI card revision"); -static unsigned int enable_885_ir; -module_param(enable_885_ir, int, 0644); -MODULE_PARM_DESC(enable_885_ir, - "Enable integrated IR controller for supported\n" - "\t\t CX2388[57] boards that are wired for it:\n" - "\t\t\tHVR-1250 (reported safe)\n" - "\t\t\tTerraTec Cinergy T PCIe Dual (not well tested, appears to be safe)\n" - "\t\t\tTeVii S470 (reported unsafe)\n" - "\t\t This can cause an interrupt storm with some cards.\n" - "\t\t Default: 0 [Disabled]"); - -/* ------------------------------------------------------------------ */ -/* board config info */ - -struct cx23885_board cx23885_boards[] = { - [CX23885_BOARD_UNKNOWN] = { - .name = "UNKNOWN/GENERIC", - /* Ensure safe default for unknown boards */ - .clk_freq = 0, - .input = {{ - .type = CX23885_VMUX_COMPOSITE1, - .vmux = 0, - }, { - .type = CX23885_VMUX_COMPOSITE2, - .vmux = 1, - }, { - .type = CX23885_VMUX_COMPOSITE3, - .vmux = 2, - }, { - .type = CX23885_VMUX_COMPOSITE4, - .vmux = 3, - } }, - }, - [CX23885_BOARD_HAUPPAUGE_HVR1800lp] = { - .name = "Hauppauge WinTV-HVR1800lp", - .portc = CX23885_MPEG_DVB, - .input = {{ - .type = CX23885_VMUX_TELEVISION, - .vmux = 0, - .gpio0 = 0xff00, - }, { - .type = CX23885_VMUX_DEBUG, - .vmux = 0, - .gpio0 = 0xff01, - }, { - .type = CX23885_VMUX_COMPOSITE1, - .vmux = 1, - .gpio0 = 0xff02, - }, { - .type = CX23885_VMUX_SVIDEO, - .vmux = 2, - .gpio0 = 0xff02, - } }, - }, - [CX23885_BOARD_HAUPPAUGE_HVR1800] = { - .name = "Hauppauge WinTV-HVR1800", - .porta = CX23885_ANALOG_VIDEO, - .portb = CX23885_MPEG_ENCODER, - .portc = CX23885_MPEG_DVB, - .tuner_type = TUNER_PHILIPS_TDA8290, - .tuner_addr = 0x42, /* 0x84 >> 1 */ - .tuner_bus = 1, - .input = {{ - .type = CX23885_VMUX_TELEVISION, - .vmux = CX25840_VIN7_CH3 | - CX25840_VIN5_CH2 | - CX25840_VIN2_CH1, - .amux = CX25840_AUDIO8, - .gpio0 = 0, - }, { - .type = CX23885_VMUX_COMPOSITE1, - .vmux = CX25840_VIN7_CH3 | - CX25840_VIN4_CH2 | - CX25840_VIN6_CH1, - .amux = CX25840_AUDIO7, - .gpio0 = 0, - }, { - .type = CX23885_VMUX_SVIDEO, - .vmux = CX25840_VIN7_CH3 | - CX25840_VIN4_CH2 | - CX25840_VIN8_CH1 | - CX25840_SVIDEO_ON, - .amux = CX25840_AUDIO7, - .gpio0 = 0, - } }, - }, - [CX23885_BOARD_HAUPPAUGE_HVR1250] = { - .name = "Hauppauge WinTV-HVR1250", - .porta = CX23885_ANALOG_VIDEO, - .portc = CX23885_MPEG_DVB, -#ifdef MT2131_NO_ANALOG_SUPPORT_YET - .tuner_type = TUNER_PHILIPS_TDA8290, - .tuner_addr = 0x42, /* 0x84 >> 1 */ - .tuner_bus = 1, -#endif - .force_bff = 1, - .input = {{ -#ifdef MT2131_NO_ANALOG_SUPPORT_YET - .type = CX23885_VMUX_TELEVISION, - .vmux = CX25840_VIN7_CH3 | - CX25840_VIN5_CH2 | - CX25840_VIN2_CH1, - .amux = CX25840_AUDIO8, - .gpio0 = 0xff00, - }, { -#endif - .type = CX23885_VMUX_COMPOSITE1, - .vmux = CX25840_VIN7_CH3 | - CX25840_VIN4_CH2 | - CX25840_VIN6_CH1, - .amux = CX25840_AUDIO7, - .gpio0 = 0xff02, - }, { - .type = CX23885_VMUX_SVIDEO, - .vmux = CX25840_VIN7_CH3 | - CX25840_VIN4_CH2 | - CX25840_VIN8_CH1 | - CX25840_SVIDEO_ON, - .amux = CX25840_AUDIO7, - .gpio0 = 0xff02, - } }, - }, - [CX23885_BOARD_DVICO_FUSIONHDTV_5_EXP] = { - .name = "DViCO FusionHDTV5 Express", - .portb = CX23885_MPEG_DVB, - }, - [CX23885_BOARD_HAUPPAUGE_HVR1500Q] = { - .name = "Hauppauge WinTV-HVR1500Q", - .portc = CX23885_MPEG_DVB, - }, - [CX23885_BOARD_HAUPPAUGE_HVR1500] = { - .name = "Hauppauge WinTV-HVR1500", - .porta = CX23885_ANALOG_VIDEO, - .portc = CX23885_MPEG_DVB, - .tuner_type = TUNER_XC2028, - .tuner_addr = 0x61, /* 0xc2 >> 1 */ - .input = {{ - .type = CX23885_VMUX_TELEVISION, - .vmux = CX25840_VIN7_CH3 | - CX25840_VIN5_CH2 | - CX25840_VIN2_CH1, - .gpio0 = 0, - }, { - .type = CX23885_VMUX_COMPOSITE1, - .vmux = CX25840_VIN7_CH3 | - CX25840_VIN4_CH2 | - CX25840_VIN6_CH1, - .gpio0 = 0, - }, { - .type = CX23885_VMUX_SVIDEO, - .vmux = CX25840_VIN7_CH3 | - CX25840_VIN4_CH2 | - CX25840_VIN8_CH1 | - CX25840_SVIDEO_ON, - .gpio0 = 0, - } }, - }, - [CX23885_BOARD_HAUPPAUGE_HVR1200] = { - .name = "Hauppauge WinTV-HVR1200", - .portc = CX23885_MPEG_DVB, - }, - [CX23885_BOARD_HAUPPAUGE_HVR1700] = { - .name = "Hauppauge WinTV-HVR1700", - .portc = CX23885_MPEG_DVB, - }, - [CX23885_BOARD_HAUPPAUGE_HVR1400] = { - .name = "Hauppauge WinTV-HVR1400", - .portc = CX23885_MPEG_DVB, - }, - [CX23885_BOARD_DVICO_FUSIONHDTV_7_DUAL_EXP] = { - .name = "DViCO FusionHDTV7 Dual Express", - .portb = CX23885_MPEG_DVB, - .portc = CX23885_MPEG_DVB, - }, - [CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP] = { - .name = "DViCO FusionHDTV DVB-T Dual Express", - .portb = CX23885_MPEG_DVB, - .portc = CX23885_MPEG_DVB, - }, - [CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H] = { - .name = "Leadtek Winfast PxDVR3200 H", - .portc = CX23885_MPEG_DVB, - }, - [CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H_XC4000] = { - .name = "Leadtek Winfast PxDVR3200 H XC4000", - .porta = CX23885_ANALOG_VIDEO, - .portc = CX23885_MPEG_DVB, - .tuner_type = TUNER_XC4000, - .tuner_addr = 0x61, - .radio_type = UNSET, - .radio_addr = ADDR_UNSET, - .input = {{ - .type = CX23885_VMUX_TELEVISION, - .vmux = CX25840_VIN2_CH1 | - CX25840_VIN5_CH2 | - CX25840_NONE0_CH3, - }, { - .type = CX23885_VMUX_COMPOSITE1, - .vmux = CX25840_COMPOSITE1, - }, { - .type = CX23885_VMUX_SVIDEO, - .vmux = CX25840_SVIDEO_LUMA3 | - CX25840_SVIDEO_CHROMA4, - }, { - .type = CX23885_VMUX_COMPONENT, - .vmux = CX25840_VIN7_CH1 | - CX25840_VIN6_CH2 | - CX25840_VIN8_CH3 | - CX25840_COMPONENT_ON, - } }, - }, - [CX23885_BOARD_COMPRO_VIDEOMATE_E650F] = { - .name = "Compro VideoMate E650F", - .portc = CX23885_MPEG_DVB, - }, - [CX23885_BOARD_TBS_6920] = { - .name = "TurboSight TBS 6920", - .portb = CX23885_MPEG_DVB, - }, - [CX23885_BOARD_TEVII_S470] = { - .name = "TeVii S470", - .portb = CX23885_MPEG_DVB, - }, - [CX23885_BOARD_DVBWORLD_2005] = { - .name = "DVBWorld DVB-S2 2005", - .portb = CX23885_MPEG_DVB, - }, - [CX23885_BOARD_NETUP_DUAL_DVBS2_CI] = { - .ci_type = 1, - .name = "NetUP Dual DVB-S2 CI", - .portb = CX23885_MPEG_DVB, - .portc = CX23885_MPEG_DVB, - }, - [CX23885_BOARD_HAUPPAUGE_HVR1270] = { - .name = "Hauppauge WinTV-HVR1270", - .portc = CX23885_MPEG_DVB, - }, - [CX23885_BOARD_HAUPPAUGE_HVR1275] = { - .name = "Hauppauge WinTV-HVR1275", - .portc = CX23885_MPEG_DVB, - }, - [CX23885_BOARD_HAUPPAUGE_HVR1255] = { - .name = "Hauppauge WinTV-HVR1255", - .porta = CX23885_ANALOG_VIDEO, - .portc = CX23885_MPEG_DVB, - .tuner_type = TUNER_ABSENT, - .tuner_addr = 0x42, /* 0x84 >> 1 */ - .force_bff = 1, - .input = {{ - .type = CX23885_VMUX_TELEVISION, - .vmux = CX25840_VIN7_CH3 | - CX25840_VIN5_CH2 | - CX25840_VIN2_CH1 | - CX25840_DIF_ON, - .amux = CX25840_AUDIO8, - }, { - .type = CX23885_VMUX_COMPOSITE1, - .vmux = CX25840_VIN7_CH3 | - CX25840_VIN4_CH2 | - CX25840_VIN6_CH1, - .amux = CX25840_AUDIO7, - }, { - .type = CX23885_VMUX_SVIDEO, - .vmux = CX25840_VIN7_CH3 | - CX25840_VIN4_CH2 | - CX25840_VIN8_CH1 | - CX25840_SVIDEO_ON, - .amux = CX25840_AUDIO7, - } }, - }, - [CX23885_BOARD_HAUPPAUGE_HVR1255_22111] = { - .name = "Hauppauge WinTV-HVR1255", - .porta = CX23885_ANALOG_VIDEO, - .portc = CX23885_MPEG_DVB, - .tuner_type = TUNER_ABSENT, - .tuner_addr = 0x42, /* 0x84 >> 1 */ - .force_bff = 1, - .input = {{ - .type = CX23885_VMUX_TELEVISION, - .vmux = CX25840_VIN7_CH3 | - CX25840_VIN5_CH2 | - CX25840_VIN2_CH1 | - CX25840_DIF_ON, - .amux = CX25840_AUDIO8, - }, { - .type = CX23885_VMUX_SVIDEO, - .vmux = CX25840_VIN7_CH3 | - CX25840_VIN4_CH2 | - CX25840_VIN8_CH1 | - CX25840_SVIDEO_ON, - .amux = CX25840_AUDIO7, - } }, - }, - [CX23885_BOARD_HAUPPAUGE_HVR1210] = { - .name = "Hauppauge WinTV-HVR1210", - .portc = CX23885_MPEG_DVB, - }, - [CX23885_BOARD_MYGICA_X8506] = { - .name = "Mygica X8506 DMB-TH", - .tuner_type = TUNER_XC5000, - .tuner_addr = 0x61, - .tuner_bus = 1, - .porta = CX23885_ANALOG_VIDEO, - .portb = CX23885_MPEG_DVB, - .input = { - { - .type = CX23885_VMUX_TELEVISION, - .vmux = CX25840_COMPOSITE2, - }, - { - .type = CX23885_VMUX_COMPOSITE1, - .vmux = CX25840_COMPOSITE8, - }, - { - .type = CX23885_VMUX_SVIDEO, - .vmux = CX25840_SVIDEO_LUMA3 | - CX25840_SVIDEO_CHROMA4, - }, - { - .type = CX23885_VMUX_COMPONENT, - .vmux = CX25840_COMPONENT_ON | - CX25840_VIN1_CH1 | - CX25840_VIN6_CH2 | - CX25840_VIN7_CH3, - }, - }, - }, - [CX23885_BOARD_MAGICPRO_PROHDTVE2] = { - .name = "Magic-Pro ProHDTV Extreme 2", - .tuner_type = TUNER_XC5000, - .tuner_addr = 0x61, - .tuner_bus = 1, - .porta = CX23885_ANALOG_VIDEO, - .portb = CX23885_MPEG_DVB, - .input = { - { - .type = CX23885_VMUX_TELEVISION, - .vmux = CX25840_COMPOSITE2, - }, - { - .type = CX23885_VMUX_COMPOSITE1, - .vmux = CX25840_COMPOSITE8, - }, - { - .type = CX23885_VMUX_SVIDEO, - .vmux = CX25840_SVIDEO_LUMA3 | - CX25840_SVIDEO_CHROMA4, - }, - { - .type = CX23885_VMUX_COMPONENT, - .vmux = CX25840_COMPONENT_ON | - CX25840_VIN1_CH1 | - CX25840_VIN6_CH2 | - CX25840_VIN7_CH3, - }, - }, - }, - [CX23885_BOARD_HAUPPAUGE_HVR1850] = { - .name = "Hauppauge WinTV-HVR1850", - .porta = CX23885_ANALOG_VIDEO, - .portb = CX23885_MPEG_ENCODER, - .portc = CX23885_MPEG_DVB, - .tuner_type = TUNER_ABSENT, - .tuner_addr = 0x42, /* 0x84 >> 1 */ - .force_bff = 1, - .input = {{ - .type = CX23885_VMUX_TELEVISION, - .vmux = CX25840_VIN7_CH3 | - CX25840_VIN5_CH2 | - CX25840_VIN2_CH1 | - CX25840_DIF_ON, - .amux = CX25840_AUDIO8, - }, { - .type = CX23885_VMUX_COMPOSITE1, - .vmux = CX25840_VIN7_CH3 | - CX25840_VIN4_CH2 | - CX25840_VIN6_CH1, - .amux = CX25840_AUDIO7, - }, { - .type = CX23885_VMUX_SVIDEO, - .vmux = CX25840_VIN7_CH3 | - CX25840_VIN4_CH2 | - CX25840_VIN8_CH1 | - CX25840_SVIDEO_ON, - .amux = CX25840_AUDIO7, - } }, - }, - [CX23885_BOARD_COMPRO_VIDEOMATE_E800] = { - .name = "Compro VideoMate E800", - .portc = CX23885_MPEG_DVB, - }, - [CX23885_BOARD_HAUPPAUGE_HVR1290] = { - .name = "Hauppauge WinTV-HVR1290", - .portc = CX23885_MPEG_DVB, - }, - [CX23885_BOARD_MYGICA_X8558PRO] = { - .name = "Mygica X8558 PRO DMB-TH", - .portb = CX23885_MPEG_DVB, - .portc = CX23885_MPEG_DVB, - }, - [CX23885_BOARD_LEADTEK_WINFAST_PXTV1200] = { - .name = "LEADTEK WinFast PxTV1200", - .porta = CX23885_ANALOG_VIDEO, - .tuner_type = TUNER_XC2028, - .tuner_addr = 0x61, - .tuner_bus = 1, - .input = {{ - .type = CX23885_VMUX_TELEVISION, - .vmux = CX25840_VIN2_CH1 | - CX25840_VIN5_CH2 | - CX25840_NONE0_CH3, - }, { - .type = CX23885_VMUX_COMPOSITE1, - .vmux = CX25840_COMPOSITE1, - }, { - .type = CX23885_VMUX_SVIDEO, - .vmux = CX25840_SVIDEO_LUMA3 | - CX25840_SVIDEO_CHROMA4, - }, { - .type = CX23885_VMUX_COMPONENT, - .vmux = CX25840_VIN7_CH1 | - CX25840_VIN6_CH2 | - CX25840_VIN8_CH3 | - CX25840_COMPONENT_ON, - } }, - }, - [CX23885_BOARD_GOTVIEW_X5_3D_HYBRID] = { - .name = "GoTView X5 3D Hybrid", - .tuner_type = TUNER_XC5000, - .tuner_addr = 0x64, - .tuner_bus = 1, - .porta = CX23885_ANALOG_VIDEO, - .portb = CX23885_MPEG_DVB, - .input = {{ - .type = CX23885_VMUX_TELEVISION, - .vmux = CX25840_VIN2_CH1 | - CX25840_VIN5_CH2, - .gpio0 = 0x02, - }, { - .type = CX23885_VMUX_COMPOSITE1, - .vmux = CX23885_VMUX_COMPOSITE1, - }, { - .type = CX23885_VMUX_SVIDEO, - .vmux = CX25840_SVIDEO_LUMA3 | - CX25840_SVIDEO_CHROMA4, - } }, - }, - [CX23885_BOARD_NETUP_DUAL_DVB_T_C_CI_RF] = { - .ci_type = 2, - .name = "NetUP Dual DVB-T/C-CI RF", - .porta = CX23885_ANALOG_VIDEO, - .portb = CX23885_MPEG_DVB, - .portc = CX23885_MPEG_DVB, - .num_fds_portb = 2, - .num_fds_portc = 2, - .tuner_type = TUNER_XC5000, - .tuner_addr = 0x64, - .input = { { - .type = CX23885_VMUX_TELEVISION, - .vmux = CX25840_COMPOSITE1, - } }, - }, - [CX23885_BOARD_MPX885] = { - .name = "MPX-885", - .porta = CX23885_ANALOG_VIDEO, - .input = {{ - .type = CX23885_VMUX_COMPOSITE1, - .vmux = CX25840_COMPOSITE1, - .amux = CX25840_AUDIO6, - .gpio0 = 0, - }, { - .type = CX23885_VMUX_COMPOSITE2, - .vmux = CX25840_COMPOSITE2, - .amux = CX25840_AUDIO6, - .gpio0 = 0, - }, { - .type = CX23885_VMUX_COMPOSITE3, - .vmux = CX25840_COMPOSITE3, - .amux = CX25840_AUDIO7, - .gpio0 = 0, - }, { - .type = CX23885_VMUX_COMPOSITE4, - .vmux = CX25840_COMPOSITE4, - .amux = CX25840_AUDIO7, - .gpio0 = 0, - } }, - }, - [CX23885_BOARD_MYGICA_X8507] = { - .name = "Mygica X8507", - .tuner_type = TUNER_XC5000, - .tuner_addr = 0x61, - .tuner_bus = 1, - .porta = CX23885_ANALOG_VIDEO, - .input = { - { - .type = CX23885_VMUX_TELEVISION, - .vmux = CX25840_COMPOSITE2, - .amux = CX25840_AUDIO8, - }, - { - .type = CX23885_VMUX_COMPOSITE1, - .vmux = CX25840_COMPOSITE8, - }, - { - .type = CX23885_VMUX_SVIDEO, - .vmux = CX25840_SVIDEO_LUMA3 | - CX25840_SVIDEO_CHROMA4, - }, - { - .type = CX23885_VMUX_COMPONENT, - .vmux = CX25840_COMPONENT_ON | - CX25840_VIN1_CH1 | - CX25840_VIN6_CH2 | - CX25840_VIN7_CH3, - }, - }, - }, - [CX23885_BOARD_TERRATEC_CINERGY_T_PCIE_DUAL] = { - .name = "TerraTec Cinergy T PCIe Dual", - .portb = CX23885_MPEG_DVB, - .portc = CX23885_MPEG_DVB, - }, - [CX23885_BOARD_TEVII_S471] = { - .name = "TeVii S471", - .portb = CX23885_MPEG_DVB, - } -}; -const unsigned int cx23885_bcount = ARRAY_SIZE(cx23885_boards); - -/* ------------------------------------------------------------------ */ -/* PCI subsystem IDs */ - -struct cx23885_subid cx23885_subids[] = { - { - .subvendor = 0x0070, - .subdevice = 0x3400, - .card = CX23885_BOARD_UNKNOWN, - }, { - .subvendor = 0x0070, - .subdevice = 0x7600, - .card = CX23885_BOARD_HAUPPAUGE_HVR1800lp, - }, { - .subvendor = 0x0070, - .subdevice = 0x7800, - .card = CX23885_BOARD_HAUPPAUGE_HVR1800, - }, { - .subvendor = 0x0070, - .subdevice = 0x7801, - .card = CX23885_BOARD_HAUPPAUGE_HVR1800, - }, { - .subvendor = 0x0070, - .subdevice = 0x7809, - .card = CX23885_BOARD_HAUPPAUGE_HVR1800, - }, { - .subvendor = 0x0070, - .subdevice = 0x7911, - .card = CX23885_BOARD_HAUPPAUGE_HVR1250, - }, { - .subvendor = 0x18ac, - .subdevice = 0xd500, - .card = CX23885_BOARD_DVICO_FUSIONHDTV_5_EXP, - }, { - .subvendor = 0x0070, - .subdevice = 0x7790, - .card = CX23885_BOARD_HAUPPAUGE_HVR1500Q, - }, { - .subvendor = 0x0070, - .subdevice = 0x7797, - .card = CX23885_BOARD_HAUPPAUGE_HVR1500Q, - }, { - .subvendor = 0x0070, - .subdevice = 0x7710, - .card = CX23885_BOARD_HAUPPAUGE_HVR1500, - }, { - .subvendor = 0x0070, - .subdevice = 0x7717, - .card = CX23885_BOARD_HAUPPAUGE_HVR1500, - }, { - .subvendor = 0x0070, - .subdevice = 0x71d1, - .card = CX23885_BOARD_HAUPPAUGE_HVR1200, - }, { - .subvendor = 0x0070, - .subdevice = 0x71d3, - .card = CX23885_BOARD_HAUPPAUGE_HVR1200, - }, { - .subvendor = 0x0070, - .subdevice = 0x8101, - .card = CX23885_BOARD_HAUPPAUGE_HVR1700, - }, { - .subvendor = 0x0070, - .subdevice = 0x8010, - .card = CX23885_BOARD_HAUPPAUGE_HVR1400, - }, { - .subvendor = 0x18ac, - .subdevice = 0xd618, - .card = CX23885_BOARD_DVICO_FUSIONHDTV_7_DUAL_EXP, - }, { - .subvendor = 0x18ac, - .subdevice = 0xdb78, - .card = CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP, - }, { - .subvendor = 0x107d, - .subdevice = 0x6681, - .card = CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H, - }, { - .subvendor = 0x107d, - .subdevice = 0x6f39, - .card = CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H_XC4000, - }, { - .subvendor = 0x185b, - .subdevice = 0xe800, - .card = CX23885_BOARD_COMPRO_VIDEOMATE_E650F, - }, { - .subvendor = 0x6920, - .subdevice = 0x8888, - .card = CX23885_BOARD_TBS_6920, - }, { - .subvendor = 0xd470, - .subdevice = 0x9022, - .card = CX23885_BOARD_TEVII_S470, - }, { - .subvendor = 0x0001, - .subdevice = 0x2005, - .card = CX23885_BOARD_DVBWORLD_2005, - }, { - .subvendor = 0x1b55, - .subdevice = 0x2a2c, - .card = CX23885_BOARD_NETUP_DUAL_DVBS2_CI, - }, { - .subvendor = 0x0070, - .subdevice = 0x2211, - .card = CX23885_BOARD_HAUPPAUGE_HVR1270, - }, { - .subvendor = 0x0070, - .subdevice = 0x2215, - .card = CX23885_BOARD_HAUPPAUGE_HVR1275, - }, { - .subvendor = 0x0070, - .subdevice = 0x221d, - .card = CX23885_BOARD_HAUPPAUGE_HVR1275, - }, { - .subvendor = 0x0070, - .subdevice = 0x2251, - .card = CX23885_BOARD_HAUPPAUGE_HVR1255, - }, { - .subvendor = 0x0070, - .subdevice = 0x2259, - .card = CX23885_BOARD_HAUPPAUGE_HVR1255_22111, - }, { - .subvendor = 0x0070, - .subdevice = 0x2291, - .card = CX23885_BOARD_HAUPPAUGE_HVR1210, - }, { - .subvendor = 0x0070, - .subdevice = 0x2295, - .card = CX23885_BOARD_HAUPPAUGE_HVR1210, - }, { - .subvendor = 0x0070, - .subdevice = 0x2299, - .card = CX23885_BOARD_HAUPPAUGE_HVR1210, - }, { - .subvendor = 0x0070, - .subdevice = 0x229d, - .card = CX23885_BOARD_HAUPPAUGE_HVR1210, /* HVR1215 */ - }, { - .subvendor = 0x0070, - .subdevice = 0x22f0, - .card = CX23885_BOARD_HAUPPAUGE_HVR1210, - }, { - .subvendor = 0x0070, - .subdevice = 0x22f1, - .card = CX23885_BOARD_HAUPPAUGE_HVR1255, - }, { - .subvendor = 0x0070, - .subdevice = 0x22f2, - .card = CX23885_BOARD_HAUPPAUGE_HVR1275, - }, { - .subvendor = 0x0070, - .subdevice = 0x22f3, - .card = CX23885_BOARD_HAUPPAUGE_HVR1210, /* HVR1215 */ - }, { - .subvendor = 0x0070, - .subdevice = 0x22f4, - .card = CX23885_BOARD_HAUPPAUGE_HVR1210, - }, { - .subvendor = 0x0070, - .subdevice = 0x22f5, - .card = CX23885_BOARD_HAUPPAUGE_HVR1210, /* HVR1215 */ - }, { - .subvendor = 0x14f1, - .subdevice = 0x8651, - .card = CX23885_BOARD_MYGICA_X8506, - }, { - .subvendor = 0x14f1, - .subdevice = 0x8657, - .card = CX23885_BOARD_MAGICPRO_PROHDTVE2, - }, { - .subvendor = 0x0070, - .subdevice = 0x8541, - .card = CX23885_BOARD_HAUPPAUGE_HVR1850, - }, { - .subvendor = 0x1858, - .subdevice = 0xe800, - .card = CX23885_BOARD_COMPRO_VIDEOMATE_E800, - }, { - .subvendor = 0x0070, - .subdevice = 0x8551, - .card = CX23885_BOARD_HAUPPAUGE_HVR1290, - }, { - .subvendor = 0x14f1, - .subdevice = 0x8578, - .card = CX23885_BOARD_MYGICA_X8558PRO, - }, { - .subvendor = 0x107d, - .subdevice = 0x6f22, - .card = CX23885_BOARD_LEADTEK_WINFAST_PXTV1200, - }, { - .subvendor = 0x5654, - .subdevice = 0x2390, - .card = CX23885_BOARD_GOTVIEW_X5_3D_HYBRID, - }, { - .subvendor = 0x1b55, - .subdevice = 0xe2e4, - .card = CX23885_BOARD_NETUP_DUAL_DVB_T_C_CI_RF, - }, { - .subvendor = 0x14f1, - .subdevice = 0x8502, - .card = CX23885_BOARD_MYGICA_X8507, - }, { - .subvendor = 0x153b, - .subdevice = 0x117e, - .card = CX23885_BOARD_TERRATEC_CINERGY_T_PCIE_DUAL, - }, { - .subvendor = 0xd471, - .subdevice = 0x9022, - .card = CX23885_BOARD_TEVII_S471, - }, -}; -const unsigned int cx23885_idcount = ARRAY_SIZE(cx23885_subids); - -void cx23885_card_list(struct cx23885_dev *dev) -{ - int i; - - if (0 == dev->pci->subsystem_vendor && - 0 == dev->pci->subsystem_device) { - printk(KERN_INFO - "%s: Board has no valid PCIe Subsystem ID and can't\n" - "%s: be autodetected. Pass card=<n> insmod option\n" - "%s: to workaround that. Redirect complaints to the\n" - "%s: vendor of the TV card. Best regards,\n" - "%s: -- tux\n", - dev->name, dev->name, dev->name, dev->name, dev->name); - } else { - printk(KERN_INFO - "%s: Your board isn't known (yet) to the driver.\n" - "%s: Try to pick one of the existing card configs via\n" - "%s: card=<n> insmod option. Updating to the latest\n" - "%s: version might help as well.\n", - dev->name, dev->name, dev->name, dev->name); - } - printk(KERN_INFO "%s: Here is a list of valid choices for the card=<n> insmod option:\n", - dev->name); - for (i = 0; i < cx23885_bcount; i++) - printk(KERN_INFO "%s: card=%d -> %s\n", - dev->name, i, cx23885_boards[i].name); -} - -static void hauppauge_eeprom(struct cx23885_dev *dev, u8 *eeprom_data) -{ - struct tveeprom tv; - - tveeprom_hauppauge_analog(&dev->i2c_bus[0].i2c_client, &tv, - eeprom_data); - - /* Make sure we support the board model */ - switch (tv.model) { - case 22001: - /* WinTV-HVR1270 (PCIe, Retail, half height) - * ATSC/QAM and basic analog, IR Blast */ - case 22009: - /* WinTV-HVR1210 (PCIe, Retail, half height) - * DVB-T and basic analog, IR Blast */ - case 22011: - /* WinTV-HVR1270 (PCIe, Retail, half height) - * ATSC/QAM and basic analog, IR Recv */ - case 22019: - /* WinTV-HVR1210 (PCIe, Retail, half height) - * DVB-T and basic analog, IR Recv */ - case 22021: - /* WinTV-HVR1275 (PCIe, Retail, half height) - * ATSC/QAM and basic analog, IR Recv */ - case 22029: - /* WinTV-HVR1210 (PCIe, Retail, half height) - * DVB-T and basic analog, IR Recv */ - case 22101: - /* WinTV-HVR1270 (PCIe, Retail, full height) - * ATSC/QAM and basic analog, IR Blast */ - case 22109: - /* WinTV-HVR1210 (PCIe, Retail, full height) - * DVB-T and basic analog, IR Blast */ - case 22111: - /* WinTV-HVR1270 (PCIe, Retail, full height) - * ATSC/QAM and basic analog, IR Recv */ - case 22119: - /* WinTV-HVR1210 (PCIe, Retail, full height) - * DVB-T and basic analog, IR Recv */ - case 22121: - /* WinTV-HVR1275 (PCIe, Retail, full height) - * ATSC/QAM and basic analog, IR Recv */ - case 22129: - /* WinTV-HVR1210 (PCIe, Retail, full height) - * DVB-T and basic analog, IR Recv */ - case 71009: - /* WinTV-HVR1200 (PCIe, Retail, full height) - * DVB-T and basic analog */ - case 71359: - /* WinTV-HVR1200 (PCIe, OEM, half height) - * DVB-T and basic analog */ - case 71439: - /* WinTV-HVR1200 (PCIe, OEM, half height) - * DVB-T and basic analog */ - case 71449: - /* WinTV-HVR1200 (PCIe, OEM, full height) - * DVB-T and basic analog */ - case 71939: - /* WinTV-HVR1200 (PCIe, OEM, half height) - * DVB-T and basic analog */ - case 71949: - /* WinTV-HVR1200 (PCIe, OEM, full height) - * DVB-T and basic analog */ - case 71959: - /* WinTV-HVR1200 (PCIe, OEM, full height) - * DVB-T and basic analog */ - case 71979: - /* WinTV-HVR1200 (PCIe, OEM, half height) - * DVB-T and basic analog */ - case 71999: - /* WinTV-HVR1200 (PCIe, OEM, full height) - * DVB-T and basic analog */ - case 76601: - /* WinTV-HVR1800lp (PCIe, Retail, No IR, Dual - channel ATSC and MPEG2 HW Encoder */ - case 77001: - /* WinTV-HVR1500 (Express Card, OEM, No IR, ATSC - and Basic analog */ - case 77011: - /* WinTV-HVR1500 (Express Card, Retail, No IR, ATSC - and Basic analog */ - case 77041: - /* WinTV-HVR1500Q (Express Card, OEM, No IR, ATSC/QAM - and Basic analog */ - case 77051: - /* WinTV-HVR1500Q (Express Card, Retail, No IR, ATSC/QAM - and Basic analog */ - case 78011: - /* WinTV-HVR1800 (PCIe, Retail, 3.5mm in, IR, No FM, - Dual channel ATSC and MPEG2 HW Encoder */ - case 78501: - /* WinTV-HVR1800 (PCIe, OEM, RCA in, No IR, FM, - Dual channel ATSC and MPEG2 HW Encoder */ - case 78521: - /* WinTV-HVR1800 (PCIe, OEM, RCA in, No IR, FM, - Dual channel ATSC and MPEG2 HW Encoder */ - case 78531: - /* WinTV-HVR1800 (PCIe, OEM, RCA in, No IR, No FM, - Dual channel ATSC and MPEG2 HW Encoder */ - case 78631: - /* WinTV-HVR1800 (PCIe, OEM, No IR, No FM, - Dual channel ATSC and MPEG2 HW Encoder */ - case 79001: - /* WinTV-HVR1250 (PCIe, Retail, IR, full height, - ATSC and Basic analog */ - case 79101: - /* WinTV-HVR1250 (PCIe, Retail, IR, half height, - ATSC and Basic analog */ - case 79501: - /* WinTV-HVR1250 (PCIe, No IR, half height, - ATSC [at least] and Basic analog) */ - case 79561: - /* WinTV-HVR1250 (PCIe, OEM, No IR, half height, - ATSC and Basic analog */ - case 79571: - /* WinTV-HVR1250 (PCIe, OEM, No IR, full height, - ATSC and Basic analog */ - case 79671: - /* WinTV-HVR1250 (PCIe, OEM, No IR, half height, - ATSC and Basic analog */ - case 80019: - /* WinTV-HVR1400 (Express Card, Retail, IR, - * DVB-T and Basic analog */ - case 81509: - /* WinTV-HVR1700 (PCIe, OEM, No IR, half height) - * DVB-T and MPEG2 HW Encoder */ - case 81519: - /* WinTV-HVR1700 (PCIe, OEM, No IR, full height) - * DVB-T and MPEG2 HW Encoder */ - break; - case 85021: - /* WinTV-HVR1850 (PCIe, Retail, 3.5mm in, IR, FM, - Dual channel ATSC and MPEG2 HW Encoder */ - break; - case 85721: - /* WinTV-HVR1290 (PCIe, OEM, RCA in, IR, - Dual channel ATSC and Basic analog */ - break; - default: - printk(KERN_WARNING "%s: warning: " - "unknown hauppauge model #%d\n", - dev->name, tv.model); - break; - } - - printk(KERN_INFO "%s: hauppauge eeprom: model=%d\n", - dev->name, tv.model); -} - -int cx23885_tuner_callback(void *priv, int component, int command, int arg) -{ - struct cx23885_tsport *port = priv; - struct cx23885_dev *dev = port->dev; - u32 bitmask = 0; - - if ((command == XC2028_RESET_CLK) || (command == XC2028_I2C_FLUSH)) - return 0; - - if (command != 0) { - printk(KERN_ERR "%s(): Unknown command 0x%x.\n", - __func__, command); - return -EINVAL; - } - - switch (dev->board) { - case CX23885_BOARD_HAUPPAUGE_HVR1400: - case CX23885_BOARD_HAUPPAUGE_HVR1500: - case CX23885_BOARD_HAUPPAUGE_HVR1500Q: - case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H: - case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H_XC4000: - case CX23885_BOARD_COMPRO_VIDEOMATE_E650F: - case CX23885_BOARD_COMPRO_VIDEOMATE_E800: - case CX23885_BOARD_LEADTEK_WINFAST_PXTV1200: - /* Tuner Reset Command */ - bitmask = 0x04; - break; - case CX23885_BOARD_DVICO_FUSIONHDTV_7_DUAL_EXP: - case CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP: - /* Two identical tuners on two different i2c buses, - * we need to reset the correct gpio. */ - if (port->nr == 1) - bitmask = 0x01; - else if (port->nr == 2) - bitmask = 0x04; - break; - case CX23885_BOARD_GOTVIEW_X5_3D_HYBRID: - /* Tuner Reset Command */ - bitmask = 0x02; - break; - case CX23885_BOARD_NETUP_DUAL_DVB_T_C_CI_RF: - altera_ci_tuner_reset(dev, port->nr); - break; - } - - if (bitmask) { - /* Drive the tuner into reset and back out */ - cx_clear(GP0_IO, bitmask); - mdelay(200); - cx_set(GP0_IO, bitmask); - } - - return 0; -} - -void cx23885_gpio_setup(struct cx23885_dev *dev) -{ - switch (dev->board) { - case CX23885_BOARD_HAUPPAUGE_HVR1250: - /* GPIO-0 cx24227 demodulator reset */ - cx_set(GP0_IO, 0x00010001); /* Bring the part out of reset */ - break; - case CX23885_BOARD_HAUPPAUGE_HVR1500: - /* GPIO-0 cx24227 demodulator */ - /* GPIO-2 xc3028 tuner */ - - /* Put the parts into reset */ - cx_set(GP0_IO, 0x00050000); - cx_clear(GP0_IO, 0x00000005); - msleep(5); - - /* Bring the parts out of reset */ - cx_set(GP0_IO, 0x00050005); - break; - case CX23885_BOARD_HAUPPAUGE_HVR1500Q: - /* GPIO-0 cx24227 demodulator reset */ - /* GPIO-2 xc5000 tuner reset */ - cx_set(GP0_IO, 0x00050005); /* Bring the part out of reset */ - break; - case CX23885_BOARD_HAUPPAUGE_HVR1800: - /* GPIO-0 656_CLK */ - /* GPIO-1 656_D0 */ - /* GPIO-2 8295A Reset */ - /* GPIO-3-10 cx23417 data0-7 */ - /* GPIO-11-14 cx23417 addr0-3 */ - /* GPIO-15-18 cx23417 READY, CS, RD, WR */ - /* GPIO-19 IR_RX */ - - /* CX23417 GPIO's */ - /* EIO15 Zilog Reset */ - /* EIO14 S5H1409/CX24227 Reset */ - mc417_gpio_enable(dev, GPIO_15 | GPIO_14, 1); - - /* Put the demod into reset and protect the eeprom */ - mc417_gpio_clear(dev, GPIO_15 | GPIO_14); - mdelay(100); - - /* Bring the demod and blaster out of reset */ - mc417_gpio_set(dev, GPIO_15 | GPIO_14); - mdelay(100); - - /* Force the TDA8295A into reset and back */ - cx23885_gpio_enable(dev, GPIO_2, 1); - cx23885_gpio_set(dev, GPIO_2); - mdelay(20); - cx23885_gpio_clear(dev, GPIO_2); - mdelay(20); - cx23885_gpio_set(dev, GPIO_2); - mdelay(20); - break; - case CX23885_BOARD_HAUPPAUGE_HVR1200: - /* GPIO-0 tda10048 demodulator reset */ - /* GPIO-2 tda18271 tuner reset */ - - /* Put the parts into reset and back */ - cx_set(GP0_IO, 0x00050000); - mdelay(20); - cx_clear(GP0_IO, 0x00000005); - mdelay(20); - cx_set(GP0_IO, 0x00050005); - break; - case CX23885_BOARD_HAUPPAUGE_HVR1700: - /* GPIO-0 TDA10048 demodulator reset */ - /* GPIO-2 TDA8295A Reset */ - /* GPIO-3-10 cx23417 data0-7 */ - /* GPIO-11-14 cx23417 addr0-3 */ - /* GPIO-15-18 cx23417 READY, CS, RD, WR */ - - /* The following GPIO's are on the interna AVCore (cx25840) */ - /* GPIO-19 IR_RX */ - /* GPIO-20 IR_TX 416/DVBT Select */ - /* GPIO-21 IIS DAT */ - /* GPIO-22 IIS WCLK */ - /* GPIO-23 IIS BCLK */ - - /* Put the parts into reset and back */ - cx_set(GP0_IO, 0x00050000); - mdelay(20); - cx_clear(GP0_IO, 0x00000005); - mdelay(20); - cx_set(GP0_IO, 0x00050005); - break; - case CX23885_BOARD_HAUPPAUGE_HVR1400: - /* GPIO-0 Dibcom7000p demodulator reset */ - /* GPIO-2 xc3028L tuner reset */ - /* GPIO-13 LED */ - - /* Put the parts into reset and back */ - cx_set(GP0_IO, 0x00050000); - mdelay(20); - cx_clear(GP0_IO, 0x00000005); - mdelay(20); - cx_set(GP0_IO, 0x00050005); - break; - case CX23885_BOARD_DVICO_FUSIONHDTV_7_DUAL_EXP: - /* GPIO-0 xc5000 tuner reset i2c bus 0 */ - /* GPIO-1 s5h1409 demod reset i2c bus 0 */ - /* GPIO-2 xc5000 tuner reset i2c bus 1 */ - /* GPIO-3 s5h1409 demod reset i2c bus 0 */ - - /* Put the parts into reset and back */ - cx_set(GP0_IO, 0x000f0000); - mdelay(20); - cx_clear(GP0_IO, 0x0000000f); - mdelay(20); - cx_set(GP0_IO, 0x000f000f); - break; - case CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP: - /* GPIO-0 portb xc3028 reset */ - /* GPIO-1 portb zl10353 reset */ - /* GPIO-2 portc xc3028 reset */ - /* GPIO-3 portc zl10353 reset */ - - /* Put the parts into reset and back */ - cx_set(GP0_IO, 0x000f0000); - mdelay(20); - cx_clear(GP0_IO, 0x0000000f); - mdelay(20); - cx_set(GP0_IO, 0x000f000f); - break; - case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H: - case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H_XC4000: - case CX23885_BOARD_COMPRO_VIDEOMATE_E650F: - case CX23885_BOARD_COMPRO_VIDEOMATE_E800: - case CX23885_BOARD_LEADTEK_WINFAST_PXTV1200: - /* GPIO-2 xc3028 tuner reset */ - - /* The following GPIO's are on the internal AVCore (cx25840) */ - /* GPIO-? zl10353 demod reset */ - - /* Put the parts into reset and back */ - cx_set(GP0_IO, 0x00040000); - mdelay(20); - cx_clear(GP0_IO, 0x00000004); - mdelay(20); - cx_set(GP0_IO, 0x00040004); - break; - case CX23885_BOARD_TBS_6920: - cx_write(MC417_CTL, 0x00000036); - cx_write(MC417_OEN, 0x00001000); - cx_set(MC417_RWD, 0x00000002); - mdelay(200); - cx_clear(MC417_RWD, 0x00000800); - mdelay(200); - cx_set(MC417_RWD, 0x00000800); - mdelay(200); - break; - case CX23885_BOARD_NETUP_DUAL_DVBS2_CI: - /* GPIO-0 INTA from CiMax1 - GPIO-1 INTB from CiMax2 - GPIO-2 reset chips - GPIO-3 to GPIO-10 data/addr for CA - GPIO-11 ~CS0 to CiMax1 - GPIO-12 ~CS1 to CiMax2 - GPIO-13 ADL0 load LSB addr - GPIO-14 ADL1 load MSB addr - GPIO-15 ~RDY from CiMax - GPIO-17 ~RD to CiMax - GPIO-18 ~WR to CiMax - */ - cx_set(GP0_IO, 0x00040000); /* GPIO as out */ - /* GPIO1 and GPIO2 as INTA and INTB from CiMaxes, reset low */ - cx_clear(GP0_IO, 0x00030004); - mdelay(100);/* reset delay */ - cx_set(GP0_IO, 0x00040004); /* GPIO as out, reset high */ - cx_write(MC417_CTL, 0x00000037);/* enable GPIO3-18 pins */ - /* GPIO-15 IN as ~ACK, rest as OUT */ - cx_write(MC417_OEN, 0x00001000); - /* ~RD, ~WR high; ADL0, ADL1 low; ~CS0, ~CS1 high */ - cx_write(MC417_RWD, 0x0000c300); - /* enable irq */ - cx_write(GPIO_ISM, 0x00000000);/* INTERRUPTS active low*/ - break; - case CX23885_BOARD_HAUPPAUGE_HVR1270: - case CX23885_BOARD_HAUPPAUGE_HVR1275: - case CX23885_BOARD_HAUPPAUGE_HVR1255: - case CX23885_BOARD_HAUPPAUGE_HVR1255_22111: - case CX23885_BOARD_HAUPPAUGE_HVR1210: - /* GPIO-5 RF Control: 0 = RF1 Terrestrial, 1 = RF2 Cable */ - /* GPIO-6 I2C Gate which can isolate the demod from the bus */ - /* GPIO-9 Demod reset */ - - /* Put the parts into reset and back */ - cx23885_gpio_enable(dev, GPIO_9 | GPIO_6 | GPIO_5, 1); - cx23885_gpio_set(dev, GPIO_9 | GPIO_6 | GPIO_5); - cx23885_gpio_clear(dev, GPIO_9); - mdelay(20); - cx23885_gpio_set(dev, GPIO_9); - break; - case CX23885_BOARD_MYGICA_X8506: - case CX23885_BOARD_MAGICPRO_PROHDTVE2: - case CX23885_BOARD_MYGICA_X8507: - /* GPIO-0 (0)Analog / (1)Digital TV */ - /* GPIO-1 reset XC5000 */ - /* GPIO-2 reset LGS8GL5 / LGS8G75 */ - cx23885_gpio_enable(dev, GPIO_0 | GPIO_1 | GPIO_2, 1); - cx23885_gpio_clear(dev, GPIO_1 | GPIO_2); - mdelay(100); - cx23885_gpio_set(dev, GPIO_0 | GPIO_1 | GPIO_2); - mdelay(100); - break; - case CX23885_BOARD_MYGICA_X8558PRO: - /* GPIO-0 reset first ATBM8830 */ - /* GPIO-1 reset second ATBM8830 */ - cx23885_gpio_enable(dev, GPIO_0 | GPIO_1, 1); - cx23885_gpio_clear(dev, GPIO_0 | GPIO_1); - mdelay(100); - cx23885_gpio_set(dev, GPIO_0 | GPIO_1); - mdelay(100); - break; - case CX23885_BOARD_HAUPPAUGE_HVR1850: - case CX23885_BOARD_HAUPPAUGE_HVR1290: - /* GPIO-0 656_CLK */ - /* GPIO-1 656_D0 */ - /* GPIO-2 Wake# */ - /* GPIO-3-10 cx23417 data0-7 */ - /* GPIO-11-14 cx23417 addr0-3 */ - /* GPIO-15-18 cx23417 READY, CS, RD, WR */ - /* GPIO-19 IR_RX */ - /* GPIO-20 C_IR_TX */ - /* GPIO-21 I2S DAT */ - /* GPIO-22 I2S WCLK */ - /* GPIO-23 I2S BCLK */ - /* ALT GPIO: EXP GPIO LATCH */ - - /* CX23417 GPIO's */ - /* GPIO-14 S5H1411/CX24228 Reset */ - /* GPIO-13 EEPROM write protect */ - mc417_gpio_enable(dev, GPIO_14 | GPIO_13, 1); - - /* Put the demod into reset and protect the eeprom */ - mc417_gpio_clear(dev, GPIO_14 | GPIO_13); - mdelay(100); - - /* Bring the demod out of reset */ - mc417_gpio_set(dev, GPIO_14); - mdelay(100); - - /* CX24228 GPIO */ - /* Connected to IF / Mux */ - break; - case CX23885_BOARD_GOTVIEW_X5_3D_HYBRID: - cx_set(GP0_IO, 0x00010001); /* Bring the part out of reset */ - break; - case CX23885_BOARD_NETUP_DUAL_DVB_T_C_CI_RF: - /* GPIO-0 ~INT in - GPIO-1 TMS out - GPIO-2 ~reset chips out - GPIO-3 to GPIO-10 data/addr for CA in/out - GPIO-11 ~CS out - GPIO-12 ADDR out - GPIO-13 ~WR out - GPIO-14 ~RD out - GPIO-15 ~RDY in - GPIO-16 TCK out - GPIO-17 TDO in - GPIO-18 TDI out - */ - cx_set(GP0_IO, 0x00060000); /* GPIO-1,2 as out */ - /* GPIO-0 as INT, reset & TMS low */ - cx_clear(GP0_IO, 0x00010006); - mdelay(100);/* reset delay */ - cx_set(GP0_IO, 0x00000004); /* reset high */ - cx_write(MC417_CTL, 0x00000037);/* enable GPIO-3..18 pins */ - /* GPIO-17 is TDO in, GPIO-15 is ~RDY in, rest is out */ - cx_write(MC417_OEN, 0x00005000); - /* ~RD, ~WR high; ADDR low; ~CS high */ - cx_write(MC417_RWD, 0x00000d00); - /* enable irq */ - cx_write(GPIO_ISM, 0x00000000);/* INTERRUPTS active low*/ - break; - } -} - -int cx23885_ir_init(struct cx23885_dev *dev) -{ - static struct v4l2_subdev_io_pin_config ir_rxtx_pin_cfg[] = { - { - .flags = V4L2_SUBDEV_IO_PIN_INPUT, - .pin = CX23885_PIN_IR_RX_GPIO19, - .function = CX23885_PAD_IR_RX, - .value = 0, - .strength = CX25840_PIN_DRIVE_MEDIUM, - }, { - .flags = V4L2_SUBDEV_IO_PIN_OUTPUT, - .pin = CX23885_PIN_IR_TX_GPIO20, - .function = CX23885_PAD_IR_TX, - .value = 0, - .strength = CX25840_PIN_DRIVE_MEDIUM, - } - }; - const size_t ir_rxtx_pin_cfg_count = ARRAY_SIZE(ir_rxtx_pin_cfg); - - static struct v4l2_subdev_io_pin_config ir_rx_pin_cfg[] = { - { - .flags = V4L2_SUBDEV_IO_PIN_INPUT, - .pin = CX23885_PIN_IR_RX_GPIO19, - .function = CX23885_PAD_IR_RX, - .value = 0, - .strength = CX25840_PIN_DRIVE_MEDIUM, - } - }; - const size_t ir_rx_pin_cfg_count = ARRAY_SIZE(ir_rx_pin_cfg); - - struct v4l2_subdev_ir_parameters params; - int ret = 0; - switch (dev->board) { - case CX23885_BOARD_HAUPPAUGE_HVR1500: - case CX23885_BOARD_HAUPPAUGE_HVR1500Q: - case CX23885_BOARD_HAUPPAUGE_HVR1800: - case CX23885_BOARD_HAUPPAUGE_HVR1200: - case CX23885_BOARD_HAUPPAUGE_HVR1400: - case CX23885_BOARD_HAUPPAUGE_HVR1275: - case CX23885_BOARD_HAUPPAUGE_HVR1255: - case CX23885_BOARD_HAUPPAUGE_HVR1255_22111: - case CX23885_BOARD_HAUPPAUGE_HVR1210: - /* FIXME: Implement me */ - break; - case CX23885_BOARD_HAUPPAUGE_HVR1270: - ret = cx23888_ir_probe(dev); - if (ret) - break; - dev->sd_ir = cx23885_find_hw(dev, CX23885_HW_888_IR); - v4l2_subdev_call(dev->sd_cx25840, core, s_io_pin_config, - ir_rx_pin_cfg_count, ir_rx_pin_cfg); - break; - case CX23885_BOARD_HAUPPAUGE_HVR1850: - case CX23885_BOARD_HAUPPAUGE_HVR1290: - ret = cx23888_ir_probe(dev); - if (ret) - break; - dev->sd_ir = cx23885_find_hw(dev, CX23885_HW_888_IR); - v4l2_subdev_call(dev->sd_cx25840, core, s_io_pin_config, - ir_rxtx_pin_cfg_count, ir_rxtx_pin_cfg); - /* - * For these boards we need to invert the Tx output via the - * IR controller to have the LED off while idle - */ - v4l2_subdev_call(dev->sd_ir, ir, tx_g_parameters, ¶ms); - params.enable = false; - params.shutdown = false; - params.invert_level = true; - v4l2_subdev_call(dev->sd_ir, ir, tx_s_parameters, ¶ms); - params.shutdown = true; - v4l2_subdev_call(dev->sd_ir, ir, tx_s_parameters, ¶ms); - break; - case CX23885_BOARD_TERRATEC_CINERGY_T_PCIE_DUAL: - case CX23885_BOARD_TEVII_S470: - if (!enable_885_ir) - break; - dev->sd_ir = cx23885_find_hw(dev, CX23885_HW_AV_CORE); - if (dev->sd_ir == NULL) { - ret = -ENODEV; - break; - } - v4l2_subdev_call(dev->sd_cx25840, core, s_io_pin_config, - ir_rx_pin_cfg_count, ir_rx_pin_cfg); - break; - case CX23885_BOARD_HAUPPAUGE_HVR1250: - if (!enable_885_ir) - break; - dev->sd_ir = cx23885_find_hw(dev, CX23885_HW_AV_CORE); - if (dev->sd_ir == NULL) { - ret = -ENODEV; - break; - } - v4l2_subdev_call(dev->sd_cx25840, core, s_io_pin_config, - ir_rxtx_pin_cfg_count, ir_rxtx_pin_cfg); - break; - case CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP: - request_module("ir-kbd-i2c"); - break; - } - - return ret; -} - -void cx23885_ir_fini(struct cx23885_dev *dev) -{ - switch (dev->board) { - case CX23885_BOARD_HAUPPAUGE_HVR1270: - case CX23885_BOARD_HAUPPAUGE_HVR1850: - case CX23885_BOARD_HAUPPAUGE_HVR1290: - cx23885_irq_remove(dev, PCI_MSK_IR); - cx23888_ir_remove(dev); - dev->sd_ir = NULL; - break; - case CX23885_BOARD_TERRATEC_CINERGY_T_PCIE_DUAL: - case CX23885_BOARD_TEVII_S470: - case CX23885_BOARD_HAUPPAUGE_HVR1250: - cx23885_irq_remove(dev, PCI_MSK_AV_CORE); - /* sd_ir is a duplicate pointer to the AV Core, just clear it */ - dev->sd_ir = NULL; - break; - } -} - -int netup_jtag_io(void *device, int tms, int tdi, int read_tdo) -{ - int data; - int tdo = 0; - struct cx23885_dev *dev = (struct cx23885_dev *)device; - /*TMS*/ - data = ((cx_read(GP0_IO)) & (~0x00000002)); - data |= (tms ? 0x00020002 : 0x00020000); - cx_write(GP0_IO, data); - - /*TDI*/ - data = ((cx_read(MC417_RWD)) & (~0x0000a000)); - data |= (tdi ? 0x00008000 : 0); - cx_write(MC417_RWD, data); - if (read_tdo) - tdo = (data & 0x00004000) ? 1 : 0; /*TDO*/ - - cx_write(MC417_RWD, data | 0x00002000); - udelay(1); - /*TCK*/ - cx_write(MC417_RWD, data); - - return tdo; -} - -void cx23885_ir_pci_int_enable(struct cx23885_dev *dev) -{ - switch (dev->board) { - case CX23885_BOARD_HAUPPAUGE_HVR1270: - case CX23885_BOARD_HAUPPAUGE_HVR1850: - case CX23885_BOARD_HAUPPAUGE_HVR1290: - if (dev->sd_ir) - cx23885_irq_add_enable(dev, PCI_MSK_IR); - break; - case CX23885_BOARD_TERRATEC_CINERGY_T_PCIE_DUAL: - case CX23885_BOARD_TEVII_S470: - case CX23885_BOARD_HAUPPAUGE_HVR1250: - if (dev->sd_ir) - cx23885_irq_add_enable(dev, PCI_MSK_AV_CORE); - break; - } -} - -void cx23885_card_setup(struct cx23885_dev *dev) -{ - struct cx23885_tsport *ts1 = &dev->ts1; - struct cx23885_tsport *ts2 = &dev->ts2; - - static u8 eeprom[256]; - - if (dev->i2c_bus[0].i2c_rc == 0) { - dev->i2c_bus[0].i2c_client.addr = 0xa0 >> 1; - tveeprom_read(&dev->i2c_bus[0].i2c_client, - eeprom, sizeof(eeprom)); - } - - switch (dev->board) { - case CX23885_BOARD_HAUPPAUGE_HVR1250: - if (dev->i2c_bus[0].i2c_rc == 0) { - if (eeprom[0x80] != 0x84) - hauppauge_eeprom(dev, eeprom+0xc0); - else - hauppauge_eeprom(dev, eeprom+0x80); - } - break; - case CX23885_BOARD_HAUPPAUGE_HVR1500: - case CX23885_BOARD_HAUPPAUGE_HVR1500Q: - case CX23885_BOARD_HAUPPAUGE_HVR1400: - if (dev->i2c_bus[0].i2c_rc == 0) - hauppauge_eeprom(dev, eeprom+0x80); - break; - case CX23885_BOARD_HAUPPAUGE_HVR1800: - case CX23885_BOARD_HAUPPAUGE_HVR1800lp: - case CX23885_BOARD_HAUPPAUGE_HVR1200: - case CX23885_BOARD_HAUPPAUGE_HVR1700: - case CX23885_BOARD_HAUPPAUGE_HVR1270: - case CX23885_BOARD_HAUPPAUGE_HVR1275: - case CX23885_BOARD_HAUPPAUGE_HVR1255: - case CX23885_BOARD_HAUPPAUGE_HVR1255_22111: - case CX23885_BOARD_HAUPPAUGE_HVR1210: - case CX23885_BOARD_HAUPPAUGE_HVR1850: - case CX23885_BOARD_HAUPPAUGE_HVR1290: - if (dev->i2c_bus[0].i2c_rc == 0) - hauppauge_eeprom(dev, eeprom+0xc0); - break; - } - - switch (dev->board) { - case CX23885_BOARD_DVICO_FUSIONHDTV_7_DUAL_EXP: - case CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP: - ts2->gen_ctrl_val = 0xc; /* Serial bus + punctured clock */ - ts2->ts_clk_en_val = 0x1; /* Enable TS_CLK */ - ts2->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; - /* break omitted intentionally */ - case CX23885_BOARD_DVICO_FUSIONHDTV_5_EXP: - ts1->gen_ctrl_val = 0xc; /* Serial bus + punctured clock */ - ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */ - ts1->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; - break; - case CX23885_BOARD_HAUPPAUGE_HVR1850: - case CX23885_BOARD_HAUPPAUGE_HVR1800: - /* Defaults for VID B - Analog encoder */ - /* DREQ_POL, SMODE, PUNC_CLK, MCLK_POL Serial bus + punc clk */ - ts1->gen_ctrl_val = 0x10e; - ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */ - ts1->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; - - /* APB_TSVALERR_POL (active low)*/ - ts1->vld_misc_val = 0x2000; - ts1->hw_sop_ctrl_val = (0x47 << 16 | 188 << 4 | 0xc); - cx_write(0x130184, 0xc); - - /* Defaults for VID C */ - ts2->gen_ctrl_val = 0xc; /* Serial bus + punctured clock */ - ts2->ts_clk_en_val = 0x1; /* Enable TS_CLK */ - ts2->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; - break; - case CX23885_BOARD_TBS_6920: - ts1->gen_ctrl_val = 0x4; /* Parallel */ - ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */ - ts1->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; - break; - case CX23885_BOARD_TEVII_S470: - case CX23885_BOARD_TEVII_S471: - case CX23885_BOARD_DVBWORLD_2005: - ts1->gen_ctrl_val = 0x5; /* Parallel */ - ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */ - ts1->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; - break; - case CX23885_BOARD_NETUP_DUAL_DVBS2_CI: - case CX23885_BOARD_NETUP_DUAL_DVB_T_C_CI_RF: - case CX23885_BOARD_TERRATEC_CINERGY_T_PCIE_DUAL: - ts1->gen_ctrl_val = 0xc; /* Serial bus + punctured clock */ - ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */ - ts1->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; - ts2->gen_ctrl_val = 0xc; /* Serial bus + punctured clock */ - ts2->ts_clk_en_val = 0x1; /* Enable TS_CLK */ - ts2->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; - break; - case CX23885_BOARD_MYGICA_X8506: - case CX23885_BOARD_MAGICPRO_PROHDTVE2: - ts1->gen_ctrl_val = 0x5; /* Parallel */ - ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */ - ts1->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; - break; - case CX23885_BOARD_MYGICA_X8558PRO: - ts1->gen_ctrl_val = 0x5; /* Parallel */ - ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */ - ts1->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; - ts2->gen_ctrl_val = 0xc; /* Serial bus + punctured clock */ - ts2->ts_clk_en_val = 0x1; /* Enable TS_CLK */ - ts2->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; - break; - case CX23885_BOARD_HAUPPAUGE_HVR1250: - case CX23885_BOARD_HAUPPAUGE_HVR1500: - case CX23885_BOARD_HAUPPAUGE_HVR1500Q: - case CX23885_BOARD_HAUPPAUGE_HVR1800lp: - case CX23885_BOARD_HAUPPAUGE_HVR1200: - case CX23885_BOARD_HAUPPAUGE_HVR1700: - case CX23885_BOARD_HAUPPAUGE_HVR1400: - case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H: - case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H_XC4000: - case CX23885_BOARD_COMPRO_VIDEOMATE_E650F: - case CX23885_BOARD_HAUPPAUGE_HVR1270: - case CX23885_BOARD_HAUPPAUGE_HVR1275: - case CX23885_BOARD_HAUPPAUGE_HVR1255: - case CX23885_BOARD_HAUPPAUGE_HVR1255_22111: - case CX23885_BOARD_HAUPPAUGE_HVR1210: - case CX23885_BOARD_COMPRO_VIDEOMATE_E800: - case CX23885_BOARD_HAUPPAUGE_HVR1290: - case CX23885_BOARD_GOTVIEW_X5_3D_HYBRID: - default: - ts2->gen_ctrl_val = 0xc; /* Serial bus + punctured clock */ - ts2->ts_clk_en_val = 0x1; /* Enable TS_CLK */ - ts2->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; - } - - /* Certain boards support analog, or require the avcore to be - * loaded, ensure this happens. - */ - switch (dev->board) { - case CX23885_BOARD_TEVII_S470: - /* Currently only enabled for the integrated IR controller */ - if (!enable_885_ir) - break; - case CX23885_BOARD_HAUPPAUGE_HVR1250: - case CX23885_BOARD_HAUPPAUGE_HVR1800: - case CX23885_BOARD_HAUPPAUGE_HVR1800lp: - case CX23885_BOARD_HAUPPAUGE_HVR1700: - case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H: - case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H_XC4000: - case CX23885_BOARD_COMPRO_VIDEOMATE_E650F: - case CX23885_BOARD_NETUP_DUAL_DVBS2_CI: - case CX23885_BOARD_NETUP_DUAL_DVB_T_C_CI_RF: - case CX23885_BOARD_COMPRO_VIDEOMATE_E800: - case CX23885_BOARD_HAUPPAUGE_HVR1255: - case CX23885_BOARD_HAUPPAUGE_HVR1255_22111: - case CX23885_BOARD_HAUPPAUGE_HVR1270: - case CX23885_BOARD_HAUPPAUGE_HVR1850: - case CX23885_BOARD_MYGICA_X8506: - case CX23885_BOARD_MAGICPRO_PROHDTVE2: - case CX23885_BOARD_HAUPPAUGE_HVR1290: - case CX23885_BOARD_LEADTEK_WINFAST_PXTV1200: - case CX23885_BOARD_GOTVIEW_X5_3D_HYBRID: - case CX23885_BOARD_HAUPPAUGE_HVR1500: - case CX23885_BOARD_MPX885: - case CX23885_BOARD_MYGICA_X8507: - case CX23885_BOARD_TERRATEC_CINERGY_T_PCIE_DUAL: - dev->sd_cx25840 = v4l2_i2c_new_subdev(&dev->v4l2_dev, - &dev->i2c_bus[2].i2c_adap, - "cx25840", 0x88 >> 1, NULL); - if (dev->sd_cx25840) { - dev->sd_cx25840->grp_id = CX23885_HW_AV_CORE; - v4l2_subdev_call(dev->sd_cx25840, core, load_fw); - } - break; - } - - /* AUX-PLL 27MHz CLK */ - switch (dev->board) { - case CX23885_BOARD_NETUP_DUAL_DVBS2_CI: - netup_initialize(dev); - break; - case CX23885_BOARD_NETUP_DUAL_DVB_T_C_CI_RF: { - int ret; - const struct firmware *fw; - const char *filename = "dvb-netup-altera-01.fw"; - char *action = "configure"; - static struct netup_card_info cinfo; - struct altera_config netup_config = { - .dev = dev, - .action = action, - .jtag_io = netup_jtag_io, - }; - - netup_initialize(dev); - - netup_get_card_info(&dev->i2c_bus[0].i2c_adap, &cinfo); - if (netup_card_rev) - cinfo.rev = netup_card_rev; - - switch (cinfo.rev) { - case 0x4: - filename = "dvb-netup-altera-04.fw"; - break; - default: - filename = "dvb-netup-altera-01.fw"; - break; - } - printk(KERN_INFO "NetUP card rev=0x%x fw_filename=%s\n", - cinfo.rev, filename); - - ret = request_firmware(&fw, filename, &dev->pci->dev); - if (ret != 0) - printk(KERN_ERR "did not find the firmware file. (%s) " - "Please see linux/Documentation/dvb/ for more details " - "on firmware-problems.", filename); - else - altera_init(&netup_config, fw); - - release_firmware(fw); - break; - } - } -} - -/* ------------------------------------------------------------------ */ diff --git a/drivers/media/video/cx23885/cx23885-core.c b/drivers/media/video/cx23885/cx23885-core.c deleted file mode 100644 index 697728f0943..00000000000 --- a/drivers/media/video/cx23885/cx23885-core.c +++ /dev/null @@ -1,2234 +0,0 @@ -/* - * Driver for the Conexant CX23885 PCIe bridge - * - * Copyright (c) 2006 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 <linux/init.h> -#include <linux/list.h> -#include <linux/module.h> -#include <linux/moduleparam.h> -#include <linux/kmod.h> -#include <linux/kernel.h> -#include <linux/slab.h> -#include <linux/interrupt.h> -#include <linux/delay.h> -#include <asm/div64.h> -#include <linux/firmware.h> - -#include "cx23885.h" -#include "cimax2.h" -#include "altera-ci.h" -#include "cx23888-ir.h" -#include "cx23885-ir.h" -#include "cx23885-av.h" -#include "cx23885-input.h" - -MODULE_DESCRIPTION("Driver for cx23885 based TV cards"); -MODULE_AUTHOR("Steven Toth <stoth@linuxtv.org>"); -MODULE_LICENSE("GPL"); -MODULE_VERSION(CX23885_VERSION); - -static unsigned int debug; -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "enable debug messages"); - -static unsigned int card[] = {[0 ... (CX23885_MAXBOARDS - 1)] = UNSET }; -module_param_array(card, int, NULL, 0444); -MODULE_PARM_DESC(card, "card type"); - -#define dprintk(level, fmt, arg...)\ - do { if (debug >= level)\ - printk(KERN_DEBUG "%s: " fmt, dev->name, ## arg);\ - } while (0) - -static unsigned int cx23885_devcount; - -#define NO_SYNC_LINE (-1U) - -/* FIXME, these allocations will change when - * analog arrives. The be reviewed. - * CX23887 Assumptions - * 1 line = 16 bytes of CDT - * cmds size = 80 - * cdt size = 16 * linesize - * iqsize = 64 - * maxlines = 6 - * - * Address Space: - * 0x00000000 0x00008fff FIFO clusters - * 0x00010000 0x000104af Channel Management Data Structures - * 0x000104b0 0x000104ff Free - * 0x00010500 0x000108bf 15 channels * iqsize - * 0x000108c0 0x000108ff Free - * 0x00010900 0x00010e9f IQ's + Cluster Descriptor Tables - * 15 channels * (iqsize + (maxlines * linesize)) - * 0x00010ea0 0x00010xxx Free - */ - -static struct sram_channel cx23885_sram_channels[] = { - [SRAM_CH01] = { - .name = "VID A", - .cmds_start = 0x10000, - .ctrl_start = 0x10380, - .cdt = 0x104c0, - .fifo_start = 0x40, - .fifo_size = 0x2800, - .ptr1_reg = DMA1_PTR1, - .ptr2_reg = DMA1_PTR2, - .cnt1_reg = DMA1_CNT1, - .cnt2_reg = DMA1_CNT2, - }, - [SRAM_CH02] = { - .name = "ch2", - .cmds_start = 0x0, - .ctrl_start = 0x0, - .cdt = 0x0, - .fifo_start = 0x0, - .fifo_size = 0x0, - .ptr1_reg = DMA2_PTR1, - .ptr2_reg = DMA2_PTR2, - .cnt1_reg = DMA2_CNT1, - .cnt2_reg = DMA2_CNT2, - }, - [SRAM_CH03] = { - .name = "TS1 B", - .cmds_start = 0x100A0, - .ctrl_start = 0x10400, - .cdt = 0x10580, - .fifo_start = 0x5000, - .fifo_size = 0x1000, - .ptr1_reg = DMA3_PTR1, - .ptr2_reg = DMA3_PTR2, - .cnt1_reg = DMA3_CNT1, - .cnt2_reg = DMA3_CNT2, - }, - [SRAM_CH04] = { - .name = "ch4", - .cmds_start = 0x0, - .ctrl_start = 0x0, - .cdt = 0x0, - .fifo_start = 0x0, - .fifo_size = 0x0, - .ptr1_reg = DMA4_PTR1, - .ptr2_reg = DMA4_PTR2, - .cnt1_reg = DMA4_CNT1, - .cnt2_reg = DMA4_CNT2, - }, - [SRAM_CH05] = { - .name = "ch5", - .cmds_start = 0x0, - .ctrl_start = 0x0, - .cdt = 0x0, - .fifo_start = 0x0, - .fifo_size = 0x0, - .ptr1_reg = DMA5_PTR1, - .ptr2_reg = DMA5_PTR2, - .cnt1_reg = DMA5_CNT1, - .cnt2_reg = DMA5_CNT2, - }, - [SRAM_CH06] = { - .name = "TS2 C", - .cmds_start = 0x10140, - .ctrl_start = 0x10440, - .cdt = 0x105e0, - .fifo_start = 0x6000, - .fifo_size = 0x1000, - .ptr1_reg = DMA5_PTR1, - .ptr2_reg = DMA5_PTR2, - .cnt1_reg = DMA5_CNT1, - .cnt2_reg = DMA5_CNT2, - }, - [SRAM_CH07] = { - .name = "TV Audio", - .cmds_start = 0x10190, - .ctrl_start = 0x10480, - .cdt = 0x10a00, - .fifo_start = 0x7000, - .fifo_size = 0x1000, - .ptr1_reg = DMA6_PTR1, - .ptr2_reg = DMA6_PTR2, - .cnt1_reg = DMA6_CNT1, - .cnt2_reg = DMA6_CNT2, - }, - [SRAM_CH08] = { - .name = "ch8", - .cmds_start = 0x0, - .ctrl_start = 0x0, - .cdt = 0x0, - .fifo_start = 0x0, - .fifo_size = 0x0, - .ptr1_reg = DMA7_PTR1, - .ptr2_reg = DMA7_PTR2, - .cnt1_reg = DMA7_CNT1, - .cnt2_reg = DMA7_CNT2, - }, - [SRAM_CH09] = { - .name = "ch9", - .cmds_start = 0x0, - .ctrl_start = 0x0, - .cdt = 0x0, - .fifo_start = 0x0, - .fifo_size = 0x0, - .ptr1_reg = DMA8_PTR1, - .ptr2_reg = DMA8_PTR2, - .cnt1_reg = DMA8_CNT1, - .cnt2_reg = DMA8_CNT2, - }, -}; - -static struct sram_channel cx23887_sram_channels[] = { - [SRAM_CH01] = { - .name = "VID A", - .cmds_start = 0x10000, - .ctrl_start = 0x105b0, - .cdt = 0x107b0, - .fifo_start = 0x40, - .fifo_size = 0x2800, - .ptr1_reg = DMA1_PTR1, - .ptr2_reg = DMA1_PTR2, - .cnt1_reg = DMA1_CNT1, - .cnt2_reg = DMA1_CNT2, - }, - [SRAM_CH02] = { - .name = "VID A (VBI)", - .cmds_start = 0x10050, - .ctrl_start = 0x105F0, - .cdt = 0x10810, - .fifo_start = 0x3000, - .fifo_size = 0x1000, - .ptr1_reg = DMA2_PTR1, - .ptr2_reg = DMA2_PTR2, - .cnt1_reg = DMA2_CNT1, - .cnt2_reg = DMA2_CNT2, - }, - [SRAM_CH03] = { - .name = "TS1 B", - .cmds_start = 0x100A0, - .ctrl_start = 0x10630, - .cdt = 0x10870, - .fifo_start = 0x5000, - .fifo_size = 0x1000, - .ptr1_reg = DMA3_PTR1, - .ptr2_reg = DMA3_PTR2, - .cnt1_reg = DMA3_CNT1, - .cnt2_reg = DMA3_CNT2, - }, - [SRAM_CH04] = { - .name = "ch4", - .cmds_start = 0x0, - .ctrl_start = 0x0, - .cdt = 0x0, - .fifo_start = 0x0, - .fifo_size = 0x0, - .ptr1_reg = DMA4_PTR1, - .ptr2_reg = DMA4_PTR2, - .cnt1_reg = DMA4_CNT1, - .cnt2_reg = DMA4_CNT2, - }, - [SRAM_CH05] = { - .name = "ch5", - .cmds_start = 0x0, - .ctrl_start = 0x0, - .cdt = 0x0, - .fifo_start = 0x0, - .fifo_size = 0x0, - .ptr1_reg = DMA5_PTR1, - .ptr2_reg = DMA5_PTR2, - .cnt1_reg = DMA5_CNT1, - .cnt2_reg = DMA5_CNT2, - }, - [SRAM_CH06] = { - .name = "TS2 C", - .cmds_start = 0x10140, - .ctrl_start = 0x10670, - .cdt = 0x108d0, - .fifo_start = 0x6000, - .fifo_size = 0x1000, - .ptr1_reg = DMA5_PTR1, - .ptr2_reg = DMA5_PTR2, - .cnt1_reg = DMA5_CNT1, - .cnt2_reg = DMA5_CNT2, - }, - [SRAM_CH07] = { - .name = "TV Audio", - .cmds_start = 0x10190, - .ctrl_start = 0x106B0, - .cdt = 0x10930, - .fifo_start = 0x7000, - .fifo_size = 0x1000, - .ptr1_reg = DMA6_PTR1, - .ptr2_reg = DMA6_PTR2, - .cnt1_reg = DMA6_CNT1, - .cnt2_reg = DMA6_CNT2, - }, - [SRAM_CH08] = { - .name = "ch8", - .cmds_start = 0x0, - .ctrl_start = 0x0, - .cdt = 0x0, - .fifo_start = 0x0, - .fifo_size = 0x0, - .ptr1_reg = DMA7_PTR1, - .ptr2_reg = DMA7_PTR2, - .cnt1_reg = DMA7_CNT1, - .cnt2_reg = DMA7_CNT2, - }, - [SRAM_CH09] = { - .name = "ch9", - .cmds_start = 0x0, - .ctrl_start = 0x0, - .cdt = 0x0, - .fifo_start = 0x0, - .fifo_size = 0x0, - .ptr1_reg = DMA8_PTR1, - .ptr2_reg = DMA8_PTR2, - .cnt1_reg = DMA8_CNT1, - .cnt2_reg = DMA8_CNT2, - }, -}; - -void cx23885_irq_add(struct cx23885_dev *dev, u32 mask) -{ - unsigned long flags; - spin_lock_irqsave(&dev->pci_irqmask_lock, flags); - - dev->pci_irqmask |= mask; - - spin_unlock_irqrestore(&dev->pci_irqmask_lock, flags); -} - -void cx23885_irq_add_enable(struct cx23885_dev *dev, u32 mask) -{ - unsigned long flags; - spin_lock_irqsave(&dev->pci_irqmask_lock, flags); - - dev->pci_irqmask |= mask; - cx_set(PCI_INT_MSK, mask); - - spin_unlock_irqrestore(&dev->pci_irqmask_lock, flags); -} - -void cx23885_irq_enable(struct cx23885_dev *dev, u32 mask) -{ - u32 v; - unsigned long flags; - spin_lock_irqsave(&dev->pci_irqmask_lock, flags); - - v = mask & dev->pci_irqmask; - if (v) - cx_set(PCI_INT_MSK, v); - - spin_unlock_irqrestore(&dev->pci_irqmask_lock, flags); -} - -static inline void cx23885_irq_enable_all(struct cx23885_dev *dev) -{ - cx23885_irq_enable(dev, 0xffffffff); -} - -void cx23885_irq_disable(struct cx23885_dev *dev, u32 mask) -{ - unsigned long flags; - spin_lock_irqsave(&dev->pci_irqmask_lock, flags); - - cx_clear(PCI_INT_MSK, mask); - - spin_unlock_irqrestore(&dev->pci_irqmask_lock, flags); -} - -static inline void cx23885_irq_disable_all(struct cx23885_dev *dev) -{ - cx23885_irq_disable(dev, 0xffffffff); -} - -void cx23885_irq_remove(struct cx23885_dev *dev, u32 mask) -{ - unsigned long flags; - spin_lock_irqsave(&dev->pci_irqmask_lock, flags); - - dev->pci_irqmask &= ~mask; - cx_clear(PCI_INT_MSK, mask); - - spin_unlock_irqrestore(&dev->pci_irqmask_lock, flags); -} - -static u32 cx23885_irq_get_mask(struct cx23885_dev *dev) -{ - u32 v; - unsigned long flags; - spin_lock_irqsave(&dev->pci_irqmask_lock, flags); - - v = cx_read(PCI_INT_MSK); - - spin_unlock_irqrestore(&dev->pci_irqmask_lock, flags); - return v; -} - -static int cx23885_risc_decode(u32 risc) -{ - static char *instr[16] = { - [RISC_SYNC >> 28] = "sync", - [RISC_WRITE >> 28] = "write", - [RISC_WRITEC >> 28] = "writec", - [RISC_READ >> 28] = "read", - [RISC_READC >> 28] = "readc", - [RISC_JUMP >> 28] = "jump", - [RISC_SKIP >> 28] = "skip", - [RISC_WRITERM >> 28] = "writerm", - [RISC_WRITECM >> 28] = "writecm", - [RISC_WRITECR >> 28] = "writecr", - }; - static int incr[16] = { - [RISC_WRITE >> 28] = 3, - [RISC_JUMP >> 28] = 3, - [RISC_SKIP >> 28] = 1, - [RISC_SYNC >> 28] = 1, - [RISC_WRITERM >> 28] = 3, - [RISC_WRITECM >> 28] = 3, - [RISC_WRITECR >> 28] = 4, - }; - static char *bits[] = { - "12", "13", "14", "resync", - "cnt0", "cnt1", "18", "19", - "20", "21", "22", "23", - "irq1", "irq2", "eol", "sol", - }; - int i; - - printk("0x%08x [ %s", risc, - instr[risc >> 28] ? instr[risc >> 28] : "INVALID"); - for (i = ARRAY_SIZE(bits) - 1; i >= 0; i--) - if (risc & (1 << (i + 12))) - printk(" %s", bits[i]); - printk(" count=%d ]\n", risc & 0xfff); - return incr[risc >> 28] ? incr[risc >> 28] : 1; -} - -void cx23885_wakeup(struct cx23885_tsport *port, - struct cx23885_dmaqueue *q, u32 count) -{ - struct cx23885_dev *dev = port->dev; - struct cx23885_buffer *buf; - int bc; - - for (bc = 0;; bc++) { - if (list_empty(&q->active)) - break; - buf = list_entry(q->active.next, - struct cx23885_buffer, vb.queue); - - /* count comes from the hw and is is 16bit wide -- - * this trick handles wrap-arounds correctly for - * up to 32767 buffers in flight... */ - if ((s16) (count - buf->count) < 0) - break; - - do_gettimeofday(&buf->vb.ts); - dprintk(2, "[%p/%d] wakeup reg=%d buf=%d\n", buf, buf->vb.i, - count, buf->count); - buf->vb.state = VIDEOBUF_DONE; - list_del(&buf->vb.queue); - wake_up(&buf->vb.done); - } - if (list_empty(&q->active)) - del_timer(&q->timeout); - else - mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT); - if (bc != 1) - printk(KERN_WARNING "%s: %d buffers handled (should be 1)\n", - __func__, bc); -} - -int cx23885_sram_channel_setup(struct cx23885_dev *dev, - struct sram_channel *ch, - unsigned int bpl, u32 risc) -{ - unsigned int i, lines; - u32 cdt; - - if (ch->cmds_start == 0) { - dprintk(1, "%s() Erasing channel [%s]\n", __func__, - ch->name); - cx_write(ch->ptr1_reg, 0); - cx_write(ch->ptr2_reg, 0); - cx_write(ch->cnt2_reg, 0); - cx_write(ch->cnt1_reg, 0); - return 0; - } else { - dprintk(1, "%s() Configuring channel [%s]\n", __func__, - ch->name); - } - - bpl = (bpl + 7) & ~7; /* alignment */ - cdt = ch->cdt; - lines = ch->fifo_size / bpl; - if (lines > 6) - lines = 6; - BUG_ON(lines < 2); - - cx_write(8 + 0, RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC); - cx_write(8 + 4, 8); - cx_write(8 + 8, 0); - - /* write CDT */ - for (i = 0; i < lines; i++) { - dprintk(2, "%s() 0x%08x <- 0x%08x\n", __func__, cdt + 16*i, - ch->fifo_start + bpl*i); - cx_write(cdt + 16*i, ch->fifo_start + bpl*i); - cx_write(cdt + 16*i + 4, 0); - cx_write(cdt + 16*i + 8, 0); - cx_write(cdt + 16*i + 12, 0); - } - - /* write CMDS */ - if (ch->jumponly) - cx_write(ch->cmds_start + 0, 8); - else - cx_write(ch->cmds_start + 0, risc); - cx_write(ch->cmds_start + 4, 0); /* 64 bits 63-32 */ - cx_write(ch->cmds_start + 8, cdt); - cx_write(ch->cmds_start + 12, (lines*16) >> 3); - cx_write(ch->cmds_start + 16, ch->ctrl_start); - if (ch->jumponly) - cx_write(ch->cmds_start + 20, 0x80000000 | (64 >> 2)); - else - cx_write(ch->cmds_start + 20, 64 >> 2); - for (i = 24; i < 80; i += 4) - cx_write(ch->cmds_start + i, 0); - - /* fill registers */ - cx_write(ch->ptr1_reg, ch->fifo_start); - cx_write(ch->ptr2_reg, cdt); - cx_write(ch->cnt2_reg, (lines*16) >> 3); - cx_write(ch->cnt1_reg, (bpl >> 3) - 1); - - dprintk(2, "[bridge %d] sram setup %s: bpl=%d lines=%d\n", - dev->bridge, - ch->name, - bpl, - lines); - - return 0; -} - -void cx23885_sram_channel_dump(struct cx23885_dev *dev, - struct sram_channel *ch) -{ - static char *name[] = { - "init risc lo", - "init risc hi", - "cdt base", - "cdt size", - "iq base", - "iq size", - "risc pc lo", - "risc pc hi", - "iq wr ptr", - "iq rd ptr", - "cdt current", - "pci target lo", - "pci target hi", - "line / byte", - }; - u32 risc; - unsigned int i, j, n; - - printk(KERN_WARNING "%s: %s - dma channel status dump\n", - dev->name, ch->name); - for (i = 0; i < ARRAY_SIZE(name); i++) - printk(KERN_WARNING "%s: cmds: %-15s: 0x%08x\n", - dev->name, name[i], - cx_read(ch->cmds_start + 4*i)); - - for (i = 0; i < 4; i++) { - risc = cx_read(ch->cmds_start + 4 * (i + 14)); - printk(KERN_WARNING "%s: risc%d: ", dev->name, i); - cx23885_risc_decode(risc); - } - for (i = 0; i < (64 >> 2); i += n) { - risc = cx_read(ch->ctrl_start + 4 * i); - /* No consideration for bits 63-32 */ - - printk(KERN_WARNING "%s: (0x%08x) iq %x: ", dev->name, - ch->ctrl_start + 4 * i, i); - n = cx23885_risc_decode(risc); - for (j = 1; j < n; j++) { - risc = cx_read(ch->ctrl_start + 4 * (i + j)); - printk(KERN_WARNING "%s: iq %x: 0x%08x [ arg #%d ]\n", - dev->name, i+j, risc, j); - } - } - - printk(KERN_WARNING "%s: fifo: 0x%08x -> 0x%x\n", - dev->name, ch->fifo_start, ch->fifo_start+ch->fifo_size); - printk(KERN_WARNING "%s: ctrl: 0x%08x -> 0x%x\n", - dev->name, ch->ctrl_start, ch->ctrl_start + 6*16); - printk(KERN_WARNING "%s: ptr1_reg: 0x%08x\n", - dev->name, cx_read(ch->ptr1_reg)); - printk(KERN_WARNING "%s: ptr2_reg: 0x%08x\n", - dev->name, cx_read(ch->ptr2_reg)); - printk(KERN_WARNING "%s: cnt1_reg: 0x%08x\n", - dev->name, cx_read(ch->cnt1_reg)); - printk(KERN_WARNING "%s: cnt2_reg: 0x%08x\n", - dev->name, cx_read(ch->cnt2_reg)); -} - -static void cx23885_risc_disasm(struct cx23885_tsport *port, - struct btcx_riscmem *risc) -{ - struct cx23885_dev *dev = port->dev; - unsigned int i, j, n; - - printk(KERN_INFO "%s: risc disasm: %p [dma=0x%08lx]\n", - dev->name, risc->cpu, (unsigned long)risc->dma); - for (i = 0; i < (risc->size >> 2); i += n) { - printk(KERN_INFO "%s: %04d: ", dev->name, i); - n = cx23885_risc_decode(le32_to_cpu(risc->cpu[i])); - for (j = 1; j < n; j++) - printk(KERN_INFO "%s: %04d: 0x%08x [ arg #%d ]\n", - dev->name, i + j, risc->cpu[i + j], j); - if (risc->cpu[i] == cpu_to_le32(RISC_JUMP)) - break; - } -} - -static void cx23885_shutdown(struct cx23885_dev *dev) -{ - /* disable RISC controller */ - cx_write(DEV_CNTRL2, 0); - - /* Disable all IR activity */ - cx_write(IR_CNTRL_REG, 0); - - /* Disable Video A/B activity */ - cx_write(VID_A_DMA_CTL, 0); - cx_write(VID_B_DMA_CTL, 0); - cx_write(VID_C_DMA_CTL, 0); - - /* Disable Audio activity */ - cx_write(AUD_INT_DMA_CTL, 0); - cx_write(AUD_EXT_DMA_CTL, 0); - - /* Disable Serial port */ - cx_write(UART_CTL, 0); - - /* Disable Interrupts */ - cx23885_irq_disable_all(dev); - cx_write(VID_A_INT_MSK, 0); - cx_write(VID_B_INT_MSK, 0); - cx_write(VID_C_INT_MSK, 0); - cx_write(AUDIO_INT_INT_MSK, 0); - cx_write(AUDIO_EXT_INT_MSK, 0); - -} - -static void cx23885_reset(struct cx23885_dev *dev) -{ - dprintk(1, "%s()\n", __func__); - - cx23885_shutdown(dev); - - cx_write(PCI_INT_STAT, 0xffffffff); - cx_write(VID_A_INT_STAT, 0xffffffff); - cx_write(VID_B_INT_STAT, 0xffffffff); - cx_write(VID_C_INT_STAT, 0xffffffff); - cx_write(AUDIO_INT_INT_STAT, 0xffffffff); - cx_write(AUDIO_EXT_INT_STAT, 0xffffffff); - cx_write(CLK_DELAY, cx_read(CLK_DELAY) & 0x80000000); - cx_write(PAD_CTRL, 0x00500300); - - mdelay(100); - - cx23885_sram_channel_setup(dev, &dev->sram_channels[SRAM_CH01], - 720*4, 0); - cx23885_sram_channel_setup(dev, &dev->sram_channels[SRAM_CH02], 128, 0); - cx23885_sram_channel_setup(dev, &dev->sram_channels[SRAM_CH03], - 188*4, 0); - cx23885_sram_channel_setup(dev, &dev->sram_channels[SRAM_CH04], 128, 0); - cx23885_sram_channel_setup(dev, &dev->sram_channels[SRAM_CH05], 128, 0); - cx23885_sram_channel_setup(dev, &dev->sram_channels[SRAM_CH06], - 188*4, 0); - cx23885_sram_channel_setup(dev, &dev->sram_channels[SRAM_CH07], 128, 0); - cx23885_sram_channel_setup(dev, &dev->sram_channels[SRAM_CH08], 128, 0); - cx23885_sram_channel_setup(dev, &dev->sram_channels[SRAM_CH09], 128, 0); - - cx23885_gpio_setup(dev); -} - - -static int cx23885_pci_quirks(struct cx23885_dev *dev) -{ - dprintk(1, "%s()\n", __func__); - - /* The cx23885 bridge has a weird bug which causes NMI to be asserted - * when DMA begins if RDR_TLCTL0 bit4 is not cleared. It does not - * occur on the cx23887 bridge. - */ - if (dev->bridge == CX23885_BRIDGE_885) - cx_clear(RDR_TLCTL0, 1 << 4); - - return 0; -} - -static int get_resources(struct cx23885_dev *dev) -{ - if (request_mem_region(pci_resource_start(dev->pci, 0), - pci_resource_len(dev->pci, 0), - dev->name)) - return 0; - - printk(KERN_ERR "%s: can't get MMIO memory @ 0x%llx\n", - dev->name, (unsigned long long)pci_resource_start(dev->pci, 0)); - - return -EBUSY; -} - -static void cx23885_timeout(unsigned long data); -int cx23885_risc_stopper(struct pci_dev *pci, struct btcx_riscmem *risc, - u32 reg, u32 mask, u32 value); - -static int cx23885_init_tsport(struct cx23885_dev *dev, - struct cx23885_tsport *port, int portno) -{ - dprintk(1, "%s(portno=%d)\n", __func__, portno); - - /* Transport bus init dma queue - Common settings */ - port->dma_ctl_val = 0x11; /* Enable RISC controller and Fifo */ - port->ts_int_msk_val = 0x1111; /* TS port bits for RISC */ - port->vld_misc_val = 0x0; - port->hw_sop_ctrl_val = (0x47 << 16 | 188 << 4); - - spin_lock_init(&port->slock); - port->dev = dev; - port->nr = portno; - - INIT_LIST_HEAD(&port->mpegq.active); - INIT_LIST_HEAD(&port->mpegq.queued); - port->mpegq.timeout.function = cx23885_timeout; - port->mpegq.timeout.data = (unsigned long)port; - init_timer(&port->mpegq.timeout); - - mutex_init(&port->frontends.lock); - INIT_LIST_HEAD(&port->frontends.felist); - port->frontends.active_fe_id = 0; - - /* This should be hardcoded allow a single frontend - * attachment to this tsport, keeping the -dvb.c - * code clean and safe. - */ - if (!port->num_frontends) - port->num_frontends = 1; - - switch (portno) { - case 1: - port->reg_gpcnt = VID_B_GPCNT; - port->reg_gpcnt_ctl = VID_B_GPCNT_CTL; - port->reg_dma_ctl = VID_B_DMA_CTL; - port->reg_lngth = VID_B_LNGTH; - port->reg_hw_sop_ctrl = VID_B_HW_SOP_CTL; - port->reg_gen_ctrl = VID_B_GEN_CTL; - port->reg_bd_pkt_status = VID_B_BD_PKT_STATUS; - port->reg_sop_status = VID_B_SOP_STATUS; - port->reg_fifo_ovfl_stat = VID_B_FIFO_OVFL_STAT; - port->reg_vld_misc = VID_B_VLD_MISC; - port->reg_ts_clk_en = VID_B_TS_CLK_EN; - port->reg_src_sel = VID_B_SRC_SEL; - port->reg_ts_int_msk = VID_B_INT_MSK; - port->reg_ts_int_stat = VID_B_INT_STAT; - port->sram_chno = SRAM_CH03; /* VID_B */ - port->pci_irqmask = 0x02; /* VID_B bit1 */ - break; - case 2: - port->reg_gpcnt = VID_C_GPCNT; - port->reg_gpcnt_ctl = VID_C_GPCNT_CTL; - port->reg_dma_ctl = VID_C_DMA_CTL; - port->reg_lngth = VID_C_LNGTH; - port->reg_hw_sop_ctrl = VID_C_HW_SOP_CTL; - port->reg_gen_ctrl = VID_C_GEN_CTL; - port->reg_bd_pkt_status = VID_C_BD_PKT_STATUS; - port->reg_sop_status = VID_C_SOP_STATUS; - port->reg_fifo_ovfl_stat = VID_C_FIFO_OVFL_STAT; - port->reg_vld_misc = VID_C_VLD_MISC; - port->reg_ts_clk_en = VID_C_TS_CLK_EN; - port->reg_src_sel = 0; - port->reg_ts_int_msk = VID_C_INT_MSK; - port->reg_ts_int_stat = VID_C_INT_STAT; - port->sram_chno = SRAM_CH06; /* VID_C */ - port->pci_irqmask = 0x04; /* VID_C bit2 */ - break; - default: - BUG(); - } - - cx23885_risc_stopper(dev->pci, &port->mpegq.stopper, - port->reg_dma_ctl, port->dma_ctl_val, 0x00); - - return 0; -} - -static void cx23885_dev_checkrevision(struct cx23885_dev *dev) -{ - switch (cx_read(RDR_CFG2) & 0xff) { - case 0x00: - /* cx23885 */ - dev->hwrevision = 0xa0; - break; - case 0x01: - /* CX23885-12Z */ - dev->hwrevision = 0xa1; - break; - case 0x02: - /* CX23885-13Z/14Z */ - dev->hwrevision = 0xb0; - break; - case 0x03: - if (dev->pci->device == 0x8880) { - /* CX23888-21Z/22Z */ - dev->hwrevision = 0xc0; - } else { - /* CX23885-14Z */ - dev->hwrevision = 0xa4; - } - break; - case 0x04: - if (dev->pci->device == 0x8880) { - /* CX23888-31Z */ - dev->hwrevision = 0xd0; - } else { - /* CX23885-15Z, CX23888-31Z */ - dev->hwrevision = 0xa5; - } - break; - case 0x0e: - /* CX23887-15Z */ - dev->hwrevision = 0xc0; - break; - case 0x0f: - /* CX23887-14Z */ - dev->hwrevision = 0xb1; - break; - default: - printk(KERN_ERR "%s() New hardware revision found 0x%x\n", - __func__, dev->hwrevision); - } - if (dev->hwrevision) - printk(KERN_INFO "%s() Hardware revision = 0x%02x\n", - __func__, dev->hwrevision); - else - printk(KERN_ERR "%s() Hardware revision unknown 0x%x\n", - __func__, dev->hwrevision); -} - -/* Find the first v4l2_subdev member of the group id in hw */ -struct v4l2_subdev *cx23885_find_hw(struct cx23885_dev *dev, u32 hw) -{ - struct v4l2_subdev *result = NULL; - struct v4l2_subdev *sd; - - spin_lock(&dev->v4l2_dev.lock); - v4l2_device_for_each_subdev(sd, &dev->v4l2_dev) { - if (sd->grp_id == hw) { - result = sd; - break; - } - } - spin_unlock(&dev->v4l2_dev.lock); - return result; -} - -static int cx23885_dev_setup(struct cx23885_dev *dev) -{ - int i; - - spin_lock_init(&dev->pci_irqmask_lock); - - mutex_init(&dev->lock); - mutex_init(&dev->gpio_lock); - - atomic_inc(&dev->refcount); - - dev->nr = cx23885_devcount++; - sprintf(dev->name, "cx23885[%d]", dev->nr); - - /* Configure the internal memory */ - if (dev->pci->device == 0x8880) { - /* Could be 887 or 888, assume a default */ - dev->bridge = CX23885_BRIDGE_887; - /* Apply a sensible clock frequency for the PCIe bridge */ - dev->clk_freq = 25000000; - dev->sram_channels = cx23887_sram_channels; - } else - if (dev->pci->device == 0x8852) { - dev->bridge = CX23885_BRIDGE_885; - /* Apply a sensible clock frequency for the PCIe bridge */ - dev->clk_freq = 28000000; - dev->sram_channels = cx23885_sram_channels; - } else - BUG(); - - dprintk(1, "%s() Memory configured for PCIe bridge type %d\n", - __func__, dev->bridge); - - /* board config */ - dev->board = UNSET; - if (card[dev->nr] < cx23885_bcount) - dev->board = card[dev->nr]; - for (i = 0; UNSET == dev->board && i < cx23885_idcount; i++) - if (dev->pci->subsystem_vendor == cx23885_subids[i].subvendor && - dev->pci->subsystem_device == cx23885_subids[i].subdevice) - dev->board = cx23885_subids[i].card; - if (UNSET == dev->board) { - dev->board = CX23885_BOARD_UNKNOWN; - cx23885_card_list(dev); - } - - /* If the user specific a clk freq override, apply it */ - if (cx23885_boards[dev->board].clk_freq > 0) - dev->clk_freq = cx23885_boards[dev->board].clk_freq; - - dev->pci_bus = dev->pci->bus->number; - dev->pci_slot = PCI_SLOT(dev->pci->devfn); - cx23885_irq_add(dev, 0x001f00); - - /* External Master 1 Bus */ - dev->i2c_bus[0].nr = 0; - dev->i2c_bus[0].dev = dev; - dev->i2c_bus[0].reg_stat = I2C1_STAT; - dev->i2c_bus[0].reg_ctrl = I2C1_CTRL; - dev->i2c_bus[0].reg_addr = I2C1_ADDR; - dev->i2c_bus[0].reg_rdata = I2C1_RDATA; - dev->i2c_bus[0].reg_wdata = I2C1_WDATA; - dev->i2c_bus[0].i2c_period = (0x9d << 24); /* 100kHz */ - - /* External Master 2 Bus */ - dev->i2c_bus[1].nr = 1; - dev->i2c_bus[1].dev = dev; - dev->i2c_bus[1].reg_stat = I2C2_STAT; - dev->i2c_bus[1].reg_ctrl = I2C2_CTRL; - dev->i2c_bus[1].reg_addr = I2C2_ADDR; - dev->i2c_bus[1].reg_rdata = I2C2_RDATA; - dev->i2c_bus[1].reg_wdata = I2C2_WDATA; - dev->i2c_bus[1].i2c_period = (0x9d << 24); /* 100kHz */ - - /* Internal Master 3 Bus */ - dev->i2c_bus[2].nr = 2; - dev->i2c_bus[2].dev = dev; - dev->i2c_bus[2].reg_stat = I2C3_STAT; - dev->i2c_bus[2].reg_ctrl = I2C3_CTRL; - dev->i2c_bus[2].reg_addr = I2C3_ADDR; - dev->i2c_bus[2].reg_rdata = I2C3_RDATA; - dev->i2c_bus[2].reg_wdata = I2C3_WDATA; - dev->i2c_bus[2].i2c_period = (0x07 << 24); /* 1.95MHz */ - - if ((cx23885_boards[dev->board].portb == CX23885_MPEG_DVB) || - (cx23885_boards[dev->board].portb == CX23885_MPEG_ENCODER)) - cx23885_init_tsport(dev, &dev->ts1, 1); - - if ((cx23885_boards[dev->board].portc == CX23885_MPEG_DVB) || - (cx23885_boards[dev->board].portc == CX23885_MPEG_ENCODER)) - cx23885_init_tsport(dev, &dev->ts2, 2); - - if (get_resources(dev) < 0) { - printk(KERN_ERR "CORE %s No more PCIe resources for " - "subsystem: %04x:%04x\n", - dev->name, dev->pci->subsystem_vendor, - dev->pci->subsystem_device); - - cx23885_devcount--; - return -ENODEV; - } - - /* PCIe stuff */ - dev->lmmio = ioremap(pci_resource_start(dev->pci, 0), - pci_resource_len(dev->pci, 0)); - - dev->bmmio = (u8 __iomem *)dev->lmmio; - - printk(KERN_INFO "CORE %s: subsystem: %04x:%04x, board: %s [card=%d,%s]\n", - dev->name, dev->pci->subsystem_vendor, - dev->pci->subsystem_device, cx23885_boards[dev->board].name, - dev->board, card[dev->nr] == dev->board ? - "insmod option" : "autodetected"); - - cx23885_pci_quirks(dev); - - /* Assume some sensible defaults */ - dev->tuner_type = cx23885_boards[dev->board].tuner_type; - dev->tuner_addr = cx23885_boards[dev->board].tuner_addr; - dev->tuner_bus = cx23885_boards[dev->board].tuner_bus; - dev->radio_type = cx23885_boards[dev->board].radio_type; - dev->radio_addr = cx23885_boards[dev->board].radio_addr; - - dprintk(1, "%s() tuner_type = 0x%x tuner_addr = 0x%x tuner_bus = %d\n", - __func__, dev->tuner_type, dev->tuner_addr, dev->tuner_bus); - dprintk(1, "%s() radio_type = 0x%x radio_addr = 0x%x\n", - __func__, dev->radio_type, dev->radio_addr); - - /* The cx23417 encoder has GPIO's that need to be initialised - * before DVB, so that demodulators and tuners are out of - * reset before DVB uses them. - */ - if ((cx23885_boards[dev->board].portb == CX23885_MPEG_ENCODER) || - (cx23885_boards[dev->board].portc == CX23885_MPEG_ENCODER)) - cx23885_mc417_init(dev); - - /* init hardware */ - cx23885_reset(dev); - - cx23885_i2c_register(&dev->i2c_bus[0]); - cx23885_i2c_register(&dev->i2c_bus[1]); - cx23885_i2c_register(&dev->i2c_bus[2]); - cx23885_card_setup(dev); - call_all(dev, core, s_power, 0); - cx23885_ir_init(dev); - - if (cx23885_boards[dev->board].porta == CX23885_ANALOG_VIDEO) { - if (cx23885_video_register(dev) < 0) { - printk(KERN_ERR "%s() Failed to register analog " - "video adapters on VID_A\n", __func__); - } - } - - if (cx23885_boards[dev->board].portb == CX23885_MPEG_DVB) { - if (cx23885_boards[dev->board].num_fds_portb) - dev->ts1.num_frontends = - cx23885_boards[dev->board].num_fds_portb; - if (cx23885_dvb_register(&dev->ts1) < 0) { - printk(KERN_ERR "%s() Failed to register dvb adapters on VID_B\n", - __func__); - } - } else - if (cx23885_boards[dev->board].portb == CX23885_MPEG_ENCODER) { - if (cx23885_417_register(dev) < 0) { - printk(KERN_ERR - "%s() Failed to register 417 on VID_B\n", - __func__); - } - } - - if (cx23885_boards[dev->board].portc == CX23885_MPEG_DVB) { - if (cx23885_boards[dev->board].num_fds_portc) - dev->ts2.num_frontends = - cx23885_boards[dev->board].num_fds_portc; - if (cx23885_dvb_register(&dev->ts2) < 0) { - printk(KERN_ERR - "%s() Failed to register dvb on VID_C\n", - __func__); - } - } else - if (cx23885_boards[dev->board].portc == CX23885_MPEG_ENCODER) { - if (cx23885_417_register(dev) < 0) { - printk(KERN_ERR - "%s() Failed to register 417 on VID_C\n", - __func__); - } - } - - cx23885_dev_checkrevision(dev); - - /* disable MSI for NetUP cards, otherwise CI is not working */ - if (cx23885_boards[dev->board].ci_type > 0) - cx_clear(RDR_RDRCTL1, 1 << 8); - - switch (dev->board) { - case CX23885_BOARD_TEVII_S470: - case CX23885_BOARD_TEVII_S471: - cx_clear(RDR_RDRCTL1, 1 << 8); - break; - } - - return 0; -} - -static void cx23885_dev_unregister(struct cx23885_dev *dev) -{ - release_mem_region(pci_resource_start(dev->pci, 0), - pci_resource_len(dev->pci, 0)); - - if (!atomic_dec_and_test(&dev->refcount)) - return; - - if (cx23885_boards[dev->board].porta == CX23885_ANALOG_VIDEO) - cx23885_video_unregister(dev); - - if (cx23885_boards[dev->board].portb == CX23885_MPEG_DVB) - cx23885_dvb_unregister(&dev->ts1); - - if (cx23885_boards[dev->board].portb == CX23885_MPEG_ENCODER) - cx23885_417_unregister(dev); - - if (cx23885_boards[dev->board].portc == CX23885_MPEG_DVB) - cx23885_dvb_unregister(&dev->ts2); - - if (cx23885_boards[dev->board].portc == CX23885_MPEG_ENCODER) - cx23885_417_unregister(dev); - - cx23885_i2c_unregister(&dev->i2c_bus[2]); - cx23885_i2c_unregister(&dev->i2c_bus[1]); - cx23885_i2c_unregister(&dev->i2c_bus[0]); - - iounmap(dev->lmmio); -} - -static __le32 *cx23885_risc_field(__le32 *rp, struct scatterlist *sglist, - unsigned int offset, u32 sync_line, - unsigned int bpl, unsigned int padding, - unsigned int lines, unsigned int lpi) -{ - struct scatterlist *sg; - unsigned int line, todo, sol; - - /* sync instruction */ - if (sync_line != NO_SYNC_LINE) - *(rp++) = cpu_to_le32(RISC_RESYNC | sync_line); - - /* scan lines */ - sg = sglist; - for (line = 0; line < lines; line++) { - while (offset && offset >= sg_dma_len(sg)) { - offset -= sg_dma_len(sg); - sg++; - } - - if (lpi && line > 0 && !(line % lpi)) - sol = RISC_SOL | RISC_IRQ1 | RISC_CNT_INC; - else - sol = RISC_SOL; - - if (bpl <= sg_dma_len(sg)-offset) { - /* fits into current chunk */ - *(rp++) = cpu_to_le32(RISC_WRITE|sol|RISC_EOL|bpl); - *(rp++) = cpu_to_le32(sg_dma_address(sg)+offset); - *(rp++) = cpu_to_le32(0); /* bits 63-32 */ - offset += bpl; - } else { - /* scanline needs to be split */ - todo = bpl; - *(rp++) = cpu_to_le32(RISC_WRITE|sol| - (sg_dma_len(sg)-offset)); - *(rp++) = cpu_to_le32(sg_dma_address(sg)+offset); - *(rp++) = cpu_to_le32(0); /* bits 63-32 */ - todo -= (sg_dma_len(sg)-offset); - offset = 0; - sg++; - while (todo > sg_dma_len(sg)) { - *(rp++) = cpu_to_le32(RISC_WRITE| - sg_dma_len(sg)); - *(rp++) = cpu_to_le32(sg_dma_address(sg)); - *(rp++) = cpu_to_le32(0); /* bits 63-32 */ - todo -= sg_dma_len(sg); - sg++; - } - *(rp++) = cpu_to_le32(RISC_WRITE|RISC_EOL|todo); - *(rp++) = cpu_to_le32(sg_dma_address(sg)); - *(rp++) = cpu_to_le32(0); /* bits 63-32 */ - offset += todo; - } - offset += padding; - } - - return rp; -} - -int cx23885_risc_buffer(struct pci_dev *pci, struct btcx_riscmem *risc, - struct scatterlist *sglist, unsigned int top_offset, - unsigned int bottom_offset, unsigned int bpl, - unsigned int padding, unsigned int lines) -{ - u32 instructions, fields; - __le32 *rp; - int rc; - - fields = 0; - if (UNSET != top_offset) - fields++; - if (UNSET != bottom_offset) - fields++; - - /* estimate risc mem: worst case is one write per page border + - one write per scan line + syncs + jump (all 2 dwords). Padding - can cause next bpl to start close to a page border. First DMA - region may be smaller than PAGE_SIZE */ - /* write and jump need and extra dword */ - instructions = fields * (1 + ((bpl + padding) * lines) - / PAGE_SIZE + lines); - instructions += 2; - rc = btcx_riscmem_alloc(pci, risc, instructions*12); - if (rc < 0) - return rc; - - /* write risc instructions */ - rp = risc->cpu; - if (UNSET != top_offset) - rp = cx23885_risc_field(rp, sglist, top_offset, 0, - bpl, padding, lines, 0); - if (UNSET != bottom_offset) - rp = cx23885_risc_field(rp, sglist, bottom_offset, 0x200, - bpl, padding, lines, 0); - - /* save pointer to jmp instruction address */ - risc->jmp = rp; - BUG_ON((risc->jmp - risc->cpu + 2) * sizeof(*risc->cpu) > risc->size); - return 0; -} - -int cx23885_risc_databuffer(struct pci_dev *pci, - struct btcx_riscmem *risc, - struct scatterlist *sglist, - unsigned int bpl, - unsigned int lines, unsigned int lpi) -{ - u32 instructions; - __le32 *rp; - int rc; - - /* estimate risc mem: worst case is one write per page border + - one write per scan line + syncs + jump (all 2 dwords). Here - there is no padding and no sync. First DMA region may be smaller - than PAGE_SIZE */ - /* Jump and write need an extra dword */ - instructions = 1 + (bpl * lines) / PAGE_SIZE + lines; - instructions += 1; - - rc = btcx_riscmem_alloc(pci, risc, instructions*12); - if (rc < 0) - return rc; - - /* write risc instructions */ - rp = risc->cpu; - rp = cx23885_risc_field(rp, sglist, 0, NO_SYNC_LINE, - bpl, 0, lines, lpi); - - /* save pointer to jmp instruction address */ - risc->jmp = rp; - BUG_ON((risc->jmp - risc->cpu + 2) * sizeof(*risc->cpu) > risc->size); - return 0; -} - -int cx23885_risc_vbibuffer(struct pci_dev *pci, struct btcx_riscmem *risc, - struct scatterlist *sglist, unsigned int top_offset, - unsigned int bottom_offset, unsigned int bpl, - unsigned int padding, unsigned int lines) -{ - u32 instructions, fields; - __le32 *rp; - int rc; - - fields = 0; - if (UNSET != top_offset) - fields++; - if (UNSET != bottom_offset) - fields++; - - /* estimate risc mem: worst case is one write per page border + - one write per scan line + syncs + jump (all 2 dwords). Padding - can cause next bpl to start close to a page border. First DMA - region may be smaller than PAGE_SIZE */ - /* write and jump need and extra dword */ - instructions = fields * (1 + ((bpl + padding) * lines) - / PAGE_SIZE + lines); - instructions += 2; - rc = btcx_riscmem_alloc(pci, risc, instructions*12); - if (rc < 0) - return rc; - /* write risc instructions */ - rp = risc->cpu; - - /* Sync to line 6, so US CC line 21 will appear in line '12' - * in the userland vbi payload */ - if (UNSET != top_offset) - rp = cx23885_risc_field(rp, sglist, top_offset, 6, - bpl, padding, lines, 0); - - if (UNSET != bottom_offset) - rp = cx23885_risc_field(rp, sglist, bottom_offset, 0x207, - bpl, padding, lines, 0); - - - - /* save pointer to jmp instruction address */ - risc->jmp = rp; - BUG_ON((risc->jmp - risc->cpu + 2) * sizeof(*risc->cpu) > risc->size); - return 0; -} - - -int cx23885_risc_stopper(struct pci_dev *pci, struct btcx_riscmem *risc, - u32 reg, u32 mask, u32 value) -{ - __le32 *rp; - int rc; - - rc = btcx_riscmem_alloc(pci, risc, 4*16); - if (rc < 0) - return rc; - - /* write risc instructions */ - rp = risc->cpu; - *(rp++) = cpu_to_le32(RISC_WRITECR | RISC_IRQ2); - *(rp++) = cpu_to_le32(reg); - *(rp++) = cpu_to_le32(value); - *(rp++) = cpu_to_le32(mask); - *(rp++) = cpu_to_le32(RISC_JUMP); - *(rp++) = cpu_to_le32(risc->dma); - *(rp++) = cpu_to_le32(0); /* bits 63-32 */ - return 0; -} - -void cx23885_free_buffer(struct videobuf_queue *q, struct cx23885_buffer *buf) -{ - struct videobuf_dmabuf *dma = videobuf_to_dma(&buf->vb); - - BUG_ON(in_interrupt()); - videobuf_waiton(q, &buf->vb, 0, 0); - videobuf_dma_unmap(q->dev, dma); - videobuf_dma_free(dma); - btcx_riscmem_free(to_pci_dev(q->dev), &buf->risc); - buf->vb.state = VIDEOBUF_NEEDS_INIT; -} - -static void cx23885_tsport_reg_dump(struct cx23885_tsport *port) -{ - struct cx23885_dev *dev = port->dev; - - dprintk(1, "%s() Register Dump\n", __func__); - dprintk(1, "%s() DEV_CNTRL2 0x%08X\n", __func__, - cx_read(DEV_CNTRL2)); - dprintk(1, "%s() PCI_INT_MSK 0x%08X\n", __func__, - cx23885_irq_get_mask(dev)); - dprintk(1, "%s() AUD_INT_INT_MSK 0x%08X\n", __func__, - cx_read(AUDIO_INT_INT_MSK)); - dprintk(1, "%s() AUD_INT_DMA_CTL 0x%08X\n", __func__, - cx_read(AUD_INT_DMA_CTL)); - dprintk(1, "%s() AUD_EXT_INT_MSK 0x%08X\n", __func__, - cx_read(AUDIO_EXT_INT_MSK)); - dprintk(1, "%s() AUD_EXT_DMA_CTL 0x%08X\n", __func__, - cx_read(AUD_EXT_DMA_CTL)); - dprintk(1, "%s() PAD_CTRL 0x%08X\n", __func__, - cx_read(PAD_CTRL)); - dprintk(1, "%s() ALT_PIN_OUT_SEL 0x%08X\n", __func__, - cx_read(ALT_PIN_OUT_SEL)); - dprintk(1, "%s() GPIO2 0x%08X\n", __func__, - cx_read(GPIO2)); - dprintk(1, "%s() gpcnt(0x%08X) 0x%08X\n", __func__, - port->reg_gpcnt, cx_read(port->reg_gpcnt)); - dprintk(1, "%s() gpcnt_ctl(0x%08X) 0x%08x\n", __func__, - port->reg_gpcnt_ctl, cx_read(port->reg_gpcnt_ctl)); - dprintk(1, "%s() dma_ctl(0x%08X) 0x%08x\n", __func__, - port->reg_dma_ctl, cx_read(port->reg_dma_ctl)); - if (port->reg_src_sel) - dprintk(1, "%s() src_sel(0x%08X) 0x%08x\n", __func__, - port->reg_src_sel, cx_read(port->reg_src_sel)); - dprintk(1, "%s() lngth(0x%08X) 0x%08x\n", __func__, - port->reg_lngth, cx_read(port->reg_lngth)); - dprintk(1, "%s() hw_sop_ctrl(0x%08X) 0x%08x\n", __func__, - port->reg_hw_sop_ctrl, cx_read(port->reg_hw_sop_ctrl)); - dprintk(1, "%s() gen_ctrl(0x%08X) 0x%08x\n", __func__, - port->reg_gen_ctrl, cx_read(port->reg_gen_ctrl)); - dprintk(1, "%s() bd_pkt_status(0x%08X) 0x%08x\n", __func__, - port->reg_bd_pkt_status, cx_read(port->reg_bd_pkt_status)); - dprintk(1, "%s() sop_status(0x%08X) 0x%08x\n", __func__, - port->reg_sop_status, cx_read(port->reg_sop_status)); - dprintk(1, "%s() fifo_ovfl_stat(0x%08X) 0x%08x\n", __func__, - port->reg_fifo_ovfl_stat, cx_read(port->reg_fifo_ovfl_stat)); - dprintk(1, "%s() vld_misc(0x%08X) 0x%08x\n", __func__, - port->reg_vld_misc, cx_read(port->reg_vld_misc)); - dprintk(1, "%s() ts_clk_en(0x%08X) 0x%08x\n", __func__, - port->reg_ts_clk_en, cx_read(port->reg_ts_clk_en)); - dprintk(1, "%s() ts_int_msk(0x%08X) 0x%08x\n", __func__, - port->reg_ts_int_msk, cx_read(port->reg_ts_int_msk)); -} - -static int cx23885_start_dma(struct cx23885_tsport *port, - struct cx23885_dmaqueue *q, - struct cx23885_buffer *buf) -{ - struct cx23885_dev *dev = port->dev; - u32 reg; - - dprintk(1, "%s() w: %d, h: %d, f: %d\n", __func__, - buf->vb.width, buf->vb.height, buf->vb.field); - - /* Stop the fifo and risc engine for this port */ - cx_clear(port->reg_dma_ctl, port->dma_ctl_val); - - /* setup fifo + format */ - cx23885_sram_channel_setup(dev, - &dev->sram_channels[port->sram_chno], - port->ts_packet_size, buf->risc.dma); - if (debug > 5) { - cx23885_sram_channel_dump(dev, - &dev->sram_channels[port->sram_chno]); - cx23885_risc_disasm(port, &buf->risc); - } - - /* write TS length to chip */ - cx_write(port->reg_lngth, buf->vb.width); - - if ((!(cx23885_boards[dev->board].portb & CX23885_MPEG_DVB)) && - (!(cx23885_boards[dev->board].portc & CX23885_MPEG_DVB))) { - printk("%s() Unsupported .portb/c (0x%08x)/(0x%08x)\n", - __func__, - cx23885_boards[dev->board].portb, - cx23885_boards[dev->board].portc); - return -EINVAL; - } - - if (cx23885_boards[dev->board].portb == CX23885_MPEG_ENCODER) - cx23885_av_clk(dev, 0); - - udelay(100); - - /* If the port supports SRC SELECT, configure it */ - if (port->reg_src_sel) - cx_write(port->reg_src_sel, port->src_sel_val); - - cx_write(port->reg_hw_sop_ctrl, port->hw_sop_ctrl_val); - cx_write(port->reg_ts_clk_en, port->ts_clk_en_val); - cx_write(port->reg_vld_misc, port->vld_misc_val); - cx_write(port->reg_gen_ctrl, port->gen_ctrl_val); - udelay(100); - - /* NOTE: this is 2 (reserved) for portb, does it matter? */ - /* reset counter to zero */ - cx_write(port->reg_gpcnt_ctl, 3); - q->count = 1; - - /* Set VIDB pins to input */ - if (cx23885_boards[dev->board].portb == CX23885_MPEG_DVB) { - reg = cx_read(PAD_CTRL); - reg &= ~0x3; /* Clear TS1_OE & TS1_SOP_OE */ - cx_write(PAD_CTRL, reg); - } - - /* Set VIDC pins to input */ - if (cx23885_boards[dev->board].portc == CX23885_MPEG_DVB) { - reg = cx_read(PAD_CTRL); - reg &= ~0x4; /* Clear TS2_SOP_OE */ - cx_write(PAD_CTRL, reg); - } - - if (cx23885_boards[dev->board].portb == CX23885_MPEG_ENCODER) { - - reg = cx_read(PAD_CTRL); - reg = reg & ~0x1; /* Clear TS1_OE */ - - /* FIXME, bit 2 writing here is questionable */ - /* set TS1_SOP_OE and TS1_OE_HI */ - reg = reg | 0xa; - cx_write(PAD_CTRL, reg); - - /* FIXME and these two registers should be documented. */ - cx_write(CLK_DELAY, cx_read(CLK_DELAY) | 0x80000011); - cx_write(ALT_PIN_OUT_SEL, 0x10100045); - } - - switch (dev->bridge) { - case CX23885_BRIDGE_885: - case CX23885_BRIDGE_887: - case CX23885_BRIDGE_888: - /* enable irqs */ - dprintk(1, "%s() enabling TS int's and DMA\n", __func__); - cx_set(port->reg_ts_int_msk, port->ts_int_msk_val); - cx_set(port->reg_dma_ctl, port->dma_ctl_val); - cx23885_irq_add(dev, port->pci_irqmask); - cx23885_irq_enable_all(dev); - break; - default: - BUG(); - } - - cx_set(DEV_CNTRL2, (1<<5)); /* Enable RISC controller */ - - if (cx23885_boards[dev->board].portb == CX23885_MPEG_ENCODER) - cx23885_av_clk(dev, 1); - - if (debug > 4) - cx23885_tsport_reg_dump(port); - - return 0; -} - -static int cx23885_stop_dma(struct cx23885_tsport *port) -{ - struct cx23885_dev *dev = port->dev; - u32 reg; - - dprintk(1, "%s()\n", __func__); - - /* Stop interrupts and DMA */ - cx_clear(port->reg_ts_int_msk, port->ts_int_msk_val); - cx_clear(port->reg_dma_ctl, port->dma_ctl_val); - - if (cx23885_boards[dev->board].portb == CX23885_MPEG_ENCODER) { - - reg = cx_read(PAD_CTRL); - - /* Set TS1_OE */ - reg = reg | 0x1; - - /* clear TS1_SOP_OE and TS1_OE_HI */ - reg = reg & ~0xa; - cx_write(PAD_CTRL, reg); - cx_write(port->reg_src_sel, 0); - cx_write(port->reg_gen_ctrl, 8); - - } - - if (cx23885_boards[dev->board].portb == CX23885_MPEG_ENCODER) - cx23885_av_clk(dev, 0); - - return 0; -} - -int cx23885_restart_queue(struct cx23885_tsport *port, - struct cx23885_dmaqueue *q) -{ - struct cx23885_dev *dev = port->dev; - struct cx23885_buffer *buf; - - dprintk(5, "%s()\n", __func__); - if (list_empty(&q->active)) { - struct cx23885_buffer *prev; - prev = NULL; - - dprintk(5, "%s() queue is empty\n", __func__); - - for (;;) { - if (list_empty(&q->queued)) - return 0; - buf = list_entry(q->queued.next, struct cx23885_buffer, - vb.queue); - if (NULL == prev) { - list_del(&buf->vb.queue); - list_add_tail(&buf->vb.queue, &q->active); - cx23885_start_dma(port, q, buf); - buf->vb.state = VIDEOBUF_ACTIVE; - buf->count = q->count++; - mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT); - dprintk(5, "[%p/%d] restart_queue - f/active\n", - buf, buf->vb.i); - - } else if (prev->vb.width == buf->vb.width && - prev->vb.height == buf->vb.height && - prev->fmt == buf->fmt) { - list_del(&buf->vb.queue); - list_add_tail(&buf->vb.queue, &q->active); - buf->vb.state = VIDEOBUF_ACTIVE; - buf->count = q->count++; - prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma); - /* 64 bit bits 63-32 */ - prev->risc.jmp[2] = cpu_to_le32(0); - dprintk(5, "[%p/%d] restart_queue - m/active\n", - buf, buf->vb.i); - } else { - return 0; - } - prev = buf; - } - return 0; - } - - buf = list_entry(q->active.next, struct cx23885_buffer, vb.queue); - dprintk(2, "restart_queue [%p/%d]: restart dma\n", - buf, buf->vb.i); - cx23885_start_dma(port, q, buf); - list_for_each_entry(buf, &q->active, vb.queue) - buf->count = q->count++; - mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT); - return 0; -} - -/* ------------------------------------------------------------------ */ - -int cx23885_buf_prepare(struct videobuf_queue *q, struct cx23885_tsport *port, - struct cx23885_buffer *buf, enum v4l2_field field) -{ - struct cx23885_dev *dev = port->dev; - int size = port->ts_packet_size * port->ts_packet_count; - int rc; - - dprintk(1, "%s: %p\n", __func__, buf); - if (0 != buf->vb.baddr && buf->vb.bsize < size) - return -EINVAL; - - if (VIDEOBUF_NEEDS_INIT == buf->vb.state) { - buf->vb.width = port->ts_packet_size; - buf->vb.height = port->ts_packet_count; - buf->vb.size = size; - buf->vb.field = field /*V4L2_FIELD_TOP*/; - - rc = videobuf_iolock(q, &buf->vb, NULL); - if (0 != rc) - goto fail; - cx23885_risc_databuffer(dev->pci, &buf->risc, - videobuf_to_dma(&buf->vb)->sglist, - buf->vb.width, buf->vb.height, 0); - } - buf->vb.state = VIDEOBUF_PREPARED; - return 0; - - fail: - cx23885_free_buffer(q, buf); - return rc; -} - -void cx23885_buf_queue(struct cx23885_tsport *port, struct cx23885_buffer *buf) -{ - struct cx23885_buffer *prev; - struct cx23885_dev *dev = port->dev; - struct cx23885_dmaqueue *cx88q = &port->mpegq; - - /* add jump to stopper */ - buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC); - buf->risc.jmp[1] = cpu_to_le32(cx88q->stopper.dma); - buf->risc.jmp[2] = cpu_to_le32(0); /* bits 63-32 */ - - if (list_empty(&cx88q->active)) { - dprintk(1, "queue is empty - first active\n"); - list_add_tail(&buf->vb.queue, &cx88q->active); - cx23885_start_dma(port, cx88q, buf); - buf->vb.state = VIDEOBUF_ACTIVE; - buf->count = cx88q->count++; - mod_timer(&cx88q->timeout, jiffies + BUFFER_TIMEOUT); - dprintk(1, "[%p/%d] %s - first active\n", - buf, buf->vb.i, __func__); - } else { - dprintk(1, "queue is not empty - append to active\n"); - prev = list_entry(cx88q->active.prev, struct cx23885_buffer, - vb.queue); - list_add_tail(&buf->vb.queue, &cx88q->active); - buf->vb.state = VIDEOBUF_ACTIVE; - buf->count = cx88q->count++; - prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma); - prev->risc.jmp[2] = cpu_to_le32(0); /* 64 bit bits 63-32 */ - dprintk(1, "[%p/%d] %s - append to active\n", - buf, buf->vb.i, __func__); - } -} - -/* ----------------------------------------------------------- */ - -static void do_cancel_buffers(struct cx23885_tsport *port, char *reason, - int restart) -{ - struct cx23885_dev *dev = port->dev; - struct cx23885_dmaqueue *q = &port->mpegq; - struct cx23885_buffer *buf; - unsigned long flags; - - spin_lock_irqsave(&port->slock, flags); - while (!list_empty(&q->active)) { - buf = list_entry(q->active.next, struct cx23885_buffer, - vb.queue); - list_del(&buf->vb.queue); - buf->vb.state = VIDEOBUF_ERROR; - wake_up(&buf->vb.done); - dprintk(1, "[%p/%d] %s - dma=0x%08lx\n", - buf, buf->vb.i, reason, (unsigned long)buf->risc.dma); - } - if (restart) { - dprintk(1, "restarting queue\n"); - cx23885_restart_queue(port, q); - } - spin_unlock_irqrestore(&port->slock, flags); -} - -void cx23885_cancel_buffers(struct cx23885_tsport *port) -{ - struct cx23885_dev *dev = port->dev; - struct cx23885_dmaqueue *q = &port->mpegq; - - dprintk(1, "%s()\n", __func__); - del_timer_sync(&q->timeout); - cx23885_stop_dma(port); - do_cancel_buffers(port, "cancel", 0); -} - -static void cx23885_timeout(unsigned long data) -{ - struct cx23885_tsport *port = (struct cx23885_tsport *)data; - struct cx23885_dev *dev = port->dev; - - dprintk(1, "%s()\n", __func__); - - if (debug > 5) - cx23885_sram_channel_dump(dev, - &dev->sram_channels[port->sram_chno]); - - cx23885_stop_dma(port); - do_cancel_buffers(port, "timeout", 1); -} - -int cx23885_irq_417(struct cx23885_dev *dev, u32 status) -{ - /* FIXME: port1 assumption here. */ - struct cx23885_tsport *port = &dev->ts1; - int count = 0; - int handled = 0; - - if (status == 0) - return handled; - - count = cx_read(port->reg_gpcnt); - dprintk(7, "status: 0x%08x mask: 0x%08x count: 0x%x\n", - status, cx_read(port->reg_ts_int_msk), count); - - if ((status & VID_B_MSK_BAD_PKT) || - (status & VID_B_MSK_OPC_ERR) || - (status & VID_B_MSK_VBI_OPC_ERR) || - (status & VID_B_MSK_SYNC) || - (status & VID_B_MSK_VBI_SYNC) || - (status & VID_B_MSK_OF) || - (status & VID_B_MSK_VBI_OF)) { - printk(KERN_ERR "%s: V4L mpeg risc op code error, status " - "= 0x%x\n", dev->name, status); - if (status & VID_B_MSK_BAD_PKT) - dprintk(1, " VID_B_MSK_BAD_PKT\n"); - if (status & VID_B_MSK_OPC_ERR) - dprintk(1, " VID_B_MSK_OPC_ERR\n"); - if (status & VID_B_MSK_VBI_OPC_ERR) - dprintk(1, " VID_B_MSK_VBI_OPC_ERR\n"); - if (status & VID_B_MSK_SYNC) - dprintk(1, " VID_B_MSK_SYNC\n"); - if (status & VID_B_MSK_VBI_SYNC) - dprintk(1, " VID_B_MSK_VBI_SYNC\n"); - if (status & VID_B_MSK_OF) - dprintk(1, " VID_B_MSK_OF\n"); - if (status & VID_B_MSK_VBI_OF) - dprintk(1, " VID_B_MSK_VBI_OF\n"); - - cx_clear(port->reg_dma_ctl, port->dma_ctl_val); - cx23885_sram_channel_dump(dev, - &dev->sram_channels[port->sram_chno]); - cx23885_417_check_encoder(dev); - } else if (status & VID_B_MSK_RISCI1) { - dprintk(7, " VID_B_MSK_RISCI1\n"); - spin_lock(&port->slock); - cx23885_wakeup(port, &port->mpegq, count); - spin_unlock(&port->slock); - } else if (status & VID_B_MSK_RISCI2) { - dprintk(7, " VID_B_MSK_RISCI2\n"); - spin_lock(&port->slock); - cx23885_restart_queue(port, &port->mpegq); - spin_unlock(&port->slock); - } - if (status) { - cx_write(port->reg_ts_int_stat, status); - handled = 1; - } - - return handled; -} - -static int cx23885_irq_ts(struct cx23885_tsport *port, u32 status) -{ - struct cx23885_dev *dev = port->dev; - int handled = 0; - u32 count; - - if ((status & VID_BC_MSK_OPC_ERR) || - (status & VID_BC_MSK_BAD_PKT) || - (status & VID_BC_MSK_SYNC) || - (status & VID_BC_MSK_OF)) { - - if (status & VID_BC_MSK_OPC_ERR) - dprintk(7, " (VID_BC_MSK_OPC_ERR 0x%08x)\n", - VID_BC_MSK_OPC_ERR); - - if (status & VID_BC_MSK_BAD_PKT) - dprintk(7, " (VID_BC_MSK_BAD_PKT 0x%08x)\n", - VID_BC_MSK_BAD_PKT); - - if (status & VID_BC_MSK_SYNC) - dprintk(7, " (VID_BC_MSK_SYNC 0x%08x)\n", - VID_BC_MSK_SYNC); - - if (status & VID_BC_MSK_OF) - dprintk(7, " (VID_BC_MSK_OF 0x%08x)\n", - VID_BC_MSK_OF); - - printk(KERN_ERR "%s: mpeg risc op code error\n", dev->name); - - cx_clear(port->reg_dma_ctl, port->dma_ctl_val); - cx23885_sram_channel_dump(dev, - &dev->sram_channels[port->sram_chno]); - - } else if (status & VID_BC_MSK_RISCI1) { - - dprintk(7, " (RISCI1 0x%08x)\n", VID_BC_MSK_RISCI1); - - spin_lock(&port->slock); - count = cx_read(port->reg_gpcnt); - cx23885_wakeup(port, &port->mpegq, count); - spin_unlock(&port->slock); - - } else if (status & VID_BC_MSK_RISCI2) { - - dprintk(7, " (RISCI2 0x%08x)\n", VID_BC_MSK_RISCI2); - - spin_lock(&port->slock); - cx23885_restart_queue(port, &port->mpegq); - spin_unlock(&port->slock); - - } - if (status) { - cx_write(port->reg_ts_int_stat, status); - handled = 1; - } - - return handled; -} - -static irqreturn_t cx23885_irq(int irq, void *dev_id) -{ - struct cx23885_dev *dev = dev_id; - struct cx23885_tsport *ts1 = &dev->ts1; - struct cx23885_tsport *ts2 = &dev->ts2; - u32 pci_status, pci_mask; - u32 vida_status, vida_mask; - u32 audint_status, audint_mask; - u32 ts1_status, ts1_mask; - u32 ts2_status, ts2_mask; - int vida_count = 0, ts1_count = 0, ts2_count = 0, handled = 0; - int audint_count = 0; - bool subdev_handled; - - pci_status = cx_read(PCI_INT_STAT); - pci_mask = cx23885_irq_get_mask(dev); - vida_status = cx_read(VID_A_INT_STAT); - vida_mask = cx_read(VID_A_INT_MSK); - audint_status = cx_read(AUDIO_INT_INT_STAT); - audint_mask = cx_read(AUDIO_INT_INT_MSK); - ts1_status = cx_read(VID_B_INT_STAT); - ts1_mask = cx_read(VID_B_INT_MSK); - ts2_status = cx_read(VID_C_INT_STAT); - ts2_mask = cx_read(VID_C_INT_MSK); - - if ((pci_status == 0) && (ts2_status == 0) && (ts1_status == 0)) - goto out; - - vida_count = cx_read(VID_A_GPCNT); - audint_count = cx_read(AUD_INT_A_GPCNT); - ts1_count = cx_read(ts1->reg_gpcnt); - ts2_count = cx_read(ts2->reg_gpcnt); - dprintk(7, "pci_status: 0x%08x pci_mask: 0x%08x\n", - pci_status, pci_mask); - dprintk(7, "vida_status: 0x%08x vida_mask: 0x%08x count: 0x%x\n", - vida_status, vida_mask, vida_count); - dprintk(7, "audint_status: 0x%08x audint_mask: 0x%08x count: 0x%x\n", - audint_status, audint_mask, audint_count); - dprintk(7, "ts1_status: 0x%08x ts1_mask: 0x%08x count: 0x%x\n", - ts1_status, ts1_mask, ts1_count); - dprintk(7, "ts2_status: 0x%08x ts2_mask: 0x%08x count: 0x%x\n", - ts2_status, ts2_mask, ts2_count); - - if (pci_status & (PCI_MSK_RISC_RD | PCI_MSK_RISC_WR | - PCI_MSK_AL_RD | PCI_MSK_AL_WR | PCI_MSK_APB_DMA | - PCI_MSK_VID_C | PCI_MSK_VID_B | PCI_MSK_VID_A | - PCI_MSK_AUD_INT | PCI_MSK_AUD_EXT | - PCI_MSK_GPIO0 | PCI_MSK_GPIO1 | - PCI_MSK_AV_CORE | PCI_MSK_IR)) { - - if (pci_status & PCI_MSK_RISC_RD) - dprintk(7, " (PCI_MSK_RISC_RD 0x%08x)\n", - PCI_MSK_RISC_RD); - - if (pci_status & PCI_MSK_RISC_WR) - dprintk(7, " (PCI_MSK_RISC_WR 0x%08x)\n", - PCI_MSK_RISC_WR); - - if (pci_status & PCI_MSK_AL_RD) - dprintk(7, " (PCI_MSK_AL_RD 0x%08x)\n", - PCI_MSK_AL_RD); - - if (pci_status & PCI_MSK_AL_WR) - dprintk(7, " (PCI_MSK_AL_WR 0x%08x)\n", - PCI_MSK_AL_WR); - - if (pci_status & PCI_MSK_APB_DMA) - dprintk(7, " (PCI_MSK_APB_DMA 0x%08x)\n", - PCI_MSK_APB_DMA); - - if (pci_status & PCI_MSK_VID_C) - dprintk(7, " (PCI_MSK_VID_C 0x%08x)\n", - PCI_MSK_VID_C); - - if (pci_status & PCI_MSK_VID_B) - dprintk(7, " (PCI_MSK_VID_B 0x%08x)\n", - PCI_MSK_VID_B); - - if (pci_status & PCI_MSK_VID_A) - dprintk(7, " (PCI_MSK_VID_A 0x%08x)\n", - PCI_MSK_VID_A); - - if (pci_status & PCI_MSK_AUD_INT) - dprintk(7, " (PCI_MSK_AUD_INT 0x%08x)\n", - PCI_MSK_AUD_INT); - - if (pci_status & PCI_MSK_AUD_EXT) - dprintk(7, " (PCI_MSK_AUD_EXT 0x%08x)\n", - PCI_MSK_AUD_EXT); - - if (pci_status & PCI_MSK_GPIO0) - dprintk(7, " (PCI_MSK_GPIO0 0x%08x)\n", - PCI_MSK_GPIO0); - - if (pci_status & PCI_MSK_GPIO1) - dprintk(7, " (PCI_MSK_GPIO1 0x%08x)\n", - PCI_MSK_GPIO1); - - if (pci_status & PCI_MSK_AV_CORE) - dprintk(7, " (PCI_MSK_AV_CORE 0x%08x)\n", - PCI_MSK_AV_CORE); - - if (pci_status & PCI_MSK_IR) - dprintk(7, " (PCI_MSK_IR 0x%08x)\n", - PCI_MSK_IR); - } - - if (cx23885_boards[dev->board].ci_type == 1 && - (pci_status & (PCI_MSK_GPIO1 | PCI_MSK_GPIO0))) - handled += netup_ci_slot_status(dev, pci_status); - - if (cx23885_boards[dev->board].ci_type == 2 && - (pci_status & PCI_MSK_GPIO0)) - handled += altera_ci_irq(dev); - - if (ts1_status) { - if (cx23885_boards[dev->board].portb == CX23885_MPEG_DVB) - handled += cx23885_irq_ts(ts1, ts1_status); - else - if (cx23885_boards[dev->board].portb == CX23885_MPEG_ENCODER) - handled += cx23885_irq_417(dev, ts1_status); - } - - if (ts2_status) { - if (cx23885_boards[dev->board].portc == CX23885_MPEG_DVB) - handled += cx23885_irq_ts(ts2, ts2_status); - else - if (cx23885_boards[dev->board].portc == CX23885_MPEG_ENCODER) - handled += cx23885_irq_417(dev, ts2_status); - } - - if (vida_status) - handled += cx23885_video_irq(dev, vida_status); - - if (audint_status) - handled += cx23885_audio_irq(dev, audint_status, audint_mask); - - if (pci_status & PCI_MSK_IR) { - subdev_handled = false; - v4l2_subdev_call(dev->sd_ir, core, interrupt_service_routine, - pci_status, &subdev_handled); - if (subdev_handled) - handled++; - } - - if ((pci_status & pci_mask) & PCI_MSK_AV_CORE) { - cx23885_irq_disable(dev, PCI_MSK_AV_CORE); - if (!schedule_work(&dev->cx25840_work)) - printk(KERN_ERR "%s: failed to set up deferred work for" - " AV Core/IR interrupt. Interrupt is disabled" - " and won't be re-enabled\n", dev->name); - handled++; - } - - if (handled) - cx_write(PCI_INT_STAT, pci_status); -out: - return IRQ_RETVAL(handled); -} - -static void cx23885_v4l2_dev_notify(struct v4l2_subdev *sd, - unsigned int notification, void *arg) -{ - struct cx23885_dev *dev; - - if (sd == NULL) - return; - - dev = to_cx23885(sd->v4l2_dev); - - switch (notification) { - case V4L2_SUBDEV_IR_RX_NOTIFY: /* Possibly called in an IRQ context */ - if (sd == dev->sd_ir) - cx23885_ir_rx_v4l2_dev_notify(sd, *(u32 *)arg); - break; - case V4L2_SUBDEV_IR_TX_NOTIFY: /* Possibly called in an IRQ context */ - if (sd == dev->sd_ir) - cx23885_ir_tx_v4l2_dev_notify(sd, *(u32 *)arg); - break; - } -} - -static void cx23885_v4l2_dev_notify_init(struct cx23885_dev *dev) -{ - INIT_WORK(&dev->cx25840_work, cx23885_av_work_handler); - INIT_WORK(&dev->ir_rx_work, cx23885_ir_rx_work_handler); - INIT_WORK(&dev->ir_tx_work, cx23885_ir_tx_work_handler); - dev->v4l2_dev.notify = cx23885_v4l2_dev_notify; -} - -static inline int encoder_on_portb(struct cx23885_dev *dev) -{ - return cx23885_boards[dev->board].portb == CX23885_MPEG_ENCODER; -} - -static inline int encoder_on_portc(struct cx23885_dev *dev) -{ - return cx23885_boards[dev->board].portc == CX23885_MPEG_ENCODER; -} - -/* Mask represents 32 different GPIOs, GPIO's are split into multiple - * registers depending on the board configuration (and whether the - * 417 encoder (wi it's own GPIO's) are present. Each GPIO bit will - * be pushed into the correct hardware register, regardless of the - * physical location. Certain registers are shared so we sanity check - * and report errors if we think we're tampering with a GPIo that might - * be assigned to the encoder (and used for the host bus). - * - * GPIO 2 thru 0 - On the cx23885 bridge - * GPIO 18 thru 3 - On the cx23417 host bus interface - * GPIO 23 thru 19 - On the cx25840 a/v core - */ -void cx23885_gpio_set(struct cx23885_dev *dev, u32 mask) -{ - if (mask & 0x7) - cx_set(GP0_IO, mask & 0x7); - - if (mask & 0x0007fff8) { - if (encoder_on_portb(dev) || encoder_on_portc(dev)) - printk(KERN_ERR - "%s: Setting GPIO on encoder ports\n", - dev->name); - cx_set(MC417_RWD, (mask & 0x0007fff8) >> 3); - } - - /* TODO: 23-19 */ - if (mask & 0x00f80000) - printk(KERN_INFO "%s: Unsupported\n", dev->name); -} - -void cx23885_gpio_clear(struct cx23885_dev *dev, u32 mask) -{ - if (mask & 0x00000007) - cx_clear(GP0_IO, mask & 0x7); - - if (mask & 0x0007fff8) { - if (encoder_on_portb(dev) || encoder_on_portc(dev)) - printk(KERN_ERR - "%s: Clearing GPIO moving on encoder ports\n", - dev->name); - cx_clear(MC417_RWD, (mask & 0x7fff8) >> 3); - } - - /* TODO: 23-19 */ - if (mask & 0x00f80000) - printk(KERN_INFO "%s: Unsupported\n", dev->name); -} - -u32 cx23885_gpio_get(struct cx23885_dev *dev, u32 mask) -{ - if (mask & 0x00000007) - return (cx_read(GP0_IO) >> 8) & mask & 0x7; - - if (mask & 0x0007fff8) { - if (encoder_on_portb(dev) || encoder_on_portc(dev)) - printk(KERN_ERR - "%s: Reading GPIO moving on encoder ports\n", - dev->name); - return (cx_read(MC417_RWD) & ((mask & 0x7fff8) >> 3)) << 3; - } - - /* TODO: 23-19 */ - if (mask & 0x00f80000) - printk(KERN_INFO "%s: Unsupported\n", dev->name); - - return 0; -} - -void cx23885_gpio_enable(struct cx23885_dev *dev, u32 mask, int asoutput) -{ - if ((mask & 0x00000007) && asoutput) - cx_set(GP0_IO, (mask & 0x7) << 16); - else if ((mask & 0x00000007) && !asoutput) - cx_clear(GP0_IO, (mask & 0x7) << 16); - - if (mask & 0x0007fff8) { - if (encoder_on_portb(dev) || encoder_on_portc(dev)) - printk(KERN_ERR - "%s: Enabling GPIO on encoder ports\n", - dev->name); - } - - /* MC417_OEN is active low for output, write 1 for an input */ - if ((mask & 0x0007fff8) && asoutput) - cx_clear(MC417_OEN, (mask & 0x7fff8) >> 3); - - else if ((mask & 0x0007fff8) && !asoutput) - cx_set(MC417_OEN, (mask & 0x7fff8) >> 3); - - /* TODO: 23-19 */ -} - -static int __devinit cx23885_initdev(struct pci_dev *pci_dev, - const struct pci_device_id *pci_id) -{ - struct cx23885_dev *dev; - int err; - - dev = kzalloc(sizeof(*dev), GFP_KERNEL); - if (NULL == dev) - return -ENOMEM; - - err = v4l2_device_register(&pci_dev->dev, &dev->v4l2_dev); - if (err < 0) - goto fail_free; - - /* Prepare to handle notifications from subdevices */ - cx23885_v4l2_dev_notify_init(dev); - - /* pci init */ - dev->pci = pci_dev; - if (pci_enable_device(pci_dev)) { - err = -EIO; - goto fail_unreg; - } - - if (cx23885_dev_setup(dev) < 0) { - err = -EINVAL; - goto fail_unreg; - } - - /* print pci info */ - dev->pci_rev = pci_dev->revision; - pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &dev->pci_lat); - printk(KERN_INFO "%s/0: found at %s, rev: %d, irq: %d, " - "latency: %d, mmio: 0x%llx\n", dev->name, - pci_name(pci_dev), dev->pci_rev, pci_dev->irq, - dev->pci_lat, - (unsigned long long)pci_resource_start(pci_dev, 0)); - - pci_set_master(pci_dev); - if (!pci_dma_supported(pci_dev, 0xffffffff)) { - printk("%s/0: Oops: no 32bit PCI DMA ???\n", dev->name); - err = -EIO; - goto fail_irq; - } - - err = request_irq(pci_dev->irq, cx23885_irq, - IRQF_SHARED | IRQF_DISABLED, dev->name, dev); - if (err < 0) { - printk(KERN_ERR "%s: can't get IRQ %d\n", - dev->name, pci_dev->irq); - goto fail_irq; - } - - switch (dev->board) { - case CX23885_BOARD_NETUP_DUAL_DVBS2_CI: - cx23885_irq_add_enable(dev, PCI_MSK_GPIO1 | PCI_MSK_GPIO0); - break; - case CX23885_BOARD_NETUP_DUAL_DVB_T_C_CI_RF: - cx23885_irq_add_enable(dev, PCI_MSK_GPIO0); - break; - } - - /* - * The CX2388[58] IR controller can start firing interrupts when - * enabled, so these have to take place after the cx23885_irq() handler - * is hooked up by the call to request_irq() above. - */ - cx23885_ir_pci_int_enable(dev); - cx23885_input_init(dev); - - return 0; - -fail_irq: - cx23885_dev_unregister(dev); -fail_unreg: - v4l2_device_unregister(&dev->v4l2_dev); -fail_free: - kfree(dev); - return err; -} - -static void __devexit cx23885_finidev(struct pci_dev *pci_dev) -{ - struct v4l2_device *v4l2_dev = pci_get_drvdata(pci_dev); - struct cx23885_dev *dev = to_cx23885(v4l2_dev); - - cx23885_input_fini(dev); - cx23885_ir_fini(dev); - - cx23885_shutdown(dev); - - pci_disable_device(pci_dev); - - /* unregister stuff */ - free_irq(pci_dev->irq, dev); - - cx23885_dev_unregister(dev); - v4l2_device_unregister(v4l2_dev); - kfree(dev); -} - -static struct pci_device_id cx23885_pci_tbl[] = { - { - /* CX23885 */ - .vendor = 0x14f1, - .device = 0x8852, - .subvendor = PCI_ANY_ID, - .subdevice = PCI_ANY_ID, - }, { - /* CX23887 Rev 2 */ - .vendor = 0x14f1, - .device = 0x8880, - .subvendor = PCI_ANY_ID, - .subdevice = PCI_ANY_ID, - }, { - /* --- end of list --- */ - } -}; -MODULE_DEVICE_TABLE(pci, cx23885_pci_tbl); - -static struct pci_driver cx23885_pci_driver = { - .name = "cx23885", - .id_table = cx23885_pci_tbl, - .probe = cx23885_initdev, - .remove = __devexit_p(cx23885_finidev), - /* TODO */ - .suspend = NULL, - .resume = NULL, -}; - -static int __init cx23885_init(void) -{ - printk(KERN_INFO "cx23885 driver version %s loaded\n", - CX23885_VERSION); - return pci_register_driver(&cx23885_pci_driver); -} - -static void __exit cx23885_fini(void) -{ - pci_unregister_driver(&cx23885_pci_driver); -} - -module_init(cx23885_init); -module_exit(cx23885_fini); diff --git a/drivers/media/video/cx23885/cx23885-dvb.c b/drivers/media/video/cx23885/cx23885-dvb.c deleted file mode 100644 index f3202a52d53..00000000000 --- a/drivers/media/video/cx23885/cx23885-dvb.c +++ /dev/null @@ -1,1356 +0,0 @@ -/* - * Driver for the Conexant CX23885 PCIe bridge - * - * Copyright (c) 2006 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 <linux/module.h> -#include <linux/init.h> -#include <linux/device.h> -#include <linux/fs.h> -#include <linux/kthread.h> -#include <linux/file.h> -#include <linux/suspend.h> - -#include "cx23885.h" -#include <media/v4l2-common.h> - -#include "dvb_ca_en50221.h" -#include "s5h1409.h" -#include "s5h1411.h" -#include "mt2131.h" -#include "tda8290.h" -#include "tda18271.h" -#include "lgdt330x.h" -#include "xc4000.h" -#include "xc5000.h" -#include "max2165.h" -#include "tda10048.h" -#include "tuner-xc2028.h" -#include "tuner-simple.h" -#include "dib7000p.h" -#include "dibx000_common.h" -#include "zl10353.h" -#include "stv0900.h" -#include "stv0900_reg.h" -#include "stv6110.h" -#include "lnbh24.h" -#include "cx24116.h" -#include "cimax2.h" -#include "lgs8gxx.h" -#include "netup-eeprom.h" -#include "netup-init.h" -#include "lgdt3305.h" -#include "atbm8830.h" -#include "ds3000.h" -#include "cx23885-f300.h" -#include "altera-ci.h" -#include "stv0367.h" -#include "drxk.h" -#include "mt2063.h" - -static unsigned int debug; - -#define dprintk(level, fmt, arg...)\ - do { if (debug >= level)\ - printk(KERN_DEBUG "%s/0: " fmt, dev->name, ## arg);\ - } while (0) - -/* ------------------------------------------------------------------ */ - -static unsigned int alt_tuner; -module_param(alt_tuner, int, 0644); -MODULE_PARM_DESC(alt_tuner, "Enable alternate tuner configuration"); - -DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); - -/* ------------------------------------------------------------------ */ - -static int dvb_buf_setup(struct videobuf_queue *q, - unsigned int *count, unsigned int *size) -{ - struct cx23885_tsport *port = q->priv_data; - - port->ts_packet_size = 188 * 4; - port->ts_packet_count = 32; - - *size = port->ts_packet_size * port->ts_packet_count; - *count = 32; - return 0; -} - -static int dvb_buf_prepare(struct videobuf_queue *q, - struct videobuf_buffer *vb, enum v4l2_field field) -{ - struct cx23885_tsport *port = q->priv_data; - return cx23885_buf_prepare(q, port, (struct cx23885_buffer *)vb, field); -} - -static void dvb_buf_queue(struct videobuf_queue *q, struct videobuf_buffer *vb) -{ - struct cx23885_tsport *port = q->priv_data; - cx23885_buf_queue(port, (struct cx23885_buffer *)vb); -} - -static void dvb_buf_release(struct videobuf_queue *q, - struct videobuf_buffer *vb) -{ - cx23885_free_buffer(q, (struct cx23885_buffer *)vb); -} - -static int cx23885_dvb_set_frontend(struct dvb_frontend *fe); - -static void cx23885_dvb_gate_ctrl(struct cx23885_tsport *port, int open) -{ - struct videobuf_dvb_frontends *f; - struct videobuf_dvb_frontend *fe; - - f = &port->frontends; - - if (f->gate <= 1) /* undefined or fe0 */ - fe = videobuf_dvb_get_frontend(f, 1); - else - fe = videobuf_dvb_get_frontend(f, f->gate); - - if (fe && fe->dvb.frontend && fe->dvb.frontend->ops.i2c_gate_ctrl) - fe->dvb.frontend->ops.i2c_gate_ctrl(fe->dvb.frontend, open); - - /* - * FIXME: Improve this path to avoid calling the - * cx23885_dvb_set_frontend() every time it passes here. - */ - cx23885_dvb_set_frontend(fe->dvb.frontend); -} - -static struct videobuf_queue_ops dvb_qops = { - .buf_setup = dvb_buf_setup, - .buf_prepare = dvb_buf_prepare, - .buf_queue = dvb_buf_queue, - .buf_release = dvb_buf_release, -}; - -static struct s5h1409_config hauppauge_generic_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 struct tda10048_config hauppauge_hvr1200_config = { - .demod_address = 0x10 >> 1, - .output_mode = TDA10048_SERIAL_OUTPUT, - .fwbulkwritelen = TDA10048_BULKWRITE_200, - .inversion = TDA10048_INVERSION_ON, - .dtv6_if_freq_khz = TDA10048_IF_3300, - .dtv7_if_freq_khz = TDA10048_IF_3800, - .dtv8_if_freq_khz = TDA10048_IF_4300, - .clk_freq_khz = TDA10048_CLK_16000, -}; - -static struct tda10048_config hauppauge_hvr1210_config = { - .demod_address = 0x10 >> 1, - .output_mode = TDA10048_SERIAL_OUTPUT, - .fwbulkwritelen = TDA10048_BULKWRITE_200, - .inversion = TDA10048_INVERSION_ON, - .dtv6_if_freq_khz = TDA10048_IF_3300, - .dtv7_if_freq_khz = TDA10048_IF_3500, - .dtv8_if_freq_khz = TDA10048_IF_4000, - .clk_freq_khz = TDA10048_CLK_16000, -}; - -static struct s5h1409_config hauppauge_ezqam_config = { - .demod_address = 0x32 >> 1, - .output_mode = S5H1409_SERIAL_OUTPUT, - .gpio = S5H1409_GPIO_OFF, - .qam_if = 4000, - .inversion = S5H1409_INVERSION_ON, - .status_mode = S5H1409_DEMODLOCKING, - .mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK, -}; - -static struct s5h1409_config hauppauge_hvr1800lp_config = { - .demod_address = 0x32 >> 1, - .output_mode = S5H1409_SERIAL_OUTPUT, - .gpio = S5H1409_GPIO_OFF, - .qam_if = 44000, - .inversion = S5H1409_INVERSION_OFF, - .status_mode = S5H1409_DEMODLOCKING, - .mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK, -}; - -static struct s5h1409_config hauppauge_hvr1500_config = { - .demod_address = 0x32 >> 1, - .output_mode = S5H1409_SERIAL_OUTPUT, - .gpio = S5H1409_GPIO_OFF, - .inversion = S5H1409_INVERSION_OFF, - .status_mode = S5H1409_DEMODLOCKING, - .mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK, -}; - -static struct mt2131_config hauppauge_generic_tunerconfig = { - 0x61 -}; - -static struct lgdt330x_config fusionhdtv_5_express = { - .demod_address = 0x0e, - .demod_chip = LGDT3303, - .serial_mpeg = 0x40, -}; - -static struct s5h1409_config hauppauge_hvr1500q_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 struct s5h1409_config dvico_s5h1409_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 struct s5h1411_config dvico_s5h1411_config = { - .output_mode = S5H1411_SERIAL_OUTPUT, - .gpio = S5H1411_GPIO_ON, - .qam_if = S5H1411_IF_44000, - .vsb_if = S5H1411_IF_44000, - .inversion = S5H1411_INVERSION_OFF, - .status_mode = S5H1411_DEMODLOCKING, - .mpeg_timing = S5H1411_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK, -}; - -static struct s5h1411_config hcw_s5h1411_config = { - .output_mode = S5H1411_SERIAL_OUTPUT, - .gpio = S5H1411_GPIO_OFF, - .vsb_if = S5H1411_IF_44000, - .qam_if = S5H1411_IF_4000, - .inversion = S5H1411_INVERSION_ON, - .status_mode = S5H1411_DEMODLOCKING, - .mpeg_timing = S5H1411_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK, -}; - -static struct xc5000_config hauppauge_hvr1500q_tunerconfig = { - .i2c_address = 0x61, - .if_khz = 5380, -}; - -static struct xc5000_config dvico_xc5000_tunerconfig = { - .i2c_address = 0x64, - .if_khz = 5380, -}; - -static struct tda829x_config tda829x_no_probe = { - .probe_tuner = TDA829X_DONT_PROBE, -}; - -static struct tda18271_std_map hauppauge_tda18271_std_map = { - .atsc_6 = { .if_freq = 5380, .agc_mode = 3, .std = 3, - .if_lvl = 6, .rfagc_top = 0x37 }, - .qam_6 = { .if_freq = 4000, .agc_mode = 3, .std = 0, - .if_lvl = 6, .rfagc_top = 0x37 }, -}; - -static struct tda18271_std_map hauppauge_hvr1200_tda18271_std_map = { - .dvbt_6 = { .if_freq = 3300, .agc_mode = 3, .std = 4, - .if_lvl = 1, .rfagc_top = 0x37, }, - .dvbt_7 = { .if_freq = 3800, .agc_mode = 3, .std = 5, - .if_lvl = 1, .rfagc_top = 0x37, }, - .dvbt_8 = { .if_freq = 4300, .agc_mode = 3, .std = 6, - .if_lvl = 1, .rfagc_top = 0x37, }, -}; - -static struct tda18271_config hauppauge_tda18271_config = { - .std_map = &hauppauge_tda18271_std_map, - .gate = TDA18271_GATE_ANALOG, - .output_opt = TDA18271_OUTPUT_LT_OFF, -}; - -static struct tda18271_config hauppauge_hvr1200_tuner_config = { - .std_map = &hauppauge_hvr1200_tda18271_std_map, - .gate = TDA18271_GATE_ANALOG, - .output_opt = TDA18271_OUTPUT_LT_OFF, -}; - -static struct tda18271_config hauppauge_hvr1210_tuner_config = { - .gate = TDA18271_GATE_DIGITAL, - .output_opt = TDA18271_OUTPUT_LT_OFF, -}; - -static struct tda18271_std_map hauppauge_hvr127x_std_map = { - .atsc_6 = { .if_freq = 3250, .agc_mode = 3, .std = 4, - .if_lvl = 1, .rfagc_top = 0x58 }, - .qam_6 = { .if_freq = 4000, .agc_mode = 3, .std = 5, - .if_lvl = 1, .rfagc_top = 0x58 }, -}; - -static struct tda18271_config hauppauge_hvr127x_config = { - .std_map = &hauppauge_hvr127x_std_map, - .output_opt = TDA18271_OUTPUT_LT_OFF, -}; - -static struct lgdt3305_config hauppauge_lgdt3305_config = { - .i2c_addr = 0x0e, - .mpeg_mode = LGDT3305_MPEG_SERIAL, - .tpclk_edge = LGDT3305_TPCLK_FALLING_EDGE, - .tpvalid_polarity = LGDT3305_TP_VALID_HIGH, - .deny_i2c_rptr = 1, - .spectral_inversion = 1, - .qam_if_khz = 4000, - .vsb_if_khz = 3250, -}; - -static struct dibx000_agc_config xc3028_agc_config = { - BAND_VHF | BAND_UHF, /* band_caps */ - - /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=0, - * P_agc_inv_pwm1=0, P_agc_inv_pwm2=0, - * P_agc_inh_dc_rv_est=0, P_agc_time_est=3, P_agc_freeze=0, - * P_agc_nb_est=2, P_agc_write=0 - */ - (0 << 15) | (0 << 14) | (0 << 11) | (0 << 10) | (0 << 9) | (0 << 8) | - (3 << 5) | (0 << 4) | (2 << 1) | (0 << 0), /* setup */ - - 712, /* inv_gain */ - 21, /* time_stabiliz */ - - 0, /* alpha_level */ - 118, /* thlock */ - - 0, /* wbd_inv */ - 2867, /* wbd_ref */ - 0, /* wbd_sel */ - 2, /* wbd_alpha */ - - 0, /* agc1_max */ - 0, /* agc1_min */ - 39718, /* agc2_max */ - 9930, /* agc2_min */ - 0, /* agc1_pt1 */ - 0, /* agc1_pt2 */ - 0, /* agc1_pt3 */ - 0, /* agc1_slope1 */ - 0, /* agc1_slope2 */ - 0, /* agc2_pt1 */ - 128, /* agc2_pt2 */ - 29, /* agc2_slope1 */ - 29, /* agc2_slope2 */ - - 17, /* alpha_mant */ - 27, /* alpha_exp */ - 23, /* beta_mant */ - 51, /* beta_exp */ - - 1, /* perform_agc_softsplit */ -}; - -/* PLL Configuration for COFDM BW_MHz = 8.000000 - * With external clock = 30.000000 */ -static struct dibx000_bandwidth_config xc3028_bw_config = { - 60000, /* internal */ - 30000, /* sampling */ - 1, /* pll_cfg: prediv */ - 8, /* pll_cfg: ratio */ - 3, /* pll_cfg: range */ - 1, /* pll_cfg: reset */ - 0, /* pll_cfg: bypass */ - 0, /* misc: refdiv */ - 0, /* misc: bypclk_div */ - 1, /* misc: IO_CLK_en_core */ - 1, /* misc: ADClkSrc */ - 0, /* misc: modulo */ - (3 << 14) | (1 << 12) | (524 << 0), /* sad_cfg: refsel, sel, freq_15k */ - (1 << 25) | 5816102, /* ifreq = 5.200000 MHz */ - 20452225, /* timf */ - 30000000 /* xtal_hz */ -}; - -static struct dib7000p_config hauppauge_hvr1400_dib7000_config = { - .output_mpeg2_in_188_bytes = 1, - .hostbus_diversity = 1, - .tuner_is_baseband = 0, - .update_lna = NULL, - - .agc_config_count = 1, - .agc = &xc3028_agc_config, - .bw = &xc3028_bw_config, - - .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS, - .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES, - .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS, - - .pwm_freq_div = 0, - .agc_control = NULL, - .spur_protect = 0, - - .output_mode = OUTMODE_MPEG2_SERIAL, -}; - -static struct zl10353_config dvico_fusionhdtv_xc3028 = { - .demod_address = 0x0f, - .if2 = 45600, - .no_tuner = 1, - .disable_i2c_gate_ctrl = 1, -}; - -static struct stv0900_reg stv0900_ts_regs[] = { - { R0900_TSGENERAL, 0x00 }, - { R0900_P1_TSSPEED, 0x40 }, - { R0900_P2_TSSPEED, 0x40 }, - { R0900_P1_TSCFGM, 0xc0 }, - { R0900_P2_TSCFGM, 0xc0 }, - { R0900_P1_TSCFGH, 0xe0 }, - { R0900_P2_TSCFGH, 0xe0 }, - { R0900_P1_TSCFGL, 0x20 }, - { R0900_P2_TSCFGL, 0x20 }, - { 0xffff, 0xff }, /* terminate */ -}; - -static struct stv0900_config netup_stv0900_config = { - .demod_address = 0x68, - .demod_mode = 1, /* dual */ - .xtal = 8000000, - .clkmode = 3,/* 0-CLKI, 2-XTALI, else AUTO */ - .diseqc_mode = 2,/* 2/3 PWM */ - .ts_config_regs = stv0900_ts_regs, - .tun1_maddress = 0,/* 0x60 */ - .tun2_maddress = 3,/* 0x63 */ - .tun1_adc = 1,/* 1 Vpp */ - .tun2_adc = 1,/* 1 Vpp */ -}; - -static struct stv6110_config netup_stv6110_tunerconfig_a = { - .i2c_address = 0x60, - .mclk = 16000000, - .clk_div = 1, - .gain = 8, /* +16 dB - maximum gain */ -}; - -static struct stv6110_config netup_stv6110_tunerconfig_b = { - .i2c_address = 0x63, - .mclk = 16000000, - .clk_div = 1, - .gain = 8, /* +16 dB - maximum gain */ -}; - -static struct cx24116_config tbs_cx24116_config = { - .demod_address = 0x55, -}; - -static struct ds3000_config tevii_ds3000_config = { - .demod_address = 0x68, -}; - -static struct cx24116_config dvbworld_cx24116_config = { - .demod_address = 0x05, -}; - -static struct lgs8gxx_config mygica_x8506_lgs8gl5_config = { - .prod = LGS8GXX_PROD_LGS8GL5, - .demod_address = 0x19, - .serial_ts = 0, - .ts_clk_pol = 1, - .ts_clk_gated = 1, - .if_clk_freq = 30400, /* 30.4 MHz */ - .if_freq = 5380, /* 5.38 MHz */ - .if_neg_center = 1, - .ext_adc = 0, - .adc_signed = 0, - .if_neg_edge = 0, -}; - -static struct xc5000_config mygica_x8506_xc5000_config = { - .i2c_address = 0x61, - .if_khz = 5380, -}; - -static int cx23885_dvb_set_frontend(struct dvb_frontend *fe) -{ - struct dtv_frontend_properties *p = &fe->dtv_property_cache; - struct cx23885_tsport *port = fe->dvb->priv; - struct cx23885_dev *dev = port->dev; - - switch (dev->board) { - case CX23885_BOARD_HAUPPAUGE_HVR1275: - switch (p->modulation) { - case VSB_8: - cx23885_gpio_clear(dev, GPIO_5); - break; - case QAM_64: - case QAM_256: - default: - cx23885_gpio_set(dev, GPIO_5); - break; - } - break; - case CX23885_BOARD_MYGICA_X8506: - case CX23885_BOARD_MAGICPRO_PROHDTVE2: - /* Select Digital TV */ - cx23885_gpio_set(dev, GPIO_0); - break; - } - return 0; -} - -static struct lgs8gxx_config magicpro_prohdtve2_lgs8g75_config = { - .prod = LGS8GXX_PROD_LGS8G75, - .demod_address = 0x19, - .serial_ts = 0, - .ts_clk_pol = 1, - .ts_clk_gated = 1, - .if_clk_freq = 30400, /* 30.4 MHz */ - .if_freq = 6500, /* 6.50 MHz */ - .if_neg_center = 1, - .ext_adc = 0, - .adc_signed = 1, - .adc_vpp = 2, /* 1.6 Vpp */ - .if_neg_edge = 1, -}; - -static struct xc5000_config magicpro_prohdtve2_xc5000_config = { - .i2c_address = 0x61, - .if_khz = 6500, -}; - -static struct atbm8830_config mygica_x8558pro_atbm8830_cfg1 = { - .prod = ATBM8830_PROD_8830, - .demod_address = 0x44, - .serial_ts = 0, - .ts_sampling_edge = 1, - .ts_clk_gated = 0, - .osc_clk_freq = 30400, /* in kHz */ - .if_freq = 0, /* zero IF */ - .zif_swap_iq = 1, - .agc_min = 0x2E, - .agc_max = 0xFF, - .agc_hold_loop = 0, -}; - -static struct max2165_config mygic_x8558pro_max2165_cfg1 = { - .i2c_address = 0x60, - .osc_clk = 20 -}; - -static struct atbm8830_config mygica_x8558pro_atbm8830_cfg2 = { - .prod = ATBM8830_PROD_8830, - .demod_address = 0x44, - .serial_ts = 1, - .ts_sampling_edge = 1, - .ts_clk_gated = 0, - .osc_clk_freq = 30400, /* in kHz */ - .if_freq = 0, /* zero IF */ - .zif_swap_iq = 1, - .agc_min = 0x2E, - .agc_max = 0xFF, - .agc_hold_loop = 0, -}; - -static struct max2165_config mygic_x8558pro_max2165_cfg2 = { - .i2c_address = 0x60, - .osc_clk = 20 -}; -static struct stv0367_config netup_stv0367_config[] = { - { - .demod_address = 0x1c, - .xtal = 27000000, - .if_khz = 4500, - .if_iq_mode = 0, - .ts_mode = 1, - .clk_pol = 0, - }, { - .demod_address = 0x1d, - .xtal = 27000000, - .if_khz = 4500, - .if_iq_mode = 0, - .ts_mode = 1, - .clk_pol = 0, - }, -}; - -static struct xc5000_config netup_xc5000_config[] = { - { - .i2c_address = 0x61, - .if_khz = 4500, - }, { - .i2c_address = 0x64, - .if_khz = 4500, - }, -}; - -static struct drxk_config terratec_drxk_config[] = { - { - .adr = 0x29, - .no_i2c_bridge = 1, - }, { - .adr = 0x2a, - .no_i2c_bridge = 1, - }, -}; - -static struct mt2063_config terratec_mt2063_config[] = { - { - .tuner_address = 0x60, - }, { - .tuner_address = 0x67, - }, -}; - -int netup_altera_fpga_rw(void *device, int flag, int data, int read) -{ - struct cx23885_dev *dev = (struct cx23885_dev *)device; - unsigned long timeout = jiffies + msecs_to_jiffies(1); - uint32_t mem = 0; - - mem = cx_read(MC417_RWD); - if (read) - cx_set(MC417_OEN, ALT_DATA); - else { - cx_clear(MC417_OEN, ALT_DATA);/* D0-D7 out */ - mem &= ~ALT_DATA; - mem |= (data & ALT_DATA); - } - - if (flag) - mem |= ALT_AD_RG; - else - mem &= ~ALT_AD_RG; - - mem &= ~ALT_CS; - if (read) - mem = (mem & ~ALT_RD) | ALT_WR; - else - mem = (mem & ~ALT_WR) | ALT_RD; - - cx_write(MC417_RWD, mem); /* start RW cycle */ - - for (;;) { - mem = cx_read(MC417_RWD); - if ((mem & ALT_RDY) == 0) - break; - if (time_after(jiffies, timeout)) - break; - udelay(1); - } - - cx_set(MC417_RWD, ALT_RD | ALT_WR | ALT_CS); - if (read) - return mem & ALT_DATA; - - return 0; -}; - -static int dvb_register(struct cx23885_tsport *port) -{ - struct cx23885_dev *dev = port->dev; - struct cx23885_i2c *i2c_bus = NULL, *i2c_bus2 = NULL; - struct videobuf_dvb_frontend *fe0, *fe1 = NULL; - int mfe_shared = 0; /* bus not shared by default */ - int ret; - - /* Get the first frontend */ - fe0 = videobuf_dvb_get_frontend(&port->frontends, 1); - if (!fe0) - return -EINVAL; - - /* init struct videobuf_dvb */ - fe0->dvb.name = dev->name; - - /* multi-frontend gate control is undefined or defaults to fe0 */ - port->frontends.gate = 0; - - /* Sets the gate control callback to be used by i2c command calls */ - port->gate_ctrl = cx23885_dvb_gate_ctrl; - - /* init frontend */ - switch (dev->board) { - case CX23885_BOARD_HAUPPAUGE_HVR1250: - i2c_bus = &dev->i2c_bus[0]; - fe0->dvb.frontend = dvb_attach(s5h1409_attach, - &hauppauge_generic_config, - &i2c_bus->i2c_adap); - if (fe0->dvb.frontend != NULL) { - dvb_attach(mt2131_attach, fe0->dvb.frontend, - &i2c_bus->i2c_adap, - &hauppauge_generic_tunerconfig, 0); - } - break; - case CX23885_BOARD_HAUPPAUGE_HVR1270: - case CX23885_BOARD_HAUPPAUGE_HVR1275: - i2c_bus = &dev->i2c_bus[0]; - fe0->dvb.frontend = dvb_attach(lgdt3305_attach, - &hauppauge_lgdt3305_config, - &i2c_bus->i2c_adap); - if (fe0->dvb.frontend != NULL) { - dvb_attach(tda18271_attach, fe0->dvb.frontend, - 0x60, &dev->i2c_bus[1].i2c_adap, - &hauppauge_hvr127x_config); - } - break; - case CX23885_BOARD_HAUPPAUGE_HVR1255: - case CX23885_BOARD_HAUPPAUGE_HVR1255_22111: - i2c_bus = &dev->i2c_bus[0]; - fe0->dvb.frontend = dvb_attach(s5h1411_attach, - &hcw_s5h1411_config, - &i2c_bus->i2c_adap); - if (fe0->dvb.frontend != NULL) { - dvb_attach(tda18271_attach, fe0->dvb.frontend, - 0x60, &dev->i2c_bus[1].i2c_adap, - &hauppauge_tda18271_config); - } - - tda18271_attach(&dev->ts1.analog_fe, - 0x60, &dev->i2c_bus[1].i2c_adap, - &hauppauge_tda18271_config); - - break; - case CX23885_BOARD_HAUPPAUGE_HVR1800: - i2c_bus = &dev->i2c_bus[0]; - switch (alt_tuner) { - case 1: - fe0->dvb.frontend = - dvb_attach(s5h1409_attach, - &hauppauge_ezqam_config, - &i2c_bus->i2c_adap); - if (fe0->dvb.frontend != NULL) { - dvb_attach(tda829x_attach, fe0->dvb.frontend, - &dev->i2c_bus[1].i2c_adap, 0x42, - &tda829x_no_probe); - dvb_attach(tda18271_attach, fe0->dvb.frontend, - 0x60, &dev->i2c_bus[1].i2c_adap, - &hauppauge_tda18271_config); - } - break; - case 0: - default: - fe0->dvb.frontend = - dvb_attach(s5h1409_attach, - &hauppauge_generic_config, - &i2c_bus->i2c_adap); - if (fe0->dvb.frontend != NULL) - dvb_attach(mt2131_attach, fe0->dvb.frontend, - &i2c_bus->i2c_adap, - &hauppauge_generic_tunerconfig, 0); - break; - } - break; - case CX23885_BOARD_HAUPPAUGE_HVR1800lp: - i2c_bus = &dev->i2c_bus[0]; - fe0->dvb.frontend = dvb_attach(s5h1409_attach, - &hauppauge_hvr1800lp_config, - &i2c_bus->i2c_adap); - if (fe0->dvb.frontend != NULL) { - dvb_attach(mt2131_attach, fe0->dvb.frontend, - &i2c_bus->i2c_adap, - &hauppauge_generic_tunerconfig, 0); - } - break; - case CX23885_BOARD_DVICO_FUSIONHDTV_5_EXP: - i2c_bus = &dev->i2c_bus[0]; - fe0->dvb.frontend = dvb_attach(lgdt330x_attach, - &fusionhdtv_5_express, - &i2c_bus->i2c_adap); - if (fe0->dvb.frontend != NULL) { - dvb_attach(simple_tuner_attach, fe0->dvb.frontend, - &i2c_bus->i2c_adap, 0x61, - TUNER_LG_TDVS_H06XF); - } - break; - case CX23885_BOARD_HAUPPAUGE_HVR1500Q: - i2c_bus = &dev->i2c_bus[1]; - fe0->dvb.frontend = dvb_attach(s5h1409_attach, - &hauppauge_hvr1500q_config, - &dev->i2c_bus[0].i2c_adap); - if (fe0->dvb.frontend != NULL) - dvb_attach(xc5000_attach, fe0->dvb.frontend, - &i2c_bus->i2c_adap, - &hauppauge_hvr1500q_tunerconfig); - break; - case CX23885_BOARD_HAUPPAUGE_HVR1500: - i2c_bus = &dev->i2c_bus[1]; - fe0->dvb.frontend = dvb_attach(s5h1409_attach, - &hauppauge_hvr1500_config, - &dev->i2c_bus[0].i2c_adap); - if (fe0->dvb.frontend != NULL) { - struct dvb_frontend *fe; - struct xc2028_config cfg = { - .i2c_adap = &i2c_bus->i2c_adap, - .i2c_addr = 0x61, - }; - static struct xc2028_ctrl ctl = { - .fname = XC2028_DEFAULT_FIRMWARE, - .max_len = 64, - .demod = XC3028_FE_OREN538, - }; - - fe = dvb_attach(xc2028_attach, - fe0->dvb.frontend, &cfg); - if (fe != NULL && fe->ops.tuner_ops.set_config != NULL) - fe->ops.tuner_ops.set_config(fe, &ctl); - } - break; - case CX23885_BOARD_HAUPPAUGE_HVR1200: - case CX23885_BOARD_HAUPPAUGE_HVR1700: - i2c_bus = &dev->i2c_bus[0]; - fe0->dvb.frontend = dvb_attach(tda10048_attach, - &hauppauge_hvr1200_config, - &i2c_bus->i2c_adap); - if (fe0->dvb.frontend != NULL) { - dvb_attach(tda829x_attach, fe0->dvb.frontend, - &dev->i2c_bus[1].i2c_adap, 0x42, - &tda829x_no_probe); - dvb_attach(tda18271_attach, fe0->dvb.frontend, - 0x60, &dev->i2c_bus[1].i2c_adap, - &hauppauge_hvr1200_tuner_config); - } - break; - case CX23885_BOARD_HAUPPAUGE_HVR1210: - i2c_bus = &dev->i2c_bus[0]; - fe0->dvb.frontend = dvb_attach(tda10048_attach, - &hauppauge_hvr1210_config, - &i2c_bus->i2c_adap); - if (fe0->dvb.frontend != NULL) { - dvb_attach(tda18271_attach, fe0->dvb.frontend, - 0x60, &dev->i2c_bus[1].i2c_adap, - &hauppauge_hvr1210_tuner_config); - } - break; - case CX23885_BOARD_HAUPPAUGE_HVR1400: - i2c_bus = &dev->i2c_bus[0]; - fe0->dvb.frontend = dvb_attach(dib7000p_attach, - &i2c_bus->i2c_adap, - 0x12, &hauppauge_hvr1400_dib7000_config); - if (fe0->dvb.frontend != NULL) { - struct dvb_frontend *fe; - struct xc2028_config cfg = { - .i2c_adap = &dev->i2c_bus[1].i2c_adap, - .i2c_addr = 0x64, - }; - static struct xc2028_ctrl ctl = { - .fname = XC3028L_DEFAULT_FIRMWARE, - .max_len = 64, - .demod = XC3028_FE_DIBCOM52, - /* This is true for all demods with - v36 firmware? */ - .type = XC2028_D2633, - }; - - fe = dvb_attach(xc2028_attach, - fe0->dvb.frontend, &cfg); - if (fe != NULL && fe->ops.tuner_ops.set_config != NULL) - fe->ops.tuner_ops.set_config(fe, &ctl); - } - break; - case CX23885_BOARD_DVICO_FUSIONHDTV_7_DUAL_EXP: - i2c_bus = &dev->i2c_bus[port->nr - 1]; - - fe0->dvb.frontend = dvb_attach(s5h1409_attach, - &dvico_s5h1409_config, - &i2c_bus->i2c_adap); - if (fe0->dvb.frontend == NULL) - fe0->dvb.frontend = dvb_attach(s5h1411_attach, - &dvico_s5h1411_config, - &i2c_bus->i2c_adap); - if (fe0->dvb.frontend != NULL) - dvb_attach(xc5000_attach, fe0->dvb.frontend, - &i2c_bus->i2c_adap, - &dvico_xc5000_tunerconfig); - break; - case CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP: { - i2c_bus = &dev->i2c_bus[port->nr - 1]; - - fe0->dvb.frontend = dvb_attach(zl10353_attach, - &dvico_fusionhdtv_xc3028, - &i2c_bus->i2c_adap); - if (fe0->dvb.frontend != NULL) { - struct dvb_frontend *fe; - struct xc2028_config cfg = { - .i2c_adap = &i2c_bus->i2c_adap, - .i2c_addr = 0x61, - }; - static struct xc2028_ctrl ctl = { - .fname = XC2028_DEFAULT_FIRMWARE, - .max_len = 64, - .demod = XC3028_FE_ZARLINK456, - }; - - fe = dvb_attach(xc2028_attach, fe0->dvb.frontend, - &cfg); - if (fe != NULL && fe->ops.tuner_ops.set_config != NULL) - fe->ops.tuner_ops.set_config(fe, &ctl); - } - break; - } - case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H: - case CX23885_BOARD_COMPRO_VIDEOMATE_E650F: - case CX23885_BOARD_COMPRO_VIDEOMATE_E800: - i2c_bus = &dev->i2c_bus[0]; - - fe0->dvb.frontend = dvb_attach(zl10353_attach, - &dvico_fusionhdtv_xc3028, - &i2c_bus->i2c_adap); - if (fe0->dvb.frontend != NULL) { - struct dvb_frontend *fe; - struct xc2028_config cfg = { - .i2c_adap = &dev->i2c_bus[1].i2c_adap, - .i2c_addr = 0x61, - }; - static struct xc2028_ctrl ctl = { - .fname = XC2028_DEFAULT_FIRMWARE, - .max_len = 64, - .demod = XC3028_FE_ZARLINK456, - }; - - fe = dvb_attach(xc2028_attach, fe0->dvb.frontend, - &cfg); - if (fe != NULL && fe->ops.tuner_ops.set_config != NULL) - fe->ops.tuner_ops.set_config(fe, &ctl); - } - break; - case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H_XC4000: - i2c_bus = &dev->i2c_bus[0]; - - fe0->dvb.frontend = dvb_attach(zl10353_attach, - &dvico_fusionhdtv_xc3028, - &i2c_bus->i2c_adap); - if (fe0->dvb.frontend != NULL) { - struct dvb_frontend *fe; - struct xc4000_config cfg = { - .i2c_address = 0x61, - .default_pm = 0, - .dvb_amplitude = 134, - .set_smoothedcvbs = 1, - .if_khz = 4560 - }; - - fe = dvb_attach(xc4000_attach, fe0->dvb.frontend, - &dev->i2c_bus[1].i2c_adap, &cfg); - if (!fe) { - printk(KERN_ERR "%s/2: xc4000 attach failed\n", - dev->name); - goto frontend_detach; - } - } - break; - case CX23885_BOARD_TBS_6920: - i2c_bus = &dev->i2c_bus[1]; - - fe0->dvb.frontend = dvb_attach(cx24116_attach, - &tbs_cx24116_config, - &i2c_bus->i2c_adap); - if (fe0->dvb.frontend != NULL) - fe0->dvb.frontend->ops.set_voltage = f300_set_voltage; - - break; - case CX23885_BOARD_TEVII_S470: - i2c_bus = &dev->i2c_bus[1]; - - fe0->dvb.frontend = dvb_attach(ds3000_attach, - &tevii_ds3000_config, - &i2c_bus->i2c_adap); - if (fe0->dvb.frontend != NULL) - fe0->dvb.frontend->ops.set_voltage = f300_set_voltage; - - break; - case CX23885_BOARD_DVBWORLD_2005: - i2c_bus = &dev->i2c_bus[1]; - - fe0->dvb.frontend = dvb_attach(cx24116_attach, - &dvbworld_cx24116_config, - &i2c_bus->i2c_adap); - break; - case CX23885_BOARD_NETUP_DUAL_DVBS2_CI: - i2c_bus = &dev->i2c_bus[0]; - switch (port->nr) { - /* port B */ - case 1: - fe0->dvb.frontend = dvb_attach(stv0900_attach, - &netup_stv0900_config, - &i2c_bus->i2c_adap, 0); - if (fe0->dvb.frontend != NULL) { - if (dvb_attach(stv6110_attach, - fe0->dvb.frontend, - &netup_stv6110_tunerconfig_a, - &i2c_bus->i2c_adap)) { - if (!dvb_attach(lnbh24_attach, - fe0->dvb.frontend, - &i2c_bus->i2c_adap, - LNBH24_PCL | LNBH24_TTX, - LNBH24_TEN, 0x09)) - printk(KERN_ERR - "No LNBH24 found!\n"); - - } - } - break; - /* port C */ - case 2: - fe0->dvb.frontend = dvb_attach(stv0900_attach, - &netup_stv0900_config, - &i2c_bus->i2c_adap, 1); - if (fe0->dvb.frontend != NULL) { - if (dvb_attach(stv6110_attach, - fe0->dvb.frontend, - &netup_stv6110_tunerconfig_b, - &i2c_bus->i2c_adap)) { - if (!dvb_attach(lnbh24_attach, - fe0->dvb.frontend, - &i2c_bus->i2c_adap, - LNBH24_PCL | LNBH24_TTX, - LNBH24_TEN, 0x0a)) - printk(KERN_ERR - "No LNBH24 found!\n"); - - } - } - break; - } - break; - case CX23885_BOARD_MYGICA_X8506: - i2c_bus = &dev->i2c_bus[0]; - i2c_bus2 = &dev->i2c_bus[1]; - fe0->dvb.frontend = dvb_attach(lgs8gxx_attach, - &mygica_x8506_lgs8gl5_config, - &i2c_bus->i2c_adap); - if (fe0->dvb.frontend != NULL) { - dvb_attach(xc5000_attach, - fe0->dvb.frontend, - &i2c_bus2->i2c_adap, - &mygica_x8506_xc5000_config); - } - break; - case CX23885_BOARD_MAGICPRO_PROHDTVE2: - i2c_bus = &dev->i2c_bus[0]; - i2c_bus2 = &dev->i2c_bus[1]; - fe0->dvb.frontend = dvb_attach(lgs8gxx_attach, - &magicpro_prohdtve2_lgs8g75_config, - &i2c_bus->i2c_adap); - if (fe0->dvb.frontend != NULL) { - dvb_attach(xc5000_attach, - fe0->dvb.frontend, - &i2c_bus2->i2c_adap, - &magicpro_prohdtve2_xc5000_config); - } - break; - case CX23885_BOARD_HAUPPAUGE_HVR1850: - i2c_bus = &dev->i2c_bus[0]; - fe0->dvb.frontend = dvb_attach(s5h1411_attach, - &hcw_s5h1411_config, - &i2c_bus->i2c_adap); - if (fe0->dvb.frontend != NULL) - dvb_attach(tda18271_attach, fe0->dvb.frontend, - 0x60, &dev->i2c_bus[0].i2c_adap, - &hauppauge_tda18271_config); - - tda18271_attach(&dev->ts1.analog_fe, - 0x60, &dev->i2c_bus[1].i2c_adap, - &hauppauge_tda18271_config); - - break; - case CX23885_BOARD_HAUPPAUGE_HVR1290: - i2c_bus = &dev->i2c_bus[0]; - fe0->dvb.frontend = dvb_attach(s5h1411_attach, - &hcw_s5h1411_config, - &i2c_bus->i2c_adap); - if (fe0->dvb.frontend != NULL) - dvb_attach(tda18271_attach, fe0->dvb.frontend, - 0x60, &dev->i2c_bus[0].i2c_adap, - &hauppauge_tda18271_config); - break; - case CX23885_BOARD_MYGICA_X8558PRO: - switch (port->nr) { - /* port B */ - case 1: - i2c_bus = &dev->i2c_bus[0]; - fe0->dvb.frontend = dvb_attach(atbm8830_attach, - &mygica_x8558pro_atbm8830_cfg1, - &i2c_bus->i2c_adap); - if (fe0->dvb.frontend != NULL) { - dvb_attach(max2165_attach, - fe0->dvb.frontend, - &i2c_bus->i2c_adap, - &mygic_x8558pro_max2165_cfg1); - } - break; - /* port C */ - case 2: - i2c_bus = &dev->i2c_bus[1]; - fe0->dvb.frontend = dvb_attach(atbm8830_attach, - &mygica_x8558pro_atbm8830_cfg2, - &i2c_bus->i2c_adap); - if (fe0->dvb.frontend != NULL) { - dvb_attach(max2165_attach, - fe0->dvb.frontend, - &i2c_bus->i2c_adap, - &mygic_x8558pro_max2165_cfg2); - } - break; - } - break; - case CX23885_BOARD_NETUP_DUAL_DVB_T_C_CI_RF: - i2c_bus = &dev->i2c_bus[0]; - mfe_shared = 1;/* MFE */ - port->frontends.gate = 0;/* not clear for me yet */ - /* ports B, C */ - /* MFE frontend 1 DVB-T */ - fe0->dvb.frontend = dvb_attach(stv0367ter_attach, - &netup_stv0367_config[port->nr - 1], - &i2c_bus->i2c_adap); - if (fe0->dvb.frontend != NULL) { - if (NULL == dvb_attach(xc5000_attach, - fe0->dvb.frontend, - &i2c_bus->i2c_adap, - &netup_xc5000_config[port->nr - 1])) - goto frontend_detach; - /* load xc5000 firmware */ - fe0->dvb.frontend->ops.tuner_ops.init(fe0->dvb.frontend); - } - /* MFE frontend 2 */ - fe1 = videobuf_dvb_get_frontend(&port->frontends, 2); - if (fe1 == NULL) - goto frontend_detach; - /* DVB-C init */ - fe1->dvb.frontend = dvb_attach(stv0367cab_attach, - &netup_stv0367_config[port->nr - 1], - &i2c_bus->i2c_adap); - if (fe1->dvb.frontend != NULL) { - fe1->dvb.frontend->id = 1; - if (NULL == dvb_attach(xc5000_attach, - fe1->dvb.frontend, - &i2c_bus->i2c_adap, - &netup_xc5000_config[port->nr - 1])) - goto frontend_detach; - } - break; - case CX23885_BOARD_TERRATEC_CINERGY_T_PCIE_DUAL: - i2c_bus = &dev->i2c_bus[0]; - i2c_bus2 = &dev->i2c_bus[1]; - - switch (port->nr) { - /* port b */ - case 1: - fe0->dvb.frontend = dvb_attach(drxk_attach, - &terratec_drxk_config[0], - &i2c_bus->i2c_adap); - if (fe0->dvb.frontend != NULL) { - if (!dvb_attach(mt2063_attach, - fe0->dvb.frontend, - &terratec_mt2063_config[0], - &i2c_bus2->i2c_adap)) - goto frontend_detach; - } - break; - /* port c */ - case 2: - fe0->dvb.frontend = dvb_attach(drxk_attach, - &terratec_drxk_config[1], - &i2c_bus->i2c_adap); - if (fe0->dvb.frontend != NULL) { - if (!dvb_attach(mt2063_attach, - fe0->dvb.frontend, - &terratec_mt2063_config[1], - &i2c_bus2->i2c_adap)) - goto frontend_detach; - } - break; - } - break; - case CX23885_BOARD_TEVII_S471: - i2c_bus = &dev->i2c_bus[1]; - - fe0->dvb.frontend = dvb_attach(ds3000_attach, - &tevii_ds3000_config, - &i2c_bus->i2c_adap); - break; - default: - printk(KERN_INFO "%s: The frontend of your DVB/ATSC card " - " isn't supported yet\n", - dev->name); - break; - } - - if ((NULL == fe0->dvb.frontend) || (fe1 && NULL == fe1->dvb.frontend)) { - printk(KERN_ERR "%s: frontend initialization failed\n", - dev->name); - goto frontend_detach; - } - - /* define general-purpose callback pointer */ - fe0->dvb.frontend->callback = cx23885_tuner_callback; - if (fe1) - fe1->dvb.frontend->callback = cx23885_tuner_callback; -#if 0 - /* Ensure all frontends negotiate bus access */ - fe0->dvb.frontend->ops.ts_bus_ctrl = cx23885_dvb_bus_ctrl; - if (fe1) - fe1->dvb.frontend->ops.ts_bus_ctrl = cx23885_dvb_bus_ctrl; -#endif - - /* Put the analog decoder in standby to keep it quiet */ - call_all(dev, core, s_power, 0); - - if (fe0->dvb.frontend->ops.analog_ops.standby) - fe0->dvb.frontend->ops.analog_ops.standby(fe0->dvb.frontend); - - /* register everything */ - ret = videobuf_dvb_register_bus(&port->frontends, THIS_MODULE, port, - &dev->pci->dev, adapter_nr, mfe_shared); - if (ret) - goto frontend_detach; - - /* init CI & MAC */ - switch (dev->board) { - case CX23885_BOARD_NETUP_DUAL_DVBS2_CI: { - static struct netup_card_info cinfo; - - netup_get_card_info(&dev->i2c_bus[0].i2c_adap, &cinfo); - memcpy(port->frontends.adapter.proposed_mac, - cinfo.port[port->nr - 1].mac, 6); - printk(KERN_INFO "NetUP Dual DVB-S2 CI card port%d MAC=%pM\n", - port->nr, port->frontends.adapter.proposed_mac); - - netup_ci_init(port); - break; - } - case CX23885_BOARD_NETUP_DUAL_DVB_T_C_CI_RF: { - struct altera_ci_config netup_ci_cfg = { - .dev = dev,/* magic number to identify*/ - .adapter = &port->frontends.adapter,/* for CI */ - .demux = &fe0->dvb.demux,/* for hw pid filter */ - .fpga_rw = netup_altera_fpga_rw, - }; - - altera_ci_init(&netup_ci_cfg, port->nr); - break; - } - case CX23885_BOARD_TEVII_S470: { - u8 eeprom[256]; /* 24C02 i2c eeprom */ - - if (port->nr != 1) - break; - - /* Read entire EEPROM */ - dev->i2c_bus[0].i2c_client.addr = 0xa0 >> 1; - tveeprom_read(&dev->i2c_bus[0].i2c_client, eeprom, sizeof(eeprom)); - printk(KERN_INFO "TeVii S470 MAC= %pM\n", eeprom + 0xa0); - memcpy(port->frontends.adapter.proposed_mac, eeprom + 0xa0, 6); - break; - } - } - - return ret; - -frontend_detach: - port->gate_ctrl = NULL; - videobuf_dvb_dealloc_frontends(&port->frontends); - return -EINVAL; -} - -int cx23885_dvb_register(struct cx23885_tsport *port) -{ - - struct videobuf_dvb_frontend *fe0; - struct cx23885_dev *dev = port->dev; - int err, i; - - /* Here we need to allocate the correct number of frontends, - * as reflected in the cards struct. The reality is that currently - * no cx23885 boards support this - yet. But, if we don't modify this - * code then the second frontend would never be allocated (later) - * and fail with error before the attach in dvb_register(). - * Without these changes we risk an OOPS later. The changes here - * are for safety, and should provide a good foundation for the - * future addition of any multi-frontend cx23885 based boards. - */ - printk(KERN_INFO "%s() allocating %d frontend(s)\n", __func__, - port->num_frontends); - - for (i = 1; i <= port->num_frontends; i++) { - if (videobuf_dvb_alloc_frontend( - &port->frontends, i) == NULL) { - printk(KERN_ERR "%s() failed to alloc\n", __func__); - return -ENOMEM; - } - - fe0 = videobuf_dvb_get_frontend(&port->frontends, i); - if (!fe0) - err = -EINVAL; - - dprintk(1, "%s\n", __func__); - dprintk(1, " ->probed by Card=%d Name=%s, PCI %02x:%02x\n", - dev->board, - dev->name, - dev->pci_bus, - dev->pci_slot); - - err = -ENODEV; - - /* dvb stuff */ - /* We have to init the queue for each frontend on a port. */ - printk(KERN_INFO "%s: cx23885 based dvb card\n", dev->name); - videobuf_queue_sg_init(&fe0->dvb.dvbq, &dvb_qops, - &dev->pci->dev, &port->slock, - V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_TOP, - sizeof(struct cx23885_buffer), port, NULL); - } - err = dvb_register(port); - if (err != 0) - printk(KERN_ERR "%s() dvb_register failed err = %d\n", - __func__, err); - - return err; -} - -int cx23885_dvb_unregister(struct cx23885_tsport *port) -{ - struct videobuf_dvb_frontend *fe0; - - /* FIXME: in an error condition where the we have - * an expected number of frontends (attach problem) - * then this might not clean up correctly, if 1 - * is invalid. - * This comment only applies to future boards IF they - * implement MFE support. - */ - fe0 = videobuf_dvb_get_frontend(&port->frontends, 1); - if (fe0 && fe0->dvb.frontend) - videobuf_dvb_unregister_bus(&port->frontends); - - switch (port->dev->board) { - case CX23885_BOARD_NETUP_DUAL_DVBS2_CI: - netup_ci_exit(port); - break; - case CX23885_BOARD_NETUP_DUAL_DVB_T_C_CI_RF: - altera_ci_release(port->dev, port->nr); - break; - } - - port->gate_ctrl = NULL; - - return 0; -} - diff --git a/drivers/media/video/cx23885/cx23885-f300.c b/drivers/media/video/cx23885/cx23885-f300.c deleted file mode 100644 index 93998f22098..00000000000 --- a/drivers/media/video/cx23885/cx23885-f300.c +++ /dev/null @@ -1,177 +0,0 @@ -/* - * Driver for Silicon Labs C8051F300 microcontroller. - * - * It is used for LNB power control in TeVii S470, - * TBS 6920 PCIe DVB-S2 cards. - * - * Microcontroller connected to cx23885 GPIO pins: - * GPIO0 - data - P0.3 F300 - * GPIO1 - reset - P0.2 F300 - * GPIO2 - clk - P0.1 F300 - * GPIO3 - busy - P0.0 F300 - * - * Copyright (C) 2009 Igor M. Liplianin <liplianin@me.by> - * - * 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 "cx23885.h" - -#define F300_DATA GPIO_0 -#define F300_RESET GPIO_1 -#define F300_CLK GPIO_2 -#define F300_BUSY GPIO_3 - -static void f300_set_line(struct cx23885_dev *dev, u32 line, u8 lvl) -{ - cx23885_gpio_enable(dev, line, 1); - if (lvl == 1) - cx23885_gpio_set(dev, line); - else - cx23885_gpio_clear(dev, line); -} - -static u8 f300_get_line(struct cx23885_dev *dev, u32 line) -{ - cx23885_gpio_enable(dev, line, 0); - - return cx23885_gpio_get(dev, line); -} - -static void f300_send_byte(struct cx23885_dev *dev, u8 dta) -{ - u8 i; - - for (i = 0; i < 8; i++) { - f300_set_line(dev, F300_CLK, 0); - udelay(30); - f300_set_line(dev, F300_DATA, (dta & 0x80) >> 7);/* msb first */ - udelay(30); - dta <<= 1; - f300_set_line(dev, F300_CLK, 1); - udelay(30); - } -} - -static u8 f300_get_byte(struct cx23885_dev *dev) -{ - u8 i, dta = 0; - - for (i = 0; i < 8; i++) { - f300_set_line(dev, F300_CLK, 0); - udelay(30); - dta <<= 1; - f300_set_line(dev, F300_CLK, 1); - udelay(30); - dta |= f300_get_line(dev, F300_DATA);/* msb first */ - - } - - return dta; -} - -static u8 f300_xfer(struct dvb_frontend *fe, u8 *buf) -{ - struct cx23885_tsport *port = fe->dvb->priv; - struct cx23885_dev *dev = port->dev; - u8 i, temp, ret = 0; - - temp = buf[0]; - for (i = 0; i < buf[0]; i++) - temp += buf[i + 1]; - temp = (~temp + 1);/* get check sum */ - buf[1 + buf[0]] = temp; - - f300_set_line(dev, F300_RESET, 1); - f300_set_line(dev, F300_CLK, 1); - udelay(30); - f300_set_line(dev, F300_DATA, 1); - msleep(1); - - /* question: */ - f300_set_line(dev, F300_RESET, 0);/* begin to send data */ - msleep(1); - - f300_send_byte(dev, 0xe0);/* the slave address is 0xe0, write */ - msleep(1); - - temp = buf[0]; - temp += 2; - for (i = 0; i < temp; i++) - f300_send_byte(dev, buf[i]); - - f300_set_line(dev, F300_RESET, 1);/* sent data over */ - f300_set_line(dev, F300_DATA, 1); - - /* answer: */ - temp = 0; - for (i = 0; ((i < 8) & (temp == 0)); i++) { - msleep(1); - if (f300_get_line(dev, F300_BUSY) == 0) - temp = 1; - } - - if (i > 7) { - printk(KERN_ERR "%s: timeout, the slave no response\n", - __func__); - ret = 1; /* timeout, the slave no response */ - } else { /* the slave not busy, prepare for getting data */ - f300_set_line(dev, F300_RESET, 0);/*ready...*/ - msleep(1); - f300_send_byte(dev, 0xe1);/* 0xe1 is Read */ - msleep(1); - temp = f300_get_byte(dev);/*get the data length */ - if (temp > 14) - temp = 14; - - for (i = 0; i < (temp + 1); i++) - f300_get_byte(dev);/* get data to empty buffer */ - - f300_set_line(dev, F300_RESET, 1);/* received data over */ - f300_set_line(dev, F300_DATA, 1); - } - - return ret; -} - -int f300_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) -{ - u8 buf[16]; - - buf[0] = 0x05; - buf[1] = 0x38;/* write port */ - buf[2] = 0x01;/* A port, lnb power */ - - switch (voltage) { - case SEC_VOLTAGE_13: - buf[3] = 0x01;/* power on */ - buf[4] = 0x02;/* B port, H/V */ - buf[5] = 0x00;/*13V v*/ - break; - case SEC_VOLTAGE_18: - buf[3] = 0x01; - buf[4] = 0x02; - buf[5] = 0x01;/* 18V h*/ - break; - case SEC_VOLTAGE_OFF: - buf[3] = 0x00;/* power off */ - buf[4] = 0x00; - buf[5] = 0x00; - break; - } - - return f300_xfer(fe, buf); -} diff --git a/drivers/media/video/cx23885/cx23885-f300.h b/drivers/media/video/cx23885/cx23885-f300.h deleted file mode 100644 index e73344c9496..00000000000 --- a/drivers/media/video/cx23885/cx23885-f300.h +++ /dev/null @@ -1,2 +0,0 @@ -extern int f300_set_voltage(struct dvb_frontend *fe, - fe_sec_voltage_t voltage); diff --git a/drivers/media/video/cx23885/cx23885-i2c.c b/drivers/media/video/cx23885/cx23885-i2c.c deleted file mode 100644 index 4887314339c..00000000000 --- a/drivers/media/video/cx23885/cx23885-i2c.c +++ /dev/null @@ -1,396 +0,0 @@ -/* - * Driver for the Conexant CX23885 PCIe bridge - * - * Copyright (c) 2006 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 <linux/module.h> -#include <linux/moduleparam.h> -#include <linux/init.h> -#include <linux/delay.h> -#include <asm/io.h> - -#include "cx23885.h" - -#include <media/v4l2-common.h> - -static unsigned int i2c_debug; -module_param(i2c_debug, int, 0644); -MODULE_PARM_DESC(i2c_debug, "enable debug messages [i2c]"); - -static unsigned int i2c_scan; -module_param(i2c_scan, int, 0444); -MODULE_PARM_DESC(i2c_scan, "scan i2c bus at insmod time"); - -#define dprintk(level, fmt, arg...)\ - do { if (i2c_debug >= level)\ - printk(KERN_DEBUG "%s/0: " fmt, dev->name, ## arg);\ - } while (0) - -#define I2C_WAIT_DELAY 32 -#define I2C_WAIT_RETRY 64 - -#define I2C_EXTEND (1 << 3) -#define I2C_NOSTOP (1 << 4) - -static inline int i2c_slave_did_ack(struct i2c_adapter *i2c_adap) -{ - struct cx23885_i2c *bus = i2c_adap->algo_data; - struct cx23885_dev *dev = bus->dev; - return cx_read(bus->reg_stat) & 0x01; -} - -static inline int i2c_is_busy(struct i2c_adapter *i2c_adap) -{ - struct cx23885_i2c *bus = i2c_adap->algo_data; - struct cx23885_dev *dev = bus->dev; - return cx_read(bus->reg_stat) & 0x02 ? 1 : 0; -} - -static int i2c_wait_done(struct i2c_adapter *i2c_adap) -{ - int count; - - for (count = 0; count < I2C_WAIT_RETRY; count++) { - if (!i2c_is_busy(i2c_adap)) - break; - udelay(I2C_WAIT_DELAY); - } - - if (I2C_WAIT_RETRY == count) - return 0; - - return 1; -} - -static int i2c_sendbytes(struct i2c_adapter *i2c_adap, - const struct i2c_msg *msg, int joined_rlen) -{ - struct cx23885_i2c *bus = i2c_adap->algo_data; - struct cx23885_dev *dev = bus->dev; - u32 wdata, addr, ctrl; - int retval, cnt; - - if (joined_rlen) - dprintk(1, "%s(msg->wlen=%d, nextmsg->rlen=%d)\n", __func__, - msg->len, joined_rlen); - else - dprintk(1, "%s(msg->len=%d)\n", __func__, msg->len); - - /* Deal with i2c probe functions with zero payload */ - if (msg->len == 0) { - cx_write(bus->reg_addr, msg->addr << 25); - cx_write(bus->reg_ctrl, bus->i2c_period | (1 << 2)); - if (!i2c_wait_done(i2c_adap)) - return -EIO; - if (!i2c_slave_did_ack(i2c_adap)) - return -ENXIO; - - dprintk(1, "%s() returns 0\n", __func__); - return 0; - } - - - /* dev, reg + first byte */ - addr = (msg->addr << 25) | msg->buf[0]; - wdata = msg->buf[0]; - ctrl = bus->i2c_period | (1 << 12) | (1 << 2); - - if (msg->len > 1) - ctrl |= I2C_NOSTOP | I2C_EXTEND; - else if (joined_rlen) - ctrl |= I2C_NOSTOP; - - cx_write(bus->reg_addr, addr); - cx_write(bus->reg_wdata, wdata); - cx_write(bus->reg_ctrl, ctrl); - - if (!i2c_wait_done(i2c_adap)) - goto eio; - if (i2c_debug) { - printk(" <W %02x %02x", msg->addr << 1, msg->buf[0]); - if (!(ctrl & I2C_NOSTOP)) - printk(" >\n"); - } - - for (cnt = 1; cnt < msg->len; cnt++) { - /* following bytes */ - wdata = msg->buf[cnt]; - ctrl = bus->i2c_period | (1 << 12) | (1 << 2); - - if (cnt < msg->len - 1) - ctrl |= I2C_NOSTOP | I2C_EXTEND; - else if (joined_rlen) - ctrl |= I2C_NOSTOP; - - cx_write(bus->reg_addr, addr); - cx_write(bus->reg_wdata, wdata); - cx_write(bus->reg_ctrl, ctrl); - - if (!i2c_wait_done(i2c_adap)) - goto eio; - if (i2c_debug) { - dprintk(1, " %02x", msg->buf[cnt]); - if (!(ctrl & I2C_NOSTOP)) - dprintk(1, " >\n"); - } - } - return msg->len; - - eio: - retval = -EIO; - if (i2c_debug) - printk(KERN_ERR " ERR: %d\n", retval); - return retval; -} - -static int i2c_readbytes(struct i2c_adapter *i2c_adap, - const struct i2c_msg *msg, int joined) -{ - struct cx23885_i2c *bus = i2c_adap->algo_data; - struct cx23885_dev *dev = bus->dev; - u32 ctrl, cnt; - int retval; - - - if (i2c_debug && !joined) - dprintk(1, "%s(msg->len=%d)\n", __func__, msg->len); - - /* Deal with i2c probe functions with zero payload */ - if (msg->len == 0) { - cx_write(bus->reg_addr, msg->addr << 25); - cx_write(bus->reg_ctrl, bus->i2c_period | (1 << 2) | 1); - if (!i2c_wait_done(i2c_adap)) - return -EIO; - if (!i2c_slave_did_ack(i2c_adap)) - return -ENXIO; - - - dprintk(1, "%s() returns 0\n", __func__); - return 0; - } - - if (i2c_debug) { - if (joined) - dprintk(1, " R"); - else - dprintk(1, " <R %02x", (msg->addr << 1) + 1); - } - - for (cnt = 0; cnt < msg->len; cnt++) { - - ctrl = bus->i2c_period | (1 << 12) | (1 << 2) | 1; - - if (cnt < msg->len - 1) - ctrl |= I2C_NOSTOP | I2C_EXTEND; - - cx_write(bus->reg_addr, msg->addr << 25); - cx_write(bus->reg_ctrl, ctrl); - - if (!i2c_wait_done(i2c_adap)) - goto eio; - msg->buf[cnt] = cx_read(bus->reg_rdata) & 0xff; - if (i2c_debug) { - dprintk(1, " %02x", msg->buf[cnt]); - if (!(ctrl & I2C_NOSTOP)) - dprintk(1, " >\n"); - } - } - return msg->len; - - eio: - retval = -EIO; - if (i2c_debug) - printk(KERN_ERR " ERR: %d\n", retval); - return retval; -} - -static int i2c_xfer(struct i2c_adapter *i2c_adap, - struct i2c_msg *msgs, int num) -{ - struct cx23885_i2c *bus = i2c_adap->algo_data; - struct cx23885_dev *dev = bus->dev; - int i, retval = 0; - - dprintk(1, "%s(num = %d)\n", __func__, num); - - for (i = 0 ; i < num; i++) { - dprintk(1, "%s(num = %d) addr = 0x%02x len = 0x%x\n", - __func__, num, msgs[i].addr, msgs[i].len); - if (msgs[i].flags & I2C_M_RD) { - /* read */ - retval = i2c_readbytes(i2c_adap, &msgs[i], 0); - } else if (i + 1 < num && (msgs[i + 1].flags & I2C_M_RD) && - msgs[i].addr == msgs[i + 1].addr) { - /* write then read from same address */ - retval = i2c_sendbytes(i2c_adap, &msgs[i], - msgs[i + 1].len); - if (retval < 0) - goto err; - i++; - retval = i2c_readbytes(i2c_adap, &msgs[i], 1); - } else { - /* write */ - retval = i2c_sendbytes(i2c_adap, &msgs[i], 0); - } - if (retval < 0) - goto err; - } - return num; - - err: - return retval; -} - -static u32 cx23885_functionality(struct i2c_adapter *adap) -{ - return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_I2C; -} - -static struct i2c_algorithm cx23885_i2c_algo_template = { - .master_xfer = i2c_xfer, - .functionality = cx23885_functionality, -}; - -/* ----------------------------------------------------------------------- */ - -static struct i2c_adapter cx23885_i2c_adap_template = { - .name = "cx23885", - .owner = THIS_MODULE, - .algo = &cx23885_i2c_algo_template, -}; - -static struct i2c_client cx23885_i2c_client_template = { - .name = "cx23885 internal", -}; - -static char *i2c_devs[128] = { - [0x10 >> 1] = "tda10048", - [0x12 >> 1] = "dib7000pc", - [0x1c >> 1] = "lgdt3303", - [0x86 >> 1] = "tda9887", - [0x32 >> 1] = "cx24227", - [0x88 >> 1] = "cx25837", - [0x84 >> 1] = "tda8295", - [0x98 >> 1] = "flatiron", - [0xa0 >> 1] = "eeprom", - [0xc0 >> 1] = "tuner/mt2131/tda8275", - [0xc2 >> 1] = "tuner/mt2131/tda8275/xc5000/xc3028", - [0xc8 >> 1] = "tuner/xc3028L", -}; - -static void do_i2c_scan(char *name, struct i2c_client *c) -{ - unsigned char buf; - int i, rc; - - for (i = 0; i < 128; i++) { - c->addr = i; - rc = i2c_master_recv(c, &buf, 0); - if (rc < 0) - continue; - printk(KERN_INFO "%s: i2c scan: found device @ 0x%x [%s]\n", - name, i << 1, i2c_devs[i] ? i2c_devs[i] : "???"); - } -} - -/* init + register i2c adapter */ -int cx23885_i2c_register(struct cx23885_i2c *bus) -{ - struct cx23885_dev *dev = bus->dev; - - dprintk(1, "%s(bus = %d)\n", __func__, bus->nr); - - bus->i2c_adap = cx23885_i2c_adap_template; - bus->i2c_client = cx23885_i2c_client_template; - bus->i2c_adap.dev.parent = &dev->pci->dev; - - strlcpy(bus->i2c_adap.name, bus->dev->name, - sizeof(bus->i2c_adap.name)); - - bus->i2c_adap.algo_data = bus; - i2c_set_adapdata(&bus->i2c_adap, &dev->v4l2_dev); - i2c_add_adapter(&bus->i2c_adap); - - bus->i2c_client.adapter = &bus->i2c_adap; - - if (0 == bus->i2c_rc) { - dprintk(1, "%s: i2c bus %d registered\n", dev->name, bus->nr); - if (i2c_scan) { - printk(KERN_INFO "%s: scan bus %d:\n", - dev->name, bus->nr); - do_i2c_scan(dev->name, &bus->i2c_client); - } - } else - printk(KERN_WARNING "%s: i2c bus %d register FAILED\n", - dev->name, bus->nr); - - /* Instantiate the IR receiver device, if present */ - if (0 == bus->i2c_rc) { - struct i2c_board_info info; - const unsigned short addr_list[] = { - 0x6b, I2C_CLIENT_END - }; - - memset(&info, 0, sizeof(struct i2c_board_info)); - strlcpy(info.type, "ir_video", I2C_NAME_SIZE); - /* Use quick read command for probe, some IR chips don't - * support writes */ - i2c_new_probed_device(&bus->i2c_adap, &info, addr_list, - i2c_probe_func_quick_read); - } - - return bus->i2c_rc; -} - -int cx23885_i2c_unregister(struct cx23885_i2c *bus) -{ - i2c_del_adapter(&bus->i2c_adap); - return 0; -} - -void cx23885_av_clk(struct cx23885_dev *dev, int enable) -{ - /* write 0 to bus 2 addr 0x144 via i2x_xfer() */ - char buffer[3]; - struct i2c_msg msg; - dprintk(1, "%s(enabled = %d)\n", __func__, enable); - - /* Register 0x144 */ - buffer[0] = 0x01; - buffer[1] = 0x44; - if (enable == 1) - buffer[2] = 0x05; - else - buffer[2] = 0x00; - - msg.addr = 0x44; - msg.flags = I2C_M_TEN; - msg.len = 3; - msg.buf = buffer; - - i2c_xfer(&dev->i2c_bus[2].i2c_adap, &msg, 1); -} - -/* ----------------------------------------------------------------------- */ - -/* - * Local variables: - * c-basic-offset: 8 - * End: - */ diff --git a/drivers/media/video/cx23885/cx23885-input.c b/drivers/media/video/cx23885/cx23885-input.c deleted file mode 100644 index 56066721edc..00000000000 --- a/drivers/media/video/cx23885/cx23885-input.c +++ /dev/null @@ -1,365 +0,0 @@ -/* - * Driver for the Conexant CX23885/7/8 PCIe bridge - * - * Infrared remote control input device - * - * Most of this file is - * - * Copyright (C) 2009 Andy Walls <awalls@md.metrocast.net> - * - * However, the cx23885_input_{init,fini} functions contained herein are - * derived from Linux kernel files linux/media/video/.../...-input.c marked as: - * - * Copyright (C) 2008 <srinivasa.deevi at conexant dot com> - * Copyright (C) 2005 Ludovico Cavedon <cavedon@sssup.it> - * Markus Rechberger <mrechberger@gmail.com> - * Mauro Carvalho Chehab <mchehab@infradead.org> - * Sascha Sommer <saschasommer@freenet.de> - * Copyright (C) 2004, 2005 Chris Pascoe - * Copyright (C) 2003, 2004 Gerd Knorr - * Copyright (C) 2003 Pavel Machek - * - * 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 <linux/slab.h> -#include <media/rc-core.h> -#include <media/v4l2-subdev.h> - -#include "cx23885.h" - -#define MODULE_NAME "cx23885" - -static void cx23885_input_process_measurements(struct cx23885_dev *dev, - bool overrun) -{ - struct cx23885_kernel_ir *kernel_ir = dev->kernel_ir; - - ssize_t num; - int count, i; - bool handle = false; - struct ir_raw_event ir_core_event[64]; - - do { - num = 0; - v4l2_subdev_call(dev->sd_ir, ir, rx_read, (u8 *) ir_core_event, - sizeof(ir_core_event), &num); - - count = num / sizeof(struct ir_raw_event); - - for (i = 0; i < count; i++) { - ir_raw_event_store(kernel_ir->rc, - &ir_core_event[i]); - handle = true; - } - } while (num != 0); - - if (overrun) - ir_raw_event_reset(kernel_ir->rc); - else if (handle) - ir_raw_event_handle(kernel_ir->rc); -} - -void cx23885_input_rx_work_handler(struct cx23885_dev *dev, u32 events) -{ - struct v4l2_subdev_ir_parameters params; - int overrun, data_available; - - if (dev->sd_ir == NULL || events == 0) - return; - - switch (dev->board) { - case CX23885_BOARD_HAUPPAUGE_HVR1270: - case CX23885_BOARD_HAUPPAUGE_HVR1850: - case CX23885_BOARD_HAUPPAUGE_HVR1290: - case CX23885_BOARD_TERRATEC_CINERGY_T_PCIE_DUAL: - case CX23885_BOARD_TEVII_S470: - case CX23885_BOARD_HAUPPAUGE_HVR1250: - /* - * The only boards we handle right now. However other boards - * using the CX2388x integrated IR controller should be similar - */ - break; - default: - return; - } - - overrun = events & (V4L2_SUBDEV_IR_RX_SW_FIFO_OVERRUN | - V4L2_SUBDEV_IR_RX_HW_FIFO_OVERRUN); - - data_available = events & (V4L2_SUBDEV_IR_RX_END_OF_RX_DETECTED | - V4L2_SUBDEV_IR_RX_FIFO_SERVICE_REQ); - - if (overrun) { - /* If there was a FIFO overrun, stop the device */ - v4l2_subdev_call(dev->sd_ir, ir, rx_g_parameters, ¶ms); - params.enable = false; - /* Mitigate race with cx23885_input_ir_stop() */ - params.shutdown = atomic_read(&dev->ir_input_stopping); - v4l2_subdev_call(dev->sd_ir, ir, rx_s_parameters, ¶ms); - } - - if (data_available) - cx23885_input_process_measurements(dev, overrun); - - if (overrun) { - /* If there was a FIFO overrun, clear & restart the device */ - params.enable = true; - /* Mitigate race with cx23885_input_ir_stop() */ - params.shutdown = atomic_read(&dev->ir_input_stopping); - v4l2_subdev_call(dev->sd_ir, ir, rx_s_parameters, ¶ms); - } -} - -static int cx23885_input_ir_start(struct cx23885_dev *dev) -{ - struct v4l2_subdev_ir_parameters params; - - if (dev->sd_ir == NULL) - return -ENODEV; - - atomic_set(&dev->ir_input_stopping, 0); - - v4l2_subdev_call(dev->sd_ir, ir, rx_g_parameters, ¶ms); - switch (dev->board) { - case CX23885_BOARD_HAUPPAUGE_HVR1270: - case CX23885_BOARD_HAUPPAUGE_HVR1850: - case CX23885_BOARD_HAUPPAUGE_HVR1290: - case CX23885_BOARD_HAUPPAUGE_HVR1250: - /* - * The IR controller on this board only returns pulse widths. - * Any other mode setting will fail to set up the device. - */ - params.mode = V4L2_SUBDEV_IR_MODE_PULSE_WIDTH; - params.enable = true; - params.interrupt_enable = true; - params.shutdown = false; - - /* Setup for baseband compatible with both RC-5 and RC-6A */ - params.modulation = false; - /* RC-5: 2,222,222 ns = 1/36 kHz * 32 cycles * 2 marks * 1.25*/ - /* RC-6A: 3,333,333 ns = 1/36 kHz * 16 cycles * 6 marks * 1.25*/ - params.max_pulse_width = 3333333; /* ns */ - /* RC-5: 666,667 ns = 1/36 kHz * 32 cycles * 1 mark * 0.75 */ - /* RC-6A: 333,333 ns = 1/36 kHz * 16 cycles * 1 mark * 0.75 */ - params.noise_filter_min_width = 333333; /* ns */ - /* - * This board has inverted receive sense: - * mark is received as low logic level; - * falling edges are detected as rising edges; etc. - */ - params.invert_level = true; - break; - case CX23885_BOARD_TERRATEC_CINERGY_T_PCIE_DUAL: - case CX23885_BOARD_TEVII_S470: - /* - * The IR controller on this board only returns pulse widths. - * Any other mode setting will fail to set up the device. - */ - params.mode = V4L2_SUBDEV_IR_MODE_PULSE_WIDTH; - params.enable = true; - params.interrupt_enable = true; - params.shutdown = false; - - /* Setup for a standard NEC protocol */ - params.carrier_freq = 37917; /* Hz, 455 kHz/12 for NEC */ - params.carrier_range_lower = 33000; /* Hz */ - params.carrier_range_upper = 43000; /* Hz */ - params.duty_cycle = 33; /* percent, 33 percent for NEC */ - - /* - * NEC max pulse width: (64/3)/(455 kHz/12) * 16 nec_units - * (64/3)/(455 kHz/12) * 16 nec_units * 1.375 = 12378022 ns - */ - params.max_pulse_width = 12378022; /* ns */ - - /* - * NEC noise filter min width: (64/3)/(455 kHz/12) * 1 nec_unit - * (64/3)/(455 kHz/12) * 1 nec_units * 0.625 = 351648 ns - */ - params.noise_filter_min_width = 351648; /* ns */ - - params.modulation = false; - params.invert_level = true; - break; - } - v4l2_subdev_call(dev->sd_ir, ir, rx_s_parameters, ¶ms); - return 0; -} - -static int cx23885_input_ir_open(struct rc_dev *rc) -{ - struct cx23885_kernel_ir *kernel_ir = rc->priv; - - if (kernel_ir->cx == NULL) - return -ENODEV; - - return cx23885_input_ir_start(kernel_ir->cx); -} - -static void cx23885_input_ir_stop(struct cx23885_dev *dev) -{ - struct v4l2_subdev_ir_parameters params; - - if (dev->sd_ir == NULL) - return; - - /* - * Stop the sd_ir subdevice from generating notifications and - * scheduling work. - * It is shutdown this way in order to mitigate a race with - * cx23885_input_rx_work_handler() in the overrun case, which could - * re-enable the subdevice. - */ - atomic_set(&dev->ir_input_stopping, 1); - v4l2_subdev_call(dev->sd_ir, ir, rx_g_parameters, ¶ms); - while (params.shutdown == false) { - params.enable = false; - params.interrupt_enable = false; - params.shutdown = true; - v4l2_subdev_call(dev->sd_ir, ir, rx_s_parameters, ¶ms); - v4l2_subdev_call(dev->sd_ir, ir, rx_g_parameters, ¶ms); - } - flush_work_sync(&dev->cx25840_work); - flush_work_sync(&dev->ir_rx_work); - flush_work_sync(&dev->ir_tx_work); -} - -static void cx23885_input_ir_close(struct rc_dev *rc) -{ - struct cx23885_kernel_ir *kernel_ir = rc->priv; - - if (kernel_ir->cx != NULL) - cx23885_input_ir_stop(kernel_ir->cx); -} - -int cx23885_input_init(struct cx23885_dev *dev) -{ - struct cx23885_kernel_ir *kernel_ir; - struct rc_dev *rc; - char *rc_map; - enum rc_driver_type driver_type; - unsigned long allowed_protos; - - int ret; - - /* - * If the IR device (hardware registers, chip, GPIO lines, etc.) isn't - * encapsulated in a v4l2_subdev, then I'm not going to deal with it. - */ - if (dev->sd_ir == NULL) - return -ENODEV; - - switch (dev->board) { - case CX23885_BOARD_HAUPPAUGE_HVR1270: - case CX23885_BOARD_HAUPPAUGE_HVR1850: - case CX23885_BOARD_HAUPPAUGE_HVR1290: - case CX23885_BOARD_HAUPPAUGE_HVR1250: - /* Integrated CX2388[58] IR controller */ - driver_type = RC_DRIVER_IR_RAW; - allowed_protos = RC_TYPE_ALL; - /* The grey Hauppauge RC-5 remote */ - rc_map = RC_MAP_HAUPPAUGE; - break; - case CX23885_BOARD_TERRATEC_CINERGY_T_PCIE_DUAL: - /* Integrated CX23885 IR controller */ - driver_type = RC_DRIVER_IR_RAW; - allowed_protos = RC_TYPE_NEC; - /* The grey Terratec remote with orange buttons */ - rc_map = RC_MAP_NEC_TERRATEC_CINERGY_XS; - break; - case CX23885_BOARD_TEVII_S470: - /* Integrated CX23885 IR controller */ - driver_type = RC_DRIVER_IR_RAW; - allowed_protos = RC_TYPE_ALL; - /* A guess at the remote */ - rc_map = RC_MAP_TEVII_NEC; - break; - default: - return -ENODEV; - } - - /* cx23885 board instance kernel IR state */ - kernel_ir = kzalloc(sizeof(struct cx23885_kernel_ir), GFP_KERNEL); - if (kernel_ir == NULL) - return -ENOMEM; - - kernel_ir->cx = dev; - kernel_ir->name = kasprintf(GFP_KERNEL, "cx23885 IR (%s)", - cx23885_boards[dev->board].name); - kernel_ir->phys = kasprintf(GFP_KERNEL, "pci-%s/ir0", - pci_name(dev->pci)); - - /* input device */ - rc = rc_allocate_device(); - if (!rc) { - ret = -ENOMEM; - goto err_out_free; - } - - kernel_ir->rc = rc; - rc->input_name = kernel_ir->name; - rc->input_phys = kernel_ir->phys; - rc->input_id.bustype = BUS_PCI; - rc->input_id.version = 1; - if (dev->pci->subsystem_vendor) { - rc->input_id.vendor = dev->pci->subsystem_vendor; - rc->input_id.product = dev->pci->subsystem_device; - } else { - rc->input_id.vendor = dev->pci->vendor; - rc->input_id.product = dev->pci->device; - } - rc->dev.parent = &dev->pci->dev; - rc->driver_type = driver_type; - rc->allowed_protos = allowed_protos; - rc->priv = kernel_ir; - rc->open = cx23885_input_ir_open; - rc->close = cx23885_input_ir_close; - rc->map_name = rc_map; - rc->driver_name = MODULE_NAME; - - /* Go */ - dev->kernel_ir = kernel_ir; - ret = rc_register_device(rc); - if (ret) - goto err_out_stop; - - return 0; - -err_out_stop: - cx23885_input_ir_stop(dev); - dev->kernel_ir = NULL; - rc_free_device(rc); -err_out_free: - kfree(kernel_ir->phys); - kfree(kernel_ir->name); - kfree(kernel_ir); - return ret; -} - -void cx23885_input_fini(struct cx23885_dev *dev) -{ - /* Always stop the IR hardware from generating interrupts */ - cx23885_input_ir_stop(dev); - - if (dev->kernel_ir == NULL) - return; - rc_unregister_device(dev->kernel_ir->rc); - kfree(dev->kernel_ir->phys); - kfree(dev->kernel_ir->name); - kfree(dev->kernel_ir); - dev->kernel_ir = NULL; -} diff --git a/drivers/media/video/cx23885/cx23885-input.h b/drivers/media/video/cx23885/cx23885-input.h deleted file mode 100644 index 75ef15d3f52..00000000000 --- a/drivers/media/video/cx23885/cx23885-input.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Driver for the Conexant CX23885/7/8 PCIe bridge - * - * Infrared remote control input device - * - * Copyright (C) 2009 Andy Walls <awalls@md.metrocast.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 _CX23885_INPUT_H_ -#define _CX23885_INPUT_H_ -int cx23885_input_rx_work_handler(struct cx23885_dev *dev, u32 events); - -int cx23885_input_init(struct cx23885_dev *dev); -void cx23885_input_fini(struct cx23885_dev *dev); -#endif diff --git a/drivers/media/video/cx23885/cx23885-ioctl.c b/drivers/media/video/cx23885/cx23885-ioctl.c deleted file mode 100644 index 44812ca7889..00000000000 --- a/drivers/media/video/cx23885/cx23885-ioctl.c +++ /dev/null @@ -1,208 +0,0 @@ -/* - * Driver for the Conexant CX23885/7/8 PCIe bridge - * - * Various common ioctl() support functions - * - * Copyright (c) 2009 Andy Walls <awalls@md.metrocast.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 "cx23885.h" -#include <media/v4l2-chip-ident.h> - -int cx23885_g_chip_ident(struct file *file, void *fh, - struct v4l2_dbg_chip_ident *chip) -{ - struct cx23885_dev *dev = ((struct cx23885_fh *)fh)->dev; - int err = 0; - u8 rev; - - chip->ident = V4L2_IDENT_NONE; - chip->revision = 0; - switch (chip->match.type) { - case V4L2_CHIP_MATCH_HOST: - switch (chip->match.addr) { - case 0: - rev = cx_read(RDR_CFG2) & 0xff; - switch (dev->pci->device) { - case 0x8852: - /* rev 0x04 could be '885 or '888. Pick '888. */ - if (rev == 0x04) - chip->ident = V4L2_IDENT_CX23888; - else - chip->ident = V4L2_IDENT_CX23885; - break; - case 0x8880: - if (rev == 0x0e || rev == 0x0f) - chip->ident = V4L2_IDENT_CX23887; - else - chip->ident = V4L2_IDENT_CX23888; - break; - default: - chip->ident = V4L2_IDENT_UNKNOWN; - break; - } - chip->revision = (dev->pci->device << 16) | (rev << 8) | - (dev->hwrevision & 0xff); - break; - case 1: - if (dev->v4l_device != NULL) { - chip->ident = V4L2_IDENT_CX23417; - chip->revision = 0; - } - break; - case 2: - /* - * The integrated IR controller on the CX23888 is - * host chip 2. It may not be used/initialized or sd_ir - * may be pointing at the cx25840 subdevice for the - * IR controller on the CX23885. Thus we find it - * without using the dev->sd_ir pointer. - */ - call_hw(dev, CX23885_HW_888_IR, core, g_chip_ident, - chip); - break; - default: - err = -EINVAL; /* per V4L2 spec */ - break; - } - break; - case V4L2_CHIP_MATCH_I2C_DRIVER: - /* If needed, returns V4L2_IDENT_AMBIGUOUS without extra work */ - call_all(dev, core, g_chip_ident, chip); - break; - case V4L2_CHIP_MATCH_I2C_ADDR: - /* - * We could return V4L2_IDENT_UNKNOWN, but we don't do the work - * to look if a chip is at the address with no driver. That's a - * dangerous thing to do with EEPROMs anyway. - */ - call_all(dev, core, g_chip_ident, chip); - break; - default: - err = -EINVAL; - break; - } - return err; -} - -#ifdef CONFIG_VIDEO_ADV_DEBUG -static int cx23885_g_host_register(struct cx23885_dev *dev, - struct v4l2_dbg_register *reg) -{ - if ((reg->reg & 0x3) != 0 || reg->reg >= pci_resource_len(dev->pci, 0)) - return -EINVAL; - - reg->size = 4; - reg->val = cx_read(reg->reg); - return 0; -} - -static int cx23417_g_register(struct cx23885_dev *dev, - struct v4l2_dbg_register *reg) -{ - u32 value; - - if (dev->v4l_device == NULL) - return -EINVAL; - - if ((reg->reg & 0x3) != 0 || reg->reg >= 0x10000) - return -EINVAL; - - if (mc417_register_read(dev, (u16) reg->reg, &value)) - return -EINVAL; /* V4L2 spec, but -EREMOTEIO really */ - - reg->size = 4; - reg->val = value; - return 0; -} - -int cx23885_g_register(struct file *file, void *fh, - struct v4l2_dbg_register *reg) -{ - struct cx23885_dev *dev = ((struct cx23885_fh *)fh)->dev; - - if (!capable(CAP_SYS_ADMIN)) - return -EPERM; - - if (reg->match.type == V4L2_CHIP_MATCH_HOST) { - switch (reg->match.addr) { - case 0: - return cx23885_g_host_register(dev, reg); - case 1: - return cx23417_g_register(dev, reg); - default: - break; - } - } - - /* FIXME - any error returns should not be ignored */ - call_all(dev, core, g_register, reg); - return 0; -} - -static int cx23885_s_host_register(struct cx23885_dev *dev, - struct v4l2_dbg_register *reg) -{ - if ((reg->reg & 0x3) != 0 || reg->reg >= pci_resource_len(dev->pci, 0)) - return -EINVAL; - - reg->size = 4; - cx_write(reg->reg, reg->val); - return 0; -} - -static int cx23417_s_register(struct cx23885_dev *dev, - struct v4l2_dbg_register *reg) -{ - if (dev->v4l_device == NULL) - return -EINVAL; - - if ((reg->reg & 0x3) != 0 || reg->reg >= 0x10000) - return -EINVAL; - - if (mc417_register_write(dev, (u16) reg->reg, (u32) reg->val)) - return -EINVAL; /* V4L2 spec, but -EREMOTEIO really */ - - reg->size = 4; - return 0; -} - -int cx23885_s_register(struct file *file, void *fh, - struct v4l2_dbg_register *reg) -{ - struct cx23885_dev *dev = ((struct cx23885_fh *)fh)->dev; - - if (!capable(CAP_SYS_ADMIN)) - return -EPERM; - - if (reg->match.type == V4L2_CHIP_MATCH_HOST) { - switch (reg->match.addr) { - case 0: - return cx23885_s_host_register(dev, reg); - case 1: - return cx23417_s_register(dev, reg); - default: - break; - } - } - - /* FIXME - any error returns should not be ignored */ - call_all(dev, core, s_register, reg); - return 0; -} -#endif diff --git a/drivers/media/video/cx23885/cx23885-ioctl.h b/drivers/media/video/cx23885/cx23885-ioctl.h deleted file mode 100644 index 315be0ca5a0..00000000000 --- a/drivers/media/video/cx23885/cx23885-ioctl.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Driver for the Conexant CX23885/7/8 PCIe bridge - * - * Various common ioctl() support functions - * - * Copyright (c) 2009 Andy Walls <awalls@md.metrocast.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. - */ - -#ifndef _CX23885_IOCTL_H_ -#define _CX23885_IOCTL_H_ - -int cx23885_g_chip_ident(struct file *file, void *fh, - struct v4l2_dbg_chip_ident *chip); - -#ifdef CONFIG_VIDEO_ADV_DEBUG -int cx23885_g_register(struct file *file, void *fh, - struct v4l2_dbg_register *reg); - - -int cx23885_s_register(struct file *file, void *fh, - struct v4l2_dbg_register *reg); - -#endif -#endif diff --git a/drivers/media/video/cx23885/cx23885-ir.c b/drivers/media/video/cx23885/cx23885-ir.c deleted file mode 100644 index 7125247dd25..00000000000 --- a/drivers/media/video/cx23885/cx23885-ir.c +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Driver for the Conexant CX23885/7/8 PCIe bridge - * - * Infrared device support routines - non-input, non-vl42_subdev routines - * - * Copyright (C) 2009 Andy Walls <awalls@md.metrocast.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 <media/v4l2-device.h> - -#include "cx23885.h" -#include "cx23885-input.h" - -#define CX23885_IR_RX_FIFO_SERVICE_REQ 0 -#define CX23885_IR_RX_END_OF_RX_DETECTED 1 -#define CX23885_IR_RX_HW_FIFO_OVERRUN 2 -#define CX23885_IR_RX_SW_FIFO_OVERRUN 3 - -#define CX23885_IR_TX_FIFO_SERVICE_REQ 0 - - -void cx23885_ir_rx_work_handler(struct work_struct *work) -{ - struct cx23885_dev *dev = - container_of(work, struct cx23885_dev, ir_rx_work); - u32 events = 0; - unsigned long *notifications = &dev->ir_rx_notifications; - - if (test_and_clear_bit(CX23885_IR_RX_SW_FIFO_OVERRUN, notifications)) - events |= V4L2_SUBDEV_IR_RX_SW_FIFO_OVERRUN; - if (test_and_clear_bit(CX23885_IR_RX_HW_FIFO_OVERRUN, notifications)) - events |= V4L2_SUBDEV_IR_RX_HW_FIFO_OVERRUN; - if (test_and_clear_bit(CX23885_IR_RX_END_OF_RX_DETECTED, notifications)) - events |= V4L2_SUBDEV_IR_RX_END_OF_RX_DETECTED; - if (test_and_clear_bit(CX23885_IR_RX_FIFO_SERVICE_REQ, notifications)) - events |= V4L2_SUBDEV_IR_RX_FIFO_SERVICE_REQ; - - if (events == 0) - return; - - if (dev->kernel_ir) - cx23885_input_rx_work_handler(dev, events); -} - -void cx23885_ir_tx_work_handler(struct work_struct *work) -{ - struct cx23885_dev *dev = - container_of(work, struct cx23885_dev, ir_tx_work); - u32 events = 0; - unsigned long *notifications = &dev->ir_tx_notifications; - - if (test_and_clear_bit(CX23885_IR_TX_FIFO_SERVICE_REQ, notifications)) - events |= V4L2_SUBDEV_IR_TX_FIFO_SERVICE_REQ; - - if (events == 0) - return; - -} - -/* Possibly called in an IRQ context */ -void cx23885_ir_rx_v4l2_dev_notify(struct v4l2_subdev *sd, u32 events) -{ - struct cx23885_dev *dev = to_cx23885(sd->v4l2_dev); - unsigned long *notifications = &dev->ir_rx_notifications; - - if (events & V4L2_SUBDEV_IR_RX_FIFO_SERVICE_REQ) - set_bit(CX23885_IR_RX_FIFO_SERVICE_REQ, notifications); - if (events & V4L2_SUBDEV_IR_RX_END_OF_RX_DETECTED) - set_bit(CX23885_IR_RX_END_OF_RX_DETECTED, notifications); - if (events & V4L2_SUBDEV_IR_RX_HW_FIFO_OVERRUN) - set_bit(CX23885_IR_RX_HW_FIFO_OVERRUN, notifications); - if (events & V4L2_SUBDEV_IR_RX_SW_FIFO_OVERRUN) - set_bit(CX23885_IR_RX_SW_FIFO_OVERRUN, notifications); - - /* - * For the integrated AV core, we are already in a workqueue context. - * For the CX23888 integrated IR, we are in an interrupt context. - */ - if (sd == dev->sd_cx25840) - cx23885_ir_rx_work_handler(&dev->ir_rx_work); - else - schedule_work(&dev->ir_rx_work); -} - -/* Possibly called in an IRQ context */ -void cx23885_ir_tx_v4l2_dev_notify(struct v4l2_subdev *sd, u32 events) -{ - struct cx23885_dev *dev = to_cx23885(sd->v4l2_dev); - unsigned long *notifications = &dev->ir_tx_notifications; - - if (events & V4L2_SUBDEV_IR_TX_FIFO_SERVICE_REQ) - set_bit(CX23885_IR_TX_FIFO_SERVICE_REQ, notifications); - - /* - * For the integrated AV core, we are already in a workqueue context. - * For the CX23888 integrated IR, we are in an interrupt context. - */ - if (sd == dev->sd_cx25840) - cx23885_ir_tx_work_handler(&dev->ir_tx_work); - else - schedule_work(&dev->ir_tx_work); -} diff --git a/drivers/media/video/cx23885/cx23885-ir.h b/drivers/media/video/cx23885/cx23885-ir.h deleted file mode 100644 index 0c9d8bda9e2..00000000000 --- a/drivers/media/video/cx23885/cx23885-ir.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Driver for the Conexant CX23885/7/8 PCIe bridge - * - * Infrared device support routines - non-input, non-vl42_subdev routines - * - * Copyright (C) 2009 Andy Walls <awalls@md.metrocast.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 _CX23885_IR_H_ -#define _CX23885_IR_H_ -void cx23885_ir_rx_v4l2_dev_notify(struct v4l2_subdev *sd, u32 events); -void cx23885_ir_tx_v4l2_dev_notify(struct v4l2_subdev *sd, u32 events); - -void cx23885_ir_rx_work_handler(struct work_struct *work); -void cx23885_ir_tx_work_handler(struct work_struct *work); -#endif diff --git a/drivers/media/video/cx23885/cx23885-reg.h b/drivers/media/video/cx23885/cx23885-reg.h deleted file mode 100644 index a99936e0cbc..00000000000 --- a/drivers/media/video/cx23885/cx23885-reg.h +++ /dev/null @@ -1,452 +0,0 @@ -/* - * Driver for the Conexant CX23885 PCIe bridge - * - * Copyright (c) 2006 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. - */ - -#ifndef _CX23885_REG_H_ -#define _CX23885_REG_H_ - -/* -Address Map -0x00000000 -> 0x00009000 TX SRAM (Fifos) -0x00010000 -> 0x00013c00 RX SRAM CMDS + CDT - -EACH CMDS struct is 0x80 bytes long - -DMAx_PTR1 = 0x03040 address of first cluster -DMAx_PTR2 = 0x10600 address of the CDT -DMAx_CNT1 = cluster size in (bytes >> 4) -1 -DMAx_CNT2 = total cdt size for all entries >> 3 - -Cluster Descriptor entry = 4 DWORDS - DWORD 0 -> ptr to cluster - DWORD 1 Reserved - DWORD 2 Reserved - DWORD 3 Reserved - -Channel manager Data Structure entry = 20 DWORD - 0 IntialProgramCounterLow - 1 IntialProgramCounterHigh - 2 ClusterDescriptorTableBase - 3 ClusterDescriptorTableSize - 4 InstructionQueueBase - 5 InstructionQueueSize -... Reserved - 19 Reserved -*/ - -/* Risc Instructions */ -#define RISC_CNT_INC 0x00010000 -#define RISC_CNT_RESET 0x00030000 -#define RISC_IRQ1 0x01000000 -#define RISC_IRQ2 0x02000000 -#define RISC_EOL 0x04000000 -#define RISC_SOL 0x08000000 -#define RISC_WRITE 0x10000000 -#define RISC_SKIP 0x20000000 -#define RISC_JUMP 0x70000000 -#define RISC_SYNC 0x80000000 -#define RISC_RESYNC 0x80008000 -#define RISC_READ 0x90000000 -#define RISC_WRITERM 0xB0000000 -#define RISC_WRITECM 0xC0000000 -#define RISC_WRITECR 0xD0000000 -#define RISC_WRITEC 0x50000000 -#define RISC_READC 0xA0000000 - - -/* Audio and Video Core */ -#define HOST_REG1 0x00000000 -#define HOST_REG2 0x00000001 -#define HOST_REG3 0x00000002 - -/* Chip Configuration Registers */ -#define CHIP_CTRL 0x00000100 -#define AFE_CTRL 0x00000104 -#define VID_PLL_INT_POST 0x00000108 -#define VID_PLL_FRAC 0x0000010C -#define AUX_PLL_INT_POST 0x00000110 -#define AUX_PLL_FRAC 0x00000114 -#define SYS_PLL_INT_POST 0x00000118 -#define SYS_PLL_FRAC 0x0000011C -#define PIN_CTRL 0x00000120 -#define AUD_IO_CTRL 0x00000124 -#define AUD_LOCK1 0x00000128 -#define AUD_LOCK2 0x0000012C -#define POWER_CTRL 0x00000130 -#define AFE_DIAG_CTRL1 0x00000134 -#define AFE_DIAG_CTRL3 0x0000013C -#define PLL_DIAG_CTRL 0x00000140 -#define AFE_CLK_OUT_CTRL 0x00000144 -#define DLL1_DIAG_CTRL 0x0000015C - -/* GPIO[23:19] Output Enable */ -#define GPIO2_OUT_EN_REG 0x00000160 -/* GPIO[23:19] Data Registers */ -#define GPIO2 0x00000164 - -#define IFADC_CTRL 0x00000180 - -/* Infrared Remote Registers */ -#define IR_CNTRL_REG 0x00000200 -#define IR_TXCLK_REG 0x00000204 -#define IR_RXCLK_REG 0x00000208 -#define IR_CDUTY_REG 0x0000020C -#define IR_STAT_REG 0x00000210 -#define IR_IRQEN_REG 0x00000214 -#define IR_FILTR_REG 0x00000218 -#define IR_FIFO_REG 0x0000023C - -/* Video Decoder Registers */ -#define MODE_CTRL 0x00000400 -#define OUT_CTRL1 0x00000404 -#define OUT_CTRL2 0x00000408 -#define GEN_STAT 0x0000040C -#define INT_STAT_MASK 0x00000410 -#define LUMA_CTRL 0x00000414 -#define HSCALE_CTRL 0x00000418 -#define VSCALE_CTRL 0x0000041C -#define CHROMA_CTRL 0x00000420 -#define VBI_LINE_CTRL1 0x00000424 -#define VBI_LINE_CTRL2 0x00000428 -#define VBI_LINE_CTRL3 0x0000042C -#define VBI_LINE_CTRL4 0x00000430 -#define VBI_LINE_CTRL5 0x00000434 -#define VBI_FC_CFG 0x00000438 -#define VBI_MISC_CFG1 0x0000043C -#define VBI_MISC_CFG2 0x00000440 -#define VBI_PAY1 0x00000444 -#define VBI_PAY2 0x00000448 -#define VBI_CUST1_CFG1 0x0000044C -#define VBI_CUST1_CFG2 0x00000450 -#define VBI_CUST1_CFG3 0x00000454 -#define VBI_CUST2_CFG1 0x00000458 -#define VBI_CUST2_CFG2 0x0000045C -#define VBI_CUST2_CFG3 0x00000460 -#define VBI_CUST3_CFG1 0x00000464 -#define VBI_CUST3_CFG2 0x00000468 -#define VBI_CUST3_CFG3 0x0000046C -#define HORIZ_TIM_CTRL 0x00000470 -#define VERT_TIM_CTRL 0x00000474 -#define SRC_COMB_CFG 0x00000478 -#define CHROMA_VBIOFF_CFG 0x0000047C -#define FIELD_COUNT 0x00000480 -#define MISC_TIM_CTRL 0x00000484 -#define DFE_CTRL1 0x00000488 -#define DFE_CTRL2 0x0000048C -#define DFE_CTRL3 0x00000490 -#define PLL_CTRL 0x00000494 -#define HTL_CTRL 0x00000498 -#define COMB_CTRL 0x0000049C -#define CRUSH_CTRL 0x000004A0 -#define SOFT_RST_CTRL 0x000004A4 -#define CX885_VERSION 0x000004B4 -#define VBI_PASS_CTRL 0x000004BC - -/* Audio Decoder Registers */ -/* 8051 Configuration */ -#define DL_CTL 0x00000800 -#define STD_DET_STATUS 0x00000804 -#define STD_DET_CTL 0x00000808 -#define DW8051_INT 0x0000080C -#define GENERAL_CTL 0x00000810 -#define AAGC_CTL 0x00000814 -#define DEMATRIX_CTL 0x000008CC -#define PATH1_CTL1 0x000008D0 -#define PATH1_VOL_CTL 0x000008D4 -#define PATH1_EQ_CTL 0x000008D8 -#define PATH1_SC_CTL 0x000008DC -#define PATH2_CTL1 0x000008E0 -#define PATH2_VOL_CTL 0x000008E4 -#define PATH2_EQ_CTL 0x000008E8 -#define PATH2_SC_CTL 0x000008EC - -/* Sample Rate Converter */ -#define SRC_CTL 0x000008F0 -#define SRC_LF_COEF 0x000008F4 -#define SRC1_CTL 0x000008F8 -#define SRC2_CTL 0x000008FC -#define SRC3_CTL 0x00000900 -#define SRC4_CTL 0x00000904 -#define SRC5_CTL 0x00000908 -#define SRC6_CTL 0x0000090C -#define BAND_OUT_SEL 0x00000910 -#define I2S_N_CTL 0x00000914 -#define I2S_OUT_CTL 0x00000918 -#define AUTOCONFIG_REG 0x000009C4 - -/* Audio ADC Registers */ -#define DSM_CTRL1 0x00000000 -#define DSM_CTRL2 0x00000001 -#define CHP_EN_CTRL 0x00000002 -#define CHP_CLK_CTRL1 0x00000004 -#define CHP_CLK_CTRL2 0x00000005 -#define BG_REF_CTRL 0x00000006 -#define SD2_SW_CTRL1 0x00000008 -#define SD2_SW_CTRL2 0x00000009 -#define SD2_BIAS_CTRL 0x0000000A -#define AMP_BIAS_CTRL 0x0000000C -#define CH_PWR_CTRL1 0x0000000E -#define FLD_CH_SEL (1 << 3) -#define CH_PWR_CTRL2 0x0000000F -#define DSM_STATUS1 0x00000010 -#define DSM_STATUS2 0x00000011 -#define DIG_CTL1 0x00000012 -#define DIG_CTL2 0x00000013 -#define I2S_TX_CFG 0x0000001A - -#define DEV_CNTRL2 0x00040000 - -#define PCI_MSK_IR (1 << 28) -#define PCI_MSK_AV_CORE (1 << 27) -#define PCI_MSK_GPIO1 (1 << 24) -#define PCI_MSK_GPIO0 (1 << 23) -#define PCI_MSK_APB_DMA (1 << 12) -#define PCI_MSK_AL_WR (1 << 11) -#define PCI_MSK_AL_RD (1 << 10) -#define PCI_MSK_RISC_WR (1 << 9) -#define PCI_MSK_RISC_RD (1 << 8) -#define PCI_MSK_AUD_EXT (1 << 4) -#define PCI_MSK_AUD_INT (1 << 3) -#define PCI_MSK_VID_C (1 << 2) -#define PCI_MSK_VID_B (1 << 1) -#define PCI_MSK_VID_A 1 -#define PCI_INT_MSK 0x00040010 - -#define PCI_INT_STAT 0x00040014 -#define PCI_INT_MSTAT 0x00040018 - -#define VID_A_INT_MSK 0x00040020 -#define VID_A_INT_STAT 0x00040024 -#define VID_A_INT_MSTAT 0x00040028 -#define VID_A_INT_SSTAT 0x0004002C - -#define VID_B_INT_MSK 0x00040030 -#define VID_B_MSK_BAD_PKT (1 << 20) -#define VID_B_MSK_VBI_OPC_ERR (1 << 17) -#define VID_B_MSK_OPC_ERR (1 << 16) -#define VID_B_MSK_VBI_SYNC (1 << 13) -#define VID_B_MSK_SYNC (1 << 12) -#define VID_B_MSK_VBI_OF (1 << 9) -#define VID_B_MSK_OF (1 << 8) -#define VID_B_MSK_VBI_RISCI2 (1 << 5) -#define VID_B_MSK_RISCI2 (1 << 4) -#define VID_B_MSK_VBI_RISCI1 (1 << 1) -#define VID_B_MSK_RISCI1 1 -#define VID_B_INT_STAT 0x00040034 -#define VID_B_INT_MSTAT 0x00040038 -#define VID_B_INT_SSTAT 0x0004003C - -#define VID_B_MSK_BAD_PKT (1 << 20) -#define VID_B_MSK_OPC_ERR (1 << 16) -#define VID_B_MSK_SYNC (1 << 12) -#define VID_B_MSK_OF (1 << 8) -#define VID_B_MSK_RISCI2 (1 << 4) -#define VID_B_MSK_RISCI1 1 - -#define VID_C_MSK_BAD_PKT (1 << 20) -#define VID_C_MSK_OPC_ERR (1 << 16) -#define VID_C_MSK_SYNC (1 << 12) -#define VID_C_MSK_OF (1 << 8) -#define VID_C_MSK_RISCI2 (1 << 4) -#define VID_C_MSK_RISCI1 1 - -/* A superset for testing purposes */ -#define VID_BC_MSK_BAD_PKT (1 << 20) -#define VID_BC_MSK_OPC_ERR (1 << 16) -#define VID_BC_MSK_SYNC (1 << 12) -#define VID_BC_MSK_OF (1 << 8) -#define VID_BC_MSK_VBI_RISCI2 (1 << 5) -#define VID_BC_MSK_RISCI2 (1 << 4) -#define VID_BC_MSK_VBI_RISCI1 (1 << 1) -#define VID_BC_MSK_RISCI1 1 - -#define VID_C_INT_MSK 0x00040040 -#define VID_C_INT_STAT 0x00040044 -#define VID_C_INT_MSTAT 0x00040048 -#define VID_C_INT_SSTAT 0x0004004C - -#define AUDIO_INT_INT_MSK 0x00040050 -#define AUDIO_INT_INT_STAT 0x00040054 -#define AUDIO_INT_INT_MSTAT 0x00040058 -#define AUDIO_INT_INT_SSTAT 0x0004005C - -#define AUDIO_EXT_INT_MSK 0x00040060 -#define AUDIO_EXT_INT_STAT 0x00040064 -#define AUDIO_EXT_INT_MSTAT 0x00040068 -#define AUDIO_EXT_INT_SSTAT 0x0004006C - -#define RDR_CFG0 0x00050000 -#define RDR_CFG1 0x00050004 -#define RDR_CFG2 0x00050008 -#define RDR_RDRCTL1 0x0005030c -#define RDR_TLCTL0 0x00050318 - -/* APB DMAC Current Buffer Pointer */ -#define DMA1_PTR1 0x00100000 -#define DMA2_PTR1 0x00100004 -#define DMA3_PTR1 0x00100008 -#define DMA4_PTR1 0x0010000C -#define DMA5_PTR1 0x00100010 -#define DMA6_PTR1 0x00100014 -#define DMA7_PTR1 0x00100018 -#define DMA8_PTR1 0x0010001C - -/* APB DMAC Current Table Pointer */ -#define DMA1_PTR2 0x00100040 -#define DMA2_PTR2 0x00100044 -#define DMA3_PTR2 0x00100048 -#define DMA4_PTR2 0x0010004C -#define DMA5_PTR2 0x00100050 -#define DMA6_PTR2 0x00100054 -#define DMA7_PTR2 0x00100058 -#define DMA8_PTR2 0x0010005C - -/* APB DMAC Buffer Limit */ -#define DMA1_CNT1 0x00100080 -#define DMA2_CNT1 0x00100084 -#define DMA3_CNT1 0x00100088 -#define DMA4_CNT1 0x0010008C -#define DMA5_CNT1 0x00100090 -#define DMA6_CNT1 0x00100094 -#define DMA7_CNT1 0x00100098 -#define DMA8_CNT1 0x0010009C - -/* APB DMAC Table Size */ -#define DMA1_CNT2 0x001000C0 -#define DMA2_CNT2 0x001000C4 -#define DMA3_CNT2 0x001000C8 -#define DMA4_CNT2 0x001000CC -#define DMA5_CNT2 0x001000D0 -#define DMA6_CNT2 0x001000D4 -#define DMA7_CNT2 0x001000D8 -#define DMA8_CNT2 0x001000DC - -/* Timer Counters */ -#define TM_CNT_LDW 0x00110000 -#define TM_CNT_UW 0x00110004 -#define TM_LMT_LDW 0x00110008 -#define TM_LMT_UW 0x0011000C - -/* GPIO */ -#define GP0_IO 0x00110010 -#define GPIO_ISM 0x00110014 -#define SOFT_RESET 0x0011001C - -/* GPIO (417 Microsoftcontroller) RW Data */ -#define MC417_RWD 0x00110020 - -/* GPIO (417 Microsoftcontroller) Output Enable, Low Active */ -#define MC417_OEN 0x00110024 -#define MC417_CTL 0x00110028 -#define ALT_PIN_OUT_SEL 0x0011002C -#define CLK_DELAY 0x00110048 -#define PAD_CTRL 0x0011004C - -/* Video A Interface */ -#define VID_A_GPCNT 0x00130020 -#define VBI_A_GPCNT 0x00130024 -#define VID_A_GPCNT_CTL 0x00130030 -#define VBI_A_GPCNT_CTL 0x00130034 -#define VID_A_DMA_CTL 0x00130040 -#define VID_A_VIP_CTRL 0x00130080 -#define VID_A_PIXEL_FRMT 0x00130084 -#define VID_A_VBI_CTRL 0x00130088 - -/* Video B Interface */ -#define VID_B_DMA 0x00130100 -#define VBI_B_DMA 0x00130108 -#define VID_B_GPCNT 0x00130120 -#define VBI_B_GPCNT 0x00130124 -#define VID_B_GPCNT_CTL 0x00130134 -#define VBI_B_GPCNT_CTL 0x00130138 -#define VID_B_DMA_CTL 0x00130140 -#define VID_B_SRC_SEL 0x00130144 -#define VID_B_LNGTH 0x00130150 -#define VID_B_HW_SOP_CTL 0x00130154 -#define VID_B_GEN_CTL 0x00130158 -#define VID_B_BD_PKT_STATUS 0x0013015C -#define VID_B_SOP_STATUS 0x00130160 -#define VID_B_FIFO_OVFL_STAT 0x00130164 -#define VID_B_VLD_MISC 0x00130168 -#define VID_B_TS_CLK_EN 0x0013016C -#define VID_B_VIP_CTRL 0x00130180 -#define VID_B_PIXEL_FRMT 0x00130184 - -/* Video C Interface */ -#define VID_C_GPCNT 0x00130220 -#define VID_C_GPCNT_CTL 0x00130230 -#define VBI_C_GPCNT_CTL 0x00130234 -#define VID_C_DMA_CTL 0x00130240 -#define VID_C_LNGTH 0x00130250 -#define VID_C_HW_SOP_CTL 0x00130254 -#define VID_C_GEN_CTL 0x00130258 -#define VID_C_BD_PKT_STATUS 0x0013025C -#define VID_C_SOP_STATUS 0x00130260 -#define VID_C_FIFO_OVFL_STAT 0x00130264 -#define VID_C_VLD_MISC 0x00130268 -#define VID_C_TS_CLK_EN 0x0013026C - -/* Internal Audio Interface */ -#define AUD_INT_A_GPCNT 0x00140020 -#define AUD_INT_B_GPCNT 0x00140024 -#define AUD_INT_A_GPCNT_CTL 0x00140030 -#define AUD_INT_B_GPCNT_CTL 0x00140034 -#define AUD_INT_DMA_CTL 0x00140040 -#define AUD_INT_A_LNGTH 0x00140050 -#define AUD_INT_B_LNGTH 0x00140054 -#define AUD_INT_A_MODE 0x00140058 -#define AUD_INT_B_MODE 0x0014005C - -/* External Audio Interface */ -#define AUD_EXT_DMA 0x00140100 -#define AUD_EXT_GPCNT 0x00140120 -#define AUD_EXT_GPCNT_CTL 0x00140130 -#define AUD_EXT_DMA_CTL 0x00140140 -#define AUD_EXT_LNGTH 0x00140150 -#define AUD_EXT_A_MODE 0x00140158 - -/* I2C Bus 1 */ -#define I2C1_ADDR 0x00180000 -#define I2C1_WDATA 0x00180004 -#define I2C1_CTRL 0x00180008 -#define I2C1_RDATA 0x0018000C -#define I2C1_STAT 0x00180010 - -/* I2C Bus 2 */ -#define I2C2_ADDR 0x00190000 -#define I2C2_WDATA 0x00190004 -#define I2C2_CTRL 0x00190008 -#define I2C2_RDATA 0x0019000C -#define I2C2_STAT 0x00190010 - -/* I2C Bus 3 */ -#define I2C3_ADDR 0x001A0000 -#define I2C3_WDATA 0x001A0004 -#define I2C3_CTRL 0x001A0008 -#define I2C3_RDATA 0x001A000C -#define I2C3_STAT 0x001A0010 - -/* UART */ -#define UART_CTL 0x001B0000 -#define UART_BRD 0x001B0004 -#define UART_ISR 0x001B000C -#define UART_CNT 0x001B0010 - -#endif /* _CX23885_REG_H_ */ diff --git a/drivers/media/video/cx23885/cx23885-vbi.c b/drivers/media/video/cx23885/cx23885-vbi.c deleted file mode 100644 index a1154f035bc..00000000000 --- a/drivers/media/video/cx23885/cx23885-vbi.c +++ /dev/null @@ -1,295 +0,0 @@ -/* - * Driver for the Conexant CX23885 PCIe bridge - * - * Copyright (c) 2007 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 <linux/kernel.h> -#include <linux/module.h> -#include <linux/moduleparam.h> -#include <linux/init.h> - -#include "cx23885.h" - -static unsigned int vbibufs = 4; -module_param(vbibufs, int, 0644); -MODULE_PARM_DESC(vbibufs, "number of vbi buffers, range 2-32"); - -static unsigned int vbi_debug; -module_param(vbi_debug, int, 0644); -MODULE_PARM_DESC(vbi_debug, "enable debug messages [vbi]"); - -#define dprintk(level, fmt, arg...)\ - do { if (vbi_debug >= level)\ - printk(KERN_DEBUG "%s/0: " fmt, dev->name, ## arg);\ - } while (0) - -/* ------------------------------------------------------------------ */ - -#define VBI_LINE_LENGTH 1440 -#define NTSC_VBI_START_LINE 10 /* line 10 - 21 */ -#define NTSC_VBI_END_LINE 21 -#define NTSC_VBI_LINES (NTSC_VBI_END_LINE - NTSC_VBI_START_LINE + 1) - - -int cx23885_vbi_fmt(struct file *file, void *priv, - struct v4l2_format *f) -{ - struct cx23885_fh *fh = priv; - struct cx23885_dev *dev = fh->dev; - - if (dev->tvnorm & V4L2_STD_525_60) { - /* ntsc */ - f->fmt.vbi.samples_per_line = VBI_LINE_LENGTH; - f->fmt.vbi.sampling_rate = 27000000; - f->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY; - f->fmt.vbi.offset = 0; - f->fmt.vbi.flags = 0; - f->fmt.vbi.start[0] = 10; - f->fmt.vbi.count[0] = 17; - f->fmt.vbi.start[1] = 263 + 10 + 1; - f->fmt.vbi.count[1] = 17; - } else if (dev->tvnorm & V4L2_STD_625_50) { - /* pal */ - f->fmt.vbi.sampling_rate = 35468950; - f->fmt.vbi.start[0] = 7 - 1; - f->fmt.vbi.start[1] = 319 - 1; - } - - return 0; -} - -/* We're given the Video Interrupt status register. - * The cx23885_video_irq() func has already validated - * the potential error bits, we just need to - * deal with vbi payload and return indication if - * we actually processed any payload. - */ -int cx23885_vbi_irq(struct cx23885_dev *dev, u32 status) -{ - u32 count; - int handled = 0; - - if (status & VID_BC_MSK_VBI_RISCI1) { - dprintk(1, "%s() VID_BC_MSK_VBI_RISCI1\n", __func__); - spin_lock(&dev->slock); - count = cx_read(VID_A_GPCNT); - cx23885_video_wakeup(dev, &dev->vbiq, count); - spin_unlock(&dev->slock); - handled++; - } - - if (status & VID_BC_MSK_VBI_RISCI2) { - dprintk(1, "%s() VID_BC_MSK_VBI_RISCI2\n", __func__); - dprintk(2, "stopper vbi\n"); - spin_lock(&dev->slock); - cx23885_restart_vbi_queue(dev, &dev->vbiq); - spin_unlock(&dev->slock); - handled++; - } - - return handled; -} - -static int cx23885_start_vbi_dma(struct cx23885_dev *dev, - struct cx23885_dmaqueue *q, - struct cx23885_buffer *buf) -{ - dprintk(1, "%s()\n", __func__); - - /* setup fifo + format */ - cx23885_sram_channel_setup(dev, &dev->sram_channels[SRAM_CH02], - buf->vb.width, buf->risc.dma); - - /* reset counter */ - cx_write(VID_A_GPCNT_CTL, 3); - cx_write(VID_A_VBI_CTRL, 3); - cx_write(VBI_A_GPCNT_CTL, 3); - q->count = 1; - - /* enable irq */ - cx23885_irq_add_enable(dev, 0x01); - cx_set(VID_A_INT_MSK, 0x000022); - - /* start dma */ - cx_set(DEV_CNTRL2, (1<<5)); - cx_set(VID_A_DMA_CTL, 0x22); /* FIFO and RISC enable */ - - return 0; -} - - -int cx23885_restart_vbi_queue(struct cx23885_dev *dev, - struct cx23885_dmaqueue *q) -{ - struct cx23885_buffer *buf; - struct list_head *item; - - if (list_empty(&q->active)) - return 0; - - buf = list_entry(q->active.next, struct cx23885_buffer, vb.queue); - dprintk(2, "restart_queue [%p/%d]: restart dma\n", - buf, buf->vb.i); - cx23885_start_vbi_dma(dev, q, buf); - list_for_each(item, &q->active) { - buf = list_entry(item, struct cx23885_buffer, vb.queue); - buf->count = q->count++; - } - mod_timer(&q->timeout, jiffies + (BUFFER_TIMEOUT / 30)); - return 0; -} - -void cx23885_vbi_timeout(unsigned long data) -{ - struct cx23885_dev *dev = (struct cx23885_dev *)data; - struct cx23885_dmaqueue *q = &dev->vbiq; - struct cx23885_buffer *buf; - unsigned long flags; - - /* Stop the VBI engine */ - cx_clear(VID_A_DMA_CTL, 0x22); - - spin_lock_irqsave(&dev->slock, flags); - while (!list_empty(&q->active)) { - buf = list_entry(q->active.next, struct cx23885_buffer, - vb.queue); - list_del(&buf->vb.queue); - buf->vb.state = VIDEOBUF_ERROR; - wake_up(&buf->vb.done); - printk("%s/0: [%p/%d] timeout - dma=0x%08lx\n", dev->name, - buf, buf->vb.i, (unsigned long)buf->risc.dma); - } - cx23885_restart_vbi_queue(dev, q); - spin_unlock_irqrestore(&dev->slock, flags); -} - -/* ------------------------------------------------------------------ */ -#define VBI_LINE_LENGTH 1440 -#define VBI_LINE_COUNT 17 - -static int -vbi_setup(struct videobuf_queue *q, unsigned int *count, unsigned int *size) -{ - *size = VBI_LINE_COUNT * VBI_LINE_LENGTH * 2; - if (0 == *count) - *count = vbibufs; - if (*count < 2) - *count = 2; - if (*count > 32) - *count = 32; - return 0; -} - -static int -vbi_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb, - enum v4l2_field field) -{ - struct cx23885_fh *fh = q->priv_data; - struct cx23885_dev *dev = fh->dev; - struct cx23885_buffer *buf = container_of(vb, - struct cx23885_buffer, vb); - struct videobuf_dmabuf *dma = videobuf_to_dma(&buf->vb); - unsigned int size; - int rc; - - size = VBI_LINE_COUNT * VBI_LINE_LENGTH * 2; - if (0 != buf->vb.baddr && buf->vb.bsize < size) - return -EINVAL; - - if (VIDEOBUF_NEEDS_INIT == buf->vb.state) { - buf->vb.width = VBI_LINE_LENGTH; - buf->vb.height = VBI_LINE_COUNT; - buf->vb.size = size; - buf->vb.field = V4L2_FIELD_SEQ_TB; - - rc = videobuf_iolock(q, &buf->vb, NULL); - if (0 != rc) - goto fail; - cx23885_risc_vbibuffer(dev->pci, &buf->risc, - dma->sglist, - 0, buf->vb.width * buf->vb.height, - buf->vb.width, 0, - buf->vb.height); - } - buf->vb.state = VIDEOBUF_PREPARED; - return 0; - - fail: - cx23885_free_buffer(q, buf); - return rc; -} - -static void -vbi_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb) -{ - struct cx23885_buffer *buf = - container_of(vb, struct cx23885_buffer, vb); - struct cx23885_buffer *prev; - struct cx23885_fh *fh = vq->priv_data; - struct cx23885_dev *dev = fh->dev; - struct cx23885_dmaqueue *q = &dev->vbiq; - - /* add jump to stopper */ - buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC); - buf->risc.jmp[1] = cpu_to_le32(q->stopper.dma); - buf->risc.jmp[2] = cpu_to_le32(0); /* bits 63-32 */ - - if (list_empty(&q->active)) { - list_add_tail(&buf->vb.queue, &q->active); - cx23885_start_vbi_dma(dev, q, buf); - buf->vb.state = VIDEOBUF_ACTIVE; - buf->count = q->count++; - mod_timer(&q->timeout, jiffies + (BUFFER_TIMEOUT / 30)); - dprintk(2, "[%p/%d] vbi_queue - first active\n", - buf, buf->vb.i); - - } else { - prev = list_entry(q->active.prev, struct cx23885_buffer, - vb.queue); - list_add_tail(&buf->vb.queue, &q->active); - buf->vb.state = VIDEOBUF_ACTIVE; - buf->count = q->count++; - prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma); - prev->risc.jmp[2] = cpu_to_le32(0); /* Bits 63-32 */ - dprintk(2, "[%p/%d] buffer_queue - append to active\n", - buf, buf->vb.i); - } -} - -static void vbi_release(struct videobuf_queue *q, struct videobuf_buffer *vb) -{ - struct cx23885_buffer *buf = - container_of(vb, struct cx23885_buffer, vb); - - cx23885_free_buffer(q, buf); -} - -struct videobuf_queue_ops cx23885_vbi_qops = { - .buf_setup = vbi_setup, - .buf_prepare = vbi_prepare, - .buf_queue = vbi_queue, - .buf_release = vbi_release, -}; - -/* ------------------------------------------------------------------ */ -/* - * Local variables: - * c-basic-offset: 8 - * End: - */ diff --git a/drivers/media/video/cx23885/cx23885-video.c b/drivers/media/video/cx23885/cx23885-video.c deleted file mode 100644 index 22f8e7fbd66..00000000000 --- a/drivers/media/video/cx23885/cx23885-video.c +++ /dev/null @@ -1,1926 +0,0 @@ -/* - * Driver for the Conexant CX23885 PCIe bridge - * - * Copyright (c) 2007 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 <linux/init.h> -#include <linux/list.h> -#include <linux/module.h> -#include <linux/moduleparam.h> -#include <linux/kmod.h> -#include <linux/kernel.h> -#include <linux/slab.h> -#include <linux/interrupt.h> -#include <linux/delay.h> -#include <linux/kthread.h> -#include <asm/div64.h> - -#include "cx23885.h" -#include <media/v4l2-common.h> -#include <media/v4l2-ioctl.h> -#include "cx23885-ioctl.h" -#include "tuner-xc2028.h" - -#include <media/cx25840.h> - -MODULE_DESCRIPTION("v4l2 driver module for cx23885 based TV cards"); -MODULE_AUTHOR("Steven Toth <stoth@linuxtv.org>"); -MODULE_LICENSE("GPL"); - -/* ------------------------------------------------------------------ */ - -static unsigned int video_nr[] = {[0 ... (CX23885_MAXBOARDS - 1)] = UNSET }; -static unsigned int vbi_nr[] = {[0 ... (CX23885_MAXBOARDS - 1)] = UNSET }; -static unsigned int radio_nr[] = {[0 ... (CX23885_MAXBOARDS - 1)] = UNSET }; - -module_param_array(video_nr, int, NULL, 0444); -module_param_array(vbi_nr, int, NULL, 0444); -module_param_array(radio_nr, int, NULL, 0444); - -MODULE_PARM_DESC(video_nr, "video device numbers"); -MODULE_PARM_DESC(vbi_nr, "vbi device numbers"); -MODULE_PARM_DESC(radio_nr, "radio device numbers"); - -static unsigned int video_debug; -module_param(video_debug, int, 0644); -MODULE_PARM_DESC(video_debug, "enable debug messages [video]"); - -static unsigned int irq_debug; -module_param(irq_debug, int, 0644); -MODULE_PARM_DESC(irq_debug, "enable debug messages [IRQ handler]"); - -static unsigned int vid_limit = 16; -module_param(vid_limit, int, 0644); -MODULE_PARM_DESC(vid_limit, "capture memory limit in megabytes"); - -#define dprintk(level, fmt, arg...)\ - do { if (video_debug >= level)\ - printk(KERN_DEBUG "%s: " fmt, dev->name, ## arg);\ - } while (0) - -/* ------------------------------------------------------------------- */ -/* static data */ - -#define FORMAT_FLAGS_PACKED 0x01 -#if 0 -static struct cx23885_fmt formats[] = { - { - .name = "8 bpp, gray", - .fourcc = V4L2_PIX_FMT_GREY, - .depth = 8, - .flags = FORMAT_FLAGS_PACKED, - }, { - .name = "15 bpp RGB, le", - .fourcc = V4L2_PIX_FMT_RGB555, - .depth = 16, - .flags = FORMAT_FLAGS_PACKED, - }, { - .name = "15 bpp RGB, be", - .fourcc = V4L2_PIX_FMT_RGB555X, - .depth = 16, - .flags = FORMAT_FLAGS_PACKED, - }, { - .name = "16 bpp RGB, le", - .fourcc = V4L2_PIX_FMT_RGB565, - .depth = 16, - .flags = FORMAT_FLAGS_PACKED, - }, { - .name = "16 bpp RGB, be", - .fourcc = V4L2_PIX_FMT_RGB565X, - .depth = 16, - .flags = FORMAT_FLAGS_PACKED, - }, { - .name = "24 bpp RGB, le", - .fourcc = V4L2_PIX_FMT_BGR24, - .depth = 24, - .flags = FORMAT_FLAGS_PACKED, - }, { - .name = "32 bpp RGB, le", - .fourcc = V4L2_PIX_FMT_BGR32, - .depth = 32, - .flags = FORMAT_FLAGS_PACKED, - }, { - .name = "32 bpp RGB, be", - .fourcc = V4L2_PIX_FMT_RGB32, - .depth = 32, - .flags = FORMAT_FLAGS_PACKED, - }, { - .name = "4:2:2, packed, YUYV", - .fourcc = V4L2_PIX_FMT_YUYV, - .depth = 16, - .flags = FORMAT_FLAGS_PACKED, - }, { - .name = "4:2:2, packed, UYVY", - .fourcc = V4L2_PIX_FMT_UYVY, - .depth = 16, - .flags = FORMAT_FLAGS_PACKED, - }, -}; -#else -static struct cx23885_fmt formats[] = { - { -#if 0 - .name = "4:2:2, packed, UYVY", - .fourcc = V4L2_PIX_FMT_UYVY, - .depth = 16, - .flags = FORMAT_FLAGS_PACKED, - }, { -#endif - .name = "4:2:2, packed, YUYV", - .fourcc = V4L2_PIX_FMT_YUYV, - .depth = 16, - .flags = FORMAT_FLAGS_PACKED, - } -}; -#endif - -static struct cx23885_fmt *format_by_fourcc(unsigned int fourcc) -{ - unsigned int i; - - for (i = 0; i < ARRAY_SIZE(formats); i++) - if (formats[i].fourcc == fourcc) - return formats+i; - - printk(KERN_ERR "%s(%c%c%c%c) NOT FOUND\n", __func__, - (fourcc & 0xff), - ((fourcc >> 8) & 0xff), - ((fourcc >> 16) & 0xff), - ((fourcc >> 24) & 0xff) - ); - return NULL; -} - -/* ------------------------------------------------------------------- */ - -static const struct v4l2_queryctrl no_ctl = { - .name = "42", - .flags = V4L2_CTRL_FLAG_DISABLED, -}; - -static struct cx23885_ctrl cx23885_ctls[] = { - /* --- video --- */ - { - .v = { - .id = V4L2_CID_BRIGHTNESS, - .name = "Brightness", - .minimum = 0x00, - .maximum = 0xff, - .step = 1, - .default_value = 0x7f, - .type = V4L2_CTRL_TYPE_INTEGER, - }, - .off = 128, - .reg = LUMA_CTRL, - .mask = 0x00ff, - .shift = 0, - }, { - .v = { - .id = V4L2_CID_CONTRAST, - .name = "Contrast", - .minimum = 0, - .maximum = 0x7f, - .step = 1, - .default_value = 0x3f, - .type = V4L2_CTRL_TYPE_INTEGER, - }, - .off = 0, - .reg = LUMA_CTRL, - .mask = 0xff00, - .shift = 8, - }, { - .v = { - .id = V4L2_CID_HUE, - .name = "Hue", - .minimum = -127, - .maximum = 128, - .step = 1, - .default_value = 0x0, - .type = V4L2_CTRL_TYPE_INTEGER, - }, - .off = 128, - .reg = CHROMA_CTRL, - .mask = 0xff0000, - .shift = 16, - }, { - /* strictly, this only describes only U saturation. - * V saturation is handled specially through code. - */ - .v = { - .id = V4L2_CID_SATURATION, - .name = "Saturation", - .minimum = 0, - .maximum = 0x7f, - .step = 1, - .default_value = 0x3f, - .type = V4L2_CTRL_TYPE_INTEGER, - }, - .off = 0, - .reg = CHROMA_CTRL, - .mask = 0x00ff, - .shift = 0, - }, { - /* --- audio --- */ - .v = { - .id = V4L2_CID_AUDIO_MUTE, - .name = "Mute", - .minimum = 0, - .maximum = 1, - .default_value = 1, - .type = V4L2_CTRL_TYPE_BOOLEAN, - }, - .reg = PATH1_CTL1, - .mask = (0x1f << 24), - .shift = 24, - }, { - .v = { - .id = V4L2_CID_AUDIO_VOLUME, - .name = "Volume", - .minimum = 0, - .maximum = 65535, - .step = 65535 / 100, - .default_value = 65535, - .type = V4L2_CTRL_TYPE_INTEGER, - }, - .reg = PATH1_VOL_CTL, - .mask = 0xff, - .shift = 0, - } -}; -static const int CX23885_CTLS = ARRAY_SIZE(cx23885_ctls); - -/* Must be sorted from low to high control ID! */ -static const u32 cx23885_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_MUTE, - 0 -}; - -static const u32 *ctrl_classes[] = { - cx23885_user_ctrls, - NULL -}; - -void cx23885_video_wakeup(struct cx23885_dev *dev, - struct cx23885_dmaqueue *q, u32 count) -{ - struct cx23885_buffer *buf; - int bc; - - for (bc = 0;; bc++) { - if (list_empty(&q->active)) - break; - buf = list_entry(q->active.next, - struct cx23885_buffer, vb.queue); - - /* count comes from the hw and is is 16bit wide -- - * this trick handles wrap-arounds correctly for - * up to 32767 buffers in flight... */ - if ((s16) (count - buf->count) < 0) - break; - - do_gettimeofday(&buf->vb.ts); - dprintk(2, "[%p/%d] wakeup reg=%d buf=%d\n", buf, buf->vb.i, - count, buf->count); - buf->vb.state = VIDEOBUF_DONE; - list_del(&buf->vb.queue); - wake_up(&buf->vb.done); - } - if (list_empty(&q->active)) - del_timer(&q->timeout); - else - mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT); - if (bc != 1) - printk(KERN_ERR "%s: %d buffers handled (should be 1)\n", - __func__, bc); -} - -int cx23885_set_tvnorm(struct cx23885_dev *dev, v4l2_std_id norm) -{ - dprintk(1, "%s(norm = 0x%08x) name: [%s]\n", - __func__, - (unsigned int)norm, - v4l2_norm_to_name(norm)); - - dev->tvnorm = norm; - - call_all(dev, core, s_std, norm); - - return 0; -} - -static struct video_device *cx23885_vdev_init(struct cx23885_dev *dev, - struct pci_dev *pci, - struct video_device *template, - char *type) -{ - struct video_device *vfd; - dprintk(1, "%s()\n", __func__); - - vfd = video_device_alloc(); - if (NULL == vfd) - return NULL; - *vfd = *template; - vfd->v4l2_dev = &dev->v4l2_dev; - vfd->release = video_device_release; - snprintf(vfd->name, sizeof(vfd->name), "%s (%s)", - cx23885_boards[dev->board].name, type); - video_set_drvdata(vfd, dev); - return vfd; -} - -static int cx23885_ctrl_query(struct v4l2_queryctrl *qctrl) -{ - int i; - - if (qctrl->id < V4L2_CID_BASE || - qctrl->id >= V4L2_CID_LASTP1) - return -EINVAL; - for (i = 0; i < CX23885_CTLS; i++) - if (cx23885_ctls[i].v.id == qctrl->id) - break; - if (i == CX23885_CTLS) { - *qctrl = no_ctl; - return 0; - } - *qctrl = cx23885_ctls[i].v; - return 0; -} - -/* ------------------------------------------------------------------- */ -/* resource management */ - -static int res_get(struct cx23885_dev *dev, struct cx23885_fh *fh, - unsigned int bit) -{ - dprintk(1, "%s()\n", __func__); - if (fh->resources & bit) - /* have it already allocated */ - return 1; - - /* is it free? */ - mutex_lock(&dev->lock); - if (dev->resources & bit) { - /* no, someone else uses it */ - mutex_unlock(&dev->lock); - return 0; - } - /* it's free, grab it */ - fh->resources |= bit; - dev->resources |= bit; - dprintk(1, "res: get %d\n", bit); - mutex_unlock(&dev->lock); - return 1; -} - -static int res_check(struct cx23885_fh *fh, unsigned int bit) -{ - return fh->resources & bit; -} - -static int res_locked(struct cx23885_dev *dev, unsigned int bit) -{ - return dev->resources & bit; -} - -static void res_free(struct cx23885_dev *dev, struct cx23885_fh *fh, - unsigned int bits) -{ - BUG_ON((fh->resources & bits) != bits); - dprintk(1, "%s()\n", __func__); - - mutex_lock(&dev->lock); - fh->resources &= ~bits; - dev->resources &= ~bits; - dprintk(1, "res: put %d\n", bits); - mutex_unlock(&dev->lock); -} - -static int cx23885_flatiron_write(struct cx23885_dev *dev, u8 reg, u8 data) -{ - /* 8 bit registers, 8 bit values */ - u8 buf[] = { reg, data }; - - struct i2c_msg msg = { .addr = 0x98 >> 1, - .flags = 0, .buf = buf, .len = 2 }; - - return i2c_transfer(&dev->i2c_bus[2].i2c_adap, &msg, 1); -} - -static u8 cx23885_flatiron_read(struct cx23885_dev *dev, u8 reg) -{ - /* 8 bit registers, 8 bit values */ - int ret; - u8 b0[] = { reg }; - u8 b1[] = { 0 }; - - struct i2c_msg msg[] = { - { .addr = 0x98 >> 1, .flags = 0, .buf = b0, .len = 1 }, - { .addr = 0x98 >> 1, .flags = I2C_M_RD, .buf = b1, .len = 1 } - }; - - ret = i2c_transfer(&dev->i2c_bus[2].i2c_adap, &msg[0], 2); - if (ret != 2) - printk(KERN_ERR "%s() error\n", __func__); - - return b1[0]; -} - -static void cx23885_flatiron_dump(struct cx23885_dev *dev) -{ - int i; - dprintk(1, "Flatiron dump\n"); - for (i = 0; i < 0x24; i++) { - dprintk(1, "FI[%02x] = %02x\n", i, - cx23885_flatiron_read(dev, i)); - } -} - -static int cx23885_flatiron_mux(struct cx23885_dev *dev, int input) -{ - u8 val; - dprintk(1, "%s(input = %d)\n", __func__, input); - - if (input == 1) - val = cx23885_flatiron_read(dev, CH_PWR_CTRL1) & ~FLD_CH_SEL; - else if (input == 2) - val = cx23885_flatiron_read(dev, CH_PWR_CTRL1) | FLD_CH_SEL; - else - return -EINVAL; - - val |= 0x20; /* Enable clock to delta-sigma and dec filter */ - - cx23885_flatiron_write(dev, CH_PWR_CTRL1, val); - - /* Wake up */ - cx23885_flatiron_write(dev, CH_PWR_CTRL2, 0); - - if (video_debug) - cx23885_flatiron_dump(dev); - - return 0; -} - -static int cx23885_video_mux(struct cx23885_dev *dev, unsigned int input) -{ - dprintk(1, "%s() video_mux: %d [vmux=%d, gpio=0x%x,0x%x,0x%x,0x%x]\n", - __func__, - input, INPUT(input)->vmux, - INPUT(input)->gpio0, INPUT(input)->gpio1, - INPUT(input)->gpio2, INPUT(input)->gpio3); - dev->input = input; - - if (dev->board == CX23885_BOARD_MYGICA_X8506 || - dev->board == CX23885_BOARD_MAGICPRO_PROHDTVE2 || - dev->board == CX23885_BOARD_MYGICA_X8507) { - /* Select Analog TV */ - if (INPUT(input)->type == CX23885_VMUX_TELEVISION) - cx23885_gpio_clear(dev, GPIO_0); - } - - /* Tell the internal A/V decoder */ - v4l2_subdev_call(dev->sd_cx25840, video, s_routing, - INPUT(input)->vmux, 0, 0); - - if ((dev->board == CX23885_BOARD_HAUPPAUGE_HVR1800) || - (dev->board == CX23885_BOARD_MPX885) || - (dev->board == CX23885_BOARD_HAUPPAUGE_HVR1250) || - (dev->board == CX23885_BOARD_HAUPPAUGE_HVR1255) || - (dev->board == CX23885_BOARD_HAUPPAUGE_HVR1255_22111) || - (dev->board == CX23885_BOARD_HAUPPAUGE_HVR1850)) { - /* Configure audio routing */ - v4l2_subdev_call(dev->sd_cx25840, audio, s_routing, - INPUT(input)->amux, 0, 0); - - if (INPUT(input)->amux == CX25840_AUDIO7) - cx23885_flatiron_mux(dev, 1); - else if (INPUT(input)->amux == CX25840_AUDIO6) - cx23885_flatiron_mux(dev, 2); - } - - return 0; -} - -static int cx23885_audio_mux(struct cx23885_dev *dev, unsigned int input) -{ - dprintk(1, "%s(input=%d)\n", __func__, input); - - /* The baseband video core of the cx23885 has two audio inputs. - * LR1 and LR2. In almost every single case so far only HVR1xxx - * cards we've only ever supported LR1. Time to support LR2, - * which is available via the optional white breakout header on - * the board. - * We'll use a could of existing enums in the card struct to allow - * devs to specify which baseband input they need, or just default - * to what we've always used. - */ - if (INPUT(input)->amux == CX25840_AUDIO7) - cx23885_flatiron_mux(dev, 1); - else if (INPUT(input)->amux == CX25840_AUDIO6) - cx23885_flatiron_mux(dev, 2); - else { - /* Not specifically defined, assume the default. */ - cx23885_flatiron_mux(dev, 1); - } - - return 0; -} - -/* ------------------------------------------------------------------ */ -static int cx23885_start_video_dma(struct cx23885_dev *dev, - struct cx23885_dmaqueue *q, - struct cx23885_buffer *buf) -{ - dprintk(1, "%s()\n", __func__); - - /* Stop the dma/fifo before we tamper with it's risc programs */ - cx_clear(VID_A_DMA_CTL, 0x11); - - /* setup fifo + format */ - cx23885_sram_channel_setup(dev, &dev->sram_channels[SRAM_CH01], - buf->bpl, buf->risc.dma); - - /* reset counter */ - cx_write(VID_A_GPCNT_CTL, 3); - q->count = 1; - - /* enable irq */ - cx23885_irq_add_enable(dev, 0x01); - cx_set(VID_A_INT_MSK, 0x000011); - - /* start dma */ - cx_set(DEV_CNTRL2, (1<<5)); - cx_set(VID_A_DMA_CTL, 0x11); /* FIFO and RISC enable */ - - return 0; -} - - -static int cx23885_restart_video_queue(struct cx23885_dev *dev, - struct cx23885_dmaqueue *q) -{ - struct cx23885_buffer *buf, *prev; - struct list_head *item; - dprintk(1, "%s()\n", __func__); - - if (!list_empty(&q->active)) { - buf = list_entry(q->active.next, struct cx23885_buffer, - vb.queue); - dprintk(2, "restart_queue [%p/%d]: restart dma\n", - buf, buf->vb.i); - cx23885_start_video_dma(dev, q, buf); - list_for_each(item, &q->active) { - buf = list_entry(item, struct cx23885_buffer, - vb.queue); - buf->count = q->count++; - } - mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT); - return 0; - } - - prev = NULL; - for (;;) { - if (list_empty(&q->queued)) - return 0; - buf = list_entry(q->queued.next, struct cx23885_buffer, - vb.queue); - if (NULL == prev) { - list_move_tail(&buf->vb.queue, &q->active); - cx23885_start_video_dma(dev, q, buf); - buf->vb.state = VIDEOBUF_ACTIVE; - buf->count = q->count++; - mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT); - dprintk(2, "[%p/%d] restart_queue - first active\n", - buf, buf->vb.i); - - } else if (prev->vb.width == buf->vb.width && - prev->vb.height == buf->vb.height && - prev->fmt == buf->fmt) { - list_move_tail(&buf->vb.queue, &q->active); - buf->vb.state = VIDEOBUF_ACTIVE; - buf->count = q->count++; - prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma); - prev->risc.jmp[2] = cpu_to_le32(0); /* Bits 63 - 32 */ - dprintk(2, "[%p/%d] restart_queue - move to active\n", - buf, buf->vb.i); - } else { - return 0; - } - prev = buf; - } -} - -static int buffer_setup(struct videobuf_queue *q, unsigned int *count, - unsigned int *size) -{ - struct cx23885_fh *fh = q->priv_data; - - *size = fh->fmt->depth*fh->width*fh->height >> 3; - if (0 == *count) - *count = 32; - if (*size * *count > vid_limit * 1024 * 1024) - *count = (vid_limit * 1024 * 1024) / *size; - return 0; -} - -static int buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb, - enum v4l2_field field) -{ - struct cx23885_fh *fh = q->priv_data; - struct cx23885_dev *dev = fh->dev; - struct cx23885_buffer *buf = - container_of(vb, struct cx23885_buffer, vb); - int rc, init_buffer = 0; - u32 line0_offset, line1_offset; - struct videobuf_dmabuf *dma = videobuf_to_dma(&buf->vb); - int field_tff; - - BUG_ON(NULL == fh->fmt); - if (fh->width < 48 || fh->width > norm_maxw(dev->tvnorm) || - fh->height < 32 || fh->height > norm_maxh(dev->tvnorm)) - return -EINVAL; - buf->vb.size = (fh->width * fh->height * fh->fmt->depth) >> 3; - if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size) - return -EINVAL; - - if (buf->fmt != fh->fmt || - buf->vb.width != fh->width || - buf->vb.height != fh->height || - buf->vb.field != field) { - buf->fmt = fh->fmt; - buf->vb.width = fh->width; - buf->vb.height = fh->height; - buf->vb.field = field; - init_buffer = 1; - } - - if (VIDEOBUF_NEEDS_INIT == buf->vb.state) { - init_buffer = 1; - rc = videobuf_iolock(q, &buf->vb, NULL); - if (0 != rc) - goto fail; - } - - if (init_buffer) { - buf->bpl = buf->vb.width * buf->fmt->depth >> 3; - switch (buf->vb.field) { - case V4L2_FIELD_TOP: - cx23885_risc_buffer(dev->pci, &buf->risc, - dma->sglist, 0, UNSET, - buf->bpl, 0, buf->vb.height); - break; - case V4L2_FIELD_BOTTOM: - cx23885_risc_buffer(dev->pci, &buf->risc, - dma->sglist, UNSET, 0, - buf->bpl, 0, buf->vb.height); - break; - case V4L2_FIELD_INTERLACED: - if (dev->tvnorm & V4L2_STD_NTSC) - /* NTSC or */ - field_tff = 1; - else - field_tff = 0; - - if (cx23885_boards[dev->board].force_bff) - /* PAL / SECAM OR 888 in NTSC MODE */ - field_tff = 0; - - if (field_tff) { - /* cx25840 transmits NTSC bottom field first */ - dprintk(1, "%s() Creating TFF/NTSC risc\n", - __func__); - line0_offset = buf->bpl; - line1_offset = 0; - } else { - /* All other formats are top field first */ - dprintk(1, "%s() Creating BFF/PAL/SECAM risc\n", - __func__); - line0_offset = 0; - line1_offset = buf->bpl; - } - cx23885_risc_buffer(dev->pci, &buf->risc, - dma->sglist, line0_offset, - line1_offset, - buf->bpl, buf->bpl, - buf->vb.height >> 1); - break; - case V4L2_FIELD_SEQ_TB: - cx23885_risc_buffer(dev->pci, &buf->risc, - dma->sglist, - 0, buf->bpl * (buf->vb.height >> 1), - buf->bpl, 0, - buf->vb.height >> 1); - break; - case V4L2_FIELD_SEQ_BT: - cx23885_risc_buffer(dev->pci, &buf->risc, - dma->sglist, - buf->bpl * (buf->vb.height >> 1), 0, - buf->bpl, 0, - buf->vb.height >> 1); - break; - default: - BUG(); - } - } - dprintk(2, "[%p/%d] buffer_prep - %dx%d %dbpp \"%s\" - dma=0x%08lx\n", - buf, buf->vb.i, - fh->width, fh->height, fh->fmt->depth, fh->fmt->name, - (unsigned long)buf->risc.dma); - - buf->vb.state = VIDEOBUF_PREPARED; - return 0; - - fail: - cx23885_free_buffer(q, buf); - return rc; -} - -static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb) -{ - struct cx23885_buffer *buf = container_of(vb, - struct cx23885_buffer, vb); - struct cx23885_buffer *prev; - struct cx23885_fh *fh = vq->priv_data; - struct cx23885_dev *dev = fh->dev; - struct cx23885_dmaqueue *q = &dev->vidq; - - /* add jump to stopper */ - buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC); - buf->risc.jmp[1] = cpu_to_le32(q->stopper.dma); - buf->risc.jmp[2] = cpu_to_le32(0); /* bits 63-32 */ - - if (!list_empty(&q->queued)) { - list_add_tail(&buf->vb.queue, &q->queued); - buf->vb.state = VIDEOBUF_QUEUED; - dprintk(2, "[%p/%d] buffer_queue - append to queued\n", - buf, buf->vb.i); - - } else if (list_empty(&q->active)) { - list_add_tail(&buf->vb.queue, &q->active); - cx23885_start_video_dma(dev, q, buf); - buf->vb.state = VIDEOBUF_ACTIVE; - buf->count = q->count++; - mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT); - dprintk(2, "[%p/%d] buffer_queue - first active\n", - buf, buf->vb.i); - - } else { - prev = list_entry(q->active.prev, struct cx23885_buffer, - vb.queue); - if (prev->vb.width == buf->vb.width && - prev->vb.height == buf->vb.height && - prev->fmt == buf->fmt) { - list_add_tail(&buf->vb.queue, &q->active); - buf->vb.state = VIDEOBUF_ACTIVE; - buf->count = q->count++; - prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma); - /* 64 bit bits 63-32 */ - prev->risc.jmp[2] = cpu_to_le32(0); - dprintk(2, "[%p/%d] buffer_queue - append to active\n", - buf, buf->vb.i); - - } else { - list_add_tail(&buf->vb.queue, &q->queued); - buf->vb.state = VIDEOBUF_QUEUED; - dprintk(2, "[%p/%d] buffer_queue - first queued\n", - buf, buf->vb.i); - } - } -} - -static void buffer_release(struct videobuf_queue *q, - struct videobuf_buffer *vb) -{ - struct cx23885_buffer *buf = container_of(vb, - struct cx23885_buffer, vb); - - cx23885_free_buffer(q, buf); -} - -static struct videobuf_queue_ops cx23885_video_qops = { - .buf_setup = buffer_setup, - .buf_prepare = buffer_prepare, - .buf_queue = buffer_queue, - .buf_release = buffer_release, -}; - -static struct videobuf_queue *get_queue(struct cx23885_fh *fh) -{ - switch (fh->type) { - case V4L2_BUF_TYPE_VIDEO_CAPTURE: - return &fh->vidq; - case V4L2_BUF_TYPE_VBI_CAPTURE: - return &fh->vbiq; - default: - BUG(); - return NULL; - } -} - -static int get_resource(struct cx23885_fh *fh) -{ - switch (fh->type) { - case V4L2_BUF_TYPE_VIDEO_CAPTURE: - return RESOURCE_VIDEO; - case V4L2_BUF_TYPE_VBI_CAPTURE: - return RESOURCE_VBI; - default: - BUG(); - return 0; - } -} - -static int video_open(struct file *file) -{ - struct video_device *vdev = video_devdata(file); - struct cx23885_dev *dev = video_drvdata(file); - struct cx23885_fh *fh; - enum v4l2_buf_type type = 0; - int radio = 0; - - switch (vdev->vfl_type) { - case VFL_TYPE_GRABBER: - type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - break; - case VFL_TYPE_VBI: - type = V4L2_BUF_TYPE_VBI_CAPTURE; - break; - case VFL_TYPE_RADIO: - radio = 1; - break; - } - - dprintk(1, "open dev=%s radio=%d type=%s\n", - video_device_node_name(vdev), radio, v4l2_type_names[type]); - - /* allocate + initialize per filehandle data */ - fh = kzalloc(sizeof(*fh), GFP_KERNEL); - if (NULL == fh) - return -ENOMEM; - - file->private_data = fh; - fh->dev = dev; - fh->radio = radio; - fh->type = type; - fh->width = 320; - fh->height = 240; - fh->fmt = format_by_fourcc(V4L2_PIX_FMT_YUYV); - - videobuf_queue_sg_init(&fh->vidq, &cx23885_video_qops, - &dev->pci->dev, &dev->slock, - V4L2_BUF_TYPE_VIDEO_CAPTURE, - V4L2_FIELD_INTERLACED, - sizeof(struct cx23885_buffer), - fh, NULL); - - videobuf_queue_sg_init(&fh->vbiq, &cx23885_vbi_qops, - &dev->pci->dev, &dev->slock, - V4L2_BUF_TYPE_VBI_CAPTURE, - V4L2_FIELD_SEQ_TB, - sizeof(struct cx23885_buffer), - fh, NULL); - - - dprintk(1, "post videobuf_queue_init()\n"); - - return 0; -} - -static ssize_t video_read(struct file *file, char __user *data, - size_t count, loff_t *ppos) -{ - struct cx23885_fh *fh = file->private_data; - - switch (fh->type) { - case V4L2_BUF_TYPE_VIDEO_CAPTURE: - if (res_locked(fh->dev, RESOURCE_VIDEO)) - return -EBUSY; - return videobuf_read_one(&fh->vidq, data, count, ppos, - file->f_flags & O_NONBLOCK); - case V4L2_BUF_TYPE_VBI_CAPTURE: - if (!res_get(fh->dev, fh, RESOURCE_VBI)) - return -EBUSY; - return videobuf_read_stream(&fh->vbiq, data, count, ppos, 1, - file->f_flags & O_NONBLOCK); - default: - BUG(); - return 0; - } -} - -static unsigned int video_poll(struct file *file, - struct poll_table_struct *wait) -{ - struct cx23885_fh *fh = file->private_data; - struct cx23885_buffer *buf; - unsigned int rc = POLLERR; - - if (V4L2_BUF_TYPE_VBI_CAPTURE == fh->type) { - if (!res_get(fh->dev, fh, RESOURCE_VBI)) - return POLLERR; - return videobuf_poll_stream(file, &fh->vbiq, wait); - } - - mutex_lock(&fh->vidq.vb_lock); - if (res_check(fh, RESOURCE_VIDEO)) { - /* streaming capture */ - if (list_empty(&fh->vidq.stream)) - goto done; - buf = list_entry(fh->vidq.stream.next, - struct cx23885_buffer, vb.stream); - } else { - /* read() capture */ - buf = (struct cx23885_buffer *)fh->vidq.read_buf; - if (NULL == buf) - goto done; - } - poll_wait(file, &buf->vb.done, wait); - if (buf->vb.state == VIDEOBUF_DONE || - buf->vb.state == VIDEOBUF_ERROR) - rc = POLLIN|POLLRDNORM; - else - rc = 0; -done: - mutex_unlock(&fh->vidq.vb_lock); - return rc; -} - -static int video_release(struct file *file) -{ - struct cx23885_fh *fh = file->private_data; - struct cx23885_dev *dev = fh->dev; - - /* turn off overlay */ - if (res_check(fh, RESOURCE_OVERLAY)) { - /* FIXME */ - res_free(dev, fh, RESOURCE_OVERLAY); - } - - /* stop video capture */ - if (res_check(fh, RESOURCE_VIDEO)) { - videobuf_queue_cancel(&fh->vidq); - res_free(dev, fh, RESOURCE_VIDEO); - } - if (fh->vidq.read_buf) { - buffer_release(&fh->vidq, fh->vidq.read_buf); - kfree(fh->vidq.read_buf); - } - - /* stop vbi capture */ - if (res_check(fh, RESOURCE_VBI)) { - if (fh->vbiq.streaming) - videobuf_streamoff(&fh->vbiq); - if (fh->vbiq.reading) - videobuf_read_stop(&fh->vbiq); - res_free(dev, fh, RESOURCE_VBI); - } - - videobuf_mmap_free(&fh->vidq); - videobuf_mmap_free(&fh->vbiq); - - file->private_data = NULL; - kfree(fh); - - /* We are not putting the tuner to sleep here on exit, because - * we want to use the mpeg encoder in another session to capture - * tuner video. Closing this will result in no video to the encoder. - */ - - return 0; -} - -static int video_mmap(struct file *file, struct vm_area_struct *vma) -{ - struct cx23885_fh *fh = file->private_data; - - return videobuf_mmap_mapper(get_queue(fh), vma); -} - -/* ------------------------------------------------------------------ */ -/* VIDEO CTRL IOCTLS */ - -int cx23885_get_control(struct cx23885_dev *dev, - struct v4l2_control *ctl) -{ - dprintk(1, "%s() calling cx25840(VIDIOC_G_CTRL)\n", __func__); - call_all(dev, core, g_ctrl, ctl); - return 0; -} - -int cx23885_set_control(struct cx23885_dev *dev, - struct v4l2_control *ctl) -{ - dprintk(1, "%s() calling cx25840(VIDIOC_S_CTRL)\n", __func__); - call_all(dev, core, s_ctrl, ctl); - - return 0; -} - -static void init_controls(struct cx23885_dev *dev) -{ - struct v4l2_control ctrl; - int i; - - for (i = 0; i < CX23885_CTLS; i++) { - ctrl.id = cx23885_ctls[i].v.id; - ctrl.value = cx23885_ctls[i].v.default_value; - - cx23885_set_control(dev, &ctrl); - } -} - -/* ------------------------------------------------------------------ */ -/* VIDEO IOCTLS */ - -static int vidioc_g_fmt_vid_cap(struct file *file, void *priv, - struct v4l2_format *f) -{ - struct cx23885_fh *fh = priv; - - f->fmt.pix.width = fh->width; - f->fmt.pix.height = fh->height; - f->fmt.pix.field = fh->vidq.field; - f->fmt.pix.pixelformat = fh->fmt->fourcc; - f->fmt.pix.bytesperline = - (f->fmt.pix.width * fh->fmt->depth) >> 3; - f->fmt.pix.sizeimage = - f->fmt.pix.height * f->fmt.pix.bytesperline; - - return 0; -} - -static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, - struct v4l2_format *f) -{ - struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev; - struct cx23885_fmt *fmt; - enum v4l2_field field; - unsigned int maxw, maxh; - - fmt = format_by_fourcc(f->fmt.pix.pixelformat); - if (NULL == fmt) - return -EINVAL; - - field = f->fmt.pix.field; - maxw = norm_maxw(dev->tvnorm); - maxh = norm_maxh(dev->tvnorm); - - if (V4L2_FIELD_ANY == field) { - field = (f->fmt.pix.height > maxh/2) - ? V4L2_FIELD_INTERLACED - : V4L2_FIELD_BOTTOM; - } - - switch (field) { - case V4L2_FIELD_TOP: - case V4L2_FIELD_BOTTOM: - maxh = maxh / 2; - break; - case V4L2_FIELD_INTERLACED: - break; - default: - return -EINVAL; - } - - f->fmt.pix.field = field; - v4l_bound_align_image(&f->fmt.pix.width, 48, maxw, 2, - &f->fmt.pix.height, 32, maxh, 0, 0); - f->fmt.pix.bytesperline = - (f->fmt.pix.width * fmt->depth) >> 3; - f->fmt.pix.sizeimage = - f->fmt.pix.height * f->fmt.pix.bytesperline; - - return 0; -} - -static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, - struct v4l2_format *f) -{ - struct cx23885_fh *fh = priv; - struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev; - struct v4l2_mbus_framefmt mbus_fmt; - int err; - - dprintk(2, "%s()\n", __func__); - err = vidioc_try_fmt_vid_cap(file, priv, f); - - if (0 != err) - return err; - fh->fmt = format_by_fourcc(f->fmt.pix.pixelformat); - fh->width = f->fmt.pix.width; - fh->height = f->fmt.pix.height; - fh->vidq.field = f->fmt.pix.field; - dprintk(2, "%s() width=%d height=%d field=%d\n", __func__, - fh->width, fh->height, fh->vidq.field); - v4l2_fill_mbus_format(&mbus_fmt, &f->fmt.pix, V4L2_MBUS_FMT_FIXED); - call_all(dev, video, s_mbus_fmt, &mbus_fmt); - v4l2_fill_pix_format(&f->fmt.pix, &mbus_fmt); - return 0; -} - -static int vidioc_querycap(struct file *file, void *priv, - struct v4l2_capability *cap) -{ - struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev; - - strcpy(cap->driver, "cx23885"); - strlcpy(cap->card, cx23885_boards[dev->board].name, - sizeof(cap->card)); - sprintf(cap->bus_info, "PCIe:%s", pci_name(dev->pci)); - cap->capabilities = - V4L2_CAP_VIDEO_CAPTURE | - V4L2_CAP_READWRITE | - V4L2_CAP_STREAMING | - V4L2_CAP_VBI_CAPTURE; - if (UNSET != dev->tuner_type) - cap->capabilities |= V4L2_CAP_TUNER; - return 0; -} - -static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv, - struct v4l2_fmtdesc *f) -{ - if (unlikely(f->index >= ARRAY_SIZE(formats))) - return -EINVAL; - - strlcpy(f->description, formats[f->index].name, - sizeof(f->description)); - f->pixelformat = formats[f->index].fourcc; - - return 0; -} - -static int vidioc_reqbufs(struct file *file, void *priv, - struct v4l2_requestbuffers *p) -{ - struct cx23885_fh *fh = priv; - return videobuf_reqbufs(get_queue(fh), p); -} - -static int vidioc_querybuf(struct file *file, void *priv, - struct v4l2_buffer *p) -{ - struct cx23885_fh *fh = priv; - return videobuf_querybuf(get_queue(fh), p); -} - -static int vidioc_qbuf(struct file *file, void *priv, - struct v4l2_buffer *p) -{ - struct cx23885_fh *fh = priv; - return videobuf_qbuf(get_queue(fh), p); -} - -static int vidioc_dqbuf(struct file *file, void *priv, - struct v4l2_buffer *p) -{ - struct cx23885_fh *fh = priv; - return videobuf_dqbuf(get_queue(fh), p, - file->f_flags & O_NONBLOCK); -} - -static int vidioc_streamon(struct file *file, void *priv, - enum v4l2_buf_type i) -{ - struct cx23885_fh *fh = priv; - struct cx23885_dev *dev = fh->dev; - dprintk(1, "%s()\n", __func__); - - if ((fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) && - (fh->type != V4L2_BUF_TYPE_VBI_CAPTURE)) - return -EINVAL; - if (unlikely(i != fh->type)) - return -EINVAL; - - if (unlikely(!res_get(dev, fh, get_resource(fh)))) - return -EBUSY; - - /* Don't start VBI streaming unless vida streaming - * has already started. - */ - if ((fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) && - ((cx_read(VID_A_DMA_CTL) & 0x11) == 0)) - return -EINVAL; - - return videobuf_streamon(get_queue(fh)); -} - -static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i) -{ - struct cx23885_fh *fh = priv; - struct cx23885_dev *dev = fh->dev; - int err, res; - dprintk(1, "%s()\n", __func__); - - if ((fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) && - (fh->type != V4L2_BUF_TYPE_VBI_CAPTURE)) - return -EINVAL; - if (i != fh->type) - return -EINVAL; - - res = get_resource(fh); - err = videobuf_streamoff(get_queue(fh)); - if (err < 0) - return err; - res_free(dev, fh, res); - return 0; -} - -static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *id) -{ - struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev; - dprintk(1, "%s()\n", __func__); - - call_all(dev, core, g_std, id); - - return 0; -} - -static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *tvnorms) -{ - struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev; - dprintk(1, "%s()\n", __func__); - - mutex_lock(&dev->lock); - cx23885_set_tvnorm(dev, *tvnorms); - mutex_unlock(&dev->lock); - - return 0; -} - -int cx23885_enum_input(struct cx23885_dev *dev, struct v4l2_input *i) -{ - static const char *iname[] = { - [CX23885_VMUX_COMPOSITE1] = "Composite1", - [CX23885_VMUX_COMPOSITE2] = "Composite2", - [CX23885_VMUX_COMPOSITE3] = "Composite3", - [CX23885_VMUX_COMPOSITE4] = "Composite4", - [CX23885_VMUX_SVIDEO] = "S-Video", - [CX23885_VMUX_COMPONENT] = "Component", - [CX23885_VMUX_TELEVISION] = "Television", - [CX23885_VMUX_CABLE] = "Cable TV", - [CX23885_VMUX_DVB] = "DVB", - [CX23885_VMUX_DEBUG] = "for debug only", - }; - unsigned int n; - dprintk(1, "%s()\n", __func__); - - n = i->index; - if (n >= MAX_CX23885_INPUT) - return -EINVAL; - - if (0 == INPUT(n)->type) - return -EINVAL; - - i->index = n; - i->type = V4L2_INPUT_TYPE_CAMERA; - strcpy(i->name, iname[INPUT(n)->type]); - if ((CX23885_VMUX_TELEVISION == INPUT(n)->type) || - (CX23885_VMUX_CABLE == INPUT(n)->type)) { - i->type = V4L2_INPUT_TYPE_TUNER; - i->std = CX23885_NORMS; - } - - /* Two selectable audio inputs for non-tv inputs */ - if (INPUT(n)->type != CX23885_VMUX_TELEVISION) - i->audioset = 0x3; - - if (dev->input == n) { - /* enum'd input matches our configured input. - * Ask the video decoder to process the call - * and give it an oppertunity to update the - * status field. - */ - call_all(dev, video, g_input_status, &i->status); - } - - return 0; -} - -static int vidioc_enum_input(struct file *file, void *priv, - struct v4l2_input *i) -{ - struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev; - dprintk(1, "%s()\n", __func__); - return cx23885_enum_input(dev, i); -} - -int cx23885_get_input(struct file *file, void *priv, unsigned int *i) -{ - struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev; - - *i = dev->input; - dprintk(1, "%s() returns %d\n", __func__, *i); - return 0; -} - -static int vidioc_g_input(struct file *file, void *priv, unsigned int *i) -{ - return cx23885_get_input(file, priv, i); -} - -int cx23885_set_input(struct file *file, void *priv, unsigned int i) -{ - struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev; - - dprintk(1, "%s(%d)\n", __func__, i); - - if (i >= MAX_CX23885_INPUT) { - dprintk(1, "%s() -EINVAL\n", __func__); - return -EINVAL; - } - - if (INPUT(i)->type == 0) - return -EINVAL; - - mutex_lock(&dev->lock); - cx23885_video_mux(dev, i); - - /* By default establish the default audio input for the card also */ - /* Caller is free to use VIDIOC_S_AUDIO to override afterwards */ - cx23885_audio_mux(dev, i); - mutex_unlock(&dev->lock); - return 0; -} - -static int vidioc_s_input(struct file *file, void *priv, unsigned int i) -{ - return cx23885_set_input(file, priv, i); -} - -static int vidioc_log_status(struct file *file, void *priv) -{ - struct cx23885_fh *fh = priv; - struct cx23885_dev *dev = fh->dev; - - printk(KERN_INFO - "%s/0: ============ START LOG STATUS ============\n", - dev->name); - call_all(dev, core, log_status); - printk(KERN_INFO - "%s/0: ============= END LOG STATUS =============\n", - dev->name); - return 0; -} - -static int cx23885_query_audinput(struct file *file, void *priv, - struct v4l2_audio *i) -{ - struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev; - static const char *iname[] = { - [0] = "Baseband L/R 1", - [1] = "Baseband L/R 2", - }; - unsigned int n; - dprintk(1, "%s()\n", __func__); - - n = i->index; - if (n >= 2) - return -EINVAL; - - memset(i, 0, sizeof(*i)); - i->index = n; - strcpy(i->name, iname[n]); - i->capability = V4L2_AUDCAP_STEREO; - i->mode = V4L2_AUDMODE_AVL; - return 0; - -} - -static int vidioc_enum_audinput(struct file *file, void *priv, - struct v4l2_audio *i) -{ - return cx23885_query_audinput(file, priv, i); -} - -static int vidioc_g_audinput(struct file *file, void *priv, - struct v4l2_audio *i) -{ - struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev; - - i->index = dev->audinput; - dprintk(1, "%s(input=%d)\n", __func__, i->index); - - return cx23885_query_audinput(file, priv, i); -} - -static int vidioc_s_audinput(struct file *file, void *priv, - struct v4l2_audio *i) -{ - struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev; - if (i->index >= 2) - return -EINVAL; - - dprintk(1, "%s(%d)\n", __func__, i->index); - - dev->audinput = i->index; - - /* Skip the audio defaults from the cards struct, caller wants - * directly touch the audio mux hardware. */ - cx23885_flatiron_mux(dev, dev->audinput + 1); - return 0; -} - -static int vidioc_queryctrl(struct file *file, void *priv, - struct v4l2_queryctrl *qctrl) -{ - qctrl->id = v4l2_ctrl_next(ctrl_classes, qctrl->id); - if (unlikely(qctrl->id == 0)) - return -EINVAL; - return cx23885_ctrl_query(qctrl); -} - -static int vidioc_g_ctrl(struct file *file, void *priv, - struct v4l2_control *ctl) -{ - struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev; - - return cx23885_get_control(dev, ctl); -} - -static int vidioc_s_ctrl(struct file *file, void *priv, - struct v4l2_control *ctl) -{ - struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev; - - return cx23885_set_control(dev, ctl); -} - -static int vidioc_g_tuner(struct file *file, void *priv, - struct v4l2_tuner *t) -{ - struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev; - - if (unlikely(UNSET == dev->tuner_type)) - return -EINVAL; - if (0 != t->index) - return -EINVAL; - - strcpy(t->name, "Television"); - - call_all(dev, tuner, g_tuner, t); - return 0; -} - -static int vidioc_s_tuner(struct file *file, void *priv, - struct v4l2_tuner *t) -{ - struct cx23885_dev *dev = ((struct cx23885_fh *)priv)->dev; - - if (UNSET == dev->tuner_type) - return -EINVAL; - if (0 != t->index) - return -EINVAL; - /* Update the A/V core */ - call_all(dev, tuner, s_tuner, t); - - return 0; -} - -static int vidioc_g_frequency(struct file *file, void *priv, - struct v4l2_frequency *f) -{ - struct cx23885_fh *fh = priv; - struct cx23885_dev *dev = fh->dev; - - if (unlikely(UNSET == dev->tuner_type)) - return -EINVAL; - - /* f->type = fh->radio ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; */ - f->type = fh->radio ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; - f->frequency = dev->freq; - - call_all(dev, tuner, g_frequency, f); - - return 0; -} - -static int cx23885_set_freq(struct cx23885_dev *dev, struct v4l2_frequency *f) -{ - struct v4l2_control ctrl; - - if (unlikely(UNSET == dev->tuner_type)) - return -EINVAL; - if (unlikely(f->tuner != 0)) - return -EINVAL; - - mutex_lock(&dev->lock); - dev->freq = f->frequency; - - /* I need to mute audio here */ - ctrl.id = V4L2_CID_AUDIO_MUTE; - ctrl.value = 1; - cx23885_set_control(dev, &ctrl); - - call_all(dev, tuner, s_frequency, f); - - /* When changing channels it is required to reset TVAUDIO */ - msleep(100); - - /* I need to unmute audio here */ - ctrl.value = 0; - cx23885_set_control(dev, &ctrl); - - mutex_unlock(&dev->lock); - - return 0; -} - -static int cx23885_set_freq_via_ops(struct cx23885_dev *dev, - struct v4l2_frequency *f) -{ - struct v4l2_control ctrl; - struct videobuf_dvb_frontend *vfe; - struct dvb_frontend *fe; - - struct analog_parameters params = { - .mode = V4L2_TUNER_ANALOG_TV, - .audmode = V4L2_TUNER_MODE_STEREO, - .std = dev->tvnorm, - .frequency = f->frequency - }; - - mutex_lock(&dev->lock); - dev->freq = f->frequency; - - /* I need to mute audio here */ - ctrl.id = V4L2_CID_AUDIO_MUTE; - ctrl.value = 1; - cx23885_set_control(dev, &ctrl); - - /* If HVR1850 */ - dprintk(1, "%s() frequency=%d tuner=%d std=0x%llx\n", __func__, - params.frequency, f->tuner, params.std); - - vfe = videobuf_dvb_get_frontend(&dev->ts2.frontends, 1); - if (!vfe) { - mutex_unlock(&dev->lock); - return -EINVAL; - } - - fe = vfe->dvb.frontend; - - if ((dev->board == CX23885_BOARD_HAUPPAUGE_HVR1850) || - (dev->board == CX23885_BOARD_HAUPPAUGE_HVR1255) || - (dev->board == CX23885_BOARD_HAUPPAUGE_HVR1255_22111)) - fe = &dev->ts1.analog_fe; - - if (fe && fe->ops.tuner_ops.set_analog_params) { - call_all(dev, core, s_std, dev->tvnorm); - fe->ops.tuner_ops.set_analog_params(fe, ¶ms); - } - else - printk(KERN_ERR "%s() No analog tuner, aborting\n", __func__); - - /* When changing channels it is required to reset TVAUDIO */ - msleep(100); - - /* I need to unmute audio here */ - ctrl.value = 0; - cx23885_set_control(dev, &ctrl); - - mutex_unlock(&dev->lock); - - return 0; -} - -int cx23885_set_frequency(struct file *file, void *priv, - struct v4l2_frequency *f) -{ - struct cx23885_fh *fh = priv; - struct cx23885_dev *dev = fh->dev; - int ret; - - switch (dev->board) { - case CX23885_BOARD_HAUPPAUGE_HVR1255: - case CX23885_BOARD_HAUPPAUGE_HVR1255_22111: - case CX23885_BOARD_HAUPPAUGE_HVR1850: - ret = cx23885_set_freq_via_ops(dev, f); - break; - default: - ret = cx23885_set_freq(dev, f); - } - - return ret; -} - -static int vidioc_s_frequency(struct file *file, void *priv, - struct v4l2_frequency *f) -{ - return cx23885_set_frequency(file, priv, f); -} - -/* ----------------------------------------------------------- */ - -static void cx23885_vid_timeout(unsigned long data) -{ - struct cx23885_dev *dev = (struct cx23885_dev *)data; - struct cx23885_dmaqueue *q = &dev->vidq; - struct cx23885_buffer *buf; - unsigned long flags; - - spin_lock_irqsave(&dev->slock, flags); - while (!list_empty(&q->active)) { - buf = list_entry(q->active.next, - struct cx23885_buffer, vb.queue); - list_del(&buf->vb.queue); - buf->vb.state = VIDEOBUF_ERROR; - wake_up(&buf->vb.done); - printk(KERN_ERR "%s: [%p/%d] timeout - dma=0x%08lx\n", - dev->name, buf, buf->vb.i, - (unsigned long)buf->risc.dma); - } - cx23885_restart_video_queue(dev, q); - spin_unlock_irqrestore(&dev->slock, flags); -} - -int cx23885_video_irq(struct cx23885_dev *dev, u32 status) -{ - u32 mask, count; - int handled = 0; - - mask = cx_read(VID_A_INT_MSK); - if (0 == (status & mask)) - return handled; - - cx_write(VID_A_INT_STAT, status); - - /* risc op code error, fifo overflow or line sync detection error */ - if ((status & VID_BC_MSK_OPC_ERR) || - (status & VID_BC_MSK_SYNC) || - (status & VID_BC_MSK_OF)) { - - if (status & VID_BC_MSK_OPC_ERR) { - dprintk(7, " (VID_BC_MSK_OPC_ERR 0x%08x)\n", - VID_BC_MSK_OPC_ERR); - printk(KERN_WARNING "%s: video risc op code error\n", - dev->name); - cx23885_sram_channel_dump(dev, - &dev->sram_channels[SRAM_CH01]); - } - - if (status & VID_BC_MSK_SYNC) - dprintk(7, " (VID_BC_MSK_SYNC 0x%08x) " - "video lines miss-match\n", - VID_BC_MSK_SYNC); - - if (status & VID_BC_MSK_OF) - dprintk(7, " (VID_BC_MSK_OF 0x%08x) fifo overflow\n", - VID_BC_MSK_OF); - - } - - /* Video */ - if (status & VID_BC_MSK_RISCI1) { - spin_lock(&dev->slock); - count = cx_read(VID_A_GPCNT); - cx23885_video_wakeup(dev, &dev->vidq, count); - spin_unlock(&dev->slock); - handled++; - } - if (status & VID_BC_MSK_RISCI2) { - dprintk(2, "stopper video\n"); - spin_lock(&dev->slock); - cx23885_restart_video_queue(dev, &dev->vidq); - spin_unlock(&dev->slock); - handled++; - } - - /* Allow the VBI framework to process it's payload */ - handled += cx23885_vbi_irq(dev, status); - - return handled; -} - -/* ----------------------------------------------------------- */ -/* exported stuff */ - -static const struct v4l2_file_operations video_fops = { - .owner = THIS_MODULE, - .open = video_open, - .release = video_release, - .read = video_read, - .poll = video_poll, - .mmap = video_mmap, - .ioctl = video_ioctl2, -}; - -static const struct v4l2_ioctl_ops video_ioctl_ops = { - .vidioc_querycap = vidioc_querycap, - .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap, - .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap, - .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap, - .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap, - .vidioc_g_fmt_vbi_cap = cx23885_vbi_fmt, - .vidioc_try_fmt_vbi_cap = cx23885_vbi_fmt, - .vidioc_s_fmt_vbi_cap = cx23885_vbi_fmt, - .vidioc_reqbufs = vidioc_reqbufs, - .vidioc_querybuf = vidioc_querybuf, - .vidioc_qbuf = vidioc_qbuf, - .vidioc_dqbuf = vidioc_dqbuf, - .vidioc_s_std = vidioc_s_std, - .vidioc_g_std = vidioc_g_std, - .vidioc_querystd = vidioc_g_std, - .vidioc_enum_input = vidioc_enum_input, - .vidioc_g_input = vidioc_g_input, - .vidioc_s_input = vidioc_s_input, - .vidioc_log_status = vidioc_log_status, - .vidioc_queryctrl = vidioc_queryctrl, - .vidioc_g_ctrl = vidioc_g_ctrl, - .vidioc_s_ctrl = vidioc_s_ctrl, - .vidioc_streamon = vidioc_streamon, - .vidioc_streamoff = vidioc_streamoff, - .vidioc_g_tuner = vidioc_g_tuner, - .vidioc_s_tuner = vidioc_s_tuner, - .vidioc_g_frequency = vidioc_g_frequency, - .vidioc_s_frequency = vidioc_s_frequency, - .vidioc_g_chip_ident = cx23885_g_chip_ident, -#ifdef CONFIG_VIDEO_ADV_DEBUG - .vidioc_g_register = cx23885_g_register, - .vidioc_s_register = cx23885_s_register, -#endif - .vidioc_enumaudio = vidioc_enum_audinput, - .vidioc_g_audio = vidioc_g_audinput, - .vidioc_s_audio = vidioc_s_audinput, -}; - -static struct video_device cx23885_vbi_template; -static struct video_device cx23885_video_template = { - .name = "cx23885-video", - .fops = &video_fops, - .ioctl_ops = &video_ioctl_ops, - .tvnorms = CX23885_NORMS, - .current_norm = V4L2_STD_NTSC_M, -}; - -static const struct v4l2_file_operations radio_fops = { - .owner = THIS_MODULE, - .open = video_open, - .release = video_release, - .ioctl = video_ioctl2, -}; - - -void cx23885_video_unregister(struct cx23885_dev *dev) -{ - dprintk(1, "%s()\n", __func__); - cx23885_irq_remove(dev, 0x01); - - if (dev->vbi_dev) { - if (video_is_registered(dev->vbi_dev)) - video_unregister_device(dev->vbi_dev); - else - video_device_release(dev->vbi_dev); - dev->vbi_dev = NULL; - btcx_riscmem_free(dev->pci, &dev->vbiq.stopper); - } - if (dev->video_dev) { - if (video_is_registered(dev->video_dev)) - video_unregister_device(dev->video_dev); - else - video_device_release(dev->video_dev); - dev->video_dev = NULL; - - btcx_riscmem_free(dev->pci, &dev->vidq.stopper); - } - - if (dev->audio_dev) - cx23885_audio_unregister(dev); -} - -int cx23885_video_register(struct cx23885_dev *dev) -{ - int err; - - dprintk(1, "%s()\n", __func__); - spin_lock_init(&dev->slock); - - /* Initialize VBI template */ - memcpy(&cx23885_vbi_template, &cx23885_video_template, - sizeof(cx23885_vbi_template)); - strcpy(cx23885_vbi_template.name, "cx23885-vbi"); - - dev->tvnorm = cx23885_video_template.current_norm; - - /* init video dma queues */ - INIT_LIST_HEAD(&dev->vidq.active); - INIT_LIST_HEAD(&dev->vidq.queued); - dev->vidq.timeout.function = cx23885_vid_timeout; - dev->vidq.timeout.data = (unsigned long)dev; - init_timer(&dev->vidq.timeout); - cx23885_risc_stopper(dev->pci, &dev->vidq.stopper, - VID_A_DMA_CTL, 0x11, 0x00); - - /* init vbi dma queues */ - INIT_LIST_HEAD(&dev->vbiq.active); - INIT_LIST_HEAD(&dev->vbiq.queued); - dev->vbiq.timeout.function = cx23885_vbi_timeout; - dev->vbiq.timeout.data = (unsigned long)dev; - init_timer(&dev->vbiq.timeout); - cx23885_risc_stopper(dev->pci, &dev->vbiq.stopper, - VID_A_DMA_CTL, 0x22, 0x00); - - cx23885_irq_add_enable(dev, 0x01); - - if ((TUNER_ABSENT != dev->tuner_type) && - ((dev->tuner_bus == 0) || (dev->tuner_bus == 1))) { - struct v4l2_subdev *sd = NULL; - - if (dev->tuner_addr) - sd = v4l2_i2c_new_subdev(&dev->v4l2_dev, - &dev->i2c_bus[dev->tuner_bus].i2c_adap, - "tuner", dev->tuner_addr, NULL); - else - sd = v4l2_i2c_new_subdev(&dev->v4l2_dev, - &dev->i2c_bus[dev->tuner_bus].i2c_adap, - "tuner", 0, v4l2_i2c_tuner_addrs(ADDRS_TV)); - if (sd) { - struct tuner_setup tun_setup; - - memset(&tun_setup, 0, sizeof(tun_setup)); - tun_setup.mode_mask = T_ANALOG_TV; - tun_setup.type = dev->tuner_type; - tun_setup.addr = v4l2_i2c_subdev_addr(sd); - tun_setup.tuner_callback = cx23885_tuner_callback; - - v4l2_subdev_call(sd, tuner, s_type_addr, &tun_setup); - - if (dev->board == CX23885_BOARD_LEADTEK_WINFAST_PXTV1200) { - struct xc2028_ctrl ctrl = { - .fname = XC2028_DEFAULT_FIRMWARE, - .max_len = 64 - }; - struct v4l2_priv_tun_config cfg = { - .tuner = dev->tuner_type, - .priv = &ctrl - }; - v4l2_subdev_call(sd, tuner, s_config, &cfg); - } - } - } - - /* register Video device */ - dev->video_dev = cx23885_vdev_init(dev, dev->pci, - &cx23885_video_template, "video"); - err = video_register_device(dev->video_dev, VFL_TYPE_GRABBER, - video_nr[dev->nr]); - if (err < 0) { - printk(KERN_INFO "%s: can't register video device\n", - dev->name); - goto fail_unreg; - } - printk(KERN_INFO "%s: registered device %s [v4l2]\n", - dev->name, video_device_node_name(dev->video_dev)); - - /* register VBI device */ - dev->vbi_dev = cx23885_vdev_init(dev, dev->pci, - &cx23885_vbi_template, "vbi"); - err = video_register_device(dev->vbi_dev, VFL_TYPE_VBI, - vbi_nr[dev->nr]); - if (err < 0) { - printk(KERN_INFO "%s: can't register vbi device\n", - dev->name); - goto fail_unreg; - } - printk(KERN_INFO "%s: registered device %s\n", - dev->name, video_device_node_name(dev->vbi_dev)); - - /* Register ALSA audio device */ - dev->audio_dev = cx23885_audio_register(dev); - - /* initial device configuration */ - mutex_lock(&dev->lock); - cx23885_set_tvnorm(dev, dev->tvnorm); - init_controls(dev); - cx23885_video_mux(dev, 0); - cx23885_audio_mux(dev, 0); - mutex_unlock(&dev->lock); - - return 0; - -fail_unreg: - cx23885_video_unregister(dev); - return err; -} - diff --git a/drivers/media/video/cx23885/cx23885.h b/drivers/media/video/cx23885/cx23885.h deleted file mode 100644 index 5d560c747e0..00000000000 --- a/drivers/media/video/cx23885/cx23885.h +++ /dev/null @@ -1,653 +0,0 @@ -/* - * Driver for the Conexant CX23885 PCIe bridge - * - * Copyright (c) 2006 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 <linux/pci.h> -#include <linux/i2c.h> -#include <linux/kdev_t.h> -#include <linux/slab.h> - -#include <media/v4l2-device.h> -#include <media/tuner.h> -#include <media/tveeprom.h> -#include <media/videobuf-dma-sg.h> -#include <media/videobuf-dvb.h> -#include <media/rc-core.h> - -#include "btcx-risc.h" -#include "cx23885-reg.h" -#include "media/cx2341x.h" - -#include <linux/mutex.h> - -#define CX23885_VERSION "0.0.3" - -#define UNSET (-1U) - -#define CX23885_MAXBOARDS 8 - -/* Max number of inputs by card */ -#define MAX_CX23885_INPUT 8 -#define INPUT(nr) (&cx23885_boards[dev->board].input[nr]) -#define RESOURCE_OVERLAY 1 -#define RESOURCE_VIDEO 2 -#define RESOURCE_VBI 4 - -#define BUFFER_TIMEOUT (HZ) /* 0.5 seconds */ - -#define CX23885_BOARD_NOAUTO UNSET -#define CX23885_BOARD_UNKNOWN 0 -#define CX23885_BOARD_HAUPPAUGE_HVR1800lp 1 -#define CX23885_BOARD_HAUPPAUGE_HVR1800 2 -#define CX23885_BOARD_HAUPPAUGE_HVR1250 3 -#define CX23885_BOARD_DVICO_FUSIONHDTV_5_EXP 4 -#define CX23885_BOARD_HAUPPAUGE_HVR1500Q 5 -#define CX23885_BOARD_HAUPPAUGE_HVR1500 6 -#define CX23885_BOARD_HAUPPAUGE_HVR1200 7 -#define CX23885_BOARD_HAUPPAUGE_HVR1700 8 -#define CX23885_BOARD_HAUPPAUGE_HVR1400 9 -#define CX23885_BOARD_DVICO_FUSIONHDTV_7_DUAL_EXP 10 -#define CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP 11 -#define CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H 12 -#define CX23885_BOARD_COMPRO_VIDEOMATE_E650F 13 -#define CX23885_BOARD_TBS_6920 14 -#define CX23885_BOARD_TEVII_S470 15 -#define CX23885_BOARD_DVBWORLD_2005 16 -#define CX23885_BOARD_NETUP_DUAL_DVBS2_CI 17 -#define CX23885_BOARD_HAUPPAUGE_HVR1270 18 -#define CX23885_BOARD_HAUPPAUGE_HVR1275 19 -#define CX23885_BOARD_HAUPPAUGE_HVR1255 20 -#define CX23885_BOARD_HAUPPAUGE_HVR1210 21 -#define CX23885_BOARD_MYGICA_X8506 22 -#define CX23885_BOARD_MAGICPRO_PROHDTVE2 23 -#define CX23885_BOARD_HAUPPAUGE_HVR1850 24 -#define CX23885_BOARD_COMPRO_VIDEOMATE_E800 25 -#define CX23885_BOARD_HAUPPAUGE_HVR1290 26 -#define CX23885_BOARD_MYGICA_X8558PRO 27 -#define CX23885_BOARD_LEADTEK_WINFAST_PXTV1200 28 -#define CX23885_BOARD_GOTVIEW_X5_3D_HYBRID 29 -#define CX23885_BOARD_NETUP_DUAL_DVB_T_C_CI_RF 30 -#define CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H_XC4000 31 -#define CX23885_BOARD_MPX885 32 -#define CX23885_BOARD_MYGICA_X8507 33 -#define CX23885_BOARD_TERRATEC_CINERGY_T_PCIE_DUAL 34 -#define CX23885_BOARD_TEVII_S471 35 -#define CX23885_BOARD_HAUPPAUGE_HVR1255_22111 36 - -#define GPIO_0 0x00000001 -#define GPIO_1 0x00000002 -#define GPIO_2 0x00000004 -#define GPIO_3 0x00000008 -#define GPIO_4 0x00000010 -#define GPIO_5 0x00000020 -#define GPIO_6 0x00000040 -#define GPIO_7 0x00000080 -#define GPIO_8 0x00000100 -#define GPIO_9 0x00000200 -#define GPIO_10 0x00000400 -#define GPIO_11 0x00000800 -#define GPIO_12 0x00001000 -#define GPIO_13 0x00002000 -#define GPIO_14 0x00004000 -#define GPIO_15 0x00008000 - -/* Currently unsupported by the driver: PAL/H, NTSC/Kr, SECAM B/G/H/LC */ -#define CX23885_NORMS (\ - V4L2_STD_NTSC_M | V4L2_STD_NTSC_M_JP | V4L2_STD_NTSC_443 | \ - V4L2_STD_PAL_BG | V4L2_STD_PAL_DK | V4L2_STD_PAL_I | \ - V4L2_STD_PAL_M | V4L2_STD_PAL_N | V4L2_STD_PAL_Nc | \ - V4L2_STD_PAL_60 | V4L2_STD_SECAM_L | V4L2_STD_SECAM_DK) - -struct cx23885_fmt { - char *name; - u32 fourcc; /* v4l2 format id */ - int depth; - int flags; - u32 cxformat; -}; - -struct cx23885_ctrl { - struct v4l2_queryctrl v; - u32 off; - u32 reg; - u32 mask; - u32 shift; -}; - -struct cx23885_tvnorm { - char *name; - v4l2_std_id id; - u32 cxiformat; - u32 cxoformat; -}; - -struct cx23885_fh { - struct cx23885_dev *dev; - enum v4l2_buf_type type; - int radio; - u32 resources; - - /* video overlay */ - struct v4l2_window win; - struct v4l2_clip *clips; - unsigned int nclips; - - /* video capture */ - struct cx23885_fmt *fmt; - unsigned int width, height; - - /* vbi capture */ - struct videobuf_queue vidq; - struct videobuf_queue vbiq; - - /* MPEG Encoder specifics ONLY */ - struct videobuf_queue mpegq; - atomic_t v4l_reading; -}; - -enum cx23885_itype { - CX23885_VMUX_COMPOSITE1 = 1, - CX23885_VMUX_COMPOSITE2, - CX23885_VMUX_COMPOSITE3, - CX23885_VMUX_COMPOSITE4, - CX23885_VMUX_SVIDEO, - CX23885_VMUX_COMPONENT, - CX23885_VMUX_TELEVISION, - CX23885_VMUX_CABLE, - CX23885_VMUX_DVB, - CX23885_VMUX_DEBUG, - CX23885_RADIO, -}; - -enum cx23885_src_sel_type { - CX23885_SRC_SEL_EXT_656_VIDEO = 0, - CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO -}; - -/* buffer for one video frame */ -struct cx23885_buffer { - /* common v4l buffer stuff -- must be first */ - struct videobuf_buffer vb; - - /* cx23885 specific */ - unsigned int bpl; - struct btcx_riscmem risc; - struct cx23885_fmt *fmt; - u32 count; -}; - -struct cx23885_input { - enum cx23885_itype type; - unsigned int vmux; - unsigned int amux; - u32 gpio0, gpio1, gpio2, gpio3; -}; - -typedef enum { - CX23885_MPEG_UNDEFINED = 0, - CX23885_MPEG_DVB, - CX23885_ANALOG_VIDEO, - CX23885_MPEG_ENCODER, -} port_t; - -struct cx23885_board { - char *name; - port_t porta, portb, portc; - int num_fds_portb, num_fds_portc; - unsigned int tuner_type; - unsigned int radio_type; - unsigned char tuner_addr; - unsigned char radio_addr; - unsigned int tuner_bus; - - /* Vendors can and do run the PCIe bridge at different - * clock rates, driven physically by crystals on the PCBs. - * The core has to accommodate this. This allows the user - * to add new boards with new frequencys. The value is - * expressed in Hz. - * - * The core framework will default this value based on - * current designs, but it can vary. - */ - u32 clk_freq; - struct cx23885_input input[MAX_CX23885_INPUT]; - int ci_type; /* for NetUP */ - /* Force bottom field first during DMA (888 workaround) */ - u32 force_bff; -}; - -struct cx23885_subid { - u16 subvendor; - u16 subdevice; - u32 card; -}; - -struct cx23885_i2c { - struct cx23885_dev *dev; - - int nr; - - /* i2c i/o */ - struct i2c_adapter i2c_adap; - struct i2c_client i2c_client; - u32 i2c_rc; - - /* 885 registers used for raw addess */ - u32 i2c_period; - u32 reg_ctrl; - u32 reg_stat; - u32 reg_addr; - u32 reg_rdata; - u32 reg_wdata; -}; - -struct cx23885_dmaqueue { - struct list_head active; - struct list_head queued; - struct timer_list timeout; - struct btcx_riscmem stopper; - u32 count; -}; - -struct cx23885_tsport { - struct cx23885_dev *dev; - - int nr; - int sram_chno; - - struct videobuf_dvb_frontends frontends; - - /* dma queues */ - struct cx23885_dmaqueue mpegq; - u32 ts_packet_size; - u32 ts_packet_count; - - int width; - int height; - - spinlock_t slock; - - /* registers */ - u32 reg_gpcnt; - u32 reg_gpcnt_ctl; - u32 reg_dma_ctl; - u32 reg_lngth; - u32 reg_hw_sop_ctrl; - u32 reg_gen_ctrl; - u32 reg_bd_pkt_status; - u32 reg_sop_status; - u32 reg_fifo_ovfl_stat; - u32 reg_vld_misc; - u32 reg_ts_clk_en; - u32 reg_ts_int_msk; - u32 reg_ts_int_stat; - u32 reg_src_sel; - - /* Default register vals */ - int pci_irqmask; - u32 dma_ctl_val; - u32 ts_int_msk_val; - u32 gen_ctrl_val; - u32 ts_clk_en_val; - u32 src_sel_val; - u32 vld_misc_val; - u32 hw_sop_ctrl_val; - - /* Allow a single tsport to have multiple frontends */ - u32 num_frontends; - void (*gate_ctrl)(struct cx23885_tsport *port, int open); - void *port_priv; - - /* Workaround for a temp dvb_frontend that the tuner can attached to */ - struct dvb_frontend analog_fe; -}; - -struct cx23885_kernel_ir { - struct cx23885_dev *cx; - char *name; - char *phys; - - struct rc_dev *rc; -}; - -struct cx23885_audio_buffer { - unsigned int bpl; - struct btcx_riscmem risc; - struct videobuf_dmabuf dma; -}; - -struct cx23885_audio_dev { - struct cx23885_dev *dev; - - struct pci_dev *pci; - - struct snd_card *card; - - spinlock_t lock; - - atomic_t count; - - unsigned int dma_size; - unsigned int period_size; - unsigned int num_periods; - - struct videobuf_dmabuf *dma_risc; - - struct cx23885_audio_buffer *buf; - - struct snd_pcm_substream *substream; -}; - -struct cx23885_dev { - atomic_t refcount; - struct v4l2_device v4l2_dev; - - /* pci stuff */ - struct pci_dev *pci; - unsigned char pci_rev, pci_lat; - int pci_bus, pci_slot; - u32 __iomem *lmmio; - u8 __iomem *bmmio; - int pci_irqmask; - spinlock_t pci_irqmask_lock; /* protects mask reg too */ - int hwrevision; - - /* This valud is board specific and is used to configure the - * AV core so we see nice clean and stable video and audio. */ - u32 clk_freq; - - /* I2C adapters: Master 1 & 2 (External) & Master 3 (Internal only) */ - struct cx23885_i2c i2c_bus[3]; - - int nr; - struct mutex lock; - struct mutex gpio_lock; - - /* board details */ - unsigned int board; - char name[32]; - - struct cx23885_tsport ts1, ts2; - - /* sram configuration */ - struct sram_channel *sram_channels; - - enum { - CX23885_BRIDGE_UNDEFINED = 0, - CX23885_BRIDGE_885 = 885, - CX23885_BRIDGE_887 = 887, - CX23885_BRIDGE_888 = 888, - } bridge; - - /* Analog video */ - u32 resources; - unsigned int input; - unsigned int audinput; /* Selectable audio input */ - u32 tvaudio; - v4l2_std_id tvnorm; - unsigned int tuner_type; - unsigned char tuner_addr; - unsigned int tuner_bus; - unsigned int radio_type; - unsigned char radio_addr; - unsigned int has_radio; - struct v4l2_subdev *sd_cx25840; - struct work_struct cx25840_work; - - /* Infrared */ - struct v4l2_subdev *sd_ir; - struct work_struct ir_rx_work; - unsigned long ir_rx_notifications; - struct work_struct ir_tx_work; - unsigned long ir_tx_notifications; - - struct cx23885_kernel_ir *kernel_ir; - atomic_t ir_input_stopping; - - /* V4l */ - u32 freq; - struct video_device *video_dev; - struct video_device *vbi_dev; - struct video_device *radio_dev; - - struct cx23885_dmaqueue vidq; - struct cx23885_dmaqueue vbiq; - spinlock_t slock; - - /* MPEG Encoder ONLY settings */ - u32 cx23417_mailbox; - struct cx2341x_mpeg_params mpeg_params; - struct video_device *v4l_device; - atomic_t v4l_reader_count; - struct cx23885_tvnorm encodernorm; - - /* Analog raw audio */ - struct cx23885_audio_dev *audio_dev; - -}; - -static inline struct cx23885_dev *to_cx23885(struct v4l2_device *v4l2_dev) -{ - return container_of(v4l2_dev, struct cx23885_dev, v4l2_dev); -} - -#define call_all(dev, o, f, args...) \ - v4l2_device_call_all(&dev->v4l2_dev, 0, o, f, ##args) - -#define CX23885_HW_888_IR (1 << 0) -#define CX23885_HW_AV_CORE (1 << 1) - -#define call_hw(dev, grpid, o, f, args...) \ - v4l2_device_call_all(&dev->v4l2_dev, grpid, o, f, ##args) - -extern struct v4l2_subdev *cx23885_find_hw(struct cx23885_dev *dev, u32 hw); - -#define SRAM_CH01 0 /* Video A */ -#define SRAM_CH02 1 /* VBI A */ -#define SRAM_CH03 2 /* Video B */ -#define SRAM_CH04 3 /* Transport via B */ -#define SRAM_CH05 4 /* VBI B */ -#define SRAM_CH06 5 /* Video C */ -#define SRAM_CH07 6 /* Transport via C */ -#define SRAM_CH08 7 /* Audio Internal A */ -#define SRAM_CH09 8 /* Audio Internal B */ -#define SRAM_CH10 9 /* Audio External */ -#define SRAM_CH11 10 /* COMB_3D_N */ -#define SRAM_CH12 11 /* Comb 3D N1 */ -#define SRAM_CH13 12 /* Comb 3D N2 */ -#define SRAM_CH14 13 /* MOE Vid */ -#define SRAM_CH15 14 /* MOE RSLT */ - -struct sram_channel { - char *name; - u32 cmds_start; - u32 ctrl_start; - u32 cdt; - u32 fifo_start; - u32 fifo_size; - u32 ptr1_reg; - u32 ptr2_reg; - u32 cnt1_reg; - u32 cnt2_reg; - u32 jumponly; -}; - -/* ----------------------------------------------------------- */ - -#define cx_read(reg) readl(dev->lmmio + ((reg)>>2)) -#define cx_write(reg, value) writel((value), dev->lmmio + ((reg)>>2)) - -#define cx_andor(reg, mask, value) \ - writel((readl(dev->lmmio+((reg)>>2)) & ~(mask)) |\ - ((value) & (mask)), dev->lmmio+((reg)>>2)) - -#define cx_set(reg, bit) cx_andor((reg), (bit), (bit)) -#define cx_clear(reg, bit) cx_andor((reg), (bit), 0) - -/* ----------------------------------------------------------- */ -/* cx23885-core.c */ - -extern int cx23885_sram_channel_setup(struct cx23885_dev *dev, - struct sram_channel *ch, - unsigned int bpl, u32 risc); - -extern void cx23885_sram_channel_dump(struct cx23885_dev *dev, - struct sram_channel *ch); - -extern int cx23885_risc_stopper(struct pci_dev *pci, struct btcx_riscmem *risc, - u32 reg, u32 mask, u32 value); - -extern int cx23885_risc_buffer(struct pci_dev *pci, struct btcx_riscmem *risc, - struct scatterlist *sglist, - unsigned int top_offset, unsigned int bottom_offset, - unsigned int bpl, unsigned int padding, unsigned int lines); - -extern int cx23885_risc_vbibuffer(struct pci_dev *pci, - struct btcx_riscmem *risc, struct scatterlist *sglist, - unsigned int top_offset, unsigned int bottom_offset, - unsigned int bpl, unsigned int padding, unsigned int lines); - -void cx23885_cancel_buffers(struct cx23885_tsport *port); - -extern int cx23885_restart_queue(struct cx23885_tsport *port, - struct cx23885_dmaqueue *q); - -extern void cx23885_wakeup(struct cx23885_tsport *port, - struct cx23885_dmaqueue *q, u32 count); - -extern void cx23885_gpio_set(struct cx23885_dev *dev, u32 mask); -extern void cx23885_gpio_clear(struct cx23885_dev *dev, u32 mask); -extern u32 cx23885_gpio_get(struct cx23885_dev *dev, u32 mask); -extern void cx23885_gpio_enable(struct cx23885_dev *dev, u32 mask, - int asoutput); - -extern void cx23885_irq_add_enable(struct cx23885_dev *dev, u32 mask); -extern void cx23885_irq_enable(struct cx23885_dev *dev, u32 mask); -extern void cx23885_irq_disable(struct cx23885_dev *dev, u32 mask); -extern void cx23885_irq_remove(struct cx23885_dev *dev, u32 mask); - -/* ----------------------------------------------------------- */ -/* cx23885-cards.c */ -extern struct cx23885_board cx23885_boards[]; -extern const unsigned int cx23885_bcount; - -extern struct cx23885_subid cx23885_subids[]; -extern const unsigned int cx23885_idcount; - -extern int cx23885_tuner_callback(void *priv, int component, - int command, int arg); -extern void cx23885_card_list(struct cx23885_dev *dev); -extern int cx23885_ir_init(struct cx23885_dev *dev); -extern void cx23885_ir_pci_int_enable(struct cx23885_dev *dev); -extern void cx23885_ir_fini(struct cx23885_dev *dev); -extern void cx23885_gpio_setup(struct cx23885_dev *dev); -extern void cx23885_card_setup(struct cx23885_dev *dev); -extern void cx23885_card_setup_pre_i2c(struct cx23885_dev *dev); - -extern int cx23885_dvb_register(struct cx23885_tsport *port); -extern int cx23885_dvb_unregister(struct cx23885_tsport *port); - -extern int cx23885_buf_prepare(struct videobuf_queue *q, - struct cx23885_tsport *port, - struct cx23885_buffer *buf, - enum v4l2_field field); -extern void cx23885_buf_queue(struct cx23885_tsport *port, - struct cx23885_buffer *buf); -extern void cx23885_free_buffer(struct videobuf_queue *q, - struct cx23885_buffer *buf); - -/* ----------------------------------------------------------- */ -/* cx23885-video.c */ -/* Video */ -extern int cx23885_video_register(struct cx23885_dev *dev); -extern void cx23885_video_unregister(struct cx23885_dev *dev); -extern int cx23885_video_irq(struct cx23885_dev *dev, u32 status); -extern void cx23885_video_wakeup(struct cx23885_dev *dev, - struct cx23885_dmaqueue *q, u32 count); -int cx23885_enum_input(struct cx23885_dev *dev, struct v4l2_input *i); -int cx23885_set_input(struct file *file, void *priv, unsigned int i); -int cx23885_get_input(struct file *file, void *priv, unsigned int *i); -int cx23885_set_frequency(struct file *file, void *priv, struct v4l2_frequency *f); -int cx23885_set_control(struct cx23885_dev *dev, struct v4l2_control *ctl); -int cx23885_get_control(struct cx23885_dev *dev, struct v4l2_control *ctl); -int cx23885_set_tvnorm(struct cx23885_dev *dev, v4l2_std_id norm); - -/* ----------------------------------------------------------- */ -/* cx23885-vbi.c */ -extern int cx23885_vbi_fmt(struct file *file, void *priv, - struct v4l2_format *f); -extern void cx23885_vbi_timeout(unsigned long data); -extern struct videobuf_queue_ops cx23885_vbi_qops; -extern int cx23885_restart_vbi_queue(struct cx23885_dev *dev, - struct cx23885_dmaqueue *q); -extern int cx23885_vbi_irq(struct cx23885_dev *dev, u32 status); - -/* cx23885-i2c.c */ -extern int cx23885_i2c_register(struct cx23885_i2c *bus); -extern int cx23885_i2c_unregister(struct cx23885_i2c *bus); -extern void cx23885_av_clk(struct cx23885_dev *dev, int enable); - -/* ----------------------------------------------------------- */ -/* cx23885-417.c */ -extern int cx23885_417_register(struct cx23885_dev *dev); -extern void cx23885_417_unregister(struct cx23885_dev *dev); -extern int cx23885_irq_417(struct cx23885_dev *dev, u32 status); -extern void cx23885_417_check_encoder(struct cx23885_dev *dev); -extern void cx23885_mc417_init(struct cx23885_dev *dev); -extern int mc417_memory_read(struct cx23885_dev *dev, u32 address, u32 *value); -extern int mc417_memory_write(struct cx23885_dev *dev, u32 address, u32 value); -extern int mc417_register_read(struct cx23885_dev *dev, - u16 address, u32 *value); -extern int mc417_register_write(struct cx23885_dev *dev, - u16 address, u32 value); -extern void mc417_gpio_set(struct cx23885_dev *dev, u32 mask); -extern void mc417_gpio_clear(struct cx23885_dev *dev, u32 mask); -extern void mc417_gpio_enable(struct cx23885_dev *dev, u32 mask, int asoutput); - -/* ----------------------------------------------------------- */ -/* cx23885-alsa.c */ -extern struct cx23885_audio_dev *cx23885_audio_register( - struct cx23885_dev *dev); -extern void cx23885_audio_unregister(struct cx23885_dev *dev); -extern int cx23885_audio_irq(struct cx23885_dev *dev, u32 status, u32 mask); -extern int cx23885_risc_databuffer(struct pci_dev *pci, - struct btcx_riscmem *risc, - struct scatterlist *sglist, - unsigned int bpl, - unsigned int lines, - unsigned int lpi); - -/* ----------------------------------------------------------- */ -/* tv norms */ - -static inline unsigned int norm_maxw(v4l2_std_id norm) -{ - return (norm & (V4L2_STD_MN & ~V4L2_STD_PAL_Nc)) ? 720 : 768; -} - -static inline unsigned int norm_maxh(v4l2_std_id norm) -{ - return (norm & V4L2_STD_625_50) ? 576 : 480; -} - -static inline unsigned int norm_swidth(v4l2_std_id norm) -{ - return (norm & (V4L2_STD_MN & ~V4L2_STD_PAL_Nc)) ? 754 : 922; -} diff --git a/drivers/media/video/cx23885/cx23888-ir.c b/drivers/media/video/cx23885/cx23888-ir.c deleted file mode 100644 index c2bc39c58f8..00000000000 --- a/drivers/media/video/cx23885/cx23888-ir.c +++ /dev/null @@ -1,1271 +0,0 @@ -/* - * Driver for the Conexant CX23885/7/8 PCIe bridge - * - * CX23888 Integrated Consumer Infrared Controller - * - * Copyright (C) 2009 Andy Walls <awalls@md.metrocast.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 <linux/kfifo.h> -#include <linux/slab.h> - -#include <media/v4l2-device.h> -#include <media/v4l2-chip-ident.h> -#include <media/rc-core.h> - -#include "cx23885.h" - -static unsigned int ir_888_debug; -module_param(ir_888_debug, int, 0644); -MODULE_PARM_DESC(ir_888_debug, "enable debug messages [CX23888 IR controller]"); - -#define CX23888_IR_REG_BASE 0x170000 -/* - * These CX23888 register offsets have a straightforward one to one mapping - * to the CX23885 register offsets of 0x200 through 0x218 - */ -#define CX23888_IR_CNTRL_REG 0x170000 -#define CNTRL_WIN_3_3 0x00000000 -#define CNTRL_WIN_4_3 0x00000001 -#define CNTRL_WIN_3_4 0x00000002 -#define CNTRL_WIN_4_4 0x00000003 -#define CNTRL_WIN 0x00000003 -#define CNTRL_EDG_NONE 0x00000000 -#define CNTRL_EDG_FALL 0x00000004 -#define CNTRL_EDG_RISE 0x00000008 -#define CNTRL_EDG_BOTH 0x0000000C -#define CNTRL_EDG 0x0000000C -#define CNTRL_DMD 0x00000010 -#define CNTRL_MOD 0x00000020 -#define CNTRL_RFE 0x00000040 -#define CNTRL_TFE 0x00000080 -#define CNTRL_RXE 0x00000100 -#define CNTRL_TXE 0x00000200 -#define CNTRL_RIC 0x00000400 -#define CNTRL_TIC 0x00000800 -#define CNTRL_CPL 0x00001000 -#define CNTRL_LBM 0x00002000 -#define CNTRL_R 0x00004000 -/* CX23888 specific control flag */ -#define CNTRL_IVO 0x00008000 - -#define CX23888_IR_TXCLK_REG 0x170004 -#define TXCLK_TCD 0x0000FFFF - -#define CX23888_IR_RXCLK_REG 0x170008 -#define RXCLK_RCD 0x0000FFFF - -#define CX23888_IR_CDUTY_REG 0x17000C -#define CDUTY_CDC 0x0000000F - -#define CX23888_IR_STATS_REG 0x170010 -#define STATS_RTO 0x00000001 -#define STATS_ROR 0x00000002 -#define STATS_RBY 0x00000004 -#define STATS_TBY 0x00000008 -#define STATS_RSR 0x00000010 -#define STATS_TSR 0x00000020 - -#define CX23888_IR_IRQEN_REG 0x170014 -#define IRQEN_RTE 0x00000001 -#define IRQEN_ROE 0x00000002 -#define IRQEN_RSE 0x00000010 -#define IRQEN_TSE 0x00000020 - -#define CX23888_IR_FILTR_REG 0x170018 -#define FILTR_LPF 0x0000FFFF - -/* This register doesn't follow the pattern; it's 0x23C on a CX23885 */ -#define CX23888_IR_FIFO_REG 0x170040 -#define FIFO_RXTX 0x0000FFFF -#define FIFO_RXTX_LVL 0x00010000 -#define FIFO_RXTX_RTO 0x0001FFFF -#define FIFO_RX_NDV 0x00020000 -#define FIFO_RX_DEPTH 8 -#define FIFO_TX_DEPTH 8 - -/* CX23888 unique registers */ -#define CX23888_IR_SEEDP_REG 0x17001C -#define CX23888_IR_TIMOL_REG 0x170020 -#define CX23888_IR_WAKE0_REG 0x170024 -#define CX23888_IR_WAKE1_REG 0x170028 -#define CX23888_IR_WAKE2_REG 0x17002C -#define CX23888_IR_MASK0_REG 0x170030 -#define CX23888_IR_MASK1_REG 0x170034 -#define CX23888_IR_MAKS2_REG 0x170038 -#define CX23888_IR_DPIPG_REG 0x17003C -#define CX23888_IR_LEARN_REG 0x170044 - -#define CX23888_VIDCLK_FREQ 108000000 /* 108 MHz, BT.656 */ -#define CX23888_IR_REFCLK_FREQ (CX23888_VIDCLK_FREQ / 2) - -/* - * We use this union internally for convenience, but callers to tx_write - * and rx_read will be expecting records of type struct ir_raw_event. - * Always ensure the size of this union is dictated by struct ir_raw_event. - */ -union cx23888_ir_fifo_rec { - u32 hw_fifo_data; - struct ir_raw_event ir_core_data; -}; - -#define CX23888_IR_RX_KFIFO_SIZE (256 * sizeof(union cx23888_ir_fifo_rec)) -#define CX23888_IR_TX_KFIFO_SIZE (256 * sizeof(union cx23888_ir_fifo_rec)) - -struct cx23888_ir_state { - struct v4l2_subdev sd; - struct cx23885_dev *dev; - u32 id; - u32 rev; - - struct v4l2_subdev_ir_parameters rx_params; - struct mutex rx_params_lock; - atomic_t rxclk_divider; - atomic_t rx_invert; - - struct kfifo rx_kfifo; - spinlock_t rx_kfifo_lock; - - struct v4l2_subdev_ir_parameters tx_params; - struct mutex tx_params_lock; - atomic_t txclk_divider; -}; - -static inline struct cx23888_ir_state *to_state(struct v4l2_subdev *sd) -{ - return v4l2_get_subdevdata(sd); -} - -/* - * IR register block read and write functions - */ -static -inline int cx23888_ir_write4(struct cx23885_dev *dev, u32 addr, u32 value) -{ - cx_write(addr, value); - return 0; -} - -static inline u32 cx23888_ir_read4(struct cx23885_dev *dev, u32 addr) -{ - return cx_read(addr); -} - -static inline int cx23888_ir_and_or4(struct cx23885_dev *dev, u32 addr, - u32 and_mask, u32 or_value) -{ - cx_andor(addr, ~and_mask, or_value); - return 0; -} - -/* - * Rx and Tx Clock Divider register computations - * - * Note the largest clock divider value of 0xffff corresponds to: - * (0xffff + 1) * 1000 / 108/2 MHz = 1,213,629.629... ns - * which fits in 21 bits, so we'll use unsigned int for time arguments. - */ -static inline u16 count_to_clock_divider(unsigned int d) -{ - if (d > RXCLK_RCD + 1) - d = RXCLK_RCD; - else if (d < 2) - d = 1; - else - d--; - return (u16) d; -} - -static inline u16 ns_to_clock_divider(unsigned int ns) -{ - return count_to_clock_divider( - DIV_ROUND_CLOSEST(CX23888_IR_REFCLK_FREQ / 1000000 * ns, 1000)); -} - -static inline unsigned int clock_divider_to_ns(unsigned int divider) -{ - /* Period of the Rx or Tx clock in ns */ - return DIV_ROUND_CLOSEST((divider + 1) * 1000, - CX23888_IR_REFCLK_FREQ / 1000000); -} - -static inline u16 carrier_freq_to_clock_divider(unsigned int freq) -{ - return count_to_clock_divider( - DIV_ROUND_CLOSEST(CX23888_IR_REFCLK_FREQ, freq * 16)); -} - -static inline unsigned int clock_divider_to_carrier_freq(unsigned int divider) -{ - return DIV_ROUND_CLOSEST(CX23888_IR_REFCLK_FREQ, (divider + 1) * 16); -} - -static inline u16 freq_to_clock_divider(unsigned int freq, - unsigned int rollovers) -{ - return count_to_clock_divider( - DIV_ROUND_CLOSEST(CX23888_IR_REFCLK_FREQ, freq * rollovers)); -} - -static inline unsigned int clock_divider_to_freq(unsigned int divider, - unsigned int rollovers) -{ - return DIV_ROUND_CLOSEST(CX23888_IR_REFCLK_FREQ, - (divider + 1) * rollovers); -} - -/* - * Low Pass Filter register calculations - * - * Note the largest count value of 0xffff corresponds to: - * 0xffff * 1000 / 108/2 MHz = 1,213,611.11... ns - * which fits in 21 bits, so we'll use unsigned int for time arguments. - */ -static inline u16 count_to_lpf_count(unsigned int d) -{ - if (d > FILTR_LPF) - d = FILTR_LPF; - else if (d < 4) - d = 0; - return (u16) d; -} - -static inline u16 ns_to_lpf_count(unsigned int ns) -{ - return count_to_lpf_count( - DIV_ROUND_CLOSEST(CX23888_IR_REFCLK_FREQ / 1000000 * ns, 1000)); -} - -static inline unsigned int lpf_count_to_ns(unsigned int count) -{ - /* Duration of the Low Pass Filter rejection window in ns */ - return DIV_ROUND_CLOSEST(count * 1000, - CX23888_IR_REFCLK_FREQ / 1000000); -} - -static inline unsigned int lpf_count_to_us(unsigned int count) -{ - /* Duration of the Low Pass Filter rejection window in us */ - return DIV_ROUND_CLOSEST(count, CX23888_IR_REFCLK_FREQ / 1000000); -} - -/* - * FIFO register pulse width count compuations - */ -static u32 clock_divider_to_resolution(u16 divider) -{ - /* - * Resolution is the duration of 1 tick of the readable portion of - * of the pulse width counter as read from the FIFO. The two lsb's are - * not readable, hence the << 2. This function returns ns. - */ - return DIV_ROUND_CLOSEST((1 << 2) * ((u32) divider + 1) * 1000, - CX23888_IR_REFCLK_FREQ / 1000000); -} - -static u64 pulse_width_count_to_ns(u16 count, u16 divider) -{ - u64 n; - u32 rem; - - /* - * The 2 lsb's of the pulse width timer count are not readable, hence - * the (count << 2) | 0x3 - */ - n = (((u64) count << 2) | 0x3) * (divider + 1) * 1000; /* millicycles */ - rem = do_div(n, CX23888_IR_REFCLK_FREQ / 1000000); /* / MHz => ns */ - if (rem >= CX23888_IR_REFCLK_FREQ / 1000000 / 2) - n++; - return n; -} - -static unsigned int pulse_width_count_to_us(u16 count, u16 divider) -{ - u64 n; - u32 rem; - - /* - * The 2 lsb's of the pulse width timer count are not readable, hence - * the (count << 2) | 0x3 - */ - n = (((u64) count << 2) | 0x3) * (divider + 1); /* cycles */ - rem = do_div(n, CX23888_IR_REFCLK_FREQ / 1000000); /* / MHz => us */ - if (rem >= CX23888_IR_REFCLK_FREQ / 1000000 / 2) - n++; - return (unsigned int) n; -} - -/* - * Pulse Clocks computations: Combined Pulse Width Count & Rx Clock Counts - * - * The total pulse clock count is an 18 bit pulse width timer count as the most - * significant part and (up to) 16 bit clock divider count as a modulus. - * When the Rx clock divider ticks down to 0, it increments the 18 bit pulse - * width timer count's least significant bit. - */ -static u64 ns_to_pulse_clocks(u32 ns) -{ - u64 clocks; - u32 rem; - clocks = CX23888_IR_REFCLK_FREQ / 1000000 * (u64) ns; /* millicycles */ - rem = do_div(clocks, 1000); /* /1000 = cycles */ - if (rem >= 1000 / 2) - clocks++; - return clocks; -} - -static u16 pulse_clocks_to_clock_divider(u64 count) -{ - do_div(count, (FIFO_RXTX << 2) | 0x3); - - /* net result needs to be rounded down and decremented by 1 */ - if (count > RXCLK_RCD + 1) - count = RXCLK_RCD; - else if (count < 2) - count = 1; - else - count--; - return (u16) count; -} - -/* - * IR Control Register helpers - */ -enum tx_fifo_watermark { - TX_FIFO_HALF_EMPTY = 0, - TX_FIFO_EMPTY = CNTRL_TIC, -}; - -enum rx_fifo_watermark { - RX_FIFO_HALF_FULL = 0, - RX_FIFO_NOT_EMPTY = CNTRL_RIC, -}; - -static inline void control_tx_irq_watermark(struct cx23885_dev *dev, - enum tx_fifo_watermark level) -{ - cx23888_ir_and_or4(dev, CX23888_IR_CNTRL_REG, ~CNTRL_TIC, level); -} - -static inline void control_rx_irq_watermark(struct cx23885_dev *dev, - enum rx_fifo_watermark level) -{ - cx23888_ir_and_or4(dev, CX23888_IR_CNTRL_REG, ~CNTRL_RIC, level); -} - -static inline void control_tx_enable(struct cx23885_dev *dev, bool enable) -{ - cx23888_ir_and_or4(dev, CX23888_IR_CNTRL_REG, ~(CNTRL_TXE | CNTRL_TFE), - enable ? (CNTRL_TXE | CNTRL_TFE) : 0); -} - -static inline void control_rx_enable(struct cx23885_dev *dev, bool enable) -{ - cx23888_ir_and_or4(dev, CX23888_IR_CNTRL_REG, ~(CNTRL_RXE | CNTRL_RFE), - enable ? (CNTRL_RXE | CNTRL_RFE) : 0); -} - -static inline void control_tx_modulation_enable(struct cx23885_dev *dev, - bool enable) -{ - cx23888_ir_and_or4(dev, CX23888_IR_CNTRL_REG, ~CNTRL_MOD, - enable ? CNTRL_MOD : 0); -} - -static inline void control_rx_demodulation_enable(struct cx23885_dev *dev, - bool enable) -{ - cx23888_ir_and_or4(dev, CX23888_IR_CNTRL_REG, ~CNTRL_DMD, - enable ? CNTRL_DMD : 0); -} - -static inline void control_rx_s_edge_detection(struct cx23885_dev *dev, - u32 edge_types) -{ - cx23888_ir_and_or4(dev, CX23888_IR_CNTRL_REG, ~CNTRL_EDG_BOTH, - edge_types & CNTRL_EDG_BOTH); -} - -static void control_rx_s_carrier_window(struct cx23885_dev *dev, - unsigned int carrier, - unsigned int *carrier_range_low, - unsigned int *carrier_range_high) -{ - u32 v; - unsigned int c16 = carrier * 16; - - if (*carrier_range_low < DIV_ROUND_CLOSEST(c16, 16 + 3)) { - v = CNTRL_WIN_3_4; - *carrier_range_low = DIV_ROUND_CLOSEST(c16, 16 + 4); - } else { - v = CNTRL_WIN_3_3; - *carrier_range_low = DIV_ROUND_CLOSEST(c16, 16 + 3); - } - - if (*carrier_range_high > DIV_ROUND_CLOSEST(c16, 16 - 3)) { - v |= CNTRL_WIN_4_3; - *carrier_range_high = DIV_ROUND_CLOSEST(c16, 16 - 4); - } else { - v |= CNTRL_WIN_3_3; - *carrier_range_high = DIV_ROUND_CLOSEST(c16, 16 - 3); - } - cx23888_ir_and_or4(dev, CX23888_IR_CNTRL_REG, ~CNTRL_WIN, v); -} - -static inline void control_tx_polarity_invert(struct cx23885_dev *dev, - bool invert) -{ - cx23888_ir_and_or4(dev, CX23888_IR_CNTRL_REG, ~CNTRL_CPL, - invert ? CNTRL_CPL : 0); -} - -static inline void control_tx_level_invert(struct cx23885_dev *dev, - bool invert) -{ - cx23888_ir_and_or4(dev, CX23888_IR_CNTRL_REG, ~CNTRL_IVO, - invert ? CNTRL_IVO : 0); -} - -/* - * IR Rx & Tx Clock Register helpers - */ -static unsigned int txclk_tx_s_carrier(struct cx23885_dev *dev, - unsigned int freq, - u16 *divider) -{ - *divider = carrier_freq_to_clock_divider(freq); - cx23888_ir_write4(dev, CX23888_IR_TXCLK_REG, *divider); - return clock_divider_to_carrier_freq(*divider); -} - -static unsigned int rxclk_rx_s_carrier(struct cx23885_dev *dev, - unsigned int freq, - u16 *divider) -{ - *divider = carrier_freq_to_clock_divider(freq); - cx23888_ir_write4(dev, CX23888_IR_RXCLK_REG, *divider); - return clock_divider_to_carrier_freq(*divider); -} - -static u32 txclk_tx_s_max_pulse_width(struct cx23885_dev *dev, u32 ns, - u16 *divider) -{ - u64 pulse_clocks; - - if (ns > IR_MAX_DURATION) - ns = IR_MAX_DURATION; - pulse_clocks = ns_to_pulse_clocks(ns); - *divider = pulse_clocks_to_clock_divider(pulse_clocks); - cx23888_ir_write4(dev, CX23888_IR_TXCLK_REG, *divider); - return (u32) pulse_width_count_to_ns(FIFO_RXTX, *divider); -} - -static u32 rxclk_rx_s_max_pulse_width(struct cx23885_dev *dev, u32 ns, - u16 *divider) -{ - u64 pulse_clocks; - - if (ns > IR_MAX_DURATION) - ns = IR_MAX_DURATION; - pulse_clocks = ns_to_pulse_clocks(ns); - *divider = pulse_clocks_to_clock_divider(pulse_clocks); - cx23888_ir_write4(dev, CX23888_IR_RXCLK_REG, *divider); - return (u32) pulse_width_count_to_ns(FIFO_RXTX, *divider); -} - -/* - * IR Tx Carrier Duty Cycle register helpers - */ -static unsigned int cduty_tx_s_duty_cycle(struct cx23885_dev *dev, - unsigned int duty_cycle) -{ - u32 n; - n = DIV_ROUND_CLOSEST(duty_cycle * 100, 625); /* 16ths of 100% */ - if (n != 0) - n--; - if (n > 15) - n = 15; - cx23888_ir_write4(dev, CX23888_IR_CDUTY_REG, n); - return DIV_ROUND_CLOSEST((n + 1) * 100, 16); -} - -/* - * IR Filter Register helpers - */ -static u32 filter_rx_s_min_width(struct cx23885_dev *dev, u32 min_width_ns) -{ - u32 count = ns_to_lpf_count(min_width_ns); - cx23888_ir_write4(dev, CX23888_IR_FILTR_REG, count); - return lpf_count_to_ns(count); -} - -/* - * IR IRQ Enable Register helpers - */ -static inline void irqenable_rx(struct cx23885_dev *dev, u32 mask) -{ - mask &= (IRQEN_RTE | IRQEN_ROE | IRQEN_RSE); - cx23888_ir_and_or4(dev, CX23888_IR_IRQEN_REG, - ~(IRQEN_RTE | IRQEN_ROE | IRQEN_RSE), mask); -} - -static inline void irqenable_tx(struct cx23885_dev *dev, u32 mask) -{ - mask &= IRQEN_TSE; - cx23888_ir_and_or4(dev, CX23888_IR_IRQEN_REG, ~IRQEN_TSE, mask); -} - -/* - * V4L2 Subdevice IR Ops - */ -static int cx23888_ir_irq_handler(struct v4l2_subdev *sd, u32 status, - bool *handled) -{ - struct cx23888_ir_state *state = to_state(sd); - struct cx23885_dev *dev = state->dev; - unsigned long flags; - - u32 cntrl = cx23888_ir_read4(dev, CX23888_IR_CNTRL_REG); - u32 irqen = cx23888_ir_read4(dev, CX23888_IR_IRQEN_REG); - u32 stats = cx23888_ir_read4(dev, CX23888_IR_STATS_REG); - - union cx23888_ir_fifo_rec rx_data[FIFO_RX_DEPTH]; - unsigned int i, j, k; - u32 events, v; - int tsr, rsr, rto, ror, tse, rse, rte, roe, kror; - - tsr = stats & STATS_TSR; /* Tx FIFO Service Request */ - rsr = stats & STATS_RSR; /* Rx FIFO Service Request */ - rto = stats & STATS_RTO; /* Rx Pulse Width Timer Time Out */ - ror = stats & STATS_ROR; /* Rx FIFO Over Run */ - - tse = irqen & IRQEN_TSE; /* Tx FIFO Service Request IRQ Enable */ - rse = irqen & IRQEN_RSE; /* Rx FIFO Service Reuqest IRQ Enable */ - rte = irqen & IRQEN_RTE; /* Rx Pulse Width Timer Time Out IRQ Enable */ - roe = irqen & IRQEN_ROE; /* Rx FIFO Over Run IRQ Enable */ - - *handled = false; - v4l2_dbg(2, ir_888_debug, sd, "IRQ Status: %s %s %s %s %s %s\n", - tsr ? "tsr" : " ", rsr ? "rsr" : " ", - rto ? "rto" : " ", ror ? "ror" : " ", - stats & STATS_TBY ? "tby" : " ", - stats & STATS_RBY ? "rby" : " "); - - v4l2_dbg(2, ir_888_debug, sd, "IRQ Enables: %s %s %s %s\n", - tse ? "tse" : " ", rse ? "rse" : " ", - rte ? "rte" : " ", roe ? "roe" : " "); - - /* - * Transmitter interrupt service - */ - if (tse && tsr) { - /* - * TODO: - * Check the watermark threshold setting - * Pull FIFO_TX_DEPTH or FIFO_TX_DEPTH/2 entries from tx_kfifo - * Push the data to the hardware FIFO. - * If there was nothing more to send in the tx_kfifo, disable - * the TSR IRQ and notify the v4l2_device. - * If there was something in the tx_kfifo, check the tx_kfifo - * level and notify the v4l2_device, if it is low. - */ - /* For now, inhibit TSR interrupt until Tx is implemented */ - irqenable_tx(dev, 0); - events = V4L2_SUBDEV_IR_TX_FIFO_SERVICE_REQ; - v4l2_subdev_notify(sd, V4L2_SUBDEV_IR_TX_NOTIFY, &events); - *handled = true; - } - - /* - * Receiver interrupt service - */ - kror = 0; - if ((rse && rsr) || (rte && rto)) { - /* - * Receive data on RSR to clear the STATS_RSR. - * Receive data on RTO, since we may not have yet hit the RSR - * watermark when we receive the RTO. - */ - for (i = 0, v = FIFO_RX_NDV; - (v & FIFO_RX_NDV) && !kror; i = 0) { - for (j = 0; - (v & FIFO_RX_NDV) && j < FIFO_RX_DEPTH; j++) { - v = cx23888_ir_read4(dev, CX23888_IR_FIFO_REG); - rx_data[i].hw_fifo_data = v & ~FIFO_RX_NDV; - i++; - } - if (i == 0) - break; - j = i * sizeof(union cx23888_ir_fifo_rec); - k = kfifo_in_locked(&state->rx_kfifo, - (unsigned char *) rx_data, j, - &state->rx_kfifo_lock); - if (k != j) - kror++; /* rx_kfifo over run */ - } - *handled = true; - } - - events = 0; - v = 0; - if (kror) { - events |= V4L2_SUBDEV_IR_RX_SW_FIFO_OVERRUN; - v4l2_err(sd, "IR receiver software FIFO overrun\n"); - } - if (roe && ror) { - /* - * The RX FIFO Enable (CNTRL_RFE) must be toggled to clear - * the Rx FIFO Over Run status (STATS_ROR) - */ - v |= CNTRL_RFE; - events |= V4L2_SUBDEV_IR_RX_HW_FIFO_OVERRUN; - v4l2_err(sd, "IR receiver hardware FIFO overrun\n"); - } - if (rte && rto) { - /* - * The IR Receiver Enable (CNTRL_RXE) must be toggled to clear - * the Rx Pulse Width Timer Time Out (STATS_RTO) - */ - v |= CNTRL_RXE; - events |= V4L2_SUBDEV_IR_RX_END_OF_RX_DETECTED; - } - if (v) { - /* Clear STATS_ROR & STATS_RTO as needed by reseting hardware */ - cx23888_ir_write4(dev, CX23888_IR_CNTRL_REG, cntrl & ~v); - cx23888_ir_write4(dev, CX23888_IR_CNTRL_REG, cntrl); - *handled = true; - } - - spin_lock_irqsave(&state->rx_kfifo_lock, flags); - if (kfifo_len(&state->rx_kfifo) >= CX23888_IR_RX_KFIFO_SIZE / 2) - events |= V4L2_SUBDEV_IR_RX_FIFO_SERVICE_REQ; - spin_unlock_irqrestore(&state->rx_kfifo_lock, flags); - - if (events) - v4l2_subdev_notify(sd, V4L2_SUBDEV_IR_RX_NOTIFY, &events); - return 0; -} - -/* Receiver */ -static int cx23888_ir_rx_read(struct v4l2_subdev *sd, u8 *buf, size_t count, - ssize_t *num) -{ - struct cx23888_ir_state *state = to_state(sd); - bool invert = (bool) atomic_read(&state->rx_invert); - u16 divider = (u16) atomic_read(&state->rxclk_divider); - - unsigned int i, n; - union cx23888_ir_fifo_rec *p; - unsigned u, v, w; - - n = count / sizeof(union cx23888_ir_fifo_rec) - * sizeof(union cx23888_ir_fifo_rec); - if (n == 0) { - *num = 0; - return 0; - } - - n = kfifo_out_locked(&state->rx_kfifo, buf, n, &state->rx_kfifo_lock); - - n /= sizeof(union cx23888_ir_fifo_rec); - *num = n * sizeof(union cx23888_ir_fifo_rec); - - for (p = (union cx23888_ir_fifo_rec *) buf, i = 0; i < n; p++, i++) { - - if ((p->hw_fifo_data & FIFO_RXTX_RTO) == FIFO_RXTX_RTO) { - /* Assume RTO was because of no IR light input */ - u = 0; - w = 1; - } else { - u = (p->hw_fifo_data & FIFO_RXTX_LVL) ? 1 : 0; - if (invert) - u = u ? 0 : 1; - w = 0; - } - - v = (unsigned) pulse_width_count_to_ns( - (u16) (p->hw_fifo_data & FIFO_RXTX), divider); - if (v > IR_MAX_DURATION) - v = IR_MAX_DURATION; - - init_ir_raw_event(&p->ir_core_data); - p->ir_core_data.pulse = u; - p->ir_core_data.duration = v; - p->ir_core_data.timeout = w; - - v4l2_dbg(2, ir_888_debug, sd, "rx read: %10u ns %s %s\n", - v, u ? "mark" : "space", w ? "(timed out)" : ""); - if (w) - v4l2_dbg(2, ir_888_debug, sd, "rx read: end of rx\n"); - } - return 0; -} - -static int cx23888_ir_rx_g_parameters(struct v4l2_subdev *sd, - struct v4l2_subdev_ir_parameters *p) -{ - struct cx23888_ir_state *state = to_state(sd); - mutex_lock(&state->rx_params_lock); - memcpy(p, &state->rx_params, sizeof(struct v4l2_subdev_ir_parameters)); - mutex_unlock(&state->rx_params_lock); - return 0; -} - -static int cx23888_ir_rx_shutdown(struct v4l2_subdev *sd) -{ - struct cx23888_ir_state *state = to_state(sd); - struct cx23885_dev *dev = state->dev; - - mutex_lock(&state->rx_params_lock); - - /* Disable or slow down all IR Rx circuits and counters */ - irqenable_rx(dev, 0); - control_rx_enable(dev, false); - control_rx_demodulation_enable(dev, false); - control_rx_s_edge_detection(dev, CNTRL_EDG_NONE); - filter_rx_s_min_width(dev, 0); - cx23888_ir_write4(dev, CX23888_IR_RXCLK_REG, RXCLK_RCD); - - state->rx_params.shutdown = true; - - mutex_unlock(&state->rx_params_lock); - return 0; -} - -static int cx23888_ir_rx_s_parameters(struct v4l2_subdev *sd, - struct v4l2_subdev_ir_parameters *p) -{ - struct cx23888_ir_state *state = to_state(sd); - struct cx23885_dev *dev = state->dev; - struct v4l2_subdev_ir_parameters *o = &state->rx_params; - u16 rxclk_divider; - - if (p->shutdown) - return cx23888_ir_rx_shutdown(sd); - - if (p->mode != V4L2_SUBDEV_IR_MODE_PULSE_WIDTH) - return -ENOSYS; - - mutex_lock(&state->rx_params_lock); - - o->shutdown = p->shutdown; - - o->mode = p->mode = V4L2_SUBDEV_IR_MODE_PULSE_WIDTH; - - o->bytes_per_data_element = p->bytes_per_data_element - = sizeof(union cx23888_ir_fifo_rec); - - /* Before we tweak the hardware, we have to disable the receiver */ - irqenable_rx(dev, 0); - control_rx_enable(dev, false); - - control_rx_demodulation_enable(dev, p->modulation); - o->modulation = p->modulation; - - if (p->modulation) { - p->carrier_freq = rxclk_rx_s_carrier(dev, p->carrier_freq, - &rxclk_divider); - - o->carrier_freq = p->carrier_freq; - - o->duty_cycle = p->duty_cycle = 50; - - control_rx_s_carrier_window(dev, p->carrier_freq, - &p->carrier_range_lower, - &p->carrier_range_upper); - o->carrier_range_lower = p->carrier_range_lower; - o->carrier_range_upper = p->carrier_range_upper; - - p->max_pulse_width = - (u32) pulse_width_count_to_ns(FIFO_RXTX, rxclk_divider); - } else { - p->max_pulse_width = - rxclk_rx_s_max_pulse_width(dev, p->max_pulse_width, - &rxclk_divider); - } - o->max_pulse_width = p->max_pulse_width; - atomic_set(&state->rxclk_divider, rxclk_divider); - - p->noise_filter_min_width = - filter_rx_s_min_width(dev, p->noise_filter_min_width); - o->noise_filter_min_width = p->noise_filter_min_width; - - p->resolution = clock_divider_to_resolution(rxclk_divider); - o->resolution = p->resolution; - - /* FIXME - make this dependent on resolution for better performance */ - control_rx_irq_watermark(dev, RX_FIFO_HALF_FULL); - - control_rx_s_edge_detection(dev, CNTRL_EDG_BOTH); - - o->invert_level = p->invert_level; - atomic_set(&state->rx_invert, p->invert_level); - - o->interrupt_enable = p->interrupt_enable; - o->enable = p->enable; - if (p->enable) { - unsigned long flags; - - spin_lock_irqsave(&state->rx_kfifo_lock, flags); - kfifo_reset(&state->rx_kfifo); - /* reset tx_fifo too if there is one... */ - spin_unlock_irqrestore(&state->rx_kfifo_lock, flags); - if (p->interrupt_enable) - irqenable_rx(dev, IRQEN_RSE | IRQEN_RTE | IRQEN_ROE); - control_rx_enable(dev, p->enable); - } - - mutex_unlock(&state->rx_params_lock); - return 0; -} - -/* Transmitter */ -static int cx23888_ir_tx_write(struct v4l2_subdev *sd, u8 *buf, size_t count, - ssize_t *num) -{ - struct cx23888_ir_state *state = to_state(sd); - struct cx23885_dev *dev = state->dev; - /* For now enable the Tx FIFO Service interrupt & pretend we did work */ - irqenable_tx(dev, IRQEN_TSE); - *num = count; - return 0; -} - -static int cx23888_ir_tx_g_parameters(struct v4l2_subdev *sd, - struct v4l2_subdev_ir_parameters *p) -{ - struct cx23888_ir_state *state = to_state(sd); - mutex_lock(&state->tx_params_lock); - memcpy(p, &state->tx_params, sizeof(struct v4l2_subdev_ir_parameters)); - mutex_unlock(&state->tx_params_lock); - return 0; -} - -static int cx23888_ir_tx_shutdown(struct v4l2_subdev *sd) -{ - struct cx23888_ir_state *state = to_state(sd); - struct cx23885_dev *dev = state->dev; - - mutex_lock(&state->tx_params_lock); - - /* Disable or slow down all IR Tx circuits and counters */ - irqenable_tx(dev, 0); - control_tx_enable(dev, false); - control_tx_modulation_enable(dev, false); - cx23888_ir_write4(dev, CX23888_IR_TXCLK_REG, TXCLK_TCD); - - state->tx_params.shutdown = true; - - mutex_unlock(&state->tx_params_lock); - return 0; -} - -static int cx23888_ir_tx_s_parameters(struct v4l2_subdev *sd, - struct v4l2_subdev_ir_parameters *p) -{ - struct cx23888_ir_state *state = to_state(sd); - struct cx23885_dev *dev = state->dev; - struct v4l2_subdev_ir_parameters *o = &state->tx_params; - u16 txclk_divider; - - if (p->shutdown) - return cx23888_ir_tx_shutdown(sd); - - if (p->mode != V4L2_SUBDEV_IR_MODE_PULSE_WIDTH) - return -ENOSYS; - - mutex_lock(&state->tx_params_lock); - - o->shutdown = p->shutdown; - - o->mode = p->mode = V4L2_SUBDEV_IR_MODE_PULSE_WIDTH; - - o->bytes_per_data_element = p->bytes_per_data_element - = sizeof(union cx23888_ir_fifo_rec); - - /* Before we tweak the hardware, we have to disable the transmitter */ - irqenable_tx(dev, 0); - control_tx_enable(dev, false); - - control_tx_modulation_enable(dev, p->modulation); - o->modulation = p->modulation; - - if (p->modulation) { - p->carrier_freq = txclk_tx_s_carrier(dev, p->carrier_freq, - &txclk_divider); - o->carrier_freq = p->carrier_freq; - - p->duty_cycle = cduty_tx_s_duty_cycle(dev, p->duty_cycle); - o->duty_cycle = p->duty_cycle; - - p->max_pulse_width = - (u32) pulse_width_count_to_ns(FIFO_RXTX, txclk_divider); - } else { - p->max_pulse_width = - txclk_tx_s_max_pulse_width(dev, p->max_pulse_width, - &txclk_divider); - } - o->max_pulse_width = p->max_pulse_width; - atomic_set(&state->txclk_divider, txclk_divider); - - p->resolution = clock_divider_to_resolution(txclk_divider); - o->resolution = p->resolution; - - /* FIXME - make this dependent on resolution for better performance */ - control_tx_irq_watermark(dev, TX_FIFO_HALF_EMPTY); - - control_tx_polarity_invert(dev, p->invert_carrier_sense); - o->invert_carrier_sense = p->invert_carrier_sense; - - control_tx_level_invert(dev, p->invert_level); - o->invert_level = p->invert_level; - - o->interrupt_enable = p->interrupt_enable; - o->enable = p->enable; - if (p->enable) { - if (p->interrupt_enable) - irqenable_tx(dev, IRQEN_TSE); - control_tx_enable(dev, p->enable); - } - - mutex_unlock(&state->tx_params_lock); - return 0; -} - - -/* - * V4L2 Subdevice Core Ops - */ -static int cx23888_ir_log_status(struct v4l2_subdev *sd) -{ - struct cx23888_ir_state *state = to_state(sd); - struct cx23885_dev *dev = state->dev; - char *s; - int i, j; - - u32 cntrl = cx23888_ir_read4(dev, CX23888_IR_CNTRL_REG); - u32 txclk = cx23888_ir_read4(dev, CX23888_IR_TXCLK_REG) & TXCLK_TCD; - u32 rxclk = cx23888_ir_read4(dev, CX23888_IR_RXCLK_REG) & RXCLK_RCD; - u32 cduty = cx23888_ir_read4(dev, CX23888_IR_CDUTY_REG) & CDUTY_CDC; - u32 stats = cx23888_ir_read4(dev, CX23888_IR_STATS_REG); - u32 irqen = cx23888_ir_read4(dev, CX23888_IR_IRQEN_REG); - u32 filtr = cx23888_ir_read4(dev, CX23888_IR_FILTR_REG) & FILTR_LPF; - - v4l2_info(sd, "IR Receiver:\n"); - v4l2_info(sd, "\tEnabled: %s\n", - cntrl & CNTRL_RXE ? "yes" : "no"); - v4l2_info(sd, "\tDemodulation from a carrier: %s\n", - cntrl & CNTRL_DMD ? "enabled" : "disabled"); - v4l2_info(sd, "\tFIFO: %s\n", - cntrl & CNTRL_RFE ? "enabled" : "disabled"); - switch (cntrl & CNTRL_EDG) { - case CNTRL_EDG_NONE: - s = "disabled"; - break; - case CNTRL_EDG_FALL: - s = "falling edge"; - break; - case CNTRL_EDG_RISE: - s = "rising edge"; - break; - case CNTRL_EDG_BOTH: - s = "rising & falling edges"; - break; - default: - s = "??? edge"; - break; - } - v4l2_info(sd, "\tPulse timers' start/stop trigger: %s\n", s); - v4l2_info(sd, "\tFIFO data on pulse timer overflow: %s\n", - cntrl & CNTRL_R ? "not loaded" : "overflow marker"); - v4l2_info(sd, "\tFIFO interrupt watermark: %s\n", - cntrl & CNTRL_RIC ? "not empty" : "half full or greater"); - v4l2_info(sd, "\tLoopback mode: %s\n", - cntrl & CNTRL_LBM ? "loopback active" : "normal receive"); - if (cntrl & CNTRL_DMD) { - v4l2_info(sd, "\tExpected carrier (16 clocks): %u Hz\n", - clock_divider_to_carrier_freq(rxclk)); - switch (cntrl & CNTRL_WIN) { - case CNTRL_WIN_3_3: - i = 3; - j = 3; - break; - case CNTRL_WIN_4_3: - i = 4; - j = 3; - break; - case CNTRL_WIN_3_4: - i = 3; - j = 4; - break; - case CNTRL_WIN_4_4: - i = 4; - j = 4; - break; - default: - i = 0; - j = 0; - break; - } - v4l2_info(sd, "\tNext carrier edge window: 16 clocks " - "-%1d/+%1d, %u to %u Hz\n", i, j, - clock_divider_to_freq(rxclk, 16 + j), - clock_divider_to_freq(rxclk, 16 - i)); - } - v4l2_info(sd, "\tMax measurable pulse width: %u us, %llu ns\n", - pulse_width_count_to_us(FIFO_RXTX, rxclk), - pulse_width_count_to_ns(FIFO_RXTX, rxclk)); - v4l2_info(sd, "\tLow pass filter: %s\n", - filtr ? "enabled" : "disabled"); - if (filtr) - v4l2_info(sd, "\tMin acceptable pulse width (LPF): %u us, " - "%u ns\n", - lpf_count_to_us(filtr), - lpf_count_to_ns(filtr)); - v4l2_info(sd, "\tPulse width timer timed-out: %s\n", - stats & STATS_RTO ? "yes" : "no"); - v4l2_info(sd, "\tPulse width timer time-out intr: %s\n", - irqen & IRQEN_RTE ? "enabled" : "disabled"); - v4l2_info(sd, "\tFIFO overrun: %s\n", - stats & STATS_ROR ? "yes" : "no"); - v4l2_info(sd, "\tFIFO overrun interrupt: %s\n", - irqen & IRQEN_ROE ? "enabled" : "disabled"); - v4l2_info(sd, "\tBusy: %s\n", - stats & STATS_RBY ? "yes" : "no"); - v4l2_info(sd, "\tFIFO service requested: %s\n", - stats & STATS_RSR ? "yes" : "no"); - v4l2_info(sd, "\tFIFO service request interrupt: %s\n", - irqen & IRQEN_RSE ? "enabled" : "disabled"); - - v4l2_info(sd, "IR Transmitter:\n"); - v4l2_info(sd, "\tEnabled: %s\n", - cntrl & CNTRL_TXE ? "yes" : "no"); - v4l2_info(sd, "\tModulation onto a carrier: %s\n", - cntrl & CNTRL_MOD ? "enabled" : "disabled"); - v4l2_info(sd, "\tFIFO: %s\n", - cntrl & CNTRL_TFE ? "enabled" : "disabled"); - v4l2_info(sd, "\tFIFO interrupt watermark: %s\n", - cntrl & CNTRL_TIC ? "not empty" : "half full or less"); - v4l2_info(sd, "\tOutput pin level inversion %s\n", - cntrl & CNTRL_IVO ? "yes" : "no"); - v4l2_info(sd, "\tCarrier polarity: %s\n", - cntrl & CNTRL_CPL ? "space:burst mark:noburst" - : "space:noburst mark:burst"); - if (cntrl & CNTRL_MOD) { - v4l2_info(sd, "\tCarrier (16 clocks): %u Hz\n", - clock_divider_to_carrier_freq(txclk)); - v4l2_info(sd, "\tCarrier duty cycle: %2u/16\n", - cduty + 1); - } - v4l2_info(sd, "\tMax pulse width: %u us, %llu ns\n", - pulse_width_count_to_us(FIFO_RXTX, txclk), - pulse_width_count_to_ns(FIFO_RXTX, txclk)); - v4l2_info(sd, "\tBusy: %s\n", - stats & STATS_TBY ? "yes" : "no"); - v4l2_info(sd, "\tFIFO service requested: %s\n", - stats & STATS_TSR ? "yes" : "no"); - v4l2_info(sd, "\tFIFO service request interrupt: %s\n", - irqen & IRQEN_TSE ? "enabled" : "disabled"); - - return 0; -} - -static inline int cx23888_ir_dbg_match(const struct v4l2_dbg_match *match) -{ - return match->type == V4L2_CHIP_MATCH_HOST && match->addr == 2; -} - -static int cx23888_ir_g_chip_ident(struct v4l2_subdev *sd, - struct v4l2_dbg_chip_ident *chip) -{ - struct cx23888_ir_state *state = to_state(sd); - - if (cx23888_ir_dbg_match(&chip->match)) { - chip->ident = state->id; - chip->revision = state->rev; - } - return 0; -} - -#ifdef CONFIG_VIDEO_ADV_DEBUG -static int cx23888_ir_g_register(struct v4l2_subdev *sd, - struct v4l2_dbg_register *reg) -{ - struct cx23888_ir_state *state = to_state(sd); - u32 addr = CX23888_IR_REG_BASE + (u32) reg->reg; - - if (!cx23888_ir_dbg_match(®->match)) - return -EINVAL; - if ((addr & 0x3) != 0) - return -EINVAL; - if (addr < CX23888_IR_CNTRL_REG || addr > CX23888_IR_LEARN_REG) - return -EINVAL; - if (!capable(CAP_SYS_ADMIN)) - return -EPERM; - reg->size = 4; - reg->val = cx23888_ir_read4(state->dev, addr); - return 0; -} - -static int cx23888_ir_s_register(struct v4l2_subdev *sd, - struct v4l2_dbg_register *reg) -{ - struct cx23888_ir_state *state = to_state(sd); - u32 addr = CX23888_IR_REG_BASE + (u32) reg->reg; - - if (!cx23888_ir_dbg_match(®->match)) - return -EINVAL; - if ((addr & 0x3) != 0) - return -EINVAL; - if (addr < CX23888_IR_CNTRL_REG || addr > CX23888_IR_LEARN_REG) - return -EINVAL; - if (!capable(CAP_SYS_ADMIN)) - return -EPERM; - cx23888_ir_write4(state->dev, addr, reg->val); - return 0; -} -#endif - -static const struct v4l2_subdev_core_ops cx23888_ir_core_ops = { - .g_chip_ident = cx23888_ir_g_chip_ident, - .log_status = cx23888_ir_log_status, -#ifdef CONFIG_VIDEO_ADV_DEBUG - .g_register = cx23888_ir_g_register, - .s_register = cx23888_ir_s_register, -#endif - .interrupt_service_routine = cx23888_ir_irq_handler, -}; - -static const struct v4l2_subdev_ir_ops cx23888_ir_ir_ops = { - .rx_read = cx23888_ir_rx_read, - .rx_g_parameters = cx23888_ir_rx_g_parameters, - .rx_s_parameters = cx23888_ir_rx_s_parameters, - - .tx_write = cx23888_ir_tx_write, - .tx_g_parameters = cx23888_ir_tx_g_parameters, - .tx_s_parameters = cx23888_ir_tx_s_parameters, -}; - -static const struct v4l2_subdev_ops cx23888_ir_controller_ops = { - .core = &cx23888_ir_core_ops, - .ir = &cx23888_ir_ir_ops, -}; - -static const struct v4l2_subdev_ir_parameters default_rx_params = { - .bytes_per_data_element = sizeof(union cx23888_ir_fifo_rec), - .mode = V4L2_SUBDEV_IR_MODE_PULSE_WIDTH, - - .enable = false, - .interrupt_enable = false, - .shutdown = true, - - .modulation = true, - .carrier_freq = 36000, /* 36 kHz - RC-5, RC-6, and RC-6A carrier */ - - /* RC-5: 666,667 ns = 1/36 kHz * 32 cycles * 1 mark * 0.75 */ - /* RC-6A: 333,333 ns = 1/36 kHz * 16 cycles * 1 mark * 0.75 */ - .noise_filter_min_width = 333333, /* ns */ - .carrier_range_lower = 35000, - .carrier_range_upper = 37000, - .invert_level = false, -}; - -static const struct v4l2_subdev_ir_parameters default_tx_params = { - .bytes_per_data_element = sizeof(union cx23888_ir_fifo_rec), - .mode = V4L2_SUBDEV_IR_MODE_PULSE_WIDTH, - - .enable = false, - .interrupt_enable = false, - .shutdown = true, - - .modulation = true, - .carrier_freq = 36000, /* 36 kHz - RC-5 carrier */ - .duty_cycle = 25, /* 25 % - RC-5 carrier */ - .invert_level = false, - .invert_carrier_sense = false, -}; - -int cx23888_ir_probe(struct cx23885_dev *dev) -{ - struct cx23888_ir_state *state; - struct v4l2_subdev *sd; - struct v4l2_subdev_ir_parameters default_params; - int ret; - - state = kzalloc(sizeof(struct cx23888_ir_state), GFP_KERNEL); - if (state == NULL) - return -ENOMEM; - - spin_lock_init(&state->rx_kfifo_lock); - if (kfifo_alloc(&state->rx_kfifo, CX23888_IR_RX_KFIFO_SIZE, GFP_KERNEL)) - return -ENOMEM; - - state->dev = dev; - state->id = V4L2_IDENT_CX23888_IR; - state->rev = 0; - sd = &state->sd; - - v4l2_subdev_init(sd, &cx23888_ir_controller_ops); - v4l2_set_subdevdata(sd, state); - /* FIXME - fix the formatting of dev->v4l2_dev.name and use it */ - snprintf(sd->name, sizeof(sd->name), "%s/888-ir", dev->name); - sd->grp_id = CX23885_HW_888_IR; - - ret = v4l2_device_register_subdev(&dev->v4l2_dev, sd); - if (ret == 0) { - /* - * Ensure no interrupts arrive from '888 specific conditions, - * since we ignore them in this driver to have commonality with - * similar IR controller cores. - */ - cx23888_ir_write4(dev, CX23888_IR_IRQEN_REG, 0); - - mutex_init(&state->rx_params_lock); - memcpy(&default_params, &default_rx_params, - sizeof(struct v4l2_subdev_ir_parameters)); - v4l2_subdev_call(sd, ir, rx_s_parameters, &default_params); - - mutex_init(&state->tx_params_lock); - memcpy(&default_params, &default_tx_params, - sizeof(struct v4l2_subdev_ir_parameters)); - v4l2_subdev_call(sd, ir, tx_s_parameters, &default_params); - } else { - kfifo_free(&state->rx_kfifo); - } - return ret; -} - -int cx23888_ir_remove(struct cx23885_dev *dev) -{ - struct v4l2_subdev *sd; - struct cx23888_ir_state *state; - - sd = cx23885_find_hw(dev, CX23885_HW_888_IR); - if (sd == NULL) - return -ENODEV; - - cx23888_ir_rx_shutdown(sd); - cx23888_ir_tx_shutdown(sd); - - state = to_state(sd); - v4l2_device_unregister_subdev(sd); - kfifo_free(&state->rx_kfifo); - kfree(state); - /* Nothing more to free() as state held the actual v4l2_subdev object */ - return 0; -} diff --git a/drivers/media/video/cx23885/cx23888-ir.h b/drivers/media/video/cx23885/cx23888-ir.h deleted file mode 100644 index d2de41caaf1..00000000000 --- a/drivers/media/video/cx23885/cx23888-ir.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Driver for the Conexant CX23885/7/8 PCIe bridge - * - * CX23888 Integrated Consumer Infrared Controller - * - * Copyright (C) 2009 Andy Walls <awalls@md.metrocast.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 _CX23888_IR_H_ -#define _CX23888_IR_H_ -int cx23888_ir_probe(struct cx23885_dev *dev); -int cx23888_ir_remove(struct cx23885_dev *dev); -#endif diff --git a/drivers/media/video/cx23885/netup-eeprom.c b/drivers/media/video/cx23885/netup-eeprom.c deleted file mode 100644 index 98a48f50068..00000000000 --- a/drivers/media/video/cx23885/netup-eeprom.c +++ /dev/null @@ -1,107 +0,0 @@ - -/* - * netup-eeprom.c - * - * 24LC02 EEPROM driver in conjunction with NetUP Dual DVB-S2 CI card - * - * Copyright (C) 2009 NetUP Inc. - * Copyright (C) 2009 Abylay Ospan <aospan@netup.ru> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -# -#include "cx23885.h" -#include "netup-eeprom.h" - -#define EEPROM_I2C_ADDR 0x50 - -int netup_eeprom_read(struct i2c_adapter *i2c_adap, u8 addr) -{ - int ret; - unsigned char buf[2]; - - /* Read from EEPROM */ - struct i2c_msg msg[] = { - { - .addr = EEPROM_I2C_ADDR, - .flags = 0, - .buf = &buf[0], - .len = 1 - }, { - .addr = EEPROM_I2C_ADDR, - .flags = I2C_M_RD, - .buf = &buf[1], - .len = 1 - } - - }; - - buf[0] = addr; - buf[1] = 0x0; - - ret = i2c_transfer(i2c_adap, msg, 2); - - if (ret != 2) { - printk(KERN_ERR "eeprom i2c read error, status=%d\n", ret); - return -1; - } - - return buf[1]; -}; - -int netup_eeprom_write(struct i2c_adapter *i2c_adap, u8 addr, u8 data) -{ - int ret; - unsigned char bufw[2]; - - /* Write into EEPROM */ - struct i2c_msg msg[] = { - { - .addr = EEPROM_I2C_ADDR, - .flags = 0, - .buf = &bufw[0], - .len = 2 - } - }; - - bufw[0] = addr; - bufw[1] = data; - - ret = i2c_transfer(i2c_adap, msg, 1); - - if (ret != 1) { - printk(KERN_ERR "eeprom i2c write error, status=%d\n", ret); - return -1; - } - - mdelay(10); /* prophylactic delay, datasheet write cycle time = 5 ms */ - return 0; -}; - -void netup_get_card_info(struct i2c_adapter *i2c_adap, - struct netup_card_info *cinfo) -{ - int i, j; - - cinfo->rev = netup_eeprom_read(i2c_adap, 63); - - for (i = 64, j = 0; i < 70; i++, j++) - cinfo->port[0].mac[j] = netup_eeprom_read(i2c_adap, i); - - for (i = 70, j = 0; i < 76; i++, j++) - cinfo->port[1].mac[j] = netup_eeprom_read(i2c_adap, i); -}; diff --git a/drivers/media/video/cx23885/netup-eeprom.h b/drivers/media/video/cx23885/netup-eeprom.h deleted file mode 100644 index 13926e18feb..00000000000 --- a/drivers/media/video/cx23885/netup-eeprom.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * netup-eeprom.h - * - * 24LC02 EEPROM driver in conjunction with NetUP Dual DVB-S2 CI card - * - * Copyright (C) 2009 NetUP Inc. - * Copyright (C) 2009 Abylay Ospan <aospan@netup.ru> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#ifndef NETUP_EEPROM_H -#define NETUP_EEPROM_H - -struct netup_port_info { - u8 mac[6];/* card MAC address */ -}; - -struct netup_card_info { - struct netup_port_info port[2];/* ports - 1,2 */ - u8 rev;/* card revision */ -}; - -extern int netup_eeprom_read(struct i2c_adapter *i2c_adap, u8 addr); -extern int netup_eeprom_write(struct i2c_adapter *i2c_adap, u8 addr, u8 data); -extern void netup_get_card_info(struct i2c_adapter *i2c_adap, - struct netup_card_info *cinfo); - -#endif diff --git a/drivers/media/video/cx23885/netup-init.c b/drivers/media/video/cx23885/netup-init.c deleted file mode 100644 index f4893e69cd8..00000000000 --- a/drivers/media/video/cx23885/netup-init.c +++ /dev/null @@ -1,125 +0,0 @@ -/* - * netup-init.c - * - * NetUP Dual DVB-S2 CI driver - * - * Copyright (C) 2009 NetUP Inc. - * Copyright (C) 2009 Igor M. Liplianin <liplianin@netup.ru> - * Copyright (C) 2009 Abylay Ospan <aospan@netup.ru> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include "cx23885.h" - -static void i2c_av_write(struct i2c_adapter *i2c, u16 reg, u8 val) -{ - int ret; - u8 buf[3]; - struct i2c_msg msg = { - .addr = 0x88 >> 1, - .flags = 0, - .buf = buf, - .len = 3 - }; - - buf[0] = reg >> 8; - buf[1] = reg & 0xff; - buf[2] = val; - - ret = i2c_transfer(i2c, &msg, 1); - - if (ret != 1) - printk(KERN_ERR "%s: i2c write error!\n", __func__); -} - -static void i2c_av_write4(struct i2c_adapter *i2c, u16 reg, u32 val) -{ - int ret; - u8 buf[6]; - struct i2c_msg msg = { - .addr = 0x88 >> 1, - .flags = 0, - .buf = buf, - .len = 6 - }; - - buf[0] = reg >> 8; - buf[1] = reg & 0xff; - buf[2] = val & 0xff; - buf[3] = (val >> 8) & 0xff; - buf[4] = (val >> 16) & 0xff; - buf[5] = val >> 24; - - ret = i2c_transfer(i2c, &msg, 1); - - if (ret != 1) - printk(KERN_ERR "%s: i2c write error!\n", __func__); -} - -static u8 i2c_av_read(struct i2c_adapter *i2c, u16 reg) -{ - int ret; - u8 buf[2]; - struct i2c_msg msg = { - .addr = 0x88 >> 1, - .flags = 0, - .buf = buf, - .len = 2 - }; - - buf[0] = reg >> 8; - buf[1] = reg & 0xff; - - ret = i2c_transfer(i2c, &msg, 1); - - if (ret != 1) - printk(KERN_ERR "%s: i2c write error!\n", __func__); - - msg.flags = I2C_M_RD; - msg.len = 1; - - ret = i2c_transfer(i2c, &msg, 1); - - if (ret != 1) - printk(KERN_ERR "%s: i2c read error!\n", __func__); - - return buf[0]; -} - -static void i2c_av_and_or(struct i2c_adapter *i2c, u16 reg, unsigned and_mask, - u8 or_value) -{ - i2c_av_write(i2c, reg, (i2c_av_read(i2c, reg) & and_mask) | or_value); -} -/* set 27MHz on AUX_CLK */ -void netup_initialize(struct cx23885_dev *dev) -{ - struct cx23885_i2c *i2c_bus = &dev->i2c_bus[2]; - struct i2c_adapter *i2c = &i2c_bus->i2c_adap; - - /* Stop microcontroller */ - i2c_av_and_or(i2c, 0x803, ~0x10, 0x00); - - /* Aux PLL frac for 27 MHz */ - i2c_av_write4(i2c, 0x114, 0xea0eb3); - - /* Aux PLL int for 27 MHz */ - i2c_av_write4(i2c, 0x110, 0x090319); - - /* start microcontroller */ - i2c_av_and_or(i2c, 0x803, ~0x10, 0x10); -} diff --git a/drivers/media/video/cx23885/netup-init.h b/drivers/media/video/cx23885/netup-init.h deleted file mode 100644 index d26ae4b1590..00000000000 --- a/drivers/media/video/cx23885/netup-init.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * netup-init.h - * - * NetUP Dual DVB-S2 CI driver - * - * Copyright (C) 2009 NetUP Inc. - * Copyright (C) 2009 Igor M. Liplianin <liplianin@netup.ru> - * Copyright (C) 2009 Abylay Ospan <aospan@netup.ru> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ -extern void netup_initialize(struct cx23885_dev *dev); |