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