]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blame - drivers/media/dvb-frontends/mn88473.c
[media] mn88473: convert driver to I2C binding
[mirror_ubuntu-artful-kernel.git] / drivers / media / dvb-frontends / mn88473.c
CommitLineData
dadb5bb4
AP
1/*
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
01b4be14 43 ret = i2c_transfer(dev->client[0]->adapter, msg, 1);
dadb5bb4
AP
44 if (ret == 1) {
45 ret = 0;
46 } else {
01b4be14
AP
47 dev_warn(&dev->client[0]->dev,
48 "i2c wr failed=%d reg=%02x len=%d\n",
49 ret, reg, len);
dadb5bb4
AP
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
01b4be14 82 ret = i2c_transfer(dev->client[0]->adapter, msg, 2);
dadb5bb4
AP
83 if (ret == 2) {
84 memcpy(val, buf, len);
85 ret = 0;
86 } else {
01b4be14
AP
87 dev_warn(&dev->client[0]->dev,
88 "i2c rd failed=%d reg=%02x len=%d\n",
89 ret, reg, len);
dadb5bb4
AP
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{
01b4be14
AP
117 struct i2c_client *client = fe->demodulator_priv;
118 struct mn88473_dev *dev = i2c_get_clientdata(client);
dadb5bb4 119 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
c00a6b9f 120 int ret, i;
df810e8a
AP
121 u32 if_frequency;
122 u8 delivery_system_val, if_val[3], bw_val[7];
dadb5bb4 123
01b4be14
AP
124 dev_dbg(&client->dev,
125 "delivery_system=%u modulation=%u frequency=%u bandwidth_hz=%u symbol_rate=%u inversion=%d stream_id=%d\n",
126 c->delivery_system, c->modulation,
c00a6b9f
AP
127 c->frequency, c->bandwidth_hz, c->symbol_rate,
128 c->inversion, c->stream_id);
dadb5bb4
AP
129
130 if (!dev->warm) {
131 ret = -EAGAIN;
132 goto err;
133 }
134
c00a6b9f 135 switch (c->delivery_system) {
6ebbe22d 136 case SYS_DVBT:
df810e8a 137 delivery_system_val = 0x02;
6ebbe22d 138 break;
c00a6b9f 139 case SYS_DVBT2:
df810e8a 140 delivery_system_val = 0x03;
c00a6b9f
AP
141 break;
142 case SYS_DVBC_ANNEX_A:
df810e8a
AP
143 delivery_system_val = 0x04;
144 break;
145 default:
146 ret = -EINVAL;
147 goto err;
148 }
149
150 switch (c->delivery_system) {
151 case SYS_DVBT:
152 case SYS_DVBT2:
153 if (c->bandwidth_hz <= 6000000) {
154 /* IF 3570000 Hz, BW 6000000 Hz */
155 memcpy(if_val, "\x24\x8e\x8a", 3);
156 memcpy(bw_val, "\xe9\x55\x55\x1c\x29\x1c\x29", 7);
157 } else if (c->bandwidth_hz <= 7000000) {
158 /* IF 4570000 Hz, BW 7000000 Hz */
159 memcpy(if_val, "\x2e\xcb\xfb", 3);
160 memcpy(bw_val, "\xc8\x00\x00\x17\x0a\x17\x0a", 7);
161 } else if (c->bandwidth_hz <= 8000000) {
162 /* IF 4570000 Hz, BW 8000000 Hz */
163 memcpy(if_val, "\x2e\xcb\xfb", 3);
164 memcpy(bw_val, "\xaf\x00\x00\x11\xec\x11\xec", 7);
165 } else {
166 ret = -EINVAL;
167 goto err;
168 }
169 break;
170 case SYS_DVBC_ANNEX_A:
171 /* IF 5070000 Hz, BW 8000000 Hz */
172 memcpy(if_val, "\x33\xea\xb3", 3);
173 memcpy(bw_val, "\xaf\x00\x00\x11\xec\x11\xec", 7);
c00a6b9f
AP
174 break;
175 default:
176 ret = -EINVAL;
177 goto err;
178 }
179
dadb5bb4
AP
180 /* program tuner */
181 if (fe->ops.tuner_ops.set_params) {
182 ret = fe->ops.tuner_ops.set_params(fe);
183 if (ret)
184 goto err;
185 }
186
187 if (fe->ops.tuner_ops.get_if_frequency) {
188 ret = fe->ops.tuner_ops.get_if_frequency(fe, &if_frequency);
189 if (ret)
190 goto err;
191
01b4be14 192 dev_dbg(&client->dev, "get_if_frequency=%d\n", if_frequency);
df810e8a
AP
193 } else {
194 if_frequency = 0;
dadb5bb4
AP
195 }
196
c00a6b9f 197 switch (if_frequency) {
df810e8a 198 case 3570000:
c00a6b9f
AP
199 case 4570000:
200 case 5070000:
201 break;
202 default:
01b4be14
AP
203 dev_err(&client->dev, "IF frequency %d not supported\n",
204 if_frequency);
dadb5bb4
AP
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);
df810e8a 216 ret = mn88473_wreg(dev, 0x1c03, delivery_system_val);
dadb5bb4 217 ret = mn88473_wregs(dev, 0x1c0b, "\x00", 1);
c00a6b9f 218
df810e8a
AP
219 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]);
c00a6b9f
AP
227 if (ret)
228 goto err;
229 }
230
dadb5bb4
AP
231 ret = mn88473_wregs(dev, 0x1c2d, "\x3b", 1);
232 ret = mn88473_wregs(dev, 0x1c2e, "\x00", 1);
233 ret = mn88473_wregs(dev, 0x1c56, "\x0d", 1);
6ebbe22d 234 ret = mn88473_wregs(dev, 0x1801, "\xba", 1);
dadb5bb4
AP
235 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);
6ebbe22d 239 ret = mn88473_wregs(dev, 0x1807, "\xe7", 1);
dadb5bb4
AP
240 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);
c00a6b9f
AP
264 ret = mn88473_wregs(dev, 0x1c32, "\x80", 1);
265 ret = mn88473_wregs(dev, 0x1c36, "\x00", 1);
dadb5bb4
AP
266 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:
01b4be14 274 dev_dbg(&client->dev, "failed=%d\n", ret);
dadb5bb4
AP
275 return ret;
276}
277
278static int mn88473_read_status(struct dvb_frontend *fe, fe_status_t *status)
279{
01b4be14
AP
280 struct i2c_client *client = fe->demodulator_priv;
281 struct mn88473_dev *dev = i2c_get_clientdata(client);
dadb5bb4
AP
282 int ret;
283
284 *status = 0;
285
286 if (!dev->warm) {
287 ret = -EAGAIN;
288 goto err;
289 }
290
291 *status = FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI |
292 FE_HAS_SYNC | FE_HAS_LOCK;
293
294 return 0;
295err:
01b4be14 296 dev_dbg(&client->dev, "failed=%d\n", ret);
dadb5bb4
AP
297 return ret;
298}
299
300static int mn88473_init(struct dvb_frontend *fe)
301{
01b4be14
AP
302 struct i2c_client *client = fe->demodulator_priv;
303 struct mn88473_dev *dev = i2c_get_clientdata(client);
dadb5bb4
AP
304 int ret, len, remaining;
305 const struct firmware *fw = NULL;
306 u8 *fw_file = MN88473_FIRMWARE;
307
01b4be14 308 dev_dbg(&client->dev, "\n");
dadb5bb4
AP
309
310 if (dev->warm)
311 return 0;
312
313 /* request the firmware, this will block and timeout */
01b4be14 314 ret = request_firmware(&fw, fw_file, &client->dev);
dadb5bb4 315 if (ret) {
01b4be14 316 dev_err(&client->dev, "firmare file '%s' not found\n", fw_file);
dadb5bb4
AP
317 goto err;
318 }
319
01b4be14
AP
320 dev_info(&client->dev, "downloading firmware from file '%s'\n",
321 fw_file);
dadb5bb4
AP
322
323 ret = mn88473_wreg(dev, 0x18f5, 0x03);
324 if (ret)
325 goto err;
326
327 for (remaining = fw->size; remaining > 0;
01b4be14 328 remaining -= (dev->i2c_wr_max - 1)) {
dadb5bb4 329 len = remaining;
01b4be14
AP
330 if (len > (dev->i2c_wr_max - 1))
331 len = (dev->i2c_wr_max - 1);
dadb5bb4
AP
332
333 ret = mn88473_wregs(dev, 0x18f6,
334 &fw->data[fw->size - remaining], len);
335 if (ret) {
01b4be14
AP
336 dev_err(&client->dev, "firmware download failed=%d\n",
337 ret);
dadb5bb4
AP
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
01b4be14 357 dev_dbg(&client->dev, "failed=%d\n", ret);
dadb5bb4
AP
358 return ret;
359}
360
361static int mn88473_sleep(struct dvb_frontend *fe)
362{
01b4be14
AP
363 struct i2c_client *client = fe->demodulator_priv;
364 struct mn88473_dev *dev = i2c_get_clientdata(client);
dadb5bb4
AP
365 int ret;
366
01b4be14 367 dev_dbg(&client->dev, "\n");
dadb5bb4
AP
368
369 ret = mn88473_wreg(dev, 0x1c05, 0x3e);
370 if (ret)
371 goto err;
372
373 dev->delivery_system = SYS_UNDEFINED;
374
375 return 0;
376err:
01b4be14 377 dev_dbg(&client->dev, "failed=%d\n", ret);
dadb5bb4
AP
378 return ret;
379}
380
01b4be14
AP
381static struct dvb_frontend_ops mn88473_ops = {
382 .delsys = {SYS_DVBT, SYS_DVBT2, SYS_DVBC_ANNEX_AC},
383 .info = {
384 .name = "Panasonic MN88473",
385 .caps = FE_CAN_FEC_1_2 |
386 FE_CAN_FEC_2_3 |
387 FE_CAN_FEC_3_4 |
388 FE_CAN_FEC_5_6 |
389 FE_CAN_FEC_7_8 |
390 FE_CAN_FEC_AUTO |
391 FE_CAN_QPSK |
392 FE_CAN_QAM_16 |
393 FE_CAN_QAM_32 |
394 FE_CAN_QAM_64 |
395 FE_CAN_QAM_128 |
396 FE_CAN_QAM_256 |
397 FE_CAN_QAM_AUTO |
398 FE_CAN_TRANSMISSION_MODE_AUTO |
399 FE_CAN_GUARD_INTERVAL_AUTO |
400 FE_CAN_HIERARCHY_AUTO |
401 FE_CAN_MUTE_TS |
402 FE_CAN_2G_MODULATION |
403 FE_CAN_MULTISTREAM
404 },
405
406 .get_tune_settings = mn88473_get_tune_settings,
407
408 .init = mn88473_init,
409 .sleep = mn88473_sleep,
dadb5bb4 410
01b4be14
AP
411 .set_frontend = mn88473_set_frontend,
412
413 .read_status = mn88473_read_status,
414};
415
416static int mn88473_probe(struct i2c_client *client,
417 const struct i2c_device_id *id)
dadb5bb4 418{
01b4be14 419 struct mn88473_config *config = client->dev.platform_data;
dadb5bb4 420 struct mn88473_dev *dev;
01b4be14 421 int ret;
dadb5bb4
AP
422 u8 u8tmp;
423
01b4be14 424 dev_dbg(&client->dev, "\n");
dadb5bb4 425
01b4be14
AP
426 /* Caller really need to provide pointer for frontend we create. */
427 if (config->fe == NULL) {
428 dev_err(&client->dev, "frontend pointer not defined\n");
429 ret = -EINVAL;
430 goto err;
431 }
432
433 dev = kzalloc(sizeof(*dev), GFP_KERNEL);
434 if (dev == NULL) {
dadb5bb4 435 ret = -ENOMEM;
dadb5bb4
AP
436 goto err;
437 }
438
01b4be14
AP
439 dev->client[0] = client;
440 dev->i2c_wr_max = config->i2c_wr_max;
dadb5bb4 441
01b4be14 442 /* check demod answers to I2C */
dadb5bb4
AP
443 ret = mn88473_rreg(dev, 0x1c00, &u8tmp);
444 if (ret)
01b4be14
AP
445 goto err_kfree;
446
447 /*
448 * Chip has three I2C addresses for different register pages. Used
449 * addresses are 0x18, 0x1a and 0x1c. We register two dummy clients,
450 * 0x1a and 0x1c, in order to get own I2C client for each register page.
451 */
452 dev->client[1] = i2c_new_dummy(client->adapter, 0x1a);
453 if (dev->client[1] == NULL) {
454 ret = -ENODEV;
455 dev_err(&client->dev, "I2C registration failed\n");
456 if (ret)
457 goto err_kfree;
458 }
459 i2c_set_clientdata(dev->client[1], dev);
460
461 dev->client[2] = i2c_new_dummy(client->adapter, 0x1c);
462 if (dev->client[2] == NULL) {
463 ret = -ENODEV;
464 dev_err(&client->dev, "2nd I2C registration failed\n");
465 if (ret)
466 goto err_client_1_i2c_unregister_device;
467 }
468 i2c_set_clientdata(dev->client[2], dev);
dadb5bb4
AP
469
470 /* create dvb_frontend */
471 memcpy(&dev->fe.ops, &mn88473_ops, sizeof(struct dvb_frontend_ops));
01b4be14
AP
472 dev->fe.demodulator_priv = client;
473 *config->fe = &dev->fe;
474 i2c_set_clientdata(client, dev);
dadb5bb4 475
01b4be14
AP
476 dev_info(&dev->client[0]->dev, "Panasonic MN88473 successfully attached\n");
477 return 0;
478
479err_client_1_i2c_unregister_device:
480 i2c_unregister_device(dev->client[1]);
481err_kfree:
dadb5bb4 482 kfree(dev);
01b4be14
AP
483err:
484 dev_dbg(&client->dev, "failed=%d\n", ret);
485 return ret;
dadb5bb4 486}
dadb5bb4 487
01b4be14
AP
488static int mn88473_remove(struct i2c_client *client)
489{
490 struct mn88473_dev *dev = i2c_get_clientdata(client);
dadb5bb4 491
01b4be14 492 dev_dbg(&client->dev, "\n");
dadb5bb4 493
01b4be14
AP
494 i2c_unregister_device(dev->client[2]);
495 i2c_unregister_device(dev->client[1]);
dadb5bb4 496
01b4be14 497 kfree(dev);
dadb5bb4 498
01b4be14
AP
499 return 0;
500}
dadb5bb4 501
01b4be14
AP
502static const struct i2c_device_id mn88473_id_table[] = {
503 {"mn88473", 0},
504 {}
505};
506MODULE_DEVICE_TABLE(i2c, mn88473_id_table);
507
508static struct i2c_driver mn88473_driver = {
509 .driver = {
510 .owner = THIS_MODULE,
511 .name = "mn88473",
512 },
513 .probe = mn88473_probe,
514 .remove = mn88473_remove,
515 .id_table = mn88473_id_table,
dadb5bb4
AP
516};
517
01b4be14
AP
518module_i2c_driver(mn88473_driver);
519
dadb5bb4
AP
520MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
521MODULE_DESCRIPTION("Panasonic MN88473 DVB-T/T2/C demodulator driver");
522MODULE_LICENSE("GPL");
523MODULE_FIRMWARE(MN88473_FIRMWARE);