Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ]
Version: [ 2.6.11.8 ] [ 2.6.25 ] [ 2.6.25.8 ] [ 2.6.31.13 ] Architecture: [ i386 ]
  1 /*
  2  * budget-ci.c: driver for the SAA7146 based Budget DVB cards 
  3  *
  4  * Compiled from various sources by Michael Hunold <michael@mihu.de> 
  5  *
  6  *     msp430 IR support contributed by Jack Thomasson <jkt@Helius.COM>
  7  *     partially based on the Siemens DVB driver by Ralph+Marcus Metzler
  8  *
  9  * CI interface support (c) 2004 Andrew de Quincey <adq_dvb@lidskialf.net>
 10  *
 11  * This program is free software; you can redistribute it and/or
 12  * modify it under the terms of the GNU General Public License
 13  * as published by the Free Software Foundation; either version 2
 14  * of the License, or (at your option) any later version.
 15  * 
 16  *
 17  * This program is distributed in the hope that it will be useful,
 18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 20  * GNU General Public License for more details.
 21  * 
 22  *
 23  * You should have received a copy of the GNU General Public License
 24  * along with this program; if not, write to the Free Software
 25  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 26  * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
 27  * 
 28  *
 29  * the project's page is at http://www.linuxtv.org/dvb/
 30  */
 31 
 32 #include "budget.h"
 33 
 34 #include <linux/module.h>
 35 #include <linux/errno.h>
 36 #include <linux/slab.h>
 37 #include <linux/interrupt.h>
 38 #include <linux/input.h>
 39 #include <linux/spinlock.h>
 40 
 41 #include "dvb_ca_en50221.h"
 42 #include "stv0299.h"
 43 #include "tda1004x.h"
 44 
 45 #define DEBIADDR_IR             0x1234
 46 #define DEBIADDR_CICONTROL      0x0000
 47 #define DEBIADDR_CIVERSION      0x4000
 48 #define DEBIADDR_IO             0x1000
 49 #define DEBIADDR_ATTR           0x3000
 50 
 51 #define CICONTROL_RESET         0x01
 52 #define CICONTROL_ENABLETS      0x02
 53 #define CICONTROL_CAMDETECT     0x08
 54 
 55 #define DEBICICTL               0x00420000
 56 #define DEBICICAM               0x02420000
 57 
 58 #define SLOTSTATUS_NONE         1
 59 #define SLOTSTATUS_PRESENT      2
 60 #define SLOTSTATUS_RESET        4
 61 #define SLOTSTATUS_READY        8
 62 #define SLOTSTATUS_OCCUPIED     (SLOTSTATUS_PRESENT|SLOTSTATUS_RESET|SLOTSTATUS_READY)
 63 
 64 struct budget_ci {
 65         struct budget budget;
 66         struct input_dev input_dev;
 67         struct tasklet_struct msp430_irq_tasklet;
 68         struct tasklet_struct ciintf_irq_tasklet;
 69         int slot_status;
 70         struct dvb_ca_en50221 ca;
 71         char ir_dev_name[50];
 72 };
 73 
 74 /* from reading the following remotes:
 75    Zenith Universal 7 / TV Mode 807 / VCR Mode 837
 76    Hauppauge (from NOVA-CI-s box product)
 77    i've taken a "middle of the road" approach and note the differences
 78 */
 79 static  u16 key_map[64] = {
 80         /* 0x0X */
 81         KEY_0, KEY_1, KEY_2, KEY_3, KEY_4, KEY_5, KEY_6, KEY_7, KEY_8,
 82         KEY_9,
 83         KEY_ENTER,
 84         KEY_RED,
 85         KEY_POWER,              /* RADIO on Hauppauge */
 86         KEY_MUTE,
 87         0,
 88         KEY_A,                  /* TV on Hauppauge */
 89         /* 0x1X */
 90         KEY_VOLUMEUP, KEY_VOLUMEDOWN,
 91         0, 0,
 92         KEY_B,
 93         0, 0, 0, 0, 0, 0, 0,
 94         KEY_UP, KEY_DOWN,
 95         KEY_OPTION,             /* RESERVED on Hauppauge */
 96         KEY_BREAK,
 97         /* 0x2X */
 98         KEY_CHANNELUP, KEY_CHANNELDOWN,
 99         KEY_PREVIOUS,           /* Prev. Ch on Zenith, SOURCE on Hauppauge */
100         0, KEY_RESTART, KEY_OK,
101         KEY_CYCLEWINDOWS,       /* MINIMIZE on Hauppauge */
102         0,
103         KEY_ENTER,              /* VCR mode on Zenith */
104         KEY_PAUSE,
105         0,
106         KEY_RIGHT, KEY_LEFT,
107         0,
108         KEY_MENU,               /* FULL SCREEN on Hauppauge */
109         0,
110         /* 0x3X */
111         KEY_SLOW,
112         KEY_PREVIOUS,           /* VCR mode on Zenith */
113         KEY_REWIND,
114         0,
115         KEY_FASTFORWARD,
116         KEY_PLAY, KEY_STOP,
117         KEY_RECORD,
118         KEY_TUNER,              /* TV/VCR on Zenith */
119         0,
120         KEY_C,
121         0,
122         KEY_EXIT,
123         KEY_POWER2,
124         KEY_TUNER,              /* VCR mode on Zenith */
125         0,
126 };
127 
128 
129 static void msp430_ir_debounce (unsigned long data)
130 {
131         struct input_dev *dev = (struct input_dev *) data;
132 
133         if (dev->rep[0] == 0 || dev->rep[0] == ~0) {
134                 input_event(dev, EV_KEY, key_map[dev->repeat_key], !!0);
135                 return;
136         }
137 
138         dev->rep[0] = 0;
139         dev->timer.expires = jiffies + HZ * 350 / 1000;
140         add_timer(&dev->timer);
141         input_event(dev, EV_KEY, key_map[dev->repeat_key], 2);  /* REPEAT */
142 }
143 
144 
145 
146 static void msp430_ir_interrupt (unsigned long data)
147 {
148         struct budget_ci *budget_ci = (struct budget_ci*) data;
149         struct input_dev *dev = &budget_ci->input_dev;
150         unsigned int code =
151                 ttpci_budget_debiread(&budget_ci->budget, DEBINOSWAP, DEBIADDR_IR, 2, 1, 0) >> 8;
152 
153         if (code & 0x40) {
154                 code &= 0x3f;
155 
156                 if (timer_pending(&dev->timer)) {
157                         if (code == dev->repeat_key) {
158                                 ++dev->rep[0];
159                                 return;
160                         }
161                         del_timer(&dev->timer);
162                         input_event(dev, EV_KEY, key_map[dev->repeat_key], !!0);
163                 }
164 
165                 if (!key_map[code]) {
166                         printk("DVB (%s): no key for %02x!\n", __FUNCTION__, code);
167                         return;
168                 }
169 
170                 /* initialize debounce and repeat */
171                 dev->repeat_key = code;
172                 /* Zenith remote _always_ sends 2 sequences */
173                 dev->rep[0] = ~0;
174                 /* 350 milliseconds */
175                 dev->timer.expires = jiffies + HZ * 350 / 1000;
176                 /* MAKE */
177                 input_event(dev, EV_KEY, key_map[code], !0);
178                 add_timer(&dev->timer);
179         }
180 }
181 
182 
183 static int msp430_ir_init (struct budget_ci *budget_ci)
184 {
185         struct saa7146_dev *saa = budget_ci->budget.dev;
186         int i;
187 
188         memset(&budget_ci->input_dev, 0, sizeof(struct input_dev));
189 
190         sprintf (budget_ci->ir_dev_name, "Budget-CI dvb ir receiver %s", saa->name);
191         budget_ci->input_dev.name = budget_ci->ir_dev_name;
192 
193         set_bit(EV_KEY, budget_ci->input_dev.evbit);
194 
195         for (i=0; i<sizeof(key_map)/sizeof(*key_map); i++)
196                 if (key_map[i])
197                         set_bit(key_map[i], budget_ci->input_dev.keybit);
198 
199         input_register_device(&budget_ci->input_dev);
200 
201         budget_ci->input_dev.timer.function = msp430_ir_debounce;
202 
203         saa7146_write(saa, IER, saa7146_read(saa, IER) | MASK_06);
204 
205         saa7146_setgpio(saa, 3, SAA7146_GPIO_IRQHI); 
206 
207         return 0;
208 }
209 
210 
211 static void msp430_ir_deinit (struct budget_ci *budget_ci)
212 {
213         struct saa7146_dev *saa = budget_ci->budget.dev;
214         struct input_dev *dev = &budget_ci->input_dev;
215 
216         saa7146_write(saa, IER, saa7146_read(saa, IER) & ~MASK_06);
217         saa7146_setgpio(saa, 3, SAA7146_GPIO_INPUT);
218 
219         if (del_timer(&dev->timer))
220                 input_event(dev, EV_KEY, key_map[dev->repeat_key], !!0);
221 
222         input_unregister_device(dev);
223 }
224 
225 static int ciintf_read_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int address)
226 {
227         struct budget_ci* budget_ci = (struct budget_ci*) ca->data;
228 
229         if (slot != 0)
230                 return -EINVAL;
231 
232         return ttpci_budget_debiread(&budget_ci->budget, DEBICICAM,
233                                      DEBIADDR_ATTR | (address & 0xfff), 1, 1, 0);
234 }
235 
236 static int ciintf_write_attribute_mem(struct dvb_ca_en50221 *ca, int slot, int address, u8 value)
237 {
238         struct budget_ci* budget_ci = (struct budget_ci*) ca->data;
239 
240         if (slot != 0)
241                 return -EINVAL;
242 
243         return ttpci_budget_debiwrite(&budget_ci->budget, DEBICICAM,
244                                       DEBIADDR_ATTR | (address & 0xfff), 1, value, 1, 0);
245 }
246 
247 static int ciintf_read_cam_control(struct dvb_ca_en50221 *ca, int slot, u8 address)
248 {
249         struct budget_ci* budget_ci = (struct budget_ci*) ca->data;
250 
251         if (slot != 0)
252                 return -EINVAL;
253 
254         return ttpci_budget_debiread(&budget_ci->budget, DEBICICAM,
255                                      DEBIADDR_IO | (address & 3), 1, 1, 0);
256 }
257 
258 static int ciintf_write_cam_control(struct dvb_ca_en50221 *ca, int slot, u8 address, u8 value)
259 {
260         struct budget_ci* budget_ci = (struct budget_ci*) ca->data;
261 
262         if (slot != 0)
263                 return -EINVAL;
264 
265         return ttpci_budget_debiwrite(&budget_ci->budget, DEBICICAM,
266                                       DEBIADDR_IO | (address & 3), 1, value, 1, 0);
267 }
268 
269 static int ciintf_slot_reset(struct dvb_ca_en50221 *ca, int slot)
270 {
271         struct budget_ci* budget_ci = (struct budget_ci*) ca->data;
272         struct saa7146_dev *saa = budget_ci->budget.dev;
273 
274         if (slot != 0)
275                 return -EINVAL;
276 
277         // trigger on RISING edge during reset so we know when READY is re-asserted
278         saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQHI);
279         budget_ci->slot_status = SLOTSTATUS_RESET;
280         ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 0, 1, 0);
281         msleep(1);
282         ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1,
283                                CICONTROL_RESET, 1, 0);
284 
285         saa7146_setgpio(saa, 1, SAA7146_GPIO_OUTHI);
286         ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTB);
287         return 0;
288 }
289 
290 static int ciintf_slot_shutdown(struct dvb_ca_en50221 *ca, int slot)
291 {
292         struct budget_ci* budget_ci = (struct budget_ci*) ca->data;
293         struct saa7146_dev *saa = budget_ci->budget.dev;
294 
295         if (slot != 0)
296                 return -EINVAL;
297 
298         saa7146_setgpio(saa, 1, SAA7146_GPIO_OUTHI);
299         ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTB);
300         return 0;
301 }
302 
303 static int ciintf_slot_ts_enable(struct dvb_ca_en50221 *ca, int slot)
304 {
305         struct budget_ci* budget_ci = (struct budget_ci*) ca->data;
306         struct saa7146_dev *saa = budget_ci->budget.dev;
307         int tmp;
308 
309         if (slot != 0)
310                 return -EINVAL;
311 
312         saa7146_setgpio(saa, 1, SAA7146_GPIO_OUTLO);
313 
314         tmp = ttpci_budget_debiread(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 1, 0);
315         ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1,
316                                tmp | CICONTROL_ENABLETS, 1, 0);
317 
318         ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTA);
319         return 0;
320 }
321 
322 
323 static void ciintf_interrupt (unsigned long data)
324 {
325         struct budget_ci *budget_ci = (struct budget_ci*) data;
326         struct saa7146_dev *saa = budget_ci->budget.dev;
327         unsigned int flags;
328 
329         // ensure we don't get spurious IRQs during initialisation
330         if (!budget_ci->budget.ci_present)
331                 return;
332 
333         // read the CAM status
334         flags = ttpci_budget_debiread(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 1, 0);
335         if (flags & CICONTROL_CAMDETECT) {
336 
337                 // GPIO should be set to trigger on falling edge if a CAM is present
338         saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQLO);
339 
340                 if (budget_ci->slot_status & SLOTSTATUS_NONE) {
341                         // CAM insertion IRQ
342                         budget_ci->slot_status = SLOTSTATUS_PRESENT;
343                         dvb_ca_en50221_camchange_irq(&budget_ci->ca, 0,
344                                                      DVB_CA_EN50221_CAMCHANGE_INSERTED);
345 
346                 } else if (budget_ci->slot_status & SLOTSTATUS_RESET) {
347                         // CAM ready (reset completed)
348                         budget_ci->slot_status = SLOTSTATUS_READY;
349                         dvb_ca_en50221_camready_irq(&budget_ci->ca, 0);
350 
351                 } else if (budget_ci->slot_status & SLOTSTATUS_READY) {
352                         // FR/DA IRQ
353                         dvb_ca_en50221_frda_irq(&budget_ci->ca, 0);
354                 }
355         } else {
356 
357                 // trigger on rising edge if a CAM is not present - when a CAM is inserted, we
358                 // only want to get the IRQ when it sets READY. If we trigger on the falling edge,
359                 // the CAM might not actually be ready yet.
360                 saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQHI);
361 
362                 // generate a CAM removal IRQ if we haven't already
363                 if (budget_ci->slot_status & SLOTSTATUS_OCCUPIED) {
364                         // CAM removal IRQ
365                         budget_ci->slot_status = SLOTSTATUS_NONE;
366                         dvb_ca_en50221_camchange_irq(&budget_ci->ca, 0,
367                                                      DVB_CA_EN50221_CAMCHANGE_REMOVED);
368                 }
369         }
370 }
371 
372 static int ciintf_init(struct budget_ci* budget_ci)
373 {
374         struct saa7146_dev *saa = budget_ci->budget.dev;
375         int flags;
376         int result;
377 
378         memset(&budget_ci->ca, 0, sizeof(struct dvb_ca_en50221));
379 
380         // enable DEBI pins
381         saa7146_write(saa, MC1, saa7146_read(saa, MC1) | (0x800 << 16) | 0x800);
382 
383         // test if it is there
384         if ((ttpci_budget_debiread(&budget_ci->budget, DEBICICTL, DEBIADDR_CIVERSION, 1, 1, 0) & 0xa0) != 0xa0) {
385                 result = -ENODEV;
386                 goto error;
387         }
388         // determine whether a CAM is present or not
389         flags = ttpci_budget_debiread(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 1, 0);
390         budget_ci->slot_status = SLOTSTATUS_NONE;
391         if (flags & CICONTROL_CAMDETECT)
392                 budget_ci->slot_status = SLOTSTATUS_PRESENT;
393 
394         // register CI interface
395         budget_ci->ca.owner = THIS_MODULE;
396         budget_ci->ca.read_attribute_mem = ciintf_read_attribute_mem;
397         budget_ci->ca.write_attribute_mem = ciintf_write_attribute_mem;
398         budget_ci->ca.read_cam_control = ciintf_read_cam_control;
399         budget_ci->ca.write_cam_control = ciintf_write_cam_control;
400         budget_ci->ca.slot_reset = ciintf_slot_reset;
401         budget_ci->ca.slot_shutdown = ciintf_slot_shutdown;
402         budget_ci->ca.slot_ts_enable = ciintf_slot_ts_enable;
403         budget_ci->ca.data = budget_ci;
404         if ((result = dvb_ca_en50221_init(budget_ci->budget.dvb_adapter,
405                                           &budget_ci->ca,
406                                           DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE |
407                                           DVB_CA_EN50221_FLAG_IRQ_FR |
408                                           DVB_CA_EN50221_FLAG_IRQ_DA, 1)) != 0) {
409                 printk("budget_ci: CI interface detected, but initialisation failed.\n");
410                 goto error;
411         }
412 
413         // Setup CI slot IRQ
414         tasklet_init (&budget_ci->ciintf_irq_tasklet, ciintf_interrupt, (unsigned long) budget_ci);
415         if (budget_ci->slot_status != SLOTSTATUS_NONE) {
416         saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQLO);
417         } else {
418                 saa7146_setgpio(saa, 0, SAA7146_GPIO_IRQHI);
419         }
420         saa7146_write(saa, IER, saa7146_read(saa, IER) | MASK_03);
421         ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1,
422                                CICONTROL_RESET, 1, 0);
423 
424         // success!
425         printk("budget_ci: CI interface initialised\n");
426         budget_ci->budget.ci_present = 1;
427 
428         // forge a fake CI IRQ so the CAM state is setup correctly
429         flags = DVB_CA_EN50221_CAMCHANGE_REMOVED;
430         if (budget_ci->slot_status != SLOTSTATUS_NONE)
431                 flags = DVB_CA_EN50221_CAMCHANGE_INSERTED;
432         dvb_ca_en50221_camchange_irq(&budget_ci->ca, 0, flags);
433 
434         return 0;
435 
436 error:
437         saa7146_write(saa, MC1, saa7146_read(saa, MC1) | (0x800 << 16));
438         return result;
439 }
440 
441 static void ciintf_deinit(struct budget_ci* budget_ci)
442 {
443         struct saa7146_dev *saa = budget_ci->budget.dev;
444 
445         // disable CI interrupts
446         saa7146_write(saa, IER, saa7146_read(saa, IER) & ~MASK_03);
447         saa7146_setgpio(saa, 0, SAA7146_GPIO_INPUT);
448         tasklet_kill(&budget_ci->ciintf_irq_tasklet);
449         ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1, 0, 1, 0);
450         msleep(1);
451         ttpci_budget_debiwrite(&budget_ci->budget, DEBICICTL, DEBIADDR_CICONTROL, 1,
452                                CICONTROL_RESET, 1, 0);
453 
454         // disable TS data stream to CI interface
455         saa7146_setgpio(saa, 1, SAA7146_GPIO_INPUT);
456 
457         // release the CA device
458         dvb_ca_en50221_release(&budget_ci->ca);
459 
460         // disable DEBI pins
461         saa7146_write(saa, MC1, saa7146_read(saa, MC1) | (0x800 << 16));
462 }
463 
464 static void budget_ci_irq (struct saa7146_dev *dev, u32 *isr)
465 {
466         struct budget_ci *budget_ci = (struct budget_ci*) dev->ext_priv;
467 
468         dprintk(8, "dev: %p, budget_ci: %p\n", dev, budget_ci);
469 
470         if (*isr & MASK_06)
471                 tasklet_schedule (&budget_ci->msp430_irq_tasklet);
472 
473         if (*isr & MASK_10)
474                 ttpci_budget_irq10_handler (dev, isr);
475 
476         if ((*isr & MASK_03) && (budget_ci->budget.ci_present))
477                 tasklet_schedule (&budget_ci->ciintf_irq_tasklet);
478 }
479 
480 
481 static u8 alps_bsru6_inittab[] = {
482         0x01, 0x15,
483         0x02, 0x00,
484         0x03, 0x00,
485         0x04, 0x7d,             /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */
486         0x05, 0x35,             /* I2CT = 0, SCLT = 1, SDAT = 1 */
487         0x06, 0x40,             /* DAC not used, set to high impendance mode */
488         0x07, 0x00,             /* DAC LSB */
489         0x08, 0x40,             /* DiSEqC off, LNB power on OP2/LOCK pin on */
490         0x09, 0x00,             /* FIFO */
491         0x0c, 0x51,             /* OP1 ctl = Normal, OP1 val = 1 (LNB Power ON) */
492         0x0d, 0x82,             /* DC offset compensation = ON, beta_agc1 = 2 */
493         0x0e, 0x23,             /* alpha_tmg = 2, beta_tmg = 3 */
494         0x10, 0x3f,             // AGC2  0x3d
495         0x11, 0x84,
496         0x12, 0xb5,             // Lock detect: -64  Carrier freq detect:on
497         0x15, 0xc9,             // lock detector threshold
498         0x16, 0x00,
499         0x17, 0x00,
500         0x18, 0x00,
501         0x19, 0x00,
502         0x1a, 0x00,
503         0x1f, 0x50,
504         0x20, 0x00,
505         0x21, 0x00,
506         0x22, 0x00,
507         0x23, 0x00,
508         0x28, 0x00,             // out imp: normal  out type: parallel FEC mode:0
509         0x29, 0x1e,             // 1/2 threshold
510         0x2a, 0x14,             // 2/3 threshold
511         0x2b, 0x0f,             // 3/4 threshold
512         0x2c, 0x09,             // 5/6 threshold
513         0x2d, 0x05,             // 7/8 threshold
514         0x2e, 0x01,
515         0x31, 0x1f,             // test all FECs
516         0x32, 0x19,             // viterbi and synchro search
517         0x33, 0xfc,             // rs control
518         0x34, 0x93,             // error control
519         0x0f, 0x52,
520         0xff, 0xff
521 };
522 
523 static int alps_bsru6_set_symbol_rate(struct dvb_frontend *fe, u32 srate, u32 ratio)
524 {
525         u8 aclk = 0;
526         u8 bclk = 0;
527 
528         if (srate < 1500000) {
529                 aclk = 0xb7;
530                 bclk = 0x47;
531         } else if (srate < 3000000) {
532                 aclk = 0xb7;
533                 bclk = 0x4b;
534         } else if (srate < 7000000) {
535                 aclk = 0xb7;
536                 bclk = 0x4f;
537         } else if (srate < 14000000) {
538                 aclk = 0xb7;
539                 bclk = 0x53;
540         } else if (srate < 30000000) {
541                 aclk = 0xb6;
542                 bclk = 0x53;
543         } else if (srate < 45000000) {
544                 aclk = 0xb4;
545                 bclk = 0x51;
546         }
547 
548         stv0299_writereg(fe, 0x13, aclk);
549         stv0299_writereg(fe, 0x14, bclk);
550         stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff);
551         stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff);
552         stv0299_writereg(fe, 0x21, (ratio) & 0xf0);
553 
554         return 0;
555 }
556 
557 static int alps_bsru6_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
558 {
559         struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv;
560         u8 buf[4];
561         u32 div;
562         struct i2c_msg msg = {.addr = 0x61,.flags = 0,.buf = buf,.len = sizeof(buf) };
563 
564         if ((params->frequency < 950000) || (params->frequency > 2150000))
565                 return -EINVAL;
566 
567         div = (params->frequency + (125 - 1)) / 125;    // round correctly
568         buf[0] = (div >> 8) & 0x7f;
569         buf[1] = div & 0xff;
570         buf[2] = 0x80 | ((div & 0x18000) >> 10) | 4;
571         buf[3] = 0xC4;
572 
573         if (params->frequency > 1530000)
574                 buf[3] = 0xc0;
575 
576         if (i2c_transfer(&budget_ci->budget.i2c_adap, &msg, 1) != 1)
577                 return -EIO;
578         return 0;
579 }
580 
581 static struct stv0299_config alps_bsru6_config = {
582 
583         .demod_address = 0x68,
584         .inittab = alps_bsru6_inittab,
585         .mclk = 88000000UL,
586         .invert = 1,
587         .enhanced_tuning = 0,
588         .skip_reinit = 0,
589         .lock_output = STV0229_LOCKOUTPUT_1,
590         .volt13_op0_op1 = STV0299_VOLT13_OP1,
591         .min_delay_ms = 100,
592         .set_symbol_rate = alps_bsru6_set_symbol_rate,
593         .pll_set = alps_bsru6_pll_set,
594 };
595 
596 
597 
598 
599 static u8 philips_su1278_tt_inittab[] = {
600         0x01, 0x0f,
601         0x02, 0x30,
602         0x03, 0x00,
603         0x04, 0x5b,
604         0x05, 0x85,
605         0x06, 0x02,
606         0x07, 0x00,
607         0x08, 0x02,
608         0x09, 0x00,
609         0x0C, 0x01,
610         0x0D, 0x81,
611         0x0E, 0x44,
612         0x0f, 0x14,
613         0x10, 0x3c,
614         0x11, 0x84,
615         0x12, 0xda,
616         0x13, 0x97,
617         0x14, 0x95,
618         0x15, 0xc9,
619         0x16, 0x19,
620         0x17, 0x8c,
621         0x18, 0x59,
622         0x19, 0xf8,
623         0x1a, 0xfe,
624         0x1c, 0x7f,
625         0x1d, 0x00,
626         0x1e, 0x00,
627         0x1f, 0x50,
628         0x20, 0x00,
629         0x21, 0x00,
630         0x22, 0x00,
631         0x23, 0x00,
632         0x28, 0x00,
633         0x29, 0x28,
634         0x2a, 0x14,
635         0x2b, 0x0f,
636         0x2c, 0x09,
637         0x2d, 0x09,
638         0x31, 0x1f,
639         0x32, 0x19,
640         0x33, 0xfc,
641         0x34, 0x93,
642         0xff, 0xff
643 };
644 
645 static int philips_su1278_tt_set_symbol_rate(struct dvb_frontend *fe, u32 srate, u32 ratio)
646 {
647         stv0299_writereg(fe, 0x0e, 0x44);
648         if (srate >= 10000000) {
649                 stv0299_writereg(fe, 0x13, 0x97);
650                 stv0299_writereg(fe, 0x14, 0x95);
651                 stv0299_writereg(fe, 0x15, 0xc9);
652                 stv0299_writereg(fe, 0x17, 0x8c);
653                 stv0299_writereg(fe, 0x1a, 0xfe);
654                 stv0299_writereg(fe, 0x1c, 0x7f);
655                 stv0299_writereg(fe, 0x2d, 0x09);
656         } else {
657                 stv0299_writereg(fe, 0x13, 0x99);
658                 stv0299_writereg(fe, 0x14, 0x8d);
659                 stv0299_writereg(fe, 0x15, 0xce);
660                 stv0299_writereg(fe, 0x17, 0x43);
661                 stv0299_writereg(fe, 0x1a, 0x1d);
662                 stv0299_writereg(fe, 0x1c, 0x12);
663                 stv0299_writereg(fe, 0x2d, 0x05);
664         }
665         stv0299_writereg(fe, 0x0e, 0x23);
666         stv0299_writereg(fe, 0x0f, 0x94);
667         stv0299_writereg(fe, 0x10, 0x39);
668         stv0299_writereg(fe, 0x15, 0xc9);
669 
670         stv0299_writereg(fe, 0x1f, (ratio >> 16) & 0xff);
671         stv0299_writereg(fe, 0x20, (ratio >> 8) & 0xff);
672         stv0299_writereg(fe, 0x21, (ratio) & 0xf0);
673 
674         return 0;
675 }
676 
677 static int philips_su1278_tt_pll_set(struct dvb_frontend *fe,
678                                      struct dvb_frontend_parameters *params)
679 {
680         struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv;
681         u32 div;
682         u8 buf[4];
683         struct i2c_msg msg = {.addr = 0x60,.flags = 0,.buf = buf,.len = sizeof(buf) };
684 
685         if ((params->frequency < 950000) || (params->frequency > 2150000))
686                 return -EINVAL;
687 
688         div = (params->frequency + (500 - 1)) / 500;    // round correctly
689         buf[0] = (div >> 8) & 0x7f;
690         buf[1] = div & 0xff;
691         buf[2] = 0x80 | ((div & 0x18000) >> 10) | 2;
692         buf[3] = 0x20;
693 
694         if (params->u.qpsk.symbol_rate < 4000000)
695                 buf[3] |= 1;
696 
697         if (params->frequency < 1250000)
698                 buf[3] |= 0;
699         else if (params->frequency < 1550000)
700                 buf[3] |= 0x40;
701         else if (params->frequency < 2050000)
702                 buf[3] |= 0x80;
703         else if (params->frequency < 2150000)
704                 buf[3] |= 0xC0;
705 
706         if (i2c_transfer(&budget_ci->budget.i2c_adap, &msg, 1) != 1)
707                 return -EIO;
708         return 0;
709 }
710 
711 static struct stv0299_config philips_su1278_tt_config = {
712 
713         .demod_address = 0x68,
714         .inittab = philips_su1278_tt_inittab,
715         .mclk = 64000000UL,
716         .invert = 0,
717         .enhanced_tuning = 1,
718         .skip_reinit = 1,
719         .lock_output = STV0229_LOCKOUTPUT_1,
720         .volt13_op0_op1 = STV0299_VOLT13_OP1,
721         .min_delay_ms = 50,
722         .set_symbol_rate = philips_su1278_tt_set_symbol_rate,
723         .pll_set = philips_su1278_tt_pll_set,
724 };
725 
726 
727 
728 static int philips_tdm1316l_pll_init(struct dvb_frontend *fe)
729 {
730         struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv;
731         static u8 td1316_init[] = { 0x0b, 0xf5, 0x85, 0xab };
732         static u8 disable_mc44BC374c[] = { 0x1d, 0x74, 0xa0, 0x68 };
733         struct i2c_msg tuner_msg = {.addr = 0x63,.flags = 0,.buf = td1316_init,.len =
734                         sizeof(td1316_init) };
735 
736         // setup PLL configuration
737         if (i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1) != 1)
738                 return -EIO;
739         msleep(1);
740 
741         // disable the mc44BC374c (do not check for errors)
742         tuner_msg.addr = 0x65;
743         tuner_msg.buf = disable_mc44BC374c;
744         tuner_msg.len = sizeof(disable_mc44BC374c);
745         if (i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1) != 1) {
746                 i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1);
747         }
748 
749         return 0;
750 }
751 
752 static int philips_tdm1316l_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
753 {
754         struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv;
755         u8 tuner_buf[4];
756         struct i2c_msg tuner_msg = {.addr = 0x63,.flags = 0,.buf = tuner_buf,.len = sizeof(tuner_buf) };
757         int tuner_frequency = 0;
758         u8 band, cp, filter;
759 
760         // determine charge pump
761         tuner_frequency = params->frequency + 36130000;
762         if (tuner_frequency < 87000000)
763                 return -EINVAL;
764         else if (tuner_frequency < 130000000)
765                 cp = 3;
766         else if (tuner_frequency < 160000000)
767                 cp = 5;
768         else if (tuner_frequency < 200000000)
769                 cp = 6;
770         else if (tuner_frequency < 290000000)
771                 cp = 3;
772         else if (tuner_frequency < 420000000)
773                 cp = 5;
774         else if (tuner_frequency < 480000000)
775                 cp = 6;
776         else if (tuner_frequency < 620000000)
777                 cp = 3;
778         else if (tuner_frequency < 830000000)
779                 cp = 5;
780         else if (tuner_frequency < 895000000)
781                 cp = 7;
782         else
783                 return -EINVAL;
784 
785         // determine band
786         if (params->frequency < 49000000)
787                 return -EINVAL;
788         else if (params->frequency < 159000000)
789                 band = 1;
790         else if (params->frequency < 444000000)
791                 band = 2;
792         else if (params->frequency < 861000000)
793                 band = 4;
794         else
795                 return -EINVAL;
796 
797         // setup PLL filter and TDA9889
798         switch (params->u.ofdm.bandwidth) {
799         case BANDWIDTH_6_MHZ:
800                 tda1004x_write_byte(fe, 0x0C, 0x14);
801                 filter = 0;
802                 break;
803 
804         case BANDWIDTH_7_MHZ:
805                 tda1004x_write_byte(fe, 0x0C, 0x80);
806                 filter = 0;
807                 break;
808 
809         case BANDWIDTH_8_MHZ:
810                 tda1004x_write_byte(fe, 0x0C, 0x14);
811                 filter = 1;
812                 break;
813 
814         default:
815                 return -EINVAL;
816         }
817 
818         // calculate divisor
819         // ((36130000+((1000000/6)/2)) + Finput)/(1000000/6)
820         tuner_frequency = (((params->frequency / 1000) * 6) + 217280) / 1000;
821 
822         // setup tuner buffer
823         tuner_buf[0] = tuner_frequency >> 8;
824         tuner_buf[1] = tuner_frequency & 0xff;
825         tuner_buf[2] = 0xca;
826         tuner_buf[3] = (cp << 5) | (filter << 3) | band;
827 
828         if (i2c_transfer(&budget_ci->budget.i2c_adap, &tuner_msg, 1) != 1)
829                 return -EIO;
830 
831         msleep(1);
832         return 0;
833 }
834 
835 static int philips_tdm1316l_request_firmware(struct dvb_frontend *fe,
836                                              const struct firmware **fw, char *name)
837 {
838         struct budget_ci *budget_ci = (struct budget_ci *) fe->dvb->priv;
839 
840         return request_firmware(fw, name, &budget_ci->budget.dev->pci->dev);
841 }
842 
843 static struct tda1004x_config philips_tdm1316l_config = {
844 
845         .demod_address = 0x8,
846         .invert = 0,
847         .invert_oclk = 0,
848         .pll_init = philips_tdm1316l_pll_init,
849         .pll_set = philips_tdm1316l_pll_set,
850         .request_firmware = philips_tdm1316l_request_firmware,
851 };
852 
853 
854 
855 static void frontend_init(struct budget_ci *budget_ci)
856 {
857         switch (budget_ci->budget.dev->pci->subsystem_device) {
858         case 0x100c:            // Hauppauge/TT Nova-CI budget (stv0299/ALPS BSRU6(tsa5059))
859                 budget_ci->budget.dvb_frontend =
860                         stv0299_attach(&alps_bsru6_config, &budget_ci->budget.i2c_adap);
861                 if (budget_ci->budget.dvb_frontend) {
862                         break;
863                 }
864                 break;
865 
866         case 0x100f:            // Hauppauge/TT Nova-CI budget (stv0299b/Philips su1278(tsa5059))
867                 budget_ci->budget.dvb_frontend =
868                         stv0299_attach(&philips_su1278_tt_config, &budget_ci->budget.i2c_adap);
869                 if (budget_ci->budget.dvb_frontend) {
870                         break;
871                 }
872                 break;
873 
874         case 0x1011:            // Hauppauge/TT Nova-T budget (tda10045/Philips tdm1316l(tda6651tt) + TDA9889)
875                 budget_ci->budget.dvb_frontend =
876                         tda10045_attach(&philips_tdm1316l_config, &budget_ci->budget.i2c_adap);
877                 if (budget_ci->budget.dvb_frontend) {
878                         break;
879                 }
880                 break;
881         }
882 
883         if (budget_ci->budget.dvb_frontend == NULL) {
884                 printk("budget-ci: A frontend driver was not found for device %04x/%04x subsystem %04x/%04x\n",
885                        budget_ci->budget.dev->pci->vendor,
886                        budget_ci->budget.dev->pci->device,
887                        budget_ci->budget.dev->pci->subsystem_vendor,
888                        budget_ci->budget.dev->pci->subsystem_device);
889         } else {
890                 if (dvb_register_frontend
891                     (budget_ci->budget.dvb_adapter, budget_ci->budget.dvb_frontend)) {
892                         printk("budget-ci: Frontend registration failed!\n");
893                         if (budget_ci->budget.dvb_frontend->ops->release)
894                                 budget_ci->budget.dvb_frontend->ops->release(budget_ci->budget.dvb_frontend);
895                         budget_ci->budget.dvb_frontend = NULL;
896                 }
897         }
898 }
899 
900 static int budget_ci_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_data *info)
901 {
902         struct budget_ci *budget_ci;
903         int err;
904 
905         if (!(budget_ci = kmalloc (sizeof(struct budget_ci), GFP_KERNEL)))
906                 return -ENOMEM;
907 
908         dprintk(2, "budget_ci: %p\n", budget_ci);
909 
910         budget_ci->budget.ci_present = 0;
911 
912         dev->ext_priv = budget_ci;
913 
914         if ((err = ttpci_budget_init(&budget_ci->budget, dev, info, THIS_MODULE))) {
915                 kfree (budget_ci);
916                 return err;
917         }
918 
919         tasklet_init (&budget_ci->msp430_irq_tasklet, msp430_ir_interrupt,
920                       (unsigned long) budget_ci);
921 
922         msp430_ir_init (budget_ci);
923 
924         ciintf_init(budget_ci);
925 
926         budget_ci->budget.dvb_adapter->priv = budget_ci;
927         frontend_init(budget_ci);
928 
929         return 0;
930 }
931 
932 
933 
934 static int budget_ci_detach (struct saa7146_dev* dev)
935 {
936         struct budget_ci *budget_ci = (struct budget_ci*) dev->ext_priv;
937         struct saa7146_dev *saa = budget_ci->budget.dev;
938         int err;
939 
940         if (budget_ci->budget.ci_present)
941                 ciintf_deinit(budget_ci);
942         if (budget_ci->budget.dvb_frontend)
943                 dvb_unregister_frontend(budget_ci->budget.dvb_frontend);
944         err = ttpci_budget_deinit (&budget_ci->budget);
945 
946         tasklet_kill (&budget_ci->msp430_irq_tasklet);
947 
948         msp430_ir_deinit (budget_ci);
949 
950         // disable frontend and CI interface
951         saa7146_setgpio(saa, 2, SAA7146_GPIO_INPUT);
952 
953         kfree (budget_ci);
954 
955         return err;
956 }
957 
958 
959 
960 static struct saa7146_extension budget_extension; 
961 
962 MAKE_BUDGET_INFO(ttbci, "TT-Budget/WinTV-NOVA-CI PCI",  BUDGET_TT_HW_DISEQC);
963 MAKE_BUDGET_INFO(ttbt2, "TT-Budget/WinTV-NOVA-T  PCI",  BUDGET_TT);
964 
965 static struct pci_device_id pci_tbl[] = {
966         MAKE_EXTENSION_PCI(ttbci, 0x13c2, 0x100c),
967         MAKE_EXTENSION_PCI(ttbci, 0x13c2, 0x100f),
968         MAKE_EXTENSION_PCI(ttbt2,  0x13c2, 0x1011),
969         {
970                 .vendor    = 0,
971         }
972 };
973 
974 MODULE_DEVICE_TABLE(pci, pci_tbl);
975 
976 static struct saa7146_extension budget_extension = {
977         .name           = "budget_ci dvb\0",
978         .flags          = 0,
979 
980         .module         = THIS_MODULE,
981         .pci_tbl        = &pci_tbl[0],
982         .attach         = budget_ci_attach,
983         .detach         = budget_ci_detach,
984 
985         .irq_mask       = MASK_03 | MASK_06 | MASK_10,
986         .irq_func       = budget_ci_irq,
987 };      
988 
989 
990 static int __init budget_ci_init(void) 
991 {
992         return saa7146_register_extension(&budget_extension);
993 }
994 
995 static void __exit budget_ci_exit(void)
996 {
997         saa7146_unregister_extension(&budget_extension); 
998 }
999 
1000 module_init(budget_ci_init);
1001 module_exit(budget_ci_exit);
1002 
1003 MODULE_LICENSE("GPL");
1004 MODULE_AUTHOR("Michael Hunold, Jack Thomasson, Andrew de Quincey, others");
1005 MODULE_DESCRIPTION("driver for the SAA7146 based so-called "
1006                    "budget PCI DVB cards w/ CI-module produced by "
1007                    "Siemens, Technotrend, Hauppauge");
1008 
1009 
  This page was automatically generated by the LXR engine.