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