1 /* $NetBSD: zl10353.c,v 1.5 2017/06/01 02:45:10 chs Exp $ */
2
3 /*-
4 * Copyright (c) 2011 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Jukka Ruohonen.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 *
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
31 */
32 #include <sys/cdefs.h>
33 __KERNEL_RCSID(0, "$NetBSD: zl10353.c,v 1.5 2017/06/01 02:45:10 chs Exp $");
34
35 #include <sys/param.h>
36 #include <sys/kmem.h>
37 #include <sys/module.h>
38
39 #include <dev/dtv/dtvif.h>
40
41 #include <dev/i2c/i2cvar.h>
42 #include <dev/i2c/zl10353reg.h>
43 #include <dev/i2c/zl10353var.h>
44
45 /*
46 * Zarlink ZL10353 demodulator (now known as Intel CE623x).
47 *
48 * An incomplete datasheet:
49 *
50 * Intel Corporation: CE6230 - COFDM demodulator with
51 * USB interface for PC-TV. Data Sheet, Revision 1.1.
52 * March 29, 2007.
53 */
54
55 static int zl10353_probe(struct zl10353 *);
56 static int zl10353_read(struct zl10353 *, uint8_t, uint8_t *);
57 static int zl10353_write(struct zl10353 *, uint8_t, uint8_t);
58 static int zl10353_reset(struct zl10353 *, bool);
59 static int zl10353_set_agc(struct zl10353 *,
60 const struct dvb_frontend_parameters *);
61 static int zl10353_set_bw(struct zl10353 *, fe_bandwidth_t);
62 static int zl10353_set_rate(struct zl10353 *);
63 static int zl10353_set_freq(struct zl10353 *);
64 static int zl10353_set_tps(struct zl10353 *,
65 const struct dvb_frontend_parameters *);
66 static int zl10353_get_guard(fe_guard_interval_t, uint16_t *);
67 static int zl10353_get_mode(fe_transmit_mode_t, uint16_t *);
68 static int zl10353_get_fec(fe_code_rate_t, bool, uint16_t *);
69 static int zl10353_get_modulation(fe_modulation_t, uint16_t *);
70 static int zl10353_get_hier(fe_hierarchy_t, uint16_t *);
71
72 struct zl10353 *
zl10353_open(device_t parent,i2c_tag_t i2c,i2c_addr_t addr)73 zl10353_open(device_t parent, i2c_tag_t i2c, i2c_addr_t addr)
74 {
75 struct zl10353 *zl;
76
77 zl = kmem_zalloc(sizeof(*zl), KM_SLEEP);
78 zl->zl_i2c = i2c;
79 zl->zl_i2c_addr = addr;
80 zl->zl_parent = parent;
81
82 zl->zl_freq = ZL10353_DEFAULT_INPUT_FREQ;
83 zl->zl_clock = ZL10353_DEFAULT_CLOCK_MHZ;
84
85 if (zl10353_reset(zl, true) != 0) {
86 zl10353_close(zl);
87 return NULL;
88 }
89
90 if (zl10353_probe(zl) != 0) {
91 zl10353_close(zl);
92 return NULL;
93 }
94
95 return zl;
96 }
97
98 void
zl10353_close(struct zl10353 * zl)99 zl10353_close(struct zl10353 *zl)
100 {
101 kmem_free(zl, sizeof(*zl));
102 }
103
104 static int
zl10353_probe(struct zl10353 * zl)105 zl10353_probe(struct zl10353 *zl)
106 {
107 uint8_t val;
108 int rv;
109
110 if ((rv = zl10353_read(zl, ZL10353_REG_ID, &val)) != 0)
111 return rv;
112
113 switch (val) {
114
115 case ZL10353_ID_CE6230:
116 zl->zl_name = "Intel CE6230";
117 break;
118
119 case ZL10353_ID_CE6231:
120 zl->zl_name = "Intel CE6231";
121 break;
122
123 case ZL10353_ID_ZL10353:
124 zl->zl_name = "Zarlink ZL10353";
125 break;
126
127 default:
128 aprint_error_dev(zl->zl_parent, "unknown chip 0x%02x\n", val);
129 return ENOTSUP;
130 }
131
132 aprint_verbose_dev(zl->zl_parent, "found %s at i2c "
133 "addr 0x%02x\n", zl->zl_name, zl->zl_i2c_addr);
134
135 return 0;
136 }
137
138 static int
zl10353_read(struct zl10353 * zl,uint8_t reg,uint8_t * valp)139 zl10353_read(struct zl10353 *zl, uint8_t reg, uint8_t *valp)
140 {
141 static const i2c_op_t op = I2C_OP_READ;
142 int rv;
143
144 if ((rv = iic_acquire_bus(zl->zl_i2c, 0)) != 0)
145 return rv;
146
147 rv = iic_exec(zl->zl_i2c, op, zl->zl_i2c_addr, ®, 1, valp, 1, 0);
148 iic_release_bus(zl->zl_i2c, 0);
149
150 return rv;
151 }
152
153 static int
zl10353_write(struct zl10353 * zl,uint8_t reg,uint8_t val)154 zl10353_write(struct zl10353 *zl, uint8_t reg, uint8_t val)
155 {
156 static const i2c_op_t op = I2C_OP_WRITE;
157 const uint8_t cmd[2] = { reg, val };
158 int rv;
159
160 if ((rv = iic_acquire_bus(zl->zl_i2c, 0)) != 0)
161 return rv;
162
163 rv = iic_exec(zl->zl_i2c, op, zl->zl_i2c_addr, cmd, 2, NULL, 0, 0);
164 iic_release_bus(zl->zl_i2c, 0);
165
166 return rv;
167 }
168
169 static int
zl10353_reset(struct zl10353 * zl,bool hard)170 zl10353_reset(struct zl10353 *zl, bool hard)
171 {
172 size_t i = 0, len = 5;
173 int rv;
174
175 static const struct {
176 uint8_t reg;
177 uint8_t val;
178 } reset[] = {
179 { 0x50, 0x03 }, /* Hard */
180 { 0x03, 0x44 },
181 { 0x44, 0x46 },
182 { 0x46, 0x15 },
183 { 0x15, 0x0f },
184 { 0x55, 0x80 }, /* Soft */
185 { 0xea, 0x01 },
186 { 0xea, 0x00 },
187 };
188
189 if (hard != true) {
190 len = __arraycount(reset);
191 i = 5;
192 }
193
194 while (i < len) {
195
196 if ((rv = zl10353_write(zl, reset[i].reg, reset[i].val)) != 0)
197 return rv;
198 else {
199 delay(100);
200 }
201
202 i++;
203
204 }
205
206 return 0;
207 }
208
209 void
zl10353_get_devinfo(struct dvb_frontend_info * fi)210 zl10353_get_devinfo(struct dvb_frontend_info *fi)
211 {
212
213 fi->type = FE_OFDM;
214
215 fi->frequency_min = 174000000;
216 fi->frequency_max = 862000000;
217
218 fi->frequency_tolerance = 0;
219 fi->frequency_stepsize = 166667;
220
221 fi->caps |= FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
222 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_QPSK |
223 FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_RECOVER |
224 FE_CAN_MUTE_TS;
225
226 fi->caps |= FE_CAN_FEC_AUTO | FE_CAN_TRANSMISSION_MODE_AUTO |
227 FE_CAN_QAM_AUTO | FE_CAN_GUARD_INTERVAL_AUTO |
228 FE_CAN_HIERARCHY_AUTO;
229 }
230
231 int
zl10353_set_params(struct zl10353 * zl,const struct dvb_frontend_parameters * fp)232 zl10353_set_params(struct zl10353 *zl,const struct dvb_frontend_parameters *fp)
233 {
234 int rv;
235
236 /* 1. Soft reset. */
237 if ((rv = zl10353_reset(zl, false)) != 0)
238 return rv;
239
240 /* 2. Set AGC. */
241 if ((rv = zl10353_set_agc(zl, fp)) != 0)
242 return rv;
243
244 /* 3. Set bandwidth. */
245 if ((rv = zl10353_set_bw(zl, fp->u.ofdm.bandwidth)) != 0)
246 return rv;
247
248 /* 4. Set nominal rate. */
249 if ((rv = zl10353_set_rate(zl)) != 0)
250 return rv;
251
252 /* 5. Set input frequency. */
253 if ((rv = zl10353_set_freq(zl)) != 0)
254 return rv;
255
256 /* 6. Set TPS parameters. */
257 if ((rv = zl10353_set_tps(zl, fp)) != 0)
258 return rv;
259
260 return 0;
261 }
262
263 int
zl10353_set_fsm(struct zl10353 * zl)264 zl10353_set_fsm(struct zl10353 *zl)
265 {
266 return zl10353_write(zl, ZL10353_REG_FSM, ZL10353_FSM_START);
267 }
268
269 int
zl10353_set_gate(void * aux,bool enable)270 zl10353_set_gate(void *aux, bool enable)
271 {
272 uint8_t val = ZL10353_GATE_DISABLE;
273
274 if (enable != false)
275 val = ZL10353_GATE_ENABLE;
276
277 return zl10353_write(aux, ZL10353_REG_GATE, val);
278 }
279
280 static int
zl10353_set_agc(struct zl10353 * zl,const struct dvb_frontend_parameters * fp)281 zl10353_set_agc(struct zl10353 *zl, const struct dvb_frontend_parameters *fp)
282 {
283 const struct dvb_ofdm_parameters *ofdm = &fp->u.ofdm;
284 uint8_t val = ZL10353_AGC_TARGET_DEFAULT;
285 int rv;
286
287 if ((rv = zl10353_write(zl, ZL10353_REG_AGC_TARGET, val)) != 0)
288 return rv;
289 else {
290 val = 0;
291 }
292
293 if (ofdm->guard_interval != GUARD_INTERVAL_AUTO)
294 val |= ZL10353_AGC_CTRL_GUARD_NONAUTO;
295
296 if (ofdm->transmission_mode != TRANSMISSION_MODE_AUTO)
297 val |= ZL10353_AGC_CTRL_MODE_NONAUTO;
298
299 return zl10353_write(zl, ZL10353_REG_AGC_CTRL, val);
300 }
301
302 static int
zl10353_set_bw(struct zl10353 * zl,fe_bandwidth_t bw)303 zl10353_set_bw(struct zl10353 *zl, fe_bandwidth_t bw)
304 {
305 uint8_t val[3];
306 int rv;
307
308 switch (bw) {
309
310 case BANDWIDTH_6_MHZ:
311 val[0] = ZL10353_BW_1_6_MHZ;
312 val[1] = ZL10353_BW_2_6_MHZ;
313 val[2] = ZL10353_BW_3_6_MHZ;
314 zl->zl_bw = 6;
315 break;
316
317 case BANDWIDTH_7_MHZ:
318 val[0] = ZL10353_BW_1_7_MHZ;
319 val[1] = ZL10353_BW_2_7_MHZ;
320 val[2] = ZL10353_BW_3_7_MHZ;
321 zl->zl_bw = 7;
322 break;
323
324 case BANDWIDTH_8_MHZ:
325 val[0] = ZL10353_BW_1_8_MHZ;
326 val[1] = ZL10353_BW_2_8_MHZ;
327 val[2] = ZL10353_BW_3_8_MHZ;
328 zl->zl_bw = 8;
329 break;
330
331 default:
332 zl->zl_bw = 0;
333 return EINVAL;
334 }
335
336 if ((rv = zl10353_write(zl, ZL10353_REG_BW_1, val[0])) != 0)
337 return rv;
338
339 if ((rv = zl10353_write(zl, ZL10353_REG_BW_2, val[1])) != 0)
340 return rv;
341
342 if ((rv = zl10353_write(zl, ZL10353_REG_BW_3, val[2])) != 0)
343 return rv;
344
345 return 0;
346 }
347
348 static int
zl10353_set_rate(struct zl10353 * zl)349 zl10353_set_rate(struct zl10353 *zl)
350 {
351 static const uint64_t c = 1497965625;
352 uint64_t val;
353 int rv;
354
355 KASSERT(zl->zl_bw >= 6 && zl->zl_bw <= 8);
356 KASSERT(zl->zl_clock > 0 && zl->zl_freq > 0);
357
358 val = zl->zl_bw * c;
359 val += zl->zl_clock >> 1;
360 val /= zl->zl_clock;
361 val = val & 0xffff;
362
363 if ((rv = zl10353_write(zl, ZL10353_REG_RATE_1, val >> 8)) != 0)
364 return rv;
365
366 return zl10353_write(zl, ZL10353_REG_RATE_2, val & 0xff);
367 }
368
369 static int
zl10353_set_freq(struct zl10353 * zl)370 zl10353_set_freq(struct zl10353 *zl)
371 {
372 const uint16_t val = zl->zl_freq;
373 int rv;
374
375 if ((rv = zl10353_write(zl, ZL10353_REG_FREQ_1, val >> 8)) != 0)
376 return rv;
377
378 return zl10353_write(zl, ZL10353_REG_FREQ_2, val & 0xff);
379 }
380
381 static int
zl10353_set_tps(struct zl10353 * zl,const struct dvb_frontend_parameters * fp)382 zl10353_set_tps(struct zl10353 *zl, const struct dvb_frontend_parameters *fp)
383 {
384 const struct dvb_ofdm_parameters *ofdm = &fp->u.ofdm;
385 uint16_t val = 0;
386 int rv;
387
388 if ((rv = zl10353_get_guard(ofdm->guard_interval, &val)) != 0)
389 goto fail;
390
391 if ((rv = zl10353_get_mode(ofdm->transmission_mode, &val)) != 0)
392 goto fail;
393
394 if ((rv = zl10353_get_fec(ofdm->code_rate_HP, true, &val)) != 0)
395 goto fail;
396
397 if ((rv = zl10353_get_fec(ofdm->code_rate_LP, false, &val)) != 0)
398 goto fail;
399
400 if ((rv = zl10353_get_modulation(ofdm->constellation, &val)) != 0)
401 goto fail;
402
403 if ((rv = zl10353_get_hier(ofdm->hierarchy_information, &val)) != 0)
404 goto fail;
405
406 if ((rv = zl10353_write(zl, ZL10353_REG_TPS_1, val >> 8)) != 0)
407 goto fail;
408
409 if ((rv = zl10353_write(zl, ZL10353_REG_TPS_2, val & 0xff)) != 0)
410 goto fail;
411
412 return 0;
413
414 fail:
415 aprint_error_dev(zl->zl_parent, "failed to set "
416 "tps for %s (err %d)\n", zl->zl_name, rv);
417
418 return rv;
419 }
420
421 static int
zl10353_get_guard(fe_guard_interval_t fg,uint16_t * valp)422 zl10353_get_guard(fe_guard_interval_t fg, uint16_t *valp)
423 {
424
425 switch (fg) {
426
427 case GUARD_INTERVAL_1_4:
428 *valp |= ZL10353_TPS_GUARD_1_4;
429 break;
430
431 case GUARD_INTERVAL_1_8:
432 *valp |= ZL10353_TPS_GUARD_1_8;
433 break;
434
435 case GUARD_INTERVAL_1_16:
436 *valp |= ZL10353_TPS_GUARD_1_16;
437 break;
438
439 case GUARD_INTERVAL_1_32:
440 *valp |= ZL10353_TPS_GUARD_1_32;
441 break;
442
443 case GUARD_INTERVAL_AUTO:
444 *valp |= ZL10353_TPS_GUARD_AUTO;
445 break;
446
447 default:
448 return EINVAL;
449 }
450
451 return 0;
452 }
453
454 static int
zl10353_get_mode(fe_transmit_mode_t fm,uint16_t * valp)455 zl10353_get_mode(fe_transmit_mode_t fm, uint16_t *valp)
456 {
457
458 switch (fm) {
459
460 case TRANSMISSION_MODE_2K:
461 *valp |= ZL10353_TPS_MODE_2K;
462 break;
463
464 case TRANSMISSION_MODE_8K:
465 *valp |= ZL10353_TPS_MODE_8K;
466 break;
467
468 case TRANSMISSION_MODE_AUTO:
469 *valp |= ZL10353_TPS_MODE_AUTO;
470 break;
471
472 default:
473 return EINVAL;
474 }
475
476 return 0;
477 }
478
479 static int
zl10353_get_fec(fe_code_rate_t fc,bool hp,uint16_t * valp)480 zl10353_get_fec(fe_code_rate_t fc, bool hp, uint16_t *valp)
481 {
482 uint16_t hpval = 0, lpval = 0;
483
484 switch (fc) {
485
486 case FEC_1_2:
487 hpval = ZL10353_TPS_HP_FEC_1_2;
488 lpval = ZL10353_TPS_LP_FEC_1_2;
489 break;
490
491 case FEC_2_3:
492 hpval = ZL10353_TPS_HP_FEC_2_3;
493 lpval = ZL10353_TPS_LP_FEC_2_3;
494 break;
495
496 case FEC_3_4:
497 hpval = ZL10353_TPS_HP_FEC_3_4;
498 lpval = ZL10353_TPS_LP_FEC_3_4;
499 break;
500
501 case FEC_5_6:
502 hpval = ZL10353_TPS_HP_FEC_5_6;
503 lpval = ZL10353_TPS_LP_FEC_5_6;
504 break;
505
506 case FEC_7_8:
507 hpval = ZL10353_TPS_HP_FEC_7_8;
508 lpval = ZL10353_TPS_LP_FEC_7_8;
509 break;
510
511 case FEC_AUTO:
512 hpval = ZL10353_TPS_HP_FEC_AUTO;
513 lpval = ZL10353_TPS_LP_FEC_AUTO;
514 break;
515
516 case FEC_NONE:
517 return EOPNOTSUPP;
518
519 default:
520 return EINVAL;
521 }
522
523 *valp |= (hp != false) ? hpval : lpval;
524
525 return 0;
526 }
527
528 static int
zl10353_get_modulation(fe_modulation_t fm,uint16_t * valp)529 zl10353_get_modulation(fe_modulation_t fm, uint16_t *valp)
530 {
531
532 switch (fm) {
533
534 case QPSK:
535 *valp |= ZL10353_TPS_MODULATION_QPSK;
536 break;
537
538 case QAM_16:
539 *valp |= ZL10353_TPS_MODULATION_QAM_16;
540 break;
541
542 case QAM_64:
543 *valp |= ZL10353_TPS_MODULATION_QAM_64;
544 break;
545
546 case QAM_AUTO:
547 *valp |= ZL10353_TPS_MODULATION_QAM_AUTO;
548 break;
549
550 default:
551 return EINVAL;
552 }
553
554 return 0;
555 }
556
557 static int
zl10353_get_hier(fe_hierarchy_t fh,uint16_t * valp)558 zl10353_get_hier(fe_hierarchy_t fh, uint16_t *valp)
559 {
560
561 switch (fh) {
562
563 case HIERARCHY_1:
564 *valp |= ZL10353_TPS_HIERARCHY_1;
565 break;
566
567 case HIERARCHY_2:
568 *valp |= ZL10353_TPS_HIERARCHY_2;
569 break;
570
571 case HIERARCHY_4:
572 *valp |= ZL10353_TPS_HIERARCHY_4;
573 break;
574
575 case HIERARCHY_NONE:
576 *valp |= ZL10353_TPS_HIERARCHY_NONE;
577 break;
578
579 case HIERARCHY_AUTO:
580 *valp |= ZL10353_TPS_HIERARCHY_AUTO;
581 break;
582
583 default:
584 return EINVAL;
585 }
586
587 return 0;
588 }
589
590 fe_status_t
zl10353_get_status(struct zl10353 * zl)591 zl10353_get_status(struct zl10353 *zl)
592 {
593 const uint8_t lock = FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC;
594 fe_status_t fs = 0;
595 uint8_t val;
596
597 if (zl10353_read(zl, ZL10353_REG_STATUS_LOCK, &val) == 0) {
598
599 if ((val & ZL10353_STATUS_LOCK_ON) != 0)
600 fs |= FE_HAS_LOCK;
601
602 if ((val & ZL10353_STATUS_LOCK_CARRIER) != 0)
603 fs |= FE_HAS_CARRIER;
604
605 if ((val & ZL10353_STATUS_LOCK_VITERBI) != 0)
606 fs |= FE_HAS_VITERBI;
607 }
608
609 if (zl10353_read(zl, ZL10353_REG_STATUS_SYNC, &val) == 0) {
610
611 if ((val & ZL10353_STATUS_SYNC_ON) != 0)
612 fs |= FE_HAS_SYNC;
613 }
614
615 if (zl10353_read(zl, ZL10353_REG_STATUS_SIGNAL, &val) == 0) {
616
617 if ((val & ZL10353_STATUS_SIGNAL_ON) != 0)
618 fs |= FE_HAS_SIGNAL;
619 }
620
621 return ((fs & lock) != lock) ? fs & ~FE_HAS_LOCK : fs;
622 };
623
624 uint16_t
zl10353_get_signal_strength(struct zl10353 * zl)625 zl10353_get_signal_strength(struct zl10353 *zl)
626 {
627 uint8_t val1, val2;
628
629 if (zl10353_read(zl, ZL10353_REG_SIGSTR_1, &val1) != 0)
630 return 0;
631
632 if (zl10353_read(zl, ZL10353_REG_SIGSTR_2, &val2) != 0)
633 return 0;
634
635 return val1 << 10 | val2 << 2 | 0x03;
636 }
637
638 uint16_t
zl10353_get_snr(struct zl10353 * zl)639 zl10353_get_snr(struct zl10353 *zl)
640 {
641 uint8_t val;
642
643 if (zl10353_read(zl, ZL10353_REG_SNR, &val) != 0)
644 return 0;
645
646 return (val << 8) | val;
647 }
648
649 MODULE(MODULE_CLASS_DRIVER, zl10353, "i2cexec");
650
651 static int
zl10353_modcmd(modcmd_t cmd,void * aux)652 zl10353_modcmd(modcmd_t cmd, void *aux)
653 {
654
655 if (cmd != MODULE_CMD_INIT && cmd != MODULE_CMD_FINI)
656 return ENOTTY;
657
658 return 0;
659 }
660