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