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