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