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