Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
budget-av.c
Go to the documentation of this file.
1 /*
2  * budget-av.c: driver for the SAA7146 based Budget DVB cards
3  * with analog video in
4  *
5  * Compiled from various sources by Michael Hunold <[email protected]>
6  *
7  * CI interface support (c) 2004 Olivier Gournet <[email protected]> &
8  * Andrew de Quincey <[email protected]>
9  *
10  * Copyright (C) 2002 Ralph Metzler <[email protected]>
11  *
12  * Copyright (C) 1999-2002 Ralph Metzler
13  * & Marcus Metzler for convergence integrated media GmbH
14  *
15  * This program is free software; you can redistribute it and/or
16  * modify it under the terms of the GNU General Public License
17  * as published by the Free Software Foundation; either version 2
18  * of the License, or (at your option) any later version.
19  *
20  *
21  * This program is distributed in the hope that it will be useful,
22  * but WITHOUT ANY WARRANTY; without even the implied warranty of
23  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24  * GNU General Public License for more details.
25  *
26  *
27  * You should have received a copy of the GNU General Public License
28  * along with this program; if not, write to the Free Software
29  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
30  * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
31  *
32  *
33  * the project's page is at http://www.linuxtv.org/
34  */
35 
36 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
37 
38 #include "budget.h"
39 #include "stv0299.h"
40 #include "stb0899_drv.h"
41 #include "stb0899_reg.h"
42 #include "stb0899_cfg.h"
43 #include "tda8261.h"
44 #include "tda8261_cfg.h"
45 #include "tda1002x.h"
46 #include "tda1004x.h"
47 #include "tua6100.h"
48 #include "dvb-pll.h"
49 #include <media/saa7146_vv.h>
50 #include <linux/module.h>
51 #include <linux/errno.h>
52 #include <linux/slab.h>
53 #include <linux/interrupt.h>
54 #include <linux/input.h>
55 #include <linux/spinlock.h>
56 
57 #include "dvb_ca_en50221.h"
58 
59 #define DEBICICAM 0x02420000
60 
61 #define SLOTSTATUS_NONE 1
62 #define SLOTSTATUS_PRESENT 2
63 #define SLOTSTATUS_RESET 4
64 #define SLOTSTATUS_READY 8
65 #define SLOTSTATUS_OCCUPIED (SLOTSTATUS_PRESENT|SLOTSTATUS_RESET|SLOTSTATUS_READY)
66 
68 
69 struct budget_av {
70  struct budget budget;
71  struct video_device *vd;
72  int cur_input;
78 };
79 
80 static int ciintf_slot_shutdown(struct dvb_ca_en50221 *ca, int slot);
81 
82 
83 /* GPIO Connections:
84  * 0 - Vcc/Reset (Reset is controlled by capacitor). Resets the frontend *AS WELL*!
85  * 1 - CI memory select 0=>IO memory, 1=>Attribute Memory
86  * 2 - CI Card Enable (Active Low)
87  * 3 - CI Card Detect
88  */
89 
90 /****************************************************************************
91  * INITIALIZATION
92  ****************************************************************************/
93 
94 static u8 i2c_readreg(struct i2c_adapter *i2c, u8 id, u8 reg)
95 {
96  u8 mm1[] = { 0x00 };
97  u8 mm2[] = { 0x00 };
98  struct i2c_msg msgs[2];
99 
100  msgs[0].flags = 0;
101  msgs[1].flags = I2C_M_RD;
102  msgs[0].addr = msgs[1].addr = id / 2;
103  mm1[0] = reg;
104  msgs[0].len = 1;
105  msgs[1].len = 1;
106  msgs[0].buf = mm1;
107  msgs[1].buf = mm2;
108 
109  i2c_transfer(i2c, msgs, 2);
110 
111  return mm2[0];
112 }
113 
114 static int i2c_readregs(struct i2c_adapter *i2c, u8 id, u8 reg, u8 * buf, u8 len)
115 {
116  u8 mm1[] = { reg };
117  struct i2c_msg msgs[2] = {
118  {.addr = id / 2,.flags = 0,.buf = mm1,.len = 1},
119  {.addr = id / 2,.flags = I2C_M_RD,.buf = buf,.len = len}
120  };
121 
122  if (i2c_transfer(i2c, msgs, 2) != 2)
123  return -EIO;
124 
125  return 0;
126 }
127 
128 static int i2c_writereg(struct i2c_adapter *i2c, u8 id, u8 reg, u8 val)
129 {
130  u8 msg[2] = { reg, val };
131  struct i2c_msg msgs;
132 
133  msgs.flags = 0;
134  msgs.addr = id / 2;
135  msgs.len = 2;
136  msgs.buf = msg;
137  return i2c_transfer(i2c, &msgs, 1);
138 }
139 
140 static int ciintf_read_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int address)
141 {
142  struct budget_av *budget_av = (struct budget_av *) ca->data;
143  int result;
144 
145  if (slot != 0)
146  return -EINVAL;
147 
148  saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTHI);
149  udelay(1);
150 
151  result = ttpci_budget_debiread(&budget_av->budget, DEBICICAM, address & 0xfff, 1, 0, 1);
152  if (result == -ETIMEDOUT) {
153  ciintf_slot_shutdown(ca, slot);
154  pr_info("cam ejected 1\n");
155  }
156  return result;
157 }
158 
159 static int ciintf_write_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int address, u8 value)
160 {
161  struct budget_av *budget_av = (struct budget_av *) ca->data;
162  int result;
163 
164  if (slot != 0)
165  return -EINVAL;
166 
167  saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTHI);
168  udelay(1);
169 
170  result = ttpci_budget_debiwrite(&budget_av->budget, DEBICICAM, address & 0xfff, 1, value, 0, 1);
171  if (result == -ETIMEDOUT) {
172  ciintf_slot_shutdown(ca, slot);
173  pr_info("cam ejected 2\n");
174  }
175  return result;
176 }
177 
178 static int ciintf_read_cam_control(struct dvb_ca_en50221 *ca, int slot, u8 address)
179 {
180  struct budget_av *budget_av = (struct budget_av *) ca->data;
181  int result;
182 
183  if (slot != 0)
184  return -EINVAL;
185 
186  saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTLO);
187  udelay(1);
188 
189  result = ttpci_budget_debiread(&budget_av->budget, DEBICICAM, address & 3, 1, 0, 0);
190  if (result == -ETIMEDOUT) {
191  ciintf_slot_shutdown(ca, slot);
192  pr_info("cam ejected 3\n");
193  return -ETIMEDOUT;
194  }
195  return result;
196 }
197 
198 static int ciintf_write_cam_control(struct dvb_ca_en50221 *ca, int slot, u8 address, u8 value)
199 {
200  struct budget_av *budget_av = (struct budget_av *) ca->data;
201  int result;
202 
203  if (slot != 0)
204  return -EINVAL;
205 
206  saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTLO);
207  udelay(1);
208 
209  result = ttpci_budget_debiwrite(&budget_av->budget, DEBICICAM, address & 3, 1, value, 0, 0);
210  if (result == -ETIMEDOUT) {
211  ciintf_slot_shutdown(ca, slot);
212  pr_info("cam ejected 5\n");
213  }
214  return result;
215 }
216 
217 static int ciintf_slot_reset(struct dvb_ca_en50221 *ca, int slot)
218 {
219  struct budget_av *budget_av = (struct budget_av *) ca->data;
220  struct saa7146_dev *saa = budget_av->budget.dev;
221 
222  if (slot != 0)
223  return -EINVAL;
224 
225  dprintk(1, "ciintf_slot_reset\n");
226  budget_av->slot_status = SLOTSTATUS_RESET;
227 
228  saa7146_setgpio(saa, 2, SAA7146_GPIO_OUTHI); /* disable card */
229 
230  saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTHI); /* Vcc off */
231  msleep(2);
232  saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTLO); /* Vcc on */
233  msleep(20); /* 20 ms Vcc settling time */
234 
235  saa7146_setgpio(saa, 2, SAA7146_GPIO_OUTLO); /* enable card */
237  msleep(20);
238 
239  /* reinitialise the frontend if necessary */
240  if (budget_av->reinitialise_demod)
241  dvb_frontend_reinitialise(budget_av->budget.dvb_frontend);
242 
243  return 0;
244 }
245 
246 static int ciintf_slot_shutdown(struct dvb_ca_en50221 *ca, int slot)
247 {
248  struct budget_av *budget_av = (struct budget_av *) ca->data;
249  struct saa7146_dev *saa = budget_av->budget.dev;
250 
251  if (slot != 0)
252  return -EINVAL;
253 
254  dprintk(1, "ciintf_slot_shutdown\n");
255 
257  budget_av->slot_status = SLOTSTATUS_NONE;
258 
259  return 0;
260 }
261 
262 static int ciintf_slot_ts_enable(struct dvb_ca_en50221 *ca, int slot)
263 {
264  struct budget_av *budget_av = (struct budget_av *) ca->data;
265  struct saa7146_dev *saa = budget_av->budget.dev;
266 
267  if (slot != 0)
268  return -EINVAL;
269 
270  dprintk(1, "ciintf_slot_ts_enable: %d\n", budget_av->slot_status);
271 
273 
274  return 0;
275 }
276 
277 static int ciintf_poll_slot_status(struct dvb_ca_en50221 *ca, int slot, int open)
278 {
279  struct budget_av *budget_av = (struct budget_av *) ca->data;
280  struct saa7146_dev *saa = budget_av->budget.dev;
281  int result;
282 
283  if (slot != 0)
284  return -EINVAL;
285 
286  /* test the card detect line - needs to be done carefully
287  * since it never goes high for some CAMs on this interface (e.g. topuptv) */
288  if (budget_av->slot_status == SLOTSTATUS_NONE) {
290  udelay(1);
291  if (saa7146_read(saa, PSR) & MASK_06) {
292  if (budget_av->slot_status == SLOTSTATUS_NONE) {
293  budget_av->slot_status = SLOTSTATUS_PRESENT;
294  pr_info("cam inserted A\n");
295  }
296  }
298  }
299 
300  /* We also try and read from IO memory to work round the above detection bug. If
301  * there is no CAM, we will get a timeout. Only done if there is no cam
302  * present, since this test actually breaks some cams :(
303  *
304  * if the CI interface is not open, we also do the above test since we
305  * don't care if the cam has problems - we'll be resetting it on open() anyway */
306  if ((budget_av->slot_status == SLOTSTATUS_NONE) || (!open)) {
307  saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTLO);
308  result = ttpci_budget_debiread(&budget_av->budget, DEBICICAM, 0, 1, 0, 1);
309  if ((result >= 0) && (budget_av->slot_status == SLOTSTATUS_NONE)) {
310  budget_av->slot_status = SLOTSTATUS_PRESENT;
311  pr_info("cam inserted B\n");
312  } else if (result < 0) {
313  if (budget_av->slot_status != SLOTSTATUS_NONE) {
314  ciintf_slot_shutdown(ca, slot);
315  pr_info("cam ejected 5\n");
316  return 0;
317  }
318  }
319  }
320 
321  /* read from attribute memory in reset/ready state to know when the CAM is ready */
322  if (budget_av->slot_status == SLOTSTATUS_RESET) {
323  result = ciintf_read_attribute_mem(ca, slot, 0);
324  if (result == 0x1d) {
325  budget_av->slot_status = SLOTSTATUS_READY;
326  }
327  }
328 
329  /* work out correct return code */
330  if (budget_av->slot_status != SLOTSTATUS_NONE) {
331  if (budget_av->slot_status & SLOTSTATUS_READY) {
333  }
335  }
336  return 0;
337 }
338 
339 static int ciintf_init(struct budget_av *budget_av)
340 {
341  struct saa7146_dev *saa = budget_av->budget.dev;
342  int result;
343 
344  memset(&budget_av->ca, 0, sizeof(struct dvb_ca_en50221));
345 
350 
351  /* Enable DEBI pins */
352  saa7146_write(saa, MC1, MASK_27 | MASK_11);
353 
354  /* register CI interface */
355  budget_av->ca.owner = THIS_MODULE;
356  budget_av->ca.read_attribute_mem = ciintf_read_attribute_mem;
357  budget_av->ca.write_attribute_mem = ciintf_write_attribute_mem;
358  budget_av->ca.read_cam_control = ciintf_read_cam_control;
359  budget_av->ca.write_cam_control = ciintf_write_cam_control;
360  budget_av->ca.slot_reset = ciintf_slot_reset;
361  budget_av->ca.slot_shutdown = ciintf_slot_shutdown;
362  budget_av->ca.slot_ts_enable = ciintf_slot_ts_enable;
363  budget_av->ca.poll_slot_status = ciintf_poll_slot_status;
364  budget_av->ca.data = budget_av;
365  budget_av->budget.ci_present = 1;
366  budget_av->slot_status = SLOTSTATUS_NONE;
367 
368  if ((result = dvb_ca_en50221_init(&budget_av->budget.dvb_adapter,
369  &budget_av->ca, 0, 1)) != 0) {
370  pr_err("ci initialisation failed\n");
371  goto error;
372  }
373 
374  pr_info("ci interface initialised\n");
375  return 0;
376 
377 error:
378  saa7146_write(saa, MC1, MASK_27);
379  return result;
380 }
381 
382 static void ciintf_deinit(struct budget_av *budget_av)
383 {
384  struct saa7146_dev *saa = budget_av->budget.dev;
385 
390 
391  /* release the CA device */
392  dvb_ca_en50221_release(&budget_av->ca);
393 
394  /* disable DEBI pins */
395  saa7146_write(saa, MC1, MASK_27);
396 }
397 
398 
399 static const u8 saa7113_tab[] = {
400  0x01, 0x08,
401  0x02, 0xc0,
402  0x03, 0x33,
403  0x04, 0x00,
404  0x05, 0x00,
405  0x06, 0xeb,
406  0x07, 0xe0,
407  0x08, 0x28,
408  0x09, 0x00,
409  0x0a, 0x80,
410  0x0b, 0x47,
411  0x0c, 0x40,
412  0x0d, 0x00,
413  0x0e, 0x01,
414  0x0f, 0x44,
415 
416  0x10, 0x08,
417  0x11, 0x0c,
418  0x12, 0x7b,
419  0x13, 0x00,
420  0x15, 0x00, 0x16, 0x00, 0x17, 0x00,
421 
422  0x57, 0xff,
423  0x40, 0x82, 0x58, 0x00, 0x59, 0x54, 0x5a, 0x07,
424  0x5b, 0x83, 0x5e, 0x00,
425  0xff
426 };
427 
428 static int saa7113_init(struct budget_av *budget_av)
429 {
430  struct budget *budget = &budget_av->budget;
431  struct saa7146_dev *saa = budget->dev;
432  const u8 *data = saa7113_tab;
433 
435  msleep(200);
436 
437  if (i2c_writereg(&budget->i2c_adap, 0x4a, 0x01, 0x08) != 1) {
438  dprintk(1, "saa7113 not found on KNC card\n");
439  return -ENODEV;
440  }
441 
442  dprintk(1, "saa7113 detected and initializing\n");
443 
444  while (*data != 0xff) {
445  i2c_writereg(&budget->i2c_adap, 0x4a, *data, *(data + 1));
446  data += 2;
447  }
448 
449  dprintk(1, "saa7113 status=%02x\n", i2c_readreg(&budget->i2c_adap, 0x4a, 0x1f));
450 
451  return 0;
452 }
453 
454 static int saa7113_setinput(struct budget_av *budget_av, int input)
455 {
456  struct budget *budget = &budget_av->budget;
457 
458  if (1 != budget_av->has_saa7113)
459  return -ENODEV;
460 
461  if (input == 1) {
462  i2c_writereg(&budget->i2c_adap, 0x4a, 0x02, 0xc7);
463  i2c_writereg(&budget->i2c_adap, 0x4a, 0x09, 0x80);
464  } else if (input == 0) {
465  i2c_writereg(&budget->i2c_adap, 0x4a, 0x02, 0xc0);
466  i2c_writereg(&budget->i2c_adap, 0x4a, 0x09, 0x00);
467  } else
468  return -EINVAL;
469 
470  budget_av->cur_input = input;
471  return 0;
472 }
473 
474 
475 static int philips_su1278_ty_ci_set_symbol_rate(struct dvb_frontend *fe, u32 srate, u32 ratio)
476 {
477  u8 aclk = 0;
478  u8 bclk = 0;
479  u8 m1;
480 
481  aclk = 0xb5;
482  if (srate < 2000000)
483  bclk = 0x86;
484  else if (srate < 5000000)
485  bclk = 0x89;
486  else if (srate < 15000000)
487  bclk = 0x8f;
488  else if (srate < 45000000)
489  bclk = 0x95;
490 
491  m1 = 0x14;
492  if (srate < 4000000)
493  m1 = 0x10;
494 
495  stv0299_writereg(fe, 0x13, aclk);
496  stv0299_writereg(fe, 0x14, bclk);
497  stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff);
498  stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff);
499  stv0299_writereg(fe, 0x21, (ratio) & 0xf0);
500  stv0299_writereg(fe, 0x0f, 0x80 | m1);
501 
502  return 0;
503 }
504 
505 static int philips_su1278_ty_ci_tuner_set_params(struct dvb_frontend *fe)
506 {
508  u32 div;
509  u8 buf[4];
510  struct budget *budget = (struct budget *) fe->dvb->priv;
511  struct i2c_msg msg = {.addr = 0x61,.flags = 0,.buf = buf,.len = sizeof(buf) };
512 
513  if ((c->frequency < 950000) || (c->frequency > 2150000))
514  return -EINVAL;
515 
516  div = (c->frequency + (125 - 1)) / 125; /* round correctly */
517  buf[0] = (div >> 8) & 0x7f;
518  buf[1] = div & 0xff;
519  buf[2] = 0x80 | ((div & 0x18000) >> 10) | 4;
520  buf[3] = 0x20;
521 
522  if (c->symbol_rate < 4000000)
523  buf[3] |= 1;
524 
525  if (c->frequency < 1250000)
526  buf[3] |= 0;
527  else if (c->frequency < 1550000)
528  buf[3] |= 0x40;
529  else if (c->frequency < 2050000)
530  buf[3] |= 0x80;
531  else if (c->frequency < 2150000)
532  buf[3] |= 0xC0;
533 
534  if (fe->ops.i2c_gate_ctrl)
535  fe->ops.i2c_gate_ctrl(fe, 1);
536  if (i2c_transfer(&budget->i2c_adap, &msg, 1) != 1)
537  return -EIO;
538  return 0;
539 }
540 
541 static u8 typhoon_cinergy1200s_inittab[] = {
542  0x01, 0x15,
543  0x02, 0x30,
544  0x03, 0x00,
545  0x04, 0x7d, /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */
546  0x05, 0x35, /* I2CT = 0, SCLT = 1, SDAT = 1 */
547  0x06, 0x40, /* DAC not used, set to high impendance mode */
548  0x07, 0x00, /* DAC LSB */
549  0x08, 0x40, /* DiSEqC off */
550  0x09, 0x00, /* FIFO */
551  0x0c, 0x51, /* OP1 ctl = Normal, OP1 val = 1 (LNB Power ON) */
552  0x0d, 0x82, /* DC offset compensation = ON, beta_agc1 = 2 */
553  0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */
554  0x10, 0x3f, // AGC2 0x3d
555  0x11, 0x84,
556  0x12, 0xb9,
557  0x15, 0xc9, // lock detector threshold
558  0x16, 0x00,
559  0x17, 0x00,
560  0x18, 0x00,
561  0x19, 0x00,
562  0x1a, 0x00,
563  0x1f, 0x50,
564  0x20, 0x00,
565  0x21, 0x00,
566  0x22, 0x00,
567  0x23, 0x00,
568  0x28, 0x00, // out imp: normal out type: parallel FEC mode:0
569  0x29, 0x1e, // 1/2 threshold
570  0x2a, 0x14, // 2/3 threshold
571  0x2b, 0x0f, // 3/4 threshold
572  0x2c, 0x09, // 5/6 threshold
573  0x2d, 0x05, // 7/8 threshold
574  0x2e, 0x01,
575  0x31, 0x1f, // test all FECs
576  0x32, 0x19, // viterbi and synchro search
577  0x33, 0xfc, // rs control
578  0x34, 0x93, // error control
579  0x0f, 0x92,
580  0xff, 0xff
581 };
582 
583 static struct stv0299_config typhoon_config = {
584  .demod_address = 0x68,
585  .inittab = typhoon_cinergy1200s_inittab,
586  .mclk = 88000000UL,
587  .invert = 0,
588  .skip_reinit = 0,
589  .lock_output = STV0299_LOCKOUTPUT_1,
590  .volt13_op0_op1 = STV0299_VOLT13_OP0,
591  .min_delay_ms = 100,
592  .set_symbol_rate = philips_su1278_ty_ci_set_symbol_rate,
593 };
594 
595 
596 static struct stv0299_config cinergy_1200s_config = {
597  .demod_address = 0x68,
598  .inittab = typhoon_cinergy1200s_inittab,
599  .mclk = 88000000UL,
600  .invert = 0,
601  .skip_reinit = 0,
602  .lock_output = STV0299_LOCKOUTPUT_0,
603  .volt13_op0_op1 = STV0299_VOLT13_OP0,
604  .min_delay_ms = 100,
605  .set_symbol_rate = philips_su1278_ty_ci_set_symbol_rate,
606 };
607 
608 static struct stv0299_config cinergy_1200s_1894_0010_config = {
609  .demod_address = 0x68,
610  .inittab = typhoon_cinergy1200s_inittab,
611  .mclk = 88000000UL,
612  .invert = 1,
613  .skip_reinit = 0,
614  .lock_output = STV0299_LOCKOUTPUT_1,
615  .volt13_op0_op1 = STV0299_VOLT13_OP0,
616  .min_delay_ms = 100,
617  .set_symbol_rate = philips_su1278_ty_ci_set_symbol_rate,
618 };
619 
620 static int philips_cu1216_tuner_set_params(struct dvb_frontend *fe)
621 {
623  struct budget *budget = (struct budget *) fe->dvb->priv;
624  u8 buf[6];
625  struct i2c_msg msg = {.addr = 0x60,.flags = 0,.buf = buf,.len = sizeof(buf) };
626  int i;
627 
628 #define CU1216_IF 36125000
629 #define TUNER_MUL 62500
630 
631  u32 div = (c->frequency + CU1216_IF + TUNER_MUL / 2) / TUNER_MUL;
632 
633  buf[0] = (div >> 8) & 0x7f;
634  buf[1] = div & 0xff;
635  buf[2] = 0xce;
636  buf[3] = (c->frequency < 150000000 ? 0x01 :
637  c->frequency < 445000000 ? 0x02 : 0x04);
638  buf[4] = 0xde;
639  buf[5] = 0x20;
640 
641  if (fe->ops.i2c_gate_ctrl)
642  fe->ops.i2c_gate_ctrl(fe, 1);
643  if (i2c_transfer(&budget->i2c_adap, &msg, 1) != 1)
644  return -EIO;
645 
646  /* wait for the pll lock */
647  msg.flags = I2C_M_RD;
648  msg.len = 1;
649  for (i = 0; i < 20; i++) {
650  if (fe->ops.i2c_gate_ctrl)
651  fe->ops.i2c_gate_ctrl(fe, 1);
652  if (i2c_transfer(&budget->i2c_adap, &msg, 1) == 1 && (buf[0] & 0x40))
653  break;
654  msleep(10);
655  }
656 
657  /* switch the charge pump to the lower current */
658  msg.flags = 0;
659  msg.len = 2;
660  msg.buf = &buf[2];
661  buf[2] &= ~0x40;
662  if (fe->ops.i2c_gate_ctrl)
663  fe->ops.i2c_gate_ctrl(fe, 1);
664  if (i2c_transfer(&budget->i2c_adap, &msg, 1) != 1)
665  return -EIO;
666 
667  return 0;
668 }
669 
670 static struct tda1002x_config philips_cu1216_config = {
671  .demod_address = 0x0c,
672  .invert = 1,
673 };
674 
675 static struct tda1002x_config philips_cu1216_config_altaddress = {
676  .demod_address = 0x0d,
677  .invert = 0,
678 };
679 
680 static struct tda10023_config philips_cu1216_tda10023_config = {
681  .demod_address = 0x0c,
682  .invert = 1,
683 };
684 
685 static int philips_tu1216_tuner_init(struct dvb_frontend *fe)
686 {
687  struct budget *budget = (struct budget *) fe->dvb->priv;
688  static u8 tu1216_init[] = { 0x0b, 0xf5, 0x85, 0xab };
689  struct i2c_msg tuner_msg = {.addr = 0x60,.flags = 0,.buf = tu1216_init,.len = sizeof(tu1216_init) };
690 
691  // setup PLL configuration
692  if (fe->ops.i2c_gate_ctrl)
693  fe->ops.i2c_gate_ctrl(fe, 1);
694  if (i2c_transfer(&budget->i2c_adap, &tuner_msg, 1) != 1)
695  return -EIO;
696  msleep(1);
697 
698  return 0;
699 }
700 
701 static int philips_tu1216_tuner_set_params(struct dvb_frontend *fe)
702 {
704  struct budget *budget = (struct budget *) fe->dvb->priv;
705  u8 tuner_buf[4];
706  struct i2c_msg tuner_msg = {.addr = 0x60,.flags = 0,.buf = tuner_buf,.len =
707  sizeof(tuner_buf) };
708  int tuner_frequency = 0;
709  u8 band, cp, filter;
710 
711  // determine charge pump
712  tuner_frequency = c->frequency + 36166000;
713  if (tuner_frequency < 87000000)
714  return -EINVAL;
715  else if (tuner_frequency < 130000000)
716  cp = 3;
717  else if (tuner_frequency < 160000000)
718  cp = 5;
719  else if (tuner_frequency < 200000000)
720  cp = 6;
721  else if (tuner_frequency < 290000000)
722  cp = 3;
723  else if (tuner_frequency < 420000000)
724  cp = 5;
725  else if (tuner_frequency < 480000000)
726  cp = 6;
727  else if (tuner_frequency < 620000000)
728  cp = 3;
729  else if (tuner_frequency < 830000000)
730  cp = 5;
731  else if (tuner_frequency < 895000000)
732  cp = 7;
733  else
734  return -EINVAL;
735 
736  // determine band
737  if (c->frequency < 49000000)
738  return -EINVAL;
739  else if (c->frequency < 161000000)
740  band = 1;
741  else if (c->frequency < 444000000)
742  band = 2;
743  else if (c->frequency < 861000000)
744  band = 4;
745  else
746  return -EINVAL;
747 
748  // setup PLL filter
749  switch (c->bandwidth_hz) {
750  case 6000000:
751  filter = 0;
752  break;
753 
754  case 7000000:
755  filter = 0;
756  break;
757 
758  case 8000000:
759  filter = 1;
760  break;
761 
762  default:
763  return -EINVAL;
764  }
765 
766  // calculate divisor
767  // ((36166000+((1000000/6)/2)) + Finput)/(1000000/6)
768  tuner_frequency = (((c->frequency / 1000) * 6) + 217496) / 1000;
769 
770  // setup tuner buffer
771  tuner_buf[0] = (tuner_frequency >> 8) & 0x7f;
772  tuner_buf[1] = tuner_frequency & 0xff;
773  tuner_buf[2] = 0xca;
774  tuner_buf[3] = (cp << 5) | (filter << 3) | band;
775 
776  if (fe->ops.i2c_gate_ctrl)
777  fe->ops.i2c_gate_ctrl(fe, 1);
778  if (i2c_transfer(&budget->i2c_adap, &tuner_msg, 1) != 1)
779  return -EIO;
780 
781  msleep(1);
782  return 0;
783 }
784 
785 static int philips_tu1216_request_firmware(struct dvb_frontend *fe,
786  const struct firmware **fw, char *name)
787 {
788  struct budget *budget = (struct budget *) fe->dvb->priv;
789 
790  return request_firmware(fw, name, &budget->dev->pci->dev);
791 }
792 
793 static struct tda1004x_config philips_tu1216_config = {
794 
795  .demod_address = 0x8,
796  .invert = 1,
797  .invert_oclk = 1,
798  .xtal_freq = TDA10046_XTAL_4M,
799  .agc_config = TDA10046_AGC_DEFAULT,
800  .if_freq = TDA10046_FREQ_3617,
801  .request_firmware = philips_tu1216_request_firmware,
802 };
803 
804 static u8 philips_sd1878_inittab[] = {
805  0x01, 0x15,
806  0x02, 0x30,
807  0x03, 0x00,
808  0x04, 0x7d,
809  0x05, 0x35,
810  0x06, 0x40,
811  0x07, 0x00,
812  0x08, 0x43,
813  0x09, 0x02,
814  0x0C, 0x51,
815  0x0D, 0x82,
816  0x0E, 0x23,
817  0x10, 0x3f,
818  0x11, 0x84,
819  0x12, 0xb9,
820  0x15, 0xc9,
821  0x16, 0x19,
822  0x17, 0x8c,
823  0x18, 0x59,
824  0x19, 0xf8,
825  0x1a, 0xfe,
826  0x1c, 0x7f,
827  0x1d, 0x00,
828  0x1e, 0x00,
829  0x1f, 0x50,
830  0x20, 0x00,
831  0x21, 0x00,
832  0x22, 0x00,
833  0x23, 0x00,
834  0x28, 0x00,
835  0x29, 0x28,
836  0x2a, 0x14,
837  0x2b, 0x0f,
838  0x2c, 0x09,
839  0x2d, 0x09,
840  0x31, 0x1f,
841  0x32, 0x19,
842  0x33, 0xfc,
843  0x34, 0x93,
844  0xff, 0xff
845 };
846 
847 static int philips_sd1878_ci_set_symbol_rate(struct dvb_frontend *fe,
848  u32 srate, u32 ratio)
849 {
850  u8 aclk = 0;
851  u8 bclk = 0;
852  u8 m1;
853 
854  aclk = 0xb5;
855  if (srate < 2000000)
856  bclk = 0x86;
857  else if (srate < 5000000)
858  bclk = 0x89;
859  else if (srate < 15000000)
860  bclk = 0x8f;
861  else if (srate < 45000000)
862  bclk = 0x95;
863 
864  m1 = 0x14;
865  if (srate < 4000000)
866  m1 = 0x10;
867 
868  stv0299_writereg(fe, 0x0e, 0x23);
869  stv0299_writereg(fe, 0x0f, 0x94);
870  stv0299_writereg(fe, 0x10, 0x39);
871  stv0299_writereg(fe, 0x13, aclk);
872  stv0299_writereg(fe, 0x14, bclk);
873  stv0299_writereg(fe, 0x15, 0xc9);
874  stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff);
875  stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff);
876  stv0299_writereg(fe, 0x21, (ratio) & 0xf0);
877  stv0299_writereg(fe, 0x0f, 0x80 | m1);
878 
879  return 0;
880 }
881 
882 static struct stv0299_config philips_sd1878_config = {
883  .demod_address = 0x68,
884  .inittab = philips_sd1878_inittab,
885  .mclk = 88000000UL,
886  .invert = 0,
887  .skip_reinit = 0,
888  .lock_output = STV0299_LOCKOUTPUT_1,
889  .volt13_op0_op1 = STV0299_VOLT13_OP0,
890  .min_delay_ms = 100,
891  .set_symbol_rate = philips_sd1878_ci_set_symbol_rate,
892 };
893 
894 /* KNC1 DVB-S (STB0899) Inittab */
895 static const struct stb0899_s1_reg knc1_stb0899_s1_init_1[] = {
896 
897  { STB0899_DEV_ID , 0x81 },
898  { STB0899_DISCNTRL1 , 0x32 },
899  { STB0899_DISCNTRL2 , 0x80 },
900  { STB0899_DISRX_ST0 , 0x04 },
901  { STB0899_DISRX_ST1 , 0x00 },
902  { STB0899_DISPARITY , 0x00 },
903  { STB0899_DISSTATUS , 0x20 },
904  { STB0899_DISF22 , 0x8c },
905  { STB0899_DISF22RX , 0x9a },
906  { STB0899_SYSREG , 0x0b },
907  { STB0899_ACRPRESC , 0x11 },
908  { STB0899_ACRDIV1 , 0x0a },
909  { STB0899_ACRDIV2 , 0x05 },
910  { STB0899_DACR1 , 0x00 },
911  { STB0899_DACR2 , 0x00 },
912  { STB0899_OUTCFG , 0x00 },
913  { STB0899_MODECFG , 0x00 },
914  { STB0899_IRQSTATUS_3 , 0x30 },
915  { STB0899_IRQSTATUS_2 , 0x00 },
916  { STB0899_IRQSTATUS_1 , 0x00 },
917  { STB0899_IRQSTATUS_0 , 0x00 },
918  { STB0899_IRQMSK_3 , 0xf3 },
919  { STB0899_IRQMSK_2 , 0xfc },
920  { STB0899_IRQMSK_1 , 0xff },
921  { STB0899_IRQMSK_0 , 0xff },
922  { STB0899_IRQCFG , 0x00 },
923  { STB0899_I2CCFG , 0x88 },
924  { STB0899_I2CRPT , 0x58 }, /* Repeater=8, Stop=disabled */
925  { STB0899_IOPVALUE5 , 0x00 },
926  { STB0899_IOPVALUE4 , 0x20 },
927  { STB0899_IOPVALUE3 , 0xc9 },
928  { STB0899_IOPVALUE2 , 0x90 },
929  { STB0899_IOPVALUE1 , 0x40 },
930  { STB0899_IOPVALUE0 , 0x00 },
931  { STB0899_GPIO00CFG , 0x82 },
932  { STB0899_GPIO01CFG , 0x82 },
933  { STB0899_GPIO02CFG , 0x82 },
934  { STB0899_GPIO03CFG , 0x82 },
935  { STB0899_GPIO04CFG , 0x82 },
936  { STB0899_GPIO05CFG , 0x82 },
937  { STB0899_GPIO06CFG , 0x82 },
938  { STB0899_GPIO07CFG , 0x82 },
939  { STB0899_GPIO08CFG , 0x82 },
940  { STB0899_GPIO09CFG , 0x82 },
941  { STB0899_GPIO10CFG , 0x82 },
942  { STB0899_GPIO11CFG , 0x82 },
943  { STB0899_GPIO12CFG , 0x82 },
944  { STB0899_GPIO13CFG , 0x82 },
945  { STB0899_GPIO14CFG , 0x82 },
946  { STB0899_GPIO15CFG , 0x82 },
947  { STB0899_GPIO16CFG , 0x82 },
948  { STB0899_GPIO17CFG , 0x82 },
949  { STB0899_GPIO18CFG , 0x82 },
950  { STB0899_GPIO19CFG , 0x82 },
951  { STB0899_GPIO20CFG , 0x82 },
952  { STB0899_SDATCFG , 0xb8 },
953  { STB0899_SCLTCFG , 0xba },
954  { STB0899_AGCRFCFG , 0x08 }, /* 0x1c */
955  { STB0899_GPIO22 , 0x82 }, /* AGCBB2CFG */
956  { STB0899_GPIO21 , 0x91 }, /* AGCBB1CFG */
957  { STB0899_DIRCLKCFG , 0x82 },
958  { STB0899_CLKOUT27CFG , 0x7e },
959  { STB0899_STDBYCFG , 0x82 },
960  { STB0899_CS0CFG , 0x82 },
961  { STB0899_CS1CFG , 0x82 },
962  { STB0899_DISEQCOCFG , 0x20 },
963  { STB0899_GPIO32CFG , 0x82 },
964  { STB0899_GPIO33CFG , 0x82 },
965  { STB0899_GPIO34CFG , 0x82 },
966  { STB0899_GPIO35CFG , 0x82 },
967  { STB0899_GPIO36CFG , 0x82 },
968  { STB0899_GPIO37CFG , 0x82 },
969  { STB0899_GPIO38CFG , 0x82 },
970  { STB0899_GPIO39CFG , 0x82 },
971  { STB0899_NCOARSE , 0x15 }, /* 0x15 = 27 Mhz Clock, F/3 = 198MHz, F/6 = 99MHz */
972  { STB0899_SYNTCTRL , 0x02 }, /* 0x00 = CLK from CLKI, 0x02 = CLK from XTALI */
973  { STB0899_FILTCTRL , 0x00 },
974  { STB0899_SYSCTRL , 0x00 },
975  { STB0899_STOPCLK1 , 0x20 },
976  { STB0899_STOPCLK2 , 0x00 },
977  { STB0899_INTBUFSTATUS , 0x00 },
978  { STB0899_INTBUFCTRL , 0x0a },
979  { 0xffff , 0xff },
980 };
981 
982 static const struct stb0899_s1_reg knc1_stb0899_s1_init_3[] = {
983  { STB0899_DEMOD , 0x00 },
984  { STB0899_RCOMPC , 0xc9 },
985  { STB0899_AGC1CN , 0x41 },
986  { STB0899_AGC1REF , 0x08 },
987  { STB0899_RTC , 0x7a },
988  { STB0899_TMGCFG , 0x4e },
989  { STB0899_AGC2REF , 0x33 },
990  { STB0899_TLSR , 0x84 },
991  { STB0899_CFD , 0xee },
992  { STB0899_ACLC , 0x87 },
993  { STB0899_BCLC , 0x94 },
994  { STB0899_EQON , 0x41 },
995  { STB0899_LDT , 0xdd },
996  { STB0899_LDT2 , 0xc9 },
997  { STB0899_EQUALREF , 0xb4 },
998  { STB0899_TMGRAMP , 0x10 },
999  { STB0899_TMGTHD , 0x30 },
1000  { STB0899_IDCCOMP , 0xfb },
1001  { STB0899_QDCCOMP , 0x03 },
1002  { STB0899_POWERI , 0x3b },
1003  { STB0899_POWERQ , 0x3d },
1004  { STB0899_RCOMP , 0x81 },
1005  { STB0899_AGCIQIN , 0x80 },
1006  { STB0899_AGC2I1 , 0x04 },
1007  { STB0899_AGC2I2 , 0xf5 },
1008  { STB0899_TLIR , 0x25 },
1009  { STB0899_RTF , 0x80 },
1010  { STB0899_DSTATUS , 0x00 },
1011  { STB0899_LDI , 0xca },
1012  { STB0899_CFRM , 0xf1 },
1013  { STB0899_CFRL , 0xf3 },
1014  { STB0899_NIRM , 0x2a },
1015  { STB0899_NIRL , 0x05 },
1016  { STB0899_ISYMB , 0x17 },
1017  { STB0899_QSYMB , 0xfa },
1018  { STB0899_SFRH , 0x2f },
1019  { STB0899_SFRM , 0x68 },
1020  { STB0899_SFRL , 0x40 },
1021  { STB0899_SFRUPH , 0x2f },
1022  { STB0899_SFRUPM , 0x68 },
1023  { STB0899_SFRUPL , 0x40 },
1024  { STB0899_EQUAI1 , 0xfd },
1025  { STB0899_EQUAQ1 , 0x04 },
1026  { STB0899_EQUAI2 , 0x0f },
1027  { STB0899_EQUAQ2 , 0xff },
1028  { STB0899_EQUAI3 , 0xdf },
1029  { STB0899_EQUAQ3 , 0xfa },
1030  { STB0899_EQUAI4 , 0x37 },
1031  { STB0899_EQUAQ4 , 0x0d },
1032  { STB0899_EQUAI5 , 0xbd },
1033  { STB0899_EQUAQ5 , 0xf7 },
1034  { STB0899_DSTATUS2 , 0x00 },
1035  { STB0899_VSTATUS , 0x00 },
1036  { STB0899_VERROR , 0xff },
1037  { STB0899_IQSWAP , 0x2a },
1038  { STB0899_ECNT1M , 0x00 },
1039  { STB0899_ECNT1L , 0x00 },
1040  { STB0899_ECNT2M , 0x00 },
1041  { STB0899_ECNT2L , 0x00 },
1042  { STB0899_ECNT3M , 0x00 },
1043  { STB0899_ECNT3L , 0x00 },
1044  { STB0899_FECAUTO1 , 0x06 },
1045  { STB0899_FECM , 0x01 },
1046  { STB0899_VTH12 , 0xf0 },
1047  { STB0899_VTH23 , 0xa0 },
1048  { STB0899_VTH34 , 0x78 },
1049  { STB0899_VTH56 , 0x4e },
1050  { STB0899_VTH67 , 0x48 },
1051  { STB0899_VTH78 , 0x38 },
1052  { STB0899_PRVIT , 0xff },
1053  { STB0899_VITSYNC , 0x19 },
1054  { STB0899_RSULC , 0xb1 }, /* DVB = 0xb1, DSS = 0xa1 */
1055  { STB0899_TSULC , 0x42 },
1056  { STB0899_RSLLC , 0x40 },
1057  { STB0899_TSLPL , 0x12 },
1058  { STB0899_TSCFGH , 0x0c },
1059  { STB0899_TSCFGM , 0x00 },
1060  { STB0899_TSCFGL , 0x0c },
1061  { STB0899_TSOUT , 0x4d }, /* 0x0d for CAM */
1062  { STB0899_RSSYNCDEL , 0x00 },
1063  { STB0899_TSINHDELH , 0x02 },
1064  { STB0899_TSINHDELM , 0x00 },
1065  { STB0899_TSINHDELL , 0x00 },
1066  { STB0899_TSLLSTKM , 0x00 },
1067  { STB0899_TSLLSTKL , 0x00 },
1068  { STB0899_TSULSTKM , 0x00 },
1069  { STB0899_TSULSTKL , 0xab },
1070  { STB0899_PCKLENUL , 0x00 },
1071  { STB0899_PCKLENLL , 0xcc },
1072  { STB0899_RSPCKLEN , 0xcc },
1073  { STB0899_TSSTATUS , 0x80 },
1074  { STB0899_ERRCTRL1 , 0xb6 },
1075  { STB0899_ERRCTRL2 , 0x96 },
1076  { STB0899_ERRCTRL3 , 0x89 },
1077  { STB0899_DMONMSK1 , 0x27 },
1078  { STB0899_DMONMSK0 , 0x03 },
1079  { STB0899_DEMAPVIT , 0x5c },
1080  { STB0899_PLPARM , 0x1f },
1081  { STB0899_PDELCTRL , 0x48 },
1082  { STB0899_PDELCTRL2 , 0x00 },
1083  { STB0899_BBHCTRL1 , 0x00 },
1084  { STB0899_BBHCTRL2 , 0x00 },
1085  { STB0899_HYSTTHRESH , 0x77 },
1086  { STB0899_MATCSTM , 0x00 },
1087  { STB0899_MATCSTL , 0x00 },
1088  { STB0899_UPLCSTM , 0x00 },
1089  { STB0899_UPLCSTL , 0x00 },
1090  { STB0899_DFLCSTM , 0x00 },
1091  { STB0899_DFLCSTL , 0x00 },
1092  { STB0899_SYNCCST , 0x00 },
1093  { STB0899_SYNCDCSTM , 0x00 },
1094  { STB0899_SYNCDCSTL , 0x00 },
1095  { STB0899_ISI_ENTRY , 0x00 },
1096  { STB0899_ISI_BIT_EN , 0x00 },
1097  { STB0899_MATSTRM , 0x00 },
1098  { STB0899_MATSTRL , 0x00 },
1099  { STB0899_UPLSTRM , 0x00 },
1100  { STB0899_UPLSTRL , 0x00 },
1101  { STB0899_DFLSTRM , 0x00 },
1102  { STB0899_DFLSTRL , 0x00 },
1103  { STB0899_SYNCSTR , 0x00 },
1104  { STB0899_SYNCDSTRM , 0x00 },
1105  { STB0899_SYNCDSTRL , 0x00 },
1106  { STB0899_CFGPDELSTATUS1 , 0x10 },
1107  { STB0899_CFGPDELSTATUS2 , 0x00 },
1108  { STB0899_BBFERRORM , 0x00 },
1109  { STB0899_BBFERRORL , 0x00 },
1110  { STB0899_UPKTERRORM , 0x00 },
1111  { STB0899_UPKTERRORL , 0x00 },
1112  { 0xffff , 0xff },
1113 };
1114 
1115 /* STB0899 demodulator config for the KNC1 and clones */
1116 static struct stb0899_config knc1_dvbs2_config = {
1117  .init_dev = knc1_stb0899_s1_init_1,
1118  .init_s2_demod = stb0899_s2_init_2,
1119  .init_s1_demod = knc1_stb0899_s1_init_3,
1120  .init_s2_fec = stb0899_s2_init_4,
1121  .init_tst = stb0899_s1_init_5,
1122 
1123  .postproc = NULL,
1124 
1125  .demod_address = 0x68,
1126 // .ts_output_mode = STB0899_OUT_PARALLEL, /* types = SERIAL/PARALLEL */
1127  .block_sync_mode = STB0899_SYNC_FORCED, /* DSS, SYNC_FORCED/UNSYNCED */
1128 // .ts_pfbit_toggle = STB0899_MPEG_NORMAL, /* DirecTV, MPEG toggling seq */
1129 
1130  .xtal_freq = 27000000,
1131  .inversion = IQ_SWAP_OFF, /* 1 */
1132 
1133  .lo_clk = 76500000,
1134  .hi_clk = 90000000,
1135 
1136  .esno_ave = STB0899_DVBS2_ESNO_AVE,
1137  .esno_quant = STB0899_DVBS2_ESNO_QUANT,
1138  .avframes_coarse = STB0899_DVBS2_AVFRAMES_COARSE,
1139  .avframes_fine = STB0899_DVBS2_AVFRAMES_FINE,
1140  .miss_threshold = STB0899_DVBS2_MISS_THRESHOLD,
1141  .uwp_threshold_acq = STB0899_DVBS2_UWP_THRESHOLD_ACQ,
1142  .uwp_threshold_track = STB0899_DVBS2_UWP_THRESHOLD_TRACK,
1143  .uwp_threshold_sof = STB0899_DVBS2_UWP_THRESHOLD_SOF,
1144  .sof_search_timeout = STB0899_DVBS2_SOF_SEARCH_TIMEOUT,
1145 
1146  .btr_nco_bits = STB0899_DVBS2_BTR_NCO_BITS,
1147  .btr_gain_shift_offset = STB0899_DVBS2_BTR_GAIN_SHIFT_OFFSET,
1148  .crl_nco_bits = STB0899_DVBS2_CRL_NCO_BITS,
1149  .ldpc_max_iter = STB0899_DVBS2_LDPC_MAX_ITER,
1150 
1151  .tuner_get_frequency = tda8261_get_frequency,
1152  .tuner_set_frequency = tda8261_set_frequency,
1153  .tuner_set_bandwidth = NULL,
1154  .tuner_get_bandwidth = tda8261_get_bandwidth,
1155  .tuner_set_rfsiggain = NULL
1156 };
1157 
1158 /*
1159  * SD1878/SHA tuner config
1160  * 1F, Single I/P, Horizontal mount, High Sensitivity
1161  */
1162 static const struct tda8261_config sd1878c_config = {
1163 // .name = "SD1878/SHA",
1164  .addr = 0x60,
1165  .step_size = TDA8261_STEP_1000 /* kHz */
1166 };
1167 
1168 static u8 read_pwm(struct budget_av *budget_av)
1169 {
1170  u8 b = 0xff;
1171  u8 pwm;
1172  struct i2c_msg msg[] = { {.addr = 0x50,.flags = 0,.buf = &b,.len = 1},
1173  {.addr = 0x50,.flags = I2C_M_RD,.buf = &pwm,.len = 1}
1174  };
1175 
1176  if ((i2c_transfer(&budget_av->budget.i2c_adap, msg, 2) != 2)
1177  || (pwm == 0xff))
1178  pwm = 0x48;
1179 
1180  return pwm;
1181 }
1182 
1183 #define SUBID_DVBS_KNC1 0x0010
1184 #define SUBID_DVBS_KNC1_PLUS 0x0011
1185 #define SUBID_DVBS_TYPHOON 0x4f56
1186 #define SUBID_DVBS_CINERGY1200 0x1154
1187 #define SUBID_DVBS_CYNERGY1200N 0x1155
1188 #define SUBID_DVBS_TV_STAR 0x0014
1189 #define SUBID_DVBS_TV_STAR_PLUS_X4 0x0015
1190 #define SUBID_DVBS_TV_STAR_CI 0x0016
1191 #define SUBID_DVBS2_KNC1 0x0018
1192 #define SUBID_DVBS2_KNC1_OEM 0x0019
1193 #define SUBID_DVBS_EASYWATCH_1 0x001a
1194 #define SUBID_DVBS_EASYWATCH_2 0x001b
1195 #define SUBID_DVBS2_EASYWATCH 0x001d
1196 #define SUBID_DVBS_EASYWATCH 0x001e
1197 
1198 #define SUBID_DVBC_EASYWATCH 0x002a
1199 #define SUBID_DVBC_EASYWATCH_MK3 0x002c
1200 #define SUBID_DVBC_KNC1 0x0020
1201 #define SUBID_DVBC_KNC1_PLUS 0x0021
1202 #define SUBID_DVBC_KNC1_MK3 0x0022
1203 #define SUBID_DVBC_KNC1_TDA10024 0x0028
1204 #define SUBID_DVBC_KNC1_PLUS_MK3 0x0023
1205 #define SUBID_DVBC_CINERGY1200 0x1156
1206 #define SUBID_DVBC_CINERGY1200_MK3 0x1176
1207 
1208 #define SUBID_DVBT_EASYWATCH 0x003a
1209 #define SUBID_DVBT_KNC1_PLUS 0x0031
1210 #define SUBID_DVBT_KNC1 0x0030
1211 #define SUBID_DVBT_CINERGY1200 0x1157
1212 
1213 static void frontend_init(struct budget_av *budget_av)
1214 {
1215  struct saa7146_dev * saa = budget_av->budget.dev;
1216  struct dvb_frontend * fe = NULL;
1217 
1218  /* Enable / PowerON Frontend */
1220 
1221  /* Wait for PowerON */
1222  msleep(100);
1223 
1224  /* additional setup necessary for the PLUS cards */
1225  switch (saa->pci->subsystem_device) {
1226  case SUBID_DVBS_KNC1_PLUS:
1227  case SUBID_DVBC_KNC1_PLUS:
1228  case SUBID_DVBT_KNC1_PLUS:
1229  case SUBID_DVBC_EASYWATCH:
1231  case SUBID_DVBS2_KNC1:
1232  case SUBID_DVBS2_KNC1_OEM:
1233  case SUBID_DVBS2_EASYWATCH:
1235  break;
1236  }
1237 
1238  switch (saa->pci->subsystem_device) {
1239 
1240  case SUBID_DVBS_KNC1:
1241  /*
1242  * maybe that setting is needed for other dvb-s cards as well,
1243  * but so far it has been only confirmed for this type
1244  */
1245  budget_av->reinitialise_demod = 1;
1246  /* fall through */
1247  case SUBID_DVBS_KNC1_PLUS:
1249  if (saa->pci->subsystem_vendor == 0x1894) {
1250  fe = dvb_attach(stv0299_attach, &cinergy_1200s_1894_0010_config,
1251  &budget_av->budget.i2c_adap);
1252  if (fe) {
1253  dvb_attach(tua6100_attach, fe, 0x60, &budget_av->budget.i2c_adap);
1254  }
1255  } else {
1256  fe = dvb_attach(stv0299_attach, &typhoon_config,
1257  &budget_av->budget.i2c_adap);
1258  if (fe) {
1259  fe->ops.tuner_ops.set_params = philips_su1278_ty_ci_tuner_set_params;
1260  }
1261  }
1262  break;
1263 
1264  case SUBID_DVBS_TV_STAR:
1266  case SUBID_DVBS_TV_STAR_CI:
1268  case SUBID_DVBS_EASYWATCH:
1270  fe = dvb_attach(stv0299_attach, &philips_sd1878_config,
1271  &budget_av->budget.i2c_adap);
1272  if (fe) {
1273  dvb_attach(dvb_pll_attach, fe, 0x60,
1274  &budget_av->budget.i2c_adap,
1276  }
1277  break;
1278 
1279  case SUBID_DVBS_TYPHOON:
1280  fe = dvb_attach(stv0299_attach, &typhoon_config,
1281  &budget_av->budget.i2c_adap);
1282  if (fe) {
1283  fe->ops.tuner_ops.set_params = philips_su1278_ty_ci_tuner_set_params;
1284  }
1285  break;
1286  case SUBID_DVBS2_KNC1:
1287  case SUBID_DVBS2_KNC1_OEM:
1288  case SUBID_DVBS2_EASYWATCH:
1289  budget_av->reinitialise_demod = 1;
1290  if ((fe = dvb_attach(stb0899_attach, &knc1_dvbs2_config, &budget_av->budget.i2c_adap)))
1291  dvb_attach(tda8261_attach, fe, &sd1878c_config, &budget_av->budget.i2c_adap);
1292 
1293  break;
1295  fe = dvb_attach(stv0299_attach, &cinergy_1200s_config,
1296  &budget_av->budget.i2c_adap);
1297  if (fe) {
1298  fe->ops.tuner_ops.set_params = philips_su1278_ty_ci_tuner_set_params;
1299  }
1300  break;
1301 
1302  case SUBID_DVBC_KNC1:
1303  case SUBID_DVBC_KNC1_PLUS:
1305  case SUBID_DVBC_EASYWATCH:
1306  budget_av->reinitialise_demod = 1;
1307  budget_av->budget.dev->i2c_bitrate = SAA7146_I2C_BUS_BIT_RATE_240;
1308  fe = dvb_attach(tda10021_attach, &philips_cu1216_config,
1309  &budget_av->budget.i2c_adap,
1310  read_pwm(budget_av));
1311  if (fe == NULL)
1312  fe = dvb_attach(tda10021_attach, &philips_cu1216_config_altaddress,
1313  &budget_av->budget.i2c_adap,
1314  read_pwm(budget_av));
1315  if (fe) {
1316  fe->ops.tuner_ops.set_params = philips_cu1216_tuner_set_params;
1317  }
1318  break;
1319 
1322  case SUBID_DVBC_KNC1_MK3:
1325  budget_av->reinitialise_demod = 1;
1326  budget_av->budget.dev->i2c_bitrate = SAA7146_I2C_BUS_BIT_RATE_240;
1328  &philips_cu1216_tda10023_config,
1329  &budget_av->budget.i2c_adap,
1330  read_pwm(budget_av));
1331  if (fe) {
1332  fe->ops.tuner_ops.set_params = philips_cu1216_tuner_set_params;
1333  }
1334  break;
1335 
1336  case SUBID_DVBT_EASYWATCH:
1337  case SUBID_DVBT_KNC1:
1338  case SUBID_DVBT_KNC1_PLUS:
1340  budget_av->reinitialise_demod = 1;
1341  fe = dvb_attach(tda10046_attach, &philips_tu1216_config,
1342  &budget_av->budget.i2c_adap);
1343  if (fe) {
1344  fe->ops.tuner_ops.init = philips_tu1216_tuner_init;
1345  fe->ops.tuner_ops.set_params = philips_tu1216_tuner_set_params;
1346  }
1347  break;
1348  }
1349 
1350  if (fe == NULL) {
1351  pr_err("A frontend driver was not found for device [%04x:%04x] subsystem [%04x:%04x]\n",
1352  saa->pci->vendor,
1353  saa->pci->device,
1354  saa->pci->subsystem_vendor,
1355  saa->pci->subsystem_device);
1356  return;
1357  }
1358 
1359  budget_av->budget.dvb_frontend = fe;
1360 
1361  if (dvb_register_frontend(&budget_av->budget.dvb_adapter,
1362  budget_av->budget.dvb_frontend)) {
1363  pr_err("Frontend registration failed!\n");
1364  dvb_frontend_detach(budget_av->budget.dvb_frontend);
1365  budget_av->budget.dvb_frontend = NULL;
1366  }
1367 }
1368 
1369 
1370 static void budget_av_irq(struct saa7146_dev *dev, u32 * isr)
1371 {
1372  struct budget_av *budget_av = (struct budget_av *) dev->ext_priv;
1373 
1374  dprintk(8, "dev: %p, budget_av: %p\n", dev, budget_av);
1375 
1376  if (*isr & MASK_10)
1377  ttpci_budget_irq10_handler(dev, isr);
1378 }
1379 
1380 static int budget_av_detach(struct saa7146_dev *dev)
1381 {
1382  struct budget_av *budget_av = (struct budget_av *) dev->ext_priv;
1383  int err;
1384 
1385  dprintk(2, "dev: %p\n", dev);
1386 
1387  if (1 == budget_av->has_saa7113) {
1389 
1390  msleep(200);
1391 
1392  saa7146_unregister_device(&budget_av->vd, dev);
1393 
1394  saa7146_vv_release(dev);
1395  }
1396 
1397  if (budget_av->budget.ci_present)
1398  ciintf_deinit(budget_av);
1399 
1400  if (budget_av->budget.dvb_frontend != NULL) {
1401  dvb_unregister_frontend(budget_av->budget.dvb_frontend);
1402  dvb_frontend_detach(budget_av->budget.dvb_frontend);
1403  }
1404  err = ttpci_budget_deinit(&budget_av->budget);
1405 
1406  kfree(budget_av);
1407 
1408  return err;
1409 }
1410 
1411 #define KNC1_INPUTS 2
1412 static struct v4l2_input knc1_inputs[KNC1_INPUTS] = {
1413  { 0, "Composite", V4L2_INPUT_TYPE_TUNER, 1, 0,
1415  { 1, "S-Video", V4L2_INPUT_TYPE_CAMERA, 2, 0,
1417 };
1418 
1419 static int vidioc_enum_input(struct file *file, void *fh, struct v4l2_input *i)
1420 {
1421  dprintk(1, "VIDIOC_ENUMINPUT %d\n", i->index);
1422  if (i->index >= KNC1_INPUTS)
1423  return -EINVAL;
1424  memcpy(i, &knc1_inputs[i->index], sizeof(struct v4l2_input));
1425  return 0;
1426 }
1427 
1428 static int vidioc_g_input(struct file *file, void *fh, unsigned int *i)
1429 {
1430  struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
1431  struct budget_av *budget_av = (struct budget_av *)dev->ext_priv;
1432 
1433  *i = budget_av->cur_input;
1434 
1435  dprintk(1, "VIDIOC_G_INPUT %d\n", *i);
1436  return 0;
1437 }
1438 
1439 static int vidioc_s_input(struct file *file, void *fh, unsigned int input)
1440 {
1441  struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
1442  struct budget_av *budget_av = (struct budget_av *)dev->ext_priv;
1443 
1444  dprintk(1, "VIDIOC_S_INPUT %d\n", input);
1445  return saa7113_setinput(budget_av, input);
1446 }
1447 
1448 static struct saa7146_ext_vv vv_data;
1449 
1450 static int budget_av_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_data *info)
1451 {
1452  struct budget_av *budget_av;
1453  u8 *mac;
1454  int err;
1455 
1456  dprintk(2, "dev: %p\n", dev);
1457 
1458  if (!(budget_av = kzalloc(sizeof(struct budget_av), GFP_KERNEL)))
1459  return -ENOMEM;
1460 
1461  budget_av->has_saa7113 = 0;
1462  budget_av->budget.ci_present = 0;
1463 
1464  dev->ext_priv = budget_av;
1465 
1466  err = ttpci_budget_init(&budget_av->budget, dev, info, THIS_MODULE,
1467  adapter_nr);
1468  if (err) {
1469  kfree(budget_av);
1470  return err;
1471  }
1472 
1473  /* knc1 initialization */
1474  saa7146_write(dev, DD1_STREAM_B, 0x04000000);
1475  saa7146_write(dev, DD1_INIT, 0x07000600);
1477 
1478  if (saa7113_init(budget_av) == 0) {
1479  budget_av->has_saa7113 = 1;
1480 
1481  if (0 != saa7146_vv_init(dev, &vv_data)) {
1482  /* fixme: proper cleanup here */
1483  ERR("cannot init vv subsystem\n");
1484  return err;
1485  }
1486  vv_data.vid_ops.vidioc_enum_input = vidioc_enum_input;
1487  vv_data.vid_ops.vidioc_g_input = vidioc_g_input;
1488  vv_data.vid_ops.vidioc_s_input = vidioc_s_input;
1489 
1490  if ((err = saa7146_register_device(&budget_av->vd, dev, "knc1", VFL_TYPE_GRABBER))) {
1491  /* fixme: proper cleanup here */
1492  ERR("cannot register capture v4l2 device\n");
1493  saa7146_vv_release(dev);
1494  return err;
1495  }
1496 
1497  /* beware: this modifies dev->vv ... */
1500 
1501  saa7113_setinput(budget_av, 0);
1502  }
1503 
1504  /* fixme: find some sane values here... */
1505  saa7146_write(dev, PCI_BT_V1, 0x1c00101f);
1506 
1507  mac = budget_av->budget.dvb_adapter.proposed_mac;
1508  if (i2c_readregs(&budget_av->budget.i2c_adap, 0xa0, 0x30, mac, 6)) {
1509  pr_err("KNC1-%d: Could not read MAC from KNC1 card\n",
1510  budget_av->budget.dvb_adapter.num);
1511  memset(mac, 0, 6);
1512  } else {
1513  pr_info("KNC1-%d: MAC addr = %pM\n",
1514  budget_av->budget.dvb_adapter.num, mac);
1515  }
1516 
1517  budget_av->budget.dvb_adapter.priv = budget_av;
1518  frontend_init(budget_av);
1519  ciintf_init(budget_av);
1520 
1521  ttpci_budget_init_hooks(&budget_av->budget);
1522 
1523  return 0;
1524 }
1525 
1526 static struct saa7146_standard standard[] = {
1527  {.name = "PAL",.id = V4L2_STD_PAL,
1528  .v_offset = 0x17,.v_field = 288,
1529  .h_offset = 0x14,.h_pixels = 680,
1530  .v_max_out = 576,.h_max_out = 768 },
1531 
1532  {.name = "NTSC",.id = V4L2_STD_NTSC,
1533  .v_offset = 0x16,.v_field = 240,
1534  .h_offset = 0x06,.h_pixels = 708,
1535  .v_max_out = 480,.h_max_out = 640, },
1536 };
1537 
1538 static struct saa7146_ext_vv vv_data = {
1539  .inputs = 2,
1540  .capabilities = 0, // perhaps later: V4L2_CAP_VBI_CAPTURE, but that need tweaking with the saa7113
1541  .flags = 0,
1542  .stds = &standard[0],
1543  .num_stds = ARRAY_SIZE(standard),
1544 };
1545 
1546 static struct saa7146_extension budget_extension;
1547 
1548 MAKE_BUDGET_INFO(knc1s, "KNC1 DVB-S", BUDGET_KNC1S);
1549 MAKE_BUDGET_INFO(knc1s2,"KNC1 DVB-S2", BUDGET_KNC1S2);
1550 MAKE_BUDGET_INFO(sates2,"Satelco EasyWatch DVB-S2", BUDGET_KNC1S2);
1551 MAKE_BUDGET_INFO(knc1c, "KNC1 DVB-C", BUDGET_KNC1C);
1552 MAKE_BUDGET_INFO(knc1t, "KNC1 DVB-T", BUDGET_KNC1T);
1553 MAKE_BUDGET_INFO(kncxs, "KNC TV STAR DVB-S", BUDGET_TVSTAR);
1554 MAKE_BUDGET_INFO(satewpls, "Satelco EasyWatch DVB-S light", BUDGET_TVSTAR);
1555 MAKE_BUDGET_INFO(satewpls1, "Satelco EasyWatch DVB-S light", BUDGET_KNC1S);
1556 MAKE_BUDGET_INFO(satewps, "Satelco EasyWatch DVB-S", BUDGET_KNC1S);
1557 MAKE_BUDGET_INFO(satewplc, "Satelco EasyWatch DVB-C", BUDGET_KNC1CP);
1558 MAKE_BUDGET_INFO(satewcmk3, "Satelco EasyWatch DVB-C MK3", BUDGET_KNC1C_MK3);
1559 MAKE_BUDGET_INFO(satewt, "Satelco EasyWatch DVB-T", BUDGET_KNC1T);
1560 MAKE_BUDGET_INFO(knc1sp, "KNC1 DVB-S Plus", BUDGET_KNC1SP);
1561 MAKE_BUDGET_INFO(knc1spx4, "KNC1 DVB-S Plus X4", BUDGET_KNC1SP);
1562 MAKE_BUDGET_INFO(knc1cp, "KNC1 DVB-C Plus", BUDGET_KNC1CP);
1563 MAKE_BUDGET_INFO(knc1cmk3, "KNC1 DVB-C MK3", BUDGET_KNC1C_MK3);
1564 MAKE_BUDGET_INFO(knc1ctda10024, "KNC1 DVB-C TDA10024", BUDGET_KNC1C_TDA10024);
1565 MAKE_BUDGET_INFO(knc1cpmk3, "KNC1 DVB-C Plus MK3", BUDGET_KNC1CP_MK3);
1566 MAKE_BUDGET_INFO(knc1tp, "KNC1 DVB-T Plus", BUDGET_KNC1TP);
1567 MAKE_BUDGET_INFO(cin1200s, "TerraTec Cinergy 1200 DVB-S", BUDGET_CIN1200S);
1568 MAKE_BUDGET_INFO(cin1200sn, "TerraTec Cinergy 1200 DVB-S", BUDGET_CIN1200S);
1569 MAKE_BUDGET_INFO(cin1200c, "Terratec Cinergy 1200 DVB-C", BUDGET_CIN1200C);
1570 MAKE_BUDGET_INFO(cin1200cmk3, "Terratec Cinergy 1200 DVB-C MK3", BUDGET_CIN1200C_MK3);
1571 MAKE_BUDGET_INFO(cin1200t, "Terratec Cinergy 1200 DVB-T", BUDGET_CIN1200T);
1572 
1573 static struct pci_device_id pci_tbl[] = {
1574  MAKE_EXTENSION_PCI(knc1s, 0x1131, 0x4f56),
1575  MAKE_EXTENSION_PCI(knc1s, 0x1131, 0x0010),
1576  MAKE_EXTENSION_PCI(knc1s, 0x1894, 0x0010),
1577  MAKE_EXTENSION_PCI(knc1sp, 0x1131, 0x0011),
1578  MAKE_EXTENSION_PCI(knc1sp, 0x1894, 0x0011),
1579  MAKE_EXTENSION_PCI(kncxs, 0x1894, 0x0014),
1580  MAKE_EXTENSION_PCI(knc1spx4, 0x1894, 0x0015),
1581  MAKE_EXTENSION_PCI(kncxs, 0x1894, 0x0016),
1582  MAKE_EXTENSION_PCI(knc1s2, 0x1894, 0x0018),
1583  MAKE_EXTENSION_PCI(knc1s2, 0x1894, 0x0019),
1584  MAKE_EXTENSION_PCI(sates2, 0x1894, 0x001d),
1585  MAKE_EXTENSION_PCI(satewpls, 0x1894, 0x001e),
1586  MAKE_EXTENSION_PCI(satewpls1, 0x1894, 0x001a),
1587  MAKE_EXTENSION_PCI(satewps, 0x1894, 0x001b),
1588  MAKE_EXTENSION_PCI(satewplc, 0x1894, 0x002a),
1589  MAKE_EXTENSION_PCI(satewcmk3, 0x1894, 0x002c),
1590  MAKE_EXTENSION_PCI(satewt, 0x1894, 0x003a),
1591  MAKE_EXTENSION_PCI(knc1c, 0x1894, 0x0020),
1592  MAKE_EXTENSION_PCI(knc1cp, 0x1894, 0x0021),
1593  MAKE_EXTENSION_PCI(knc1cmk3, 0x1894, 0x0022),
1594  MAKE_EXTENSION_PCI(knc1ctda10024, 0x1894, 0x0028),
1595  MAKE_EXTENSION_PCI(knc1cpmk3, 0x1894, 0x0023),
1596  MAKE_EXTENSION_PCI(knc1t, 0x1894, 0x0030),
1597  MAKE_EXTENSION_PCI(knc1tp, 0x1894, 0x0031),
1598  MAKE_EXTENSION_PCI(cin1200s, 0x153b, 0x1154),
1599  MAKE_EXTENSION_PCI(cin1200sn, 0x153b, 0x1155),
1600  MAKE_EXTENSION_PCI(cin1200c, 0x153b, 0x1156),
1601  MAKE_EXTENSION_PCI(cin1200cmk3, 0x153b, 0x1176),
1602  MAKE_EXTENSION_PCI(cin1200t, 0x153b, 0x1157),
1603  {
1604  .vendor = 0,
1605  }
1606 };
1607 
1608 MODULE_DEVICE_TABLE(pci, pci_tbl);
1609 
1610 static struct saa7146_extension budget_extension = {
1611  .name = "budget_av",
1612  .flags = SAA7146_USE_I2C_IRQ,
1613 
1614  .pci_tbl = pci_tbl,
1615 
1616  .module = THIS_MODULE,
1617  .attach = budget_av_attach,
1618  .detach = budget_av_detach,
1619 
1620  .irq_mask = MASK_10,
1621  .irq_func = budget_av_irq,
1622 };
1623 
1624 static int __init budget_av_init(void)
1625 {
1626  return saa7146_register_extension(&budget_extension);
1627 }
1628 
1629 static void __exit budget_av_exit(void)
1630 {
1631  saa7146_unregister_extension(&budget_extension);
1632 }
1633 
1634 module_init(budget_av_init);
1635 module_exit(budget_av_exit);
1636 
1637 MODULE_LICENSE("GPL");
1638 MODULE_AUTHOR("Ralph Metzler, Marcus Metzler, Michael Hunold, others");
1639 MODULE_DESCRIPTION("driver for the SAA7146 based so-called "
1640  "budget PCI DVB w/ analog input and CI-module (e.g. the KNC cards)");