Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.5.6.
  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, 0x6a60, 0x11);
 85	if (ret)
 86		goto err;
 87	ret = zd1301_demod_wreg(dev, 0x6a47, 0x46);
 88	if (ret)
 89		goto err;
 90	ret = zd1301_demod_wreg(dev, 0x6a48, 0x46);
 91	if (ret)
 92		goto err;
 93	ret = zd1301_demod_wreg(dev, 0x6a4a, 0x15);
 94	if (ret)
 95		goto err;
 96	ret = zd1301_demod_wreg(dev, 0x6a4b, 0x63);
 97	if (ret)
 98		goto err;
 99	ret = zd1301_demod_wreg(dev, 0x6a5b, 0x99);
100	if (ret)
101		goto err;
102	ret = zd1301_demod_wreg(dev, 0x6a3b, 0x10);
103	if (ret)
104		goto err;
105	ret = zd1301_demod_wreg(dev, 0x6806, 0x01);
106	if (ret)
107		goto err;
108	ret = zd1301_demod_wreg(dev, 0x6a41, 0x08);
109	if (ret)
110		goto err;
111	ret = zd1301_demod_wreg(dev, 0x6a42, 0x46);
112	if (ret)
113		goto err;
114	ret = zd1301_demod_wreg(dev, 0x6a44, 0x14);
115	if (ret)
116		goto err;
117	ret = zd1301_demod_wreg(dev, 0x6a45, 0x67);
118	if (ret)
119		goto err;
120	ret = zd1301_demod_wreg(dev, 0x6a38, 0x00);
121	if (ret)
122		goto err;
123	ret = zd1301_demod_wreg(dev, 0x6a4c, 0x52);
124	if (ret)
125		goto err;
126	ret = zd1301_demod_wreg(dev, 0x6a49, 0x2a);
127	if (ret)
128		goto err;
129	ret = zd1301_demod_wreg(dev, 0x6840, 0x2e);
130	if (ret)
131		goto err;
132	ret = zd1301_demod_wreg(dev, 0x6a50, r6a50_val);
133	if (ret)
134		goto err;
135	ret = zd1301_demod_wreg(dev, 0x6a38, 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, 0x6a43, 0x70);
154	if (ret)
155		goto err;
156	ret = zd1301_demod_wreg(dev, 0x684e, 0x00);
157	if (ret)
158		goto err;
159	ret = zd1301_demod_wreg(dev, 0x6849, 0x00);
160	if (ret)
161		goto err;
162	ret = zd1301_demod_wreg(dev, 0x68e2, 0xd7);
163	if (ret)
164		goto err;
165	ret = zd1301_demod_wreg(dev, 0x68e0, 0x39);
166	if (ret)
167		goto err;
168	ret = zd1301_demod_wreg(dev, 0x6840, 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, 0x6840, 0x26);
187	if (ret)
188		goto err;
189	ret = zd1301_demod_wreg(dev, 0x68e0, 0xff);
190	if (ret)
191		goto err;
192	ret = zd1301_demod_wreg(dev, 0x68e2, 0xd8);
193	if (ret)
194		goto err;
195	ret = zd1301_demod_wreg(dev, 0x6849, 0x4e);
196	if (ret)
197		goto err;
198	ret = zd1301_demod_wreg(dev, 0x684e, 0x01);
199	if (ret)
200		goto err;
201	ret = zd1301_demod_wreg(dev, 0x6a43, 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, 0x6a24, &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, 0x6a43, 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(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, 0x6811, 0x80);
334		if (ret)
335			goto err;
336		ret = zd1301_demod_wreg(dev, 0x6812, 0x05);
337		if (ret)
338			goto err;
339		ret = zd1301_demod_wreg(dev, 0x6813, msg[1].addr << 1);
340		if (ret)
341			goto err;
342		ret = zd1301_demod_wreg(dev, 0x6801, msg[0].buf[0]);
343		if (ret)
344			goto err;
345		ret = zd1301_demod_wreg(dev, 0x6802, 0x00);
346		if (ret)
347			goto err;
348		ret = zd1301_demod_wreg(dev, 0x6803, 0x06);
349		if (ret)
350			goto err;
351		ret = zd1301_demod_wreg(dev, 0x6805, 0x00);
352		if (ret)
353			goto err;
354		ret = zd1301_demod_wreg(dev, 0x6804, 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(500, 800);
362
363			ret = zd1301_demod_rreg(dev, 0x6804, &u8tmp);
364			if (ret)
365				goto err;
366		}
367
368		for (i = 0; i < msg[1].len; i++) {
369			ret = zd1301_demod_rreg(dev, 0x0600 + i, &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, 0x6811, 0x80);
381		if (ret)
382			goto err;
383		ret = zd1301_demod_wreg(dev, 0x6812, 0x01);
384		if (ret)
385			goto err;
386		ret = zd1301_demod_wreg(dev, 0x6813, msg[0].addr << 1);
387		if (ret)
388			goto err;
389		ret = zd1301_demod_wreg(dev, 0x6800, msg[0].buf[0]);
390		if (ret)
391			goto err;
392		ret = zd1301_demod_wreg(dev, 0x6802, 0x00);
393		if (ret)
394			goto err;
395		ret = zd1301_demod_wreg(dev, 0x6803, 0x06);
396		if (ret)
397			goto err;
398
399		for (i = 0; i < msg[0].len - 1; i++) {
400			ret = zd1301_demod_wreg(dev, 0x0600 + i, msg[0].buf[1 + i]);
401			if (ret)
402				goto err;
403		}
404
405		ret = zd1301_demod_wreg(dev, 0x6805, 0x80);
406		if (ret)
407			goto err;
408		ret = zd1301_demod_wreg(dev, 0x6804, 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(500, 800);
416
417			ret = zd1301_demod_rreg(dev, 0x6804, &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(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, 0x6840, 0x21);
485	if (ret)
486		goto err_kfree;
487	ret = zd1301_demod_wreg(dev, 0x6a38, 0x07);
488	if (ret)
489		goto err_kfree;
490
491	/* Create I2C adapter */
492	strscpy(dev->adapter.name, "ZyDAS ZD1301 demod",
493		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(&dev->adapter, dev);
498	ret = i2c_add_adapter(&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, dev);
508	dev_info(&pdev->dev, "ZyDAS ZD1301 demod attached\n");
509
510	return 0;
511err_kfree:
512	kfree(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(&dev->adapter);
525	kfree(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");