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
68static unsigned int ci_dbg;
69module_param(ci_dbg, int, 0644);
70MODULE_PARM_DESC(ci_dbg, "Enable CI debugging");
71
72static unsigned int pid_dbg;
73module_param(pid_dbg, int, 0644);
74MODULE_PARM_DESC(pid_dbg, "Enable PID filtering debugging");
75
76MODULE_DESCRIPTION("altera FPGA CI module");
77MODULE_AUTHOR("Igor M. Liplianin  <liplianin@netup.ru>");
78MODULE_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
94struct altera_ci_state;
95struct netup_hw_pid_filter;
96
97struct 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 */
110struct 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 */
118struct 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 */
130struct 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 */
137static struct fpga_inode *fpga_first_inode;
138
139/* find chip by dev */
140static 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 */
157static 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 */
173static 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 */
198static 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 */
222static 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
249static 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 */
257static 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
292static 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
298static 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
304static 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
311static 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
317static 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
360static int altera_ci_slot_shutdown(struct dvb_ca_en50221 *en50221, int slot)
361{
362	/* not implemented */
363	return 0;
364}
365
366static 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 */
389static 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 */
424int 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}
441EXPORT_SYMBOL(altera_ci_irq);
442
443static 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
454static 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
482void 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}
512EXPORT_SYMBOL(altera_ci_release);
513
514static 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
545static 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
575static 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
596static 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
603static 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
610static int altera_ci_start_feed_1(struct dvb_demux_feed *feed)
611{
612	return altera_ci_start_feed(feed, 1);
613}
614
615static int altera_ci_stop_feed_1(struct dvb_demux_feed *feed)
616{
617	return altera_ci_stop_feed(feed, 1);
618}
619
620static int altera_ci_start_feed_2(struct dvb_demux_feed *feed)
621{
622	return altera_ci_start_feed(feed, 2);
623}
624
625static int altera_ci_stop_feed_2(struct dvb_demux_feed *feed)
626{
627	return altera_ci_stop_feed(feed, 2);
628}
629
630static 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;
691err:
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
701int 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;
799err:
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}
807EXPORT_SYMBOL(altera_ci_init);
808
809int 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}
838EXPORT_SYMBOL(altera_ci_tuner_reset);
839