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 
19 static const struct dvb_frontend_ops si2168_ops;
20 
21 /* execute firmware command */
22 static 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 
71 err_mutex_unlock:
72 	mutex_unlock(&s->i2c_mutex);
73 	if (ret)
74 		goto err;
75 
76 	return 0;
77 err:
78 	dev_dbg(&s->client->dev, "%s: failed=%d\n", __func__, ret);
79 	return ret;
80 }
81 
82 static 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;
157 err:
158 	dev_dbg(&s->client->dev, "%s: failed=%d\n", __func__, ret);
159 	return ret;
160 }
161 
162 static 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;
345 err:
346 	dev_dbg(&s->client->dev, "%s: failed=%d\n", __func__, ret);
347 	return ret;
348 }
349 
350 static 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;
471 err:
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 
479 static 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;
497 err:
498 	dev_dbg(&s->client->dev, "%s: failed=%d\n", __func__, ret);
499 	return ret;
500 }
501 
502 static 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  */
515 static 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 
542 static 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 
569 static 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 
603 static 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;
643 err:
644 	kfree(s);
645 	dev_dbg(&client->dev, "%s: failed=%d\n", __func__, ret);
646 	return ret;
647 }
648 
649 static 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 
665 static const struct i2c_device_id si2168_id[] = {
666 	{"si2168", 0},
667 	{}
668 };
669 MODULE_DEVICE_TABLE(i2c, si2168_id);
670 
671 static 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 
681 module_i2c_driver(si2168_driver);
682 
683 MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
684 MODULE_DESCRIPTION("Silicon Labs Si2168 DVB-T/T2/C demodulator driver");
685 MODULE_LICENSE("GPL");
686 MODULE_FIRMWARE(SI2168_A20_FIRMWARE);
687 MODULE_FIRMWARE(SI2168_A30_FIRMWARE);
688 MODULE_FIRMWARE(SI2168_B40_FIRMWARE);
689