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