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