cx23885-dvb.c revision b3ea01668907bdb32b0c690d28f9f2b1298bd258
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"
353ba71d2194500d1a9fef1b8491b9e0c168e7d46eMichael Krufky#include "tda8290.h"
364041f1a58774249f5f26163e68b844521ece1fb4Michael Krufky#include "tda18271.h"
379bc37caadffe8327683980b2323371691fa182e3Michael Krufky#include "lgdt330x.h"
38d1987d55a1eda774dfbab240a432607c17241d07Steven Toth#include "xc5000.h"
39b3ea01668907bdb32b0c690d28f9f2b1298bd258Steven Toth#include "tda10048.h"
409bc37caadffe8327683980b2323371691fa182e3Michael Krufky#include "dvb-pll.h"
4107b4a835d42d6d59e84cbafdc8b7090f97d7b67aMichael Krufky#include "tuner-xc2028.h"
4207b4a835d42d6d59e84cbafdc8b7090f97d7b67aMichael Krufky#include "tuner-xc2028-types.h"
43827855d39761889aecc7c29385d9c4989b43d01dMichael Krufky#include "tuner-simple.h"
44d19770e5178a4bc49641711246360c25781d20a4Steven Toth
454513fc696e273d64ea32f2366748aed810316eccSteven Tothstatic unsigned int debug;
46d19770e5178a4bc49641711246360c25781d20a4Steven Toth
474513fc696e273d64ea32f2366748aed810316eccSteven Toth#define dprintk(level, fmt, arg...)\
484513fc696e273d64ea32f2366748aed810316eccSteven Toth	do { if (debug >= level)\
494513fc696e273d64ea32f2366748aed810316eccSteven Toth		printk(KERN_DEBUG "%s/0: " fmt, dev->name, ## arg);\
504513fc696e273d64ea32f2366748aed810316eccSteven Toth	} while (0)
51d19770e5178a4bc49641711246360c25781d20a4Steven Toth
52d19770e5178a4bc49641711246360c25781d20a4Steven Toth/* ------------------------------------------------------------------ */
53d19770e5178a4bc49641711246360c25781d20a4Steven Toth
543ba71d2194500d1a9fef1b8491b9e0c168e7d46eMichael Krufkystatic unsigned int alt_tuner;
553ba71d2194500d1a9fef1b8491b9e0c168e7d46eMichael Krufkymodule_param(alt_tuner, int, 0644);
563ba71d2194500d1a9fef1b8491b9e0c168e7d46eMichael KrufkyMODULE_PARM_DESC(alt_tuner, "Enable alternate tuner configuration");
573ba71d2194500d1a9fef1b8491b9e0c168e7d46eMichael Krufky
5878e92006f410a4044f8c1760c25ac9d11d259aa2Janne GrunauDVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
5978e92006f410a4044f8c1760c25ac9d11d259aa2Janne Grunau
603ba71d2194500d1a9fef1b8491b9e0c168e7d46eMichael Krufky/* ------------------------------------------------------------------ */
613ba71d2194500d1a9fef1b8491b9e0c168e7d46eMichael Krufky
62d19770e5178a4bc49641711246360c25781d20a4Steven Tothstatic int dvb_buf_setup(struct videobuf_queue *q,
63d19770e5178a4bc49641711246360c25781d20a4Steven Toth			 unsigned int *count, unsigned int *size)
64d19770e5178a4bc49641711246360c25781d20a4Steven Toth{
65d19770e5178a4bc49641711246360c25781d20a4Steven Toth	struct cx23885_tsport *port = q->priv_data;
66d19770e5178a4bc49641711246360c25781d20a4Steven Toth
67d19770e5178a4bc49641711246360c25781d20a4Steven Toth	port->ts_packet_size  = 188 * 4;
68d19770e5178a4bc49641711246360c25781d20a4Steven Toth	port->ts_packet_count = 32;
69d19770e5178a4bc49641711246360c25781d20a4Steven Toth
70d19770e5178a4bc49641711246360c25781d20a4Steven Toth	*size  = port->ts_packet_size * port->ts_packet_count;
71d19770e5178a4bc49641711246360c25781d20a4Steven Toth	*count = 32;
72d19770e5178a4bc49641711246360c25781d20a4Steven Toth	return 0;
73d19770e5178a4bc49641711246360c25781d20a4Steven Toth}
74d19770e5178a4bc49641711246360c25781d20a4Steven Toth
7544a6481dcd9ec835bbd608b1b2ee47ee62c7e1d8Michael Krufkystatic int dvb_buf_prepare(struct videobuf_queue *q,
7644a6481dcd9ec835bbd608b1b2ee47ee62c7e1d8Michael Krufky			   struct videobuf_buffer *vb, enum v4l2_field field)
77d19770e5178a4bc49641711246360c25781d20a4Steven Toth{
78d19770e5178a4bc49641711246360c25781d20a4Steven Toth	struct cx23885_tsport *port = q->priv_data;
7944a6481dcd9ec835bbd608b1b2ee47ee62c7e1d8Michael Krufky	return cx23885_buf_prepare(q, port, (struct cx23885_buffer*)vb, field);
80d19770e5178a4bc49641711246360c25781d20a4Steven Toth}
81d19770e5178a4bc49641711246360c25781d20a4Steven Toth
82d19770e5178a4bc49641711246360c25781d20a4Steven Tothstatic void dvb_buf_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
83d19770e5178a4bc49641711246360c25781d20a4Steven Toth{
84d19770e5178a4bc49641711246360c25781d20a4Steven Toth	struct cx23885_tsport *port = q->priv_data;
85d19770e5178a4bc49641711246360c25781d20a4Steven Toth	cx23885_buf_queue(port, (struct cx23885_buffer*)vb);
86d19770e5178a4bc49641711246360c25781d20a4Steven Toth}
87d19770e5178a4bc49641711246360c25781d20a4Steven Toth
8844a6481dcd9ec835bbd608b1b2ee47ee62c7e1d8Michael Krufkystatic void dvb_buf_release(struct videobuf_queue *q,
8944a6481dcd9ec835bbd608b1b2ee47ee62c7e1d8Michael Krufky			    struct videobuf_buffer *vb)
90d19770e5178a4bc49641711246360c25781d20a4Steven Toth{
91d19770e5178a4bc49641711246360c25781d20a4Steven Toth	cx23885_free_buffer(q, (struct cx23885_buffer*)vb);
92d19770e5178a4bc49641711246360c25781d20a4Steven Toth}
93d19770e5178a4bc49641711246360c25781d20a4Steven Toth
94d19770e5178a4bc49641711246360c25781d20a4Steven Tothstatic struct videobuf_queue_ops dvb_qops = {
95d19770e5178a4bc49641711246360c25781d20a4Steven Toth	.buf_setup    = dvb_buf_setup,
96d19770e5178a4bc49641711246360c25781d20a4Steven Toth	.buf_prepare  = dvb_buf_prepare,
97d19770e5178a4bc49641711246360c25781d20a4Steven Toth	.buf_queue    = dvb_buf_queue,
98d19770e5178a4bc49641711246360c25781d20a4Steven Toth	.buf_release  = dvb_buf_release,
99d19770e5178a4bc49641711246360c25781d20a4Steven Toth};
100d19770e5178a4bc49641711246360c25781d20a4Steven Toth
10186184e06da4b71fc24ae9505ec60ce95c098d0deSteven Tothstatic struct s5h1409_config hauppauge_generic_config = {
102d19770e5178a4bc49641711246360c25781d20a4Steven Toth	.demod_address = 0x32 >> 1,
103d19770e5178a4bc49641711246360c25781d20a4Steven Toth	.output_mode   = S5H1409_SERIAL_OUTPUT,
104fc959befe0f0e4647bb4e326e3ae55875401888aSteven Toth	.gpio          = S5H1409_GPIO_ON,
1052b03238a79295aff30afc3d9a82afa617fd33971Michael Krufky	.qam_if        = 44000,
106fc959befe0f0e4647bb4e326e3ae55875401888aSteven Toth	.inversion     = S5H1409_INVERSION_OFF,
107dfc1c08aab447d49230dacb390d3f2263584d28fSteven Toth	.status_mode   = S5H1409_DEMODLOCKING,
108dfc1c08aab447d49230dacb390d3f2263584d28fSteven Toth	.mpeg_timing   = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK,
109fc959befe0f0e4647bb4e326e3ae55875401888aSteven Toth};
110fc959befe0f0e4647bb4e326e3ae55875401888aSteven Toth
111b3ea01668907bdb32b0c690d28f9f2b1298bd258Steven Tothstatic struct tda10048_config hauppauge_hvr1200_config = {
112b3ea01668907bdb32b0c690d28f9f2b1298bd258Steven Toth	.demod_address    = 0x10 >> 1,
113b3ea01668907bdb32b0c690d28f9f2b1298bd258Steven Toth	.output_mode      = TDA10048_SERIAL_OUTPUT,
114b3ea01668907bdb32b0c690d28f9f2b1298bd258Steven Toth	.fwbulkwritelen   = TDA10048_BULKWRITE_200,
115b3ea01668907bdb32b0c690d28f9f2b1298bd258Steven Toth	.inversion        = TDA10048_INVERSION_ON
116b3ea01668907bdb32b0c690d28f9f2b1298bd258Steven Toth};
117b3ea01668907bdb32b0c690d28f9f2b1298bd258Steven Toth
1183ba71d2194500d1a9fef1b8491b9e0c168e7d46eMichael Krufkystatic struct s5h1409_config hauppauge_ezqam_config = {
1193ba71d2194500d1a9fef1b8491b9e0c168e7d46eMichael Krufky	.demod_address = 0x32 >> 1,
1203ba71d2194500d1a9fef1b8491b9e0c168e7d46eMichael Krufky	.output_mode   = S5H1409_SERIAL_OUTPUT,
1213ba71d2194500d1a9fef1b8491b9e0c168e7d46eMichael Krufky	.gpio          = S5H1409_GPIO_OFF,
1223ba71d2194500d1a9fef1b8491b9e0c168e7d46eMichael Krufky	.qam_if        = 4000,
1233ba71d2194500d1a9fef1b8491b9e0c168e7d46eMichael Krufky	.inversion     = S5H1409_INVERSION_ON,
124dfc1c08aab447d49230dacb390d3f2263584d28fSteven Toth	.status_mode   = S5H1409_DEMODLOCKING,
125dfc1c08aab447d49230dacb390d3f2263584d28fSteven Toth	.mpeg_timing   = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK,
1263ba71d2194500d1a9fef1b8491b9e0c168e7d46eMichael Krufky};
1273ba71d2194500d1a9fef1b8491b9e0c168e7d46eMichael Krufky
128fc959befe0f0e4647bb4e326e3ae55875401888aSteven Tothstatic struct s5h1409_config hauppauge_hvr1800lp_config = {
129fc959befe0f0e4647bb4e326e3ae55875401888aSteven Toth	.demod_address = 0x32 >> 1,
130fc959befe0f0e4647bb4e326e3ae55875401888aSteven Toth	.output_mode   = S5H1409_SERIAL_OUTPUT,
131d19770e5178a4bc49641711246360c25781d20a4Steven Toth	.gpio          = S5H1409_GPIO_OFF,
1322b03238a79295aff30afc3d9a82afa617fd33971Michael Krufky	.qam_if        = 44000,
133fe475163ff9680495af3b1b5b7633ea7a42e4185Steven Toth	.inversion     = S5H1409_INVERSION_OFF,
134dfc1c08aab447d49230dacb390d3f2263584d28fSteven Toth	.status_mode   = S5H1409_DEMODLOCKING,
135dfc1c08aab447d49230dacb390d3f2263584d28fSteven Toth	.mpeg_timing   = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK,
136d19770e5178a4bc49641711246360c25781d20a4Steven Toth};
137d19770e5178a4bc49641711246360c25781d20a4Steven Toth
13807b4a835d42d6d59e84cbafdc8b7090f97d7b67aMichael Krufkystatic struct s5h1409_config hauppauge_hvr1500_config = {
13907b4a835d42d6d59e84cbafdc8b7090f97d7b67aMichael Krufky	.demod_address = 0x32 >> 1,
14007b4a835d42d6d59e84cbafdc8b7090f97d7b67aMichael Krufky	.output_mode   = S5H1409_SERIAL_OUTPUT,
14107b4a835d42d6d59e84cbafdc8b7090f97d7b67aMichael Krufky	.gpio          = S5H1409_GPIO_OFF,
14207b4a835d42d6d59e84cbafdc8b7090f97d7b67aMichael Krufky	.inversion     = S5H1409_INVERSION_OFF,
143dfc1c08aab447d49230dacb390d3f2263584d28fSteven Toth	.status_mode   = S5H1409_DEMODLOCKING,
144dfc1c08aab447d49230dacb390d3f2263584d28fSteven Toth	.mpeg_timing   = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK,
14507b4a835d42d6d59e84cbafdc8b7090f97d7b67aMichael Krufky};
14607b4a835d42d6d59e84cbafdc8b7090f97d7b67aMichael Krufky
14786184e06da4b71fc24ae9505ec60ce95c098d0deSteven Tothstatic struct mt2131_config hauppauge_generic_tunerconfig = {
148a77743bc2d29197d48a6f4ae9f8f9e0f0b0ba5d7Steven Toth	0x61
149a77743bc2d29197d48a6f4ae9f8f9e0f0b0ba5d7Steven Toth};
150a77743bc2d29197d48a6f4ae9f8f9e0f0b0ba5d7Steven Toth
1519bc37caadffe8327683980b2323371691fa182e3Michael Krufkystatic struct lgdt330x_config fusionhdtv_5_express = {
1529bc37caadffe8327683980b2323371691fa182e3Michael Krufky	.demod_address = 0x0e,
1539bc37caadffe8327683980b2323371691fa182e3Michael Krufky	.demod_chip = LGDT3303,
1549bc37caadffe8327683980b2323371691fa182e3Michael Krufky	.serial_mpeg = 0x40,
1559bc37caadffe8327683980b2323371691fa182e3Michael Krufky};
1569bc37caadffe8327683980b2323371691fa182e3Michael Krufky
157d1987d55a1eda774dfbab240a432607c17241d07Steven Tothstatic struct s5h1409_config hauppauge_hvr1500q_config = {
158d1987d55a1eda774dfbab240a432607c17241d07Steven Toth	.demod_address = 0x32 >> 1,
159d1987d55a1eda774dfbab240a432607c17241d07Steven Toth	.output_mode   = S5H1409_SERIAL_OUTPUT,
160d1987d55a1eda774dfbab240a432607c17241d07Steven Toth	.gpio          = S5H1409_GPIO_ON,
161d1987d55a1eda774dfbab240a432607c17241d07Steven Toth	.qam_if        = 44000,
162d1987d55a1eda774dfbab240a432607c17241d07Steven Toth	.inversion     = S5H1409_INVERSION_OFF,
163dfc1c08aab447d49230dacb390d3f2263584d28fSteven Toth	.status_mode   = S5H1409_DEMODLOCKING,
164dfc1c08aab447d49230dacb390d3f2263584d28fSteven Toth	.mpeg_timing   = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK,
165d1987d55a1eda774dfbab240a432607c17241d07Steven Toth};
166d1987d55a1eda774dfbab240a432607c17241d07Steven Toth
167d1987d55a1eda774dfbab240a432607c17241d07Steven Tothstatic struct xc5000_config hauppauge_hvr1500q_tunerconfig = {
168e12671cf0c3c8460dfa3ab945023803612827fb7Steven Toth	.i2c_address      = 0x61,
169e12671cf0c3c8460dfa3ab945023803612827fb7Steven Toth	.if_khz           = 5380,
1708c70017f5793e68ea48085a65008d713c9a85ddeSteven Toth	.tuner_callback   = cx23885_tuner_callback
171d1987d55a1eda774dfbab240a432607c17241d07Steven Toth};
172d1987d55a1eda774dfbab240a432607c17241d07Steven Toth
1734041f1a58774249f5f26163e68b844521ece1fb4Michael Krufkystatic struct tda829x_config tda829x_no_probe = {
1744041f1a58774249f5f26163e68b844521ece1fb4Michael Krufky	.probe_tuner = TDA829X_DONT_PROBE,
1754041f1a58774249f5f26163e68b844521ece1fb4Michael Krufky};
1764041f1a58774249f5f26163e68b844521ece1fb4Michael Krufky
177f21e0d7f0513e743b14df3197fdeeb9a9b7edbb2Michael Krufkystatic struct tda18271_std_map hauppauge_tda18271_std_map = {
178c0dc0c1122b585193dd6650c749e919542dd3e23Michael Krufky	.atsc_6   = { .if_freq = 5380, .agc_mode = 3, .std = 3,
179c0dc0c1122b585193dd6650c749e919542dd3e23Michael Krufky		      .if_lvl = 6, .rfagc_top = 0x37 },
180c0dc0c1122b585193dd6650c749e919542dd3e23Michael Krufky	.qam_6    = { .if_freq = 4000, .agc_mode = 3, .std = 0,
181c0dc0c1122b585193dd6650c749e919542dd3e23Michael Krufky		      .if_lvl = 6, .rfagc_top = 0x37 },
182f21e0d7f0513e743b14df3197fdeeb9a9b7edbb2Michael Krufky};
183f21e0d7f0513e743b14df3197fdeeb9a9b7edbb2Michael Krufky
184f21e0d7f0513e743b14df3197fdeeb9a9b7edbb2Michael Krufkystatic struct tda18271_config hauppauge_tda18271_config = {
185f21e0d7f0513e743b14df3197fdeeb9a9b7edbb2Michael Krufky	.std_map = &hauppauge_tda18271_std_map,
186f21e0d7f0513e743b14df3197fdeeb9a9b7edbb2Michael Krufky	.gate    = TDA18271_GATE_ANALOG,
187f21e0d7f0513e743b14df3197fdeeb9a9b7edbb2Michael Krufky};
188f21e0d7f0513e743b14df3197fdeeb9a9b7edbb2Michael Krufky
189b3ea01668907bdb32b0c690d28f9f2b1298bd258Steven Tothstatic struct tda18271_config hauppauge_hvr1200_tuner_config = {
190b3ea01668907bdb32b0c690d28f9f2b1298bd258Steven Toth	.gate    = TDA18271_GATE_ANALOG,
191b3ea01668907bdb32b0c690d28f9f2b1298bd258Steven Toth};
192b3ea01668907bdb32b0c690d28f9f2b1298bd258Steven Toth
19307b4a835d42d6d59e84cbafdc8b7090f97d7b67aMichael Krufkystatic int cx23885_hvr1500_xc3028_callback(void *ptr, int command, int arg)
19407b4a835d42d6d59e84cbafdc8b7090f97d7b67aMichael Krufky{
19507b4a835d42d6d59e84cbafdc8b7090f97d7b67aMichael Krufky	struct cx23885_tsport *port = ptr;
19607b4a835d42d6d59e84cbafdc8b7090f97d7b67aMichael Krufky	struct cx23885_dev *dev = port->dev;
19707b4a835d42d6d59e84cbafdc8b7090f97d7b67aMichael Krufky
19807b4a835d42d6d59e84cbafdc8b7090f97d7b67aMichael Krufky	switch (command) {
19907b4a835d42d6d59e84cbafdc8b7090f97d7b67aMichael Krufky	case XC2028_TUNER_RESET:
20007b4a835d42d6d59e84cbafdc8b7090f97d7b67aMichael Krufky		/* Send the tuner in then out of reset */
20107b4a835d42d6d59e84cbafdc8b7090f97d7b67aMichael Krufky		/* GPIO-2 xc3028 tuner */
20222b4e64f0a119e94090ef45285a5c311f1f6855fHarvey Harrison		dprintk(1, "%s: XC2028_TUNER_RESET %d\n", __func__, arg);
20307b4a835d42d6d59e84cbafdc8b7090f97d7b67aMichael Krufky
20407b4a835d42d6d59e84cbafdc8b7090f97d7b67aMichael Krufky		cx_set(GP0_IO, 0x00040000);
20507b4a835d42d6d59e84cbafdc8b7090f97d7b67aMichael Krufky		cx_clear(GP0_IO, 0x00000004);
20607b4a835d42d6d59e84cbafdc8b7090f97d7b67aMichael Krufky		msleep(5);
20707b4a835d42d6d59e84cbafdc8b7090f97d7b67aMichael Krufky
20807b4a835d42d6d59e84cbafdc8b7090f97d7b67aMichael Krufky		cx_set(GP0_IO, 0x00040004);
20907b4a835d42d6d59e84cbafdc8b7090f97d7b67aMichael Krufky		msleep(5);
21007b4a835d42d6d59e84cbafdc8b7090f97d7b67aMichael Krufky		break;
21107b4a835d42d6d59e84cbafdc8b7090f97d7b67aMichael Krufky	case XC2028_RESET_CLK:
21222b4e64f0a119e94090ef45285a5c311f1f6855fHarvey Harrison		dprintk(1, "%s: XC2028_RESET_CLK %d\n", __func__, arg);
21307b4a835d42d6d59e84cbafdc8b7090f97d7b67aMichael Krufky		break;
21407b4a835d42d6d59e84cbafdc8b7090f97d7b67aMichael Krufky	default:
21522b4e64f0a119e94090ef45285a5c311f1f6855fHarvey Harrison		dprintk(1, "%s: unknown command %d, arg %d\n", __func__,
21607b4a835d42d6d59e84cbafdc8b7090f97d7b67aMichael Krufky			command, arg);
21707b4a835d42d6d59e84cbafdc8b7090f97d7b67aMichael Krufky		return -EINVAL;
21807b4a835d42d6d59e84cbafdc8b7090f97d7b67aMichael Krufky	}
21907b4a835d42d6d59e84cbafdc8b7090f97d7b67aMichael Krufky
22007b4a835d42d6d59e84cbafdc8b7090f97d7b67aMichael Krufky	return 0;
22107b4a835d42d6d59e84cbafdc8b7090f97d7b67aMichael Krufky}
22207b4a835d42d6d59e84cbafdc8b7090f97d7b67aMichael Krufky
223d19770e5178a4bc49641711246360c25781d20a4Steven Tothstatic int dvb_register(struct cx23885_tsport *port)
224d19770e5178a4bc49641711246360c25781d20a4Steven Toth{
225d19770e5178a4bc49641711246360c25781d20a4Steven Toth	struct cx23885_dev *dev = port->dev;
226f139fa71c03d80c1d1ee60aa4b0a3ec7a14d45f9Michael Krufky	struct cx23885_i2c *i2c_bus = NULL;
227d19770e5178a4bc49641711246360c25781d20a4Steven Toth
228d19770e5178a4bc49641711246360c25781d20a4Steven Toth	/* init struct videobuf_dvb */
229d19770e5178a4bc49641711246360c25781d20a4Steven Toth	port->dvb.name = dev->name;
230d19770e5178a4bc49641711246360c25781d20a4Steven Toth
231d19770e5178a4bc49641711246360c25781d20a4Steven Toth	/* init frontend */
232d19770e5178a4bc49641711246360c25781d20a4Steven Toth	switch (dev->board) {
233a77743bc2d29197d48a6f4ae9f8f9e0f0b0ba5d7Steven Toth	case CX23885_BOARD_HAUPPAUGE_HVR1250:
234f139fa71c03d80c1d1ee60aa4b0a3ec7a14d45f9Michael Krufky		i2c_bus = &dev->i2c_bus[0];
235d19770e5178a4bc49641711246360c25781d20a4Steven Toth		port->dvb.frontend = dvb_attach(s5h1409_attach,
23686184e06da4b71fc24ae9505ec60ce95c098d0deSteven Toth						&hauppauge_generic_config,
237f139fa71c03d80c1d1ee60aa4b0a3ec7a14d45f9Michael Krufky						&i2c_bus->i2c_adap);
238d19770e5178a4bc49641711246360c25781d20a4Steven Toth		if (port->dvb.frontend != NULL) {
23944a6481dcd9ec835bbd608b1b2ee47ee62c7e1d8Michael Krufky			dvb_attach(mt2131_attach, port->dvb.frontend,
240f139fa71c03d80c1d1ee60aa4b0a3ec7a14d45f9Michael Krufky				   &i2c_bus->i2c_adap,
24186184e06da4b71fc24ae9505ec60ce95c098d0deSteven Toth				   &hauppauge_generic_tunerconfig, 0);
242d19770e5178a4bc49641711246360c25781d20a4Steven Toth		}
243d19770e5178a4bc49641711246360c25781d20a4Steven Toth		break;
2443ba71d2194500d1a9fef1b8491b9e0c168e7d46eMichael Krufky	case CX23885_BOARD_HAUPPAUGE_HVR1800:
2453ba71d2194500d1a9fef1b8491b9e0c168e7d46eMichael Krufky		i2c_bus = &dev->i2c_bus[0];
2463ba71d2194500d1a9fef1b8491b9e0c168e7d46eMichael Krufky		switch (alt_tuner) {
2473ba71d2194500d1a9fef1b8491b9e0c168e7d46eMichael Krufky		case 1:
2483ba71d2194500d1a9fef1b8491b9e0c168e7d46eMichael Krufky			port->dvb.frontend =
2493ba71d2194500d1a9fef1b8491b9e0c168e7d46eMichael Krufky				dvb_attach(s5h1409_attach,
2503ba71d2194500d1a9fef1b8491b9e0c168e7d46eMichael Krufky					   &hauppauge_ezqam_config,
2513ba71d2194500d1a9fef1b8491b9e0c168e7d46eMichael Krufky					   &i2c_bus->i2c_adap);
2523ba71d2194500d1a9fef1b8491b9e0c168e7d46eMichael Krufky			if (port->dvb.frontend != NULL) {
2533ba71d2194500d1a9fef1b8491b9e0c168e7d46eMichael Krufky				dvb_attach(tda829x_attach, port->dvb.frontend,
2543ba71d2194500d1a9fef1b8491b9e0c168e7d46eMichael Krufky					   &dev->i2c_bus[1].i2c_adap, 0x42,
2554041f1a58774249f5f26163e68b844521ece1fb4Michael Krufky					   &tda829x_no_probe);
2564041f1a58774249f5f26163e68b844521ece1fb4Michael Krufky				dvb_attach(tda18271_attach, port->dvb.frontend,
2574041f1a58774249f5f26163e68b844521ece1fb4Michael Krufky					   0x60, &dev->i2c_bus[1].i2c_adap,
258f21e0d7f0513e743b14df3197fdeeb9a9b7edbb2Michael Krufky					   &hauppauge_tda18271_config);
2593ba71d2194500d1a9fef1b8491b9e0c168e7d46eMichael Krufky			}
2603ba71d2194500d1a9fef1b8491b9e0c168e7d46eMichael Krufky			break;
2613ba71d2194500d1a9fef1b8491b9e0c168e7d46eMichael Krufky		case 0:
2623ba71d2194500d1a9fef1b8491b9e0c168e7d46eMichael Krufky		default:
2633ba71d2194500d1a9fef1b8491b9e0c168e7d46eMichael Krufky			port->dvb.frontend =
2643ba71d2194500d1a9fef1b8491b9e0c168e7d46eMichael Krufky				dvb_attach(s5h1409_attach,
2653ba71d2194500d1a9fef1b8491b9e0c168e7d46eMichael Krufky					   &hauppauge_generic_config,
2663ba71d2194500d1a9fef1b8491b9e0c168e7d46eMichael Krufky					   &i2c_bus->i2c_adap);
2673ba71d2194500d1a9fef1b8491b9e0c168e7d46eMichael Krufky			if (port->dvb.frontend != NULL)
2683ba71d2194500d1a9fef1b8491b9e0c168e7d46eMichael Krufky				dvb_attach(mt2131_attach, port->dvb.frontend,
2693ba71d2194500d1a9fef1b8491b9e0c168e7d46eMichael Krufky					   &i2c_bus->i2c_adap,
2703ba71d2194500d1a9fef1b8491b9e0c168e7d46eMichael Krufky					   &hauppauge_generic_tunerconfig, 0);
2713ba71d2194500d1a9fef1b8491b9e0c168e7d46eMichael Krufky			break;
2723ba71d2194500d1a9fef1b8491b9e0c168e7d46eMichael Krufky		}
2733ba71d2194500d1a9fef1b8491b9e0c168e7d46eMichael Krufky		break;
274fc959befe0f0e4647bb4e326e3ae55875401888aSteven Toth	case CX23885_BOARD_HAUPPAUGE_HVR1800lp:
275f139fa71c03d80c1d1ee60aa4b0a3ec7a14d45f9Michael Krufky		i2c_bus = &dev->i2c_bus[0];
276fc959befe0f0e4647bb4e326e3ae55875401888aSteven Toth		port->dvb.frontend = dvb_attach(s5h1409_attach,
277fc959befe0f0e4647bb4e326e3ae55875401888aSteven Toth						&hauppauge_hvr1800lp_config,
278f139fa71c03d80c1d1ee60aa4b0a3ec7a14d45f9Michael Krufky						&i2c_bus->i2c_adap);
279fc959befe0f0e4647bb4e326e3ae55875401888aSteven Toth		if (port->dvb.frontend != NULL) {
280fc959befe0f0e4647bb4e326e3ae55875401888aSteven Toth			dvb_attach(mt2131_attach, port->dvb.frontend,
281f139fa71c03d80c1d1ee60aa4b0a3ec7a14d45f9Michael Krufky				   &i2c_bus->i2c_adap,
282fc959befe0f0e4647bb4e326e3ae55875401888aSteven Toth				   &hauppauge_generic_tunerconfig, 0);
283fc959befe0f0e4647bb4e326e3ae55875401888aSteven Toth		}
284fc959befe0f0e4647bb4e326e3ae55875401888aSteven Toth		break;
2859bc37caadffe8327683980b2323371691fa182e3Michael Krufky	case CX23885_BOARD_DVICO_FUSIONHDTV_5_EXP:
286f139fa71c03d80c1d1ee60aa4b0a3ec7a14d45f9Michael Krufky		i2c_bus = &dev->i2c_bus[0];
2879bc37caadffe8327683980b2323371691fa182e3Michael Krufky		port->dvb.frontend = dvb_attach(lgdt330x_attach,
2889bc37caadffe8327683980b2323371691fa182e3Michael Krufky						&fusionhdtv_5_express,
289f139fa71c03d80c1d1ee60aa4b0a3ec7a14d45f9Michael Krufky						&i2c_bus->i2c_adap);
2909bc37caadffe8327683980b2323371691fa182e3Michael Krufky		if (port->dvb.frontend != NULL) {
291827855d39761889aecc7c29385d9c4989b43d01dMichael Krufky			dvb_attach(simple_tuner_attach, port->dvb.frontend,
292827855d39761889aecc7c29385d9c4989b43d01dMichael Krufky				   &i2c_bus->i2c_adap, 0x61,
293827855d39761889aecc7c29385d9c4989b43d01dMichael Krufky				   TUNER_LG_TDVS_H06XF);
2949bc37caadffe8327683980b2323371691fa182e3Michael Krufky		}
2959bc37caadffe8327683980b2323371691fa182e3Michael Krufky		break;
296d1987d55a1eda774dfbab240a432607c17241d07Steven Toth	case CX23885_BOARD_HAUPPAUGE_HVR1500Q:
297d1987d55a1eda774dfbab240a432607c17241d07Steven Toth		i2c_bus = &dev->i2c_bus[1];
298d1987d55a1eda774dfbab240a432607c17241d07Steven Toth		port->dvb.frontend = dvb_attach(s5h1409_attach,
299d1987d55a1eda774dfbab240a432607c17241d07Steven Toth						&hauppauge_hvr1500q_config,
300d1987d55a1eda774dfbab240a432607c17241d07Steven Toth						&dev->i2c_bus[0].i2c_adap);
301d1987d55a1eda774dfbab240a432607c17241d07Steven Toth		if (port->dvb.frontend != NULL) {
30273c993a8294077ae1b724286da8ac323c25d90dbSteven Toth			hauppauge_hvr1500q_tunerconfig.priv = i2c_bus;
303d1987d55a1eda774dfbab240a432607c17241d07Steven Toth			dvb_attach(xc5000_attach, port->dvb.frontend,
304d1987d55a1eda774dfbab240a432607c17241d07Steven Toth				&i2c_bus->i2c_adap,
305d1987d55a1eda774dfbab240a432607c17241d07Steven Toth				&hauppauge_hvr1500q_tunerconfig);
306d1987d55a1eda774dfbab240a432607c17241d07Steven Toth		}
307d1987d55a1eda774dfbab240a432607c17241d07Steven Toth		break;
30807b4a835d42d6d59e84cbafdc8b7090f97d7b67aMichael Krufky	case CX23885_BOARD_HAUPPAUGE_HVR1500:
30907b4a835d42d6d59e84cbafdc8b7090f97d7b67aMichael Krufky		i2c_bus = &dev->i2c_bus[1];
31007b4a835d42d6d59e84cbafdc8b7090f97d7b67aMichael Krufky		port->dvb.frontend = dvb_attach(s5h1409_attach,
31107b4a835d42d6d59e84cbafdc8b7090f97d7b67aMichael Krufky						&hauppauge_hvr1500_config,
31207b4a835d42d6d59e84cbafdc8b7090f97d7b67aMichael Krufky						&dev->i2c_bus[0].i2c_adap);
31307b4a835d42d6d59e84cbafdc8b7090f97d7b67aMichael Krufky		if (port->dvb.frontend != NULL) {
31407b4a835d42d6d59e84cbafdc8b7090f97d7b67aMichael Krufky			struct dvb_frontend *fe;
31507b4a835d42d6d59e84cbafdc8b7090f97d7b67aMichael Krufky			struct xc2028_config cfg = {
31607b4a835d42d6d59e84cbafdc8b7090f97d7b67aMichael Krufky				.i2c_adap  = &i2c_bus->i2c_adap,
31707b4a835d42d6d59e84cbafdc8b7090f97d7b67aMichael Krufky				.i2c_addr  = 0x61,
31807b4a835d42d6d59e84cbafdc8b7090f97d7b67aMichael Krufky				.callback  = cx23885_hvr1500_xc3028_callback,
31907b4a835d42d6d59e84cbafdc8b7090f97d7b67aMichael Krufky			};
32007b4a835d42d6d59e84cbafdc8b7090f97d7b67aMichael Krufky			static struct xc2028_ctrl ctl = {
32107b4a835d42d6d59e84cbafdc8b7090f97d7b67aMichael Krufky				.fname       = "xc3028-v27.fw",
32207b4a835d42d6d59e84cbafdc8b7090f97d7b67aMichael Krufky				.max_len     = 64,
32307b4a835d42d6d59e84cbafdc8b7090f97d7b67aMichael Krufky				.scode_table = OREN538,
32407b4a835d42d6d59e84cbafdc8b7090f97d7b67aMichael Krufky			};
32507b4a835d42d6d59e84cbafdc8b7090f97d7b67aMichael Krufky
32607b4a835d42d6d59e84cbafdc8b7090f97d7b67aMichael Krufky			fe = dvb_attach(xc2028_attach,
32707b4a835d42d6d59e84cbafdc8b7090f97d7b67aMichael Krufky					port->dvb.frontend, &cfg);
32807b4a835d42d6d59e84cbafdc8b7090f97d7b67aMichael Krufky			if (fe != NULL && fe->ops.tuner_ops.set_config != NULL)
32907b4a835d42d6d59e84cbafdc8b7090f97d7b67aMichael Krufky				fe->ops.tuner_ops.set_config(fe, &ctl);
33007b4a835d42d6d59e84cbafdc8b7090f97d7b67aMichael Krufky		}
33107b4a835d42d6d59e84cbafdc8b7090f97d7b67aMichael Krufky		break;
332b3ea01668907bdb32b0c690d28f9f2b1298bd258Steven Toth	case CX23885_BOARD_HAUPPAUGE_HVR1200:
333b3ea01668907bdb32b0c690d28f9f2b1298bd258Steven Toth		i2c_bus = &dev->i2c_bus[0];
334b3ea01668907bdb32b0c690d28f9f2b1298bd258Steven Toth		port->dvb.frontend = dvb_attach(tda10048_attach,
335b3ea01668907bdb32b0c690d28f9f2b1298bd258Steven Toth			&hauppauge_hvr1200_config,
336b3ea01668907bdb32b0c690d28f9f2b1298bd258Steven Toth			&i2c_bus->i2c_adap);
337b3ea01668907bdb32b0c690d28f9f2b1298bd258Steven Toth		if (port->dvb.frontend != NULL) {
338b3ea01668907bdb32b0c690d28f9f2b1298bd258Steven Toth			dvb_attach(tda829x_attach, port->dvb.frontend,
339b3ea01668907bdb32b0c690d28f9f2b1298bd258Steven Toth				&dev->i2c_bus[1].i2c_adap, 0x42,
340b3ea01668907bdb32b0c690d28f9f2b1298bd258Steven Toth				&tda829x_no_probe);
341b3ea01668907bdb32b0c690d28f9f2b1298bd258Steven Toth			dvb_attach(tda18271_attach, port->dvb.frontend,
342b3ea01668907bdb32b0c690d28f9f2b1298bd258Steven Toth				0x60, &dev->i2c_bus[1].i2c_adap,
343b3ea01668907bdb32b0c690d28f9f2b1298bd258Steven Toth				&hauppauge_hvr1200_tuner_config);
344b3ea01668907bdb32b0c690d28f9f2b1298bd258Steven Toth		}
345b3ea01668907bdb32b0c690d28f9f2b1298bd258Steven Toth		break;
346d19770e5178a4bc49641711246360c25781d20a4Steven Toth	default:
347d19770e5178a4bc49641711246360c25781d20a4Steven Toth		printk("%s: The frontend of your DVB/ATSC card isn't supported yet\n",
348d19770e5178a4bc49641711246360c25781d20a4Steven Toth		       dev->name);
349d19770e5178a4bc49641711246360c25781d20a4Steven Toth		break;
350d19770e5178a4bc49641711246360c25781d20a4Steven Toth	}
351d19770e5178a4bc49641711246360c25781d20a4Steven Toth	if (NULL == port->dvb.frontend) {
352d19770e5178a4bc49641711246360c25781d20a4Steven Toth		printk("%s: frontend initialization failed\n", dev->name);
353d19770e5178a4bc49641711246360c25781d20a4Steven Toth		return -1;
354d19770e5178a4bc49641711246360c25781d20a4Steven Toth	}
355d19770e5178a4bc49641711246360c25781d20a4Steven Toth
356d19770e5178a4bc49641711246360c25781d20a4Steven Toth	/* Put the analog decoder in standby to keep it quiet */
357f139fa71c03d80c1d1ee60aa4b0a3ec7a14d45f9Michael Krufky	cx23885_call_i2c_clients(i2c_bus, TUNER_SET_STANDBY, NULL);
358d19770e5178a4bc49641711246360c25781d20a4Steven Toth
3593ba71d2194500d1a9fef1b8491b9e0c168e7d46eMichael Krufky	if (port->dvb.frontend->ops.analog_ops.standby)
3603ba71d2194500d1a9fef1b8491b9e0c168e7d46eMichael Krufky		port->dvb.frontend->ops.analog_ops.standby(port->dvb.frontend);
3613ba71d2194500d1a9fef1b8491b9e0c168e7d46eMichael Krufky
362d19770e5178a4bc49641711246360c25781d20a4Steven Toth	/* register everything */
36344a6481dcd9ec835bbd608b1b2ee47ee62c7e1d8Michael Krufky	return videobuf_dvb_register(&port->dvb, THIS_MODULE, port,
36478e92006f410a4044f8c1760c25ac9d11d259aa2Janne Grunau				     &dev->pci->dev, adapter_nr);
365d19770e5178a4bc49641711246360c25781d20a4Steven Toth}
366d19770e5178a4bc49641711246360c25781d20a4Steven Toth
367d19770e5178a4bc49641711246360c25781d20a4Steven Tothint cx23885_dvb_register(struct cx23885_tsport *port)
368d19770e5178a4bc49641711246360c25781d20a4Steven Toth{
369d19770e5178a4bc49641711246360c25781d20a4Steven Toth	struct cx23885_dev *dev = port->dev;
370d19770e5178a4bc49641711246360c25781d20a4Steven Toth	int err;
371d19770e5178a4bc49641711246360c25781d20a4Steven Toth
37222b4e64f0a119e94090ef45285a5c311f1f6855fHarvey Harrison	dprintk(1, "%s\n", __func__);
37344a6481dcd9ec835bbd608b1b2ee47ee62c7e1d8Michael Krufky	dprintk(1, " ->being probed by Card=%d Name=%s, PCI %02x:%02x\n",
374d19770e5178a4bc49641711246360c25781d20a4Steven Toth		dev->board,
375d19770e5178a4bc49641711246360c25781d20a4Steven Toth		dev->name,
376d19770e5178a4bc49641711246360c25781d20a4Steven Toth		dev->pci_bus,
377d19770e5178a4bc49641711246360c25781d20a4Steven Toth		dev->pci_slot);
378d19770e5178a4bc49641711246360c25781d20a4Steven Toth
379d19770e5178a4bc49641711246360c25781d20a4Steven Toth	err = -ENODEV;
380d19770e5178a4bc49641711246360c25781d20a4Steven Toth
381d19770e5178a4bc49641711246360c25781d20a4Steven Toth	/* dvb stuff */
382d19770e5178a4bc49641711246360c25781d20a4Steven Toth	printk("%s: cx23885 based dvb card\n", dev->name);
3830705135e59f8503e4dade4b3580fed77b1743b7cGuennadi Liakhovetski	videobuf_queue_sg_init(&port->dvb.dvbq, &dvb_qops, &dev->pci->dev, &port->slock,
38444a6481dcd9ec835bbd608b1b2ee47ee62c7e1d8Michael Krufky			    V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_TOP,
38544a6481dcd9ec835bbd608b1b2ee47ee62c7e1d8Michael Krufky			    sizeof(struct cx23885_buffer), port);
386d19770e5178a4bc49641711246360c25781d20a4Steven Toth	err = dvb_register(port);
387d19770e5178a4bc49641711246360c25781d20a4Steven Toth	if (err != 0)
38822b4e64f0a119e94090ef45285a5c311f1f6855fHarvey Harrison		printk("%s() dvb_register failed err = %d\n", __func__, err);
389d19770e5178a4bc49641711246360c25781d20a4Steven Toth
390d19770e5178a4bc49641711246360c25781d20a4Steven Toth	return err;
391d19770e5178a4bc49641711246360c25781d20a4Steven Toth}
392d19770e5178a4bc49641711246360c25781d20a4Steven Toth
393d19770e5178a4bc49641711246360c25781d20a4Steven Tothint cx23885_dvb_unregister(struct cx23885_tsport *port)
394d19770e5178a4bc49641711246360c25781d20a4Steven Toth{
395d19770e5178a4bc49641711246360c25781d20a4Steven Toth	/* dvb */
396d19770e5178a4bc49641711246360c25781d20a4Steven Toth	if(port->dvb.frontend)
397d19770e5178a4bc49641711246360c25781d20a4Steven Toth		videobuf_dvb_unregister(&port->dvb);
398d19770e5178a4bc49641711246360c25781d20a4Steven Toth
399d19770e5178a4bc49641711246360c25781d20a4Steven Toth	return 0;
400d19770e5178a4bc49641711246360c25781d20a4Steven Toth}
40144a6481dcd9ec835bbd608b1b2ee47ee62c7e1d8Michael Krufky
40244a6481dcd9ec835bbd608b1b2ee47ee62c7e1d8Michael Krufky/*
40344a6481dcd9ec835bbd608b1b2ee47ee62c7e1d8Michael Krufky * Local variables:
40444a6481dcd9ec835bbd608b1b2ee47ee62c7e1d8Michael Krufky * c-basic-offset: 8
40544a6481dcd9ec835bbd608b1b2ee47ee62c7e1d8Michael Krufky * End:
40644a6481dcd9ec835bbd608b1b2ee47ee62c7e1d8Michael 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
40744a6481dcd9ec835bbd608b1b2ee47ee62c7e1d8Michael Krufky*/
408