xref: /linux/drivers/media/pci/cx23885/cimax2.c (revision c532de5a67a70f8533d495f8f2aaa9a0491c3ad0)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * cimax2.c
4  *
5  * CIMax2(R) SP2 driver in conjunction with NetUp Dual DVB-S2 CI card
6  *
7  * Copyright (C) 2009 NetUP Inc.
8  * Copyright (C) 2009 Igor M. Liplianin <liplianin@netup.ru>
9  * Copyright (C) 2009 Abylay Ospan <aospan@netup.ru>
10  */
11 
12 #include "cx23885.h"
13 #include "cimax2.h"
14 #include <media/dvb_ca_en50221.h>
15 
16 /* Max transfer size done by I2C transfer functions */
17 #define MAX_XFER_SIZE  64
18 
19 /**** Bit definitions for MC417_RWD and MC417_OEN registers  ***
20   bits 31-16
21 +-----------+
22 | Reserved  |
23 +-----------+
24   bit 15  bit 14  bit 13 bit 12  bit 11  bit 10  bit 9   bit 8
25 +-------+-------+-------+-------+-------+-------+-------+-------+
26 |  WR#  |  RD#  |       |  ACK# |  ADHI |  ADLO |  CS1# |  CS0# |
27 +-------+-------+-------+-------+-------+-------+-------+-------+
28  bit 7   bit 6   bit 5   bit 4   bit 3   bit 2   bit 1   bit 0
29 +-------+-------+-------+-------+-------+-------+-------+-------+
30 |  DATA7|  DATA6|  DATA5|  DATA4|  DATA3|  DATA2|  DATA1|  DATA0|
31 +-------+-------+-------+-------+-------+-------+-------+-------+
32 ***/
33 /* MC417 */
34 #define NETUP_DATA		0x000000ff
35 #define NETUP_WR		0x00008000
36 #define NETUP_RD		0x00004000
37 #define NETUP_ACK		0x00001000
38 #define NETUP_ADHI		0x00000800
39 #define NETUP_ADLO		0x00000400
40 #define NETUP_CS1		0x00000200
41 #define NETUP_CS0		0x00000100
42 #define NETUP_EN_ALL		0x00001000
43 #define NETUP_CTRL_OFF		(NETUP_CS1 | NETUP_CS0 | NETUP_WR | NETUP_RD)
44 #define NETUP_CI_CTL		0x04
45 #define NETUP_CI_RD		1
46 
47 #define NETUP_IRQ_DETAM		0x1
48 #define NETUP_IRQ_IRQAM		0x4
49 
50 static unsigned int ci_dbg;
51 module_param(ci_dbg, int, 0644);
52 MODULE_PARM_DESC(ci_dbg, "Enable CI debugging");
53 
54 static unsigned int ci_irq_enable;
55 module_param(ci_irq_enable, int, 0644);
56 MODULE_PARM_DESC(ci_irq_enable, "Enable IRQ from CAM");
57 
58 #define ci_dbg_print(fmt, args...) \
59 	do { \
60 		if (ci_dbg) \
61 			printk(KERN_DEBUG pr_fmt("%s: " fmt), \
62 			       __func__, ##args); \
63 	} while (0)
64 
65 #define ci_irq_flags() (ci_irq_enable ? NETUP_IRQ_IRQAM : 0)
66 
67 /* stores all private variables for communication with CI */
68 struct netup_ci_state {
69 	struct dvb_ca_en50221 ca;
70 	struct mutex ca_mutex;
71 	struct i2c_adapter *i2c_adap;
72 	u8 ci_i2c_addr;
73 	int status;
74 	struct work_struct work;
75 	void *priv;
76 	u8 current_irq_mode;
77 	int current_ci_flag;
78 	unsigned long next_status_checked_time;
79 };
80 
81 
82 static int netup_read_i2c(struct i2c_adapter *i2c_adap, u8 addr, u8 reg,
83 						u8 *buf, int len)
84 {
85 	int ret;
86 	struct i2c_msg msg[] = {
87 		{
88 			.addr	= addr,
89 			.flags	= 0,
90 			.buf	= &reg,
91 			.len	= 1
92 		}, {
93 			.addr	= addr,
94 			.flags	= I2C_M_RD,
95 			.buf	= buf,
96 			.len	= len
97 		}
98 	};
99 
100 	ret = i2c_transfer(i2c_adap, msg, 2);
101 
102 	if (ret != 2) {
103 		ci_dbg_print("%s: i2c read error, Reg = 0x%02x, Status = %d\n",
104 						__func__, reg, ret);
105 
106 		return -1;
107 	}
108 
109 	ci_dbg_print("%s: i2c read Addr=0x%04x, Reg = 0x%02x, data = %02x\n",
110 						__func__, addr, reg, buf[0]);
111 
112 	return 0;
113 }
114 
115 static int netup_write_i2c(struct i2c_adapter *i2c_adap, u8 addr, u8 reg,
116 						u8 *buf, int len)
117 {
118 	int ret;
119 	u8 buffer[MAX_XFER_SIZE];
120 
121 	struct i2c_msg msg = {
122 		.addr	= addr,
123 		.flags	= 0,
124 		.buf	= &buffer[0],
125 		.len	= len + 1
126 	};
127 
128 	if (1 + len > sizeof(buffer)) {
129 		pr_warn("%s: i2c wr reg=%04x: len=%d is too big!\n",
130 		       KBUILD_MODNAME, reg, len);
131 		return -EINVAL;
132 	}
133 
134 	buffer[0] = reg;
135 	memcpy(&buffer[1], buf, len);
136 
137 	ret = i2c_transfer(i2c_adap, &msg, 1);
138 
139 	if (ret != 1) {
140 		ci_dbg_print("%s: i2c write error, Reg=[0x%02x], Status=%d\n",
141 						__func__, reg, ret);
142 		return -1;
143 	}
144 
145 	return 0;
146 }
147 
148 static int netup_ci_get_mem(struct cx23885_dev *dev)
149 {
150 	int mem;
151 	unsigned long timeout = jiffies + msecs_to_jiffies(1);
152 
153 	for (;;) {
154 		mem = cx_read(MC417_RWD);
155 		if ((mem & NETUP_ACK) == 0)
156 			break;
157 		if (time_after(jiffies, timeout))
158 			break;
159 		udelay(1);
160 	}
161 
162 	cx_set(MC417_RWD, NETUP_CTRL_OFF);
163 
164 	return mem & 0xff;
165 }
166 
167 static int netup_ci_op_cam(struct dvb_ca_en50221 *en50221, int slot,
168 				u8 flag, u8 read, int addr, u8 data)
169 {
170 	struct netup_ci_state *state = en50221->data;
171 	struct cx23885_tsport *port = state->priv;
172 	struct cx23885_dev *dev = port->dev;
173 
174 	u8 store;
175 	int mem;
176 	int ret;
177 
178 	if (0 != slot)
179 		return -EINVAL;
180 
181 	if (state->current_ci_flag != flag) {
182 		ret = netup_read_i2c(state->i2c_adap, state->ci_i2c_addr,
183 				0, &store, 1);
184 		if (ret != 0)
185 			return ret;
186 
187 		store &= ~0x0c;
188 		store |= flag;
189 
190 		ret = netup_write_i2c(state->i2c_adap, state->ci_i2c_addr,
191 				0, &store, 1);
192 		if (ret != 0)
193 			return ret;
194 	}
195 	state->current_ci_flag = flag;
196 
197 	mutex_lock(&dev->gpio_lock);
198 
199 	/* write addr */
200 	cx_write(MC417_OEN, NETUP_EN_ALL);
201 	cx_write(MC417_RWD, NETUP_CTRL_OFF |
202 				NETUP_ADLO | (0xff & addr));
203 	cx_clear(MC417_RWD, NETUP_ADLO);
204 	cx_write(MC417_RWD, NETUP_CTRL_OFF |
205 				NETUP_ADHI | (0xff & (addr >> 8)));
206 	cx_clear(MC417_RWD, NETUP_ADHI);
207 
208 	if (read) { /* data in */
209 		cx_write(MC417_OEN, NETUP_EN_ALL | NETUP_DATA);
210 	} else /* data out */
211 		cx_write(MC417_RWD, NETUP_CTRL_OFF | data);
212 
213 	/* choose chip */
214 	cx_clear(MC417_RWD,
215 			(state->ci_i2c_addr == 0x40) ? NETUP_CS0 : NETUP_CS1);
216 	/* read/write */
217 	cx_clear(MC417_RWD, (read) ? NETUP_RD : NETUP_WR);
218 	mem = netup_ci_get_mem(dev);
219 
220 	mutex_unlock(&dev->gpio_lock);
221 
222 	if (!read)
223 		if (mem < 0)
224 			return -EREMOTEIO;
225 
226 	ci_dbg_print("%s: %s: chipaddr=[0x%x] addr=[0x%02x], %s=%x\n", __func__,
227 			(read) ? "read" : "write", state->ci_i2c_addr, addr,
228 			(flag == NETUP_CI_CTL) ? "ctl" : "mem",
229 			(read) ? mem : data);
230 
231 	if (read)
232 		return mem;
233 
234 	return 0;
235 }
236 
237 int netup_ci_read_attribute_mem(struct dvb_ca_en50221 *en50221,
238 						int slot, int addr)
239 {
240 	return netup_ci_op_cam(en50221, slot, 0, NETUP_CI_RD, addr, 0);
241 }
242 
243 int netup_ci_write_attribute_mem(struct dvb_ca_en50221 *en50221,
244 						int slot, int addr, u8 data)
245 {
246 	return netup_ci_op_cam(en50221, slot, 0, 0, addr, data);
247 }
248 
249 int netup_ci_read_cam_ctl(struct dvb_ca_en50221 *en50221, int slot,
250 				 u8 addr)
251 {
252 	return netup_ci_op_cam(en50221, slot, NETUP_CI_CTL,
253 							NETUP_CI_RD, addr, 0);
254 }
255 
256 int netup_ci_write_cam_ctl(struct dvb_ca_en50221 *en50221, int slot,
257 							u8 addr, u8 data)
258 {
259 	return netup_ci_op_cam(en50221, slot, NETUP_CI_CTL, 0, addr, data);
260 }
261 
262 int netup_ci_slot_reset(struct dvb_ca_en50221 *en50221, int slot)
263 {
264 	struct netup_ci_state *state = en50221->data;
265 	u8 buf =  0x80;
266 	int ret;
267 
268 	if (0 != slot)
269 		return -EINVAL;
270 
271 	udelay(500);
272 	ret = netup_write_i2c(state->i2c_adap, state->ci_i2c_addr,
273 							0, &buf, 1);
274 
275 	if (ret != 0)
276 		return ret;
277 
278 	udelay(500);
279 
280 	buf = 0x00;
281 	ret = netup_write_i2c(state->i2c_adap, state->ci_i2c_addr,
282 							0, &buf, 1);
283 
284 	msleep(1000);
285 	dvb_ca_en50221_camready_irq(&state->ca, 0);
286 
287 	return 0;
288 
289 }
290 
291 int netup_ci_slot_shutdown(struct dvb_ca_en50221 *en50221, int slot)
292 {
293 	/* not implemented */
294 	return 0;
295 }
296 
297 static int netup_ci_set_irq(struct dvb_ca_en50221 *en50221, u8 irq_mode)
298 {
299 	struct netup_ci_state *state = en50221->data;
300 	int ret;
301 
302 	if (irq_mode == state->current_irq_mode)
303 		return 0;
304 
305 	ci_dbg_print("%s: chipaddr=[0x%x] setting ci IRQ to [0x%x] \n",
306 			__func__, state->ci_i2c_addr, irq_mode);
307 	ret = netup_write_i2c(state->i2c_adap, state->ci_i2c_addr,
308 							0x1b, &irq_mode, 1);
309 
310 	if (ret != 0)
311 		return ret;
312 
313 	state->current_irq_mode = irq_mode;
314 
315 	return 0;
316 }
317 
318 int netup_ci_slot_ts_ctl(struct dvb_ca_en50221 *en50221, int slot)
319 {
320 	struct netup_ci_state *state = en50221->data;
321 	u8 buf;
322 
323 	if (0 != slot)
324 		return -EINVAL;
325 
326 	netup_read_i2c(state->i2c_adap, state->ci_i2c_addr,
327 			0, &buf, 1);
328 	buf |= 0x60;
329 
330 	return netup_write_i2c(state->i2c_adap, state->ci_i2c_addr,
331 							0, &buf, 1);
332 }
333 
334 /* work handler */
335 static void netup_read_ci_status(struct work_struct *work)
336 {
337 	struct netup_ci_state *state =
338 			container_of(work, struct netup_ci_state, work);
339 	u8 buf[33];
340 	int ret;
341 
342 	/* CAM module IRQ processing. fast operation */
343 	dvb_ca_en50221_frda_irq(&state->ca, 0);
344 
345 	/* CAM module INSERT/REMOVE processing. slow operation because of i2c
346 	 * transfers */
347 	if (time_after(jiffies, state->next_status_checked_time)
348 			|| !state->status) {
349 		ret = netup_read_i2c(state->i2c_adap, state->ci_i2c_addr,
350 				0, &buf[0], 33);
351 
352 		state->next_status_checked_time = jiffies
353 			+ msecs_to_jiffies(1000);
354 
355 		if (ret != 0)
356 			return;
357 
358 		ci_dbg_print("%s: Slot Status Addr=[0x%04x], Reg=[0x%02x], data=%02x, TS config = %02x\n",
359 			     __func__,	state->ci_i2c_addr, 0, buf[0], buf[0]);
360 
361 
362 		if (buf[0] & 1)
363 			state->status = DVB_CA_EN50221_POLL_CAM_PRESENT |
364 				DVB_CA_EN50221_POLL_CAM_READY;
365 		else
366 			state->status = 0;
367 	}
368 }
369 
370 /* CI irq handler */
371 int netup_ci_slot_status(struct cx23885_dev *dev, u32 pci_status)
372 {
373 	struct cx23885_tsport *port = NULL;
374 	struct netup_ci_state *state = NULL;
375 
376 	ci_dbg_print("%s:\n", __func__);
377 
378 	if (0 == (pci_status & (PCI_MSK_GPIO0 | PCI_MSK_GPIO1)))
379 		return 0;
380 
381 	if (pci_status & PCI_MSK_GPIO0) {
382 		port = &dev->ts1;
383 		state = port->port_priv;
384 		schedule_work(&state->work);
385 		ci_dbg_print("%s: Wakeup CI0\n", __func__);
386 	}
387 
388 	if (pci_status & PCI_MSK_GPIO1) {
389 		port = &dev->ts2;
390 		state = port->port_priv;
391 		schedule_work(&state->work);
392 		ci_dbg_print("%s: Wakeup CI1\n", __func__);
393 	}
394 
395 	return 1;
396 }
397 
398 int netup_poll_ci_slot_status(struct dvb_ca_en50221 *en50221,
399 				     int slot, int open)
400 {
401 	struct netup_ci_state *state = en50221->data;
402 
403 	if (0 != slot)
404 		return -EINVAL;
405 
406 	netup_ci_set_irq(en50221, open ? (NETUP_IRQ_DETAM | ci_irq_flags())
407 			: NETUP_IRQ_DETAM);
408 
409 	return state->status;
410 }
411 
412 int netup_ci_init(struct cx23885_tsport *port)
413 {
414 	struct netup_ci_state *state;
415 	u8 cimax_init[34] = {
416 		0x00, /* module A control*/
417 		0x00, /* auto select mask high A */
418 		0x00, /* auto select mask low A */
419 		0x00, /* auto select pattern high A */
420 		0x00, /* auto select pattern low A */
421 		0x44, /* memory access time A */
422 		0x00, /* invert input A */
423 		0x00, /* RFU */
424 		0x00, /* RFU */
425 		0x00, /* module B control*/
426 		0x00, /* auto select mask high B */
427 		0x00, /* auto select mask low B */
428 		0x00, /* auto select pattern high B */
429 		0x00, /* auto select pattern low B */
430 		0x44, /* memory access time B */
431 		0x00, /* invert input B */
432 		0x00, /* RFU */
433 		0x00, /* RFU */
434 		0x00, /* auto select mask high Ext */
435 		0x00, /* auto select mask low Ext */
436 		0x00, /* auto select pattern high Ext */
437 		0x00, /* auto select pattern low Ext */
438 		0x00, /* RFU */
439 		0x02, /* destination - module A */
440 		0x01, /* power on (use it like store place) */
441 		0x00, /* RFU */
442 		0x00, /* int status read only */
443 		ci_irq_flags() | NETUP_IRQ_DETAM, /* DETAM, IRQAM unmasked */
444 		0x05, /* EXTINT=active-high, INT=push-pull */
445 		0x00, /* USCG1 */
446 		0x04, /* ack active low */
447 		0x00, /* LOCK = 0 */
448 		0x33, /* serial mode, rising in, rising out, MSB first*/
449 		0x31, /* synchronization */
450 	};
451 	int ret;
452 
453 	ci_dbg_print("%s\n", __func__);
454 	state = kzalloc(sizeof(struct netup_ci_state), GFP_KERNEL);
455 	if (!state) {
456 		ci_dbg_print("%s: Unable create CI structure!\n", __func__);
457 		ret = -ENOMEM;
458 		goto err;
459 	}
460 
461 	port->port_priv = state;
462 
463 	switch (port->nr) {
464 	case 1:
465 		state->ci_i2c_addr = 0x40;
466 		break;
467 	case 2:
468 		state->ci_i2c_addr = 0x41;
469 		break;
470 	}
471 
472 	state->i2c_adap = &port->dev->i2c_bus[0].i2c_adap;
473 	state->ca.owner = THIS_MODULE;
474 	state->ca.read_attribute_mem = netup_ci_read_attribute_mem;
475 	state->ca.write_attribute_mem = netup_ci_write_attribute_mem;
476 	state->ca.read_cam_control = netup_ci_read_cam_ctl;
477 	state->ca.write_cam_control = netup_ci_write_cam_ctl;
478 	state->ca.slot_reset = netup_ci_slot_reset;
479 	state->ca.slot_shutdown = netup_ci_slot_shutdown;
480 	state->ca.slot_ts_enable = netup_ci_slot_ts_ctl;
481 	state->ca.poll_slot_status = netup_poll_ci_slot_status;
482 	state->ca.data = state;
483 	state->priv = port;
484 	state->current_irq_mode = ci_irq_flags() | NETUP_IRQ_DETAM;
485 
486 	ret = netup_write_i2c(state->i2c_adap, state->ci_i2c_addr,
487 						0, &cimax_init[0], 34);
488 	/* lock registers */
489 	ret |= netup_write_i2c(state->i2c_adap, state->ci_i2c_addr,
490 						0x1f, &cimax_init[0x18], 1);
491 	/* power on slots */
492 	ret |= netup_write_i2c(state->i2c_adap, state->ci_i2c_addr,
493 						0x18, &cimax_init[0x18], 1);
494 
495 	if (0 != ret)
496 		goto err;
497 
498 	ret = dvb_ca_en50221_init(&port->frontends.adapter,
499 				   &state->ca,
500 				   /* flags */ 0,
501 				   /* n_slots */ 1);
502 	if (0 != ret)
503 		goto err;
504 
505 	INIT_WORK(&state->work, netup_read_ci_status);
506 	schedule_work(&state->work);
507 
508 	ci_dbg_print("%s: CI initialized!\n", __func__);
509 
510 	return 0;
511 err:
512 	ci_dbg_print("%s: Cannot initialize CI: Error %d.\n", __func__, ret);
513 	kfree(state);
514 	return ret;
515 }
516 
517 void netup_ci_exit(struct cx23885_tsport *port)
518 {
519 	struct netup_ci_state *state;
520 
521 	if (NULL == port)
522 		return;
523 
524 	state = (struct netup_ci_state *)port->port_priv;
525 	if (NULL == state)
526 		return;
527 
528 	if (NULL == state->ca.data)
529 		return;
530 
531 	dvb_ca_en50221_release(&state->ca);
532 	kfree(state);
533 }
534