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 */
35static int fmode;
36module_param(fmode, int, 0444);
37MODULE_PARM_DESC(fmode, "frontend emulation mode");
38
39static int fmode_sat = -1;
40module_param(fmode_sat, int, 0444);
41MODULE_PARM_DESC(fmode_sat, "set frontend emulation mode sat");
42
43static int old_quattro;
44module_param(old_quattro, int, 0444);
45MODULE_PARM_DESC(old_quattro, "old quattro LNB input order ");
46
47/******************************************************************************/
48
49static 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
67static 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
92static 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
105static 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
117static 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
143static 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
170static 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
193static 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
231static 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
335static int max_enable_high_lnb_voltage(struct dvb_frontend *fe, long arg)
336{
337	return 0;
338}
339
340static int max_send_burst(struct dvb_frontend *fe, enum fe_sec_mini_cmd burst)
341{
342	return 0;
343}
344
345static 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
355int 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
390static 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
399int 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
451int 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