xref: /linux/drivers/media/dvb-frontends/cxd2820r_t.c (revision 24bce201d79807b668bf9d9e0aca801c5c0d5f78)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Sony CXD2820R demodulator driver
4  *
5  * Copyright (C) 2010 Antti Palosaari <crope@iki.fi>
6  */
7 
8 
9 #include "cxd2820r_priv.h"
10 
11 int cxd2820r_set_frontend_t(struct dvb_frontend *fe)
12 {
13 	struct cxd2820r_priv *priv = fe->demodulator_priv;
14 	struct i2c_client *client = priv->client[0];
15 	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
16 	int ret, bw_i;
17 	unsigned int utmp;
18 	u32 if_frequency;
19 	u8 buf[3], bw_param;
20 	u8 bw_params1[][5] = {
21 		{ 0x17, 0xea, 0xaa, 0xaa, 0xaa }, /* 6 MHz */
22 		{ 0x14, 0x80, 0x00, 0x00, 0x00 }, /* 7 MHz */
23 		{ 0x11, 0xf0, 0x00, 0x00, 0x00 }, /* 8 MHz */
24 	};
25 	u8 bw_params2[][2] = {
26 		{ 0x1f, 0xdc }, /* 6 MHz */
27 		{ 0x12, 0xf8 }, /* 7 MHz */
28 		{ 0x01, 0xe0 }, /* 8 MHz */
29 	};
30 	struct reg_val_mask tab[] = {
31 		{ 0x00080, 0x00, 0xff },
32 		{ 0x00081, 0x03, 0xff },
33 		{ 0x00085, 0x07, 0xff },
34 		{ 0x00088, 0x01, 0xff },
35 
36 		{ 0x00070, priv->ts_mode, 0xff },
37 		{ 0x00071, !priv->ts_clk_inv << 4, 0x10 },
38 		{ 0x000cb, priv->if_agc_polarity << 6, 0x40 },
39 		{ 0x000a5, 0x00, 0x01 },
40 		{ 0x00082, 0x20, 0x60 },
41 		{ 0x000c2, 0xc3, 0xff },
42 		{ 0x0016a, 0x50, 0xff },
43 		{ 0x00427, 0x41, 0xff },
44 	};
45 
46 	dev_dbg(&client->dev,
47 		"delivery_system=%d modulation=%d frequency=%u bandwidth_hz=%u inversion=%d\n",
48 		c->delivery_system, c->modulation, c->frequency,
49 		c->bandwidth_hz, c->inversion);
50 
51 	switch (c->bandwidth_hz) {
52 	case 6000000:
53 		bw_i = 0;
54 		bw_param = 2;
55 		break;
56 	case 7000000:
57 		bw_i = 1;
58 		bw_param = 1;
59 		break;
60 	case 8000000:
61 		bw_i = 2;
62 		bw_param = 0;
63 		break;
64 	default:
65 		return -EINVAL;
66 	}
67 
68 	/* program tuner */
69 	if (fe->ops.tuner_ops.set_params)
70 		fe->ops.tuner_ops.set_params(fe);
71 
72 	if (priv->delivery_system != SYS_DVBT) {
73 		ret = cxd2820r_wr_reg_val_mask_tab(priv, tab, ARRAY_SIZE(tab));
74 		if (ret)
75 			goto error;
76 	}
77 
78 	priv->delivery_system = SYS_DVBT;
79 	priv->ber_running = false; /* tune stops BER counter */
80 
81 	/* program IF frequency */
82 	if (fe->ops.tuner_ops.get_if_frequency) {
83 		ret = fe->ops.tuner_ops.get_if_frequency(fe, &if_frequency);
84 		if (ret)
85 			goto error;
86 		dev_dbg(&client->dev, "if_frequency=%u\n", if_frequency);
87 	} else {
88 		ret = -EINVAL;
89 		goto error;
90 	}
91 
92 	utmp = DIV_ROUND_CLOSEST_ULL((u64)if_frequency * 0x1000000, CXD2820R_CLK);
93 	buf[0] = (utmp >> 16) & 0xff;
94 	buf[1] = (utmp >>  8) & 0xff;
95 	buf[2] = (utmp >>  0) & 0xff;
96 	ret = regmap_bulk_write(priv->regmap[0], 0x00b6, buf, 3);
97 	if (ret)
98 		goto error;
99 
100 	ret = regmap_bulk_write(priv->regmap[0], 0x009f, bw_params1[bw_i], 5);
101 	if (ret)
102 		goto error;
103 
104 	ret = regmap_update_bits(priv->regmap[0], 0x00d7, 0xc0, bw_param << 6);
105 	if (ret)
106 		goto error;
107 
108 	ret = regmap_bulk_write(priv->regmap[0], 0x00d9, bw_params2[bw_i], 2);
109 	if (ret)
110 		goto error;
111 
112 	ret = regmap_write(priv->regmap[0], 0x00ff, 0x08);
113 	if (ret)
114 		goto error;
115 
116 	ret = regmap_write(priv->regmap[0], 0x00fe, 0x01);
117 	if (ret)
118 		goto error;
119 
120 	return ret;
121 error:
122 	dev_dbg(&client->dev, "failed=%d\n", ret);
123 	return ret;
124 }
125 
126 int cxd2820r_get_frontend_t(struct dvb_frontend *fe,
127 			    struct dtv_frontend_properties *c)
128 {
129 	struct cxd2820r_priv *priv = fe->demodulator_priv;
130 	struct i2c_client *client = priv->client[0];
131 	int ret;
132 	unsigned int utmp;
133 	u8 buf[2];
134 
135 	dev_dbg(&client->dev, "\n");
136 
137 	ret = regmap_bulk_read(priv->regmap[0], 0x002f, buf, sizeof(buf));
138 	if (ret)
139 		goto error;
140 
141 	switch ((buf[0] >> 6) & 0x03) {
142 	case 0:
143 		c->modulation = QPSK;
144 		break;
145 	case 1:
146 		c->modulation = QAM_16;
147 		break;
148 	case 2:
149 		c->modulation = QAM_64;
150 		break;
151 	}
152 
153 	switch ((buf[1] >> 1) & 0x03) {
154 	case 0:
155 		c->transmission_mode = TRANSMISSION_MODE_2K;
156 		break;
157 	case 1:
158 		c->transmission_mode = TRANSMISSION_MODE_8K;
159 		break;
160 	}
161 
162 	switch ((buf[1] >> 3) & 0x03) {
163 	case 0:
164 		c->guard_interval = GUARD_INTERVAL_1_32;
165 		break;
166 	case 1:
167 		c->guard_interval = GUARD_INTERVAL_1_16;
168 		break;
169 	case 2:
170 		c->guard_interval = GUARD_INTERVAL_1_8;
171 		break;
172 	case 3:
173 		c->guard_interval = GUARD_INTERVAL_1_4;
174 		break;
175 	}
176 
177 	switch ((buf[0] >> 3) & 0x07) {
178 	case 0:
179 		c->hierarchy = HIERARCHY_NONE;
180 		break;
181 	case 1:
182 		c->hierarchy = HIERARCHY_1;
183 		break;
184 	case 2:
185 		c->hierarchy = HIERARCHY_2;
186 		break;
187 	case 3:
188 		c->hierarchy = HIERARCHY_4;
189 		break;
190 	}
191 
192 	switch ((buf[0] >> 0) & 0x07) {
193 	case 0:
194 		c->code_rate_HP = FEC_1_2;
195 		break;
196 	case 1:
197 		c->code_rate_HP = FEC_2_3;
198 		break;
199 	case 2:
200 		c->code_rate_HP = FEC_3_4;
201 		break;
202 	case 3:
203 		c->code_rate_HP = FEC_5_6;
204 		break;
205 	case 4:
206 		c->code_rate_HP = FEC_7_8;
207 		break;
208 	}
209 
210 	switch ((buf[1] >> 5) & 0x07) {
211 	case 0:
212 		c->code_rate_LP = FEC_1_2;
213 		break;
214 	case 1:
215 		c->code_rate_LP = FEC_2_3;
216 		break;
217 	case 2:
218 		c->code_rate_LP = FEC_3_4;
219 		break;
220 	case 3:
221 		c->code_rate_LP = FEC_5_6;
222 		break;
223 	case 4:
224 		c->code_rate_LP = FEC_7_8;
225 		break;
226 	}
227 
228 	ret = regmap_read(priv->regmap[0], 0x07c6, &utmp);
229 	if (ret)
230 		goto error;
231 
232 	switch ((utmp >> 0) & 0x01) {
233 	case 0:
234 		c->inversion = INVERSION_OFF;
235 		break;
236 	case 1:
237 		c->inversion = INVERSION_ON;
238 		break;
239 	}
240 
241 	return ret;
242 error:
243 	dev_dbg(&client->dev, "failed=%d\n", ret);
244 	return ret;
245 }
246 
247 int cxd2820r_read_status_t(struct dvb_frontend *fe, enum fe_status *status)
248 {
249 	struct cxd2820r_priv *priv = fe->demodulator_priv;
250 	struct i2c_client *client = priv->client[0];
251 	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
252 	int ret;
253 	unsigned int utmp, utmp1, utmp2;
254 	u8 buf[3];
255 
256 	/* Lock detection */
257 	ret = regmap_bulk_read(priv->regmap[0], 0x0010, &buf[0], 1);
258 	if (ret)
259 		goto error;
260 	ret = regmap_bulk_read(priv->regmap[0], 0x0073, &buf[1], 1);
261 	if (ret)
262 		goto error;
263 
264 	utmp1 = (buf[0] >> 0) & 0x07;
265 	utmp2 = (buf[1] >> 3) & 0x01;
266 
267 	if (utmp1 == 6 && utmp2 == 1) {
268 		*status = FE_HAS_SIGNAL | FE_HAS_CARRIER |
269 			  FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
270 	} else if (utmp1 == 6 || utmp2 == 1) {
271 		*status = FE_HAS_SIGNAL | FE_HAS_CARRIER |
272 			  FE_HAS_VITERBI | FE_HAS_SYNC;
273 	} else {
274 		*status = 0;
275 	}
276 
277 	dev_dbg(&client->dev, "status=%02x raw=%*ph sync=%u ts=%u\n",
278 		*status, 2, buf, utmp1, utmp2);
279 
280 	/* Signal strength */
281 	if (*status & FE_HAS_SIGNAL) {
282 		unsigned int strength;
283 
284 		ret = regmap_bulk_read(priv->regmap[0], 0x0026, buf, 2);
285 		if (ret)
286 			goto error;
287 
288 		utmp = buf[0] << 8 | buf[1] << 0;
289 		utmp = ~utmp & 0x0fff;
290 		/* Scale value to 0x0000-0xffff */
291 		strength = utmp << 4 | utmp >> 8;
292 
293 		c->strength.len = 1;
294 		c->strength.stat[0].scale = FE_SCALE_RELATIVE;
295 		c->strength.stat[0].uvalue = strength;
296 	} else {
297 		c->strength.len = 1;
298 		c->strength.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
299 	}
300 
301 	/* CNR */
302 	if (*status & FE_HAS_VITERBI) {
303 		unsigned int cnr;
304 
305 		ret = regmap_bulk_read(priv->regmap[0], 0x002c, buf, 2);
306 		if (ret)
307 			goto error;
308 
309 		utmp = buf[0] << 8 | buf[1] << 0;
310 		if (utmp)
311 			cnr = div_u64((u64)(intlog10(utmp)
312 				      - intlog10(32000 - utmp) + 55532585)
313 				      * 10000, (1 << 24));
314 		else
315 			cnr = 0;
316 
317 		c->cnr.len = 1;
318 		c->cnr.stat[0].scale = FE_SCALE_DECIBEL;
319 		c->cnr.stat[0].svalue = cnr;
320 	} else {
321 		c->cnr.len = 1;
322 		c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
323 	}
324 
325 	/* BER */
326 	if (*status & FE_HAS_SYNC) {
327 		unsigned int post_bit_error;
328 		bool start_ber;
329 
330 		if (priv->ber_running) {
331 			ret = regmap_bulk_read(priv->regmap[0], 0x0076, buf, 3);
332 			if (ret)
333 				goto error;
334 
335 			if ((buf[2] >> 7) & 0x01) {
336 				post_bit_error = buf[2] << 16 | buf[1] << 8 |
337 						 buf[0] << 0;
338 				post_bit_error &= 0x0fffff;
339 				start_ber = true;
340 			} else {
341 				post_bit_error = 0;
342 				start_ber = false;
343 			}
344 		} else {
345 			post_bit_error = 0;
346 			start_ber = true;
347 		}
348 
349 		if (start_ber) {
350 			ret = regmap_write(priv->regmap[0], 0x0079, 0x01);
351 			if (ret)
352 				goto error;
353 			priv->ber_running = true;
354 		}
355 
356 		priv->post_bit_error += post_bit_error;
357 
358 		c->post_bit_error.len = 1;
359 		c->post_bit_error.stat[0].scale = FE_SCALE_COUNTER;
360 		c->post_bit_error.stat[0].uvalue = priv->post_bit_error;
361 	} else {
362 		c->post_bit_error.len = 1;
363 		c->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
364 	}
365 
366 	return ret;
367 error:
368 	dev_dbg(&client->dev, "failed=%d\n", ret);
369 	return ret;
370 }
371 
372 int cxd2820r_init_t(struct dvb_frontend *fe)
373 {
374 	struct cxd2820r_priv *priv = fe->demodulator_priv;
375 	struct i2c_client *client = priv->client[0];
376 	int ret;
377 
378 	dev_dbg(&client->dev, "\n");
379 
380 	ret = regmap_write(priv->regmap[0], 0x0085, 0x07);
381 	if (ret)
382 		goto error;
383 
384 	return ret;
385 error:
386 	dev_dbg(&client->dev, "failed=%d\n", ret);
387 	return ret;
388 }
389 
390 int cxd2820r_sleep_t(struct dvb_frontend *fe)
391 {
392 	struct cxd2820r_priv *priv = fe->demodulator_priv;
393 	struct i2c_client *client = priv->client[0];
394 	int ret;
395 	static struct reg_val_mask tab[] = {
396 		{ 0x000ff, 0x1f, 0xff },
397 		{ 0x00085, 0x00, 0xff },
398 		{ 0x00088, 0x01, 0xff },
399 		{ 0x00081, 0x00, 0xff },
400 		{ 0x00080, 0x00, 0xff },
401 	};
402 
403 	dev_dbg(&client->dev, "\n");
404 
405 	priv->delivery_system = SYS_UNDEFINED;
406 
407 	ret = cxd2820r_wr_reg_val_mask_tab(priv, tab, ARRAY_SIZE(tab));
408 	if (ret)
409 		goto error;
410 
411 	return ret;
412 error:
413 	dev_dbg(&client->dev, "failed=%d\n", ret);
414 	return ret;
415 }
416 
417 int cxd2820r_get_tune_settings_t(struct dvb_frontend *fe,
418 	struct dvb_frontend_tune_settings *s)
419 {
420 	s->min_delay_ms = 500;
421 	s->step_size = fe->ops.info.frequency_stepsize_hz * 2;
422 	s->max_drift = (fe->ops.info.frequency_stepsize_hz * 2) + 1;
423 
424 	return 0;
425 }
426