1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * ZyDAS ZD1301 driver (demodulator)
4 *
5 * Copyright (C) 2015 Antti Palosaari <crope@iki.fi>
6 */
7
8#include "zd1301_demod.h"
9
10static u8 zd1301_demod_gain = 0x38;
11module_param_named(gain, zd1301_demod_gain, byte, 0644);
12MODULE_PARM_DESC(gain, "gain (value: 0x00 - 0x70, default: 0x38)");
13
14struct zd1301_demod_dev {
15 struct platform_device *pdev;
16 struct dvb_frontend frontend;
17 struct i2c_adapter adapter;
18 u8 gain;
19};
20
21static int zd1301_demod_wreg(struct zd1301_demod_dev *dev, u16 reg, u8 val)
22{
23 struct platform_device *pdev = dev->pdev;
24 struct zd1301_demod_platform_data *pdata = pdev->dev.platform_data;
25
26 return pdata->reg_write(pdata->reg_priv, reg, val);
27}
28
29static int zd1301_demod_rreg(struct zd1301_demod_dev *dev, u16 reg, u8 *val)
30{
31 struct platform_device *pdev = dev->pdev;
32 struct zd1301_demod_platform_data *pdata = pdev->dev.platform_data;
33
34 return pdata->reg_read(pdata->reg_priv, reg, val);
35}
36
37static int zd1301_demod_set_frontend(struct dvb_frontend *fe)
38{
39 struct zd1301_demod_dev *dev = fe->demodulator_priv;
40 struct platform_device *pdev = dev->pdev;
41 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
42 int ret;
43 u32 if_frequency;
44 u8 r6a50_val;
45
46 dev_dbg(&pdev->dev, "frequency=%u bandwidth_hz=%u\n",
47 c->frequency, c->bandwidth_hz);
48
49 /* Program tuner */
50 if (fe->ops.tuner_ops.set_params &&
51 fe->ops.tuner_ops.get_if_frequency) {
52 ret = fe->ops.tuner_ops.set_params(fe);
53 if (ret)
54 goto err;
55 ret = fe->ops.tuner_ops.get_if_frequency(fe, &if_frequency);
56 if (ret)
57 goto err;
58 } else {
59 ret = -EINVAL;
60 goto err;
61 }
62
63 dev_dbg(&pdev->dev, "if_frequency=%u\n", if_frequency);
64 if (if_frequency != 36150000) {
65 ret = -EINVAL;
66 goto err;
67 }
68
69 switch (c->bandwidth_hz) {
70 case 6000000:
71 r6a50_val = 0x78;
72 break;
73 case 7000000:
74 r6a50_val = 0x68;
75 break;
76 case 8000000:
77 r6a50_val = 0x58;
78 break;
79 default:
80 ret = -EINVAL;
81 goto err;
82 }
83
84 ret = zd1301_demod_wreg(dev, reg: 0x6a60, val: 0x11);
85 if (ret)
86 goto err;
87 ret = zd1301_demod_wreg(dev, reg: 0x6a47, val: 0x46);
88 if (ret)
89 goto err;
90 ret = zd1301_demod_wreg(dev, reg: 0x6a48, val: 0x46);
91 if (ret)
92 goto err;
93 ret = zd1301_demod_wreg(dev, reg: 0x6a4a, val: 0x15);
94 if (ret)
95 goto err;
96 ret = zd1301_demod_wreg(dev, reg: 0x6a4b, val: 0x63);
97 if (ret)
98 goto err;
99 ret = zd1301_demod_wreg(dev, reg: 0x6a5b, val: 0x99);
100 if (ret)
101 goto err;
102 ret = zd1301_demod_wreg(dev, reg: 0x6a3b, val: 0x10);
103 if (ret)
104 goto err;
105 ret = zd1301_demod_wreg(dev, reg: 0x6806, val: 0x01);
106 if (ret)
107 goto err;
108 ret = zd1301_demod_wreg(dev, reg: 0x6a41, val: 0x08);
109 if (ret)
110 goto err;
111 ret = zd1301_demod_wreg(dev, reg: 0x6a42, val: 0x46);
112 if (ret)
113 goto err;
114 ret = zd1301_demod_wreg(dev, reg: 0x6a44, val: 0x14);
115 if (ret)
116 goto err;
117 ret = zd1301_demod_wreg(dev, reg: 0x6a45, val: 0x67);
118 if (ret)
119 goto err;
120 ret = zd1301_demod_wreg(dev, reg: 0x6a38, val: 0x00);
121 if (ret)
122 goto err;
123 ret = zd1301_demod_wreg(dev, reg: 0x6a4c, val: 0x52);
124 if (ret)
125 goto err;
126 ret = zd1301_demod_wreg(dev, reg: 0x6a49, val: 0x2a);
127 if (ret)
128 goto err;
129 ret = zd1301_demod_wreg(dev, reg: 0x6840, val: 0x2e);
130 if (ret)
131 goto err;
132 ret = zd1301_demod_wreg(dev, reg: 0x6a50, val: r6a50_val);
133 if (ret)
134 goto err;
135 ret = zd1301_demod_wreg(dev, reg: 0x6a38, val: 0x07);
136 if (ret)
137 goto err;
138
139 return 0;
140err:
141 dev_dbg(&pdev->dev, "failed=%d\n", ret);
142 return ret;
143}
144
145static int zd1301_demod_sleep(struct dvb_frontend *fe)
146{
147 struct zd1301_demod_dev *dev = fe->demodulator_priv;
148 struct platform_device *pdev = dev->pdev;
149 int ret;
150
151 dev_dbg(&pdev->dev, "\n");
152
153 ret = zd1301_demod_wreg(dev, reg: 0x6a43, val: 0x70);
154 if (ret)
155 goto err;
156 ret = zd1301_demod_wreg(dev, reg: 0x684e, val: 0x00);
157 if (ret)
158 goto err;
159 ret = zd1301_demod_wreg(dev, reg: 0x6849, val: 0x00);
160 if (ret)
161 goto err;
162 ret = zd1301_demod_wreg(dev, reg: 0x68e2, val: 0xd7);
163 if (ret)
164 goto err;
165 ret = zd1301_demod_wreg(dev, reg: 0x68e0, val: 0x39);
166 if (ret)
167 goto err;
168 ret = zd1301_demod_wreg(dev, reg: 0x6840, val: 0x21);
169 if (ret)
170 goto err;
171
172 return 0;
173err:
174 dev_dbg(&pdev->dev, "failed=%d\n", ret);
175 return ret;
176}
177
178static int zd1301_demod_init(struct dvb_frontend *fe)
179{
180 struct zd1301_demod_dev *dev = fe->demodulator_priv;
181 struct platform_device *pdev = dev->pdev;
182 int ret;
183
184 dev_dbg(&pdev->dev, "\n");
185
186 ret = zd1301_demod_wreg(dev, reg: 0x6840, val: 0x26);
187 if (ret)
188 goto err;
189 ret = zd1301_demod_wreg(dev, reg: 0x68e0, val: 0xff);
190 if (ret)
191 goto err;
192 ret = zd1301_demod_wreg(dev, reg: 0x68e2, val: 0xd8);
193 if (ret)
194 goto err;
195 ret = zd1301_demod_wreg(dev, reg: 0x6849, val: 0x4e);
196 if (ret)
197 goto err;
198 ret = zd1301_demod_wreg(dev, reg: 0x684e, val: 0x01);
199 if (ret)
200 goto err;
201 ret = zd1301_demod_wreg(dev, reg: 0x6a43, val: zd1301_demod_gain);
202 if (ret)
203 goto err;
204
205 return 0;
206err:
207 dev_dbg(&pdev->dev, "failed=%d\n", ret);
208 return ret;
209}
210
211static int zd1301_demod_get_tune_settings(struct dvb_frontend *fe,
212 struct dvb_frontend_tune_settings *settings)
213{
214 struct zd1301_demod_dev *dev = fe->demodulator_priv;
215 struct platform_device *pdev = dev->pdev;
216
217 dev_dbg(&pdev->dev, "\n");
218
219 /* ~180ms seems to be enough */
220 settings->min_delay_ms = 400;
221
222 return 0;
223}
224
225static int zd1301_demod_read_status(struct dvb_frontend *fe,
226 enum fe_status *status)
227{
228 struct zd1301_demod_dev *dev = fe->demodulator_priv;
229 struct platform_device *pdev = dev->pdev;
230 int ret;
231 u8 u8tmp;
232
233 ret = zd1301_demod_rreg(dev, reg: 0x6a24, val: &u8tmp);
234 if (ret)
235 goto err;
236 if (u8tmp > 0x00 && u8tmp < 0x20)
237 *status = FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI |
238 FE_HAS_SYNC | FE_HAS_LOCK;
239 else
240 *status = 0;
241
242 dev_dbg(&pdev->dev, "lock byte=%02x\n", u8tmp);
243
244 /*
245 * Interesting registers here are:
246 * 0x6a05: get some gain value
247 * 0x6a06: get about same gain value than set to 0x6a43
248 * 0x6a07: get some gain value
249 * 0x6a43: set gain value by driver
250 * 0x6a24: get demod lock bits (FSM stage?)
251 *
252 * Driver should implement some kind of algorithm to calculate suitable
253 * value for register 0x6a43, based likely values from register 0x6a05
254 * and 0x6a07. Looks like gain register 0x6a43 value could be from
255 * range 0x00 - 0x70.
256 */
257
258 if (dev->gain != zd1301_demod_gain) {
259 dev->gain = zd1301_demod_gain;
260
261 ret = zd1301_demod_wreg(dev, reg: 0x6a43, val: dev->gain);
262 if (ret)
263 goto err;
264 }
265
266 return 0;
267err:
268 dev_dbg(&pdev->dev, "failed=%d\n", ret);
269 return ret;
270}
271
272static const struct dvb_frontend_ops zd1301_demod_ops = {
273 .delsys = {SYS_DVBT},
274 .info = {
275 .name = "ZyDAS ZD1301",
276 .caps = FE_CAN_FEC_1_2 |
277 FE_CAN_FEC_2_3 |
278 FE_CAN_FEC_3_4 |
279 FE_CAN_FEC_5_6 |
280 FE_CAN_FEC_7_8 |
281 FE_CAN_FEC_AUTO |
282 FE_CAN_QPSK |
283 FE_CAN_QAM_16 |
284 FE_CAN_QAM_64 |
285 FE_CAN_QAM_AUTO |
286 FE_CAN_TRANSMISSION_MODE_AUTO |
287 FE_CAN_GUARD_INTERVAL_AUTO |
288 FE_CAN_HIERARCHY_AUTO |
289 FE_CAN_MUTE_TS
290 },
291
292 .sleep = zd1301_demod_sleep,
293 .init = zd1301_demod_init,
294 .set_frontend = zd1301_demod_set_frontend,
295 .get_tune_settings = zd1301_demod_get_tune_settings,
296 .read_status = zd1301_demod_read_status,
297};
298
299struct dvb_frontend *zd1301_demod_get_dvb_frontend(struct platform_device *pdev)
300{
301 struct zd1301_demod_dev *dev = platform_get_drvdata(pdev);
302
303 dev_dbg(&pdev->dev, "\n");
304
305 return &dev->frontend;
306}
307EXPORT_SYMBOL(zd1301_demod_get_dvb_frontend);
308
309static int zd1301_demod_i2c_master_xfer(struct i2c_adapter *adapter,
310 struct i2c_msg msg[], int num)
311{
312 struct zd1301_demod_dev *dev = i2c_get_adapdata(adap: adapter);
313 struct platform_device *pdev = dev->pdev;
314 int ret, i;
315 unsigned long timeout;
316 u8 u8tmp;
317
318 #define I2C_XFER_TIMEOUT 5
319 #define ZD1301_IS_I2C_XFER_WRITE_READ(_msg, _num) \
320 (_num == 2 && !(_msg[0].flags & I2C_M_RD) && (_msg[1].flags & I2C_M_RD))
321 #define ZD1301_IS_I2C_XFER_WRITE(_msg, _num) \
322 (_num == 1 && !(_msg[0].flags & I2C_M_RD))
323 #define ZD1301_IS_I2C_XFER_READ(_msg, _num) \
324 (_num == 1 && (_msg[0].flags & I2C_M_RD))
325 if (ZD1301_IS_I2C_XFER_WRITE_READ(msg, num)) {
326 dev_dbg(&pdev->dev, "write&read msg[0].len=%u msg[1].len=%u\n",
327 msg[0].len, msg[1].len);
328 if (msg[0].len > 1 || msg[1].len > 8) {
329 ret = -EOPNOTSUPP;
330 goto err;
331 }
332
333 ret = zd1301_demod_wreg(dev, reg: 0x6811, val: 0x80);
334 if (ret)
335 goto err;
336 ret = zd1301_demod_wreg(dev, reg: 0x6812, val: 0x05);
337 if (ret)
338 goto err;
339 ret = zd1301_demod_wreg(dev, reg: 0x6813, val: msg[1].addr << 1);
340 if (ret)
341 goto err;
342 ret = zd1301_demod_wreg(dev, reg: 0x6801, val: msg[0].buf[0]);
343 if (ret)
344 goto err;
345 ret = zd1301_demod_wreg(dev, reg: 0x6802, val: 0x00);
346 if (ret)
347 goto err;
348 ret = zd1301_demod_wreg(dev, reg: 0x6803, val: 0x06);
349 if (ret)
350 goto err;
351 ret = zd1301_demod_wreg(dev, reg: 0x6805, val: 0x00);
352 if (ret)
353 goto err;
354 ret = zd1301_demod_wreg(dev, reg: 0x6804, val: msg[1].len);
355 if (ret)
356 goto err;
357
358 /* Poll xfer ready */
359 timeout = jiffies + msecs_to_jiffies(I2C_XFER_TIMEOUT);
360 for (u8tmp = 1; !time_after(jiffies, timeout) && u8tmp;) {
361 usleep_range(min: 500, max: 800);
362
363 ret = zd1301_demod_rreg(dev, reg: 0x6804, val: &u8tmp);
364 if (ret)
365 goto err;
366 }
367
368 for (i = 0; i < msg[1].len; i++) {
369 ret = zd1301_demod_rreg(dev, reg: 0x0600 + i, val: &msg[1].buf[i]);
370 if (ret)
371 goto err;
372 }
373 } else if (ZD1301_IS_I2C_XFER_WRITE(msg, num)) {
374 dev_dbg(&pdev->dev, "write msg[0].len=%u\n", msg[0].len);
375 if (msg[0].len > 1 + 8) {
376 ret = -EOPNOTSUPP;
377 goto err;
378 }
379
380 ret = zd1301_demod_wreg(dev, reg: 0x6811, val: 0x80);
381 if (ret)
382 goto err;
383 ret = zd1301_demod_wreg(dev, reg: 0x6812, val: 0x01);
384 if (ret)
385 goto err;
386 ret = zd1301_demod_wreg(dev, reg: 0x6813, val: msg[0].addr << 1);
387 if (ret)
388 goto err;
389 ret = zd1301_demod_wreg(dev, reg: 0x6800, val: msg[0].buf[0]);
390 if (ret)
391 goto err;
392 ret = zd1301_demod_wreg(dev, reg: 0x6802, val: 0x00);
393 if (ret)
394 goto err;
395 ret = zd1301_demod_wreg(dev, reg: 0x6803, val: 0x06);
396 if (ret)
397 goto err;
398
399 for (i = 0; i < msg[0].len - 1; i++) {
400 ret = zd1301_demod_wreg(dev, reg: 0x0600 + i, val: msg[0].buf[1 + i]);
401 if (ret)
402 goto err;
403 }
404
405 ret = zd1301_demod_wreg(dev, reg: 0x6805, val: 0x80);
406 if (ret)
407 goto err;
408 ret = zd1301_demod_wreg(dev, reg: 0x6804, val: msg[0].len - 1);
409 if (ret)
410 goto err;
411
412 /* Poll xfer ready */
413 timeout = jiffies + msecs_to_jiffies(I2C_XFER_TIMEOUT);
414 for (u8tmp = 1; !time_after(jiffies, timeout) && u8tmp;) {
415 usleep_range(min: 500, max: 800);
416
417 ret = zd1301_demod_rreg(dev, reg: 0x6804, val: &u8tmp);
418 if (ret)
419 goto err;
420 }
421 } else {
422 dev_dbg(&pdev->dev, "unknown msg[0].len=%u\n", msg[0].len);
423 ret = -EOPNOTSUPP;
424 goto err;
425 }
426
427 return num;
428err:
429 dev_dbg(&pdev->dev, "failed=%d\n", ret);
430 return ret;
431}
432
433static u32 zd1301_demod_i2c_functionality(struct i2c_adapter *adapter)
434{
435 return I2C_FUNC_I2C;
436}
437
438static const struct i2c_algorithm zd1301_demod_i2c_algorithm = {
439 .master_xfer = zd1301_demod_i2c_master_xfer,
440 .functionality = zd1301_demod_i2c_functionality,
441};
442
443struct i2c_adapter *zd1301_demod_get_i2c_adapter(struct platform_device *pdev)
444{
445 struct zd1301_demod_dev *dev = platform_get_drvdata(pdev);
446
447 dev_dbg(&pdev->dev, "\n");
448
449 return &dev->adapter;
450}
451EXPORT_SYMBOL(zd1301_demod_get_i2c_adapter);
452
453/* Platform driver interface */
454static int zd1301_demod_probe(struct platform_device *pdev)
455{
456 struct zd1301_demod_dev *dev;
457 struct zd1301_demod_platform_data *pdata = pdev->dev.platform_data;
458 int ret;
459
460 dev_dbg(&pdev->dev, "\n");
461
462 if (!pdata) {
463 ret = -EINVAL;
464 dev_err(&pdev->dev, "cannot proceed without platform data\n");
465 goto err;
466 }
467 if (!pdev->dev.parent->driver) {
468 ret = -EINVAL;
469 dev_dbg(&pdev->dev, "no parent device\n");
470 goto err;
471 }
472
473 dev = kzalloc(size: sizeof(*dev), GFP_KERNEL);
474 if (!dev) {
475 ret = -ENOMEM;
476 goto err;
477 }
478
479 /* Setup the state */
480 dev->pdev = pdev;
481 dev->gain = zd1301_demod_gain;
482
483 /* Sleep */
484 ret = zd1301_demod_wreg(dev, reg: 0x6840, val: 0x21);
485 if (ret)
486 goto err_kfree;
487 ret = zd1301_demod_wreg(dev, reg: 0x6a38, val: 0x07);
488 if (ret)
489 goto err_kfree;
490
491 /* Create I2C adapter */
492 strscpy(p: dev->adapter.name, q: "ZyDAS ZD1301 demod",
493 size: sizeof(dev->adapter.name));
494 dev->adapter.algo = &zd1301_demod_i2c_algorithm;
495 dev->adapter.algo_data = NULL;
496 dev->adapter.dev.parent = pdev->dev.parent;
497 i2c_set_adapdata(adap: &dev->adapter, data: dev);
498 ret = i2c_add_adapter(adap: &dev->adapter);
499 if (ret) {
500 dev_err(&pdev->dev, "I2C adapter add failed %d\n", ret);
501 goto err_kfree;
502 }
503
504 /* Create dvb frontend */
505 memcpy(&dev->frontend.ops, &zd1301_demod_ops, sizeof(dev->frontend.ops));
506 dev->frontend.demodulator_priv = dev;
507 platform_set_drvdata(pdev, data: dev);
508 dev_info(&pdev->dev, "ZyDAS ZD1301 demod attached\n");
509
510 return 0;
511err_kfree:
512 kfree(objp: dev);
513err:
514 dev_dbg(&pdev->dev, "failed=%d\n", ret);
515 return ret;
516}
517
518static void zd1301_demod_remove(struct platform_device *pdev)
519{
520 struct zd1301_demod_dev *dev = platform_get_drvdata(pdev);
521
522 dev_dbg(&pdev->dev, "\n");
523
524 i2c_del_adapter(adap: &dev->adapter);
525 kfree(objp: dev);
526}
527
528static struct platform_driver zd1301_demod_driver = {
529 .driver = {
530 .name = "zd1301_demod",
531 .suppress_bind_attrs = true,
532 },
533 .probe = zd1301_demod_probe,
534 .remove_new = zd1301_demod_remove,
535};
536module_platform_driver(zd1301_demod_driver);
537
538MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
539MODULE_DESCRIPTION("ZyDAS ZD1301 demodulator driver");
540MODULE_LICENSE("GPL");
541

source code of linux/drivers/media/dvb-frontends/zd1301_demod.c