1 /*
2  * Sony CXD2820R demodulator driver
3  *
4  * Copyright (C) 2010 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  *    You should have received a copy of the GNU General Public License along
17  *    with this program; if not, write to the Free Software Foundation, Inc.,
18  *    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19  */
20 
21 
22 #include "cxd2820r_priv.h"
23 
24 int cxd2820r_debug;
25 module_param_named(debug, cxd2820r_debug, int, 0644);
26 MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
27 
28 /* write multiple registers */
cxd2820r_wr_regs_i2c(struct cxd2820r_priv * priv,u8 i2c,u8 reg,u8 * val,int len)29 static int cxd2820r_wr_regs_i2c(struct cxd2820r_priv *priv, u8 i2c, u8 reg,
30 	u8 *val, int len)
31 {
32 	int ret;
33 	u8 buf[len+1];
34 	struct i2c_msg msg[1] = {
35 		{
36 			.addr = i2c,
37 			.flags = 0,
38 			.len = sizeof(buf),
39 			.buf = buf,
40 		}
41 	};
42 
43 	buf[0] = reg;
44 	memcpy(&buf[1], val, len);
45 
46 	ret = i2c_transfer(priv->i2c, msg, 1);
47 	if (ret == 1) {
48 		ret = 0;
49 	} else {
50 		warn("i2c wr failed ret:%d reg:%02x len:%d", ret, reg, len);
51 		ret = -EREMOTEIO;
52 	}
53 	return ret;
54 }
55 
56 /* read multiple registers */
cxd2820r_rd_regs_i2c(struct cxd2820r_priv * priv,u8 i2c,u8 reg,u8 * val,int len)57 static int cxd2820r_rd_regs_i2c(struct cxd2820r_priv *priv, u8 i2c, u8 reg,
58 	u8 *val, int len)
59 {
60 	int ret;
61 	u8 buf[len];
62 	struct i2c_msg msg[2] = {
63 		{
64 			.addr = i2c,
65 			.flags = 0,
66 			.len = 1,
67 			.buf = &reg,
68 		}, {
69 			.addr = i2c,
70 			.flags = I2C_M_RD,
71 			.len = sizeof(buf),
72 			.buf = buf,
73 		}
74 	};
75 
76 	ret = i2c_transfer(priv->i2c, msg, 2);
77 	if (ret == 2) {
78 		memcpy(val, buf, len);
79 		ret = 0;
80 	} else {
81 		warn("i2c rd failed ret:%d reg:%02x len:%d", ret, reg, len);
82 		ret = -EREMOTEIO;
83 	}
84 
85 	return ret;
86 }
87 
88 /* write multiple registers */
cxd2820r_wr_regs(struct cxd2820r_priv * priv,u32 reginfo,u8 * val,int len)89 int cxd2820r_wr_regs(struct cxd2820r_priv *priv, u32 reginfo, u8 *val,
90 	int len)
91 {
92 	int ret;
93 	u8 i2c_addr;
94 	u8 reg = (reginfo >> 0) & 0xff;
95 	u8 bank = (reginfo >> 8) & 0xff;
96 	u8 i2c = (reginfo >> 16) & 0x01;
97 
98 	/* select I2C */
99 	if (i2c)
100 		i2c_addr = priv->cfg.i2c_address | (1 << 1); /* DVB-C */
101 	else
102 		i2c_addr = priv->cfg.i2c_address; /* DVB-T/T2 */
103 
104 	/* switch bank if needed */
105 	if (bank != priv->bank[i2c]) {
106 		ret = cxd2820r_wr_regs_i2c(priv, i2c_addr, 0x00, &bank, 1);
107 		if (ret)
108 			return ret;
109 		priv->bank[i2c] = bank;
110 	}
111 	return cxd2820r_wr_regs_i2c(priv, i2c_addr, reg, val, len);
112 }
113 
114 /* read multiple registers */
cxd2820r_rd_regs(struct cxd2820r_priv * priv,u32 reginfo,u8 * val,int len)115 int cxd2820r_rd_regs(struct cxd2820r_priv *priv, u32 reginfo, u8 *val,
116 	int len)
117 {
118 	int ret;
119 	u8 i2c_addr;
120 	u8 reg = (reginfo >> 0) & 0xff;
121 	u8 bank = (reginfo >> 8) & 0xff;
122 	u8 i2c = (reginfo >> 16) & 0x01;
123 
124 	/* select I2C */
125 	if (i2c)
126 		i2c_addr = priv->cfg.i2c_address | (1 << 1); /* DVB-C */
127 	else
128 		i2c_addr = priv->cfg.i2c_address; /* DVB-T/T2 */
129 
130 	/* switch bank if needed */
131 	if (bank != priv->bank[i2c]) {
132 		ret = cxd2820r_wr_regs_i2c(priv, i2c_addr, 0x00, &bank, 1);
133 		if (ret)
134 			return ret;
135 		priv->bank[i2c] = bank;
136 	}
137 	return cxd2820r_rd_regs_i2c(priv, i2c_addr, reg, val, len);
138 }
139 
140 /* write single register */
cxd2820r_wr_reg(struct cxd2820r_priv * priv,u32 reg,u8 val)141 int cxd2820r_wr_reg(struct cxd2820r_priv *priv, u32 reg, u8 val)
142 {
143 	return cxd2820r_wr_regs(priv, reg, &val, 1);
144 }
145 
146 /* read single register */
cxd2820r_rd_reg(struct cxd2820r_priv * priv,u32 reg,u8 * val)147 int cxd2820r_rd_reg(struct cxd2820r_priv *priv, u32 reg, u8 *val)
148 {
149 	return cxd2820r_rd_regs(priv, reg, val, 1);
150 }
151 
152 /* write single register with mask */
cxd2820r_wr_reg_mask(struct cxd2820r_priv * priv,u32 reg,u8 val,u8 mask)153 int cxd2820r_wr_reg_mask(struct cxd2820r_priv *priv, u32 reg, u8 val,
154 	u8 mask)
155 {
156 	int ret;
157 	u8 tmp;
158 
159 	/* no need for read if whole reg is written */
160 	if (mask != 0xff) {
161 		ret = cxd2820r_rd_reg(priv, reg, &tmp);
162 		if (ret)
163 			return ret;
164 
165 		val &= mask;
166 		tmp &= ~mask;
167 		val |= tmp;
168 	}
169 
170 	return cxd2820r_wr_reg(priv, reg, val);
171 }
172 
cxd2820r_gpio(struct dvb_frontend * fe)173 int cxd2820r_gpio(struct dvb_frontend *fe)
174 {
175 	struct cxd2820r_priv *priv = fe->demodulator_priv;
176 	int ret, i;
177 	u8 *gpio, tmp0, tmp1;
178 	dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system);
179 
180 	switch (fe->dtv_property_cache.delivery_system) {
181 	case SYS_DVBT:
182 		gpio = priv->cfg.gpio_dvbt;
183 		break;
184 	case SYS_DVBT2:
185 		gpio = priv->cfg.gpio_dvbt2;
186 		break;
187 	case SYS_DVBC_ANNEX_AC:
188 		gpio = priv->cfg.gpio_dvbc;
189 		break;
190 	default:
191 		ret = -EINVAL;
192 		goto error;
193 	}
194 
195 	/* update GPIOs only when needed */
196 	if (!memcmp(gpio, priv->gpio, sizeof(priv->gpio)))
197 		return 0;
198 
199 	tmp0 = 0x00;
200 	tmp1 = 0x00;
201 	for (i = 0; i < sizeof(priv->gpio); i++) {
202 		/* enable / disable */
203 		if (gpio[i] & CXD2820R_GPIO_E)
204 			tmp0 |= (2 << 6) >> (2 * i);
205 		else
206 			tmp0 |= (1 << 6) >> (2 * i);
207 
208 		/* input / output */
209 		if (gpio[i] & CXD2820R_GPIO_I)
210 			tmp1 |= (1 << (3 + i));
211 		else
212 			tmp1 |= (0 << (3 + i));
213 
214 		/* high / low */
215 		if (gpio[i] & CXD2820R_GPIO_H)
216 			tmp1 |= (1 << (0 + i));
217 		else
218 			tmp1 |= (0 << (0 + i));
219 
220 		dbg("%s: GPIO i=%d %02x %02x", __func__, i, tmp0, tmp1);
221 	}
222 
223 	dbg("%s: wr gpio=%02x %02x", __func__, tmp0, tmp1);
224 
225 	/* write bits [7:2] */
226 	ret = cxd2820r_wr_reg_mask(priv, 0x00089, tmp0, 0xfc);
227 	if (ret)
228 		goto error;
229 
230 	/* write bits [5:0] */
231 	ret = cxd2820r_wr_reg_mask(priv, 0x0008e, tmp1, 0x3f);
232 	if (ret)
233 		goto error;
234 
235 	memcpy(priv->gpio, gpio, sizeof(priv->gpio));
236 
237 	return ret;
238 error:
239 	dbg("%s: failed:%d", __func__, ret);
240 	return ret;
241 }
242 
243 /* 64 bit div with round closest, like DIV_ROUND_CLOSEST but 64 bit */
cxd2820r_div_u64_round_closest(u64 dividend,u32 divisor)244 u32 cxd2820r_div_u64_round_closest(u64 dividend, u32 divisor)
245 {
246 	return div_u64(dividend + (divisor / 2), divisor);
247 }
248 
cxd2820r_set_frontend(struct dvb_frontend * fe)249 static int cxd2820r_set_frontend(struct dvb_frontend *fe)
250 {
251 	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
252 	int ret;
253 
254 	dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system);
255 	switch (c->delivery_system) {
256 	case SYS_DVBT:
257 		ret = cxd2820r_init_t(fe);
258 		if (ret < 0)
259 			goto err;
260 		ret = cxd2820r_set_frontend_t(fe);
261 		if (ret < 0)
262 			goto err;
263 		break;
264 	case SYS_DVBT2:
265 		ret = cxd2820r_init_t(fe);
266 		if (ret < 0)
267 			goto err;
268 		ret = cxd2820r_set_frontend_t2(fe);
269 		if (ret < 0)
270 			goto err;
271 		break;
272 	case SYS_DVBC_ANNEX_A:
273 		ret = cxd2820r_init_c(fe);
274 		if (ret < 0)
275 			goto err;
276 		ret = cxd2820r_set_frontend_c(fe);
277 		if (ret < 0)
278 			goto err;
279 		break;
280 	default:
281 		dbg("%s: error state=%d", __func__, fe->dtv_property_cache.delivery_system);
282 		ret = -EINVAL;
283 		break;
284 	}
285 err:
286 	return ret;
287 }
cxd2820r_read_status(struct dvb_frontend * fe,fe_status_t * status)288 static int cxd2820r_read_status(struct dvb_frontend *fe, fe_status_t *status)
289 {
290 	int ret;
291 
292 	dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system);
293 	switch (fe->dtv_property_cache.delivery_system) {
294 	case SYS_DVBT:
295 		ret = cxd2820r_read_status_t(fe, status);
296 		break;
297 	case SYS_DVBT2:
298 		ret = cxd2820r_read_status_t2(fe, status);
299 		break;
300 	case SYS_DVBC_ANNEX_A:
301 		ret = cxd2820r_read_status_c(fe, status);
302 		break;
303 	default:
304 		ret = -EINVAL;
305 		break;
306 	}
307 	return ret;
308 }
309 
cxd2820r_get_frontend(struct dvb_frontend * fe)310 static int cxd2820r_get_frontend(struct dvb_frontend *fe)
311 {
312 	struct cxd2820r_priv *priv = fe->demodulator_priv;
313 	int ret;
314 
315 	dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system);
316 
317 	if (priv->delivery_system == SYS_UNDEFINED)
318 		return 0;
319 
320 	switch (fe->dtv_property_cache.delivery_system) {
321 	case SYS_DVBT:
322 		ret = cxd2820r_get_frontend_t(fe);
323 		break;
324 	case SYS_DVBT2:
325 		ret = cxd2820r_get_frontend_t2(fe);
326 		break;
327 	case SYS_DVBC_ANNEX_A:
328 		ret = cxd2820r_get_frontend_c(fe);
329 		break;
330 	default:
331 		ret = -EINVAL;
332 		break;
333 	}
334 	return ret;
335 }
336 
cxd2820r_read_ber(struct dvb_frontend * fe,u32 * ber)337 static int cxd2820r_read_ber(struct dvb_frontend *fe, u32 *ber)
338 {
339 	int ret;
340 
341 	dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system);
342 	switch (fe->dtv_property_cache.delivery_system) {
343 	case SYS_DVBT:
344 		ret = cxd2820r_read_ber_t(fe, ber);
345 		break;
346 	case SYS_DVBT2:
347 		ret = cxd2820r_read_ber_t2(fe, ber);
348 		break;
349 	case SYS_DVBC_ANNEX_A:
350 		ret = cxd2820r_read_ber_c(fe, ber);
351 		break;
352 	default:
353 		ret = -EINVAL;
354 		break;
355 	}
356 	return ret;
357 }
358 
cxd2820r_read_signal_strength(struct dvb_frontend * fe,u16 * strength)359 static int cxd2820r_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
360 {
361 	int ret;
362 
363 	dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system);
364 	switch (fe->dtv_property_cache.delivery_system) {
365 	case SYS_DVBT:
366 		ret = cxd2820r_read_signal_strength_t(fe, strength);
367 		break;
368 	case SYS_DVBT2:
369 		ret = cxd2820r_read_signal_strength_t2(fe, strength);
370 		break;
371 	case SYS_DVBC_ANNEX_A:
372 		ret = cxd2820r_read_signal_strength_c(fe, strength);
373 		break;
374 	default:
375 		ret = -EINVAL;
376 		break;
377 	}
378 	return ret;
379 }
380 
cxd2820r_read_snr(struct dvb_frontend * fe,u16 * snr)381 static int cxd2820r_read_snr(struct dvb_frontend *fe, u16 *snr)
382 {
383 	int ret;
384 
385 	dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system);
386 	switch (fe->dtv_property_cache.delivery_system) {
387 	case SYS_DVBT:
388 		ret = cxd2820r_read_snr_t(fe, snr);
389 		break;
390 	case SYS_DVBT2:
391 		ret = cxd2820r_read_snr_t2(fe, snr);
392 		break;
393 	case SYS_DVBC_ANNEX_A:
394 		ret = cxd2820r_read_snr_c(fe, snr);
395 		break;
396 	default:
397 		ret = -EINVAL;
398 		break;
399 	}
400 	return ret;
401 }
402 
cxd2820r_read_ucblocks(struct dvb_frontend * fe,u32 * ucblocks)403 static int cxd2820r_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
404 {
405 	int ret;
406 
407 	dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system);
408 	switch (fe->dtv_property_cache.delivery_system) {
409 	case SYS_DVBT:
410 		ret = cxd2820r_read_ucblocks_t(fe, ucblocks);
411 		break;
412 	case SYS_DVBT2:
413 		ret = cxd2820r_read_ucblocks_t2(fe, ucblocks);
414 		break;
415 	case SYS_DVBC_ANNEX_A:
416 		ret = cxd2820r_read_ucblocks_c(fe, ucblocks);
417 		break;
418 	default:
419 		ret = -EINVAL;
420 		break;
421 	}
422 	return ret;
423 }
424 
cxd2820r_init(struct dvb_frontend * fe)425 static int cxd2820r_init(struct dvb_frontend *fe)
426 {
427 	return 0;
428 }
429 
cxd2820r_sleep(struct dvb_frontend * fe)430 static int cxd2820r_sleep(struct dvb_frontend *fe)
431 {
432 	int ret;
433 
434 	dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system);
435 	switch (fe->dtv_property_cache.delivery_system) {
436 	case SYS_DVBT:
437 		ret = cxd2820r_sleep_t(fe);
438 		break;
439 	case SYS_DVBT2:
440 		ret = cxd2820r_sleep_t2(fe);
441 		break;
442 	case SYS_DVBC_ANNEX_A:
443 		ret = cxd2820r_sleep_c(fe);
444 		break;
445 	default:
446 		ret = -EINVAL;
447 		break;
448 	}
449 	return ret;
450 }
451 
cxd2820r_get_tune_settings(struct dvb_frontend * fe,struct dvb_frontend_tune_settings * s)452 static int cxd2820r_get_tune_settings(struct dvb_frontend *fe,
453 				      struct dvb_frontend_tune_settings *s)
454 {
455 	int ret;
456 
457 	dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system);
458 	switch (fe->dtv_property_cache.delivery_system) {
459 	case SYS_DVBT:
460 		ret = cxd2820r_get_tune_settings_t(fe, s);
461 		break;
462 	case SYS_DVBT2:
463 		ret = cxd2820r_get_tune_settings_t2(fe, s);
464 		break;
465 	case SYS_DVBC_ANNEX_A:
466 		ret = cxd2820r_get_tune_settings_c(fe, s);
467 		break;
468 	default:
469 		ret = -EINVAL;
470 		break;
471 	}
472 	return ret;
473 }
474 
cxd2820r_search(struct dvb_frontend * fe)475 static enum dvbfe_search cxd2820r_search(struct dvb_frontend *fe)
476 {
477 	struct cxd2820r_priv *priv = fe->demodulator_priv;
478 	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
479 	int ret, i;
480 	fe_status_t status = 0;
481 	dbg("%s: delsys=%d", __func__, fe->dtv_property_cache.delivery_system);
482 
483 	/* switch between DVB-T and DVB-T2 when tune fails */
484 	if (priv->last_tune_failed) {
485 		if (priv->delivery_system == SYS_DVBT) {
486 			ret = cxd2820r_sleep_t(fe);
487 			if (ret)
488 				goto error;
489 
490 			c->delivery_system = SYS_DVBT2;
491 		} else if (priv->delivery_system == SYS_DVBT2) {
492 			ret = cxd2820r_sleep_t2(fe);
493 			if (ret)
494 				goto error;
495 
496 			c->delivery_system = SYS_DVBT;
497 		}
498 	}
499 
500 	/* set frontend */
501 	ret = cxd2820r_set_frontend(fe);
502 	if (ret)
503 		goto error;
504 
505 
506 	/* frontend lock wait loop count */
507 	switch (priv->delivery_system) {
508 	case SYS_DVBT:
509 	case SYS_DVBC_ANNEX_A:
510 		i = 20;
511 		break;
512 	case SYS_DVBT2:
513 		i = 40;
514 		break;
515 	case SYS_UNDEFINED:
516 	default:
517 		i = 0;
518 		break;
519 	}
520 
521 	/* wait frontend lock */
522 	for (; i > 0; i--) {
523 		dbg("%s: LOOP=%d", __func__, i);
524 		msleep(50);
525 		ret = cxd2820r_read_status(fe, &status);
526 		if (ret)
527 			goto error;
528 
529 		if (status & FE_HAS_SIGNAL)
530 			break;
531 	}
532 
533 	/* check if we have a valid signal */
534 	if (status) {
535 		priv->last_tune_failed = 0;
536 		return DVBFE_ALGO_SEARCH_SUCCESS;
537 	} else {
538 		priv->last_tune_failed = 1;
539 		return DVBFE_ALGO_SEARCH_AGAIN;
540 	}
541 
542 error:
543 	dbg("%s: failed:%d", __func__, ret);
544 	return DVBFE_ALGO_SEARCH_ERROR;
545 }
546 
cxd2820r_get_frontend_algo(struct dvb_frontend * fe)547 static int cxd2820r_get_frontend_algo(struct dvb_frontend *fe)
548 {
549 	return DVBFE_ALGO_CUSTOM;
550 }
551 
cxd2820r_release(struct dvb_frontend * fe)552 static void cxd2820r_release(struct dvb_frontend *fe)
553 {
554 	struct cxd2820r_priv *priv = fe->demodulator_priv;
555 	dbg("%s", __func__);
556 
557 	kfree(priv);
558 	return;
559 }
560 
cxd2820r_i2c_gate_ctrl(struct dvb_frontend * fe,int enable)561 static int cxd2820r_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
562 {
563 	struct cxd2820r_priv *priv = fe->demodulator_priv;
564 	dbg("%s: %d", __func__, enable);
565 
566 	/* Bit 0 of reg 0xdb in bank 0x00 controls I2C repeater */
567 	return cxd2820r_wr_reg_mask(priv, 0xdb, enable ? 1 : 0, 0x1);
568 }
569 
570 static const struct dvb_frontend_ops cxd2820r_ops = {
571 	.delsys = { SYS_DVBT, SYS_DVBT2, SYS_DVBC_ANNEX_A },
572 	/* default: DVB-T/T2 */
573 	.info = {
574 		.name = "Sony CXD2820R",
575 
576 		.caps =	FE_CAN_FEC_1_2			|
577 			FE_CAN_FEC_2_3			|
578 			FE_CAN_FEC_3_4			|
579 			FE_CAN_FEC_5_6			|
580 			FE_CAN_FEC_7_8			|
581 			FE_CAN_FEC_AUTO			|
582 			FE_CAN_QPSK			|
583 			FE_CAN_QAM_16			|
584 			FE_CAN_QAM_32			|
585 			FE_CAN_QAM_64			|
586 			FE_CAN_QAM_128			|
587 			FE_CAN_QAM_256			|
588 			FE_CAN_QAM_AUTO			|
589 			FE_CAN_TRANSMISSION_MODE_AUTO	|
590 			FE_CAN_GUARD_INTERVAL_AUTO	|
591 			FE_CAN_HIERARCHY_AUTO		|
592 			FE_CAN_MUTE_TS			|
593 			FE_CAN_2G_MODULATION
594 		},
595 
596 	.release		= cxd2820r_release,
597 	.init			= cxd2820r_init,
598 	.sleep			= cxd2820r_sleep,
599 
600 	.get_tune_settings	= cxd2820r_get_tune_settings,
601 	.i2c_gate_ctrl		= cxd2820r_i2c_gate_ctrl,
602 
603 	.get_frontend		= cxd2820r_get_frontend,
604 
605 	.get_frontend_algo	= cxd2820r_get_frontend_algo,
606 	.search			= cxd2820r_search,
607 
608 	.read_status		= cxd2820r_read_status,
609 	.read_snr		= cxd2820r_read_snr,
610 	.read_ber		= cxd2820r_read_ber,
611 	.read_ucblocks		= cxd2820r_read_ucblocks,
612 	.read_signal_strength	= cxd2820r_read_signal_strength,
613 };
614 
cxd2820r_attach(const struct cxd2820r_config * cfg,struct i2c_adapter * i2c)615 struct dvb_frontend *cxd2820r_attach(const struct cxd2820r_config *cfg,
616 		struct i2c_adapter *i2c)
617 {
618 	struct cxd2820r_priv *priv = NULL;
619 	int ret;
620 	u8 tmp;
621 
622 	priv = kzalloc(sizeof (struct cxd2820r_priv), GFP_KERNEL);
623 	if (!priv)
624 		goto error;
625 
626 	priv->i2c = i2c;
627 	memcpy(&priv->cfg, cfg, sizeof (struct cxd2820r_config));
628 
629 	priv->bank[0] = priv->bank[1] = 0xff;
630 	ret = cxd2820r_rd_reg(priv, 0x000fd, &tmp);
631 	dbg("%s: chip id=%02x", __func__, tmp);
632 	if (ret || tmp != 0xe1)
633 		goto error;
634 
635 	memcpy(&priv->fe.ops, &cxd2820r_ops, sizeof (struct dvb_frontend_ops));
636 	priv->fe.demodulator_priv = priv;
637 	return &priv->fe;
638 error:
639 	kfree(priv);
640 	return NULL;
641 }
642 EXPORT_SYMBOL(cxd2820r_attach);
643 
644 MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
645 MODULE_DESCRIPTION("Sony CXD2820R demodulator driver");
646 MODULE_LICENSE("GPL");
647