si2168.c revision fcb388ce6c293b36a71a24c0bfe526c13774302a
1/*
2 * Silicon Labs Si2168 DVB-T/T2/C demodulator driver
3 *
4 * Copyright (C) 2014 Antti Palosaari <crope@iki.fi>
5 *
6 *    This program is free software; you can redistribute it and/or modify
7 *    it under the terms of the GNU General Public License as published by
8 *    the Free Software Foundation; either version 2 of the License, or
9 *    (at your option) any later version.
10 *
11 *    This program is distributed in the hope that it will be useful,
12 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
13 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 *    GNU General Public License for more details.
15 */
16
17#include "si2168_priv.h"
18
19static const struct dvb_frontend_ops si2168_ops;
20
21/* execute firmware command */
22static int si2168_cmd_execute(struct si2168 *s, struct si2168_cmd *cmd)
23{
24	int ret;
25	unsigned long timeout;
26
27	mutex_lock(&s->i2c_mutex);
28
29	if (cmd->wlen) {
30		/* write cmd and args for firmware */
31		ret = i2c_master_send(s->client, cmd->args, cmd->wlen);
32		if (ret < 0) {
33			goto err_mutex_unlock;
34		} else if (ret != cmd->wlen) {
35			ret = -EREMOTEIO;
36			goto err_mutex_unlock;
37		}
38	}
39
40	if (cmd->rlen) {
41		/* wait cmd execution terminate */
42		#define TIMEOUT 50
43		timeout = jiffies + msecs_to_jiffies(TIMEOUT);
44		while (!time_after(jiffies, timeout)) {
45			ret = i2c_master_recv(s->client, cmd->args, cmd->rlen);
46			if (ret < 0) {
47				goto err_mutex_unlock;
48			} else if (ret != cmd->rlen) {
49				ret = -EREMOTEIO;
50				goto err_mutex_unlock;
51			}
52
53			/* firmware ready? */
54			if ((cmd->args[0] >> 7) & 0x01)
55				break;
56		}
57
58		dev_dbg(&s->client->dev, "%s: cmd execution took %d ms\n",
59				__func__,
60				jiffies_to_msecs(jiffies) -
61				(jiffies_to_msecs(timeout) - TIMEOUT));
62
63		if (!((cmd->args[0] >> 7) & 0x01)) {
64			ret = -ETIMEDOUT;
65			goto err_mutex_unlock;
66		}
67	}
68
69	ret = 0;
70
71err_mutex_unlock:
72	mutex_unlock(&s->i2c_mutex);
73	if (ret)
74		goto err;
75
76	return 0;
77err:
78	dev_dbg(&s->client->dev, "%s: failed=%d\n", __func__, ret);
79	return ret;
80}
81
82static int si2168_read_status(struct dvb_frontend *fe, fe_status_t *status)
83{
84	struct si2168 *s = fe->demodulator_priv;
85	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
86	int ret;
87	struct si2168_cmd cmd;
88
89	*status = 0;
90
91	if (!s->active) {
92		ret = -EAGAIN;
93		goto err;
94	}
95
96	switch (c->delivery_system) {
97	case SYS_DVBT:
98		memcpy(cmd.args, "\xa0\x01", 2);
99		cmd.wlen = 2;
100		cmd.rlen = 13;
101		break;
102	case SYS_DVBC_ANNEX_A:
103		memcpy(cmd.args, "\x90\x01", 2);
104		cmd.wlen = 2;
105		cmd.rlen = 9;
106		break;
107	case SYS_DVBT2:
108		memcpy(cmd.args, "\x50\x01", 2);
109		cmd.wlen = 2;
110		cmd.rlen = 14;
111		break;
112	default:
113		ret = -EINVAL;
114		goto err;
115	}
116
117	ret = si2168_cmd_execute(s, &cmd);
118	if (ret)
119		goto err;
120
121	/*
122	 * Possible values seen, in order from strong signal to weak:
123	 * 16 0001 0110 full lock
124	 * 1e 0001 1110 partial lock
125	 * 1a 0001 1010 partial lock
126	 * 18 0001 1000 no lock
127	 *
128	 * [b3:b1] lock bits
129	 * [b4] statistics ready? Set in a few secs after lock is gained.
130	 */
131
132	switch ((cmd.args[2] >> 1) & 0x03) {
133	case 0x01:
134		*status = FE_HAS_SIGNAL | FE_HAS_CARRIER;
135		break;
136	case 0x03:
137		*status = FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI |
138				FE_HAS_SYNC | FE_HAS_LOCK;
139		break;
140	}
141
142	s->fe_status = *status;
143
144	if (*status & FE_HAS_LOCK) {
145		c->cnr.len = 1;
146		c->cnr.stat[0].scale = FE_SCALE_DECIBEL;
147		c->cnr.stat[0].svalue = cmd.args[3] * 1000 / 4;
148	} else {
149		c->cnr.len = 1;
150		c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
151	}
152
153	dev_dbg(&s->client->dev, "%s: status=%02x args=%*ph\n",
154			__func__, *status, cmd.rlen, cmd.args);
155
156	return 0;
157err:
158	dev_dbg(&s->client->dev, "%s: failed=%d\n", __func__, ret);
159	return ret;
160}
161
162static int si2168_set_frontend(struct dvb_frontend *fe)
163{
164	struct si2168 *s = fe->demodulator_priv;
165	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
166	int ret;
167	struct si2168_cmd cmd;
168	u8 bandwidth, delivery_system;
169
170	dev_dbg(&s->client->dev,
171			"%s: delivery_system=%u modulation=%u frequency=%u bandwidth_hz=%u symbol_rate=%u inversion=%u\n",
172			__func__, c->delivery_system, c->modulation,
173			c->frequency, c->bandwidth_hz, c->symbol_rate,
174			c->inversion);
175
176	if (!s->active) {
177		ret = -EAGAIN;
178		goto err;
179	}
180
181	switch (c->delivery_system) {
182	case SYS_DVBT:
183		delivery_system = 0x20;
184		break;
185	case SYS_DVBC_ANNEX_A:
186		delivery_system = 0x30;
187		break;
188	case SYS_DVBT2:
189		delivery_system = 0x70;
190		break;
191	default:
192		ret = -EINVAL;
193		goto err;
194	}
195
196	if (c->bandwidth_hz <= 5000000)
197		bandwidth = 0x05;
198	else if (c->bandwidth_hz <= 6000000)
199		bandwidth = 0x06;
200	else if (c->bandwidth_hz <= 7000000)
201		bandwidth = 0x07;
202	else if (c->bandwidth_hz <= 8000000)
203		bandwidth = 0x08;
204	else if (c->bandwidth_hz <= 9000000)
205		bandwidth = 0x09;
206	else if (c->bandwidth_hz <= 10000000)
207		bandwidth = 0x0a;
208	else
209		bandwidth = 0x0f;
210
211	/* program tuner */
212	if (fe->ops.tuner_ops.set_params) {
213		ret = fe->ops.tuner_ops.set_params(fe);
214		if (ret)
215			goto err;
216	}
217
218	memcpy(cmd.args, "\x88\x02\x02\x02\x02", 5);
219	cmd.wlen = 5;
220	cmd.rlen = 5;
221	ret = si2168_cmd_execute(s, &cmd);
222	if (ret)
223		goto err;
224
225	/* that has no big effect */
226	if (c->delivery_system == SYS_DVBT)
227		memcpy(cmd.args, "\x89\x21\x06\x11\xff\x98", 6);
228	else if (c->delivery_system == SYS_DVBC_ANNEX_A)
229		memcpy(cmd.args, "\x89\x21\x06\x11\x89\xf0", 6);
230	else if (c->delivery_system == SYS_DVBT2)
231		memcpy(cmd.args, "\x89\x21\x06\x11\x89\x20", 6);
232	cmd.wlen = 6;
233	cmd.rlen = 3;
234	ret = si2168_cmd_execute(s, &cmd);
235	if (ret)
236		goto err;
237
238	memcpy(cmd.args, "\x51\x03", 2);
239	cmd.wlen = 2;
240	cmd.rlen = 12;
241	ret = si2168_cmd_execute(s, &cmd);
242	if (ret)
243		goto err;
244
245	memcpy(cmd.args, "\x12\x08\x04", 3);
246	cmd.wlen = 3;
247	cmd.rlen = 3;
248	ret = si2168_cmd_execute(s, &cmd);
249	if (ret)
250		goto err;
251
252	memcpy(cmd.args, "\x14\x00\x0c\x10\x12\x00", 6);
253	cmd.wlen = 6;
254	cmd.rlen = 4;
255	ret = si2168_cmd_execute(s, &cmd);
256	if (ret)
257		goto err;
258
259	memcpy(cmd.args, "\x14\x00\x06\x10\x24\x00", 6);
260	cmd.wlen = 6;
261	cmd.rlen = 4;
262	ret = si2168_cmd_execute(s, &cmd);
263	if (ret)
264		goto err;
265
266	memcpy(cmd.args, "\x14\x00\x07\x10\x00\x24", 6);
267	cmd.wlen = 6;
268	cmd.rlen = 4;
269	ret = si2168_cmd_execute(s, &cmd);
270	if (ret)
271		goto err;
272
273	memcpy(cmd.args, "\x14\x00\x0a\x10\x00\x00", 6);
274	cmd.args[4] = delivery_system | bandwidth;
275	cmd.wlen = 6;
276	cmd.rlen = 4;
277	ret = si2168_cmd_execute(s, &cmd);
278	if (ret)
279		goto err;
280
281	/* set DVB-C symbol rate */
282	if (c->delivery_system == SYS_DVBC_ANNEX_A) {
283		memcpy(cmd.args, "\x14\x00\x02\x11", 4);
284		cmd.args[4] = (c->symbol_rate / 1000) & 0xff;
285		cmd.args[5] = ((c->symbol_rate / 1000) >> 8) & 0xff;
286		cmd.wlen = 6;
287		cmd.rlen = 4;
288		ret = si2168_cmd_execute(s, &cmd);
289		if (ret)
290			goto err;
291	}
292
293	memcpy(cmd.args, "\x14\x00\x0f\x10\x10\x00", 6);
294	cmd.wlen = 6;
295	cmd.rlen = 4;
296	ret = si2168_cmd_execute(s, &cmd);
297	if (ret)
298		goto err;
299
300	memcpy(cmd.args, "\x14\x00\x01\x10\x16\x00", 6);
301	cmd.wlen = 6;
302	cmd.rlen = 4;
303	ret = si2168_cmd_execute(s, &cmd);
304	if (ret)
305		goto err;
306
307	memcpy(cmd.args, "\x14\x00\x09\x10\xe3\x18", 6);
308	cmd.wlen = 6;
309	cmd.rlen = 4;
310	ret = si2168_cmd_execute(s, &cmd);
311	if (ret)
312		goto err;
313
314	memcpy(cmd.args, "\x14\x00\x08\x10\xd7\x15", 6);
315	cmd.wlen = 6;
316	cmd.rlen = 4;
317	ret = si2168_cmd_execute(s, &cmd);
318	if (ret)
319		goto err;
320
321	memcpy(cmd.args, "\x14\x00\x01\x12\x00\x00", 6);
322	cmd.wlen = 6;
323	cmd.rlen = 4;
324	ret = si2168_cmd_execute(s, &cmd);
325	if (ret)
326		goto err;
327
328	memcpy(cmd.args, "\x14\x00\x01\x03\x0c\x00", 6);
329	cmd.wlen = 6;
330	cmd.rlen = 4;
331	ret = si2168_cmd_execute(s, &cmd);
332	if (ret)
333		goto err;
334
335	memcpy(cmd.args, "\x85", 1);
336	cmd.wlen = 1;
337	cmd.rlen = 1;
338	ret = si2168_cmd_execute(s, &cmd);
339	if (ret)
340		goto err;
341
342	s->delivery_system = c->delivery_system;
343
344	return 0;
345err:
346	dev_dbg(&s->client->dev, "%s: failed=%d\n", __func__, ret);
347	return ret;
348}
349
350static int si2168_init(struct dvb_frontend *fe)
351{
352	struct si2168 *s = fe->demodulator_priv;
353	int ret, len, remaining;
354	const struct firmware *fw = NULL;
355	u8 *fw_file;
356	const unsigned int i2c_wr_max = 8;
357	struct si2168_cmd cmd;
358	unsigned int chip_id;
359
360	dev_dbg(&s->client->dev, "%s:\n", __func__);
361
362	memcpy(cmd.args, "\xc0\x12\x00\x0c\x00\x0d\x16\x00\x00\x00\x00\x00\x00", 13);
363	cmd.wlen = 13;
364	cmd.rlen = 0;
365	ret = si2168_cmd_execute(s, &cmd);
366	if (ret)
367		goto err;
368
369	memcpy(cmd.args, "\xc0\x06\x01\x0f\x00\x20\x20\x01", 8);
370	cmd.wlen = 8;
371	cmd.rlen = 1;
372	ret = si2168_cmd_execute(s, &cmd);
373	if (ret)
374		goto err;
375
376	/* query chip revision */
377	memcpy(cmd.args, "\x02", 1);
378	cmd.wlen = 1;
379	cmd.rlen = 13;
380	ret = si2168_cmd_execute(s, &cmd);
381	if (ret)
382		goto err;
383
384	chip_id = cmd.args[1] << 24 | cmd.args[2] << 16 | cmd.args[3] << 8 |
385			cmd.args[4] << 0;
386
387	#define SI2168_A20 ('A' << 24 | 68 << 16 | '2' << 8 | '0' << 0)
388	#define SI2168_A30 ('A' << 24 | 68 << 16 | '3' << 8 | '0' << 0)
389	#define SI2168_B40 ('B' << 24 | 68 << 16 | '4' << 8 | '0' << 0)
390
391	switch (chip_id) {
392	case SI2168_A20:
393		fw_file = SI2168_A20_FIRMWARE;
394		break;
395	case SI2168_A30:
396		fw_file = SI2168_A30_FIRMWARE;
397		break;
398	case SI2168_B40:
399		fw_file = SI2168_B40_FIRMWARE;
400		break;
401	default:
402		dev_err(&s->client->dev,
403				"%s: unkown chip version Si21%d-%c%c%c\n",
404				KBUILD_MODNAME, cmd.args[2], cmd.args[1],
405				cmd.args[3], cmd.args[4]);
406		ret = -EINVAL;
407		goto err;
408	}
409
410	/* cold state - try to download firmware */
411	dev_info(&s->client->dev, "%s: found a '%s' in cold state\n",
412			KBUILD_MODNAME, si2168_ops.info.name);
413
414	/* request the firmware, this will block and timeout */
415	ret = request_firmware(&fw, fw_file, &s->client->dev);
416	if (ret) {
417		/* fallback mechanism to handle old name for Si2168 B40 fw */
418		if (chip_id == SI2168_B40) {
419			fw_file = SI2168_B40_FIRMWARE_FALLBACK;
420			ret = request_firmware(&fw, fw_file, &s->client->dev);
421		}
422
423		if (ret == 0) {
424			dev_notice(&s->client->dev,
425					"%s: please install firmware file '%s'\n",
426					KBUILD_MODNAME, SI2168_B40_FIRMWARE);
427		} else {
428			dev_err(&s->client->dev,
429					"%s: firmware file '%s' not found\n",
430					KBUILD_MODNAME, fw_file);
431			goto err;
432		}
433	}
434
435	dev_info(&s->client->dev, "%s: downloading firmware from file '%s'\n",
436			KBUILD_MODNAME, fw_file);
437
438	for (remaining = fw->size; remaining > 0; remaining -= i2c_wr_max) {
439		len = remaining;
440		if (len > i2c_wr_max)
441			len = i2c_wr_max;
442
443		memcpy(cmd.args, &fw->data[fw->size - remaining], len);
444		cmd.wlen = len;
445		cmd.rlen = 1;
446		ret = si2168_cmd_execute(s, &cmd);
447		if (ret) {
448			dev_err(&s->client->dev,
449					"%s: firmware download failed=%d\n",
450					KBUILD_MODNAME, ret);
451			goto err;
452		}
453	}
454
455	release_firmware(fw);
456	fw = NULL;
457
458	memcpy(cmd.args, "\x01\x01", 2);
459	cmd.wlen = 2;
460	cmd.rlen = 1;
461	ret = si2168_cmd_execute(s, &cmd);
462	if (ret)
463		goto err;
464
465	dev_info(&s->client->dev, "%s: found a '%s' in warm state\n",
466			KBUILD_MODNAME, si2168_ops.info.name);
467
468	s->active = true;
469
470	return 0;
471err:
472	if (fw)
473		release_firmware(fw);
474
475	dev_dbg(&s->client->dev, "%s: failed=%d\n", __func__, ret);
476	return ret;
477}
478
479static int si2168_sleep(struct dvb_frontend *fe)
480{
481	struct si2168 *s = fe->demodulator_priv;
482	int ret;
483	struct si2168_cmd cmd;
484
485	dev_dbg(&s->client->dev, "%s:\n", __func__);
486
487	s->active = false;
488
489	memcpy(cmd.args, "\x13", 1);
490	cmd.wlen = 1;
491	cmd.rlen = 0;
492	ret = si2168_cmd_execute(s, &cmd);
493	if (ret)
494		goto err;
495
496	return 0;
497err:
498	dev_dbg(&s->client->dev, "%s: failed=%d\n", __func__, ret);
499	return ret;
500}
501
502static int si2168_get_tune_settings(struct dvb_frontend *fe,
503	struct dvb_frontend_tune_settings *s)
504{
505	s->min_delay_ms = 900;
506
507	return 0;
508}
509
510/*
511 * I2C gate logic
512 * We must use unlocked i2c_transfer() here because I2C lock is already taken
513 * by tuner driver.
514 */
515static int si2168_select(struct i2c_adapter *adap, void *mux_priv, u32 chan)
516{
517	struct si2168 *s = mux_priv;
518	int ret;
519	struct i2c_msg gate_open_msg = {
520		.addr = s->client->addr,
521		.flags = 0,
522		.len = 3,
523		.buf = "\xc0\x0d\x01",
524	};
525
526	mutex_lock(&s->i2c_mutex);
527
528	/* open tuner I2C gate */
529	ret = __i2c_transfer(s->client->adapter, &gate_open_msg, 1);
530	if (ret != 1) {
531		dev_warn(&s->client->dev, "%s: i2c write failed=%d\n",
532				KBUILD_MODNAME, ret);
533		if (ret >= 0)
534			ret = -EREMOTEIO;
535	} else {
536		ret = 0;
537	}
538
539	return ret;
540}
541
542static int si2168_deselect(struct i2c_adapter *adap, void *mux_priv, u32 chan)
543{
544	struct si2168 *s = mux_priv;
545	int ret;
546	struct i2c_msg gate_close_msg = {
547		.addr = s->client->addr,
548		.flags = 0,
549		.len = 3,
550		.buf = "\xc0\x0d\x00",
551	};
552
553	/* close tuner I2C gate */
554	ret = __i2c_transfer(s->client->adapter, &gate_close_msg, 1);
555	if (ret != 1) {
556		dev_warn(&s->client->dev, "%s: i2c write failed=%d\n",
557				KBUILD_MODNAME, ret);
558		if (ret >= 0)
559			ret = -EREMOTEIO;
560	} else {
561		ret = 0;
562	}
563
564	mutex_unlock(&s->i2c_mutex);
565
566	return ret;
567}
568
569static const struct dvb_frontend_ops si2168_ops = {
570	.delsys = {SYS_DVBT, SYS_DVBT2, SYS_DVBC_ANNEX_A},
571	.info = {
572		.name = "Silicon Labs Si2168",
573		.caps =	FE_CAN_FEC_1_2 |
574			FE_CAN_FEC_2_3 |
575			FE_CAN_FEC_3_4 |
576			FE_CAN_FEC_5_6 |
577			FE_CAN_FEC_7_8 |
578			FE_CAN_FEC_AUTO |
579			FE_CAN_QPSK |
580			FE_CAN_QAM_16 |
581			FE_CAN_QAM_32 |
582			FE_CAN_QAM_64 |
583			FE_CAN_QAM_128 |
584			FE_CAN_QAM_256 |
585			FE_CAN_QAM_AUTO |
586			FE_CAN_TRANSMISSION_MODE_AUTO |
587			FE_CAN_GUARD_INTERVAL_AUTO |
588			FE_CAN_HIERARCHY_AUTO |
589			FE_CAN_MUTE_TS |
590			FE_CAN_2G_MODULATION
591	},
592
593	.get_tune_settings = si2168_get_tune_settings,
594
595	.init = si2168_init,
596	.sleep = si2168_sleep,
597
598	.set_frontend = si2168_set_frontend,
599
600	.read_status = si2168_read_status,
601};
602
603static int si2168_probe(struct i2c_client *client,
604		const struct i2c_device_id *id)
605{
606	struct si2168_config *config = client->dev.platform_data;
607	struct si2168 *s;
608	int ret;
609
610	dev_dbg(&client->dev, "%s:\n", __func__);
611
612	s = kzalloc(sizeof(struct si2168), GFP_KERNEL);
613	if (!s) {
614		ret = -ENOMEM;
615		dev_err(&client->dev, "%s: kzalloc() failed\n", KBUILD_MODNAME);
616		goto err;
617	}
618
619	s->client = client;
620	mutex_init(&s->i2c_mutex);
621
622	/* create mux i2c adapter for tuner */
623	s->adapter = i2c_add_mux_adapter(client->adapter, &client->dev, s,
624			0, 0, 0, si2168_select, si2168_deselect);
625	if (s->adapter == NULL) {
626		ret = -ENODEV;
627		goto err;
628	}
629
630	/* create dvb_frontend */
631	memcpy(&s->fe.ops, &si2168_ops, sizeof(struct dvb_frontend_ops));
632	s->fe.demodulator_priv = s;
633
634	*config->i2c_adapter = s->adapter;
635	*config->fe = &s->fe;
636
637	i2c_set_clientdata(client, s);
638
639	dev_info(&s->client->dev,
640			"%s: Silicon Labs Si2168 successfully attached\n",
641			KBUILD_MODNAME);
642	return 0;
643err:
644	kfree(s);
645	dev_dbg(&client->dev, "%s: failed=%d\n", __func__, ret);
646	return ret;
647}
648
649static int si2168_remove(struct i2c_client *client)
650{
651	struct si2168 *s = i2c_get_clientdata(client);
652
653	dev_dbg(&client->dev, "%s:\n", __func__);
654
655	i2c_del_mux_adapter(s->adapter);
656
657	s->fe.ops.release = NULL;
658	s->fe.demodulator_priv = NULL;
659
660	kfree(s);
661
662	return 0;
663}
664
665static const struct i2c_device_id si2168_id[] = {
666	{"si2168", 0},
667	{}
668};
669MODULE_DEVICE_TABLE(i2c, si2168_id);
670
671static struct i2c_driver si2168_driver = {
672	.driver = {
673		.owner	= THIS_MODULE,
674		.name	= "si2168",
675	},
676	.probe		= si2168_probe,
677	.remove		= si2168_remove,
678	.id_table	= si2168_id,
679};
680
681module_i2c_driver(si2168_driver);
682
683MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
684MODULE_DESCRIPTION("Silicon Labs Si2168 DVB-T/T2/C demodulator driver");
685MODULE_LICENSE("GPL");
686MODULE_FIRMWARE(SI2168_A20_FIRMWARE);
687MODULE_FIRMWARE(SI2168_A30_FIRMWARE);
688MODULE_FIRMWARE(SI2168_B40_FIRMWARE);
689