xref: /linux/drivers/media/pci/ddbridge/ddbridge-max.c (revision c83b49383b595be50647f0c764a48c78b5f3c4f8)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * ddbridge-max.c: Digital Devices bridge MAX card support
4  *
5  * Copyright (C) 2010-2017 Digital Devices GmbH
6  *                         Ralph Metzler <rjkm@metzlerbros.de>
7  *                         Marcus Metzler <mocm@metzlerbros.de>
8  */
9 
10 #include <linux/module.h>
11 #include <linux/init.h>
12 #include <linux/interrupt.h>
13 #include <linux/delay.h>
14 #include <linux/slab.h>
15 #include <linux/poll.h>
16 #include <linux/io.h>
17 #include <linux/pci.h>
18 #include <linux/pci_ids.h>
19 #include <linux/timer.h>
20 #include <linux/i2c.h>
21 #include <linux/swab.h>
22 #include <linux/vmalloc.h>
23 
24 #include "ddbridge.h"
25 #include "ddbridge-regs.h"
26 #include "ddbridge-io.h"
27 #include "ddbridge-mci.h"
28 
29 #include "ddbridge-max.h"
30 #include "mxl5xx.h"
31 
32 /******************************************************************************/
33 
34 /* MaxS4/8 related modparams */
35 static int fmode;
36 module_param(fmode, int, 0444);
37 MODULE_PARM_DESC(fmode, "frontend emulation mode");
38 
39 static int fmode_sat = -1;
40 module_param(fmode_sat, int, 0444);
41 MODULE_PARM_DESC(fmode_sat, "set frontend emulation mode sat");
42 
43 static int old_quattro;
44 module_param(old_quattro, int, 0444);
45 MODULE_PARM_DESC(old_quattro, "old quattro LNB input order ");
46 
47 /******************************************************************************/
48 
49 static int lnb_command(struct ddb *dev, u32 link, u32 lnb, u32 cmd)
50 {
51 	u32 c, v = 0, tag = DDB_LINK_TAG(link);
52 
53 	v = LNB_TONE & (dev->link[link].lnb.tone << (15 - lnb));
54 	ddbwritel(dev, cmd | v, tag | LNB_CONTROL(lnb));
55 	for (c = 0; c < 10; c++) {
56 		v = ddbreadl(dev, tag | LNB_CONTROL(lnb));
57 		if ((v & LNB_BUSY) == 0)
58 			break;
59 		msleep(20);
60 	}
61 	if (c == 10)
62 		dev_info(dev->dev, "%s lnb = %08x  cmd = %08x\n",
63 			 __func__, lnb, cmd);
64 	return 0;
65 }
66 
67 static int max_send_master_cmd(struct dvb_frontend *fe,
68 			       struct dvb_diseqc_master_cmd *cmd)
69 {
70 	struct ddb_input *input = fe->sec_priv;
71 	struct ddb_port *port = input->port;
72 	struct ddb *dev = port->dev;
73 	struct ddb_dvb *dvb = &port->dvb[input->nr & 1];
74 	u32 tag = DDB_LINK_TAG(port->lnr);
75 	int i;
76 	u32 fmode = dev->link[port->lnr].lnb.fmode;
77 
78 	if (fmode == 2 || fmode == 1)
79 		return 0;
80 	if (dvb->diseqc_send_master_cmd)
81 		dvb->diseqc_send_master_cmd(fe, cmd);
82 
83 	mutex_lock(&dev->link[port->lnr].lnb.lock);
84 	ddbwritel(dev, 0, tag | LNB_BUF_LEVEL(dvb->input));
85 	for (i = 0; i < cmd->msg_len; i++)
86 		ddbwritel(dev, cmd->msg[i], tag | LNB_BUF_WRITE(dvb->input));
87 	lnb_command(dev, port->lnr, dvb->input, LNB_CMD_DISEQC);
88 	mutex_unlock(&dev->link[port->lnr].lnb.lock);
89 	return 0;
90 }
91 
92 static int lnb_send_diseqc(struct ddb *dev, u32 link, u32 input,
93 			   struct dvb_diseqc_master_cmd *cmd)
94 {
95 	u32 tag = DDB_LINK_TAG(link);
96 	int i;
97 
98 	ddbwritel(dev, 0, tag | LNB_BUF_LEVEL(input));
99 	for (i = 0; i < cmd->msg_len; i++)
100 		ddbwritel(dev, cmd->msg[i], tag | LNB_BUF_WRITE(input));
101 	lnb_command(dev, link, input, LNB_CMD_DISEQC);
102 	return 0;
103 }
104 
105 static int lnb_set_sat(struct ddb *dev, u32 link, u32 input, u32 sat, u32 band,
106 		       u32 hor)
107 {
108 	struct dvb_diseqc_master_cmd cmd = {
109 		.msg = {0xe0, 0x10, 0x38, 0xf0, 0x00, 0x00},
110 		.msg_len = 4
111 	};
112 	cmd.msg[3] = 0xf0 | (((sat << 2) & 0x0c) | (band ? 1 : 0) |
113 		(hor ? 2 : 0));
114 	return lnb_send_diseqc(dev, link, input, &cmd);
115 }
116 
117 static int lnb_set_tone(struct ddb *dev, u32 link, u32 input,
118 			enum fe_sec_tone_mode tone)
119 {
120 	int s = 0;
121 	u32 mask = (1ULL << input);
122 
123 	switch (tone) {
124 	case SEC_TONE_OFF:
125 		if (!(dev->link[link].lnb.tone & mask))
126 			return 0;
127 		dev->link[link].lnb.tone &= ~(1ULL << input);
128 		break;
129 	case SEC_TONE_ON:
130 		if (dev->link[link].lnb.tone & mask)
131 			return 0;
132 		dev->link[link].lnb.tone |= (1ULL << input);
133 		break;
134 	default:
135 		s = -EINVAL;
136 		break;
137 	}
138 	if (!s)
139 		s = lnb_command(dev, link, input, LNB_CMD_NOP);
140 	return s;
141 }
142 
143 static int lnb_set_voltage(struct ddb *dev, u32 link, u32 input,
144 			   enum fe_sec_voltage voltage)
145 {
146 	int s = 0;
147 
148 	if (dev->link[link].lnb.oldvoltage[input] == voltage)
149 		return 0;
150 	switch (voltage) {
151 	case SEC_VOLTAGE_OFF:
152 		if (dev->link[link].lnb.voltage[input])
153 			return 0;
154 		lnb_command(dev, link, input, LNB_CMD_OFF);
155 		break;
156 	case SEC_VOLTAGE_13:
157 		lnb_command(dev, link, input, LNB_CMD_LOW);
158 		break;
159 	case SEC_VOLTAGE_18:
160 		lnb_command(dev, link, input, LNB_CMD_HIGH);
161 		break;
162 	default:
163 		s = -EINVAL;
164 		break;
165 	}
166 	dev->link[link].lnb.oldvoltage[input] = voltage;
167 	return s;
168 }
169 
170 static int max_set_input_unlocked(struct dvb_frontend *fe, int in)
171 {
172 	struct ddb_input *input = fe->sec_priv;
173 	struct ddb_port *port = input->port;
174 	struct ddb *dev = port->dev;
175 	struct ddb_dvb *dvb = &port->dvb[input->nr & 1];
176 	int res = 0;
177 
178 	if (in > 3)
179 		return -EINVAL;
180 	if (dvb->input != in) {
181 		u32 bit = (1ULL << input->nr);
182 		u32 obit =
183 			dev->link[port->lnr].lnb.voltage[dvb->input & 3] & bit;
184 
185 		dev->link[port->lnr].lnb.voltage[dvb->input & 3] &= ~bit;
186 		dvb->input = in;
187 		dev->link[port->lnr].lnb.voltage[dvb->input & 3] |= obit;
188 	}
189 	res = dvb->set_input(fe, in);
190 	return res;
191 }
192 
193 static int max_set_tone(struct dvb_frontend *fe, enum fe_sec_tone_mode tone)
194 {
195 	struct ddb_input *input = fe->sec_priv;
196 	struct ddb_port *port = input->port;
197 	struct ddb *dev = port->dev;
198 	struct ddb_dvb *dvb = &port->dvb[input->nr & 1];
199 	int tuner = 0;
200 	int res = 0;
201 	u32 fmode = dev->link[port->lnr].lnb.fmode;
202 
203 	mutex_lock(&dev->link[port->lnr].lnb.lock);
204 	dvb->tone = tone;
205 	switch (fmode) {
206 	default:
207 	case 0:
208 	case 3:
209 		res = lnb_set_tone(dev, port->lnr, dvb->input, tone);
210 		break;
211 	case 1:
212 	case 2:
213 		if (old_quattro) {
214 			if (dvb->tone == SEC_TONE_ON)
215 				tuner |= 2;
216 			if (dvb->voltage == SEC_VOLTAGE_18)
217 				tuner |= 1;
218 		} else {
219 			if (dvb->tone == SEC_TONE_ON)
220 				tuner |= 1;
221 			if (dvb->voltage == SEC_VOLTAGE_18)
222 				tuner |= 2;
223 		}
224 		res = max_set_input_unlocked(fe, tuner);
225 		break;
226 	}
227 	mutex_unlock(&dev->link[port->lnr].lnb.lock);
228 	return res;
229 }
230 
231 static int max_set_voltage(struct dvb_frontend *fe, enum fe_sec_voltage voltage)
232 {
233 	struct ddb_input *input = fe->sec_priv;
234 	struct ddb_port *port = input->port;
235 	struct ddb *dev = port->dev;
236 	struct ddb_dvb *dvb = &port->dvb[input->nr & 1];
237 	int tuner = 0;
238 	u32 nv, ov = dev->link[port->lnr].lnb.voltages;
239 	int res = 0;
240 	u32 fmode = dev->link[port->lnr].lnb.fmode;
241 
242 	mutex_lock(&dev->link[port->lnr].lnb.lock);
243 	dvb->voltage = voltage;
244 
245 	switch (fmode) {
246 	case 3:
247 	default:
248 	case 0:
249 		if (fmode == 3)
250 			max_set_input_unlocked(fe, 0);
251 		if (voltage == SEC_VOLTAGE_OFF)
252 			dev->link[port->lnr].lnb.voltage[dvb->input] &=
253 				~(1ULL << input->nr);
254 		else
255 			dev->link[port->lnr].lnb.voltage[dvb->input] |=
256 				(1ULL << input->nr);
257 
258 		res = lnb_set_voltage(dev, port->lnr, dvb->input, voltage);
259 		break;
260 	case 1:
261 	case 2:
262 		if (voltage == SEC_VOLTAGE_OFF)
263 			dev->link[port->lnr].lnb.voltages &=
264 				~(1ULL << input->nr);
265 		else
266 			dev->link[port->lnr].lnb.voltages |=
267 				(1ULL << input->nr);
268 
269 		nv = dev->link[port->lnr].lnb.voltages;
270 
271 		if (old_quattro) {
272 			if (dvb->tone == SEC_TONE_ON)
273 				tuner |= 2;
274 			if (dvb->voltage == SEC_VOLTAGE_18)
275 				tuner |= 1;
276 		} else {
277 			if (dvb->tone == SEC_TONE_ON)
278 				tuner |= 1;
279 			if (dvb->voltage == SEC_VOLTAGE_18)
280 				tuner |= 2;
281 		}
282 		res = max_set_input_unlocked(fe, tuner);
283 
284 		if (nv != ov) {
285 			if (nv) {
286 				lnb_set_voltage(
287 					dev, port->lnr,
288 					0, SEC_VOLTAGE_13);
289 				if (fmode == 1) {
290 					lnb_set_voltage(
291 						dev, port->lnr,
292 						0, SEC_VOLTAGE_13);
293 					if (old_quattro) {
294 						lnb_set_voltage(
295 							dev, port->lnr,
296 							1, SEC_VOLTAGE_18);
297 						lnb_set_voltage(
298 							dev, port->lnr,
299 							2, SEC_VOLTAGE_13);
300 					} else {
301 						lnb_set_voltage(
302 							dev, port->lnr,
303 							1, SEC_VOLTAGE_13);
304 						lnb_set_voltage(
305 							dev, port->lnr,
306 							2, SEC_VOLTAGE_18);
307 					}
308 					lnb_set_voltage(
309 						dev, port->lnr,
310 						3, SEC_VOLTAGE_18);
311 				}
312 			} else {
313 				lnb_set_voltage(
314 					dev, port->lnr,
315 					0, SEC_VOLTAGE_OFF);
316 				if (fmode == 1) {
317 					lnb_set_voltage(
318 						dev, port->lnr,
319 						1, SEC_VOLTAGE_OFF);
320 					lnb_set_voltage(
321 						dev, port->lnr,
322 						2, SEC_VOLTAGE_OFF);
323 					lnb_set_voltage(
324 						dev, port->lnr,
325 						3, SEC_VOLTAGE_OFF);
326 				}
327 			}
328 		}
329 		break;
330 	}
331 	mutex_unlock(&dev->link[port->lnr].lnb.lock);
332 	return res;
333 }
334 
335 static int max_enable_high_lnb_voltage(struct dvb_frontend *fe, long arg)
336 {
337 	return 0;
338 }
339 
340 static int max_send_burst(struct dvb_frontend *fe, enum fe_sec_mini_cmd burst)
341 {
342 	return 0;
343 }
344 
345 static int mxl_fw_read(void *priv, u8 *buf, u32 len)
346 {
347 	struct ddb_link *link = priv;
348 	struct ddb *dev = link->dev;
349 
350 	dev_info(dev->dev, "Read mxl_fw from link %u\n", link->nr);
351 
352 	return ddbridge_flashread(dev, link->nr, buf, 0xc0000, len);
353 }
354 
355 int ddb_lnb_init_fmode(struct ddb *dev, struct ddb_link *link, u32 fm)
356 {
357 	u32 l = link->nr;
358 
359 	if (link->lnb.fmode == fm)
360 		return 0;
361 	dev_info(dev->dev, "Set fmode link %u = %u\n", l, fm);
362 	mutex_lock(&link->lnb.lock);
363 	if (fm == 2 || fm == 1) {
364 		if (fmode_sat >= 0) {
365 			lnb_set_sat(dev, l, 0, fmode_sat, 0, 0);
366 			if (old_quattro) {
367 				lnb_set_sat(dev, l, 1, fmode_sat, 0, 1);
368 				lnb_set_sat(dev, l, 2, fmode_sat, 1, 0);
369 			} else {
370 				lnb_set_sat(dev, l, 1, fmode_sat, 1, 0);
371 				lnb_set_sat(dev, l, 2, fmode_sat, 0, 1);
372 			}
373 			lnb_set_sat(dev, l, 3, fmode_sat, 1, 1);
374 		}
375 		lnb_set_tone(dev, l, 0, SEC_TONE_OFF);
376 		if (old_quattro) {
377 			lnb_set_tone(dev, l, 1, SEC_TONE_OFF);
378 			lnb_set_tone(dev, l, 2, SEC_TONE_ON);
379 		} else {
380 			lnb_set_tone(dev, l, 1, SEC_TONE_ON);
381 			lnb_set_tone(dev, l, 2, SEC_TONE_OFF);
382 		}
383 		lnb_set_tone(dev, l, 3, SEC_TONE_ON);
384 	}
385 	link->lnb.fmode = fm;
386 	mutex_unlock(&link->lnb.lock);
387 	return 0;
388 }
389 
390 static struct mxl5xx_cfg mxl5xx = {
391 	.adr      = 0x60,
392 	.type     = 0x01,
393 	.clk      = 27000000,
394 	.ts_clk   = 139,
395 	.cap      = 12,
396 	.fw_read  = mxl_fw_read,
397 };
398 
399 int ddb_fe_attach_mxl5xx(struct ddb_input *input)
400 {
401 	struct ddb *dev = input->port->dev;
402 	struct i2c_adapter *i2c = &input->port->i2c->adap;
403 	struct ddb_dvb *dvb = &input->port->dvb[input->nr & 1];
404 	struct ddb_port *port = input->port;
405 	struct ddb_link *link = &dev->link[port->lnr];
406 	struct mxl5xx_cfg cfg;
407 	int demod, tuner;
408 
409 	cfg = mxl5xx;
410 	cfg.fw_priv = link;
411 	dvb->set_input = NULL;
412 
413 	demod = input->nr;
414 	tuner = demod & 3;
415 	if (fmode == 3)
416 		tuner = 0;
417 
418 	dvb->fe = dvb_attach(mxl5xx_attach, i2c, &cfg,
419 			     demod, tuner, &dvb->set_input);
420 
421 	if (!dvb->fe) {
422 		dev_err(dev->dev, "No MXL5XX found!\n");
423 		return -ENODEV;
424 	}
425 
426 	if (!dvb->set_input) {
427 		dev_err(dev->dev, "No mxl5xx_set_input function pointer!\n");
428 		return -ENODEV;
429 	}
430 
431 	if (input->nr < 4) {
432 		lnb_command(dev, port->lnr, input->nr, LNB_CMD_INIT);
433 		lnb_set_voltage(dev, port->lnr, input->nr, SEC_VOLTAGE_OFF);
434 	}
435 	ddb_lnb_init_fmode(dev, link, fmode);
436 
437 	dvb->fe->ops.set_voltage = max_set_voltage;
438 	dvb->fe->ops.enable_high_lnb_voltage = max_enable_high_lnb_voltage;
439 	dvb->fe->ops.set_tone = max_set_tone;
440 	dvb->diseqc_send_master_cmd = dvb->fe->ops.diseqc_send_master_cmd;
441 	dvb->fe->ops.diseqc_send_master_cmd = max_send_master_cmd;
442 	dvb->fe->ops.diseqc_send_burst = max_send_burst;
443 	dvb->fe->sec_priv = input;
444 	dvb->input = tuner;
445 	return 0;
446 }
447 
448 /******************************************************************************/
449 /* MAX MCI related functions */
450 
451 int ddb_fe_attach_mci(struct ddb_input *input, u32 type)
452 {
453 	struct ddb *dev = input->port->dev;
454 	struct ddb_dvb *dvb = &input->port->dvb[input->nr & 1];
455 	struct ddb_port *port = input->port;
456 	struct ddb_link *link = &dev->link[port->lnr];
457 	int demod, tuner;
458 	struct mci_cfg cfg;
459 
460 	demod = input->nr;
461 	tuner = demod & 3;
462 	switch (type) {
463 	case DDB_TUNER_MCI_SX8:
464 		cfg = ddb_max_sx8_cfg;
465 		if (fmode == 3)
466 			tuner = 0;
467 		break;
468 	default:
469 		return -EINVAL;
470 	}
471 	dvb->fe = ddb_mci_attach(input, &cfg, demod, &dvb->set_input);
472 	if (!dvb->fe) {
473 		dev_err(dev->dev, "No MCI card found!\n");
474 		return -ENODEV;
475 	}
476 	if (!dvb->set_input) {
477 		dev_err(dev->dev, "No MCI set_input function pointer!\n");
478 		return -ENODEV;
479 	}
480 	if (input->nr < 4) {
481 		lnb_command(dev, port->lnr, input->nr, LNB_CMD_INIT);
482 		lnb_set_voltage(dev, port->lnr, input->nr, SEC_VOLTAGE_OFF);
483 	}
484 	ddb_lnb_init_fmode(dev, link, fmode);
485 
486 	dvb->fe->ops.set_voltage = max_set_voltage;
487 	dvb->fe->ops.enable_high_lnb_voltage = max_enable_high_lnb_voltage;
488 	dvb->fe->ops.set_tone = max_set_tone;
489 	dvb->diseqc_send_master_cmd = dvb->fe->ops.diseqc_send_master_cmd;
490 	dvb->fe->ops.diseqc_send_master_cmd = max_send_master_cmd;
491 	dvb->fe->ops.diseqc_send_burst = max_send_burst;
492 	dvb->fe->sec_priv = input;
493 	dvb->input = tuner;
494 	return 0;
495 }
496