• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 */
find_inode(void * 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 */
check_filter(struct fpga_internal * temp_int,void * demux_dev,int filt_nr)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 */
find_dinode(void * demux_dev)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 */
remove_inode(struct fpga_internal * internal)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 */
append_internal(struct fpga_internal * internal)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 
netup_fpga_op_rw(struct fpga_internal * inter,int addr,u8 val,u8 read)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 */
altera_ci_op_cam(struct dvb_ca_en50221 * en50221,int slot,u8 flag,u8 read,int addr,u8 val)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 
altera_ci_read_attribute_mem(struct dvb_ca_en50221 * en50221,int slot,int addr)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 
altera_ci_write_attribute_mem(struct dvb_ca_en50221 * en50221,int slot,int addr,u8 data)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 
altera_ci_read_cam_ctl(struct dvb_ca_en50221 * en50221,int slot,u8 addr)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 
altera_ci_write_cam_ctl(struct dvb_ca_en50221 * en50221,int slot,u8 addr,u8 data)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 
altera_ci_slot_reset(struct dvb_ca_en50221 * en50221,int slot)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 
altera_ci_slot_shutdown(struct dvb_ca_en50221 * en50221,int slot)360 static int altera_ci_slot_shutdown(struct dvb_ca_en50221 *en50221, int slot)
361 {
362 	/* not implemented */
363 	return 0;
364 }
365 
altera_ci_slot_ts_ctl(struct dvb_ca_en50221 * en50221,int slot)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 */
netup_read_ci_status(struct work_struct * work)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 */
altera_ci_irq(void * dev)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 
altera_poll_ci_slot_status(struct dvb_ca_en50221 * en50221,int slot,int open)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 
altera_hw_filt_release(void * main_dev,int filt_nr)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 
altera_ci_release(void * dev,int ci_nr)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 
altera_pid_control(struct netup_hw_pid_filter * pid_filt,u16 pid,int onoff)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 
altera_toggle_fullts_streaming(struct netup_hw_pid_filter * pid_filt,int filt_nr,int onoff)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 
altera_pid_feed_control(void * demux_dev,int filt_nr,struct dvb_demux_feed * feed,int onoff)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 
altera_ci_start_feed(struct dvb_demux_feed * feed,int num)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 
altera_ci_stop_feed(struct dvb_demux_feed * feed,int num)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 
altera_ci_start_feed_1(struct dvb_demux_feed * feed)610 static int altera_ci_start_feed_1(struct dvb_demux_feed *feed)
611 {
612 	return altera_ci_start_feed(feed, 1);
613 }
614 
altera_ci_stop_feed_1(struct dvb_demux_feed * feed)615 static int altera_ci_stop_feed_1(struct dvb_demux_feed *feed)
616 {
617 	return altera_ci_stop_feed(feed, 1);
618 }
619 
altera_ci_start_feed_2(struct dvb_demux_feed * feed)620 static int altera_ci_start_feed_2(struct dvb_demux_feed *feed)
621 {
622 	return altera_ci_start_feed(feed, 2);
623 }
624 
altera_ci_stop_feed_2(struct dvb_demux_feed * feed)625 static int altera_ci_stop_feed_2(struct dvb_demux_feed *feed)
626 {
627 	return altera_ci_stop_feed(feed, 2);
628 }
629 
altera_hw_filt_init(struct altera_ci_config * config,int hw_filt_nr)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 
altera_ci_init(struct altera_ci_config * config,int ci_nr)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 
altera_ci_tuner_reset(void * dev,int ci_nr)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);
839