GNU Linux-libre 5.19-rc6-gnu
[releases.git] / drivers / media / pci / netup_unidvb / netup_unidvb_ci.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * netup_unidvb_ci.c
4  *
5  * DVB CAM support for NetUP Universal Dual DVB-CI
6  *
7  * Copyright (C) 2014 NetUP Inc.
8  * Copyright (C) 2014 Sergey Kozlov <serjk@netup.ru>
9  * Copyright (C) 2014 Abylay Ospan <aospan@netup.ru>
10  */
11
12 #include <linux/init.h>
13 #include <linux/module.h>
14 #include <linux/moduleparam.h>
15 #include <linux/kmod.h>
16 #include <linux/kernel.h>
17 #include <linux/slab.h>
18 #include <linux/interrupt.h>
19 #include <linux/delay.h>
20 #include "netup_unidvb.h"
21
22 /* CI slot 0 base address */
23 #define CAM0_CONFIG             0x0
24 #define CAM0_IO                 0x8000
25 #define CAM0_MEM                0x10000
26 #define CAM0_SZ                 32
27 /* CI slot 1 base address */
28 #define CAM1_CONFIG             0x20000
29 #define CAM1_IO                 0x28000
30 #define CAM1_MEM                0x30000
31 #define CAM1_SZ                 32
32 /* ctrlstat registers */
33 #define CAM_CTRLSTAT_READ_SET   0x4980
34 #define CAM_CTRLSTAT_CLR        0x4982
35 /* register bits */
36 #define BIT_CAM_STCHG           (1<<0)
37 #define BIT_CAM_PRESENT         (1<<1)
38 #define BIT_CAM_RESET           (1<<2)
39 #define BIT_CAM_BYPASS          (1<<3)
40 #define BIT_CAM_READY           (1<<4)
41 #define BIT_CAM_ERROR           (1<<5)
42 #define BIT_CAM_OVERCURR        (1<<6)
43 /* BIT_CAM_BYPASS bit shift for SLOT 1 */
44 #define CAM1_SHIFT 8
45
46 irqreturn_t netup_ci_interrupt(struct netup_unidvb_dev *ndev)
47 {
48         writew(0x101, ndev->bmmio0 + CAM_CTRLSTAT_CLR);
49         return IRQ_HANDLED;
50 }
51
52 static int netup_unidvb_ci_slot_ts_ctl(struct dvb_ca_en50221 *en50221,
53                                        int slot)
54 {
55         struct netup_ci_state *state = en50221->data;
56         struct netup_unidvb_dev *dev = state->dev;
57         u16 shift = (state->nr == 1) ? CAM1_SHIFT : 0;
58
59         dev_dbg(&dev->pci_dev->dev, "%s(): CAM_CTRLSTAT=0x%x\n",
60                 __func__, readw(dev->bmmio0 + CAM_CTRLSTAT_READ_SET));
61         if (slot != 0)
62                 return -EINVAL;
63         /* pass data to CAM module */
64         writew(BIT_CAM_BYPASS << shift, dev->bmmio0 + CAM_CTRLSTAT_CLR);
65         dev_dbg(&dev->pci_dev->dev, "%s(): CAM_CTRLSTAT=0x%x done\n",
66                 __func__, readw(dev->bmmio0 + CAM_CTRLSTAT_READ_SET));
67         return 0;
68 }
69
70 static int netup_unidvb_ci_slot_shutdown(struct dvb_ca_en50221 *en50221,
71                                          int slot)
72 {
73         struct netup_ci_state *state = en50221->data;
74         struct netup_unidvb_dev *dev = state->dev;
75
76         dev_dbg(&dev->pci_dev->dev, "%s()\n", __func__);
77         return 0;
78 }
79
80 static int netup_unidvb_ci_slot_reset(struct dvb_ca_en50221 *en50221,
81                                       int slot)
82 {
83         struct netup_ci_state *state = en50221->data;
84         struct netup_unidvb_dev *dev = state->dev;
85         unsigned long timeout = 0;
86         u16 shift = (state->nr == 1) ? CAM1_SHIFT : 0;
87         u16 ci_stat = 0;
88         int reset_counter = 3;
89
90         dev_dbg(&dev->pci_dev->dev, "%s(): CAM_CTRLSTAT_READ_SET=0x%x\n",
91                 __func__, readw(dev->bmmio0 + CAM_CTRLSTAT_READ_SET));
92 reset:
93         timeout = jiffies + msecs_to_jiffies(5000);
94         /* start reset */
95         writew(BIT_CAM_RESET << shift, dev->bmmio0 + CAM_CTRLSTAT_READ_SET);
96         dev_dbg(&dev->pci_dev->dev, "%s(): waiting for reset\n", __func__);
97         /* wait until reset done */
98         while (time_before(jiffies, timeout)) {
99                 ci_stat = readw(dev->bmmio0 + CAM_CTRLSTAT_READ_SET);
100                 if (ci_stat & (BIT_CAM_READY << shift))
101                         break;
102                 udelay(1000);
103         }
104         if (!(ci_stat & (BIT_CAM_READY << shift)) && reset_counter > 0) {
105                 dev_dbg(&dev->pci_dev->dev,
106                         "%s(): CAMP reset timeout! Will try again..\n",
107                          __func__);
108                 reset_counter--;
109                 goto reset;
110         }
111         return 0;
112 }
113
114 static int netup_unidvb_poll_ci_slot_status(struct dvb_ca_en50221 *en50221,
115                                             int slot, int open)
116 {
117         struct netup_ci_state *state = en50221->data;
118         struct netup_unidvb_dev *dev = state->dev;
119         u16 shift = (state->nr == 1) ? CAM1_SHIFT : 0;
120         u16 ci_stat = 0;
121
122         dev_dbg(&dev->pci_dev->dev, "%s(): CAM_CTRLSTAT_READ_SET=0x%x\n",
123                 __func__, readw(dev->bmmio0 + CAM_CTRLSTAT_READ_SET));
124         ci_stat = readw(dev->bmmio0 + CAM_CTRLSTAT_READ_SET);
125         if (ci_stat & (BIT_CAM_READY << shift)) {
126                 state->status = DVB_CA_EN50221_POLL_CAM_PRESENT |
127                         DVB_CA_EN50221_POLL_CAM_READY;
128         } else if (ci_stat & (BIT_CAM_PRESENT << shift)) {
129                 state->status = DVB_CA_EN50221_POLL_CAM_PRESENT;
130         } else {
131                 state->status = 0;
132         }
133         return state->status;
134 }
135
136 static int netup_unidvb_ci_read_attribute_mem(struct dvb_ca_en50221 *en50221,
137                                               int slot, int addr)
138 {
139         struct netup_ci_state *state = en50221->data;
140         struct netup_unidvb_dev *dev = state->dev;
141         u8 val = *((u8 __force *)state->membase8_config + addr);
142
143         dev_dbg(&dev->pci_dev->dev,
144                 "%s(): addr=0x%x val=0x%x\n", __func__, addr, val);
145         return val;
146 }
147
148 static int netup_unidvb_ci_write_attribute_mem(struct dvb_ca_en50221 *en50221,
149                                                int slot, int addr, u8 data)
150 {
151         struct netup_ci_state *state = en50221->data;
152         struct netup_unidvb_dev *dev = state->dev;
153
154         dev_dbg(&dev->pci_dev->dev,
155                 "%s(): addr=0x%x data=0x%x\n", __func__, addr, data);
156         *((u8 __force *)state->membase8_config + addr) = data;
157         return 0;
158 }
159
160 static int netup_unidvb_ci_read_cam_ctl(struct dvb_ca_en50221 *en50221,
161                                         int slot, u8 addr)
162 {
163         struct netup_ci_state *state = en50221->data;
164         struct netup_unidvb_dev *dev = state->dev;
165         u8 val = *((u8 __force *)state->membase8_io + addr);
166
167         dev_dbg(&dev->pci_dev->dev,
168                 "%s(): addr=0x%x val=0x%x\n", __func__, addr, val);
169         return val;
170 }
171
172 static int netup_unidvb_ci_write_cam_ctl(struct dvb_ca_en50221 *en50221,
173                                          int slot, u8 addr, u8 data)
174 {
175         struct netup_ci_state *state = en50221->data;
176         struct netup_unidvb_dev *dev = state->dev;
177
178         dev_dbg(&dev->pci_dev->dev,
179                 "%s(): addr=0x%x data=0x%x\n", __func__, addr, data);
180         *((u8 __force *)state->membase8_io + addr) = data;
181         return 0;
182 }
183
184 int netup_unidvb_ci_register(struct netup_unidvb_dev *dev,
185                              int num, struct pci_dev *pci_dev)
186 {
187         int result;
188         struct netup_ci_state *state;
189
190         if (num < 0 || num > 1) {
191                 dev_err(&pci_dev->dev, "%s(): invalid CI adapter %d\n",
192                         __func__, num);
193                 return -EINVAL;
194         }
195         state = &dev->ci[num];
196         state->nr = num;
197         state->membase8_config = dev->bmmio1 +
198                 ((num == 0) ? CAM0_CONFIG : CAM1_CONFIG);
199         state->membase8_io = dev->bmmio1 +
200                 ((num == 0) ? CAM0_IO : CAM1_IO);
201         state->dev = dev;
202         state->ca.owner = THIS_MODULE;
203         state->ca.read_attribute_mem = netup_unidvb_ci_read_attribute_mem;
204         state->ca.write_attribute_mem = netup_unidvb_ci_write_attribute_mem;
205         state->ca.read_cam_control = netup_unidvb_ci_read_cam_ctl;
206         state->ca.write_cam_control = netup_unidvb_ci_write_cam_ctl;
207         state->ca.slot_reset = netup_unidvb_ci_slot_reset;
208         state->ca.slot_shutdown = netup_unidvb_ci_slot_shutdown;
209         state->ca.slot_ts_enable = netup_unidvb_ci_slot_ts_ctl;
210         state->ca.poll_slot_status = netup_unidvb_poll_ci_slot_status;
211         state->ca.data = state;
212         result = dvb_ca_en50221_init(&dev->frontends[num].adapter,
213                 &state->ca, 0, 1);
214         if (result < 0) {
215                 dev_err(&pci_dev->dev,
216                         "%s(): dvb_ca_en50221_init result %d\n",
217                         __func__, result);
218                 return result;
219         }
220         writew(NETUP_UNIDVB_IRQ_CI, dev->bmmio0 + REG_IMASK_SET);
221         dev_info(&pci_dev->dev,
222                 "%s(): CI adapter %d init done\n", __func__, num);
223         return 0;
224 }
225
226 void netup_unidvb_ci_unregister(struct netup_unidvb_dev *dev, int num)
227 {
228         struct netup_ci_state *state;
229
230         dev_dbg(&dev->pci_dev->dev, "%s()\n", __func__);
231         if (num < 0 || num > 1) {
232                 dev_err(&dev->pci_dev->dev, "%s(): invalid CI adapter %d\n",
233                                 __func__, num);
234                 return;
235         }
236         state = &dev->ci[num];
237         dvb_ca_en50221_release(&state->ca);
238 }
239