xref: /openbmc/linux/drivers/media/tuners/si2157.c (revision 82df5b73)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Silicon Labs Si2146/2147/2148/2157/2158 silicon tuner driver
4  *
5  * Copyright (C) 2014 Antti Palosaari <crope@iki.fi>
6  */
7 
8 #include "si2157_priv.h"
9 
10 static const struct dvb_tuner_ops si2157_ops;
11 
12 static int tuner_lock_debug;
13 module_param(tuner_lock_debug, int, 0644);
14 MODULE_PARM_DESC(tuner_lock_debug, "if set, signal lock is briefly waited on after setting params");
15 
16 /* execute firmware command */
17 static int si2157_cmd_execute(struct i2c_client *client, struct si2157_cmd *cmd)
18 {
19 	struct si2157_dev *dev = i2c_get_clientdata(client);
20 	int ret;
21 	unsigned long timeout;
22 
23 	mutex_lock(&dev->i2c_mutex);
24 
25 	if (cmd->wlen) {
26 		/* write cmd and args for firmware */
27 		ret = i2c_master_send(client, cmd->args, cmd->wlen);
28 		if (ret < 0) {
29 			goto err_mutex_unlock;
30 		} else if (ret != cmd->wlen) {
31 			ret = -EREMOTEIO;
32 			goto err_mutex_unlock;
33 		}
34 	}
35 
36 	if (cmd->rlen) {
37 		/* wait cmd execution terminate */
38 		#define TIMEOUT 80
39 		timeout = jiffies + msecs_to_jiffies(TIMEOUT);
40 		while (!time_after(jiffies, timeout)) {
41 			ret = i2c_master_recv(client, cmd->args, cmd->rlen);
42 			if (ret < 0) {
43 				goto err_mutex_unlock;
44 			} else if (ret != cmd->rlen) {
45 				ret = -EREMOTEIO;
46 				goto err_mutex_unlock;
47 			}
48 
49 			/* firmware ready? */
50 			if ((cmd->args[0] >> 7) & 0x01)
51 				break;
52 		}
53 
54 		dev_dbg(&client->dev, "cmd execution took %d ms, status=%x\n",
55 			jiffies_to_msecs(jiffies) -
56 			(jiffies_to_msecs(timeout) - TIMEOUT),
57 			cmd->args[0]);
58 
59 		if (!((cmd->args[0] >> 7) & 0x01)) {
60 			ret = -ETIMEDOUT;
61 			goto err_mutex_unlock;
62 		}
63 		/* check error status bit */
64 		if (cmd->args[0] & 0x40) {
65 			ret = -EAGAIN;
66 			goto err_mutex_unlock;
67 		}
68 	}
69 
70 	mutex_unlock(&dev->i2c_mutex);
71 	return 0;
72 
73 err_mutex_unlock:
74 	mutex_unlock(&dev->i2c_mutex);
75 	dev_dbg(&client->dev, "failed=%d\n", ret);
76 	return ret;
77 }
78 
79 static int si2157_init(struct dvb_frontend *fe)
80 {
81 	struct i2c_client *client = fe->tuner_priv;
82 	struct si2157_dev *dev = i2c_get_clientdata(client);
83 	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
84 	int ret, len, remaining;
85 	struct si2157_cmd cmd;
86 	const struct firmware *fw;
87 	const char *fw_name;
88 	unsigned int chip_id, xtal_trim;
89 
90 	dev_dbg(&client->dev, "\n");
91 
92 	/* Try to get Xtal trim property, to verify tuner still running */
93 	memcpy(cmd.args, "\x15\x00\x04\x02", 4);
94 	cmd.wlen = 4;
95 	cmd.rlen = 4;
96 	ret = si2157_cmd_execute(client, &cmd);
97 
98 	xtal_trim = cmd.args[2] | (cmd.args[3] << 8);
99 
100 	if (ret == 0 && xtal_trim < 16)
101 		goto warm;
102 
103 	dev->if_frequency = 0; /* we no longer know current tuner state */
104 
105 	/* power up */
106 	if (dev->chiptype == SI2157_CHIPTYPE_SI2146) {
107 		memcpy(cmd.args, "\xc0\x05\x01\x00\x00\x0b\x00\x00\x01", 9);
108 		cmd.wlen = 9;
109 	} else if (dev->chiptype == SI2157_CHIPTYPE_SI2141) {
110 		memcpy(cmd.args, "\xc0\x00\x0d\x0e\x00\x01\x01\x01\x01\x03", 10);
111 		cmd.wlen = 10;
112 	} else {
113 		memcpy(cmd.args, "\xc0\x00\x0c\x00\x00\x01\x01\x01\x01\x01\x01\x02\x00\x00\x01", 15);
114 		cmd.wlen = 15;
115 	}
116 	cmd.rlen = 1;
117 	ret = si2157_cmd_execute(client, &cmd);
118 	if (ret && (dev->chiptype != SI2157_CHIPTYPE_SI2141 || ret != -EAGAIN))
119 		goto err;
120 
121 	/* Si2141 needs a second command before it answers the revision query */
122 	if (dev->chiptype == SI2157_CHIPTYPE_SI2141) {
123 		memcpy(cmd.args, "\xc0\x08\x01\x02\x00\x00\x01", 7);
124 		cmd.wlen = 7;
125 		ret = si2157_cmd_execute(client, &cmd);
126 		if (ret)
127 			goto err;
128 	}
129 
130 	if (dev->dont_load_firmware) {
131 		dev_info(&client->dev, "device is buggy, skipping firmware download\n");
132 		goto skip_fw_download;
133 	}
134 
135 	/* query chip revision */
136 	memcpy(cmd.args, "\x02", 1);
137 	cmd.wlen = 1;
138 	cmd.rlen = 13;
139 	ret = si2157_cmd_execute(client, &cmd);
140 	if (ret)
141 		goto err;
142 
143 	chip_id = cmd.args[1] << 24 | cmd.args[2] << 16 | cmd.args[3] << 8 |
144 			cmd.args[4] << 0;
145 
146 	#define SI2177_A30 ('A' << 24 | 77 << 16 | '3' << 8 | '0' << 0)
147 	#define SI2158_A20 ('A' << 24 | 58 << 16 | '2' << 8 | '0' << 0)
148 	#define SI2148_A20 ('A' << 24 | 48 << 16 | '2' << 8 | '0' << 0)
149 	#define SI2157_A30 ('A' << 24 | 57 << 16 | '3' << 8 | '0' << 0)
150 	#define SI2147_A30 ('A' << 24 | 47 << 16 | '3' << 8 | '0' << 0)
151 	#define SI2146_A10 ('A' << 24 | 46 << 16 | '1' << 8 | '0' << 0)
152 	#define SI2141_A10 ('A' << 24 | 41 << 16 | '1' << 8 | '0' << 0)
153 
154 	switch (chip_id) {
155 	case SI2158_A20:
156 	case SI2148_A20:
157 		fw_name = SI2158_A20_FIRMWARE;
158 		break;
159 	case SI2141_A10:
160 		fw_name = SI2141_A10_FIRMWARE;
161 		break;
162 	case SI2177_A30:
163 		fw_name = SI2157_A30_FIRMWARE;
164 		break;
165 	case SI2157_A30:
166 	case SI2147_A30:
167 	case SI2146_A10:
168 		fw_name = NULL;
169 		break;
170 	default:
171 		dev_err(&client->dev, "unknown chip version Si21%d-%c%c%c\n",
172 				cmd.args[2], cmd.args[1],
173 				cmd.args[3], cmd.args[4]);
174 		ret = -EINVAL;
175 		goto err;
176 	}
177 
178 	dev_info(&client->dev, "found a 'Silicon Labs Si21%d-%c%c%c'\n",
179 			cmd.args[2], cmd.args[1], cmd.args[3], cmd.args[4]);
180 
181 	if (fw_name == NULL)
182 		goto skip_fw_download;
183 
184 	/* request the firmware, this will block and timeout */
185 	ret = request_firmware(&fw, fw_name, &client->dev);
186 	if (ret) {
187 		dev_err(&client->dev, "firmware file '%s' not found\n",
188 				fw_name);
189 		goto err;
190 	}
191 
192 	/* firmware should be n chunks of 17 bytes */
193 	if (fw->size % 17 != 0) {
194 		dev_err(&client->dev, "firmware file '%s' is invalid\n",
195 				fw_name);
196 		ret = -EINVAL;
197 		goto err_release_firmware;
198 	}
199 
200 	dev_info(&client->dev, "downloading firmware from file '%s'\n",
201 			fw_name);
202 
203 	for (remaining = fw->size; remaining > 0; remaining -= 17) {
204 		len = fw->data[fw->size - remaining];
205 		if (len > SI2157_ARGLEN) {
206 			dev_err(&client->dev, "Bad firmware length\n");
207 			ret = -EINVAL;
208 			goto err_release_firmware;
209 		}
210 		memcpy(cmd.args, &fw->data[(fw->size - remaining) + 1], len);
211 		cmd.wlen = len;
212 		cmd.rlen = 1;
213 		ret = si2157_cmd_execute(client, &cmd);
214 		if (ret) {
215 			dev_err(&client->dev, "firmware download failed %d\n",
216 					ret);
217 			goto err_release_firmware;
218 		}
219 	}
220 
221 	release_firmware(fw);
222 
223 skip_fw_download:
224 	/* reboot the tuner with new firmware? */
225 	memcpy(cmd.args, "\x01\x01", 2);
226 	cmd.wlen = 2;
227 	cmd.rlen = 1;
228 	ret = si2157_cmd_execute(client, &cmd);
229 	if (ret)
230 		goto err;
231 
232 	/* query firmware version */
233 	memcpy(cmd.args, "\x11", 1);
234 	cmd.wlen = 1;
235 	cmd.rlen = 10;
236 	ret = si2157_cmd_execute(client, &cmd);
237 	if (ret)
238 		goto err;
239 
240 	dev_info(&client->dev, "firmware version: %c.%c.%d\n",
241 			cmd.args[6], cmd.args[7], cmd.args[8]);
242 
243 	/* enable tuner status flags */
244 	memcpy(cmd.args, "\x14\x00\x01\x05\x01\x00", 6);
245 	cmd.wlen = 6;
246 	cmd.rlen = 1;
247 	ret = si2157_cmd_execute(client, &cmd);
248 	if (ret)
249 		goto err;
250 
251 	memcpy(cmd.args, "\x14\x00\x01\x06\x01\x00", 6);
252 	cmd.wlen = 6;
253 	cmd.rlen = 1;
254 	ret = si2157_cmd_execute(client, &cmd);
255 	if (ret)
256 		goto err;
257 
258 	memcpy(cmd.args, "\x14\x00\x01\x07\x01\x00", 6);
259 	cmd.wlen = 6;
260 	cmd.rlen = 1;
261 	ret = si2157_cmd_execute(client, &cmd);
262 	if (ret)
263 		goto err;
264 warm:
265 	/* init statistics in order signal app which are supported */
266 	c->strength.len = 1;
267 	c->strength.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
268 	/* start statistics polling */
269 	schedule_delayed_work(&dev->stat_work, msecs_to_jiffies(1000));
270 
271 	dev->active = true;
272 	return 0;
273 err_release_firmware:
274 	release_firmware(fw);
275 err:
276 	dev_dbg(&client->dev, "failed=%d\n", ret);
277 	return ret;
278 }
279 
280 static int si2157_sleep(struct dvb_frontend *fe)
281 {
282 	struct i2c_client *client = fe->tuner_priv;
283 	struct si2157_dev *dev = i2c_get_clientdata(client);
284 	int ret;
285 	struct si2157_cmd cmd;
286 
287 	dev_dbg(&client->dev, "\n");
288 
289 	dev->active = false;
290 
291 	/* stop statistics polling */
292 	cancel_delayed_work_sync(&dev->stat_work);
293 
294 	/* standby */
295 	memcpy(cmd.args, "\x16\x00", 2);
296 	cmd.wlen = 2;
297 	cmd.rlen = 1;
298 	ret = si2157_cmd_execute(client, &cmd);
299 	if (ret)
300 		goto err;
301 
302 	return 0;
303 err:
304 	dev_dbg(&client->dev, "failed=%d\n", ret);
305 	return ret;
306 }
307 
308 static int si2157_tune_wait(struct i2c_client *client, u8 is_digital)
309 {
310 #define TUN_TIMEOUT 40
311 #define DIG_TIMEOUT 30
312 #define ANALOG_TIMEOUT 150
313 	struct si2157_dev *dev = i2c_get_clientdata(client);
314 	int ret;
315 	unsigned long timeout;
316 	unsigned long start_time;
317 	u8 wait_status;
318 	u8  tune_lock_mask;
319 
320 	if (is_digital)
321 		tune_lock_mask = 0x04;
322 	else
323 		tune_lock_mask = 0x02;
324 
325 	mutex_lock(&dev->i2c_mutex);
326 
327 	/* wait tuner command complete */
328 	start_time = jiffies;
329 	timeout = start_time + msecs_to_jiffies(TUN_TIMEOUT);
330 	while (1) {
331 		ret = i2c_master_recv(client, &wait_status,
332 				      sizeof(wait_status));
333 		if (ret < 0) {
334 			goto err_mutex_unlock;
335 		} else if (ret != sizeof(wait_status)) {
336 			ret = -EREMOTEIO;
337 			goto err_mutex_unlock;
338 		}
339 
340 		if (time_after(jiffies, timeout))
341 			break;
342 
343 		/* tuner done? */
344 		if ((wait_status & 0x81) == 0x81)
345 			break;
346 		usleep_range(5000, 10000);
347 	}
348 
349 	dev_dbg(&client->dev, "tuning took %d ms, status=0x%x\n",
350 		jiffies_to_msecs(jiffies) - jiffies_to_msecs(start_time),
351 		wait_status);
352 
353 	/* if we tuned ok, wait a bit for tuner lock */
354 	if (tuner_lock_debug && (wait_status & 0x81) == 0x81) {
355 		if (is_digital)
356 			timeout = jiffies + msecs_to_jiffies(DIG_TIMEOUT);
357 		else
358 			timeout = jiffies + msecs_to_jiffies(ANALOG_TIMEOUT);
359 
360 		while (!time_after(jiffies, timeout)) {
361 			ret = i2c_master_recv(client, &wait_status,
362 					      sizeof(wait_status));
363 			if (ret < 0) {
364 				goto err_mutex_unlock;
365 			} else if (ret != sizeof(wait_status)) {
366 				ret = -EREMOTEIO;
367 				goto err_mutex_unlock;
368 			}
369 
370 			/* tuner locked? */
371 			if (wait_status & tune_lock_mask)
372 				break;
373 			usleep_range(5000, 10000);
374 		}
375 
376 		dev_dbg(&client->dev, "tuning+lock took %d ms, status=0x%x\n",
377 			jiffies_to_msecs(jiffies) - jiffies_to_msecs(start_time),
378 			wait_status);
379 	}
380 
381 	if ((wait_status & 0xc0) != 0x80) {
382 		ret = -ETIMEDOUT;
383 		goto err_mutex_unlock;
384 	}
385 
386 	mutex_unlock(&dev->i2c_mutex);
387 	return 0;
388 
389 err_mutex_unlock:
390 	mutex_unlock(&dev->i2c_mutex);
391 	dev_err(&client->dev, "failed=%d\n", ret);
392 	return ret;
393 }
394 
395 static int si2157_set_params(struct dvb_frontend *fe)
396 {
397 	struct i2c_client *client = fe->tuner_priv;
398 	struct si2157_dev *dev = i2c_get_clientdata(client);
399 	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
400 	int ret;
401 	struct si2157_cmd cmd;
402 	u8 bandwidth, delivery_system;
403 	u32 if_frequency = 5000000;
404 
405 	dev_dbg(&client->dev,
406 			"delivery_system=%d frequency=%u bandwidth_hz=%u\n",
407 			c->delivery_system, c->frequency, c->bandwidth_hz);
408 
409 	if (!dev->active) {
410 		ret = -EAGAIN;
411 		goto err;
412 	}
413 
414 	if (c->bandwidth_hz <= 6000000)
415 		bandwidth = 0x06;
416 	else if (c->bandwidth_hz <= 7000000)
417 		bandwidth = 0x07;
418 	else if (c->bandwidth_hz <= 8000000)
419 		bandwidth = 0x08;
420 	else
421 		bandwidth = 0x0f;
422 
423 	switch (c->delivery_system) {
424 	case SYS_ATSC:
425 			delivery_system = 0x00;
426 			if_frequency = 3250000;
427 			break;
428 	case SYS_DVBC_ANNEX_B:
429 			delivery_system = 0x10;
430 			if_frequency = 4000000;
431 			break;
432 	case SYS_DVBT:
433 	case SYS_DVBT2: /* it seems DVB-T and DVB-T2 both are 0x20 here */
434 			delivery_system = 0x20;
435 			break;
436 	case SYS_DVBC_ANNEX_A:
437 			delivery_system = 0x30;
438 			break;
439 	default:
440 			ret = -EINVAL;
441 			goto err;
442 	}
443 
444 	memcpy(cmd.args, "\x14\x00\x03\x07\x00\x00", 6);
445 	cmd.args[4] = delivery_system | bandwidth;
446 	if (dev->inversion)
447 		cmd.args[5] = 0x01;
448 	cmd.wlen = 6;
449 	cmd.rlen = 4;
450 	ret = si2157_cmd_execute(client, &cmd);
451 	if (ret)
452 		goto err;
453 
454 	if (dev->chiptype == SI2157_CHIPTYPE_SI2146)
455 		memcpy(cmd.args, "\x14\x00\x02\x07\x00\x01", 6);
456 	else
457 		memcpy(cmd.args, "\x14\x00\x02\x07\x00\x00", 6);
458 	cmd.args[4] = dev->if_port;
459 	cmd.wlen = 6;
460 	cmd.rlen = 4;
461 	ret = si2157_cmd_execute(client, &cmd);
462 	if (ret)
463 		goto err;
464 
465 	/* set digital if frequency if needed */
466 	if (if_frequency != dev->if_frequency) {
467 		memcpy(cmd.args, "\x14\x00\x06\x07", 4);
468 		cmd.args[4] = (if_frequency / 1000) & 0xff;
469 		cmd.args[5] = ((if_frequency / 1000) >> 8) & 0xff;
470 		cmd.wlen = 6;
471 		cmd.rlen = 4;
472 		ret = si2157_cmd_execute(client, &cmd);
473 		if (ret)
474 			goto err;
475 
476 		dev->if_frequency = if_frequency;
477 	}
478 
479 	/* set digital frequency */
480 	memcpy(cmd.args, "\x41\x00\x00\x00\x00\x00\x00\x00", 8);
481 	cmd.args[4] = (c->frequency >>  0) & 0xff;
482 	cmd.args[5] = (c->frequency >>  8) & 0xff;
483 	cmd.args[6] = (c->frequency >> 16) & 0xff;
484 	cmd.args[7] = (c->frequency >> 24) & 0xff;
485 	cmd.wlen = 8;
486 	cmd.rlen = 1;
487 	ret = si2157_cmd_execute(client, &cmd);
488 	if (ret)
489 		goto err;
490 
491 	dev->bandwidth = bandwidth;
492 	dev->frequency = c->frequency;
493 
494 	si2157_tune_wait(client, 1); /* wait to complete, ignore any errors */
495 
496 	return 0;
497 err:
498 	dev->bandwidth = 0;
499 	dev->frequency = 0;
500 	dev->if_frequency = 0;
501 	dev_dbg(&client->dev, "failed=%d\n", ret);
502 	return ret;
503 }
504 
505 static int si2157_set_analog_params(struct dvb_frontend *fe,
506 				    struct analog_parameters *params)
507 {
508 	struct i2c_client *client = fe->tuner_priv;
509 	struct si2157_dev *dev = i2c_get_clientdata(client);
510 	char *std; /* for debugging */
511 	int ret;
512 	struct si2157_cmd cmd;
513 	u32 bandwidth = 0;
514 	u32 if_frequency = 0;
515 	u32 freq = 0;
516 	u64 tmp_lval = 0;
517 	u8 system = 0;
518 	u8 color = 0;    /* 0=NTSC/PAL, 0x10=SECAM */
519 	u8 invert_analog = 1; /* analog tuner spectrum; 0=normal, 1=inverted */
520 
521 	if (dev->chiptype != SI2157_CHIPTYPE_SI2157) {
522 		dev_info(&client->dev, "Analog tuning not supported for chiptype=%u\n",
523 			 dev->chiptype);
524 		ret = -EINVAL;
525 		goto err;
526 	}
527 
528 	if (!dev->active)
529 		si2157_init(fe);
530 
531 	if (!dev->active) {
532 		ret = -EAGAIN;
533 		goto err;
534 	}
535 	if (params->mode == V4L2_TUNER_RADIO) {
536 	/*
537 	 * std = "fm";
538 	 * bandwidth = 1700000; //best can do for FM, AGC will be a mess though
539 	 * if_frequency = 1250000;  //HVR-225x(saa7164), HVR-12xx(cx23885)
540 	 * if_frequency = 6600000;  //HVR-9xx(cx231xx)
541 	 * if_frequency = 5500000;  //HVR-19xx(pvrusb2)
542 	 */
543 		dev_err(&client->dev, "si2157 does not currently support FM radio\n");
544 		ret = -EINVAL;
545 		goto err;
546 	}
547 	tmp_lval = params->frequency * 625LL;
548 	do_div(tmp_lval, 10); /* convert to HZ */
549 	freq = (u32)tmp_lval;
550 
551 	if (freq < 1000000) /* is freq in KHz */
552 		freq = freq * 1000;
553 	dev->frequency = freq;
554 
555 	/* if_frequency values based on tda187271C2 */
556 	if (params->std & (V4L2_STD_B | V4L2_STD_GH)) {
557 		if (freq >= 470000000) {
558 			std = "palGH";
559 			bandwidth = 8000000;
560 			if_frequency = 6000000;
561 			system = 1;
562 			if (params->std &
563 			    (V4L2_STD_SECAM_G | V4L2_STD_SECAM_H)) {
564 				std = "secamGH";
565 				color = 0x10;
566 			}
567 		} else {
568 			std = "palB";
569 			bandwidth = 7000000;
570 			if_frequency = 6000000;
571 			system = 0;
572 			if (params->std & V4L2_STD_SECAM_B) {
573 				std = "secamB";
574 				color = 0x10;
575 			}
576 		}
577 	} else if (params->std & V4L2_STD_MN) {
578 		std = "MN";
579 		bandwidth = 6000000;
580 		if_frequency = 5400000;
581 		system = 2;
582 	} else if (params->std & V4L2_STD_PAL_I) {
583 		std = "palI";
584 		bandwidth = 8000000;
585 		if_frequency = 7250000; /* TODO: does not work yet */
586 		system = 4;
587 	} else if (params->std & V4L2_STD_DK) {
588 		std = "palDK";
589 		bandwidth = 8000000;
590 		if_frequency = 6900000; /* TODO: does not work yet */
591 		system = 5;
592 		if (params->std & V4L2_STD_SECAM_DK) {
593 			std = "secamDK";
594 			color = 0x10;
595 		}
596 	} else if (params->std & V4L2_STD_SECAM_L) {
597 		std = "secamL";
598 		bandwidth = 8000000;
599 		if_frequency = 6750000; /* TODO: untested */
600 		system = 6;
601 		color = 0x10;
602 	} else if (params->std & V4L2_STD_SECAM_LC) {
603 		std = "secamL'";
604 		bandwidth = 7000000;
605 		if_frequency = 1250000; /* TODO: untested */
606 		system = 7;
607 		color = 0x10;
608 	} else {
609 		std = "unknown";
610 	}
611 	/* calc channel center freq */
612 	freq = freq - 1250000 + (bandwidth / 2);
613 
614 	dev_dbg(&client->dev,
615 		"mode=%d system=%u std='%s' params->frequency=%u center freq=%u if=%u bandwidth=%u\n",
616 		params->mode, system, std, params->frequency,
617 		freq, if_frequency, bandwidth);
618 
619 	/* set analog IF port */
620 	memcpy(cmd.args, "\x14\x00\x03\x06\x08\x02", 6);
621 	/* in using dev->if_port, we assume analog and digital IF's */
622 	/*   are always on different ports */
623 	/* assumes if_port definition is 0 or 1 for digital out */
624 	cmd.args[4] = (dev->if_port == 1) ? 8 : 10;
625 	/* Analog AGC assumed external */
626 	cmd.args[5] = (dev->if_port == 1) ? 2 : 1;
627 	cmd.wlen = 6;
628 	cmd.rlen = 4;
629 	ret = si2157_cmd_execute(client, &cmd);
630 	if (ret)
631 		goto err;
632 
633 	/* set analog IF output config */
634 	memcpy(cmd.args, "\x14\x00\x0d\x06\x94\x64", 6);
635 	cmd.wlen = 6;
636 	cmd.rlen = 4;
637 	ret = si2157_cmd_execute(client, &cmd);
638 	if (ret)
639 		goto err;
640 
641 	/* make this distinct from a digital IF */
642 	dev->if_frequency = if_frequency | 1;
643 
644 	/* calc and set tuner analog if center frequency */
645 	if_frequency = if_frequency + 1250000 - (bandwidth / 2);
646 	dev_dbg(&client->dev, "IF Ctr freq=%d\n", if_frequency);
647 
648 	memcpy(cmd.args, "\x14\x00\x0C\x06", 4);
649 	cmd.args[4] = (if_frequency / 1000) & 0xff;
650 	cmd.args[5] = ((if_frequency / 1000) >> 8) & 0xff;
651 	cmd.wlen = 6;
652 	cmd.rlen = 4;
653 	ret = si2157_cmd_execute(client, &cmd);
654 	if (ret)
655 		goto err;
656 
657 	/* set analog AGC config */
658 	memcpy(cmd.args, "\x14\x00\x07\x06\x32\xc8", 6);
659 	cmd.wlen = 6;
660 	cmd.rlen = 4;
661 	ret = si2157_cmd_execute(client, &cmd);
662 	if (ret)
663 		goto err;
664 
665 	/* set analog video mode */
666 	memcpy(cmd.args, "\x14\x00\x04\x06\x00\x00", 6);
667 	cmd.args[4] = system | color;
668 	/* can use dev->inversion if assumed applies to both digital/analog */
669 	if (invert_analog)
670 		cmd.args[5] |= 0x02;
671 	cmd.wlen = 6;
672 	cmd.rlen = 1;
673 	ret = si2157_cmd_execute(client, &cmd);
674 	if (ret)
675 		goto err;
676 
677 	/* set analog frequency */
678 	memcpy(cmd.args, "\x41\x01\x00\x00\x00\x00\x00\x00", 8);
679 	cmd.args[4] = (freq >>  0) & 0xff;
680 	cmd.args[5] = (freq >>  8) & 0xff;
681 	cmd.args[6] = (freq >> 16) & 0xff;
682 	cmd.args[7] = (freq >> 24) & 0xff;
683 	cmd.wlen = 8;
684 	cmd.rlen = 1;
685 	ret = si2157_cmd_execute(client, &cmd);
686 	if (ret)
687 		goto err;
688 
689 	dev->bandwidth = bandwidth;
690 
691 	si2157_tune_wait(client, 0); /* wait to complete, ignore any errors */
692 
693 	return 0;
694 err:
695 	dev->bandwidth = 0;
696 	dev->frequency = 0;
697 	dev->if_frequency = 0;
698 	dev_dbg(&client->dev, "failed=%d\n", ret);
699 	return ret;
700 }
701 
702 static int si2157_get_frequency(struct dvb_frontend *fe, u32 *frequency)
703 {
704 	struct i2c_client *client = fe->tuner_priv;
705 	struct si2157_dev *dev = i2c_get_clientdata(client);
706 
707 	*frequency = dev->frequency;
708 	dev_dbg(&client->dev, "freq=%u\n", dev->frequency);
709 	return 0;
710 }
711 
712 static int si2157_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
713 {
714 	struct i2c_client *client = fe->tuner_priv;
715 	struct si2157_dev *dev = i2c_get_clientdata(client);
716 
717 	*bandwidth = dev->bandwidth;
718 	dev_dbg(&client->dev, "bandwidth=%u\n", dev->bandwidth);
719 	return 0;
720 }
721 
722 static int si2157_get_if_frequency(struct dvb_frontend *fe, u32 *frequency)
723 {
724 	struct i2c_client *client = fe->tuner_priv;
725 	struct si2157_dev *dev = i2c_get_clientdata(client);
726 
727 	*frequency = dev->if_frequency & ~1; /* strip analog IF indicator bit */
728 	dev_dbg(&client->dev, "if_frequency=%u\n", *frequency);
729 	return 0;
730 }
731 
732 static int si2157_get_rf_strength(struct dvb_frontend *fe, u16 *rssi)
733 {
734 	struct i2c_client *client = fe->tuner_priv;
735 	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
736 	struct si2157_cmd cmd;
737 	int ret;
738 	int strength;
739 
740 	dev_dbg(&client->dev, "\n");
741 
742 	memcpy(cmd.args, "\x42\x00", 2);
743 	cmd.wlen = 2;
744 	cmd.rlen = 12;
745 	ret = si2157_cmd_execute(client, &cmd);
746 	if (ret)
747 		goto err;
748 
749 	c->strength.stat[0].scale = FE_SCALE_DECIBEL;
750 	c->strength.stat[0].svalue = (s8)cmd.args[3] * 1000;
751 
752 	/* normalize values based on Silicon Labs reference
753 	 * add 100, then anything > 80 is 100% signal
754 	 */
755 	strength = (s8)cmd.args[3] + 100;
756 	strength = clamp_val(strength, 0, 80);
757 	*rssi = (u16)(strength * 0xffff / 80);
758 
759 	dev_dbg(&client->dev, "strength=%d rssi=%u\n",
760 		(s8)cmd.args[3], *rssi);
761 
762 	return 0;
763 err:
764 	dev_dbg(&client->dev, "failed=%d\n", ret);
765 	return ret;
766 }
767 
768 static const struct dvb_tuner_ops si2157_ops = {
769 	.info = {
770 		.name             = "Silicon Labs Si2141/Si2146/2147/2148/2157/2158",
771 		.frequency_min_hz =  42 * MHz,
772 		.frequency_max_hz = 870 * MHz,
773 	},
774 
775 	.init = si2157_init,
776 	.sleep = si2157_sleep,
777 	.set_params = si2157_set_params,
778 	.set_analog_params = si2157_set_analog_params,
779 	.get_frequency     = si2157_get_frequency,
780 	.get_bandwidth     = si2157_get_bandwidth,
781 	.get_if_frequency  = si2157_get_if_frequency,
782 
783 	.get_rf_strength   = si2157_get_rf_strength,
784 };
785 
786 static void si2157_stat_work(struct work_struct *work)
787 {
788 	struct si2157_dev *dev = container_of(work, struct si2157_dev, stat_work.work);
789 	struct dvb_frontend *fe = dev->fe;
790 	struct i2c_client *client = fe->tuner_priv;
791 	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
792 	struct si2157_cmd cmd;
793 	int ret;
794 
795 	dev_dbg(&client->dev, "\n");
796 
797 	memcpy(cmd.args, "\x42\x00", 2);
798 	cmd.wlen = 2;
799 	cmd.rlen = 12;
800 	ret = si2157_cmd_execute(client, &cmd);
801 	if (ret)
802 		goto err;
803 
804 	c->strength.stat[0].scale = FE_SCALE_DECIBEL;
805 	c->strength.stat[0].svalue = (s8) cmd.args[3] * 1000;
806 
807 	schedule_delayed_work(&dev->stat_work, msecs_to_jiffies(2000));
808 	return;
809 err:
810 	c->strength.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
811 	dev_dbg(&client->dev, "failed=%d\n", ret);
812 }
813 
814 static int si2157_probe(struct i2c_client *client,
815 			const struct i2c_device_id *id)
816 {
817 	struct si2157_config *cfg = client->dev.platform_data;
818 	struct dvb_frontend *fe = cfg->fe;
819 	struct si2157_dev *dev;
820 	struct si2157_cmd cmd;
821 	int ret;
822 
823 	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
824 	if (!dev) {
825 		ret = -ENOMEM;
826 		dev_err(&client->dev, "kzalloc() failed\n");
827 		goto err;
828 	}
829 
830 	i2c_set_clientdata(client, dev);
831 	dev->fe = cfg->fe;
832 	dev->inversion = cfg->inversion;
833 	dev->dont_load_firmware = cfg->dont_load_firmware;
834 	dev->if_port = cfg->if_port;
835 	dev->chiptype = (u8)id->driver_data;
836 	dev->if_frequency = 5000000; /* default value of property 0x0706 */
837 	mutex_init(&dev->i2c_mutex);
838 	INIT_DELAYED_WORK(&dev->stat_work, si2157_stat_work);
839 
840 	/* check if the tuner is there */
841 	cmd.wlen = 0;
842 	cmd.rlen = 1;
843 	ret = si2157_cmd_execute(client, &cmd);
844 	if (ret && ret != -EAGAIN)
845 		goto err_kfree;
846 
847 	memcpy(&fe->ops.tuner_ops, &si2157_ops, sizeof(struct dvb_tuner_ops));
848 	fe->tuner_priv = client;
849 
850 #ifdef CONFIG_MEDIA_CONTROLLER
851 	if (cfg->mdev) {
852 		dev->mdev = cfg->mdev;
853 
854 		dev->ent.name = KBUILD_MODNAME;
855 		dev->ent.function = MEDIA_ENT_F_TUNER;
856 
857 		dev->pad[SI2157_PAD_RF_INPUT].flags = MEDIA_PAD_FL_SINK;
858 		dev->pad[SI2157_PAD_RF_INPUT].sig_type = PAD_SIGNAL_ANALOG;
859 		dev->pad[SI2157_PAD_VID_OUT].flags = MEDIA_PAD_FL_SOURCE;
860 		dev->pad[SI2157_PAD_VID_OUT].sig_type = PAD_SIGNAL_ANALOG;
861 		dev->pad[SI2157_PAD_AUD_OUT].flags = MEDIA_PAD_FL_SOURCE;
862 		dev->pad[SI2157_PAD_AUD_OUT].sig_type = PAD_SIGNAL_AUDIO;
863 
864 		ret = media_entity_pads_init(&dev->ent, SI2157_NUM_PADS,
865 					     &dev->pad[0]);
866 
867 		if (ret)
868 			goto err_kfree;
869 
870 		ret = media_device_register_entity(cfg->mdev, &dev->ent);
871 		if (ret) {
872 			media_entity_cleanup(&dev->ent);
873 			goto err_kfree;
874 		}
875 	}
876 #endif
877 
878 	dev_info(&client->dev, "Silicon Labs %s successfully attached\n",
879 			dev->chiptype == SI2157_CHIPTYPE_SI2141 ?  "Si2141" :
880 			dev->chiptype == SI2157_CHIPTYPE_SI2146 ?
881 			"Si2146" : "Si2147/2148/2157/2158");
882 
883 	return 0;
884 
885 err_kfree:
886 	kfree(dev);
887 err:
888 	dev_dbg(&client->dev, "failed=%d\n", ret);
889 	return ret;
890 }
891 
892 static int si2157_remove(struct i2c_client *client)
893 {
894 	struct si2157_dev *dev = i2c_get_clientdata(client);
895 	struct dvb_frontend *fe = dev->fe;
896 
897 	dev_dbg(&client->dev, "\n");
898 
899 	/* stop statistics polling */
900 	cancel_delayed_work_sync(&dev->stat_work);
901 
902 #ifdef CONFIG_MEDIA_CONTROLLER_DVB
903 	if (dev->mdev)
904 		media_device_unregister_entity(&dev->ent);
905 #endif
906 
907 	memset(&fe->ops.tuner_ops, 0, sizeof(struct dvb_tuner_ops));
908 	fe->tuner_priv = NULL;
909 	kfree(dev);
910 
911 	return 0;
912 }
913 
914 static const struct i2c_device_id si2157_id_table[] = {
915 	{"si2157", SI2157_CHIPTYPE_SI2157},
916 	{"si2146", SI2157_CHIPTYPE_SI2146},
917 	{"si2141", SI2157_CHIPTYPE_SI2141},
918 	{"si2177", SI2157_CHIPTYPE_SI2177},
919 	{}
920 };
921 MODULE_DEVICE_TABLE(i2c, si2157_id_table);
922 
923 static struct i2c_driver si2157_driver = {
924 	.driver = {
925 		.name		     = "si2157",
926 		.suppress_bind_attrs = true,
927 	},
928 	.probe		= si2157_probe,
929 	.remove		= si2157_remove,
930 	.id_table	= si2157_id_table,
931 };
932 
933 module_i2c_driver(si2157_driver);
934 
935 MODULE_DESCRIPTION("Silicon Labs Si2141/Si2146/2147/2148/2157/2158 silicon tuner driver");
936 MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
937 MODULE_LICENSE("GPL");
938 MODULE_FIRMWARE(SI2158_A20_FIRMWARE);
939 MODULE_FIRMWARE(SI2141_A10_FIRMWARE);
940 MODULE_FIRMWARE(SI2157_A30_FIRMWARE);
941