4 * DVB CAM support for NetUP Universal Dual DVB-CI
6 * Copyright (C) 2014 NetUP Inc.
7 * Copyright (C) 2014 Sergey Kozlov <serjk@netup.ru>
8 * Copyright (C) 2014 Abylay Ospan <aospan@netup.ru>
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
21 #include <linux/init.h>
22 #include <linux/module.h>
23 #include <linux/moduleparam.h>
24 #include <linux/kmod.h>
25 #include <linux/kernel.h>
26 #include <linux/slab.h>
27 #include <linux/interrupt.h>
28 #include <linux/delay.h>
29 #include "netup_unidvb.h"
31 /* CI slot 0 base address */
32 #define CAM0_CONFIG 0x0
33 #define CAM0_IO 0x8000
34 #define CAM0_MEM 0x10000
36 /* CI slot 1 base address */
37 #define CAM1_CONFIG 0x20000
38 #define CAM1_IO 0x28000
39 #define CAM1_MEM 0x30000
41 /* ctrlstat registers */
42 #define CAM_CTRLSTAT_READ_SET 0x4980
43 #define CAM_CTRLSTAT_CLR 0x4982
45 #define BIT_CAM_STCHG (1<<0)
46 #define BIT_CAM_PRESENT (1<<1)
47 #define BIT_CAM_RESET (1<<2)
48 #define BIT_CAM_BYPASS (1<<3)
49 #define BIT_CAM_READY (1<<4)
50 #define BIT_CAM_ERROR (1<<5)
51 #define BIT_CAM_OVERCURR (1<<6)
52 /* BIT_CAM_BYPASS bit shift for SLOT 1 */
55 irqreturn_t
netup_ci_interrupt(struct netup_unidvb_dev
*ndev
)
57 writew(0x101, ndev
->bmmio0
+ CAM_CTRLSTAT_CLR
);
61 static int netup_unidvb_ci_slot_ts_ctl(struct dvb_ca_en50221
*en50221
,
64 struct netup_ci_state
*state
= en50221
->data
;
65 struct netup_unidvb_dev
*dev
= state
->dev
;
66 u16 shift
= (state
->nr
== 1) ? CAM1_SHIFT
: 0;
68 dev_dbg(&dev
->pci_dev
->dev
, "%s(): CAM_CTRLSTAT=0x%x\n",
69 __func__
, readw(dev
->bmmio0
+ CAM_CTRLSTAT_READ_SET
));
72 /* pass data to CAM module */
73 writew(BIT_CAM_BYPASS
<< shift
, dev
->bmmio0
+ CAM_CTRLSTAT_CLR
);
74 dev_dbg(&dev
->pci_dev
->dev
, "%s(): CAM_CTRLSTAT=0x%x done\n",
75 __func__
, readw(dev
->bmmio0
+ CAM_CTRLSTAT_READ_SET
));
79 static int netup_unidvb_ci_slot_shutdown(struct dvb_ca_en50221
*en50221
,
82 struct netup_ci_state
*state
= en50221
->data
;
83 struct netup_unidvb_dev
*dev
= state
->dev
;
85 dev_dbg(&dev
->pci_dev
->dev
, "%s()\n", __func__
);
89 static int netup_unidvb_ci_slot_reset(struct dvb_ca_en50221
*en50221
,
92 struct netup_ci_state
*state
= en50221
->data
;
93 struct netup_unidvb_dev
*dev
= state
->dev
;
94 unsigned long timeout
= 0;
95 u16 shift
= (state
->nr
== 1) ? CAM1_SHIFT
: 0;
97 int reset_counter
= 3;
99 dev_dbg(&dev
->pci_dev
->dev
, "%s(): CAM_CTRLSTAT_READ_SET=0x%x\n",
100 __func__
, readw(dev
->bmmio0
+ CAM_CTRLSTAT_READ_SET
));
102 timeout
= jiffies
+ msecs_to_jiffies(5000);
104 writew(BIT_CAM_RESET
<< shift
, dev
->bmmio0
+ CAM_CTRLSTAT_READ_SET
);
105 dev_dbg(&dev
->pci_dev
->dev
, "%s(): waiting for reset\n", __func__
);
106 /* wait until reset done */
107 while (time_before(jiffies
, timeout
)) {
108 ci_stat
= readw(dev
->bmmio0
+ CAM_CTRLSTAT_READ_SET
);
109 if (ci_stat
& (BIT_CAM_READY
<< shift
))
113 if (!(ci_stat
& (BIT_CAM_READY
<< shift
)) && reset_counter
> 0) {
114 dev_dbg(&dev
->pci_dev
->dev
,
115 "%s(): CAMP reset timeout! Will try again..\n",
123 static int netup_unidvb_poll_ci_slot_status(struct dvb_ca_en50221
*en50221
,
126 struct netup_ci_state
*state
= en50221
->data
;
127 struct netup_unidvb_dev
*dev
= state
->dev
;
128 u16 shift
= (state
->nr
== 1) ? CAM1_SHIFT
: 0;
131 dev_dbg(&dev
->pci_dev
->dev
, "%s(): CAM_CTRLSTAT_READ_SET=0x%x\n",
132 __func__
, readw(dev
->bmmio0
+ CAM_CTRLSTAT_READ_SET
));
133 ci_stat
= readw(dev
->bmmio0
+ CAM_CTRLSTAT_READ_SET
);
134 if (ci_stat
& (BIT_CAM_READY
<< shift
)) {
135 state
->status
= DVB_CA_EN50221_POLL_CAM_PRESENT
|
136 DVB_CA_EN50221_POLL_CAM_READY
;
137 } else if (ci_stat
& (BIT_CAM_PRESENT
<< shift
)) {
138 state
->status
= DVB_CA_EN50221_POLL_CAM_PRESENT
;
142 return state
->status
;
145 static int netup_unidvb_ci_read_attribute_mem(struct dvb_ca_en50221
*en50221
,
148 struct netup_ci_state
*state
= en50221
->data
;
149 struct netup_unidvb_dev
*dev
= state
->dev
;
150 u8 val
= *((u8 __force
*)state
->membase8_config
+ addr
);
152 dev_dbg(&dev
->pci_dev
->dev
,
153 "%s(): addr=0x%x val=0x%x\n", __func__
, addr
, val
);
157 static int netup_unidvb_ci_write_attribute_mem(struct dvb_ca_en50221
*en50221
,
158 int slot
, int addr
, u8 data
)
160 struct netup_ci_state
*state
= en50221
->data
;
161 struct netup_unidvb_dev
*dev
= state
->dev
;
163 dev_dbg(&dev
->pci_dev
->dev
,
164 "%s(): addr=0x%x data=0x%x\n", __func__
, addr
, data
);
165 *((u8 __force
*)state
->membase8_config
+ addr
) = data
;
169 static int netup_unidvb_ci_read_cam_ctl(struct dvb_ca_en50221
*en50221
,
172 struct netup_ci_state
*state
= en50221
->data
;
173 struct netup_unidvb_dev
*dev
= state
->dev
;
174 u8 val
= *((u8 __force
*)state
->membase8_io
+ addr
);
176 dev_dbg(&dev
->pci_dev
->dev
,
177 "%s(): addr=0x%x val=0x%x\n", __func__
, addr
, val
);
181 static int netup_unidvb_ci_write_cam_ctl(struct dvb_ca_en50221
*en50221
,
182 int slot
, u8 addr
, u8 data
)
184 struct netup_ci_state
*state
= en50221
->data
;
185 struct netup_unidvb_dev
*dev
= state
->dev
;
187 dev_dbg(&dev
->pci_dev
->dev
,
188 "%s(): addr=0x%x data=0x%x\n", __func__
, addr
, data
);
189 *((u8 __force
*)state
->membase8_io
+ addr
) = data
;
193 int netup_unidvb_ci_register(struct netup_unidvb_dev
*dev
,
194 int num
, struct pci_dev
*pci_dev
)
197 struct netup_ci_state
*state
;
199 if (num
< 0 || num
> 1) {
200 dev_err(&pci_dev
->dev
, "%s(): invalid CI adapter %d\n",
204 state
= &dev
->ci
[num
];
206 state
->membase8_config
= dev
->bmmio1
+
207 ((num
== 0) ? CAM0_CONFIG
: CAM1_CONFIG
);
208 state
->membase8_io
= dev
->bmmio1
+
209 ((num
== 0) ? CAM0_IO
: CAM1_IO
);
211 state
->ca
.owner
= THIS_MODULE
;
212 state
->ca
.read_attribute_mem
= netup_unidvb_ci_read_attribute_mem
;
213 state
->ca
.write_attribute_mem
= netup_unidvb_ci_write_attribute_mem
;
214 state
->ca
.read_cam_control
= netup_unidvb_ci_read_cam_ctl
;
215 state
->ca
.write_cam_control
= netup_unidvb_ci_write_cam_ctl
;
216 state
->ca
.slot_reset
= netup_unidvb_ci_slot_reset
;
217 state
->ca
.slot_shutdown
= netup_unidvb_ci_slot_shutdown
;
218 state
->ca
.slot_ts_enable
= netup_unidvb_ci_slot_ts_ctl
;
219 state
->ca
.poll_slot_status
= netup_unidvb_poll_ci_slot_status
;
220 state
->ca
.data
= state
;
221 result
= dvb_ca_en50221_init(&dev
->frontends
[num
].adapter
,
224 dev_err(&pci_dev
->dev
,
225 "%s(): dvb_ca_en50221_init result %d\n",
229 writew(NETUP_UNIDVB_IRQ_CI
, dev
->bmmio0
+ REG_IMASK_SET
);
230 dev_info(&pci_dev
->dev
,
231 "%s(): CI adapter %d init done\n", __func__
, num
);
235 void netup_unidvb_ci_unregister(struct netup_unidvb_dev
*dev
, int num
)
237 struct netup_ci_state
*state
;
239 dev_dbg(&dev
->pci_dev
->dev
, "%s()\n", __func__
);
240 if (num
< 0 || num
> 1) {
241 dev_err(&dev
->pci_dev
->dev
, "%s(): invalid CI adapter %d\n",
245 state
= &dev
->ci
[num
];
246 dvb_ca_en50221_release(&state
->ca
);