blob: 2c81a83d3d5db1d2b577974db4c92c9b388e4711 [file] [log] [blame]
Antti Palosaaridadb5bb2014-09-30 01:01:47 -03001/*
2 * Panasonic MN88473 DVB-T/T2/C demodulator driver
3 *
4 * Copyright (C) 2014 Antti Palosaari <crope@iki.fi>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 */
16
17#include "mn88473_priv.h"
18
19static struct dvb_frontend_ops mn88473_ops;
20
21/* write multiple registers */
22static int mn88473_wregs(struct mn88473_dev *dev, u16 reg, const u8 *val, int len)
23{
24#define MAX_WR_LEN 21
25#define MAX_WR_XFER_LEN (MAX_WR_LEN + 1)
26 int ret;
27 u8 buf[MAX_WR_XFER_LEN];
28 struct i2c_msg msg[1] = {
29 {
30 .addr = (reg >> 8) & 0xff,
31 .flags = 0,
32 .len = 1 + len,
33 .buf = buf,
34 }
35 };
36
37 if (WARN_ON(len > MAX_WR_LEN))
38 return -EINVAL;
39
40 buf[0] = (reg >> 0) & 0xff;
41 memcpy(&buf[1], val, len);
42
43 ret = i2c_transfer(dev->i2c, msg, 1);
44 if (ret == 1) {
45 ret = 0;
46 } else {
47 dev_warn(&dev->i2c->dev,
48 "%s: i2c wr failed=%d reg=%02x len=%d\n",
49 KBUILD_MODNAME, ret, reg, len);
50 ret = -EREMOTEIO;
51 }
52
53 return ret;
54}
55
56/* read multiple registers */
57static int mn88473_rregs(struct mn88473_dev *dev, u16 reg, u8 *val, int len)
58{
59#define MAX_RD_LEN 2
60#define MAX_RD_XFER_LEN (MAX_RD_LEN)
61 int ret;
62 u8 buf[MAX_RD_XFER_LEN];
63 struct i2c_msg msg[2] = {
64 {
65 .addr = (reg >> 8) & 0xff,
66 .flags = 0,
67 .len = 1,
68 .buf = buf,
69 }, {
70 .addr = (reg >> 8) & 0xff,
71 .flags = I2C_M_RD,
72 .len = len,
73 .buf = buf,
74 }
75 };
76
77 if (WARN_ON(len > MAX_RD_LEN))
78 return -EINVAL;
79
80 buf[0] = (reg >> 0) & 0xff;
81
82 ret = i2c_transfer(dev->i2c, msg, 2);
83 if (ret == 2) {
84 memcpy(val, buf, len);
85 ret = 0;
86 } else {
87 dev_warn(&dev->i2c->dev,
88 "%s: i2c rd failed=%d reg=%02x len=%d\n",
89 KBUILD_MODNAME, ret, reg, len);
90 ret = -EREMOTEIO;
91 }
92
93 return ret;
94}
95
96/* write single register */
97static int mn88473_wreg(struct mn88473_dev *dev, u16 reg, u8 val)
98{
99 return mn88473_wregs(dev, reg, &val, 1);
100}
101
102/* read single register */
103static int mn88473_rreg(struct mn88473_dev *dev, u16 reg, u8 *val)
104{
105 return mn88473_rregs(dev, reg, val, 1);
106}
107
108static int mn88473_get_tune_settings(struct dvb_frontend *fe,
109 struct dvb_frontend_tune_settings *s)
110{
111 s->min_delay_ms = 1000;
112 return 0;
113}
114
115static int mn88473_set_frontend(struct dvb_frontend *fe)
116{
117 struct mn88473_dev *dev = fe->demodulator_priv;
118 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
Antti Palosaaric00a6b92014-09-30 17:52:03 -0300119 int ret, i;
Antti Palosaaridf810e82014-09-30 23:19:30 -0300120 u32 if_frequency;
121 u8 delivery_system_val, if_val[3], bw_val[7];
Antti Palosaaridadb5bb2014-09-30 01:01:47 -0300122
123 dev_dbg(&dev->i2c->dev,
Antti Palosaaric00a6b92014-09-30 17:52:03 -0300124 "%s: delivery_system=%u modulation=%u frequency=%u bandwidth_hz=%u symbol_rate=%u inversion=%d stream_id=%d\n",
Antti Palosaaridadb5bb2014-09-30 01:01:47 -0300125 __func__, c->delivery_system, c->modulation,
Antti Palosaaric00a6b92014-09-30 17:52:03 -0300126 c->frequency, c->bandwidth_hz, c->symbol_rate,
127 c->inversion, c->stream_id);
Antti Palosaaridadb5bb2014-09-30 01:01:47 -0300128
129 if (!dev->warm) {
130 ret = -EAGAIN;
131 goto err;
132 }
133
Antti Palosaaric00a6b92014-09-30 17:52:03 -0300134 switch (c->delivery_system) {
Antti Palosaari6ebbe222014-09-30 19:56:22 -0300135 case SYS_DVBT:
Antti Palosaaridf810e82014-09-30 23:19:30 -0300136 delivery_system_val = 0x02;
Antti Palosaari6ebbe222014-09-30 19:56:22 -0300137 break;
Antti Palosaaric00a6b92014-09-30 17:52:03 -0300138 case SYS_DVBT2:
Antti Palosaaridf810e82014-09-30 23:19:30 -0300139 delivery_system_val = 0x03;
Antti Palosaaric00a6b92014-09-30 17:52:03 -0300140 break;
141 case SYS_DVBC_ANNEX_A:
Antti Palosaaridf810e82014-09-30 23:19:30 -0300142 delivery_system_val = 0x04;
143 break;
144 default:
145 ret = -EINVAL;
146 goto err;
147 }
148
149 switch (c->delivery_system) {
150 case SYS_DVBT:
151 case SYS_DVBT2:
152 if (c->bandwidth_hz <= 6000000) {
153 /* IF 3570000 Hz, BW 6000000 Hz */
154 memcpy(if_val, "\x24\x8e\x8a", 3);
155 memcpy(bw_val, "\xe9\x55\x55\x1c\x29\x1c\x29", 7);
156 } else if (c->bandwidth_hz <= 7000000) {
157 /* IF 4570000 Hz, BW 7000000 Hz */
158 memcpy(if_val, "\x2e\xcb\xfb", 3);
159 memcpy(bw_val, "\xc8\x00\x00\x17\x0a\x17\x0a", 7);
160 } else if (c->bandwidth_hz <= 8000000) {
161 /* IF 4570000 Hz, BW 8000000 Hz */
162 memcpy(if_val, "\x2e\xcb\xfb", 3);
163 memcpy(bw_val, "\xaf\x00\x00\x11\xec\x11\xec", 7);
164 } else {
165 ret = -EINVAL;
166 goto err;
167 }
168 break;
169 case SYS_DVBC_ANNEX_A:
170 /* IF 5070000 Hz, BW 8000000 Hz */
171 memcpy(if_val, "\x33\xea\xb3", 3);
172 memcpy(bw_val, "\xaf\x00\x00\x11\xec\x11\xec", 7);
Antti Palosaaric00a6b92014-09-30 17:52:03 -0300173 break;
174 default:
175 ret = -EINVAL;
176 goto err;
177 }
178
Antti Palosaaridadb5bb2014-09-30 01:01:47 -0300179 /* program tuner */
180 if (fe->ops.tuner_ops.set_params) {
181 ret = fe->ops.tuner_ops.set_params(fe);
182 if (ret)
183 goto err;
184 }
185
186 if (fe->ops.tuner_ops.get_if_frequency) {
187 ret = fe->ops.tuner_ops.get_if_frequency(fe, &if_frequency);
188 if (ret)
189 goto err;
190
191 dev_dbg(&dev->i2c->dev, "%s: get_if_frequency=%d\n",
192 __func__, if_frequency);
Antti Palosaaridf810e82014-09-30 23:19:30 -0300193 } else {
194 if_frequency = 0;
Antti Palosaaridadb5bb2014-09-30 01:01:47 -0300195 }
196
Antti Palosaaric00a6b92014-09-30 17:52:03 -0300197 switch (if_frequency) {
Antti Palosaaridf810e82014-09-30 23:19:30 -0300198 case 3570000:
Antti Palosaaric00a6b92014-09-30 17:52:03 -0300199 case 4570000:
200 case 5070000:
201 break;
202 default:
Antti Palosaaridadb5bb2014-09-30 01:01:47 -0300203 dev_err(&dev->i2c->dev, "%s: IF frequency %d not supported\n",
204 KBUILD_MODNAME, if_frequency);
205 ret = -EINVAL;
206 goto err;
207 }
208
209 ret = mn88473_wregs(dev, 0x1c05, "\x00", 1);
210 ret = mn88473_wregs(dev, 0x1cfb, "\x13", 1);
211 ret = mn88473_wregs(dev, 0x1cef, "\x13", 1);
212 ret = mn88473_wregs(dev, 0x1cf9, "\x13", 1);
213 ret = mn88473_wregs(dev, 0x1c00, "\x18", 1);
214 ret = mn88473_wregs(dev, 0x1c01, "\x01", 1);
215 ret = mn88473_wregs(dev, 0x1c02, "\x21", 1);
Antti Palosaaridf810e82014-09-30 23:19:30 -0300216 ret = mn88473_wreg(dev, 0x1c03, delivery_system_val);
Antti Palosaaridadb5bb2014-09-30 01:01:47 -0300217 ret = mn88473_wregs(dev, 0x1c0b, "\x00", 1);
Antti Palosaaric00a6b92014-09-30 17:52:03 -0300218
Antti Palosaaridf810e82014-09-30 23:19:30 -0300219 for (i = 0; i < sizeof(if_val); i++) {
220 ret = mn88473_wreg(dev, 0x1c10 + i, if_val[i]);
221 if (ret)
222 goto err;
223 }
224
225 for (i = 0; i < sizeof(bw_val); i++) {
226 ret = mn88473_wreg(dev, 0x1c13 + i, bw_val[i]);
Antti Palosaaric00a6b92014-09-30 17:52:03 -0300227 if (ret)
228 goto err;
229 }
230
Antti Palosaaridadb5bb2014-09-30 01:01:47 -0300231 ret = mn88473_wregs(dev, 0x1c2d, "\x3b", 1);
232 ret = mn88473_wregs(dev, 0x1c2e, "\x00", 1);
233 ret = mn88473_wregs(dev, 0x1c56, "\x0d", 1);
Antti Palosaari6ebbe222014-09-30 19:56:22 -0300234 ret = mn88473_wregs(dev, 0x1801, "\xba", 1);
Antti Palosaaridadb5bb2014-09-30 01:01:47 -0300235 ret = mn88473_wregs(dev, 0x1802, "\x13", 1);
236 ret = mn88473_wregs(dev, 0x1803, "\x80", 1);
237 ret = mn88473_wregs(dev, 0x1804, "\xba", 1);
238 ret = mn88473_wregs(dev, 0x1805, "\x91", 1);
Antti Palosaari6ebbe222014-09-30 19:56:22 -0300239 ret = mn88473_wregs(dev, 0x1807, "\xe7", 1);
Antti Palosaaridadb5bb2014-09-30 01:01:47 -0300240 ret = mn88473_wregs(dev, 0x1808, "\x28", 1);
241 ret = mn88473_wregs(dev, 0x180a, "\x1a", 1);
242 ret = mn88473_wregs(dev, 0x1813, "\x1f", 1);
243 ret = mn88473_wregs(dev, 0x1819, "\x03", 1);
244 ret = mn88473_wregs(dev, 0x181d, "\xb0", 1);
245 ret = mn88473_wregs(dev, 0x182a, "\x72", 1);
246 ret = mn88473_wregs(dev, 0x182d, "\x00", 1);
247 ret = mn88473_wregs(dev, 0x183c, "\x00", 1);
248 ret = mn88473_wregs(dev, 0x183f, "\xf8", 1);
249 ret = mn88473_wregs(dev, 0x1840, "\xf4", 1);
250 ret = mn88473_wregs(dev, 0x1841, "\x08", 1);
251 ret = mn88473_wregs(dev, 0x18d2, "\x29", 1);
252 ret = mn88473_wregs(dev, 0x18d4, "\x55", 1);
253 ret = mn88473_wregs(dev, 0x1a10, "\x10", 1);
254 ret = mn88473_wregs(dev, 0x1a11, "\xab", 1);
255 ret = mn88473_wregs(dev, 0x1a12, "\x0d", 1);
256 ret = mn88473_wregs(dev, 0x1a13, "\xae", 1);
257 ret = mn88473_wregs(dev, 0x1a14, "\x1d", 1);
258 ret = mn88473_wregs(dev, 0x1a15, "\x9d", 1);
259 ret = mn88473_wregs(dev, 0x1abe, "\x08", 1);
260 ret = mn88473_wregs(dev, 0x1c09, "\x08", 1);
261 ret = mn88473_wregs(dev, 0x1c08, "\x1d", 1);
262 ret = mn88473_wregs(dev, 0x18b2, "\x37", 1);
263 ret = mn88473_wregs(dev, 0x18d7, "\x04", 1);
Antti Palosaaric00a6b92014-09-30 17:52:03 -0300264 ret = mn88473_wregs(dev, 0x1c32, "\x80", 1);
265 ret = mn88473_wregs(dev, 0x1c36, "\x00", 1);
Antti Palosaaridadb5bb2014-09-30 01:01:47 -0300266 ret = mn88473_wregs(dev, 0x1cf8, "\x9f", 1);
267 if (ret)
268 goto err;
269
270 dev->delivery_system = c->delivery_system;
271
272 return 0;
273err:
274 dev_dbg(&dev->i2c->dev, "%s: failed=%d\n", __func__, ret);
275 return ret;
276}
277
278static int mn88473_read_status(struct dvb_frontend *fe, fe_status_t *status)
279{
280 struct mn88473_dev *dev = fe->demodulator_priv;
281 int ret;
282
283 *status = 0;
284
285 if (!dev->warm) {
286 ret = -EAGAIN;
287 goto err;
288 }
289
290 *status = FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI |
291 FE_HAS_SYNC | FE_HAS_LOCK;
292
293 return 0;
294err:
295 dev_dbg(&dev->i2c->dev, "%s: failed=%d\n", __func__, ret);
296 return ret;
297}
298
299static int mn88473_init(struct dvb_frontend *fe)
300{
301 struct mn88473_dev *dev = fe->demodulator_priv;
302 int ret, len, remaining;
303 const struct firmware *fw = NULL;
304 u8 *fw_file = MN88473_FIRMWARE;
305
306 dev_dbg(&dev->i2c->dev, "%s:\n", __func__);
307
308 if (dev->warm)
309 return 0;
310
311 /* request the firmware, this will block and timeout */
312 ret = request_firmware(&fw, fw_file, dev->i2c->dev.parent);
313 if (ret) {
314 dev_err(&dev->i2c->dev, "%s: firmare file '%s' not found\n",
315 KBUILD_MODNAME, fw_file);
316 goto err;
317 }
318
319 dev_info(&dev->i2c->dev, "%s: downloading firmware from file '%s'\n",
320 KBUILD_MODNAME, fw_file);
321
322 ret = mn88473_wreg(dev, 0x18f5, 0x03);
323 if (ret)
324 goto err;
325
326 for (remaining = fw->size; remaining > 0;
327 remaining -= (dev->cfg->i2c_wr_max - 1)) {
328 len = remaining;
329 if (len > (dev->cfg->i2c_wr_max - 1))
330 len = (dev->cfg->i2c_wr_max - 1);
331
332 ret = mn88473_wregs(dev, 0x18f6,
333 &fw->data[fw->size - remaining], len);
334 if (ret) {
335 dev_err(&dev->i2c->dev,
336 "%s: firmware download failed=%d\n",
337 KBUILD_MODNAME, ret);
338 goto err;
339 }
340 }
341
342 ret = mn88473_wreg(dev, 0x18f5, 0x00);
343 if (ret)
344 goto err;
345
346 release_firmware(fw);
347 fw = NULL;
348
349 /* warm state */
350 dev->warm = true;
351
352 return 0;
353err:
354 if (fw)
355 release_firmware(fw);
356
357 dev_dbg(&dev->i2c->dev, "%s: failed=%d\n", __func__, ret);
358 return ret;
359}
360
361static int mn88473_sleep(struct dvb_frontend *fe)
362{
363 struct mn88473_dev *dev = fe->demodulator_priv;
364 int ret;
365
366 dev_dbg(&dev->i2c->dev, "%s:\n", __func__);
367
368 ret = mn88473_wreg(dev, 0x1c05, 0x3e);
369 if (ret)
370 goto err;
371
372 dev->delivery_system = SYS_UNDEFINED;
373
374 return 0;
375err:
376 dev_dbg(&dev->i2c->dev, "%s: failed=%d\n", __func__, ret);
377 return ret;
378}
379
380static void mn88473_release(struct dvb_frontend *fe)
381{
382 struct mn88473_dev *dev = fe->demodulator_priv;
383 kfree(dev);
384}
385
386struct dvb_frontend *mn88473_attach(const struct mn88473_config *cfg,
387 struct i2c_adapter *i2c)
388{
389 int ret;
390 struct mn88473_dev *dev;
391 u8 u8tmp;
392
393 dev_dbg(&i2c->dev, "%s:\n", __func__);
394
395 /* allocate memory for the internal state */
396 dev = kzalloc(sizeof(struct mn88473_dev), GFP_KERNEL);
397 if (!dev) {
398 ret = -ENOMEM;
399 dev_err(&i2c->dev, "%s: kzalloc() failed\n", KBUILD_MODNAME);
400 goto err;
401 }
402
403 dev->cfg = cfg;
404 dev->i2c = i2c;
405
406 /* check demod responds to I2C */
407 ret = mn88473_rreg(dev, 0x1c00, &u8tmp);
408 if (ret)
409 goto err;
410
411 /* create dvb_frontend */
412 memcpy(&dev->fe.ops, &mn88473_ops, sizeof(struct dvb_frontend_ops));
413 dev->fe.demodulator_priv = dev;
414
415 return &dev->fe;
416err:
417 dev_dbg(&i2c->dev, "%s: failed=%d\n", __func__, ret);
418 kfree(dev);
419 return NULL;
420}
421EXPORT_SYMBOL(mn88473_attach);
422
423static struct dvb_frontend_ops mn88473_ops = {
Antti Palosaari6ebbe222014-09-30 19:56:22 -0300424 .delsys = {SYS_DVBT, SYS_DVBT2, SYS_DVBC_ANNEX_AC},
Antti Palosaaridadb5bb2014-09-30 01:01:47 -0300425 .info = {
426 .name = "Panasonic MN88473",
427 .caps = FE_CAN_FEC_1_2 |
428 FE_CAN_FEC_2_3 |
429 FE_CAN_FEC_3_4 |
430 FE_CAN_FEC_5_6 |
431 FE_CAN_FEC_7_8 |
432 FE_CAN_FEC_AUTO |
433 FE_CAN_QPSK |
434 FE_CAN_QAM_16 |
435 FE_CAN_QAM_32 |
436 FE_CAN_QAM_64 |
437 FE_CAN_QAM_128 |
438 FE_CAN_QAM_256 |
439 FE_CAN_QAM_AUTO |
440 FE_CAN_TRANSMISSION_MODE_AUTO |
441 FE_CAN_GUARD_INTERVAL_AUTO |
442 FE_CAN_HIERARCHY_AUTO |
443 FE_CAN_MUTE_TS |
444 FE_CAN_2G_MODULATION |
445 FE_CAN_MULTISTREAM
446 },
447
448 .release = mn88473_release,
449
450 .get_tune_settings = mn88473_get_tune_settings,
451
452 .init = mn88473_init,
453 .sleep = mn88473_sleep,
454
455 .set_frontend = mn88473_set_frontend,
456
457 .read_status = mn88473_read_status,
458};
459
460MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
461MODULE_DESCRIPTION("Panasonic MN88473 DVB-T/T2/C demodulator driver");
462MODULE_LICENSE("GPL");
463MODULE_FIRMWARE(MN88473_FIRMWARE);