11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 2b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher * Driver for DiBcom DiB3000MC/P-demodulator. 31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 4b6884a17fc70e979ef34e4b5560988b522bb50a0Patrick Boettcher * Copyright (C) 2004-7 DiBcom (http://www.dibcom.fr/) 51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de) 61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 7b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher * This code is partially based on the previous dib3000mc.c . 81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 9b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher * This program is free software; you can redistribute it and/or 101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * modify it under the terms of the GNU General Public License as 111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * published by the Free Software Foundation, version 2. 121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 13b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher 141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/kernel.h> 155a0e3ad6af8660be21ca98a971cd00f331318c05Tejun Heo#include <linux/slab.h> 16b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher#include <linux/i2c.h> 17b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher 18b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher#include "dvb_frontend.h" 19b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher 20b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher#include "dib3000mc.h" 21b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher 221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int debug; 231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmodule_param(debug, int, 0644); 24b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick BoettcherMODULE_PARM_DESC(debug, "turn on debugging (default: 0)"); 251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 268f6956c7f9fa72c502bde47df4122bd32d0b86d5Matt Doranstatic int buggy_sfn_workaround; 278f6956c7f9fa72c502bde47df4122bd32d0b86d5Matt Doranmodule_param(buggy_sfn_workaround, int, 0644); 288d99996b0942ff566c62602d83ac2c13521bbe40Patrick BoettcherMODULE_PARM_DESC(buggy_sfn_workaround, "Enable work-around for buggy SFNs (default: 0)"); 298f6956c7f9fa72c502bde47df4122bd32d0b86d5Matt Doran 30b6884a17fc70e979ef34e4b5560988b522bb50a0Patrick Boettcher#define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiB3000MC/P:"); printk(args); printk("\n"); } } while (0) 31b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher 32b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcherstruct dib3000mc_state { 33b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher struct dvb_frontend demod; 34b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher struct dib3000mc_config *cfg; 35b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher 36b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher u8 i2c_addr; 37b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher struct i2c_adapter *i2c_adap; 38b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher 39b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher struct dibx000_i2c_master i2c_master; 40b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher 4101b4bf31ce6ca6c1de31c773fa281a34fd98ff87Patrick Boettcher u32 timf; 4201b4bf31ce6ca6c1de31c773fa281a34fd98ff87Patrick Boettcher 4388ab898f6639ca5a14943a882fbd141afc81fe90Mauro Carvalho Chehab u32 current_bandwidth; 44b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher 45b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher u16 dev_id; 468f6956c7f9fa72c502bde47df4122bd32d0b86d5Matt Doran 478f6956c7f9fa72c502bde47df4122bd32d0b86d5Matt Doran u8 sfn_workaround_active :1; 48b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher}; 49b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher 50b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcherstatic u16 dib3000mc_read_word(struct dib3000mc_state *state, u16 reg) 51b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher{ 52b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher u8 wb[2] = { (reg >> 8) | 0x80, reg & 0xff }; 53b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher u8 rb[2]; 54b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher struct i2c_msg msg[2] = { 55b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher { .addr = state->i2c_addr >> 1, .flags = 0, .buf = wb, .len = 2 }, 56b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher { .addr = state->i2c_addr >> 1, .flags = I2C_M_RD, .buf = rb, .len = 2 }, 57b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher }; 58b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher 59b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher if (i2c_transfer(state->i2c_adap, msg, 2) != 2) 60b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher dprintk("i2c read error on %d\n",reg); 61b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher 62b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher return (rb[0] << 8) | rb[1]; 63b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher} 64b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher 65b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcherstatic int dib3000mc_write_word(struct dib3000mc_state *state, u16 reg, u16 val) 66b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher{ 67b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher u8 b[4] = { 68b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher (reg >> 8) & 0xff, reg & 0xff, 69b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher (val >> 8) & 0xff, val & 0xff, 70b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher }; 71b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher struct i2c_msg msg = { 72b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher .addr = state->i2c_addr >> 1, .flags = 0, .buf = b, .len = 4 73b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher }; 74b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher return i2c_transfer(state->i2c_adap, &msg, 1) != 1 ? -EREMOTEIO : 0; 75b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher} 76b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher 77b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcherstatic int dib3000mc_identify(struct dib3000mc_state *state) 781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 79b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher u16 value; 80b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher if ((value = dib3000mc_read_word(state, 1025)) != 0x01b3) { 81b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher dprintk("-E- DiB3000MC/P: wrong Vendor ID (read=0x%x)\n",value); 82b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher return -EREMOTEIO; 83b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher } 841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 85b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher value = dib3000mc_read_word(state, 1026); 86b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher if (value != 0x3001 && value != 0x3002) { 87b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher dprintk("-E- DiB3000MC/P: wrong Device ID (%x)\n",value); 88b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher return -EREMOTEIO; 891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 90b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher state->dev_id = value; 91b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher 92b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher dprintk("-I- found DiB3000MC/P: %x\n",state->dev_id); 93b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher 94b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher return 0; 95b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher} 96b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher 97b6884a17fc70e979ef34e4b5560988b522bb50a0Patrick Boettcherstatic int dib3000mc_set_timing(struct dib3000mc_state *state, s16 nfft, u32 bw, u8 update_offset) 98b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher{ 9901b4bf31ce6ca6c1de31c773fa281a34fd98ff87Patrick Boettcher u32 timf; 100b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher 10101b4bf31ce6ca6c1de31c773fa281a34fd98ff87Patrick Boettcher if (state->timf == 0) { 10201b4bf31ce6ca6c1de31c773fa281a34fd98ff87Patrick Boettcher timf = 1384402; // default value for 8MHz 10301b4bf31ce6ca6c1de31c773fa281a34fd98ff87Patrick Boettcher if (update_offset) 10401b4bf31ce6ca6c1de31c773fa281a34fd98ff87Patrick Boettcher msleep(200); // first time we do an update 1051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else 10601b4bf31ce6ca6c1de31c773fa281a34fd98ff87Patrick Boettcher timf = state->timf; 1071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 108b6884a17fc70e979ef34e4b5560988b522bb50a0Patrick Boettcher timf *= (bw / 1000); 1091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11001b4bf31ce6ca6c1de31c773fa281a34fd98ff87Patrick Boettcher if (update_offset) { 11101b4bf31ce6ca6c1de31c773fa281a34fd98ff87Patrick Boettcher s16 tim_offs = dib3000mc_read_word(state, 416); 11201b4bf31ce6ca6c1de31c773fa281a34fd98ff87Patrick Boettcher 11301b4bf31ce6ca6c1de31c773fa281a34fd98ff87Patrick Boettcher if (tim_offs & 0x2000) 11401b4bf31ce6ca6c1de31c773fa281a34fd98ff87Patrick Boettcher tim_offs -= 0x4000; 11501b4bf31ce6ca6c1de31c773fa281a34fd98ff87Patrick Boettcher 116b6884a17fc70e979ef34e4b5560988b522bb50a0Patrick Boettcher if (nfft == TRANSMISSION_MODE_2K) 11701b4bf31ce6ca6c1de31c773fa281a34fd98ff87Patrick Boettcher tim_offs *= 4; 11801b4bf31ce6ca6c1de31c773fa281a34fd98ff87Patrick Boettcher 11901b4bf31ce6ca6c1de31c773fa281a34fd98ff87Patrick Boettcher timf += tim_offs; 120b6884a17fc70e979ef34e4b5560988b522bb50a0Patrick Boettcher state->timf = timf / (bw / 1000); 12101b4bf31ce6ca6c1de31c773fa281a34fd98ff87Patrick Boettcher } 122b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher 12301b4bf31ce6ca6c1de31c773fa281a34fd98ff87Patrick Boettcher dprintk("timf: %d\n", timf); 1241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 125b6884a17fc70e979ef34e4b5560988b522bb50a0Patrick Boettcher dib3000mc_write_word(state, 23, (u16) (timf >> 16)); 126b6884a17fc70e979ef34e4b5560988b522bb50a0Patrick Boettcher dib3000mc_write_word(state, 24, (u16) (timf ) & 0xffff); 1271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 1291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13101b4bf31ce6ca6c1de31c773fa281a34fd98ff87Patrick Boettcherstatic int dib3000mc_setup_pwm_state(struct dib3000mc_state *state) 1321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 13301b4bf31ce6ca6c1de31c773fa281a34fd98ff87Patrick Boettcher u16 reg_51, reg_52 = state->cfg->agc->setup & 0xfefb; 134b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher if (state->cfg->pwm3_inversion) { 13501b4bf31ce6ca6c1de31c773fa281a34fd98ff87Patrick Boettcher reg_51 = (2 << 14) | (0 << 10) | (7 << 6) | (2 << 2) | (2 << 0); 13601b4bf31ce6ca6c1de31c773fa281a34fd98ff87Patrick Boettcher reg_52 |= (1 << 2); 1371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 13801b4bf31ce6ca6c1de31c773fa281a34fd98ff87Patrick Boettcher reg_51 = (2 << 14) | (4 << 10) | (7 << 6) | (2 << 2) | (2 << 0); 13901b4bf31ce6ca6c1de31c773fa281a34fd98ff87Patrick Boettcher reg_52 |= (1 << 8); 1401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 14101b4bf31ce6ca6c1de31c773fa281a34fd98ff87Patrick Boettcher dib3000mc_write_word(state, 51, reg_51); 14201b4bf31ce6ca6c1de31c773fa281a34fd98ff87Patrick Boettcher dib3000mc_write_word(state, 52, reg_52); 143b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher 144b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher if (state->cfg->use_pwm3) 145b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher dib3000mc_write_word(state, 245, (1 << 3) | (1 << 0)); 146b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher else 147b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher dib3000mc_write_word(state, 245, 0); 148b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher 149b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher dib3000mc_write_word(state, 1040, 0x3); 1501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 1511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 153b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcherstatic int dib3000mc_set_output_mode(struct dib3000mc_state *state, int mode) 1541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 155b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher int ret = 0; 156b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher u16 fifo_threshold = 1792; 157b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher u16 outreg = 0; 158b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher u16 outmode = 0; 159b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher u16 elecout = 1; 160fb6065bbd915f9cf6022d52e114f5078654834b5Patrick Boettcher u16 smo_reg = dib3000mc_read_word(state, 206) & 0x0010; /* keep the pid_parse bit */ 161b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher 162b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher dprintk("-I- Setting output mode for demod %p to %d\n", 163b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher &state->demod, mode); 164b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher 165b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher switch (mode) { 166b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher case OUTMODE_HIGH_Z: // disable 167b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher elecout = 0; 168b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher break; 169b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher case OUTMODE_MPEG2_PAR_GATED_CLK: // STBs with parallel gated clock 170b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher outmode = 0; 171b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher break; 172b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher case OUTMODE_MPEG2_PAR_CONT_CLK: // STBs with parallel continues clock 173b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher outmode = 1; 174b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher break; 175b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher case OUTMODE_MPEG2_SERIAL: // STBs with serial input 176b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher outmode = 2; 177b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher break; 178b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher case OUTMODE_MPEG2_FIFO: // e.g. USB feeding 179b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher elecout = 3; 180b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher /*ADDR @ 206 : 181b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher P_smo_error_discard [1;6:6] = 0 182b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher P_smo_rs_discard [1;5:5] = 0 183b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher P_smo_pid_parse [1;4:4] = 0 184b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher P_smo_fifo_flush [1;3:3] = 0 185b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher P_smo_mode [2;2:1] = 11 186b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher P_smo_ovf_prot [1;0:0] = 0 187b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher */ 188fb6065bbd915f9cf6022d52e114f5078654834b5Patrick Boettcher smo_reg |= 3 << 1; 189b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher fifo_threshold = 512; 190b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher outmode = 5; 191b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher break; 192b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher case OUTMODE_DIVERSITY: 193b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher outmode = 4; 194b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher elecout = 1; 1951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 1961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 197b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher dprintk("Unhandled output_mode passed to be set for demod %p\n",&state->demod); 198b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher outmode = 0; 1991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 2001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 201b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher 202b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher if ((state->cfg->output_mpeg2_in_188_bytes)) 203559463bba8b91d36b12f6722dc27440567e4f6bePatrick Boettcher smo_reg |= (1 << 5); // P_smo_rs_discard [1;5:5] = 1 204b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher 205b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher outreg = dib3000mc_read_word(state, 244) & 0x07FF; 206b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher outreg |= (outmode << 11); 207b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher ret |= dib3000mc_write_word(state, 244, outreg); 208b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher ret |= dib3000mc_write_word(state, 206, smo_reg); /*smo_ mode*/ 209b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher ret |= dib3000mc_write_word(state, 207, fifo_threshold); /* synchronous fread */ 210b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher ret |= dib3000mc_write_word(state, 1040, elecout); /* P_out_cfg */ 211b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher return ret; 2121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 214b6884a17fc70e979ef34e4b5560988b522bb50a0Patrick Boettcherstatic int dib3000mc_set_bandwidth(struct dib3000mc_state *state, u32 bw) 2151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 216b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher u16 bw_cfg[6] = { 0 }; 217b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher u16 imp_bw_cfg[3] = { 0 }; 218b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher u16 reg; 2191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 220b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher/* settings here are for 27.7MHz */ 221b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher switch (bw) { 222b6884a17fc70e979ef34e4b5560988b522bb50a0Patrick Boettcher case 8000: 223b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher bw_cfg[0] = 0x0019; bw_cfg[1] = 0x5c30; bw_cfg[2] = 0x0054; bw_cfg[3] = 0x88a0; bw_cfg[4] = 0x01a6; bw_cfg[5] = 0xab20; 224b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher imp_bw_cfg[0] = 0x04db; imp_bw_cfg[1] = 0x00db; imp_bw_cfg[2] = 0x00b7; 225b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher break; 2261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 227b6884a17fc70e979ef34e4b5560988b522bb50a0Patrick Boettcher case 7000: 228b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher bw_cfg[0] = 0x001c; bw_cfg[1] = 0xfba5; bw_cfg[2] = 0x0060; bw_cfg[3] = 0x9c25; bw_cfg[4] = 0x01e3; bw_cfg[5] = 0x0cb7; 229b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher imp_bw_cfg[0] = 0x04c0; imp_bw_cfg[1] = 0x00c0; imp_bw_cfg[2] = 0x00a0; 230b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher break; 2311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 232b6884a17fc70e979ef34e4b5560988b522bb50a0Patrick Boettcher case 6000: 233b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher bw_cfg[0] = 0x0021; bw_cfg[1] = 0xd040; bw_cfg[2] = 0x0070; bw_cfg[3] = 0xb62b; bw_cfg[4] = 0x0233; bw_cfg[5] = 0x8ed5; 234b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher imp_bw_cfg[0] = 0x04a5; imp_bw_cfg[1] = 0x00a5; imp_bw_cfg[2] = 0x0089; 2351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 236b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher 237b6884a17fc70e979ef34e4b5560988b522bb50a0Patrick Boettcher case 5000: 238b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher bw_cfg[0] = 0x0028; bw_cfg[1] = 0x9380; bw_cfg[2] = 0x0087; bw_cfg[3] = 0x4100; bw_cfg[4] = 0x02a4; bw_cfg[5] = 0x4500; 239b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher imp_bw_cfg[0] = 0x0489; imp_bw_cfg[1] = 0x0089; imp_bw_cfg[2] = 0x0072; 2401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 241b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher 242b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher default: return -EINVAL; 2431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 245b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher for (reg = 6; reg < 12; reg++) 246b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher dib3000mc_write_word(state, reg, bw_cfg[reg - 6]); 247b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher dib3000mc_write_word(state, 12, 0x0000); 248b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher dib3000mc_write_word(state, 13, 0x03e8); 249b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher dib3000mc_write_word(state, 14, 0x0000); 250b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher dib3000mc_write_word(state, 15, 0x03f2); 251b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher dib3000mc_write_word(state, 16, 0x0001); 252b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher dib3000mc_write_word(state, 17, 0xb0d0); 253b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher // P_sec_len 254b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher dib3000mc_write_word(state, 18, 0x0393); 255b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher dib3000mc_write_word(state, 19, 0x8700); 2561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 257b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher for (reg = 55; reg < 58; reg++) 258b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher dib3000mc_write_word(state, reg, imp_bw_cfg[reg - 55]); 2591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 260b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher // Timing configuration 261b6884a17fc70e979ef34e4b5560988b522bb50a0Patrick Boettcher dib3000mc_set_timing(state, TRANSMISSION_MODE_2K, bw, 0); 2621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 263b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher return 0; 264b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher} 2651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 266b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcherstatic u16 impulse_noise_val[29] = 2671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 268b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher{ 269b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher 0x38, 0x6d9, 0x3f28, 0x7a7, 0x3a74, 0x196, 0x32a, 0x48c, 0x3ffe, 0x7f3, 270b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher 0x2d94, 0x76, 0x53d, 0x3ff8, 0x7e3, 0x3320, 0x76, 0x5b3, 0x3feb, 0x7d2, 271b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher 0x365e, 0x76, 0x48c, 0x3ffe, 0x5b3, 0x3feb, 0x76, 0x0000, 0xd 272b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher}; 2731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 274b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcherstatic void dib3000mc_set_impulse_noise(struct dib3000mc_state *state, u8 mode, s16 nfft) 275b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher{ 276b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher u16 i; 277b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher for (i = 58; i < 87; i++) 278b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher dib3000mc_write_word(state, i, impulse_noise_val[i-58]); 279b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher 280b6884a17fc70e979ef34e4b5560988b522bb50a0Patrick Boettcher if (nfft == TRANSMISSION_MODE_8K) { 281b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher dib3000mc_write_word(state, 58, 0x3b); 282b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher dib3000mc_write_word(state, 84, 0x00); 283b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher dib3000mc_write_word(state, 85, 0x8200); 2841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 286b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher dib3000mc_write_word(state, 34, 0x1294); 287b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher dib3000mc_write_word(state, 35, 0x1ff8); 288b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher if (mode == 1) 289b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher dib3000mc_write_word(state, 55, dib3000mc_read_word(state, 55) | (1 << 10)); 290b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher} 291b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher 292b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcherstatic int dib3000mc_init(struct dvb_frontend *demod) 293b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher{ 294b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher struct dib3000mc_state *state = demod->demodulator_priv; 295b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher struct dibx000_agc_config *agc = state->cfg->agc; 296b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher 297b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher // Restart Configuration 298b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher dib3000mc_write_word(state, 1027, 0x8000); 299b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher dib3000mc_write_word(state, 1027, 0x0000); 300b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher 301b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher // power up the demod + mobility configuration 302b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher dib3000mc_write_word(state, 140, 0x0000); 303b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher dib3000mc_write_word(state, 1031, 0); 304b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher 305b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher if (state->cfg->mobile_mode) { 306b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher dib3000mc_write_word(state, 139, 0x0000); 307b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher dib3000mc_write_word(state, 141, 0x0000); 308b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher dib3000mc_write_word(state, 175, 0x0002); 309b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher dib3000mc_write_word(state, 1032, 0x0000); 3101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 311b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher dib3000mc_write_word(state, 139, 0x0001); 312b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher dib3000mc_write_word(state, 141, 0x0000); 313b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher dib3000mc_write_word(state, 175, 0x0000); 314b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher dib3000mc_write_word(state, 1032, 0x012C); 3151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 316303cbeaaacd449545d259f82b966d070418c58afPatrick Boettcher dib3000mc_write_word(state, 1033, 0x0000); 3171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 318b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher // P_clk_cfg 319303cbeaaacd449545d259f82b966d070418c58afPatrick Boettcher dib3000mc_write_word(state, 1037, 0x3130); 3201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 321b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher // other configurations 3221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 323b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher // P_ctrl_sfreq 324b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher dib3000mc_write_word(state, 33, (5 << 0)); 325b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher dib3000mc_write_word(state, 88, (1 << 10) | (0x10 << 0)); 3261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 327b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher // Phase noise control 328b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher // P_fft_phacor_inh, P_fft_phacor_cpe, P_fft_powrange 329b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher dib3000mc_write_word(state, 99, (1 << 9) | (0x20 << 0)); 3301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 331b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher if (state->cfg->phase_noise_mode == 0) 332b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher dib3000mc_write_word(state, 111, 0x00); 333b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher else 334b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher dib3000mc_write_word(state, 111, 0x02); 335b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher 336b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher // P_agc_global 337b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher dib3000mc_write_word(state, 50, 0x8000); 338b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher 339b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher // agc setup misc 34001b4bf31ce6ca6c1de31c773fa281a34fd98ff87Patrick Boettcher dib3000mc_setup_pwm_state(state); 341b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher 342b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher // P_agc_counter_lock 343b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher dib3000mc_write_word(state, 53, 0x87); 344b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher // P_agc_counter_unlock 345b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher dib3000mc_write_word(state, 54, 0x87); 346b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher 347b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher /* agc */ 348b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher dib3000mc_write_word(state, 36, state->cfg->max_time); 3495570dd02ca7fb2e28d32516fae05031d48711aa5Patrick Boettcher dib3000mc_write_word(state, 37, (state->cfg->agc_command1 << 13) | (state->cfg->agc_command2 << 12) | (0x1d << 0)); 350b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher dib3000mc_write_word(state, 38, state->cfg->pwm3_value); 351b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher dib3000mc_write_word(state, 39, state->cfg->ln_adc_level); 352b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher 353b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher // set_agc_loop_Bw 354b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher dib3000mc_write_word(state, 40, 0x0179); 355b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher dib3000mc_write_word(state, 41, 0x03f0); 356b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher 357b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher dib3000mc_write_word(state, 42, agc->agc1_max); 358b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher dib3000mc_write_word(state, 43, agc->agc1_min); 359b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher dib3000mc_write_word(state, 44, agc->agc2_max); 360b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher dib3000mc_write_word(state, 45, agc->agc2_min); 361b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher dib3000mc_write_word(state, 46, (agc->agc1_pt1 << 8) | agc->agc1_pt2); 362b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher dib3000mc_write_word(state, 47, (agc->agc1_slope1 << 8) | agc->agc1_slope2); 363b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher dib3000mc_write_word(state, 48, (agc->agc2_pt1 << 8) | agc->agc2_pt2); 364b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher dib3000mc_write_word(state, 49, (agc->agc2_slope1 << 8) | agc->agc2_slope2); 365b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher 366b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher// Begin: TimeOut registers 367b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher // P_pha3_thres 368b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher dib3000mc_write_word(state, 110, 3277); 369b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher // P_timf_alpha = 6, P_corm_alpha = 6, P_corm_thres = 0x80 370b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher dib3000mc_write_word(state, 26, 0x6680); 371b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher // lock_mask0 372b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher dib3000mc_write_word(state, 1, 4); 373b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher // lock_mask1 374b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher dib3000mc_write_word(state, 2, 4); 375b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher // lock_mask2 376b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher dib3000mc_write_word(state, 3, 0x1000); 377b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher // P_search_maxtrial=1 378b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher dib3000mc_write_word(state, 5, 1); 379b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher 380b6884a17fc70e979ef34e4b5560988b522bb50a0Patrick Boettcher dib3000mc_set_bandwidth(state, 8000); 381b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher 382b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher // div_lock_mask 383b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher dib3000mc_write_word(state, 4, 0x814); 384b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher 385b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher dib3000mc_write_word(state, 21, (1 << 9) | 0x164); 386b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher dib3000mc_write_word(state, 22, 0x463d); 387b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher 388b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher // Spurious rm cfg 389b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher // P_cspu_regul, P_cspu_win_cut 390b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher dib3000mc_write_word(state, 120, 0x200f); 391b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher // P_adp_selec_monit 392b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher dib3000mc_write_word(state, 134, 0); 393b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher 394b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher // Fec cfg 395b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher dib3000mc_write_word(state, 195, 0x10); 396b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher 397b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher // diversity register: P_dvsy_sync_wait.. 398b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher dib3000mc_write_word(state, 180, 0x2FF0); 399b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher 400b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher // Impulse noise configuration 401b6884a17fc70e979ef34e4b5560988b522bb50a0Patrick Boettcher dib3000mc_set_impulse_noise(state, 0, TRANSMISSION_MODE_8K); 402b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher 403b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher // output mode set-up 404b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher dib3000mc_set_output_mode(state, OUTMODE_HIGH_Z); 405b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher 406b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher /* close the i2c-gate */ 407b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher dib3000mc_write_word(state, 769, (1 << 7) ); 4081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 409b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher return 0; 410b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher} 4111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 412b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcherstatic int dib3000mc_sleep(struct dvb_frontend *demod) 413b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher{ 414b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher struct dib3000mc_state *state = demod->demodulator_priv; 4151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 416b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher dib3000mc_write_word(state, 1031, 0xFFFF); 417b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher dib3000mc_write_word(state, 1032, 0xFFFF); 418303cbeaaacd449545d259f82b966d070418c58afPatrick Boettcher dib3000mc_write_word(state, 1033, 0xFFF0); 4191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 420b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher return 0; 421b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher} 4221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 423b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcherstatic void dib3000mc_set_adp_cfg(struct dib3000mc_state *state, s16 qam) 424b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher{ 425b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher u16 cfg[4] = { 0 },reg; 426b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher switch (qam) { 427b6884a17fc70e979ef34e4b5560988b522bb50a0Patrick Boettcher case QPSK: 428b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher cfg[0] = 0x099a; cfg[1] = 0x7fae; cfg[2] = 0x0333; cfg[3] = 0x7ff0; 429b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher break; 430b6884a17fc70e979ef34e4b5560988b522bb50a0Patrick Boettcher case QAM_16: 431b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher cfg[0] = 0x023d; cfg[1] = 0x7fdf; cfg[2] = 0x00a4; cfg[3] = 0x7ff0; 432b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher break; 433b6884a17fc70e979ef34e4b5560988b522bb50a0Patrick Boettcher case QAM_64: 434b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher cfg[0] = 0x0148; cfg[1] = 0x7ff0; cfg[2] = 0x00a4; cfg[3] = 0x7ff8; 435b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher break; 4361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 437b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher for (reg = 129; reg < 133; reg++) 438b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher dib3000mc_write_word(state, reg, cfg[reg - 129]); 4391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 441c1f814f49904ae5b275407f71aefd3a31c774098Mauro Carvalho Chehabstatic void dib3000mc_set_channel_cfg(struct dib3000mc_state *state, 442c1f814f49904ae5b275407f71aefd3a31c774098Mauro Carvalho Chehab struct dtv_frontend_properties *ch, u16 seq) 4431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 444b6884a17fc70e979ef34e4b5560988b522bb50a0Patrick Boettcher u16 value; 445c1f814f49904ae5b275407f71aefd3a31c774098Mauro Carvalho Chehab u32 bw = BANDWIDTH_TO_KHZ(ch->bandwidth_hz); 446c1f814f49904ae5b275407f71aefd3a31c774098Mauro Carvalho Chehab 447c1f814f49904ae5b275407f71aefd3a31c774098Mauro Carvalho Chehab dib3000mc_set_bandwidth(state, bw); 448c1f814f49904ae5b275407f71aefd3a31c774098Mauro Carvalho Chehab dib3000mc_set_timing(state, ch->transmission_mode, bw, 0); 4491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 450b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher// if (boost) 451b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher// dib3000mc_write_word(state, 100, (11 << 6) + 6); 452b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher// else 453b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher dib3000mc_write_word(state, 100, (16 << 6) + 9); 4541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 455b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher dib3000mc_write_word(state, 1027, 0x0800); 456b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher dib3000mc_write_word(state, 1027, 0x0000); 4571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 458b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher //Default cfg isi offset adp 459b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher dib3000mc_write_word(state, 26, 0x6680); 460b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher dib3000mc_write_word(state, 29, 0x1273); 461b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher dib3000mc_write_word(state, 33, 5); 462b6884a17fc70e979ef34e4b5560988b522bb50a0Patrick Boettcher dib3000mc_set_adp_cfg(state, QAM_16); 463b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher dib3000mc_write_word(state, 133, 15564); 4641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 465b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher dib3000mc_write_word(state, 12 , 0x0); 466b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher dib3000mc_write_word(state, 13 , 0x3e8); 467b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher dib3000mc_write_word(state, 14 , 0x0); 468b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher dib3000mc_write_word(state, 15 , 0x3f2); 4691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 470b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher dib3000mc_write_word(state, 93,0); 471b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher dib3000mc_write_word(state, 94,0); 472b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher dib3000mc_write_word(state, 95,0); 473b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher dib3000mc_write_word(state, 96,0); 474b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher dib3000mc_write_word(state, 97,0); 475b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher dib3000mc_write_word(state, 98,0); 4761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 477c1f814f49904ae5b275407f71aefd3a31c774098Mauro Carvalho Chehab dib3000mc_set_impulse_noise(state, 0, ch->transmission_mode); 478e4d6c1f74aaac1bbe5be50e7368e5ac99d54e5a2Patrick Boettcher 479b6884a17fc70e979ef34e4b5560988b522bb50a0Patrick Boettcher value = 0; 480c1f814f49904ae5b275407f71aefd3a31c774098Mauro Carvalho Chehab switch (ch->transmission_mode) { 481b6884a17fc70e979ef34e4b5560988b522bb50a0Patrick Boettcher case TRANSMISSION_MODE_2K: value |= (0 << 7); break; 482b6884a17fc70e979ef34e4b5560988b522bb50a0Patrick Boettcher default: 483b6884a17fc70e979ef34e4b5560988b522bb50a0Patrick Boettcher case TRANSMISSION_MODE_8K: value |= (1 << 7); break; 484b6884a17fc70e979ef34e4b5560988b522bb50a0Patrick Boettcher } 485c1f814f49904ae5b275407f71aefd3a31c774098Mauro Carvalho Chehab switch (ch->guard_interval) { 486b6884a17fc70e979ef34e4b5560988b522bb50a0Patrick Boettcher case GUARD_INTERVAL_1_32: value |= (0 << 5); break; 487b6884a17fc70e979ef34e4b5560988b522bb50a0Patrick Boettcher case GUARD_INTERVAL_1_16: value |= (1 << 5); break; 488b6884a17fc70e979ef34e4b5560988b522bb50a0Patrick Boettcher case GUARD_INTERVAL_1_4: value |= (3 << 5); break; 489b6884a17fc70e979ef34e4b5560988b522bb50a0Patrick Boettcher default: 490b6884a17fc70e979ef34e4b5560988b522bb50a0Patrick Boettcher case GUARD_INTERVAL_1_8: value |= (2 << 5); break; 491b6884a17fc70e979ef34e4b5560988b522bb50a0Patrick Boettcher } 492c1f814f49904ae5b275407f71aefd3a31c774098Mauro Carvalho Chehab switch (ch->modulation) { 493b6884a17fc70e979ef34e4b5560988b522bb50a0Patrick Boettcher case QPSK: value |= (0 << 3); break; 494b6884a17fc70e979ef34e4b5560988b522bb50a0Patrick Boettcher case QAM_16: value |= (1 << 3); break; 495b6884a17fc70e979ef34e4b5560988b522bb50a0Patrick Boettcher default: 496b6884a17fc70e979ef34e4b5560988b522bb50a0Patrick Boettcher case QAM_64: value |= (2 << 3); break; 497b6884a17fc70e979ef34e4b5560988b522bb50a0Patrick Boettcher } 498b6884a17fc70e979ef34e4b5560988b522bb50a0Patrick Boettcher switch (HIERARCHY_1) { 499b6884a17fc70e979ef34e4b5560988b522bb50a0Patrick Boettcher case HIERARCHY_2: value |= 2; break; 500b6884a17fc70e979ef34e4b5560988b522bb50a0Patrick Boettcher case HIERARCHY_4: value |= 4; break; 501b6884a17fc70e979ef34e4b5560988b522bb50a0Patrick Boettcher default: 502b6884a17fc70e979ef34e4b5560988b522bb50a0Patrick Boettcher case HIERARCHY_1: value |= 1; break; 503b6884a17fc70e979ef34e4b5560988b522bb50a0Patrick Boettcher } 504b6884a17fc70e979ef34e4b5560988b522bb50a0Patrick Boettcher dib3000mc_write_word(state, 0, value); 505e3ab2fdd3f5efe62d266877c53c578fe5b547b31Mario Rossi dib3000mc_write_word(state, 5, (1 << 8) | ((seq & 0xf) << 4)); 5061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 507b6884a17fc70e979ef34e4b5560988b522bb50a0Patrick Boettcher value = 0; 508c1f814f49904ae5b275407f71aefd3a31c774098Mauro Carvalho Chehab if (ch->hierarchy == 1) 509b6884a17fc70e979ef34e4b5560988b522bb50a0Patrick Boettcher value |= (1 << 4); 510b6884a17fc70e979ef34e4b5560988b522bb50a0Patrick Boettcher if (1 == 1) 511b6884a17fc70e979ef34e4b5560988b522bb50a0Patrick Boettcher value |= 1; 512c1f814f49904ae5b275407f71aefd3a31c774098Mauro Carvalho Chehab switch ((ch->hierarchy == 0 || 1 == 1) ? ch->code_rate_HP : ch->code_rate_LP) { 513b6884a17fc70e979ef34e4b5560988b522bb50a0Patrick Boettcher case FEC_2_3: value |= (2 << 1); break; 514b6884a17fc70e979ef34e4b5560988b522bb50a0Patrick Boettcher case FEC_3_4: value |= (3 << 1); break; 515b6884a17fc70e979ef34e4b5560988b522bb50a0Patrick Boettcher case FEC_5_6: value |= (5 << 1); break; 516b6884a17fc70e979ef34e4b5560988b522bb50a0Patrick Boettcher case FEC_7_8: value |= (7 << 1); break; 517b6884a17fc70e979ef34e4b5560988b522bb50a0Patrick Boettcher default: 518b6884a17fc70e979ef34e4b5560988b522bb50a0Patrick Boettcher case FEC_1_2: value |= (1 << 1); break; 519b6884a17fc70e979ef34e4b5560988b522bb50a0Patrick Boettcher } 520b6884a17fc70e979ef34e4b5560988b522bb50a0Patrick Boettcher dib3000mc_write_word(state, 181, value); 5211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 522b6884a17fc70e979ef34e4b5560988b522bb50a0Patrick Boettcher // diversity synchro delay add 50% SFN margin 523c1f814f49904ae5b275407f71aefd3a31c774098Mauro Carvalho Chehab switch (ch->transmission_mode) { 524b6884a17fc70e979ef34e4b5560988b522bb50a0Patrick Boettcher case TRANSMISSION_MODE_8K: value = 256; break; 525b6884a17fc70e979ef34e4b5560988b522bb50a0Patrick Boettcher case TRANSMISSION_MODE_2K: 526b6884a17fc70e979ef34e4b5560988b522bb50a0Patrick Boettcher default: value = 64; break; 527b6884a17fc70e979ef34e4b5560988b522bb50a0Patrick Boettcher } 528c1f814f49904ae5b275407f71aefd3a31c774098Mauro Carvalho Chehab switch (ch->guard_interval) { 529b6884a17fc70e979ef34e4b5560988b522bb50a0Patrick Boettcher case GUARD_INTERVAL_1_16: value *= 2; break; 530b6884a17fc70e979ef34e4b5560988b522bb50a0Patrick Boettcher case GUARD_INTERVAL_1_8: value *= 4; break; 531b6884a17fc70e979ef34e4b5560988b522bb50a0Patrick Boettcher case GUARD_INTERVAL_1_4: value *= 8; break; 532b6884a17fc70e979ef34e4b5560988b522bb50a0Patrick Boettcher default: 533b6884a17fc70e979ef34e4b5560988b522bb50a0Patrick Boettcher case GUARD_INTERVAL_1_32: value *= 1; break; 534b6884a17fc70e979ef34e4b5560988b522bb50a0Patrick Boettcher } 535b6884a17fc70e979ef34e4b5560988b522bb50a0Patrick Boettcher value <<= 4; 536b6884a17fc70e979ef34e4b5560988b522bb50a0Patrick Boettcher value |= dib3000mc_read_word(state, 180) & 0x000f; 537b6884a17fc70e979ef34e4b5560988b522bb50a0Patrick Boettcher dib3000mc_write_word(state, 180, value); 5381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 539b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher // restart demod 540b6884a17fc70e979ef34e4b5560988b522bb50a0Patrick Boettcher value = dib3000mc_read_word(state, 0); 541b6884a17fc70e979ef34e4b5560988b522bb50a0Patrick Boettcher dib3000mc_write_word(state, 0, value | (1 << 9)); 542b6884a17fc70e979ef34e4b5560988b522bb50a0Patrick Boettcher dib3000mc_write_word(state, 0, value); 5431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 544b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher msleep(30); 5451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 546c1f814f49904ae5b275407f71aefd3a31c774098Mauro Carvalho Chehab dib3000mc_set_impulse_noise(state, state->cfg->impulse_noise_mode, ch->transmission_mode); 547b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher} 5481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 549c1f814f49904ae5b275407f71aefd3a31c774098Mauro Carvalho Chehabstatic int dib3000mc_autosearch_start(struct dvb_frontend *demod) 550b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher{ 551c1f814f49904ae5b275407f71aefd3a31c774098Mauro Carvalho Chehab struct dtv_frontend_properties *chan = &demod->dtv_property_cache; 552b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher struct dib3000mc_state *state = demod->demodulator_priv; 553b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher u16 reg; 554b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher// u32 val; 555c1f814f49904ae5b275407f71aefd3a31c774098Mauro Carvalho Chehab struct dtv_frontend_properties schan; 5561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 557b6884a17fc70e979ef34e4b5560988b522bb50a0Patrick Boettcher schan = *chan; 5581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 559b6884a17fc70e979ef34e4b5560988b522bb50a0Patrick Boettcher /* TODO what is that ? */ 5601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 561b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher /* a channel for autosearch */ 562c1f814f49904ae5b275407f71aefd3a31c774098Mauro Carvalho Chehab schan.transmission_mode = TRANSMISSION_MODE_8K; 563c1f814f49904ae5b275407f71aefd3a31c774098Mauro Carvalho Chehab schan.guard_interval = GUARD_INTERVAL_1_32; 564c1f814f49904ae5b275407f71aefd3a31c774098Mauro Carvalho Chehab schan.modulation = QAM_64; 565c1f814f49904ae5b275407f71aefd3a31c774098Mauro Carvalho Chehab schan.code_rate_HP = FEC_2_3; 566c1f814f49904ae5b275407f71aefd3a31c774098Mauro Carvalho Chehab schan.code_rate_LP = FEC_2_3; 567c1f814f49904ae5b275407f71aefd3a31c774098Mauro Carvalho Chehab schan.hierarchy = 0; 5681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 569b6884a17fc70e979ef34e4b5560988b522bb50a0Patrick Boettcher dib3000mc_set_channel_cfg(state, &schan, 11); 5701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 571b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher reg = dib3000mc_read_word(state, 0); 572b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher dib3000mc_write_word(state, 0, reg | (1 << 8)); 57301b4bf31ce6ca6c1de31c773fa281a34fd98ff87Patrick Boettcher dib3000mc_read_word(state, 511); 574b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher dib3000mc_write_word(state, 0, reg); 5751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 576b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher return 0; 577b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher} 5781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 579b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcherstatic int dib3000mc_autosearch_is_irq(struct dvb_frontend *demod) 580b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher{ 581b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher struct dib3000mc_state *state = demod->demodulator_priv; 582b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher u16 irq_pending = dib3000mc_read_word(state, 511); 5831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 584b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher if (irq_pending & 0x1) // failed 585b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher return 1; 5861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 587b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher if (irq_pending & 0x2) // succeeded 588b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher return 2; 589a16bf5d5603184dc1db88f37051881b2eeacfd17Olivier DANET 590b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher return 0; // still pending 5911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 592b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher 593c1f814f49904ae5b275407f71aefd3a31c774098Mauro Carvalho Chehabstatic int dib3000mc_tune(struct dvb_frontend *demod) 5941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 595c1f814f49904ae5b275407f71aefd3a31c774098Mauro Carvalho Chehab struct dtv_frontend_properties *ch = &demod->dtv_property_cache; 596b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher struct dib3000mc_state *state = demod->demodulator_priv; 5971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 598b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher // ** configure demod ** 599b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher dib3000mc_set_channel_cfg(state, ch, 0); 600b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher 601b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher // activates isi 6028f6956c7f9fa72c502bde47df4122bd32d0b86d5Matt Doran if (state->sfn_workaround_active) { 6038f6956c7f9fa72c502bde47df4122bd32d0b86d5Matt Doran dprintk("SFN workaround is active\n"); 6048f6956c7f9fa72c502bde47df4122bd32d0b86d5Matt Doran dib3000mc_write_word(state, 29, 0x1273); 6058f6956c7f9fa72c502bde47df4122bd32d0b86d5Matt Doran dib3000mc_write_word(state, 108, 0x4000); // P_pha3_force_pha_shift 6068f6956c7f9fa72c502bde47df4122bd32d0b86d5Matt Doran } else { 6078f6956c7f9fa72c502bde47df4122bd32d0b86d5Matt Doran dib3000mc_write_word(state, 29, 0x1073); 6088f6956c7f9fa72c502bde47df4122bd32d0b86d5Matt Doran dib3000mc_write_word(state, 108, 0x0000); // P_pha3_force_pha_shift 6098f6956c7f9fa72c502bde47df4122bd32d0b86d5Matt Doran } 6101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 611c1f814f49904ae5b275407f71aefd3a31c774098Mauro Carvalho Chehab dib3000mc_set_adp_cfg(state, (u8)ch->modulation); 612c1f814f49904ae5b275407f71aefd3a31c774098Mauro Carvalho Chehab if (ch->transmission_mode == TRANSMISSION_MODE_8K) { 613b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher dib3000mc_write_word(state, 26, 38528); 614b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher dib3000mc_write_word(state, 33, 8); 615b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher } else { 616b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher dib3000mc_write_word(state, 26, 30336); 617b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher dib3000mc_write_word(state, 33, 6); 618b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher } 619b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher 62001b4bf31ce6ca6c1de31c773fa281a34fd98ff87Patrick Boettcher if (dib3000mc_read_word(state, 509) & 0x80) 621c1f814f49904ae5b275407f71aefd3a31c774098Mauro Carvalho Chehab dib3000mc_set_timing(state, ch->transmission_mode, 622c1f814f49904ae5b275407f71aefd3a31c774098Mauro Carvalho Chehab BANDWIDTH_TO_KHZ(ch->bandwidth_hz), 1); 6231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 6251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 6261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 627b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcherstruct i2c_adapter * dib3000mc_get_tuner_i2c_master(struct dvb_frontend *demod, int gating) 6281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 629b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher struct dib3000mc_state *st = demod->demodulator_priv; 630b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher return dibx000_get_i2c_adapter(&st->i2c_master, DIBX000_I2C_INTERFACE_TUNER, gating); 6311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 6321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 633b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick BoettcherEXPORT_SYMBOL(dib3000mc_get_tuner_i2c_master); 634b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher 6357c61d80a9bcfc3fdec8ffd75756cad6a64678229Mauro Carvalho Chehabstatic int dib3000mc_get_frontend(struct dvb_frontend* fe) 6361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 6377c61d80a9bcfc3fdec8ffd75756cad6a64678229Mauro Carvalho Chehab struct dtv_frontend_properties *fep = &fe->dtv_property_cache; 638b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher struct dib3000mc_state *state = fe->demodulator_priv; 639b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher u16 tps = dib3000mc_read_word(state,458); 6401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 641b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher fep->inversion = INVERSION_AUTO; 642b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher 643c1f814f49904ae5b275407f71aefd3a31c774098Mauro Carvalho Chehab fep->bandwidth_hz = state->current_bandwidth; 644b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher 645b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher switch ((tps >> 8) & 0x1) { 646c1f814f49904ae5b275407f71aefd3a31c774098Mauro Carvalho Chehab case 0: fep->transmission_mode = TRANSMISSION_MODE_2K; break; 647c1f814f49904ae5b275407f71aefd3a31c774098Mauro Carvalho Chehab case 1: fep->transmission_mode = TRANSMISSION_MODE_8K; break; 648b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher } 649b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher 650b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher switch (tps & 0x3) { 651c1f814f49904ae5b275407f71aefd3a31c774098Mauro Carvalho Chehab case 0: fep->guard_interval = GUARD_INTERVAL_1_32; break; 652c1f814f49904ae5b275407f71aefd3a31c774098Mauro Carvalho Chehab case 1: fep->guard_interval = GUARD_INTERVAL_1_16; break; 653c1f814f49904ae5b275407f71aefd3a31c774098Mauro Carvalho Chehab case 2: fep->guard_interval = GUARD_INTERVAL_1_8; break; 654c1f814f49904ae5b275407f71aefd3a31c774098Mauro Carvalho Chehab case 3: fep->guard_interval = GUARD_INTERVAL_1_4; break; 655b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher } 656b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher 657b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher switch ((tps >> 13) & 0x3) { 658c1f814f49904ae5b275407f71aefd3a31c774098Mauro Carvalho Chehab case 0: fep->modulation = QPSK; break; 659c1f814f49904ae5b275407f71aefd3a31c774098Mauro Carvalho Chehab case 1: fep->modulation = QAM_16; break; 660b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher case 2: 661c1f814f49904ae5b275407f71aefd3a31c774098Mauro Carvalho Chehab default: fep->modulation = QAM_64; break; 662b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher } 663b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher 664b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher /* as long as the frontend_param structure is fixed for hierarchical transmission I refuse to use it */ 665b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher /* (tps >> 12) & 0x1 == hrch is used, (tps >> 9) & 0x7 == alpha */ 666b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher 667c1f814f49904ae5b275407f71aefd3a31c774098Mauro Carvalho Chehab fep->hierarchy = HIERARCHY_NONE; 668b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher switch ((tps >> 5) & 0x7) { 669c1f814f49904ae5b275407f71aefd3a31c774098Mauro Carvalho Chehab case 1: fep->code_rate_HP = FEC_1_2; break; 670c1f814f49904ae5b275407f71aefd3a31c774098Mauro Carvalho Chehab case 2: fep->code_rate_HP = FEC_2_3; break; 671c1f814f49904ae5b275407f71aefd3a31c774098Mauro Carvalho Chehab case 3: fep->code_rate_HP = FEC_3_4; break; 672c1f814f49904ae5b275407f71aefd3a31c774098Mauro Carvalho Chehab case 5: fep->code_rate_HP = FEC_5_6; break; 673b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher case 7: 674c1f814f49904ae5b275407f71aefd3a31c774098Mauro Carvalho Chehab default: fep->code_rate_HP = FEC_7_8; break; 675b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher 676b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher } 677b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher 678b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher switch ((tps >> 2) & 0x7) { 679c1f814f49904ae5b275407f71aefd3a31c774098Mauro Carvalho Chehab case 1: fep->code_rate_LP = FEC_1_2; break; 680c1f814f49904ae5b275407f71aefd3a31c774098Mauro Carvalho Chehab case 2: fep->code_rate_LP = FEC_2_3; break; 681c1f814f49904ae5b275407f71aefd3a31c774098Mauro Carvalho Chehab case 3: fep->code_rate_LP = FEC_3_4; break; 682c1f814f49904ae5b275407f71aefd3a31c774098Mauro Carvalho Chehab case 5: fep->code_rate_LP = FEC_5_6; break; 683b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher case 7: 684c1f814f49904ae5b275407f71aefd3a31c774098Mauro Carvalho Chehab default: fep->code_rate_LP = FEC_7_8; break; 685b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher } 6861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 6881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 6891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 690c1f814f49904ae5b275407f71aefd3a31c774098Mauro Carvalho Chehabstatic int dib3000mc_set_frontend(struct dvb_frontend *fe) 6911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 6927c61d80a9bcfc3fdec8ffd75756cad6a64678229Mauro Carvalho Chehab struct dtv_frontend_properties *fep = &fe->dtv_property_cache; 693b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher struct dib3000mc_state *state = fe->demodulator_priv; 694c1f814f49904ae5b275407f71aefd3a31c774098Mauro Carvalho Chehab int ret; 695853ea132c75ff2c4e3c3aaf61bf3ef5779774dbcSoeren Moch 696853ea132c75ff2c4e3c3aaf61bf3ef5779774dbcSoeren Moch dib3000mc_set_output_mode(state, OUTMODE_HIGH_Z); 697b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher 698c1f814f49904ae5b275407f71aefd3a31c774098Mauro Carvalho Chehab state->current_bandwidth = fep->bandwidth_hz; 699c1f814f49904ae5b275407f71aefd3a31c774098Mauro Carvalho Chehab dib3000mc_set_bandwidth(state, BANDWIDTH_TO_KHZ(fep->bandwidth_hz)); 700b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher 7018f6956c7f9fa72c502bde47df4122bd32d0b86d5Matt Doran /* maybe the parameter has been changed */ 7028f6956c7f9fa72c502bde47df4122bd32d0b86d5Matt Doran state->sfn_workaround_active = buggy_sfn_workaround; 7038f6956c7f9fa72c502bde47df4122bd32d0b86d5Matt Doran 704b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher if (fe->ops.tuner_ops.set_params) { 70514d24d148c7521b2b88b396652e36f55d061e195Mauro Carvalho Chehab fe->ops.tuner_ops.set_params(fe); 706b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher msleep(100); 707b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher } 708b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher 709c1f814f49904ae5b275407f71aefd3a31c774098Mauro Carvalho Chehab if (fep->transmission_mode == TRANSMISSION_MODE_AUTO || 710c1f814f49904ae5b275407f71aefd3a31c774098Mauro Carvalho Chehab fep->guard_interval == GUARD_INTERVAL_AUTO || 711c1f814f49904ae5b275407f71aefd3a31c774098Mauro Carvalho Chehab fep->modulation == QAM_AUTO || 712c1f814f49904ae5b275407f71aefd3a31c774098Mauro Carvalho Chehab fep->code_rate_HP == FEC_AUTO) { 7133a0311c6c539bd022a65d298355471aacbd7a618Jose Alberto Reguero int i = 1000, found; 714b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher 715c1f814f49904ae5b275407f71aefd3a31c774098Mauro Carvalho Chehab dib3000mc_autosearch_start(fe); 716b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher do { 717b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher msleep(1); 718b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher found = dib3000mc_autosearch_is_irq(fe); 719b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher } while (found == 0 && i--); 720b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher 721b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher dprintk("autosearch returns: %d\n",found); 722b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher if (found == 0 || found == 1) 723b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher return 0; // no channel found 724b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher 7257c61d80a9bcfc3fdec8ffd75756cad6a64678229Mauro Carvalho Chehab dib3000mc_get_frontend(fe); 726b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher } 727b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher 728c1f814f49904ae5b275407f71aefd3a31c774098Mauro Carvalho Chehab ret = dib3000mc_tune(fe); 729853ea132c75ff2c4e3c3aaf61bf3ef5779774dbcSoeren Moch 730b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher /* make this a config parameter */ 731b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher dib3000mc_set_output_mode(state, OUTMODE_MPEG2_FIFO); 732c1f814f49904ae5b275407f71aefd3a31c774098Mauro Carvalho Chehab return ret; 7331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 7341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 735b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcherstatic int dib3000mc_read_status(struct dvb_frontend *fe, fe_status_t *stat) 7361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 737b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher struct dib3000mc_state *state = fe->demodulator_priv; 738b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher u16 lock = dib3000mc_read_word(state, 509); 739b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher 740b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher *stat = 0; 741b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher 742b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher if (lock & 0x8000) 743b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher *stat |= FE_HAS_SIGNAL; 744b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher if (lock & 0x3000) 745b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher *stat |= FE_HAS_CARRIER; 746b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher if (lock & 0x0100) 747b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher *stat |= FE_HAS_VITERBI; 748b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher if (lock & 0x0010) 749b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher *stat |= FE_HAS_SYNC; 750b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher if (lock & 0x0008) 751b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher *stat |= FE_HAS_LOCK; 752b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher 7531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 7541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 7551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 756b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcherstatic int dib3000mc_read_ber(struct dvb_frontend *fe, u32 *ber) 7571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 758b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher struct dib3000mc_state *state = fe->demodulator_priv; 759b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher *ber = (dib3000mc_read_word(state, 500) << 16) | dib3000mc_read_word(state, 501); 760b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher return 0; 7611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 7621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 763b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcherstatic int dib3000mc_read_unc_blocks(struct dvb_frontend *fe, u32 *unc) 7641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 765b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher struct dib3000mc_state *state = fe->demodulator_priv; 766b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher *unc = dib3000mc_read_word(state, 508); 767b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher return 0; 7681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 7691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 770b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcherstatic int dib3000mc_read_signal_strength(struct dvb_frontend *fe, u16 *strength) 7711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 772b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher struct dib3000mc_state *state = fe->demodulator_priv; 773b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher u16 val = dib3000mc_read_word(state, 392); 774b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher *strength = 65535 - val; 775b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher return 0; 7761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 7771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 778b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcherstatic int dib3000mc_read_snr(struct dvb_frontend* fe, u16 *snr) 7791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 780b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher *snr = 0x0000; 7811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 7821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 7831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 784b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcherstatic int dib3000mc_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune) 7851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 786b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher tune->min_delay_ms = 1000; 7871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 7881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 7891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 790b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcherstatic void dib3000mc_release(struct dvb_frontend *fe) 7911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 792b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher struct dib3000mc_state *state = fe->demodulator_priv; 793b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher dibx000_exit_i2c_master(&state->i2c_master); 794b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher kfree(state); 7951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 7961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 797b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcherint dib3000mc_pid_control(struct dvb_frontend *fe, int index, int pid,int onoff) 7981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 799b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher struct dib3000mc_state *state = fe->demodulator_priv; 800b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher dib3000mc_write_word(state, 212 + index, onoff ? (1 << 13) | pid : 0); 8011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 8021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 803b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick BoettcherEXPORT_SYMBOL(dib3000mc_pid_control); 8041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 805b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcherint dib3000mc_pid_parse(struct dvb_frontend *fe, int onoff) 8061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 807b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher struct dib3000mc_state *state = fe->demodulator_priv; 808b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher u16 tmp = dib3000mc_read_word(state, 206) & ~(1 << 4); 809b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher tmp |= (onoff << 4); 810b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher return dib3000mc_write_word(state, 206, tmp); 8111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 812b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick BoettcherEXPORT_SYMBOL(dib3000mc_pid_parse); 8131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 814b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettchervoid dib3000mc_set_config(struct dvb_frontend *fe, struct dib3000mc_config *cfg) 815e4d6c1f74aaac1bbe5be50e7368e5ac99d54e5a2Patrick Boettcher{ 816b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher struct dib3000mc_state *state = fe->demodulator_priv; 817b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher state->cfg = cfg; 818e4d6c1f74aaac1bbe5be50e7368e5ac99d54e5a2Patrick Boettcher} 819b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick BoettcherEXPORT_SYMBOL(dib3000mc_set_config); 8201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 821136cafbf4a024b52ba0a10627217f03cea9ff9f8Patrick Boettcherint dib3000mc_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 default_addr, struct dib3000mc_config cfg[]) 8221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 8230de8e3533e08745616a30bdb3fa5106c85083e51Randy Dunlap struct dib3000mc_state *dmcst; 824136cafbf4a024b52ba0a10627217f03cea9ff9f8Patrick Boettcher int k; 825136cafbf4a024b52ba0a10627217f03cea9ff9f8Patrick Boettcher u8 new_addr; 8261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 827136cafbf4a024b52ba0a10627217f03cea9ff9f8Patrick Boettcher static u8 DIB3000MC_I2C_ADDRESS[] = {20,22,24,26}; 8281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8290de8e3533e08745616a30bdb3fa5106c85083e51Randy Dunlap dmcst = kzalloc(sizeof(struct dib3000mc_state), GFP_KERNEL); 8300de8e3533e08745616a30bdb3fa5106c85083e51Randy Dunlap if (dmcst == NULL) 831febe2ea10e041c014b295a0321f7ec62c05b7e3fAndrew Morton return -ENOMEM; 8320de8e3533e08745616a30bdb3fa5106c85083e51Randy Dunlap 8330de8e3533e08745616a30bdb3fa5106c85083e51Randy Dunlap dmcst->i2c_adap = i2c; 8340de8e3533e08745616a30bdb3fa5106c85083e51Randy Dunlap 835136cafbf4a024b52ba0a10627217f03cea9ff9f8Patrick Boettcher for (k = no_of_demods-1; k >= 0; k--) { 8360de8e3533e08745616a30bdb3fa5106c85083e51Randy Dunlap dmcst->cfg = &cfg[k]; 8371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 838136cafbf4a024b52ba0a10627217f03cea9ff9f8Patrick Boettcher /* designated i2c address */ 839136cafbf4a024b52ba0a10627217f03cea9ff9f8Patrick Boettcher new_addr = DIB3000MC_I2C_ADDRESS[k]; 8400de8e3533e08745616a30bdb3fa5106c85083e51Randy Dunlap dmcst->i2c_addr = new_addr; 8410de8e3533e08745616a30bdb3fa5106c85083e51Randy Dunlap if (dib3000mc_identify(dmcst) != 0) { 8420de8e3533e08745616a30bdb3fa5106c85083e51Randy Dunlap dmcst->i2c_addr = default_addr; 8430de8e3533e08745616a30bdb3fa5106c85083e51Randy Dunlap if (dib3000mc_identify(dmcst) != 0) { 844136cafbf4a024b52ba0a10627217f03cea9ff9f8Patrick Boettcher dprintk("-E- DiB3000P/MC #%d: not identified\n", k); 8450de8e3533e08745616a30bdb3fa5106c85083e51Randy Dunlap kfree(dmcst); 846136cafbf4a024b52ba0a10627217f03cea9ff9f8Patrick Boettcher return -ENODEV; 847136cafbf4a024b52ba0a10627217f03cea9ff9f8Patrick Boettcher } 848136cafbf4a024b52ba0a10627217f03cea9ff9f8Patrick Boettcher } 8491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8500de8e3533e08745616a30bdb3fa5106c85083e51Randy Dunlap dib3000mc_set_output_mode(dmcst, OUTMODE_MPEG2_PAR_CONT_CLK); 8511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 852136cafbf4a024b52ba0a10627217f03cea9ff9f8Patrick Boettcher // set new i2c address and force divstr (Bit 1) to value 0 (Bit 0) 8530de8e3533e08745616a30bdb3fa5106c85083e51Randy Dunlap dib3000mc_write_word(dmcst, 1024, (new_addr << 3) | 0x1); 8540de8e3533e08745616a30bdb3fa5106c85083e51Randy Dunlap dmcst->i2c_addr = new_addr; 855b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher } 8561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 857136cafbf4a024b52ba0a10627217f03cea9ff9f8Patrick Boettcher for (k = 0; k < no_of_demods; k++) { 8580de8e3533e08745616a30bdb3fa5106c85083e51Randy Dunlap dmcst->cfg = &cfg[k]; 8590de8e3533e08745616a30bdb3fa5106c85083e51Randy Dunlap dmcst->i2c_addr = DIB3000MC_I2C_ADDRESS[k]; 8601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8610de8e3533e08745616a30bdb3fa5106c85083e51Randy Dunlap dib3000mc_write_word(dmcst, 1024, dmcst->i2c_addr << 3); 8621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 863136cafbf4a024b52ba0a10627217f03cea9ff9f8Patrick Boettcher /* turn off data output */ 8640de8e3533e08745616a30bdb3fa5106c85083e51Randy Dunlap dib3000mc_set_output_mode(dmcst, OUTMODE_HIGH_Z); 865136cafbf4a024b52ba0a10627217f03cea9ff9f8Patrick Boettcher } 8660de8e3533e08745616a30bdb3fa5106c85083e51Randy Dunlap 8670de8e3533e08745616a30bdb3fa5106c85083e51Randy Dunlap kfree(dmcst); 868b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher return 0; 869136cafbf4a024b52ba0a10627217f03cea9ff9f8Patrick Boettcher} 870136cafbf4a024b52ba0a10627217f03cea9ff9f8Patrick BoettcherEXPORT_SYMBOL(dib3000mc_i2c_enumeration); 871136cafbf4a024b52ba0a10627217f03cea9ff9f8Patrick Boettcher 872136cafbf4a024b52ba0a10627217f03cea9ff9f8Patrick Boettcherstatic struct dvb_frontend_ops dib3000mc_ops; 873136cafbf4a024b52ba0a10627217f03cea9ff9f8Patrick Boettcher 874136cafbf4a024b52ba0a10627217f03cea9ff9f8Patrick Boettcherstruct dvb_frontend * dib3000mc_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib3000mc_config *cfg) 875136cafbf4a024b52ba0a10627217f03cea9ff9f8Patrick Boettcher{ 876136cafbf4a024b52ba0a10627217f03cea9ff9f8Patrick Boettcher struct dvb_frontend *demod; 877136cafbf4a024b52ba0a10627217f03cea9ff9f8Patrick Boettcher struct dib3000mc_state *st; 878136cafbf4a024b52ba0a10627217f03cea9ff9f8Patrick Boettcher st = kzalloc(sizeof(struct dib3000mc_state), GFP_KERNEL); 879136cafbf4a024b52ba0a10627217f03cea9ff9f8Patrick Boettcher if (st == NULL) 880136cafbf4a024b52ba0a10627217f03cea9ff9f8Patrick Boettcher return NULL; 881136cafbf4a024b52ba0a10627217f03cea9ff9f8Patrick Boettcher 882136cafbf4a024b52ba0a10627217f03cea9ff9f8Patrick Boettcher st->cfg = cfg; 883136cafbf4a024b52ba0a10627217f03cea9ff9f8Patrick Boettcher st->i2c_adap = i2c_adap; 8846958effedb0dc709966c22e7fd0e8210b5401b84Patrick Boettcher st->i2c_addr = i2c_addr; 885136cafbf4a024b52ba0a10627217f03cea9ff9f8Patrick Boettcher 886136cafbf4a024b52ba0a10627217f03cea9ff9f8Patrick Boettcher demod = &st->demod; 887136cafbf4a024b52ba0a10627217f03cea9ff9f8Patrick Boettcher demod->demodulator_priv = st; 888136cafbf4a024b52ba0a10627217f03cea9ff9f8Patrick Boettcher memcpy(&st->demod.ops, &dib3000mc_ops, sizeof(struct dvb_frontend_ops)); 889136cafbf4a024b52ba0a10627217f03cea9ff9f8Patrick Boettcher 890136cafbf4a024b52ba0a10627217f03cea9ff9f8Patrick Boettcher if (dib3000mc_identify(st) != 0) 891136cafbf4a024b52ba0a10627217f03cea9ff9f8Patrick Boettcher goto error; 892136cafbf4a024b52ba0a10627217f03cea9ff9f8Patrick Boettcher 893136cafbf4a024b52ba0a10627217f03cea9ff9f8Patrick Boettcher dibx000_init_i2c_master(&st->i2c_master, DIB3000MC, st->i2c_adap, st->i2c_addr); 894136cafbf4a024b52ba0a10627217f03cea9ff9f8Patrick Boettcher 895303cbeaaacd449545d259f82b966d070418c58afPatrick Boettcher dib3000mc_write_word(st, 1037, 0x3130); 896303cbeaaacd449545d259f82b966d070418c58afPatrick Boettcher 897136cafbf4a024b52ba0a10627217f03cea9ff9f8Patrick Boettcher return demod; 8981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldserror: 900136cafbf4a024b52ba0a10627217f03cea9ff9f8Patrick Boettcher kfree(st); 901136cafbf4a024b52ba0a10627217f03cea9ff9f8Patrick Boettcher return NULL; 9021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 903e4d6c1f74aaac1bbe5be50e7368e5ac99d54e5a2Patrick BoettcherEXPORT_SYMBOL(dib3000mc_attach); 9041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct dvb_frontend_ops dib3000mc_ops = { 906c1f814f49904ae5b275407f71aefd3a31c774098Mauro Carvalho Chehab .delsys = { SYS_DVBT }, 9071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .info = { 908b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher .name = "DiBcom 3000MC/P", 909b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher .frequency_min = 44250000, 910b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher .frequency_max = 867250000, 911b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher .frequency_stepsize = 62500, 9121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .caps = FE_CAN_INVERSION_AUTO | 913b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | 914b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | 915b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO | 916b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher FE_CAN_TRANSMISSION_MODE_AUTO | 917b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher FE_CAN_GUARD_INTERVAL_AUTO | 918b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher FE_CAN_RECOVER | 919b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher FE_CAN_HIERARCHY_AUTO, 9201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds }, 9211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 922b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher .release = dib3000mc_release, 9231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 924b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher .init = dib3000mc_init, 925b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher .sleep = dib3000mc_sleep, 9261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 927c1f814f49904ae5b275407f71aefd3a31c774098Mauro Carvalho Chehab .set_frontend = dib3000mc_set_frontend, 928b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher .get_tune_settings = dib3000mc_fe_get_tune_settings, 929c1f814f49904ae5b275407f71aefd3a31c774098Mauro Carvalho Chehab .get_frontend = dib3000mc_get_frontend, 9301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 931b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher .read_status = dib3000mc_read_status, 932b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher .read_ber = dib3000mc_read_ber, 9331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .read_signal_strength = dib3000mc_read_signal_strength, 934b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher .read_snr = dib3000mc_read_snr, 935b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick Boettcher .read_ucblocks = dib3000mc_read_unc_blocks, 9361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 9371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 938b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick BoettcherMODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>"); 939b7571f8d7e12cd70048331e6a0199a42dc995d99Patrick BoettcherMODULE_DESCRIPTION("Driver for the DiBcom 3000MC/P COFDM demodulator"); 9401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_LICENSE("GPL"); 941