11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 26a5cbd591c703491b62892682adc124ece67f3a9Matthias Schwarzott Driver for Zarlink VP310/MT312/ZL10313 Satellite Channel Decoder 31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds Copyright (C) 2003 Andreas Oberritter <obi@linuxtv.org> 56a5cbd591c703491b62892682adc124ece67f3a9Matthias Schwarzott Copyright (C) 2008 Matthias Schwarzott <zzam@gentoo.org> 61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds This program is free software; you can redistribute it and/or modify 81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds it under the terms of the GNU General Public License as published by 91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds the Free Software Foundation; either version 2 of the License, or 101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (at your option) any later version. 111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds This program is distributed in the hope that it will be useful, 131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds but WITHOUT ANY WARRANTY; without even the implied warranty of 141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds GNU General Public License for more details. 171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds You should have received a copy of the GNU General Public License 191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds along with this program; if not, write to the Free Software 201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds References: 231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds http://products.zarlink.com/product_profiles/MT312.htm 241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds http://products.zarlink.com/product_profiles/SL1935.htm 251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds*/ 261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/delay.h> 281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/errno.h> 291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/init.h> 301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/kernel.h> 311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/module.h> 324e57b6817880946a3a78d5d8cad1ace363f7e449Tim Schmielau#include <linux/string.h> 334e57b6817880946a3a78d5d8cad1ace363f7e449Tim Schmielau#include <linux/slab.h> 341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "dvb_frontend.h" 361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "mt312_priv.h" 371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "mt312.h" 381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 398393796dfa4cf5dffcceec464c7789bec3a2f471Mauro Carvalho Chehab/* Max transfer size done by I2C transfer functions */ 408393796dfa4cf5dffcceec464c7789bec3a2f471Mauro Carvalho Chehab#define MAX_XFER_SIZE 64 411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct mt312_state { 4389f6475857b89e956a8bcfef64944409ce4173b4Matthias Schwarzott struct i2c_adapter *i2c; 441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* configuration settings */ 4589f6475857b89e956a8bcfef64944409ce4173b4Matthias Schwarzott const struct mt312_config *config; 461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct dvb_frontend frontend; 471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 id; 49111221fb676176dc90638d6004f1c26164ddd5aeMatthias Schwarzott unsigned long xtal; 50111221fb676176dc90638d6004f1c26164ddd5aeMatthias Schwarzott u8 freq_mult; 511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int debug; 541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define dprintk(args...) \ 551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds do { \ 5689f6475857b89e956a8bcfef64944409ce4173b4Matthias Schwarzott if (debug) \ 5789f6475857b89e956a8bcfef64944409ce4173b4Matthias Schwarzott printk(KERN_DEBUG "mt312: " args); \ 581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } while (0) 591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define MT312_PLL_CLK 10000000UL /* 10 MHz */ 616a5cbd591c703491b62892682adc124ece67f3a9Matthias Schwarzott#define MT312_PLL_CLK_10_111 10111000UL /* 10.111 MHz */ 621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6389f6475857b89e956a8bcfef64944409ce4173b4Matthias Schwarzottstatic int mt312_read(struct mt312_state *state, const enum mt312_reg_addr reg, 641881ee89e0fe03ac5bba9045acb3bea1818f9466Matthias Schwarzott u8 *buf, const size_t count) 651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int ret; 671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct i2c_msg msg[2]; 681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 regbuf[1] = { reg }; 691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds msg[0].addr = state->config->demod_address; 711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds msg[0].flags = 0; 721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds msg[0].buf = regbuf; 731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds msg[0].len = 1; 741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds msg[1].addr = state->config->demod_address; 751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds msg[1].flags = I2C_M_RD; 761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds msg[1].buf = buf; 771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds msg[1].len = count; 781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ret = i2c_transfer(state->i2c, msg, 2); 801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (ret != 2) { 82302e8acc4137821cd30514da3d91ac109b461c7dMatthias Schwarzott printk(KERN_DEBUG "%s: ret == %d\n", __func__, ret); 831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EREMOTEIO; 841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8689f6475857b89e956a8bcfef64944409ce4173b4Matthias Schwarzott if (debug) { 871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i; 881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dprintk("R(%d):", reg & 0x7f); 891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < count; i++) 900389b34e7c5c2dcdef61ed1741db674b47e4dc00Matthias Schwarzott printk(KERN_CONT " %02x", buf[i]); 911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk("\n"); 921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9789f6475857b89e956a8bcfef64944409ce4173b4Matthias Schwarzottstatic int mt312_write(struct mt312_state *state, const enum mt312_reg_addr reg, 981881ee89e0fe03ac5bba9045acb3bea1818f9466Matthias Schwarzott const u8 *src, const size_t count) 991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int ret; 1018393796dfa4cf5dffcceec464c7789bec3a2f471Mauro Carvalho Chehab u8 buf[MAX_XFER_SIZE]; 1021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct i2c_msg msg; 1031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1048393796dfa4cf5dffcceec464c7789bec3a2f471Mauro Carvalho Chehab if (1 + count > sizeof(buf)) { 1058393796dfa4cf5dffcceec464c7789bec3a2f471Mauro Carvalho Chehab printk(KERN_WARNING 10635f30f36a7e66caa0973a4db620b4245df2cf428Mauro Carvalho Chehab "mt312: write: len=%zu is too big!\n", count); 1078393796dfa4cf5dffcceec464c7789bec3a2f471Mauro Carvalho Chehab return -EINVAL; 1088393796dfa4cf5dffcceec464c7789bec3a2f471Mauro Carvalho Chehab } 1098393796dfa4cf5dffcceec464c7789bec3a2f471Mauro Carvalho Chehab 11089f6475857b89e956a8bcfef64944409ce4173b4Matthias Schwarzott if (debug) { 1111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i; 1121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dprintk("W(%d):", reg & 0x7f); 1131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < count; i++) 1140389b34e7c5c2dcdef61ed1741db674b47e4dc00Matthias Schwarzott printk(KERN_CONT " %02x", src[i]); 1151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk("\n"); 1161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds buf[0] = reg; 1191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds memcpy(&buf[1], src, count); 1201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds msg.addr = state->config->demod_address; 1221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds msg.flags = 0; 1231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds msg.buf = buf; 1241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds msg.len = count + 1; 1251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ret = i2c_transfer(state->i2c, &msg, 1); 1271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (ret != 1) { 129271ddbf702c3a4e6b18f6464180eda0f62efd9a5Harvey Harrison dprintk("%s: ret == %d\n", __func__, ret); 1301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EREMOTEIO; 1311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 1341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13689f6475857b89e956a8bcfef64944409ce4173b4Matthias Schwarzottstatic inline int mt312_readreg(struct mt312_state *state, 1371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds const enum mt312_reg_addr reg, u8 *val) 1381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return mt312_read(state, reg, val, 1); 1401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14289f6475857b89e956a8bcfef64944409ce4173b4Matthias Schwarzottstatic inline int mt312_writereg(struct mt312_state *state, 1431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds const enum mt312_reg_addr reg, const u8 val) 1441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return mt312_write(state, reg, &val, 1); 1461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic inline u32 mt312_div(u32 a, u32 b) 1491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (a + (b / 2)) / b; 1511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15389f6475857b89e956a8bcfef64944409ce4173b4Matthias Schwarzottstatic int mt312_reset(struct mt312_state *state, const u8 full) 1541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return mt312_writereg(state, RESET, full ? 0x80 : 0x40); 1561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 15889f6475857b89e956a8bcfef64944409ce4173b4Matthias Schwarzottstatic int mt312_get_inversion(struct mt312_state *state, 1591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fe_spectral_inversion_t *i) 1601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int ret; 1621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 vit_mode; 1631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 164994fc28b6cd087cf6ef8d3ebd4eeef97c8194e4eMatthias Schwarzott ret = mt312_readreg(state, VIT_MODE, &vit_mode); 165994fc28b6cd087cf6ef8d3ebd4eeef97c8194e4eMatthias Schwarzott if (ret < 0) 1661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ret; 1671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (vit_mode & 0x80) /* auto inversion was used */ 1691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *i = (vit_mode & 0x40) ? INVERSION_ON : INVERSION_OFF; 1701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 1721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 17489f6475857b89e956a8bcfef64944409ce4173b4Matthias Schwarzottstatic int mt312_get_symbol_rate(struct mt312_state *state, u32 *sr) 1751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int ret; 1771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 sym_rate_h; 1781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 dec_ratio; 1791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u16 sym_rat_op; 1801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u16 monitor; 1811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 buf[2]; 1821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 183994fc28b6cd087cf6ef8d3ebd4eeef97c8194e4eMatthias Schwarzott ret = mt312_readreg(state, SYM_RATE_H, &sym_rate_h); 184994fc28b6cd087cf6ef8d3ebd4eeef97c8194e4eMatthias Schwarzott if (ret < 0) 1851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ret; 1861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 18789f6475857b89e956a8bcfef64944409ce4173b4Matthias Schwarzott if (sym_rate_h & 0x80) { 18889f6475857b89e956a8bcfef64944409ce4173b4Matthias Schwarzott /* symbol rate search was used */ 189994fc28b6cd087cf6ef8d3ebd4eeef97c8194e4eMatthias Schwarzott ret = mt312_writereg(state, MON_CTRL, 0x03); 190994fc28b6cd087cf6ef8d3ebd4eeef97c8194e4eMatthias Schwarzott if (ret < 0) 1911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ret; 1921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 193994fc28b6cd087cf6ef8d3ebd4eeef97c8194e4eMatthias Schwarzott ret = mt312_read(state, MONITOR_H, buf, sizeof(buf)); 194994fc28b6cd087cf6ef8d3ebd4eeef97c8194e4eMatthias Schwarzott if (ret < 0) 1951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ret; 1961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds monitor = (buf[0] << 8) | buf[1]; 1981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1990b6a3342a645208feaab76332f1eee33e1688bd5Matthias Schwarzott dprintk("sr(auto) = %u\n", 2001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mt312_div(monitor * 15625, 4)); 2011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 202994fc28b6cd087cf6ef8d3ebd4eeef97c8194e4eMatthias Schwarzott ret = mt312_writereg(state, MON_CTRL, 0x05); 203994fc28b6cd087cf6ef8d3ebd4eeef97c8194e4eMatthias Schwarzott if (ret < 0) 2041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ret; 2051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 206994fc28b6cd087cf6ef8d3ebd4eeef97c8194e4eMatthias Schwarzott ret = mt312_read(state, MONITOR_H, buf, sizeof(buf)); 207994fc28b6cd087cf6ef8d3ebd4eeef97c8194e4eMatthias Schwarzott if (ret < 0) 2081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ret; 2091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dec_ratio = ((buf[0] >> 5) & 0x07) * 32; 2111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 212994fc28b6cd087cf6ef8d3ebd4eeef97c8194e4eMatthias Schwarzott ret = mt312_read(state, SYM_RAT_OP_H, buf, sizeof(buf)); 213994fc28b6cd087cf6ef8d3ebd4eeef97c8194e4eMatthias Schwarzott if (ret < 0) 2141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ret; 2151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sym_rat_op = (buf[0] << 8) | buf[1]; 2171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2180b6a3342a645208feaab76332f1eee33e1688bd5Matthias Schwarzott dprintk("sym_rat_op=%d dec_ratio=%d\n", 2191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds sym_rat_op, dec_ratio); 2200b6a3342a645208feaab76332f1eee33e1688bd5Matthias Schwarzott dprintk("*sr(manual) = %lu\n", 221111221fb676176dc90638d6004f1c26164ddd5aeMatthias Schwarzott (((state->xtal * 8192) / (sym_rat_op + 8192)) * 2221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2) - dec_ratio); 2231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 2261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 22889f6475857b89e956a8bcfef64944409ce4173b4Matthias Schwarzottstatic int mt312_get_code_rate(struct mt312_state *state, fe_code_rate_t *cr) 2291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds const fe_code_rate_t fec_tab[8] = 2311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { FEC_1_2, FEC_2_3, FEC_3_4, FEC_5_6, FEC_6_7, FEC_7_8, 2321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FEC_AUTO, FEC_AUTO }; 2331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int ret; 2351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 fec_status; 2361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 237994fc28b6cd087cf6ef8d3ebd4eeef97c8194e4eMatthias Schwarzott ret = mt312_readreg(state, FEC_STATUS, &fec_status); 238994fc28b6cd087cf6ef8d3ebd4eeef97c8194e4eMatthias Schwarzott if (ret < 0) 2391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ret; 2401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *cr = fec_tab[(fec_status >> 4) & 0x07]; 2421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 2441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 24689f6475857b89e956a8bcfef64944409ce4173b4Matthias Schwarzottstatic int mt312_initfe(struct dvb_frontend *fe) 2471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 248b8742700f13163ffa00cddce2a3c940b9ab2ab5aJohannes Stezenbach struct mt312_state *state = fe->demodulator_priv; 2491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int ret; 2501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 buf[2]; 2511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* wake up */ 253994fc28b6cd087cf6ef8d3ebd4eeef97c8194e4eMatthias Schwarzott ret = mt312_writereg(state, CONFIG, 254111221fb676176dc90638d6004f1c26164ddd5aeMatthias Schwarzott (state->freq_mult == 6 ? 0x88 : 0x8c)); 255994fc28b6cd087cf6ef8d3ebd4eeef97c8194e4eMatthias Schwarzott if (ret < 0) 2561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ret; 2571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* wait at least 150 usec */ 2591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds udelay(150); 2601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* full reset */ 262994fc28b6cd087cf6ef8d3ebd4eeef97c8194e4eMatthias Schwarzott ret = mt312_reset(state, 1); 263994fc28b6cd087cf6ef8d3ebd4eeef97c8194e4eMatthias Schwarzott if (ret < 0) 2641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ret; 2651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 26689f6475857b89e956a8bcfef64944409ce4173b4Matthias Schwarzott/* Per datasheet, write correct values. 09/28/03 ACCJr. 26789f6475857b89e956a8bcfef64944409ce4173b4Matthias Schwarzott * If we don't do this, we won't get FE_HAS_VITERBI in the VP310. */ 2681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 26989f6475857b89e956a8bcfef64944409ce4173b4Matthias Schwarzott u8 buf_def[8] = { 0x14, 0x12, 0x03, 0x02, 27089f6475857b89e956a8bcfef64944409ce4173b4Matthias Schwarzott 0x01, 0x00, 0x00, 0x00 }; 2711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 272994fc28b6cd087cf6ef8d3ebd4eeef97c8194e4eMatthias Schwarzott ret = mt312_write(state, VIT_SETUP, buf_def, sizeof(buf_def)); 273994fc28b6cd087cf6ef8d3ebd4eeef97c8194e4eMatthias Schwarzott if (ret < 0) 2741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ret; 2751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2776a5cbd591c703491b62892682adc124ece67f3a9Matthias Schwarzott switch (state->id) { 2786a5cbd591c703491b62892682adc124ece67f3a9Matthias Schwarzott case ID_ZL10313: 2796a5cbd591c703491b62892682adc124ece67f3a9Matthias Schwarzott /* enable ADC */ 2806a5cbd591c703491b62892682adc124ece67f3a9Matthias Schwarzott ret = mt312_writereg(state, GPP_CTRL, 0x80); 2816a5cbd591c703491b62892682adc124ece67f3a9Matthias Schwarzott if (ret < 0) 2826a5cbd591c703491b62892682adc124ece67f3a9Matthias Schwarzott return ret; 2836a5cbd591c703491b62892682adc124ece67f3a9Matthias Schwarzott 2846a5cbd591c703491b62892682adc124ece67f3a9Matthias Schwarzott /* configure ZL10313 for optimal ADC performance */ 2856a5cbd591c703491b62892682adc124ece67f3a9Matthias Schwarzott buf[0] = 0x80; 2866a5cbd591c703491b62892682adc124ece67f3a9Matthias Schwarzott buf[1] = 0xB0; 2876a5cbd591c703491b62892682adc124ece67f3a9Matthias Schwarzott ret = mt312_write(state, HW_CTRL, buf, 2); 2886a5cbd591c703491b62892682adc124ece67f3a9Matthias Schwarzott if (ret < 0) 2896a5cbd591c703491b62892682adc124ece67f3a9Matthias Schwarzott return ret; 2906a5cbd591c703491b62892682adc124ece67f3a9Matthias Schwarzott 2916a5cbd591c703491b62892682adc124ece67f3a9Matthias Schwarzott /* enable MPEG output and ADCs */ 2926a5cbd591c703491b62892682adc124ece67f3a9Matthias Schwarzott ret = mt312_writereg(state, HW_CTRL, 0x00); 2936a5cbd591c703491b62892682adc124ece67f3a9Matthias Schwarzott if (ret < 0) 2946a5cbd591c703491b62892682adc124ece67f3a9Matthias Schwarzott return ret; 2956a5cbd591c703491b62892682adc124ece67f3a9Matthias Schwarzott 2966a5cbd591c703491b62892682adc124ece67f3a9Matthias Schwarzott ret = mt312_writereg(state, MPEG_CTRL, 0x00); 2976a5cbd591c703491b62892682adc124ece67f3a9Matthias Schwarzott if (ret < 0) 2986a5cbd591c703491b62892682adc124ece67f3a9Matthias Schwarzott return ret; 2996a5cbd591c703491b62892682adc124ece67f3a9Matthias Schwarzott 3006a5cbd591c703491b62892682adc124ece67f3a9Matthias Schwarzott break; 3016a5cbd591c703491b62892682adc124ece67f3a9Matthias Schwarzott } 3026a5cbd591c703491b62892682adc124ece67f3a9Matthias Schwarzott 3031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* SYS_CLK */ 304111221fb676176dc90638d6004f1c26164ddd5aeMatthias Schwarzott buf[0] = mt312_div(state->xtal * state->freq_mult * 2, 1000000); 3051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* DISEQC_RATIO */ 307111221fb676176dc90638d6004f1c26164ddd5aeMatthias Schwarzott buf[1] = mt312_div(state->xtal, 22000 * 4); 3081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 309994fc28b6cd087cf6ef8d3ebd4eeef97c8194e4eMatthias Schwarzott ret = mt312_write(state, SYS_CLK, buf, sizeof(buf)); 310994fc28b6cd087cf6ef8d3ebd4eeef97c8194e4eMatthias Schwarzott if (ret < 0) 3111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ret; 3121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 313994fc28b6cd087cf6ef8d3ebd4eeef97c8194e4eMatthias Schwarzott ret = mt312_writereg(state, SNR_THS_HIGH, 0x32); 314994fc28b6cd087cf6ef8d3ebd4eeef97c8194e4eMatthias Schwarzott if (ret < 0) 3151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ret; 3161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3176a5cbd591c703491b62892682adc124ece67f3a9Matthias Schwarzott /* different MOCLK polarity */ 3186a5cbd591c703491b62892682adc124ece67f3a9Matthias Schwarzott switch (state->id) { 3196a5cbd591c703491b62892682adc124ece67f3a9Matthias Schwarzott case ID_ZL10313: 3206a5cbd591c703491b62892682adc124ece67f3a9Matthias Schwarzott buf[0] = 0x33; 3216a5cbd591c703491b62892682adc124ece67f3a9Matthias Schwarzott break; 3226a5cbd591c703491b62892682adc124ece67f3a9Matthias Schwarzott default: 3236a5cbd591c703491b62892682adc124ece67f3a9Matthias Schwarzott buf[0] = 0x53; 3246a5cbd591c703491b62892682adc124ece67f3a9Matthias Schwarzott break; 3256a5cbd591c703491b62892682adc124ece67f3a9Matthias Schwarzott } 3266a5cbd591c703491b62892682adc124ece67f3a9Matthias Schwarzott 3276a5cbd591c703491b62892682adc124ece67f3a9Matthias Schwarzott ret = mt312_writereg(state, OP_CTRL, buf[0]); 328994fc28b6cd087cf6ef8d3ebd4eeef97c8194e4eMatthias Schwarzott if (ret < 0) 3291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ret; 3301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* TS_SW_LIM */ 3321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds buf[0] = 0x8c; 3331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds buf[1] = 0x98; 3341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 335994fc28b6cd087cf6ef8d3ebd4eeef97c8194e4eMatthias Schwarzott ret = mt312_write(state, TS_SW_LIM_L, buf, sizeof(buf)); 336994fc28b6cd087cf6ef8d3ebd4eeef97c8194e4eMatthias Schwarzott if (ret < 0) 3371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ret; 3381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 339994fc28b6cd087cf6ef8d3ebd4eeef97c8194e4eMatthias Schwarzott ret = mt312_writereg(state, CS_SW_LIM, 0x69); 340994fc28b6cd087cf6ef8d3ebd4eeef97c8194e4eMatthias Schwarzott if (ret < 0) 3411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ret; 3421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 3441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 34689f6475857b89e956a8bcfef64944409ce4173b4Matthias Schwarzottstatic int mt312_send_master_cmd(struct dvb_frontend *fe, 3471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct dvb_diseqc_master_cmd *c) 3481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 349b8742700f13163ffa00cddce2a3c940b9ab2ab5aJohannes Stezenbach struct mt312_state *state = fe->demodulator_priv; 3501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int ret; 3511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 diseqc_mode; 3521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if ((c->msg_len == 0) || (c->msg_len > sizeof(c->msg))) 3541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EINVAL; 3551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 356994fc28b6cd087cf6ef8d3ebd4eeef97c8194e4eMatthias Schwarzott ret = mt312_readreg(state, DISEQC_MODE, &diseqc_mode); 357994fc28b6cd087cf6ef8d3ebd4eeef97c8194e4eMatthias Schwarzott if (ret < 0) 3581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ret; 3591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 360994fc28b6cd087cf6ef8d3ebd4eeef97c8194e4eMatthias Schwarzott ret = mt312_write(state, (0x80 | DISEQC_INSTR), c->msg, c->msg_len); 361994fc28b6cd087cf6ef8d3ebd4eeef97c8194e4eMatthias Schwarzott if (ret < 0) 3621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ret; 3631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 364994fc28b6cd087cf6ef8d3ebd4eeef97c8194e4eMatthias Schwarzott ret = mt312_writereg(state, DISEQC_MODE, 365994fc28b6cd087cf6ef8d3ebd4eeef97c8194e4eMatthias Schwarzott (diseqc_mode & 0x40) | ((c->msg_len - 1) << 3) 366994fc28b6cd087cf6ef8d3ebd4eeef97c8194e4eMatthias Schwarzott | 0x04); 367994fc28b6cd087cf6ef8d3ebd4eeef97c8194e4eMatthias Schwarzott if (ret < 0) 3681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ret; 3691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 37082cd2dff4a5562a081c8bbf449a1ae7b9ecb5b1bMatthias Schwarzott /* is there a better way to wait for message to be transmitted */ 37182cd2dff4a5562a081c8bbf449a1ae7b9ecb5b1bMatthias Schwarzott msleep(100); 37282cd2dff4a5562a081c8bbf449a1ae7b9ecb5b1bMatthias Schwarzott 3731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* set DISEQC_MODE[2:0] to zero if a return message is expected */ 374994fc28b6cd087cf6ef8d3ebd4eeef97c8194e4eMatthias Schwarzott if (c->msg[0] & 0x02) { 375994fc28b6cd087cf6ef8d3ebd4eeef97c8194e4eMatthias Schwarzott ret = mt312_writereg(state, DISEQC_MODE, (diseqc_mode & 0x40)); 376994fc28b6cd087cf6ef8d3ebd4eeef97c8194e4eMatthias Schwarzott if (ret < 0) 3771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ret; 378994fc28b6cd087cf6ef8d3ebd4eeef97c8194e4eMatthias Schwarzott } 3791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 3811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 38389f6475857b89e956a8bcfef64944409ce4173b4Matthias Schwarzottstatic int mt312_send_burst(struct dvb_frontend *fe, const fe_sec_mini_cmd_t c) 3841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 385b8742700f13163ffa00cddce2a3c940b9ab2ab5aJohannes Stezenbach struct mt312_state *state = fe->demodulator_priv; 3861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds const u8 mini_tab[2] = { 0x02, 0x03 }; 3871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int ret; 3891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 diseqc_mode; 3901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (c > SEC_MINI_B) 3921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EINVAL; 3931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 394994fc28b6cd087cf6ef8d3ebd4eeef97c8194e4eMatthias Schwarzott ret = mt312_readreg(state, DISEQC_MODE, &diseqc_mode); 395994fc28b6cd087cf6ef8d3ebd4eeef97c8194e4eMatthias Schwarzott if (ret < 0) 3961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ret; 3971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 398994fc28b6cd087cf6ef8d3ebd4eeef97c8194e4eMatthias Schwarzott ret = mt312_writereg(state, DISEQC_MODE, 399994fc28b6cd087cf6ef8d3ebd4eeef97c8194e4eMatthias Schwarzott (diseqc_mode & 0x40) | mini_tab[c]); 400994fc28b6cd087cf6ef8d3ebd4eeef97c8194e4eMatthias Schwarzott if (ret < 0) 4011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ret; 4021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 4041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 40689f6475857b89e956a8bcfef64944409ce4173b4Matthias Schwarzottstatic int mt312_set_tone(struct dvb_frontend *fe, const fe_sec_tone_mode_t t) 4071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 408b8742700f13163ffa00cddce2a3c940b9ab2ab5aJohannes Stezenbach struct mt312_state *state = fe->demodulator_priv; 4091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds const u8 tone_tab[2] = { 0x01, 0x00 }; 4101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int ret; 4121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 diseqc_mode; 4131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (t > SEC_TONE_OFF) 4151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EINVAL; 4161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 417994fc28b6cd087cf6ef8d3ebd4eeef97c8194e4eMatthias Schwarzott ret = mt312_readreg(state, DISEQC_MODE, &diseqc_mode); 418994fc28b6cd087cf6ef8d3ebd4eeef97c8194e4eMatthias Schwarzott if (ret < 0) 4191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ret; 4201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 421994fc28b6cd087cf6ef8d3ebd4eeef97c8194e4eMatthias Schwarzott ret = mt312_writereg(state, DISEQC_MODE, 422994fc28b6cd087cf6ef8d3ebd4eeef97c8194e4eMatthias Schwarzott (diseqc_mode & 0x40) | tone_tab[t]); 423994fc28b6cd087cf6ef8d3ebd4eeef97c8194e4eMatthias Schwarzott if (ret < 0) 4241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ret; 4251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 4271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 42989f6475857b89e956a8bcfef64944409ce4173b4Matthias Schwarzottstatic int mt312_set_voltage(struct dvb_frontend *fe, const fe_sec_voltage_t v) 4301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 431b8742700f13163ffa00cddce2a3c940b9ab2ab5aJohannes Stezenbach struct mt312_state *state = fe->demodulator_priv; 4321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds const u8 volt_tab[3] = { 0x00, 0x40, 0x00 }; 43311d3f323930ef625c1018ed13adeb04127c356e0Matthias Schwarzott u8 val; 4341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (v > SEC_VOLTAGE_OFF) 4361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EINVAL; 4371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 43811d3f323930ef625c1018ed13adeb04127c356e0Matthias Schwarzott val = volt_tab[v]; 43911d3f323930ef625c1018ed13adeb04127c356e0Matthias Schwarzott if (state->config->voltage_inverted) 44011d3f323930ef625c1018ed13adeb04127c356e0Matthias Schwarzott val ^= 0x40; 44111d3f323930ef625c1018ed13adeb04127c356e0Matthias Schwarzott 44211d3f323930ef625c1018ed13adeb04127c356e0Matthias Schwarzott return mt312_writereg(state, DISEQC_MODE, val); 4431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 44589f6475857b89e956a8bcfef64944409ce4173b4Matthias Schwarzottstatic int mt312_read_status(struct dvb_frontend *fe, fe_status_t *s) 4461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 447b8742700f13163ffa00cddce2a3c940b9ab2ab5aJohannes Stezenbach struct mt312_state *state = fe->demodulator_priv; 4481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int ret; 4491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 status[3]; 4501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *s = 0; 4521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 453994fc28b6cd087cf6ef8d3ebd4eeef97c8194e4eMatthias Schwarzott ret = mt312_read(state, QPSK_STAT_H, status, sizeof(status)); 454994fc28b6cd087cf6ef8d3ebd4eeef97c8194e4eMatthias Schwarzott if (ret < 0) 4551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ret; 4561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4570b6a3342a645208feaab76332f1eee33e1688bd5Matthias Schwarzott dprintk("QPSK_STAT_H: 0x%02x, QPSK_STAT_L: 0x%02x," 45889f6475857b89e956a8bcfef64944409ce4173b4Matthias Schwarzott " FEC_STATUS: 0x%02x\n", status[0], status[1], status[2]); 4591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (status[0] & 0xc0) 4611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *s |= FE_HAS_SIGNAL; /* signal noise ratio */ 4621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (status[0] & 0x04) 4631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *s |= FE_HAS_CARRIER; /* qpsk carrier lock */ 4641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (status[2] & 0x02) 4651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *s |= FE_HAS_VITERBI; /* viterbi lock */ 4661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (status[2] & 0x04) 4671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *s |= FE_HAS_SYNC; /* byte align lock */ 4681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (status[0] & 0x01) 4691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *s |= FE_HAS_LOCK; /* qpsk lock */ 4701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 4721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 47489f6475857b89e956a8bcfef64944409ce4173b4Matthias Schwarzottstatic int mt312_read_ber(struct dvb_frontend *fe, u32 *ber) 4751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 476b8742700f13163ffa00cddce2a3c940b9ab2ab5aJohannes Stezenbach struct mt312_state *state = fe->demodulator_priv; 4771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int ret; 4781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 buf[3]; 4791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 480994fc28b6cd087cf6ef8d3ebd4eeef97c8194e4eMatthias Schwarzott ret = mt312_read(state, RS_BERCNT_H, buf, 3); 481994fc28b6cd087cf6ef8d3ebd4eeef97c8194e4eMatthias Schwarzott if (ret < 0) 4821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ret; 4831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *ber = ((buf[0] << 16) | (buf[1] << 8) | buf[2]) * 64; 4851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 4871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 48989f6475857b89e956a8bcfef64944409ce4173b4Matthias Schwarzottstatic int mt312_read_signal_strength(struct dvb_frontend *fe, 49089f6475857b89e956a8bcfef64944409ce4173b4Matthias Schwarzott u16 *signal_strength) 4911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 492b8742700f13163ffa00cddce2a3c940b9ab2ab5aJohannes Stezenbach struct mt312_state *state = fe->demodulator_priv; 4931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int ret; 4941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 buf[3]; 4951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u16 agc; 4961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds s16 err_db; 4971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 498994fc28b6cd087cf6ef8d3ebd4eeef97c8194e4eMatthias Schwarzott ret = mt312_read(state, AGC_H, buf, sizeof(buf)); 499994fc28b6cd087cf6ef8d3ebd4eeef97c8194e4eMatthias Schwarzott if (ret < 0) 5001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ret; 5011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds agc = (buf[0] << 6) | (buf[1] >> 2); 5031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds err_db = (s16) (((buf[1] & 0x03) << 14) | buf[2] << 6) >> 6; 5041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *signal_strength = agc; 5061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5070b6a3342a645208feaab76332f1eee33e1688bd5Matthias Schwarzott dprintk("agc=%08x err_db=%hd\n", agc, err_db); 5081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 5101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 51289f6475857b89e956a8bcfef64944409ce4173b4Matthias Schwarzottstatic int mt312_read_snr(struct dvb_frontend *fe, u16 *snr) 5131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 514b8742700f13163ffa00cddce2a3c940b9ab2ab5aJohannes Stezenbach struct mt312_state *state = fe->demodulator_priv; 5151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int ret; 5161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 buf[2]; 5171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5181881ee89e0fe03ac5bba9045acb3bea1818f9466Matthias Schwarzott ret = mt312_read(state, M_SNR_H, buf, sizeof(buf)); 519994fc28b6cd087cf6ef8d3ebd4eeef97c8194e4eMatthias Schwarzott if (ret < 0) 5201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ret; 5211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *snr = 0xFFFF - ((((buf[0] & 0x7f) << 8) | buf[1]) << 1); 5231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 5251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 52789f6475857b89e956a8bcfef64944409ce4173b4Matthias Schwarzottstatic int mt312_read_ucblocks(struct dvb_frontend *fe, u32 *ubc) 5281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 529b8742700f13163ffa00cddce2a3c940b9ab2ab5aJohannes Stezenbach struct mt312_state *state = fe->demodulator_priv; 5301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int ret; 5311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 buf[2]; 5321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5331881ee89e0fe03ac5bba9045acb3bea1818f9466Matthias Schwarzott ret = mt312_read(state, RS_UBC_H, buf, sizeof(buf)); 534994fc28b6cd087cf6ef8d3ebd4eeef97c8194e4eMatthias Schwarzott if (ret < 0) 5351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ret; 5361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *ubc = (buf[0] << 8) | buf[1]; 5381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 5401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 542827b5f3e30296f5ddeedc0c0359b1db77fd499a6Mauro Carvalho Chehabstatic int mt312_set_frontend(struct dvb_frontend *fe) 5431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 544827b5f3e30296f5ddeedc0c0359b1db77fd499a6Mauro Carvalho Chehab struct dtv_frontend_properties *p = &fe->dtv_property_cache; 545b8742700f13163ffa00cddce2a3c940b9ab2ab5aJohannes Stezenbach struct mt312_state *state = fe->demodulator_priv; 5461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int ret; 5471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 buf[5], config_val; 5481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u16 sr; 5491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds const u8 fec_tab[10] = 5511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 0x00, 0x01, 0x02, 0x04, 0x3f, 0x08, 0x10, 0x20, 0x3f, 0x3f }; 5521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds const u8 inv_tab[3] = { 0x00, 0x40, 0x80 }; 5531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 554271ddbf702c3a4e6b18f6464180eda0f62efd9a5Harvey Harrison dprintk("%s: Freq %d\n", __func__, p->frequency); 5551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 556dea74869f3c62b0b7addd67017b22b394e942aacPatrick Boettcher if ((p->frequency < fe->ops.info.frequency_min) 557dea74869f3c62b0b7addd67017b22b394e942aacPatrick Boettcher || (p->frequency > fe->ops.info.frequency_max)) 5581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EINVAL; 5591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 560830e4b55b02b8a2638958e4249eba71797940ee5Mauro Carvalho Chehab if (((int)p->inversion < INVERSION_OFF) 5611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds || (p->inversion > INVERSION_ON)) 5621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EINVAL; 5631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 564827b5f3e30296f5ddeedc0c0359b1db77fd499a6Mauro Carvalho Chehab if ((p->symbol_rate < fe->ops.info.symbol_rate_min) 565827b5f3e30296f5ddeedc0c0359b1db77fd499a6Mauro Carvalho Chehab || (p->symbol_rate > fe->ops.info.symbol_rate_max)) 5661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EINVAL; 5671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 568830e4b55b02b8a2638958e4249eba71797940ee5Mauro Carvalho Chehab if (((int)p->fec_inner < FEC_NONE) 569827b5f3e30296f5ddeedc0c0359b1db77fd499a6Mauro Carvalho Chehab || (p->fec_inner > FEC_AUTO)) 5701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EINVAL; 5711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 572827b5f3e30296f5ddeedc0c0359b1db77fd499a6Mauro Carvalho Chehab if ((p->fec_inner == FEC_4_5) 573827b5f3e30296f5ddeedc0c0359b1db77fd499a6Mauro Carvalho Chehab || (p->fec_inner == FEC_8_9)) 5741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EINVAL; 5751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (state->id) { 5771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case ID_VP310: 57889f6475857b89e956a8bcfef64944409ce4173b4Matthias Schwarzott /* For now we will do this only for the VP310. 57989f6475857b89e956a8bcfef64944409ce4173b4Matthias Schwarzott * It should be better for the mt312 as well, 58089f6475857b89e956a8bcfef64944409ce4173b4Matthias Schwarzott * but tuning will be slower. ACCJr 09/29/03 58189f6475857b89e956a8bcfef64944409ce4173b4Matthias Schwarzott */ 582682e852e2638ed0aff84aa51181c9e5d2f939562Alexey Dobriyan ret = mt312_readreg(state, CONFIG, &config_val); 583682e852e2638ed0aff84aa51181c9e5d2f939562Alexey Dobriyan if (ret < 0) 5841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ret; 585827b5f3e30296f5ddeedc0c0359b1db77fd499a6Mauro Carvalho Chehab if (p->symbol_rate >= 30000000) { 58689f6475857b89e956a8bcfef64944409ce4173b4Matthias Schwarzott /* Note that 30MS/s should use 90MHz */ 587111221fb676176dc90638d6004f1c26164ddd5aeMatthias Schwarzott if (state->freq_mult == 6) { 58889f6475857b89e956a8bcfef64944409ce4173b4Matthias Schwarzott /* We are running 60MHz */ 589111221fb676176dc90638d6004f1c26164ddd5aeMatthias Schwarzott state->freq_mult = 9; 590994fc28b6cd087cf6ef8d3ebd4eeef97c8194e4eMatthias Schwarzott ret = mt312_initfe(fe); 591994fc28b6cd087cf6ef8d3ebd4eeef97c8194e4eMatthias Schwarzott if (ret < 0) 5921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ret; 5931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 59489f6475857b89e956a8bcfef64944409ce4173b4Matthias Schwarzott } else { 595111221fb676176dc90638d6004f1c26164ddd5aeMatthias Schwarzott if (state->freq_mult == 9) { 59689f6475857b89e956a8bcfef64944409ce4173b4Matthias Schwarzott /* We are running 90MHz */ 597111221fb676176dc90638d6004f1c26164ddd5aeMatthias Schwarzott state->freq_mult = 6; 598994fc28b6cd087cf6ef8d3ebd4eeef97c8194e4eMatthias Schwarzott ret = mt312_initfe(fe); 599994fc28b6cd087cf6ef8d3ebd4eeef97c8194e4eMatthias Schwarzott if (ret < 0) 6001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ret; 6011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 6041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case ID_MT312: 6066a5cbd591c703491b62892682adc124ece67f3a9Matthias Schwarzott case ID_ZL10313: 6071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 6081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 6101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EINVAL; 6111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 613dea74869f3c62b0b7addd67017b22b394e942aacPatrick Boettcher if (fe->ops.tuner_ops.set_params) { 61414d24d148c7521b2b88b396652e36f55d061e195Mauro Carvalho Chehab fe->ops.tuner_ops.set_params(fe); 61589f6475857b89e956a8bcfef64944409ce4173b4Matthias Schwarzott if (fe->ops.i2c_gate_ctrl) 61689f6475857b89e956a8bcfef64944409ce4173b4Matthias Schwarzott fe->ops.i2c_gate_ctrl(fe, 0); 617a81870e00bf502db2c579dcb9721adab3775ba58Andrew de Quincey } 6181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* sr = (u16)(sr * 256.0 / 1000000.0) */ 620827b5f3e30296f5ddeedc0c0359b1db77fd499a6Mauro Carvalho Chehab sr = mt312_div(p->symbol_rate * 4, 15625); 6211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* SYM_RATE */ 6231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds buf[0] = (sr >> 8) & 0x3f; 6241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds buf[1] = (sr >> 0) & 0xff; 6251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* VIT_MODE */ 627827b5f3e30296f5ddeedc0c0359b1db77fd499a6Mauro Carvalho Chehab buf[2] = inv_tab[p->inversion] | fec_tab[p->fec_inner]; 6281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* QPSK_CTRL */ 6301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds buf[3] = 0x40; /* swap I and Q before QPSK demodulation */ 6311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 632827b5f3e30296f5ddeedc0c0359b1db77fd499a6Mauro Carvalho Chehab if (p->symbol_rate < 10000000) 6331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds buf[3] |= 0x04; /* use afc mode */ 6341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* GO */ 6361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds buf[4] = 0x01; 6371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 638994fc28b6cd087cf6ef8d3ebd4eeef97c8194e4eMatthias Schwarzott ret = mt312_write(state, SYM_RATE_H, buf, sizeof(buf)); 639994fc28b6cd087cf6ef8d3ebd4eeef97c8194e4eMatthias Schwarzott if (ret < 0) 6401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ret; 6411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6429101e6222cb115240e24160bb90cce425bb74de5Mauro Carvalho Chehab mt312_reset(state, 0); 6431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 6451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 6461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6477c61d80a9bcfc3fdec8ffd75756cad6a64678229Mauro Carvalho Chehabstatic int mt312_get_frontend(struct dvb_frontend *fe) 6481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 6497c61d80a9bcfc3fdec8ffd75756cad6a64678229Mauro Carvalho Chehab struct dtv_frontend_properties *p = &fe->dtv_property_cache; 650b8742700f13163ffa00cddce2a3c940b9ab2ab5aJohannes Stezenbach struct mt312_state *state = fe->demodulator_priv; 6511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int ret; 6521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 653994fc28b6cd087cf6ef8d3ebd4eeef97c8194e4eMatthias Schwarzott ret = mt312_get_inversion(state, &p->inversion); 654994fc28b6cd087cf6ef8d3ebd4eeef97c8194e4eMatthias Schwarzott if (ret < 0) 6551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ret; 6561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 657827b5f3e30296f5ddeedc0c0359b1db77fd499a6Mauro Carvalho Chehab ret = mt312_get_symbol_rate(state, &p->symbol_rate); 658994fc28b6cd087cf6ef8d3ebd4eeef97c8194e4eMatthias Schwarzott if (ret < 0) 6591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ret; 6601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 661827b5f3e30296f5ddeedc0c0359b1db77fd499a6Mauro Carvalho Chehab ret = mt312_get_code_rate(state, &p->fec_inner); 662994fc28b6cd087cf6ef8d3ebd4eeef97c8194e4eMatthias Schwarzott if (ret < 0) 6631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ret; 6641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 6661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 6671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 66889f6475857b89e956a8bcfef64944409ce4173b4Matthias Schwarzottstatic int mt312_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) 669a81870e00bf502db2c579dcb9721adab3775ba58Andrew de Quincey{ 67089f6475857b89e956a8bcfef64944409ce4173b4Matthias Schwarzott struct mt312_state *state = fe->demodulator_priv; 671a81870e00bf502db2c579dcb9721adab3775ba58Andrew de Quincey 6726a5cbd591c703491b62892682adc124ece67f3a9Matthias Schwarzott u8 val = 0x00; 6736a5cbd591c703491b62892682adc124ece67f3a9Matthias Schwarzott int ret; 6746a5cbd591c703491b62892682adc124ece67f3a9Matthias Schwarzott 6756a5cbd591c703491b62892682adc124ece67f3a9Matthias Schwarzott switch (state->id) { 6766a5cbd591c703491b62892682adc124ece67f3a9Matthias Schwarzott case ID_ZL10313: 6776a5cbd591c703491b62892682adc124ece67f3a9Matthias Schwarzott ret = mt312_readreg(state, GPP_CTRL, &val); 6786a5cbd591c703491b62892682adc124ece67f3a9Matthias Schwarzott if (ret < 0) 6796a5cbd591c703491b62892682adc124ece67f3a9Matthias Schwarzott goto error; 6806a5cbd591c703491b62892682adc124ece67f3a9Matthias Schwarzott 68125985edcedea6396277003854657b5f3cb31a628Lucas De Marchi /* preserve this bit to not accidentally shutdown ADC */ 6826a5cbd591c703491b62892682adc124ece67f3a9Matthias Schwarzott val &= 0x80; 6836a5cbd591c703491b62892682adc124ece67f3a9Matthias Schwarzott break; 684a81870e00bf502db2c579dcb9721adab3775ba58Andrew de Quincey } 6856a5cbd591c703491b62892682adc124ece67f3a9Matthias Schwarzott 6866a5cbd591c703491b62892682adc124ece67f3a9Matthias Schwarzott if (enable) 6876a5cbd591c703491b62892682adc124ece67f3a9Matthias Schwarzott val |= 0x40; 6886a5cbd591c703491b62892682adc124ece67f3a9Matthias Schwarzott else 6896a5cbd591c703491b62892682adc124ece67f3a9Matthias Schwarzott val &= ~0x40; 6906a5cbd591c703491b62892682adc124ece67f3a9Matthias Schwarzott 6916a5cbd591c703491b62892682adc124ece67f3a9Matthias Schwarzott ret = mt312_writereg(state, GPP_CTRL, val); 6926a5cbd591c703491b62892682adc124ece67f3a9Matthias Schwarzott 6936a5cbd591c703491b62892682adc124ece67f3a9Matthias Schwarzotterror: 6946a5cbd591c703491b62892682adc124ece67f3a9Matthias Schwarzott return ret; 695a81870e00bf502db2c579dcb9721adab3775ba58Andrew de Quincey} 696a81870e00bf502db2c579dcb9721adab3775ba58Andrew de Quincey 69789f6475857b89e956a8bcfef64944409ce4173b4Matthias Schwarzottstatic int mt312_sleep(struct dvb_frontend *fe) 6981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 699b8742700f13163ffa00cddce2a3c940b9ab2ab5aJohannes Stezenbach struct mt312_state *state = fe->demodulator_priv; 7001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int ret; 7011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 config; 7021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* reset all registers to defaults */ 704994fc28b6cd087cf6ef8d3ebd4eeef97c8194e4eMatthias Schwarzott ret = mt312_reset(state, 1); 705994fc28b6cd087cf6ef8d3ebd4eeef97c8194e4eMatthias Schwarzott if (ret < 0) 7061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ret; 7071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7086a5cbd591c703491b62892682adc124ece67f3a9Matthias Schwarzott if (state->id == ID_ZL10313) { 7096a5cbd591c703491b62892682adc124ece67f3a9Matthias Schwarzott /* reset ADC */ 7106a5cbd591c703491b62892682adc124ece67f3a9Matthias Schwarzott ret = mt312_writereg(state, GPP_CTRL, 0x00); 7116a5cbd591c703491b62892682adc124ece67f3a9Matthias Schwarzott if (ret < 0) 7126a5cbd591c703491b62892682adc124ece67f3a9Matthias Schwarzott return ret; 7136a5cbd591c703491b62892682adc124ece67f3a9Matthias Schwarzott 7146a5cbd591c703491b62892682adc124ece67f3a9Matthias Schwarzott /* full shutdown of ADCs, mpeg bus tristated */ 7156a5cbd591c703491b62892682adc124ece67f3a9Matthias Schwarzott ret = mt312_writereg(state, HW_CTRL, 0x0d); 7166a5cbd591c703491b62892682adc124ece67f3a9Matthias Schwarzott if (ret < 0) 7176a5cbd591c703491b62892682adc124ece67f3a9Matthias Schwarzott return ret; 7186a5cbd591c703491b62892682adc124ece67f3a9Matthias Schwarzott } 7196a5cbd591c703491b62892682adc124ece67f3a9Matthias Schwarzott 720994fc28b6cd087cf6ef8d3ebd4eeef97c8194e4eMatthias Schwarzott ret = mt312_readreg(state, CONFIG, &config); 721994fc28b6cd087cf6ef8d3ebd4eeef97c8194e4eMatthias Schwarzott if (ret < 0) 7221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ret; 7231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* enter standby */ 725994fc28b6cd087cf6ef8d3ebd4eeef97c8194e4eMatthias Schwarzott ret = mt312_writereg(state, CONFIG, config & 0x7f); 726994fc28b6cd087cf6ef8d3ebd4eeef97c8194e4eMatthias Schwarzott if (ret < 0) 7271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ret; 7281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 7301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 7311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 73289f6475857b89e956a8bcfef64944409ce4173b4Matthias Schwarzottstatic int mt312_get_tune_settings(struct dvb_frontend *fe, 73389f6475857b89e956a8bcfef64944409ce4173b4Matthias Schwarzott struct dvb_frontend_tune_settings *fesettings) 7341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 7351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fesettings->min_delay_ms = 50; 7361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fesettings->step_size = 0; 7371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds fesettings->max_drift = 0; 7381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 7391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 7401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 74189f6475857b89e956a8bcfef64944409ce4173b4Matthias Schwarzottstatic void mt312_release(struct dvb_frontend *fe) 7421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 74389f6475857b89e956a8bcfef64944409ce4173b4Matthias Schwarzott struct mt312_state *state = fe->demodulator_priv; 7441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds kfree(state); 7451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 7461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 747111221fb676176dc90638d6004f1c26164ddd5aeMatthias Schwarzott#define MT312_SYS_CLK 90000000UL /* 90 MHz */ 748e4671b6bc0b5b488adc5acbcfcbfa6661abec94eMatthias Schwarzottstatic struct dvb_frontend_ops mt312_ops = { 749827b5f3e30296f5ddeedc0c0359b1db77fd499a6Mauro Carvalho Chehab .delsys = { SYS_DVBS }, 7501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .info = { 7511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .name = "Zarlink ???? DVB-S", 7521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .frequency_min = 950000, 7531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .frequency_max = 2150000, 7540389b34e7c5c2dcdef61ed1741db674b47e4dc00Matthias Schwarzott /* FIXME: adjust freq to real used xtal */ 7550389b34e7c5c2dcdef61ed1741db674b47e4dc00Matthias Schwarzott .frequency_stepsize = (MT312_PLL_CLK / 1000) / 128, 756111221fb676176dc90638d6004f1c26164ddd5aeMatthias Schwarzott .symbol_rate_min = MT312_SYS_CLK / 128, /* FIXME as above */ 7571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .symbol_rate_max = MT312_SYS_CLK / 2, 7581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .caps = 7591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | 7601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | 7611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds FE_CAN_FEC_AUTO | FE_CAN_QPSK | FE_CAN_MUTE_TS | 7629101e6222cb115240e24160bb90cce425bb74de5Mauro Carvalho Chehab FE_CAN_RECOVER 7631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds }, 7641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .release = mt312_release, 7661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .init = mt312_initfe, 7681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .sleep = mt312_sleep, 769a81870e00bf502db2c579dcb9721adab3775ba58Andrew de Quincey .i2c_gate_ctrl = mt312_i2c_gate_ctrl, 7701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 771827b5f3e30296f5ddeedc0c0359b1db77fd499a6Mauro Carvalho Chehab .set_frontend = mt312_set_frontend, 772827b5f3e30296f5ddeedc0c0359b1db77fd499a6Mauro Carvalho Chehab .get_frontend = mt312_get_frontend, 7731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .get_tune_settings = mt312_get_tune_settings, 7741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .read_status = mt312_read_status, 7761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .read_ber = mt312_read_ber, 7771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .read_signal_strength = mt312_read_signal_strength, 7781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .read_snr = mt312_read_snr, 7791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .read_ucblocks = mt312_read_ucblocks, 7801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .diseqc_send_master_cmd = mt312_send_master_cmd, 7821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .diseqc_send_burst = mt312_send_burst, 7831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .set_tone = mt312_set_tone, 7841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .set_voltage = mt312_set_voltage, 7851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 7861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 787e4671b6bc0b5b488adc5acbcfcbfa6661abec94eMatthias Schwarzottstruct dvb_frontend *mt312_attach(const struct mt312_config *config, 78889f6475857b89e956a8bcfef64944409ce4173b4Matthias Schwarzott struct i2c_adapter *i2c) 789805e660ca32ef63b81203a556f29fef262b95cc0Adrian Bunk{ 79089f6475857b89e956a8bcfef64944409ce4173b4Matthias Schwarzott struct mt312_state *state = NULL; 791805e660ca32ef63b81203a556f29fef262b95cc0Adrian Bunk 792805e660ca32ef63b81203a556f29fef262b95cc0Adrian Bunk /* allocate memory for the internal state */ 793084e24acc906c162c92de7df807190856ae60928Matthias Schwarzott state = kzalloc(sizeof(struct mt312_state), GFP_KERNEL); 794805e660ca32ef63b81203a556f29fef262b95cc0Adrian Bunk if (state == NULL) 795805e660ca32ef63b81203a556f29fef262b95cc0Adrian Bunk goto error; 796805e660ca32ef63b81203a556f29fef262b95cc0Adrian Bunk 797805e660ca32ef63b81203a556f29fef262b95cc0Adrian Bunk /* setup the state */ 798805e660ca32ef63b81203a556f29fef262b95cc0Adrian Bunk state->config = config; 799805e660ca32ef63b81203a556f29fef262b95cc0Adrian Bunk state->i2c = i2c; 800805e660ca32ef63b81203a556f29fef262b95cc0Adrian Bunk 801805e660ca32ef63b81203a556f29fef262b95cc0Adrian Bunk /* check if the demod is there */ 802805e660ca32ef63b81203a556f29fef262b95cc0Adrian Bunk if (mt312_readreg(state, ID, &state->id) < 0) 803805e660ca32ef63b81203a556f29fef262b95cc0Adrian Bunk goto error; 804805e660ca32ef63b81203a556f29fef262b95cc0Adrian Bunk 805dea74869f3c62b0b7addd67017b22b394e942aacPatrick Boettcher /* create dvb_frontend */ 806e4671b6bc0b5b488adc5acbcfcbfa6661abec94eMatthias Schwarzott memcpy(&state->frontend.ops, &mt312_ops, 80789f6475857b89e956a8bcfef64944409ce4173b4Matthias Schwarzott sizeof(struct dvb_frontend_ops)); 808dea74869f3c62b0b7addd67017b22b394e942aacPatrick Boettcher state->frontend.demodulator_priv = state; 809dea74869f3c62b0b7addd67017b22b394e942aacPatrick Boettcher 810805e660ca32ef63b81203a556f29fef262b95cc0Adrian Bunk switch (state->id) { 811805e660ca32ef63b81203a556f29fef262b95cc0Adrian Bunk case ID_VP310: 812dea74869f3c62b0b7addd67017b22b394e942aacPatrick Boettcher strcpy(state->frontend.ops.info.name, "Zarlink VP310 DVB-S"); 813111221fb676176dc90638d6004f1c26164ddd5aeMatthias Schwarzott state->xtal = MT312_PLL_CLK; 814111221fb676176dc90638d6004f1c26164ddd5aeMatthias Schwarzott state->freq_mult = 9; 815805e660ca32ef63b81203a556f29fef262b95cc0Adrian Bunk break; 816805e660ca32ef63b81203a556f29fef262b95cc0Adrian Bunk case ID_MT312: 817dea74869f3c62b0b7addd67017b22b394e942aacPatrick Boettcher strcpy(state->frontend.ops.info.name, "Zarlink MT312 DVB-S"); 818111221fb676176dc90638d6004f1c26164ddd5aeMatthias Schwarzott state->xtal = MT312_PLL_CLK; 819111221fb676176dc90638d6004f1c26164ddd5aeMatthias Schwarzott state->freq_mult = 6; 820805e660ca32ef63b81203a556f29fef262b95cc0Adrian Bunk break; 8216a5cbd591c703491b62892682adc124ece67f3a9Matthias Schwarzott case ID_ZL10313: 8226a5cbd591c703491b62892682adc124ece67f3a9Matthias Schwarzott strcpy(state->frontend.ops.info.name, "Zarlink ZL10313 DVB-S"); 8236a5cbd591c703491b62892682adc124ece67f3a9Matthias Schwarzott state->xtal = MT312_PLL_CLK_10_111; 8246a5cbd591c703491b62892682adc124ece67f3a9Matthias Schwarzott state->freq_mult = 9; 8256a5cbd591c703491b62892682adc124ece67f3a9Matthias Schwarzott break; 826805e660ca32ef63b81203a556f29fef262b95cc0Adrian Bunk default: 8276a5cbd591c703491b62892682adc124ece67f3a9Matthias Schwarzott printk(KERN_WARNING "Only Zarlink VP310/MT312/ZL10313" 82889f6475857b89e956a8bcfef64944409ce4173b4Matthias Schwarzott " are supported chips.\n"); 829805e660ca32ef63b81203a556f29fef262b95cc0Adrian Bunk goto error; 830805e660ca32ef63b81203a556f29fef262b95cc0Adrian Bunk } 831805e660ca32ef63b81203a556f29fef262b95cc0Adrian Bunk 832805e660ca32ef63b81203a556f29fef262b95cc0Adrian Bunk return &state->frontend; 833805e660ca32ef63b81203a556f29fef262b95cc0Adrian Bunk 834805e660ca32ef63b81203a556f29fef262b95cc0Adrian Bunkerror: 835805e660ca32ef63b81203a556f29fef262b95cc0Adrian Bunk kfree(state); 836805e660ca32ef63b81203a556f29fef262b95cc0Adrian Bunk return NULL; 837805e660ca32ef63b81203a556f29fef262b95cc0Adrian Bunk} 838e4671b6bc0b5b488adc5acbcfcbfa6661abec94eMatthias SchwarzottEXPORT_SYMBOL(mt312_attach); 839805e660ca32ef63b81203a556f29fef262b95cc0Adrian Bunk 8401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmodule_param(debug, int, 0644); 8411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); 8421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8436a5cbd591c703491b62892682adc124ece67f3a9Matthias SchwarzottMODULE_DESCRIPTION("Zarlink VP310/MT312/ZL10313 DVB-S Demodulator driver"); 8441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_AUTHOR("Andreas Oberritter <obi@linuxtv.org>"); 845e4671b6bc0b5b488adc5acbcfcbfa6661abec94eMatthias SchwarzottMODULE_AUTHOR("Matthias Schwarzott <zzam@gentoo.org>"); 8461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_LICENSE("GPL"); 8471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 848