root/drivers/media/pci/cx23885/altera-ci.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. find_inode
  2. check_filter
  3. find_dinode
  4. remove_inode
  5. append_internal
  6. netup_fpga_op_rw
  7. altera_ci_op_cam
  8. altera_ci_read_attribute_mem
  9. altera_ci_write_attribute_mem
  10. altera_ci_read_cam_ctl
  11. altera_ci_write_cam_ctl
  12. altera_ci_slot_reset
  13. altera_ci_slot_shutdown
  14. altera_ci_slot_ts_ctl
  15. netup_read_ci_status
  16. altera_ci_irq
  17. altera_poll_ci_slot_status
  18. altera_hw_filt_release
  19. altera_ci_release
  20. altera_pid_control
  21. altera_toggle_fullts_streaming
  22. altera_pid_feed_control
  23. altera_ci_start_feed
  24. altera_ci_stop_feed
  25. altera_ci_start_feed_1
  26. altera_ci_stop_feed_1
  27. altera_ci_start_feed_2
  28. altera_ci_stop_feed_2
  29. altera_hw_filt_init
  30. altera_ci_init
  31. altera_ci_tuner_reset

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  * altera-ci.c
   4  *
   5  *  CI driver in conjunction with NetUp Dual DVB-T/C RF CI card
   6  *
   7  * Copyright (C) 2010,2011 NetUP Inc.
   8  * Copyright (C) 2010,2011 Igor M. Liplianin <liplianin@netup.ru>
   9  */
  10 
  11 /*
  12  * currently cx23885 GPIO's used.
  13  * GPIO-0 ~INT in
  14  * GPIO-1 TMS out
  15  * GPIO-2 ~reset chips out
  16  * GPIO-3 to GPIO-10 data/addr for CA in/out
  17  * GPIO-11 ~CS out
  18  * GPIO-12 AD_RG out
  19  * GPIO-13 ~WR out
  20  * GPIO-14 ~RD out
  21  * GPIO-15 ~RDY in
  22  * GPIO-16 TCK out
  23  * GPIO-17 TDO in
  24  * GPIO-18 TDI out
  25  */
  26 /*
  27  *  Bit definitions for MC417_RWD and MC417_OEN registers
  28  * bits 31-16
  29  * +-----------+
  30  * | Reserved  |
  31  * +-----------+
  32  *   bit 15  bit 14  bit 13 bit 12  bit 11  bit 10  bit 9   bit 8
  33  * +-------+-------+-------+-------+-------+-------+-------+-------+
  34  * |  TDI  |  TDO  |  TCK  |  RDY# |  #RD  |  #WR  | AD_RG |  #CS  |
  35  * +-------+-------+-------+-------+-------+-------+-------+-------+
  36  *  bit 7   bit 6   bit 5   bit 4   bit 3   bit 2   bit 1   bit 0
  37  * +-------+-------+-------+-------+-------+-------+-------+-------+
  38  * |  DATA7|  DATA6|  DATA5|  DATA4|  DATA3|  DATA2|  DATA1|  DATA0|
  39  * +-------+-------+-------+-------+-------+-------+-------+-------+
  40  */
  41 
  42 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  43 
  44 #include <media/dvb_demux.h>
  45 #include <media/dvb_frontend.h>
  46 #include "altera-ci.h"
  47 #include <media/dvb_ca_en50221.h>
  48 
  49 /* FPGA regs */
  50 #define NETUP_CI_INT_CTRL       0x00
  51 #define NETUP_CI_BUSCTRL2       0x01
  52 #define NETUP_CI_ADDR0          0x04
  53 #define NETUP_CI_ADDR1          0x05
  54 #define NETUP_CI_DATA           0x06
  55 #define NETUP_CI_BUSCTRL        0x07
  56 #define NETUP_CI_PID_ADDR0      0x08
  57 #define NETUP_CI_PID_ADDR1      0x09
  58 #define NETUP_CI_PID_DATA       0x0a
  59 #define NETUP_CI_TSA_DIV        0x0c
  60 #define NETUP_CI_TSB_DIV        0x0d
  61 #define NETUP_CI_REVISION       0x0f
  62 
  63 /* const for ci op */
  64 #define NETUP_CI_FLG_CTL        1
  65 #define NETUP_CI_FLG_RD         1
  66 #define NETUP_CI_FLG_AD         1
  67 
  68 static unsigned int ci_dbg;
  69 module_param(ci_dbg, int, 0644);
  70 MODULE_PARM_DESC(ci_dbg, "Enable CI debugging");
  71 
  72 static unsigned int pid_dbg;
  73 module_param(pid_dbg, int, 0644);
  74 MODULE_PARM_DESC(pid_dbg, "Enable PID filtering debugging");
  75 
  76 MODULE_DESCRIPTION("altera FPGA CI module");
  77 MODULE_AUTHOR("Igor M. Liplianin  <liplianin@netup.ru>");
  78 MODULE_LICENSE("GPL");
  79 
  80 #define ci_dbg_print(fmt, args...) \
  81         do { \
  82                 if (ci_dbg) \
  83                         printk(KERN_DEBUG pr_fmt("%s: " fmt), \
  84                                __func__, ##args); \
  85         } while (0)
  86 
  87 #define pid_dbg_print(fmt, args...) \
  88         do { \
  89                 if (pid_dbg) \
  90                         printk(KERN_DEBUG pr_fmt("%s: " fmt), \
  91                                __func__, ##args); \
  92         } while (0)
  93 
  94 struct altera_ci_state;
  95 struct netup_hw_pid_filter;
  96 
  97 struct fpga_internal {
  98         void *dev;
  99         struct mutex fpga_mutex;/* two CI's on the same fpga */
 100         struct netup_hw_pid_filter *pid_filt[2];
 101         struct altera_ci_state *state[2];
 102         struct work_struct work;
 103         int (*fpga_rw) (void *dev, int flag, int data, int rw);
 104         int cis_used;
 105         int filts_used;
 106         int strt_wrk;
 107 };
 108 
 109 /* stores all private variables for communication with CI */
 110 struct altera_ci_state {
 111         struct fpga_internal *internal;
 112         struct dvb_ca_en50221 ca;
 113         int status;
 114         int nr;
 115 };
 116 
 117 /* stores all private variables for hardware pid filtering */
 118 struct netup_hw_pid_filter {
 119         struct fpga_internal *internal;
 120         struct dvb_demux *demux;
 121         /* save old functions */
 122         int (*start_feed)(struct dvb_demux_feed *feed);
 123         int (*stop_feed)(struct dvb_demux_feed *feed);
 124 
 125         int status;
 126         int nr;
 127 };
 128 
 129 /* internal params node */
 130 struct fpga_inode {
 131         /* pointer for internal params, one for each pair of CI's */
 132         struct fpga_internal            *internal;
 133         struct fpga_inode               *next_inode;
 134 };
 135 
 136 /* first internal params */
 137 static struct fpga_inode *fpga_first_inode;
 138 
 139 /* find chip by dev */
 140 static struct fpga_inode *find_inode(void *dev)
 141 {
 142         struct fpga_inode *temp_chip = fpga_first_inode;
 143 
 144         if (temp_chip == NULL)
 145                 return temp_chip;
 146 
 147         /*
 148          Search for the last fpga CI chip or
 149          find it by dev */
 150         while ((temp_chip != NULL) &&
 151                                 (temp_chip->internal->dev != dev))
 152                 temp_chip = temp_chip->next_inode;
 153 
 154         return temp_chip;
 155 }
 156 /* check demux */
 157 static struct fpga_internal *check_filter(struct fpga_internal *temp_int,
 158                                                 void *demux_dev, int filt_nr)
 159 {
 160         if (temp_int == NULL)
 161                 return NULL;
 162 
 163         if ((temp_int->pid_filt[filt_nr]) == NULL)
 164                 return NULL;
 165 
 166         if (temp_int->pid_filt[filt_nr]->demux == demux_dev)
 167                 return temp_int;
 168 
 169         return NULL;
 170 }
 171 
 172 /* find chip by demux */
 173 static struct fpga_inode *find_dinode(void *demux_dev)
 174 {
 175         struct fpga_inode *temp_chip = fpga_first_inode;
 176         struct fpga_internal *temp_int;
 177 
 178         /*
 179          * Search of the last fpga CI chip or
 180          * find it by demux
 181          */
 182         while (temp_chip != NULL) {
 183                 if (temp_chip->internal != NULL) {
 184                         temp_int = temp_chip->internal;
 185                         if (check_filter(temp_int, demux_dev, 0))
 186                                 break;
 187                         if (check_filter(temp_int, demux_dev, 1))
 188                                 break;
 189                 }
 190 
 191                 temp_chip = temp_chip->next_inode;
 192         }
 193 
 194         return temp_chip;
 195 }
 196 
 197 /* deallocating chip */
 198 static void remove_inode(struct fpga_internal *internal)
 199 {
 200         struct fpga_inode *prev_node = fpga_first_inode;
 201         struct fpga_inode *del_node = find_inode(internal->dev);
 202 
 203         if (del_node != NULL) {
 204                 if (del_node == fpga_first_inode) {
 205                         fpga_first_inode = del_node->next_inode;
 206                 } else {
 207                         while (prev_node->next_inode != del_node)
 208                                 prev_node = prev_node->next_inode;
 209 
 210                         if (del_node->next_inode == NULL)
 211                                 prev_node->next_inode = NULL;
 212                         else
 213                                 prev_node->next_inode =
 214                                         prev_node->next_inode->next_inode;
 215                 }
 216 
 217                 kfree(del_node);
 218         }
 219 }
 220 
 221 /* allocating new chip */
 222 static struct fpga_inode *append_internal(struct fpga_internal *internal)
 223 {
 224         struct fpga_inode *new_node = fpga_first_inode;
 225 
 226         if (new_node == NULL) {
 227                 new_node = kmalloc(sizeof(struct fpga_inode), GFP_KERNEL);
 228                 fpga_first_inode = new_node;
 229         } else {
 230                 while (new_node->next_inode != NULL)
 231                         new_node = new_node->next_inode;
 232 
 233                 new_node->next_inode =
 234                                 kmalloc(sizeof(struct fpga_inode), GFP_KERNEL);
 235                 if (new_node->next_inode != NULL)
 236                         new_node = new_node->next_inode;
 237                 else
 238                         new_node = NULL;
 239         }
 240 
 241         if (new_node != NULL) {
 242                 new_node->internal = internal;
 243                 new_node->next_inode = NULL;
 244         }
 245 
 246         return new_node;
 247 }
 248 
 249 static int netup_fpga_op_rw(struct fpga_internal *inter, int addr,
 250                                                         u8 val, u8 read)
 251 {
 252         inter->fpga_rw(inter->dev, NETUP_CI_FLG_AD, addr, 0);
 253         return inter->fpga_rw(inter->dev, 0, val, read);
 254 }
 255 
 256 /* flag - mem/io, read - read/write */
 257 static int altera_ci_op_cam(struct dvb_ca_en50221 *en50221, int slot,
 258                                 u8 flag, u8 read, int addr, u8 val)
 259 {
 260 
 261         struct altera_ci_state *state = en50221->data;
 262         struct fpga_internal *inter = state->internal;
 263 
 264         u8 store;
 265         int mem = 0;
 266 
 267         if (0 != slot)
 268                 return -EINVAL;
 269 
 270         mutex_lock(&inter->fpga_mutex);
 271 
 272         netup_fpga_op_rw(inter, NETUP_CI_ADDR0, ((addr << 1) & 0xfe), 0);
 273         netup_fpga_op_rw(inter, NETUP_CI_ADDR1, ((addr >> 7) & 0x7f), 0);
 274         store = netup_fpga_op_rw(inter, NETUP_CI_BUSCTRL, 0, NETUP_CI_FLG_RD);
 275 
 276         store &= 0x0f;
 277         store |= ((state->nr << 7) | (flag << 6));
 278 
 279         netup_fpga_op_rw(inter, NETUP_CI_BUSCTRL, store, 0);
 280         mem = netup_fpga_op_rw(inter, NETUP_CI_DATA, val, read);
 281 
 282         mutex_unlock(&inter->fpga_mutex);
 283 
 284         ci_dbg_print("%s: %s: addr=[0x%02x], %s=%x\n", __func__,
 285                         (read) ? "read" : "write", addr,
 286                         (flag == NETUP_CI_FLG_CTL) ? "ctl" : "mem",
 287                         (read) ? mem : val);
 288 
 289         return mem;
 290 }
 291 
 292 static int altera_ci_read_attribute_mem(struct dvb_ca_en50221 *en50221,
 293                                         int slot, int addr)
 294 {
 295         return altera_ci_op_cam(en50221, slot, 0, NETUP_CI_FLG_RD, addr, 0);
 296 }
 297 
 298 static int altera_ci_write_attribute_mem(struct dvb_ca_en50221 *en50221,
 299                                          int slot, int addr, u8 data)
 300 {
 301         return altera_ci_op_cam(en50221, slot, 0, 0, addr, data);
 302 }
 303 
 304 static int altera_ci_read_cam_ctl(struct dvb_ca_en50221 *en50221,
 305                                   int slot, u8 addr)
 306 {
 307         return altera_ci_op_cam(en50221, slot, NETUP_CI_FLG_CTL,
 308                                                 NETUP_CI_FLG_RD, addr, 0);
 309 }
 310 
 311 static int altera_ci_write_cam_ctl(struct dvb_ca_en50221 *en50221, int slot,
 312                                    u8 addr, u8 data)
 313 {
 314         return altera_ci_op_cam(en50221, slot, NETUP_CI_FLG_CTL, 0, addr, data);
 315 }
 316 
 317 static int altera_ci_slot_reset(struct dvb_ca_en50221 *en50221, int slot)
 318 {
 319         struct altera_ci_state *state = en50221->data;
 320         struct fpga_internal *inter = state->internal;
 321         /* reasonable timeout for CI reset is 10 seconds */
 322         unsigned long t_out = jiffies + msecs_to_jiffies(9999);
 323         int ret;
 324 
 325         ci_dbg_print("%s\n", __func__);
 326 
 327         if (0 != slot)
 328                 return -EINVAL;
 329 
 330         mutex_lock(&inter->fpga_mutex);
 331 
 332         ret = netup_fpga_op_rw(inter, NETUP_CI_BUSCTRL, 0, NETUP_CI_FLG_RD);
 333         netup_fpga_op_rw(inter, NETUP_CI_BUSCTRL,
 334                                 (ret & 0xcf) | (1 << (5 - state->nr)), 0);
 335 
 336         mutex_unlock(&inter->fpga_mutex);
 337 
 338         for (;;) {
 339                 msleep(50);
 340 
 341                 mutex_lock(&inter->fpga_mutex);
 342 
 343                 ret = netup_fpga_op_rw(inter, NETUP_CI_BUSCTRL,
 344                                                 0, NETUP_CI_FLG_RD);
 345                 mutex_unlock(&inter->fpga_mutex);
 346 
 347                 if ((ret & (1 << (5 - state->nr))) == 0)
 348                         break;
 349                 if (time_after(jiffies, t_out))
 350                         break;
 351         }
 352 
 353 
 354         ci_dbg_print("%s: %d msecs\n", __func__,
 355                 jiffies_to_msecs(jiffies + msecs_to_jiffies(9999) - t_out));
 356 
 357         return 0;
 358 }
 359 
 360 static int altera_ci_slot_shutdown(struct dvb_ca_en50221 *en50221, int slot)
 361 {
 362         /* not implemented */
 363         return 0;
 364 }
 365 
 366 static int altera_ci_slot_ts_ctl(struct dvb_ca_en50221 *en50221, int slot)
 367 {
 368         struct altera_ci_state *state = en50221->data;
 369         struct fpga_internal *inter = state->internal;
 370         int ret;
 371 
 372         ci_dbg_print("%s\n", __func__);
 373 
 374         if (0 != slot)
 375                 return -EINVAL;
 376 
 377         mutex_lock(&inter->fpga_mutex);
 378 
 379         ret = netup_fpga_op_rw(inter, NETUP_CI_BUSCTRL, 0, NETUP_CI_FLG_RD);
 380         netup_fpga_op_rw(inter, NETUP_CI_BUSCTRL,
 381                                 (ret & 0x0f) | (1 << (3 - state->nr)), 0);
 382 
 383         mutex_unlock(&inter->fpga_mutex);
 384 
 385         return 0;
 386 }
 387 
 388 /* work handler */
 389 static void netup_read_ci_status(struct work_struct *work)
 390 {
 391         struct fpga_internal *inter =
 392                         container_of(work, struct fpga_internal, work);
 393         int ret;
 394 
 395         ci_dbg_print("%s\n", __func__);
 396 
 397         mutex_lock(&inter->fpga_mutex);
 398         /* ack' irq */
 399         ret = netup_fpga_op_rw(inter, NETUP_CI_INT_CTRL, 0, NETUP_CI_FLG_RD);
 400         ret = netup_fpga_op_rw(inter, NETUP_CI_BUSCTRL, 0, NETUP_CI_FLG_RD);
 401 
 402         mutex_unlock(&inter->fpga_mutex);
 403 
 404         if (inter->state[1] != NULL) {
 405                 inter->state[1]->status =
 406                                 ((ret & 1) == 0 ?
 407                                 DVB_CA_EN50221_POLL_CAM_PRESENT |
 408                                 DVB_CA_EN50221_POLL_CAM_READY : 0);
 409                 ci_dbg_print("%s: setting CI[1] status = 0x%x\n",
 410                                 __func__, inter->state[1]->status);
 411         }
 412 
 413         if (inter->state[0] != NULL) {
 414                 inter->state[0]->status =
 415                                 ((ret & 2) == 0 ?
 416                                 DVB_CA_EN50221_POLL_CAM_PRESENT |
 417                                 DVB_CA_EN50221_POLL_CAM_READY : 0);
 418                 ci_dbg_print("%s: setting CI[0] status = 0x%x\n",
 419                                 __func__, inter->state[0]->status);
 420         }
 421 }
 422 
 423 /* CI irq handler */
 424 int altera_ci_irq(void *dev)
 425 {
 426         struct fpga_inode *temp_int = NULL;
 427         struct fpga_internal *inter = NULL;
 428 
 429         ci_dbg_print("%s\n", __func__);
 430 
 431         if (dev != NULL) {
 432                 temp_int = find_inode(dev);
 433                 if (temp_int != NULL) {
 434                         inter = temp_int->internal;
 435                         schedule_work(&inter->work);
 436                 }
 437         }
 438 
 439         return 1;
 440 }
 441 EXPORT_SYMBOL(altera_ci_irq);
 442 
 443 static int altera_poll_ci_slot_status(struct dvb_ca_en50221 *en50221,
 444                                       int slot, int open)
 445 {
 446         struct altera_ci_state *state = en50221->data;
 447 
 448         if (0 != slot)
 449                 return -EINVAL;
 450 
 451         return state->status;
 452 }
 453 
 454 static void altera_hw_filt_release(void *main_dev, int filt_nr)
 455 {
 456         struct fpga_inode *temp_int = find_inode(main_dev);
 457         struct netup_hw_pid_filter *pid_filt = NULL;
 458 
 459         ci_dbg_print("%s\n", __func__);
 460 
 461         if (temp_int != NULL) {
 462                 pid_filt = temp_int->internal->pid_filt[filt_nr - 1];
 463                 /* stored old feed controls */
 464                 pid_filt->demux->start_feed = pid_filt->start_feed;
 465                 pid_filt->demux->stop_feed = pid_filt->stop_feed;
 466 
 467                 if (((--(temp_int->internal->filts_used)) <= 0) &&
 468                          ((temp_int->internal->cis_used) <= 0)) {
 469 
 470                         ci_dbg_print("%s: Actually removing\n", __func__);
 471 
 472                         remove_inode(temp_int->internal);
 473                         kfree(pid_filt->internal);
 474                 }
 475 
 476                 kfree(pid_filt);
 477 
 478         }
 479 
 480 }
 481 
 482 void altera_ci_release(void *dev, int ci_nr)
 483 {
 484         struct fpga_inode *temp_int = find_inode(dev);
 485         struct altera_ci_state *state = NULL;
 486 
 487         ci_dbg_print("%s\n", __func__);
 488 
 489         if (temp_int != NULL) {
 490                 state = temp_int->internal->state[ci_nr - 1];
 491                 altera_hw_filt_release(dev, ci_nr);
 492 
 493 
 494                 if (((temp_int->internal->filts_used) <= 0) &&
 495                                 ((--(temp_int->internal->cis_used)) <= 0)) {
 496 
 497                         ci_dbg_print("%s: Actually removing\n", __func__);
 498 
 499                         remove_inode(temp_int->internal);
 500                         kfree(state->internal);
 501                 }
 502 
 503                 if (state != NULL) {
 504                         if (state->ca.data != NULL)
 505                                 dvb_ca_en50221_release(&state->ca);
 506 
 507                         kfree(state);
 508                 }
 509         }
 510 
 511 }
 512 EXPORT_SYMBOL(altera_ci_release);
 513 
 514 static void altera_pid_control(struct netup_hw_pid_filter *pid_filt,
 515                 u16 pid, int onoff)
 516 {
 517         struct fpga_internal *inter = pid_filt->internal;
 518         u8 store = 0;
 519 
 520         /* pid 0-0x1f always enabled, don't touch them */
 521         if ((pid == 0x2000) || (pid < 0x20))
 522                 return;
 523 
 524         mutex_lock(&inter->fpga_mutex);
 525 
 526         netup_fpga_op_rw(inter, NETUP_CI_PID_ADDR0, (pid >> 3) & 0xff, 0);
 527         netup_fpga_op_rw(inter, NETUP_CI_PID_ADDR1,
 528                         ((pid >> 11) & 0x03) | (pid_filt->nr << 2), 0);
 529 
 530         store = netup_fpga_op_rw(inter, NETUP_CI_PID_DATA, 0, NETUP_CI_FLG_RD);
 531 
 532         if (onoff)/* 0 - on, 1 - off */
 533                 store |= (1 << (pid & 7));
 534         else
 535                 store &= ~(1 << (pid & 7));
 536 
 537         netup_fpga_op_rw(inter, NETUP_CI_PID_DATA, store, 0);
 538 
 539         mutex_unlock(&inter->fpga_mutex);
 540 
 541         pid_dbg_print("%s: (%d) set pid: %5d 0x%04x '%s'\n", __func__,
 542                 pid_filt->nr, pid, pid, onoff ? "off" : "on");
 543 }
 544 
 545 static void altera_toggle_fullts_streaming(struct netup_hw_pid_filter *pid_filt,
 546                                         int filt_nr, int onoff)
 547 {
 548         struct fpga_internal *inter = pid_filt->internal;
 549         u8 store = 0;
 550         int i;
 551 
 552         pid_dbg_print("%s: pid_filt->nr[%d]  now %s\n", __func__, pid_filt->nr,
 553                         onoff ? "off" : "on");
 554 
 555         if (onoff)/* 0 - on, 1 - off */
 556                 store = 0xff;/* ignore pid */
 557         else
 558                 store = 0;/* enable pid */
 559 
 560         mutex_lock(&inter->fpga_mutex);
 561 
 562         for (i = 0; i < 1024; i++) {
 563                 netup_fpga_op_rw(inter, NETUP_CI_PID_ADDR0, i & 0xff, 0);
 564 
 565                 netup_fpga_op_rw(inter, NETUP_CI_PID_ADDR1,
 566                                 ((i >> 8) & 0x03) | (pid_filt->nr << 2), 0);
 567                 /* pid 0-0x1f always enabled */
 568                 netup_fpga_op_rw(inter, NETUP_CI_PID_DATA,
 569                                 (i > 3 ? store : 0), 0);
 570         }
 571 
 572         mutex_unlock(&inter->fpga_mutex);
 573 }
 574 
 575 static int altera_pid_feed_control(void *demux_dev, int filt_nr,
 576                 struct dvb_demux_feed *feed, int onoff)
 577 {
 578         struct fpga_inode *temp_int = find_dinode(demux_dev);
 579         struct fpga_internal *inter = temp_int->internal;
 580         struct netup_hw_pid_filter *pid_filt = inter->pid_filt[filt_nr - 1];
 581 
 582         altera_pid_control(pid_filt, feed->pid, onoff ? 0 : 1);
 583         /* call old feed proc's */
 584         if (onoff)
 585                 pid_filt->start_feed(feed);
 586         else
 587                 pid_filt->stop_feed(feed);
 588 
 589         if (feed->pid == 0x2000)
 590                 altera_toggle_fullts_streaming(pid_filt, filt_nr,
 591                                                 onoff ? 0 : 1);
 592 
 593         return 0;
 594 }
 595 
 596 static int altera_ci_start_feed(struct dvb_demux_feed *feed, int num)
 597 {
 598         altera_pid_feed_control(feed->demux, num, feed, 1);
 599 
 600         return 0;
 601 }
 602 
 603 static int altera_ci_stop_feed(struct dvb_demux_feed *feed, int num)
 604 {
 605         altera_pid_feed_control(feed->demux, num, feed, 0);
 606 
 607         return 0;
 608 }
 609 
 610 static int altera_ci_start_feed_1(struct dvb_demux_feed *feed)
 611 {
 612         return altera_ci_start_feed(feed, 1);
 613 }
 614 
 615 static int altera_ci_stop_feed_1(struct dvb_demux_feed *feed)
 616 {
 617         return altera_ci_stop_feed(feed, 1);
 618 }
 619 
 620 static int altera_ci_start_feed_2(struct dvb_demux_feed *feed)
 621 {
 622         return altera_ci_start_feed(feed, 2);
 623 }
 624 
 625 static int altera_ci_stop_feed_2(struct dvb_demux_feed *feed)
 626 {
 627         return altera_ci_stop_feed(feed, 2);
 628 }
 629 
 630 static int altera_hw_filt_init(struct altera_ci_config *config, int hw_filt_nr)
 631 {
 632         struct netup_hw_pid_filter *pid_filt = NULL;
 633         struct fpga_inode *temp_int = find_inode(config->dev);
 634         struct fpga_internal *inter = NULL;
 635         int ret = 0;
 636 
 637         pid_filt = kzalloc(sizeof(struct netup_hw_pid_filter), GFP_KERNEL);
 638 
 639         ci_dbg_print("%s\n", __func__);
 640 
 641         if (!pid_filt) {
 642                 ret = -ENOMEM;
 643                 goto err;
 644         }
 645 
 646         if (temp_int != NULL) {
 647                 inter = temp_int->internal;
 648                 (inter->filts_used)++;
 649                 ci_dbg_print("%s: Find Internal Structure!\n", __func__);
 650         } else {
 651                 inter = kzalloc(sizeof(struct fpga_internal), GFP_KERNEL);
 652                 if (!inter) {
 653                         ret = -ENOMEM;
 654                         goto err;
 655                 }
 656 
 657                 temp_int = append_internal(inter);
 658                 if (!temp_int) {
 659                         ret = -ENOMEM;
 660                         goto err;
 661                 }
 662                 inter->filts_used = 1;
 663                 inter->dev = config->dev;
 664                 inter->fpga_rw = config->fpga_rw;
 665                 mutex_init(&inter->fpga_mutex);
 666                 inter->strt_wrk = 1;
 667                 ci_dbg_print("%s: Create New Internal Structure!\n", __func__);
 668         }
 669 
 670         ci_dbg_print("%s: setting hw pid filter = %p for ci = %d\n", __func__,
 671                                                 pid_filt, hw_filt_nr - 1);
 672         inter->pid_filt[hw_filt_nr - 1] = pid_filt;
 673         pid_filt->demux = config->demux;
 674         pid_filt->internal = inter;
 675         pid_filt->nr = hw_filt_nr - 1;
 676         /* store old feed controls */
 677         pid_filt->start_feed = config->demux->start_feed;
 678         pid_filt->stop_feed = config->demux->stop_feed;
 679         /* replace with new feed controls */
 680         if (hw_filt_nr == 1) {
 681                 pid_filt->demux->start_feed = altera_ci_start_feed_1;
 682                 pid_filt->demux->stop_feed = altera_ci_stop_feed_1;
 683         } else if (hw_filt_nr == 2) {
 684                 pid_filt->demux->start_feed = altera_ci_start_feed_2;
 685                 pid_filt->demux->stop_feed = altera_ci_stop_feed_2;
 686         }
 687 
 688         altera_toggle_fullts_streaming(pid_filt, 0, 1);
 689 
 690         return 0;
 691 err:
 692         ci_dbg_print("%s: Can't init hardware filter: Error %d\n",
 693                      __func__, ret);
 694 
 695         kfree(pid_filt);
 696         kfree(inter);
 697 
 698         return ret;
 699 }
 700 
 701 int altera_ci_init(struct altera_ci_config *config, int ci_nr)
 702 {
 703         struct altera_ci_state *state;
 704         struct fpga_inode *temp_int = find_inode(config->dev);
 705         struct fpga_internal *inter = NULL;
 706         int ret = 0;
 707         u8 store = 0;
 708 
 709         state = kzalloc(sizeof(struct altera_ci_state), GFP_KERNEL);
 710 
 711         ci_dbg_print("%s\n", __func__);
 712 
 713         if (!state) {
 714                 ret = -ENOMEM;
 715                 goto err;
 716         }
 717 
 718         if (temp_int != NULL) {
 719                 inter = temp_int->internal;
 720                 (inter->cis_used)++;
 721                 inter->fpga_rw = config->fpga_rw;
 722                 ci_dbg_print("%s: Find Internal Structure!\n", __func__);
 723         } else {
 724                 inter = kzalloc(sizeof(struct fpga_internal), GFP_KERNEL);
 725                 if (!inter) {
 726                         ret = -ENOMEM;
 727                         goto err;
 728                 }
 729 
 730                 temp_int = append_internal(inter);
 731                 if (!temp_int) {
 732                         ret = -ENOMEM;
 733                         goto err;
 734                 }
 735                 inter->cis_used = 1;
 736                 inter->dev = config->dev;
 737                 inter->fpga_rw = config->fpga_rw;
 738                 mutex_init(&inter->fpga_mutex);
 739                 inter->strt_wrk = 1;
 740                 ci_dbg_print("%s: Create New Internal Structure!\n", __func__);
 741         }
 742 
 743         ci_dbg_print("%s: setting state = %p for ci = %d\n", __func__,
 744                                                 state, ci_nr - 1);
 745         state->internal = inter;
 746         state->nr = ci_nr - 1;
 747 
 748         state->ca.owner = THIS_MODULE;
 749         state->ca.read_attribute_mem = altera_ci_read_attribute_mem;
 750         state->ca.write_attribute_mem = altera_ci_write_attribute_mem;
 751         state->ca.read_cam_control = altera_ci_read_cam_ctl;
 752         state->ca.write_cam_control = altera_ci_write_cam_ctl;
 753         state->ca.slot_reset = altera_ci_slot_reset;
 754         state->ca.slot_shutdown = altera_ci_slot_shutdown;
 755         state->ca.slot_ts_enable = altera_ci_slot_ts_ctl;
 756         state->ca.poll_slot_status = altera_poll_ci_slot_status;
 757         state->ca.data = state;
 758 
 759         ret = dvb_ca_en50221_init(config->adapter,
 760                                    &state->ca,
 761                                    /* flags */ 0,
 762                                    /* n_slots */ 1);
 763         if (0 != ret)
 764                 goto err;
 765 
 766         inter->state[ci_nr - 1] = state;
 767 
 768         altera_hw_filt_init(config, ci_nr);
 769 
 770         if (inter->strt_wrk) {
 771                 INIT_WORK(&inter->work, netup_read_ci_status);
 772                 inter->strt_wrk = 0;
 773         }
 774 
 775         ci_dbg_print("%s: CI initialized!\n", __func__);
 776 
 777         mutex_lock(&inter->fpga_mutex);
 778 
 779         /* Enable div */
 780         netup_fpga_op_rw(inter, NETUP_CI_TSA_DIV, 0x0, 0);
 781         netup_fpga_op_rw(inter, NETUP_CI_TSB_DIV, 0x0, 0);
 782 
 783         /* enable TS out */
 784         store = netup_fpga_op_rw(inter, NETUP_CI_BUSCTRL2, 0, NETUP_CI_FLG_RD);
 785         store |= (3 << 4);
 786         netup_fpga_op_rw(inter, NETUP_CI_BUSCTRL2, store, 0);
 787 
 788         ret = netup_fpga_op_rw(inter, NETUP_CI_REVISION, 0, NETUP_CI_FLG_RD);
 789         /* enable irq */
 790         netup_fpga_op_rw(inter, NETUP_CI_INT_CTRL, 0x44, 0);
 791 
 792         mutex_unlock(&inter->fpga_mutex);
 793 
 794         ci_dbg_print("%s: NetUP CI Revision = 0x%x\n", __func__, ret);
 795 
 796         schedule_work(&inter->work);
 797 
 798         return 0;
 799 err:
 800         ci_dbg_print("%s: Cannot initialize CI: Error %d.\n", __func__, ret);
 801 
 802         kfree(state);
 803         kfree(inter);
 804 
 805         return ret;
 806 }
 807 EXPORT_SYMBOL(altera_ci_init);
 808 
 809 int altera_ci_tuner_reset(void *dev, int ci_nr)
 810 {
 811         struct fpga_inode *temp_int = find_inode(dev);
 812         struct fpga_internal *inter = NULL;
 813         u8 store;
 814 
 815         ci_dbg_print("%s\n", __func__);
 816 
 817         if (temp_int == NULL)
 818                 return -1;
 819 
 820         if (temp_int->internal == NULL)
 821                 return -1;
 822 
 823         inter = temp_int->internal;
 824 
 825         mutex_lock(&inter->fpga_mutex);
 826 
 827         store = netup_fpga_op_rw(inter, NETUP_CI_BUSCTRL2, 0, NETUP_CI_FLG_RD);
 828         store &= ~(4 << (2 - ci_nr));
 829         netup_fpga_op_rw(inter, NETUP_CI_BUSCTRL2, store, 0);
 830         msleep(100);
 831         store |= (4 << (2 - ci_nr));
 832         netup_fpga_op_rw(inter, NETUP_CI_BUSCTRL2, store, 0);
 833 
 834         mutex_unlock(&inter->fpga_mutex);
 835 
 836         return 0;
 837 }
 838 EXPORT_SYMBOL(altera_ci_tuner_reset);

/* [<][>][^][v][top][bottom][index][help] */