cx23885-dvb.c revision f139fa71c03d80c1d1ee60aa4b0a3ec7a14d45f9
1d19770e5178a4bc49641711246360c25781d20a4Steven Toth/* 2d19770e5178a4bc49641711246360c25781d20a4Steven Toth * Driver for the Conexant CX23885 PCIe bridge 3d19770e5178a4bc49641711246360c25781d20a4Steven Toth * 4d19770e5178a4bc49641711246360c25781d20a4Steven Toth * Copyright (c) 2006 Steven Toth <stoth@hauppauge.com> 5d19770e5178a4bc49641711246360c25781d20a4Steven Toth * 6d19770e5178a4bc49641711246360c25781d20a4Steven Toth * This program is free software; you can redistribute it and/or modify 7d19770e5178a4bc49641711246360c25781d20a4Steven Toth * it under the terms of the GNU General Public License as published by 8d19770e5178a4bc49641711246360c25781d20a4Steven Toth * the Free Software Foundation; either version 2 of the License, or 9d19770e5178a4bc49641711246360c25781d20a4Steven Toth * (at your option) any later version. 10d19770e5178a4bc49641711246360c25781d20a4Steven Toth * 11d19770e5178a4bc49641711246360c25781d20a4Steven Toth * This program is distributed in the hope that it will be useful, 12d19770e5178a4bc49641711246360c25781d20a4Steven Toth * but WITHOUT ANY WARRANTY; without even the implied warranty of 13d19770e5178a4bc49641711246360c25781d20a4Steven Toth * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14d19770e5178a4bc49641711246360c25781d20a4Steven Toth * 15d19770e5178a4bc49641711246360c25781d20a4Steven Toth * GNU General Public License for more details. 16d19770e5178a4bc49641711246360c25781d20a4Steven Toth * 17d19770e5178a4bc49641711246360c25781d20a4Steven Toth * You should have received a copy of the GNU General Public License 18d19770e5178a4bc49641711246360c25781d20a4Steven Toth * along with this program; if not, write to the Free Software 19d19770e5178a4bc49641711246360c25781d20a4Steven Toth * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 20d19770e5178a4bc49641711246360c25781d20a4Steven Toth */ 21d19770e5178a4bc49641711246360c25781d20a4Steven Toth 22d19770e5178a4bc49641711246360c25781d20a4Steven Toth#include <linux/module.h> 23d19770e5178a4bc49641711246360c25781d20a4Steven Toth#include <linux/init.h> 24d19770e5178a4bc49641711246360c25781d20a4Steven Toth#include <linux/device.h> 25d19770e5178a4bc49641711246360c25781d20a4Steven Toth#include <linux/fs.h> 26d19770e5178a4bc49641711246360c25781d20a4Steven Toth#include <linux/kthread.h> 27d19770e5178a4bc49641711246360c25781d20a4Steven Toth#include <linux/file.h> 28d19770e5178a4bc49641711246360c25781d20a4Steven Toth#include <linux/suspend.h> 29d19770e5178a4bc49641711246360c25781d20a4Steven Toth 30d19770e5178a4bc49641711246360c25781d20a4Steven Toth#include "cx23885.h" 31d19770e5178a4bc49641711246360c25781d20a4Steven Toth#include <media/v4l2-common.h> 32d19770e5178a4bc49641711246360c25781d20a4Steven Toth 33d19770e5178a4bc49641711246360c25781d20a4Steven Toth#include "s5h1409.h" 34d19770e5178a4bc49641711246360c25781d20a4Steven Toth#include "mt2131.h" 359bc37caadffe8327683980b2323371691fa182e3Michael Krufky#include "lgdt330x.h" 369bc37caadffe8327683980b2323371691fa182e3Michael Krufky#include "dvb-pll.h" 37d19770e5178a4bc49641711246360c25781d20a4Steven Toth 382e52f215be1b3a0337788c8d3345bdf5e3894e19Steven Tothstatic unsigned int debug = 0; 39d19770e5178a4bc49641711246360c25781d20a4Steven Toth 40d19770e5178a4bc49641711246360c25781d20a4Steven Toth#define dprintk(level,fmt, arg...) if (debug >= level) \ 41d19770e5178a4bc49641711246360c25781d20a4Steven Toth printk(KERN_DEBUG "%s: " fmt, dev->name, ## arg) 42d19770e5178a4bc49641711246360c25781d20a4Steven Toth 43d19770e5178a4bc49641711246360c25781d20a4Steven Toth/* ------------------------------------------------------------------ */ 44d19770e5178a4bc49641711246360c25781d20a4Steven Toth 45d19770e5178a4bc49641711246360c25781d20a4Steven Tothstatic int dvb_buf_setup(struct videobuf_queue *q, 46d19770e5178a4bc49641711246360c25781d20a4Steven Toth unsigned int *count, unsigned int *size) 47d19770e5178a4bc49641711246360c25781d20a4Steven Toth{ 48d19770e5178a4bc49641711246360c25781d20a4Steven Toth struct cx23885_tsport *port = q->priv_data; 49d19770e5178a4bc49641711246360c25781d20a4Steven Toth 50d19770e5178a4bc49641711246360c25781d20a4Steven Toth port->ts_packet_size = 188 * 4; 51d19770e5178a4bc49641711246360c25781d20a4Steven Toth port->ts_packet_count = 32; 52d19770e5178a4bc49641711246360c25781d20a4Steven Toth 53d19770e5178a4bc49641711246360c25781d20a4Steven Toth *size = port->ts_packet_size * port->ts_packet_count; 54d19770e5178a4bc49641711246360c25781d20a4Steven Toth *count = 32; 55d19770e5178a4bc49641711246360c25781d20a4Steven Toth return 0; 56d19770e5178a4bc49641711246360c25781d20a4Steven Toth} 57d19770e5178a4bc49641711246360c25781d20a4Steven Toth 5844a6481dcd9ec835bbd608b1b2ee47ee62c7e1d8Michael Krufkystatic int dvb_buf_prepare(struct videobuf_queue *q, 5944a6481dcd9ec835bbd608b1b2ee47ee62c7e1d8Michael Krufky struct videobuf_buffer *vb, enum v4l2_field field) 60d19770e5178a4bc49641711246360c25781d20a4Steven Toth{ 61d19770e5178a4bc49641711246360c25781d20a4Steven Toth struct cx23885_tsport *port = q->priv_data; 6244a6481dcd9ec835bbd608b1b2ee47ee62c7e1d8Michael Krufky return cx23885_buf_prepare(q, port, (struct cx23885_buffer*)vb, field); 63d19770e5178a4bc49641711246360c25781d20a4Steven Toth} 64d19770e5178a4bc49641711246360c25781d20a4Steven Toth 65d19770e5178a4bc49641711246360c25781d20a4Steven Tothstatic void dvb_buf_queue(struct videobuf_queue *q, struct videobuf_buffer *vb) 66d19770e5178a4bc49641711246360c25781d20a4Steven Toth{ 67d19770e5178a4bc49641711246360c25781d20a4Steven Toth struct cx23885_tsport *port = q->priv_data; 68d19770e5178a4bc49641711246360c25781d20a4Steven Toth cx23885_buf_queue(port, (struct cx23885_buffer*)vb); 69d19770e5178a4bc49641711246360c25781d20a4Steven Toth} 70d19770e5178a4bc49641711246360c25781d20a4Steven Toth 7144a6481dcd9ec835bbd608b1b2ee47ee62c7e1d8Michael Krufkystatic void dvb_buf_release(struct videobuf_queue *q, 7244a6481dcd9ec835bbd608b1b2ee47ee62c7e1d8Michael Krufky struct videobuf_buffer *vb) 73d19770e5178a4bc49641711246360c25781d20a4Steven Toth{ 74d19770e5178a4bc49641711246360c25781d20a4Steven Toth cx23885_free_buffer(q, (struct cx23885_buffer*)vb); 75d19770e5178a4bc49641711246360c25781d20a4Steven Toth} 76d19770e5178a4bc49641711246360c25781d20a4Steven Toth 77d19770e5178a4bc49641711246360c25781d20a4Steven Tothstatic struct videobuf_queue_ops dvb_qops = { 78d19770e5178a4bc49641711246360c25781d20a4Steven Toth .buf_setup = dvb_buf_setup, 79d19770e5178a4bc49641711246360c25781d20a4Steven Toth .buf_prepare = dvb_buf_prepare, 80d19770e5178a4bc49641711246360c25781d20a4Steven Toth .buf_queue = dvb_buf_queue, 81d19770e5178a4bc49641711246360c25781d20a4Steven Toth .buf_release = dvb_buf_release, 82d19770e5178a4bc49641711246360c25781d20a4Steven Toth}; 83d19770e5178a4bc49641711246360c25781d20a4Steven Toth 8486184e06da4b71fc24ae9505ec60ce95c098d0deSteven Tothstatic struct s5h1409_config hauppauge_generic_config = { 85d19770e5178a4bc49641711246360c25781d20a4Steven Toth .demod_address = 0x32 >> 1, 86d19770e5178a4bc49641711246360c25781d20a4Steven Toth .output_mode = S5H1409_SERIAL_OUTPUT, 87fc959befe0f0e4647bb4e326e3ae55875401888aSteven Toth .gpio = S5H1409_GPIO_ON, 88fc959befe0f0e4647bb4e326e3ae55875401888aSteven Toth .if_freq = 44000, 89fc959befe0f0e4647bb4e326e3ae55875401888aSteven Toth .inversion = S5H1409_INVERSION_OFF, 90fc959befe0f0e4647bb4e326e3ae55875401888aSteven Toth .status_mode = S5H1409_DEMODLOCKING 91fc959befe0f0e4647bb4e326e3ae55875401888aSteven Toth}; 92fc959befe0f0e4647bb4e326e3ae55875401888aSteven Toth 93fc959befe0f0e4647bb4e326e3ae55875401888aSteven Tothstatic struct s5h1409_config hauppauge_hvr1800lp_config = { 94fc959befe0f0e4647bb4e326e3ae55875401888aSteven Toth .demod_address = 0x32 >> 1, 95fc959befe0f0e4647bb4e326e3ae55875401888aSteven Toth .output_mode = S5H1409_SERIAL_OUTPUT, 96d19770e5178a4bc49641711246360c25781d20a4Steven Toth .gpio = S5H1409_GPIO_OFF, 97d19770e5178a4bc49641711246360c25781d20a4Steven Toth .if_freq = 44000, 98fe475163ff9680495af3b1b5b7633ea7a42e4185Steven Toth .inversion = S5H1409_INVERSION_OFF, 99fe475163ff9680495af3b1b5b7633ea7a42e4185Steven Toth .status_mode = S5H1409_DEMODLOCKING 100d19770e5178a4bc49641711246360c25781d20a4Steven Toth}; 101d19770e5178a4bc49641711246360c25781d20a4Steven Toth 10286184e06da4b71fc24ae9505ec60ce95c098d0deSteven Tothstatic struct mt2131_config hauppauge_generic_tunerconfig = { 103a77743bc2d29197d48a6f4ae9f8f9e0f0b0ba5d7Steven Toth 0x61 104a77743bc2d29197d48a6f4ae9f8f9e0f0b0ba5d7Steven Toth}; 105a77743bc2d29197d48a6f4ae9f8f9e0f0b0ba5d7Steven Toth 1069bc37caadffe8327683980b2323371691fa182e3Michael Krufkystatic struct lgdt330x_config fusionhdtv_5_express = { 1079bc37caadffe8327683980b2323371691fa182e3Michael Krufky .demod_address = 0x0e, 1089bc37caadffe8327683980b2323371691fa182e3Michael Krufky .demod_chip = LGDT3303, 1099bc37caadffe8327683980b2323371691fa182e3Michael Krufky .serial_mpeg = 0x40, 1109bc37caadffe8327683980b2323371691fa182e3Michael Krufky}; 1119bc37caadffe8327683980b2323371691fa182e3Michael Krufky 112d19770e5178a4bc49641711246360c25781d20a4Steven Tothstatic int dvb_register(struct cx23885_tsport *port) 113d19770e5178a4bc49641711246360c25781d20a4Steven Toth{ 114d19770e5178a4bc49641711246360c25781d20a4Steven Toth struct cx23885_dev *dev = port->dev; 115f139fa71c03d80c1d1ee60aa4b0a3ec7a14d45f9Michael Krufky struct cx23885_i2c *i2c_bus = NULL; 116d19770e5178a4bc49641711246360c25781d20a4Steven Toth 117d19770e5178a4bc49641711246360c25781d20a4Steven Toth /* init struct videobuf_dvb */ 118d19770e5178a4bc49641711246360c25781d20a4Steven Toth port->dvb.name = dev->name; 119d19770e5178a4bc49641711246360c25781d20a4Steven Toth 120d19770e5178a4bc49641711246360c25781d20a4Steven Toth /* init frontend */ 121d19770e5178a4bc49641711246360c25781d20a4Steven Toth switch (dev->board) { 122a77743bc2d29197d48a6f4ae9f8f9e0f0b0ba5d7Steven Toth case CX23885_BOARD_HAUPPAUGE_HVR1250: 123d19770e5178a4bc49641711246360c25781d20a4Steven Toth case CX23885_BOARD_HAUPPAUGE_HVR1800: 124f139fa71c03d80c1d1ee60aa4b0a3ec7a14d45f9Michael Krufky i2c_bus = &dev->i2c_bus[0]; 125d19770e5178a4bc49641711246360c25781d20a4Steven Toth port->dvb.frontend = dvb_attach(s5h1409_attach, 12686184e06da4b71fc24ae9505ec60ce95c098d0deSteven Toth &hauppauge_generic_config, 127f139fa71c03d80c1d1ee60aa4b0a3ec7a14d45f9Michael Krufky &i2c_bus->i2c_adap); 128d19770e5178a4bc49641711246360c25781d20a4Steven Toth if (port->dvb.frontend != NULL) { 12944a6481dcd9ec835bbd608b1b2ee47ee62c7e1d8Michael Krufky dvb_attach(mt2131_attach, port->dvb.frontend, 130f139fa71c03d80c1d1ee60aa4b0a3ec7a14d45f9Michael Krufky &i2c_bus->i2c_adap, 13186184e06da4b71fc24ae9505ec60ce95c098d0deSteven Toth &hauppauge_generic_tunerconfig, 0); 132d19770e5178a4bc49641711246360c25781d20a4Steven Toth } 133d19770e5178a4bc49641711246360c25781d20a4Steven Toth break; 134fc959befe0f0e4647bb4e326e3ae55875401888aSteven Toth case CX23885_BOARD_HAUPPAUGE_HVR1800lp: 135f139fa71c03d80c1d1ee60aa4b0a3ec7a14d45f9Michael Krufky i2c_bus = &dev->i2c_bus[0]; 136fc959befe0f0e4647bb4e326e3ae55875401888aSteven Toth port->dvb.frontend = dvb_attach(s5h1409_attach, 137fc959befe0f0e4647bb4e326e3ae55875401888aSteven Toth &hauppauge_hvr1800lp_config, 138f139fa71c03d80c1d1ee60aa4b0a3ec7a14d45f9Michael Krufky &i2c_bus->i2c_adap); 139fc959befe0f0e4647bb4e326e3ae55875401888aSteven Toth if (port->dvb.frontend != NULL) { 140fc959befe0f0e4647bb4e326e3ae55875401888aSteven Toth dvb_attach(mt2131_attach, port->dvb.frontend, 141f139fa71c03d80c1d1ee60aa4b0a3ec7a14d45f9Michael Krufky &i2c_bus->i2c_adap, 142fc959befe0f0e4647bb4e326e3ae55875401888aSteven Toth &hauppauge_generic_tunerconfig, 0); 143fc959befe0f0e4647bb4e326e3ae55875401888aSteven Toth } 144fc959befe0f0e4647bb4e326e3ae55875401888aSteven Toth break; 1459bc37caadffe8327683980b2323371691fa182e3Michael Krufky case CX23885_BOARD_DVICO_FUSIONHDTV_5_EXP: 146f139fa71c03d80c1d1ee60aa4b0a3ec7a14d45f9Michael Krufky i2c_bus = &dev->i2c_bus[0]; 1479bc37caadffe8327683980b2323371691fa182e3Michael Krufky port->dvb.frontend = dvb_attach(lgdt330x_attach, 1489bc37caadffe8327683980b2323371691fa182e3Michael Krufky &fusionhdtv_5_express, 149f139fa71c03d80c1d1ee60aa4b0a3ec7a14d45f9Michael Krufky &i2c_bus->i2c_adap); 1509bc37caadffe8327683980b2323371691fa182e3Michael Krufky if (port->dvb.frontend != NULL) { 151f139fa71c03d80c1d1ee60aa4b0a3ec7a14d45f9Michael Krufky dvb_attach(dvb_pll_attach, port->dvb.frontend, 0x61, 152f139fa71c03d80c1d1ee60aa4b0a3ec7a14d45f9Michael Krufky &i2c_bus->i2c_adap, DVB_PLL_LG_TDVS_H06XF); 1539bc37caadffe8327683980b2323371691fa182e3Michael Krufky } 1549bc37caadffe8327683980b2323371691fa182e3Michael Krufky break; 155d19770e5178a4bc49641711246360c25781d20a4Steven Toth default: 156d19770e5178a4bc49641711246360c25781d20a4Steven Toth printk("%s: The frontend of your DVB/ATSC card isn't supported yet\n", 157d19770e5178a4bc49641711246360c25781d20a4Steven Toth dev->name); 158d19770e5178a4bc49641711246360c25781d20a4Steven Toth break; 159d19770e5178a4bc49641711246360c25781d20a4Steven Toth } 160d19770e5178a4bc49641711246360c25781d20a4Steven Toth if (NULL == port->dvb.frontend) { 161d19770e5178a4bc49641711246360c25781d20a4Steven Toth printk("%s: frontend initialization failed\n", dev->name); 162d19770e5178a4bc49641711246360c25781d20a4Steven Toth return -1; 163d19770e5178a4bc49641711246360c25781d20a4Steven Toth } 164d19770e5178a4bc49641711246360c25781d20a4Steven Toth 165d19770e5178a4bc49641711246360c25781d20a4Steven Toth /* Put the analog decoder in standby to keep it quiet */ 166f139fa71c03d80c1d1ee60aa4b0a3ec7a14d45f9Michael Krufky cx23885_call_i2c_clients(i2c_bus, TUNER_SET_STANDBY, NULL); 167d19770e5178a4bc49641711246360c25781d20a4Steven Toth 168d19770e5178a4bc49641711246360c25781d20a4Steven Toth /* register everything */ 16944a6481dcd9ec835bbd608b1b2ee47ee62c7e1d8Michael Krufky return videobuf_dvb_register(&port->dvb, THIS_MODULE, port, 17044a6481dcd9ec835bbd608b1b2ee47ee62c7e1d8Michael Krufky &dev->pci->dev); 171d19770e5178a4bc49641711246360c25781d20a4Steven Toth} 172d19770e5178a4bc49641711246360c25781d20a4Steven Toth 173d19770e5178a4bc49641711246360c25781d20a4Steven Tothint cx23885_dvb_register(struct cx23885_tsport *port) 174d19770e5178a4bc49641711246360c25781d20a4Steven Toth{ 175d19770e5178a4bc49641711246360c25781d20a4Steven Toth struct cx23885_dev *dev = port->dev; 176d19770e5178a4bc49641711246360c25781d20a4Steven Toth int err; 177d19770e5178a4bc49641711246360c25781d20a4Steven Toth 17844a6481dcd9ec835bbd608b1b2ee47ee62c7e1d8Michael Krufky dprintk(1, "%s\n", __FUNCTION__); 17944a6481dcd9ec835bbd608b1b2ee47ee62c7e1d8Michael Krufky dprintk(1, " ->being probed by Card=%d Name=%s, PCI %02x:%02x\n", 180d19770e5178a4bc49641711246360c25781d20a4Steven Toth dev->board, 181d19770e5178a4bc49641711246360c25781d20a4Steven Toth dev->name, 182d19770e5178a4bc49641711246360c25781d20a4Steven Toth dev->pci_bus, 183d19770e5178a4bc49641711246360c25781d20a4Steven Toth dev->pci_slot); 184d19770e5178a4bc49641711246360c25781d20a4Steven Toth 185d19770e5178a4bc49641711246360c25781d20a4Steven Toth err = -ENODEV; 186d19770e5178a4bc49641711246360c25781d20a4Steven Toth 187d19770e5178a4bc49641711246360c25781d20a4Steven Toth /* dvb stuff */ 188d19770e5178a4bc49641711246360c25781d20a4Steven Toth printk("%s: cx23885 based dvb card\n", dev->name); 18944a6481dcd9ec835bbd608b1b2ee47ee62c7e1d8Michael Krufky videobuf_queue_init(&port->dvb.dvbq, &dvb_qops, dev->pci, &port->slock, 19044a6481dcd9ec835bbd608b1b2ee47ee62c7e1d8Michael Krufky V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_TOP, 19144a6481dcd9ec835bbd608b1b2ee47ee62c7e1d8Michael Krufky sizeof(struct cx23885_buffer), port); 192d19770e5178a4bc49641711246360c25781d20a4Steven Toth err = dvb_register(port); 193d19770e5178a4bc49641711246360c25781d20a4Steven Toth if (err != 0) 194d19770e5178a4bc49641711246360c25781d20a4Steven Toth printk("%s() dvb_register failed err = %d\n", __FUNCTION__, err); 195d19770e5178a4bc49641711246360c25781d20a4Steven Toth 196d19770e5178a4bc49641711246360c25781d20a4Steven Toth return err; 197d19770e5178a4bc49641711246360c25781d20a4Steven Toth} 198d19770e5178a4bc49641711246360c25781d20a4Steven Toth 199d19770e5178a4bc49641711246360c25781d20a4Steven Tothint cx23885_dvb_unregister(struct cx23885_tsport *port) 200d19770e5178a4bc49641711246360c25781d20a4Steven Toth{ 201d19770e5178a4bc49641711246360c25781d20a4Steven Toth /* dvb */ 202d19770e5178a4bc49641711246360c25781d20a4Steven Toth if(port->dvb.frontend) 203d19770e5178a4bc49641711246360c25781d20a4Steven Toth videobuf_dvb_unregister(&port->dvb); 204d19770e5178a4bc49641711246360c25781d20a4Steven Toth 205d19770e5178a4bc49641711246360c25781d20a4Steven Toth return 0; 206d19770e5178a4bc49641711246360c25781d20a4Steven Toth} 20744a6481dcd9ec835bbd608b1b2ee47ee62c7e1d8Michael Krufky 20844a6481dcd9ec835bbd608b1b2ee47ee62c7e1d8Michael Krufky/* 20944a6481dcd9ec835bbd608b1b2ee47ee62c7e1d8Michael Krufky * Local variables: 21044a6481dcd9ec835bbd608b1b2ee47ee62c7e1d8Michael Krufky * c-basic-offset: 8 21144a6481dcd9ec835bbd608b1b2ee47ee62c7e1d8Michael Krufky * End: 21244a6481dcd9ec835bbd608b1b2ee47ee62c7e1d8Michael Krufky * kate: eol "unix"; indent-width 3; remove-trailing-space on; replace-trailing-space-save on; tab-width 8; replace-tabs off; space-indent off; mixed-indent off 21344a6481dcd9ec835bbd608b1b2ee47ee62c7e1d8Michael Krufky*/ 214