]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/blame - drivers/media/dvb-frontends/dib9000.c
UBUNTU: Ubuntu-5.15.0-39.42
[mirror_ubuntu-jammy-kernel.git] / drivers / media / dvb-frontends / dib9000.c
CommitLineData
a10e763b 1// SPDX-License-Identifier: GPL-2.0-only
dd316c6b
OG
2/*
3 * Linux-DVB Driver for DiBcom's DiB9000 and demodulator-family.
4 *
5 * Copyright (C) 2005-10 DiBcom (http://www.dibcom.fr/)
dd316c6b 6 */
3dd72262
MCC
7
8#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
9
dd316c6b
OG
10#include <linux/kernel.h>
11#include <linux/i2c.h>
12#include <linux/mutex.h>
13
fada1935
MCC
14#include <media/dvb_math.h>
15#include <media/dvb_frontend.h>
dd316c6b
OG
16
17#include "dib9000.h"
18#include "dibx000_common.h"
19
20static int debug;
21module_param(debug, int, 0644);
22MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
23
3dd72262
MCC
24#define dprintk(fmt, arg...) do { \
25 if (debug) \
26 printk(KERN_DEBUG pr_fmt("%s: " fmt), \
27 __func__, ##arg); \
28} while (0)
29
dd316c6b
OG
30#define MAX_NUMBER_OF_FRONTENDS 6
31
32struct i2c_device {
33 struct i2c_adapter *i2c_adap;
34 u8 i2c_addr;
5a0deeed
OG
35 u8 *i2c_read_buffer;
36 u8 *i2c_write_buffer;
dd316c6b
OG
37};
38
79fcce32
PB
39struct dib9000_pid_ctrl {
40#define DIB9000_PID_FILTER_CTRL 0
41#define DIB9000_PID_FILTER 1
42 u8 cmd;
43 u8 id;
44 u16 pid;
45 u8 onoff;
46};
47
dd316c6b
OG
48struct dib9000_state {
49 struct i2c_device i2c;
50
51 struct dibx000_i2c_master i2c_master;
52 struct i2c_adapter tuner_adap;
53 struct i2c_adapter component_bus;
54
55 u16 revision;
56 u8 reg_offs;
57
58 enum frontend_tune_state tune_state;
59 u32 status;
60 struct dvb_frontend_parametersContext channel_status;
61
62 u8 fe_id;
63
64#define DIB9000_GPIO_DEFAULT_DIRECTIONS 0xffff
65 u16 gpio_dir;
66#define DIB9000_GPIO_DEFAULT_VALUES 0x0000
67 u16 gpio_val;
68#define DIB9000_GPIO_DEFAULT_PWM_POS 0xffff
69 u16 gpio_pwm_pos;
70
71 union { /* common for all chips */
72 struct {
73 u8 mobile_mode:1;
74 } host;
75
76 struct {
77 struct dib9000_fe_memory_map {
78 u16 addr;
79 u16 size;
80 } fe_mm[18];
81 u8 memcmd;
82
1eaef48b
AK
83 struct mutex mbx_if_lock; /* to protect read/write operations */
84 struct mutex mbx_lock; /* to protect the whole mailbox handling */
dd316c6b 85
1eaef48b
AK
86 struct mutex mem_lock; /* to protect the memory accesses */
87 struct mutex mem_mbx_lock; /* to protect the memory-based mailbox */
dd316c6b
OG
88
89#define MBX_MAX_WORDS (256 - 200 - 2)
90#define DIB9000_MSG_CACHE_SIZE 2
91 u16 message_cache[DIB9000_MSG_CACHE_SIZE][MBX_MAX_WORDS];
92 u8 fw_is_running;
93 } risc;
94 } platform;
95
96 union { /* common for all platforms */
97 struct {
98 struct dib9000_config cfg;
99 } d9;
100 } chip;
101
102 struct dvb_frontend *fe[MAX_NUMBER_OF_FRONTENDS];
103 u16 component_bus_speed;
5a0deeed
OG
104
105 /* for the I2C transfer */
106 struct i2c_msg msg[2];
107 u8 i2c_write_buffer[255];
108 u8 i2c_read_buffer[255];
1eaef48b 109 struct mutex demod_lock;
79fcce32
PB
110 u8 get_frontend_internal;
111 struct dib9000_pid_ctrl pid_ctrl[10];
112 s8 pid_ctrl_index; /* -1: empty list; -2: do not use the list */
dd316c6b
OG
113};
114
5a0deeed 115static const u32 fe_info[44] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
dd316c6b 116 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5a0deeed 117 0, 0, 0, 0, 0, 0, 0, 0
dd316c6b
OG
118};
119
120enum dib9000_power_mode {
121 DIB9000_POWER_ALL = 0,
122
123 DIB9000_POWER_NO,
124 DIB9000_POWER_INTERF_ANALOG_AGC,
125 DIB9000_POWER_COR4_DINTLV_ICIRM_EQUAL_CFROD,
126 DIB9000_POWER_COR4_CRY_ESRAM_MOUT_NUD,
127 DIB9000_POWER_INTERFACE_ONLY,
128};
129
130enum dib9000_out_messages {
131 OUT_MSG_HBM_ACK,
132 OUT_MSG_HOST_BUF_FAIL,
133 OUT_MSG_REQ_VERSION,
134 OUT_MSG_BRIDGE_I2C_W,
135 OUT_MSG_BRIDGE_I2C_R,
136 OUT_MSG_BRIDGE_APB_W,
137 OUT_MSG_BRIDGE_APB_R,
138 OUT_MSG_SCAN_CHANNEL,
139 OUT_MSG_MONIT_DEMOD,
140 OUT_MSG_CONF_GPIO,
141 OUT_MSG_DEBUG_HELP,
142 OUT_MSG_SUBBAND_SEL,
143 OUT_MSG_ENABLE_TIME_SLICE,
144 OUT_MSG_FE_FW_DL,
145 OUT_MSG_FE_CHANNEL_SEARCH,
146 OUT_MSG_FE_CHANNEL_TUNE,
147 OUT_MSG_FE_SLEEP,
148 OUT_MSG_FE_SYNC,
149 OUT_MSG_CTL_MONIT,
150
151 OUT_MSG_CONF_SVC,
152 OUT_MSG_SET_HBM,
153 OUT_MSG_INIT_DEMOD,
154 OUT_MSG_ENABLE_DIVERSITY,
155 OUT_MSG_SET_OUTPUT_MODE,
156 OUT_MSG_SET_PRIORITARY_CHANNEL,
157 OUT_MSG_ACK_FRG,
158 OUT_MSG_INIT_PMU,
159};
160
161enum dib9000_in_messages {
162 IN_MSG_DATA,
163 IN_MSG_FRAME_INFO,
164 IN_MSG_CTL_MONIT,
165 IN_MSG_ACK_FREE_ITEM,
166 IN_MSG_DEBUG_BUF,
167 IN_MSG_MPE_MONITOR,
168 IN_MSG_RAWTS_MONITOR,
169 IN_MSG_END_BRIDGE_I2C_RW,
170 IN_MSG_END_BRIDGE_APB_RW,
171 IN_MSG_VERSION,
172 IN_MSG_END_OF_SCAN,
173 IN_MSG_MONIT_DEMOD,
174 IN_MSG_ERROR,
175 IN_MSG_FE_FW_DL_DONE,
176 IN_MSG_EVENT,
177 IN_MSG_ACK_CHANGE_SVC,
178 IN_MSG_HBM_PROF,
179};
180
181/* memory_access requests */
182#define FE_MM_W_CHANNEL 0
183#define FE_MM_W_FE_INFO 1
184#define FE_MM_RW_SYNC 2
185
186#define FE_SYNC_CHANNEL 1
187#define FE_SYNC_W_GENERIC_MONIT 2
188#define FE_SYNC_COMPONENT_ACCESS 3
189
190#define FE_MM_R_CHANNEL_SEARCH_STATE 3
191#define FE_MM_R_CHANNEL_UNION_CONTEXT 4
192#define FE_MM_R_FE_INFO 5
193#define FE_MM_R_FE_MONITOR 6
194
195#define FE_MM_W_CHANNEL_HEAD 7
196#define FE_MM_W_CHANNEL_UNION 8
197#define FE_MM_W_CHANNEL_CONTEXT 9
198#define FE_MM_R_CHANNEL_UNION 10
199#define FE_MM_R_CHANNEL_CONTEXT 11
200#define FE_MM_R_CHANNEL_TUNE_STATE 12
201
202#define FE_MM_R_GENERIC_MONITORING_SIZE 13
203#define FE_MM_W_GENERIC_MONITORING 14
204#define FE_MM_R_GENERIC_MONITORING 15
205
206#define FE_MM_W_COMPONENT_ACCESS 16
207#define FE_MM_RW_COMPONENT_ACCESS_BUFFER 17
b4d6046e 208static int dib9000_risc_apb_access_read(struct dib9000_state *state, u32 address, u16 attribute, const u8 * tx, u32 txlen, u8 * b, u32 len);
dd316c6b
OG
209static int dib9000_risc_apb_access_write(struct dib9000_state *state, u32 address, u16 attribute, const u8 * b, u32 len);
210
211static u16 to_fw_output_mode(u16 mode)
212{
213 switch (mode) {
214 case OUTMODE_HIGH_Z:
215 return 0;
216 case OUTMODE_MPEG2_PAR_GATED_CLK:
217 return 4;
218 case OUTMODE_MPEG2_PAR_CONT_CLK:
219 return 8;
220 case OUTMODE_MPEG2_SERIAL:
221 return 16;
222 case OUTMODE_DIVERSITY:
223 return 128;
224 case OUTMODE_MPEG2_FIFO:
225 return 2;
226 case OUTMODE_ANALOG_ADC:
227 return 1;
228 default:
229 return 0;
230 }
231}
232
88d0518c 233static int dib9000_read16_attr(struct dib9000_state *state, u16 reg, u8 *b, u32 len, u16 attribute)
dd316c6b
OG
234{
235 u32 chunk_size = 126;
236 u32 l;
237 int ret;
dd316c6b
OG
238
239 if (state->platform.risc.fw_is_running && (reg < 1024))
240 return dib9000_risc_apb_access_read(state, reg, attribute, NULL, 0, b, len);
241
5a0deeed
OG
242 memset(state->msg, 0, 2 * sizeof(struct i2c_msg));
243 state->msg[0].addr = state->i2c.i2c_addr >> 1;
244 state->msg[0].flags = 0;
245 state->msg[0].buf = state->i2c_write_buffer;
246 state->msg[0].len = 2;
247 state->msg[1].addr = state->i2c.i2c_addr >> 1;
248 state->msg[1].flags = I2C_M_RD;
249 state->msg[1].buf = b;
250 state->msg[1].len = len;
251
252 state->i2c_write_buffer[0] = reg >> 8;
253 state->i2c_write_buffer[1] = reg & 0xff;
254
dd316c6b 255 if (attribute & DATA_BUS_ACCESS_MODE_8BIT)
5a0deeed 256 state->i2c_write_buffer[0] |= (1 << 5);
dd316c6b 257 if (attribute & DATA_BUS_ACCESS_MODE_NO_ADDRESS_INCREMENT)
5a0deeed 258 state->i2c_write_buffer[0] |= (1 << 4);
dd316c6b
OG
259
260 do {
261 l = len < chunk_size ? len : chunk_size;
5a0deeed
OG
262 state->msg[1].len = l;
263 state->msg[1].buf = b;
264 ret = i2c_transfer(state->i2c.i2c_adap, state->msg, 2) != 2 ? -EREMOTEIO : 0;
dd316c6b 265 if (ret != 0) {
3dd72262 266 dprintk("i2c read error on %d\n", reg);
dd316c6b
OG
267 return -EREMOTEIO;
268 }
269
270 b += l;
271 len -= l;
272
273 if (!(attribute & DATA_BUS_ACCESS_MODE_NO_ADDRESS_INCREMENT))
274 reg += l / 2;
275 } while ((ret == 0) && len);
276
277 return 0;
278}
279
280static u16 dib9000_i2c_read16(struct i2c_device *i2c, u16 reg)
281{
dd316c6b 282 struct i2c_msg msg[2] = {
5a0deeed
OG
283 {.addr = i2c->i2c_addr >> 1, .flags = 0,
284 .buf = i2c->i2c_write_buffer, .len = 2},
285 {.addr = i2c->i2c_addr >> 1, .flags = I2C_M_RD,
286 .buf = i2c->i2c_read_buffer, .len = 2},
dd316c6b
OG
287 };
288
5a0deeed
OG
289 i2c->i2c_write_buffer[0] = reg >> 8;
290 i2c->i2c_write_buffer[1] = reg & 0xff;
291
dd316c6b 292 if (i2c_transfer(i2c->i2c_adap, msg, 2) != 2) {
3dd72262 293 dprintk("read register %x error\n", reg);
dd316c6b
OG
294 return 0;
295 }
296
5a0deeed 297 return (i2c->i2c_read_buffer[0] << 8) | i2c->i2c_read_buffer[1];
dd316c6b
OG
298}
299
300static inline u16 dib9000_read_word(struct dib9000_state *state, u16 reg)
301{
5a0deeed 302 if (dib9000_read16_attr(state, reg, state->i2c_read_buffer, 2, 0) != 0)
dd316c6b 303 return 0;
5a0deeed 304 return (state->i2c_read_buffer[0] << 8) | state->i2c_read_buffer[1];
dd316c6b
OG
305}
306
307static inline u16 dib9000_read_word_attr(struct dib9000_state *state, u16 reg, u16 attribute)
308{
5a0deeed
OG
309 if (dib9000_read16_attr(state, reg, state->i2c_read_buffer, 2,
310 attribute) != 0)
dd316c6b 311 return 0;
5a0deeed 312 return (state->i2c_read_buffer[0] << 8) | state->i2c_read_buffer[1];
dd316c6b
OG
313}
314
315#define dib9000_read16_noinc_attr(state, reg, b, len, attribute) dib9000_read16_attr(state, reg, b, len, (attribute) | DATA_BUS_ACCESS_MODE_NO_ADDRESS_INCREMENT)
316
88d0518c 317static int dib9000_write16_attr(struct dib9000_state *state, u16 reg, const u8 *buf, u32 len, u16 attribute)
dd316c6b 318{
dd316c6b
OG
319 u32 chunk_size = 126;
320 u32 l;
321 int ret;
322
dd316c6b
OG
323 if (state->platform.risc.fw_is_running && (reg < 1024)) {
324 if (dib9000_risc_apb_access_write
b4d6046e 325 (state, reg, DATA_BUS_ACCESS_MODE_16BIT | DATA_BUS_ACCESS_MODE_NO_ADDRESS_INCREMENT | attribute, buf, len) != 0)
dd316c6b
OG
326 return -EINVAL;
327 return 0;
328 }
329
5a0deeed
OG
330 memset(&state->msg[0], 0, sizeof(struct i2c_msg));
331 state->msg[0].addr = state->i2c.i2c_addr >> 1;
332 state->msg[0].flags = 0;
333 state->msg[0].buf = state->i2c_write_buffer;
334 state->msg[0].len = len + 2;
335
336 state->i2c_write_buffer[0] = (reg >> 8) & 0xff;
337 state->i2c_write_buffer[1] = (reg) & 0xff;
dd316c6b
OG
338
339 if (attribute & DATA_BUS_ACCESS_MODE_8BIT)
5a0deeed 340 state->i2c_write_buffer[0] |= (1 << 5);
dd316c6b 341 if (attribute & DATA_BUS_ACCESS_MODE_NO_ADDRESS_INCREMENT)
5a0deeed 342 state->i2c_write_buffer[0] |= (1 << 4);
dd316c6b
OG
343
344 do {
345 l = len < chunk_size ? len : chunk_size;
5a0deeed
OG
346 state->msg[0].len = l + 2;
347 memcpy(&state->i2c_write_buffer[2], buf, l);
dd316c6b 348
5a0deeed 349 ret = i2c_transfer(state->i2c.i2c_adap, state->msg, 1) != 1 ? -EREMOTEIO : 0;
dd316c6b
OG
350
351 buf += l;
352 len -= l;
353
354 if (!(attribute & DATA_BUS_ACCESS_MODE_NO_ADDRESS_INCREMENT))
355 reg += l / 2;
356 } while ((ret == 0) && len);
357
358 return ret;
359}
360
361static int dib9000_i2c_write16(struct i2c_device *i2c, u16 reg, u16 val)
362{
dd316c6b 363 struct i2c_msg msg = {
5a0deeed
OG
364 .addr = i2c->i2c_addr >> 1, .flags = 0,
365 .buf = i2c->i2c_write_buffer, .len = 4
dd316c6b
OG
366 };
367
5a0deeed
OG
368 i2c->i2c_write_buffer[0] = (reg >> 8) & 0xff;
369 i2c->i2c_write_buffer[1] = reg & 0xff;
370 i2c->i2c_write_buffer[2] = (val >> 8) & 0xff;
371 i2c->i2c_write_buffer[3] = val & 0xff;
372
dd316c6b
OG
373 return i2c_transfer(i2c->i2c_adap, &msg, 1) != 1 ? -EREMOTEIO : 0;
374}
375
376static inline int dib9000_write_word(struct dib9000_state *state, u16 reg, u16 val)
377{
378 u8 b[2] = { val >> 8, val & 0xff };
379 return dib9000_write16_attr(state, reg, b, 2, 0);
380}
381
382static inline int dib9000_write_word_attr(struct dib9000_state *state, u16 reg, u16 val, u16 attribute)
383{
384 u8 b[2] = { val >> 8, val & 0xff };
385 return dib9000_write16_attr(state, reg, b, 2, attribute);
386}
387
388#define dib9000_write(state, reg, buf, len) dib9000_write16_attr(state, reg, buf, len, 0)
389#define dib9000_write16_noinc(state, reg, buf, len) dib9000_write16_attr(state, reg, buf, len, DATA_BUS_ACCESS_MODE_NO_ADDRESS_INCREMENT)
390#define dib9000_write16_noinc_attr(state, reg, buf, len, attribute) dib9000_write16_attr(state, reg, buf, len, DATA_BUS_ACCESS_MODE_NO_ADDRESS_INCREMENT | (attribute))
391
392#define dib9000_mbx_send(state, id, data, len) dib9000_mbx_send_attr(state, id, data, len, 0)
393#define dib9000_mbx_get_message(state, id, msg, len) dib9000_mbx_get_message_attr(state, id, msg, len, 0)
394
395#define MAC_IRQ (1 << 1)
396#define IRQ_POL_MSK (1 << 4)
397
398#define dib9000_risc_mem_read_chunks(state, b, len) dib9000_read16_attr(state, 1063, b, len, DATA_BUS_ACCESS_MODE_8BIT | DATA_BUS_ACCESS_MODE_NO_ADDRESS_INCREMENT)
399#define dib9000_risc_mem_write_chunks(state, buf, len) dib9000_write16_attr(state, 1063, buf, len, DATA_BUS_ACCESS_MODE_8BIT | DATA_BUS_ACCESS_MODE_NO_ADDRESS_INCREMENT)
400
401static void dib9000_risc_mem_setup_cmd(struct dib9000_state *state, u32 addr, u32 len, u8 reading)
402{
403 u8 b[14] = { 0 };
404
b4d6046e
OG
405/* dprintk("%d memcmd: %d %d %d\n", state->fe_id, addr, addr+len, len); */
406/* b[0] = 0 << 7; */
dd316c6b
OG
407 b[1] = 1;
408
b4d6046e
OG
409/* b[2] = 0; */
410/* b[3] = 0; */
411 b[4] = (u8) (addr >> 8);
dd316c6b
OG
412 b[5] = (u8) (addr & 0xff);
413
b4d6046e
OG
414/* b[10] = 0; */
415/* b[11] = 0; */
416 b[12] = (u8) (addr >> 8);
dd316c6b
OG
417 b[13] = (u8) (addr & 0xff);
418
419 addr += len;
b4d6046e
OG
420/* b[6] = 0; */
421/* b[7] = 0; */
422 b[8] = (u8) (addr >> 8);
dd316c6b
OG
423 b[9] = (u8) (addr & 0xff);
424
425 dib9000_write(state, 1056, b, 14);
426 if (reading)
427 dib9000_write_word(state, 1056, (1 << 15) | 1);
428 state->platform.risc.memcmd = -1; /* if it was called directly reset it - to force a future setup-call to set it */
429}
430
431static void dib9000_risc_mem_setup(struct dib9000_state *state, u8 cmd)
432{
433 struct dib9000_fe_memory_map *m = &state->platform.risc.fe_mm[cmd & 0x7f];
434 /* decide whether we need to "refresh" the memory controller */
435 if (state->platform.risc.memcmd == cmd && /* same command */
b4d6046e 436 !(cmd & 0x80 && m->size < 67)) /* and we do not want to read something with less than 67 bytes looping - working around a bug in the memory controller */
dd316c6b
OG
437 return;
438 dib9000_risc_mem_setup_cmd(state, m->addr, m->size, cmd & 0x80);
439 state->platform.risc.memcmd = cmd;
440}
441
442static int dib9000_risc_mem_read(struct dib9000_state *state, u8 cmd, u8 * b, u16 len)
443{
444 if (!state->platform.risc.fw_is_running)
445 return -EIO;
446
1eaef48b 447 if (mutex_lock_interruptible(&state->platform.risc.mem_lock) < 0) {
3dd72262 448 dprintk("could not get the lock\n");
f3033aec
AK
449 return -EINTR;
450 }
dd316c6b
OG
451 dib9000_risc_mem_setup(state, cmd | 0x80);
452 dib9000_risc_mem_read_chunks(state, b, len);
1eaef48b 453 mutex_unlock(&state->platform.risc.mem_lock);
dd316c6b
OG
454 return 0;
455}
456
457static int dib9000_risc_mem_write(struct dib9000_state *state, u8 cmd, const u8 * b)
458{
459 struct dib9000_fe_memory_map *m = &state->platform.risc.fe_mm[cmd];
460 if (!state->platform.risc.fw_is_running)
461 return -EIO;
462
1eaef48b 463 if (mutex_lock_interruptible(&state->platform.risc.mem_lock) < 0) {
3dd72262 464 dprintk("could not get the lock\n");
f3033aec
AK
465 return -EINTR;
466 }
dd316c6b
OG
467 dib9000_risc_mem_setup(state, cmd);
468 dib9000_risc_mem_write_chunks(state, b, m->size);
1eaef48b 469 mutex_unlock(&state->platform.risc.mem_lock);
dd316c6b
OG
470 return 0;
471}
472
473static int dib9000_firmware_download(struct dib9000_state *state, u8 risc_id, u16 key, const u8 * code, u32 len)
474{
475 u16 offs;
476
477 if (risc_id == 1)
478 offs = 16;
479 else
480 offs = 0;
481
482 /* config crtl reg */
483 dib9000_write_word(state, 1024 + offs, 0x000f);
484 dib9000_write_word(state, 1025 + offs, 0);
485 dib9000_write_word(state, 1031 + offs, key);
486
3dd72262 487 dprintk("going to download %dB of microcode\n", len);
dd316c6b 488 if (dib9000_write16_noinc(state, 1026 + offs, (u8 *) code, (u16) len) != 0) {
3dd72262 489 dprintk("error while downloading microcode for RISC %c\n", 'A' + risc_id);
dd316c6b
OG
490 return -EIO;
491 }
492
3dd72262 493 dprintk("Microcode for RISC %c loaded\n", 'A' + risc_id);
dd316c6b
OG
494
495 return 0;
496}
497
498static int dib9000_mbx_host_init(struct dib9000_state *state, u8 risc_id)
499{
500 u16 mbox_offs;
501 u16 reset_reg;
502 u16 tries = 1000;
503
504 if (risc_id == 1)
505 mbox_offs = 16;
506 else
507 mbox_offs = 0;
508
509 /* Reset mailbox */
510 dib9000_write_word(state, 1027 + mbox_offs, 0x8000);
511
512 /* Read reset status */
513 do {
514 reset_reg = dib9000_read_word(state, 1027 + mbox_offs);
515 msleep(100);
516 } while ((reset_reg & 0x8000) && --tries);
517
518 if (reset_reg & 0x8000) {
3dd72262 519 dprintk("MBX: init ERROR, no response from RISC %c\n", 'A' + risc_id);
dd316c6b
OG
520 return -EIO;
521 }
3dd72262 522 dprintk("MBX: initialized\n");
dd316c6b
OG
523 return 0;
524}
525
526#define MAX_MAILBOX_TRY 100
527static int dib9000_mbx_send_attr(struct dib9000_state *state, u8 id, u16 * data, u8 len, u16 attr)
528{
b00aff6a 529 u8 *d, b[2];
dd316c6b
OG
530 u16 tmp;
531 u16 size;
532 u32 i;
b00aff6a 533 int ret = 0;
dd316c6b
OG
534
535 if (!state->platform.risc.fw_is_running)
536 return -EINVAL;
537
1eaef48b 538 if (mutex_lock_interruptible(&state->platform.risc.mbx_if_lock) < 0) {
3dd72262 539 dprintk("could not get the lock\n");
f3033aec
AK
540 return -EINTR;
541 }
dd316c6b
OG
542 tmp = MAX_MAILBOX_TRY;
543 do {
544 size = dib9000_read_word_attr(state, 1043, attr) & 0xff;
545 if ((size + len + 1) > MBX_MAX_WORDS && --tmp) {
3dd72262 546 dprintk("MBX: RISC mbx full, retrying\n");
dd316c6b
OG
547 msleep(100);
548 } else
549 break;
550 } while (1);
551
3dd72262 552 /*dprintk( "MBX: size: %d\n", size); */
dd316c6b
OG
553
554 if (tmp == 0) {
555 ret = -EINVAL;
556 goto out;
557 }
558#ifdef DUMP_MSG
3dd72262 559 dprintk("--> %02x %d %*ph\n", id, len + 1, len, data);
dd316c6b
OG
560#endif
561
562 /* byte-order conversion - works on big (where it is not necessary) or little endian */
563 d = (u8 *) data;
564 for (i = 0; i < len; i++) {
565 tmp = data[i];
566 *d++ = tmp >> 8;
567 *d++ = tmp & 0xff;
568 }
569
570 /* write msg */
571 b[0] = id;
572 b[1] = len + 1;
573 if (dib9000_write16_noinc_attr(state, 1045, b, 2, attr) != 0 || dib9000_write16_noinc_attr(state, 1045, (u8 *) data, len * 2, attr) != 0) {
574 ret = -EIO;
575 goto out;
576 }
577
578 /* update register nb_mes_in_RX */
579 ret = (u8) dib9000_write_word_attr(state, 1043, 1 << 14, attr);
580
b4d6046e 581out:
1eaef48b 582 mutex_unlock(&state->platform.risc.mbx_if_lock);
dd316c6b
OG
583
584 return ret;
585}
586
587static u8 dib9000_mbx_read(struct dib9000_state *state, u16 * data, u8 risc_id, u16 attr)
588{
589#ifdef DUMP_MSG
590 u16 *d = data;
591#endif
592
593 u16 tmp, i;
594 u8 size;
595 u8 mc_base;
596
597 if (!state->platform.risc.fw_is_running)
598 return 0;
599
1eaef48b 600 if (mutex_lock_interruptible(&state->platform.risc.mbx_if_lock) < 0) {
3dd72262 601 dprintk("could not get the lock\n");
f3033aec
AK
602 return 0;
603 }
dd316c6b
OG
604 if (risc_id == 1)
605 mc_base = 16;
606 else
607 mc_base = 0;
608
609 /* Length and type in the first word */
610 *data = dib9000_read_word_attr(state, 1029 + mc_base, attr);
611
612 size = *data & 0xff;
613 if (size <= MBX_MAX_WORDS) {
614 data++;
615 size--; /* Initial word already read */
616
617 dib9000_read16_noinc_attr(state, 1029 + mc_base, (u8 *) data, size * 2, attr);
618
619 /* to word conversion */
620 for (i = 0; i < size; i++) {
621 tmp = *data;
622 *data = (tmp >> 8) | (tmp << 8);
623 data++;
624 }
625
626#ifdef DUMP_MSG
3dd72262 627 dprintk("<--\n");
dd316c6b 628 for (i = 0; i < size + 1; i++)
3dd72262 629 dprintk("%04x\n", d[i]);
dd316c6b
OG
630 dprintk("\n");
631#endif
632 } else {
3dd72262 633 dprintk("MBX: message is too big for message cache (%d), flushing message\n", size);
dd316c6b
OG
634 size--; /* Initial word already read */
635 while (size--)
636 dib9000_read16_noinc_attr(state, 1029 + mc_base, (u8 *) data, 2, attr);
637 }
638 /* Update register nb_mes_in_TX */
639 dib9000_write_word_attr(state, 1028 + mc_base, 1 << 14, attr);
640
1eaef48b 641 mutex_unlock(&state->platform.risc.mbx_if_lock);
dd316c6b
OG
642
643 return size + 1;
644}
645
646static int dib9000_risc_debug_buf(struct dib9000_state *state, u16 * data, u8 size)
647{
648 u32 ts = data[1] << 16 | data[0];
649 char *b = (char *)&data[2];
650
651 b[2 * (size - 2) - 1] = '\0'; /* Bullet proof the buffer */
652 if (*b == '~') {
653 b++;
3dd72262 654 dprintk("%s\n", b);
dd316c6b 655 } else
3dd72262
MCC
656 dprintk("RISC%d: %d.%04d %s\n",
657 state->fe_id,
658 ts / 10000, ts % 10000, *b ? b : "<empty>");
dd316c6b
OG
659 return 1;
660}
661
662static int dib9000_mbx_fetch_to_cache(struct dib9000_state *state, u16 attr)
663{
664 int i;
665 u8 size;
666 u16 *block;
667 /* find a free slot */
668 for (i = 0; i < DIB9000_MSG_CACHE_SIZE; i++) {
669 block = state->platform.risc.message_cache[i];
670 if (*block == 0) {
671 size = dib9000_mbx_read(state, block, 1, attr);
672
3dd72262 673/* dprintk( "MBX: fetched %04x message to cache\n", *block); */
dd316c6b
OG
674
675 switch (*block >> 8) {
676 case IN_MSG_DEBUG_BUF:
677 dib9000_risc_debug_buf(state, block + 1, size); /* debug-messages are going to be printed right away */
678 *block = 0; /* free the block */
679 break;
680#if 0
681 case IN_MSG_DATA: /* FE-TRACE */
682 dib9000_risc_data_process(state, block + 1, size);
683 *block = 0;
684 break;
685#endif
686 default:
687 break;
688 }
689
690 return 1;
691 }
692 }
3dd72262 693 dprintk("MBX: no free cache-slot found for new message...\n");
dd316c6b
OG
694 return -1;
695}
696
697static u8 dib9000_mbx_count(struct dib9000_state *state, u8 risc_id, u16 attr)
698{
699 if (risc_id == 0)
700 return (u8) (dib9000_read_word_attr(state, 1028, attr) >> 10) & 0x1f; /* 5 bit field */
701 else
702 return (u8) (dib9000_read_word_attr(state, 1044, attr) >> 8) & 0x7f; /* 7 bit field */
703}
704
705static int dib9000_mbx_process(struct dib9000_state *state, u16 attr)
706{
707 int ret = 0;
dd316c6b
OG
708
709 if (!state->platform.risc.fw_is_running)
710 return -1;
711
1eaef48b 712 if (mutex_lock_interruptible(&state->platform.risc.mbx_lock) < 0) {
3dd72262 713 dprintk("could not get the lock\n");
f3033aec
AK
714 return -1;
715 }
dd316c6b
OG
716
717 if (dib9000_mbx_count(state, 1, attr)) /* 1=RiscB */
718 ret = dib9000_mbx_fetch_to_cache(state, attr);
719
fdf07b02 720 dib9000_read_word_attr(state, 1229, attr); /* Clear the IRQ */
b4d6046e 721/* if (tmp) */
3dd72262 722/* dprintk( "cleared IRQ: %x\n", tmp); */
1eaef48b 723 mutex_unlock(&state->platform.risc.mbx_lock);
dd316c6b
OG
724
725 return ret;
726}
727
728static int dib9000_mbx_get_message_attr(struct dib9000_state *state, u16 id, u16 * msg, u8 * size, u16 attr)
729{
730 u8 i;
731 u16 *block;
732 u16 timeout = 30;
733
734 *msg = 0;
735 do {
736 /* dib9000_mbx_get_from_cache(); */
737 for (i = 0; i < DIB9000_MSG_CACHE_SIZE; i++) {
738 block = state->platform.risc.message_cache[i];
739 if ((*block >> 8) == id) {
740 *size = (*block & 0xff) - 1;
741 memcpy(msg, block + 1, (*size) * 2);
742 *block = 0; /* free the block */
743 i = 0; /* signal that we found a message */
744 break;
745 }
746 }
747
748 if (i == 0)
749 break;
750
751 if (dib9000_mbx_process(state, attr) == -1) /* try to fetch one message - if any */
752 return -1;
753
754 } while (--timeout);
755
756 if (timeout == 0) {
3dd72262 757 dprintk("waiting for message %d timed out\n", id);
dd316c6b
OG
758 return -1;
759 }
760
761 return i == 0;
762}
763
764static int dib9000_risc_check_version(struct dib9000_state *state)
765{
766 u8 r[4];
767 u8 size;
768 u16 fw_version = 0;
769
770 if (dib9000_mbx_send(state, OUT_MSG_REQ_VERSION, &fw_version, 1) != 0)
771 return -EIO;
772
773 if (dib9000_mbx_get_message(state, IN_MSG_VERSION, (u16 *) r, &size) < 0)
774 return -EIO;
775
776 fw_version = (r[0] << 8) | r[1];
3dd72262 777 dprintk("RISC: ver: %d.%02d (IC: %d)\n", fw_version >> 10, fw_version & 0x3ff, (r[2] << 8) | r[3]);
dd316c6b
OG
778
779 if ((fw_version >> 10) != 7)
780 return -EINVAL;
781
782 switch (fw_version & 0x3ff) {
783 case 11:
784 case 12:
785 case 14:
786 case 15:
787 case 16:
788 case 17:
789 break;
790 default:
791 dprintk("RISC: invalid firmware version");
792 return -EINVAL;
793 }
794
795 dprintk("RISC: valid firmware version");
796 return 0;
797}
798
799static int dib9000_fw_boot(struct dib9000_state *state, const u8 * codeA, u32 lenA, const u8 * codeB, u32 lenB)
800{
801 /* Reconfig pool mac ram */
802 dib9000_write_word(state, 1225, 0x02); /* A: 8k C, 4 k D - B: 32k C 6 k D - IRAM 96k */
803 dib9000_write_word(state, 1226, 0x05);
804
805 /* Toggles IP crypto to Host APB interface. */
806 dib9000_write_word(state, 1542, 1);
807
808 /* Set jump and no jump in the dma box */
809 dib9000_write_word(state, 1074, 0);
810 dib9000_write_word(state, 1075, 0);
811
812 /* Set MAC as APB Master. */
813 dib9000_write_word(state, 1237, 0);
814
815 /* Reset the RISCs */
816 if (codeA != NULL)
817 dib9000_write_word(state, 1024, 2);
818 else
819 dib9000_write_word(state, 1024, 15);
820 if (codeB != NULL)
821 dib9000_write_word(state, 1040, 2);
822
823 if (codeA != NULL)
824 dib9000_firmware_download(state, 0, 0x1234, codeA, lenA);
825 if (codeB != NULL)
826 dib9000_firmware_download(state, 1, 0x1234, codeB, lenB);
827
828 /* Run the RISCs */
829 if (codeA != NULL)
830 dib9000_write_word(state, 1024, 0);
831 if (codeB != NULL)
832 dib9000_write_word(state, 1040, 0);
833
834 if (codeA != NULL)
835 if (dib9000_mbx_host_init(state, 0) != 0)
836 return -EIO;
837 if (codeB != NULL)
838 if (dib9000_mbx_host_init(state, 1) != 0)
839 return -EIO;
840
841 msleep(100);
842 state->platform.risc.fw_is_running = 1;
843
844 if (dib9000_risc_check_version(state) != 0)
845 return -EINVAL;
846
847 state->platform.risc.memcmd = 0xff;
848 return 0;
849}
850
851static u16 dib9000_identify(struct i2c_device *client)
852{
853 u16 value;
854
b4d6046e
OG
855 value = dib9000_i2c_read16(client, 896);
856 if (value != 0x01b3) {
3dd72262 857 dprintk("wrong Vendor ID (0x%x)\n", value);
dd316c6b
OG
858 return 0;
859 }
860
861 value = dib9000_i2c_read16(client, 897);
862 if (value != 0x4000 && value != 0x4001 && value != 0x4002 && value != 0x4003 && value != 0x4004 && value != 0x4005) {
3dd72262 863 dprintk("wrong Device ID (0x%x)\n", value);
dd316c6b
OG
864 return 0;
865 }
866
867 /* protect this driver to be used with 7000PC */
868 if (value == 0x4000 && dib9000_i2c_read16(client, 769) == 0x4000) {
3dd72262 869 dprintk("this driver does not work with DiB7000PC\n");
dd316c6b
OG
870 return 0;
871 }
872
873 switch (value) {
874 case 0x4000:
3dd72262 875 dprintk("found DiB7000MA/PA/MB/PB\n");
dd316c6b
OG
876 break;
877 case 0x4001:
3dd72262 878 dprintk("found DiB7000HC\n");
dd316c6b
OG
879 break;
880 case 0x4002:
3dd72262 881 dprintk("found DiB7000MC\n");
dd316c6b
OG
882 break;
883 case 0x4003:
3dd72262 884 dprintk("found DiB9000A\n");
dd316c6b
OG
885 break;
886 case 0x4004:
3dd72262 887 dprintk("found DiB9000H\n");
dd316c6b
OG
888 break;
889 case 0x4005:
3dd72262 890 dprintk("found DiB9000M\n");
dd316c6b
OG
891 break;
892 }
893
894 return value;
895}
896
897static void dib9000_set_power_mode(struct dib9000_state *state, enum dib9000_power_mode mode)
898{
899 /* by default everything is going to be powered off */
900 u16 reg_903 = 0x3fff, reg_904 = 0xffff, reg_905 = 0xffff, reg_906;
901 u8 offset;
902
903 if (state->revision == 0x4003 || state->revision == 0x4004 || state->revision == 0x4005)
904 offset = 1;
905 else
906 offset = 0;
907
908 reg_906 = dib9000_read_word(state, 906 + offset) | 0x3; /* keep settings for RISC */
909
910 /* now, depending on the requested mode, we power on */
911 switch (mode) {
912 /* power up everything in the demod */
913 case DIB9000_POWER_ALL:
914 reg_903 = 0x0000;
915 reg_904 = 0x0000;
916 reg_905 = 0x0000;
917 reg_906 = 0x0000;
918 break;
919
920 /* just leave power on the control-interfaces: GPIO and (I2C or SDIO or SRAM) */
921 case DIB9000_POWER_INTERFACE_ONLY: /* TODO power up either SDIO or I2C or SRAM */
922 reg_905 &= ~((1 << 7) | (1 << 6) | (1 << 5) | (1 << 2));
923 break;
924
925 case DIB9000_POWER_INTERF_ANALOG_AGC:
926 reg_903 &= ~((1 << 15) | (1 << 14) | (1 << 11) | (1 << 10));
927 reg_905 &= ~((1 << 7) | (1 << 6) | (1 << 5) | (1 << 4) | (1 << 2));
928 reg_906 &= ~((1 << 0));
929 break;
930
931 case DIB9000_POWER_COR4_DINTLV_ICIRM_EQUAL_CFROD:
932 reg_903 = 0x0000;
933 reg_904 = 0x801f;
934 reg_905 = 0x0000;
935 reg_906 &= ~((1 << 0));
936 break;
937
938 case DIB9000_POWER_COR4_CRY_ESRAM_MOUT_NUD:
939 reg_903 = 0x0000;
940 reg_904 = 0x8000;
941 reg_905 = 0x010b;
942 reg_906 &= ~((1 << 0));
943 break;
944 default:
945 case DIB9000_POWER_NO:
946 break;
947 }
948
949 /* always power down unused parts */
950 if (!state->platform.host.mobile_mode)
951 reg_904 |= (1 << 7) | (1 << 6) | (1 << 4) | (1 << 2) | (1 << 1);
952
953 /* P_sdio_select_clk = 0 on MC and after */
954 if (state->revision != 0x4000)
955 reg_906 <<= 1;
956
957 dib9000_write_word(state, 903 + offset, reg_903);
958 dib9000_write_word(state, 904 + offset, reg_904);
959 dib9000_write_word(state, 905 + offset, reg_905);
960 dib9000_write_word(state, 906 + offset, reg_906);
961}
962
963static int dib9000_fw_reset(struct dvb_frontend *fe)
964{
965 struct dib9000_state *state = fe->demodulator_priv;
966
b4d6046e 967 dib9000_write_word(state, 1817, 0x0003);
dd316c6b
OG
968
969 dib9000_write_word(state, 1227, 1);
970 dib9000_write_word(state, 1227, 0);
971
972 switch ((state->revision = dib9000_identify(&state->i2c))) {
973 case 0x4003:
974 case 0x4004:
975 case 0x4005:
976 state->reg_offs = 1;
977 break;
978 default:
979 return -EINVAL;
980 }
981
982 /* reset the i2c-master to use the host interface */
983 dibx000_reset_i2c_master(&state->i2c_master);
984
985 dib9000_set_power_mode(state, DIB9000_POWER_ALL);
986
987 /* unforce divstr regardless whether i2c enumeration was done or not */
988 dib9000_write_word(state, 1794, dib9000_read_word(state, 1794) & ~(1 << 1));
989 dib9000_write_word(state, 1796, 0);
990 dib9000_write_word(state, 1805, 0x805);
991
992 /* restart all parts */
993 dib9000_write_word(state, 898, 0xffff);
994 dib9000_write_word(state, 899, 0xffff);
995 dib9000_write_word(state, 900, 0x0001);
996 dib9000_write_word(state, 901, 0xff19);
997 dib9000_write_word(state, 902, 0x003c);
998
999 dib9000_write_word(state, 898, 0);
1000 dib9000_write_word(state, 899, 0);
1001 dib9000_write_word(state, 900, 0);
1002 dib9000_write_word(state, 901, 0);
1003 dib9000_write_word(state, 902, 0);
1004
1005 dib9000_write_word(state, 911, state->chip.d9.cfg.if_drives);
1006
1007 dib9000_set_power_mode(state, DIB9000_POWER_INTERFACE_ONLY);
1008
1009 return 0;
1010}
1011
b4d6046e 1012static int dib9000_risc_apb_access_read(struct dib9000_state *state, u32 address, u16 attribute, const u8 * tx, u32 txlen, u8 * b, u32 len)
dd316c6b
OG
1013{
1014 u16 mb[10];
1015 u8 i, s;
1016
1017 if (address >= 1024 || !state->platform.risc.fw_is_running)
1018 return -EINVAL;
1019
868c9a17 1020 /* dprintk( "APB access through rd fw %d %x\n", address, attribute); */
dd316c6b
OG
1021
1022 mb[0] = (u16) address;
1023 mb[1] = len / 2;
1024 dib9000_mbx_send_attr(state, OUT_MSG_BRIDGE_APB_R, mb, 2, attribute);
1025 switch (dib9000_mbx_get_message_attr(state, IN_MSG_END_BRIDGE_APB_RW, mb, &s, attribute)) {
1026 case 1:
b4d6046e 1027 s--;
dd316c6b
OG
1028 for (i = 0; i < s; i++) {
1029 b[i * 2] = (mb[i + 1] >> 8) & 0xff;
1030 b[i * 2 + 1] = (mb[i + 1]) & 0xff;
1031 }
1032 return 0;
1033 default:
1034 return -EIO;
1035 }
1036 return -EIO;
1037}
1038
1039static int dib9000_risc_apb_access_write(struct dib9000_state *state, u32 address, u16 attribute, const u8 * b, u32 len)
1040{
1041 u16 mb[10];
1042 u8 s, i;
1043
1044 if (address >= 1024 || !state->platform.risc.fw_is_running)
1045 return -EINVAL;
1046
18d75a09
HS
1047 if (len > 18)
1048 return -EINVAL;
1049
868c9a17 1050 /* dprintk( "APB access through wr fw %d %x\n", address, attribute); */
dd316c6b 1051
18d75a09
HS
1052 mb[0] = (u16)address;
1053 for (i = 0; i + 1 < len; i += 2)
1054 mb[1 + i / 2] = b[i] << 8 | b[i + 1];
1055 if (len & 1)
1056 mb[1 + len / 2] = b[len - 1] << 8;
dd316c6b 1057
18d75a09 1058 dib9000_mbx_send_attr(state, OUT_MSG_BRIDGE_APB_W, mb, (3 + len) / 2, attribute);
dd316c6b
OG
1059 return dib9000_mbx_get_message_attr(state, IN_MSG_END_BRIDGE_APB_RW, mb, &s, attribute) == 1 ? 0 : -EINVAL;
1060}
1061
1062static int dib9000_fw_memmbx_sync(struct dib9000_state *state, u8 i)
1063{
1064 u8 index_loop = 10;
1065
1066 if (!state->platform.risc.fw_is_running)
1067 return 0;
1068 dib9000_risc_mem_write(state, FE_MM_RW_SYNC, &i);
1069 do {
5a0deeed
OG
1070 dib9000_risc_mem_read(state, FE_MM_RW_SYNC, state->i2c_read_buffer, 1);
1071 } while (state->i2c_read_buffer[0] && index_loop--);
dd316c6b
OG
1072
1073 if (index_loop > 0)
1074 return 0;
1075 return -EIO;
1076}
1077
1078static int dib9000_fw_init(struct dib9000_state *state)
1079{
1080 struct dibGPIOFunction *f;
1081 u16 b[40] = { 0 };
1082 u8 i;
1083 u8 size;
1084
1085 if (dib9000_fw_boot(state, NULL, 0, state->chip.d9.cfg.microcode_B_fe_buffer, state->chip.d9.cfg.microcode_B_fe_size) != 0)
dd316c6b
OG
1086 return -EIO;
1087
1088 /* initialize the firmware */
1089 for (i = 0; i < ARRAY_SIZE(state->chip.d9.cfg.gpio_function); i++) {
1090 f = &state->chip.d9.cfg.gpio_function[i];
1091 if (f->mask) {
1092 switch (f->function) {
1093 case BOARD_GPIO_FUNCTION_COMPONENT_ON:
1094 b[0] = (u16) f->mask;
1095 b[1] = (u16) f->direction;
1096 b[2] = (u16) f->value;
1097 break;
1098 case BOARD_GPIO_FUNCTION_COMPONENT_OFF:
1099 b[3] = (u16) f->mask;
1100 b[4] = (u16) f->direction;
1101 b[5] = (u16) f->value;
1102 break;
1103 }
1104 }
1105 }
1106 if (dib9000_mbx_send(state, OUT_MSG_CONF_GPIO, b, 15) != 0)
1107 return -EIO;
1108
1109 /* subband */
1110 b[0] = state->chip.d9.cfg.subband.size; /* type == 0 -> GPIO - PWM not yet supported */
1111 for (i = 0; i < state->chip.d9.cfg.subband.size; i++) {
1112 b[1 + i * 4] = state->chip.d9.cfg.subband.subband[i].f_mhz;
1113 b[2 + i * 4] = (u16) state->chip.d9.cfg.subband.subband[i].gpio.mask;
1114 b[3 + i * 4] = (u16) state->chip.d9.cfg.subband.subband[i].gpio.direction;
1115 b[4 + i * 4] = (u16) state->chip.d9.cfg.subband.subband[i].gpio.value;
dd316c6b
OG
1116 }
1117 b[1 + i * 4] = 0; /* fe_id */
1118 if (dib9000_mbx_send(state, OUT_MSG_SUBBAND_SEL, b, 2 + 4 * i) != 0)
1119 return -EIO;
1120
1121 /* 0 - id, 1 - no_of_frontends */
1122 b[0] = (0 << 8) | 1;
1123 /* 0 = i2c-address demod, 0 = tuner */
b4d6046e 1124 b[1] = (0 << 8) | (0);
dd316c6b
OG
1125 b[2] = (u16) (((state->chip.d9.cfg.xtal_clock_khz * 1000) >> 16) & 0xffff);
1126 b[3] = (u16) (((state->chip.d9.cfg.xtal_clock_khz * 1000)) & 0xffff);
1127 b[4] = (u16) ((state->chip.d9.cfg.vcxo_timer >> 16) & 0xffff);
1128 b[5] = (u16) ((state->chip.d9.cfg.vcxo_timer) & 0xffff);
1129 b[6] = (u16) ((state->chip.d9.cfg.timing_frequency >> 16) & 0xffff);
1130 b[7] = (u16) ((state->chip.d9.cfg.timing_frequency) & 0xffff);
1131 b[29] = state->chip.d9.cfg.if_drives;
1132 if (dib9000_mbx_send(state, OUT_MSG_INIT_DEMOD, b, ARRAY_SIZE(b)) != 0)
1133 return -EIO;
1134
1135 if (dib9000_mbx_send(state, OUT_MSG_FE_FW_DL, NULL, 0) != 0)
1136 return -EIO;
1137
1138 if (dib9000_mbx_get_message(state, IN_MSG_FE_FW_DL_DONE, b, &size) < 0)
1139 return -EIO;
1140
1141 if (size > ARRAY_SIZE(b)) {
b4d6046e
OG
1142 dprintk("error : firmware returned %dbytes needed but the used buffer has only %dbytes\n Firmware init ABORTED", size,
1143 (int)ARRAY_SIZE(b));
dd316c6b
OG
1144 return -EINVAL;
1145 }
1146
1147 for (i = 0; i < size; i += 2) {
1148 state->platform.risc.fe_mm[i / 2].addr = b[i + 0];
1149 state->platform.risc.fe_mm[i / 2].size = b[i + 1];
dd316c6b
OG
1150 }
1151
1152 return 0;
1153}
1154
759e236c 1155static void dib9000_fw_set_channel_head(struct dib9000_state *state)
dd316c6b
OG
1156{
1157 u8 b[9];
1158 u32 freq = state->fe[0]->dtv_property_cache.frequency / 1000;
1159 if (state->fe_id % 2)
1160 freq += 101;
1161
1162 b[0] = (u8) ((freq >> 0) & 0xff);
1163 b[1] = (u8) ((freq >> 8) & 0xff);
1164 b[2] = (u8) ((freq >> 16) & 0xff);
1165 b[3] = (u8) ((freq >> 24) & 0xff);
1166 b[4] = (u8) ((state->fe[0]->dtv_property_cache.bandwidth_hz / 1000 >> 0) & 0xff);
1167 b[5] = (u8) ((state->fe[0]->dtv_property_cache.bandwidth_hz / 1000 >> 8) & 0xff);
1168 b[6] = (u8) ((state->fe[0]->dtv_property_cache.bandwidth_hz / 1000 >> 16) & 0xff);
1169 b[7] = (u8) ((state->fe[0]->dtv_property_cache.bandwidth_hz / 1000 >> 24) & 0xff);
1170 b[8] = 0x80; /* do not wait for CELL ID when doing autosearch */
1171 if (state->fe[0]->dtv_property_cache.delivery_system == SYS_DVBT)
1172 b[8] |= 1;
1173 dib9000_risc_mem_write(state, FE_MM_W_CHANNEL_HEAD, b);
1174}
1175
759e236c 1176static int dib9000_fw_get_channel(struct dvb_frontend *fe)
dd316c6b
OG
1177{
1178 struct dib9000_state *state = fe->demodulator_priv;
1179 struct dibDVBTChannel {
1180 s8 spectrum_inversion;
1181
1182 s8 nfft;
1183 s8 guard;
1184 s8 constellation;
1185
1186 s8 hrch;
1187 s8 alpha;
1188 s8 code_rate_hp;
1189 s8 code_rate_lp;
1190 s8 select_hp;
1191
1192 s8 intlv_native;
1193 };
5a0deeed 1194 struct dibDVBTChannel *ch;
dd316c6b
OG
1195 int ret = 0;
1196
1eaef48b 1197 if (mutex_lock_interruptible(&state->platform.risc.mem_mbx_lock) < 0) {
3dd72262 1198 dprintk("could not get the lock\n");
f3033aec
AK
1199 return -EINTR;
1200 }
dd316c6b 1201 if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0) {
dd316c6b 1202 ret = -EIO;
2f098cb1 1203 goto error;
dd316c6b
OG
1204 }
1205
5a0deeed
OG
1206 dib9000_risc_mem_read(state, FE_MM_R_CHANNEL_UNION,
1207 state->i2c_read_buffer, sizeof(struct dibDVBTChannel));
1208 ch = (struct dibDVBTChannel *)state->i2c_read_buffer;
1209
dd316c6b 1210
5a0deeed 1211 switch (ch->spectrum_inversion & 0x7) {
dd316c6b
OG
1212 case 1:
1213 state->fe[0]->dtv_property_cache.inversion = INVERSION_ON;
1214 break;
1215 case 0:
1216 state->fe[0]->dtv_property_cache.inversion = INVERSION_OFF;
1217 break;
1218 default:
1219 case -1:
1220 state->fe[0]->dtv_property_cache.inversion = INVERSION_AUTO;
1221 break;
1222 }
5a0deeed 1223 switch (ch->nfft) {
dd316c6b
OG
1224 case 0:
1225 state->fe[0]->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_2K;
1226 break;
1227 case 2:
1228 state->fe[0]->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_4K;
1229 break;
1230 case 1:
1231 state->fe[0]->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_8K;
1232 break;
1233 default:
1234 case -1:
1235 state->fe[0]->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_AUTO;
1236 break;
1237 }
5a0deeed 1238 switch (ch->guard) {
dd316c6b
OG
1239 case 0:
1240 state->fe[0]->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_32;
1241 break;
1242 case 1:
1243 state->fe[0]->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_16;
1244 break;
1245 case 2:
1246 state->fe[0]->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_8;
1247 break;
1248 case 3:
1249 state->fe[0]->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_4;
1250 break;
1251 default:
1252 case -1:
1253 state->fe[0]->dtv_property_cache.guard_interval = GUARD_INTERVAL_AUTO;
1254 break;
1255 }
5a0deeed 1256 switch (ch->constellation) {
dd316c6b
OG
1257 case 2:
1258 state->fe[0]->dtv_property_cache.modulation = QAM_64;
1259 break;
1260 case 1:
1261 state->fe[0]->dtv_property_cache.modulation = QAM_16;
1262 break;
1263 case 0:
1264 state->fe[0]->dtv_property_cache.modulation = QPSK;
1265 break;
1266 default:
1267 case -1:
1268 state->fe[0]->dtv_property_cache.modulation = QAM_AUTO;
1269 break;
1270 }
5a0deeed 1271 switch (ch->hrch) {
dd316c6b
OG
1272 case 0:
1273 state->fe[0]->dtv_property_cache.hierarchy = HIERARCHY_NONE;
1274 break;
1275 case 1:
1276 state->fe[0]->dtv_property_cache.hierarchy = HIERARCHY_1;
1277 break;
1278 default:
1279 case -1:
1280 state->fe[0]->dtv_property_cache.hierarchy = HIERARCHY_AUTO;
1281 break;
1282 }
5a0deeed 1283 switch (ch->code_rate_hp) {
dd316c6b
OG
1284 case 1:
1285 state->fe[0]->dtv_property_cache.code_rate_HP = FEC_1_2;
1286 break;
1287 case 2:
1288 state->fe[0]->dtv_property_cache.code_rate_HP = FEC_2_3;
1289 break;
1290 case 3:
1291 state->fe[0]->dtv_property_cache.code_rate_HP = FEC_3_4;
1292 break;
1293 case 5:
1294 state->fe[0]->dtv_property_cache.code_rate_HP = FEC_5_6;
1295 break;
1296 case 7:
1297 state->fe[0]->dtv_property_cache.code_rate_HP = FEC_7_8;
1298 break;
1299 default:
1300 case -1:
1301 state->fe[0]->dtv_property_cache.code_rate_HP = FEC_AUTO;
1302 break;
1303 }
5a0deeed 1304 switch (ch->code_rate_lp) {
dd316c6b
OG
1305 case 1:
1306 state->fe[0]->dtv_property_cache.code_rate_LP = FEC_1_2;
1307 break;
1308 case 2:
1309 state->fe[0]->dtv_property_cache.code_rate_LP = FEC_2_3;
1310 break;
1311 case 3:
1312 state->fe[0]->dtv_property_cache.code_rate_LP = FEC_3_4;
1313 break;
1314 case 5:
1315 state->fe[0]->dtv_property_cache.code_rate_LP = FEC_5_6;
1316 break;
1317 case 7:
1318 state->fe[0]->dtv_property_cache.code_rate_LP = FEC_7_8;
1319 break;
1320 default:
1321 case -1:
1322 state->fe[0]->dtv_property_cache.code_rate_LP = FEC_AUTO;
1323 break;
1324 }
1325
b4d6046e 1326error:
1eaef48b 1327 mutex_unlock(&state->platform.risc.mem_mbx_lock);
dd316c6b
OG
1328 return ret;
1329}
1330
f20b12ec 1331static int dib9000_fw_set_channel_union(struct dvb_frontend *fe)
dd316c6b
OG
1332{
1333 struct dib9000_state *state = fe->demodulator_priv;
1334 struct dibDVBTChannel {
1335 s8 spectrum_inversion;
1336
1337 s8 nfft;
1338 s8 guard;
1339 s8 constellation;
1340
1341 s8 hrch;
1342 s8 alpha;
1343 s8 code_rate_hp;
1344 s8 code_rate_lp;
1345 s8 select_hp;
1346
1347 s8 intlv_native;
1348 };
1349 struct dibDVBTChannel ch;
1350
1351 switch (state->fe[0]->dtv_property_cache.inversion) {
1352 case INVERSION_ON:
1353 ch.spectrum_inversion = 1;
1354 break;
1355 case INVERSION_OFF:
1356 ch.spectrum_inversion = 0;
1357 break;
1358 default:
1359 case INVERSION_AUTO:
1360 ch.spectrum_inversion = -1;
1361 break;
1362 }
1363 switch (state->fe[0]->dtv_property_cache.transmission_mode) {
1364 case TRANSMISSION_MODE_2K:
1365 ch.nfft = 0;
1366 break;
1367 case TRANSMISSION_MODE_4K:
1368 ch.nfft = 2;
1369 break;
1370 case TRANSMISSION_MODE_8K:
1371 ch.nfft = 1;
1372 break;
1373 default:
1374 case TRANSMISSION_MODE_AUTO:
1375 ch.nfft = 1;
1376 break;
1377 }
1378 switch (state->fe[0]->dtv_property_cache.guard_interval) {
1379 case GUARD_INTERVAL_1_32:
1380 ch.guard = 0;
1381 break;
1382 case GUARD_INTERVAL_1_16:
1383 ch.guard = 1;
1384 break;
1385 case GUARD_INTERVAL_1_8:
1386 ch.guard = 2;
1387 break;
1388 case GUARD_INTERVAL_1_4:
1389 ch.guard = 3;
1390 break;
1391 default:
1392 case GUARD_INTERVAL_AUTO:
1393 ch.guard = -1;
1394 break;
1395 }
1396 switch (state->fe[0]->dtv_property_cache.modulation) {
1397 case QAM_64:
1398 ch.constellation = 2;
1399 break;
1400 case QAM_16:
1401 ch.constellation = 1;
1402 break;
1403 case QPSK:
1404 ch.constellation = 0;
1405 break;
1406 default:
1407 case QAM_AUTO:
1408 ch.constellation = -1;
1409 break;
1410 }
1411 switch (state->fe[0]->dtv_property_cache.hierarchy) {
1412 case HIERARCHY_NONE:
1413 ch.hrch = 0;
1414 break;
1415 case HIERARCHY_1:
1416 case HIERARCHY_2:
1417 case HIERARCHY_4:
1418 ch.hrch = 1;
1419 break;
1420 default:
1421 case HIERARCHY_AUTO:
1422 ch.hrch = -1;
1423 break;
1424 }
1425 ch.alpha = 1;
1426 switch (state->fe[0]->dtv_property_cache.code_rate_HP) {
1427 case FEC_1_2:
1428 ch.code_rate_hp = 1;
1429 break;
1430 case FEC_2_3:
1431 ch.code_rate_hp = 2;
1432 break;
1433 case FEC_3_4:
1434 ch.code_rate_hp = 3;
1435 break;
1436 case FEC_5_6:
1437 ch.code_rate_hp = 5;
1438 break;
1439 case FEC_7_8:
1440 ch.code_rate_hp = 7;
1441 break;
1442 default:
1443 case FEC_AUTO:
1444 ch.code_rate_hp = -1;
1445 break;
1446 }
1447 switch (state->fe[0]->dtv_property_cache.code_rate_LP) {
1448 case FEC_1_2:
1449 ch.code_rate_lp = 1;
1450 break;
1451 case FEC_2_3:
1452 ch.code_rate_lp = 2;
1453 break;
1454 case FEC_3_4:
1455 ch.code_rate_lp = 3;
1456 break;
1457 case FEC_5_6:
1458 ch.code_rate_lp = 5;
1459 break;
1460 case FEC_7_8:
1461 ch.code_rate_lp = 7;
1462 break;
1463 default:
1464 case FEC_AUTO:
1465 ch.code_rate_lp = -1;
1466 break;
1467 }
1468 ch.select_hp = 1;
1469 ch.intlv_native = 1;
1470
b4d6046e 1471 dib9000_risc_mem_write(state, FE_MM_W_CHANNEL_UNION, (u8 *) &ch);
dd316c6b
OG
1472
1473 return 0;
1474}
1475
f20b12ec 1476static int dib9000_fw_tune(struct dvb_frontend *fe)
dd316c6b
OG
1477{
1478 struct dib9000_state *state = fe->demodulator_priv;
1479 int ret = 10, search = state->channel_status.status == CHANNEL_STATUS_PARAMETERS_UNKNOWN;
1480 s8 i;
1481
1482 switch (state->tune_state) {
1483 case CT_DEMOD_START:
759e236c 1484 dib9000_fw_set_channel_head(state);
dd316c6b
OG
1485
1486 /* write the channel context - a channel is initialized to 0, so it is OK */
1487 dib9000_risc_mem_write(state, FE_MM_W_CHANNEL_CONTEXT, (u8 *) fe_info);
1488 dib9000_risc_mem_write(state, FE_MM_W_FE_INFO, (u8 *) fe_info);
1489
1490 if (search)
1491 dib9000_mbx_send(state, OUT_MSG_FE_CHANNEL_SEARCH, NULL, 0);
1492 else {
f20b12ec 1493 dib9000_fw_set_channel_union(fe);
dd316c6b
OG
1494 dib9000_mbx_send(state, OUT_MSG_FE_CHANNEL_TUNE, NULL, 0);
1495 }
1496 state->tune_state = CT_DEMOD_STEP_1;
1497 break;
1498 case CT_DEMOD_STEP_1:
1499 if (search)
5a0deeed 1500 dib9000_risc_mem_read(state, FE_MM_R_CHANNEL_SEARCH_STATE, state->i2c_read_buffer, 1);
dd316c6b 1501 else
5a0deeed
OG
1502 dib9000_risc_mem_read(state, FE_MM_R_CHANNEL_TUNE_STATE, state->i2c_read_buffer, 1);
1503 i = (s8)state->i2c_read_buffer[0];
dd316c6b
OG
1504 switch (i) { /* something happened */
1505 case 0:
1506 break;
1507 case -2: /* tps locks are "slower" than MPEG locks -> even in autosearch data is OK here */
1508 if (search)
1509 state->status = FE_STATUS_DEMOD_SUCCESS;
1510 else {
1511 state->tune_state = CT_DEMOD_STOP;
1512 state->status = FE_STATUS_LOCKED;
1513 }
1514 break;
1515 default:
1516 state->status = FE_STATUS_TUNE_FAILED;
1517 state->tune_state = CT_DEMOD_STOP;
1518 break;
1519 }
1520 break;
1521 default:
1522 ret = FE_CALLBACK_TIME_NEVER;
1523 break;
1524 }
1525
1526 return ret;
1527}
1528
1529static int dib9000_fw_set_diversity_in(struct dvb_frontend *fe, int onoff)
1530{
1531 struct dib9000_state *state = fe->demodulator_priv;
1532 u16 mode = (u16) onoff;
1533 return dib9000_mbx_send(state, OUT_MSG_ENABLE_DIVERSITY, &mode, 1);
1534}
1535
1536static int dib9000_fw_set_output_mode(struct dvb_frontend *fe, int mode)
1537{
1538 struct dib9000_state *state = fe->demodulator_priv;
1539 u16 outreg, smo_mode;
1540
3dd72262 1541 dprintk("setting output mode for demod %p to %d\n", fe, mode);
dd316c6b
OG
1542
1543 switch (mode) {
b4d6046e 1544 case OUTMODE_MPEG2_PAR_GATED_CLK:
dd316c6b
OG
1545 outreg = (1 << 10); /* 0x0400 */
1546 break;
b4d6046e 1547 case OUTMODE_MPEG2_PAR_CONT_CLK:
dd316c6b
OG
1548 outreg = (1 << 10) | (1 << 6); /* 0x0440 */
1549 break;
b4d6046e 1550 case OUTMODE_MPEG2_SERIAL:
dd316c6b
OG
1551 outreg = (1 << 10) | (2 << 6) | (0 << 1); /* 0x0482 */
1552 break;
1553 case OUTMODE_DIVERSITY:
1554 outreg = (1 << 10) | (4 << 6); /* 0x0500 */
1555 break;
b4d6046e 1556 case OUTMODE_MPEG2_FIFO:
dd316c6b
OG
1557 outreg = (1 << 10) | (5 << 6);
1558 break;
b4d6046e 1559 case OUTMODE_HIGH_Z:
dd316c6b
OG
1560 outreg = 0;
1561 break;
1562 default:
3dd72262 1563 dprintk("Unhandled output_mode passed to be set for demod %p\n", &state->fe[0]);
dd316c6b
OG
1564 return -EINVAL;
1565 }
1566
b4d6046e 1567 dib9000_write_word(state, 1795, outreg);
dd316c6b
OG
1568
1569 switch (mode) {
1570 case OUTMODE_MPEG2_PAR_GATED_CLK:
1571 case OUTMODE_MPEG2_PAR_CONT_CLK:
1572 case OUTMODE_MPEG2_SERIAL:
1573 case OUTMODE_MPEG2_FIFO:
1574 smo_mode = (dib9000_read_word(state, 295) & 0x0010) | (1 << 1);
1575 if (state->chip.d9.cfg.output_mpeg2_in_188_bytes)
1576 smo_mode |= (1 << 5);
1577 dib9000_write_word(state, 295, smo_mode);
1578 break;
1579 }
1580
1581 outreg = to_fw_output_mode(mode);
1582 return dib9000_mbx_send(state, OUT_MSG_SET_OUTPUT_MODE, &outreg, 1);
1583}
1584
1585static int dib9000_tuner_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num)
1586{
1587 struct dib9000_state *state = i2c_get_adapdata(i2c_adap);
1588 u16 i, len, t, index_msg;
1589
1590 for (index_msg = 0; index_msg < num; index_msg++) {
1591 if (msg[index_msg].flags & I2C_M_RD) { /* read */
1592 len = msg[index_msg].len;
1593 if (len > 16)
1594 len = 16;
1595
1596 if (dib9000_read_word(state, 790) != 0)
3dd72262 1597 dprintk("TunerITF: read busy\n");
dd316c6b
OG
1598
1599 dib9000_write_word(state, 784, (u16) (msg[index_msg].addr));
1600 dib9000_write_word(state, 787, (len / 2) - 1);
1601 dib9000_write_word(state, 786, 1); /* start read */
1602
1603 i = 1000;
1604 while (dib9000_read_word(state, 790) != (len / 2) && i)
1605 i--;
1606
1607 if (i == 0)
3dd72262 1608 dprintk("TunerITF: read failed\n");
dd316c6b
OG
1609
1610 for (i = 0; i < len; i += 2) {
1611 t = dib9000_read_word(state, 785);
1612 msg[index_msg].buf[i] = (t >> 8) & 0xff;
1613 msg[index_msg].buf[i + 1] = (t) & 0xff;
1614 }
1615 if (dib9000_read_word(state, 790) != 0)
3dd72262 1616 dprintk("TunerITF: read more data than expected\n");
dd316c6b
OG
1617 } else {
1618 i = 1000;
1619 while (dib9000_read_word(state, 789) && i)
1620 i--;
1621 if (i == 0)
3dd72262 1622 dprintk("TunerITF: write busy\n");
dd316c6b
OG
1623
1624 len = msg[index_msg].len;
1625 if (len > 16)
1626 len = 16;
1627
1628 for (i = 0; i < len; i += 2)
1629 dib9000_write_word(state, 785, (msg[index_msg].buf[i] << 8) | msg[index_msg].buf[i + 1]);
1630 dib9000_write_word(state, 784, (u16) msg[index_msg].addr);
1631 dib9000_write_word(state, 787, (len / 2) - 1);
1632 dib9000_write_word(state, 786, 0); /* start write */
1633
1634 i = 1000;
1635 while (dib9000_read_word(state, 791) > 0 && i)
1636 i--;
1637 if (i == 0)
3dd72262 1638 dprintk("TunerITF: write failed\n");
dd316c6b
OG
1639 }
1640 }
1641 return num;
1642}
1643
1644int dib9000_fw_set_component_bus_speed(struct dvb_frontend *fe, u16 speed)
1645{
1646 struct dib9000_state *state = fe->demodulator_priv;
1647
1648 state->component_bus_speed = speed;
1649 return 0;
1650}
1651EXPORT_SYMBOL(dib9000_fw_set_component_bus_speed);
1652
1653static int dib9000_fw_component_bus_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num)
1654{
1655 struct dib9000_state *state = i2c_get_adapdata(i2c_adap);
b4d6046e 1656 u8 type = 0; /* I2C */
dd316c6b 1657 u8 port = DIBX000_I2C_INTERFACE_GPIO_3_4;
b4d6046e 1658 u16 scl = state->component_bus_speed; /* SCL frequency */
dd316c6b
OG
1659 struct dib9000_fe_memory_map *m = &state->platform.risc.fe_mm[FE_MM_RW_COMPONENT_ACCESS_BUFFER];
1660 u8 p[13] = { 0 };
1661
1662 p[0] = type;
1663 p[1] = port;
1664 p[2] = msg[0].addr << 1;
1665
1666 p[3] = (u8) scl & 0xff; /* scl */
1667 p[4] = (u8) (scl >> 8);
1668
dd316c6b
OG
1669 p[7] = 0;
1670 p[8] = 0;
1671
1672 p[9] = (u8) (msg[0].len);
1673 p[10] = (u8) (msg[0].len >> 8);
1674 if ((num > 1) && (msg[1].flags & I2C_M_RD)) {
1675 p[11] = (u8) (msg[1].len);
1676 p[12] = (u8) (msg[1].len >> 8);
1677 } else {
1678 p[11] = 0;
1679 p[12] = 0;
1680 }
1681
1eaef48b 1682 if (mutex_lock_interruptible(&state->platform.risc.mem_mbx_lock) < 0) {
3dd72262 1683 dprintk("could not get the lock\n");
f3033aec
AK
1684 return 0;
1685 }
dd316c6b
OG
1686
1687 dib9000_risc_mem_write(state, FE_MM_W_COMPONENT_ACCESS, p);
1688
1689 { /* write-part */
1690 dib9000_risc_mem_setup_cmd(state, m->addr, msg[0].len, 0);
1691 dib9000_risc_mem_write_chunks(state, msg[0].buf, msg[0].len);
1692 }
1693
1694 /* do the transaction */
1695 if (dib9000_fw_memmbx_sync(state, FE_SYNC_COMPONENT_ACCESS) < 0) {
1eaef48b 1696 mutex_unlock(&state->platform.risc.mem_mbx_lock);
dd316c6b
OG
1697 return 0;
1698 }
1699
1700 /* read back any possible result */
1701 if ((num > 1) && (msg[1].flags & I2C_M_RD))
1702 dib9000_risc_mem_read(state, FE_MM_RW_COMPONENT_ACCESS_BUFFER, msg[1].buf, msg[1].len);
1703
1eaef48b 1704 mutex_unlock(&state->platform.risc.mem_mbx_lock);
dd316c6b
OG
1705
1706 return num;
1707}
1708
1709static u32 dib9000_i2c_func(struct i2c_adapter *adapter)
1710{
1711 return I2C_FUNC_I2C;
1712}
1713
19779f40 1714static const struct i2c_algorithm dib9000_tuner_algo = {
dd316c6b
OG
1715 .master_xfer = dib9000_tuner_xfer,
1716 .functionality = dib9000_i2c_func,
1717};
1718
19779f40 1719static const struct i2c_algorithm dib9000_component_bus_algo = {
dd316c6b
OG
1720 .master_xfer = dib9000_fw_component_bus_xfer,
1721 .functionality = dib9000_i2c_func,
1722};
1723
1724struct i2c_adapter *dib9000_get_tuner_interface(struct dvb_frontend *fe)
1725{
1726 struct dib9000_state *st = fe->demodulator_priv;
1727 return &st->tuner_adap;
1728}
dd316c6b
OG
1729EXPORT_SYMBOL(dib9000_get_tuner_interface);
1730
1731struct i2c_adapter *dib9000_get_component_bus_interface(struct dvb_frontend *fe)
1732{
1733 struct dib9000_state *st = fe->demodulator_priv;
1734 return &st->component_bus;
1735}
dd316c6b
OG
1736EXPORT_SYMBOL(dib9000_get_component_bus_interface);
1737
1738struct i2c_adapter *dib9000_get_i2c_master(struct dvb_frontend *fe, enum dibx000_i2c_interface intf, int gating)
1739{
1740 struct dib9000_state *st = fe->demodulator_priv;
1741 return dibx000_get_i2c_adapter(&st->i2c_master, intf, gating);
1742}
dd316c6b
OG
1743EXPORT_SYMBOL(dib9000_get_i2c_master);
1744
1745int dib9000_set_i2c_adapter(struct dvb_frontend *fe, struct i2c_adapter *i2c)
1746{
1747 struct dib9000_state *st = fe->demodulator_priv;
1748
1749 st->i2c.i2c_adap = i2c;
1750 return 0;
1751}
dd316c6b
OG
1752EXPORT_SYMBOL(dib9000_set_i2c_adapter);
1753
1754static int dib9000_cfg_gpio(struct dib9000_state *st, u8 num, u8 dir, u8 val)
1755{
1756 st->gpio_dir = dib9000_read_word(st, 773);
1757 st->gpio_dir &= ~(1 << num); /* reset the direction bit */
1758 st->gpio_dir |= (dir & 0x1) << num; /* set the new direction */
1759 dib9000_write_word(st, 773, st->gpio_dir);
1760
1761 st->gpio_val = dib9000_read_word(st, 774);
1762 st->gpio_val &= ~(1 << num); /* reset the direction bit */
1763 st->gpio_val |= (val & 0x01) << num; /* set the new value */
1764 dib9000_write_word(st, 774, st->gpio_val);
1765
3dd72262 1766 dprintk("gpio dir: %04x: gpio val: %04x\n", st->gpio_dir, st->gpio_val);
dd316c6b
OG
1767
1768 return 0;
1769}
1770
1771int dib9000_set_gpio(struct dvb_frontend *fe, u8 num, u8 dir, u8 val)
1772{
1773 struct dib9000_state *state = fe->demodulator_priv;
1774 return dib9000_cfg_gpio(state, num, dir, val);
1775}
dd316c6b 1776EXPORT_SYMBOL(dib9000_set_gpio);
b4d6046e 1777
dd316c6b
OG
1778int dib9000_fw_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff)
1779{
1780 struct dib9000_state *state = fe->demodulator_priv;
79fcce32
PB
1781 u16 val;
1782 int ret;
1783
1784 if ((state->pid_ctrl_index != -2) && (state->pid_ctrl_index < 9)) {
1785 /* postpone the pid filtering cmd */
3dd72262 1786 dprintk("pid filter cmd postpone\n");
79fcce32
PB
1787 state->pid_ctrl_index++;
1788 state->pid_ctrl[state->pid_ctrl_index].cmd = DIB9000_PID_FILTER_CTRL;
1789 state->pid_ctrl[state->pid_ctrl_index].onoff = onoff;
1790 return 0;
1791 }
1792
1eaef48b 1793 if (mutex_lock_interruptible(&state->demod_lock) < 0) {
3dd72262 1794 dprintk("could not get the lock\n");
f3033aec
AK
1795 return -EINTR;
1796 }
79fcce32
PB
1797
1798 val = dib9000_read_word(state, 294 + 1) & 0xffef;
dd316c6b
OG
1799 val |= (onoff & 0x1) << 4;
1800
3dd72262 1801 dprintk("PID filter enabled %d\n", onoff);
79fcce32 1802 ret = dib9000_write_word(state, 294 + 1, val);
1eaef48b 1803 mutex_unlock(&state->demod_lock);
79fcce32
PB
1804 return ret;
1805
dd316c6b 1806}
dd316c6b 1807EXPORT_SYMBOL(dib9000_fw_pid_filter_ctrl);
b4d6046e 1808
dd316c6b
OG
1809int dib9000_fw_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff)
1810{
1811 struct dib9000_state *state = fe->demodulator_priv;
79fcce32
PB
1812 int ret;
1813
1814 if (state->pid_ctrl_index != -2) {
1815 /* postpone the pid filtering cmd */
3dd72262 1816 dprintk("pid filter postpone\n");
79fcce32
PB
1817 if (state->pid_ctrl_index < 9) {
1818 state->pid_ctrl_index++;
1819 state->pid_ctrl[state->pid_ctrl_index].cmd = DIB9000_PID_FILTER;
1820 state->pid_ctrl[state->pid_ctrl_index].id = id;
1821 state->pid_ctrl[state->pid_ctrl_index].pid = pid;
1822 state->pid_ctrl[state->pid_ctrl_index].onoff = onoff;
1823 } else
3dd72262 1824 dprintk("can not add any more pid ctrl cmd\n");
79fcce32
PB
1825 return 0;
1826 }
1827
1eaef48b 1828 if (mutex_lock_interruptible(&state->demod_lock) < 0) {
3dd72262 1829 dprintk("could not get the lock\n");
f3033aec
AK
1830 return -EINTR;
1831 }
3dd72262 1832 dprintk("Index %x, PID %d, OnOff %d\n", id, pid, onoff);
79fcce32
PB
1833 ret = dib9000_write_word(state, 300 + 1 + id,
1834 onoff ? (1 << 13) | pid : 0);
1eaef48b 1835 mutex_unlock(&state->demod_lock);
79fcce32 1836 return ret;
dd316c6b 1837}
dd316c6b
OG
1838EXPORT_SYMBOL(dib9000_fw_pid_filter);
1839
1840int dib9000_firmware_post_pll_init(struct dvb_frontend *fe)
1841{
1842 struct dib9000_state *state = fe->demodulator_priv;
1843 return dib9000_fw_init(state);
1844}
dd316c6b
OG
1845EXPORT_SYMBOL(dib9000_firmware_post_pll_init);
1846
1847static void dib9000_release(struct dvb_frontend *demod)
1848{
1849 struct dib9000_state *st = demod->demodulator_priv;
1850 u8 index_frontend;
1851
b4d6046e 1852 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (st->fe[index_frontend] != NULL); index_frontend++)
dd316c6b
OG
1853 dvb_frontend_detach(st->fe[index_frontend]);
1854
dd316c6b
OG
1855 dibx000_exit_i2c_master(&st->i2c_master);
1856
1857 i2c_del_adapter(&st->tuner_adap);
1858 i2c_del_adapter(&st->component_bus);
1859 kfree(st->fe[0]);
1860 kfree(st);
1861}
1862
1863static int dib9000_wakeup(struct dvb_frontend *fe)
1864{
1865 return 0;
1866}
1867
1868static int dib9000_sleep(struct dvb_frontend *fe)
1869{
1870 struct dib9000_state *state = fe->demodulator_priv;
1871 u8 index_frontend;
79fcce32 1872 int ret = 0;
dd316c6b 1873
1eaef48b 1874 if (mutex_lock_interruptible(&state->demod_lock) < 0) {
3dd72262 1875 dprintk("could not get the lock\n");
f3033aec
AK
1876 return -EINTR;
1877 }
b4d6046e 1878 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
dd316c6b
OG
1879 ret = state->fe[index_frontend]->ops.sleep(state->fe[index_frontend]);
1880 if (ret < 0)
79fcce32 1881 goto error;
dd316c6b 1882 }
79fcce32
PB
1883 ret = dib9000_mbx_send(state, OUT_MSG_FE_SLEEP, NULL, 0);
1884
1885error:
1eaef48b 1886 mutex_unlock(&state->demod_lock);
79fcce32 1887 return ret;
dd316c6b
OG
1888}
1889
1890static int dib9000_fe_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings *tune)
1891{
1892 tune->min_delay_ms = 1000;
1893 return 0;
1894}
1895
7e3e68bc
MCC
1896static int dib9000_get_frontend(struct dvb_frontend *fe,
1897 struct dtv_frontend_properties *c)
dd316c6b
OG
1898{
1899 struct dib9000_state *state = fe->demodulator_priv;
1900 u8 index_frontend, sub_index_frontend;
0df289a2 1901 enum fe_status stat;
79fcce32
PB
1902 int ret = 0;
1903
f3033aec 1904 if (state->get_frontend_internal == 0) {
1eaef48b 1905 if (mutex_lock_interruptible(&state->demod_lock) < 0) {
3dd72262 1906 dprintk("could not get the lock\n");
f3033aec
AK
1907 return -EINTR;
1908 }
1909 }
dd316c6b 1910
b4d6046e 1911 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
dd316c6b
OG
1912 state->fe[index_frontend]->ops.read_status(state->fe[index_frontend], &stat);
1913 if (stat & FE_HAS_SYNC) {
3dd72262 1914 dprintk("TPS lock on the slave%i\n", index_frontend);
dd316c6b
OG
1915
1916 /* synchronize the cache with the other frontends */
7e3e68bc 1917 state->fe[index_frontend]->ops.get_frontend(state->fe[index_frontend], c);
b4d6046e
OG
1918 for (sub_index_frontend = 0; (sub_index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[sub_index_frontend] != NULL);
1919 sub_index_frontend++) {
dd316c6b 1920 if (sub_index_frontend != index_frontend) {
b4d6046e
OG
1921 state->fe[sub_index_frontend]->dtv_property_cache.modulation =
1922 state->fe[index_frontend]->dtv_property_cache.modulation;
1923 state->fe[sub_index_frontend]->dtv_property_cache.inversion =
1924 state->fe[index_frontend]->dtv_property_cache.inversion;
1925 state->fe[sub_index_frontend]->dtv_property_cache.transmission_mode =
1926 state->fe[index_frontend]->dtv_property_cache.transmission_mode;
1927 state->fe[sub_index_frontend]->dtv_property_cache.guard_interval =
1928 state->fe[index_frontend]->dtv_property_cache.guard_interval;
1929 state->fe[sub_index_frontend]->dtv_property_cache.hierarchy =
1930 state->fe[index_frontend]->dtv_property_cache.hierarchy;
1931 state->fe[sub_index_frontend]->dtv_property_cache.code_rate_HP =
1932 state->fe[index_frontend]->dtv_property_cache.code_rate_HP;
1933 state->fe[sub_index_frontend]->dtv_property_cache.code_rate_LP =
1934 state->fe[index_frontend]->dtv_property_cache.code_rate_LP;
1935 state->fe[sub_index_frontend]->dtv_property_cache.rolloff =
1936 state->fe[index_frontend]->dtv_property_cache.rolloff;
dd316c6b
OG
1937 }
1938 }
79fcce32
PB
1939 ret = 0;
1940 goto return_value;
dd316c6b
OG
1941 }
1942 }
1943
1944 /* get the channel from master chip */
759e236c 1945 ret = dib9000_fw_get_channel(fe);
dd316c6b 1946 if (ret != 0)
79fcce32 1947 goto return_value;
dd316c6b
OG
1948
1949 /* synchronize the cache with the other frontends */
b4d6046e 1950 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
7e3e68bc
MCC
1951 state->fe[index_frontend]->dtv_property_cache.inversion = c->inversion;
1952 state->fe[index_frontend]->dtv_property_cache.transmission_mode = c->transmission_mode;
1953 state->fe[index_frontend]->dtv_property_cache.guard_interval = c->guard_interval;
1954 state->fe[index_frontend]->dtv_property_cache.modulation = c->modulation;
1955 state->fe[index_frontend]->dtv_property_cache.hierarchy = c->hierarchy;
1956 state->fe[index_frontend]->dtv_property_cache.code_rate_HP = c->code_rate_HP;
1957 state->fe[index_frontend]->dtv_property_cache.code_rate_LP = c->code_rate_LP;
1958 state->fe[index_frontend]->dtv_property_cache.rolloff = c->rolloff;
dd316c6b 1959 }
79fcce32 1960 ret = 0;
dd316c6b 1961
79fcce32
PB
1962return_value:
1963 if (state->get_frontend_internal == 0)
1eaef48b 1964 mutex_unlock(&state->demod_lock);
79fcce32 1965 return ret;
dd316c6b
OG
1966}
1967
1968static int dib9000_set_tune_state(struct dvb_frontend *fe, enum frontend_tune_state tune_state)
1969{
1970 struct dib9000_state *state = fe->demodulator_priv;
1971 state->tune_state = tune_state;
1972 if (tune_state == CT_DEMOD_START)
1973 state->status = FE_STATUS_TUNE_PENDING;
1974
1975 return 0;
1976}
1977
1978static u32 dib9000_get_status(struct dvb_frontend *fe)
1979{
1980 struct dib9000_state *state = fe->demodulator_priv;
1981 return state->status;
1982}
1983
1984static int dib9000_set_channel_status(struct dvb_frontend *fe, struct dvb_frontend_parametersContext *channel_status)
1985{
1986 struct dib9000_state *state = fe->demodulator_priv;
1987
1988 memcpy(&state->channel_status, channel_status, sizeof(struct dvb_frontend_parametersContext));
1989 return 0;
1990}
1991
9e9c5bf7 1992static int dib9000_set_frontend(struct dvb_frontend *fe)
dd316c6b
OG
1993{
1994 struct dib9000_state *state = fe->demodulator_priv;
1995 int sleep_time, sleep_time_slave;
1996 u32 frontend_status;
1997 u8 nbr_pending, exit_condition, index_frontend, index_frontend_success;
1998 struct dvb_frontend_parametersContext channel_status;
1999
2000 /* check that the correct parameters are set */
2001 if (state->fe[0]->dtv_property_cache.frequency == 0) {
3dd72262 2002 dprintk("dib9000: must specify frequency\n");
dd316c6b
OG
2003 return 0;
2004 }
2005
2006 if (state->fe[0]->dtv_property_cache.bandwidth_hz == 0) {
3dd72262 2007 dprintk("dib9000: must specify bandwidth\n");
dd316c6b
OG
2008 return 0;
2009 }
79fcce32
PB
2010
2011 state->pid_ctrl_index = -1; /* postpone the pid filtering cmd */
1eaef48b 2012 if (mutex_lock_interruptible(&state->demod_lock) < 0) {
3dd72262 2013 dprintk("could not get the lock\n");
f3033aec
AK
2014 return 0;
2015 }
79fcce32 2016
dd316c6b
OG
2017 fe->dtv_property_cache.delivery_system = SYS_DVBT;
2018
2019 /* set the master status */
9e9c5bf7
MCC
2020 if (state->fe[0]->dtv_property_cache.transmission_mode == TRANSMISSION_MODE_AUTO ||
2021 state->fe[0]->dtv_property_cache.guard_interval == GUARD_INTERVAL_AUTO ||
2022 state->fe[0]->dtv_property_cache.modulation == QAM_AUTO ||
2023 state->fe[0]->dtv_property_cache.code_rate_HP == FEC_AUTO) {
dd316c6b
OG
2024 /* no channel specified, autosearch the channel */
2025 state->channel_status.status = CHANNEL_STATUS_PARAMETERS_UNKNOWN;
2026 } else
2027 state->channel_status.status = CHANNEL_STATUS_PARAMETERS_SET;
2028
2029 /* set mode and status for the different frontends */
b4d6046e 2030 for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
dd316c6b
OG
2031 dib9000_fw_set_diversity_in(state->fe[index_frontend], 1);
2032
2033 /* synchronization of the cache */
2034 memcpy(&state->fe[index_frontend]->dtv_property_cache, &fe->dtv_property_cache, sizeof(struct dtv_frontend_properties));
2035
2036 state->fe[index_frontend]->dtv_property_cache.delivery_system = SYS_DVBT;
2037 dib9000_fw_set_output_mode(state->fe[index_frontend], OUTMODE_HIGH_Z);
2038
2039 dib9000_set_channel_status(state->fe[index_frontend], &state->channel_status);
2040 dib9000_set_tune_state(state->fe[index_frontend], CT_DEMOD_START);
2041 }
2042
2043 /* actual tune */
b4d6046e 2044 exit_condition = 0; /* 0: tune pending; 1: tune failed; 2:tune success */
dd316c6b
OG
2045 index_frontend_success = 0;
2046 do {
f20b12ec 2047 sleep_time = dib9000_fw_tune(state->fe[0]);
b4d6046e 2048 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
f20b12ec 2049 sleep_time_slave = dib9000_fw_tune(state->fe[index_frontend]);
dd316c6b
OG
2050 if (sleep_time == FE_CALLBACK_TIME_NEVER)
2051 sleep_time = sleep_time_slave;
2052 else if ((sleep_time_slave != FE_CALLBACK_TIME_NEVER) && (sleep_time_slave > sleep_time))
2053 sleep_time = sleep_time_slave;
2054 }
2055 if (sleep_time != FE_CALLBACK_TIME_NEVER)
2056 msleep(sleep_time / 10);
2057 else
2058 break;
2059
2060 nbr_pending = 0;
2061 exit_condition = 0;
2062 index_frontend_success = 0;
b4d6046e 2063 for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
dd316c6b
OG
2064 frontend_status = -dib9000_get_status(state->fe[index_frontend]);
2065 if (frontend_status > -FE_STATUS_TUNE_PENDING) {
b4d6046e 2066 exit_condition = 2; /* tune success */
dd316c6b
OG
2067 index_frontend_success = index_frontend;
2068 break;
2069 }
2070 if (frontend_status == -FE_STATUS_TUNE_PENDING)
b4d6046e 2071 nbr_pending++; /* some frontends are still tuning */
dd316c6b
OG
2072 }
2073 if ((exit_condition != 2) && (nbr_pending == 0))
b4d6046e 2074 exit_condition = 1; /* if all tune are done and no success, exit: tune failed */
dd316c6b
OG
2075
2076 } while (exit_condition == 0);
2077
2078 /* check the tune result */
b4d6046e 2079 if (exit_condition == 1) { /* tune failed */
3dd72262 2080 dprintk("tune failed\n");
1eaef48b 2081 mutex_unlock(&state->demod_lock);
79fcce32
PB
2082 /* tune failed; put all the pid filtering cmd to junk */
2083 state->pid_ctrl_index = -1;
dd316c6b
OG
2084 return 0;
2085 }
2086
3dd72262 2087 dprintk("tune success on frontend%i\n", index_frontend_success);
dd316c6b
OG
2088
2089 /* synchronize all the channel cache */
79fcce32 2090 state->get_frontend_internal = 1;
7e3e68bc 2091 dib9000_get_frontend(state->fe[0], &state->fe[0]->dtv_property_cache);
79fcce32 2092 state->get_frontend_internal = 0;
dd316c6b
OG
2093
2094 /* retune the other frontends with the found channel */
2095 channel_status.status = CHANNEL_STATUS_PARAMETERS_SET;
b4d6046e 2096 for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
dd316c6b
OG
2097 /* only retune the frontends which was not tuned success */
2098 if (index_frontend != index_frontend_success) {
2099 dib9000_set_channel_status(state->fe[index_frontend], &channel_status);
2100 dib9000_set_tune_state(state->fe[index_frontend], CT_DEMOD_START);
2101 }
2102 }
2103 do {
2104 sleep_time = FE_CALLBACK_TIME_NEVER;
b4d6046e 2105 for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
dd316c6b 2106 if (index_frontend != index_frontend_success) {
f20b12ec 2107 sleep_time_slave = dib9000_fw_tune(state->fe[index_frontend]);
dd316c6b
OG
2108 if (sleep_time == FE_CALLBACK_TIME_NEVER)
2109 sleep_time = sleep_time_slave;
2110 else if ((sleep_time_slave != FE_CALLBACK_TIME_NEVER) && (sleep_time_slave > sleep_time))
2111 sleep_time = sleep_time_slave;
2112 }
2113 }
2114 if (sleep_time != FE_CALLBACK_TIME_NEVER)
2115 msleep(sleep_time / 10);
2116 else
2117 break;
2118
2119 nbr_pending = 0;
b4d6046e 2120 for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
dd316c6b
OG
2121 if (index_frontend != index_frontend_success) {
2122 frontend_status = -dib9000_get_status(state->fe[index_frontend]);
2123 if ((index_frontend != index_frontend_success) && (frontend_status == -FE_STATUS_TUNE_PENDING))
b4d6046e 2124 nbr_pending++; /* some frontends are still tuning */
dd316c6b
OG
2125 }
2126 }
2127 } while (nbr_pending != 0);
2128
2129 /* set the output mode */
2130 dib9000_fw_set_output_mode(state->fe[0], state->chip.d9.cfg.output_mode);
b4d6046e 2131 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++)
dd316c6b
OG
2132 dib9000_fw_set_output_mode(state->fe[index_frontend], OUTMODE_DIVERSITY);
2133
2134 /* turn off the diversity for the last frontend */
b4d6046e 2135 dib9000_fw_set_diversity_in(state->fe[index_frontend - 1], 0);
dd316c6b 2136
1eaef48b 2137 mutex_unlock(&state->demod_lock);
79fcce32
PB
2138 if (state->pid_ctrl_index >= 0) {
2139 u8 index_pid_filter_cmd;
2140 u8 pid_ctrl_index = state->pid_ctrl_index;
2141
2142 state->pid_ctrl_index = -2;
2143 for (index_pid_filter_cmd = 0;
2144 index_pid_filter_cmd <= pid_ctrl_index;
2145 index_pid_filter_cmd++) {
2146 if (state->pid_ctrl[index_pid_filter_cmd].cmd == DIB9000_PID_FILTER_CTRL)
2147 dib9000_fw_pid_filter_ctrl(state->fe[0],
2148 state->pid_ctrl[index_pid_filter_cmd].onoff);
2149 else if (state->pid_ctrl[index_pid_filter_cmd].cmd == DIB9000_PID_FILTER)
2150 dib9000_fw_pid_filter(state->fe[0],
2151 state->pid_ctrl[index_pid_filter_cmd].id,
2152 state->pid_ctrl[index_pid_filter_cmd].pid,
2153 state->pid_ctrl[index_pid_filter_cmd].onoff);
2154 }
2155 }
2156 /* do not postpone any more the pid filtering */
2157 state->pid_ctrl_index = -2;
2158
dd316c6b
OG
2159 return 0;
2160}
2161
2162static u16 dib9000_read_lock(struct dvb_frontend *fe)
2163{
2164 struct dib9000_state *state = fe->demodulator_priv;
2165
2166 return dib9000_read_word(state, 535);
2167}
2168
0df289a2 2169static int dib9000_read_status(struct dvb_frontend *fe, enum fe_status *stat)
dd316c6b
OG
2170{
2171 struct dib9000_state *state = fe->demodulator_priv;
2172 u8 index_frontend;
2173 u16 lock = 0, lock_slave = 0;
2174
1eaef48b 2175 if (mutex_lock_interruptible(&state->demod_lock) < 0) {
3dd72262 2176 dprintk("could not get the lock\n");
f3033aec
AK
2177 return -EINTR;
2178 }
b4d6046e 2179 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++)
dd316c6b
OG
2180 lock_slave |= dib9000_read_lock(state->fe[index_frontend]);
2181
2182 lock = dib9000_read_word(state, 535);
2183
2184 *stat = 0;
2185
2186 if ((lock & 0x8000) || (lock_slave & 0x8000))
2187 *stat |= FE_HAS_SIGNAL;
2188 if ((lock & 0x3000) || (lock_slave & 0x3000))
2189 *stat |= FE_HAS_CARRIER;
2190 if ((lock & 0x0100) || (lock_slave & 0x0100))
2191 *stat |= FE_HAS_VITERBI;
2192 if (((lock & 0x0038) == 0x38) || ((lock_slave & 0x0038) == 0x38))
2193 *stat |= FE_HAS_SYNC;
2194 if ((lock & 0x0008) || (lock_slave & 0x0008))
2195 *stat |= FE_HAS_LOCK;
2196
1eaef48b 2197 mutex_unlock(&state->demod_lock);
79fcce32 2198
dd316c6b
OG
2199 return 0;
2200}
2201
2202static int dib9000_read_ber(struct dvb_frontend *fe, u32 * ber)
2203{
2204 struct dib9000_state *state = fe->demodulator_priv;
5a0deeed 2205 u16 *c;
79fcce32 2206 int ret = 0;
dd316c6b 2207
1eaef48b 2208 if (mutex_lock_interruptible(&state->demod_lock) < 0) {
3dd72262 2209 dprintk("could not get the lock\n");
f3033aec
AK
2210 return -EINTR;
2211 }
1eaef48b 2212 if (mutex_lock_interruptible(&state->platform.risc.mem_mbx_lock) < 0) {
3dd72262 2213 dprintk("could not get the lock\n");
f3033aec
AK
2214 ret = -EINTR;
2215 goto error;
2216 }
79fcce32 2217 if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0) {
1eaef48b 2218 mutex_unlock(&state->platform.risc.mem_mbx_lock);
79fcce32
PB
2219 ret = -EIO;
2220 goto error;
2221 }
5a0deeed
OG
2222 dib9000_risc_mem_read(state, FE_MM_R_FE_MONITOR,
2223 state->i2c_read_buffer, 16 * 2);
1eaef48b 2224 mutex_unlock(&state->platform.risc.mem_mbx_lock);
dd316c6b 2225
5a0deeed
OG
2226 c = (u16 *)state->i2c_read_buffer;
2227
dd316c6b 2228 *ber = c[10] << 16 | c[11];
79fcce32
PB
2229
2230error:
1eaef48b 2231 mutex_unlock(&state->demod_lock);
79fcce32 2232 return ret;
dd316c6b
OG
2233}
2234
2235static int dib9000_read_signal_strength(struct dvb_frontend *fe, u16 * strength)
2236{
2237 struct dib9000_state *state = fe->demodulator_priv;
2238 u8 index_frontend;
5a0deeed 2239 u16 *c = (u16 *)state->i2c_read_buffer;
dd316c6b 2240 u16 val;
79fcce32 2241 int ret = 0;
dd316c6b 2242
1eaef48b 2243 if (mutex_lock_interruptible(&state->demod_lock) < 0) {
3dd72262 2244 dprintk("could not get the lock\n");
f3033aec
AK
2245 return -EINTR;
2246 }
dd316c6b 2247 *strength = 0;
b4d6046e 2248 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
dd316c6b
OG
2249 state->fe[index_frontend]->ops.read_signal_strength(state->fe[index_frontend], &val);
2250 if (val > 65535 - *strength)
2251 *strength = 65535;
2252 else
2253 *strength += val;
2254 }
2255
1eaef48b 2256 if (mutex_lock_interruptible(&state->platform.risc.mem_mbx_lock) < 0) {
3dd72262 2257 dprintk("could not get the lock\n");
f3033aec
AK
2258 ret = -EINTR;
2259 goto error;
2260 }
79fcce32 2261 if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0) {
1eaef48b 2262 mutex_unlock(&state->platform.risc.mem_mbx_lock);
79fcce32
PB
2263 ret = -EIO;
2264 goto error;
2265 }
5a0deeed 2266 dib9000_risc_mem_read(state, FE_MM_R_FE_MONITOR, (u8 *) c, 16 * 2);
1eaef48b 2267 mutex_unlock(&state->platform.risc.mem_mbx_lock);
dd316c6b
OG
2268
2269 val = 65535 - c[4];
2270 if (val > 65535 - *strength)
2271 *strength = 65535;
2272 else
2273 *strength += val;
79fcce32
PB
2274
2275error:
1eaef48b 2276 mutex_unlock(&state->demod_lock);
79fcce32 2277 return ret;
dd316c6b
OG
2278}
2279
2280static u32 dib9000_get_snr(struct dvb_frontend *fe)
2281{
2282 struct dib9000_state *state = fe->demodulator_priv;
5a0deeed 2283 u16 *c = (u16 *)state->i2c_read_buffer;
dd316c6b
OG
2284 u32 n, s, exp;
2285 u16 val;
2286
1eaef48b 2287 if (mutex_lock_interruptible(&state->platform.risc.mem_mbx_lock) < 0) {
3dd72262 2288 dprintk("could not get the lock\n");
f3033aec
AK
2289 return 0;
2290 }
9bb24a7e 2291 if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0) {
1eaef48b 2292 mutex_unlock(&state->platform.risc.mem_mbx_lock);
f3033aec 2293 return 0;
9bb24a7e 2294 }
5a0deeed 2295 dib9000_risc_mem_read(state, FE_MM_R_FE_MONITOR, (u8 *) c, 16 * 2);
1eaef48b 2296 mutex_unlock(&state->platform.risc.mem_mbx_lock);
dd316c6b
OG
2297
2298 val = c[7];
2299 n = (val >> 4) & 0xff;
2300 exp = ((val & 0xf) << 2);
2301 val = c[8];
2302 exp += ((val >> 14) & 0x3);
2303 if ((exp & 0x20) != 0)
2304 exp -= 0x40;
2305 n <<= exp + 16;
2306
2307 s = (val >> 6) & 0xFF;
2308 exp = (val & 0x3F);
2309 if ((exp & 0x20) != 0)
2310 exp -= 0x40;
2311 s <<= exp + 16;
2312
2313 if (n > 0) {
2314 u32 t = (s / n) << 16;
2315 return t + ((s << 16) - n * t) / n;
2316 }
2317 return 0xffffffff;
2318}
2319
2320static int dib9000_read_snr(struct dvb_frontend *fe, u16 * snr)
2321{
2322 struct dib9000_state *state = fe->demodulator_priv;
2323 u8 index_frontend;
2324 u32 snr_master;
2325
1eaef48b 2326 if (mutex_lock_interruptible(&state->demod_lock) < 0) {
3dd72262 2327 dprintk("could not get the lock\n");
f3033aec
AK
2328 return -EINTR;
2329 }
dd316c6b 2330 snr_master = dib9000_get_snr(fe);
b4d6046e 2331 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++)
dd316c6b
OG
2332 snr_master += dib9000_get_snr(state->fe[index_frontend]);
2333
2334 if ((snr_master >> 16) != 0) {
2335 snr_master = 10 * intlog10(snr_master >> 16);
2336 *snr = snr_master / ((1 << 24) / 10);
2337 } else
2338 *snr = 0;
2339
1eaef48b 2340 mutex_unlock(&state->demod_lock);
79fcce32 2341
dd316c6b
OG
2342 return 0;
2343}
2344
2345static int dib9000_read_unc_blocks(struct dvb_frontend *fe, u32 * unc)
2346{
2347 struct dib9000_state *state = fe->demodulator_priv;
5a0deeed 2348 u16 *c = (u16 *)state->i2c_read_buffer;
79fcce32 2349 int ret = 0;
dd316c6b 2350
1eaef48b 2351 if (mutex_lock_interruptible(&state->demod_lock) < 0) {
3dd72262 2352 dprintk("could not get the lock\n");
f3033aec
AK
2353 return -EINTR;
2354 }
1eaef48b 2355 if (mutex_lock_interruptible(&state->platform.risc.mem_mbx_lock) < 0) {
3dd72262 2356 dprintk("could not get the lock\n");
f3033aec
AK
2357 ret = -EINTR;
2358 goto error;
2359 }
79fcce32 2360 if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0) {
1eaef48b 2361 mutex_unlock(&state->platform.risc.mem_mbx_lock);
79fcce32
PB
2362 ret = -EIO;
2363 goto error;
2364 }
5a0deeed 2365 dib9000_risc_mem_read(state, FE_MM_R_FE_MONITOR, (u8 *) c, 16 * 2);
1eaef48b 2366 mutex_unlock(&state->platform.risc.mem_mbx_lock);
dd316c6b
OG
2367
2368 *unc = c[12];
79fcce32
PB
2369
2370error:
1eaef48b 2371 mutex_unlock(&state->demod_lock);
79fcce32 2372 return ret;
dd316c6b
OG
2373}
2374
2375int dib9000_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 default_addr, u8 first_addr)
2376{
5a0deeed 2377 int k = 0, ret = 0;
dd316c6b
OG
2378 u8 new_addr = 0;
2379 struct i2c_device client = {.i2c_adap = i2c };
2380
6396bb22 2381 client.i2c_write_buffer = kzalloc(4, GFP_KERNEL);
5a0deeed 2382 if (!client.i2c_write_buffer) {
3dd72262 2383 dprintk("%s: not enough memory\n", __func__);
5a0deeed
OG
2384 return -ENOMEM;
2385 }
6396bb22 2386 client.i2c_read_buffer = kzalloc(4, GFP_KERNEL);
5a0deeed 2387 if (!client.i2c_read_buffer) {
3dd72262 2388 dprintk("%s: not enough memory\n", __func__);
5a0deeed
OG
2389 ret = -ENOMEM;
2390 goto error_memory;
2391 }
2392
dd316c6b 2393 client.i2c_addr = default_addr + 16;
b4d6046e 2394 dib9000_i2c_write16(&client, 1796, 0x0);
dd316c6b
OG
2395
2396 for (k = no_of_demods - 1; k >= 0; k--) {
2397 /* designated i2c address */
2398 new_addr = first_addr + (k << 1);
2399 client.i2c_addr = default_addr;
2400
2401 dib9000_i2c_write16(&client, 1817, 3);
2402 dib9000_i2c_write16(&client, 1796, 0);
2403 dib9000_i2c_write16(&client, 1227, 1);
2404 dib9000_i2c_write16(&client, 1227, 0);
2405
2406 client.i2c_addr = new_addr;
2407 dib9000_i2c_write16(&client, 1817, 3);
2408 dib9000_i2c_write16(&client, 1796, 0);
2409 dib9000_i2c_write16(&client, 1227, 1);
2410 dib9000_i2c_write16(&client, 1227, 0);
2411
2412 if (dib9000_identify(&client) == 0) {
2413 client.i2c_addr = default_addr;
2414 if (dib9000_identify(&client) == 0) {
3dd72262 2415 dprintk("DiB9000 #%d: not identified\n", k);
5a0deeed
OG
2416 ret = -EIO;
2417 goto error;
dd316c6b
OG
2418 }
2419 }
2420
2421 dib9000_i2c_write16(&client, 1795, (1 << 10) | (4 << 6));
2422 dib9000_i2c_write16(&client, 1794, (new_addr << 2) | 2);
2423
3dd72262 2424 dprintk("IC %d initialized (to i2c_address 0x%x)\n", k, new_addr);
dd316c6b
OG
2425 }
2426
2427 for (k = 0; k < no_of_demods; k++) {
2428 new_addr = first_addr | (k << 1);
2429 client.i2c_addr = new_addr;
2430
2431 dib9000_i2c_write16(&client, 1794, (new_addr << 2));
2432 dib9000_i2c_write16(&client, 1795, 0);
2433 }
2434
5a0deeed
OG
2435error:
2436 kfree(client.i2c_read_buffer);
2437error_memory:
2438 kfree(client.i2c_write_buffer);
2439
2440 return ret;
dd316c6b 2441}
dd316c6b
OG
2442EXPORT_SYMBOL(dib9000_i2c_enumeration);
2443
2444int dib9000_set_slave_frontend(struct dvb_frontend *fe, struct dvb_frontend *fe_slave)
2445{
2446 struct dib9000_state *state = fe->demodulator_priv;
2447 u8 index_frontend = 1;
2448
2449 while ((index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL))
2450 index_frontend++;
2451 if (index_frontend < MAX_NUMBER_OF_FRONTENDS) {
3dd72262 2452 dprintk("set slave fe %p to index %i\n", fe_slave, index_frontend);
dd316c6b
OG
2453 state->fe[index_frontend] = fe_slave;
2454 return 0;
2455 }
2456
3dd72262 2457 dprintk("too many slave frontend\n");
dd316c6b
OG
2458 return -ENOMEM;
2459}
2460EXPORT_SYMBOL(dib9000_set_slave_frontend);
2461
b4d6046e 2462struct dvb_frontend *dib9000_get_slave_frontend(struct dvb_frontend *fe, int slave_index)
dd316c6b
OG
2463{
2464 struct dib9000_state *state = fe->demodulator_priv;
2465
2466 if (slave_index >= MAX_NUMBER_OF_FRONTENDS)
2467 return NULL;
2468 return state->fe[slave_index];
2469}
2470EXPORT_SYMBOL(dib9000_get_slave_frontend);
2471
bd336e63 2472static const struct dvb_frontend_ops dib9000_ops;
dd316c6b
OG
2473struct dvb_frontend *dib9000_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, const struct dib9000_config *cfg)
2474{
2475 struct dvb_frontend *fe;
2476 struct dib9000_state *st;
2477 st = kzalloc(sizeof(struct dib9000_state), GFP_KERNEL);
2478 if (st == NULL)
2479 return NULL;
2480 fe = kzalloc(sizeof(struct dvb_frontend), GFP_KERNEL);
451a51b2
JJ
2481 if (fe == NULL) {
2482 kfree(st);
dd316c6b 2483 return NULL;
451a51b2 2484 }
dd316c6b
OG
2485
2486 memcpy(&st->chip.d9.cfg, cfg, sizeof(struct dib9000_config));
2487 st->i2c.i2c_adap = i2c_adap;
2488 st->i2c.i2c_addr = i2c_addr;
5a0deeed
OG
2489 st->i2c.i2c_write_buffer = st->i2c_write_buffer;
2490 st->i2c.i2c_read_buffer = st->i2c_read_buffer;
dd316c6b
OG
2491
2492 st->gpio_dir = DIB9000_GPIO_DEFAULT_DIRECTIONS;
2493 st->gpio_val = DIB9000_GPIO_DEFAULT_VALUES;
2494 st->gpio_pwm_pos = DIB9000_GPIO_DEFAULT_PWM_POS;
2495
1eaef48b
AK
2496 mutex_init(&st->platform.risc.mbx_if_lock);
2497 mutex_init(&st->platform.risc.mbx_lock);
2498 mutex_init(&st->platform.risc.mem_lock);
2499 mutex_init(&st->platform.risc.mem_mbx_lock);
2500 mutex_init(&st->demod_lock);
79fcce32
PB
2501 st->get_frontend_internal = 0;
2502
2503 st->pid_ctrl_index = -2;
dd316c6b
OG
2504
2505 st->fe[0] = fe;
2506 fe->demodulator_priv = st;
2507 memcpy(&st->fe[0]->ops, &dib9000_ops, sizeof(struct dvb_frontend_ops));
2508
2509 /* Ensure the output mode remains at the previous default if it's
2510 * not specifically set by the caller.
2511 */
2512 if ((st->chip.d9.cfg.output_mode != OUTMODE_MPEG2_SERIAL) && (st->chip.d9.cfg.output_mode != OUTMODE_MPEG2_PAR_GATED_CLK))
2513 st->chip.d9.cfg.output_mode = OUTMODE_MPEG2_FIFO;
2514
2515 if (dib9000_identify(&st->i2c) == 0)
2516 goto error;
2517
2518 dibx000_init_i2c_master(&st->i2c_master, DIB7000MC, st->i2c.i2c_adap, st->i2c.i2c_addr);
2519
2520 st->tuner_adap.dev.parent = i2c_adap->dev.parent;
85709cbf
MCC
2521 strscpy(st->tuner_adap.name, "DIB9000_FW TUNER ACCESS",
2522 sizeof(st->tuner_adap.name));
dd316c6b
OG
2523 st->tuner_adap.algo = &dib9000_tuner_algo;
2524 st->tuner_adap.algo_data = NULL;
2525 i2c_set_adapdata(&st->tuner_adap, st);
2526 if (i2c_add_adapter(&st->tuner_adap) < 0)
2527 goto error;
2528
2529 st->component_bus.dev.parent = i2c_adap->dev.parent;
85709cbf
MCC
2530 strscpy(st->component_bus.name, "DIB9000_FW COMPONENT BUS ACCESS",
2531 sizeof(st->component_bus.name));
dd316c6b
OG
2532 st->component_bus.algo = &dib9000_component_bus_algo;
2533 st->component_bus.algo_data = NULL;
2534 st->component_bus_speed = 340;
2535 i2c_set_adapdata(&st->component_bus, st);
2536 if (i2c_add_adapter(&st->component_bus) < 0)
2537 goto component_bus_add_error;
2538
2539 dib9000_fw_reset(fe);
2540
2541 return fe;
2542
b4d6046e 2543component_bus_add_error:
dd316c6b 2544 i2c_del_adapter(&st->tuner_adap);
b4d6046e 2545error:
dd316c6b
OG
2546 kfree(st);
2547 return NULL;
2548}
dd316c6b
OG
2549EXPORT_SYMBOL(dib9000_attach);
2550
bd336e63 2551static const struct dvb_frontend_ops dib9000_ops = {
9e9c5bf7 2552 .delsys = { SYS_DVBT },
dd316c6b
OG
2553 .info = {
2554 .name = "DiBcom 9000",
f1b1eabf
MCC
2555 .frequency_min_hz = 44250 * kHz,
2556 .frequency_max_hz = 867250 * kHz,
2557 .frequency_stepsize_hz = 62500,
dd316c6b
OG
2558 .caps = FE_CAN_INVERSION_AUTO |
2559 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
2560 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
2561 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
2562 FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_RECOVER | FE_CAN_HIERARCHY_AUTO,
2563 },
2564
2565 .release = dib9000_release,
2566
2567 .init = dib9000_wakeup,
2568 .sleep = dib9000_sleep,
2569
9e9c5bf7 2570 .set_frontend = dib9000_set_frontend,
dd316c6b 2571 .get_tune_settings = dib9000_fe_get_tune_settings,
9e9c5bf7 2572 .get_frontend = dib9000_get_frontend,
dd316c6b
OG
2573
2574 .read_status = dib9000_read_status,
2575 .read_ber = dib9000_read_ber,
2576 .read_signal_strength = dib9000_read_signal_strength,
2577 .read_snr = dib9000_read_snr,
2578 .read_ucblocks = dib9000_read_unc_blocks,
2579};
2580
99e44da7
PB
2581MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@posteo.de>");
2582MODULE_AUTHOR("Olivier Grenie <olivier.grenie@parrot.com>");
dd316c6b
OG
2583MODULE_DESCRIPTION("Driver for the DiBcom 9000 COFDM demodulator");
2584MODULE_LICENSE("GPL");