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